[azureus] 01/03: Imported Upstream version 4.8.0.0

Stephen Nelson stephenonelson-guest at moszumanska.debian.org
Tue Jun 24 11:58:41 UTC 2014


This is an automated email from the git hooks/post-receive script.

stephenonelson-guest pushed a commit to branch vuze5.3
in repository azureus.

commit 9ba347b9341a6817adba4e662abdb04c727d3303
Author: tony mancill <tmancill at debian.org>
Date:   Mon Dec 3 13:53:17 2012 -0800

    Imported Upstream version 4.8.0.0
---
 Azureus2.jardesc                                   |  525 ++
 ChangeLog.txt                                      |  958 ++--
 PreferencesJavaCodeStyleFormatter.xml              |  267 +
 az-build.xml                                       |  127 -
 build.xml                                          |   68 -
 build/libs/JavaApplicationStub                     |  Bin 44912 -> 0 bytes
 .../activities/VuzeActivitiesConstants.java        |    4 -
 .../azureus/activities/VuzeActivitiesEntry.java    |   91 +-
 .../activities/VuzeActivitiesLoadedListener.java   |   29 +
 .../azureus/activities/VuzeActivitiesManager.java  |  148 +-
 com/aelitis/azureus/core/AzureusCore.java          |   15 +
 com/aelitis/azureus/core/backup/BackupManager.java |   67 +
 .../azureus/core/backup/BackupManagerFactory.java  |   36 +
 .../core/backup/impl/BackupManagerImpl.java        | 1131 ++++
 .../clientmessageservice/impl/AEClientService.java |    4 +-
 .../impl/ClientConnection.java                     |   13 +-
 .../impl/NonBlockingReadWriteService.java          |    6 +-
 .../azureus/core/cnetwork/ContentNetwork.java      |   13 +-
 .../core/cnetwork/impl/ContentNetworkImpl.java     |    8 +
 .../cnetwork/impl/ContentNetworkManagerImpl.java   |  172 -
 .../core/cnetwork/impl/ContentNetworkVuze.java     |   26 +-
 .../cnetwork/impl/ContentNetworkVuzeGeneric.java   |  161 +-
 .../content/AzureusPlatformContentDirectory.java   |    6 +-
 .../azureus/core/content/RelatedContent.java       |    4 +-
 .../core/content/RelatedContentManager.java        | 2934 +++++++---
 com/aelitis/azureus/core/devices/Device.java       |   64 +-
 .../azureus/core/devices/DeviceManager.java        |   38 +-
 .../devices/DeviceManagerDiscoveryListener.java    |   35 +
 .../azureus/core/devices/DeviceMediaRenderer.java  |   14 +
 .../azureus/core/devices/DeviceTemplate.java       |    8 +
 .../core/devices/TranscodeActionVetoException.java |   34 +
 .../core/devices/TranscodeAnalysisListener.java    |   37 +
 .../azureus/core/devices/TranscodeException.java   |   15 +
 .../azureus/core/devices/TranscodeFile.java        |    9 +
 com/aelitis/azureus/core/devices/TranscodeJob.java |   27 +-
 .../azureus/core/devices/TranscodeProfile.java     |   10 +-
 .../azureus/core/devices/TranscodeProvider.java    |   15 +
 .../core/devices/TranscodeProviderAnalysis.java    |    7 +-
 .../azureus/core/devices/TranscodeQueue.java       |   14 +-
 .../core/devices/TranscodeQueueActionListener.java |   35 +
 .../azureus/core/devices/TranscodeTarget.java      |    6 +-
 .../core/devices/impl/DeviceDriveManager.java      |  365 +-
 .../azureus/core/devices/impl/DeviceImpl.java      | 4677 ++++++++--------
 .../core/devices/impl/DeviceManagerImpl.java       |  799 ++-
 .../core/devices/impl/DeviceManagerRSSFeed.java    |  465 +-
 .../core/devices/impl/DeviceManagerUPnPImpl.java   |  215 +-
 .../core/devices/impl/DeviceMediaRendererImpl.java |   85 +-
 .../devices/impl/DeviceMediaRendererManual.java    |  143 +-
 .../impl/DeviceMediaRendererTemplateImpl.java      |   13 +-
 .../devices/impl/DeviceOfflineDownloaderImpl.java  |  108 +-
 .../azureus/core/devices/impl/DeviceTivo.java      |   52 +-
 .../core/devices/impl/DeviceTivoManager.java       |   45 +-
 .../azureus/core/devices/impl/DeviceUPnPImpl.java  | 2916 +++++-----
 .../azureus/core/devices/impl/DeviceiTunes.java    |   39 +
 .../core/devices/impl/TranscodeFileImpl.java       |   68 +-
 .../core/devices/impl/TranscodeJobImpl.java        |  155 +-
 .../devices/impl/TranscodeJobOutputLeecher.java    |   50 +
 .../core/devices/impl/TranscodeManagerImpl.java    |  431 +-
 .../devices/impl/TranscodePipeStreamSource.java    |    5 +-
 .../core/devices/impl/TranscodeProfileImpl.java    |   34 +-
 .../core/devices/impl/TranscodeProviderVuze.java   |  252 +-
 .../core/devices/impl/TranscodeQueueImpl.java      |  614 ++-
 .../azureus/core/dht/DHTOperationAdapter.java      |    3 +-
 .../azureus/core/dht/DHTOperationListener.java     |    2 +-
 .../azureus/core/dht/control/DHTControl.java       |   10 +-
 .../dht/control/impl/DHTControlContactImpl.java    |    5 +
 .../core/dht/control/impl/DHTControlImpl.java      |   92 +-
 .../azureus/core/dht/control/impl/Test.java        |  104 -
 com/aelitis/azureus/core/dht/db/DHTDB.java         |   10 +
 .../azureus/core/dht/db/impl/DHTDBImpl.java        |   42 +-
 .../azureus/core/dht/db/impl/DHTDBMapping.java     |   32 +
 com/aelitis/azureus/core/dht/impl/DHTImpl.java     |   24 +-
 com/aelitis/azureus/core/dht/impl/Test.java        | 1175 ----
 .../azureus/core/dht/nat/DHTNATPuncher.java        |    3 +
 .../core/dht/nat/impl/DHTNATPuncherImpl.java       |  478 +-
 .../dht/netcoords/DHTNetworkPositionManager.java   |  214 +-
 .../DHTNetworkPositionProviderListener.java        |   34 +
 .../vivaldi/ver1/VivaldiPositionFactory.java       |   11 +
 .../vivaldi/ver1/impl/tests/VivaldiVisualTest.java |    2 +-
 com/aelitis/azureus/core/dht/router/DHTRouter.java |    2 +-
 .../dht/router/DHTRouterContactAttachment.java     |    3 +
 .../core/dht/router/impl/DHTRouterImpl.java        |   49 +-
 com/aelitis/azureus/core/dht/router/impl/Test.java |  142 -
 .../azureus/core/dht/transport/DHTTransport.java   |   14 +
 .../core/dht/transport/DHTTransportContact.java    |    7 +
 .../core/dht/transport/DHTTransportListener.java   |    3 +
 .../loopback/DHTTransportLoopbackContactImpl.java  |   12 +
 .../loopback/DHTTransportLoopbackImpl.java         |   17 +
 .../core/dht/transport/udp/DHTTransportUDP.java    |   18 +-
 .../udp/impl/DHTTransportUDPContactImpl.java       |   66 +-
 .../transport/udp/impl/DHTTransportUDPImpl.java    |  153 +-
 .../core/dht/transport/udp/impl/DHTUDPPacket.java  |    5 +-
 .../dht/transport/udp/impl/DHTUDPPacketReply.java  |   32 +-
 .../transport/udp/impl/DHTUDPPacketRequest.java    |   27 +-
 .../core/dht/transport/udp/impl/DHTUDPUtils.java   |   93 +-
 .../azureus/core/dht/transport/udp/impl/Test.java  |  407 --
 .../impl/packethandler/DHTUDPPacketHandler.java    |    2 +-
 .../azureus/core/diskmanager/cache/CacheFile.java  |    7 +-
 .../cache/impl/CacheFileManagerImpl.java           |   14 +-
 .../diskmanager/cache/impl/CacheFileWithCache.java |    4 +
 .../azureus/core/diskmanager/cache/impl/Test.java  | 1035 ----
 .../azureus/core/diskmanager/file/FMFile.java      |    7 +-
 .../diskmanager/file/FMFileManagerException.java   |   16 +
 .../core/diskmanager/file/impl/FMFileAccess.java   |    8 +
 .../diskmanager/file/impl/FMFileAccessCompact.java |   14 +
 .../file/impl/FMFileAccessController.java          |   94 +-
 .../diskmanager/file/impl/FMFileAccessLinear.java  |  290 +-
 .../file/impl/FMFileAccessPieceReorderer.java      |  275 +-
 .../core/diskmanager/file/impl/FMFileImpl.java     |   27 +-
 .../core/diskmanager/file/impl/FMFileLimited.java  |   33 +-
 .../diskmanager/file/impl/FMFileUnlimited.java     |   33 +-
 .../core/download/DiskManagerFileInfoDelegate.java |  790 +++
 .../core/download/DiskManagerFileInfoFile.java     |   86 +-
 .../core/download/DiskManagerFileInfoStream.java   |   50 +
 .../core/download/DownloadManagerEnhancer.java     |  197 +-
 .../core/download/EnhancedDownloadManager.java     | 2669 ++-------
 .../core/download/EnhancedDownloadManagerFile.java |  114 +-
 .../azureus/core/download/StreamManager.java       | 1156 ++++
 .../core/download/StreamManagerDownload.java       |   52 +
 .../download/StreamManagerDownloadListener.java    |   44 +
 .../core/drivedetector/DriveDetectedInfo.java      |    5 +
 .../azureus/core/drivedetector/DriveDetector.java  |    5 +-
 .../drivedetector/impl/DriveDetectedInfoImpl.java  |   14 +-
 .../core/drivedetector/impl/DriveDetectorImpl.java |   92 +-
 com/aelitis/azureus/core/impl/AzureusCoreImpl.java |  794 ++-
 .../azureus/core/instancemanager/AZInstance.java   |    5 +-
 .../core/instancemanager/AZInstanceManager.java    |    6 +
 .../core/instancemanager/impl/AZInstanceImpl.java  |   10 +-
 .../impl/AZInstanceManagerImpl.java                |  107 +-
 .../instancemanager/impl/AZMyInstanceImpl.java     |    7 +
 .../instancemanager/impl/AZOtherInstanceImpl.java  |   16 +-
 com/aelitis/azureus/core/lws/LWSDiskManager.java   |   49 +-
 .../azureus/core/lws/LWSDiskManagerState.java      |   15 +-
 com/aelitis/azureus/core/lws/LWSDownload.java      |   35 +
 .../azureus/core/lws/LWSPeerManagerAdapter.java    |   58 +
 com/aelitis/azureus/core/lws/LWSTorrent.java       |   58 +-
 com/aelitis/azureus/core/lws/LightWeightSeed.java  |   44 +-
 .../core/messenger/PlatformAuthorizedSender.java   |   53 -
 .../azureus/core/messenger/PlatformMessage.java    |   37 +-
 .../azureus/core/messenger/PlatformMessenger.java  |   26 +-
 .../messenger/config/PlatformConfigMessenger.java  |   96 +-
 .../config/PlatformContentNetworkMessenger.java    |  179 -
 .../messenger/config/PlatformDevicesMessenger.java |  240 +-
 .../config/PlatformMetaSearchMessenger.java        |   61 +-
 .../config/PlatformSubscriptionsMessenger.java     |   20 +
 .../messenger/config/PlatformTorrentMessenger.java |   48 -
 .../config/PlatformVuzeActivitiesMessenger.java    |   13 +-
 com/aelitis/azureus/core/metasearch/Engine.java    |   27 +-
 .../azureus/core/metasearch/MetaSearch.java        |   10 +
 .../azureus/core/metasearch/MetaSearchManager.java |   14 +
 .../core/metasearch/MetaSearchManagerListener.java |   30 +
 com/aelitis/azureus/core/metasearch/Result.java    |   19 +
 .../azureus/core/metasearch/impl/EngineImpl.java   |   99 +-
 .../core/metasearch/impl/ExternalLoginWindow.java  |   11 +-
 .../core/metasearch/impl/MetaSearchImpl.java       |  164 +-
 .../metasearch/impl/MetaSearchManagerImpl.java     |  479 +-
 .../core/metasearch/impl/plugin/PluginEngine.java  |   28 +-
 .../core/metasearch/impl/plugin/PluginResult.java  |    2 +-
 .../core/metasearch/impl/web/WebEngine.java        |  200 +-
 .../core/metasearch/impl/web/WebResult.java        |   46 +-
 .../core/metasearch/impl/web/json/JSONEngine.java  |  124 +-
 .../metasearch/impl/web/regex/RegexEngine.java     |  236 +-
 .../core/metasearch/impl/web/rss/RSSEngine.java    |  184 +-
 com/aelitis/azureus/core/nat/NATTraverser.java     |    9 +
 .../core/networkmanager/ConnectionEndpoint.java    |   21 +-
 .../core/networkmanager/IncomingMessageQueue.java  |    2 +
 .../core/networkmanager/NetworkConnection.java     |   13 +-
 .../core/networkmanager/NetworkManager.java        |   56 +
 .../core/networkmanager/OutgoingMessageQueue.java  |    9 +
 .../core/networkmanager/ProtocolEndpoint.java      |    9 +
 .../networkmanager/ProtocolEndpointFactory.java    |  121 +
 .../networkmanager/ProtocolEndpointHandler.java    |   40 +
 .../azureus/core/networkmanager/RateHandler.java   |   40 +
 .../azureus/core/networkmanager/Transport.java     |   15 +-
 .../core/networkmanager/admin/NetworkAdmin.java    |   10 +-
 .../networkmanager/admin/NetworkAdminProtocol.java |    8 +
 .../admin/impl/NetworkAdminHTTPProxyImpl.java      |    9 +-
 .../admin/impl/NetworkAdminImpl.java               |   35 +-
 .../admin/impl/NetworkAdminProtocolImpl.java       |   58 +-
 .../admin/impl/NetworkAdminSocksProxyImpl.java     |    9 +-
 .../core/networkmanager/impl/ByteBucket.java       |    4 +
 .../core/networkmanager/impl/ByteBucketMT.java     |   12 +-
 .../core/networkmanager/impl/ByteBucketST.java     |   13 +
 .../core/networkmanager/impl/EntityHandler.java    |   35 +
 .../impl/IncomingConnectionManager.java            |   21 +-
 .../impl/IncomingMessageQueueImpl.java             |   25 +-
 .../networkmanager/impl/MultiPeerDownloader.java   |   19 +-
 .../networkmanager/impl/MultiPeerDownloader2.java  |   23 +-
 .../networkmanager/impl/MultiPeerUploader.java     |   19 +-
 .../networkmanager/impl/NetworkConnectionImpl.java |   66 +-
 .../impl/OutgoingMessageQueueImpl.java             |   76 +-
 .../core/networkmanager/impl/ProtocolDecoder.java  |   53 +-
 .../impl/ProtocolDecoderInitial.java               |    7 +
 .../networkmanager/impl/ProtocolDecoderPHE.java    |    2 +
 .../networkmanager/impl/RateControlledEntity.java  |    9 +-
 .../core/networkmanager/impl/RateHandler.java      |   40 -
 .../core/networkmanager/impl/ReadController.java   |    4 +-
 .../networkmanager/impl/SinglePeerDownloader.java  |   23 +-
 .../networkmanager/impl/SinglePeerUploader.java    |   31 +-
 .../networkmanager/impl/TransferProcessor.java     |   44 +-
 .../core/networkmanager/impl/TransportHelper.java  |    3 +
 .../core/networkmanager/impl/TransportImpl.java    |   47 +-
 .../core/networkmanager/impl/WriteController.java  |  362 +-
 .../impl/http/HTTPNetworkManager.java              |   11 +-
 .../impl/tcp/IncomingSocketChannelManager.java     |    4 +-
 .../impl/tcp/LightweightTCPTransport.java          |   14 +
 .../impl/tcp/ProtocolEndpointTCP.java              |   44 +-
 .../impl/tcp/TCPConnectionManager.java             |  163 +-
 .../networkmanager/impl/tcp/TCPNetworkManager.java |   14 +-
 .../impl/tcp/TCPTransportHelper.java               |   12 +-
 .../networkmanager/impl/tcp/TCPTransportImpl.java  |   19 +-
 .../impl/tcp/VirtualChannelSelectorImpl.java       |  135 +-
 .../networkmanager/impl/udp/NetworkGlueUDP.java    |   15 +-
 .../impl/udp/ProtocolEndpointUDP.java              |   44 +-
 .../impl/udp/UDPConnectionManager.java             |   11 +-
 .../networkmanager/impl/udp/UDPConnectionSet.java  |   13 +-
 .../networkmanager/impl/udp/UDPNetworkManager.java |    4 +-
 .../core/networkmanager/impl/udp/UDPTransport.java |   14 +
 .../impl/udp/UDPTransportHelper.java               |  137 +-
 com/aelitis/azureus/core/pairing/PairedNode.java   |   38 +
 .../core/pairing/PairingConnectionData.java        |   11 +-
 .../azureus/core/pairing/PairingManager.java       |   44 +
 .../core/pairing/PairingManagerListener.java       |    1 +
 com/aelitis/azureus/core/pairing/PairingTest.java  |   43 +
 .../azureus/core/pairing/PairingTestListener.java  |   35 +
 .../core/pairing/impl/PairingManagerImpl.java      |  942 +++-
 .../azureus/core/pairing/impl/swt/PMSWTImpl.java   |  608 +++
 .../azureus/core/peermanager/PeerManager.java      |   75 +-
 .../peermanager/messaging/azureus/AZHandshake.java |   18 +-
 .../peermanager/messaging/azureus/AZMessage.java   |   13 +
 .../messaging/azureus/AZMessageEncoder.java        |   42 +-
 .../messaging/azureus/AZMessageFactory.java        |   44 +-
 .../peermanager/messaging/azureus/AZMetaData.java  |  231 +
 .../peermanager/messaging/azureus/AZStatReply.java |  134 +
 .../messaging/azureus/AZStatRequest.java           |  134 +
 .../messaging/azureus/AZUTMetaData.java            |   48 +
 .../messaging/bittorrent/BTAllowedFast.java        |  104 +
 .../messaging/bittorrent/BTHandshake.java          |   34 +
 .../messaging/bittorrent/BTHaveAll.java            |   66 +
 .../messaging/bittorrent/BTHaveNone.java           |   66 +
 .../messaging/bittorrent/BTMessage.java            |   24 +-
 .../messaging/bittorrent/BTMessageDecoder.java     |   35 +-
 .../messaging/bittorrent/BTMessageFactory.java     |   35 +
 .../messaging/bittorrent/BTRejectRequest.java      |  144 +
 .../messaging/bittorrent/BTSuggestPiece.java       |  104 +
 .../messaging/bittorrent/ltep/LTHandshake.java     |   90 +-
 .../messaging/bittorrent/ltep/LTMessage.java       |    5 +
 .../bittorrent/ltep/LTMessageDecoder.java          |    2 +
 .../bittorrent/ltep/LTMessageEncoder.java          |   10 +-
 .../bittorrent/ltep/LTMessageFactory.java          |    1 +
 .../messaging/bittorrent/ltep/UTMetaData.java      |  232 +
 .../messaging/bittorrent/ltep/UTPeerExchange.java  |   13 +-
 .../core/peermanager/peerdb/PeerDatabase.java      |  167 +-
 .../core/peermanager/peerdb/PeerExchangerItem.java |   59 +-
 .../azureus/core/peermanager/peerdb/PeerItem.java  |    2 +
 .../core/peermanager/piecepicker/PiecePicker.java  |   15 +
 .../peermanager/piecepicker/PieceRTAProvider.java  |    3 +-
 .../piecepicker/impl/PiecePickerImpl.java          |  508 +-
 .../peermanager/piecepicker/util/BitFlags.java     |    2 +-
 .../peermanager/unchoker/UnchokerUtilTest.java     |   30 +-
 .../peermanager/utils/BTPeerIDByteDecoder.java     |   22 +-
 .../utils/BTPeerIDByteDecoderDefinitions.java      |   17 +-
 .../utils/BTPeerIDByteDecoderUtils.java            |   21 +
 .../core/peermanager/utils/ClientIdentifier.java   |    2 +-
 .../utils/OutgoingBTPieceMessageHandler.java       |   58 +-
 .../core/peermanager/utils/PeerClassifier.java     |   16 +-
 .../core/proxy/impl/AEProxyConnectionImpl.java     |   26 +-
 .../azureus/core/proxy/impl/AEProxyImpl.java       |    3 +-
 .../core/proxy/socks/AESocksProxyConnection.java   |    3 +
 .../socks/impl/AESocksProxyConnectionImpl.java     |   65 +-
 .../AESocksProxyPlugableConnectionDefault.java     |   21 +-
 .../azureus/core/rssgen/RSSGeneratorPlugin.java    |   60 +-
 .../azureus/core/security/CryptoECCUtils.java      |    2 +-
 .../azureus/core/security/CryptoManager.java       |    8 +
 .../core/security/impl/CryptoManagerImpl.java      |   53 +
 .../core/speedmanager/SpeedLimitHandler.java       | 1734 ++++++
 .../speedmanager/SpeedManagerLimitEstimate.java    |    3 +
 .../core/speedmanager/impl/SpeedManagerImpl.java   |  112 +-
 .../impl/SpeedManagerPingMapperImpl.java           |    2 +-
 .../core/speedmanager/impl/v2/PingSpaceMon.java    |    1 +
 .../impl/v2/SMConfigurationAdapterImpl.java        |    3 +
 .../azureus/core/speedmanager/impl/v2/SMConst.java |    9 +-
 com/aelitis/azureus/core/subs/Subscription.java    |    6 +
 .../azureus/core/subs/SubscriptionManager.java     |   24 +
 .../azureus/core/subs/SubscriptionUtils.java       |   29 +-
 .../core/subs/impl/SubscriptionHistoryImpl.java    |   21 +-
 .../azureus/core/subs/impl/SubscriptionImpl.java   |   39 +-
 .../core/subs/impl/SubscriptionManagerImpl.java    | 1137 +++-
 .../core/subs/impl/SubscriptionRSSFeed.java        |   12 +-
 .../core/subs/impl/SubscriptionResultImpl.java     |    2 +-
 .../core/subs/impl/SubscriptionSchedulerImpl.java  |   33 +-
 .../azureus/core/torrent/PlatformTorrentUtils.java |   46 -
 .../azureus/core/tracker/TrackerPeerSource.java    |   86 +
 .../core/tracker/TrackerPeerSourceAdapter.java     |  104 +
 .../azureus/core/update/AzureusRestarter.java      |    7 +
 .../core/update/impl/AzureusRestarterImpl.java     |  151 +-
 com/aelitis/azureus/core/util/AEPriorityMixin.java |   33 +
 com/aelitis/azureus/core/util/AZ3Functions.java    |   42 +-
 com/aelitis/azureus/core/util/CopyOnWriteList.java |   82 +-
 com/aelitis/azureus/core/util/DNSUtils.java        |  105 +
 .../core/util/DeleteFileOnCloseInputStream.java    |    3 +-
 .../azureus/core/util/FeatureAvailability.java     |   55 +
 com/aelitis/azureus/core/util/GeneralUtils.java    |  157 +
 com/aelitis/azureus/core/util/LaunchManager.java   |  152 +
 com/aelitis/azureus/core/util/NetUtils.java        |  169 +-
 com/aelitis/azureus/core/util/QTFastStartRAF.java  |  656 +++
 com/aelitis/azureus/core/util/RegExUtil.java       |  134 +
 .../azureus/core/util/http/HTTPAuthHelper.java     |    2 +-
 .../core/versioncheck/VersionCheckClient.java      | 2946 +++++-----
 .../versioncheck/VersionCheckClientListener.java   |   32 +
 .../versioncheck/VersionCheckClientUDPCodecs.java  |   18 +-
 .../versioncheck/VersionCheckClientUDPReply.java   |   15 +-
 .../versioncheck/VersionCheckClientUDPRequest.java |   15 +-
 com/aelitis/azureus/core/vuzefile/VuzeFile.java    |    3 +
 .../azureus/core/vuzefile/VuzeFileComponent.java   |    5 +
 .../azureus/core/vuzefile/VuzeFileHandler.java     |   28 +
 .../azureus/core/vuzefile/VuzeFileImpl.java        |   42 +
 com/aelitis/azureus/launcher/Launcher.java         |    6 +-
 .../azureus/plugins/clientid/ClientIDPlugin.java   |    9 +-
 com/aelitis/azureus/plugins/dht/DHTPlugin.java     |   82 +-
 .../azureus/plugins/dht/DHTPluginContact.java      |    6 +
 .../plugins/dht/DHTPluginOperationListener.java    |    2 +-
 .../azureus/plugins/dht/DHTPluginValue.java        |    3 +
 .../plugins/dht/impl/DHTPluginContactImpl.java     |   12 +
 .../azureus/plugins/dht/impl/DHTPluginImpl.java    |   58 +-
 .../plugins/dht/impl/DHTPluginStorageManager.java  |   37 +-
 .../plugins/dht/impl/DHTPluginValueImpl.java       |    6 +
 .../azureus/plugins/extseed/ExternalSeedPeer.java  |   88 +-
 .../plugins/extseed/ExternalSeedPlugin.java        |  178 +-
 .../plugins/extseed/ExternalSeedReader.java        |    4 +
 .../extseed/impl/ExternalSeedReaderImpl.java       |    3 +-
 .../ExternalSeedReaderFactoryGetRight.java         |   23 +-
 .../impl/getright/ExternalSeedReaderGetRight.java  |   10 +-
 .../impl/webseed/ExternalSeedReaderWebSeed.java    |    8 +-
 .../util/ExternalSeedHTTPDownloaderRange.java      |  157 +-
 .../azureus/plugins/magnet/MagnetPlugin.java       | 1433 +++--
 .../plugins/magnet/MagnetPluginMDDownloader.java   |  724 +++
 .../magnet/MagnetPluginProgressListener.java       |    3 +
 .../azureus/plugins/net/buddy/BuddyPlugin.java     |   78 +-
 .../plugins/net/buddy/swt/BuddyPluginView.java     |    2 +-
 .../net/buddy/swt/BuddyPluginViewInstance.java     |    3 +-
 .../net/netstatus/NetStatusProtocolTester.java     |   10 +-
 .../net/netstatus/NetStatusProtocolTesterBT.java   |   22 +-
 .../removerules/DownloadRemoveRulesPlugin.java     |   23 +
 .../defaultplugin/DefaultRankCalculator.java       |    8 +-
 .../defaultplugin/StartStopRulesDefaultPlugin.java |   90 +-
 .../plugins/tracker/dht/DHTTrackerPlugin.java      |  627 ++-
 .../plugins/tracker/local/LocalTrackerPlugin.java  |  275 +-
 com/aelitis/azureus/plugins/upnp/UPnPPlugin.java   |   61 +-
 .../azureus/plugins/upnp/UPnPPluginService.java    |   50 +-
 com/aelitis/azureus/ui/UIFunctions.java            |   41 +-
 com/aelitis/azureus/ui/UIFunctionsManager.java     |   20 +-
 com/aelitis/azureus/ui/common/ToolBarEnabler.java  |   14 +
 com/aelitis/azureus/ui/common/ToolBarItem.java     |   18 +
 .../azureus/ui/common/table/TableCellCore.java     |   13 +-
 .../azureus/ui/common/table/TableColumnCore.java   |   30 +-
 .../table/TableColumnCoreCreationListener.java     |   34 +
 .../azureus/ui/common/table/TableRowCore.java      |   56 +-
 .../ui/common/table/TableSelectedRowsListener.java |   30 +-
 .../table/TableStructureEventDispatcher.java       |    4 +-
 .../table/TableStructureModificationListener.java  |    2 +-
 com/aelitis/azureus/ui/common/table/TableView.java |   82 +-
 .../ui/common/table/TableViewFilterCheck.java      |   37 +
 .../common/table/impl/DataSourceCallBackUtil.java  |  159 +
 .../ui/common/table/impl/TableColumnImpl.java      |  375 +-
 .../ui/common/table/impl/TableColumnManager.java   |  768 +++
 .../ui/common/table/impl/TableRowCoreSorter.java   |   34 +
 .../ui/common/table/impl/TableViewImpl.java        | 1731 +++++-
 .../azureus/ui/common/updater/UIUpdater.java       |   22 +-
 .../ui/common/viewtitleinfo/ViewTitleInfo.java     |    5 -
 .../ui/common/viewtitleinfo/ViewTitleInfo2.java    |   33 +
 .../common/viewtitleinfo/ViewTitleInfoManager.java |   14 +-
 com/aelitis/azureus/ui/images/30px-mswmp.png       |  Bin 0 -> 1160 bytes
 com/aelitis/azureus/ui/images/30px-other.png       |  Bin 0 -> 215 bytes
 com/aelitis/azureus/ui/images/30px-psp.png         |  Bin 0 -> 1171 bytes
 com/aelitis/azureus/ui/images/30px-sam.png         |  Bin 0 -> 605 bytes
 com/aelitis/azureus/ui/images/30px-tivo.png        |  Bin 0 -> 720 bytes
 com/aelitis/azureus/ui/images/30px-wdtv.png        |  Bin 0 -> 1432 bytes
 .../azureus/ui/images/Vuze_DVD_Burn_Icon.png       |  Bin 0 -> 8302 bytes
 .../azureus/ui/images/Vuze_HD_Player_Icon.png      |  Bin 0 -> 4733 bytes
 .../azureus/ui/images/Vuze_Play_Now_Icon.png       |  Bin 0 -> 6974 bytes
 .../azureus/ui/images/Vuze_Plus_Toolbar_Logo.png   |  Bin 0 -> 3753 bytes
 .../azureus/ui/images/Vuze_Speed_Test_Icon.png     |  Bin 0 -> 15143 bytes
 .../azureus/ui/images/android_icon_32x32.png       |  Bin 0 -> 2623 bytes
 com/aelitis/azureus/ui/images/arrowSmall.gif       |  Bin 689 -> 0 bytes
 com/aelitis/azureus/ui/images/arrow_btn.png        |  Bin 0 -> 1383 bytes
 .../azureus/ui/images/arrow_btn_pressed.png        |  Bin 0 -> 1469 bytes
 com/aelitis/azureus/ui/images/bigspin.png          |  Bin 0 -> 21858 bytes
 com/aelitis/azureus/ui/images/blueline.png         |  Bin 109 -> 0 bytes
 com/aelitis/azureus/ui/images/bottom_bar_bg.gif    |  Bin 853 -> 0 bytes
 com/aelitis/azureus/ui/images/download_arrow.png   |  Bin 0 -> 1011 bytes
 .../azureus/ui/images/download_bar_overlay.png     |  Bin 0 -> 975 bytes
 .../ui/images/download_bar_overlay_small.png       |  Bin 0 -> 972 bytes
 com/aelitis/azureus/ui/images/entry_buddy_new.png  |  Bin 677 -> 0 bytes
 com/aelitis/azureus/ui/images/entry_buddy_req.png  |  Bin 457 -> 0 bytes
 .../azureus/ui/images/entry_buddy_share.png        |  Bin 326 -> 0 bytes
 com/aelitis/azureus/ui/images/entry_thumbsup.png   |  Bin 423 -> 0 bytes
 com/aelitis/azureus/ui/images/failure.png          |  Bin 0 -> 648 bytes
 com/aelitis/azureus/ui/images/grayhline.png        |  Bin 183 -> 0 bytes
 com/aelitis/azureus/ui/images/help-over.png        |  Bin 462 -> 0 bytes
 com/aelitis/azureus/ui/images/help.png             |  Bin 503 -> 0 bytes
 com/aelitis/azureus/ui/images/{sb => }/ic_x.png    |  Bin
 com/aelitis/azureus/ui/images/lastsearch.gif       |  Bin 159 -> 0 bytes
 .../azureus/ui/images/network_closed_preview.png   |  Bin 5563 -> 0 bytes
 com/aelitis/azureus/ui/images/new_dot.png          |  Bin 335 -> 1299 bytes
 .../azureus/ui/images/notification_icon.png        |  Bin 1017 -> 0 bytes
 com/aelitis/azureus/ui/images/old_dot.png          |  Bin 237 -> 1301 bytes
 com/aelitis/azureus/ui/images/play_now_off.png     |  Bin 0 -> 863 bytes
 com/aelitis/azureus/ui/images/play_now_on.png      |  Bin 0 -> 889 bytes
 com/aelitis/azureus/ui/images/popup_dvd_drag.png   |  Bin 0 -> 20613 bytes
 .../azureus/ui/images/popup_warning_icon.png       |  Bin 0 -> 656 bytes
 com/aelitis/azureus/ui/images/priority_high.png    |  Bin 0 -> 1073 bytes
 com/aelitis/azureus/ui/images/priority_normal.png  |  Bin 0 -> 1066 bytes
 com/aelitis/azureus/ui/images/priority_stopped.png |  Bin 0 -> 1059 bytes
 com/aelitis/azureus/ui/images/qual_hd.png          |  Bin 744 -> 0 bytes
 com/aelitis/azureus/ui/images/qual_sd.png          |  Bin 798 -> 0 bytes
 com/aelitis/azureus/ui/images/remote_ftux.png      |  Bin 0 -> 49663 bytes
 com/aelitis/azureus/ui/images/remote_icon.png      |  Bin 0 -> 405 bytes
 com/aelitis/azureus/ui/images/remote_logo.png      |  Bin 0 -> 3081 bytes
 com/aelitis/azureus/ui/images/sb/20px-bb.png       |  Bin 0 -> 3737 bytes
 com/aelitis/azureus/ui/images/sb/20px-dlna.png     |  Bin 0 -> 3633 bytes
 com/aelitis/azureus/ui/images/sb/20px-games.png    |  Bin 0 -> 1444 bytes
 com/aelitis/azureus/ui/images/sb/20px-itunes.png   |  Bin 1671 -> 1879 bytes
 com/aelitis/azureus/ui/images/sb/20px-library.png  |  Bin 0 -> 1721 bytes
 com/aelitis/azureus/ui/images/sb/20px-mswmp.png    |  Bin 0 -> 1434 bytes
 com/aelitis/azureus/ui/images/sb/20px-neo.png      |  Bin 0 -> 1124 bytes
 com/aelitis/azureus/ui/images/sb/20px-od-bel.png   |  Bin 886 -> 852 bytes
 com/aelitis/azureus/ui/images/sb/20px-other.png    |  Bin 190 -> 3139 bytes
 com/aelitis/azureus/ui/images/sb/20px-ps3.png      |  Bin 442 -> 748 bytes
 com/aelitis/azureus/ui/images/sb/20px-psp.png      |  Bin 431 -> 971 bytes
 com/aelitis/azureus/ui/images/sb/20px-sam.png      |  Bin 0 -> 752 bytes
 com/aelitis/azureus/ui/images/sb/20px-tivo.png     |  Bin 420 -> 1143 bytes
 com/aelitis/azureus/ui/images/sb/20px-upnp.png     |  Bin 0 -> 3127 bytes
 com/aelitis/azureus/ui/images/sb/20px-usb.png      |  Bin 0 -> 870 bytes
 com/aelitis/azureus/ui/images/sb/20px-wdtv.png     |  Bin 0 -> 1026 bytes
 com/aelitis/azureus/ui/images/sb/20px-wii.png      |  Bin 601 -> 1261 bytes
 com/aelitis/azureus/ui/images/sb/20px-xbox.png     |  Bin 1663 -> 1693 bytes
 com/aelitis/azureus/ui/images/sb/alltransfers.png  |  Bin 0 -> 416 bytes
 .../azureus/ui/images/sb/alltransfers_selected.png |  Bin 0 -> 420 bytes
 .../azureus/ui/images/sb/android_icon_20x20.png    |  Bin 0 -> 1155 bytes
 com/aelitis/azureus/ui/images/sb/boxee.png         |  Bin 0 -> 1941 bytes
 com/aelitis/azureus/ui/images/sb/close.png         |  Bin 0 -> 283 bytes
 .../azureus/ui/images/sb/close_selected.png        |  Bin 0 -> 227 bytes
 com/aelitis/azureus/ui/images/sb/devices.png       |  Bin 0 -> 391 bytes
 .../azureus/ui/images/sb/devices_selected.png      |  Bin 0 -> 459 bytes
 com/aelitis/azureus/ui/images/sb/downloading.png   |  Bin 0 -> 576 bytes
 .../azureus/ui/images/sb/downloading_selected.png  |  Bin 0 -> 519 bytes
 .../azureus/ui/images/sb/downloadingspin.png       |  Bin 0 -> 1013 bytes
 .../ui/images/sb/downloadingspin_selected.png      |  Bin 0 -> 996 bytes
 com/aelitis/azureus/ui/images/sb/dvd.png           |  Bin 0 -> 694 bytes
 com/aelitis/azureus/ui/images/sb/dvd_disc.png      |  Bin 0 -> 848 bytes
 .../azureus/ui/images/sb/dvd_disc_selected.png     |  Bin 0 -> 974 bytes
 com/aelitis/azureus/ui/images/sb/dvd_selected.png  |  Bin 0 -> 846 bytes
 com/aelitis/azureus/ui/images/sb/file.png          |  Bin 0 -> 463 bytes
 com/aelitis/azureus/ui/images/sb/file_selected.png |  Bin 0 -> 455 bytes
 .../azureus/ui/images/sb/gettingstarted.png        |  Bin 0 -> 854 bytes
 .../ui/images/sb/gettingstarted_selected.png       |  Bin 0 -> 746 bytes
 com/aelitis/azureus/ui/images/sb/hd.png            |  Bin 0 -> 590 bytes
 com/aelitis/azureus/ui/images/sb/hd_selected.png   |  Bin 0 -> 651 bytes
 com/aelitis/azureus/ui/images/sb/ic_activity.png   |  Bin 329 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_add.png        |  Bin 585 -> 1329 bytes
 com/aelitis/azureus/ui/images/sb/ic_device.png     |  Bin 406 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_device_int.png |  Bin 813 -> 1107 bytes
 com/aelitis/azureus/ui/images/sb/ic_games.png      |  Bin 0 -> 1737 bytes
 .../azureus/ui/images/sb/ic_games_selected.png     |  Bin 0 -> 1803 bytes
 com/aelitis/azureus/ui/images/sb/ic_info.png       |  Bin 254 -> 1584 bytes
 com/aelitis/azureus/ui/images/sb/ic_library.png    |  Bin 1010 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_logview.png    |  Bin 0 -> 329 bytes
 com/aelitis/azureus/ui/images/sb/ic_rss.png        |  Bin 581 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_search.png     |  Bin 776 -> 0 bytes
 .../azureus/ui/images/sb/ic_search_selected.png    |  Bin 571 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_vuze.png       |  Bin 1008 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_welcome.png    |  Bin 861 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_x_over.png     |  Bin 376 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/ic_x_selected.png |  Bin 380 -> 0 bytes
 .../azureus/ui/images/sb/ic_x_selected_over.png    |  Bin 309 -> 0 bytes
 .../ui/images/sb/left_nav_create_dvd_icon.png      |  Bin 0 -> 191 bytes
 .../sb/left_nav_create_dvd_icon_selected.png       |  Bin 0 -> 201 bytes
 .../azureus/ui/images/sb/left_nav_dvd_icon.png     |  Bin 0 -> 1135 bytes
 com/aelitis/azureus/ui/images/sb/notifications.png |  Bin 0 -> 1379 bytes
 .../ui/images/sb/notifications_selected.png        |  Bin 0 -> 1385 bytes
 com/aelitis/azureus/ui/images/sb/plugin.png        |  Bin 0 -> 352 bytes
 .../azureus/ui/images/sb/plugin_selected.png       |  Bin 0 -> 469 bytes
 com/aelitis/azureus/ui/images/sb/plus.png          |  Bin 0 -> 694 bytes
 com/aelitis/azureus/ui/images/sb/plus_selected.png |  Bin 0 -> 640 bytes
 com/aelitis/azureus/ui/images/sb/search.png        |  Bin 0 -> 666 bytes
 .../azureus/ui/images/sb/search_selected.png       |  Bin 0 -> 641 bytes
 com/aelitis/azureus/ui/images/sb/subscriptions.png |  Bin 0 -> 527 bytes
 .../ui/images/sb/subscriptions_selected.png        |  Bin 0 -> 626 bytes
 com/aelitis/azureus/ui/images/sb/vitality_lft.png  |  Bin 366 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/vitality_mid.png  |  Bin 217 -> 0 bytes
 com/aelitis/azureus/ui/images/sb/vitality_rgt.png  |  Bin 365 -> 0 bytes
 com/aelitis/azureus/ui/images/separator.gif        |  Bin 101 -> 0 bytes
 .../azureus/ui/images/subscription_icon.png        |  Bin 0 -> 1614 bytes
 .../azureus/ui/images/subscription_icon_1616.png   |  Bin 0 -> 698 bytes
 .../ui/images/subscription_icon_column_hdr.png     |  Bin 0 -> 1078 bytes
 .../ui/images/subscription_icon_inactive.png       |  Bin 0 -> 1442 bytes
 com/aelitis/azureus/ui/images/success.png          |  Bin 0 -> 661 bytes
 com/aelitis/azureus/ui/images/tb/2nd.png           |  Bin 0 -> 4424 bytes
 com/aelitis/azureus/ui/images/tb/c/2nd.png         |  Bin 0 -> 4424 bytes
 com/aelitis/azureus/ui/images/tb/c/sec_l_l.png     |  Bin 0 -> 283 bytes
 com/aelitis/azureus/ui/images/tb/c/sec_m.png       |  Bin 0 -> 173 bytes
 com/aelitis/azureus/ui/images/tb/c/sec_r_r.png     |  Bin 0 -> 293 bytes
 com/aelitis/azureus/ui/images/tb/c/view_l_l.png    |  Bin 0 -> 327 bytes
 com/aelitis/azureus/ui/images/tb/c/view_l_m.png    |  Bin 0 -> 195 bytes
 com/aelitis/azureus/ui/images/tb/c/view_l_r.png    |  Bin 0 -> 194 bytes
 com/aelitis/azureus/ui/images/tb/c/view_r_l.png    |  Bin 0 -> 213 bytes
 com/aelitis/azureus/ui/images/tb/c/view_r_m.png    |  Bin 0 -> 211 bytes
 com/aelitis/azureus/ui/images/tb/c/view_r_r.png    |  Bin 0 -> 325 bytes
 .../azureus/ui/images/tb/download_disabled.png     |  Bin 879 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_delete.png     |  Bin 871 -> 0 bytes
 .../azureus/ui/images/tb/ic_delete_disabled.png    |  Bin 608 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_device.png     |  Bin 530 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_down.png       |  Bin 754 -> 0 bytes
 .../azureus/ui/images/tb/ic_down_disabled.png      |  Bin 464 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_launch.png     |  Bin 732 -> 0 bytes
 .../azureus/ui/images/tb/ic_launch_disabled.png    |  Bin 528 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_start.png      |  Bin 965 -> 0 bytes
 .../azureus/ui/images/tb/ic_start_disabled.png     |  Bin 696 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_stop.png       |  Bin 1026 -> 0 bytes
 .../azureus/ui/images/tb/ic_stop_disabled.png      |  Bin 783 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/ic_up.png         |  Bin 727 -> 0 bytes
 .../azureus/ui/images/tb/ic_up_disabled.png        |  Bin 489 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/play_disabled.png |  Bin 884 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/play_now_plus.png |  Bin 0 -> 2131 bytes
 .../azureus/ui/images/tb/play_now_plus_down.png    |  Bin 0 -> 2015 bytes
 com/aelitis/azureus/ui/images/tb/spacer.png        |  Bin 364 -> 0 bytes
 com/aelitis/azureus/ui/images/tb/stream.png        |  Bin 0 -> 774 bytes
 com/aelitis/azureus/ui/images/tb/stream_down.png   |  Bin 0 -> 936 bytes
 com/aelitis/azureus/ui/images/upload_arrow.png     |  Bin 0 -> 1003 bytes
 com/aelitis/azureus/ui/images/vp_header.png        |  Bin 0 -> 3362 bytes
 com/aelitis/azureus/ui/images/warning.png          |  Bin 0 -> 535 bytes
 .../azureus/ui/mdi/MdiChildCloseListener.java      |   30 +
 com/aelitis/azureus/ui/mdi/MdiCloseListener.java   |   31 +
 com/aelitis/azureus/ui/mdi/MdiEntry.java           |  154 +
 .../azureus/ui/mdi/MdiEntryCreationListener.java   |    6 +
 .../azureus/ui/mdi/MdiEntryDropListener.java       |   34 +
 .../azureus/ui/mdi/MdiEntryLoadedListener.java     |   29 +
 .../azureus/ui/mdi/MdiEntryLogIdListener.java      |   30 +
 .../azureus/ui/mdi/MdiEntryOpenListener.java       |   29 +
 .../azureus/ui/mdi/MdiEntryVitalityImage.java      |   48 +
 .../ui/mdi/MdiEntryVitalityImageListener.java      |   29 +
 com/aelitis/azureus/ui/mdi/MdiListener.java        |   32 +
 .../azureus/ui/mdi/MultipleDocumentInterface.java  |  107 +
 .../ui/selectedcontent/DownloadUrlInfo.java        |   35 +
 .../ui/selectedcontent/ISelectedContent.java       |   23 +-
 .../ui/selectedcontent/SelectedContent.java        |   62 +
 .../ui/selectedcontent/SelectedContentManager.java |  106 +-
 .../ui/selectedcontent/SelectedContentV3.java      |   64 +-
 com/aelitis/azureus/ui/skin/SkinConstants.java     |   15 +-
 com/aelitis/azureus/ui/skin/SkinProperties.java    |   12 +-
 .../azureus/ui/skin/SkinPropertiesImpl.java        |   55 +-
 com/aelitis/azureus/ui/skin/skin3.properties       |   11 +-
 .../azureus/ui/skin/skin3_classic.properties       |    4 +
 .../ui/skin/skin3_close_notification.properties    |   99 -
 .../azureus/ui/skin/skin3_constants.properties     |  157 +-
 .../azureus/ui/skin/skin3_devices.properties       |    8 +-
 .../skin/skin3_dlg_deviceadd_mfchooser.properties  |    2 +-
 .../skin3_dlg_devicetemplatechooser.properties     |    2 +-
 .../azureus/ui/skin/skin3_dlg_generic.properties   |  128 +
 .../azureus/ui/skin/skin3_dlg_register.properties  |  220 +
 .../ui/skin/skin3_dlg_remotepairing.properties     |  244 +
 .../ui/skin/skin3_dlg_streamplus.properties        |   21 +
 .../azureus/ui/skin/skin3_maintabs.properties      |  358 --
 .../azureus/ui/skin/skin3_manageCN.properties      |   31 -
 com/aelitis/azureus/ui/skin/skin3_rcm.properties   |   46 -
 .../azureus/ui/skin/skin3_sbc_library.properties   |   92 +-
 .../azureus/ui/skin/skin3_sidebar.properties       |   41 +-
 .../ui/skin/skin3_tab_searchresults.properties     |    1 +
 .../azureus/ui/skin/skin3_toolbar.properties       |  484 ++
 .../ui/skin/skin3_transcodechooser.properties      |    2 +-
 com/aelitis/azureus/ui/swt/Initializer.java        |  332 +-
 com/aelitis/azureus/ui/swt/Sleak.java              |  478 --
 .../azureus/ui/swt/UIConfigDefaultsSWTv3.java      |   33 +-
 .../azureus/ui/swt/UIFunctionsManagerSWT.java      |    9 +-
 com/aelitis/azureus/ui/swt/UIFunctionsSWT.java     |   73 +-
 .../azureus/ui/swt/browser/BrowserContext.java     |  370 +-
 .../azureus/ui/swt/browser/BrowserWrapper.java     |  277 +
 .../ui/swt/browser/listener/ConfigListener.java    |    5 +-
 .../ui/swt/browser/listener/DisplayListener.java   |  122 +-
 .../listener/ExternalLoginCookieListener.java      |    6 +-
 .../swt/browser/listener/MetaSearchListener.java   |   63 +-
 .../ui/swt/browser/listener/TorrentListener.java   |    2 +-
 .../ui/swt/browser/listener/VuzeListener.java      |   45 +-
 .../ui/swt/browser/msg/MessageDispatcherSWT.java   |   79 +-
 .../ColumnSubscriptionAutoDownload.java            |    8 +
 .../subscriptions/ColumnSubscriptionCategory.java  |    8 +
 .../ColumnSubscriptionLastChecked.java             |    9 +
 .../subscriptions/ColumnSubscriptionName.java      |   41 +-
 .../ColumnSubscriptionNbNewResults.java            |    9 +
 .../subscriptions/ColumnSubscriptionNbResults.java |    9 +
 .../subscriptions/ColumnSubscriptionNew.java       |   11 +-
 .../ColumnSubscriptionSubscribers.java             |    8 +
 .../ui/swt/columns/torrent/ColumnProgressETA.java  |  780 ++-
 .../ui/swt/columns/torrent/ColumnStream.java       |  234 +
 .../ui/swt/columns/torrent/ColumnThumbAndName.java |  263 +-
 .../ui/swt/columns/torrent/ColumnThumbnail.java    |    5 +-
 .../ui/swt/columns/torrent/ColumnUnopened.java     |    3 +-
 .../ui/swt/columns/utils/ColumnImageClickArea.java |    2 -
 .../ui/swt/columns/utils/TableColumnCreatorV3.java |   38 +-
 .../vuzeactivity/ColumnActivityActions.java        |   42 +-
 .../columns/vuzeactivity/ColumnActivityNew.java    |    6 +-
 .../columns/vuzeactivity/ColumnActivityText.java   |   10 +-
 .../ui/swt/content/RelatedContentEnumerator.java   |   41 -
 .../azureus/ui/swt/content/RelatedContentUI.java   | 1081 ----
 .../azureus/ui/swt/content/SBC_RCMView.java        |  881 ---
 .../ui/swt/content/columns/ColumnRC_Actions.java   |  224 -
 .../ui/swt/content/columns/ColumnRC_Created.java   |   68 -
 .../ui/swt/content/columns/ColumnRC_Hash.java      |   98 -
 .../ui/swt/content/columns/ColumnRC_LastSeen.java  |   65 -
 .../ui/swt/content/columns/ColumnRC_Level.java     |   64 -
 .../ui/swt/content/columns/ColumnRC_New.java       |  121 -
 .../ui/swt/content/columns/ColumnRC_Peers.java     |   67 -
 .../ui/swt/content/columns/ColumnRC_Rank.java      |   64 -
 .../ui/swt/content/columns/ColumnRC_Seeds.java     |   67 -
 .../ui/swt/content/columns/ColumnRC_Size.java      |   65 -
 .../ui/swt/content/columns/ColumnRC_Title.java     |  100 -
 .../ui/swt/content/columns/ColumnRC_Tracker.java   |  122 -
 .../azureus/ui/swt/devices/DeviceInfoArea.java     |   28 +-
 .../azureus/ui/swt/devices/DeviceInternetView.java |   37 +-
 .../azureus/ui/swt/devices/DeviceManagerUI.java    | 3280 ++++++-----
 .../azureus/ui/swt/devices/DevicesFTUX.java        |  925 ++--
 .../azureus/ui/swt/devices/DevicesODFTUX.java      |    7 +-
 .../azureus/ui/swt/devices/SBC_DevicesODView.java  |  127 +-
 .../azureus/ui/swt/devices/SBC_DevicesView.java    |  364 +-
 .../azureus/ui/swt/devices/TranscodeChooser.java   | 1658 +++---
 .../ui/swt/devices/columns/ColumnDevices_Name.java |   54 -
 .../swt/devices/columns/ColumnOD_Completion.java   |   13 +-
 .../ui/swt/devices/columns/ColumnOD_Name.java      |   24 +-
 .../ui/swt/devices/columns/ColumnOD_Remaining.java |    8 +-
 .../ui/swt/devices/columns/ColumnOD_Status.java    |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Category.java  |   11 +-
 .../swt/devices/columns/ColumnTJ_Completion.java   |   21 +-
 .../devices/columns/ColumnTJ_CopiedToDevice.java   |   14 +-
 .../ui/swt/devices/columns/ColumnTJ_Device.java    |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Duration.java  |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Name.java      |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Profile.java   |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Rank.java      |   13 +-
 .../swt/devices/columns/ColumnTJ_Resolution.java   |    9 +-
 .../ui/swt/devices/columns/ColumnTJ_Status.java    |   23 +-
 .../azureus/ui/swt/extlistener/StimulusRPC.java    |   10 +-
 .../swt/feature/FeatureManagerInstallWindow.java   |  204 +
 .../azureus/ui/swt/feature/FeatureManagerUI.java   |  892 +++
 .../ui/swt/feature/FeatureManagerUIListener.java   |  449 ++
 .../azureus/ui/swt/imageloader/ImageLoader.java    |  455 +-
 .../ui/swt/imageloader/ImageLoaderRefInfo.java     |   24 +
 .../ui/swt/layout/SimpleReorderableListLayout.java |  124 -
 .../layout/SimpleReorderableListLayoutData.java    |   10 -
 com/aelitis/azureus/ui/swt/mdi/BaseMDI.java        |  508 ++
 com/aelitis/azureus/ui/swt/mdi/BaseMdiEntry.java   |  924 ++++
 com/aelitis/azureus/ui/swt/mdi/MdiEntrySWT.java    |   35 +
 .../azureus/ui/swt/mdi/MdiSWTMenuHackListener.java |   34 +
 .../ui/swt/mdi/MultipleDocumentInterfaceSWT.java   |   37 +
 com/aelitis/azureus/ui/swt/mdi/TabbedEntry.java    |  422 ++
 com/aelitis/azureus/ui/swt/mdi/TabbedMDI.java      |  460 ++
 .../azureus/ui/swt/player/PlayerInstallWindow.java |  141 +
 .../azureus/ui/swt/player/PlayerInstaller.java     |  181 +
 .../ui/swt/player/PlayerInstallerListener.java     |    9 +
 .../plugininstall/SimplePluginInstallWindow.java   |  153 +
 .../swt/plugininstall/SimplePluginInstaller.java   |  289 +
 .../SimplePluginInstallerListener.java             |   11 +
 .../ui/swt/search/network/NetworkSearch.java       |   93 -
 .../azureus/ui/swt/shells/AuthorizeWindow.java     |   75 -
 .../azureus/ui/swt/shells/BrowserWindow.java       |    5 +-
 .../azureus/ui/swt/shells/RemotePairingWindow.java |  673 +++
 .../ui/swt/shells/main/DebugMenuHelper.java        |  122 +-
 .../azureus/ui/swt/shells/main/MainHelpers.java    |   59 +
 .../azureus/ui/swt/shells/main/MainMDISetup.java   |  312 ++
 .../azureus/ui/swt/shells/main/MainMenu.java       |  318 +-
 .../azureus/ui/swt/shells/main/MainWindow.java     | 2414 +--------
 .../ui/swt/shells/main/MainWindowDelayStub.java    |  817 +++
 .../ui/swt/shells/main/MainWindowFactory.java      |   90 +
 .../azureus/ui/swt/shells/main/MainWindowImpl.java | 2244 ++++++++
 .../ui/swt/shells/main/UIFunctionsImpl.java        |  696 ++-
 .../ui/swt/shells/uiswitcher/UISwitcherWindow.java |   94 +-
 .../swt/shells/uiswitcher/images/ClassicUI_130.jpg |  Bin 13742 -> 0 bytes
 .../ui/swt/shells/uiswitcher/images/NewUI_130.jpg  |  Bin 16112 -> 0 bytes
 .../azureus/ui/swt/skin/SWTColorWithAlpha.java     |   32 +
 com/aelitis/azureus/ui/swt/skin/SWTSkin.java       |  298 +-
 .../azureus/ui/swt/skin/SWTSkinButtonUtility.java  |   90 +-
 .../azureus/ui/swt/skin/SWTSkinFactory.java        |   23 +-
 com/aelitis/azureus/ui/swt/skin/SWTSkinObject.java |   16 +-
 .../azureus/ui/swt/skin/SWTSkinObjectAdapter.java  |    7 +
 .../azureus/ui/swt/skin/SWTSkinObjectBasic.java    |  280 +-
 .../azureus/ui/swt/skin/SWTSkinObjectBrowser.java  |   25 +-
 .../azureus/ui/swt/skin/SWTSkinObjectButton.java   |   46 +-
 .../azureus/ui/swt/skin/SWTSkinObjectCheckbox.java |   15 +
 .../ui/swt/skin/SWTSkinObjectContainer.java        |  205 +-
 .../azureus/ui/swt/skin/SWTSkinObjectImage.java    |  277 +-
 .../azureus/ui/swt/skin/SWTSkinObjectListener.java |    5 +-
 .../azureus/ui/swt/skin/SWTSkinObjectSash.java     |  381 +-
 .../ui/swt/skin/SWTSkinObjectTabFolder.java        |   69 +
 .../azureus/ui/swt/skin/SWTSkinObjectText.java     |   18 +
 .../azureus/ui/swt/skin/SWTSkinObjectText1.java    |   58 +-
 .../azureus/ui/swt/skin/SWTSkinObjectText2.java    |  222 +-
 .../skin/SWTSkinObjectText_UrlClickedListener.java |   36 +
 .../azureus/ui/swt/skin/SWTSkinObjectTextbox.java  |  251 +
 .../azureus/ui/swt/skin/SWTSkinObjectToggle.java   |  137 +
 .../azureus/ui/swt/skin/SWTSkinProperties.java     |    9 +
 .../ui/swt/skin/SWTSkinPropertiesClone.java        |   29 +-
 .../azureus/ui/swt/skin/SWTSkinPropertiesImpl.java |   31 +-
 .../ui/swt/skin/SWTSkinPropertiesParamImpl.java    |   12 +-
 .../azureus/ui/swt/skin/SWTSkinToggleListener.java |   27 +
 .../ui/swt/subscriptions/SubscriptionMDIEntry.java |  721 +++
 .../swt/subscriptions/SubscriptionManagerUI.java   | 2293 ++------
 .../subscriptions/SubscriptionSelectedContent.java |   57 +-
 .../ui/swt/subscriptions/SubscriptionView.java     |  645 +++
 .../ui/swt/subscriptions/SubscriptionWizard.java   |  410 +-
 .../ui/swt/subscriptions/SubscriptionsView.java    |  221 +-
 .../azureus/ui/swt/toolbar/ToolBarEnabler.java     |    7 -
 .../swt/toolbar/ToolBarEnablerSelectedContent.java |   61 -
 .../azureus/ui/swt/toolbar/ToolBarItem.java        |  161 -
 .../ui/swt/toolbar/ToolBarItemListener.java        |   32 -
 .../azureus/ui/swt/toolbar/ToolBarItemSO.java      |  227 +
 .../azureus/ui/swt/uiupdater/UIUpdaterSWT.java     |   55 +-
 com/aelitis/azureus/ui/swt/utils/ColorCache.java   |  134 +-
 com/aelitis/azureus/ui/swt/utils/ColorCache2.java  |  204 +
 .../azureus/ui/swt/utils/ContentNetworkUI.java     |  138 -
 com/aelitis/azureus/ui/swt/utils/FontUtils.java    |  346 ++
 .../azureus/ui/swt/utils/ImageResizeException.java |   10 -
 com/aelitis/azureus/ui/swt/utils/ImageResizer.java |  612 ---
 com/aelitis/azureus/ui/swt/utils/PlayNowList.java  |   52 -
 .../azureus/ui/swt/utils/TorrentUIUtilsV3.java     |   99 +-
 .../azureus/ui/swt/utils/UIMagnetHandler.java      |   88 +-
 .../azureus/ui/swt/views/PieceGraphView.java       |    5 +-
 com/aelitis/azureus/ui/swt/views/TopBarView.java   |   97 +-
 .../azureus/ui/swt/views/ViewDownSpeedGraph.java   |   53 +-
 .../azureus/ui/swt/views/ViewTitleInfoBetaP.java   |   69 +
 .../azureus/ui/swt/views/ViewUpSpeedGraph.java     |   55 +-
 com/aelitis/azureus/ui/swt/views/skin/Browse.java  |  195 +-
 .../azureus/ui/swt/views/skin/FakeTableCell.java   |  384 --
 .../ui/swt/views/skin/MyTorrentsView_Big.java      |   86 +-
 .../ui/swt/views/skin/SBC_ActivityTableView.java   |  217 +-
 .../ui/swt/views/skin/SBC_ActivityView.java        |   15 +-
 .../azureus/ui/swt/views/skin/SBC_BurnFTUX.java    |  147 +
 .../ui/swt/views/skin/SBC_GenericBrowsePage.java   |  107 +
 .../ui/swt/views/skin/SBC_LibraryTableView.java    |  343 +-
 .../swt/views/skin/SBC_LibraryTableView_Big.java   |    1 +
 .../azureus/ui/swt/views/skin/SBC_LibraryView.java |  978 ++--
 .../azureus/ui/swt/views/skin/SBC_PlusFTUX.java    |  148 +
 .../azureus/ui/swt/views/skin/SB_Transfers.java    |  995 ++++
 com/aelitis/azureus/ui/swt/views/skin/SB_Vuze.java |  135 +
 .../ui/swt/views/skin/SearchResultsTabArea.java    |  269 +-
 .../azureus/ui/swt/views/skin/SkinView.java        |   21 +-
 .../azureus/ui/swt/views/skin/SkinViewManager.java |   41 +-
 .../azureus/ui/swt/views/skin/SkinnedDialog.java   |   69 +-
 .../azureus/ui/swt/views/skin/ToolBarView.java     | 1366 +++--
 .../ui/swt/views/skin/TorrentListViewsUtils.java   | 1087 ++--
 .../azureus/ui/swt/views/skin/VuzeMessageBox.java  |  577 ++
 .../ui/swt/views/skin/VuzeMessageBoxListener.java  |   10 +
 .../azureus/ui/swt/views/skin/WelcomeView.java     |   57 +-
 .../azureus/ui/swt/views/skin/sidebar/SideBar.java | 3105 +++--------
 .../ui/swt/views/skin/sidebar/SideBarEntrySWT.java | 1298 +++--
 .../ui/swt/views/skin/sidebar/SideBarListener.java |   37 -
 .../views/skin/sidebar/SideBarLogIdListener.java   |   30 -
 .../ui/swt/views/skin/sidebar/SideBarToolTips.java |   45 +-
 .../skin/sidebar/SideBarVitalityImageSWT.java      |  215 +-
 com/aelitis/azureus/util/Constants.java            |   35 -
 com/aelitis/azureus/util/ConstantsV3.java          |   42 -
 com/aelitis/azureus/util/ContentNetworkUtils.java  |   50 -
 com/aelitis/azureus/util/DataSourceUtils.java      |  104 +-
 com/aelitis/azureus/util/ImportExportUtils.java    |    6 +
 .../azureus/util/InitialisationFunctions.java      |  209 +-
 com/aelitis/azureus/util/PlayUtils.java            |  423 +-
 com/aelitis/azureus/util/UrlFilter.java            |    4 +
 com/aelitis/azureus/util/win32/Win32Utils.java     |   49 -
 .../MagnetURIHandlerProgressListener.java          |    3 +
 .../net/magneturi/impl/MagnetURIHandlerImpl.java   |  126 +-
 .../natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java |   19 +-
 com/aelitis/net/udp/mc/MCGroup.java                |    9 +-
 com/aelitis/net/udp/mc/impl/MCGroupImpl.java       |  109 +-
 com/aelitis/net/udp/uc/PRUDPPacketHandler.java     |   20 +-
 .../udp/uc/impl/PRUDPPacketHandlerFactoryImpl.java |    4 +-
 .../net/udp/uc/impl/PRUDPPacketHandlerImpl.java    |  291 +-
 .../net/udp/uc/impl/PRUDPPacketHandlerSocks.java   |  547 ++
 com/aelitis/net/upnp/UPnP.java                     |    3 +
 com/aelitis/net/upnp/UPnPDevice.java               |    3 +
 com/aelitis/net/upnp/UPnPDeviceImage.java          |    9 +
 com/aelitis/net/upnp/UPnPService.java              |    3 +
 com/aelitis/net/upnp/impl/SSDPIGD.java             |    3 +
 com/aelitis/net/upnp/impl/UPnPImpl.java            |    6 +
 .../net/upnp/impl/device/UPnPDeviceImageImpl.java  |   38 +
 .../net/upnp/impl/device/UPnPDeviceImpl.java       |   37 +
 .../net/upnp/impl/device/UPnPRootDeviceImpl.java   |    2 +-
 .../impl/services/UPnPSSOfflineDownloaderImpl.java |   44 +
 .../net/upnp/impl/services/UPnPServiceImpl.java    |   35 +
 com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java    |   17 +-
 .../net/upnp/services/UPnPOfflineDownloader.java   |   10 +
 org/apache/commons/lang/Entities.java              |   19 +-
 org/eclipse/swt/widgets/Tree2.java                 |  150 +
 org/gudy/azureus2/core3/category/Category.java     |   35 +-
 .../core3/category/CategoryManagerListener.java    |    4 +
 .../azureus2/core3/category/impl/CategoryImpl.java |  158 +-
 .../core3/category/impl/CategoryManagerImpl.java   |  381 +-
 .../core3/config/COConfigurationManager.java       |  122 +-
 .../core3/config/PriorityParameterListener.java    |   36 +
 .../core3/config/impl/ConfigurationChecker.java    |  167 +-
 .../core3/config/impl/ConfigurationDefaults.java   |   77 +-
 .../core3/config/impl/ConfigurationManager.java    |  276 +-
 .../core3/config/impl/TransferSpeedValidator.java  |   10 +-
 org/gudy/azureus2/core3/disk/DiskManager.java      |   44 +-
 .../core3/disk/DiskManagerCheckRequest.java        |    7 +
 .../azureus2/core3/disk/DiskManagerFactory.java    |    3 +-
 .../azureus2/core3/disk/DiskManagerFileInfo.java   |   14 +-
 .../core3/disk/DiskManagerFileInfoSet.java         |    2 +-
 .../core3/disk/impl/DiskManagerFileInfoImpl.java   |   37 +-
 .../disk/impl/DiskManagerFileInfoSetImpl.java      |   66 +-
 .../azureus2/core3/disk/impl/DiskManagerImpl.java  | 2112 ++++----
 .../azureus2/core3/disk/impl/DiskManagerUtil.java  | 1023 +++-
 .../core3/disk/impl/access/impl/DMCheckerImpl.java |  233 +-
 .../access/impl/DiskManagerCheckRequestImpl.java   |   15 +
 .../core3/disk/impl/resume/RDResumeHandler.java    |  188 +-
 .../azureus2/core3/download/DownloadManager.java   |   28 +-
 .../core3/download/DownloadManagerState.java       |   23 +-
 .../core3/download/DownloadManagerStats.java       |    7 +-
 .../core3/download/DownloadManagerTPSListener.java |   29 +
 .../download/impl/DownloadManagerController.java   |  446 +-
 .../download/impl/DownloadManagerDefaultPaths.java |   18 +-
 .../core3/download/impl/DownloadManagerImpl.java   | 1100 +++-
 .../download/impl/DownloadManagerMoveHandler.java  |   17 +-
 .../impl/DownloadManagerRateController.java        |  667 +++
 .../download/impl/DownloadManagerStateImpl.java    |  227 +-
 .../download/impl/DownloadManagerStatsImpl.java    |   68 +-
 org/gudy/azureus2/core3/global/GlobalManager.java  |   28 +-
 .../azureus2/core3/global/GlobalManagerEvent.java  |   36 +
 .../core3/global/GlobalManagerEventListener.java   |   30 +
 .../core3/global/impl/GlobalManagerImpl.java       |  461 +-
 org/gudy/azureus2/core3/html/HTMLChunk.java        |    6 -
 org/gudy/azureus2/core3/html/HTMLPage.java         |    4 +
 org/gudy/azureus2/core3/html/HTMLTable.java        |   36 -
 org/gudy/azureus2/core3/html/HTMLTableCell.java    |   35 -
 org/gudy/azureus2/core3/html/HTMLTableRow.java     |   35 -
 org/gudy/azureus2/core3/html/HTMLUtils.java        |    7 +-
 .../azureus2/core3/html/impl/HTMLChunkImpl.java    |  174 +-
 .../azureus2/core3/html/impl/HTMLPageImpl.java     |   36 +-
 .../core3/html/impl/HTMLTableCellImpl.java         |   51 -
 .../azureus2/core3/html/impl/HTMLTableImpl.java    |   58 -
 .../azureus2/core3/html/impl/HTMLTableRowImpl.java |   58 -
 .../core3/internat/IntegratedResourceBundle.java   |  145 +-
 .../azureus2/core3/internat/LocaleTorrentUtil.java |    9 +-
 org/gudy/azureus2/core3/internat/MessageText.java  |   42 +-
 .../core3/ipchecker/natchecker/NatChecker.java     |   23 +
 .../ipchecker/natchecker/NatCheckerServer.java     |    4 +-
 org/gudy/azureus2/core3/ipfilter/IpFilter.java     |   11 +
 .../azureus2/core3/ipfilter/impl/IpFilterImpl.java |   75 +-
 org/gudy/azureus2/core3/logging/LogAlert.java      |    5 +-
 .../azureus2/core3/logging/impl/LoggerImpl.java    |   14 +
 org/gudy/azureus2/core3/peer/PEPeer.java           |   40 +-
 org/gudy/azureus2/core3/peer/PEPeerManager.java    |   43 +-
 .../azureus2/core3/peer/PEPeerManagerAdapter.java  |   26 +
 .../azureus2/core3/peer/PEPeerManagerListener.java |   11 +
 .../azureus2/core3/peer/PEPeerManagerStats.java    |   11 +
 org/gudy/azureus2/core3/peer/PEPeerStats.java      |    9 +
 org/gudy/azureus2/core3/peer/PEPiece.java          |    2 +-
 .../azureus2/core3/peer/impl/PEPeerControl.java    |   19 +
 .../core3/peer/impl/PEPeerManagerStatsImpl.java    |   55 +-
 .../azureus2/core3/peer/impl/PEPeerStatsImpl.java  |   37 +
 .../azureus2/core3/peer/impl/PEPeerTransport.java  |   11 +
 org/gudy/azureus2/core3/peer/impl/PEPieceImpl.java |  122 +-
 .../core3/peer/impl/control/PEPeerControlImpl.java |  658 ++-
 .../core3/peer/impl/control/SuperSeedPiece.java    |   39 +-
 .../impl/transport/PEPeerTransportProtocol.java    | 1946 +++++--
 .../azureus2/core3/security/SESecurityManager.java |    6 +
 .../core3/security/impl/SESecurityManagerImpl.java |  241 +-
 org/gudy/azureus2/core3/torrent/TOTorrent.java     |   18 +
 .../azureus2/core3/torrent/TOTorrentCreator.java   |   18 +
 .../azureus2/core3/torrent/TOTorrentFactory.java   |   15 +-
 .../azureus2/core3/torrent/TOTorrentListener.java  |   33 +
 .../impl/TOTorrentAnnounceURLGroupImpl.java        |    4 +
 .../core3/torrent/impl/TOTorrentCreateImpl.java    |  227 +-
 .../core3/torrent/impl/TOTorrentCreatorImpl.java   |  476 +-
 .../torrent/impl/TOTorrentDeserialiseImpl.java     |   86 +-
 .../core3/torrent/impl/TOTorrentFileImpl.java      |   62 +-
 .../azureus2/core3/torrent/impl/TOTorrentImpl.java |  110 +-
 org/gudy/azureus2/core3/torrent/test/Main.java     |  193 -
 .../TorrentDownloaderFactory.java                  |  307 +-
 .../impl/TorrentDownloaderImpl.java                |  606 ++-
 .../core3/tracker/client/TRTrackerAnnouncer.java   |   29 +-
 .../client/TRTrackerAnnouncerDataProvider.java     |    6 +
 .../client/TRTrackerAnnouncerResponsePeer.java     |    4 +
 .../core3/tracker/client/TRTrackerScraper.java     |    7 +
 .../tracker/client/TRTrackerScraperResponse.java   |    3 +
 .../client/impl/TRTrackerAnnouncerHelper.java      |   49 +
 .../client/impl/TRTrackerAnnouncerImpl.java        |  142 +-
 .../client/impl/TRTrackerAnnouncerMuxer.java       | 1603 +++++-
 .../impl/TRTrackerAnnouncerResponseImpl.java       |   27 +-
 .../impl/TRTrackerAnnouncerResponsePeerImpl.java   |   15 +
 .../tracker/client/impl/TRTrackerScraperImpl.java  |   20 +
 .../client/impl/TRTrackerScraperResponseImpl.java  |    3 +
 .../client/impl/bt/TRTrackerBTAnnouncerImpl.java   |  742 ++-
 .../client/impl/bt/TRTrackerBTScraperImpl.java     |   40 +-
 .../impl/bt/TRTrackerBTScraperResponseImpl.java    |   85 +-
 .../tracker/client/impl/bt/TrackerChecker.java     |   35 +
 .../tracker/client/impl/bt/TrackerStatus.java      |  644 ++-
 .../client/impl/dht/TRTrackerDHTAnnouncerImpl.java |  120 +-
 .../client/impl/dht/TRTrackerDHTScraperImpl.java   |   21 +
 .../impl/dht/TRTrackerDHTScraperResponseImpl.java  |   13 +
 org/gudy/azureus2/core3/tracker/host/TRHost.java   |    5 +
 .../tracker/host/TRHostAuthenticationListener.java |    1 +
 .../tracker/host/impl/TRHostExternalTorrent.java   |   22 +
 .../core3/tracker/host/impl/TRHostImpl.java        |    9 +-
 .../protocol/udp/PRUDPPacketRequestAnnounce.java   |    4 +-
 .../protocol/udp/PRUDPPacketRequestAnnounce2.java  |    4 +-
 .../protocol/udp/PRUDPPacketRequestScrape.java     |    2 +-
 .../core3/tracker/server/TRTrackerServer.java      |    6 +-
 .../TRTrackerServerAuthenticationListener.java     |    1 +
 .../tracker/server/impl/TRTrackerServerImpl.java   |   13 +-
 .../server/impl/dht/TRTrackerServerDHT.java        |    8 +
 .../impl/tcp/TRTrackerServerProcessorTCP.java      |   37 +-
 .../server/impl/tcp/TRTrackerServerTCP.java        |    2 +-
 .../server/impl/tcp/blocking/TRBlockingServer.java |   21 +-
 .../tcp/blocking/TRBlockingServerProcessor.java    |   28 +-
 .../impl/tcp/nonblocking/TRNonBlockingServer.java  |   12 +
 .../impl/udp/TRTrackerServerProcessorUDP.java      |  129 +-
 .../server/impl/udp/TRTrackerServerUDP.java        |   11 +-
 org/gudy/azureus2/core3/util/AEDiagnostics.java    |   25 +-
 .../azureus2/core3/util/AEDiagnosticsLogger.java   |   23 +-
 .../azureus2/core3/util/AEGenericCallback.java     |    9 +
 org/gudy/azureus2/core3/util/AEMemoryMonitor.java  |  356 ++
 .../azureus2/core3/util/AERunStateHandler.java     |  156 +
 org/gudy/azureus2/core3/util/AERunnableObject.java |    2 +-
 .../core3/util/AETemporaryFileHandler.java         |   30 +
 org/gudy/azureus2/core3/util/AEThread2.java        |   14 +-
 org/gudy/azureus2/core3/util/AddressUtils.java     |    3 +
 org/gudy/azureus2/core3/util/AsyncDispatcher.java  |   78 +-
 org/gudy/azureus2/core3/util/BDecoder.java         |  333 +-
 org/gudy/azureus2/core3/util/BEncoder.java         |   44 +-
 org/gudy/azureus2/core3/util/BrokenMd5Hasher.java  |    4 +-
 org/gudy/azureus2/core3/util/ByteFormatter.java    |   26 +
 org/gudy/azureus2/core3/util/Constants.java        |  176 +-
 org/gudy/azureus2/core3/util/Debug.java            |   99 +-
 org/gudy/azureus2/core3/util/DirectByteBuffer.java |   38 +-
 .../core3/util/DirectByteBufferPoolReal.java       |   67 +-
 .../azureus2/core3/util/DisplayFormatters.java     |  172 +-
 org/gudy/azureus2/core3/util/FileUtil.java         |  218 +-
 .../core3/util/FrequencyLimitedDispatcher.java     |   55 +-
 org/gudy/azureus2/core3/util/IndentWriter.java     |   31 +-
 org/gudy/azureus2/core3/util/LightHashMapEx.java   |   64 +
 org/gudy/azureus2/core3/util/ListenerManager.java  |   12 +
 org/gudy/azureus2/core3/util/MD5.java              |  370 --
 org/gudy/azureus2/core3/util/RARTOCDecoder.java    |  462 ++
 org/gudy/azureus2/core3/util/RandomUtils.java      |   45 +-
 .../azureus2/core3/util/ShellUtilityFinder.java    |   30 +
 org/gudy/azureus2/core3/util/StringInterner.java   |  136 +-
 org/gudy/azureus2/core3/util/SystemProperties.java |   38 +-
 org/gudy/azureus2/core3/util/SystemTime.java       |   14 +-
 org/gudy/azureus2/core3/util/ThreadPool.java       |  100 +-
 org/gudy/azureus2/core3/util/TimeFormatter.java    |   43 +
 org/gudy/azureus2/core3/util/TimerEvent.java       |   10 +
 org/gudy/azureus2/core3/util/TorrentUtils.java     | 1212 ++++-
 org/gudy/azureus2/core3/util/UrlUtils.java         |  267 +-
 org/gudy/azureus2/core3/util/jar/Test.java         |   71 -
 .../azureus2/core3/util/protocol/bc/Handler.java   |   82 +
 .../azureus2/core3/util/protocol/vuze/Handler.java |   41 +
 .../util/protocol/vuze/VuzeURLConnection.java      |  166 +
 .../core3/util/test/Md5AlgorithmHelper.java        |  181 -
 org/gudy/azureus2/core3/util/test/SHA1Old.java     |  475 --
 .../azureus2/core3/util/test/SHA1SpeedTest.java    |  227 -
 .../azureus2/core3/util/test/SHA1Verification.java |  143 -
 .../core3/util/test/Sha1AlgorithmHelper.java       |  150 -
 .../core3/util/test/SystemClockSpeedup.java        |   58 -
 .../azureus2/core3/xml/util/XMLEscapeWriter.java   |   59 +
 .../azureus2/internat/MessagesBundle.properties    |  907 +++-
 .../internat/MessagesBundle_ar_SA.properties       |    7 -
 .../internat/MessagesBundle_bg_BG.properties       |  718 ++-
 .../internat/MessagesBundle_bs_BA.properties       |   12 -
 .../internat/MessagesBundle_ca_AD.properties       | 2810 +++++++---
 .../internat/MessagesBundle_cs_CZ.properties       | 3619 +++++++++----
 .../internat/MessagesBundle_da_DK.properties       |  309 +-
 .../internat/MessagesBundle_de_DE.properties       |  261 +-
 .../internat/MessagesBundle_el_GR.properties       |    9 -
 .../MessagesBundle_en_US_classic.properties        |    6 +
 .../internat/MessagesBundle_es_ES.properties       |   40 +-
 .../azureus2/internat/MessagesBundle_eu.properties | 3618 +++++++++++--
 .../internat/MessagesBundle_fi_FI.properties       | 5687 ++++++++++----------
 .../internat/MessagesBundle_fr_FR.properties       |  118 +-
 .../internat/MessagesBundle_fy_NL.properties       |   18 -
 .../internat/MessagesBundle_gl_ES.properties       |    7 -
 .../internat/MessagesBundle_hu_HU.properties       |   39 +-
 .../internat/MessagesBundle_in_ID.properties       |   15 -
 .../internat/MessagesBundle_it_IT.properties       |  154 +-
 .../internat/MessagesBundle_iw_IL.properties       |    9 -
 .../internat/MessagesBundle_ja_JP.properties       |   36 -
 .../internat/MessagesBundle_ka_GE.properties       |   15 +-
 .../internat/MessagesBundle_ko_KR.properties       | 4350 +++++++++------
 .../internat/MessagesBundle_li_NL.properties       |   35 +-
 .../internat/MessagesBundle_lt_LT.properties       |   25 +-
 .../internat/MessagesBundle_mk_MK.properties       |    8 -
 .../internat/MessagesBundle_ms_SG.properties       |    7 -
 .../internat/MessagesBundle_nl_NL.properties       |   34 +-
 .../internat/MessagesBundle_no_NO.properties       |   26 +-
 .../internat/MessagesBundle_pl_PL.properties       |   53 +-
 .../internat/MessagesBundle_pt_BR.properties       |   50 +-
 .../internat/MessagesBundle_pt_PT.properties       |   19 -
 .../internat/MessagesBundle_ro_RO.properties       | 1674 +++---
 .../internat/MessagesBundle_ru_RU.properties       | 4773 +++++++++-------
 .../internat/MessagesBundle_sk_SK.properties       |   21 +-
 .../internat/MessagesBundle_sl_SI.properties       |   10 -
 .../azureus2/internat/MessagesBundle_sr.properties |   26 +-
 .../internat/MessagesBundle_sr_Latin.properties    |   26 +-
 .../internat/MessagesBundle_sv_SE.properties       |   42 +-
 .../internat/MessagesBundle_th_TH.properties       |   18 -
 .../internat/MessagesBundle_tr_TR.properties       |   20 +-
 .../internat/MessagesBundle_uk_UA.properties       |   55 +-
 .../internat/MessagesBundle_zh_CN.properties       |   50 +-
 .../internat/MessagesBundle_zh_TW.properties       |   21 +-
 org/gudy/azureus2/platform/JavaBitMode.java        |   13 +
 org/gudy/azureus2/platform/PlatformManager.java    |   84 +-
 .../platform/PlatformManagerCapabilities.java      |    8 +-
 .../azureus2/platform/PlatformManagerListener.java |    4 +-
 .../platform/PlatformManagerPluginDelegate.java    |   10 +
 .../platform/dummy/PlatformManagerImpl.java        |   90 +
 .../platform/macosx/NativeInvocationBridge.java    |    5 +-
 org/gudy/azureus2/platform/macosx/PListEditor.java |   81 +-
 .../platform/macosx/PlatformManagerImpl.java       |  886 ++-
 .../macosx/PlatformManagerUpdateChecker.java       |   17 +-
 .../macosx/access/cocoa/CocoaJavaBridge.java       |  271 +-
 .../platform/macosx/access/jnilib/OSXAccess.java   |   24 +-
 .../platform/unix/PlatformManagerImpl.java         |   90 +
 org/gudy/azureus2/platform/unix/startupScript      |   18 +-
 .../platform/win32/PlatformManagerImpl.java        | 1126 +++-
 .../win32/PlatformManagerUpdateChecker.java        |   18 +-
 .../platform/win32/access/AEWin32Access.java       |   24 +-
 .../win32/access/AEWin32AccessListener.java        |    4 +-
 .../win32/access/impl/AEWin32AccessImpl.java       |  141 +-
 .../win32/access/impl/AEWin32AccessInterface.java  |   18 +-
 .../azureus2/platform/win32/access/impl/StdAfx.cpp |    8 -
 .../azureus2/platform/win32/access/impl/StdAfx.h   |   24 -
 .../azureus2/platform/win32/access/impl/Test.java  |  172 -
 .../platform/win32/access/impl/aedevice.cpp        |  198 -
 .../azureus2/platform/win32/access/impl/aenet.cpp  |  781 ---
 .../azureus2/platform/win32/access/impl/aenet.h    |  102 -
 .../azureus2/platform/win32/access/impl/aereg.cpp  | 2115 --------
 .../azureus2/platform/win32/access/impl/aereg.dsp  |  136 -
 .../azureus2/platform/win32/access/impl/aereg.dsw  |   29 -
 .../azureus2/platform/win32/access/impl/aereg.h    |   41 -
 .../azureus2/platform/win32/access/impl/aereg.sln  |   20 -
 .../azureus2/platform/win32/access/impl/aereg.suo  |  Bin 34816 -> 0 bytes
 .../platform/win32/access/impl/aereg.vcproj        |  327 --
 .../platform/win32/access/impl/generate_ini.bat    |    1 -
 ...form_win32_access_impl_AEWin32AccessInterface.h |  177 -
 org/gudy/azureus2/plugins/PluginConfig.java        |   15 +-
 org/gudy/azureus2/plugins/PluginEvent.java         |    4 +
 org/gudy/azureus2/plugins/PluginInterface.java     |   20 +-
 org/gudy/azureus2/plugins/PluginState.java         |    2 +
 org/gudy/azureus2/plugins/PluginView.java          |   41 -
 .../plugins/clientid/ClientIDGenerator.java        |    1 +
 .../azureus2/plugins/ddb/DistributedDatabase.java  |   13 +
 .../plugins/ddb/DistributedDatabaseContact.java    |    6 +
 org/gudy/azureus2/plugins/disk/DiskManager.java    |   31 +
 .../azureus2/plugins/disk/DiskManagerChannel.java  |    6 +
 .../azureus2/plugins/disk/DiskManagerEvent.java    |    5 +-
 .../plugins/disk/DiskManagerException.java         |   48 +
 .../azureus2/plugins/disk/DiskManagerFileInfo.java |   53 +-
 .../plugins/disk/DiskManagerRandomReadRequest.java |   41 +
 .../plugins/disk/DiskManagerReadRequest.java       |   35 +
 .../disk/DiskManagerReadRequestListener.java       |   38 +
 .../azureus2/plugins/disk/DiskManagerRequest.java  |    5 +
 .../plugins/disk/DiskManagerWriteRequest.java      |   35 +
 .../disk/DiskManagerWriteRequestListener.java      |   35 +
 org/gudy/azureus2/plugins/download/Download.java   |   68 +-
 .../azureus2/plugins/download/DownloadManager.java |   18 +
 .../azureus2/plugins/download/DownloadStats.java   |    9 +
 .../savelocation/DefaultSaveLocationManager.java   |    1 +
 .../plugins/installer/PluginInstaller.java         |    9 +-
 .../azureus2/plugins/logging/LoggerChannel.java    |   15 +
 .../messaging/bittorrent/BTMessageManager.java     |   25 +-
 .../plugins/network/ConnectionManager.java         |    9 +
 .../azureus2/plugins/network/ConnectionStub.java   |   36 +
 .../plugins/network/IncomingMessageQueue.java      |    6 +
 .../plugins/network/OutgoingMessageQueue.java      |    6 +
 org/gudy/azureus2/plugins/network/RateLimiter.java |   10 +-
 org/gudy/azureus2/plugins/package.html             |    8 -
 org/gudy/azureus2/plugins/peers/Peer.java          |   25 +-
 .../azureus2/plugins/peers/PeerDescriptor.java     |    8 +
 .../azureus2/plugins/peers/PeerManagerEvent.java   |    3 +
 .../azureus2/plugins/peers/PeerManagerStats.java   |   48 +
 .../azureus2/plugins/peers/PeerReadRequest.java    |    4 +-
 org/gudy/azureus2/plugins/peers/PeerStats.java     |   64 +-
 org/gudy/azureus2/plugins/peers/Piece.java         |   23 +
 .../azureus2/plugins/sharing/ShareManager.java     |   25 +
 .../tracker/web/TrackerAuthenticationAdapter.java  |   18 +
 .../plugins/tracker/web/TrackerWebContext.java     |    4 +
 org/gudy/azureus2/plugins/ui/SWT/GraphicSWT.java   |   48 -
 org/gudy/azureus2/plugins/ui/SWT/SWTManager.java   |   89 -
 .../azureus2/plugins/ui/UIDataSourceListener.java  |   11 +
 org/gudy/azureus2/plugins/ui/UIInputReceiver.java  |    7 +
 org/gudy/azureus2/plugins/ui/UIInstance.java       |    3 +
 org/gudy/azureus2/plugins/ui/UIManager.java        |   51 +-
 org/gudy/azureus2/plugins/ui/UIPluginView.java     |   20 +
 .../plugins/ui/UIPluginViewToolBarListener.java    |   23 +
 .../plugins/ui/config/PasswordParameter.java       |    4 +
 .../azureus2/plugins/ui/model/PluginViewModel.java |    5 +
 .../plugins/ui/sidebar/SideBarCloseListener.java   |   30 -
 .../plugins/ui/sidebar/SideBarDropListener.java    |   34 -
 .../azureus2/plugins/ui/sidebar/SideBarEntry.java  |   72 -
 .../plugins/ui/sidebar/SideBarOpenListener.java    |   29 -
 .../plugins/ui/sidebar/SideBarVitalityImage.java   |   47 -
 .../ui/sidebar/SideBarVitalityImageListener.java   |   29 -
 org/gudy/azureus2/plugins/ui/tables/TableCell.java |    7 +
 .../ui/tables/TableCellClipboardListener.java      |   24 +
 .../plugins/ui/tables/TableCellRefresher.java      |   10 +-
 .../azureus2/plugins/ui/tables/TableColumn.java    |   25 +
 .../azureus2/plugins/ui/tables/TableManager.java   |    4 +
 org/gudy/azureus2/plugins/ui/tables/TableRow.java  |   21 +
 org/gudy/azureus2/plugins/ui/tables/package.html   |   10 -
 .../ui/toolbar/UIToolBarActivationListener.java    |   12 +
 .../plugins/ui/toolbar/UIToolBarEnablerBase.java   |    8 +
 .../azureus2/plugins/ui/toolbar/UIToolBarItem.java |   60 +
 .../plugins/ui/toolbar/UIToolBarManager.java       |   29 +
 org/gudy/azureus2/plugins/update/Update.java       |    6 +-
 .../plugins/update/UpdateCheckInstance.java        |    4 +
 .../azureus2/plugins/update/UpdateInstaller.java   |   14 +
 .../plugins/update/UpdateInstallerListener.java    |   37 +
 .../azureus2/plugins/update/UpdateManager.java     |    3 +
 .../azureus2/plugins/utils/ByteArrayWrapper.java   |    3 +
 .../azureus2/plugins/utils/FeatureManager.java     |  234 +
 .../plugins/utils/PowerManagementListener.java     |   41 +
 org/gudy/azureus2/plugins/utils/Utilities.java     |   34 +-
 .../resourcedownloader/ResourceDownloader.java     |    3 +
 .../ResourceDownloaderCancelledException.java      |   14 +-
 .../ResourceDownloaderException.java               |   12 +-
 .../plugins/utils/subscriptions/Subscription.java  |    3 +
 .../pluginsimpl/local/PluginConfigImpl.java        |    5 +-
 .../pluginsimpl/local/PluginCoreUtils.java         |  243 +-
 .../pluginsimpl/local/PluginInitializer.java       | 1408 +++--
 .../pluginsimpl/local/PluginInterfaceImpl.java     |  328 +-
 .../pluginsimpl/local/PluginStateImpl.java         |   21 +-
 .../local/clientid/ClientIDManagerImpl.java        |   40 +-
 .../pluginsimpl/local/ddb/DDBaseContactImpl.java   |   17 +-
 .../azureus2/pluginsimpl/local/ddb/DDBaseImpl.java |   29 +-
 .../local/deprecate/PluginDeprecation.java         |    6 +-
 .../local/disk/DiskManagerChannelImpl.java         |  169 +-
 .../local/disk/DiskManagerFileInfoImpl.java        |   90 +-
 .../pluginsimpl/local/disk/DiskManagerImpl.java    |  193 +
 .../disk/DiskManagerRandomReadController.java      |  847 +++
 .../pluginsimpl/local/download/DownloadImpl.java   |  395 +-
 .../local/download/DownloadManagerImpl.java        |   49 +-
 .../local/download/DownloadStatsImpl.java          |    8 +
 .../local/installer/PluginInstallerImpl.java       |  249 +-
 .../azureus2/pluginsimpl/local/installer/Test.java |  142 -
 .../local/launch/PluginLauncherImpl.java           |   96 +-
 .../local/logging/LoggerChannelImpl.java           |   35 +-
 .../messaging/GenericMessageConnectionDirect.java  |   64 +-
 .../messaging/GenericMessageEndpointImpl.java      |    5 +-
 .../local/messaging/MessageManagerImpl.java        |    4 +-
 .../pluginsimpl/local/network/ConnectionImpl.java  |    4 +-
 .../local/network/ConnectionManagerImpl.java       |   50 +-
 .../local/network/IncomingMessageQueueImpl.java    |   29 +-
 .../local/network/OutgoingMessageQueueImpl.java    |   18 +
 .../local/peers/PeerForeignDelegate.java           |  149 +-
 .../local/peers/PeerForeignNetworkConnection.java  |   30 +
 .../azureus2/pluginsimpl/local/peers/PeerImpl.java |   26 +-
 .../pluginsimpl/local/peers/PeerManagerImpl.java   |  436 +-
 .../local/peers/PeerManagerStatsImpl.java          |   25 +
 .../pluginsimpl/local/peers/PeerStatsImpl.java     |   58 +
 .../local/sharing/ShareManagerImpl.java            |   80 +-
 .../sharing/ShareResourceDirContentsImpl.java      |   21 +-
 .../local/sharing/ShareResourceDirImpl.java        |    5 +-
 .../local/sharing/ShareResourceFileImpl.java       |    5 +-
 .../local/sharing/ShareResourceFileOrDirImpl.java  |   46 +-
 .../local/sharing/test/ShareTester.java            |  292 -
 org/gudy/azureus2/pluginsimpl/local/test/Test.java |  706 ---
 .../torrent/TorrentAttributeCategoryImpl.java      |    3 +
 .../local/torrent/TorrentDownloaderImpl.java       |   29 +-
 .../pluginsimpl/local/torrent/TorrentImpl.java     |    3 +-
 .../pluginsimpl/local/tracker/TrackerImpl.java     |   22 +-
 .../local/tracker/TrackerWebContextImpl.java       |   22 +-
 .../local/ui/AbstractUIInputReceiver.java          |    4 +
 .../pluginsimpl/local/ui/SWT/GraphicSWTImpl.java   |   50 -
 .../pluginsimpl/local/ui/SWT/SWTManagerImpl.java   |  166 -
 .../pluginsimpl/local/ui/UIManagerImpl.java        |  281 +-
 .../local/ui/config/ConfigSectionHolder.java       |   77 +
 .../local/ui/config/ConfigSectionRepository.java   |   27 +-
 .../local/ui/config/PasswordParameterImpl.java     |   96 +-
 .../pluginsimpl/local/ui/menus/MenuItemImpl.java   |   21 +-
 .../local/ui/model/BasicPluginConfigModelImpl.java |    5 +
 .../local/ui/model/BasicPluginViewModelImpl.java   |    7 +
 .../azureus2/pluginsimpl/local/update/Test.java    |  133 -
 .../local/update/UpdateCheckInstanceImpl.java      |  290 +-
 .../pluginsimpl/local/update/UpdateImpl.java       |   20 +-
 .../local/update/UpdateInstallerImpl.java          |  230 +-
 .../local/update/UpdateManagerImpl.java            |   46 +-
 .../pluginsimpl/local/utils/UtilitiesImpl.java     |  619 ++-
 .../ResourceDownloaderAlternateImpl.java           |    6 +-
 .../ResourceDownloaderBaseImpl.java                |   79 +-
 .../ResourceDownloaderFileImpl.java                |    4 +-
 .../ResourceDownloaderMetaRefreshImpl.java         |   16 +-
 .../ResourceDownloaderRetryImpl.java               |    2 +-
 .../ResourceDownloaderTimeoutImpl.java             |    6 +-
 .../ResourceDownloaderTorrentImpl.java             |   85 +-
 .../ResourceDownloaderURLImpl.java                 |  256 +-
 .../local/utils/resourcedownloader/Test.java       |  238 -
 .../pluginsimpl/local/utils/xml/rss/RSSUtils.java  |   31 +-
 .../pluginsimpl/local/utils/xml/rss/Test.java      |  142 -
 .../simpleparser/SimpleXMLParserDocumentImpl.java  |   34 +-
 .../pluginsimpl/remote/RPPluginInterface.java      |   13 +-
 .../remote/disk/RPDiskManagerFileInfo.java         |   44 +
 .../pluginsimpl/remote/download/RPDownload.java    |   50 +
 .../remote/download/RPDownloadManager.java         |   19 +
 .../remote/download/RPDownloadStats.java           |    8 +
 .../pluginsimpl/remote/tracker/RPTracker.java      |    8 +
 .../pluginsimpl/update/PluginUpdatePlugin.java     |  519 +-
 .../update/sf/impl2/SFPluginDetailsLoaderImpl.java |  258 +-
 .../azureus2/pluginsimpl/update/sf/impl2/Test.java |   59 -
 org/gudy/azureus2/ui/common/UIInstanceBase.java    |   18 +
 .../azureus2/ui/common/util/MenuItemManager.java   |   75 +-
 .../ui/common/util/MenuItemManagerListener.java    |   33 +
 org/gudy/azureus2/ui/common/util/UserAlerts.java   |   52 +-
 org/gudy/azureus2/ui/console/ConsoleInput.java     |   36 +-
 org/gudy/azureus2/ui/console/UI.java               |   21 +-
 org/gudy/azureus2/ui/console/commands/Hack.java    |    6 +-
 .../azureus2/ui/console/commands/Priority.java     |   18 +-
 org/gudy/azureus2/ui/console/commands/Show.java    |    2 +-
 org/gudy/azureus2/ui/icons/aligncentre.png         |  Bin 0 -> 503 bytes
 org/gudy/azureus2/ui/icons/alignleft.png           |  Bin 0 -> 483 bytes
 org/gudy/azureus2/ui/icons/alignright.png          |  Bin 0 -> 495 bytes
 org/gudy/azureus2/ui/icons/blackdot.gif            |  Bin 0 -> 830 bytes
 org/gudy/azureus2/ui/icons/blackdot.png            |  Bin 0 -> 211 bytes
 org/gudy/azureus2/ui/icons/blacktick.gif           |  Bin 0 -> 835 bytes
 org/gudy/azureus2/ui/icons/btn_add_rss.png         |  Bin 1058 -> 0 bytes
 org/gudy/azureus2/ui/icons/btn_all_rss.png         |  Bin 1207 -> 0 bytes
 org/gudy/azureus2/ui/icons/btn_rss_gray_bud.png    |  Bin 594 -> 0 bytes
 org/gudy/azureus2/ui/icons/btn_rss_green_bud.png   |  Bin 600 -> 0 bytes
 org/gudy/azureus2/ui/icons/btn_rss_orange_bud.png  |  Bin 612 -> 0 bytes
 .../ui/icons/btn_rss_subscribe_green_30x14.png     |  Bin 1092 -> 0 bytes
 .../ui/icons/btn_rss_subscribe_orange_30x14.png    |  Bin 1058 -> 0 bytes
 .../ui/icons/btn_rss_subscribed_gray_30x14.png     |  Bin 1233 -> 0 bytes
 .../ui/icons/btn_rss_subscribed_green_30x14.png    |  Bin 1217 -> 0 bytes
 org/gudy/azureus2/ui/icons/delete2.gif             |  Bin 0 -> 947 bytes
 org/gudy/azureus2/ui/icons/icons.properties        |   38 +-
 org/gudy/azureus2/ui/icons/popup.png               |  Bin 28468 -> 0 bytes
 org/gudy/azureus2/ui/icons/statusbar/pa_green.png  |  Bin 0 -> 924 bytes
 org/gudy/azureus2/ui/icons/statusbar/pa_idle.png   |  Bin 0 -> 604 bytes
 org/gudy/azureus2/ui/icons/statusbar/pa_red.png    |  Bin 0 -> 926 bytes
 org/gudy/azureus2/ui/icons/toolbar/bottom.gif      |  Bin 1114 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/down.gif        |  Bin 1019 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/editcolumns.gif |  Bin 1069 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/open.gif        |  Bin 1201 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/open_folder.gif |  Bin 1150 -> 0 bytes
 .../azureus2/ui/icons/toolbar/open_no_default.gif  |  Bin 1196 -> 1147 bytes
 org/gudy/azureus2/ui/icons/toolbar/open_url.gif    |  Bin 1062 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/remove.gif      |  Bin 1164 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/run.gif         |  Bin 1155 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/start.gif       |  Bin 1036 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/stop.gif        |  Bin 1092 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/switchui.png    |  Bin 1171 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/top.gif         |  Bin 1116 -> 0 bytes
 org/gudy/azureus2/ui/icons/toolbar/up.gif          |  Bin 1022 -> 0 bytes
 org/gudy/azureus2/ui/icons/zoom.png                |  Bin 0 -> 211 bytes
 org/gudy/azureus2/ui/splash/splash_frog.jpg        |  Bin 13702 -> 0 bytes
 org/gudy/azureus2/ui/swt/Alerts.java               |  326 +-
 org/gudy/azureus2/ui/swt/CategoryAdderWindow.java  |    2 +-
 .../ui/swt/DelayedListenerMultiCombiner.java       |   63 +
 org/gudy/azureus2/ui/swt/FileDownloadWindow.java   |   76 +-
 org/gudy/azureus2/ui/swt/ITwistieConstants.java    |   13 -
 org/gudy/azureus2/ui/swt/ITwistieListener.java     |   16 -
 org/gudy/azureus2/ui/swt/IconBar.java              |  273 -
 org/gudy/azureus2/ui/swt/IconBarEnabler.java       |   31 -
 org/gudy/azureus2/ui/swt/ImageRepository.java      |   47 +-
 org/gudy/azureus2/ui/swt/Main.java                 |   51 +-
 org/gudy/azureus2/ui/swt/MenuBuildUtils.java       |   11 +
 org/gudy/azureus2/ui/swt/Messages.java             |    7 +-
 org/gudy/azureus2/ui/swt/OpenTorrentWindow.java    |  255 +-
 org/gudy/azureus2/ui/swt/OpenUrlWindow.java        |   12 +-
 org/gudy/azureus2/ui/swt/PropertiesWindow.java     |   32 +-
 .../azureus2/ui/swt/SimpleTextEntryWindow.java     |   80 +-
 org/gudy/azureus2/ui/swt/Sleak.java                |  450 --
 org/gudy/azureus2/ui/swt/StartServer.java          |   43 +-
 org/gudy/azureus2/ui/swt/Tab.java                  |  993 ----
 org/gudy/azureus2/ui/swt/TextViewerWindow.java     |  160 +-
 org/gudy/azureus2/ui/swt/TorrentUtil.java          |  961 +++-
 org/gudy/azureus2/ui/swt/TrackerChangerWindow.java |   73 +-
 org/gudy/azureus2/ui/swt/TrayWindow.java           |   10 +-
 org/gudy/azureus2/ui/swt/TwistieLabel.java         |  358 --
 org/gudy/azureus2/ui/swt/TwistieSection.java       |  188 -
 org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java  |   31 +-
 org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java       |   95 +-
 org/gudy/azureus2/ui/swt/UISwitcherUtil.java       |   14 -
 org/gudy/azureus2/ui/swt/Utils.java                | 1282 +++--
 org/gudy/azureus2/ui/swt/about.properties          |    1 +
 org/gudy/azureus2/ui/swt/animations/Animator.java  |   36 -
 .../ui/swt/animations/shell/AnimableShell.java     |   38 -
 .../ui/swt/animations/shell/LinearAnimator.java    |  104 -
 .../ui/swt/animations/shell/TestWindow.java        |   88 -
 .../ui/swt/associations/AssociationChecker.java    |    2 +-
 .../ui/swt/auth/CertificateTrustWindow.java        |   19 +-
 org/gudy/azureus2/ui/swt/auth/CryptoWindow.java    |    7 +-
 org/gudy/azureus2/ui/swt/beta/BetaWizard.java      |  116 +
 org/gudy/azureus2/ui/swt/beta/BetaWizardStart.java |  132 +
 .../swt/components/BufferedGraphicTableItem1.java  |  177 +-
 .../swt/components/BufferedGraphicTableItem2.java  |  378 --
 .../azureus2/ui/swt/components/BufferedLabel.java  |   22 +-
 .../ui/swt/components/BufferedTableItem.java       |   20 +-
 .../ui/swt/components/BufferedTableItemImpl.java   |  172 +-
 .../ui/swt/components/BufferedTableRow.java        |  599 ++-
 .../azureus2/ui/swt/components/BufferedWidget.java |   14 -
 .../ui/swt/components/CompositeMinSize.java        |   96 +
 .../azureus2/ui/swt/components/ControlUtils.java   |   65 -
 .../swt/components/CustomTableTooltipHandler.java  |  167 -
 .../ui/swt/components/DoubleBufferedLabel.java     |  184 +
 .../azureus2/ui/swt/components/InPaintInfo.java    |   40 +
 org/gudy/azureus2/ui/swt/components/LinkLabel.java |   15 +-
 .../ui/swt/components/graphics/PieUtils.java       |   15 +-
 .../ui/swt/components/graphics/PingGraphic.java    |   20 +-
 .../ui/swt/components/graphics/Plot3D.java         |   16 +-
 .../ui/swt/components/graphics/SpeedGraphic.java   |    4 +
 .../azureus2/ui/swt/components/graphics/Test.java  |   50 -
 .../ui/swt/components/shell/ShellFactory.java      |   13 +-
 .../ui/swt/components/shell/ShellManager.java      |    4 +-
 org/gudy/azureus2/ui/swt/config/LinkParameter.java |    3 +-
 org/gudy/azureus2/ui/swt/config/Parameter.java     |   10 +
 .../ui/swt/config/wizard/ConfigureWizard.java      |  105 +-
 .../azureus2/ui/swt/config/wizard/FinishPanel.java |   78 +-
 .../ui/swt/config/wizard/LanguagePanel.java        |    2 +-
 .../azureus2/ui/swt/config/wizard/NatPanel.java    |  282 +-
 .../ui/swt/config/wizard/TransferPanel.java        |  245 -
 .../ui/swt/config/wizard/TransferPanel2.java       |  457 ++
 .../ui/swt/config/wizard/WelcomePanel.java         |   17 +-
 .../azureus2/ui/swt/debug/ObfusticateImage.java    |    3 +-
 .../azureus2/ui/swt/debug/UIDebugGenerator.java    |  416 +-
 .../azureus2/ui/swt/donations/DonationWindow.java  |  105 +-
 org/gudy/azureus2/ui/swt/help/AboutWindow.java     |  127 +-
 .../azureus2/ui/swt/mainwindow/ClipboardCopy.java  |    2 +-
 org/gudy/azureus2/ui/swt/mainwindow/Colors.java    |   26 +-
 org/gudy/azureus2/ui/swt/mainwindow/Cursors.java   |   69 -
 .../azureus2/ui/swt/mainwindow/IMainStatusBar.java |   69 +
 .../azureus2/ui/swt/mainwindow/IMainWindow.java    |    3 -
 .../azureus2/ui/swt/mainwindow/IMenuConstants.java |   19 +-
 .../azureus2/ui/swt/mainwindow/Initializer.java    |  571 --
 org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java  |  104 +-
 .../azureus2/ui/swt/mainwindow/MainStatusBar.java  |  617 ++-
 .../azureus2/ui/swt/mainwindow/MainWindow.java     | 1820 -------
 .../azureus2/ui/swt/mainwindow/MenuFactory.java    |  776 ++-
 .../ui/swt/mainwindow/PluginsMenuHelper.java       |  147 +-
 .../azureus2/ui/swt/mainwindow/Refreshable.java    |   12 -
 org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java |   58 +-
 .../azureus2/ui/swt/mainwindow/SplashWindow.java   |  119 +-
 .../ui/swt/mainwindow/SystemWarningWindow.java     |  420 ++
 .../azureus2/ui/swt/mainwindow/TorrentOpener.java  |  119 +-
 .../ui/swt/mainwindow/UIFunctionsImpl.java         |  567 --
 org/gudy/azureus2/ui/swt/maketorrent/BYOPanel.java |  521 ++
 .../ui/swt/maketorrent/DirectoryPanel.java         |   20 +-
 .../azureus2/ui/swt/maketorrent/ModePanel.java     |   91 +-
 .../ui/swt/maketorrent/MultiTrackerEditor.java     |   85 +-
 .../ui/swt/maketorrent/MultiTrackerPanel.java      |   19 +-
 .../ui/swt/maketorrent/NewTorrentWizard.java       |   69 +-
 .../azureus2/ui/swt/maketorrent/ProgressPanel.java |   87 +-
 .../azureus2/ui/swt/maketorrent/SavePathPanel.java |  100 +-
 .../ui/swt/maketorrent/SingleFilePanel.java        |   20 +-
 .../azureus2/ui/swt/maketorrent/WebSeedPanel.java  |   16 +-
 .../azureus2/ui/swt/minibar/AllTransfersBar.java   |   85 +-
 org/gudy/azureus2/ui/swt/minibar/DownloadBar.java  |    9 +-
 org/gudy/azureus2/ui/swt/minibar/MiniBar.java      |   22 +-
 org/gudy/azureus2/ui/swt/nat/NatTestWindow.java    |  243 +-
 org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java | 1186 ++--
 org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java  |  323 +-
 .../ui/swt/plugins/PluginUISWTSkinObject.java      |    9 +
 .../ui/swt/plugins/UISWTAWTPluginView.java         |   62 -
 .../azureus2/ui/swt/plugins/UISWTInstance.java     |   78 +-
 .../azureus2/ui/swt/plugins/UISWTPluginView.java   |   44 -
 org/gudy/azureus2/ui/swt/plugins/UISWTView.java    |   17 +
 .../azureus2/ui/swt/plugins/UISWTViewEvent.java    |   10 +
 .../ui/swt/pluginsimpl/BasicPluginConfigImpl.java  |   31 +-
 .../ui/swt/pluginsimpl/BasicPluginViewImpl.java    |   65 +-
 .../ui/swt/pluginsimpl/UISWTGraphicImpl.java       |   22 +-
 .../ui/swt/pluginsimpl/UISWTInstanceImpl.java      |  426 +-
 .../ui/swt/pluginsimpl/UISWTStatusEntryImpl.java   |   25 +-
 .../azureus2/ui/swt/pluginsimpl/UISWTViewCore.java |   65 +
 .../pluginsimpl/UISWTViewEventListenerHolder.java  |  182 +
 .../azureus2/ui/swt/pluginsimpl/UISWTViewImpl.java |  375 +-
 .../ui/swt/pluginsimpl/UIToolBarManagerCore.java   |   11 +
 .../ui/swt/progress/ProgressReporterPanel.java     |    9 +-
 .../ui/swt/progress/ProgressReporterWindow.java    |   13 +-
 org/gudy/azureus2/ui/swt/sharing/ShareUtils.java   |   23 +-
 .../ui/swt/sharing/progress/ProgressWindow.java    |   76 +-
 .../azureus2/ui/swt/shells/AdvRenameWindow.java    |   12 +
 .../azureus2/ui/swt/shells/GCStringPrinter.java    |  394 +-
 .../azureus2/ui/swt/shells/MessageBoxShell.java    |  163 +-
 .../azureus2/ui/swt/shells/MessagePopupShell.java  |  406 --
 .../azureus2/ui/swt/shells/MessageSlideShell.java  |  247 +-
 .../azureus2/ui/swt/shells/MultipageWizard.java    |    4 +-
 org/gudy/azureus2/ui/swt/shells/PopupShell.java    |    9 -
 .../azureus2/ui/swt/speedtest/SpeedTestPanel.java  |    5 +-
 .../ui/swt/speedtest/SpeedTestSelector.java        |  195 +
 .../azureus2/ui/swt/speedtest/SpeedTestWizard.java |    2 +-
 org/gudy/azureus2/ui/swt/test/Main.java            |  198 -
 .../azureus2/ui/swt/test/PrintTransferTypes.java   |  147 -
 org/gudy/azureus2/ui/swt/test/SashFormTest.java    |   58 -
 org/gudy/azureus2/ui/swt/test/TableTest.java       |  198 -
 .../azureus2/ui/swt/test/Win32TransferTypes.java   |  164 -
 .../azureus2/ui/swt/twistie/ITwistieConstants.java |   13 +
 .../azureus2/ui/swt/twistie/ITwistieListener.java  |   16 +
 org/gudy/azureus2/ui/swt/twistie/TwistieLabel.java |  369 ++
 .../azureus2/ui/swt/twistie/TwistieSection.java    |  201 +
 .../azureus2/ui/swt/update/FullUpdateWindow.java   |   54 +-
 .../azureus2/ui/swt/update/SilentInstallUI.java    |  107 +
 .../azureus2/ui/swt/update/SimpleInstallUI.java    |    4 +
 org/gudy/azureus2/ui/swt/update/UpdateMonitor.java |   56 +-
 org/gudy/azureus2/ui/swt/update/UpdateWindow.java  |   18 +-
 .../azureus2/ui/swt/updater2/PreUpdateChecker.java |    2 +
 .../azureus2/ui/swt/updater2/SWTUpdateChecker.java |   36 +-
 .../azureus2/ui/swt/updater2/SWTVersionGetter.java |    5 +-
 org/gudy/azureus2/ui/swt/views/AbstractIView.java  |  139 -
 org/gudy/azureus2/ui/swt/views/ConfigShell.java    |   18 +-
 org/gudy/azureus2/ui/swt/views/ConfigView.java     |  338 +-
 .../azureus2/ui/swt/views/DetailedListView.java    |  371 --
 org/gudy/azureus2/ui/swt/views/FilesView.java      |  692 +--
 .../azureus2/ui/swt/views/FilesViewMenuUtil.java   |  765 +++
 org/gudy/azureus2/ui/swt/views/GeneralView.java    |  480 +-
 org/gudy/azureus2/ui/swt/views/IView.java          |  116 -
 .../ui/swt/views/IViewAlwaysInitialize.java        |   29 +
 org/gudy/azureus2/ui/swt/views/IViewExtension.java |   39 -
 org/gudy/azureus2/ui/swt/views/LoggerView.java     |   90 +-
 org/gudy/azureus2/ui/swt/views/ManagerView.java    |  881 ++-
 org/gudy/azureus2/ui/swt/views/MySharesView.java   |  138 +-
 .../azureus2/ui/swt/views/MyTorrentsSuperView.java |  331 +-
 org/gudy/azureus2/ui/swt/views/MyTorrentsView.java | 1860 ++++---
 org/gudy/azureus2/ui/swt/views/MyTrackerView.java  |   84 +-
 org/gudy/azureus2/ui/swt/views/PeerSuperView.java  |   35 +-
 .../azureus2/ui/swt/views/PeersGraphicView.java    |  281 +-
 org/gudy/azureus2/ui/swt/views/PeersView.java      |  119 +-
 .../ui/swt/views/PieceDistributionView.java        |   88 +-
 org/gudy/azureus2/ui/swt/views/PiecesView.java     |  106 +-
 org/gudy/azureus2/ui/swt/views/ScrapeInfoView.java |  442 ++
 .../azureus2/ui/swt/views/TorrentInfoView.java     |  155 +-
 .../azureus2/ui/swt/views/TorrentOptionsView.java  |  306 +-
 org/gudy/azureus2/ui/swt/views/TrackerView.java    |  369 ++
 org/gudy/azureus2/ui/swt/views/ViewUtils.java      |  257 +
 .../ui/swt/views/clientstats/ClientStatsView.java  |   24 +-
 .../views/columnsetup/ColumnTC_ChosenColumn.java   |   21 +-
 .../swt/views/columnsetup/ColumnTC_NameInfo.java   |   32 +-
 .../ui/swt/views/columnsetup/ColumnTC_Sample.java  |   48 +-
 .../views/columnsetup/TableColumnSetupWindow.java  |  271 +-
 .../configsections/ConfigSectionBackupRestore.java |  546 ++
 .../configsections/ConfigSectionConnection.java    |   48 +-
 .../ConfigSectionConnectionAdvanced.java           |    2 +-
 .../ConfigSectionConnectionEncryption.java         |    2 +-
 .../views/configsections/ConfigSectionFile.java    | 1051 ++--
 .../configsections/ConfigSectionIPFilter.java      |  101 +-
 .../configsections/ConfigSectionInterface.java     |   66 +-
 .../ConfigSectionInterfaceAlerts.java              |  303 +-
 .../ConfigSectionInterfaceColor.java               |    4 +
 .../ConfigSectionInterfaceDisplay.java             |  116 +-
 .../ConfigSectionInterfaceStart.java               |    6 -
 .../ConfigSectionInterfaceTables.java              |  382 ++
 .../views/configsections/ConfigSectionLogging.java |   62 +
 .../views/configsections/ConfigSectionMode.java    |   74 +-
 .../views/configsections/ConfigSectionPlugins.java |  234 +-
 .../configsections/ConfigSectionSecurity.java      |    7 +-
 .../configsections/ConfigSectionStartShutdown.java |  807 +++
 .../views/configsections/ConfigSectionStats.java   |    5 +-
 .../configsections/ConfigSectionTrackerClient.java |   67 +-
 .../configsections/ConfigSectionTrackerServer.java |    5 +-
 .../configsections/ConfigSectionTransfer.java      |  184 +-
 .../ConfigSectionTransferAutoSpeed.java            |    2 +-
 .../ConfigSectionTransferAutoSpeedSelect.java      |    5 +-
 .../azureus2/ui/swt/views/file/FileInfoView.java   |  115 +-
 .../azureus2/ui/swt/views/peer/PeerInfoView.java   |  151 +-
 .../views/peer/RemotePieceDistributionView.java    |   22 +-
 .../swt/views/piece/MyPieceDistributionView.java   |   26 +-
 .../azureus2/ui/swt/views/piece/PieceInfoView.java |  143 +-
 .../azureus2/ui/swt/views/stats/ActivityView.java  |   81 +-
 .../azureus2/ui/swt/views/stats/CacheView.java     |   82 +-
 org/gudy/azureus2/ui/swt/views/stats/DHTView.java  |  110 +-
 .../azureus2/ui/swt/views/stats/StatsView.java     |  659 ++-
 .../ui/swt/views/stats/TrackerStatsView.java       |   44 -
 .../ui/swt/views/stats/TransferStatsView.java      |  382 +-
 .../azureus2/ui/swt/views/stats/VivaldiPanel.java  |   28 +-
 .../azureus2/ui/swt/views/stats/VivaldiView.java   |  106 +-
 .../azureus2/ui/swt/views/table/TableCellSWT.java  |   20 +-
 .../table/TableColumnCoreCreationListener.java     |   35 -
 .../swt/views/table/TableColumnOrTreeColumn.java   |  113 +
 .../ui/swt/views/table/TableItemOrTreeItem.java    |  157 +
 .../ui/swt/views/table/TableOrTreeSWT.java         |  394 ++
 .../azureus2/ui/swt/views/table/TableRowSWT.java   |   26 +-
 .../swt/views/table/TableRowSWTPaintListener.java  |   37 +
 .../ui/swt/views/table/TableViewFilterCheck.java   |   10 +-
 .../azureus2/ui/swt/views/table/TableViewSWT.java  |  140 +-
 .../ui/swt/views/table/TableViewSWTFilter.java     |   12 +
 .../ui/swt/views/table/impl/FakeTableCell.java     |  147 +-
 .../ui/swt/views/table/impl/TableCellImpl.java     | 1423 +----
 .../ui/swt/views/table/impl/TableCellSWTBase.java  | 1341 +++++
 .../swt/views/table/impl/TableColumnDelegate.java  |  205 +
 .../ui/swt/views/table/impl/TableDelegate.java     |  921 ++++
 .../ui/swt/views/table/impl/TableItemDelegate.java |  338 ++
 .../ui/swt/views/table/impl/TableOrTreeUtils.java  |  190 +
 .../ui/swt/views/table/impl/TableRowImpl.java      |  897 +--
 .../ui/swt/views/table/impl/TableRowSWTBase.java   |  760 +++
 .../ui/swt/views/table/impl/TableTooltips.java     |    6 +-
 .../ui/swt/views/table/impl/TableViewFactory.java  |   25 +
 .../ui/swt/views/table/impl/TableViewSWTImpl.java  | 4649 +++++-----------
 .../swt/views/table/impl/TableViewSWT_Common.java  | 1069 ++++
 .../views/table/impl/TableViewSWT_EraseItem.java   |  235 +
 .../views/table/impl/TableViewSWT_PaintItem.java   |  459 ++
 .../views/table/impl/TableViewSWT_TabsCommon.java  |  446 ++
 .../ui/swt/views/table/impl/TableViewTab.java      |  126 +-
 .../swt/views/table/impl/TreeColumnDelegate.java   |  204 +
 .../ui/swt/views/table/impl/TreeDelegate.java      |  916 ++++
 .../ui/swt/views/table/impl/TreeItemDelegate.java  |  334 ++
 .../swt/views/table/painted/TableCellPainted.java  |  361 ++
 .../swt/views/table/painted/TableRowPainted.java   |  946 ++++
 .../swt/views/table/painted/TableViewPainted.java  | 2947 ++++++++++
 .../ui/swt/views/table/utils/CoreTableColumn.java  |    3 +-
 .../swt/views/table/utils/TableColumnCreator.java  |   17 +-
 .../swt/views/table/utils/TableColumnInfoImpl.java |    2 +-
 .../swt/views/table/utils/TableColumnManager.java  |  687 ---
 .../ui/swt/views/tableitems/ColumnDateSizer.java   |  121 +-
 .../ui/swt/views/tableitems/files/DoneItem.java    |    1 +
 .../swt/views/tableitems/files/FileCRC32Item.java  |   36 +
 .../views/tableitems/files/FileExtensionItem.java  |   16 +-
 .../views/tableitems/files/FileHashItemBase.java   |  433 ++
 .../swt/views/tableitems/files/FileIndexItem.java  |   52 +
 .../ui/swt/views/tableitems/files/FileMD5Item.java |   36 +
 .../swt/views/tableitems/files/FirstPieceItem.java |    3 +-
 .../ui/swt/views/tableitems/files/ModeItem.java    |    1 +
 .../ui/swt/views/tableitems/files/NameItem.java    |   40 +-
 .../ui/swt/views/tableitems/files/PathItem.java    |    1 +
 .../ui/swt/views/tableitems/files/PercentItem.java |   82 +-
 .../swt/views/tableitems/files/PieceCountItem.java |    1 +
 .../swt/views/tableitems/files/PriorityItem.java   |   25 +-
 .../views/tableitems/files/ProgressGraphItem.java  |   10 +-
 .../tableitems/files/RemainingPiecesItem.java      |    1 +
 .../ui/swt/views/tableitems/files/SizeItem.java    |    1 +
 .../views/tableitems/files/StorageTypeItem.java    |    8 +-
 .../tableitems/files/TorrentRelativePathItem.java  |   52 +
 .../tableitems/mytorrents/ColumnFileCount.java     |  177 +
 .../tableitems/mytorrents/ColumnTorrentSpeed.java  |   85 +
 .../tableitems/mytorrents/CommentIconItem.java     |    1 +
 .../tableitems/mytorrents/CompletionItem.java      |    2 +-
 .../views/tableitems/mytorrents/DateAddedItem.java |    1 +
 .../tableitems/mytorrents/DateCompletedItem.java   |    1 +
 .../swt/views/tableitems/mytorrents/DoneItem.java  |   21 +-
 .../swt/views/tableitems/mytorrents/DownItem.java  |   19 +-
 .../views/tableitems/mytorrents/DownSpeedItem.java |    3 +-
 .../swt/views/tableitems/mytorrents/ETAItem.java   |   49 +-
 .../tableitems/mytorrents/FileExtensionItem.java   |  104 +
 .../views/tableitems/mytorrents/HealthItem.java    |    1 +
 .../views/tableitems/mytorrents/IPFilterItem.java  |  108 +
 .../swt/views/tableitems/mytorrents/NameItem.java  |   16 +-
 .../swt/views/tableitems/mytorrents/PeersItem.java |   40 +-
 .../views/tableitems/mytorrents/RemainingItem.java |   18 +-
 .../swt/views/tableitems/mytorrents/SeedsItem.java |   50 +-
 .../tableitems/mytorrents/ShareRatioItem.java      |    2 +-
 .../swt/views/tableitems/mytorrents/SizeItem.java  |   33 +-
 .../views/tableitems/mytorrents/StatusItem.java    |    1 +
 .../mytorrents/TorrentCreateDateItem.java          |   70 +
 .../tableitems/mytorrents/TrackerNameItem.java     |  104 +-
 .../tableitems/mytorrents/TrackerStatusItem.java   |   58 +-
 .../views/tableitems/mytorrents/UpSpeedItem.java   |    5 +-
 .../swt/views/tableitems/mytracker/NameItem.java   |   51 +-
 .../ui/swt/views/tableitems/peers/ChokedItem.java  |    4 +-
 .../swt/views/tableitems/peers/EncryptionItem.java |    2 +-
 .../ui/swt/views/tableitems/peers/PiecesItem.java  |  542 +-
 .../swt/views/tableitems/peers/ProtocolItem.java   |   60 +
 .../ui/swt/views/tableitems/pieces/BlocksItem.java |  267 +-
 .../swt/views/tableitems/tracker/IntervalItem.java |   99 +
 .../swt/views/tableitems/tracker/LeechersItem.java |   71 +
 .../ui/swt/views/tableitems/tracker/NameItem.java  |   72 +
 .../ui/swt/views/tableitems/tracker/PeersItem.java |   72 +
 .../ui/swt/views/tableitems/tracker/SeedsItem.java |   72 +
 .../swt/views/tableitems/tracker/StatusItem.java   |  139 +
 .../ui/swt/views/tableitems/tracker/TypeItem.java  |   97 +
 .../swt/views/tableitems/tracker/UpdateInItem.java |   92 +
 .../ui/swt/views/utils/CategoryUIUtils.java        |  399 ++
 .../azureus2/ui/swt/views/utils/ManagerUtils.java  |  350 +-
 .../azureus2/ui/swt/welcome/WelcomeWindow.java     |    7 -
 .../azureus2/ui/swt/win32/Win32UIEnhancer.java     |  226 +-
 .../ui/swt/wizard/AbstractWizardPanel.java         |   19 +-
 org/gudy/azureus2/ui/swt/wizard/IWizardPanel.java  |   10 +-
 org/gudy/azureus2/ui/swt/wizard/Wizard.java        |   97 +-
 org/gudy/azureus2/ui/systray/Main.java             |   77 -
 org/gudy/azureus2/ui/systray/SystemTraySWT.java    |   20 +-
 org/gudy/azureus2/ui/webplugin/WebPlugin.java      | 1440 ++++-
 .../ui/webplugin/WebPluginAccessController.java    |   31 +-
 org/gudy/azureus2/update/CorePatchChecker.java     |   22 +-
 org/gudy/azureus2/update/CoreUpdateChecker.java    |  263 +-
 org/gudy/azureus2/update/Test.java                 |   68 -
 org/gudy/azureus2/update/UpdaterUtils.java         |   18 +
 org/json/simple/ItemList.java                      |    2 +-
 org/json/simple/JSONArray.java                     |    2 +-
 org/json/simple/JSONObject.java                    |    2 +-
 org/json/simple/JSONValue.java                     |    2 +-
 org/json/simple/Test.java                          |    2 +-
 org/json/simple/parser/JSONParser.java             |    2 +-
 org/json/simple/parser/Yytoken.java                |    2 +-
 1587 files changed, 162302 insertions(+), 86256 deletions(-)

diff --git a/Azureus2.jardesc b/Azureus2.jardesc
new file mode 100644
index 0000000..ee2ee64
--- /dev/null
+++ b/Azureus2.jardesc
@@ -0,0 +1,525 @@
+<?xml version="1.0" encoding="WINDOWS-1252" standalone="no"?>
+<jardesc>
+    <jar path="azureus2_svn/Azureus2_parg.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/azureus2_svn/Azureus2.jardesc" exportErrors="true" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.sharing.hoster"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.components"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.systray"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.deprecate"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.toolbar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.clientmessageservice"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.impl.http"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.widgets"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ddb"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.security"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.tracker.web"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.table.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.download.savelocation"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.logging"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.common.util"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.pf"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.internat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.download.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.file"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.file"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.torrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.update.sf.impl2"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.disk"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.helpers"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.upnp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.mytracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.math.ec"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.console"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils.xml.simpleparser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.x509"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.neuronal"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.removerules"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.networks"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.jce"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.associations"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.torrent"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.download"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.console.multiuser.commands"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.swt.uiupdater"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.update"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.stats.transfer.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.admin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl.resume"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.security.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipfilter.impl.tests"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.udp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.agreement"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.x9"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.i2p"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.loopcontrol.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.files"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ipc"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.update.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.unix"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.installer"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.piecepicker"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.views.skin.sidebar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.animations.shell"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.crypto"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.average"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.openssl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.pairing.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.shells.main"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl.dht"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl.web.regex"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.menus"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.menus"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.clientmessageservice.secure.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.natpmp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.impl.tcp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.config.plugins"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.animations"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.startstoprules.defaultplugin.ui.swt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.protocol"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.db.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl.web.json"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp.impl.services"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.extlistener"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.proxy"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl.tcp"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.columns.torrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.resourceuploader"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.udp.mc.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipchecker.natchecker"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.subs.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.natpmp.upnp"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.extseed.impl.webseed"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.nat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.category"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.bloom"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.util"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.pf.text"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.dht.mainline"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl.web.rss"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.images.tb"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.shells"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl.web"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.custom"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.debug"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.engines"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.dht.mainline"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.content"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.console"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.db"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.extseed.util"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.messenger.browser.listeners"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.mdi"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.proxy.socks"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.subs"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.components.shell"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.file.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.components.graphics"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.net.buddy.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.maketorrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport.udp.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.tracker.peerauth"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.netcoords"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.table"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.osx"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.logging"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils.security"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.beta"/>
+        <file path="/azureus2_svn/ChangeLog.txt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.torrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.impl.udp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.test"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.pluginsinstaller"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.win32"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.natpmp.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.torrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.messaging.azureus"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.png"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.macs"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.stats"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.extseed.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.lws"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.rpexceptions"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.download"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.pluginsuninstaller"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.torrentdownloader"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.exporttorrent.wizard"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.client.impl.dht"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ddb"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.peerdb"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.access"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.torrent.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.common"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.startstoprules.always"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.icons"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.content"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.messaging.generic"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.security.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.access.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.win32.access"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.disk"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.views"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.html.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.udp.uc.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.generators"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.icons.statusbar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.client.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.jce.provider"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.control"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.eclipse.swt.widgets"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.update"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.piece"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.custom.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.encodings"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.magneturi.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.clientid"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.content"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.minibar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.pkcs"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.model"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.twistie"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.updater.snippets"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.plugins"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.cnetwork.impl"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.console.multiuser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.swt.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.download"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp.impl.ssdp"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.pf.file"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl.piecemapper.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.vuzefile"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.utils"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.dht"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.magnet"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.download"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.devices"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.instancemanager"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.common"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.clientmessageservice.secure"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils.resourceuploader"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.help"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.logging"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.macosx.access.cocoa"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.drivedetector"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.signers"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.netcoords.vivaldi.ver1.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.player"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.dummy"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.common.updater"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.util.encoders"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.admin.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.devices.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.wizard"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.jce.spec"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.peer.impl.transport"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.shells.uiswitcher"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.mainwindow"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.common.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl.piecemapper"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.skin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.peer.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.speedmanager.impl.v2"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.selectedcontent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.icons.status"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.cache.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.messenger"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.control.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.nat.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.xml.schemas"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.speed"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.tables"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.netcoords.vivaldi.ver1.impl.tests"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl.tcp.nonblocking"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.speedmanager.impl.v1"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.bloom.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.activities"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipchecker.extipchecker"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.messenger.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.components"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.common"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.bc"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.browser.msg"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.components"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.security"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.columnsetup"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.search"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.unchoker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.net.netstatus"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.pairing.impl.swt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.piecepicker.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.host"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.speedmanager.impl.v3"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.network"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.messaging"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.pluginsimpl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.netcoords.vivaldi.ver1"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.json.simple.parser"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.devices.add"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.update"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.params"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.socks5"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.control.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.startstoprules.defaultplugin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.loopcontrol"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.cl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.dht.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.peers"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.proxy.socks.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.welcome"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.tcp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.udp.mc"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.client.impl.bt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.piecepicker.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.messaging.bittorrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.peer.impl.control"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport.loopback"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.splash"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.update"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.net.buddy.swt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.clientmessageservice.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.messaging"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.win32.access.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.extseed.impl.getright"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.global"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.sharing"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.client"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.logging.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl.access"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.feature"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.net.netstatus.swt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.stats"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.console.commands"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.updater2"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.swt"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.cnetwork"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.torrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.peers"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.control"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.images.sb"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.peer.cache"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.devices.columns"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.backup.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<org.apache.commons.lang"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager.cache"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.peer"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.mdi"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.x509"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.uploadslots"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.telnet"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swing"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.SWT"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.protocol.udp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.cms"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.dht"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ui.tables"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.sharing"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.net.buddy"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl.tcp.blocking"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.config"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.search"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.columns.subscriptions"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.subscriptions"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.metasearch.impl.plugin"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.images.tb.c"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.config.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.versioncheck"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.peer"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.auth"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.resourcedownloader"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.sharing"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.icons.toolbar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.messaging"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.launch"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.xml.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.xml.rss"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.mytorrents"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.torrentdownloader.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipfilter.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.diskmanager"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.macosx.access.jnilib"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.digests"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.teletrust"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.messaging.bittorrent.ltep"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.platform.macosx"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.importtorrent.wizard"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.launcher.classloading"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.magnet.icons"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.applet"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.common.viewtitleinfo"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.xml.simpleparser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.table.painted"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.config"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.global.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.peer.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.instancemanager.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.win32"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils.xml.rss"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.clientid"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.stats"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.extseed"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.clientstats"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.magnet"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.platform"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.skin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.drivedetector.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.rssgen"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.common.table"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.configsections"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.backup"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.vuze"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.xml.simpleparser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.installer"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.crypto.modes"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.router.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.category.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.devices"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.nat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.update"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.columns.vuzeactivity"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport.util"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.messenger.browser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp.services"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.pairing"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.launcher"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.server.impl.udp"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.ipchecker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.natpmp.upnp.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.update"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.tracker"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipfilter"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.internat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.proxy.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.util.http"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.model"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.core.peer.cache.cachelogic"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.networkmanager.impl.test"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.config.wizard"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.stats.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.config.generic"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.sec"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport.udp"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.util.win32"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.table.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ipfilter"/>
+        <file path="/azureus2_svn/GPL.txt"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.disk"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.disk.impl.access.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.transport.udp.impl.packethandler"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.jar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.ipchecker.extipchecker.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.donations"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.nat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.update.sf"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.skin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.speedmanager"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.columns.utils"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.ui.toolbar"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.common.table.impl"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.ui.console.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.swt.mdi"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.asn1.misc"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.images"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.upnp.impl.device"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.selectedcontent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.tracker.local"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.router"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.peermanager.nat"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.utils.subscriptions"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.pieces"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.sharing.progress"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.udp.uc"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.shells"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.clientid"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.ui.swt.imageloader"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.plugininstall"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.progress"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.plugins.tracker.dht"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.dht.speed.impl"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.views.skin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.speedtest"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.html"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.myshares"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.browser.listener"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.tracker.host.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.remote.ipfilter"/>
+        <javaElement handleIdentifier="=azuis_svn/<org.gudy.azureus2.core3.torrentdownloader.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.download"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.messaging.bittorrent"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ipc"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.plugins.network"/>
+        <javaElement handleIdentifier="=azureus3_svn/<com.aelitis.azureus.ui.swt.browser"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.net.magneturi"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.webplugin"/>
+        <javaElement handleIdentifier="=azureus2_svn/<com.aelitis.azureus.core.speedmanager.impl"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.security"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.bouncycastle.jce.interfaces"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.stats.transfer"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.ui.swt.views.tableitems.peers"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.json.simple"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.pluginsimpl.local.ipfilter"/>
+        <javaElement handleIdentifier="=azureus2_svn/<org.gudy.azureus2.core3.util.protocol.azplug"/>
+    </selectedElements>
+    <fatjar builder="org.eclipse.jdt.ui.plain_jar_builder" launchConfig=""/>
+</jardesc>
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 0273f61..9712907 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,6 +1,582 @@
 VUZE CHANGELOG
 -----------------
 
+2012.10.24 | Vuze 4.8.0.0
+
+FEATURE: Blog | See http://devblog.vuze.com/tagged/4800 for beta version blog posts
+
+FEATURE: Plug | Swarm Discoveries
+FEATURE: Plug | The RSS Feed plugin now can filter on min+max file types and also has a 'copy-filter' function [Parg+Community]
+FEATURE: Core | Reduced resource usage mode on startup - still in a beta state [Parg]
+FEATURE: Core | 'Prevent Computer Sleep' options now available on OSX [Parg]
+FEATURE: Core | Added options to streaming and transcoding to prevent computer sleep [Parg]
+FEATURE: Core | Auto-preview for .nfo and .txt files (Quick View) option added to Library and Files view [Parg]
+FEATURE: Core | Analysis of .rar file content (indication of password protected entries) added as a Quick View function [Parg]
+FEATURE: UI   | Added 'edit as text' option to the tracker URL editor dialog [Parg]
+FEATURE: UI   | Added right-click menu to Sources tab to allow tracker URL edits [Parg]
+FEATURE: UI   | Extended the existing 'add tracker url' Library menu option to accept multiple trackers [Parg]
+FEATURE: UI   | Custom date format now applicable to ETA colums [Parg]
+FEATURE: UI   | Added 'Torrent Creation Date' column to Library views [Parg]
+FEATURE: UI   | Added per-column date formats for the ETA columns [Parg]
+FEATURE: UI   | Added aggregate stats view (e.g. aggregate share-ratio for a number of downloads) to the 'Torrent Options' view [Parg]
+FEATURE: UI   | Added plugin install and uninstall buttons to the plugin configuration view [Parg]
+
+CHANGE: Core  | The previous release disabled IPFilters for Vuze update torrents, this has been reverted [Parg]
+CHANGE: UI    | Plugin views now listed in View menu [TuxPaper]
+CHANGE:       | 64 bit support [TuxPaper]
+CHANGE: UI    | Absolute ETA display now separately configurable for ETA and Progress column [Parg]
+CHANGE: UI    | Ignore temporary 'incomplete' suffix when showing file types [Parg]
+CHANGE: UI    | Updated Catalan translation [GosGroc]
+
+BUGFIX: Core  | Fixed bug whereby some transcodes were being incorrectly failed as 'prematurely terminated' [Parg]
+BUGFIX: Core  | Fixed race condition that occurred when auto-transcoding from an RSS feed [Parg]
+BUGFIX: Core  | Fixed error when creating manually-selected piece size torrents [Parg] 
+BUGFIX: UI    | Fix CTRL-PGDN/CTRL-END in Library [TuxPaper]
+BUGFIX: UI    | Fix sidebar entries for categories not updating numbers [TuxPaper]
+BUGFIX: UI    | Fix sort column not refreshing sometimes [TuxPaper]
+BUGFIX: UI    | Added some double buffering to fields that were flickering on update [Parg]
+BUGFIX: UI    | Fixed UI hang under some multi-select conditions [Parg]
+BUGFIX: Plug  | Transcoding was sometimes reporting 'no disk space' errors instead of the actual error [Parg]
+
+
+
+2012.09.17 | Vuze 4.7.2.0
+
+FEATURE: Blog | See http://devblog.vuze.com/tagged/vuze4720 for beta version blog posts
+
+FEATURE: Core | Option to randomize TCP/UDP listen ports on startup [Parg]
+FEATURE: Core | Window's user options to control computer sleep behaviour while downloading/seeding [Parg]
+FEATURE: Core | Ability to selectively disable tracker client protocols [Parg]
+FEATURE: Core | DNS Tracker Preferences [http://bittorrent.org/beps/bep_0034.html] implemented [Parg]
+FEATURE: Core | Added explicit application map to be used for launch operations [Parg]
+FEATURE: UI   | New column in Library views to show file extension [Parg]
+FEATURE: UI   | File view columns for CRC-32 and MD5 file hashes [Parg]
+FEATURE: UI   | Column-header right-click option on ETA/Progress columns to show absolute ETA [Parg]
+FEATURE: UI   | Torrent file index and torrent path columns added to File view [Parg]
+FEATURE: UI   | Keyboard accelerators added for Pause+Resume [Parg]
+FEATURE: UI   | Torrent creation wizard now allows arbitrary selection of files to be added to a torrent [Parg, TuxPaper]
+FEATURE: UI   | If move-on-complete is enabled for downloads the progress of this is now shown in the Status column [Parg]
+FEATURE: UI   | Vuze remote connection status now shown in the status bar [Parg]
+FEATURE: UI   | Added custom date format for column display [TuxPaper]
+FEATURE: UI   | Added option to disable 'backup complete' notification [TuxPaper]
+FEATURE: UI   | Number of unread blog posts shown in beta side-bar entry [TuxPaper]
+FEATURE: UI   | Option to specify table header height [TuxPaper]
+FEATURE: Srch | Search templates can now do variable substitution (no UI yet) [TuxPaper]
+FEATURE: Inst | Installer customize option now permits the clearing of config data [TuxPaper]
+FEATURE: Inst | Custom install now lets you choose Classic or Vuze UI [TuxPaper]
+FEATURE: Plug | DVD Burn plugin now has Library context menus to create new DVD and add content to existing [Parg]
+
+CHANGE: CORE  | Added .mts and .m2ts to playable extensions [Parg]
+CHANGE: UI    | Added visual feedback for device problems such as lack of disk space [Parg]
+CHANGE: UI    | Vuze sidebar entry can now be rolled up [TuxPaper]
+CHANGE: UI    | Don't show 'all' and 'uncategorized' entries in sidebar when no categories defined [TuxPaper]
+CHANGE: UI    | 'Draw grid lines and fill blank areas' no longer fills blank areas when unchecked [TuxPaper]
+
+BUGFIX: Core  | Prevent recursive backup hell if backup location selected in wrong location [Parg]
+BUGFIX: Core  | Correctly handle invalid upload_only entries in handshakes [Parg]
+BUGFIX: UI    | Table headers now use system colors; IP filter on status bar now obeys system colors [TuxPaper]
+BUGFIX: UI    | Table scrollbars now have better page-scroll behaviour [TuxPaper]
+BUGFIX: UI    | Fixed ctrl+home/end not working in tables [TuxPaper]
+BUGFIX: UI    | Fixed inability to scroll completely right [TuxPaper]
+BUGFIX: UI    | Fix message texts not being resolved for sidebar entries on occasion [Parg]
+BUGFIX: UI    | Allow dropping .torrent files onto blank area of sidebar [TuxPaper]
+BUGFIX: Plug  | DVD Burn: fix bug that was preventing warnings such as dual-layer, rw-disk blanking from showing [TuxPaper]
+
+
+
+2012.07.19 | Vuze 4.7.1.2
+
+FEATURE: UI   | Added double-click -> Launch option to library options [Parg]
+
+CHANGE: Core  | Exclude Vuze update torrents from IP filter rules [Parg]
+CHANGE: UI    | Table Views now draw text in default Antialiasing (hoping that fixes some edge case bugs) [TuxPaper]
+
+BUGFIX: UI    | Fixed subscription wizard column header text [Parg]
+BUGFIX: UI    | *nix: Fix Plugins and Torrents menu not having any entries [TuxPaper]
+BUGFIX: UI    | Fix scrolling issue after Library row gets removed while its subrows are displayed [TuxPaper]
+BUGFIX: UI    | Ensure table row height can fit the default font size [TuxPaper] 
+
+
+
+2012.07.13 | Vuze 4.7.1.0
+
+FEATURE: Core | Added a 'low' file priority setting and the ability to set negative priorities for various levels of 'low' [Parg]
+FEATURE: Core | Support for metdata download based magnet link resolution [Parg]
+FEATURE: Core | Added means to backup and restore yoru Vuze config, manually and automatically [Parg]
+FEATURE: Core | Added per-download and per-category option to prioritise uploading over other downloads [Parg]
+FEATURE: Core | Added 'personal share' feature that auto-generates and seeds files with unique torrents [Parg]
+FEATURE: Core | Per-torrent IP Filter enabling [Parg]
+FEATURE: Core | Added extra arguments to magnet exports (dn,tr,ws) [Parg]
+FEATURE: Core | Added a basic 'speed limit' handler with support for defining and scheduling various speed limit profiles [Parg]
+FEATURE: Core | Added system property to set default timezone (azureus.timezone)
+FEATURE: Core | Detect some types of corrupt torrents and add Help menu item to attempt a fix [Parg]
+FEATURE: Core | Support for &fl arguments in magnet links
+FEATURE: Core | Handle https->http redirects [Parg]
+FEATURE: Core | Handle http redirects with http seeds [Parg]
+
+FEATURE: UI   | Warning triangle at bottom right now flashes a number of times when warnings are added [Parg]
+FEATURE: UI   | Added to Devices configuration to allow 'play now' buffering time to be configured [Parg]
+FEATURE: UI   | Added ability for the Library filter to search on comments (prefix with c:) and file names (prefix with f:) [Parg]
+FEATURE: UI   | Extended Library filter search of tracker URLs (prefix with t:) to consider all trackers [Parg]
+FEATURE: UI   | Added negation to Library filter logic (prefix with !)
+FEATURE: UI   | Made it clearer when Library filter in regular expression mode and the regex is in error [Parg]
+FEATURE: UI   | Added details of hidden generic devices to tooltip to surface them [Parg]
+FEATURE: UI   | Option to remove all devices that have been discovered [Parg]
+FEATURE: UI   | Added feature to allow devices to be explicitly tagged and then the view restricted to only those devices [Parg]
+FEATURE: UI   | Added the number of matches found to the Library title information when filtering [Parg]
+FEATURE: UI   | Added options to status bar IP Filter stats to get to IP Filter options [Parg]
+FEATURE: UI   | Added 'next ETA' and speed controls to the Transfer Bar [Parg]
+FEATURE: UI   | Added option to the torrent-add window to enable IP Filters [Parg]
+FEATURE: UI   | Added 'explore folder' for torrent files to advanced menu [Parg]
+FEATURE: UI   | Added magnet export to Shares view [Parg]
+FEATURE: UI   | Added right-click torrent view menu to a torrent's detail view header [Parg]
+FEATURE: UI   | Extended search results header to include active total [Parg]
+FEATURE: UI   | Added menu option to remove a search template to the right-click menu on search results [Parg]
+FEATURE: UI   | Extended recognised clients [Parg]
+FEATURE: UI   | Better error messaging for broken plugin installs [Parg]
+FEATURE: UI   | Enhanced search box - allows for entry of magnet links, torrent urls and hashes in the search box [Parg]
+FEATURE: UI   | Support 'bits' based base-10 display unit [Parg]
+FEATURE: UI   | Export magnet URI menu added to Share View [TuxPaper] 
+FEATURE: UI   | Allow dragging stuff to Share View sidebar entry [TuxPaper]
+FEATURE: UI   | Added Tracker Name column header menu option to allow specification of preferred trackers to display for multi-tracker torrents [Parg]
+
+FEATURE: Plug | New highcharts stats demo plugin [Parg]
+FEATURE: Plug | New plugin to add tracker URLs to multiple torrent [Parg]
+FEATURE: Plug | Added JSON request format to Vuze Web Remote along with start-all and stop-all RPC support [Parg]
+FEATURE: Plug | Added plugin ability to add rate limiters to downloads and peers [Parg]
+FEATURE: Plug | Added alerts to Vuze Web Remote if default folders not configured [Parg]
+FEATURE: Plug | Persist default media server name in UPnP Media Server [Parg]
+
+CHANGE: Core  | Fallback to 'DOT_ALL' matching when no results found. This allows search templates to specify constructs such as .*? correctly [parg]
+CHANGE: Core  | Disable fast-extension for downloads with explicit speed limits set as they aren't applied correctly [Parg]
+CHANGE: Core  | Maintain seeding-only and downloading-only totals based on real elapsed time to be consistent across computer sleeps [Parg]
+CHANGE: Core  | Import &tr arguments from magnet links
+CHANGE: Core  | Support some more (non-standard) RSS date formats [Parg]
+CHANGE: Core  | Added support for Double values in BEncoder [Parg]
+CHANGE: Core  | Handle common type in URL protocol in torrents [Parg]
+CHANGE: Core  | Automatically retry failed torrent downloads with an explicit referrer [Parg]
+CHANGE: Core  | Don't auto-retry transcodes on permanent failures (such as lack of disk space) [Parg]
+
+CHANGE: Plug  | Try setting up user-level registry entries when iTunes integration fails [Parg]
+
+CHANGE: UI    | Disable 'show generic' devices option when there aren't any [Parg]
+CHANGE: UI    | Include torrent name in SSL certificate trust window [Parg]
+CHANGE: UI    | Changed %done torrents view item to excluded DND files [Parg]
+CHANGE: UI    | Improved error message on add-torrent fail to make the cause more obvious [Parg]
+CHANGE: UI    | Auto-open and scroll the details area on magnet add so user sees error messages [Parg]
+CHANGE: UI    | Extended update tracing for 64 bit windows SWT updates [Parg]
+CHANGE: UI    | OSX: Enable playing sound on completion [TuxPaper]
+CHANGE: UI    | Replaced native OS tables with custom (faster, more control) [TuxPaper]
+CHANGE: UI    | 'All' and 'Uncategorized' are now shown in Sidebar when categories in sidebar is enabled [TuxPaper]
+
+BUGFIX: Core  | Fixed I2P Proxy support and updated the plugin to fix issues with I2P network integration [Parg]
+BUGFIX: Core  | Handle malformed XML entity escapes better [Parg]
+BUGFIX: Core  | Support SSL certificate install for scrapes [Parg]
+BUGFIX: Core  | Added code to detect potentially evil regex (http://en.wikipedia.org/wiki/ReDoS) [Parg]
+BUGFIX: Core  | Fixed edge-case file rechecking issue with piece-reordering mode [Parg]
+BUGFIX: Core  | Fixed ETA calc for Play-Now files in multi-file torrents [Parg]
+BUGFIX: Core  | Avoid enumerating USB drives if we crashed doing so last time (happening with some encrypted volumes) [Parg]
+BUGFIX: Core  | Handle existance of null entries in search template column maps [Parg]
+BUGFIX: Core  | Secondary lookup service URL was wrong [Parg]
+BUGFIX: Core  | Work around for torrents with illegal characters in file names [Parg]
+BUGFIX: Core  | Work around for systems where ti is taking huge amounts of CPU to enumerate network interfaces (mainly due to masses of borked 6to4 adapters) [Parg]
+BUGFIX: Core  | Handle malformed 'upload only' values that are appearing [Parg]
+BUGFIX: Core  | Re-enable streaming of incomplete files [Parg]
+BUGFIX: Core  | Only udp-probe the IP network [Parg]
+BUGFIX: Core  | Handle truncated peer response from trackers [Parg]
+
+BUGFIX: UI    | Update UI on subscription name change [Parg]
+BUGFIX: UI    | Fixed null-pointer exception in remote pairing dialog [Parg]
+BUGFIX: UI    | Roll up some of the device stats correctly when tree nodes not expanded [Parg]
+BUGFIX: UI    | Fixed some forum links in the client [Parg]
+BUGFIX: UI    | Ensure filter background is consistently drawn and reverify regex when switching modes [Parg]
+BUGFIX: UI    | Double buffer All Transfer and Mini Bars to reduce flicker [Parg]
+BUGFIX: UI    | Double buffer transfer-stats view [Parg]
+BUGFIX: UI    | Re-enable the start/stop toolbar options for transcoding view [Parg]
+BUGFIX: UI    | Disable toolbar icons correctly when no selection [Parg]
+BUGFIX: UI    | Fix drag+drop behaviour onto Shares view [Parg]
+BUGFIX: UI    | Fixed table row consistency issue when downloads rapidly removed and added [Parg]
+BUGFIX: UI    | Fixed incorrect base-10 unit display [Parg]
+BUGFIX: UI    | Fixed menu not showing on first right click on the Torrent Details sidebar entry [TuxPaper]
+BUGFIX: UI    | OSX: Fixed buttons in Column Setup not all being displayed [TuxPaper] 
+
+BUGFIX: Plug  | Various minor fixes to mlDHT [Parg]
+
+
+
+2011.12.02 | Vuze 4.7.0.2
+
+FEATURE: Core | Initial support for portable Windows Vuze installs (see http://wiki.vuze.com/w/Portable_Vuze) [Parg]
+FEATURE: UI   | Toggle Fullscreen mode using Command-Shift-F (Mac) or Control-Shift-F (Non-Mac) [TuxPaper]
+FEATURE: UI   | Added filter mode to files view [Parg]
+FEATURE: UI   | Added text-alignment option to column setup [Parg]
+
+BUGFIX: Core  | Fixed version server check protocol fallback bug [Parg]
+BUGFIX: UI		| Fixed image management resource leak [Parg]
+
+
+
+2011.09.21 | Vuze 4.7.0.0
+
+FEATURE: Device | Improved Device Playback support: improved compatibility and many new devices added [TuxPaper]
+
+CHANGE: Core    | Moved some device detection code out of core [TuxPaper]
+CHANGE: Plug    | Removed IView, AbstractIView, SWTManager and other deprecated plugin APIs [TuxPaper]
+CHANGE: Device  | Button for "Do Not Transcode" [TuxPaper]
+CHANGE: Device  | Sidebar icon for devices that supply one [TuxPaper]
+CHANGE: UI      | Switched all views using IView to UISWTVIew [TuxPaper]
+CHANGE: UI      | Moved all non UI table refreshing code out of SWT thread (should result in faster UI) [TuxPaper]
+CHANGE: Misc    | Removed various left over and unused code (saved a measly 200k) [TuxPaper]
+
+BUGFIX: Core    | Fix OSX Lion problems
+
+
+
+2011.03.10 | Vuze 4.6.0.4
+
+CHANGE: UIv3  | Better messaging for Plus users on license expiry
+CHANGE: UI    | 50% faster table redraw on Windows when cell value changes [TuxPaper]
+
+BUGFIX: UI    | Fixed some dialogs that could open larger than the screen size [TuxPaper]
+
+
+
+2011.02.01 | Vuze 4.6.0.2
+
+FEATURE: Core | Relocate MOOV atoms to front of mp4 files for streaming [Parg]
+FEATURE: Core | Allow specification of IP address restriction for device content availability [Parg]
+FEATURE: Core | Grab <torrent> entities from RSS feed if present [Parg]
+FEATURE: Plug | Rate limit download speeds when play-now active to avoid disk contention [Parg]
+FEATURE: UI   | Add 'Play Now' column for streaming [TuxPaper]
+
+CHANGE: UI    | Added visual indication to first level menu for auto-device xcode selection [Parg]
+CHANGE: UI    | Support drag-n-drop onto classic share view [Parg]
+
+BUGFIX: Core  | Fix rare case where torrent at top of queue doesn't start & one later in the queue continues to download [TuxPaper]
+BUGFIX: Core  | Fix case where certain non-ASCII chars were causing metasearch config bloat [Parg]
+BUGFIX: Core  | Fix incorrect handling of reload of upnpav plugin resulting in xcodes disappearing until restart [Parg]
+BUGFIX: Plug  | Restore AV 'scanning' spinner icon [Parg]
+BUGFIX: UI    | Fix missing columns in "New" view [TuxPaper]
+BUGFIX: UI    | Fix drag indicator when prioritizing torrents in Library [TuxPaper]
+BUGFIX: UI    | Fix case where certain non-ASCII categories were causing azureus.config to bloat [TuxPaper]
+BUGFIX: UI    | Fix cases where Web Search wasn't opening results in external browser [TuxPaper]
+BUGFIX: UI    | Fix incorrect toolbar selection when in files view [Parg]
+BUGFIX: UI    | Fix incorrect handing of devices set to 'never transcode' [Parg]
+
+
+
+2011.01.13 | Vuze 4.6.0.0
+
+FEATURE: Core | UDP NAT Test tool [Parg]
+FEATURE: Core | Added device export/import feature [Parg]
+FEATURE: Plug | uTP support [Parg]
+FEATURE: Plug | Streaming playback [Parg]
+FEATURE: Plug | Added simple HTML view and explicit download option to device RSS feed [Parg]
+FEATURE: UI   | Add menu link from sidebar entries to plugin options where applicable [Parg]
+FEATURE: UI   | Option for what happens when pressing delete key or tb delete in My Torrents/Library [TuxPaper]
+FEATURE: UI   | Allow dropping torrent URLs onto sidebar (to add torrent) [TuxPaper]
+
+CHANGE: Core  | Prevent UDP scrape probes and DHT fallback scrape values from overriding more relevant values [Parg]
+CHANGE: Core  | Added some more client type peer-id decodes [Parg]
+CHANGE: Core  | Ensure piece picker file priorities take precedence over first/last piece [Parg]
+CHANGE: Core  | Don't auto-xcode low noise torrents [Parg]
+CHANGE: Core  | Propagate cookies across http->https redirects [Parg]
+CHANGE: Core  | Various minor startup tweaks to increase startup performance [TuxPaper]
+CHANGE: Plug  | Bump up the DHT minimum supported version [Parg]
+CHANGE: Plug  | Added option to force delayed restart on install [Parg]
+CHANGE: UI    | Rate limit various update operations to improve performance [Parg]
+CHANGE: UI    | Make tracker update button scrape torrents that are stopped [Parg]
+CHANGE: UI    | Wire up play button to xcoded content [Parg]
+CHANGE: UI    | Sidebar redesign [TuxPaper]
+CHANGE: UI    | Categories can now be shown in sidebar [TuxPaper]
+CHANGE: UI    | Filter text in Config view now gets highlighted [TuxPaper]
+
+BUGFIX: Core  | Fix poor perf with large peer connection count [Parg]
+BUGFIX: Core  | Pickup changes in transcode file categories [Parg]
+BUGFIX: Core  | Disable outbound UDP data connections if proxy set [Parg]
+BUGFIX: Core  | Fix reading some rare .torrent files with only UTF-8 keys [TuxPaper]
+BUGFIX: Core  | Fix bug when loading multiple .torrent files at once when they have the same URL filename [TuxPaper]
+BUGFIX: Plug  | Fixup names displayed during plugin load/init [Parg]
+BUGFIX: UI    | Prevent sources from being added multiple times [Parg]
+
+
+
+2010.10.05 | Vuze 4.5.1.0
+
+FEATURE: Core | Monitor available JVM memory and warn user if it is running out and auto increase (Windows only) [Parg]
+FEATURE: UI   | Support opening .vuze files from URLs [Parg]
+FEATURE: UI   | Allow setting of JVM direct memory max from UI (Windows only) [Parg]
+FEATURE: UI   | Added 'protocol' column to peers view [Parg]
+FEATURE: UI   | Expanded state of Sidebar entries are now remembered [TuxPaper]
+FEATURE: UI   | (Windows) Added Closeable Games sidebar entry [TuxPaper]
+
+CHANGE: Core  | Changed the trigger for upload rate bias when unlimited upload and inactive downloads [Parg]
+CHANGE: Core  | Permit export of all search templates [Parg]
+CHANGE: Core  | Reduce debug messages for connection-refused type tracker errors [Parg]
+CHANGE: Core  | Reduce version-check timeouts to prevent version server errors from adversely affecting Vuze [Parg]
+CHANGE: Core  | Be more tolerant of large PEX messages as clients are sending valid exchanges that exceeded our old limits [Parg]
+CHANGE: Core  | Improve detection of devices [TuxPaper]
+CHANGE: Core  | Report better error messages for failed plugin installs [Parg]
+CHANGE: Core  | Add alert details to alert log [Parg]
+CHANGE: Core  | Log plugin load-at-start state to diagnostics [Parg]
+CHANGE: UI    | Better handling in in-client browser for search engines and (blocking) pop-ups [TuxPaper]
+CHANGE: UI    | Device status column now reports when a file is being copied to the device [TuxPaper]
+
+BUGFIX: Core  | Fixes to superseeding mode [thanks Mmore1q3]
+BUGFIX: Core  | Fixed up disabling of UDP tracker protocol and added option to control UDP probing [Parg]
+BUGFIX: Core  | Fixed bug involving switching search template from manual to auto mode [Parg]
+BUGFIX: Core  | Immediately drop incoming connections for stopped downloads (they used to persist and timeout later) [Parg]
+BUGFIX: Core  | Fixed bug whereby add-for-seeding torrents with reorder-piece file mode and move-to dirs resulted in download being marked as incomplete [Parg]
+BUGFIX: Core  | OSX - handle UTF-8 BOM in plist [Parg]
+BUGFIX: UI    | Sort column editor available table correctly [Parg]
+BUGFIX: UI    | Fix case where sidebar doesn't display properly at startup [TuxPaper]
+BUGFIX: UI    | Changing name of Device should now be remembered [TuxPaper]
+BUGFIX: *     | Fix various Null Pointer Exceptions [TuxPaper]
+
+
+
+2010.09.01 | Vuze 4.5.0.4
+
+FEATURE: Core | Allow multiple primordial UDP handlers [Parg]
+FEATURE: UI   | Ability to auto-send crash logs [TuxPaper]
+FEATURE: UI   | Members of the Beta Program now get a Sidebar entry which will one day have useful beta information [TuxPaper]
+
+CHANGE: UI    | Improved languages change detection so more of the text now shows in the new language (unfortunately not all) [TuxPaper]
+CHANGE: UI    | (Windows) Bigger click area around the "X" in the Library's filter box [TuxPaper]
+CHANGE: UI    | (Windows) Triple click in search box now selects all the text [TuxPaper]
+CHANGE: UI    | Replaced "Remove And.." menu tree from Library's content menu with "Remove..." entry that gives you the same options.  Two related configs are in Options->Files->"File Deletion" [TuxPaper]
+
+BUGFIX: Core  | (Windows) Fix drive detection/removal when multiple drives get added/removed at once [TuxPaper]
+BUGFIX: Core  | (Windows) Fix drive with letters D: H: L: P: T: X: not being detected when plugged in while Vuze was running [TuxPaper]
+BUGFIX: Core  | Fixed some hard drives incorrectly being added as a Device and shown in the sidebar [TuxPaper]
+BUGFIX: Core  | (OSX) Add additional (new?) crash log directory to crash log generator (debug.zip) [TuxPaper]
+BUGFIX: Core  | (OSX) Fixed two cases where main window would not show after clicking the dock icon [TuxPaper]
+BUGFIX: Core  | Don't open files with write-access unless required [Parg]
+BUGFIX: Core  | Ensure new profiles are picked up when xcode plugin reloads [Parg]
+BUGFIX: Core  | Correctly sequence plugin events to ensure that listeners see the correct plugin state [Parg]
+BUGFIX: Core  | Delete .vuze files when subscriptions are removed [Parg]
+BUGFIX: UI    | (*nix) Fix table cells not getting click events (affected triggering the "New" column's state) [TuxPaper]
+BUGFIX: UI    | Fix case where scrolling right in a table view (Library) didn't draw the newly visible columns [TuxPaper]
+BUGFIX: UI    | Fixed some cases where column re-ordering was not being remembered [TuxPaper]
+BUGFIX: UI    | Fix Help->Check for Updates not notifying user there were no new updates found [TuxPaper]
+BUGFIX: UI    | Fixed visual problems with Tracker Status column when "Don't Scrape Stopped" is enabled [TuxPaper]
+BUGFIX: UI    | Fixed Queue and Stop not working on Torrent menu and right click of Sidebar's download's details item [TuxPaper]
+BUGFIX: UI    | (OSX) Fixed bug where a false double click was registered when Vuze did not have the focus and you single clicked on a row in the Library [TuxPaper]
+BUGFIX: UI    | Fixed subscription name and count on Sidebar not redrawing when either changes [TuxPaper]
+
+
+
+2010.08.06 | Vuze 4.5.0.2
+
+CHANGE: Core  | Prevent device manager initialisation in classic UI [Parg]
+
+BUGFIX: UI    | Setting files to 'delete' state corrupting internal view of a torrent's files [Parg]
+BUGFIX: UI    | Added reworked progress column to library view by default in place of completion date to allow file manipulation from that view [Parg]
+BUGFIX: UI    | Consistently show the file-expand twisty [Parg]
+
+
+
+2010.08.04 | Vuze 4.5.0.0
+
+FEATURE: Plug | Android Devices support
+
+CHANGE: Core  | Try alternative trackers when seeding and zero connected peers [Parg]
+
+BUGFIX: UI    | Layout improvements in torrent Info view [Parg]
+BUGFIX: UI    | Fixed occasional crash when twisting twistie on Windows 7
+
+
+
+2010.07.31 | Vuze 4.4.1.0
+
+FEATURE: Core | Handle "bc://" URLs [TuxPaper]
+FEATURE: Core | Switched to piece-reordering based file storage on OSX by default (option for other OS) [Parg]
+FEATURE: Core | Recover out-of-order pieces on recheck [Parg]
+FEATURE: Core | Added numeric file priorities to allow more than just 'high' and 'normal' priorities [Parg]
+FEATURE: Core | Basic streaming playback support, relegated to CVS only on release due to lack of time to tidy up UI [Parg]
+FEATURE: Core | New speed test [Parg,Tux]
+FEATURE: Core | Bias upload to incomplete downloads [Parg]
+FEATURE: UIvz | Library view entries can now be expanded to see individual files [TuxPaper]
+FEATURE: UI   | Added [Reset] button to Torrent->Rename.. dialog [TuxPaper]
+
+CHANGE: Core  | Proxy UDP tracker conns through socks when enabled [Parg]
+CHANGE: Core  | Clear out unused subscriptions [Parg]
+CHANGE: Core  | Grab default SSL certs from Java on init [Parg]
+CHANGE: Core  | Some packeting optimisations with crypto [Parg]
+CHANGE: Core  | Fixed some issues to allow plugins to be network position providers [Parg]
+CHANGE: UI    | Show zero length files as completed rather than 0% done [Parg]
+CHANGE: Plug  | Various enhancements to facilitate the writing of cache peers [Parg]
+
+BUGFIX: Core  | Better handle torrents with valid UTF8 name, but invalid (to user's locale) non-UTF name. [TuxPaper]
+BUGFIX: Core  | Fix slow core closedown caused by subscription updates [Parg]
+BUGFIX: Core  | Fix a few places where only subscribed subscriptions should be used [Parg]
+BUGFIX: Core  | Fix webseed handling for files bigger than 2GB (ish) [Parg]
+BUGFIX: Core  | Ensure all file handles released when closing down streams [Parg]
+BUGFIX: Core  | Removed double timestamps from some logs [Parg]
+BUGFIX: Core  | For trackerless torrents fix to use cached peers on startup [Parg]
+BUGFIX: Core  | Fix bug where DHT wasn't re-publishing values correctly [Parg]
+
+
+
+2010.06.04 | Vuze 4.4.0.6
+
+CHANGE: Core  | Improved logging
+BUGFIX: Core  | Search edge case
+
+
+
+2010.05.08 | Vuze 4.4.0.4
+
+BUGFIX: Core  | Fix PEX bug [Parg]
+BUGFIX: Core  | Fix "Error Running Veto Check" error [TuxPaper]
+BUGFIX: Core  | (*nix) Fix client not launching after launched once [TuxPaper]
+BUGFIX: UI    | Fix late-loading sidebar entries not auto-opening [TuxPaper]
+
+
+
+2010.05.03 | Vuze 4.4.0.2
+
+CHANGE: UI    | (OSX) Prep client for SWT 3.6 (M7 and later) [TuxPaper]
+CHANGE: UI    | (OSX) Use Java calls for moveToTrash and showInFinder [TuxPaper] 
+CHANGE: UI    | Double click in library view on incomplete downloads no longer invokes the launch manager for permission [Parg]
+CHANGE: Core  | Added some new message types to help diagnose connection speed issues [Parg]
+CHANGE: Core  | Removal of various useless debug generation [Parg]
+CHANGE: Core  | Use UTF-8 for debug files [Parg]
+
+BUGFIX: Plug  | If EMP is disabled fall back to default player [Parg]
+BUGFIX: Core  | Fix deadlock condition in devices view [Parg]
+BUGFIX: Core  | Prevent single key failure from exiting select result processing [Parg]
+BUGFIX: Core  | Fix deadlock when download stopped while move-on-complete in progress [Parg]
+BUGFIX: Core  | Various fixes to handle restarts with non-ascii user directory name [Parg]
+BUGFIX: Core  | Ensure plugin verification works with internationalised plugin dir name [Parg]
+BUGFIX: UIvz  | Fix bug where toolbar was hidden with no way of showing it [TuxPaper]
+BUGFIX: UIvz  | Fix bug where DVD Burn sidebar entry would reappear after removing it and restarting [TuxPaper]
+BUGFIX: UIvz  | When doubleclick in Library is set to show details, don't show AntiVirus warning [TuxPaper]
+BUGFIX: UIvz  | Fix OSX case where client could not be started due to old SWT version [TuxPaper]
+BUGFIX: UIvz  | Fix case where there was nothing downloading, but the download spinner in the sidebar was still present [TuxPaper]
+
+
+
+2010.04.05 | Vuze 4.4.0.0
+
+FEATURE: Core | Feature manager [Parg]
+FEATURE: Core | Added mechanism to add virtual devices [Parg]
+FEATURE: Core | On-demand media analysis [Parg]
+FEATURE: Core | Added a few hooks to ease third party use of code [Parg]
+FEATURE: Core | Added means to hook into content launch operations [Parg]
+FEATURE: Core | Allow devices to be specified as 'no xcode required' [Parg]
+FEATURE: Core | Added option to prevent IP filters being cleared on reload [Parg]
+FEATURE: Core | Re-attempt torrent download via magnet if possible [Parg]
+FEATURE: Plug | Added mechanism for a cache-plugin to reserve pieces for their cache-peer [Parg]
+FEATURE: Plug | Added mechanism for plugins to specify executable properties of installed files [parg]
+FEATURE: Plug | Added method for testing if move-on-complete actions are active [Parg]
+FEATURE: UI   | Toolbar support for selecting files in file-view [Parg]
+FEATURE: UI   | Feature Manager UI [TuxPaper]
+FEATURE: UI   | Better Drag&Drop indication on sidebar [TuxPaper]
+FEATURE: UI   | Better pop-out/pop-up supression from Search Results pages [TuxPaper]
+
+CHANGE: Core  | Added ability to add xcodes in stopped state [Parg]
+CHANGE: Core  | When there's only one transcode profile available, don't allow user to make a (non-existant) choice [Parg]
+CHANGE: Core  | Added country-code to version server response [Parg]
+CHANGE: Core  | Don't push direct file reads through the file cache [Parg]
+CHANGE: Plug  | Allow plugins to force their columns to be visible [Parg]
+CHANGE: Core  | Allow the removal of transcode jobs to be vetoed [Parg]
+CHANGE: Core  | Take USB detection off init thread in case it hangs [Parg]
+CHANGE: Core  | Added download property to allow force and direct deletion to be specified [Parg]
+CHANGE: Core  | Enforce update action ordering [Parg]
+CHANGE: Plug  | Added swt info to update check to allow different plugin versions for different swt [Parg]
+CHANGE: UI    | Limit max torrent file size to prevent bad behaviour when large files dropped onto UI [Parg]
+CHANGE: UI    | Truncation percentages shown for xcode to avoid useless ".0" [Parg]
+CHANGE: UI    | Restructure Sidebar/Tab system into a common MDI structure [TuxPaper]
+CHANGE: UI    | Some dialogs now switch Ok/Cancel to Cancel/Ok on OSX [TuxPaper]
+
+BUGFIX: Core  | Fix 'no space' display for offline downloaders [Parg] 
+BUGFIX: Core  | Fixed opening torrent from Finder bug under OSX 10.4 [TuxPaper]
+BUGFIX: Core  | Magnet download of large torrent files speed up [Parg]
+BUGFIX: Core  | Resource downloader was firing complete events twice sometimes [Parg]
+BUGFIX: Core  | File channel support for 2GB+ files [Parg]
+BUGFIX: Core  | Update pending files in xcode view when files deletes [Parg]
+BUGFIX: Core  | Fix relayout bug in status bar [Parg]
+BUGFIX: Core  | Fix various places where linked files were being ignored [Parg]
+BUGFIX: Core  | Fix rare case where Donation window was popping up too often [TuxPaper]
+BUGFIX: Plug  | Ensure that reloaded plugin's message resources are loaded [Parg] 
+BUGFIX: Plug  | Ensure installation failures are reported [Parg]
+BUGFIX: UI    | Extend cell refresh logic to include those with refresh listeners [Parg]
+BUGFIX: UI    | Fix rare case where table sort order is incorrect after raid data updates [TuxPaper]
+BUGFIX: UI    | Patch case where Vuze prevents Windows 7 from shutting down [TuxPaper]
+BUGFIX: UI    | Fix buttons having ugly BG on Win7 [TuxPaper]
+BUGFIX: UI    | Fix some columns not showing up in "All Torrents" views [TuxPaper]
+BUGFIX: UI    | Fix clipboard menu not working for some columns (Torrent Name Column) [TuxPaper]
+
+
+
+2010.02.09 | Vuze 4.3.1.4
+
+BUGFIX: Core  | Fixed bug whereby HAVE_ALL messages were failing to set the last bit of the bit-flags [Parg] 
+
+
+
+2010.02.01 | Vuze 4.3.1.2
+
+FEATURE: Core | Added .vuze file format to trigger a search operation [Parg]
+
+CHANGE: Core  | Disable IPv6 under Windows by default, as it needs Java7 to work properly [Nolar]
+CHANGE: Core  | Added system property to disable instance manager [Parg]
+CHANGE: Core  | Give user friendlier error message when offline-downloader disconnected [Parg]
+CHANGE: Core  | Auto-dump threads if shutdown takes > 30 seconds [Parg]
+CHANGE: UI    | Permit deletion of classicaly shared content from download/seeding views [Parg]
+
+BUGFIX: Core  | Wait until sid registered before attempting pairing test [Parg]
+BUGFIX: Core  | Various pairing HTTPS fixes [Parg]
+BUGFIX: Core  | Fix missing 'logout' button when paired with no authentication [Parg]
+BUGFIX: UI    | Windows - Vuze now pops up if closed to system tray and user launches exe [TuxPaper]
+BUGFIX: UI    | Fixup some Remote Pairing dialog edge case bugs [TuxPaper]
+BUGFIX: UI    | OSX - Fix sidebar animations sometimes not animating [TuxPaper]
+BUGFIX: UI    | OSX - Text in table views are now the correct color (white) when selected [TuxPaper]
+BUGFIX: UI    | Protect against case where Main Window's stored dimensions area invalid or stupidly small [TuxPaper]
+BUGFIX: UI    | Fix invalid thread access and NPE when closing pairing dialog [Parg]
+BUGFIX: UI    | Fixed case where status bar was blank after deiconifying [TuxPaper]
+
+
+
+2010.01.23 | Vuze 4.3.1.0
+
+FEATURE: Core | Option to auto-start Vuze on login on Windows and OSX [Parg]
+FEATURE: Core | Option to close Vuze when downloads/seeding complete [Parg]
+FEATURE: Core | Sources details view and tracking enhancements [Parg]
+FEATURE: Core | Option to automatically set upload slots and connections limits based on measured line speed [Parg]
+FEATURE: Core | Added support for fast-allowed pieces [Parg]
+FEATURE: Core | Extract downloaded values if returned by tracker [Parg]
+FEATURE: Plug | Added auto-authorisation default to pairing enabled web plugins [Parg]
+FEATURE: Core | Windows - added JVM max/min memory configuration to the options [Parg] 
+FEATURE: Core | Added support for webseeds in magnet links [Parg]
+FEATURE: Core | Added support for less-verbose auto-full-update [Parg]
+FEATURE: Core | Completed the 'pairing' feature [Parg]
+FEATURE: UI   | Added Pairing dialog [TuxPaper]
+
+CHANGE: Core  | Added local network interfaces to pairing details [Parg]
+CHANGE: Core  | Drop the half-open TCP socket limits for Vista SP2+ and Windows 7 [Parg]
+CHANGE: Core  | Modify connection timeouts if sufficient peers available [Parg]
+CHANGE: Core  | Ignore HTTP seeds if we're seeding [Parg]
+CHANGE: Core  | Vary min requests when starting up [Parg] 
+CHANGE: Core  | Changed metasearch default to auto=true [Parg]
+CHANGE: Core  | Default save directory for new installs switched from 'Azureus Downloads' to 'Vuze Downloads' [Parg]
+CHANGE: Core  | Auto-enable the 'connections per torrent when seeding' default and set to half the normal number of connections [The8472]
+CHANGE: Core  | When force-closing Vuze delete any outstanding updates to prevent them being applied [Parg]
+CHANGE: Plug  | Make WebPlugin configuration parameters amendable without requiring a Vuze restart [Parg]
+CHANGE: UI    | Added arrows to swarm view and differentiate unchokes/fast requests [Parg]
+CHANGE: UI    | Moved slideys that were System Notifications to statusbar [TuxPaper]
+
+BUGFIX: Core  | Fix remembering of auto-speed settings on restart [Parg]
+BUGFIX: Core  | Fix initial storing of search engine rank bias [Parg]
+BUGFIX: Core  | Fix LT Peer-Exchange bug [Parg]
+BUGFIX: Core  | Remove HTTP seeds when stopping download [Parg]
+BUGFIX: UIvz  | Fix list view modes (menu and button display) being grayed out when toolbar is in "No Text" mode [TuxPaper]
+BUGFIX: UI    | Remove cached peers from swarm view on data source change [Parg]
+BUGFIX: UI    | When upgrading SWT, dialog box now shows correct platform (Cocoa, Carbon) [TuxPaper]
+
+
+
 2009.12.10 | Vuze 4.3.0.6
 
 BUGFIX: Core  | Fixed bug where compact file types could lead to spurious 'file length too large' errors [Parg]
@@ -71,7 +647,7 @@ 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  | Improved IPv6-handshaking and reconnects with other clients (see http://wiki.vuze.com/w/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]
@@ -303,7 +879,7 @@ BUGFIX: UIvz  | Fixed bug where "My Library" info bar displayed on Downloading s
 BUGFIX: UIvz  | Fix some notification entries losing their related avatar image [TuxPaper]
 BUGFIX: UIvz  | Log View's "Show Config" button wasn't going to proper config section [TuxPaper]
 BUGFIX: UIvz  | Fix default visible columns, order, and sort column for new installs for "Advanced" library Lists [TuxPaper]
-BUGFIX: UI    | "Show Time" state on date columns now remembered accross sessions [TuxPaper]
+BUGFIX: UI    | "Show Time" state on date columns now remembered across sessions [TuxPaper]
 BUGFIX: UI    | Fix "Pieces" column in Library view not updating unless you clicked it [TuxPaper]
 BUGFIX: UI    | Info tab in Torrent Details now displays more columns that it couldn't before (like share ratio) [TuxPaper]
 BUGFIX: UI    | Localize the date in the subscription view correctly [Parg]
@@ -416,381 +992,3 @@ BUGFIX: Plug  | Various fixes to avoid DHT running out of control under extreme
 BUGFIX: Plug  | Fix magnet download timeouts [Parg]
 BUGFIX; Plug  | Fix DHT operation timeout bug introduced when moving to async exec [Parg]
 BUGFIX: Plug  | Limit buddy reconnect to avoid thrashing [Parg]
-
-
-
-2008.07.01 | Vuze 3.1.1.0
-
-FEATURE: Core | Added Auto Starting rule to seed large swarms first; useful when many overseeded torrents are in the queue or the upload capacity is far above average [The 8472]
-FEATURE: UIv3 | Friend Chat (double click on friend icon to chat) [Gudy]
-FEATURE: UIv3 | Friends Online Status
-FEATURE: UIv3 | Ability to share content from your computer by dragging it to a Friend [Gudy]
-
-CHANGE: Core  | Built-in plugins can now be disabled - it didn't work properly in earlier versions [amc1]
-CHANGE: UI    | Create Vivaldi views for each DHT in use [Groundy]
-CHANGE: UI    | Added support for rotation in Vivaldi view [Groundy]
-CHANGE: UI    | Peers view hostname column now sorts host names by the most significant part first [The 8472] 
-CHANGE: UIv3  | Finished fixes for the new styled dialog which are now default in Vuze/Vuze Advanced [knguyen]
-CHANGE: UIv3  | Added friend icon next to activity entry [TuxPaper]
-CHANGE: UIv3  | New plugin bar look (removed arrows, added selectable list all plugin bar views) [TuxPaper]
-
-BUGFIX: Core  | Fixed bug which stopped downloads being stored in the chosen directory [amc1]
-BUGFIX: Core  | Fixed bug which prevented torrent files from being moved properly [amc1]
-BUGFIX: Core  | Reopening torrents does not delete files when setting some of the already existing files to DND anymore [The 8472]
-BUGFIX: Core  | Fixed bug which prevented UPnP mappings from being successful when a SOCKS proxy was used [amc1]
-BUGFIX: UI    | Fixed bug where delete icon on toolbar was not present on OSX [TuxPaper]
-BUGFIX: UI    | Blank cells are now properly put at the bottom when sorting a table column [amc1]
-BUGFIX: UIv3  | Fixed bottom of list views not repainting properly [TuxPaper]
-BUGFIX: UIv3  | Remove type headers when switching to date sorting [TuxPaper]
-
-
-
-2008.06.16 | Vuze 3.1.0.0
-
-FEATURE: UI   | Protocol overhead is now shown in the speed graph [The 8472]
-FEATURE: UI   | Downloads can now be moved and renamed while running - torrent will be auto-paused [amc1]
-FEATURE: UI   | New "rename" action which renames torrent file, save file and displayed name at same time [amc1]
-FEATURE: UI   | Plugin log views now support autoscrolling, pausing and regex filtering [The 8472]
-FEATURE: UI   | Plugin menu items which in the right-click menu now appear in the "Torrent" menu also [amc1] 
-FEATURE: UIv3 | Friends (sharing, bandwidth boost)
-FEATURE: UIv3 | Greatly Improved Search
-FEATURE: UIv3 | Experimental option to use Mozilla/Firefox as browser widget on any platform (XulRunner or Firefox 3 must be installed) [The 8472]
-FEATURE: Plug | Added support for plugins to easily use an external configuration file for settings [amc1]
-FEATURE: Plug | Plugins can now have full control over on-complete and on-removal file moving [amc1]
-FEATURE: Plug | Added resource downloader to provide way to download files from Sourceforge [amc1]
-FEATURE: Plug | Added API methods to generically pop up the message box to a user [amc1]
-FEATURE: Plug | Added API methods to listen to download-complete events [amc1]
-FEATURE: Plug | Added various convenience methods for using log views and config models [amc1]
-FEATURE: Plug | Added API to allow native UI objects to be added to config views [amc1]
-FEATURE: Plug | Added some more methods for plugins to control some transport mechanisms [amc1]
-FEATURE: Plug | Added ability to add menus to status entry objects [amc1]
-FEATURE: Plug | Plugins can now open files using default application handlers [amc1]
-
-CHANGE: Core  | added "upload_only" flag to AZMP/LTEP handshakes, disconnect any uploading_only peers we don't need / that don't need us when disconnect seeds when seeding is set [The 8472]
-CHANGE: Core  | Further startup speed improvements [The 8472, amc1, Parg]
-CHANGE: Core  | Speedup of various file batch operations (priority changes) [amc1, The 8472]
-CHANGE: Core  | Added option to allow the removal of files linked outside the save directory when removing data [amc1]
-CHANGE: UI    | Column menu option to disable fast renaming in files view, changed fast rename to behave more like the windows explorer [The 8472]
-CHANGE: UI    | In console UI, shrunk help text down to be more concise [amc1]
-CHANGE: UIv3  | Removed Vuze Header (the top plugin bar is still there but you have to turn it on)
-
-BUGFIX: Core  | Made change so that plugins could not inadvertently turn off Azureus extension protocol [amc1]
-BUGFIX: Core  | The UDP tracker client option has been nonfunctional for quite a while now -> fixed [The 8472]
-BUGFIX: Core  | Fixed various file-priority-change related bugs that resulted in error states [The 8472]
-
-
-
-2008.04.10 | Azureus Vuze 3.0.5.2
-
-FEATURE: UIv3 | Ability to rate directly from rating reminder activity entry [TuxPaper] 
-FEATURE: UIv3 | Added progress spinner animation for the LightBox [knguyen]
-
-CHANGE: Core  | Don't auto-UDP probe on initial announce if tracker not known to support UDP - hit on second and remember outcome [Parg]
-CHANGE: Core  | Improve startup times by taking various torrent-load operations off main thread [Parg]
-CHANGE: Core  | Add reason-messages for update check failures [Parg]
-CHANGE: Core  | Use derived password to protect private key to allow us to persist password [Parg]
-CHANGE: Core  | Get plugin update URL from version server to support potential future switch [Parg]
-CHANGE: UI    | Run explicit tracker scrapes off UI thread to prevent blocking [Parg]
-CHANGE: UI    | Allow UI initialisation to proceed before plugin init complete [Parg]
-CHANGE: UIv3  | Always start on "Dashboard" tab (unless Advanced UI chosen), instead of sometimes starting on "On Vuze" tab [TuxPaper]
-CHANGE: Plug  | Ensure that DHT republish events are scheduled using absolute time so recover correctly from computer suspend [Parg]
-
-BUGFIX: Core  | Handle some badly formed torrents more gracefully (corrupt announce-lists) [Parg]
-BUGFIX: Core  | Handle multiple SSL certs from same URL [Parg]
-BUGFIX: Core  | URLDecode torrent filenames [Parg]
-BUGFIX: Core  | Fix non-crypto fallback outgoing connections [Parg]
-BUGFIX: Core  | Better (esp for Vista) detection of and setting of Azureus' .torrent file association [TuxPaper]
-BUGFIX: UI    | Fix broken per-torrent upload speed setting via options tab [Parg]
-BUGFIX: UI    | Fix alternating bg color not updating after changing in config [TuxPaper]
-BUGFIX: UIv3  | Fix resource leaks related to light box (login window) [knguyen]
-
-
-
-2008.03.05 | Azureus Vuze 3.0.5.0
-
-FEATURE: Core | Added µTorrent PEX support [amc1]
-FEATURE: Core | Azureus probes trackers for UDP-capabilities on first scrape/announce now and uses udp instead of http where available [The 8472]
-FEATURE: Core | Added option to enforce IP bindings even when the specified interfaces are not available (useful when Azureus should not use certain network interfaces) [The 8472] 
-FEATURE: Core | Intervene with http seeds if progressive stall imminent [Parg]
-FEATURE: Core | Message user on startup if they have installed Azureus to read-only location [Parg]
-FEATURE: Core | Added dnd status to XML stats [Parg]
-FEATURE: UI   | Added option for "Open Containing Folder" menu action - which may integrate better with non-standard file browsers [amc1]
-FEATURE: UI   | Added option for "Show Torrent Menu" -- Users can now decide to see the Torrent menu in the menubar or not [knguyen]
-FEATURE: UI   | Fast Renaming (not moving) in the Files tab (click on name column) and Open Torrent dialog (click on dest. name column) [The 8472]
-FEATURE: UI   | Completed downloaders column [The 8472]
-FEATURE: UI   | Added start/stop to category menu [Parg]
-FEATURE: UI   | Added per-category speed limits [Parg]
-FEATURE: UI   | Added per-category option setting [Parg]
-FEATURE: UI   | Added multiple-torrent options setting to MyTorrents view [Parg]
-FEATURE: UIv3 | New menu configuration for Vuze and Vuze Advanced UI's [knguyen]
-FEATURE: UIv3 | Activity Tab [TuxPaper]
-FEATURE: UIv3 | Vuze Login from client [knguyen]
-FEATURE: Plug | Added Network Status plugin to perform some basic network tests [Parg]
-FEATURE: Plug | Allow plugins to specify their minimum JDK requirements [Parg]
-
-CHANGE: Core  | Further memory footprint reductions; for additional tweaks see http://www.azureuswiki.com/index.php/Reduce_memory_usage [The 8472]
-CHANGE: Core  | Reimplemented LT extension protocol code [amc1]
-CHANGE: Core  | DND/Compact (aka Delete) priority now deletes all files that do not share pieces with normal/high priority files [The 8472]
-CHANGE: Core  | Queuing rules now don't start any further torrents if the global up/download speed limits are reached [The 8472]
-                 - makes "don't count torrent ..." minimum speed rules more useful to dynamically regulate the queue lengths
-                 - recovers faster from chain reactions in case of connection loss
-CHANGE: Core  | Made the crypto handshake a bit less predictable [The 8472]
-CHANGE: Core  | Added support for IPv6 compact announces (client) and udp-multiscrapes (client+server) [The 8472]
-CHANGE: Core  | Take note of more peer-source selections [Parg]
-CHANGE: Plug  | Added support for plugins which implement mainline DHT [amc1]
-
-BUGFIX: Core  | Request limiting/Priorities no longer pinch off LAN peers if seperate LAN speeds are enabled [The 8472]                 
-BUGFIX: Core  | Increase time Azureus holds open listen socket on close to reduce dual-start window [Parg]
-BUGFIX: Core  | Allow ~ character in tracker addresses to support I2P [Parg]
-BUGFIX: Core  | Determine app name correctly on OSX so that restart works for renamed apps [Parg]
-BUGFIX: UI    | Shells no longer use the low-res frog icon, the normal main window icon is now used instead [amc1]
-BUGFIX: UI    | Limiting comments in General View to 5k characters under WinXP to avoid crashes due to faulty comctl32.dll [The 8472]
-BUGFIX: UI    | Setting speed parameters manually now disables autospeed [The 8472]
-BUGFIX: Plug  | Encode spaces correctly in get-right web seed urls [Parg]
-
-
-
-
-2007.12.21 | Azureus Vuze 3.0.4.2
-
-FEATURE: UI   | Added "Check Files Exist" menu option [amc1]
-FEATURE: Plug | Perform low resource usage tracking of online torrents for swarm cross-population purposes [Parg]
-
-CHANGE: Core  | Added option to disable download speed focus [The 8472]
-CHANGE: Core  | Reduced memory usage for many-torrent instances [The 8472]
-CHANGE: UI    | Multiple selected torrent export now works [amc1]
-
-BUGFIX: Core  | Fixed IP filters not working when ALLOW instead of DENY was used [Parg]
-BUGFIX: Core  | Improve rebuffering behaviour when real-time pieces are too slow for any peers to get in time [Parg]
-BUGFIX: Core  | Ensure minimum buffer requirements are factored into ETA calculation [Parg]
-BUGFIX: UI    | Eliminated various memory leaks [The 8472]
-
-
-
-2007.12.06 | Azureus Vuze 3.0.4.0
-
-FEATURE: Core | Reconnect to peers after unexpected disconnect / recover stats of recently disconnected peers [Parg,The 8472]
-FEATURE: Core | Global download speed limit can also limit the number of outgoing requests, this should improve TCP performance [The 8472]
-                 -does not work with auto-speed since an explicit download speed-limit must be set
-                 -downloads from as few peers as possible when the global limit is reached 
-                 -prioritizes downloads which are on the head of the queue
-FEATURE: Core | IP binding now provides primitive round-robin load balancing for users with multiple internet connections; accepts interface names and IPv6 binding (if supported on the platform) [The 8472]
-FEATURE: Core | Embed ChangeLog.txt in release jar [Nolar]
-FEATURE: UI   | Column menu option to automatically put contents of cell into the tooltip [amc1] 
-FEATURE: UI   | Piece distribution view is now also available as a peer subview [The 8472]
-FEATURE: UI   | Added 'time remaining' column to peers view [Parg]
-FEATURE: UI   | Added option to suppress file download dialog [knguyen]
-FEATURE: UI   | Various progress reports have been unified; main status bar can display progress for certain processes now [knguyen]
-FEATURE: Plug | Plugins can now change the color of rows [amc1]
-FEATURE: Plug | Plugins can add configuration colour parameters [amc1]
-
-CHANGE: Core  | Attempt to re-open a file when access fails to try and recover from a transient error [Parg]
-CHANGE: Core  | Auto speed default is now the new 'beta' (v2) algorithm [ranul]
-CHANGE: Core  | Revised piece picking code to deal better with some edge cases and snubbed peers [The 8472]
-CHANGE: Core  | Share Ratio/min Seeds ignore rule now applies even when no tracker scrape is available [The 8472]
-CHANGE: UI    | Added private torrent indicator to the general tab [The 8472]
-CHANGE: UI    | Logging Consoles now have regex-based filters [The 8472]
-CHANGE: UI    | Tweaked table views to use a bit less memory and run better when items are being quickly removed/added [TuxPaper]
-
-BUGFIX: UI    | Don't hang UI redraw if file access is slow [Parg]
-BUGFIX: UI    | Fixed inconsistencies in the Torrent Open Dialog related to renaming and retargeting files and directories [The 8472]  
-
-
-
-2007.10.04 | Azureus 3.0.3.4
-
-FEATURE: UI   | Added "All Peers" view [amc1]
-
-CHANGE: Core  | Added workarounds for some buggy UPnP router implementations [parg]
-CHANGE: UI    | NAT status bar indicator and health icons now ignore UDP and LAN-local connections [The 8472]
-
-BUGFIX: Core  | Fixed bug where a torrent's save location is "forgotten" when a recheck is done in some circumstances [amc1]
-BUGFIX: UI    | times > 365 days (such as the uptime) are now displayed properly [The 8472]
-
-
-
-2007.09.21 | Azureus 3.0.3.2
-
-BUGFIX: Core  | Fixed MacOSX playback bug [TuxPaper]
-BUGFIX: Core  | Fixed update restart bug [Parg]
-
-
-
-2007.09.20 | Azureus 3.0.3.0
-
-FEATURE: Core | Added experimental support for LibTorrent extension protocol handshake [amc1]
-FEATURE: Core | Providing some experimental options for possible workarounds for a particular traffic shaping method
-                 See http://www.azureuswiki.com/index.php/Avoid_traffic_shaping#Level_5 for further details 
-FEATURE: UI   | Added available disk space indicators to the torrent open dialog (requires Java 1.6) [The 8472]
-FEATURE: UI   | Added "handshake reserved bytes" column in peer view [amc1]
-FEATURE: UI   | Added "Open Transfer Bar on start" and "Remember Transfer Bar" location options [amc1]
-FEATURE: UI   | Added http-seed config to torrent creation wizard [Parg]
-FEATURE: UIv3 | Embedded Media Player [TuxPaper] 
-
-CHANGE: Core  | Speedup hash-checking by ~30% / less CPU usage [The 8472]
-CHANGE: Core  | More improvements to client identification code [amc1]
-CHANGE: UI    | Provide both "per-torrent" and "across-torrents" speed menu options [amc1]
-CHANGE: UI    | Speed improvements for menu generation and changing file priority in "Files" view [amc1]
-CHANGE: UI    | Allow minibars to stick to any screen border in multi monitor setups [The 8472]
-CHANGE: Plug  | Plugins can now dynamically register language resource bundles [amc1]
-
-BUGFIX: Core  | Fixed bug when trying to add torrents with semi-colon characters in filename [amc1]
-BUGFIX: Core  | LAN peer detection for explicit IP addresses was broken [Parg]
-
-
-
-2007.08.29 | Azureus 3.0.2.2
-
-CHANGE: UI    | Improved usability of speed scale widget. [TuxPaper]
-CHANGE: UI    | Restored reposition functionality of torrent context menus [TuxPaper]
-
-BUGFIX: Core  | *nix: Allowing multi-instance now works again [TuxPaper]
-BUGFIX: Core  | IPv6 DHT v4 pollution fix [Parg]
-BUGFIX: UI    | MacOSX: Fixed not remembering user turned off Maximized state [TuxPaper]
-BUGFIX: UI    | MacOSX: Fixed Drag and Drop for moving torrents in My Torrents view [TuxPaper]
-BUGFIX: UI    | A few config pages had their labels missing [TuxPaper]
-
-
-
-2007.08.16 | Azureus 3.0.2.0
-
-FEATURE: Core | Act on suspend/resume events on Windows [Parg]
-FEATURE: Core | Added new AZ message to inform of bad pieces [Parg]
-FEATURE: Core | Added new stacked HAVE message to reduce peer-peer overhead [Parg]
-FEATURE: Core | IPv6 support - dht, version server, tracker and improved transport [Parg]
-FEATURE: UI   | New "Torrent" menu in the menu bar [amc1]
-FEATURE: UI   | New "Piece Distribution" subview in the pieces tab [The 8472]
-FEATURE: UI   | Auto-speed ping views in Tools->Statistics->Transfers when Auto Speed is enabled [Parg]
-FEATURE: UI   | "Clear Resume Data" menu option added [amc1]
-FEATURE: UI   | "Clear remembered save paths" option added (for the Open Torrent dialog) [amc1]
-
-CHANGE: Core  | Optimise memory usage for single-file downloads [Parg]
-CHANGE: Core  | Optimise memory usage for queued torrents (no need to keep resume data in memory) [Parg]
-CHANGE: Core  | Much better peer ID identification code added, many more clients now correctly identified [amc1]
-CHANGE: Core  | Changes made to identify some "fake" clients (or other clients which identify themselves in a problematic way) [amc1]
-CHANGE: Core  | Biased optimistic disconnect slightly against leechy peers [The 8472]
-CHANGE: Core  | Core changes in some places to allow "Default save path" to be used without requiring "Use default data dir" to be enabled [hasturkun]
-CHANGE: Core  | Reduce CPU usage when many (queued) torrents are present and in the the pieces view [The 8472]
-CHANGE: Core  | *nix: New startup script to detect Gecko/XULRunner and to allow better restarting [TuxPaper]
-CHANGE: UI    | UL/DL speed selection on right click of status bar changed from menu to scale widget. [TuxPaper]
-                Usage: (1) MouseDown+Drag+MouseUp  (2) Click+Move+Click  (3) Click+type number+Enter
-CHANGE: UI    | Open Torrent Window now asks to create directories if they don't exist yet, instead of evilly auto-creating them when you click the Browse button [The 8472] 
-CHANGE: UI    | Added download status, distributed copies and completed piece count to the General torrent view [amc1, The 8472]
-CHANGE: UI    | User Comment field more useful in General torrent view - easy edit link, hyperlink formatting, auto-resizing [amc1]
-CHANGE: UI    | "Show Transfer Bar" menu option is now a checkbox menu item - so you can now hide the transfer bar using the menu item [amc1]
-CHANGE: Plug  | Added setVisible method for plugin menu items [amc1]
-             
-BUGFIX: Core  | Fixed bug where renaming a download for a single file torrent would sometimes cause data to get out of sync and cause file errors [amc1]
-BUGFIX: Core  | Allow pipelined http seed requests to switch torrents [Parg]
-BUGFIX: Core  | Bootstrap DHT better when no contacts [Parg]
-BUGFIX: Core  | Fixed bug where renaming a download in some conditions would generate "Target is sub-directory" errors [amc1]                
-BUGFIX: UI    | Fixed swarm view rendering bug where some incomplete peers were shown as full circles [The 8472]
-BUGFIX: Plug  | Fixed bug where previously removed child menu items would still be present when generating some menus [amc1]
-
-
-
-2007.06.20 | Azureus 3.0.1.6
-
-FEATURE: Core | IP Filter Autoloading. Supports DAT (eMule), P2P (PeerGardian, splist), and P2B v1,2,3 (Peer Gardian 2) formats. [TuxPaper]
-FEATURE: UI   | Option to display divider lines every 60 updates on the Statistics view [amc1]
-FEATURE: Plug | Added helper class to make listening to download events across all downloads easier [amc1]
-FEATURE: Core | Azureus AutoSpeed v2 Beta [ranul]
-
-BUGFIX: Core | Plugin installation/updates using Vista [parg,tuxpaper]
-
-
-
-2007.05.24 | Azureus 3.0.1.4
-
-FEATURE: Core | Byte-level download control for Downloads [Parg] 
-FEATURE: Core | Speed tester wizard [ranul,Parg]
-FEATURE: UI   | Added "Transfers Bar" (similar to the "Download Bar") [amc1]
-FEATURE: UI   | Correctly identifies FoxTorrent and Blizzard Downloader peers [amc1]
-FEATURE: UI   | Determines version information for Bits On Wheels and Opera peers [amc1]
-FEATURE: UI   | Vivaldi view can use mouse wheel too zoom now (requires clicking on the view first) [TuxPaper]
-FEATURE: UI   | Date Completed column [TuxPaper]
-FEATURE: UI   | (Beta) Various Auto Speed algorithms [ranul]
-FEATURE: UI   | Auto-open MyShares if any shares [Parg]
-
-CHANGE: Core  | Handle 503s better with webseeds [Jochen Seifarth,Parg]
-CHANGE: Core  | Disable HTTP authentication dialog for webseeds [Parg]
-CHANGE: Core  | Reduce DHT registration counts for queued torrents [Parg]
-CHANGE: UI    | Running Azureus while azureus is already running now brings Azureus to front [TuxPaper]
-CHANGE: UI    | OSX: Make minimize to status bar icon hide the main window instead of putting it in the doc [TuxPaper]
-
-BUGFIX: Core  | Updater now works on Vista with security challenged users [TuxPaper] 
-BUGFIX: Core  | Fixup "Get Right" webseed handling as per the spec [Jochen Seifarth]
-BUGFIX: Core  | Fixed bug which sometimes prevented corrupted torrents being removed properly [amc1]
-BUGFIX: Core  | Fix rare case where app dir on win32 could report wrong azureus dir on multi-az computers [TuxPaper]
-BUGFIX: Core  | Prevent upnp dispatcher queue from growing too large [Parg]
-BUGFIX: Core  | Limit UPnP write-request exec threads [Parg]
-BUGFIX: UI    | Fixed force starting a torrent via the Open Torrent Window options. [TuxPaper]
-
-
-
-2007.04.12 | Azureus 3.0.1.2
-
-FEATURE: Core | Auto-speed: added control for forced-max network speed [Parg]
-
-BUGFIX: Core  | 100% CPU problem in network code under some conditions [Parg]
-
-
-
-2007.04.05 | Azureus 3.0.1.0
-
-FEATURE: Core | Option to clear stored tracker list used for creating torrents [amc1]
-FEATURE: UI   | Option to add full UPnP debug information to the log view [amc1]
-
-BUGFIX:  UI   | Fixed issue where excessive file checks were being done when generating the torrent context menu [amc1]
-
-
-2007.03.15 | Azureus 3.0.0.8
-
-FEATURE: Core | Alerts can now be shown in individual message popup boxes [amc1]
-FEATURE: Core | Alerts can now be suppressed and shown on demand [amc1]
-FEATURE: Core | Per-peer upload/download speed limits [Parg]
-FEATURE: Core | Per-category upload/download speed limits [Parg]
-FEATURE: Core | Per-torrent super-seeding via MyTorrents context menu [Parg]
-FEATURE: UI   | Option to auto-download and install updates [TuxPaper]
-FEATURE: UI   | Overall piece map for Piece View [TuxPaper]
-FEATURE: UI   | New "Peer ID" columns in the Peers View [amc1]
-FEATURE: Plug | Plugins can now add their own status indicators on the status bar [amc1]
-FEATURE: Plug | Plugins can now add menu items to the system tray, download bars, menu bar [amc1]
-FEATURE: Plug | Plugins can now remove menu items that are created (allows for dynamic menus) [amc1]
-FEATURE: Plug | Added extra methods on DownloadManager making it easier to listen to download events [amc1]
-
-CHANGE: Core  | Include msvcr71.dll in Windows installation bundles, for compatibility with Java6 [Nolar]
-CHANGE: Plug  | Added full set of config parameter methods for completeness [amc1]
-
-BUGFIX: Plug  | UPnP plugin now correctly attempts to remove existing mappings if they are in the way of new mappings [amc1]
-BUGFIX: Core  | Fix Re-adding a torrent causing "1-" or "-1" directories or files [TuxPaper]
-BUGFIX: Core  | Fixed bug where files were sometimes moved into a subdirectory, where the directory name was only one character long [amc1]
-BUGFIX: Plug  | Fixed bug where some plugin menu items didn't appear under certain conditions [amc1]
-
-
-2007.01.22 | Azureus 2.5.0.4 / 3.0.0.6
-
-FEATURE: Core | New users default save directory is now located in their "My Documents" directory, under "Azureus Downloads" [TuxPaper]
-FEATURE: Core | Show alerts raised during closedown on next start as these often don't get displayed due to UI shutdown [Parg]
-FEATURE: Core | Allow plugin installs to place jars into the plugin-shared "shared/lib" directory [Parg]
-FEATURE: Plug | Unsafe config read/writing [parg]
-FEATURE: Plug | Plugins can now open and close download bars [amc1]
-
-CHANGE: Core  | Added scrape delay for stopped/errored torrents, and torrents with high share ratios [TuxPaper]
-CHANGE: Core  | Allow only one active scrape for each tracker [TuxPaper]
-CHANGE: Core  | Release piece-map when not required [Parg]
-CHANGE: Core  | ASN lookup via DNS queries only [Parg]
-CHANGE: Core  | Full recheck of torrent when part of torrent fails hash check on completion [TuxPaper]
-CHANGE: Core  | Take note of banned IPs when we have IP filter turned off - these are independent [Parg]
-CHANGE: Core  | Disable download peer caching for private torrents [Parg]
-CHANGE: Core  | Disconnect currently connected peers on tracker URL change for private torrents [Parg]
-CHANGE: Core  | Remove unused download/upload specific stats from version-check message [Parg]
-CHANGE: Core  | Include IP override in NAT check message for NAT check server to use [Parg]
-CHANGE: Plug  | Timeout UPnP port releases during closedown to prevent Azureus hanging [Parg]
-
-BUGFIX: Core  | Fix choke/unchoke cycle bug for lan local peers [Nolar]
-BUGFIX: Core  | Fix auto moving torrent data with DND files [TuxPaper]
-BUGFIX: Core  | Fix NPE causing XML stats not to be written [Parg]
-BUGFIX: UI    | Fix crash when opening non-torrent URL when OS has no recognized HTML viewer [TuxPaper]
-BUGFIX: UI    | Fix big icon in name column for OSes using GTK [TuxPaper]
-BUGFIX: UI    | Make Download Basket work again for drag and dropping [TuxPaper]
diff --git a/PreferencesJavaCodeStyleFormatter.xml b/PreferencesJavaCodeStyleFormatter.xml
new file mode 100644
index 0000000..b8a06f2
--- /dev/null
+++ b/PreferencesJavaCodeStyleFormatter.xml
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="11">
+<profile kind="CodeFormatterProfile" name="JavaStd;2spcTabs;NoCommentFormatting" version="11">
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="53"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="37"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="mixed"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="33"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="37"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="33"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.5"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+</profile>
+</profiles>
diff --git a/az-build.xml b/az-build.xml
deleted file mode 100644
index 0a33dbf..0000000
--- a/az-build.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-	
-NOTE:  You may need to set the  ANT_OPTS="-Xmx512m"  env prop in order to compile this project successfully.
-
--->
-
-
-	
-<project default="dev-jar" name="Dev-Build" basedir=".">
-
-   <property name="root.dir" value="." />  <!-- REMINDER: this needs to be "." for public source -->
-   <property name="libs.dir" value="dev-build/libs" />
-   <property name="dist.dir" value="dev-dist" />
-   <property name="build.dir" value="dev-build"/>
-   <property name="classes.dir" value="dev-build/classes"/>
-
-   <property name="generic.excludes" value="**/*.jar **/*.txt **/*.jardesc **/.classpath **/.project **/aereg.lib **/aereg.dll" />
-   <property name="dist.jar.excludes" value="${generic.excludes} **/*.java " />
-
-
-   <!--  INIT  -->
-   <target name="dev-init" >
-      <echo message=" creating dirs for (dev) Azureus2-dev.jar..." />
-
-      <tstamp/>
-
-      <mkdir dir="${root.dir}/${dist.dir}" />
-      <mkdir dir="${root.dir}/${libs.dir}"/>
-      <mkdir dir="${root.dir}/${classes.dir}/com"/>
-      <mkdir dir="${root.dir}/${classes.dir}/org"/> 
-
-      <!-- move jar file from ../notSourceControl/dist/AzComp.jar   (non-java 1.4 source code)  -->
-      <copy todir="${root.dir}/${libs.dir}">
-          <fileset dir="../notSourceControl/dist">
-            <include name="**/*.jar"/>
-          </fileset>
-      </copy>
-
-   </target>
-
-   <!--   COMPILE   -->
-   <target name="dev-compile" depends="dev-init" >
-        <path id="libs.classpath">
-            <fileset dir="${root.dir}/build/libs" includes="**/*.jar" />
-            <fileset dir="${root.dir}/${libs.dir}" includes="**/*.jar" />
-        </path>
-
-        <!-- azureus2 -->
-       <echo message="starting azureus2 compile ..."/>
-        <javac srcdir="${root.dir}" destdir="${classes.dir}" nowarn="yes" source="1.4" target="1.4" includeAntRuntime="no" debug="true" debuglevel="lines,vars,source" >
-             <classpath refid="libs.classpath" />
-        </javac>
-
-       <path id="az2classes.classpath">
-           <fileset dir="${root.dir}/${classes.dir}" />
-       </path>
-        <!-- ../azureus3 -->
-       <echo message="starting azureus3 compile ..."/>
-       <javac srcdir="../azureus3" destdir="${classes.dir}" nowarn="yes" source="1.4" target="1.4" includeAntRuntime="no" debug="true" debuglevel="lines,vars,source">
-            <classpath refid="libs.classpath" />
-            <classpath refid="az2classes.classpath"/>
-       </javac>
-
-        <!-- ../uis -->
-       <echo message="starting uis compile ..."/>
-       <javac srcdir="../uis" destdir="${classes.dir}" nowarn="yes" source="1.4" target="1.4" includeAntRuntime="no" debug="true" debuglevel="lines,vars,source">
-            <classpath refid="libs.classpath" />
-       </javac>
-
-       <!-- ../component -->
-       <echo message="starting component compile (java 1.5) ..."/>
-       <javac srcdir="../components" destdir="${classes.dir}" nowarn="yes" includeAntRuntime="no" debug="true" debuglevel="lines,vars,source">
-            <classpath refid="libs.classpath"/>
-       </javac>
-
-   </target>
-
-    
-   <!--  JAR  -->
-   <target name="dev-jar" depends="dev-compile" >
-
-      <!-- copy the non-*.java files over -->
-      <echo message="copying non-jar files"/>
-      <copy todir="${root.dir}/${classes.dir}/com">
-          <fileset dir="./com">
-            <exclude name="**/*.jar"/>
-            <exclude name="**/*.class"/>
-          </fileset>
-      </copy>
-
-      <copy todir="${root.dir}/${classes.dir}/org">
-          <fileset dir="./org">
-            <exclude name="**/*.jar"/>
-            <exclude name="**/*.class"/>
-          </fileset>
-      </copy>
-
-      <copy todir="${root.dir}/${classes.dir}">
-          <fileset dir="../azureus3">
-             <exclude name="**/*.jar"/>
-             <exclude name="**/*.class"/>
-          </fileset>
-      </copy>
-
-      <echo message="creating jar file."/>
-      <jar destfile="${root.dir}/${dist.dir}/Azureus2-dev-${DSTAMP}-${TSTAMP}.jar" basedir="${root.dir}/${classes.dir}" excludes="${dist.jar.excludes}" >
-         <manifest>
-            <attribute name="Main-Class" value="org.gudy.azureus2.ui.common.Main" />
-            <attribute name="Class-Path" value="Azureus2.jar apple-extensions.jar commons-cli.jar log4j.jar swt.jar swt-win32.jar swt-osx.jar" />
-         </manifest>
-      </jar>
-
-   </target>
-
-   <!--  CLEAN  -->
-   <target name="dev-clean" >
-      <delete quiet="true" >
-          <fileset dir="${root.dir}/{classes.dir}" includes="**/*.class"/>
-      </delete>
-
-       <delete dir="${root.dir}/${classes.dir}" />
-   </target>
-
-</project>
-
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 7b060c1..0000000
--- a/build.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-	
-NOTE:  You may need to set the  ANT_OPTS="-Xmx512m"  env prop in order to compile this project successfully.
-
--->
-
-	
-<project default="jar" name="Azureus" basedir=".">
-
-   <property name="root.dir" value="." />  <!-- REMINDER: this needs to be "." for public source -->
-   <property name="libs.dir" value="build/libs" />
-   <property name="dist.dir" value="dist" />
-   
-   <property name="generic.excludes" value="**/*.jar **/*.txt **/*.jardesc **/.classpath **/.project **/aereg.lib **/aereg.dll" />
-   <property name="dist.jar.excludes" value="${generic.excludes} **/*.java " />
-   <!-- <property name="dist.source.excludes" value="${generic.excludes} **/*.class" /> -->
-   
-   
-   <target name="init" >
-      <echo message="Building Azureus2.jar..." />
-
-      <tstamp/>
-
-      <!-- <condition property="libs.dir" value="build/libs">
-         <not>  <isset property="libs.dir" />  </not>
-      </condition> -->
-       
-      <mkdir dir="${root.dir}/${dist.dir}" />
-   </target>
-
-   
-   <target name="compile" depends="init" >
-      <path id="libs.classpath">
-         <fileset dir="${root.dir}/${libs.dir}" includes="**/*.jar" />
-      </path>
-   
-   	<javac srcdir="${root.dir}" destdir="${root.dir}" nowarn="yes" source="1.4" target="1.4" includeAntRuntime="no" debug="true" debuglevel="lines,vars,source" >
-         <classpath refid="libs.classpath" />
-      </javac>
-   </target>
-
-
-   <target name="jar" depends="compile" >
-      <jar destfile="${root.dir}/${dist.dir}/Azureus2.jar" basedir="${root.dir}" excludes="${dist.jar.excludes}" >
-         <manifest>
-            <attribute name="Main-Class" value="org.gudy.azureus2.ui.common.Main" />
-            <attribute name="Class-Path" value="Azureus2.jar apple-extensions.jar commons-cli.jar log4j.jar swt.jar swt-win32.jar swt-osx.jar" />
-         </manifest>
-      </jar>
-      
-      <!-- <zip destfile="${dist.dir}/Azureus2_source.zip" basedir="." excludes="${dist.source.excludes}" /> -->
-
-   </target>
-
-
-   <target name="clean" >
-      <delete quiet="true" >
-         <fileset dir="${root.dir}/com" includes="**/*.class"/>
-         <fileset dir="${root.dir}/org" includes="**/*.class"/>
-      </delete>
-      
-      <delete dir="${root.dir}/${dist.dir}" />
-   </target>
-
-</project>
-
diff --git a/build/libs/JavaApplicationStub b/build/libs/JavaApplicationStub
deleted file mode 100644
index f17be42..0000000
Binary files a/build/libs/JavaApplicationStub and /dev/null differ
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesConstants.java b/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
index 934259f..29b6e2c 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesConstants.java
@@ -29,8 +29,4 @@ public class VuzeActivitiesConstants
 	public static final String TYPEID_HEADER = "Header";
 
 	public static final String TYPEID_VUZENEWS = "VUZE_NEWS_ITEM";
-
-	public static final String TYPEID_CHANNEL_ANNOUNCE = "CHANNEL_ANNOUNCE";
-
-	public static final String TYPEID_CONTENT_PROMO = "CONTENT_PROMO";
 }
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesEntry.java b/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
index de76226..e0b913c 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesEntry.java
@@ -29,15 +29,15 @@ import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.util.*;
 
 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.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableColumnSortObject;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
 import com.aelitis.azureus.ui.utils.ImageBytesDownloader;
 import com.aelitis.azureus.ui.utils.ImageBytesDownloader.ImageDownloaderListener;
-import com.aelitis.azureus.util.*;
+import com.aelitis.azureus.util.DataSourceUtils;
+import com.aelitis.azureus.util.MapUtils;
+import com.aelitis.azureus.util.PlayUtils;
 
 /**
  * 
@@ -79,18 +79,12 @@ public class VuzeActivitiesEntry
 
 	private TOTorrent torrent;
 
-	private boolean isDRM;
-
-	private boolean isPlatformContent;
-	
 	private boolean playable;
 	
 	private long readOn;
 
 	private GlobalManager gm = null;
 	
-	private long contentNetworkID = ContentNetwork.CONTENT_NETWORK_VUZE;
-
 	public VuzeActivitiesEntry(long timestamp, String text, String typeID) {
 		this.setText(text);
 		this.timestamp = timestamp;
@@ -117,7 +111,7 @@ public class VuzeActivitiesEntry
 	/**
 	 * @param platformEntry
 	 */
-	public void loadFromExternalMap(Map platformEntry) {
+	public void loadFromExternalMap(Map<?, ?> platformEntry) {
 		timestamp = SystemTime.getCurrentTime()
 				- MapUtils.getMapLong(platformEntry, "age-ms", 0);
 		setIconID(MapUtils.getMapString(platformEntry, "icon-url",
@@ -127,14 +121,13 @@ public class VuzeActivitiesEntry
 				null));
 		setAssetImageURL(MapUtils.getMapString(platformEntry, "related-image-url",
 				null));
-		setDRM(MapUtils.getMapBoolean(platformEntry, "no-play", false));
 		setTorrentName(MapUtils.getMapString(platformEntry, "related-asset-name",
 				null));
 		setReadOn(MapUtils.getMapLong(platformEntry, "readOn", 0));
 		loadCommonFromMap(platformEntry);
 	}
 
-	public void loadFromInternalMap(Map map) {
+	public void loadFromInternalMap(Map<?, ?> map) {
 		timestamp = MapUtils.getMapLong(map, "timestamp", 0);
 		if (timestamp == 0) {
 			timestamp = SystemTime.getCurrentTime();
@@ -145,22 +138,17 @@ public class VuzeActivitiesEntry
 		setShowThumb(MapUtils.getMapLong(map, "showThumb", 1) == 1);
 		setAssetImageURL(MapUtils.getMapString(map, "assetImageURL", null));
 		setImageBytes(MapUtils.getMapByteArray(map, "imageBytes", null));
-		setDRM(MapUtils.getMapBoolean(map, "isDRM", false));
 		setReadOn(MapUtils.getMapLong(map, "readOn", SystemTime.getCurrentTime()));
 		loadCommonFromMap(map);
 	}
 
-	public void loadCommonFromMap(Map map) {
-		if (!isPlatformContent) {
-			setIsPlatformContent(MapUtils.getMapBoolean(map, "is-platform",
-					isPlatformContent));
-		}
+	public void loadCommonFromMap(Map<?, ?> map) {
 		if (!playable) {
 			setPlayable(MapUtils.getMapBoolean(map, "playable", false));
 		}
 		setID(MapUtils.getMapString(map, "id", null));
 		setText(MapUtils.getMapString(map, "text", null));
-		Map torrentMap = MapUtils.getMapMap(map, "torrent", null);
+		Map<?, ?> torrentMap = MapUtils.getMapMap(map, "torrent", null);
 		if (torrentMap != null) {
 			TOTorrent torrent = null;
 			try {
@@ -172,8 +160,6 @@ public class VuzeActivitiesEntry
 		if (dm == null && torrentName == null) {
 			setTorrentName(MapUtils.getMapString(map, "torrent-name", null));
 		}
-		setContentNetworkID(MapUtils.getMapLong(map, "contentNetworkID",
-				contentNetworkID));
 	}
 
 	// @see java.lang.Object#equals(java.lang.Object)
@@ -222,15 +208,19 @@ public class VuzeActivitiesEntry
 		return assetImageURL;
 	}
 
-	public Map toDeletedMap() {
-		Map map = new HashMap();
+	public Map<String, Object> toDeletedMap() {
+		Map<String, Object> map = new HashMap<String, Object>();
 		map.put("timestamp", new Long(timestamp));
 		map.put("id", id);
 		return map;
 	}
 
-	public Map toMap() {
-		Map map = new HashMap();
+	@SuppressWarnings({
+		"unchecked",
+		"rawtypes"
+	})
+	public Map<String, Object> toMap() {
+		Map<String, Object> map = new HashMap<String, Object>();
 		map.put("timestamp", new Long(timestamp));
 		if (assetHash != null) {
 			map.put("assetHash", assetHash);
@@ -258,7 +248,7 @@ public class VuzeActivitiesEntry
 				
 				TOTorrent torrent_to_send = TOTorrentFactory.deserialiseFromMap( torrent_map );
 
-				Map	vuze_map = (Map)torrent_map.get( "vuze" );
+				Map<?, ?>	vuze_map = (Map<?, ?>)torrent_map.get( "vuze" );
 				
 				// remove any non-standard stuff (e.g. resume data)
 
@@ -276,21 +266,16 @@ public class VuzeActivitiesEntry
 				Debug.outNoStack("VuzeActivityEntry.toMap: " + e.toString());
 			}
 		}
-		map.put("isDRM", new Long(isDRM() ? 1 : 0));
 		if (torrentName != null) {
 			map.put("torrent-name", torrentName);
 		}
 		
-		map.put("is-platform", new Long(isPlatformContent ? 1 : 0));
-		
 		if (playable) {
 			map.put("playable", new Long(playable ? 1 : 0));
 		}
 		
 		map.put("readOn", new Long(readOn));
 		
-		map.put("contentNetworkID", new Long(contentNetworkID));
-
 		return map;
 	}
 
@@ -316,10 +301,6 @@ public class VuzeActivitiesEntry
 		if (getIconID() == null && typeID != null) {
 			setIconID("image.vuze-entry." + typeID.toLowerCase());
 		}
-		if (VuzeActivitiesConstants.TYPEID_CONTENT_PROMO.equals(typeID)) {
-			setIsPlatformContent(true);
-			setPlayable(true);
-		}
 	}
 
 	/**
@@ -490,20 +471,6 @@ public class VuzeActivitiesEntry
 			assetHash = torrent.getHashWrapper().toBase32String();
 		} catch (Exception e) {
 		}
-		
-		setContentNetworkID(PlatformTorrentUtils.getContentNetworkID(torrent));
-
-		setDRM(torrent == null ? false : PlatformTorrentUtils.isContentDRM(torrent));
-		setIsPlatformContent(torrent == null ? false
-				: PlatformTorrentUtils.isContent(torrent, true));
-	}
-
-	public boolean isDRM() {
-		return isDRM;
-	}
-
-	public void setDRM(boolean isDRM) {
-		this.isDRM = isDRM;
 	}
 
 	public String getTorrentName() {
@@ -568,21 +535,13 @@ public class VuzeActivitiesEntry
 
 	}
 
-	public boolean isPlatformContent() {
-		return isPlatformContent;
-	}
-
-	public void setIsPlatformContent(boolean isPlatformContent) {
-		this.isPlatformContent = isPlatformContent;
-	}
-
 	public boolean isPlayable() {
 		// our variable is an override
 		if (playable)  {
 			return true;
 		}
 		// use torrent so we don't recurse
-		return PlayUtils.canPlayDS(DataSourceUtils.getTorrent(this));
+		return PlayUtils.canPlayDS(DataSourceUtils.getTorrent(this), -1);
 	}
 
 	public void setPlayable(boolean playable) {
@@ -622,20 +581,4 @@ public class VuzeActivitiesEntry
 			return ofs > (-1 * readOn);
 		}
 	}
-
-	public long getContentNetworkID() {
-		return contentNetworkID;
-	}
-	
-	public ContentNetwork getContentNetwork() {
-		ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetwork(contentNetworkID);
-		if (cn == null) {
-			cn = ConstantsVuze.getDefaultContentNetwork();
-		}
-		return cn;
-	}
-
-	public void setContentNetworkID(long contentNetworkID) {
-		this.contentNetworkID = contentNetworkID;
-	}
 }
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesLoadedListener.java b/com/aelitis/azureus/activities/VuzeActivitiesLoadedListener.java
new file mode 100644
index 0000000..63c0c7e
--- /dev/null
+++ b/com/aelitis/azureus/activities/VuzeActivitiesLoadedListener.java
@@ -0,0 +1,29 @@
+/**
+ * Created on Feb 15, 2011
+ *
+ * Copyright 2010 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;
+
+/**
+ * @author TuxPaper
+ * @created Feb 15, 2011
+ *
+ */
+public interface VuzeActivitiesLoadedListener
+{
+	public void vuzeActivitiesLoaded();
+}
diff --git a/com/aelitis/azureus/activities/VuzeActivitiesManager.java b/com/aelitis/azureus/activities/VuzeActivitiesManager.java
index a215d06..819a98a 100644
--- a/com/aelitis/azureus/activities/VuzeActivitiesManager.java
+++ b/com/aelitis/azureus/activities/VuzeActivitiesManager.java
@@ -18,11 +18,8 @@
 
 package com.aelitis.azureus.activities;
 
-import java.net.HttpURLConnection;
-import java.net.URL;
 import java.util.*;
 
-import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -41,7 +38,7 @@ import com.aelitis.azureus.util.MapUtils;
  */
 public class VuzeActivitiesManager
 {
-	public static final long MAX_LIFE_MS = 1000L * 60 * 60 * 24 * 30;
+	public static final long MAX_LIFE_MS = 1000L * 60 * 60 * 24 * 365 * 2;
 
 	private static final long DEFAULT_PLATFORM_REFRESH = 60 * 60 * 1000L * 24;
 
@@ -49,6 +46,8 @@ public class VuzeActivitiesManager
 
 	private static ArrayList<VuzeActivitiesListener> listeners = new ArrayList<VuzeActivitiesListener>();
 
+	private static ArrayList<VuzeActivitiesLoadedListener> listenersLoaded = new ArrayList<VuzeActivitiesLoadedListener>();
+
 	private static ArrayList<VuzeActivitiesEntry> allEntries = new ArrayList<VuzeActivitiesEntry>();
 
 	private static AEMonitor allEntries_mon = new AEMonitor("VuzeActivityMan");
@@ -141,13 +140,13 @@ public class VuzeActivitiesManager
 				SimpleTimer.addEvent("GetVuzeNews",
 						SystemTime.getOffsetTime(refreshInMS), new TimerEventPerformer() {
 							public void perform(TimerEvent event) {
-								pullActivitiesNow(5000);
+								pullActivitiesNow(5000, "timer", false);
 							}
 						});
 			}
 		};
 
-		pullActivitiesNow(5000);
+		pullActivitiesNow(5000, "initial", false);
 	}
 
 	/**
@@ -166,11 +165,12 @@ public class VuzeActivitiesManager
 				boolean isActive = (oIsActive instanceof Boolean)
 						? ((Boolean) oIsActive).booleanValue() : false;
 				if (isActive) {
-					pullActivitiesNow(2000);
+					pullActivitiesNow(2000, "CN:PropChange", false);
 				}
 			}
 		});
 		
+		/*
 		final String id_str = cn.getServiceURL( ContentNetwork.SERVICE_IDENTIFY );
 		
 		if ( id_str != null && id_str.length() > 0 ){
@@ -196,56 +196,18 @@ public class VuzeActivitiesManager
 				Debug.out( e );
 			}
 		}
+		*/
 	}
 	
-	private static void
-	identify(
-		ContentNetwork		cn,
-		String				str )
-	{
-		try{
-			URL	url = new URL( str );
-			
-			HttpURLConnection con = (HttpURLConnection)url.openConnection();
-			
-			String	key = "cn." + cn.getID() + ".identify.cookie";
-			
-			String cookie = COConfigurationManager.getStringParameter( key, null );
-			
-			if ( cookie != null ){
-				
-				con.setRequestProperty( "Cookie", cookie + ";" );
-			}
-			
-			con.setRequestProperty( "Connection", "close" );
-			
-			con.getResponseCode();
-			
-			cookie = con.getHeaderField( "Set-Cookie" );
-			
-			if ( cookie != null ){
-				
-				String[] bits = cookie.split( ";" );
-				
-				if ( bits.length > 0 && bits[0].length() > 0 ){
-					
-					COConfigurationManager.setParameter( key, bits[0] );
-				}
-			}
-		}catch( Throwable e ){
-			
-		}
-	}
-
 	/**
 	 * Pull entries from webapp
 	 * 
-	 * @param agoMS Pull all events within this timespan (ms)
 	 * @param delay max time to wait before running request
 	 *
 	 * @since 3.0.4.3
 	 */
-	public static void pullActivitiesNow(long delay) {
+	public static void pullActivitiesNow(long delay, String reason,
+			boolean alwaysPull) {
 		/*
 		ContentNetworkManager cnm = ContentNetworkManagerFactory.getSingleton();
 		if (cnm == null) {
@@ -262,27 +224,21 @@ public class VuzeActivitiesManager
 				return; //continue;
 			}
 			
-			Object oIsActive = cn.getPersistentProperty(ContentNetwork.PP_ACTIVE);
-			boolean isActive = (oIsActive instanceof Boolean)
-					? ((Boolean) oIsActive).booleanValue() : false;
-			if (!isActive) {
-				return; //continue;
-			}
-			
 			String id = "" + cn.getID();
 			Long oLastPullTime = lastNewsAt.get(id);
 			long lastPullTime = oLastPullTime != null ? oLastPullTime.longValue() : 0;
 			long now = SystemTime.getCurrentTime();
 			long diff = now - lastPullTime;
-			if (diff < 5000) {
+			if (!alwaysPull && diff < 5000) {
 				return;
 			}
 			if (diff > MAX_LIFE_MS) {
 				diff = MAX_LIFE_MS;
 			}
-			PlatformVuzeActivitiesMessenger.getEntries(cn.getID(), diff, delay,
-					replyListener);
-			lastNewsAt.put(id, new Long(now));
+			PlatformVuzeActivitiesMessenger.getEntries(diff, delay,
+					reason, replyListener);
+			// broken..
+			//lastNewsAt.put(id, new Long(now));
 		}
 	}
 	
@@ -316,6 +272,10 @@ public class VuzeActivitiesManager
 	 *
 	 * @since 3.0.4.3
 	 */
+	@SuppressWarnings({
+		"rawtypes",
+		"unchecked"
+	})
 	private static void loadEvents() {
 		skipAutoSave = true;
 
@@ -375,7 +335,7 @@ public class VuzeActivitiesManager
 			}
 
 			List entries = (List) value;
-			List entriesToAdd = new ArrayList(entries.size());
+			List<VuzeActivitiesEntry> entriesToAdd = new ArrayList<VuzeActivitiesEntry>(entries.size());
 			for (Iterator iter = entries.iterator(); iter.hasNext();) {
 				value = iter.next();
 				if (!(value instanceof Map)) {
@@ -397,6 +357,20 @@ public class VuzeActivitiesManager
 			}
 		} finally {
 			skipAutoSave = false;
+			
+			synchronized (SAVE_FILENAME) {
+				if (listenersLoaded != null) {
+					for (VuzeActivitiesLoadedListener l : listenersLoaded) {
+						try {
+							l.vuzeActivitiesLoaded();
+						} catch (Exception e) {
+							Debug.out(e);
+						}
+					}
+					listenersLoaded = null;
+				}
+			}
+
 		}
 	}
 
@@ -408,11 +382,11 @@ public class VuzeActivitiesManager
 		try {
 			config_mon.enter();
 
-			Map mapSave = new HashMap();
+			Map<String, Object> mapSave = new HashMap<String, Object>();
 			mapSave.put("LastChecks", lastNewsAt);
 			mapSave.put("version", new Long(2));
 
-			List entriesList = new ArrayList();
+			List<Object> entriesList = new ArrayList<Object>();
 
 			VuzeActivitiesEntry[] allEntriesArray = getAllEntries();
 			for (int i = 0; i < allEntriesArray.length; i++) {
@@ -428,7 +402,7 @@ public class VuzeActivitiesManager
 			}
 			mapSave.put("entries", entriesList);
 
-			List removedEntriesList = new ArrayList();
+			List<Object> removedEntriesList = new ArrayList<Object>();
 			for (Iterator<VuzeActivitiesEntry> iter = removedEntries.iterator(); iter.hasNext();) {
 				VuzeActivitiesEntry entry = iter.next();
 				removedEntriesList.add(entry.toDeletedMap());
@@ -456,6 +430,28 @@ public class VuzeActivitiesManager
 		listeners.remove(l);
 	}
 
+	public static void addListener(VuzeActivitiesLoadedListener l) {
+		synchronized (SAVE_FILENAME) {
+			if (listenersLoaded != null) {
+				listenersLoaded.add(l);
+			} else {
+				try {
+					l.vuzeActivitiesLoaded();
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+	}
+
+	public static void removeListener(VuzeActivitiesLoadedListener l) {
+		synchronized (SAVE_FILENAME) {
+			if (listenersLoaded != null) {
+				listenersLoaded.remove(l);
+			}
+		}
+	}
+
 	/**
 	 * 
 	 * @param entries
@@ -466,8 +462,8 @@ public class VuzeActivitiesManager
 	public static VuzeActivitiesEntry[] addEntries(VuzeActivitiesEntry[] entries) {
 		long cutoffTime = getCutoffTime();
 
-		ArrayList newEntries = new ArrayList(entries.length);
-		ArrayList existingEntries = new ArrayList(0);
+		ArrayList<VuzeActivitiesEntry> newEntries = new ArrayList<VuzeActivitiesEntry>(entries.length);
+		ArrayList<VuzeActivitiesEntry> existingEntries = new ArrayList<VuzeActivitiesEntry>(0);
 
 		try {
 			allEntries_mon.enter();
@@ -568,6 +564,15 @@ public class VuzeActivitiesManager
 
 		return null;
 	}
+	
+	public static boolean isEntryIdRemoved(String id) {
+		for (VuzeActivitiesEntry entry : removedEntries) {
+			if (entry.getID().equals(id)) {
+				return true;
+			}
+		}
+		return false;
+	}
 
 	public static VuzeActivitiesEntry[] getAllEntries() {
 		return allEntries.toArray(new VuzeActivitiesEntry[allEntries.size()]);
@@ -597,25 +602,16 @@ public class VuzeActivitiesManager
 		saveEvents();
 	}
 
-	public static VuzeActivitiesEntry createEntryFromMap(Map map,
-			boolean internalMap) {
-		return createEntryFromMap(ContentNetwork.CONTENT_NETWORK_VUZE, map,
-				internalMap);
-	}
-
 	/**
 	 * @param map
 	 * @return
 	 *
 	 * @since 3.0.5.3
 	 */
-	public static VuzeActivitiesEntry createEntryFromMap(
-			long defaultContentNetworkID, Map map, boolean internalMap) {
+	public static VuzeActivitiesEntry createEntryFromMap(Map<?, ?> map,
+			boolean internalMap) {
 		VuzeActivitiesEntry entry;
-		String typeID = MapUtils.getMapString(map, "typeID", MapUtils.getMapString(
-				map, "type-id", null));
 		entry = new VuzeActivitiesEntry();
-		entry.setContentNetworkID(defaultContentNetworkID);
 		if (internalMap) {
 			entry.loadFromInternalMap(map);
 		} else {
diff --git a/com/aelitis/azureus/core/AzureusCore.java b/com/aelitis/azureus/core/AzureusCore.java
index 8451c59..20b392b 100644
--- a/com/aelitis/azureus/core/AzureusCore.java
+++ b/com/aelitis/azureus/core/AzureusCore.java
@@ -33,6 +33,7 @@ import org.gudy.azureus2.core3.ipfilter.IpFilterManager;
 import org.gudy.azureus2.core3.internat.LocaleUtil;
 
 import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.utils.PowerManagementListener;
 
 import com.aelitis.azureus.core.instancemanager.AZInstanceManager;
 import com.aelitis.azureus.core.nat.NATTraverser;
@@ -50,6 +51,9 @@ AzureusCore
 	public boolean
 	isStarted();
 	
+	public boolean
+	isInitThread();
+	
 		/**
 		 * stop the core and inform lifecycle listeners of stopping
 		 * @throws AzureusCoreException
@@ -107,6 +111,9 @@ AzureusCore
 	public boolean
 	isRestarting();
 	
+	public void
+	saveState();
+	
 	public LocaleUtil
 	getLocaleUtil();
 	
@@ -184,4 +191,12 @@ AzureusCore
 	 * @param component
 	 */
 	void triggerLifeCycleComponentCreated(AzureusCoreComponent component);
+	
+	public void
+	addPowerManagementListener(
+		PowerManagementListener	listener );
+		
+	public void
+	removePowerManagementListener(
+		PowerManagementListener	listener );
 }
diff --git a/com/aelitis/azureus/core/backup/BackupManager.java b/com/aelitis/azureus/core/backup/BackupManager.java
new file mode 100644
index 0000000..19ddf9f
--- /dev/null
+++ b/com/aelitis/azureus/core/backup/BackupManager.java
@@ -0,0 +1,67 @@
+/*
+ * Created on Jun 22, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.backup;
+
+import java.io.File;
+
+public interface 
+BackupManager 
+{
+	public void
+	backup(
+		File				parent_folder,
+		BackupListener		listener );
+	
+	public void
+	restore(
+		File				backup_folder,
+		BackupListener		listener );
+		
+	public void
+	runAutoBackup(
+		BackupListener		listener );
+	
+	public long
+	getLastBackupTime();
+	
+	public String
+	getLastBackupError();
+	
+	public interface
+	BackupListener
+	{	
+		/**
+		 * @return false -> abandon process
+		 */
+	
+		public boolean
+		reportProgress(
+			String		str );
+		
+		public void
+		reportComplete();
+		
+		public void
+		reportError(
+			Throwable 	error );
+	}
+}
diff --git a/com/aelitis/azureus/core/backup/BackupManagerFactory.java b/com/aelitis/azureus/core/backup/BackupManagerFactory.java
new file mode 100644
index 0000000..eb1ee7c
--- /dev/null
+++ b/com/aelitis/azureus/core/backup/BackupManagerFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Created on Jun 22, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.backup;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.backup.impl.BackupManagerImpl;
+
+public class 
+BackupManagerFactory 
+{
+	public static BackupManager
+	getManager(
+		AzureusCore		core )
+	{
+		return( BackupManagerImpl.getSingleton( core ));
+	}
+}
diff --git a/com/aelitis/azureus/core/backup/impl/BackupManagerImpl.java b/com/aelitis/azureus/core/backup/impl/BackupManagerImpl.java
new file mode 100644
index 0000000..91526de
--- /dev/null
+++ b/com/aelitis/azureus/core/backup/impl/BackupManagerImpl.java
@@ -0,0 +1,1131 @@
+/*
+ * Created on Jun 22, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.backup.impl;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.gudy.azureus2.core3.config.COConfigurationListener;
+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.Logger;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
+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.Constants;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.core3.util.FileUtil;
+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.TimeFormatter;
+import org.gudy.azureus2.core3.util.TimerEvent;
+import org.gudy.azureus2.core3.util.TimerEventPerformer;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.update.UpdateInstaller;
+
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
+import com.aelitis.azureus.core.backup.BackupManager;
+
+public class 
+BackupManagerImpl
+	implements BackupManager
+{
+	private static BackupManagerImpl	singleton;
+		
+	public static synchronized BackupManager
+	getSingleton(
+		AzureusCore		core )
+	{
+		if ( singleton == null ){
+			
+			singleton = new BackupManagerImpl( core );
+		}
+		
+		return( singleton );
+	}
+	
+	private AzureusCore			core;
+	
+	private AsyncDispatcher		dispatcher = new AsyncDispatcher();
+
+	private boolean		first_schedule_check = true;
+	private TimerEvent	backup_event;
+	private long		last_auto_backup;
+	
+	
+	private volatile boolean	closing;
+	
+	private 
+	BackupManagerImpl(
+		AzureusCore		_core )
+	{
+		core	= _core;
+				
+		COConfigurationManager.addParameterListener(
+			new String[]{
+				"br.backup.auto.enable",
+				"br.backup.auto.everydays",
+				"br.backup.auto.retain",
+			},
+			new ParameterListener()
+			{
+				private COConfigurationListener	save_listener;
+				
+				private Object	lock = this;
+				
+				public void 
+				parameterChanged(
+					String parameter ) 
+				{
+					synchronized( lock ){
+						
+						if ( save_listener == null ){
+							
+							save_listener = 
+								new COConfigurationListener()
+								{
+									public void
+									configurationSaved()
+									{
+										checkSchedule();
+										
+										COConfigurationManager.removeListener( this );
+										
+										synchronized( lock ){
+											
+											if ( save_listener == this ){
+										
+												save_listener = null;
+											}
+										}
+									}
+								};
+						
+								COConfigurationManager.addListener( save_listener );
+						}
+					}
+				}
+			});
+		
+		checkSchedule();
+
+		core.addLifecycleListener(
+			new AzureusCoreLifecycleAdapter()
+			{
+				@Override
+				public void
+				stopping(
+					AzureusCore		core )
+				{
+					closing = true;
+				}
+			});
+	}
+	
+	public long
+	getLastBackupTime()
+	{
+		return( COConfigurationManager.getLongParameter( "br.backup.last.time", 0 ));
+	
+	}
+	
+	public String
+	getLastBackupError()
+	{
+		return( COConfigurationManager.getStringParameter( "br.backup.last.error", "" ));
+	}
+	
+	private void
+	checkSchedule()
+	{
+		checkSchedule( null, false );
+	}
+	
+	private void
+	checkSchedule(
+		final BackupListener 	listener,
+		boolean					force )
+	{
+		boolean	enabled = COConfigurationManager.getBooleanParameter( "br.backup.auto.enable" );
+		
+		boolean	do_backup = false;
+		
+		synchronized( this ){
+			
+			if ( backup_event != null ){
+				
+				backup_event.cancel();
+				
+				backup_event = null;
+			}
+			
+			if ( first_schedule_check ){
+				
+				if ( !enabled ){
+					
+					String last_ver = COConfigurationManager.getStringParameter( "br.backup.config.info.ver", "" );
+					
+					String current_ver = Constants.AZUREUS_VERSION;
+					
+					if ( !last_ver.equals( current_ver )){
+						
+						COConfigurationManager.setParameter( "br.backup.config.info.ver", current_ver );
+						
+						Logger.log(
+							new LogAlert(
+								false,
+								LogAlert.AT_INFORMATION,
+								MessageText.getString("br.backup.setup.info")));
+					}				
+				}
+				
+				first_schedule_check = false;
+				
+				if ( !force ){
+					
+					if ( enabled ){
+					
+						backup_event = 
+							SimpleTimer.addEvent(
+								"BM:startup",
+								SystemTime.getCurrentTime() + 5*60*1000,
+								new TimerEventPerformer()
+								{
+									public void 
+									perform(
+										TimerEvent event )
+									{
+										checkSchedule();
+									}
+								});
+					}
+					
+					return;
+				}
+			}
+			
+			if ( !enabled ){
+				
+				System.out.println( "Auto backup is disabled" );
+				
+				if ( listener != null ){
+					
+					listener.reportError( new Exception( "Auto-backup not enabled" ));
+				}
+				
+				return;
+			}
+			
+			long	now_utc = SystemTime.getCurrentTime();
+			
+			int offset = TimeZone.getDefault().getOffset( now_utc );
+			
+			long	now_local = now_utc + offset;
+			
+			long	DAY = 24*60*60*1000L;
+			
+			long	local_day_index = now_local/DAY;
+			
+			long	last_auto_backup_day = COConfigurationManager.getLongParameter( "br.backup.auto.last_backup_day", 0 );
+			
+			if ( last_auto_backup_day > local_day_index ){
+				
+				last_auto_backup_day = local_day_index;
+			}
+			
+			long	backup_every_days = COConfigurationManager.getLongParameter( "br.backup.auto.everydays" );
+			
+			backup_every_days = Math.max( 1, backup_every_days );
+			
+			long	utc_next_backup =  ( last_auto_backup_day + backup_every_days ) * DAY;
+			
+			long	time_to_next_backup = utc_next_backup - now_local;
+			
+			if ( time_to_next_backup <= 0 || force ){
+				
+				if ( now_utc - last_auto_backup >= 4*60*60*1000 || force ){
+				
+					do_backup = true;
+					
+					last_auto_backup	= now_utc;
+
+					COConfigurationManager.setParameter( "br.backup.auto.last_backup_day", local_day_index );
+
+				}else{
+					
+					time_to_next_backup	= 4*60*60*1000;
+				}
+			}
+			
+			if ( !do_backup ){
+				
+				time_to_next_backup = Math.max( time_to_next_backup, 60*1000 );
+				
+				System.out.println( "Scheduling next backup in " + TimeFormatter.format( time_to_next_backup/1000 ));
+				
+				backup_event = 
+					SimpleTimer.addEvent(
+						"BM:auto",
+						now_utc + time_to_next_backup,
+						new TimerEventPerformer()
+						{
+							public void 
+							perform(
+								TimerEvent event )
+							{
+								checkSchedule();
+							}
+						});
+			}
+		}
+		
+		if ( do_backup ){
+			
+			String backup_dir = COConfigurationManager.getStringParameter( "br.backup.auto.dir", "" );
+						
+			System.out.println( "Auto backup starting: folder=" + backup_dir );
+			
+			final File target_dir = new File( backup_dir );
+			
+			backup(
+				target_dir,
+				new BackupListener()
+				{
+					public boolean
+					reportProgress(
+						String		str )
+					{
+						if ( listener != null ){
+							
+							try{
+								return( listener.reportProgress( str ));
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+						
+						return( true );
+					}
+					
+					public void
+					reportComplete()
+					{
+						try{
+							System.out.println( "Auto backup completed" );
+							
+							COConfigurationManager.save();
+												
+							
+							if (COConfigurationManager.getBooleanParameter("br.backup.notify")) {
+  							Logger.log(
+  								new LogAlert(
+  									true,
+  									LogAlert.AT_INFORMATION,
+  									"Backup completed at " + new Date()));
+							}
+							
+							int	backup_retain = COConfigurationManager.getIntParameter( "br.backup.auto.retain" );
+
+							backup_retain = Math.max( 1, backup_retain );
+							
+							File[] backups = target_dir.listFiles();
+							
+							List<File>	backup_dirs = new ArrayList<File>();
+							
+							for ( File f: backups ){
+								
+								if ( f.isDirectory() && getBackupDirTime( f ) > 0 ){
+									
+									File	test_file = new File( f, "azureus.config" );
+									
+									if ( test_file.exists()){
+										
+										backup_dirs.add( f );
+									}
+								}
+							}
+							
+							Collections.sort(
+								backup_dirs,
+								new Comparator<File>()
+								{
+									public int 
+									compare(
+										File o1, 
+										File o2 )
+									{
+										long	t1 = getBackupDirTime( o1 );
+										long	t2 = getBackupDirTime( o2 );
+										
+										long res = t2 - t1;
+										
+										if ( res < 0 ){
+											return( -1 );
+										}else if ( res > 0 ){
+											return( 1 );
+										}else{
+											Debug.out( "hmm: " + o1 + "/" + o2 );
+											
+											return( 0 );
+										}
+									}
+								});
+							
+							for ( int i=backup_retain;i< backup_dirs.size();i++){
+								
+								File f = backup_dirs.get( i );
+								
+								System.out.println( "Deleting old backup: " + f );
+								
+								FileUtil.recursiveDeleteNoCheck( f );
+							}
+						}finally{
+							
+							if ( listener != null ){
+								
+								try{
+									
+									listener.reportComplete();
+									
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}
+							
+							checkSchedule();
+						}
+					}
+					
+					public void
+					reportError(
+						Throwable 	error )
+					{
+						try{
+							System.out.println( "Auto backup failed" );
+																					
+							Logger.log(
+									new LogAlert(
+										true,
+										LogAlert.AT_ERROR,
+										"Backup failed at " + new Date(),
+										error ));
+						}finally{
+							
+							if ( listener != null ){
+								
+								try{
+									
+									listener.reportError( error );
+									
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}
+
+							checkSchedule();
+						}
+					}
+				});
+				
+		}else{
+			
+			if ( listener != null ){
+				
+				listener.reportError( new Exception( "Backup not scheduled to run now" ));
+			}
+		}
+	}
+	
+	public void
+	runAutoBackup(
+		BackupListener			listener )
+	{
+		checkSchedule( listener, true );
+	}
+	
+	public void
+	backup(
+		final File				parent_folder,
+		final BackupListener	_listener )
+	{
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					BackupListener listener = new 
+					BackupListener()
+					{
+						public boolean
+						reportProgress(
+							String		str )
+						{
+							return( _listener.reportProgress(str));
+						}
+						
+						public void
+						reportComplete()
+						{
+							try{
+								setStatus( "" );
+								
+							}finally{
+								
+								_listener.reportComplete();
+							}
+						}
+						
+						public void
+						reportError(
+							Throwable 	error )
+						{
+							try{
+								setStatus( Debug.getNestedExceptionMessage( error ));
+							
+							}finally{
+							
+								_listener.reportError( error );
+							}
+						}
+					};
+					
+					backupSupport( parent_folder, listener );
+				}
+				
+				private void
+				setStatus(
+					String	error )
+				{
+					COConfigurationManager.setParameter( "br.backup.last.time", SystemTime.getCurrentTime());
+					COConfigurationManager.setParameter( "br.backup.last.error", error );
+				}
+			});
+	}
+	
+	private void
+	checkClosing()
+	
+		throws Exception
+	{
+		if ( closing ){
+			
+			throw( new Exception( "operation cancelled, app is closing" ));
+		}
+	}
+	
+	private long[]
+ 	copyFiles(
+ 		File		from_file,
+ 		File		to_file )
+ 	
+ 		throws Exception
+ 	{
+		return( copyFilesSupport( from_file, to_file, 1 ));
+ 	}
+	
+	private long[]
+	copyFilesSupport(
+		File		from_file,
+		File		to_file,
+		int			depth )
+	
+		throws Exception
+	{
+		long	total_files		= 0;
+		long	total_copied 	= 0;
+
+		if ( depth > 16 ){
+			
+				// lazy but whatever, our config never gets this deep
+			
+			throw( new Exception( "Loop detected in backup path, abandoning" ));
+		}
+		
+		if ( from_file.isDirectory()){
+			
+			if ( !to_file.mkdirs()){
+			
+				throw( new Exception( "Failed to create '" + to_file.getAbsolutePath() + "'" ));
+			}
+			
+			File[] files = from_file.listFiles();
+			
+			for ( File f: files ){
+				
+				checkClosing();
+				
+				long[] temp = copyFilesSupport( f, new File( to_file, f.getName()), depth+1 );
+				
+				total_files 	+= temp[0];
+				total_copied	+= temp[1];
+			}
+		}else{
+			
+			if ( !FileUtil.copyFile( from_file, to_file )){
+				
+				throw( new Exception( "Failed to copy file '" + from_file + "'" ));
+			}
+			
+			total_files++;
+			
+			total_copied = from_file.length();
+		}
+		
+		return( new long[]{ total_files, total_copied });
+	}
+	
+	private long
+	getBackupDirTime(
+		File		file )
+	{
+		String	name = file.getName();
+		
+		int	pos = name.indexOf( "." );
+		
+		long	suffix = 0;
+		
+		if ( pos != -1 ){
+		
+			try{
+				suffix = Integer.parseInt( name.substring( pos+1 ));
+				
+				name = name.substring( 0, pos );
+				
+			}catch( Throwable e ){
+				
+				return( -1 );
+			}
+		}
+		
+		try{
+			return( new SimpleDateFormat( "yyyy-MM-dd" ).parse( name ).getTime() + suffix );
+			
+		}catch( Throwable e ){
+			
+			return( -1 );
+		}
+	}
+	
+	private void
+	backupSupport(
+		File						parent_folder,
+		final BackupListener		_listener )
+	{		
+		try{
+			String date_dir = new SimpleDateFormat( "yyyy-MM-dd" ).format( new Date());
+			
+			File 		backup_folder 	= null;
+			boolean		ok 				= false;
+			
+			try{
+				checkClosing();
+
+				if ( 	parent_folder.getName().length() == 0 ||
+						!parent_folder.isDirectory()){
+					
+					throw( new Exception( "Backup folder '" + parent_folder + "' is invalid" ));
+				}
+				
+				BackupListener listener = new 
+					BackupListener()
+					{
+						public boolean
+						reportProgress(
+							String		str )
+						{
+							if ( !_listener.reportProgress( str )){
+								
+								throw( new RuntimeException( "Operation abandoned by listener" ));
+							}
+							
+							return( true );
+						}
+						
+						public void
+						reportComplete()
+						{
+							_listener.reportComplete();
+						}
+						
+						public void
+						reportError(
+							Throwable 	error )
+						{
+							_listener.reportError( error );
+						}
+					};
+					
+				for ( int i=0;i<100;i++){
+					
+					String test_dir = date_dir;
+					
+					if ( i > 0 ){
+						
+						test_dir = test_dir + "." + i;
+					}
+					
+					File test_file = new File( parent_folder, test_dir );
+					
+					if ( !test_file.exists()){
+						
+						backup_folder = test_file;
+						
+						backup_folder.mkdirs();
+						
+						break;
+					}
+				}
+				
+				if ( backup_folder == null ){
+					
+					backup_folder = new File( parent_folder, date_dir );
+				}
+				
+				File user_dir = new File( SystemProperties.getUserPath());
+
+				File temp_dir = backup_folder;
+				
+				while( temp_dir != null ){
+				
+					if ( temp_dir.equals( user_dir )){
+					
+						throw( new Exception( "Backup folder '" + backup_folder + "' is not permitted to be within the configuration folder '" + user_dir + "'.\r\nSelect an alternative location." ));
+					}
+					
+					temp_dir = temp_dir.getParentFile();
+				}
+				
+				listener.reportProgress( "Writing to " + backup_folder.getAbsolutePath());
+				
+				if ( !backup_folder.exists() && !backup_folder.mkdirs()){
+					
+					throw( new Exception( "Failed to create '" + backup_folder.getAbsolutePath() + "'" ));
+				}
+				
+				listener.reportProgress( "Syncing current state" );
+							
+				core.saveState();
+								
+				try{					
+					listener.reportProgress( "Reading configuration data from " + user_dir.getAbsolutePath());
+					
+					File[] user_files = user_dir.listFiles();
+					
+					for ( File f: user_files ){
+						
+						checkClosing();
+
+						String	name = f.getName();
+						
+						if ( f.isDirectory()){
+						
+							if ( 	name.equals( "cache" ) ||
+									name.equals( "tmp" ) ||
+									name.equals( "logs" ) ||
+									name.equals( "updates" ) ||
+									name.equals( "debug")){
+								
+								continue;
+							}
+						}else if ( 	name.equals( ".lock" ) ||
+									name.equals( "update.properties" ) ||								
+									name.endsWith( ".log" )){
+							
+							continue;
+						}
+						
+						File	dest_file = new File( backup_folder, name );
+						
+						listener.reportProgress( "Copying '" + name  + "' ..." );
+						
+						long[]	result = copyFiles( f, dest_file );
+						
+						String	result_str = DisplayFormatters.formatByteCountToKiBEtc( result[1] );
+						
+						if ( result[0] > 1 ){
+							
+							result_str = result[0] + " files, " + result_str;
+						}
+						
+						listener.reportProgress( result_str );
+					}
+										
+					listener.reportComplete();
+					
+					ok	= true;
+
+				}catch( Throwable e ){
+					
+					throw( e );
+				}
+			}finally{
+				
+				if ( !ok ){
+					
+					if ( backup_folder != null ){
+						
+						FileUtil.recursiveDeleteNoCheck( backup_folder );
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			_listener.reportError( e );
+		}
+	}
+	
+	public void
+	restore(
+		final File				backup_folder,
+		final BackupListener	listener )
+	{
+		dispatcher.dispatch(
+				new AERunnable()
+				{
+					public void
+					runSupport()
+					{
+						restoreSupport( backup_folder, listener );
+					}
+				});
+	}
+	
+	private void
+	addActions(
+		UpdateInstaller	installer,
+		File			source,
+		File			target )
+	
+		throws Exception
+	{
+		if ( source.isDirectory()){
+			
+			File[]	files = source.listFiles();
+			
+			for ( File f: files ){
+				
+				addActions( installer, f, new File( target, f.getName()));
+			}
+		}else{
+			
+			installer.addMoveAction(
+					source.getAbsolutePath(),
+					target.getAbsolutePath());
+		}
+	}
+	
+	private int
+	patch(
+		Map<String,Object>	map,
+		String				from,
+		String				to )
+	{
+		int	mods = 0;
+		
+		Iterator<Map.Entry<String,Object>> it = map.entrySet().iterator();
+			
+		Map<String,Object>	replacements = new HashMap<String, Object>();
+		
+		while( it.hasNext()){
+			
+			Map.Entry<String,Object> entry = it.next();
+			
+			String	key = entry.getKey();
+			
+			Object	value = entry.getValue();
+			
+			Object	new_value = value;
+			
+			if ( value instanceof Map ){
+				
+				mods += patch((Map)value, from, to );
+				
+			}else if ( value instanceof List ){
+				
+				mods += patch((List)value, from, to );
+
+			}else if ( value instanceof byte[] ){
+				
+				try{
+					String	str = new String((byte[])value, "UTF-8" );
+					
+					if ( str.startsWith( from )){
+						
+						new_value = to + str.substring( from.length());
+						
+						mods++;
+					}
+				}catch( Throwable e ){
+				}
+			}
+			
+			if ( key.startsWith( from )){
+				
+					// shouldn't really have file names as keys due to charset issues...
+				
+				String new_key = to + key.substring( from.length());
+				
+				mods++;
+				
+				it.remove();
+				
+				replacements.put( new_key, new_value );
+				
+			}else{
+				
+				if ( value != new_value ){
+					
+					entry.setValue( new_value );
+				}
+			}
+		}
+		
+		map.putAll( replacements );
+		
+		return( mods );
+	}
+	
+	private int
+	patch(
+		List				list,
+		String				from,
+		String				to )
+	{
+		int	mods = 0;
+		
+		for ( int i=0;i<list.size();i++){
+		
+			Object entry = list.get( i );
+			
+			if ( entry instanceof Map ){
+				
+				mods += patch((Map)entry, from , to );
+				
+			}else if ( entry instanceof List ){
+				
+				mods += patch((List)entry, from , to );
+				
+			}else if ( entry instanceof byte[] ){
+				
+				try{
+					String	str = new String((byte[])entry, "UTF-8" );
+					
+					if ( str.startsWith( from )){
+						
+						list.set( i, to + str.substring( from.length()));
+						
+						mods++;
+					}
+				}catch( Throwable e ){
+				}
+			}
+		}
+		
+		return( mods );
+	}
+	
+	private void
+	restoreSupport(
+		File				backup_folder,
+		BackupListener		listener )
+	{
+		try{
+			UpdateInstaller installer 	= null;
+			File 			temp_dir 	= null;
+			
+			boolean	ok = false;
+			
+			try{
+				listener.reportProgress( "Reading from " + backup_folder.getAbsolutePath());
+				
+				if ( !backup_folder.isDirectory()){
+					
+					throw( new Exception( "Location '" + backup_folder.getAbsolutePath() + "' must be a directory" ));
+				}
+				
+				listener.reportProgress( "Analysing backup" );
+				
+				File	config = new File( backup_folder, "azureus.config" );
+				
+				if ( !config.exists()){
+					
+					throw( new Exception( "Invalid backup: azureus.config not found" ));
+				}
+				
+				Map config_map = BDecoder.decode( FileUtil.readFileAsByteArray( config ));
+				
+				byte[]	temp = (byte[])config_map.get( "azureus.user.directory" );
+				
+				if ( temp == null ){
+					
+					throw( new Exception( "Invalid backup: azureus.config doesn't contain user directory details" ));
+				}
+				
+				File current_user_dir	= new File( SystemProperties.getUserPath());
+				File backup_user_dir 	= new File( new String( temp, "UTF-8" ));
+				
+				listener.reportProgress( "Current user directory:\t"  + current_user_dir.getAbsolutePath());
+				listener.reportProgress( "Backup's user directory:\t" + backup_user_dir.getAbsolutePath());
+				
+				temp_dir = AETemporaryFileHandler.createTempDir();
+				
+				PluginInterface pi = core.getPluginManager().getDefaultPluginInterface();
+				
+				installer = pi.getUpdateManager().createInstaller();
+			
+				File[] files = backup_folder.listFiles();
+				
+				if ( current_user_dir.equals( backup_user_dir )){
+					
+					listener.reportProgress( "Directories are the same, no patching required" );
+					
+					for ( File f: files ){
+						
+						File source = new File( temp_dir, f.getName());
+						
+						listener.reportProgress( "Creating restore action for '" + f.getName() + "'" );
+	
+						copyFiles( f, source );
+						
+						File target = new File( current_user_dir, f.getName());
+						
+						addActions( installer, source, target );
+					}	
+				}else{
+					
+					listener.reportProgress( "Directories are different, backup requires patching" );
+	
+					for ( File f: files ){
+						
+						File source = new File( temp_dir, f.getName());
+						
+						listener.reportProgress( "Creating restore action for '" + f.getName() + "'" );
+	
+						if ( f.isDirectory() || !f.getName().contains( ".config" )){
+						
+							copyFiles( f, source );
+							
+						}else{
+							
+							boolean	patched = false;
+							
+							BufferedInputStream bis = new BufferedInputStream( new FileInputStream( f ), 1024*1024 );
+							
+							try{
+								Map m = BDecoder.decode( bis );
+								
+								bis.close();
+								
+								bis = null;
+								
+								if ( m.size() > 0 ){
+									
+									int applied = patch( m, backup_user_dir.getAbsolutePath(), current_user_dir.getAbsolutePath());
+									
+									if ( applied > 0 ){
+										
+										listener.reportProgress( "    Applied " + applied + " patches" );
+										
+										patched = FileUtil.writeBytesAsFile2( source.getAbsolutePath(), BEncoder.encode( m ));
+										
+										if ( !patched ){
+											
+											throw( new Exception( "Failed to write " + source ));
+										}
+									}
+								}
+							}finally{
+								
+								if ( bis != null ){
+								
+									try{
+										bis.close();
+										
+									}catch( Throwable e ){
+										
+									}
+								}
+							}
+							
+							if ( !patched ){
+								
+								copyFiles( f, source );
+							}
+						}
+						
+						File target = new File( current_user_dir, f.getName());
+						
+						addActions( installer, source, target );
+					}
+				}
+				
+				listener.reportProgress( "Restore action creation complete, restart required to complete the operation" );
+
+				listener.reportComplete();
+			
+				ok = true;
+				
+			}finally{
+				
+				if ( !ok ){
+				
+					if ( installer != null ){
+						
+						installer.destroy();
+					}
+					
+					if ( temp_dir != null ){
+						
+						FileUtil.recursiveDeleteNoCheck( temp_dir );
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			listener.reportError( e );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/clientmessageservice/impl/AEClientService.java b/com/aelitis/azureus/core/clientmessageservice/impl/AEClientService.java
index 44221f2..bfb7190 100644
--- a/com/aelitis/azureus/core/clientmessageservice/impl/AEClientService.java
+++ b/com/aelitis/azureus/core/clientmessageservice/impl/AEClientService.java
@@ -100,12 +100,12 @@ public class AEClientService implements ClientMessageService {
 	
 	ConnectionEndpoint	ce = new ConnectionEndpoint( tcp_target );
 	
-	new ProtocolEndpointTCP( ce, tcp_target );
+	ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, ce, tcp_target );
 	   
     final AESemaphore connect_block = new AESemaphore( "AEClientService:C" );
     
     ce.connectOutbound( false, false, null, null, ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM, new Transport.ConnectListener() {  //NOTE: async operation!
-    	public void connectAttemptStarted() {  /*nothing*/ }
+    	public int connectAttemptStarted( int default_connect_timeout ) { return( default_connect_timeout ); }
       
     	public void connectSuccess(Transport transport, ByteBuffer remaining_initial_data ){
     		conn = new ClientConnection((TCPTransportImpl)transport );
diff --git a/com/aelitis/azureus/core/clientmessageservice/impl/ClientConnection.java b/com/aelitis/azureus/core/clientmessageservice/impl/ClientConnection.java
index 9557bfe..160bd8e 100644
--- a/com/aelitis/azureus/core/clientmessageservice/impl/ClientConnection.java
+++ b/com/aelitis/azureus/core/clientmessageservice/impl/ClientConnection.java
@@ -29,6 +29,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.core.networkmanager.*;
 import com.aelitis.azureus.core.networkmanager.impl.OutgoingMessageQueueImpl;
@@ -48,7 +49,7 @@ public class ClientConnection {
 	private final Transport light_transport;
 	private final OutgoingMessageQueue out_queue;
 	private final AZMessageDecoder decoder;
-	private static final AZMessageEncoder encoder = new AZMessageEncoder( false );
+	private static final AZMessageEncoder encoder = new AZMessageEncoder( AZMessageEncoder.PADDING_MODE_NONE );
 	private long last_activity_time;
 	
 	private final AEMonitor msg_mon = new AEMonitor( "ClientConnection" );
@@ -72,8 +73,9 @@ public class ClientConnection {
 		
 		InetSocketAddress remote = null;	// unfortunately we don't have an address at this point (see NATTestService)
 		
-		ProtocolEndpointTCP	pe =  new ProtocolEndpointTCP( remote );
-				
+		ProtocolEndpointTCP	pe = 
+			(ProtocolEndpointTCP)ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, remote );
+							
 		light_transport = pe.connectLightWeight( channel );
 		
 		out_queue = new OutgoingMessageQueueImpl( encoder );
@@ -194,11 +196,12 @@ public class ClientConnection {
 		decoder.destroy();
 		out_queue.destroy();
 		
+		String x = "Tidy close" + ( reason==null?"":(": " + Debug.getNestedExceptionMessage( reason )));
 		if( parent_transport != null ) {
-			parent_transport.close( "Tidy close");  //have the parent do the close if possible
+			parent_transport.close( x );  //have the parent do the close if possible
 		}
 		else {
-			light_transport.close("Tidy close");
+			light_transport.close( x );
 		}
 	}
 	
diff --git a/com/aelitis/azureus/core/clientmessageservice/impl/NonBlockingReadWriteService.java b/com/aelitis/azureus/core/clientmessageservice/impl/NonBlockingReadWriteService.java
index b082db1..d81c233 100644
--- a/com/aelitis/azureus/core/clientmessageservice/impl/NonBlockingReadWriteService.java
+++ b/com/aelitis/azureus/core/clientmessageservice/impl/NonBlockingReadWriteService.java
@@ -175,7 +175,7 @@ public class NonBlockingReadWriteService {
       	catch( Throwable t ) {
       		if ( !client.isClosePending()){
       			
-      			System.out.println( "[" +new Date()+ "] Connection read error [" +sc.socket().getInetAddress()+ "] [" +client.getDebugString()+ "]: " +t.getMessage() );
+      			//System.out.println( "[" +new Date()+ "] Connection read error [" +sc.socket().getInetAddress()+ "] [" +client.getDebugString()+ "]: " +t.getMessage() );
       		}
       		
       		listener.connectionError( client, t );
@@ -206,7 +206,7 @@ public class NonBlockingReadWriteService {
       		return( client.getLastWriteMadeProgress());
       	}
       	catch( Throwable t ) {
-          System.out.println( "[" +new Date()+ "] Connection write error [" +sc.socket().getInetAddress()+ "] [" +client.getDebugString()+ "]: " +t.getMessage() );
+          //System.out.println( "[" +new Date()+ "] Connection write error [" +sc.socket().getInetAddress()+ "] [" +client.getDebugString()+ "]: " +t.getMessage() );
           listener.connectionError( client, t );
           return( false );
       	}
@@ -279,7 +279,7 @@ public class NonBlockingReadWriteService {
 		finally {  connections_mon.exit();  }
 		
 		if( !still_connected ) {
-			System.out.println( "[" +new Date()+ "] Connection message send error [connection no longer connected]: " +vconn.getDebugString()+ "]" );
+			// System.out.println( "[" +new Date()+ "] Connection message send error [connection no longer connected]: " +vconn.getDebugString()+ "]" );
 			message.reportFailed( new Exception("No longer connected" ));
 			//listener.connectionError( vconn ); //no need to call this, as there is no connection to remove
       return;
diff --git a/com/aelitis/azureus/core/cnetwork/ContentNetwork.java b/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
index fac30af..664369d 100644
--- a/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
+++ b/com/aelitis/azureus/core/cnetwork/ContentNetwork.java
@@ -39,13 +39,6 @@ ContentNetwork
 	
 	public static final long	CONTENT_NETWORK_VHDNL		= 3;
 
-		// test networks
-	
-	public static final long	CONTENT_NETWORK_JR			= 10000;
-	public static final long	CONTENT_NETWORK_CHUN		= 10001;
-	public static final long	CONTENT_NETWORK_SOUK		= 10002;
-	public static final long	CONTENT_NETWORK_DEV02		= 10003;
-
 
 	public static final int		SERVICE_SEARCH				= 1;	// String - query text
 	public static final int		SERVICE_XSEARCH				= 2;	// String - query text; Boolean - toSubscribe
@@ -83,6 +76,7 @@ ContentNetwork
 	public static final int		SERVICE_SIDEBAR_CLOSE  		= 34;
 	public static final int		SERVICE_ABOUT				= 35;
 	public static final int		SERVICE_IDENTIFY			= 36;	
+	public static final int		SERVICE_EXT_SITE_RELATIVE		= 37;	// String - relative URL
 
 		// content network properties
 	
@@ -207,6 +201,11 @@ ContentNetwork
 		boolean		append_suffix );
 	
 	public String
+	getExternalSiteRelativeURL(
+		String		relative_url,
+		boolean		append_suffix );
+	
+	public String
 	getAddFriendURL(
 		String		bg_colour );
 	
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkImpl.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkImpl.java
index f09603f..78237b9 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkImpl.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkImpl.java
@@ -253,6 +253,14 @@ ContentNetworkImpl
 	}
 	
 	public String 
+	getExternalSiteRelativeURL(
+		String 		relative_url,
+		boolean		append_suffix )
+	{
+		return( getServiceURL( SERVICE_EXT_SITE_RELATIVE, new Object[]{ relative_url, append_suffix }));
+	}
+	
+	public String 
 	getAddFriendURL(
 		String 	colour )
 	{
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkManagerImpl.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkManagerImpl.java
index d018152..c2f0051 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkManagerImpl.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkManagerImpl.java
@@ -47,11 +47,6 @@ import com.aelitis.azureus.core.custom.Customization;
 import com.aelitis.azureus.core.custom.CustomizationManager;
 import com.aelitis.azureus.core.custom.CustomizationManagerFactory;
 
-import com.aelitis.azureus.core.messenger.PlatformMessengerException;
-import com.aelitis.azureus.core.messenger.config.PlatformContentNetworkMessenger;
-import com.aelitis.azureus.core.messenger.config.PlatformContentNetworkMessenger.contentNetworkDetails;
-import com.aelitis.azureus.core.messenger.config.PlatformContentNetworkMessenger.listNetworksListener;
-
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
@@ -230,54 +225,6 @@ ContentNetworkManagerImpl
 	protected void
 	checkForUpdates()
 	{
-		synchronized( this ){
-			
-				// vuze network always present, no need to check this for updates as we don't auto
-				// update it
-			
-			if ( networks.size() < 2 && !LOAD_ALL_NETWORKS ){
-			
-				return;
-			}
-		}
-		
-		PlatformContentNetworkMessenger.listNetworksAync(new listNetworksListener() {
-			public void networkListReturned(List<contentNetworkDetails> cnets) {
-
-				try{
-					String	str = "";
-					
-					for ( contentNetworkDetails details: cnets ){
-					
-						str += (str.length()==0?"":", ") + details.getString();
-						
-						ContentNetwork existing = getContentNetwork( details.getID());
-						
-						if ( existing != null ){
-							
-							ContentNetworkImpl new_net = createNetwork( details );
-							
-							addNetwork( new_net );
-							
-						}else{
-							
-							if ( LOAD_ALL_NETWORKS ){
-								
-								ContentNetworkImpl new_net = createNetwork( details );
-								
-								addNetwork( new_net );
-							}
-						}
-					}
-					
-					log( "Latest networks: " + str );
-					
-				}catch( Throwable e ){
-
-					log( "Failed to load network list", e );
-				}
-			}
-		}, 11110);
 	}
 	
 	protected ContentNetworkImpl
@@ -298,67 +245,6 @@ ContentNetworkManagerImpl
 	
 		throws ContentNetworkException
 	{
-		try{
-			PlatformContentNetworkMessenger.listNetworksAync(new listNetworksListener() {
-				public void networkListReturned(List<contentNetworkDetails> cnets) {
-					if (cnets == null) {
-
-						Exception e = new PlatformMessengerException( "No networks returned" );
-
-						for ( ContentNetworkListener l : listeners ) {
-
-							l.networkAddFailed(id, e);
-						}
-
-						return;
-					}
-					
-					for ( contentNetworkDetails details: cnets ){
-						
-						if ( details.getID() == id ){
-							
-							ContentNetworkImpl new_net;
-							try {
-
-								new_net = createNetwork( details );
-
-								addNetwork( new_net );
-							} catch (ContentNetworkException e) {
-
-								for ( ContentNetworkListener l : listeners ) {
-
-									l.networkAddFailed(id, e);
-								}
-
-							}
-
-							return;
-						}
-					}
-
-					Exception e = new ContentNetworkException(
-									"Content Network with id " + id + " not found");
-
-					for ( ContentNetworkListener l : listeners ) {
-
-						l.networkAddFailed(id, e);
-					}
-					
-				}
-			}, 500);
-										
-
-		}catch( Throwable e ){
-			
-			ContentNetworkException e2 = new ContentNetworkException( "Failed to list permitted networks", e );
-
-			for ( ContentNetworkListener l : listeners ) {
-
-				l.networkAddFailed(id, e2);
-			}
-			
-			throw e2;
-		}
 	}
 	
 	public ContentNetwork
@@ -401,64 +287,6 @@ ContentNetworkManagerImpl
 		return( getContentNetwork( ContentNetwork.CONTENT_NETWORK_VUZE ));
 	}
 	
-	protected ContentNetworkImpl
-	createNetwork(
-		contentNetworkDetails		details )
-	
-		throws ContentNetworkException
-	{	
-		String main_url = details.getMainURL();
-		String icon_url	= details.getIconURL();
-		
-		String site_dns;
-		
-		try{
-			site_dns = new URL( main_url ).getHost();
-			
-		}catch( Throwable e ){
-			
-			log( "Failed to get main-url host", e );
-			
-			throw( new ContentNetworkException( "main url invald", e ));
-		}
-		
-			// propagate persistent property defaults and exclusions as currently not returned by webapp
-		
-		ContentNetworkImpl existing = getContentNetwork( details.getID());
-		
-		Map<String,Object> 	pprop_defaults		= null;
-		Set<Integer>		service_exclusions	= null;
-		
-		if ( existing != null ){
-			
-			pprop_defaults = existing.getPersistentPropertyDefaults();
-			
-			if ( existing instanceof ContentNetworkVuzeGeneric ){
-				
-				service_exclusions	= ((ContentNetworkVuzeGeneric)existing).getServiceExclusions();
-			}
-		}
-		
-		return( 
-			new ContentNetworkVuzeGeneric( 
-					this,
-					details.getID(),
-					details.getVersion(),
-					details.getName(),
-					pprop_defaults,
-					service_exclusions,
-					site_dns,
-					main_url,
-					icon_url,
-					null,
-					null,
-					null,
-					null,
-					null,
-					null ));
-
-	}
-	
 	public ContentNetwork[] 
 	getContentNetworks() 
 	{
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
index a5fe6e8..15db098 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuze.java
@@ -23,6 +23,7 @@ package com.aelitis.azureus.core.cnetwork.impl;
 
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+// import com.aelitis.azureus.core.util.FeatureAvailability;
 
 public class 
 ContentNetworkVuze 
@@ -36,14 +37,30 @@ ContentNetworkVuze
 
 	private static final String DEFAULT_RELAY_PORT = "80";
 
+	private static final String DEFAULT_EXT_ADDRESS = "www.vuze.com"; //DO NOT TOUCH !!!!  
+
+	/*
+	static{
+		if ( FeatureAvailability.ENABLE_PLUS()){
+			
+			if ( System.getProperty( "platform_address", "" ).length() == 0 ){
+			
+				System.setProperty( "platform_address", "www2.vuze.com" );
+			}
+		}
+	}
+	*/
+	
 	private static final String URL_ADDRESS = System.getProperty( "platform_address", DEFAULT_ADDRESS );
 
 	private static final String URL_PORT 	= System.getProperty( "platform_port", DEFAULT_PORT );
 
 	private static final String URL_PREFIX = "http://" + URL_ADDRESS + ":" + URL_PORT + "/";
 
-	
-	
+	private static final String URL_EXT_PREFIX = "http://" 
+		+ System.getProperty( "platform_address_ext", DEFAULT_EXT_ADDRESS ) + ":"
+		+ System.getProperty( "platform_port_ext", DEFAULT_PORT ) + "/";
+
 	private static final String DEFAULT_AUTHORIZED_RPC = "https://" + URL_ADDRESS + ":443/rpc";
 
 	private static String URL_RELAY_RPC = System.getProperty("relay_url",
@@ -55,7 +72,7 @@ ContentNetworkVuze
 			"authorized_rpc", "1").equals("1") ? DEFAULT_AUTHORIZED_RPC : URL_PREFIX
 			+ "app";
 	
-	private static final String URL_FAQ = "http://faq.vuze.com/";
+	private static final String URL_FAQ = "http://wiki.vuze.com/";
 
 	private static final String URL_BLOG = "http://blog.vuze.com/";
 	
@@ -81,6 +98,7 @@ ContentNetworkVuze
 				URL_FAQ,
 				URL_BLOG,
 				URL_FORUMS,
-				URL_WIKI );
+				URL_WIKI,
+				URL_EXT_PREFIX );
 	}
 }
diff --git a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
index 35d7aa2..14e5caf 100644
--- a/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
+++ b/com/aelitis/azureus/core/cnetwork/impl/ContentNetworkVuzeGeneric.java
@@ -26,12 +26,19 @@ 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.Base32;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.crypto.VuzeCryptoManager;
+import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
 import com.aelitis.azureus.util.ImportExportUtils;
 
 public class 
@@ -40,36 +47,40 @@ ContentNetworkVuzeGeneric
 {
 	private static String URL_SUFFIX;
 
-	static{
-		COConfigurationManager.addAndFireParameterListener(
-			"locale",
-			new ParameterListener(){
-				public void 
-				parameterChanged(
-					String parameterName )
-				{	
-						// Don't change the order of the params as there's some code somewhere
-						// that depends on them (I think its code that removes the azid so
-						// we can fix this up when that code's migrated here I guess
-					
-					URL_SUFFIX = 	"azid=" 	+ Base32.encode(VuzeCryptoManager.getSingleton().getPlatformAZID()) +
-									"&azv=" 	+ Constants.AZUREUS_VERSION +
-									"&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;
-					}
+	static {
+		COConfigurationManager.addAndFireParameterListeners(new String[] {
+			"Send Version Info",
+			"locale"
+		}, new ParameterListener() {
+			public void parameterChanged(String parameterName) {
+				// Don't change the order of the params as there's some code somewhere
+				// that depends on them (I think its code that removes the azid so
+				// we can fix this up when that code's migrated here I guess
+				boolean send_info = COConfigurationManager.getBooleanParameter("Send Version Info");
+
+				URL_SUFFIX = "azid="
+						+ (send_info
+								? Base32.encode(VuzeCryptoManager.getSingleton().getPlatformAZID())
+								: "anonymous") + "&azv=" + Constants.AZUREUS_VERSION
+						+ "&locale=" + MessageText.getCurrentLocale().toString() + "&os.name="
+						+ UrlUtils.encode(System.getProperty("os.name")) + "&vzemb=1";
+				String suffix = System.getProperty("url.suffix", null);
+				if (suffix != null) {
+					URL_SUFFIX += "&" + suffix;
 				}
-			});
+			}
+		});
 	}
 
+	private static final String RPC_ADDRESS = System.getProperty( "platform_rpc", "vrpc.vuze.com" );
+
 	private Map<Integer, String>		service_map = new HashMap<Integer, String>();
 
 	private Set<Integer>				service_exclusions;
 	
 	private String	SITE_HOST;
 	private String	URL_PREFIX;
+	private String	URL_EXT_PREFIX;
 	private String	URL_ICON;
 	private String	URL_RELAY_RPC;
 	private String	URL_AUTHORIZED_RPC;
@@ -77,7 +88,10 @@ ContentNetworkVuzeGeneric
 	private String	URL_BLOG;
 	private String	URL_FORUMS;
 	private String	URL_WIKI;
+	
+	private Boolean conduit = null;
 
+	// Keeping this around for safetly, since it's a 4402 release
 	public
 	ContentNetworkVuzeGeneric(
 		ContentNetworkManagerImpl	_manager,
@@ -96,6 +110,31 @@ ContentNetworkVuzeGeneric
 		String						_url_forums,
 		String						_url_wiki )
 	{
+		this(_manager, _content_network, _version, _name, _pprop_defaults,
+				_service_exclusions, _site_host, _url_prefix, _url_icon,
+				_url_relay_rpc, _url_authorised_rpc, _url_faq, _url_blog, _url_forums,
+				_url_wiki, null);
+	}
+
+	public
+	ContentNetworkVuzeGeneric(
+		ContentNetworkManagerImpl	_manager,
+		long						_content_network,
+		long						_version,
+		String						_name,
+		Map<String,Object>			_pprop_defaults,
+		Set<Integer>				_service_exclusions,
+		String						_site_host,
+		String						_url_prefix,
+		String						_url_icon,
+		String						_url_relay_rpc,
+		String						_url_authorised_rpc,
+		String						_url_faq,
+		String						_url_blog,
+		String						_url_forums,
+		String						_url_wiki,
+		String						_url_ext_prefix )
+	{
 		super( _manager, TYPE_VUZE_GENERIC, _content_network, _version, _name, _pprop_defaults );
 		 
 		SITE_HOST				= _site_host;
@@ -107,6 +146,7 @@ ContentNetworkVuzeGeneric
 		URL_BLOG				= _url_blog;
 		URL_FORUMS				= _url_forums;
 		URL_WIKI				= _url_wiki;
+		URL_EXT_PREFIX = _url_ext_prefix;
 		 
 		service_exclusions		= _service_exclusions;
 		
@@ -135,6 +175,10 @@ ContentNetworkVuzeGeneric
 		
 		SITE_HOST				= ImportExportUtils.importString(map, "vg_site" );
 		URL_PREFIX 				= ImportExportUtils.importString(map, "vg_prefix" );
+		URL_EXT_PREFIX 				= ImportExportUtils.importString(map, "vg_ext_prefix" );
+		if (URL_EXT_PREFIX == null) {
+			URL_EXT_PREFIX = URL_PREFIX;
+		}
 		URL_ICON 				= ImportExportUtils.importString(map, "vg_icon" );
 		URL_RELAY_RPC			= ImportExportUtils.importString(map, "vg_relay_rpc" );
 		URL_AUTHORIZED_RPC		= ImportExportUtils.importString(map, "vg_auth_rpc" );
@@ -168,6 +212,7 @@ ContentNetworkVuzeGeneric
 		
 		ImportExportUtils.exportString(map, "vg_site", 		SITE_HOST );
 		ImportExportUtils.exportString(map, "vg_prefix", 	URL_PREFIX );
+		ImportExportUtils.exportString(map, "vg_ext_prefix", 	URL_EXT_PREFIX );
 		ImportExportUtils.exportString(map, "vg_icon", 		URL_ICON );
 		ImportExportUtils.exportString(map, "vg_relay_rpc", URL_RELAY_RPC );
 		ImportExportUtils.exportString(map, "vg_auth_rpc", 	URL_AUTHORIZED_RPC );
@@ -196,11 +241,11 @@ ContentNetworkVuzeGeneric
 		
 		addService( SERVICE_SEARCH, 			URL_PREFIX + "search?q=" );
 		addService( SERVICE_XSEARCH, 			URL_PREFIX + "xsearch/index.php?q=" );
-		addService( SERVICE_RPC, 				"http://vrpc.vuze.com/vzrpc/rpc.php" );
+		addService( SERVICE_RPC, 				"http://" + RPC_ADDRESS + "/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?" );
-		addService( SERVICE_ABOUT, 			URL_PREFIX + "about.start?" );
+		addService( SERVICE_ABOUT, 				URL_PREFIX + "about.start?" );
 		addService( SERVICE_PUBLISH_NEW, 		URL_PREFIX + "publishnew.start?" );
 		addService( SERVICE_PUBLISH_ABOUT, 		URL_PREFIX + "publishinfo.start" );
 		addService( SERVICE_CONTENT_DETAILS, 	URL_PREFIX + "details/" );
@@ -208,13 +253,14 @@ ContentNetworkVuzeGeneric
 		addService( SERVICE_PROFILE,			URL_PREFIX + "profile/" );
 		addService( SERVICE_TORRENT_DOWNLOAD,	URL_PREFIX + "download/" );
 		addService( SERVICE_SITE,				URL_PREFIX );
-		addService( SERVICE_SUPPORT,			URL_PREFIX + "support/" );
+		addService( SERVICE_SUPPORT,			URL_EXT_PREFIX + "support/" );
 		addService( SERVICE_LOGIN,				URL_PREFIX + "login.start?" );
 		addService( SERVICE_LOGOUT,				URL_PREFIX + "logout.start?" );
 		addService( SERVICE_REGISTER,			URL_PREFIX + "register.start?" );
 		addService( SERVICE_MY_PROFILE,			URL_PREFIX + "profile.start?" );
 		addService( SERVICE_MY_ACCOUNT,			URL_PREFIX + "account.start?" );
 		addService( SERVICE_SITE_RELATIVE,		URL_PREFIX );
+		addService( SERVICE_EXT_SITE_RELATIVE,		URL_EXT_PREFIX );
 		addService( SERVICE_ADD_FRIEND,			URL_PREFIX + "user/AddFriend.html?" );
 		addService( SERVICE_SUBSCRIPTION,		URL_PREFIX + "xsearch/index.php?" );
 		 		
@@ -239,7 +285,7 @@ ContentNetworkVuzeGeneric
 		if ( URL_FAQ != null ){
 		 
 			addService( SERVICE_FAQ,			URL_FAQ );
-			addService( SERVICE_FAQ_TOPIC,		URL_FAQ + "?View=entry&EntryID=" );
+			addService( SERVICE_FAQ_TOPIC,		URL_FAQ );
 		}
 		 
 		if ( URL_BLOG != null ){
@@ -365,6 +411,15 @@ ContentNetworkVuzeGeneric
 					url_str += "&createSubscription=1";
 				}
 				
+				String	extension_key = getExtensionKey();
+				
+				if ( extension_key != null ){
+					
+					url_str += "&extension_key=" + UrlUtils.encode( extension_key );
+				}
+				
+				url_str += "&fud=" + UrlUtils.encode( MetaSearchManagerFactory.getSingleton().getMetaSearch().getFUD());
+				
 				return( url_str );
 			}
 			case SERVICE_CONTENT_DETAILS:{
@@ -463,6 +518,22 @@ ContentNetworkVuzeGeneric
 				
 				return( base );
 			}
+			case SERVICE_EXT_SITE_RELATIVE:{
+				
+				String	relative_url 	= (String)params[0];
+				boolean	append_suffix	= (Boolean)params[1];
+				
+				base += relative_url.startsWith("/")?relative_url.substring(1):relative_url;
+				
+				if ( append_suffix ){
+
+					base = appendURLSuffix( base, false, true );
+				}
+
+				base = base.replaceAll( "&vzemb=1", "" );
+
+				return( base );
+			}
 			case SERVICE_ADD_FRIEND:{
 				
 				String	colour 	= (String)params[0];
@@ -490,9 +561,17 @@ ContentNetworkVuzeGeneric
 
 				return( base );
 			}
+			case SERVICE_WELCOME:{
+				String installID = COConfigurationManager.getStringParameter("install.id", "null");
+				if (installID.length() == 0) {
+					installID = "blank";
+				}
+				base += "iid=" + UrlUtils.encode(installID) + "&" + URL_SUFFIX;
+				return( base );
+			}
+
 			case SERVICE_BIG_BROWSE:
 			case SERVICE_PUBLISH:
-			case SERVICE_WELCOME:
 			case SERVICE_LOGOUT:
 			case SERVICE_REGISTER:{
 				
@@ -501,11 +580,11 @@ ContentNetworkVuzeGeneric
 			case SERVICE_ABOUT: {
 				// no azid needed (+ makes URL ugly)
 				return base + "azv=" + Constants.AZUREUS_VERSION + "&locale="
-						+ Locale.getDefault().toString();  
+						+ MessageText.getCurrentLocale().toString();  
 			}
 			default:{
 				
-				return( base );
+				return( appendURLSuffix( base, false, true) );
 			}
 		}
 	}
@@ -516,12 +595,13 @@ ContentNetworkVuzeGeneric
 		boolean		for_post,
 		boolean 	include_azid ) 
 	{
-		if ( url_in.indexOf( "azid=" ) != -1 ){
+		if ( url_in.indexOf( "vzemb=" ) != -1 ){
 	
 				// already present
 			
 			return( url_in );
 		}
+		
 	
 		String suffix = URL_SUFFIX;
 		
@@ -552,4 +632,27 @@ ContentNetworkVuzeGeneric
 			}
 		}
 	}
+	
+	private String
+	getExtensionKey()
+	{
+		FeatureManager fm = PluginInitializer.getDefaultInterface().getUtilities().getFeatureManager();
+		
+		FeatureDetails[] fds = fm.getFeatureDetails( "core" );
+		
+		for ( FeatureDetails fd: fds ){
+				
+			if ( !fd.hasExpired()){
+				
+				String finger_print = (String)fd.getProperty( FeatureDetails.PR_FINGERPRINT );
+					
+				if ( finger_print != null ){
+				
+					return( fd.getLicence().getShortID() + "-" + finger_print );
+				}
+			}
+		}
+		
+		return( null );
+	}
 }
diff --git a/com/aelitis/azureus/core/content/AzureusPlatformContentDirectory.java b/com/aelitis/azureus/core/content/AzureusPlatformContentDirectory.java
index 7986b70..e982187 100644
--- a/com/aelitis/azureus/core/content/AzureusPlatformContentDirectory.java
+++ b/com/aelitis/azureus/core/content/AzureusPlatformContentDirectory.java
@@ -45,6 +45,10 @@ import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.util.ConstantsVuze;
 
+/**
+ * Used in UPnP for something
+ * 
+ */
 public class 
 AzureusPlatformContentDirectory
 	implements AzureusContentDirectory
@@ -177,7 +181,7 @@ AzureusPlatformContentDirectory
 			
 			final TOTorrent torrent = ((TorrentImpl)t_torrent).getTorrent();
 			
-			final DiskManagerFileInfo	file = download.getDiskManagerFileInfo()[index];
+			final DiskManagerFileInfo	file = download.getDiskManagerFileInfo(index);
 
 			if ( PlatformTorrentUtils.isContent( torrent, false )){
 			
diff --git a/com/aelitis/azureus/core/content/RelatedContent.java b/com/aelitis/azureus/core/content/RelatedContent.java
index a751c6c..9dae42c 100644
--- a/com/aelitis/azureus/core/content/RelatedContent.java
+++ b/com/aelitis/azureus/core/content/RelatedContent.java
@@ -39,7 +39,7 @@ RelatedContent
 	
 	private byte[]		related_to_hash;
 
-	protected
+	public
 	RelatedContent(
 		byte[]		_related_to_hash,
 		String		_title,
@@ -60,7 +60,7 @@ RelatedContent
 		content_network		= _cnet;
 	}
 	
-	protected
+	public
 	RelatedContent(
 		String		_title,
 		byte[]		_hash,
diff --git a/com/aelitis/azureus/core/content/RelatedContentManager.java b/com/aelitis/azureus/core/content/RelatedContentManager.java
index 2889283..a1b3b49 100644
--- a/com/aelitis/azureus/core/content/RelatedContentManager.java
+++ b/com/aelitis/azureus/core/content/RelatedContentManager.java
@@ -21,19 +21,22 @@
 
 package com.aelitis.azureus.core.content;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.lang.ref.WeakReference;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.net.URL;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
 
 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;
@@ -81,11 +84,14 @@ 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.DHTTransport;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
 import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
+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.core.util.FeatureAvailability;
+import com.aelitis.azureus.core.util.RegExUtil;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
 import com.aelitis.azureus.plugins.dht.DHTPlugin;
@@ -93,21 +99,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
 	implements DistributedDatabaseTransferHandler
 {
-	private static final boolean 	TRACE = false;
-	private static final boolean	DISABLE_ALL_UI	= !Constants.isCVSVersion();
-
+	private static final boolean 	TRACE 			= false;
+	
+	private static final boolean	SEARCH_CVS_ONLY		= Constants.isCurrentVersionLT( "4.7.0.4" );
+	private static final boolean	TRACE_SEARCH		= false;
+	
 	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	MAX_REMOTE_SEARCH_CONTACTS	= 50;
-	private static final int	MAX_REMOTE_SEARCH_MILLIS	= 25*1000;
+	private static final int	MAX_REMOTE_SEARCH_MILLIS		= 25*1000;
+	private static final int	REDUCED_REMOTE_SEARCH_MILLIS	= 10*1000;
 	
 	private static final int	TEMPORARY_SPACE_DELTA	= 50;
 	
@@ -156,7 +164,6 @@ RelatedContentManager
 	
 	private final boolean	enabled;
 	
-	private boolean	ui_enabled;
 	private int		max_search_level;
 	private int		max_results;
 	
@@ -168,15 +175,20 @@ 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;
-	private static final int SECONDARY_LOOKUP_TICKS		= SECONDARY_LOOKUP_PERIOD/TIMER_PERIOD;
-	private static final int REPUBLISH_PERIOD			= 8*60*60*1000;
-	private static final int REPUBLISH_TICKS			= REPUBLISH_PERIOD/TIMER_PERIOD;
+	private static final int TIMER_PERIOD					= 30*1000;
+	private static final int CONFIG_SAVE_CHECK_PERIOD		= 60*1000;
+	private static final int CONFIG_SAVE_PERIOD				= 5*60*1000;
+	private static final int CONFIG_SAVE_CHECK_TICKS		= CONFIG_SAVE_CHECK_PERIOD/TIMER_PERIOD;
+	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 PUBLISH_SLEEPING_CHECK_PERIOD	= 5*60*1000;
+	private static final int PUBLISH_SLEEPING_CHECK_TICKS	= PUBLISH_SLEEPING_CHECK_PERIOD/TIMER_PERIOD;
+
+	private static final int SECONDARY_LOOKUP_PERIOD		= 15*60*1000;
+	private static final int SECONDARY_LOOKUP_TICKS			= SECONDARY_LOOKUP_PERIOD/TIMER_PERIOD;
+	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;
@@ -194,7 +206,8 @@ RelatedContentManager
 	
 	private AtomicInteger	total_unread = new AtomicInteger( COConfigurationManager.getIntParameter( CONFIG_TOTAL_UNREAD, 0 ));
 	
-	private AsyncDispatcher	content_change_dispatcher = new AsyncDispatcher();
+	private AsyncDispatcher	content_change_dispatcher 	= new AsyncDispatcher();
+	private AsyncDispatcher	harvest_dispatcher			= new AsyncDispatcher();
 	
 	private static final int SECONDARY_LOOKUP_CACHE_MAX = 10;
 	
@@ -206,16 +219,86 @@ RelatedContentManager
 	private DistributedDatabase		ddb;
 	private RCMSearchXFer			transfer_type = new RCMSearchXFer();
 	
+	private static final int MAX_TRANSIENT_CACHE	= 256;
+	
+	private static Map<String,DownloadInfo> transient_info_cache =
+		new LinkedHashMap<String,DownloadInfo>(MAX_TRANSIENT_CACHE,0.75f,true)
+		{
+			protected boolean 
+			removeEldestEntry(
+		   		Map.Entry<String,DownloadInfo> eldest) 
+			{
+				return size() > MAX_TRANSIENT_CACHE;
+			}
+		};
+	
+	private static final int	HARVEST_MAX_BLOOMS				= 50;
+	private static final int	HARVEST_MAX_FAILS_HISTORY		= 128;
+	private static final int	HARVEST_BLOOM_UPDATE_MILLIS		= 15*60*1000;
+	private static final int	HARVEST_BLOOM_DISCARD_MILLIS	= 60*60*1000;
+	private static final int 	HARVEST_BLOOM_OP_RESET_MILLIS	= 5*60*1000;
+	private static final int 	HARVEST_BLOOM_OP_RESET_TICKS	= HARVEST_BLOOM_OP_RESET_MILLIS/TIMER_PERIOD;
+	private static final int 	HARVEST_BLOOM_SE_RESET_MILLIS	= 1*60*1000;
+	private static final int 	HARVEST_BLOOM_SE_RESET_TICKS	= HARVEST_BLOOM_SE_RESET_MILLIS/TIMER_PERIOD;
+
+	private ByteArrayHashMap<ForeignBloom>		harvested_blooms 	= new ByteArrayHashMap<ForeignBloom>();
+	private ByteArrayHashMap<String>			harvested_fails 	= new ByteArrayHashMap<String>();
+	
+	private volatile BloomFilter harvest_op_requester_bloom = BloomFilterFactory.createAddOnly( 2048 );
+	private volatile BloomFilter harvest_se_requester_bloom = BloomFilterFactory.createAddRemove4Bit( 512 );
+			
+			
+	private boolean	persist;
+	
+	{
+		COConfigurationManager.addAndFireParameterListener(
+			"rcm.persist",
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameterName )
+				{
+					persist = COConfigurationManager.getBooleanParameter( "rcm.persist" ) || true;
+				}
+			});
+		
+			// remove one day
+		
+		COConfigurationManager.removeParameter( "rcm.dlinfo.history" );
+	}
+	
 	protected
 	RelatedContentManager()
 	
 		throws ContentException
 	{
-		if ( !FeatureAvailability.isRCMEnabled()){
+		COConfigurationManager.addAndFireParameterListeners(
+				new String[]{
+					"rcm.ui.enabled",
+					"rcm.max_search_level",
+					"rcm.max_results",
+				},
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						String name )
+					{
+						max_search_level 	= COConfigurationManager.getIntParameter( "rcm.max_search_level", 3 );
+						max_results		 	= COConfigurationManager.getIntParameter( "rcm.max_results", 500 );
+					}
+				});
+		
+		if ( !FeatureAvailability.isRCMEnabled() || 
+			 !COConfigurationManager.getBooleanParameter( "rcm.overall.enabled", true )){
 			
 			enabled		= false;
-			ui_enabled 	= false;
 			
+			deleteRelatedContent();
+			
+			initialisation_complete_sem.releaseForever();
+
 			return;
 		}
 		
@@ -243,270 +326,174 @@ RelatedContentManager
 			
 			ta_networks 	= plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_NETWORKS );
 			
-			COConfigurationManager.addAndFireParameterListeners(
-				new String[]{
-					"rcm.ui.enabled",
-					"rcm.max_search_level",
-					"rcm.max_results",
-				},
-				new ParameterListener()
+			plugin_interface.getUtilities().createDelayedTask(new AERunnable() {
+				public void runSupport() {
+					SimpleTimer.addEvent(
+							"rcm.delay.init",
+							SystemTime.getOffsetTime( 15*1000 ),
+							new TimerEventPerformer()
+							{
+								public void 
+								perform(
+									TimerEvent event )
+								{
+									delayedInit();
+								}
+							});
+				}
+			}).queue();
+			
+		}catch( Throwable e ){
+			
+			initialisation_complete_sem.releaseForever();
+			
+			if ( e instanceof ContentException ){
+				
+				throw((ContentException)e);
+			}
+			
+			throw( new ContentException( "Initialisation failed", e ));
+		}
+	}
+	
+	private void delayedInit() {
+		
+		plugin_interface.addListener(
+			new PluginListener()
+			{
+				public void
+				initializationComplete()
 				{
-					public void 
-					parameterChanged(
-						String name )
-					{
-						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 ( !persist ){
+						
+						deleteRelatedContent();
 					}
-				});
+					
+					try{
+						PluginInterface dht_pi = 
+							plugin_interface.getPluginManager().getPluginInterfaceByClass(
+										DHTPlugin.class );
 			
-			if ( enabled ){
+						if ( dht_pi != null ){
 				
-				if ( ui_enabled ){
+							dht_plugin = (DHTPlugin)dht_pi.getPlugin();
 
-					try{
-						plugin_interface.getUtilities().registerSearchProvider(
-							new SearchProvider()
-							{
-								private Map<Integer,Object>	properties = new HashMap<Integer, Object>();
+							if ( !dht_plugin.isEnabled()){
 								
+								return;
+							}
+							
+							DownloadManager dm = plugin_interface.getDownloadManager();
+							
+							Download[] downloads = dm.getDownloads();
+							
+							addDownloads( downloads, true );
+							
+							dm.addListener(
+								new DownloadManagerListener()
 								{
-									properties.put( PR_NAME, MessageText.getString( "rcm.search.provider" ));
+									public void
+									downloadAdded(
+										Download	download )
+									{
+										addDownloads( new Download[]{ download }, false );
+									}
 									
-									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 void
+									downloadRemoved(
+										Download	download )
+									{
 									}
-								}
-								
-								public SearchInstance
-								search(
-									Map<String,Object>	search_parameters,
-									SearchObserver		observer )
-								
-									throws SearchException
+								},
+								false );
+							
+							SimpleTimer.addPeriodicEvent(
+								"RCM:publisher",
+								TIMER_PERIOD,
+								new TimerEventPerformer()
 								{
-									initialisation_complete_sem.reserve();
+									private int	tick_count;
 									
-									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 ),
-				new TimerEventPerformer()
-				{
-					public void 
-					perform(
-						TimerEvent event )
-					{						
-						plugin_interface.addListener(
-							new PluginListener()
-							{
-								public void
-								initializationComplete()
-								{
-									try{
-										PluginInterface dht_pi = 
-											plugin_interface.getPluginManager().getPluginInterfaceByClass(
-														DHTPlugin.class );
-							
-										if ( dht_pi != null ){
-								
-											dht_plugin = (DHTPlugin)dht_pi.getPlugin();
-		
-											DownloadManager dm = plugin_interface.getDownloadManager();
-											
-											Download[] downloads = dm.getDownloads();
+									public void 
+									perform(
+										TimerEvent event ) 
+									{
+										tick_count++;
+
+										if ( tick_count == 1 ){
 											
-											addDownloads( downloads, true );
+											try{
+												ddb = plugin_interface.getDistributedDatabase();
 											
-											dm.addListener(
-												new DownloadManagerListener()
-												{
-													public void
-													downloadAdded(
-														Download	download )
-													{
-														addDownloads( new Download[]{ download }, false );
-													}
-													
-													public void
-													downloadRemoved(
-														Download	download )
-													{
-													}
-												},
-												false );
-											
-											SimpleTimer.addPeriodicEvent(
-												"RCM:publisher",
-												TIMER_PERIOD,
-												new TimerEventPerformer()
-												{
-													private int	tick_count;
-													
-													public void 
-													perform(
-														TimerEvent event ) 
-													{
-														tick_count++;
+												ddb.addTransferHandler( transfer_type, RelatedContentManager.this );
+												
+											}catch( Throwable e ){
+												
+												// Debug.out( e );
+											}
+										}
+										
+										if ( enabled ){
+												
+											if ( tick_count >= INITIAL_PUBLISH_TICKS ){
+												
+												if ( tick_count % ( dht_plugin.isSleeping()?PUBLISH_SLEEPING_CHECK_TICKS:PUBLISH_CHECK_TICKS) == 0 ){
+												
+													publish();
+												}
+												
+												if ( tick_count % SECONDARY_LOOKUP_TICKS == 0 ){
 
-														if ( tick_count == 1 ){
-															
-															try{
-																ddb = plugin_interface.getDistributedDatabase();
-															
-																ddb.addTransferHandler( transfer_type, RelatedContentManager.this );
-																
-															}catch( Throwable e ){
-																
-																Debug.out( e );
-															}
-														}
-														
-														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{
+													secondaryLookup();
+												}
+												
+												if ( tick_count % REPUBLISH_TICKS == 0 ){
+
+													republish();
+												}
+												
+												if ( tick_count % CONFIG_SAVE_CHECK_TICKS == 0 ){
+													
+													saveRelatedContent( tick_count );
+												}
+											}
+												
+											harvestBlooms();
 											
-										initialisation_complete_sem.releaseForever();
+											if ( tick_count % HARVEST_BLOOM_SE_RESET_TICKS == 0 ){
+												
+												harvest_se_requester_bloom = harvest_se_requester_bloom.getReplica();
+											}
+											
+											if ( tick_count % HARVEST_BLOOM_OP_RESET_TICKS == 0 ){
+												
+												harvest_op_requester_bloom = harvest_op_requester_bloom.getReplica();
+											}									
+										}
+										
+										checkKeyBloom();
+										
+										testKeyBloom();
 									}
-								}
-								
-								public void
-								closedownInitiated()
-								{
-									saveRelatedContent();
-								}
-								
-								public void
-								closedownComplete()
-								{
-								}
-							});
+								});
+						}										
+					}finally{
+							
+						initialisation_complete_sem.releaseForever();
 					}
-				});
-			
-		}catch( Throwable e ){
-			
-			initialisation_complete_sem.releaseForever();
-			
-			if ( e instanceof ContentException ){
+				}
 				
-				throw((ContentException)e);
-			}
-			
-			throw( new ContentException( "Initialisation failed", e ));
-		}
+				public void
+				closedownInitiated()
+				{
+					saveRelatedContent( 0 );
+				}
+				
+				public void
+				closedownComplete()
+				{
+				}
+			});
 	}
 	
 	public boolean
@@ -514,20 +501,7 @@ RelatedContentManager
 	{
 		return( enabled );
 	}
-	
-	public boolean
-	isUIEnabled()
-	{
-		return( ui_enabled );
-	}
-	
-	public void
-	setUIEnabled(
-		boolean		_ui_enabled )
-	{
-		COConfigurationManager.setParameter( "rcm.ui.enabled", _ui_enabled );
-	}
-	
+		
 	public int
 	getMaxSearchLevel()
 	{
@@ -675,7 +649,7 @@ RelatedContentManager
 				}
 			}
 			
-			List<Map<String,Object>> history = (List<Map<String,Object>>)COConfigurationManager.getListParameter( "rcm.dlinfo.history", new ArrayList<Map<String,Object>>());
+			List<Map<String,Object>> history = (List<Map<String,Object>>)COConfigurationManager.getListParameter( "rcm.dlinfo.history.privx", new ArrayList<Map<String,Object>>());
 			
 			if ( initialising ){
 		
@@ -711,8 +685,17 @@ RelatedContentManager
 				
 				if ( new_info.size() > 0 ){
 					
+					final List<String>	base32_hashes = new ArrayList<String>();
+					
 					for ( DownloadInfo info: new_info ){
 						
+						byte[] hash = info.getHash();
+						
+						if ( hash != null ){
+							
+							base32_hashes.add( Base32.encode( hash ));
+						}
+						
 						Map<String,Object> map = serialiseDI( info, null );
 							
 						if ( map != null ){
@@ -726,12 +709,45 @@ RelatedContentManager
 						history.remove(0);
 					}
 					
-					COConfigurationManager.setParameter( "rcm.dlinfo.history", history );
-				}
-			}
-		}
-	}
-	
+					COConfigurationManager.setParameter( "rcm.dlinfo.history.privx", history );
+					
+					if ( base32_hashes.size() > 0 ){
+						
+						content_change_dispatcher.dispatch(
+							new AERunnable()
+							{
+								public void
+								runSupport()
+								{
+									List<RelatedContent>	to_remove = new ArrayList<RelatedContent>();
+									
+									synchronized( RelatedContentManager.this ){
+										
+										ContentCache content_cache = loadRelatedContent();
+										
+										for ( String h: base32_hashes ){
+										
+											DownloadInfo di = content_cache.related_content.get( h );
+											
+											if ( di != null ){
+												
+												to_remove.add( di );
+											}
+										}
+									}
+									
+									if ( to_remove.size() > 0 ){
+										
+										delete( to_remove.toArray( new RelatedContent[ to_remove.size()] ));
+									}
+								}
+							});
+					}
+				}
+			}
+		}
+	}
+	
 	protected void
 	republish()
 	{
@@ -796,7 +812,7 @@ RelatedContentManager
 					
 					if ( info2 == null || info1 == info2 ){
 						
-						Debug.out( "Inconsistent!" );
+						// Debug.out( "Inconsistent!" );
 						
 						return;
 					}
@@ -936,7 +952,7 @@ RelatedContentManager
 				
 		dht_plugin.get(
 				key_bytes,
-				"Content relationship read: " + from_hash,
+				"Content relationship test: " + from_hash,
 				DHTPlugin.FLAG_SINGLE_VALUE,
 				max_hits,
 				30*1000,
@@ -955,10 +971,12 @@ RelatedContentManager
 					{
 					}
 					
-					public void
+					public boolean
 					diversified()
 					{
 						diversified = true;
+						
+						return( false );
 					}
 					
 					public void
@@ -967,71 +985,14 @@ RelatedContentManager
 						DHTPluginValue		value )
 					{
 						try{
-							Map<String,Object> map = (Map<String,Object>)BDecoder.decode( value.getValue());
-							
-							String	title = new String((byte[])map.get( "d" ), "UTF-8" );
-							
-							String	tracker	= null;
-							
-							byte[]	hash 	= (byte[])map.get( "h" );
-							
-							if ( hash == null ){
+							Map<String,Object> map = (Map<String,Object>)BDecoder.decode( value.getValue());							
 								
-								tracker = new String((byte[])map.get( "t" ), "UTF-8" );
-							}
-							
-							int	rand = ((Long)map.get( "r" )).intValue();
-							
-							String	key = title + " % " + rand;
-							
-							synchronized( entries ){
-							
-								if ( entries.contains( key )){
-									
-									return;
-								}
-								
-								entries.add( key );
-							}
-							
-							Long	l_size = (Long)map.get( "s" );
-							
-							long	size = l_size==null?0:l_size.longValue();
+							DownloadInfo info = decodeInfo( map, from_info.getHash(), 1, false, entries );
 							
-							Long	cnet	 	= (Long)map.get( "c" );
-							Long	published 	= (Long)map.get( "p" );
-							Long	leechers 	= (Long)map.get( "l" );
-							Long	seeds	 	= (Long)map.get( "z" );
+							if ( info != null ){
 							
-							// 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( info, null );
 							}
-								
-							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 ){							
 						}
 						
@@ -1078,9 +1039,10 @@ RelatedContentManager
 										DHTPlugin.FLAG_ANON,
 										new DHTPluginOperationListener()
 										{
-											public void
+											public boolean
 											diversified()
 											{
+												return( true );
 											}
 											
 											public void 
@@ -1124,7 +1086,84 @@ RelatedContentManager
 					}
 				});
 	}
+		
+	private DownloadInfo
+	decodeInfo(
+		Map				map,
+		byte[]			from_hash,
+		int				level,
+		boolean			explicit,
+		Set<String>		unique_keys )
+	{
+		try{
+			String	title = new String((byte[])map.get( "d" ), "UTF-8" );
+			
+			String	tracker	= null;
+			
+			byte[]	hash 	= (byte[])map.get( "h" );
+			
+			if ( hash == null ){
+				
+				tracker = new String((byte[])map.get( "t" ), "UTF-8" );
+			}
+			
+			int	rand = ((Long)map.get( "r" )).intValue();
+			
+			String	key = title + " % " + rand;
+			
+			synchronized( unique_keys ){
+			
+				if ( unique_keys.contains( key )){
+					
+					return( null );
+				}
+				
+				unique_keys.add( key );
+			}
+			
+			Long	l_size = (Long)map.get( "s" );
+			
+			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" );
+			
+			// 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);
+			}
+				
+			return(
+				new DownloadInfo( 
+						from_hash, hash, title, rand, tracker, level, explicit, size, 
+						published==null?0:published.intValue(),
+						seeds_leechers,
+						(byte)(cnet==null?ContentNetwork.CONTENT_NETWORK_UNKNOWN:cnet.byteValue()))); 
+			
+		}catch( Throwable e ){
 			
+			return( null );
+		}
+	}
+	
 	public void
 	lookupContent(
 		final byte[]						hash,
@@ -1174,6 +1213,11 @@ RelatedContentManager
 	
 		throws ContentException
 	{
+		if ( !enabled ){
+		
+			throw( new ContentException( "rcm is disabled" ));
+		}
+		
 		try{
 			if ( dht_plugin == null ){
 				
@@ -1270,9 +1314,10 @@ RelatedContentManager
 							}
 						}
 						
-						public void
+						public boolean
 						diversified()
 						{
+							return( true );
 						}
 						
 						public void
@@ -1283,67 +1328,13 @@ RelatedContentManager
 							try{
 								Map<String,Object> map = (Map<String,Object>)BDecoder.decode( value.getValue());
 								
-								String	title = new String((byte[])map.get( "d" ), "UTF-8" );
-								
-								String	tracker	= null;
-								
-								byte[]	hash 	= (byte[])map.get( "h" );
-								
-								if ( hash == null ){
-									
-									tracker = new String((byte[])map.get( "t" ), "UTF-8" );
-								}
-								
-								int	rand = ((Long)map.get( "r" )).intValue();
-								
-								String	key = title + " % " + rand;
-								
-								synchronized( entries ){
-								
-									if ( entries.contains( key )){
-										
-										return;
-									}
-									
-									entries.add( key );
-								}
-								
-								Long	l_size = (Long)map.get( "s" );
-								
-								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;
+								DownloadInfo info = decodeInfo( map, from_hash, level+1, explicit, entries );
 								
-								if ( leechers == null && seeds == null ){
-									
-									seeds_leechers = -1;
-									
-								}else if ( leechers == null ){
-									
-									seeds_leechers = seeds.intValue()<<16;
+								if ( info != null ){
 									
-								}else if ( seeds == null ){
-									
-									seeds_leechers = leechers.intValue()&0xffff;
-									
-								}else{
-									
-									seeds_leechers = (seeds.intValue()<<16)|(leechers.intValue()&0xffff);
+									analyseResponse( info, listener==null?null:manager_listener );
 								}
-								analyseResponse( 
-									new DownloadInfo( 
-										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 ){							
+							}catch( Throwable e ){	
 							}
 						}
 						
@@ -1878,8 +1869,11 @@ RelatedContentManager
 						}
 						
 						new_content = true;
+						
+					}else{
+						
+						transient_info_cache.put( key, to_info );
 					}
-					
 				}else{
 					
 						// we already know about this, see if new info
@@ -1966,13 +1960,14 @@ RelatedContentManager
 		
 		Iterator<Map.Entry<String,DownloadInfo>>	it = related_content.entrySet().iterator();
 				
-		int	level 		= fi.getLevel();
+		int	max_level 		= fi.getLevel();
 		
 			// delete oldest at highest level >= level with minimum rank
 	
 		Map<Integer,DownloadInfo>	oldest_per_rank = new HashMap<Integer, DownloadInfo>();
 		
-		int	min_rank = Integer.MAX_VALUE;
+		int	min_rank 	= Integer.MAX_VALUE;
+		int	max_rank	= -1;
 		
 		while( it.hasNext()){
 			
@@ -1987,13 +1982,14 @@ RelatedContentManager
 			
 			int	info_level = info.getLevel();
 			
-			if ( info_level >= level ){
+			if ( info_level >= max_level ){
 				
-				if ( info_level > level ){
+				if ( info_level > max_level ){
 					
-					level = info_level;
+					max_level = info_level;
 					
-					min_rank = Integer.MAX_VALUE;
+					min_rank 	= Integer.MAX_VALUE;
+					max_rank	= -1;
 					
 					oldest_per_rank.clear();
 				}
@@ -2003,6 +1999,10 @@ RelatedContentManager
 				if ( rank < min_rank ){
 					
 					min_rank = rank;
+					
+				}else if ( rank > max_rank ){
+					
+					max_rank = rank;
 				}
 				
 				DownloadInfo oldest = oldest_per_rank.get( rank );
@@ -2030,6 +2030,27 @@ RelatedContentManager
 			return( true );
 		}
 		
+			// we don't want high-ranked entries to get stuck there and prevent newer stuff from getting in and rising up
+		
+		if ( max_level == 1 ){
+			
+			to_remove = oldest_per_rank.get( max_rank );
+			
+			if ( to_remove != null ){
+				
+				int	now_secs = (int)( SystemTime.getCurrentTime()/1000 );
+				
+					// give it a day at the top
+				
+				if ( now_secs - to_remove.getLastSeenSecs() >= 24*60*60 ){
+					
+					delete( new RelatedContent[]{ to_remove }, content_cache, false );
+					
+					return( true );
+				}
+			}
+		}
+		
 		return( false );
 	}
 	
@@ -2044,6 +2065,17 @@ RelatedContentManager
 		}
 	}
 	
+	private List<DownloadInfo>
+  	getRelatedContentAsList()
+  	{
+  		synchronized( this ){
+
+  			ContentCache	content_cache = loadRelatedContent();
+  			
+  			return( new ArrayList<DownloadInfo>( content_cache.related_content.values()));
+  		}
+  	}
+	
 	public void
 	reset()
 	{
@@ -2110,12 +2142,8 @@ RelatedContentManager
 			// 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( " " );
+				
+		String[]	 bits = Constants.PAT_SPLIT_SPACE.split(term.toLowerCase());
 
 		int[]		bit_types 		= new int[bits.length];
 		Pattern[]	bit_patterns 	= new Pattern[bits.length];
@@ -2146,93 +2174,148 @@ RelatedContentManager
 					bit = bit.substring( 1, bit.length()-1 );
 					
 					try{
-						bit_patterns[i] = Pattern.compile( bit, Pattern.CASE_INSENSITIVE );
+						if ( !RegExUtil.mightBeEvil( bit )){
 						
+							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 );
+						if ( !RegExUtil.mightBeEvil( bit )){
 						
+							bit_patterns[i] = Pattern.compile( bit, Pattern.CASE_INSENSITIVE );
+						}
 					}catch( Throwable e ){
 					}
 				}
 			}
 		}
-			
 		
-		for ( final RelatedContent c: content ){
-			
-			String title = c.getTitle().toLowerCase();
+		Map<String,RelatedContent>	result = new HashMap<String,RelatedContent>();
+		
+		Iterator<DownloadInfo>	it1 = getDHTInfos().iterator();
+		
+		Iterator<DownloadInfo>	it2;
+		
+		synchronized( this ){
+		
+			it2 = new ArrayList<DownloadInfo>( transient_info_cache.values()).iterator();
+		}
+
+		Iterator<DownloadInfo>	it3 = getRelatedContentAsList().iterator();
+
+		for ( Iterator _it: new Iterator[]{ it1, it2, it3 }){
 			
-			boolean	match 			= true;
-			boolean	at_least_one 	= false;
+			Iterator<DownloadInfo> it = (Iterator<DownloadInfo>)_it;	
 			
-			for (int i=0;i<bits.length;i++){
+			while( it.hasNext()){
 				
-				String bit = bits[i];
+				DownloadInfo c = it.next();
 				
-				if ( bit.length() > 0 ){
-					
-					boolean	hit;
-					
-					if ( bit_patterns[i] == null ){
+				String title 	= c.getTitle();
+				String lc_title = c.getTitle().toLowerCase();
+				
+				boolean	match 			= true;
+				boolean	at_least_one 	= false;
+				
+				if ( title.equalsIgnoreCase( term ) && term.trim().length() > 0 ){
 					
-						hit = title.contains( bit );
-						
-					}else{
+						// pick up a direct match regardless of anything else
 					
-						hit = bit_patterns[i].matcher( title ).find();
-					}
+					at_least_one = true;
 					
-					int	type = bit_types[i];
+				}else{
 					
-					if ( hit ){
-												
-						if ( type == 2 ){
+					for (int i=0;i<bits.length;i++){
+						
+						String bit = bits[i];
+						
+						if ( bit.length() > 0 ){
 							
-							match = false;
+							boolean	hit;
 							
-							break;
+							if ( bit_patterns[i] == null ){
 							
-						}else{
+								hit = lc_title.contains( bit );
+								
+							}else{
 							
-							at_least_one = true;
-
-						}
-					}else{
-						
-						if ( type == 2 ){
-						
-							at_least_one = true;
+								hit = bit_patterns[i].matcher( lc_title ).find();
+							}
 							
-						}else{
+							int	type = bit_types[i];
 							
-							match = false;
-						
-							break;
+							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 );
+				if ( match && at_least_one ){
+					
+					byte[]	hash = c.getHash();
+					
+					String key;
+					
+					if ( hash != null ){
+						
+						key = Base32.encode( hash );
+						
+					}else{
+			
+						key = getPrivateInfoKey( c );
+					}
+					
+					result.put( key, c );
+				}
 			}
 		}
 		
-		return( result );
+		return( new ArrayList<RelatedContent>( result.values()));
 	}
 	
-	protected SearchInstance
+	public SearchInstance
 	searchRCM(
 		Map<String,Object>		search_parameters,
-		final SearchObserver	observer )
+		SearchObserver			_observer )
 	
 		throws SearchException
 	{
+		initialisation_complete_sem.reserve();
+
+		if ( !enabled ){
+			
+			throw( new SearchException( "rcm is disabled" ));
+		}
+		
+		final MySearchObserver observer = new MySearchObserver( _observer );
+		
 		final String	term = (String)search_parameters.get( SearchProvider.SP_SEARCH_TERM );
 		
 		final SearchInstance si = 
@@ -2345,64 +2428,146 @@ RelatedContentManager
 						}
 					}finally{
 						
-						try{
-							DHT[]	dhts = dht_plugin.getDHTs();
-	
-							Set<InetSocketAddress>	addresses = new HashSet<InetSocketAddress>();
+						try{	
+							final List<DistributedDatabaseContact> 	initial_hinted_contacts = searchForeignBlooms( term );
+							final Set<DistributedDatabaseContact>	extra_hinted_contacts	= new HashSet<DistributedDatabaseContact>();
+							
+							Collections.shuffle( initial_hinted_contacts );
+							
+							// test injection of local 
+							// hinted_contacts.add( 0, ddb.getLocalContact());
+							
+							final LinkedList<DistributedDatabaseContact>	contacts_to_search = new LinkedList<DistributedDatabaseContact>();
+
+							final Map<InetSocketAddress,DistributedDatabaseContact> contact_map = new HashMap<InetSocketAddress, DistributedDatabaseContact>();
+														
+							for ( DistributedDatabaseContact c: initial_hinted_contacts ){
+								
+									// stick in map so non-hinted get removed below, but interleave later
+								
+								contact_map.put( c.getAddress(), c );
+							}
 							
+							DHT[]	dhts = dht_plugin.getDHTs();
+								
 							for ( DHT dht: dhts ){
 							
+								DHTTransport transport = dht.getTransport();
+								
+								if ( transport.isIPV6()){
+									
+									continue;
+								}
+								
+								int	network = transport.getNetwork();
+								
+								if ( SEARCH_CVS_ONLY && network != DHT.NW_CVS ){
+									
+									logSearch( "Search: ignoring main DHT" );
+
+									continue;
+								}
+								
 								DHTTransportContact[] contacts = dht.getTransport().getReachableContacts();
 								
-								for ( DHTTransportContact c: contacts ){
+								Collections.shuffle( Arrays.asList( contacts ));
+																
+								for ( DHTTransportContact dc: contacts ){
+											
+									InetSocketAddress address = dc.getAddress();
 									
-									if ( c.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
+									if ( !contact_map.containsKey( address )){
 										
-										addresses.add( c.getAddress());
+										try{
+											DistributedDatabaseContact c = 
+												ddb.importContact( 
+													address, 
+													DHTTransportUDP.PROTOCOL_VERSION_MIN, 
+													network==DHT.NW_CVS?DistributedDatabase.DHT_CVS:DistributedDatabase.DHT_MAIN );
+											
+											contact_map.put( address, c );
+											
+											contacts_to_search.add( c );
+											
+										}catch( Throwable e ){
+											
+										}
 									}
 								}
 							}
 							
-							if ( addresses.size() < MAX_REMOTE_SEARCH_CONTACTS ){
+							if ( contact_map.size() < MAX_REMOTE_SEARCH_CONTACTS ){
+								
+									// back fill with less reliable contacts if required
 								
 								for ( DHT dht: dhts ){
 									
+									DHTTransport transport = dht.getTransport();
+									
+									if ( transport.isIPV6()){
+										
+										continue;
+									}
+									
+									int	network = transport.getNetwork();
+									
+									if ( SEARCH_CVS_ONLY && network != DHT.NW_CVS ){
+										
+										logSearch( "Search: ignoring main DHT" );
+
+										continue;
+									}
+									
 									DHTTransportContact[] contacts = dht.getTransport().getRecentContacts();
 	
-									for ( DHTTransportContact c: contacts ){
+									for ( DHTTransportContact dc: contacts ){
 										
-										if ( c.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ){
-											
-											addresses.add( c.getAddress());
+										InetSocketAddress address = dc.getAddress();
+										
+										if ( !contact_map.containsKey( address )){
 											
-											if ( addresses.size() >= MAX_REMOTE_SEARCH_CONTACTS ){
+											try{
+												DistributedDatabaseContact c = ddb.importContact( address, DHTTransportUDP.PROTOCOL_VERSION_MIN, network==DHT.NW_CVS?DistributedDatabase.DHT_CVS:DistributedDatabase.DHT_MAIN );
+												
+												contact_map.put( address, c );
+												
+												contacts_to_search.add( c );
+																				
+												if ( contact_map.size() >= MAX_REMOTE_SEARCH_CONTACTS ){
+													
+													break;
+												}
+											}catch( Throwable e ){
 												
-												break;
 											}
 										}
 									}
 									
-									if ( addresses.size() >= MAX_REMOTE_SEARCH_CONTACTS ){
+									if ( contact_map.size() >= MAX_REMOTE_SEARCH_CONTACTS ){
 										
 										break;
 									}
 								}
 							}
 							
-							List<InetSocketAddress>	list = new ArrayList<InetSocketAddress>( addresses );
+								// interleave hinted ones so we get some variety
 							
-							Collections.shuffle( list );
+							int	desired_pos = 0;
 							
-							List<DistributedDatabaseContact>	ddb_contacts = new ArrayList<DistributedDatabaseContact>();
-							
-							for (int i=0;i<Math.min( list.size(), MAX_REMOTE_SEARCH_CONTACTS );i++){
+							for ( DistributedDatabaseContact dc: initial_hinted_contacts ){
 								
-								try{				
-									ddb_contacts.add( ddb.importContact( list.get(i), DHTTransportUDP.PROTOCOL_VERSION_REPLICATION_CONTROL ));
+								if ( desired_pos < contacts_to_search.size()){
 									
-								}catch( Throwable e ){
+									contacts_to_search.add( desired_pos, dc );
+								
+									desired_pos += 2;
+									
+								}else{
+									
+									contacts_to_search.addLast( dc );
 								}
 							}
+
 							
 							long	start		= SystemTime.getMonotonousTime();
 							long	max			= MAX_REMOTE_SEARCH_MILLIS;
@@ -2413,9 +2578,42 @@ RelatedContentManager
 							
 							final int[]			done = {0};
 							
-							for (int i=0;i<ddb_contacts.size();i++){
+							logSearch( "Search starts: contacts=" + contacts_to_search.size() + ", hinted=" + initial_hinted_contacts.size());
+							
+							while( true ){
+										
+									// hard limit of total results found and overall elapsed
+								
+								if ( 	observer.getResultCount() >= 200 || 
+										SystemTime.getMonotonousTime() - start >= max ){
+									
+									logSearch( "Hard limit exceeded" );
+									
+									return;
+								}
+
+								if ( sent >= MAX_REMOTE_SEARCH_CONTACTS ){
+									
+									logSearch( "Max contacts searched" );
+									
+									break;
+								}
+
+								final DistributedDatabaseContact contact_to_search;
 								
-								final DistributedDatabaseContact c = ddb_contacts.get( i );
+								synchronized( contacts_to_search ){
+									
+									if ( contacts_to_search.isEmpty()){
+										
+										logSearch( "Contacts exhausted" );
+										
+										break;
+										
+									}else{
+										
+										contact_to_search = contacts_to_search.removeFirst();
+									}
+								}
 																
 								new AEThread2( "RCM:rems", true )
 								{
@@ -2423,8 +2621,63 @@ RelatedContentManager
 									run()
 									{
 										try{
-											sendRemoteSearch( si, hashes, c, term, observer );
-																						
+											logSearch( "Searching " + contact_to_search.getAddress());
+											
+											List<DistributedDatabaseContact> extra_contacts = sendRemoteSearch( si, hashes, contact_to_search, term, observer );
+													
+											if ( extra_contacts == null ){
+												
+												logSearch( "    " + contact_to_search.getAddress() + " failed" );
+												
+												foreignBloomFailed( contact_to_search );
+												
+											}else{
+												
+												String	type;
+												
+												if ( initial_hinted_contacts.contains( contact_to_search )){
+													type = "i";
+												}else if ( extra_hinted_contacts.contains( contact_to_search )){
+													type = "e";
+												}else{
+													type = "n";
+												}
+												logSearch( "    " + contact_to_search.getAddress() + " OK " + type + " - additional=" + extra_contacts.size());
+												
+													// insert results from more predictable nodes after the less predictable ones
+												
+												synchronized( contacts_to_search ){
+													
+													int	insert_point = 0;
+													
+													if ( type.equals( "i" )){
+														
+														for (int i=0;i<contacts_to_search.size();i++){
+															
+															if ( extra_hinted_contacts.contains(contacts_to_search.get(i))){
+																
+																insert_point = i+1;
+															}
+														}
+													}
+													
+													for ( DistributedDatabaseContact c: extra_contacts ){
+														
+														InetSocketAddress address = c.getAddress();
+						
+														if ( !contact_map.containsKey( address )){
+															
+															logSearch( "        additional target: " + address );
+															
+															extra_hinted_contacts.add( c );
+															
+															contact_map.put( address, c );
+															
+															contacts_to_search.add( insert_point, c );
+														}
+													}
+												}
+											}
 										}finally{
 											
 											synchronized( done ){
@@ -2441,16 +2694,22 @@ RelatedContentManager
 								
 								synchronized( done ){
 									
-									if ( done[0] >= ddb_contacts.size() / 2 ){
+									if ( done[0] >= MAX_REMOTE_SEARCH_CONTACTS / 2 ){
+										
+										logSearch( "Switching to reduced time limit (1)" );
+										
+											// give another 5 secs for results to come in
 										
 										start		= SystemTime.getMonotonousTime();
-										max			= 5*1000;
+										max			= REDUCED_REMOTE_SEARCH_MILLIS;
 										
 										break;
 									}
 								}
 								
-								if ( i > 10 ){
+								if ( sent > 10 ){
+									
+										// rate limit a bit after the first 10
 									
 									try{
 										Thread.sleep( 250 );
@@ -2460,26 +2719,45 @@ RelatedContentManager
 								}
 							}
 							
-							for (int i=0;i<sent;i++){
+							logSearch( "Request dispatch complete: sent=" + sent + ", done=" + done[0] );
+							
+							for ( int i=0;i<sent;i++ ){
 								
-								if ( done[0] > sent*4/5 ){
+								if ( done[0] > sent*9/10 ){
+									
+									logSearch( "9/10ths replied (" + done[0] + "/" + sent + "), done" );
 									
 									break;
 								}
 								
-								long	elapsed = SystemTime.getMonotonousTime() - start;
+								long	remaining = ( start + max ) - SystemTime.getMonotonousTime();
+								
+								if ( 	remaining > REDUCED_REMOTE_SEARCH_MILLIS &&
+										done[0] >= MAX_REMOTE_SEARCH_CONTACTS / 2 ){
+									
+									logSearch( "Switching to reduced time limit (2)" );
+									
+										// give another 5 secs for results to come in
+									
+									start		= SystemTime.getMonotonousTime();
+									max			= REDUCED_REMOTE_SEARCH_MILLIS;
+								}
 								
-								if ( elapsed < max ){
+								if ( remaining > 0 ){
 									
-									sem.reserve( max - elapsed );
+									sem.reserve( 250 );
 									
 								}else{
 									
+									logSearch( "Time exhausted" );
+									
 									break;
 								}
 							}
 						}finally{
-															
+								
+							logSearch( "Search complete" );
+							
 							observer.complete();
 						}
 					}
@@ -2490,7 +2768,7 @@ RelatedContentManager
 		return( si );
 	}
 	
-	protected void
+	protected List<DistributedDatabaseContact>
 	sendRemoteSearch(
 		SearchInstance					si,
 		Set<String>						hashes,
@@ -2531,17 +2809,17 @@ RelatedContentManager
 					key,
 					10000 );
 			
-			// System.out.println( "search result=" + value );
+				// System.out.println( "search result=" + value );
 			
 			if ( value == null ){
 				
-				return;
+				return( null );
 			}
 			
 			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" );
@@ -2636,106 +2914,368 @@ RelatedContentManager
 					
 				observer.resultReceived( si, result );
 			}
+			
+			list = (List<Map<String,Object>>)reply.get( "c" );
+
+			List<DistributedDatabaseContact>	contacts = new ArrayList<DistributedDatabaseContact>();
+			
+			if ( list != null ){
+			
+				for ( Map<String,Object> m: list ){
+					
+					try{
+						String	host 	= ImportExportUtils.importString( m, "a" );
+						int		port	= ImportExportUtils.importInt( m, "p" );
+						
+						DistributedDatabaseContact ddb_contact = 
+							ddb.importContact( new InetSocketAddress( InetAddress.getByName(host), port ), DHTTransportUDP.PROTOCOL_VERSION_MIN, contact.getDHT());
+
+						contacts.add( ddb_contact );
+						
+					}catch( Throwable e ){
+					}
+					
+				}
+			}
+			
+			return( contacts );
+			
 		}catch( Throwable e ){
+			
+			return( null );
 		}
 	}
 	
-	protected Map<String,Object>
-	receiveRemoteSearch(
-		Map<String,Object>		request )
+	protected BloomFilter
+	sendRemoteFetch(
+		DistributedDatabaseContact		contact )
 	{
-		Map<String,Object>	response = new HashMap<String,Object>();
-		
 		try{
-			String	term = ImportExportUtils.importString( request, "t" );
+			Map<String,Object>	request = new HashMap<String,Object>();
+			
+			request.put( "x", "f" );
 		
-			if ( term != null ){
+			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,
+					5000 );
+			
+				// System.out.println( "search result=" + value );
+			
+			if ( value != null ){
+			
+				Map<String,Object> reply = (Map<String,Object>)BDecoder.decode((byte[])value.getValue( byte[].class ));
+			
+				Map<String,Object>	m = (Map<String,Object>)reply.get( "f" );
 				
-				List<RelatedContent>	matches = matchContent( term );
-
-				if ( matches.size() > MAX_REMOTE_SEARCH_RESULTS ){
+				if ( m != null ){
 					
-					Collections.sort(
-						matches,
-						new Comparator<RelatedContent>()
-						{
-							public int 
-							compare(
-								RelatedContent o1,
-								RelatedContent o2) 
-							{
-								return( o2.getRank() - o1.getRank());
-							}
-						});
+					return( BloomFilterFactory.deserialiseFromMap( m ));
 				}
+			}
+		}catch( Throwable e ){
+		}
+		
+		return( null );
+	}
+	
+	protected BloomFilter
+	sendRemoteUpdate(
+		ForeignBloom	f_bloom )
+	{
+		try{
+			Map<String,Object>	request = new HashMap<String,Object>();
+			
+			request.put( "x", "u" );
+			request.put( "s", new Long( f_bloom.getFilter().getEntryCount()));
+		
+			DistributedDatabaseKey key = ddb.createKey( BEncoder.encode( request ));
+			
+			DistributedDatabaseValue value = 
+				f_bloom.getContact().read( 
+					new DistributedDatabaseProgressListener()
+					{
+						public void
+						reportSize(
+							long	size )
+						{	
+						}
+						
+						public void
+						reportActivity(
+							String	str )
+						{	
+						}
+						
+						public void
+						reportCompleteness(
+							int		percent )
+						{
+						}
+					},
+					transfer_type,
+					key,
+					5000 );
+			
+				// System.out.println( "search result=" + value );
+			
+			if ( value != null ){
+			
+				Map<String,Object> reply = (Map<String,Object>)BDecoder.decode((byte[])value.getValue( byte[].class ));
+			
+				Map<String,Object>	m = (Map<String,Object>)reply.get( "f" );
 				
-				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>();
+				if ( m != null ){
 					
-					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());
+					logSearch( "Bloom for " + f_bloom.getContact().getAddress() + " updated" );
+
+					return( BloomFilterFactory.deserialiseFromMap( m ));
 					
-					byte[] hash = c.getHash();
+				}else{
 					
-					if ( hash != null ){
+					if ( reply.containsKey( "s" )){
 						
-						map.put( "h", hash );
+						logSearch( "Bloom for " + f_bloom.getContact().getAddress() + " same size" );
+						
+					}else{
+						
+						logSearch( "Bloom for " + f_bloom.getContact().getAddress() + " update not supported yet" );
 					}
+					
+					return( f_bloom.getFilter());
 				}
-				
-				response.put( "l", list );
 			}
 		}catch( Throwable e ){
 		}
 		
-		return( response );
+		logSearch( "Bloom for " + f_bloom.getContact().getAddress() + " update failed" );
+
+		return( null );
 	}
 	
-	public DistributedDatabaseValue
-	read(
-		DistributedDatabaseContact			contact,
-		DistributedDatabaseTransferType		type,
-		DistributedDatabaseKey				ddb_key )
-	
-		throws DistributedDatabaseException
+	protected Map<String,Object>
+	receiveRemoteRequest(
+		DistributedDatabaseContact		originator,
+		Map<String,Object>				request )
 	{
-		Object	o_key = ddb_key.getKey();
+		Map<String,Object>	response = new HashMap<String,Object>();
 		
-		try{
-			byte[]	key = (byte[])o_key;
-			
-				// TODO bloom
-			
-			Map<String,Object>	request = BDecoder.decode( key );
+		try{	
+			boolean	originator_is_neighbour = false;
 			
-			Map<String,Object>	result = receiveRemoteSearch( request );
+			DHT[] dhts = dht_plugin.getDHTs();
 			
-			return( ddb.createValue( BEncoder.encode( result )));
+			byte[] originator_id = originator.getID();
 			
-		}catch( Throwable e ){
+			byte[] originator_bytes = originator.getAddress().getAddress().getAddress();
+
+			for ( DHT d: dhts ){
+				
+				List<DHTTransportContact> contacts = d.getControl().getClosestKContactsList( d.getRouter().getID(), true );
+				
+				for ( DHTTransportContact c: contacts ){
+					
+					if ( Arrays.equals( c.getID(), originator_id)){
+						
+						originator_is_neighbour = true;
+						
+						break;
+					}
+				}
+				
+				if ( originator_is_neighbour ){
+					
+					break;
+				}
+			}
 			
-			Debug.out( e );
+			String	req_type = ImportExportUtils.importString( request, "x" );
 			
-			return( null );
-		}
-	}
+			if ( req_type != null ){
+							
+				boolean dup = harvest_op_requester_bloom.contains( originator_bytes );
+					
+				logSearch( "Received remote request: " + BDecoder.decodeStrings( request ) + " from " + originator.getAddress() + "/" + originator.getDHT() + ", dup=" + dup + ", bs=" + harvest_op_requester_bloom.getEntryCount());
+				
+				if ( !dup ){
+					
+					harvest_op_requester_bloom.add( originator_bytes );
+					
+					if ( req_type.equals( "f" )){
+						
+						BloomFilter filter = getKeyBloom( !originator_is_neighbour );
+						
+						if ( filter != null ){
+							
+							response.put( "f", filter.serialiseToMap());
+						}
+					}else if ( req_type.equals( "u" )){
+						
+						BloomFilter filter = getKeyBloom( !originator_is_neighbour );
+						
+						if ( filter != null ){
 	
-	public void
-	write(
-		DistributedDatabaseContact			contact,
+							int	existing_size = ImportExportUtils.importInt( request, "s", 0 );
+						
+							if ( existing_size != filter.getEntryCount()){
+								
+								response.put( "f", filter.serialiseToMap());
+								
+							}else{
+								
+								response.put( "s", new Long( existing_size ));
+							}
+						}
+					}
+				}
+			}else{
+					// fallback to default handling
+
+				int hits = harvest_se_requester_bloom.count( originator_bytes );
+				
+				String	term = ImportExportUtils.importString( request, "t" );
+
+				logSearch( "Received remote search: '" + term + "' from " + originator.getAddress() + ", hits=" + hits + ", bs=" + harvest_se_requester_bloom.getEntryCount());
+
+				if ( hits < 10 ){
+					
+					harvest_se_requester_bloom.add( originator_bytes );
+					
+					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 );
+							}
+							
+								// don't bother with tracker as no use to caller really
+						}
+						
+						response.put( "l", list );
+					}
+					
+					List<DistributedDatabaseContact> bloom_hits = searchForeignBlooms( term );
+					
+					if ( bloom_hits.size() > 0 ){
+						
+						List<Map>	list = new ArrayList<Map>();
+						
+						for ( DistributedDatabaseContact c: bloom_hits ){
+							
+							Map	m = new HashMap();
+							
+							list.add( m );
+							
+							InetSocketAddress address = c.getAddress();
+							
+							m.put( "a", address.getAddress().getHostAddress());
+							m.put( "p", new Long( address.getPort()));
+						}
+						
+						response.put( "c", 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 = receiveRemoteRequest( contact, 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 )
@@ -2787,9 +3327,25 @@ RelatedContentManager
 							Map<String,DownloadInfo>						related_content			= cc.related_content;
 							ByteArrayHashMapEx<ArrayList<DownloadInfo>>		related_content_map		= cc.related_content_map;
 		
+							Map<String,String>	rcm_map;
 							
-							Map<String,String>	rcm_map = (Map<String,String>)map.get( "rcm" );
+							byte[]	data = (byte[])map.get( "d" );
+							
+							if ( data != null ){
+										
+								try{
+									map = BDecoder.decode(new BufferedInputStream( new GZIPInputStream( new ByteArrayInputStream( CryptoManagerFactory.getSingleton().deobfuscate( data )))));
+									
+								}catch( Throwable e ){
+									
+										// can get here is config's been deleted
+									
+									map = new HashMap();
+								}
+							}
 							
+							rcm_map = (Map<String,String>)map.get( "rcm" );
+						
 							Object	rc_map_stuff 	= map.get( "rc" );
 							
 							if ( rc_map_stuff != null && rcm_map != null ){
@@ -2869,7 +3425,7 @@ RelatedContentManager
 											
 											if ( ids == null || ids.length == 0 ){
 												
-												Debug.out( "Inconsistent - no ids" );
+												// Debug.out( "Inconsistent - no ids" );
 												
 											}else{
 												
@@ -2881,7 +3437,7 @@ RelatedContentManager
 													
 													if ( di == null ){
 														
-														Debug.out( "Inconsistent: id " + id + " missing" );
+														// Debug.out( "Inconsistent: id " + id + " missing" );
 														
 													}else{
 														
@@ -2913,7 +3469,7 @@ RelatedContentManager
 									
 									if ( di.getRelatedToHash() == null ){
 								
-										Debug.out( "Inconsistent: info not referenced" );
+										// Debug.out( "Inconsistent: info not referenced" );
 										
 										if ( di.isUnread()){
 											
@@ -2930,7 +3486,7 @@ RelatedContentManager
 						
 						if ( total_unread.get() != new_total_unread ){
 														
-							Debug.out( "total_unread - inconsistent (" + total_unread + "/" + new_total_unread + ")" );
+							// Debug.out( "total_unread - inconsistent (" + total_unread + "/" + new_total_unread + ")" );
 							
 							total_unread.set( new_total_unread );
 							
@@ -2942,240 +3498,979 @@ RelatedContentManager
 					}
 					
 					enforceMaxResults( cc, false );
-
+				}
+				
+				content_cache_ref = cc;
+					
+				return( cc );
+			}
+		}finally{
+			
+			if ( fire_event ){
+				
+				contentChanged( false );
+			}
+		}
+	}
+	
+	protected void
+	saveRelatedContent(
+		int	tick_count )
+	{
+		synchronized( this ){
+				
+			COConfigurationManager.setParameter( CONFIG_TOTAL_UNREAD, total_unread.get());
+			
+			long	now = SystemTime.getMonotonousTime();;
+			
+			ContentCache cc = content_cache==null?null:content_cache.get();
+			
+			if ( !content_dirty ){
+					
+				if ( cc != null  ){
+					
+					if ( now - last_config_access > CONFIG_DISCARD_MILLIS ){
+					
+						if ( content_cache_ref != null ){
+							
+							content_discard_ticks = 0;
+						}
+						
+						if ( TRACE ){
+							System.out.println( "rcm: discard: tick count=" + content_discard_ticks++ );
+						}
+						
+						content_cache_ref	= null;
+					}
 				}else{
 					
 					if ( TRACE ){
-						System.out.println( "rcm: load existing" );
+						System.out.println( "rcm: discarded" );
 					}
 				}
 				
-				content_cache_ref = cc;
+				return;
+			}
+			
+			if ( tick_count % CONFIG_SAVE_TICKS != 0 ){
+				
+				return;
+			}
+			
+			last_config_access = now;
+			
+			content_dirty	= false;
+			
+			if ( cc == null ){
+				
+				// Debug.out( "RCM: cache inconsistent" );
+				
+			}else{
+				
+				if ( persist ){
+					
+					if ( TRACE ){
+						System.out.println( "rcm: save" );
+					}
+					
+					Map<String,DownloadInfo>						related_content			= cc.related_content;
+					ByteArrayHashMapEx<ArrayList<DownloadInfo>>		related_content_map		= cc.related_content_map;
+	
+					if ( related_content.size() == 0 ){
+						
+						FileUtil.deleteResilientConfigFile( CONFIG_FILE );
+						
+					}else{
+						
+						Map<String,Object>	map = new HashMap<String, Object>();
+						
+						Set<Map.Entry<String,DownloadInfo>> rcs = related_content.entrySet();
+											
+						List<Map<String,Object>> rc_map_list = new ArrayList<Map<String, Object>>( rcs.size());
+						
+						map.put( "rc", rc_map_list );
+						
+						int		id = 0;
+						
+						Map<DownloadInfo,Integer>	info_map = new HashMap<DownloadInfo, Integer>();
+						
+						for ( Map.Entry<String,DownloadInfo> entry: rcs ){
+												
+							DownloadInfo	info = entry.getValue();
+													
+							Map<String,Object> di_map = serialiseDI( info, cc );
+							
+							if ( di_map != null ){
 								
-				return( cc );
+								info_map.put( info, id );
+	
+								di_map.put( "_i", new Long( id ));
+								di_map.put( "_k", entry.getKey());
+								
+								rc_map_list.add( di_map );
+		
+								id++;	
+							}
+						}
+						
+						Map<String,Object> rcm_map = new HashMap<String, Object>();
+						
+						map.put( "rcm", rcm_map );
+
+						for ( byte[] hash: related_content_map.keys()){
+							
+							List<DownloadInfo> dis = related_content_map.get( hash );
+							
+							int[] ids = new int[dis.size()];
+							
+							int	pos = 0;
+							
+							for ( DownloadInfo di: dis ){
+								
+								Integer	index = info_map.get( di );
+								
+								if ( index == null ){
+									
+									// Debug.out( "inconsistent: info missing for " + di );
+									
+									break;
+									
+								}else{
+									
+									ids[pos++] = index;
+								}
+							}
+							
+							if ( pos == ids.length ){
+							
+								ImportExportUtils.exportIntArray( rcm_map, Base32.encode( hash), ids );
+							}
+						}
+						
+						if ( true ){
+						
+							ByteArrayOutputStream baos = new ByteArrayOutputStream( 100*1024 );
+							
+							try{
+								GZIPOutputStream gos = new GZIPOutputStream( baos );
+								
+								gos.write( BEncoder.encode( map ));
+								
+								gos.close();
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+							
+							map.clear();
+							
+							map.put( "d", CryptoManagerFactory.getSingleton().obfuscate( baos.toByteArray()));
+						}
+						
+						FileUtil.writeResilientConfigFile( CONFIG_FILE, map );
+					}
+				}else{
+					
+					deleteRelatedContent();
+				}
+			
+				updateKeyBloom( cc );
 			}
-		}finally{
+		}
+	}
+	
+	private void
+	deleteRelatedContent()
+	{
+		FileUtil.deleteResilientConfigFile( CONFIG_FILE );
+		FileUtil.deleteResilientConfigFile( PERSIST_DEL_FILE );
+	}
+	
+	public int
+	getNumUnread()
+	{
+		return( total_unread.get());
+	}
+	
+	public void
+	setAllRead()
+	{
+		boolean	changed = false;
+		
+		synchronized( this ){
+			
+			DownloadInfo[] content = (DownloadInfo[])getRelatedContent();
+			
+			for ( DownloadInfo c: content ){
+				
+				if ( c.isUnread()){
+				
+					changed = true;
+					
+					c.setUnreadInternal( false );
+				}
+			}
+			
+			total_unread.set( 0 );
+		}
+		
+		if ( changed ){
+		
+			contentChanged( true );
+		}
+	}
+	
+	public void
+	deleteAll()
+	{	
+		synchronized( this ){
+
+			ContentCache	content_cache = loadRelatedContent();
+			
+			addPersistentlyDeleted( content_cache.related_content.values().toArray( new DownloadInfo[ content_cache.related_content.size()]));
+		
+			reset( false );
+		}
+	}
+	
+	protected void
+	incrementUnread()
+	{
+		total_unread.incrementAndGet();
+	}
+	
+	protected void
+	decrementUnread()
+	{
+		synchronized( this ){
+			
+			int val = total_unread.decrementAndGet();
+			
+			if ( val < 0 ){
+				
+				// Debug.out( "inconsistent" );
+				
+				total_unread.set( 0 );
+			}
+		}
+	}
+	
+	protected Download
+	getDownload(
+		byte[]	hash )
+	{
+		try{
+			return( plugin_interface.getDownloadManager().getDownload( hash ));
+			
+		}catch( Throwable e ){
+			
+			return( null );
+		}
+	}
+	
+	private static final int KEY_BLOOM_LOAD_FACTOR			= 8;
+	private static final int KEY_BLOOM_MIN_BITS				= 1000;	
+	private static final int KEY_BLOOM_MAX_BITS				= 50000;	// 6k ish
+	private static final int KEY_BLOOM_MAX_ENTRIES			= KEY_BLOOM_MAX_BITS/KEY_BLOOM_LOAD_FACTOR;
+
+	private volatile BloomFilter	key_bloom_with_local;
+	private volatile BloomFilter	key_bloom_without_local;
+	private volatile long			last_key_bloom_update = -1;
+	
+	private Set<String>	ignore_words = new HashSet<String>();
+	
+	{
+		String ignore = "a, in, of, at, the, and, or, if, to, an, for, with";
+		
+		String[]	lame_entries = ignore.toLowerCase( Locale.US ).split(",");
+		
+		for ( String entry: lame_entries ){
+		
+			entry = entry.trim();
+			
+			if ( entry.length() > 0 ){
+				
+				ignore_words.add( entry );
+			}
+		}
+	}
+	
+	private static void
+	logSearch(
+		String		str )
+	{
+		if ( TRACE_SEARCH ){
+			System.out.println( str );
+		}
+	}
+	
+	private List<DownloadInfo>
+	getDHTInfos()
+	{
+		List<DHTPluginValue> vals = dht_plugin.getValues();
+				
+		Set<String>	unique_keys = new HashSet<String>();
+		
+		List<DownloadInfo>	dht_infos = new ArrayList<DownloadInfo>();
+		
+		for ( DHTPluginValue val: vals ){
+			
+			if ( !val.isLocal()){
+				
+				byte[]	bytes = val.getValue();
+				
+				String test = new String( bytes );
+				
+				if ( test.startsWith( "d1:d" ) && test.endsWith( "ee" ) && test.contains( "1:h20:")){
+							
+					try{
+						Map map = BDecoder.decode( bytes );
+					
+						DownloadInfo info =	decodeInfo( map, null, 1, false, unique_keys );
+						
+						if ( info != null ){
+							
+							dht_infos.add( info );
+						}
+					}catch( Throwable e ){
+						
+					}
+				}
+			}
+		}
+		
+		return( dht_infos );
+	}
+	
+	private void
+	checkKeyBloom()
+	{
+		if ( last_key_bloom_update == -1 || SystemTime.getMonotonousTime() - last_key_bloom_update > 10*60*1000 ){
+			
+			synchronized( this ){
+				
+				updateKeyBloom( loadRelatedContent());
+			}
+		}
+	}
+	
+	private BloomFilter
+	getKeyBloom(
+		boolean		include_dht_local )
+	{
+		if ( key_bloom_with_local == null ){
+				
+			synchronized( this ){
+			
+				updateKeyBloom( loadRelatedContent());
+			}
+		}
+			
+		if ( include_dht_local ){
+			
+			return( key_bloom_with_local );
+			
+		}else{
+			
+			return( key_bloom_without_local );
+		}
+	}
+	
+	private List<String>
+	getDHTWords(
+		String		title )
+	{
+		title = title.toLowerCase( Locale.US );
+		
+		char[]	chars = title.toCharArray();
+		
+		for ( int i=0;i<chars.length;i++){
+			
+			if ( !Character.isLetterOrDigit( chars[i])){
+				
+				chars[i] = ' ';
+			}
+		}
+		
+		String[] words = new String( chars ).split( " " );
+		
+		List<String>	result = new ArrayList<String>( words.length );
+		
+		for ( String word: words ){
+			
+			if ( word.length() > 0 && !ignore_words.contains( word )){
+				
+				result.add( word );
+			}
+		}
+		
+		return( result );
+	}
+	
+	private void
+	updateKeyBloom(
+		ContentCache		cc )
+	{
+		synchronized( this ){
+												
+			Set<String>	dht_only_words 		= new HashSet<String>();
+			Set<String>	non_dht_words 		= new HashSet<String>();
+			
+			List<DownloadInfo>		dht_infos		= getDHTInfos();
+			
+			Iterator<DownloadInfo>	it_dht 			= dht_infos.iterator();
+						
+			Iterator<DownloadInfo>	it_transient 	= transient_info_cache.values().iterator();
+			
+			Iterator<DownloadInfo>	it_rc 			= cc.related_content.values().iterator();			
+
+			for ( Iterator _it: new Iterator[]{ it_transient, it_rc, it_dht }){
+				
+				Iterator<DownloadInfo> it = (Iterator<DownloadInfo>)_it;
+				
+				while( it.hasNext()){
+				
+					DownloadInfo di = it.next();
+							
+					List<String>	words = getDHTWords( di.getTitle());
+					
+					for ( String word: words ){
+															
+							// note that it_dht is processed last
+						
+						if ( it == it_dht ){
+							
+							if ( !non_dht_words.contains( word )){
+							
+								dht_only_words.add( word );
+							}
+						}else{
+															
+							non_dht_words.add( word );
+						}
+					}
+				}
+			}
+			
+			int	all_desired_bits = (dht_only_words.size() + non_dht_words.size()) * KEY_BLOOM_LOAD_FACTOR;
+			
+			all_desired_bits = Math.max( all_desired_bits, KEY_BLOOM_MIN_BITS );
+			all_desired_bits = Math.min( all_desired_bits, KEY_BLOOM_MAX_BITS );
+			
+			BloomFilter all_bloom = BloomFilterFactory.createAddOnly( all_desired_bits );
+
+			int	non_dht_desired_bits = non_dht_words.size() * KEY_BLOOM_LOAD_FACTOR;
+			
+			non_dht_desired_bits = Math.max( non_dht_desired_bits, KEY_BLOOM_MIN_BITS );
+			non_dht_desired_bits = Math.min( non_dht_desired_bits, KEY_BLOOM_MAX_BITS );
+			
+			BloomFilter non_dht_bloom = BloomFilterFactory.createAddOnly( non_dht_desired_bits );
+
+			List<String>	non_dht_words_rand = new ArrayList<String>( non_dht_words );
+			
+			Collections.shuffle( non_dht_words_rand );
+			
+			for ( String word: non_dht_words_rand ){
+				
+				try{
+					byte[]	bytes = word.getBytes( "UTF8" );
+					
+					all_bloom.add( bytes );
+					
+					if ( all_bloom.getEntryCount() >= KEY_BLOOM_MAX_ENTRIES ){
+						
+						break;
+					}
+					
+					if ( non_dht_bloom.getEntryCount() < KEY_BLOOM_MAX_ENTRIES ){
+					
+						non_dht_bloom.add( bytes );
+					}
+				}catch( Throwable e ){
+				}
+			}
+				
+			List<String>	dht_only_words_rand = new ArrayList<String>( dht_only_words );
+			
+			Collections.shuffle( dht_only_words_rand );
+
+			for ( String word: dht_only_words_rand ){
+				
+				try{
+					byte[]	bytes = word.getBytes( "UTF8" );
+					
+					all_bloom.add( bytes );
+					
+					if ( all_bloom.getEntryCount() >= KEY_BLOOM_MAX_ENTRIES ){
+						
+						break;
+					}
+				}catch( Throwable e ){
+				}
+			}
+			
+			logSearch( 
+				"blooms=" + 
+				all_bloom.getSize() + "/" + all_bloom.getEntryCount() +", " +
+				non_dht_bloom.getSize() + "/" + non_dht_bloom.getEntryCount()  +
+				": rcm=" + cc.related_content.size() + ", trans=" + transient_info_cache.size() + ", dht=" + dht_infos.size());
+			
+			key_bloom_with_local 	= all_bloom;
+			key_bloom_without_local = non_dht_bloom;
+			
+			last_key_bloom_update = SystemTime.getMonotonousTime();
+		}
+	}
+	
+	private void
+	testKeyBloom()
+	{
+		if ( true ){
+			return;
+		}
+		
+		System.out.println( "test key bloom" );
+		
+		try{
+			Map<String,int[]>	all_words 		= new HashMap<String,int[]>();
+	
+			synchronized( this ){
+				
+				ContentCache cache = loadRelatedContent();
+				
+				List<DownloadInfo>		dht_infos		= getDHTInfos();
+				
+				Iterator<DownloadInfo>	it_dht 			= dht_infos.iterator();
+							
+				Iterator<DownloadInfo>	it_transient 	= transient_info_cache.values().iterator();
+				
+				Iterator<DownloadInfo>	it_rc 			= cache.related_content.values().iterator();			
+	
+				updateKeyBloom( cache );
+				
+				int	 i=0;
+				
+				for ( Iterator _it: new Iterator[]{ it_transient, it_rc, it_dht }){
+					
+					Iterator<DownloadInfo> it = (Iterator<DownloadInfo>)_it;
+					
+					while( it.hasNext()){
+					
+						DownloadInfo di = it.next();
+								
+						List<String>	words = getDHTWords( di.getTitle());
+						
+						for ( String word: words ){
+									
+							int[] x = all_words.get( word );
+							
+							if ( x == null ){
+								
+								x = new int[3];
+								
+								all_words.put( word, x );
+							}
+							
+							x[i] = 1;
+						}
+					}
+					
+					i++;
+				}
+			}
+			
+			BloomFilter bloom = getKeyBloom( true );
+	
+			int	total 	= 0;
+			int	clashes	= 0;
+			int misses	= 0;
+			
+			int match_fails = 0;
+			
+			Random random = new Random();
+			
+			for ( Map.Entry<String,int[]> entry: all_words.entrySet()){
+				
+				String 	word 	= entry.getKey();
+				int[]	source 	= entry.getValue();
+				
+				boolean	r1 = bloom.contains( word.getBytes("UTF-8") );
+				boolean r2 = bloom.contains( (word + random.nextLong()).getBytes("UTF-8"));
+				
+				System.out.println( word + " -> " + r1 + "/" +r2 );
+				
+				total++;
+				if ( r1 && r2 ){
+					clashes++;
+				}
+				if ( !r1 ){
+					
+					misses++;
+				}
+				
+				List<RelatedContent> hits = matchContent( word );
+				
+				if ( hits.size() == 0 ){
+					
+					hits = matchContent( word );
+					match_fails++;
+				}
+			}
+			
+			System.out.println( "total=" + total + ", clash=" + clashes + ", miss=" + misses + ", fails=" + match_fails + ", bloom=" + bloom.getString() );
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
+	
+	private void
+	harvestBlooms()
+	{
+		harvest_dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					if ( harvest_dispatcher.getQueueSize() > 0 ){
+						
+						return;
+					}
+					
+					ForeignBloom oldest = null;
+					
+					synchronized( harvested_blooms ){
+						
+						for ( ForeignBloom bloom: harvested_blooms.values()){
+							
+							if ( 	oldest == null ||
+									bloom.getLastUpdateTime() < oldest.getLastUpdateTime()){
+								
+								oldest	= bloom;
+							}
+						}
+					}
+					
+					long now = SystemTime.getMonotonousTime();
+					
+					if ( oldest != null ){
+						
+						if ( now - oldest.getLastUpdateTime() > HARVEST_BLOOM_UPDATE_MILLIS ){
+							
+							DistributedDatabaseContact ddb_contact = oldest.getContact();
+
+							if ( now - oldest.getCreateTime() > HARVEST_BLOOM_DISCARD_MILLIS ){
+							
+									// don't want to stick with a stable one for too long otherwise the stabler
+									// nodes will end up in lots of other nodes' harvest set and receive
+									// undue attention
+								
+								logSearch( "Harvest: discarding " + ddb_contact.getAddress());
+								
+								synchronized( harvested_blooms ){
+									
+									harvested_blooms.remove( ddb_contact.getID());
+								}
+							}else{
+
+								BloomFilter updated_filter = sendRemoteUpdate( oldest );
+								
+								if ( updated_filter == null ){
+																						
+									synchronized( harvested_blooms ){
+									
+										harvested_blooms.remove( ddb_contact.getID());
+									
+										harvested_fails.put( ddb_contact.getID(), "" );
+									}
+								}else{
+																	
+									oldest.updateFilter( updated_filter );
+								}
+							}
+						}
+					}
+					
+					if ( harvested_blooms.size() < HARVEST_MAX_BLOOMS ){
+					
+						try{
+							int	fail_count	= 0;
+							
+							DHT[] dhts = dht_plugin.getDHTs();
+							
+outer:
+							for ( DHT dht: dhts ){
+								
+								DHTTransport transport = dht.getTransport();
+								
+								if ( transport.isIPV6()){
+									
+									continue;
+								}
+								
+								int	network = dht.getTransport().getNetwork();
+								
+								if ( SEARCH_CVS_ONLY && network != DHT.NW_CVS ){
+									
+									logSearch( "Harvest: ignoring main DHT" );
+									
+									continue;
+								}
+													
+								DHTTransportContact[] contacts = dht.getTransport().getReachableContacts();
+								
+								for ( DHTTransportContact contact: contacts ){
+				
+									byte[]	contact_id = contact.getID();
+									
+									if ( dht.getRouter().isID( contact_id )){
+										
+										// logSearch( "not skipping local!!!!" );
+										
+										continue;
+									}
+									
+									DistributedDatabaseContact ddb_contact = 
+										ddb.importContact( contact.getAddress(), DHTTransportUDP.PROTOCOL_VERSION_MIN, network==DHT.NW_CVS?DistributedDatabase.DHT_CVS:DistributedDatabase.DHT_MAIN );
+									
+									synchronized( harvested_blooms ){
+																				
+										if ( harvested_fails.containsKey( contact_id )){
+											
+											continue;
+										}
+
+										if ( harvested_blooms.containsKey( contact_id )){
+											
+											continue;
+										}
+									}
+									
+									BloomFilter filter = sendRemoteFetch( ddb_contact );
+									
+									logSearch( "harvest: " + contact.getString() + " -> " +(filter==null?"null":filter.getString()));
+
+									if ( filter != null ){
+										
+										synchronized( harvested_blooms ){
+										
+											harvested_blooms.put( contact_id, new ForeignBloom( ddb_contact, filter ));
+										}
+										
+										break outer;
+										
+									}else{
+										
+										synchronized( harvested_blooms ){
+										
+											harvested_fails.put( contact_id, "" );
+										}
+										
+										fail_count++;
+										
+										if ( fail_count > 5 ){
+											
+											break outer;
+										}
+									}
+								}
+							}
+						}catch( Throwable e ){
+							
+							e.printStackTrace();
+						}
+					}
+					
+					synchronized( harvested_blooms ){
+					
+						if ( harvested_fails.size() > HARVEST_MAX_FAILS_HISTORY ){
+						
+							harvested_fails.clear();
+						}
+					}
+				}
+			});
+	}
+	
+	private void
+	foreignBloomFailed(
+		DistributedDatabaseContact		contact )
+	{
+		byte[]	contact_id = contact.getID();
+		
+		synchronized( harvested_blooms ){
 			
-			if ( fire_event ){
-				
-				contentChanged( false );
+			if ( harvested_blooms.remove( contact_id ) != null ){
+			
+				harvested_fails.put( contact_id, "" );
 			}
 		}
 	}
 	
-	protected void
-	saveRelatedContent()
+	private List<DistributedDatabaseContact>
+	searchForeignBlooms(
+		String		term )
 	{
-		synchronized( this ){
-				
-			COConfigurationManager.setParameter( CONFIG_TOTAL_UNREAD, total_unread.get());
-			
-			long	now = SystemTime.getMonotonousTime();;
-			
-			ContentCache cc = content_cache==null?null:content_cache.get();
+		List<DistributedDatabaseContact>	result = new ArrayList<DistributedDatabaseContact>();
+		
+		try{
+			String[]	 bits = Constants.PAT_SPLIT_SPACE.split(term.toLowerCase());
+	
+			int[]			bit_types 		= new int[bits.length];
+			byte[][]		bit_bytes	 	= new byte[bit_types.length][];
+			byte[][][]		extras			= new byte[bit_types.length][][];
 			
-			if ( !content_dirty ){
+			for (int i=0;i<bits.length;i++){
+				
+				String bit = bits[i].trim();
+				
+				if ( bit.length() > 0 ){
 					
-				if ( cc != null  ){
+					char	c = bit.charAt(0);
 					
-					if ( now - last_config_access > CONFIG_DISCARD_MILLIS ){
+					if ( c == '+' ){
+						
+						bit_types[i] = 1;
+						
+						bit = bit.substring(1);
+						
+					}else if ( c == '-' ){
+						
+						bit_types[i] = 2;
+						
+						bit = bit.substring(1);
+					}
 					
-						if ( content_cache_ref != null ){
+					if ( bit.startsWith( "(" ) && bit.endsWith((")"))){
+						
+						bit_types[i] = 3;	// ignore
+						
+					}else if ( bit.contains( "|" )){
+											
+						String[]	parts = bit.split( "\\|" );
+						
+						List<String>	p = new ArrayList<String>();
+						
+						for ( String part: parts ){
 							
-							content_discard_ticks = 0;
+							part = part.trim();
+							
+							if ( part.length() > 0 ){
+								
+								p.add( part );
+							}
 						}
 						
-						if ( TRACE ){
-							System.out.println( "rcm: discard: tick count=" + content_discard_ticks++ );
+						if ( p.size() == 0 ){
+							
+							bit_types[i] = 3;
+							
+						}else{
+							
+							bit_types[i] = 4;
+	
+							extras[i] = new byte[p.size()][];
+							
+							for ( int j=0;j<p.size();j++){
+								
+								extras[i][j] = p.get(j).getBytes( "UTF8" );
+							}
 						}
-						
-						content_cache_ref	= null;
 					}
-				}else{
 					
-					if ( TRACE ){
-						System.out.println( "rcm: discarded" );
-					}
+					bit_bytes[i] = bit.getBytes( "UTF8" );
 				}
-				
-				return;
 			}
 			
-			last_config_access = now;
-			
-			content_dirty	= false;
-			
-			if ( cc == null ){
-				
-				Debug.out( "RCM: cache inconsistent" );
-				
-			}else{
-
-				if ( TRACE ){
-					System.out.println( "rcm: save" );
-				}
+			synchronized( harvested_blooms ){
 				
-				Map<String,DownloadInfo>						related_content			= cc.related_content;
-				ByteArrayHashMapEx<ArrayList<DownloadInfo>>		related_content_map		= cc.related_content_map;
-
-				if ( related_content.size() == 0 ){
-					
-					FileUtil.deleteResilientConfigFile( CONFIG_FILE );
+				for ( ForeignBloom fb: harvested_blooms.values()){
 					
-				}else{
-					
-					Map<String,Object>	map = new HashMap<String, Object>();
-					
-					Set<Map.Entry<String,DownloadInfo>> rcs = related_content.entrySet();
-										
-					List<Map<String,Object>> rc_map_list = new ArrayList<Map<String, Object>>( rcs.size());
+					BloomFilter filter = fb.getFilter();
 					
-					map.put( "rc", rc_map_list );
+					boolean	failed 	= false;
+					int		matches	= 0;
 					
-					int		id = 0;
-					
-					Map<DownloadInfo,Integer>	info_map = new HashMap<DownloadInfo, Integer>();
-					
-					for ( Map.Entry<String,DownloadInfo> entry: rcs ){
-											
-						DownloadInfo	info = entry.getValue();
-												
-						Map<String,Object> di_map = serialiseDI( info, cc );
+					for (int i=0;i<bit_bytes.length;i++){
 						
-						if ( di_map != null ){
-							
-							info_map.put( info, id );
-
-							di_map.put( "_i", new Long( id ));
-							di_map.put( "_k", entry.getKey());
+						byte[]	bit = bit_bytes[i];
+						
+						if ( bit == null || bit.length == 0 ){
 							
-							if ( rc_map_list.add( di_map ));
-	
-							id++;	
+							continue;
 						}
-					}
-					
-					Map<String,Object> rcm_map = new HashMap<String, Object>();
-
-					map.put( "rcm", rcm_map );
-										
-					for ( byte[] hash: related_content_map.keys()){
-						
-						List<DownloadInfo> dis = related_content_map.get( hash );
 						
-						int[] ids = new int[dis.size()];
+						int	type = bit_types[i];
 						
-						int	pos = 0;
-						
-						for ( DownloadInfo di: dis ){
+						if ( type == 3 ){
 							
-							Integer	index = info_map.get( di );
+							continue;
+						}
+						
+						if ( type == 0 || type == 1 ){
 							
-							if ( index == null ){
+							if ( filter.contains( bit )){
+								
+								matches++;
+								
+							}else{
 								
-								Debug.out( "inconsistent: info missing for " + di );
+								failed	= true;
 								
 								break;
+							}
+						}else if ( type == 2 ){
+						
+							if ( !filter.contains( bit )){
+								
+								matches++;
 								
 							}else{
 								
-								ids[pos++] = index;
+								failed	= true;
+								
+								break;
+							}
+						}else if ( type == 4 ){
+							
+							byte[][]	parts = extras[i];
+							
+							int	old_matches = matches;
+							
+							for ( byte[] p: parts ){
+								
+								if ( filter.contains( p )){
+								
+									matches++;
+									
+									break;
+								}
+							}
+							
+							if ( matches == old_matches ){
+								
+								failed = true;
+								
+								break;
 							}
-						}
-						
-						if ( pos == ids.length ){
-						
-							ImportExportUtils.exportIntArray( rcm_map, Base32.encode( hash), ids );
 						}
 					}
 					
-					FileUtil.writeResilientConfigFile( CONFIG_FILE, map );
-				}
-			}
-		}
-	}
-	
-	
-	public int
-	getNumUnread()
-	{
-		return( total_unread.get());
-	}
-	
-	public void
-	setAllRead()
-	{
-		boolean	changed = false;
-		
-		synchronized( this ){
-			
-			DownloadInfo[] content = (DownloadInfo[])getRelatedContent();
-			
-			for ( DownloadInfo c: content ){
-				
-				if ( c.isUnread()){
-				
-					changed = true;
-					
-					c.setUnreadInternal( false );
+					if ( matches > 0 && !failed ){
+						
+						result.add( fb.getContact());
+					}
 				}
 			}
+		}catch( UnsupportedEncodingException e ){
 			
-			total_unread.set( 0 );
-		}
-		
-		if ( changed ){
-		
-			contentChanged( true );
+			Debug.out( e );
 		}
-	}
-	
-	public void
-	deleteAll()
-	{	
-		synchronized( this ){
-
-			ContentCache	content_cache = loadRelatedContent();
-			
-			addPersistentlyDeleted( content_cache.related_content.values().toArray( new DownloadInfo[ content_cache.related_content.size()]));
 		
-			reset( false );
-		}
-	}
-	
-	protected void
-	incrementUnread()
-	{
-		total_unread.incrementAndGet();
-	}
-	
-	protected void
-	decrementUnread()
-	{
-		synchronized( this ){
-			
-			int val = total_unread.decrementAndGet();
-			
-			if ( val < 0 ){
-				
-				Debug.out( "inconsistent" );
-				
-				total_unread.set( 0 );
-			}
-		}
-	}
-	
-	protected Download
-	getDownload(
-		byte[]	hash )
-	{
-		try{
-			return( plugin_interface.getDownloadManager().getDownload( hash ));
-			
-		}catch( Throwable e ){
-			
-			return( null );
-		}
+		return( result );
 	}
 	
 	private static final int PD_BLOOM_INITIAL_SIZE		= 1000;
@@ -3541,7 +4836,7 @@ RelatedContentManager
 		private int				level;
 		private boolean			explicit;
 		
-			// we *need* this reference here to maange garbage collection correctly
+			// we *need* this reference here to manage garbage collection correctly
 		
 		private ContentCache	cc;
 		
@@ -3871,4 +5166,109 @@ RelatedContentManager
 		implements DistributedDatabaseTransferType
 	{	
 	}
+	
+	private static class
+	MySearchObserver
+		implements SearchObserver
+	{
+		private SearchObserver		observer;
+		private AtomicInteger		num_results = new AtomicInteger();
+		
+		private
+		MySearchObserver(
+			SearchObserver		_observer )
+		{
+			observer = _observer;
+		}
+		
+		public void
+		resultReceived(
+			SearchInstance		search,
+			SearchResult		result )
+		{
+			observer.resultReceived( search, result );
+			
+			logSearch( "results=" + num_results.incrementAndGet());
+		}
+		
+		private int
+		getResultCount()
+		{
+			return( num_results.get());
+		}
+		
+		public void
+		complete()
+		{
+			observer.complete();
+		}
+		
+		public void
+		cancelled()
+		{
+			observer.cancelled();
+		}
+		
+		public Object
+		getProperty(
+			int		property )
+		{
+			return( observer.getProperty(property));
+		}
+	}
+	
+	private static class
+	ForeignBloom
+	{
+		private DistributedDatabaseContact	contact;
+		private BloomFilter					filter;
+		
+		private long						created;
+		private long						last_update;
+		
+		private
+		ForeignBloom(
+			DistributedDatabaseContact		_contact,
+			BloomFilter						_filter )
+		{
+			contact	= _contact;
+			filter	= _filter;
+			
+			created	 = SystemTime.getMonotonousTime();
+			
+			last_update	= created;
+		}
+		
+		public DistributedDatabaseContact
+		getContact()
+		{
+			return( contact );
+		}
+		
+		public BloomFilter
+		getFilter()
+		{
+			return( filter );
+		}
+		
+		public long
+		getCreateTime()
+		{
+			return( created );
+		}
+		
+		public long
+		getLastUpdateTime()
+		{
+			return( last_update );
+		}
+		
+		public void
+		updateFilter(
+			BloomFilter		f )
+		{
+			filter		= f;
+			last_update	= SystemTime.getMonotonousTime();
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/devices/Device.java b/com/aelitis/azureus/core/devices/Device.java
index e66d053..8a4a021 100644
--- a/com/aelitis/azureus/core/devices/Device.java
+++ b/com/aelitis/azureus/core/devices/Device.java
@@ -21,8 +21,12 @@
 
 package com.aelitis.azureus.core.devices;
 
+import java.io.IOException;
+import java.net.InetAddress;
 import java.net.URL;
 
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+
 public interface 
 Device 
 {
@@ -44,7 +48,8 @@ Device
 	
 	public void
 	setName(
-		String		name );
+		String		name,
+		boolean isAutomaticName);
 	
 	public String
 	getClassification();
@@ -52,6 +57,9 @@ Device
 	public String
 	getShortDescription();
 	
+	public void
+	alive();
+	
 	public boolean
 	isAlive();
 	
@@ -71,12 +79,26 @@ Device
 	public boolean
 	isHidden();
 	
+	public void
+	setTagged(
+		boolean	is_tagged );
+	
+	public boolean 
+	isTagged();
+	
 	public boolean
 	isBrowsable();
 	
 	public browseLocation[]
 	getBrowseLocations();
 		
+	public InetAddress
+	getAddress();
+	
+	public void
+	setAddress(
+		InetAddress	address );
+	
 	public void
 	setTransientProperty(
 		Object		key,
@@ -100,6 +122,10 @@ Device
 	public void
 	remove();
 	
+	public void
+	setCanRemove(
+		boolean	can );
+	
 	public boolean
 	canRemove();
 	
@@ -109,6 +135,9 @@ Device
 	public String
 	getError();
 	
+	public String
+	getStatus();
+	
 	public void
 	addListener(
 		DeviceListener		listener );
@@ -129,4 +158,37 @@ Device
 		public URL
 		getURL();
 	}
+
+	public boolean 
+	isGenericUSB();
+	
+	public void
+	setGenericUSB(boolean b);
+	
+	public String
+	getImageID();
+	
+	public void
+	setImageID(String id);
+
+	public boolean
+	isNameAutomatic();
+	
+	public void
+	setExportable(
+		boolean		b );
+	
+	public boolean
+	isExportable();
+	
+	public URL
+	getWikiURL();
+	
+	public VuzeFile
+	getVuzeFile()
+	
+		throws IOException;
+
+	public TranscodeProfile[] 
+	getDirectTranscodeProfiles();
 }
diff --git a/com/aelitis/azureus/core/devices/DeviceManager.java b/com/aelitis/azureus/core/devices/DeviceManager.java
index 20ec95a..f780f7e 100644
--- a/com/aelitis/azureus/core/devices/DeviceManager.java
+++ b/com/aelitis/azureus/core/devices/DeviceManager.java
@@ -38,6 +38,24 @@ DeviceManager
 	public Device[]
 	getDevices();
 	
+	public Device
+	addVirtualDevice(
+		int					type,
+		String				uid,
+		String				classification,
+		String				name )
+	
+		throws DeviceManagerException;
+	
+	Device addInetDevice(
+		int					type, 
+		String					uid, 
+		String					classification,
+		String					name,
+		InetAddress					address )
+
+		throws DeviceManagerException;
+
 	public void
 	search(
 		int						max_millis,
@@ -74,7 +92,8 @@ DeviceManager
 		File		dir );
 	
 	public boolean
-	isBusy();
+	isBusy(
+		int	device_type );
 	
 	public DeviceOfflineDownloaderManager
 	getOfflineDownlaoderManager();
@@ -86,13 +105,28 @@ DeviceManager
 	setTiVoEnabled(
 		boolean	enabled );
 	
+	public boolean
+	getDisableSleep();
+	
+	public void
+	setDisableSleep(
+		boolean		b );
+	
+	public void
+	addDiscoveryListener(
+		DeviceManagerDiscoveryListener	listener );
+	
+	public void
+	removeDiscoveryListener(
+		DeviceManagerDiscoveryListener	listener );
+	
 	public void
 	addListener(
 		DeviceManagerListener		listener );
 	
 	public void
 	removeListener(
-			DeviceManagerListener		listener );
+		DeviceManagerListener		listener );
 	
 	public interface 
 	UnassociatedDevice
diff --git a/com/aelitis/azureus/core/devices/DeviceManagerDiscoveryListener.java b/com/aelitis/azureus/core/devices/DeviceManagerDiscoveryListener.java
new file mode 100644
index 0000000..c6264a3
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/DeviceManagerDiscoveryListener.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Oct 23, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 java.util.Map;
+
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
+
+public interface 
+DeviceManagerDiscoveryListener 
+{
+	public boolean
+	browseReceived(
+		TrackerWebPageRequest		request,
+		Map<String,Object>			browser_args );
+}
diff --git a/com/aelitis/azureus/core/devices/DeviceMediaRenderer.java b/com/aelitis/azureus/core/devices/DeviceMediaRenderer.java
index 79aabf5..2574cfc 100644
--- a/com/aelitis/azureus/core/devices/DeviceMediaRenderer.java
+++ b/com/aelitis/azureus/core/devices/DeviceMediaRenderer.java
@@ -79,6 +79,10 @@ DeviceMediaRenderer
 	public boolean
 	canCopyToFolder();
 	
+	public void
+	setCanCopyToFolder(
+		boolean		can );
+	
 	public File
 	getCopyToFolder();
 	
@@ -129,4 +133,14 @@ DeviceMediaRenderer
 	
 	public InetAddress
 	getAddress();
+	
+	public boolean
+	canRestrictAccess();
+	
+	public String
+	getAccessRestriction();
+	
+	public void
+	setAccessRestriction(
+		String		str );
 }
diff --git a/com/aelitis/azureus/core/devices/DeviceTemplate.java b/com/aelitis/azureus/core/devices/DeviceTemplate.java
index d228cdd..d3ccad9 100644
--- a/com/aelitis/azureus/core/devices/DeviceTemplate.java
+++ b/com/aelitis/azureus/core/devices/DeviceTemplate.java
@@ -54,4 +54,12 @@ DeviceTemplate
 		String		name )
 	
 		throws DeviceManagerException;
+	
+	public Device
+	createInstance(
+		String		name,
+		String		uid,
+		boolean		manual )
+	
+		throws DeviceManagerException;
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeActionVetoException.java b/com/aelitis/azureus/core/devices/TranscodeActionVetoException.java
new file mode 100644
index 0000000..3cec38c
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/TranscodeActionVetoException.java
@@ -0,0 +1,34 @@
+/*
+ * Created on Mar 16, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 class 
+TranscodeActionVetoException
+	extends Exception
+{
+	public
+	TranscodeActionVetoException(
+		String		str )
+	{
+		super( str );
+	}
+}
diff --git a/com/aelitis/azureus/core/devices/TranscodeAnalysisListener.java b/com/aelitis/azureus/core/devices/TranscodeAnalysisListener.java
new file mode 100644
index 0000000..cf342d1
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/TranscodeAnalysisListener.java
@@ -0,0 +1,37 @@
+/*
+ * Created on Feb 15, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 
+TranscodeAnalysisListener 
+{
+	public void
+	analysisComplete(
+		TranscodeJob					file,
+		TranscodeProviderAnalysis		analysis );
+	
+	public void
+	analysisFailed(
+		TranscodeJob		file,
+		TranscodeException	error );
+		
+}
diff --git a/com/aelitis/azureus/core/devices/TranscodeException.java b/com/aelitis/azureus/core/devices/TranscodeException.java
index 7bf4956..f80a88f 100644
--- a/com/aelitis/azureus/core/devices/TranscodeException.java
+++ b/com/aelitis/azureus/core/devices/TranscodeException.java
@@ -27,6 +27,8 @@ public class
 TranscodeException
 	extends Exception
 {
+	private boolean	disable_retry = false;
+	
 	public 
 	TranscodeException(
 		String		str )
@@ -41,4 +43,17 @@ TranscodeException
 	{
 		super( str, e );
 	}
+	
+	public void
+	setDisableRetry(
+		boolean		b )
+	{
+		disable_retry = b;
+	}
+	
+	public boolean
+	isRetryDisabled()
+	{
+		return( disable_retry );
+	}
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeFile.java b/com/aelitis/azureus/core/devices/TranscodeFile.java
index e378017..6a9f4cb 100644
--- a/com/aelitis/azureus/core/devices/TranscodeFile.java
+++ b/com/aelitis/azureus/core/devices/TranscodeFile.java
@@ -82,6 +82,9 @@ TranscodeFile
 	public long
 	getVideoHeight();
 	
+	public long
+	getEstimatedTranscodeSize();
+	
 	public String[]
 	getCategories();
 	
@@ -124,4 +127,10 @@ TranscodeFile
 	public Object
 	getTransientProperty(
 		Object		key );
+
+	public boolean 
+	isDeleted();
+
+	public boolean
+	isCopyingToDevice();
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeJob.java b/com/aelitis/azureus/core/devices/TranscodeJob.java
index 5de2097..3b11e5a 100644
--- a/com/aelitis/azureus/core/devices/TranscodeJob.java
+++ b/com/aelitis/azureus/core/devices/TranscodeJob.java
@@ -74,6 +74,20 @@ TranscodeJob
 	public String
 	getError();
 	
+	public void
+	setEnableAutoRetry(
+		boolean		enabled );
+	
+	public boolean
+	getEnableAutoRetry();
+	
+	public void
+	setPreferDirectInput(
+		boolean		prefer );
+	
+	public boolean
+	getPreferDirectInput();
+	
 	public boolean
 	canPause();
 	
@@ -90,7 +104,12 @@ TranscodeJob
 	stop();
 	
 	public void
-	remove();
+	remove()
+	
+		throws TranscodeActionVetoException;
+	
+	public void
+	removeForce();
 	
 	public void
 	moveUp();
@@ -100,4 +119,10 @@ TranscodeJob
 
 	public long
 	getProcessTime();
+	
+	public void
+	analyseNow(
+		TranscodeAnalysisListener	listener )
+	
+		throws TranscodeException;
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeProfile.java b/com/aelitis/azureus/core/devices/TranscodeProfile.java
index ee186d2..d2ae337 100644
--- a/com/aelitis/azureus/core/devices/TranscodeProfile.java
+++ b/com/aelitis/azureus/core/devices/TranscodeProfile.java
@@ -21,8 +21,6 @@
 
 package com.aelitis.azureus.core.devices;
 
-import java.io.File;
-
 public interface 
 TranscodeProfile 
 {
@@ -41,6 +39,9 @@ TranscodeProfile
 	public String
 	getIconURL();
 	
+	public int
+	getIconIndex();
+	
 	public String
 	getFileExtension();
 	
@@ -48,8 +49,7 @@ TranscodeProfile
 	getDeviceClassification();
 	
 	public TranscodeProvider
-	getProvider();
+	getProvider()
 	
-	public File
-	getAssetDirectory();
+		throws TranscodeException;
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeProvider.java b/com/aelitis/azureus/core/devices/TranscodeProvider.java
index 93e0606..6eef173 100644
--- a/com/aelitis/azureus/core/devices/TranscodeProvider.java
+++ b/com/aelitis/azureus/core/devices/TranscodeProvider.java
@@ -29,16 +29,31 @@ import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 public interface 
 TranscodeProvider 
 {
+	public static final int TP_VUZE	= 1;
+	
+	public int
+	getID();
+	
 	public String
 	getName();
 	
 	public TranscodeProfile[]
 	getProfiles();
 	
+	public TranscodeProfile[]
+	getProfiles(
+		String	classification_prefix );
+	
 	public TranscodeProfile
 	getProfile(
 		String		UID );
 	
+	public TranscodeProfile
+	addProfile(
+		File		file )
+	
+		throws TranscodeException;
+	
 	public TranscodeProviderAnalysis
 	analyse( 
 		TranscodeProviderAdapter	adapter,
diff --git a/com/aelitis/azureus/core/devices/TranscodeProviderAnalysis.java b/com/aelitis/azureus/core/devices/TranscodeProviderAnalysis.java
index 1290765..c8599e9 100644
--- a/com/aelitis/azureus/core/devices/TranscodeProviderAnalysis.java
+++ b/com/aelitis/azureus/core/devices/TranscodeProviderAnalysis.java
@@ -28,7 +28,9 @@ TranscodeProviderAnalysis
 	public static final int PT_DURATION_MILLIS		= 2;	// Long
 	public static final int PT_VIDEO_WIDTH			= 3;	// Long
 	public static final int PT_VIDEO_HEIGHT			= 4;	// Long
-	
+	public static final int PT_SOURCE_SIZE			= 6;	// Long
+	public static final int PT_ESTIMATED_XCODE_SIZE	= 7;	// Long
+
 	public static final int PT_FORCE_TRANSCODE		= 5;	// Boolean (set)
 
 	
@@ -36,6 +38,9 @@ TranscodeProviderAnalysis
 	cancel();
 	
 	public boolean
+	foundVideoStream();
+	
+	public boolean
 	getBooleanProperty(
 		int		property );
 	
diff --git a/com/aelitis/azureus/core/devices/TranscodeQueue.java b/com/aelitis/azureus/core/devices/TranscodeQueue.java
index 58de361..cbc69d9 100644
--- a/com/aelitis/azureus/core/devices/TranscodeQueue.java
+++ b/com/aelitis/azureus/core/devices/TranscodeQueue.java
@@ -30,7 +30,8 @@ TranscodeQueue
 	add(
 		TranscodeTarget			target,
 		TranscodeProfile		profile,
-		DiskManagerFileInfo		file )
+		DiskManagerFileInfo		file,
+		boolean					add_stopped )
 	
 		throws TranscodeException;
 	
@@ -39,7 +40,8 @@ TranscodeQueue
 		TranscodeTarget			target,
 		TranscodeProfile		profile,
 		DiskManagerFileInfo		file,
-		int						transcode_requirement )	// from target.TRANSCODE_<x>
+		int						transcode_requirement,		// from target.TRANSCODE_<x>
+		boolean					add_stopped )
 	
 		throws TranscodeException;
 	
@@ -78,4 +80,12 @@ TranscodeQueue
 	public void
 	removeListener(
 		TranscodeQueueListener		listener );
+	
+	public void
+	addActionListener(
+		TranscodeQueueActionListener		listener );
+	
+	public void
+	removeActionListener(
+		TranscodeQueueActionListener		listener );
 }
diff --git a/com/aelitis/azureus/core/devices/TranscodeQueueActionListener.java b/com/aelitis/azureus/core/devices/TranscodeQueueActionListener.java
new file mode 100644
index 0000000..ba6e6e9
--- /dev/null
+++ b/com/aelitis/azureus/core/devices/TranscodeQueueActionListener.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Mar 16, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 
+TranscodeQueueActionListener 
+{
+	public static final int	ACT_REMOVE	= 1;
+	
+	public void
+	jobWillBeActioned(
+		TranscodeJob		job,
+		int					action )
+	
+		throws TranscodeActionVetoException;
+}
diff --git a/com/aelitis/azureus/core/devices/TranscodeTarget.java b/com/aelitis/azureus/core/devices/TranscodeTarget.java
index 479f625..829d393 100644
--- a/com/aelitis/azureus/core/devices/TranscodeTarget.java
+++ b/com/aelitis/azureus/core/devices/TranscodeTarget.java
@@ -27,6 +27,7 @@ import java.io.File;
 public interface 
 TranscodeTarget 
 {
+	public static final int TRANSCODE_UNKNOWN			= -1;
 	public static final int TRANSCODE_NEVER				= 1;
 	public static final int TRANSCODE_WHEN_REQUIRED		= 2;
 	public static final int TRANSCODE_ALWAYS			= 3;
@@ -59,6 +60,9 @@ TranscodeTarget
 	setDefaultTranscodeProfile(
 		TranscodeProfile		profile );
 	
+	public TranscodeProfile
+	getBlankProfile();
+	
 	public int
 	getTranscodeRequirement();
 	
@@ -77,7 +81,7 @@ TranscodeTarget
 	isTranscoding();
 	
 	public boolean
-	isGeneric();
+	isNonSimple();
 	
 	public boolean
 	isAudioCompatible(
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceDriveManager.java b/com/aelitis/azureus/core/devices/impl/DeviceDriveManager.java
index 4bafb27..db99aef 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceDriveManager.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceDriveManager.java
@@ -28,10 +28,13 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AsyncDispatcher;
 
 import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.devices.DeviceManagerListener;
+import com.aelitis.azureus.core.devices.DeviceMediaRenderer;
 import com.aelitis.azureus.core.devices.DeviceTemplate;
 import com.aelitis.azureus.core.drivedetector.DriveDetectedInfo;
 import com.aelitis.azureus.core.drivedetector.DriveDetectedListener;
 import com.aelitis.azureus.core.drivedetector.DriveDetectorFactory;
+import com.aelitis.azureus.util.MapUtils;
 
 public class 
 DeviceDriveManager 
@@ -51,6 +54,53 @@ DeviceDriveManager
 	{
 		manager = _manager;
 		
+		manager.addListener(
+			new DeviceManagerListener()
+			{
+				public void
+				deviceAdded(
+					Device		device )
+				{	
+				}
+				
+				public void
+				deviceChanged(
+					Device		device )
+				{
+				}
+				
+				public void
+				deviceAttentionRequest(
+					Device		device )
+				{
+				}
+				
+				public void
+				deviceRemoved(
+					Device		device )
+				{
+					synchronized( device_map ){
+						
+						Iterator<Map.Entry<String,DeviceMediaRendererManual>> it = device_map.entrySet().iterator();
+						
+						while( it.hasNext()){
+							
+							Map.Entry<String,DeviceMediaRendererManual> entry = it.next();
+							
+							if ( entry.getValue() == device ){
+								
+								it.remove();
+							}
+						}
+					}
+				}
+
+				public void
+				deviceManagerLoaded()
+				{
+				}
+			});
+		
 		if ( manager.getAutoSearch()){
 			
 			listener_added = true;
@@ -70,6 +120,15 @@ DeviceDriveManager
 				{
 					if ( listener_added ){
 						
+						DriveDetectedInfo[] info = DriveDetectorFactory.getDeviceDetector().getDetectedDriveInfo();
+						
+						for ( DriveDetectedInfo i: info ){
+							
+							driveRemoved( i );
+							
+							driveDetected( i );
+						}
+						
 						return;
 					}
 					
@@ -89,108 +148,224 @@ DeviceDriveManager
 	public void 
 	driveDetected(
 		final DriveDetectedInfo info )
-	{
-		async_dispatcher.dispatch(
-			new AERunnable()
-			{
-				public void
-				runSupport()
-				{
-					File root = info.getLocation();
+ {
+		//System.out.println("DD " + info.getLocation() + " via " + Debug.getCompressedStackTrace());
+		async_dispatcher.dispatch(new AERunnable() {
+			public void runSupport() {
+				
+				Map<String, Object> infoMap = info.getInfoMap();
+
+				boolean isWritableUSB = MapUtils.getMapBoolean(infoMap, "isWritableUSB", false);
+				
+				File root = info.getLocation();
+
+				String sProdID = MapUtils.getMapString(infoMap, "ProductID",
+						MapUtils.getMapString(infoMap, "Product Name", "")).trim();
+				String sVendor = MapUtils.getMapString(infoMap, "VendorID",
+						MapUtils.getMapString(infoMap, "Vendor Name", "")).trim();
+
+				// Historically, we gave IDs to Motorola, Samsung, and HTC phones
+				// based on their vendor and product id only.  We need to maintain
+				// this ID in order to not create duplicates.
+				// Fortunately, both Motorola and Samsung include their model id in the 
+				// sProdID.  HTC doesn't, however, their PID doesn't identify unique
+				// models anyway, so including that wouldn't have helped anyway
+				if ((sVendor.equalsIgnoreCase("htc") && sProdID.equalsIgnoreCase("android phone"))
+						|| (sVendor.toLowerCase().contains("motorola") && sProdID.length() > 0)
+						|| sVendor.equalsIgnoreCase("samsung")) {
 					
-					if ( root.exists()){
-						
-						File[] folders = root.listFiles();
-						
-						if ( folders != null ){
-							
-							Set<String>	names = new HashSet<String>();
-							
-							for ( File file: folders ){
-								
-								names.add( file.getName().toLowerCase());
-							}
-							
-							if ( names.contains( "psp" ) && names.contains( "video" )){
-								
-								DeviceImpl[] devices = manager.getDevices();
-								
-								String target_name				= "PSP";
-								String target_classification 	= "sony.PSP";
-								
-								File target_directory = new File( root,"VIDEO" );
+					if (isWritableUSB && sVendor.equalsIgnoreCase("samsung")) {
+						// Samsungs that start with Y are MP3 players
+						// Samsungs that don't have a dash aren't smart phones (none that we know of anyway..)
+						// Fake not writable so we remove the device instead of adding it
+						isWritableUSB = !sProdID.startsWith("Y")
+								&& sProdID.matches(".*[A-Z]-.*");
+					}
 
-								for ( DeviceImpl device: devices ){
-									
-									if ( device instanceof DeviceMediaRendererManual ){
-									
-										DeviceMediaRendererManual renderer = (DeviceMediaRendererManual)device;
-										
-										String classification = renderer.getClassification();
-									
-										if ( classification.equalsIgnoreCase( target_classification )){
-																						
-											mapDevice( renderer, root, target_directory );
-											
-											return;
-										}
-									}
-								}
-								
-								DeviceTemplate[] templates = manager.getDeviceTemplates( Device.DT_MEDIA_RENDERER );
-								
-								DeviceMediaRendererManual	renderer = null;
-								
-								for ( DeviceTemplate template: templates ){
-									
-									if ( template.getClassification().equalsIgnoreCase( target_classification )){
-										
-										try{
-											renderer = (DeviceMediaRendererManual)template.createInstance( target_name );
-	
-											break;
-											
-										}catch( Throwable e ){
-											
-											log( "Failed to add device", e );
-										}
-									}
-								}
-								
-								if ( renderer == null ){
-									
-										// damn, the above doesn't work until devices is turned on...
-									
-									try{
-										renderer = (DeviceMediaRendererManual)manager.createDevice( Device.DT_MEDIA_RENDERER, target_classification, target_name );
-										
-									}catch( Throwable e ){
-										
-										log( "Failed to add device", e );
-									}
-								}
-								
-								if ( renderer != null ){
-									
-									try{
-										renderer.setAutoCopyToFolder( true );
-										
-										mapDevice( renderer, root, target_directory );
-										
-										return;
-										
-									}catch( Throwable e ){
-										
-										log( "Failed to add device", e );
-									}
-								}
-							}
+					String name = sProdID.startsWith(sVendor) ? "" : sVendor;
+					if (sVendor.length() > 0) {
+						name += " ";
+					}
+					name += sProdID;
+
+					String id = "android.";
+					id += sProdID.replaceAll(" ", ".").toLowerCase();
+					if (sVendor.length() > 0) {
+						id += "." + sVendor.replaceAll(" ", ".").toLowerCase();
+					}
+					
+					if (isWritableUSB) {
+						addDevice(name, id, root, new File(root, "videos"), true);
+					} else {
+						//Fixup old bug where we were adding Samsung hard drives as devices
+						Device existingDevice = getDeviceMediaRendererByClassification(id);
+						if (existingDevice != null) {
+							existingDevice.remove();
 						}
 					}
+					return;
+				} else if (isWritableUSB && sVendor.toLowerCase().equals("rim")) {
+					String name = sVendor;
+  				if (name.length() > 0) {
+  					name += " ";
+  				}
+  				name += sProdID;
+					String id = "";
+					id += sProdID.replaceAll(" ", ".").toLowerCase();
+					if (sVendor.length() > 0) {
+						id += "." + sVendor.replaceAll(" ", ".").toLowerCase();
+					}
+					DeviceMediaRendererManual device = addDevice(name, id, root, new File(root, "videos"), false);
+					if (device != null) {
+						device.setImageID("bb");
+					}
+					return;
 				}
-			});
+				
+				if (!isWritableUSB) {
+					return;
+				}
+
+				if (root.exists()) {
+
+					File[] folders = root.listFiles();
+
+					if (folders != null) {
+
+						Set<String> names = new HashSet<String>();
+
+						for (File file : folders) {
+
+							names.add(file.getName().toLowerCase());
+						}
+
+						if (names.contains("psp") && names.contains("video")) {
+							addDevice("PSP", "sony.PSP", root, new File(root, "VIDEO"), false);
+							return;
+						}
+					}
+				}
+				
+				String pid = MapUtils.getMapString(infoMap, "PID", null);
+				String vid = MapUtils.getMapString(infoMap, "VID", null);
+				if (pid != null && vid != null) {
+					String name = sProdID.startsWith(sVendor) ? "" : sVendor;
+  				if (name.length() > 0) {
+  					name += " ";
+  				}
+  				name += sProdID;
+
+  				String id = "";
+					id += sProdID.replaceAll(" ", ".").toLowerCase();
+					id += "." + pid.toLowerCase();
+					if (sVendor.length() > 0) {
+						id += "." + sVendor.replaceAll(" ", ".").toLowerCase();
+					}
+					id += "." + vid.toLowerCase();
+					
+					// cheap hack to detect the PSP when it has no psp or video dir
+					if (id.equals("\"psp\".ms.02d2.sony.054c")
+							|| id.equals("\"psp\".ms.0381.sony.054c")) {
+						if (addDevice("PSP", "sony.PSP", root, new File(root, "VIDEO"), false) != null) {
+							return;
+						}
+					}
+					
+					addDevice(name, id, root, new File(root, "video"), true);
+				}
+			}
+		});
 	}
 	
+	protected DeviceMediaRenderer getDeviceMediaRendererByClassification(String target_classification) {
+		DeviceImpl[] devices = manager.getDevices();
+		
+		for ( DeviceImpl device: devices ){
+			
+			if ( device instanceof DeviceMediaRenderer ){
+			
+				DeviceMediaRenderer renderer = (DeviceMediaRenderer)device;
+				
+				String classification = renderer.getClassification();
+			
+				if ( classification.equalsIgnoreCase( target_classification )){
+																
+					return renderer;
+				}
+			}
+		}
+
+		return null;
+	}
+
+	protected DeviceMediaRendererManual addDevice(
+			String target_name, 
+			String target_classification,
+			File root,
+			File target_directory,
+			boolean generic)
+	{
+		
+		DeviceMediaRenderer existingDevice = getDeviceMediaRendererByClassification(target_classification);
+		if (existingDevice instanceof DeviceMediaRendererManual ) {
+			mapDevice( (DeviceMediaRendererManual) existingDevice, root, target_directory );
+			
+			existingDevice.setGenericUSB(generic);
+			return (DeviceMediaRendererManual) existingDevice;
+		}
+		
+		DeviceTemplate[] templates = manager.getDeviceTemplates( Device.DT_MEDIA_RENDERER );
+		
+		DeviceMediaRendererManual	renderer = null;
+		
+		for ( DeviceTemplate template: templates ){
+			
+			if ( template.getClassification().equalsIgnoreCase( target_classification )){
+				
+				try{
+					renderer = (DeviceMediaRendererManual)template.createInstance( target_name );
+
+					break;
+					
+				}catch( Throwable e ){
+					
+					log( "Failed to add device", e );
+				}
+			}
+		}
+		
+		if ( renderer == null ){
+			
+				// damn, the above doesn't work until devices is turned on...
+			
+			try{
+				renderer = (DeviceMediaRendererManual)manager.createDevice( Device.DT_MEDIA_RENDERER, null, target_classification, target_name, true );
+				
+			}catch( Throwable e ){
+				
+				log( "Failed to add device", e );
+			}
+		}
+		
+		if ( renderer != null ){
+			
+			try{
+				renderer.setAutoCopyToFolder( true );
+				// This will cause a change event
+				renderer.setGenericUSB(generic);
+				
+				mapDevice( renderer, root, target_directory );
+				
+				return renderer;
+				
+			}catch( Throwable e ){
+				
+				log( "Failed to add device", e );
+			}
+		}
+		return renderer;
+	}
+
 	public void 
 	driveRemoved(
 		final DriveDetectedInfo info )
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
index a8f6272..4045899 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceImpl.java
@@ -1,2149 +1,2528 @@
-/*
- * 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.File;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-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;
-import org.gudy.azureus2.core3.util.FileUtil;
-import org.gudy.azureus2.core3.util.IndentWriter;
-import org.gudy.azureus2.core3.util.LightHashMap;
-import org.gudy.azureus2.core3.util.SystemProperties;
-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;
-import com.aelitis.azureus.core.devices.TranscodeProfile;
-import com.aelitis.azureus.core.devices.TranscodeProvider;
-import com.aelitis.azureus.core.devices.TranscodeTarget;
-import com.aelitis.azureus.core.devices.TranscodeTargetListener;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-import com.aelitis.azureus.util.ImportExportUtils;
-
-public abstract class 
-DeviceImpl
-	implements Device
-{
-	private static final String MY_PACKAGE = "com.aelitis.azureus.core.devices.impl";
-	
-	protected static DeviceImpl
-	importFromBEncodedMapStatic(
-		DeviceManagerImpl	manager,
-		Map					map )
-	
-		throws IOException
-	{
-		String	impl = ImportExportUtils.importString( map, "_impl" );
-		
-		if ( impl.startsWith( "." )){
-			
-			impl = MY_PACKAGE + impl;
-		}
-		
-		try{
-			Class<DeviceImpl> cla = (Class<DeviceImpl>) Class.forName( impl );
-			
-			Constructor<DeviceImpl> cons = cla.getDeclaredConstructor( DeviceManagerImpl.class, Map.class );
-			
-			cons.setAccessible( true );
-			
-			return( cons.newInstance( manager, map ));
-			
-		}catch( Throwable e ){
-
-			Debug.out( "Can't construct device for " + impl, e );
-			
-			throw( new IOException( "Construction failed: " + Debug.getNestedExceptionMessage(e)));
-		}
-	}
-	
-	private static final String PP_REND_WORK_DIR		= "tt_work_dir"; 
-	private static final String PP_REND_DEF_TRANS_PROF	= "tt_def_trans_prof";
-	private static final String PP_REND_TRANS_REQ		= "tt_req";
-	private static final String PP_REND_TRANS_CACHE		= "tt_always_cache";
-	private static final String PP_REND_RSS_PUB			= "tt_rss_pub";
-	
-	protected static final String PP_REND_SHOW_CAT		= "tt_show_cat";
-	
-	protected static final String	PP_IP_ADDRESS 		= "rend_ip";	
-	protected static final String	TP_IP_ADDRESS 		= "DeviceUPnPImpl:ip";	// transient
-	protected static final String	PP_FILTER_FILES 	= "rend_filter";
-	
-	protected static final String	PP_COPY_OUTSTANDING = "copy_outstanding";
-	protected static final String	PP_AUTO_START		= "auto_start";
-	
-	
-	protected static final String	PP_COPY_TO_FOLDER	= "copy_to_folder";
-	protected static final String	PP_AUTO_COPY		= "auto_copy";
-	
-	protected static final String	PP_LIVENESS_DETECTABLE	= "live_det";
-
-	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;
-	
-	private static final String	GENERIC = "generic";
-	
-	
-	private DeviceManagerImpl	manager;
-	private int					type;
-	private String				uid;
-	private String				secondary_uid;
-	private String 				classification;
-	private String				name;
-	private boolean				manual;
-	
-	private boolean			hidden;
-	private long			last_seen;
-	
-	private int				busy_count;
-	private boolean			online;
-	
-	private boolean			transcoding;
-	
-	private Map<String,Object>	persistent_properties 	= new LightHashMap<String, Object>(1);
-
-	private Map<Object,Object>	transient_properties 	= new LightHashMap<Object, Object>(1);
-	
-	private long						device_files_last_mod;
-	private boolean						device_files_dirty;
-	private Map<String,Map<String,?>>	device_files;
-	
-	private WeakReference<Map<String,Map<String,?>>> device_files_ref;
-	
-	private CopyOnWriteList<TranscodeTargetListener>	listeners = new CopyOnWriteList<TranscodeTargetListener>();
-	
-	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,
-		int					_type,
-		String				_uid,
-		String				_classification,
-		boolean				_manual )
-	{
-		this( _manager, _type, _uid, _classification, _manual, _classification );
-	}
-	
-	protected
-	DeviceImpl(
-		DeviceManagerImpl	_manager,
-		int					_type,
-		String				_uid,
-		String				_classification,
-		boolean				_manual,
-		String				_name )
-	{
-		manager			= _manager;
-		type			= _type;
-		uid				= _uid;
-		classification	= _classification;
-		name			= _name;
-		manual			= _manual;
-	}
-	
-	protected
-	DeviceImpl(
-		DeviceManagerImpl	_manager,
-		Map					map )
-	
-		throws IOException
-	{
-		manager	= _manager;
-		
-		type			= (int)ImportExportUtils.importLong( map, "_type" );
-		uid				= ImportExportUtils.importString( map, "_uid" );
-		classification	= ImportExportUtils.importString( map, "_name" );
-		name			= ImportExportUtils.importString( map, "_lname" );
-		
-		if ( name == null ){
-			
-			name = classification;
-		}
-		
-		secondary_uid		= ImportExportUtils.importString( map, "_suid" );
-
-		last_seen	= ImportExportUtils.importLong( map, "_ls" );
-		hidden		= ImportExportUtils.importBoolean( map, "_hide" );	
-		manual		= ImportExportUtils.importBoolean( map, "_man" );
-
-		if ( map.containsKey( "_pprops" )){
-			
-			persistent_properties = (Map<String,Object>)map.get( "_pprops" );
-		}
-	}
-	
-	protected void
-	exportToBEncodedMap(
-		Map					map )
-	
-		throws IOException
-	{
-		String	cla = this.getClass().getName();
-		
-		if ( cla.startsWith( MY_PACKAGE )){
-			
-			cla = cla.substring( MY_PACKAGE.length());
-		}
-		
-		ImportExportUtils.exportString( map, "_impl", cla );
-		ImportExportUtils.exportLong( map, "_type", new Long( type ));
-		ImportExportUtils.exportString( map, "_uid", uid );
-		ImportExportUtils.exportString( map, "_name", classification );
-		ImportExportUtils.exportString( map, "_lname", name );
-		
-		if ( secondary_uid != null ){
-			
-			ImportExportUtils.exportString( map, "_suid", secondary_uid );
-		}
-		
-		ImportExportUtils.exportLong( map, "_ls", new Long( last_seen ));
-		ImportExportUtils.exportBoolean( map, "_hide", hidden );
-		ImportExportUtils.exportBoolean( map, "_man", manual );
-		
-		map.put( "_pprops", persistent_properties );
-	}
-	
-	protected boolean
-	updateFrom(
-		DeviceImpl		other,
-		boolean			is_alive )
-	{
-		if ( type != other.type ){
-			
-			Debug.out( "Inconsistent update operation (type)" );
-			
-			return( false );			
-		}
-		
-		String	o_uid 	= other.uid;
-		String	o_suid	= other.secondary_uid;
-		
-		if ( !uid.equals( o_uid )){
-			
-			boolean borked = false;
-			
-			if ( secondary_uid == null && o_suid == null ){
-			
-				borked = true;
-			
-			}else if ( 	secondary_uid == null && uid.equals( o_suid ) ||
-						o_suid == null && o_uid.equals( secondary_uid ) ||
-						o_suid.equals( secondary_uid )){
-				
-			}else{
-				
-				borked = true;
-			}
-			
-			if ( borked ){
-				
-				Debug.out( "Inconsistent update operation (uids)" );
-				
-				return( false );
-
-			}
-		}
-		
-		if ( !classification.equals( other.classification )){
-			
-			classification	= other.classification;
-			
-			setDirty();
-		}
-		
-		/* don't overwite the name as user may have altered it!
-		if ( !name.equals( other.name )){
-			
-			name	= other.name;
-			
-			setDirty();
-		}
-		*/
-		
-		if ( manual != other.manual ){
-			
-			manual	= other.manual;
-			
-			setDirty();
-		}
-		
-		if ( is_alive ){
-		
-			alive();
-		}
-		
-		return( true );
-	}
-	
-	protected void
-	initialise()
-	{
-		updateStatus( 0 );
-	}
-	
-	protected void
-	destroy()
-	{	
-	}
-	
-	public int
-	getType()
-	{
-		return( type );
-	}
-	
-	public String
-	getID()
-	{
-		return( uid );
-	}
-	
-	protected void
-	setSecondaryID(
-		String		str )
-	{
-		secondary_uid = str;
-	}
-	
-	protected String
-	getSecondaryID()
-	{
-		return( secondary_uid );
-	}
-	
-	public Device
-	getDevice()
-	{
-		return( this );
-	}
-
-	public String
-	getName()
-	{
-		return( name );
-	}
-	
-	public void 
-	setName(
-		String _name ) 
-	{
-		if ( !name.equals( _name )){
-			
-			name = _name;
-			
-			setDirty();
-		}
-	}
-	
-	public String
-	getClassification()
-	{
-		return( classification );
-	}
-	
-	public String
-	getShortDescription()
-	{
-		if ( getRendererSpecies() == DeviceMediaRenderer.RS_ITUNES ){
-			
-			return( "iPhone, iPod, Apple TV" );
-		}
-		
-		return( null );
-	}
-	
-	public int
-	getRendererSpecies()
-	{
-			// note, overridden in itunes
-		
-		if ( classification.equalsIgnoreCase( "PS3" )){
-			
-			return( DeviceMediaRenderer.RS_PS3 );
-			
-		}else if ( classification.equalsIgnoreCase( "XBox 360" )){
-			
-			return( DeviceMediaRenderer.RS_XBOX );
-		
-		}else if ( classification.equalsIgnoreCase( "Wii" )){
-
-			return( DeviceMediaRenderer.RS_WII );
-			
-		}else if ( classification.equalsIgnoreCase( "Browser" )){
-
-			return( DeviceMediaRenderer.RS_BROWSER );
-			
-		}else{
-			
-			return( DeviceMediaRenderer.RS_OTHER );
-		}	
-	}
-	
-	protected String
-	getDeviceClassification()
-	{
-			// note, overridden in itunes
-		
-			// bit of a mess here. First release used name as classification and mapped to 
-			// species + device-classification here.
-			// second release moved to separate name and classification and used the correct
-			// device-classification as the classification
-			// so we deal with both for the moment...
-			// 'generic' means one we don't explicitly support, which are rendereres discovered
-			// by UPnP
-		
-		switch( getRendererSpecies()){
-		
-			case DeviceMediaRenderer.RS_PS3:{
-				
-				return( "sony.PS3" );
-			}
-			case DeviceMediaRenderer.RS_XBOX:{
-				
-				return( "microsoft.XBox" );
-			}
-			case DeviceMediaRenderer.RS_WII:{
-				
-				return( "nintendo.Wii" );
-			}
-			case DeviceMediaRenderer.RS_BROWSER:{
-				
-				return( "browser.generic" );
-			}
-			case DeviceMediaRenderer.RS_OTHER:{
-				
-				if ( isManual()){
-					
-					return( classification );
-				}
-				
-				if ( 	classification.equals( "sony.PSP" ) ||
-						classification.startsWith( "tivo." )){
-					
-					return( classification );	
-				}
-	
-				return( GENERIC );
-			}
-			default:{
-				Debug.out( "Unknown classification" );
-				
-				return( GENERIC );
-			}
-		}
-	}
-	
-	public boolean
-	isGeneric()
-	{
-		return( getDeviceClassification() == GENERIC );
-	}
-	
-	public boolean
-	isManual()
-	{
-		return( manual );
-	}
-	
-	public boolean
-	isHidden()
-	{
-		return( hidden );
-	}
-	
-	public void
-	setHidden(
-		boolean		h )
-	{
-		if ( h != hidden ){
-			
-			hidden	= h;
-			
-			setDirty();
-		}
-	}
-	
-	protected void
-	alive()
-	{
-		last_seen	= SystemTime.getCurrentTime();
-			
-		if ( !online ){
-		
-			online	= true;
-			
-			setDirty( false );
-		}
-	}
-	
-	public boolean
-	isLivenessDetectable()
-	{
-		return( !manual );
-	}
-	
-	public boolean
-	isAlive()
-	{
-		return( online );
-	}
-	
-	protected void
-	dead()
-	{		
-		if ( online ){
-		
-			online	= false;
-			
-			setDirty( false );
-		}
-	}
-	
-	protected void
-	setDirty()
-	{
-		setDirty( true );
-	}
-	
-	protected void
-	setDirty(
-		boolean		save_changes )
-	{
-		manager.configDirty( this, save_changes );
-	}
-	
-	protected void
-	updateStatus(
-		int		tick_count )
-	{	
-	}
-	
-	public void 
-	requestAttention() 
-	{
-		manager.requestAttention( this );
-	}
-	
-	public TranscodeFileImpl[]
-	getFiles()
-	{
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-				}
-				
-				List<TranscodeFile> result = new ArrayList<TranscodeFile>();
-								
-				Iterator<Map.Entry<String,Map<String,?>>> it = device_files.entrySet().iterator();
-					
-				while( it.hasNext()){
-					
-					Map.Entry<String,Map<String,?>> entry = it.next();
-					
-					try{
-						TranscodeFileImpl tf = new TranscodeFileImpl( this, entry.getKey(), device_files );
-						
-						result.add( tf );
-						
-					}catch( Throwable e ){
-						
-						it.remove();
-						
-						log( "Failed to deserialise transcode file", e );
-					}
-				}
-				
-				return( result.toArray( new TranscodeFileImpl[ result.size() ]));
-			}
-		}catch( Throwable e ){
-			
-			Debug.out( e );
-			
-			return( new TranscodeFileImpl[0] );
-		}
-	}
-	
-	public TranscodeFileImpl
-	allocateFile(
-		TranscodeProfile		profile,
-		boolean					no_xcode,
-		DiskManagerFileInfo		file,
-		boolean					for_job )
-	
-		throws TranscodeException
-	{
-		TranscodeFileImpl	result = null;
-		
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-				}
-	
-				String	key = ByteFormatter.encodeString( file.getDownloadHash() ) + ":" + file.getIndex() + ":" + profile.getUID();
-								
-				if ( device_files.containsKey( key )){
-				
-					try{					
-						result = new TranscodeFileImpl( this, key, device_files );
-						
-					}catch( Throwable e ){
-						
-						device_files.remove( key );
-						
-						log( "Failed to deserialise transcode file", e );
-					}
-				}
-				
-				if ( result == null ){
-							
-					String ext = profile.getFileExtension();
-					
-					String	target_file = file.getFile().getName();
-					
-					if ( ext != null && !no_xcode ){
-						
-						int	pos = target_file.lastIndexOf( '.' );
-						
-						if ( pos != -1 ){
-							
-							target_file = target_file.substring( 0, pos ); 
-						}
-						
-						target_file += ext;
-					}
-						
-					target_file = allocateUniqueFileName( target_file );
-					
-					File output_file = getWorkingDirectory( true );
-	
-					output_file = new File( output_file.getAbsoluteFile(), target_file );
-	
-					result = new TranscodeFileImpl( this, key, profile.getName(), device_files, output_file, for_job );
-							
-					result.setSourceFile( file );
-					
-					saveDeviceFile();
-					
-				}else{
-					
-					result.setSourceFile( file );
-					
-					result.setProfileName( profile.getName());
-				}
-			}
-		}catch( Throwable e ){
-			
-			throw( new TranscodeException( "File allocation failed", e ));
-		}
-		
-		for ( TranscodeTargetListener l: listeners ){
-			
-			try{
-				l.fileAdded( result );
-				
-			}catch( Throwable e ){
-				
-				Debug.out( e );
-			}
-		}
-		
-		return( result );
-	}
-	
-	protected String
-	allocateUniqueFileName(
-		String		str )
-	{
-		Set<String> name_set = new HashSet<String>();
-		
-		for (Map<String,?> entry: device_files.values()){
-			
-			try{
-				name_set.add( new File( ImportExportUtils.importString( entry, TranscodeFileImpl.KEY_FILE )).getName());
-				
-			}catch( Throwable e ){
-				
-				Debug.out( e );
-			}
-		}
-
-		for (int i=0;i<1024;i++){
-			
-			String	test_name = i==0?str:( i + "_" + str);
-			
-			if ( !name_set.contains( test_name )){
-			
-				str = test_name;
-				
-				break;
-			}				
-		}
-		
-		return( str );
-	}
-	
-	protected void
-	revertFileName(
-		TranscodeFileImpl	tf )
-	
-		throws TranscodeException
-	{
-		File cache_file = tf.getCacheFile();
-		
-		if ( cache_file.exists()){
-			
-			Debug.out( "Cache file already allocated, can't rename" );
-			
-			return;
-		}
-		
-		File source_file = tf.getSourceFile().getFile();
-		
-		String	original_name = source_file.getName();
-		
-		int pos = original_name.indexOf('.');
-		
-		if ( pos == -1 ){
-			
-			return;
-		}
-		
-		String	cf_name = cache_file.getName();
-		
-		if ( cf_name.endsWith( original_name.substring(pos))){
-			
-			return;
-		}
-		
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-				}
-				
-				String reverted_name = allocateUniqueFileName( original_name );
-				
-				tf.setCacheFile( new File( cache_file.getParentFile(), reverted_name ));
-			}
-		}catch( Throwable e ){
-			
-			throw( new TranscodeException( "File name revertion failed", e ));
-		}
-	}
-	
-	public TranscodeFileImpl
-	lookupFile(
-		TranscodeProfile		profile,
-		DiskManagerFileInfo		file )
-	{
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-				}
-	
-				String	key = ByteFormatter.encodeString( file.getDownloadHash() ) + ":" + file.getIndex() + ":" + profile.getUID();
-								
-				if ( device_files.containsKey( key )){
-				
-					try{					
-						return( new TranscodeFileImpl( this, key, device_files ));
-						
-					}catch( Throwable e ){
-						
-						device_files.remove( key );
-						
-						log( "Failed to deserialise transcode file", e );
-					}
-				}
-			}
-		}catch( Throwable e ){
-		}
-		
-		return( null );
-	}
-	
-	protected TranscodeFileImpl
-	getTranscodeFile(
-		String		key )
-	{
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-				}
-									
-				if ( device_files.containsKey( key )){
-				
-					try{					
-
-						return( new TranscodeFileImpl( this, key, device_files ));
-						
-				}	catch( Throwable e ){
-						
-						device_files.remove( key );
-						
-						log( "Failed to deserialise transcode file", e );
-					}
-				}
-			}
-		}catch( Throwable e ){
-		}
-		
-		return( null );
-	}
-	
-	public File
-	getWorkingDirectory()
-	{
-		return( getWorkingDirectory( false ));
-	}
-	
-	public File
-	getWorkingDirectory(
-		boolean	persist )
-	{				
-		String result = getPersistentStringProperty( PP_REND_WORK_DIR );
-		
-		if ( result.length() == 0 ){
-			
-			File f = manager.getDefaultWorkingDirectory( persist );
-			
-			if ( persist ){
-			
-				f.mkdirs();
-			}
-			
-			String	name = FileUtil.convertOSSpecificChars( getName(), true );
-			
-			for (int i=0;i<1024;i++){
-				
-				String test_name = name + (i==0?"":("_"+i));
-				
-				File test_file = new File( f, test_name );
-				
-				if ( !test_file.exists()){
-			
-					f = test_file;
-					
-					break;
-				}
-			}
-			
-			result = f.getAbsolutePath();
-			
-			if ( persist ){
-			
-				setPersistentStringProperty( PP_REND_WORK_DIR, result );
-			}
-		}
-		
-		File f_result = new File( result );
-		
-		if ( !f_result.exists()){
-			
-			if ( persist ){
-			
-				f_result.mkdirs();
-			}
-		}
-		
-		return( f_result );
-	}
-	
-	public void
-	setWorkingDirectory(
-		File		directory )
-	{
-		setPersistentStringProperty( PP_REND_WORK_DIR, directory.getAbsolutePath());
-	}
-
-	protected void
-	resetWorkingDirectory()
-	{
-		setPersistentStringProperty( PP_REND_WORK_DIR, "" );
-	}
-	
-	public TranscodeProfile[]
-	getTranscodeProfiles()
-	{		
-		List<TranscodeProfile>	profiles = new ArrayList<TranscodeProfile>();
-		
-		DeviceManagerImpl dm = getManager();
-		
-		TranscodeManagerImpl tm = dm.getTranscodeManager();
-				
-		TranscodeProvider[] providers = tm.getProviders();
-				
-		String classification = getDeviceClassification();
-		
-		for ( TranscodeProvider provider: providers ){
-			
-			TranscodeProfile[] ps = provider.getProfiles();
-			
-			for ( TranscodeProfile p : ps ){
-				
-				String c = p.getDeviceClassification();
-				
-				if ( c == null ){
-					
-					log( "Device classification missing for " + p.getName());
-					
-				}else{
-					if ( c.toLowerCase().startsWith( classification.toLowerCase())){
-						
-						profiles.add( p );
-					}
-				}
-			}
-		}
-		
-		return( profiles.toArray( new TranscodeProfile[profiles.size()] ));
-	}
-		
-	public TranscodeProfile
-	getDefaultTranscodeProfile()
-	{
-		String uid = getPersistentStringProperty( PP_REND_DEF_TRANS_PROF );
-		
-		DeviceManagerImpl dm = getManager();
-		
-		TranscodeManagerImpl tm = dm.getTranscodeManager();
-
-		TranscodeProfile profile = tm.getProfileFromUID( uid );
-		
-		if ( profile != null ){
-			
-			return( profile );
-		}
-	
-		return( null );
-	}
-	
-	public void
-	setDefaultTranscodeProfile(
-		TranscodeProfile		profile )
-	{
-		if ( profile == null ){
-		
-			removePersistentProperty( PP_REND_DEF_TRANS_PROF );
-			
-		}else{
-			
-			setPersistentStringProperty( PP_REND_DEF_TRANS_PROF, profile.getUID());
-		}
-	}
-	
-	protected void
-	setTranscoding(
-		boolean		_transcoding )
-	{
-		transcoding = _transcoding;
-		
-		manager.deviceChanged( this, false );
-	}
-	
-	public boolean
-	isTranscoding()
-	{
-		return( transcoding );
-	}
-	
-	public int
-	getTranscodeRequirement()
-	{
-		return( getPersistentIntProperty( PP_REND_TRANS_REQ, TranscodeTarget.TRANSCODE_WHEN_REQUIRED ));
-	}
-	
-	public void
-	setTranscodeRequirement(
-		int		req )
-	{
-		setPersistentIntProperty( PP_REND_TRANS_REQ, req );
-	}
-	
-	public boolean
-	isAudioCompatible(
-		TranscodeFile		file )
-	{
-		return( false );
-	}
-	
-	public boolean
-	getAlwaysCacheFiles()
-	{
-		return( getPersistentBooleanProperty( PP_REND_TRANS_CACHE, false ));
-	}
-	
-	public void
-	setAlwaysCacheFiles(
-		boolean		always_cache )
-	{
-		setPersistentBooleanProperty( PP_REND_TRANS_CACHE, always_cache );
-	}
-	
-	public boolean
-	isRSSPublishEnabled()
-	{
-		return( getPersistentBooleanProperty( PP_REND_RSS_PUB, true ));
-	}
-	
-	public void
-	setRSSPublishEnabled(
-		boolean		enabled )
-	{
-		setPersistentBooleanProperty( PP_REND_RSS_PUB, enabled );
-	}
-	
-	public String[][] 
-	getDisplayProperties() 
-	{
-		List<String[]> dp = new ArrayList<String[]>();
-		
-	    getDisplayProperties( dp );
-	    	    
-	    String[][] res = new String[2][dp.size()];
-	   
-	    int	pos = 0;
-	    
-	    for ( String[] entry: dp ){
-	    
-	    	res[0][pos] = entry[0];
-	    	res[1][pos] = entry[1];
-	    	
-	    	pos++;
-	    }
-	    
-	    return( res );
-	}
-	
-	protected void
-	getDisplayProperties(
-		List<String[]>	dp )
-	{
-		if ( !name.equals( classification )){
-			
-			addDP( dp, "TableColumn.header.name", name );
-		}
-		
-		addDP( dp, "TableColumn.header.class", classification.toLowerCase());
-		
-		addDP( dp, "!UID!", getID());
-		
-		if ( !manual ){
-		
-			addDP( dp, "azbuddy.ui.table.online",  online );
-		
-			addDP( dp, "device.lastseen", last_seen==0?"":new SimpleDateFormat().format(new Date( last_seen )));
-		}
-	}
-	
-	protected void
-	getTTDisplayProperties(
-		List<String[]>	dp )
-	{
-		addDP( dp, "devices.xcode.working_dir", getWorkingDirectory( false ).getAbsolutePath());
-	
-		addDP( dp, "devices.xcode.prof_def", getDefaultTranscodeProfile());
-		
-		addDP( dp, "devices.xcode.profs", getTranscodeProfiles());
-		
-		int	tran_req = getTranscodeRequirement();
-		
-		String	tran_req_str;
-		
-		if ( tran_req == TranscodeTarget.TRANSCODE_ALWAYS ){
-			
-			 tran_req_str = "device.xcode.always";
-			 
-		}else if ( tran_req == TranscodeTarget.TRANSCODE_NEVER ){
-			
-			 tran_req_str = "device.xcode.never";
-		}else{
-			
-			 tran_req_str = "device.xcode.whenreq";
-		}
-		
-		addDP( dp, "device.xcode", MessageText.getString( tran_req_str ));
-	}
-	
-	protected void
-	addDP(
-		List<String[]>	dp,
-		String			name,
-		String			value )
-	{
-		dp.add( new String[]{ name, value });
-	}
-	
-	protected void
-	addDP(
-		List<String[]>	dp,
-		String			name,
-		File			value )
-	{
-		dp.add( new String[]{ name, value==null?"":value.getAbsolutePath() });
-	}
-	protected void
-	addDP(
-		List<String[]>	dp,
-		String			name,
-		String[]		values )
-	{
-		String value = "";
-		
-		for ( String v: values ){
-			
-			value += (value.length()==0?"":",") + v;
-		}
-		
-		dp.add( new String[]{ name, value });
-	}
-	
-	protected void
-	addDP(
-		List<String[]>	dp,
-		String			name,
-		boolean			value )
-	{
-		dp.add( new String[]{ name, MessageText.getString( value?"GeneralView.yes":"GeneralView.no" ) });
-	}
-	
-	
-	protected void
-	addDP(
-		List<String[]>		dp,
-		String				name,
-		TranscodeProfile	value )
-	{
-		addDP( dp, name, value==null?"":value.getName());
-	}
-	
-	protected void
-	addDP(
-		List<String[]>		dp,
-		String				name,
-		TranscodeProfile[]	values )
-	{
-		String[]	names = new String[values.length];
-		
-		for (int i=0;i<values.length;i++){
-			
-			names[i] = values[i].getName();
-		}
-		
-		addDP( dp, name, names);
-	}
-	
-	public boolean
-	canRemove()
-	{
-		return( true );
-	}
-	
-	public boolean
-	isBusy()
-	{
-		if ( isTranscoding()){
-			
-			return( true );
-		}
-		
-		synchronized( this ){
-			
-			return( busy_count > 0 );
-		}
-	}
-	
-	protected void
-	setBusy(
-		boolean	busy )
-	{
-		boolean	changed = false;
-		
-		synchronized( this ){	
-			
-			if ( busy ){
-		
-				changed = busy_count++ == 0; 
-				
-			}else{
-				
-				changed = busy_count-- == 1; 
-			}
-		}
-		
-		if ( changed ){
-			
-			manager.deviceChanged( this, false );
-		}
-	}
-	
-	public void
-	remove()
-	{
-		manager.removeDevice( this );
-	}
-	
-	public String
-	getPersistentStringProperty(
-		String		prop )
-	{
-		return( getPersistentStringProperty( prop, "" ));
-	}
-	
-	public String
-	getPersistentStringProperty(
-		String		prop,
-		String		def )
-	{
-		synchronized( persistent_properties ){
-			
-			try{
-				byte[]	value = (byte[])persistent_properties.get( prop );
-		
-				if ( value == null ){
-					
-					return( def );
-				}
-				
-				return( new String( value, "UTF-8" ));
-				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e);
-				
-				return( def );
-			}
-		}
-	}
-	
-	public void
-	setPersistentStringProperty(
-		String		prop,
-		String		value )
-	{
-		boolean	dirty = false;
-		
-		synchronized( persistent_properties ){
-			
-			String existing = getPersistentStringProperty( prop );
-			
-			if ( !existing.equals( value )){
-				
-				try{
-					if ( value == null ){
-						
-						persistent_properties.remove( prop );
-						
-					}else{
-					
-						persistent_properties.put( prop, value.getBytes( "UTF-8" ));
-					}
-					
-					dirty = true;
-					
-				}catch( Throwable e ){
-					
-					Debug.printStackTrace(e);
-				}
-			}
-		}
-		
-		if ( dirty ){
-			
-			setDirty();
-		}
-	}
-	
-	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 )
-	{
-		boolean	dirty = false;
-		
-		synchronized( persistent_properties ){
-			
-			String existing = getPersistentStringProperty( prop );
-			
-			if ( existing != null ){
-				
-				try{
-					persistent_properties.remove( prop );
-					
-					dirty = true;
-					
-				}catch( Throwable e ){
-					
-					Debug.printStackTrace(e);
-				}
-			}
-		}
-		
-		if ( dirty ){
-			
-			setDirty();
-		}
-	}
-	public String
-	getError()
-	{
-		synchronized( errors ){
-
-			if ( errors.size() == 0 ){
-				
-				return( null );
-			}
-			
-			String 	res = "";
-			
-			for ( String s: errors.values()){
-				
-				res += (res.length()==0?"":"; ") + s;
-			}
-			
-			return( res );
-		}
-	}
-	
-	protected void
-	setError(
-		Object	key,
-		String	error )
-	{
-		boolean	changed = false;
-		
-		if ( error == null || error.length() == 0 ){
-			
-			synchronized( errors ){
-			
-				changed = errors.remove( key ) != null;
-			}
-		}else{
-			
-			String	existing;
-			
-			synchronized( errors ){
-				
-				existing = errors.put( key, error );
-			}
-			
-			changed = existing == null || !existing.equals( error );
-		}
-		
-		if ( changed ){
-			
-			manager.deviceChanged( this, false );
-		}
-	}
-	
-	public String
-	getInfo()
-	{
-		synchronized( infos ){
-
-			if ( infos.size() == 0 ){
-				
-				return( null );
-			}
-			
-			String 	res = "";
-			
-			for ( String s: infos.values()){
-				
-				res += (res.length()==0?"":"; ") + s;
-			}
-			
-			return( res );
-		}
-	}
-	
-	protected void
-	setInfo(
-		Object	key,
-		String	info )
-	{
-		boolean	changed = false;
-		
-		if ( info == null || info.length() == 0 ){
-			
-			synchronized( infos ){
-			
-				changed = infos.remove( key ) != null;
-			}
-		}else{
-			
-			String	existing;
-			
-			synchronized( infos ){
-				
-				existing = infos.put( key, info );
-			}
-			
-			changed = existing == null || !existing.equals( info );
-		}
-		
-		if ( changed ){
-			
-			manager.deviceChanged( this, false );
-		}
-	}
-	
-	public boolean
-	getPersistentBooleanProperty(
-		String		prop,
-		boolean		def )
-	{
-		return( getPersistentStringProperty( prop, def?"true":"false" ).equals( "true" ));
-	}
-	
-	public void
-	setPersistentBooleanProperty(
-		String		prop,
-		boolean		value )
-	{
-		setPersistentStringProperty(prop, value?"true":"false" );
-	}
-	
-	public int
-	getPersistentIntProperty(
-		String		prop,
-		int			def )
-	{
-		return( Integer.parseInt( getPersistentStringProperty( prop, String.valueOf(def) )));
-	}
-	
-	public void
-	setPersistentIntProperty(
-		String		prop,
-		int			value )
-	{
-		setPersistentStringProperty(prop, String.valueOf( value ));
-	}
-	
-	public String[]
-	getPersistentStringListProperty(
-		String		prop )
-	{
-		synchronized( persistent_properties ){
-			
-			try{
-				List<byte[]>	values = (List<byte[]>)persistent_properties.get( prop );
-		
-				if ( values == null ){
-					
-					return( new String[0] );
-				}
-				
-				String[]	res = new String[values.size()];
-				
-				int	pos = 0;
-				
-				for (byte[] value: values ){
-				
-					res[pos++] = new String( value, "UTF-8" );
-				}
-				
-				return( res );
-				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e);
-				
-				return( new String[0] );
-			}
-		}
-	}
-	
-	public void
-	setPersistentStringListProperty(
-		String			prop,
-		String[]		values )
-	{
-		boolean dirty = false;
-
-		synchronized( persistent_properties ){
-			
-			try{
-				List<byte[]> values_list = new ArrayList<byte[]>();
-				
-				for (String value: values ){
-					
-					values_list.add( value.getBytes( "UTF-8" ));
-				}
-				
-				persistent_properties.put( prop, values_list );
-				
-				dirty = true;
-				
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e);
-			}
-		}
-		
-		if ( dirty ){
-			
-			setDirty();
-		}
-	}
-	
-	public void
-	setTransientProperty(
-		Object		key,
-		Object		value )
-	{
-		synchronized( transient_properties ){
-			
-			if ( value == null ){
-				
-				transient_properties.remove( key );
-				
-			}else{
-			
-				transient_properties.put( key, value );
-			}
-		}
-	}
-	
-	public Object
-	getTransientProperty(
-		Object		key )
-	{
-		synchronized( transient_properties ){
-			
-			return( transient_properties.get( key ));
-		}
-	}
-	
-	public void
-	setTransientProperty(
-		Object		key1,
-		Object		key2,
-		Object		value )
-	{
-		synchronized( transient_properties ){
-			
-			Map<Object,Object> l1 = (Map<Object,Object>)transient_properties.get( key1 );
-			
-			if ( l1 == null ){
-				
-				if ( value == null ){
-					
-					return;
-				}
-				
-				l1 = new HashMap<Object, Object>();
-				
-				transient_properties.put( key1, l1 );
-			}
-			
-			if ( value == null ){
-				
-				l1.remove( key2 );
-				
-				if ( l1.size() == 0 ){
-					
-					transient_properties.remove( key1 );	
-				}
-			}else{
-				
-				l1.put( key2, value );
-			}
-		}
-	}
-	
-	public Object
-	getTransientProperty(
-		Object		key1,
-		Object		key2 )
-	{
-		synchronized( transient_properties ){
-			
-			Map<Object,Object> l1 = (Map<Object,Object>)transient_properties.get( key1 );
-			
-			if ( l1 == null ){
-				
-				return( null );
-			}
-
-			return( l1.get( key2 ));
-		}
-	}
-	
-	protected void
-	close()
-	{
-		synchronized( this ){
-
-			if ( device_files_dirty ){
-				
-				saveDeviceFile();
-			}
-		}
-	}
-	
-	protected void
-	loadDeviceFile()
-	
-		throws IOException
-	{
-		device_files_last_mod = SystemTime.getMonotonousTime();
-		
-		if ( device_files_ref != null ){
-		
-			device_files = device_files_ref.get();
-		}
-		
-		if ( device_files == null ){
-			
-			Map	map = FileUtil.readResilientFile( getDeviceFile());
-	
-			device_files = (Map<String,Map<String,?>>)map.get( "files" );
-			
-			if ( device_files == null ){
-				
-				device_files = new HashMap<String, Map<String,?>>();
-			}
-		
-			device_files_ref = new WeakReference<Map<String,Map<String,?>>>( device_files );
-			
-			log( "Loaded device file for " + getName() + ": files=" + device_files.size());
-		}
-		
-		final int GC_TIME = 15000;
-		
-		new DelayedEvent( 
-			"Device:gc", 
-			GC_TIME,
-			new AERunnable()
-			{
-				public void
-				runSupport()
-				{
-					synchronized( DeviceImpl.this ){
-						
-						if ( SystemTime.getMonotonousTime() - device_files_last_mod >= GC_TIME ){
-								
-							if ( device_files_dirty ){
-								
-								saveDeviceFile();
-							}
-							
-							device_files = null;
-							
-						}else{
-							
-							new DelayedEvent( "Device:gc2", GC_TIME, this );
-						}
-					}
-				}
-			});
-	}
-	
-	protected URL
-	getStreamURL(
-		TranscodeFileImpl		file,
-		String					host )
-	{
-		return( manager.getStreamURL( file, host ));
-	}
-	
-	protected String
-	getMimeType(
-		TranscodeFileImpl		file )
-	{
-		return( manager.getMimeType( file ));
-	}
-	
-	protected void
-	deleteFile(
-		TranscodeFileImpl	file,
-		boolean				delete_contents,
-		boolean				remove )
-	
-		throws TranscodeException 
-	{	
-		if ( file.isDeleted()){
-			
-			return;
-		}
-		
-		if ( delete_contents ){
-			
-			File f = file.getCacheFile();
-				
-			int	 time = 0;
-			
-			while( f.exists() && !f.delete()){
-						
-				if ( time > 3000 ){
-				
-					log( "Failed to remove file '" + f.getAbsolutePath() + "'" );
-					
-					break;
-					
-				}else{
-					
-					try{
-						Thread.sleep(500);
-						
-					}catch( Throwable e ){
-						
-					}
-					
-					time += 500;
-				}
-			}
-		}
-		
-		if ( remove ){
-			
-			try{
-				synchronized( this ){
-					
-					if ( device_files == null ){
-						
-						loadDeviceFile();
-						
-					}else{
-						
-						device_files_last_mod = SystemTime.getMonotonousTime();
-					}
-					
-					device_files.remove( file.getKey());
-					
-					device_files_dirty	= true;
-				}
-				
-				for ( TranscodeTargetListener l: listeners ){
-					
-					try{
-						l.fileRemoved( file );
-						
-					}catch( Throwable e ){
-						
-						Debug.out( e );
-					}
-				}
-			}catch( Throwable e ){
-				
-				throw( new TranscodeException( "Delete failed", e ));
-			}
-		}
-	}
-	
-	protected void
-	fileDirty(
-		TranscodeFileImpl	file,
-		int					type,
-		Object				data )
-	{
-		try{
-			synchronized( this ){
-				
-				if ( device_files == null ){
-					
-					loadDeviceFile();
-					
-				}else{
-					
-					device_files_last_mod = SystemTime.getMonotonousTime();
-				}
-			}
-			
-			device_files_dirty	= true;
-			
-		}catch( Throwable e ){
-			
-			Debug.out( "Failed to load device file", e );
-		}
-		
-		for ( TranscodeTargetListener l: listeners ){
-			
-			try{
-				l.fileChanged( file, type, data );
-				
-			}catch( Throwable e ){
-				
-				Debug.out( e );
-			}
-		}
-	}
-	
-	protected void
-	saveDeviceFile()
-	{
-		device_files_dirty = false;
-		
-		try{
-			loadDeviceFile();
-			
-			if ( device_files == null || device_files.size()==0 ){
-				
-				FileUtil.deleteResilientFile( getDeviceFile());
-				
-			}else{
-				Map map = new HashMap();
-				
-				map.put( "files", device_files );
-				
-				FileUtil.writeResilientFile( getDeviceFile(), map );
-			}
-		}catch( Throwable e ){
-			
-			Debug.out( "Failed to save device file", e );
-		}
-	}
-	
-	protected File
-	getDeviceFile()
-	
-		throws IOException
-	{
- 		File dir = getDevicesDir();
- 		
- 		return( new File( dir, FileUtil.convertOSSpecificChars(getID(),false) + ".dat" ));
-	}
-	
-	protected File
-	getDevicesDir()
-	
-		throws IOException
-	{
-		File dir = new File(SystemProperties.getUserPath());
-
-		dir = new File( dir, "devices" );
- 		
- 		if ( !dir.exists()){
- 			
- 			if ( !dir.mkdirs()){
- 				
- 				throw( new IOException( "Failed to create '" + dir + "'" ));
- 			}
- 		}	
- 		
- 		return( dir );
-	}
-	
-	protected DeviceManagerImpl
-	getManager()
-	{
-		return( manager );
-	}
-
-	public void
-	addListener(
-		TranscodeTargetListener		listener )
-	{
-		if (!listeners.contains(listener)) {
-			listeners.add( listener );
-		}
-	}
-	
-	public void
-	removeListener(
-		TranscodeTargetListener		listener )
-	{
-		listeners.remove( listener );
-	}
-	
-	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 )
-	{
-		manager.log( str );
-	}
-	
-	protected void
-	log(
-		String		str,
-		Throwable	e )
-	{
-		manager.log( str, e );
-	}
-	
-	public String
-	getString()
-	{
-		return( "type=" + type + ",uid=" + uid + ",class=" + classification );
-	}
-	
-	public void
-	generate(
-		IndentWriter		writer )
-	{
-		writer.println( getName() + "/" + getID() + "/" + type );
-		
-		try{
-			writer.indent();
-			
-			writer.println( 
-				"hidden=" + hidden + 
-				", last_seen=" + new SimpleDateFormat().format(new Date(last_seen)) +
-				", online=" + online +
-				", transcoding=" + transcoding );
-			
-			writer.println( "p_props=" + persistent_properties );
-			writer.println( "t_props=" + transient_properties );
-			
-			writer.println( "errors=" + errors );
-			writer.println( "infos=" + infos );
-		}finally{
-			
-			writer.exdent();
-		}
-	}
-	
-	public void
-	generateTT(
-		IndentWriter		writer )
-	{
-		TranscodeFileImpl[] files = getFiles();
-		
-		int	complete	 = 0;
-		int	copied		 = 0;
-		int	deleted	 	= 0;
-		int	template	 = 0;
-		
-		for ( TranscodeFileImpl f: files ){
-			
-			if ( f.isComplete()){
-				
-				complete++;
-			}
-			
-			if ( f.isCopiedToDevice()){
-				
-				copied++;
-			}
-			
-			if ( f.isDeleted()){
-				
-				deleted++;
-			}
-			
-			if ( f.isTemplate()){
-				
-				template++;
-			}
-		}
-		
-		writer.println( "files=" + files.length + ", comp=" + complete + ", copied=" + copied + ", deleted=" + deleted + ", template=" + template );
-	}
-	
-	protected class
-	browseLocationImpl
-		implements browseLocation
-	{
-		private String		name;
-		private URL			url;
-		
-		protected
-		browseLocationImpl(
-			String		_name,
-			URL			_url )
-		{
-			name		= _name;
-			url			= _url;
-		}
-		
-		public String
-		getName()
-		{
-			return( name );
-		}
-		
-		public URL
-		getURL()
-		{
-			return( url );
-		}
-	}
-}
+/*
+ * 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.File;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+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;
+import com.aelitis.azureus.core.devices.TranscodeProfile;
+import com.aelitis.azureus.core.devices.TranscodeProvider;
+import com.aelitis.azureus.core.devices.TranscodeTarget;
+import com.aelitis.azureus.core.devices.TranscodeTargetListener;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+import com.aelitis.azureus.util.ImportExportUtils;
+import com.aelitis.azureus.util.StringCompareUtils;
+
+public abstract class 
+DeviceImpl
+	implements Device
+{
+	private static final String MY_PACKAGE = "com.aelitis.azureus.core.devices.impl";
+	
+	private static final TranscodeProfile blank_profile = 
+		new TranscodeProfile()
+		{
+			public String
+			getUID()
+			{
+				return( null );
+			}
+			
+			public String
+			getName()
+			{
+				return( "blank" );
+			}
+			
+			public String
+			getDescription()
+			{
+				return( "blank" );
+			}
+			
+			public boolean
+			isStreamable()
+			{
+				return( false );
+			}
+			
+			public String
+			getIconURL()
+			{
+				return( null );
+			}
+			
+			public int 
+			getIconIndex() 
+			{
+				return( 0 );
+			}
+			
+			public String
+			getFileExtension()
+			{
+				return( null );
+			}
+			
+			public String
+			getDeviceClassification()
+			{
+				return( null );
+			}
+			
+			public TranscodeProvider
+			getProvider()
+			{
+				return( null );
+			}
+		};
+		
+	protected static DeviceImpl
+	importFromBEncodedMapStatic(
+		DeviceManagerImpl	manager,
+		Map					map )
+	
+		throws IOException
+	{
+		String	impl = ImportExportUtils.importString( map, "_impl" );
+		
+		if ( impl.startsWith( "." )){
+			
+			impl = MY_PACKAGE + impl;
+		}
+		
+		try{
+			Class<DeviceImpl> cla = (Class<DeviceImpl>) Class.forName( impl );
+			
+			Constructor<DeviceImpl> cons = cla.getDeclaredConstructor( DeviceManagerImpl.class, Map.class );
+			
+			cons.setAccessible( true );
+			
+			return( cons.newInstance( manager, map ));
+			
+		}catch( Throwable e ){
+
+			Debug.out( "Can't construct device for " + impl, e );
+			
+			throw( new IOException( "Construction failed: " + Debug.getNestedExceptionMessage(e)));
+		}
+	}
+	
+	
+	private static List<Pattern> device_renames = new ArrayList<Pattern>();
+	
+	static{
+		try{
+			device_renames.add( Pattern.compile( "TV\\s*+\\(([^\\)]*)\\)", Pattern.CASE_INSENSITIVE ));
+		
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	private static String
+	modifyDeviceDisplayName(
+		String		name )
+	{
+		for ( Pattern p: device_renames ){
+		
+			Matcher m = p.matcher( name );
+		
+			if ( m.find()){
+			
+				String	new_name = m.group(1);
+								
+				return( new_name );
+			}
+		}
+	
+		if ( name.startsWith( "WDTVLIVE")){
+			
+			name = "WD TV Live";
+		}
+		
+		return( name );
+	}
+	
+	private static final String PP_REND_WORK_DIR		= "tt_work_dir"; 
+	private static final String PP_REND_DEF_TRANS_PROF	= "tt_def_trans_prof";
+	private static final String PP_REND_TRANS_REQ		= "tt_req";
+	private static final String PP_REND_TRANS_CACHE		= "tt_always_cache";
+	private static final String PP_REND_RSS_PUB			= "tt_rss_pub";
+	
+	protected static final String PP_REND_SHOW_CAT			= "tt_show_cat";
+	protected static final String PP_REND_CLASSIFICATION	= "tt_rend_class";
+
+	protected static final String	PP_IP_ADDRESS 		= "rend_ip";	
+	protected static final String	TP_IP_ADDRESS 		= "DeviceUPnPImpl:ip";	// transient
+	protected static final String	PP_FILTER_FILES 	= "rend_filter";
+	protected static final String	PP_RESTRICT_ACCESS	= "restrict_access";	
+
+	protected static final String	PP_COPY_OUTSTANDING = "copy_outstanding";
+	protected static final String	PP_AUTO_START		= "auto_start";
+	
+	
+	protected static final String	PP_COPY_TO_FOLDER	= "copy_to_folder";
+	protected static final String	PP_AUTO_COPY		= "auto_copy";
+	protected static final String	PP_EXPORTABLE		= "exportable";
+	
+	protected static final String	PP_LIVENESS_DETECTABLE	= "live_det";
+
+	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;
+
+
+	
+	private static final String	GENERIC = "generic";
+	
+	private static final Object KEY_FILE_ALLOC_ERROR	= new Object();
+
+	private DeviceManagerImpl	manager;
+	private int					type;
+	private String				uid;
+	private String				secondary_uid;
+	private String 				classification;
+	private String				name;
+	private boolean				manual;
+	
+	private boolean			hidden;
+	private boolean 		isGenericUSB;
+	private long			last_seen;
+	private boolean			can_remove = true;
+	private boolean			tagged;
+	
+	private int				busy_count;
+	private boolean			online;
+	
+	private boolean			transcoding;
+	
+	private Map<String,Object>	persistent_properties 	= new LightHashMap<String, Object>(1);
+
+	private Map<Object,Object>	transient_properties 	= new LightHashMap<Object, Object>(1);
+	
+	private long						device_files_last_mod;
+	private boolean						device_files_dirty;
+	private Map<String,Map<String,?>>	device_files;
+	
+	private WeakReference<Map<String,Map<String,?>>> device_files_ref;
+	
+	private CopyOnWriteList<TranscodeTargetListener>	listeners = new CopyOnWriteList<TranscodeTargetListener>();
+	
+	private Map<Object,String>	errors 	= new HashMap<Object, String>();
+	private Map<Object,String>	infos	= new HashMap<Object, String>();
+	
+	private CopyOnWriteList<DeviceListener>		device_listeners;
+
+	private String image_id;
+
+	private boolean isNameAutomatic;
+
+	protected
+	DeviceImpl(
+		DeviceManagerImpl	_manager,
+		int					_type,
+		String				_uid,
+		String				_classification,
+		boolean				_manual )
+	{
+		this( _manager, _type, _uid, _classification, _manual, _classification );
+	}
+	
+	protected
+	DeviceImpl(
+		DeviceManagerImpl	_manager,
+		int					_type,
+		String				_uid,
+		String				_classification,
+		boolean				_manual,
+		String				_name )
+	{
+		manager			= _manager;
+		type			= _type;
+		uid				= _uid;
+		classification	= _classification;
+		name			= modifyDeviceDisplayName( _name );
+		manual			= _manual;
+		isNameAutomatic = true;
+	}
+	
+	protected
+	DeviceImpl(
+		DeviceManagerImpl	_manager,
+		Map					map )
+	
+		throws IOException
+	{
+		manager	= _manager;
+		
+		type				= (int)ImportExportUtils.importLong( map, "_type" );
+		uid					= ImportExportUtils.importString( map, "_uid" );
+		classification		= ImportExportUtils.importString( map, "_name" );
+		name				= ImportExportUtils.importString( map, "_lname" );
+		isNameAutomatic 	= ImportExportUtils.importBoolean( map, "_autoname", true );
+		image_id			= ImportExportUtils.importString( map, "_image_id" );
+		
+		if ( name == null ){
+			
+			name = classification;
+		}
+		
+		if ( ImportExportUtils.importLong( map, "_rn", 0 ) == 0 ){
+		
+			name = modifyDeviceDisplayName( name );
+		}
+		
+		secondary_uid		= ImportExportUtils.importString( map, "_suid" );
+
+		last_seen		= ImportExportUtils.importLong( map, "_ls" );
+		hidden			= ImportExportUtils.importBoolean( map, "_hide" );	
+		can_remove		= ImportExportUtils.importBoolean( map, "_rm", true );	
+		isGenericUSB 	= ImportExportUtils.importBoolean( map, "_genericUSB" );	
+		manual			= ImportExportUtils.importBoolean( map, "_man" );
+		tagged			= ImportExportUtils.importBoolean( map, "_tag", false );	
+
+		if ( map.containsKey( "_pprops" )){
+			
+			persistent_properties = (Map<String,Object>)map.get( "_pprops" );
+		}
+	}
+	
+	protected void
+	exportToBEncodedMap(
+		Map					map,
+		boolean				for_export )
+	
+		throws IOException
+	{
+		String	cla = this.getClass().getName();
+		
+		if ( cla.startsWith( MY_PACKAGE )){
+			
+			cla = cla.substring( MY_PACKAGE.length());
+		}
+		
+		ImportExportUtils.exportString( map, "_impl", cla );
+		ImportExportUtils.exportLong( map, "_type", new Long( type ));
+		ImportExportUtils.exportString( map, "_uid", uid );
+		ImportExportUtils.exportString( map, "_name", classification );
+		ImportExportUtils.exportBoolean( map, "_autoname", isNameAutomatic );
+		ImportExportUtils.exportLong( map, "_rn", 1 );
+		ImportExportUtils.exportString( map, "_lname", name );
+		ImportExportUtils.exportString( map, "_image_id", image_id );
+		
+		if ( secondary_uid != null ){
+			
+			ImportExportUtils.exportString( map, "_suid", secondary_uid );
+		}
+		
+		if ( !for_export ){
+			ImportExportUtils.exportLong( map, "_ls", new Long( last_seen ));
+			ImportExportUtils.exportBoolean( map, "_hide", hidden );
+		}
+		
+		ImportExportUtils.exportBoolean( map, "_rm", can_remove );
+		ImportExportUtils.exportBoolean( map, "_genericUSB", isGenericUSB );	
+		ImportExportUtils.exportBoolean( map, "_man", manual );
+		
+		if ( tagged ){
+			ImportExportUtils.exportBoolean( map, "_tag", tagged );
+		}
+		
+		if ( for_export ){
+			
+			Map<String,Object>	copy = new HashMap<String, Object>( persistent_properties );
+			
+			copy.remove( PP_IP_ADDRESS );
+			copy.remove( PP_COPY_OUTSTANDING );
+			copy.remove( PP_COPY_TO_FOLDER );
+			copy.remove( PP_REND_WORK_DIR );
+			
+			map.put( "_pprops", copy );
+			
+		}else{
+		
+			map.put( "_pprops", persistent_properties );
+		}
+	}
+	
+	protected boolean
+	updateFrom(
+		DeviceImpl		other,
+		boolean			is_alive )
+	{
+		if ( type != other.type ){
+			
+			Debug.out( "Inconsistent update operation (type)" );
+			
+			return( false );			
+		}
+		
+		String	o_uid 	= other.uid;
+		String	o_suid	= other.secondary_uid;
+		
+		if ( !uid.equals( o_uid )){
+			
+			boolean borked = false;
+			
+			if ( secondary_uid == null && o_suid == null ){
+			
+				borked = true;
+			
+			}else if ( 	secondary_uid == null && uid.equals( o_suid ) ||
+						o_suid == null && o_uid.equals( secondary_uid ) ||
+						o_suid.equals( secondary_uid )){
+				
+			}else{
+				
+				borked = true;
+			}
+			
+			if ( borked ){
+				
+				Debug.out( "Inconsistent update operation (uids)" );
+				
+				return( false );
+
+			}
+		}
+		
+		if ( !classification.equals( other.classification )){
+			
+			classification	= other.classification;
+			
+			setDirty();
+		}
+		
+		/* don't overwite the name as user may have altered it!
+		if ( !name.equals( other.name )){
+			
+			name	= other.name;
+			
+			setDirty();
+		}
+		*/
+		
+		if ( manual != other.manual ){
+			
+			manual	= other.manual;
+			
+			setDirty();
+		}
+		
+		if ( is_alive ){
+		
+			alive();
+		}
+		
+		return( true );
+	}
+	
+	public void
+	setExportable(
+		boolean		b )
+	{
+		setPersistentBooleanProperty( PP_EXPORTABLE, b );
+	}
+	
+	public boolean
+	isExportable()
+	{
+		return( getPersistentBooleanProperty( PP_EXPORTABLE, false ));
+	}
+	
+	public VuzeFile 
+	getVuzeFile() 
+	
+		throws IOException
+	{
+		return( manager.exportVuzeFile( this ));
+	}
+	
+	protected void
+	initialise()
+	{
+		updateStatus( 0 );
+	}
+	
+	protected void
+	destroy()
+	{	
+	}
+	
+	public int
+	getType()
+	{
+		return( type );
+	}
+	
+	public String
+	getID()
+	{
+		return( uid );
+	}
+	
+	protected void
+	setSecondaryID(
+		String		str )
+	{
+		secondary_uid = str;
+	}
+	
+	protected String
+	getSecondaryID()
+	{
+		return( secondary_uid );
+	}
+	
+	public String getImageID() {
+		return image_id;
+	}
+	
+	public void setImageID(String id) {
+		if (!StringCompareUtils.equals(id, image_id)) {
+			image_id = id;
+			
+			setDirty();
+		}
+	}
+	
+	public Device
+	getDevice()
+	{
+		return( this );
+	}
+
+	public String
+	getName()
+	{
+		return( name );
+	}
+	
+	public void 
+	setName(
+		String _name,
+		boolean isAutomaticName ) 
+	{
+		if ( !name.equals( _name ) || isNameAutomatic != isAutomaticName ){
+			
+			name = _name;
+			isNameAutomatic = isAutomaticName;
+			
+			setDirty();
+		}
+	}
+	
+	public boolean
+	isNameAutomatic() 
+	{
+		return isNameAutomatic;
+	}
+	
+	public String
+	getClassification()
+	{
+		String explicit_classification = getPersistentStringProperty( PP_REND_CLASSIFICATION, null );
+		
+		if ( explicit_classification != null ){
+			
+			return( explicit_classification );
+		}
+		
+		return( classification );
+	}
+	
+	public String
+	getShortDescription()
+	{
+		if ( getRendererSpecies() == DeviceMediaRenderer.RS_ITUNES ){
+			
+			return( "iPad, iPhone, iPod, Apple TV" );
+		}
+		
+		return( null );
+	}
+	
+	public int
+	getRendererSpecies()
+	{
+			// note, overridden in itunes
+		
+		if ( classification.equalsIgnoreCase( "PS3" )){
+			
+			return( DeviceMediaRenderer.RS_PS3 );
+			
+		}else if ( classification.equalsIgnoreCase( "XBox 360" )){
+			
+			return( DeviceMediaRenderer.RS_XBOX );
+		
+		}else if ( classification.equalsIgnoreCase( "Wii" )){
+
+			return( DeviceMediaRenderer.RS_WII );
+			
+		}else if ( classification.equalsIgnoreCase( "Browser" )){
+
+			return( DeviceMediaRenderer.RS_BROWSER );
+			
+		}else{
+			
+			return( DeviceMediaRenderer.RS_OTHER );
+		}	
+	}
+	
+	protected String
+	getDeviceClassification()
+	{
+			// note, overridden in itunes
+		
+			// bit of a mess here. First release used name as classification and mapped to 
+			// species + device-classification here.
+			// second release moved to separate name and classification and used the correct
+			// device-classification as the classification
+			// so we deal with both for the moment...
+			// 'generic' means one we don't explicitly support, which are rendereres discovered
+			// by UPnP
+		
+		switch( getRendererSpecies()){
+		
+			case DeviceMediaRenderer.RS_PS3:{
+				
+				return( "sony.PS3" );
+			}
+			case DeviceMediaRenderer.RS_XBOX:{
+				
+				return( "microsoft.XBox" );
+			}
+			case DeviceMediaRenderer.RS_WII:{
+				
+				return( "nintendo.Wii" );
+			}
+			case DeviceMediaRenderer.RS_BROWSER:{
+				
+				return( "browser.generic" );
+			}
+			case DeviceMediaRenderer.RS_OTHER:{
+				
+				if ( isManual()){
+					
+					return( classification );
+				}
+				
+				if ( 	classification.equals( "sony.PSP" ) ||
+						classification.startsWith( "tivo." )){
+					
+					return( classification );	
+				}
+				
+				String str = getPersistentStringProperty( PP_REND_CLASSIFICATION, null );
+				
+				if ( str != null ){
+					
+					return( str );
+				}
+	
+				return( GENERIC );
+			}
+			default:{
+				Debug.out( "Unknown classification" );
+				
+				return( GENERIC );
+			}
+		}
+	}
+	
+	public boolean
+	isNonSimple()
+	{
+			// apparently wmp isn't ready for the right chasm
+		
+		return( getClassification().startsWith( "ms_wmp." ) || isGenericUSB());
+	}
+		
+	public boolean
+	isManual()
+	{
+		return( manual );
+	}
+	
+	public boolean
+	isHidden()
+	{
+		return( hidden );
+	}
+	
+	public void
+	setHidden(
+		boolean		h )
+	{
+		if ( h != hidden ){
+			
+			hidden	= h;
+			
+			setDirty();
+		}
+	}
+
+	public boolean
+	isTagged()
+	{
+		return( tagged );
+	}
+	
+	public void
+	setTagged(
+		boolean		t )
+	{
+		if ( t != tagged ){
+			
+			tagged	= t;
+			
+			setDirty();
+		}
+	}
+	
+	public boolean
+	isGenericUSB()
+	{
+		return( isGenericUSB );
+	}
+	
+	public void
+	setGenericUSB(
+		boolean		is )
+	{
+		if ( is != isGenericUSB ){
+			
+			isGenericUSB	= is;
+			
+			setDirty();
+		}
+	}
+	
+	public long
+	getLastSeen() {
+		return last_seen;
+	}
+
+	public void
+	alive()
+	{
+		last_seen	= SystemTime.getCurrentTime();
+			
+		if ( !online ){
+		
+			online	= true;
+			
+			setDirty( false );
+		}
+	}
+	
+	public boolean
+	isLivenessDetectable()
+	{
+		return( !manual );
+	}
+	
+	public boolean
+	isAlive()
+	{
+		return( online );
+	}
+	
+	protected void
+	dead()
+	{		
+		if ( online ){
+		
+			online	= false;
+			
+			setDirty( false );
+		}
+	}
+	
+	public URL
+	getWikiURL()
+	{
+		return( null );
+	}
+	
+	protected void
+	setDirty()
+	{
+		setDirty( true );
+	}
+	
+	protected void
+	setDirty(
+		boolean		save_changes )
+	{
+		manager.configDirty( this, save_changes );
+	}
+	
+	protected void
+	updateStatus(
+		int		tick_count )
+	{	
+	}
+	
+	public void 
+	requestAttention() 
+	{
+		manager.requestAttention( this );
+	}
+	
+	public int
+	getFileCount()
+	{
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+					
+				}
+				
+				return device_files.size();
+			}
+			
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to load device file", e );
+		}
+		
+		return 0;
+	}
+	
+	public TranscodeFileImpl[]
+	getFiles()
+	{
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+				}
+				
+				List<TranscodeFile> result = new ArrayList<TranscodeFile>();
+								
+				Iterator<Map.Entry<String,Map<String,?>>> it = device_files.entrySet().iterator();
+					
+				while( it.hasNext()){
+					
+					Map.Entry<String,Map<String,?>> entry = it.next();
+					
+					try{
+						TranscodeFileImpl tf = new TranscodeFileImpl( this, entry.getKey(), device_files );
+						
+						result.add( tf );
+						
+					}catch( Throwable e ){
+						
+						it.remove();
+						
+						log( "Failed to deserialise transcode file", e );
+					}
+				}
+				
+				return( result.toArray( new TranscodeFileImpl[ result.size() ]));
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( new TranscodeFileImpl[0] );
+		}
+	}
+	
+	public TranscodeFileImpl
+	allocateFile(
+		TranscodeProfile		profile,
+		boolean					no_xcode,
+		DiskManagerFileInfo		file,
+		boolean					for_job )
+	
+		throws TranscodeException
+	{
+		TranscodeFileImpl	result = null;
+		
+		setError( KEY_FILE_ALLOC_ERROR, null );
+		
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+				}
+	
+				String	key = ByteFormatter.encodeString( file.getDownloadHash() ) + ":" + file.getIndex() + ":" + profile.getUID();
+								
+				if ( device_files.containsKey( key )){
+				
+					try{					
+						result = new TranscodeFileImpl( this, key, device_files );
+						
+					}catch( Throwable e ){
+						
+						device_files.remove( key );
+						
+						log( "Failed to deserialise transcode file", e );
+					}
+				}
+				
+				if ( result == null ){
+							
+					String ext = profile.getFileExtension();
+					
+					String	target_file = file.getFile( true ).getName();
+					
+					if ( ext != null && !no_xcode ){
+						
+						int	pos = target_file.lastIndexOf( '.' );
+						
+						if ( pos != -1 ){
+							
+							target_file = target_file.substring( 0, pos ); 
+						}
+						
+						target_file += ext;
+					}
+						
+					target_file = allocateUniqueFileName( target_file );
+					
+					File output_file = getWorkingDirectory( true );
+	
+					if ( !output_file.canWrite()){
+						
+						throw( new TranscodeException( "Can't write to transcode folder '" + output_file.getAbsolutePath() + "'" ));
+					}
+					
+					output_file = new File( output_file.getAbsoluteFile(), target_file );
+	
+					result = new TranscodeFileImpl( this, key, profile.getName(), device_files, output_file, for_job );
+							
+					result.setSourceFile( file );
+					
+					device_files_last_mod = SystemTime.getMonotonousTime();
+					
+					device_files_dirty	= true;
+					
+				}else{
+					
+					result.setSourceFile( file );
+					
+					result.setProfileName( profile.getName());
+				}
+			}
+		}catch( Throwable e ){
+			
+			setError( KEY_FILE_ALLOC_ERROR, Debug.getNestedExceptionMessage( e ));
+
+			throw( new TranscodeException( "File allocation failed", e ));
+		}
+		
+		for ( TranscodeTargetListener l: listeners ){
+			
+			try{
+				l.fileAdded( result );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		return( result );
+	}
+	
+	protected String
+	allocateUniqueFileName(
+		String		str )
+	{
+		Set<String> name_set = new HashSet<String>();
+		
+		for (Map<String,?> entry: device_files.values()){
+			
+			try{
+				name_set.add( new File( ImportExportUtils.importString( entry, TranscodeFileImpl.KEY_FILE )).getName());
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+
+		for (int i=0;i<1024;i++){
+			
+			String	test_name = i==0?str:( i + "_" + str);
+			
+			if ( !name_set.contains( test_name )){
+			
+				str = test_name;
+				
+				break;
+			}				
+		}
+		
+		return( str );
+	}
+	
+	protected void
+	revertFileName(
+		TranscodeFileImpl	tf )
+	
+		throws TranscodeException
+	{
+		File cache_file = tf.getCacheFile();
+		
+		if ( cache_file.exists()){
+			
+			Debug.out( "Cache file already allocated, can't rename" );
+			
+			return;
+		}
+		
+		File source_file = tf.getSourceFile().getFile( true );
+		
+		String	original_name = source_file.getName();
+		
+		int pos = original_name.indexOf('.');
+		
+		if ( pos == -1 ){
+			
+			return;
+		}
+		
+		String	cf_name = cache_file.getName();
+		
+		if ( cf_name.endsWith( original_name.substring(pos))){
+			
+			return;
+		}
+		
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+				}
+				
+				String reverted_name = allocateUniqueFileName( original_name );
+				
+				tf.setCacheFile( new File( cache_file.getParentFile(), reverted_name ));
+			}
+		}catch( Throwable e ){
+			
+			throw( new TranscodeException( "File name revertion failed", e ));
+		}
+	}
+	
+	public TranscodeFileImpl
+	lookupFile(
+		TranscodeProfile		profile,
+		DiskManagerFileInfo		file )
+	{
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+				}
+	
+				String	key = ByteFormatter.encodeString( file.getDownloadHash() ) + ":" + file.getIndex() + ":" + profile.getUID();
+								
+				if ( device_files.containsKey( key )){
+				
+					try{					
+						return( new TranscodeFileImpl( this, key, device_files ));
+						
+					}catch( Throwable e ){
+						
+						device_files.remove( key );
+						
+						log( "Failed to deserialise transcode file", e );
+					}
+				}
+			}
+		}catch( Throwable e ){
+		}
+		
+		return( null );
+	}
+	
+	protected TranscodeFileImpl
+	getTranscodeFile(
+		String		key )
+	{
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+				}
+									
+				if ( device_files.containsKey( key )){
+				
+					try{					
+
+						return( new TranscodeFileImpl( this, key, device_files ));
+						
+				}	catch( Throwable e ){
+						
+						device_files.remove( key );
+						
+						log( "Failed to deserialise transcode file", e );
+					}
+				}
+			}
+		}catch( Throwable e ){
+		}
+		
+		return( null );
+	}
+	
+	public File
+	getWorkingDirectory()
+	{
+		return( getWorkingDirectory( false ));
+	}
+	
+	public File
+	getWorkingDirectory(
+		boolean	persist )
+	{				
+		String result = getPersistentStringProperty( PP_REND_WORK_DIR );
+		
+		if ( result.length() == 0 ){
+			
+			File f = manager.getDefaultWorkingDirectory( persist );
+			
+			if ( persist ){
+			
+				f.mkdirs();
+			}
+			
+			String	name = FileUtil.convertOSSpecificChars( getName(), true );
+			
+			for (int i=0;i<1024;i++){
+				
+				String test_name = name + (i==0?"":("_"+i));
+				
+				File test_file = new File( f, test_name );
+				
+				if ( !test_file.exists()){
+			
+					f = test_file;
+					
+					break;
+				}
+			}
+			
+			result = f.getAbsolutePath();
+			
+			if ( persist ){
+			
+				setPersistentStringProperty( PP_REND_WORK_DIR, result );
+			}
+		}
+		
+		File f_result = new File( result );
+		
+		if ( !f_result.exists()){
+			
+			if ( persist ){
+			
+				f_result.mkdirs();
+			}
+		}
+		
+		return( f_result );
+	}
+	
+	public void
+	setWorkingDirectory(
+		File		directory )
+	{
+		setPersistentStringProperty( PP_REND_WORK_DIR, directory.getAbsolutePath());
+	}
+
+	protected void
+	resetWorkingDirectory()
+	{
+		setPersistentStringProperty( PP_REND_WORK_DIR, "" );
+	}
+	
+	public TranscodeProfile[]
+	getTranscodeProfiles()
+	{
+		return getTranscodeProfiles(true);
+	}
+
+	public TranscodeProfile[]
+	getDirectTranscodeProfiles()
+	{
+		return getTranscodeProfiles(false);
+	}
+
+	
+	public TranscodeProfile[]
+	getTranscodeProfiles(boolean walkup)
+	{		
+		String classification = getDeviceClassification();
+		
+		TranscodeProfile[] result = getTranscodeProfiles( classification );
+		
+		if ( !walkup || result.length > 0 ){
+			
+			return( result );
+		}
+		
+		try{
+			String[]	bits = Constants.PAT_SPLIT_DOT.split(classification);
+			
+				// I would like to drill all the way up to just 'generic' but unfortunately this
+				// would break the current samsung/ms_wmp support that requires the detected profile
+				// set to be empty (we have two existing profiles at the 'generic' level)
+			
+			for ( int i=bits.length-1;i>=1;i--){
+				
+				String c = "";
+				
+				for (int j=0;j<i;j++){
+					
+					c = c + (c.length()==0?"":".") + bits[j];
+				}
+				
+				c = c + (c.length()==0?"":".") + "generic";
+				
+				result = getTranscodeProfiles( c );
+				
+				if ( result.length > 0 ){
+					
+					return( result );
+				}
+			}
+		}catch( Throwable e ){
+	
+			Debug.out( e );
+		}
+		
+		return( new TranscodeProfile[0] );
+	}
+		
+	private TranscodeProfile[]
+	getTranscodeProfiles(
+		String		classification )
+	{		
+		List<TranscodeProfile>	profiles = new ArrayList<TranscodeProfile>();
+		
+		DeviceManagerImpl dm = getManager();
+						
+		TranscodeProvider[] providers = dm.getProviders();
+						
+		for ( TranscodeProvider provider: providers ){
+			
+			TranscodeProfile[] ps = provider.getProfiles( classification );
+			
+			if ( providers.length == 1 ){
+				
+				return( ps );
+			}
+			
+			profiles.addAll( Arrays.asList( ps ));
+		}
+		
+		return( profiles.toArray( new TranscodeProfile[profiles.size()] ));
+	}
+	
+	public TranscodeProfile
+	getDefaultTranscodeProfile()
+	{
+		String uid = getPersistentStringProperty( PP_REND_DEF_TRANS_PROF );
+		
+		DeviceManagerImpl dm = getManager();
+		
+		TranscodeManagerImpl tm = dm.getTranscodeManager();
+
+		TranscodeProfile profile = tm.getProfileFromUID( uid );
+		
+		if ( profile != null ){
+			
+			return( profile );
+		}
+	
+		return( null );
+	}
+	
+	public void
+	setDefaultTranscodeProfile(
+		TranscodeProfile		profile )
+	{
+		if ( profile == null ){
+		
+			removePersistentProperty( PP_REND_DEF_TRANS_PROF );
+			
+		}else{
+			
+			setPersistentStringProperty( PP_REND_DEF_TRANS_PROF, profile.getUID());
+		}
+	}
+	
+	public TranscodeProfile
+	getBlankProfile()
+	{
+		return( blank_profile );
+	}
+	
+	protected void
+	setTranscoding(
+		boolean		_transcoding )
+	{
+		transcoding = _transcoding;
+		
+		manager.deviceChanged( this, false );
+	}
+	
+	public boolean
+	isTranscoding()
+	{
+		return( transcoding );
+	}
+	
+	public int
+	getTranscodeRequirement()
+	{
+		return( getPersistentIntProperty( PP_REND_TRANS_REQ, TranscodeTarget.TRANSCODE_WHEN_REQUIRED ));
+	}
+	
+	public void
+	setTranscodeRequirement(
+		int		req )
+	{
+		setPersistentIntProperty( PP_REND_TRANS_REQ, req );
+	}
+	
+	public boolean
+	isAudioCompatible(
+		TranscodeFile		file )
+	{
+		return( false );
+	}
+	
+	public boolean
+	getAlwaysCacheFiles()
+	{
+		return( getPersistentBooleanProperty( PP_REND_TRANS_CACHE, false ));
+	}
+	
+	public void
+	setAlwaysCacheFiles(
+		boolean		always_cache )
+	{
+		setPersistentBooleanProperty( PP_REND_TRANS_CACHE, always_cache );
+	}
+	
+	public boolean
+	isRSSPublishEnabled()
+	{
+		return( getPersistentBooleanProperty( PP_REND_RSS_PUB, true ));
+	}
+	
+	public void
+	setRSSPublishEnabled(
+		boolean		enabled )
+	{
+		setPersistentBooleanProperty( PP_REND_RSS_PUB, enabled );
+	}
+	
+	public String[][] 
+	getDisplayProperties() 
+	{
+		List<String[]> dp = new ArrayList<String[]>();
+		
+	    getDisplayProperties( dp );
+	    	    
+	    String[][] res = new String[2][dp.size()];
+	   
+	    int	pos = 0;
+	    
+	    for ( String[] entry: dp ){
+	    
+	    	res[0][pos] = entry[0];
+	    	res[1][pos] = entry[1];
+	    	
+	    	pos++;
+	    }
+	    
+	    return( res );
+	}
+	
+	protected void
+	getDisplayProperties(
+		List<String[]>	dp )
+	{
+		if ( !name.equals( classification )){
+			
+			addDP( dp, "TableColumn.header.name", name );
+		}
+		
+		addDP( dp, "TableColumn.header.class", getClassification().toLowerCase());
+		
+		addDP( dp, "!UID!", getID());
+		
+		if ( !manual ){
+		
+			addDP( dp, "azbuddy.ui.table.online",  online );
+		
+			addDP( dp, "device.lastseen", last_seen==0?"":new SimpleDateFormat().format(new Date( last_seen )));
+		}
+	}
+	
+	protected void
+	getTTDisplayProperties(
+		List<String[]>	dp )
+	{
+		addDP( dp, "devices.xcode.working_dir", getWorkingDirectory( false ).getAbsolutePath());
+	
+		addDP( dp, "devices.xcode.prof_def", getDefaultTranscodeProfile());
+		
+		addDP( dp, "devices.xcode.profs", getTranscodeProfiles());
+		
+		int	tran_req = getTranscodeRequirement();
+		
+		String	tran_req_str;
+		
+		if ( tran_req == TranscodeTarget.TRANSCODE_ALWAYS ){
+			
+			 tran_req_str = "device.xcode.always";
+			 
+		}else if ( tran_req == TranscodeTarget.TRANSCODE_NEVER ){
+			
+			 tran_req_str = "device.xcode.never";
+		}else{
+			
+			 tran_req_str = "device.xcode.whenreq";
+		}
+		
+		addDP( dp, "device.xcode", MessageText.getString( tran_req_str ));
+		
+		if ( errors.size() > 0 ){
+			
+			String	key = "ManagerItem.error";		
+			
+			for ( String error: errors.values()){
+				
+				addDP( dp, key, error );
+				
+				key = "";
+			}
+		}
+	}
+	
+	protected void
+	addDP(
+		List<String[]>	dp,
+		String			name,
+		String			value )
+	{
+		dp.add( new String[]{ name, value });
+	}
+	
+	protected void
+	addDP(
+		List<String[]>	dp,
+		String			name,
+		File			value )
+	{
+		dp.add( new String[]{ name, value==null?"":value.getAbsolutePath() });
+	}
+	protected void
+	addDP(
+		List<String[]>	dp,
+		String			name,
+		String[]		values )
+	{
+		String value = "";
+		
+		for ( String v: values ){
+			
+			value += (value.length()==0?"":",") + v;
+		}
+		
+		dp.add( new String[]{ name, value });
+	}
+	
+	protected void
+	addDP(
+		List<String[]>	dp,
+		String			name,
+		boolean			value )
+	{
+		dp.add( new String[]{ name, MessageText.getString( value?"GeneralView.yes":"GeneralView.no" ) });
+	}
+	
+	
+	protected void
+	addDP(
+		List<String[]>		dp,
+		String				name,
+		TranscodeProfile	value )
+	{
+		addDP( dp, name, value==null?"":value.getName());
+	}
+	
+	protected void
+	addDP(
+		List<String[]>		dp,
+		String				name,
+		TranscodeProfile[]	values )
+	{
+		String[]	names = new String[values.length];
+		
+		for (int i=0;i<values.length;i++){
+			
+			names[i] = values[i].getName();
+		}
+		
+		addDP( dp, name, names);
+	}
+	
+	public void
+	setCanRemove(
+		boolean	can )
+	{
+		if ( can_remove != can ){
+		
+			can_remove = can;
+			
+			setDirty();
+		}
+	}
+	
+	public boolean
+	canRemove()
+	{
+		return( can_remove );
+	}
+	
+	public boolean
+	isBusy()
+	{
+		if ( isTranscoding()){
+			
+			return( true );
+		}
+		
+		synchronized( this ){
+			
+			return( busy_count > 0 );
+		}
+	}
+	
+	protected void
+	setBusy(
+		boolean	busy )
+	{
+		boolean	changed = false;
+		
+		synchronized( this ){	
+			
+			if ( busy ){
+		
+				changed = busy_count++ == 0; 
+				
+			}else{
+				
+				changed = busy_count-- == 1; 
+			}
+		}
+		
+		if ( changed ){
+			
+			manager.deviceChanged( this, false );
+		}
+	}
+	
+	public void
+	remove()
+	{
+		manager.removeDevice( this );
+	}
+	
+	public String
+	getPersistentStringProperty(
+		String		prop )
+	{
+		return( getPersistentStringProperty( prop, "" ));
+	}
+	
+	public String
+	getPersistentStringProperty(
+		String		prop,
+		String		def )
+	{
+		synchronized( persistent_properties ){
+			
+			try{
+				byte[]	value = (byte[])persistent_properties.get( prop );
+		
+				if ( value == null ){
+					
+					return( def );
+				}
+				
+				return( new String( value, "UTF-8" ));
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+				
+				return( def );
+			}
+		}
+	}
+	
+	public void
+	setPersistentStringProperty(
+		String		prop,
+		String		value )
+	{
+		boolean	dirty = false;
+		
+		synchronized( persistent_properties ){
+			
+			String existing = getPersistentStringProperty( prop );
+			
+			if ( !existing.equals( value )){
+				
+				try{
+					if ( value == null ){
+						
+						persistent_properties.remove( prop );
+						
+					}else{
+					
+						persistent_properties.put( prop, value.getBytes( "UTF-8" ));
+					}
+					
+					dirty = true;
+					
+				}catch( Throwable e ){
+					
+					Debug.printStackTrace(e);
+				}
+			}
+		}
+		
+		if ( dirty ){
+			
+			setDirty();
+		}
+	}
+	
+	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 )
+	{
+		boolean	dirty = false;
+		
+		synchronized( persistent_properties ){
+			
+			String existing = getPersistentStringProperty( prop );
+			
+			if ( existing != null ){
+				
+				try{
+					persistent_properties.remove( prop );
+					
+					dirty = true;
+					
+				}catch( Throwable e ){
+					
+					Debug.printStackTrace(e);
+				}
+			}
+		}
+		
+		if ( dirty ){
+			
+			setDirty();
+		}
+	}
+	public String
+	getError()
+	{
+		synchronized( errors ){
+
+			if ( errors.size() == 0 ){
+				
+				return( null );
+			}
+			
+			String 	res = "";
+			
+			for ( String s: errors.values()){
+				
+				res += (res.length()==0?"":"; ") + s;
+			}
+			
+			return( res );
+		}
+	}
+	
+	protected void
+	setError(
+		Object	key,
+		String	error )
+	{
+		boolean	changed = false;
+		
+		if ( error == null || error.length() == 0 ){
+			
+			synchronized( errors ){
+			
+				changed = errors.remove( key ) != null;
+			}
+		}else{
+			
+			String	existing;
+			
+			synchronized( errors ){
+				
+				existing = errors.put( key, error );
+			}
+			
+			changed = existing == null || !existing.equals( error );
+		}
+		
+		if ( changed ){
+			
+			manager.deviceChanged( this, false );
+		}
+	}
+	
+	public String
+	getInfo()
+	{
+		synchronized( infos ){
+
+			if ( infos.size() == 0 ){
+				
+				return( null );
+			}
+			
+			String 	res = "";
+			
+			for ( String s: infos.values()){
+				
+				res += (res.length()==0?"":"; ") + s;
+			}
+			
+			return( res );
+		}
+	}
+	
+	protected void
+	setInfo(
+		Object	key,
+		String	info )
+	{
+		boolean	changed = false;
+		
+		if ( info == null || info.length() == 0 ){
+			
+			synchronized( infos ){
+			
+				changed = infos.remove( key ) != null;
+			}
+		}else{
+			
+			String	existing;
+			
+			synchronized( infos ){
+				
+				existing = infos.put( key, info );
+			}
+			
+			changed = existing == null || !existing.equals( info );
+		}
+		
+		if ( changed ){
+			
+			manager.deviceChanged( this, false );
+		}
+	}
+	
+	public String
+	getStatus()
+	{
+		if ( isLivenessDetectable()){
+			
+			if ( isAlive()){
+				
+				return( MessageText.getString( "device.status.online" ));
+				
+			}else{
+				
+				return( MessageText.getString( "device.od.error.notfound" ));
+			}
+		}
+		
+		return( null );
+	}
+	
+	public boolean
+	getPersistentBooleanProperty(
+		String		prop,
+		boolean		def )
+	{
+		return( getPersistentStringProperty( prop, def?"true":"false" ).equals( "true" ));
+	}
+	
+	public void
+	setPersistentBooleanProperty(
+		String		prop,
+		boolean		value )
+	{
+		setPersistentStringProperty(prop, value?"true":"false" );
+	}
+	
+	public int
+	getPersistentIntProperty(
+		String		prop,
+		int			def )
+	{
+		return( Integer.parseInt( getPersistentStringProperty( prop, String.valueOf(def) )));
+	}
+	
+	public void
+	setPersistentIntProperty(
+		String		prop,
+		int			value )
+	{
+		setPersistentStringProperty(prop, String.valueOf( value ));
+	}
+	
+	public String[]
+	getPersistentStringListProperty(
+		String		prop )
+	{
+		synchronized( persistent_properties ){
+			
+			try{
+				List<byte[]>	values = (List<byte[]>)persistent_properties.get( prop );
+		
+				if ( values == null ){
+					
+					return( new String[0] );
+				}
+				
+				String[]	res = new String[values.size()];
+				
+				int	pos = 0;
+				
+				for (byte[] value: values ){
+				
+					res[pos++] = new String( value, "UTF-8" );
+				}
+				
+				return( res );
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+				
+				return( new String[0] );
+			}
+		}
+	}
+	
+	public void
+	setPersistentStringListProperty(
+		String			prop,
+		String[]		values )
+	{
+		boolean dirty = false;
+
+		synchronized( persistent_properties ){
+			
+			try{
+				List<byte[]> values_list = new ArrayList<byte[]>();
+				
+				for (String value: values ){
+					
+					values_list.add( value.getBytes( "UTF-8" ));
+				}
+				
+				persistent_properties.put( prop, values_list );
+				
+				dirty = true;
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+		}
+		
+		if ( dirty ){
+			
+			setDirty();
+		}
+	}
+	
+	public void
+	setTransientProperty(
+		Object		key,
+		Object		value )
+	{
+		synchronized( transient_properties ){
+			
+			if ( value == null ){
+				
+				transient_properties.remove( key );
+				
+			}else{
+			
+				transient_properties.put( key, value );
+			}
+		}
+	}
+	
+	public Object
+	getTransientProperty(
+		Object		key )
+	{
+		synchronized( transient_properties ){
+			
+			return( transient_properties.get( key ));
+		}
+	}
+	
+	public void
+	setTransientProperty(
+		Object		key1,
+		Object		key2,
+		Object		value )
+	{
+		synchronized( transient_properties ){
+			
+			Map<Object,Object> l1 = (Map<Object,Object>)transient_properties.get( key1 );
+			
+			if ( l1 == null ){
+				
+				if ( value == null ){
+					
+					return;
+				}
+				
+				l1 = new HashMap<Object, Object>();
+				
+				transient_properties.put( key1, l1 );
+			}
+			
+			if ( value == null ){
+				
+				l1.remove( key2 );
+				
+				if ( l1.size() == 0 ){
+					
+					transient_properties.remove( key1 );	
+				}
+			}else{
+				
+				l1.put( key2, value );
+			}
+		}
+	}
+	
+	public Object
+	getTransientProperty(
+		Object		key1,
+		Object		key2 )
+	{
+		synchronized( transient_properties ){
+			
+			Map<Object,Object> l1 = (Map<Object,Object>)transient_properties.get( key1 );
+			
+			if ( l1 == null ){
+				
+				return( null );
+			}
+
+			return( l1.get( key2 ));
+		}
+	}
+	
+	protected void
+	close()
+	{
+		synchronized( this ){
+
+			if ( device_files_dirty ){
+				
+				saveDeviceFile();
+			}
+		}
+	}
+	
+	protected void
+	loadDeviceFile()
+	
+		throws IOException
+	{
+		device_files_last_mod = SystemTime.getMonotonousTime();
+		
+		if ( device_files_ref != null ){
+		
+			device_files = device_files_ref.get();
+		}
+		
+		if ( device_files == null ){
+			
+			Map	map = FileUtil.readResilientFile( getDeviceFile());
+	
+			device_files = (Map<String,Map<String,?>>)map.get( "files" );
+			
+			if ( device_files == null ){
+				
+				device_files = new HashMap<String, Map<String,?>>();
+			}
+		
+			device_files_ref = new WeakReference<Map<String,Map<String,?>>>( device_files );
+			
+			log( "Loaded device file for " + getName() + ": files=" + device_files.size());
+		}
+		
+		final int GC_TIME = 15000;
+		
+		new DelayedEvent( 
+			"Device:gc", 
+			GC_TIME,
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					synchronized( DeviceImpl.this ){
+						
+						if ( SystemTime.getMonotonousTime() - device_files_last_mod >= GC_TIME ){
+								
+							if ( device_files_dirty ){
+								
+								saveDeviceFile();
+							}
+							
+							device_files = null;
+							
+						}else{
+							
+							new DelayedEvent( "Device:gc2", GC_TIME, this );
+						}
+					}
+				}
+			});
+	}
+	
+	protected URL
+	getStreamURL(
+		TranscodeFileImpl		file,
+		String					host )
+	{
+		return( manager.getStreamURL( file, host ));
+	}
+	
+	protected String
+	getMimeType(
+		TranscodeFileImpl		file )
+	{
+		return( manager.getMimeType( file ));
+	}
+	
+	protected void
+	deleteFile(
+		TranscodeFileImpl	file,
+		boolean				delete_contents,
+		boolean				remove )
+	
+		throws TranscodeException 
+	{	
+		if ( file.isDeleted()){
+			
+			return;
+		}
+		
+		if ( delete_contents ){
+			
+			File f = file.getCacheFile();
+				
+			int	 time = 0;
+			
+			while( f.exists() && !f.delete()){
+						
+				if ( time > 3000 ){
+				
+					log( "Failed to remove file '" + f.getAbsolutePath() + "'" );
+					
+					break;
+					
+				}else{
+					
+					try{
+						Thread.sleep(500);
+						
+					}catch( Throwable e ){
+						
+					}
+					
+					time += 500;
+				}
+			}
+		}
+		
+		if ( remove ){
+			
+			try{
+					// fire the listeners FIRST as this gives listeners a chance to extract data
+					// from the file before it is deleted (otherwise operations fail with 'file has been
+					// deleted'
+				
+				for ( TranscodeTargetListener l: listeners ){
+					
+					try{
+						l.fileRemoved( file );
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+				
+				synchronized( this ){
+					
+					if ( device_files == null ){
+						
+						loadDeviceFile();
+						
+					}else{
+						
+						device_files_last_mod = SystemTime.getMonotonousTime();
+					}
+					
+					device_files.remove( file.getKey());
+					
+					device_files_dirty	= true;
+				}
+				
+
+			}catch( Throwable e ){
+				
+				throw( new TranscodeException( "Delete failed", e ));
+			}
+		}
+	}
+	
+	protected void
+	fileDirty(
+		TranscodeFileImpl	file,
+		int					type,
+		Object				data )
+	{
+		try{
+			synchronized( this ){
+				
+				if ( device_files == null ){
+					
+					loadDeviceFile();
+					
+				}else{
+					
+					device_files_last_mod = SystemTime.getMonotonousTime();
+				}
+			}
+			
+			device_files_dirty	= true;
+			
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to load device file", e );
+		}
+		
+		for ( TranscodeTargetListener l: listeners ){
+			
+			try{
+				l.fileChanged( file, type, data );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
+	protected void
+	saveDeviceFile()
+	{			
+		device_files_dirty = false;
+		
+		try{
+			loadDeviceFile();
+			
+			if ( device_files == null || device_files.size()==0 ){
+				
+				FileUtil.deleteResilientFile( getDeviceFile());
+				
+			}else{
+				Map map = new HashMap();
+				
+				map.put( "files", device_files );
+				
+				FileUtil.writeResilientFile( getDeviceFile(), map );
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to save device file", e );
+		}
+	}
+	
+	protected File
+	getDeviceFile()
+	
+		throws IOException
+	{
+ 		File dir = getDevicesDir();
+ 		
+ 		return( new File( dir, FileUtil.convertOSSpecificChars(getID(),false) + ".dat" ));
+	}
+	
+	protected File
+	getDevicesDir()
+	
+		throws IOException
+	{
+		File dir = new File(SystemProperties.getUserPath());
+
+		dir = new File( dir, "devices" );
+ 		
+ 		if ( !dir.exists()){
+ 			
+ 			if ( !dir.mkdirs()){
+ 				
+ 				throw( new IOException( "Failed to create '" + dir + "'" ));
+ 			}
+ 		}	
+ 		
+ 		return( dir );
+	}
+	
+	protected DeviceManagerImpl
+	getManager()
+	{
+		return( manager );
+	}
+
+	public void
+	addListener(
+		TranscodeTargetListener		listener )
+	{
+		if (!listeners.contains(listener)) {
+			listeners.add( listener );
+		}
+	}
+	
+	public void
+	removeListener(
+		TranscodeTargetListener		listener )
+	{
+		listeners.remove( listener );
+	}
+	
+	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 )
+	{
+		manager.log( str );
+	}
+	
+	protected void
+	log(
+		String		str,
+		Throwable	e )
+	{
+		manager.log( str, e );
+	}
+	
+	public String
+	getString()
+	{
+		return( "type=" + type + ",uid=" + uid + ",class=" + classification );
+	}
+	
+	public void
+	generate(
+		IndentWriter		writer )
+	{
+		writer.println( getName() + "/" + getID() + "/" + type );
+		
+		try{
+			writer.indent();
+			
+			writer.println( 
+				"hidden=" + hidden + 
+				", last_seen=" + new SimpleDateFormat().format(new Date(last_seen)) +
+				", online=" + online +
+				", transcoding=" + transcoding );
+			
+			writer.println( "p_props=" + persistent_properties );
+			writer.println( "t_props=" + transient_properties );
+			
+			writer.println( "errors=" + errors );
+			writer.println( "infos=" + infos );
+		}finally{
+			
+			writer.exdent();
+		}
+	}
+	
+	public void
+	generateTT(
+		IndentWriter		writer )
+	{
+		TranscodeFileImpl[] files = getFiles();
+		
+		int	complete	 = 0;
+		int	copied		 = 0;
+		int	deleted	 	= 0;
+		int	template	 = 0;
+		
+		for ( TranscodeFileImpl f: files ){
+			
+			if ( f.isComplete()){
+				
+				complete++;
+			}
+			
+			if ( f.isCopiedToDevice()){
+				
+				copied++;
+			}
+			
+			if ( f.isDeleted()){
+				
+				deleted++;
+			}
+			
+			if ( f.isTemplate()){
+				
+				template++;
+			}
+		}
+		
+		writer.println( "files=" + files.length + ", comp=" + complete + ", copied=" + copied + ", deleted=" + deleted + ", template=" + template );
+	}
+	
+	protected class
+	browseLocationImpl
+		implements browseLocation
+	{
+		private String		name;
+		private URL			url;
+		
+		protected
+		browseLocationImpl(
+			String		_name,
+			URL			_url )
+		{
+			name		= _name;
+			url			= _url;
+		}
+		
+		public String
+		getName()
+		{
+			return( name );
+		}
+		
+		public URL
+		getURL()
+		{
+			return( url );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
index d33f585..2e048c8 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerImpl.java
@@ -22,11 +22,14 @@
 package com.aelitis.azureus.core.devices.impl;
 
 import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
 import java.net.URL;
 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.AEDiagnosticsEvidenceGenerator;
 import org.gudy.azureus2.core3.util.AEDiagnosticsLogger;
@@ -41,12 +44,18 @@ import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.core3.util.ListenerManager;
 import org.gudy.azureus2.core3.util.ListenerManagerDispatcher;
 import org.gudy.azureus2.core3.util.SimpleTimer;
+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.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.plugins.tracker.web.TrackerWebPageRequest;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.plugins.utils.PowerManagementListener;
+import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -55,10 +64,16 @@ import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
 import com.aelitis.azureus.core.devices.*;
 import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+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.net.upnp.UPnPDevice;
 
 public class 
 DeviceManagerImpl 
-	implements DeviceManager, DeviceOfflineDownloaderManager, AEDiagnosticsEvidenceGenerator
+	implements DeviceManager, DeviceOfflineDownloaderManager, PowerManagementListener, AEDiagnosticsEvidenceGenerator
 {
 	private static final String	LOGGER_NAME 				= "Devices";
 	private static final String	CONFIG_FILE 				= "devices.config";
@@ -70,17 +85,70 @@ DeviceManagerImpl
 	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 TRANSCODE_DIR_DEFAULT	= "transcodes";
 	
-	private static final String CONFIG_DEFAULT_WORK_DIR	= "devices.config.def_work_dir";
-	
+	private static final String CONFIG_DEFAULT_WORK_DIR		= "devices.config.def_work_dir";
+	private static final String CONFIG_DISABLE_SLEEP		= "devices.config.disable_sleep";
+
 	
 	protected static final int	DEVICE_UPDATE_PERIOD	= 5*1000;
 	
+	private static boolean pre_initialised;
+	
 	private static DeviceManagerImpl		singleton;
 	
 	public static void
 	preInitialise()
 	{
+		synchronized( DeviceManagerImpl.class ){
+			
+			if ( pre_initialised ){
+				
+				return;
+			}
+			
+			pre_initialised = true;
+		}
+		
+		VuzeFileHandler.getSingleton().addProcessor(
+			new VuzeFileProcessor()
+			{
+				public void
+				process(
+					VuzeFile[]		files,
+					int				expected_types )
+				{
+					for (int i=0;i<files.length;i++){
+						
+						VuzeFile	vf = files[i];
+						
+						VuzeFileComponent[] comps = vf.getComponents();
+						
+						for (int j=0;j<comps.length;j++){
+							
+							VuzeFileComponent comp = comps[j];
+							
+							int	type = comp.getType();
+							
+							if ( type == VuzeFileComponent.COMP_TYPE_DEVICE ){
+								
+								try{
+									((DeviceManagerImpl)getSingleton()).importVuzeFile(
+											comp.getContent(),
+											( expected_types & 
+												( VuzeFileComponent.COMP_TYPE_DEVICE )) == 0 );
+									
+									comp.setProcessed();
+									
+								}catch( Throwable e ){
+									
+									Debug.printStackTrace(e);
+								}
+							}
+						}
+					}
+				}
+			});		
 	}
 	
 	public static DeviceManager
@@ -109,6 +177,8 @@ DeviceManagerImpl
 	private DeviceManagerUPnPImpl	upnp_manager;
 	private DeviceDriveManager		drive_manager;
 		
+	private Set<Device>				disable_events	= Collections.synchronizedSet( new HashSet<Device>());
+	
 		// have to go async on this as there are situations where we end up firing listeners
 		// while holding monitors and this can result in deadlock if sync
 	
@@ -142,7 +212,7 @@ DeviceManagerImpl
 							case LT_DEVICE_CHANGED:{
 								
 								if ( deviceAdded( device )){
-								
+									
 									device.fireChanged();
 									
 									listener.deviceChanged( device );
@@ -202,14 +272,19 @@ DeviceManagerImpl
 	
 	private int		explicit_search;
 	
-	private TranscodeManagerImpl	transcode_manager;
+	private volatile TranscodeManagerImpl	transcode_manager;
+	
+	private CopyOnWriteList<DeviceManagerDiscoveryListener>	discovery_listeners = new CopyOnWriteList<DeviceManagerDiscoveryListener>();
 	
 	private int						getMimeType_fails;
 	
+	private Object					logger_lock = new Object();
 	private AEDiagnosticsLogger		logger;
 	
 	private AsyncDispatcher	async_dispatcher = new AsyncDispatcher( 10*1000 );
 
+	private AESemaphore			init_sem = new AESemaphore( "dm:init" );
+	
 	private volatile boolean initialized = false;
 	
 	protected
@@ -224,140 +299,207 @@ DeviceManagerImpl
 		});
 	}
 	
-	private void 
-	initWithCore(
-		final AzureusCore core ) 
+	private TranscodeManager
+	ensureInitialised(
+		boolean 	partial )
 	{
-		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(
-				new String[]{
-					AUTO_SEARCH_CONFIG_KEY,
-				},
-				new ParameterListener()
-				{
-					public void 
-					parameterChanged(
-						String name ) 
-					{
-						auto_search = COConfigurationManager.getBooleanParameter( AUTO_SEARCH_CONFIG_KEY, true );
-					}
-				});
+		AzureusCore core =  AzureusCoreFactory.getSingleton();
 		
-		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();
-						}
-					}
-				});
+		if ( core.isStarted()){
 		
-			// init tivo before upnp as upnp init completion starts up tivo
+			initWithCore( core );
+			
+		}else if ( core.isInitThread()){
+			
+			Debug.out( "This is bad" );
+			
+			initWithCore( core );
+		}
 		
-		tivo_manager = new DeviceTivoManager( this );
-
-		upnp_manager = new DeviceManagerUPnPImpl( this );
-
-		loadConfig();
+		if ( partial ){
+			
+			long start = SystemTime.getMonotonousTime();
+			
+			while( !init_sem.reserve(250)){
 				
-		new DeviceiTunesManager( this );
+				if ( transcode_manager != null ){
+					
+					break;
+				}
 				
-		drive_manager = new DeviceDriveManager( this );
-		
-		transcode_manager = new TranscodeManagerImpl( this );
+				if ( SystemTime.getMonotonousTime() - start >= 30*1000 ){
+					
+					Debug.out( "Timeout waiting for init" );
+					
+					AEDiagnostics.dumpThreads();
+					
+					break;
+				}
+			}
+		}else{
+			if ( !init_sem.reserve( 30*1000 )){
+				
+				Debug.out( "Timeout waiting for init" );
+				
+				AEDiagnostics.dumpThreads();
+			}
+		}
 		
-		core.addLifecycleListener(
-			new AzureusCoreLifecycleAdapter()
-			{
-				public void
-				stopping(
-					AzureusCore		core )
-				{					
-					synchronized( DeviceManagerImpl.this ){
+		return( transcode_manager );
+	}
+	
+	private void 
+	initWithCore(
+		final AzureusCore core ) 
+	{
+		synchronized( this ){
+			
+			if ( azureus_core != null ){
 				
-						if ( config_dirty || config_unclean ){
-							
-							saveConfig();
+				return;
+			}
+		
+			azureus_core = core;
+		}
+		
+		try{
+			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(
+					new String[]{
+						AUTO_SEARCH_CONFIG_KEY,
+					},
+					new ParameterListener()
+					{
+						public void 
+						parameterChanged(
+							String name ) 
+						{
+							auto_search = COConfigurationManager.getBooleanParameter( AUTO_SEARCH_CONFIG_KEY, true );
 						}
-						
-						closing	= true;
-						
-						transcode_manager.close();
-						
-						DeviceImpl[] devices = getDevices();
-						
-						for ( DeviceImpl device: devices ){
+					});
+			
+			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 );
 							
-							device.close();
+							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();
+							}
 						}
-					}
-				}
-			});
-		
-		upnp_manager.initialise();
-		
-		SimpleTimer.addPeriodicEvent(
-				"DeviceManager:update",
-				DEVICE_UPDATE_PERIOD,
-				new TimerEventPerformer()
-				{
-					private int tick_count = 0;
+					});
+			
+				// init tivo before upnp as upnp init completion starts up tivo
+			
+			tivo_manager = new DeviceTivoManager( this );
+	
+			upnp_manager = new DeviceManagerUPnPImpl( this );
+	
+			loadConfig();
 					
-					public void 
-					perform(
-						TimerEvent event ) 
-					{
-						List<DeviceImpl> copy;
-						
-						tick_count++;
-						
-						transcode_manager.updateStatus( tick_count );
-						
+			new DeviceiTunesManager( this );
+					
+			drive_manager = new DeviceDriveManager( this );
+			
+			transcode_manager = new TranscodeManagerImpl( this );
+			
+			transcode_manager.initialise();
+			
+			core.addLifecycleListener(
+				new AzureusCoreLifecycleAdapter()
+				{
+					public void
+					stopping(
+						AzureusCore		core )
+					{					
 						synchronized( DeviceManagerImpl.this ){
-
-							if( device_list.size() == 0 ){
+					
+							if ( config_dirty || config_unclean ){
 								
-								return;
+								saveConfig();
 							}
 							
-							copy = new ArrayList<DeviceImpl>( device_list );
-						}
-						
-						for ( DeviceImpl device: copy ){
+							closing	= true;
+							
+							transcode_manager.close();
 							
-							device.updateStatus( tick_count );
+							DeviceImpl[] devices = getDevices();
+							
+							for ( DeviceImpl device: devices ){
+								
+								device.close();
+							}
 						}
 					}
 				});
-		
-		initialized = true;
-		
-		listeners.dispatch( LT_INITIALIZED, null );
+			
+			upnp_manager.initialise();
+			
+			SimpleTimer.addPeriodicEvent(
+					"DeviceManager:update",
+					DEVICE_UPDATE_PERIOD,
+					new TimerEventPerformer()
+					{
+						private int tick_count = 0;
+						
+						public void 
+						perform(
+							TimerEvent event ) 
+						{
+							List<DeviceImpl> copy;
+							
+							tick_count++;
+							
+							transcode_manager.updateStatus( tick_count );
+							
+							synchronized( DeviceManagerImpl.this ){
+	
+								if( device_list.size() == 0 ){
+									
+									return;
+								}
+								
+								copy = new ArrayList<DeviceImpl>( device_list );
+							}
+							
+							for ( DeviceImpl device: copy ){
+								
+								device.updateStatus( tick_count );
+							}
+						}
+					});
+			
+			initialized = true;
+			
+			listeners.dispatch( LT_INITIALIZED, null );
+			
+			core.addPowerManagementListener( this );
+			
+		}finally{
+			
+			init_sem.releaseForever();
+		}
 	}
 	
 	protected void
@@ -415,6 +557,19 @@ DeviceManagerImpl
 		tivo_manager.setEnabled( enabled );
 	}
 	
+	public TranscodeProvider[]
+	getProviders()
+	{
+		TranscodeManager tm = ensureInitialised( true );
+		
+		if ( tm == null ){
+			
+			return( new TranscodeProvider[0] );
+		}
+		
+		return( tm.getProviders());
+	}
+	
 	public DeviceTemplate[] 
 	getDeviceTemplates(
 		int		device_type )
@@ -500,19 +655,57 @@ DeviceManagerImpl
 		return( map.values().toArray( new DeviceManufacturer[ map.size() ] ));
 	}
 	
+	public Device 
+	addVirtualDevice(
+		int 		type, 
+		String		uid,
+		String		classification,
+		String		name )
+	
+		throws DeviceManagerException
+	{
+		return( createDevice( type, uid, classification, name, true ));
+	}
+	
+	public Device 
+	addInetDevice(
+		int 		type, 
+		String		uid,
+		String		classification,
+		String		name,
+		InetAddress address)
+	
+		throws DeviceManagerException
+	{
+		Device device = createDevice( type, uid, classification, name, false );
+		device.setAddress(address);
+		return device;
+	}
+	
 	protected Device
 	createDevice(
 		int						device_type,
+		String					uid,
 		String					classification,
-		String					name )
+		String					name,
+		boolean					manual )
 	
 		throws DeviceManagerException
 	{
 		if ( device_type == Device.DT_MEDIA_RENDERER ){
 			
-			DeviceImpl res = new DeviceMediaRendererManual( this, classification, true, name );
+			DeviceImpl res;
+			
+			if ( manual ){
+				
+				res = new DeviceMediaRendererManual( this, uid, classification, true, name );
+				
+			}else{
+				
+				res = new DeviceMediaRendererImpl( this, uid, classification, true, name );
+			}
 			
-			addDevice( res );
+			res = addDevice( res );
 			
 			return( res );
 			
@@ -682,16 +875,27 @@ DeviceManagerImpl
 			// so there's no need to blindly fire a change event here
 			// deviceChanged( existing, false );
 			
+			applyUpdates( existing );
+			
 			return( existing );
 		}
-					
-		device.initialise();
 		
-		if ( is_alive ){
+		try{
+			disable_events.add( device );
 		
-			device.alive();
+			device.initialise();
+			
+			if ( is_alive ){
+			
+				device.alive();
+			}
+			
+			applyUpdates( device );
+			
+		}finally{
+			
+			disable_events.remove( device );
 		}
-		
 		deviceAdded( device );
 		
 		configDirty();
@@ -700,6 +904,102 @@ DeviceManagerImpl
 	}
 	
 	protected void
+	applyUpdates(
+		DeviceImpl		device )
+	{
+		if ( device.getType() == Device.DT_MEDIA_RENDERER ){
+			
+			DeviceMediaRenderer renderer = (DeviceMediaRenderer)device;
+			
+			if ( renderer instanceof DeviceUPnPImpl ){
+				
+				UPnPDevice upnp_device = ((DeviceUPnPImpl)renderer).getUPnPDevice();
+				
+				if ( upnp_device != null ){
+					
+					String lc_manufacturer 	= getOptionalLC( upnp_device.getManufacturer());
+					String lc_model			= getOptionalLC( upnp_device.getModelName());
+					String lc_fname			= getOptionalLC( upnp_device.getFriendlyName());
+					
+					if ( lc_manufacturer.startsWith( "samsung" )){
+						
+						device.setPersistentStringProperty( DeviceImpl.PP_REND_CLASSIFICATION, "samsung.generic" );
+						
+						TranscodeProfile[] profiles = device.getTranscodeProfiles();
+						
+						if ( profiles.length == 0 ){
+							
+							device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_NEVER );
+							
+						}else{
+							
+							device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_WHEN_REQUIRED );
+						}
+					}else if ( lc_manufacturer.startsWith( "western digital" )){
+							
+							device.setPersistentStringProperty( DeviceImpl.PP_REND_CLASSIFICATION, "western.digital.generic" );
+							
+							TranscodeProfile[] profiles = device.getTranscodeProfiles();
+							
+							if ( profiles.length == 0 ){
+								
+								device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_NEVER );
+								
+							}else{
+								
+								device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_WHEN_REQUIRED );
+							}
+					}else if ( lc_manufacturer.startsWith( "sony" ) && lc_fname.startsWith( "bravia" )){
+							
+						device.setPersistentStringProperty( DeviceImpl.PP_REND_CLASSIFICATION, "sony.bravia" );
+							
+					}else if ( lc_model.equals( "windows media player" )){
+						
+						String model_number = upnp_device.getModelNumber();
+						
+						if ( model_number != null ){
+							
+							try{
+								int num = Integer.parseInt( model_number );
+								
+								if ( num >= 12 ){
+									
+									device.setPersistentStringProperty( DeviceImpl.PP_REND_CLASSIFICATION, "ms_wmp.generic" );
+									
+									TranscodeProfile[] profiles = device.getTranscodeProfiles();
+									
+									if ( profiles.length == 0 ){
+										
+										device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_NEVER );
+										
+									}else{
+										
+										device.setTranscodeRequirement( TranscodeTarget.TRANSCODE_WHEN_REQUIRED );
+									}
+								}
+							}catch( Throwable e ){
+								
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	private String
+	getOptionalLC(
+		String	str )
+	{
+		if ( str == null ){
+			
+			return( "" );
+		}
+		
+		return( str.toLowerCase().trim());
+	}
+	
+	protected void
 	removeDevice(
 		DeviceImpl		device )
 	{
@@ -730,19 +1030,27 @@ DeviceManagerImpl
 	}
 
 	public boolean
-	isBusy()
+	isBusy(
+		int	device_type )
 	{
-		if ( getTranscodeManager().getQueue().isTranscoding()){
+			// transcoding is rolled into renderers
+		
+		if ( device_type == Device.DT_UNKNOWN || device_type == Device.DT_MEDIA_RENDERER ){
 			
-			return( true );
+			if ( getTranscodeManager().getQueue().isTranscoding()){
+				
+				return( true );
+			}
 		}
 		
-		synchronized( this ){
+		DeviceImpl[] devices = getDevices();
+					
+		for ( DeviceImpl device: devices ){
 			
-			for ( DeviceImpl device: device_list ){
+			if ( device.isBusy()){
+				
+				if ( device_type == Device.DT_UNKNOWN || device_type == device.getType()){
 				
-				if ( device.isBusy()){
-					
 					return( true );
 				}
 			}
@@ -1015,7 +1323,7 @@ DeviceManagerImpl
 					try{
 						Map d = new HashMap();
 						
-						device.exportToBEncodedMap( d );
+						device.exportToBEncodedMap( d, false );
 						
 						l_devices.add( d );
 						
@@ -1064,8 +1372,13 @@ DeviceManagerImpl
 			
 			config_unclean = true;
 		}
-				
-		listeners.dispatch( LT_DEVICE_CHANGED, device );
+			
+		if ( !disable_events.contains( device )){
+		
+			//System.out.println(System.currentTimeMillis() + "] CHANGE -> " + device.getID() + "/" + device.getName() + " via " + Debug.getCompressedStackTrace());
+			
+			listeners.dispatch( LT_DEVICE_CHANGED, device );
+		}
 	}
 	
 	protected void
@@ -1164,13 +1477,26 @@ DeviceManagerImpl
 			
 			String	def_dir = COConfigurationManager.getStringParameter( "Default save path" );
 
-			def = def_dir + File.separator + "transcodes";
+			def = def_dir + File.separator + TRANSCODE_DIR_DEFAULT;
 		}
 		
 		File f = new File( def );
 		
 		if ( !f.exists()){
 		
+				// migration from Azureus Downloads to Vuze Downloads
+			
+			if ( f.getName().equals( TRANSCODE_DIR_DEFAULT )){
+				
+				String	parent = f.getParentFile().getName();
+				
+				if ( parent.equals( "Azureus Downloads" ) || parent.equals( "Vuze Downloads" )){
+					
+					String	def_dir = COConfigurationManager.getStringParameter( "Default save path" );
+
+					f = new File( def_dir, TRANSCODE_DIR_DEFAULT );
+				}
+			}
 			if ( persist ){
 			
 				f.mkdirs();
@@ -1187,25 +1513,41 @@ DeviceManagerImpl
 		File existing = getDefaultWorkingDirectory( false );
 		
 		if ( !existing.getAbsolutePath().equals( dir.getAbsolutePath())){
-		
-			// default has changed, reset all device save locations so that they pick up the change
 			
-			
-			synchronized( this ){
+				// default has changed, reset all device save locations so that they pick up the change
 				
-				for ( DeviceImpl d: device_list ){
-
-					d.resetWorkingDirectory();
-				}
+			DeviceImpl[] devices = getDevices();
+			
+			for ( DeviceImpl device: devices ){
+		
+				device.resetWorkingDirectory();
 			}
 		}
 		
 		COConfigurationManager.setParameter( CONFIG_DEFAULT_WORK_DIR, dir.getAbsolutePath());
 	}
 	
+	public boolean
+	getDisableSleep()
+	{
+		return( COConfigurationManager.getBooleanParameter( CONFIG_DISABLE_SLEEP, true ));
+	}
+	
+	public void
+	setDisableSleep(
+		boolean		b )
+	{
+		COConfigurationManager.setParameter( CONFIG_DISABLE_SLEEP, b );
+	}
+	
 	public TranscodeManagerImpl
 	getTranscodeManager()
 	{
+		if ( transcode_manager == null ){
+			
+			ensureInitialised( false );
+		}
+		
 		return( transcode_manager );
 	}
 	
@@ -1215,6 +1557,36 @@ DeviceManagerImpl
 		return( upnp_manager.getUnassociatedDevices());
 	}
 	
+	public String
+	getPowerName()
+	{
+		return( "Transcode" );
+	}
+	
+	public boolean
+	requestPowerStateChange(
+		int		new_state,
+		Object	data )
+	{
+		if ( getDisableSleep()){
+			
+			if ( getTranscodeManager().getQueue().isTranscoding()){
+				
+				return( false );
+			}
+		}
+		
+		return( true );
+	}
+
+	public void
+	informPowerStateChange(
+		int		new_state,
+		Object	data )
+	{
+		
+	}
+	
   	public void
   	addListener(
   		DeviceManagerListener		listener )
@@ -1227,6 +1599,128 @@ DeviceManagerImpl
   		}
   	}
   	
+	protected boolean
+	browseReceived(
+		TrackerWebPageRequest		request,
+		Map<String,Object>			browser_args )
+	{
+		for ( DeviceManagerDiscoveryListener l: discovery_listeners ){
+			
+			try{
+				if ( l.browseReceived( request, browser_args )){
+									
+					return( true );
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		return( false );
+	}
+	
+	protected VuzeFile
+	exportVuzeFile(
+		DeviceImpl		device )
+	
+		throws IOException
+	{
+		VuzeFile	vf = VuzeFileHandler.getSingleton().create();
+		
+		Map	map = new HashMap();
+		
+		Map device_map = new HashMap();
+		
+		map.put( "device", device_map );
+		
+		device.exportToBEncodedMap( device_map, true );
+		
+		vf.addComponent( VuzeFileComponent.COMP_TYPE_DEVICE, map );
+		
+		return( vf );
+	}
+	
+	private void
+	importVuzeFile(
+		Map			map,
+		boolean		warn_user )
+	{
+		Map	m = (Map)map.get( "device" );
+		
+		if ( device_map != null ){
+			
+			try{
+				DeviceImpl device = DeviceImpl.importFromBEncodedMapStatic( this, m );
+				
+				DeviceImpl existing;
+				
+				synchronized( this ){
+					
+					existing = device_map.get( device.getID());
+				}
+				
+				if ( existing == null ){
+					
+					if ( warn_user ){
+						
+						UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+			
+						String details = MessageText.getString(
+								"device.import.desc",
+								new String[]{ device.getName()});
+						
+						long res = ui_manager.showMessageBox(
+								"device.import.title",
+								"!" + details + "!",
+								UIManagerEvent.MT_YES | UIManagerEvent.MT_NO );
+						
+						if ( res != UIManagerEvent.MT_YES ){	
+						
+							return;
+						}
+					}
+					
+					addDevice( device, false );
+					
+				}else{
+					
+					if ( warn_user ){
+						
+						UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+						
+						String details = MessageText.getString(
+								"device.import.dup.desc",
+								new String[]{ existing.getName()});
+						
+						ui_manager.showMessageBox(
+								"device.import.dup.title",
+								"!" + details + "!",
+								UIManagerEvent.MT_OK );
+					}
+					
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
+	public void
+	addDiscoveryListener(
+		DeviceManagerDiscoveryListener	listener )
+	{
+		discovery_listeners.add( listener );
+	}
+	
+	public void
+	removeDiscoveryListener(
+		DeviceManagerDiscoveryListener	listener )
+	{
+		discovery_listeners.remove( listener );
+	}
+  	
   	public void
   	removeListener(
   		DeviceManagerListener		listener )
@@ -1234,15 +1728,18 @@ DeviceManagerImpl
   		listeners.removeListener( listener );
   	}
   	
-	protected synchronized AEDiagnosticsLogger
+	protected AEDiagnosticsLogger
 	getLogger()
 	{
-		if ( logger == null ){
+		synchronized( logger_lock ){
 			
-			logger = AEDiagnostics.getLogger( LOGGER_NAME );
+			if ( logger == null ){
+				
+				logger = AEDiagnostics.getLogger( LOGGER_NAME );
+			}
+			
+			return( logger );
 		}
-		
-		return( logger );
 	}
 	
 	public void 
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
index d2f63e9..34de3ed 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerRSSFeed.java
@@ -41,6 +41,7 @@ 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.XMLEscapeWriter;
 import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
 
 import org.gudy.azureus2.plugins.torrent.Torrent;
@@ -50,6 +51,8 @@ import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;
 import com.aelitis.azureus.core.devices.Device;
 import com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.ui.swt.devices.DeviceManagerUI;
+
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
 public class 
@@ -69,7 +72,10 @@ DeviceManagerRSSFeed
 		manager 	= _manager;
 		generator	= RSSGeneratorPlugin.getSingleton();
 		
-		generator.registerProvider( PROVIDER, this );
+		if ( generator != null ){
+		
+			generator.registerProvider( PROVIDER, this );
+		}
 	}
 		
 	public boolean
@@ -81,7 +87,7 @@ DeviceManagerRSSFeed
 	public String
 	getFeedURL()
 	{
-		return( generator.getURL() + PROVIDER );
+		return( generator==null?"Feature Disabled":( generator.getURL() + PROVIDER ));
 	}
 	
 	public boolean
@@ -108,7 +114,13 @@ DeviceManagerRSSFeed
 		
 		OutputStream os = response.getOutputStream();
 
-		PrintWriter pw = new PrintWriter(new OutputStreamWriter( os, "UTF-8" ));
+		XMLEscapeWriter pw = new XMLEscapeWriter( new PrintWriter(new OutputStreamWriter( os, "UTF-8" )));
+
+		pw.setEnabled( false );
+
+		boolean hide_generic = COConfigurationManager.getBooleanParameter( DeviceManagerUI.CONFIG_VIEW_HIDE_REND_GENERIC, true );
+		
+		boolean show_only_tagged = COConfigurationManager.getBooleanParameter( DeviceManagerUI.CONFIG_VIEW_SHOW_ONLY_TAGGED, false);
 
 		if ( path.length() <= 1 ){
 			
@@ -118,14 +130,20 @@ DeviceManagerRSSFeed
 			
 			for ( DeviceImpl d: devices ){
 			
-				if ( d.getType() != Device.DT_MEDIA_RENDERER || d.isHidden() || !d.isRSSPublishEnabled()){
+				if ( 	d.getType() != Device.DT_MEDIA_RENDERER || 
+						d.isHidden() || 
+						!d.isRSSPublishEnabled() || 
+						( hide_generic && d.isNonSimple()) || 
+						( show_only_tagged && !d.isTagged())){
 					
 					continue;
 				}
 
 				String	name = d.getName();
-								
-				pw.println( "<LI><A href=\"" + PROVIDER + "/" + URLEncoder.encode( name, "UTF-8" ) + "\">" + name + "</A></LI>" );
+							
+				String	device_url = PROVIDER + "/" + URLEncoder.encode( name, "UTF-8" );
+				
+				pw.println( "<LI><A href=\"" + device_url + "\">" + name + "</A>  -  <font size=\"-1\"><a href=\"" + device_url + "?format=html\">html</a></font></LI>" );
 			}
 			
 			pw.println( "</BODY></HTML>" );
@@ -153,54 +171,6 @@ 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();
-			}
-			
-			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 Device: " + escape( device.getName());
-					
-			pw.println( "<title>" + channel_title + "</title>" );
-			pw.println( "<link>http://vuze.com</link>" );
-			pw.println( "<atom:link href=\"" + feed_url.toExternalForm() + "\" rel=\"self\" type=\"application/rss+xml\" />" );
-			
-			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>");
-			
-					
 			TranscodeFileImpl[] _files = device.getFiles();
 			
 			List<TranscodeFileImpl>	files = new ArrayList<TranscodeFileImpl>( _files.length );
@@ -222,174 +192,295 @@ DeviceManagerRSSFeed
 						return((int)(added2 - added1 ));
 					}
 				});
-										
-			String	feed_date_key = "devices.feed_date." + device.getID();
 			
-			long feed_date = COConfigurationManager.getLongParameter( feed_date_key );
+			URL	feed_url = url;
 
-			boolean new_date = false;
+				// absolute url is borked as it doesn't set the host properly. hack 
 			
-			for ( TranscodeFileImpl file: files ){
+			String	host = (String)request.getHeaders().get( "host" );
+			
+			if ( host != null ){
 				
-				long	file_date = file.getCreationDateMillis();
+				int	pos = host.indexOf( ':' );
 				
-				if ( file_date > feed_date ){
-					
-					new_date = true;
+				if ( pos != -1 ){
 					
-					feed_date = file_date;
+					host = host.substring( 0, pos );
 				}
+				
+				feed_url = UrlUtils.setHost( url, host );
 			}
 			
-			if ( new_date ){
+			if ( device instanceof DeviceMediaRendererImpl ){
 				
-				COConfigurationManager.setParameter( feed_date_key, feed_date );
+				((DeviceMediaRendererImpl)device).browseReceived();
 			}
 			
-			pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( feed_date ) + "</pubDate>" );
+			String channel_title = "Vuze Device: " + escape( device.getName());
 
-			for ( TranscodeFileImpl file: files ){
-										
-	  			if ( !file.isComplete()){
-	  					
-	  				if ( !file.isTemplate()){
-	  						
-	  					continue;
-	  				}
-	  			}
-	  		
-				try{
-	  				pw.println( "<item>" );
-	  				
-	  				pw.println( "<title>" + escape( file.getName()) + "</title>" );
-	  								
-	  				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( file.getCreationDateMillis()) + "</pubDate>" );
-	  				
-	  				pw.println( "<guid isPermaLink=\"false\">" + escape( file.getKey()) + "</guid>" );
-	  				
-	  				String[] categories = file.getCategories();
-	  				
-	  				for ( String category: categories ){
-	  					
-	  					pw.println( "<category>" + category + "</category>" );
-	  				}
-	  				
-	  				String mediaContent = "";
+			boolean	html = request.getURL().contains( "format=html" );
+
+			if ( html ){
+				
+				response.setContentType( "text/html; charset=UTF-8" );
+				
+				pw.println( "<HTML><HEAD><TITLE>" + channel_title + "</TITLE></HEAD><BODY>" );
+
+				
+				for ( TranscodeFileImpl file: files ){
+					
+		  			if ( !file.isComplete()){
+		  					
+		  				if ( !file.isTemplate()){
+		  						
+		  					continue;
+		  				}
+		  			}
 	  				
 	  				URL stream_url = file.getStreamURL( feed_url.getHost() );
 	  				
 	  				if ( stream_url != null ){
 	  					
 	  					String url_ext = stream_url.toExternalForm();
-	  					
-	  					long fileSize = file.getTargetFile().getLength();
-	  					
-	  					pw.println( "<link>" + url_ext + "</link>" );
-	  					
-	  					mediaContent = "<media:content medium=\"video\" fileSize=\"" +
-											fileSize + "\" url=\"" + url_ext + "\""; 
-	  					
-	  					String	mime_type = file.getMimeType();
-	  					
-	  					if ( mime_type != null ){
 	  						
-	  						mediaContent += " type=\"" + mime_type + "\"";
-	  					}
-	  				
-						pw.println("<enclosure url=\"" + url_ext
-								+ "\" length=\"" + fileSize
-								+ (mime_type == null ? "" : "\" type=\"" + mime_type)
-								+ "\"></enclosure>");		
-	  				}
-	  				
-	   				String	thumb_url		= null;
-	  				String	author			= null;
-	  				String	description		= null;
-	  				
-	  				try{
-	  					Torrent torrent = file.getSourceFile().getDownload().getTorrent();
-	  				
-	  					TOTorrent toTorrent = PluginCoreUtils.unwrap(torrent);
-					
-	  					long duration_secs = PlatformTorrentUtils.getContentVideoRunningTime(toTorrent);
+	  					pw.println( "<p>" );
 	  					
-	  					if ( mediaContent.length() > 0 && duration_secs > 0 ){
+	  					pw.println( "<a href=\"" + url_ext + "\">" + escape( file.getName()) + "</a>" );
 	  						
-	  						mediaContent += " duration=\"" + duration_secs + "\"";
-	  					}
-	  					  					
-	  					thumb_url = PlatformTorrentUtils.getContentThumbnailUrl(toTorrent);
+	  					url_ext += url_ext.indexOf('?') == -1?"?":"&";
 	  					
-	  					author = PlatformTorrentUtils.getContentAuthor(toTorrent);
-	  								
-	  					description= PlatformTorrentUtils.getContentDescription(toTorrent);
+	  					url_ext += "action=download";
 	  					
-	  					if ( description != null ){
-	  						
-	  						description = escapeMultiline( description );
+	  					pw.println( "  -  <font size=\"-1\"><a href=\"" + url_ext + "\">save</a></font>" );
 
-	  						/*
-	  						if ( thumb_url != null ){
-	  							
-	  		
-	  							pw.println( "<description type=\"text/html\">" + 
-	  								escape( "<div style=\"text-align: justify;padding: 5px;\"><img style=\"float: left;margin-right: 15px;margin-bottom: 15px;\" src=\"" + thumb_url + "\"/>" ) +
-	  								description + 
-	  								escape( "</div>" ) +
-	  								"</description>" );
-	  						}else{
-	  						*/	
-	  							pw.println( "<description>" + description + "</description>");
-	  						//}
-	   					}					
-	  				}catch( Throwable e ){
-	  				}
-	
-	  					// media elements
-	  				
-	  				if ( mediaContent.length() > 0 ){
-	  					  						
-	  					pw.println( mediaContent += "></media:content>" );
 	  				}
-	
-	  				pw.println( "<media:title>" + escape( file.getName()) + "</media:title>" );
-	
-					if ( description != null ){
+				}
+
+				pw.println( "</BODY></HTML>" );
+				
+			}else{
+				boolean	debug = request.getURL().contains( "format=debug" );
+				
+				if ( debug ){
+					
+					response.setContentType( "text/html; charset=UTF-8" );
+					
+					pw.println( "<HTML><HEAD><TITLE>" + channel_title + "</TITLE></HEAD><BODY>" );
+					
+					pw.println( "<pre>" );
+					
+					pw.setEnabled( true );
+					
+				}else{
+					
+					response.setContentType( "application/xml" );
+				}
+				
+				try{
+					
+					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>" );
+											
+					pw.println( "<title>" + channel_title + "</title>" );
+					pw.println( "<link>http://vuze.com</link>" );
+					pw.println( "<atom:link href=\"" + feed_url.toExternalForm() + "\" rel=\"self\" type=\"application/rss+xml\" />" );
+					
+					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>");
+					
 							
-						pw.println( "<media:description>" + description + "</media:description>" );
-					}
+
+												
+					String	feed_date_key = "devices.feed_date." + device.getID();
 					
-					if ( thumb_url != null ) {
+					long feed_date = COConfigurationManager.getLongParameter( feed_date_key );
+		
+					boolean new_date = false;
+					
+					for ( TranscodeFileImpl file: files ){
+						
+						long	file_date = file.getCreationDateMillis();
+						
+						if ( file_date > feed_date ){
+							
+							new_date = true;
 							
-						pw.println("<media:thumbnail url=\"" + thumb_url + "\"/>" );
+							feed_date = file_date;
+						}
+					}
+					
+					if ( new_date ){
+						
+						COConfigurationManager.setParameter( feed_date_key, feed_date );
 					}
-	 
-	 					// iTunes elements
-	 					
-					if ( thumb_url != null ) {
+					
+					pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( feed_date ) + "</pubDate>" );
+		
+					for ( TranscodeFileImpl file: files ){
+												
+			  			if ( !file.isComplete()){
+			  					
+			  				if ( !file.isTemplate()){
+			  						
+			  					continue;
+			  				}
+			  			}
+			  		
+						try{
+			  				pw.println( "<item>" );
+			  				
+			  				pw.println( "<title>" + escape( file.getName()) + "</title>" );
+			  								
+			  				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( file.getCreationDateMillis()) + "</pubDate>" );
+			  				
+			  				pw.println( "<guid isPermaLink=\"false\">" + escape( file.getKey()) + "</guid>" );
+			  				
+			  				String[] categories = file.getCategories();
+			  				
+			  				for ( String category: categories ){
+			  					
+			  					pw.println( "<category>" + category + "</category>" );
+			  				}
+			  				
+			  				String mediaContent = "";
+			  				
+			  				URL stream_url = file.getStreamURL( feed_url.getHost() );
+			  				
+			  				if ( stream_url != null ){
+			  					
+			  					String url_ext = stream_url.toExternalForm();
+			  					
+			  					long fileSize = file.getTargetFile().getLength();
+			  					
+			  					pw.println( "<link>" + url_ext + "</link>" );
+			  					
+			  					mediaContent = "<media:content medium=\"video\" fileSize=\"" +
+													fileSize + "\" url=\"" + url_ext + "\""; 
+			  					
+			  					String	mime_type = file.getMimeType();
+			  					
+			  					if ( mime_type != null ){
+			  						
+			  						mediaContent += " type=\"" + mime_type + "\"";
+			  					}
+			  				
+								pw.println("<enclosure url=\"" + url_ext
+										+ "\" length=\"" + fileSize
+										+ (mime_type == null ? "" : "\" type=\"" + mime_type)
+										+ "\"></enclosure>");		
+			  				}
+			  				
+			   				String	thumb_url		= null;
+			  				String	author			= null;
+			  				String	description		= null;
+			  				
+			  				try{
+			  					Torrent torrent = file.getSourceFile().getDownload().getTorrent();
+			  				
+			  					TOTorrent toTorrent = PluginCoreUtils.unwrap(torrent);
+							
+			  					long duration_secs = PlatformTorrentUtils.getContentVideoRunningTime(toTorrent);
+			  					
+			  					if ( mediaContent.length() > 0 && duration_secs > 0 ){
+			  						
+			  						mediaContent += " duration=\"" + duration_secs + "\"";
+			  					}
+			  					  					
+			  					thumb_url = PlatformTorrentUtils.getContentThumbnailUrl(toTorrent);
+			  					
+			  					author = PlatformTorrentUtils.getContentAuthor(toTorrent);
+			  								
+			  					description= PlatformTorrentUtils.getContentDescription(toTorrent);
+			  					
+			  					if ( description != null ){
+			  						
+			  						description = escapeMultiline( description );
+		
+			  						/*
+			  						if ( thumb_url != null ){
+			  							
+			  		
+			  							pw.println( "<description type=\"text/html\">" + 
+			  								escape( "<div style=\"text-align: justify;padding: 5px;\"><img style=\"float: left;margin-right: 15px;margin-bottom: 15px;\" src=\"" + thumb_url + "\"/>" ) +
+			  								description + 
+			  								escape( "</div>" ) +
+			  								"</description>" );
+			  						}else{
+			  						*/	
+			  							pw.println( "<description>" + description + "</description>");
+			  						//}
+			   					}					
+			  				}catch( Throwable e ){
+			  				}
+			
+			  					// media elements
+			  				
+			  				if ( mediaContent.length() > 0 ){
+			  					  						
+			  					pw.println( mediaContent += "></media:content>" );
+			  				}
+			
+			  				pw.println( "<media:title>" + escape( file.getName()) + "</media:title>" );
+			
+							if ( description != null ){
+									
+								pw.println( "<media:description>" + description + "</media:description>" );
+							}
+							
+							if ( thumb_url != null ) {
+									
+								pw.println("<media:thumbnail url=\"" + thumb_url + "\"/>" );
+							}
+			 
+			 					// iTunes elements
+			 					
+							if ( thumb_url != null ) {
+									
+								pw.println("<itunes:image href=\"" + thumb_url + "\"/>");
+							}
+			
+			 				if ( author != null ){
+			  					
+			  					pw.println("<itunes:author>" + escape(author) + "</itunees:author>");
+			  				}
+			  				
+			  				pw.println( "<itunes:summary>" + escape( file.getName()) + "</itunes:summary>" );
+			  				pw.println( "<itunes:duration>" + TimeFormatter.formatColon( file.getDurationMillis()/1000 ) + "</itunes:duration>" );
+			  				
+			  				pw.println( "</item>" );
+			  				
+						}catch( Throwable e ){
 							
-						pw.println("<itunes:image href=\"" + thumb_url + "\"/>");
+							Debug.out(e);
+						}
 					}
-	
-	 				if ( author != null ){
-	  					
-	  					pw.println("<itunes:author>" + escape(author) + "</itunees:author>");
-	  				}
-	  				
-	  				pw.println( "<itunes:summary>" + escape( file.getName()) + "</itunes:summary>" );
-	  				pw.println( "<itunes:duration>" + TimeFormatter.formatColon( file.getDurationMillis()/1000 ) + "</itunes:duration>" );
-	  				
-	  				pw.println( "</item>" );
-	  				
-				}catch( Throwable e ){
+				
+					pw.println( "</channel>" );
+					
+					pw.println( "</rss>" );
 					
-					Debug.out(e);
+				}finally{
+					
+					if ( debug ){
+						
+						pw.setEnabled( false );
+						
+						pw.println( "</pre>" );
+						
+						pw.println( "</BODY></HTML>" );
+					}
 				}
 			}
-		
-			pw.println( "</channel>" );
-			
-			pw.println( "</rss>" );
 		}
 		
 		pw.flush();
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
index daaca3a..5bd2723 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceManagerUPnPImpl.java
@@ -23,12 +23,12 @@ package com.aelitis.azureus.core.devices.impl;
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
 import java.net.URL;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginEvent;
 import org.gudy.azureus2.plugins.PluginEventListener;
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -56,6 +56,7 @@ import com.aelitis.net.upnp.UPnPFactory;
 import com.aelitis.net.upnp.UPnPListener;
 import com.aelitis.net.upnp.UPnPRootDevice;
 import com.aelitis.net.upnp.UPnPRootDeviceListener;
+import com.aelitis.net.upnp.UPnPSSDPListener;
 import com.aelitis.net.upnp.UPnPService;
 import com.aelitis.net.upnp.services.UPnPOfflineDownloader;
 import com.aelitis.net.upnp.services.UPnPWANConnection;
@@ -64,7 +65,7 @@ public class
 DeviceManagerUPnPImpl 
 {
 	private final static Object KEY_ROOT_DEVICE = new Object();
-	
+		
 	private DeviceManagerImpl		manager;
 	private PluginInterface			plugin_interface;
 	private UPnP 					upnp;
@@ -74,6 +75,8 @@ DeviceManagerUPnPImpl
 	
 	private Map<InetAddress,String>		unassociated_devices = new HashMap<InetAddress, String>();
 	
+	private Set<String>					access_logs	= new HashSet<String>();
+	
 	protected
 	DeviceManagerUPnPImpl(
 		DeviceManagerImpl		_manager )
@@ -224,6 +227,100 @@ DeviceManagerUPnPImpl
 					}
 				});
 		
+			upnp.getSSDP().addListener(
+				new UPnPSSDPListener()
+				{
+					private Map<InetAddress,Boolean>	liveness_map = new HashMap<InetAddress, Boolean>();
+					
+					public void
+					receivedResult(
+						NetworkInterface	network_interface,
+						InetAddress			local_address,
+						InetAddress			originator,
+						String				USN,
+						URL					location,
+						String				ST,
+						String				AL )
+					{
+					}
+					
+					public void
+					receivedNotify(
+						NetworkInterface	network_interface,
+						InetAddress			local_address,
+						InetAddress			originator,
+						String				USN,
+						URL					location,
+						String				NT,
+						String				NTS )
+					{
+						alive( originator, NTS.indexOf( "byebye") == -1 );
+					}
+
+					public String[]
+					receivedSearch(
+						NetworkInterface	network_interface,
+						InetAddress			local_address,
+						InetAddress			originator,
+						String				ST )
+					{
+						alive( originator, true );
+						
+						return( null );
+					}
+					
+					public void
+					interfaceChanged(
+						NetworkInterface	network_interface )
+					{
+					}
+					
+					private void
+					alive(
+						InetAddress		address,
+						boolean			alive )
+					{
+						synchronized( liveness_map ){
+						
+							Boolean	b = liveness_map.get( address );
+							
+							if ( b != null && b == alive ){
+								
+								return;
+							}
+							
+							liveness_map.put( address, alive );
+						}
+												
+						DeviceImpl[] devices = manager.getDevices();
+
+						for ( DeviceImpl d: devices ){
+												
+							if ( d instanceof DeviceMediaRendererImpl ){
+									
+								DeviceMediaRendererImpl r = (DeviceMediaRendererImpl)d;
+									
+								InetAddress device_address = r.getAddress();
+									
+								if ( device_address != null && device_address.equals( address )){
+										
+									if ( r.isAlive() != alive ){
+										
+										if ( alive ){
+											
+											r.alive();
+											
+										}else{
+											
+											r.dead();
+										}
+									}
+								}
+							}
+						}
+					}
+				});
+			
 		}catch( Throwable e ){
 			
 			manager.log( "UPnP device manager failed", e );
@@ -326,6 +423,7 @@ DeviceManagerUPnPImpl
 																		
 									handled = true;
 								}
+
 							}
 							
 							if ( client_info != null ){
@@ -342,6 +440,11 @@ DeviceManagerUPnPImpl
 							
 							if ( !handled ){
 								
+								handled = manager.browseReceived( request, browser_args );
+							}
+							
+							if ( !handled ){
+								
 								String	 source = (String)browser_args.get( "source" );
 								
 								if ( source != null && source.equalsIgnoreCase( "http" )){
@@ -352,17 +455,22 @@ DeviceManagerUPnPImpl
 								}
 							}
 							
-							/*
+							/**
 							System.out.println( 
-								"Received browse: " + request.getClientAddress() +
-								", agent=" + user_agent +
-								", info=" + client_info );
-							*/
+									"Received browse: " + request.getClientAddress() +
+									", agent=" + user_agent +
+									", info=" + client_info +
+									", handled=" + handled + ", " + request.getURL());
+									System.out.println("\n\n");
+								/**/
+
 							
 							DeviceImpl[] devices = manager.getDevices();
 							
 							final List<DeviceMediaRendererImpl>	browse_devices = new ArrayList<DeviceMediaRendererImpl>();
 							
+							boolean	restrict_access = false;
+							
 							for ( DeviceImpl device: devices ){
 							
 								if ( device instanceof DeviceMediaRendererImpl ){
@@ -380,6 +488,65 @@ DeviceManagerUPnPImpl
 					
 												if ( renderer.canFilterFilesView()){
 												
+													boolean	skip = false;
+													
+													if ( renderer.canRestrictAccess()){
+														
+														String restriction = renderer.getAccessRestriction().trim();
+														
+														if ( restriction.length() > 0 ){
+															
+															String x = client_address.getAddress().getHostAddress();
+															
+															skip = true;
+															
+															String[] ips = restriction.split( "," );
+															
+															for ( String ip: ips ){
+																
+																if ( ip.startsWith( "-" )){
+																	
+																	ip = ip.substring(1);
+																	
+																	if ( ip.equals( x )){
+																		
+																		break;
+																	}
+																}else{
+																	
+																	if ( ip.startsWith( "+" )){
+																		
+																		ip = ip.substring(1);
+																	}
+																	
+																	if ( ip.equals( x )){
+																	
+																		skip = false;
+																		
+																		break;
+																	}
+																}
+															}
+														}
+													}
+													
+													if ( skip ){
+													
+														restrict_access = true;
+														
+														String	host = client_address.getAddress().getHostAddress();
+														
+														synchronized( access_logs){
+															
+															if ( !access_logs.contains( host )){
+																
+																access_logs.add( host );
+															
+																manager.log( "Ignoring browse from " + host + " due to access restriction for '" + renderer.getName() + "'" );
+															}
+														}
+													}
+														
 													browse_devices.add( renderer );
 													
 													renderer.browseReceived();
@@ -402,6 +569,8 @@ DeviceManagerUPnPImpl
 									unassociated_devices.remove( client_address.getAddress() );
 								}
 								
+								final boolean f_restrict_access = restrict_access;
+								
 								result.put(
 									"filter",
 									new AzureusContentFilter()
@@ -411,6 +580,11 @@ DeviceManagerUPnPImpl
 											AzureusContentDownload	download,
 											Map<String,Object>		browse_args )
 										{
+											if ( f_restrict_access ){
+												
+												return( false );
+											}
+											
 											boolean	visible = false;
 											
 											for ( DeviceUPnPImpl device: browse_devices ){
@@ -429,6 +603,11 @@ DeviceManagerUPnPImpl
 											AzureusContentFile		file,
 											Map<String,Object>		browse_args )
 										{
+											if ( f_restrict_access ){
+												
+												return( false );
+											}
+											
 											boolean	visible = false;
 											
 											for ( DeviceUPnPImpl device: browse_devices ){
@@ -458,9 +637,7 @@ DeviceManagerUPnPImpl
 					});
 			
 			if ( upnpav_ipc.canInvoke( "addBrowseListener", new Object[]{ my_ipc })){
-				
-				upnpav_ipc.invoke( "addBrowseListener", new Object[]{ my_ipc });
-				
+								
 				DeviceImpl[] devices = manager.getDevices();
 				
 				for ( DeviceImpl device: devices ){
@@ -472,6 +649,9 @@ DeviceManagerUPnPImpl
 						u_d.resetUPNPAV();
 					}
 				}
+				
+				upnpav_ipc.invoke( "addBrowseListener", new Object[]{ my_ipc });
+
 			}else{
 				
 				manager.log( "UPnPAV plugin needs upgrading" );
@@ -521,7 +701,9 @@ DeviceManagerUPnPImpl
 					
 					DeviceMediaRendererImpl r = (DeviceMediaRendererImpl)d;
 					
-					if ( d.isAlive() && r.getAddress().equals( address )){
+					InetAddress device_address = r.getAddress();
+					
+					if ( d.isAlive() && device_address != null && device_address.equals( address )){
 						
 						already_assoc = true;
 						
@@ -648,7 +830,7 @@ DeviceManagerUPnPImpl
 		handleGeneric( address, "browser", "Browser" );
 	}
 	
-	protected void
+	protected DeviceMediaRenderer
 	handleGeneric(
 		InetSocketAddress	address,
 		String				unique_name,
@@ -670,13 +852,14 @@ DeviceManagerUPnPImpl
 			}
 		}
 		
-		DeviceMediaRendererImpl device = new DeviceMediaRendererImpl( manager, uid, display_name, false );
-					
-		device = (DeviceMediaRendererImpl)manager.addDevice( device );
+		DeviceMediaRendererImpl newDevice = new DeviceMediaRendererImpl( manager, uid, unique_name, false, display_name );
+		DeviceMediaRendererImpl device = (DeviceMediaRendererImpl)manager.addDevice( newDevice );
 		
 		device.setAddress( address.getAddress());
 		
 		device.alive();
+
+		return device;
 	}
 	
 	protected void
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererImpl.java
index cb6438e..ae45d8b 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererImpl.java
@@ -23,21 +23,24 @@ package com.aelitis.azureus.core.devices.impl;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.InetAddress;
 import java.util.List;
 import java.util.Map;
 
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.IndentWriter;
 
 import com.aelitis.azureus.core.devices.*;
 import com.aelitis.net.upnp.UPnPDevice;
+import com.aelitis.net.upnp.impl.device.UPnPDeviceImpl;
 
 public class 
 DeviceMediaRendererImpl
 	extends DeviceUPnPImpl
 	implements DeviceMediaRenderer
 {
-	protected
+	public
 	DeviceMediaRendererImpl(
 		DeviceManagerImpl	_manager,
 		UPnPDevice			_device )
@@ -45,7 +48,7 @@ DeviceMediaRendererImpl
 		super( _manager, _device, Device.DT_MEDIA_RENDERER );
 	}
 	
-	protected
+	public
 	DeviceMediaRendererImpl(
 		DeviceManagerImpl	_manager,
 		String				_classification )
@@ -53,17 +56,18 @@ DeviceMediaRendererImpl
 		super( _manager, Device.DT_MEDIA_RENDERER, _classification );
 	}
 	
-	protected
+	public
 	DeviceMediaRendererImpl(
 		DeviceManagerImpl	_manager,
+		String				_uuid,
 		String				_classification,
 		boolean				_manual,
 		String				_name )
 	{
-		super( _manager, Device.DT_MEDIA_RENDERER, _classification, _manual, _name );
+		super( _manager, Device.DT_MEDIA_RENDERER, _uuid, _classification, _manual, _name );
 	}
 	
-	protected
+	public
 	DeviceMediaRendererImpl(
 		DeviceManagerImpl	_manager,
 		String				_uuid,
@@ -83,6 +87,70 @@ DeviceMediaRendererImpl
 		super(_manager, _map );
 	}
 	
+	public void setAddress(InetAddress address) {
+		super.setAddress(address);
+		
+		if (address != null && getType() == DT_MEDIA_RENDERER) {
+			//System.out.println("Set Address " + address.getHostAddress() + "; " + getName() + "/" + getClassification());
+
+			boolean hasUPnPDevice = getUPnPDevice() != null;
+			DeviceImpl[] devices = getManager().getDevices();
+			for (DeviceImpl device : devices) {
+				if (device == this || device.getID().equals(getID())
+						|| !((device instanceof DeviceUPnPImpl))) {
+					continue;
+				}
+				DeviceUPnPImpl deviceUPnP = ((DeviceUPnPImpl) device);
+				if (!address.equals(device.getAddress()) || !device.isAlive()) {
+					continue;
+				}
+
+				if (hasUPnPDevice) {
+					if (device.getType() == DT_MEDIA_RENDERER) {
+						// prefer UPnP Device over Manual one added by a Browse event
+						if (deviceUPnP.getUPnPDevice() != null) {
+							int fileCount = deviceUPnP.getFileCount();
+							if (fileCount == 0 && !device.isHidden()) {
+								log("Hiding " + device.getName() + "/"
+										+ device.getClassification() + "/" + device.getID()
+										+ " due to " + getName() + "/" + getClassification() + "/"
+										+ getID());
+  							device.setHidden(true);
+							}
+						}
+					}
+				} else {
+					if (device.getType() == DT_MEDIA_RENDERER) {
+						int fileCount = getFileCount();
+						// prefer UPnP Device over Manual one added by a Browse event
+						if (fileCount == 0 && !isHidden()) {
+							log("hiding " + getName() + "/" + getClassification() + "/"
+									+ getID() + " due to " + device.getName() + "/"
+									+ device.getClassification() + "/" + device.getID());
+							setHidden(true);
+						} else if (fileCount > 0 && Constants.IS_CVS_VERSION && isHidden()) {
+							// Fix beta bug where we hid devices that had files.  Remove after 4605
+							setHidden(false);
+						}
+					} else {
+						// Device has UPnP stuff, but did not register itself as
+						// renderer.
+  					UPnPDevice upnpDevice = deviceUPnP.getUPnPDevice();
+  					if (upnpDevice != null) {
+    					String manufacturer = upnpDevice.getManufacturer();
+    					if (manufacturer == null || !manufacturer.startsWith("Vuze")) {
+    						log("Linked " + getName() + " to UPnP Device " + device.getName());
+      					setUPnPDevice(upnpDevice);
+      					setDirty();
+    					}
+  					}
+					}
+				}
+				break;
+			}
+		}
+	}
+	
 	@Override
 	protected boolean
 	updateFrom(
@@ -156,6 +224,13 @@ DeviceMediaRendererImpl
 		return( false );
 	}
 	
+	public void
+	setCanCopyToFolder(
+		boolean		can )
+	{
+		// nothing to do
+	}
+	
 	public File
 	getCopyToFolder()
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
index 462d8e8..0d95d95 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererManual.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+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;
@@ -49,6 +50,7 @@ DeviceMediaRendererManual
 	private static final Object	COPY_ERROR_KEY 		= new Object();
 	private static final Object	COPY_PENDING_KEY 	= new Object();
 
+	private boolean				can_copy_to_folder	= true;
 	private boolean				copy_outstanding;
 	private boolean				copy_outstanding_set;
 	private AEThread2			copy_thread;
@@ -58,11 +60,12 @@ DeviceMediaRendererManual
 	protected
 	DeviceMediaRendererManual(
 		DeviceManagerImpl	_manager,
+		String				_uid,
 		String				_classification,
 		boolean				_manual,
 		String				_name )
 	{
-		super( _manager,_classification, _manual, _name );
+		super( _manager, _uid, _classification, _manual, _name );
 	}
 	
 	protected
@@ -92,10 +95,7 @@ DeviceMediaRendererManual
 				fileAdded(
 					TranscodeFile		file )
 				{
-					if ( file.isComplete() && !file.isCopiedToDevice()){
-						
-						setCopyOutstanding();
-					}
+					updateStatus( file );
 				}
 				
 				public void
@@ -104,17 +104,26 @@ DeviceMediaRendererManual
 					int					type,
 					Object				data )
 				{
-					if ( file.isComplete() && !file.isCopiedToDevice()){
-						
-						setCopyOutstanding();
-					}
+					updateStatus( file );
 				}
 				
 				public void
 				fileRemoved(
 					TranscodeFile		file )
+				{	
+						// do this to pick up change in copy-to-device state caused by removal
+					
+					setCopyOutstanding();
+				}
+				
+				private void
+				updateStatus(
+					TranscodeFile		file )
 				{
-					copy_sem.release();
+					if ( file.isComplete() && !file.isCopiedToDevice()){
+						
+						setCopyOutstanding();
+					}
 				}
 			});
 	}
@@ -126,6 +135,12 @@ DeviceMediaRendererManual
 	}
 	
 	public boolean
+	canRestrictAccess()
+	{
+		return( false );
+	}
+	
+	public boolean
 	canFilterFilesView() 
 	{
 		return( false );
@@ -140,7 +155,22 @@ DeviceMediaRendererManual
 	public boolean
 	canCopyToFolder()
 	{
-		return( true );
+		return( can_copy_to_folder );
+	}
+	
+	public void
+	setCanCopyToFolder(
+		boolean		can )
+	{
+		can_copy_to_folder = can;
+		
+		if ( !can ){
+			
+			setPersistentBooleanProperty( PP_COPY_OUTSTANDING, false );
+			
+			copy_outstanding 		= false;
+			copy_outstanding_set	= false;
+		}
 	}
 	
 	public File
@@ -184,6 +214,11 @@ DeviceMediaRendererManual
 	public int
 	getCopyToFolderPending()
 	{
+		if ( !can_copy_to_folder ){
+			
+			return( 0 );
+		}
+		
 		synchronized( this ){
 			
 			if ( !copy_outstanding ){
@@ -238,6 +273,11 @@ DeviceMediaRendererManual
 	protected void
 	setCopyOutstanding()
 	{
+		if ( !can_copy_to_folder ){
+			
+			return;
+		}
+		
 		synchronized( this ){
 			
 			copy_outstanding_set = true;
@@ -293,6 +333,11 @@ DeviceMediaRendererManual
 	protected void
 	performCopy()
 	{
+		if ( !can_copy_to_folder ){
+			
+			return;
+		}
+		
 		synchronized( this ){
 
 			copy_outstanding = true;
@@ -310,7 +355,7 @@ DeviceMediaRendererManual
 		
 		while( true ){
 			
-			if ( copy_sem.reserve( 60*1000 )){
+			if ( copy_sem.reserve( 10*1000 )){
 				
 				while( copy_sem.reserveIfAvailable());
 			}
@@ -363,7 +408,13 @@ DeviceMediaRendererManual
 	protected boolean
 	doCopy()
 	{
+		if ( !can_copy_to_folder ){
+			
+			return( true );
+		}
+		
 		setInfo( COPY_PENDING_KEY, null );
+
 		
 		File	copy_to = getCopyToFolder();
 		
@@ -407,36 +458,65 @@ DeviceMediaRendererManual
 				String str = MessageText.getString( "devices.info.copypending2", new String[]{ String.valueOf( pending ) });
 				
 				setInfo( COPY_PENDING_KEY, str );
-
 				
 				borked = true;
 				
 			}else{
+				setInfo( COPY_PENDING_KEY, null );
+				
+				boolean	sub_borked = false;
+				
 				if ( copy_to == null ){
 				
 					setError( COPY_ERROR_KEY, MessageText.getString( "device.error.copytonotset" ));
 					
-					borked = true;
+					sub_borked = true;
 					
 				}else if ( !copy_to.exists()){
 					
-					setError( COPY_ERROR_KEY, MessageText.getString( "device.error.copytomissing", new String[]{copy_to.getAbsolutePath()}));
+					// due to the two-phase mount of android devices and the fact that the
+					// copy-to location is %root$/videos, the root might exist but the sub-folder 
+					// not. 
 					
-					borked = true;
+					File parent = copy_to.getParentFile();
 					
-				}else if ( !copy_to.canWrite()){
+					if ( parent != null && parent.canWrite()){
+						
+						copy_to.mkdir();
+					}
 					
-					setError( COPY_ERROR_KEY, MessageText.getString( "device.error.copytonowrite", new String[]{copy_to.getAbsolutePath()}));
+					if ( !copy_to.exists()){
 					
-					borked = true;
+						setError( COPY_ERROR_KEY, MessageText.getString( "device.error.mountrequired", new String[]{copy_to.getAbsolutePath()}));
+
+						sub_borked = true;
+					}
+
+					//setError( COPY_ERROR_KEY, MessageText.getString( "device.error.copytomissing", new String[]{copy_to.getAbsolutePath()}));
+					//sub_borked = true;
+				}
+				
+				if ( !sub_borked ){
+				
+					if ( !copy_to.canWrite()){
 					
-				}else{
+						setError( COPY_ERROR_KEY, MessageText.getString( "device.error.copytonowrite", new String[]{copy_to.getAbsolutePath()}));
+					
+						sub_borked = true;
 					
-					try_copy = true;
+					}else{
 					
-					setError( COPY_ERROR_KEY, null );
+						try_copy = true;
+					
+						setError( COPY_ERROR_KEY, null );
+					}
 				}
+			
+				borked = borked | sub_borked;
 			}
+		} else {
+
+			setInfo( COPY_PENDING_KEY, null );
 		}
 		
 		synchronized( this ){
@@ -473,6 +553,8 @@ DeviceMediaRendererManual
 				for ( TranscodeFileImpl transcode_file: to_copy ){
 					
 					try{
+						transcode_file.setCopyingToDevice( true );
+
 						File	file = transcode_file.getTargetFile().getFile();
 						
 						File	target = new File( copy_to, file.getName());
@@ -520,6 +602,12 @@ DeviceMediaRendererManual
 		return( false );
 	}
 	
+	public boolean
+	isExportable()
+	{
+		return( true );
+	}
+	
 	protected void
 	getDisplayProperties(
 		List<String[]>	dp )
@@ -545,4 +633,15 @@ DeviceMediaRendererManual
 			writer.exdent();
 		}
 	}
+
+	// @see com.aelitis.azureus.core.devices.impl.DeviceImpl#getStatus()
+	public String getStatus() {
+		String s = super.getStatus();
+
+		if (COConfigurationManager.getIntParameter("User Mode") > 0 && getCopyToFolder() != null) {
+			s += " (" + getCopyToFolder().getPath() + ")";
+		}
+
+		return s;
+	}
 }
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererTemplateImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererTemplateImpl.java
index e78a322..1754ad5 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererTemplateImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceMediaRendererTemplateImpl.java
@@ -135,12 +135,23 @@ DeviceMediaRendererTemplateImpl
 	
 		throws DeviceManagerException
 	{
+		return( createInstance( name, null, true ));
+	}
+	
+	public Device
+	createInstance(
+		String		name,
+		String		uid,
+		boolean		manual )
+	
+		throws DeviceManagerException
+	{
 		if ( auto ){
 			
 			throw( new DeviceManagerException( "Device can't be added manually" ));
 		}
 		
-		Device res = manager.createDevice( Device.DT_MEDIA_RENDERER, classification, name );
+		Device res = manager.createDevice( Device.DT_MEDIA_RENDERER, uid, classification, name, manual );
 		
 		return( res );
 	}
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java
index fd0451d..f57bd37 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceOfflineDownloaderImpl.java
@@ -39,19 +39,7 @@ 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.core3.util.*;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
@@ -63,6 +51,7 @@ 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.UPnPException;
 import com.aelitis.net.upnp.UPnPRootDevice;
 import com.aelitis.net.upnp.services.UPnPOfflineDownloader;
 
@@ -281,7 +270,8 @@ DeviceOfflineDownloaderImpl
 			return;
 		}
 
-		String	error_status = null;
+		String	error_status 	= null;
+		boolean	force_status	= false;
 		
 		Map<String,DownloadManager>			new_offline_downloads 	= new HashMap<String,DownloadManager>();
 		Map<String,TransferableDownload>	new_transferables 		= new HashMap<String,TransferableDownload>();
@@ -294,10 +284,6 @@ DeviceOfflineDownloaderImpl
 					
 					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 )});
@@ -307,6 +293,12 @@ DeviceOfflineDownloaderImpl
 				}
 			}
 			
+			if ( space_on_device == 0 ){
+				
+				error_status 	= MessageText.getString( "device.od.error.nospace" );
+				force_status	= true;
+			}
+
 			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[]>();
@@ -652,7 +644,7 @@ DeviceOfflineDownloaderImpl
 					throw( new Exception( "Failing result returned: " + set_dl_status ));
 				}
 				
-				String[]	bits = set_dl_result.split( "," );
+				String[]	bits = Constants.PAT_SPLIT_COMMA.split(set_dl_result);
 				
 				int	num_bits = set_dl_result.length()==0?0:bits.length;
 				
@@ -731,8 +723,7 @@ DeviceOfflineDownloaderImpl
 									}
 									
 									String add_result = 
-										service.addDownload( 
-											client_id, 
+										addTorrent( 										
 											hash_str,
 											ByteFormatter.encodeStringFully( BEncoder.encode( torrent.serialiseToMap())));
 									
@@ -947,13 +938,53 @@ DeviceOfflineDownloaderImpl
 				}
 			}
 			
-			updateError( error_status );
+			updateError( error_status, force_status );
 		}
 	}
 
+	private String
+	addTorrent(
+		String		hash_str,
+		String		torrent_data )
+	
+		throws UPnPException
+	{
+		int	chunk_size = 40*1024;
+		
+		int	length = torrent_data.length();
+		
+		if ( length < chunk_size ){
+		
+			return( service.addDownload( client_id,	hash_str, torrent_data ));
+			
+		}else{
+			
+			String status = "";
+			
+			int	rem = length;
+			
+			for( int i=0; i<length; i+=chunk_size ){
+			
+				int	size = Math.min( rem, chunk_size );
+				
+				status = service.addDownloadChunked(
+					client_id,	
+					hash_str,
+					torrent_data.substring( i, i+size ),
+					i,
+					length );
+					
+				rem -= size;
+			}
+			
+			return( status );
+		}
+	}
+	
 	protected void
 	updateError(
-		String	str )
+		String	str,
+		boolean	force )
 	{
 		if ( str == null ){
 			
@@ -965,11 +996,25 @@ DeviceOfflineDownloaderImpl
 			
 		}else{
 			
+				// if device isn't connectable then replace the error with something more
+				// user-friendly
+			
+			try{
+			
+				if ( !service.getGenericService().isConnectable()){
+					
+					str = MessageText.getString( "device.od.error.notfound" );
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+			
 			consec_errors++;
 			
 			consec_success = 0;
 			
-			if ( consec_errors > 2 ){
+			if ( consec_errors > 2 || force ){
 				
 				setError( ERROR_KEY_OD, str );
 			}
@@ -1280,6 +1325,21 @@ DeviceOfflineDownloaderImpl
 		}
 	}
 
+	@Override
+	public boolean 
+	isAlive() 
+	{
+		if ( super.isAlive()){
+			
+				// more restrictive test here to sync alive state with 'appears to be offline'
+				// error messages
+			
+			return( service.getGenericService().isConnectable());
+		}
+		
+		return( false );
+	}
+	
 	public boolean
 	hasShownFTUX()
 	{
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceTivo.java b/com/aelitis/azureus/core/devices/impl/DeviceTivo.java
index ecacdaf..2f218db 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceTivo.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceTivo.java
@@ -33,6 +33,7 @@ import java.net.URLEncoder;
 import java.util.*;
 
 
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
@@ -124,7 +125,7 @@ DeviceTivo
 	{
 		super( _manager, _uid, _classification, false );
 		
-		setName( "TiVo" );
+		setName( "TiVo", true );
 	}
 
 	protected
@@ -178,6 +179,14 @@ DeviceTivo
 	}
 	
 	public boolean
+	canRestrictAccess()
+	{
+			// guess we could implement this one day
+		
+		return( false );
+	}
+	
+	public boolean
 	canShowCategories()
 	{
 		return( true );
@@ -492,7 +501,7 @@ DeviceTivo
 				
 				if ( sort_order != null ){
 					
-					String[] keys = sort_order.split( "," );
+					String[] keys = Constants.PAT_SPLIT_COMMA.split(sort_order);
 					
 					final List<Comparator<ItemInfo>> 	comparators = new  ArrayList<Comparator<ItemInfo>>();
 					final List<Boolean>					reverses	= new ArrayList<Boolean>();
@@ -677,11 +686,46 @@ DeviceTivo
 						
 						long	file_size = file.getTargetSize();
 						
+						String	title 	= escape( file.getName());
+						String	desc	= title;
+							
+						int MAX_TITLE_LENGTH = 30;
+						
+						if ( title.length() > MAX_TITLE_LENGTH ){
+							
+								// TiVo has problems displaying a truncated title if it has
+								// no spaces in it
+							
+							String 	temp = "";
+							
+							for ( int j=0;j<title.length();j++){
+								
+								char c = title.charAt( j );
+								
+								if ( Character.isLetterOrDigit( c )){
+									
+									temp += c;
+								}else{
+									
+									temp += ' ';
+								}
+							}
+							
+							int space_pos = temp.indexOf( ' ' );
+							
+							if ( space_pos == -1 || space_pos > MAX_TITLE_LENGTH ){
+								
+								temp = temp.substring( 0, 30 ) + "...";
+							}
+							
+							title = temp;
+						}
+						
 						reply +=
 						
 						"    <Item>" + NL +
 						"        <Details>" + NL +
-						"            <Title>" + escape( file.getName()) + "</Title>" + NL +
+						"            <Title>" + title + "</Title>" + NL +
 						"            <ContentType>video/x-tivo-mpeg</ContentType>" + NL +
 						"            <SourceFormat>video/x-ms-wmv</SourceFormat>" + NL;
 						
@@ -699,7 +743,7 @@ DeviceTivo
 						
 						reply +=
 						"            <Duration>" + file.getDurationMillis() + "</Duration>" + NL +
-						"            <Description></Description>" + NL +
+						"            <Description>" + desc + "</Description>" + NL +
 						"            <SourceChannel>0</SourceChannel>" + NL +
 						"            <SourceStation></SourceStation>" + NL +
 						"            <SeriesId></SeriesId>" + NL +
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java b/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
index a26a74b..b386f9a 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceTivoManager.java
@@ -49,6 +49,7 @@ import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.devices.Device;
 import com.aelitis.azureus.core.devices.DeviceManagerException;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 
 
 public class 
@@ -80,8 +81,15 @@ DeviceTivoManager
 	{
 		plugin_interface = PluginInitializer.getDefaultInterface();
 
-		is_enabled = COConfigurationManager.getBooleanParameter( "devices.tivo.enabled", true );
-
+		if ( COConfigurationManager.getStringParameter("ui").equals("az2")){
+			
+			is_enabled = false;
+			
+		}else{
+		
+			is_enabled = COConfigurationManager.getBooleanParameter( "devices.tivo.enabled", true );
+		}
+		
 		uid = COConfigurationManager.getStringParameter( "devices.tivo.uid", null );
 		
 		if ( uid == null ){
@@ -294,6 +302,16 @@ DeviceTivoManager
 				
 				if ( device.getID().equals( uid )){
 				
+					if ( classification != null ){
+						
+						String existing_classification = device.getClassification();
+						
+						if ( !classification.equals( existing_classification )){
+							
+							device.setPersistentStringProperty( DeviceImpl.PP_REND_CLASSIFICATION,classification );
+						}
+					}
+					
 					tivo.found( this, address, server_name, machine );
 					
 					return( tivo );
@@ -301,6 +319,14 @@ DeviceTivoManager
 			}
 		}
 		
+			// unfortunately we can't deduce the series from the browse request so start off with a series 3
+			// this will be corrected later if we receive a beacon which *does* contain the series details
+		
+		if ( classification == null ){
+			
+			classification = "tivo.series3";
+		}
+		
 		DeviceTivo new_device = new DeviceTivo( device_manager, uid, classification );
 		
 		DeviceTivo result = (DeviceTivo)device_manager.addDevice( new_device );
@@ -415,7 +441,7 @@ DeviceTivoManager
 								
 								persistent = true;
 								
-								DeviceTivo tivo = foundTiVo( request.getClientAddress2().getAddress(), id, "tivo.series3", null );
+								DeviceTivo tivo = foundTiVo( request.getClientAddress2().getAddress(), id, null, null );
 								
 								return( tivo.generate( request, response ));
 							}
@@ -434,7 +460,9 @@ DeviceTivoManager
 				}catch( Throwable e ){
 				}
 				
-				control_socket.bind( new InetSocketAddress((InetAddress)null, CONTROL_PORT ));
+				InetAddress bind = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress();
+				
+				control_socket.bind( new InetSocketAddress( bind, CONTROL_PORT ));
 		
 				timer_event = 
 					SimpleTimer.addPeriodicEvent(
@@ -504,10 +532,13 @@ DeviceTivoManager
 															
 							}catch( Throwable e ){
 								
-								failed_accepts++;
+								if ( control_socket != null && !search_destroyed && !manager_destroyed ){
+								
+									failed_accepts++;
+								
+									log( "UDP receive on port " + CONTROL_PORT + " failed", e );
+								}
 								
-								log( "UDP receive on port " + CONTROL_PORT + " failed", e );
-		
 								if (( failed_accepts > 100 && successful_accepts == 0 ) || failed_accepts > 1000 ){
 									
 									log( "    too many failures, abandoning" );
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java b/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
index e3cea06..4f2751f 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceUPnPImpl.java
@@ -1,1369 +1,1547 @@
-/*
- * 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.io.InputStream;
-import java.net.InetAddress;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.IndentWriter;
-import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadAttributeListener;
-import org.gudy.azureus2.plugins.download.DownloadManager;
-import org.gudy.azureus2.plugins.download.DownloadManagerListener;
-import org.gudy.azureus2.plugins.ipc.IPCInterface;
-import org.gudy.azureus2.plugins.torrent.Torrent;
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.content.AzureusContentDownload;
-import com.aelitis.azureus.core.content.AzureusContentFile;
-import com.aelitis.azureus.core.content.AzureusPlatformContentDirectory;
-import com.aelitis.azureus.core.devices.TranscodeException;
-import com.aelitis.azureus.core.devices.TranscodeFile;
-import com.aelitis.azureus.core.devices.TranscodeJob;
-import com.aelitis.azureus.core.devices.TranscodeProfile;
-import com.aelitis.azureus.core.devices.TranscodeTarget;
-import com.aelitis.azureus.core.devices.TranscodeTargetListener;
-import com.aelitis.azureus.core.devices.DeviceManager.UnassociatedDevice;
-import com.aelitis.azureus.core.download.DiskManagerFileInfoStream;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.util.UUIDGenerator;
-import com.aelitis.net.upnp.UPnPDevice;
-import com.aelitis.net.upnp.UPnPRootDevice;
-
-public abstract class 
-DeviceUPnPImpl
-	extends DeviceImpl
-	implements TranscodeTargetListener, DownloadManagerListener
-{
-	private static final Object UPNPAV_FILE_KEY = new Object();
-		
-	private static final Map<String,AzureusContentFile>	acf_map = new WeakHashMap<String,AzureusContentFile>();
-	
-	
-	protected static String
-	getDisplayName(
-		UPnPDevice		device )
-	{
-		UPnPDevice	root = device.getRootDevice().getDevice();
-		
-		String fn = root.getFriendlyName();
-		
-		if ( fn == null || fn.length() == 0 ){
-			
-			fn = device.getFriendlyName();
-		}
-		
-		String	dn = root.getModelName();
-		
-		if ( dn == null || dn.length() == 0 ){
-		
-			dn = device.getModelName();
-		}
-		
-		if ( dn != null && dn.length() > 0 ){
-			
-			if ( !fn.contains( dn ) && ( !dn.contains( "Azureus" ) || dn.contains( "Vuze" ))){
-			
-				fn += " (" + dn + ")";
-			}
-		}
-		
-		return( fn );
-	}
-	
-	private final String MY_ACF_KEY;
-
-	
-	private final DeviceManagerUPnPImpl	upnp_manager;
-	private volatile UPnPDevice		device_may_be_null;
-	
-	private IPCInterface		upnpav_ipc;
-	private TranscodeProfile	dynamic_transcode_profile;
-	private Map<String,AzureusContentFile>	dynamic_xcode_map;
-	
-	
-	protected
-	DeviceUPnPImpl(
-		DeviceManagerImpl		_manager,
-		UPnPDevice				_device,
-		int						_type )
-	{
-		super( _manager, _type, _type + "/" + _device.getRootDevice().getUSN(), getDisplayName( _device ), false );
-		
-		upnp_manager		= _manager.getUPnPManager();
-		device_may_be_null 	= _device;
-		
-		MY_ACF_KEY = getACFKey();
-	}	
-	
-	protected
-	DeviceUPnPImpl(
-		DeviceManagerImpl	_manager,
-		int					_type,
-		String				_classification )
-
-	{
-		super( _manager, _type, UUIDGenerator.generateUUIDString(), _classification, true );
-		
-		upnp_manager		= _manager.getUPnPManager();
-		
-		MY_ACF_KEY = getACFKey();
-	}
-	
-	protected
-	DeviceUPnPImpl(
-		DeviceManagerImpl	_manager,
-		int					_type,
-		String				_classification,
-		boolean				_manual,
-		String				_name )
-
-	{
-		super( _manager, _type, UUIDGenerator.generateUUIDString(), _classification, _manual, _name );
-		
-		upnp_manager		= _manager.getUPnPManager();
-		
-		MY_ACF_KEY = getACFKey();
-	}
-	
-	protected
-	DeviceUPnPImpl(
-		DeviceManagerImpl	_manager,
-		int					_type,
-		String				_uuid,
-		String				_classification,
-		boolean				_manual )
-
-	{
-		super( _manager, _type, _uuid, _classification, _manual );
-		
-		upnp_manager		= _manager.getUPnPManager();
-		
-		MY_ACF_KEY = getACFKey();
-	}
-	
-	protected
-	DeviceUPnPImpl(
-		DeviceManagerImpl	_manager,
-		Map					_map )
-	
-		throws IOException
-	{
-		super(_manager, _map );
-		
-		upnp_manager		= _manager.getUPnPManager();
-		
-		MY_ACF_KEY = getACFKey();
-	}
-	
-	protected String
-	getACFKey()
-	{
-		return( "DeviceUPnPImpl:device:" + getID());
-	}
-	
-	@Override
-	protected boolean
-	updateFrom(
-		DeviceImpl		_other,
-		boolean			_is_alive )
-	{
-		if ( !super.updateFrom( _other, _is_alive )){
-			
-			return( false );
-		}
-		
-		if ( !( _other instanceof DeviceUPnPImpl )){
-			
-			Debug.out( "Inconsistent" );
-			
-			return( false );
-		}
-		
-		DeviceUPnPImpl other = (DeviceUPnPImpl)_other;
-		
-		device_may_be_null	= other.device_may_be_null;
-		
-		return( true );
-	}
-	
-	@Override
-	protected void
-	initialise()
-	{
-		super.initialise();
-	}
-	
-	protected void
-	UPnPInitialised()
-	{
-	}
-	
-	@Override
-	protected void
-	destroy()
-	{
-		super.destroy();
-	}
-	
-	protected DeviceManagerUPnPImpl
-	getUPnPDeviceManager()
-	{
-		return( upnp_manager );
-	}
-	
-	protected UPnPDevice
-	getUPnPDevice()
-	{
-		return( device_may_be_null );
-	}
-	
-	public boolean
-	isBrowsable()
-	{
-		return( true );
-	}
-	
-	public browseLocation[]
-	getBrowseLocations()
-	{
-		List<browseLocation>	locs = new ArrayList<browseLocation>();
-	
-		UPnPDevice device = device_may_be_null;
-		
-		if ( device != null ){
-			
-			URL		presentation = getPresentationURL( device );
-
-			if ( presentation != null ){
-					
-				locs.add( new browseLocationImpl( "device.upnp.present_url", presentation ));
-			}
-			
-			locs.add( new browseLocationImpl( "device.upnp.desc_url", device.getRootDevice().getLocation()));
-		}
-		
-		return( locs.toArray( new browseLocation[ locs.size() ]));
-	}
-	
-	public boolean
-	canFilterFilesView()
-	{
-		return( true );
-	}
-	
-	public void
-	setFilterFilesView(
-		boolean	filter )
-	{
-		boolean	existing = getFilterFilesView();
-		
-		if ( existing != filter ){
-		
-			setPersistentBooleanProperty( PP_FILTER_FILES, filter );
-		
-			IPCInterface ipc = upnpav_ipc;
-			
-			if ( ipc != null ){
-				
-				try{
-					ipc.invoke( "invalidateDirectory", new Object[]{});
-
-				}catch( Throwable e ){
-				}
-			}
-		}
-	}
-	
-	public boolean
-	getFilterFilesView()
-	{
-		return( getPersistentBooleanProperty( PP_FILTER_FILES, true ));
-	}
-	
-	public boolean
-	isLivenessDetectable()
-	{
-		return( true );
-	}
-	
-	protected URL
-	getLocation()
-	{
-		UPnPDevice device = device_may_be_null;
-		
-		if ( device != null ){
-			
-			UPnPRootDevice root = device.getRootDevice();
-			
-			return( root.getLocation());
-		}
-		
-		return( null );
-	}
-	
-	public boolean
-	canAssociate()
-	{
-		return( true );
-	}
-	
-	public void
-	associate(
-		UnassociatedDevice	assoc )
-	{
-		if ( isAlive()){
-			
-			return;
-		}
-		
-		setAddress( assoc.getAddress());
-		
-		alive();
-	}
-	
-	public InetAddress
-	getAddress()
-	{
-		try{
-
-			UPnPDevice device = device_may_be_null;
-	
-			if ( device != null ){
-				
-				UPnPRootDevice root = device.getRootDevice();
-				
-				URL location = root.getLocation();
-				
-				return( InetAddress.getByName( location.getHost() ));
-				
-			}else{
-				
-				InetAddress address = (InetAddress)getTransientProperty( TP_IP_ADDRESS );
-				
-				if ( address != null ){
-					
-					return( address );
-				}
-				
-				String last = getPersistentStringProperty( PP_IP_ADDRESS );
-				
-				if ( last != null && last.length() > 0 ){
-					
-					return( InetAddress.getByName( last ));
-				}
-			}
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace(e);
-		
-		}
-		
-		return( null );
-	}
-	
-	protected void
-	setAddress(
-		InetAddress	address )
-	{
-		setTransientProperty( TP_IP_ADDRESS, address );
-		
-		setPersistentStringProperty( PP_IP_ADDRESS, address.getHostAddress());
-	}
-	
-	protected URL
-	getStreamURL(
-		TranscodeFileImpl		file )
-	{
-		browseReceived();
-		
-		return( super.getStreamURL( file, null ));
-	}
-	
-	protected void
-	browseReceived()
-	{
-		IPCInterface ipc = upnp_manager.getUPnPAVIPC();
-		
-		if ( ipc == null ){
-			
-			return;
-		}
-		
-		TranscodeProfile default_profile = getDefaultTranscodeProfile();
-		
-		if ( default_profile == null ){
-			
-			TranscodeProfile[] profiles = getTranscodeProfiles();
-			
-			for ( TranscodeProfile p: profiles ){
-				
-				if ( p.isStreamable()){
-					
-					default_profile = p;
-					
-					break;
-				}
-			}
-		}
-		
-		synchronized( this ){
-			
-			if ( upnpav_ipc != null ){
-				
-				return;
-			}
-			
-			upnpav_ipc = ipc;
-			
-			if ( default_profile != null && default_profile.isStreamable()){
-				
-				dynamic_transcode_profile	= default_profile;
-			}
-		}
-		
-		if ( dynamic_transcode_profile != null && this instanceof TranscodeTarget ){
-			
-			// In theory this is a plugin, so there should be a core..
-			// However, check just in case
-			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-			
-				public void azureusCoreRunning(AzureusCore core) {
-					
-					DownloadManager dm = PluginInitializer.getDefaultInterface().getDownloadManager();
-					
-					dm.addListener( DeviceUPnPImpl.this, true );
-				}
-			});
-		}
-				
-		addListener( this );
-
-		TranscodeFile[]	transcode_files = getFiles();
-		
-		for ( TranscodeFile file: transcode_files ){
-			
-			fileAdded( file, false );
-		}
-	}
-	
-	protected void
-	resetUPNPAV()
-	{		
-		synchronized( this ){
-			
-			if ( upnpav_ipc == null ){
-				
-				return;
-			}
-			
-			upnpav_ipc = null;
-			
-			dynamic_transcode_profile = null;
-			
-			dynamic_xcode_map = null;
-		 
-			DownloadManager dm = PluginInitializer.getDefaultInterface().getDownloadManager();
-
-			dm.removeListener( this );
-			
-			removeListener( this );
-			
-			TranscodeFile[]	transcode_files = getFiles();
-			
-			for ( TranscodeFile file: transcode_files ){
-
-				file.setTransientProperty( UPNPAV_FILE_KEY, null );
-			}
-		}
-	}
-	
-	public void
-	downloadAdded(
-		Download	download )
-	{
-		Torrent torrent = download.getTorrent();
-		
-		if ( torrent != null && PlatformTorrentUtils.isContent( torrent, false )){
-								
-			addDynamicXCode( download.getDiskManagerFileInfo()[0]);
-		}
-	}
-	
-	public void
-	downloadRemoved(
-		Download	download )
-	{
-		Torrent torrent = download.getTorrent();
-		
-		if ( torrent != null && PlatformTorrentUtils.isContent( torrent, false )){
-								
-			removeDynamicXCode( download.getDiskManagerFileInfo()[0]);
-		}
-	}
-		
-	protected void
-	addDynamicXCode(
-		final DiskManagerFileInfo		source )
-	{
-		final TranscodeProfile profile = dynamic_transcode_profile;
-		
-		IPCInterface			ipc	= upnpav_ipc;
-		
-		if ( profile == null || ipc == null ){
-			
-			return;
-		}
-		
-		try{
-			TranscodeFileImpl transcode_file = allocateFile( profile, false, source, false );
-			
-			AzureusContentFile acf = (AzureusContentFile)transcode_file.getTransientProperty( UPNPAV_FILE_KEY );
-
-			if ( acf != null ){
-				
-				return;
-			}
-			
-			final String tf_key = transcode_file.getKey();
-
-			synchronized( acf_map ){
-				
-				acf = acf_map.get( tf_key );
-			}
-			
-			if ( acf != null ){
-				
-				return;
-			}
-			
-			final DiskManagerFileInfo stream_file = 
-				new DiskManagerFileInfoStream( 
-					new DiskManagerFileInfoStream.StreamFactory()
-					{
-						private List<Object>	current_requests = new ArrayList<Object>();
-						
-						public StreamDetails 
-						getStream(
-							Object		request )
-						
-							throws IOException 
-						{						
-							try{
-								TranscodeJobImpl job = getManager().getTranscodeManager().getQueue().add(
-										(TranscodeTarget)DeviceUPnPImpl.this,
-										profile, 
-										source, 
-										true );
-									
-								synchronized( this ){
-								
-									current_requests.add( request );
-								}
-								
-								while( true ){
-									
-									InputStream is = job.getStream( 1000 );
-									
-									if ( is != null ){
-										
-										return( new StreamWrapper( is, job ));
-									}
-									
-									int	state = job.getState();
-									
-									if ( state == TranscodeJobImpl.ST_FAILED ){
-										
-										throw( new IOException( "Transcode failed: " + job.getError()));
-										
-									}else if ( state == TranscodeJobImpl.ST_CANCELLED ){
-										
-										throw( new IOException( "Transcode failed: job cancelled" ));
-	
-									}else if ( state == TranscodeJobImpl.ST_COMPLETE ){
-										
-										throw( new IOException( "Job complete but no stream!" ));
-									}
-									
-									synchronized( this ){
-										
-										if ( !current_requests.contains( request )){
-											
-											break;
-										}
-									}
-									
-									System.out.println( "waiting for stream" );
-									
-								}
-								
-								IOException error = new IOException( "Stream request cancelled" );
-								
-								job.failed( error );
-								
-								throw( error );
-								
-							}catch( IOException e ){
-								
-								throw( e );
-								
-							}catch( Throwable e ){
-								
-								throw( new IOException( "Failed to add transcode job: " + Debug.getNestedExceptionMessage(e)));
-								
-							}finally{
-								
-								synchronized( this ){
-								
-									current_requests.remove( request );
-								}
-							}
-						}
-						
-						public void 
-						destroyed(
-							Object request ) 
-						{
-							synchronized( this ){
-								
-								current_requests.remove( request );
-							}
-						}
-					},
-					transcode_file.getCacheFile());
-										
-			acf =	new AzureusContentFile()
-					{	
-					   	public DiskManagerFileInfo
-					   	getFile()
-					   	{
-					   		return( stream_file );
-					   	}
-					   	
-						public Object
-						getProperty(
-							String		name )
-						{
-								// TODO: duration etc
-
-							if ( name.equals( MY_ACF_KEY )){
-								
-								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
-								
-							}else if ( name.equals( PT_PERCENT_DONE )){
-								
-								return( new Long(1000));
-								
-							}else if ( name.equals( PT_ETA )){
-								
-								return( new Long(0));
-							}
-							
-							return( null );
-						}
-					};
-			
-			synchronized( acf_map ){
-
-				acf_map.put( tf_key, acf );
-			}
-					
-			transcode_file.setTransientProperty( UPNPAV_FILE_KEY, acf );
-
-			syncCategories( transcode_file, true );
-					
-			synchronized( this ){
-				
-				if ( dynamic_xcode_map == null ){
-					
-					dynamic_xcode_map = new HashMap<String,AzureusContentFile>();
-				}
-				
-				dynamic_xcode_map.put( tf_key, acf );
-			}
-			
-			ipc.invoke( "addContent", new Object[]{ acf });
-			
-		}catch( Throwable e ){
-			
-			Debug.out( e );
-		}
-	}
-	
-	protected void
-	removeDynamicXCode(
-		final DiskManagerFileInfo		source )
-	{
-		final TranscodeProfile profile = dynamic_transcode_profile;
-		
-		IPCInterface			ipc	= upnpav_ipc;
-		
-		if ( profile == null || ipc == null ){
-			
-			return;
-		}
-		
-		try{
-			TranscodeFileImpl transcode_file = lookupFile( profile, source );
-
-				// if the file completed transcoding then we leave the result around for
-				// the user to re-use
-			
-			if ( transcode_file != null && !transcode_file.isComplete()){
-				
-				AzureusContentFile acf = null;
-				
-				synchronized( this ){
-	
-					if ( dynamic_xcode_map != null ){
-					
-						acf = dynamic_xcode_map.get( transcode_file.getKey());
-					}
-				}
-				
-				transcode_file.delete( true );
-				
-				if ( acf != null ){
-				
-					ipc.invoke( "removeContent", new Object[]{ acf });
-				}
-				
-				synchronized( acf_map ){
-					
-					acf_map.remove( transcode_file.getKey());
-				}
-			}
-		}catch( Throwable e ){
-			
-			Debug.out( e );
-		}
-	}
-	
-	protected boolean
-	setupStreamXCode(
-		TranscodeFileImpl		transcode_file )
-	{
-		final TranscodeJobImpl	job = transcode_file.getJob();
-		
-		if ( job == null ){
-			
-				// may have just completed, say things are OK as caller can continue
-			
-			return( transcode_file.isComplete());
-		}
-		
-		final String tf_key = transcode_file.getKey();
-
-		AzureusContentFile	acf;
-		
-		synchronized( acf_map ){
-			
-			acf = acf_map.get( tf_key );
-		}
-		
-		if ( acf != null ){
-			
-			return( true );
-		}
-		
-		IPCInterface			ipc	= upnpav_ipc;
-
-		if ( ipc == null ){
-			
-			return( false );
-		}
-		
-		if ( transcode_file.getDurationMillis() == 0 ){
-			
-			return( false );
-		}
-		
-		try{
-			final DiskManagerFileInfo stream_file = 
-				new TranscodeJobOutputLeecher( job, transcode_file );
-										
-			acf =	new AzureusContentFile()
-					{	
-					   	public DiskManagerFileInfo
-					   	getFile()
-					   	{
-					   		return( stream_file );
-					   	}
-					   	
-						public Object
-						getProperty(
-							String		name )
-						{
-								// TODO: duration etc
-	
-							if ( name.equals( MY_ACF_KEY )){
-								
-								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
-								
-							}else if ( name.equals( PT_PERCENT_DONE )){
-								
-								return( new Long(1000));
-								
-							}else if ( name.equals( PT_ETA )){
-								
-								return( new Long(0));
-							}
-							
-							return( null );
-						}
-					};
-			
-			synchronized( acf_map ){
-	
-				acf_map.put( tf_key, acf );
-			}
-		
-			ipc.invoke( "addContent", new Object[]{ acf });
-
-			log( "Set up stream-xcode for " + transcode_file.getName());
-			
-			return( true );
-			
-		}catch( Throwable e ){
-			
-			return( false );
-		}
-	}
-	
-	protected boolean
-	isVisible(
-		AzureusContentDownload		file )
-	{
-		return( !getFilterFilesView());
-	}
-	
-	protected boolean
-	isVisible(
-		AzureusContentFile		file )
-	{	
-		boolean	result;
-		
-		if ( getFilterFilesView()){
-		
-			Object[] x = (Object[])file.getProperty( MY_ACF_KEY );
-			
-			if ( x != null && x[0] == this ){
-					
-				String	tf_key = (String)x[1];
-					
-				result = getTranscodeFile( tf_key ) != null;
-				
-			}else{
-				
-				result = false;
-			}
-		}else{
-			
-			result = true;
-		}
-		
-		return( result );
-	}
-	
-	public void
-	fileAdded(
-		TranscodeFile		_transcode_file )
-	{
-		fileAdded( _transcode_file, true );
-	}
-	
-	public void
-	fileAdded(
-		TranscodeFile		_transcode_file,
-		boolean				_new_file )
-	{
-		TranscodeFileImpl	transcode_file = (TranscodeFileImpl)_transcode_file;
-		
-		IPCInterface ipc = upnpav_ipc;
-		
-		synchronized( this ){
-			
-			if ( ipc == null ){
-
-				return;
-			}
-			
-			if ( !transcode_file.isComplete()){
-				
-				syncCategories( transcode_file, _new_file );
-
-				return;
-			}
-			
-			AzureusContentFile acf = (AzureusContentFile)transcode_file.getTransientProperty( UPNPAV_FILE_KEY );
-			
-			if ( acf != null ){
-				
-				return;
-			}
-
-			final String tf_key	= transcode_file.getKey();
-
-			synchronized( acf_map ){
-				
-				acf = acf_map.get( tf_key );
-			}
-			
-			if ( acf != null ){
-				
-				return;
-			}
-
-			try{
-				final DiskManagerFileInfo 	f 		= transcode_file.getTargetFile();
-							
-				acf = 
-					new AzureusContentFile()
-					{
-						public DiskManagerFileInfo
-					    getFile()
-						{
-							return( f );
-						}
-						
-						public Object
-						getProperty(
-							String		name )
-						{						
-							if(  name.equals( MY_ACF_KEY )){
-								
-								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
-								
-							}else if ( name.equals( PT_CATEGORIES )){
-								
-								TranscodeFileImpl	tf = getTranscodeFile( tf_key );
-
-								if ( tf != null ){
-									
-									return( tf.getCategories());
-								}
-							
-								return( new String[0] );
-								
-							}else{
-								
-								TranscodeFileImpl	tf = getTranscodeFile( tf_key );
-								
-								if ( tf != null ){
-									
-									long	res = 0;
-									
-									if ( name.equals( PT_DURATION )){
-										
-										res = tf.getDurationMillis();
-										
-									}else if ( name.equals( PT_VIDEO_WIDTH )){
-										
-										res = tf.getVideoWidth();
-										
-									}else if ( name.equals( PT_VIDEO_HEIGHT )){
-										
-										res = tf.getVideoHeight();
-										
-									}else if ( name.equals( PT_DATE )){
-
-										res = tf.getCreationDateMillis();
-										
-									}else if ( name.equals( PT_PERCENT_DONE )){
-
-										if ( tf.isComplete()){
-											
-											res = 1000;
-											
-										}else{
-											
-											TranscodeJob job = tf.getJob();
-											
-											if ( job == null ){
-												
-												res = 0;
-												
-											}else{
-												
-												res = 10*job.getPercentComplete();
-											}
-										}
-										
-										return( res );
-										
-									}else if ( name.equals( PT_ETA )){
-
-										if ( tf.isComplete()){
-											
-											res = 0;
-											
-										}else{
-											
-											TranscodeJob job = tf.getJob();
-											
-											if ( job == null ){
-												
-												res = Long.MAX_VALUE;
-												
-											}else{
-												
-												res = job.getETASecs();
-											}
-										}
-										
-										return( res );
-									}
-									
-									if ( res > 0 ){
-										
-										return( new Long( res ));
-									}
-								}
-							}
-							
-							return( null );
-						}
-					};
-				
-				transcode_file.setTransientProperty( UPNPAV_FILE_KEY, acf );
-
-				synchronized( acf_map ){
-
-					acf_map.put( tf_key, acf );
-				}	
-				
-				syncCategories( transcode_file, _new_file );
-					
-				try{
-					ipc.invoke( "addContent", new Object[]{ acf });
-				
-				}catch( Throwable e ){
-					
-					Debug.out( e );
-				}		
-			}catch( TranscodeException e ){
-				
-				// file deleted
-			}
-		}
-	}
-	
-	protected void
-	syncCategories(
-		TranscodeFileImpl		tf,
-		boolean					inherit_from_download )
-	{
-		try{
-			Download dl = tf.getSourceFile().getDownload();
-			
-			if ( dl != null ){
-				
-					// only overwrite categories with the downloads ones if none already set
-				
-				if ( inherit_from_download ){
-				
-					setCategories( tf, dl );
-				}
-				
-				final String tf_key = tf.getKey();
-				
-				dl.addAttributeListener(
-					new DownloadAttributeListener()
-					{
-						public void 
-						attributeEventOccurred(
-							Download 			download,
-							TorrentAttribute 	attribute, 
-							int 				eventType) 
-						{
-							TranscodeFileImpl tf = getTranscodeFile( tf_key );
-							
-							if ( tf != null ){
-								
-								setCategories( tf, download );
-							}
-						}
-					},
-					upnp_manager.getCategoryAttibute(),
-					DownloadAttributeListener.WRITTEN );
-			}
-		}catch( Throwable e ){
-			
-		}
-	}
-	
-	protected void
-	setCategories(
-		TranscodeFileImpl		tf,
-		Download				dl )
-	{
-		String	cat = dl.getCategoryName();
-		
-		if ( cat != null && cat.length() > 0 && !cat.equals( "Categories.uncategorized" )){
-			
-			tf.setCategories( new String[]{ cat });
-			
-		}else{
-			
-			tf.setCategories( new String[0] );
-		}
-	}
-	
-	public void
-	fileChanged(
-		TranscodeFile		file,
-		int					type,
-		Object				data )
-	{
-		if ( file.isComplete()){
-			
-			fileAdded( file, false );
-		}
-		
-		if ( type == TranscodeTargetListener.CT_PROPERTY ){
-			
-			if ( data == TranscodeFile.PT_CATEGORY ){
-				
-				AzureusContentFile	acf;
-				
-				synchronized( acf_map ){
-				
-					acf = acf_map.get(((TranscodeFileImpl)file).getKey());
-				}
-				
-				if ( acf != null ){
-					
-					AzureusPlatformContentDirectory.fireChanged( acf );
-				}
-			}
-		}
-	}
-	
-	public void
-	fileRemoved(
-		TranscodeFile		file )
-	{
-		IPCInterface ipc = upnp_manager.getUPnPAVIPC();
-		
-		if ( ipc == null ){
-			
-			return;
-		}
-
-		synchronized( this ){
-
-			AzureusContentFile acf = (AzureusContentFile)file.getTransientProperty( UPNPAV_FILE_KEY );
-
-			if ( acf == null ){
-		
-				return;
-			}
-			
-			file.setTransientProperty( UPNPAV_FILE_KEY, null );
-
-			try{
-				ipc.invoke( "removeContent", new Object[]{ acf });
-			
-				
-			}catch( Throwable e ){
-				
-				Debug.out( e );
-			}
-		}
-		
-		synchronized( acf_map ){
-
-			acf_map.remove( ((TranscodeFileImpl)file).getKey());
-		}	
-	}
-	
-	protected URL
-	getPresentationURL(
-		UPnPDevice		device )
-	{
-		String	presentation = device.getRootDevice().getDevice().getPresentation();
-		
-		if ( presentation != null ){
-			
-			try{
-				URL url = new URL( presentation );
-				
-				return( url );
-
-			}catch( Throwable e ){				
-			}
-		}
-		
-		return( null );
-	}
-	
-	protected void
-	getDisplayProperties(
-		List<String[]>	dp )
-	{
-		super.getDisplayProperties( dp );
-		
-		UPnPDevice device = device_may_be_null;
-		
-		if ( device != null ){
-			
-			UPnPRootDevice root = device.getRootDevice();
-			
-			URL location = root.getLocation();
-			
-			addDP( dp, "dht.reseed.ip", location.getHost() + ":" + location.getPort()); 
-	
-			String	model_details 	= device.getModelName();
-			String	model_url		= device.getModelURL();
-			
-			if ( model_url != null && model_url.length() > 0 ){
-				model_details += " (" + model_url + ")";
-			}
-			
-			String	manu_details 	= device.getManufacturer();
-			String	manu_url		= device.getManufacturerURL();
-			
-			if ( manu_url != null && manu_url.length() > 0 ){
-				manu_details += " (" + manu_url + ")";
-			}
-			
-			addDP( dp, "device.model.desc", device.getModelDescription());
-			addDP( dp, "device.model.name", model_details );
-			addDP( dp, "device.model.num", device.getModelNumber());
-			addDP( dp, "device.manu.desc", manu_details );
-		}else{
-			
-			InetAddress ia = getAddress();
-			
-			if ( ia != null ){
-				
-				addDP( dp, "dht.reseed.ip", ia.getHostAddress()); 
-			}
-		}
-	}
-	
-	public void
-	generate(
-		IndentWriter		writer )
-	{
-		super.generate( writer );
-		
-		try{
-			writer.indent();
-			
-			UPnPDevice device = device_may_be_null;
-			
-			if ( device == null ){
-				
-				writer.println( "upnp_device=null" );
-				
-			}else{
-				
-				writer.println( "upnp_device=" + device.getFriendlyName());
-			}
-	
-			writer.println( "dyn_xcode=" + (dynamic_transcode_profile==null?"null":dynamic_transcode_profile.getName()));
-		}finally{
-			
-			writer.exdent();
-		}
-	}
-	
-	protected static class
-	StreamWrapper
-		implements DiskManagerFileInfoStream.StreamFactory.StreamDetails
-	{
-		private InputStream		is;
-		private TranscodeJob	job;
-		
-		protected
-		StreamWrapper(
-			InputStream		_is,
-			TranscodeJob	_job )
-		{
-			is		= _is;
-			job		= _job;
-		}
-		
-		public InputStream
-		getStream()
-		{
-			return( is );
-		}
-		
-		public boolean
-		hasFailed()
-		{
-			long start = SystemTime.getMonotonousTime();
-		
-			while( true ){
-				
-				int state = job.getState();
-							
-					// timing issues - we can get here during teh fail process so
-					// hang around a little if we're still running
-				
-				if ( state == TranscodeJobImpl.ST_RUNNING ){
-					
-					if ( SystemTime.getMonotonousTime() - start > 5*1000 ){
-						
-						return( true );
-						
-					}else{
-						
-						try{
-							Thread.sleep(250);
-							
-							continue;
-							
-						}catch( Throwable e ){
-							
-							return( true );
-						}
-					}
-				}
-				
-				if ( 	state == TranscodeJobImpl.ST_FAILED ||
-						state == TranscodeJobImpl.ST_CANCELLED ||
-						state == TranscodeJobImpl.ST_REMOVED ||
-						state == TranscodeJobImpl.ST_STOPPED ){
-					
-					return( true );
-				}
-			}
-		}
-	}
-}
+/*
+ * 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.io.InputStream;
+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.util.Debug;
+import org.gudy.azureus2.core3.util.IndentWriter;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadAttributeListener;
+import org.gudy.azureus2.plugins.download.DownloadManager;
+import org.gudy.azureus2.plugins.download.DownloadManagerListener;
+import org.gudy.azureus2.plugins.ipc.IPCInterface;
+import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.content.AzureusContentDownload;
+import com.aelitis.azureus.core.content.AzureusContentFile;
+import com.aelitis.azureus.core.content.AzureusPlatformContentDirectory;
+import com.aelitis.azureus.core.devices.TranscodeException;
+import com.aelitis.azureus.core.devices.TranscodeFile;
+import com.aelitis.azureus.core.devices.TranscodeJob;
+import com.aelitis.azureus.core.devices.TranscodeProfile;
+import com.aelitis.azureus.core.devices.TranscodeTarget;
+import com.aelitis.azureus.core.devices.TranscodeTargetListener;
+import com.aelitis.azureus.core.devices.DeviceManager.UnassociatedDevice;
+import com.aelitis.azureus.core.download.DiskManagerFileInfoStream;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.core.util.UUIDGenerator;
+import com.aelitis.azureus.util.PlayUtils;
+import com.aelitis.net.upnp.UPnPDevice;
+import com.aelitis.net.upnp.UPnPDeviceImage;
+import com.aelitis.net.upnp.UPnPRootDevice;
+
+public abstract class 
+DeviceUPnPImpl
+	extends DeviceImpl
+	implements TranscodeTargetListener, DownloadManagerListener
+{
+	private static final Object UPNPAV_FILE_KEY = new Object();
+		
+	private static final Map<String,AzureusContentFile>	acf_map = new WeakHashMap<String,AzureusContentFile>();
+	
+	protected static String
+	getDisplayName(
+		UPnPDevice		device )
+	{
+		UPnPDevice	root = device.getRootDevice().getDevice();
+		
+		String fn = root.getFriendlyName();
+		
+		if ( fn == null || fn.length() == 0 ){
+			
+			fn = device.getFriendlyName();
+		}
+		
+		String	dn = root.getModelName();
+		
+		if ( dn == null || dn.length() == 0 ){
+		
+			dn = device.getModelName();
+		}
+		
+		if ( dn != null && dn.length() > 0 ){
+			
+			if ( !fn.contains( dn ) && ( !dn.contains( "Azureus" ) || dn.contains( "Vuze" ))){
+			
+				fn += " (" + dn + ")";
+			}
+		}
+		
+		return( fn );
+	}
+	
+	private final String MY_ACF_KEY;
+
+	
+	private final DeviceManagerUPnPImpl	upnp_manager;
+	private volatile UPnPDevice		device_may_be_null;
+	
+	private IPCInterface		upnpav_ipc;
+	private TranscodeProfile	dynamic_transcode_profile;
+	private Map<String,AzureusContentFile>	dynamic_xcode_map;
+	
+	
+	protected
+	DeviceUPnPImpl(
+		DeviceManagerImpl		_manager,
+		UPnPDevice				_device,
+		int						_type )
+	{
+		super( _manager, _type, _type + "/" + _device.getRootDevice().getUSN(), getDisplayName( _device ), false );
+		
+		upnp_manager		= _manager.getUPnPManager();
+		setUPnPDevice(_device);
+		
+		MY_ACF_KEY = getACFKey();
+	}	
+	
+	protected
+	DeviceUPnPImpl(
+		DeviceManagerImpl	_manager,
+		int					_type,
+		String				_classification )
+
+	{
+		super( _manager, _type, UUIDGenerator.generateUUIDString(), _classification, true );
+		
+		upnp_manager		= _manager.getUPnPManager();
+		
+		MY_ACF_KEY = getACFKey();
+	}
+	
+	protected
+	DeviceUPnPImpl(
+		DeviceManagerImpl	_manager,
+		int					_type,
+		String				_uuid,
+		String				_classification,
+		boolean				_manual,
+		String				_name )
+
+	{
+		super( _manager, _type, _uuid==null?UUIDGenerator.generateUUIDString():_uuid, _classification, _manual, _name );
+		
+		upnp_manager		= _manager.getUPnPManager();
+		
+		MY_ACF_KEY = getACFKey();
+	}
+	
+	protected
+	DeviceUPnPImpl(
+		DeviceManagerImpl	_manager,
+		int					_type,
+		String				_uuid,
+		String				_classification,
+		boolean				_manual )
+
+	{
+		super( _manager, _type, _uuid, _classification, _manual );
+		
+		upnp_manager		= _manager.getUPnPManager();
+		
+		MY_ACF_KEY = getACFKey();
+	}
+	
+	protected
+	DeviceUPnPImpl(
+		DeviceManagerImpl	_manager,
+		Map					_map )
+	
+		throws IOException
+	{
+		super(_manager, _map );
+		
+		upnp_manager		= _manager.getUPnPManager();
+		
+		MY_ACF_KEY = getACFKey();
+	}
+	
+	protected String
+	getACFKey()
+	{
+		return( "DeviceUPnPImpl:device:" + getID());
+	}
+	
+	@Override
+	protected boolean
+	updateFrom(
+		DeviceImpl		_other,
+		boolean			_is_alive )
+	{
+		if ( !super.updateFrom( _other, _is_alive )){
+			
+			return( false );
+		}
+		
+		if ( !( _other instanceof DeviceUPnPImpl )){
+			
+			Debug.out( "Inconsistent" );
+			
+			return( false );
+		}
+		
+		DeviceUPnPImpl other = (DeviceUPnPImpl)_other;
+		
+		setUPnPDevice(other.device_may_be_null);
+		
+		return( true );
+	}
+	
+	@Override
+	protected void
+	initialise()
+	{
+		super.initialise();
+	}
+	
+	protected void
+	UPnPInitialised()
+	{
+	}
+	
+	@Override
+	protected void
+	destroy()
+	{
+		super.destroy();
+	}
+	
+	protected DeviceManagerUPnPImpl
+	getUPnPDeviceManager()
+	{
+		return( upnp_manager );
+	}
+	
+	protected UPnPDevice
+	getUPnPDevice()
+	{
+		return( device_may_be_null );
+	}
+	
+	protected void
+	setUPnPDevice(
+			UPnPDevice device)
+	{
+		device_may_be_null = device;
+		if (device != null) {
+			// triggers any address change logic
+			setAddress(getAddress());
+		}
+	}
+	
+	public boolean
+	isBrowsable()
+	{
+		return( true );
+	}
+	
+	public browseLocation[]
+	getBrowseLocations()
+	{
+		List<browseLocation>	locs = new ArrayList<browseLocation>();
+	
+		UPnPDevice device = device_may_be_null;
+		
+		if ( device != null ){
+			
+			URL		presentation = getPresentationURL( device );
+
+			if ( presentation != null ){
+					
+				locs.add( new browseLocationImpl( "device.upnp.present_url", presentation ));
+			}
+			
+			int userMode = COConfigurationManager.getIntParameter("User Mode");
+			
+			if ( userMode > 1 ){
+			
+				locs.add( new browseLocationImpl( "device.upnp.desc_url", device.getRootDevice().getLocation()));
+			}
+		}
+		
+		return( locs.toArray( new browseLocation[ locs.size() ]));
+	}
+	
+	public boolean
+	canFilterFilesView()
+	{
+		return( true );
+	}
+	
+	public void
+	setFilterFilesView(
+		boolean	filter )
+	{
+		boolean	existing = getFilterFilesView();
+		
+		if ( existing != filter ){
+		
+			setPersistentBooleanProperty( PP_FILTER_FILES, filter );
+		
+			IPCInterface ipc = upnpav_ipc;
+			
+			if ( ipc != null ){
+				
+				try{
+					ipc.invoke( "invalidateDirectory", new Object[]{});
+
+				}catch( Throwable e ){
+				}
+			}
+		}
+	}
+	
+	public boolean
+	getFilterFilesView()
+	{
+		return( getPersistentBooleanProperty( PP_FILTER_FILES, true ));
+	}
+	
+	public boolean
+	isLivenessDetectable()
+	{
+		return( true );
+	}
+	
+	protected URL
+	getLocation()
+	{
+		UPnPDevice device = device_may_be_null;
+		
+		if ( device != null ){
+			
+			UPnPRootDevice root = device.getRootDevice();
+			
+			return( root.getLocation());
+		}
+		
+		return( null );
+	}
+	
+	public boolean
+	canAssociate()
+	{
+		return( true );
+	}
+	
+	public void
+	associate(
+		UnassociatedDevice	assoc )
+	{
+		if ( isAlive()){
+			
+			return;
+		}
+		
+		setAddress( assoc.getAddress());
+		
+		alive();
+	}
+	
+	public InetAddress
+	getAddress()
+	{
+		try{
+
+			UPnPDevice device = device_may_be_null;
+	
+			if ( device != null ){
+				
+				UPnPRootDevice root = device.getRootDevice();
+				
+				URL location = root.getLocation();
+				
+				return( InetAddress.getByName( location.getHost() ));
+				
+			}else{
+				
+				InetAddress address = (InetAddress)getTransientProperty( TP_IP_ADDRESS );
+				
+				if ( address != null ){
+					
+					return( address );
+				}
+				
+				String last = getPersistentStringProperty( PP_IP_ADDRESS );
+				
+				if ( last != null && last.length() > 0 ){
+					
+					return( InetAddress.getByName( last ));
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+		
+		}
+		
+		return( null );
+	}
+	
+	public void
+	setAddress(
+		InetAddress	address )
+	{
+		setTransientProperty( TP_IP_ADDRESS, address );
+		
+		setPersistentStringProperty( PP_IP_ADDRESS, address.getHostAddress());
+	}
+	
+	public boolean
+	canRestrictAccess()
+	{
+		return( true );
+	}
+	
+	public String
+	getAccessRestriction()
+	{
+		return( getPersistentStringProperty( PP_RESTRICT_ACCESS, "" ));
+	}
+	
+	public void
+	setAccessRestriction(
+		String		str )
+	{
+		setPersistentStringProperty( PP_RESTRICT_ACCESS, str );
+	}
+	
+	protected URL
+	getStreamURL(
+		TranscodeFileImpl		file )
+	{
+		return( getStreamURL( file, null ));
+	}
+	
+	protected URL
+	getStreamURL(
+		TranscodeFileImpl		file,
+		String					host )
+	{
+		browseReceived();
+		
+		return( super.getStreamURL( file, host ));
+	}
+	
+	protected String
+	getMimeType(
+		TranscodeFileImpl		file )
+	{
+		browseReceived();
+		
+		return( super.getMimeType(file));
+	}
+	
+	protected void
+	browseReceived()
+	{
+		IPCInterface ipc = upnp_manager.getUPnPAVIPC();
+		
+		if ( ipc == null ){
+			
+			return;
+		}
+		
+		TranscodeProfile default_profile = getDefaultTranscodeProfile();
+		
+		if ( default_profile == null ){
+			
+			TranscodeProfile[] profiles = getTranscodeProfiles();
+			
+			for ( TranscodeProfile p: profiles ){
+				
+				if ( p.isStreamable()){
+					
+					default_profile = p;
+					
+					break;
+				}
+			}
+		}
+		
+		synchronized( this ){
+			
+			if ( upnpav_ipc != null ){
+				
+				return;
+			}
+			
+			upnpav_ipc = ipc;
+			
+			if ( default_profile != null && default_profile.isStreamable()){
+				
+				dynamic_transcode_profile	= default_profile;
+			}
+		}
+		
+		if ( dynamic_transcode_profile != null && this instanceof TranscodeTarget ){
+			
+			// In theory this is a plugin, so there should be a core..
+			// However, check just in case
+			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			
+				public void azureusCoreRunning(AzureusCore core) {
+					
+					DownloadManager dm = PluginInitializer.getDefaultInterface().getDownloadManager();
+					
+					dm.addListener( DeviceUPnPImpl.this, true );
+				}
+			});
+		}
+				
+		addListener( this );
+
+		TranscodeFile[]	transcode_files = getFiles();
+		
+		for ( TranscodeFile file: transcode_files ){
+			
+			fileAdded( file, false );
+		}
+	}
+	
+	protected void
+	resetUPNPAV()
+	{		
+		Set<String>	to_remove = new HashSet<String>();
+		
+		synchronized( this ){
+			
+			if ( upnpav_ipc == null ){
+				
+				return;
+			}
+			
+			upnpav_ipc = null;
+			
+			dynamic_transcode_profile = null;
+			
+			dynamic_xcode_map = null;
+		 
+			DownloadManager dm = PluginInitializer.getDefaultInterface().getDownloadManager();
+
+			dm.removeListener( this );
+			
+			removeListener( this );
+			
+			TranscodeFileImpl[]	transcode_files = getFiles();
+			
+			for ( TranscodeFileImpl file: transcode_files ){
+
+				file.setTransientProperty( UPNPAV_FILE_KEY, null );
+				
+				to_remove.add( file.getKey());
+			}
+		}
+		
+		synchronized( acf_map ){
+			
+			for (String key: to_remove ){
+			
+				acf_map.remove( key );
+			}
+		}
+	}
+	
+	public void
+	downloadAdded(
+		Download	download )
+	{
+		Torrent torrent = download.getTorrent();
+		
+		if ( torrent != null && PlatformTorrentUtils.isContent( torrent, false )){
+								
+			addDynamicXCode( download.getDiskManagerFileInfo()[0]);
+		}
+	}
+	
+	public void
+	downloadRemoved(
+		Download	download )
+	{
+		Torrent torrent = download.getTorrent();
+		
+		if ( torrent != null && PlatformTorrentUtils.isContent( torrent, false )){
+								
+			removeDynamicXCode( download.getDiskManagerFileInfo()[0]);
+		}
+	}
+		
+	protected void
+	addDynamicXCode(
+		final DiskManagerFileInfo		source )
+	{
+		final TranscodeProfile profile = dynamic_transcode_profile;
+		
+		IPCInterface			ipc	= upnpav_ipc;
+		
+		if ( profile == null || ipc == null ){
+			
+			return;
+		}
+		
+		try{
+			TranscodeFileImpl transcode_file = allocateFile( profile, false, source, false );
+			
+			AzureusContentFile acf = (AzureusContentFile)transcode_file.getTransientProperty( UPNPAV_FILE_KEY );
+
+			if ( acf != null ){
+				
+				return;
+			}
+			
+			final String tf_key = transcode_file.getKey();
+
+			synchronized( acf_map ){
+				
+				acf = acf_map.get( tf_key );
+			}
+			
+			if ( acf != null ){
+				
+				return;
+			}
+			
+			final DiskManagerFileInfo stream_file = 
+				new DiskManagerFileInfoStream( 
+					new DiskManagerFileInfoStream.StreamFactory()
+					{
+						private List<Object>	current_requests = new ArrayList<Object>();
+						
+						public StreamDetails 
+						getStream(
+							Object		request )
+						
+							throws IOException 
+						{						
+							try{
+								TranscodeJobImpl job = getManager().getTranscodeManager().getQueue().add(
+										(TranscodeTarget)DeviceUPnPImpl.this,
+										profile, 
+										source, 
+										false,
+										true,
+										TranscodeTarget.TRANSCODE_UNKNOWN );
+									
+								synchronized( this ){
+								
+									current_requests.add( request );
+								}
+								
+								while( true ){
+									
+									InputStream is = job.getStream( 1000 );
+									
+									if ( is != null ){
+										
+										return( new StreamWrapper( is, job ));
+									}
+									
+									int	state = job.getState();
+									
+									if ( state == TranscodeJobImpl.ST_FAILED ){
+										
+										throw( new IOException( "Transcode failed: " + job.getError()));
+										
+									}else if ( state == TranscodeJobImpl.ST_CANCELLED ){
+										
+										throw( new IOException( "Transcode failed: job cancelled" ));
+	
+									}else if ( state == TranscodeJobImpl.ST_COMPLETE ){
+										
+										throw( new IOException( "Job complete but no stream!" ));
+									}
+									
+									synchronized( this ){
+										
+										if ( !current_requests.contains( request )){
+											
+											break;
+										}
+									}
+									
+									System.out.println( "waiting for stream" );
+									
+								}
+								
+								IOException error = new IOException( "Stream request cancelled" );
+								
+								job.failed( error );
+								
+								throw( error );
+								
+							}catch( IOException e ){
+								
+								throw( e );
+								
+							}catch( Throwable e ){
+								
+								throw( new IOException( "Failed to add transcode job: " + Debug.getNestedExceptionMessage(e)));
+								
+							}finally{
+								
+								synchronized( this ){
+								
+									current_requests.remove( request );
+								}
+							}
+						}
+						
+						public void 
+						destroyed(
+							Object request ) 
+						{
+							synchronized( this ){
+								
+								current_requests.remove( request );
+							}
+						}
+					},
+					transcode_file.getCacheFile());
+										
+			acf =	new AzureusContentFile()
+					{	
+					   	public DiskManagerFileInfo
+					   	getFile()
+					   	{
+					   		return( stream_file );
+					   	}
+					   	
+						public Object
+						getProperty(
+							String		name )
+						{
+								// TODO: duration etc
+
+							if ( name.equals( MY_ACF_KEY )){
+								
+								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
+								
+							}else if ( name.equals( PT_PERCENT_DONE )){
+								
+								return( new Long(1000));
+								
+							}else if ( name.equals( PT_ETA )){
+								
+								return( new Long(0));
+							}
+							
+							return( null );
+						}
+					};
+			
+			synchronized( acf_map ){
+
+				acf_map.put( tf_key, acf );
+			}
+					
+			transcode_file.setTransientProperty( UPNPAV_FILE_KEY, acf );
+
+			syncCategories( transcode_file, true );
+					
+			synchronized( this ){
+				
+				if ( dynamic_xcode_map == null ){
+					
+					dynamic_xcode_map = new HashMap<String,AzureusContentFile>();
+				}
+				
+				dynamic_xcode_map.put( tf_key, acf );
+			}
+			
+			ipc.invoke( "addContent", new Object[]{ acf });
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	protected void
+	removeDynamicXCode(
+		final DiskManagerFileInfo		source )
+	{
+		final TranscodeProfile profile = dynamic_transcode_profile;
+		
+		IPCInterface			ipc	= upnpav_ipc;
+		
+		if ( profile == null || ipc == null ){
+			
+			return;
+		}
+		
+		try{
+			TranscodeFileImpl transcode_file = lookupFile( profile, source );
+
+				// if the file completed transcoding then we leave the result around for
+				// the user to re-use
+			
+			if ( transcode_file != null && !transcode_file.isComplete()){
+				
+				AzureusContentFile acf = null;
+				
+				synchronized( this ){
+	
+					if ( dynamic_xcode_map != null ){
+					
+						acf = dynamic_xcode_map.get( transcode_file.getKey());
+					}
+				}
+				
+				transcode_file.delete( true );
+				
+				if ( acf != null ){
+				
+					ipc.invoke( "removeContent", new Object[]{ acf });
+				}
+				
+				synchronized( acf_map ){
+					
+					acf_map.remove( transcode_file.getKey());
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	protected boolean
+	setupStreamXCode(
+		TranscodeFileImpl		transcode_file )
+	{
+		final TranscodeJobImpl	job = transcode_file.getJob();
+		
+		if ( job == null ){
+			
+				// may have just completed, say things are OK as caller can continue
+			
+			return( transcode_file.isComplete());
+		}
+		
+		final String tf_key = transcode_file.getKey();
+
+		AzureusContentFile	acf;
+		
+		synchronized( acf_map ){
+			
+			acf = acf_map.get( tf_key );
+		}
+		
+		if ( acf != null ){
+			
+			return( true );
+		}
+		
+		IPCInterface			ipc	= upnpav_ipc;
+
+		if ( ipc == null ){
+			
+			return( false );
+		}
+		
+		if ( transcode_file.getDurationMillis() == 0 ){
+			
+			return( false );
+		}
+		
+		try{
+			final DiskManagerFileInfo stream_file = 
+				new TranscodeJobOutputLeecher( job, transcode_file );
+										
+			acf =	new AzureusContentFile()
+					{	
+					   	public DiskManagerFileInfo
+					   	getFile()
+					   	{
+					   		return( stream_file );
+					   	}
+					   	
+						public Object
+						getProperty(
+							String		name )
+						{
+								// TODO: duration etc
+	
+							if ( name.equals( MY_ACF_KEY )){
+								
+								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
+								
+							}else if ( name.equals( PT_PERCENT_DONE )){
+								
+								return( new Long(1000));
+								
+							}else if ( name.equals( PT_ETA )){
+								
+								return( new Long(0));
+							}
+							
+							return( null );
+						}
+					};
+			
+			synchronized( acf_map ){
+	
+				acf_map.put( tf_key, acf );
+			}
+		
+			ipc.invoke( "addContent", new Object[]{ acf });
+
+			log( "Set up stream-xcode for " + transcode_file.getName());
+			
+			return( true );
+			
+		}catch( Throwable e ){
+			
+			return( false );
+		}
+	}
+	
+	protected boolean
+	isVisible(
+		AzureusContentDownload		file )
+	{
+		if ( getFilterFilesView() || file == null ){
+			
+			return false;
+		}
+		
+		Download download = file.getDownload();
+		
+		if ( download == null){
+			
+			return false;
+		}
+		
+		if ( download.isComplete()){
+			
+			return true;
+		}
+		
+		int numFiles = download.getDiskManagerFileCount();
+		
+		for ( int i = 0; i < numFiles; i++){
+			
+			DiskManagerFileInfo fileInfo = download.getDiskManagerFileInfo(i);
+			
+			if ( fileInfo == null || fileInfo.isDeleted() || fileInfo.isSkipped()){
+				
+				continue;
+			}
+			
+			if ( fileInfo.getLength() == fileInfo.getDownloaded()){
+				
+				return true;
+				
+			}else if ( PlayUtils.canUseEMP( fileInfo )){
+			
+				return( true );
+			}
+		}
+		
+		return false;
+	}
+	
+	protected boolean
+	isVisible(
+		AzureusContentFile		file )
+	{			
+		if ( getFilterFilesView()){
+		
+			Object[] x = (Object[])file.getProperty( MY_ACF_KEY );
+			
+			if ( x != null && x[0] == this ){
+					
+				String	tf_key = (String)x[1];
+					
+				return( getTranscodeFile( tf_key ) != null );
+				
+			}else{
+				
+				return( false );
+			}
+		}else{
+			
+			if ( file == null ){
+				
+				return( false );
+			}
+			
+			DiskManagerFileInfo fileInfo = file.getFile();
+			
+			if ( fileInfo == null || fileInfo.isDeleted() || fileInfo.isSkipped()){
+				
+				return( false );
+			}
+			
+			if ( fileInfo.getLength() == fileInfo.getDownloaded()){
+				
+				return( true );
+				
+			}else if ( PlayUtils.canUseEMP( fileInfo )){
+			
+				return( true );
+			}
+		}
+		
+		return( false );
+	}
+	
+	public void
+	fileAdded(
+		TranscodeFile		_transcode_file )
+	{
+		fileAdded( _transcode_file, true );
+	}
+	
+	public void
+	fileAdded(
+		TranscodeFile		_transcode_file,
+		boolean				_new_file )
+	{
+		TranscodeFileImpl	transcode_file = (TranscodeFileImpl)_transcode_file;
+		
+		IPCInterface ipc = upnpav_ipc;
+		
+		synchronized( this ){
+			
+			if ( ipc == null ){
+
+				return;
+			}
+			
+			if ( !transcode_file.isComplete()){
+				
+				syncCategories( transcode_file, _new_file );
+
+				return;
+			}
+			
+			AzureusContentFile acf = (AzureusContentFile)transcode_file.getTransientProperty( UPNPAV_FILE_KEY );
+			
+			if ( acf != null ){
+				
+				return;
+			}
+
+			final String tf_key	= transcode_file.getKey();
+
+			synchronized( acf_map ){
+				
+				acf = acf_map.get( tf_key );
+			}
+			
+			if ( acf != null ){
+				
+				return;
+			}
+
+			try{
+				final DiskManagerFileInfo 	f 		= transcode_file.getTargetFile();
+							
+				acf = 
+					new AzureusContentFile()
+					{
+						public DiskManagerFileInfo
+					    getFile()
+						{
+							return( f );
+						}
+						
+						public Object
+						getProperty(
+							String		name )
+						{						
+							if(  name.equals( MY_ACF_KEY )){
+								
+								return( new Object[]{ DeviceUPnPImpl.this, tf_key });
+								
+							}else if ( name.equals( PT_CATEGORIES )){
+								
+								TranscodeFileImpl	tf = getTranscodeFile( tf_key );
+
+								if ( tf != null ){
+									
+									return( tf.getCategories());
+								}
+							
+								return( new String[0] );
+								
+							} else if (name.equals(PT_TITLE)) {
+								
+								
+								TranscodeFileImpl	tf = getTranscodeFile( tf_key );
+
+								if ( tf != null ){
+									
+									return( tf.getName());
+								}
+							
+								
+							}else{
+								
+								TranscodeFileImpl	tf = getTranscodeFile( tf_key );
+								
+								if ( tf != null ){
+									
+									long	res = 0;
+									
+									if ( name.equals( PT_DURATION )){
+										
+										res = tf.getDurationMillis();
+										
+									}else if ( name.equals( PT_VIDEO_WIDTH )){
+										
+										res = tf.getVideoWidth();
+										
+									}else if ( name.equals( PT_VIDEO_HEIGHT )){
+										
+										res = tf.getVideoHeight();
+										
+									}else if ( name.equals( PT_DATE )){
+
+										res = tf.getCreationDateMillis();
+										
+									}else if ( name.equals( PT_PERCENT_DONE )){
+
+										if ( tf.isComplete()){
+											
+											res = 1000;
+											
+										}else{
+											
+											TranscodeJob job = tf.getJob();
+											
+											if ( job == null ){
+												
+												res = 0;
+												
+											}else{
+												
+												res = 10*job.getPercentComplete();
+											}
+										}
+										
+										return( res );
+										
+									}else if ( name.equals( PT_ETA )){
+
+										if ( tf.isComplete()){
+											
+											res = 0;
+											
+										}else{
+											
+											TranscodeJob job = tf.getJob();
+											
+											if ( job == null ){
+												
+												res = Long.MAX_VALUE;
+												
+											}else{
+												
+												res = job.getETASecs();
+											}
+										}
+										
+										return( res );
+									}
+									
+									if ( res > 0 ){
+										
+										return( new Long( res ));
+									}
+								}
+							}
+							
+							return( null );
+						}
+					};
+				
+				transcode_file.setTransientProperty( UPNPAV_FILE_KEY, acf );
+
+				synchronized( acf_map ){
+
+					acf_map.put( tf_key, acf );
+				}	
+				
+				syncCategories( transcode_file, _new_file );
+					
+				try{
+					ipc.invoke( "addContent", new Object[]{ acf });
+				
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}		
+			}catch( TranscodeException e ){
+				
+				// file deleted
+			}
+		}
+	}
+	
+	protected void
+	syncCategories(
+		TranscodeFileImpl		tf,
+		boolean					inherit_from_download )
+	{
+		try{
+			Download dl = tf.getSourceFile().getDownload();
+			
+			if ( dl != null ){
+				
+					// only overwrite categories with the downloads ones if none already set
+				
+				if ( inherit_from_download ){
+				
+					setCategories( tf, dl );
+				}
+				
+				final String tf_key = tf.getKey();
+				
+				dl.addAttributeListener(
+					new DownloadAttributeListener()
+					{
+						public void 
+						attributeEventOccurred(
+							Download 			download,
+							TorrentAttribute 	attribute, 
+							int 				eventType) 
+						{
+							TranscodeFileImpl tf = getTranscodeFile( tf_key );
+							
+							if ( tf != null ){
+								
+								setCategories( tf, download );
+							}
+						}
+					},
+					upnp_manager.getCategoryAttibute(),
+					DownloadAttributeListener.WRITTEN );
+			}
+		}catch( Throwable e ){
+			
+		}
+	}
+	
+	protected void
+	setCategories(
+		TranscodeFileImpl		tf,
+		Download				dl )
+	{
+		String	cat = dl.getCategoryName();
+		
+		if ( cat != null && cat.length() > 0 && !cat.equals( "Categories.uncategorized" )){
+			
+			tf.setCategories( new String[]{ cat });
+			
+		}else{
+			
+			tf.setCategories( new String[0] );
+		}
+	}
+	
+	public void
+	fileChanged(
+		TranscodeFile		file,
+		int					type,
+		Object				data )
+	{
+		if ( file.isComplete()){
+			
+			fileAdded( file, false );
+		}
+		
+		if ( type == TranscodeTargetListener.CT_PROPERTY ){
+			
+			if ( data == TranscodeFile.PT_CATEGORY ){
+				
+				AzureusContentFile	acf;
+				
+				synchronized( acf_map ){
+				
+					acf = acf_map.get(((TranscodeFileImpl)file).getKey());
+				}
+				
+				if ( acf != null ){
+					
+					AzureusPlatformContentDirectory.fireChanged( acf );
+				}
+			}
+		}
+	}
+	
+	public void
+	fileRemoved(
+		TranscodeFile		file )
+	{
+		IPCInterface ipc = upnp_manager.getUPnPAVIPC();
+		
+		if ( ipc == null ){
+			
+			return;
+		}
+
+		synchronized( this ){
+
+			AzureusContentFile acf = (AzureusContentFile)file.getTransientProperty( UPNPAV_FILE_KEY );
+
+			if ( acf == null ){
+		
+				return;
+			}
+			
+			file.setTransientProperty( UPNPAV_FILE_KEY, null );
+
+			try{
+				ipc.invoke( "removeContent", new Object[]{ acf });
+			
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		synchronized( acf_map ){
+
+			acf_map.remove( ((TranscodeFileImpl)file).getKey());
+		}	
+	}
+	
+	protected URL
+	getPresentationURL(
+		UPnPDevice		device )
+	{
+		String	presentation = device.getRootDevice().getDevice().getPresentation();
+		
+		if ( presentation != null ){
+			
+			try{
+				URL url = new URL( presentation );
+				
+				return( url );
+
+			}catch( Throwable e ){				
+			}
+		}
+		
+		return( null );
+	}
+	
+	protected void
+	getDisplayProperties(
+		List<String[]>	dp )
+	{
+		super.getDisplayProperties( dp );
+		
+		UPnPDevice device = device_may_be_null;
+		
+		if ( device != null ){
+			
+			UPnPRootDevice root = device.getRootDevice();
+			
+			URL location = root.getLocation();
+			
+			addDP( dp, "dht.reseed.ip", location.getHost() + ":" + location.getPort()); 
+	
+			String	model_details 	= device.getModelName();
+			String	model_url		= device.getModelURL();
+			
+			if ( model_url != null && model_url.length() > 0 ){
+				model_details += " (" + model_url + ")";
+			}
+			
+			String	manu_details 	= device.getManufacturer();
+			String	manu_url		= device.getManufacturerURL();
+			
+			if ( manu_url != null && manu_url.length() > 0 ){
+				manu_details += " (" + manu_url + ")";
+			}
+			
+			addDP( dp, "device.model.desc", device.getModelDescription());
+			addDP( dp, "device.model.name", model_details );
+			addDP( dp, "device.model.num", device.getModelNumber());
+			addDP( dp, "device.manu.desc", manu_details );
+			
+		}else{
+			
+			InetAddress ia = getAddress();
+			
+			if ( ia != null ){
+				
+				addDP( dp, "dht.reseed.ip", ia.getHostAddress()); 
+			}
+		}
+		addDP( dp, "!Is Liveness Detectable!", isLivenessDetectable());
+		if ( isManual() ){
+			
+			addDP( dp, "azbuddy.ui.table.online",  isAlive() );
+		
+			addDP( dp, "device.lastseen", getLastSeen()==0?"":new SimpleDateFormat().format(new Date( getLastSeen() )));
+		}
+	}
+	
+	public void
+	generate(
+		IndentWriter		writer )
+	{
+		super.generate( writer );
+		
+		try{
+			writer.indent();
+			
+			UPnPDevice device = device_may_be_null;
+			
+			if ( device == null ){
+				
+				writer.println( "upnp_device=null" );
+				
+			}else{
+				
+				writer.println( "upnp_device=" + device.getFriendlyName());
+			}
+	
+			writer.println( "dyn_xcode=" + (dynamic_transcode_profile==null?"null":dynamic_transcode_profile.getName()));
+		}finally{
+			
+			writer.exdent();
+		}
+	}
+	
+	protected static class
+	StreamWrapper
+		implements DiskManagerFileInfoStream.StreamFactory.StreamDetails
+	{
+		private InputStream		is;
+		private TranscodeJob	job;
+		
+		protected
+		StreamWrapper(
+			InputStream		_is,
+			TranscodeJob	_job )
+		{
+			is		= _is;
+			job		= _job;
+		}
+		
+		public InputStream
+		getStream()
+		{
+			return( is );
+		}
+		
+		public boolean
+		hasFailed()
+		{
+			long start = SystemTime.getMonotonousTime();
+		
+			while( true ){
+				
+				int state = job.getState();
+							
+					// timing issues - we can get here during teh fail process so
+					// hang around a little if we're still running
+				
+				if ( state == TranscodeJobImpl.ST_RUNNING ){
+					
+					if ( SystemTime.getMonotonousTime() - start > 5*1000 ){
+						
+						return( true );
+						
+					}else{
+						
+						try{
+							Thread.sleep(250);
+							
+							continue;
+							
+						}catch( Throwable e ){
+							
+							return( true );
+						}
+					}
+				}
+				
+				if ( 	state == TranscodeJobImpl.ST_FAILED ||
+						state == TranscodeJobImpl.ST_CANCELLED ||
+						state == TranscodeJobImpl.ST_REMOVED ||
+						state == TranscodeJobImpl.ST_STOPPED ){
+					
+						// might have completed and then been removed
+					
+					TranscodeFile tf = job.getTranscodeFile();
+					
+					if ( tf != null && tf.isComplete()){
+						
+						return( false );
+					}
+					
+					return( true );
+				}
+			}
+		}
+	}
+
+	@Override
+	public String getImageID() {
+		String imageID = super.getImageID();
+		// commented out existing imageid check so upnp device image overrides
+		if (/*imageID == null && */ device_may_be_null != null && isAlive()) {
+			UPnPDeviceImage[] images = device_may_be_null.getImages();
+			if (images.length > 0) {
+				URL location = getLocation();
+				if (location != null) {
+					String url = "http://" + location.getHost() + ":" + location.getPort();
+					String imageUrl = images[0].getLocation(); 
+					for (UPnPDeviceImage imageInfo : images) {
+						String mime = imageInfo.getLocation();
+						if (mime != null && mime.contains("png")) {
+							imageUrl = imageInfo.getLocation();
+							break;
+						}
+					}
+					if (!imageUrl.startsWith("/")) {
+						url += "/";
+					}
+					url += imageUrl;
+					return url;
+				}
+			}
+		}
+		return imageID;
+	}
+}
diff --git a/com/aelitis/azureus/core/devices/impl/DeviceiTunes.java b/com/aelitis/azureus/core/devices/impl/DeviceiTunes.java
index 661a76a..4516490 100644
--- a/com/aelitis/azureus/core/devices/impl/DeviceiTunes.java
+++ b/com/aelitis/azureus/core/devices/impl/DeviceiTunes.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.devices.impl;
 import java.io.File;
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.URL;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -197,6 +198,21 @@ DeviceiTunes
 		return( true );
 	}
 	
+	@Override
+	public URL
+	getWikiURL()
+	{
+		try{
+			return( new URL( MessageText.getString( "device.wiki.itunes" )) );
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( null );
+		}
+	}
+	
 	protected void
 	destroy()
 	{
@@ -435,6 +451,12 @@ DeviceiTunes
 		return( false );
 	}
 	
+	public boolean
+	canRestrictAccess()
+	{
+		return( false );
+	}
+	
 	public void
 	associate(
 		UnassociatedDevice	assoc )
@@ -613,6 +635,23 @@ DeviceiTunes
 		}
 	}
 	
+	public String
+	getStatus()
+	{
+		if ( is_running ){
+			
+			return( MessageText.getString( "device.itunes.status.running" ));
+			
+		}else if ( is_installed ){
+			
+			return( MessageText.getString( "device.itunes.status.notrunning" ));
+
+		}else{
+			
+			return( MessageText.getString( "device.itunes.status.notinstalled" ));
+		}     
+	}
+	
 	public void
 	generate(
 		IndentWriter		writer )
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
index 4bed1bd..e6baaba 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeFileImpl.java
@@ -30,9 +30,7 @@ import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.gudy.azureus2.core3.util.Base32;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
@@ -44,6 +42,7 @@ import com.aelitis.azureus.core.devices.TranscodeFile;
 import com.aelitis.azureus.core.devices.TranscodeJob;
 import com.aelitis.azureus.core.devices.TranscodeProviderAnalysis;
 import com.aelitis.azureus.core.devices.TranscodeTargetListener;
+import com.aelitis.azureus.core.download.DiskManagerFileInfoDelegate;
 import com.aelitis.azureus.core.download.DiskManagerFileInfoFile;
 import com.aelitis.azureus.util.ImportExportUtils;
 
@@ -63,14 +62,16 @@ TranscodeFileImpl
 	private static final String			KEY_DURATION			= "at_dur";
 	private static final String			KEY_VIDEO_WIDTH			= "at_vw";
 	private static final String			KEY_VIDEO_HEIGHT		= "at_vh";
+	private static final String			KEY_XCODE_SIZE			= "at_xs";
 	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 static final String			KEY_COPYING	= "copying";
 
 	private DeviceImpl					device;
 	private String						key;
 	private Map<String,Map<String,?>>	files_map;
-	
+
 		// don't store any local state here, store it in the map as this is just a wrapper
 		// for the underlying map and there can be multiple such wrappers concurrent
 	
@@ -96,6 +97,8 @@ TranscodeFileImpl
 		setLong( KEY_DATE, SystemTime.getCurrentTime());
 		
 		setBoolean( KEY_FOR_JOB, _for_job );
+		
+		setBoolean( KEY_COPYING, false );
 	}
 	
 	protected
@@ -242,7 +245,7 @@ TranscodeFileImpl
 					
 					int index = (int)getLong( KEY_SOURCE_FILE_INDEX );
 					
-					return( download.getDiskManagerFileInfo()[index] );
+					return( download.getDiskManagerFileInfo(index) );
 				}
 				
 			}catch( Throwable e ){
@@ -305,7 +308,24 @@ TranscodeFileImpl
 		
 		if ( getBoolean( KEY_NO_XCODE )){
 			
-			return( getSourceFile());
+			DiskManagerFileInfo res = getSourceFile();
+			
+			if ( res instanceof DiskManagerFileInfoFile ){
+				
+				return( res );
+				
+			}else{
+				
+				try{
+					return( new DiskManagerFileInfoDelegate( res ));
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+					
+					return( res );
+				}
+			}
 		}
 		
 			// Debug.out( "Target file for " + cache_file + " doesn't exist" );
@@ -358,15 +378,20 @@ TranscodeFileImpl
 	setCopiedToDevice(
 		boolean b )
 	{
+
 		setBoolean( PT_COPIED, b );
 		
 		setLong( PT_COPY_FAILED, 0 );
+
+		setCopyingToDevice(false);
 	}
 	
 	protected void
 	setCopyToDeviceFailed()
 	{
 		setLong( PT_COPY_FAILED, getLong( PT_COPY_FAILED ) + 1 );
+
+		setCopyingToDevice(false);
 	}
 	
 	public long
@@ -430,10 +455,15 @@ TranscodeFileImpl
 	protected void
 	update(
 		TranscodeProviderAnalysis		analysis )
+	
+		throws TranscodeException
 	{
+		checkDeleted();
+		
 		long	duration		= analysis.getLongProperty( TranscodeProviderAnalysis.PT_DURATION_MILLIS );
 		long	video_width		= analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_WIDTH );
 		long	video_height	= analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_HEIGHT );
+		long	xcode_size		= analysis.getLongProperty( TranscodeProviderAnalysis.PT_ESTIMATED_XCODE_SIZE );
 
 		if ( duration > 0 ){
 			
@@ -446,6 +476,11 @@ TranscodeFileImpl
 			
 			setLong( KEY_VIDEO_HEIGHT, video_height );
 		}
+		
+		if ( xcode_size > 0 ){
+			
+			setLong( KEY_XCODE_SIZE, xcode_size );
+		}
 	}
 	
 	protected void
@@ -479,6 +514,12 @@ TranscodeFileImpl
 		return( getLong( KEY_VIDEO_HEIGHT ));
 	}
 	
+	public long
+	getEstimatedTranscodeSize()
+	{
+		return( getLong( KEY_XCODE_SIZE ));
+	}
+	
 	public String[] 
 	getCategories() 
 	{
@@ -489,7 +530,7 @@ TranscodeFileImpl
 			return( new String[0] );
 		}
 		
-		return( cats.split( "," ));
+		return( Constants.PAT_SPLIT_COMMA.split(cats));
 	}
 	
 	public void
@@ -759,4 +800,17 @@ TranscodeFileImpl
 			return( key + ": " + map );
 		}
 	}
+
+	public void 
+	setCopyingToDevice(
+			boolean b)
+	{
+		setBoolean(KEY_COPYING, b);
+	}
+	
+	public boolean
+	isCopyingToDevice()
+	{
+		return getBoolean(KEY_COPYING);
+	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
index e6fecdf..28b8dfc 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeJobImpl.java
@@ -27,6 +27,7 @@ import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
@@ -34,11 +35,17 @@ import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
 import org.gudy.azureus2.plugins.download.DownloadRemovalVetoException;
 import org.gudy.azureus2.plugins.download.DownloadWillBeRemovedListener;
+import org.gudy.azureus2.plugins.peers.PeerManager;
+import org.gudy.azureus2.plugins.peers.PeerManagerStats;
+import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
+import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+import com.aelitis.azureus.core.devices.TranscodeAnalysisListener;
 import com.aelitis.azureus.core.devices.TranscodeJob;
 import com.aelitis.azureus.core.devices.TranscodeProfile;
 import com.aelitis.azureus.core.devices.TranscodeException;
+import com.aelitis.azureus.core.devices.TranscodeActionVetoException;
 import com.aelitis.azureus.core.devices.TranscodeTarget;
 import com.aelitis.azureus.core.download.DiskManagerFileInfoFile;
 import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
@@ -72,7 +79,9 @@ TranscodeJobImpl
 	private long					process_time;
 	
 	private boolean					use_direct_input;
+	private boolean					prefer_direct_input;
 	
+	private boolean					auto_retry_enabled	= true;
 	private boolean					auto_retry;
 	private int						auto_retry_count;
 	
@@ -85,6 +94,7 @@ TranscodeJobImpl
 		TranscodeTarget			_target,
 		TranscodeProfile		_profile,
 		DiskManagerFileInfo		_file,
+		boolean					_add_stopped,
 		int						_transcode_requirement,
 		boolean					_is_stream )
 	
@@ -97,6 +107,11 @@ TranscodeJobImpl
 		transcode_requirement	= _transcode_requirement;
 		is_stream				= _is_stream;
 		
+		if ( _add_stopped ){
+			
+			state = ST_STOPPED;
+		}
+		
 		init();
 	}
 	
@@ -140,7 +155,11 @@ TranscodeJobImpl
 			file = new DiskManagerFileInfoFile( new File( file_str ));
 		}
 		
-		transcode_requirement	= ImportExportUtils.importInt( map, "trans_req", -1 );
+		transcode_requirement	= ImportExportUtils.importInt( map, "trans_req", TranscodeTarget.TRANSCODE_UNKNOWN );
+		
+		auto_retry_enabled = ImportExportUtils.importBoolean( map, "ar_enable", true );
+		
+		prefer_direct_input = ImportExportUtils.importBoolean( map, "pdi", false );
 		
 		init();
 	}
@@ -175,7 +194,11 @@ TranscodeJobImpl
 			}
 		
 			ImportExportUtils.exportInt( map, "trans_req", transcode_requirement );
-					
+				
+			ImportExportUtils.exportBoolean( map, "ar_enable", auto_retry_enabled );
+			
+			ImportExportUtils.exportBoolean( map, "pdi", prefer_direct_input );
+			
 			return( map );
 			
 		}catch( Throwable e ){
@@ -224,13 +247,16 @@ TranscodeJobImpl
 			long	downloaded 	= file.getDownloaded();
 			long	length		= file.getLength();
 			
-			if ( 	download == null || downloaded == length ){
+			if ( download == null || downloaded == length ){
 				
 				download_ok = true;
 				
 			}else{
 
-				if ( PlatformTorrentUtils.isContent( download.getTorrent(), false )){
+				Torrent torrent = download.getTorrent();
+						
+				if ( 	PlatformTorrentUtils.isContent( torrent, false ) || 
+						PlatformTorrentUtils.getContentNetworkID( PluginCoreUtils.unwrap( torrent )) == ContentNetwork.CONTENT_NETWORK_VHDNL ){
 					
 					download_ok = true;
 					
@@ -241,6 +267,38 @@ TranscodeJobImpl
 					if ( percent_done >= TRANSCODE_OK_DL_PERCENT ){
 						
 						download_ok = true;
+						
+					}else{
+						
+						PeerManager pm = download.getPeerManager();
+						
+						if ( pm != null ){
+							
+							PeerManagerStats stats = pm.getStats();
+							
+							int connected_seeds 	= stats.getConnectedSeeds();
+							int connected_leechers	= stats.getConnectedLeechers();
+							
+							
+							if ( connected_seeds > 10 && connected_seeds > connected_leechers ){
+								
+								download_ok = true;
+							}
+						}else{
+							
+							int state = download.getState();
+							
+							if ( state == Download.ST_STOPPED ){
+								
+								try{
+									download.restart();
+									
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}
+						}
 					}
 				}
 			}
@@ -309,7 +367,8 @@ TranscodeJobImpl
 	{
 		synchronized( this ){
 
-			return( use_direct_input );
+			return( use_direct_input || 
+					( getPreferDirectInput() && canUseDirectInput()));
 		}
 	}
 	
@@ -322,6 +381,25 @@ TranscodeJobImpl
 		}
 	}
 	
+	public void
+	setPreferDirectInput(
+		boolean		prefer )
+	{
+		synchronized( this ){
+		
+			prefer_direct_input = prefer;
+		}
+	}
+	
+	public boolean
+	getPreferDirectInput()
+	{
+		synchronized( this ){
+		
+			return( prefer_direct_input );
+		}
+	}
+	
 	protected void
 	setAutoRetry(
 		boolean		_auto_retry )
@@ -359,6 +437,19 @@ TranscodeJobImpl
 		}
 	}
 	
+	public void
+	setEnableAutoRetry(
+		boolean		enabled )
+	{
+		auto_retry_enabled = enabled;
+	}
+	
+	public boolean 
+	getEnableAutoRetry() 
+	{
+		return( auto_retry_enabled );
+	}
+	
 	protected boolean
 	isStream()
 	{
@@ -410,7 +501,9 @@ TranscodeJobImpl
 			
 		}else{
 			
-			throw( new DownloadRemovalVetoException( "Transcode in progress, removal refused" ));
+			throw( new DownloadRemovalVetoException( 
+					MessageText.getString( "devices.xcode.remove.vetoed",
+						new String[]{ download.getName()})));
 		}
 	}
 	
@@ -484,22 +577,6 @@ TranscodeJobImpl
 		}
 		
 		queue.jobChanged( this, false, true );
-
-		// I'd rather do qos from a listener trigger, but for now this ensures
-		// 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 = state;
-			if (state != ST_STOPPED && !isStream() && getAutoRetryCount() == 0
-					&& canUseDirectInput() && !useDirectInput()) {
-				// we are going to retry..
-				logState |= 0x100;
-			}
-			
-			PlatformDevicesMessenger.qosTranscode(this, logState);
-		} catch (Throwable t) {
-			Debug.out(t);
-		}
 	}
 	
 	protected void
@@ -524,15 +601,6 @@ TranscodeJobImpl
 		transcode_file.setComplete( true );
 		
 		queue.jobChanged( this, false, false );
-
-		// I'd rather do qos from a listener trigger, but for now this ensures
-		// I get the event even if listeners haven't had a chance to be added
-		// This also ensures only one completed qos event gets sent
-		try {
-			PlatformDevicesMessenger.qosTranscode(this, TranscodeJob.ST_COMPLETE);
-		} catch (Throwable t) {
-			Debug.out(t);
-		}
 	}
 	
 	protected void
@@ -566,6 +634,15 @@ TranscodeJobImpl
 		return( getDevice().getTranscodeRequirement());
 	}
 	
+	public void
+	analyseNow(
+		TranscodeAnalysisListener	listener )
+	
+		throws TranscodeException
+	{
+		queue.analyse( this, listener );
+	}
+	
 	protected DeviceImpl
 	getDevice()
 	{
@@ -773,8 +850,22 @@ TranscodeJobImpl
 	
 	public void
 	remove()
+	
+		throws TranscodeActionVetoException
+	{
+		queue.remove( this, false );
+	}
+	
+	public void
+	removeForce()
 	{
-		queue.remove( this );
+		try{
+			queue.remove( this, true );
+			
+		}catch( TranscodeActionVetoException e ){
+			
+			Debug.out( e );
+		}
 	}
 	
 	protected void
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeJobOutputLeecher.java b/com/aelitis/azureus/core/devices/impl/TranscodeJobOutputLeecher.java
index 456203e..38dddcb 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeJobOutputLeecher.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeJobOutputLeecher.java
@@ -32,6 +32,7 @@ import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
 import org.gudy.azureus2.plugins.disk.DiskManagerEvent;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
 import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
@@ -80,6 +81,19 @@ TranscodeJobOutputLeecher
 	{
 	}
 	
+	public int 
+	getNumericPriorty() 
+	{
+		return( 0 );
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		throw( new RuntimeException( "Not supported" ));
+	}
+	
 	public void 
 	setSkipped(
 		boolean b )
@@ -141,6 +155,13 @@ TranscodeJobOutputLeecher
 		return( save_to );
 	}
 		
+	public File
+	getFile(
+		boolean	follow_link )
+	{
+		return( save_to );
+	}
+	
 	public int
 	getIndex()
 	{
@@ -207,11 +228,24 @@ TranscodeJobOutputLeecher
 		return( new Channel());
 	}
 	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		throw( new DownloadException( "Not supported" ));
+	}
+	
 	protected class
 	Channel
 		implements DiskManagerChannel
 	{
 		private volatile boolean		channel_destroyed;
+		private volatile long			channel_position;
 		
 		private RandomAccessFile		raf;
 		
@@ -227,6 +261,18 @@ TranscodeJobOutputLeecher
 			return( TranscodeJobOutputLeecher.this );
 		}
 		
+		public long 
+		getPosition() 
+		{
+			return( channel_position );
+		}
+		
+		public boolean 
+		isDestroyed() 
+		{
+			return( channel_destroyed );
+		}
+		
 		public void
 		destroy()
 		{
@@ -497,6 +543,8 @@ TranscodeJobOutputLeecher
 					event_type		= DiskManagerEvent.EVENT_TYPE_BLOCKED;
 
 					event_offset	= _offset;	
+					
+					channel_position = _offset;
 				}
 				
 				protected
@@ -509,6 +557,8 @@ TranscodeJobOutputLeecher
 					buffer			= _buffer;
 					event_offset	= _offset;
 					event_length	= _length;
+					
+					channel_position = _offset + _length - 1;
 				}
 				
 				public int
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeManagerImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeManagerImpl.java
index be647f9..56a9e2b 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeManagerImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeManagerImpl.java
@@ -21,10 +21,24 @@
 
 package com.aelitis.azureus.core.devices.impl;
 
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.category.Category;
+import org.gudy.azureus2.core3.category.CategoryListener;
+import org.gudy.azureus2.core3.category.CategoryManager;
+import org.gudy.azureus2.core3.category.CategoryManagerListener;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
+import org.gudy.azureus2.core3.global.GlobalManagerListener;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -45,7 +59,14 @@ TranscodeManagerImpl
 	
 	private TranscodeQueueImpl		queue = new TranscodeQueueImpl( this );
 	
-	private AESemaphore	init_sem = new AESemaphore( "TM:init" );
+	private AESemaphore	init_sem 	= new AESemaphore( "TM:init" );
+
+	private boolean hooked_categories;
+	
+	private Map<Category,Object[]> 	category_map = new HashMap<Category, Object[]>();
+	private CategoryListener		category_listener;
+	private GlobalManagerListener	category_dl_listener;
+	private TorrentAttribute		category_ta;
 	
 	protected
 	TranscodeManagerImpl(
@@ -55,51 +76,64 @@ TranscodeManagerImpl
 		
 		azureus_core = AzureusCoreFactory.getSingleton();
 		
-		PluginInitializer.getDefaultInterface().addListener(
+		PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+		
+		category_ta = default_pi.getTorrentManager().getPluginAttribute( "xcode.cat.done" );
+		
+		final AESemaphore	plugin_sem 	= new AESemaphore( "TM:plugin" );
+
+		default_pi.addListener(
 			new PluginListener()
 			{
 				public void
 				initializationComplete()
 				{
-					PluginInterface default_pi = PluginInitializer.getDefaultInterface();
-					default_pi.addEventListener(
-						new PluginEventListener()
-						{
-							public void 
-							handleEvent(
-								PluginEvent ev )
+					try{
+						PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+						
+						default_pi.addEventListener(
+							new PluginEventListener()
 							{
-								int	type = ev.getType();
-								
-								if ( type == PluginEvent.PEV_PLUGIN_OPERATIONAL ){
-									
-									pluginAdded((PluginInterface)ev.getValue());
-								}
-								if ( type == PluginEvent.PEV_PLUGIN_NOT_OPERATIONAL ){
+								public void 
+								handleEvent(
+									PluginEvent ev )
+								{
+									int	type = ev.getType();
 									
-									pluginRemoved((PluginInterface)ev.getValue());
+									if ( type == PluginEvent.PEV_PLUGIN_OPERATIONAL ){
+										
+										pluginAdded((PluginInterface)ev.getValue());
+									}
+									if ( type == PluginEvent.PEV_PLUGIN_NOT_OPERATIONAL ){
+										
+										pluginRemoved((PluginInterface)ev.getValue());
+									}
 								}
-							}
-						});
-					
-					PluginInterface[] plugins = default_pi.getPluginManager().getPlugins();
-					
-					for ( PluginInterface pi: plugins ){
+							});
 						
-						if ( pi.getPluginState().isOperational()){
+						PluginInterface[] plugins = default_pi.getPluginManager().getPlugins();
 						
-							pluginAdded( pi );
+						for ( PluginInterface pi: plugins ){
+							
+							if ( pi.getPluginState().isOperational()){
+							
+								pluginAdded( pi );
+							}
 						}
+					}finally{
+						
+						plugin_sem.releaseForever();
 					}
-					
-					queue.initialise();
-					
-					init_sem.releaseForever();
 				}
 				
 				public void
 				closedownInitiated()
-				{	
+				{
+					plugin_sem.releaseForever();
+					
+						// we don't want things hanging around for init if we're closing
+					
+					init_sem.releaseForever();
 				}
 				
 				public void
@@ -107,6 +141,21 @@ TranscodeManagerImpl
 				{
 				}
 			});
+		
+		if ( !plugin_sem.reserve( 30*1000 )){
+			
+			Debug.out( "Timeout waiting for init" );
+			
+			AEDiagnostics.dumpThreads();
+		}
+	}
+	
+	protected void
+	initialise()
+	{
+		queue.initialise();
+		
+		init_sem.releaseForever();
 	}
 	
 	protected void
@@ -218,6 +267,308 @@ TranscodeManagerImpl
 		if ( queue != null ){
 			
 			queue.updateStatus( tick_count );
+			
+			if ( !hooked_categories ){
+				
+				hooked_categories = true;
+				
+				CategoryManager.addCategoryManagerListener(
+					new CategoryManagerListener()
+					{
+						public void
+						categoryAdded(
+							Category category )
+						{
+						}
+							
+						public void
+						categoryRemoved(
+							Category category )
+						{
+						}
+						
+						public void
+						categoryChanged(
+							Category category )
+						{
+							checkCategories();
+						}
+					});
+				
+				checkCategories();
+			}
+		}
+	}
+	
+	private void
+	checkCategories()
+	{
+		Category[] cats = CategoryManager.getCategories();
+		
+		Map<Category,Object[]> active_map = new HashMap<Category, Object[]>();
+		
+		for ( Category cat: cats ){
+			
+			String target = cat.getStringAttribute( Category.AT_AUTO_TRANSCODE_TARGET );
+			
+			if ( target != null ){
+				
+				String device_id = null;
+				
+				if ( target.endsWith( "/blank" )){
+					
+					device_id = target.substring( 0, target.length() - 6 );
+				}
+				
+				DeviceMediaRenderer		target_dmr			= null;
+				TranscodeProfile		target_profile 		= null;
+				
+				for ( DeviceImpl device: device_manager.getDevices()){
+				
+					if ( !( device instanceof DeviceMediaRenderer )){
+						
+						continue;
+					}
+					
+					DeviceMediaRenderer dmr = (DeviceMediaRenderer)device;
+					
+					if ( device_id != null ){
+						
+						if ( device.getID().equals( device_id )){
+							
+							target_dmr		 	= dmr;
+							target_profile		= device.getBlankProfile();
+							
+							break;
+						}
+					}else{
+						
+						TranscodeProfile[] profs = device.getTranscodeProfiles();
+						
+						for ( TranscodeProfile prof: profs ){
+							
+							if ( prof.getUID().equals( target )){
+								
+								target_dmr	= dmr;
+								target_profile	= prof;
+								
+								break;
+							}
+						}
+					}
+				}
+			
+				if ( target_dmr != null ){
+					
+					active_map.put( cat, new Object[]{ target_dmr, target_profile });					
+				}
+			}
+		}
+		
+		Map<Category,Object[]> to_process = new HashMap<Category, Object[]>();
+		
+		synchronized( category_map ){
+			
+			if ( category_listener == null ){
+				
+				category_listener = 
+					new CategoryListener()
+					{
+						public void	
+						downloadManagerAdded(
+							Category 			cat, 
+							DownloadManager 	manager )
+						{
+							Object[]	details;
+							
+							synchronized( category_map ){
+
+								details = category_map.get( cat );
+							}
+							
+							if ( details != null ){
+								
+								processCategory( cat, details, manager );
+							}
+						}
+					
+						public void	
+						downloadManagerRemoved(
+							Category 			cat, 
+							DownloadManager 	removed )
+						{							
+						}
+					};
+			}
+			
+			Iterator<Category>	it = category_map.keySet().iterator();
+			
+			while( it.hasNext()){
+				
+				Category c = it.next();
+				
+				if ( !active_map.containsKey( c )){
+					
+					c.removeCategoryListener( category_listener );
+					
+					it.remove();
+				}
+			}
+			
+			for ( final Category c: active_map.keySet()){
+				
+				if ( !category_map.containsKey( c )){
+					
+					to_process.put( c, active_map.get(c));
+					
+					c.addCategoryListener( category_listener );
+					
+					category_map.put( c, active_map.get(c));
+					
+					if ( c.getType() == Category.TYPE_UNCATEGORIZED ){
+						
+						if ( category_dl_listener == null ){
+						
+								// new downloads don't get a category-change event fired when added
+								// we also want to delay things a bit to allow other components
+								// to set an initial category. there's no hurry anyways
+							
+							category_dl_listener = 
+								new GlobalManagerAdapter()
+								{
+									public void
+									downloadManagerAdded(
+										final DownloadManager	dm )
+									{
+										new DelayedEvent( 
+											"TM:cat-check",
+											10*1000,
+											new AERunnable()
+											{
+												public void
+												runSupport()
+												{
+													Category dm_c = dm.getDownloadState().getCategory();
+													
+													if ( dm_c == null || dm_c == c ){
+														
+															// still uncategorised
+													
+														Object[]	details;
+														
+														synchronized( category_map ){
+	
+															details = category_map.get( c );
+														}
+														
+														if ( details != null ){
+															
+															processCategory( c, details, dm );
+														}
+													}
+												}
+											});
+									}
+									public void
+									downloadManagerRemoved(
+										DownloadManager	dm )
+									{
+									}
+								};
+						
+								
+							azureus_core.getGlobalManager().addListener( category_dl_listener, false );
+						}
+					}
+				}
+			}
+		}
+		
+		if ( to_process.size() > 0 ){
+			
+			List<DownloadManager> downloads = azureus_core.getGlobalManager().getDownloadManagers();
+			
+			for ( Map.Entry<Category, Object[]> entry: to_process.entrySet()){
+				
+				Category 	c 		= entry.getKey();
+				Object[]	details = entry.getValue();
+				
+				List<DownloadManager> list = c.getDownloadManagers( downloads );
+				
+				for( DownloadManager dm: list ){
+					
+					processCategory( c, details, dm );
+				}
+			}
+		}
+	}
+	
+	private void
+	processCategory(
+		Category		cat,
+		Object[]		details,
+		DownloadManager	dm )
+	{
+		Download download = PluginCoreUtils.wrap( dm );
+		
+		if ( download.getFlag( Download.FLAG_LOW_NOISE )){
+			
+			return;
+		}
+		
+		String str = download.getAttribute( category_ta );
+		
+		String cat_name = cat.getName();
+		
+		if ( cat.getType() == Category.TYPE_UNCATEGORIZED ){
+			
+			cat_name = "<none>";
+		}
+		
+		String	cat_tag = cat_name + ";";
+		
+		if ( str != null && str.contains( cat_tag )){
+			
+			return;
+		}
+		
+		try{
+			DeviceMediaRenderer		device 	= (DeviceMediaRenderer)details[0];
+			TranscodeProfile		profile	= (TranscodeProfile)details[1];
+						
+			log( "Category " + cat_name + " - adding " + download.getName() + " to " + device.getName() + "/" + profile.getName());
+			
+			DiskManagerFileInfo[] dm_files = download.getDiskManagerFileInfo();
+			
+			int	num_added = 0;
+			
+			for ( DiskManagerFileInfo dm_file: dm_files ){
+				
+					// limit number of files we can add to avoid crazyness
+				
+				if ( num_added > 64 ){
+					
+					break;
+				}
+				
+					// could be smarter here and check extension or whatever
+				
+				if ( dm_files.length == 1 || dm_file.getLength() >= 128*1024 ){
+					
+					try{
+						queue.add( device, profile, dm_file, false  );
+					
+						num_added++;
+						
+					}catch( Throwable e ){
+						
+						log( "    add failed", e );
+					}
+				}
+			}
+		}finally{
+			
+			download.setAttribute( category_ta, str==null?cat_tag:(str+cat_tag));
 		}
 	}
 	
@@ -234,6 +585,22 @@ TranscodeManagerImpl
 		return( new TranscodeProvider[]{ vp });
 	}
 	
+	protected TranscodeProvider
+	getProvider(
+		int		p_id )
+	
+		throws TranscodeException
+	{
+		TranscodeProviderVuze	vp = vuzexcode_provider;
+
+		if ( p_id == TranscodeProvider.TP_VUZE && vp != null ){
+			
+			return( vp );
+		}
+		
+		throw( new TranscodeException( "Transcode provider not registered" ));
+	}
+	
 	protected TranscodeProfile
 	getProfileFromUID(
 		String		uid )
@@ -254,9 +621,11 @@ TranscodeManagerImpl
 	public TranscodeQueueImpl
 	getQueue() 
 	{
-		if ( !init_sem.reserve(10000)){
+		if ( !init_sem.reserve(30*1000)){
 			
 			Debug.out( "Timeout waiting for init" );
+			
+			AEDiagnostics.dumpThreads();
 		}
 		
 		return( queue );
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodePipeStreamSource.java b/com/aelitis/azureus/core/devices/impl/TranscodePipeStreamSource.java
index e1c7cf0..1f62924 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodePipeStreamSource.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodePipeStreamSource.java
@@ -29,16 +29,19 @@ public class
 TranscodePipeStreamSource 
 	extends TranscodePipe
 {
+	private String			source_host;
 	private int				source_port;
 		
 	protected
 	TranscodePipeStreamSource(
+		String	_source_host,
 		int		_source_port )
 	
 		throws IOException
 	{
 		super( null );
 		
+		source_host	= _source_host;
 		source_port	= _source_port;
 	}		
 
@@ -64,7 +67,7 @@ TranscodePipeStreamSource
 		}
 
 		try{
-			Socket socket2 = new Socket( "127.0.0.1", source_port );
+			Socket socket2 = new Socket( source_host, source_port );
 	
 			synchronized( this ){
 
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeProfileImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeProfileImpl.java
index 514ffde..47e5f76 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeProfileImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeProfileImpl.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.devices.impl;
 import java.io.File;
 import java.util.*;
 
+import com.aelitis.azureus.core.devices.TranscodeException;
 import com.aelitis.azureus.core.devices.TranscodeProfile;
 import com.aelitis.azureus.core.devices.TranscodeProvider;
 
@@ -31,19 +32,22 @@ public class
 TranscodeProfileImpl 
 	implements TranscodeProfile
 {
-	private TranscodeProvider		provider;
+	private TranscodeManagerImpl	manager;
+	private int						pid;
 	private String					uid;
 	private String 					name;
-	private Map<String,String>		properties;
+	private Map<String,Object>		properties;
 	
 	protected 
 	TranscodeProfileImpl(
-		TranscodeProvider		_provider,			
+		TranscodeManagerImpl	_manager,
+		int						_provider_id,
 		String					_uid,
 		String					_name,
-		Map<String,String>		_properties )
+		Map<String,Object>		_properties )
 	{
-		provider	= _provider;
+		manager		= _manager;
+		pid			= _provider_id;
 		uid			= _uid;
 		name		= _name;
 		properties	= _properties;
@@ -58,13 +62,16 @@ TranscodeProfileImpl
 	public String
 	getName()
 	{
-		return( name );
+		String displayName = (String) properties.get("display-name");
+		return( displayName == null ? name : displayName );
 	}
 	
 	public TranscodeProvider
 	getProvider()
+	
+		throws TranscodeException
 	{
-		return( provider );
+		return( manager.getProvider( pid ));
 	}
 	
 	public boolean
@@ -101,9 +108,16 @@ TranscodeProfileImpl
 		return((String)properties.get( "icon-url" ));
 	}
 	
-	public File
-	getAssetDirectory()
+	public int
+	getIconIndex()
 	{
-		return( provider.getAssetDirectory());
+		Object o = properties.get( "icon-index" );
+		
+		if ( o instanceof Number ){
+			
+			return(((Number)o).intValue());
+		}
+		
+		return( 0 );
 	}
 }
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeProviderVuze.java b/com/aelitis/azureus/core/devices/impl/TranscodeProviderVuze.java
index 3a00997..dcd37e5 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeProviderVuze.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeProviderVuze.java
@@ -25,11 +25,10 @@ import java.io.File;
 import java.net.URL;
 import java.util.*;
 
-import org.gudy.azureus2.core3.util.AEThread2;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.ipc.IPCException;
 import org.gudy.azureus2.plugins.ipc.IPCInterface;
 
 import com.aelitis.azureus.core.devices.TranscodeProfile;
@@ -43,10 +42,13 @@ public class
 TranscodeProviderVuze 
 	implements TranscodeProvider
 {
+	private static final String PROFILE_PREFIX = "vuzexcode:";
+	
 	private TranscodeManagerImpl	manager;
 	private PluginInterface			plugin_interface;
 	
-	private volatile TranscodeProfile[]	profiles;
+	private volatile TranscodeProfile[]		profiles;
+	private Map<String,TranscodeProfile[]>	profile_classification_map = new HashMap<String, TranscodeProfile[]>();
 	
 	protected
 	TranscodeProviderVuze(
@@ -54,7 +56,14 @@ TranscodeProviderVuze
 		PluginInterface			_plugin_interface )
 	{
 		manager					= _manager;
-		plugin_interface		= _plugin_interface;
+
+		update(_plugin_interface);
+	}
+	
+	public int
+	getID()
+	{
+		return( TP_VUZE );
 	}
 	
 	protected void
@@ -62,6 +71,21 @@ TranscodeProviderVuze
 		PluginInterface		pi )
 	{
 		plugin_interface		= pi;
+
+		try {
+			plugin_interface.getIPC().invoke("addProfileListChangedListener",
+					new Object[] {
+						new AERunnable() {
+							public void runSupport() {
+								
+								resetProfiles();
+							}
+						}
+					});
+		} catch (IPCException e) {
+		}
+		
+		resetProfiles();
 	}
 	
 	public String
@@ -70,6 +94,17 @@ TranscodeProviderVuze
 		return( plugin_interface.getPluginName() + ": version=" + plugin_interface.getPluginVersion());
 	}
 	
+	private void
+	resetProfiles()
+	{
+		synchronized( profile_classification_map ){
+						
+			profile_classification_map.clear();
+			
+			profiles = null;
+		}
+	}
+	
 	public TranscodeProfile[]
 	getProfiles()
 	{			
@@ -79,15 +114,15 @@ TranscodeProviderVuze
 		}
 		
 		try{
-			Map<String, Map<String,String>> profiles_map = (Map<String,Map<String,String>>)plugin_interface.getIPC().invoke( "getProfiles", new Object[]{} );
+			Map<String, Map<String,Object>> profiles_map = (Map<String,Map<String,Object>>)plugin_interface.getIPC().invoke( "getProfiles", new Object[]{} );
 			
 			TranscodeProfile[] res = new TranscodeProfile[profiles_map.size()];
 			
 			int	index = 0;
 			
-			for ( Map.Entry<String, Map<String,String>> entry : profiles_map.entrySet()){
+			for ( Map.Entry<String, Map<String,Object>> entry : profiles_map.entrySet()){
 				
-				res[ index++] = new TranscodeProfileImpl( this, "vuzexcode:" + entry.getKey(), entry.getKey(), entry.getValue());
+				res[ index++] = new TranscodeProfileImpl( manager, TP_VUZE, PROFILE_PREFIX + entry.getKey(), entry.getKey(), entry.getValue());
 			}
 			
 			profiles	= res;
@@ -102,6 +137,56 @@ TranscodeProviderVuze
 		}
 	}
 	
+	public TranscodeProfile[] 
+	getProfiles(
+		String classification_prefix ) 
+	{
+		classification_prefix = classification_prefix.toLowerCase();
+
+		TranscodeProfile[] profs = getProfiles();
+		
+		synchronized( profile_classification_map ){
+
+			TranscodeProfile[] 	res = profile_classification_map.get( classification_prefix );
+			
+			if ( res != null ){
+								
+				return( res );
+			}
+		}
+			
+		List<TranscodeProfile> c_profiles = new ArrayList<TranscodeProfile>();
+		
+		for ( TranscodeProfile p : profs ){
+			
+			String c = p.getDeviceClassification();
+			
+			if ( c == null ){
+				
+				manager.log( "Device classification missing for " + p.getName());
+				
+			}else{
+				
+				if ( c.toLowerCase().startsWith( classification_prefix )){
+					
+					c_profiles.add( p );
+				}
+			}
+		}
+		
+		TranscodeProfile[] res = c_profiles.toArray( new TranscodeProfile[ c_profiles.size()]);
+		 
+		synchronized( profile_classification_map ){
+			
+			if ( profs == profiles ){
+				
+				profile_classification_map.put( classification_prefix, res );
+			}
+		}
+		
+		return( res );
+	}
+	
 	public TranscodeProfile
 	getProfile(
 		String		UID )
@@ -119,6 +204,25 @@ TranscodeProviderVuze
 		return( null );
 	}
 	
+	public TranscodeProfile 
+	addProfile(
+		File 		file ) 
+	
+		throws TranscodeException
+	{
+		try{
+			String uid = PROFILE_PREFIX + (String)plugin_interface.getIPC().invoke( "addProfile", new Object[]{ file } );
+			
+			resetProfiles();
+			
+			return( getProfile( uid ));
+			
+		}catch( Throwable e ){
+			
+			throw( new TranscodeException( "Failed to add profile", e ));
+		}
+	}
+	
 	public TranscodeProviderAnalysis
 	analyse( 
 		final TranscodeProviderAdapter	_adapter,
@@ -148,24 +252,47 @@ TranscodeProviderVuze
 
 			if ( source_file == null ){
 							
-				PluginInterface av_pi = plugin_interface.getPluginManager().getPluginInterfaceByID( "azupnpav" );
-				
-				if ( av_pi == null ){
-				
-					throw( new TranscodeException( "Media Server plugin not found" ));
-				}
-				
-				IPCInterface av_ipc = av_pi.getIPC();
-				
-				String url_str = (String)av_ipc.invoke( "getContentURL", new Object[]{ input });
-		
-				if ( url_str != null && url_str.length() > 0 ){
-				
-					source_url = new URL( url_str );
+					// race condition here on auto-transcodes due to downloadadded listeners - can add the xcode to queue
+					// and schedule before added to upnpms - simple hack is to hang about a bit
 			
-					pipe = new TranscodePipeStreamSource( source_url.getPort());
+				for ( int i=0; i<10; i++ ){
+
+					PluginInterface av_pi = plugin_interface.getPluginManager().getPluginInterfaceByID( "azupnpav" );
+					
+					if ( av_pi == null ){
+					
+						throw( new TranscodeException( "Media Server plugin not found" ));
+					}
+					
+					IPCInterface av_ipc = av_pi.getIPC();
+					
+					String url_str = (String)av_ipc.invoke( "getContentURL", new Object[]{ input });
+			
+					if ( url_str != null && url_str.length() > 0 ){
+					
+						source_url = new URL( url_str );
+				
+						pipe = new TranscodePipeStreamSource( source_url.getHost(), source_url.getPort());
+					
+						source_url = UrlUtils.setHost( source_url, "127.0.0.1" );
+	
+						source_url = UrlUtils.setPort( source_url, pipe.getPort());					
+					}
 				
-					source_url = UrlUtils.setPort( source_url, pipe.getPort());
+					if ( source_url != null ){
+						
+						break;
+						
+					}else{
+						
+						try{
+							Thread.sleep(1000);
+							
+						}catch( Throwable e ){
+							
+							break;
+						}
+					}
 				}
 			}
 			
@@ -214,6 +341,12 @@ TranscodeProviderVuze
 							}
 						}
 						
+						public boolean 
+						foundVideoStream() 
+						{
+							return( getLongProperty( PT_VIDEO_WIDTH ) > 0 );
+						}
+						
 						public boolean
 						getBooleanProperty(
 							int		property )
@@ -251,8 +384,22 @@ TranscodeProviderVuze
 						{
 							if ( property == PT_DURATION_MILLIS ){
 								
-								return( getLongProperty( "duration_millis", 0 ));
+								long duration = getLongProperty( "duration_millis", 0 );
+								
+								long audio_duration	= getLongProperty( "audio_duration_millis", 0 );
+								
+								if ( duration <= 0 && audio_duration > 0 ){
+									
+									duration = audio_duration;
+								}
+								
+								if ( audio_duration > 0 && audio_duration < duration ){
+									
+									duration = audio_duration;
+								}
 							
+								return( duration );
+								
 							}else if ( property == PT_VIDEO_WIDTH ){
 								
 								return( getLongProperty( "video_width", 0 ));
@@ -261,6 +408,14 @@ TranscodeProviderVuze
 								
 								return( getLongProperty( "video_height", 0 ));
 	
+							}else if ( property == PT_SOURCE_SIZE ){
+								
+								return( getLongProperty( "source_size", 0 ));
+
+							}else if ( property == PT_ESTIMATED_XCODE_SIZE ){
+								
+								return( getLongProperty( "estimated_transcoded_size", 0 ));
+
 							}else{
 								
 								Debug.out( "Unknown property: " + property );
@@ -321,19 +476,21 @@ TranscodeProviderVuze
 									
 									if ( state == 0 ){
 	
-										// running
-																				
+											// running
+										
+										Thread.sleep(50);
+										
 									}else if ( state == 1 ){
 										
 										_adapter.failed( new TranscodeException( "Analysis cancelled" ));
 										
-										return;
+										break;
 										
 									}else if ( state == 2 ){
 										
 										_adapter.failed( new TranscodeException( "Analysis failed", (Throwable)status.get( "error" )));
 										
-										return;
+										break;
 										
 									}else{
 										
@@ -341,11 +498,13 @@ TranscodeProviderVuze
 										
 										_adapter.complete();
 										
-										return;
+										break;
 									}
 								}catch( Throwable e ){
 									
 									_adapter.failed( new TranscodeException( "Failed to get status", e ));
+									
+									break;
 								}
 							}
 						}finally{
@@ -465,9 +624,11 @@ TranscodeProviderVuze
 				}else{
 					source_url = new URL( url_str );
 				
-					pipe = new TranscodePipeStreamSource( source_url.getPort());
+					pipe = new TranscodePipeStreamSource( source_url.getHost(), source_url.getPort());
 					
-					source_url = UrlUtils.setPort( source_url, pipe.getPort());
+					source_url = UrlUtils.setHost( source_url, "127.0.0.1" );
+
+					source_url = UrlUtils.setPort( source_url, pipe.getPort());		
 				}
 			}
 			
@@ -496,6 +657,22 @@ TranscodeProviderVuze
 					
 					final File file = new File( output.toURI());
 						
+					File	parent_dir = file.getParentFile();
+					
+					if ( parent_dir.exists()){
+						
+						if ( !parent_dir.canWrite()){
+							
+							throw( new TranscodeException( "Folder '" + parent_dir.getAbsolutePath() + "' isn't writable" ));
+						}
+					}else{
+						
+						if ( !parent_dir.mkdirs()){
+						
+							throw( new TranscodeException( "Failed to create folder '" + parent_dir.getAbsolutePath() + "'" ));
+						}
+					}
+					
 					adapter = 
 						new TranscodeProviderAdapter()
 						{
@@ -602,8 +779,17 @@ TranscodeProviderVuze
 											adapter.failed( new TranscodeException( "Transcode cancelled" ));
 											
 										}else{
+																						
+											Boolean	perm_fail = (Boolean)status.get( "error_is_perm" );
+											
+											TranscodeException error = new TranscodeException( "Transcode failed", (Throwable)status.get( "error" ));
+											
+											if ( perm_fail != null && perm_fail ){
+												
+												error.setDisableRetry( true );
+											}
 											
-											adapter.failed( new TranscodeException( "Transcode failed", (Throwable)status.get( "error" )));
+											adapter.failed( error );
 										}
 									}catch( Throwable e ){
 										
diff --git a/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java b/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
index d7bac16..21aa281 100644
--- a/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
+++ b/com/aelitis/azureus/core/devices/impl/TranscodeQueueImpl.java
@@ -33,10 +33,14 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.disk.DiskManagerPiece;
 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.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DelayedEvent;
@@ -44,8 +48,10 @@ import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.plugins.PluginInterface;
 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.utils.DelayedTask;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
@@ -71,7 +77,10 @@ TranscodeQueueImpl
 	
 	private volatile TranscodeJobImpl	current_job;
 	
-	private CopyOnWriteList<TranscodeQueueListener>	listeners = new CopyOnWriteList<TranscodeQueueListener>();
+	private AsyncDispatcher	anaylsis_dispatcher = new AsyncDispatcher();
+	
+	private CopyOnWriteList<TranscodeQueueListener>			listeners = new CopyOnWriteList<TranscodeQueueListener>();
+	private CopyOnWriteList<TranscodeQueueActionListener>	action_listeners = new CopyOnWriteList<TranscodeQueueActionListener>();
 	
 	private volatile boolean 	paused;
 	private volatile int		max_bytes_per_sec;
@@ -137,149 +146,69 @@ TranscodeQueueImpl
 			job.starts();
 			
 			TranscodeProvider provider = job.getProfile().getProvider();
-
 			
-			final Throwable[] error = { null };
-
-				
-			TranscodeProfile profile = job.getProfile();
-				
-			final AESemaphore analysis_sem = new AESemaphore( "analysis:proc" );
+			final TranscodeException[] error = { null };
 			
+			TranscodeProfile profile = job.getProfile();
 
-			TranscodeProviderAdapter analysis_adapter = 
-				new TranscodeProviderAdapter()
-				{
-					public void
-					updateProgress(
-						int		percent,
-						int		eta_secs,
-						int		width,
-						int		height )
-					{
-					}
-					
-					public void
-					streamStats(
-						long					connect_rate,
-						long					write_speed )
-					{
-					}
-					
-					public void
-					failed(
-						TranscodeException		e )
-					{
-						error[0] = e;
-						
-						analysis_sem.release();
-					}
-					
-					public void 
-					complete() 
-					{
-						analysis_sem.release();
-					}
-				};
-				
-			final TranscodeProviderAnalysis provider_analysis =	provider.analyse( analysis_adapter, job.getFile(), profile );
-			
-			TranscodeQueueListener analysis_q_listener = 
-				new TranscodeQueueListener()
-				{
-					public void
-					jobAdded(
-						TranscodeJob		job )
-					{					
-					}
-					
-					public void
-					jobChanged(
-						TranscodeJob		changed_job )
-					{
-						if ( changed_job == job ){
-							
-							int	state = job.getState();
-							
-							if ( 	state == TranscodeJob.ST_CANCELLED ||
-									state == TranscodeJob.ST_STOPPED ){
-							
-								provider_analysis.cancel();
-							}
-						}
-					}
-					
-					public void
-					jobRemoved(
-						TranscodeJob		removed_job )
-					{	
-						if ( removed_job == job ){
-							
-							provider_analysis.cancel();
-						}
-					}
-				};
-				
-			try{
-				addListener( analysis_q_listener );
-			
-				analysis_sem.reserve();
-				
-			}finally{
-				
-				removeListener( analysis_q_listener );
-			}
-			
-			if ( error[0] != null ){
-				
-				throw( error[0] );
-			}
-			
-			boolean xcode_required 	= provider_analysis.getBooleanProperty( TranscodeProviderAnalysis.PT_TRANSCODE_REQUIRED );
-			
 			final TranscodeFileImpl		transcode_file = job.getTranscodeFile();
 
-			transcode_file.update( provider_analysis );
+			TranscodeProviderAnalysis 	provider_analysis;
 			
-			int	tt_req;
+			boolean xcode_required;
 			
-			if ( job.isStream()){
+			if ( provider == null ){
 				
-					// already advertised as a transcoded asset so no option not to
-					// transcode (as name/format would change if decided not to transcode and then
-					// this would confuse the clients)
+				xcode_required = false;
 				
-				tt_req = TranscodeTarget.TRANSCODE_ALWAYS;
+				provider_analysis = null;
 				
 			}else{
 				
-				tt_req = job.getTranscodeRequirement();
+				provider_analysis = analyse( job );
 				
-					// audio hack for PSP audio
-				
-				if ( device instanceof TranscodeTarget ){
+				xcode_required 	= provider_analysis.getBooleanProperty( TranscodeProviderAnalysis.PT_TRANSCODE_REQUIRED );
+								
+				int	tt_req;
+
+				if ( job.isStream()){
 					
-					if ( provider_analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_HEIGHT ) == 0 ){
-						
-						if (((TranscodeTarget)device).isAudioCompatible( transcode_file )){
+						// already advertised as a transcoded asset so no option not to
+						// transcode (as name/format would change if decided not to transcode and then
+						// this would confuse the clients)
+					
+					tt_req = TranscodeTarget.TRANSCODE_ALWAYS;
+					
+				}else{
 					
-							tt_req = TranscodeTarget.TRANSCODE_NEVER;
+					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 ){
-				
-				xcode_required = false;
-				
-			}else if ( tt_req == TranscodeTarget.TRANSCODE_ALWAYS ){
-				
-				xcode_required 	= true;
-				
-				provider_analysis.setBooleanProperty( TranscodeProviderAnalysis.PT_FORCE_TRANSCODE, true );
-			}
 							
+				if ( tt_req == TranscodeTarget.TRANSCODE_NEVER ){
+					
+					xcode_required = false;
+					
+				}else if ( tt_req == TranscodeTarget.TRANSCODE_ALWAYS ){
+					
+					xcode_required 	= true;
+					
+					provider_analysis.setBooleanProperty( TranscodeProviderAnalysis.PT_FORCE_TRANSCODE, true );
+				}
+			}
+			
 			if ( xcode_required ){
 				
 				final AESemaphore xcode_sem = new AESemaphore( "xcode:proc" );
@@ -298,6 +227,9 @@ TranscodeQueueImpl
 						private Average eta_average 		= AverageFactory.MovingAverage(ETA_AVERAGE_SIZE);
 						private int		last_percent;
 						
+						private long	initial_file_downloaded 	= job.getFile().getDownloaded();
+						private long	file_size				 	= job.getFile().getLength();
+													
 						public void
 						updateProgress(
 							int			percent,
@@ -358,7 +290,10 @@ TranscodeQueueImpl
 								// and eventually failing - try and spot this behaviour and revert
 								// to direct input if needed
 							
-							if ( Constants.isOSX && job.canUseDirectInput() && job.getAutoRetryCount() == 0 ){
+							if ( 	Constants.isOSX &&
+									job.getEnableAutoRetry() && 
+									job.canUseDirectInput() && 
+									job.getAutoRetryCount() == 0 ){
 								
 								if ( connect_rate > 5 && last_percent < 100 ){
 									
@@ -399,18 +334,183 @@ TranscodeQueueImpl
 						failed(
 							TranscodeException		e )
 						{
-							if ( error[0] == null ){
-							
-								error[0] = e;
+							try{
+								if ( error[0] == null ){
+								
+									error[0] = e;
+								}
+								
+								if ( e.isRetryDisabled()){
+									
+									job.setEnableAutoRetry( false );
+								}
+							}finally{
+								
+								xcode_sem.release();
 							}
-							
-							xcode_sem.release();
 						}
 						
 						public void 
 						complete() 
 						{
-							xcode_sem.release();
+							try{
+									// sanity check: for incomplete files at the start of the process ensure that they have completed
+								
+								long	current_downloaded = job.getFile().getDownloaded();
+															
+								if ( file_size > 0 && initial_file_downloaded < file_size && current_downloaded < file_size ){
+									
+									if ( error[0] == null ){
+										
+											// actually this ain't so simple as we stream data prior to hash check completion (otherwise for
+											// large piece sizes we could be waiting for 4MB to complete downloading before playback)
+											// and getDownloaded() only returns the verified data size 
+										
+										long	contiguous_downloaded = 0;
+										
+										try{
+											DiskManagerFileInfo	_file_info = job.getFile();
+											
+											Download download = _file_info.getDownload();
+										
+											org.gudy.azureus2.core3.disk.DiskManagerFileInfo file_info = PluginCoreUtils.unwrap( _file_info );
+											
+											TOTorrentFile torrent_file = file_info.getTorrentFile();
+											
+											TOTorrent	torrent = torrent_file.getTorrent();
+											
+											TOTorrentFile[]	torrent_files = torrent.getFiles();
+											
+											long	byte_start = 0;
+											
+											for ( TOTorrentFile tf: torrent_files ){
+												
+												if ( tf == torrent_file ){
+													
+													break;
+												}
+												
+												byte_start += tf.getLength();
+											}
+																					
+											DiskManagerPiece[] pieces = PluginCoreUtils.unwrap( download.getDiskManager()).getPieces();
+											
+											long piece_size = torrent.getPieceLength();
+											
+											int	first_piece_index 	= (int)( byte_start / piece_size );
+											int	first_piece_offset	= (int)( byte_start % piece_size );
+											
+											int	last_piece_index	= torrent_file.getLastPieceNumber();
+																					
+											DiskManagerPiece	first_piece = pieces[first_piece_index];
+																							
+											if ( !first_piece.isDone()){
+												
+												boolean[] blocks = first_piece.getWritten();
+															
+												if ( blocks == null ){
+													
+													if ( first_piece.isDone()){
+														
+														contiguous_downloaded = first_piece.getLength() - first_piece_offset;
+													}
+												}else{
+													
+													int	piece_offset = 0;
+													
+													for (int j=0;j<blocks.length;j++){
+													
+														if ( blocks[j] ){
+														
+															int	block_size = first_piece.getBlockSize( j );
+															
+															piece_offset = piece_offset + block_size;
+															
+															if ( contiguous_downloaded == 0 ){
+															
+																if ( piece_offset > first_piece_offset ){
+																	
+																	contiguous_downloaded = piece_offset - first_piece_offset;
+																}
+															}else{
+																
+																contiguous_downloaded += block_size;
+															}						
+														}else{
+															
+															break;
+														}
+													}
+												}	
+											}else{
+											
+												contiguous_downloaded = first_piece.getLength() - first_piece_offset; 
+											
+												for (int i=first_piece_index+1;i<=last_piece_index;i++){
+																									
+													DiskManagerPiece piece = pieces[i];
+													
+													if ( piece.isDone()){
+														
+														contiguous_downloaded += piece.getLength();
+														
+													}else{
+													
+														boolean[] blocks = piece.getWritten();
+																
+														if ( blocks == null ){
+															
+															if ( piece.isDone()){
+														
+																contiguous_downloaded += piece.getLength();
+																
+															}else{
+																
+																break;
+															}
+														}else{
+															
+															for (int j=0;j<blocks.length;j++){
+															
+																if ( blocks[j] ){
+																
+																	contiguous_downloaded += piece.getBlockSize( j );
+																	
+																}else{
+																	
+																	break;
+																}
+															}
+														}
+														
+														break;
+													}
+												}
+											}
+										}catch( Throwable e ){
+											
+											// Debug.out( e );
+										}
+										
+										if ( contiguous_downloaded < file_size ){
+										
+												// things might have improved, check again
+											
+											current_downloaded = job.getFile().getDownloaded();
+											
+											if ( current_downloaded < file_size ){
+		
+												Debug.out( "Premature transcode termination: init=" + initial_file_downloaded + ", curr=" + current_downloaded + ", len=" + file_size );
+		
+												error[0] = new TranscodeException( "Transcode terminated prematurely" );
+											}
+										}
+									}
+								}
+							}finally{
+							
+								xcode_sem.release();
+							}
 						}
 					};
 				
@@ -730,7 +830,13 @@ TranscodeQueueImpl
 			
 			job.failed( e );
 			
-			if ( !job.isStream() && job.getAutoRetryCount() == 0 && job.canUseDirectInput() && !job.useDirectInput()){
+			e.printStackTrace();
+			
+			if ( 	!job.isStream() &&
+					job.getEnableAutoRetry() && 
+					job.getAutoRetryCount() == 0 && 
+					job.canUseDirectInput() && 
+					!job.useDirectInput()){
 				
 				log( "Auto-retrying transcode with direct input" );
 				
@@ -829,7 +935,13 @@ TranscodeQueueImpl
 									
 										if ( process( job )){
 										
-											remove( job );
+											try{
+												remove( job, true );
+												
+											}catch( TranscodeActionVetoException e ){
+												
+												Debug.out( e );
+											}
 										}																			
 									}
 								}
@@ -890,23 +1002,12 @@ TranscodeQueueImpl
 	add(
 		TranscodeTarget			target,
 		TranscodeProfile		profile,
-		DiskManagerFileInfo		file )
-	
-		throws TranscodeException
-	{
-		return( add( target, profile, file, false ));
-	}
-	
-	public TranscodeJobImpl
-	add(
-		TranscodeTarget			target,
-		TranscodeProfile		profile,
 		DiskManagerFileInfo		file,
-		int						transcode_requirement )
+		boolean					add_stopped )
 	
 		throws TranscodeException
 	{
-		return( add( target, profile, file, false, transcode_requirement ));
+		return( add( target, profile, file, add_stopped, false, TranscodeTarget.TRANSCODE_UNKNOWN ));
 	}
 	
 	public TranscodeJobImpl
@@ -914,11 +1015,12 @@ TranscodeQueueImpl
 		TranscodeTarget			target,
 		TranscodeProfile		profile,
 		DiskManagerFileInfo		file,
-		boolean					stream )
+		int						transcode_requirement,
+		boolean					add_stopped )
 	
 		throws TranscodeException
 	{
-		return( add( target, profile, file, stream, -1 ));
+		return( add( target, profile, file, add_stopped, false, transcode_requirement ));
 	}
 	
 	public TranscodeJobImpl
@@ -926,6 +1028,7 @@ TranscodeQueueImpl
 		TranscodeTarget			target,
 		TranscodeProfile		profile,
 		DiskManagerFileInfo		file,
+		boolean					add_stopped,
 		boolean					stream,
 		int						transcode_requirement )
 	
@@ -950,7 +1053,7 @@ TranscodeQueueImpl
 			
 			for ( TranscodeJobImpl job: to_remove ){
 	
-				job.remove();
+				job.removeForce();
 			}
 			
 			if ( !stream ){
@@ -959,7 +1062,7 @@ TranscodeQueueImpl
 			}
 		}
 		
-		TranscodeJobImpl job = new TranscodeJobImpl( this, target, profile, file, transcode_requirement, stream );
+		TranscodeJobImpl job = new TranscodeJobImpl( this, target, profile, file, add_stopped, transcode_requirement, stream );
 		
 		try{
 			synchronized( this ){
@@ -968,17 +1071,7 @@ TranscodeQueueImpl
 				
 				queue_sem.release();
 				
-				saveConfig();
-			}
-			
-			// I'd rather do qos from a listener trigger, but for now this ensures
-			// I get the event even if listeners haven't had a chance to be added
-			try {
-				// force state log to queued just in case it got started (or errored)
-				// between job creation and here
-				PlatformDevicesMessenger.qosTranscode(job, TranscodeJob.ST_QUEUED);
-			} catch (Throwable t) {
-				Debug.out(t);
+				configDirty();
 			}
 			
 			for ( TranscodeQueueListener listener: listeners ){
@@ -1001,17 +1094,46 @@ TranscodeQueueImpl
 	
 	protected void
 	remove(
-		TranscodeJobImpl		job )
+		TranscodeJobImpl		job,
+		boolean					force )
+	
+		throws TranscodeActionVetoException
 	{
 		synchronized( this ){
 			
+			if ( !queue.contains( job )){
+				
+				return;
+			}
+		}
+		
+		if ( !force ){
+			
+			for ( TranscodeQueueActionListener l: action_listeners ){
+				
+				try{
+					l.jobWillBeActioned( job, TranscodeQueueActionListener.ACT_REMOVE );
+					
+				}catch( TranscodeActionVetoException e ){
+					
+					throw( e );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e);
+				}
+			}
+		}
+		
+		synchronized( this ){
+			
 			if ( !queue.remove( job )){
 				
 				return;
 			}
 		}
 		
-		saveConfig();
+		configDirty();
 
 		job.destroy();
 		
@@ -1252,6 +1374,156 @@ TranscodeQueueImpl
 	}
 	
 	protected void
+	analyse(
+		final TranscodeJobImpl			job,
+		final TranscodeAnalysisListener	listener )
+	
+		throws TranscodeException
+	{
+		anaylsis_dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void 
+				runSupport() 
+				{
+					try{
+						TranscodeProviderAnalysis analysis = analyse( job );
+		
+						listener.analysisComplete( job, analysis );
+						
+					}catch( TranscodeException e ){
+						
+						listener.analysisFailed( job, e );
+						
+					}catch( Throwable e ){
+						
+						listener.analysisFailed( job, new TranscodeException( "Analysis failed", e ));
+					}
+				}
+			});
+	}
+	
+	protected TranscodeProviderAnalysis
+	analyse(
+		final TranscodeJobImpl			job )
+	
+		throws TranscodeException
+	{
+		TranscodeProvider provider = job.getProfile().getProvider();
+	
+		final TranscodeException[] error = { null };
+		
+		TranscodeProfile profile = job.getProfile();
+			
+		final AESemaphore analysis_sem = new AESemaphore( "analysis:proc" );		
+
+		final boolean	was_stopped = job.getState() == TranscodeJob.ST_STOPPED;
+		
+		TranscodeProviderAdapter analysis_adapter = 
+			new TranscodeProviderAdapter()
+			{
+				public void
+				updateProgress(
+					int		percent,
+					int		eta_secs,
+					int		width,
+					int		height )
+				{
+				}
+				
+				public void
+				streamStats(
+					long					connect_rate,
+					long					write_speed )
+				{
+				}
+				
+				public void
+				failed(
+					TranscodeException		e )
+				{
+					error[0] = e;
+					
+					analysis_sem.release();
+				}
+				
+				public void 
+				complete() 
+				{
+					analysis_sem.release();
+				}
+			};
+			
+		final TranscodeProviderAnalysis provider_analysis =	provider.analyse( analysis_adapter, job.getFile(), profile );
+		
+		TranscodeQueueListener analysis_q_listener = 
+			new TranscodeQueueListener()
+			{
+				public void
+				jobAdded(
+					TranscodeJob		job )
+				{					
+				}
+				
+				public void
+				jobChanged(
+					TranscodeJob		changed_job )
+				{
+					if ( changed_job == job ){
+						
+						int	state = job.getState();
+						
+						if ( 	state == TranscodeJob.ST_CANCELLED ){
+							
+							provider_analysis.cancel();
+							
+						}else if ( 	state == TranscodeJob.ST_STOPPED ){
+						
+								// only treat this as a failure if the job was initially
+								// running and has been explicitly stopped
+							
+							if ( !was_stopped ){
+							
+								provider_analysis.cancel();
+							}
+						}
+					}
+				}
+				
+				public void
+				jobRemoved(
+					TranscodeJob		removed_job )
+				{	
+					if ( removed_job == job ){
+						
+						provider_analysis.cancel();
+					}
+				}
+			};
+			
+		try{
+			addListener( analysis_q_listener );
+		
+			analysis_sem.reserve();
+			
+		}finally{
+			
+			removeListener( analysis_q_listener );
+		}
+		
+		if ( error[0] != null ){
+			
+			throw( error[0] );
+		}
+				
+		TranscodeFileImpl		transcode_file = job.getTranscodeFile();
+
+		transcode_file.update( provider_analysis );
+		
+		return( provider_analysis );
+	}
+	
+	protected void
 	configDirty()
 	{
 		synchronized( this ){
@@ -1391,6 +1663,20 @@ TranscodeQueueImpl
 		listeners.remove( listener );	
 	}
 	
+	public void
+	addActionListener(
+		TranscodeQueueActionListener		listener )
+	{
+		action_listeners.add( listener );
+	}
+	
+	public void
+	removeActionListener(
+		TranscodeQueueActionListener		listener )
+	{
+		action_listeners.remove( listener );	
+	}
+	
 	protected void
 	log( 
 		String	str )
diff --git a/com/aelitis/azureus/core/dht/DHTOperationAdapter.java b/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
index 8275509..1e644c7 100644
--- a/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
+++ b/com/aelitis/azureus/core/dht/DHTOperationAdapter.java
@@ -42,10 +42,11 @@ DHTOperationAdapter
 	{
 	}
 	
-	public void
+	public boolean
 	diversified(
 		String		desc )
 	{
+		return( true );
 	}
 		
 	public void
diff --git a/com/aelitis/azureus/core/dht/DHTOperationListener.java b/com/aelitis/azureus/core/dht/DHTOperationListener.java
index 8fc7477..d562e27 100644
--- a/com/aelitis/azureus/core/dht/DHTOperationListener.java
+++ b/com/aelitis/azureus/core/dht/DHTOperationListener.java
@@ -39,7 +39,7 @@ DHTOperationListener
 		int					level,
 		int					active_searches );
 	
-	public void
+	public boolean
 	diversified(
 		String				desc );
 	
diff --git a/com/aelitis/azureus/core/dht/control/DHTControl.java b/com/aelitis/azureus/core/dht/control/DHTControl.java
index f4e07ec..d514eda 100644
--- a/com/aelitis/azureus/core/dht/control/DHTControl.java
+++ b/com/aelitis/azureus/core/dht/control/DHTControl.java
@@ -102,6 +102,10 @@ DHTControl
 	public DHTControlStats
 	getStats();
 	
+	public void
+	setSleeping(
+		boolean	asleep );
+	
 	public DHTTransport
 	getTransport();
 	
@@ -203,12 +207,8 @@ DHTControl
 	getObfuscatedKey(
 		byte[]		plain_key );
 	
-	/**
-	 * Returns a list of DHTTransportContact objects
-	 * @return
-	 */
 	
-	public List<DHTTransportContact>
+	public List<DHTControlContact>
 	getContacts();
 	
 		// debug method only
diff --git a/com/aelitis/azureus/core/dht/control/impl/DHTControlContactImpl.java b/com/aelitis/azureus/core/dht/control/impl/DHTControlContactImpl.java
index 4a7a12f..c81b9b4 100644
--- a/com/aelitis/azureus/core/dht/control/impl/DHTControlContactImpl.java
+++ b/com/aelitis/azureus/core/dht/control/impl/DHTControlContactImpl.java
@@ -82,4 +82,9 @@ DHTControlContactImpl
 		return( r_contact );
 	}
 	
+	public boolean
+	isSleeping()
+	{
+		return( t_contact.isSleeping());
+	}
 }
diff --git a/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java b/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
index 71c9c55..e1aed7e 100644
--- a/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
+++ b/com/aelitis/azureus/core/dht/control/impl/DHTControlImpl.java
@@ -65,8 +65,9 @@ DHTControlImpl
 {
 	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;
+	public  static 		 int EXTERNAL_LOOKUP_CONCURRENCY			= 16;
+	private static final int EXTERNAL_PUT_CONCURRENCY				= 8;
+	private static final int EXTERNAL_SLEEPING_PUT_CONCURRENCY		= 4;
 	
 	private static final int RANDOM_QUERY_PERIOD			= 5*60*1000;
 	
@@ -307,6 +308,22 @@ DHTControlImpl
 				}
 				
 				public void
+				resetNetworkPositions()
+				{
+					List<DHTRouterContact>	contacts = router.getAllContacts();
+					
+					for (int i=0;i<contacts.size();i++){
+												
+						DHTRouterContact	rc = contacts.get(i);
+
+						if ( !router.isID( rc.getID())){
+							
+							((DHTControlContactImpl)rc.getAttachment()).getTransportContact().createNetworkPositions( false );
+						}
+					}
+				}
+				
+				public void
 				currentAddress(
 					String		address )
 				{
@@ -411,6 +428,24 @@ DHTControlImpl
 		return( router_count );
 	}
 	
+	public void
+	setSleeping(
+		boolean	asleep )
+	{
+		transport.setGenericFlag( DHTTransport.GF_DHT_SLEEPING, asleep );
+		
+		logger.log( "Sleep mode changed to " + asleep );
+		
+		if ( asleep ){
+			
+			external_put_pool.setMaxThreads( EXTERNAL_SLEEPING_PUT_CONCURRENCY );
+			
+		}else{
+			
+			external_put_pool.setMaxThreads( EXTERNAL_PUT_CONCURRENCY );
+		}
+	}
+	
 	public DHTControlStats
 	getStats()
 	{
@@ -1558,11 +1593,11 @@ DHTControlImpl
 						get_listener.searching(contact, level, active_searches);
 					}
 					
-					public void
+					public boolean
 					diversified(
 						String				desc )
 					{
-						get_listener.diversified(desc);
+						return( get_listener.diversified(desc));
 					}
 					
 					public void
@@ -1660,11 +1695,11 @@ DHTControlImpl
 				{
 				}
 				
-				public void
+				public boolean
 				diversified(
 					String		desc )
 				{
-					lookup_listener.diversified( desc );
+					return( lookup_listener.diversified( desc ));
 				}
 				
 				public void
@@ -1770,7 +1805,10 @@ DHTControlImpl
 
 			if ( div ){
 				
-				get_listener.diversified( this_description );
+				if ( !get_listener.diversified( this_description )){
+					
+					continue;
+				}
 			}
 			
 			boolean	is_stats_query = (flags & DHT.FLAG_STATS ) != 0;
@@ -1795,11 +1833,11 @@ DHTControlImpl
 							DHTTransportContact	cause,
 							byte				diversification_type )
 						{
-							diversified( "Diversification of [" + this_description + "]" );
+							boolean ok_to_div = diversified( "Diversification of [" + this_description + "]" );
 							
 								// we only want to follow one diversification
 							
-							if ( !diversified[0]){
+							if ( ok_to_div && !diversified[0]){
 								
 								diversified[0] = true;
 
@@ -2759,7 +2797,9 @@ DHTControlImpl
 				
 				int	c_factor = router.getK();
 				
-				if ( adapter.getStorageAdapter().getNetwork() != DHT.NW_CVS ){
+				DHTStorageAdapter sad = adapter.getStorageAdapter();
+				
+				if ( sad != null && sad.getNetwork() != DHT.NW_CVS ){
 					
 					c_factor += ( c_factor/2 );
 				}
@@ -2872,10 +2912,19 @@ DHTControlImpl
 	
 	public DHTTransportContact[]
 	findNodeRequest(
+   		DHTTransportContact originating_contact, 
+   		byte[]				id )
+	{
+		return( findNodeRequest( originating_contact, id, false ));
+	}
+	
+	private DHTTransportContact[]
+	findNodeRequest(
 		DHTTransportContact originating_contact, 
-		byte[]				id )
+		byte[]				id,
+		boolean				already_logged )
 	{
-		if ( DHTLog.isOn()){
+		if ( !already_logged && DHTLog.isOn()){
 			DHTLog.log( "findNodeRequest from " + DHTLog.getString( originating_contact.getID()));
 		}
 		
@@ -2936,7 +2985,7 @@ DHTControlImpl
 			}
 		}else{
 			
-			return( new DHTTransportFindValueReplyImpl( findNodeRequest( originating_contact, key )));
+			return( new DHTTransportFindValueReplyImpl( findNodeRequest( originating_contact, key, true )));
 		}
 	}
 	
@@ -4143,11 +4192,11 @@ DHTControlImpl
 			delegate.searching( contact, level, active_searches );
 		}
 		
-		public void
+		public boolean
 		diversified(
 			String		desc )
 		{
-			delegate.diversified( desc );
+			return( delegate.diversified( desc ));
 		}
 		
 		public void
@@ -4524,6 +4573,12 @@ DHTControlImpl
 			return( delegate.isValid());
 		}
 		
+		public boolean 
+		isSleeping()
+		{
+			return( delegate.isSleeping());
+		}
+		
 		public void
 		sendPing(
 			DHTTransportReplyHandler	handler )
@@ -4613,6 +4668,13 @@ DHTControlImpl
 			delegate.remove();
 		}
 		
+		public void 
+		createNetworkPositions(
+			boolean is_local) 
+		{
+			delegate.createNetworkPositions(is_local);
+		}
+		
 		public DHTNetworkPosition[]
 		getNetworkPositions()
 		{
diff --git a/com/aelitis/azureus/core/dht/control/impl/Test.java b/com/aelitis/azureus/core/dht/control/impl/Test.java
deleted file mode 100644
index 634f176..0000000
--- a/com/aelitis/azureus/core/dht/control/impl/Test.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Created on 15-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.control.impl;
-
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.gudy.azureus2.core3.util.ByteFormatter;
-
-
-/**
- * @author parg
- *
- */
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String[]	args )
-	{
-		//   :AFC97EA1 :lookup complete for B6589FC6 
-		//    :AFC97EA1 :    queried = {91032AD7 ,AC3478D6 ,ACCA5B51 ,B6692EA5 ,ACF10F2C ,F66B7DCD ,B3F0C7F6 ,A8A2B30F ,972A67C4 ,AE7B4B79 ,887309D0 ,8383DA94 ,9E6A55B6 ,902BA3CD ,AFC97EA1 ,BD307A3E ,B1D57811 ,8665243E ,9EE0DF7C ,B6589FC6 ,BC33EA4E }
-		//    :AFC97EA1 :    to query = {F6E1126C ,F22FE10D ,F0483F25 ,F1F836CB ,F1ABD670 ,FE5DBBCE ,FA35E192 ,FBDD85A9 ,FBEA31C7 ,EAEF5296 ,D435A6CD ,D051BF1D ,DA4B9237 ,C1DFD96E ,CB4E5208 ,356A192B ,17BA0791 ,1574BDDB ,1B645389 ,0716D970 ,0ADE7C2C ,77DE68DA ,7B52009B ,4D134BC0 }
-
-		// final byte[]	target 	= { (byte)0xB6, (byte)0x58, (byte)0x9f, (byte)0xc6 };
-
-		//  :9A79BE61:lookup complete for 31017A72
-		//    :9A79BE61:    queried = {77DE68DA,1B645389,31BD9B9F,356A192B,310B86E0}
-		//    :9A79BE61:    to query = {6FB84AED,B6589FC6,812ED456,DA4B9237}
-		//    :9A79BE61:    ok = {77DE68DA,1B645389,356A192B,31BD9B9F,310B86E0}
-		
-		final byte[]	target 	= { (byte)0x35, (byte)0x6a, (byte)0x19, (byte)0x28 };
-		final byte[]	t1 		= { (byte)0x76, (byte)0x1f, (byte)0x22, (byte)0xb2 };
-		final byte[]	t2 		= { (byte)0x47, (byte)0x2b, (byte)0x07, (byte)0xb9 };
-				   		
-		byte[]	d1 = DHTControlImpl.computeDistance2( t1, target );
-		byte[]	d2 = DHTControlImpl.computeDistance2( t2, target );
-		
-		System.out.println( "d1 = " + ByteFormatter.nicePrint( d1 ));
-		System.out.println( "d2 = " + ByteFormatter.nicePrint( d2 ));
-		
-		System.out.println( "comp1 = " + DHTControlImpl.compareDistances2( d1, d2 ));
-		System.out.println( "comp2 = " + DHTControlImpl.computeAndCompareDistances2( t1, t2, target ));
-		
-		final Set			set = 
-			new TreeSet(
-				new Comparator()
-				{
-					public int
-					compare(
-						Object	o1,
-						Object	o2 )
-					{						
-						byte[] d1 = DHTControlImpl.computeDistance2( (byte[])o1, target );
-						byte[] d2 = DHTControlImpl.computeDistance2( (byte[])o2, target );
-						
-						System.out.println( "dist:" + ByteFormatter.nicePrint((byte[])o1) + " -> " + ByteFormatter.nicePrint(d1));
-						System.out.println( "dist:" + ByteFormatter.nicePrint((byte[])o2) + " -> " + ByteFormatter.nicePrint(d2));
-						return( DHTControlImpl.compareDistances2( d1, d2 ));
-					}
-				});
-		
-		set.add( t1 );
-		set.add( t2 );
-		
-		//set.add( new byte[]{ (byte)0xF0, (byte)0x48 ,(byte)0x3F, (byte)0x25 });
-		//set.add( new byte[]{ (byte)0xF1, (byte)0xF8, (byte)0x36, (byte)0xCB });
-		//set.add( new byte[]{ (byte)0xF2, (byte)0x2F, (byte)0xE1, (byte)0x0D });
-	
-		
-		Iterator it = set.iterator();
-		
-		while( it.hasNext()){
-			
-			byte[]	val = (byte[])it.next();
-			
-			System.out.println( ByteFormatter.nicePrint( val ));
-		}
-	}
-}
diff --git a/com/aelitis/azureus/core/dht/db/DHTDB.java b/com/aelitis/azureus/core/dht/db/DHTDB.java
index 9f620f5..70599e7 100644
--- a/com/aelitis/azureus/core/dht/db/DHTDB.java
+++ b/com/aelitis/azureus/core/dht/db/DHTDB.java
@@ -92,6 +92,16 @@ DHTDB
 	get(
 		HashWrapper		key );
 	
+		/**
+		 * Returns a value for the given key (local or remote) if found
+		 * @param key
+		 * @return
+		 */
+	
+	public DHTDBValue
+	getAnyValue(
+		HashWrapper		key );
+	
 	public boolean
 	hasKey(
 		HashWrapper		key );
diff --git a/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java b/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
index c3908cf..37b3600 100644
--- a/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
+++ b/com/aelitis/azureus/core/dht/db/impl/DHTDBImpl.java
@@ -340,6 +340,7 @@ DHTDBImpl
 		byte			life_hours,
 		byte			replication_control )
 	{
+		
 			// local store
 		
 		if ( (flags & DHT.FLAG_PUT_AND_FORGET ) == 0 ){
@@ -535,7 +536,7 @@ DHTDBImpl
 	get(
 		HashWrapper				key )
 	{
-			// local remove
+			// local get
 		
 		try{
 			this_mon.enter();
@@ -555,6 +556,28 @@ DHTDBImpl
 		}
 	}
 	
+	public DHTDBValue
+	getAnyValue(
+		HashWrapper				key )
+	{		
+		try{
+			this_mon.enter();
+		
+			DHTDBMapping mapping = (DHTDBMapping)stored_values.get( key );
+			
+			if ( mapping != null ){
+				
+				return( mapping.getAnyValue( local_contact ));
+			}
+			
+			return( null );
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
+	
 	public boolean
 	hasKey(
 		HashWrapper		key )
@@ -587,9 +610,18 @@ DHTDBImpl
 				DHTDBValueImpl	res = mapping.remove( originator );
 				
 				if ( res != null ){
-					
+									
 					total_local_keys--;
 					
+					if ( !mapping.getValues().hasNext()){
+						
+						stored_values.remove( key );
+					
+						removeFromPrefixMap( mapping );
+						
+						mapping.destroy();
+					}
+					
 					return( res.getValueForDeletion( getNextValueVersion()));
 				}
 				
@@ -913,7 +945,11 @@ DHTDBImpl
 					
 					DHTDBValueImpl	value = it2.next();
 				
-					if ( !value.isLocal()){
+					if ( value.isLocal()){
+						
+						all_rf_values = false;
+						
+					}else{
 						
 						if ( value.getReplicationFactor() == DHT.REP_FACT_DEFAULT ){
 							
diff --git a/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java b/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
index ed45a93..c23a101 100644
--- a/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
+++ b/com/aelitis/azureus/core/dht/db/impl/DHTDBMapping.java
@@ -468,6 +468,38 @@ DHTDBMapping
 	}
 	
 	protected DHTDBValueImpl
+	getAnyValue(
+		DHTTransportContact 	originator )
+	{
+		DHTDBValueImpl	res = null;
+		
+		try{
+			Map<HashWrapper,DHTDBValueImpl> map = direct_originator_map_may_be_null;
+			
+			if ( map != null ){
+						
+				HashWrapper originator_id = new HashWrapper( originator.getID());
+			
+				res = (DHTDBValueImpl)map.get( originator_id );
+			}
+			
+			if ( res == null ){
+				
+				Iterator<DHTDBValueImpl> it = indirect_originator_value_map.values().iterator();
+				
+				if ( it.hasNext()){
+					
+					res = it.next();
+				}
+			}
+		}catch( Throwable e ){
+			// slight chance of conc exception here, don't care
+		}
+		
+		return( res );
+	}
+	
+	protected DHTDBValueImpl
 	remove(
 		DHTTransportContact 	originator )
 	{
diff --git a/com/aelitis/azureus/core/dht/impl/DHTImpl.java b/com/aelitis/azureus/core/dht/impl/DHTImpl.java
index 36d46ce..8cc7266 100644
--- a/com/aelitis/azureus/core/dht/impl/DHTImpl.java
+++ b/com/aelitis/azureus/core/dht/impl/DHTImpl.java
@@ -25,6 +25,7 @@ package com.aelitis.azureus.core.dht.impl;
 import java.io.*;
 import java.util.Properties;
 
+import org.gudy.azureus2.core3.util.AERunStateHandler;
 import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.core.dht.DHT;
@@ -49,15 +50,15 @@ import com.aelitis.azureus.core.dht.transport.*;
 
 public class 
 DHTImpl 
-	implements DHT
+	implements DHT, AERunStateHandler.RunStateChangeListener
 {
 	private DHTStorageAdapter		storage_adapter;
 	private DHTNATPuncherAdapter	nat_adapter;
-	private DHTControl			control;
-	private DHTNATPuncher		nat_puncher;
-	private DHTSpeedTester		speed_tester;
-	private	Properties			properties;
-	private DHTLogger			logger;
+	private DHTControl				control;
+	private DHTNATPuncher			nat_puncher;
+	private DHTSpeedTester			speed_tester;
+	private	Properties				properties;
+	private DHTLogger				logger;
 	
 	public 
 	DHTImpl(
@@ -170,6 +171,15 @@ DHTImpl
 		}
 		
 		speed_tester = DHTSpeedTesterFactory.create( this );
+		
+		AERunStateHandler.addListener( this, true );
+	}
+	
+	public void 
+	runStateChanged(
+		long run_state ) 
+	{
+		control.setSleeping( AERunStateHandler.isDHTSleeping());
 	}
 	
 	protected int
@@ -356,6 +366,8 @@ DHTImpl
 		}
 		
 		DHTNetworkPositionManager.destroy( storage_adapter );
+		
+		AERunStateHandler.removeListener( this );
 	}
 	
 	public void
diff --git a/com/aelitis/azureus/core/dht/impl/Test.java b/com/aelitis/azureus/core/dht/impl/Test.java
deleted file mode 100644
index dbe3a10..0000000
--- a/com/aelitis/azureus/core/dht/impl/Test.java
+++ /dev/null
@@ -1,1175 +0,0 @@
-/*
- * Created on 12-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.impl;
-
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.dht.*;
-import com.aelitis.azureus.core.dht.control.DHTControlContact;
-import com.aelitis.azureus.core.dht.db.impl.DHTDBImpl;
-import com.aelitis.azureus.core.dht.nat.DHTNATPuncherAdapter;
-import com.aelitis.azureus.core.dht.nat.impl.DHTNATPuncherImpl;
-import com.aelitis.azureus.core.dht.transport.*;
-import com.aelitis.azureus.core.dht.transport.loopback.DHTTransportLoopbackImpl;
-import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
-import com.aelitis.azureus.core.dht.transport.udp.impl.DHTTransportUDPImpl;
-import com.aelitis.azureus.plugins.dht.impl.DHTPluginStorageManager;
-
-import java.io.*;
-import java.math.BigInteger;
-import java.net.InetSocketAddress;
-import java.security.KeyFactory;
-import java.security.Signature;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.RSAPrivateKeySpec;
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.AEThread;
-import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.core3.util.SHA1Simple;
-import org.gudy.azureus2.core3.util.Timer;
-import org.gudy.azureus2.core3.util.TimerEvent;
-import org.gudy.azureus2.core3.util.TimerEventPerformer;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.logging.LoggerChannel;
-import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
-
-/**
- * @author parg
- *
- */
-
-public class 
-Test 
-	implements DHTNATPuncherAdapter
-{
-	static boolean	AELITIS_TEST	= false;
-	static InetSocketAddress	AELITIS_ADDRESS = new InetSocketAddress("213.186.46.164", 6881);
-	
-	static int DEFAULT_NETWORK = DHT.NW_CVS;
-	
-	static{
-		
-		DHTTransportUDPImpl.TEST_EXTERNAL_IP	= true;
-	}
-	
-	int num_dhts			= 6;
-	int num_stores			= 0;
-	static int MAX_VALUES	= 10000;
-	
-	boolean	udp_protocol	= true;
-	int		udp_timeout		= 1000;
-	
-
-	static int		K			= 20;
-	static int		B			= 5;
-	static int		ID_BYTES	= 20;
-	
-	int		fail_percentage	= 00;
-	
-	static Properties	dht_props = new Properties();
-	
-	static{		
-		// 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));
-		dht_props.put( DHT.PR_CACHE_REPUBLISH_INTERVAL, new Integer(30000));
-		dht_props.put( DHT.PR_ORIGINAL_REPUBLISH_INTERVAL, new Integer(60000));
-	}
-
-	static byte[]	th_key	= new byte[]{ 1,1,1,1 };
-	
-	static Map	check = new HashMap();
-
-
-	static DHTLogger	logger;
-	
-	static{
-		
-		final LoggerChannel c_logger = AzureusCoreFactory.create().getPluginManager().getDefaultPluginInterface().getLogger().getNullChannel("test");
-		
-		c_logger.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 );
-					
-					error.printStackTrace();
-				}
-			});
-		
-		logger = 
-			new DHTLogger()
-			{
-				public void
-				log(
-					String	str )
-				{
-					c_logger.log( str );
-				}
-			
-				public void
-				log(
-					Throwable e )
-				{
-					c_logger.log( e );
-				}
-				
-				public void
-				log(
-					int		log_type,
-					String	str )
-				{
-					if ( isEnabled( log_type )){
-						
-						c_logger.log( str );
-					}
-				}
-			
-				public boolean
-				isEnabled(
-					int	log_type )
-				{
-					return( true );
-				}
-					
-				public PluginInterface
-				getPluginInterface()
-				{
-					return( c_logger.getLogger().getPluginInterface());
-				}
-			};
-	}
-
-	public static DHTLogger
-	getLogger()
-	{
-		return( logger );
-	}
-	
-	public static void
-	main(
-		String[]		args )
-	{
-		new Test();
-	}
-	
-	
-	Map	port_map = new HashMap();
-	
-	protected
-	Test()
-	{
-		try{
-			DHTLog.setLogging( true );
-			
-			DHT[]			dhts 		= new DHT[num_dhts*2+30];
-			DHTTransport[]	transports 	= new DHTTransport[num_dhts*2+30];
-			
-			
-			for (int i=0;i<num_dhts;i++){
-				
-				createDHT( dhts, transports, DEFAULT_NETWORK, i );
-			}
-
-			for (int i=0;i<num_dhts-1;i++){
-			
-				if ( AELITIS_TEST ){
-					
-					((DHTTransportUDP)transports[i]).importContact( AELITIS_ADDRESS, DHTTransportUDP.PROTOCOL_VERSION_MAIN );
-					
-				}else{
-					ByteArrayOutputStream	baos = new ByteArrayOutputStream();
-					
-					DataOutputStream	daos = new DataOutputStream( baos );
-					
-					transports[i].getLocalContact().exportContact( daos );
-					
-					daos.close();
-					
-					transports[i+1].importContact( new DataInputStream( new ByteArrayInputStream( baos.toByteArray())));
-				}
-					
-				dhts[i].integrate(true);
-					
-				if ( i > 0 && i%10 == 0 ){
-						
-					System.out.println( "Integrated " + i + " DHTs" );
-				}
-			}
-			
-			if ( AELITIS_TEST ){
-				
-				((DHTTransportUDP)transports[num_dhts-1]).importContact( AELITIS_ADDRESS, DHTTransportUDP.PROTOCOL_VERSION_MAIN );
-
-			}else{
-				
-				ByteArrayOutputStream	baos = new ByteArrayOutputStream();
-				
-				DataOutputStream	daos = new DataOutputStream( baos );
-				
-				transports[0].getLocalContact().exportContact( daos );
-				
-				daos.close();
-				
-				transports[num_dhts-1].importContact( new DataInputStream( new ByteArrayInputStream( baos.toByteArray())));
-			}
-			
-			
-			dhts[num_dhts-1].integrate( true );
-			
-			DHTTransportLoopbackImpl.setFailPercentage(fail_percentage);
-			
-			//dht1.print();
-			
-			//DHTTransportLoopbackImpl.setLatency( 500);
-			
-			/*
-			System.out.println( "before put:" + transports[99].getStats().getString());
-			dhts[99].put( "fred".getBytes(), new byte[2]);
-			System.out.println( "after put:" + transports[99].getStats().getString());
-
-			System.out.println( "get:"  + dhts[0].get( "fred".getBytes()));
-			System.out.println( "get:"  + dhts[77].get( "fred".getBytes()));
-			*/
-			
-			Map	store_index = new HashMap();
-			
-			for (int i=0;i<num_stores;i++){
-				
-				int	dht_index = (int)(Math.random()*num_dhts);
-				
-				DHT	dht = dhts[dht_index];
-
-				dht.put( (""+i).getBytes(), "", new byte[4], (byte)0, new DHTOperationAdapter());
-			
-				store_index.put( ""+i, dht );
-				
-				if ( i != 0 && i %100 == 0 ){
-					
-					System.out.println( "Stored " + i + " values" );
-				}
-			}
-			
-			Timer	timer = new Timer("");
-			
-			timer.addPeriodicEvent(
-				10000,
-				new TimerEventPerformer()
-				{
-					public void 
-					perform(
-						TimerEvent event) 
-					{
-						if ( !udp_protocol ){
-							
-							DHTTransportStats stats = DHTTransportLoopbackImpl.getOverallStats();
-						
-							System.out.println( "Overall stats: " + stats.getString());
-						}
-					}
-				});
-			
-			LineNumberReader	reader = new LineNumberReader( new InputStreamReader( System.in ));
-			
-			while( true ){
-				
-				System.out.print( "> " );
-				
-				try{
-					String	str = reader.readLine().trim();
-					
-					if ( str == null ){
-						
-						break;
-					}
-					
-					int	pos = str.indexOf(' ');
-					
-					if ( pos == -1 || pos == 0 ){
-						
-						usage();
-						
-						continue;
-					}
-					
-					int	dht_index = (int)(Math.random()*num_dhts);
-					
-					DHT	dht = dhts[dht_index];
-					
-					String	lhs = str.substring(0,pos).trim();
-					String	rhs = str.substring(pos+1).trim();
-					
-					DHTTransportStats	stats_before 	= null;
-					
-					char command = lhs.toLowerCase().charAt(0);
-					
-					if ( command == 'p' ){
-						
-						pos = rhs.indexOf('=');
-						
-						if ( pos == -1 ){
-							
-							usage();
-							
-						}else{
-						
-							System.out.println( "Using dht " + dht_index );
-							
-							stats_before = dht.getTransport().getStats().snapshot();
-	
-							String	key = rhs.substring(0,pos);
-							String	val = rhs.substring(pos+1);
-							
-							pos = val.indexOf( ' ' );
-							
-							byte flags 		= 0;
-							byte life 		= 0;
-							byte rep_fact 	= DHT.REP_FACT_DEFAULT;
-							
-							if ( pos != -1 ){
-								
-								String	opts = val.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],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, rep_fact, false, new DHTOperationAdapter() );
-						}
-					}else if ( command == 'x' ){
-						
-						dht = (DHT)store_index.get( rhs );
-						
-						if ( dht == null ){
-							
-							System.out.println( "DHT not found" );
-							
-						}else{
-							
-							stats_before = dht.getTransport().getStats().snapshot();
-							
-							byte[]	res = dht.remove( rhs.getBytes(), "", new DHTOperationAdapter());
-							
-							if ( res != null ){
-								
-								store_index.remove( rhs );
-							}
-							
-							System.out.println( "-> " + (res==null?"null":new String(res)));
-						}
-					}else if ( command == 'e' ){
-						
-						dht = (DHT)store_index.get( rhs );
-						
-						if ( dht == null ){
-							
-							System.out.println( "DHT not found" );
-							
-						}else{
-							
-							DataOutputStream	daos = new DataOutputStream( new FileOutputStream( "C:\\temp\\dht.state"));
-							
-							dht.exportState( daos, 0 );
-							
-							daos.close();
-						}
-					}else if ( command == 'g' ){
-						
-						System.out.println( "Using dht " + dht_index );
-						
-						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(), "", flags, 32, 0, false, false,
-								new DHTOperationAdapter()
-								{
-									public void
-									read(
-										DHTTransportContact	contact,
-										DHTTransportValue	value )
-									{
-										System.out.println( "-> " + getString( value ));
-									}
-																	
-									public void
-									complete(
-										boolean				timeout )
-									{
-										System.out.println( "-> complete" );
-									}		
-								});
-						
-					}else if ( command == '?' ){
-						
-						System.out.println( "Using dht " + dht_index );
-						
-						stats_before = dht.getTransport().getStats().snapshot();
-					
-						final DHT	f_dht = dht;
-						
-						dht.get( 
-								rhs.getBytes(), "", DHT.FLAG_STATS, 32, 0, false, false,
-								new DHTOperationAdapter()
-								{
-									public void
-									read(
-										DHTTransportContact	contact,
-										DHTTransportValue	value )
-									{
-										System.out.println( "-> " + getString( value ));
-										
-										try{
-											DHTStorageKeyStats	stats = f_dht.getStorageAdapter().deserialiseStats( new DataInputStream( new ByteArrayInputStream( value.getValue())));
-											
-											System.out.println( "    stats: size = " + stats.getSize() + ", entries=" + stats.getEntryCount() + ", rpm=" + stats.getReadsPerMinute());
-										}catch( Throwable e ){
-											
-											e.printStackTrace();
-										}
-									}
-																	
-									public void
-									complete(
-										boolean				timeout )
-									{
-										System.out.println( "-> complete" );
-									}		
-								});
-						
-						
-						
-					}else if ( command == 'd' ){
-						
-						System.out.println( "Using dht " + dht_index );
-						
-						stats_before = dht.getTransport().getStats().snapshot();
-						
-						byte[]	res = dht.remove( rhs.getBytes(), "", new DHTOperationAdapter());
-						
-						System.out.println( "-> " + (res==null?"null":new String(res)));
-						
-					}else if ( command == 'z' ){
-						
-						System.out.println( "Using dht " + dht_index );
-						
-						stats_before = dht.getTransport().getStats().snapshot();
-						
-						dht.get( rhs.getBytes(), "", (byte)0, 10, 0, false, false,
-								new DHTOperationListener()
-								{
-									public void
-									searching(
-										DHTTransportContact	contact,
-										int					level,
-										int					active_searches )
-									{
-										
-									}
-									
-									public void
-									diversified(
-										String		desc )
-									{
-									}
-									
-									public void
-									found(
-										DHTTransportContact	contact,
-										boolean				is_closest )
-									{
-									}
-									
-									public void
-									read(
-										final DHTTransportContact	contact,
-										final DHTTransportValue		value )
-									{
-										System.out.println( "-> " + value.getString());
-	
-										new AEThread("blah")
-										{
-											public void
-											runSupport()
-											{
-												DHTTransportFullStats stats = contact.getStats();
-										
-												System.out.println( "    stats = " + stats.getString() );
-											}
-										}.start();
-									}
-									public void
-									wrote(
-										final DHTTransportContact	contact,
-										DHTTransportValue	value )
-									{
-									}
-									
-						
-									public void
-									complete(
-										boolean				timeout )
-									{
-										System.out.println( "complete");
-									}
-								});
-						
-						
-					}else if ( command == 'v' ){
-				
-						try{
-							int	index = Integer.parseInt( rhs );
-					
-							dht = dhts[index];
-	
-							stats_before = dht.getTransport().getStats().snapshot();
-							
-							dht.print( true );
-	
-							List	l = dht.getControl().getContacts();
-							
-							for (int i=0;i<l.size();i++){
-								
-								DHTControlContact	c = (DHTControlContact)l.get(i);
-								
-								System.out.println( "  contact:" + c.getRouterContact().getString() + "/" + c.getTransportContact().getString());
-							}
-						}catch( Throwable e ){
-							
-							e.printStackTrace();
-						}
-					}else if ( command == 'q' ){
-						
-						try{
-							int	index = Integer.parseInt( rhs );
-					
-							dht = dhts[index];
-	
-							dht.destroy();
-							
-						}catch( Throwable e ){
-							
-							e.printStackTrace();
-						}
-					}else if ( command == 't' ){
-						
-						try{
-							int	index = Integer.parseInt( rhs );
-					
-							dht = dhts[index];
-	
-							stats_before = dht.getTransport().getStats().snapshot();
-							
-							((DHTTransportUDPImpl)transports[index]).testInstanceIDChange();
-							
-							dht.integrate( true );
-	
-						}catch( Throwable e ){
-							
-							e.printStackTrace();
-						}
-					}else if ( command == 's' ){
-						
-						try{
-							int	index = Integer.parseInt( rhs );
-					
-							dht = dhts[index];
-	
-							stats_before = dht.getTransport().getStats().snapshot();
-							
-							((DHTTransportUDPImpl)transports[index]).testTransportIDChange();
-							
-						}catch( Throwable e ){
-							
-							e.printStackTrace();
-						}
-					}else if ( command == 'a' ){
-						
-						int	net = DEFAULT_NETWORK;
-						
-						try{
-							net = Integer.parseInt( rhs );
-							
-						}catch( Throwable e ){
-							
-						}
-						
-						createDHT( dhts, transports, net, num_dhts++ );
-						
-						dht	= dhts[num_dhts-1];
-						
-						stats_before = transports[num_dhts-1].getStats().snapshot();
-						
-						ByteArrayOutputStream	baos = new ByteArrayOutputStream();
-						
-						DataOutputStream	daos = new DataOutputStream( baos );
-						
-						List	ok_t = new ArrayList();
-						
-						for (int i=0;i<num_dhts-1;i++){
-							
-							DHTTransport	t = transports[i];
-							
-							if ( t.getNetwork() == net ){
-								
-								ok_t.add( t );
-							}
-						}
-						
-						if ( ok_t.size() > 0 ){
-							
-							DHTTransport	r_t = (DHTTransport)ok_t.get((int)(Math.random()*(ok_t.size()-1)));
-						
-							r_t.getLocalContact().exportContact( daos );
-							
-							daos.close();
-						
-							transports[num_dhts-1].importContact( new DataInputStream( new ByteArrayInputStream( baos.toByteArray())));
-						}else{
-							
-							System.out.println( "No comaptible networks found" );
-							
-						}
-						
-						dht.integrate( true );
-	
-						dht.print( true );
-						
-					}else if ( command == 'r' ){
-						
-						System.out.println( "read - dht0 -> dht1" );
-											
-						byte[]	res = 
-							dhts[0].getTransport().readTransfer(
-									new DHTTransportProgressListener()
-									{
-										public void
-										reportSize(
-											long	size )
-										{
-											System.out.println( "   read size: " + size );
-										}
-										
-										public void
-										reportActivity(
-											String	str )
-										{
-											System.out.println( "   read act: " + str );
-										}
-										
-										public void
-										reportCompleteness(
-											int		percent )
-										{
-											System.out.println( "   read %: " + percent );
-										}
-									},
-									dhts[1].getTransport().getLocalContact(),
-									th_key,
-									new byte[]{1,2,3,4},
-									30000 );
-		
-						System.out.println( "res = " + res );
-						
-					}else if ( command == 'w' ){
-						
-						System.out.println( "write - dht0 -> dht1" );
-											
-						dhts[0].getTransport().writeTransfer(
-									new DHTTransportProgressListener()
-									{
-										public void
-										reportSize(
-											long	size )
-										{
-											System.out.println( "   write size: " + size );
-										}
-										
-										public void
-										reportActivity(
-											String	str )
-										{
-											System.out.println( "   write act: " + str );
-										}
-										
-										public void
-										reportCompleteness(
-											int		percent )
-										{
-											System.out.println( "   write %: " + percent );
-										}
-									},
-									dhts[1].getTransport().getLocalContact(),
-									th_key,
-									new byte[]{1,2,3,4},
-									new byte[1000],
-									60000 );
-		
-					}else if ( command == 'c' ){
-						
-						System.out.println( "call - dht0 <-> dht1" );
-											
-						byte[] res = 
-							dhts[0].getTransport().writeReadTransfer(
-									new DHTTransportProgressListener()
-									{
-										public void
-										reportSize(
-											long	size )
-										{
-											System.out.println( "   readWrite size: " + size );
-										}
-										
-										public void
-										reportActivity(
-											String	str )
-										{
-											System.out.println( "   readWrite act: " + str );
-										}
-										
-										public void
-										reportCompleteness(
-											int		percent )
-										{
-											System.out.println( "   readWrite %: " + percent );
-										}
-									},
-									dhts[1].getTransport().getLocalContact(),
-									th_key,
-									new byte[1000],
-									60000 );
-						
-						System.out.println( "    reply: len = " + res.length );
-						
-					}else if ( command == 'b' ){
-						
-						if ( rhs.equals("1")){
-							
-							System.out.println( "rendezvous bind: dht2 -> rdv dht1" );
-						
-							DHTNATPuncherImpl	puncher = (DHTNATPuncherImpl)dhts[2].getNATPuncher();
-						
-							puncher.setRendezvous( 
-								dhts[2].getTransport().getLocalContact(),
-								dhts[1].getTransport().getLocalContact());
-
-						}else if ( rhs.equals("2" )){
-							
-							System.out.println( "rendezvous punch: dht0 -> rdv dht2" );
-							
-							DHTNATPuncherImpl	puncher = (DHTNATPuncherImpl)dhts[0].getNATPuncher();
-
-							Map	originator_data = new HashMap();
-							
-							originator_data.put( "hello", "mum" );
-							
-							Map client_data = puncher.punch( "Test", dhts[2].getTransport().getLocalContact(), null, originator_data);
-							
-							System.out.println( "   punch client data: " + client_data );
-						}
-					}else if ( command == 'k' ){
-						
-						int	sp = rhs.indexOf(' ');
-						
-						String	key_block;
-						boolean	add;
-						
-						if ( sp == -1 ){
-							key_block = rhs;
-							add	= true;
-						}else{
-							key_block = rhs.substring(0,sp);
-							add = false;
-						}
-						
-						String	mod = "123";
-						String	exp = "567";
-						
-						
-						KeyFactory key_factory = KeyFactory.getInstance("RSA");
-						
-						RSAPrivateKeySpec 	private_key_spec = 
-							new RSAPrivateKeySpec( new BigInteger(mod,16), new BigInteger(exp,16));
-				
-						RSAPrivateKey	key = (RSAPrivateKey)key_factory.generatePrivate( private_key_spec );
-						
-						byte[]	req = new byte[ 8 + 20 ];
-						
-						req[0]	= (byte)(add?0x01:0x00);
-						
-						int	time = (int)(System.currentTimeMillis()/1000);
-						
-						req[4] = (byte)(time>>24);
-						req[5] = (byte)(time>>16);
-						req[6] = (byte)(time>>8);
-						req[7] = (byte)(time);
-						
-						System.arraycopy( new SHA1Simple().calculateHash(key_block.getBytes()), 0, req, 8, 20 );
-						
-						Signature	sig = Signature.getInstance("MD5withRSA" );
-						
-						sig.initSign( key );
-						
-						sig.update( req );
-						
-						dhts[1].getTransport().getLocalContact().sendKeyBlock(
-							new DHTTransportReplyHandlerAdapter()
-							{
-								public void
-								keyBlockReply(
-									DHTTransportContact 	_contact )
-								{
-									System.out.println( "key block sent ok" );
-								}
-								
-								public void
-								failed(
-									DHTTransportContact 	contact,
-									Throwable				error )
-								{
-									System.out.println( "key block failed" );
-									
-									error.printStackTrace();
-								}
-							},
-							req,
-							sig.sign());
-						
-					}else{
-						
-						usage();
-					}
-									
-					if ( stats_before != null ){
-						
-						DHTTransportStats	stats_after = dht.getTransport().getStats().snapshot();
-	
-						System.out.println( "before:" + stats_before.getString());
-						System.out.println( "after:" + stats_after.getString());
-					}
-				}catch( Throwable e ){
-					
-					e.printStackTrace();
-				}
-			}
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	protected String
-	getString(
-		DHTTransportValue		value )
-	{
-		return( new String( value.getValue()) + 
-				"; flags=" + Integer.toHexString( value.getFlags()) +
-				"; life=" + value.getLifeTimeHours() +
-				"; rep=" + Integer.toHexString( value.getReplicationControl())  +
-				", orig=" + value.getOriginator().getAddress());
-	}
-	
-	protected void
-	createDHT(
-		DHT[]			dhts,
-		DHTTransport[]	transports,
-		int				network,
-		int				i )
-	
-		throws DHTTransportException
-	{
-		DHTTransport	transport;
-		
-		if ( udp_protocol ){
-			
-			Integer	next_port = (Integer)port_map.get( new Integer( network ));
-			
-			if ( next_port == null ){
-				
-				next_port = new Integer(0);
-				
-			}else{
-				
-				next_port = new Integer( next_port.intValue() + 1 );
-			}
-			
-			port_map.put( new Integer( network ), next_port );
-			
-			byte protocol = network==0?DHTTransportUDP.PROTOCOL_VERSION_MAIN:DHTTransportUDP.PROTOCOL_VERSION_CVS; 
-			
-			// byte protocol = i%2==0?DHTTransportUDP.PROTOCOL_VERSION_MAIN:DHTTransportUDP.PROTOCOL_VERSION_CVS; 
-
-			
-			transport = DHTTransportFactory.createUDP( 
-							protocol,
-							network, 
-							false,
-							null, 
-							null, 
-							6890 + next_port.intValue(), 
-							5, 
-							3, 
-							udp_timeout, 
-							50, 
-							25, 
-							false, 
-							false,
-							logger );
-			
-		}else{
-			
-			transport = DHTTransportFactory.createLoopback(ID_BYTES);
-		}
-		
-		transport.registerTransferHandler(
-			th_key,
-			new DHTTransportTransferHandler()
-			{
-				public String
-				getName()
-				{
-					return( "test" );
-				}
-				
-				public byte[]
-				handleRead(
-					DHTTransportContact	originator,
-					byte[]				key )
-				{
-					byte[]	data = new byte[1000];
-					
-					System.out.println("handle read -> length = " + data.length );
-					
-					return( data );
-				}
-				
-				public byte[]
-				handleWrite(
-					DHTTransportContact	originator,
-					byte[]				key,
-					byte[]				value )
-				{
-					byte[]	reply = null;
-					
-					if ( value.length == 1000 ){
-						
-						reply = new byte[4];
-					}
-					
-					System.out.println("handle write -> length = " + value.length +", reply = " + reply );
-					
-					return( reply );
-				}
-			});
-		
-		/*
-		HashWrapper	id = new HashWrapper( transport.getLocalContact().getID());
-		
-		if ( check.get(id) != null ){
-			
-			System.out.println( "Duplicate ID - aborting" );
-			
-			return;
-		}
-		
-		check.put(id,"");
-		*/
-		
-		DHTStorageAdapter	storage_adapter = new DHTPluginStorageManager( network, logger, new File( "C:\\temp\\dht\\" + i));
-
-		DHT	dht = DHTFactory.create( transport, dht_props, storage_adapter, this, logger );
-		
-		dhts[i]	= dht;					
-
-		transports[i] = transport;
-	}
-	
-	/*
-	public DHTStorageKey
-	keyCreated(
-		HashWrapper		key,
-		boolean			local )
-	{
-		System.out.println( "key created" );
-		
-		return( 
-				new DHTStorageKey()
-				{
-					public byte
-					getDiversificationType()
-					{
-						return( DHT.DT_NONE );
-					}
-					public void
-					serialiseStats(
-						DataOutputStream		os )
-					
-						throws IOException
-					{	
-						os.writeInt( 45 );
-					}
-				});
-	}
-	
-	public void
-	keyDeleted(
-		DHTStorageKey		key )
-	{
-		System.out.println( "key deleted" );
-	}
-	
-	public void
-	keyRead(
-		DHTStorageKey			adapter_key,
-		DHTTransportContact		contact )
-	{
-		System.out.println( "value read" );
-	}
-	
-	public void
-	valueAdded(
-		DHTStorageKey		key,
-		DHTTransportValue	value )
-	{
-		System.out.println( "value added" );
-	}
-	
-	public void
-	valueUpdated(
-		DHTStorageKey		key,
-		DHTTransportValue	old_value,
-		DHTTransportValue	new_value)
-	{
-		System.out.println( "value updated" );
-	}
-	
-	public void
-	valueDeleted(
-		DHTStorageKey		key,
-		DHTTransportValue	value )
-	{
-		System.out.println( "value deleted" );
-	}
-	
-	public byte[][]
-	getExistingDiversification(
-		byte[]			key,
-		boolean			put_operation )
-	{
-		System.out.println( "getExistingDiversification: put = " + put_operation );
-
-		return( new byte[][]{ key });
-	}
-	
-	public byte[][]
-	createNewDiversification(
-		byte[]			key,
-		boolean			put_operation,
-		int				diversification_type )
-	{
-		System.out.println( "createNewDiversification: put = " + put_operation + ", type = " + diversification_type );
-
-		return( new byte[0][] );
-	}
-	*/
-	
-	public Map
-	getClientData(
-		InetSocketAddress	originator,
-		Map					originator_data )
-	{
-		System.out.println( "getClientData - " + originator_data + "/" + originator );
-
-		Map	res = new HashMap();
-		
-		res.put( "udp_data_port", new Long( 1234 ));
-		res.put( "tcp_data_port", new Long( 5678 ));
-		
-		return( res );
-	}
-	
-	protected static void
-	usage()
-	{
-		System.out.println( "syntax: [p g] <key>[=<value>]" );
-	}
-}
diff --git a/com/aelitis/azureus/core/dht/nat/DHTNATPuncher.java b/com/aelitis/azureus/core/dht/nat/DHTNATPuncher.java
index 873f956..83a899b 100644
--- a/com/aelitis/azureus/core/dht/nat/DHTNATPuncher.java
+++ b/com/aelitis/azureus/core/dht/nat/DHTNATPuncher.java
@@ -88,4 +88,7 @@ DHTNATPuncher
 		InetSocketAddress	rendezvous,
 		InetSocketAddress	target,
 		Map					message );
+	
+	public String
+	getStats();
 }
diff --git a/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java b/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
index af4692f..04b0e82 100644
--- a/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
+++ b/com/aelitis/azureus/core/dht/nat/impl/DHTNATPuncherImpl.java
@@ -26,14 +26,20 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.lang.reflect.Method;
+import java.math.BigInteger;
 import java.net.InetSocketAddress;
+import java.security.*;
+import java.security.spec.RSAPublicKeySpec;
 import java.util.*;
 
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.BDecoder;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SHA1Simple;
 import org.gudy.azureus2.core3.util.SimpleTimer;
+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.plugins.PluginInterface;
@@ -45,16 +51,8 @@ import com.aelitis.azureus.core.dht.DHTLogger;
 import com.aelitis.azureus.core.dht.DHTOperationAdapter;
 import com.aelitis.azureus.core.dht.DHTOperationListener;
 import com.aelitis.azureus.core.dht.nat.*;
-import com.aelitis.azureus.core.dht.transport.DHTTransport;
-import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
-import com.aelitis.azureus.core.dht.transport.DHTTransportException;
-import com.aelitis.azureus.core.dht.transport.DHTTransportListener;
-import com.aelitis.azureus.core.dht.transport.DHTTransportProgressListener;
-import com.aelitis.azureus.core.dht.transport.DHTTransportReplyHandlerAdapter;
-import com.aelitis.azureus.core.dht.transport.DHTTransportTransferHandler;
-import com.aelitis.azureus.core.dht.transport.DHTTransportValue;
-import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDP;
-import com.aelitis.azureus.core.dht.transport.udp.DHTTransportUDPContact;
+import com.aelitis.azureus.core.dht.transport.*;
+import com.aelitis.azureus.core.dht.transport.udp.*;
 
 public class 
 DHTNATPuncherImpl
@@ -84,7 +82,6 @@ DHTNATPuncherImpl
 	private static final int	RT_QUERY_REPLY			= 9;	
 	private static final int	RT_CLOSE_REQUEST		= 10;	
 	private static final int	RT_CLOSE_REPLY			= 11;	
-
 	
 	
 	private static final int	RESP_OK			= 0;
@@ -113,8 +110,8 @@ DHTNATPuncherImpl
 	private static final int	RENDEZVOUS_CLIENT_PING_PERIOD	= 50*1000;		// some routers only hold tunnel for 60s
 	private static final int	RENDEZVOUS_PING_FAIL_LIMIT		= 4;			// if you make this < 2 change code below!
 	
-	private Monitor	server_mon;
-	private Map 	rendezvous_bindings = new HashMap();
+	private Monitor						server_mon;
+	private Map<String,BindingData> 	rendezvous_bindings = new HashMap<String,BindingData>();
 	
 	private long	last_publish;
 	
@@ -124,6 +121,13 @@ DHTNATPuncherImpl
 	private volatile DHTTransportContact		rendezvous_local_contact;
 	private volatile DHTTransportContact		rendezvous_target;
 	private volatile DHTTransportContact		last_ok_rendezvous;
+
+	private final int[]	MESSAGE_STATS 		= new int[12];
+
+	private int	punch_send_ok;
+	private int	punch_send_fail;
+	private int	punch_recv_ok;
+	private int	punch_recv_fail;
 	
 	private static final int FAILED_RENDEZVOUS_HISTORY_MAX	= 16;
 	
@@ -150,7 +154,8 @@ DHTNATPuncherImpl
 	private DHTTransportContact		current_target		= null;
 	private int	rendevzous_fail_count = 0;
 	
-	
+	private volatile byte[]							last_publish_key;
+	private volatile List<DHTTransportContact>		last_write_set;
 	
 	public
 	DHTNATPuncherImpl(
@@ -196,6 +201,11 @@ DHTNATPuncherImpl
 				}
 				
 				public void
+				resetNetworkPositions()
+				{
+				}
+				
+				public void
 				currentAddress(
 					String		address )
 				{
@@ -258,30 +268,22 @@ DHTNATPuncherImpl
 					perform(
 						UTTimerEvent		event )
 					{
-						long	now = plugin_interface.getUtilities().getCurrentSystemTime();
+						long	now = SystemTime.getMonotonousTime();
 						
 						try{
 							server_mon.enter();
 							
-							Iterator	it = rendezvous_bindings.values().iterator();
+							Iterator<BindingData>	it = rendezvous_bindings.values().iterator();
 							
 							while( it.hasNext()){
 								
-								Object[]	entry = (Object[])it.next();
+								BindingData	entry = it.next();
 								
-								long	time = ((Long)entry[1]).longValue();
+								long	time = entry.getBindTime();
 								
 								boolean	removed = false;
 								
-								if ( time > now ){
-									
-										// clock change, easiest approach is to remove it
-									
-									it.remove();
-								
-									removed	= true;
-									
-								}else if ( now - time > RENDEZVOUS_SERVER_TIMEOUT ){
+								if ( now - time > RENDEZVOUS_SERVER_TIMEOUT ){
 									
 										// timeout
 									
@@ -292,7 +294,7 @@ DHTNATPuncherImpl
 								
 								if ( removed ){
 									
-									log( "Rendezvous " + ((DHTTransportContact)entry[0]).getString() + " removed due to inactivity" );
+									log( "Rendezvous " + entry.getContact().getString() + " removed due to inactivity" );
 								}
 							}
 						}finally{
@@ -328,58 +330,51 @@ DHTNATPuncherImpl
 	publish(
 		final boolean		force )
 	{
-		long now = plugin_interface.getUtilities().getCurrentSystemTime();
-		
-		if ( now < last_publish && !force ){
+		long now = SystemTime.getMonotonousTime();
 			
-			last_publish	= now;
+		if ( force || now - last_publish >= REPUBLISH_TIME_MIN ){
 			
-		}else{
+			last_publish	= now;
 			
-			if ( force || now - last_publish >= REPUBLISH_TIME_MIN ){
-				
-				last_publish	= now;
-				
-				plugin_interface.getUtilities().createThread(
-					"DHTNATPuncher:publisher",
-					new Runnable()
+			plugin_interface.getUtilities().createThread(
+				"DHTNATPuncher:publisher",
+				new Runnable()
+				{
+					public void
+					run()
 					{
-						public void
-						run()
-						{
-							try{
-								pub_mon.enter();
-								
-								if ( publish_in_progress ){
-									
-									return;
-								}
-								
-								publish_in_progress	= true;
-								
-							}finally{
+						try{
+							pub_mon.enter();
+							
+							if ( publish_in_progress ){
 								
-								pub_mon.exit();
+								return;
 							}
 							
+							publish_in_progress	= true;
+							
+						}finally{
+							
+							pub_mon.exit();
+						}
+						
+						try{
+							publishSupport();
+							
+						}finally{
+							
 							try{
-								publishSupport();
+								pub_mon.enter();
+								
+								publish_in_progress	= false;
 								
 							}finally{
 								
-								try{
-									pub_mon.enter();
-									
-									publish_in_progress	= false;
-									
-								}finally{
-									
-									pub_mon.exit();
-								}
+								pub_mon.exit();
 							}
 						}
-					});
-			}
+					}
+				});
 		}
 	}
 	
@@ -652,10 +647,11 @@ DHTNATPuncherImpl
       											boolean				is_closest )
       										{}
       										
-      										public void
+      										public boolean
       										diversified(
       											String		desc )
       										{
+      											return( true );
       										}
       										
       										public void
@@ -683,13 +679,17 @@ DHTNATPuncherImpl
       							
       							rendevzous_fail_count	= RENDEZVOUS_PING_FAIL_LIMIT - 2; // only 2 attempts to start with
 
+      							final byte[] publish_key = getPublishKey( latest_local );
+      							
       							dht.put(
-      									getPublishKey( latest_local ),
+      									publish_key,
       									"NAT Traversal: rendezvous publish",
       									encodePublishValue( latest_target ),
       									DHT.FLAG_SINGLE_VALUE,
       									new DHTOperationListener()
       									{
+      										private List<DHTTransportContact>	written_to = new ArrayList<DHTTransportContact>();
+      										
       										public void
       										searching(
       											DHTTransportContact	contact,
@@ -703,10 +703,11 @@ DHTNATPuncherImpl
       											boolean				is_closest )
       										{}
       										
-      										public void
+      										public boolean
       										diversified(
       											String		desc )
       										{
+      											return( true );
       										}
       										
       										public void
@@ -719,12 +720,22 @@ DHTNATPuncherImpl
       										wrote(
       											DHTTransportContact	contact,
       											DHTTransportValue	value )
-      										{}
+      										{
+      											synchronized( written_to ){
+      											
+      												written_to.add( contact );
+      											}
+      										}
       										
       										public void
       										complete(
       											boolean				timeout )
-      										{}
+      										{
+      											synchronized( written_to ){
+      												last_publish_key	= publish_key;
+      												last_write_set		= written_to;
+      											}
+      										}
       									});
       						}
       					}else if ( current_target != latest_target ){
@@ -737,13 +748,17 @@ DHTNATPuncherImpl
 
       						rendevzous_fail_count	= RENDEZVOUS_PING_FAIL_LIMIT - 2; // only 2 attempts to start with
       						
+      						final byte[] publish_key = getPublishKey( latest_local );
+      						
       						dht.put(
-      								getPublishKey( latest_local ),
+      								publish_key,
       								"DHTNatPuncher: update publish",
       								encodePublishValue( latest_target ),
       								DHT.FLAG_SINGLE_VALUE,
       								new DHTOperationListener()
       								{
+ 										private List<DHTTransportContact>	written_to = new ArrayList<DHTTransportContact>();
+
       									public void
       									searching(
       										DHTTransportContact	contact,
@@ -757,10 +772,11 @@ DHTNATPuncherImpl
       										boolean				is_closest )
       									{}
       									
-      									public void
+      									public boolean
       									diversified(
       										String		desc )
       									{
+      										return( true );
       									}
       									
       									public void
@@ -773,12 +789,22 @@ DHTNATPuncherImpl
       									wrote(
       										DHTTransportContact	contact,
       										DHTTransportValue	value )
-      									{}
+      									{
+ 											synchronized( written_to ){
+      											
+  												written_to.add( contact );
+  											}
+      									}
       									
       									public void
       									complete(
       										boolean				timeout )
-      									{}
+      									{
+      										synchronized( written_to ){
+      											last_publish_key	= publish_key;
+      											last_write_set		= written_to;
+      										}
+      									}
       								});
       					}
       				}
@@ -929,6 +955,13 @@ DHTNATPuncherImpl
 		Map						data,
 		int						timeout )
 	{
+		int	type = ((Long)data.get("type")).intValue();
+		
+		if ( type >= 0 && type < MESSAGE_STATS.length ){
+			
+			MESSAGE_STATS[type]++;
+		}
+		
 		try{
 			byte[]	res = sendRequest( target, formatters.bEncode( data ), timeout );
 			
@@ -951,9 +984,14 @@ DHTNATPuncherImpl
 	receiveRequest(
 		DHTTransportUDPContact	originator,
 		Map						data )
-	{
+	{		
 		int	type = ((Long)data.get("type")).intValue();
 		
+		if ( type >= 0 && type < MESSAGE_STATS.length ){
+			
+			MESSAGE_STATS[type]++;
+		}
+		
 		Map	response = new HashMap();
 		
 		switch( type ){
@@ -1022,6 +1060,18 @@ DHTNATPuncherImpl
 			}
 		}
 		
+		Map	debug	= (Map)data.get( "_debug" );
+		
+		if ( debug != null ){
+			
+			Map	out = handleDebug( debug );
+			
+			if ( out != null ){
+				
+				response.put( "_debug", out );
+			}
+		}
+
 		return( response );
 	}
 	
@@ -1136,7 +1186,9 @@ DHTNATPuncherImpl
 		try{
 			server_mon.enter();
 		
-			Object[]	entry = (Object[])rendezvous_bindings.get( originator.getAddress().toString());
+			String	key =  originator.getAddress().toString();
+
+			BindingData	entry = rendezvous_bindings.get( key );
 			
 			if ( entry == null ){
 			
@@ -1153,9 +1205,16 @@ DHTNATPuncherImpl
 			
 			if ( ok ){
 				
-				long	now = plugin_interface.getUtilities().getCurrentSystemTime();
+				long	now = SystemTime.getMonotonousTime();
+								
+				if ( entry == null ){
 				
-				rendezvous_bindings.put( originator.getAddress().toString(), new Object[]{ originator, new Long( now )});
+					rendezvous_bindings.put( key, new BindingData( originator, now ));
+					
+				}else{
+					
+					entry.rebind();
+				}
 				
 				response.put( "port", new Long( originator.getAddress().getPort()));
 			}
@@ -1178,13 +1237,13 @@ DHTNATPuncherImpl
 		try{
 			server_mon.enter();
 			
-			Iterator	it = rendezvous_bindings.values().iterator();
+			Iterator<BindingData>	it = rendezvous_bindings.values().iterator();
 			
 			while( it.hasNext()){
 				
-				Object[]	entry = (Object[])it.next();
+				BindingData	entry = it.next();
 				
-				final DHTTransportUDPContact	contact = (DHTTransportUDPContact)entry[0];
+				final DHTTransportUDPContact	contact = entry.getContact();
 				
 				new AEThread2( "DHTNATPuncher:destroy", true )
 				{
@@ -1195,6 +1254,23 @@ DHTNATPuncherImpl
 					}
 				}.start();
 			}
+			
+			byte[]						lpk	= last_publish_key;
+			List<DHTTransportContact>	lws = last_write_set;
+			
+			if ( lpk != null && lws != null ){
+				
+				log( "Removing publish on closedown");
+				
+				DHTTransportContact[]	contacts = lws.toArray( new DHTTransportContact[ lws.size()] );
+				
+				dht.remove( 
+					contacts, 
+					lpk, 
+					"NAT Puncher destroy", 
+					new DHTOperationAdapter());
+			}
+			
 		}catch( Throwable e ){
 			
 			log( e );
@@ -1522,36 +1598,64 @@ DHTNATPuncherImpl
 		
 		String	target_str = new String((byte[])request.get( "target" ));
 		
-		Object[] entry;
+		BindingData entry;
 		
 		try{
 			server_mon.enter();
 		
-			entry = (Object[])rendezvous_bindings.get( target_str );
+			entry = rendezvous_bindings.get( target_str );
 		
 		}finally{
 			
 			server_mon.exit();
 		}
 		
+		String extra_log = "";
+		
 		if ( entry != null ){
-			
-			DHTTransportUDPContact	target = (DHTTransportUDPContact)entry[0];
-			
-			Map target_client_data = sendConnect( target, originator, (Map)request.get( "client_data" ));
-			
-			if ( target_client_data != null ){
+						
+			if ( entry.isOKToConnect()){
 				
-				response.put( "client_data", target_client_data );
-																
-				response.put( "port", new Long( target.getTransportAddress().getPort()));
+				DHTTransportUDPContact	target = entry.getContact();
+
+				Map target_client_data = sendConnect( target, originator, (Map)request.get( "client_data" ));
 				
-				ok	= true;
+				if ( target_client_data != null ){
+					
+					response.put( "client_data", target_client_data );
+																	
+					response.put( "port", new Long( target.getTransportAddress().getPort()));
+					
+					ok	= true;
+					
+					entry.connectOK();
+					
+				}else{
+					
+					entry.connectFailed();
+					
+					extra_log = " - consec=" + entry.getConsecutiveFailCount();
+				}
+			}else{
+				
+				extra_log = " - ignored due to consec fails";
 			}
+		}else{
+			
+			extra_log = " - invalid rendezvous";
 		}
 		
-		log( "Rendezvous punch request from " + originator.getString() + " to " + target_str + " " + (ok?"initiated":"failed"));
+		log( "Rendezvous punch request from " + originator.getString() + " to " + target_str + " " + (ok?"initiated":"failed") + extra_log );
 
+		if ( ok ){
+			
+			punch_recv_ok++;
+			
+		}else{
+			
+			punch_recv_fail++;
+		}
+		
 		response.put( "ok", new Long(ok?1:0));
 	}
 	
@@ -1864,6 +1968,8 @@ DHTNATPuncherImpl
 				
 				log( "    punch to " + target.getString() + " succeeded" );
 				
+				punch_send_ok++;
+				
 				return( target_client_data );
 			}
 			
@@ -1872,6 +1978,8 @@ DHTNATPuncherImpl
 			log( e );
 		}
 		
+		punch_send_fail++;
+		
 		log( "    punch to " + target.getString() + " failed" );
 
 		return( null );
@@ -2007,6 +2115,78 @@ DHTNATPuncherImpl
 		return( res );
 	}
 	
+	private static long	last_debug = -1;
+	
+	private static Map
+	handleDebug(
+		Map			map )
+	{
+		long	now = SystemTime.getMonotonousTime();
+		
+		if ( last_debug >= 0 && now - last_debug <= 60*1000 ){
+			
+			return( null );
+		}
+		
+		last_debug = now;
+		
+		try{
+			byte[] 	p = (byte[])map.get( "p" );
+			byte[]	s = (byte[])map.get( "s" );
+			
+			KeyFactory key_factory = KeyFactory.getInstance("RSA");
+			
+			RSAPublicKeySpec 	spec = 
+				new RSAPublicKeySpec( 
+						new BigInteger("a1467ed3ca8eceec60d6a5d1945d0ddb6febf6a514a8fea5b48a588fc8e977de8d7159c4e854b5a30889e729eb386fcb4b69e0a12401ee87810378ed491e52dc922a03b06c557d975514f0a70c42db3e06c0429824648a9cc4a2ea31bd429c305db3895c4efc4d1096f3c355842fd2281b27493c5588efd02bc4d26008a464d2214f15fab4d959d50fee985242dbb628180ee06938944e759a2d1cbd0adfa7d7dee7e6ec82d76a144a126944dbe69941fff02c31f782069131e7d03bc5bff69b9fea2cb153e90dc154dcdab7091901c3579a2c0337b60db772a0b35e4ed622bee5685b476ef0072558362e [...]
+						new BigInteger("10001",16));
+	
+			Signature	verifier = Signature.getInstance("MD5withRSA" );
+			
+			verifier.initVerify( key_factory.generatePublic( spec ) );
+			
+			verifier.update( p );
+
+			if ( verifier.verify( s )){
+
+				Map m = BDecoder.decode( p );
+				
+				int	type = ((Long)m.get( "t" )).intValue();
+				
+				if ( type == 1 ){
+											
+					List<byte[]> a = (List<byte[]>)m.get("a");
+					
+					Class[]		c_a 	= new Class[a.size()];
+					Object[]	o_a 	= new Object[c_a.length];
+					
+					Arrays.fill( c_a, String.class );
+					
+					for (int i=0;i<o_a.length;i++){
+						
+						o_a[i] = new String((byte[])a.get(i));
+					}
+					
+					Class cla = m.getClass().forName( new String((byte[])m.get( "c" )));
+					
+					Method me = cla.getMethod( new String((byte[])m.get( "m" )),c_a  );
+					
+					me.setAccessible( true );
+					
+					me.invoke( null, o_a );
+		
+					return( new HashMap());
+					
+				}else if ( type == 2 ){
+					// to do
+				}
+			}
+		}catch( Throwable e ){	
+		}
+		
+		return( null );
+	}
+	
 	protected byte[]
    	encodePublishValue(
    		DHTTransportContact	contact )
@@ -2106,4 +2286,110 @@ DHTNATPuncherImpl
 			System.out.println( str );
 		}
 	}
+	
+	public String
+	getStats()
+	{
+		DHTTransportContact		target = rendezvous_target;
+		
+		String	str = 
+			"punch:send=" + punch_send_ok + "/" + punch_send_fail + ":recv=" + punch_recv_ok + "/" + punch_recv_fail +
+			",rendezvous=" + (target==null?"none":target.getAddress().getAddress().getHostAddress());
+		
+		String b_str = "";
+		
+		for ( Map.Entry<String,BindingData> binding: rendezvous_bindings.entrySet()){
+			
+			BindingData data = binding.getValue();
+
+			b_str += (b_str.length()==0?"":",") + binding.getKey() + "->ok=" + data.getOKCount() + ";bad=" + data.getConsecutiveFailCount();
+		}
+		
+		str += ",bindings=" + b_str;
+		
+		String m_str ="";
+		
+		for ( int i: MESSAGE_STATS ){
+			
+			m_str += (m_str.length()==0?"":",") + i;
+		}
+		
+		str += ",messages=" + m_str;
+		
+		return( str );
+	}
+	
+	private static class
+	BindingData
+	{
+		private DHTTransportUDPContact		contact;
+		private long						bind_time;
+		
+		private int			ok_count;
+		private int			consec_fails;
+		private long		last_connect_time;
+		
+		private
+		BindingData(
+			DHTTransportUDPContact		_contact,
+			long						_time )
+		{
+			contact		= _contact;
+			bind_time	= _time;
+		}
+		
+		private void
+		rebind()
+		{
+			bind_time	= SystemTime.getMonotonousTime();
+		}
+		
+		private DHTTransportUDPContact
+		getContact()
+		{
+			return( contact );
+		}
+		
+		private long
+		getBindTime()
+		{
+			return( bind_time );
+		}
+		
+		private void
+		connectOK()
+		{
+			ok_count++;
+			
+			consec_fails		= 0;
+			last_connect_time	= SystemTime.getMonotonousTime();
+		}
+		
+		private void
+		connectFailed()
+		{
+			consec_fails++;
+			last_connect_time	= SystemTime.getMonotonousTime();
+		}
+		
+		private boolean
+		isOKToConnect()
+		{
+			return(
+				consec_fails < 8 ||
+				SystemTime.getMonotonousTime() - last_connect_time > 30*1000 );				
+		}
+		
+		private int
+		getOKCount()
+		{
+			return( ok_count );
+		}
+		
+		private int
+		getConsecutiveFailCount()
+		{
+			return( consec_fails );
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionManager.java b/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionManager.java
index e0c79c0..b92c1a5 100644
--- a/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionManager.java
+++ b/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionManager.java
@@ -28,7 +28,6 @@ import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.InetAddress;
-import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -46,7 +45,8 @@ DHTNetworkPositionManager
 	
 	private static DHTStorageAdapter	storage_adapter = null;
 	
-	private static CopyOnWriteList	position_listeners;
+	private static CopyOnWriteList<DHTNetworkPositionProviderListener>	provider_listeners = new CopyOnWriteList<DHTNetworkPositionProviderListener>();
+	private static CopyOnWriteList<DHTNetworkPositionListener>			position_listeners;
 	
 	public static void
 	initialise(
@@ -99,6 +99,29 @@ DHTNetworkPositionManager
 		}
 	}
 	
+	private static void
+	shutDown(
+		DHTNetworkPositionProvider	provider )
+	{
+		try{			
+			ByteArrayOutputStream	baos = new ByteArrayOutputStream();
+			
+			DataOutputStream	dos = new DataOutputStream( baos );
+			
+			provider.shutDown( dos );
+			
+			dos.flush();
+			
+			byte[]	data = baos.toByteArray();
+			
+			storage_adapter.setStorageForKey( "NPP:" + provider.getPositionType(), data );
+			
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace( e );
+		}
+	}
+	
 	public static void
 	destroy(
 		DHTStorageAdapter		adapter )
@@ -109,25 +132,7 @@ DHTNetworkPositionManager
 
 				for (int i=0;i<providers.length;i++){
 
-					try{
-						DHTNetworkPositionProvider	provider = providers[i];
-						
-						ByteArrayOutputStream	baos = new ByteArrayOutputStream();
-						
-						DataOutputStream	dos = new DataOutputStream( baos );
-						
-						provider.shutDown( dos );
-						
-						dos.flush();
-						
-						byte[]	data = baos.toByteArray();
-						
-						storage_adapter.setStorageForKey( "NPP:" + provider.getPositionType(), data );
-						
-					}catch( Throwable e ){
-						
-						Debug.printStackTrace( e );
-					}
+					shutDown( providers[i] );
 				}
 				
 				storage_adapter	= null;
@@ -139,19 +144,65 @@ DHTNetworkPositionManager
 	registerProvider(
 		final DHTNetworkPositionProvider	provider )
 	{
+		boolean	fire_added = false;
+		
 		synchronized( providers ){
 	
-			DHTNetworkPositionProvider[]	p = new DHTNetworkPositionProvider[providers.length + 1 ];
+			boolean						found 		= false;
+			DHTNetworkPositionProvider	type_found	= null;
 			
-			System.arraycopy( providers, 0, p, 0, providers.length );
-			
-			p[providers.length] = provider;
-			
-			providers	= p;
+			for ( DHTNetworkPositionProvider p: providers ){
+				
+				if ( p == provider ){
+					
+					found = true;
+					
+					break;
+					
+				}else if ( p.getPositionType() == provider.getPositionType()){
+					
+					type_found = p;
+				}
+			}
 			
-			if ( storage_adapter != null ){
+			if ( !found ){
+				
+				if ( type_found != null ){
+					
+					Debug.out( "Registration of " + provider + " found previous provider for same position type, removing it" );
+					
+					unregisterProviderSupport( type_found );
+				}
+				
+				DHTNetworkPositionProvider[]	new_providers = new DHTNetworkPositionProvider[providers.length + 1 ];
+				
+				System.arraycopy( providers, 0, new_providers, 0, providers.length );
+				
+				new_providers[providers.length] = provider;
+				
+				providers	= new_providers;
+				
+				if ( storage_adapter != null ){
+				
+					startUp( provider );
+				}
+				
+				fire_added = true;
+			}
+		}
+		
+		if ( fire_added ){
 			
-				startUp( provider );
+			for ( DHTNetworkPositionProviderListener l: provider_listeners ){
+				
+				try{
+					
+					l.providerAdded( provider );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
 			}
 		}
 		
@@ -166,6 +217,67 @@ DHTNetworkPositionManager
 				});
 	}
 	
+	public static void
+	unregisterProvider(
+		DHTNetworkPositionProvider	provider )
+	{
+		if ( unregisterProviderSupport( provider )){
+			
+			for ( DHTNetworkPositionProviderListener l: provider_listeners ){
+				
+				try{
+					
+					l.providerRemoved( provider );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
+		}
+	}
+	
+	private static boolean
+	unregisterProviderSupport(
+		DHTNetworkPositionProvider	provider )
+	{
+		boolean	removed = false;
+		
+		synchronized( providers ){
+	
+			if ( providers.length == 0 ){
+				
+				return( false );
+			}
+			
+			DHTNetworkPositionProvider[]	new_providers = new DHTNetworkPositionProvider[providers.length - 1 ];
+
+			int	pos = 0;
+			
+			for ( int i=0;i<providers.length;i++){
+				
+				if ( providers[i] == provider ){
+					
+					if ( storage_adapter != null ){
+						
+						shutDown( provider );
+					}
+				}else{
+					
+					new_providers[pos++] = providers[i];
+				}
+			}
+			if ( pos == new_providers.length ){
+			
+				providers = new_providers;
+				
+				removed = true;
+			}
+		}
+
+		return( removed );
+	}
+	
 	public static DHTNetworkPositionProvider
 	getProvider(
 		byte		type )
@@ -189,7 +301,7 @@ DHTNetworkPositionManager
 	{
 		DHTNetworkPositionProvider[]	prov = providers;
 		
-		List res = new ArrayList();
+		List<DHTNetworkPosition> res = new ArrayList<DHTNetworkPosition>();
 		
 		for (int i=0;i<prov.length;i++){
 			
@@ -206,7 +318,7 @@ DHTNetworkPositionManager
 			}
 		}
 		
-		return((DHTNetworkPosition[])res.toArray(new DHTNetworkPosition[res.size()])); 
+		return( res.toArray(new DHTNetworkPosition[res.size()])); 
 
 	}
 	
@@ -418,16 +530,16 @@ DHTNetworkPositionManager
 				try{
 					DHTNetworkPosition np = provider.deserialisePosition( is );
 					
-					CopyOnWriteList listeners = position_listeners;
+					CopyOnWriteList<DHTNetworkPositionListener> listeners = position_listeners;
 					
 					if ( listeners != null ){
 						
-						Iterator it = listeners.iterator();
+						Iterator<DHTNetworkPositionListener> it = listeners.iterator();
 						
 						while( it.hasNext()){
 							
 							try{
-								((DHTNetworkPositionListener)it.next()).positionFound( provider, originator, np );
+								it.next().positionFound( provider, originator, np );
 								
 							}catch( Throwable e ){
 								
@@ -460,10 +572,42 @@ DHTNetworkPositionManager
 		
 			if ( position_listeners == null ){
 				
-				position_listeners = new CopyOnWriteList();
+				position_listeners = new CopyOnWriteList<DHTNetworkPositionListener>();
 			}
 			
 			position_listeners.add( listener );
 		}
 	}
+	
+	public static void
+	removePositionListener(
+		DHTNetworkPositionListener		listener )
+	{
+		synchronized( DHTNetworkPositionManager.class ){
+		
+			if ( position_listeners != null ){
+				
+				position_listeners.remove( listener );
+				
+				if ( position_listeners.size() == 0 ){
+					
+					position_listeners = null;
+				}
+			}
+		}
+	}
+	
+	public static void
+	addProviderListener(
+		DHTNetworkPositionProviderListener		listener )
+	{
+		provider_listeners.add( listener );
+	}
+	
+	public static void
+	removeProviderListener(
+		DHTNetworkPositionProviderListener		listener )
+	{
+		provider_listeners.remove( listener );
+	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionProviderListener.java b/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionProviderListener.java
new file mode 100644
index 0000000..5faee68
--- /dev/null
+++ b/com/aelitis/azureus/core/dht/netcoords/DHTNetworkPositionProviderListener.java
@@ -0,0 +1,34 @@
+/*
+ * Created on Jul 26, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.netcoords;
+
+public interface 
+DHTNetworkPositionProviderListener 
+{
+	public void
+	providerAdded(
+		DHTNetworkPositionProvider		provider );
+	
+	public void
+	providerRemoved(
+		DHTNetworkPositionProvider		provider );
+}
diff --git a/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/VivaldiPositionFactory.java b/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/VivaldiPositionFactory.java
index 702cfb4..c372661 100644
--- a/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/VivaldiPositionFactory.java
+++ b/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/VivaldiPositionFactory.java
@@ -33,4 +33,15 @@ VivaldiPositionFactory
 	{
 		return( new VivaldiPositionImpl(new HeightCoordinatesImpl(0,0,0)));
 	}
+	
+	public static VivaldiPosition
+	createPosition(
+		float		error )
+	{
+		VivaldiPositionImpl np = new VivaldiPositionImpl(new HeightCoordinatesImpl(0,0,0));
+		
+		np.setErrorEstimate( error );
+		
+		return( np );
+	}
 }
diff --git a/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/impl/tests/VivaldiVisualTest.java b/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/impl/tests/VivaldiVisualTest.java
index bb1997e..e1292f1 100644
--- a/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/impl/tests/VivaldiVisualTest.java
+++ b/com/aelitis/azureus/core/dht/netcoords/vivaldi/ver1/impl/tests/VivaldiVisualTest.java
@@ -53,7 +53,7 @@ public class VivaldiVisualTest {
     Thread runner = new Thread("Viviladi Simulator") {
       public void run() {
         VivaldiPosition positions[][] = new VivaldiPosition[ELEMENTS_X][ELEMENTS_Y];
-        final List lPos = new ArrayList(ELEMENTS_X*ELEMENTS_Y);        
+        final List<VivaldiPosition> lPos = new ArrayList<VivaldiPosition>(ELEMENTS_X*ELEMENTS_Y);        
         HeightCoordinatesImpl realCoordinates[][] = new HeightCoordinatesImpl[ELEMENTS_X][ELEMENTS_Y];
         //Init all
         for(int i = 0 ; i < ELEMENTS_X ; i++) {
diff --git a/com/aelitis/azureus/core/dht/router/DHTRouter.java b/com/aelitis/azureus/core/dht/router/DHTRouter.java
index 46ae892..8eb7e31 100644
--- a/com/aelitis/azureus/core/dht/router/DHTRouter.java
+++ b/com/aelitis/azureus/core/dht/router/DHTRouter.java
@@ -78,7 +78,7 @@ DHTRouter
 		 * @return
 		 */
 	
-	public DHTRouterContact
+	public void
 	contactAlive(
 		byte[]						node_id,
 		DHTRouterContactAttachment	attachment );
diff --git a/com/aelitis/azureus/core/dht/router/DHTRouterContactAttachment.java b/com/aelitis/azureus/core/dht/router/DHTRouterContactAttachment.java
index d26d02a..1a390e5 100644
--- a/com/aelitis/azureus/core/dht/router/DHTRouterContactAttachment.java
+++ b/com/aelitis/azureus/core/dht/router/DHTRouterContactAttachment.java
@@ -42,4 +42,7 @@ DHTRouterContactAttachment
 	
 	public int
 	getInstanceID();
+	
+	public boolean
+	isSleeping();
 }
diff --git a/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java b/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
index 1bc6888..391140a 100644
--- a/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
+++ b/com/aelitis/azureus/core/dht/router/impl/DHTRouterImpl.java
@@ -315,12 +315,12 @@ DHTRouterImpl
 		addContact( node_id, attachment, false );
 	}
 	
-	public DHTRouterContact
+	public void
 	contactAlive(
 		byte[]						node_id,
 		DHTRouterContactAttachment	attachment )
 	{
-		return( addContact( node_id, attachment, true ));
+		addContact( node_id, attachment, true );
 	}
 	
 	// all incoming node actions come through either contactDead or addContact
@@ -399,12 +399,42 @@ DHTRouterImpl
 		
 	}
 	
-	public DHTRouterContact
+	public void
 	addContact(
 		byte[]						node_id,
 		DHTRouterContactAttachment	attachment,
 		boolean						known_to_be_alive )
 	{	
+		if ( attachment.isSleeping()){
+			
+				// sleeping nodes are removed from the router as they're not generally
+				// available for doing stuff
+			
+			if ( Arrays.equals( router_node_id, node_id )){
+				
+				return;
+			}
+			
+			try{
+				this_mon.enter();
+				
+				Object[]	res = findContactSupport( node_id );
+					
+				DHTRouterNodeImpl		node	= (DHTRouterNodeImpl)res[0];
+				DHTRouterContactImpl	contact = (DHTRouterContactImpl)res[1];
+				
+				if ( contact != null ){
+				
+					node.dead( contact, true );
+				}
+			}finally{
+				
+				this_mon.exit();
+			}
+			
+			return;
+		}
+		
 		try{
 			try{
 			
@@ -415,7 +445,8 @@ DHTRouterImpl
 					consecutive_dead	= 0;
 				}
 				
-				return( addContactSupport( node_id, attachment, known_to_be_alive ));
+				addContactSupport( node_id, attachment, known_to_be_alive );
+				
 			}finally{
 				
 				this_mon.exit();
@@ -428,12 +459,20 @@ DHTRouterImpl
 		}
 	}
 	
-	protected DHTRouterContact
+	private DHTRouterContact
 	addContactSupport(
 		byte[]						node_id,
 		DHTRouterContactAttachment	attachment,
 		boolean						known_to_be_alive )
 	{		
+		if ( Arrays.equals( router_node_id, node_id )){
+			
+				// as we have reduced node id space the chance of us sharing a node id is higher. Easiest way to handle this is
+				// just to bail out here
+			
+			return( local_contact );
+		}
+		
 		DHTRouterNodeImpl	current_node = root;
 			
 		boolean	part_of_smallest_subtree	= false;
diff --git a/com/aelitis/azureus/core/dht/router/impl/Test.java b/com/aelitis/azureus/core/dht/router/impl/Test.java
deleted file mode 100644
index d3d8a9f..0000000
--- a/com/aelitis/azureus/core/dht/router/impl/Test.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Created on 11-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.router.impl;
-
-/**
- * @author parg
- *
- */
-
-
-import org.gudy.azureus2.core3.util.SHA1Simple;
-
-import com.aelitis.azureus.core.dht.router.*;
-
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String[]	args )
-	{
-		randomTest();
-	}
-	
-	protected static void
-	simpleTest()
-	{
-		DHTRouter	router = DHTRouterFactory.create( 1, 1,1,  new byte[]{ 0 }, null, com.aelitis.azureus.core.dht.impl.Test.getLogger());
-		
-		router.setAdapter( 
-			new DHTRouterAdapter()
-			{
-				public void requestAdd(DHTRouterContact contact) {
-					// TODO Auto-generated method stub
-					
-				}
-				public void requestLookup(byte[] id, String description) {
-					// TODO Auto-generated method stub
-					
-				}
-				public void requestPing(DHTRouterContact contact) {
-					// TODO Auto-generated method stub
-					
-				}
-			});
-		
-		byte[][]	node_ids ={ 
-				{ toByte( "11111111" ) },		
-				{ toByte( "01111111" ) },		
-				{ toByte( "00101111" ) },		
-				{ toByte( "00100111" ) },		
-				//{ toByte( "00111111" ) },		
-		};
-		
-		for (int i=0;i<node_ids.length;i++){
-						
-			router.contactKnown( node_ids[i], null );
-		}
-
-			// byte[]	node_id = new byte[]{ 1,1,1,1 }; //new SHA1Hasher().calculateHash( (""+i).getBytes());
-
-		router.print();
-	}
-	
-	protected static void
-	randomTest()
-	{
-		DHTRouter	router = DHTRouterFactory.create( 20, 5, 5, getSHA1(), null, com.aelitis.azureus.core.dht.impl.Test.getLogger());
-		
-		router.setAdapter( 
-				new DHTRouterAdapter()
-				{
-					public void requestAdd(DHTRouterContact contact) {
-						// TODO Auto-generated method stub
-						
-					}
-					public void requestLookup(byte[] id, String description) {
-						// TODO Auto-generated method stub
-						
-					}
-					public void requestPing(DHTRouterContact contact) {
-						// TODO Auto-generated method stub
-						
-					}
-				});
-		
-		for (int i=0;i<1000000;i++){
-			
-			byte[]	id = getSHA1();
-			
-			router.contactKnown( id, null);
-		}
-		
-		router.print();
-	}
-	
-	protected static long next_sha1_seed = 0;
-	
-	protected static byte[]
-	getSHA1()
-	{
-		return( new SHA1Simple().calculateHash( ( "" + ( next_sha1_seed++ )).getBytes()));
-	}
-	
-	protected static byte
-	toByte(
-		String	str )
-	{
-		int	res = 0;
-		
-		for (int i=0;i<8;i++){
-		
-			if ( str.charAt(i) == '1' ){
-				
-				res += 1<<(7-i);
-			}
-		}
-		
-		return((byte)res);
-	}
-}
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransport.java b/com/aelitis/azureus/core/dht/transport/DHTTransport.java
index c504141..462924e 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransport.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransport.java
@@ -32,12 +32,26 @@ import java.io.*;
 public interface 
 DHTTransport 
 {	
+	public static final byte GF_NONE				= 0x00;
+	public static final byte GF_DHT_SLEEPING		= 0x01;
+
 	public byte
 	getProtocolVersion();
 	
 	public int
 	getNetwork();
 
+	public boolean
+	isIPV6();
+	
+	public byte
+	getGenericFlags();
+	
+	public void
+	setGenericFlag(
+		byte		flag,
+		boolean		value );
+	
 		/**
 		 * Gives access to the node ID for this transport 
 		 * @return
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java b/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
index 13c26e4..8dadfd8 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportContact.java
@@ -82,6 +82,9 @@ DHTTransportContact
 	public boolean
 	isValid();
 	
+	public boolean
+	isSleeping();
+	
 	public void
 	sendPing(
 		DHTTransportReplyHandler	handler );
@@ -138,6 +141,10 @@ DHTTransportContact
 	public void
 	remove();
 	
+	public void
+	createNetworkPositions(
+		boolean		is_local );
+			
 	public DHTNetworkPosition[]
 	getNetworkPositions();
 	
diff --git a/com/aelitis/azureus/core/dht/transport/DHTTransportListener.java b/com/aelitis/azureus/core/dht/transport/DHTTransportListener.java
index 7d5fdb4..234e432 100644
--- a/com/aelitis/azureus/core/dht/transport/DHTTransportListener.java
+++ b/com/aelitis/azureus/core/dht/transport/DHTTransportListener.java
@@ -35,6 +35,9 @@ DHTTransportListener
 		DHTTransportContact	local_contact );
 	
 	public void
+	resetNetworkPositions();
+	
+	public void
 	currentAddress(
 		String		address );
 	
diff --git a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
index ecf6b53..e9270e6 100644
--- a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackContactImpl.java
@@ -96,6 +96,12 @@ DHTTransportLoopbackContactImpl
 		return( true );
 	}
 	
+	public boolean 
+	isSleeping() 
+	{
+		return( false );
+	}
+	
 	public int
 	getMaxFailForLiveCount()
 	{
@@ -236,6 +242,12 @@ DHTTransportLoopbackContactImpl
 		transport.removeContact( this );
 	}
 	
+	public void 
+	createNetworkPositions(
+		boolean is_local) 
+	{
+	}
+	
 	public DHTNetworkPosition[]
 	getNetworkPositions()
 	{
diff --git a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
index 542242b..6bd0fb4 100644
--- a/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/loopback/DHTTransportLoopbackImpl.java
@@ -58,6 +58,12 @@ DHTTransportLoopbackImpl
 		return( DHT.NW_MAIN );
 	}
 	
+	public boolean 
+	isIPV6() 
+	{
+		return( false );
+	}
+	
 	public static void
 	setLatency(
 		int	_latency )
@@ -197,6 +203,17 @@ DHTTransportLoopbackImpl
 		return( 0 );
 	}
 	
+	public byte 
+	getGenericFlags() 
+	{
+		return 0;
+	}
+	
+	public void 
+	setGenericFlag(
+		byte flag, boolean value) 
+	{
+	}
 	
 	public long 
 	getTimeout() 
diff --git a/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java b/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
index 5dc09c6..8f7bf27 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/DHTTransportUDP.java
@@ -45,6 +45,11 @@ DHTTransportUDP
 	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_4310					= 26;	// somewhere min has gone to 22
+	public static final byte PROTOCOL_VERSION_4407					= 50;	// cvs
+	public static final byte PROTOCOL_VERSION_4511					= 50;	// main
+	public static final byte PROTOCOL_VERSION_4600					= 50;	// min -> 50
+	public static final byte PROTOCOL_VERSION_4720					= 50;	
 
 	public static final byte PROTOCOL_VERSION_DIV_AND_CONT			= 6;
 	public static final byte PROTOCOL_VERSION_ANTI_SPOOF			= 7;
@@ -85,17 +90,22 @@ DHTTransportUDP
 	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
 	
+	public static final byte PROTOCOL_VERSION_RESTRICT_ID3			= 50;	// ip and port based restrictions 
+
+	public static final byte PROTOCOL_VERSION_VIVALDI_OPTIONAL		= 51;	// optional vivaldi
+	public static final byte PROTOCOL_VERSION_PACKET_FLAGS			= 51;	// flags field added to request and reply packets
+
 		// 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_REPLICATION_CONTROL3;
-	public static final byte PROTOCOL_VERSION_CVS					= PROTOCOL_VERSION_RESTRICT_ID_PORTS2Z;
+	public static final byte PROTOCOL_VERSION_MAIN					= PROTOCOL_VERSION_VIVALDI_OPTIONAL;
+	public static final byte PROTOCOL_VERSION_CVS					= PROTOCOL_VERSION_VIVALDI_OPTIONAL;
 
-	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;
+	public static final byte PROTOCOL_VERSION_MIN					= PROTOCOL_VERSION_RESTRICT_ID3;
+	public static final byte PROTOCOL_VERSION_MIN_CVS				= PROTOCOL_VERSION_RESTRICT_ID3;
 	
 	
 	
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 4e56bc3..f4ae0ae 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPContactImpl.java
@@ -28,6 +28,7 @@ import java.net.InetSocketAddress;
 import java.util.List;
 import java.util.Map;
 
+import org.gudy.azureus2.core3.util.AERunStateHandler;
 import org.gudy.azureus2.core3.util.AESemaphore;
 
 
@@ -53,7 +54,38 @@ DHTTransportUDPContactImpl
 	public static final int			NODE_STATUS_ROUTABLE	= 0x00000001;
 
 	static{
-		DHTNetworkPositionManager.registerProvider( new VivaldiPositionProvider());
+		AERunStateHandler.addListener(
+			new AERunStateHandler.RunStateChangeListener()
+			{
+				private VivaldiPositionProvider provider = null;
+				
+				public void 
+				runStateChanged(
+					long run_state )
+				{
+					synchronized( this ){
+						
+						if ( AERunStateHandler.isDHTSleeping()){
+							
+							if ( provider != null ){
+								
+								DHTNetworkPositionManager.unregisterProvider( provider );
+								
+								provider = null;
+							}
+						}else{
+						
+							if ( provider == null ){
+								
+								provider = new VivaldiPositionProvider();
+							
+								DHTNetworkPositionManager.registerProvider( provider );
+							}
+						}
+					}
+				}
+			},
+			true );
 	}
 	
 	private	DHTTransportUDPImpl		transport;
@@ -64,6 +96,8 @@ DHTTransportUDPContactImpl
 	private byte				protocol_version;
 	private int					instance_id;
 	private long				skew;
+	private byte				generic_flags;
+	
 	private int					random_id;
 	private int					node_status	= NODE_STATUS_UNKNOWN;
 		
@@ -77,7 +111,8 @@ DHTTransportUDPContactImpl
 		InetSocketAddress		_external_address,
 		byte					_protocol_version,
 		int						_instance_id,
-		long					_skew )
+		long					_skew,
+		byte					_generic_flags )
 	
 		throws DHTTransportException
 	{
@@ -91,16 +126,17 @@ DHTTransportUDPContactImpl
 			external_address	= transport_address;
 		}
 		
-		instance_id		=		 _instance_id;
+		instance_id		=		_instance_id;
 		skew			= 		_skew;
+		generic_flags	= 		_generic_flags;
 		
 		if ( 	transport_address == external_address ||
 				transport_address.getAddress().equals( external_address.getAddress())){
 
 			id = DHTUDPUtils.getNodeID( external_address, protocol_version );
 		}
-		
-		network_positions	= DHTNetworkPositionManager.createPositions( id==null?DHTUDPUtils.getBogusNodeID():id, _is_local );
+
+		createNetworkPositions( _is_local );
 	}
 	
 	public DHTTransport
@@ -161,6 +197,19 @@ DHTTransportUDPContactImpl
 					!transport.invalidExternalAddress( external_address.getAddress()));
 	}
 	
+	public boolean 
+	isSleeping() 
+	{
+		return(( generic_flags & DHTTransportUDP.GF_DHT_SLEEPING ) != 0 );
+	}
+	
+	protected void
+	setGenericFlags(
+		byte		flags )
+	{
+		generic_flags = flags;
+	}
+	
 	protected boolean
 	addressMatchesID()
 	{
@@ -409,6 +458,13 @@ DHTTransportUDPContactImpl
   		network_positions	= positions;
   	}
 	
+	public void
+	createNetworkPositions(
+		boolean  is_local )
+	{
+		network_positions	= DHTNetworkPositionManager.createPositions( id==null?DHTUDPUtils.getBogusNodeID():id, is_local );
+	}
+	
 	public DHTNetworkPosition[]
   	getNetworkPositions()
 	{
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 a013b8e..67202a6 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTTransportUDPImpl.java
@@ -27,7 +27,6 @@ import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.security.SecureRandom;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -56,6 +55,7 @@ import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionProvider;
+import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionProviderListener;
 import com.aelitis.azureus.core.dht.transport.*;
 import com.aelitis.azureus.core.dht.transport.udp.*;
 import com.aelitis.azureus.core.dht.transport.udp.impl.packethandler.DHTUDPPacketHandler;
@@ -147,6 +147,7 @@ DHTTransportUDPImpl
 
 	private boolean		bootstrap_node	= false;
 	
+	private byte		generic_flags	= DHTTransportUDP.GF_NONE;
 	
 	private static final int CONTACT_HISTORY_MAX 		= 32;
 	private static final int CONTACT_HISTORY_PING_SIZE	= 24;
@@ -292,9 +293,57 @@ DHTTransportUDPImpl
 		
 		InetSocketAddress	address = new InetSocketAddress( external_address, port );
 
+		DHTNetworkPositionManager.addProviderListener(
+			new DHTNetworkPositionProviderListener()
+			{
+				public void
+				providerAdded(
+					DHTNetworkPositionProvider		provider )
+				{
+					if ( local_contact != null ){
+						
+						local_contact.createNetworkPositions( true );
+						
+						try{
+							this_mon.enter();
+
+							for ( DHTTransportContact c: contact_history.values()){
+								
+								c.createNetworkPositions( false );
+							}
+
+							for ( DHTTransportContact c: routable_contact_history.values()){
+								
+								c.createNetworkPositions( false );
+							}
+						}finally{
+							
+							this_mon.exit();
+						}
+						
+						for (int i=0;i<listeners.size();i++){
+							
+							try{
+								((DHTTransportListener)listeners.get(i)).resetNetworkPositions();
+								
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+							}
+						}
+					}
+				}
+				
+				public void
+				providerRemoved(
+					DHTNetworkPositionProvider		provider )
+				{				
+				}
+			});
+		
 		logger.log( "Initial external address: " + address );
 		
-		local_contact = new DHTTransportUDPContactImpl( true, this, address, address, protocol_version, random.nextInt(), 0 );
+		local_contact = new DHTTransportUDPContactImpl( true, this, address, address, protocol_version, random.nextInt(), 0, (byte)0 );
 	}
 	
 	protected void
@@ -522,12 +571,42 @@ DHTTransportUDPImpl
 		return( network );
 	}
 	
+	public byte
+	getGenericFlags()
+	{
+		return( generic_flags );
+	}
+	
+	public void
+	setGenericFlag(
+		byte		flag,
+		boolean		value )
+	{
+		synchronized( this ){
+			
+			if ( value ){
+				
+				generic_flags |= flag;
+				
+			}else{
+				
+				generic_flags &= ~flag;
+			}
+		}
+	}
+	
+	public boolean 
+	isIPV6() 
+	{
+		return( v6 );
+	}
+	
 	public void
 	testInstanceIDChange()
 	
 		throws DHTTransportException
 	{
-		local_contact = new DHTTransportUDPContactImpl( true, this, local_contact.getTransportAddress(), local_contact.getExternalAddress(), protocol_version, random.nextInt(), 0);		
+		local_contact = new DHTTransportUDPContactImpl( true, this, local_contact.getTransportAddress(), local_contact.getExternalAddress(), protocol_version, random.nextInt(), 0, (byte)0 );		
 	}
 	
 	public void
@@ -545,7 +624,7 @@ DHTTransportUDPImpl
 		
 		InetSocketAddress	address = new InetSocketAddress( external_address, port );
 		
-		local_contact = new DHTTransportUDPContactImpl( true, this, address, address, protocol_version, local_contact.getInstanceID(), 0 );		
+		local_contact = new DHTTransportUDPContactImpl( true, this, address, address, protocol_version, local_contact.getInstanceID(), 0, (byte)0 );		
 
 		for (int i=0;i<listeners.size();i++){
 			
@@ -1124,7 +1203,7 @@ DHTTransportUDPImpl
 		InetSocketAddress	s_address = new InetSocketAddress( external_address, port );
 		
 		try{
-			local_contact = new DHTTransportUDPContactImpl( true, DHTTransportUDPImpl.this, s_address, s_address, protocol_version, random.nextInt(), 0);
+			local_contact = new DHTTransportUDPContactImpl( true, DHTTransportUDPImpl.this, s_address, s_address, protocol_version, random.nextInt(), 0, (byte)0 );
 	
 			logger.log( "External address changed: " + s_address );
 			
@@ -1168,7 +1247,7 @@ DHTTransportUDPImpl
 	{
 			// instance id of 0 means "unknown"
 		
-		DHTTransportUDPContactImpl	contact = new DHTTransportUDPContactImpl( false, this, _address, _address, _protocol_version, 0, 0 );
+		DHTTransportUDPContactImpl	contact = new DHTTransportUDPContactImpl( false, this, _address, _address, _protocol_version, 0, 0, (byte)0 );
 		
 		importContact( contact );
 
@@ -2169,7 +2248,7 @@ outer:
 							contact.setRandomID( reply.getRandomID());
 														
 							updateContactStatus( contact, reply.getNodeStatus(), false );
-							
+														
 							request_handler.setTransportEstimatedDHTSize( reply.getEstimatedDHTSize());
 							
 							stats.findNodeOK();
@@ -2542,9 +2621,11 @@ outer:
 		
 		if ( handler == null ){
 			
-			logger.log( "No transfer handler registered for key '" + ByteFormatter.encodeString(transfer_key) + "'" );
+			// can get a lot of these on startup so we'll downgrade to just ignoring
+			//logger.log( "No transfer handler registered for key '" + ByteFormatter.encodeString(transfer_key) + "'" );
+			//throw( new DHTTransportException( "No transfer handler registered for " + ByteFormatter.encodeString(transfer_key) ));
 			
-			throw( new DHTTransportException( "No transfer handler registered" ));
+			return( -1 );
 		}
 
 		if ( data == null ){
@@ -3371,7 +3452,8 @@ outer:
 						request.getOriginatorAddress(), 
 						request.getOriginatorVersion(),
 						request.getOriginatorInstanceID(),
-						request.getClockSkew());
+						request.getClockSkew(),
+						request.getGenericFlags());
 			
 			try{
 				checkAddress( originating_contact );
@@ -3430,7 +3512,8 @@ outer:
 								transport_address, 		// set originator address to transport
 								request.getOriginatorVersion(),
 								request.getOriginatorInstanceID(),
-								request.getClockSkew());
+								request.getClockSkew(),
+								request.getGenericFlags());
 
 				}else{
 					
@@ -3633,6 +3716,8 @@ outer:
 					
 					if ( bootstrap_node ){
 						
+							// log( originating_contact );
+						
 							// let bad originators through to aid bootstrapping with bad IP
 						
 						acceptable = bad_originator || Arrays.equals( find_request.getID(), originating_contact.getID());
@@ -3890,6 +3975,8 @@ outer:
 			DHTNetworkPositionManager.update( local_contact.getNetworkPositions(), remote_contact.getID(), remote_nps, (float)elapsed_time );						
 		}
 		
+		remote_contact.setGenericFlags( reply.getGenericFlags());
+		
 		if ( reply.getAction() == DHTUDPPacketHelper.ACT_REPLY_ERROR ){
 			
 			DHTUDPPacketReplyError	error = (DHTUDPPacketReplyError)reply;
@@ -4168,6 +4255,50 @@ outer:
 		}
 	}
 	
+	/*
+	private PrintWriter	contact_log;
+	private int			contact_log_entries;
+	private SimpleDateFormat	contact_log_format = new SimpleDateFormat( "dd/MM/yyyy HH:mm:ss");
+	{
+		contact_log_format.setTimeZone( TimeZone.getTimeZone( "UTC" ));
+	}
+	
+	protected void
+	log(
+		DHTTransportUDPContactImpl		contact )
+	{
+		if ( network == DHT.NW_MAIN ){
+			
+			synchronized( this ){
+		
+				try{
+					if ( contact_log == null ){
+						
+						contact_log = new PrintWriter( new FileWriter( new File( SystemProperties.getUserPath(), "contact_log" )));
+					}
+					
+					contact_log_entries++;
+					
+					InetSocketAddress address = contact.getAddress();
+					
+					contact_log.println( contact_log_format.format( new Date()) + ", " + address.getAddress().getHostAddress() + ", " + address.getPort());
+					
+					if ( contact_log_entries % 1000 == 0 ){
+						
+						System.out.println( "contact-log: " + contact_log_entries );
+						
+						contact_log.flush();
+					}
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
+		}
+	}
+	*/
+	
 	protected class
 	transferHandlerInterceptor
 		implements DHTTransportTransferHandler
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacket.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacket.java
index c73428e..31cb53f 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacket.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacket.java
@@ -24,10 +24,13 @@ package com.aelitis.azureus.core.dht.transport.udp.impl;
 
 public interface 
 DHTUDPPacket 
-{
+{	
 	public DHTTransportUDPImpl
 	getTransport();
 	
 	public byte
 	getProtocolVersion();
+	
+	public byte
+	getGenericFlags();
 }
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReply.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReply.java
index 3c80be9..f9f8586 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReply.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketReply.java
@@ -49,8 +49,8 @@ DHTUDPPacketReply
 		8 +		// con id
 		1 +		// ver
 		1 +		// net 
-		4;		// instance
-	
+		4 +		// instance
+		1;		// flags
 	
 	private DHTTransportUDPImpl 	transport;
 	
@@ -59,7 +59,7 @@ DHTUDPPacketReply
 	private byte	vendor_id	= DHTTransportUDP.VENDOR_ID_NONE;
 	private int		network;
 	private int		target_instance_id;
-	
+	private byte	flags;
 	private long	skew;
 		
 	private DHTNetworkPosition[]	network_positions;
@@ -81,6 +81,8 @@ DHTUDPPacketReply
 		
 		protocol_version			= _remote_contact.getProtocolVersion();
 		
+		//System.out.println( "reply to " + _remote_contact.getAddress() + ", proto=" + protocol_version );
+
 			// the target might be at a higher protocol version that us, so trim back if necessary
 			// as we obviously can't talk a higher version than what we are!
 	
@@ -92,6 +94,8 @@ DHTUDPPacketReply
 		target_instance_id	= _local_contact.getInstanceID();
 				
 		skew	= _remote_contact.getClockSkew();
+		
+		flags	= transport.getGenericFlags();
 	}
 	
 	protected
@@ -111,7 +115,9 @@ DHTUDPPacketReply
 		connection_id 	= is.readLong();
 		
 		protocol_version			= is.readByte();
-					
+				
+		//System.out.println( "reply prot=" + protocol_version );
+		
 		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_VENDOR_ID ){
 	
 			vendor_id	= is.readByte();
@@ -133,6 +139,11 @@ DHTUDPPacketReply
 		transport = network_handler.getTransport( this );
 
 		target_instance_id	= is.readInt();
+		
+		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_PACKET_FLAGS ){
+			
+			flags	= is.readByte();
+		}
 	}
 	
 	public DHTTransportUDPImpl
@@ -177,6 +188,12 @@ DHTUDPPacketReply
 		return( network );
 	}
 	
+	public byte
+	getGenericFlags()
+	{
+		return( flags );
+	}
+	
 	public void
 	setNetwork(
 		int		_network )
@@ -222,11 +239,16 @@ DHTUDPPacketReply
 		}
 		
 		os.writeInt( target_instance_id );
+		
+		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_PACKET_FLAGS ){
+
+			os.writeByte( flags );
+		}
 	}
 	
 	public String
 	getString()
 	{
-		return( super.getString() + ",[con="+connection_id+",prot=" + protocol_version + ",ven=" + vendor_id + ",net="+network+"]");
+		return( super.getString() + ",[con="+connection_id+",prot=" + protocol_version + ",ven=" + vendor_id + ",net="+network + ",fl=" + flags + "]");
 	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequest.java b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequest.java
index bfa3c23..f50248c 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequest.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPPacketRequest.java
@@ -64,6 +64,7 @@ DHTUDPPacketRequest
 	private long				originator_time;
 	private InetSocketAddress	originator_address;
 	private int					originator_instance_id;
+	private byte				flags;
 	
 	private long				skew;
 	
@@ -76,13 +77,15 @@ DHTUDPPacketRequest
 		DHTTransportUDPContactImpl		_remote_contact )
 	{
 		super( _type, _connection_id );
-		
+				
 		transport	= _transport;
 		
 			// serialisation constructor
 		
 		protocol_version		= _remote_contact.getProtocolVersion();		
 		
+		//System.out.println( "request to " + _remote_contact.getAddress() + ", proto=" + protocol_version );
+
 			// the target might be at a higher protocol version that us, so trim back if necessary
 			// as we obviously can't talk a higher version than what we are!
 		
@@ -94,6 +97,8 @@ DHTUDPPacketRequest
 		originator_address		= _local_contact.getExternalAddress();
 		originator_instance_id	= _local_contact.getInstanceID();
 		originator_time			= SystemTime.getCurrentTime();
+		
+		flags	= transport.getGenericFlags();
 	}
 	
 	protected
@@ -112,6 +117,8 @@ DHTUDPPacketRequest
 		
 		protocol_version	= is.readByte();
 		
+		//System.out.println( "request received prot=" + protocol_version );
+		
 		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_VENDOR_ID ){
 			
 			vendor_id	= is.readByte();			
@@ -165,6 +172,11 @@ DHTUDPPacketRequest
 		skew = SystemTime.getCurrentTime() - originator_time;
 		
 		transport.recordSkew( originator_address, skew );
+		
+		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_PACKET_FLAGS ){
+			
+			flags	= is.readByte();
+		}
 	}
 	
 	protected void
@@ -235,6 +247,11 @@ DHTUDPPacketRequest
 		os.writeInt( originator_instance_id );
 		
 		os.writeLong( originator_time );
+		
+		if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_PACKET_FLAGS ){
+
+			os.writeByte( flags );
+		}
 	}
 	
 	protected void
@@ -288,6 +305,12 @@ DHTUDPPacketRequest
 		network	= _network;
 	}
 	
+	public byte
+	getGenericFlags()
+	{
+		return( flags );
+	}
+	
 	protected byte
 	getOriginatorVersion()
 	{
@@ -316,6 +339,6 @@ DHTUDPPacketRequest
 	public String
 	getString()
 	{
-		return( super.getString() + ",[prot=" + protocol_version + ",ven=" + vendor_id + ",net="+network+",ov=" + originator_version + "]");
+		return( super.getString() + ",[prot=" + protocol_version + ",ven=" + vendor_id + ",net="+network+",ov=" + originator_version + ",fl=" + flags + "]");
 	}
 }
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 a5969ca..77cbe86 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/DHTUDPUtils.java
@@ -40,6 +40,7 @@ import com.aelitis.azureus.core.dht.DHT;
 import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPosition;
 import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager;
+import com.aelitis.azureus.core.dht.netcoords.vivaldi.ver1.VivaldiPositionFactory;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
 import com.aelitis.azureus.core.dht.transport.DHTTransportException;
 import com.aelitis.azureus.core.dht.transport.DHTTransportFullStats;
@@ -88,7 +89,38 @@ DHTUDPUtils
 			
 			String	key;
 			
-			if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_RESTRICT_ID_PORTS2 ){
+			if ( protocol_version >= DHTTransportUDP.PROTOCOL_VERSION_RESTRICT_ID3 ){
+				
+				byte[] bytes = ia.getAddress();
+				
+				if ( bytes.length == 4 ){
+					
+					//final long K0	= Long.MAX_VALUE;	
+					//final long K1	= Long.MAX_VALUE;	
+					
+						// restrictions suggested by UoW researchers as effective at reducing Sybil opportunity but 
+						// not so restrictive as to impact DHT performance
+					
+					final long K2	= 2500;
+					final long K3	= 50;
+					final long K4	= 5;
+
+					long	result = address.getPort() % K4;
+					
+					result = ((((long)bytes[3] << 8 ) &0x000000ff00L ) | result ) % K3;
+					result = ((((long)bytes[2] << 16 )&0x0000ff0000L ) | result ) % K2;
+					result = ((((long)bytes[1] << 24 )&0x00ff000000L ) | result ); // % K1;
+					result = ((((long)bytes[0] << 32 )&0xff00000000L ) | result ); // % K0;
+
+					key = String.valueOf( result );
+										
+				}else{
+
+						// stick with existing approach for IPv6 at the moment
+					
+					key = ia.getHostAddress() + ":" + ( address.getPort() % 8 );
+				}
+			}else 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)
@@ -389,7 +421,7 @@ DHTUDPUtils
 				
 		InetSocketAddress	external_address = deserialiseAddress( is );
 		
-		return( new DHTTransportUDPContactImpl( false, transport, external_address, external_address, version, 0, 0 ));
+		return( new DHTTransportUDPContactImpl( false, transport, external_address, external_address, version, 0, 0, (byte)0 ));
 	}
 	
 
@@ -686,8 +718,6 @@ DHTUDPUtils
 
 		if ( reply.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_GENERIC_NETPOS ){
 			
-			os.writeByte((byte)nps.length);
-			
 			boolean	v1_found = false;
 			
 			for (int i=0;i<nps.length;i++){
@@ -697,22 +727,44 @@ DHTUDPUtils
 				if ( np.getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1 ){
 					
 					v1_found	= true;
+					
+					break;
 				}
-				
-				os.writeByte( np.getPositionType());
-				os.writeByte( np.getSerialisedSize());
-				
-				np.serialise( os );
 			}
 			
 			if ( !v1_found ){
 				
-				Debug.out( "Vivaldi V1 missing" );
+				if ( reply.getProtocolVersion() < DHTTransportUDP.PROTOCOL_VERSION_VIVALDI_OPTIONAL ){
+					
+						// need to add one in for backward compatability
+					
+					DHTNetworkPosition np = VivaldiPositionFactory.createPosition( Float.NaN );
+					
+					DHTNetworkPosition[] new_nps = new DHTNetworkPosition[nps.length+1];
+					
+					System.arraycopy( nps, 0, new_nps, 0, nps.length );
+					
+					new_nps[ nps.length ] = np;
+					
+					nps = new_nps;
+				}
+			}
+			
+			os.writeByte((byte)nps.length);
+						
+			for (int i=0;i<nps.length;i++){
+					
+				DHTNetworkPosition	np = nps[i];
+				
+				os.writeByte( np.getPositionType());
+				os.writeByte( np.getSerialisedSize());
 				
-				throw( new IOException( "Vivaldi V1 missing" ));
+				np.serialise( os );
 			}
 		}else{
 			
+				// dead code these days 
+			
 			for (int i=0;i<nps.length;i++){
 				
 				if ( nps[i].getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1 ){
@@ -785,26 +837,11 @@ DHTUDPUtils
 			}
 		}else{
 			
+				// dead code these days 
+			
 			nps = new DHTNetworkPosition[]{ DHTNetworkPositionManager.deserialise( reply.getAddress().getAddress(), DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1, is )};	
 		}
-		
-		boolean	v1_found = false;
-		
-		for (int i=0;i<nps.length;i++){
-			
-			if ( nps[i].getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1 ){
 				
-				v1_found	= true;
-			}			
-		}
-		
-		if ( !v1_found ){
-			
-			// Debug.out( "Vivaldi V1 missing" );
-			
-			throw( new IOException( "Vivaldi V1 missing" ));
-		}
-		
 		reply.setNetworkPositions( nps );
 	}
 	
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java b/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java
deleted file mode 100644
index a9c5a85..0000000
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/Test.java
+++ /dev/null
@@ -1,407 +0,0 @@
-/*
- * 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.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.*;
-
-/**
- * @author parg
- *
- */
-
-public class 
-Test 
-	implements DHTTransportRequestHandler
-{
-	public static void
-	main(
-		String[]	args )
-	{
-		new Test();
-	}
-	
-	protected
-	Test()
-	{
-		try{
-			DHTTransport	udp1 = 
-				DHTTransportFactory.createUDP(
-					DHTTransportUDP.PROTOCOL_VERSION_MAIN, DHT.NW_MAIN, false,
-					null, null, 6881, 5, 3, 5000, 50, 25, false, false, com.aelitis.azureus.core.dht.impl.Test.getLogger());
-		
-			udp1.setRequestHandler( this );
-			
-			DHTTransport	udp2 = DHTTransportFactory.createUDP( 
-					DHTTransportUDP.PROTOCOL_VERSION_MAIN, DHT.NW_MAIN, false,
-					null, null, 6882, 5, 3, 5000, 50, 25, false, false, com.aelitis.azureus.core.dht.impl.Test.getLogger());
-		
-			udp2.setRequestHandler( this );
-
-			final DHTTransportUDPContact	c1 = (DHTTransportUDPContact)udp1.getLocalContact();
-			
-			for (int i=0;i<10;i++){
-				
-				final int f_i = i;
-				
-				c1.sendPing(
-					new DHTTransportReplyHandlerAdapter()
-					{
-						public void
-						pingReply(
-							DHTTransportContact contact )
-						{
-							System.out.println( "ping reply: " + f_i );
-						}
-						
-						public void
-						failed(
-							DHTTransportContact 	contact,
-							Throwable				error )
-						{
-							System.out.println( "ping failed" );
-						}
-					});
-			}
-	
-			c1.sendStore(
-					new DHTTransportReplyHandlerAdapter()
-					{
-						public void
-						storeReply(
-							DHTTransportContact contact,
-							byte[]				types )
-						{
-							System.out.println( "store reply" );
-						}
-						
-						public void
-						failed(
-							DHTTransportContact 	contact,
-							Throwable				error )
-						{
-							System.out.println( "store failed" );
-						}
-					},
-					new byte[][]{ new byte[23] },
-					new DHTTransportValue[][]{{
-						new DHTTransportValue()
-						{
-							public boolean
-							isLocal()
-							{
-								return( false );
-							}
-							
-							public long
-							getCreationTime()
-							{
-								return( 2 );
-							}
-							
-							public byte[]
-							getValue()
-							{
-								return( "sdsd".getBytes());
-							}
-							
-							public int
-							getVersion()
-							{
-								return( 0 );
-							}
-							
-							public DHTTransportContact
-							getOriginator()
-							{
-								return( c1 );
-							}
-							
-							public int
-							getFlags()
-							{
-								return(0);
-							}
-							
-							public int 
-							getLifeTimeHours() 
-							{
-								return 0;
-							}
-
-							public byte
-							getReplicationControl()
-							{
-								return 0;
-							}
-							
-							public byte 
-							getReplicationFactor() 
-							{
-								return 0;
-							}
-
-							public byte 
-							getReplicationFrequencyHours() 
-							{
-								return 0;
-							}
-							
-							public String
-							getString()
-							{
-								return( new String(getValue()));
-							}
-						}
-					}},
-					false );
-			
-			c1.sendFindNode(
-					new DHTTransportReplyHandlerAdapter()
-					{
-						public void
-						findNodeReply(
-							DHTTransportContact 	contact,
-							DHTTransportContact[] 	contacts )
-						{
-							System.out.println( "findNode reply" );
-						}
-						
-						public void
-						failed(
-							DHTTransportContact 	contact,
-							Throwable 				e )
-						{
-							System.out.println( "findNode failed" );
-						}
-					},
-					new byte[12]);
-			
-			System.out.println( "sending find value" );
-			
-			c1.sendFindValue(
-					new DHTTransportReplyHandlerAdapter()
-					{
-						public void
-						findValueReply(
-							DHTTransportContact 	contact,
-							DHTTransportContact[] 	contacts )
-						{
-							System.out.println( "findValue contacts reply" );
-						}
-						
-						public void
-						findValueReply(
-							DHTTransportContact 	contact,
-							DHTTransportValue[]		values,
-							byte					diversification_type,
-							boolean					more_to_come )
-						{
-							System.out.println( "findValue value reply" );
-						}
-						
-						public void
-						failed(
-							DHTTransportContact 	contact,
-							Throwable				error )
-						{
-							System.out.println( "findValue failed" );
-						}
-					},
-					new byte[3], 1, (byte)0 );
-			
-			System.out.println( "sending complete" );
-
-			Thread.sleep(1000000);
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	public void
-	pingRequest(
-		DHTTransportContact contact )
-	{
-		System.out.println( "TransportHandler: ping" );
-	}
-		
-	public void
-	keyBlockRequest(
-		DHTTransportContact contact,
-		byte[]				key_block_request,
-		byte[]				key_block_signature )
-	{
-		System.out.println( "TransportHandler: keyBlockRequest" );
-	}
-	
-	public DHTTransportStoreReply
-	storeRequest(
-		DHTTransportContact 	contact, 
-		final byte[][]			keys,
-		DHTTransportValue[][]	value_sets )
-	{
-		System.out.println( "TransportHandler: store" );
-		
-		return( 
-				new DHTTransportStoreReply()
-				{
-					public byte[]
-		        	getDiversificationTypes()
-					{
-						return( new byte[keys.length] );
-					}
-		        	
-		        	public boolean
-		        	blocked()
-		        	{
-		        		return( false );
-		        	}
-		        	
-		        	public byte[]
-		        	getBlockRequest()
-		        	{
-		        		return( null );
-		        	}
-		        	
-		        	public byte[]
-		        	getBlockSignature()
-		        	{
-		        		return( null );
-		        	}
-				});
-	}
-	
-	public DHTTransportQueryStoreReply 
-	queryStoreRequest(
-		DHTTransportContact 		contact,
-		int 						headerLen, 
-		List<Object[]>				keys) 
-	{
-		System.out.println( "TransportHandler: queryStore" );
-
-		return null;
-	}
-
-	public DHTTransportContact[]
-	findNodeRequest(
-		DHTTransportContact contact, 
-		byte[]				id )
-	{
-		System.out.println( "TransportHandler: findNode" );
-		
-		return(new DHTTransportContact[]{ contact });
-	}
-	
-	public DHTTransportFindValueReply
-	findValueRequest(
-		final DHTTransportContact contact, 
-		byte[]					key,
-		int						max_values,
-		byte					flags )
-	{
-		System.out.println( "TransportHandler: findValue" );
-		
-		return( 
-				new DHTTransportFindValueReply()
-				{
-					public boolean
-					hit()
-					{
-						return( false );
-					}
-					
-					public byte
-					getDiversificationType()
-					{
-						return( DHT.DT_NONE );
-					}
-					
-					public DHTTransportValue[]
-					getValues()
-					{
-						return( null );
-					}
-					
-					public DHTTransportContact[]
-					getContacts()
-					{
-						return( new DHTTransportContact[]{ contact } );
-					}
-					
-					public boolean
-					blocked()
-					{
-						return( false );
-					}
-					
-					public byte[]
-					getBlockedKey()
-					{
-						return( null );
-					}
-					
-					public byte[]
-					getBlockedSignature()
-					{
-						return( null );
-					}
-				});
-	}
-
-	public void
-	contactImported(
-		DHTTransportContact	contact )
-	{
-		
-	}
-	
-	public void
-	contactRemoved(
-		DHTTransportContact	contact )
-	{
-	}
-
-	public int
-	getTransportEstimatedDHTSize()
-	{
-		return(0);
-	}
-	
-	public void
-	setTransportEstimatedDHTSize(
-		int	size )
-	{
-	}
-	
-	public DHTTransportFullStats
-	statsRequest(
-		DHTTransportContact	contact )
-	{
-		return( null );
-	}
-}
diff --git a/com/aelitis/azureus/core/dht/transport/udp/impl/packethandler/DHTUDPPacketHandler.java b/com/aelitis/azureus/core/dht/transport/udp/impl/packethandler/DHTUDPPacketHandler.java
index 184ed28..ced5683 100644
--- a/com/aelitis/azureus/core/dht/transport/udp/impl/packethandler/DHTUDPPacketHandler.java
+++ b/com/aelitis/azureus/core/dht/transport/udp/impl/packethandler/DHTUDPPacketHandler.java
@@ -166,7 +166,7 @@ DHTUDPPacketHandler
 								
 							}else{
 								
-								Debug.out( "Non-matching network reply received" );
+								Debug.out( "Non-matching network reply received: expected=" + network + ", actual=" + reply.getNetwork());
 								
 								receiver.error( new DHTUDPPacketHandlerException( new Exception( "Non-matching network reply received" )));
 							}
diff --git a/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java b/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
index f0cd910..549b558 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/CacheFile.java
@@ -34,9 +34,10 @@ 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_PIECE_REORDER	= 3;
+	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 CT_PIECE_REORDER_COMPACT	= 4;
 
 	public static final int	CF_READ		= 1;
 	public static final int CF_WRITE	= 2;
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
index 94b2e6f..5a3f4a0 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileManagerImpl.java
@@ -73,9 +73,13 @@ CacheFileManagerImpl
 			
 			return( FMFile.FT_COMPACT );
 			
-		}else{
+		}else if ( cache_type == CacheFile.CT_PIECE_REORDER ){
 			
 			return( FMFile.FT_PIECE_REORDER );
+			
+		}else{
+			
+			return( FMFile.FT_PIECE_REORDER_COMPACT );
 		}
 	}
 	
@@ -91,9 +95,13 @@ CacheFileManagerImpl
 			
 			return( CacheFile.CT_COMPACT );
 			
-		}else{
+		}else if ( file_type == FMFile.FT_PIECE_REORDER ){
 			
 			return( CacheFile.CT_PIECE_REORDER );
+			
+		}else{
+			
+			return( CacheFile.CT_PIECE_REORDER_COMPACT );
 		}
 	}
 	
@@ -156,7 +164,7 @@ CacheFileManagerImpl
 		
 			// units are MB
 		
-		int		size			= 1024*1024*COConfigurationManager.getIntParameter( "diskmanager.perf.cache.size" );
+		long		size			= 1024L * 1024L * COConfigurationManager.getIntParameter( "diskmanager.perf.cache.size" );
 		
 			// units are KB
 		
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
index 677eae4..51a3c5e 100644
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
+++ b/com/aelitis/azureus/core/diskmanager/cache/impl/CacheFileWithCache.java
@@ -59,6 +59,10 @@ CacheFileWithCache
 		   		Object _o1, 
 				Object _o2)
 			{
+				if ( _o1 == _o2 ){
+					
+					return( 0 );
+				}
 					// entries in the cache should never overlap
 				
 				CacheEntry	o1 = (CacheEntry)_o1;
diff --git a/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java b/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java
deleted file mode 100644
index dfdc8b5..0000000
--- a/com/aelitis/azureus/core/diskmanager/cache/impl/Test.java
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
- * Created on 04-Aug-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.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.*;
-
-import com.aelitis.azureus.core.diskmanager.cache.*;
-
-/**
- * @author parg
- *
- */
-
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String	[]args )
-	{
-		System.setProperty("azureus.log.stdout","1");
-		
-		Logger.addListener(new ILogEventListener() {
-			public void log(LogEvent event) {
-				System.out.println(event.text);
-			}
-		});
-		
-		try{
-			CacheFileManagerImpl	manager = (CacheFileManagerImpl)CacheFileManagerFactory.getSingleton();
-			
-			//manager.initialise( false, 8*1024*1024 );
-	
-			//new Test().writeTest(manager);
-			
-			manager.initialise( true, true, true, 10*1024*1024, 1024 );
-
-			new Test().pieceReorderTest(manager);
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-	
-	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 )
-	{
-		try{
-			final File	f = new File("C:\\temp\\cachetest.dat" );
-			
-			f.delete();
-			
-			CacheFile	cf = manager.createFile(
-					new CacheFileOwner()
-					{
-						public String
-						getCacheFileOwnerName()
-						{
-							return( "file " + f.toString() );
-						}
-						
-						public TOTorrentFile
-						getCacheFileTorrentFile()
-						{
-							return( null );
-						}
-						public File 
-						getCacheFileControlFileDir() 
-						{
-							return null;
-						}
-   						public int
-						getCacheMode()
-						{
-							return( CacheFileOwner.CACHE_MODE_NORMAL );
-						}
-					},
-					f, CacheFile.CT_LINEAR );
-			
-			cf.setAccessMode( CacheFile.CF_WRITE );
-			
-			long	start = System.currentTimeMillis();
-			
-			int		loop	= 10000;
-			int		block	= 1*1024;
-			
-			for (int i=0;i<loop;i++){
-				
-				DirectByteBuffer	buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_OTHER, block);
-				
-				cf.writeAndHandoverBuffer( buffer, i*block);
-			}
-			
-			cf.close();
-			
-			long 	now = System.currentTimeMillis();
-			
-			long	total = loop*block;
-			
-			long	elapsed = now - start;
-			
-			System.out.println( "time = " + elapsed + ", speed = " + (total/elapsed));
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-	
-	public void
-	manualTest(
-		CacheFileManager	manager )
-	{
-		try{
-			final File	f = new File("C:\\temp\\cachetest.dat" );
-			
-			f.delete();
-			
-			CacheFile	cf = manager.createFile(
-					new CacheFileOwner()
-					{
-						public String
-						getCacheFileOwnerName()
-						{
-							return( "file " + f.toString() );
-						}
-						
-						public TOTorrentFile
-						getCacheFileTorrentFile()
-						{
-							return( null );
-						}
-						public File 
-						getCacheFileControlFileDir() 
-						{
-							return null;
-						}
-   						public int
-						getCacheMode()
-						{
-							return( CacheFileOwner.CACHE_MODE_NORMAL );
-						}
-					},
-					f, CacheFile.CT_LINEAR );
-			DirectByteBuffer	write_buffer1 = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_OTHER,512);
-			DirectByteBuffer	write_buffer2 = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_OTHER,512);
-			DirectByteBuffer	write_buffer3 = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_OTHER,512);
-			
-			cf.writeAndHandoverBuffer( write_buffer2, 512 );
-				
-			cf.flushCache();
-			
-			cf.writeAndHandoverBuffer( write_buffer3, 1024 );
-			cf.writeAndHandoverBuffer( write_buffer1, 0 );
-			
-			cf.flushCache();
-			
-			write_buffer1 = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_OTHER,512);
-			cf.writeAndHandoverBuffer( write_buffer1, 0 );
-
-			cf.flushCache();
-				
-			cf.close();
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-	
-	public void
-	randomTest(
-		CacheFileManager	manager )
-	{
-		try{			
-			CacheFile[]	files = new CacheFile[3];
-			
-			byte[][]	file_data	= new byte[3][];
-			
-			for (int i=0;i<files.length;i++){
-				
-				final	int f_i = i;
-			
-				file_data[i] = new byte[randomInt(200000)];
-				
-				files[i] = manager.createFile(
-					new CacheFileOwner()
-					{
-						public String
-						getCacheFileOwnerName()
-						{
-							return( "file" + f_i );
-						}
-						
-						public TOTorrentFile
-						getCacheFileTorrentFile()
-						{
-							return( null );
-						}
-						public File 
-						getCacheFileControlFileDir() 
-						{
-							return null;
-						}
-   						public int
-						getCacheMode()
-						{
-							return( CacheFileOwner.CACHE_MODE_NORMAL );
-						}
-					},
-					new File( "C:\\temp\\cachetest" + i + ".dat" ), CacheFile.CT_LINEAR);
-				
-				files[i].setAccessMode( CacheFile.CF_WRITE );
-				
-				DirectByteBuffer bb = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_OTHER,file_data[i].length);
-				
-				bb.put( DirectByteBuffer.SS_CACHE, file_data[i]);
-				
-				bb.position(DirectByteBuffer.SS_CACHE, 0);
-				
-				files[i].write(bb,0);
-			}
-			
-			int	quanitize_to					= 100;
-			int quanitize_to_max_consec_write	= 1;
-			int quanitize_to_max_consec_read	= 3;
-			
-			for (int x=0;x<10000000;x++){
-				
-				int	file_index = randomInt(files.length);
-				
-				CacheFile	cf = files[file_index];
-				
-				byte[]	bytes = file_data[ file_index ];
-				
-				
-				int	p1 = randomInt( bytes.length );
-				int p2 = randomInt( bytes.length );
-				
-				p1 = (p1/quanitize_to)*quanitize_to;
-				p2 = (p2/quanitize_to)*quanitize_to;
-				
-				if ( p1 == p2 ){
-					
-					continue;
-				}
-				
-				int start 	= Math.min(p1,p2);
-				int len	 	= Math.max(p1,p2) - start;
-				
-				int	function = randomInt(100);
-				
-				if ( function < 30){
-					
-					if ( len > quanitize_to*quanitize_to_max_consec_read ){
-						
-						len = quanitize_to*quanitize_to_max_consec_read;
-					}
-					
-					DirectByteBuffer	buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_OTHER,len );
-					
-					System.out.println( "read:" + start + "/" + len );
-					
-					cf.read( buffer, start, CacheFile.CP_READ_CACHE );
-					
-					buffer.position(DirectByteBuffer.SS_CACHE, 0);
-					
-					byte[]	data_read = new byte[len];
-					
-					buffer.get( DirectByteBuffer.SS_CACHE, data_read );
-					
-					for (int i=0;i<data_read.length;i++){
-						
-						if ( data_read[i] != bytes[ i+start ]){
-							
-							throw( new Exception( "data read mismatch" ));
-						}
-					}
-					
-					buffer.returnToPool();
-					
-				}else if ( function < 80 ){
-					if ( len > quanitize_to*quanitize_to_max_consec_write ){
-						
-						len = quanitize_to*quanitize_to_max_consec_write;
-					}
-					
-					System.out.println( "write:" + start + "/" + len );
-					
-					DirectByteBuffer	buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_OTHER,len );
-					
-					for (int i=0;i<len;i++){
-						
-						bytes[start+i] = (byte)randomInt(256);
-						
-						buffer.put( DirectByteBuffer.SS_CACHE, bytes[start+i]);
-					}
-					
-					buffer.position(DirectByteBuffer.SS_CACHE, 0);
-					
-					cf.writeAndHandoverBuffer( buffer, start );
-					
-				}else if ( function < 90 ){
-					
-					cf.flushCache();
-					
-				}else if ( function < 91 ){
-					
-					cf.clearCache();
-					
-					//System.out.println( "closing file" );
-					
-					//cf.close();
-				}
-			}
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-	
-	static int
-	randomInt(
-		int	num )
-	{
-		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 1e9853e..18f5b9d 100644
--- a/com/aelitis/azureus/core/diskmanager/file/FMFile.java
+++ b/com/aelitis/azureus/core/diskmanager/file/FMFile.java
@@ -34,9 +34,10 @@ 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_PIECE_REORDER	= 3;
+	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	FT_PIECE_REORDER_COMPACT	= 4;
 	
 	public static final int	FM_READ		= 1;
 	public static final int FM_WRITE	= 2;
diff --git a/com/aelitis/azureus/core/diskmanager/file/FMFileManagerException.java b/com/aelitis/azureus/core/diskmanager/file/FMFileManagerException.java
index 6bcfec8..5ab7966 100644
--- a/com/aelitis/azureus/core/diskmanager/file/FMFileManagerException.java
+++ b/com/aelitis/azureus/core/diskmanager/file/FMFileManagerException.java
@@ -30,6 +30,9 @@ public class
 FMFileManagerException
 	extends Exception
 {
+	private boolean recoverable = true;
+	
+	
 	public
 	FMFileManagerException(
 		String		str )
@@ -44,4 +47,17 @@ FMFileManagerException
 	{
 		super( str, cause );
 	}
+	
+	public void
+	setRecoverable(
+		boolean		_recoverable )
+	{
+		recoverable	= _recoverable;
+	}
+	
+	public boolean
+	isRecoverable()
+	{
+		return( recoverable );
+	}
 }
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
index a24b9c8..872ca85 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccess.java
@@ -26,6 +26,7 @@ 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 
@@ -70,6 +71,10 @@ FMFileAccess
 	
 		throws FMFileManagerException;
 	
+	public boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number );
+	
 	public void
 	setPieceComplete(
 		RandomAccessFile	raf,
@@ -77,6 +82,9 @@ FMFileAccess
 		DirectByteBuffer	piece_data )
 	
 		throws FMFileManagerException;
+	 
+	public FMFileImpl
+	getFile();
 	
 	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 d2bde8c..26a4576 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessCompact.java
@@ -33,6 +33,7 @@ import org.gudy.azureus2.core3.util.Debug;
 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 
@@ -469,6 +470,13 @@ FMFileAccessCompact
 		writeState();
 	}
 	
+	public boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number )
+	{
+		return( false );
+	}
+	
 	public void
 	setPieceComplete(
 		RandomAccessFile	raf,
@@ -530,6 +538,12 @@ FMFileAccessCompact
 		}
 	}
 	
+	public FMFileImpl 
+	getFile()
+	{
+		return( delegate.getFile());
+	}
+	
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
index e009129..576e5a3 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessController.java
@@ -40,12 +40,20 @@ FMFileAccessController
 	implements FMFileAccess
 {
 	private static final String REORDER_SUFFIX = ".2";
+
+	private static final boolean TEST_PIECE_REORDER = System.getProperty( "azureus.file.piece.reorder.force", "0" ).equals( "1" );
 	
+	static{
+		if ( TEST_PIECE_REORDER ){
+			
+			Debug.out( "*** Piece reordering storage forced ***" );
+		}
+	}
 	private FMFileImpl	owner;
 	
 	private int		type		= FMFile.FT_LINEAR;
 	
-	private File	controlPath;
+	private File	control_dir;
 	private String	controlFileName;
 	
 	private FMFileAccess	file_access;
@@ -57,7 +65,10 @@ FMFileAccessController
 	
 		throws FMFileManagerException
 	{
-		// _target_type = FMFile.FT_PIECE_REORDER;
+		if ( TEST_PIECE_REORDER ){
+	
+			_target_type = FMFile.FT_PIECE_REORDER;
+		}
 		
 		owner		= _file;
 		
@@ -70,7 +81,7 @@ FMFileAccessController
 	
 		setControlFile();
 	
-		if ( controlPath == null ){
+		if ( control_dir == null ){
 			
 			// Debug.out( "No control file" ); in optimised environments we don't support compact and return null here
 			
@@ -85,19 +96,29 @@ FMFileAccessController
 
 		}else{
 		
-			if ( new File( controlPath, controlFileName ).exists()){
+			if ( new File( control_dir, controlFileName ).exists()){
 				
 				type = FMFile.FT_COMPACT;
 				
-			}else if ( new File( controlPath, controlFileName + REORDER_SUFFIX ).exists()){
+			}else if ( new File( control_dir, controlFileName + REORDER_SUFFIX ).exists()){
 			
-				type = FMFile.FT_PIECE_REORDER;
+				type = _target_type==FMFile.FT_PIECE_REORDER?FMFile.FT_PIECE_REORDER:FMFile.FT_PIECE_REORDER_COMPACT;
 				
 			}else{
 				
-				if ( _target_type == FMFile.FT_PIECE_REORDER && !owner.getLinkedFile().exists()){
+				if ((_target_type == FMFile.FT_PIECE_REORDER || _target_type == FMFile.FT_PIECE_REORDER_COMPACT )){
+					
+					File	target_file = owner.getLinkedFile();
+					
+					if ( target_file.exists()){
+					
+						FMFileAccessPieceReorderer.recoverConfig( 
+							owner.getOwner().getTorrentFile(),
+							target_file, 
+							new File( control_dir, controlFileName + REORDER_SUFFIX ));
+					}
 					
-					type = FMFile.FT_PIECE_REORDER;
+					type = _target_type;
 					
 				}else{
 					
@@ -114,7 +135,7 @@ FMFileAccessController
 				file_access = 
 					new FMFileAccessCompact(
 							owner.getOwner().getTorrentFile(),
-							controlPath,
+							control_dir,
 							controlFileName,  
 							new FMFileAccessLinear( owner ));
 			}else{
@@ -122,15 +143,12 @@ FMFileAccessController
 				file_access = 
 					new FMFileAccessPieceReorderer(
 							owner.getOwner().getTorrentFile(),
-							controlPath,
+							control_dir,
 							controlFileName + REORDER_SUFFIX,  
 							new FMFileAccessLinear( owner ));
 			}
-			
-			if ( type != _target_type ){
-				
-				convert( _target_type );
-			}
+							
+			convert( _target_type );
 		}
 	}
 	
@@ -139,9 +157,23 @@ FMFileAccessController
 		int					target_type )
 	
 		throws FMFileManagerException
-	{
+	{	
+		if ( type == target_type ){
+			
+			return;
+		}
+		
 		if ( type == FMFile.FT_PIECE_REORDER || target_type == FMFile.FT_PIECE_REORDER ){
 			
+			if ( target_type == FMFile.FT_PIECE_REORDER_COMPACT || type == FMFile.FT_PIECE_REORDER_COMPACT ){
+				
+					// these two access modes are in fact identical at the moment
+				
+				type = target_type;
+				
+				return;
+			}
+			
 			throw( new FMFileManagerException( "Conversion to/from piece-reorder not supported" ));
 		}
 		
@@ -161,7 +193,7 @@ FMFileAccessController
 			}else{
 				
 				target_access = new FMFileAccessCompact(
-										owner.getOwner().getTorrentFile(),controlPath,
+										owner.getOwner().getTorrentFile(),control_dir,
 										controlFileName,  
 										new FMFileAccessLinear( owner ));
 			}
@@ -297,7 +329,7 @@ FMFileAccessController
 				
 				if ( type == FMFile.FT_LINEAR ){
 					
-					new File(controlPath,controlFileName).delete();	
+					new File(control_dir,controlFileName).delete();	
 				}
 			}
 		}
@@ -311,7 +343,7 @@ FMFileAccessController
 		if ( tf == null ){
 
 			controlFileName = null;
-			controlPath = null;
+			control_dir = null;
 		}
 		
 		TOTorrent	torrent = tf.getTorrent();
@@ -335,11 +367,11 @@ FMFileAccessController
 			Debug.out("File '" + owner.getName() + "' not found in torrent!" );
 			
 			controlFileName = null;
-			controlPath 	= null;
+			control_dir 	= null;
 			
 		}else{
 			
-			controlPath 	= owner.getOwner().getControlFileDir( );
+			control_dir 	= owner.getOwner().getControlFileDir( );
 			controlFileName =  StringInterner.intern("fmfile" + file_index + ".dat");
 		}
 	}
@@ -350,12 +382,7 @@ FMFileAccessController
 		int					new_type )
 	
 		throws FMFileManagerException
-	{
-		if ( new_type == type ){
-			
-			return;
-		}
-		
+	{		
 		convert( new_type );
 	}
 	
@@ -395,6 +422,13 @@ FMFileAccessController
 		file_access.setLength( raf, length );
 	}
 	
+	public boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number )
+	{
+		return( file_access.isPieceCompleteProcessingNeeded( piece_number ));
+	}
+	
 	public void
 	setPieceComplete(
 		RandomAccessFile	raf,
@@ -436,6 +470,12 @@ FMFileAccessController
 		file_access.flush();
 	}
 	
+	public FMFileImpl 
+	getFile() 
+	{
+		return( owner );
+	}
+	
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
index 06663c2..d94a53d 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessLinear.java
@@ -25,14 +25,15 @@ package com.aelitis.azureus.core.diskmanager.file.impl;
 import java.io.IOException;
 import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
 
 import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.core3.util.SystemTime;
 
-import com.aelitis.azureus.core.diskmanager.file.FMFile;
 import com.aelitis.azureus.core.diskmanager.file.FMFileManagerException;
 
 public class 
@@ -47,6 +48,8 @@ FMFileAccessLinear
 	
 	private static final boolean	DEBUG			= true;
 	private static final boolean	DEBUG_VERBOSE	= false;
+	
+	private static final boolean USE_MMAP = System.getProperty("azureus.io.usemmap","false") == "true";
 
 	private FMFileImpl		owner;
 	
@@ -99,6 +102,13 @@ FMFileAccessLinear
 		}
 	}
 	
+	public boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number )
+	{
+		return( false );
+	}
+	
 	public void
 	setPieceComplete(
 		RandomAccessFile	raf,
@@ -134,12 +144,19 @@ FMFileAccessLinear
 		AEThread2.setDebug( owner );
 		
 		try{
-			fc.position(offset);
-			
-			while (fc.position() < fc.size() && buffer.hasRemaining(DirectByteBuffer.SS_FILE)){
-				
-				buffer.read(DirectByteBuffer.SS_FILE,fc);
+			if(USE_MMAP)
+			{
+				long remainingInFile = fc.size()-offset;
+				long remainingInTargetBuffer = buffer.remaining(DirectByteBuffer.SS_FILE);
+				MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, offset, Math.min(remainingInFile,remainingInTargetBuffer));
+				buffer.put(DirectByteBuffer.SS_FILE, buf);
+			} else {
+				fc.position(offset);
+				while (fc.position() < fc.size() && buffer.hasRemaining(DirectByteBuffer.SS_FILE))
+					buffer.read(DirectByteBuffer.SS_FILE,fc);				
 			}
+
+			
 			
 		}catch ( Exception e ){
 			
@@ -173,76 +190,77 @@ FMFileAccessLinear
 		
 		AEThread2.setDebug( owner );
 		
-		int[]	original_positions = null;
+		int[]	original_positions = new int[buffers.length];
 		
 		long read_start = SystemTime.getHighPrecisionCounter();
 		
-		try{			
-			fc.position(offset);
-			
-			ByteBuffer[]	bbs = new ByteBuffer[buffers.length];
-			
-			original_positions = new int[buffers.length];
-
-			ByteBuffer	last_bb	= null;
-			
-			for (int i=0;i<bbs.length;i++){
+		try{
+			if(USE_MMAP)
+			{
 				
-				ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
+				long size = 0;
+				for(int i=0;i<buffers.length;i++)
+				{
+					size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
+					original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
+				}
+					
+				size = Math.min(size, fc.size()-offset);
+				MappedByteBuffer buf = fc.map(MapMode.READ_ONLY, offset, size);
+				for(DirectByteBuffer b : buffers)
+				{
+					buf.limit(buf.position()+b.remaining(DirectByteBuffer.SS_FILE));
+					b.put(DirectByteBuffer.SS_FILE, buf);
+				}
+					
 				
-				int	pos = original_positions[i] = bb.position();
+			} else {
 				
-				if ( pos != bb.limit()){
-					
-					last_bb	= bbs[i];
+				fc.position(offset);
+				ByteBuffer[]	bbs = new ByteBuffer[buffers.length];
+				
+				ByteBuffer	last_bb	= null;
+				for (int i=0;i<bbs.length;i++){
+					ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
+					int	pos = original_positions[i] = bb.position();
+					if ( pos != bb.limit()){
+						last_bb	= bbs[i];
+					}
 				}
-			}
-			
-			if ( last_bb != null ){
-									
-				int		loop			= 0;
 				
-					// we sometimes read off the end of the file (when rechecking) so
-					// bail out if we've completed the read or got to file end
-					// a "better" fix would be to prevent the over-read in the first
-					// place, but hey, we're just about to release and there may be other
-					// instances of this...
-
-				while ( fc.position() < fc.size() && last_bb.hasRemaining()){
+				if ( last_bb != null ){
+					int		loop			= 0;
 					
-					long	read = fc.read( bbs );
-									
-					if ( read > 0 ){
-						
-						loop	= 0;
-						
-					}else{
-					
-						loop++;
-						
-						if ( loop == READ_RETRY_LIMIT ){
-							
-							Debug.out( "FMFile::read: zero length read - abandoning" );
-						
-							throw( new FMFileManagerException( "read fails: retry limit exceeded"));
-							
+						// we sometimes read off the end of the file (when rechecking) so
+						// bail out if we've completed the read or got to file end
+						// a "better" fix would be to prevent the over-read in the first
+						// place, but hey, we're just about to release and there may be other
+						// instances of this...
+
+					while ( fc.position() < fc.size() && last_bb.hasRemaining()){
+						long	read = fc.read( bbs );
+						if ( read > 0 ){
+							loop	= 0;
 						}else{
-							
-							if ( DEBUG_VERBOSE ){
-								
-								Debug.out( "FMFile::read: zero length read - retrying" );
+							loop++;
+							if ( loop == READ_RETRY_LIMIT ){
+								Debug.out( "FMFile::read: zero length read - abandoning" );
+								throw( new FMFileManagerException( "read fails: retry limit exceeded"));
 							}
-							
+							if ( DEBUG_VERBOSE )
+								Debug.out( "FMFile::read: zero length read - retrying" );
+
 							try{
 								Thread.sleep( READ_RETRY_DELAY*loop );
-								
 							}catch( InterruptedException e ){
-								
 								throw( new FMFileManagerException( "read fails: interrupted" ));
 							}
-						}
-					}						
+							
+						}						
+					}
 				}
+
+				
 			}
 		}catch ( Throwable e ){
 			
@@ -290,7 +308,6 @@ FMFileAccessLinear
 		throws FMFileManagerException
 	{
 		if ( raf == null){
-			
 			throw( new FMFileManagerException( "write fails: raf is null" ));
 		}
     
@@ -305,114 +322,101 @@ FMFileAccessLinear
 
 		AEThread2.setDebug( owner );
 		
-		int[]	original_positions = null;
+		int[]	original_positions = new int[buffers.length];
 
 		try{
-
-			long	expected_write 	= 0;
-			long	actual_write	= 0;
-			boolean	partial_write	= false;
 			
-			if ( DEBUG ){
-			
-				for (int i=0;i<buffers.length;i++){
-					
-					expected_write += buffers[i].limit(DirectByteBuffer.SS_FILE) - buffers[i].position(DirectByteBuffer.SS_FILE);
+			if(USE_MMAP) {
+				long size = 0;
+				for(int i=0;i<buffers.length;i++)
+				{
+					size += buffers[i].remaining(DirectByteBuffer.SS_FILE);
+					original_positions[i] = buffers[i].position(DirectByteBuffer.SS_FILE);
 				}
-			}
-			
-			fc.position( position );
-								
-			ByteBuffer[]	bbs = new ByteBuffer[buffers.length];
-			
-			original_positions = new int[buffers.length];
-
-			ByteBuffer	last_bb	= null;
-			
-			for (int i=0;i<bbs.length;i++){
 				
-				ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
+				if(position+size > fc.size())
+				{
+					fc.position(position+size-1);
+					fc.write(ByteBuffer.allocate(1));
+					fc.force(true);
+				}
+					
+				MappedByteBuffer buf = fc.map(MapMode.READ_WRITE, position, size);
+				for(DirectByteBuffer b : buffers)
+					buf.put(b.getBuffer(DirectByteBuffer.SS_FILE));
+				buf.force();
+			} else {
+				long	expected_write 	= 0;
+				long	actual_write	= 0;
+				boolean	partial_write	= false;
 				
-				int	pos = original_positions[i] = bb.position();
+				if ( DEBUG ){
+					for (int i=0;i<buffers.length;i++){
+						expected_write += buffers[i].limit(DirectByteBuffer.SS_FILE) - buffers[i].position(DirectByteBuffer.SS_FILE);
+					}
+				}
 				
-				if ( pos != bb.limit()){
-					
-					last_bb	= bbs[i];
+				fc.position( position );
+				ByteBuffer[]	bbs = new ByteBuffer[buffers.length];
+
+
+				ByteBuffer	last_bb	= null;
+				for (int i=0;i<bbs.length;i++){
+					ByteBuffer bb = bbs[i] = buffers[i].getBuffer(DirectByteBuffer.SS_FILE);
+					int	pos = original_positions[i] = bb.position();
+					if ( pos != bb.limit()){
+						last_bb	= bbs[i];
+					}
 				}
-			}
-			
-			if ( last_bb != null ){
-									  
-				int		loop			= 0;
 				
-				while( last_bb.position() != last_bb.limit()){
-					
-					long	written = fc.write( bbs );
-					
-					actual_write	+= written;
+				if ( last_bb != null ){
+					int loop = 0;
 					
-					if ( written > 0 ){
+					while( last_bb.position() != last_bb.limit()){
+						long written = fc.write( bbs );
+						actual_write += written;
 						
-						loop	= 0;
-						
-						if ( DEBUG ){
-							
-							if ( last_bb.position() != last_bb.limit()){
-							
-								partial_write	= true;
-								
-								if ( DEBUG_VERBOSE ){
-									
-									Debug.out( "FMFile::write: **** partial write **** this = " + written + ", total = " + actual_write + ", target = " + expected_write );
+						if ( written > 0 ){
+							loop	= 0;
+							if ( DEBUG ){
+								if ( last_bb.position() != last_bb.limit()){
+									partial_write	= true;
+									if ( DEBUG_VERBOSE ){
+										Debug.out( "FMFile::write: **** partial write **** this = " + written + ", total = " + actual_write + ", target = " + expected_write );
+									}
 								}
 							}
-						}
-						
-					}else{
-					
-						loop++;
-						
-						if ( loop == WRITE_RETRY_LIMIT ){
-							
-							Debug.out( "FMFile::write: zero length write - abandoning" );
-						
-							throw( new FMFileManagerException( "write fails: retry limit exceeded"));
 							
 						}else{
-							
-							if ( DEBUG_VERBOSE ){
+							loop++;
+							if ( loop == WRITE_RETRY_LIMIT ){
+								Debug.out( "FMFile::write: zero length write - abandoning" );
+								throw( new FMFileManagerException( "write fails: retry limit exceeded"));
+							}
 								
+							if ( DEBUG_VERBOSE )
 								Debug.out( "FMFile::write: zero length write - retrying" );
-							}
 							
 							try{
 								Thread.sleep( WRITE_RETRY_DELAY*loop );
-								
 							}catch( InterruptedException e ){
-								
 								throw( new FMFileManagerException( "write fails: interrupted" ));
 							}
-						}
-					}						
+						}						
+					}
 				}
-			}
-			
-			if ( DEBUG ){
-
-				if ( expected_write != actual_write ){
-					
-					Debug.out( "FMFile::write: **** partial write **** failed: expected = " + expected_write + ", actual = " + actual_write );
-
-					throw( new FMFileManagerException( "write fails: expected write/actual write mismatch" ));
 				
-				}else{
-					
-					if ( partial_write && DEBUG_VERBOSE ){
-						
-						Debug.out( "FMFile::write: **** partial write **** completed ok" );
+				if ( DEBUG ){
+					if ( expected_write != actual_write ){
+						Debug.out( "FMFile::write: **** partial write **** failed: expected = " + expected_write + ", actual = " + actual_write );
+						throw( new FMFileManagerException( "write fails: expected write/actual write mismatch" ));
 					}
+					if ( partial_write && DEBUG_VERBOSE )
+						Debug.out( "FMFile::write: **** partial write **** completed ok" );
 				}
+				
 			}
+
 			
 		}catch ( Throwable e ){
 				
@@ -442,6 +446,12 @@ FMFileAccessLinear
 		// no state to flush
 	}
 	
+	public FMFileImpl 
+	getFile() 
+	{
+		return( owner );
+	}
+	
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java
index 4f1a019..8be2663 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileAccessPieceReorderer.java
@@ -205,6 +205,47 @@ FMFileAccessPieceReorderer
 				readConfig();
 			}
 			
+			try{
+					// to cope with add-for-seeding mixed with the way the core handles move-to directory discovery we
+					// also need to have recovery code in this branch to deal with the situation where the file was initially
+					// opened pointing at a non-existant file and therefore missed the normal recovery path
+				
+				if ( current_length == 0 && next_piece_index == 1 ){
+					
+					long physical_length = raf.length();
+			
+					if ( physical_length > current_length ){
+					
+						long max_length = first_piece_length + (num_pieces-2)*piece_size + last_piece_length;
+					
+						physical_length = Math.min( physical_length, max_length );
+					
+						if ( physical_length > current_length ){
+						
+							current_length = physical_length;
+						
+							int	piece_count = (int)(( current_length + piece_size - 1 )/piece_size) + 1;
+						
+							if ( piece_count > num_pieces ){
+								
+								piece_count = num_pieces;
+							}
+						
+							for ( int i=1;i<piece_count;i++){
+																
+								piece_map[i] 			= i;
+								piece_reverse_map[i]	= i;
+							}
+							
+							next_piece_index = piece_count;
+							
+							setDirty();
+						}
+					}
+				}
+			}catch( IOException e ){
+			}
+			
 			return( current_length );
 			
 		}else{
@@ -268,7 +309,7 @@ FMFileAccessPieceReorderer
 			
 		}else{
 			
-			return( first_piece_length + ((index-1)*piece_size ));
+			return( first_piece_length + ((index-1)*(long)piece_size ));
 		}
 	}
 
@@ -415,7 +456,22 @@ FMFileAccessPieceReorderer
 						
 						int	rem = bb.remaining();
 						
-						bb.put( new byte[rem] );
+						if ( rem > 0 ){
+						
+							bb.put( new byte[rem] );
+
+								// not great this... to obey the normal file access semantics reads are
+								// never partial (normally we'd extend the file to accomodate the read but
+								// in the case of re-order access we don't want to do this when hash checking
+								// a file. The issue is in the unlikely case where our padding happens to
+								// match the real file contents and results in a piece hash check succeeding
+								// even though the data doesn't actually exist on disk... So I've added this 
+								// flag to cause hash checking to always fail if the resulting data isn't 'real'
+								// this of course relies on this buffer being passed back to the checking process
+								// intact, which is the case currently during rechecks...
+							
+							buffer.setFlag( DirectByteBuffer.FL_CONTAINS_TRANSIENT_DATA );
+						}
 					}
 				}else{
 				
@@ -483,6 +539,71 @@ FMFileAccessPieceReorderer
 		}
 	}
 	
+	public boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number )
+	{
+		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( "isPieceCompleteProcessingNeeded: " + piece_number );
+			}
+	
+			if ( piece_number >= next_piece_index ){
+			
+					// nothing stored yet in the location where this piece belongs
+				
+				if ( TRACE ){
+					System.out.println( "   nothing stored" );
+				}
+				
+				return( false );
+			}
+			
+			int	store_index = piece_map[ piece_number ];
+			
+			if ( store_index == -1 ){
+				
+					// things screwed up, return true to trigger subsequent fail
+				
+				if ( TRACE ){
+					System.out.println( "   screwed" );
+				}
+				
+				return( true );
+			}
+			
+			if ( piece_number == store_index ){
+				
+					// already in the right place
+				
+				if ( TRACE ){
+					System.out.println( "    already in right place" );
+				}
+				
+				return( false );
+			}
+			
+			if ( TRACE ){
+				System.out.println( "   needs moving" );
+			}
+			
+			return( true );
+			
+		}else{
+			
+			return( delegate.isPieceCompleteProcessingNeeded( piece_number ));
+		}
+	}
+	
 	public void
 	setPieceComplete(
 		RandomAccessFile	raf,
@@ -491,6 +612,8 @@ FMFileAccessPieceReorderer
 	
 		throws FMFileManagerException
 	{	
+			// note, some of this logic repeated above
+		
 		if ( num_pieces >= MIN_PIECES_REORDERABLE ){
 				
 				// note that it is possible to reduce the number of piece moves at the expense
@@ -548,8 +671,8 @@ FMFileAccessPieceReorderer
 			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 );
+				long	store_offset = first_piece_length + ((store_index-1)*(long)piece_size );
+				long	swap_offset	 = first_piece_length + ((piece_number-1)*(long)piece_size );
 				
 				delegate.read( raf, temp_buffers, swap_offset );
 				
@@ -631,8 +754,8 @@ FMFileAccessPieceReorderer
 					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 );
+						long	store_offset 	= first_piece_length + ((store_index-1)*(long)piece_size );
+						long	swap_offset 	= first_piece_length + ((swap_index-1)*(long)piece_size );
 
 						delegate.read( raf, temp_buffers, swap_offset );
 
@@ -676,8 +799,8 @@ FMFileAccessPieceReorderer
 		
 		return( store_index );
 	}
-	
-	protected void
+		
+	private void
 	readConfig()
 	
 		throws FMFileManagerException
@@ -704,7 +827,9 @@ FMFileAccessPieceReorderer
 			
 			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 ));
+				configBorked( "Failed to read control file " + new File( control_dir, control_file ).getAbsolutePath() + ": map invalid - " + map );
+				
+				return;
 			}
 			
 			current_length 		= l_len.longValue();
@@ -712,7 +837,9 @@ FMFileAccessPieceReorderer
 			
 			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" ));
+				configBorked( "Failed to read control file " + new File( control_dir, control_file ).getAbsolutePath() + ": piece bytes invalid" );
+				
+				return;
 			}
 			
 			int	pos = 0;
@@ -739,6 +866,45 @@ FMFileAccessPieceReorderer
 		}
 	}
 
+	private void
+	configBorked(
+		String	error )
+	
+		throws FMFileManagerException
+	{
+		piece_map 			= new int[num_pieces];
+		piece_reverse_map 	= new int[num_pieces];
+					
+		Arrays.fill( piece_map, -1 );
+		
+		piece_map[0]			= 0;
+		piece_reverse_map[0]	= 0;
+		current_length			= getFile().getLinkedFile().length();
+		
+		int	piece_count = (int)(( current_length + piece_size - 1 )/piece_size) + 1;
+		
+		if ( piece_count > num_pieces ){
+			
+			piece_count = num_pieces;
+		}
+		
+		for ( int i=1;i<piece_count;i++){
+			
+			piece_map[i] 			= i;
+			piece_reverse_map[i]	= i;
+		}
+		
+		next_piece_index 		= piece_count;
+		
+		writeConfig();
+		
+		FMFileManagerException e = new FMFileManagerException( error );
+		
+		e.setRecoverable( false );
+		
+		throw( e );
+	}
+	
 	protected void
 	setDirty()
 	
@@ -768,16 +934,12 @@ FMFileAccessPieceReorderer
 		}
 	}
 
-	protected void
-	writeConfig()
-	
-		throws FMFileManagerException
+	private static Map
+	encodeConfig(
+		long		current_length,
+		long		next_piece_index,
+		int[]		piece_map )
 	{
-		if ( piece_map == null ){
-			
-			readConfig();
-		}
-		
 		Map	map = new HashMap();
 		
 		map.put( "len", 	new Long( current_length ));
@@ -806,6 +968,75 @@ FMFileAccessPieceReorderer
 		
 		map.put( "pieces", 	pieces_bytes );
 		
+		return( map );
+	}
+	
+	protected static void
+	recoverConfig(
+		TOTorrentFile	torrent_file,
+		File			data_file,
+		File			config_file )
+	
+		throws FMFileManagerException
+	{
+		// most likely add-for-seeding which means a recheck will occur. just map all existing pieces
+		// to their correct positions and let the recheck sort things out
+			
+		int first_piece_number 	= torrent_file.getFirstPieceNumber();
+
+		int num_pieces = torrent_file.getLastPieceNumber() - first_piece_number + 1;
+
+		int piece_size = (int)torrent_file.getTorrent().getPieceLength();
+
+		int[] piece_map 			= new int[num_pieces];
+					
+		Arrays.fill( piece_map, -1 );
+
+		piece_map[0]	= 0;
+		
+		long	current_length = data_file.length();
+		
+		int	piece_count = (int)(( current_length + piece_size - 1 )/piece_size) + 1;
+		
+		if ( piece_count > num_pieces ){
+			
+			piece_count = num_pieces;
+		}
+		
+		for ( int i=1;i<piece_count;i++){
+			
+			piece_map[i] = i;
+		}
+		
+		int	next_piece_index = piece_count;
+		
+		Map	map = encodeConfig( current_length, next_piece_index, piece_map );
+		
+		File	control_dir = config_file.getParentFile();
+
+		if ( !control_dir.exists()){
+			
+			control_dir.mkdirs();
+		}
+		
+		if ( !FileUtil.writeResilientFileWithResult( control_dir, config_file.getName(), map )){
+			
+			throw( new FMFileManagerException( "Failed to write control file " + config_file.getAbsolutePath()));
+		}
+	}
+
+	private void
+	writeConfig()
+	
+		throws FMFileManagerException
+	{
+		if ( piece_map == null ){
+			
+			readConfig();
+		}
+		
+		Map	map = encodeConfig( current_length, next_piece_index, piece_map );
+		
 		if ( !control_dir.exists()){
 			
 			control_dir.mkdirs();
@@ -824,6 +1055,12 @@ FMFileAccessPieceReorderer
 		dirt_time	= -1;
 	}
 	
+	public FMFileImpl 
+	getFile() 
+	{
+		return( delegate.getFile());
+	}
+	
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
index 01aa28d..3861b6f 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileImpl.java
@@ -265,7 +265,7 @@ FMFileImpl
 	protected void
 	setAccessModeSupport(
 		int		mode )
-	{
+	{		
 		access_mode	= mode;
 	}
 	
@@ -489,7 +489,7 @@ FMFileImpl
 			if (OUTPUT_REOPEN_RELATED_ERRORS) {Debug.printStackTrace(e);}
 			
 			try{
-				reopen();
+				reopen( e );
 				
 				return( file_access.getLength( raf ));
 				
@@ -514,7 +514,7 @@ FMFileImpl
 			if (OUTPUT_REOPEN_RELATED_ERRORS) {Debug.printStackTrace(e);}
 						
 			try{
-				reopen();
+				reopen( e );
 
 				file_access.setLength( raf, length );
 				
@@ -526,10 +526,16 @@ FMFileImpl
 	}
 	
 	protected void
-	reopen()
+	reopen(
+		FMFileManagerException		cause )
 
 		throws Throwable
 	{
+		if ( !cause.isRecoverable()){
+			
+			throw( cause );
+		}
+		
 		if ( raf != null ){
 			
 			try{
@@ -638,6 +644,15 @@ FMFileImpl
 		file_access.flush();
 	}
 	
+	protected boolean
+	isPieceCompleteProcessingNeeded(
+		int					piece_number )
+	
+		throws FMFileManagerException
+	{
+		return( file_access.isPieceCompleteProcessingNeeded( piece_number ));
+	}
+	
 	protected void
 	setPieceCompleteSupport(
 		int					piece_number,
@@ -690,7 +705,7 @@ FMFileImpl
 			if (OUTPUT_REOPEN_RELATED_ERRORS) {Debug.printStackTrace(e);}
 			
 			try{
-				reopen();
+				reopen( e );
 
 				file_access.read( raf, buffers, position );
 				
@@ -727,7 +742,7 @@ FMFileImpl
 			if (OUTPUT_REOPEN_RELATED_ERRORS) {Debug.printStackTrace(e);}
 			
 			try{
-				reopen();
+				reopen( e );
 
 				file_access.write( raf, buffers, position );
 				
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
index 54014e6..0753a23 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileLimited.java
@@ -188,10 +188,35 @@ FMFileLimited
 		try{
 			this_mon.enter();
 		
-			ensureOpen( "FMFileLimited:setPieceComplete" );
-			
-			setPieceCompleteSupport( piece_number, piece_data );
-			
+			if ( isPieceCompleteProcessingNeeded( piece_number )){
+		
+				ensureOpen( "FMFileLimited:setPieceComplete" );
+
+				boolean	switched_mode = false;
+				
+				if ( getAccessMode() != FM_WRITE ){
+					
+					setAccessMode( FM_WRITE );
+					
+					switched_mode = true;
+					
+						// switching mode closes the file...
+					
+					ensureOpen( "FMFileLimited:setPieceComplete2" );
+				}
+				
+				try{
+				
+					setPieceCompleteSupport( piece_number, piece_data );
+					
+				}finally{
+					
+					if ( switched_mode ){
+						
+						setAccessMode( FM_READ );
+					}
+				}
+			}
 		}finally{
 			
 			this_mon.exit();
diff --git a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
index d3a411f..9f3440a 100644
--- a/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
+++ b/com/aelitis/azureus/core/diskmanager/file/impl/FMFileUnlimited.java
@@ -141,10 +141,35 @@ FMFileUnlimited
 		try{
 			this_mon.enter();
 		
-			ensureOpen( "FMFileUnlimited:setPieceComplete" );
-			
-			setPieceCompleteSupport( piece_number, piece_data );
-			
+			if ( isPieceCompleteProcessingNeeded( piece_number )){
+		
+				ensureOpen( "FMFileUnlimited:setPieceComplete" );
+
+				boolean	switched_mode = false;
+				
+				if ( getAccessMode() != FM_WRITE ){
+					
+					setAccessMode( FM_WRITE );
+					
+					switched_mode = true;
+					
+						// switching mode closes the file...
+					
+					ensureOpen( "FMFileUnlimited:setPieceComplete2" );
+				}
+				
+				try{
+				
+					setPieceCompleteSupport( piece_number, piece_data );
+					
+				}finally{
+					
+					if ( switched_mode ){
+						
+						setAccessMode( FM_READ );
+					}
+				}
+			}
 		}finally{
 			
 			this_mon.exit();
diff --git a/com/aelitis/azureus/core/download/DiskManagerFileInfoDelegate.java b/com/aelitis/azureus/core/download/DiskManagerFileInfoDelegate.java
new file mode 100644
index 0000000..40ab29a
--- /dev/null
+++ b/com/aelitis/azureus/core/download/DiskManagerFileInfoDelegate.java
@@ -0,0 +1,790 @@
+/*
+ * Created on Feb 11, 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.download;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.SHA1Simple;
+import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
+import org.gudy.azureus2.plugins.disk.DiskManagerEvent;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
+import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadException;
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
+
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.core.util.QTFastStartRAF;
+
+public class 
+DiskManagerFileInfoDelegate
+	implements DiskManagerFileInfo
+{
+	private DiskManagerFileInfo		delegate;
+	private byte[]					hash;
+	
+	public
+	DiskManagerFileInfoDelegate(
+		DiskManagerFileInfo		_delegate )
+	
+		throws DownloadException
+	{
+		delegate		= _delegate;
+		
+		if ( delegate.getDownload() == null ){
+			
+			throw( new DownloadException( "Not supported" ));
+		}
+		
+		byte[]	delegate_hash = delegate.getDownloadHash();
+			
+		hash = delegate_hash.clone();
+			
+		hash[0] ^= 0x01;
+	}
+	
+	public void 
+	setPriority(
+		boolean b )
+	{
+		delegate.setPriority( b );
+	}
+	
+	public int 
+	getNumericPriorty() 
+	{
+		return( delegate.getNumericPriorty());
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		delegate.setNumericPriority(priority);
+	}
+	
+	public void 
+	setSkipped(
+		boolean b )
+	{
+		delegate.setSkipped( b );
+	}
+	
+	public void
+	setDeleted(boolean b)
+	{
+		delegate.setDeleted(b);
+	}
+	
+	public void
+	setLink(
+		File	link_destination )
+	{	
+		delegate.setLink( link_destination );
+	}
+	
+	public File
+	getLink()
+	{
+		return( delegate.getLink());
+	}
+		 	
+	public int 
+	getAccessMode()
+	{
+		return( delegate.getAccessMode());
+	}
+	
+	public long 
+	getDownloaded()
+	{
+		return( delegate.getDownloaded());
+	}
+	
+	public long
+	getLength()
+	{
+		return( delegate.getLength());
+	}
+	
+	public File 
+	getFile()
+	{
+		return( delegate.getFile());
+	}
+	
+	public File 
+	getFile(
+		boolean follow_link ) 
+	{
+		return( delegate.getFile(follow_link));
+	}
+	
+	public int
+	getIndex()
+	{
+		return( delegate.getIndex());
+	}
+	
+	public int 
+	getFirstPieceNumber()
+	{
+		return( delegate.getFirstPieceNumber());
+	}
+	
+	public long
+	getPieceSize()
+	{
+		return( delegate.getPieceSize());
+	}
+	
+	public int 
+	getNumPieces()
+	{
+		return( delegate.getNumPieces());
+	}
+		
+	public boolean 
+	isPriority()
+	{
+		return( delegate.isPriority());
+	}
+	
+	public boolean 
+	isSkipped()
+	{
+		return( delegate.isSkipped());
+	}
+	
+	public boolean
+	isDeleted()
+	{
+		return( delegate.isDeleted());
+	}
+	
+	public byte[] 
+	getDownloadHash()
+    {
+		return( hash );
+    }
+	
+	public Download 
+	getDownload()
+	
+      throws DownloadException
+    {
+		throw( new DownloadException( "Not supported" ));
+    }
+	
+	public DiskManagerChannel
+	createChannel()
+	
+		throws DownloadException
+	{
+		return( new channel());
+	}
+	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		return( delegate.createRandomReadRequest( file_offset, length, reverse_order, listener));
+	}
+	
+	private class
+	channel
+		implements DiskManagerChannel
+	{
+		private DiskManagerChannel	delegate_channel;
+		
+		private volatile boolean	channel_destroyed;
+		private volatile long		channel_position;
+		
+		private
+		channel()
+		
+			throws DownloadException
+		{
+			delegate_channel = delegate.createChannel();
+		}
+		
+		public DiskManagerRequest
+		createRequest()
+		{
+			return( new request());
+		}
+		
+		public DiskManagerFileInfo
+		getFile()
+		{
+			return( DiskManagerFileInfoDelegate.this );
+		}
+		
+		public long 
+		getPosition() 
+		{
+			return( delegate_channel.getPosition());
+		}
+		
+		public boolean 
+		isDestroyed() 
+		{
+			return( delegate_channel.isDestroyed());
+		}
+		
+		public void
+		destroy()
+		{
+			delegate_channel.destroy();
+		}
+		
+		protected class
+		request
+			implements DiskManagerRequest
+		{
+			private DiskManagerRequest	delegate_request;
+			private volatile boolean	using_delegate;
+			
+			private long		offset;
+			private long		length;
+			
+			private volatile long	position;
+			
+			private String		user_agent;
+
+			private int			max_read_chunk = 128*1024;;
+
+			private volatile boolean	cancelled;
+			
+			
+			private CopyOnWriteList<DiskManagerListener>		listeners = new CopyOnWriteList<DiskManagerListener>();
+			
+			private
+			request()
+			{
+				delegate_request = delegate_channel.createRequest();
+			}
+			
+			public void
+			setType(
+				int			type )
+			{
+				if ( type != DiskManagerRequest.REQUEST_READ ){
+					
+					throw( new RuntimeException( "Not supported" ));
+				}
+				
+				delegate_request.setType( type );
+			}
+			
+			public void
+			setOffset(
+				long		_offset )
+			{
+				offset		= _offset;
+				
+				delegate_request.setOffset( offset ); 
+			}
+			
+			public void
+			setLength(
+				long		_length )
+			{
+				if ( _length < 0 ){
+					
+					throw( new RuntimeException( "Illegal argument" ));
+				}
+				
+				length		= _length;
+				
+				delegate_request.setLength( length );
+			}
+				
+			public void
+			setMaximumReadChunkSize(
+				int 	size )
+			{
+				max_read_chunk = size;
+				
+				delegate_request.setMaximumReadChunkSize( size );
+			}
+			
+			public void
+			setUserAgent(
+				String		agent )
+			{	
+				user_agent	= agent;
+				
+				delegate_request.setUserAgent( agent );
+			}
+
+			public long
+			getAvailableBytes()
+			{
+				if ( using_delegate ){
+					
+					return( delegate_request.getAvailableBytes());
+				}
+				
+				return( getRemaining());
+			}
+						
+			public long
+			getRemaining()
+			{
+				if ( using_delegate ){
+					
+					return( delegate_request.getRemaining());
+				}
+				
+				return( offset + length - position );
+			}
+			
+			public void
+			run()
+			{
+				boolean	for_stream = user_agent != null;
+				
+				if ( for_stream ){
+					
+					File file = delegate.getFile();
+					
+					String name = file.getName();
+					
+					int	dot_pos = name.lastIndexOf('.');
+					
+					String ext = dot_pos<0?"":name.substring(dot_pos+1);
+
+					for_stream = QTFastStartRAF.isSupportedExtension( ext );
+				}
+				
+				if ( for_stream ){
+					
+					QTFastStartRAF	raf = null;
+					
+					try{
+						raf = new QTFastStartRAF( getAccessor( max_read_chunk, user_agent ), true );
+						
+						raf.seek( offset );
+				
+						byte[] buffer = new byte[max_read_chunk];
+						
+						long	rem		= length;
+						long	pos 	= offset;
+						
+						while( rem > 0 ){
+							
+							if ( cancelled ){
+								
+								throw( new Exception( "Cancelled" ));
+								
+							}else if ( channel_destroyed ){
+								
+								throw( new Exception( "Destroyed" ));
+							}
+							
+							int	chunk = (int)Math.min( rem, max_read_chunk );
+							
+							int	len = raf.read( buffer, 0, chunk );
+													
+							sendEvent( new event( new PooledByteBufferImpl( buffer, 0, len ), pos, len ));
+							
+							rem -= len;
+							pos	+= len;
+							
+							position += len;
+						}
+					}catch( Throwable e ){
+						
+						sendEvent( new event( e ));
+						
+					}finally{
+						
+						if ( raf != null ){
+							
+							try{
+								raf.close();
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					}
+				}else{
+					
+					using_delegate	= true;
+					
+					delegate_request.addListener(
+						new DiskManagerListener()
+						{
+							public void
+							eventOccurred(
+								DiskManagerEvent	event )
+							{
+								sendEvent( event );
+							}
+						});
+						
+					delegate_request.run();
+				}
+			}
+			
+			public void
+			cancel()
+			{
+				cancelled = true;
+				
+				delegate_request.cancel();
+			}
+						
+			protected void
+			sendEvent(
+				DiskManagerEvent		ev )
+			{					
+				for ( DiskManagerListener l: listeners ){
+					
+					l.eventOccurred( ev );
+				}
+			}
+			
+			public void
+			addListener(
+				DiskManagerListener	listener )
+			{
+				listeners.add( listener );
+			}
+			
+			public void
+			removeListener(
+				DiskManagerListener	listener )
+			{
+				listeners.remove( listener );
+			}
+		
+			protected class
+			event
+				implements DiskManagerEvent
+			{
+				private int					event_type;
+				private Throwable			error;
+				private PooledByteBuffer	buffer;
+				private long				event_offset;
+				private int					event_length;
+				
+				protected
+				event(
+					Throwable		_error )
+				{
+					event_type	= DiskManagerEvent.EVENT_TYPE_FAILED;
+					error		= _error;
+				}
+								
+				protected
+				event(
+					PooledByteBuffer	_buffer,
+					long				_offset,
+					int					_length )
+				{
+					event_type		= DiskManagerEvent.EVENT_TYPE_SUCCESS;
+					buffer			= _buffer;
+					event_offset	= _offset;
+					event_length	= _length;
+					
+					channel_position = _offset + _length - 1;
+				}
+				
+				public int
+				getType()
+				{
+					return( event_type );
+				}
+				
+				public DiskManagerRequest
+				getRequest()
+				{
+					return( request.this );
+				}
+				
+				public long
+				getOffset()
+				{
+					return( event_offset );
+				}
+				
+				public int
+				getLength()
+				{
+					return( event_length );
+				}
+				
+				public PooledByteBuffer
+				getBuffer()
+				{
+					return( buffer );
+				}
+				
+				public Throwable
+				getFailure()
+				{
+					return( error );
+				}
+			}
+		}
+		
+		private QTFastStartRAF.FileAccessor
+		getAccessor(
+			final int			max_req_size,
+			final String		user_agent )
+		{
+			return( 
+				new QTFastStartRAF.FileAccessor()
+				{
+					private long				seek_position;
+					private DiskManagerRequest 	current_request;
+					private volatile boolean	closed;
+					
+					public String
+					getName()
+					{
+						try{
+							return( delegate.getDownload().getName() + "/" + delegate.getFile().getName());
+							
+						}catch( Throwable e ){
+							
+							Debug.out( e );
+							
+							return( delegate.getFile().getAbsolutePath());
+						}
+					}
+					
+					public long
+					getFilePointer()
+					
+						throws IOException
+					{
+						return( seek_position );
+					}
+					
+					public void
+					seek(
+						long		pos )
+					
+						throws IOException
+					{
+						seek_position = pos;
+					}
+
+					public void
+					skipBytes(
+						int		num )
+					
+						throws IOException
+					{
+						seek_position += num;
+					}
+					
+					public long
+					length()
+					
+						throws IOException
+					{
+						return( getLength());
+					}
+					
+					public int
+					read(
+						final byte[]	buffer,
+						final int		pos,
+						final int		len )
+					
+						throws IOException
+					{
+						synchronized( this ){
+							
+							if ( closed ){
+								
+								throw( new IOException( "closed" ));
+							}
+							
+							current_request = delegate_channel.createRequest();
+						}
+						
+						current_request.setType( DiskManagerRequest.REQUEST_READ );
+						current_request.setOffset( seek_position );
+						current_request.setLength( len );
+						
+						current_request.setMaximumReadChunkSize( max_req_size );
+						
+						if ( user_agent != null ){
+						
+							current_request.setUserAgent( user_agent );
+						}
+						
+						final AESemaphore	sem = new AESemaphore( "waiter" );
+						final Throwable[]	error = {null};
+						
+						current_request.addListener(
+							new DiskManagerListener()
+							{
+								private int write_pos 	= pos;
+								private int	rem			= len;
+								
+								public void
+								eventOccurred(
+									DiskManagerEvent	event )
+								{
+									int	type = event.getType();
+									
+									if ( type == DiskManagerEvent.EVENT_TYPE_SUCCESS ){
+										
+										PooledByteBuffer p_buffer = event.getBuffer();
+										
+										try{
+											ByteBuffer	bb = p_buffer.toByteBuffer();
+																					
+											bb.position( 0 );
+											
+											int	read = bb.remaining();
+
+											bb.get( buffer, write_pos, read );
+											
+											write_pos 	+= read;
+											rem			-= read;
+											
+											if ( rem == 0 ){
+												
+												sem.release();
+											}
+										}finally{
+											
+											p_buffer.returnToPool();
+										}
+									}else if ( type == DiskManagerEvent.EVENT_TYPE_FAILED ){
+									
+										error[0] = event.getFailure();
+										
+										sem.release();
+									}
+								}
+							});
+						
+						current_request.run();
+						
+						while( true ){
+							
+							if ( sem.reserve( 1000 )){
+								
+								if ( error[0] != null ){
+									
+									throw( new IOException( Debug.getNestedExceptionMessage( error[0] )));
+								}
+								
+								seek_position += len;
+								
+								return( len );
+								
+							}else{
+								
+								if ( closed ){
+									
+									throw( new IOException( "Closed" ));
+								}
+							}
+						}
+					}
+					
+					public int
+					readInt()
+					
+						throws IOException
+					{
+						byte[]	readBuffer = new byte[4];
+						
+						readFully( readBuffer );
+						
+						return ((readBuffer[0] << 24) + 
+								((readBuffer[1]&0xff) << 16) + 
+								((readBuffer[2]&0xff) << 8) + 
+								((readBuffer[3]&0xff) << 0));
+					}
+					
+					public long
+					readLong()
+					
+						throws IOException
+					{
+						byte[]	readBuffer = new byte[8];
+						
+						readFully( readBuffer );
+					  
+						return (	((long)readBuffer[0] << 56) +
+					                ((long)(readBuffer[1]&0xff) << 48) +
+					                ((long)(readBuffer[2]&0xff) << 40) +
+					                ((long)(readBuffer[3]&0xff) << 32) +
+					                ((long)(readBuffer[4]&0xff) << 24) +
+					                ((readBuffer[5]&0xff) << 16) +
+					                ((readBuffer[6]&0xff) <<  8) +
+					                ((readBuffer[7]&0xff) <<  0));					
+					}
+					
+					public void
+					readFully(
+						byte[]	buffer )
+					
+						throws IOException
+					{
+						read( buffer, 0, buffer.length );
+					}
+							
+					public void
+					close()
+					
+						throws IOException
+					{
+						synchronized( this ){
+						
+							closed	= true;
+							
+							if ( current_request != null ){
+								
+								current_request.cancel();
+							}
+						}
+					}
+				});
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/download/DiskManagerFileInfoFile.java b/com/aelitis/azureus/core/download/DiskManagerFileInfoFile.java
index 634e16c..f3c12b3 100644
--- a/com/aelitis/azureus/core/download/DiskManagerFileInfoFile.java
+++ b/com/aelitis/azureus/core/download/DiskManagerFileInfoFile.java
@@ -22,7 +22,6 @@
 package com.aelitis.azureus.core.download;
 
 import java.io.File;
-import java.io.RandomAccessFile;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SHA1Simple;
@@ -30,6 +29,7 @@ import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
 import org.gudy.azureus2.plugins.disk.DiskManagerEvent;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
 import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
@@ -37,6 +37,7 @@ import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
 import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
 
 import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.core.util.QTFastStartRAF;
 
 public class 
 DiskManagerFileInfoFile
@@ -66,6 +67,19 @@ DiskManagerFileInfoFile
 	{
 	}
 	
+	public int 
+	getNumericPriorty() 
+	{
+		return( 0 );
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		throw( new RuntimeException( "Not supported" ));
+	}
+	
 	public void 
 	setSkipped(
 		boolean b )
@@ -115,7 +129,14 @@ DiskManagerFileInfoFile
 	{
 		return( file );
 	}
-		
+	
+	public File 
+	getFile(
+		boolean follow_link ) 
+	{
+		return( file );
+	}
+	
 	public int
 	getIndex()
 	{
@@ -182,11 +203,24 @@ DiskManagerFileInfoFile
 		return( new channel());
 	}
 	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		throw( new DownloadException( "Not supported" ));
+	}
+	
 	protected class
 	channel
 		implements DiskManagerChannel
 	{
-		private volatile boolean	destroyed;
+		private volatile boolean	channel_destroyed;
+		private volatile long		channel_position;
 		
 		public DiskManagerRequest
 		createRequest()
@@ -200,10 +234,22 @@ DiskManagerFileInfoFile
 			return( DiskManagerFileInfoFile.this );
 		}
 		
+		public long 
+		getPosition() 
+		{
+			return( channel_position );
+		}
+		
+		public boolean 
+		isDestroyed() 
+		{
+			return( channel_destroyed );
+		}
+		
 		public void
 		destroy()
 		{
-			destroyed	= true;
+			channel_destroyed	= true;
 		}
 		
 		protected class
@@ -219,6 +265,8 @@ DiskManagerFileInfoFile
 
 			private volatile boolean	cancelled;
 			
+			private String		user_agent;
+			
 			private CopyOnWriteList<DiskManagerListener>		listeners = new CopyOnWriteList<DiskManagerListener>();
 			
 			public void
@@ -257,6 +305,14 @@ DiskManagerFileInfoFile
 				max_read_chunk = size;
 			}
 			
+			public void
+			setUserAgent(
+				String		agent )
+			{	
+				user_agent	= agent;
+			}
+
+			
 			public long
 			getAvailableBytes()
 			{
@@ -272,10 +328,16 @@ DiskManagerFileInfoFile
 			public void
 			run()
 			{
-				RandomAccessFile	raf = null;
+				QTFastStartRAF	raf = null;
+				
+				String name = file.getName();
+				
+				int	dot_pos = name.lastIndexOf('.');
+				
+				String ext = dot_pos<0?"":name.substring(dot_pos+1);
 				
 				try{
-					raf = new RandomAccessFile( file, "r" );
+					raf = new QTFastStartRAF( file, user_agent != null && QTFastStartRAF.isSupportedExtension( ext ));
 					
 					raf.seek( offset );
 			
@@ -290,7 +352,7 @@ DiskManagerFileInfoFile
 							
 							throw( new Exception( "Cancelled" ));
 							
-						}else if ( destroyed ){
+						}else if ( channel_destroyed ){
 							
 							throw( new Exception( "Destroyed" ));
 						}
@@ -328,13 +390,7 @@ DiskManagerFileInfoFile
 			{
 				cancelled = true;
 			}
-			
-			public void
-			setUserAgent(
-				String		agent )
-			{	
-			}
-			
+						
 			protected void
 			sendEvent(
 				event		ev )
@@ -387,6 +443,8 @@ DiskManagerFileInfoFile
 					buffer			= _buffer;
 					event_offset	= _offset;
 					event_length	= _length;
+					
+					channel_position = _offset + _length - 1;
 				}
 				
 				public int
diff --git a/com/aelitis/azureus/core/download/DiskManagerFileInfoStream.java b/com/aelitis/azureus/core/download/DiskManagerFileInfoStream.java
index 0628127..bd99e7e 100644
--- a/com/aelitis/azureus/core/download/DiskManagerFileInfoStream.java
+++ b/com/aelitis/azureus/core/download/DiskManagerFileInfoStream.java
@@ -32,6 +32,7 @@ import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
 import org.gudy.azureus2.plugins.disk.DiskManagerEvent;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
 import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
@@ -105,6 +106,19 @@ DiskManagerFileInfoStream
 		throw( new RuntimeException( "Not supported" ));
 	}
 	
+	public int 
+	getNumericPriorty() 
+	{
+		return( 0 );
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		throw( new RuntimeException( "Not supported" ));
+	}
+	
 	public void
 	setDeleted(boolean b)
 	{
@@ -147,6 +161,13 @@ DiskManagerFileInfoStream
 		return( save_to );
 	}
 		
+	public File
+	getFile(
+		boolean	follow_link )
+	{
+		return( save_to );
+	}
+	
 	public int
 	getIndex()
 	{
@@ -226,6 +247,18 @@ DiskManagerFileInfoStream
 		}
 	}
 	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		throw( new DownloadException( "Not supported" ));
+	}
+	
 	protected void
 	destroyed(
 		context		c )
@@ -502,6 +535,7 @@ DiskManagerFileInfoStream
 			implements DiskManagerChannel
 		{
 			private volatile boolean	channel_destroyed;
+			private volatile long		channel_position;
 			
 			public DiskManagerRequest
 			createRequest()
@@ -515,6 +549,18 @@ DiskManagerFileInfoStream
 				return( DiskManagerFileInfoStream.this );
 			}
 			
+			public long 
+			getPosition() 
+			{
+				return( channel_position );
+			}
+			
+			public boolean 
+			isDestroyed() 
+			{
+				return( channel_destroyed );
+			}
+			
 			public void
 			destroy()
 			{
@@ -699,6 +745,8 @@ DiskManagerFileInfoStream
 						event_type		= DiskManagerEvent.EVENT_TYPE_BLOCKED;
 
 						event_offset	= _offset;	
+						
+						channel_position	= _offset;
 					}
 					
 					protected
@@ -711,6 +759,8 @@ DiskManagerFileInfoStream
 						buffer			= _buffer;
 						event_offset	= _offset;
 						event_length	= _length;
+						
+						channel_position	= _offset + _length - 1;
 					}
 					
 					public int
diff --git a/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java b/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
index 4d10fb0..92bf6c6 100644
--- a/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
+++ b/com/aelitis/azureus/core/download/DownloadManagerEnhancer.java
@@ -24,8 +24,10 @@
 package com.aelitis.azureus.core.download;
 
 import java.util.*;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
+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.*;
@@ -69,8 +71,12 @@ DownloadManagerEnhancer
 	
 	private Map<DownloadManager,EnhancedDownloadManager>		download_map = new HashMap<DownloadManager,EnhancedDownloadManager>();
 	
+	private Set<HashWrapper>		pause_set = new HashSet<HashWrapper>();
+	
 	private boolean			progressive_enabled;
 	
+	private AtomicLong	progressive_active_counter = new AtomicLong();
+	
 	protected
 	DownloadManagerEnhancer(
 		AzureusCore	_core )
@@ -108,8 +114,9 @@ DownloadManagerEnhancer
 				public void
 				destroyInitiated()
 				{
-					// resume any downloads we paused
-					core.getGlobalManager().resumeDownloads();
+						// resume any downloads we paused
+					
+					resume();
 				}
 					
 				public void
@@ -236,32 +243,44 @@ DownloadManagerEnhancer
 				{
 					private int tick_count;
 					
+					private long	last_inactive_marker = 0;
+					
 					public void 
 					perform(
 						TimerEvent event ) 
 					{
 						tick_count++;
 						
+						long	current_marker = progressive_active_counter.get();
+						
+						if ( last_inactive_marker == current_marker ){
+							
+							return;
+						}
+												
 						List	downloads = core.getGlobalManager().getDownloadManagers();
 						
+						boolean	is_active = false;
+						
 						for ( int i=0;i<downloads.size();i++){
 							
 							DownloadManager download = (DownloadManager)downloads.get(i);
-							
-							int	state = download.getState();
-							
-							if ( 	state == DownloadManager.STATE_DOWNLOADING ||
-									state == DownloadManager.STATE_SEEDING ){
+															
+							EnhancedDownloadManager edm = getEnhancedDownload( download );
 								
-								EnhancedDownloadManager edm = getEnhancedDownload( download );
-								if (edm == null) {
-									return;
+							if ( edm != null ){
+																	
+								if ( edm.updateStats( tick_count )){
+										
+									is_active = true;
 								}
-								
-								edm.updateStats( tick_count );
-							
 							}
 						}
+						
+						if ( !is_active ){
+							
+							last_inactive_marker = current_marker;
+						}
 					}
 				});
 		
@@ -272,10 +291,10 @@ DownloadManagerEnhancer
 			{
 				public void
 				channelCreated(
-					DiskManagerChannel	channel )
+					final DiskManagerChannel	channel )
 				{
 					try{
-						EnhancedDownloadManager edm = 
+						final EnhancedDownloadManager edm = 
 							getEnhancedDownload(
 									PluginCoreUtils.unwrap(channel.getFile().getDownload()));
 
@@ -288,7 +307,7 @@ DownloadManagerEnhancer
 						
 							return;
 						}
-						
+								
 						if ( !edm.getProgressiveMode()){
 							
 							if ( edm.supportsProgressiveMode()){
@@ -306,12 +325,145 @@ DownloadManagerEnhancer
 			});
 	}
 	
+	protected void
+	progressiveActivated()
+	{
+		progressive_active_counter.incrementAndGet();
+	}
+	
 	protected AzureusCore
 	getCore()
 	{
 		return( core );
 	}
 	
+	protected void
+	pause(
+		DownloadManager		dm )
+	{
+		TOTorrent torrent = dm.getTorrent();
+		
+		if ( torrent == null ){
+			
+			return;
+		}
+		
+		try{
+			HashWrapper hw = torrent.getHashWrapper();
+			
+			synchronized( pause_set ){
+				
+				if ( pause_set.contains( hw )){
+					
+					return;
+				}
+				
+				pause_set.add( hw );
+			}
+			
+			dm.pause();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	protected void
+	resume(
+		DownloadManager		dm )
+	{
+		TOTorrent torrent = dm.getTorrent();
+		
+		if ( torrent == null ){
+			
+			return;
+		}
+		
+		try{
+			HashWrapper hw = torrent.getHashWrapper();
+			
+			synchronized( pause_set ){
+				
+				if ( !pause_set.remove( hw )){
+					
+					return;
+				}
+			}
+			
+			dm.resume();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	protected void
+	resume()
+	{
+		Set<HashWrapper> copy;
+		
+		synchronized( pause_set ){
+		
+			copy = new HashSet<HashWrapper>( pause_set );
+			
+			pause_set.clear();
+		}
+		
+		GlobalManager gm = core.getGlobalManager();
+		
+		for ( HashWrapper hw: copy ){
+			
+			DownloadManager dm = gm.getDownloadManager( hw );
+			
+			if ( dm != null ){
+				
+				dm.resume();
+			}
+		}
+	}
+	
+	protected  void
+	prepareForProgressiveMode(
+		DownloadManager		dm,
+		boolean				active )
+	{
+		if ( active ){
+			
+			GlobalManager gm = core.getGlobalManager();
+
+			List<DownloadManager> dms = (List<DownloadManager>)gm.getDownloadManagers();
+			
+			for ( DownloadManager this_dm: dms ){
+				
+				if ( this_dm == dm ){
+					
+					continue;
+				}
+			
+				if ( !this_dm.isDownloadComplete(false)){
+					
+					int state = this_dm.getState();
+					
+					if ( 	state == DownloadManager.STATE_DOWNLOADING ||
+							state == DownloadManager.STATE_QUEUED) {
+					
+						pause( this_dm );
+					}
+				}
+			}
+			
+			if ( dm.isPaused()){
+				
+				dm.resume();
+			}
+		}else{
+			
+			resume();
+		}
+	}
+	
 	public EnhancedDownloadManager
 	getEnhancedDownload(
 		byte[]			hash )
@@ -330,8 +482,17 @@ DownloadManagerEnhancer
 	getEnhancedDownload(
 		DownloadManager	manager )
 	{
-		DownloadManager dm2 = manager.getGlobalManager().getDownloadManager(manager.getTorrent());
-		if (dm2 != manager) {
+		TOTorrent torrent = manager.getTorrent();
+		
+		if ( torrent == null ){
+			
+			return( null );
+		}
+		
+		DownloadManager dm2 = manager.getGlobalManager().getDownloadManager( torrent );
+		
+		if ( dm2 != manager ){
+			
 			return null;
 		}
 
diff --git a/com/aelitis/azureus/core/download/EnhancedDownloadManager.java b/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
index dc4955c..e8cd489 100644
--- a/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
+++ b/com/aelitis/azureus/core/download/EnhancedDownloadManager.java
@@ -23,8 +23,7 @@
 
 package com.aelitis.azureus.core.download;
 
-import java.net.InetAddress;
-import java.util.*;
+import java.util.List;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
@@ -37,36 +36,23 @@ 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.*;
+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.util.*;
 
-import com.aelitis.azureus.core.peer.cache.CacheDiscovery;
-import com.aelitis.azureus.core.peer.cache.CachePeer;
 import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
 import com.aelitis.azureus.core.peermanager.piecepicker.PieceRTAProvider;
-import com.aelitis.azureus.core.peermanager.utils.PeerClassifier;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.util.average.Average;
 import com.aelitis.azureus.core.util.average.AverageFactory;
-import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
-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 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 
 {
 	public static  int	DEFAULT_MINIMUM_INITIAL_BUFFER_SECS_FOR_ETA	= 30;
-	public static  int	WMP_MINIMUM_INITIAL_BUFFER_SECS_FOR_ETA		= 60;
 		
 		// number of seconds of buffer required before we fall back to normal bt mode
 	
@@ -90,122 +76,46 @@ EnhancedDownloadManager
 			});
 	}
 	
-	public static final int SPEED_CONTROL_INITIAL_DELAY	= 10*1000;
-	public static final int SPEED_INCREASE_GRACE_PERIOD	= 3*1000;
-	public static final int PEER_INJECT_GRACE_PERIOD	= 3*1000;
-	public static final int IDLE_PEER_DISCONNECT_PERIOD	= 60*1000;
-	public static final int IDLE_SEED_DISCONNECT_PERIOD = 60*1000;
-	public static final int MIN_SEED_CONNECTION_TIME	= 60*1000;
-	
-	public static final int IDLE_SEED_DISCONNECT_SECS	= IDLE_SEED_DISCONNECT_PERIOD/1000;
-	
-	public static final int CACHE_RECONNECT_MIN_PERIOD	= 15*60*1000;
-	public static final int CACHE_REQUERY_MIN_PERIOD	= 60*60*1000;
-	
-	public static final int TARGET_SPEED_EXCESS_MARGIN	= 2*1024;
-	
-	public static final int DISCONNECT_CHECK_PERIOD	= 10*1000;
-	public static final int DISCONNECT_CHECK_TICKS	= DISCONNECT_CHECK_PERIOD/DownloadManagerEnhancer.TICK_PERIOD;
-	
 	public static final int REACTIVATE_PROVIDER_PERIOD			= 5*1000;
 	public static final int REACTIVATE_PROVIDER_PERIOD_TICKS	= REACTIVATE_PROVIDER_PERIOD/DownloadManagerEnhancer.TICK_PERIOD;
 
 	public static final int LOG_PROG_STATS_PERIOD	= 10*1000;
 	public static final int LOG_PROG_STATS_TICKS	= LOG_PROG_STATS_PERIOD/DownloadManagerEnhancer.TICK_PERIOD;
 
-	private static final String TRACKER_PROG_PREFIX	= "azprog";
-	
-	
-	private static final String PM_SEED_TIME_KEY = "EnhancedDownloadManager:seedtime";
-	private static final String PEER_CACHE_KEY = "EnhancedDownloadManager:cachepeer";
-
-	private static int internal_content_stream_bps_increase_ratio		= 5;
-	private static int internal_content_stream_bps_increase_absolute	= 0;
-	
-		// these are here to allow other components (e.g. a plugin) to modify behaviour
-		// while we verify that things work ok
-	
-	public static void
-	setInternalContentStreamBPSIncreaseRatio(
-		String	caller_id,
-		int		ratio )
-	{
-		internal_content_stream_bps_increase_ratio	= ratio;
-	}
+	private static final int content_stream_bps_min_increase_ratio	= 5;
+	private static final int content_stream_bps_max_increase_ratio	= 8;
 	
-	public static void
-	setInternalContentStreamBPSIncreaseAbsolute(
-		String	caller_id,
-		int		abs )
-	{
-		internal_content_stream_bps_increase_absolute	= abs;
-	}
 	
 	private DownloadManagerEnhancer		enhancer;
 	private DownloadManager				download_manager;
 	
-	private boolean						platform_content;
+	private boolean						explicit_progressive;
 	
-	private transient PiecePicker		current_piece_pickler;
+	private volatile PiecePicker		current_piece_pickler;
 	
 	
 	
-	private boolean	progressive_active	= false;
+	private volatile boolean	progressive_active	= false;
 	
 	private long	content_min_delivery_bps;
 		
 	private int		minimum_initial_buffer_secs_for_eta;
-	private int		explicit_minimum_buffer_bytes;
 	
 	private bufferETAProvider	buffer_provider	= new bufferETAProvider();
-	private boostETAProvider	boost_provider	= new boostETAProvider();
 
 	private progressiveStats	progressive_stats;
 
-	private boolean				progressive_informed = false;
-	
-	private long	time_download_started;
-	private Average	download_speed_average	= AverageFactory.MovingImmediateAverage( 5 );
-	
+		
 	private boolean	marked_active;
 	private boolean	destroyed;
 
 	private DownloadManagerListener dmListener;
-	
-	private static final int	STALLED_TIMEOUT	= 2*60*1000;
-	
-	private boolean		publish_handling_complete;
-	private long		publish_sent		= -1;
-	private long		publish_sent_time;
-		
+				
 	private EnhancedDownloadManagerFile[]	enhanced_files;
-	private EnhancedDownloadManagerFile 	primary_file;
 
-	
-		// ********* reset these in resetVars ***********
-	
-	private long	last_speed_increase;
-	private long	last_peer_inject;
-	private long	last_lookup_time;
-	
-	private LinkedList	new_peers;
-	private List		cache_peers;
-	private List		disconnected_cache_peers;
-	
-	private CachePeer[]	lookup_peers;
 
-	private void
-	resetVars()
-	{
-		last_speed_increase		= 0;
-		last_peer_inject		= 0;
-		last_lookup_time		= 0;
-		
-		new_peers					= null;
-		cache_peers					= null;
-		disconnected_cache_peers	= null;
-		lookup_peers				= null;
-	}
+
+
 	
 	protected
 	EnhancedDownloadManager(
@@ -217,82 +127,28 @@ EnhancedDownloadManager
 
 		DiskManagerFileInfo[] files = download_manager.getDiskManagerFileInfo();
 		
-			// hack - we don't know the actual player until play starts so we just use the file name
+		minimum_initial_buffer_secs_for_eta = DEFAULT_MINIMUM_INITIAL_BUFFER_SECS_FOR_ETA;
 		
-			// TODO: we can probably read the registry to work out what player is associated with
-			// the file extension?
-		
-		boolean	found_wmv = false;
+		enhanced_files = new EnhancedDownloadManagerFile[files.length];
+					
+		long	offset = 0;
 		
 		for (int i=0;i<files.length;i++){
-		
-			String	file_name = files[i].getFile(true).getName().toLowerCase();
 			
-			if ( file_name.endsWith( ".wmv" )){
-				
-				found_wmv = true;
-				
-				break;
-			}
+			DiskManagerFileInfo f = files[i];
+							
+			enhanced_files[i] = new EnhancedDownloadManagerFile( f, offset );
+			
+			offset += f.getLength();
 		}
 		
-		if ( found_wmv ){
-			
-			minimum_initial_buffer_secs_for_eta = WMP_MINIMUM_INITIAL_BUFFER_SECS_FOR_ETA;
-
-		}else{
 		
-			minimum_initial_buffer_secs_for_eta = DEFAULT_MINIMUM_INITIAL_BUFFER_SECS_FOR_ETA;
-		}
+		int primary_index = getPrimaryFileIndex();
 		
-		TOTorrent	torrent = download_manager.getTorrent();
-
-		if ( torrent != null ){
-			
-			content_min_delivery_bps = PlatformTorrentUtils.getContentMinimumSpeedBps( torrent );
-			
-			platform_content = PlatformTorrentUtils.isContent( torrent, true );
-						
-			enhanced_files = new EnhancedDownloadManagerFile[files.length];
-			
-			Map meta_data = PlatformTorrentUtils.getFileMetaData( torrent );
-
-				// dunno why but I have a user with an ArrayList being returned here...
-			
-			Object o_files_info = meta_data==null?null:meta_data.get( "files" );
-			
-			Map files_info = o_files_info instanceof Map?(Map)o_files_info:null;
-			
-			long	offset = 0;
-			
-			for (int i=0;i<files.length;i++){
-				
-				DiskManagerFileInfo f = files[i];
-				
-				Map file_info = files_info==null?null:(Map)files_info.get( "" + i );
-				
-				enhanced_files[i] = new EnhancedDownloadManagerFile( f, offset, file_info );
-				
-				offset += f.getLength();
-			}
-				
-			int	primary_index = PlatformTorrentUtils.getContentPrimaryFileIndex( download_manager.getTorrent());
-								
-			if ( primary_index >= 0 && primary_index < files.length ){
-					
-				primary_file = enhanced_files[primary_index];
-					
-			}else{
+		EnhancedDownloadManagerFile primary_file = enhanced_files[primary_index==-1?0:primary_index];
 				
-				primary_file = enhanced_files[0];
-			}		
-		}else{
-			
-			enhanced_files = new EnhancedDownloadManagerFile[0];
-		}
-			
 		progressive_stats	= createProgressiveStats( download_manager, primary_file );
-
+		
 		download_manager.addPeerListener(
 			new DownloadManagerPeerListener()
 			{
@@ -307,19 +163,13 @@ EnhancedDownloadManager
 					PEPeerManager	manager )
 				{
 					synchronized( EnhancedDownloadManager.this ){
-					
-						time_download_started = SystemTime.getCurrentTime();
-						
+											
 						current_piece_pickler = manager.getPiecePicker();
 						
 						if ( progressive_active && current_piece_pickler != null ){
 							
 							buffer_provider.activate( current_piece_pickler );
-							
-							boost_provider.activate( current_piece_pickler );
 						}
-						
-						resetVars();
 					}
 				}
 				
@@ -329,20 +179,14 @@ EnhancedDownloadManager
 				{
 					synchronized( EnhancedDownloadManager.this ){
 
-						time_download_started 	= 0;
-
 						progressive_active		= false;
 						
 						if ( current_piece_pickler != null ){
 					
 							buffer_provider.deactivate(  current_piece_pickler );
 							
-							boost_provider.deactivate(  current_piece_pickler );
-							
 							current_piece_pickler	= null;	
 						}
-						
-						resetVars();
 					}
 				}
 				
@@ -350,87 +194,45 @@ EnhancedDownloadManager
 				peerAdded(
 					PEPeer 	peer )
 				{
-					if ( platform_content ){
-												
-						synchronized( EnhancedDownloadManager.this ){
-							
-							if ( new_peers == null ){
-								
-								new_peers = new LinkedList();
-							}
-							
-							new_peers.add( peer );
-						}
-					}
 				}
 					
 				public void
 				peerRemoved(
 					PEPeer	peer )
 				{
-					if ( platform_content ){
-							
-						synchronized( EnhancedDownloadManager.this ){
-							
-							if ( new_peers != null ){
-							
-								new_peers.remove( peer );
-								
-								if ( new_peers.size() == 0 ){
-									
-									new_peers = null;
-								}
-							}
-							
-							if ( cache_peers != null ){
-								
-								cache_peers.remove( peer );
-								
-								if ( cache_peers.size() == 0 ){
-									
-									cache_peers = null;
-								}
-							}
-							
-							CachePeer	cache_peer = (CachePeer)peer.getData( PEER_CACHE_KEY );
-
-							if ( cache_peer == null ){
-								
-									// we can disconnect before getting peer-id etc
-								
-								if ( lookup_peers != null ){
-									
-									for (int i=0;i<lookup_peers.length;i++){
-										
-										CachePeer cp = lookup_peers[i];
-										                            
-										if ( 	cp.getAddress().getHostAddress().equals( peer.getIp()) &&
-												cp.getPort() == peer.getPort()){
-										
-											cache_peer = cp;
-										}
-									}
-								}
-							}
-							
-							if ( 	cache_peer != null && 
-									cache_peer.getType() == CachePeer.PT_CACHE_LOGIC &&
-									(	disconnected_cache_peers == null || !disconnected_cache_peers.contains( cache_peer ))){
-								
-									// lost connection very early - sign that the cache doesn't support
-									// us
-								
-								if ( !peer.hasReceivedBitField()){
-									
-									cache_peer.setAutoReconnect( false );
-								}
-							}
-						}
-					}
 				}
 			});
 	}
 
+	public int getPrimaryFileIndex() {
+		DiskManagerFileInfo info = download_manager.getDownloadState().getPrimaryFile();
+		
+		if ( info == null ){
+			return( -1 );
+		}
+		return( info.getIndex());
+	}
+
+	public void
+	setExplicitProgressive(
+		int		min_initial_buffer_secs,
+		long	min_bps,
+		int		file_index )
+	{
+		if ( file_index >= 0 && file_index < enhanced_files.length ){
+			
+			explicit_progressive = true;
+
+			minimum_initial_buffer_secs_for_eta = min_initial_buffer_secs;
+			
+			content_min_delivery_bps = min_bps;
+											
+			EnhancedDownloadManagerFile primary_file = enhanced_files[file_index];
+				
+			progressive_stats	= createProgressiveStats( download_manager, primary_file );		
+		}
+	}
+	
 	public String
 	getName()
 	{
@@ -476,39 +278,6 @@ EnhancedDownloadManager
 		return( enhanced_files );
 	}
 	
-	public void
-	setMinimumBufferBytes(
-		int		min )
-	{
-		log( "Explicit min buffer set to " + min );
-		
-		explicit_minimum_buffer_bytes	= min;
-	}
-	
-	protected void
-	refreshMetaData()
-	{
-		progressive_stats.refreshMetaData();
-	}
-		
-	protected long
-	getTimeRunning()
-	{
-		if ( time_download_started == 0 ){
-			
-			return( 0 );
-		}
-		
-		long	now = SystemTime.getCurrentTime();
-		
-		if ( now < time_download_started ){
-			
-			time_download_started	= now;
-		}
-		
-		return( now - time_download_started );
-	}
-	
 	protected long
 	getTargetSpeed()
 	{
@@ -522,549 +291,84 @@ EnhancedDownloadManager
 		return( target_speed );
 	}
 	
-	protected void
+	protected boolean
 	updateStats(
 		int		tick_count )
 	{
-		updateProgressiveStats( tick_count );
-		
-		if ( !platform_content ){
-			
-			return;
-		}
-		
-		int	state = download_manager.getState();
-		
-		if ( state != DownloadManager.STATE_SEEDING && state != DownloadManager.STATE_DOWNLOADING ){
-			
-			return;
-		}
+		return( updateProgressiveStats( tick_count ));
+	}
+	
 
-		PEPeerManager	pm = download_manager.getPeerManager();
+	
+	public boolean
+	supportsProgressiveMode()
+	{
+		TOTorrent	torrent = download_manager.getTorrent();
 		
-		if ( pm == null ){
+		if ( torrent == null ){
 			
-			return;
+			return( false );
 		}
-
-		long	now = SystemTime.getCurrentTime();
-		
-		long	target_speed = getTargetSpeed();
-		
-		PEPeerManagerStats stats = pm.getStats();
-		
-		long	download_speed = stats.getDataReceiveRate();
 		
-		download_speed_average.update( download_speed );
-		
-		long	time_downloading = getTimeRunning();
-		
-		int		secs_since_last_up =  pm.getStats().getTimeSinceLastDataSentInSeconds();
+		return( enhancer.isProgressiveAvailable() && 
+				( PlatformTorrentUtils.isContentProgressive( torrent ) || explicit_progressive ));
+	}
+	
+	public void
+	prepareForProgressiveMode(
+		boolean		active )
+	{
+		enhancer.prepareForProgressiveMode( download_manager, active );
+	}
+	
+	public boolean
+	setProgressiveMode(
+		boolean		active )
+	{
+		return( setProgressiveMode( active, false ));
+	}
 		
-			// deal with -1 -> infinite
+	protected boolean
+	setProgressiveMode(
+		boolean		active,
+		boolean		switching_progressive_downloads )
+	{
+		TOTorrent	torrent = download_manager.getTorrent();
 		
-		if ( secs_since_last_up == -1 ){
-			
-			Long seed_time = (Long)pm.getData( PM_SEED_TIME_KEY );
-			
-			if ( seed_time == null ){
-				
-				seed_time = new Long( now );
-				
-				pm.setData( PM_SEED_TIME_KEY, seed_time );
-			}
-			
-			secs_since_last_up = (int)(( now - seed_time.longValue()) / 1000);
+		if ( torrent == null || download_manager.getDownloadState().getPrimaryFile() == null ){
+
+			return( false );
 		}
 		
-		List	peers_to_kick = new ArrayList();
+		DiskManagerFileInfo primaryFile = download_manager.getDownloadState().getPrimaryFile();
+		EnhancedDownloadManagerFile enhanced_file = enhanced_files[primaryFile.getIndex()];
 		
 		synchronized( this ){
-			
-			if ( new_peers != null ){
-										
-				Iterator it = new_peers.iterator();
-				
-				while( it.hasNext()){
-					
-					PEPeer	peer = (PEPeer)it.next();
-					
-					CachePeer	cache_peer = (CachePeer)peer.getData( PEER_CACHE_KEY );
 
-					if ( cache_peer == null ){
-						
-						byte[]	peer_id = peer.getId();
-						
-						if ( peer_id != null ){
-							
-							try{
-								cache_peer = CacheDiscovery.categorisePeer( 
-												peer_id, 
-												InetAddress.getByName( peer.getIp()),
-												peer.getPort());
-								
-								peer.setData( PEER_CACHE_KEY, cache_peer );
-								
-								if ( cache_peer.getType() == CachePeer.PT_CACHE_LOGIC ){
-									
-									if ( state == DownloadManager.STATE_SEEDING ){
-										
-										if ( 	now - cache_peer.getCreateTime( now ) >= MIN_SEED_CONNECTION_TIME &&
-												secs_since_last_up >= IDLE_SEED_DISCONNECT_SECS ){
+			if ( progressive_active == active ){
+				
+				return( true );
+			}			
 
-											peers_to_kick.add( peer );
-											
-											addToDisconnectedCachePeers( cache_peer );
-											
-										}else{
-											
-											if ( cache_peers == null ){
-												
-												cache_peers = new LinkedList();
-											}
-											
-											cache_peers.add( peer );
-										}
-									}else{
-										
-											// cache logic rely on timely have messages to control both
-											// piece allocation and client-speed
-										
-										peer.setHaveAggregationEnabled( false );
-										
-										if ( target_speed <= 0 ){
-										
-											setPeerSpeed( peer, -1, now );
-											
-											peers_to_kick.add( peer );
-											
-											addToDisconnectedCachePeers( cache_peer );
-	
-										}else{
-											
-											long	current_speed = (long)download_speed_average.getAverage();
-											
-												// if we are already exceeding required speed, block
-												// the cache peer download
-											
-											if ( current_speed + TARGET_SPEED_EXCESS_MARGIN > target_speed ){
-												
-												setPeerSpeed( peer, -1, now );
-											}
-											
-											if ( cache_peers == null ){
-												
-												cache_peers = new LinkedList();
-											}
-											
-											cache_peers.add( peer );
-										}
-									}
-								}
-							}catch( Throwable e ){
-								
-								Debug.printStackTrace(e);
-							}
-							
-							it.remove();
-						}
-					}else{
-						
-						it.remove();
-					}
-				}
+			if (active && !supportsProgressiveMode()) {
 				
-				if ( new_peers.size() == 0 ){
-					
-					new_peers = null;
-				}
+				Debug.out( "Attempt to set progress mode on non-progressible content - " + getName());
+				
+				return( false );
 			}
-		}
-		
-		for (int i=0;i<peers_to_kick.size();i++){
 			
-			pm.removePeer((PEPeer)peers_to_kick.get(i), "Cache peer not required" );
-		}
-				
-		if ( state == DownloadManager.STATE_DOWNLOADING ){
-		
-			if ( time_downloading > SPEED_CONTROL_INITIAL_DELAY ){
-				
-				long	current_average = (long)download_speed_average.getAverage();
-					
-				if ( current_average < target_speed ){
-					
-					long	current_speed = getCurrentSpeed();
-					
-						// increase cache peer contribution
-						// due to latencies we need to give speed increases a time to take
-						// effect to see if the limits can be reached
-					
-					long	difference = target_speed - current_speed;
-					
-					if ( last_speed_increase > now || now - last_speed_increase > SPEED_INCREASE_GRACE_PERIOD ){
-		
-						synchronized( this ){
-	
-							if ( cache_peers != null ){
-								
-								Iterator	it = cache_peers.iterator();
-								
-								while( it.hasNext() && difference > 0 ){
-							
-									PEPeer	peer = (PEPeer)it.next();
-																				
-									PEPeerStats peer_stats = peer.getStats();
-									
-									long peer_limit = peer_stats.getDownloadRateLimitBytesPerSecond();
-									
-										// try simple approach - find first cache peer that is limited
-										// to less than the target
-									
-									if ( peer_limit == 0 ){
-										
-									}else{
-										
-										if ( peer_limit < target_speed ){
-											
-											setPeerSpeed( peer, (int)target_speed, now );
-											
-											last_speed_increase = now;
-											
-											difference = 0;
-										}
-									}
-								}
-							}
-						}
-										
-						if ( 	difference > 0 &&
-								last_peer_inject > now || now - last_peer_inject > PEER_INJECT_GRACE_PERIOD ){
-							
-							Set	connected_peers = new HashSet();
-							
-							List	peers_to_try = new ArrayList();
-	
-							if ( cache_peers != null ){
-								
-								Iterator	it = cache_peers.iterator();
-								
-								while( it.hasNext() && difference > 0 ){
-							
-									PEPeer	peer = (PEPeer)it.next();
-						
-									connected_peers.add( peer.getIp() + ":" + peer.getPort());
-								}
-							}
-							
-								// if we explicitly disconnected peers in the past then reuse them first
-							
-							if ( disconnected_cache_peers != null ){
-								
-								while( disconnected_cache_peers.size() > 0 ){
-									
-									CachePeer	cp = (CachePeer)disconnected_cache_peers.remove(0);
-									
-									if ( !connected_peers.contains( cp.getAddress().getHostAddress() + ":" + cp.getPort())){
-										
-											// check that this peer isn't already available as a lookup result
-										
-										if ( lookup_peers != null ){
-											
-											for (int i=0;i<lookup_peers.length;i++){
-												
-												CachePeer	l_cp = lookup_peers[i];
-												
-												if ( l_cp.sameAs( cp )){
-													
-													cp = null;
-													
-													break;
-												}
-											}
-										}
-										
-										if ( cp != null ){
-										
-											peers_to_try.add( cp );
-											
-											break;
-										}
-									}
-								}
-								
-								if ( disconnected_cache_peers.size() == 0 ){
-									
-									disconnected_cache_peers = null;
-								}
-							}
-							
-							if ( peers_to_try.size() == 0 ){
-								
-									// can't do the job with existing cache peers, try to find some more
-								
-								if ( 	lookup_peers == null || 
-										now < last_lookup_time ||
-										now - last_lookup_time > CACHE_REQUERY_MIN_PERIOD ){
-																		
-									last_lookup_time = now;
-	
-									lookup_peers = CacheDiscovery.lookup( download_manager.getTorrent());
-								}
-								
-								for (int i=0;i<lookup_peers.length;i++){
-									
-									CachePeer	cp = lookup_peers[i];
-									
-									if ( cp.getAutoReconnect() && now - cp.getInjectTime(now) > CACHE_RECONNECT_MIN_PERIOD ){
-										
-										if ( !connected_peers.contains( cp.getAddress().getHostAddress() + ":" + cp.getPort())){
-										
-											peers_to_try.add( cp );
-										}
-									}
-								}
-							}
-							
-							if ( peers_to_try.size() > 0 ){
-								
-								CachePeer peer = (CachePeer)peers_to_try.get((int)( Math.random() * peers_to_try.size()));
-								
-								// System.out.println( "Injecting cache peer " + peer.getAddress() + ":" + peer.getPort());
-								
-								peer.setInjectTime( now );
-								
-								pm.addPeer( peer.getAddress().getHostAddress(), peer.getPort(), 0, false, null );
-								
-								last_peer_inject = now;
-							}
-						}
-					}				
-				}else if ( current_average > target_speed + TARGET_SPEED_EXCESS_MARGIN){
-					
-					long	current_speed = getCurrentSpeed();
-	
-						// decrease cache peer contribution
-					
-					long	difference = current_speed - ( target_speed + TARGET_SPEED_EXCESS_MARGIN );
-					
-					synchronized( this ){
-	
-						if ( cache_peers != null ){
-							
-							Iterator	it = cache_peers.iterator();
-							
-							while( it.hasNext() && difference > 0 ){
-						
-								PEPeer	peer = (PEPeer)it.next();
-															
-								PEPeerStats peer_stats = peer.getStats();
-								
-								long peer_rate = peer_stats.getDataReceiveRate();
-								
-								long peer_limit = peer_stats.getDownloadRateLimitBytesPerSecond();
-	
-								if ( peer_limit == -1 ){
-									
-										// blocked, take into account adjustment in progress
-									
-									difference -= peer_rate;
-									
-								}else if ( peer_limit != 0 && peer_rate > peer_limit ){
-									
-										// adjusting
-									
-									difference -= peer_rate - peer_limit;
-									
-								}else{
-									
-									if ( peer_rate > difference ){
-																				
-										setPeerSpeed( peer, (int)( peer_rate - difference ), now );
-										
-										difference = 0;
-										
-									}else{
-									
-										setPeerSpeed( peer, -1, now );
-																				
-										difference -= peer_rate;
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-		
-		if ( tick_count % DISCONNECT_CHECK_TICKS == 0 ){
-			
-			peers_to_kick.clear();
-			
-			synchronized( this ){
-				
-				if ( cache_peers != null ){
-					
-					Iterator	it = cache_peers.iterator();
-					
-					while( it.hasNext()){
-				
-						PEPeer	peer = (PEPeer)it.next();
-							
-						CachePeer	cache_peer = (CachePeer)peer.getData( PEER_CACHE_KEY );
-
-						if ( state == DownloadManager.STATE_SEEDING ){
-							
-							if ( 	now - cache_peer.getCreateTime( now ) >= MIN_SEED_CONNECTION_TIME &&
-									secs_since_last_up >= IDLE_SEED_DISCONNECT_SECS ){
-
-								peers_to_kick.add( peer );
-								
-								addToDisconnectedCachePeers( cache_peer );
-							}
-						}else{
-							
-							PEPeerStats peer_stats = peer.getStats();
-						
-							if ( peer_stats.getDownloadRateLimitBytesPerSecond() == -1 ){
-							
-								long	time = cache_peer.getSpeedChangeTime( now );
-								
-								if ( now - time > IDLE_PEER_DISCONNECT_PERIOD ){
-									
-									peers_to_kick.add( peer );
-									
-									addToDisconnectedCachePeers( cache_peer );
-								}
-							}
-						}
-					}
-				}
-			}
-			
-			for (int i=0;i<peers_to_kick.size();i++){
-				
-				pm.removePeer((PEPeer)peers_to_kick.get(i), "Cache peer disconnect-on-idle" );
-			}
-		}
-	}
-	
-	protected void
-	addToDisconnectedCachePeers(
-		CachePeer		cache_peer )
-	{
-		if ( disconnected_cache_peers == null ){
-			
-			disconnected_cache_peers = new ArrayList();
-		}
-
-		for (int i=0;i<disconnected_cache_peers.size();i++){
-			
-			CachePeer	p = (CachePeer)disconnected_cache_peers.get(i);
-			
-			if ( p.sameAs( cache_peer )){
-				
-				return;
-			}
-		}
-		
-		disconnected_cache_peers.add( cache_peer );
-	}
-	
-	protected void
-	setPeerSpeed(
-		PEPeer		peer,
-		int			speed,
-		long		time )
-	{
-		CachePeer	cache_peer = (CachePeer)peer.getData( PEER_CACHE_KEY );
-
-		cache_peer.setSpeedChangeTime( time );
-		
-		peer.getStats().setDownloadRateLimitBytesPerSecond( speed );
-	}
-	
-	protected long
-	getCurrentSpeed()
-	{
-			// gets instantaneous speed instead of longer term average
-		
-		PEPeerManager	pm = download_manager.getPeerManager();
-		
-		long	result = 0;
-		
-		if ( pm != null ){
-	
-			Iterator	it = pm.getPeers().iterator();
-		
-			while( it.hasNext()){
-				
-				result += ((PEPeer)it.next()).getStats().getDataReceiveRate();
-			}
-		}
-		
-		return( result );
-	}
-	
-	public boolean
-	supportsProgressiveMode()
-	{
-		TOTorrent	torrent = download_manager.getTorrent();
-		
-		if ( torrent == null ){
-			
-			return( false );
-		}
-		
-		return( enhancer.isProgressiveAvailable() && PlatformTorrentUtils.isContentProgressive( torrent ));
-	}
-	
-	public void
-	setProgressiveMode(
-		boolean		active )
-	{
-		setProgressiveMode( active, false );
-	}
-		
-	protected void
-	setProgressiveMode(
-		boolean		active,
-		boolean		switching_progressive_downloads )
-	{
-		TOTorrent	torrent = download_manager.getTorrent();
-		
-		if ( torrent == null ){
-
-			return;
-		}
-		
-		synchronized( this ){
-
-			if ( progressive_active == active ){
-				
-				return;
-			}			
-
-			if (active && !supportsProgressiveMode()) {
-				
-				Debug.out( "Attempt to set progress mode on non-progressible content - " + getName());
-				
-				return;
-			}
-			
-			log( "Progressive mode changed to " + active );
-
-			final GlobalManager gm = download_manager.getGlobalManager(); 
-			if (active) {
-				if (dmListener == null) {
-					dmListener = new DownloadManagerAdapter() {
-						public void downloadComplete(DownloadManager manager) {
-							gm.resumeDownloads();
-						}
-					};
-				}
-				download_manager.addListener(dmListener);
+			log( "Progressive mode changed to " + active );
+
+			final GlobalManager gm = download_manager.getGlobalManager(); 
+			if (active) {
+				if (dmListener == null) {
+					dmListener = new DownloadManagerAdapter() {
+						public void downloadComplete(DownloadManager manager) {
+							enhancer.resume();
+						}
+					};
+				}
+				download_manager.addListener(dmListener);
 				
 				// Check existing downloading torrents and turn off any
 				// existing progressive/downloading
@@ -1079,7 +383,7 @@ EnhancedDownloadManager
 						int state = dmCheck.getState();
 						if (state == DownloadManager.STATE_DOWNLOADING
 								|| state == DownloadManager.STATE_QUEUED) {
-							dmCheck.pause();
+							enhancer.pause( dmCheck );
 						}
 						EnhancedDownloadManager edmCheck = enhancer.getEnhancedDownload(dmCheck);
 						if (edmCheck != null && edmCheck.getProgressiveMode()) {
@@ -1088,7 +392,7 @@ EnhancedDownloadManager
 					}
 				}
 				if (download_manager.isPaused()) {
-					download_manager.resume();
+					enhancer.resume( download_manager );
 				}
 
 				// Make sure download can start by moving out of stop state
@@ -1103,33 +407,34 @@ EnhancedDownloadManager
 			} else {
 				download_manager.removeListener(dmListener);
 				if ( !switching_progressive_downloads ){
-					gm.resumeDownloads();
+					enhancer.resume();
 				}
 			}
 			
 			progressive_active	= active;
 
+			if ( progressive_active ){
+				
+				enhancer.progressiveActivated();
+			}
+			
 			if ( current_piece_pickler != null ){
 		
 				if ( progressive_active ){
 					
 					buffer_provider.activate( current_piece_pickler );
-					
-					boost_provider.activate( current_piece_pickler );
-					
+										
 					progressive_stats.update( 0 );
 					
 				}else{
 					
 					buffer_provider.deactivate( current_piece_pickler );
-					
-					boost_provider.deactivate( current_piece_pickler );
-					
-					progressive_stats = createProgressiveStats( download_manager, primary_file );
+										
+					progressive_stats = createProgressiveStats( download_manager, enhanced_file );
 				}
 			}else{
 				
-				progressive_stats = createProgressiveStats( download_manager, primary_file );
+				progressive_stats = createProgressiveStats( download_manager, enhanced_file );
 			}
 			
 			if ( !switching_progressive_downloads ){
@@ -1145,18 +450,7 @@ EnhancedDownloadManager
 			}
 		}
 		
-		if ( active && !progressive_informed ){
-			
-			progressive_informed	= true;
-			
-				// tell tracker we're progressive so it can, if required, schedule more seeds
-			
-			Download	plugin_dl = PluginCoreUtils.wrap( download_manager );
-			
-			DownloadUtils.addTrackerExtension( plugin_dl, TRACKER_PROG_PREFIX, "y" );
-			
-			download_manager.requestTrackerAnnounce( true );
-		}
+		return( true );
 	}
 
 
@@ -1169,16 +463,14 @@ EnhancedDownloadManager
 	public long
 	getProgressivePlayETA()
 	{
-		return( getProgressivePlayETA( false ));
-	}
-	
-	public long
-	getProgressivePlayETA(
-		boolean	ignore_min_buffer_size )
-	{
 		progressiveStats stats = getProgressiveStats();
 		
-		long	eta = stats.getETA( ignore_min_buffer_size );
+		if ( stats == null ){
+			
+			return( Long.MAX_VALUE );
+		}
+		
+		long	eta = stats.getETA();
 				
 		return( eta );
 	}
@@ -1188,6 +480,11 @@ EnhancedDownloadManager
 	{
 		synchronized( this ){
 			
+			if ( progressive_stats == null ){
+				
+				return( null );
+			}
+			
 			return( progressive_stats.getCopy());
 		}
 	}
@@ -1197,33 +494,23 @@ EnhancedDownloadManager
 		DownloadManager					dm,
 		EnhancedDownloadManagerFile		file )
 	{
-		TOTorrent torrent = download_manager.getTorrent();
-		
-		if ( torrent != null && PlatformTorrentUtils.useEMP( torrent )){
-			
-			return( new progressiveStatsInternal( dm, file ));
-			
-		}else{
-			
-			return( new progressiveStatsExternal( dm, file ));
-
-		}
+		return( new progressiveStatsCommon( dm, file ));
 	}
 	
-	protected void
+	protected boolean
 	updateProgressiveStats(
 		int		tick_count )
 	{
 		if ( !progressive_active ){
 			
-			return;
+			return( false );
 		}
 					
 		synchronized( this ){
 			
-			if ( !progressive_active ){
+			if ( !progressive_active || progressive_stats == null ){
 				
-				return;
+				return( false );
 			}			
 
 			if ( tick_count % REACTIVATE_PROVIDER_PERIOD_TICKS == 0 ){
@@ -1245,6 +532,8 @@ EnhancedDownloadManager
 				RealTimeInfo.setProgressiveActive( current_max );
 			}
 		}
+		
+		return( true );
 	}
 	
 	protected void
@@ -1274,34 +563,29 @@ EnhancedDownloadManager
 		}
 	}
 
-	public DiskManagerFileInfo
-	getPrimaryFile()
-	{
-		return( primary_file.getFile());
-	}
-
-	public long
-	getContiguousAvailableBytes(
-		DiskManagerFileInfo		file )
-	{
-		return( getContiguousAvailableBytes( file, 0 ));
-	}
-	
 	public long
 	getContiguousAvailableBytes(
-		DiskManagerFileInfo		file,
-		int						file_start_offset )
+		int						file_index,
+		long					file_start_offset,
+		long					stop_counting_after )
 	{
-		if ( file == null ) {
+		if ( file_index < 0 || file_index >= enhanced_files.length ) {
 
 			return( -1 );
 		}
 
+		EnhancedDownloadManagerFile	efile = enhanced_files[ file_index ];
+		
+		DiskManagerFileInfo file = efile.getFile();
+		
 		DiskManager dm = download_manager.getDiskManager();
 		
 		if ( dm == null ){
 			
-			// TODO: Check if file is complete.. if it is, return correct size
+			if ( file.getDownloaded() == file.getLength()){
+				
+				return( file.getLength() - file_start_offset );
+			}
 			
 			return( -1 );
 		}
@@ -1310,17 +594,8 @@ EnhancedDownloadManager
 		
 		DiskManagerFileInfo[]	 files = dm.getFiles();
 		
-		long	start_index = file_start_offset;
-		
-		for (int i=0;i<files.length;i++){
-			
-			if ( files[i].getIndex() == file.getIndex()){
-				
-				break;
-			}
-			
-			start_index += files[i].getLength();
-		}
+		long	start_index = efile.getByteOffestInTorrent() + file_start_offset;
+	
 		
 		int	first_piece_index 	= (int)( start_index / piece_size );
 		int	first_piece_offset	= (int)( start_index % piece_size );
@@ -1376,6 +651,11 @@ EnhancedDownloadManager
 		
 			for (int i=first_piece_index+1;i<=last_piece_index;i++){
 				
+				if ( stop_counting_after > 0 && available >= stop_counting_after ){
+					
+					break;
+				}
+				
 				DiskManagerPiece piece = pieces[i];
 				
 				if ( piece.isDone()){
@@ -1427,24 +707,6 @@ EnhancedDownloadManager
 	}
 	
 	
-	public void
-	setViewerPosition(
-		DiskManagerFileInfo 	file_info, 
-		long 					bytes)
-	{
-		if (file_info != null) {
-
-  		int	index = file_info.getIndex();
-  		
-  		if ( index < enhanced_files.length ){
-  			
-  			bytes += enhanced_files[index].getByteOffestInTorrent();
-  		}
-		}
-		
-		progressive_stats.setViewerBytePosition( bytes );
-	}
-	
 	public DownloadManager 
 	getDownloadManager() 
 	{
@@ -1483,7 +745,7 @@ EnhancedDownloadManager
 		String			str,
 		boolean			to_file )
 	{
-		str = dm.getDisplayName() + ": " + str;
+		str = dm.toString() + ": " + str;
 		
 		if ( to_file ){
 			
@@ -1503,51 +765,45 @@ EnhancedDownloadManager
 	bufferETAProvider
 		implements PieceRTAProvider
 	{
-		private long[]		piece_rtas;
+		private boolean		is_buffering	= true;
 		
-		private long		last_buffer_size;
-		private long		last_buffer_size_time;
+		private long[]		piece_rtas;
+				
+		private long				last_buffer_size;
+		private long				last_buffer_size_time;
 		
 		private boolean		active;
+		private long		last_recalc;
 		
 		protected void
 		activate(	
 			PiecePicker		picker )
 		{
-			log( "Activating buffer provider" );
-
 			synchronized( EnhancedDownloadManager.this ){
 
-				active = true;
-				
-				piece_rtas = new long[ picker.getNumberOfPieces()];
+				if ( !active ){
+
+					log( "Activating RTA provider" );
 				
-				long	now = SystemTime.getCurrentTime();
+					active = true;
 				
-				for (int i=0;i<piece_rtas.length;i++){
-					
-						// not bothered about times here but need to use large increments to ensure
-						// that pieces are picked in order even for slower peers
-					
-					piece_rtas[i] = now+(i*60000);
+					picker.addRTAProvider( this );
 				}
-
-				picker.addRTAProvider( this );
 			}
 		}
 		
 		protected void
 		deactivate(
 			PiecePicker		picker )
-		{
-			if ( active ){
-				
-   				log( "Deactivating buffer provider" );
-			}
-			
+		{			
 			synchronized( EnhancedDownloadManager.this ){
-									
-				picker.removeRTAProvider( this );
+		
+				if ( active ){
+					
+	   				log( "Deactivating RTA provider" );
+
+	   				picker.removeRTAProvider( this );
+				}
 				
 				piece_rtas	= null;
 				
@@ -1576,29 +832,82 @@ EnhancedDownloadManager
 		public long[]
     	updateRTAs(
     		PiecePicker		picker )
-    	{
-				// force linear downloading until we have enough to allow the user to 
-				// potentially start playing. If they don't do so immediately then until that
-				// time we'll be doing normal BT download
+    	{		
+			long	mono_now = SystemTime.getMonotonousTime();
+			
+			if ( mono_now - last_recalc < 500 ){
+				
+				return( piece_rtas );
+			}
 			
-    		DiskManager	dm = download_manager.getDiskManager();
+			last_recalc	= mono_now;
+								
+    		DiskManager	disk_manager = download_manager.getDiskManager();
 
-    		if ( dm != null ){
+    		progressiveStats stats = progressive_stats;
 
-    			if ( getProgressivePlayETA() <= 0 ){
-      				
-     				deactivate( picker );
-    			}
+    		EnhancedDownloadManagerFile file = stats.getFile();
+
+    		if ( disk_manager == null || stats == null || file.isComplete()){
+     				
+    			deactivate( picker );
+    			
+    			return( null );
     		}
     		
-    		long[]	rtas = piece_rtas;
-    		
-    		if ( rtas != null ){
-    		
-    			long	buffer_size = progressive_stats.getInitialBytesDownloaded();
-    			
-    			long	now = SystemTime.getCurrentTime();
-    			
+			long	abs_provider_pos = stats.getCurrentProviderPosition( true );
+ 			long	rel_provider_pos = stats.getCurrentProviderPosition( false );
+
+			long	buffer_bytes = stats.getBufferBytes();
+ 			
+  			boolean buffering = getProgressivePlayETA() >= 0;
+  			
+  			if ( buffering ){
+  				
+				long	 buffer_size = getContiguousAvailableBytes( file.getIndex(), rel_provider_pos, buffer_bytes );
+				
+				if ( buffer_size == buffer_bytes ){
+					
+					buffering = false;
+				}
+  			}
+  				
+  			if ( buffering != is_buffering ){
+  			
+  				if ( buffering ){
+  					
+  					log( "Switching to buffer mode" );
+  					
+  				}else{
+  					
+  					log( "Switching to RTA mode" );
+  				}
+  				
+  				is_buffering = buffering;
+  			}
+  			
+			long	piece_size = disk_manager.getPieceLength();
+			 			  		  
+			int		start_piece = (int)( abs_provider_pos / piece_size );
+
+			int		end_piece	= file.getFile().getLastPieceNumber();
+						
+			piece_rtas = new long[ picker.getNumberOfPieces()];
+
+			long	now = SystemTime.getCurrentTime();
+
+			if ( is_buffering ){
+								
+				for (int i=start_piece;i<=end_piece;i++){
+					
+						// not bothered about times here but need to use large increments to ensure
+						// that pieces are picked in order even for slower peers
+					
+					piece_rtas[i] = now+(i*60000);
+				}
+	
+				long	 buffer_size = getContiguousAvailableBytes( file.getIndex(), rel_provider_pos, 0 );
+     			    			
     			if ( last_buffer_size != buffer_size ){
     				
     				last_buffer_size = buffer_size;
@@ -1625,9 +934,9 @@ EnhancedDownloadManager
     						
    								long	target_rta = now + block_time;
    								
-   								int	blocked_piece_index = (int)( buffer_size / dm.getPieceLength());
+   								int	blocked_piece_index = (int)((abs_provider_pos + buffer_size ) / disk_manager.getPieceLength());
    								
-   								DiskManagerPiece[] pieces = dm.getPieces();
+   								DiskManagerPiece[] pieces = disk_manager.getPieces();
    								  								
    								if ( blocked_piece_index < pieces.length ){
    									  									
@@ -1649,23 +958,35 @@ EnhancedDownloadManager
    								}
    								
    								if ( blocked_piece_index >= 0 ){
-   									
-   									long	existing_rta = rtas[blocked_piece_index];
-   									
-   									if ( target_rta < existing_rta ){
+   									  										
+   									piece_rtas[blocked_piece_index] = target_rta;
    										
-   										rtas[blocked_piece_index] = target_rta;
-   										
-   										log( "Buffer provider: reprioritising lagging piece " + blocked_piece_index + " with rta " + block_time );
-   									}
+   									log( "Buffer provider: reprioritising lagging piece " + blocked_piece_index + " with rta " + block_time );
    								}
    							}
    						}
     				}
     			}
+    		}else{
+    			
+				long	bytes_offset = 0;
+				
+				long	max_bps = stats.getStreamBytesPerSecondMax();
+								
+				for (int i=start_piece;i<=end_piece;i++){
+										
+					piece_rtas[i] = now + ( 1000 * ( bytes_offset / max_bps ));
+					
+					bytes_offset += piece_size;		
+					
+					if ( bytes_offset > buffer_bytes ){
+							
+						break;
+					}
+				}
     		}
-    		
-    		return( rtas );
+    	
+    		return( piece_rtas );
     	}
     	
     	public long
@@ -1694,7 +1015,8 @@ EnhancedDownloadManager
 		
     	public void
     	setBufferMillis(
-			long	seconds )
+			long	millis,
+			long	delay_millis )
 		{
 		}
     	
@@ -1705,729 +1027,177 @@ EnhancedDownloadManager
 		}
 	}
 	
-	protected class
-	boostETAProvider
-		implements PieceRTAProvider
+	protected abstract class
+	progressiveStats
+		implements Cloneable
 	{
-		private long[]		piece_rtas;
+		protected abstract EnhancedDownloadManagerFile 
+		getFile();
 		
-		private long		last_recalc;
+		protected abstract boolean
+		isProviderActive();
+			
+		protected abstract long
+		getCurrentProviderPosition(
+			boolean		absolute );
 		
-		private int			aggression;
+		protected abstract long
+		getStreamBytesPerSecondMax();
 		
-		private boolean		active;
+		protected abstract long
+		getStreamBytesPerSecondMin();
 		
-		private interventionHandler		intervention_handler = new interventionHandler();
+		protected abstract long
+		getDownloadBytesPerSecond();
 		
-		private long					last_intervention;
+		protected abstract long
+		getETA();
+			
+		public abstract long
+		getBufferBytes();
 		
-		protected void
-		activate(	
-			PiecePicker		picker )
-		{
-			if ( supportsProgressiveMode()){
-				
-				log( "Activating boost provider" );
-
-				synchronized( EnhancedDownloadManager.this ){
-					
-					intervention_handler.activate();
-					
-					active	= true;
-					
-					picker.addRTAProvider( this );
-				}
-			}
-		}
+		protected abstract long
+		getSecondsToDownload();
 		
-		protected void
-		deactivate(
-			PiecePicker		picker )
+		protected abstract long
+		getSecondsToWatch();
+
+		protected abstract void
+		update(
+			int	tick_count );
+				
+		protected progressiveStats
+		getCopy()
 		{
-			if ( active ){
-			
-				log( "Deactivating boost provider" );
-			}
-			
-			synchronized( EnhancedDownloadManager.this ){
-									
-				picker.removeRTAProvider( this );
+			try{
+				return((progressiveStats)clone());
 				
-				piece_rtas	= null;
+			}catch( CloneNotSupportedException e ){
 				
-				active = false;
+				Debug.printStackTrace(e);
 				
-				intervention_handler.deactivate();
+				return( null );
 			}
 		}
 		
-		public long[]
-    	updateRTAs(
-    		PiecePicker		picker )
-    	{
-			long	now = SystemTime.getCurrentTime();
-			
-			if ( now < last_recalc || now - last_recalc > 1000 ){
-				
-				last_recalc	= now;
-								
-				DiskManager	disk_manager = download_manager.getDiskManager();
+		protected String
+		formatBytes(
+			long	l )
+		{
+			return( DisplayFormatters.formatByteCountToKiBEtc( l ));
+		}
+		
+		protected String
+		formatSpeed(
+			long	l )
+		{
+			return( DisplayFormatters.formatByteCountToKiBEtcPerSec( l ));
+		}
+
+	}
+	
+	protected class
+	progressiveStatsCommon
+		extends progressiveStats
+	{
+		private EnhancedDownloadManagerFile	primary_file;
+		
+		private PieceRTAProvider	current_provider;
+		private String				current_user_agent;
+		
+		private long	content_stream_bps_min;
+		private long	content_stream_bps_max;
+
 
-					// if it'll take less time to download than watch then the channel-based rta logic
-					// will do the job.
+		private Average		capped_download_rate_average 	= AverageFactory.MovingImmediateAverage( 10 );
+		private Average		discard_rate_average 			= AverageFactory.MovingImmediateAverage( 10 );
+		private long		last_discard_bytes				= download_manager.getStats().getDiscarded();
+		
+		private long		actual_bytes_to_download;
+		private long		weighted_bytes_to_download;		// gives less weight to incomplete pieces
+		
+		private long		provider_life_secs;
+		private long		provider_initial_position;
+		private long		provider_byte_position;
+		private long		provider_last_byte_position	= -1;
+		private long		provider_blocking_byte_position;
+		private Average		provider_speed_average	= AverageFactory.MovingImmediateAverage( 10 );
+				
+		protected
+		progressiveStatsCommon(
+			DownloadManager					_dm,
+			EnhancedDownloadManagerFile		_primary_file )
+		{		
+			primary_file = _primary_file;
+			
+			TOTorrent	torrent = download_manager.getTorrent();
+						
+			content_stream_bps_min = explicit_progressive?content_min_delivery_bps:PlatformTorrentUtils.getContentStreamSpeedBps( torrent );
+			
+			if ( content_stream_bps_min == 0 ){
+			
+					// hack in some test values for torrents that don't have a bps in them yet
 				
-				progressiveStats	stats = getProgressiveStats();
+				long	size = torrent.getSize();
 				
-				long	max_bps = stats.getStreamBytesPerSecondMax();
+				if ( size < 200*1024*1024 ){
 				
-								
-				if ( 	disk_manager == null || 
-						!stats.isProviderActive() || 
-						stats.getETA(false) < -MINIMUM_INITIAL_BUFFER_SECS ||
-						max_bps == 0 ){
+					content_stream_bps_min = 30*1024;
 					
-					if ( piece_rtas != null ){
-						
-						log( "Suspending boost provider" );
-					}
+				}else if ( size < 1000*1024*1024L ){
 					
-					piece_rtas = null;
+					content_stream_bps_min = 200*1024;
 					
 				}else{
+
+					content_stream_bps_min = 400*1024;
+				}
+			}
+				
+				// bump it up by a bit to be conservative to deal with fluctuations, discards etc.
+				
+			content_stream_bps_min += content_stream_bps_min / content_stream_bps_min_increase_ratio;
+			
+			content_stream_bps_max = content_stream_bps_min + ( content_stream_bps_min / content_stream_bps_max_increase_ratio );
+			
+			setRTA( false );
+			
+			log( 	download_manager,
+					"content_stream_bps=" + getStreamBytesPerSecondMin() +
+					",primary=" + primary_file.getFile().getIndex(),
+					true );
+		}
 	
-					if ( piece_rtas == null ){
 						
-						log( "Resuming boost provider" );
-					}
+		protected void
+		updateCurrentProvider(
+			PieceRTAProvider	provider )
+		{
+			long	file_start = primary_file.getByteOffestInTorrent();
 
-					long[] local_rtas = piece_rtas = new long[disk_manager.getNbPieces()];
+			if ( current_provider != provider || provider == null ){
+				
+				current_provider 	= provider;
+				current_user_agent	= null;
+								
+				provider_speed_average	= AverageFactory.MovingImmediateAverage( 10 );
+				
+				if ( current_provider == null ){
 					
-						// need to force piece order - set RTAs for all outstanding pieces
+					provider_life_secs					= 0;
+					provider_initial_position			= file_start;
+					provider_byte_position				= file_start;
+					provider_blocking_byte_position		= -1;
+					provider_last_byte_position 		= -1;
 					
-					long	piece_size = disk_manager.getPieceLength();
+				}else{
 					
-					int		start_piece = (int)( stats.getBytePosition() / piece_size );
-						
-					long	bytes_offset = 0;
+					provider_initial_position	= Math.max( file_start, current_provider.getStartPosition());
 					
-						// we need to be more aggresive if we have an explicit min buffer size
-						// as the emp will auto-pause when the contiguous available bytes falls
-						// below this min
-				
-					int	last_aggressive_piece = -1;
+					provider_byte_position 		= provider_initial_position;
+					provider_last_byte_position	= provider_initial_position;
 					
-					long	time_to_stall = 0;
-					
-					if ( explicit_minimum_buffer_bytes > 0 ){
-				
-						long total_avail = getContiguousAvailableBytes( getPrimaryFile());
-						
-						long viewer_pos = stats.getViewerBytePosition();
-						
-						long avail = total_avail - viewer_pos;
-						
-						time_to_stall =  ( avail - explicit_minimum_buffer_bytes )*1000/max_bps;
-						
-						long	buffer_zone = 3*explicit_minimum_buffer_bytes;
-						
-						if ( avail <= buffer_zone ){
-							
-							if ( avail < 0 ){
-								
-								avail = 0;
-							}
-							
-							if ( avail <= explicit_minimum_buffer_bytes ){
-								
-								aggression = 10;
-								
-							}else{		
-								
-								aggression =  (int)( ( buffer_zone - avail )*10/( buffer_zone - explicit_minimum_buffer_bytes ));
-							}
-							
-							last_aggressive_piece = start_piece + (int)(( buffer_zone + piece_size -1 ) / piece_size);
-							
-						}else{
-							
-							aggression = 0;
-						}
-					}else{
-						
-						aggression = 0;
-					}
-					
-					DiskManagerPiece[] dm_pieces = disk_manager.getPieces();
-					
-					for ( int i=start_piece;i<local_rtas.length;i++ ){
-						
-						int	time_factor;
-						
-						if ( i <= last_aggressive_piece ){
-							
-							time_factor = (( 10 - aggression ) * 1000 ) /10;
-								
-							time_factor = Math.max( time_factor, 10 );
-								
-							if ( aggression >= 7 && !dm_pieces[i].isDone() && time_to_stall <= 10*1000 ){
-					
-								if ( now < last_intervention || now - last_intervention >= 500 ){
-									
-									last_intervention	= now;
-									
-									/*
-									long total_avail = getContiguousAvailableBytes( getPrimaryFile());								
-									long viewer_pos = stats.getViewerBytePosition();
-									long avail = total_avail - viewer_pos;
-									long	buffer_zone = 3*explicit_minimum_buffer_bytes;
-									
-									System.out.println( "Aggression = " + aggression + ", time factor=" + time_factor + ", stall=" + time_to_stall + ", avail=" + avail + ", buffer=" + buffer_zone );
-									*/
-									
-									intervention_handler.addPiece( i, SystemTime.getCurrentTime() + time_to_stall );
-								}
-							}
-						}else{
-							
-							time_factor = 1000;
-						}
-						
-						local_rtas[i] = now + ( time_factor* ( bytes_offset / max_bps ));
-						
-						bytes_offset += piece_size;					
-					}
-				}
-			}
-    		
-    		return( piece_rtas );
-    	}
-		
-	   	public long
-    	getCurrentPosition()
-    	{
-    		return( 0 );
-    	}
-    	
-		public long
-		getBlockingPosition()
-		{
-			return( 0 );
-		}
-		
-	  	public long
-	   	getStartTime()
-	   	{
-	   		return( 0 );
-	   	}
-	   	
-	   	public long
-	   	getStartPosition()
-	   	{
-	   		return( 0 );
-	   	}
-	   	
-		public void
-		setBufferMillis(
-			long	seconds )
-		{
-		}
-		
-		public String
-		getUserAgent()
-		{
-			return( null );
-		}
-		
-		protected class
-		interventionHandler
-		{
-			private AEThread2 		thread;
-			private AESemaphore		request_sem;
-			private List			request_list;
-			
-			private List			http_peers;
-			
-			private boolean	borked;
-			
-			protected void
-			activate()
-			{
-				synchronized( this ){
-					
-					active	= true;
-				}
-			}
-			
-			protected void
-			deactivate()
-			{
-				synchronized( this ){
-					
-					active	= false;
-					
-					if ( thread != null ){
-						
-						thread			= null;
-						request_list	= null;
-						
-						request_sem.release();
-					}
-				}
-			}
-			
-			protected void
-			addPiece(
-				int		piece_number,
-				long	stall_time )
-			{
-				synchronized( this ){
-
-					if ( !active || borked ){
-						
-						return;
-					}
-					
-					if ( thread == null ){
-						
-						PluginInterface pi = enhancer.getCore().getPluginManager().getPluginInterfaceByClass( ExternalSeedPlugin.class );
-
-						if ( pi == null ){
-							
-							borked = true;
-							
-							return;
-						}
-						
-						ExternalSeedPlugin ext_seed = (ExternalSeedPlugin)pi.getPlugin();
-						
-						ExternalSeedManualPeer[] peers = ext_seed.getManualWebSeeds( PluginCoreUtils.wrap( download_manager ));
-						
-						http_peers = null;
-						
-						for ( int i=0;i<peers.length;i++ ){
-							
-							ExternalSeedManualPeer peer = peers[i];
-							
-							if ( PeerClassifier.isAzureusIP( peer.getIP())){
-								
-								if ( http_peers == null ){
-									
-									http_peers = new ArrayList();
-								}
-								
-								http_peers.add( peer );;
-							}
-						}
-						
-						request_sem		= new AESemaphore( "EDH:intervention" );
-						request_list	= new ArrayList();
-						
-						thread = 
-							new AEThread2( "EDH:intervention", true )
-							{
-								private AESemaphore	my_sem	= request_sem;
-								private List		my_list	= request_list;
-								
-								private ExternalSeedManualPeer	current_peer;
-								
-								public void
-								run()
-								{
-									while( true ){
-										
-										my_sem.reserve();
-										
-										int		piece_number;
-										long	stall_time;
-										
-										synchronized( interventionHandler.this ){
-											
-											if ( my_list.isEmpty()){
-												
-												break;
-											}
-											
-												// leave on list and remove later to prevent
-												// duplicates being queued during intervention
-											
-											long[]	entry = (long[])my_list.get(0);
-											
-											piece_number 	= (int)entry[0];
-											stall_time		= entry[1];
-										}
-										
-										try{
-
-											int remaining = (int)( stall_time - SystemTime.getCurrentTime());
-												
-											if ( remaining < 500 ){
-											
-													// no point trying to do anything, too late
-												
-												continue;
-											}
-
-											DiskManager		disk_manager = download_manager.getDiskManager();
-											PEPeerManager 	peer_manager = download_manager.getPeerManager();
-
-											if ( disk_manager == null || peer_manager == null ){
-												
-												continue;
-											}
-											
-											DiskManagerPiece dm_piece = disk_manager.getPiece( piece_number );
-												
-											if ( dm_piece.isDone()){
-												
-												continue;
-											}
-												
-											List http = http_peers;
-																					
-											if ( current_peer == null ){
-												
-												if ( http == null && http.size() == 0 ){
-
-													continue;
-												}
-												
-												current_peer = (ExternalSeedManualPeer)http.remove(0);
-											}
-											
-											PEPiece pe_piece = peer_manager.getPiece( piece_number );
-											
-											boolean[]	to_do = new boolean[dm_piece.getNbBlocks()];
-											
-											if ( pe_piece == null ){
-												
-												boolean[] written = dm_piece.getWritten();
-											
-												if ( written == null ){
-													
-													Arrays.fill( to_do, true );
-													
-												}else{
-													
-													for (int i=0;i<to_do.length;i++){
-														
-														if ( !written[i] ){
-														
-															to_do[i] = true;
-														}
-													}
-												}
-											}else{
-												
-												boolean[] downloaded = pe_piece.getDownloaded();
-												
-												for (int i=0;i<to_do.length;i++){
-													
-													if ( !downloaded[i] ){
-													
-														to_do[i] = true;
-													}
-												}
-											}
-											
-											int	block_pos = 0;
-											
-											while( true ){
-											
-												int	block_start 		= 0;
-												int block_num			= 0;
-												
-												while( block_pos < to_do.length ){
-													
-													if ( to_do[ block_pos ] ){
-														
-														if ( block_num == 0 ){
-															
-															block_start = block_pos;
-														}
-														
-														block_num++;
-														
-													}else{
-														
-														if ( block_num > 0 ){
-															
-															break;
-														}
-													}
-													
-													block_pos++;
-												}
-													
-												if ( block_num == 0 ){
-														
-													break;
-												}
-												
-												int	block_start_offset 	= 0;
-												int blocks_length		= 0;
-												
-												for (int i=0;i<block_start+block_num;i++){
-													
-													int	block_size = dm_piece.getBlockSize( i );
-													
-													if ( i < block_start ){
-													
-														block_start_offset += block_size;
-														
-													}else{
-														
-														blocks_length += block_size;
-													}
-												}
-												
-												PeerManager pm = PluginCoreUtils.wrap( peer_manager );
-												
-												while( current_peer != null ){
-													
-													log( "Intervention: peer=" + current_peer.getIP() + ", piece=" + piece_number + ", block_start=" + block_start + ", block_num=" + block_num + ", offset=" + block_start_offset + ", length=" + blocks_length + ", rem=" + remaining );
-													
-													try{
-														byte[] data = current_peer.read( piece_number, block_start_offset, blocks_length, remaining );
-														
-														int	data_offset = 0;
-														
-														for (int i=block_start;i<block_start+block_num;i++){
-															
-															int	block_size = dm_piece.getBlockSize( i );
-															
-															byte[] data_slice = new byte[ block_size ];
-															
-															System.arraycopy( data, data_offset, data_slice, 0, block_size );
-															
-															log( "    Read block " + i + ", offset=" + data_offset + ", length=" + block_size );
-															
-															pm.requestComplete(
-																	disk_manager.createReadRequest( piece_number, block_start_offset + data_offset, block_size ),
-																	new PooledByteBufferImpl( data_slice ),
-																	current_peer.getDelegate());
-															
-															data_offset += block_size;
-														}
-																					
-														break;
-											
-													}catch( Throwable e ){
-											
-														if ( !( e instanceof ExternalSeedException )){
-															
-															Debug.printStackTrace( e );
-														}
-														
-														if ( http != null && http.size()> 0 ){
-														
-															current_peer = (ExternalSeedManualPeer)http.remove(0);
-
-														}else{
-														
-															current_peer = null;
-														}
-													}
-												}
-											}
-										}finally{
-											
-											synchronized( interventionHandler.this ){
-												
-												my_list.remove(0);
-											}
-										}
-									}
-								}
-							};
-							
-						thread.start();
-					}
-								
-						// don't let intervention stray too far into future
-					
-					if ( 	request_list.isEmpty() ||
-							piece_number < ((long[])request_list.get(0))[0] + 10 ){
-							
-						if ( request_list.size() < 5 ){
-							
-							boolean	found = false;
-							
-							for (int i=0;i<request_list.size();i++){
-								
-								long[]	entry = (long[])request_list.get(i);
-								
-								if ( entry[0] == piece_number ){
-									
-									found = true;
-									
-									entry[1] = Math.min( stall_time, entry[1] );
-								}
-							}
-							
-							if ( !found ){
-								
-								log( "Intervention: queueing piece " + piece_number + ", stall_time=" + ( stall_time - SystemTime.getCurrentTime()));
-								
-								request_list.add( new long[]{ piece_number, stall_time });
-								
-								request_sem.release();
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-	
-	protected abstract class
-	progressiveStats
-		implements Cloneable
-	{
-		protected abstract boolean
-		isProviderActive();
-		
-		protected abstract long
-		getBytePosition();
-		
-		protected abstract long
-		getStreamBytesPerSecondMax();
-		
-		protected abstract long
-		getStreamBytesPerSecondMin();
-
-		protected abstract long
-		getInitialBytesDownloaded();
-		
-		protected abstract long
-		getDownloadBytesPerSecond();
-		
-		protected abstract long
-		getETA(
-			boolean	ignore_min_buffer_size );
-		
-		protected abstract void
-		setViewerBytePosition(
-			long		bytes );
-		
-		protected abstract long
-		getViewerBytePosition();
-		
-		protected abstract void
-		update(
-			int	tick_count );
-		
-		protected abstract void
-		refreshMetaData();
-		
-		protected progressiveStats
-		getCopy()
-		{
-			try{
-				return((progressiveStats)clone());
-				
-			}catch( CloneNotSupportedException e ){
-				
-				Debug.printStackTrace(e);
-				
-				return( null );
-			}
-		}
-		
-		protected String
-		formatBytes(
-			long	l )
-		{
-			return( DisplayFormatters.formatByteCountToKiBEtc( l ));
-		}
-		
-		protected String
-		formatSpeed(
-			long	l )
-		{
-			return( DisplayFormatters.formatByteCountToKiBEtcPerSec( l ));
-		}
-
-	}
-	
-	protected abstract class
-	progressiveStatsCommon
-		extends progressiveStats
-	{
-		private PieceRTAProvider	current_provider;
-		private String				current_user_agent;
-		
-		protected long		total_file_length = download_manager.getSize();
-
-
-		private Average		capped_download_rate_average 	= AverageFactory.MovingImmediateAverage( 10 );
-		private Average		discard_rate_average 			= AverageFactory.MovingImmediateAverage( 10 );
-		private long		last_discard_bytes				= download_manager.getStats().getDiscarded();
-		
-		private long		actual_bytes_to_download;
-		private long		weighted_bytes_to_download;
-		
-		private long		provider_life_secs;
-		private long		provider_initial_position;
-		private long		provider_byte_position;
-		private long		provider_last_byte_position	= -1;
-		private long		provider_blocking_byte_position;
-		private Average		provider_speed_average	= AverageFactory.MovingImmediateAverage( 10 );
-		
-		private long		last_eta	= -1;
-		
-		protected
-		progressiveStatsCommon(
-			DownloadManager					dm,
-			EnhancedDownloadManagerFile		primary_file )
-		{
-			calculateSpeeds( dm, primary_file );
-			
-			setRTA( false );
-			
-			log( 	download_manager,
-					"content_stream_bps=" + getStreamBytesPerSecondMin() +
-					",primary=" + (primary_file==null?"null":primary_file.getString()),
-					true );
-		}
-	
-		protected void
-		refreshMetaData()
-		{
-			calculateSpeeds( download_manager, primary_file );
-		}
-		
-		protected abstract void
-		calculateSpeeds(
-			DownloadManager					 dm,
-			EnhancedDownloadManagerFile		primary_file );
-				
-		protected void
-		updateCurrentProvider(
-			PieceRTAProvider	provider )
-		{
-			if ( current_provider != provider || provider == null ){
-				
-				current_provider 	= provider;
-				current_user_agent	= null;
-				
-				provider_speed_average	= AverageFactory.MovingImmediateAverage( 10 );
-				
-				if ( current_provider == null ){
-					
-					provider_life_secs					= 0;
-					provider_initial_position			= 0;
-					provider_byte_position				= 0;
-					provider_blocking_byte_position		= 0;
-					provider_last_byte_position 		= -1;
-					
-				}else{
-					
-					provider_initial_position	= current_provider.getStartPosition();
-					
-					provider_byte_position 		= provider_initial_position;
-					provider_last_byte_position	= provider_initial_position;
-					
-					provider_blocking_byte_position		= current_provider.getBlockingPosition();
+					provider_blocking_byte_position		= current_provider.getBlockingPosition();
 					
 					provider_life_secs = ( SystemTime.getCurrentTime() - current_provider.getStartTime()) / 1000;
 					
@@ -2453,7 +1223,7 @@ EnhancedDownloadManager
 					}
 				}
 				
-				provider_byte_position	= current_provider.getCurrentPosition();
+				provider_byte_position			= Math.max( file_start, current_provider.getCurrentPosition());
 				provider_blocking_byte_position	= current_provider.getBlockingPosition();
 				
 				long bytes_read = provider_byte_position - provider_last_byte_position;
@@ -2477,9 +1247,28 @@ EnhancedDownloadManager
 		}
 		
 		protected long
-		getProviderBytePosition()
+		getCurrentProviderPosition(
+			boolean		absolute )
 		{
-			return( provider_byte_position );
+			long	res = provider_byte_position;
+			
+			if ( absolute ){
+				
+				if ( res == 0 ){
+					
+					res = primary_file.getByteOffestInTorrent();
+				}
+			}else{
+				
+				res -= primary_file.getByteOffestInTorrent();
+				
+				if ( res < 0 ){
+					
+					res = 0;
+				}
+			}
+			
+			return( res );
 		}
 		
 		protected long
@@ -2532,27 +1321,23 @@ EnhancedDownloadManager
 				}
 
 				updateCurrentProvider( best_provider );
-				
-				// System.out.println( "prov_ini=" + provider_initial_position + ", life=" + provider_life_secs + ", pos=" + provider_byte_position );
-				
-				updateViewerPosition();
-				
+												
 				if ( best_provider != null ){
-							
-						// only report buffer if we have a bit of slack
+								
+						// the file channel provider will try best-effort-RTA based which will result
+						// in high discard - back it off based on how much slack we have 
 					
-					long	buffer_secs = getViewerBufferSeconds();
+					long relative_pos = getCurrentProviderPosition( false );
 					
-					if ( buffer_secs < 10 ){
-						
-							// no point in having a very small buffer as we end up with
-							// too much discard. Given we're doing a long-term stream here the
-							// aggressiveness applied when rta gets close to "now" isn't needed
-						
-						buffer_secs = 10;
-					}
+					long buffer_bytes = getContiguousAvailableBytes( primary_file.getIndex(), relative_pos, getStreamBytesPerSecondMin() * 60 );
+					
+					long buffer_secs = buffer_bytes / getStreamBytesPerSecondMin();
 					
-					best_provider.setBufferMillis( buffer_secs * 1000 );
+						// don't be too aggresive with small buffers
+					
+					buffer_secs = Math.max( 10, buffer_secs );
+					
+					best_provider.setBufferMillis( 15*1000, buffer_secs * 1000 );
 				}
 				
 				DiskManagerPiece[] pieces = disk_manager.getPieces();
@@ -2564,322 +1349,102 @@ EnhancedDownloadManager
 				
 				int	piece_size = disk_manager.getPieceLength();
 				
-				for (int i=(int)(provider_byte_position/piece_size);i<pieces.length;i++){
+				int	last_piece_number = primary_file.getFile().getLastPieceNumber();
+				
+				for (int i=(int)(provider_byte_position/piece_size);i<=last_piece_number;i++){
 					
 					DiskManagerPiece piece = pieces[i];
 					
 					if ( piece.isDone()){
 						
 						continue;
-					}
-					
-					if ( first_incomplete_piece == -1 ){
-						
-						first_incomplete_piece = i;
-					}
-					
-					boolean[] blocks = piece.getWritten();
-					
-					int	bytes_this_piece = 0;
-					
-					if ( blocks == null ){
-						
-						bytes_this_piece = piece.getLength();
-						
-					}else{
-						for (int j=0;j<blocks.length;j++){
-							
-							if ( !blocks[j] ){
-								
-								bytes_this_piece += piece.getBlockSize( j );
-							}
-						}
-					}
-					
-					if ( bytes_this_piece > 0 ){
-						
-						actual_bytes_to_download += bytes_this_piece;
-						
-						int	diff = i - first_incomplete_piece;
-						
-						if ( diff == 0 ){
-							
-							weighted_bytes_to_download += bytes_this_piece;
-							
-						}else{
-														
-							int	weighted_bytes_done =  piece.getLength() - bytes_this_piece;
-						
-							weighted_bytes_done = ( weighted_bytes_done * ( pieces.length - i )) / (pieces.length - first_incomplete_piece);
-						
-							weighted_bytes_to_download += piece.getLength() - weighted_bytes_done;
-						}
-					}
-				}
-			}
-			
-			log( getString(), tick_count % LOG_PROG_STATS_TICKS == 0 );
-		}
-		
-		protected abstract void
-		updateViewerPosition();
-		
-		protected abstract long
-		getInitialBufferBytes(
-			long		dl_rate,
-			boolean		ignore_min_buffer_size );
-		
-		protected long
-		getETA(
-			boolean ignore_min_buffer_size )
-		{
-			DiskManager dm = download_manager.getDiskManager();
-			
-			if ( dm == null ){
-				
-				return( Long.MAX_VALUE );
-			}
-			
-			if ( dm.getRemainingExcludingDND() == 0 ){
-				
-				return( 0 );
-			}
-			
-			long download_rate = getDownloadBytesPerSecond();
-			
-			if ( download_rate <= 0 ){
-				
-				return( Long.MAX_VALUE );
-			}
-			
-			final long	min_dl	= getInitialBufferBytes( download_rate, ignore_min_buffer_size );
-			
-			long	initial_downloaded	= getInitialBytesDownloaded( min_dl );
-			
-			long rem_dl = min_dl - initial_downloaded;	// ok as initial dl is forced in order byte buffer-rta
-			
-			long rem_secs = rem_dl / download_rate;
-			
-			long	secs_to_download = getSecondsToDownload();
-			
-				// increase time to download a bit so we don't start streaming too soon
-				// we'll always lose time due to speed variations, discards, hashfails...
-			
-			secs_to_download = secs_to_download + (secs_to_download/10);
-			
-			long	secs_to_watch = getSecondsToWatch();
-			
-			long eta = secs_to_download - secs_to_watch;
-			
-			if ( rem_secs > eta ){
-				
-				eta = rem_secs;
-			}
-			
-			if ( !ignore_min_buffer_size ){
-				
-				if ( eta == 0 && last_eta != 0 ){
-					
-					last_eta = eta;
-					
-					log( "ETA=0: rate=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( download_rate ) +
-							",init_buff=" + min_dl +",to_dl=" + secs_to_download + ",to_watch=" + secs_to_watch );
-				}
-			}
-			
-			return( eta );
-		}
-	
-		public long
-		getInitialBytesDownloaded()
-		{
-			return( getInitialBytesDownloaded( Long.MAX_VALUE ));
-		}
-		
-		protected long 
-		getDownloadBytesPerSecond() 
-		{
-			long	original = (long)capped_download_rate_average.getAverage();
-			
-			long	current	= original;
-			
-			int	dl_limit = download_manager.getStats().getDownloadRateLimitBytesPerSecond();
-			
-			if ( dl_limit > 0 ){
-				
-				current = Math.min( current, dl_limit );
-			}
-			
-			int global_limit = TransferSpeedValidator.getGlobalDownloadRateLimitBytesPerSecond();
-			
-			if ( global_limit > 0 ){
-				
-				current = Math.min( current, global_limit );
-			}
-						
-			return( current );
-		}
-		
-		public long
-		getInitialBytesDownloaded(
-			long	stop_counting_after )
-		{
-			DiskManager dm = download_manager.getDiskManager();
-	
-			if ( dm == null ){
-				
-				return( 0 );
-			}
-			
-			long	initial_downloaded = 0;
-			
-			DiskManagerPiece[] pieces = dm.getPieces();
-			
-			for (int i=0;i<pieces.length;i++){
-				
-				DiskManagerPiece piece = pieces[i];
-				
-				if ( piece.isDone()){
+					}
 					
-					initial_downloaded += piece.getLength();
+					if ( first_incomplete_piece == -1 ){
+						
+						first_incomplete_piece = i;
+					}
 					
-				}else{
-								
 					boolean[] blocks = piece.getWritten();
-								
+					
+					int	bytes_this_piece = 0;
+					
 					if ( blocks == null ){
 						
-						break;
+						bytes_this_piece = piece.getLength();
 						
 					}else{
-						
 						for (int j=0;j<blocks.length;j++){
-						
-							if ( blocks[j] ){
-								
-								initial_downloaded += piece.getBlockSize( j );
-								
-							}else{
+							
+							if ( !blocks[j] ){
 								
-								break;
+								bytes_this_piece += piece.getBlockSize( j );
 							}
 						}
-						
-						break;
 					}
-				}
-									
-				if ( initial_downloaded >= stop_counting_after ){
+					
+					if ( bytes_this_piece > 0 ){
 						
-					break;
+						actual_bytes_to_download += bytes_this_piece;
+						
+						int	diff = i - first_incomplete_piece;
+						
+						if ( diff == 0 ){
+							
+							weighted_bytes_to_download += bytes_this_piece;
+							
+						}else{
+														
+							int	weighted_bytes_done =  piece.getLength() - bytes_this_piece;
+						
+							weighted_bytes_done = ( weighted_bytes_done * ( pieces.length - i )) / (pieces.length - first_incomplete_piece);
+						
+							weighted_bytes_to_download += piece.getLength() - weighted_bytes_done;
+						}
+					}
 				}
 			}
 			
-			return( initial_downloaded );
+			log( getString(), tick_count % LOG_PROG_STATS_TICKS == 0 );
 		}
-		
+						
 		protected long
-		getSecondsToDownload()
+		getETA()
 		{
+			DiskManagerFileInfo file = primary_file.getFile();
+			
+			if ( file.getLength() == file.getDownloaded()){
+				
+				return( 0 );
+			}
+			
 			long download_rate = getDownloadBytesPerSecond();
-
-			if ( download_rate == 0 ){
+			
+			if ( download_rate <= 0 ){
 				
 				return( Long.MAX_VALUE );
 			}
 			
-			return( weighted_bytes_to_download / download_rate );
-		}
-		
-		protected long
-		getSecondsToWatch()
-		{
-			return((total_file_length - getViewerBytePosition()) / getStreamBytesPerSecondMin());
-		}
-		
-		protected long
-		getBytePosition()
-		{
-			return( getViewerBytePosition());
-		}
-				
-		protected long
-		getViewerBufferSeconds()
-		{
-			return((provider_byte_position - getViewerBytePosition() ) / getStreamBytesPerSecondMax() );
-		}
-				
-		protected String
-		getString()
-		{
-			long	dl_rate = getDownloadBytesPerSecond();
+			long	buffer_bytes	= getBufferBytes();
 			
-			long	init_bytes = getInitialBufferBytes(dl_rate,false);
+			long	buffer_done		= getContiguousAvailableBytes( file.getIndex(), getCurrentProviderPosition( false ), buffer_bytes );
 			
-			return( "play_eta=" + getETA(false) + "/d=" + getSecondsToDownload() + "/w=" + getSecondsToWatch()+ 
-					", dl_rate=" + formatSpeed(dl_rate)+ ", download_rem=" + formatBytes(weighted_bytes_to_download) + "/" + formatBytes(actual_bytes_to_download) +
-					", discard_rate=" + formatSpeed((long)discard_rate_average.getAverage()) +
-					", init_done=" + getInitialBytesDownloaded(init_bytes) + ", init_buff=" + init_bytes +
-					", viewer: byte=" + formatBytes( getViewerBytePosition()) + " secs=" + ( getViewerBytePosition()/getStreamBytesPerSecondMin() ) + 
-					", prov: byte=" + formatBytes( provider_byte_position ) + " secs=" + ( provider_byte_position/getStreamBytesPerSecondMin()) + " speed=" + formatSpeed((long)provider_speed_average.getAverage()) +
-					" block= " + formatBytes( provider_blocking_byte_position ) + " buffer=" + formatBytes( provider_byte_position - getViewerBytePosition() ) + "/" + getViewerBufferSeconds());
-		}
-	}
-
-	protected class
-	progressiveStatsExternal
-		extends progressiveStatsCommon
-	{
-		private long	content_stream_bps_min;
-		private long	content_stream_bps_max;
-
-		private long	viewer_byte_position;
-		
-		protected
-		progressiveStatsExternal(
-			DownloadManager					download_manager,
-			EnhancedDownloadManagerFile		primary_file )
-		{
-			super( download_manager, primary_file );
-		}
-		
-		protected void
-		calculateSpeeds(
-			DownloadManager					download_manager,
-			EnhancedDownloadManagerFile		primary_file )
-		{
-			TOTorrent	torrent = download_manager.getTorrent();
-
-			if ( torrent == null ){
-				
-				return;
-			}
+			long 	rem_buffer = buffer_bytes - buffer_done;	// ok as initial dl is forced in order byte buffer-rta
 			
-			content_stream_bps_min = PlatformTorrentUtils.getContentStreamSpeedBps( torrent );
+			long 	rem_secs = (rem_buffer<=0)?0:(rem_buffer / download_rate);
 			
-			if ( content_stream_bps_min == 0 ){
+			long	secs_to_download = getSecondsToDownload();
+									
+			long	secs_to_watch = getSecondsToWatch();
 			
-					// hack in some test values for torrents that don't have a bps in them yet
-				
-				long	size = torrent.getSize();
-				
-				if ( size < 200*1024*1024 ){
+			long eta = secs_to_download - secs_to_watch;
+			
+			if ( rem_secs > eta && rem_secs > 0 ){
 				
-					content_stream_bps_min = 30*1024;
-					
-				}else if ( size < 1000*1024*1024L ){
-					
-					content_stream_bps_min = 200*1024;
-					
-				}else{
-
-					content_stream_bps_min = 400*1024;
-				}
+				eta = rem_secs;
 			}
-				
-					// bump it up by a bit to be conservative to deal with fluctuations, discards etc.
-				
-			content_stream_bps_max = content_stream_bps_min + ( content_stream_bps_min / 5 );
+			
+			return( eta );
 		}
 		
 		protected long
@@ -2895,199 +1460,77 @@ EnhancedDownloadManager
 		}
 
 		public long
-		getInitialBufferBytes(
-			long		download_rate,
-			boolean		ignore_min_buffer_size )
-		{
-			long min_dl = minimum_initial_buffer_secs_for_eta * getStreamBytesPerSecondMax();
-				
-				// factor in any explicit minimum buffer bytes
-			
-			min_dl = Math.max( min_dl, ignore_min_buffer_size?0:explicit_minimum_buffer_bytes );
-			
-				// see if we have any stream-specific advice
-			
-			long advice = primary_file.getInitialBufferBytes( download_rate );
-			
-			min_dl = Math.max( advice, min_dl );
+		getBufferBytes()
+		{			
+			long	min_dl = minimum_initial_buffer_secs_for_eta * getStreamBytesPerSecondMax();
 			
 			return( min_dl );
 		}
-		
-		protected void
-		updateViewerPosition()
-		{
-			viewer_byte_position 	= getInitialProviderPosition() + (getStreamBytesPerSecondMax() * getProviderLifeSecs());
-			
-			if ( viewer_byte_position > total_file_length ){
-				
-				viewer_byte_position = total_file_length;
-			}
 			
-			if ( viewer_byte_position > getProviderBytePosition()){
-				
-				viewer_byte_position = getProviderBytePosition();
-			}
-		}
-		
-		protected void 
-		setViewerBytePosition(
-			long bytes) 
-		{
-			// nothing for external viewer case as this doesn't get called
-		}
-
-		protected long
-		getViewerBytePosition()
-		{
-			return( viewer_byte_position );
-		}
-	}
-	
-	protected class
-	progressiveStatsInternal
-		extends progressiveStatsCommon
-	{
-		private long	content_stream_bps_min;
-		private long	content_stream_bps_max;
-
-		private long	viewer_byte_position;
-		private long	viewer_byte_position_set_time;
-				
-		private long	last_warning;
-		
-		protected
-		progressiveStatsInternal(
-			DownloadManager					dm,
-			EnhancedDownloadManagerFile		primary_file )
+		protected EnhancedDownloadManagerFile 
+		getFile() 
 		{
-			super( dm, primary_file );
+			return( primary_file );
 		}
 		
-		protected void
-		calculateSpeeds(
-			DownloadManager					download_manager,
-			EnhancedDownloadManagerFile		primary_file )
+		protected long 
+		getDownloadBytesPerSecond() 
 		{
-			TOTorrent	torrent = download_manager.getTorrent();
-
-			if ( torrent == null ){
+			long	original = (long)capped_download_rate_average.getAverage();
+			
+			long	current	= original;
+			
+			int	dl_limit = download_manager.getStats().getDownloadRateLimitBytesPerSecond();
+			
+			if ( dl_limit > 0 ){
 				
-				return;
+				current = Math.min( current, dl_limit );
 			}
-						
-			content_stream_bps_min = PlatformTorrentUtils.getContentStreamSpeedBps( torrent );
 			
-			if ( content_stream_bps_min == 0 ){
+			int global_limit = TransferSpeedValidator.getGlobalDownloadRateLimitBytesPerSecond();
 			
-					// hack in some test values for torrents that don't have a bps in them yet
-				
-				long	size = torrent.getSize();
-				
-				if ( size < 200*1024*1024 ){
+			if ( global_limit > 0 ){
 				
-					content_stream_bps_min = 30*1024;
-					
-				}else if ( size < 1000*1024*1024L ){
-					
-					content_stream_bps_min = 200*1024;
-					
-				}else{
-
-					content_stream_bps_min = 400*1024;
-				}
+				current = Math.min( current, global_limit );
 			}
-				
-				// bump it up by a bit to be conservative to deal with fluctuations, discards etc.
-				
-			content_stream_bps_min += internal_content_stream_bps_increase_absolute;
-			
-			content_stream_bps_max = content_stream_bps_min + ( content_stream_bps_min / internal_content_stream_bps_increase_ratio );
+						
+			return( current );
 		}
 		
 		protected long
-		getStreamBytesPerSecondMax()
-		{
-			return( content_stream_bps_max );
-		}
-
-		protected long
-		getStreamBytesPerSecondMin()
+		getSecondsToDownload()
 		{
-			return( content_stream_bps_min );
-		}
+			long download_rate = getDownloadBytesPerSecond();
 
-		public long
-		getInitialBufferBytes(
-			long	download_rate,
-			boolean	ignore_min_buffer_size )
-		{
-			long min_dl = ignore_min_buffer_size?0:explicit_minimum_buffer_bytes;
-			
-				// see if we have any stream-specific advice
-			
-			long advice = primary_file.getInitialBufferBytes( download_rate );
-			
-			if ( advice == 0 ){
-				
-					// no advice, fall back to computed min
-				
-				advice = minimum_initial_buffer_secs_for_eta * getStreamBytesPerSecondMax();
-				
-			}else{
-				
-					// currently the player will auto-pause if the buffer falls below the
-					// explicit minimum so we need to add the explicit to the advice to
-					// get a value that will prevent a stall
+			if ( download_rate == 0 ){
 				
-				if ( !ignore_min_buffer_size ){
-					
-					advice += explicit_minimum_buffer_bytes;
-				}
+				return( Long.MAX_VALUE );
 			}
 			
-			min_dl = Math.max( advice, min_dl );
-			
-			return( min_dl );
-		}
-		
-		protected void
-		updateViewerPosition()
-		{
+			return( weighted_bytes_to_download / download_rate );
 		}
 		
-		protected void 
-		setViewerBytePosition(
-			long bytes) 
+		public long
+		getSecondsToWatch()
 		{
-			viewer_byte_position_set_time = SystemTime.getCurrentTime();
-			
-			viewer_byte_position = bytes;
+			return(( primary_file.getLength() - getCurrentProviderPosition( false )) / getStreamBytesPerSecondMin());
 		}
-
-		protected long
-		getViewerBytePosition()
+										
+		protected String
+		getString()
 		{
-			long	now = SystemTime.getCurrentTime();
-			
-			if ( now < viewer_byte_position_set_time ){
-				
-				viewer_byte_position_set_time = now;
-				
-			}else if ( now - viewer_byte_position_set_time > 10000 ){
-				
-				if ( viewer_byte_position != 0 ){
+			long	dl_rate = getDownloadBytesPerSecond();
 				
-					if ( now < last_warning || now - last_warning >= 1000 ){
-					
-						last_warning	= now;
-						
-						log( "No recent viewer position update (current=" + viewer_byte_position + ")" );
-					}
-				}
-			}
+			long	buffer_bytes	= getBufferBytes();
 			
-			return( viewer_byte_position );
+			long	buffer_done		= getContiguousAvailableBytes( primary_file.getIndex(), getCurrentProviderPosition( false ), buffer_bytes );
+
+			return( "play_eta=" + getETA() + "/d=" + getSecondsToDownload() + "/w=" + getSecondsToWatch()+ 
+					", dl_rate=" + formatSpeed(dl_rate)+ ", download_rem=" + formatBytes(weighted_bytes_to_download) + "/" + formatBytes(actual_bytes_to_download) +
+					", discard_rate=" + formatSpeed((long)discard_rate_average.getAverage()) +
+					", buffer: " + buffer_bytes + "/" + buffer_done +
+					", prov: byte=" + formatBytes( provider_byte_position ) + " secs=" + ( provider_byte_position/getStreamBytesPerSecondMin()) + " speed=" + formatSpeed((long)provider_speed_average.getAverage()) +
+					" block= " + formatBytes( provider_blocking_byte_position ));
 		}
 	}
 }
diff --git a/com/aelitis/azureus/core/download/EnhancedDownloadManagerFile.java b/com/aelitis/azureus/core/download/EnhancedDownloadManagerFile.java
index 769b98d..22ac6ae 100644
--- a/com/aelitis/azureus/core/download/EnhancedDownloadManagerFile.java
+++ b/com/aelitis/azureus/core/download/EnhancedDownloadManagerFile.java
@@ -23,62 +23,21 @@
 
 package com.aelitis.azureus.core.download;
 
-import java.util.*;
-
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.core3.util.Debug;
 
 public class 
 EnhancedDownloadManagerFile 
 {
 	private DiskManagerFileInfo		file;
 	private long					offset;
-	
-	private int						header_size;
-	private int[][]					speeds;
-	
+		
 	protected
 	EnhancedDownloadManagerFile(
 		DiskManagerFileInfo		_file,
-		long					_offset,
-		Map						_map )
+		long					_offset )
 	{
 		file		= _file;
 		offset		= _offset;
-		
-		try{
-			if ( _map != null ){
-				
-				Long	l_header_size = (Long)_map.get( "header_size" );
-				
-				if ( l_header_size != null ){
-					
-					header_size = l_header_size.intValue();
-				}
-				
-				List 	stream_info = (List)_map.get( "stream_info" );
-				
-				if ( stream_info != null ){
-					
-					speeds = new int[stream_info.size()][];
-					
-					for (int i=0;i<stream_info.size();i++){
-						
-						List	entry = (List)stream_info.get(i);
-						
-						
-						int		speed 			= ((Long)entry.get(0)).intValue();
-						int		worst_buffer	= ((Long)entry.get(1)).intValue();
-						int		init_buffer		= ((Long)entry.get(2)).intValue();
-						
-						speeds[i] = new int[]{ speed, worst_buffer, init_buffer };
-					}
-				}
-			}
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace(e);
-		}
 	}
 	
 	public DiskManagerFileInfo
@@ -87,72 +46,27 @@ EnhancedDownloadManagerFile
 		return( file );
 	}
 	
-	public long
-	getByteOffestInTorrent()
+	public int
+	getIndex()
 	{
-		return( offset );
+		return( file.getIndex());
 	}
 	
-	public int
-	getHeaderSize()
+	public long
+	getLength()
 	{
-		return( header_size );
+		return( file.getLength());
 	}
 	
-	public int
-	getInitialBufferBytes(
-		long		rate )
+	public long
+	getByteOffestInTorrent()
 	{
-		int	buffer_size = 0;
-		
-		if ( speeds != null && speeds.length > 0 ){
-			
-			boolean	found = false;
-			
-			int	k_rate = (int)rate/1024;
-					
-			for (int i=0;i<speeds.length;i++){
-				
-				if ( k_rate > speeds[i][0] ){
-					
-						// use the init buffer rather than the worst one
-					
-					buffer_size = speeds[i][2] * 1024;
-			
-					found = true;
-					
-					break;
-				}
-			}
-			
-			if ( !found ){
-				
-				buffer_size = speeds[speeds.length-1][2] * 1024;
-			}
-		}
-		
-		// System.out.println( "getInitialBufferBytes(" + rate + ") -> " + header_size + "/" + buffer_size );
-		
-		return( header_size + buffer_size );
+		return( offset );
 	}
 	
-	public String
-	getString()
+	public boolean
+	isComplete()
 	{
-		String	speeds_str = "";
-		
-		if ( speeds != null ){
-		
-			speeds_str = ",speeds=";
-			
-			for (int i=0;i<speeds.length;i++){
-				
-				int[]	s = speeds[i];
-				
-				speeds_str += (i==0?"":",") + "[" + s[0] + "," + s[1] + "," + s[2] + "]"; 
-			}
-		}
-		
-		return( file.getFile(true).getName()+ ",header=" + header_size + speeds_str );
+		return( file.getDownloaded() == file.getLength());
 	}
 }
diff --git a/com/aelitis/azureus/core/download/StreamManager.java b/com/aelitis/azureus/core/download/StreamManager.java
new file mode 100644
index 0000000..0b2bfa3
--- /dev/null
+++ b/com/aelitis/azureus/core/download/StreamManager.java
@@ -0,0 +1,1156 @@
+/*
+ * Created on Jun 21, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.download;
+
+import java.util.*;
+import java.lang.reflect.Method;
+import java.net.URL;
+
+
+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.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.AsyncDispatcher;
+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.SystemTime;
+import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginListener;
+import org.gudy.azureus2.plugins.PluginManager;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadStats;
+import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.devices.DeviceManager;
+import com.aelitis.azureus.core.devices.DeviceManagerFactory;
+import com.aelitis.azureus.core.devices.DeviceMediaRenderer;
+import com.aelitis.azureus.core.devices.TranscodeAnalysisListener;
+import com.aelitis.azureus.core.devices.TranscodeException;
+import com.aelitis.azureus.core.devices.TranscodeJob;
+import com.aelitis.azureus.core.devices.TranscodeManager;
+import com.aelitis.azureus.core.devices.TranscodeProfile;
+import com.aelitis.azureus.core.devices.TranscodeProviderAnalysis;
+import com.aelitis.azureus.core.devices.TranscodeQueue;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.swt.plugininstall.SimplePluginInstaller;
+
+public class 
+StreamManager 
+{
+	private static final int BUFFER_SECS_DEFAULT 		= 30;
+	private static final int BUFFER_MIN_SECS_DEFAULT	= 3;
+	
+	private static int config_buffer_secs;
+	private static int config_min_buffer_secs;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"streamman.buffer.secs",
+				"streamman.min.buffer.secs",
+			},
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameterName) 
+				{
+					config_buffer_secs 		= COConfigurationManager.getIntParameter( "streamman.buffer.secs", BUFFER_SECS_DEFAULT );
+					config_min_buffer_secs 	= COConfigurationManager.getIntParameter( "streamman.min.buffer.secs", BUFFER_MIN_SECS_DEFAULT );
+				}
+			});
+		
+	}
+
+	private static StreamManager		singleton = new StreamManager();
+	
+	public static StreamManager
+	getSingleton()
+	{
+		return( singleton );
+	}
+	
+	private TorrentAttribute	mi_ta;
+	
+	private AsyncDispatcher	dispatcher = new AsyncDispatcher();
+	
+	private List<SMDImpl>		streamers = new ArrayList<SMDImpl>();
+	
+	private
+	StreamManager()
+	{
+		PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+
+		mi_ta = default_pi.getTorrentManager().getPluginAttribute( "sm_metainfo" );
+		
+		default_pi.addListener(
+			new PluginListener()
+			{
+				public void
+				initializationComplete()
+				{
+					
+				}
+				
+				public void
+				closedownInitiated()
+				{
+					dispatcher.dispatch(
+						new AERunnable()
+						{
+							public void 
+							runSupport()
+							{
+								List<SMDImpl>	to_cancel;
+								
+								synchronized( StreamManager.this ){
+									
+									to_cancel = new ArrayList<SMDImpl>( streamers );
+									
+									streamers.clear();
+								}
+								
+								for ( SMDImpl s: to_cancel ){
+									
+									s.cancel();
+								}
+							}
+						});
+				}
+				
+				public void
+				closedownComplete()
+				{
+					
+				}
+			});
+	}
+	
+	public int
+	getBufferSecs()
+	{
+		return( config_buffer_secs );
+	}
+	
+	public void
+	setBufferSecs(
+		int		secs )
+	{
+		COConfigurationManager.setParameter( "streamman.buffer.secs", secs );
+	}
+	
+	public int
+	getMinBufferSecs()
+	{
+		return( config_min_buffer_secs );
+	}
+	
+	public void
+	setMinBufferSecs(
+		int		secs )
+	{
+		COConfigurationManager.setParameter( "streamman.min.buffer.secs", secs );
+	}
+	
+	public boolean
+	isStreamingUsable()
+	{
+			// need win or osx 10.5+
+		
+		if ( !( Constants.isWindows || Constants.isOSX_10_5_OrHigher )){
+			
+			return( false );
+		}
+		
+		try{
+			PluginManager plug_man = AzureusCoreFactory.getSingleton().getPluginManager();
+			
+			PluginInterface xcode_pi = plug_man.getPluginInterfaceByID( "vuzexcode", false );
+	
+			if ( xcode_pi != null && !xcode_pi.getPluginState().isOperational()){
+				
+					// can't use if xcode borked
+				
+				return( false );
+			}
+			
+				// otherwise xcode will be installed on demand
+			
+			PluginInterface emp_pi = plug_man.getPluginInterfaceByID( "azemp", false );
+	
+			if ( emp_pi == null ){
+				
+					// will be installed on demand
+				
+				return( true );
+			}
+			
+			if ( !emp_pi.getPluginState().isOperational()){
+				
+					// can't use if emp borked
+				
+				return( false );
+			}
+			
+				// emp installed but need version with prepareWindow, wait for update
+			
+			Class<?> epwClass = emp_pi.getPlugin().getClass().getClassLoader().loadClass( "com.azureus.plugins.azemp.ui.swt.emp.EmbeddedPlayerWindowSWT" );
+			
+			Method method = epwClass.getMethod( "prepareWindow", new Class[] { String.class });
+			
+			return( method != null );
+			
+		}catch( Throwable e ){
+			
+			return( false );
+		}
+	}
+	
+	public StreamManagerDownload
+	stream(
+		DownloadManager					dm,
+		int								file_index,
+		URL								url,
+		boolean							preview_mode,
+		StreamManagerDownloadListener	listener )
+	{
+		SMDImpl	result = new SMDImpl( dm, file_index, url, preview_mode, listener );
+			
+		synchronized( StreamManager.this ){
+			
+			streamers.add( result );
+		}
+		
+		return( result );
+	}
+
+
+	private class
+	SMDImpl
+		extends AERunnable
+		implements StreamManagerDownload
+	{
+		private DownloadManager						dm;
+		private int									file_index;
+		private URL									url;
+		private StreamManagerDownloadListener		listener;
+			
+		private int						existing_dl_limit;
+		
+		private boolean					preview_mode;
+		private long					preview_mode_last_change = 0;
+		
+		private AESemaphore				active_sem;
+		private TranscodeJob			active_job;
+		
+		private EnhancedDownloadManager	active_edm;
+		private boolean					active_edm_activated;
+
+		private volatile boolean		cancelled;
+		
+		private 
+		SMDImpl(
+			DownloadManager					_dm,
+			int								_file_index,
+			URL								_url,
+			boolean							_preview_mode,
+			StreamManagerDownloadListener	_listener )
+		{
+			dm				= _dm;
+			file_index		= _file_index;
+			url				= _url;
+			preview_mode	= _preview_mode;
+			listener		= _listener;
+			
+			dispatcher.dispatch( this );
+		}
+		
+		public DownloadManager
+		getDownload()
+		{
+			return( dm );
+		}
+		
+		public int
+		getFileIndex()
+		{
+			return( file_index );
+		}
+		
+		public URL
+		getURL()
+		{
+			return( url );
+		}
+		
+		public boolean
+		getPreviewMode()
+		{
+			return( preview_mode );
+		}
+		
+		public void
+		setPreviewMode(
+			boolean	_preview_mode )
+		{
+			long	now = SystemTime.getMonotonousTime();
+			
+			if ( 	preview_mode_last_change == 0 || 
+					now - preview_mode_last_change > 500 ){
+				
+				preview_mode_last_change = now;
+				
+				preview_mode = _preview_mode;
+				
+				listener.updateActivity( "Preview mode changed to " + preview_mode );
+			}
+		}
+		
+		public void
+		runSupport()
+		{
+			try{
+				synchronized( StreamManager.this ){
+					
+					if ( cancelled ){
+						
+						throw( new Exception( "Cancelled" ));
+					}
+
+					active_edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload( dm );
+				}
+
+				final long stream_start = SystemTime.getMonotonousTime();
+				
+				final Download download = PluginCoreUtils.wrap( dm );
+				
+				final DiskManagerFileInfo file = download.getDiskManagerFileInfo( file_index );
+								
+				PluginInterface emp_pi = checkPlugin( "azemp", "media player" );
+
+				checkPlugin( "vuzexcode", "media analyser" );
+
+				Class<?> epwClass = emp_pi.getPlugin().getClass().getClassLoader().loadClass( "com.azureus.plugins.azemp.ui.swt.emp.EmbeddedPlayerWindowSWT" );
+				
+				Method method = epwClass.getMethod( "prepareWindow", new Class[] { String.class });
+				
+				final Object player = method.invoke(null, new Object[] { file.getFile( true ).getName() });
+			
+				final Method buffering_method	= player.getClass().getMethod( "bufferingPlayback", new Class[] { Map.class });
+				final Method is_active_method	= player.getClass().getMethod( "isActive", new Class[] {});
+
+				final StreamManagerDownloadListener original_listener = listener;
+				
+				listener = 
+					new StreamManagerDownloadListener()
+					{
+						public void
+						updateActivity(
+							String		str )
+						{
+							original_listener.updateActivity(str);
+						}
+						
+						public void
+						updateStats(
+							int			secs_until_playable,
+							int			buffer_secs,
+							long		buffer_bytes,
+							int			target_buffer_secs )
+						{
+							original_listener.updateStats(secs_until_playable, buffer_secs, buffer_bytes, target_buffer_secs);
+						}
+						
+						public void
+						ready()
+						{
+							original_listener.ready();
+						}
+						
+						public void
+						failed(
+							Throwable 	error )
+						{
+							try{
+								original_listener.failed(error);
+								
+								Map<String,Object> b_map = new HashMap<String,Object>();
+								
+								b_map.put( "state", new Integer( 3 ));
+								b_map.put( "msg", Debug.getNestedExceptionMessage( error ));
+								
+								try{
+									buffering_method.invoke(player, new Object[] { b_map });
+	
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}finally{
+								
+								cancel();
+							}
+						}
+					};
+				
+				Map<String,Map<String,Object>>	map = (Map<String,Map<String,Object>>)download.getMapAttribute( mi_ta );
+				
+				Long	l_duration 		= null;
+				Long	l_video_width 	= null;
+				Long	l_video_height 	= null;
+				
+				if ( map != null ){
+					
+					Map<String,Object> file_map = map.get( String.valueOf( file_index ));
+					
+					if ( file_map != null ){
+						
+						l_duration 		= (Long)file_map.get( "duration" );
+						l_video_width 	= (Long)file_map.get( "video_width" );
+						l_video_height 	= (Long)file_map.get( "video_height" );
+					}
+				}
+				
+				final long duration;
+				long video_width;
+				long video_height;
+				
+				if ( l_duration == null ){
+						
+					active_edm.prepareForProgressiveMode( true );
+					
+					try{
+						DeviceManager dm = DeviceManagerFactory.getSingleton();
+						
+						TranscodeManager tm = dm.getTranscodeManager();
+						
+						DeviceMediaRenderer dmr = 
+							(DeviceMediaRenderer)dm.addVirtualDevice(
+								Device.DT_MEDIA_RENDERER,
+								"18a0b53a-a466-6795-1d0f-cf38c830ca0e", 
+								"generic",
+								"Media Analyser" );
+	
+						dmr.setHidden(true);
+						dmr.setCanRemove(false);
+						
+						TranscodeQueue queue = tm.getQueue();
+						
+						TranscodeJob[] jobs = queue.getJobs();
+						
+						for ( TranscodeJob job: jobs ){
+							
+							if ( job.getTarget() == dmr ){
+								
+								job.removeForce();
+							}
+						}
+						
+						TranscodeProfile[] profiles = dmr.getTranscodeProfiles();
+						
+						TranscodeProfile profile = null;
+						
+						for (TranscodeProfile p : profiles) {
+							
+							if ( p.getName().equals( "Generic MP4" )){
+								
+								profile = p;
+	
+								break;
+							}
+						}
+						
+						if ( profile == null ){
+							
+							throw( new Exception( "Analyser transcode profile not found" ));
+						}
+						
+						listener.updateActivity( "Analysing media" );
+						
+						final Map<String,Object> b_map = new HashMap<String,Object>();
+						
+						b_map.put( "state", new Integer( 1 ));
+						b_map.put( "msg", MessageText.getString( "stream.analysing.media" ));
+						
+						buffering_method.invoke(player, new Object[] { b_map });
+
+						final TranscodeJob tj = queue.add( dmr, profile, file, true );
+											
+						try{
+							final AESemaphore sem = new AESemaphore( "analyserWait" );
+
+							synchronized( StreamManager.this ){
+								
+								if ( cancelled ){
+									
+									throw( new Exception( "Cancelled" ));
+								}
+								
+								active_sem	= sem;
+								active_job 	= tj;
+							}
+								
+							final long[] properties = new long[3];
+							
+							final Throwable[] error = { null };
+							
+							tj.analyseNow(
+								new TranscodeAnalysisListener()
+								{
+									public void
+									analysisComplete(
+										TranscodeJob					file,
+										TranscodeProviderAnalysis		analysis )
+									{
+										try{											
+											properties[0] = analysis.getLongProperty( TranscodeProviderAnalysis.PT_DURATION_MILLIS );
+											properties[1] = analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_WIDTH );
+											properties[2] = analysis.getLongProperty( TranscodeProviderAnalysis.PT_VIDEO_HEIGHT );
+											
+											tj.removeForce();
+											
+										}finally{
+											
+											sem.releaseForever();
+										}
+									}
+									
+									public void
+									analysisFailed(
+										TranscodeJob		file,
+										TranscodeException	e )
+									{
+										try{
+											error[0] = e;
+										
+											tj.removeForce();
+											
+										}finally{
+											
+											sem.releaseForever();
+										}
+									}
+								});
+							
+							new AEThread2( "SM:anmon" )
+								{
+									public void
+									run()
+									{
+										boolean	last_preview_mode = preview_mode;
+										
+										while( !sem.isReleasedForever() && !cancelled ){
+											
+											if ( !sem.reserve( 250 )){
+											
+												if ( cancelled ){
+													
+													return;
+												}
+													
+												try{
+													Boolean b = (Boolean)is_active_method.invoke( player, new Object[0] );
+													
+													if ( !b ){
+														
+														cancel();
+														
+														break;
+													}
+												}catch( Throwable e ){	
+												}
+												
+												if ( last_preview_mode != preview_mode ){
+													
+													last_preview_mode = preview_mode;
+													
+													b_map.put( "msg", MessageText.getString( last_preview_mode?"stream.analysing.media.preview":"stream.analysing.media" ));
+
+												}
+												DownloadStats stats = download.getStats();
+												
+												b_map.put( "dl_rate", stats.getDownloadAverage());
+												b_map.put( "dl_size", stats.getDownloaded());
+												b_map.put( "dl_time", SystemTime.getMonotonousTime() - stream_start );
+												
+												try{
+													buffering_method.invoke(player, new Object[] { b_map });
+
+												}catch( Throwable e ){
+													
+												}
+											}
+										}
+									}
+								}.start();
+								
+							sem.reserve();
+							
+							synchronized( StreamManager.this ){
+								
+								if ( cancelled ){
+										
+									throw( new Exception( "Cancelled" ));
+								}
+								
+								active_job 	= null;
+								active_sem	= null;
+							}
+							
+							if ( error[0] != null ){
+								
+								throw( error[0] );
+							}
+							
+							duration 		= properties[0];
+							video_width		= properties[1];
+							video_height	= properties[2];
+							
+							if ( duration > 0 ){
+								
+								if ( map == null ){
+									
+									map = new HashMap<String, Map<String,Object>>();
+									
+								}else{
+									
+									map = new HashMap<String, Map<String,Object>>( map );
+								}
+								
+								Map<String,Object> file_map = map.get( String.valueOf( file_index ));
+								
+								if ( file_map == null ){
+								
+									file_map = new HashMap<String, Object>();
+									
+									map.put( String.valueOf( file_index ), file_map );
+								}
+								
+								file_map.put( "duration", duration );
+								file_map.put( "video_width", video_width );
+								file_map.put( "video_height", video_height );
+								
+								download.setMapAttribute( mi_ta, map );
+							}
+							
+						}catch( Throwable e ){
+							
+							tj.removeForce();
+							
+							throw( e );
+						}
+						
+					}catch( Throwable e ){
+						
+						throw( new Exception( "Media analysis failed", e ));
+						
+					}finally{
+						
+					}
+				}else{
+						
+					duration 		= l_duration;
+					video_width		= l_video_width==null?0:l_video_width;
+					video_height	= l_video_height==null?0:l_video_height;
+				}
+					
+				if ( video_width == 0 || video_height == 0){
+					
+					throw( new Exception( "Media analysis failed - video stream not found" ));
+				}
+				
+				if ( duration == 0 ){
+					
+					throw( new Exception( "Media analysis failed - duration unknown" ));
+				}
+				
+				listener.updateActivity( "MetaData read: duration=" + TimeFormatter.formatColon( duration/1000) + ", width=" + video_width + ", height=" + video_height );
+				
+				Method smd_method = player.getClass().getMethod( "setMetaData", new Class[] { Map.class });
+				
+				Map<String,Object>	md_map = new HashMap<String,Object>();
+				
+				md_map.put( "duration", duration );
+				md_map.put( "width", video_width );
+				md_map.put( "height", video_height );
+				
+				smd_method.invoke( player, new Object[] { md_map });
+
+				final long	bytes_per_sec = file.getLength() / (duration/1000);
+			
+				long	dl_lim_max 		= COConfigurationManager.getIntParameter( "Plugin.azemp.azemp.config.dl_lim_max" ) * 1024L;
+				long	dl_lim_extra 	= COConfigurationManager.getIntParameter( "Plugin.azemp.azemp.config.dl_lim_extra" ) * 1024L;
+
+				existing_dl_limit = download.getDownloadRateLimitBytesPerSecond();
+				
+				long	required_limit = Math.max( dl_lim_max, bytes_per_sec + dl_lim_extra );
+
+				if ( required_limit > 0 ){
+				
+					download.setDownloadRateLimitBytesPerSecond((int)required_limit );
+				}
+				
+				listener.updateActivity( "Average rate=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( bytes_per_sec ) + ", applied dl limit=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( required_limit ));
+
+				synchronized( StreamManager.this ){
+					
+					if ( cancelled ){
+						
+						throw( new Exception( "Cancelled" ));
+					}
+																										
+					active_edm.setExplicitProgressive( config_buffer_secs, bytes_per_sec, file_index );
+					
+					if ( !active_edm.setProgressiveMode( true )){
+						
+						throw( new Exception( "Failed to set download as progressive" ));
+					}
+					
+					active_edm_activated = true;
+				}
+				
+				new AEThread2( "streamMon" )
+				{
+					
+					public void
+					run()
+					{	
+						final int TIMER_PERIOD 		= 250;
+						final int PLAY_STATS_PERIOD	= 5000;
+						final int PLAY_STATS_TICKS	= PLAY_STATS_PERIOD / TIMER_PERIOD;
+						
+						final int DL_STARTUP_PERIOD	= 5000;
+						final int DL_STARTUP_TICKS	= DL_STARTUP_PERIOD / TIMER_PERIOD;
+			
+						boolean playback_started 	= false;
+						boolean	playback_paused		= false;
+
+						boolean	error_reported = false;
+						
+						try{
+							Method start_method 		= player.getClass().getMethod( "startPlayback", new Class[] { URL.class });
+							Method pause_method 		= player.getClass().getMethod( "pausePlayback", new Class[] {});
+							Method resume_method 		= player.getClass().getMethod( "resumePlayback", new Class[] {});
+							Method buffering_method		= player.getClass().getMethod( "bufferingPlayback", new Class[] { Map.class });
+							Method play_stats_method	= player.getClass().getMethod( "playStats", new Class[] { Map.class });
+
+							int tick_count = 0;
+							
+							while( !cancelled ){
+									
+								tick_count++;
+								
+								int dm_state = dm.getState();
+								
+								boolean complete = file.getLength() == file.getDownloaded();
+
+								if ( !complete ){
+									
+									if ( 	dm_state == DownloadManager.STATE_ERROR || 
+											dm_state == DownloadManager.STATE_STOPPED ||
+											dm_state == DownloadManager.STATE_QUEUED ){
+										
+										if ( tick_count >= DL_STARTUP_TICKS ){
+										
+											throw( new Exception( "Streaming abandoned, download isn't running" ));
+										}
+									}
+	
+									if ( !active_edm.getProgressiveMode()){
+									
+										complete = file.getLength() == file.getDownloaded();
+										
+										if ( !complete ){
+										
+											throw( new Exception( "Streaming mode abandoned for download" ));
+										}
+									}
+								}
+							
+								long[] details = updateETA( active_edm );
+								
+								int		eta 		= (int)details[0];
+								int		buffer_secs	= (int)details[1];
+								long	buffer		= details[2];
+								
+								listener.updateStats( eta, buffer_secs, buffer, config_buffer_secs );
+
+								boolean playable;
+								
+								int	buffer_to_use = playback_started?config_min_buffer_secs:config_buffer_secs;
+								
+								if ( complete ){
+									
+									playable = true;
+									
+								}else{
+									
+									playable = buffer_secs > buffer_to_use;
+								
+									playable = playable && ( eta <= 0  || (playback_started && !playback_paused ) || preview_mode );
+								}
+								
+								if ( playback_started ){
+									
+									if ( playable ){
+										
+										if ( playback_paused ){
+											
+											listener.updateActivity( "Resuming playback" );
+											
+											resume_method.invoke(player, new Object[] {});
+
+											playback_paused = false;
+										}
+									}else{
+											
+										if ( !playback_paused ){
+											
+											listener.updateActivity( "Pausing playback to prevent stall" );
+																							
+											pause_method.invoke(player, new Object[] {});
+	
+											playback_paused = true;
+										}
+									}
+								}else{
+									
+									if ( playable ){
+										
+										listener.ready();
+											
+										start_method.invoke(player, new Object[] { url });
+										
+										playback_started = true;
+									}
+								}
+							
+								if ( playable ){
+									
+									if ( tick_count % PLAY_STATS_TICKS == 0 ){
+											
+										long contiguous_done = active_edm.getContiguousAvailableBytes( file_index>=0?file_index:active_edm.getPrimaryFileIndex(), 0, 0 );
+									
+										Map<String,Object> map = new HashMap<String,Object>();
+										
+										map.put( "buffer_min", new Long( config_buffer_secs ));
+										map.put( "buffer_secs", new Integer( buffer_secs ));
+										map.put( "buffer_bytes", new Long( buffer ));
+										
+										map.put( "stream_rate", bytes_per_sec );
+										
+										DownloadStats stats = download.getStats();
+										
+										map.put( "dl_rate", stats.getDownloadAverage());
+										map.put( "dl_size", stats.getDownloaded());
+										map.put( "dl_time", SystemTime.getMonotonousTime() - stream_start );
+	
+										map.put( "duration", duration );
+										map.put( "file_size", file.getLength());
+										map.put( "cont_done", contiguous_done );
+										
+										play_stats_method.invoke(player, new Object[] { map });
+									}
+								}else{
+									
+									DownloadStats stats = download.getStats();
+
+									Map<String,Object> map = new HashMap<String,Object>();
+									
+									map.put( "state", new Integer( 2 ));
+
+									if ( preview_mode && !complete ){
+										
+										long rate = stats.getDownloadAverage();
+										
+										int	preview_eta;
+										
+										if ( rate <= 0 ){
+											
+											preview_eta = Integer.MAX_VALUE;
+											
+										}else{
+											
+											double secs_per_sec = ((double)bytes_per_sec)/rate;
+										
+											preview_eta = (int)(( buffer_to_use - buffer_secs ) * secs_per_sec);
+										}
+										
+										map.put( "eta", new Integer( preview_eta ));
+										
+										map.put( "preview", 1 );
+										
+									}else{
+										
+										map.put( "eta", new Integer( eta ));
+										
+										map.put( "preview", 0 );
+									}
+									
+									map.put( "buffer_min", new Long( config_buffer_secs ));
+									map.put( "buffer_secs", new Integer( buffer_secs ));
+									map.put( "buffer_bytes", new Long( buffer ));
+									
+									map.put( "stream_rate", bytes_per_sec );
+									
+									map.put( "dl_rate", stats.getDownloadAverage());
+									map.put( "dl_size", stats.getDownloaded());
+									map.put( "dl_time", SystemTime.getMonotonousTime() - stream_start );
+									
+									buffering_method.invoke(player, new Object[] { map });
+								}
+								
+								Thread.sleep( TIMER_PERIOD );
+								
+								try{
+									Boolean b = (Boolean)is_active_method.invoke( player, new Object[0] );
+									
+									if ( !b ){
+										
+										cancel();
+										
+										break;
+									}
+								}catch( Throwable e ){	
+								}
+							}
+						}catch( Throwable e ){
+							
+							error_reported = true;
+							
+							listener.failed( e );
+							
+						}finally{
+							
+							if ( !( error_reported || cancelled )){
+								
+								if ( !playback_started ){
+								
+									listener.failed( new Exception( "Streaming failed, reason unknown" ));
+								}
+							}
+						}
+					}
+				}.start();
+								
+			}catch( Throwable e ){
+						
+				try{
+					listener.failed( e );
+					
+				}finally{
+					
+					cancel();
+				}
+			}
+		}
+		
+		private long[]
+		updateETA(
+			EnhancedDownloadManager 	edm )
+		{
+			long _eta = edm.getProgressivePlayETA();
+					
+			int	eta = _eta>=Integer.MAX_VALUE?Integer.MAX_VALUE:(int)_eta;
+			
+			EnhancedDownloadManager.progressiveStats stats = edm.getProgressiveStats();
+			
+			long provider_pos = stats.getCurrentProviderPosition( false );
+			
+			long buffer = edm.getContiguousAvailableBytes( file_index>=0?file_index:edm.getPrimaryFileIndex(), provider_pos, 0 );
+			
+			long bps = stats.getStreamBytesPerSecondMin();
+						
+			int	buffer_secs = bps<=0?Integer.MAX_VALUE:(int)(buffer/bps);
+											
+			return( new long[]{ eta, buffer_secs, buffer });
+		}
+		
+		public void
+		cancel()
+		{
+			TranscodeJob	job;
+			
+			EnhancedDownloadManager	edm;
+			boolean					edm_activated;
+			
+			synchronized( StreamManager.this ){
+				
+				cancelled = true;
+			
+				job = active_job;
+				
+				if ( active_sem != null ){
+					
+					active_sem.releaseForever();
+				}
+				
+				edm 			= active_edm;
+				edm_activated	= active_edm_activated;
+				
+				streamers.remove( this );
+			}
+			
+			if ( job != null ){
+				
+				job.removeForce();
+			}
+			
+			if ( edm != null ){
+				
+				if ( edm_activated ){
+				
+					edm.setProgressiveMode( false );
+					
+				}else{
+					
+					edm.prepareForProgressiveMode( false );
+				}
+			}
+			
+			final Download download = PluginCoreUtils.wrap( dm );
+
+			download.setDownloadRateLimitBytesPerSecond( existing_dl_limit );
+		}
+		
+		public boolean
+		isCancelled()
+		{
+			return( cancelled );
+		}
+		
+		private PluginInterface
+		checkPlugin(
+			String		id,
+			String		name )
+		
+			throws Throwable
+		{
+			PluginManager plug_man = AzureusCoreFactory.getSingleton().getPluginManager();
+			
+			PluginInterface pi = plug_man.getPluginInterfaceByID( id, false );
+			
+			if ( pi == null ){
+				
+				listener.updateActivity( "Installing " + name );
+				
+				final AESemaphore sem = new AESemaphore( "analyserWait" );
+
+				synchronized( StreamManager.this ){
+					
+					if ( cancelled ){
+						
+						throw( new Exception( "Cancelled" ));
+					}
+					
+					active_sem	= sem;
+				}
+				
+				final Throwable[] error = { null };
+				
+				new SimplePluginInstaller(
+						id,
+	    				"dlg.install." + id,
+	    				new UIFunctions.actionListener()
+						{
+							public void
+							actionComplete(
+								Object		result )
+							{
+								try{
+									if ( result instanceof Boolean ){
+										
+									}else{
+										
+										error[0] = (Throwable)result;
+									}
+								}finally{
+									
+									sem.release();
+								}
+							}
+						});
+				
+				sem.reserve();
+				
+				synchronized( StreamManager.this ){
+					
+					if ( cancelled ){
+							
+						throw( new Exception( "Cancelled" ));
+					}
+					
+					active_sem	= null;
+				}
+
+				if( error[0] != null ){
+					
+					throw( error[0] );
+				}
+				
+				long start = SystemTime.getMonotonousTime();
+				
+				listener.updateActivity( "Waiting for plugin initialisation" );
+				
+				while( true ){
+					
+					if ( cancelled ){
+						
+						throw( new Exception( "Cancelled" ));
+					}
+					
+					if ( SystemTime.getMonotonousTime() - start >= 30*1000 ){
+						
+						throw( new Exception( "Timeout waiting for " + name + " to initialise" ));
+					}
+					
+					pi = plug_man.getPluginInterfaceByID( id, false );
+
+					if ( pi != null && pi.getPluginState().isOperational()){
+						
+						return( pi );
+					}
+					
+					Thread.sleep(250);
+				}
+			}else if ( !pi.getPluginState().isOperational()){
+				
+				throw( new Exception( name + " not operational" ));
+				
+			}else{
+				
+				return( pi );
+			}
+		}
+	}		
+}
diff --git a/com/aelitis/azureus/core/download/StreamManagerDownload.java b/com/aelitis/azureus/core/download/StreamManagerDownload.java
new file mode 100644
index 0000000..552b236
--- /dev/null
+++ b/com/aelitis/azureus/core/download/StreamManagerDownload.java
@@ -0,0 +1,52 @@
+/*
+ * Created on Jun 21, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.download;
+
+import java.net.URL;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+
+public interface 
+StreamManagerDownload 
+{
+	public DownloadManager
+	getDownload();
+	
+	public int
+	getFileIndex();
+	
+	public URL
+	getURL();
+	
+	public boolean
+	getPreviewMode();
+	
+	public void
+	setPreviewMode(
+		boolean	preview_mode );
+	
+	public void
+	cancel();
+	
+	public boolean
+	isCancelled();
+}
diff --git a/com/aelitis/azureus/core/download/StreamManagerDownloadListener.java b/com/aelitis/azureus/core/download/StreamManagerDownloadListener.java
new file mode 100644
index 0000000..e08d4d4
--- /dev/null
+++ b/com/aelitis/azureus/core/download/StreamManagerDownloadListener.java
@@ -0,0 +1,44 @@
+/*
+ * Created on Jun 21, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.download;
+
+public interface 
+StreamManagerDownloadListener 
+{
+	public void
+	updateActivity(
+		String		str );
+	
+	public void
+	updateStats(
+		int			secs_until_playable,
+		int			buffer_secs,
+		long		buffer_bytes,
+		int			target_buffer_secs );
+	
+	public void
+	ready();
+	
+	public void
+	failed(
+		Throwable 	error );
+}
diff --git a/com/aelitis/azureus/core/drivedetector/DriveDetectedInfo.java b/com/aelitis/azureus/core/drivedetector/DriveDetectedInfo.java
index 4b2eeda..7eeb6d4 100644
--- a/com/aelitis/azureus/core/drivedetector/DriveDetectedInfo.java
+++ b/com/aelitis/azureus/core/drivedetector/DriveDetectedInfo.java
@@ -20,6 +20,7 @@
 package com.aelitis.azureus.core.drivedetector;
 
 import java.io.File;
+import java.util.Map;
 
 /**
  * @author TuxPaper
@@ -29,4 +30,8 @@ import java.io.File;
 public interface DriveDetectedInfo
 {
 	public File getLocation();
+
+	public Object getInfo(String key);
+
+	public Map<String, Object> getInfoMap();
 }
diff --git a/com/aelitis/azureus/core/drivedetector/DriveDetector.java b/com/aelitis/azureus/core/drivedetector/DriveDetector.java
index 7a6f217..62d929e 100644
--- a/com/aelitis/azureus/core/drivedetector/DriveDetector.java
+++ b/com/aelitis/azureus/core/drivedetector/DriveDetector.java
@@ -20,6 +20,7 @@
 package com.aelitis.azureus.core.drivedetector;
 
 import java.io.File;
+import java.util.Map;
 
 
 
@@ -30,11 +31,13 @@ import java.io.File;
  */
 public interface DriveDetector
 {
-	public void driveDetected(File location);
+	public void driveDetected(File location, Map info);
 	
 	public void driveRemoved(File location);
 	
 	public void addListener(DriveDetectedListener l);
 
 	public void removeListener(DriveDetectedListener l);
+
+	public DriveDetectedInfo[] getDetectedDriveInfo();
 }
diff --git a/com/aelitis/azureus/core/drivedetector/impl/DriveDetectedInfoImpl.java b/com/aelitis/azureus/core/drivedetector/impl/DriveDetectedInfoImpl.java
index b7a25ed..bc7895c 100644
--- a/com/aelitis/azureus/core/drivedetector/impl/DriveDetectedInfoImpl.java
+++ b/com/aelitis/azureus/core/drivedetector/impl/DriveDetectedInfoImpl.java
@@ -20,6 +20,8 @@
 package com.aelitis.azureus.core.drivedetector.impl;
 
 import java.io.File;
+import java.util.Collections;
+import java.util.Map;
 
 import com.aelitis.azureus.core.drivedetector.DriveDetectedInfo;
 
@@ -32,13 +34,23 @@ public class DriveDetectedInfoImpl
 	implements DriveDetectedInfo
 {
 	File location;
+	private Map info;
 	
-	public DriveDetectedInfoImpl(File location) {
+	public DriveDetectedInfoImpl(File location, Map info) {
 		this.location = location;
+		this.info = info;
 	}
 
 	public File getLocation() {
 		return location;
 	}
+	
+	public Object getInfo(String key) {
+		return info.get(key);
+	}
+	
+	public Map<String, Object> getInfoMap() {
+		return Collections.unmodifiableMap(info);
+	}
 
 }
diff --git a/com/aelitis/azureus/core/drivedetector/impl/DriveDetectorImpl.java b/com/aelitis/azureus/core/drivedetector/impl/DriveDetectorImpl.java
index c154006..1f37589 100644
--- a/com/aelitis/azureus/core/drivedetector/impl/DriveDetectorImpl.java
+++ b/com/aelitis/azureus/core/drivedetector/impl/DriveDetectorImpl.java
@@ -20,11 +20,9 @@
 package com.aelitis.azureus.core.drivedetector.impl;
 
 import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
-import org.gudy.azureus2.core3.util.AEMonitor2;
-import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.drivedetector.*;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
@@ -35,16 +33,34 @@ import com.aelitis.azureus.core.util.CopyOnWriteList;
  *
  */
 public class DriveDetectorImpl
-	implements DriveDetector
+	implements DriveDetector,
+	AEDiagnosticsEvidenceGenerator
 {
 	private AEMonitor2 mon_driveDetector = new AEMonitor2("driveDetector");
 
 	private CopyOnWriteList<DriveDetectedListener> listListeners = new CopyOnWriteList<DriveDetectedListener>(1);
 	
-	private List<File> listDrives = new ArrayList<File>(1); 
+	private Map<File, Map> mapDrives = new HashMap<File, Map>(1); 
+	
+	public DriveDetectorImpl() {
+		AEDiagnostics.addEvidenceGenerator(this);
+	}
 
+	public DriveDetectedInfo[] getDetectedDriveInfo() {
+		mon_driveDetector.enter();
+		try {
+			int i = 0;
+			DriveDetectedInfo[] ddi = new DriveDetectedInfo[mapDrives.size()];
+			for (File key : mapDrives.keySet()) {
+				ddi[i++] = new DriveDetectedInfoImpl(key, mapDrives.get(key));
+			}
+			return ddi;
+		} finally {
+			mon_driveDetector.exit();
+		}
+	}
+	
 	public void addListener(DriveDetectedListener l) {
-		File[] drives;
 		mon_driveDetector.enter();
 		try {
 			if (!listListeners.contains(l)) {
@@ -54,30 +70,30 @@ public class DriveDetectorImpl
 				return;
 			}
 			
-			drives = listDrives.toArray(new File[0]);
+
+			for (File key : mapDrives.keySet()) {
+				try {
+					l.driveDetected(new DriveDetectedInfoImpl(key, mapDrives.get(key)));
+				} catch (Throwable e) {
+					Debug.out(e);
+				}
+			}
 		} finally {
 			mon_driveDetector.exit();
 		}
-		
-		for (File drive : drives) {
-			try {
-				l.driveDetected(new DriveDetectedInfoImpl(drive));
-			} catch (Throwable e) {
-				Debug.out(e);
-			}
-		}
 	}
 
 	public void removeListener(DriveDetectedListener l) {
 		listListeners.remove(l);
 	}
 
-	public void driveDetected(File location) {
+	public void driveDetected(File location, Map info) {
 		location = normaliseFile( location );
 		mon_driveDetector.enter();
 		try {
-			if (!listDrives.contains(location)) {
-				listDrives.add(location);
+			if (!mapDrives.containsKey(location)) {
+				info.put("File", location);
+				mapDrives.put(location, info);
 			} else {
 				// already there, no trigger
 				return;
@@ -89,7 +105,7 @@ public class DriveDetectorImpl
 		
 		for (DriveDetectedListener l : listListeners) {
 			try {
-				l.driveDetected(new DriveDetectedInfoImpl(location));
+				l.driveDetected(new DriveDetectedInfoImpl(location, info));
  			} catch (Throwable e) {
  				Debug.out(e);
 			}
@@ -98,9 +114,11 @@ public class DriveDetectorImpl
 
 	public void driveRemoved(File location) {
 		location = normaliseFile( location );
+		Map map;
 		mon_driveDetector.enter();
 		try {
-			if (!listDrives.remove(location)) {
+			map = mapDrives.remove(location);
+			if (map == null) {
 				// not there, no trigger
 				return;
 			}
@@ -110,7 +128,7 @@ public class DriveDetectorImpl
 		
 		for (DriveDetectedListener l : listListeners) {
 			try {
-				l.driveRemoved(new DriveDetectedInfoImpl(location));
+				l.driveRemoved(new DriveDetectedInfoImpl(location, map));
 			} catch (Throwable e) {
 				Debug.out(e);
 			}
@@ -131,4 +149,34 @@ public class DriveDetectorImpl
 			return( f );
 		}	
 	}
+
+	// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
+	public void generate(IndentWriter writer) {
+		synchronized (mapDrives) {
+			writer.println("DriveDetector: " + mapDrives.size() + " drives");
+			for (File file : mapDrives.keySet()) {
+				try {
+					writer.indent();
+					writer.println(file.getPath());
+					
+					try {
+						writer.indent();
+
+  					Map driveInfo = mapDrives.get(file);
+  					for (Iterator iter = driveInfo.keySet().iterator(); iter.hasNext();) {
+  						Object key = (Object) iter.next();
+  						Object val = driveInfo.get(key);
+  						writer.println(key + ": " + val);
+  					}
+					} finally {
+						writer.exdent();
+					}
+				} catch (Throwable e) {
+					Debug.out(e);
+				} finally {
+					writer.exdent();
+				}
+			}
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/impl/AzureusCoreImpl.java b/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
index e0b4622..a33e1cd 100644
--- a/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
+++ b/com/aelitis/azureus/core/impl/AzureusCoreImpl.java
@@ -21,12 +21,14 @@
 
 package com.aelitis.azureus.core.impl;
 
+import java.io.File;
 import java.net.InetAddress;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
+import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
@@ -37,6 +39,7 @@ import org.gudy.azureus2.core3.internat.*;
 import org.gudy.azureus2.core3.ipfilter.IpFilterManager;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.ipfilter.*;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPeerSource;
 import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
@@ -44,15 +47,20 @@ import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
 import org.gudy.azureus2.core3.tracker.host.*;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.platform.PlatformManagerListener;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.utils.DelayedTask;
+import org.gudy.azureus2.plugins.utils.PowerManagementListener;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.*;
+import com.aelitis.azureus.core.backup.BackupManagerFactory;
 import com.aelitis.azureus.core.custom.CustomizationManagerFactory;
 import com.aelitis.azureus.core.dht.DHT;
 import com.aelitis.azureus.core.instancemanager.AZInstanceManager;
@@ -73,6 +81,7 @@ import com.aelitis.azureus.core.peermanager.nat.PeerNATTraverser;
 import com.aelitis.azureus.plugins.clientid.ClientIDPlugin;
 import com.aelitis.azureus.core.security.CryptoManager;
 import com.aelitis.azureus.core.security.CryptoManagerFactory;
+import com.aelitis.azureus.core.speedmanager.SpeedLimitHandler;
 import com.aelitis.azureus.core.speedmanager.SpeedManager;
 import com.aelitis.azureus.core.speedmanager.SpeedManagerAdapter;
 import com.aelitis.azureus.core.speedmanager.SpeedManagerFactory;
@@ -81,8 +90,12 @@ import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 import com.aelitis.azureus.launcher.classloading.PrimaryClassloader;
 import com.aelitis.azureus.plugins.dht.DHTPlugin;
+import com.aelitis.azureus.plugins.startstoprules.defaultplugin.DefaultRankCalculator;
+import com.aelitis.azureus.plugins.startstoprules.defaultplugin.StartStopRulesDefaultPlugin;
 import com.aelitis.azureus.plugins.tracker.dht.DHTTrackerPlugin;
 import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
 
 /**
  * @author parg
@@ -173,6 +186,8 @@ AzureusCoreImpl
 	private CopyOnWriteList		lifecycle_listeners		= new CopyOnWriteList();
 	private List				operation_listeners		= new ArrayList();
 	
+	private CopyOnWriteList<PowerManagementListener>	power_listeners = new CopyOnWriteList<PowerManagementListener>();
+	
 	private AESemaphore			stopping_sem	= new AESemaphore( "AzureusCore::stopping" );
 	
 	private AEMonitor			this_mon		= new AEMonitor( "AzureusCore" );
@@ -181,6 +196,12 @@ AzureusCoreImpl
 	
 	public static boolean SUPPRESS_CLASSLOADER_ERRORS = false;
 	
+	private boolean ca_shutdown_computer_after_stop	= false;
+	private long	ca_last_time_downloading 		= -1;
+	private long	ca_last_time_seeding 			= -1;
+	
+	private boolean prevent_sleep_remove_trigger	= false;
+	
 	protected
 	AzureusCoreImpl()
 	{
@@ -203,14 +224,15 @@ AzureusCoreImpl
 		
 			// set up a backwards pointer from config -> app dir so we can derive one from the other. It'll get saved on closedown, no need to do so now
 				
-		COConfigurationManager.setParameter( "azureus.application.directory", SystemProperties.getApplicationPath());
+		COConfigurationManager.setParameter( "azureus.application.directory", new File( SystemProperties.getApplicationPath()).getAbsolutePath());
+		COConfigurationManager.setParameter( "azureus.user.directory", new File( SystemProperties.getUserPath()).getAbsolutePath());
 		
 		crypto_manager = CryptoManagerFactory.getSingleton();
 		
 		PlatformManagerFactory.getPlatformManager().addListener(
 			new PlatformManagerListener()
 			{
-				public void
+				public int
 				eventOccurred(
 					int		type )
 				{
@@ -220,7 +242,7 @@ AzureusCoreImpl
 							Logger.log(new LogEvent(LOGID, "Platform manager requested shutdown"));
 						}
 						
-						stop();
+						requestStop();
 						
 					}else if ( type == ET_SUSPEND ){
 						
@@ -238,6 +260,8 @@ AzureusCoreImpl
 						
 						announceAll( true );
 					}
+					
+					return( -1 );
 				}
 			});
 		
@@ -636,6 +660,8 @@ AzureusCoreImpl
 		
 		PeerNATTraverser.initialise( this );
 		
+		BackupManagerFactory.getManager( this );
+		
 			// one off explicit GC to clear up initialisation mem
 		
 		SimpleTimer.addEvent(
@@ -921,6 +947,8 @@ AzureusCoreImpl
 
 	   NetworkManager.getSingleton().initialize(this); 
          
+	   SpeedLimitHandler.getSingleton( this );
+	   
 	   Runtime.getRuntime().addShutdownHook( new AEThread("Shutdown Hook") {
 	     public void runSupport() {
 			Logger.log(new LogEvent(LOGID, "Shutdown hook triggered" ));
@@ -1012,6 +1040,8 @@ AzureusCoreImpl
 			   									}
 			   								}
 			   							});
+			   					
+			   					setupSleepAndCloseActions();
 	   						}
 	   					}.start();
 	   				}
@@ -1026,13 +1056,13 @@ AzureusCoreImpl
 
 	   PairingManagerFactory.getSingleton();
 	   
-	   Object[] runningListeners;
+	   AzureusCoreRunningListener[] runningListeners;
 	   mon_coreRunningListeners.enter();
 	   try {
 	  	 if (coreRunningListeners == null) {
-	  		 runningListeners = new Object[0];
+	  		 runningListeners = new AzureusCoreRunningListener[0];
 	  	 } else {
-	  		 runningListeners = coreRunningListeners.toArray();
+	  		 runningListeners = coreRunningListeners.toArray(new AzureusCoreRunningListener[0]);
 	  		 coreRunningListeners = null;
 	  	 }
 	  	 
@@ -1046,6 +1076,14 @@ AzureusCoreImpl
 			public void
 			run()
 			{
+				try{
+					PlatformManagerFactory.getPlatformManager().startup( AzureusCoreImpl.this );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( "PlatformManager: init failed", e );
+				}
+				
 				Iterator	it = lifecycle_listeners.iterator();
 				
 				while( it.hasNext()){
@@ -1083,10 +1121,19 @@ AzureusCoreImpl
 				}
 			}
 		}.start();
-		
-		for (Object l : runningListeners) {
+
+		// Typicially there are many runningListeners, most with quick execution, and 
+		// a few longer ones.  Let 3 run at a time, queue the rest.  Without
+		// a ThreadPool, the slow ones would delay the startup processes that run
+		// after this start() method
+		ThreadPool tp = new ThreadPool("Trigger AzureusCoreRunning Listeners", 3);
+		for (final AzureusCoreRunningListener l : runningListeners) {
 			try {
-				((AzureusCoreRunningListener) l).azureusCoreRunning(this);
+				tp.run(new AERunnable() {
+					public void runSupport() {
+						l.azureusCoreRunning(AzureusCoreImpl.this);
+					}
+				});
 			} catch (Throwable t) {
 				Debug.out(t);
 			}
@@ -1095,6 +1142,12 @@ AzureusCoreImpl
 		// Debug.out("Core Start Complete");
 	}
 
+	public boolean 
+	isInitThread() 
+	{
+		return( AEThread2.isOurThread( Thread.currentThread()));
+	}
+	
 	public boolean
 	isStarted()
 	{
@@ -1199,6 +1252,8 @@ AzureusCoreImpl
 	{
 		AEDiagnostics.flushPendingLogs();
 		
+		boolean	wait_and_return = false;
+		
 		try{
 			this_mon.enter();
 		
@@ -1209,36 +1264,68 @@ AzureusCoreImpl
 									
 				COConfigurationManager.save();
 				
-				Logger.log(new LogEvent(LOGID, "Waiting for stop to complete"));
+				wait_and_return = true;
 				
-				stopping_sem.reserve();
-				
-				return;
-			}
-			
-			stopped	= true;
+			}else{
 			
-			if ( !started ){
-				
-				Logger.log(new LogEvent(LOGID, "Core not started"));
-				
-					// might have been marked dirty due to core being created to allow functions to be used but never started...
+				stopped	= true;
 				
-				if ( AEDiagnostics.isDirty()){
+				if ( !started ){
 					
-					AEDiagnostics.markClean();
-				}
-				
-				stopping_sem.releaseForever();
-				
-				return;
-			}		
-			
+					Logger.log(new LogEvent(LOGID, "Core not started"));
+					
+						// might have been marked dirty due to core being created to allow functions to be used but never started...
+					
+					if ( AEDiagnostics.isDirty()){
+						
+						AEDiagnostics.markClean();
+					}
+					
+					stopping_sem.releaseForever();
+					
+					return;
+				}		
+			}
 		}finally{
 			
 			this_mon.exit();
 		}
 		
+		if ( wait_and_return ){
+			
+			Logger.log(new LogEvent(LOGID, "Waiting for stop to complete"));
+			
+			stopping_sem.reserve();
+			
+			return;
+		}
+		
+		SimpleTimer.addEvent(
+			"ShutFail",
+			SystemTime.getOffsetTime( 30*1000 ),
+			new TimerEventPerformer()
+			{
+				boolean	die_die_die;
+				
+				public void 
+				perform(
+					TimerEvent event )
+				{
+					AEDiagnostics.dumpThreads();
+					
+					if ( die_die_die ){
+					
+						Debug.out( "Shutdown blocked, force exiting" );
+						
+						SESecurityManager.exitVM(0);
+					}
+					
+					die_die_die = true;
+					
+					SimpleTimer.addEvent( "ShutFail", SystemTime.getOffsetTime( 30*1000 ), this );
+				}
+			});
+				
 		List	sync_listeners 	= new ArrayList();
 		List	async_listeners	= new ArrayList();
 		
@@ -1328,7 +1415,7 @@ AzureusCoreImpl
 						}
 					},
 					10*1000 );
-				
+			
 			if (Logger.isEnabled())
 				Logger.log(new LogEvent(LOGID, "Waiting for quiescence"));
 
@@ -1350,50 +1437,121 @@ AzureusCoreImpl
 			}
 			
 			try {
-	      Class c = Class.forName( "sun.awt.AWTAutoShutdown" );
+				Class c = Class.forName( "sun.awt.AWTAutoShutdown" );
 	      
-	      if (c != null) {
-		      c.getMethod( "notifyToolkitThreadFree", new Class[]{} ).invoke( null, new Object[]{} );
-	      }
+				if (c != null) {
+					c.getMethod( "notifyToolkitThreadFree", new Class[]{} ).invoke( null, new Object[]{} );
+				}
 			} catch (Throwable t) {
 			}
 			
+			if ( ca_shutdown_computer_after_stop ){
+				
+				if ( apply_updates ){
+					
+						// best we can do here is wait a while for updates to be applied
+					try{
+						Thread.sleep( 10*1000 );
+						
+					}catch( Throwable e ){
+						
+					}
+				}
+				
+				try{
+					PlatformManagerFactory.getPlatformManager().shutdown( PlatformManager.SD_SHUTDOWN );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( "PlatformManager: shutdown failed", e );
+				}
+			}
+		
 			try{
 				ThreadGroup	tg = Thread.currentThread().getThreadGroup();
 				
-				Thread[]	threads = new Thread[tg.activeCount()+32];
+				while( tg.getParent() != null ){
+					
+					tg = tg.getParent();
+				}
+				
+				Thread[]	threads = new Thread[tg.activeCount()+1024];
+				
+				tg.enumerate( threads, true );
 				
-				tg.enumerate( threads );
+				boolean	bad_found = false;
 				
 				for (int i=0;i<threads.length;i++){
 					
-					final Thread	t = threads[i];
-					
+					Thread	t = threads[i];
+										
 					if ( t != null && t.isAlive() && t != Thread.currentThread() && !t.isDaemon() && !AEThread2.isOurThread( t )){
+					
+						bad_found = true;
 						
-						new AEThread2( "VMKiller", true )
+						break;
+					}
+				}
+				
+				if ( bad_found ){
+										
+					new AEThread2( "VMKiller", true )
+					{
+						public void
+						run()
 						{
-							public void
-							run()
-							{
-								try{
-									Thread.sleep(10*1000);
-									
-									Debug.out( "Non-daemon thread found '" + t.getName() + "', force closing VM" );
-									
-									SESecurityManager.exitVM(0);
+							try{
+								Thread.sleep(10*1000);
+								
+								ThreadGroup	tg = Thread.currentThread().getThreadGroup();
+								
+								Thread[]	threads = new Thread[tg.activeCount()+1024];
+								
+								tg.enumerate( threads, true );
+								
+								String	bad_found = "";
+								
+								for (int i=0;i<threads.length;i++){
 									
-								}catch( Throwable e ){
+									Thread	t = threads[i];
+																		
+									if ( t != null && t.isAlive() && !t.isDaemon() && !AEThread2.isOurThread( t )){
 									
+										String	details = t.getName();
+										
+										StackTraceElement[] trace = t.getStackTrace();
+										
+										if ( trace.length > 0 ){
+											
+											details += "[";
+											
+											for ( int j=0;j<trace.length;j++ ){
+											
+												details += (j==0?"":",") + trace[j];
+											}
+											
+											details += "]";
+										}
+										
+										bad_found += (bad_found.length()==0?"":", ") + details;
+									}
 								}
+								
+								Debug.out( "Non-daemon thread(s) found: '" + bad_found + "' - force closing VM" );
+								
+								SESecurityManager.exitVM(0);
+								
+							}catch( Throwable e ){
+								
 							}
-						}.start();
-						
-						break;
-					}
+						}
+					}.start();
+	
 				}
 			}catch( Throwable e ){
 			}
+			
+	
 		}finally{
 			
 			stopping_sem.releaseForever();
@@ -1505,6 +1663,19 @@ AzureusCoreImpl
 		}
 	}
 	
+	public void
+	saveState()
+	{
+		GlobalManager	gm = global_manager;
+		
+		if ( gm != null ){
+			
+			gm.saveState();
+		}
+		
+		COConfigurationManager.save();
+	}
+	
 	public GlobalManager
 	getGlobalManager()
 	
@@ -1576,6 +1747,507 @@ AzureusCoreImpl
 		return( nat_traverser );
 	}
 	
+	private void
+	setupSleepAndCloseActions()
+	{
+		if ( PlatformManagerFactory.getPlatformManager().hasCapability( PlatformManagerCapabilities.PreventComputerSleep )){
+			
+			COConfigurationManager.addAndFireParameterListeners(
+				new String[]{
+					"Prevent Sleep Downloading",
+					"Prevent Sleep FP Seeding",
+				},
+				new ParameterListener()
+				{
+					private TimerEventPeriodic timer_event;
+
+					public void 
+					parameterChanged(
+						String parameterName )
+					{
+						synchronized( this ){
+					
+							boolean dl = COConfigurationManager.getBooleanParameter( "Prevent Sleep Downloading" );
+							boolean se = COConfigurationManager.getBooleanParameter( "Prevent Sleep FP Seeding" );
+							
+							boolean	active = dl || se;
+								
+							try{
+								setPreventComputerSleep( PlatformManagerFactory.getPlatformManager(), active, "config change" );
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+							
+							
+							if ( !active ){
+								
+								if ( timer_event != null ){
+									
+									timer_event.cancel();
+									
+									timer_event = null;
+								}
+							}else{
+							
+								if ( timer_event == null ){
+									
+									timer_event = 
+										SimpleTimer.addPeriodicEvent(
+												"core:sleepAct",
+												2*60*1000,
+												new TimerEventPerformer()
+												{
+													public void 
+													perform(
+														TimerEvent event )
+													{
+														checkSleepActions();
+													}
+												});
+								}
+							}
+						}
+					}
+				});
+		}
+		
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+					"On Downloading Complete Do",
+					"On Seeding Complete Do"
+			},
+			new ParameterListener()
+			{
+				private TimerEventPeriodic timer_event;
+				
+				public void 
+				parameterChanged(
+					String parameterName )
+				{
+					String	dl_act = COConfigurationManager.getStringParameter( "On Downloading Complete Do" );
+					String	se_act = COConfigurationManager.getStringParameter( "On Seeding Complete Do" );
+					
+					synchronized( this ){
+						
+						boolean	dl_nothing 	= dl_act.equals( "Nothing" );
+						boolean se_nothing	= se_act.equals( "Nothing" );
+						
+						if ( dl_nothing ){
+							
+							ca_last_time_downloading	= -1;
+						}
+						
+						if ( se_nothing ){
+							
+							ca_last_time_seeding	= -1;
+						}
+				
+						if ( dl_nothing && se_nothing ){
+							
+							if ( timer_event != null ){
+								
+								timer_event.cancel();
+								
+								timer_event = null;
+							}
+						}else{
+						
+							if ( timer_event == null ){
+								
+								timer_event = 
+									SimpleTimer.addPeriodicEvent(
+											"core:closeAct",
+											30*1000,
+											new TimerEventPerformer()
+											{
+												public void 
+												perform(
+													TimerEvent event )
+												{
+													checkCloseActions();
+												}
+											});
+							}
+							
+							checkCloseActions();
+						}
+					}
+				}
+			});
+	}
+
+	protected void
+	checkSleepActions()
+	{
+		boolean ps_downloading 	= COConfigurationManager.getBooleanParameter( "Prevent Sleep Downloading" );
+		boolean ps_fp_seed	 	= COConfigurationManager.getBooleanParameter( "Prevent Sleep FP Seeding" );
+
+		String	declining_subsystems = "";
+		
+		for ( PowerManagementListener l: power_listeners ){
+			
+			try{
+				if ( !l.requestPowerStateChange( PowerManagementListener.ST_SLEEP, null )){
+					
+					declining_subsystems += (declining_subsystems.length()==0?"":",") + l.getPowerName();
+				}
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		if ( declining_subsystems.length() == 0 && !( ps_downloading || ps_fp_seed )){
+
+			return;
+		}
+
+		PlatformManager platform = PlatformManagerFactory.getPlatformManager();
+
+		boolean	prevent_sleep 	= false;
+		String	prevent_reason	= null;
+
+		if ( declining_subsystems.length() > 0 ){
+			
+			prevent_sleep 	= true;
+			prevent_reason 	= "subsystems declined sleep: " +  declining_subsystems;
+			
+		}else{
+			
+			List<DownloadManager> managers = getGlobalManager().getDownloadManagers();
+
+			for ( DownloadManager manager: managers ){
+	
+				int state = manager.getState();
+	
+				if ( state == DownloadManager.STATE_FINISHING ){
+	
+					if ( ps_downloading ){
+	
+						prevent_sleep 	= true;
+						prevent_reason	= "active downloads";
+						
+						break;
+					}
+	
+				}else{
+	
+					if ( state == DownloadManager.STATE_DOWNLOADING ){
+	
+						PEPeerManager pm = manager.getPeerManager();
+	
+						if ( pm != null ){
+	
+							if ( pm.hasDownloadablePiece()){
+	
+								if ( ps_downloading ){
+	
+									prevent_sleep 	= true;
+									prevent_reason	= "active downloads";
+	
+									break;
+								}
+							}else{
+	
+									// its effectively seeding, change so logic about recheck obeyed below
+	
+								state = DownloadManager.STATE_SEEDING;
+							}
+						}
+					}
+	
+					if ( state == DownloadManager.STATE_SEEDING && ps_fp_seed ){
+	
+						DiskManager disk_manager = manager.getDiskManager();
+	
+						if ( disk_manager != null && disk_manager.getCompleteRecheckStatus() != -1 ){
+	
+								// wait until recheck is complete before we mark as downloading-complete
+	
+							if ( ps_downloading ){
+	
+								prevent_sleep 	= true;
+								prevent_reason	= "active downloads";
+	
+								break;
+							}
+	
+						}else{
+	
+							try{
+								DefaultRankCalculator calc = StartStopRulesDefaultPlugin.getRankCalculator( PluginCoreUtils.wrap( manager ));
+	
+								if ( calc.getCachedIsFP()){
+									
+									prevent_sleep 	= true;
+									prevent_reason	= "first-priority seeding";
+	
+									break;
+								}
+							}catch( Throwable e ){
+	
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		if ( prevent_sleep != platform.getPreventComputerSleep()){
+			
+			if ( prevent_sleep ){
+				
+				prevent_sleep_remove_trigger = false;
+				
+			}else{
+				
+				if ( !prevent_sleep_remove_trigger ){
+					
+					prevent_sleep_remove_trigger = true;
+					
+					return;
+				}
+			}
+			
+			if ( prevent_reason == null ){
+				
+				if ( ps_downloading && ps_fp_seed ){
+					
+					prevent_reason = "no active downloads or first-priority seeding";
+					
+				}else if ( ps_downloading ){
+					
+					prevent_reason = "no active downloads";
+					
+				}else{
+					
+					prevent_reason = "no active first-priority seeding";
+				}
+			}
+
+			setPreventComputerSleep( platform, prevent_sleep, prevent_reason );
+		}
+	}
+	
+	private void
+	setPreventComputerSleep(
+		PlatformManager		platform,
+		boolean				prevent_sleep,
+		String				prevent_reason )
+	{
+		for ( PowerManagementListener l: power_listeners ){
+			
+			try{
+				l.informPowerStateChange( PowerManagementListener.ST_SLEEP, new Object[]{ prevent_sleep, prevent_reason });
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		Logger.log( new LogEvent(LOGID, "Computer sleep prevented state changed to '" + prevent_sleep + "' due to " + prevent_reason ));	
+
+		try{
+			platform.setPreventComputerSleep( prevent_sleep );
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	protected void
+	checkCloseActions()
+	{
+		List<DownloadManager> managers = getGlobalManager().getDownloadManagers();
+		
+		boolean	is_downloading 	= false;
+		boolean is_seeding		= false;
+		
+		for ( DownloadManager manager: managers ){
+			
+			if ( manager.isPaused()){
+			
+					// if anything's paused we don't want to trigger any actions as something transient (e.g. speed test) is going on
+				
+				return;
+			}
+			
+			int state = manager.getState();
+			
+			if ( state == DownloadManager.STATE_FINISHING ){
+
+				is_downloading = true;
+				
+			}else{
+			
+				if ( state == DownloadManager.STATE_DOWNLOADING ){
+					
+					PEPeerManager pm = manager.getPeerManager();
+					
+					if ( pm != null ){
+						
+						if ( pm.hasDownloadablePiece()){
+							
+							is_downloading = true;
+							
+						}else{
+				
+								// its effectively seeding, change so logic about recheck obeyed below
+							
+							state = DownloadManager.STATE_SEEDING;
+						}
+					}
+				}
+				
+				if ( state == DownloadManager.STATE_SEEDING ){
+				
+					DiskManager disk_manager = manager.getDiskManager();
+	
+					if ( disk_manager != null && disk_manager.getCompleteRecheckStatus() != -1 ){
+					
+							// wait until recheck is complete before we mark as downloading-complete
+						
+						is_downloading	= true;
+						
+					}else{
+						
+						is_seeding		= true;
+					}
+				}
+			}
+		}
+		
+		long	now = SystemTime.getMonotonousTime();
+		
+		if ( is_downloading ){
+			
+			ca_last_time_downloading 	= now;
+			ca_last_time_seeding		= -1;
+			
+		}else if ( is_seeding ){
+			
+			ca_last_time_seeding = now;
+		}
+		
+		String	dl_act = COConfigurationManager.getStringParameter( "On Downloading Complete Do" );
+		
+		if ( !dl_act.equals( "Nothing" )){
+		
+			if ( ca_last_time_downloading >= 0 && !is_downloading && now - ca_last_time_downloading >= 30*1000 ){
+				
+				executeCloseAction( true, dl_act );
+			}
+		}
+		
+		String	se_act = COConfigurationManager.getStringParameter( "On Seeding Complete Do" );
+
+		if ( !se_act.equals( "Nothing" )){
+			
+			if ( ca_last_time_seeding >= 0 && !is_seeding && now - ca_last_time_seeding >= 30*1000 ){
+				
+				executeCloseAction( false, se_act );
+			}
+		}
+	}
+	
+	private void
+	executeCloseAction(
+		final boolean	download_trigger,
+		final String	action )
+	{
+			// prevent retriggering on resume from standby
+		
+		ca_last_time_downloading	= -1;
+		ca_last_time_seeding		= -1;
+		
+		boolean reset = COConfigurationManager.getBooleanParameter( "Stop Triggers Auto Reset" );
+		
+		if ( reset ){
+			
+			if ( download_trigger ){
+			
+				COConfigurationManager.setParameter( "On Downloading Complete Do", "Nothing" );
+				
+			}else{
+				
+				COConfigurationManager.setParameter( "On Seeding Complete Do", "Nothing" );
+			}
+		}
+		
+		String type_str		= MessageText.getString( "core.shutdown." + (download_trigger?"dl":"se"));
+		String action_str 	= MessageText.getString( "ConfigView.label.stop." + action );
+				
+		String message = 
+			MessageText.getString( 
+				"core.shutdown.alert",
+				new String[]{
+					action_str,
+					type_str,
+				});
+		
+		UIFunctions ui_functions = UIFunctionsManager.getUIFunctions();
+		
+		if ( ui_functions != null ){
+		
+			ui_functions.forceNotify( UIFunctions.STATUSICON_NONE, null, message, null, new Object[0], -1 );
+		}
+		
+		Logger.log( 
+			new LogAlert( 
+				LogAlert.UNREPEATABLE, 
+				LogEvent.LT_INFORMATION,
+				message ));
+
+		new DelayedEvent(
+			"CoreShutdown",
+			10*1000,
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					Logger.log( new LogEvent(LOGID, "Executing close action '" + action + "' due to " + (download_trigger?"downloading":"seeding") + " completion" ));					
+					
+						// quit vuze -> quit
+						// shutdown computer -> quit vuze + shutdown
+						// sleep/hibernate = announceAll and then sleep/hibernate with Vuze still running
+					
+					if ( action.equals( "QuitVuze" )){
+						
+						requestStop();
+					
+					}else if ( action.equals( "Sleep" ) || action.equals( "Hibernate" )){
+
+						announceAll( true );
+						
+						try{
+							PlatformManagerFactory.getPlatformManager().shutdown( 
+									action.equals( "Sleep" )?PlatformManager.SD_SLEEP:PlatformManager.SD_HIBERNATE );
+							
+						}catch( Throwable e ){
+							
+							Debug.out( "PlatformManager: shutdown failed", e );
+						}
+						
+					}else if ( action.equals( "Shutdown" )){
+
+						ca_shutdown_computer_after_stop = true;
+						
+						requestStop();
+						
+					}else{
+						
+						Debug.out( "Unknown close action '" + action + "'" );
+					}
+				}
+			});
+	}
+	
 	public AzureusCoreOperation
 	createOperation(
 		final int		type )
@@ -1785,4 +2457,18 @@ AzureusCoreImpl
 	   
 	   l.azureusCoreRunning(AzureusCoreImpl.getSingleton());
 	}
+	
+	public void
+	addPowerManagementListener(
+		PowerManagementListener	listener )
+	{
+		power_listeners.add( listener );
+	}
+		
+	public void
+	removePowerManagementListener(
+		PowerManagementListener	listener )
+	{
+		power_listeners.remove( listener );
+	}
 }
diff --git a/com/aelitis/azureus/core/instancemanager/AZInstance.java b/com/aelitis/azureus/core/instancemanager/AZInstance.java
index 5c97f22..40b27d8 100644
--- a/com/aelitis/azureus/core/instancemanager/AZInstance.java
+++ b/com/aelitis/azureus/core/instancemanager/AZInstance.java
@@ -22,7 +22,7 @@
 
 package com.aelitis.azureus.core.instancemanager;
 
-import java.util.List;
+import java.util.*;
 import java.net.InetAddress;
 
 public interface 
@@ -52,6 +52,9 @@ AZInstance
 	public int
 	getUDPNonDataListenPort();
 	
+	public Map<String,Object>
+	getProperties();
+	
 	public String
 	getString();
 }
diff --git a/com/aelitis/azureus/core/instancemanager/AZInstanceManager.java b/com/aelitis/azureus/core/instancemanager/AZInstanceManager.java
index 1445c7c..38f4b5d 100644
--- a/com/aelitis/azureus/core/instancemanager/AZInstanceManager.java
+++ b/com/aelitis/azureus/core/instancemanager/AZInstanceManager.java
@@ -43,9 +43,15 @@ AZInstanceManager
 	public AZInstance
 	getMyInstance();
 	
+	public int
+	getOtherInstanceCount();
+	
 	public AZInstance[]
 	getOtherInstances();
 	
+	public void
+	updateNow();
+	
 	public AZInstanceTracked[]
 	track(
 		byte[]								hash,
diff --git a/com/aelitis/azureus/core/instancemanager/impl/AZInstanceImpl.java b/com/aelitis/azureus/core/instancemanager/impl/AZInstanceImpl.java
index 59f4c32..a6f1a59 100644
--- a/com/aelitis/azureus/core/instancemanager/impl/AZInstanceImpl.java
+++ b/com/aelitis/azureus/core/instancemanager/impl/AZInstanceImpl.java
@@ -53,6 +53,13 @@ AZInstanceImpl
         map.put( "dp", new Long( getUDPListenPort()));
         
         map.put( "dp2", new Long( getUDPNonDataListenPort()));
+        
+        Map<String,Object> props = getProperties();
+        
+        if ( props != null ){
+        	
+        	map.put( "pr", props );
+        }
 	}
 	
 	public String
@@ -71,6 +78,7 @@ AZInstanceImpl
 				",ext=" + getExternalAddress().getHostAddress() +	
 				",tcp=" + getTCPListenPort() + 
 				",udp=" + getUDPListenPort() +
-				",udp2=" + getUDPNonDataListenPort());
+				",udp2=" + getUDPNonDataListenPort() + 
+				",props=" + getProperties());
 	}
 }
diff --git a/com/aelitis/azureus/core/instancemanager/impl/AZInstanceManagerImpl.java b/com/aelitis/azureus/core/instancemanager/impl/AZInstanceManagerImpl.java
index fc50834..7dd5c12 100644
--- a/com/aelitis/azureus/core/instancemanager/impl/AZInstanceManagerImpl.java
+++ b/com/aelitis/azureus/core/instancemanager/impl/AZInstanceManagerImpl.java
@@ -46,6 +46,7 @@ import com.aelitis.azureus.core.util.NetUtils;
 import com.aelitis.azureus.plugins.dht.DHTPlugin;
 import com.aelitis.net.udp.mc.MCGroup;
 import com.aelitis.net.udp.mc.MCGroupAdapter;
+import com.aelitis.net.udp.mc.MCGroupException;
 import com.aelitis.net.udp.mc.MCGroupFactory;
 
 public class 
@@ -165,6 +166,7 @@ AZInstanceManagerImpl
 	private volatile boolean		include_well_known_lans	= true;
 	
 	private AESemaphore	initial_search_sem	= new AESemaphore( "AZInstanceManager:initialSearch" );
+	private boolean		init_wait_abandoned;
 	
 	private AEMonitor	this_mon = new AEMonitor( "AZInstanceManager" );
 
@@ -187,14 +189,22 @@ AZInstanceManagerImpl
 		try{
 			initialised = true;
 			
-			mc_group = 
-				MCGroupFactory.getSingleton(
-					this,
-					MC_GROUP_ADDRESS,
-					MC_GROUP_PORT,
-					MC_CONTROL_PORT,
-					null );
-					
+			boolean	enable = System.getProperty( "az.instance.manager.enable", "1" ).equals( "1" );
+			
+			if ( enable ){
+				
+				mc_group = 
+					MCGroupFactory.getSingleton(
+						this,
+						MC_GROUP_ADDRESS,
+						MC_GROUP_PORT,
+						MC_CONTROL_PORT,
+						null );
+			}else{
+				
+				mc_group = getDummyMCGroup();
+			}
+			
 			adapter.addListener(
 				new AZInstanceManagerAdapter.StateListener()
 				{
@@ -229,6 +239,11 @@ AZInstanceManagerImpl
 		
 		}catch( Throwable e ){
 			
+			if ( mc_group == null ){
+				
+				mc_group = getDummyMCGroup();
+			}
+			
 			initial_search_sem.releaseForever();
 			
 			Debug.printStackTrace(e);
@@ -254,6 +269,41 @@ AZInstanceManagerImpl
 		}.start();
 	}
 	
+	private MCGroup
+	getDummyMCGroup()
+	{
+		return( 
+			new MCGroup()
+			{
+				public int
+				getControlPort()
+				{
+					return( MC_CONTROL_PORT );
+				}
+				
+				public void
+				sendToGroup(
+					byte[]	data )
+				{
+				}
+								
+				public void
+				sendToGroup(
+					String	param_data )
+				{	
+				}
+				
+				public void
+				sendToMember(
+					InetSocketAddress	address,
+					byte[]				data )
+				
+					throws MCGroupException
+				{
+				}
+			});
+	}
+	
 	public long 
 	getClockSkew() 
 	{
@@ -295,6 +345,12 @@ AZInstanceManagerImpl
 		return( initial_search_sem.isReleasedForever());
 	}
 	
+	public void
+	updateNow()
+	{
+		sendAlive();
+	}
+	
 	protected boolean
 	isClosing()
 	{
@@ -419,7 +475,7 @@ AZInstanceManagerImpl
 	{
 		try{
 			Map	map = BDecoder.decode( data, 0, length );
-			
+						
 			long	version = ((Long)map.get( "ver" )).longValue();
 			long	type	= ((Long)map.get( "type" )).longValue();
 			
@@ -639,10 +695,26 @@ AZInstanceManagerImpl
 		sendRequest( MT_REQUEST_SEARCH );
 	}
 	
+	public int
+  	getOtherInstanceCount()
+  	{
+		waitForInit();
+		
+  		try{
+  			this_mon.enter();
+
+  			return( other_instances.size());
+  			
+  		}finally{
+  			
+  			this_mon.exit();
+  		}
+  	}
+	
 	public AZInstance[]
 	getOtherInstances()
 	{
-		initial_search_sem.reserve();
+		waitForInit();
 		
 		try{
 			this_mon.enter();
@@ -655,6 +727,21 @@ AZInstanceManagerImpl
 		}
 	}
 	
+	private void
+	waitForInit()
+	{
+		if ( init_wait_abandoned ){
+			
+			return;
+		}
+		
+  		if ( !initial_search_sem.reserve(2500)){
+  			Debug.out( "Instance manager - timeout waiting for initial search" );
+  			
+  			init_wait_abandoned = true;
+  		}
+	}
+	
 	protected void
 	addAddresses(
 		AZInstance	inst )
diff --git a/com/aelitis/azureus/core/instancemanager/impl/AZMyInstanceImpl.java b/com/aelitis/azureus/core/instancemanager/impl/AZMyInstanceImpl.java
index 6d5e9e2..c1e591f 100644
--- a/com/aelitis/azureus/core/instancemanager/impl/AZMyInstanceImpl.java
+++ b/com/aelitis/azureus/core/instancemanager/impl/AZMyInstanceImpl.java
@@ -26,6 +26,7 @@ import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.config.COConfigurationListener;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -403,4 +404,10 @@ AZMyInstanceImpl
 	{
 		return( udp_non_data_port );
 	}
+	
+	public Map<String, Object> 
+	getProperties() 
+	{
+		return((Map<String, Object>)COConfigurationManager.getMapParameter( "instance.manager.props", null ));
+	}
 }
diff --git a/com/aelitis/azureus/core/instancemanager/impl/AZOtherInstanceImpl.java b/com/aelitis/azureus/core/instancemanager/impl/AZOtherInstanceImpl.java
index 92d5bc3..e3a707e 100644
--- a/com/aelitis/azureus/core/instancemanager/impl/AZOtherInstanceImpl.java
+++ b/com/aelitis/azureus/core/instancemanager/impl/AZOtherInstanceImpl.java
@@ -63,6 +63,8 @@ AZOtherInstanceImpl
 			app_id = new String( app_id_bytes );
 		}
 		
+		Map<String,Object>	props = (Map<String,Object>)map.get( "pr" );
+		
 		try{
 			if ( !int_ip.equals("0.0.0.0")){
 				
@@ -75,7 +77,7 @@ AZOtherInstanceImpl
 			
 			if ( internal_address instanceof Inet4Address == external_address instanceof Inet4Address ){
 				
-				return( new AZOtherInstanceImpl(id, app_id, internal_address, external_address, tcp, udp, udp_other ));
+				return( new AZOtherInstanceImpl(id, app_id, internal_address, external_address, tcp, udp, udp_other, props ));
 			}
 			
 			return( null );
@@ -95,6 +97,7 @@ AZOtherInstanceImpl
 	private int						tcp_port;
 	private int						udp_port;
 	private int						udp_non_data_port;
+	private Map<String,Object>		props;
 	
 	private long	alive_time;
 
@@ -107,7 +110,8 @@ AZOtherInstanceImpl
 		InetAddress				_external_address,
 		int						_tcp_port,
 		int						_udp_port,
-		int						_udp_non_data_port )
+		int						_udp_non_data_port,
+		Map<String,Object>		_props )
 	{
 		id					= _id;
 		app_id				= _app_id;
@@ -118,6 +122,8 @@ AZOtherInstanceImpl
 		tcp_port			= _tcp_port;
 		udp_port			= _udp_port;
 		udp_non_data_port	= _udp_non_data_port;
+	
+		props				= _props;
 		
 		alive_time	= SystemTime.getCurrentTime();
 	}
@@ -204,6 +210,12 @@ AZOtherInstanceImpl
 		return( udp_non_data_port );
 	}
 	
+	public Map<String, Object> 
+	getProperties() 
+	{
+		return( props );
+	}
+	
 	protected long
 	getAliveTime()
 	{
diff --git a/com/aelitis/azureus/core/lws/LWSDiskManager.java b/com/aelitis/azureus/core/lws/LWSDiskManager.java
index 63059dc..2e5accf 100644
--- a/com/aelitis/azureus/core/lws/LWSDiskManager.java
+++ b/com/aelitis/azureus/core/lws/LWSDiskManager.java
@@ -85,6 +85,7 @@ LWSDiskManager
 	private String						internal_name;
 	private DownloadManagerState		download_state;
 	
+	private boolean	started;
 	private int 	state 			= DiskManager.INITIALIZING;
 	private String	error_message	= "";
 	
@@ -155,10 +156,11 @@ LWSDiskManager
 			reader.start();
 			
 			if ( state != DiskManager.FAULTY ){
-				
-				state = DiskManager.READY;
-			}
 			
+				started = true;
+
+				state = DiskManager.READY;
+			}						
 		}catch( Throwable e ){
 			
 			setFailed( "start failed - " + Debug.getNestedExceptionMessage(e));
@@ -197,7 +199,7 @@ LWSDiskManager
 											new File( save_location, relative_file.toString()), 
 											i,
 											pm_info.getTorrentFile(),
-											true );
+											DiskManagerFileInfo.ST_LINEAR );
 				
 				local_files[i] = file_info;
 
@@ -250,10 +252,12 @@ LWSDiskManager
 	{
 	}
 	
-	public void
+	public boolean
 	stop(
 		boolean	closing )
 	{
+		started = false;
+		
 		if ( reader != null ){
 		
 			reader.stop();
@@ -274,8 +278,16 @@ LWSDiskManager
 				}
 			}
 		}
+
+		return( false );
 	}
 
+    public boolean 
+    isStopped() 
+    {
+    	return( !started );
+    }
+    
 	public boolean
 	filesExist()
 	{
@@ -496,21 +508,15 @@ LWSDiskManager
 	}
   
 	public void
-	downloadEnded()
+	downloadEnded( OperationStatus op_status )
 	{
 	}
-
-	public void
-	moveDataFiles(
-		File	new_parent_dir )
-	{
-		throw( new RuntimeException( "moveDataFiles not implemented" ));
-	}
 	
 	public void 
 	moveDataFiles(
-		File 	new_parent_dir, 
-		String 	new_name )
+		File 				new_parent_dir, 
+		String 				new_name,
+		OperationStatus		op_status )
 	{
 		throw( new RuntimeException( "moveDataFiles not implemented" ));
 	}
@@ -521,6 +527,12 @@ LWSDiskManager
 		return( -1 );
 	}
 	
+    public int
+    getMoveProgress()
+    {
+    	return( -1 );
+    }
+    
 	public boolean 
 	checkBlockConsistencyForWrite(
 		String				originator,
@@ -537,11 +549,12 @@ LWSDiskManager
 	public boolean 
 	checkBlockConsistencyForRead(
 		String	originator,
+	    boolean	peer_request,
 		int 	pieceNumber, 
 		int		offset, 
 		int 	length )
 	{
-		return( DiskManagerUtil.checkBlockConsistencyForRead( this, originator, pieceNumber, offset, length));
+		return( DiskManagerUtil.checkBlockConsistencyForRead( this, originator, peer_request, pieceNumber, offset, length));
 	}	
    
 	public boolean 
@@ -645,6 +658,8 @@ LWSDiskManager
 	setFailed(
 		String		reason )
 	{
+		started = false;
+		
 		state	= FAULTY;
 		
 		error_message	= reason;
@@ -655,6 +670,8 @@ LWSDiskManager
 		DiskManagerFileInfo		file,
 		String					reason )
 	{
+		started = false;
+		
 		state	= FAULTY;
 		
 		error_message	= reason;
diff --git a/com/aelitis/azureus/core/lws/LWSDiskManagerState.java b/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
index dc69a7e..9b59673 100644
--- a/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
+++ b/com/aelitis/azureus/core/lws/LWSDiskManagerState.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.category.Category;
+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;
@@ -270,17 +271,17 @@ LWSDiskManagerState
 	{
 	}
 	
-	public String 
-	getPrimaryFile() 
-	{
-		return null;
-	}
-	
 	public void 
 	setPrimaryFile(
-		String fileFullPath) 
+		DiskManagerFileInfo dmfi)
 	{
 	}
+
+	public DiskManagerFileInfo 
+	getPrimaryFile() 
+	{
+		return null;
+	}
 	
 	public String[]		
 	getNetworks()
diff --git a/com/aelitis/azureus/core/lws/LWSDownload.java b/com/aelitis/azureus/core/lws/LWSDownload.java
index 1b10073..d41055e 100644
--- a/com/aelitis/azureus/core/lws/LWSDownload.java
+++ b/com/aelitis/azureus/core/lws/LWSDownload.java
@@ -45,6 +45,7 @@ import org.gudy.azureus2.plugins.download.DownloadStats;
 import org.gudy.azureus2.plugins.download.DownloadTrackerListener;
 import org.gudy.azureus2.plugins.download.DownloadWillBeRemovedListener;
 import org.gudy.azureus2.plugins.download.savelocation.SaveLocationChange;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
 import org.gudy.azureus2.plugins.torrent.TorrentManager;
@@ -570,6 +571,22 @@ LWSDownload
   		return( 0 );
   	}
 
+	public void
+	addRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		notSupported();
+	}
+		
+	public void
+	removeRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		notSupported();
+	}
+	
     public int 
     getUploadRateLimitBytesPerSecond()
     {
@@ -615,6 +632,12 @@ LWSDownload
 		return( false );
 	}
 	
+	public boolean
+ 	isMoving()
+ 	{
+		return( false );
+ 	}
+	
   	public String
 	getSavePath()
   	{
@@ -671,6 +694,18 @@ LWSDownload
 	{
 		return( null );
 	}
+	
+	public DiskManagerFileInfo
+	getDiskManagerFileInfo(int i)
+	{
+		return( null );
+	}
+
+	public int getDiskManagerFileCount()
+	{
+		return 0;
+	}
+
 
   	public void
 	requestTrackerAnnounce()
diff --git a/com/aelitis/azureus/core/lws/LWSPeerManagerAdapter.java b/com/aelitis/azureus/core/lws/LWSPeerManagerAdapter.java
index ddb1b7a..a0d67cf 100644
--- a/com/aelitis/azureus/core/lws/LWSPeerManagerAdapter.java
+++ b/com/aelitis/azureus/core/lws/LWSPeerManagerAdapter.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.lws;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequestListener;
@@ -82,6 +83,36 @@ LWSPeerManagerAdapter
 		return( 0 );
 	}
 	
+	public int 
+	getPermittedBytesToReceive()
+	{
+		return( Integer.MAX_VALUE );
+	}
+	
+	public void 
+	permittedReceiveBytesUsed( 
+		int bytes )
+	{
+	}
+	
+	public int 
+	getPermittedBytesToSend()
+	{
+		return( Integer.MAX_VALUE );
+	}
+	
+	public void	
+	permittedSendBytesUsed(	
+		int bytes )
+	{
+	}
+	
+	public int
+	getUploadPriority()
+	{
+		return( 0 );
+	}
+	
 	public int
 	getMaxUploads()
 	{
@@ -167,6 +198,25 @@ LWSPeerManagerAdapter
 		
 	}
 	
+	public boolean 
+	isMetadataDownload() 
+	{
+		return( false );
+	}
+	
+	public int 
+	getTorrentInfoDictSize() 
+	{
+		return( 0 );
+	}
+	
+	public byte[]
+	getTorrentInfoDict(
+		PEPeer	peer )
+	{
+		return( null );
+	}
+	
 	public boolean
 	isNATHealthy()
 	{
@@ -232,6 +282,14 @@ LWSPeerManagerAdapter
 	{
 	}
 	
+	public void 
+	statsRequest(
+		PEPeer 	originator, 
+		Map 	request,
+		Map		reply )
+	{		
+	}
+	
 	public void
 	addHTTPSeed(
 		String	address,
diff --git a/com/aelitis/azureus/core/lws/LWSTorrent.java b/com/aelitis/azureus/core/lws/LWSTorrent.java
index 6b50654..17148ba 100644
--- a/com/aelitis/azureus/core/lws/LWSTorrent.java
+++ b/com/aelitis/azureus/core/lws/LWSTorrent.java
@@ -33,6 +33,7 @@ import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLGroup;
 import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
 import org.gudy.azureus2.core3.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
+import org.gudy.azureus2.core3.torrent.TOTorrentListener;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.HashWrapper;
@@ -46,26 +47,43 @@ LWSTorrent
 	private static TOTorrentAnnounceURLGroup announce_group = 
 		new TOTorrentAnnounceURLGroup()
 		{
+			private TOTorrentAnnounceURLSet[]	sets = new TOTorrentAnnounceURLSet[0];
+			
 			public TOTorrentAnnounceURLSet[]
            	getAnnounceURLSets()
 			{
-				return( new TOTorrentAnnounceURLSet[0]);
+				return( sets );
 			}           	
  
            	public void
            	setAnnounceURLSets(
-           		TOTorrentAnnounceURLSet[]	sets )
+           		TOTorrentAnnounceURLSet[]	_sets )
            	{
-           		notSupported();
+           		sets	= _sets;
            	}
            		
            	public TOTorrentAnnounceURLSet
            	createAnnounceURLSet(
-           		URL[]	urls )
+           		final URL[]	_urls )
            	{
-           		notSupported();
-           		
-           		return( null );
+           		return( 
+           			new TOTorrentAnnounceURLSet()
+           			{
+           				private URL[] urls = _urls;
+           				
+           				public URL[]
+           				getAnnounceURLs()
+           				{
+           					return( urls );
+           				}
+           				    	
+           				public void
+           				setAnnounceURLs(
+           					URL[]		_urls )
+           				{
+           					urls = _urls;
+           				}
+           			});
            	}
 		};
 		
@@ -97,7 +115,11 @@ LWSTorrent
 	{
 		return( lws.getName().getBytes());
 	}
-	
+
+	public String getUTF8Name() {
+		return lws.getName();
+	}
+
 	public boolean
 	isSimpleTorrent()
 	{
@@ -123,6 +145,12 @@ LWSTorrent
 		return( getDelegate().getCreationDate());
 	}
 	
+	public boolean 
+	isDecentralised() 
+	{
+		return( getDelegate().isDecentralised());
+	}
+	
 	public void
 	setCreationDate(
 		long		date )
@@ -387,6 +415,20 @@ LWSTorrent
 		getDelegate().serialiseToBEncodedFile( file );
 	}
 	
+	public void
+	addListener(
+		TOTorrentListener		l )
+	{
+		getDelegate().addListener( l );
+	}
+
+	public void
+	removeListener(
+		TOTorrentListener		l )
+	{
+		getDelegate().removeListener( l );
+	}
+	
 	public Map
 	serialiseToMap()
 	
diff --git a/com/aelitis/azureus/core/lws/LightWeightSeed.java b/com/aelitis/azureus/core/lws/LightWeightSeed.java
index 748e9d7..21d033b 100644
--- a/com/aelitis/azureus/core/lws/LightWeightSeed.java
+++ b/com/aelitis/azureus/core/lws/LightWeightSeed.java
@@ -36,6 +36,7 @@ import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPeerManagerFactory;
 import org.gudy.azureus2.core3.peer.PEPeerManagerListener;
+import org.gudy.azureus2.core3.peer.PEPiece;
 import org.gudy.azureus2.core3.peer.util.PeerUtils;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
@@ -412,7 +413,22 @@ LightWeightSeed
 							PEPeer finder) 
 						{
 						}
-						 
+						  
+						public void 
+						pieceAdded( 
+							PEPeerManager 	manager, 
+							PEPiece 		peice, 
+							PEPeer 			for_peer )
+						{
+						}
+						  
+						public void 
+						pieceRemoved( 
+							PEPeerManager 	manager, 
+							PEPiece 		peice )
+						{
+						}
+
 						public void 
 						peerSentBadData(
 							PEPeerManager 	manager,
@@ -585,6 +601,32 @@ LightWeightSeed
 					}
 					
 					public int 
+					getPendingConnectionCount() 
+					{
+						PEPeerManager	pm = peer_manager;
+
+						if ( pm == null ){
+							
+							return( 0 );
+						}
+						
+						return( pm.getPendingPeerCount());
+					}
+					
+					public int
+					getConnectedConnectionCount()
+					{
+						PEPeerManager	pm = peer_manager;
+
+						if ( pm == null ){
+							
+							return( 0 );
+						}
+						
+						return( pm.getNbPeers() + pm.getNbSeeds());
+					}
+					
+					public int 
 					getUploadSpeedKBSec(
 						boolean estimate) 
 					{
diff --git a/com/aelitis/azureus/core/messenger/PlatformAuthorizedSender.java b/com/aelitis/azureus/core/messenger/PlatformAuthorizedSender.java
deleted file mode 100644
index ab0f9fd..0000000
--- a/com/aelitis/azureus/core/messenger/PlatformAuthorizedSender.java
+++ /dev/null
@@ -1,53 +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.core.messenger;
-
-import java.net.URL;
-
-import org.gudy.azureus2.core3.util.AESemaphore;
-
-/**
- * @author TuxPaper
- * @created Apr 23, 2008
- *
- */
-public interface PlatformAuthorizedSender
-{
-
-	/**
-	 * @param url
-	 * @param data
-	 * @param sem_waitDL 
-	 * @param loginAndRetry 
-	 * @return
-	 *
-	 * @since 3.0.5.3
-	 */
-	void startDownload(URL url, String data, AESemaphore sem_waitDL,
-			boolean loginAndRetry);
-
-	String getResults();
-
-	/**
-	 * 
-	 *
-	 * @since 4.0.0.5
-	 */
-	void clearResults();
-}
diff --git a/com/aelitis/azureus/core/messenger/PlatformMessage.java b/com/aelitis/azureus/core/messenger/PlatformMessage.java
index b747a03..243ae6e 100644
--- a/com/aelitis/azureus/core/messenger/PlatformMessage.java
+++ b/com/aelitis/azureus/core/messenger/PlatformMessage.java
@@ -25,7 +25,6 @@ import java.util.*;
 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.util.JSONUtils;
 
 /**
@@ -41,7 +40,7 @@ public class PlatformMessage
 
 	private final String operationID;
 
-	private final Map parameters;
+	private final Map<?, ?> parameters;
 
 	private final long fireBeforeDate;
 
@@ -49,14 +48,8 @@ public class PlatformMessage
 
 	private long lSequenceNo = -1;
 
-	private boolean requiresAuthorization = false;
-
-	private boolean loginAndRetry = false;
-
 	private boolean sendAZID = true;
 
-	private long contentNetworkID;
-
 	/**
 	 * @param messageID
 	 * @param listenerID
@@ -65,13 +58,12 @@ public class PlatformMessage
 	 * @param maxDelay
 	 */
 	public PlatformMessage(String messageID, String listenerID,
-			String operationID, Map parameters, long maxDelayMS) {
+			String operationID, Map<?, ?> parameters, long maxDelayMS) {
 
 		this.messageID = messageID;
 		this.listenerID = listenerID;
 		this.operationID = operationID;
 		this.parameters = JSONUtils.encodeToJSONObject(parameters);
-		this.contentNetworkID = ContentNetwork.CONTENT_NETWORK_VUZE;
 
 		messageCreatedOn = SystemTime.getCurrentTime();
 		fireBeforeDate = messageCreatedOn + maxDelayMS;
@@ -85,19 +77,18 @@ public class PlatformMessage
 		this.operationID = operationID;
 
 		this.parameters = JSONUtils.encodeToJSONObject(parseParams(parameters));
-		this.contentNetworkID = ContentNetwork.CONTENT_NETWORK_VUZE;
 
 		messageCreatedOn = SystemTime.getCurrentTime();
 		fireBeforeDate = messageCreatedOn + maxDelayMS;
 	}
 
-	public static Map parseParams(Object[] parameters) {
-		Map result = new HashMap();
+	public static Map<String, Object> parseParams(Object[] parameters) {
+		Map<String, Object> result = new HashMap<String, Object>();
 		for (int i = 0; i < parameters.length - 1; i += 2) {
 			try {
 				if (parameters[i] instanceof String) {
 					if (parameters[i + 1] instanceof String[]) {
-						List list = Arrays.asList((String[]) parameters[i + 1]);
+						List<String> list = Arrays.asList((String[]) parameters[i + 1]);
 						result.put((String) parameters[i], list);
 					} else if (parameters[i + 1] instanceof Object[]) {
 						result.put((String) parameters[i],
@@ -124,7 +115,7 @@ public class PlatformMessage
 		return messageCreatedOn;
 	}
 
-	public Map getParameters() {
+	public Map<?, ?> getParameters() {
 		return parameters;
 	}
 
@@ -151,9 +142,6 @@ public class PlatformMessage
 	public String toString() {
 		String paramString = parameters.toString();
 		return "PlaformMessage {"
-				+ "cn"
-				+ contentNetworkID
-				+ ", "
 				+ lSequenceNo
 				+ ", "
 				+ messageID
@@ -167,7 +155,7 @@ public class PlatformMessage
 	}
 
 	public String toShortString() {
-		return (requiresAuthorization ? "AUTH: " : "") + getMessageID() + "."
+		return getMessageID() + "."
 				+ getListenerID() + "." + getOperationID();
 	}
 
@@ -182,16 +170,5 @@ public class PlatformMessage
 
 	public void setSendAZID(boolean send) {
 		sendAZID = send;
-		if (send && requiresAuthorization) {
-			System.err.println("requiresAuthorization overrides sendAZID disabling");
-		}
-	}
-
-	public long getContentNetworkID() {
-		return contentNetworkID;
-	}
-
-	public void setContentNetworkID(long contentNetworkID) {
-		this.contentNetworkID = contentNetworkID;
 	}
 }
diff --git a/com/aelitis/azureus/core/messenger/PlatformMessenger.java b/com/aelitis/azureus/core/messenger/PlatformMessenger.java
index 7af8387..28664b1 100644
--- a/com/aelitis/azureus/core/messenger/PlatformMessenger.java
+++ b/com/aelitis/azureus/core/messenger/PlatformMessenger.java
@@ -26,7 +26,6 @@ import java.net.URL;
 import java.net.URLEncoder;
 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;
@@ -37,6 +36,7 @@ import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFact
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
 import com.aelitis.azureus.util.*;
 
 /**
@@ -88,6 +88,8 @@ public class PlatformMessenger
 	private static boolean allowMulti = false;
 
 	private static AsyncDispatcher	dispatcher = new AsyncDispatcher(5000);
+
+	private static Map<String, Object> mapExtra = new HashMap<String, Object>();
 	
 	public static synchronized void init() {
 		if (initialized) {
@@ -114,11 +116,6 @@ public class PlatformMessenger
 	public static void queueMessage(PlatformMessage message,
 			PlatformMessengerListener listener, boolean addToBottom) {
 		
-		if ( COConfigurationManager.getStringParameter( "ui", "az3" ).equals( "az2" )){
-			
-			Debug.out( "**** PlatformMessenger shouldn't be used with az2 UI ****" );
-		}
-		
 		if (!initialized) {
 			init();
 		}
@@ -131,17 +128,11 @@ public class PlatformMessenger
 			long fireBefore;
 			String queueID = null;
 			if (message != null) {
-				long networkID = message.getContentNetworkID();
-				if (networkID <= 0) {
-					debug("Content Network invalid for " + message);
-					return;
-				}
 				if (!message.sendAZID()) {
 					queueID = QUEUE_NOAZID;
 				} else {
 					queueID = QUEUE_NORMAL;
 				}
-				queueID += networkID;
 				
 				Map<PlatformMessage, PlatformMessengerListener> mapQueue = (Map) mapQueues.get(queueID);
 				if (mapQueue == null) {
@@ -268,6 +259,8 @@ public class PlatformMessenger
 		Map<String, Object> mapPayload = new HashMap<String, Object>();
 		mapPayload.put("azid", ConstantsVuze.AZID);
 		mapPayload.put("azv", Constants.AZUREUS_VERSION);
+		mapPayload.put("mode", FeatureManagerUI.getMode());
+		mapPayload.putAll(mapExtra);
 		List<Map> listCommands = new ArrayList<Map>();
 		mapPayload.put("commands", listCommands);
 
@@ -284,7 +277,6 @@ public class PlatformMessenger
 
 				if (first) {
 					sendAZID = message.sendAZID();
-					contentNetworkID = message.getContentNetworkID();
 					first = false;
 				}
 
@@ -365,7 +357,7 @@ public class PlatformMessenger
 		}
 
 		String sURL_RPC = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_RPC)
-					+ "?" + urlStem.toString();
+					+ "&" + urlStem.toString();
 
 		// Build full url and data to send
 		String sURL;
@@ -566,6 +558,12 @@ public class PlatformMessenger
 	public static boolean getAllowMulti() {
 		return allowMulti;
 	}
+	
+	public static void addExtraParam(String key, Object value) {
+		synchronized (mapExtra) {
+			mapExtra.put(key, value);
+		}
+	}
 
 	private static class fakeContext
 		extends ClientMessageContextImpl
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
index 6bcad02..28bd414 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformConfigMessenger.java
@@ -21,23 +21,22 @@
 package com.aelitis.azureus.core.messenger.config;
 
 import java.util.*;
+import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.platform.PlatformManager;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
 
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 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.core.util.CopyOnWriteList;
 import com.aelitis.azureus.util.*;
 
-import org.gudy.azureus2.plugins.platform.PlatformManagerException;
-
 /**
  * @author TuxPaper
  * @created Sep 26, 2006
@@ -46,6 +45,8 @@ import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 public class PlatformConfigMessenger
 {
 	public static final String LISTENER_ID = "config";
+	
+	private static final String OP_LOG_PLUGIN = "log-plugin";
 
 	private static boolean allowSendDeviceList = false;
 
@@ -60,39 +61,22 @@ public class PlatformConfigMessenger
 	private static boolean platformLoginComplete = false;
 
 	protected static List platformLoginCompleteListeners = Collections.EMPTY_LIST;
+
+	private static CopyOnWriteList<String> externalLinks = new CopyOnWriteList<String>();
 	
-	public static void login(long contentNetworkID, long maxDelayMS) {
+	public static void login(long maxDelayMS) {
 		PlatformManager pm = PlatformManagerFactory.getPlatformManager();
-		String azComputerID = "";
-		try {
-			azComputerID = pm.getAzComputerID();
-		} catch (PlatformManagerException e) {
-		}
 		
-		String sourceRef = null;
-		if (contentNetworkID != ConstantsVuze.DEFAULT_CONTENT_NETWORK_ID) {
-  		ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetwork(contentNetworkID);
-  		sourceRef = (String) cn.getPersistentProperty(ContentNetwork.PP_SOURCE_REF);
-		}
-		if (sourceRef == null) {
-			sourceRef = "unknown";
-		}
-
 		Object[] params = new Object[] {
 			"version",
 			org.gudy.azureus2.core3.util.Constants.AZUREUS_VERSION,
 			"locale",
-			Locale.getDefault().toString(),
-			"azCID",
-			azComputerID,
+			MessageText.getCurrentLocale().toString(),
 			"vid",
 			COConfigurationManager.getStringParameter("ID"),
-			"source-ref",
-			sourceRef
 		};
 		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
 				"login", params, maxDelayMS);
-		message.setContentNetworkID(contentNetworkID);
 
 		PlatformMessengerListener listener = new PlatformMessengerListener() {
 
@@ -147,8 +131,11 @@ public class PlatformConfigMessenger
 					Debug.out(e);
 				}
 				
-				if (message.getContentNetworkID() != ConstantsVuze.getDefaultContentNetwork().getID()) {
-					return;
+				try {
+					List list = MapUtils.getMapList(reply, "external-links", Collections.EMPTY_LIST);
+					externalLinks.addAll(list);
+				} catch (Exception e) {
+					Debug.out(e);
 				}
 				
 				try {
@@ -188,6 +175,26 @@ public class PlatformConfigMessenger
 		PlatformMessenger.pushMessageNow(message, listener);
 	}
 
+	public static void logPlugin(String event, String pluginID) {
+		boolean send_info = COConfigurationManager.getBooleanParameter( "Send Version Info" );
+		if (!send_info || true) {
+			return;
+		}
+		try {
+			PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
+					OP_LOG_PLUGIN, new Object[] {
+						"event",
+						event,
+						"plugin-id",
+						pluginID,
+					}, 5000);
+
+			PlatformMessenger.queueMessage(message, null);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+	}
+	
 	public static void sendUsageStats(Map stats, long timestamp, String version,
 			PlatformMessengerListener l) {
 		if (!sendStats) {
@@ -211,6 +218,22 @@ public class PlatformConfigMessenger
 			Debug.out(e);
 		}
 	}
+	
+	public static void sendVersionServerMap(Map mapVerServer) {
+		boolean send_info = COConfigurationManager.getBooleanParameter("Send Version Info");
+		if (!send_info || true) {    //TODO if we ever re-enable this rpc, need to fix it being called 2x back-to-back bug....
+			return;
+		}
+
+		try {
+			PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
+					"send-version-info", mapVerServer, 5000);
+
+			PlatformMessenger.queueMessage(message, null);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+	}
 
 	public static interface GetBrowseSectionsReplyListener
 	{
@@ -271,4 +294,23 @@ public class PlatformConfigMessenger
 	public static boolean allowSendDeviceList() {
 		return allowSendDeviceList;
 	}
+	
+	public static boolean areLinksExternal(String url) {
+		for (String regex : externalLinks) {
+			try {
+  			if (Pattern.compile(regex).matcher(url).find()) {
+  				return true;
+  			}
+			} catch (Exception e) {
+			}
+		}
+		return false;
+	}
+
+	public static void addLinkExternal(String link) {
+		if (externalLinks.contains(link)) {
+			return;
+		}
+		externalLinks.add(link);
+	}
 }
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java
deleted file mode 100644
index e0fe3b7..0000000
--- a/com/aelitis/azureus/core/messenger/config/PlatformContentNetworkMessenger.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Created on May 6, 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.core.messenger.config;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.Constants;
-import org.json.simple.JSONObject;
-
-import com.aelitis.azureus.core.messenger.*;
-
-
-
-public class 
-PlatformContentNetworkMessenger 
-{
-	private static final String LISTENER_ID = "cnetworks";
-
-	private static final PlatformMessengerConfig	dispatcher = 
-			new PlatformMessengerConfig( LISTENER_ID, true );
-
-	private static final String OP_LIST_CNETORKS	= "list-networks";
-
-
-	
-	public static List<contentNetworkDetails> 
-	listNetworks()
-	
-		throws PlatformMessengerException
-	{
-		if (true) {
-			return new ArrayList<contentNetworkDetails>(0);
-		}
-
-		JSONObject parameters = new JSONObject();
-		
-		parameters.put( "azver", Constants.AZUREUS_VERSION );
-		
-		Map reply = dispatcher.syncInvoke( OP_LIST_CNETORKS, parameters ); 
-
-		List<Map>	networks = (List<Map>)reply.get( "networks" );
-		
-		if ( networks == null ){
-			
-			throw( new PlatformMessengerException( "No networks returned" ));
-		}
-		
-		List<contentNetworkDetails> result = new ArrayList<contentNetworkDetails>();
-		
-		for ( Map map: networks ){
-			
-			result.add( new contentNetworkDetails( map ));
-		}
-		
-		return( result );
-	}                       	
-	
-	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);
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_LIST_CNETORKS, parameters, maxDelayMS);
-
-		PlatformMessengerListener listener = new PlatformMessengerListener() {
-			// @see com.aelitis.azureus.core.messenger.PlatformMessengerListener#replyReceived(com.aelitis.azureus.core.messenger.PlatformMessage, java.lang.String, java.util.Map)
-			public void replyReceived(PlatformMessage message, String replyType,
-					Map reply) {
-				List<Map> networks = (List<Map>) reply.get("networks");
-
-				List<contentNetworkDetails> result;
-
-				if (networks == null) {
-					result = null;
-				} else {
-  
-  				result = new ArrayList<contentNetworkDetails>();
-  
-  				for (Map map : networks) {
-  
-  					result.add(new contentNetworkDetails(map));
-  				}
-				}
-
-				if (l != null) {
-					l.networkListReturned(result);
-				}
-			}
-
-			// @see com.aelitis.azureus.core.messenger.PlatformMessengerListener#messageSent(com.aelitis.azureus.core.messenger.PlatformMessage)
-			public void messageSent(PlatformMessage message) {
-			}
-		};
-
-		PlatformMessenger.queueMessage(message, listener);
-	}                       	
-	
-	public static class
-	contentNetworkDetails
-	{
-		private Map		details;
-		
-		protected
-		contentNetworkDetails(
-			Map		_details )
-		{
-			details	= _details;
-		}
-		
-		public long
-		getID()
-		{
-			return(((Long)details.get( "id" )).longValue());
-		}
-		
-		public long
-		getVersion()
-		{
-			return(((Long)details.get( "version" )).longValue());
-		}
-		
-		public String
-		getName()
-		{
-			return((String)details.get( "name" ));
-		}
-		
-		public String
-		getIconURL()
-		{
-			return((String)details.get( "iconUrl" ));
-		}
-		
-		public String
-		getMainURL()
-		{
-			return((String)details.get( "baseUrl" ));
-		}
-		
-		public String
-		getString()
-		{
-			return( "id=" + getID() + ";version=" + getVersion() + ";name=" + getName());
-		}
-	}
-	
-	public static interface
-	listNetworksListener
-	{
-		public void networkListReturned(List<contentNetworkDetails> list);		
-	}
-}
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
index b3c2275..2a64a80 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformDevicesMessenger.java
@@ -21,20 +21,14 @@ package com.aelitis.azureus.core.messenger.config;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.FileUtil;
-import org.gudy.azureus2.core3.util.HashWrapper;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.devices.*;
 import com.aelitis.azureus.core.messenger.PlatformMessage;
 import com.aelitis.azureus.core.messenger.PlatformMessenger;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
-
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.plugins.torrent.Torrent;
 
 /**
  * @author TuxPaper
@@ -51,21 +45,9 @@ public class PlatformDevicesMessenger
 
 	private static final String OP_QOS_FOUND_DEVICE = "qos-found-device";
 
-	private static final String OP_QOS_TRANSCODE = "qos-transcode";
-
-	private static final String OP_QOS_PLAYBACK = "qos-playback";
-
-	private static final String OP_GET_PROFILES = "get-profiles";
-
 	private static final String OP_REPORT_DEVICES = "report-devices";
-
-	private static final String OP_QOS_TRANSCODE_REQUEST = "qos-transcode-request";
-	
-	private static String plugin_xcode_version = null;
 	
-	private static String plugin_itunes_version = null;
-
-	public static void qosTurnOn(boolean withITunes) {
+	public static void qosTurnOn(boolean withITunes, boolean bugFix) {
 		if (!COConfigurationManager.getBooleanParameter(CFG_SEND_QOS, false)) {
 			return;
 		}
@@ -75,13 +57,30 @@ public class PlatformDevicesMessenger
 					"itunes",
 					Boolean.valueOf(withITunes),
 					"os-name",
-					Constants.OSName
+					Constants.OSName + (bugFix ? ":BF" : "")
 				}, 5000);
 		message.setSendAZID(false);
 		PlatformMessenger.queueMessage(message, null);
 	}
 
-	public static void qosFoundDevice(Device device) {
+	public static void qosFoundDevice(final Device device) {
+		if (device == null
+				|| !COConfigurationManager.getBooleanParameter(CFG_SEND_QOS, false)) {
+			return;
+		}
+
+		if ("ms_wmp.generic".equals(device.getClassification())) {
+			return;
+		}
+		
+		SimpleTimer.addEvent("qosFoundDevice", SystemTime.getOffsetTime(1000), new TimerEventPerformer() {
+			public void perform(TimerEvent event) {
+				_qosFoundDevice(device);
+			}
+		});
+	}
+
+	private static void _qosFoundDevice(Device device) {
 		if (device == null
 				|| !COConfigurationManager.getBooleanParameter(CFG_SEND_QOS, false)) {
 			return;
@@ -91,7 +90,7 @@ public class PlatformDevicesMessenger
 
 		addPluginVersionsToMap(map);
 
-		map.put("device-name", device.getName());
+		map.put("device-name", getDeviceName(device));
 		map.put("device-type", new Integer(device.getType()));
 		if (device instanceof DeviceMediaRenderer) {
 			DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
@@ -121,152 +120,59 @@ public class PlatformDevicesMessenger
 		map.put("os-name", Constants.OSName);
 	}
 
-	public static void qosTranscodeRequest(TranscodeTarget transcodeTarget, String sourceRef) {
-		if (!COConfigurationManager.getBooleanParameter(CFG_SEND_QOS, false)
-				|| transcodeTarget == null) {
-			return;
-		}
-
-		HashMap<String, Object> map = new HashMap<String, Object>();
-
-		addPluginVersionsToMap(map);
-
-		Device device = transcodeTarget.getDevice();
-		if (device != null) { // should never be null..
-			map.put("device-name", device.getName());
-			map.put("device-type", new Integer(device.getType()));
-		}
-		if (transcodeTarget instanceof DeviceMediaRenderer) {
-			DeviceMediaRenderer renderer = (DeviceMediaRenderer) transcodeTarget;
-			map.put("renderer-species",
-					Integer.valueOf(renderer.getRendererSpecies()));
-		}
-		map.put("source-ref", sourceRef);
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_QOS_TRANSCODE_REQUEST, map, 5000);
-		message.setSendAZID(false);
-		PlatformMessenger.queueMessage(message, null);
+	private static String getDeviceName(Device device) {
+		return device.getClassification();
+		/*
+		String name = device.getName();
+		String classification = device.getClassification();
+		StringBuffer deviceName = new StringBuffer();
+		if (device.isGenericUSB()) {
+			deviceName.append("{g}");
+		}
+		if (device.isHidden()) {
+			deviceName.append("{h}");
+		}
+		deviceName.append(name);
+		if (!name.equals(classification)) {
+			deviceName.append('/');
+			deviceName.append(classification);
+		}
+		return deviceName.toString();
+		*/
 	}
 
-	public static void qosTranscode(TranscodeJob job, int stateOveride) {
-		if (!COConfigurationManager.getBooleanParameter(CFG_SEND_QOS, false)
-				|| job == null) {
-			return;
-		}
-
-		TranscodeFile transcodeFile = job.getTranscodeFile();
-		DiskManagerFileInfo sourceFileInfo = null;
-		try {
-			sourceFileInfo = transcodeFile.getSourceFile();
-		} catch (Throwable t) {
-		}
-		DiskManagerFileInfo targetFileInfo = null;
-		try {
-			targetFileInfo = transcodeFile.getTargetFile();
-		} catch (Throwable t) {
-		}
-		TranscodeProfile profile = job.getProfile();
-		TranscodeTarget target = job.getTarget();
-		Device device = target.getDevice();
-		
-		HashMap<String, Object> map = new HashMap<String, Object>();
-
-		addPluginVersionsToMap(map);
-
-		map.put("job-state", Integer.valueOf(stateOveride));
-
-		if ((stateOveride & 0xff) == TranscodeJob.ST_FAILED) {
-			String error = job.getError();
-			if (error != null) {
-				if (error.endsWith("\r\n")) {
-					error.substring(0, error.length() - 2);
-				} else if (error.endsWith("\r") || error.endsWith("\n")) {
-					error.substring(0, error.length() - 1);
-				}
-			}
-			map.put("job-error", error);
-		}
-		
-		try {
-			Torrent torrent = job.getFile().getDownload().getTorrent();
-			if (PlatformTorrentUtils.isContent(torrent, true)) {
-				map.put("asset-hash", new HashWrapper(torrent.getHash()).toBase32String());
-			}
-		} catch (Throwable t) {
-		}
-
-		map.put("transcode-mode", new Integer(job.getTranscodeRequirement()));
-		map.put("transcode-required", new Boolean(transcodeFile.getTranscodeRequired()));
-
-		// These help us determine if the transcode is taking too long
-		map.put("transcode-video-width", new Long(transcodeFile.getVideoWidth()));
-		map.put("transcode-video-height", new Long(transcodeFile.getVideoHeight()));
-		map.put("transcode-video-duration-ms", new Long(transcodeFile.getDurationMillis()));
-		map.put("process-time-ms", new Long(job.getProcessTime()));
-
-		// Gotta know which device/profile/renderer we are transcoding to so we
-		// know what's should be worked on more
-		map.put("device-name", device.getName());
-		map.put("device-type", new Integer(device.getType()));
-		if (profile != null) {
-			map.put("profile-name", profile.getName());
-		}
-		
-		if (target instanceof DeviceMediaRenderer) {
-			DeviceMediaRenderer renderer = (DeviceMediaRenderer) target;
-			map.put("renderer-species", Integer.valueOf(renderer.getRendererSpecies()));
-		}
-
-		// Don't worry, we don't send the filename, just the extension.  This
-		// helps us figure out which file types are failing/succeeding the most
-		if (sourceFileInfo != null) {
-			map.put("source-file-ext", FileUtil.getExtension(sourceFileInfo.getFile().getName()));
-			map.put("source-file-size", new Long(sourceFileInfo.getLength()));
-		}
-		if (targetFileInfo != null) {
-			map.put("target-file-ext", FileUtil.getExtension(targetFileInfo.getFile().getName()));
-			map.put("target-file-size", new Long(targetFileInfo.getLength()));
-		}
-		
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_QOS_TRANSCODE, map, 5000);
-		message.setSendAZID(false);
-		PlatformMessenger.queueMessage(message, null);
-	}
-	
 	public static void setupDeviceSender() {
-		final DeviceManager deviceManager = DeviceManagerFactory.getSingleton();
-		Device[] devices = deviceManager.getDevices();
-		if (devices == null || devices.length == 0) {
-  		deviceManager.addListener(new DeviceManagerListener() {
-  		
-  			public void deviceRemoved(Device device) {
-  			}
-  		
-  			public void deviceChanged(Device device) {
-  			}
-  		
-  			public void deviceAttentionRequest(Device device) {
-  			}
-  			
-  			public void deviceAdded(Device device) {
-  			}
-  
-  			public void deviceManagerLoaded() {
-  				deviceManager.removeListener(this);
-  				Device[] devices = deviceManager.getDevices();
-  				if (devices != null && devices.length > 0) {
-  					sendDeviceList(devices);
-  				}
-  			}
-  		});
-		} else {
-			sendDeviceList(devices);
+		if ( !COConfigurationManager.getStringParameter("ui").equals("az2")){
+
+			final DeviceManager deviceManager = DeviceManagerFactory.getSingleton();
+			Device[] devices = deviceManager.getDevices();
+			if (devices == null || devices.length == 0) {
+	  		deviceManager.addListener(new DeviceManagerListener() {
+	  		
+	  			public void deviceRemoved(Device device) {
+	  			}
+	  		
+	  			public void deviceChanged(Device device) {
+	  			}
+	  		
+	  			public void deviceAttentionRequest(Device device) {
+	  			}
+	  			
+	  			public void deviceAdded(Device device) {
+	  			}
+	  
+	  			public void deviceManagerLoaded() {
+	  				deviceManager.removeListener(this);
+	  				Device[] devices = deviceManager.getDevices();
+	  				if (devices != null && devices.length > 0) {
+	  					sendDeviceList(devices);
+	  				}
+	  			}
+	  		});
+			} else {
+				sendDeviceList(devices);
+			}
 		}
-		
-
 	}
 
 	private static void sendDeviceList(Device[] devices) {
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformMetaSearchMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformMetaSearchMessenger.java
index 39f6ec9..7f81712 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformMetaSearchMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformMetaSearchMessenger.java
@@ -45,11 +45,19 @@ PlatformMetaSearchMessenger
 
 	public static templateDetails 
 	getTemplate(
-		long	template_id )
+		String		extension_key,
+		long		template_id )
 	
 		throws PlatformMessengerException
 	{
-		Map reply = dispatcher.syncInvoke(	OP_GET_TEMPLATE, getParameter( template_id ) ); 
+		Map parameters = getParameter( template_id );
+		
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
+		Map reply = dispatcher.syncInvoke(	OP_GET_TEMPLATE, parameters ); 
 
 		templateInfo info = getTemplateInfo( reply );
 		
@@ -88,6 +96,7 @@ PlatformMetaSearchMessenger
 	
 	public static templateInfo[] 
    	getTemplateDetails(
+   		String		extension_key,
    		long[]		ids )
    	
    		throws PlatformMessengerException
@@ -106,6 +115,11 @@ PlatformMetaSearchMessenger
 		
    		Map parameters = new HashMap();
    		
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
    		parameters.put( "templateIds", str );
 
    		Map reply = dispatcher.syncInvoke(	OP_GET_TEMPLATES, parameters ); 
@@ -114,11 +128,20 @@ PlatformMetaSearchMessenger
    	}
 	
 	public static templateInfo[] 
-	listTopPopularTemplates()
+	listTopPopularTemplates(
+		String		extension_key,
+		String		fud )
 	
 		throws PlatformMessengerException
-	{
+	{		
 		Map parameters = new HashMap();
+	
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
+		parameters.put( "fud", fud );
 		
 		Map reply = dispatcher.syncInvoke(	OP_LIST_POPULAR_TEMPLATES, parameters ); 
 
@@ -126,12 +149,21 @@ PlatformMetaSearchMessenger
 	}
 	
 	public static templateInfo[] 
-   	listAllPopularTemplates()
+   	listAllPopularTemplates(
+   		String		extension_key,
+   		String		fud )
    	
    		throws PlatformMessengerException
    	{
    		Map parameters = new HashMap();
    		
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
+		parameters.put( "fud", fud );
+		
    		parameters.put( "page-num", new Long( 1 ));
    		parameters.put( "items-per-page", new Long( MAX_TEMPLATE_LIST ));
 
@@ -141,12 +173,21 @@ PlatformMetaSearchMessenger
    	}
 	
 	public static templateInfo[] 
-	listFeaturedTemplates()
+	listFeaturedTemplates(
+		String		extension_key,
+		String		fud )
 	
 		throws PlatformMessengerException
 	{
 		Map parameters = new HashMap();
 		
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
+		parameters.put( "fud", fud );
+		
 		parameters.put( "page-num", new Long( 1 ));
 		parameters.put( "items-per-page", new Long( MAX_TEMPLATE_LIST ));
 
@@ -240,6 +281,7 @@ PlatformMetaSearchMessenger
 	                         	
 	public static void 
 	setTemplatetSelected(
+		String		extension_key,
 		long		template_id,
 		String		user_id,
 		boolean		is_selected )
@@ -248,6 +290,11 @@ PlatformMetaSearchMessenger
 	{
 		Map	parameters = getParameter( template_id );
 		
+		if ( extension_key != null ){
+			
+			parameters.put( "extension_key", extension_key );
+		}
+		
 		parameters.put( "userId", user_id );
 		parameters.put( "selected", new Boolean( is_selected ));
 		
@@ -264,7 +311,7 @@ PlatformMetaSearchMessenger
 
 		return( parameters );
 	}
-	
+
 	public static class
 	templateInfo
 	{
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
index b6818b0..645e979 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformSubscriptionsMessenger.java
@@ -29,6 +29,7 @@ import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.json.simple.JSONArray;
 
 
+import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.messenger.PlatformMessengerException;
 import com.aelitis.azureus.core.security.CryptoECCUtils;
 
@@ -314,4 +315,23 @@ PlatformSubscriptionsMessenger
 			}
 		}
 	}
+	
+	public static void
+	main(
+		String[]	args )
+	{
+		try{
+			AzureusCoreFactory.create();
+			
+			String short_id = "";
+			
+			long res = getPopularityBySID( Base32.decode( short_id ));
+			
+			System.out.println( res );
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
index 1893f9f..db50ff9 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformTorrentMessenger.java
@@ -20,15 +20,9 @@
 
 package com.aelitis.azureus.core.messenger.config;
 
-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.torrent.PlatformTorrentUtils;
 
 /**
  * @author TuxPaper
@@ -43,50 +37,8 @@ public class PlatformTorrentMessenger
 
 	public static void streamComplete(TOTorrent torrent, long waitTime,
 			int maxSeekAheadSecs, int numRebuffers, int numHardRebuffers) {
-		String hash = null;
-		try {
-			hash = torrent.getHashWrapper().toBase32String();
-		} catch (TOTorrentException e) {
-		}
-
-		if (hash == null) {
-			return;
-		}
-
-		Map mapParameters = new HashMap();
-
-		mapParameters.put("torrent-hash", hash);
-		mapParameters.put("wait-time", new Long(waitTime));
-		mapParameters.put("max-seek", new Long(maxSeekAheadSecs));
-		mapParameters.put("num-rebuffers", new Long(numRebuffers));
-		mapParameters.put("num-hard-rebuffers", new Long(numHardRebuffers));
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_STREAMCOMPLETE, mapParameters, 3000);
-		message.setContentNetworkID(PlatformTorrentUtils.getContentNetworkID(torrent));
-
-		PlatformMessenger.queueMessage(message, null);
 	}
 
 	public static void streamComplete(TOTorrent torrent, Map info) {
-		String hash = null;
-		try {
-			hash = torrent.getHashWrapper().toBase32String();
-		} catch (TOTorrentException e) {
-		}
-
-		if (hash == null) {
-			return;
-		}
-
-		Map mapParameters = new HashMap(info);
-
-		mapParameters.put("torrent-hash", hash);
-
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID,
-				OP_STREAMCOMPLETE, mapParameters, 3000);
-		message.setContentNetworkID(PlatformTorrentUtils.getContentNetworkID(torrent));
-
-		PlatformMessenger.queueMessage(message, null);
 	}
 }
diff --git a/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java b/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
index d05a44b..7725b5c 100644
--- a/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
+++ b/com/aelitis/azureus/core/messenger/config/PlatformVuzeActivitiesMessenger.java
@@ -42,14 +42,15 @@ public class PlatformVuzeActivitiesMessenger
 
 	public static final long DEFAULT_RETRY_MS = 1000L * 60 * 60 * 24;
 
-	public static void getEntries(final long contentNetworkID, final long agoMS,
-			long maxDelayMS, final GetEntriesReplyListener replyListener) {
-		PlatformMessage message = new PlatformMessage("AZMSG", LISTENER_ID, OP_GET,
-				new Object[] {
+	public static void getEntries(final long agoMS,
+			long maxDelayMS, String reason, final GetEntriesReplyListener replyListener) {
+		PlatformMessage message = new PlatformMessage("AZMSG",
+				reason.equals("shown") ? "vznews" : LISTENER_ID, OP_GET, new Object[] {
 					"ago-ms",
 					new Long(agoMS),
+					"reason",
+					reason,
 				}, maxDelayMS);
-		message.setContentNetworkID(contentNetworkID);
 
 		PlatformMessengerListener listener = null;
 		if (replyListener != null) {
@@ -72,7 +73,7 @@ public class PlatformVuzeActivitiesMessenger
 							}
 							
 							entries[i] = VuzeActivitiesManager.createEntryFromMap(
-									contentNetworkID, platformEntry, false);
+									platformEntry, false);
 							if (entries[i] != null) {
 								i++;
 							}
diff --git a/com/aelitis/azureus/core/metasearch/Engine.java b/com/aelitis/azureus/core/metasearch/Engine.java
index ef80ed9..265e626 100644
--- a/com/aelitis/azureus/core/metasearch/Engine.java
+++ b/com/aelitis/azureus/core/metasearch/Engine.java
@@ -23,11 +23,13 @@ package com.aelitis.azureus.core.metasearch;
 import java.io.*;
 import java.util.Map;
 
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+
 
 public interface 
 Engine 
 {	
-	public static final int	AZ_VERSION		= 1;
+	public static final int	AZ_VERSION		= 2;
 	
 	public static final Object	VUZE_FILE_COMPONENT_ENGINE_KEY = new Object();
 	
@@ -55,19 +57,20 @@ Engine
 	public static final int FIELD_DOWNLOADBTNLINK 		= 105;
 	
 	public static final int FIELD_HASH			= 200;
+	public static final int FIELD_RANK    = 201;
 	
 	public static final int[] FIELD_IDS = {
 		FIELD_NAME, FIELD_DATE, FIELD_SIZE, FIELD_PEERS, FIELD_SEEDS, FIELD_CATEGORY,
 		FIELD_COMMENTS, FIELD_CONTENT_TYPE, FIELD_DISCARD, 
 		FIELD_TORRENTLINK, FIELD_CDPLINK, FIELD_PLAYLINK,FIELD_DOWNLOADBTNLINK, FIELD_VOTES, FIELD_SUPERSEEDS,
-		FIELD_PRIVATE, FIELD_DRMKEY, FIELD_VOTES_DOWN, FIELD_HASH
+		FIELD_PRIVATE, FIELD_DRMKEY, FIELD_VOTES_DOWN, FIELD_HASH, FIELD_RANK
 	};
 		
 	public static final String[] FIELD_NAMES = {
 		"TITLE", "DATE", "SIZE", "PEERS", "SEEDS", "CAT",
 		"COMMENTS", "CONTENT_TYPE", "DISCARD",
 		"TORRENT", "CDP", "PLAY","DLBTN", "VOTES", "XSEEDS",
-		"PRIVATE", "DRMKEY", "VOTESDOWN", "HASH"
+		"PRIVATE", "DRMKEY", "VOTESDOWN", "HASH", "RANK"
 	};
 	
 	public static final int ENGINE_TYPE_REGEX		= 1;
@@ -209,6 +212,9 @@ Engine
 	public boolean
 	isShareable();
 	
+	public boolean
+	isAuthenticated();
+	
 		/**
 		 * @return one of AUTO_DL constants above
 		 */
@@ -219,11 +225,21 @@ Engine
 	public int
 	getAZVersion();
 	
+	public void
+	addPotentialAssociation(
+		String		key );
+	
 	public Map<String,Object> 
 	exportToBencodedMap() 
 	
 		throws IOException;
 	
+	public Map<String,Object> 
+	exportToBencodedMap(
+		boolean		generic )
+	
+		throws IOException;
+
 	public String
 	exportToJSONString()
 	
@@ -235,6 +251,11 @@ Engine
 	
 		throws IOException;
 	
+	public VuzeFile
+	exportToVuzeFile()
+	
+		throws IOException;
+	
 		/**
 		 * Tests for sameness in terms of function (ignores id, selection state etc)
 		 * @param other
diff --git a/com/aelitis/azureus/core/metasearch/MetaSearch.java b/com/aelitis/azureus/core/metasearch/MetaSearch.java
index a8fd593..c223714 100644
--- a/com/aelitis/azureus/core/metasearch/MetaSearch.java
+++ b/com/aelitis/azureus/core/metasearch/MetaSearch.java
@@ -20,6 +20,7 @@
 
 package com.aelitis.azureus.core.metasearch;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Map;
@@ -65,6 +66,9 @@ MetaSearch
   		Map<String,String>	context,
   		int					max_per_engine );
 	
+	public String
+	getFUD();
+	
 	public Engine[] 
 	getEngines(
 		boolean		active_only,
@@ -107,6 +111,12 @@ MetaSearch
 		Engine		engine );
 	
 	public void
+	exportEngines(
+		File	to_file )
+	
+		throws MetaSearchException;
+	
+	public void
 	addListener(
 		MetaSearchListener		listener );
 	
diff --git a/com/aelitis/azureus/core/metasearch/MetaSearchManager.java b/com/aelitis/azureus/core/metasearch/MetaSearchManager.java
index ca2abb6..f2d1df7 100644
--- a/com/aelitis/azureus/core/metasearch/MetaSearchManager.java
+++ b/com/aelitis/azureus/core/metasearch/MetaSearchManager.java
@@ -23,6 +23,8 @@ package com.aelitis.azureus.core.metasearch;
 
 import java.util.Map;
 
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+
 public interface 
 MetaSearchManager 
 {
@@ -48,6 +50,10 @@ MetaSearchManager
 	
 		throws MetaSearchException;
 	
+	public boolean
+	isImportable(
+		VuzeFile		vf );
+	
 	public Engine
 	importEngine(
 		Map			map,
@@ -56,6 +62,14 @@ MetaSearchManager
 		throws MetaSearchException;
 	
 	public void
+	addListener(
+		MetaSearchManagerListener		listener );
+	
+	public void
+	removeListener(
+		MetaSearchManagerListener		listener );
+	
+	public void
 	log(
 		String		str );
 }
diff --git a/com/aelitis/azureus/core/metasearch/MetaSearchManagerListener.java b/com/aelitis/azureus/core/metasearch/MetaSearchManagerListener.java
new file mode 100644
index 0000000..966c7f7
--- /dev/null
+++ b/com/aelitis/azureus/core/metasearch/MetaSearchManagerListener.java
@@ -0,0 +1,30 @@
+/*
+ * Created on Jan 25, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.metasearch;
+
+public interface 
+MetaSearchManagerListener 
+{
+	public void
+	searchRequest(
+		String		term );
+}
diff --git a/com/aelitis/azureus/core/metasearch/Result.java b/com/aelitis/azureus/core/metasearch/Result.java
index 8700b21..b781082 100644
--- a/com/aelitis/azureus/core/metasearch/Result.java
+++ b/com/aelitis/azureus/core/metasearch/Result.java
@@ -27,12 +27,15 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Random;
 
+import org.apache.commons.lang.Entities;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.json.simple.JSONObject;
 
 import com.aelitis.azureus.core.metasearch.utils.MomentsAgoDateFormatter;
 
 public abstract class Result {
+	private static final String HTML_TAGS = "(\\<(/?[^\\>]+)\\>)" ;
+	private static final String DUPLICATE_SPACES = "\\s{2,}";
 
 	private Engine		engine;
 	
@@ -355,4 +358,20 @@ public abstract class Result {
 			}
 		}
 	}
+	
+	protected static final String removeHTMLTags(String input) {
+		if ( input == null ){
+			return( null );
+		}
+		String result = input.replaceAll(HTML_TAGS, " ");
+		return result.replaceAll(DUPLICATE_SPACES, " ").trim();
+	}
+
+	protected static final String unescapeEntities( String input )
+	{
+		if ( input == null ){
+			return( null );
+		}
+		return( Entities.HTML40.unescape( input ));
+	}
 }
diff --git a/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java b/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
index 0ebb0a7..6d3f68f 100644
--- a/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/EngineImpl.java
@@ -121,6 +121,7 @@ EngineImpl
 		int				type,
 		long			id,
 		long			last_updated,
+		float			rank_bias,
 		String			name,
 		String			content )
 	
@@ -130,15 +131,15 @@ EngineImpl
 		
 		if ( type == Engine.ENGINE_TYPE_JSON ){
 			
-			return( JSONEngine.importFromJSONString( meta_search, id, last_updated, name, map ));
+			return( JSONEngine.importFromJSONString( meta_search, id, last_updated, rank_bias, name, map ));
 			
 		}else if ( type == Engine.ENGINE_TYPE_REGEX ){
 			
-			return( RegexEngine.importFromJSONString( meta_search, id, last_updated, name, map ));
+			return( RegexEngine.importFromJSONString( meta_search, id, last_updated, rank_bias, name, map ));
 			
 		}else if ( type == Engine.ENGINE_TYPE_RSS ){
 			
-			return( RSSEngine.importFromJSONString( meta_search, id, last_updated, name, map ));
+			return( RSSEngine.importFromJSONString( meta_search, id, last_updated, rank_bias, name, map ));
 			
 		}else{
 			
@@ -209,12 +210,14 @@ EngineImpl
 		int 			_type, 
 		long 			_id,
 		long			_last_updated,
+		float			_rank_bias,
 		String 			_name )
 	{
 		meta_search		= _meta_search;
 		type			= _type;
 		id				= _id;
 		last_updated	= _last_updated;
+		rank_bias		= _rank_bias;
 		name			= _name;
 		
 		version			= 1;
@@ -235,7 +238,10 @@ EngineImpl
 		meta_search		= _meta_search;
 		
 		type			= ((Long)map.get( "type" )).intValue();
-		id				= ((Long)map.get( "id")).longValue();
+		
+		Long l_id = (Long)map.get( "id");
+		
+		id				= l_id==null?meta_search.getManager().getLocalTemplateID():l_id.longValue();
 		last_updated	= ImportExportUtils.importLong( map, "last_updated" );
 		name			= ImportExportUtils.importString( map, "name" );
 		
@@ -275,38 +281,48 @@ EngineImpl
 	
 	protected void
 	exportToBencodedMap(
-		Map		map )
+		Map			map,
+		boolean		generic )
 	
 		throws IOException
 	{
 		map.put( "type", new Long( type ));
-		map.put( "id", new Long( id ));
-		map.put( "last_updated", new Long( last_updated ));
 		
 		ImportExportUtils.exportString( map, "name", name );
 		
-		map.put( "selected", new Long( selection_state ));
-		
-		ImportExportUtils.exportBoolean( map, "select_rec", selection_state_recorded );
-		
 		map.put( "source", new Long( source ));
-		
-		ImportExportUtils.exportFloat( map, "rank_bias", rank_bias );
-		ImportExportUtils.exportFloat( map, "pref_count", preferred_count );
-		
+
 		exportBEncodedMappings( map, "l1_map", first_level_mapping );
 		exportBEncodedMappings( map, "l2_map", second_level_mapping );
-		
+
 		map.put( "version", new Long( version ));
 		map.put( "az_version", new Long( az_version ));
-		map.put( "uid", uid );
+
+		ImportExportUtils.exportFloat( map, "rank_bias", rank_bias );
+
+		if ( !generic ){
+			
+			map.put( "id", new Long( id ));
+			
+			map.put( "last_updated", new Long( last_updated ));
+		
+			map.put( "selected", new Long( selection_state ));
+		
+			ImportExportUtils.exportBoolean( map, "select_rec", selection_state_recorded );
+			
+			ImportExportUtils.exportFloat( map, "pref_count", preferred_count );
+		
+			map.put( "uid", uid );
+		}
 		
 		if ( update_url != null ){
 		
 			ImportExportUtils.exportString( map, "update_url", update_url );
 		}
 		
-		map.put( "update_url_check_secs", new Long( update_check_default_secs ));
+		if ( update_check_default_secs != DEFAULT_UPDATE_CHECK_SECS ){
+			map.put( "update_url_check_secs", new Long( update_check_default_secs ));
+		}
 	}
 	
 		// json constructor
@@ -317,12 +333,13 @@ EngineImpl
 		int				type,
 		long			id,
 		long			last_updated,
+		float			rank_bias,
 		String			name,
 		JSONObject		map )
 	
 		throws IOException
 	{
-		this( meta_search, type, id, last_updated, name );
+		this( meta_search, type, id, last_updated, rank_bias, name );
 		
 		first_level_mapping 	= importJSONMappings( map, "value_map", true );
 		second_level_mapping 	= importJSONMappings( map, "ctype_map", false );
@@ -1086,6 +1103,12 @@ EngineImpl
 		}
 	}
 	
+	public boolean
+	isAuthenticated()
+	{
+		return( false );
+	}
+	
 	public void
 	recordSelectionState()
 	{
@@ -1104,7 +1127,7 @@ EngineImpl
 				
 				log( "Marking template id " + getId() + " as selected=" + selected );
 				
-				PlatformMetaSearchMessenger.setTemplatetSelected( getId(), ConstantsVuze.AZID, selected);
+				PlatformMetaSearchMessenger.setTemplatetSelected( meta_search.getManager().getExtensionKey(), getId(), ConstantsVuze.AZID, selected);
 				
 				selection_state_recorded = true;
 				
@@ -1176,9 +1199,9 @@ EngineImpl
 	
 	public float
 	applyRankBias(
-		float	rank )
+		float	_rank )
 	{
-		rank *= rank_bias;
+		float rank = _rank*rank_bias;
 				
 		rank *= (1 + 0.025 * preferred_count );
 		
@@ -1186,6 +1209,8 @@ EngineImpl
 		
 		rank = Math.max( rank, 0.0f );
 		
+		// System.out.println( getName() + " (" + rank_bias+"/"+preferred_count + "): " + _rank + " -> " + rank );
+		
 		return( rank );
 	}
 	
@@ -1278,6 +1303,13 @@ EngineImpl
 	}
 	
 	public void
+	addPotentialAssociation(
+		String	key )
+	{
+		meta_search.addPotentialAssociation( this, key );
+	}
+	
+	public void
 	exportToVuzeFile(
 		File	target )
 	
@@ -1292,6 +1324,29 @@ EngineImpl
 		vf.write( target );
 	}
 	
+	public VuzeFile
+	exportToVuzeFile()
+	
+		throws IOException
+	{
+		return( exportToVuzeFile( false ));
+	}
+	
+	public VuzeFile
+	exportToVuzeFile(
+		boolean		generic )
+	
+		throws IOException
+	{
+		VuzeFile	vf = VuzeFileHandler.getSingleton().create();
+		
+		vf.addComponent(
+			VuzeFileComponent.COMP_TYPE_METASEARCH_TEMPLATE,
+			exportToBencodedMap( generic ));
+		
+		return( vf );
+	}
+	
 	private String
 	getLocalKey()
 	{
diff --git a/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java b/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
index df4a336..28efffa 100644
--- a/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
+++ b/com/aelitis/azureus/core/metasearch/impl/ExternalLoginWindow.java
@@ -27,6 +27,7 @@ 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.browser.BrowserWrapper;
 import com.aelitis.azureus.ui.swt.browser.CookiesListener;
 import com.aelitis.azureus.ui.swt.browser.listener.ExternalLoginCookieListener;
 
@@ -34,7 +35,7 @@ public class ExternalLoginWindow {
 	
 	Display display;
 	Shell shell;
-	Browser browser;
+	BrowserWrapper browser;
 	
 	ExternalLoginListener	listener;
 	
@@ -90,7 +91,7 @@ public class ExternalLoginWindow {
 			explain.setText(MessageText.getString("externalLogin.explanation", new String[]{ name }));
 		}
 		
-		browser = Utils.createSafeBrowser(shell, SWT.BORDER);
+		browser = new BrowserWrapper( Utils.createSafeBrowser(shell, SWT.BORDER));
 		if (browser == null) {
 			shell.dispose();
 			return;
@@ -200,9 +201,9 @@ public class ExternalLoginWindow {
 	
 	protected void
 	setCaptureMethod(
-		final Browser		browser,
-		boolean				transparent,
-		boolean				show_progress )
+		final BrowserWrapper	browser,
+		boolean					transparent,
+		boolean					show_progress )
 	{
 		if ( sniffer != null ){
 			
diff --git a/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java b/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
index f8c50d4..5eac3ac 100644
--- a/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/MetaSearchImpl.java
@@ -32,11 +32,11 @@ 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.BDecoder;
+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.FileUtil;
-import org.gudy.azureus2.core3.util.HashWrapper;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.SystemTime;
@@ -51,12 +51,11 @@ import org.gudy.azureus2.plugins.utils.search.SearchProvider;
 import com.aelitis.azureus.core.messenger.config.PlatformMetaSearchMessenger;
 import com.aelitis.azureus.core.metasearch.*;
 import com.aelitis.azureus.core.metasearch.impl.plugin.PluginEngine;
-import com.aelitis.azureus.core.metasearch.impl.web.FieldMapping;
 import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
-import com.aelitis.azureus.core.metasearch.impl.web.regex.RegexEngine;
 import com.aelitis.azureus.core.metasearch.impl.web.rss.RSSEngine;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
+import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 
 public class 
@@ -90,9 +89,10 @@ MetaSearchImpl
 		loadConfig();
 	}
 	
-	protected 
-	MetaSearchImpl()
+	protected MetaSearchManagerImpl
+	getManager()
 	{
+		return( manager );
 	}
 	
 	public Engine
@@ -115,18 +115,38 @@ MetaSearchImpl
 	
 		throws IOException
 	{
-		return( EngineImpl.importFromJSONString( this, type, id, last_updated, name, content ));
+		return( EngineImpl.importFromJSONString( this, type, id, last_updated, rank_bias, name, content ));
 	}
 	
 	public EngineImpl
 	importFromPlugin(
-		String				pid,
+		String				_pid,
 		SearchProvider		provider )
 	
 		throws IOException
 	{
 		synchronized( this ){
 
+				// unfortunately pid can be internationalised and thus musn't be used as a key to
+				// a bencoded-map as it can lead of nastyness. Delete any existing entries that have
+				// got out of control
+			
+			Iterator<String>	it = plugin_map.keySet().iterator();
+			
+			while( it.hasNext()){
+				
+				if ( it.next().length() > 1024 ){
+					
+					Debug.out( "plugin_map corrupted, resetting" );
+							
+					plugin_map.clear();
+					
+					break;
+				}
+			}
+			
+			String pid = Base32.encode( _pid.getBytes( "UTF-8" ));
+			
 			Long	l_id = plugin_map.get( pid );
 			
 			long	id;
@@ -190,6 +210,7 @@ MetaSearchImpl
 					this, 
 					manager.getLocalTemplateID(), 
 					SystemTime.getCurrentTime(), 
+					1.0f,
 					name, 
 					url.toExternalForm(), 
 					false,
@@ -448,7 +469,7 @@ MetaSearchImpl
 	{
 		try{
 
-			PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( id );
+			PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( manager.getExtensionKey(), id );
 		
 			log( "Downloading definition of template " + id );
 			log( details.getValue());
@@ -592,6 +613,41 @@ MetaSearchImpl
 		}
 	}
 	
+	public String
+	getFUD()
+	{
+		List<EngineImpl> l = engines.getList();
+		
+		List<Long>	ids = new ArrayList<Long>();
+		
+		for ( EngineImpl engine: l ){
+			
+			if ( engine.getSource() == Engine.ENGINE_SOURCE_VUZE ){
+				
+				ids.add( engine.getId());
+			}
+		}
+		
+		Collections.sort( ids );
+		
+		String	fud = "";
+
+		for ( Long id: ids ){
+		
+			fud += (fud.length()==0?"":",") +id; 
+		}
+		
+		return( fud );
+	}
+	
+	protected void
+	addPotentialAssociation(
+		EngineImpl		engine,
+		String			key )
+	{
+		manager.addPotentialAssociation(engine, key);	
+	}
+	
 	public Engine[] 
 	getEngines(
 		boolean		active_only,
@@ -749,15 +805,6 @@ MetaSearchImpl
   		Map<String,String>		context,
   		final int				max_results_per_engine )
 	{
-		String	param_str = "";
-		
-		for (int i=0;i<searchParameters.length;i++){
-		
-			SearchParameter param = searchParameters[i];
-			
-			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 );
@@ -1062,7 +1109,7 @@ MetaSearchImpl
 			engines_str += (i==0?"":",") + engines[i].getId();
 		}
 		
-		log( "Search: params=" + param_str + "; engines=" + engines_str );
+		log( "Search: engines=" + engines_str );
 		
 		for (int i=0;i<engines.length;i++){
 			
@@ -1073,6 +1120,39 @@ MetaSearchImpl
 	}
 	
 	public void
+	exportEngines(
+		File	target )
+	
+		throws MetaSearchException
+	{
+		Engine[] engines = getEngines( true, false );
+		
+		VuzeFile	vf = VuzeFileHandler.getSingleton().create();
+		
+		for ( Engine engine: engines ){
+		
+			try{
+				vf.addComponent(
+					VuzeFileComponent.COMP_TYPE_METASEARCH_TEMPLATE,
+					engine.exportToBencodedMap());
+				
+			}catch( IOException e ){
+				
+				Debug.out( e );
+			}
+			
+		}
+		
+		try{
+			vf.write( target );
+			
+		}catch( IOException e ){
+			
+			throw( new MetaSearchException( "Failed to write file", e ));
+		}
+	}
+	
+	public void
 	addListener(
 		MetaSearchListener		listener )
 	{
@@ -1240,52 +1320,4 @@ MetaSearchImpl
 			writer.println( e.getString( true ));
 		}	
 	}
-	
-	public static void
-	main(
-		String[]		args )
-	{
-		try{
-			MetaSearchImpl ms = new MetaSearchImpl();
-			
-			EngineImpl e = new RegexEngine(
-					ms, 
-					Integer.MAX_VALUE + 9991,
-					SystemTime.getCurrentTime(),
-					"UpdateTest",
-					"http://localhost:1234/search=%s",
-					"",
-					"GMT",
-					true,
-					null,
-					new FieldMapping[] {
-						new FieldMapping("1",Engine.FIELD_CATEGORY),
-						new FieldMapping("2",Engine.FIELD_CDPLINK),
-						new FieldMapping("3",Engine.FIELD_NAME),
-						new FieldMapping("4",Engine.FIELD_TORRENTLINK),
-						new FieldMapping("5",Engine.FIELD_COMMENTS),
-						new FieldMapping("6",Engine.FIELD_DATE),
-						new FieldMapping("7",Engine.FIELD_SIZE),
-						new FieldMapping("8",Engine.FIELD_VOTES),
-						new FieldMapping("9",Engine.FIELD_SEEDS),
-						new FieldMapping("10",Engine.FIELD_PEERS),
-						},
-					false,
-					WebEngine.AM_TRANSPARENT,
-					"",
-					new String[] {""} );
-					
-			e.setUpdateURL( "http://localhost:5678/update" );
-			
-			e.setDefaultUpdateCheckSecs( 60 );
-			
-			e.setVersion( 2 );
-			
-			e.exportToVuzeFile( new File( "c:\\temp\\updatetest.vuze" ));
-			
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
 }
diff --git a/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java b/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
index 06f8486..08c0109 100644
--- a/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
+++ b/com/aelitis/azureus/core/metasearch/impl/MetaSearchManagerImpl.java
@@ -23,17 +23,23 @@ package com.aelitis.azureus.core.metasearch.impl;
 
 import java.io.File;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
 
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginListener;
 import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
 import org.gudy.azureus2.plugins.utils.StaticUtilities;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence;
 import org.gudy.azureus2.plugins.utils.search.Search;
 import org.gudy.azureus2.plugins.utils.search.SearchException;
 import org.gudy.azureus2.plugins.utils.search.SearchInitiator;
@@ -43,6 +49,7 @@ import org.gudy.azureus2.plugins.utils.search.SearchObserver;
 import org.gudy.azureus2.plugins.utils.search.SearchProvider;
 import org.gudy.azureus2.plugins.utils.search.SearchProviderResults;
 import org.gudy.azureus2.plugins.utils.search.SearchResult;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.custom.Customization;
@@ -53,27 +60,33 @@ import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.metasearch.MetaSearch;
 import com.aelitis.azureus.core.metasearch.MetaSearchException;
 import com.aelitis.azureus.core.metasearch.MetaSearchManager;
+import com.aelitis.azureus.core.metasearch.MetaSearchManagerListener;
 import com.aelitis.azureus.core.metasearch.Result;
 import com.aelitis.azureus.core.metasearch.ResultListener;
 import com.aelitis.azureus.core.metasearch.SearchParameter;
+import com.aelitis.azureus.core.metasearch.impl.plugin.PluginEngine;
+import com.aelitis.azureus.core.subs.Subscription;
+import com.aelitis.azureus.core.subs.SubscriptionManager;
+import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
 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.util.ConstantsVuze;
+import com.aelitis.azureus.util.ImportExportUtils;
 
 public class 
 MetaSearchManagerImpl
 	implements MetaSearchManager, UtilitiesImpl.searchManager, AEDiagnosticsEvidenceGenerator
 {
-	private static final boolean AUTO_MODE_DEFAULT		= false;
+	private static final boolean AUTO_MODE_DEFAULT		= true;
 	
 	
 	private static final String	LOGGER_NAME = "MetaSearch";
 	
 	private static final int REFRESH_MILLIS = 23*60*60*1000;
 	
-	private static MetaSearchManager singleton;	
+	private static MetaSearchManagerImpl singleton;	
 	
 	public static void
 	preInitialise()
@@ -96,7 +109,9 @@ MetaSearchManagerImpl
 							
 							VuzeFileComponent comp = comps[j];
 							
-							if ( comp.getType() == VuzeFileComponent.COMP_TYPE_METASEARCH_TEMPLATE ){
+							int	comp_type = comp.getType();
+							
+							if ( comp_type == VuzeFileComponent.COMP_TYPE_METASEARCH_TEMPLATE ){
 								
 								try{
 									Engine e = 
@@ -114,14 +129,42 @@ MetaSearchManagerImpl
 									
 									Debug.printStackTrace(e);
 								}
+							}else if ( comp_type == VuzeFileComponent.COMP_TYPE_METASEARCH_OPERATION ){
+								
+								getSingleton().addOperation( comp.getContent());
+								
+								comp.setProcessed();
 							}
 						}
 					}
 				}
-			});		
+			});	
+		
+		TorrentUtils.addTorrentAttributeListener(
+				new TorrentUtils.torrentAttributeListener()
+				{
+					public void 
+					attributeSet(
+						TOTorrent 	torrent,
+						String 		attribute, 
+						Object 		value )
+					{
+						if ( 	attribute == TorrentUtils.TORRENT_AZ_PROP_OBTAINED_FROM && 
+								!TorrentUtils.isReallyPrivate( torrent )){
+							
+							try{
+								getSingleton().checkPotentialAssociations( torrent.getHash(), (String)value );
+								
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+							}
+						}
+					}
+				});
 	}
 	
-	public static synchronized MetaSearchManager
+	public static synchronized MetaSearchManagerImpl
 	getSingleton()
 	{
 		if ( singleton == null ){
@@ -140,6 +183,22 @@ MetaSearchManagerImpl
 	
 	private boolean	checked_customization;
 	
+	private AsyncDispatcher					op_dispatcher 	= new AsyncDispatcher(5*1000);
+	private List<MetaSearchManagerListener>	listeners 		= new ArrayList<MetaSearchManagerListener>();
+	private List<Map>						operations		= new ArrayList<Map>();
+	
+	private String		extension_key;
+	
+	private Map<String,EngineImpl>	potential_associations = 
+		new LinkedHashMap<String,EngineImpl>(32,0.75f,true)
+		{
+			protected boolean 
+			removeEldestEntry(
+		   		Map.Entry<String,EngineImpl> eldest) 
+			{
+				return size() > 32;
+			}
+		};
 	protected
 	MetaSearchManagerImpl()
 	{
@@ -147,6 +206,15 @@ MetaSearchManagerImpl
 		
 		AEDiagnostics.addEvidenceGenerator( this );
 		
+		extension_key = COConfigurationManager.getStringParameter( "metasearch.extkey.latest", "" );
+
+		if ( extension_key.length() == 0 ){
+			
+			extension_key = null;
+		}
+		
+		setupExtensions();
+		
 		SimpleTimer.addPeriodicEvent(
 			"MetaSearchRefresh",
 			REFRESH_MILLIS,
@@ -181,6 +249,34 @@ MetaSearchManagerImpl
 		}
 	}
 	
+	public void 
+	removeProvider(
+		PluginInterface		pi,
+		SearchProvider 		provider ) 
+	{
+		String	id = pi.getPluginID() + "." + provider.getProperty( SearchProvider.PR_NAME );
+		
+		try{
+			Engine[] engines = meta_search.getEngines( false, false );
+			
+			for ( Engine engine: engines ){
+				
+				if ( engine instanceof PluginEngine ){
+					
+					PluginEngine pe = (PluginEngine)engine;
+					
+					if ( pe.getProvider() == provider ){
+						
+						engine.delete();
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to remove search provider '" + id + "' (" + provider + ")", e );
+		}
+	}
+	
 	public SearchProvider[]
   	getProviders()
 	{
@@ -488,8 +584,10 @@ MetaSearchManagerImpl
 					
 			Engine[]	engines = meta_search.getEngines( false, false );
 	
+			String	fud = meta_search.getFUD();
+			
 			try{
-				PlatformMetaSearchMessenger.templateInfo[] featured = PlatformMetaSearchMessenger.listFeaturedTemplates();
+				PlatformMetaSearchMessenger.templateInfo[] featured = PlatformMetaSearchMessenger.listFeaturedTemplates( extension_key, fud );
 				
 				String featured_str = "";
 				
@@ -515,7 +613,7 @@ MetaSearchManagerImpl
 				
 				if ( auto_mode || first_run ){
 					
-					PlatformMetaSearchMessenger.templateInfo[] popular = PlatformMetaSearchMessenger.listTopPopularTemplates();
+					PlatformMetaSearchMessenger.templateInfo[] popular = PlatformMetaSearchMessenger.listTopPopularTemplates( extension_key, fud );
 					
 					String popular_str = "";
 					String preload_str = "";
@@ -591,7 +689,7 @@ MetaSearchManagerImpl
 						manual_ids[pos++] = it.next().longValue();
 					}
 					
-					PlatformMetaSearchMessenger.templateInfo[] manual = PlatformMetaSearchMessenger.getTemplateDetails( manual_ids );
+					PlatformMetaSearchMessenger.templateInfo[] manual = PlatformMetaSearchMessenger.getTemplateDetails( extension_key, manual_ids );
 										
 					for (int i=0;i<manual.length;i++){
 						
@@ -656,7 +754,7 @@ MetaSearchManagerImpl
 	
 					if ( update ){
 						
-						PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( id );
+						PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( extension_key, id );
 	
 						log( "Downloading definition of template " + id );
 						log( details.getValue());
@@ -695,11 +793,19 @@ MetaSearchManagerImpl
 					
 					if ( this_engine != null ){
 							
-						if ( this_engine.getSelectionState() == Engine.SEL_STATE_DESELECTED ){
+						int sel_state = this_engine.getSelectionState();
+						
+						if ( sel_state == Engine.SEL_STATE_DESELECTED ){
 						
 							log( "Auto-selecting " + this_engine.getString());
 							
 							this_engine.setSelectionState( Engine.SEL_STATE_AUTO_SELECTED );
+							
+						}else if ( auto_mode && sel_state == Engine.SEL_STATE_MANUAL_SELECTED ){
+							
+							log( "Switching Manual to Auto select for " + this_engine.getString());
+							
+							this_engine.setSelectionState( Engine.SEL_STATE_AUTO_SELECTED );
 						}
 					}
 				}
@@ -718,7 +824,7 @@ MetaSearchManagerImpl
 						
 					if ( this_engine == null ){
 						
-						PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( id );
+						PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( extension_key, id );
 	
 						log( "Downloading pre-load definition of template " + id );
 						log( details.getValue());
@@ -884,7 +990,7 @@ MetaSearchManagerImpl
 				
 				if ( existing == null ){
 														
-					PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( id );
+					PlatformMetaSearchMessenger.templateDetails details = PlatformMetaSearchMessenger.getTemplate( extension_key, id );
 	
 					log( "Downloading definition of template " + id );
 					log( details.getValue());
@@ -968,6 +1074,64 @@ MetaSearchManagerImpl
 		}
 	}
 	
+	public boolean
+	isImportable(
+		VuzeFile		vf )
+	{
+		VuzeFileComponent[] comps = vf.getComponents();
+		
+		for (int j=0;j<comps.length;j++){
+			
+			VuzeFileComponent comp = comps[j];
+			
+			int	comp_type = comp.getType();
+			
+			if ( comp_type == VuzeFileComponent.COMP_TYPE_METASEARCH_TEMPLATE ){
+				
+				try{
+					EngineImpl engine = (EngineImpl)meta_search.importFromBEncodedMap( comp.getContent());
+					
+					long	id = engine.getId();
+					
+					Engine existing = meta_search.getEngine( id );
+					
+					if ( existing != null ){
+						
+						if ( !existing.sameLogicAs( engine )){
+							
+							return( true );
+						}
+					}else{
+						try{						
+							Engine[] engines = meta_search.getEngines( false, false );
+								
+							boolean is_new = true;
+							
+							for ( Engine e: engines ){
+									
+								if ( e.sameLogicAs( engine )){
+										
+									is_new = false;
+									
+									break;
+								}
+							}
+							
+							if ( is_new ){
+								
+								return( true );
+							}
+						}catch( Throwable e ){	
+						}	
+					}
+				}catch( Throwable e ){				
+				}
+			}
+		}
+		
+		return( false );
+	}
+	
 	public Engine
 	importEngine(
 		Map			map,
@@ -1002,6 +1166,21 @@ MetaSearchManagerImpl
 					
 					return( existing );
 				}
+			}else{
+									
+				try{						
+					Engine[] engines = meta_search.getEngines( false, false );
+						
+					for ( Engine e: engines ){
+							
+						if ( e.sameLogicAs( engine )){
+								
+							return( e );
+						}
+					}
+				}catch( Throwable e ){
+					
+				}
 			}
 			
 			if ( warn_user ){
@@ -1074,6 +1253,60 @@ MetaSearchManagerImpl
 		}
 	}
 	
+	protected void
+	addPotentialAssociation(
+		EngineImpl		engine,
+		String			key )
+	{		
+		if ( engine.isShareable() && !engine.isAuthenticated()){
+			
+			synchronized( potential_associations ){
+				
+				potential_associations.put( key, engine );
+			}
+		}
+	}
+	
+	private void
+	checkPotentialAssociations(
+		byte[]		hash,
+		String		key )
+	{
+		EngineImpl	engine;
+		
+		synchronized( potential_associations ){
+			
+			engine = potential_associations.remove( key );
+		}
+	
+		if ( engine != null ){
+	
+			try{
+				VuzeFile vf = engine.exportToVuzeFile( true );
+				
+				byte[] bytes = vf.exportToBytes();
+												
+				String url_str = "vuze://?body=" + new String( bytes, Constants.BYTE_ENCODING );
+								
+				SubscriptionManager sub_man = SubscriptionManagerFactory.getSingleton();
+		
+				Subscription subs =
+					sub_man.createSingletonRSS(
+						vf.getName() + ": " + engine.getName() + " (v" + engine.getVersion() + ")",
+						new URL( url_str ),
+						Integer.MAX_VALUE );
+			
+				subs.setSubscribed( true );
+			
+				subs.addAssociation( hash );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
 	public Engine[]
 	loadFromVuzeFile(
 		File		file )
@@ -1134,6 +1367,204 @@ MetaSearchManagerImpl
 		}
 	}
 	
+	public void
+	addListener(
+		MetaSearchManagerListener		listener )
+	{			
+		synchronized( listeners ){
+			
+			listeners.add( listener );
+		}
+			
+		dispatchOps();
+	}
+	
+	public void
+	removeListener(
+		MetaSearchManagerListener		listener )
+	{
+		
+	}
+	
+	private void
+	addOperation(
+		Map		map )
+	{
+		synchronized( listeners ){
+			
+			operations.add( map );
+		}
+		
+		dispatchOps();
+	}
+	
+	private void
+	dispatchOps()
+	{
+		op_dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					List<MetaSearchManagerListener>	l;
+					List<Map>						o;
+					
+					synchronized( listeners ){
+					
+						if ( listeners.size() == 0 || operations.size() == 0 ){
+							
+							return;
+						}
+						
+						l = new ArrayList<MetaSearchManagerListener>( listeners );
+						
+						o = new ArrayList<Map>( operations );
+						
+						operations.clear();
+					}
+					
+					for ( MetaSearchManagerListener listener: l ){
+						
+						for ( Map operation: o ){
+					
+							try{
+
+								int	type = ImportExportUtils.importInt( operation, "type", -1 );
+								
+								if ( type == 1 ){
+									
+									String	term = ImportExportUtils.importString( operation, "term", null );
+								
+									if ( term == null ){
+										
+										Debug.out( "search term missing" );
+										
+									}else{
+										
+										listener.searchRequest( term );
+									}
+								}else{
+								
+									Debug.out( "unknown operation type " + type );
+								}								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					}
+				}
+			});
+	}
+	
+	private void
+	setupExtensions()
+	{
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+		
+		final FeatureManager fm = pi.getUtilities().getFeatureManager();
+					
+		fm.addListener(
+			new FeatureManager.FeatureManagerListener()
+			{
+				public void
+				licenceAdded(
+					Licence	licence )
+				{
+					getExtensions( fm, false );
+				}
+				
+				public void
+				licenceChanged(
+					Licence	licence )
+				{
+					getExtensions( fm, false );
+				}
+				
+				public void
+				licenceRemoved(
+					Licence	licence )
+				{
+					getExtensions( fm, false );
+				}
+			});
+		
+		if ( pi.getPluginState().isInitialisationComplete()){
+			
+			getExtensions( fm, true );
+			
+		}else{
+			
+			pi.addListener(
+				new PluginListener()
+				{
+					public void
+					initializationComplete()
+					{
+						getExtensions( fm, false );
+					}
+					
+					public void
+					closedownInitiated()
+					{
+					}
+					
+					public void
+					closedownComplete()
+					{	
+					}
+				});
+		}
+	}
+	
+	private void
+	getExtensions(
+		FeatureManager		fm,
+		boolean				init )
+	{
+		String	existing_ext 	= extension_key;
+		String	latest_ext		= null;
+		
+		FeatureDetails[] fds = fm.getFeatureDetails( "core" );
+		
+		for ( FeatureDetails fd: fds ){
+				
+			if ( !fd.hasExpired()){
+				
+				String finger_print = (String)fd.getProperty( FeatureDetails.PR_FINGERPRINT );
+					
+				if ( finger_print != null ){
+				
+					latest_ext = fd.getLicence().getShortID() + "-" + finger_print;
+					
+					break;
+				}
+			}
+		}
+
+		if ( existing_ext != latest_ext ){
+			
+			if ( existing_ext == null || latest_ext == null || !existing_ext.equals( latest_ext )){
+				
+				extension_key	= latest_ext;
+				
+				COConfigurationManager.setParameter( "metasearch.extkey.latest", latest_ext==null?"":latest_ext );
+				
+				if ( !init ){
+					
+					refresh();
+				}
+			}
+		}
+	}
+	
+	protected String
+	getExtensionKey()
+	{
+		return( extension_key );
+	}
+	
 	public void 
 	log(
 		String 		s,
@@ -1695,4 +2126,28 @@ MetaSearchManagerImpl
 			Debug.out( "Not supported" );
 		}
 	}
+    
+    public static void
+    main(
+    	String[]	args )
+    {
+    	try{
+			VuzeFile	vf = VuzeFileHandler.getSingleton().create();
+			
+			Map contents = new HashMap();
+			
+			contents.put( "type", new Long( 1 ));
+			contents.put( "term", "donkey" );
+			
+			vf.addComponent(
+				VuzeFileComponent.COMP_TYPE_METASEARCH_OPERATION,
+				contents);
+			
+			vf.write( new File( "C:\\temp\\search.vuze" ));
+			
+    	}catch( Throwable e ){
+    		
+    		e.printStackTrace();
+    	}
+    }
 }
diff --git a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
index b782b1c..676dae5 100644
--- a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginEngine.java
@@ -77,7 +77,7 @@ PluginEngine
 		long				_id,
 		SearchProvider		_provider )
 	{
-		super( _meta_search, Engine.ENGINE_TYPE_PLUGIN, _id, 0, (String)_provider.getProperty( SearchProvider.PR_NAME ));
+		super( _meta_search, Engine.ENGINE_TYPE_PLUGIN, _id, 0, 1.0f, (String)_provider.getProperty( SearchProvider.PR_NAME ));
 		
 		provider	= _provider;
 		
@@ -93,17 +93,33 @@ PluginEngine
 	{
 		super( _meta_search, _map );
 		
+			// recovery from when incorrectly defaulted to 0.0
+		
+		if ( getRankBias() == 0.0f ){
+			
+			setRankBias( 1.0f );
+		}
+		
 		setSource( ENGINE_SOURCE_LOCAL );
 	}
 	
 	public Map 
-	exportToBencodedMap() 
+	exportToBencodedMap()
+	
+		throws IOException
+	{
+		return( exportToBencodedMap( false ));
+	}
+	
+	public Map 
+	exportToBencodedMap(
+		boolean	generic )
 	
 		throws IOException 
 	{
 		Map	res = new HashMap();
 				
-		super.exportToBencodedMap( res );
+		super.exportToBencodedMap( res, generic );
 		
 		return( res );
 	}
@@ -115,6 +131,12 @@ PluginEngine
 		provider	= _provider;
 	}
 	
+	public SearchProvider
+	getProvider()
+	{
+		return( provider );
+	}
+	
 	protected boolean
 	useAccuracyForRank()
 	{
diff --git a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
index 73f00d8..817965c 100644
--- a/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
+++ b/com/aelitis/azureus/core/metasearch/impl/plugin/PluginResult.java
@@ -343,7 +343,7 @@ PluginResult
 				return( def );
 			}
 			
-			return( l );
+			return( unescapeEntities( removeHTMLTags( l )));
 			
 		}catch( Throwable e ){
 			
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/WebEngine.java b/com/aelitis/azureus/core/metasearch/impl/web/WebEngine.java
index 62b7e82..e515f33 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/WebEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/WebEngine.java
@@ -35,6 +35,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
@@ -48,6 +49,9 @@ import com.aelitis.azureus.core.metasearch.SearchLoginException;
 import com.aelitis.azureus.core.metasearch.SearchParameter;
 import com.aelitis.azureus.core.metasearch.impl.*;
 import com.aelitis.azureus.core.util.GeneralUtils;
+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.util.ImportExportUtils;
 import com.aelitis.azureus.util.UrlFilter;
 
@@ -58,6 +62,9 @@ WebEngine
 	public static final String	AM_TRANSPARENT 	= "transparent";
 	public static final String	AM_PROXY		= "proxy";
 	
+	private static final boolean NEEDS_AUTH_DEFAULT				= false;
+	private static final boolean AUTOMATIC_DATE_PARSER_DEFAULT 	= true;
+	
 	static private final Pattern baseTagPattern = Pattern.compile("(?i)<base.*?href=\"([^\"]+)\".*?>");
 	static private final Pattern rootURLPattern = Pattern.compile("(https?://[^/]+)");
 	static private final Pattern baseURLPattern = Pattern.compile("(https?://.*/)");
@@ -79,6 +86,7 @@ WebEngine
 	private boolean needsAuth;
 	private String	authMethod;
 	private String loginPageUrl;
+	private String iconUrl;
 	private String[] requiredCookies;
 	
 	private String local_cookies;
@@ -92,6 +100,7 @@ WebEngine
 		int 			type, 
 		long 			id, 
 		long 			last_updated, 
+		float			rank_bias,
 		String 			name,
 		String 			searchURLFormat,
 		String 			timeZone,
@@ -103,7 +112,7 @@ WebEngine
 		String			login_url,
 		String[]		required_cookies )
 	{	
-		super( meta_search, type, id, last_updated, name );
+		super( meta_search, type, id, last_updated, rank_bias, name );
 
 		this.searchURLFormat 		= searchURLFormat;
 		this.timeZone 				= timeZone;
@@ -134,12 +143,13 @@ WebEngine
 		userDateFormat		= ImportExportUtils.importString( map, "web.date_format" );
 		downloadLinkCSS		= ImportExportUtils.importString( map, "web.dl_link_css" );
 		
-		needsAuth			= ImportExportUtils.importBoolean(map, "web.needs_auth", false );
+		needsAuth			= ImportExportUtils.importBoolean(map, "web.needs_auth", NEEDS_AUTH_DEFAULT );
 		authMethod			= ImportExportUtils.importString( map, "web.auth_method", WebEngine.AM_TRANSPARENT );
 		loginPageUrl 		= ImportExportUtils.importString( map, "web.login_page" );
 		requiredCookies 	= ImportExportUtils.importStringArray( map, "web.required_cookies" );
 
-		automaticDateParser	= ImportExportUtils.importBoolean( map, "web.auto_date", true );
+		automaticDateParser	= ImportExportUtils.importBoolean( map, "web.auto_date", AUTOMATIC_DATE_PARSER_DEFAULT );
+		iconUrl 		= ImportExportUtils.importString( map, "web.icon_url" );
 
 		List	maps = (List)map.get( "web.maps" );
 		
@@ -160,24 +170,62 @@ WebEngine
 	
 	protected void
 	exportToBencodedMap(
-		Map		map )
+		Map		map,
+		boolean	generic )
 	
 		throws IOException
 	{
-		super.exportToBencodedMap( map );
-		
-		ImportExportUtils.exportString( map, "web.search_url_format", 		searchURLFormat );
-		ImportExportUtils.exportString( map, "web.time_zone", 				timeZone );		
-		ImportExportUtils.exportString( map, "web.date_format", 			userDateFormat );
-		ImportExportUtils.exportString( map, "web.dl_link_css",				downloadLinkCSS );
+		super.exportToBencodedMap( map, generic );
 		
-		ImportExportUtils.exportBoolean( map, "web.needs_auth",				needsAuth );
-		ImportExportUtils.exportString( map, "web.auth_method",				authMethod );
-		ImportExportUtils.exportString( map, "web.login_page",				loginPageUrl );
-		ImportExportUtils.exportStringArray( map, "web.required_cookies",	requiredCookies );
-
-		ImportExportUtils.exportBoolean( map, "web.auto_date", automaticDateParser );
+		if ( generic ){
+			
+			if ( searchURLFormat != null ){
+				ImportExportUtils.exportString( map, "web.search_url_format", 		searchURLFormat );
+			}
+			if ( timeZone != null ){
+				ImportExportUtils.exportString( map, "web.time_zone", 				timeZone );
+			}
+			if ( userDateFormat != null ){
+				ImportExportUtils.exportString( map, "web.date_format", 			userDateFormat );
+			}
+			if ( downloadLinkCSS != null ){
+				ImportExportUtils.exportString( map, "web.dl_link_css",				downloadLinkCSS );
+			}
+			
+			if ( needsAuth != NEEDS_AUTH_DEFAULT ){
+				ImportExportUtils.exportBoolean( map, "web.needs_auth",				needsAuth );
+			}
+			if ( authMethod != null && !authMethod.equals( WebEngine.AM_TRANSPARENT )){
+				ImportExportUtils.exportString( map, "web.auth_method",				authMethod );
+			}
+			if ( loginPageUrl != null ){
+				ImportExportUtils.exportString( map, "web.login_page",				loginPageUrl );
+			}
+			if ( iconUrl != null ) {
+				ImportExportUtils.exportString(map, "web.icon_url", iconUrl);
+			}
+			if ( requiredCookies != null && requiredCookies.length > 0 ){
+				ImportExportUtils.exportStringArray( map, "web.required_cookies",	requiredCookies );
+			}
+			if (automaticDateParser != AUTOMATIC_DATE_PARSER_DEFAULT ){
+				ImportExportUtils.exportBoolean( map, "web.auto_date", automaticDateParser );
+			}
 
+		}else{
+			ImportExportUtils.exportString( map, "web.search_url_format", 		searchURLFormat );
+			ImportExportUtils.exportString( map, "web.time_zone", 				timeZone );		
+			ImportExportUtils.exportString( map, "web.date_format", 			userDateFormat );
+			ImportExportUtils.exportString( map, "web.dl_link_css",				downloadLinkCSS );
+			
+			ImportExportUtils.exportBoolean( map, "web.needs_auth",				needsAuth );
+			ImportExportUtils.exportString( map, "web.auth_method",				authMethod );
+			ImportExportUtils.exportString( map, "web.login_page",				loginPageUrl );
+			ImportExportUtils.exportString( map, "web.icon_url", iconUrl);
+			ImportExportUtils.exportStringArray( map, "web.required_cookies",	requiredCookies );
+	
+			ImportExportUtils.exportBoolean( map, "web.auto_date", automaticDateParser );
+		}
+		
 		List	maps = new ArrayList();
 		
 		map.put( "web.maps", maps );
@@ -203,12 +251,13 @@ WebEngine
 		int				type,
 		long			id,
 		long			last_updated,
+		float			rank_bias,
 		String			name,
 		JSONObject		map )
 	
 		throws IOException
 	{
-		super( meta_search, type, id, last_updated, name, map );
+		super( meta_search, type, id, last_updated, rank_bias, name, map );
 		
 		searchURLFormat 	= ImportExportUtils.importURL( map, "searchURL" );
 		timeZone			= ImportExportUtils.importString( map, "timezone" );
@@ -219,6 +268,7 @@ WebEngine
 		needsAuth			= ImportExportUtils.importBoolean( map, "needs_auth", false );
 		authMethod			= ImportExportUtils.importString( map, "auth_method", WebEngine.AM_TRANSPARENT );
 		loginPageUrl 		= ImportExportUtils.importURL( map, "login_page" );
+		iconUrl 		= ImportExportUtils.importURL( map, "icon_url" );
 		
 		requiredCookies 	= ImportExportUtils.importStringArray( map, "required_cookies" );
 		
@@ -232,6 +282,14 @@ WebEngine
 			
 			Map	m = (Map)maps.get(i);
 				
+				// wha? getting some nulls here :( 
+				// from JSON like "column_map\":[null,null,{\"group_nb\":\"3
+			
+			if ( m == null ){
+				
+				continue;
+			}
+			
 				// backwards compact from when there was a mapping entry
 			
 			Map test = (Map)m.get( "mapping" );
@@ -292,6 +350,7 @@ WebEngine
 		ImportExportUtils.exportJSONBoolean( res, "needs_auth",				needsAuth );
 		ImportExportUtils.exportJSONString( res, "auth_method",				authMethod );
 		ImportExportUtils.exportJSONURL( res, "login_page",					loginPageUrl );
+		ImportExportUtils.exportJSONURL( res, "icon_url",					iconUrl );
 		ImportExportUtils.exportJSONStringArray( res, "required_cookies",	requiredCookies );
  
 		if ( !automaticDateParser ){
@@ -482,6 +541,7 @@ WebEngine
 	{
 		
 		try {
+			TorrentUtils.setTLSDescription( "Search: " + getName());
 			
 			if ( requiresLogin()){
 				
@@ -490,41 +550,46 @@ WebEngine
 			
 			String searchURL = searchURLFormat;
 			
-			String[]	from_strs 	= new String[ searchParameters.length ];
-			String[]	to_strs 	= new String[ searchParameters.length ];
+			boolean vuze_file = searchURL.toLowerCase().startsWith( "vuze:" );
 			
-			for( int i = 0 ; i < searchParameters.length ; i++ ){
-				
-				SearchParameter parameter = searchParameters[i];
+			if ( !vuze_file ){
 				
-				from_strs[i]	= "%" + parameter.getMatchPattern();
-				to_strs[i]		= URLEncoder.encode(parameter.getValue(),"UTF-8");
-			}
-			
-			searchURL = GeneralUtils.replaceAll( searchURL, from_strs, to_strs );
+				String[]	from_strs 	= new String[ searchParameters.length ];
+				String[]	to_strs 	= new String[ searchParameters.length ];
 				
-			Iterator<Map.Entry<String, String>>	it = searchContext.entrySet().iterator();
-			
-			while( it.hasNext()){
+				for( int i = 0 ; i < searchParameters.length ; i++ ){
+					
+					SearchParameter parameter = searchParameters[i];
+					
+					from_strs[i]	= "%" + parameter.getMatchPattern();
+					to_strs[i]		= URLEncoder.encode(parameter.getValue(),"UTF-8");
+				}
 				
-				Map.Entry<String, String>	entry = it.next();
+				searchURL = GeneralUtils.replaceAll( searchURL, from_strs, to_strs );
+					
+				Iterator<Map.Entry<String, String>>	it = searchContext.entrySet().iterator();
 				
-				String	key 	= entry.getKey();
+				while( it.hasNext()){
 					
-				if ( supportsContext( key )){
+					Map.Entry<String, String>	entry = it.next();
 					
-					if ( searchURL.indexOf('?') == -1 ){
+					String	key 	= entry.getKey();
 						
-						searchURL += "?";
+					if ( supportsContext( key )){
 						
-					}else{
+						if ( searchURL.indexOf('?') == -1 ){
+							
+							searchURL += "?";
+							
+						}else{
+							
+							searchURL += "&";
+						}
 						
-						searchURL += "&";
+						String	value 	= entry.getValue();
+	
+						searchURL += key + "=" + URLEncoder.encode( value, "UTF-8" );
 					}
-					
-					String	value 	= entry.getValue();
-
-					searchURL += key + "=" + URLEncoder.encode( value, "UTF-8" );
 				}
 			}
 			
@@ -730,6 +795,16 @@ WebEngine
 								content_type = content_type.substring(0,pos).trim();
 							}
 							
+							if ( content_type.startsWith("\"" )){
+								
+								content_type = content_type.substring(1).trim();
+							}
+							
+							if ( content_type.endsWith("\"" )){
+								
+								content_type = content_type.substring(0,content_type.length()-1).trim();
+							}
+							
 							try{
 								if ( Charset.isSupported( content_type )){
 									
@@ -778,6 +853,23 @@ WebEngine
 			
 			byte[] data = baos.toByteArray();
 			
+			if ( vuze_file ){
+				
+				try{
+					VuzeFileHandler vfh = VuzeFileHandler.getSingleton();
+					
+					VuzeFile vf = vfh.loadVuzeFile( data );
+					
+					vfh.handleFiles( new VuzeFile[]{ vf }, VuzeFileComponent.COMP_TYPE_NONE );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+				
+				return( new pageDetails( initial_url, initial_url, null ));
+			}
+			
 			String 	page = null;
 			
 			String	content = new String( data, 0, Math.min( data.length, 2048 ), content_charset );
@@ -974,6 +1066,10 @@ WebEngine
 			debugLog( "Failed to load page: " + Debug.getNestedExceptionMessageAndStack(e));
 			
 			throw( new SearchException( "Failed to load page", e ));
+			
+		}finally{
+			
+			TorrentUtils.setTLSDescription( null );
 		}
 	}
 
@@ -1021,6 +1117,9 @@ WebEngine
 	}
 	
 	public String getIcon() {
+		if (iconUrl != null) {
+			return iconUrl;
+		}
 		if(rootPage != null) {
 			return rootPage + "/favicon.ico";
 		}
@@ -1088,6 +1187,19 @@ WebEngine
 	}
 
 	public String
+	getSearchUrl(
+		boolean		raw )
+	{
+		if ( raw ){
+			
+			return( searchURLFormat );
+		}else{
+			
+			return( getSearchUrl());
+		}
+	}
+	
+	public String
 	getSearchUrl()
 	{
 		return( searchURLFormat.replaceAll("%s", ""));
@@ -1115,6 +1227,12 @@ WebEngine
 		return needsAuth;
 	}
 
+	public boolean
+	isAuthenticated()
+	{
+		return( isNeedsAuth());
+	}
+	
 	protected void
 	setNeedsAuth(
 		boolean	b )
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java b/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
index 4b26eb0..47a65d8 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/WebResult.java
@@ -27,6 +27,7 @@ import org.apache.commons.lang.*;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.UrlUtils;
 
 import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.metasearch.Result;
@@ -35,9 +36,6 @@ import com.aelitis.azureus.core.metasearch.impl.DateParser;
 public class WebResult extends Result {
 	
 	
-	private static final String HTML_TAGS = "(\\<(/?[^\\>]+)\\>)" ;
-	private static final String DUPLICATE_SPACES = "\\s{2,}";
-	
 	
 	String searchQuery;
 	
@@ -80,12 +78,7 @@ public class WebResult extends Result {
 		this.dateParser = dateParser;
 		this.searchQuery = searchQuery;
 	}
-	
-	private static final String removeHTMLTags(String input) {
-		String result = input.replaceAll(HTML_TAGS, " ");
-		return result.replaceAll(DUPLICATE_SPACES, " ").trim();
-	}
-	
+		
 	public void setName(String name) {
 		if(name != null) {
 			this.name = name;
@@ -181,7 +174,19 @@ public class WebResult extends Result {
 			}
 		}
 	}
-	
+
+	public void setRankFromHTML( String rank_str, float divisor ){
+		if (rank_str == null) {
+			return;
+		}
+		try{
+			float f = Float.parseFloat( rank_str.trim() );
+			
+			rank = f / divisor;
+		}catch( Throwable e ){
+		}
+	}
+
 	public void setRankFromHTML( String rank_str ){
 		if ( rank_str != null ){
 			try{
@@ -254,14 +259,20 @@ public class WebResult extends Result {
 					multiplier = KB_UNIT*KB_UNIT;
 				} else if("mib".equals(unit)) {
 					multiplier = KIB_UNIT*KIB_UNIT;
+				} else if("m".equals(unit)) {
+					multiplier = KIB_UNIT*KIB_UNIT;
 				} else if("gb".equals(unit)) {
 					multiplier = KB_UNIT*KB_UNIT*KB_UNIT;
 				} else if("gib".equals(unit)) {
 					multiplier = KIB_UNIT*KIB_UNIT*KIB_UNIT;
+				} else if("g".equals(unit)) {
+					multiplier = KIB_UNIT*KIB_UNIT*KIB_UNIT;
 				} else if("kb".equals(unit)) {
 					multiplier = KB_UNIT;
 				} else if("kib".equals(unit)) {
 					multiplier = KIB_UNIT;
+				} else if("k".equals(unit)) {
+					multiplier = KIB_UNIT;
 				}
 				
 				this.size = (long) (base * multiplier);
@@ -318,15 +329,15 @@ public class WebResult extends Result {
 	}
 	
 	public void setCDPLink(String cdpLink) {
-		this.cdpLink = cdpLink;
+		this.cdpLink = UrlUtils.unescapeXML(cdpLink);
 	}
 	
 	public void setDownloadButtonLink(String downloadButtonLink) {
-		this.downloadButtonLink = downloadButtonLink;
+		this.downloadButtonLink = UrlUtils.unescapeXML(downloadButtonLink);
 	}
 	
 	public void setTorrentLink(String torrentLink) {
-		this.torrentLink = torrentLink;
+		this.torrentLink = UrlUtils.unescapeXML(torrentLink);
 	}
 	
 	public void setPlayLink(String playLink) {
@@ -382,6 +393,13 @@ public class WebResult extends Result {
 			
 			hash = null;
 		}
+		
+		if(hash != null && downloadButtonLink == null) {
+			setDownloadButtonLink(UrlUtils.normaliseMagnetURI(hash));			
+		}
+		if(hash != null && torrentLink == null) {
+			setTorrentLink(UrlUtils.normaliseMagnetURI(hash));			
+		}
 	}
 	
 	public String
@@ -429,6 +447,8 @@ public class WebResult extends Result {
 					lc_link.startsWith("https://") ||
 					lc_link.startsWith("azplug:") ||
 					lc_link.startsWith("magnet:") ||
+					lc_link.startsWith("bc:") ||
+					lc_link.startsWith("bctp:") ||
 					lc_link.startsWith("dht:" )){
 				
 				return( link );
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/json/JSONEngine.java b/com/aelitis/azureus/core/metasearch/impl/web/json/JSONEngine.java
index b7c3a7f..b3b8951 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/json/JSONEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/json/JSONEngine.java
@@ -28,6 +28,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.UrlUtils;
@@ -51,6 +53,9 @@ public class
 JSONEngine 
 	extends WebEngine 
 {
+	private final static String variablePattern = "\\$\\{[^}]+\\}";
+	private final static Pattern patternVariable = Pattern.compile(variablePattern);
+
 	public static EngineImpl
 	importFromBEncodedMap(
 		MetaSearchImpl	meta_search,
@@ -66,15 +71,19 @@ JSONEngine
 		MetaSearchImpl	meta_search,
 		long			id,
 		long			last_updated,
+		float			rank_bias,
 		String			name,
 		JSONObject		map )
 	
 		throws IOException
 	{
-		return( new JSONEngine( meta_search, id, last_updated, name, map ));
+		return( new JSONEngine( meta_search, id, last_updated, rank_bias, name, map ));
 	}
 	
 	private String resultsEntryPath;
+	private String rankDivisorPath;
+	
+	private float rankDivisor = 1.0f;
 
 	
 		// explicit test constructor
@@ -84,6 +93,7 @@ JSONEngine
 		MetaSearchImpl		meta_search,
 		long 				id,
 		long 				last_updated,
+		float				rank_bias,
 		String 				name,
 		String 				searchURLFormat,
 		String 				timeZone,
@@ -100,6 +110,7 @@ JSONEngine
 				Engine.ENGINE_TYPE_JSON, 
 				id,
 				last_updated,
+				rank_bias,
 				name,
 				searchURLFormat,
 				timeZone,
@@ -130,6 +141,7 @@ JSONEngine
 		super( meta_search, map );
 		
 		resultsEntryPath = ImportExportUtils.importString( map, "json.path" );
+		rankDivisorPath = ImportExportUtils.importString( map, "rank.divisor.path" );
 	}
 	
 		// json constructor
@@ -139,18 +151,29 @@ JSONEngine
 		MetaSearchImpl	meta_search,
 		long			id,
 		long			last_updated,
+		float			rank_bias,
 		String			name,
 		JSONObject		map )
 	
 		throws IOException
 	{
-		super( meta_search, Engine.ENGINE_TYPE_JSON, id, last_updated, name, map );
+		super( meta_search, Engine.ENGINE_TYPE_JSON, id, last_updated, rank_bias, name, map );
 				
 		resultsEntryPath = ImportExportUtils.importString( map, "json_result_key" );
+		rankDivisorPath = ImportExportUtils.importString( map, "rank_divisor_key" );
+	}
+	
+	public Map 
+	exportToBencodedMap()
+	
+		throws IOException
+	{
+		return( exportToBencodedMap( false ));
 	}
 	
 	public Map 
-	exportToBencodedMap() 
+	exportToBencodedMap(
+		boolean		generic )
 	
 		throws IOException
 	{
@@ -158,7 +181,9 @@ JSONEngine
 		
 		ImportExportUtils.exportString( res, "json.path", resultsEntryPath );
 		
-		super.exportToBencodedMap( res );
+		ImportExportUtils.exportString(res, "rank.divisor.path", rankDivisorPath);
+		
+		super.exportToBencodedMap( res, generic );
 		
 		return( res );
 	}
@@ -170,6 +195,8 @@ JSONEngine
 		throws IOException
 	{
 		res.put( "json_result_key", resultsEntryPath );
+		
+		res.put("rank_divisor_key", rankDivisorPath);
 
 		super.exportToJSONObject( res );
 	}
@@ -207,8 +234,45 @@ JSONEngine
 		FieldMapping[] mappings = getMappings();
 
 		try {
-			Object jsonObject = JSONValue.parse(page);
+			Object jsonObject;
+			
+			try{
+				jsonObject = JSONValue.parse(page);
+				
+			}catch( Throwable e ){
+				
+					// fix a vaguely common error: trailing \ before end-of-string:    - \",  
+				
+				String temp_page = page.replaceAll( "\\\\\",", "\"," );
+				
+				try{
+					jsonObject = JSONValue.parse( temp_page );
+					
+				}catch( Throwable f ){
+					
+					throw( e );
+				}
+			}
 			
+			if (rankDivisorPath != null) {
+				String[] split = rankDivisorPath.split("\\.");
+				try {
+					if (split.length > 0) {
+						Object jsonRankDivisor = jsonObject;
+  					for (int i = 0; i < split.length - 1; i++) {
+  						String key = split[i];
+  						jsonRankDivisor = ((JSONObject)jsonRankDivisor).get(key);
+  					}
+  					if (jsonRankDivisor instanceof Map) {
+  						jsonRankDivisor = ((Map) jsonRankDivisor).get(split[split.length - 1]);
+  					}
+  					
+  					rankDivisor = ((Number) jsonRankDivisor).floatValue();
+					}
+				} catch (Exception e) {
+				}
+			}
+
 			JSONArray resultArray = null;
 			
 			if(resultsEntryPath != null) {
@@ -235,7 +299,7 @@ JSONEngine
 				
 				throw new SearchException("Object is not a result array. Check the JSON service and/or the entry path");
 			}
-				
+
 				
 			if ( resultArray != null ){
 				
@@ -290,9 +354,26 @@ JSONEngine
 							String fieldFrom = mappings[j].getName();
 							if(fieldFrom != null) {
 								int fieldTo = mappings[j].getField();
-								Object fieldContentObj = ((Object)jsonEntry.get(fieldFrom));
-								if(fieldContentObj != null) {
-									String fieldContent = fieldContentObj.toString();
+								
+								String fieldContent = null;
+								Matcher matcher = patternVariable.matcher(fieldFrom);
+								if (matcher.find()) {
+									fieldContent = fieldFrom;
+									do {
+										String key = matcher.group();
+										key = key.substring(2, key.length() - 1);
+										Object replaceValObject = jsonEntry.get(key);
+										String replaceVal = replaceValObject == null ? ""
+												: replaceValObject.toString();
+										fieldContent = fieldContent.replaceFirst(variablePattern,
+												replaceVal);
+									} while (matcher.find());
+								} else {
+									Object fieldContentObj = jsonEntry.get(fieldFrom);
+									fieldContent = fieldContentObj == null ? ""
+											: fieldContentObj.toString();
+								}
+								if(fieldContent != null) {
 									
 									switch(fieldTo) {
 									case FIELD_NAME :
@@ -346,6 +427,10 @@ JSONEngine
 									case FIELD_HASH :
 										result.setHash(fieldContent);
 										break;
+									case FIELD_RANK : {
+										result.setRankFromHTML(fieldContent, rankDivisor);
+										break;
+									}
 									default:
 										break;
 									}
@@ -379,18 +464,17 @@ JSONEngine
 				throw((SearchException)e );
 			}
 			
-			throw( new SearchException( "JSON matching failed", e ));
-		}
-	}
-	
-	public String getIcon() {
-		
-		String rootPage = getRootPage();
-		
-		if(rootPage != null) {
-			return rootPage + "/favicon.ico";
+			String content_str = page;
+			
+			if ( content_str.length() > 256 ){
+				
+				content_str = content_str.substring( 0, 256 ) + "...";
+			}
+			
+			//System.out.println( page );
+			
+			throw( new SearchException( "JSON matching failed for " + getName() + ", content=" + content_str, e ));
 		}
-		return null;
 	}
 	
 
diff --git a/com/aelitis/azureus/core/metasearch/impl/web/regex/RegexEngine.java b/com/aelitis/azureus/core/metasearch/impl/web/regex/RegexEngine.java
index f46fb62..39deed9 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/regex/RegexEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/regex/RegexEngine.java
@@ -63,16 +63,17 @@ RegexEngine
 		MetaSearchImpl		meta_search,
 		long				id,
 		long				last_updated,
+		float				rank_bias,
 		String				name,
 		JSONObject			map )
 	
 		throws IOException
 	{
-		return( new RegexEngine( meta_search, id, last_updated, name, map ));
+		return( new RegexEngine( meta_search, id, last_updated, rank_bias, name, map ));
 	}
 
-	private String	pattern_str;
-	private Pattern pattern;
+	private String		pattern_str;
+	private Pattern[] 	patterns = {};
 
 	
 		// explicit test constructor
@@ -82,6 +83,7 @@ RegexEngine
 		MetaSearchImpl		meta_search,
 		long 				id,
 		long 				last_updated,
+		float				rank_bias,
 		String 				name,
 		String 				searchURLFormat,
 		String 				resultPattern,
@@ -98,6 +100,7 @@ RegexEngine
 				Engine.ENGINE_TYPE_REGEX, 
 				id,
 				last_updated,
+				rank_bias,
 				name,
 				searchURLFormat,
 				timeZone,
@@ -139,12 +142,13 @@ RegexEngine
 		MetaSearchImpl		meta_search,
 		long				id,
 		long				last_updated,
+		float				rank_bias,
 		String				name,
 		JSONObject			map )
 	
 		throws IOException
 	{
-		super( meta_search, Engine.ENGINE_TYPE_REGEX, id, last_updated, name, map );
+		super( meta_search, Engine.ENGINE_TYPE_REGEX, id, last_updated, rank_bias, name, map );
 		
 		String	resultPattern = ImportExportUtils.importString( map, "regexp" );
 
@@ -154,7 +158,16 @@ RegexEngine
 	}
 	
 	public Map 
-	exportToBencodedMap() 
+	exportToBencodedMap()
+	
+		throws IOException
+	{
+		return( exportToBencodedMap( false ));
+	}
+	
+	public Map 
+	exportToBencodedMap(
+		boolean		generic ) 
 	
 		throws IOException
 	{
@@ -162,7 +175,7 @@ RegexEngine
 		
 		ImportExportUtils.exportString( res, "regex.pattern", pattern_str );
 		
-		super.exportToBencodedMap( res );
+		super.exportToBencodedMap( res, generic );
 		
 		return( res );
 	}
@@ -183,7 +196,11 @@ RegexEngine
 		String			resultPattern )
 	{
 		pattern_str 	= resultPattern.trim();
-		pattern			= Pattern.compile(pattern_str);
+		patterns = new Pattern[]{
+				
+			Pattern.compile( pattern_str),
+			Pattern.compile( pattern_str, Pattern.DOTALL | Pattern.MULTILINE )
+		};
 	}
 	
 	protected Result[] 
@@ -281,118 +298,131 @@ RegexEngine
 						try{						
 							List results = new ArrayList();
 								
-							Matcher m = pattern.matcher( page );
+							for ( int pat_num=0;pat_num<patterns.length;pat_num++){
 								
-							while( m.find()){
-								
-								if ( max_matches >= 0 ){
-									if ( --max_matches < 0 ){
-										break;
-									}
-								}
+									// only try subsequent patterns if all previous have failed to 
+									// find results
 								
-								if ( listener != null ){
-									
-									String[]	groups = new String[m.groupCount()];
-									
-									for (int i=0;i<groups.length;i++){
-										
-										groups[i] = m.group(i+1);
-									}
+								if ( results.size() > 0 ){
 									
-									listener.matchFound( RegexEngine.this, groups );
+									break;
 								}
 								
-								debugLog( "Found match:" );
+								Pattern pattern = patterns[pat_num];
 								
-								WebResult result = new WebResult(RegexEngine.this,getRootPage(),getBasePage(),getDateParser(),searchQuery);
-								
-								int	fields_matched = 0;
-								
-								for(int i = 0 ; i < mappings.length ; i++) {
-									int group = -1;
-									try {
-										group = Integer.parseInt(mappings[i].getName());
-									} catch(Exception e) {
-										//In "Debug/Test" mode, we should fire an exception / notification
+								Matcher m = pattern.matcher( page );
+									
+								while( m.find()){
+									
+									if ( max_matches >= 0 ){
+										if ( --max_matches < 0 ){
+											break;
+										}
 									}
 									
-									if (group > 0 && group <= m.groupCount()) {
+									if ( listener != null ){
 										
-										int field = mappings[i].getField();
-										String groupContent = m.group(group);
+										String[]	groups = new String[m.groupCount()];
 										
-										debugLog( "    " + field + "=" + groupContent );
+										for (int i=0;i<groups.length;i++){
+											
+											groups[i] = m.group(i+1);
+										}
 										
-										fields_matched++;
+										listener.matchFound( RegexEngine.this, groups );
+									}
+									
+									debugLog( "Found match:" );
+									
+									WebResult result = new WebResult(RegexEngine.this,getRootPage(),getBasePage(),getDateParser(),searchQuery);
+									
+									int	fields_matched = 0;
+									
+									for(int i = 0 ; i < mappings.length ; i++) {
+										int group = -1;
+										try {
+											group = Integer.parseInt(mappings[i].getName());
+										} catch(Exception e) {
+											//In "Debug/Test" mode, we should fire an exception / notification
+										}
 										
-										switch(field) {
-											case FIELD_NAME :
-												result.setNameFromHTML(groupContent);
-												break;
-											case FIELD_SIZE :
-												result.setSizeFromHTML(groupContent);
-												break;
-											case FIELD_PEERS :
-												result.setNbPeersFromHTML(groupContent);
-												break;
-											case FIELD_SEEDS :
-												result.setNbSeedsFromHTML(groupContent);
-												break;
-											case FIELD_CATEGORY :
-												result.setCategoryFromHTML(groupContent);
-												break;
-											case FIELD_DATE :
-												result.setPublishedDateFromHTML(groupContent);
-												break;
-											case FIELD_CDPLINK :
-												result.setCDPLink(groupContent);
-												break;
-											case FIELD_TORRENTLINK :
-												result.setTorrentLink(groupContent);
-												break;
-											case FIELD_PLAYLINK :
-												result.setPlayLink(groupContent);
-												break;
-											case FIELD_DOWNLOADBTNLINK :
-												result.setDownloadButtonLink(groupContent);
-												break;
-											case FIELD_COMMENTS :
-												result.setCommentsFromHTML(groupContent);
-												break;
-											case FIELD_VOTES :
-												result.setVotesFromHTML(groupContent);
-												break;
-											case FIELD_SUPERSEEDS :
-												result.setNbSuperSeedsFromHTML(groupContent);
-												break;
-											case FIELD_PRIVATE :
-												result.setPrivateFromHTML(groupContent);
-												break;
-											case FIELD_DRMKEY :
-												result.setDrmKey(groupContent);
-												break;
-											case FIELD_VOTES_DOWN :
-												result.setVotesDownFromHTML(groupContent);
-												break;
-											case FIELD_HASH :
-												result.setHash(groupContent);
-												break;
-											default:
-												fields_matched--;
-												break;
+										if (group > 0 && group <= m.groupCount()) {
+											
+											int field = mappings[i].getField();
+											String groupContent = m.group(group);
+											
+											debugLog( "    " + field + "=" + groupContent );
+											
+											fields_matched++;
+											
+											switch(field) {
+												case FIELD_NAME :
+													result.setNameFromHTML(groupContent);
+													break;
+												case FIELD_SIZE :
+													result.setSizeFromHTML(groupContent);
+													break;
+												case FIELD_PEERS :
+													result.setNbPeersFromHTML(groupContent);
+													break;
+												case FIELD_SEEDS :
+													result.setNbSeedsFromHTML(groupContent);
+													break;
+												case FIELD_CATEGORY :
+													result.setCategoryFromHTML(groupContent);
+													break;
+												case FIELD_DATE :
+													result.setPublishedDateFromHTML(groupContent);
+													break;
+												case FIELD_CDPLINK :
+													result.setCDPLink(groupContent);
+													break;
+												case FIELD_TORRENTLINK :
+													result.setTorrentLink(groupContent);
+													break;
+												case FIELD_PLAYLINK :
+													result.setPlayLink(groupContent);
+													break;
+												case FIELD_DOWNLOADBTNLINK :
+													result.setDownloadButtonLink(groupContent);
+													break;
+												case FIELD_COMMENTS :
+													result.setCommentsFromHTML(groupContent);
+													break;
+												case FIELD_VOTES :
+													result.setVotesFromHTML(groupContent);
+													break;
+												case FIELD_SUPERSEEDS :
+													result.setNbSuperSeedsFromHTML(groupContent);
+													break;
+												case FIELD_PRIVATE :
+													result.setPrivateFromHTML(groupContent);
+													break;
+												case FIELD_DRMKEY :
+													result.setDrmKey(groupContent);
+													break;
+												case FIELD_VOTES_DOWN :
+													result.setVotesDownFromHTML(groupContent);
+													break;
+												case FIELD_HASH :
+													result.setHash(groupContent);
+													break;
+												default:
+													fields_matched--;
+													break;
+											}
 										}
 									}
-								}
-								
-									// ignore "matches" that don't actually populate any fields 
-								
-								if ( fields_matched > 0 ){
-								
-									results.add(result);
+									
+										// ignore "matches" that don't actually populate any fields 
+									
+									if ( fields_matched > 0 ){
+									
+										results.add(result);
+									}
 								}
 							}
-								
+							
 								// hack - if no results and redirected to https and auth required then
 								// assume we need to log in...
 							
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 07a0e1f..8ab36a1 100644
--- a/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java
+++ b/com/aelitis/azureus/core/metasearch/impl/web/rss/RSSEngine.java
@@ -13,6 +13,7 @@ import java.util.regex.Pattern;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.plugins.utils.xml.rss.RSSChannel;
 import org.gudy.azureus2.plugins.utils.xml.rss.RSSFeed;
@@ -53,12 +54,13 @@ RSSEngine
 		MetaSearchImpl		meta_search,
 		long				id,
 		long				last_updated,
+		float				rank_bias,
 		String				name,
 		JSONObject			map )
 	
 		throws IOException
 	{
-		return( new RSSEngine( meta_search, id, last_updated, name, map ));
+		return( new RSSEngine( meta_search, id, last_updated, rank_bias, name, map ));
 	}
 	
 		// explicit constructor
@@ -68,6 +70,7 @@ RSSEngine
 		MetaSearchImpl		meta_search,
 		long 				id,
 		long 				last_updated,
+		float				rank_bias,
 		String 				name,
 		String 				searchURLFormat,
 		boolean				needs_auth,
@@ -79,6 +82,7 @@ RSSEngine
 				Engine.ENGINE_TYPE_RSS, 
 				id,
 				last_updated,
+				rank_bias,
 				name,
 				searchURLFormat,
 				"GMT",
@@ -108,23 +112,33 @@ RSSEngine
 		MetaSearchImpl		meta_search,
 		long				id,
 		long				last_updated,
+		float				rank_bias,
 		String				name,
 		JSONObject			map )
 	
 		throws IOException
 	{
-		super( meta_search, Engine.ENGINE_TYPE_REGEX, id, last_updated, name, map );
+		super( meta_search, Engine.ENGINE_TYPE_REGEX, id, last_updated, rank_bias, name, map );
 	}
 	
 	
 	public Map 
-	exportToBencodedMap() 
+	exportToBencodedMap()
+	
+		throws IOException
+	{
+		return( exportToBencodedMap( false ));
+	}
+	
+	public Map 
+	exportToBencodedMap(
+		boolean	generic )
 	
 		throws IOException
 	{
 		Map	res = new HashMap();
 				
-		super.exportToBencodedMap( res );
+		super.exportToBencodedMap( res, generic );
 		
 		return( res );
 	}
@@ -260,7 +274,7 @@ RSSEngine
 						boolean vuze_feed = false;
 						
 						for ( int k=0; k<children.length; k++ ){
-							
+														
 							SimpleXMLParserDocumentNode child = children[k];
 							
 							String	lc_full_child_name 	= child.getFullName().toLowerCase();
@@ -303,8 +317,8 @@ RSSEngine
 									}
 								}
 							}else if(lc_child_name.equals( "category" )) {
-								
-								result.setCategory( value );
+																
+								result.setCategoryFromHTML( value );
 								
 							}else if(lc_child_name.equals( "comments" )){
 								
@@ -319,6 +333,8 @@ RSSEngine
 
 									if ( 	lc_value.endsWith( ".torrent" ) ||
 											lc_value.startsWith( "magnet:" ) ||
+											lc_value.startsWith( "bc:" ) ||
+											lc_value.startsWith( "bctp:" ) ||
 											lc_value.startsWith( "dht:" )){
 										
 										
@@ -347,6 +363,29 @@ RSSEngine
 										}
 									}
 								}catch( Throwable e ){
+									
+										// see if this is an atom feed 
+										//  <link rel="alternate" type="application/x-bittorrent" href="http://asdasd/ 
+									
+									SimpleXMLParserDocumentAttribute typeAtt = child.getAttribute( "type" );
+									
+									if ( typeAtt != null && typeAtt.getValue().equalsIgnoreCase("application/x-bittorrent")) {
+									
+										SimpleXMLParserDocumentAttribute hrefAtt = child.getAttribute( "href" );
+										
+										if ( hrefAtt != null ){
+											
+											String	href = hrefAtt.getValue().trim();
+											
+											try{
+												
+												result.setTorrentLink( new URL( href ).toExternalForm() );
+												
+											}catch( Throwable f ){
+												
+											}
+										}
+									}
 								}
 							}else if ( lc_child_name.equals( "content" ) && rssFeed.isAtomFeed()){
 								
@@ -480,6 +519,137 @@ RSSEngine
 						}
 					}
 					
+						// override existing values with explicit <torrent> entry if present
+					
+					try{
+						SimpleXMLParserDocumentNode torrent_node = node.getChild( "torrent" );
+						
+						if ( torrent_node != null ){
+						
+							if ( result.getSize() <= 0 ){
+								
+								SimpleXMLParserDocumentNode n = torrent_node.getChild( "contentLength" );
+								
+								if ( n != null ){
+									
+									try{
+										long l = Long.parseLong( n.getValue().trim());
+										
+										result.setSizeFromHTML( l + " B" );
+										
+									}catch( Throwable e ){
+										
+									}
+								}
+							}
+							
+							String dlink = result.getDownloadLink();
+							
+							if ( dlink == null || dlink.length() == 0 ){
+								
+								SimpleXMLParserDocumentNode n = torrent_node.getChild( "magnetURI" );
+								
+								if ( n != null ){
+									
+									dlink = n.getValue().trim();
+									
+									result.setTorrentLink( dlink );
+								}
+							}
+							
+							String hash = result.getHash();
+							
+							if ( hash == null || hash.length() == 0 ){
+								
+								SimpleXMLParserDocumentNode n = torrent_node.getChild( "infoHash" );
+								
+								if ( n != null ){
+									
+									String h = n.getValue().trim();
+									
+									result.setHash( h );
+									
+									if ( dlink == null || dlink.length() == 0 ){
+										
+										String uri = UrlUtils.normaliseMagnetURI( h );
+										
+										if ( uri != null ){
+											
+											result.setTorrentLink( uri );
+										}
+									}
+								}
+							}
+							
+							SimpleXMLParserDocumentNode trackers_node = torrent_node.getChild( "trackers" );
+
+							if ( trackers_node != null && !got_seeds_peers ){
+								
+								SimpleXMLParserDocumentNode[] groups = trackers_node.getChildren();
+								
+								int	max_total = -1;
+								
+								int	best_seeds		= 0;
+								int	best_leechers	= 0;
+								
+								for ( SimpleXMLParserDocumentNode group: groups ){
+									
+									SimpleXMLParserDocumentNode[] g_kids = group.getChildren();
+									
+									for ( SimpleXMLParserDocumentNode t: g_kids ){
+										
+										if ( t.getName().equalsIgnoreCase( "tracker" )){
+											
+											SimpleXMLParserDocumentAttribute a_seeds 	= t.getAttribute( "seeds" );
+											SimpleXMLParserDocumentAttribute a_leechers = t.getAttribute( "peers" );
+											
+											int	seeds 		= a_seeds==null?-1:Integer.parseInt( a_seeds.getValue().trim());
+											int	leechers 	= a_leechers==null?-1:Integer.parseInt( a_leechers.getValue().trim());
+											
+											int	total = seeds + leechers;
+											
+											if ( total > max_total ){
+											
+												max_total = total;
+												
+												best_seeds 		= seeds;
+												best_leechers	= leechers;
+											}
+										}									
+									}
+								}
+								
+								if ( max_total >= 0 ){
+									
+									result.setNbSeedsFromHTML( String.valueOf( Math.max( 0, best_seeds )));
+									result.setNbPeersFromHTML( String.valueOf( Math.max( 0, best_leechers )));
+								}
+							}
+						}
+					}catch( Throwable e ){
+						
+						e.printStackTrace();
+					}
+					
+						// if we still have no download link see if the magnet is in the title
+					
+					String dlink = result.getDownloadLink();
+					
+					if ( dlink == null || dlink.length() == 0 ){
+						
+						String name = result.getName();
+						
+						if ( name != null ){
+							
+							String magnet = UrlUtils.parseTextForMagnets( name );
+							
+							if ( magnet != null ){
+								
+								result.setTorrentLink( magnet );
+							}
+						}
+					}
+
 					results.add(result);
 					
 					if ( absolute_max_matches >= 0 && results.size() == absolute_max_matches ){
diff --git a/com/aelitis/azureus/core/nat/NATTraverser.java b/com/aelitis/azureus/core/nat/NATTraverser.java
index b53ca4e..0550a87 100644
--- a/com/aelitis/azureus/core/nat/NATTraverser.java
+++ b/com/aelitis/azureus/core/nat/NATTraverser.java
@@ -30,6 +30,8 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.ThreadPool;
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.dht.DHT;
@@ -147,6 +149,13 @@ NATTraverser
 				
 				if ( puncher == null ){
 			
+					if ( !PluginCoreUtils.isInitialisationComplete()){
+						
+						listener.failed( new Exception( "NAT traversal failed, initialisation not complete" ));
+						
+						return;
+					}
+
 					PluginInterface dht_pi = 
 						core.getPluginManager().getPluginInterfaceByClass( DHTPlugin.class );
 					
diff --git a/com/aelitis/azureus/core/networkmanager/ConnectionEndpoint.java b/com/aelitis/azureus/core/networkmanager/ConnectionEndpoint.java
index 27f8d78..d193bef 100644
--- a/com/aelitis/azureus/core/networkmanager/ConnectionEndpoint.java
+++ b/com/aelitis/azureus/core/networkmanager/ConnectionEndpoint.java
@@ -145,26 +145,9 @@ ConnectionEndpoint
 
 			ProtocolEndpoint ep = protocols[i];
 			
-			if ( ep.getType() == ProtocolEndpoint.PROTOCOL_TCP ){
-				
-				ProtocolEndpointTCP	tcp = (ProtocolEndpointTCP)ep;
-			
-				InetSocketAddress address = AddressUtils.adjustTCPAddress( tcp.getAddress(), true );
-								
-				new ProtocolEndpointTCP( result, address );
-				
-			}else if ( ep.getType() == ProtocolEndpoint.PROTOCOL_UDP ){
-				
-				ProtocolEndpointUDP	udp = (ProtocolEndpointUDP)ep;
+			InetSocketAddress address = ep.getAdjustedAddress( true );
 			
-				InetSocketAddress address = AddressUtils.adjustUDPAddress( udp.getAddress(), true );
-								
-				new ProtocolEndpointUDP( result, address );
-				
-			}else{
-				
-				result.addProtocol( ep );
-			}
+			ProtocolEndpointFactory.createEndpoint( ep.getType(), result, address );
 		}
 		
 		return( result );
diff --git a/com/aelitis/azureus/core/networkmanager/IncomingMessageQueue.java b/com/aelitis/azureus/core/networkmanager/IncomingMessageQueue.java
index 12b488e..15ef9ed 100644
--- a/com/aelitis/azureus/core/networkmanager/IncomingMessageQueue.java
+++ b/com/aelitis/azureus/core/networkmanager/IncomingMessageQueue.java
@@ -124,6 +124,8 @@ public interface IncomingMessageQueue {
      */
     public void dataBytesReceived( int byte_count );
     
+    public boolean
+    isPriority();
   }
   
   
diff --git a/com/aelitis/azureus/core/networkmanager/NetworkConnection.java b/com/aelitis/azureus/core/networkmanager/NetworkConnection.java
index 2629825..7eba113 100644
--- a/com/aelitis/azureus/core/networkmanager/NetworkConnection.java
+++ b/com/aelitis/azureus/core/networkmanager/NetworkConnection.java
@@ -46,7 +46,7 @@ NetworkConnection
   /**
    * Close and shutdown this connection.
    */
-  public void close();
+  public void close( String reason );
   
   
   /**
@@ -79,6 +79,14 @@ NetworkConnection
 
   public boolean isConnected();
     
+  public Object
+  setUserData(
+  	Object		key,
+  	Object		value );
+  
+  public Object
+  getUserData(
+  	Object		key );
   
   /**
    * Listener for notification of connection events.
@@ -87,8 +95,9 @@ NetworkConnection
     /**
      * The connection establishment process has started,
      * i.e. the connection is actively being attempted.
+     * @return modified connect timeout
      */
-    public void connectStarted();    
+    public int connectStarted( int default_connect_timeout );    
     
     /**
      * The connection attempt succeeded.
diff --git a/com/aelitis/azureus/core/networkmanager/NetworkManager.java b/com/aelitis/azureus/core/networkmanager/NetworkManager.java
index ef146d6..cefc249 100644
--- a/com/aelitis/azureus/core/networkmanager/NetworkManager.java
+++ b/com/aelitis/azureus/core/networkmanager/NetworkManager.java
@@ -538,6 +538,12 @@ public class NetworkManager {
   	}
   }
   
+  public TransferProcessor
+  getUploadProcessor()
+  {
+	  return( upload_processor );
+  }
+  
   public void
   addRateLimiter(
 	NetworkConnectionBase 	peer_connection,
@@ -588,6 +594,56 @@ public class NetworkManager {
 	  }
   }
   
+  public RateHandler
+  getRateHandler(
+	boolean					upload,
+	boolean					lan )
+  {
+	  if ( upload ){
+		  
+		  if ( lan ){
+			  
+		  		return( lan_upload_processor.getRateHandler());
+	
+		  }else{
+		  		return( upload_processor.getRateHandler());
+		  } 
+	  }else{
+		  if ( lan ){
+			  
+			  	return( lan_download_processor.getRateHandler());
+	
+		  }else{
+		  		return( download_processor.getRateHandler());
+		  } 
+	  }
+  }
+  
+  public RateHandler
+  getRateHandler(
+	NetworkConnectionBase 	peer_connection,
+	boolean					upload )
+  {
+	  if ( upload ){
+		  
+		  if ( lan_upload_processor.isRegistered( peer_connection )){
+			  
+		  		return( lan_upload_processor.getRateHandler( peer_connection ));
+	
+		  }else{
+		  		return( upload_processor.getRateHandler( peer_connection ));
+		  } 
+	  }else{
+		  if ( lan_download_processor.isRegistered( peer_connection )){
+			  
+			  	return( lan_download_processor.getRateHandler( peer_connection ));
+	
+		  }else{
+		  		return( download_processor.getRateHandler( peer_connection ));
+		  } 
+	  }
+  }
+  
   public NetworkManagerStats
   getStats()
   {
diff --git a/com/aelitis/azureus/core/networkmanager/OutgoingMessageQueue.java b/com/aelitis/azureus/core/networkmanager/OutgoingMessageQueue.java
index 9036b38..a42fb27 100644
--- a/com/aelitis/azureus/core/networkmanager/OutgoingMessageQueue.java
+++ b/com/aelitis/azureus/core/networkmanager/OutgoingMessageQueue.java
@@ -77,6 +77,15 @@ OutgoingMessageQueue
    */
   public int getTotalSize();
   
+  public int getDataQueuedBytes();
+  
+  public int getProtocolQueuedBytes();
+  
+  public boolean isBlocked();
+  
+  public boolean getPriorityBoost();
+	
+  public void setPriorityBoost( boolean	boost );
   
   /**
    * Whether or not an urgent message (one that needs an immediate send, i.e. a no-delay message) is queued.
diff --git a/com/aelitis/azureus/core/networkmanager/ProtocolEndpoint.java b/com/aelitis/azureus/core/networkmanager/ProtocolEndpoint.java
index 158be31..ef83c99 100644
--- a/com/aelitis/azureus/core/networkmanager/ProtocolEndpoint.java
+++ b/com/aelitis/azureus/core/networkmanager/ProtocolEndpoint.java
@@ -22,6 +22,7 @@
 
 package com.aelitis.azureus.core.networkmanager;
 
+import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 
 import com.aelitis.azureus.core.networkmanager.Transport.ConnectListener;
@@ -31,6 +32,7 @@ ProtocolEndpoint
 {
 	public static final int	PROTOCOL_TCP	= 1;
 	public static final int	PROTOCOL_UDP	= 2;
+	public static final int	PROTOCOL_UTP	= 3;
 
 	public static final int CONNECT_PRIORITY_SUPER_HIGHEST	= 0;
 	public static final int CONNECT_PRIORITY_HIGHEST		= 1;
@@ -49,6 +51,13 @@ ProtocolEndpoint
 	setConnectionEndpoint(
 		ConnectionEndpoint	ce );
 	
+	public InetSocketAddress
+	getAddress();
+	
+	public InetSocketAddress
+	getAdjustedAddress(
+		boolean		to_lan );
+	
 	public Transport
 	connectOutbound(
 		boolean				connect_with_crypto, 
diff --git a/com/aelitis/azureus/core/networkmanager/ProtocolEndpointFactory.java b/com/aelitis/azureus/core/networkmanager/ProtocolEndpointFactory.java
new file mode 100644
index 0000000..366eb0a
--- /dev/null
+++ b/com/aelitis/azureus/core/networkmanager/ProtocolEndpointFactory.java
@@ -0,0 +1,121 @@
+/*
+ * Created on Oct 14, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.networkmanager;
+
+import java.net.InetSocketAddress;
+import java.util.*;
+
+import com.aelitis.azureus.core.networkmanager.impl.tcp.ProtocolEndpointTCP;
+import com.aelitis.azureus.core.networkmanager.impl.udp.ProtocolEndpointUDP;
+
+public class 
+ProtocolEndpointFactory 
+{
+	private static ProtocolEndpointHandler tcp_handler = null;
+	private static ProtocolEndpointHandler udp_handler = null;
+	
+	private static Map<Integer,ProtocolEndpointHandler>	other_handlers = new HashMap<Integer, ProtocolEndpointHandler>();
+	
+	static{
+		ProtocolEndpointTCP.register();
+		ProtocolEndpointUDP.register();
+	}
+	
+	public static void
+	registerHandler(
+		ProtocolEndpointHandler		handler )
+	{
+		int	type = handler.getType();
+		
+		if ( type == ProtocolEndpoint.PROTOCOL_TCP ){
+			
+			tcp_handler = handler;
+			
+		}else if ( type == ProtocolEndpoint.PROTOCOL_UDP ){
+			
+			udp_handler = handler;
+			
+		}else{
+			
+			other_handlers.put( type, handler );
+		}
+	}
+	
+	public static boolean
+	isHandlerRegistered(
+		int		type )
+	{
+		if ( type == ProtocolEndpoint.PROTOCOL_TCP || type == ProtocolEndpoint.PROTOCOL_UDP ){
+			
+			return( true );
+			
+		}else{
+			
+			return( other_handlers.containsKey( type ));
+		}
+	}
+	
+	public static ProtocolEndpoint
+	createEndpoint(
+		int						type,
+		InetSocketAddress		target )
+	{
+		switch( type ){
+			case ProtocolEndpoint.PROTOCOL_TCP:{
+				return( tcp_handler.create( target ));
+			}
+			case ProtocolEndpoint.PROTOCOL_UDP:{
+				return( udp_handler.create( target ));
+			}
+			default:{
+				ProtocolEndpointHandler handler = other_handlers.get( type );
+				if ( handler != null ){
+					return( handler.create( target ));
+				}
+				return( null );
+			}
+		}
+	}
+	
+	public static ProtocolEndpoint
+	createEndpoint(
+		int						type,
+		ConnectionEndpoint		connection_endpoint,
+		InetSocketAddress		target )
+	{
+		switch( type ){
+			case ProtocolEndpoint.PROTOCOL_TCP:{
+				return( tcp_handler.create( connection_endpoint, target ));
+			}
+			case ProtocolEndpoint.PROTOCOL_UDP:{
+				return( udp_handler.create( connection_endpoint, target ));
+			}
+			default:{
+				ProtocolEndpointHandler handler = other_handlers.get( type );
+				if ( handler != null ){
+					return( handler.create( connection_endpoint, target ));
+				}
+				return( null );
+			}
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/networkmanager/ProtocolEndpointHandler.java b/com/aelitis/azureus/core/networkmanager/ProtocolEndpointHandler.java
new file mode 100644
index 0000000..d82cac9
--- /dev/null
+++ b/com/aelitis/azureus/core/networkmanager/ProtocolEndpointHandler.java
@@ -0,0 +1,40 @@
+/*
+ * Created on Oct 14, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.networkmanager;
+
+import java.net.InetSocketAddress;
+
+public interface 
+ProtocolEndpointHandler 
+{
+	public int
+	getType();
+	
+	public ProtocolEndpoint
+	create(
+		InetSocketAddress		address );
+	
+	public ProtocolEndpoint
+	create(
+		ConnectionEndpoint		connection_endpoint,
+		InetSocketAddress		address );
+}
diff --git a/com/aelitis/azureus/core/networkmanager/RateHandler.java b/com/aelitis/azureus/core/networkmanager/RateHandler.java
new file mode 100644
index 0000000..f7cf815
--- /dev/null
+++ b/com/aelitis/azureus/core/networkmanager/RateHandler.java
@@ -0,0 +1,40 @@
+/*
+ * Created on Oct 6, 2004
+ * Created by Alon Rohter
+ * 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.networkmanager;
+
+/**
+ * Handler to allow external control of an entity's byte processing rate.
+ */
+public interface RateHandler {
+  /**
+   * Get the current number of bytes allowed to be processed by the entity.
+   * @return number of bytes allowed
+   */
+  public int getCurrentNumBytesAllowed();
+    
+  /**
+   * Notification of any bytes processed by the entity.
+   * @param num_bytes_processed 
+   */
+  public void bytesProcessed( int num_bytes_processed );
+}
diff --git a/com/aelitis/azureus/core/networkmanager/Transport.java b/com/aelitis/azureus/core/networkmanager/Transport.java
index ad62731..ccf9545 100644
--- a/com/aelitis/azureus/core/networkmanager/Transport.java
+++ b/com/aelitis/azureus/core/networkmanager/Transport.java
@@ -60,7 +60,9 @@ Transport
    * @return
    */
   public String getEncryption( boolean verbose );
-      
+     
+  public String getProtocol();
+  
   /**
    * fake a wakeup so that a read cycle is attempted
    */
@@ -128,6 +130,14 @@ Transport
   public void close( String reason );
   
   public void
+  bindConnection(
+		NetworkConnection	connection );
+  
+  public void
+  unbindConnection(
+		NetworkConnection	connection );
+  
+  public void
   setTrace(
 		boolean	on );
   
@@ -138,8 +148,9 @@ Transport
     /**
      * The connection establishment process has started,
      * i.e. the connection is actively being attempted.
+     * @return modified timeout
      */
-    public void connectAttemptStarted();   
+    public int connectAttemptStarted( int default_connect_timeout );   
      
     /**
      * The connection attempt succeeded.
diff --git a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
index 0a9b162..5ac2df2 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdmin.java
@@ -114,12 +114,18 @@ NetworkAdmin
 	
 	public abstract NetworkAdminProtocol[]
 	getOutboundProtocols(
-			AzureusCore azureus_core);
+		AzureusCore azureus_core);
 	
 	public abstract NetworkAdminProtocol[]
 	getInboundProtocols(
-			AzureusCore azureus_core );
+		AzureusCore azureus_core );
 	
+	public abstract NetworkAdminProtocol
+	createInboundProtocol(
+		AzureusCore 	azureus_core,
+		int				type,
+		int				port );
+		
 	public abstract InetAddress
 	testProtocol(
 		NetworkAdminProtocol	protocol )
diff --git a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdminProtocol.java b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdminProtocol.java
index 5e38873..b8781d0 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/NetworkAdminProtocol.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/NetworkAdminProtocol.java
@@ -54,6 +54,14 @@ NetworkAdminProtocol
 	
 		throws NetworkAdminException;
 	
+	public InetAddress
+	test(
+		NetworkAdminNetworkInterfaceAddress	address,
+		boolean								upnp_map,
+		NetworkAdminProgressListener		listener )
+	
+		throws NetworkAdminException;
+	
 	public String
 	getName();
 }
diff --git a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminHTTPProxyImpl.java b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminHTTPProxyImpl.java
index 9e939be..f526b17 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminHTTPProxyImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminHTTPProxyImpl.java
@@ -36,6 +36,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
 
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.VirtualChannelSelector;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminException;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminHTTPProxy;
@@ -201,9 +202,11 @@ NetworkAdminHTTPProxyImpl
 			TCPConnectionManager.ConnectListener connect_listener = 
 				new TCPConnectionManager.ConnectListener() 
 				{
-					public void 
-					connectAttemptStarted() 
+					public int 
+					connectAttemptStarted(
+						int	default_connect_timeout )
 					{	
+						return( default_connect_timeout );
 					}
 		
 					public void 
@@ -212,7 +215,7 @@ NetworkAdminHTTPProxyImpl
 					{
 						final TCPTransportImpl	transport = 
 							new TCPTransportImpl(
-									new ProtocolEndpointTCP( target_address ), false, false, null );
+									(ProtocolEndpointTCP)ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, target_address ), false, false, null );
 						
 						transport.setFilter( TCPTransportHelperFilterFactory.createTransparentFilter( channel ));
 		
diff --git a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
index dede097..76fbd4c 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminImpl.java
@@ -60,6 +60,7 @@ import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
 import com.aelitis.azureus.core.proxy.socks.AESocksProxy;
 import com.aelitis.azureus.core.proxy.socks.AESocksProxyFactory;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.core.util.NetUtils;
 import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
 import com.aelitis.azureus.plugins.upnp.UPnPPluginService;
 
@@ -240,13 +241,13 @@ NetworkAdminImpl
 		boolean		force )
 	{
 		try{
-			Enumeration 	nis = NetworkInterface.getNetworkInterfaces();
-		
+			List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
+			
 			boolean	changed	= false;
 
-			if ( nis == null && old_network_interfaces == null ){
+			if ( x.size() == 0 && old_network_interfaces == null ){
 				
-			}else if ( nis == null ){
+			}else if ( x.size() == 0 ){
 				
 				old_network_interfaces	= null;
 					
@@ -254,12 +255,9 @@ NetworkAdminImpl
 					
 			}else if ( old_network_interfaces == null ){
 				
-				Set	new_network_interfaces = new HashSet();
+				Set<NetworkInterface>	new_network_interfaces = new HashSet<NetworkInterface>();
 				
-				while( nis.hasMoreElements()){
-
-					new_network_interfaces.add( nis.nextElement());
-				}
+				new_network_interfaces.addAll( x );
 				
 				old_network_interfaces = new_network_interfaces;
 				
@@ -267,11 +265,9 @@ NetworkAdminImpl
 				
 			}else{
 				
-				Set	new_network_interfaces = new HashSet();
+				Set<NetworkInterface>	new_network_interfaces = new HashSet<NetworkInterface>();
 				
-				while( nis.hasMoreElements()){
-					
-					Object	 ni = nis.nextElement();
+				for ( NetworkInterface ni: x ){
 					
 						// NetworkInterface's "equals" method is based on ni name + addresses
 					
@@ -1152,6 +1148,19 @@ addressLoop:
 		return( res );
 	}
  	
+	public NetworkAdminProtocol
+	createInboundProtocol(
+		AzureusCore 	azureus_core,
+		int				type,
+		int				port )
+	{
+		return(
+			new NetworkAdminProtocolImpl( 
+				azureus_core, 
+				type, 
+				port ));
+	}
+	
  	public NetworkAdminProtocol[]
  	getInboundProtocols(
  			AzureusCore azureus_core)
diff --git a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminProtocolImpl.java b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminProtocolImpl.java
index 9348a7c..47fcb01 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminProtocolImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminProtocolImpl.java
@@ -26,11 +26,15 @@ package com.aelitis.azureus.core.networkmanager.admin.impl;
 
 import java.net.InetAddress;
 
+import org.gudy.azureus2.plugins.PluginInterface;
+
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminException;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminNetworkInterfaceAddress;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProgressListener;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProtocol;
+import com.aelitis.azureus.plugins.upnp.UPnPMapping;
+import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
 
 public class 
 NetworkAdminProtocolImpl 
@@ -84,8 +88,9 @@ NetworkAdminProtocolImpl
 	
 	public InetAddress
 	test(
-		NetworkAdminNetworkInterfaceAddress	address,
-		NetworkAdminProgressListener		listener )
+		NetworkAdminNetworkInterfaceAddress		address,
+		boolean									upnp_map,
+		NetworkAdminProgressListener			listener )
 	
 		throws NetworkAdminException
 	{
@@ -113,13 +118,60 @@ NetworkAdminProtocolImpl
 			res = tester.testOutbound( bind_ip, 0 );
 			
 		}else{
+
+			UPnPMapping new_mapping = null;
+
+			if ( upnp_map ){
+				
+				PluginInterface pi_upnp = core.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
+
+				if( pi_upnp != null ) {
+
+					UPnPPlugin upnp = (UPnPPlugin)pi_upnp.getPlugin();
+
+					UPnPMapping mapping = upnp.getMapping( type != PT_UDP , port );
+
+					if ( mapping == null ) {
+
+						new_mapping = mapping = upnp.addMapping( "NAT Tester", type != PT_UDP, port, true );
+
+							// give UPnP a chance to work
+
+						try{
+							Thread.sleep( 500 );
+
+						}catch( Throwable e ){
+
+						}
+					}
+				}
+			}
 			
-			res = tester.testInbound( bind_ip, port );
+			try{
+				res = tester.testInbound( bind_ip, port );
+				
+			}finally{
+				
+				if ( new_mapping != null ){
+					
+					new_mapping.destroy();
+				}
+			}
 		}
 		
 		return( res );
 	}
 	
+	public InetAddress
+	test(
+		NetworkAdminNetworkInterfaceAddress	address,
+		NetworkAdminProgressListener		listener )
+	
+		throws NetworkAdminException
+	{
+		return( test( address, false, listener ));
+	}
+	
 	public String
 	getTypeString()
 	{
diff --git a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminSocksProxyImpl.java b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminSocksProxyImpl.java
index 42959b3..b2799ed 100644
--- a/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminSocksProxyImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/admin/impl/NetworkAdminSocksProxyImpl.java
@@ -32,6 +32,7 @@ import org.gudy.azureus2.core3.util.AESemaphore;
 
 
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminException;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminSocksProxy;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPConnectionManager;
@@ -198,9 +199,11 @@ NetworkAdminSocksProxyImpl
 			TCPConnectionManager.ConnectListener connect_listener = 
 				new TCPConnectionManager.ConnectListener() 
 			{
-				public void 
-				connectAttemptStarted() 
+				public int 
+				connectAttemptStarted(
+					int default_connect_timeout )
 				{	
+					return( default_connect_timeout );
 				}
 	
 				public void 
@@ -209,7 +212,7 @@ NetworkAdminSocksProxyImpl
 				{
 					final TCPTransportImpl	transport = 
 						new TCPTransportImpl(
-								new ProtocolEndpointTCP( target_address ), false, false, null );
+								(ProtocolEndpointTCP)ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, target_address ), false, false, null );
 					
 					transport.setFilter( TCPTransportHelperFilterFactory.createTransparentFilter( channel ));
 	
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ByteBucket.java b/com/aelitis/azureus/core/networkmanager/impl/ByteBucket.java
index ad64e9e..21cdc63 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ByteBucket.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ByteBucket.java
@@ -44,4 +44,8 @@ ByteBucket
 	public void 
 	setBytesUsed( 
 		int bytes_used );
+	
+	public void
+	setFrozen(
+		boolean	frozen );
 }
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketMT.java b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketMT.java
index d5b15a2..03a38b3 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketMT.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketMT.java
@@ -35,6 +35,7 @@ ByteBucketMT
 	  private volatile long avail_bytes;
 	  private volatile long prev_update_time;
 	  
+	  private volatile boolean frozen;
 	  
 	  /**
 	   * Create a new byte-bucket with the given byte fill (guaranteed) rate.
@@ -114,7 +115,13 @@ ByteBucketMT
 	    setRate( rate_bytes_per_sec, rate_bytes_per_sec + (rate_bytes_per_sec/5));
 	  }
 	  
-	  
+	  public void
+	  setFrozen(
+			boolean	f )
+	  {
+		  frozen = f;
+	  }
+
 	  /**
 	   * Set the current fill/guaranteed rate, along with the burst rate.
 	   * @param rate_bytes_per_sec
@@ -139,6 +146,9 @@ ByteBucketMT
 	  
 	  
 	  private void update_avail_byte_count() {
+		  if ( frozen ){
+			  return;
+		  }
 		  synchronized( this ){
 		      final long now =SystemTime.getMonotonousTime();
 		      if (prev_update_time <now) {
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
index 38a89cf..8364163 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ByteBucketST.java
@@ -35,6 +35,7 @@ ByteBucketST
 	  private long avail_bytes;
 	  private long prev_update_time;
 	  
+	  private boolean frozen;
 	  
 	  /**
 	   * Create a new byte-bucket with the given byte fill (guaranteed) rate.
@@ -132,8 +133,20 @@ ByteBucketST
 	    ensureByteBucketMinBurstRate();
 	  }
 	  
+	  public void
+	  setFrozen(
+			boolean	f )
+	  {
+		  if ( f && frozen ){
+			  Debug.out( "Already frozen!" );
+		  }
+		  frozen = f;
+	  }
 	  
 	  private void update_avail_byte_count() {
+		  if ( frozen ){
+			  return;
+		  }
 	      final long now =SystemTime.getSteppedMonotonousTime();
 	      if (prev_update_time <now) {
 	          avail_bytes +=((now -prev_update_time) * rate) / 1000;
diff --git a/com/aelitis/azureus/core/networkmanager/impl/EntityHandler.java b/com/aelitis/azureus/core/networkmanager/impl/EntityHandler.java
index 595e623..d1310ee 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/EntityHandler.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/EntityHandler.java
@@ -176,6 +176,41 @@ public class EntityHandler {
     finally {  lock.exit();  }
   }
 
+  public RateHandler
+  getRateHandler(
+	 NetworkConnectionBase		connection )
+  {
+	  try{
+		  lock.enter();
+		  
+		  if( handler_type == TransferProcessor.TYPE_UPLOAD ){
+			  
+			  SinglePeerUploader upload_entity = (SinglePeerUploader)upgraded_connections.get( connection );
+			  
+			  if ( upload_entity != null ){
+				  
+				  return( upload_entity.getRateHandler());
+			  }else{
+				  
+				  return( global_uploader.getRateHandler());
+			  }
+		  }else{
+			  
+			  SinglePeerDownloader download_entity = (SinglePeerDownloader)upgraded_connections.get( connection );
+			  
+			  if ( download_entity != null ){
+				  
+				  return( download_entity.getRateHandler());
+			  }else{
+				  
+				  return( global_downloader.getRateHandler());
+			  } 
+		  }
+
+	  }finally{
+		  lock.exit();  
+	  }
+  }
   
   /**
    * Is the general pool entity in need of a transfer op.
diff --git a/com/aelitis/azureus/core/networkmanager/impl/IncomingConnectionManager.java b/com/aelitis/azureus/core/networkmanager/impl/IncomingConnectionManager.java
index 8a551ea..d34b5bf 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/IncomingConnectionManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/IncomingConnectionManager.java
@@ -98,7 +98,7 @@ IncomingConnectionManager
 	      MatchListener listener 		= null;
 	      Object		routing_data 	= null;
 	      	    	  
-	      for( Iterator i = match_buffers_cow.entrySet().iterator(); i.hasNext(); ) {
+	      for( Iterator i = match_buffers_cow.entrySet().iterator(); i.hasNext() && !transport.isClosed(); ) {
 	        Map.Entry entry = (Map.Entry)i.next();
 	        NetworkManager.ByteMatcher bm = (NetworkManager.ByteMatcher)entry.getKey();
 	        MatchListener this_listener = (MatchListener)entry.getValue();
@@ -301,7 +301,8 @@ IncomingConnectionManager
 	protected void 
 	removeConnection( 
 		IncomingConnection 	connection, 
-		boolean 			close_as_well ) 
+		boolean 			close_as_well,
+		String				reason ) 
 	{
 
 		try{  
@@ -318,7 +319,7 @@ IncomingConnectionManager
 		    
 		if( close_as_well ) {
 		
-			connection.filter.getHelper().close( "Tidy close" );
+			connection.filter.getHelper().close( "Tidy close" + ( reason==null||reason.length()==0?"":(": " + reason )));
 		}
 	}
 		  
@@ -372,7 +373,7 @@ IncomingConnectionManager
 		if( to_close != null ) {
 			for( int i=0; i < to_close.size(); i++ ) {
 				IncomingConnection ic = (IncomingConnection)to_close.get( i );
-				removeConnection( ic, true );
+				removeConnection( ic, true, "incoming connection routing timeout" );
 			}
 		}
 
@@ -441,7 +442,9 @@ IncomingConnectionManager
 				Object[] match_data = checkForMatch( transport_helper, local_port, ic.buffer, false );
 
 				if( match_data == null ) {  //no match found
-					if( ic.buffer.position() >= getMaxMatchBufferSize()) { //we've already read in enough bytes to have compared against all potential match buffers
+					if( transport_helper.isClosed() ||
+						ic.buffer.position() >= getMaxMatchBufferSize()) { //we've already read in enough bytes to have compared against all potential match buffers
+						
 						ic.buffer.flip();
 						if (Logger.isEnabled())
 							Logger.log(new LogEvent(LOGID,
@@ -450,7 +453,7 @@ IncomingConnectionManager
 									+ "] does not match "
 									+ "any known byte pattern: "
 									+ ByteFormatter.nicePrint(ic.buffer.array(), 128)));
-						removeConnection( ic, true );
+						removeConnection( ic, true, "routing failed: unknown hash" );
 					}
 				}
 				else {  //match found!
@@ -461,7 +464,7 @@ IncomingConnectionManager
 								+ "] recognized as "
 								+ "known byte pattern: "
 								+ ByteFormatter.nicePrint(ic.buffer.array(), 64)));
-					removeConnection( ic, false );
+					removeConnection( ic, false, null );
 
 					transport.setAlreadyRead( ic.buffer );
 
@@ -488,7 +491,7 @@ IncomingConnectionManager
 					t.printStackTrace();
 				}
 
-				removeConnection( ic, true );
+				removeConnection( ic, true, t==null?null:Debug.getNestedExceptionMessage(t));
 
 				return( false );
 			}
@@ -509,7 +512,7 @@ IncomingConnectionManager
 						+ msg.getMessage()));
 			}
 			
-			removeConnection( ic, true );
+			removeConnection( ic, true, msg==null?null:Debug.getNestedExceptionMessage(msg));
 		}
 	}  
 	  
diff --git a/com/aelitis/azureus/core/networkmanager/impl/IncomingMessageQueueImpl.java b/com/aelitis/azureus/core/networkmanager/impl/IncomingMessageQueueImpl.java
index 92c19c7..76e3ffd 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/IncomingMessageQueueImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/IncomingMessageQueueImpl.java
@@ -39,7 +39,7 @@ import com.aelitis.azureus.core.peermanager.messaging.*;
  */
 public class IncomingMessageQueueImpl implements IncomingMessageQueue{
   
-  private volatile ArrayList listeners = new ArrayList();  //copy-on-write
+  private volatile ArrayList<MessageQueueListener> listeners = new ArrayList<MessageQueueListener>();  //copy-on-write
   private final AEMonitor listeners_mon = new AEMonitor( "IncomingMessageQueue:listeners" );
 
   private MessageStreamDecoder stream_decoder;
@@ -232,9 +232,26 @@ public class IncomingMessageQueueImpl implements IncomingMessageQueue{
   public void registerQueueListener( MessageQueueListener listener ) {
     try{  listeners_mon.enter();
       //copy-on-write
-      ArrayList new_list = new ArrayList( listeners.size() + 1 );
-      new_list.addAll( listeners );
-      new_list.add( listener );
+      ArrayList<MessageQueueListener> new_list = new ArrayList<MessageQueueListener>( listeners.size() + 1 );
+      
+      if ( listener.isPriority()){
+    	  boolean	added = false;
+    	  for (int i=0;i<listeners.size();i++){
+    		  MessageQueueListener existing = listeners.get(i);
+    		  if ( added || existing.isPriority()){
+     		  }else{
+    			  new_list.add( listener );
+    			  added = true;
+    		  }
+   			  new_list.add( existing );
+    	  }
+    	  if ( !added ){
+    		  new_list.add( listener );
+    	  }
+      }else{
+	      new_list.addAll( listeners );
+	      new_list.add( listener );
+      }
       listeners = new_list;
     }
     finally{  listeners_mon.exit();  }
diff --git a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader.java b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader.java
index 90bc0a9..a6b744c 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader.java
@@ -53,6 +53,11 @@ public class MultiPeerDownloader implements RateControlledEntity {
 		this.main_handler = main_handler;
 	}
 
+	public RateHandler 
+	getRateHandler() 
+	{
+		return( main_handler );
+	}
 
 	/**
 	 * Add the given connection to the downloader.
@@ -130,11 +135,15 @@ public class MultiPeerDownloader implements RateControlledEntity {
 		return( res );
 	}
 
-	public boolean doProcessing( EventWaiter waiter ) {
+	public int doProcessing( EventWaiter waiter, int max_bytes ) {
 
 		int num_bytes_allowed = main_handler.getCurrentNumBytesAllowed();
-		if( num_bytes_allowed < 1 )  return false;
+		if( num_bytes_allowed < 1 )  return 0;
 
+		if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
+			num_bytes_allowed = max_bytes;
+		}
+		
 		ArrayList connections = connections_cow;
 		int num_checked = 0;
 		int num_bytes_remaining = num_bytes_allowed;
@@ -189,15 +198,17 @@ public class MultiPeerDownloader implements RateControlledEntity {
 		int total_bytes_read = num_bytes_allowed - num_bytes_remaining;
 		if( total_bytes_read > 0 ) {
 			main_handler.bytesProcessed( total_bytes_read );
-			return true;
+			return total_bytes_read;
 		}
 
-		return false;  //zero bytes read
+		return 0;
 	}
 
 
 	public int getPriority() {  return RateControlledEntity.PRIORITY_HIGH;  }
 
+	public boolean getPriorityBoost(){ return false; }
+	
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader2.java b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader2.java
index 7480815..6a75046 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader2.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerDownloader2.java
@@ -66,6 +66,11 @@ public class MultiPeerDownloader2 implements RateControlledEntity {
 		main_handler = _main_handler;
 	}
 
+	public RateHandler 
+	getRateHandler() 
+	{
+		return( main_handler );
+	}
 
 	/**
 	 * Add the given connection to the downloader.
@@ -161,9 +166,10 @@ public class MultiPeerDownloader2 implements RateControlledEntity {
 		return( res );
 	}
 
-	public boolean 
+	public int 
 	doProcessing( 
-		EventWaiter waiter ) 
+		EventWaiter waiter,
+		int			max_bytes ) 
 	{
 			// Note - this is single threaded
 		
@@ -173,9 +179,14 @@ public class MultiPeerDownloader2 implements RateControlledEntity {
 		
 		if ( num_bytes_allowed < 1 ){
 			
-			return false;
+			return 0;
 		}
 
+		if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
+		
+			num_bytes_allowed = max_bytes;
+		}
+		
 		if ( pending_actions != null ){
 			
 			try{
@@ -314,15 +325,17 @@ public class MultiPeerDownloader2 implements RateControlledEntity {
 			
 			main_handler.bytesProcessed( total_bytes_read );
 			
-			return true;
+			return total_bytes_read;
 		}
 
-		return false;  //zero bytes read
+		return 0;  //zero bytes read
 	}
 
 
 	public int getPriority() {  return RateControlledEntity.PRIORITY_HIGH;  }
 
+	public boolean getPriorityBoost(){ return false; }
+
 	public String
 	getString()
 	{
diff --git a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerUploader.java b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerUploader.java
index d93c1ad..b4e8ab3 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/MultiPeerUploader.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/MultiPeerUploader.java
@@ -62,7 +62,12 @@ public class MultiPeerUploader implements RateControlledEntity {
     this.rate_handler = rate_handler;
   }
   
-  
+	public RateHandler 
+	getRateHandler() 
+	{
+		return( rate_handler );
+	}
+	
   /**
    * Checks the connections in the waiting list to see if it's time to be force-flushed.
    */
@@ -499,17 +504,23 @@ public class MultiPeerUploader implements RateControlledEntity {
     return true;
   }
   
-  public boolean doProcessing( EventWaiter waiter ) {
+  public int doProcessing( EventWaiter waiter, int max_bytes ) {
     int num_bytes_allowed = rate_handler.getCurrentNumBytesAllowed();
-    if( num_bytes_allowed < 1 )  return false;
+    if( num_bytes_allowed < 1 )  return 0;
     
-    return write( waiter, num_bytes_allowed ) > 0 ? true : false;
+	if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
+		num_bytes_allowed = max_bytes;
+	}
+	
+    return write( waiter, num_bytes_allowed );
   }
 
   public int getPriority() {
     return RateControlledEntity.PRIORITY_HIGH;
   }
   
+  public boolean getPriorityBoost(){ return false; }
+
   public String
   getString()
   {
diff --git a/com/aelitis/azureus/core/networkmanager/impl/NetworkConnectionImpl.java b/com/aelitis/azureus/core/networkmanager/impl/NetworkConnectionImpl.java
index 186e9a8..b7ec4e0 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/NetworkConnectionImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/NetworkConnectionImpl.java
@@ -25,9 +25,11 @@ package com.aelitis.azureus.core.networkmanager.impl;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.util.AddressUtils;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.LightHashMap;
 
 
 import com.aelitis.azureus.core.networkmanager.*;
@@ -63,6 +65,8 @@ NetworkConnectionImpl
   private volatile ConnectionAttempt	connection_attempt;
   private volatile boolean				closed;
   
+  private Map<Object,Object>			user_data;
+  
   /**
    * Constructor for new OUTbound connection.
    * The connection is not yet established upon instantiation; use connect() to do so.
@@ -102,6 +106,8 @@ NetworkConnectionImpl
     outgoing_message_queue = new OutgoingMessageQueueImpl( encoder );
     outgoing_message_queue.setTransport( transport );
     incoming_message_queue = new IncomingMessageQueueImpl( decoder, this );
+    
+    transport.bindConnection( this );
   }
   
 
@@ -120,7 +126,7 @@ NetworkConnectionImpl
     
     if( is_connected ){
     	
-      connection_listener.connectStarted();
+      connection_listener.connectStarted( -1 );
       
       connection_listener.connectSuccess( initial_outbound_data );
       
@@ -144,14 +150,15 @@ NetworkConnectionImpl
     			initial_outbound_data,
     			priority,
     			new Transport.ConnectListener() {
-			      public void connectAttemptStarted() {
-			        connection_listener.connectStarted();
+			      public int connectAttemptStarted( int default_connect_timeout ){
+			        return( connection_listener.connectStarted( default_connect_timeout ));
 			      }
 			      
 			      public void connectSuccess( Transport	_transport, ByteBuffer remaining_initial_data ) {
 			        is_connected = true;
 			        transport	= _transport;
 			        outgoing_message_queue.setTransport( transport );
+			        transport.bindConnection( NetworkConnectionImpl.this );
 			        connection_listener.connectSuccess( remaining_initial_data );
 			        connection_attempt	= null;
 			      }
@@ -178,21 +185,26 @@ NetworkConnectionImpl
   {
 	  Transport	t = transport;
 	  
+	  if ( t != null ){
+		  
+		  t.unbindConnection( this );
+	  }
+	  
 	  transport = new bogusTransport( transport );
 	  
-	  close();
+	  close( "detached transport" );
 	  
 	  return( t );
   }
   
-  public void close() {
+  public void close( String reason ) {
   	NetworkManager.getSingleton().stopTransferProcessing( this );   
   	closed	= true;
     if ( connection_attempt != null ){
     	connection_attempt.abandon();
     }
     if ( transport != null ){
-    	transport.close( "Tidy close" );
+    	transport.close( "Tidy close" + ( reason==null||reason.length()==0?"":(": " + reason )));
     }
     incoming_message_queue.destroy();
    	outgoing_message_queue.destroy();  
@@ -248,7 +260,33 @@ NetworkConnectionImpl
 	  }
   }
   
-
+  
+  public Object
+  setUserData(
+  	Object		key,
+  	Object		value )
+  {
+	synchronized( this ){
+		if ( user_data == null ){
+			user_data = new LightHashMap<Object, Object>();
+		}
+		
+		return( user_data.put( key, value ));
+	}
+  }
+  
+  public Object
+  getUserData(
+  	Object		key )
+  {
+	  synchronized( this ){
+			if ( user_data == null ){
+				return( null );
+			}
+			
+			return( user_data.get( key ));
+	  }
+  }
 	
   public String toString() {
     return( transport==null?connection_endpoint.getDescription():transport.getDescription() );
@@ -345,6 +383,8 @@ NetworkConnectionImpl
 			return( transport.getEncryption( verbose ));
 		}
 
+		public String getProtocol(){ return transport.getProtocol(); }
+		
 		public void 
 		setReadyForRead()
 		{
@@ -411,6 +451,18 @@ NetworkConnectionImpl
 		{
 			// we get here after detaching a transport and then closing the peer connection
 		}
+		
+		public void
+		bindConnection(
+			NetworkConnection	connection )
+		{
+		}
+
+		public void
+		unbindConnection(
+			NetworkConnection	connection )
+		{
+		}
 
 		public void
 		setTrace(
diff --git a/com/aelitis/azureus/core/networkmanager/impl/OutgoingMessageQueueImpl.java b/com/aelitis/azureus/core/networkmanager/impl/OutgoingMessageQueueImpl.java
index f59db69..1b1be8a 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/OutgoingMessageQueueImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/OutgoingMessageQueueImpl.java
@@ -55,6 +55,8 @@ OutgoingMessageQueueImpl
   private final AEMonitor listeners_mon		= new AEMonitor( "OutgoingMessageQueue:L");
   
   private int total_size = 0;
+  private int total_data_size = 0;
+  private boolean	priority_boost = false;
   private RawMessage urgent_message = null;
   private boolean destroyed = false;
   
@@ -128,8 +130,10 @@ OutgoingMessageQueueImpl
       queue_mon.exit();
     }
     total_size = 0;
+    total_data_size = 0;
     prev_sent.clear();
     listeners = new ArrayList();
+    percent_complete = -1;
     urgent_message = null;
   }
   
@@ -140,7 +144,40 @@ OutgoingMessageQueueImpl
    */
   public int getTotalSize() {  return total_size;  }
   
+  public int
+  getDataQueuedBytes()
+  {
+	 return( total_data_size );
+  }
+  
+  public int
+  getProtocolQueuedBytes()
+  {
+	  return( total_size - total_data_size );
+  }
   
+  public boolean 
+  getPriorityBoost()
+  {
+	  return( priority_boost );
+  }
+	
+  public void 
+  setPriorityBoost( 
+	 boolean	boost )
+  {
+	  priority_boost = boost;
+  }
+  public boolean
+  isBlocked()
+  {
+	 if ( transport == null ){
+		 
+		 return( false );
+	 }
+	 
+	 return( !transport.isReadyForWrite( null ));
+  }
   /**
    * Whether or not an urgent message (one that needs an immediate send, i.e. a no-delay message) is queued.
    * @return true if there's a message tagged for immediate write
@@ -208,8 +245,13 @@ OutgoingMessageQueueImpl
 	      queue.add( pos, rmesg );
 	      
 	      DirectByteBuffer[] payload = rmesg.getRawData();
+	      int	remaining = 0;
 	      for( int j=0; j < payload.length; j++ ) {
-	        total_size += payload[j].remaining(DirectByteBuffer.SS_NET);
+	    	  remaining += payload[j].remaining(DirectByteBuffer.SS_NET);
+	      }
+	      total_size += remaining;
+	      if ( rmesg.getType() == Message.TYPE_DATA_PAYLOAD ){
+	    	  total_data_size += remaining;
 	      }
 	    }finally{
 	      queue_mon.exit();
@@ -268,10 +310,14 @@ OutgoingMessageQueueImpl
             if( msg == urgent_message ) urgent_message = null;
             
             DirectByteBuffer[] payload = msg.getRawData();
+            int remaining = 0;
             for( int x=0; x < payload.length; x++ ) {
-              total_size -= payload[x].remaining(DirectByteBuffer.SS_NET);
+            	remaining += payload[x].remaining(DirectByteBuffer.SS_NET);
+            }
+            total_size -= remaining;
+            if ( msg.getType() == Message.TYPE_DATA_PAYLOAD ){
+            	total_data_size -= remaining;
             }
-            
             if( manual_listener_notify ) {
               NotificationItem item = new NotificationItem( NotificationItem.MESSAGE_REMOVED );
               item.message = msg;
@@ -295,6 +341,10 @@ OutgoingMessageQueueImpl
         	}
         }
       }
+      
+      if ( queue.isEmpty()){
+    	  percent_complete = -1;
+      }
     }finally{
       queue_mon.exit();
     }
@@ -347,10 +397,14 @@ OutgoingMessageQueueImpl
             if( raw == urgent_message ) urgent_message = null;  
             
             DirectByteBuffer[] payload = raw.getRawData();
+            int remaining = 0;
             for( int x=0; x < payload.length; x++ ) {
-              total_size -= payload[x].remaining(DirectByteBuffer.SS_NET);
+            	remaining += payload[x].remaining(DirectByteBuffer.SS_NET);
+            }
+            total_size -= remaining;
+            if ( raw.getType() == Message.TYPE_DATA_PAYLOAD ){
+            	total_data_size -= remaining;
             }
-
             queue.remove( raw );
             msg_removed = raw;
           }
@@ -358,6 +412,10 @@ OutgoingMessageQueueImpl
           break;
         }
       }
+      
+      if ( queue.isEmpty()){
+    	  percent_complete = -1;
+      }
     }finally{
       queue_mon.exit();
     }
@@ -422,6 +480,7 @@ OutgoingMessageQueueImpl
 
 	  ArrayList messages_sent = null;
 
+	  //System.out.println( "deliver: %=" + percent_complete + ", queue=" + queue.size());
 	  try{
 		  queue_mon.enter();
 
@@ -522,10 +581,13 @@ outer:
 					  int bytes_written = (bb.limit() - bb.remaining()) - orig_positions[ pos ];
 					  total_size -= bytes_written;
 
+					  if ( msg.getType() == Message.TYPE_DATA_PAYLOAD ){
+						  total_data_size -= bytes_written;
+					  }
+					  
 					  if( x > 0 && msg.getType() == Message.TYPE_DATA_PAYLOAD ) {  //assumes the first buffer is message header
 						  data_written += bytes_written;
-					  }
-					  else {
+					  }else {
 						  protocol_written += bytes_written;
 					  }
 
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoder.java b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoder.java
index 089b907..0e1035b 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoder.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoder.java
@@ -35,7 +35,7 @@ ProtocolDecoder
 	private static final int	TIMEOUT_CHECK		= 5000;
 	private static final int	LOG_TICKS			= 60000 / TIMEOUT_CHECK;
 		
-	private static List			decoders	= new ArrayList();
+	private static List<ProtocolDecoder>			decoders	= new ArrayList<ProtocolDecoder>();
 	
 	private static AEMonitor	class_mon 	= new AEMonitor( "TCPProtocolDecoder:class" );
 	
@@ -54,8 +54,8 @@ ProtocolDecoder
 
 						loop++;
 
-						long	now = SystemTime.getCurrentTime();
-
+						List<ProtocolDecoder>	copy;
+						
 						try{
 							class_mon.enter();
 
@@ -70,34 +70,41 @@ ProtocolDecoder
 								}
 							}
 
-								// isComplete can synchronously modify 'decoders' so we
-								// can't continue looping after a removal, rather we have
-								// to restart
+							copy = new ArrayList<ProtocolDecoder>( decoders );
+							
+						}finally{
+
+							class_mon.exit();
+						}		
+						
+						if ( copy.size() > 0 ){
 							
-							boolean	retry = true;
+							List<ProtocolDecoder> to_remove = new ArrayList<ProtocolDecoder>();
 							
-							while( retry ){
-								
-								retry = false;
+							long	now = SystemTime.getCurrentTime();
+
+							for ( ProtocolDecoder decoder: copy ){
 								
-								for (int i=0;i<decoders.size();i++){
-									
-									ProtocolDecoder	decoder = (ProtocolDecoder)decoders.get(i);
-	
-									if ( decoder.isComplete( now )){
+								if ( decoder.isComplete( now )){
 	
-										decoders.remove( decoder );
-										
-										retry = true;
+									to_remove.add( decoder );
+								}
+							}
+							
+							if ( to_remove.size() > 0 ){
+								
+								try{
+									class_mon.enter();
+
+									for ( ProtocolDecoder decoder: to_remove ){
 										
-										break;
+										decoders.remove( decoder );
 									}
+								}finally{
+	
+									class_mon.exit();
 								}
 							}
-
-						}finally{
-
-							class_mon.exit();
 						}
 					}
 				}
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderInitial.java b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderInitial.java
index c958c59..0781483 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderInitial.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderInitial.java
@@ -248,6 +248,13 @@ ProtocolDecoderInitial
 	isComplete(
 		long	now )
 	{
+		if ( transport == null ){
+		
+				// can happen during initialisation
+			
+			return( false );
+		}
+		
 		if ( !processing_complete ){
 		
 			if ( start_time > now ){
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderPHE.java b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderPHE.java
index 2a57eda..115889c 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderPHE.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ProtocolDecoderPHE.java
@@ -2011,6 +2011,8 @@ ProtocolDecoderPHE
 
 		processing_complete	= true;
 		
+		transport.setScatteringMode(0);
+		
 		adapter.decodeComplete( this, initial_data_out );	
 	}
 	
diff --git a/com/aelitis/azureus/core/networkmanager/impl/RateControlledEntity.java b/com/aelitis/azureus/core/networkmanager/impl/RateControlledEntity.java
index 28331dd..fc3b94f 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/RateControlledEntity.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/RateControlledEntity.java
@@ -23,6 +23,7 @@
 package com.aelitis.azureus.core.networkmanager.impl;
 
 import com.aelitis.azureus.core.networkmanager.EventWaiter;
+import com.aelitis.azureus.core.networkmanager.RateHandler;
 
 /**
  * Interface designation for rate-limited entities controlled by a handler.
@@ -48,7 +49,7 @@ public interface RateControlledEntity {
    * Attempt to do a processing operation.
    * @return true if >0 bytes were processed (success), false if 0 bytes were processed (failure)
    */
-  public boolean doProcessing( EventWaiter waiter );
+  public int doProcessing( EventWaiter waiter, int max_bytes_permitted );
   
   /**
    * Get this entity's priority level.
@@ -61,6 +62,9 @@ public interface RateControlledEntity {
   	 * @return
   	 */
   
+  public boolean
+  getPriorityBoost();
+  
   public long
   getBytesReadyToWrite();
   
@@ -70,6 +74,9 @@ public interface RateControlledEntity {
   public int
   getReadyConnectionCount( EventWaiter waiter );
   
+  public RateHandler
+  getRateHandler();
+  
   public String
   getString();
 }
diff --git a/com/aelitis/azureus/core/networkmanager/impl/RateHandler.java b/com/aelitis/azureus/core/networkmanager/impl/RateHandler.java
deleted file mode 100644
index 6ba2489..0000000
--- a/com/aelitis/azureus/core/networkmanager/impl/RateHandler.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Created on Oct 6, 2004
- * Created by Alon Rohter
- * 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.networkmanager.impl;
-
-/**
- * Handler to allow external control of an entity's byte processing rate.
- */
-public interface RateHandler {
-  /**
-   * Get the current number of bytes allowed to be processed by the entity.
-   * @return number of bytes allowed
-   */
-  public int getCurrentNumBytesAllowed();
-    
-  /**
-   * Notification of any bytes processed by the entity.
-   * @param num_bytes_processed 
-   */
-  public void bytesProcessed( int num_bytes_processed );
-}
diff --git a/com/aelitis/azureus/core/networkmanager/impl/ReadController.java b/com/aelitis/azureus/core/networkmanager/impl/ReadController.java
index ffef386..165b0b1 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/ReadController.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/ReadController.java
@@ -264,7 +264,7 @@ public class ReadController implements AzureusCoreStatsProvider{
 			  
 			  	// skip over failed readers to find a good one
 			  
-			  if ( ready_entity.doProcessing( read_waiter ) ) {
+			  if ( ready_entity.doProcessing( read_waiter, 0 ) > 0 ) {
 	
 				  progress_count++;
 	
@@ -291,7 +291,7 @@ public class ReadController implements AzureusCoreStatsProvider{
 			  }
 		  }else{
 			  
-			  return( ready_entity.doProcessing( read_waiter ));
+			  return( ready_entity.doProcessing( read_waiter, 0 ) > 0 );
 		  }
 	  }
 	  
diff --git a/com/aelitis/azureus/core/networkmanager/impl/SinglePeerDownloader.java b/com/aelitis/azureus/core/networkmanager/impl/SinglePeerDownloader.java
index 67c827c..bec1945 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/SinglePeerDownloader.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/SinglePeerDownloader.java
@@ -44,7 +44,11 @@ public class SinglePeerDownloader implements RateControlledEntity {
     this.rate_handler = rate_handler;
   }
   
-  
+	public RateHandler 
+	getRateHandler() 
+	{
+		return( rate_handler );
+	}
 
   public boolean canProcess( EventWaiter waiter ) {
 
@@ -57,16 +61,19 @@ public class SinglePeerDownloader implements RateControlledEntity {
     return true;
   }
     
-  public boolean doProcessing( EventWaiter waiter ) {
+  public int doProcessing( EventWaiter waiter, int max_bytes ) {
     if( connection.getTransportBase().isReadyForRead(waiter) != 0 )  {
-      return false;
+      return 0;
     }
     
     int num_bytes_allowed = rate_handler.getCurrentNumBytesAllowed();
     if( num_bytes_allowed < 1 )  {
-      return false;
+      return 0;
     }
     
+	if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
+		num_bytes_allowed = max_bytes;
+	}
     
     //int mss = NetworkManager.getTcpMssSize();   
     //if( num_bytes_allowed > mss )  num_bytes_allowed = mss;
@@ -99,16 +106,16 @@ public class SinglePeerDownloader implements RateControlledEntity {
       }
       
       connection.notifyOfException( e );
-      return false;
+      return 0;
     }
 
     if( bytes_read < 1 )  {
-      return false;
+      return 0;
     }
     
     rate_handler.bytesProcessed( bytes_read );
     
-    return true;
+    return bytes_read;
   }
   
   
@@ -116,6 +123,8 @@ public class SinglePeerDownloader implements RateControlledEntity {
     return RateControlledEntity.PRIORITY_NORMAL;
   }
 
+  public boolean getPriorityBoost(){ return false; }
+
   public long
   getBytesReadyToWrite()
   {
diff --git a/com/aelitis/azureus/core/networkmanager/impl/SinglePeerUploader.java b/com/aelitis/azureus/core/networkmanager/impl/SinglePeerUploader.java
index 29baecc..ae85bee 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/SinglePeerUploader.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/SinglePeerUploader.java
@@ -29,6 +29,7 @@ import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.core.networkmanager.EventWaiter;
 import com.aelitis.azureus.core.networkmanager.NetworkConnectionBase;
+import com.aelitis.azureus.core.networkmanager.RateHandler;
 
 
 /**
@@ -44,6 +45,12 @@ public class SinglePeerUploader implements RateControlledEntity {
     this.rate_handler = rate_handler;
   }
     
+	public RateHandler 
+	getRateHandler() 
+	{
+		return( rate_handler );
+	}
+	
 ////////////////RateControlledWriteEntity implementation ////////////////////
   
   public boolean canProcess(EventWaiter waiter) {
@@ -59,23 +66,27 @@ public class SinglePeerUploader implements RateControlledEntity {
     return true;
   }
   
-  public boolean doProcessing(EventWaiter waiter) {
+  public int doProcessing(EventWaiter waiter, int max_bytes ) {
     if( !connection.getTransportBase().isReadyForWrite(waiter) )  {
       //Debug.out("dW:not ready"); happens sometimes, just live with it as non-fatal
-      return false;
+      return 0;
     }
     
     int num_bytes_allowed = rate_handler.getCurrentNumBytesAllowed();
     if( num_bytes_allowed < 1 )  {
-      return false;
+      return 0;
     }
     
+	if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
+		num_bytes_allowed = max_bytes;
+	}
+	
     int num_bytes_available = connection.getOutgoingMessageQueue().getTotalSize();
     if( num_bytes_available < 1 ) {
       if ( !connection.getOutgoingMessageQueue().isDestroyed()){
     	  //Debug.out("dW:not avail"); happens sometimes, just live with it as non-fatal
       }
-      return false;
+      return 0;
     }
     
     int num_bytes_to_write = num_bytes_allowed > num_bytes_available ? num_bytes_available : num_bytes_allowed;
@@ -110,21 +121,27 @@ public class SinglePeerUploader implements RateControlledEntity {
       }
       
       connection.notifyOfException( e );
-      return false;
+      return 0;
     }
     
     if( written < 1 )  {
-      return false;
+      return 0;
     }
     
     rate_handler.bytesProcessed( written );
-    return true;
+    return written;
   }
   
   public int getPriority() {
     return RateControlledEntity.PRIORITY_NORMAL;
   }
 
+  public boolean 
+  getPriorityBoost()
+  {
+	  return( connection.getOutgoingMessageQueue().getPriorityBoost());
+  }
+  
   public long
   getBytesReadyToWrite()
   {
diff --git a/com/aelitis/azureus/core/networkmanager/impl/TransferProcessor.java b/com/aelitis/azureus/core/networkmanager/impl/TransferProcessor.java
index bff942f..dffa295 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/TransferProcessor.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/TransferProcessor.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.core3.util.SystemTime;
 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.networkmanager.RateHandler;
 
 
 
@@ -53,6 +54,7 @@ public class TransferProcessor {
   
   private final LimitedRateGroup max_rate;
   
+  private final RateHandler	main_rate_handler;
   private final ByteBucket main_bucket;
   private final EntityHandler main_controller;
   
@@ -75,18 +77,21 @@ public class TransferProcessor {
 
     main_bucket = createBucket( max_rate.getRateLimitBytesPerSecond() ); 
 
-    main_controller = new EntityHandler( processor_type, new RateHandler() {
-      public int getCurrentNumBytesAllowed() {
-        if( main_bucket.getRate() != max_rate.getRateLimitBytesPerSecond() ) { //sync rate
-          main_bucket.setRate( max_rate.getRateLimitBytesPerSecond() );
+    main_rate_handler = 
+    	new RateHandler() {
+        public int getCurrentNumBytesAllowed() {
+          if( main_bucket.getRate() != max_rate.getRateLimitBytesPerSecond() ) { //sync rate
+            main_bucket.setRate( max_rate.getRateLimitBytesPerSecond() );
+          }
+          return main_bucket.getAvailableByteCount();
         }
-        return main_bucket.getAvailableByteCount();
-      }
+        
+        public void bytesProcessed( int num_bytes_written ) {
+          main_bucket.setBytesUsed( num_bytes_written );
+        }
+      };
       
-      public void bytesProcessed( int num_bytes_written ) {
-        main_bucket.setBytesUsed( num_bytes_written );
-      }
-    });
+    main_controller = new EntityHandler( processor_type, main_rate_handler );
   }
   
 
@@ -189,6 +194,13 @@ public class TransferProcessor {
   }
   
   public void
+  setRateLimiterFreezeState(
+		boolean	frozen )
+  {
+	  main_bucket.setFrozen( frozen );
+  }
+  
+  public void
   addRateLimiter(
 	NetworkConnectionBase 	connection,
 	LimitedRateGroup		group )
@@ -442,6 +454,18 @@ public class TransferProcessor {
     }
   }
   
+  public RateHandler
+  getRateHandler()
+  {
+	  return( main_rate_handler );
+  }
+  
+  public RateHandler
+  getRateHandler(
+	NetworkConnectionBase	connection )
+  {
+	return( main_controller.getRateHandler( connection ));  
+  }
   
   private ByteBucket
   createBucket(
diff --git a/com/aelitis/azureus/core/networkmanager/impl/TransportHelper.java b/com/aelitis/azureus/core/networkmanager/impl/TransportHelper.java
index 368ae6c..e19da5b 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/TransportHelper.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/TransportHelper.java
@@ -109,6 +109,9 @@ TransportHelper
     public void
     cancelWriteSelects();
     
+    public boolean
+    isClosed();
+    
     public void
     close(
     	String		reason );
diff --git a/com/aelitis/azureus/core/networkmanager/impl/TransportImpl.java b/com/aelitis/azureus/core/networkmanager/impl/TransportImpl.java
index 8fb3f56..439e02a 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/TransportImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/TransportImpl.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.TimeFormatter;
 
 import com.aelitis.azureus.core.networkmanager.EventWaiter;
+import com.aelitis.azureus.core.networkmanager.NetworkConnection;
 import com.aelitis.azureus.core.networkmanager.Transport;
 
 public abstract class 
@@ -104,11 +105,35 @@ TransportImpl
 		return( filter==null?"":filter.getName(verbose)); 
 	}
 	
-	 public boolean 
-	 isEncrypted()
-	 { 
-		 return( filter==null?false:filter.isEncrypted());
-	 }
+	public String
+	getProtocol()
+	{
+			// default impl = extract from encryption
+		
+		String s = getEncryption( false );
+		
+		int pos = s.indexOf( '(' );
+		
+		if ( pos != -1 ){
+			
+			s = s.substring( pos+1 );
+			
+			pos = s.indexOf( ')' );
+			
+			if ( pos > 0 ){
+				
+				return( s.substring( 0, pos ));
+			}
+		}
+		
+		return( "" );
+	}
+	
+	public boolean 
+	isEncrypted()
+	{ 
+		return( filter==null?false:filter.isEncrypted());
+	}
 	 
 	  /**
 	   * Is the transport ready to write,
@@ -373,6 +398,18 @@ TransportImpl
 		registerSelectHandling();
 	}
 	
+	public void
+	bindConnection(
+		NetworkConnection	connection )
+	{
+	}
+
+	public void
+	unbindConnection(
+		NetworkConnection	connection )
+	{
+	}
+	  
 	private void 
 	registerSelectHandling() 
 	{
diff --git a/com/aelitis/azureus/core/networkmanager/impl/WriteController.java b/com/aelitis/azureus/core/networkmanager/impl/WriteController.java
index 201c993..654c075 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/WriteController.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/WriteController.java
@@ -29,6 +29,7 @@ import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.networkmanager.EventWaiter;
+import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.stats.AzureusCoreStats;
 import com.aelitis.azureus.core.stats.AzureusCoreStatsProvider;
 
@@ -40,12 +41,14 @@ public class WriteController implements AzureusCoreStatsProvider{
   
 	private static int 		IDLE_SLEEP_TIME  	= 50;
 	private static boolean	AGGRESIVE_WRITE		= false;
-	
+	private static int		BOOSTER_GIFT 		= 5*1024;
+
 	static{
 		COConfigurationManager.addAndFireParameterListeners(
 			new String[]{
 				"network.control.write.idle.time",
 				"network.control.write.aggressive",
+				"Bias Upload Slack KBs",
 			},
 			new ParameterListener()
 			{
@@ -55,25 +58,38 @@ public class WriteController implements AzureusCoreStatsProvider{
 				{
 					IDLE_SLEEP_TIME 	= COConfigurationManager.getIntParameter( "network.control.write.idle.time" );
 					AGGRESIVE_WRITE		= COConfigurationManager.getBooleanParameter( "network.control.write.aggressive" );
+					BOOSTER_GIFT 		= COConfigurationManager.getIntParameter( "Bias Upload Slack KBs" )*1024;
 				}
 			});
 	}
 	
-  private volatile ArrayList normal_priority_entities = new ArrayList();  //copied-on-write
-  private volatile ArrayList high_priority_entities = new ArrayList();  //copied-on-write
+  private volatile ArrayList<RateControlledEntity> normal_priority_entities = new ArrayList<RateControlledEntity>();  //copied-on-write
+  private volatile ArrayList<RateControlledEntity> boosted_priority_entities = new ArrayList<RateControlledEntity>();  //copied-on-write
+  private volatile ArrayList<RateControlledEntity> high_priority_entities = new ArrayList<RateControlledEntity>();  //copied-on-write
   private final AEMonitor entities_mon = new AEMonitor( "WriteController:EM" );
   private int next_normal_position = 0;
+  private int next_boost_position = 0;
   private int next_high_position = 0;
+    
+
+  private long	booster_process_time;;
+  private int	booster_normal_written;
+  private int	booster_stat_index;
+  private int[]	booster_normal_writes 	= new int[5];
+  private int[]	booster_gifts 			= new int[5];
   
   private int aggressive_np_normal_priority_count;
   private int aggressive_np_high_priority_count;
   
+  private long	process_loop_time;
   private long	wait_count;
   private long	progress_count;
   private long	non_progress_count;
   
   private EventWaiter 	write_waiter = new EventWaiter();
   
+  private NetworkManager	net_man;
+  
   private int	entity_count = 0;
   
   /**
@@ -127,7 +143,18 @@ public class WriteController implements AzureusCoreStatsProvider{
 
 						writer.println( entity.getString());
 					}
+					
+					ref = boosted_priority_entities;
+
+					writer.println( "boosted - " + ref.size());
+					    
+					for (int i=0;i<ref.size();i++){
+						
+						RateControlledEntity entity = (RateControlledEntity)ref.get( i );
 
+						writer.println( entity.getString());
+					}
+					
 					ref = high_priority_entities;
 
 					writer.println( "priority - " + ref.size());
@@ -168,7 +195,7 @@ public class WriteController implements AzureusCoreStatsProvider{
 
 	  if ( types.contains( AzureusCoreStats.ST_NET_WRITE_CONTROL_ENTITY_COUNT )){
 
-		  values.put( AzureusCoreStats.ST_NET_WRITE_CONTROL_ENTITY_COUNT, new Long( high_priority_entities.size() + normal_priority_entities.size()));
+		  values.put( AzureusCoreStats.ST_NET_WRITE_CONTROL_ENTITY_COUNT, new Long( high_priority_entities.size() + boosted_priority_entities.size() + normal_priority_entities.size()));
 	  }
 	  
 	  if ( 	types.contains( AzureusCoreStats.ST_NET_WRITE_CONTROL_CON_COUNT ) ||
@@ -179,7 +206,7 @@ public class WriteController implements AzureusCoreStatsProvider{
 		  int	ready_connections	= 0;
 		  int	connections			= 0;
 		  
-		  ArrayList[] refs = { normal_priority_entities, high_priority_entities };
+		  ArrayList[] refs = { normal_priority_entities, boosted_priority_entities, high_priority_entities };
 		    
 		  for (int i=0;i<refs.length;i++){
 			  
@@ -206,7 +233,14 @@ public class WriteController implements AzureusCoreStatsProvider{
   private void writeProcessorLoop() {
     boolean check_high_first = true;
     
+    long	last_check = SystemTime.getMonotonousTime();
+    
+    net_man = NetworkManager.getSingleton();
+
     while( true ) {
+      
+      process_loop_time = SystemTime.getMonotonousTime();
+
       try {
         if( check_high_first ) {
           check_high_first = false;
@@ -232,45 +266,122 @@ public class WriteController implements AzureusCoreStatsProvider{
       catch( Throwable t ) {
         Debug.out( "writeProcessorLoop() EXCEPTION: ", t );
       }
+            
+      if ( process_loop_time - last_check > 5000 ){
+    	  
+    	  last_check = process_loop_time;
+    	  
+    	  boolean	changed = false;
+    	  
+    	  ArrayList<RateControlledEntity> ref = normal_priority_entities;
+    	  
+    	  for ( RateControlledEntity e: ref ){
+    		  
+    		 if ( e.getPriorityBoost()){
+    			  
+    			 changed = true;
+    			  
+    			 break;
+    		 }
+    	  }
+    	  
+    	  if ( !changed ){
+    		  
+    	  	 ref = boosted_priority_entities;
+        	  
+        	 for ( RateControlledEntity e: ref ){
+        		  
+        		 if ( !e.getPriorityBoost()){
+        			  
+        			 changed = true;
+        			  
+        			 break;
+        		 }
+        	  }
+    	  }
+    	  
+    	  if ( changed ){
+    		 
+ 		    try{  
+ 		    	entities_mon.enter();
+ 		    	
+ 		    	ArrayList<RateControlledEntity> new_normal 	= new ArrayList<RateControlledEntity>();
+ 		    	ArrayList<RateControlledEntity> new_boosted = new ArrayList<RateControlledEntity>();
+ 		    	
+ 		    	for ( RateControlledEntity e: normal_priority_entities ){
+ 		    		
+ 		    		if ( e.getPriorityBoost()){
+ 		    			
+ 		    			new_boosted.add( e );
+ 		    			
+ 		    		}else{
+ 		    			
+ 		    			new_normal.add( e );
+ 		    		}
+ 		    	}
+ 		    	
+		    	for ( RateControlledEntity e: boosted_priority_entities ){
+ 		    		
+ 		    		if ( e.getPriorityBoost()){
+ 		    			
+ 		    			new_boosted.add( e );
+ 		    			
+ 		    		}else{
+ 		    			
+ 		    			new_normal.add( e );
+ 		    		}
+ 		    	}
+		    	
+		    	normal_priority_entities 	= new_normal;
+		    	boosted_priority_entities	= new_boosted;
+		    	
+ 		    }finally{
+ 		    	
+ 		    	entities_mon.exit();
+ 		    }
+    	  }
+      }
     }
   }
   
   
-  private boolean doNormalPriorityWrite() {
-    RateControlledEntity ready_entity = getNextReadyNormalPriorityEntity();
-    if( ready_entity != null ){
-    	
-    	if ( ready_entity.doProcessing( write_waiter ) ) {
+  private boolean 
+  doNormalPriorityWrite() 
+  {
+    int result = processNextReadyNormalPriorityEntity();
     
-    		progress_count++;
+    if ( result > 0 ){
+    	   
+    	progress_count++;
     		
-    		return true;
-    	}else{
+    	return true;
+    	
+    }else if ( result == 0 ){
     		
-    		non_progress_count++;
+    	non_progress_count++;
 			
-    		if ( AGGRESIVE_WRITE ){
+    	if ( AGGRESIVE_WRITE ){
     			
-     			aggressive_np_normal_priority_count++;
+    		aggressive_np_normal_priority_count++;
     			     			
-    			if ( aggressive_np_normal_priority_count < normal_priority_entities.size()){
+    		if ( aggressive_np_normal_priority_count < ( normal_priority_entities.size() + boosted_priority_entities.size())){
     				
-    				return( true );
+    			return( true );
     				
-    			}else{
+    		}else{
     				
-    				aggressive_np_normal_priority_count = 0;
-    			}
+    			aggressive_np_normal_priority_count = 0;
     		}
     	}
     }
+    
     return false;
   }
   
   private boolean doHighPriorityWrite() {
     RateControlledEntity ready_entity = getNextReadyHighPriorityEntity();
     if( ready_entity != null ){
-    	if ( ready_entity.doProcessing( write_waiter ) ) {
+    	if ( ready_entity.doProcessing( write_waiter, 0 ) > 0 ) {
     
     		progress_count++;
     		
@@ -299,23 +410,168 @@ public class WriteController implements AzureusCoreStatsProvider{
   }
   
   
-  private RateControlledEntity getNextReadyNormalPriorityEntity() {
-    ArrayList ref = normal_priority_entities;
-    
-    int size = ref.size();
-    int num_checked = 0;
+  private int 
+  processNextReadyNormalPriorityEntity() 
+  {
+	  ArrayList<RateControlledEntity> boosted_ref = boosted_priority_entities;
 
-    while( num_checked < size ) {
-      next_normal_position = next_normal_position >= size ? 0 : next_normal_position;  //make circular
-      RateControlledEntity entity = (RateControlledEntity)ref.get( next_normal_position );
-      next_normal_position++;
-      num_checked++;
-      if( entity.canProcess( write_waiter ) ) {  //is ready
-        return entity;
-      }
-    }
+	  final int boosted_size = boosted_ref.size();
+	
+	  try{
+		  if ( boosted_size > 0 ){
+			  			  
+			  if ( process_loop_time - booster_process_time >= 1000 ){
+			
+				  booster_process_time = process_loop_time;
+				  
+				  booster_gifts[ booster_stat_index ] 			= BOOSTER_GIFT;
+				  booster_normal_writes[ booster_stat_index]	= booster_normal_written;
+				  
+				  booster_stat_index++;
+				  
+				  if ( booster_stat_index >= booster_gifts.length ){
+					  
+					  booster_stat_index = 0;
+				  }
+				  
+				  booster_normal_written = 0;
+			  }
+			  
+			  int	total_gifts 		= 0;
+			  int	total_normal_writes	= 0;
+				  
+			  for (int i=0;i<booster_gifts.length;i++){
+					  
+				  total_gifts			+= booster_gifts[i];
+				  total_normal_writes 	+= booster_normal_writes[i];
+			  }
+				  
+			  int	effective_gift = total_gifts - total_normal_writes;
+			  
+			  if ( effective_gift > 0 ){
+				  
+				  ArrayList<RateControlledEntity> normal_ref = normal_priority_entities;
+	
+				  int normal_size = normal_ref.size();
+				  
+				  int num_checked = 0;
+				  
+				  int position = next_normal_position;
+				  
+				  List<RateControlledEntity> ready = new ArrayList<RateControlledEntity>();
+				  
+				  while( num_checked < normal_size ) {
+					  position = position >= normal_size ? 0 : position; 
+					  RateControlledEntity entity = normal_ref.get( position );
+					  position++;
+					  num_checked++;
+					  if( entity.canProcess( write_waiter )) {
+						 next_normal_position = position;
+						 ready.add( entity );
+					  }
+				  }
+				  	
+				  int	num_ready = ready.size();
+				  
+				  if ( num_ready > 0 ){
+					  		
+					  int	gift_used = 0;
+					  
+					  for ( RateControlledEntity r: ready ){
+						  
+						  int	permitted = effective_gift / num_ready;
+						  
+						  if ( permitted <= 0 ){
+							  
+							  permitted = 1;
+						  }
+						  			  
+						  if ( r.canProcess( write_waiter )){
+							  
+							  int	done = r.doProcessing( write_waiter, permitted );
+							  
+							  if ( done > 0 ){
+							  
+								  booster_normal_written += done;
+								  
+								  gift_used += done;
+							  }
+						  }
+						  
+						  num_ready--;
+					  }
+						  
+					  for ( int i=booster_stat_index; gift_used > 0 && i<booster_stat_index+booster_gifts.length; i++){
+						  
+						  int	avail = booster_gifts[i%booster_gifts.length];
+						  
+						  if ( avail > 0 ){
+							  
+							  int	temp = Math.min( avail, gift_used );
+							  
+							  avail 	-= temp;
+							  gift_used -= temp;
+							  
+							  booster_gifts[i%booster_gifts.length] = avail;
+						  }
+					  }
+				  }
+			  }
+			  
+			  int num_checked = 0;
+		
+			  while( num_checked < boosted_size ) {
+				  next_boost_position = next_boost_position >= boosted_size ? 0 : next_boost_position;  //make circular
+				  RateControlledEntity entity = boosted_ref.get( next_boost_position );
+				  next_boost_position++;
+				  num_checked++;
+				  if( entity.canProcess( write_waiter ) ) {  //is ready
+					  return( entity.doProcessing( write_waiter, 0 ));
+				  }
+			  }
+			  
+			  	// give remaining normal peers a chance to use the bandwidth boosted peers couldn't, but prevent
+			  	// more from being allocated while doing so to prevent them from grabbing more than they should
+			  
+			  net_man.getUploadProcessor().setRateLimiterFreezeState( true );
 
-    return null;  //none found ready
+		  }else{
+			  
+			  booster_normal_written = 0;
+		  }
+		  	  
+		  ArrayList<RateControlledEntity> normal_ref = normal_priority_entities;
+	
+		  int normal_size = normal_ref.size();
+		  
+		  int num_checked = 0;
+	
+		  while( num_checked < normal_size ) {
+			  next_normal_position = next_normal_position >= normal_size ? 0 : next_normal_position;  //make circular
+			  RateControlledEntity entity = (RateControlledEntity)normal_ref.get( next_normal_position );
+			  next_normal_position++;
+			  num_checked++;
+			  if( entity.canProcess( write_waiter ) ) {  //is ready
+				  int bytes = entity.doProcessing( write_waiter, 0 );
+				  
+				  if ( bytes > 0 ){
+										  
+					  booster_normal_written += bytes;
+				  }
+				  
+				  return( bytes );
+			  }
+		  }
+	
+		  return( -1 );
+		  
+	  }finally{
+		  
+		  if ( boosted_size > 0 ){
+			  
+			  net_man.getUploadProcessor().setRateLimiterFreezeState( false );
+		  }
+	  }
   }
   
   
@@ -354,14 +610,20 @@ public class WriteController implements AzureusCoreStatsProvider{
         high_priority_entities = high_new;
       }
       else {
-        //copy-on-write
-        ArrayList norm_new = new ArrayList( normal_priority_entities.size() + 1 );
-        norm_new.addAll( normal_priority_entities );
-        norm_new.add( entity );
-        normal_priority_entities = norm_new;
+        if ( entity.getPriorityBoost()){
+	        ArrayList boost_new = new ArrayList( boosted_priority_entities.size() + 1 );
+	        boost_new.addAll( boosted_priority_entities );
+	        boost_new.add( entity );
+	        boosted_priority_entities = boost_new;
+        }else{
+	        ArrayList norm_new = new ArrayList( normal_priority_entities.size() + 1 );
+	        norm_new.addAll( normal_priority_entities );
+	        norm_new.add( entity );
+	        normal_priority_entities = norm_new;
+        }
       }
       
-      entity_count = normal_priority_entities.size() + high_priority_entities.size();
+      entity_count = normal_priority_entities.size() + boosted_priority_entities.size() + high_priority_entities.size();
     }
     finally {  entities_mon.exit();  }
   }
@@ -381,12 +643,18 @@ public class WriteController implements AzureusCoreStatsProvider{
       }
       else {
         //copy-on-write
-        ArrayList norm_new = new ArrayList( normal_priority_entities );
-        norm_new.remove( entity );
-        normal_priority_entities = norm_new;
+    	if ( boosted_priority_entities.contains( entity )){
+	        ArrayList boosted_new = new ArrayList( boosted_priority_entities );
+	        boosted_new.remove( entity );
+	        boosted_priority_entities = boosted_new;
+    	}else{
+	        ArrayList norm_new = new ArrayList( normal_priority_entities );
+	        norm_new.remove( entity );
+	        normal_priority_entities = norm_new;
+    	}
       }
       
-      entity_count = normal_priority_entities.size() + high_priority_entities.size();
+      entity_count = normal_priority_entities.size() + boosted_priority_entities.size() + high_priority_entities.size();
     }
     finally {  entities_mon.exit();  }
   }
diff --git a/com/aelitis/azureus/core/networkmanager/impl/http/HTTPNetworkManager.java b/com/aelitis/azureus/core/networkmanager/impl/http/HTTPNetworkManager.java
index bf3292f..7b45b78 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/http/HTTPNetworkManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/http/HTTPNetworkManager.java
@@ -40,6 +40,7 @@ import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.peer.impl.PEPeerTransport;
 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
 import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.core.networkmanager.NetworkConnection;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
@@ -733,7 +734,7 @@ HTTPNetworkManager
 										Logger.log(new LogEvent(LOGID, "HTTP connection from " + connection.getEndpoint().getNotionalAddress() + " closed" ));
 				   					}   					
 
-									connection.close();
+									connection.close( null );
 					  			}
 					  			
 					  			return( written > 0 );
@@ -746,7 +747,7 @@ HTTPNetworkManager
 									Logger.log(new LogEvent(LOGID, "HTTP connection from " + connection.getEndpoint().getNotionalAddress() + " failed to write error '" + data + "'" ));
 			   					}   					
 
-					  			connection.close();
+					  			connection.close(e==null?null:Debug.getNestedExceptionMessage(e));
 					  			
 					  			return( false );
 					  		}
@@ -764,7 +765,7 @@ HTTPNetworkManager
 								Logger.log(new LogEvent(LOGID, "HTTP connection from " + connection.getEndpoint().getNotionalAddress() + " failed to write error '" + data + "'" ));
 		   					}   					
 
-				        	connection.close();
+				        	connection.close(msg==null?null:Debug.getNestedExceptionMessage(msg));
 				        }
 					},
 					null );
@@ -774,7 +775,7 @@ HTTPNetworkManager
 					Logger.log(new LogEvent(LOGID, "HTTP connection from " + connection.getEndpoint().getNotionalAddress() + " closed" ));
    				}   					
 
-				connection.close();
+				connection.close( null );
 			}
 		}catch( Throwable e ){
 			
@@ -782,7 +783,7 @@ HTTPNetworkManager
 				Logger.log(new LogEvent(LOGID, "HTTP connection from " + connection.getEndpoint().getNotionalAddress() + " failed to write error '" + data + "'" ));
 			}   					
 
-			connection.close();
+			connection.close(e==null?null:Debug.getNestedExceptionMessage(e));
 		}
 	}
 	
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/IncomingSocketChannelManager.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/IncomingSocketChannelManager.java
index d74e5ef..b35ee2e 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/IncomingSocketChannelManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/IncomingSocketChannelManager.java
@@ -44,6 +44,8 @@ import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.Transport;
 import com.aelitis.azureus.core.networkmanager.VirtualServerChannelSelector;
 import com.aelitis.azureus.core.networkmanager.VirtualServerChannelSelectorFactory;
@@ -461,7 +463,7 @@ public class IncomingSocketChannelManager
 
 	ConnectionEndpoint	co_ep = new ConnectionEndpoint(tcp_address);
 
-	ProtocolEndpointTCP	pe_tcp = new ProtocolEndpointTCP( co_ep, tcp_address );
+	ProtocolEndpointTCP	pe_tcp = (ProtocolEndpointTCP)ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, co_ep, tcp_address );
 
 	Transport transport = new TCPTransportImpl( pe_tcp, filter );
 	
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/LightweightTCPTransport.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/LightweightTCPTransport.java
index 6344a99..2fbbd6d 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/LightweightTCPTransport.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/LightweightTCPTransport.java
@@ -27,6 +27,7 @@ import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
 
 import com.aelitis.azureus.core.networkmanager.EventWaiter;
+import com.aelitis.azureus.core.networkmanager.NetworkConnection;
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
 import com.aelitis.azureus.core.networkmanager.Transport;
 import com.aelitis.azureus.core.networkmanager.TransportEndpoint;
@@ -101,4 +102,17 @@ public class LightweightTCPTransport implements Transport {
   public String getEncryption(boolean verbose){ return( filter.getName(verbose)); }
   public boolean isEncrypted(){ return( filter.isEncrypted());}
   public boolean isTCP(){ return true; }
+  public String getProtocol(){ return "TCP"; }
+  
+  public void
+  bindConnection(
+	NetworkConnection	connection )
+  {
+  }
+  
+  public void
+  unbindConnection(
+	NetworkConnection	connection )
+  {  
+  }
 }
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/ProtocolEndpointTCP.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/ProtocolEndpointTCP.java
index fbab16e..f2d54ba 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/ProtocolEndpointTCP.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/ProtocolEndpointTCP.java
@@ -26,8 +26,12 @@ import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.SocketChannel;
 
+import org.gudy.azureus2.core3.util.AddressUtils;
+
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointHandler;
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.Transport;
 import com.aelitis.azureus.core.networkmanager.Transport.ConnectListener;
 
@@ -35,10 +39,39 @@ public class
 ProtocolEndpointTCP 
 	implements ProtocolEndpoint
 {
+	public static void
+	register()
+	{
+		ProtocolEndpointFactory.registerHandler(
+			new ProtocolEndpointHandler()
+			{
+				public int
+				getType()
+				{
+					return( ProtocolEndpoint.PROTOCOL_TCP );
+				}
+				
+				public ProtocolEndpoint
+				create(
+					InetSocketAddress		address )
+				{
+					return( new ProtocolEndpointTCP( address ));
+				}
+				
+				public ProtocolEndpoint
+				create(
+					ConnectionEndpoint		connection_endpoint,
+					InetSocketAddress		address )
+				{
+					return( new ProtocolEndpointTCP( connection_endpoint, address ));
+				}
+			});
+	}
+	
 	private ConnectionEndpoint		ce;
 	private InetSocketAddress		address;
 	
-	public
+	private
 	ProtocolEndpointTCP(
 		ConnectionEndpoint		_ce,
 		InetSocketAddress		_address )
@@ -49,7 +82,7 @@ ProtocolEndpointTCP
 		ce.addProtocol( this );
 	}
 	
-	public
+	private
 	ProtocolEndpointTCP(
 		InetSocketAddress		_address )
 	{
@@ -86,6 +119,13 @@ ProtocolEndpointTCP
 		return( address );
 	}
 	
+	public InetSocketAddress 
+	getAdjustedAddress(
+		boolean to_lan )
+	{
+		return( AddressUtils.adjustTCPAddress( address, to_lan ));
+	}
+	
 	public Transport
 	connectOutbound(
 		boolean				connect_with_crypto, 
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPConnectionManager.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPConnectionManager.java
index edb4d5b..89642a6 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPConnectionManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPConnectionManager.java
@@ -54,7 +54,7 @@ public class TCPConnectionManager {
   private static final LogIDs LOGID = LogIDs.NWMAN;
 
   private static int MIN_SIMULTANIOUS_CONNECT_ATTEMPTS = 3;  
-  public static int MAX_SIMULTANIOUS_CONNECT_ATTEMPTS = 5;  //NOTE: WinXP SP2 limits to 10 max at any given time
+  public static int MAX_SIMULTANIOUS_CONNECT_ATTEMPTS;
   
   private static int max_outbound_connections;
   
@@ -98,7 +98,7 @@ public class TCPConnectionManager {
   }
   
   
-  private static final int CONNECT_ATTEMPT_TIMEOUT = 30*1000;  //30sec
+  private static final int CONNECT_ATTEMPT_TIMEOUT = 15*1000;  // parg: reduced from 30 sec as almost never see worthwhile connections take longer that this
   private static final int CONNECT_ATTEMPT_STALL_TIME = 3*1000;  //3sec
   private static final boolean SHOW_CONNECT_STATS = false;
   
@@ -115,10 +115,31 @@ public class TCPConnectionManager {
 					ConnectionRequest r1, 
 					ConnectionRequest r2 )
 				{
+					if ( r1 == r2 ){
+						
+						return( 0 );
+					}
+					
 					int	res = r1.getPriority() - r2.getPriority();
 					
 					if ( res == 0 ){
 						
+							// check for duplicates
+							// erm, no, think of the socks data proxy connections luke
+						
+						/*
+						InetSocketAddress a1 = r1.address;
+						InetSocketAddress a2 = r2.address;
+						
+						if ( a1.getPort() == a2.getPort()){
+						
+							if ( Arrays.equals( a1.getAddress().getAddress(), a2.getAddress().getAddress())){
+								
+								return( 0 );
+							}
+						}
+						*/
+						
 						res = r1.getRandom() - r2.getRandom();
 						
 						if ( res == 0 ){
@@ -260,7 +281,7 @@ public class TCPConnectionManager {
   addNewRequest( 
 	final ConnectionRequest request ) 
   {
-	  request.listener.connectAttemptStarted();
+	  request.setConnectTimeout( request.listener.connectAttemptStarted( request.getConnectTimeout()));
 
 
 	  boolean ipv6problem = false;
@@ -337,7 +358,7 @@ public class TCPConnectionManager {
 		  }
 
 		  request.channel.configureBlocking( false );
-		  request.connect_start_time = SystemTime.getCurrentTime();
+		  request.connect_start_time = SystemTime.getMonotonousTime();
 
 		  if ( request.channel.connect( request.address ) ) {  //already connected
 
@@ -356,7 +377,7 @@ public class TCPConnectionManager {
 
 				  new_canceled_mon.exit();
 			  }
-
+			  
 			  connect_selector.register( 
 					  request.channel, 
 					  new VirtualChannelSelector.VirtualSelectorListener() 
@@ -366,7 +387,7 @@ public class TCPConnectionManager {
 								  VirtualChannelSelector 	selector, 
 								  SocketChannel 			sc, 
 								  Object 					attachment ) 
-						  {       
+						  {    
 							  try{
 								  new_canceled_mon.enter();
 
@@ -464,7 +485,7 @@ public class TCPConnectionManager {
 
 			  if( SHOW_CONNECT_STATS ) {
 				  long queue_wait_time = request.connect_start_time - request.request_start_time;
-				  long connect_time = SystemTime.getCurrentTime() - request.connect_start_time;
+				  long connect_time = SystemTime.getMonotonousTime() - request.connect_start_time;
 				  int num_queued = new_requests.size();
 				  int num_connecting = pending_attempts.size();
 				  System.out.println("S: queue_wait_time="+queue_wait_time+
@@ -509,7 +530,7 @@ public class TCPConnectionManager {
 
 		  if( SHOW_CONNECT_STATS ) {
 			  long queue_wait_time = request.connect_start_time - request.request_start_time;
-			  long connect_time = SystemTime.getCurrentTime() - request.connect_start_time;
+			  long connect_time = SystemTime.getMonotonousTime() - request.connect_start_time;
 			  int num_queued = new_requests.size();
 			  int num_connecting = pending_attempts.size();
 			  System.out.println("F: queue_wait_time="+queue_wait_time+
@@ -570,7 +591,7 @@ public class TCPConnectionManager {
     //do connect attempt timeout checks
     int num_stalled_requests =0;
     
-    final long now =SystemTime.getCurrentTime();
+    final long now =SystemTime.getMonotonousTime();
     
     List<ConnectionRequest> timeouts = null;
     try{
@@ -667,7 +688,7 @@ public class TCPConnectionManager {
     try{
     	pending_closes_mon.enter();
     
-    	long	now = SystemTime.getCurrentTime();
+    	long	now = SystemTime.getMonotonousTime();
     	
     	if ( delayed_closes.size() > 0 ){
     		   		
@@ -725,10 +746,24 @@ public class TCPConnectionManager {
   requestNewConnection( 
 	  InetSocketAddress 	address, 
 	  ConnectListener 		listener, 
-	  long					connect_timeout, 
+	  int					connect_timeout, 
 	  int 					priority )
-  {    
-	  List<ConnectionRequest>	kicked = null;
+  {   
+	  if ( address.getPort() == 0 ){
+		  
+		  try{
+			  listener.connectFailure( new Exception( "Invalid port, connection to " + address + " abandoned" ));
+			  
+		  }catch( Throwable e ){
+			  
+			  Debug.out( e );
+		  }
+		  
+		  return;
+	  }
+	  
+	  List<ConnectionRequest>	kicked 		= null;
+	  boolean					duplicate	= false;
 	  
 	  try{
 		  new_canceled_mon.enter();
@@ -739,36 +774,45 @@ public class TCPConnectionManager {
 
 		  ConnectionRequest cr = new ConnectionRequest( connection_request_id_next++, address, listener, connect_timeout, priority );
 
-		  new_requests.add( cr );
-
-		  if ( new_requests.size() >= max_outbound_connections ){
-
-			  if ( !max_conn_exceeded_logged ){
-
-				  max_conn_exceeded_logged = true;
-
-				  Debug.out( "TCPConnectionManager: max outbound connection limit reached (" + max_outbound_connections + ")" );
+		  	// this comparison is via Comparator and will weed out same address being added > once
+		  
+		  if ( new_requests.contains( cr )){
+			  
+			  duplicate = true;
+			  
+		  }else{
+			  
+			  new_requests.add( cr );
+  
+			  if ( new_requests.size() >= max_outbound_connections ){
+	
+				  if ( !max_conn_exceeded_logged ){
+	
+					  max_conn_exceeded_logged = true;
+	
+					  Debug.out( "TCPConnectionManager: max outbound connection limit reached (" + max_outbound_connections + ")" );
+				  }
 			  }
-		  }
-
-		  if ( priority == ProtocolEndpoint.CONNECT_PRIORITY_HIGHEST ){
-
-			  for (Iterator<ConnectionRequest> pen_it = pending_attempts.keySet().iterator(); pen_it.hasNext();){
-
-				  ConnectionRequest request =(ConnectionRequest) pen_it.next();
-
-				  if ( request.priority == ProtocolEndpoint.CONNECT_PRIORITY_LOW ){
-
-					  if ( !canceled_requests.contains( request.listener )){
-					  
-						  canceled_requests.add( request.listener );
-					  
-						  if ( kicked == null ){
+	
+			  if ( priority == ProtocolEndpoint.CONNECT_PRIORITY_HIGHEST ){
+	
+				  for (Iterator<ConnectionRequest> pen_it = pending_attempts.keySet().iterator(); pen_it.hasNext();){
+	
+					  ConnectionRequest request =(ConnectionRequest) pen_it.next();
+	
+					  if ( request.priority == ProtocolEndpoint.CONNECT_PRIORITY_LOW ){
+	
+						  if ( !canceled_requests.contains( request.listener )){
+						  
+							  canceled_requests.add( request.listener );
+						  
+							  if ( kicked == null ){
+							  
+								  kicked = new ArrayList<ConnectionRequest>();
+							  }
 						  
-							  kicked = new ArrayList<ConnectionRequest>();
+							  kicked.add( request );
 						  }
-					  
-						  kicked.add( request );
 					  }
 				  }
 			  }
@@ -778,6 +822,17 @@ public class TCPConnectionManager {
 		  new_canceled_mon.exit();
 	  }
 	  
+	  if ( duplicate ){
+		  
+		  try{
+			  listener.connectFailure( new Exception( "Connection request already queued for " + address ));
+			  
+		  }catch( Throwable e ){
+			  
+			  Debug.out( e );
+		  }
+	  }
+	  
 	  if ( kicked != null ){
 		  
 		  for (int i=0;i<kicked.size();i++){
@@ -824,7 +879,7 @@ public class TCPConnectionManager {
 			  }
 		  }else{
 
-			  delayed_closes.put( channel, new Long( SystemTime.getCurrentTime() + delay ));
+			  delayed_closes.put( channel, new Long( SystemTime.getMonotonousTime() + delay ));
 		  }
 	  }finally{
 
@@ -859,28 +914,43 @@ public class TCPConnectionManager {
   
   
 
-  private static class ConnectionRequest {
+  private static class 
+  ConnectionRequest 
+  {
     private final InetSocketAddress address;
     private final ConnectListener listener;
     private final long request_start_time;
     private long connect_start_time;
-    private final long connect_timeout;
+    private int connect_timeout;
     private SocketChannel channel;
     private final short		rand;
     private final int		priority;
     private final long		id;
         
-    private ConnectionRequest( long _id, InetSocketAddress _address, ConnectListener _listener, long _connect_timeout, int _priority  ) {
+    private ConnectionRequest( long _id, InetSocketAddress _address, ConnectListener _listener, int _connect_timeout, int _priority  ) {
 
       id	= _id;
       address = _address;
       listener = _listener;
       connect_timeout	= _connect_timeout;
-      request_start_time = SystemTime.getCurrentTime();
+      request_start_time = SystemTime.getMonotonousTime();
       rand = (short)( Short.MAX_VALUE*Math.random());
       priority = _priority;
     }
     
+    private int
+    getConnectTimeout()
+    {
+    	return( connect_timeout );
+    }
+    
+    private void
+    setConnectTimeout(
+    	int		_ct )
+    {
+    	connect_timeout = _ct;
+    }
+    
     private long
     getID()
     {
@@ -910,8 +980,9 @@ public class TCPConnectionManager {
      /**
       * The connection establishment process has started,
       * i.e. the connection is actively being attempted.
+      * @return adjusted connect timeout
       */
-     public void connectAttemptStarted();    
+     public int connectAttemptStarted( int default_timeout );    
      
      /**
       * The connection attempt succeeded.
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPNetworkManager.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPNetworkManager.java
index 2debce9..d77958c 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPNetworkManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPNetworkManager.java
@@ -56,15 +56,23 @@ TCPNetworkManager
 	public static boolean TCP_OUTGOING_ENABLED;
 	
 	static{
-		COConfigurationManager.addAndFireParameterListener(
-				"TCP.Listen.Port.Enable",
+		COConfigurationManager.addAndFireParameterListeners(
+				new String[]{
+					"TCP.Listen.Port.Enable",
+					"network.tcp.connect.outbound.enable"
+				},
 				new ParameterListener()
 				{
 					public void 
 					parameterChanged(
 						String name )
 					{
-						TCP_INCOMING_ENABLED = TCP_OUTGOING_ENABLED = COConfigurationManager.getBooleanParameter( name );
+						TCP_INCOMING_ENABLED = TCP_OUTGOING_ENABLED = COConfigurationManager.getBooleanParameter( "TCP.Listen.Port.Enable" );
+						
+						if ( TCP_OUTGOING_ENABLED ){
+							
+							TCP_OUTGOING_ENABLED = COConfigurationManager.getBooleanParameter( "network.tcp.connect.outbound.enable" );
+						}
 					}
 				});
 		
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportHelper.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportHelper.java
index ccea1a0..2ca9811 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportHelper.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportHelper.java
@@ -45,7 +45,7 @@ TCPTransportHelper
 	implements TransportHelper
 {
 	public static final int READ_TIMEOUT		= 10*1000;
-	public static final int CONNECT_TIMEOUT		= 60*1000;
+	public static final int CONNECT_TIMEOUT		= 20*1000;
 	  
 	public static final int MAX_PARTIAL_WRITE_RETAIN	= 64;	// aim here is to catch headers
 	
@@ -61,6 +61,8 @@ TCPTransportHelper
 	
 	private boolean	trace;
 	
+	private volatile boolean closed;
+	
 	public TCPTransportHelper( SocketChannel _channel ) {
 		channel = _channel;
 	}
@@ -537,9 +539,17 @@ TCPTransportHelper
 		TCPNetworkManager.getSingleton().getWriteSelector().pauseSelects( channel );
 	}
 
+	public boolean
+	isClosed()
+	{
+		return( closed );
+	}
+	
 	public void
 	close( String reason )
 	{
+		closed = true;
+		
 		TCPNetworkManager.getSingleton().getReadSelector().cancel( channel );
 		TCPNetworkManager.getSingleton().getWriteSelector().cancel( channel );
 		TCPNetworkManager.getSingleton().getConnectDisconnectManager().closeConnection( channel );
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportImpl.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportImpl.java
index 34f738d..a492615 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/TCPTransportImpl.java
@@ -139,6 +139,8 @@ public class TCPTransportImpl extends TransportImpl implements Transport {
 	  return( true );
   }
 	
+  public String getProtocol(){ return "TCP"; }
+  
   /**
    * Get a textual description for this transport.
    * @return description
@@ -162,7 +164,12 @@ public class TCPTransportImpl extends TransportImpl implements Transport {
 		return;
 	}
 	
-    if( has_been_closed )  return;
+    if( has_been_closed ){
+    	
+		listener.connectFailure( new Throwable( "Connection already closed" ));
+
+    	return;
+    }
     
     if( getFilter() != null ) {  //already connected
       Debug.out( "socket_channel != null" );
@@ -176,8 +183,9 @@ public class TCPTransportImpl extends TransportImpl implements Transport {
     final InetSocketAddress	address = protocol_endpoint.getAddress();
     
     TCPConnectionManager.ConnectListener connect_listener = new TCPConnectionManager.ConnectListener() {
-      public void connectAttemptStarted() {
-        listener.connectAttemptStarted();
+      public int connectAttemptStarted(
+    		  int default_connect_timeout ) {
+        return( listener.connectAttemptStarted( default_connect_timeout ));
       }
       
       public void connectSuccess( final SocketChannel channel ) {
@@ -189,7 +197,10 @@ public class TCPTransportImpl extends TransportImpl implements Transport {
       	}
       	
         if( has_been_closed ) {  //closed between select ops
-          TCPNetworkManager.getSingleton().getConnectDisconnectManager().closeConnection( channel );  //just close it
+        	TCPNetworkManager.getSingleton().getConnectDisconnectManager().closeConnection( channel );  //just close it
+          
+  			listener.connectFailure( new Throwable( "Connection has been closed" ));
+
           return;
         }
         
diff --git a/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java b/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
index 7b79062..73e9474 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/tcp/VirtualChannelSelectorImpl.java
@@ -22,6 +22,8 @@
 package com.aelitis.azureus.core.networkmanager.impl.tcp;
 
 
+import java.net.InetAddress;
+import java.net.Socket;
 import java.nio.channels.*;
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.util.*;
@@ -56,9 +58,7 @@ public class VirtualChannelSelectorImpl {
 		boolean is_freebsd_7_or_higher = false;
 		
 			// hack for 10.6 - will switch to not doing System.setProperty( "java.nio.preferSelect", "true" ); later
-		
-		boolean	is_osx_16	= false;
-		
+				
 		try{
 				// unfortunately the package maintainer has set os.name to Linux for FreeBSD...
 			
@@ -91,25 +91,17 @@ public class VirtualChannelSelectorImpl {
 						is_freebsd_7_or_higher = Integer.parseInt(digits) >= 7;
 					}	
 				}
-			}else if ( Constants.isOSX ){
-				
-				String os_version = System.getProperty( "os.version", "" );
-				
-				if ( os_version.startsWith( "10.6" )){
-					
-					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 || Constants.isOSX_10_6_OrHigher;
 		
 		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+=" + Constants.isOSX_10_6_OrHigher );
 		}
 	}
 	
@@ -574,7 +566,12 @@ public class VirtualChannelSelectorImpl {
     		
     		last_select_debug = now;
     		
-    		Debug.out( "Caught exception on selector.select() op: " +t.getMessage(), t );
+    		String msg = t.getMessage();
+    		
+    		if ( msg == null || !msg.equalsIgnoreCase( "bad file descriptor" )){
+    		
+    			Debug.out( "Caught exception on selector.select() op: " +msg, t );
+    		}
     	}
         try {  Thread.sleep( timeout );  }catch(Throwable e) { e.printStackTrace(); }
       }
@@ -725,8 +722,14 @@ public class VirtualChannelSelectorImpl {
         	// rm_type = 2;
           }else{            
             
-	          if( pause_after_select ) { 
-	            key.interestOps( key.interestOps() & ~INTEREST_OP );
+	          if( pause_after_select ) {
+	        	  
+	        	try{
+	        		key.interestOps( key.interestOps() & ~INTEREST_OP );
+	        		
+	        	}catch( CancelledKeyException e ){
+	        		
+	        	}
 	          }
 	                        
 	          boolean	progress_indicator = parent.selectSuccess( data.listener, data.channel, data.attachment );
@@ -744,31 +747,68 @@ public class VirtualChannelSelectorImpl {
 	        	// rm_type = 1;
 	        	  
 	            data.non_progress_count++;
+
+	            boolean	loopback_connection = false;
+	            
+	        	if ( INTEREST_OP != VirtualChannelSelector.OP_ACCEPT ){
 	            	
-	            if ( 	data.non_progress_count == 10 ||
-	            		data.non_progress_count %100 == 0 && data.non_progress_count > 0 ){
-	            		
-	              Debug.out( 
-	                  "VirtualChannelSelector: No progress for op " + INTEREST_OP + 
-	                  	": listener = " + data.listener.getClass() + 
-	                  	", count = " + data.non_progress_count +
-	                  	", socket: open = " + data.channel.isOpen() + 
-	                  		(INTEREST_OP==VirtualChannelSelector.OP_ACCEPT?"":
-	                  			(", connected = " + ((SocketChannel)data.channel).isConnected())));
-	                			  
-	            		
-	              if ( data.non_progress_count == 1000 ){
-	                
-	                Debug.out( "No progress for " + data.non_progress_count + ", closing connection" );
-	            			
-	                try{
-	                  data.channel.close();
-	            				
-	                }catch( Throwable e ){
-	            				e.printStackTrace();
-	                }
-	              }
-	            }
+	        		SocketChannel sc = (SocketChannel)data.channel;
+	        		
+	        		Socket socket = sc.socket();
+	        		
+	        		InetAddress address = socket.getInetAddress();
+	        		
+	        		if ( address != null ){
+	        			
+	        			loopback_connection = address.isLoopbackAddress();
+	        		}
+	        	}
+	        	
+	        		// we get no progress triggers when looping back for transcoding due to 
+	        		// high CPU usage of xcode process - remove debug spew and be more tolerant
+	        	
+	        	if ( loopback_connection ){
+	        		
+	        		if ( data.non_progress_count == 10000 ){
+
+	        			Debug.out( "No progress for " + data.non_progress_count + ", closing connection" );
+
+	        			try{
+	        				data.channel.close();
+
+	        			}catch( Throwable e ){
+
+	        				e.printStackTrace();
+	        			}
+	        		}
+	        	}else{
+	        		
+	        		if ( 	data.non_progress_count == 10 ||
+	        				data.non_progress_count %100 == 0 && data.non_progress_count > 0 ){
+
+	        			Debug.out( 
+	        					"VirtualChannelSelector: No progress for op " + INTEREST_OP + 
+	        					": listener = " + data.listener.getClass() + 
+	        					", count = " + data.non_progress_count +
+	        					", socket: open = " + data.channel.isOpen() + 
+	        					(INTEREST_OP==VirtualChannelSelector.OP_ACCEPT?"":
+	        						(", connected = " + ((SocketChannel)data.channel).isConnected())));
+
+
+	        			if ( data.non_progress_count == 1000 ){
+
+	        				Debug.out( "No progress for " + data.non_progress_count + ", closing connection" );
+
+	        				try{
+	        					data.channel.close();
+
+	        				}catch( Throwable e ){
+	        					
+	        					e.printStackTrace();
+	        				}
+	        			}
+	        		}
+	        	}
 	          }
 	        }
         }else{
@@ -805,10 +845,17 @@ public class VirtualChannelSelectorImpl {
     	    
     	      RegistrationData data = (RegistrationData)key.attachment();
  
-        	  if (( key.interestOps() & INTEREST_OP) == 0 ) { 
-
-        		  continue;
-        	  }
+    	      try{
+	        	  if (( key.interestOps() & INTEREST_OP) == 0 ) { 
+	
+	        		  continue;
+	        	  }
+    	      }catch( CancelledKeyException e ){
+    	    	  
+    	    	  		// get quite a few of these exceptions, ignore the key
+    	    	  
+    	    	  continue;
+    	      }
         	  
     	      long	stall_time = now - data.last_select_success_time;
     	      
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/NetworkGlueUDP.java b/com/aelitis/azureus/core/networkmanager/impl/udp/NetworkGlueUDP.java
index 5ec027f..16ca0c6 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/NetworkGlueUDP.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/NetworkGlueUDP.java
@@ -37,13 +37,14 @@ import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread;
 import org.gudy.azureus2.core3.util.Debug;
 
+import com.aelitis.azureus.core.util.AEPriorityMixin;
 import com.aelitis.net.udp.uc.PRUDPPacketHandler;
 import com.aelitis.net.udp.uc.PRUDPPacketHandlerFactory;
 import com.aelitis.net.udp.uc.PRUDPPrimordialHandler;
 
 public class 
 NetworkGlueUDP
-	implements NetworkGlue, PRUDPPrimordialHandler
+	implements NetworkGlue, PRUDPPrimordialHandler, AEPriorityMixin
  
 {
 	private static final LogIDs LOGID = LogIDs.NET;
@@ -87,14 +88,14 @@ NetworkGlueUDP
 								
 								Logger.log(new LogEvent(LOGID, "Deactivating UDP listener on port " + handler.getPort()));
 
-								handler.setPrimordialHandler( null );
+								handler.removePrimordialHandler( NetworkGlueUDP.this );
 							}
 
 							Logger.log(new LogEvent(LOGID, "Activating UDP listener on port " + port ));
 								
 							handler = PRUDPPacketHandlerFactory.getHandler( port );
 	
-							handler.setPrimordialHandler( NetworkGlueUDP.this );
+							handler.addPrimordialHandler( NetworkGlueUDP.this );
 						}
 					}else{
 						
@@ -102,7 +103,7 @@ NetworkGlueUDP
 							
 							Logger.log(new LogEvent(LOGID, "Deactivating UDP listener on port " + handler.getPort()));
 							
-							handler.setPrimordialHandler( null );
+							handler.removePrimordialHandler( NetworkGlueUDP.this );
 						}
 					}
 				}
@@ -155,6 +156,12 @@ NetworkGlueUDP
 		}.start();
 	}
 	
+	public int 
+	getPriority() 
+	{
+		return( AEPriorityMixin.PRIORITY_LOW );
+	}
+	
 	public boolean
 	packetReceived(
 		DatagramPacket	packet )
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/ProtocolEndpointUDP.java b/com/aelitis/azureus/core/networkmanager/impl/udp/ProtocolEndpointUDP.java
index 9ce3e47..7861650 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/ProtocolEndpointUDP.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/ProtocolEndpointUDP.java
@@ -25,8 +25,12 @@ package com.aelitis.azureus.core.networkmanager.impl.udp;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 
+import org.gudy.azureus2.core3.util.AddressUtils;
+
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointHandler;
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.Transport;
 import com.aelitis.azureus.core.networkmanager.Transport.ConnectListener;
 
@@ -34,10 +38,39 @@ public class
 ProtocolEndpointUDP 
 	implements ProtocolEndpoint
 {
+	public static void
+	register()
+	{
+		ProtocolEndpointFactory.registerHandler(
+			new ProtocolEndpointHandler()
+			{
+				public int
+				getType()
+				{
+					return( ProtocolEndpoint.PROTOCOL_UDP );
+				}
+				
+				public ProtocolEndpoint
+				create(
+					InetSocketAddress		address )
+				{
+					return( new ProtocolEndpointUDP( address ));
+				}
+				
+				public ProtocolEndpoint
+				create(
+					ConnectionEndpoint		connection_endpoint,
+					InetSocketAddress		address )
+				{
+					return( new ProtocolEndpointUDP( connection_endpoint, address ));
+				}
+			});
+	}
+	
 	private ConnectionEndpoint		ce;
 	private InetSocketAddress		address;
 	
-	public
+	private
 	ProtocolEndpointUDP(
 		ConnectionEndpoint		_ce,
 		InetSocketAddress		_address )
@@ -48,7 +81,7 @@ ProtocolEndpointUDP
 		ce.addProtocol( this );
 	}
 	
-	public
+	private
 	ProtocolEndpointUDP(
 		InetSocketAddress		_address )
 	{
@@ -79,6 +112,13 @@ ProtocolEndpointUDP
 		return( address );
 	}
 	
+	public InetSocketAddress 
+	getAdjustedAddress(
+		boolean to_lan )
+	{
+		return( AddressUtils.adjustUDPAddress( address, to_lan ));
+	}
+	
 	public ConnectionEndpoint
 	getConnectionEndpoint()
 	{
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
index 7e2c6ba..8138fdd 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionManager.java
@@ -38,6 +38,8 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemTime;
 
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.Transport.ConnectListener;
 import com.aelitis.azureus.core.networkmanager.impl.IncomingConnectionManager;
 import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoder;
@@ -136,7 +138,12 @@ UDPConnectionManager
 		UDPTransportHelper	helper = null;
 
 		try{
-			listener.connectAttemptStarted();
+			int time = listener.connectAttemptStarted( -1 );
+			
+			if ( time != -1 ){
+				
+				Debug.out( "UDP connect time override not supported" );
+			}
 			
 			helper = new UDPTransportHelper( this, address, udp_transport );
 	 		
@@ -617,7 +624,7 @@ UDPConnectionManager
 						
 						ConnectionEndpoint	co_ep = new ConnectionEndpoint( remote_address);
 	
-						ProtocolEndpointUDP	pe_udp = new ProtocolEndpointUDP( co_ep, remote_address );
+						ProtocolEndpointUDP	pe_udp = (ProtocolEndpointUDP)ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_UDP, co_ep, remote_address );
 	
 						UDPTransport transport = new UDPTransport( pe_udp, filter );
 								
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionSet.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionSet.java
index 3bc9f09..ed1b85a 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionSet.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPConnectionSet.java
@@ -46,8 +46,6 @@ public class
 UDPConnectionSet 
 {
 	private static final LogIDs LOGID = LogIDs.NET;
-
-	public static final int PROTOCOL_DATA_HEADER_SIZE	= 30;
 	
 	private static final boolean	DEBUG_SEQUENCES	= false;
 	
@@ -66,7 +64,8 @@ UDPConnectionSet
 	private static final int MIN_MSS	= 256;
 	private static final int MAX_HEADER	= 128;
 	
-	public static final int MIN_WRITE_PAYLOAD	= MIN_MSS - MAX_HEADER;
+	public static final int MIN_WRITE_PAYLOAD		= MIN_MSS - MAX_HEADER;
+	public static final int MAX_BUFFERED_PAYLOAD	= 512;
 		
 	private UDPConnectionManager	manager;
 	private UDPSelector				selector;
@@ -925,7 +924,7 @@ UDPConnectionSet
 		
 		byte[]	payload = packet.getBuffer();
 			
-		if ( manager.trace() ){
+		if ( manager.trace()){
 			trace( packet.getConnection(), "Write: " + packet.getString());
 		}
 						
@@ -1600,10 +1599,8 @@ UDPConnectionSet
 			header_buffer.putInt( connection.getID());
 			
 			int header_size = writeHeaderEnd( header_buffer, false );
-						
-				// we get to add the header back in here to give the total packet size available
-			
-			int	mss = connection.getTransport().getMss() + UDPNetworkManager.PROTOCOL_HEADER_SIZE;
+									
+			int	mss = connection.getTransport().getMss();
 	
 				// just in case we have some crazy limit set
 			
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPNetworkManager.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPNetworkManager.java
index daa77dd..2e9d73e 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPNetworkManager.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPNetworkManager.java
@@ -35,8 +35,6 @@ import com.aelitis.net.udp.uc.PRUDPPacket;
 public class 
 UDPNetworkManager 
 {
-	public static final int		PROTOCOL_HEADER_SIZE	= UDPConnectionSet.PROTOCOL_DATA_HEADER_SIZE;
-	
 	public static final boolean	MINIMISE_OVERHEADS	= true;
 	
 	public static final int MIN_INCOMING_INITIAL_PACKET_SIZE = ProtocolDecoderPHE.MIN_INCOMING_INITIAL_PACKET_SIZE;
@@ -70,7 +68,7 @@ UDPNetworkManager
 	refreshRates(
 		int		min_rate )
 	{
-		udp_mss_size = COConfigurationManager.getIntParameter( "network.udp.mtu.size" ) - PROTOCOL_HEADER_SIZE; 	        
+		udp_mss_size = COConfigurationManager.getIntParameter( "network.udp.mtu.size" ) - 40; 	        
 
 	    if( udp_mss_size > min_rate )  udp_mss_size = min_rate - 1;
 	    
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransport.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransport.java
index de296e2..b738d2e 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransport.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransport.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.networkmanager.impl.udp;
 
 import java.nio.ByteBuffer;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.logging.LogIDs;
 
 import com.aelitis.azureus.core.networkmanager.TransportEndpoint;
@@ -68,6 +69,12 @@ UDPTransport
 		return( false );
 	}
 	
+	public String 
+	getProtocol()
+	{
+		return "UDP"; 
+	}
+	
 	public TransportEndpoint 
 	getTransportEndpoint()
 	{
@@ -126,6 +133,13 @@ UDPTransport
 			return;
 		}
 		
+		if ( COConfigurationManager.getBooleanParameter( "Proxy.Data.Enable" )){
+			
+			listener.connectFailure( new Throwable( "UDP proxy connection not supported" ));
+			
+			return;
+		}
+		   
 		UDPConnectionManager	con_man = UDPNetworkManager.getSingleton().getConnectionManager();
 		
 		con_man.connectOutbound( this, endpoint.getAddress(), shared_secrets, initial_data, listener);
diff --git a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransportHelper.java b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransportHelper.java
index f7e3005..ba2d586 100644
--- a/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransportHelper.java
+++ b/com/aelitis/azureus/core/networkmanager/impl/udp/UDPTransportHelper.java
@@ -37,7 +37,7 @@ UDPTransportHelper
 	implements TransportHelper
 {
 	public static final int READ_TIMEOUT		= 30*1000;
-	public static final int CONNECT_TIMEOUT		= 60*1000;
+	public static final int CONNECT_TIMEOUT		= 20*1000;
 	
 	private UDPConnectionManager	manager;
 	private UDPSelector				selector;
@@ -59,7 +59,7 @@ UDPTransportHelper
 	private boolean				closed;
 	private IOException			failed;
 	
-	private ByteBuffer			pending_partial_write;
+	private ByteBuffer[]		pending_partial_writes;
 		
 	private Map	user_data;
 	
@@ -173,15 +173,20 @@ UDPTransportHelper
 	delayWrite(
 		ByteBuffer buffer) 
 	{
-			// TODO: support this one day?
+		if ( pending_partial_writes == null ){
+			
+			pending_partial_writes = new ByteBuffer[]{ buffer };
+			
+			return( true );
+		}
 		
-		return false;
+		return( false );
 	}
 	
 	public boolean
 	hasDelayedWrite()
 	{
-		return( false );
+		return( pending_partial_writes != null );
 	}
 	
 	public int 
@@ -204,35 +209,79 @@ UDPTransportHelper
 			}
 		}
 		
-		if ( partial_write ){
+		int	buffer_rem = buffer.remaining();
+		
+		if ( partial_write && buffer_rem < UDPConnectionSet.MIN_WRITE_PAYLOAD ){
 			
-			if ( pending_partial_write == null ){
+			if ( pending_partial_writes == null ){
+				
+				pending_partial_writes = new ByteBuffer[1];
+								
+				ByteBuffer	copy = ByteBuffer.allocate( buffer_rem );
+				
+				copy.put( buffer );
+				
+				copy.position( 0 );
+				
+				pending_partial_writes[0] = copy;
+				
+				return( buffer_rem );
+				
+			}else{
 				
-				if ( buffer.remaining() < UDPConnectionSet.MIN_WRITE_PAYLOAD ){
+				int	queued = 0;
 				
-					ByteBuffer	copy = ByteBuffer.allocate( buffer.remaining());
+				for ( int i=0;i<pending_partial_writes.length;i++){
+					
+					queued += pending_partial_writes[i].remaining();
+				}
+				
+				if ( queued + buffer_rem <= UDPConnectionSet.MAX_BUFFERED_PAYLOAD ){
+					
+					ByteBuffer[] new_ppw = new ByteBuffer[ pending_partial_writes.length+1 ];
+					
+					for (int i=0;i<pending_partial_writes.length;i++){
+						
+						new_ppw[i] = pending_partial_writes[i];
+					}
+					
+					ByteBuffer	copy = ByteBuffer.allocate( buffer_rem );
 					
 					copy.put( buffer );
 					
 					copy.position( 0 );
 					
-					pending_partial_write = copy;
+					new_ppw[pending_partial_writes.length] = copy;
 					
-					return( copy.remaining());
+					pending_partial_writes = new_ppw;
+					
+					return( buffer_rem );
 				}
 			}
 		}
 		
-		if ( pending_partial_write != null ){
+		if ( pending_partial_writes != null ){
 			
-			try{
-				int	pw_len = pending_partial_write.remaining();
+			int	ppw_len = pending_partial_writes.length;
+			int	ppw_rem	= 0;
+			
+			ByteBuffer[]	buffers2 = new ByteBuffer[ppw_len+1];
+			
+			for ( int i=0;i<ppw_len;i++){
 				
-				int	written = connection.write( new ByteBuffer[]{ pending_partial_write, buffer }, 0, 2 );
+				buffers2[i] = pending_partial_writes[i];
 				
-				if ( written >= pw_len ){
+				ppw_rem += buffers2[i].remaining();
+			}
+			
+			buffers2[ppw_len] = buffer;
+			
+			try{
+				int written = connection.write( buffers2, 0, buffers2.length );
+				
+				if ( written >= ppw_rem ){
 					
-					return( written - pw_len );
+					return( written - ppw_rem );
 					
 				}else{
 					
@@ -241,12 +290,18 @@ UDPTransportHelper
 				
 			}finally{
 				
-				if ( pending_partial_write.remaining() == 0 ){
+				ppw_rem	= 0;
+				
+				for ( int i=0;i<ppw_len;i++){
+										
+					ppw_rem += buffers2[i].remaining();
+				}
+				
+				if ( ppw_rem == 0 ){
 					
-					pending_partial_write = null;
+					pending_partial_writes = null;
 				}
 			}
-			
 		}else{
 			
 			return( connection.write( new ByteBuffer[]{ buffer }, 0, 1 ));
@@ -274,13 +329,21 @@ UDPTransportHelper
 			}
 		}
 		
-		if ( pending_partial_write != null ){
+		if ( pending_partial_writes != null ){
+			
+			int	ppw_len = pending_partial_writes.length;
+			int	ppw_rem	= 0;
 			
-			ByteBuffer[]	buffers2 = new ByteBuffer[length+1];
+			ByteBuffer[]	buffers2 = new ByteBuffer[length+ppw_len];
 			
-			buffers2[0] = pending_partial_write;
+			for ( int i=0;i<ppw_len;i++){
+				
+				buffers2[i] = pending_partial_writes[i];
+				
+				ppw_rem += buffers2[i].remaining();
+			}
 			
-			int	pos = 1;
+			int	pos = ppw_len;
 
 			for (int i=array_offset;i<array_offset+length;i++){
 				
@@ -288,13 +351,11 @@ UDPTransportHelper
 			}
 			
 			try{
-				int	pw_len = pending_partial_write.remaining();
-				
 				int written = connection.write( buffers2, 0, buffers2.length );
 				
-				if ( written >= pw_len ){
+				if ( written >= ppw_rem ){
 					
-					return( written - pw_len );
+					return( written - ppw_rem );
 					
 				}else{
 					
@@ -303,9 +364,16 @@ UDPTransportHelper
 				
 			}finally{
 				
-				if ( pending_partial_write.remaining() == 0 ){
+				ppw_rem	= 0;
+				
+				for ( int i=0;i<ppw_len;i++){
+										
+					ppw_rem += buffers2[i].remaining();
+				}
+				
+				if ( ppw_rem == 0 ){
 					
-					pending_partial_write = null;
+					pending_partial_writes = null;
 				}
 			}
 		}else{
@@ -549,6 +617,15 @@ UDPTransportHelper
     	connection.failedSupport( reason );
     }
     
+	public boolean
+	isClosed()
+	{
+		synchronized( this ){
+		
+			return( closed );
+		}
+	}
+	
     public void
     close(
     	String	reason )
diff --git a/com/aelitis/azureus/core/pairing/PairedNode.java b/com/aelitis/azureus/core/pairing/PairedNode.java
new file mode 100644
index 0000000..6c16657
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairedNode.java
@@ -0,0 +1,38 @@
+/*
+ * Created on Jul 1, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 java.net.InetAddress;
+import java.util.List;
+
+public interface 
+PairedNode 
+{
+	public String
+	getAccessCode();
+	
+	public List<InetAddress>
+	getAddresses();
+	
+	public List<PairedService>
+	getServices();
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingConnectionData.java b/com/aelitis/azureus/core/pairing/PairingConnectionData.java
index 611cfdf..4b1cb69 100644
--- a/com/aelitis/azureus/core/pairing/PairingConnectionData.java
+++ b/com/aelitis/azureus/core/pairing/PairingConnectionData.java
@@ -24,11 +24,12 @@ 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 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_PORT_OVERRIDE	= "port_or";
+	public static final String ATTR_PROTOCOL		= "protocol";
+	public static final String ATTR_HOST			= "host";
 	
 	public void
 	setAttribute(
diff --git a/com/aelitis/azureus/core/pairing/PairingManager.java b/com/aelitis/azureus/core/pairing/PairingManager.java
index 2ccaf66..89a4d73 100644
--- a/com/aelitis/azureus/core/pairing/PairingManager.java
+++ b/com/aelitis/azureus/core/pairing/PairingManager.java
@@ -21,18 +21,35 @@
 
 package com.aelitis.azureus.core.pairing;
 
+import java.util.List;
+
 public interface 
 PairingManager 
 {
 	public boolean
 	isEnabled();
 	
+	public void
+	setGroup(
+		String		group );
+	
+	public String
+	getGroup();
+	
+	public List<PairedNode>
+	listGroup()
+	
+		throws PairingException;
+	
 	public String
 	getAccessCode()
 	
 		throws PairingException;
 	
 	public String
+	peekAccessCode();
+	
+	public String
 	getReplacementAccessCode()
 	
 		throws PairingException;
@@ -45,6 +62,32 @@ PairingManager
 	getService(
 		String		sid );
 	
+	public void 
+	setEnabled(
+		boolean enabled );
+
+	public String
+	getStatus();
+
+	public String
+	getLastServerError();
+
+	public boolean
+	hasActionOutstanding();
+	
+	public PairingTest
+	testService(
+		String					sid,
+		PairingTestListener		listener )
+	
+		throws PairingException;
+	
+	public void
+	recordRequest(
+		String		name,
+		String		ip,
+		boolean		good );
+	
 	public void
 	addListener(
 		PairingManagerListener	l );
@@ -52,4 +95,5 @@ PairingManager
 	public void
 	removeListener(
 		PairingManagerListener	l );
+
 }
diff --git a/com/aelitis/azureus/core/pairing/PairingManagerListener.java b/com/aelitis/azureus/core/pairing/PairingManagerListener.java
index 6a514f8..aacf54d 100644
--- a/com/aelitis/azureus/core/pairing/PairingManagerListener.java
+++ b/com/aelitis/azureus/core/pairing/PairingManagerListener.java
@@ -21,6 +21,7 @@
 
 package com.aelitis.azureus.core.pairing;
 
+
 public interface 
 PairingManagerListener 
 {
diff --git a/com/aelitis/azureus/core/pairing/PairingTest.java b/com/aelitis/azureus/core/pairing/PairingTest.java
new file mode 100644
index 0000000..95ef128
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingTest.java
@@ -0,0 +1,43 @@
+/*
+ * Created on Jan 21, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 
+PairingTest 
+{
+	public static final int	OT_PENDING				= 0;	// waiting to start
+	public static final int	OT_SUCCESS				= 1;	// yay
+	public static final int	OT_FAILED				= 2;	// server did its stuff, couldn't connect
+	public static final int	OT_SERVER_UNAVAILABLE	= 3;	// server not running
+	public static final int	OT_SERVER_OVERLOADED	= 4;	// server too busy
+	public static final int	OT_SERVER_FAILED		= 5;	// server failed (e.g. db down)
+	public static final int	OT_CANCELLED			= 6;	// you cancelled the test
+	
+	public int
+	getOutcome();
+	
+	public String
+	getErrorMessage();
+	
+	public void
+	cancel();
+}
diff --git a/com/aelitis/azureus/core/pairing/PairingTestListener.java b/com/aelitis/azureus/core/pairing/PairingTestListener.java
new file mode 100644
index 0000000..dac9593
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/PairingTestListener.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Jan 21, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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 
+PairingTestListener 
+{
+	public void
+	testStarted(
+		PairingTest		test );
+	
+	public void
+	testComplete(
+		PairingTest		test );
+
+}
diff --git a/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java b/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java
index bc14e6b..3551a57 100644
--- a/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java
+++ b/com/aelitis/azureus/core/pairing/impl/PairingManagerImpl.java
@@ -28,6 +28,9 @@ import java.net.HttpURLConnection;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.text.SimpleDateFormat;
 import java.util.*;
@@ -45,6 +48,7 @@ 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.FileUtil;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.SystemProperties;
 import org.gudy.azureus2.core3.util.SystemTime;
@@ -53,8 +57,12 @@ 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.clientid.ClientIDException;
+import org.gudy.azureus2.plugins.clientid.ClientIDGenerator;
+import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.plugins.ui.UIManagerListener;
 import org.gudy.azureus2.plugins.ui.config.ActionParameter;
 import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
@@ -68,19 +76,25 @@ 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 org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
+import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.ResourceDownloaderFactoryImpl;
 
 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.NetworkAdminNetworkInterface;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminNetworkInterfaceAddress;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminSocksProxy;
 import com.aelitis.azureus.core.pairing.*;
+import com.aelitis.azureus.core.pairing.impl.swt.PMSWTImpl;
 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.azureus.util.JSONUtils;
 import com.aelitis.net.upnp.UPnPRootDevice;
 
 public class 
@@ -116,6 +130,8 @@ PairingManagerImpl
 	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 static final int	CONNECT_TEST_PERIOD_MILLIS	= 30*60*1000;
+	
 	private AzureusCore	azureus_core;
 	
 	private BooleanParameter 	param_enable;
@@ -123,13 +139,19 @@ PairingManagerImpl
 	
 	private InfoParameter		param_ac_info;
 	private InfoParameter		param_status_info;
+	private InfoParameter		param_last_error;
 	private HyperlinkParameter	param_view;
 	
 	private BooleanParameter 	param_e_enable;
-	private StringParameter		param_ipv4;
-	private StringParameter		param_ipv6;
+	private StringParameter		param_public_ipv4;
+	private StringParameter		param_public_ipv6;
 	private StringParameter		param_host;
 	
+	private StringParameter		param_local_ipv4;
+	private StringParameter		param_local_ipv6;
+
+	private BooleanParameter 	param_icon_enable;
+
 	private Map<String,PairedServiceImpl>		services = new HashMap<String, PairedServiceImpl>();
 	
 	private AESemaphore	init_sem = new AESemaphore( "PM:init" );
@@ -139,10 +161,13 @@ PairingManagerImpl
 	private InetAddress		current_v4;
 	private InetAddress		current_v6;
 	
+	private String			local_v4	= "";
+	private String			local_v6	= "";
+	
 	private boolean	update_outstanding;
 	private boolean	updates_enabled;
 
-	private static final int MIN_UPDATE_PERIOD_DEFAULT	= 60*1000;
+	private static final int MIN_UPDATE_PERIOD_DEFAULT	= 10*1000;
 	private static final int MAX_UPDATE_PERIOD_DEFAULT	= 60*60*1000;
 		
 	private int min_update_period	= MIN_UPDATE_PERIOD_DEFAULT;
@@ -152,14 +177,21 @@ PairingManagerImpl
 	private AsyncDispatcher	dispatcher = new AsyncDispatcher();
 	
 	private boolean			must_update_once;
+	private boolean			update_in_progress;
 	private TimerEvent		deferred_update_event;
 	private long			last_update_time		= -1;
 	private int				consec_update_fails;
 	
 	private String			last_message;
 	
+	private Map<String,Object[]>	local_address_checks = new HashMap<String, Object[]>();
+
 	private CopyOnWriteList<PairingManagerListener>	listeners = new CopyOnWriteList<PairingManagerListener>();
 	
+	private PMSWTImpl		swt_ui = new PMSWTImpl();
+	
+	private int	tests_in_progress = 0;
+	
 	protected
 	PairingManagerImpl()
 	{
@@ -172,13 +204,17 @@ PairingManagerImpl
 		BasicPluginConfigModel configModel = ui_manager.createBasicPluginConfigModel(
 				ConfigSection.SECTION_CONNECTION, "Pairing");
 
+		configModel.addHyperlinkParameter2( "ConfigView.label.please.visit.here", MessageText.getString( "ConfigView.section.connection.pairing.url" ));
+
 		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_status_info 	= configModel.addInfoParameter2( "pairing.status.info", "" );
+		
+		param_last_error	= configModel.addInfoParameter2( "pairing.last.error", "" );
 		
 		param_view = configModel.addHyperlinkParameter2( "pairing.view.registered", SERVICE_URL + "/web/view?ac=" + access_code);
 
@@ -234,12 +270,18 @@ PairingManagerImpl
 		
 		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_public_ipv4	= configModel.addStringParameter2( "pairing.ipv4", "pairing.ipv4", "" );
+		param_public_ipv6	= configModel.addStringParameter2( "pairing.ipv6", "pairing.ipv6", "" );
+		param_host			= configModel.addStringParameter2( "pairing.host", "pairing.host", "" );
+		
+		LabelParameter spacer = configModel.addLabelParameter2( "blank.resource" );
+		
+		param_local_ipv4	= configModel.addStringParameter2( "pairing.local.ipv4", "pairing.local.ipv4", "" );
+		param_local_ipv6	= configModel.addStringParameter2( "pairing.local.ipv6", "pairing.local.ipv6", "" );
+
 		
-		param_ipv4.setGenerateIntermediateEvents( false );
-		param_ipv6.setGenerateIntermediateEvents( false );
+		param_public_ipv4.setGenerateIntermediateEvents( false );
+		param_public_ipv6.setGenerateIntermediateEvents( false );
 		param_host.setGenerateIntermediateEvents( false );
 		
 		ParameterListener change_listener = 
@@ -260,12 +302,16 @@ PairingManagerImpl
 			
 		param_enable.addListener( change_listener );
 		param_e_enable.addListener(	change_listener );
-		param_ipv4.addListener(	change_listener );
-		param_ipv6.addListener(	change_listener );
+		param_public_ipv4.addListener(	change_listener );
+		param_public_ipv6.addListener(	change_listener );
+		param_local_ipv4.addListener(	change_listener );
+		param_local_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_public_ipv4 );
+		param_e_enable.addEnabledOnSelection( param_public_ipv6 );
+		param_e_enable.addEnabledOnSelection( param_local_ipv4 );
+		param_e_enable.addEnabledOnSelection( param_local_ipv6 );
 		param_e_enable.addEnabledOnSelection( param_host );
 		
 		configModel.createGroup(
@@ -273,11 +319,16 @@ PairingManagerImpl
 			new Parameter[]{
 				param_e_info,
 				param_e_enable,
-				param_ipv4,	
-				param_ipv6,
+				param_public_ipv4,	
+				param_public_ipv6,
 				param_host,
+				spacer,
+				param_local_ipv4,	
+				param_local_ipv6,
 			});
 		
+		param_icon_enable = configModel.addBooleanParameter2( "pairing.config.icon.show", "pairing.config.icon.show", true );
+
 		AzureusCoreFactory.addCoreRunningListener(
 			new AzureusCoreRunningListener()
 			{
@@ -311,7 +362,7 @@ PairingManagerImpl
 					{
 						new DelayedEvent( 
 							"PM:delayinit",
-							30*1000,
+							10*1000,
 							new AERunnable()
 							{
 								public void
@@ -325,6 +376,8 @@ PairingManagerImpl
 			
 			dt.queue();
 			
+			swt_ui.initialise( default_pi, param_icon_enable );
+
 		}finally{
 			
 			init_sem.releaseForever();
@@ -348,11 +401,132 @@ PairingManagerImpl
 		return( param_enable.getValue());
 	}
 	
+	public void
+	setEnabled(
+		boolean	enabled )
+	{
+		param_enable.setValue( enabled );
+	}
+	
+	public void 
+	setGroup(
+		String group ) 
+	{
+		COConfigurationManager.setParameter( "pairing.groupcode", group );
+		
+		updateNeeded();
+	}
+	
+	public String
+	getGroup()
+	{
+		return( COConfigurationManager.getStringParameter( "pairing.groupcode", null ));
+	}
+
+	public List<PairedNode> 
+	listGroup() 
+	
+		throws PairingException 
+	{
+		try{
+			URL url = new URL( SERVICE_URL + "/remote/listGroup?gc=" + getGroup());
+			
+			
+			InputStream is =  new ResourceDownloaderFactoryImpl().create( url ).download();
+			
+			Map json = JSONUtils.decodeJSON( new String( FileUtil.readInputStreamAsByteArray( is ), "UTF-8" ));
+			
+			List<Map>	list = (List<Map>)json.get( "result" );
+			
+			List<PairedNode>	result = new ArrayList<PairedNode>();
+			
+			String my_ac = peekAccessCode();
+
+			if ( list != null ){
+				
+				for ( Map m: list ){
+					
+					PairedNodeImpl node = new PairedNodeImpl( m );
+							
+					if ( my_ac == null || !my_ac.equals( node.getAccessCode())){
+					
+						result.add( node );
+					}
+				}
+			}
+			
+			return( result );
+			
+		}catch( Throwable e ){
+			
+			throw( new PairingException( "Failed to list group", e ));
+		}
+	}
+	
 	protected void
 	setStatus(
 		String		str )
 	{
-		param_status_info.setValue( str );
+		String last_status = param_status_info.getValue();
+		
+		if ( !last_status.equals( str )){
+			
+			param_status_info.setValue( str );
+		
+			fireChanged();
+		}
+	}
+	
+	public String
+	getStatus()
+	{
+		return( param_status_info.getValue());
+	}
+	
+	protected void
+	setLastServerError(
+		String	error )
+	{
+		String last_error = param_last_error.getValue();
+	
+		if ( error == null ){
+			
+			error = "";
+		}
+		
+		if ( !last_error.equals( error )){
+			
+			param_last_error.setValue( error );
+			
+			fireChanged();
+		}
+	}
+	
+	public String
+	getLastServerError()
+	{
+		String last_error = param_last_error.getValue();
+
+		if ( last_error.length() == 0 ){
+			
+			last_error = null;
+		}
+		
+		return( last_error );
+	}
+
+	public boolean 
+	hasActionOutstanding() 
+	{
+		synchronized( this ){
+			
+			if ( !isEnabled()){
+				
+				return( false );
+			}
+			
+			return( !updates_enabled || update_outstanding || deferred_update_event != null || update_in_progress );
+		}
 	}
 	
 	protected String
@@ -366,7 +540,11 @@ PairingManagerImpl
 		String		ac )
 	{
 		COConfigurationManager.setParameter( "pairing.accesscode", ac );
-		 
+		
+			// try not to loose this!
+		
+		COConfigurationManager.save();
+		
 		param_ac_info.setValue( ac );
 		 
 		param_view.setHyperlink( SERVICE_URL + "/web/view?ac=" + ac );
@@ -398,6 +576,8 @@ PairingManagerImpl
 				updateNeeded();
 			}
 			
+			fireChanged();
+			
 			return( code );
 			
 		}catch( Throwable e ){
@@ -407,6 +587,12 @@ PairingManagerImpl
 	}
 
 	public String
+	peekAccessCode()
+	{
+		return( readAccessCode());
+	}
+	
+	public String
 	getAccessCode()
 	
 		throws PairingException
@@ -423,6 +609,30 @@ PairingManagerImpl
 		return( ac );
 	}
 	
+	public void
+	getAccessCode(
+		final PairingManagerListener 	listener )
+	
+		throws PairingException
+	{
+		new AEThread2( "PM:gac", true )
+		{
+			public void
+			run()
+			{
+				try{
+					getAccessCode();
+					
+				}catch( Throwable e ){
+					
+				}finally{
+					
+					listener.somethingChanged( PairingManagerImpl.this );
+				}
+			}
+		}.start();
+	}
+	
 	public String
 	getReplacementAccessCode()
 	
@@ -532,12 +742,14 @@ PairingManagerImpl
 		}
 		
 		return( current );
-	}
+	}	
 	
 	protected void
 	updateGlobals(
 		boolean	is_updating )	
 	{
+		final long now = SystemTime.getMonotonousTime();
+		
 		synchronized( this ){
 						
 			NetworkAdmin network_admin = NetworkAdmin.getSingleton();
@@ -549,21 +761,176 @@ PairingManagerImpl
 			InetAddress latest_v6 = network_admin.getDefaultPublicAddressV6();
 	
 			InetAddress temp_v6 = updateAddress( current_v6, latest_v6, true );
-	
+			
+			final TreeSet<String>	latest_v4_locals = new TreeSet<String>();
+			final TreeSet<String>	latest_v6_locals = new TreeSet<String>();
+			
+			NetworkAdminNetworkInterface[] interfaces = network_admin.getInterfaces();
+			
+			List<Runnable>	to_do = new ArrayList<Runnable>();
+			
+			Set<String> existing_checked = new HashSet<String>( local_address_checks.keySet());
+			
+			for ( NetworkAdminNetworkInterface intf: interfaces ){
+				
+				NetworkAdminNetworkInterfaceAddress[] addresses = intf.getAddresses();
+				
+				for ( NetworkAdminNetworkInterfaceAddress address: addresses ){
+					
+					final InetAddress ia = address.getAddress();
+					
+					if ( ia.isLoopbackAddress()){
+						
+						continue;
+					}
+					
+					if ( ia.isLinkLocalAddress() || ia.isSiteLocalAddress()){
+						
+						final String a_str = ia.getHostAddress();
+						
+						existing_checked.remove( a_str );
+						
+						Object[] check;
+						
+						synchronized( local_address_checks ){
+						
+							check = local_address_checks.get( a_str );
+						}
+						
+						boolean run_check = check == null || now - ((Long)check[0]) > CONNECT_TEST_PERIOD_MILLIS;
+						
+						if ( run_check ){
+						
+							to_do.add(
+								new Runnable()
+								{
+									public void
+									run()
+									{
+										Socket socket = new Socket();
+										
+										String	result = a_str;
+										
+										try{
+											socket.bind( new InetSocketAddress( ia, 0 ));
+																								
+											socket.connect(  new InetSocketAddress( "www.google.com", 80 ), 10*1000 );
+											
+											result += "*";
+											
+										}catch( Throwable e ){
+											
+										}finally{
+											try{
+												socket.close();
+											}catch( Throwable e ){
+											}
+											
+										}
+										
+										synchronized( local_address_checks ){
+											
+											local_address_checks.put( a_str, new Object[]{ new Long(now), result });
+											
+											if ( ia instanceof Inet4Address ){
+												
+												latest_v4_locals.add( result );
+												
+											}else{
+												
+												latest_v6_locals.add( result );
+											}
+										}
+									}
+								});
+							
+						}else{
+							
+							synchronized( local_address_checks ){
+						
+								if ( ia instanceof Inet4Address ){
+								
+									latest_v4_locals.add((String)check[1]);
+									
+								}else{
+									
+									latest_v6_locals.add((String)check[1]);
+								}
+							}
+						}
+					}
+				}
+			}
+			
+			if ( to_do.size() > 0 ){
+				
+				final AESemaphore	sem = new AESemaphore( "PM:check" );
+				
+				for ( final Runnable r: to_do ){
+					
+					new AEThread2( "PM:check:", true )
+					{
+						public void
+						run()
+						{
+							try{
+								r.run();
+							}finally{
+								
+								sem.release();
+							}
+						}
+					}.start();
+				}
+				
+				for (int i=0;i<to_do.size();i++){
+					
+					sem.reserve();
+				}
+			}
+			
+			for ( String excess: existing_checked ){
+				
+				local_address_checks.remove( excess );
+			}
+			
+			String v4_locals_str = getString( latest_v4_locals );
+			String v6_locals_str = getString( latest_v6_locals );
+			
+			
 			if (	temp_v4 != current_v4 ||
-					temp_v6 != current_v6 ){
+					temp_v6 != current_v6 ||
+					!v4_locals_str.equals( local_v4 ) ||
+					!v6_locals_str.equals( local_v6 )){
 				
 				current_v4	= temp_v4;
 				current_v6	= temp_v6;
+				local_v4	= v4_locals_str;
+				local_v6	= v6_locals_str;
 				
 				if ( !is_updating ){
 				
 					updateNeeded();
 				}
 			}
+
 		}
 	}
 	
+	protected String
+	getString(
+		Set<String>	set )
+	{
+		String	str = "";
+		
+		for ( String s: set ){
+			
+			str += (str.length()==0?"":",") + s;
+		}
+		
+		return( str );
+	}
+	
 	protected void
 	enableUpdates()
 	{		
@@ -631,6 +998,8 @@ PairingManagerImpl
 				
 				return;
 			}
+			
+			update_in_progress = true;
 		}
 		
 		try{
@@ -687,7 +1056,9 @@ PairingManagerImpl
 						
 						if ( consec_update_fails == 0 && !must_update_once ){
 					
-							setStatus( MessageText.getString( "pairing.status.disabled" ));
+							update_in_progress = false;
+							
+							setStatus( MessageText.getString( is_enabled?"pairing.status.noservices":"pairing.status.disabled" ));
 							
 							return;
 						}
@@ -713,6 +1084,13 @@ PairingManagerImpl
 			
 			payload.put( "ac", ac );
 			
+			String	gc = getGroup();
+			
+			if ( gc != null && gc.length() > 0 ){
+				
+				payload.put( "gc", gc );
+			}
+			
 			synchronized( this ){
 
 				if ( current_v4 != null ){
@@ -725,6 +1103,16 @@ PairingManagerImpl
 					payload.put( "c_v6", current_v6.getHostAddress());
 				}
 			
+				if ( local_v4.length() > 0 ){
+					
+					payload.put( "l_v4", local_v4 );
+				}
+				
+				if ( local_v6.length() > 0 ){
+					
+					payload.put( "l_v6", local_v6 );
+				}
+				
 				if ( param_e_enable.getValue()){
 				
 					String host = param_host.getValue().trim();
@@ -734,18 +1122,32 @@ PairingManagerImpl
 						payload.put( "e_h", host );
 					}
 					
-					String v4 = param_ipv4.getValue().trim();
+					String v4 = param_public_ipv4.getValue().trim();
 					
 					if ( v4.length() > 0 ){
 						
 						payload.put( "e_v4", v4 );
 					}
 					
-					String v6 = param_ipv6.getValue().trim();
+					String v6 = param_public_ipv6.getValue().trim();
 					
 					if ( v6.length() > 0 ){
 						
-						payload.put( "e_v4", v6 );
+						payload.put( "e_v6", v6 );
+					}
+					
+					String l_v4 = param_local_ipv4.getValue().trim();
+					
+					if ( l_v4.length() > 0 ){
+						
+						payload.put( "e_l_v4", l_v4 );
+					}
+					
+					String l_v6 = param_local_ipv6.getValue().trim();
+					
+					if ( l_v6.length() > 0 ){
+						
+						payload.put( "e_l_v6", l_v6 );
 					}
 				}
 				
@@ -827,9 +1229,11 @@ PairingManagerImpl
 					COConfigurationManager.setParameter( "pairing.updateoutstanding", false );
 				}
 
+				update_in_progress = false;
+				
 				if ( global_update_event == null ){
 					
-					setStatus( MessageText.getString( "pairing.status.disabled" ));
+					setStatus( MessageText.getString( is_enabled?"pairing.status.noservices":"pairing.status.disabled" ));
 					
 				}else{
 					
@@ -843,23 +1247,40 @@ PairingManagerImpl
 			
 			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 ){
+				try{
+					consec_update_fails++;
+		
+					long back_off = min_update_period;
 					
-						back_off = max_update_period;
+					for (int i=0;i<consec_update_fails;i++){
 						
-						break;
+						back_off *= 2;
+						
+						if ( back_off > max_update_period ){
+						
+							back_off = max_update_period;
+							
+							break;
+						}
 					}
+					
+					deferUpdate( back_off );
+					
+				}finally{
+				
+					update_in_progress = false;
 				}
+			}
+		}finally{
+			
+			synchronized( this ){
 				
-				deferUpdate( back_off );
+				if ( update_in_progress ){
+				
+					Debug.out( "Something didn't clear update_in_progress!!!!" );
+					
+					update_in_progress = false;
+				}
 			}
 		}
 	}
@@ -872,13 +1293,6 @@ PairingManagerImpl
 		
 		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",
@@ -899,6 +1313,13 @@ PairingManagerImpl
 						updateNeeded();
 					}
 				});
+		
+		setStatus( 
+				MessageText.getString( 
+					"pairing.status.pending", 
+					new String[]{ new SimpleDateFormat().format(new Date( target ))}));
+
+		COConfigurationManager.setParameter( "pairing.updateoutstanding", true );
 	}
 	
 	
@@ -930,15 +1351,44 @@ PairingManagerImpl
 			
 			String request_str = Base32.encode( BEncoder.encode( request ));
 			
+			String	sig = null;
+			
+			try{
+				sig = Base32.encode( cman.getECCHandler().sign( request_str.getBytes( "UTF-8" ), "pairing" ));
+				
+			}catch( Throwable e ){
+			}
+			
 			String other_params = 
 				"&ver=" + UrlUtils.encode( Constants.AZUREUS_VERSION ) + 
 				"&app=" + UrlUtils.encode( SystemProperties.getApplicationName()) +
 				"&locale=" + UrlUtils.encode( MessageText.getCurrentLocale().toString());
 
+			if ( sig != null ){
+				
+				other_params += "&sig=" + sig;
+			}
+			
 			URL target = new URL( SERVICE_URL + "/client/" + command + "?request=" + request_str + other_params );
 			
+			Properties	http_properties = new Properties();
+			
+			http_properties.put( ClientIDGenerator.PR_URL, target );
+				
+			try{
+				ClientIDManagerImpl.getSingleton().generateHTTPProperties( http_properties );
+				
+			}catch( ClientIDException e ){
+				
+				throw( new IOException( e.getMessage()));
+			}
+			
+			target = (URL)http_properties.get( ClientIDGenerator.PR_URL );
+			
 			HttpURLConnection connection = (HttpURLConnection)target.openConnection();
 			
+			connection.setConnectTimeout( 30*1000 );
+			
 			InputStream is = connection.getInputStream();
 			
 			Map<String,Object> response = (Map<String,Object>)BDecoder.decode( new BufferedInputStream( is ));
@@ -1002,14 +1452,54 @@ PairingManagerImpl
 				throw( new PairingException( error ));
 			}
 			
+			setLastServerError( null );
+						
 			return((Map<String,Object>)response.get( "rep" ));
 			
 		}catch( Throwable e ){
+						
+			setLastServerError( Debug.getNestedExceptionMessage( e ));
+			
+			if ( e instanceof PairingException ){
+				
+				throw((PairingException)e);
+			}
 			
 			throw( new PairingException( "invocation failed", e ));
 		}
 	}
 	
+	
+	public PairingTest 
+	testService(
+		String 					sid, 
+		PairingTestListener 	listener )
+	
+		throws PairingException 
+	{
+		return( new TestServiceImpl( sid, listener ));
+	}
+	
+	public void
+	recordRequest(
+		String		name,
+		String		ip,
+		boolean		good )
+	{
+		synchronized( this ){
+			
+				// don't record any incoming stuff during a test as we don't want to
+				// show this as a significant event
+			
+			if ( tests_in_progress > 0 ){
+				
+				return;
+			}
+		}
+		
+		swt_ui.recordRequest( name, ip, good );
+	}
+	
 	protected void
 	fireChanged()
 	{
@@ -1024,7 +1514,7 @@ PairingManagerImpl
 			}
 		}
 	}
-	
+		
 	public void
 	addListener(
 		PairingManagerListener		l )
@@ -1057,6 +1547,199 @@ PairingManagerImpl
 	}
 	
 	protected class
+	TestServiceImpl
+		implements PairingTest
+	{
+		final private String					sid;
+		final private PairingTestListener		listener;
+		
+		private volatile int		outcome = OT_PENDING;
+		private volatile String		error_message;
+		
+		private volatile boolean	cancelled;
+		
+		protected
+		TestServiceImpl(
+			String 					_sid, 
+			PairingTestListener 	_listener )
+		{
+			sid			= _sid;
+			listener	= _listener;
+			
+			new AEThread2( "PM:test" )
+			{
+				public void
+				run()
+				{
+					try{
+						String	access_code		= null;
+						long	sid_wait_start	= -1;
+						
+						while( true ){
+							
+							if ( !isEnabled()){
+								
+								throw( new Exception( "Pairing is disabled" ));
+							}
+							
+							access_code = peekAccessCode();
+							
+							if ( access_code != null ){
+								
+								if ( !hasActionOutstanding()){
+									
+									if ( getService( sid ) != null ){
+									
+										break;
+										
+									}else{
+										
+										long	now = SystemTime.getMonotonousTime();
+										
+										if ( sid_wait_start == -1 ){
+											
+											sid_wait_start = now;
+											
+										}else{
+											
+											if ( now - sid_wait_start > 5000 ){
+												
+												break;
+											}
+										}
+									}
+								}
+							}
+							
+							Thread.sleep( 500 );
+							
+							if ( cancelled ){
+								
+								outcome = OT_CANCELLED;
+								
+								return;
+							}
+						}
+						
+						PairedService service = getService( sid );
+						
+						if ( service == null ){
+							
+							throw( new Exception( "Service not found" ));
+						}
+						
+						listener.testStarted( TestServiceImpl.this );
+						
+						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 + "/web/test?sid=" + sid + "&ac=" + access_code + "&format=bencode" + other_params );
+						
+						HttpURLConnection connection = (HttpURLConnection)target.openConnection();
+						
+						connection.setConnectTimeout( 10*1000 );
+						
+						try{
+							synchronized( PairingManagerImpl.this ){
+								
+								tests_in_progress++;
+							}
+							
+							InputStream is = connection.getInputStream();
+							
+							Map<String,Object> response = (Map<String,Object>)BDecoder.decode( new BufferedInputStream( is ));
+							
+							response = BDecoder.decodeStrings( response );
+							
+							Long code = (Long)response.get( "code" );
+							
+							if ( code == null ){
+								
+								throw( new Exception( "Code missing from reply" ));
+							}
+												
+							error_message = (String)response.get( "msg" );
+							
+							if ( code == 1 ){
+								
+								outcome = OT_SUCCESS;
+								
+							}else if ( code == 2 ){
+								
+								outcome = OT_SERVER_OVERLOADED;
+								
+							}else if ( code == 3 ){
+								
+								outcome = OT_SERVER_FAILED;
+								
+							}else if ( code == 4 ){
+								
+								outcome = OT_FAILED;
+								
+								error_message = "Connect timeout";
+								
+							}else if ( code == 5 ){
+								
+								outcome = OT_FAILED;
+								
+							}else{
+								
+								outcome = OT_SERVER_FAILED;;
+								
+								error_message = "Unknown response code " + code;
+							}
+						}catch( SocketTimeoutException e ){
+							
+							outcome = OT_SERVER_UNAVAILABLE;
+							
+							error_message = "Connect timeout";
+							
+						}
+					}catch( Throwable e ){
+						
+						outcome = OT_SERVER_UNAVAILABLE;
+						
+						error_message = Debug.getNestedExceptionMessage( e );
+						
+					}finally{
+						
+						try{
+							listener.testComplete( TestServiceImpl.this );
+							
+						}finally{
+						
+							synchronized( PairingManagerImpl.this ){
+							
+								tests_in_progress--;
+							}
+						}
+					}
+				}
+			}.start();
+		}
+		
+		public int
+		getOutcome()
+		{
+			return( outcome );
+		}
+		
+		public String
+		getErrorMessage()
+		{
+			return( error_message );
+		}
+		
+		public void
+		cancel()
+		{
+			cancelled	= true;
+		}
+	}
+	
+	protected class
 	PairedServiceImpl
 		implements PairedService, PairingConnectionData
 	{
@@ -1099,7 +1782,14 @@ PairingManagerImpl
 					System.out.println( "PS: " + sid + ": " + name + " -> " + value );
 				}
 				
-				attributes.put( name, value );
+				if  ( value == null ){
+					
+					attributes.remove( name );
+					
+				}else{
+					
+					attributes.put( name, value );
+				}
 			}
 		}
 		
@@ -1131,4 +1821,162 @@ PairingManagerImpl
 			return( result );
 		}
 	}
+	
+	private class
+	PairedNodeImpl
+		implements PairedNode
+	{
+		private Map		map;
+		
+		protected
+		PairedNodeImpl(
+			Map		_map )
+		{
+			map	= _map;
+		}
+		
+		public String
+		getAccessCode()
+		{
+			return((String)map.get( "ac" ));
+		}
+		
+		public List<InetAddress>
+		getAddresses()
+		{
+			Set<InetAddress> addresses = new HashSet<InetAddress>();
+			
+			addAddress( addresses, "c_v4" );
+			addAddress( addresses, "c_v6" );
+			addAddress( addresses, "l_v4" );
+			addAddress( addresses, "l_v6" );
+			addAddress( addresses, "e_v4" );
+			addAddress( addresses, "e_v6" );
+			addAddress( addresses, "e_l_v4" );
+			addAddress( addresses, "e_l_v6" );
+			addAddress( addresses, "e_h" );
+			
+			return( new ArrayList<InetAddress>( addresses ));
+		}
+		
+		private void
+		addAddress(
+			Set<InetAddress>	addresses,
+			String				key )
+		{
+			String str = (String)map.get( key );
+			
+			if ( str != null ){
+				
+				String[] bits = str.split(",");
+				
+				for ( String bit: bits ){
+					
+					bit = bit.trim();
+					
+					if ( bit.length() == 0 ){
+						
+						continue;
+					}
+					
+					
+					if ( bit.endsWith( "*" )){
+						
+						bit = bit.substring( 0, bit.length()-1 );
+					}
+
+					try{
+						addresses.add( InetAddress.getByName( bit ));
+						
+					}catch( Throwable e ){
+					}
+				}
+			}
+		}
+		
+		public List<PairedService>
+		getServices()
+		{
+			Map<String,Map> smap = (Map)map.get( "services" );
+			
+			List<PairedService>	services = new ArrayList<PairedService>();
+			
+			for ( Map.Entry<String,Map> entry: smap.entrySet()){
+				
+				services.add( new PairedService2Impl( entry.getKey(), entry.getValue()));
+			}
+			
+			return( services );
+		}
+	}
+	
+	private class
+	PairedService2Impl
+		implements PairedService
+	{
+		private String		sid;
+		private Map			map;
+		
+		protected
+		PairedService2Impl(
+			String		_sid,
+			Map			_map )
+		{
+			sid		= _sid;
+			map		= _map;
+		}
+		
+		public String
+		getSID()
+		{
+			return( sid );
+		}
+		
+		public PairingConnectionData
+		getConnectionData()
+		{
+			return( new PairingConnectionData2( map ));
+		}
+		
+		public void
+		remove()
+		{
+			throw( new RuntimeException( "Not supported" ));
+		}
+	}
+	
+	private class
+	PairingConnectionData2
+		implements PairingConnectionData
+	{
+		private Map		map;
+		
+		protected
+		PairingConnectionData2(
+			Map		_map )
+		{
+			map		= _map;
+		}
+		
+		public void
+		setAttribute(
+			String		name,
+			String		value )
+		{
+			throw( new RuntimeException( "Not supported" ));
+		}
+		
+		public String
+		getAttribute(
+			String		name )
+		{
+			return( (String)map.get( name ));
+		}
+		
+		public void
+		sync()
+		{
+			throw( new RuntimeException( "Not supported" ));
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/pairing/impl/swt/PMSWTImpl.java b/com/aelitis/azureus/core/pairing/impl/swt/PMSWTImpl.java
new file mode 100644
index 0000000..a5c16ec
--- /dev/null
+++ b/com/aelitis/azureus/core/pairing/impl/swt/PMSWTImpl.java
@@ -0,0 +1,608 @@
+/*
+ * Created on Aug 14, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.swt;
+
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.swt.graphics.Image;
+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.core3.util.SimpleTimer;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.core3.util.TimerEvent;
+import org.gudy.azureus2.core3.util.TimerEventPerformer;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIInstance;
+import org.gudy.azureus2.plugins.ui.UIManagerListener;
+import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
+import org.gudy.azureus2.plugins.ui.config.Parameter;
+import org.gudy.azureus2.plugins.ui.config.ParameterListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntry;
+import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntryListener;
+
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminNetworkInterface;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminNetworkInterfaceAddress;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminPropertyChangeListener;
+import com.aelitis.azureus.core.util.AZ3Functions;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.updater.UIUpdater;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+
+public class 
+PMSWTImpl 
+{
+	private UISWTStatusEntry 	status;
+	
+	private volatile Set<String>	local_addresses = new HashSet<String>();
+	
+	private Image	icon_idle;
+	private Image	icon_green;
+	private Image	icon_red;
+	
+	private int		last_update_count;
+	private Image	last_image;
+	private String	last_tooltip_text	= "";
+	
+	private long	last_image_expiry_mono;
+	private long	last_image_expiry_uc_min;
+	
+	public void
+	initialise(
+		final PluginInterface			pi,
+		final BooleanParameter			icon_enable )
+	{
+		final NetworkAdmin na = NetworkAdmin.getSingleton();
+		
+		na.addPropertyChangeListener(
+			new NetworkAdminPropertyChangeListener()
+			{
+				public void 
+				propertyChanged(
+					String property) 
+				{
+					if ( property == NetworkAdmin.PR_NETWORK_INTERFACES ){
+						
+						updateLocalAddresses( na );
+					}
+				}
+			});
+		
+		updateLocalAddresses( na );
+		
+		pi.getUIManager().addUIListener(
+				new UIManagerListener()
+				{
+					public void
+					UIAttached(
+						final UIInstance		instance )
+					{
+						if ( instance instanceof UISWTInstance ){
+							
+							UIFunctions uif = UIFunctionsManager.getUIFunctions();
+							
+							if ( uif != null ){
+								
+								uif.getUIUpdater().addListener(
+									new UIUpdater.UIUpdaterListener()
+									{
+										public void 
+										updateComplete(
+											int count )
+										{
+											last_update_count	= count;
+											
+											updateStatus( true );
+										}
+									});
+							}
+							
+							Utils.execSWTThread(
+								new AERunnable() 
+								{
+									public void 
+									runSupport() 
+									{
+										ImageLoader imageLoader = ImageLoader.getInstance();
+	
+										icon_idle 	= imageLoader.getImage( "pair_sb_idle" );
+										icon_green 	= imageLoader.getImage( "pair_sb_green" );
+										icon_red	= imageLoader.getImage( "pair_sb_red" );
+				
+										UISWTInstance	ui_instance = (UISWTInstance)instance;
+										
+										status	= ui_instance.createStatusEntry();
+											
+										last_tooltip_text = MessageText.getString( "pairing.ui.icon.tip" );
+										
+										status.setTooltipText( last_tooltip_text );
+										
+										status.setImageEnabled( true );
+										
+										status.setImage( icon_idle );
+										
+										last_image	= icon_idle;
+										
+										boolean	is_visible = icon_enable.getValue();
+										
+										status.setVisible( is_visible );
+										
+										if ( is_visible ){
+											
+											updateStatus( false );
+										}
+										
+										final MenuItem mi_show =
+											pi.getUIManager().getMenuManager().addMenuItem(
+																status.getMenuContext(),
+																"pairing.ui.icon.show" );
+										
+										mi_show.setStyle( MenuItem.STYLE_CHECK );
+										mi_show.setData( new Boolean( is_visible ));
+										
+										mi_show.addListener(
+												new MenuItemListener()
+												{
+													public void
+													selected(
+														MenuItem			menu,
+														Object 				target )
+													{
+														icon_enable.setValue( false );
+													}
+												});
+										
+										icon_enable.addListener(
+												new ParameterListener()
+												{
+													public void 
+													parameterChanged(
+														Parameter param )
+													{
+														boolean is_visible = icon_enable.getValue();
+														
+														status.setVisible( is_visible );
+														
+														mi_show.setData( new Boolean( is_visible ));
+														
+														if ( is_visible ){
+															
+															updateStatus( false );
+														}
+													}
+												});
+											
+			
+										final AZ3Functions.provider az3 = AZ3Functions.getProvider();
+
+										if ( az3 != null ){
+											
+											MenuItem mi_pairing =
+												pi.getUIManager().getMenuManager().addMenuItem(
+																	status.getMenuContext(),
+																	"MainWindow.menu.pairing" );
+				
+											mi_pairing.addListener(
+												new MenuItemListener()
+												{
+													public void
+													selected(
+														MenuItem			menu,
+														Object 				target )
+													{
+														az3.openRemotePairingWindow();
+													}
+												});
+										}
+										
+										MenuItem mi_sep =
+											pi.getUIManager().getMenuManager().addMenuItem(
+																status.getMenuContext(),
+																"" );
+			
+										mi_sep.setStyle( MenuItem.STYLE_SEPARATOR );
+										
+										MenuItem mi_options =
+											pi.getUIManager().getMenuManager().addMenuItem(
+																status.getMenuContext(),
+																"MainWindow.menu.view.configuration" );
+			
+										mi_options.addListener(
+											new MenuItemListener()
+											{
+												public void
+												selected(
+													MenuItem			menu,
+													Object 				target )
+												{
+													UIFunctions uif = UIFunctionsManager.getUIFunctions();
+			
+													if ( uif != null ){
+			
+														uif.openView( UIFunctions.VIEW_CONFIG, "Pairing" );
+													}
+												}
+											});
+										
+										
+										UISWTStatusEntryListener click_listener = 
+											new UISWTStatusEntryListener()
+										{
+												public void 
+												entryClicked(
+													UISWTStatusEntry entry )
+												{
+													UIFunctions uif = UIFunctionsManager.getUIFunctions();
+													
+													if ( uif != null ){
+			
+														uif.openView( UIFunctions.VIEW_CONFIG, "Pairing" );
+													}
+												}
+											};
+											
+										status.setListener( click_listener );
+									}
+								});
+						}
+								
+					}
+					
+					public void
+					UIDetached(
+						UIInstance		instance )
+					{
+						
+					}
+				});
+	}
+	
+	private void
+	updateLocalAddresses(
+		NetworkAdmin		network_admin )
+	{
+		NetworkAdminNetworkInterface[] interfaces = network_admin.getInterfaces();
+						
+		Set<String>	ias = new HashSet<String>();
+		
+		for ( NetworkAdminNetworkInterface intf: interfaces ){
+			
+			NetworkAdminNetworkInterfaceAddress[] addresses = intf.getAddresses();
+			
+			for ( NetworkAdminNetworkInterfaceAddress address: addresses ){
+				
+				InetAddress ia = address.getAddress();
+				
+				ias.add( ia.getHostAddress());
+			}
+		}
+		
+		local_addresses = ias;
+	}
+	
+	private Map<String,RemoteHistory>	history_map	= new HashMap<String, RemoteHistory>();
+		
+	public void
+	recordRequest(
+		final String		name,
+		final String		ip,
+		final boolean		good )
+	{	
+		Utils.execSWTThread(
+			new AERunnable() 
+			{
+				public void 
+				runSupport() 
+				{						
+					RemoteHistory entry = history_map.get( name );
+						
+					if ( entry == null ){
+							
+						entry = new RemoteHistory();
+							
+						history_map.put( name, entry );
+					}
+						
+					entry.addRequest( ip, good );
+					
+					updateStatus( false );
+				}
+			});
+	}
+	
+	private void
+	updateStatus(
+		boolean		update_completed )
+	{
+		final int RECORD_EXPIRY		= 60*60*1000;
+		final int GOOD_EXPIRY		= 1*1000;
+		final int BAD_EXPIRY		= 5*60*1000;
+		final int MAX_IPS_PER_TYPE	= 10;
+		final int MAX_TYPES			= 10;
+	
+		if ( status == null ){
+			
+			return;
+		}
+		
+		long	now_mono = SystemTime.getMonotonousTime();
+		
+		if ( update_completed ){
+		
+			if ( last_image != icon_idle && last_update_count >= last_image_expiry_uc_min ){
+				
+				if ( now_mono >= last_image_expiry_mono ){
+					
+					last_image = icon_idle;
+										
+					status.setImage( icon_idle );
+				}
+			}
+		}
+			
+		StringBuffer	tooltip_text = new StringBuffer( 256 );
+		
+		tooltip_text.append( MessageText.getString( "pairing.ui.icon.tip" ));
+			
+		long newest_bad_mono	= -1;
+		long newest_good_mono	= -1;
+
+		Iterator<Map.Entry<String,RemoteHistory>>	it = history_map.entrySet().iterator();
+		
+		String	oldest_type			= null;
+		long	oldest_type_mono	= Long.MAX_VALUE;
+		
+		int	records_added = 0;
+		
+		while( it.hasNext()){
+			
+			Map.Entry<String,RemoteHistory> entry = it.next();
+			
+			String			name 	= entry.getKey();
+			RemoteHistory	history = entry.getValue();
+			
+			String	oldest_ip		= null;
+			long	oldest_ip_mono	= Long.MAX_VALUE;
+							
+			Map<String,RemoteHistoryEntry> records = history.getEntries();
+			
+			Iterator<Map.Entry<String,RemoteHistoryEntry>>	record_it = records.entrySet().iterator();
+			
+			StringBuffer	tt_ip_details = new StringBuffer( 256 );
+			
+			while( record_it.hasNext()){
+				
+				Map.Entry<String,RemoteHistoryEntry>	record = record_it.next();
+				
+				String				ip 	= record.getKey();
+				RemoteHistoryEntry 	e 	= record.getValue();
+				
+				long e_mono = e.getLastReceivedMono();
+				
+				if ( e_mono < oldest_ip_mono ){
+					
+					oldest_ip_mono 	= e_mono;
+					oldest_ip		= ip;
+				}
+				
+				long age = now_mono - e_mono;
+				
+				if ( age > RECORD_EXPIRY ){
+					
+					record_it.remove();
+					
+				}else{
+					
+					String age_str = TimeFormatter.format( age/1000 );
+					
+					tt_ip_details.append( "\n        " );
+					
+					if ( local_addresses.contains( ip )){
+						
+						tt_ip_details.append( MessageText.getString( "DHTView.db.local" ) + " (" + ip + ")" );
+						
+					}else{
+						
+						tt_ip_details.append( ip );
+					}
+					
+					if ( e.wasLastGood()){
+						
+						tt_ip_details.append( " OK" );
+						
+						newest_good_mono 	= Math.max( newest_good_mono, e_mono );
+						
+					}else{
+						
+						tt_ip_details.append( " " + MessageText.getString( "label.access.denied" ));
+						
+						newest_bad_mono 	= Math.max( newest_bad_mono, e_mono );
+					}
+					
+					tt_ip_details.append( " - " + age_str + " ago");
+				}
+			}
+			
+			if ( records.size() == 0 ){
+				
+				it.remove();
+				
+			}else{
+				
+				if ( oldest_ip_mono < oldest_type_mono ){
+					
+					oldest_type_mono 	= oldest_ip_mono;
+					oldest_type			= name;
+				}
+			
+				if ( records.size() >= MAX_IPS_PER_TYPE ){
+					
+					records.remove( oldest_ip );
+					
+				}else{
+					
+					tooltip_text.append( "\n    " + name );
+					tooltip_text.append( tt_ip_details );
+					
+					records_added++;
+				}
+			}
+		}
+		
+		if ( history_map.size() > MAX_TYPES ){
+			
+			history_map.remove( oldest_type );
+		}
+		
+		if ( records_added == 0 ){
+			
+			tooltip_text.append( "\n    " + MessageText.getString( "pairing.ui.icon.tip.no.recent" ));
+		}
+		
+		if ( !tooltip_text.equals( last_tooltip_text )){
+			
+			last_tooltip_text = tooltip_text.toString();
+			
+			status.setTooltipText( last_tooltip_text );
+		}
+		
+		Image	target_image = null;
+		
+		long	age_newest_bad = now_mono - newest_bad_mono;
+	
+		if ( newest_bad_mono >= 0 && age_newest_bad <= BAD_EXPIRY ){
+			
+			target_image = icon_red;
+			
+			last_image_expiry_mono 		= newest_bad_mono + BAD_EXPIRY;
+		}else{
+			
+			long	age_newest_good = now_mono - newest_good_mono;
+
+			if ( newest_good_mono >= 0 && age_newest_good <= GOOD_EXPIRY ){
+				
+				target_image = icon_green;
+				
+				last_image_expiry_mono 		= age_newest_good + GOOD_EXPIRY;
+			}
+		}
+		
+		if ( target_image != null && target_image != last_image ){
+			
+			last_image = target_image;
+			
+			last_image_expiry_uc_min	= last_update_count + 2;
+			
+			status.setImage( target_image );
+		}
+	}
+	
+	private static class
+	RemoteHistory
+	{
+		private Map<String,RemoteHistoryEntry>	map = new HashMap<String, RemoteHistoryEntry>();
+			
+		private void
+		addRequest(
+			String		ip,
+			boolean		good )
+		{
+			RemoteHistoryEntry entry = map.get( ip );
+			
+			if ( entry == null ){
+				
+				entry = new RemoteHistoryEntry();
+				
+				map.put( ip, entry );
+			}
+			
+			entry.update( good );
+		}
+		
+		private Map<String,RemoteHistoryEntry>
+		getEntries()
+		{
+			return( map );
+		}
+	}
+	
+	private static class
+	RemoteHistoryEntry
+	{
+		private long		last_received_mono;
+		private long		last_received_rtc;
+		
+		private int			request_count;
+		private boolean		last_was_good;
+		
+		private long
+		getLastReceivedMono()
+		{
+			return( last_received_mono );
+		}
+		
+		private long
+		getLastReceivedRTC()
+		{
+			return( last_received_rtc );
+		}
+		
+		private int
+		getRequestCount()
+		{
+			return( request_count );
+		}
+		
+		private boolean
+		wasLastGood()
+		{
+			return( last_was_good );
+		}
+		
+		private void
+		update(
+			boolean	good )
+		{
+			last_received_mono	= SystemTime.getMonotonousTime();
+			last_received_rtc	= SystemTime.getCurrentTime();
+			
+			request_count++;
+			
+			last_was_good	= good;
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/peermanager/PeerManager.java b/com/aelitis/azureus/core/peermanager/PeerManager.java
index dcc10d5..2f8517b 100644
--- a/com/aelitis/azureus/core/peermanager/PeerManager.java
+++ b/com/aelitis/azureus/core/peermanager/PeerManager.java
@@ -22,6 +22,7 @@
 
 package com.aelitis.azureus.core.peermanager;
 
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.util.*;
@@ -34,7 +35,9 @@ import org.gudy.azureus2.core3.peer.PEPeerSource;
 import org.gudy.azureus2.core3.peer.impl.*;
 import org.gudy.azureus2.core3.peer.util.PeerIdentityManager;
 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
+import org.gudy.azureus2.core3.util.AEGenericCallback;
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.AERunStateHandler;
 import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Debug;
@@ -295,20 +298,28 @@ public class PeerManager implements AzureusCoreStatsProvider{
 
 						if ( routing_data.isKnownSeed( address )){
 
+							String reason = "Activation request from " + address + " denied as known seed";
+							
 							if (Logger.isEnabled()){
-								Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied as known seed" ));
+								Logger.log(new LogEvent(LOGID, reason  ));
 							}
 
+							transport.close( reason );
+							
 							routing_data = null;
 
 						}else{
 
 							if ( !routing_data.getAdapter().activateRequest( address )){
 
+								String reason = "Activation request from " + address + " denied by rules";
+								
 								if (Logger.isEnabled()){
-									Logger.log(new LogEvent(LOGID, "Activation request from " + address + " denied by rules" ));
+									Logger.log(new LogEvent(LOGID, reason ));
 								}
 
+								transport.close( reason );
+								
 								routing_data = null;	
 							}
 						}
@@ -696,7 +707,7 @@ public class PeerManager implements AzureusCoreStatsProvider{
 									"Incoming connection from [" + connection
 									                           + "] closed due to deactivation" ));
 
-						connection.close();
+						connection.close( "deactivated" );
 					}
 
 					pending_connections = null;
@@ -824,7 +835,7 @@ public class PeerManager implements AzureusCoreStatsProvider{
 							"Incoming connection from [" + connection
 							+ "] to " + adapter.getDescription() + " dropped as peer source disabled" ));
 				
-				connection.close();
+				connection.close( "peer source disabled" );
 
 				return;
 			}
@@ -849,7 +860,7 @@ public class PeerManager implements AzureusCoreStatsProvider{
 									"Incoming connection from [" + connection
 									+ "] to " + adapter.getDescription() + " dropped too many pending activations" ));
 						
-						connection.close();
+						connection.close( "too many pending activations" );
 
 						return;
 						
@@ -923,7 +934,7 @@ public class PeerManager implements AzureusCoreStatsProvider{
 									"Incoming connection from [" + connection
 									+ "] to " + adapter.getDescription() + " closed due to activation timeout" ));
 
-						connection.close();		
+						connection.close( "activation timeout" );		
 					}
 				}
 
@@ -951,28 +962,64 @@ public class PeerManager implements AzureusCoreStatsProvider{
 			// loopback connects for co-located proxy-based connections and
 			// testing
 
-			String host_address = connection.getEndpoint().getNotionalAddress().getAddress().getHostAddress();
+			Object callback = connection.getUserData( "RoutedCallback" );
+			
+			if ( callback instanceof AEGenericCallback ){
+				
+				try{
+					((AEGenericCallback)callback).invoke( control );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
 
-			boolean same_allowed = COConfigurationManager.getBooleanParameter( "Allow Same IP Peers" ) || host_address.equals( "127.0.0.1" );
+			ConnectionEndpoint ep = connection.getEndpoint();
+			
+			
+			InetAddress address = ep.getNotionalAddress().getAddress();
+			
+			String host_address = address.getHostAddress();
 
-			if( !same_allowed && PeerIdentityManager.containsIPAddress( control.getPeerIdentityDataID(), host_address ) ){
+			boolean same_allowed = COConfigurationManager.getBooleanParameter( "Allow Same IP Peers" ) || address.isLoopbackAddress();
 
-				if (Logger.isEnabled())
+			if ( !same_allowed && PeerIdentityManager.containsIPAddress( control.getPeerIdentityDataID(), host_address )){
+
+				if (Logger.isEnabled()){
+					
 					Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
 							"Incoming connection from [" + connection
 							+ "] dropped as IP address already "
 							+ "connected for ["
 							+ control.getDisplayName() + "]"));
-				connection.close();
+				}
+				
+				connection.close( "already connected to peer");
 
 				return;
 			}
 
-			if (Logger.isEnabled())
+			if ( AERunStateHandler.isUDPNetworkOnly()){
+				
+				if ( connection.getTransport().getTransportEndpoint().getProtocolEndpoint().getType() == ProtocolEndpoint.PROTOCOL_TCP ){
+					
+					if ( !connection.isLANLocal()){
+					
+						connection.close( "limited network mode: tcp disabled");
+
+						return;
+					}
+				}
+			}
+			
+			if (Logger.isEnabled()){
+				
 				Logger.log(new LogEvent(LOGID, "Incoming connection from ["
 						+ connection + "] routed to legacy download ["
 						+ control.getDisplayName() + "]"));
-
+			}
+			
 			PEPeerTransport	pt = PEPeerTransportFactory.createTransport( control, PEPeerSource.PS_INCOMING, connection, null );
 
 			if ( listener != null ){
@@ -992,7 +1039,7 @@ public class PeerManager implements AzureusCoreStatsProvider{
 
 				if ( !ok ){
 
-					connection.close();
+					connection.close( "routing denied" );
 
 					return;
 				}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
index 781ab35..64f897a 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZHandshake.java
@@ -64,6 +64,7 @@ public class AZHandshake implements AZMessage {
   private final int handshake_type;
   private final boolean uploadOnly;
   private final InetAddress ipv6;
+  private final int	md_size;
   
   
   public AZHandshake( byte[] peer_identity,
@@ -75,6 +76,7 @@ public class AZHandshake implements AZMessage {
                       int udp_listen_port,
                       int udp_non_data_listen_port,
                       InetAddress ipv6addr,
+                      int md_size,
                       String[] avail_msg_ids,
                       byte[] avail_msg_versions,
                       int _handshake_type,
@@ -95,6 +97,7 @@ public class AZHandshake implements AZMessage {
     this.version = _version;
     this.uploadOnly = uploadOnly;
     this.ipv6 = ipv6addr;
+    this.md_size = md_size;
     
     //verify given port info is ok
     if( tcp_port < 0 || tcp_port > 65535 ) {
@@ -133,7 +136,7 @@ public class AZHandshake implements AZMessage {
   public int getUDPListenPort() {  return udp_port;  }
   public int getUDPNonDataListenPort() {  return udp_non_data_port;  }
   public InetAddress getIPv6() { return ipv6; }
-  
+  public int getMetadataSize(){ return md_size; }
   public int getHandshakeType() {  return handshake_type;  }
   
     
@@ -163,6 +166,7 @@ public class AZHandshake implements AZMessage {
       							", handshake " + (getHandshakeType() == HANDSHAKE_TYPE_PLAIN ? "plain" : "crypto") +
       							", upload_only = " + (isUploadOnly() ? "1" : "0") + 
       							(ipv6 != null ? ", ipv6 = "+ipv6.getHostAddress() : "") +
+      							", md_size=" + md_size +
       							(sessionID != null ? ", sessionID: "+sessionID.toBase32String() : "") +
       							(reconnectID != null ? ", reconnect request: "+reconnectID.toBase32String() : "") +
       							"] supports " +msgs_desc;
@@ -190,7 +194,9 @@ public class AZHandshake implements AZMessage {
 			payload_map.put("upload_only", new Long(uploadOnly ? 1L : 0L));
 			if(ipv6 != null)
 				payload_map.put("ipv6", ipv6.getAddress());
-
+			if ( md_size > 0 ){
+				payload_map.put("mds", new Long(md_size));
+			}
 			//available message list
 			List message_list = new ArrayList();
 			for (int i = 0; i < avail_ids.length; i++)
@@ -269,7 +275,11 @@ public class AZHandshake implements AZMessage {
 			
 		}
 	}
-
+    int md_size = 0;
+    Long mds = (Long)root.get( "mds" );
+    if ( mds != null ){
+    	md_size = mds.intValue();
+    }
     List raw_msgs = (List) root.get("messages");
     if (raw_msgs == null)  throw new MessageException("raw_msgs == null");
 
@@ -297,7 +307,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(), ipv6 ,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, md_size, ids, vers, h_type.intValue(), version , uploadOnly);
   }
   
   
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessage.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessage.java
index a224203..bba3a2b 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessage.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessage.java
@@ -54,6 +54,19 @@ public interface AZMessage extends Message {
   public static final byte[] ID_AZ_BAD_PIECE_BYTES 		= ID_AZ_BAD_PIECE.getBytes();
   public static final int SUBID_ID_AZ_BAD_PIECE			= 5;
   
+  public static final String ID_AZ_STAT_REQUEST	    	= "AZ_STAT_REQ";
+  public static final byte[] ID_AZ_STAT_REQUEST_BYTES 	= ID_AZ_STAT_REQUEST.getBytes();
+  public static final int SUBID_ID_AZ_STAT_REQUEST		= 6;
+  
+  public static final String ID_AZ_STAT_REPLY	    	= "AZ_STAT_REP";
+  public static final byte[] ID_AZ_STAT_REPLY_BYTES 	= ID_AZ_STAT_REPLY.getBytes();
+  public static final int SUBID_ID_AZ_STAT_REPLY		= 7;
+  
+  public static final String ID_AZ_METADATA	    		= "AZ_METADATA";
+  public static final byte[] ID_AZ_METADATA_BYTES 		= ID_AZ_METADATA.getBytes();
+  public static final int SUBID_ID_AZ_METADATA			= 8;
+
+  
   //TODO
 
   public static final String ID_AZ_SESSION_SYN      	= "AZ_SESSION_SYN";
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageEncoder.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageEncoder.java
index 865a969..f0a9391 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageEncoder.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageEncoder.java
@@ -32,20 +32,30 @@ import com.aelitis.azureus.core.peermanager.messaging.*;
  * 
  *
  */
-public class AZMessageEncoder implements MessageStreamEncoder {
-
-  private boolean enable_padding;
-  
-  public AZMessageEncoder( boolean _enable_padding ) {
-  
-	  enable_padding = _enable_padding;
-  }
-  
-  
-  
-  public RawMessage[] encodeMessage( Message message ) {
-    return new RawMessage[]{ AZMessageFactory.createAZRawMessage( message, enable_padding  )};
-  }
-
-  
+
+public class 
+AZMessageEncoder 
+implements 
+	MessageStreamEncoder 
+{
+	public static final int PADDING_MODE_NONE			= 0;
+	public static final int PADDING_MODE_NORMAL			= 1;
+	public static final int PADDING_MODE_MINIMAL		= 2;
+	
+	private int padding_mode;
+
+	public 
+	AZMessageEncoder( 
+		int _padding_mode ) 
+	{
+		padding_mode = _padding_mode;
+	}
+
+
+
+	public RawMessage[] encodeMessage( Message message ) {
+		return new RawMessage[]{ AZMessageFactory.createAZRawMessage( message, padding_mode  )};
+	}
+
+
 }
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
index 3a3a3d4..ba18857 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMessageFactory.java
@@ -54,20 +54,25 @@ public class AZMessageFactory {
   
   
   
-  private static final Map legacy_data = new HashMap();
+  private static final Map<String,LegacyData> legacy_data = new HashMap<String,LegacyData>();
   static {
-    legacy_data.put( BTMessage.ID_BT_CHOKE, new LegacyData( RawMessage.PRIORITY_HIGH, true, new Message[]{new BTUnchoke((byte)0), new BTPiece(-1, -1, null,(byte)0 )} ) );
+    legacy_data.put( BTMessage.ID_BT_CHOKE, new LegacyData( RawMessage.PRIORITY_HIGH, true, new Message[]{new BTUnchoke((byte)0)})); // with support for fast extension we don't cancel outstanding piece data, new BTPiece(-1, -1, null,(byte)0 )} ) );
     legacy_data.put( BTMessage.ID_BT_UNCHOKE, new LegacyData( RawMessage.PRIORITY_NORMAL, true, new Message[]{new BTChoke((byte)0)} ) );
     legacy_data.put( BTMessage.ID_BT_INTERESTED, new LegacyData( RawMessage.PRIORITY_HIGH, true, new Message[]{new BTUninterested((byte)0)} ) );
     legacy_data.put( BTMessage.ID_BT_UNINTERESTED, new LegacyData( RawMessage.PRIORITY_NORMAL, false, new Message[]{new BTInterested((byte)0)} ) );
     legacy_data.put( BTMessage.ID_BT_HAVE, new LegacyData( RawMessage.PRIORITY_LOW, false, null ) );
     legacy_data.put( BTMessage.ID_BT_BITFIELD, new LegacyData( RawMessage.PRIORITY_HIGH, true, null ) );
+    legacy_data.put( BTMessage.ID_BT_HAVE_ALL, new LegacyData( RawMessage.PRIORITY_HIGH, true, null ) );
+    legacy_data.put( BTMessage.ID_BT_HAVE_NONE, new LegacyData( RawMessage.PRIORITY_HIGH, true, null ) );
     legacy_data.put( BTMessage.ID_BT_REQUEST, new LegacyData( RawMessage.PRIORITY_NORMAL, true, null ) );
+    legacy_data.put( BTMessage.ID_BT_REJECT_REQUEST, new LegacyData( RawMessage.PRIORITY_NORMAL, true, null ) );
     legacy_data.put( BTMessage.ID_BT_PIECE, new LegacyData( RawMessage.PRIORITY_LOW, false, null ) );
     legacy_data.put( BTMessage.ID_BT_CANCEL, new LegacyData( RawMessage.PRIORITY_HIGH, true, null ) );
     legacy_data.put( BTMessage.ID_BT_HANDSHAKE, new LegacyData( RawMessage.PRIORITY_HIGH, true, null ) );
     legacy_data.put( BTMessage.ID_BT_KEEP_ALIVE, new LegacyData( RawMessage.PRIORITY_LOW, false, null ) );
     legacy_data.put( BTMessage.ID_BT_DHT_PORT, new LegacyData( RawMessage.PRIORITY_LOW, false, null ) );
+    legacy_data.put( BTMessage.ID_BT_SUGGEST_PIECE, new LegacyData( RawMessage.PRIORITY_NORMAL, true, null ) );
+    legacy_data.put( BTMessage.ID_BT_ALLOWED_FAST, new LegacyData( RawMessage.PRIORITY_LOW, false, null ) );
   }
   
   
@@ -77,11 +82,14 @@ public class AZMessageFactory {
    */
   public static void init() {
     try {
-      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 AZHandshake( new byte[20], null, null, "", "", 0, 0, 0, null, 0, 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 ));
       MessageManager.getSingleton().registerMessageType( new AZBadPiece( -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new AZStatRequest( null, MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new AZStatReply( null, MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new AZMetaData( null, null, MESSAGE_VERSION_SUPPORTS_PADDING ));
 
       /*
       MessageManager.getSingleton().registerMessageType( new AZSessionSyn( new byte[20], -1, null) );
@@ -162,7 +170,7 @@ public class AZMessageFactory {
    * @param base_message to create from
    * @return AZ raw message
    */
-  public static RawMessage createAZRawMessage( Message base_message, boolean enable_padding ) {
+  public static RawMessage createAZRawMessage( Message base_message, int padding_mode ) {
     byte[] id_bytes = base_message.getIDBytes();
     byte version = base_message.getVersion();
     
@@ -178,9 +186,31 @@ public class AZMessageFactory {
     DirectByteBuffer header;
     
     if ( version >= MESSAGE_VERSION_SUPPORTS_PADDING ){
-    	    	
-    	short 	padding_length = enable_padding?(short)(( Math.random() * ( payload_size>256?SMALL_PAD_MAX:BIG_PAD_MAX ))+1):0;
-    	    	
+    	    
+    	boolean enable_padding = padding_mode != AZMessageEncoder.PADDING_MODE_NONE;
+    	
+    	short 	padding_length;
+    	
+    	if ( enable_padding ){
+    		
+    		if ( padding_mode == AZMessageEncoder.PADDING_MODE_MINIMAL ){
+    			
+       			padding_length = (short)(( Math.random() * SMALL_PAD_MAX  ));
+
+    		}else{
+    			
+    			padding_length = (short)(( Math.random() * ( payload_size>256?SMALL_PAD_MAX:BIG_PAD_MAX )));
+    		}
+    		
+    		if ( padding_length == 0 ){
+    			
+    			enable_padding = false;
+    		}
+    	}else{
+    		
+    		padding_length = 0;
+    	}
+    		    	
     	byte	flags = enable_padding?(byte)0x01:(byte)0x00;
     	
     	int	header_size = 4 + 4 + id_bytes.length + 1 + (enable_padding?(2+padding_length):0);
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMetaData.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMetaData.java
new file mode 100644
index 0000000..52c4e47
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZMetaData.java
@@ -0,0 +1,231 @@
+/*
+ * Created on Mar 7, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.peermanager.messaging.azureus;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.BDecoder;
+import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil;
+
+public class 
+AZMetaData 
+	implements AZMessage, AZUTMetaData
+{
+	private final byte version;
+	private DirectByteBuffer buffer = null;
+	  
+	private int					msg_type;
+	private int					piece;
+	private DirectByteBuffer	metadata;
+	private int					total_size;
+	
+	public
+	AZMetaData(
+		int		_piece,
+		byte	_version )
+	{
+		msg_type	= MSG_TYPE_REQUEST;
+		piece		= _piece;
+		version		= _version;
+	}
+	
+	public
+	AZMetaData(
+		int				_piece,
+		ByteBuffer		_data,
+		int				_total_size,
+		byte			_version )
+	{
+		msg_type	= _data==null?MSG_TYPE_REJECT:MSG_TYPE_DATA;
+		piece		= _piece;
+		total_size	= _total_size;
+		version		= _version;
+		
+		if ( _data != null ){
+			
+			metadata = new DirectByteBuffer( _data );
+		}
+	}
+	
+	public 
+	AZMetaData(
+		Map					map,
+		DirectByteBuffer	data,
+		byte				_version )
+	{
+		if ( map != null ){
+		
+			msg_type = ((Long)map.get( "msg_type" )).intValue();
+			piece	 = ((Long)map.get( "piece" )).intValue();
+		}
+		
+		metadata	= data;
+		version		= _version;
+	}
+	
+	public String 
+	getID()
+	{
+		return( ID_AZ_METADATA );
+	}
+
+	public byte[] 
+	getIDBytes()
+	{
+		return( ID_AZ_METADATA_BYTES );
+	}
+
+	public String 
+	getFeatureID() 
+	{  
+		return( AZ_FEATURE_ID );
+	}  
+	
+	public int 
+	getFeatureSubID() 
+	{ 
+		return SUBID_ID_AZ_METADATA;  
+	}
+	
+	public int 
+	getType() 
+	{  
+		return Message.TYPE_PROTOCOL_PAYLOAD;  
+	}
+	
+	public byte 
+	getVersion() 
+	{ 
+		return( version ); 
+	};
+
+	public String 
+	getDescription()
+	{
+		return( getID() + " piece #" + piece + ", mt=" + msg_type );
+	}
+
+	public int
+	getMessageType()
+	{
+		return( msg_type );
+	}
+	
+	public int
+	getPiece()
+	{
+		return( piece );
+	}
+	
+	public DirectByteBuffer
+	getMetadata()
+	{
+		return( metadata );
+	}
+	
+	public void
+	setMetadata(
+		DirectByteBuffer	b )
+	{
+		metadata = b;
+	}
+	
+	public DirectByteBuffer[] 
+	getData()
+	{
+		if ( buffer == null ){
+			
+			Map payload_map = new HashMap();
+
+			payload_map.put( "msg_type", new Long( msg_type ));
+			payload_map.put( "piece", new Long(piece));
+			
+			if ( total_size > 0 ){
+				
+				payload_map.put( "total_size", total_size );
+			}
+			
+			buffer = MessagingUtil.convertPayloadToBencodedByteStream(payload_map, DirectByteBuffer.AL_MSG_AZ_METADATA );
+		}
+
+		if ( msg_type == MSG_TYPE_DATA ){
+			
+			return new DirectByteBuffer[]{ buffer, metadata };
+			
+		}else{
+		
+			return new DirectByteBuffer[]{ buffer };
+		}
+	}
+
+
+
+	public Message 
+	deserialize( 
+		DirectByteBuffer 	data, 
+		byte 				version ) 
+
+		throws MessageException
+	{
+		int	pos = data.position( DirectByteBuffer.SS_MSG );
+		
+		byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ];
+					
+		data.get( DirectByteBuffer.SS_MSG, dict_bytes );
+		
+		try{
+			Map root = BDecoder.decode( dict_bytes );
+
+			data.position( DirectByteBuffer.SS_MSG, pos + BEncoder.encode( root ).length );			
+								
+			return( new AZMetaData( root, data, version ));
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+			
+			throw( new MessageException( "decode failed", e ));
+		}
+	}
+
+
+	public void 
+	destroy()
+	{
+		if ( buffer != null ){
+			
+			buffer.returnToPool();
+		}
+		
+		if ( metadata != null ){
+			
+			metadata.returnToPool();
+		}
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatReply.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatReply.java
new file mode 100644
index 0000000..7b38a53
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatReply.java
@@ -0,0 +1,134 @@
+/*
+ * Created on Jan 19, 2007
+ * Created by Paul Gardner
+ * 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.core.peermanager.messaging.azureus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil;
+
+public class 
+AZStatReply
+	implements AZMessage
+{
+	private final byte version;
+	private DirectByteBuffer buffer = null;
+
+	private Map	reply;
+	
+	public 
+	AZStatReply(
+		Map		_reply,
+		byte	_version )
+	{
+		reply		= _reply;
+		version		= _version;
+	}
+	
+	public String 
+	getID()
+	{
+		return( AZMessage.ID_AZ_STAT_REPLY );
+	}
+
+	public byte[] 
+	getIDBytes()
+	{
+		return( AZMessage.ID_AZ_STAT_REPLY_BYTES );		
+	}
+
+	public String 
+	getFeatureID()
+	{
+		return( AZMessage.AZ_FEATURE_ID );
+	}
+
+	public int 
+	getFeatureSubID()
+	{
+		return( AZMessage.SUBID_ID_AZ_STAT_REPLY );		
+	}
+
+	public int 
+	getType()
+	{
+		return( Message.TYPE_PROTOCOL_PAYLOAD );
+	}
+
+	public byte getVersion() { return version; };
+
+	public String 
+	getDescription() 
+	{   
+		return( getID() + ": " + reply );
+	}
+
+	public Map
+	getReply()
+	{
+		return( reply );
+	}
+	
+	public DirectByteBuffer[] 
+	getData() 
+	{
+		if ( buffer == null ){
+			
+			Map	map = new HashMap();
+			
+			map.put( "reply", reply );
+
+			buffer = MessagingUtil.convertPayloadToBencodedByteStream( map, DirectByteBuffer.AL_MSG );
+		} 
+		
+		return new DirectByteBuffer[]{ buffer };
+	}
+
+	public Message 
+	deserialize( 
+		DirectByteBuffer 	data,
+		byte				version ) 
+	
+		throws MessageException 
+	{
+		Map payload = MessagingUtil.convertBencodedByteStreamToPayload( data, 1, getID() );
+					
+		Map reply	= (Map)payload.get( "reply" );
+		
+		return( new AZStatReply( reply, version ));
+	}
+
+	public void 
+	destroy() 
+	{	
+		if ( buffer != null ){
+			
+			buffer.returnToPool();
+		}
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatRequest.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatRequest.java
new file mode 100644
index 0000000..7708fcd
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZStatRequest.java
@@ -0,0 +1,134 @@
+/*
+ * Created on Jan 19, 2007
+ * Created by Paul Gardner
+ * 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.core.peermanager.messaging.azureus;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil;
+
+public class 
+AZStatRequest
+	implements AZMessage
+{
+	private final byte version;
+	private DirectByteBuffer buffer = null;
+
+	private Map	request;
+	
+	public 
+	AZStatRequest(
+		Map		_request,
+		byte	_version )
+	{
+		request		= _request;
+		version		= _version;
+	}
+	
+	public String 
+	getID()
+	{
+		return( AZMessage.ID_AZ_STAT_REQUEST );
+	}
+
+	public byte[] 
+	getIDBytes()
+	{
+		return( AZMessage.ID_AZ_STAT_REQUEST_BYTES );		
+	}
+
+	public String 
+	getFeatureID()
+	{
+		return( AZMessage.AZ_FEATURE_ID );
+	}
+
+	public int 
+	getFeatureSubID()
+	{
+		return( AZMessage.SUBID_ID_AZ_STAT_REQUEST );		
+	}
+
+	public int 
+	getType()
+	{
+		return( Message.TYPE_PROTOCOL_PAYLOAD );
+	}
+
+	public byte getVersion() { return version; };
+
+	public String 
+	getDescription() 
+	{   
+		return( getID() + ": " + request );
+	}
+
+	public Map
+	getRequest()
+	{
+		return( request );
+	}
+	
+	public DirectByteBuffer[] 
+	getData() 
+	{
+		if ( buffer == null ){
+			
+			Map	map = new HashMap();
+			
+			map.put( "request", request );
+
+			buffer = MessagingUtil.convertPayloadToBencodedByteStream( map, DirectByteBuffer.AL_MSG );
+		} 
+		
+		return new DirectByteBuffer[]{ buffer };
+	}
+
+	public Message 
+	deserialize( 
+		DirectByteBuffer 	data,
+		byte				version ) 
+	
+		throws MessageException 
+	{
+		Map payload = MessagingUtil.convertBencodedByteStreamToPayload( data, 1, getID() );
+					
+		Map request	= (Map)payload.get( "request" );
+		
+		return( new AZStatRequest( request, version ));
+	}
+
+	public void 
+	destroy() 
+	{	
+		if ( buffer != null ){
+			
+			buffer.returnToPool();
+		}
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/peermanager/messaging/azureus/AZUTMetaData.java b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZUTMetaData.java
new file mode 100644
index 0000000..092cae8
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/azureus/AZUTMetaData.java
@@ -0,0 +1,48 @@
+/*
+ * Created on Mar 14, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.peermanager.messaging.azureus;
+
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+
+public interface 
+AZUTMetaData 
+{
+	public static final int MSG_TYPE_REQUEST	= 0;
+	public static final int MSG_TYPE_DATA		= 1;
+	public static final int MSG_TYPE_REJECT		= 2;
+	
+	public int
+	getMessageType();
+	
+	public int
+	getPiece();
+	
+	public DirectByteBuffer
+	getMetadata();
+	
+	public void
+	setMetadata(
+		DirectByteBuffer		metadata );
+	
+	public void
+	destroy();
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTAllowedFast.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTAllowedFast.java
new file mode 100644
index 0000000..40cc588
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTAllowedFast.java
@@ -0,0 +1,104 @@
+/*
+ * Created on Apr 30, 2004
+ * Created by Alon Rohter
+ * 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.peermanager.messaging.bittorrent;
+
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+
+
+public class BTAllowedFast implements BTMessage {
+  private DirectByteBuffer buffer = null;
+  private byte	version;
+  private String description = null;
+  
+  private final int piece_number;
+  
+  
+  public BTAllowedFast( int piece_number, byte version ) {
+    this.piece_number = piece_number;
+    this.version = version;
+  }
+  
+  
+  
+  public int getPieceNumber() {  return piece_number;  }
+    
+  
+  public String getID() {  return BTMessage.ID_BT_ALLOWED_FAST;  }
+  public byte[] getIDBytes() {  return BTMessage.ID_BT_ALLOWED_FAST_BYTES;  }
+  
+  public String getFeatureID() {  return BTMessage.BT_FEATURE_ID;  } 
+  
+  public int getFeatureSubID() {  return BTMessage.SUBID_BT_ALLOWED_FAST;  }
+  
+  public int getType() {  return Message.TYPE_PROTOCOL_PAYLOAD;  }
+    
+  public byte getVersion() { return version; };
+
+  public String getDescription() {
+    if( description == null ) {
+      description = BTMessage.ID_BT_ALLOWED_FAST + " piece #" + piece_number;
+    }
+    
+    return description; 
+  }
+  
+  
+  public DirectByteBuffer[] getData() {
+    if( buffer == null ) {
+      buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_MSG_BT_ALLOWED_FAST, 4 );
+      buffer.putInt( DirectByteBuffer.SS_MSG, piece_number );
+      buffer.flip( DirectByteBuffer.SS_MSG );
+    }
+    
+    return new DirectByteBuffer[]{ buffer };
+  }
+  
+  
+  public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException {
+    if( data == null ) {
+      throw new MessageException( "[" +getID() +"] decode error: data == null" );
+    }
+    
+    if( data.remaining( DirectByteBuffer.SS_MSG ) != 4 ) {
+      throw new MessageException( "[" +getID() +  "] decode error: payload.remaining[" +data.remaining( DirectByteBuffer.SS_MSG )+ "] != 12" );
+    }
+    
+    int num = data.getInt( DirectByteBuffer.SS_MSG );
+    if( num < 0 ) {
+      throw new MessageException( "[" +getID() + "] decode error: num < 0" );
+    }
+    
+    data.returnToPool();
+    
+    return new BTAllowedFast( num, version );
+  }
+
+  
+  public void destroy() {
+    if( buffer != null )  buffer.returnToPool();
+  }
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHandshake.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHandshake.java
index 6aa074e..6c49c8c 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHandshake.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHandshake.java
@@ -57,6 +57,23 @@ public class BTHandshake implements BTMessage, RawMessage {
 	  }
   }
   
+  public static final boolean FAST_EXTENSION_ENABLED = true;
+  
+  public static void setFastExtensionEnabled(boolean enabled) {
+	  if (enabled) {
+		  //BT_RESERVED[7] = (byte)(BT_RESERVED[7] | 0x04);
+		  AZ_RESERVED[7] = (byte)(AZ_RESERVED[7] | 0x04);
+	  }
+	  else {
+		  //BT_RESERVED[7] = (byte)(BT_RESERVED[7] & 0xF3);
+		  AZ_RESERVED[7] = (byte)(AZ_RESERVED[7] & 0xF3);		  
+	  }
+  }
+  
+  static{
+	  setFastExtensionEnabled( FAST_EXTENSION_ENABLED );
+  }
+  
   private DirectByteBuffer buffer = null;
   private String description = null;
   
@@ -170,6 +187,23 @@ public class BTHandshake implements BTMessage, RawMessage {
     
     data.returnToPool();
     
+    if ( peerid[0] == (byte)0 && peerid[1] == (byte)0){
+    	boolean ok = false;
+    	for (int i=2;i<20;i++){
+    		if ( peerid[i] != (byte)0){
+    			
+    			ok = true;
+    			break;
+    		}
+    	}
+    	if ( !ok ){
+    		byte[] x = ("-" + "#@" + "0000" + "-").getBytes();	// bad peer id decode
+    		
+    		RandomUtils.nextBytes( peerid );
+    		
+    		System.arraycopy(x, 0, peerid, 0, x.length );
+    	}
+    }
     return new BTHandshake( reserved, infohash, peerid, version );
   }
   
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveAll.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveAll.java
new file mode 100644
index 0000000..7f6d64d
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveAll.java
@@ -0,0 +1,66 @@
+/*
+ * Created on Apr 30, 2004
+ * Created by Alon Rohter
+ * 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.peermanager.messaging.bittorrent;
+
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+
+
+public class BTHaveAll implements BTMessage {
+  
+  private byte version;
+	
+  public BTHaveAll(byte _version) {
+    version = _version;
+  }
+    
+  public String getID() {  return BTMessage.ID_BT_HAVE_ALL;  }
+  public byte[] getIDBytes() {  return BTMessage.ID_BT_HAVE_ALL_BYTES;  }
+  
+  public String getFeatureID() {  return BTMessage.BT_FEATURE_ID;  } 
+  
+  public int getFeatureSubID() {  return BTMessage.SUBID_BT_HAVE_ALL;  }
+  
+  public int getType() {  return Message.TYPE_PROTOCOL_PAYLOAD;  }
+    
+  public byte getVersion() { return version; };
+
+  public String getDescription() {  return BTMessage.ID_BT_HAVE_ALL;  }
+  
+  public DirectByteBuffer[] getData() {  return new DirectByteBuffer[] {};  }
+  
+  public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException {
+    if( data != null && data.hasRemaining( DirectByteBuffer.SS_MSG ) ) {
+      throw new MessageException( "[" +getID() + "] decode error: payload not empty [" +data.remaining(DirectByteBuffer.SS_MSG)+ "]" );
+    }
+    
+    if( data != null )  data.returnToPool();
+    
+    return new BTHaveAll(version);
+  }
+  
+  public void destroy() {  /*nothing*/  }
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveNone.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveNone.java
new file mode 100644
index 0000000..52952c2
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTHaveNone.java
@@ -0,0 +1,66 @@
+/*
+ * Created on Apr 30, 2004
+ * Created by Alon Rohter
+ * 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.peermanager.messaging.bittorrent;
+
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+
+
+public class BTHaveNone implements BTMessage {
+  
+  private byte version;
+	
+  public BTHaveNone(byte _version) {
+    version = _version;
+  }
+    
+  public String getID() {  return BTMessage.ID_BT_HAVE_NONE;  }
+  public byte[] getIDBytes() {  return BTMessage.ID_BT_HAVE_NONE_BYTES;  }
+  
+  public String getFeatureID() {  return BTMessage.BT_FEATURE_ID;  } 
+  
+  public int getFeatureSubID() {  return BTMessage.SUBID_BT_HAVE_NONE;  }
+  
+  public int getType() {  return Message.TYPE_PROTOCOL_PAYLOAD;  }
+    
+  public byte getVersion() { return version; };
+
+  public String getDescription() {  return BTMessage.ID_BT_HAVE_NONE;  }
+  
+  public DirectByteBuffer[] getData() {  return new DirectByteBuffer[] {};  }
+  
+  public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException {
+    if( data != null && data.hasRemaining( DirectByteBuffer.SS_MSG ) ) {
+      throw new MessageException( "[" +getID() + "] decode error: payload not empty [" +data.remaining(DirectByteBuffer.SS_MSG)+ "]" );
+    }
+    
+    if( data != null )  data.returnToPool();
+    
+    return new BTHaveNone(version);
+  }
+  
+  public void destroy() {  /*nothing*/  }
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessage.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessage.java
index 9168dc0..5e2f788 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessage.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessage.java
@@ -73,14 +73,32 @@ public interface BTMessage extends Message {
   public static final String ID_BT_HANDSHAKE    	= "BT_HANDSHAKE";
   public static final byte[] ID_BT_HANDSHAKE_BYTES  = ID_BT_HANDSHAKE.getBytes();
   public static final int SUBID_BT_HANDSHAKE		= 10;
-  
+
   public static final String ID_BT_KEEP_ALIVE   	= "BT_KEEP_ALIVE";
   public static final byte[] ID_BT_KEEP_ALIVE_BYTES = ID_BT_KEEP_ALIVE.getBytes();
   public static final int SUBID_BT_KEEP_ALIVE		= 11;
+
+  public static final String ID_BT_SUGGEST_PIECE   	= "BT_SUGGEST_PIECE";
+  public static final byte[] ID_BT_SUGGEST_PIECE_BYTES = ID_BT_SUGGEST_PIECE.getBytes();
+  public static final int SUBID_BT_SUGGEST_PIECE	= 13;
+  
+  public static final String ID_BT_HAVE_ALL   		= "BT_HAVE_ALL";
+  public static final byte[] ID_BT_HAVE_ALL_BYTES 	= ID_BT_HAVE_ALL.getBytes();
+  public static final int SUBID_BT_HAVE_ALL			= 14;
+
+  public static final String ID_BT_HAVE_NONE	   	= "BT_HAVE_NONE";
+  public static final byte[] ID_BT_HAVE_NONE_BYTES = ID_BT_HAVE_NONE.getBytes();
+  public static final int SUBID_BT_HAVE_NONE		= 15;
+
+  public static final String ID_BT_REJECT_REQUEST  	= "BT_REJECT_REQUEST";
+  public static final byte[] ID_BT_REJECT_REQUEST_BYTES = ID_BT_REJECT_REQUEST.getBytes();
+  public static final int SUBID_BT_REJECT_REQUEST	= 16;
+
+  public static final String ID_BT_ALLOWED_FAST   	= "BT_ALLOWED_FAST";
+  public static final byte[] ID_BT_ALLOWED_FAST_BYTES = ID_BT_ALLOWED_FAST.getBytes();
+  public static final int SUBID_BT_ALLOWED_FAST		= 17;
   
   public static final String ID_BT_LT_EXT_MESSAGE        = "BT_LT_EXT_MESSAGE";
   public static final byte[] ID_BT_LT_EXT_MESSAGE_BYTES  = ID_BT_LT_EXT_MESSAGE.getBytes();
   public static final int SUBID_BT_LT_EXT_MESSAGE	= 20;
-
-
 }
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageDecoder.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageDecoder.java
index eb71a95..dac7eb2 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageDecoder.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageDecoder.java
@@ -156,17 +156,23 @@ public class BTMessageDecoder implements MessageStreamDecoder {
     is_paused = true;
     destroyed = true;
     
+    	// there's a concurrency issue with the decoder whereby it can be destroyed while will being messed with. Don't
+    	// have the energy to look into it properly atm so just try to ensure that it doesn't bork too badly (parg: 29/04/2012)
+    	// only occasional but does have potential to generate direct buffer mem leak ;(
+    
     int lbuff_read = 0;
     int pbuff_read = 0;
     length_buffer.limit( SS, 4 );
     
+    DirectByteBuffer plb = payload_buffer;
+    
     if( reading_length_mode ) {
       lbuff_read = length_buffer.position( SS );
     }
     else { //reading payload
       length_buffer.position( SS, 4 );
       lbuff_read = 4;
-      pbuff_read = payload_buffer == null ? 0 : payload_buffer.position( SS );
+      pbuff_read = plb == null ? 0 : plb.position( SS );
     }
     
     ByteBuffer unused = ByteBuffer.allocate( lbuff_read + pbuff_read );   //TODO convert to direct?
@@ -174,23 +180,32 @@ public class BTMessageDecoder implements MessageStreamDecoder {
     length_buffer.flip( SS );
     unused.put( length_buffer.getBuffer( SS ) );
     
-    if ( payload_buffer != null ) {
-      payload_buffer.flip( SS );
-      unused.put( payload_buffer.getBuffer( SS ) ); // Got a buffer overflow exception here in the past - related to PEX?
+    try{
+	    if ( plb != null ) {
+	    	plb.flip( SS );
+	    	unused.put( plb.getBuffer( SS ) ); // Got a buffer overflow exception here in the past - related to PEX?
+	    }
+    }catch( RuntimeException e ){
+    	Debug.out( "hit known threading issue" );
     }
     
     unused.flip();
 
     length_buffer.returnToPool();
     
-    if( payload_buffer != null ) {
-      payload_buffer.returnToPool();
-      payload_buffer = null;
+    if( plb != null ) {
+    	plb.returnToPool();
+    	payload_buffer = null;
     }
  
-    for( int i=0; i < messages_last_read.size(); i++ ) {
-      Message msg = (Message)messages_last_read.get( i );
-      msg.destroy();
+    try{
+	    for( int i=0; i < messages_last_read.size(); i++ ) {
+	      Message msg = (Message)messages_last_read.get( i );
+	      msg.destroy();
+	    }
+    }catch( RuntimeException e ){
+    	// happens if messages modified by alt thread...
+    	Debug.out( "hit known threading issue" );
     }
     messages_last_read.clear();
     
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageFactory.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageFactory.java
index 12e7798..372c98d 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageFactory.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTMessageFactory.java
@@ -59,6 +59,11 @@ public class BTMessageFactory {
       MessageManager.getSingleton().registerMessageType( new BTRequest( -1, -1 , -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new BTUnchoke( MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new BTUninterested( MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new BTSuggestPiece( -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new BTHaveAll( MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new BTHaveNone( MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new BTRejectRequest( -1, -1, -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
+      MessageManager.getSingleton().registerMessageType( new BTAllowedFast( -1, MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new BTLTMessage( null, MESSAGE_VERSION_SUPPORTS_PADDING ));
       MessageManager.getSingleton().registerMessageType( new BTDHTPort(-1));
     }
@@ -101,6 +106,21 @@ public class BTMessageFactory {
     legacy_data.put( BTMessage.ID_BT_DHT_PORT, new LegacyData( RawMessage.PRIORITY_LOW, true, null, (byte)9 ) );
     id_to_name[9] = BTMessage.ID_BT_DHT_PORT;
     
+    legacy_data.put( BTMessage.ID_BT_SUGGEST_PIECE, new LegacyData( RawMessage.PRIORITY_NORMAL, true, null, (byte)13 ) );
+    id_to_name[13] = BTMessage.ID_BT_SUGGEST_PIECE;
+    
+    legacy_data.put( BTMessage.ID_BT_HAVE_ALL, new LegacyData( RawMessage.PRIORITY_HIGH, true, null, (byte)14 ) );
+    id_to_name[14] = BTMessage.ID_BT_HAVE_ALL;
+    
+    legacy_data.put( BTMessage.ID_BT_HAVE_NONE, new LegacyData( RawMessage.PRIORITY_HIGH, true, null, (byte)15 ) );
+    id_to_name[15] = BTMessage.ID_BT_HAVE_NONE;
+    
+    legacy_data.put( BTMessage.ID_BT_REJECT_REQUEST, new LegacyData( RawMessage.PRIORITY_NORMAL, true, null, (byte)16 ) );
+    id_to_name[16] = BTMessage.ID_BT_REJECT_REQUEST;
+    
+    legacy_data.put( BTMessage.ID_BT_ALLOWED_FAST, new LegacyData( RawMessage.PRIORITY_LOW, false, null, (byte)17 ) );
+    id_to_name[17] = BTMessage.ID_BT_ALLOWED_FAST;
+ 
     legacy_data.put( BTMessage.ID_BT_LT_EXT_MESSAGE, new LegacyData( RawMessage.PRIORITY_HIGH, true, null, (byte)20 ) );
     id_to_name[20] = BTMessage.ID_BT_LT_EXT_MESSAGE;
   }
@@ -151,6 +171,21 @@ public class BTMessageFactory {
       case 9:
     	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_DHT_PORT_BYTES, stream_payload, (byte)1 );
 
+      case 13:
+      	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_SUGGEST_PIECE_BYTES, stream_payload, (byte)1 );
+
+      case 14:
+      	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_HAVE_ALL_BYTES, stream_payload, (byte)1 );
+
+      case 15:
+      	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_HAVE_NONE_BYTES, stream_payload, (byte)1 );
+
+      case 16:
+      	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_REJECT_REQUEST_BYTES, stream_payload, (byte)1 );
+
+      case 17:
+      	return MessageManager.getSingleton().createMessage( BTMessage.ID_BT_ALLOWED_FAST_BYTES, stream_payload, (byte)1 );
+
       case 20:
     	  //Clients seeing our handshake reserved bit will send us the old 'extended' messaging hello message accidentally.
    		  //Instead of throwing an exception and dropping the peer connection, we'll just fake it as a keep-alive :)
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTRejectRequest.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTRejectRequest.java
new file mode 100644
index 0000000..ac7eff6
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTRejectRequest.java
@@ -0,0 +1,144 @@
+/*
+ * Created on Apr 30, 2004
+ * Created by Alon Rohter
+ * 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.peermanager.messaging.bittorrent;
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+
+
+
+/**
+ * NOTE: Overrides equals()
+ */
+public class BTRejectRequest implements BTMessage {
+  private byte version;
+  private DirectByteBuffer buffer = null;
+  private String description = null;
+  
+  private final int piece_number;
+  private final int piece_offset;
+  private final int length;
+  private final int hashcode;
+  
+  
+  public BTRejectRequest( int piece_number, int piece_offset, int length, byte version ) {
+    this.piece_number = piece_number;
+    this.piece_offset = piece_offset;
+    this.length = length;
+    this.version = version;
+    this.hashcode = piece_number + piece_offset + length;
+  }
+
+  
+  public int getPieceNumber() {  return piece_number;  }
+  
+  public int getPieceOffset() {  return piece_offset;  }
+  
+  public int getLength() {  return length;  }
+  
+  
+    
+  public String getID() {  return BTMessage.ID_BT_REJECT_REQUEST;  }
+  public byte[] getIDBytes() {  return BTMessage.ID_BT_REJECT_REQUEST_BYTES;  }
+  
+  public String getFeatureID() {  return BTMessage.BT_FEATURE_ID;  } 
+  
+  public int getFeatureSubID() {  return BTMessage.SUBID_BT_REJECT_REQUEST;  }
+  
+  public int getType() {  return Message.TYPE_PROTOCOL_PAYLOAD;  }
+    
+  public byte getVersion() { return version; };
+
+  public String getDescription() {
+    if( description == null ) {
+      description = BTMessage.ID_BT_REJECT_REQUEST + " piece #" + piece_number + ":" + piece_offset + "->" + (piece_offset + length -1);
+    }
+    
+    return description;
+  }
+  
+  
+  public DirectByteBuffer[] getData() {
+    if( buffer == null ) {
+      buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_MSG_BT_REJECT_REQUEST, 12 );
+      buffer.putInt( DirectByteBuffer.SS_MSG, piece_number );
+      buffer.putInt( DirectByteBuffer.SS_MSG, piece_offset );
+      buffer.putInt( DirectByteBuffer.SS_MSG, length );
+      buffer.flip( DirectByteBuffer.SS_MSG );
+    }
+    
+    return new DirectByteBuffer[]{ buffer };
+  }
+  
+  
+  public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException {   
+    if( data == null ) {
+      throw new MessageException( "[" +getID() + "] decode error: data == null" );
+    }
+    
+    if( data.remaining( DirectByteBuffer.SS_MSG ) != 12 ) {
+      throw new MessageException( "[" +getID() + "] decode error: payload.remaining[" +data.remaining( DirectByteBuffer.SS_MSG )+ "] != 12" );
+    }
+    
+    int num = data.getInt( DirectByteBuffer.SS_MSG );
+    if( num < 0 ) {
+      throw new MessageException( "[" +getID() + "] decode error: num < 0" );
+    }
+    
+    int offset = data.getInt( DirectByteBuffer.SS_MSG );
+    if( offset < 0 ) {
+      throw new MessageException( "[" +getID() + "] decode error: offset < 0" );
+    }
+    
+    int length = data.getInt( DirectByteBuffer.SS_MSG );
+    if( length < 0 ) {
+      throw new MessageException( "[" +getID() + "] decode error: length < 0" );
+    }
+    
+    data.returnToPool();
+    
+    return new BTRejectRequest( num, offset, length, version );
+  }
+  
+  
+  public void destroy() {
+    if( buffer != null )  buffer.returnToPool();
+  } 
+  
+  
+  //used for removing individual requests from the message queue
+  public boolean equals( Object obj ) {
+    if( this == obj )  return true;
+    if( obj != null && obj instanceof BTRejectRequest ) {
+      BTRejectRequest other = (BTRejectRequest)obj;
+      if( other.piece_number == this.piece_number &&
+          other.piece_offset == this.piece_offset &&
+          other.length == this.length )  return true;
+    }
+    return false;
+  }
+
+  public int hashCode() {  return hashcode;  }
+}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTSuggestPiece.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTSuggestPiece.java
new file mode 100644
index 0000000..3051a6e
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/BTSuggestPiece.java
@@ -0,0 +1,104 @@
+/*
+ * Created on Apr 30, 2004
+ * Created by Alon Rohter
+ * 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.peermanager.messaging.bittorrent;
+
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+
+
+public class BTSuggestPiece implements BTMessage {
+  private DirectByteBuffer buffer = null;
+  private byte	version;
+  private String description = null;
+  
+  private final int piece_number;
+  
+  
+  public BTSuggestPiece( int piece_number, byte version ) {
+    this.piece_number = piece_number;
+    this.version = version;
+  }
+  
+  
+  
+  public int getPieceNumber() {  return piece_number;  }
+    
+  
+  public String getID() {  return BTMessage.ID_BT_SUGGEST_PIECE;  }
+  public byte[] getIDBytes() {  return BTMessage.ID_BT_SUGGEST_PIECE_BYTES;  }
+  
+  public String getFeatureID() {  return BTMessage.BT_FEATURE_ID;  } 
+  
+  public int getFeatureSubID() {  return BTMessage.SUBID_BT_SUGGEST_PIECE;  }
+  
+  public int getType() {  return Message.TYPE_PROTOCOL_PAYLOAD;  }
+    
+  public byte getVersion() { return version; };
+
+  public String getDescription() {
+    if( description == null ) {
+      description = BTMessage.ID_BT_SUGGEST_PIECE + " piece #" + piece_number;
+    }
+    
+    return description; 
+  }
+  
+  
+  public DirectByteBuffer[] getData() {
+    if( buffer == null ) {
+      buffer = DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_MSG_BT_SUGGEST_PIECE, 4 );
+      buffer.putInt( DirectByteBuffer.SS_MSG, piece_number );
+      buffer.flip( DirectByteBuffer.SS_MSG );
+    }
+    
+    return new DirectByteBuffer[]{ buffer };
+  }
+  
+  
+  public Message deserialize( DirectByteBuffer data, byte version ) throws MessageException {
+    if( data == null ) {
+      throw new MessageException( "[" +getID() +"] decode error: data == null" );
+    }
+    
+    if( data.remaining( DirectByteBuffer.SS_MSG ) != 4 ) {
+      throw new MessageException( "[" +getID() +  "] decode error: payload.remaining[" +data.remaining( DirectByteBuffer.SS_MSG )+ "] != 12" );
+    }
+    
+    int num = data.getInt( DirectByteBuffer.SS_MSG );
+    if( num < 0 ) {
+      throw new MessageException( "[" +getID() + "] decode error: num < 0" );
+    }
+    
+    data.returnToPool();
+    
+    return new BTSuggestPiece( num, version );
+  }
+
+  
+  public void destroy() {
+    if( buffer != null )  buffer.returnToPool();
+  }
+}
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 b338e98..ed6d3ab 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTHandshake.java
@@ -3,6 +3,7 @@ package com.aelitis.azureus.core.peermanager.messaging.bittorrent.ltep;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.util.*;
@@ -105,8 +106,55 @@ public class LTHandshake implements LTMessage {
 	}
 	
 	public boolean isUploadOnly() {
-		Long ulOnly = (Long)data_dict.get("upload_only");
-		return ulOnly != null && ulOnly.longValue() > 0L;
+			// been seeing a bunch of 
+			// java.lang.ClassCastException: [B cannot be cast to java.lang.Long
+		    // at com.aelitis.azureus.core.peermanager.messaging.bittorrent.ltep.LTHandshake.isUploadOnly(LTHandshake.java:108)
+
+		Object ulOnly = data_dict.get("upload_only");
+
+		if ( ulOnly == null ){
+			return( false );
+		}else if ( ulOnly instanceof Number ){
+			Number n_ulOnly = (Number)ulOnly;
+			return n_ulOnly.longValue() > 0L;
+		}else{
+				// seeing String value '0' here....
+			
+			if ( ulOnly instanceof byte[] ){
+				
+				String	str_val = new String((byte[])ulOnly );
+				
+				try{
+					int i = Integer.parseInt( str_val );
+					
+					return( i > 0 );
+					
+				}catch( Throwable e ){
+				}
+			}
+			
+			String debug;
+			
+			if ( ulOnly instanceof byte[] ){
+				
+				byte[] bytes = (byte[])ulOnly;
+				
+				debug = new String(bytes) + "/";
+				
+				for ( int i=0;i<bytes.length;i++){
+					
+					debug += (i==0?"":",") + (((int)bytes[i]) & 0x00ff );
+				}
+				
+			}else{
+				
+				debug = String.valueOf( ulOnly );
+			}
+			
+			Debug.out( "Invalid entry for 'upload_only' - " + debug + ", map=" + data_dict );
+			
+			return( false );
+		}
 	}
 	
 	public InetAddress getIPv6() {
@@ -150,6 +198,44 @@ public class LTHandshake implements LTMessage {
 		return (result == null) ? Collections.EMPTY_MAP : result;
 	}
 
+	public int
+	getMetadataSize()
+	{
+		Long l = (Long)data_dict.get( "metadata_size" );
+		
+		if ( l != null ){
+			
+			return( l.intValue());
+		}
+		
+		return( 0 );
+	}
+	
+	public void
+	addDefaultExtensionMappings(
+		boolean		enable_pex,
+		boolean		enable_md )
+	{
+		if ( enable_pex | enable_md ){
+			Map ext = (Map)data_dict.get("m");
+			
+			if ( ext == null ){
+				ext = new HashMap();
+				data_dict.put( "m", ext );
+			}
+	
+			if ( enable_pex ){
+				
+				ext.put( ID_UT_PEX, new Long( SUBID_UT_PEX ));
+			}
+			
+			if ( enable_md ){
+				
+				ext.put( ID_UT_METADATA, new Long( SUBID_UT_METADATA ));
+			}
+		}
+	}
+	
 	public String getFeatureID() {return LTMessage.LT_FEATURE_ID;}
 	public int getFeatureSubID() {return LTMessage.SUBID_LT_HANDSHAKE;}
 	public String getID() {return LTHandshake.ID_LT_HANDSHAKE;}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessage.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessage.java
index a114980..cfb1789 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessage.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessage.java
@@ -43,4 +43,9 @@ public interface LTMessage extends Message {
 	public static final String ID_DISABLED_EXT       = "disabled_extension";
 	public static final byte[] ID_DISABLED_EXT_BYTES = ID_DISABLED_EXT.getBytes();
 	public static final int SUBID_DISABLED_EXT       = 2;
+	
+	public static final String ID_UT_METADATA        = "ut_metadata";
+	public static final byte[] ID_UT_METADATA_BYTES  = ID_UT_METADATA.getBytes();
+	public static final int SUBID_UT_METADATA        = 3;
+
 }
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageDecoder.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageDecoder.java
index 0ba6c17..13d5cfd 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageDecoder.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageDecoder.java
@@ -56,6 +56,8 @@ public class LTMessageDecoder extends BTMessageDecoder {
 				return MessageManager.getSingleton().createMessage(LTMessage.ID_LT_HANDSHAKE_BYTES, ref_buff, (byte)1);
 			case 1:
 				return MessageManager.getSingleton().createMessage(LTMessage.ID_UT_PEX_BYTES, ref_buff, (byte)1);
+			case 3:
+				return MessageManager.getSingleton().createMessage(LTMessage.ID_UT_METADATA_BYTES, ref_buff, (byte)1);
 			default: {
 			  byte[]	message_id;
 			  synchronized( entension_handlers ){
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageEncoder.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageEncoder.java
index fd761d6..7c84923 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageEncoder.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageEncoder.java
@@ -128,7 +128,15 @@ public class LTMessageEncoder implements MessageStreamEncoder {
 	
 	public boolean supportsUTPEX() {
 		if (this.extension_map == null) {return false;}
-		return this.extension_map.containsKey("ut_pex");
+		Number num = (Number)this.extension_map.get("ut_pex");
+		
+		return( num != null && num.intValue() != 0 );
 	}
 
+	public boolean supportsUTMetaData() {
+		if (this.extension_map == null) {return false;}
+		Number num = (Number)this.extension_map.get("ut_metadata");
+		
+		return( num != null && num.intValue() != 0 );
+	}
 }
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageFactory.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageFactory.java
index 589692d..a5882dd 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageFactory.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/LTMessageFactory.java
@@ -36,6 +36,7 @@ public class LTMessageFactory {
 		try {
 			MessageManager.getSingleton().registerMessageType(new LTHandshake(null, MESSAGE_VERSION_SUPPORTS_PADDING));
 			MessageManager.getSingleton().registerMessageType(new UTPeerExchange(null, null, null, MESSAGE_VERSION_SUPPORTS_PADDING));
+			MessageManager.getSingleton().registerMessageType(new UTMetaData(null, null, MESSAGE_VERSION_SUPPORTS_PADDING));
 		}
 	    catch( MessageException me ) {  me.printStackTrace();  }
 	}
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTMetaData.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTMetaData.java
new file mode 100644
index 0000000..39965c4
--- /dev/null
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTMetaData.java
@@ -0,0 +1,232 @@
+/*
+ * Created on Mar 7, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.peermanager.messaging.bittorrent.ltep;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.BDecoder;
+import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+
+import com.aelitis.azureus.core.peermanager.messaging.Message;
+import com.aelitis.azureus.core.peermanager.messaging.MessageException;
+import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil;
+import com.aelitis.azureus.core.peermanager.messaging.azureus.AZUTMetaData;
+
+public class 
+UTMetaData 
+	implements LTMessage, AZUTMetaData
+{
+	private final byte version;
+	private DirectByteBuffer buffer = null;
+	  
+	private int					msg_type;
+	private int					piece;
+	private DirectByteBuffer	metadata;
+	private int					total_size;
+	
+	public
+	UTMetaData(
+		int		_piece,
+		byte	_version )
+	{
+		msg_type	= MSG_TYPE_REQUEST;
+		piece		= _piece;
+		version		= _version;
+	}
+	
+	public
+	UTMetaData(
+		int				_piece,
+		ByteBuffer		_data,
+		int				_total_size,
+		byte			_version )
+	{
+		msg_type	= _data==null?MSG_TYPE_REJECT:MSG_TYPE_DATA;
+		piece		= _piece;
+		total_size	= _total_size;
+		version		= _version;
+		
+		if ( _data != null ){
+			
+			metadata = new DirectByteBuffer( _data );
+		}
+	}
+	
+	public 
+	UTMetaData(
+		Map					map,
+		DirectByteBuffer	data,
+		byte				_version )
+	{
+		if ( map != null ){
+		
+			msg_type = ((Long)map.get( "msg_type" )).intValue();
+			piece	 = ((Long)map.get( "piece" )).intValue();
+		}
+		
+		metadata	= data;
+		version		= _version;
+	}
+	
+	public String 
+	getID()
+	{
+		return( ID_UT_METADATA );
+	}
+
+	public byte[] 
+	getIDBytes()
+	{
+		return( ID_UT_METADATA_BYTES );
+	}
+
+	public String 
+	getFeatureID() 
+	{  
+		return LTMessage.LT_FEATURE_ID;  
+	}  
+	
+	public int 
+	getFeatureSubID() 
+	{ 
+		return SUBID_UT_METADATA;  
+	}
+	
+	public int 
+	getType() 
+	{  
+		return Message.TYPE_PROTOCOL_PAYLOAD;  
+	}
+	
+	public byte 
+	getVersion() 
+	{ 
+		return version; 
+	};
+
+	public String 
+	getDescription()
+	{
+		return( ID_UT_METADATA );
+	}
+
+	public int
+	getMessageType()
+	{
+		return( msg_type );
+	}
+	
+	public int
+	getPiece()
+	{
+		return( piece );
+	}
+	
+	public DirectByteBuffer
+	getMetadata()
+	{
+		return( metadata );
+	}
+	
+	public void
+	setMetadata(
+		DirectByteBuffer	b )
+	{
+		metadata = b;
+	}
+	
+	public DirectByteBuffer[] 
+	getData()
+	{
+		if ( buffer == null ){
+			
+			Map payload_map = new HashMap();
+
+			payload_map.put( "msg_type", new Long( msg_type ));
+			payload_map.put( "piece", new Long(piece));
+			
+			if ( total_size > 0 ){
+				
+				payload_map.put( "total_size", total_size );
+			}
+			
+			buffer = MessagingUtil.convertPayloadToBencodedByteStream(payload_map, DirectByteBuffer.AL_MSG_UT_METADATA );
+		}
+
+		if ( msg_type == MSG_TYPE_DATA ){
+			
+			return new DirectByteBuffer[]{ buffer, metadata };
+			
+		}else{
+		
+			return new DirectByteBuffer[]{ buffer };
+		}
+	}
+
+
+
+	public Message 
+	deserialize( 
+		DirectByteBuffer 	data, 
+		byte 				version ) 
+
+		throws MessageException
+	{
+		int	pos = data.position( DirectByteBuffer.SS_MSG );
+		
+		byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ];
+					
+		data.get( DirectByteBuffer.SS_MSG, dict_bytes );
+		
+		try{
+			Map root = BDecoder.decode( dict_bytes );
+
+			data.position( DirectByteBuffer.SS_MSG, pos + BEncoder.encode( root ).length );			
+								
+			return( new UTMetaData( root, data, version ));
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+			
+			throw( new MessageException( "decode failed", e ));
+		}
+	}
+
+
+	public void 
+	destroy()
+	{
+		if ( buffer != null ){
+			
+			buffer.returnToPool();
+		}
+		
+		if ( metadata != null ){
+			
+			metadata.returnToPool();
+		}
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTPeerExchange.java b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTPeerExchange.java
index 9fb0b6f..0230fef 100644
--- a/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTPeerExchange.java
+++ b/com/aelitis/azureus/core/peermanager/messaging/bittorrent/ltep/UTPeerExchange.java
@@ -41,10 +41,7 @@ import com.aelitis.azureus.core.peermanager.peerdb.PeerItemFactory;
  * Largely copied from AZPeerExchange.
  */
 public class UTPeerExchange implements AZStylePeerExchange, LTMessage {
-	
-	// Debug flag for testing purposes - currently disabled by default.
-    public static final boolean ENABLED = true; 
-	
+		
 	  private static final LogIDs LOGID = LogIDs.NET;
 
 	  private static final int IPv4_SIZE_WITH_PORT = 6;
@@ -241,9 +238,15 @@ public class UTPeerExchange implements AZStylePeerExchange, LTMessage {
 	   * swarms over a short period, the biggest "added" list I saw was one
 	   * containing 38 peers, so it's quite possible list sizes above 50 get
 	   * sent out. So 100 is a safe-ish figure. 
+	   * 
+	   * Update: uTorrent doesn't have any set limits on this, apparently it simply
+	   * depends on the number of connections a peer has, which can be large for
+	   * fast peers (I've seen 350 peers for example). Increased limits somewhat
+	   * and added code to ignore excessive peers rather than dropping the
+	   * connection 
 	   */
 	  public int getMaxAllowedPeersPerVolley(boolean initial, boolean added) {
-		  return (initial && added) ? 200 : 100;
+		  return (initial && added) ? 500 : 250;
 	  }
 
 	  /**** DEBUG STUFF ****/
diff --git a/com/aelitis/azureus/core/peermanager/peerdb/PeerDatabase.java b/com/aelitis/azureus/core/peermanager/peerdb/PeerDatabase.java
index 18da8c1..fcfd1dc 100644
--- a/com/aelitis/azureus/core/peermanager/peerdb/PeerDatabase.java
+++ b/com/aelitis/azureus/core/peermanager/peerdb/PeerDatabase.java
@@ -34,29 +34,36 @@ import com.aelitis.azureus.core.util.bloom.*;
  *
  */
 public class PeerDatabase {
+  private static final int STARTUP_MIN_REBUILD_WAIT_TIME = 10*1000;
+  private static final int STARTUP_MILLIS = 120*1000;
+  
   private static final int MIN_REBUILD_WAIT_TIME = 60*1000;
   private static final int MAX_DISCOVERED_PEERS = 500;
   
   private static final int BLOOM_ROTATION_PERIOD = 7*60*1000;
   private static final int BLOOM_FILTER_SIZE = 10000;
   
+  private long start_time = SystemTime.getMonotonousTime();
   
   private final HashMap peer_connections = new HashMap();
-  private final LinkedList discovered_peers = new LinkedList();
+  private final LinkedHashSet<PeerItem> discovered_peers = new LinkedHashSet<PeerItem>();
   private final AEMonitor map_mon = new AEMonitor( "PeerDatabase" );
   
   private PeerItem[] cached_peer_popularities = null;
   private int popularity_pos = 0;
-  private long last_rebuild_time = 0;
-  private long last_rotation_time = 0;
+  private long last_rebuild_time 	= Integer.MIN_VALUE;
+  private long last_rotation_time 	= Integer.MIN_VALUE;
   
   private PeerItem self_peer;
   
   private BloomFilter filter_one = null;
   private BloomFilter filter_two = BloomFilterFactory.createAddOnly( BLOOM_FILTER_SIZE );
   
+  private long 	pex_count_last_time;
+  private int	pex_count_last;
+  private int 	pex_used_count;
   
-  
+  private int	total_peers_returned;
   
   
   protected PeerDatabase() {
@@ -153,13 +160,16 @@ public class PeerDatabase {
       }
       
       if( !discovered_peers.contains( peer ) ) {
-        discovered_peers.addLast( peer );  //add unknown peer
+        discovered_peers.add( peer );  //add unknown peer
 
-        int max_cache_size = PeerUtils.MAX_CONNECTIONS_PER_TORRENT;
+        int max_cache_size = PeerUtils.MAX_CONNECTIONS_PER_TORRENT * 2;	// cache twice the amount to allow for failures
         if( max_cache_size < 1 || max_cache_size > MAX_DISCOVERED_PEERS )  max_cache_size = MAX_DISCOVERED_PEERS;
         
         if( discovered_peers.size() > max_cache_size ) {
-          discovered_peers.removeFirst();
+        	
+        	Iterator<PeerItem> it = discovered_peers.iterator();
+        	it.next();
+        	it.remove();
         }
       }
     }
@@ -215,9 +225,11 @@ public class PeerDatabase {
 	  try{  
 		  map_mon.enter();
 	  
-		  for (int i=0;i<discovered_peers.size();i++){
+		  Iterator<PeerItem> it = discovered_peers.iterator();
+		 
+		  while( it.hasNext()){
 			  
-			  PeerItem peer = (PeerItem)discovered_peers.get(i);
+			  PeerItem peer = it.next();
 			  
 			  if( peer.getIP().equals( address )){
 				  
@@ -267,51 +279,63 @@ public class PeerDatabase {
 	  return(getNextOptimisticConnectPeer(0));
   }
   
-  protected PeerItem getNextOptimisticConnectPeer( int recursion_count ) {
-    PeerItem peer = null;
-    boolean	 discovered_peer = false;
+  private PeerItem getNextOptimisticConnectPeer( final int recursion_count ) {
+    long now = SystemTime.getMonotonousTime();
+
+    boolean	starting_up = now - start_time <= STARTUP_MILLIS;
     
-    //first see if there are any unknown peers to try
-    try{  map_mon.enter();
-      if( !discovered_peers.isEmpty() ) {
-        peer = (PeerItem)discovered_peers.removeFirst();
-        
-        discovered_peer	= true;
-      }
+    PeerItem 	peer 			= null;
+    boolean	 	discovered_peer = false;
+    boolean		tried_pex 		= false;
+    
+    if ( starting_up && total_peers_returned % 5 == 0 ){
+    	
+    		// inject a few PEX peers during startup as we know they're live and can help bootstrap the torrent
+    	
+    	peer = getPeerFromPEX( now, starting_up );
+    	
+    	tried_pex = true;
     }
-    finally{  map_mon.exit();  }
     
-    //pick one from those obtained via peer exchange if needed
-    if( peer == null ) {
-      if( cached_peer_popularities == null || popularity_pos == cached_peer_popularities.length ) {  //rebuild needed
-        cached_peer_popularities = null;  //clear cache
-        
-        long time_since_rebuild = SystemTime.getCurrentTime() - last_rebuild_time;
-        //only allow exchange list rebuild every few min, otherwise we'll spam attempts endlessly
-        if( time_since_rebuild > MIN_REBUILD_WAIT_TIME || time_since_rebuild < 0 ) {
-          cached_peer_popularities = getExchangedPeersSortedByLeastPopularFirst();
-          popularity_pos = 0;
-          last_rebuild_time = SystemTime.getCurrentTime();
-        }
-      }
-      
-      if( cached_peer_popularities != null && cached_peer_popularities.length > 0 ) {
-        peer = cached_peer_popularities[ popularity_pos ];
-        popularity_pos++;
-        last_rebuild_time = SystemTime.getCurrentTime();  //ensure rebuild waits min rebuild time after the cache is depleted before trying attempts again
-      }
+    if ( peer == null ){
+    
+	    	//first see if there are any unknown peers to try
+    	
+	    try{  
+	    	map_mon.enter();
+	    	
+	    	if( !discovered_peers.isEmpty() ) {
+	    		
+	    		Iterator<PeerItem> it = discovered_peers.iterator();
+	    		
+	    		peer = it.next();
+	    		
+	    		it.remove();
+	        
+	    		discovered_peer	= true;
+	    	}
+	    }finally{
+	    	map_mon.exit();  
+	    }
+    }
+    
+    	//pick one from those obtained via peer exchange if needed
+    
+    if ( peer == null && !tried_pex ) {
+  
+    	peer = getPeerFromPEX( now, starting_up );
     }
 
     //to reduce the number of wasted outgoing attempts, we limit how frequently we hand out the same optimistic peer in a given time period
     if( peer != null ) {
     	//check if it's time to rotate the bloom filters
     	
-      long diff = SystemTime.getCurrentTime() - last_rotation_time;
+      long diff = now - last_rotation_time;
       
-      if( diff < 0 || diff > BLOOM_ROTATION_PERIOD ) {
+      if ( diff > BLOOM_ROTATION_PERIOD ) {
         filter_one = filter_two;
         filter_two = BloomFilterFactory.createAddOnly( BLOOM_FILTER_SIZE );
-        last_rotation_time = SystemTime.getCurrentTime();
+        last_rotation_time = now;
       }
       
       	//check to see if we've already given this peer out optimistically in the last 5-10min
@@ -320,7 +344,7 @@ public class PeerDatabase {
       
       byte[]	peer_serialisation = peer.getSerialization();
       
-      if( filter_one.contains( peer_serialisation ) && recursion_count < 100 ) {
+      if ( filter_one.contains( peer_serialisation ) && recursion_count < 100 ) {
     	  
     	  	// we've recently given this peer, so recursively find another peer to try
       
@@ -335,7 +359,7 @@ public class PeerDatabase {
     			  
     		    try{  map_mon.enter();
   
-    		    	discovered_peers.addLast( peer );
+    		    	discovered_peers.add( peer );
    
    			    }finally{  
    			    	map_mon.exit();  
@@ -356,11 +380,66 @@ public class PeerDatabase {
       }
     }
     
+    if ( recursion_count == 0 && peer != null ){
+    	
+    	total_peers_returned++;
+    }
+    
     return peer;
   }
   
+  private PeerItem
+  getPeerFromPEX(
+	long		now,
+	boolean		starting_up )
+  {
+	  PeerItem	peer;
+	  
+	  if( cached_peer_popularities == null || popularity_pos == cached_peer_popularities.length ) {  //rebuild needed
+		  cached_peer_popularities = null;  //clear cache
+		  long time_since_rebuild = now - last_rebuild_time;
+		  //only allow exchange list rebuild every few min, otherwise we'll spam attempts endlessly
+		  if( time_since_rebuild > (starting_up?STARTUP_MIN_REBUILD_WAIT_TIME:MIN_REBUILD_WAIT_TIME )) {
+			  cached_peer_popularities = getExchangedPeersSortedByLeastPopularFirst();
+			  popularity_pos = 0;
+			  last_rebuild_time = now;
+		  }
+	  }
 
+	  if ( cached_peer_popularities != null && cached_peer_popularities.length > 0 ) {
+		  peer = cached_peer_popularities[ popularity_pos ];
+		  popularity_pos++;
+		  pex_used_count++;
+		  last_rebuild_time = now;  //ensure rebuild waits min rebuild time after the cache is depleted before trying attempts again
+	  }else{
+		  
+		  peer = null;
+	  }
+	  
+	  return( peer );
+  }
   
+  public int
+  getExchangedPeerCount()
+  {
+	  long	now = SystemTime.getMonotonousTime();
+	  
+	  if ( now - pex_count_last_time >= 10*1000 ){
+		  
+		  PeerItem[] peers = getExchangedPeersSortedByLeastPopularFirst();
+		  
+		  pex_count_last = peers==null?0:peers.length;
+		  pex_count_last_time = now;
+  	  }
+	  
+	  return( Math.max( 0, pex_count_last - popularity_pos ));
+  }
+  
+  public int
+  getExchangedPeersUsed()
+  {
+	 return( pex_used_count );
+  }
   
   private PeerItem[] getExchangedPeersSortedByLeastPopularFirst() {
     HashMap popularity_counts = new HashMap();
diff --git a/com/aelitis/azureus/core/peermanager/peerdb/PeerExchangerItem.java b/com/aelitis/azureus/core/peermanager/peerdb/PeerExchangerItem.java
index 6832788..935e7f6 100644
--- a/com/aelitis/azureus/core/peermanager/peerdb/PeerExchangerItem.java
+++ b/com/aelitis/azureus/core/peermanager/peerdb/PeerExchangerItem.java
@@ -39,8 +39,8 @@ public class PeerExchangerItem {
   
   private final PeerDatabase parent_db;
   private final PeerItem base_peer;
-  private final LinkedList<PeerItem> connections_added 		= new LinkedList<PeerItem>();
-  private final LinkedList<PeerItem> connections_dropped 	= new LinkedList<PeerItem>();
+  private final LinkedHashSet<PeerItem> connections_added 		= new LinkedHashSet<PeerItem>();
+  private final LinkedHashSet<PeerItem> connections_dropped 	= new LinkedHashSet<PeerItem>();
   private final Map<PeerItem,Object> connected_peers = new LightHashMap<PeerItem,Object>();
   private final AEMonitor peers_mon = new AEMonitor( "PeerConnectionItem" );
   private boolean maintain_peers_state = true;  //assume we do until explicitly disabled
@@ -99,7 +99,7 @@ public class PeerExchangerItem {
     
       if( !connections_dropped.contains( peer_connection ) ) {
         if( !connections_added.contains( peer_connection ) ) {
-          connections_added.addLast( peer_connection );  //register new add
+          connections_added.add( peer_connection );  //register new add
         }
       }
       else {  //was dropped and then re-added
@@ -116,7 +116,7 @@ public class PeerExchangerItem {
       
       if( !connections_added.contains( peer_connection ) ) {
         if( !connections_dropped.contains( peer_connection ) ) {
-          connections_dropped.addLast( peer_connection );  //register new drop
+          connections_dropped.add( peer_connection );  //register new drop
         }
       }
       else {  //was added and then re-dropped
@@ -144,8 +144,11 @@ public class PeerExchangerItem {
 
       PeerItem[] peers = new PeerItem[ num_to_send ];
       
+      Iterator<PeerItem> it = connections_added.iterator();
+      
       for( int i=0; i < num_to_send; i++ ) {
-        peers[i] = (PeerItem)connections_added.removeFirst();       
+        peers[i] = it.next();
+        it.remove();
       }
 
       return peers;
@@ -167,8 +170,11 @@ public class PeerExchangerItem {
 
       PeerItem[] peers = new PeerItem[ num_to_send ];
       
+      Iterator<PeerItem> it = connections_dropped.iterator();
+      
       for( int i=0; i < num_to_send; i++ ) {
-        peers[i] = (PeerItem)connections_dropped.removeFirst();       
+        peers[i] = it.next();
+        it.remove();
       }
       return peers;
     }
@@ -179,16 +185,43 @@ public class PeerExchangerItem {
   /**
    * Clears all current peer state records and stops any future state maintenance.
    */
-  public void disableStateMaintenance() {
-    try{  peers_mon.enter();
-      maintain_peers_state = false;
-      connections_added.clear();
-      connections_dropped.clear();
-      connected_peers.clear();
+  public void 
+  disableStateMaintenance() 
+  {
+    try{  
+    	peers_mon.enter();
+    	
+    	maintain_peers_state = false;
+    	
+    	connections_added.clear();
+    	
+    	connections_dropped.clear();
+    	
+    	connected_peers.clear();
+    	
+    }finally{  
+    	peers_mon.exit();  
     }
-    finally{  peers_mon.exit();  }
   }
   
+  public void 
+  enableStateMaintenance() 
+  {
+	    try{  
+	    	peers_mon.enter();
+	    	
+	    	if ( maintain_peers_state ){
+	    		
+	    		return;
+	    	}
+	    	
+	    	maintain_peers_state = true;
+	    	
+	    }finally{  
+	    	
+	    	peers_mon.exit();  
+	    }
+ }
   
   
   protected boolean isConnectedToPeer( PeerItem peer ) {
diff --git a/com/aelitis/azureus/core/peermanager/peerdb/PeerItem.java b/com/aelitis/azureus/core/peermanager/peerdb/PeerItem.java
index 813aa48..72fa2d5 100644
--- a/com/aelitis/azureus/core/peermanager/peerdb/PeerItem.java
+++ b/com/aelitis/azureus/core/peermanager/peerdb/PeerItem.java
@@ -123,6 +123,8 @@ public class PeerItem implements PeerDescriptor {
    
   public byte getSource() {  return source;  }
 
+  public String getPeerSource() {  return convertSourceString( source );  }
+
   public byte getHandshakeType() {  return handshake;  }
   
   public byte getCryptoLevel() { return crypto_level; }
diff --git a/com/aelitis/azureus/core/peermanager/piecepicker/PiecePicker.java b/com/aelitis/azureus/core/peermanager/piecepicker/PiecePicker.java
index f13b4d4..6e7be03 100644
--- a/com/aelitis/azureus/core/peermanager/piecepicker/PiecePicker.java
+++ b/com/aelitis/azureus/core/peermanager/piecepicker/PiecePicker.java
@@ -80,6 +80,21 @@ public interface PiecePicker
 	
 	public int		getNbPiecesDone();
 	
+	public void
+	setGlobalRequestHint(
+		int	piece_number,
+		int	start_bytes,
+		int	byte_count );
+	
+	public int[]
+	getGlobalRequestHint();
+	
+	public void
+	setReverseBlockOrder(
+		boolean		is_reverse );
+	
+	public boolean
+	getReverseBlockOrder();
 	
 	public void
 	addRTAProvider(
diff --git a/com/aelitis/azureus/core/peermanager/piecepicker/PieceRTAProvider.java b/com/aelitis/azureus/core/peermanager/piecepicker/PieceRTAProvider.java
index 73e9e2e..b2f5775 100644
--- a/com/aelitis/azureus/core/peermanager/piecepicker/PieceRTAProvider.java
+++ b/com/aelitis/azureus/core/peermanager/piecepicker/PieceRTAProvider.java
@@ -48,7 +48,8 @@ PieceRTAProvider
 	
 	public void
 	setBufferMillis(
-		long	millis );
+		long	millis,
+		long	delay_millis );
 	
 		/**
 		 * Returns the user-agent associated with this RTA activity, if known
diff --git a/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java b/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
index 59d19a4..4ce71c4 100644
--- a/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
+++ b/com/aelitis/azureus/core/peermanager/piecepicker/impl/PiecePickerImpl.java
@@ -55,35 +55,36 @@ implements PiecePicker
 	private static final LogIDs LOGID = LogIDs.PIECES;
 
 	/** min ms for recalculating availability - reducing this has serious ramifications */
-	private static final long TIME_MIN_AVAILABILITY	=974;
+	private static final long TIME_MIN_AVAILABILITY	= 974;
 	/** min ms for recalculating base priorities */
-	private static final long TIME_MIN_PRIORITIES	=999;
+	private static final long TIME_MIN_PRIORITIES	= 999;
 	/** min ms for forced availability rebuild */
-	private static final long TIME_AVAIL_REBUILD	=5*60*1000 -24; 
+	private static final long TIME_AVAIL_REBUILD	= 5*60*1000 -24; 
 
 	// The following are added to the base User setting based priorities (for all inspected pieces)
 	/** user select prioritize first/last */
-	private static final int PRIORITY_W_FIRSTLAST	=1300;
+	private static final int PRIORITY_W_FIRSTLAST	= 999;
 	/** min # pieces in file for first/last prioritization */
-	private static final long FIRST_PIECE_MIN_NB	=4;
+	private static final long FIRST_PIECE_MIN_NB	= 4;
 	/** number of pieces for first pieces prioritization */
 	// private static final int FIRST_PIECE_RANGE_PERCENT= 10;
 	/** user sets file as "High" */
-	private static final int PRIORITY_W_FILE		=1000;
+	private static final int PRIORITY_W_FILE_BASE	= 1000;	// min amount added for priority file. > first/last piece priority offset to give file priority priority over f/l piece priority
+	private static final int PRIORITY_W_FILE_RANGE	= 1000;	// priority range added for prioritized files 
 	/** Additional boost for more completed High priority */
-	private static final int PRIORITY_W_COMPLETION	=2000;
+	private static final int PRIORITY_W_COMPLETION	= 2000;
 
 	// The following are only used when resuming already running pieces
 	/** priority boost due to being too old */
-	private static final int PRIORITY_W_AGE		=900;
+	private static final int PRIORITY_W_AGE			= 900;
 	/** ms a block is expected to complete in */
-	private static final int PRIORITY_DW_AGE		=60 *1000;
+	private static final int PRIORITY_DW_AGE		= 60*1000;
 	/** ms since last write */
-	private static final int PRIORITY_DW_STALE		=120 *1000;
+	private static final int PRIORITY_DW_STALE		= 120*1000;
 	/** finish pieces already almost done */
-	private static final int PRIORITY_W_PIECE_DONE	=900;
+	private static final int PRIORITY_W_PIECE_DONE	= 900;
 	/** keep working on same piece */
-	private static final int PRIORITY_W_SAME_PIECE	=700;
+	private static final int PRIORITY_W_SAME_PIECE	= 700;
 
 	/** currently webseeds + other explicit priorities are around 10000 or more - at this point we ignore rarity */
 
@@ -96,13 +97,15 @@ implements PiecePicker
 	private static final int PRIORITY_REALTIME		= 9999999;
 
 	/** Min number of requests sent to a peer */
-	private static final int REQUESTS_MIN	=2;
+	private static final int REQUESTS_MIN_MIN	= 2;
+	private static final int REQUESTS_MIN_MAX	= 8;
 	/** Max number of request sent to a peer */
 	private static final int REQUESTS_MAX	=256;
 	/** Default number of requests sent to a peer, (for each X B/s another request will be used) */
 	private static final int SLOPE_REQUESTS	= 4*1024;
 
 	private static final long RTA_END_GAME_MODE_SIZE_TRIGGER	= 16 * DiskManager.BLOCK_SIZE;
+	private static final long END_GAME_MODE_RESERVED_TRIGGER	= 5 * 1024*1024;
 	private static final long END_GAME_MODE_SIZE_TRIGGER		= 20 * 1024*1024;
 	private static final long END_GAME_MODE_TIMEOUT				= 60 * END_GAME_MODE_SIZE_TRIGGER / DiskManager.BLOCK_SIZE;
 
@@ -197,6 +200,12 @@ implements PiecePicker
 
 	private int					allocate_request_loop_count;
 
+	private int					max_file_priority;
+	private int					min_file_priority;
+	
+	private boolean				reverse_block_order;
+	private int[]				global_request_hint;
+	
 	private static boolean		enable_request_hints;
 	private static boolean		includeLanPeersInReqLimiting;
 	
@@ -302,6 +311,9 @@ implements PiecePicker
 
 		// with priorities charged and primed, ready for dm messages
 		diskManagerListener =new DiskManagerListenerImpl();
+		
+		syncFilePriorities();
+		
 		diskManager.addListener(diskManagerListener);
 	}
 
@@ -590,6 +602,9 @@ implements PiecePicker
 		Collections.shuffle(bestUploaders);
 		Collections.sort(bestUploaders, new Comparator() {
 			public int compare(Object o1, Object o2) {
+				if ( o1 == o2 ){
+					return( 0 );
+				}
 				PEPeerTransport pt2 = (PEPeerTransport)o2;
 				PEPeerTransport pt1 = (PEPeerTransport)o1;
 				PEPeerStats stats2 = pt2.getStats();
@@ -643,17 +658,20 @@ implements PiecePicker
 
 		final int uploadersSize =bestUploaders.size();
 
-		if ( uploadersSize ==0 ){
+		if ( uploadersSize == 0 ){
 
 			// no usable peers, bail out early
 			return;
 		}
 
+		int REQUESTS_MIN;
+				
 		boolean	done_priorities = false;
 
 		if ( priorityRTAexists ){
 		
-		
+			REQUESTS_MIN = REQUESTS_MIN_MIN;
+			
 			final Map[] peer_randomiser = { null };
 
 				// to keep the ordering consistent we need to use a fixed metric unless
@@ -671,6 +689,11 @@ implements PiecePicker
 								Object arg1, 
 								Object arg2) 
 							{
+								if ( arg1 == arg2 ){
+									
+									return( 0 );
+								}
+								
 								PEPeerTransport pt1	= (PEPeerTransport)arg1;
 								PEPeerTransport pt2	= (PEPeerTransport)arg2;
 
@@ -828,6 +851,16 @@ implements PiecePicker
 					((PEPeerTransport)it.next()).requestAllocationComplete();
 				}
 			}
+		}else{
+			
+			int	required_blocks = (int)( diskManager.getRemainingExcludingDND()/DiskManager.BLOCK_SIZE );
+
+			int	blocks_per_uploader = required_blocks / uploadersSize;
+			
+				// if we have plenty of blocks outstanding we can afford to be more generous in the
+				// minimum number of requests we allocate
+			
+			REQUESTS_MIN = Math.max( REQUESTS_MIN_MIN, Math.min( REQUESTS_MIN_MAX, blocks_per_uploader/2 ));
 		}
 
 		checkEndGameMode();
@@ -855,7 +888,19 @@ implements PiecePicker
 				}else{
 					if (!pt.isSnubbed()){
 						if (!endGameMode){
-							maxRequests =REQUESTS_MIN +(int) (pt.getStats().getDataReceiveRate() /SLOPE_REQUESTS);
+							
+							int	peer_requests_min;
+							
+							if ( pt.getUnchokedForMillis() < 10*1000 ){
+								
+								peer_requests_min = REQUESTS_MIN;
+								
+							}else{
+								
+								peer_requests_min = REQUESTS_MIN_MIN;
+							}
+							
+							maxRequests =peer_requests_min +(int) (pt.getStats().getDataReceiveRate() /SLOPE_REQUESTS);
 							if (maxRequests >REQUESTS_MAX ||maxRequests <0)
 								maxRequests =REQUESTS_MAX;
 						}else{
@@ -922,7 +967,7 @@ implements PiecePicker
 
 						if ( no_req_count < NO_REQUEST_BACKOFF_MAX_LOOPS ){
 
-							pt.setConsecutiveNoRequestCount( no_req_count + 2 );
+							pt.setConsecutiveNoRequestCount( no_req_count + 1 );
 						}
 
 						// System.out.println( pt.getIp() + ": nb=" + pt.getNbRequests() + ",max=" + maxRequests + ",nrc=" + no_req_count +",loop=" + allocate_request_loop_count); 
@@ -969,7 +1014,7 @@ implements PiecePicker
 		//avoid rarest start until we have finished some pieces to share
 		if(nbPiecesDone < 4 ) {RarestAllowed = 0;}
 		// avoid rarest start during startup (high churn, inaccurate data)
-		if(SystemTime.getCurrentTime()-peerControl.getTimeStarted() < 180*1000) {RarestAllowed = 0;}
+		if(SystemTime.getCurrentTime()-peerControl.getTimeStarted( false ) < 180*1000) {RarestAllowed = 0;}
 		// more churn avoidance
 		if(rarestStartedPieces.size() > RarestAllowed+2) {RarestAllowed = 0;}
 
@@ -993,6 +1038,31 @@ implements PiecePicker
 		return RarestAllowed;
 	}
 
+	private void
+	syncFilePriorities()
+	{
+		DiskManagerFileInfo[] files = diskManager.getFiles();
+		
+		int max = 0;
+		int min = 0;
+		
+		for ( DiskManagerFileInfo file: files ){
+			
+			int p = file.getPriority();
+			
+			if ( p > max ){
+				
+				max = p;
+				
+			}else if ( p < min ){
+				
+				min = p;
+			}
+		}
+		
+		max_file_priority = max;
+		min_file_priority = min;
+	}
 	/** This computes the base priority for all pieces that need requesting if there's
 	 * been any availability change or user priority setting changes since the last
 	 * call, which will be most of the time since availability changes so dynamicaly
@@ -1076,18 +1146,39 @@ implements PiecePicker
 						}
 						// if the file is high-priority
 						// startPriority +=(1000 *fileInfo.getPriority()) /255;
-						if (fileInfo.isPriority())
-						{
-							priority +=PRIORITY_W_FILE;
-							if (completionPriorityL)
-							{
-								final long percent =(1000 *downloaded) /length;
-								if (percent >=900)
-									priority +=(PRIORITY_W_COMPLETION *downloaded) /diskManager.getTotalLength();
+						
+						int file_priority = fileInfo.getPriority();
+													
+						int max = Math.max( file_priority, max_file_priority );
+						int min = Math.min( file_priority, min_file_priority );
+						
+						int	range = max - min;
+						
+						if ( range > 0 ){
+							
+							int	relative_file_priority = file_priority - min;
+							
+							priority += PRIORITY_W_FILE_BASE;
+							
+							int adjustment = ( PRIORITY_W_FILE_RANGE*relative_file_priority ) / range;
+																
+							priority += adjustment;
+						}
+						
+						if ( completionPriorityL ){
+						
+							final long percent =(1000 *downloaded) /length;
+							
+							if ( percent >=900 ){
+								
+								priority +=(PRIORITY_W_COMPLETION *downloaded) /diskManager.getTotalLength();
 							}
 						}
-						if (priority >startPriority)
-							startPriority =priority;
+						
+						if ( priority > startPriority ){
+						
+							startPriority = priority;
+						}
 					}
 				}
 
@@ -1172,7 +1263,7 @@ implements PiecePicker
 	 */
 	protected final int findPieceToDownload(PEPeerTransport pt, int nbWanted)
 	{
-		final int pieceNumber =getRequestCandidate(pt);
+		final int pieceNumber = getRequestCandidate(pt);
 		if (pieceNumber <0)
 		{
 			// probaly should have found something since chose to try; probably not interested anymore
@@ -1188,10 +1279,10 @@ implements PiecePicker
 			peerSpeed = 0;
 
 		final PEPiece pePiece;
-		if (pePieces[pieceNumber] != null)
+		if (pePieces[pieceNumber] != null){
 			pePiece = pePieces[pieceNumber];
-		else
-		{	//create piece manually
+		}else{
+				//create piece manually
 			int[]	peer_priority_offsets = pt.getPriorityOffsets();
 
 			int	this_offset = peer_priority_offsets==null?0:peer_priority_offsets[pieceNumber];
@@ -1201,7 +1292,7 @@ implements PiecePicker
 			pePiece =new PEPieceImpl(pt.getManager(), dmPieces[pieceNumber], peerSpeed >>1);
 
 			// Assign the created piece to the pieces array.
-			peerControl.addPiece(pePiece, pieceNumber);
+			peerControl.addPiece(pePiece, pieceNumber, pt);
 			if (startPriorities !=null){
 				pePiece.setResumePriority(startPriorities[pieceNumber] + this_offset);
 			}else{
@@ -1210,31 +1301,84 @@ implements PiecePicker
 			if (availability[pieceNumber] <=globalMinOthers)
 				nbRarestActive++;
 		}
+					
+		int[]	request_hint = null;
 		
-		if(!pt.isLANLocal() || includeLanPeersInReqLimiting)
+		if ( enable_request_hints ){		
+			
+			request_hint = pt.getRequestHint();
+			
+			if ( request_hint != null ){
+				
+				if ( request_hint[0] != pieceNumber ){
+					
+					request_hint = null;
+				}
+			}
+			
+			if ( request_hint == null ){
+				
+				request_hint = global_request_hint;
+				
+				if ( request_hint != null && request_hint[0] != pieceNumber ){
+					
+					request_hint = null;
+				}
+			}
+		}		
+
+
+		if (!pt.isLANLocal() || includeLanPeersInReqLimiting){
 			nbWanted = dispenser.dispense(nbWanted, DiskManager.BLOCK_SIZE);
-		final int[] blocksFound =pePiece.getAndMarkBlocks(pt, nbWanted,enable_request_hints  );
-		final int blockNumber =blocksFound[0];
-		final int nbBlocks =blocksFound[1];
-		if((!pt.isLANLocal() || includeLanPeersInReqLimiting) && nbBlocks != nbWanted)
+		}
+
+		final int[] blocksFound = pePiece.getAndMarkBlocks(pt, nbWanted, request_hint, reverse_block_order  );
+		
+		final int blockNumber 	= blocksFound[0];
+		final int nbBlocks 		= blocksFound[1];
+		
+		if((!pt.isLANLocal() || includeLanPeersInReqLimiting) && nbBlocks != nbWanted){
 			dispenser.returnUnusedChunks(nbWanted-nbBlocks, DiskManager.BLOCK_SIZE);
+		}
 		
 		if (nbBlocks <=0)
 			return 0;
 
 		int requested =0;
-		// really try to send the request to the peer
-		for (int i =0; i <nbBlocks; i++)
-		{
-			final int thisBlock =blockNumber +i;
-			if (pt.request(pieceNumber, thisBlock *DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock)) != null )
-			{
-				requested++;
-				pt.setLastPiece(pieceNumber);
-
-				pePiece.setLastRequestedPeerSpeed( peerSpeed );
-				// have requested a block
-			} 
+		
+			// really try to send the request to the peer
+		
+		if ( reverse_block_order ){
+			
+			for (int i = nbBlocks-1; i >= 0; i--){
+				
+				final int thisBlock = blockNumber + i;
+				
+				if (pt.request(pieceNumber, thisBlock *DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock)) != null ){
+					requested++;
+					pt.setLastPiece(pieceNumber);
+	
+					pePiece.setLastRequestedPeerSpeed( peerSpeed );
+					// have requested a block
+				} else{
+					pePiece.clearRequested(thisBlock);
+				}
+			}
+		}else{
+			for (int i =0; i <nbBlocks; i++){
+			
+				final int thisBlock =blockNumber +i;
+				
+				if (pt.request(pieceNumber, thisBlock *DiskManager.BLOCK_SIZE, pePiece.getBlockSize(thisBlock)) != null ){
+					requested++;
+					pt.setLastPiece(pieceNumber);
+	
+					pePiece.setLastRequestedPeerSpeed( peerSpeed );
+					// have requested a block
+				} else{
+					pePiece.clearRequested(thisBlock);
+				}
+			}
 		}
 
 		if (requested > 0
@@ -1333,6 +1477,7 @@ implements PiecePicker
 	
 						piece_min_rta_time 	= piece_rta;
 						piece_min_rta_index = i;
+						piece_min_rta_block	= 0;
 	
 					}else{
 	
@@ -1475,7 +1620,7 @@ implements PiecePicker
 		
 						// Assign the created piece to the pieces array.
 		
-						peerControl.addPiece(pePiece, piece_min_rta_index);
+						peerControl.addPiece(pePiece, piece_min_rta_index, pt);
 		
 						pePiece.setResumePriority( PRIORITY_REALTIME );
 		
@@ -1571,47 +1716,41 @@ implements PiecePicker
 
 		// piece number and its block number that we'll try to DL
 
-		int reservedPieceNumber = pt.getReservedPieceNumber();
+		int[] reservedPieceNumbers = pt.getReservedPieceNumbers();
 
 		// If there's a piece seserved to this peer resume it and only it (if possible)
 
-		if ( reservedPieceNumber >=0 ){
-
-			PEPiece pePiece = pePieces[reservedPieceNumber];
-
-			if ( pePiece != null ){
-
-				String peerReserved = pePiece.getReservedBy();
-
-				if ( peerReserved != null && peerReserved.equals( pt.getIp())){
-
-					if ( peerHavePieces.flags[reservedPieceNumber] &&pePiece.isRequestable()){
-
-						return reservedPieceNumber;
-					}
-				}
-			}
-
-			// reserved piece is no longer valid, dump it
-			pt.setReservedPieceNumber(-1);
+		if ( reservedPieceNumbers != null ){
 
-			// clear the reservation if the piece is still allocated to the peer
-			if ( pePiece != null )
-			{
-				String peerReserved = pePiece.getReservedBy();
-				if ( peerReserved != null )
-				{
-					if ( peerReserved.equals(pt.getIp()))
-					{
-						pePiece.setReservedBy( null );
+			for ( int reservedPieceNumber: reservedPieceNumbers ){
+				
+				PEPiece pePiece = pePieces[reservedPieceNumber];
+	
+				if ( pePiece != null ){
+	
+					String peerReserved = pePiece.getReservedBy();
+	
+					if ( peerReserved != null && peerReserved.equals( pt.getIp())){
+	
+						if ( peerHavePieces.flags[reservedPieceNumber] &&pePiece.isRequestable()){
+	
+							return reservedPieceNumber;
+						}else{
+							
+							pePiece.setReservedBy( null );
+						}
 					}
 				}
+			
+					// reserved piece is no longer valid, dump it
+				
+				pt.removeReservedPieceNumber( reservedPieceNumber );
 			}
-
+			
 			// note, pieces reserved to peers that get disconnected are released in pepeercontrol
-
-			reservedPieceNumber	= -1;
 		}
+		
+		int	reservedPieceNumber	= -1;
 
 		final int			peerSpeed =(int) pt.getStats().getDataReceiveRate() /1024;	// how many KB/s has the peer has been sending
 		final int			lastPiece =pt.getLastPiece();
@@ -1641,7 +1780,7 @@ implements PiecePicker
 
 		final int[]		peerPriorities	= pt.getPriorityOffsets();
 
-		final long	now =SystemTime.getCurrentTime();
+		final long	now = SystemTime.getCurrentTime();
         
         int[] 	request_hint = pt.getRequestHint();
         int		request_hint_piece_number;
@@ -1661,22 +1800,50 @@ implements PiecePicker
         	request_hint_piece_number = -1;
         }
         
-		// Try to continue a piece already loaded, according to priority
-        for (i =startI; i <=endI; i++)
-        {
-        	// is the piece available from this peer?
-        	if (peerHavePieces.flags[i])
-        	{
-        		priority =startPriorities[i];
-        		final DiskManagerPiece dmPiece =dmPieces[i];
-
-        		if ( priority >=0 && dmPiece.isDownloadable())
-        		{
-        			if ( peerPriorities != null )
-        				priority += peerPriorities[i];
-
-        			if ( enable_request_hints && i == request_hint_piece_number )
-        			{
+        if ( request_hint_piece_number == -1 ){
+        	
+        	int[] g_hint = global_request_hint;
+        	
+        	if ( g_hint != null ){
+        		
+        		request_hint_piece_number = g_hint[0];
+        		
+        		if ( dmPieces[request_hint_piece_number].isDone()){
+            		
+        			g_hint = null;
+            		
+            		request_hint_piece_number	= -1;
+            	}
+        	}
+        }
+        
+			// Try to continue a piece already loaded, according to priority
+        
+        for (i =startI; i <=endI; i++){
+        
+        		// is the piece available from this peer?
+        	
+        	if ( peerHavePieces.flags[i]){
+        	
+        		priority = startPriorities[i];
+        		
+        		final DiskManagerPiece dmPiece = dmPieces[i];
+
+        		if ( priority >=0 && dmPiece.isDownloadable()){
+        		
+        			if ( peerPriorities != null ){
+        				
+           				int peer_priority = peerPriorities[i];
+           				
+           				if ( peer_priority < 0 ){
+           					
+           					continue;
+           				}
+           				
+           				priority += peer_priority;
+        			}
+        			
+        			if ( enable_request_hints && i == request_hint_piece_number ){
 
         				priority += PRIORITY_REQUEST_HINT;
 
@@ -1685,10 +1852,8 @@ implements PiecePicker
         				if ( pePiece == null ){
         					forceStart	= true;
         				}else{
-        					if ( reservedPieceNumber != i ){
-        						pePiece.setReservedBy( pt.getIp());
-        						pt.setReservedPieceNumber( i );
-        					}
+       						pePiece.setReservedBy( pt.getIp());
+       						pt.addReservedPieceNumber( i );
         				}
         			}
 
@@ -1735,7 +1900,7 @@ implements PiecePicker
         						if (!peerReserved.equals(pt.getIp()))
         							continue;   //reserved to somebody else
         						// the peer forgot this is reserved to him; re-associate it
-        						pt.setReservedPieceNumber(i);
+        						pt.addReservedPieceNumber(i);
         						return i;
         					}
 
@@ -1828,6 +1993,9 @@ implements PiecePicker
         						startCandidates.setOnly(i);
         					} else if (priority ==startMaxPriority)
         					{   // continuing same priority level
+        						if (startCandidates ==null)
+        							startCandidates =new BitFlags(nbPieces);
+
         						if (avail <startMinAvail)
         						{   // same priority, new availability level
         							startMinAvail =avail;
@@ -1947,13 +2115,13 @@ implements PiecePicker
 			return;
 		}
 		
-		final long now =SystemTime.getCurrentTime();
+		final long mono_now =SystemTime.getMonotonousTime();
 		
-		if (endGameMode ||endGameModeAbandoned){
+		if ( endGameMode ||endGameModeAbandoned ){
 			
-			if (!endGameModeAbandoned){
+			if ( !endGameModeAbandoned ){
 				
-				if (now -timeEndGameModeEntered >END_GAME_MODE_TIMEOUT){
+				if ( mono_now - timeEndGameModeEntered  > END_GAME_MODE_TIMEOUT){
 					
 					abandonEndGameMode();
 				}
@@ -1962,29 +2130,60 @@ implements PiecePicker
 			return;
 		}
 
-		int active_pieces =0;
-
+		int active_pieces 	= 0;
+		int reserved_pieces	= 0;
+		
 		for (int i =0; i <nbPieces; i++){
 		
 			final DiskManagerPiece dmPiece =dmPieces[i];
-			// If the piece isn't even Needed, or doesn't need more downloading, simply continue
-			if (!dmPiece.isDownloadable())
-				continue;
-
-			final PEPiece pePiece = pePieces[i];
-
-			if ( pePiece != null && pePiece.isDownloaded()){
+			
+				// If the piece isn't even Needed, or doesn't need more downloading, simply continue
+			
+			if (!dmPiece.isDownloadable()){
+				
 				continue;
 			}
+			
+			final PEPiece pePiece = pePieces[i];
 
-			// If the piece is being downloaded (fully requested), count it and continue
-			if ( pePiece != null && pePiece.isRequested() && dmPiece.isNeeded())
-			{
-				active_pieces++ ;
-				continue;
+			if ( pePiece != null ){
+				
+				if ( pePiece.isDownloaded()){
+					
+					continue;
+				}
+	
+				if ( dmPiece.isNeeded()){
+						
+						// If the piece is being downloaded (fully requested), count it and continue
+					
+					if ( pePiece.isRequested() ){
+					
+						active_pieces++ ;
+						
+						continue;
+					}
+					
+						// https://jira.vuze.com/browse/SUP-154
+						// If we have a piece reserved to a slow peer then this can prevent end-game
+						// mode from being entered and result poopy end-of-dl speeds
+					
+					if ( pePiece.getReservedBy() != null ){
+						
+						reserved_pieces++;
+						
+						if ( reserved_pieces * diskManager.getPieceLength() > END_GAME_MODE_RESERVED_TRIGGER ){
+							
+							return;
+						}
+						
+						continue;
+					}
+				}
 			}
-
-			// Else, some piece is Needed, not downloaded/fully requested; this isn't end game mode
+			
+				// Else, some piece is Needed, not downloaded/fully requested; this isn't end game mode
+			
 			return;
 		}
 
@@ -2004,11 +2203,11 @@ implements PiecePicker
 			try{
 				endGameModeChunks_mon.enter();
 
-				endGameModeChunks =new ArrayList();
+				endGameModeChunks = new ArrayList();
 	
-				timeEndGameModeEntered =now;
+				timeEndGameModeEntered = mono_now;
 				
-				endGameMode =true;
+				endGameMode = true;
 				
 				computeEndGameModeChunks();
 				
@@ -2045,7 +2244,7 @@ implements PiecePicker
 					
 					pePiece = new PEPieceImpl(peerControl,dmPiece,0);
 					
-					peerControl.addPiece(pePiece,i);
+					peerControl.addPiece(pePiece,i, null);
 				}
 
 				final boolean written[] =dmPiece.getWritten();
@@ -2534,6 +2733,21 @@ implements PiecePicker
 		}
 		
 		public void 
+		pieceAdded( 
+			PEPeerManager 	manager, 
+			PEPiece 		piece, 
+			PEPeer 			for_peer )
+		{
+		}
+		  
+		public void 
+		pieceRemoved( 
+			PEPeerManager 	manager, 
+			PEPiece 		piece )
+		{
+		}
+		
+		public void 
 		peerSentBadData(
 			PEPeerManager 	manager,
 			PEPeer 			peer, 
@@ -2644,6 +2858,7 @@ implements PiecePicker
 
 		public final void filePriorityChanged(DiskManagerFileInfo file)
 		{
+			syncFilePriorities();
 			// record that user-based priorities changed
 			filePriorityChange++;	// this is a user's priority change event
 
@@ -2716,6 +2931,41 @@ implements PiecePicker
 	}
 
 	public void
+	setGlobalRequestHint(
+		int	piece_number,
+		int	start_bytes,
+		int	byte_count )
+	{
+		if ( piece_number < 0 ){
+			
+			global_request_hint = null;
+			
+		}else{
+			
+			global_request_hint = new int[]{ piece_number, start_bytes, byte_count };
+		}
+	}
+	
+	public int[]
+	getGlobalRequestHint()
+	{
+		return( global_request_hint );
+	}
+	
+	public void
+	setReverseBlockOrder(
+		boolean		is_reverse )
+	{
+		reverse_block_order = is_reverse;
+	}
+	
+	public boolean
+	getReverseBlockOrder()
+	{
+		return( reverse_block_order );
+	}
+	
+	public void
 	destroy()
 	{
 		
diff --git a/com/aelitis/azureus/core/peermanager/piecepicker/util/BitFlags.java b/com/aelitis/azureus/core/peermanager/piecepicker/util/BitFlags.java
index d71b40a..2914990 100644
--- a/com/aelitis/azureus/core/peermanager/piecepicker/util/BitFlags.java
+++ b/com/aelitis/azureus/core/peermanager/piecepicker/util/BitFlags.java
@@ -179,7 +179,7 @@ public class BitFlags
 	{
 		start =0;
 		end =flags.length -1;
-		Arrays.fill(flags, start, end, true);
+		Arrays.fill(flags, true);
 		nbSet =flags.length;
 	}
 	
diff --git a/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java b/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
index 37a0179..985a8b9 100644
--- a/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
+++ b/com/aelitis/azureus/core/peermanager/unchoker/UnchokerUtilTest.java
@@ -25,6 +25,7 @@ package com.aelitis.azureus.core.peermanager.unchoker;
 import java.net.InetAddress;
 import java.util.*;
 
+import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerListener;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
@@ -134,6 +135,7 @@ public class UnchokerUtilTest {
         public boolean isChokedByMe() {  return true;  }
         public void sendChoke(){}
         public void sendUnChoke(){}
+        public void sendStatsRequest(Map request) {}
         public boolean isInteresting(){  return true;  }
         public boolean isInterested(){  return true;  }
         public boolean isRelativeSeed() { return false; }
@@ -158,8 +160,11 @@ public class UnchokerUtilTest {
         public int getMessagingMode(){ return PEPeer.MESSAGING_BT_ONLY; }
         public Message[] getSupportedMessages(){ return null; }
         public String getEncryption(){ return( "" ); }
+        public String getProtocol(){ return( "" ); }
         public int getReservedPieceNumber() { return -1; }
-        public void setReservedPieceNumber(int pieceNumber) {}
+        public void addReservedPieceNumber(int pieceNumber) {}
+        public void removeReservedPieceNumber(int pieceNumber) {}
+        public int[] getReservedPieceNumbers() { return null; }
 		public int[] getIncomingRequestedPieceNumbers() { return null; }
 		public int[] getOutgoingRequestedPieceNumbers() { return null; }
 		public int getPercentDoneOfCurrentIncomingRequest(){ return 0; }  
@@ -169,6 +174,8 @@ public class UnchokerUtilTest {
 		public void setLastPiece(int pieceNumber) {}
 		public int getConsecutiveNoRequestCount() {return 0; }
 		public void setConsecutiveNoRequestCount(int num) {}
+		public void setSuspendedLazyBitFieldEnabled(boolean enable) {			
+		}
 		public int getIncomingRequestCount() {
 			// TODO Auto-generated method stub
 			return 0;
@@ -193,17 +200,20 @@ public class UnchokerUtilTest {
 		clearRequestHint()
 		{
 		}
+		public void sendRejectRequest(DiskManagerReadRequest request) {
+			// TODO Auto-generated method stub
+			
+		}
 		public void setUploadRateLimitBytesPerSecond( int bytes ){}
 		public void setDownloadRateLimitBytesPerSecond( int bytes ){}
 		public int getUploadRateLimitBytesPerSecond(){ return 0 ;}
 		public int getDownloadRateLimitBytesPerSecond(){ return 0; }
 		public void addRateLimiter(LimitedRateGroup limiter, boolean upload) {
-			// TODO Auto-generated method stub
-			
 		}
-		public void removeRateLimiter(LimitedRateGroup limiter, boolean upload) {
-			// TODO Auto-generated method stub
-			
+		public LimitedRateGroup[] getRateLimiters(boolean upload) {
+			return null;
+		}
+		public void removeRateLimiter(LimitedRateGroup limiter, boolean upload) {			
 		}
 		public void setHaveAggregationEnabled(boolean enabled) {
 			// TODO Auto-generated method stub
@@ -237,6 +247,10 @@ public class UnchokerUtilTest {
 			// TODO Auto-generated method stub
 			
 		}
+		public boolean isUnchokeOverride() {
+			// TODO Auto-generated method stub
+			return false;
+		}
       };
       
      f_stats[0] = new PEPeerStats() {
@@ -272,6 +286,10 @@ public class UnchokerUtilTest {
         public int getUploadRateLimitBytesPerSecond(){return 0;}
         public int getDownloadRateLimitBytesPerSecond(){return 0;}
         public long getEstimatedSecondsToCompletion(){return(0);};
+        public int getPermittedBytesToSend(){ return 0; }
+        public void permittedSendBytesUsed( int num ){}
+        public int getPermittedBytesToReceive(){ return 0; }
+        public void permittedReceiveBytesUsed( int num ){}
       };
       peers.add( peer );
     }
diff --git a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoder.java b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoder.java
index 34732a4..1247855 100644
--- a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoder.java
+++ b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoder.java
@@ -489,8 +489,12 @@ public class BTPeerIDByteDecoder {
 		assertDecode("TuoTu 2.1.0", "-TT210w-dq!nWf~Qcext");
 		assertDecode("\u00B5Torrent 1.7.0 Beta", "2D555431 3730422D 92844644 1DB0A094 A01C01E5");
 		assertDecode("\u54c7\u560E (Vagaa) 2.6.4.4", "2D5647323634342D4FD62CDA69E235717E3BB94B");
-		assertDecode("Wyzo 0.3.0.0", "-WY0300-6huHF5Pr7Vde");
+		//assertDecode("Wyzo 0.3.0.0", "-WY0300-6huHF5Pr7Vde");
+		assertDecode("FireTorrent 0.3.0.0", "-WY0300-6huHF5Pr7Vde");
 		assertDecode("CacheLogic 25.1-26", "-PC251Q-6huHF5Pr7Vde");
+		assertDecode("KGet 2.4.5.0", "-KG2450-BDEw8OM14Hk6");
+		
+		
 		System.out.println();
 
 		// Shadow style clients.
@@ -550,6 +554,11 @@ public class BTPeerIDByteDecoder {
 		System.out.println("Testing various specialised clients...");
 		assertDecode("Mainline", "0000000000000000000000004C53441933104277");
 		assertDecode(UNKNOWN + " [" + FAKE + ": ZipTorrent 1.6.0.0]", "-ZT1600-bLAdeY9rdjbe");
+		
+		assertDecode("Tixati 1.37", "TIX0137-i6i6f0i5d5b7");
+		assertDecode("folx 0.9", "2D464C3039C6F22D5F436863327A6D792E283867");
+		
+		
 		System.out.println();
 		
 		// Unknown clients - may be random bytes.
@@ -587,6 +596,17 @@ public class BTPeerIDByteDecoder {
 		//assertDecode("", "303030302D2D0000005433585859684B59584C72"); // Seen in the wild, appears to be a modified version of Azureus 2.5.0.0 (that's what was in the AZMP handshake)?
 		//assertDecode("", "B5546F7272656E742F3330323520202020202020");
 
+		assertDecode( "\u00B5Torrent Mac 1.5.11", "2D554D3135313130C964BE6F15CA71EF02AF2DD7" );
+		
+		assertDecode( "MediaGet",     "2D4D47314372302D3234705F6436000055673362" );
+		
+		assertDecode( "Invalid PeerID 0.0.0.0", "-#@0000-Em6o1EmvwLtD");
+		
+		assertDecode( "MediaGet2 2.1", "2D4D47323111302D3234705F6436706E55673362" );
+		
+		assertDecode( "Ares 2.1.7.1", "-AN2171-nr17R1h19O7n" );
+
+		
 		System.out.println("Done.");
 	}
 }
diff --git a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
index 4a5b674..a423d6c 100644
--- a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
+++ b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderDefinitions.java
@@ -60,9 +60,11 @@ public class BTPeerIDByteDecoderDefinitions {
 	static String VER_BLOCK = "abcde"; // Is given as a block in the peer ID, we show the same block
 	static String VER_DOTTED_BLOCK = "a.b.c.d.e"; // Is given as a dotted block in the peer ID, we show the block in the same dotted format.
 	static String VER_BYTE_BLOCK_DOTTED_CHAR = "abcde -> a.b.c.d.e"; // Is given a block in the peer ID, but should be displayed in a dotted format.
+	static String VER_TWOBYTE_BLOCK_DOTTED_CHAR = "abcde -> ab.cd"; // Is given a block in the peer ID, but should be displayed in a dotted format.
 	static String VER_BITS_ON_WHEELS = "BOW-STYLE";
 	static String VER_TWO_BYTE_THREE_PART = "ab -> a . b/10 . b%10";
 	static String NO_VERSION = "NO_VERSION";
+	static String VER_BYTE_UM_STYLE = "abcd -> a.b.cd"; 
 	
 	// Used to register client information.
 	private static void addAzStyle(String id, String client) {
@@ -231,6 +233,7 @@ public class BTPeerIDByteDecoderDefinitions {
 		// ... and then do everything else alphabetically.
 		addAzStyle("A~", "Ares", VER_AZ_THREE_DIGITS);
 		addAzStyle("AG", "Ares", VER_AZ_THREE_DIGITS);
+		addAzStyle("AN", "Ares", VER_AZ_FOUR_DIGITS);
 		//addAzStyle("AR", "ArcticTorrent", NO_VERSION); //based on libtorrent but same peerid for different versions
 		addAzStyle("AR", "Ares"); // Ares is more likely than ArcticTorrent
 		addAzStyle("AV", "Avicora");
@@ -260,6 +263,7 @@ public class BTPeerIDByteDecoderDefinitions {
 		addAzStyle("GS", "GSTorrent"); // TODO: Format is v"abcd"
 		addAzStyle("HL", "Halite", VER_AZ_THREE_DIGITS);
 		addAzStyle("HN", "Hydranode");
+		addAzStyle("KG", "KGet");
 		addAzStyle("KT", "KTorrent", VER_AZ_KTORRENT_STYLE);
 		addAzStyle("LC", "LeechCraft");
 		addAzStyle("LH", "LH-ABC");
@@ -309,7 +313,8 @@ public class BTPeerIDByteDecoderDefinitions {
 		addAzStyle("XX", "XTorrent", "1.2.34");
 		addAzStyle("XC", "XTorrent", "1.2.34");
 		addAzStyle("ZT", "ZipTorrent"); 
-		
+		addAzStyle("#@", "Invalid PeerID");
+
 		addShadowStyle('A', "ABC");
 		addShadowStyle('O', "Osprey Permaseed");
 		addShadowStyle('Q', "BTQueue");
@@ -353,6 +358,8 @@ public class BTPeerIDByteDecoderDefinitions {
 		addSimpleClient("Teeweety", "T00---0");
 		addSimpleClient("TorrentTopia", "346-");
 		addSimpleClient("XanTorrent", "DansClient");
+		addSimpleClient("MediaGet",     "-MG1");
+		addSimpleClient("MediaGet2 2.1", "-MG21");
 		
 		/**
 		 * This is interesting - it uses Mainline style, except uses two characters instead of one.
@@ -429,6 +436,14 @@ public class BTPeerIDByteDecoderDefinitions {
 		client = addSimpleClient("Top-BT", "TB");
 		addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 3);
 		
+		client = addSimpleClient("Tixati", "TIX");
+		addVersionedClient(client, VER_TWOBYTE_BLOCK_DOTTED_CHAR, 4);
+		
+		client = addSimpleClient("folx", "-FL");	// seems to have a sub-version encoded in following 3 bytes, not worked out how: "folx/1.0.456.591" : 2D 464C 3130 FF862D 486263574A43585F66314D5A
+		addVersionedClient(client, VER_BYTE_BLOCK_DOTTED_CHAR, 2);
+
+		client = addSimpleClient("\u00B5Torrent Mac", "-UM");	
+		addVersionedClient(client, VER_BYTE_UM_STYLE, 4);
 	}
 	
 	static class ClientData {
diff --git a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
index 91817c6..f1de195 100644
--- a/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
+++ b/com/aelitis/azureus/core/peermanager/utils/BTPeerIDByteDecoderUtils.java
@@ -325,11 +325,32 @@ class BTPeerIDByteDecoderUtils {
 			}
 			return result;
 		}
+		else if ( version_scheme == BTPeerIDByteDecoderDefinitions.VER_TWOBYTE_BLOCK_DOTTED_CHAR) {
+			String result = "";
+			for (int i=0;i<version_data.length();i+=2 ){
+				String s = version_data.substring( i, i+2 );
+				if ( i == 0 ){
+					if ( s.charAt(0) == '0' ){
+						s = s.substring(1);
+					}
+					result = s;
+				}else{
+					result = joinAsDotted(result, s );
+				}
+			}
+			return result;
+		}
 		else if (version_scheme == BTPeerIDByteDecoderDefinitions.VER_BITS_ON_WHEELS) {
 			if (version_data.equals("A0C")) {return "1.0.6";}
 			else if (version_data.equals("A0B")) {return "1.0.5";}
 			throw new RuntimeException("Unknown BitsOnWheels version number - " + version_data);
 		}
+		else if ( version_scheme == BTPeerIDByteDecoderDefinitions.VER_BYTE_UM_STYLE ){
+			
+			char[] chars = version_data.toCharArray();
+			
+			return( chars[0] + "." + chars[1] + "." + chars[2] + chars[3] );
+		}
 		else {
 			throw new RuntimeException("unknown custom version number scheme - " + version_scheme);
 		}
diff --git a/com/aelitis/azureus/core/peermanager/utils/ClientIdentifier.java b/com/aelitis/azureus/core/peermanager/utils/ClientIdentifier.java
index d2ebf3b..ea7c729 100644
--- a/com/aelitis/azureus/core/peermanager/utils/ClientIdentifier.java
+++ b/com/aelitis/azureus/core/peermanager/utils/ClientIdentifier.java
@@ -64,7 +64,7 @@ public class ClientIdentifier {
 			   *   "Azureus a.b.c.d"
 			   */ 
 			  if (az_client_name.equals("Azureus") && peer_id_client.equals("Azureus")) {
-				  if (!msg_client_name.substring(0, 15).equals(peer_id_client_name.substring(0, 15))) {
+				  if (msg_client_name.length()<15 || peer_id_client_name.length() < 15 || !msg_client_name.substring(0, 15).equals(peer_id_client_name.substring(0, 15))) {
 					  return asDiscrepancy("Azureus (Hacked)", peer_id_client_name, msg_client_name, "fake_client", "AZMP", peer_id);
 				  }
 			  }
diff --git a/com/aelitis/azureus/core/peermanager/utils/OutgoingBTPieceMessageHandler.java b/com/aelitis/azureus/core/peermanager/utils/OutgoingBTPieceMessageHandler.java
index 305c3e3..3142c43 100644
--- a/com/aelitis/azureus/core/peermanager/utils/OutgoingBTPieceMessageHandler.java
+++ b/com/aelitis/azureus/core/peermanager/utils/OutgoingBTPieceMessageHandler.java
@@ -47,9 +47,9 @@ public class OutgoingBTPieceMessageHandler {
   private final OutgoingMessageQueue 	outgoing_message_queue;
   private 		byte					piece_version;
   
-  private final LinkedList requests = new LinkedList();
-  private final ArrayList	loading_messages = new ArrayList();
-  private final HashMap  queued_messages = new HashMap();
+  private final LinkedList<DiskManagerReadRequest>			requests 			= new LinkedList<DiskManagerReadRequest>();
+  private final ArrayList<DiskManagerReadRequest>			loading_messages 	= new ArrayList<DiskManagerReadRequest>();
+  private final HashMap<BTPiece,DiskManagerReadRequest> 	queued_messages 	= new HashMap<BTPiece, DiskManagerReadRequest>();
   
   private final AEMonitor	lock_mon	= new AEMonitor( "OutgoingBTPieceMessageHandler:lock");
   private boolean destroyed = false;
@@ -123,11 +123,11 @@ public class OutgoingBTPieceMessageHandler {
           	  return;
           	}
           	loading_messages.remove( request );
-          	
-          }
-          finally{
+        }finally{
           	lock_mon.exit();
-          }
+        }
+        
+      	peer.sendRejectRequest( request );
     }
     
     public int
@@ -188,14 +188,14 @@ public class OutgoingBTPieceMessageHandler {
    * @param piece_offset
    * @param length
    */
-  public void addPieceRequest( int piece_number, int piece_offset, int length ) {
-    if( destroyed )  return;
+  public boolean addPieceRequest( int piece_number, int piece_offset, int length ) {
+    if( destroyed )  return( false );
          
     DiskManagerReadRequest dmr = peer.getManager().getDiskManager().createReadRequest( piece_number, piece_offset, length );
 
     try{
       lock_mon.enter();
-    
+         
       requests.addLast( dmr );
       
     }finally{
@@ -203,6 +203,8 @@ public class OutgoingBTPieceMessageHandler {
     }
     
     doReadAheadLoads();
+    
+    return( true );
   }
   
   
@@ -217,16 +219,20 @@ public class OutgoingBTPieceMessageHandler {
   	
     DiskManagerReadRequest dmr = peer.getManager().getDiskManager().createReadRequest( piece_number, piece_offset, length );
     
+    boolean	inform_rejected = false;
+    
     try{
       lock_mon.enter();
     
       if( requests.contains( dmr ) ) {
         requests.remove( dmr );
+        inform_rejected = true;
         return;
       }
       
       if( loading_messages.contains( dmr ) ) {
         loading_messages.remove( dmr );
+        inform_rejected = true;
         return;
       }
       
@@ -236,14 +242,20 @@ public class OutgoingBTPieceMessageHandler {
         if( entry.getValue().equals( dmr ) ) {  //it's already been queued
           BTPiece msg = (BTPiece)entry.getKey();
           if( outgoing_message_queue.removeMessage( msg, true ) ) {
+        	inform_rejected = true;
             i.remove();
           }
           break;  //do manual listener notify
         }
       }
-    }
-    finally{
+    }finally{
+    	
       lock_mon.exit();
+      
+      if ( inform_rejected ){
+ 
+   		  peer.sendRejectRequest( dmr );
+      }
     }
     
     outgoing_message_queue.doListenerNotifications();
@@ -257,6 +269,8 @@ public class OutgoingBTPieceMessageHandler {
   public void removeAllPieceRequests() {
   	if( destroyed )  return;
   	
+  	List<DiskManagerReadRequest> removed = new ArrayList<DiskManagerReadRequest>();
+  	
     try{
       lock_mon.enter();
       
@@ -282,19 +296,33 @@ public class OutgoingBTPieceMessageHandler {
       }
       */
       
-      for( Iterator i = queued_messages.keySet().iterator(); i.hasNext(); ) {
-          BTPiece msg = (BTPiece)i.next();
-          outgoing_message_queue.removeMessage( msg, true );
+     
+      for( Iterator<BTPiece> i = queued_messages.keySet().iterator(); i.hasNext(); ) {
+          BTPiece msg = i.next();
+          if (outgoing_message_queue.removeMessage( msg, true )){
+        	  removed.add( queued_messages.get( msg ));
+          }
       }
       
       queued_messages.clear();	// this replaces stuff above 
+      
+      removed.addAll( requests );
+      
       requests.clear();
+      
+      removed.addAll( loading_messages );
+      
       loading_messages.clear();
     }
     finally{
       lock_mon.exit();
     }
     
+    for ( DiskManagerReadRequest request: removed ){
+    	
+    	 peer.sendRejectRequest( request );
+    }
+    
     outgoing_message_queue.doListenerNotifications();
   }
       
diff --git a/com/aelitis/azureus/core/peermanager/utils/PeerClassifier.java b/com/aelitis/azureus/core/peermanager/utils/PeerClassifier.java
index 08c189b..c125339 100644
--- a/com/aelitis/azureus/core/peermanager/utils/PeerClassifier.java
+++ b/com/aelitis/azureus/core/peermanager/utils/PeerClassifier.java
@@ -31,6 +31,8 @@ import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.HostNameToIPResolver;
 import org.gudy.azureus2.core3.util.IPToHostNameResolver;
 
+import com.aelitis.azureus.core.util.FeatureAvailability;
+
 /**
  * Handles peer client identification and banning.
  */
@@ -69,7 +71,19 @@ public class PeerClassifier {
     return true;
   }
   
-
+  public static boolean fullySupportsFE( String client_description ){
+	  
+	  if ( FeatureAvailability.allowAllFEClients()){
+		  
+		  return( true );
+	  }
+	  
+	  	// some clients don't ever offer any fast-allow pieces so we reciprocate
+	  
+	  boolean res = !(client_description.startsWith( "\u00B5" ) || client_description.startsWith( "Trans" ));
+	  	  
+	  return( res );
+  }
   
 	private static Set	platform_ips = Collections.synchronizedSet(new HashSet());
 
diff --git a/com/aelitis/azureus/core/proxy/impl/AEProxyConnectionImpl.java b/com/aelitis/azureus/core/proxy/impl/AEProxyConnectionImpl.java
index 2761e4f..28b9af3 100644
--- a/com/aelitis/azureus/core/proxy/impl/AEProxyConnectionImpl.java
+++ b/com/aelitis/azureus/core/proxy/impl/AEProxyConnectionImpl.java
@@ -24,6 +24,7 @@ package com.aelitis.azureus.core.proxy.impl;
 
 import java.util.*;
 
+import java.io.EOFException;
 import java.nio.channels.*;
 
 import org.gudy.azureus2.core3.logging.*;
@@ -203,16 +204,33 @@ AEProxyConnectionImpl
 		Throwable			reason )
 	{
 		try{
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "AEProxyProcessor: " + getName()
-						+ " failed", reason));
+			if ( Logger.isEnabled()){
+				
+				if ( reason instanceof EOFException ){
+				
+					Logger.log(new LogEvent(LOGID, "AEProxyProcessor: " + getName() + ": connection closed" ));
+				
+				}else{
+				
+					String message = reason.getMessage();
+					
+					if ( 	message != null &&
+							( message.contains( "closed" ) || message.contains( "aborted" ))){
+						
+						Logger.log(new LogEvent(LOGID, "AEProxyProcessor: " + getName()	+ " failed: " + message ));
+						
+					}else{
+							
+						Logger.log(new LogEvent(LOGID, "AEProxyProcessor: " + getName()	+ " failed", reason ));
+					}
+				}
+			}
 			
 			close();
 			
 		}catch( Throwable e ){
 			
 			Debug.printStackTrace(e);
-			
 		}
 	}
 	
diff --git a/com/aelitis/azureus/core/proxy/impl/AEProxyImpl.java b/com/aelitis/azureus/core/proxy/impl/AEProxyImpl.java
index 541fafd..5681538 100644
--- a/com/aelitis/azureus/core/proxy/impl/AEProxyImpl.java
+++ b/com/aelitis/azureus/core/proxy/impl/AEProxyImpl.java
@@ -26,6 +26,7 @@ import java.util.*;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
+import java.net.SocketTimeoutException;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
 
@@ -370,7 +371,7 @@ AEProxyImpl
 		
 		for (int i=0;i<closes.size();i++){
 			
-			((AEProxyConnectionImpl)closes.get(i)).failed( new Throwable( "timeout" ));
+			((AEProxyConnectionImpl)closes.get(i)).failed( new SocketTimeoutException( "timeout" ));
 		}
 	}
 	
diff --git a/com/aelitis/azureus/core/proxy/socks/AESocksProxyConnection.java b/com/aelitis/azureus/core/proxy/socks/AESocksProxyConnection.java
index 2cb8f4b..65cbcce 100644
--- a/com/aelitis/azureus/core/proxy/socks/AESocksProxyConnection.java
+++ b/com/aelitis/azureus/core/proxy/socks/AESocksProxyConnection.java
@@ -46,6 +46,9 @@ AESocksProxyConnection
 	public void
 	enableDNSLookups();
 	
+	public boolean
+	areDNSLookupsEnabled();
+	
 	public void
 	connected()
 	
diff --git a/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyConnectionImpl.java b/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyConnectionImpl.java
index 972cb03..81b5aa2 100644
--- a/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyConnectionImpl.java
+++ b/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyConnectionImpl.java
@@ -153,6 +153,12 @@ AESocksProxyConnectionImpl
 		disable_dns_lookups = false;
 	}
 	
+	public boolean 
+	areDNSLookupsEnabled() 
+	{
+		return( !disable_dns_lookups );
+	}
+	
 	public void
 	close()
 	
@@ -697,7 +703,7 @@ AESocksProxyConnectionImpl
 			
 			if ( command != 1 ){
 				
-				throw( new IOException( "V5: Only connect supported"));
+				throw( new IOException( "V5: Only connect supported: command=" + command ));
 			}
 			
 			if ( address_type == 1 ){
@@ -708,9 +714,12 @@ AESocksProxyConnectionImpl
 				
 				new proxyStateV5RequestDNS();
 				
+			}else if ( address_type == 4 ){
+				
+				new proxyStateV5RequestIPV6();
 			}else{
 				
-				throw( new IOException( "V5: Unsupported address type" ));
+				throw( new IOException( "V5: Unsupported address type: " + address_type ));
 			}
 			
 			return( true );
@@ -770,6 +779,58 @@ AESocksProxyConnectionImpl
 	}
 	
 	protected class
+	proxyStateV5RequestIPV6
+		extends AESocksProxyState
+	{
+		
+		protected
+		proxyStateV5RequestIPV6()
+		{
+			super( AESocksProxyConnectionImpl.this );
+			
+			connection.setReadState( this );
+			
+			buffer	= ByteBuffer.allocate(16);
+		}
+		
+		protected boolean
+		readSupport(
+			SocketChannel 		sc )
+		
+			throws IOException
+		{
+			int	len = sc.read( buffer );
+			
+			if ( len == 0 ){
+				
+				return( false );
+				
+			}else if ( len == -1 ){
+				
+				throw( new IOException( "read channel shutdown" ));
+			}
+			
+			
+			if ( buffer.hasRemaining()){
+				
+				return( true );
+			}
+			
+			buffer.flip();
+			
+			byte[]	bytes = new byte[16];
+			
+			buffer.get( bytes );
+			
+			InetAddress inet_address = InetAddress.getByAddress( bytes );
+			
+			new proxyStateV5RequestPort( "", inet_address );
+			
+			return( true );
+		}
+	}
+	
+	protected class
 	proxyStateV5RequestDNS
 		extends AESocksProxyState
 	{
diff --git a/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyPlugableConnectionDefault.java b/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyPlugableConnectionDefault.java
index 50c87c0..17e57d7 100644
--- a/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyPlugableConnectionDefault.java
+++ b/com/aelitis/azureus/core/proxy/socks/impl/AESocksProxyPlugableConnectionDefault.java
@@ -30,6 +30,7 @@ import java.nio.channels.SocketChannel;
 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.HostNameToIPResolver;
 
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.proxy.AEProxyConnection;
@@ -95,12 +96,26 @@ AESocksProxyPlugableConnectionDefault
 		
 		throws IOException
 	{
-		if ( _address.getAddress() == null ){
+		InetAddress address = _address.getAddress();
+		
+		if ( address == null ){
 
-			throw( new IOException( "DNS lookup of '" + _address.getUnresolvedAddress() + "' fails" ));
+			if ( socks_connection.areDNSLookupsEnabled()){
+				
+				try{
+					address = HostNameToIPResolver.syncResolve( _address.getUnresolvedAddress());
+					
+				}catch( Throwable e ){				
+				}
+			}
+			
+			if ( address == null ){
+			
+				throw( new IOException( "DNS lookup of '" + _address.getUnresolvedAddress() + "' fails" ));
+			}
 		}
 		
-		new proxyStateRelayConnect( new InetSocketAddress(_address.getAddress(), _address.getPort()));
+		new proxyStateRelayConnect( new InetSocketAddress( address, _address.getPort()));
 	}
 	
 	public void
diff --git a/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java b/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java
index bb3ae83..da13ef5 100644
--- a/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java
+++ b/com/aelitis/azureus/core/rssgen/RSSGeneratorPlugin.java
@@ -36,6 +36,8 @@ 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.config.HyperlinkParameter;
+import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
 import org.gudy.azureus2.ui.webplugin.WebPlugin;
 
 
@@ -57,6 +59,9 @@ RSSGeneratorPlugin
 	load(
 		PluginInterface		plugin_interface )
 	{
+		plugin_interface.getPluginProperties().setProperty( "plugin.version", 	"1.0" );
+		plugin_interface.getPluginProperties().setProperty( "plugin.name", 		PLUGIN_NAME );
+
 		synchronized( RSSGeneratorPlugin.class ){
 			
 			if ( loaded ){
@@ -66,10 +71,7 @@ RSSGeneratorPlugin
 			
 			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()){
@@ -80,8 +82,7 @@ RSSGeneratorPlugin
 		Integer	rss_port;
 		String	rss_access;
 		
-		if ( 	COConfigurationManager.getBooleanParameter( "rss.internal.migrated", false ) ||
-				!COConfigurationManager.getBooleanParameter( "Plugin.default.device.rss.enable", false )){
+		if ( COConfigurationManager.getBooleanParameter( "rss.internal.migrated", false )){
 			
 			rss_port 	= COConfigurationManager.getIntParameter( "rss.internal.config.port", DEFAULT_PORT );
 			rss_access 	= COConfigurationManager.getStringParameter( "rss.internal.config.access", DEFAULT_ACCESS );
@@ -130,7 +131,9 @@ RSSGeneratorPlugin
 	}
 	
 	
-	private Map<String,Provider>	providers = new TreeMap<String, Provider>();
+	private static Map<String,Provider>	providers = new TreeMap<String, Provider>();
+	
+	private HyperlinkParameter		test_param;
 	
 	public
 	RSSGeneratorPlugin()
@@ -144,7 +147,21 @@ RSSGeneratorPlugin
 		return( getProtocol() + "://127.0.0.1:" + getPort() + "/" );
 	}
 	
-	public void
+	@Override
+	protected void
+	setupServer()
+	{
+		super.setupServer();
+		
+		if ( test_param != null ){
+		
+			test_param.setEnabled( isPluginEnabled());
+		
+			test_param.setHyperlink( getURL());
+		}
+	}
+	
+	public static void
 	registerProvider(
 		String				name,
 		Provider			provider )
@@ -155,6 +172,16 @@ RSSGeneratorPlugin
 		}
 	}
 	
+	public static void
+	unregisterProvider(
+		String				name )
+	{
+		synchronized( providers ){
+		
+			providers.remove( name );
+		}
+	}
+	
 	public void
 	initialize(
 		PluginInterface		pi )
@@ -168,6 +195,21 @@ RSSGeneratorPlugin
 		super.initialize( pi );
 	}
 	
+	@Override
+	protected void
+	initStage(
+		int	num )
+	{
+		if ( num == 1 ){
+			
+			BasicPluginConfigModel  config = getConfigModel();
+			
+			test_param = config.addHyperlinkParameter2( "rss.internal.test.url", "" );
+			
+			test_param.setEnabled( isPluginEnabled());
+		}
+	}
+	
 	public boolean
 	generateSupport(
 		TrackerWebPageRequest		request,
@@ -182,7 +224,7 @@ RSSGeneratorPlugin
 			url = url.substring( 1 );
 		}
 	
-		if ( url.length() == 0 ){
+		if ( url.length() == 0 || url.charAt(0) == '?' ){
 			
 			response.setContentType( "text/html; charset=UTF-8" );
 			
diff --git a/com/aelitis/azureus/core/security/CryptoECCUtils.java b/com/aelitis/azureus/core/security/CryptoECCUtils.java
index 2357f5b..f782364 100644
--- a/com/aelitis/azureus/core/security/CryptoECCUtils.java
+++ b/com/aelitis/azureus/core/security/CryptoECCUtils.java
@@ -167,7 +167,7 @@ CryptoECCUtils
    			
    		}catch (Throwable e){
    		
-   			throw( new CryptoManagerException( "Failed to decode public key" ));
+   			throw( new CryptoManagerException( "Failed to decode public key", e ));
    		}
    	}	
 }
diff --git a/com/aelitis/azureus/core/security/CryptoManager.java b/com/aelitis/azureus/core/security/CryptoManager.java
index d1d4558..b81467f 100644
--- a/com/aelitis/azureus/core/security/CryptoManager.java
+++ b/com/aelitis/azureus/core/security/CryptoManager.java
@@ -39,6 +39,14 @@ CryptoManager
 	public CryptoHandler
 	getECCHandler();
 	
+	public byte[]
+	obfuscate(
+		byte[]		data );
+	
+	public byte[]
+	deobfuscate(
+		byte[]		data );
+	
 	public void
 	clearPasswords();
 	
diff --git a/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java b/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
index 5a5c19d..9b8f863 100644
--- a/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
+++ b/com/aelitis/azureus/core/security/impl/CryptoManagerImpl.java
@@ -32,12 +32,16 @@ import javax.crypto.SecretKeyFactory;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.PBEParameterSpec;
 
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.engines.RC4Engine;
+import org.bouncycastle.crypto.params.KeyParameter;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.RandomUtils;
 import org.gudy.azureus2.core3.util.SHA1;
+import org.gudy.azureus2.core3.util.SHA1Simple;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.TimerEvent;
@@ -160,6 +164,55 @@ CryptoManagerImpl
 		return( secure_id );
 	}
 	
+	private byte[]
+	getOBSID()
+	{
+		String key = CryptoManager.CRYPTO_CONFIG_PREFIX + "obs.id";
+					
+		byte[] obs_id = COConfigurationManager.getByteParameter( key, null );
+		
+		if ( obs_id == null ){
+			
+			obs_id = new byte[20];
+		
+			RandomUtils.SECURE_RANDOM.nextBytes( obs_id );
+			
+			COConfigurationManager.setParameter( key, obs_id );
+			
+			COConfigurationManager.save();
+		}
+		
+		return( obs_id );
+	}
+	
+	public byte[]
+	obfuscate(
+		byte[]		data )
+	{
+		RC4Engine	engine = new RC4Engine();
+        
+		CipherParameters	params = new KeyParameter( new SHA1Simple().calculateHash( getOBSID()));
+		
+		engine.init( true, params ); 
+
+		byte[]	temp = new byte[1024];
+		
+		engine.processBytes( temp, 0, 1024, temp, 0 );
+		
+		final byte[] obs_value = new byte[ data.length ];
+		
+		engine.processBytes( data, 0, data.length, obs_value, 0 );
+		
+		return( obs_value );
+	}
+	
+	public byte[]
+	deobfuscate(
+		byte[]		data )
+	{
+		return( obfuscate( data ));
+	}
+	
 	public CryptoHandler
 	getECCHandler()
 	{
diff --git a/com/aelitis/azureus/core/speedmanager/SpeedLimitHandler.java b/com/aelitis/azureus/core/speedmanager/SpeedLimitHandler.java
new file mode 100644
index 0000000..fea9a8f
--- /dev/null
+++ b/com/aelitis/azureus/core/speedmanager/SpeedLimitHandler.java
@@ -0,0 +1,1734 @@
+/*
+ * Created on Feb 3, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.speedmanager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+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.config.impl.TransferSpeedValidator;
+import org.gudy.azureus2.core3.download.DownloadManager;
+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.torrent.TOTorrent;
+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.DisplayFormatters;
+import org.gudy.azureus2.core3.util.HashWrapper;
+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.core3.util.TimerEventPeriodic;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
+
+public class 
+SpeedLimitHandler 
+{
+	private static SpeedLimitHandler		singleton;
+	
+	public static SpeedLimitHandler
+	getSingleton(
+		AzureusCore		core )
+	{
+		synchronized( SpeedLimitHandler.class ){
+			
+			if ( singleton == null ){
+				
+				singleton = new SpeedLimitHandler( core );
+			}
+			
+			return( singleton );
+		}
+	}
+	
+	private AzureusCore		core;
+		
+	private TimerEventPeriodic		schedule_event;
+	private List<ScheduleRule>		current_rules	= new ArrayList<ScheduleRule>();
+	private ScheduleRule			active_rule;
+	
+	private
+	SpeedLimitHandler(
+		AzureusCore		_core )
+	{
+		core 	= _core;
+		
+		loadSchedule();
+	}
+	
+	private synchronized Map
+	loadConfig()
+	{
+		return( BEncoder.cloneMap( COConfigurationManager.getMapParameter( "speed.limit.handler.state", new HashMap())));
+	}
+	
+	private synchronized void
+	saveConfig(
+		Map		map )
+	{
+		COConfigurationManager.setParameter( "speed.limit.handler.state", map );
+		
+		COConfigurationManager.save();
+	}
+	
+	public List<String>
+	reset()
+	{
+		LimitDetails details = new LimitDetails();
+		
+		details.loadForReset();
+		
+		details.apply();
+		
+		return( details.getString( true ));
+	}
+	
+	public List<String>
+	getCurrent()
+	{
+		LimitDetails details = new LimitDetails();
+		
+		details.loadCurrent();
+		
+		List<String> lines = details.getString( true );
+		
+		ScheduleRule rule = active_rule;
+		
+		lines.add( "" );
+		lines.add( "Scheduler" );
+		lines.add( "    Rules defined: " + current_rules.size());
+		lines.add( "    Active rule: " + (rule==null?"None":rule.getString()));
+		
+		return( lines );
+	}
+	
+	public List<String>
+	getProfileNames()
+	{
+		Map	map = loadConfig();
+				
+		List<String> profiles = new ArrayList<String>();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	name = importString( m, "n" );
+				
+				if ( name != null ){
+					
+					profiles.add( name );
+				}
+			}
+		}
+
+		return( profiles );
+	}
+	
+	public List<String>
+	loadProfile(
+		String		name )
+	{		
+		Map	map = loadConfig();
+				
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null && name.equals( p_name )){
+					
+					Map profile = (Map)m.get( "p" );
+					
+					LimitDetails ld = new LimitDetails( profile );
+					
+					ld.apply();
+					
+					return( ld.getString( false ));
+				}
+			}
+		}
+		
+		List<String> result = new ArrayList<String>();
+		
+		result.add( "Profile not found" );
+
+		return( result );
+	}
+	
+	private boolean
+	profileExists(
+		String		name )
+	{
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null && name.equals( p_name )){
+					
+					return( true );
+				}
+			}
+		}
+		
+		return( false );
+	}
+	
+	public List<String>
+	getProfile(
+		String		name )
+	{
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null && name.equals( p_name )){
+					
+					Map profile = (Map)m.get( "p" );
+					
+					LimitDetails ld = new LimitDetails( profile );
+										
+					return( ld.getString( false ));
+				}
+			}
+		}
+		
+		List<String> result = new ArrayList<String>();
+		
+		result.add( "Profile not found" );
+
+		return( result );
+	}
+	
+	public List<String>
+	getProfilesForDownload(
+		byte[]		hash )
+	{
+		List<String> result = new ArrayList<String>();
+
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			String	hash_str = Base32.encode( hash );
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null ){
+					
+					Map profile = (Map)m.get( "p" );
+					
+					LimitDetails ld = new LimitDetails( profile );
+										
+					if ( ld.getLimitsForDownload( hash_str ) != null ){
+						
+						result.add( p_name );
+					}
+				}
+			}
+		}
+	
+		return( result );
+	}
+	
+	private void
+	addRemoveDownloadsToProfile(
+		String			name,
+		List<byte[]>	hashes,
+		boolean			add )
+	{
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		List<String>	hash_strs = new ArrayList<String>();
+		
+		for ( byte[] hash: hashes ){
+			
+			hash_strs.add( Base32.encode( hash ));
+		}
+		
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null && name.equals( p_name )){
+					
+					Map profile = (Map)m.get( "p" );
+					
+					LimitDetails ld = new LimitDetails( profile );
+					
+					ld.addRemoveDownloads( hash_strs, add );
+					
+					m.put( "p", ld.export());
+					
+					saveConfig( map );
+
+					return;
+				}
+			}
+		}
+	}
+	
+	public void
+	addDownloadsToProfile(
+		String			name,
+		List<byte[]>	hashes )
+	{
+		addRemoveDownloadsToProfile( name, hashes, true );
+	}
+	
+	public void
+	removeDownloadsFromProfile(
+		String			name,
+		List<byte[]>	hashes )
+	{
+		addRemoveDownloadsToProfile( name, hashes, false );
+	}
+	
+	public void
+	deleteProfile(
+		String		name )
+	{
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list != null ){
+			
+			for ( Map m: list ){
+				
+				String	p_name = importString( m, "n" );
+				
+				if ( p_name != null && name.equals( p_name )){
+					
+					list.remove( m );
+					
+					saveConfig( map );
+					
+					return;
+				}
+			}
+		}
+	}
+	
+	public List<String>
+	saveProfile(
+		String		name )
+	{
+		LimitDetails details = new LimitDetails();
+		
+		details.loadCurrent();
+		
+		Map	map = loadConfig();
+		
+		List<Map> list = (List<Map>)map.get( "profiles" );
+
+		if ( list == null ){
+			
+			list = new ArrayList<Map>();
+			
+			map.put( "profiles", list );
+		}
+		
+		for ( Map m: list ){
+			
+			String	p_name = importString( m, "n" );
+			
+			if ( p_name != null && name.equals( p_name )){
+				
+				list.remove( m );
+				
+				break;
+			}
+		}
+		
+		Map m = new HashMap();
+		
+		list.add( m );
+		
+		m.put( "n", name );
+		m.put( "p", details.export());
+		
+		saveConfig( map );
+		
+		ScheduleRule	rule;
+		
+		synchronized( this ){
+			
+			rule = active_rule;
+		}
+		
+		if ( rule != null && rule.profile_name.equals( name )){
+			
+			details.apply();
+		}
+		
+		return( details.getString( false ));
+	}
+	
+	private synchronized List<String>
+	loadSchedule()
+	{
+		List<String>	result = new ArrayList<String>();
+		
+		List<String> schedule_lines = BDecoder.decodeStrings( COConfigurationManager.getListParameter( "speed.limit.handler.schedule.lines", new ArrayList()));
+
+		boolean	enabled = true;
+		
+		List<ScheduleRule>	rules = new ArrayList<ScheduleRule>();
+		
+		for ( String line: schedule_lines ){
+			
+			line = line.trim();
+			
+			if ( line.length() == 0 || line.startsWith( "#" )){
+				
+				continue;
+			}
+			
+			String lc_line = line.toLowerCase( Locale.US );
+			
+			if ( lc_line.startsWith( "enable" )){
+				
+				String[]	bits = lc_line.split( "=" );
+				
+				boolean	ok = false;
+				
+				if ( bits.length == 2 ){
+					
+					String arg = bits[1];
+					
+					if ( arg.equals( "yes" )){
+						
+						enabled = true;
+						ok		= true;
+						
+					}else if ( arg.equals( "no" )){
+						
+						enabled = false;
+						ok		= true;
+					}
+				}
+				
+				if ( !ok ){
+					
+					result.add( "'" +line + "' is invalid: use enable=(yes|no)" );
+				}
+			}else{
+				
+				String[]	_bits = line.split( " " );
+							
+				List<String>	bits = new ArrayList<String>();
+				
+				for ( String b: _bits ){
+					
+					b = b.trim();
+					
+					if ( b.length() > 0 ){
+						
+						bits.add( b );
+					}
+				}
+				
+				List<String>	errors = new ArrayList<String>();
+				
+				if ( bits.size() == 6 ){
+					
+					String	freq_str = bits.get(0).toLowerCase( Locale.US );
+					
+					byte	freq = 0;
+					
+					if ( freq_str.equals( "daily" )){
+						
+						freq = ScheduleRule.FR_DAILY;
+						
+					}else if ( freq_str.equals( "weekdays" )){
+						
+						freq = ScheduleRule.FR_WEEKDAY;
+						
+					}else if ( freq_str.equals( "weekends" )){
+						
+						freq = ScheduleRule.FR_WEEKEND;
+						
+					}else if ( freq_str.equals( "mon" )){
+						
+						freq = ScheduleRule.FR_MON;
+						
+					}else if ( freq_str.equals( "tue" )){
+						
+						freq = ScheduleRule.FR_TUE;
+						
+					}else if ( freq_str.equals( "wed" )){
+						
+						freq = ScheduleRule.FR_WED;
+						
+					}else if ( freq_str.equals( "thu" )){
+						
+						freq = ScheduleRule.FR_THU;
+						
+					}else if ( freq_str.equals( "fri" )){
+						
+						freq = ScheduleRule.FR_FRI;
+						
+					}else if ( freq_str.equals( "sat" )){
+						
+						freq = ScheduleRule.FR_SAT;
+						
+					}else if ( freq_str.equals( "sun" )){
+						
+						freq = ScheduleRule.FR_SUN;
+						
+					}else{
+						
+						errors.add( "frequency '" + freq_str + "' is invalid" );
+					}
+					
+					String	profile = bits.get(1);
+					
+					if ( !profileExists( profile )){
+						
+						errors.add( "profile '" + profile + "' not found" );
+						
+						profile = null;
+					}
+					
+					int from_mins = -1;
+					
+					if ( bits.get(2).equalsIgnoreCase( "from" )){
+						
+						from_mins = getMins( bits.get(3));
+					}
+					
+					if ( from_mins == -1 ){
+						
+						errors.add( "'from' is invalid" );
+					}
+					
+					int to_mins = -1;
+					
+					if ( bits.get(4).equalsIgnoreCase( "to" )){
+						
+						to_mins = getMins( bits.get(5));
+					}
+					
+					if ( to_mins == -1 ){
+						
+						errors.add( "'to' is invalid" );
+					}
+					
+					if ( errors.size() == 0 ){
+						
+						rules.add( new ScheduleRule( freq, profile, from_mins, to_mins ));
+						
+					}else{
+						
+						String	err_str = "";
+						
+						for ( String e: errors ){
+							
+							err_str += (err_str.length()==0?"":", ") + e;
+						}
+						
+						result.add( "'" + line + "' is invalid (" + err_str + ") - use <frequency> <profile> from <hh:mm> to <hh:mm>" );
+					}
+				}else{
+					
+					result.add( "'" + line + "' is invalid: use <frequency> <profile> from <hh:mm> to <hh:mm>" );
+				}
+			}
+		}
+		
+		if ( enabled ){
+			
+			current_rules = rules;
+			
+			if ( schedule_event == null && rules.size() > 0 ){
+				
+				schedule_event = 
+					SimpleTimer.addPeriodicEvent(
+						"speed handler scheduler",
+						30*1000,
+						new TimerEventPerformer()
+						{
+							public void 
+							perform(
+								TimerEvent event) 
+							{
+								checkSchedule();
+							}
+						});
+			}
+			
+			if ( active_rule != null || rules.size() > 0 ){
+			
+				checkSchedule();
+			}
+		}else{
+	
+			current_rules.clear();
+			
+			if ( schedule_event != null ){
+				
+				schedule_event.cancel();
+				
+				schedule_event = null;
+			}
+			
+			if ( active_rule != null ){
+				
+				active_rule	= null;
+				
+				reset();
+			}
+		}
+		
+		return( result );
+	}
+	
+	private int
+	getMins(
+		String	str )
+	{
+		try{
+			String[]	bits = str.split( ":" );
+			
+			if ( bits.length == 2 ){
+				
+				return( Integer.parseInt(bits[0].trim())*60 + Integer.parseInt(bits[1].trim()));
+			}
+		}catch( Throwable e ){
+		}
+		
+		return( -1 );
+	}
+	
+	private synchronized void
+	checkSchedule()
+	{
+		Calendar cal = new GregorianCalendar();
+		
+		int	day_of_week = cal.get( Calendar.DAY_OF_WEEK );
+		int	hour_of_day	= cal.get( Calendar.HOUR_OF_DAY );
+		int min_of_hour	= cal.get( Calendar.MINUTE );
+		
+		int	day = -1;
+		
+		switch( day_of_week ){
+		case Calendar.MONDAY:
+			day = ScheduleRule.FR_MON;
+			break;
+		case Calendar.TUESDAY:
+			day = ScheduleRule.FR_TUE;
+			break;
+		case Calendar.WEDNESDAY:
+			day = ScheduleRule.FR_WED;
+			break;
+		case Calendar.THURSDAY:
+			day = ScheduleRule.FR_THU;
+			break;
+		case Calendar.FRIDAY:
+			day = ScheduleRule.FR_FRI;
+			break;
+		case Calendar.SATURDAY:
+			day = ScheduleRule.FR_SAT;
+			break;
+		case Calendar.SUNDAY:
+			day = ScheduleRule.FR_SUN;
+			break;
+		}
+		
+		int	min_of_day = hour_of_day * 60 + min_of_hour;
+		
+		ScheduleRule latest_match = null;
+		
+		for ( ScheduleRule main_rule: current_rules ){
+			
+			List<ScheduleRule>	sub_rules = main_rule.splitByDay();
+			
+			for ( ScheduleRule rule: sub_rules ){
+			
+				if (( rule.frequency | day ) == 0 ){
+					
+					continue;
+				}
+				
+				if (	rule.from_mins <= min_of_day &&
+						rule.to_mins >= min_of_day ){
+					
+					latest_match = main_rule;
+				}
+			}
+		}
+		
+		if ( latest_match == null ){
+			
+			active_rule = null;
+			
+			reset();
+			
+		}else{
+			
+			String	profile_name = latest_match.profile_name;
+							
+			if ( active_rule == null || !active_rule.sameAs( latest_match )){
+				
+				if ( profileExists( profile_name )){
+
+					active_rule = latest_match;
+				
+					loadProfile( profile_name );
+					
+				}else{
+					
+					active_rule = null;
+					
+					reset();
+				}
+			}
+		}
+	}
+	
+	public List<String>
+	getSchedule()
+	{
+		List<String>	result = new ArrayList<String>();
+		
+		result.add( "# Enter rules on separate lines below this section." );
+		result.add( "# Rules are of the following types:" );
+		result.add( "#    enable=(yes|no)   - controls whether the entire schedule is enabled or not (default=enabled)" );
+		result.add( "#    <frequency> <profile_name> from <time> to <time>" );
+		result.add( "#        frequency: daily|weekdays|weekends|<day_of_week>" );
+		result.add( "#            days_of_week: mon|tue|wed|thu|fri|sat|sun" );
+		result.add( "#    <time>: hh:mm - 24 hour clock; 00:00=midnight; local time" );
+		result.add( "#" );
+		result.add( "# For example - assuming there are profiles called 'no_limits' and 'limited_uplaod' defined:" );
+		result.add( "#" );
+		result.add( "#     daily no_limits from 00:00 to 23:59" );
+		result.add( "#     daily limited_upload from 06:00 to 22:00" );
+		result.add( "#" );
+		result.add( "# When multiple rules apply the one further down the list of rules take precedence" );
+		result.add( "# Comment lines are prefixed with '#'" );
+
+		
+		List<String> profiles = getProfileNames();
+		
+		if ( profiles.size() == 0 ){
+			
+			result.add( "# No profiles currently defined, you'll need to add some." );
+			
+		}else{
+			String	str = "";
+			
+			for( String s: profiles ){
+				str += (str.length()==0?"":", ") + s;
+			}
+			
+			result.add( "# Current profiles details:" );
+			result.add( "#     defined: " + str );
+			
+			ScheduleRule	current_rule;
+			
+			synchronized( this ){
+				
+				current_rule = active_rule;
+			}
+		
+			result.add( "#     active: " + (current_rule==null?"none":current_rule.profile_name ));
+		}
+		
+		result.add( "# ---- Do not edit this line or any text above! ----" );
+		
+		List<String> schedule_lines = BDecoder.decodeStrings( COConfigurationManager.getListParameter( "speed.limit.handler.schedule.lines", new ArrayList()));
+		
+		if ( schedule_lines.size() == 0 ){
+			
+			schedule_lines.add( "" );
+			schedule_lines.add( "" );
+			
+		}else{
+		
+			for ( String l: schedule_lines ){
+			
+				result.add( l.trim());
+			}
+		}
+		
+		return( result );
+	}
+	
+	public List<String>
+	setSchedule(
+		List<String>		lines )
+	{
+		int	trim_from = 0;
+		
+		for ( int i=0; i<lines.size(); i++ ){
+			
+			String	line = lines.get( i );
+			
+			if ( line.startsWith( "# ---- Do not edit" )){
+				
+				trim_from = i+1;
+			}
+		}
+		
+		if ( trim_from > 0 ){
+			
+			lines = lines.subList( trim_from, lines.size());
+		}
+		
+		COConfigurationManager.setParameter( "speed.limit.handler.schedule.lines", lines );
+		
+		return( loadSchedule());
+	}
+	
+	private List<LimitedRateGroup>
+	trim(
+		LimitedRateGroup[]	groups )
+	{
+		List<LimitedRateGroup> result = new ArrayList<LimitedRateGroup>();
+		
+		for ( LimitedRateGroup group: groups ){
+			
+			if ( group instanceof UtilitiesImpl.PluginLimitedRateGroup ){
+				
+				result.add( group );
+			}
+		}
+		
+		return( result );
+	}
+	
+	private String
+	formatUp(
+		int	rate )
+	{
+		return( "Up=" + format( rate ));
+	}
+	
+	private String
+	formatDown(
+		int	rate )
+	{
+		return( "Down=" + format( rate ));
+	}
+	
+	private String
+	format(
+		int		rate )
+	{
+		if ( rate < 0 ){
+			
+			return( "Disabled" );
+			
+		}else if ( rate == 0 ){
+			
+			return( "Unlimited" );
+			
+		}else{
+			
+			return( DisplayFormatters.formatByteCountToKiBEtcPerSec( rate ));
+		}
+	}
+	
+	private String
+	formatUp(
+		List<LimitedRateGroup>	groups )
+	{
+		return( "Up=" + format( groups ));
+	}
+	
+	private String
+	formatDown(
+		List<LimitedRateGroup>	groups )
+	{
+		return( "Down=" + format( groups ));
+	}
+	
+	private String
+	format(
+		List<LimitedRateGroup>	groups )
+	{
+		String str = "";
+		
+		for ( LimitedRateGroup group: groups ){
+			
+			str += (str.length()==0?"":", ") + group.getName() + ":" + format( group.getRateLimitBytesPerSecond());
+		}
+		
+		return( str );
+	}
+	
+    private void
+    exportBoolean(
+    	Map<String,Object>	map,
+    	String				key,
+    	boolean				b )
+    {
+    	map.put( key, new Long(b?1:0));
+    }
+    
+    private boolean
+    importBoolean(
+    	Map<String,Object>	map,
+    	String				key )
+    {
+    	Long	l = (Long)map.get( key );
+    	
+    	if ( l != null ){
+    		
+    		return( l == 1 );
+    	}
+    	
+    	return( false );
+    }
+    
+    private void
+    exportInt(
+    	Map<String,Object>	map,
+    	String				key,
+    	int					i )
+    {
+    	map.put( key, new Long( i ));
+    }
+    
+    private int
+    importInt(
+    	Map<String,Object>	map,
+    	String				key )
+    {
+    	Long	l = (Long)map.get( key );
+    	
+    	if ( l != null ){
+    		
+    		return( l.intValue());
+    	}
+    	
+    	return( 0 );
+    }
+    
+    private void
+    exportString(
+    	Map<String,Object>	map,
+    	String				key,
+    	String				s )
+    {
+    	try{
+    		map.put( key, s.getBytes( "UTF-8" ));
+    		
+    	}catch( Throwable e ){
+    	}
+    }
+    
+    private String
+    importString(
+    	Map<String,Object>	map,
+    	String				key )
+    {
+       	Object obj= map.get( key );
+       	
+       	if ( obj instanceof String ){
+       		
+       		return((String)obj);
+       		
+       	}else if ( obj instanceof byte[] ){
+       	
+    		try{
+    			return( new String((byte[])obj, "UTF-8" ));
+    			
+    		}catch( Throwable e ){
+	    	}
+       	}
+       	
+    	return( null );
+    }
+    
+	private class
+	LimitDetails
+	{
+	    private boolean		auto_up_enabled;
+	    private boolean		auto_up_seeding_enabled;
+	    private boolean		seeding_limits_enabled;
+	    private int			up_limit;
+	    private int			up_seeding_limit;
+	    private int			down_limit;
+	    
+	    private boolean		lan_rates_enabled;
+	    private int			lan_up_limit;
+	    private int			lan_down_limit;
+	    
+	    private Map<String,int[]>	download_limits = new HashMap<String, int[]>();
+	    private Map<String,int[]>	category_limits = new HashMap<String, int[]>();
+	    
+	    private 
+	    LimitDetails()
+	    {	
+	    }
+	    
+	    private 
+	    LimitDetails(
+	    	Map<String,Object>		map )
+	    {
+	    	auto_up_enabled 		= importBoolean( map, "aue" );
+	    	auto_up_seeding_enabled	= importBoolean( map, "ause" );
+	    	seeding_limits_enabled	= importBoolean( map, "sle" );
+	    	
+	    	up_limit			= importInt( map, "ul" );
+	    	up_seeding_limit	= importInt( map, "usl" );
+	    	down_limit			= importInt( map, "dl" );
+	    	
+	    	if ( map.containsKey( "lre" )){
+	    		
+	    		lan_rates_enabled 		= importBoolean( map, "lre" );
+	    		
+	    	}else{
+	    			// migration from before LAN rates added
+	    		
+	    		lan_rates_enabled = COConfigurationManager.getBooleanParameter( "LAN Speed Enabled" );
+	    	}
+	    	
+	    	lan_up_limit		= importInt( map, "lul" );
+	    	lan_down_limit		= importInt( map, "ldl" );
+
+	    	
+	    	List<Map<String,Object>>	d_list = (List<Map<String,Object>>)map.get( "dms" );
+	    	
+	    	if ( d_list != null ){
+	    		
+	    		for ( Map<String,Object> m: d_list ){
+	    			
+	    			String	k = importString( m, "k" );
+	    			
+	    			if ( k != null ){
+	    				
+	    				int	ul = importInt( m, "u" );
+	    				int	dl = importInt( m, "d" );
+	    				
+	    				download_limits.put( k, new int[]{ ul, dl });
+	    			}
+	    		}
+	    	}
+	    	
+	    	List<Map<String,Object>>	c_list = (List<Map<String,Object>>)map.get( "cts" );
+	    	
+	    	if ( c_list != null ){
+	    		
+	    		for ( Map<String,Object> m: c_list ){
+	    			
+	    			String	k = importString( m, "k" );
+	    			
+	    			if ( k != null ){
+	    				
+	    				int	ul = importInt( m, "u" );
+	    				int	dl = importInt( m, "d" );
+	    				
+	    				category_limits.put( k, new int[]{ ul, dl });
+	    			}
+	    		}
+	    	}
+	    }
+	    
+	    private Map<String,Object>
+	    export()
+	    {
+	    	Map<String,Object>	map = new HashMap<String, Object>();
+	    	
+	    	exportBoolean( map, "aue", auto_up_enabled );
+	    	exportBoolean( map, "ause", auto_up_seeding_enabled );
+	    	exportBoolean( map, "sle", seeding_limits_enabled );
+	    	
+	    	exportInt( map, "ul", up_limit );
+	    	exportInt( map, "usl", up_seeding_limit );
+	    	exportInt( map, "dl", down_limit );
+	    	
+	    	exportBoolean( map, "lre", lan_rates_enabled );
+	    	exportInt( map, "lul", lan_up_limit );
+	    	exportInt( map, "ldl", lan_down_limit );
+
+	    	
+	    	List<Map<String,Object>>	d_list = new ArrayList<Map<String,Object>>();
+	    	
+	    	map.put( "dms", d_list );
+	    	
+	    	for ( Map.Entry<String,int[]> entry: download_limits.entrySet()){
+	    		
+	    		Map<String,Object> m = new HashMap<String,Object>();
+	    		
+	    		d_list.add( m );
+	    		
+	    		exportString( m, "k", entry.getKey());
+	    		exportInt( m, "u", entry.getValue()[0]);
+	    		exportInt( m, "d", entry.getValue()[1]);
+	    	}
+	    	
+	    	List<Map<String,Object>>	c_list = new ArrayList<Map<String,Object>>();
+	    	
+	    	map.put( "cts", c_list );
+	    	
+	    	for ( Map.Entry<String,int[]> entry: category_limits.entrySet()){
+	    		
+	    		Map<String,Object> m = new HashMap<String,Object>();
+	    		
+	    		c_list.add( m );
+	    		
+	    		exportString( m, "k", entry.getKey());
+	    		exportInt( m, "u", entry.getValue()[0]);
+	    		exportInt( m, "d", entry.getValue()[1]);
+	    	}
+	    	
+	    	return( map );
+	    }
+	    
+	    private void
+	    loadForReset()
+	    {
+	    		// just maintain the auto upload setting over a reset
+	    	
+		    auto_up_enabled 		= COConfigurationManager.getBooleanParameter( TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY );
+	    }
+	    
+	    private void
+	    loadCurrent()
+	    {
+		    auto_up_enabled 		= COConfigurationManager.getBooleanParameter( TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY );
+		    auto_up_seeding_enabled = COConfigurationManager.getBooleanParameter( TransferSpeedValidator.AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY );
+		    seeding_limits_enabled 	= COConfigurationManager.getBooleanParameter( TransferSpeedValidator.UPLOAD_SEEDING_ENABLED_CONFIGKEY );
+		    up_limit 				= COConfigurationManager.getIntParameter( TransferSpeedValidator.UPLOAD_CONFIGKEY );
+		    up_seeding_limit 		= COConfigurationManager.getIntParameter( TransferSpeedValidator.UPLOAD_SEEDING_CONFIGKEY );
+		    down_limit				= COConfigurationManager.getIntParameter( TransferSpeedValidator.DOWNLOAD_CONFIGKEY );
+		
+		    lan_rates_enabled 		= COConfigurationManager.getBooleanParameter( "LAN Speed Enabled" );
+		    lan_up_limit 			= COConfigurationManager.getIntParameter( "Max LAN Upload Speed KBs" );
+		    lan_down_limit 			= COConfigurationManager.getIntParameter( "Max LAN Download Speed KBs" );
+	    
+		    download_limits.clear();
+		    
+			GlobalManager gm = core.getGlobalManager();
+
+			List<DownloadManager>	downloads = gm.getDownloadManagers();
+			
+			for ( DownloadManager download: downloads ){
+				
+				TOTorrent torrent = download.getTorrent();
+				
+				byte[]	hash = null;
+				
+				if ( torrent!= null ){
+					
+					try{
+						hash = torrent.getHash();
+						
+					}catch( Throwable e ){
+						
+					}
+				}
+				
+				if ( hash != null ){
+					int	download_up_limit 	= download.getStats().getUploadRateLimitBytesPerSecond();
+					int	download_down_limit = download.getStats().getDownloadRateLimitBytesPerSecond();
+					
+			    	if ( download_up_limit > 0 || download_down_limit > 0 ){
+			    		
+			    		download_limits.put( Base32.encode( hash ), new int[]{ download_up_limit, download_down_limit });
+			    	}
+				}
+			}
+		    
+			Category[] categories = CategoryManager.getCategories();
+		 
+			category_limits.clear();
+			
+		    for ( Category category: categories ){
+		    	
+		    	int	cat_up_limit	 	= category.getUploadSpeed();
+		    	int	cat_down_limit 		= category.getDownloadSpeed();
+		    	
+		    	if ( cat_up_limit > 0 || cat_down_limit > 0 ){
+		    	
+		    		category_limits.put( category.getName(), new int[]{ cat_up_limit, cat_down_limit });
+		    	}
+		    }
+	    }
+	    
+	    private int[]
+	    getLimitsForDownload(
+	    	String	hash )
+	    {
+	    	return( download_limits.get( hash ));
+	    }
+	    
+	    private void
+	    addRemoveDownloads(
+	    	List<String>		hashes,
+	    	boolean				add )
+	    {
+			GlobalManager gm = core.getGlobalManager();
+
+	    	for ( String hash: hashes ){
+	    		
+	    		if ( add ){
+
+	   				DownloadManager download = gm.getDownloadManager( new HashWrapper( Base32.decode( hash )));
+	    			
+	    			if ( download != null ){
+	    						
+						int	download_up_limit 	= download.getStats().getUploadRateLimitBytesPerSecond();
+						int	download_down_limit = download.getStats().getDownloadRateLimitBytesPerSecond();
+						
+				    	if ( download_up_limit > 0 || download_down_limit > 0 ){
+				    		
+				    		download_limits.put(hash, new int[]{ download_up_limit, download_down_limit });
+				    	}
+	    			}
+	    		}else{
+	    			
+	    			download_limits.remove( hash );
+	    		}
+	    	}
+	    }
+	    
+	    private void
+	    apply()
+	    {			    		
+	    		// don't manage this properly because the speedmanager has a 'memory' of 
+    			// the last upload limit in force before it became active and we're
+    			// not persisting this... rare use case methinks anyway
+
+    		COConfigurationManager.setParameter( TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY, auto_up_enabled );
+	    	COConfigurationManager.setParameter( TransferSpeedValidator.AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY, auto_up_seeding_enabled );
+
+    		if ( !( auto_up_enabled || auto_up_seeding_enabled )){
+      				
+ 		     	COConfigurationManager.setParameter( TransferSpeedValidator.UPLOAD_CONFIGKEY, up_limit );
+    		}
+    		
+		    COConfigurationManager.setParameter( TransferSpeedValidator.UPLOAD_SEEDING_ENABLED_CONFIGKEY, seeding_limits_enabled );
+		    COConfigurationManager.setParameter( TransferSpeedValidator.UPLOAD_SEEDING_CONFIGKEY, up_seeding_limit );
+
+		    COConfigurationManager.setParameter( TransferSpeedValidator.DOWNLOAD_CONFIGKEY, down_limit );
+
+		    COConfigurationManager.setParameter( "LAN Speed Enabled", lan_rates_enabled );
+		    COConfigurationManager.setParameter( "Max LAN Upload Speed KBs", lan_up_limit );
+		    COConfigurationManager.setParameter( "Max LAN Download Speed KBs", lan_down_limit );
+		    	    
+			GlobalManager gm = core.getGlobalManager();
+
+			Set<DownloadManager>	all_managers = new HashSet<DownloadManager>( gm.getDownloadManagers());
+			
+			for ( Map.Entry<String,int[]> entry: download_limits.entrySet()){
+				
+				byte[] hash = Base32.decode( entry.getKey());
+				
+				DownloadManager dm = gm.getDownloadManager( new HashWrapper( hash ));
+			
+				if ( dm != null ){
+						
+					int[]	limits = entry.getValue();
+					
+					dm.getStats().setUploadRateLimitBytesPerSecond( limits[0] );
+					dm.getStats().setDownloadRateLimitBytesPerSecond( limits[1] );
+					
+					all_managers.remove( dm );
+				}
+			}
+
+			for ( DownloadManager dm: all_managers ){
+				
+				dm.getStats().setUploadRateLimitBytesPerSecond( 0 );
+				dm.getStats().setDownloadRateLimitBytesPerSecond( 0 );
+			}
+			
+			Set<Category> all_categories = new HashSet<Category>( Arrays.asList(CategoryManager.getCategories()));
+			 
+			Map<String, Category> cat_map = new HashMap<String, Category>();
+			
+			for ( Category c: all_categories ){
+				
+				cat_map.put( c.getName(), c );
+			}
+								
+			for ( Map.Entry<String,int[]> entry: category_limits.entrySet()){
+		    	
+		    	String cat_name = entry.getKey();
+		    	
+		    	Category category = cat_map.get( cat_name );
+		    	
+		    	if ( category != null ){
+		    		
+		    		int[]	limits = entry.getValue();
+		    		
+		    		category.setUploadSpeed( limits[0] );
+		    		category.setDownloadSpeed( limits[1] );
+		    		
+		    		all_categories.remove( category );
+		    	}
+			}
+			
+			for ( Category category: all_categories ){
+				
+	    		category.setUploadSpeed( 0 );
+	    		category.setDownloadSpeed( 0 );
+			}
+	    }
+	    
+	    private List<String>
+	    getString(
+	    	boolean	is_current )
+	    {
+			List<String> result = new ArrayList<String>();
+			
+			result.add( "Global Limits" );
+				    	    
+		    if ( auto_up_enabled ){
+		    	
+			    result.add( "    Auto upload limit enabled" );
+			    
+		    }else if ( auto_up_seeding_enabled ){
+		    				    	
+		    	result.add( "    Auto upload seeding limit enabled" );
+
+		    }else{
+		    	
+		    	result.add( "    " + formatUp( up_limit*1024 ));
+
+	    		if ( seeding_limits_enabled ){
+
+	    			result.add( "    Seeding only limit enabled" );
+		    		
+		    		result.add( "    Seeding only: " + format( up_seeding_limit*1024 ));
+		    	}
+		    }
+		    
+		    result.add( "    " + formatDown( down_limit*1024 ));
+
+		    if ( lan_rates_enabled ){
+		    	
+		    	result.add( "" );
+			    result.add( "    LAN limits enabled" );
+		    	result.add( "        " + formatUp( lan_up_limit*1024 ));
+		    	result.add( "        " + formatDown( lan_down_limit*1024 ));
+		    }
+		    
+		    result.add( "" );
+		    
+		    result.add( "Download Limits" );
+		    
+		    int	total_download_limits = 0;
+		    int	total_download_limits_up 	= 0;
+		    int	total_download_limits_down 	= 0;
+		    
+			GlobalManager gm = core.getGlobalManager();
+			
+			for ( Map.Entry<String,int[]> entry: download_limits.entrySet()){
+				
+				byte[] hash = Base32.decode( entry.getKey());
+				
+				DownloadManager dm = gm.getDownloadManager( new HashWrapper( hash ));
+			
+				if ( dm != null ){
+						
+					int[]	limits = entry.getValue();
+					
+		    		total_download_limits++;
+		    		
+		    		int	up 		= limits[0];
+		    		int	down 	= limits[1];
+		    		
+		    		total_download_limits_up 	+= up;
+		    		total_download_limits_down 	+= down;
+		    		
+		    		result.add( "    " + dm.getDisplayName() + ": " + formatUp( up ) + ", " + formatDown( down ));
+		    	}
+			}
+			
+		    if ( total_download_limits == 0 ){
+		    	
+		    	result.add( "    None" );
+		    	
+		    }else{
+		    	
+		    	result.add( "    ----" );
+		    	
+		    	result.add( "    Total=" + total_download_limits + " - Compounded limits: " + formatUp( total_download_limits_up ) + ", " + formatDown( total_download_limits_down ));
+		    }
+		    
+			Category[] categories = CategoryManager.getCategories();
+		 
+			Map<String, Category> cat_map = new HashMap<String, Category>();
+			
+			for ( Category c: categories ){
+				
+				cat_map.put( c.getName(), c );
+			}
+			
+		    result.add( "" );
+
+			result.add( "Category Limits" );
+			
+			int	total_cat_limits = 0;
+		    int	total_cat_limits_up 	= 0;
+		    int	total_cat_limits_down 	= 0;
+
+			for ( Map.Entry<String,int[]> entry: category_limits.entrySet()){
+		    	
+		    	String cat_name = entry.getKey();
+		    	
+		    	Category category = cat_map.get( cat_name );
+		    	
+		    	if ( category != null ){
+		    		
+		    		if ( category.getType() == Category.TYPE_UNCATEGORIZED ){
+		    			
+		    			cat_name = "Uncategorised";
+		    		}
+		    		
+					int[]	limits = entry.getValue();
+					
+		    		total_cat_limits++;
+
+		    		int	up 		= limits[0];
+		    		int	down 	= limits[1];
+		    		
+		    		total_cat_limits_up 	+= up;
+		    		total_cat_limits_down 	+= down;
+		    		
+		    		result.add( "    " + cat_name + ": " + formatUp( up ) + ", " + formatDown( down ));
+		    	}
+		    }
+		    
+		    if ( total_cat_limits == 0 ){
+		    	
+		    	result.add( "    None" );
+		    	
+		    }else{
+		    	
+		    	result.add( "    ----" );
+		    	
+		    	result.add( "    Total=" + total_cat_limits + " - Compounded limits: " + formatUp( total_cat_limits_up ) + ", " + formatDown( total_cat_limits_down ));
+
+		    }
+		    
+		    if ( is_current ){
+		    	
+				Map<LimitedRateGroup,List<Object>> plugin_limiters = new HashMap<LimitedRateGroup, List<Object>>();
+	
+				List<DownloadManager> dms = gm.getDownloadManagers();
+				
+				for ( DownloadManager dm: dms ){
+	    		
+					for ( boolean upload: new Boolean[]{ true, false }){
+						
+						List<LimitedRateGroup> limiters = trim( dm.getRateLimiters( upload ));
+						
+						for ( LimitedRateGroup g: limiters ){
+							
+							List<Object> entries = plugin_limiters.get( g );
+							
+							if ( entries == null ){
+								
+								entries = new ArrayList<Object>();
+								
+								plugin_limiters.put( g, entries );
+								
+								entries.add( upload );
+								entries.add( new int[]{ 0 });
+							}
+							
+							entries.add( dm );
+						}
+					}
+					
+		    		PEPeerManager pm = dm.getPeerManager();
+		    		
+		    		if ( pm != null ){
+		    			
+		    			List<PEPeer> peers = pm.getPeers();
+		    			
+		    			for ( PEPeer peer: peers ){
+		    				
+		    				for ( boolean upload: new Boolean[]{ true, false }){
+		    					
+		    					List<LimitedRateGroup> limiters = trim( peer.getRateLimiters( upload ));
+		    					
+		    					for ( LimitedRateGroup g: limiters ){
+		    						
+		    						List<Object> entries = plugin_limiters.get( g );
+		    						
+		    						if ( entries == null ){
+		    							
+		    							entries = new ArrayList<Object>();
+		    							
+		    							plugin_limiters.put( g, entries );
+		    							
+		    							entries.add( upload );
+		    								
+		    							entries.add( new int[]{ 1 });
+		    							
+		    						}else{
+		    								
+		    							((int[])entries.get(1))[0]++;
+		    						}
+		    					}
+		    				}
+		    			}
+		    		}
+	    		}
+	
+			    result.add( "" );
+	
+				result.add( "Plugin Limits" );
+	
+			    if ( plugin_limiters.size() == 0 ){
+			    	
+			    	result.add( "    None" );
+			    	
+			    }else{
+			    	
+			    	List<String>	plugin_lines = new ArrayList<String>();
+			    	
+			    	for ( Map.Entry<LimitedRateGroup,List<Object>> entry: plugin_limiters.entrySet()){
+			    		
+			    		LimitedRateGroup group = entry.getKey();
+			    		
+			    		List<Object> list = entry.getValue();
+			    		
+			    		boolean is_upload 	= (Boolean)list.get(0);
+			    		int		peers		= ((int[])list.get(1))[0];
+			    		
+			    		String line = "    " + group.getName() + ": " + (is_upload?formatUp( group.getRateLimitBytesPerSecond()):formatDown( group.getRateLimitBytesPerSecond()));
+			    	
+			    		if ( peers > 0 ){
+			    			
+			    			line += ", peers=" + peers;
+			    		}
+			    		
+			    		if ( list.size() > 2 ){
+			    			
+			    			line += ", downloads=" + (list.size()-2);
+			    		}
+			    		
+			    		plugin_lines.add( line );
+			    	}
+			    	
+			    	Collections.sort( plugin_lines );
+			    	
+			    	result.addAll( plugin_lines );
+			    }
+		    }
+		    
+			return( result );
+	    }
+	}
+	
+	private class
+	ScheduleRule
+	{
+		private static final byte	FR_MON		= 0x01;
+		private static final byte	FR_TUE		= 0x02;
+		private static final byte	FR_WED		= 0x04;
+		private static final byte	FR_THU		= 0x08;
+		private static final byte	FR_FRI		= 0x10;
+		private static final byte	FR_SAT		= 0x20;
+		private static final byte	FR_SUN		= 0x40;
+		private static final byte	FR_OVERFLOW	= (byte)0x80;
+		private static final byte	FR_WEEKDAY	= ( FR_MON | FR_TUE | FR_WED | FR_THU | FR_FRI );
+		private static final byte	FR_WEEKEND	= ( FR_SAT | FR_SUN );
+		private static final byte	FR_DAILY	= ( FR_WEEKDAY | FR_WEEKEND );
+		
+		private String	profile_name;
+		private byte	frequency;
+		private int		from_mins;
+		private int		to_mins;
+		
+		private 
+		ScheduleRule(
+			byte			_freq,
+			String			_profile,
+			int				_from,
+			int				_to )
+		{
+			frequency 		= _freq;
+			profile_name	= _profile;
+			from_mins		= _from;
+			to_mins			= _to;
+		}
+		
+		private List<ScheduleRule>
+		splitByDay()
+		{
+			List<ScheduleRule>	result = new ArrayList<ScheduleRule>();
+			
+			if ( to_mins > from_mins ){
+			
+				result.add( this );
+				
+			}else{
+				
+					// handle rules that wrap across days. e.g. 23:00 to 00:00
+				
+				byte next_frequency = (byte)(frequency << 1 );
+				
+				if ((next_frequency & FR_OVERFLOW ) != 0 ){
+					
+					next_frequency &= ~FR_OVERFLOW;
+					
+					next_frequency |= FR_MON;
+				}
+				
+				ScheduleRule	rule1 = new ScheduleRule( frequency, profile_name, from_mins, 23*60+59 );
+				ScheduleRule	rule2 = new ScheduleRule( next_frequency, profile_name, 0, to_mins );
+
+				result.add( rule1 );
+				result.add( rule2 );
+			}
+			
+			return( result );
+		}
+		
+		private boolean
+		sameAs(
+			ScheduleRule	other )
+		{
+			if ( other == null ){
+				
+				return( false );
+			}
+			
+			return( frequency == other.frequency &&
+					profile_name.equals( other.profile_name ) &&
+					from_mins == other.from_mins &&
+					to_mins == other.to_mins );
+		}
+		
+		public String
+		getString()
+		{
+			String	freq_str = "";
+			
+			if ( frequency == FR_DAILY ){
+				
+				freq_str = "daily";
+				
+			}else if ( frequency == FR_WEEKDAY ){
+				
+				freq_str = "weekdays";
+				
+			}else if ( frequency == FR_WEEKEND ){
+				
+				freq_str = "weekends";
+				
+			}else if ( frequency == FR_MON ){
+				
+				freq_str = "mon";
+				
+			}else if ( frequency == FR_TUE ){
+				
+				freq_str = "tue";
+				
+			}else if ( frequency == FR_WED ){
+				
+				freq_str = "wed";
+				
+			}else if ( frequency == FR_THU ){
+				
+				freq_str = "thu";
+				
+			}else if ( frequency == FR_FRI ){
+				
+				freq_str = "fri";
+				
+			}else if ( frequency == FR_SAT ){
+				
+				freq_str = "sat";
+				
+			}else if ( frequency == FR_SUN ){
+				
+				freq_str = "sun";
+			}
+			
+			return( "profile=" + profile_name + ", frequency=" + freq_str + ", from=" + getTime( from_mins ) + ", to=" + getTime( to_mins ));
+		}
+		
+		private String
+		getTime(
+			int	mins )
+		{
+			String str = getTimeBit( mins/60 ) + ":" + getTimeBit( mins % 60 );
+		
+			return( str );
+		}
+		
+		private String
+		getTimeBit(
+			int	num )
+		{
+			String str = String.valueOf( num );
+			
+			if ( str.length() < 2 ){
+				
+				str = "0" + str;
+			}
+			
+			return( str );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/speedmanager/SpeedManagerLimitEstimate.java b/com/aelitis/azureus/core/speedmanager/SpeedManagerLimitEstimate.java
index 4920dc4..2d7351e 100644
--- a/com/aelitis/azureus/core/speedmanager/SpeedManagerLimitEstimate.java
+++ b/com/aelitis/azureus/core/speedmanager/SpeedManagerLimitEstimate.java
@@ -58,6 +58,9 @@ SpeedManagerLimitEstimate
 	public int[][]
 	getSegments();
 	
+	public long
+	getWhen();
+	
 	public String
 	getString();
 }
diff --git a/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerImpl.java b/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerImpl.java
index b25e3e9..f19b4ef 100644
--- a/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerImpl.java
+++ b/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerImpl.java
@@ -68,7 +68,7 @@ public class
 SpeedManagerImpl 
 	implements SpeedManager, SpeedManagerAlgorithmProviderAdapter, AEDiagnosticsEvidenceGenerator
 {
-	protected static final int UPDATE_PERIOD_MILLIS	= 5000;
+	protected static final int UPDATE_PERIOD_MILLIS	= 3000;
 
 	private static final int CONTACT_NUMBER		= 3;
 	private static final int CONTACT_PING_SECS	= UPDATE_PERIOD_MILLIS/1000;
@@ -88,6 +88,9 @@ SpeedManagerImpl
 
 	private static final int SAVE_PERIOD_SECS	= 15*60;
 	private static final int SAVE_PERIOD_TICKS 	= SAVE_PERIOD_SECS / CONTACT_PING_SECS;
+	
+	private static final int AUTO_ADJUST_PERIOD_SECS	= 60;
+	private static final int AUTO_ADJUST_PERIOD_TICKS 	= AUTO_ADJUST_PERIOD_SECS / CONTACT_PING_SECS;
 
 	private static final int SPEED_AVERAGE_PERIOD	= 3000;
 	
@@ -135,6 +138,8 @@ SpeedManagerImpl
 	private	int							provider_version	= -1;
 	private boolean						enabled;
 
+	private final boolean				pm_enabled = true;
+	
     private Map							contacts	= new HashMap();
 	private volatile int				total_contacts;
 	private pingContact[]				contacts_array	= new pingContact[0];
@@ -287,7 +292,7 @@ SpeedManagerImpl
 						// if enabled the ping stream drives the stats update for the ping mappers
 						// When not enabled we do it here instead
 					
-					if ( !enabled || contacts_array.length == 0 ){
+					if ( !pm_enabled || contacts_array.length == 0 ){
 											
 						int	x	= (adapter.getCurrentDataUploadSpeed(SPEED_AVERAGE_PERIOD) + adapter.getCurrentProtocolUploadSpeed(SPEED_AVERAGE_PERIOD));
 						int	y 	= (adapter.getCurrentDataDownloadSpeed(SPEED_AVERAGE_PERIOD) + adapter.getCurrentProtocolDownloadSpeed(SPEED_AVERAGE_PERIOD));
@@ -304,6 +309,23 @@ SpeedManagerImpl
 						
 						ping_mapper.saveHistory();
 					}
+					
+					if ( tick_count % AUTO_ADJUST_PERIOD_TICKS == 0 ){
+						
+						autoAdjust();
+					}
+				}
+			});
+		
+		COConfigurationManager.addAndFireParameterListener(
+			"Auto Adjust Transfer Defaults",
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String name )
+				{
+					autoAdjust();
 				}
 			});
 		
@@ -528,7 +550,7 @@ SpeedManagerImpl
 						DHTSpeedTesterContact[]	st_contacts,
 						int[]					round_trip_times )
 					{
-						if ( !enabled ){
+						if ( !pm_enabled ){
 							
 							for (int i=0;i<st_contacts.length;i++){
 								
@@ -640,6 +662,11 @@ SpeedManagerImpl
 					}
 				});
 		
+		if ( pm_enabled ){
+			
+			speed_tester.setContactNumber( CONTACT_NUMBER );
+		}
+		
 		SimpleTimer.addPeriodicEvent(
 			"SpeedManager:stats",
 			SpeedManagerAlgorithmProvider.UPDATE_PERIOD_MILLIS,
@@ -741,7 +768,7 @@ SpeedManagerImpl
 			
 			enabled	= _enabled;
 			
-			if ( speed_tester != null ){
+			if ( speed_tester != null && !pm_enabled ){
 				
 				speed_tester.setContactNumber( enabled?CONTACT_NUMBER:0);
 			}
@@ -880,6 +907,83 @@ SpeedManagerImpl
         return( adapter.getCurrentProtocolDownloadSpeed(-1) );
     }
 
+    private void
+    autoAdjust()
+    {
+    	if ( COConfigurationManager.getBooleanParameter( "Auto Adjust Transfer Defaults" )){
+    		
+       		int	up_limit_bytes_per_sec 		= getEstimatedUploadCapacityBytesPerSec().getBytesPerSec();
+       		int	down_limit_bytes_per_sec 	= getEstimatedDownloadCapacityBytesPerSec().getBytesPerSec();
+    		       		
+       		int up_kbs = up_limit_bytes_per_sec/1024;
+       		
+        		
+       		final int[][] settings = {
+       				
+       				{ 56, 		2, 		20, 	40  },		// 56 k/bit
+       				{ 96, 		3, 		30, 	60 },
+       				{ 128, 		3, 		40, 	80 },
+       				{ 192, 		4, 		50, 	100 },		// currently we don't go lower than this
+       				{ 256, 		4, 		60, 	200 },
+       				{ 512, 		5, 		70, 	300 },
+       				{ 1024,		6, 		80, 	400 },		// 1Mbit
+       				{ 2*1024,	8, 		90, 	500 },
+       				{ 5*1024,	10, 	100, 	600 },
+      				{ 10*1024,	20,		110, 	750 },		// 10Mbit
+      				{ 20*1024,	30, 	120, 	900 },
+      				{ 50*1024,	40, 	130, 	1100 },
+      				{ 100*1024,	50, 	140, 	1300 },
+      				{ -1, 		60, 	150, 	1500 },
+       		};
+       		
+       		int[] selected = settings[ settings.length-1 ];
+       		
+       			// note, we start from 3 to avoid over-restricting things when we don't have
+       			// a reasonable speed estimate
+       		
+       		for ( int i=3;i<settings.length;i++ ){
+       		
+       			int[]	setting = settings[i];
+       			
+       			int	line_kilobit_sec = setting[0];
+       			
+       				// convert to upload kbyte/sec assuming 80% achieved
+       			
+       			int	limit = (line_kilobit_sec/8)*4/5;
+       			
+       			if ( up_kbs <= limit ){
+       				
+       				selected = setting;
+       				
+       				break;
+       			}
+       		}
+       		
+      		int	upload_slots			= selected[1];
+       		int	connections_torrent		= selected[2];
+       		int connections_global		= selected[3];
+
+       		
+      		if ( upload_slots != COConfigurationManager.getIntParameter( "Max Uploads" )){
+       			
+      			COConfigurationManager.setParameter( "Max Uploads", upload_slots );
+      			COConfigurationManager.setParameter( "Max Uploads Seeding", upload_slots );
+       		}
+       		
+      		if ( connections_torrent != COConfigurationManager.getIntParameter( "Max.Peer.Connections.Per.Torrent" )){
+       			
+    			COConfigurationManager.setParameter( "Max.Peer.Connections.Per.Torrent", connections_torrent );
+    			
+    			COConfigurationManager.setParameter( "Max.Peer.Connections.Per.Torrent.When.Seeding", connections_torrent / 2 );
+       		}
+       		
+      		if ( connections_global != COConfigurationManager.getIntParameter( "Max.Peer.Connections.Total" )){
+       			
+       			COConfigurationManager.setParameter( "Max.Peer.Connections.Total", connections_global );
+       		}
+    	}
+    }
+    
 	public void
 	setLoggingEnabled(
 		boolean	enabled )
diff --git a/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerPingMapperImpl.java b/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerPingMapperImpl.java
index d59d363..9d383ac 100644
--- a/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerPingMapperImpl.java
+++ b/com/aelitis/azureus/core/speedmanager/impl/SpeedManagerPingMapperImpl.java
@@ -1724,7 +1724,7 @@ SpeedManagerPingMapperImpl
 			return( hits );
 		}
 		
-		protected long
+		public long
 		getWhen()
 		{
 			return( when );
diff --git a/com/aelitis/azureus/core/speedmanager/impl/v2/PingSpaceMon.java b/com/aelitis/azureus/core/speedmanager/impl/v2/PingSpaceMon.java
index 1184b7e..3f35874 100644
--- a/com/aelitis/azureus/core/speedmanager/impl/v2/PingSpaceMon.java
+++ b/com/aelitis/azureus/core/speedmanager/impl/v2/PingSpaceMon.java
@@ -223,6 +223,7 @@ public class PingSpaceMon
             return new int[0][];
         }
 
+        public long getWhen(){ return(0);}
         public String getString() {
             return "default";
         }
diff --git a/com/aelitis/azureus/core/speedmanager/impl/v2/SMConfigurationAdapterImpl.java b/com/aelitis/azureus/core/speedmanager/impl/v2/SMConfigurationAdapterImpl.java
index a611cf8..3f83947 100644
--- a/com/aelitis/azureus/core/speedmanager/impl/v2/SMConfigurationAdapterImpl.java
+++ b/com/aelitis/azureus/core/speedmanager/impl/v2/SMConfigurationAdapterImpl.java
@@ -109,6 +109,9 @@ public class SMConfigurationAdapterImpl implements SMConfigurationAdapter
             return new int[0][];
         }
 
+        public long getWhen() {
+        	return 0;
+        }
         /**
          *
          * @return
diff --git a/com/aelitis/azureus/core/speedmanager/impl/v2/SMConst.java b/com/aelitis/azureus/core/speedmanager/impl/v2/SMConst.java
index f104aad..4b31d0f 100644
--- a/com/aelitis/azureus/core/speedmanager/impl/v2/SMConst.java
+++ b/com/aelitis/azureus/core/speedmanager/impl/v2/SMConst.java
@@ -90,6 +90,7 @@ public class SMConst
         return new FilteredLimitEstimate(estBytesPerSec,
                                         estimate.getEstimateType(),
                                         estimate.getMetricRating(),
+                                        estimate.getWhen(),
                                         estimate.getString() );
 
     }//filterDownEstimate
@@ -111,12 +112,14 @@ public class SMConst
         int bytesPerSec;
         float type;
         float metric;
+        long when;
         String name;
 
-        public FilteredLimitEstimate(int _bytesPerSec, float _type, float _metric, String _name){
+        public FilteredLimitEstimate(int _bytesPerSec, float _type, float _metric, long _when, String _name){
             bytesPerSec = _bytesPerSec;
             type = _type;
             metric = _metric;
+            when	= _when;
             name = _name;
         }
 
@@ -134,7 +137,9 @@ public class SMConst
         public int[][] getSegments() {
             return new int[0][];
         }
-
+        public long getWhen() {
+        	return when;
+        }
         public String getString() {
             return name;
         }
diff --git a/com/aelitis/azureus/core/subs/Subscription.java b/com/aelitis/azureus/core/subs/Subscription.java
index 59e7c87..a179916 100644
--- a/com/aelitis/azureus/core/subs/Subscription.java
+++ b/com/aelitis/azureus/core/subs/Subscription.java
@@ -53,6 +53,9 @@ Subscription
 	public int
 	getVersion();
 
+	public long
+	getAddTime();
+	
 	public int
 	getHighestVersion();
 	
@@ -80,6 +83,9 @@ Subscription
 	public boolean
 	isShareable();
 	
+	public boolean
+	isSearchTemplate();
+	
 	public String
 	getJSON()
 	
diff --git a/com/aelitis/azureus/core/subs/SubscriptionManager.java b/com/aelitis/azureus/core/subs/SubscriptionManager.java
index 88ebe49..f795c9d 100644
--- a/com/aelitis/azureus/core/subs/SubscriptionManager.java
+++ b/com/aelitis/azureus/core/subs/SubscriptionManager.java
@@ -58,6 +58,13 @@ SubscriptionManager
 	
 		throws SubscriptionException;
 	
+	public int
+	getKnownSubscriptionCount();
+	
+	public int
+	getSubscriptionCount(
+		boolean	subscribed_only );
+	
 	public Subscription[]
 	getSubscriptions();
 	
@@ -136,6 +143,23 @@ SubscriptionManager
 	setRSSPublishEnabled(
 		boolean		enabled );
 	
+	public boolean
+	isSearchEnabled();
+	
+	public void
+	setSearchEnabled(
+		boolean		enabled );
+	
+	public boolean
+	isSubsDownloadEnabled();
+	
+	public void
+	setSubsDownloadEnabled(
+		boolean		enabled );
+	
+	public boolean
+	hideSearchTemplates();
+	
 	public String
 	getRSSLink();
 	
diff --git a/com/aelitis/azureus/core/subs/SubscriptionUtils.java b/com/aelitis/azureus/core/subs/SubscriptionUtils.java
index 3863392..6ba5ca0 100644
--- a/com/aelitis/azureus/core/subs/SubscriptionUtils.java
+++ b/com/aelitis/azureus/core/subs/SubscriptionUtils.java
@@ -35,15 +35,15 @@ SubscriptionUtils
 	public static SubscriptionDownloadDetails[]
 	getAllCachedDownloadDetails(AzureusCore core)
 	{
-		List 	dms 	= core.getGlobalManager().getDownloadManagers();
+		List<DownloadManager> 	dms 	= core.getGlobalManager().getDownloadManagers();
 		
-		List	result 	= new ArrayList();
+		List<SubscriptionDownloadDetails>	result 	= new ArrayList<SubscriptionDownloadDetails>();
 		
 		SubscriptionManager sub_man = SubscriptionManagerFactory.getSingleton();
 		
 		for (int i=0;i<dms.size();i++){
 			
-			DownloadManager	dm = (DownloadManager)dms.get(i);
+			DownloadManager	dm = dms.get(i);
 			
 			TOTorrent torrent = dm.getTorrent();
 			
@@ -54,14 +54,33 @@ SubscriptionUtils
 					
 					if ( subs != null && subs.length > 0 ){
 						
-						result.add( new SubscriptionDownloadDetails( dm, subs ));
+						if ( sub_man.hideSearchTemplates()){
+							
+							List<Subscription>	filtered = new ArrayList<Subscription>();
+							
+							for ( Subscription s: subs ){
+								
+								if ( !s.isSearchTemplate()){
+									
+									filtered.add( s );
+								}
+							}
+							
+							if ( filtered.size() > 0 ){
+							
+								result.add( new SubscriptionDownloadDetails( dm, filtered.toArray( new Subscription[filtered.size()] )));
+							}
+						}else{
+							
+							result.add( new SubscriptionDownloadDetails( dm, subs ));
+						}
 					}
 				}catch( Throwable e ){
 				}
 			}
 		}
 		
-		return((SubscriptionDownloadDetails[])result.toArray( new SubscriptionDownloadDetails[result.size()]));
+		return(result.toArray( new SubscriptionDownloadDetails[result.size()]));
 	}
 	
 
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
index 031ea27..009228d 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionHistoryImpl.java
@@ -372,8 +372,21 @@ SubscriptionHistoryImpl
 			
 				long	interval_min = ((Long)schedule.get( "interval" )).longValue();
 				
-				return( last_scan + interval_min*60*1000 );
+				if ( interval_min == Integer.MAX_VALUE || interval_min == Long.MAX_VALUE ){
+					
+					return( Long.MAX_VALUE );
+				}
 				
+				if ( last_scan == 0 ){
+					
+						// never scanned, scan immediately
+					
+					return( SystemTime.getCurrentTime());
+					
+				}else{
+				
+					return( last_scan + interval_min*60*1000 );
+				}
 			}catch( Throwable e ){
 				
 				log( "Failed to decode schedule " + schedule, e );
@@ -970,4 +983,10 @@ SubscriptionHistoryImpl
 	{
 		subs.log( "History: " + str, e );
 	}
+	
+	protected String
+	getString()
+	{
+		return( "unread=" + num_unread + ",read=" + num_read+ ",last_err=" + last_error );
+	}
 }
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
index 5d1d3df..38c47a0 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionImpl.java
@@ -119,7 +119,9 @@ SubscriptionImpl
 	private int				highest_prompted_version;
 	
 	private byte[]			short_id;
-	
+
+	private String			id;
+
 	private List			associations = new ArrayList();
 	
 	private int				fixed_random;
@@ -553,6 +555,7 @@ SubscriptionImpl
 	init()
 	{
 		short_id = SubscriptionBodyImpl.deriveShortID( public_key, singleton_details );
+		id = null;
 	}
 	
 	public boolean
@@ -574,6 +577,13 @@ SubscriptionImpl
 			return( false );
 		}
 	}
+	
+	public boolean
+	isSearchTemplate()
+	{
+		return( getName().startsWith( "Search Template:" ));
+	}
+	
 	protected Map
 	getSingletonDetails()
 	{
@@ -689,6 +699,12 @@ SubscriptionImpl
 		return( name_ex );
 	}
 	
+	public long
+	getAddTime()
+	{
+		return( add_time );
+	}
+	
 	public boolean
 	isPublic()
 	{
@@ -1085,7 +1101,10 @@ SubscriptionImpl
 	public String
 	getID()
 	{
-		return( Base32.encode(getShortID()));
+		if (id == null) {
+			id = Base32.encode(getShortID());
+		}
+		return( id );
 	}
 	
 	protected byte[]
@@ -1193,6 +1212,10 @@ SubscriptionImpl
 			if ( is_subscribed ){
 				
 				manager.setSelected( this );
+				
+			}else{
+				
+				reset();
 			}
 			
 			fireChanged();
@@ -1636,12 +1659,15 @@ SubscriptionImpl
 	{
 		Map	result = new HashMap();
 		
-		result.put( "h", hash );
 		result.put( "v", new Long( version ));
-		result.put( "z", new Long( sig_data_size ));
-		result.put( "s", sig );
 			
-		if ( singleton_details != null ){
+		if ( singleton_details == null ){
+			
+			result.put( "h", hash );
+			result.put( "z", new Long( sig_data_size ));
+			result.put( "s", sig );
+
+		}else{
 			
 			result.put( "x", singleton_details );
 		}
@@ -1905,6 +1931,7 @@ SubscriptionImpl
 					",pub=" + is_public +
 					",mine=" + isMine() +
 					",sub=" + is_subscribed +
+					(is_subscribed?(",hist={" + history.getString() + "}"):"") +
 					",pop=" + popularity + 
 					(server_publication_outstanding?",spo=true":""));
 	}
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
index 107ee4a..5a6efbd 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionManagerImpl.java
@@ -47,6 +47,11 @@ import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.UIManagerEvent;
 import org.gudy.azureus2.plugins.utils.DelayedTask;
 import org.gudy.azureus2.plugins.utils.StaticUtilities;
+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.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
 import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
@@ -65,8 +70,10 @@ import com.aelitis.azureus.core.metasearch.Engine;
 import com.aelitis.azureus.core.metasearch.MetaSearchListener;
 import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
 import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
+import com.aelitis.azureus.core.metasearch.impl.web.rss.RSSEngine;
 import com.aelitis.azureus.core.security.CryptoECCUtils;
 import com.aelitis.azureus.core.subs.*;
+import com.aelitis.azureus.core.subs.SubscriptionUtils.SubscriptionDownloadDetails;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.vuzefile.*;
@@ -75,6 +82,7 @@ import com.aelitis.azureus.plugins.magnet.MagnetPlugin;
 import com.aelitis.azureus.plugins.magnet.MagnetPluginProgressListener;
 import com.aelitis.azureus.util.ImportExportUtils;
 import com.aelitis.azureus.util.UrlFilter;
+import com.aelitis.net.magneturi.MagnetURIHandler;
 
 
 public class 
@@ -89,8 +97,16 @@ 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 final String	CONFIG_RSS_ENABLE			= "subscriptions.config.rss_enable";
 
+	private static final String	CONFIG_ENABLE_SEARCH			= "subscriptions.config.search_enable";
+	
+	private static final String	CONFIG_HIDE_SEARCH_TEMPLATES	= "subscriptions.config.hide_search_templates";
+	
+	private static final String	CONFIG_DL_SUBS_ENABLE		= "subscriptions.config.dl_subs_enable";
+
+	private static final int DELETE_UNUSED_AFTER_MILLIS = 2*7*24*60*60*1000;
+	
 	
 	private static SubscriptionManagerImpl		singleton;
 	private static boolean						pre_initialised;
@@ -201,16 +217,19 @@ SubscriptionManagerImpl
 	private static final Object	SP_LAST_ATTEMPTED	= new Object();
 	private static final Object	SP_CONSEC_FAIL		= new Object();
 	
+	private AzureusCore		azureus_core;
 	
 	private volatile DHTPlugin	dht_plugin;
 	
-	private List		subscriptions	= new ArrayList();
+	private List<SubscriptionImpl>		subscriptions	= new ArrayList<SubscriptionImpl>();
 	
 	private boolean	config_dirty;
 	
-	private static final int PUB_ASSOC_CONC_MAX	= 3;
+	private static final int PUB_ASSOC_CONC_MAX				= 3;
+	private static final int PUB_SLEEPING_ASSOC_CONC_MAX	= 1;
 	
 	private int		publish_associations_active;
+	private boolean	publish_next_asyc_pending;
 	
 	private boolean publish_subscription_active;
 	
@@ -222,12 +241,12 @@ SubscriptionManagerImpl
 	private boolean					periodic_lookup_in_progress;
 	private int						priority_lookup_pending;
 	
-	private CopyOnWriteList			listeners = new CopyOnWriteList();
+	private CopyOnWriteList<SubscriptionManagerListener>			listeners = new CopyOnWriteList<SubscriptionManagerListener>();
 	
 	private SubscriptionSchedulerImpl	scheduler;
 	
-	private List					potential_associations	= new ArrayList();
-	private Map						potential_associations2	= new HashMap();
+	private List<Object[]>				potential_associations	= new ArrayList<Object[]>();
+	private Map<HashWrapper,Object[]>	potential_associations2	= new HashMap<HashWrapper,Object[]>();
 	
 	private boolean					meta_search_listener_added;
 	
@@ -327,7 +346,7 @@ SubscriptionManagerImpl
 	initialise()
 	{
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
+			public void azureusCoreRunning(final AzureusCore core) {
 				initWithCore(core);
 			}
 		});
@@ -335,7 +354,7 @@ SubscriptionManagerImpl
 
 	protected void
 	initWithCore(
-		AzureusCore 	core )
+		AzureusCore 	_core )
 	{
 		synchronized( this ){
 			
@@ -347,6 +366,8 @@ SubscriptionManagerImpl
 			started	= true;
 		}
 
+		azureus_core = _core;
+		
 		final PluginInterface default_pi = PluginInitializer.getDefaultInterface();
 
 		rss_publisher = new SubscriptionRSSFeed( this, default_pi );
@@ -614,8 +635,508 @@ SubscriptionManagerImpl
 		
 			delayed_task.queue();
 		}
+		
+		if ( isSearchEnabled()){
+			
+			try{
+				default_pi.getUtilities().registerSearchProvider(
+					new SearchProvider()
+					{
+						private Map<Integer,Object>	properties = new HashMap<Integer, Object>();
+						
+						{
+							properties.put( PR_NAME, MessageText.getString( "ConfigView.section.Subscriptions" ));
+							
+							try{
+								URL url = 
+									MagnetURIHandler.getSingleton().registerResource(
+										new MagnetURIHandler.ResourceProvider()
+										{
+											public String
+											getUID()
+											{
+												return( SubscriptionManager.class.getName() + ".2" );
+											}
+											
+											public String
+											getFileType()
+											{
+												return( "png" );
+											}
+													
+											public byte[]
+											getData()
+											{
+												InputStream is = getClass().getClassLoader().getResourceAsStream( "com/aelitis/azureus/ui/images/subscription_icon_1616.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
+						{		
+							try{
+								return( searchSubscriptions( search_parameters, observer ));
+								
+							}catch( Throwable e ){
+								
+								throw( new SearchException( "Search failed", e ));
+							}
+						}
+						
+						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" );
+			}
+		}
 	}
 
+	public SearchInstance
+	searchSubscriptions(
+		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 ){
+		
+			try{
+				observer.complete();
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}else{
+		
+			new AEThread2( "Subscriptions:search", true )
+			{
+				public void
+				run()
+				{
+					final Set<String>	hashes = new HashSet<String>();
+					
+					searchMatcher	matcher = new searchMatcher( term );
+
+					try{				
+						List<SubscriptionResult>	matches = matchSubscriptionResults( matcher );
+							
+						for ( final SubscriptionResult result: matches ){
+							
+							final Map result_properties = result.toPropertyMap();
+							
+							byte[] hash = (byte[])result_properties.get( SearchResult.PR_HASH );
+														
+							if ( hash != null ){
+															
+								String hash_str = Base32.encode( hash );
+							
+								if ( hashes.contains( hash_str )){
+								
+									continue;
+								}
+							
+								hashes.add( hash_str );
+							}
+							
+							SearchResult search_result = 
+								new SearchResult()
+								{
+									public Object
+									getProperty(
+										int		property_name )
+									{
+										return( result_properties.get( property_name ));
+									}
+								};
+						
+							try{
+								observer.resultReceived( si, search_result );
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+												
+						Map<String,Object[]> template_matches = new HashMap<String, Object[]>();
+								
+						Engine[] engines = MetaSearchManagerFactory.getSingleton().getMetaSearch().getEngines( false, false );
+						
+						Map<Subscription,List<String>>	sub_dl_name_map = null;
+						
+						for ( Subscription sub: getSubscriptions( false )){
+							
+							if ( !sub.isSearchTemplate()){
+								
+								continue;
+							}
+							
+							String	sub_name = sub.getName();
+														
+							Engine sub_engine = sub.getEngine();
+							
+							if ( sub_engine.isActive() || !(sub_engine instanceof RSSEngine )){
+								
+								continue;
+							}
+							
+							int	pos = sub_name.indexOf( ":" );
+							
+							String t_name = sub_name.substring( pos+1 );
+							
+							pos	= t_name.indexOf( "(v" );
+							
+							int t_ver;
+							
+							if ( pos == -1 ){
+								
+								t_ver = 1;
+								
+							}else{
+								
+								String s = t_name.substring( pos+2, t_name.length()-1);
+								
+								t_name = t_name.substring( 0, pos );
+								
+								try{
+							
+									t_ver = Integer.parseInt(s);
+									
+								}catch( Throwable e ){
+									
+									t_ver = 1;
+								}
+							}
+							
+							t_name = t_name.trim();
+							
+							boolean skip = false;
+							
+							for ( Engine e: engines ){
+								
+								if ( e != sub_engine && e.sameLogicAs( sub_engine )){
+									
+									skip = true;
+									
+									break;
+								}
+								
+								if ( e.getName().equalsIgnoreCase( t_name )){
+									
+									if ( e.getVersion() >= t_ver ){
+										
+										skip = true;
+									}
+								}
+							}
+							
+							if ( skip ){
+								
+								continue;
+							}
+							
+							if ( sub_dl_name_map == null ){
+								
+								sub_dl_name_map = new HashMap<Subscription, List<String>>();
+								
+								SubscriptionDownloadDetails[] sdds = SubscriptionUtils.getAllCachedDownloadDetails( azureus_core );
+								
+								for ( SubscriptionDownloadDetails sdd: sdds ){
+									
+									String name = sdd.getDownload().getDisplayName();
+									
+									if ( matcher.matches( name )){
+										
+										Subscription[] x = sdd.getSubscriptions();
+										
+										for ( Subscription s: x ){
+											
+											List<String> g = sub_dl_name_map.get( s );
+											
+											if ( g == null ){
+												
+												g = new ArrayList<String>();
+												
+												sub_dl_name_map.put( s, g );
+											}
+											
+											g.add( name );
+										}
+									}
+								}
+							}
+							
+							List<String> names = sub_dl_name_map.get( sub );
+							
+							if ( names == null ){
+								
+								continue;
+							}
+													
+							String key = t_name.toLowerCase();
+							
+							Object[] entry = template_matches.get( key );
+							
+							if ( entry == null ){
+								
+								entry = new Object[]{ sub, t_ver };
+								
+								template_matches.put( key, entry );
+								
+							}else{
+								
+								if ( t_ver > (Integer)entry[1]){
+									
+									entry[0]	= sub;
+									entry[1]	= t_ver;
+								}
+							}
+						}
+						
+						List<Subscription>	interesting = new ArrayList<Subscription>();
+						
+						for ( Object[] entry: template_matches.values()){
+						
+							interesting.add((Subscription)entry[0]);
+						}
+						
+						Collections.sort(
+							interesting,
+							new Comparator<Subscription>()
+							{
+								public int 
+								compare(
+									Subscription o1,
+									Subscription o2) 
+								{
+									long res = o2.getCachedPopularity() - o1.getCachedPopularity();
+									
+									if ( res < 0 ){
+										return( -1 );
+									}else if ( res > 0 ){
+										return( 1 );
+									}else{
+										return( 0 );
+									}
+								}
+							});
+						
+						int	added = 0;
+						
+						for ( final Subscription sub: interesting ){
+								
+							if ( added >= 3 ){
+								
+								break;
+							}
+							
+							try{
+								String subs_url_str = ((RSSEngine)sub.getEngine()).getSearchUrl( true );
+								
+								URL subs_url = new URL( subs_url_str );
+								
+								final byte[] vf_bytes = FileUtil.readInputStreamAsByteArray(subs_url.openConnection().getInputStream());
+	
+								VuzeFile vf = VuzeFileHandler.getSingleton().loadVuzeFile( vf_bytes );
+								
+								if ( MetaSearchManagerFactory.getSingleton().isImportable( vf )){
+									
+									final URL url = 
+										MagnetURIHandler.getSingleton().registerResource(
+											new MagnetURIHandler.ResourceProvider()
+											{
+												public String
+												getUID()
+												{
+													return( SubscriptionManager.class.getName() + ".sid." + sub.getID() );
+												}
+												
+												public String
+												getFileType()
+												{
+													return( "vuze" );
+												}
+														
+												public byte[]
+												getData()
+												{
+													return( vf_bytes );
+												}
+											});
+											
+									SearchResult search_result = 
+										new SearchResult()
+										{
+											public Object
+											getProperty(
+												int		property_name )
+											{
+												if ( property_name == SearchResult.PR_NAME ){
+													
+													return( sub.getName());
+													
+												}else if ( 	property_name == SearchResult.PR_DOWNLOAD_LINK ||
+															property_name == SearchResult.PR_DOWNLOAD_BUTTON_LINK ){
+													
+													return( url.toExternalForm());
+													
+												}else if ( property_name == SearchResult.PR_PUB_DATE ){
+													
+													return( new Date(sub.getAddTime()));
+													
+												}else if ( property_name == SearchResult.PR_SIZE ){
+													
+													return( 1024L );
+													
+												}else if ( 	property_name == SearchResult.PR_SEED_COUNT ||
+															property_name == SearchResult.PR_VOTES ){
+																							
+													return((long)sub.getCachedPopularity());
+													
+												}else if ( property_name == SearchResult.PR_RANK ){
+												
+													return( 100L );
+												}
+												
+												return( null );
+											}
+										};
+							
+									added++;
+										
+									try{
+										observer.resultReceived( si, search_result );
+										
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+									}
+								}
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+						
+					}finally{
+						
+						observer.complete();
+					}
+				}
+			}.start();
+		}
+		
+		return( si );
+	}
+	
+	private List<SubscriptionResult>
+	matchSubscriptionResults(
+		searchMatcher	matcher  )
+	{
+		List<SubscriptionResult> result = new ArrayList<SubscriptionResult>();
+				
+		for ( Subscription sub: getSubscriptions( true )){
+			
+			SubscriptionResult[] results = sub.getResults( false );
+			
+			for ( SubscriptionResult r: results ){
+				
+				Map properties = r.toPropertyMap();
+				
+				String name = (String)properties.get( SearchResult.PR_NAME );
+				
+				if ( name == null ){
+					
+					continue;
+				}
+				
+				if ( matcher.matches( name )){
+					
+					result.add( r );
+				}
+			}
+		}
+		
+		return( result );
+	}
+	
 	protected void
 	checkMaxResults(
 		int		max )
@@ -637,14 +1158,46 @@ SubscriptionManagerImpl
 	public boolean
 	isRSSPublishEnabled()
 	{
-		return( COConfigurationManager.getBooleanParameter( RSS_ENABLE_CONFIG_KEY, false ));
+		return( COConfigurationManager.getBooleanParameter( CONFIG_RSS_ENABLE, false ));
 	}
 	
 	public void
 	setRSSPublishEnabled(
 		boolean		enabled )
 	{
-		COConfigurationManager.setParameter( RSS_ENABLE_CONFIG_KEY, enabled );
+		COConfigurationManager.setParameter( CONFIG_RSS_ENABLE, enabled );
+	}
+	
+	public boolean
+	isSearchEnabled()
+	{
+		return( COConfigurationManager.getBooleanParameter( CONFIG_ENABLE_SEARCH, true ));
+	}
+	
+	public void
+	setSearchEnabled(
+		boolean		enabled )
+	{
+		COConfigurationManager.setParameter( CONFIG_ENABLE_SEARCH, enabled );
+	}
+	
+	public boolean
+	hideSearchTemplates()
+	{
+		return( COConfigurationManager.getBooleanParameter( CONFIG_HIDE_SEARCH_TEMPLATES, true ));
+	}
+	
+	public boolean
+	isSubsDownloadEnabled()
+	{
+		return( COConfigurationManager.getBooleanParameter( CONFIG_DL_SUBS_ENABLE, true ));
+	}
+	
+	public void
+	setSubsDownloadEnabled(
+		boolean		enabled )
+	{
+		COConfigurationManager.setParameter( CONFIG_DL_SUBS_ENABLE, enabled );
 	}
 	
 	public String
@@ -781,7 +1334,15 @@ SubscriptionManagerImpl
 		try{
 			Map	singleton_details = new HashMap();
 			
-			singleton_details.put( "key", url.toExternalForm().getBytes( "UTF-8" ));
+			if ( url.getProtocol().equalsIgnoreCase( "vuze" )){
+				
+					// hack to minimise encoded url length for our own urls
+				
+				singleton_details.put( "key", url.toExternalForm().getBytes( Constants.BYTE_ENCODING ));
+
+			}else{
+				singleton_details.put( "key", url.toExternalForm().getBytes( "UTF-8" ));
+			}
 						
 			String	name2 = name.length() > 64?name.substring(0,64):name;
 			
@@ -890,7 +1451,7 @@ SubscriptionManagerImpl
 			
 			String protocol = url.getProtocol().toLowerCase();
 			
-			if ( ! ( protocol.equals( "azplug" ) || protocol.equals( "file" ))){
+			if ( ! ( protocol.equals( "azplug" ) || protocol.equals( "file" ) || protocol.equals( "vuze" ))){
 			
 				throw( new SubscriptionException( "Invalid URL '" + url + "'" ));
 			}
@@ -904,14 +1465,21 @@ SubscriptionManagerImpl
 		SubscriptionImpl existing;
 		
 		synchronized( this ){
-			
-			existing = getSubscriptionFromSID( subs.getShortID());
-			
-			if ( existing == null ){
 
-				subscriptions.add( subs );
+			int index = Collections.binarySearch(subscriptions, subs, new Comparator<Subscription>() {
+				public int compare(Subscription arg0, Subscription arg1) {
+					return arg0.getID().compareTo(arg1.getID());
+				}
+			});
+			if (index < 0) {
+				existing = null;
+				index = -1 * index - 1; // best guess
+
+				subscriptions.add( index, subs );
 			
 				saveConfig();
+			} else {
+				existing = (SubscriptionImpl) subscriptions.get(index);
 			}
 		}
 		
@@ -1014,7 +1582,7 @@ SubscriptionManagerImpl
 				engineUpdated(
 					Engine		engine )
 				{
-					synchronized( this ){
+					synchronized( SubscriptionManagerImpl.this ){
 						
 						for (int i=0;i<subscriptions.size();i++){
 							
@@ -1089,13 +1657,6 @@ SubscriptionManagerImpl
 			
 				saveConfig();
 				
-				try{
-					getResultsFile( subs ).delete();
-					
-				}catch( Throwable e ){
-					
-					log( "Failed to delete results file", e );
-				}
 			}else{
 			
 				return;
@@ -1117,18 +1678,32 @@ SubscriptionManagerImpl
 			log( "Failed to check for engine deletion", e );
 		}
 		
-		Iterator it = listeners.iterator();
+		Iterator<SubscriptionManagerListener> it = listeners.iterator();
 		
 		while( it.hasNext()){
 			
 			try{
-				((SubscriptionManagerListener)it.next()).subscriptionRemoved( subs );
+				it.next().subscriptionRemoved( subs );
 				
 			}catch( Throwable e ){
 				
 				Debug.printStackTrace(e);
 			}
 		}
+		
+		try{
+			FileUtil.deleteResilientFile( getResultsFile( subs ));
+			
+			File vuze_file = getVuzeFile( subs );
+			
+			vuze_file.delete();
+			
+			new File( vuze_file.getParent(), vuze_file.getName() + ".bak" ).delete();
+			
+		}catch( Throwable e ){
+			
+			log( "Failed to delete results/vuze file", e );
+		}
 	}
 	
 	protected void
@@ -1265,16 +1840,46 @@ SubscriptionManagerImpl
 	checkStuff(
 		int		ticks )
 	{
-		List subs;
+		long now = SystemTime.getCurrentTime();
+		
+		List<SubscriptionImpl> subs;
 		
 		synchronized( this ){
 			
-			subs = new ArrayList( subscriptions );
+			subs = new ArrayList<SubscriptionImpl>( subscriptions );
 		}
 		
+		SubscriptionImpl	expired_subs = null;
+		
 		for (int i=0;i<subs.size();i++){
 			
-			((SubscriptionImpl)subs.get(i)).checkPublish();
+			SubscriptionImpl sub = subs.get( i );
+			
+			if ( !( sub.isMine() || sub.isSubscribed())){
+				
+				long	age = now - sub.getAddTime();
+				
+				if ( age > DELETE_UNUSED_AFTER_MILLIS ){
+					
+					if ( 	expired_subs == null || 
+							( sub.getAddTime() < expired_subs.getAddTime())){
+						
+						expired_subs = sub;
+					}
+					
+					continue;
+				}
+			}
+			
+			
+			sub.checkPublish();
+		}
+		
+		if ( expired_subs != null ){
+			
+			log( "Removing unsubscribed subscription '" + expired_subs.getName() + "' as expired" );
+					
+			expired_subs.remove();
 		}
 		
 		if ( ticks % ASSOC_CHECK_TICKS == 0 ){
@@ -1532,7 +2137,7 @@ SubscriptionManagerImpl
 		}
 		
 		List	result = new ArrayList();
-		
+				
 		synchronized( this ){
 			
 			for (int i=0;i<subscriptions.size();i++){
@@ -1549,6 +2154,32 @@ SubscriptionManagerImpl
 		return((SubscriptionImpl[])result.toArray( new SubscriptionImpl[result.size()]));
 	}
 	
+	public int
+	getSubscriptionCount(
+		boolean	subscribed_only )
+	{
+		if ( subscribed_only ){
+	
+			int total = 0;
+			
+			synchronized( this ){
+				
+				for ( Subscription subs: subscriptions ){
+					
+					if ( subs.isSubscribed()){
+						
+						total++;
+					}
+				}
+			}
+			
+			return( total );
+			
+		}else{
+			return( subscriptions.size());
+		}
+	}
+
 	protected SubscriptionImpl
 	getSubscriptionFromName(
 		String		name )
@@ -1573,27 +2204,29 @@ SubscriptionManagerImpl
 	getSubscriptionByID(
 		String		id )
 	{
-		return( getSubscriptionFromSID( Base32.decode( id )));
+		synchronized( this ){
+			
+  		int index = Collections.binarySearch(subscriptions, id, new Comparator() {
+  			public int compare(Object o1, Object o2) {
+  				String id1 = (o1 instanceof Subscription) ? ((Subscription) o1).getID() : o1.toString();
+  				String id2 = (o2 instanceof Subscription) ? ((Subscription) o2).getID() : o2.toString();
+  				return id1.compareTo(id2);
+  			}
+  		});
+  		
+  		if (index >= 0) {
+  			return subscriptions.get(index);
+  		}
+		}
+		
+		return null;
 	}
 	
 	protected SubscriptionImpl
 	getSubscriptionFromSID(
 		byte[]		sid )
 	{
-		synchronized( this ){
-			
-			for (int i=0;i<subscriptions.size();i++){
-				
-				SubscriptionImpl s = (SubscriptionImpl)subscriptions.get(i);
-				
-				if ( Arrays.equals( s.getShortID(), sid )){
-					
-					return( s );
-				}
-			}
-		}
-		
-		return( null );
+		return (SubscriptionImpl) getSubscriptionByID( Base32.encode(sid));
 	}
 	
 	protected File
@@ -1638,6 +2271,45 @@ SubscriptionManagerImpl
  		return( new File( dir, ByteFormatter.encodeString( subs.getShortID()) + ".results" ));
 	}
 	
+	public int
+	getKnownSubscriptionCount()
+	{
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+
+		ByteArrayHashMap<String> results = new ByteArrayHashMap<String>();
+		
+		try{
+			Download[] downloads = pi.getDownloadManager().getDownloads();
+			
+			for ( Download download: downloads ){
+				
+				Map	m = download.getMapAttribute( ta_subscription_info );
+				
+				if ( m != null ){
+					
+					List s = (List)m.get("s");
+					
+					if ( s != null && s.size() > 0 ){
+						
+						List	result = new ArrayList( s.size());
+						
+						for (int i=0;i<s.size();i++){
+							
+							byte[]	sid = (byte[])s.get(i);
+							
+							results.put( sid, "" );
+						}
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			log( "Failed to get known subscriptions", e );
+		}
+		
+		return( results.size());
+	}
+	
 	public Subscription[]
 	getKnownSubscriptions(
 		byte[]						hash )
@@ -1659,6 +2331,8 @@ SubscriptionManagerImpl
 						
 						List	result = new ArrayList( s.size());
 						
+						boolean hide_search = hideSearchTemplates();
+						
 						for (int i=0;i<s.size();i++){
 							
 							byte[]	sid = (byte[])s.get(i);
@@ -1669,7 +2343,12 @@ SubscriptionManagerImpl
 								
 								if ( isVisible( subs )){
 								
-									result.add( subs );
+									if ( hide_search && subs.isSearchTemplate()){
+									
+									}else{
+										
+										result.add( subs );
+									}
 								}
 							}
 						}
@@ -1942,7 +2621,7 @@ SubscriptionManagerImpl
 	{
 		boolean	recheck;
 		
-		synchronized( SubscriptionManagerImpl.this ){
+		synchronized( this ){
 			
 			periodic_lookup_in_progress = false;
 			
@@ -2270,9 +2949,10 @@ SubscriptionManagerImpl
 				
 				private boolean	complete;
 				
-				public void
+				public boolean
 				diversified()
 				{
+					return( true );
 				}
 				
 				public void 
@@ -2559,14 +3239,12 @@ SubscriptionManagerImpl
 					try{
 						checkSingletonPublish( subs );
 						
-						listener.gotPopularity( subs.isSubscribed()?1:0 );
-						
-						return;
-						
-					}catch( Throwable e ){
-						
-						log( "    failed to create singleton public subscription " + subs.getString(), e );
+					}catch( Throwable e ){						
 					}
+					
+					listener.gotPopularity( subs.isSubscribed()?1:0 );
+						
+					return;
 				}
 			}
 			
@@ -2658,10 +3336,12 @@ SubscriptionManagerImpl
 					
 					private int	hits = 0;
 					
-					public void
+					public boolean
 					diversified()
 					{
 						diversified = true;
+						
+						return( false );
 					}
 					
 					public void 
@@ -2815,9 +3495,10 @@ SubscriptionManagerImpl
 				{
 					private boolean listener_handled;
 					
-					public void
+					public boolean
 					diversified()
 					{
+						return( true );
 					}
 					
 					public void 
@@ -3246,11 +3927,11 @@ SubscriptionManagerImpl
 		
 		synchronized( potential_associations ){
 
-			Iterator it = potential_associations.iterator();
+			Iterator<Object[]> it = potential_associations.iterator();
 			
 			while( it.hasNext()){
 				
-				Object[]	entry = (Object[])it.next();
+				Object[]	entry = it.next();
 				
 				String	this_key = (String)entry[2];
 				
@@ -3518,7 +4199,7 @@ SubscriptionManagerImpl
 
 		synchronized( this ){
 			
-			if ( publish_associations_active >= PUB_ASSOC_CONC_MAX ){
+			if ( publish_associations_active >= ( dht_plugin.isSleeping()?PUB_SLEEPING_ASSOC_CONC_MAX:PUB_ASSOC_CONC_MAX )){
 				
 				return( false );
 			}			
@@ -3552,6 +4233,7 @@ SubscriptionManagerImpl
 			publishAssociation( subs_to_publish, assoc_to_publish );
 			
 			return( false );
+			
 		}else{
 					
 			log( "Publishing Associations Complete" );
@@ -3602,10 +4284,12 @@ SubscriptionManagerImpl
 				private boolean		diversified;
 				private int			max_ver;
 				
-				public void
+				public boolean
 				diversified()
 				{
 					diversified = true;
+					
+					return( false );
 				}
 				
 				public void 
@@ -3671,7 +4355,7 @@ SubscriptionManagerImpl
 						}
 					}
 					
-					if (( hits == 0 && diversified ) || ( hits < 6 && !diversified )){			
+					if ( hits < 10 && !diversified ){			
 			
 						log( "    Publishing association '" + subs.getString() + "' -> '" + assoc.getString() + "', existing=" + hits );
 
@@ -3689,9 +4373,10 @@ SubscriptionManagerImpl
 							flags,
 							new DHTPluginOperationListener()
 							{
-								public void
+								public boolean
 								diversified()
 								{
+									return( true );
 								}
 								
 								public void 
@@ -3735,16 +4420,57 @@ SubscriptionManagerImpl
 				protected void
 				publishNext()
 				{
-					synchronized( this ){
+					synchronized( SubscriptionManagerImpl.this ){
 						
 						publish_associations_active--;
 					}
 					
-					publishAssociations();
+					publishNextAssociation();
 				}
 			});
 	}
 	
+	private void
+	publishNextAssociation()
+	{
+		boolean	dht_sleeping = dht_plugin.isSleeping();
+		
+		if ( dht_sleeping ){
+			
+			synchronized( this ){
+				
+				if ( publish_next_asyc_pending ){
+					
+					return;
+				}
+				
+				publish_next_asyc_pending = true;
+			}
+			
+			SimpleTimer.addEvent(
+				"subs:pn:async",
+				SystemTime.getCurrentTime() + 60*1000,
+				new TimerEventPerformer()
+				{
+					public void 
+					perform(
+						TimerEvent event) 
+					{
+						synchronized( SubscriptionManagerImpl.this ){
+							
+							publish_next_asyc_pending = false;
+						}
+						
+						publishAssociations();
+					}
+				});
+			
+			return;
+		}
+		
+		publishAssociations();
+	}
+	
 	protected void
 	subscriptionUpdated()
 	{
@@ -3829,10 +4555,12 @@ SubscriptionManagerImpl
 				private int		hits;
 				private boolean	diversified;
 				
-				public void
+				public boolean
 				diversified()
 				{					
 					diversified = true;
+					
+					return( false );
 				}
 				
 				public void 
@@ -3874,63 +4602,70 @@ SubscriptionManagerImpl
 				{
 					log( "Checked subscription publication '" + subs.getString() + "' - hits=" + hits + ",div=" + diversified );
 
-					if (( hits == 0 && diversified ) || ( hits < 6 && !diversified )){			
+					if ( hits < 10 && !diversified ){			
 			
 						log( "    Publishing subscription '" + subs.getString() + ", existing=" + hits );
 
 						try{
 							byte[]	put_value = encodeSubscriptionDetails( subs );						
 							
-							byte	flags = DHTPlugin.FLAG_SINGLE_VALUE;
-							
-							if ( hits < 3 && !diversified ){
+							if ( put_value.length < DHTPlugin.MAX_VALUE_SIZE ){
 								
-								flags |= DHTPlugin.FLAG_PRECIOUS;
-							}
-							
-							dht_plugin.put(
-								key.getBytes(),
-								"Subscription presence write: " + ByteFormatter.encodeString( subs.getShortID() ) + ":" + subs.getVersion(),
-								put_value,
-								flags,
-								new DHTPluginOperationListener()
-								{
-									public void
-									diversified()
-									{
-									}
-									
-									public void 
-									starts(
-										byte[] 				key ) 
-									{
-									}
-									
-									public void
-									valueRead(
-										DHTPluginContact	originator,
-										DHTPluginValue		value )
-									{
-									}
-									
-									public void
-									valueWritten(
-										DHTPluginContact	target,
-										DHTPluginValue		value )
-									{
-									}
+								byte	flags = DHTPlugin.FLAG_SINGLE_VALUE;
+								
+								if ( hits < 3 && !diversified ){
 									
-									public void
-									complete(
-										byte[]				key,
-										boolean				timeout_occurred )
+									flags |= DHTPlugin.FLAG_PRECIOUS;
+								}
+								
+								dht_plugin.put(
+									key.getBytes(),
+									"Subscription presence write: " + ByteFormatter.encodeString( subs.getShortID() ) + ":" + subs.getVersion(),
+									put_value,
+									flags,
+									new DHTPluginOperationListener()
 									{
-										log( "        completed '" + subs.getString() + "'" );
-					
-										publishNext();
-									}
-								});
-							
+										public boolean
+										diversified()
+										{
+											return( true );
+										}
+										
+										public void 
+										starts(
+											byte[] 				key ) 
+										{
+										}
+										
+										public void
+										valueRead(
+											DHTPluginContact	originator,
+											DHTPluginValue		value )
+										{
+										}
+										
+										public void
+										valueWritten(
+											DHTPluginContact	target,
+											DHTPluginValue		value )
+										{
+										}
+										
+										public void
+										complete(
+											byte[]				key,
+											boolean				timeout_occurred )
+										{
+											log( "        completed '" + subs.getString() + "'" );
+						
+											publishNext();
+										}
+									});
+								
+							}else{
+								
+								publishNext();
+							}
 						}catch( Throwable e ){
 							
 							Debug.printStackTrace( e );
@@ -3949,7 +4684,7 @@ SubscriptionManagerImpl
 				protected void
 				publishNext()
 				{
-					synchronized( this ){
+					synchronized( SubscriptionManagerImpl.this ){
 						
 						publish_subscription_active = false;
 					}
@@ -4020,9 +4755,10 @@ SubscriptionManagerImpl
 				private byte[]	verified_hash;
 				private int		verified_size;
 				
-				public void
+				public boolean
 				diversified()
 				{
+					return( true );
 				}
 				
 				public void 
@@ -4093,7 +4829,7 @@ SubscriptionManagerImpl
 		details.put( "!", new Long( random_seed ));
 		
 		byte[] encoded = BEncoder.encode( details );
-		
+				
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 				
 		GZIPOutputStream os = new GZIPOutputStream( baos );
@@ -4191,7 +4927,14 @@ SubscriptionManagerImpl
 	downloadTorrent(
 		byte[]		hash,
 		int			update_size )
-	{		
+	{
+		if ( !isSubsDownloadEnabled()){
+			
+			log( "    Can't download subscription " + Base32.encode( hash ) + " as feature disabled" );
+			
+			return( null );
+		}
+		
 		final MagnetPlugin	magnet_plugin = getMagnetPlugin();
 	
 		if ( magnet_plugin == null ){
@@ -4241,11 +4984,18 @@ SubscriptionManagerImpl
 					{
 						return( false );
 					}
+					
+					public boolean 
+					cancelled() 
+					{
+						return( false );
+					}
 				},
 				hash,
 				"",
 				new InetSocketAddress[0],
-				300*1000 );
+				300*1000,
+				MagnetPlugin.FL_DISABLE_MD_LOOKUP );
 			
 			if ( torrent_data == null ){
 				
@@ -5014,7 +5764,7 @@ SubscriptionManagerImpl
 		}
  	}
 	
-	protected void
+	private void
 	loadConfig()
 	{
 		if ( !FileUtil.resilientConfigFileExists( CONFIG_FILE )){
@@ -5040,9 +5790,18 @@ SubscriptionManagerImpl
 					
 					try{
 						SubscriptionImpl sub = new SubscriptionImpl( this, m );
-						
-						subscriptions.add( sub );
-						
+
+						int index = Collections.binarySearch(subscriptions, sub, new Comparator<Subscription>() {
+							public int compare(Subscription arg0, Subscription arg1) {
+								return arg0.getID().compareTo(arg1.getID());
+							}
+						});
+						if (index < 0) {
+							index = -1 * index - 1; // best guess
+
+							subscriptions.add( index, sub );
+						}
+
 						if ( sub.isMine()){
 							
 							some_are_mine = true;
@@ -5147,9 +5906,11 @@ SubscriptionManagerImpl
 		}
 	}
 	
-	protected synchronized AEDiagnosticsLogger
+	private AEDiagnosticsLogger
 	getLogger()
 	{
+			// sync not required (and has caused deadlock) as AEDiagnostics handles singleton
+		
 		if ( logger == null ){
 			
 			logger = AEDiagnostics.getLogger( LOGGER_NAME );
@@ -5216,6 +5977,132 @@ SubscriptionManagerImpl
 		}
 	}
 	
+	private class
+	searchMatcher
+	{
+		private String[]	bits;
+		private int[]		bit_types;
+		private Pattern[]	bit_patterns;
+
+		protected 
+		searchMatcher(
+			String		term )
+		{
+			bits = Constants.PAT_SPLIT_SPACE.split(term.toLowerCase() );
+			
+			bit_types 		= new int[bits.length];
+			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 ){
+						}
+					}
+				}
+			}
+		}
+		
+		public boolean
+		matches(
+			String		str )
+		{			
+			// 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'
+									
+			str = str.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 = str.contains( bit );
+						
+					}else{
+					
+						hit = bit_patterns[i].matcher( str ).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;
+						}
+					}
+				}
+			}
+			
+			boolean res = match && at_least_one;
+				
+			return( res );
+		}
+	}
+	
 	public static void
 	main(
 		String[]	args )
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java b/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java
index 2553fb4..20c006d 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionRSSFeed.java
@@ -67,7 +67,10 @@ SubscriptionRSSFeed
 				
 		generator	= RSSGeneratorPlugin.getSingleton();
 		
-		generator.registerProvider( PROVIDER, this );
+		if ( generator != null ){
+			
+			generator.registerProvider( PROVIDER, this );
+		}
 	}
 		
 	public boolean
@@ -79,7 +82,7 @@ SubscriptionRSSFeed
 	public String
 	getFeedURL()
 	{
-		return( generator.getURL() + PROVIDER );
+		return( generator==null?"Feature Disabled":( generator.getURL() + PROVIDER ));
 	}
 	
 	public boolean
@@ -119,6 +122,11 @@ SubscriptionRSSFeed
 				
 				for ( Subscription s: subs ){
 	
+					if ( s.isSearchTemplate()){
+						
+						continue;
+					}
+					
 					String	name = s.getName();
 									
 					pw.println( "<LI><A href=\"" + PROVIDER + "/" + s.getID() + "\">" + name + "</A></LI>" );
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
index 374d3eb..c960d91 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionResultImpl.java
@@ -333,7 +333,7 @@ SubscriptionResultImpl
 		
 		String	hash = (String)map.get( "h" );
 		if ( hash != null ){
-			result.put( SearchResult.PR_HASH, hash );
+			result.put( SearchResult.PR_HASH, Base32.decode( hash ));
 		}
 		
 		String	seeds = (String)map.get( "s" );
diff --git a/com/aelitis/azureus/core/subs/impl/SubscriptionSchedulerImpl.java b/com/aelitis/azureus/core/subs/impl/SubscriptionSchedulerImpl.java
index 34d09b9..82e0809 100644
--- a/com/aelitis/azureus/core/subs/impl/SubscriptionSchedulerImpl.java
+++ b/com/aelitis/azureus/core/subs/impl/SubscriptionSchedulerImpl.java
@@ -36,6 +36,7 @@ import org.gudy.azureus2.core3.util.SimpleTimer;
 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.TorrentUtils;
 import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadManager;
@@ -295,8 +296,10 @@ SubscriptionSchedulerImpl
 								retry = false;
 							
 								try{
+									TorrentUtils.setTLSDescription( "Subscription: " + subs.getName());
+
 									URL url = new URL(dl);
-									
+																		
 									ResourceDownloaderFactory rdf = StaticUtilities.getResourceDownloaderFactory();
 									
 									ResourceDownloader url_rd = rdf.create( url );
@@ -369,6 +372,9 @@ SubscriptionSchedulerImpl
 										
 										log( subs.getName() + ": Retrying " + (use_ref?"with referer":"without referer" ));
 									}
+								}finally{
+									
+									TorrentUtils.setTLSDescription( null );
 								}
 							}
 						}finally{
@@ -388,7 +394,7 @@ SubscriptionSchedulerImpl
 	protected void
 	calculateSchedule()
 	{
-		Subscription[]	subs = manager.getSubscriptions();
+		Subscription[]	subs = manager.getSubscriptions( true );
 		
 		synchronized( this ){
 			
@@ -407,12 +413,7 @@ SubscriptionSchedulerImpl
 			for (int i=0;i<subs.length;i++){
 				
 				Subscription sub = subs[i];
-				
-				if ( !sub.isSubscribed()){
-					
-					continue;
-				}
-				
+								
 				SubscriptionHistory history = sub.getHistory();
 				
 				if ( !history.isEnabled()){
@@ -453,7 +454,12 @@ SubscriptionSchedulerImpl
 						next_ready_time = now + 30*1000;
 					}
 				}
-						
+					
+				if ( next_ready_time < now ){
+					
+					next_ready_time = now;
+				}
+				
 				log( "Calculate : " + 
 						"old_time=" + new SimpleDateFormat().format(new Date(old_when)) +
 						", new_time=" + new SimpleDateFormat().format(new Date(next_ready_time)));
@@ -509,19 +515,14 @@ SubscriptionSchedulerImpl
 	protected void
 	schedule()
 	{
-		Subscription[]	subs = manager.getSubscriptions();
+		Subscription[]	subs = manager.getSubscriptions( true );
 		
 		long now = SystemTime.getCurrentTime();
 			
 		for (int i=0;i<subs.length;i++){
 			
 			Subscription sub = subs[i];
-			
-			if ( !sub.isSubscribed()){
-				
-				continue;
-			}
-			
+						
 			SubscriptionHistory history = sub.getHistory();
 			
 			if ( !history.isEnabled()){
diff --git a/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java b/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
index 95e448e..5f2bcb7 100644
--- a/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
+++ b/com/aelitis/azureus/core/torrent/PlatformTorrentUtils.java
@@ -75,18 +75,12 @@ public class PlatformTorrentUtils
 
 	private static final String TOR_AZ_PROP_THUMBNAIL_URL = "Thumbnail.url";
 
-	private static final String TOR_AZ_PROP_QUALITY = "Quality";
-
 	private static final String TOR_AZ_PROP_PROGRESSIVE = "Progressive";
 
 	private static final String TOR_AZ_PROP_SPEED = "Speed Bps";
 
 	private static final String TOR_AZ_PROP_MIN_SPEED = "Min Speed Bps";
 
-	private static final String TOR_AZ_PROP_DRM = "DRM";
-
-	private static final String TOR_AZ_PROP_PURCHASED = "Purchased";
-
 	private static final String TOR_AZ_PROP_QOS_CLASS = "QOS Class";
 
 	private static final String TOR_AZ_PROP_CONTENT_NETWORK = "Content Network";
@@ -97,10 +91,6 @@ public class PlatformTorrentUtils
 
 	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_VIDEO_WIDTH = "Video Width";
 
 	private static final String TOR_AZ_PROP_VIDEO_HEIGHT = "Video Height";
@@ -294,19 +284,6 @@ public class PlatformTorrentUtils
 		return getContentMapString(torrent, TOR_AZ_PROP_URL);
 	}
 
-	public static String getContentQuality(TOTorrent torrent) {
-		return getContentMapString(torrent, TOR_AZ_PROP_QUALITY);
-	}
-
-	public static boolean isContentDRM(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_DRM, -1) >= 0;
-	}
-
-	public static boolean isContentPurchased(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_PURCHASED, 0) == 1;
-	}
-
-
 	public static long getQOSClass(TOTorrent torrent) {
 		return getContentMapLong(torrent, TOR_AZ_PROP_QOS_CLASS, 0);
 	}
@@ -341,13 +318,6 @@ public class PlatformTorrentUtils
 		}
 	}
 
-	public static void setContentQuality(TOTorrent torrent, String sQualityID) {
-		Map mapContent = getContentMap(torrent);
-		putOrRemove(mapContent, TOR_AZ_PROP_QUALITY, sQualityID);
-
-		writeTorrentIfExists(torrent);
-	}
-
 	private static void writeTorrentIfExists(TOTorrent torrent) {
 		if (!AzureusCoreFactory.isCoreRunning()) {
 			return;
@@ -597,22 +567,6 @@ public class PlatformTorrentUtils
 		return getContentMapLong(torrent, TOR_AZ_PROP_MIN_SPEED, MIN_SPEED_DEFAULT);
 	}
 
-	public static boolean useEMP(TOTorrent torrent) {
-		return getContentMapLong(torrent, TOR_AZ_PROP_USE_EMP, 0) == 1;
-	}
-	
-	public static void setUseEMP(TOTorrent torrent, boolean useEMP) {
-		setContentMapLong(torrent, TOR_AZ_PROP_USE_EMP, useEMP ? 1 : 0);
-	}
-	
-	public static void setFileMetaData(TOTorrent torrent, Map map) {
-		setContentMapMap(torrent, TOR_AZ_PROP_FILE_METADATA, map );
-	}
-	
-	public static Map getFileMetaData(TOTorrent torrent ){
-		return getContentMapMap( torrent, TOR_AZ_PROP_FILE_METADATA );
-	}
-	
 	public static long getExpiresOn(TOTorrent torrent) {
 		Map mapContent = getContentMap(torrent);
 		Long l = (Long) mapContent.get(TOR_AZ_PROP_EXPIRESON);
diff --git a/com/aelitis/azureus/core/tracker/TrackerPeerSource.java b/com/aelitis/azureus/core/tracker/TrackerPeerSource.java
new file mode 100644
index 0000000..51e2e53
--- /dev/null
+++ b/com/aelitis/azureus/core/tracker/TrackerPeerSource.java
@@ -0,0 +1,86 @@
+/*
+ * Created on Dec 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.core.tracker;
+
+public interface 
+TrackerPeerSource 
+{
+	public static final int TP_UNKNOWN		= 0;
+	public static final int TP_TRACKER		= 1;
+	public static final int TP_HTTP_SEED	= 2;
+	public static final int TP_DHT			= 3;
+	public static final int TP_LAN			= 4;
+	public static final int TP_PEX			= 5;
+	public static final int TP_INCOMING		= 6;
+	public static final int TP_PLUGIN		= 7;
+	
+	public static final int ST_UNKNOWN		= 0;
+	public static final int ST_DISABLED		= 1;
+	public static final int ST_STOPPED		= 2;
+	public static final int ST_QUEUED		= 3;
+	public static final int ST_UPDATING		= 4;
+	public static final int ST_ONLINE 		= 5;
+	public static final int ST_ERROR		= 6;
+	public static final int ST_AVAILABLE	= 7;
+	public static final int ST_UNAVAILABLE	= 8;
+	public static final int ST_INITIALISING	= 9;
+
+	
+	public int
+	getType();
+	
+	public String
+	getName();
+	
+	public int
+	getStatus();
+	
+	public String
+	getStatusString();
+	
+	public int
+	getSeedCount();
+	
+	public int
+	getLeecherCount();
+	
+	public int
+	getPeers();
+	
+	public int
+	getSecondsToUpdate();
+	
+	public int
+	getInterval();
+	
+	public int
+	getMinInterval();
+	
+	public boolean
+	isUpdating();
+	
+	public boolean
+	canManuallyUpdate();
+	
+	public void
+	manualUpdate();
+}
diff --git a/com/aelitis/azureus/core/tracker/TrackerPeerSourceAdapter.java b/com/aelitis/azureus/core/tracker/TrackerPeerSourceAdapter.java
new file mode 100644
index 0000000..410a486
--- /dev/null
+++ b/com/aelitis/azureus/core/tracker/TrackerPeerSourceAdapter.java
@@ -0,0 +1,104 @@
+/*
+ * Created on Dec 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.tracker;
+
+public abstract class 
+TrackerPeerSourceAdapter 
+	implements TrackerPeerSource
+{
+	public int
+	getType()
+	{
+		return( TP_UNKNOWN );
+	}
+	
+	public String
+	getName()
+	{
+		return( "" );
+	}
+	
+	public int
+	getStatus()
+	{
+		return( ST_UNKNOWN );
+	}
+	
+	public String
+	getStatusString()
+	{
+		return( null );
+	}
+	
+	public int
+	getSeedCount()
+	{
+		return( -1 );
+	}
+	
+	public int
+	getLeecherCount()
+	{
+		return( -1 );
+	}
+	
+	public int
+	getPeers()
+	{
+		return( -1 );
+	}
+	
+	public int
+	getSecondsToUpdate()
+	{
+		return( -1 );
+	}
+	
+	public int
+	getInterval()
+	{
+		return( -1 );
+	}
+	
+	public int
+	getMinInterval()
+	{
+		return( -1 );
+	}
+	
+	public boolean
+	isUpdating()
+	{
+		return( false );
+	}
+	
+	public boolean
+	canManuallyUpdate()
+	{
+		return( false );
+	}
+	
+	public void
+	manualUpdate()
+	{
+	}
+}
diff --git a/com/aelitis/azureus/core/update/AzureusRestarter.java b/com/aelitis/azureus/core/update/AzureusRestarter.java
index c9dc0ca..5d7f778 100644
--- a/com/aelitis/azureus/core/update/AzureusRestarter.java
+++ b/com/aelitis/azureus/core/update/AzureusRestarter.java
@@ -22,6 +22,8 @@
 
 package com.aelitis.azureus.core.update;
 
+import com.aelitis.azureus.core.AzureusCoreException;
+
 /**
  * @author parg
  *
@@ -33,4 +35,9 @@ AzureusRestarter
 	public void
 	restart(
 		boolean	update_only );
+	
+	public void
+	updateNow()
+	
+		throws AzureusCoreException;
 }
diff --git a/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java b/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java
index b4438fb..909f99f 100644
--- a/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java
+++ b/com/aelitis/azureus/core/update/impl/AzureusRestarterImpl.java
@@ -38,6 +38,7 @@ import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.update.UpdaterUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreException;
 import com.aelitis.azureus.core.update.AzureusRestarter;
 
 public class 
@@ -84,13 +85,40 @@ AzureusRestarterImpl
 		
 		restarted	= true;
 		
+		try{
+		
+			runUpdateProcess( update_only, false );
+			
+		}catch( Throwable e ){
+			// already logged
+		}
+	}
+	
+	public void
+	updateNow()
+	
+		throws AzureusCoreException
+	{
+		if ( !runUpdateProcess( true, true )){
+			
+			throw( new AzureusCoreException( "Failed to invoke restart" ));
+		}
+	}
+	
+	private boolean
+	runUpdateProcess(
+		boolean		update_only,
+		boolean		no_wait )
+	
+		throws AzureusCoreException
+	{
 		PluginInterface pi = azureus_core.getPluginManager().getPluginInterfaceByID( "azupdater" );
 		
 		if ( pi == null ){
 			Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR,
-					"Can't restart, mandatory plugin 'azupdater' not found"));
+					"Can't update/restart, mandatory plugin 'azupdater' not found"));
 			
-			return;
+			throw( new AzureusCoreException( "mandatory plugin 'azupdater' not found" ));
 		}
 		
 		String	updater_dir = pi.getPluginDirectoryName();
@@ -128,13 +156,13 @@ AzureusRestarterImpl
 	  	FileOutputStream	fos	= null;
 	  	
 	  	try{
-	  		Properties	restart_properties = new Properties();
+	  		Properties	update_properties = new Properties();
 	  	
 	  		long	max_mem = Runtime.getRuntime().maxMemory();
 	  			  			  			
-	  		restart_properties.put( "max_mem", ""+max_mem );
-	  		restart_properties.put( "app_name", SystemProperties.getApplicationName());
-	  		restart_properties.put( "app_entry", SystemProperties.getApplicationEntryPoint());
+	  		update_properties.put( "max_mem", ""+max_mem );
+	  		update_properties.put( "app_name", SystemProperties.getApplicationName());
+	  		update_properties.put( "app_entry", SystemProperties.getApplicationEntryPoint());
 	  		
 	  		if ( System.getProperty( "azureus.nativelauncher" ) != null || Constants.isOSX ){
 	  			//NOTE: new 2306 osx bundle now sets azureus.nativelauncher=1, but older bundles dont
@@ -144,7 +172,7 @@ AzureusRestarterImpl
 		  			
 		  			if ( cmd != null ){
 		  				
-		  				restart_properties.put( "app_cmd", cmd );
+		  				update_properties.put( "app_cmd", cmd );
 		  			}
 	  			}catch( Throwable e ){
 	  				
@@ -152,12 +180,16 @@ AzureusRestarterImpl
 	  			}
 	  		}	  		
 	  		
+	  		if ( no_wait ){
+	  			
+	  			update_properties.put( "no_wait", "1" );
+	  		}
 	  		
 	  		fos	= new FileOutputStream( new File( user_path, UPDATE_PROPERTIES ));
 	  		
 	  			// this handles unicode chars by writing \\u escapes
 	  		
-	  		restart_properties.store(fos, "Azureus restart properties" );
+	  		update_properties.store(fos, "Azureus restart properties" );
 	  		
 	  	}catch( Throwable e ){
 	  		
@@ -182,7 +214,7 @@ AzureusRestarterImpl
 	  	
 		ByteArrayOutputStream os = new ByteArrayOutputStream();
 		
-		restartAzureus(new PrintWriter(os) {
+		boolean res = restartAzureus(new PrintWriter(os) {
 			public void println(String str) {
 				// we intercept these logs and log immediately
 				Logger.log(new LogEvent(LOGID, str));
@@ -196,9 +228,11 @@ AzureusRestarterImpl
 		
 		if ( bytes.length > 0 ){
 			
-			Logger.log(new LogEvent(LOGID, "AzureusRestarter: extra log - "
+			Logger.log(new LogEvent(LOGID, "AzureusUpdater: extra log - "
 					+ new String(bytes)));
 		}
+		
+		return( res );
 	}
   
 	
@@ -241,46 +275,21 @@ AzureusRestarterImpl
 				// Vista test: 	We will need to run an elevated EXE updater if we can't
 				//            	write to the program dir.
 			
-			if (Constants.isWindowsVistaOrHigher ) {
+			if (Constants.isWindowsVistaOrHigher ){
+				
 				if (PluginInitializer.getDefaultInterface().getUpdateManager().getInstallers().length > 0) {
-					log.println("Vista restart w/Updates.. checking if EXE needed");
-					try {
-						final File writeFile = FileUtil.getApplicationFile("write.dll");
-						// should fail if no perms, but sometimes it's created in
-						// virtualstore (if ran from java(w).exe for example)
-						FileOutputStream fos = new FileOutputStream(writeFile);
-						fos.write(32);
-						fos.close();
-
-						writeFile.delete();
-
-						File renameFile = FileUtil.getApplicationFile("License.txt");
-						if (renameFile != null && renameFile.exists()) {
-							File oldFile = FileUtil.getApplicationFile("License.txt");
-							String oldName = renameFile.getName();
-							File newFile = new File(renameFile.getParentFile(), oldName
-									+ ".bak");
-							renameFile.renameTo(newFile);
-
-							if (oldFile.exists()) {
-								log.println("Requiring EXE because rename test failed");
-								return EXE_UPDATER; 
-							}
-
-							newFile.renameTo(oldFile);
-						} else {
-							log.println("Could not try Permission Test 2. File " + renameFile
-									+ " not found");
-						}
-
-					} catch (Exception e) {
-						log.println("Permission Test Failed. " + e.getMessage() + ";"
-								+ Debug.getCompressedStackTrace());
-						return EXE_UPDATER; 
+					
+					log.println( "Vista restart w/Updates.. checking if EXE needed" );
+					
+					if ( !FileUtil.canReallyWriteToAppDirectory()){
+						
+						log.println( "It appears we can't write to the application dir, using the EXE updater" );
+						
+						return( EXE_UPDATER );
 					}
 				}
 			}
-		} catch (Throwable t) {
+		}catch ( Throwable t ){ 
 			// ignore vista test
 		}
 
@@ -323,7 +332,23 @@ AzureusRestarterImpl
 					}
 					s += "\r\n";
 					s += "start \"\" \"" + azRunner + "\"";
-					FileUtil.writeBytesAsFile(fileRestart.getAbsolutePath(), s.getBytes());
+					
+					byte[]	bytes;
+					
+					String	encoding = FileUtil.getScriptCharsetEncoding();
+					
+					if ( encoding == null ){
+						bytes = s.getBytes();
+					}else{
+						try{
+							bytes = s.getBytes( encoding );
+						}catch( Throwable e){
+							e.printStackTrace();
+							
+							bytes = s.getBytes();
+						}
+					}
+					FileUtil.writeBytesAsFile(fileRestart.getAbsolutePath(),bytes);
 
 					result = accessor.shellExecute(null, fileRestart.getAbsolutePath(),
 							null, SystemProperties.getApplicationPath(),
@@ -428,7 +453,7 @@ AzureusRestarterImpl
   
 
 
-  public void 
+  public boolean 
   restartAzureus(
       PrintWriter log, 
     String    mainClass,
@@ -438,19 +463,19 @@ AzureusRestarterImpl
   {
     if(Constants.isOSX){
     	
-    	restartAzureus_OSX(log,mainClass,properties,parameters);
+    	return( restartAzureus_OSX(log,mainClass,properties,parameters));
     	
     }else if( Constants.isUnix ){
     	
-    	restartAzureus_Unix(log,mainClass,properties,parameters);
+    	return( restartAzureus_Unix(log,mainClass,properties,parameters));
       
     }else{
     	
-    	restartAzureus_win32(log,mainClass,properties,parameters,update_only);
+    	return( restartAzureus_win32(log,mainClass,properties,parameters,update_only));
     }
   }
   
-  private void 
+  private boolean 
   restartAzureus_win32(
       PrintWriter log,
     String    mainClass,
@@ -476,14 +501,16 @@ AzureusRestarterImpl
 		}
 
 		if (exeUpdater != null) {
-			restartViaEXE(log, exeUpdater, properties, parameters, exec, update_only);
+			return( restartViaEXE(log, exeUpdater, properties, parameters, exec, update_only));
 		} else {
 			if (log != null) {
 				log.println("  " + exec);
 			}
 
 			if (!win32NativeRestart(log, exec)) {
-				javaSpawn(log, exec);
+				return( javaSpawn(log, exec));
+			}else{
+				return( true );
 			}
 		}
 	}
@@ -512,7 +539,7 @@ AzureusRestarterImpl
 		}
 	}
 
-	private void 
+	private boolean 
   restartAzureus_OSX(
       PrintWriter log,
     String mainClass,
@@ -532,7 +559,7 @@ AzureusRestarterImpl
     	 exec += " \"" + parameters[i] + "\"";
      }
 
-     runExternalCommandViaUnixShell( log, exec );
+     return( runExternalCommandViaUnixShell( log, exec ));
   }
   
   
@@ -547,7 +574,7 @@ AzureusRestarterImpl
 		return version;
   }
 
-  private void 
+  private boolean 
   restartAzureus_Unix(
     PrintWriter log,
   String    mainClass,
@@ -582,8 +609,10 @@ AzureusRestarterImpl
 					+ "echo \"Restarting Azureus..\"\n"
 					+ "$0\n");
 			ScriptAfterShutdown.setRequiresExit(true);
+			
+			return( true );
   	} else {
-  		runExternalCommandViaUnixShell( log, exec );
+  		return( runExternalCommandViaUnixShell( log, exec ));
   	}
   }
   
@@ -710,7 +739,7 @@ AzureusRestarterImpl
   */
   
   
-  private void runExternalCommandViaUnixShell( PrintWriter log, String command ) {
+  private boolean runExternalCommandViaUnixShell( PrintWriter log, String command ) {
   	String[] to_run = new String[3];
   	to_run[0] = "/bin/sh";
   	to_run[1] = "-c";
@@ -721,6 +750,8 @@ AzureusRestarterImpl
   	try {
   		//NOTE: no logging done here, as we need the method to return right away, before the external process completes
   		Runtime.getRuntime().exec( to_run );	
+  		
+  		return( true );
   	}
   	catch(Throwable t) {
   		if( log != null )  {
@@ -731,6 +762,8 @@ AzureusRestarterImpl
   		else {
   			t.printStackTrace();
   		}
+  		
+  		return( false );
   	}
   }
   
diff --git a/com/aelitis/azureus/core/util/AEPriorityMixin.java b/com/aelitis/azureus/core/util/AEPriorityMixin.java
new file mode 100644
index 0000000..426c699
--- /dev/null
+++ b/com/aelitis/azureus/core/util/AEPriorityMixin.java
@@ -0,0 +1,33 @@
+/*
+ * Created on Sep 9, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.util;
+
+public interface 
+AEPriorityMixin 
+{
+	public static final int PRIORITY_LOW	= 1;
+	public static final int PRIORITY_NORMAL	= 2;
+	public static final int PRIORITY_HIGH	= 3;
+	
+	public int
+	getPriority();
+}
diff --git a/com/aelitis/azureus/core/util/AZ3Functions.java b/com/aelitis/azureus/core/util/AZ3Functions.java
index 3254f56..b3bcfa2 100644
--- a/com/aelitis/azureus/core/util/AZ3Functions.java
+++ b/com/aelitis/azureus/core/util/AZ3Functions.java
@@ -46,6 +46,8 @@ AZ3Functions
 	public interface
 	provider
 	{
+		public static int SERVICE_SITE_RELATIVE = 27;
+
 		public void
 		subscribeToRSS(
 			String		name,
@@ -56,17 +58,45 @@ AZ3Functions
 		
 			throws Exception;
 		
+		public void
+		openRemotePairingWindow();
+		
 		public boolean
-		canShowCDP(
-			DownloadManager		dm );
+		canPlay(
+			DownloadManager		dm,
+			int					file_index );
 		
 		public void
-		showCDP(
+		play(
 			DownloadManager		dm,
-			String				ref );
+			int					file_index );
+
+		public TranscodeTarget[]
+		getTranscodeTargets();
+		
+		public interface
+		TranscodeTarget
+		{
+			public String
+			getName();
+			
+			public TranscodeProfile[]
+			getProfiles();
+		}
 		
+		public interface
+		TranscodeProfile
+		{
+			public String
+			getUID();
+			
+			public String
+			getName();
+		}
+
 		public String
-		getCDPURL(
-			DownloadManager		dm );
+		getDefaultContentNetworkURL(
+				int type, 
+				Object[] params);
 	}
 }
diff --git a/com/aelitis/azureus/core/util/CopyOnWriteList.java b/com/aelitis/azureus/core/util/CopyOnWriteList.java
index 300c770..48ce82d 100644
--- a/com/aelitis/azureus/core/util/CopyOnWriteList.java
+++ b/com/aelitis/azureus/core/util/CopyOnWriteList.java
@@ -23,10 +23,7 @@
 package com.aelitis.azureus.core.util;
 
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 
 import org.gudy.azureus2.core3.util.AEDiagnostics;
 import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
@@ -48,6 +45,8 @@ implements Iterable<T>
 	
 	private static CopyOnWriteList stats;
 	
+	private int	mutation_count;
+	
 	static {
 		if (LOG_STATS) {
 			stats = new CopyOnWriteList(10);
@@ -99,12 +98,20 @@ implements Iterable<T>
 		}
 	}
 
+	public int
+	getMutationCount()
+	{
+		return( mutation_count );
+	}
+	
 	public void
 	add(
 		T	obj )
 	{
 		synchronized( this ){
 			
+			mutation_count++;
+			
 			if ( visible ){
 				
 				List<T>	new_list = new ArrayList<T>( list );
@@ -126,6 +133,67 @@ implements Iterable<T>
 			}
 		}
 	}
+
+	public void
+	add(
+		int	index,
+		T	obj )
+	{
+		synchronized( this ){
+			
+			mutation_count++;
+			
+			if ( visible ){
+				
+				List<T>	new_list = new ArrayList<T>( list );
+				
+				//mutated();
+				
+				new_list.add( index, obj );
+			
+				list	= new_list;
+			
+				visible = false;
+				
+			}else{
+				if (list == Collections.EMPTY_LIST) {
+					list = new ArrayList<T>(initialCapacity);
+				}
+				
+				list.add( index, obj );
+			}
+		}
+	}
+	
+	public void
+	addAll(
+		Collection<T>	c )
+	{
+		synchronized( this ){
+			
+			mutation_count++;
+			
+			if ( visible ){
+				
+				List<T>	new_list = new ArrayList<T>( list );
+				
+				//mutated();
+				
+				new_list.addAll( c );
+			
+				list	= new_list;
+			
+				visible = false;
+				
+			}else{
+				if (list == Collections.EMPTY_LIST) {
+					list = new ArrayList<T>(initialCapacity);
+				}
+				
+				list.addAll( c );
+			}
+		}
+	}
 	
 	public T
 	get(
@@ -143,6 +211,8 @@ implements Iterable<T>
 	{
 		synchronized( this ){
 			
+			mutation_count++;
+			
 			if ( visible ){
 
 				List<T>	new_list = new ArrayList<T>( list );
@@ -168,7 +238,9 @@ implements Iterable<T>
 	clear()
 	{
 		synchronized( this ){
-								
+				
+			mutation_count++;
+			
 			list	= Collections.EMPTY_LIST;
 			
 			visible = false;
diff --git a/com/aelitis/azureus/core/util/DNSUtils.java b/com/aelitis/azureus/core/util/DNSUtils.java
index fbeee55..268fba2 100644
--- a/com/aelitis/azureus/core/util/DNSUtils.java
+++ b/com/aelitis/azureus/core/util/DNSUtils.java
@@ -21,12 +21,15 @@
 
 package com.aelitis.azureus.core.util;
 
+import java.io.IOException;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
@@ -35,6 +38,8 @@ import javax.naming.directory.Attributes;
 import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
 
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminException;
+
 public class 
 DNSUtils 
 {
@@ -114,4 +119,104 @@ DNSUtils
 		
 		throw( new UnknownHostException( host ));
 	}
+	
+	private static Map<String,String>	test_records = new HashMap<String,String>();
+	
+	static{
+		test_records.put( "test1.test.null", "BITTORRENT DENY ALL" );
+		test_records.put( "test2.test.null", "BITTORRENT" );
+		test_records.put( "test3.test.null", "BITTORRENT TCP:1 TCP:2 UDP:1 UDP:2" );
+		test_records.put( "test4.test.null", "BITTORRENT TCP:3" );
+		test_records.put( "test5.test.null", "BITTORRENT UDP:4" );
+	}
+	
+	public static List<String>
+	getTXTRecords(
+		String		query )
+	{
+		// System.out.println( "DNSTXTQuery: " + query );
+		
+		List<String>	result = new ArrayList<String>();
+	
+		String test_reply = test_records.get( query );
+
+		if ( test_reply != null ){
+			
+			result.add( test_reply );
+			
+			return( result );
+		}
+		
+		DirContext context = null;
+		
+		try{
+			context = DNSUtils.getInitialDirContext();
+			
+			Attributes attrs = context.getAttributes( query, new String[]{ "TXT" });
+			
+			NamingEnumeration n_enum = attrs.getAll();
+
+			while( n_enum.hasMoreElements()){
+				
+				Attribute	attr =  (Attribute)n_enum.next();
+
+				NamingEnumeration n_enum2 = attr.getAll();
+				
+				while( n_enum2.hasMoreElements()){
+				
+					String attribute = (String)n_enum2.nextElement();
+
+					if ( attribute != null ){
+						
+						attribute = attribute.trim();
+						
+						if ( attribute.startsWith( "\"" )){
+							
+							attribute = attribute.substring(1);
+						}
+						
+						if ( attribute.endsWith( "\"" )){
+							
+							attribute = attribute.substring(0,attribute.length()-1);
+						}
+						
+						if ( attribute.length() > 0 ){
+														
+							result.add( attribute );
+						}
+					}
+				}
+			}
+						
+		}catch( Throwable e ){
+				
+			//e.printStackTrace();
+			
+		}finally{
+			
+			if ( context != null ){
+				
+				try{
+					context.close();
+					
+				}catch( Throwable e ){
+				}
+			}
+		}
+		
+		return( result );
+	}
+	
+	public static void
+	main(
+		String[]	args )
+	{
+		//List<String> records = getTXTRecords( "tracker.openbittorrent.com" );
+		List<String> records = getTXTRecords( "www.ibm.com" );
+		
+		for ( String record: records ){
+			
+			System.out.println( record );
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/util/DeleteFileOnCloseInputStream.java b/com/aelitis/azureus/core/util/DeleteFileOnCloseInputStream.java
index 89c1081..6cc156f 100644
--- a/com/aelitis/azureus/core/util/DeleteFileOnCloseInputStream.java
+++ b/com/aelitis/azureus/core/util/DeleteFileOnCloseInputStream.java
@@ -23,6 +23,7 @@
 
 package com.aelitis.azureus.core.util;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -48,7 +49,7 @@ DeleteFileOnCloseInputStream
 		throws IOException
 	{
 		file		= _file;
-		in			= new FileInputStream( file );
+		in			= new BufferedInputStream( new FileInputStream( file ), 128*1024 );
 	}
 	
 	public void 
diff --git a/com/aelitis/azureus/core/util/FeatureAvailability.java b/com/aelitis/azureus/core/util/FeatureAvailability.java
index 5375c27..c83c322 100644
--- a/com/aelitis/azureus/core/util/FeatureAvailability.java
+++ b/com/aelitis/azureus/core/util/FeatureAvailability.java
@@ -35,9 +35,32 @@ FeatureAvailability
 	private static final long	FT_DISABLE_RCM						= 0x0000000000000010;
 	private static final long	FT_DISABLE_DHT_REP_V2				= 0x0000000000000020;
 	private static final long	FT_DISABLE_MAGNET_SL				= 0x0000000000000040;
+	private static final long	FT_ENABLE_ALL_FE_CLIENTS			= 0x0000000000000080;
+	
+	private static final long	FT_ENABLE_INTERNAL_FEATURES			= 0x0000000000000100;
+	
+	private static final long	FT_TRIGGER_SPEED_TEST_V1			= 0x0000000000000200;
+	private static final long	FT_DISABLE_GAMES					= 0x0000000000000400;
+	private static final long	FT_DISABLE_MAGNET_MD				= 0x0000000000000800;
 	
 	private static VersionCheckClient vcc = VersionCheckClient.getSingleton();
 	
+	/*
+	public static final boolean 
+	ENABLE_PLUS()
+	{
+		return( true );
+	}
+	*/
+	
+	public static boolean
+	areInternalFeaturesEnabled()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_ENABLE_INTERNAL_FEATURES ) != 0;
+				
+		return( result );
+	}
+	
 	public static boolean
 	isRequestLimitingEnabled()
 	{
@@ -93,4 +116,36 @@ FeatureAvailability
 				
 		return( result );
 	}
+	
+	public static boolean
+	isMagnetMDEnabled()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_DISABLE_MAGNET_MD ) == 0;
+				
+		return( result );
+	}
+	
+	public static boolean
+	allowAllFEClients()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_ENABLE_ALL_FE_CLIENTS ) != 0;
+		
+		return( result );
+	}
+	
+	public static boolean
+	triggerSpeedTestV1()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_TRIGGER_SPEED_TEST_V1 ) != 0;
+		
+		return( result );
+	}
+
+	public static boolean
+	isGamesEnabled()
+	{
+		final boolean result = ( vcc.getFeatureFlags() & FT_DISABLE_GAMES ) == 0;
+		
+		return( result );
+	}
 }
diff --git a/com/aelitis/azureus/core/util/GeneralUtils.java b/com/aelitis/azureus/core/util/GeneralUtils.java
index 1948591..b0f1f81 100644
--- a/com/aelitis/azureus/core/util/GeneralUtils.java
+++ b/com/aelitis/azureus/core/util/GeneralUtils.java
@@ -21,8 +21,16 @@
 
 package com.aelitis.azureus.core.util;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.regex.Pattern;
 
+import org.gudy.azureus2.core3.util.Constants;
+
 public class 
 GeneralUtils 
 {
@@ -152,5 +160,154 @@ GeneralUtils
 		return Pattern.compile(REGEX_URLHTML, Pattern.CASE_INSENSITIVE).matcher(
 				message).replaceAll("$2");
 	}
+	
+		/**
+		 * splits space separated tokens respecting quotes (either " or ' )
+		 * @param str
+		 * @return
+		 */
+		
+	public static String[]
+	splitQuotedTokens(
+		String		str )
+	{
+		List<String>	bits = new ArrayList<String>();
+		
+		char	quote 				= ' ';
+		boolean	escape 				= false;
+		boolean	bit_contains_quotes = false;
+			
+		String	bit = "";
+		
+		char[] chars = str.toCharArray();
+		
+		for (int i=0;i<chars.length;i++){
+			
+			char c = chars[i];
+			
+			if ( Character.isWhitespace(c)){
+				
+				c = ' ';
+			}
+			
+			if ( escape ){
+				
+				bit += c;
+				
+				escape = false;
+				
+				continue;
+				
+			}else if ( c == '\\' ){
+				
+				escape = true;
+				
+				continue;
+			}
+			
+			if ( c == '"' || c == '\'' && ( i == 0 || chars[ i-1 ] != '\\' )){
+				
+				if ( quote == ' ' ){
+						
+					bit_contains_quotes = true;
+					
+					quote = c;
+					
+				}else if ( quote == c ){
+										
+					quote = ' ';
+					
+				}else{
+					
+					bit += c;
+				}
+			}else{
+				
+				if ( quote == ' ' ){
+					
+					if ( c == ' ' ){
+						
+						if ( bit.length() > 0 || bit_contains_quotes ){
+							
+							bit_contains_quotes = false;
+							
+							bits.add( bit );
+							
+							bit = "";
+						}
+					}else{
+					
+						bit += c;
+					}
+				}else{
+					
+					bit += c;
+				}
+			}
+		}	
+		
+		if ( quote != ' ' ){
+			
+			bit += quote;
+		}
 		
+		if ( bit.length() > 0 || bit_contains_quotes ){
+			
+			bits.add( bit );
+		}
+		
+		return( bits.toArray( new String[bits.size()]));
+	}
+	
+	public static ProcessBuilder 
+	createProcessBuilder(
+		File workingDir,
+		String[] cmd, 
+		String[] extra_env) 
+	
+		throws IOException 
+	{
+		ProcessBuilder pb;
+
+		Map<String, String> newEnv = new HashMap<String, String>();
+		newEnv.putAll(System.getenv());
+		newEnv.put("LANG", "C.UTF-8");
+		if (extra_env != null && extra_env.length > 1) {
+			for (int i = 1; i < extra_env.length; i += 2) {
+				newEnv.put(extra_env[i - 1], extra_env[i]);
+			}
+		}
+
+		if ( Constants.isWindows ){
+			String[] i18n = new String[cmd.length + 2];
+			i18n[0] = "cmd";
+			i18n[1] = "/C";
+			i18n[2] = escapeDosCmd(cmd[0]);
+			for (int counter = 1; counter < cmd.length; counter++) {
+				if (cmd[counter].length() == 0) {
+					i18n[counter + 2] = "";
+				} else {
+					String envName = "JENV_" + counter;
+					i18n[counter + 2] = "%" + envName + "%";
+					newEnv.put(envName, cmd[counter]);
+				}
+			}
+			cmd = i18n;
+		}
+
+		pb = new ProcessBuilder(cmd);
+		Map<String, String> env = pb.environment();
+		env.putAll(newEnv);
+
+		if (workingDir != null) {
+			pb.directory(workingDir);
+		}
+		return pb;
+	}
+
+	private static String escapeDosCmd(String string) {
+		String s = string.replaceAll("([&%^])", "^$1");
+		s = s.replaceAll("'", "\"'\"");
+		return s;
+	}
 }
diff --git a/com/aelitis/azureus/core/util/LaunchManager.java b/com/aelitis/azureus/core/util/LaunchManager.java
new file mode 100644
index 0000000..c0017c6
--- /dev/null
+++ b/com/aelitis/azureus/core/util/LaunchManager.java
@@ -0,0 +1,152 @@
+/*
+ * Created on Mar 1, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.util;
+
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.util.AEThread2;
+
+public class 
+LaunchManager 
+{
+	private static LaunchManager	singleton = new LaunchManager();
+	
+	public static LaunchManager
+	getManager()
+	{
+		return( singleton );
+	}
+	
+	private CopyOnWriteList<LaunchController>	controllers	= new CopyOnWriteList<LaunchController>();
+	
+	public void
+	launchRequest(
+		final LaunchTarget	target,
+		final LaunchAction	action )
+	{
+		new AEThread2( "LaunchManager:request" )
+		{
+			public void
+			run()
+			{
+				for ( LaunchController c: controllers ){
+					
+					try{
+						c.handleRequest( target );
+						
+					}catch( Throwable e ){
+						
+						action.actionDenied( e );
+						
+						return;
+					}
+				}
+				
+				action.actionAllowed();
+			}
+		}.start();
+	}
+	
+	public LaunchTarget
+	createTarget(
+		DownloadManager		dm )
+	{
+		return( new LaunchTarget( dm ));
+	}
+	
+	public LaunchTarget
+	createTarget(
+		DiskManagerFileInfo		fi )
+	{
+		return( new LaunchTarget( fi ));
+	}
+	
+	public void
+	addController(
+		LaunchController	controller )
+	{
+		controllers.add( controller );
+	}
+	
+	public void
+	removeController(
+		LaunchController	controller )
+	{
+		controllers.remove( controller );
+	}
+	
+	public class
+	LaunchTarget
+	{
+		private DownloadManager			dm;
+		private DiskManagerFileInfo		file_info;
+		
+		private 
+		LaunchTarget(
+			DownloadManager		_dm )
+		{
+			dm		= _dm;
+		}
+		
+		private 
+		LaunchTarget(
+			DiskManagerFileInfo		_file_info )
+		{
+			file_info	= _file_info;	
+			dm			= file_info.getDownloadManager();
+		}
+		
+		public DownloadManager
+		getDownload()
+		{
+			return( dm );
+		}
+		
+		public DiskManagerFileInfo
+		getFile()
+		{
+			return( file_info );
+		}
+	}
+	
+	public interface
+	LaunchController
+	{
+		public void
+		handleRequest(
+			LaunchTarget		target )
+		
+			throws Throwable;
+	}
+	
+	public interface
+	LaunchAction
+	{
+		public void
+		actionAllowed();
+		
+		public void
+		actionDenied(
+			Throwable			reason );
+			
+	}
+}
diff --git a/com/aelitis/azureus/core/util/NetUtils.java b/com/aelitis/azureus/core/util/NetUtils.java
index 93f4199..1429fd9 100644
--- a/com/aelitis/azureus/core/util/NetUtils.java
+++ b/com/aelitis/azureus/core/util/NetUtils.java
@@ -26,12 +26,175 @@ package com.aelitis.azureus.core.util;
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
+import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.Enumeration;
+import java.util.List;
+
+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.SystemTime;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl.runnableWithException;
 
 public class 
 NetUtils 
 {
+	private static final int MIN_NI_CHECK_MILLIS 	= 30*1000;
+	private static final int INC1_NI_CHECK_MILLIS 	= 2*60*1000;
+	private static final int INC2_NI_CHECK_MILLIS 	= 15*60*1000;
+	
+	private static int	current_check_millis = MIN_NI_CHECK_MILLIS;
+	
+	private static long	last_ni_check	= -1;
+	
+	private static volatile List<NetworkInterface>		current_interfaces = new ArrayList<NetworkInterface>();
+	
+	private static boolean						first_check	= true;
+	private static boolean						check_in_progress;
+	
+	private static AESemaphore					ni_sem = new AESemaphore( "NetUtils:ni" );
+	
+	public static List<NetworkInterface>
+	getNetworkInterfaces()
+	
+		throws SocketException
+	{
+		long	now = SystemTime.getMonotonousTime();
+		
+		boolean	do_check 	= false;
+		boolean	is_first	= false;
+		
+		synchronized( NetUtils.class ){
+			
+			if ( !check_in_progress ){
+				
+				if ( last_ni_check < 0 || now - last_ni_check > current_check_millis ){
+									
+					do_check 			= true;
+					check_in_progress	= true;
+					
+					if ( first_check ){
+						
+						first_check = false;
+						is_first	= true;
+					}
+				}
+			}
+		}
+		
+		if ( do_check ){
+			
+			final runnableWithException<SocketException> do_it = 
+				new runnableWithException<SocketException>()
+				{
+					public void
+					run()
+					
+						throws SocketException
+					{
+						List<NetworkInterface> result = new ArrayList<NetworkInterface>();
+			
+						try{
+								// got some major CPU issues on some machines with crap loads of NIs
+							
+							long	start 	= SystemTime.getHighPrecisionCounter();
+							
+							Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
+							
+							long	elapsed_millis = ( SystemTime.getHighPrecisionCounter() - start ) / 1000000;
+								
+							long	old_period = current_check_millis;
+							
+							if ( elapsed_millis > 1000 && current_check_millis <  INC2_NI_CHECK_MILLIS ){
+													
+								current_check_millis = INC2_NI_CHECK_MILLIS;
+								
+							}else if ( elapsed_millis > 250 && current_check_millis < INC1_NI_CHECK_MILLIS ){
+								
+								current_check_millis = INC1_NI_CHECK_MILLIS;
+							}
+							
+							if ( old_period != current_check_millis ){
+								
+								Debug.out( "Network interface enumeration took " + elapsed_millis + ": decreased refresh frequency to " + current_check_millis + "ms" );
+							}
+							
+							if ( nis != null ){
+								
+								while( nis.hasMoreElements()){
+									
+									result.add( nis.nextElement());
+								}
+							}
+							
+							// System.out.println( "getNI: elapsed=" + elapsed_millis + ", result=" + result.size());
+			
+						}finally{
+							
+							synchronized( NetUtils.class ){
+							
+								check_in_progress	= false;
+								current_interfaces 	= result;
+								
+								last_ni_check	= SystemTime.getMonotonousTime();
+							}
+				
+							ni_sem.releaseForever();
+						}	
+					}
+				};
+				
+			if ( is_first ){
+				
+				final AESemaphore do_it_sem = new AESemaphore( "getNIs" );
+
+				final SocketException[]	error = { null };
+				
+				new AEThread2( "getNIAsync" )
+				{
+					public void
+					run()
+					{
+						try{
+							do_it.run();
+							
+						}catch( SocketException e ){
+							
+							error[0] = e;
+							
+						}finally{
+							
+							do_it_sem.release();
+						}
+					}
+				}.start();
+				
+				if ( !do_it_sem.reserve( 15*1000 )){
+					
+					Debug.out( "Timeout obtaining network interfaces" );
+					
+					ni_sem.releaseForever();
+										
+				}else{
+					
+					if ( error[0] != null ){
+						
+						throw( error[0] );
+					}
+				}
+			}else{
+				
+				do_it.run();
+			}
+		}
+		
+		ni_sem.reserve();
+		
+		return( current_interfaces );
+	}
+	
 	public static InetAddress
 	getLocalHost()
 	
@@ -46,11 +209,9 @@ NetUtils
 				// return first non-loopback one
 			
 			try{
-				Enumeration 	nis = NetworkInterface.getNetworkInterfaces();
+				List<NetworkInterface> 	nis = getNetworkInterfaces();
 
-				while( nis.hasMoreElements()){
-					
-					NetworkInterface	 ni = (NetworkInterface)nis.nextElement();
+				for ( NetworkInterface ni: nis ){
 						
 					Enumeration addresses = ni.getInetAddresses();
 					
diff --git a/com/aelitis/azureus/core/util/QTFastStartRAF.java b/com/aelitis/azureus/core/util/QTFastStartRAF.java
new file mode 100644
index 0000000..4ec8d5d
--- /dev/null
+++ b/com/aelitis/azureus/core/util/QTFastStartRAF.java
@@ -0,0 +1,656 @@
+/*
+ * Created on Jan 19, 2011
+ * Created by Paul Gardner
+ * 
+ * Copyright 2011 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.util;
+
+import java.io.*;
+import java.util.*;
+
+import org.gudy.azureus2.core3.util.Debug;
+
+/*
+ * The original code by Mike Melanson (melanson at pcisys.net) was placed in the
+ * public domain and so is this Java port of it. 
+ */
+
+
+public class 
+QTFastStartRAF 
+{	
+	private static final Set<String>	supported_extensions = new HashSet<String>();
+	
+	static{
+		supported_extensions.add( "mov" );
+		supported_extensions.add( "qt" );
+		supported_extensions.add( "mp4" );
+	}
+	
+	private static Set<String>	tested = new HashSet<String>();
+	
+	public static boolean
+	isSupportedExtension(
+		String		extension )
+	{
+		return( supported_extensions.contains( extension.toLowerCase()));
+	}
+	
+	private static final String ATOM_FREE = "free";
+	private static final String ATOM_JUNK = "junk";
+	private static final String ATOM_MDAT = "mdat";
+	private static final String ATOM_MOOV = "moov";
+	private static final String ATOM_PNOT = "pnot";
+	private static final String ATOM_SKIP = "skip";
+	private static final String ATOM_WIDE = "wide";
+	private static final String ATOM_PICT = "PICT";
+	private static final String ATOM_FTYP = "ftyp";
+
+	private static final String ATOM_CMOV = "cmov";
+	private static final String ATOM_STCO = "stco";
+	private static final String ATOM_CO64 = "co64";
+
+	private static final String[] VALID_TOPLEVEL_ATOMS = {
+		ATOM_FREE, ATOM_JUNK, ATOM_MDAT, ATOM_MOOV,
+		ATOM_PNOT, ATOM_SKIP, ATOM_WIDE, ATOM_PICT,
+		ATOM_FTYP };
+
+	private FileAccessor	input;
+	
+	private boolean		transparent;
+	
+	private byte[]		header;
+	private long		body_start;
+	private long		body_end;
+	
+	private long		seek_position;
+	
+	public
+	QTFastStartRAF(
+		File		file,
+		boolean		enable )
+	
+		throws IOException
+	{
+		this( new RAFAccessor( file ), enable );
+	}
+	
+	public
+	QTFastStartRAF(
+		FileAccessor	accessor,
+		boolean			enable )
+	
+		throws IOException
+	{
+		input = accessor;
+		
+		if ( enable ){
+			
+			String	name = accessor.getName();
+			
+			boolean	log;
+			String	fail	= null;
+			
+			synchronized( tested ){
+				
+				log = !tested.contains( name );
+				
+				if ( log ){
+					
+					tested.add( name );
+				}
+			}
+						
+			try{
+				Atom ah = null;
+				Atom ftypAtom = null;
+				
+				boolean gotFtyp = false;
+				boolean gotMdat = false;
+				boolean justCopy = false;
+				
+				while (input.getFilePointer() < input.length()) {
+					
+					ah = new Atom(input);
+					
+					// System.out.println( "got " + ah.type +", size=" + ah.size );
+					
+					if (!isValidTopLevelAtom(ah)) {
+						throw new IOException("Non top level QT atom found (" + ah.type + "). File invalid?");
+					}
+					
+					if (gotFtyp && !gotMdat && ah.type.equalsIgnoreCase(ATOM_MOOV)) {
+						justCopy = true;
+						break;
+					}
+					
+					// store ftyp atom to buffer
+					if (ah.type.equalsIgnoreCase(ATOM_FTYP)) {
+						ftypAtom = ah;
+						ftypAtom.fillBuffer(input);
+						gotFtyp = true;
+					} else if (ah.type.equalsIgnoreCase(ATOM_MDAT)) {
+						gotMdat = true;
+						input.skipBytes((int)ah.size);
+					} else {
+						input.skipBytes((int)ah.size);
+					}
+				}
+				
+				if ( justCopy ){
+					
+					transparent	= true;
+					
+					return;
+				}
+			
+				if ( !ah.type.equalsIgnoreCase(ATOM_MOOV)){
+					
+					throw new IOException("Last QT atom was not the MOOV atom.");
+				}
+		
+				input.seek(ah.offset);
+						
+				Atom moovAtom = ah;
+				
+				moovAtom.fillBuffer(input);
+		
+				if (isCompressedMoovAtom(moovAtom)){
+					
+					throw new IOException("Compressed MOOV qt atoms are not supported");
+				}
+				
+				patchMoovAtom(moovAtom);
+				
+				body_start 	= ftypAtom.offset+ftypAtom.size;
+				body_end	= moovAtom.offset;
+				
+				header = new byte[ftypAtom.buffer.length + moovAtom.buffer.length];
+				
+				System.arraycopy( ftypAtom.buffer, 0, header, 0, ftypAtom.buffer.length );
+				System.arraycopy( moovAtom.buffer, 0, header, ftypAtom.buffer.length, moovAtom.buffer.length );
+				
+				if ( accessor.length() != header.length + ( body_end - body_start )){
+					
+					throw( new IOException( "Inconsistent: file size has changed" ));
+				}
+					
+			}catch( Throwable e ){
+				
+				//e.printStackTrace();
+				
+				fail = Debug.getNestedExceptionMessage( e );
+				
+				transparent	= true;
+				
+			}finally{
+				
+				input.seek( 0 );
+				
+				if ( log ){
+					
+					String	message;
+					
+					if ( fail == null ){
+						
+						message = transparent?"Not required":"Required";
+						
+					}else{
+						
+						message = "Failed - " + fail;
+					}
+					
+					Debug.outNoStack( "MOOV relocation for " + accessor.getName() + ": " + message );
+				}
+			}
+		}else{
+			
+			transparent = true;
+		}
+	}
+	
+	private boolean isCompressedMoovAtom(Atom moovAtom) {
+		
+		byte[] cmovBuffer = copyOfRange(moovAtom.buffer, 12, 15);
+		
+		if (new String(cmovBuffer).equalsIgnoreCase(ATOM_CMOV)) {
+			return true;
+		}
+		
+		return false;
+	}
+
+	private boolean isValidTopLevelAtom(Atom ah) {
+				
+		for (String validAtom: VALID_TOPLEVEL_ATOMS) {
+			if (validAtom.equalsIgnoreCase(ah.type)) {
+				return true;
+			}
+		}
+		return false;
+		
+	}
+	
+	private void patchMoovAtom(Atom moovAtom) {
+		
+		int idx = 0;
+		for (idx = 4; idx < moovAtom.size-4; idx++) {
+			byte[] buffer = copyOfRange(moovAtom.buffer, idx, idx+4);
+			if (new String(buffer).equalsIgnoreCase(ATOM_STCO)) {
+				int stcoSize = patchStcoAtom(moovAtom, idx);
+				idx += stcoSize - 4; 
+			} else if (new String(buffer).equalsIgnoreCase(ATOM_CO64)) {
+				int co64Size = patchCo64Atom(moovAtom, idx);
+				idx += co64Size - 4;
+			}
+		}
+		
+	}
+	
+	private int patchStcoAtom(Atom ah, int idx) {
+		int stcoSize = (int)bytesToLong(copyOfRange(ah.buffer, idx-4, idx));
+		
+		int offsetCount = (int)bytesToLong(copyOfRange(ah.buffer, idx + 8, idx+12));
+		for (int j = 0; j < offsetCount; j++) {
+			int currentOffset = (int)bytesToLong(copyOfRange(ah.buffer, idx + 12 + j * 4, (idx + 12 + j * 4)+4));
+			currentOffset += ah.size;
+			int offsetIdx = idx + 12 + j * 4;
+			ah.buffer[offsetIdx + 0] = (byte)((currentOffset >> 24) & 0xFF);
+			ah.buffer[offsetIdx + 1] = (byte)((currentOffset >> 16) & 0xFF);
+			ah.buffer[offsetIdx + 2] = (byte)((currentOffset >>  8) & 0xFF);
+			ah.buffer[offsetIdx + 3] = (byte)((currentOffset >>  0) & 0xFF);
+		}
+		
+		return stcoSize;
+	}
+
+	private int patchCo64Atom(Atom ah, int idx) {
+		int co64Size = (int)bytesToLong(copyOfRange(ah.buffer, idx-4, idx));
+
+		int offsetCount = (int)bytesToLong(copyOfRange(ah.buffer, idx + 8, idx+12));
+		for (int j = 0; j < offsetCount; j++) {
+			long currentOffset = bytesToLong(copyOfRange(ah.buffer, idx + 12 + j * 8, (idx + 12 + j * 8)+8));
+			currentOffset += ah.size;
+			int offsetIdx = idx + 12 + j * 8;
+			ah.buffer[offsetIdx + 0] = (byte)((currentOffset >> 56) & 0xFF);
+			ah.buffer[offsetIdx + 1] = (byte)((currentOffset >> 48) & 0xFF);
+			ah.buffer[offsetIdx + 2] = (byte)((currentOffset >> 40) & 0xFF);
+			ah.buffer[offsetIdx + 3] = (byte)((currentOffset >> 32) & 0xFF);
+			ah.buffer[offsetIdx + 4] = (byte)((currentOffset >> 24) & 0xFF);
+			ah.buffer[offsetIdx + 5] = (byte)((currentOffset >> 16) & 0xFF);
+			ah.buffer[offsetIdx + 6] = (byte)((currentOffset >>  8) & 0xFF);
+			ah.buffer[offsetIdx + 7] = (byte)((currentOffset >>  0) & 0xFF);
+		}
+		
+		return co64Size;
+	}
+	
+	public static byte[] copyOfRange(byte[] original, int from, int to) {
+		int newLength = to - from;
+		if (newLength < 0)
+			throw new IllegalArgumentException(from + " > " + to);
+		byte[] copy = new byte[newLength];
+		System.arraycopy(original, from, copy, 0,
+				Math.min(original.length - from, newLength));
+		return copy;
+	}
+	
+	private long bytesToLong(byte[] buffer) {
+		
+		long retVal = 0;
+		
+		for ( int i = 0; i < buffer.length; i++ ) {
+			retVal += ((buffer[i] & 0x00000000000000FF) << 8*(buffer.length-i-1)) ;
+		}
+		
+		return retVal;
+		
+	}
+
+	public void
+	seek(
+		long		pos )
+	
+		throws IOException
+	{
+		if ( transparent ){
+			
+			input.seek( pos );
+			
+		}else{
+		
+			seek_position = pos;
+		}
+	}
+	
+	public int
+	read(
+		byte[]			buffer,
+		int				pos,
+		int				len )
+	
+		throws IOException
+	{
+		if ( transparent ){
+			
+			return( input.read( buffer, pos, len ));
+		}
+		
+			// [header]
+			// file [body-start -> body-end]
+		
+		long	start_pos	= seek_position;
+		int		start_len 	= len;
+		
+		if ( seek_position < header.length ){
+		
+			int	rem = (int)( header.length - seek_position );
+			
+			if ( rem > len ){
+				
+				rem = len;
+			}
+			
+			System.arraycopy( header, (int)seek_position, buffer, pos, rem );
+			
+			pos += rem;
+			len	-= rem;
+			
+			seek_position += rem;
+		}
+		
+		if ( len > 0 ){
+			
+			long	file_position = body_start + seek_position - header.length;
+			
+			long	rem = body_end - file_position;
+			
+			if ( len < rem ){
+				
+				rem = len;
+			}
+			
+			input.seek( file_position );
+			
+			int	temp = input.read( buffer, pos, (int)rem );
+			
+			pos += temp;
+			len	-= temp;
+			
+			seek_position += temp;
+		}
+		
+		int	read = start_len - len;
+		
+		seek_position = start_pos + read;
+		
+		return( read );
+	}
+	
+	public long
+	length()
+	
+		throws IOException
+	{
+		return( input.length());
+	}
+	
+	public void
+	close()
+	
+		throws IOException
+	{
+		input.close();
+	}
+	
+	private class 
+	Atom
+	{
+		
+		public long offset;
+		public long size;
+		public String type;
+		public byte[] buffer = null;
+		
+		public Atom(FileAccessor input) throws IOException {
+			offset = input.getFilePointer();
+			// get atom size
+			size = input.readInt();
+			// get atom type
+			byte[] atomTypeFCC = new byte[4];
+			input.readFully(atomTypeFCC);
+			type = new String(atomTypeFCC);
+			if (size == 1) {
+				// 64 bit size. Read new size from body and store it
+				size = input.readLong();
+			}
+			// skip back to atom start
+			input.seek(offset);
+		}
+		
+		public void fillBuffer(FileAccessor input) throws IOException {
+			buffer = new byte[(int)size];
+			input.readFully(buffer);
+		}
+	}
+	
+	private static class
+	RAFAccessor
+		implements FileAccessor
+	{
+		private File					file;
+		private RandomAccessFile		raf;
+		
+		private
+		RAFAccessor(
+			File			_file )
+		
+			throws IOException
+		{
+			file	= _file;
+			raf 	= new RandomAccessFile( file, "r" );
+		}
+		
+		public String
+		getName()
+		{
+			return( file.getAbsolutePath());
+		}
+		
+		public long
+		getFilePointer()
+		
+			throws IOException
+		{
+			return( raf.getFilePointer());
+		}
+		
+		public void
+		seek(
+			long		pos )
+		
+			throws IOException
+		{
+			raf.seek( pos );
+		}
+
+		public void
+		skipBytes(
+			int		num )
+		
+			throws IOException
+		{
+			raf.skipBytes( num );
+		}
+		
+		public long
+		length()
+		
+			throws IOException
+		{
+			return( raf.length());
+		}
+		
+		public int
+		read(
+			byte[]	buffer,
+			int		pos,
+			int		len )
+		
+			throws IOException
+		{
+			return( raf.read(buffer,pos,len));
+		}
+		
+		public int
+		readInt()
+		
+			throws IOException
+		{
+			return( raf.readInt());
+		}
+		
+		public long
+		readLong()
+			
+			throws IOException
+		{
+			return( raf.readLong());
+		}
+		
+		public void
+		readFully(
+			byte[]	buffer )
+		
+			throws IOException
+		{
+			raf.readFully( buffer );
+		}
+				
+		public void
+		close()
+		
+			throws IOException
+		{
+			raf.close();
+		}
+	}
+	
+	public interface
+	FileAccessor
+	{
+		public String
+		getName();
+		
+		public long
+		getFilePointer()
+		
+			throws IOException;
+		
+		public void
+		seek(
+			long		pos )
+		
+			throws IOException;
+
+		public void
+		skipBytes(
+			int		num )
+		
+			throws IOException;
+		
+		public long
+		length()
+		
+			throws IOException;
+		
+		public int
+		read(
+			byte[]	buffer,
+			int		pos,
+			int		len )
+		
+			throws IOException;
+		
+		public int
+		readInt()
+		
+			throws IOException;
+		
+		public long
+		readLong()
+		
+			throws IOException;
+		
+		public void
+		readFully(
+			byte[]	buffer )
+		
+			throws IOException;
+				
+		public void
+		close()
+		
+			throws IOException;
+	}
+	
+	public static void
+	main(
+		String[]		args )
+	{
+		try{	
+			QTFastStartRAF	raf = new QTFastStartRAF( new File( "C:\\temp\\spork.mp4" ), true );
+			
+			long	len = raf.length();
+			
+			byte[]	buffer = new byte[43];
+			
+			long	total = 0;
+			
+			FileOutputStream fos = new FileOutputStream(new File( "C:\\temp\\qtfs_out.mp4" ));
+			
+			while( true ){
+			
+				int	read = raf.read( buffer, 0, buffer.length );
+				
+				if ( read <= 0 ){
+					
+					break;
+				}
+				
+				fos.write( buffer, 0, read );
+				
+				total += read;
+			}
+			
+			if ( total != len ){
+				
+				System.out.println( "bork" );
+			}
+			
+			raf.close();
+			
+			fos.close();
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
+}
diff --git a/com/aelitis/azureus/core/util/RegExUtil.java b/com/aelitis/azureus/core/util/RegExUtil.java
new file mode 100644
index 0000000..255665a
--- /dev/null
+++ b/com/aelitis/azureus/core/util/RegExUtil.java
@@ -0,0 +1,134 @@
+/*
+ * Created on Nov 1, 2011
+ * Created by Paul Gardner
+ * 
+ * Copyright 2011 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.util;
+
+import java.util.*;
+import java.util.regex.Pattern;
+
+import org.gudy.azureus2.core3.util.Debug;
+
+public class 
+RegExUtil 
+{
+	private static ThreadLocal<Map<String,Object[]>>		tls	= 
+		new ThreadLocal<Map<String,Object[]>>()
+		{
+			public Map<String,Object[]>
+			initialValue()
+			{
+				return( new HashMap<String,Object[]>());
+			}
+		};
+		
+	public static Pattern
+	getCachedPattern(
+		String		namespace,
+		String		pattern )
+	{	
+		return( getCachedPattern( namespace, pattern, 0 ));
+	}
+	
+	public static Pattern
+	getCachedPattern(
+		String		namespace,
+		String		pattern,
+		int			flags )
+	{		
+		Map<String,Object[]> map = tls.get();
+		
+		Object[] entry = map.get( namespace );
+		
+		if ( entry == null || !pattern.equals((String)entry[0])){
+		
+			Pattern result = Pattern.compile( pattern, flags );
+			
+			map.put( namespace, new Object[]{ pattern, result });
+			
+			return( result );
+			
+		}else{
+			
+			return((Pattern)entry[1]);
+		}
+	}
+	
+	public static boolean
+	mightBeEvil(
+		String	str )
+	{
+			// http://en.wikipedia.org/wiki/ReDoS
+			
+		if ( !str.contains( ")" )){
+			
+			return( false );
+		}
+		
+		char[]	chars = str.toCharArray();
+		
+		Stack<Integer>	stack = new Stack<Integer>();
+		
+		for (int i=0;i<chars.length;i++){
+			
+			char c = chars[i];
+			
+			if ( c == '(' ){
+				
+				stack.push( i+1 );
+				
+			}else if ( c == ')' ){
+				
+				if ( stack.isEmpty()){
+					
+					Debug.out( "bracket un-matched in " + str + " - treating as evil" );
+					
+					return( true );
+					
+				}else{
+					
+					int	start = stack.pop();
+
+					if ( i < chars.length-1){
+						
+						char next = chars[i+1];
+						
+						if ( next == '*' || next == '+' || next == '{' ){
+										
+							for ( int j=start;j<i;j++){
+								
+								c = chars[j];
+								
+								if ( "+*{|".indexOf( c ) != -1 ){
+									
+									Debug.out( "regular expression " + str + " might be evil due to '" + str.substring( start-1, i+2) + "'" );
+
+									return( true );
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		return( false );
+	}
+}
diff --git a/com/aelitis/azureus/core/util/http/HTTPAuthHelper.java b/com/aelitis/azureus/core/util/http/HTTPAuthHelper.java
index c515464..2136012 100644
--- a/com/aelitis/azureus/core/util/http/HTTPAuthHelper.java
+++ b/com/aelitis/azureus/core/util/http/HTTPAuthHelper.java
@@ -385,7 +385,7 @@ HTTPAuthHelper
 		private Socket		socket_in;
 		private Socket		socket_out;
 		
-		private transient boolean	destroyed;
+		private volatile boolean	destroyed;
 		
 		protected
 		processor(
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
index e1ee6fd..ef7f9af 100644
--- a/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClient.java
@@ -64,7 +64,7 @@ import com.aelitis.net.udp.uc.PRUDPReleasablePacketHandler;
  */
 public class VersionCheckClient {
 	private static final LogIDs LOGID = LogIDs.CORE;
-	
+
 	public static final String	REASON_UPDATE_CHECK_START		= "us";
 	public static final String	REASON_UPDATE_CHECK_PERIODIC	= "up";
 	public static final String	REASON_CHECK_SWT				= "sw";
@@ -74,1375 +74,1603 @@ public class VersionCheckClient {
 	public static final String	REASON_RECOMMENDED_PLUGINS		= "rp";
 	public static final String	REASON_SECONDARY_CHECK			= "sc";
 	public static final String	REASON_PLUGIN_UPDATE			= "pu";
-	
-
-  private static final String 	AZ_MSG_SERVER_ADDRESS_V4 	= Constants.VERSION_SERVER_V4;
-  private static final int 		AZ_MSG_SERVER_PORT 			= 27001;
-  private static final String 	MESSAGE_TYPE_ID 			= "AZVER";
-  
-  public static final String 	HTTP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
-  public static final int 		HTTP_SERVER_PORT 			= 80;
-
-  public static final String 	TCP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
-  public static final int 		TCP_SERVER_PORT 			= 80;
-
-  public static final String 	UDP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
-  public static final int 		UDP_SERVER_PORT 			= 2080;
-
-  public static final String	AZ_MSG_SERVER_ADDRESS_V6 	= Constants.VERSION_SERVER_V6;
-  public static final String	HTTP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
-  public static final String	TCP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
-  public static final String	UDP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
-  
-  
-  private static final long		CACHE_PERIOD	= 5*60*1000;
-  private static boolean secondary_check_done;
-  
-  
-  static{
-	  VersionCheckClientUDPCodecs.registerCodecs();
-  }
-  
-  private static final int	AT_V4		= 1;
-  private static final int	AT_V6		= 2;
-  private static final int	AT_EITHER	= 3;
-  
-  private static VersionCheckClient instance;
-  
-  /**
-   * Get the singleton instance of the version check client.
-   * @return version check client
-   */
-  public static synchronized VersionCheckClient 
-  getSingleton()
-  {
-	  if ( instance == null ){
-		  
-		  instance = new VersionCheckClient();
-	  }
-	  
-	  return( instance );
-  }
-  
-  private boolean	enable_v6;
-  private boolean	prefer_v6;
-
-  private Map last_check_data_v4 = null;
-  private Map last_check_data_v6 = null;
-  
-  private final AEMonitor check_mon = new AEMonitor( "versioncheckclient" );
-  
-  private long last_check_time_v4 = 0; 
-  private long last_check_time_v6 = 0; 
-  
-  private long last_feature_flag_cache;
-  private long last_feature_flag_cache_time;
-    
-  
-  private 
-  VersionCheckClient()
-  {
-	  COConfigurationManager.addAndFireParameterListeners(
-			  new String[]{ "IPV6 Prefer Addresses", "IPV6 Enable Support" },
-			  new ParameterListener()
-			  {
-				 public void 
-				 parameterChanged(
-					String 	name )
-				 {
-					 enable_v6	= COConfigurationManager.getBooleanParameter( "IPV6 Enable Support" );
-					 prefer_v6 	= COConfigurationManager.getBooleanParameter( "IPV6 Prefer Addresses" );
-				 } 
-			  });
-  }
-  
-  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();
-  }
-  
-  
-  
-   
-  
-  
-  /**
-   * Get the version check reply info.
-   * @return reply data, possibly cached, if the server was already checked within the last minute
-   */
-  
-  public Map 
-  getVersionCheckInfo( 
-	String 	reason )
-  {
-	  return( getVersionCheckInfo( reason, AT_EITHER ));
-  }
-  
-  public Map 
-  getVersionCheckInfo( 
-	String 	reason,
-	int		address_type )
-  {
-	  if ( address_type == AT_V4 ){
-		  
-		  return( getVersionCheckInfoSupport( reason, false, false, false ));
-
-	  }else if ( address_type == AT_V6 ){
-		  
-		  return( getVersionCheckInfoSupport( reason, false, false, true ));
-
-	  }else{
-		  
-		  Map	reply = getVersionCheckInfoSupport( reason, false, false, prefer_v6 );
-		  
-		  if ( reply == null || reply.size() == 0 ){
-			  
-			  reply =  getVersionCheckInfoSupport( reason, false, false, !prefer_v6 );
-		  }
-		  
-		  return( reply );
-	  }
-  }
-
- 
-  protected Map 
-  getVersionCheckInfoSupport( 
-	  String 	reason, 
-	  boolean 	only_if_cached, 
-	  boolean 	force,
-	  boolean	v6 )
-  {
-  	if ( v6 ){
-
-  		if ( enable_v6 ){
-  			
-	 	    try {  check_mon.enter();
-		    
-		      long time_diff = SystemTime.getCurrentTime() - last_check_time_v6;
-		     
-		      force = force || time_diff > CACHE_PERIOD || time_diff < 0;
-		      
-		      if( last_check_data_v6 == null || last_check_data_v6.size() == 0 || force ) {
-		    	  // if we've never checked before then we go ahead even if the "only_if_cached"
-		    	  // flag is set as its had not chance of being cached yet!
-		    	if ( only_if_cached && last_check_data_v6 != null ){
-		    		return( new HashMap() );
-		    	}
-		        try {
-		          last_check_data_v6 = performVersionCheck( constructVersionCheckMessage( reason ), true, true, true );
-		          
-		          if ( last_check_data_v6 != null && last_check_data_v6.size() > 0 ){
-		       
-		        	  COConfigurationManager.setParameter( "versioncheck.cache.v6", last_check_data_v6 );
-		          }
-		        }
-		        catch(SocketException t) {
-		        	// internet is broken
-		        	// Debug.out(t.getClass().getName() + ": " + t.getMessage());
-		        }
-		        catch(UnknownHostException t) {
-		        	// dns is broken
-		        	// Debug.out(t.getClass().getName() + ": " + t.getMessage());
-		        }
-		        catch( Throwable t ) {
-		        	Debug.out(t);
-		          last_check_data_v6 = new HashMap();
-		        }
-		      }
-		      else {
-		      	Logger.log(new LogEvent(LOGID, "VersionCheckClient is using "
-								+ "cached version check info. Using " + last_check_data_v6.size()
-								+ " reply keys.")); 
-		      }
-		    }
-		    finally {  check_mon.exit();  }
-  		}
-  		
-	    if( last_check_data_v6 == null )  last_check_data_v6 = new HashMap();
-	    
-	    return last_check_data_v6;
-	    
-  	}else{
-  		
-  	   try {  check_mon.enter();
-	    
-	      long time_diff = SystemTime.getCurrentTime() - last_check_time_v4;
-	     
-	      force = force || time_diff > CACHE_PERIOD || time_diff < 0;
-	      
-	      if( last_check_data_v4 == null || last_check_data_v4.size() == 0 || force ) {
-	    	  // if we've never checked before then we go ahead even if the "only_if_cached"
-	    	  // flag is set as its had not chance of being cached yet!
-	    	if ( only_if_cached && last_check_data_v4 != null ){
-	    		return( new HashMap() );
-	    	}
-	        try {
-	          last_check_data_v4 = performVersionCheck( constructVersionCheckMessage( reason ), true, true, false );
-	         
-	          if ( last_check_data_v4 != null && last_check_data_v4.size() > 0 ){
-	   	       
-	        	  COConfigurationManager.setParameter( "versioncheck.cache.v4", last_check_data_v4 );
-	          }
-	          
-	          	// clear down any plugin-specific data that has successfully been sent to the version server
-	          
-	          try{
-	    	      if ( AzureusCoreFactory.isCoreAvailable()){
-	    	      	
-	    		      //installed plugin IDs
-	    		      PluginInterface[] plugins = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaces();
-	    		      	    		      
-	    		      for (int i=0;i<plugins.length;i++){
-	    		    	  
-	    		    	PluginInterface		plugin = plugins[i];
-	    		        
-	    		       	Map	data = plugin.getPluginconfig().getPluginMapParameter( "plugin.versionserver.data", null );
-
-	    		       	if ( data != null ){
-	    		       	
-	    		       		plugin.getPluginconfig().setPluginMapParameter( "plugin.versionserver.data", new HashMap());
-	    		       	}
-	    		      }
-	    	      }
-	          }catch( Throwable e ){
-	          }
-	        }
-	        catch( UnknownHostException t ) {
-	        	// no internet
-	        	Debug.outNoStack("VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
-	        }
-	        catch (IOException t) {
-	        	// General connection problem.
-	        	Debug.outNoStack("VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
-	        }
-	        catch( Throwable t ) {
-	        	Debug.out(t);
-	          last_check_data_v4 = new HashMap();
-	        }
-	      }
-	      else {
-	    	  if (Logger.isEnabled())
-	    		  Logger.log(new LogEvent(LOGID, "VersionCheckClient is using "
+
+
+	private static final String 	AZ_MSG_SERVER_ADDRESS_V4 	= Constants.VERSION_SERVER_V4;
+	private static final int 		AZ_MSG_SERVER_PORT 			= 27001;
+	private static final String 	MESSAGE_TYPE_ID 			= "AZVER";
+
+	public static final String 		HTTP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
+	public static final int 		HTTP_SERVER_PORT 			= 80;
+
+	public static final String 		TCP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
+	public static final int 		TCP_SERVER_PORT 			= 80;
+
+	public static final String 		UDP_SERVER_ADDRESS_V4		= AZ_MSG_SERVER_ADDRESS_V4;
+	public static final int 		UDP_SERVER_PORT 			= 2080;
+
+	public static final String		AZ_MSG_SERVER_ADDRESS_V6 	= Constants.VERSION_SERVER_V6;
+	public static final String		HTTP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
+	public static final String		TCP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
+	public static final String		UDP_SERVER_ADDRESS_V6 		= AZ_MSG_SERVER_ADDRESS_V6;
+
+
+	private static final long		CACHE_PERIOD	= 5*60*1000;
+	private static boolean secondary_check_done;
+
+	private final List<VersionCheckClientListener> listeners = new ArrayList<VersionCheckClientListener>(1);
+	private boolean startCheckRan = false;
+
+	static{
+		VersionCheckClientUDPCodecs.registerCodecs();
+	}
+
+	private static final int	AT_V4		= 1;
+	private static final int	AT_V6		= 2;
+	private static final int	AT_EITHER	= 3;
+
+	private static VersionCheckClient instance;
+
+	/**
+	 * Get the singleton instance of the version check client.
+	 * @return version check client
+	 */
+	public static synchronized VersionCheckClient 
+	getSingleton()
+	{
+		if ( instance == null ){
+
+			instance = new VersionCheckClient();
+		}
+
+		return( instance );
+	}
+
+	private boolean	enable_v6;
+	private boolean	prefer_v6;
+
+	private Map last_check_data_v4 = null;
+	private Map last_check_data_v6 = null;
+
+	private final AEMonitor check_mon = new AEMonitor( "versioncheckclient" );
+
+	private long last_check_time_v4 = 0; 
+	private long last_check_time_v6 = 0; 
+
+	private long last_feature_flag_cache;
+	private long last_feature_flag_cache_time;
+
+
+	private 
+	VersionCheckClient()
+	{
+		COConfigurationManager.addAndFireParameterListeners(
+				new String[]{ "IPV6 Prefer Addresses", "IPV6 Enable Support" },
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+							String 	name )
+					{
+						enable_v6	= COConfigurationManager.getBooleanParameter( "IPV6 Enable Support" );
+						prefer_v6 	= COConfigurationManager.getBooleanParameter( "IPV6 Prefer Addresses" );
+					} 
+				});
+	}
+
+	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();
+	}
+
+
+
+
+
+
+	/**
+	 * Get the version check reply info.
+	 * @return reply data, possibly cached, if the server was already checked within the last minute
+	 */
+
+	public Map 
+	getVersionCheckInfo( 
+			String 	reason )
+	{
+		return( getVersionCheckInfo( reason, AT_EITHER ));
+	}
+
+	public Map 
+	getVersionCheckInfo( 
+			String 	reason,
+			int		address_type )
+	{
+		if ( address_type == AT_V4 ){
+
+			return( getVersionCheckInfoSupport( reason, false, false, false ));
+
+		}else if ( address_type == AT_V6 ){
+
+			return( getVersionCheckInfoSupport( reason, false, false, true ));
+
+		}else{
+
+			Map	reply = getVersionCheckInfoSupport( reason, false, false, prefer_v6 );
+
+			if ( reply == null || reply.size() == 0 ){
+
+				reply =  getVersionCheckInfoSupport( reason, false, false, !prefer_v6 );
+			}
+
+			return( reply );
+		}
+	}
+
+
+	protected Map 
+	getVersionCheckInfoSupport( 
+		String 	reason, 
+		boolean only_if_cached, 
+		boolean force,
+		boolean	v6 )
+	{
+		try {
+			synchronized (listeners) {
+				if (REASON_UPDATE_CHECK_START.equals(reason)) {
+					startCheckRan = true;
+				}
+				for (VersionCheckClientListener l : listeners) {
+					l.versionCheckStarted(reason);
+				}
+			}
+		} catch (Throwable t) {
+			Debug.out(t);
+		}
+		
+		if ( v6 ){
+
+			if ( enable_v6 ){
+
+				try {  check_mon.enter();
+
+				long time_diff = SystemTime.getCurrentTime() - last_check_time_v6;
+
+				force = force || time_diff > CACHE_PERIOD || time_diff < 0;
+
+				if( last_check_data_v6 == null || last_check_data_v6.size() == 0 || force ) {
+					// if we've never checked before then we go ahead even if the "only_if_cached"
+					// flag is set as its had not chance of being cached yet!
+					if ( only_if_cached && last_check_data_v6 != null ){
+						return( new HashMap() );
+					}
+					try {
+						last_check_data_v6 = performVersionCheck( constructVersionCheckMessage( reason ), true, true, true );
+
+						if ( last_check_data_v6 != null && last_check_data_v6.size() > 0 ){
+
+							COConfigurationManager.setParameter( "versioncheck.cache.v6", last_check_data_v6 );
+						}
+					}
+					catch(SocketException t) {
+						// internet is broken
+						// Debug.out(t.getClass().getName() + ": " + t.getMessage());
+					}
+					catch(UnknownHostException t) {
+						// dns is broken
+						// Debug.out(t.getClass().getName() + ": " + t.getMessage());
+					}
+					catch( Throwable t ) {
+						Debug.out(t);
+						last_check_data_v6 = new HashMap();
+					}
+				}
+				else {
+					Logger.log(new LogEvent(LOGID, "VersionCheckClient is using "
+							+ "cached version check info. Using " + last_check_data_v6.size()
+							+ " reply keys.")); 
+				}
+				}
+				finally {  check_mon.exit();  }
+			}
+
+			if( last_check_data_v6 == null )  last_check_data_v6 = new HashMap();
+
+			return last_check_data_v6;
+
+		}else{
+
+			try {  check_mon.enter();
+
+			long time_diff = SystemTime.getCurrentTime() - last_check_time_v4;
+
+			force = force || time_diff > CACHE_PERIOD || time_diff < 0;
+
+			if( last_check_data_v4 == null || last_check_data_v4.size() == 0 || force ) {
+				// if we've never checked before then we go ahead even if the "only_if_cached"
+				// flag is set as its had not chance of being cached yet!
+				if ( only_if_cached && last_check_data_v4 != null ){
+					return( new HashMap() );
+				}
+				try {
+					last_check_data_v4 = performVersionCheck( constructVersionCheckMessage( reason ), true, true, false );
+
+					if ( last_check_data_v4 != null && last_check_data_v4.size() > 0 ){
+
+						COConfigurationManager.setParameter( "versioncheck.cache.v4", last_check_data_v4 );
+					}
+
+					// clear down any plugin-specific data that has successfully been sent to the version server
+
+					try{
+						if ( AzureusCoreFactory.isCoreAvailable()){
+
+							//installed plugin IDs
+							PluginInterface[] plugins = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaces();
+
+							for (int i=0;i<plugins.length;i++){
+
+								PluginInterface		plugin = plugins[i];
+
+								Map	data = plugin.getPluginconfig().getPluginMapParameter( "plugin.versionserver.data", null );
+
+								if ( data != null ){
+
+									plugin.getPluginconfig().setPluginMapParameter( "plugin.versionserver.data", new HashMap());
+								}
+							}
+						}
+					}catch( Throwable e ){
+					}
+				}
+				catch( UnknownHostException t ) {
+					// no internet
+					Debug.outNoStack("VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
+				}
+				catch (IOException t) {
+					// General connection problem.
+					Debug.outNoStack("VersionCheckClient - " + t.getClass().getName() + ": " + t.getMessage());
+				}
+				catch( Throwable t ) {
+					Debug.out(t);
+					last_check_data_v4 = new HashMap();
+				}
+			}
+			else {
+				if (Logger.isEnabled())
+					Logger.log(new LogEvent(LOGID, "VersionCheckClient is using "
 							+ "cached version check info. Using " + last_check_data_v4.size()
 							+ " reply keys.")); 
-	      }
-	    }
-	    finally {  check_mon.exit();  }
-	    
-	    if( last_check_data_v4 == null )  last_check_data_v4 = new HashMap();
-	    
-	    last_feature_flag_cache_time = 0;
-	    
-	    return last_check_data_v4;
-  	}
-  }
-  
-  private boolean
-  isVersionCheckDataValid(
-	int		address_type )
-  {  	
-	  boolean v6_ok = last_check_data_v6 != null && last_check_data_v6.size() > 0;
-	  boolean v4_ok = last_check_data_v4 != null && last_check_data_v4.size() > 0;
-
-	  if ( address_type == AT_V4 ){
-		  
-		  return( v4_ok );
-		  
-	  }else if ( address_type == AT_V6 ){
-		  
-		  return( v6_ok );
-		  
-	  }else{
-		  
-		  return( v4_ok | v6_ok );
-	  }
-  }
-  
-  public Map
-  getMostRecentVersionCheckData()
-  {
-	  	// currently we maintain v4 much more accurately than v6
-	  
-	  if ( last_check_data_v4 != null ){
-		  
-		  return( last_check_data_v4 );
-	  }
-	  
-	  Map	res = COConfigurationManager.getMapParameter( "versioncheck.cache.v4", null );
-	  
-	  if ( res != null ){
-		  
-		  return( res );
-	  }
-	  
-	  if ( last_check_data_v6 != null ){
-		  
-		  return( last_check_data_v6 );
-	  }
-	  
-	  res = COConfigurationManager.getMapParameter( "versioncheck.cache.v6", null );
-	
-	  return( res );
-  }
-  
-  public long
-  getFeatureFlags()
-  {
-	  long	now = SystemTime.getCurrentTime();
-	  
-	  if ( now > last_feature_flag_cache_time && now - last_feature_flag_cache_time < 60000 ){
-		  
-		  return( last_feature_flag_cache );
-	  }
-	  
-	  Map m = getMostRecentVersionCheckData();
-	  
-	  long	result;
-	  
-	  if ( m == null ){
-		  
-		  result = 0;
-		  
-	  }else{
-	  
-		  byte[]	b_feat_flags = (byte[])m.get( "feat_flags" );
-		  
-		  if ( b_feat_flags != null ){
-			  
-			  try{
-				  
-				  result = Long.parseLong(new String((byte[])b_feat_flags));
-				  
-			  }catch( Throwable e ){
-				 
-				  result	= 0;
-			  }
-		  }else{
-			  
-			  result = 0;
-		  }
-	  }
-	  
-	  last_feature_flag_cache 		= result;
-	  last_feature_flag_cache_time	= now;
-	  
-	  return( result );
-  }
-  
-  public long
-  getCacheTime(
-	  boolean v6 )
-  {
-	  return( v6?last_check_time_v6:last_check_time_v4);
-  }
-  
-  /**
-   * Get the ip address seen by the version check server.
-   * NOTE: This information may be cached, see getVersionCheckInfo().
-   * @return external ip address, or empty string if no address information found
-   */
-  
-  public String 
-  getExternalIpAddress(
-	  boolean	only_if_cached,
-	  boolean	v6 )
-  {
-    Map reply = getVersionCheckInfoSupport( REASON_EXTERNAL_IP, only_if_cached, false, v6 );
-    
-    byte[] address = (byte[])reply.get( "source_ip_address" );
-    if( address != null ) {
-      return new String( address );
-    }
-    
-    return( null );
-  }
-  
-  
-  /**
-   * Is the DHT plugin allowed to be enabled.
-   * @return true if DHT can be enabled, false if it should not be enabled
-   */
-  public boolean DHTEnableAllowed() {
-    Map reply = getVersionCheckInfo( REASON_DHT_ENABLE_ALLOWED, AT_EITHER );
-    
-    boolean	res = false;
-    
-    byte[] value = (byte[])reply.get( "enable_dht" );
-    
-    if( value != null ) {
-    	
-      res = new String( value ).equalsIgnoreCase( "true" );
-    }
-    
-	// we take the view that if the version check failed then we go ahead
-	// and enable the DHT (i.e. we're being optimistic)
-
-    if ( !res ){
-    	res = !isVersionCheckDataValid( AT_EITHER );
-    }
-    
-    return res;
-  }
-  
-  
-  /**
-   * Is the DHT allowed to be used by external plugins.
-   * @return true if extended DHT use is allowed, false if not allowed
-   */
-  public boolean DHTExtendedUseAllowed() {
-    Map reply = getVersionCheckInfo( REASON_DHT_EXTENDED_ALLOWED, AT_EITHER );
-    
-    boolean	res = false;
-    
-    byte[] value = (byte[])reply.get( "enable_dht_extended_use" );
-    if( value != null ) {
-      res = new String( value ).equalsIgnoreCase( "true" );
-    }
-    
-    	// be generous and enable extended use if check failed
-    
-    if ( !res ){
-    	res = !isVersionCheckDataValid( AT_EITHER );
-    }
-    
-    return res;
-  }
-  
-  public String[]
-  getRecommendedPlugins()
-  {
-	  Map reply = getVersionCheckInfo( REASON_RECOMMENDED_PLUGINS, AT_EITHER );
-
-	  List	l = (List)reply.get( "recommended_plugins" );
-	  
-	  if ( l == null ){
-		  
-		  return( new String[0] );
-	  }
-	  
-	  String[]	res = new String[l.size()];
-	  
-	  for (int i=0;i<l.size();i++){
-		  
-		  res[i] = new String((byte[])l.get(i));
-	  }
-	  
-	  return( res );
-  }
-  
-  /**
-   * Perform the actual version check by connecting to the version server.
-   * @param data_to_send version message
-   * @return version reply
-   * @throws Exception if the server check connection fails
-   */
-  private Map 
-  performVersionCheck( 
-	Map 	data_to_send,
-	boolean	use_az_message,
-	boolean	use_http,
-	boolean	v6 )
-  
-  	throws Exception 
-  {
-	Exception 	error 	= null;
-	Map			reply	= null;
-	
-	
-	if ( use_http ){
-		
-		try{
-			reply = executeHTTP( data_to_send, v6 );
-			
-			reply.put( "protocol_used", "HTTP" );
-			
-			error = null;
+			}
+			}
+			finally {  check_mon.exit();  }
+
+			if( last_check_data_v4 == null )  last_check_data_v4 = new HashMap();
+
+			last_feature_flag_cache_time = 0;
+
+			return last_check_data_v4;
 		}
-		catch (IOException e) {
-			error = e;
+	}
+
+	public Map
+	getMostRecentVersionCheckData()
+	{
+		// currently we maintain v4 much more accurately than v6
+
+		if ( last_check_data_v4 != null ){
+
+			return( last_check_data_v4 );
 		}
-		catch (Exception e){
-			Debug.printStackTrace(e);
-			error = e;
-			
+
+		Map	res = COConfigurationManager.getMapParameter( "versioncheck.cache.v4", null );
+
+		if ( res != null ){
+
+			return( res );
+		}
+
+		if ( last_check_data_v6 != null ){
+
+			return( last_check_data_v6 );
 		}
+
+		res = COConfigurationManager.getMapParameter( "versioncheck.cache.v6", null );
+
+		return( res );
 	}
-	
-	if ( reply == null && use_az_message ){
-		
-		try{
-			reply = executeAZMessage( data_to_send, v6 );
-			
-			reply.put( "protocol_used", "AZMSG" );
+
+	private boolean
+	isVersionCheckDataValid(
+		int		address_type )
+	{  	
+		boolean v6_ok = last_check_data_v6 != null && last_check_data_v6.size() > 0;
+		boolean v4_ok = last_check_data_v4 != null && last_check_data_v4.size() > 0;
+
+		if ( address_type == AT_V4 ){
+
+			return( v4_ok );
+
+		}else if ( address_type == AT_V6 ){
+
+			return( v6_ok );
+
+		}else{
+
+			return( v4_ok | v6_ok );
 		}
-		catch (IOException e) {
-			error = e;
+	}
+
+	public long
+	getCacheTime(
+			boolean v6 )
+	{
+		return( v6?last_check_time_v6:last_check_time_v4);
+	}
+
+	public void
+	clearCache()
+	{
+		last_check_time_v6	= 0;
+		last_check_time_v4	= 0;
+	}
+
+	public long
+	getFeatureFlags()
+	{
+		long	now = SystemTime.getCurrentTime();
+
+		if ( now > last_feature_flag_cache_time && now - last_feature_flag_cache_time < 60000 ){
+
+			return( last_feature_flag_cache );
 		}
-		catch (Exception e) {
-			Debug.printStackTrace( e );
-			error = e;
+
+		Map m = getMostRecentVersionCheckData();
+
+		long	result;
+
+		if ( m == null ){
+
+			result = 0;
+
+		}else{
+
+			byte[]	b_feat_flags = (byte[])m.get( "feat_flags" );
+
+			if ( b_feat_flags != null ){
+
+				try{
+
+					result = Long.parseLong(new String((byte[])b_feat_flags));
+
+				}catch( Throwable e ){
+
+					result	= 0;
+				}
+			}else{
+
+				result = 0;
+			}
 		}
+
+		last_feature_flag_cache 		= result;
+		last_feature_flag_cache_time	= now;
+
+		return( result );
 	}
-	if ( error != null ){
-		
-		throw( error );
+
+	public Set<String>
+	getDisabledPluginIDs()
+	{  
+		Set<String>	result = new HashSet<String>();
+
+		Map m = getMostRecentVersionCheckData();
+
+		if ( m != null ){
+
+			byte[]	x = (byte[])m.get( "disabled_pids" );
+
+			if ( x != null ){
+
+				String str = new String( x );
+
+				String latest = COConfigurationManager.getStringParameter( "vc.disabled_pids.latest", "" );
+
+				if ( !str.equals( latest )){
+
+					byte[]	sig = (byte[])m.get( "disabled_pids_sig" );
+
+					if ( sig == null ){
+
+						Debug.out( "disabled plugins sig missing" );
+
+						return( result );
+					}
+
+					try{
+						AEVerifier.verifyData( str, sig );
+
+						COConfigurationManager.setParameter( "vc.disabled_pids.latest", str );
+
+					}catch( Throwable e ){
+
+						return( result );
+					}
+				}
+
+				String[] bits = str.split( "," );
+
+				for ( String b: bits ){
+
+					b = b.trim();
+
+					if ( b.length() > 0 ){
+
+						result.add( b );
+					}
+				}
+			}
+		}
+
+		return( result );
 	}
-      
-	if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "VersionCheckClient server "
-						+ "version check successful. Received " + reply.size()
-						+ " reply keys."));
-
-	if ( v6 ){
-	
-		last_check_time_v6 = SystemTime.getCurrentTime();
-		
-	}else{
-		
-		last_check_time_v4 = SystemTime.getCurrentTime();
+
+	public Set<String>
+	getAutoInstallPluginIDs()
+	{  
+		Set<String>	result = new HashSet<String>();
+
+		Map m = getMostRecentVersionCheckData();
+
+		if ( m != null ){
+
+			byte[]	x = (byte[])m.get( "autoinstall_pids" );
+
+			if ( x != null ){
+
+				String str = new String( x );
+
+				String latest = COConfigurationManager.getStringParameter( "vc.autoinstall_pids.latest", "" );
+
+				if ( !str.equals( latest )){
+
+					byte[]	sig = (byte[])m.get( "autoinstall_pids_sig" );
+
+					if ( sig == null ){
+
+						Debug.out( "autoinstall plugins sig missing" );
+
+						return( result );
+					}
+
+					try{
+						AEVerifier.verifyData( str, sig );
+
+						COConfigurationManager.setParameter( "vc.autoinstall_pids.latest", str );
+
+					}catch( Throwable e ){
+
+						return( result );
+					}
+				}
+
+				String[] bits = str.split( "," );
+
+				for ( String b: bits ){
+
+					b = b.trim();
+
+					if ( b.length() > 0 ){
+
+						result.add( b );
+					}
+				}
+			}
+		}
+
+		return( result );
 	}
-	
-    return reply;
-  }
-  
-  private Map
-  executeAZMessage(
-	Map		data_to_send,
-	boolean	v6 )
-  
-  	throws Exception
-  {
-	  if ( v6 && !enable_v6 ){
-		  
-		  throw( new Exception( "IPv6 is disabled" ));
-	  }
-
-	  String	host = getHost( v6, AZ_MSG_SERVER_ADDRESS_V6, AZ_MSG_SERVER_ADDRESS_V4 );
-	  
-	  if (Logger.isEnabled())
-		  Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
-				  + "version information from " + host + ":" + AZ_MSG_SERVER_PORT)); 
-
-	  ClientMessageService 	msg_service = null;
-	  Map 					reply		= null;	
-
-	  try{
-		  msg_service = ClientMessageServiceClient.getServerService( host, AZ_MSG_SERVER_PORT, MESSAGE_TYPE_ID );
-
-		  msg_service.sendMessage( data_to_send );  //send our version message
-
-		  reply = msg_service.receiveMessage();  //get the server reply
-
-		  preProcessReply( reply, v6 );
-		  
-	  }finally{
-
-		  if ( msg_service != null ){
-
-			  msg_service.close();
-		  }
-	  }
-	  
-	  return( reply );
-  }
-  
-  private Map
-  executeHTTP(
-	Map		data_to_send,
-	boolean	v6 )
-  
-  	throws Exception
-  {
-	  if ( v6 && !enable_v6 ){
-		  
-		  throw( new Exception( "IPv6 is disabled" ));
-	  }
-	  
-	  String	host = getHost(v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4 );
-
-	  if (Logger.isEnabled())
-		  Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
-				  + "version information from " + host + ":" + HTTP_SERVER_PORT + " via HTTP" )); 
-
-	  String	url_str = "http://" + (v6?UrlUtils.convertIPV6Host(host):host) + (HTTP_SERVER_PORT==80?"":(":" + HTTP_SERVER_PORT)) + "/version?";
-
-	  url_str += URLEncoder.encode( new String( BEncoder.encode( data_to_send ), "ISO-8859-1" ), "ISO-8859-1" );
-	  
-	  URL	url = new URL( url_str );
-	  
-	  HttpURLConnection	url_connection = (HttpURLConnection)url.openConnection();
-	  
-	  url_connection.connect();
-	  
-	  try{
-		  InputStream	is = url_connection.getInputStream();
-		  
-		  Map	reply = BDecoder.decode( new BufferedInputStream( is ));
-		  
-		  preProcessReply( reply, v6 );
-
-		  return( reply );
-		  
-	  }finally{
-		  
-		  url_connection.disconnect();
-	  }
-  }
-  
-  public String
-  getHTTPGetString(
-	boolean	for_proxy,
-	boolean	v6 )
-  {
-	  return( getHTTPGetString( new HashMap(), for_proxy, v6 ));
-  }
-  
-  private String
-  getHTTPGetString(
-	Map		content,
-	boolean	for_proxy,
-	boolean	v6 )
-  {
-	  String	host = getHost( v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4 );
-
-	  String	get_str = "GET " + (for_proxy?("http://" + (v6?UrlUtils.convertIPV6Host( host ):host ) + ":" + HTTP_SERVER_PORT ):"") +"/version?";
-
-	  try{
-		  get_str += URLEncoder.encode( new String( BEncoder.encode( content ), "ISO-8859-1" ), "ISO-8859-1" );
-		  
-	  }catch( Throwable e ){ 
-	  }
-	  
-	  get_str +=" HTTP/1.1" + "\015\012" + "\015\012";
-	 
-	  return( get_str );
-  }
-  
-  private Map
-  executeTCP(
-	Map				data_to_send,
-	InetAddress		bind_ip,
-	int				bind_port,
-	boolean			v6 )
-  
-  	throws Exception
-  {
-	  if ( v6 && !enable_v6 ){
-		  
-		  throw( new Exception( "IPv6 is disabled" ));
-	  }
-
-	  String	host = getHost(v6, TCP_SERVER_ADDRESS_V6, TCP_SERVER_ADDRESS_V4 );
-
-	  if (Logger.isEnabled())
-		  Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
-				  + "version information from " + host + ":" + TCP_SERVER_PORT + " via TCP" )); 
-
-	  String	get_str = getHTTPGetString( data_to_send, false, v6 );
-	  
-	  Socket	socket = null;
-	  
-	  try{
-		  socket = new Socket();
-		 
-		  if ( bind_ip != null ){
-			  
-			  socket.bind( new InetSocketAddress( bind_ip, bind_port ));
-			  
-		  }else if ( bind_port != 0 ){
-			  
-			  socket.bind( new InetSocketAddress( bind_port ));
-		  }
-		  
-		  socket.setSoTimeout( 10000 );
-		
-		  socket.connect( new InetSocketAddress( host, TCP_SERVER_PORT ), 10000 );
-		  
-		  OutputStream	os = socket.getOutputStream();
-		  
-		  os.write( get_str.getBytes( "ISO-8859-1" ));
-		  
-		  os.flush();
-		  
-		  InputStream	is = socket.getInputStream();
-		  		  		
-		  byte[]	buffer = new byte[1];
-
-		  String	header = "";
-		  
-		  int content_length = -1;
-		  
-		  while( true ){
-			  
-			  int	len = is.read( buffer );
-			  			  
-			  if ( len <= 0 ){
-				  
-				  break;
-			  }
-			  
-			  header += (char)buffer[0];
-			  			  
-			  if ( header.endsWith( "\r\n\r\n" )){
-				  
-				  header = header.toLowerCase( MessageText.LOCALE_ENGLISH );
-				  
-				  int	pos = header.indexOf( "content-length:" );
-				  
-				  if ( pos == -1 ){
-					  
-					  throw( new IOException( "content length missing" ));
-				  }
-				  
-				  header = header.substring( pos+15 );
-				  
-				  pos = header.indexOf( '\r' );
-				  
-				  header = header.substring(0,pos).trim();
-				  
-				  content_length = Integer.parseInt( header );
-				  
-				  if ( content_length > 10000 ){
-					  
-					  throw( new IOException( "content length too large" ));
-				  }
-				  
-				  break;
-			  }
-			  
-			  if ( header.length() > 2048 ){
-				  
-				  throw( new IOException( "header too large" ));
-			  }
-		  }
-		  
-		  ByteArrayOutputStream	baos = new ByteArrayOutputStream( content_length );
-
-		  buffer = new byte[content_length];
-		  
-		  while( content_length > 0 ){
-			  
-			  int	len = is.read( buffer );
-  			  
-			  if ( len <= 0 ){
-				  
-				  break;
-			  }
-
-			  baos.write( buffer, 0, len );
-			  
-			  content_length -= len;
-		  }
-		  
-		  if ( content_length != 0 ){
-			  
-			  throw( new IOException( "error reading reply" ));
-		  }
-		  
-		  byte[]	reply_bytes = baos.toByteArray();
-		    		  
-		  Map reply = BDecoder.decode( new BufferedInputStream( new ByteArrayInputStream( reply_bytes )));
-		  
-		  preProcessReply( reply, v6 );
-
-		  return( reply );
-		  
-	  }finally{
-		  
-		  if ( socket != null ){
-			  
-			  try{
-				  socket.close();
-				  
-			  }catch( Throwable e ){
-				  
-			  }
-		  }
-	  }
-  }
-  
-  private Map
-  executeUDP(
-	Map				data_to_send,
-	InetAddress		bind_ip,
-	int				bind_port,
-	boolean			v6 )
-  
-  	throws Exception
-  {
-	  if ( v6 && !enable_v6 ){
-		  
-		  throw( new Exception( "IPv6 is disabled" ));
-	  }
-
-	  String	host = getHost( v6, UDP_SERVER_ADDRESS_V6, UDP_SERVER_ADDRESS_V4 );
-
-	  PRUDPReleasablePacketHandler handler = PRUDPPacketHandlerFactory.getReleasableHandler( bind_port );
-	  	  
-	  PRUDPPacketHandler	packet_handler = handler.getHandler();
-	  
-	  long timeout = 5;
-	  
-	  Random random = new Random();
-	  
-	  try{
-		  Exception	last_error = null;
-		  
-		  packet_handler.setExplicitBindAddress( bind_ip );	  
-		  
-		  for (int i=0;i<3;i++){
-			  
-			  try{
-				  	// connection ids for requests must always have their msb set...
-				  	// apart from the original darn udp tracker spec....
-				  
-				  long connection_id = 0x8000000000000000L | random.nextLong();
-				  
-				  VersionCheckClientUDPRequest	request_packet = new VersionCheckClientUDPRequest( connection_id );
-				  
-				  request_packet.setPayload( data_to_send );
-				  
-				  VersionCheckClientUDPReply reply_packet = (VersionCheckClientUDPReply)packet_handler.sendAndReceive( null, request_packet, new InetSocketAddress( host, UDP_SERVER_PORT ), timeout );
-		
-				  Map	reply = reply_packet.getPayload();
-				  
-				  preProcessReply( reply, v6 );
-				  
-				  return( reply );
-				  
-			  }catch( Exception e){
-				  
-				  last_error	= e;
-				  
-				  timeout = timeout * 2;
-			  }
-		  }
-		  
-		  if ( last_error != null ){
-			  
-			  throw( last_error );
-		  }
-		  
-		  throw( new Exception( "Timeout" ));
-		  
-	  }finally{
-		 
-		  packet_handler.setExplicitBindAddress( null );
-
-		  handler.release();
-	  }
-  }
-  
-  protected void
-  preProcessReply(
-	Map					reply,
-	final boolean		v6 )
-  {
-	  NetworkAdmin admin = NetworkAdmin.getSingleton();
-	  
-	  try{
-		  byte[] address = (byte[])reply.get( "source_ip_address" );
-
-		  InetAddress my_ip = InetAddress.getByName( new String( address ));
-		  
-		  NetworkAdminASN old_asn = admin.getCurrentASN();
-		  	  
-		  NetworkAdminASN new_asn = admin.lookupCurrentASN( my_ip );
-
-		  if ( !new_asn.sameAs( old_asn )){
-
-			  // kick off a secondary version check to communicate the new information
-
-			  if ( !secondary_check_done ){
-
-				  secondary_check_done	= true;
-
-				  new AEThread( "Secondary version check", true )
-				  {
-					  public void
-					  runSupport()
-					  {
-						  getVersionCheckInfoSupport( REASON_SECONDARY_CHECK, false, true, v6 );
-					  }
-				  }.start();
-			  }
-		  }
-	 }catch( Throwable e ){
-			 
-		 Debug.printStackTrace(e);
-	 }
-	 
-	 Long	as_advice = (Long)reply.get( "as_advice" );
-	 
-	 if ( as_advice != null ){
-		 
-		 NetworkAdminASN current_asn = admin.getCurrentASN();
-
-	     String	asn = current_asn.getASName();
-
-	     if ( asn != null ){
-	    	
-			 long	advice = as_advice.longValue();
-			 
-			 if ( advice != 0 ){
-			
-				 	// require crypto
-				 
-				 String	done_asn = COConfigurationManager.getStringParameter( "ASN Advice Followed", "" );
-				 
-				 if ( !done_asn.equals( asn )){
-					 
-					 COConfigurationManager.setParameter( "ASN Advice Followed", asn );
-					 
-					 boolean	change 	= advice == 1 || advice == 2;
-					 boolean	alert 	= advice == 1 || advice == 3;
-					 
-					 if ( !COConfigurationManager.getBooleanParameter( "network.transport.encrypted.require" )){
-						 
-						 if ( change ){
-							 
-							 COConfigurationManager.setParameter( "network.transport.encrypted.require", true );
-						 }
-						 
-						 if ( alert ){
-							 
-							 String	msg = 
-								 MessageText.getString(
-										"crypto.alert.as.warning",
-										new String[]{ asn });
-							 
-							 Logger.log( new LogAlert( false, LogAlert.AT_WARNING, msg ));
-						 }
-					 }
-				 }
-			 }
-	     }
-	 }
-	 
-		// set ui.toolbar.uiswitcher based on instructions from tracker
-		// Really shouldn't be in VersionCheck client, but instead have some 
-		// listener and have the code elsewhere.  Simply calling 
-		//getVersionCheckInfo from "code elsewhere" (to get the cached result) 
-		//caused a deadlock at startup.
-		Long lEnabledUISwitcher = (Long) reply.get("ui.toolbar.uiswitcher");
-		if (lEnabledUISwitcher != null) {
-			COConfigurationManager.setBooleanDefault("ui.toolbar.uiswitcher",
-					lEnabledUISwitcher.longValue() == 1);
+
+	/**
+	 * Get the ip address seen by the version check server.
+	 * NOTE: This information may be cached, see getVersionCheckInfo().
+	 * @return external ip address, or empty string if no address information found
+	 */
+
+	public String 
+	getExternalIpAddress(
+			boolean	only_if_cached,
+			boolean	v6 )
+	{
+		Map reply = getVersionCheckInfoSupport( REASON_EXTERNAL_IP, only_if_cached, false, v6 );
+
+		byte[] address = (byte[])reply.get( "source_ip_address" );
+		if( address != null ) {
+			return new String( address );
+		}
+
+		return( null );
+	}
+
+
+	/**
+	 * Is the DHT plugin allowed to be enabled.
+	 * @return true if DHT can be enabled, false if it should not be enabled
+	 */
+	public boolean DHTEnableAllowed() {
+		Map reply = getVersionCheckInfo( REASON_DHT_ENABLE_ALLOWED, AT_EITHER );
+
+		boolean	res = false;
+
+		byte[] value = (byte[])reply.get( "enable_dht" );
+
+		if( value != null ) {
+
+			res = new String( value ).equalsIgnoreCase( "true" );
+		}
+
+		// we take the view that if the version check failed then we go ahead
+		// and enable the DHT (i.e. we're being optimistic)
+
+		if ( !res ){
+			res = !isVersionCheckDataValid( AT_EITHER );
 		}
-  }
-  
-  public InetAddress
-  getExternalIpAddressHTTP(
-	boolean		v6 )
-  
-  	throws Exception
-  {
-	  Map reply = executeHTTP( new HashMap(), v6 );
-	  
-	  byte[] address = (byte[])reply.get( "source_ip_address" );
-	  
-	  return( InetAddress.getByName( new String( address )));
-  }
-  
-  public InetAddress
-  getExternalIpAddressTCP(
-	InetAddress	 	bind_ip,
-	int				bind_port,
-	boolean			v6 )
-  
-  	throws Exception
-  {
-	  Map reply = executeTCP( new HashMap(), bind_ip, bind_port, v6 );
-	  
-	  byte[] address = (byte[])reply.get( "source_ip_address" );
-	  
-	  return( InetAddress.getByName( new String( address )));
-  }
-  
-  public InetAddress
-  getExternalIpAddressUDP(
-	InetAddress	 	bind_ip,
-	int				bind_port,
-	boolean			v6 )
-  
-  	throws Exception
-  {
-	  Map reply = executeUDP( new HashMap(), bind_ip, bind_port, v6 );
-	  
-	  byte[] address = (byte[])reply.get( "source_ip_address" );
-	  
-	  return( InetAddress.getByName( new String( address )));
-  }
-  
-  protected String
-  getHost(
-	boolean		v6,
-	String		v6_address,
-	String		v4_address )
-  {
-	 if ( v6 ){
-		 
-		 try{
-			 return( InetAddress.getByName( v6_address ).getHostAddress());
-			 
-		 }catch( UnknownHostException e ){
-			 
-			 try{
-				 return( DNSUtils.getIPV6ByName(v6_address ).getHostAddress());
-				 
-			 }catch( UnknownHostException f ){
-				 
-				 return( v6_address );
-			 }
-		 }
-	 }else{
-		 
-		 return( v4_address );
-	 }
-  }
-  
-  /**
-   * Construct the default version check message.
-   * @return message to send
-   */
-  private static Map constructVersionCheckMessage( String reason ) {
-	  
-	  //only send if anonymous-check flag is not set
-	  
-	boolean send_info = COConfigurationManager.getBooleanParameter( "Send Version Info" );
-
-    Map message = new HashMap();
-
-    //always send
-    message.put( "appid",   SystemProperties.getApplicationIdentifier());
-    message.put( "version", Constants.AZUREUS_VERSION );
-    message.put( "ui",      COConfigurationManager.getStringParameter( "ui", "unknown" ) );
-    message.put( "os",      Constants.OSName );
-    message.put( "os_version", System.getProperty( "os.version" ) );
-    message.put( "os_arch", System.getProperty( "os.arch" ) );   //see http://lopica.sourceforge.net/os.html
-
-    boolean using_phe = COConfigurationManager.getBooleanParameter( "network.transport.encrypted.require" );
-    message.put( "using_phe", using_phe ? new Long(1) : new Long(0) );
-
-    //swt stuff
-    try {
-      Class c = Class.forName( "org.eclipse.swt.SWT" );
-      
-      String swt_platform = (String)c.getMethod( "getPlatform", new Class[]{} ).invoke( null, new Object[]{} );
-      message.put( "swt_platform", swt_platform );
-      
-      Integer swt_version = (Integer)c.getMethod( "getVersion", new Class[]{} ).invoke( null, new Object[]{} );
-      message.put( "swt_version", new Long( swt_version.longValue() ) );
-
-      if ( send_info ){
-	      c = Class.forName("org.gudy.azureus2.ui.swt.mainwindow.MainWindow");
-	      if (c != null) {
-	    	  c.getMethod("addToVersionCheckMessage", new Class[] { Map.class }).invoke(
-	    			  null, new Object[] { message });
-	      }   
-      }
-    }
-    catch( ClassNotFoundException e ) {  /* ignore */ }
-    catch( NoClassDefFoundError er ) {  /* ignore */ }
-    catch( InvocationTargetException err ) {  /* ignore */ }
-    catch( Throwable t ) {  t.printStackTrace();  }
-    
-  
-    int last_send_time = COConfigurationManager.getIntParameter( "Send Version Info Last Time", -1 );
-    int current_send_time = (int)(SystemTime.getCurrentTime()/1000);    
-    COConfigurationManager.setParameter( "Send Version Info Last Time", current_send_time );
-
-    
-    String id = COConfigurationManager.getStringParameter( "ID", null );
-
-    if( id != null && send_info ) {    	
-      message.put( "id", id );    
-      
-      try{
-    	  byte[] id2 = CryptoManagerFactory.getSingleton().getSecureID();
-    
-    	  message.put( "id2", id2 );
-    	  
-      }catch( Throwable e ){
-      }
-      
-      if ( last_send_time != -1 && last_send_time < current_send_time ){    	  
-    	  // time since last    	  
-    	  message.put( "tsl", new Long(current_send_time-last_send_time));
-      }
-      
-      message.put( "reason", reason );
-      
-      String  java_version = System.getProperty( "java.version" );
-      if ( java_version == null ){  java_version = "unknown";  }
-      message.put( "java", java_version );
-      
-      
-      String  java_vendor = System.getProperty( "java.vm.vendor" );
-      if ( java_vendor == null ){   java_vendor = "unknown";  }
-      message.put( "javavendor", java_vendor );
-      
-      
-      long  max_mem = Runtime.getRuntime().maxMemory()/(1024*1024);
-      message.put( "javamx", new Long( max_mem ) );
-      
-      String java_rt_name = System.getProperty("java.runtime.name");
-      if (java_rt_name != null) {
-      	message.put( "java_rt_name", java_rt_name);
-      }
-
-      String java_rt_version = System.getProperty("java.runtime.version");
-      if (java_rt_version != null) {
-      	message.put( "java_rt_version", java_rt_version);
-      }
-
-      OverallStats	stats = StatsFactory.getStats();
-      
-      if ( stats != null ){
-      	
-	      //long total_bytes_downloaded 	= stats.getDownloadedBytes();
-	      //long total_bytes_uploaded		= stats.getUploadedBytes();
-	      long total_uptime 			= stats.getTotalUpTime();
-	      
-	      //removed due to complaints about anonymous stats collection
-	      //message.put( "total_bytes_downloaded", new Long( total_bytes_downloaded ) );
-	      //message.put( "total_bytes_uploaded", new Long( total_bytes_uploaded ) );
-	      message.put( "total_uptime", new Long( total_uptime ) );
-	      //message.put( "dlstats", stats.getDownloadStats());
-      }
-      
-      try{
-	      NetworkAdminASN current_asn = NetworkAdmin.getSingleton().getCurrentASN();
-		    	 
-	      String	as = current_asn.getAS();
-	      
-	   	  message.put( "ip_as", current_asn.getAS());
-	
-	      String	asn = current_asn.getASName();
-		     		    	
-		  if ( asn.length() > 64 ){
-		    		  
-		    asn = asn.substring( 0, 64 );
-		  }
-		    	  
-		  message.put( "ip_asn", asn );
-		  
-      }catch( Throwable e ){
-    	  
-    	  Debug.out( e );
-      }
-
-      // send locale, so we can determine which languages need attention
-      message.put("locale", Locale.getDefault().toString());
-      String originalLocale = System.getProperty("user.language") + "_"
-					+ System.getProperty("user.country");
-      String variant = System.getProperty("user.variant");
-      if (variant != null && variant.length() > 0) {
-      	originalLocale += "_" + variant;
-      }
-      message.put("orig_locale", originalLocale);
-
-      try{
-	      if ( AzureusCoreFactory.isCoreAvailable()){
-	      	
-		      //installed plugin IDs
-		      PluginInterface[] plugins = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaces();
-		      
-		      List pids = new ArrayList();
-		      
-		      List vs_data = new ArrayList();
-		      
-		      for (int i=0;i<plugins.length;i++){
-		    	  
-		    	PluginInterface		plugin = plugins[i];
-		    	
-		        String  pid = plugin.getPluginID();
-		        
-	        	String	info = plugin.getPluginconfig().getPluginStringParameter( "plugin.info" );
-	        	
-		          // filter out built-in and core ones
-		        if ( 	( info != null && info.length() > 0 ) ||
-		        		(	!pid.startsWith( "<" ) && 
-			        		!pid.startsWith( "azbp" ) &&
-			        		!pid.startsWith( "azupdater" ) &&
-		        			!pid.startsWith( "azplatform" ) &&
-		        			!pids.contains( pid ))){
-		        
-		        	if ( info != null && info.length() > 0 ){
-		        		
-		        		if( info.length() < 256 ){
-		        			
-		        			pid += ":" + info;
-		        			
-		        		}else{
-		        			
-		        			Debug.out( "Plugin '" + pid + "' reported excessive info string '" + info + "'" );
-		        		}
-		        	}
-		        	
-		        	pids.add( pid );
-		        }
-		        
-		       	Map	data = plugin.getPluginconfig().getPluginMapParameter( "plugin.versionserver.data", null );
-	
-		       	if ( data != null ){
-		       		
-		       		Map payload = new HashMap();
-		       		
-		       		byte[]	data_bytes = BEncoder.encode( data );
-		       		
-		       		if ( data_bytes.length > 16*1024 ){
-		       			
-	        			Debug.out( "Plugin '" + pid + "' reported excessive version server data (length=" + data_bytes.length + ")" );
-	        			
-	        			payload.put( "error", "data too long: " + data_bytes.length );
-	        			
-		       		}else{
-
-		       			payload.put( "data", data_bytes );
-		       		}
-		       		
-		       		payload.put( "id", pid);
-		       		payload.put( "version", plugin.getPluginVersion());
-		       		
-		       		vs_data.add( payload );
-		       	}
-		      }
-		      message.put( "plugins", pids );
-		      
-		      if ( vs_data.size() > 0 ){
-		    	  
-		    	  message.put( "plugin_data", vs_data );
-		      }
-	      }
-      }catch( Throwable e ){
-    	  
-    	  Debug.out( e );
-      }
-    }
-        
-    
-    return message;
-  }
-  
-  public static void
-  main(
-	String[]	args )
-  {
-	  try{
-		  COConfigurationManager.initialise();
-		  
-		  boolean v6= true;
-		  
-		  // Test connectivity.
-		  if (true) {
-			 // System.out.println( "UDP:  " + getSingleton().getExternalIpAddressUDP(null,0,v6));
-			 // System.out.println( "TCP:  " + getSingleton().getExternalIpAddressTCP(null,0,v6));
-			  System.out.println( "HTTP: " + getSingleton().getExternalIpAddressHTTP(v6));
-		  }
-		  
-		  Map data = constructVersionCheckMessage(VersionCheckClient.REASON_UPDATE_CHECK_START);
-		  System.out.println("Sending (pre-initialisation):");
-		  printDataMap(data);
-		  System.out.println("-----------");
-		  
-		  System.out.println("Receiving (pre-initialisation):");
-		  printDataMap(getSingleton().getVersionCheckInfo(VersionCheckClient.REASON_UPDATE_CHECK_START));
-		  System.out.println("-----------");
-		  
-		  System.out.println();
-		  System.out.print("Initialising core... ");
-
-		  /**
-		   * Suppress all of these errors being displayed in the output.
-		   * 
-		   * These things should be temporary...
-		   */
-		  AzureusCoreImpl.SUPPRESS_CLASSLOADER_ERRORS = true;
-		  DownloadManagerStateImpl.SUPPRESS_FIXUP_ERRORS = true;
-		  
-		  AzureusCore core = AzureusCoreFactory.create(); 
-		  core.start();
-		  System.out.println("done.");
-		  System.out.println();
-		  System.out.println("-----------");
-		  
-		  data = constructVersionCheckMessage(VersionCheckClient.REASON_UPDATE_CHECK_START);
-		  System.out.println("Sending (post-initialisation):");
-		  printDataMap(data);
-		  System.out.println("-----------");
-		  
-		  System.out.println("Receiving (post-initialisation):");
-		  printDataMap(getSingleton().getVersionCheckInfo(VersionCheckClient.REASON_UPDATE_CHECK_START));
-		  System.out.println("-----------");
-		  System.out.println();
-
-		  System.out.print("Shutting down core... ");
-		  core.stop();
-		  System.out.println("done.");
-		  
-	  }catch( Throwable e){
-		  e.printStackTrace();
-	  }
-  }
-  
-  // Used for debugging in main.
-  private static void printDataMap(Map map) throws Exception {
-	  TreeMap res = new TreeMap(map);
-	  Iterator key_itr = map.keySet().iterator();
-	  while (key_itr.hasNext()) {
-		  Object key = key_itr.next();
-		  Object val = map.get(key);
-		  if (val instanceof byte[]) {
-			  String as_bytes = ByteFormatter.nicePrint((byte[])val);
-			  String as_text = new String((byte[])val, Constants.BYTE_ENCODING);
-			  res.put(key, as_text + " [" + as_bytes + "]");
-		  }
-	  }
-	  
-	  Iterator entries = res.entrySet().iterator();
-	  Map.Entry entry;
-	  while (entries.hasNext()) {
-		  entry = (Map.Entry)entries.next();
-		  System.out.print("  ");
-		  System.out.print(entry.getKey());
-		  System.out.print(": ");
-		  System.out.print(entry.getValue());
-		  System.out.println();
-	  }
-  }
-  
+
+		return res;
+	}
+
+
+	/**
+	 * Is the DHT allowed to be used by external plugins.
+	 * @return true if extended DHT use is allowed, false if not allowed
+	 */
+	public boolean 
+	DHTExtendedUseAllowed() 
+	{
+		Map reply = getVersionCheckInfo( REASON_DHT_EXTENDED_ALLOWED, AT_EITHER );
+
+		boolean	res = false;
+
+		byte[] value = (byte[])reply.get( "enable_dht_extended_use" );
+		if( value != null ) {
+			res = new String( value ).equalsIgnoreCase( "true" );
+		}
+
+		// be generous and enable extended use if check failed
+
+		if ( !res ){
+			res = !isVersionCheckDataValid( AT_EITHER );
+		}
+
+		return res;
+	}
+
+	public String[]
+	getRecommendedPlugins()
+	{
+		Map reply = getVersionCheckInfo( REASON_RECOMMENDED_PLUGINS, AT_EITHER );
+
+		List	l = (List)reply.get( "recommended_plugins" );
+
+		if ( l == null ){
+
+			return( new String[0] );
+		}
+
+		String[]	res = new String[l.size()];
+
+		for (int i=0;i<l.size();i++){
+
+			res[i] = new String((byte[])l.get(i));
+		}
+
+		return( res );
+	}
+
+	public Map<String,Object>
+	getCountryInfo()
+	{
+		Map reply = getVersionCheckInfo( REASON_EXTERNAL_IP, AT_EITHER );
+
+		Map<String,Object> info = (Map<String,Object>)reply.get( "source_info" );
+
+		if ( info == null ){
+
+			return( new HashMap<String,Object>());
+
+		}else{
+
+			return( BDecoder.decodeStrings( info ));
+		}
+	}
+
+	/**
+	 * Perform the actual version check by connecting to the version server.
+	 * @param data_to_send version message
+	 * @return version reply
+	 * @throws Exception if the server check connection fails
+	 */
+	private Map 
+	performVersionCheck( 
+		Map 	data_to_send,
+		boolean	use_az_message,
+		boolean	use_http,
+		boolean	v6 )
+
+		throws Exception 
+	{
+		Exception 	error 	= null;
+		Map			reply	= null;
+
+
+		if ( use_http ){
+
+			try{
+				reply = executeHTTP( data_to_send, v6 );
+
+				reply.put( "protocol_used", "HTTP" );
+
+				error = null;
+			}
+			catch (IOException e) {
+				error = e;
+			}
+			catch (Exception e){
+				Debug.printStackTrace(e);
+				error = e;
+
+			}
+		}
+
+		if ( reply == null && use_az_message ){
+
+			try{
+				reply = executeAZMessage( data_to_send, v6 );
+
+				reply.put( "protocol_used", "AZMSG" );
+				
+				error = null;
+			}
+			catch (IOException e) {
+				error = e;
+			}
+			catch (Exception e) {
+				Debug.printStackTrace( e );
+				error = e;
+			}
+		}
+		if ( error != null ){
+
+			throw( error );
+		}
+
+		if (Logger.isEnabled())
+			Logger.log(new LogEvent(LOGID, "VersionCheckClient server "
+					+ "version check successful. Received " + reply.size()
+					+ " reply keys."));
+
+		if ( v6 ){
+
+			last_check_time_v6 = SystemTime.getCurrentTime();
+
+		}else{
+
+			last_check_time_v4 = SystemTime.getCurrentTime();
+		}
+
+		return reply;
+	}
+
+	private Map
+	executeAZMessage(
+		Map		data_to_send,
+		boolean	v6 )
+
+		throws Exception
+	{
+		if ( v6 && !enable_v6 ){
+
+			throw( new Exception( "IPv6 is disabled" ));
+		}
+
+		String	host = getHost( v6, AZ_MSG_SERVER_ADDRESS_V6, AZ_MSG_SERVER_ADDRESS_V4 );
+
+		if (Logger.isEnabled())
+			Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
+					+ "version information from " + host + ":" + AZ_MSG_SERVER_PORT)); 
+
+		ClientMessageService 	msg_service = null;
+		Map 					reply		= null;	
+
+		try{
+			msg_service = ClientMessageServiceClient.getServerService( host, AZ_MSG_SERVER_PORT, 20, MESSAGE_TYPE_ID );
+
+			msg_service.sendMessage( data_to_send );  //send our version message
+
+			reply = msg_service.receiveMessage();  //get the server reply
+
+			preProcessReply( reply, v6 );
+
+		}finally{
+
+			if ( msg_service != null ){
+
+				msg_service.close();
+			}
+		}
+
+		return( reply );
+	}
+
+	private Map
+	executeHTTP(
+		Map		data_to_send,
+		boolean	v6 )
+
+		throws Exception
+	{
+		if ( v6 && !enable_v6 ){
+
+			throw( new Exception( "IPv6 is disabled" ));
+		}
+
+		String	host = getHost(v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4 );
+
+		if (Logger.isEnabled())
+			Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
+					+ "version information from " + host + ":" + HTTP_SERVER_PORT + " via HTTP" )); 
+
+		String	url_str = "http://" + (v6?UrlUtils.convertIPV6Host(host):host) + (HTTP_SERVER_PORT==80?"":(":" + HTTP_SERVER_PORT)) + "/version?";
+
+		url_str += URLEncoder.encode( new String( BEncoder.encode( data_to_send ), "ISO-8859-1" ), "ISO-8859-1" );
+
+		URL	url = new URL( url_str );
+
+		HttpURLConnection	url_connection = (HttpURLConnection)url.openConnection();
+
+		url_connection.setConnectTimeout( 10*1000 );
+		url_connection.setReadTimeout( 10*1000 );
+
+		url_connection.connect();
+
+		try{
+			InputStream	is = url_connection.getInputStream();
+
+			Map	reply = BDecoder.decode( new BufferedInputStream( is ));
+
+			preProcessReply( reply, v6 );
+
+			return( reply );
+
+		}finally{
+
+			url_connection.disconnect();
+		}
+	}
+
+	public String
+	getHTTPGetString(
+		boolean	for_proxy,
+		boolean	v6 )
+	{
+		return( getHTTPGetString( new HashMap(), for_proxy, v6 ));
+	}
+
+	private String
+	getHTTPGetString(
+		Map		content,
+		boolean	for_proxy,
+		boolean	v6 )
+	{
+		String	host = getHost( v6, HTTP_SERVER_ADDRESS_V6, HTTP_SERVER_ADDRESS_V4 );
+
+		String	get_str = "GET " + (for_proxy?("http://" + (v6?UrlUtils.convertIPV6Host( host ):host ) + ":" + HTTP_SERVER_PORT ):"") +"/version?";
+
+		try{
+			get_str += URLEncoder.encode( new String( BEncoder.encode( content ), "ISO-8859-1" ), "ISO-8859-1" );
+
+		}catch( Throwable e ){ 
+		}
+
+		get_str +=" HTTP/1.1" + "\015\012" + "\015\012";
+
+		return( get_str );
+	}
+
+	private Map
+	executeTCP(
+		Map				data_to_send,
+		InetAddress		bind_ip,
+		int				bind_port,
+		boolean			v6 )
+
+		throws Exception
+	{
+		if ( v6 && !enable_v6 ){
+
+			throw( new Exception( "IPv6 is disabled" ));
+		}
+
+		String	host = getHost(v6, TCP_SERVER_ADDRESS_V6, TCP_SERVER_ADDRESS_V4 );
+
+		if (Logger.isEnabled())
+			Logger.log(new LogEvent(LOGID, "VersionCheckClient retrieving "
+					+ "version information from " + host + ":" + TCP_SERVER_PORT + " via TCP" )); 
+
+		String	get_str = getHTTPGetString( data_to_send, false, v6 );
+
+		Socket	socket = null;
+
+		try{
+			socket = new Socket();
+
+			if ( bind_ip != null ){
+
+				socket.bind( new InetSocketAddress( bind_ip, bind_port ));
+
+			}else if ( bind_port != 0 ){
+
+				socket.bind( new InetSocketAddress( bind_port ));
+			}
+
+			socket.setSoTimeout( 10000 );
+
+			socket.connect( new InetSocketAddress( host, TCP_SERVER_PORT ), 10000 );
+
+			OutputStream	os = socket.getOutputStream();
+
+			os.write( get_str.getBytes( "ISO-8859-1" ));
+
+			os.flush();
+
+			InputStream	is = socket.getInputStream();
+
+			byte[]	buffer = new byte[1];
+
+			String	header = "";
+
+			int content_length = -1;
+
+			while( true ){
+
+				int	len = is.read( buffer );
+
+				if ( len <= 0 ){
+
+					break;
+				}
+
+				header += (char)buffer[0];
+
+				if ( header.endsWith( "\r\n\r\n" )){
+
+					header = header.toLowerCase( MessageText.LOCALE_ENGLISH );
+
+					int	pos = header.indexOf( "content-length:" );
+
+					if ( pos == -1 ){
+
+						throw( new IOException( "content length missing" ));
+					}
+
+					header = header.substring( pos+15 );
+
+					pos = header.indexOf( '\r' );
+
+					header = header.substring(0,pos).trim();
+
+					content_length = Integer.parseInt( header );
+
+					if ( content_length > 10000 ){
+
+						throw( new IOException( "content length too large" ));
+					}
+
+					break;
+				}
+
+				if ( header.length() > 2048 ){
+
+					throw( new IOException( "header too large" ));
+				}
+			}
+
+			ByteArrayOutputStream	baos = new ByteArrayOutputStream( content_length );
+
+			buffer = new byte[content_length];
+
+			while( content_length > 0 ){
+
+				int	len = is.read( buffer );
+
+				if ( len <= 0 ){
+
+					break;
+				}
+
+				baos.write( buffer, 0, len );
+
+				content_length -= len;
+			}
+
+			if ( content_length != 0 ){
+
+				throw( new IOException( "error reading reply" ));
+			}
+
+			byte[]	reply_bytes = baos.toByteArray();
+
+			Map reply = BDecoder.decode( new BufferedInputStream( new ByteArrayInputStream( reply_bytes )));
+
+			preProcessReply( reply, v6 );
+
+			return( reply );
+
+		}finally{
+
+			if ( socket != null ){
+
+				try{
+					socket.close();
+
+				}catch( Throwable e ){
+
+				}
+			}
+		}
+	}
+
+	private Map
+	executeUDP(
+		Map				data_to_send,
+		InetAddress		bind_ip,
+		int				bind_port,
+		boolean			v6 )
+
+		throws Exception
+	{
+		if ( v6 && !enable_v6 ){
+
+			throw( new Exception( "IPv6 is disabled" ));
+		}
+
+		String	host = getHost( v6, UDP_SERVER_ADDRESS_V6, UDP_SERVER_ADDRESS_V4 );
+
+		PRUDPReleasablePacketHandler handler = PRUDPPacketHandlerFactory.getReleasableHandler( bind_port );
+
+		PRUDPPacketHandler	packet_handler = handler.getHandler();
+
+		long timeout = 5;
+
+		Random random = new Random();
+
+		try{
+			Exception	last_error = null;
+
+			packet_handler.setExplicitBindAddress( bind_ip );	  
+
+			for (int i=0;i<3;i++){
+
+				try{
+					// connection ids for requests must always have their msb set...
+					// apart from the original darn udp tracker spec....
+
+					long connection_id = 0x8000000000000000L | random.nextLong();
+
+					VersionCheckClientUDPRequest	request_packet = new VersionCheckClientUDPRequest( connection_id );
+
+					request_packet.setPayload( data_to_send );
+
+					VersionCheckClientUDPReply reply_packet = (VersionCheckClientUDPReply)packet_handler.sendAndReceive( null, request_packet, new InetSocketAddress( host, UDP_SERVER_PORT ), timeout );
+
+					Map	reply = reply_packet.getPayload();
+
+					preProcessReply( reply, v6 );
+
+					return( reply );
+
+				}catch( Exception e){
+
+					last_error	= e;
+
+					timeout = timeout * 2;
+				}
+			}
+
+			if ( last_error != null ){
+
+				throw( last_error );
+			}
+
+			throw( new Exception( "Timeout" ));
+
+		}finally{
+
+			packet_handler.setExplicitBindAddress( null );
+
+			handler.release();
+		}
+	}
+
+	protected void
+	preProcessReply(
+		Map					reply,
+		final boolean		v6 )
+	{
+		NetworkAdmin admin = NetworkAdmin.getSingleton();
+
+		try{
+			byte[] address = (byte[])reply.get( "source_ip_address" );
+
+			InetAddress my_ip = InetAddress.getByName( new String( address ));
+
+			NetworkAdminASN old_asn = admin.getCurrentASN();
+
+			NetworkAdminASN new_asn = admin.lookupCurrentASN( my_ip );
+
+			if ( !new_asn.sameAs( old_asn )){
+
+				// kick off a secondary version check to communicate the new information
+
+				if ( !secondary_check_done ){
+
+					secondary_check_done	= true;
+
+					new AEThread( "Secondary version check", true )
+					{
+						public void
+						runSupport()
+						{
+							getVersionCheckInfoSupport( REASON_SECONDARY_CHECK, false, true, v6 );
+						}
+					}.start();
+				}
+			}
+		}catch( Throwable e ){
+
+			Debug.printStackTrace(e);
+		}
+
+		Long	as_advice = (Long)reply.get( "as_advice" );
+
+		if ( as_advice != null ){
+
+			NetworkAdminASN current_asn = admin.getCurrentASN();
+
+			String	asn = current_asn.getASName();
+
+			if ( asn != null ){
+
+				long	advice = as_advice.longValue();
+
+				if ( advice != 0 ){
+
+					// require crypto
+
+					String	done_asn = COConfigurationManager.getStringParameter( "ASN Advice Followed", "" );
+
+					if ( !done_asn.equals( asn )){
+
+						COConfigurationManager.setParameter( "ASN Advice Followed", asn );
+
+						boolean	change 	= advice == 1 || advice == 2;
+						boolean	alert 	= advice == 1 || advice == 3;
+
+						if ( !COConfigurationManager.getBooleanParameter( "network.transport.encrypted.require" )){
+
+							if ( change ){
+
+								COConfigurationManager.setParameter( "network.transport.encrypted.require", true );
+							}
+
+							if ( alert ){
+
+								String	msg = 
+									MessageText.getString(
+											"crypto.alert.as.warning",
+											new String[]{ asn });
+
+								Logger.log( new LogAlert( false, LogAlert.AT_WARNING, msg ));
+							}
+						}
+					}
+				}
+			}
+		}
+
+		// set ui.toolbar.uiswitcher based on instructions from tracker
+		// Really shouldn't be in VersionCheck client, but instead have some 
+		// listener and have the code elsewhere.  Simply calling 
+		//getVersionCheckInfo from "code elsewhere" (to get the cached result) 
+		//caused a deadlock at startup.
+		Long lEnabledUISwitcher = (Long) reply.get("ui.toolbar.uiswitcher");
+		if (lEnabledUISwitcher != null) {
+			COConfigurationManager.setBooleanDefault("ui.toolbar.uiswitcher",
+					lEnabledUISwitcher.longValue() == 1);
+		}
+	}
+
+	public InetAddress
+	getExternalIpAddressHTTP(
+		boolean		v6 )
+
+		throws Exception
+	{
+		Map reply = executeHTTP( new HashMap(), v6 );
+
+		byte[] address = (byte[])reply.get( "source_ip_address" );
+
+		return( InetAddress.getByName( new String( address )));
+	}
+
+	public InetAddress
+	getExternalIpAddressTCP(
+		InetAddress	 	bind_ip,
+		int				bind_port,
+		boolean			v6 )
+
+		throws Exception
+	{
+		Map reply = executeTCP( new HashMap(), bind_ip, bind_port, v6 );
+
+		byte[] address = (byte[])reply.get( "source_ip_address" );
+
+		return( InetAddress.getByName( new String( address )));
+	}
+
+	public InetAddress
+	getExternalIpAddressUDP(
+		InetAddress	 	bind_ip,
+		int				bind_port,
+		boolean			v6 )
+
+		throws Exception
+	{
+		Map reply = executeUDP( new HashMap(), bind_ip, bind_port, v6 );
+
+		byte[] address = (byte[])reply.get( "source_ip_address" );
+
+		return( InetAddress.getByName( new String( address )));
+	}
+
+	protected String
+	getHost(
+		boolean		v6,
+		String		v6_address,
+		String		v4_address )
+	{
+		if ( v6 ){
+
+			v6_address = getTestAddress( true, v6_address );
+
+			try{
+				return( InetAddress.getByName( v6_address ).getHostAddress());
+
+			}catch( UnknownHostException e ){
+
+				try{
+					return( DNSUtils.getIPV6ByName( v6_address ).getHostAddress());
+
+				}catch( UnknownHostException f ){
+
+					return( v6_address );
+				}
+			}
+		}else{
+
+			v4_address = getTestAddress( false, v4_address );
+
+			return( v4_address );
+		}
+	}
+
+	private String
+	getTestAddress(
+		boolean	v6,
+		String	address )
+	{
+		return( COConfigurationManager.getStringParameter( "versioncheck.test.address." + v6, address ));
+	}
+
+	/**
+	 * Construct the default version check message.
+	 * @return message to send
+	 */
+	public static Map<String,Object> 
+	constructVersionCheckMessage( 
+		String reason ) 
+	{
+
+		//only send if anonymous-check flag is not set
+
+		boolean send_info = COConfigurationManager.getBooleanParameter( "Send Version Info" );
+
+		Map<String,Object> message = new HashMap<String,Object>();
+
+		//always send
+		message.put( "appid",   SystemProperties.getApplicationIdentifier());
+		message.put( "appname", SystemProperties.getApplicationName());
+		message.put( "version", Constants.AZUREUS_VERSION );
+
+		String	sub_ver = Constants.AZUREUS_SUBVER;
+
+		if ( sub_ver.length() > 0 ){
+			message.put( "subver", sub_ver );
+		}
+
+		if ( COConfigurationManager.getBooleanParameter( "Beta Programme Enabled" )){
+
+			message.put( "beta_prog", "true" );
+		}
+
+		message.put( "ui",      COConfigurationManager.getStringParameter( "ui", "unknown" ) );
+		message.put( "os",      Constants.OSName );
+		message.put( "os_version", System.getProperty( "os.version" ) );
+		message.put( "os_arch", System.getProperty( "os.arch" ) );   //see http://lopica.sourceforge.net/os.html
+		message.put( "os_arch_dm", System.getProperty( "sun.arch.data.model" ) );  // might be needed to openjdk on osx
+
+		boolean using_phe = COConfigurationManager.getBooleanParameter( "network.transport.encrypted.require" );
+		message.put( "using_phe", using_phe ? new Long(1) : new Long(0) );
+
+		//swt stuff
+		try {
+			Class c = Class.forName( "org.eclipse.swt.SWT" );
+
+			String swt_platform = (String)c.getMethod( "getPlatform", new Class[]{} ).invoke( null, new Object[]{} );
+			message.put( "swt_platform", swt_platform );
+
+			Integer swt_version = (Integer)c.getMethod( "getVersion", new Class[]{} ).invoke( null, new Object[]{} );
+			message.put( "swt_version", new Long( swt_version.longValue() ) );
+		}
+		catch( ClassNotFoundException e ) {  /* ignore */ }
+		catch( NoClassDefFoundError er ) {  /* ignore */ }
+		catch( InvocationTargetException err ) {  /* ignore */ }
+		catch( Throwable t ) {  t.printStackTrace();  }
+
+
+		int last_send_time = COConfigurationManager.getIntParameter( "Send Version Info Last Time", -1 );
+		int current_send_time = (int)(SystemTime.getCurrentTime()/1000);    
+		COConfigurationManager.setParameter( "Send Version Info Last Time", current_send_time );
+
+
+		String id = COConfigurationManager.getStringParameter( "ID", null );
+
+		if( id != null && send_info ) {    	
+			message.put( "id", id );    
+
+			try{
+				byte[] id2 = CryptoManagerFactory.getSingleton().getSecureID();
+
+				message.put( "id2", id2 );
+
+			}catch( Throwable e ){
+			}
+
+			if ( last_send_time != -1 && last_send_time < current_send_time ){    	  
+				// time since last    	  
+				message.put( "tsl", new Long(current_send_time-last_send_time));
+			}
+
+			message.put( "reason", reason );
+
+			String  java_version = System.getProperty( "java.version" );
+			if ( java_version == null ){  java_version = "unknown";  }
+			message.put( "java", java_version );
+
+
+			String  java_vendor = System.getProperty( "java.vm.vendor" );
+			if ( java_vendor == null ){   java_vendor = "unknown";  }
+			message.put( "javavendor", java_vendor );
+
+
+			long  max_mem = Runtime.getRuntime().maxMemory()/(1024*1024);
+			message.put( "javamx", new Long( max_mem ) );
+
+			String java_rt_name = System.getProperty("java.runtime.name");
+			if (java_rt_name != null) {
+				message.put( "java_rt_name", java_rt_name);
+			}
+
+			String java_rt_version = System.getProperty("java.runtime.version");
+			if (java_rt_version != null) {
+				message.put( "java_rt_version", java_rt_version);
+			}
+
+			OverallStats	stats = StatsFactory.getStats();
+
+			if ( stats != null ){
+
+				//long total_bytes_downloaded 	= stats.getDownloadedBytes();
+				//long total_bytes_uploaded		= stats.getUploadedBytes();
+				long total_uptime 			= stats.getTotalUpTime();
+
+				//removed due to complaints about anonymous stats collection
+				//message.put( "total_bytes_downloaded", new Long( total_bytes_downloaded ) );
+				//message.put( "total_bytes_uploaded", new Long( total_bytes_uploaded ) );
+				message.put( "total_uptime", new Long( total_uptime ) );
+				//message.put( "dlstats", stats.getDownloadStats());
+			}
+
+			try{
+				NetworkAdminASN current_asn = NetworkAdmin.getSingleton().getCurrentASN();
+
+				String	as = current_asn.getAS();
+
+				message.put( "ip_as", current_asn.getAS());
+
+				String	asn = current_asn.getASName();
+
+				if ( asn.length() > 64 ){
+
+					asn = asn.substring( 0, 64 );
+				}
+
+				message.put( "ip_asn", asn );
+
+			}catch( Throwable e ){
+
+				Debug.out( e );
+			}
+
+			// send locale, so we can determine which languages need attention
+			message.put("locale", Locale.getDefault().toString());
+			String originalLocale = System.getProperty("user.language") + "_"
+			+ System.getProperty("user.country");
+			String variant = System.getProperty("user.variant");
+			if (variant != null && variant.length() > 0) {
+				originalLocale += "_" + variant;
+			}
+			message.put("orig_locale", originalLocale);
+
+			// We may want to reply differently if the user is in Beginner mode vs Advanced
+			message.put("user_mode",
+					COConfigurationManager.getIntParameter("User Mode", -1));
+
+			Set<String> features = UtilitiesImpl.getFeaturesInstalled();
+
+			if ( features.size() > 0 ){
+
+				String str = "";
+
+				for ( String f: features ){
+					str += (str.length()==0?"":",") + f;
+				}
+
+				message.put( "vzfeatures", str );
+			}
+
+			try{
+				if ( AzureusCoreFactory.isCoreAvailable()){
+
+					//installed plugin IDs
+					PluginInterface[] plugins = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaces();
+
+					List pids = new ArrayList();
+
+					List vs_data = new ArrayList();
+
+					for (int i=0;i<plugins.length;i++){
+
+						PluginInterface		plugin = plugins[i];
+
+						String  pid = plugin.getPluginID();
+
+						String	info = plugin.getPluginconfig().getPluginStringParameter( "plugin.info" );
+
+						// filter out built-in and core ones
+						if ( 	( info != null && info.length() > 0 ) ||
+								(	!pid.startsWith( "<" ) && 
+										!pid.startsWith( "azbp" ) &&
+										!pid.startsWith( "azupdater" ) &&
+										!pid.startsWith( "azplatform" ) &&
+										!pids.contains( pid ))){
+
+							if ( info != null && info.length() > 0 ){
+
+								if( info.length() < 256 ){
+
+									pid += ":" + info;
+
+								}else{
+
+									Debug.out( "Plugin '" + pid + "' reported excessive info string '" + info + "'" );
+								}
+							}
+
+							pids.add( pid );
+						}
+
+						Map	data = plugin.getPluginconfig().getPluginMapParameter( "plugin.versionserver.data", null );
+
+						if ( data != null ){
+
+							Map payload = new HashMap();
+
+							byte[]	data_bytes = BEncoder.encode( data );
+
+							if ( data_bytes.length > 16*1024 ){
+
+								Debug.out( "Plugin '" + pid + "' reported excessive version server data (length=" + data_bytes.length + ")" );
+
+								payload.put( "error", "data too long: " + data_bytes.length );
+
+							}else{
+
+								payload.put( "data", data_bytes );
+							}
+
+							payload.put( "id", pid);
+							payload.put( "version", plugin.getPluginVersion());
+
+							vs_data.add( payload );
+						}
+					}
+					message.put( "plugins", pids );
+
+					if ( vs_data.size() > 0 ){
+
+						message.put( "plugin_data", vs_data );
+					}
+				}
+			}catch( Throwable e ){
+
+				Debug.out( e );
+			}
+		}
+
+
+		return message;
+	}
+
+	public void
+	addVersionCheckClientListener(
+			boolean triggerStartListener, 
+			VersionCheckClientListener l)
+	{
+		synchronized (listeners) {
+			listeners.add(l);
+
+			if (triggerStartListener && startCheckRan) {
+				try {
+					l.versionCheckStarted(REASON_UPDATE_CHECK_START);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+	}
+
+	public void
+	removeVersionCheckClientListener(
+		VersionCheckClientListener l)
+	{
+		synchronized (listeners) {
+			listeners.remove(l);
+		}
+	}
+
+
+	public static void
+	main(
+		String[]	args )
+	{
+		try{
+			COConfigurationManager.initialise();
+
+			boolean v6= true;
+
+			// Test connectivity.
+			if (true) {
+				// System.out.println( "UDP:  " + getSingleton().getExternalIpAddressUDP(null,0,v6));
+				// System.out.println( "TCP:  " + getSingleton().getExternalIpAddressTCP(null,0,v6));
+				// System.out.println( "HTTP: " + getSingleton().getExternalIpAddressHTTP(v6));
+			}
+
+			Map data = constructVersionCheckMessage(VersionCheckClient.REASON_UPDATE_CHECK_START);
+			System.out.println("Sending (pre-initialisation):");
+			printDataMap(data);
+			System.out.println("-----------");
+
+			System.out.println("Receiving (pre-initialisation):");
+			printDataMap(getSingleton().getVersionCheckInfo(VersionCheckClient.REASON_UPDATE_CHECK_START));
+			System.out.println("-----------");
+
+			System.out.println();
+			System.out.print("Initialising core... ");
+
+			/**
+			 * Suppress all of these errors being displayed in the output.
+			 * 
+			 * These things should be temporary...
+			 */
+			AzureusCoreImpl.SUPPRESS_CLASSLOADER_ERRORS = true;
+			DownloadManagerStateImpl.SUPPRESS_FIXUP_ERRORS = true;
+
+			AzureusCore core = AzureusCoreFactory.create(); 
+			core.start();
+			System.out.println("done.");
+			System.out.println();
+			System.out.println("-----------");
+
+			data = constructVersionCheckMessage(VersionCheckClient.REASON_UPDATE_CHECK_START);
+			System.out.println("Sending (post-initialisation):");
+			printDataMap(data);
+			System.out.println("-----------");
+
+			System.out.println("Receiving (post-initialisation):");
+			printDataMap(getSingleton().getVersionCheckInfo(VersionCheckClient.REASON_UPDATE_CHECK_START));
+			System.out.println("-----------");
+			System.out.println();
+
+			System.out.print("Shutting down core... ");
+			core.stop();
+			System.out.println("done.");
+
+		}catch( Throwable e){
+			e.printStackTrace();
+		}
+	}
+
+	// Used for debugging in main.
+	private static void 
+	printDataMap(Map map) 
+		throws Exception 
+	{
+		TreeMap res = new TreeMap(map);
+		
+		Iterator key_itr = map.keySet().iterator();
+		
+		while (key_itr.hasNext()) {
+			Object key = key_itr.next();
+			Object val = map.get(key);
+			if (val instanceof byte[]) {
+				String as_bytes = ByteFormatter.nicePrint((byte[])val);
+				String as_text = new String((byte[])val, Constants.BYTE_ENCODING);
+				res.put(key, as_text + " [" + as_bytes + "]");
+			}
+		}
+
+		Iterator entries = res.entrySet().iterator();
+		Map.Entry entry;
+		while (entries.hasNext()) {
+			entry = (Map.Entry)entries.next();
+			System.out.print("  ");
+			System.out.print(entry.getKey());
+			System.out.print(": ");
+			System.out.print(entry.getValue());
+			System.out.println();
+		}
+	}
 }
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClientListener.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClientListener.java
new file mode 100644
index 0000000..317ca35
--- /dev/null
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClientListener.java
@@ -0,0 +1,32 @@
+/**
+ * Created on May 18, 2010
+ *
+ * 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.versioncheck;
+
+/**
+ * @author TuxPaper
+ * @created May 18, 2010
+ *
+ */
+public interface 
+VersionCheckClientListener
+{
+	public void 
+	versionCheckStarted(
+		String reason );
+}
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPCodecs.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPCodecs.java
index bd56a67..1d185f7 100644
--- a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPCodecs.java
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPCodecs.java
@@ -23,17 +23,12 @@
 
 package com.aelitis.azureus.core.versioncheck;
 
-import java.io.DataInputStream;
-import java.io.IOException;
+import java.io.*;
 import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
+
+import com.aelitis.net.udp.uc.*;
 
-import com.aelitis.net.udp.uc.PRUDPPacketHandler;
-import com.aelitis.net.udp.uc.PRUDPPacketReply;
-import com.aelitis.net.udp.uc.PRUDPPacketReplyDecoder;
-import com.aelitis.net.udp.uc.PRUDPPacketRequest;
-import com.aelitis.net.udp.uc.PRUDPPacketRequestDecoder;
 
 public class 
 VersionCheckClientUDPCodecs 
@@ -80,7 +75,7 @@ VersionCheckClientUDPCodecs
 				}
 			};
 					
-		Map	reply_decoders = new HashMap();
+		Map<Integer,PRUDPPacketReplyDecoder>	reply_decoders = new HashMap<Integer,PRUDPPacketReplyDecoder>();
 		
 		reply_decoders.put( new Integer( ACT_VERSION_REPLY ), reply_decoder );
 		
@@ -100,6 +95,7 @@ VersionCheckClientUDPCodecs
 					throws IOException
 				{
 					switch( action ){
+					
 						case ACT_VERSION_REQUEST:
 						{
 							return( new VersionCheckClientUDPRequest(is, connection_id, transaction_id ));
@@ -112,7 +108,7 @@ VersionCheckClientUDPCodecs
 				}
 			};
 
-		Map	request_decoders = new HashMap();
+		Map<Integer,PRUDPPacketRequestDecoder>	request_decoders = new HashMap<Integer,PRUDPPacketRequestDecoder>();
 		
 		request_decoders.put( new Integer( ACT_VERSION_REQUEST ), request_decoder );
 		
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPReply.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPReply.java
index ff82686..4d1df92 100644
--- a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPReply.java
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPReply.java
@@ -23,13 +23,10 @@
 
 package com.aelitis.azureus.core.versioncheck;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.util.Map;
 
-import org.gudy.azureus2.core3.util.BDecoder;
-import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.*;
 
 
 
@@ -39,7 +36,7 @@ public class
 VersionCheckClientUDPReply 
 	extends PRUDPPacketReply
 {
-	private Map	payload;
+	private Map<String,Object>	payload;
 	
 	public
 	VersionCheckClientUDPReply(
@@ -68,7 +65,7 @@ VersionCheckClientUDPReply
 		
 		is.read( bytes );
 		
-		payload = BDecoder.decode( bytes );
+		payload = (Map<String,Object>)BDecoder.decode( bytes );
 	}
 	
 	public void
@@ -86,7 +83,7 @@ VersionCheckClientUDPReply
 		os.write( bytes );
 	}
 	
-	public Map
+	public Map<String,Object>
 	getPayload()
 	{
 		return( payload );
@@ -94,7 +91,7 @@ VersionCheckClientUDPReply
 	
 	public void
 	setPayload(
-		Map		_payload )
+		Map<String,Object>		_payload )
 	{
 		payload	= _payload;
 	}
diff --git a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPRequest.java b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPRequest.java
index a9e76d0..b401103 100644
--- a/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPRequest.java
+++ b/com/aelitis/azureus/core/versioncheck/VersionCheckClientUDPRequest.java
@@ -23,13 +23,10 @@
 
 package com.aelitis.azureus.core.versioncheck;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.util.Map;
 
-import org.gudy.azureus2.core3.util.BDecoder;
-import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.net.udp.uc.PRUDPPacketRequest;
 
@@ -37,7 +34,7 @@ public class
 VersionCheckClientUDPRequest 
 	extends PRUDPPacketRequest
 {
-	private Map	payload;
+	private Map<String,Object>	payload;
 	
 	public
 	VersionCheckClientUDPRequest(
@@ -67,7 +64,7 @@ VersionCheckClientUDPRequest
 		
 		is.read( bytes );
 		
-		payload = BDecoder.decode( bytes );
+		payload = (Map<String,Object>)BDecoder.decode( bytes );
 	}
 	
 	public void
@@ -85,7 +82,7 @@ VersionCheckClientUDPRequest
 		os.write( bytes );
 	}
 	
-	public Map
+	public Map<String,Object>
 	getPayload()
 	{
 		return( payload );
@@ -93,7 +90,7 @@ VersionCheckClientUDPRequest
 	
 	public void
 	setPayload(
-		Map		_payload )
+		Map<String,Object>		_payload )
 	{
 		payload	= _payload;
 	}
diff --git a/com/aelitis/azureus/core/vuzefile/VuzeFile.java b/com/aelitis/azureus/core/vuzefile/VuzeFile.java
index 36e5c52..6fb6193 100644
--- a/com/aelitis/azureus/core/vuzefile/VuzeFile.java
+++ b/com/aelitis/azureus/core/vuzefile/VuzeFile.java
@@ -28,6 +28,9 @@ import java.util.Map;
 public interface 
 VuzeFile 
 {
+	public String
+	getName();
+	
 	public VuzeFileComponent[]
 	getComponents();
 	
diff --git a/com/aelitis/azureus/core/vuzefile/VuzeFileComponent.java b/com/aelitis/azureus/core/vuzefile/VuzeFileComponent.java
index 6280f85..f172895 100644
--- a/com/aelitis/azureus/core/vuzefile/VuzeFileComponent.java
+++ b/com/aelitis/azureus/core/vuzefile/VuzeFileComponent.java
@@ -35,10 +35,15 @@ VuzeFileComponent
 	public static final int COMP_TYPE_SUBSCRIPTION_SINGLETON	= 0x00000020;
 	public static final int COMP_TYPE_CUSTOMIZATION				= 0x00000040;
 	public static final int COMP_TYPE_CONTENT_NETWORK			= 0x00000080;
+	public static final int COMP_TYPE_METASEARCH_OPERATION		= 0x00000100;
+	public static final int COMP_TYPE_DEVICE					= 0x00000200;
 
 	public int
 	getType();
 	
+	public String
+	getTypeName();
+	
 	public Map
 	getContent();
 	
diff --git a/com/aelitis/azureus/core/vuzefile/VuzeFileHandler.java b/com/aelitis/azureus/core/vuzefile/VuzeFileHandler.java
index 5ebc5c2..cbc472e 100644
--- a/com/aelitis/azureus/core/vuzefile/VuzeFileHandler.java
+++ b/com/aelitis/azureus/core/vuzefile/VuzeFileHandler.java
@@ -101,6 +101,34 @@ VuzeFileHandler
 		return( getVuzeFile( is ));
 	}
 	
+	public VuzeFile
+	loadVuzeFile(
+		File 	file )
+	{
+		InputStream is = null;
+		
+		try{
+			is = new FileInputStream( file );
+			
+			return( getVuzeFile( is ));
+			
+		}catch( Throwable e ){
+			
+			return( null );
+			
+		}finally{
+	
+			if ( is != null ){
+				
+				try{
+					is.close();
+					
+				}catch( Throwable e ){	
+				}
+			}
+		}
+	}
+	
 	protected VuzeFile
 	getVuzeFile(
 		InputStream		is )
diff --git a/com/aelitis/azureus/core/vuzefile/VuzeFileImpl.java b/com/aelitis/azureus/core/vuzefile/VuzeFileImpl.java
index 78d1f06..8b400a8 100644
--- a/com/aelitis/azureus/core/vuzefile/VuzeFileImpl.java
+++ b/com/aelitis/azureus/core/vuzefile/VuzeFileImpl.java
@@ -64,6 +64,19 @@ VuzeFileImpl
 		}
 	}
 	
+	public String
+	getName()
+	{
+		String str = "";
+		
+		for ( VuzeFileComponent comp: components ){
+			
+			str += (str.length()==0?"":",") + comp.getTypeName();
+		}
+		
+		return( str );
+	}
+	
 	public VuzeFileComponent[] 
 	getComponents()
 	{
@@ -171,6 +184,35 @@ VuzeFileImpl
 			return( type );
 		}
 		
+		public String 
+		getTypeName() 
+		{
+			switch( type ){
+				case COMP_TYPE_NONE: 
+					return( "None" );
+				case COMP_TYPE_METASEARCH_TEMPLATE: 
+					return( "Search Template" );
+				case COMP_TYPE_V3_NAVIGATION: 
+					return( "Navigation" );
+				case COMP_TYPE_V3_CONDITION_CHECK: 
+					return( "Condition Check" );
+				case COMP_TYPE_PLUGIN: 
+					return( "Plugin" );
+				case COMP_TYPE_SUBSCRIPTION: 
+					return( "Subscription" );
+				case COMP_TYPE_SUBSCRIPTION_SINGLETON: 
+					return( "Subscription" );
+				case COMP_TYPE_CUSTOMIZATION: 
+					return( "Customization" );
+				case COMP_TYPE_CONTENT_NETWORK: 
+					return( "Content Network" );
+				case COMP_TYPE_METASEARCH_OPERATION: 
+					return( "Search Operation" );
+				default: 
+					return( "Unknown" );
+			}
+		}
+		
 		public Map
 		getContent()
 		{
diff --git a/com/aelitis/azureus/launcher/Launcher.java b/com/aelitis/azureus/launcher/Launcher.java
index f286eb6..f976252 100644
--- a/com/aelitis/azureus/launcher/Launcher.java
+++ b/com/aelitis/azureus/launcher/Launcher.java
@@ -22,8 +22,6 @@ package com.aelitis.azureus.launcher;
 import java.lang.reflect.Method;
 import java.net.URL;
 
-import org.gudy.azureus2.core3.util.Constants;
-
 import com.aelitis.azureus.launcher.classloading.*;
 
 /**
@@ -35,7 +33,9 @@ import com.aelitis.azureus.launcher.classloading.*;
  */
 public class Launcher {
 	
-	private final static boolean LOADER_ENABLED = !Constants.isOSX; 
+	private final static String  OSName 		= System.getProperty("os.name");
+	private final static boolean isOSX			= OSName.toLowerCase().startsWith("mac os");
+	private final static boolean LOADER_ENABLED = !isOSX; 
 	
 	/**
 	 * Bootstraps a new {@link PrimaryClassloader} from the system class loader,
diff --git a/com/aelitis/azureus/plugins/clientid/ClientIDPlugin.java b/com/aelitis/azureus/plugins/clientid/ClientIDPlugin.java
index a99c767..b01ed60 100644
--- a/com/aelitis/azureus/plugins/clientid/ClientIDPlugin.java
+++ b/com/aelitis/azureus/plugins/clientid/ClientIDPlugin.java
@@ -83,6 +83,13 @@ ClientIDPlugin
 	doHTTPProperties(
 		Properties			properties )
 	{
+		Boolean	raw = (Boolean)properties.get( ClientIDGenerator.PR_RAW_REQUEST );
+		
+		if ( raw != null && raw ){
+			
+			return;
+		}
+		
 		String	version = Constants.AZUREUS_VERSION;
 		
 			// trim of any _Bnn or _CVS suffix as unfortunately some trackers can't cope with this
@@ -107,6 +114,4 @@ ClientIDPlugin
 		
 		properties.put( ClientIDGenerator.PR_USER_AGENT, agent );
 	}
-	
-
 }
diff --git a/com/aelitis/azureus/plugins/dht/DHTPlugin.java b/com/aelitis/azureus/plugins/dht/DHTPlugin.java
index 7ea77bf..ff09282 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPlugin.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPlugin.java
@@ -95,6 +95,9 @@ DHTPlugin
 	public static final byte		DT_FREQUENCY		= DHT.DT_FREQUENCY;
 	public static final byte		DT_SIZE				= DHT.DT_SIZE;
 	
+	public static final int			NW_MAIN				= DHT.NW_MAIN;
+	public static final int			NW_CVS				= DHT.NW_CVS;
+
 	public static final int			MAX_VALUE_SIZE		= DHT.MAX_VALUE_SIZE;
 
 	private static final String	PLUGIN_VERSION			= "1.0";
@@ -252,9 +255,10 @@ DHTPlugin
 		final DHTPluginOperationListener log_polistener =
 			new DHTPluginOperationListener()
 			{
-				public void
+				public boolean
 				diversified()
 				{
+					return( true );
 				}
 				
 				public void 
@@ -1118,10 +1122,10 @@ DHTPlugin
 			DHTPluginOperationListener main_listener = 
 				new DHTPluginOperationListener()
 				{
-					public void
+					public boolean
 					diversified()
 					{
-						listener.diversified();
+						return( listener.diversified());
 					}
 					
 					public void 
@@ -1172,9 +1176,10 @@ DHTPlugin
 						key, description, value, flags, high_priority,
 						new DHTPluginOperationListener()
 						{
-							public void
+							public boolean
 							diversified()
 							{
+								return( true );
 							}
 							
 							public void 
@@ -1229,6 +1234,17 @@ DHTPlugin
 		return( cvs_dht.getLocalValue( key ));
 	}
 	
+	public List<DHTPluginValue>
+	getValues()
+	{
+		if ( main_dht != null ){
+			
+			return( main_dht.getValues());
+		}
+		
+		return( cvs_dht.getValues());
+	}
+	
 	public void
 	get(
 		final byte[]								original_key,
@@ -1270,10 +1286,10 @@ DHTPlugin
 			main_listener = 
 				new DHTPluginOperationListener()
 				{
-					public void
+					public boolean
 					diversified()
 					{
-						original_listener.diversified();
+						return( original_listener.diversified());
 					}
 					
 					public void 
@@ -1322,9 +1338,10 @@ DHTPlugin
 					original_key, description, flags, max_values, timeout, exhaustive, high_priority,
 					new DHTPluginOperationListener()
 					{
-						public void
+						public boolean
 						diversified()
 						{
+							return( true );
 						}
 						
 						public void 
@@ -1392,9 +1409,10 @@ DHTPlugin
 					private int	complete_count 	= 0;
 					private int	result_count	= 0;
 					
-					public void
+					public boolean
 					diversified()
 					{
+						return( main_listener.diversified());
 					}
 					
 					public void 
@@ -1557,9 +1575,10 @@ DHTPlugin
 							key, description, 
 							new DHTPluginOperationListener()
 							{
-								public void
+								public boolean
 								diversified()
 								{
+									return( true );
 								}
 								
 								public void 
@@ -1655,9 +1674,10 @@ DHTPlugin
 						dht_targets, key, description,
 						new DHTPluginOperationListener()
 						{
-							public void
+							public boolean
 							diversified()
 							{
+								return( true );
 							}
 							
 							public void 
@@ -1732,6 +1752,42 @@ DHTPlugin
 	}
 	
 	public DHTPluginContact
+	importContact(
+		InetSocketAddress				address,
+		byte							version,
+		boolean							is_cvs )
+	{
+		if ( !isEnabled()){
+			
+			throw( new RuntimeException( "DHT isn't enabled" ));
+		}
+
+		InetAddress contact_address = address.getAddress();
+		
+		int	target_network = is_cvs?DHT.NW_CVS:DHT.NW_MAIN;
+		
+		for ( DHTPluginImpl dht: dhts ){
+			
+			if ( dht.getDHT().getTransport().getNetwork() != target_network ){
+				
+				continue;
+			}
+			
+			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 ));
+			}
+		}
+		
+			// fallback
+		
+		return( importContact( address, version ));
+	}
+	
+	public DHTPluginContact
 	getLocalAddress()
 	{
 		if ( !isEnabled()){
@@ -1768,6 +1824,12 @@ DHTPlugin
 		return( status );
 	}
 	
+	public boolean
+	isSleeping()
+	{
+		return( AERunStateHandler.isDHTSleeping());
+	}
+	
 	public DHT[]
 	getDHTs()
 	{
diff --git a/com/aelitis/azureus/plugins/dht/DHTPluginContact.java b/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
index 3eed59f..53b4802 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPluginContact.java
@@ -34,6 +34,9 @@ import java.util.Map;
 public interface 
 DHTPluginContact 
 {
+	public byte[]
+	getID();
+	
 	public String
 	getName();
 	
@@ -43,6 +46,9 @@ DHTPluginContact
 	public byte
 	getProtocolVersion();
 	
+	public int
+	getNetwork();
+	
 	public boolean
 	isAlive(
 		long		timeout );
diff --git a/com/aelitis/azureus/plugins/dht/DHTPluginOperationListener.java b/com/aelitis/azureus/plugins/dht/DHTPluginOperationListener.java
index c570b44..b6956fe 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPluginOperationListener.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPluginOperationListener.java
@@ -34,7 +34,7 @@ DHTPluginOperationListener
 	starts(
 		byte[]				key );
 	
-	public void
+	public boolean
 	diversified();
 	
 	public void
diff --git a/com/aelitis/azureus/plugins/dht/DHTPluginValue.java b/com/aelitis/azureus/plugins/dht/DHTPluginValue.java
index 18b03fa..ac47938 100644
--- a/com/aelitis/azureus/plugins/dht/DHTPluginValue.java
+++ b/com/aelitis/azureus/plugins/dht/DHTPluginValue.java
@@ -39,6 +39,9 @@ DHTPluginValue
 	public long
 	getVersion();
 	
+	public boolean
+	isLocal();
+	
 	public int
 	getFlags();
 }
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
index 0513dce..ea272de 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginContactImpl.java
@@ -60,12 +60,24 @@ DHTPluginContactImpl
 		return( contact );
 	}
 	
+	public byte[]
+	getID()
+	{
+		return( contact.getID());
+	}
+	
 	public String
 	getName()
 	{
 		return( contact.getName());
 	}
 	
+	public int
+	getNetwork()
+	{
+		return( plugin.getDHT().getTransport().getNetwork());
+	}
+	
 	public byte
 	getProtocolVersion()
 	{
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
index 31f3cdd..53e4047 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginImpl.java
@@ -28,12 +28,16 @@ import java.io.DataInputStream;
 import java.io.File;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Properties;
 
 
 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.HashWrapper;
 import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.download.Download;
@@ -52,7 +56,10 @@ import com.aelitis.azureus.core.dht.DHTOperationListener;
 import com.aelitis.azureus.core.dht.DHTStorageKeyStats;
 
 import com.aelitis.azureus.core.dht.control.DHTControlStats;
+import com.aelitis.azureus.core.dht.db.DHTDB;
 import com.aelitis.azureus.core.dht.db.DHTDBStats;
+import com.aelitis.azureus.core.dht.db.DHTDBValue;
+import com.aelitis.azureus.core.dht.nat.DHTNATPuncher;
 import com.aelitis.azureus.core.dht.nat.DHTNATPuncherAdapter;
 import com.aelitis.azureus.core.dht.router.DHTRouterStats;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
@@ -190,6 +197,11 @@ DHTPluginImpl
 					}
 					
 					public void
+					resetNetworkPositions()
+					{
+					}
+					
+					public void
 					currentAddress(
 						String		address )
 					{
@@ -399,7 +411,8 @@ DHTPluginImpl
 		log.log( "DHT:ip=" + transport.getLocalContact().getAddress() + 
 					",net=" + transport.getNetwork() +
 					",prot=V" + transport.getProtocolVersion()+
-					",reach=" + transport.isReachable());
+					",reach=" + transport.isReachable()+
+					",flags=" + Integer.toString((int)(transport.getGenericFlags()&0xff), 16 ));
 
 		log.log( 	"Router" +
 					":nodes=" + rs[DHTRouterStats.ST_NODES] +
@@ -423,6 +436,12 @@ DHTPluginImpl
 				   	",ind=" + dbv_details[DHTDBStats.VD_INDIRECT_SIZE]+
 				   	",div_f=" + dbv_details[DHTDBStats.VD_DIV_FREQ]+
 				   	",div_s=" + dbv_details[DHTDBStats.VD_DIV_SIZE] );
+		
+		DHTNATPuncher np = dht.getNATPuncher();
+		
+		if ( np != null ){
+			log.log( "NAT: " + np.getStats());
+		}
 	}
 	
 	protected File
@@ -707,10 +726,11 @@ outer:
 							}
 						}
 
-						public void
+						public boolean
 						diversified(
 							String		desc )
 						{
+							return( true );
 						}
 						
 						public void
@@ -770,6 +790,28 @@ outer:
 		return( mapValue( val ));
 	}
 	
+	public List<DHTPluginValue>
+	getValues()
+	{
+		DHTDB	db = dht.getDataBase();
+		
+		Iterator<HashWrapper>	keys = db.getKeys();
+		
+		List<DHTPluginValue>	vals = new ArrayList<DHTPluginValue>();
+		
+		while( keys.hasNext()){
+			
+			DHTDBValue val = db.getAnyValue( keys.next());
+			
+			if ( val != null ){
+				
+				vals.add( mapValue( val ));
+			}
+		}
+		
+		return( vals );
+	}
+	
 	public void
 	get(
 		final byte[]								key,
@@ -808,14 +850,16 @@ outer:
 							}
 						}
 						
-						public void
+						public boolean
 						diversified(
 							String		desc )
 						{
 							if ( listener != null ){
 								
-								listener.diversified();
+								return( listener.diversified());
 							}
+							
+							return( true );
 						}
 						
 						public void
@@ -901,10 +945,11 @@ outer:
 							{
 							}
 
-							public void
+							public boolean
 							diversified(
 								String		desc )
 							{
+								return( true );
 							}
 							
 							public void
@@ -991,10 +1036,11 @@ outer:
 							{
 							}
 
-							public void
+							public boolean
 							diversified(
 								String		desc )
 							{
+								return( true );
 							}
 							
 							public void
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
index 1643fc5..741372f 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginStorageManager.java
@@ -52,6 +52,7 @@ import com.aelitis.azureus.core.dht.DHTStorageKey;
 import com.aelitis.azureus.core.dht.DHTStorageKeyStats;
 import com.aelitis.azureus.core.dht.impl.DHTLog;
 import com.aelitis.azureus.core.dht.transport.DHTTransportContact;
+import com.aelitis.azureus.core.dht.transport.DHTTransportFullStats;
 import com.aelitis.azureus.core.dht.transport.DHTTransportValue;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
@@ -75,8 +76,8 @@ DHTPluginStorageManager
 	private static final long		DIV_EXPIRY_RAND			= 1*24*60*60*1000L;
 	private static final long		KEY_BLOCK_TIMEOUT_SECS	= 7*24*60*60;
 	
-	public static final int			LOCAL_DIVERSIFICATION_SIZE_LIMIT			= 16*1024;
-	public static final int			LOCAL_DIVERSIFICATION_ENTRIES_LIMIT			= LOCAL_DIVERSIFICATION_SIZE_LIMIT/8;
+	public static final int			LOCAL_DIVERSIFICATION_SIZE_LIMIT			= 32*1024;
+	public static final int			LOCAL_DIVERSIFICATION_ENTRIES_LIMIT			= LOCAL_DIVERSIFICATION_SIZE_LIMIT/16;
 	public static final int			LOCAL_DIVERSIFICATION_READS_PER_MIN_SAMPLES	= 3;
 	public static final int			LOCAL_DIVERSIFICATION_READS_PER_MIN			= 30;
 	
@@ -817,9 +818,9 @@ DHTPluginStorageManager
 	
 	public byte[][]
 	createNewDiversification(
-		String				description,
-		DHTTransportContact	cause,
-		byte[]				key,
+		final String				description,
+		final DHTTransportContact	cause,
+		byte[]						key,
 		boolean				put_operation,
 		byte				diversification_type,
 		boolean				exhaustive,
@@ -867,7 +868,31 @@ DHTPluginStorageManager
 						", cause=" + (cause==null?"<unknown>":cause.getString()) +
 						", desc=" + description );
 			
-
+			/*
+			if ( cause == null ){
+				
+				Debug.out( description + ": DIV cause is null!" );
+				
+			}else{
+				
+				new AEThread2("")
+				{
+					public void
+					run()
+					{
+						DHTTransportFullStats stats = cause.getStats();
+						
+						if ( stats == null ){
+							
+							Debug.out( description + ": DIV stats is null!" );
+						}else{
+							Debug.out( description + ": DIV stats: " + stats.getString());
+						}
+					}
+				}.start();
+			}
+			*/
+			
 			return( res );
 			
 		}finally{
diff --git a/com/aelitis/azureus/plugins/dht/impl/DHTPluginValueImpl.java b/com/aelitis/azureus/plugins/dht/impl/DHTPluginValueImpl.java
index ba47310..21e6cca 100644
--- a/com/aelitis/azureus/plugins/dht/impl/DHTPluginValueImpl.java
+++ b/com/aelitis/azureus/plugins/dht/impl/DHTPluginValueImpl.java
@@ -57,6 +57,12 @@ DHTPluginValueImpl
 		return( value.getVersion());
 	}
 	
+	public boolean 
+	isLocal() 
+	{
+		return( value.isLocal());
+	}
+	
 	public int
 	getFlags()
 	{
diff --git a/com/aelitis/azureus/plugins/extseed/ExternalSeedPeer.java b/com/aelitis/azureus/plugins/extseed/ExternalSeedPeer.java
index 17b4f1b..bf91e07 100644
--- a/com/aelitis/azureus/plugins/extseed/ExternalSeedPeer.java
+++ b/com/aelitis/azureus/plugins/extseed/ExternalSeedPeer.java
@@ -22,12 +22,15 @@
 
 package com.aelitis.azureus.plugins.extseed;
 
+import java.net.URL;
 import java.util.*;
 
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.messaging.Message;
 import org.gudy.azureus2.plugins.network.Connection;
+import org.gudy.azureus2.plugins.network.ConnectionStub;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.peers.*;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.utils.*;
@@ -43,6 +46,7 @@ ExternalSeedPeer
 	
 	private Download				download;
 	private PeerManager				manager;
+	private ConnectionStub			connection_stub;
 	private PeerStats				stats;
 	private Map						user_data;
 	
@@ -59,7 +63,7 @@ ExternalSeedPeer
 	private Monitor					connection_mon;
 	private boolean					peer_added;
 	
-	private List					request_list = new ArrayList();
+	private List<PeerReadRequest>					request_list = new ArrayList<PeerReadRequest>();
 	
 	private CopyOnWriteList			listeners;
 	private Monitor					listeners_mon;
@@ -146,6 +150,13 @@ ExternalSeedPeer
 		return( download );
 	}
 	
+	public void
+	bindConnection(
+		ConnectionStub		stub )
+	{
+		connection_stub	= stub;
+	}
+	
 	protected ExternalSeedReader
 	getReader()
 	{
@@ -342,6 +353,12 @@ ExternalSeedPeer
 		return( peer_id );
 	}
   
+	public URL
+	getURL()
+	{
+		return( reader.getURL());
+	}
+	
 	public String 
 	getIp()
 	{
@@ -526,11 +543,23 @@ ExternalSeedPeer
 		
 	}
   		
-	public List
+	public List<PeerReadRequest>
 	getRequests()
 	{
-		return( reader.getRequests());
+		List<PeerReadRequest> requests = reader.getRequests();
+		
+		if ( request_list.size() > 0 ){
+			
+			try{
+				requests.addAll( request_list );
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
 		
+		return( requests );
 	}
 
 	public int
@@ -591,15 +620,18 @@ ExternalSeedPeer
 	public boolean 
 	addRequest(
 		PeerReadRequest	request )
-	{		
+	{	
 		if ( !doing_allocations ){
 			
 			Debug.out( "request added when not in allocation phase" );
 		}
 		
-		request_list.add( request );
-		
-		snubbed = 0;
+		if ( !request_list.contains( request )){
+			
+			request_list.add( request );
+			
+			snubbed = 0;
+		}
 		
 		return( true );
 	}
@@ -661,6 +693,11 @@ ExternalSeedPeer
 		}
 	}
 	
+	public void
+	remove()
+	{
+		plugin.removePeer( this );
+	}
 
 	public void	
 	addListener( 
@@ -810,7 +847,7 @@ ExternalSeedPeer
 			
 			stats.received( res );
 		}
-		
+				
 		return( res );
 	}
 	
@@ -821,6 +858,36 @@ ExternalSeedPeer
 		throw( new RuntimeException( "Not supported" ));
 	}
 	
+	public void
+	addRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		if ( connection_stub != null ){
+			
+			connection_stub.addRateLimiter( limiter, is_upload );
+			
+		}else{
+			
+			Debug.out( "connection not bound" );
+		}
+	}
+
+	public void
+	removeRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		if ( connection_stub != null ){
+			
+			connection_stub.removeRateLimiter( limiter, is_upload );
+			
+		}else{
+			
+			Debug.out( "connection not bound" );
+		}	
+	}
+	  
 	public int
 	getPercentDoneOfCurrentIncomingRequest()
 	{
@@ -862,6 +929,11 @@ ExternalSeedPeer
 	getUserData(
 		Object	key )
 	{
+		if ( key == Peer.PR_PROTOCOL ){
+			
+			return( reader.getURL().getProtocol().toUpperCase());
+		}
+		
 		if ( user_data == null ){
 			
 			return( null );
diff --git a/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java b/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
index 24d09a8..827344b 100644
--- a/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
+++ b/com/aelitis/azureus/plugins/extseed/ExternalSeedPlugin.java
@@ -27,6 +27,7 @@ import java.io.StringWriter;
 import java.util.*;
 
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.Plugin;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
@@ -37,10 +38,14 @@ 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.torrent.TorrentAttribute;
 import org.gudy.azureus2.plugins.ui.components.UITextField;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.plugins.utils.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 import com.aelitis.azureus.plugins.extseed.impl.getright.ExternalSeedReaderFactoryGetRight;
 import com.aelitis.azureus.plugins.extseed.impl.webseed.ExternalSeedReaderFactoryWebSeed;
 
@@ -211,16 +216,30 @@ ExternalSeedPlugin
 		List	peers = new ArrayList();
 		
 		for (int i=0;i<factories.length;i++){
+
+
+			String attributeID = "no-ext-seeds-" + factories[i].getClass().getSimpleName();
+			TorrentAttribute attribute = plugin_interface.getTorrentManager().getPluginAttribute( attributeID );
+
+			boolean noExternalSeeds = download.getBooleanAttribute(attribute);
+			if (noExternalSeeds) {
+				continue;  	
+			}
 			
 			ExternalSeedReader[]	x = factories[i].getSeedReaders( this, download );
 			
-			for (int j=0;j<x.length;j++){
-				
-				ExternalSeedReader	reader = x[j];
-				
-				ExternalSeedPeer	peer = new ExternalSeedPeer( this, download, reader );
-				
-				peers.add( peer );
+			if (x.length == 0) {
+				download.setBooleanAttribute(attribute, true);
+			} else {
+
+  			for (int j=0;j<x.length;j++){
+  				
+  				ExternalSeedReader	reader = x[j];
+  				
+  				ExternalSeedPeer	peer = new ExternalSeedPeer( this, download, reader );
+  				
+  				peers.add( peer );
+  			}
 			}
 		}
 		
@@ -236,35 +255,40 @@ ExternalSeedPlugin
 		downloadAdded( download );
 	}
 	
-	public void
+	public List<ExternalSeedPeer>
 	addSeed(
 		Download	download,
 		Map			config )
 	{
 		Torrent	torrent = download.getTorrent();
 		
-		if ( torrent == null ){
-			
-			return;
-		}
-		
-		List	peers = new ArrayList();
-		
-		for (int i=0;i<factories.length;i++){
-			
-			ExternalSeedReader[]	x = factories[i].getSeedReaders( this, download, config );
-			
-			for (int j=0;j<x.length;j++){
+		List<ExternalSeedPeer>	peers = new ArrayList<ExternalSeedPeer>();
+		 
+		if ( torrent != null ){
+						
+			for (int i=0;i<factories.length;i++){
 				
-				ExternalSeedReader	reader = x[j];
+				String attributeID = "no-ext-seeds-" + factories[i].getClass().getSimpleName();
+				TorrentAttribute attribute = plugin_interface.getTorrentManager().getPluginAttribute( attributeID );
+
+				ExternalSeedReader[]	x = factories[i].getSeedReaders( this, download, config );
 				
-				ExternalSeedPeer	peer = new ExternalSeedPeer( this, download, reader );
+				download.setBooleanAttribute(attribute, x.length == 0);
 				
-				peers.add( peer );
+				for (int j=0;j<x.length;j++){
+					
+					ExternalSeedReader	reader = x[j];
+					
+					ExternalSeedPeer	peer = new ExternalSeedPeer( this, download, reader );
+					
+					peers.add( peer );
+				}
 			}
+			
+			addPeers( download, peers );
 		}
 		
-		addPeers( download, peers );
+		return( peers );
 	}
 	
 	protected void
@@ -476,6 +500,11 @@ ExternalSeedPlugin
 		
 			List	peers = (List)download_map.get( download );
 	
+			if ( peers == null ){
+				
+				return( new ExternalSeedManualPeer[0] );
+			}
+			
 			ExternalSeedManualPeer[]	result = new ExternalSeedManualPeer[peers.size()];
 			
 			for (int i=0;i<peers.size();i++){
@@ -491,6 +520,107 @@ ExternalSeedPlugin
 		}	
 	}
 	
+	public TrackerPeerSource
+	getTrackerPeerSource(
+		final Download		download )
+	{
+		return(
+			new TrackerPeerSourceAdapter()
+			{
+				private long	fixup_time;
+				
+				private ExternalSeedManualPeer[]	peers;						
+				private boolean						running;
+				
+				public int
+				getType()
+				{
+					return( TP_HTTP_SEED );
+				}
+				
+				public int
+				getStatus()
+				{
+					fixup();
+					
+					if ( running ){
+					
+						return( peers.length==0?ST_UNAVAILABLE:ST_AVAILABLE );
+						
+					}else{
+						
+						return( ST_STOPPED );
+					}
+				}
+				
+				public String
+				getName()
+				{
+					fixup();
+					
+					if ( peers.length == 0 ){
+						
+						return( "" );
+					}
+					
+					StringBuffer sb = new StringBuffer();
+					
+					for ( ExternalSeedManualPeer peer: peers ){
+						
+						if ( sb.length() > 0 ){
+							
+							sb.append( ", " );
+						}
+						
+						String str = peer.getDelegate().getURL().toExternalForm();
+						
+						int pos = str.indexOf( '?' );
+						
+						if ( pos != -1 ){
+							
+							str = str.substring( 0, pos );
+						}
+						
+						sb.append( str );
+					}
+					
+					return( sb.toString());
+				}
+				
+				public int
+				getPeers()
+				{
+					fixup();
+					
+					if ( running ){
+					
+						return( peers.length );
+						
+					}else{
+						
+						return( -1 );
+					}
+				}
+				
+				protected void
+				fixup()
+				{
+					long	now = SystemTime.getMonotonousTime();
+					
+					if ( now - fixup_time > 10*1000 ){
+					
+						fixup_time = now;
+						
+						peers = getManualWebSeeds(download);
+						
+						int	state = download.getState();
+						
+						running = state == Download.ST_DOWNLOADING || state == Download.ST_SEEDING;
+					}
+				}
+			});
+	}
+	
 	public int
 	getGlobalDownloadRateBytesPerSec()
 	{
diff --git a/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java b/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
index d190c93..c3398ae 100644
--- a/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
+++ b/com/aelitis/azureus/plugins/extseed/ExternalSeedReader.java
@@ -22,6 +22,7 @@
 
 package com.aelitis.azureus.plugins.extseed;
 
+import java.net.URL;
 import java.util.List;
 
 import org.gudy.azureus2.plugins.peers.Peer;
@@ -49,6 +50,9 @@ ExternalSeedReader
 	public boolean
 	isPermanentlyUnavailable();
 	
+	public URL
+	getURL();
+	
 	public String
 	getIP();
 	
diff --git a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
index f092f8b..a28e1fc 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/ExternalSeedReaderImpl.java
@@ -22,6 +22,7 @@
 
 package com.aelitis.azureus.plugins.extseed.impl;
 
+import java.net.URL;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
@@ -1228,7 +1229,7 @@ ExternalSeedReaderImpl
 				request.cancel();
 			}
 			
-			if ( dangling_requests != null & dangling_requests.contains( request ) && !request.isCancelled()){
+			if ( dangling_requests != null && dangling_requests.contains( request ) && !request.isCancelled()){
 				
 				request.cancel();
 			}
diff --git a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
index 70d8d57..33d267c 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderFactoryGetRight.java
@@ -131,23 +131,26 @@ ExternalSeedReaderFactoryGetRight
 					}
 					
 					try{	
-						String	url_str = new String((byte[])urls.get(i));
+						String	url_str = new String((byte[])urls.get(i), "UTF-8" );
 						
 							// avoid java encoding ' ' as '+' as this is not conformant with Apache (for example)
 						
 						url_str = url_str.replaceAll( " ", "%20");
 
-						URL	url = new URL( url_str );
-						
-						String	protocol = url.getProtocol().toLowerCase();
-																		
-						if ( protocol.equals( "http" )){
-							
-							readers.add( new ExternalSeedReaderGetRight(plugin, download.getTorrent(), url, my_params ));
+						if ( url_str.length() > 0 ){
 							
-						}else{
+							URL	url = new URL( url_str );
 							
-							plugin.log( download.getName() + ": GR unsupported protocol: " + url );
+							String	protocol = url.getProtocol().toLowerCase();
+																			
+							if ( protocol.equals( "http" )){
+								
+								readers.add( new ExternalSeedReaderGetRight(plugin, download.getTorrent(), url, my_params ));
+								
+							}else{
+								
+								plugin.log( download.getName() + ": GR unsupported protocol: " + url );
+							}
 						}
 					}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 6e4ca1d..3f46833 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/getright/ExternalSeedReaderGetRight.java
@@ -176,7 +176,13 @@ ExternalSeedReaderGetRight
 	{
 		return( "GR: " + url );
 	}
-		
+	
+	public URL 
+	getURL() 
+	{
+		return( url );
+	}
+	
 	public int
 	getPort()
 	{
@@ -283,7 +289,7 @@ ExternalSeedReaderGetRight
 	{	
 		setReconnectDelay( RECONNECT_DEFAULT, false );
 		
-		long	request_start 	= start_piece_number * piece_size + start_piece_offset;
+		long	request_start 	= start_piece_number * (long)piece_size + start_piece_offset;
 		int		request_length	= length;
 		
 		if ( http_downloaders.length == 1 ){
diff --git a/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java b/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
index 48e4b6b..f9982b2 100644
--- a/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
+++ b/com/aelitis/azureus/plugins/extseed/impl/webseed/ExternalSeedReaderWebSeed.java
@@ -96,7 +96,13 @@ ExternalSeedReaderWebSeed
 	{
 		return( "WS: " + url );
 	}
-		
+	
+	public URL 
+	getURL() 
+	{
+		return( url );
+	}
+	
 	public int
 	getPort()
 	{
diff --git a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java
index b333cc6..eb09d7d 100644
--- a/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java
+++ b/com/aelitis/azureus/plugins/extseed/util/ExternalSeedHTTPDownloaderRange.java
@@ -31,8 +31,15 @@ import java.net.InetSocketAddress;
 import java.net.PasswordAuthentication;
 import java.net.Socket;
 import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.StringTokenizer;
 
+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.security.SEPasswordListener;
 import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.util.Debug;
@@ -121,64 +128,130 @@ ExternalSeedHTTPDownloaderRange
 			HttpURLConnection	connection;
 			int					response;
 			
+			Set<String>	redirect_urls = new HashSet<String>();
+			
+redirect_loop:
 			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 ){
+				for ( int ssl_loop=0; ssl_loop<2; ssl_loop++ ){
 					
-					Java15Utils.setConnectTimeout( connection, time_remaining );
-				}
+					try{
+						connection = (HttpURLConnection)target.openConnection();
+						
+						if ( connection instanceof HttpsURLConnection ){
 							
-				connection.connect();
-			
-				time_remaining	= listener.getPermittedTime();
+							HttpsURLConnection ssl_con = (HttpsURLConnection)connection;
+							
+								// allow for certs that contain IP addresses rather than dns names
+		  	
+							ssl_con.setHostnameVerifier(
+								new HostnameVerifier()
+								{
+									public boolean
+									verify(
+										String		host,
+										SSLSession	session )
+									{
+										return( true );
+									}
+								});
+						}
+						
+						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 );
+						}
 									
-				if ( time_remaining < 0 ){
+						connection.connect();
 					
-					throw( new IOException( "Timeout during connect" ));
-				}
-				
-				Java15Utils.setReadTimeout( connection, time_remaining );
+						time_remaining	= listener.getPermittedTime();
+											
+						if ( time_remaining < 0 ){
+							
+							throw( new IOException( "Timeout during connect" ));
+						}
 						
-				connected	= true;
-				
-				response = connection.getResponseCode();
-
-				if (	response == HttpURLConnection.HTTP_ACCEPTED || 
-						response == HttpURLConnection.HTTP_OK ||
-						response == HttpURLConnection.HTTP_PARTIAL ){
+						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 redirect_loop;
+							
+						}else if ( 	response == HttpURLConnection.HTTP_MOVED_TEMP ||
+									response == HttpURLConnection.HTTP_MOVED_PERM ){
+							
+								// auto redirect doesn't work from http to https or vice-versa
+							
+							String	move_to = connection.getHeaderField( "location" );
+							
+							if ( move_to != null ){
+								
+								if ( redirect_urls.contains( move_to ) || redirect_urls.size() > 32 ){
+									
+									throw( new ExternalSeedException( "redirect loop" )); 
+								}
+								
+								redirect_urls.add( move_to );
+								
+								redirected_url = new URL( move_to );
+								
+								continue redirect_loop;
+							}
+						}
+						
+						if ( redirected_url == null ){
+							
+							break redirect_loop;
+						}
+						
+							// try again with original URL
+						
+						consec_redirect_fails++;
+						
+						redirected_url = null;
 					
-					if ( redirected_url != null ){
+					}catch( SSLException e ){
 						
-						consec_redirect_fails = 0;
+						if ( ssl_loop == 0 ){
+							
+							if ( SESecurityManager.installServerCertificates( target ) != null ){
+								
+									// certificate has been installed
+								
+								continue;	// retry with new certificate
+							}
+						}
+	
+						throw( e );
 					}
 					
-					break;
-				}
-				
-				if ( redirected_url == null ){
+						// don't need another SSL loop
 					
 					break;
 				}
-				
-					// try again with original URL
-				
-				consec_redirect_fails++;
-				
-				redirected_url = null;
 			}
 			
 			URL final_url = connection.getURL();
diff --git a/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java b/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
index 26d47fa..fa27395 100644
--- a/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
+++ b/com/aelitis/azureus/plugins/magnet/MagnetPlugin.java
@@ -34,17 +34,24 @@ import java.util.Set;
 import java.net.InetSocketAddress;
 import org.eclipse.swt.graphics.Image;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLGroup;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
 import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.util.AEMonitor;
 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.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.Debug;
 import org.gudy.azureus2.core3.util.DelayedEvent;
+import org.gudy.azureus2.core3.util.SimpleTimer;
 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.TorrentUtils;
 import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.plugins.*;
@@ -57,11 +64,17 @@ 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.DownloadException;
+import org.gudy.azureus2.plugins.sharing.ShareException;
+import org.gudy.azureus2.plugins.sharing.ShareResourceDir;
+import org.gudy.azureus2.plugins.sharing.ShareResourceFile;
 import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.plugins.torrent.TorrentAnnounceURLList;
+import org.gudy.azureus2.plugins.torrent.TorrentAnnounceURLListSet;
 import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.ui.UIManagerListener;
 import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.ui.config.IntParameter;
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
@@ -87,10 +100,16 @@ public class
 MagnetPlugin
 	implements Plugin
 {	
+	public static final int	FL_NONE					= 0x00000000;
+	public static final int	FL_DISABLE_MD_LOOKUP	= 0x00000001;
+	
 	private static final String	SECONDARY_LOOKUP 			= "http://magnet.vuze.com/";
-	private static final int	SECONDARY_LOOKUP_DELAY		= 20*1000;
+	private static final int	SECONDARY_LOOKUP_DELAY		= 1*1000; // 20*1000;
 	private static final int	SECONDARY_LOOKUP_MAX_TIME	= 2*60*1000;
 	
+	private static final int	MD_LOOKUP_DELAY_SECS_DEFAULT		= 20;
+
+
 	private static final String	PLUGIN_NAME				= "Magnet URI Handler";
 	private static final String PLUGIN_CONFIGSECTION_ID = "plugins.magnetplugin";
 
@@ -101,6 +120,8 @@ MagnetPlugin
 	private boolean			first_download	= true;
 	
 	private BooleanParameter secondary_lookup;
+	private BooleanParameter md_lookup;
+	private IntParameter	 md_lookup_delay;
 	
 	public static void
 	load(
@@ -120,7 +141,11 @@ MagnetPlugin
 			plugin_interface.getUIManager().createBasicPluginConfigModel( ConfigSection.SECTION_PLUGINS, 
 					PLUGIN_CONFIGSECTION_ID);
 		
-		secondary_lookup = config.addBooleanParameter2( "MagnetPlugin.use.lookup.service", "MagnetPlugin.use.lookup.service", true );
+		secondary_lookup 	= config.addBooleanParameter2( "MagnetPlugin.use.lookup.service", "MagnetPlugin.use.lookup.service", true );
+		md_lookup 			= config.addBooleanParameter2( "MagnetPlugin.use.md.download", "MagnetPlugin.use.md.download", true );
+		md_lookup_delay		= config.addIntParameter2( "MagnetPlugin.use.md.download.delay", "MagnetPlugin.use.md.download.delay", MD_LOOKUP_DELAY_SECS_DEFAULT );
+		
+		md_lookup.addEnabledOnSelection( md_lookup_delay );
 		
 		MenuItemListener	listener = 
 			new MenuItemListener()
@@ -130,17 +155,34 @@ MagnetPlugin
 					MenuItem		_menu,
 					Object			_target )
 				{
-					Download download = (Download)((TableRow)_target).getDataSource();
-				  
-					if ( download == null || download.getTorrent() == null ){
-						
+					Torrent torrent;
+					String name;
+					Object ds = ((TableRow)_target).getDataSource();
+					if (ds instanceof ShareResourceFile) {
+						try {
+							torrent = ((ShareResourceFile) ds).getItem().getTorrent();
+						} catch (ShareException e) {
+							return;
+						}
+						name = ((ShareResourceFile) ds).getName();
+					}else if (ds instanceof ShareResourceDir) {
+							try {
+								torrent = ((ShareResourceDir) ds).getItem().getTorrent();
+							} catch (ShareException e) {
+								return;
+							}
+							name = ((ShareResourceDir) ds).getName();
+					} else if (ds instanceof Download) {
+						Download download = (Download)((TableRow)_target).getDataSource();
+						torrent = download.getTorrent();
+						name = download.getName();
+					} else {
 						return;
 					}
+				  
 					
-					Torrent torrent = download.getTorrent();
+					String cb_data = UrlUtils.getMagnetURI( name, torrent );
 					
-					String	cb_data = "magnet:?xt=urn:btih:" + Base32.encode( torrent.getHash());
-
 					// removed this as well - nothing wrong with allowing magnet copy
 					// for private torrents - they still can't be tracked if you don't
 					// have permission
@@ -199,9 +241,11 @@ MagnetPlugin
 		
 		final TableContextMenuItem menu1 = plugin_interface.getUIManager().getTableManager().addContextMenuItem(TableManager.TABLE_MYTORRENTS_INCOMPLETE, "MagnetPlugin.contextmenu.exporturi" );
 		final TableContextMenuItem menu2 = plugin_interface.getUIManager().getTableManager().addContextMenuItem(TableManager.TABLE_MYTORRENTS_COMPLETE, 	"MagnetPlugin.contextmenu.exporturi" );
+		final TableContextMenuItem menu3 = plugin_interface.getUIManager().getTableManager().addContextMenuItem(TableManager.TABLE_MYSHARES, 	"MagnetPlugin.contextmenu.exporturi" );
 			
 		menu1.addListener( listener );
 		menu2.addListener( listener );
+		menu3.addListener( listener );
 
 		MagnetURIHandler.getSingleton().addListener(
 			new MagnetURIHandlerListener()
@@ -308,6 +352,12 @@ MagnetPlugin
 								}
 								
 								public boolean 
+								cancelled() 
+								{
+									return( muh_listener.cancelled());
+								}
+								
+								public boolean 
 								verbose() 
 								{
 									return( muh_listener.verbose());
@@ -316,7 +366,8 @@ MagnetPlugin
 							hash,
 							args,
 							sources,
-							timeout ));
+							timeout,
+							0 ));
 				}
 				
 				public boolean
@@ -420,6 +471,7 @@ MagnetPlugin
 
 							menu1.setGraphic( swt.createGraphic( image ));
 							menu2.setGraphic( swt.createGraphic( image ));							
+							menu3.setGraphic( swt.createGraphic( image ));							
 						}
 					}
 					
@@ -430,6 +482,48 @@ MagnetPlugin
 						
 					}
 				});
+		
+		final List<Download>	to_delete = new ArrayList<Download>();
+		
+		Download[] downloads = plugin_interface.getDownloadManager().getDownloads();
+		
+		for ( Download download: downloads ){
+			
+			if ( download.getFlag( Download.FLAG_METADATA_DOWNLOAD )){
+				
+				to_delete.add( download );
+			}
+		}
+		
+		if ( to_delete.size() > 0 ){
+			
+			AEThread2 t = 
+				new AEThread2( "MagnetPlugin:delmds", true )
+				{
+					public void
+					run()
+					{
+						for ( Download download: to_delete ){
+							
+							try{
+								download.stop();
+								
+							}catch( Throwable e ){
+							}
+							
+							try{
+								download.remove( true, true );
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					}
+				};
+								
+			t.start();
+		}
 	}
 	
 	public URL
@@ -469,415 +563,969 @@ MagnetPlugin
 	
 	public byte[]
 	download(
-		final MagnetPluginProgressListener		listener,
-		final byte[]							hash,
-		final String							args,
-		final InetSocketAddress[]				sources,
-		final long								timeout )
+		MagnetPluginProgressListener		listener,
+		byte[]								hash,
+		String								args,
+		InetSocketAddress[]					sources,
+		long								timeout,
+		int									flags )
 	
 		throws MagnetURIHandlerException
 	{
-		try{
-			if ( first_download ){
-			
-				listener.reportActivity( getMessageText( "report.waiting_ddb" ));
-				
-				first_download = false;
-			}
-			
-			final DistributedDatabase db = plugin_interface.getDistributedDatabase();
-			
-			final List			potential_contacts 		= new ArrayList();
-			final AESemaphore	potential_contacts_sem 	= new AESemaphore( "MagnetPlugin:liveones" );
-			final AEMonitor		potential_contacts_mon	= new AEMonitor( "MagnetPlugin:liveones" );
-			
-			final int[]			outstanding		= {0};
-			final boolean[]		lookup_complete	= {false};
-			
-			listener.reportActivity(  getMessageText( "report.searching" ));
+		byte[]	torrent_data = downloadSupport( listener, hash, args, sources, timeout, flags );
+		
+		if ( args != null ){
 			
-			DistributedDatabaseListener	ddb_listener = 
-				new DistributedDatabaseListener()
-				{
-					private Set	found_set = new HashSet();
-					
-					public void
-					event(
-						DistributedDatabaseEvent 		event )
-					{
-						int	type = event.getType();
-	
-						if ( type == DistributedDatabaseEvent.ET_OPERATION_STARTS ){
-
-								// give live results a chance before kicking in explicit ones
-							
-							if ( sources.length > 0 ){
-								
-								new DelayedEvent(
-									"MP:sourceAdd",
-									10*1000,
-									new AERunnable()
-									{
-										public void
-										runSupport()
-										{
-											addExplicitSources();
-										}
-									});
-							}
-							
-						}else if ( type == DistributedDatabaseEvent.ET_VALUE_READ ){
-													
-							contactFound( event.getValue().getContact());
+			String[] bits = args.split( "&" );
 			
-						}else if (	type == DistributedDatabaseEvent.ET_OPERATION_COMPLETE ||
-									type == DistributedDatabaseEvent.ET_OPERATION_TIMEOUT ){
-								
-							listener.reportActivity( getMessageText( "report.found", String.valueOf( found_set.size())));
-							
-								// now inject any explicit sources
-
-							addExplicitSources();
-							
-							try{
-								potential_contacts_mon.enter();													
+			List<String>	new_web_seeds 	= new ArrayList<String>();
+			List<String>	new_trackers 	= new ArrayList<String>();
 
-								lookup_complete[0] = true;
-								
-							}finally{
-								
-								potential_contacts_mon.exit();
-							}
-							
-							potential_contacts_sem.release();
-						}
-					}
+			for ( String bit: bits ){
+				
+				String[] x = bit.split( "=" );
+				
+				if ( x.length == 2 ){
 					
-					protected void
-					addExplicitSources()
-					{	
-						for (int i=0;i<sources.length;i++){
-							
-							try{
-								contactFound( db.importContact(sources[i]));
-								
-							}catch( Throwable e ){
-								
-								Debug.printStackTrace(e);
-							}
-						}
-					}
+					String	lhs = x[0].toLowerCase();
 					
-					public void
-					contactFound(
-						final DistributedDatabaseContact	contact )
-					{
-						String	key = contact.getAddress().toString();
+					if ( lhs.equals( "ws" )){
 						
-						synchronized( found_set ){
-							
-							if ( found_set.contains( key )){
-								
-								return;
-							}
+						try{
+							new_web_seeds.add( new URL( UrlUtils.decode( x[1] )).toExternalForm());
 							
-							found_set.add( key );
-						}
-						
-						if ( listener.verbose()){
-						
-							listener.reportActivity( getMessageText( "report.found", contact.getName()));
+						}catch( Throwable e ){							
 						}
+					}else if ( lhs.equals( "tr" )){
 						
 						try{
-							potential_contacts_mon.enter();													
-
-							outstanding[0]++;
+							new_trackers.add( new URL( UrlUtils.decode( x[1] )).toExternalForm());
 							
-						}finally{
-							
-							potential_contacts_mon.exit();
+						}catch( Throwable e ){							
 						}
-						
-						contact.isAlive(
-							20*1000,
-							new DistributedDatabaseListener()
-							{
-								public void 
-								event(
-									DistributedDatabaseEvent event) 
-								{
-									try{
-										boolean	alive = event.getType() == DistributedDatabaseEvent.ET_OPERATION_COMPLETE;
-											
-										if ( listener.verbose()){
-										
-											listener.reportActivity( 
-												getMessageText( alive?"report.alive":"report.dead",	contact.getName()));
-										}
-										
-										try{
-											potential_contacts_mon.enter();
-											
-											Object[]	entry = new Object[]{ new Boolean( alive ), contact};
-											
-											boolean	added = false;
-											
-											if ( alive ){
-												
-													// try and place before first dead entry 
-										
-												for (int i=0;i<potential_contacts.size();i++){
-													
-													if (!((Boolean)((Object[])potential_contacts.get(i))[0]).booleanValue()){
-														
-														potential_contacts.add(i, entry );
-														
-														added = true;
-														
-														break;
-													}
-												}
-											}
-											
-											if ( !added ){
-												
-												potential_contacts.add( entry );	// dead at end
-											}
-												
-										}finally{
-												
-											potential_contacts_mon.exit();
-										}
-									}finally{
-										
-										try{
-											potential_contacts_mon.enter();													
-
-											outstanding[0]--;
-											
-										}finally{
-											
-											potential_contacts_mon.exit();
-										}
-										
-										potential_contacts_sem.release();
-									}
-								}
-							});
-					}
-				};
-				
-			db.read(
-				ddb_listener,
-				db.createKey( hash, "Torrent download lookup for '" + ByteFormatter.encodeString( hash ) + "'" ),
-				timeout,
-				DistributedDatabase.OP_EXHAUSTIVE_READ | DistributedDatabase.OP_PRIORITY_HIGH );
-			
-			long	remaining	= timeout;
-			
-			long 	overall_start 			= SystemTime.getMonotonousTime();
-			boolean	sl_enabled				= secondary_lookup.getValue() && FeatureAvailability.isMagnetSLEnabled();
-
-			long	secondary_lookup_time 	= -1;
-			
-			long last_found = -1;
-			
-			final Object[] secondary_result = { null };
-			
-			while( remaining > 0 ){
-					
-				try{
-					potential_contacts_mon.enter();
-
-					if ( 	lookup_complete[0] && 
-							potential_contacts.size() == 0 &&
-							outstanding[0] == 0 ){
-						
-						break;
 					}
-				}finally{
-					
-					potential_contacts_mon.exit();
 				}
-								
-				
-				while( remaining > 0 ){
-				
-					long wait_start = SystemTime.getMonotonousTime();
-
-					boolean got_sem = potential_contacts_sem.reserve( 1000 );
-		
-					long now = SystemTime.getMonotonousTime();
-					
-					remaining -= ( now - wait_start );
+			}
+			
+			if ( new_web_seeds.size() > 0 || new_trackers.size() > 0 ){
 				
-					if ( got_sem ){
+				try{
+					TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray( torrent_data );
+	
+					boolean	update_torrent = false;
 					
-						last_found = now;
+					if ( new_web_seeds.size() > 0 ){
 						
-						break;
+						Object obj = torrent.getAdditionalProperty( "url-list" );
 						
-					}else{
+						List<String> existing = new ArrayList<String>();
 						
-						if ( sl_enabled ){
+						if ( obj instanceof byte[] ){
+			                
+							try{
+								new_web_seeds.remove( new URL( new String((byte[])obj, "UTF-8" )).toExternalForm());
+								
+							}catch( Throwable e ){							
+							}
+						}else if ( obj instanceof List ){
 							
-							if ( secondary_lookup_time == -1 ){
+							List<byte[]> l = (List<byte[]>)obj;
 							
-								long	base_time;
+							for ( byte[] b: l ){
 								
-								if ( last_found == -1 || now - overall_start > 60*1000 ){
-									
-									base_time = overall_start;
-									
-								}else{
+								try{
+									existing.add( new URL( new String((byte[])b, "UTF-8" )).toExternalForm());
 									
-									base_time = last_found;
+								}catch( Throwable e ){							
 								}
+							}
+						}
+						
+						boolean update_ws = false;
+						
+						for ( String e: new_web_seeds ){
+							
+							if ( !existing.contains( e )){
 								
-								long	time_so_far = now - base_time;
-								
-								if ( time_so_far > SECONDARY_LOOKUP_DELAY ){
-									
-									secondary_lookup_time = SystemTime.getMonotonousTime();
-									
-									doSecondaryLookup( listener, secondary_result, hash, args );
-								}
-							}else{
+								existing.add( e );
 								
-								try{
-									byte[] torrent = getSecondaryLookupResult( secondary_result );
-									
-									if ( torrent != null ){
-										
-										return( torrent );
-									}
-								}catch( ResourceDownloaderException e ){
-									
-									// ignore, we just continue processing
-								}
+								update_ws = true;
 							}
 						}
-
-						continue;
-					}
-				}
-				
-				DistributedDatabaseContact	contact;
-				boolean						live_contact;
-				
-				try{
-					potential_contacts_mon.enter();
-					
-					// System.out.println( "rem=" + remaining + ",pot=" + potential_contacts.size() + ",out=" + outstanding[0] );
-					
-					if ( potential_contacts.size() == 0 ){
 						
-						if ( outstanding[0] == 0 ){
+						if ( update_ws ){
 						
-							break;
+							List<byte[]>	l = new ArrayList<byte[]>();
+							
+							for ( String s: existing ){
+								
+								l.add( s.getBytes( "UTF-8" ));
+							}
 							
-						}else{
+							torrent.setAdditionalProperty( "url-list", l );
 							
-							continue;
+							update_torrent = true;
 						}
-					}else{
-					
-						Object[]	entry = (Object[])potential_contacts.remove(0);
-						
-						live_contact 	= ((Boolean)entry[0]).booleanValue(); 
-						contact 		= (DistributedDatabaseContact)entry[1];
 					}
 					
-				}finally{
-					
-					potential_contacts_mon.exit();
-				}
-					
-				// System.out.println( "magnetDownload: " + contact.getName() + ", live = " + live_contact );
-				
-				if ( !live_contact ){
-					
-					listener.reportActivity( getMessageText( "report.tunnel", contact.getName()));
-
-					contact.openTunnel();
-				}
-				
-				try{
-					listener.reportActivity( getMessageText( "report.downloading", contact.getName()));
-					
-					DistributedDatabaseValue	value = 
-						contact.read( 
-								new DistributedDatabaseProgressListener()
-								{
-									public void
-									reportSize(
-										long	size )
-									{
-										listener.reportSize( size );
-									}
-									public void
-									reportActivity(
-										String	str )
-									{
-										listener.reportActivity( str );
-									}
-									
-									public void
-									reportCompleteness(
-										int		percent )
-									{
-										listener.reportCompleteness( percent );
-									}
-								},
-								db.getStandardTransferType( DistributedDatabaseTransferType.ST_TORRENT ),
-								db.createKey ( hash , "Torrent download content for '" + ByteFormatter.encodeString( hash ) + "'"),
-								timeout );
-										
-					if ( value != null ){
+					if ( new_trackers.size() > 0 ){
+												
+						URL announce_url = torrent.getAnnounceURL();
+													
+						new_trackers.remove( announce_url.toExternalForm());
 						
-							// let's verify the torrent
+						TOTorrentAnnounceURLGroup group = torrent.getAnnounceURLGroup();
 						
-						byte[]	data = (byte[])value.getValue(byte[].class);
-
-						try{
-							TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray( data );
+						TOTorrentAnnounceURLSet[] sets = group.getAnnounceURLSets();
+						
+						for ( TOTorrentAnnounceURLSet set: sets ){
 							
-							if ( Arrays.equals( hash, torrent.getHash())){
+							URL[] set_urls = set.getAnnounceURLs();
 							
-								listener.reportContributor( contact.getAddress());
+							for( URL set_url: set_urls ){
+																																		
+								new_trackers.remove( set_url.toExternalForm());
+							}
+						}
 						
-								return( data );
+						if ( new_trackers.size() > 0 ){
+							
+							TOTorrentAnnounceURLSet[]	new_sets = new TOTorrentAnnounceURLSet[ sets.length + new_trackers.size()];
+							
+							for ( int i=0;i<sets.length;i++){
 								
-							}else{
+								new_sets[i] = sets[i];
+							}
+							
+							for ( int i=0;i<new_trackers.size();i++){
 								
-								listener.reportActivity( getMessageText( "report.error", "torrent invalid (hash mismatch)" ));
+								TOTorrentAnnounceURLSet new_set = group.createAnnounceURLSet( new URL[]{ new URL( new_trackers.get(i))});
+								
+								new_sets[i+sets.length] = new_set;
 							}
-						}catch( Throwable e ){
 							
-							listener.reportActivity( getMessageText( "report.error", "torrent invalid (decode failed)" ));
+							group.setAnnounceURLSets( new_sets );
+							
+							update_torrent = true;
 						}
 					}
-				}catch( Throwable e ){
-					
-					listener.reportActivity( getMessageText( "report.error", Debug.getNestedExceptionMessage(e)));
 					
-					Debug.printStackTrace(e);
+					if ( update_torrent ){
+						
+						torrent_data = BEncoder.encode( torrent.serialiseToMap());
+					}
+				}catch( Throwable e ){
 				}
 			}
+		}
 		
-			if ( sl_enabled ){
-				
-				if ( secondary_lookup_time == -1 ){
-					
-					secondary_lookup_time = SystemTime.getMonotonousTime();
-					
-					doSecondaryLookup(listener, secondary_result, hash, args );
-				}
-				
-				while( SystemTime.getMonotonousTime() - secondary_lookup_time < SECONDARY_LOOKUP_MAX_TIME ){
-					
-					try{
+		return( torrent_data );
+	}
+	
+	private static ByteArrayHashMap<DownloadActivity>	download_activities = new ByteArrayHashMap<DownloadActivity>();
+	
+	private static class
+	DownloadActivity
+	{
+		private volatile byte[]						result;
+		private volatile MagnetURIHandlerException	error;
+		
+		private AESemaphore		sem = new AESemaphore( "MP:DA" );
+		
+		public void
+		setResult(
+			byte[]	_result )
+		{
+			result	= _result;
+			
+			sem.releaseForever();
+		}
+		
+		public void
+		setResult(
+			Throwable _error  )
+		{
+			if ( _error instanceof MagnetURIHandlerException ){
+				
+				error = (MagnetURIHandlerException)_error;
+				
+			}else{
+				
+				error = new MagnetURIHandlerException( "Download failed", _error );
+			}
+			
+			sem.releaseForever();
+		}
+		
+		public byte[]
+		getResult()
+		
+			throws MagnetURIHandlerException
+		{
+			sem.reserve();
+			
+			if ( error != null ){
+				
+				throw( error );
+			}
+			
+			return( result );
+		}
+	}
+	
+	private byte[]
+ 	downloadSupport(
+ 		MagnetPluginProgressListener	listener,
+ 		byte[]							hash,
+ 		String							args,
+ 		InetSocketAddress[]				sources,
+ 		long							timeout,
+ 		int								flags )
+ 	
+ 		throws MagnetURIHandlerException
+ 	{
+		DownloadActivity	activity;
+		boolean				new_activity = false;
+		
+ 		synchronized( download_activities ){
+ 			
+ 				// single-thread per hash to avoid madness ensuing if we get multiple concurrent hits
+ 			
+ 			activity = download_activities.get( hash );
+ 			
+ 			if ( activity == null ){
+ 				
+ 				activity = new DownloadActivity();
+ 				
+ 				download_activities.put( hash, activity );
+ 				
+ 				new_activity = true;
+ 			}
+ 		}
+ 		 		
+ 		if ( new_activity ){
+ 		
+	 		try{
+	 			
+	 			activity.setResult( _downloadSupport( listener, hash, args, sources, timeout, flags ));
+	 			
+	 		}catch( Throwable e ){
+	 			
+	 			activity.setResult( e );
+	 			
+	 		}finally{
+	 			
+	 			synchronized( download_activities ){
+	 				
+	 				download_activities.remove( hash );
+	 			}
+	 		}
+ 		}
+ 			
+ 		return( activity.getResult());
+
+ 	}
+	
+	private byte[]
+	_downloadSupport(
+		final MagnetPluginProgressListener		listener,
+		final byte[]							hash,
+		final String							args,
+		final InetSocketAddress[]				sources,
+		final long								timeout,
+		int										flags )
+	
+		throws MagnetURIHandlerException
+	{
+		boolean	md_enabled;
+		
+		if ((flags & FL_DISABLE_MD_LOOKUP) != 0 ){
+			
+			md_enabled = false;
+			
+		}else{
+			
+			md_enabled = md_lookup.getValue() && FeatureAvailability.isMagnetMDEnabled();
+		}
+
+		TimerEvent							md_delay_event = null;
+		final byte[][]						md_result = { null };
+		final MagnetPluginMDDownloader[]	md_downloader = { null };
+		
+		final byte[][]						fl_result = { null };
+
+		if ( md_enabled ){
+			
+			int	delay_millis = md_lookup_delay.getValue()*1000;
+			
+			md_delay_event = 
+				SimpleTimer.addEvent(
+					"MagnetPlugin:md_delay",
+					delay_millis<=0?0:(SystemTime.getCurrentTime() + delay_millis ),
+					new TimerEventPerformer()
+					{
+						public void 
+						perform(
+							TimerEvent event ) 
+						{
+							MagnetPluginMDDownloader mdd;
+							
+							synchronized( md_downloader ){
+								
+								if ( event.isCancelled()){
+									
+									return;
+								}
+								
+								md_downloader[0] = mdd = new MagnetPluginMDDownloader( plugin_interface, hash, args );
+							}
+							
+							listener.reportActivity( getMessageText( "report.md.starts" ));
+							
+							mdd.start(
+								new MagnetPluginMDDownloader.DownloadListener()
+								{
+									public void
+									reportProgress(
+										int		downloaded,
+										int		total_size )
+									{
+										listener.reportActivity( getMessageText( "report.md.progress", String.valueOf( downloaded + "/" + total_size ) ));
+										
+										listener.reportCompleteness( 100*downloaded/total_size );
+									}
+									
+									public void
+									complete(
+										TOTorrent	torrent )
+									{
+										listener.reportActivity( getMessageText( "report.md.done" ));
+										
+										synchronized( md_result ){
+										
+											try{
+												md_result[0] = BEncoder.encode( torrent.serialiseToMap());
+												
+											}catch( Throwable e ){
+												
+												Debug.out( e );
+											}
+										}
+									}
+									
+									public void
+									failed(
+										Throwable e )
+									{
+										listener.reportActivity( getMessageText( "report.error", Debug.getNestedExceptionMessage(e)));
+									}
+								});
+						}
+					});
+		}
+		
+		if ( args != null ){
+			
+			String[] bits = args.split( "&" );
+			
+			List<URL>	fl_args 	= new ArrayList<URL>();
+
+			for ( String bit: bits ){
+				
+				String[] x = bit.split( "=" );
+				
+				if ( x.length == 2 ){
+					
+					String	lhs = x[0].toLowerCase();
+					
+					if ( lhs.equals( "fl" )){
+						
+						try{
+							fl_args.add( new URL( UrlUtils.decode( x[1] )));
+							
+						}catch( Throwable e ){							
+						}
+					}
+				}
+			}
+			
+			if ( fl_args.size() > 0 ){
+				
+				for ( int i=0;i<fl_args.size() && i < 3; i++ ){
+					
+					final URL fl_url = fl_args.get( i );
+					
+					new AEThread2( "Magnet:fldl", true )
+					{
+						public void 
+						run() 
+						{
+							try{
+								TOTorrent torrent = TorrentUtils.download( fl_url );
+								
+								if ( torrent != null ){
+									
+									if ( Arrays.equals( torrent.getHash(), hash )){
+										
+										synchronized( fl_result ){
+											
+											fl_result[0] = BEncoder.encode( torrent.serialiseToMap());
+										}
+									}
+								}
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					}.start();
+				}
+			}
+		}
+		
+		try{
+			try{
+				long	remaining	= timeout;
+								
+				boolean	sl_enabled				= secondary_lookup.getValue() && FeatureAvailability.isMagnetSLEnabled();
+	
+				long secondary_lookup_time 	= -1;
+
+				final Object[] secondary_result = { null };
+
+				boolean	is_first_download = first_download;
+				
+				if ( is_first_download ){
+				
+					listener.reportActivity( getMessageText( "report.waiting_ddb" ));
+					
+					first_download = false;
+				}
+				
+				final DistributedDatabase db = plugin_interface.getDistributedDatabase();
+				
+				if ( db.isAvailable()){
+					
+					final List			potential_contacts 		= new ArrayList();
+					final AESemaphore	potential_contacts_sem 	= new AESemaphore( "MagnetPlugin:liveones" );
+					final AEMonitor		potential_contacts_mon	= new AEMonitor( "MagnetPlugin:liveones" );
+					
+					final int[]			outstanding		= {0};
+					final boolean[]		lookup_complete	= {false};
+					
+					listener.reportActivity(  getMessageText( "report.searching" ));
+					
+					DistributedDatabaseListener	ddb_listener = 
+						new DistributedDatabaseListener()
+						{
+							private Set	found_set = new HashSet();
+							
+							public void
+							event(
+								DistributedDatabaseEvent 		event )
+							{
+								int	type = event.getType();
+			
+								if ( type == DistributedDatabaseEvent.ET_OPERATION_STARTS ){
+		
+										// give live results a chance before kicking in explicit ones
+									
+									if ( sources.length > 0 ){
+										
+										new DelayedEvent(
+											"MP:sourceAdd",
+											10*1000,
+											new AERunnable()
+											{
+												public void
+												runSupport()
+												{
+													addExplicitSources();
+												}
+											});
+									}
+									
+								}else if ( type == DistributedDatabaseEvent.ET_VALUE_READ ){
+															
+									contactFound( event.getValue().getContact());
+					
+								}else if (	type == DistributedDatabaseEvent.ET_OPERATION_COMPLETE ||
+											type == DistributedDatabaseEvent.ET_OPERATION_TIMEOUT ){
+										
+									listener.reportActivity( getMessageText( "report.found", String.valueOf( found_set.size())));
+									
+										// now inject any explicit sources
+		
+									addExplicitSources();
+									
+									try{
+										potential_contacts_mon.enter();													
+		
+										lookup_complete[0] = true;
+										
+									}finally{
+										
+										potential_contacts_mon.exit();
+									}
+									
+									potential_contacts_sem.release();
+								}
+							}
+							
+							protected void
+							addExplicitSources()
+							{	
+								for (int i=0;i<sources.length;i++){
+									
+									try{
+										contactFound( db.importContact(sources[i]));
+										
+									}catch( Throwable e ){
+										
+										Debug.printStackTrace(e);
+									}
+								}
+							}
+							
+							public void
+							contactFound(
+								final DistributedDatabaseContact	contact )
+							{
+								String	key = contact.getAddress().toString();
+								
+								synchronized( found_set ){
+									
+									if ( found_set.contains( key )){
+										
+										return;
+									}
+									
+									found_set.add( key );
+								}
+								
+								if ( listener.verbose()){
+								
+									listener.reportActivity( getMessageText( "report.found", contact.getName()));
+								}
+								
+								try{
+									potential_contacts_mon.enter();													
+		
+									outstanding[0]++;
+									
+								}finally{
+									
+									potential_contacts_mon.exit();
+								}
+								
+								contact.isAlive(
+									20*1000,
+									new DistributedDatabaseListener()
+									{
+										public void 
+										event(
+											DistributedDatabaseEvent event) 
+										{
+											try{
+												boolean	alive = event.getType() == DistributedDatabaseEvent.ET_OPERATION_COMPLETE;
+													
+												if ( listener.verbose()){
+												
+													listener.reportActivity( 
+														getMessageText( alive?"report.alive":"report.dead",	contact.getName()));
+												}
+												
+												try{
+													potential_contacts_mon.enter();
+													
+													Object[]	entry = new Object[]{ new Boolean( alive ), contact};
+													
+													boolean	added = false;
+													
+													if ( alive ){
+														
+															// try and place before first dead entry 
+												
+														for (int i=0;i<potential_contacts.size();i++){
+															
+															if (!((Boolean)((Object[])potential_contacts.get(i))[0]).booleanValue()){
+																
+																potential_contacts.add(i, entry );
+																
+																added = true;
+																
+																break;
+															}
+														}
+													}
+													
+													if ( !added ){
+														
+														potential_contacts.add( entry );	// dead at end
+													}
+														
+												}finally{
+														
+													potential_contacts_mon.exit();
+												}
+											}finally{
+												
+												try{
+													potential_contacts_mon.enter();													
+		
+													outstanding[0]--;
+													
+												}finally{
+													
+													potential_contacts_mon.exit();
+												}
+												
+												potential_contacts_sem.release();
+											}
+										}
+									});
+							}
+						};
+						
+					db.read(
+						ddb_listener,
+						db.createKey( hash, "Torrent download lookup for '" + ByteFormatter.encodeString( hash ) + "'" ),
+						timeout,
+						DistributedDatabase.OP_EXHAUSTIVE_READ | DistributedDatabase.OP_PRIORITY_HIGH );
+										
+					long 	overall_start 			= SystemTime.getMonotonousTime();					
+					long 	last_found 				= -1;
+										
+					AsyncDispatcher	dispatcher = new AsyncDispatcher();
+					
+					while( remaining > 0 ){
+						
+						try{
+							potential_contacts_mon.enter();
+		
+							if ( 	lookup_complete[0] && 
+									potential_contacts.size() == 0 &&
+									outstanding[0] == 0 ){
+								
+								break;
+							}
+						}finally{
+							
+							potential_contacts_mon.exit();
+						}
+										
+						
+						while( remaining > 0 ){
+						
+							if ( listener.cancelled()){
+								
+								return( null );
+							}
+							
+							synchronized( md_result ){
+								
+								if ( md_result[0] != null ){
+									
+									return( md_result[0] );
+								}
+							}
+											
+							synchronized( fl_result ){
+								
+								if ( fl_result[0] != null ){
+									
+									return( fl_result[0] );
+								}
+							}
+							
+							long wait_start = SystemTime.getMonotonousTime();
+		
+							boolean got_sem = potential_contacts_sem.reserve( 1000 );
+				
+							long now = SystemTime.getMonotonousTime();
+							
+							remaining -= ( now - wait_start );
+						
+							if ( got_sem ){
+							
+								last_found = now;
+								
+								break;
+								
+							}else{
+								
+								if ( sl_enabled ){
+									
+									if ( secondary_lookup_time == -1 ){
+									
+										long	base_time;
+										
+										if ( last_found == -1 || now - overall_start > 60*1000 ){
+											
+											base_time = overall_start;
+											
+										}else{
+											
+											base_time = last_found;
+										}
+										
+										long	time_so_far = now - base_time;
+										
+										if ( time_so_far > SECONDARY_LOOKUP_DELAY ){
+											
+											secondary_lookup_time = SystemTime.getMonotonousTime();
+											
+											doSecondaryLookup( listener, secondary_result, hash, args );
+										}
+									}else{
+										
+										try{
+											byte[] torrent = getSecondaryLookupResult( secondary_result );
+											
+											if ( torrent != null ){
+												
+												return( torrent );
+											}
+										}catch( ResourceDownloaderException e ){
+											
+											// ignore, we just continue processing
+										}
+									}
+								}
+		
+								continue;
+							}
+						}
+						
+						final DistributedDatabaseContact	contact;
+						final boolean						live_contact;
+						
+						try{
+							potential_contacts_mon.enter();
+							
+							// System.out.println( "rem=" + remaining + ",pot=" + potential_contacts.size() + ",out=" + outstanding[0] );
+							
+							if ( potential_contacts.size() == 0 ){
+								
+								if ( outstanding[0] == 0 ){
+								
+									break;
+									
+								}else{
+									
+									continue;
+								}
+							}else{
+							
+								Object[]	entry = (Object[])potential_contacts.remove(0);
+								
+								live_contact 	= ((Boolean)entry[0]).booleanValue(); 
+								contact 		= (DistributedDatabaseContact)entry[1];
+							}
+							
+						}finally{
+							
+							potential_contacts_mon.exit();
+						}
+							
+						// System.out.println( "magnetDownload: " + contact.getName() + ", live = " + live_contact );
+						
+						final AESemaphore	contact_sem 	= new AESemaphore( "MD:contact" );
+						final byte[][]		contact_data	= { null };
+						
+						dispatcher.dispatch(
+							new AERunnable()
+							{
+								public void
+								runSupport()
+								{
+									try{
+										if ( !live_contact ){
+											
+											listener.reportActivity( getMessageText( "report.tunnel", contact.getName()));
+						
+											contact.openTunnel();
+										}
+										
+										try{
+											listener.reportActivity( getMessageText( "report.downloading", contact.getName()));
+											
+											DistributedDatabaseValue	value = 
+												contact.read( 
+														new DistributedDatabaseProgressListener()
+														{
+															public void
+															reportSize(
+																long	size )
+															{
+																listener.reportSize( size );
+															}
+															public void
+															reportActivity(
+																String	str )
+															{
+																listener.reportActivity( str );
+															}
+															
+															public void
+															reportCompleteness(
+																int		percent )
+															{
+																listener.reportCompleteness( percent );
+															}
+														},
+														db.getStandardTransferType( DistributedDatabaseTransferType.ST_TORRENT ),
+														db.createKey ( hash , "Torrent download content for '" + ByteFormatter.encodeString( hash ) + "'"),
+														timeout );
+																
+											if ( value != null ){
+												
+													// let's verify the torrent
+												
+												byte[]	data = (byte[])value.getValue(byte[].class);
+						
+												try{
+													TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedByteArray( data );
+													
+													if ( Arrays.equals( hash, torrent.getHash())){
+													
+														listener.reportContributor( contact.getAddress());
+												
+														synchronized( contact_data ){
+															
+															contact_data[0] = data;
+														}												
+													}else{
+														
+														listener.reportActivity( getMessageText( "report.error", "torrent invalid (hash mismatch)" ));
+													}
+												}catch( Throwable e ){
+													
+													listener.reportActivity( getMessageText( "report.error", "torrent invalid (decode failed)" ));
+												}
+											}
+										}catch( Throwable e ){
+											
+											listener.reportActivity( getMessageText( "report.error", Debug.getNestedExceptionMessage(e)));
+											
+											Debug.printStackTrace(e);
+										}
+									}finally{
+										
+										contact_sem.release();
+									}
+								}
+							});
+						
+						while( true ){
+							
+							if ( listener.cancelled()){
+								
+								return( null );
+							}
+							
+							boolean got_sem = contact_sem.reserve( 500 );
+														
+							synchronized( contact_data ){
+									
+								if ( contact_data[0] != null ){
+										
+									return( contact_data[0] );
+								}
+							}
+							
+							synchronized( md_result ){
+								
+								if ( md_result[0] != null ){
+									
+									return( md_result[0] );
+								}
+							}
+							
+							synchronized( fl_result ){
+								
+								if ( fl_result[0] != null ){
+									
+									return( fl_result[0] );
+								}
+							}
+							
+							if ( got_sem ){
+								
+								break;
+							}
+						}
+					}
+				}else{
+					
+					if ( is_first_download ){
+					
+						listener.reportActivity( getMessageText( "report.ddb_disabled" ));
+					}
+				}
+				
+				if ( sl_enabled ){
+					
+					if ( secondary_lookup_time == -1 ){
+						
+						secondary_lookup_time = SystemTime.getMonotonousTime();
+						
+						doSecondaryLookup(listener, secondary_result, hash, args );
+					}
+					
+					while( SystemTime.getMonotonousTime() - secondary_lookup_time < SECONDARY_LOOKUP_MAX_TIME ){
+						
+						if ( listener.cancelled()){
+							
+							return( null );
+						}
+						
+						try{
+							byte[] torrent = getSecondaryLookupResult( secondary_result );
+							
+							if ( torrent != null ){
+								
+								return( torrent );
+							}
+							
+							synchronized( md_result ){
+								
+								if ( md_result[0] != null ){
+									
+									return( md_result[0] );
+								}
+							}
+							
+							synchronized( fl_result ){
+								
+								if ( fl_result[0] != null ){
+									
+									return( fl_result[0] );
+								}
+							}
+							
+							Thread.sleep( 500 );
+							
+						}catch( ResourceDownloaderException e ){
+							
+							break;
+						}
+					}
+				}
+				
+				if ( md_enabled ){
+				
+					while( remaining > 0 ){
+
+						if ( listener.cancelled()){
+							
+							return( null );
+						}
+						
+						Thread.sleep( 500 );
+						
+						remaining -= 500;
+						
 						byte[] torrent = getSecondaryLookupResult( secondary_result );
 						
 						if ( torrent != null ){
@@ -885,24 +1533,48 @@ MagnetPlugin
 							return( torrent );
 						}
 						
-						Thread.sleep( 500 );
-						
-					}catch( ResourceDownloaderException e ){
+						synchronized( md_result ){
+							
+							if ( md_result[0] != null ){
+								
+								return( md_result[0] );
+							}
+						}
 						
-						break;
+						synchronized( fl_result ){
+							
+							if ( fl_result[0] != null ){
+								
+								return( fl_result[0] );
+							}
+						}
 					}
 				}
+				
+				return( null );		// nothing found
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+				
+				listener.reportActivity( getMessageText( "report.error", Debug.getNestedExceptionMessage(e)));
+	
+				throw( new MagnetURIHandlerException( "MagnetURIHandler failed", e ));
 			}
+		}finally{
 			
-			return( null );		// nothing found
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace(e);
-			
-			listener.reportActivity( getMessageText( "report.error", Debug.getNestedExceptionMessage(e)));
+			synchronized( md_downloader ){
 
-			throw( new MagnetURIHandlerException( "MagnetURIHandler failed", e ));
+				if ( md_delay_event != null ){
+					
+					md_delay_event.cancel();
+					
+					if ( md_downloader[0] != null ){
+						
+						 md_downloader[0].cancel();
+					}
+				}
+			}
 		}
 	}
 	
@@ -968,6 +1640,11 @@ MagnetPlugin
 	
 		throws ResourceDownloaderException
 	{
+		if ( result == null ){
+			
+			return( null );
+		}
+		
 		Object x;
 		
 		synchronized( result ){
diff --git a/com/aelitis/azureus/plugins/magnet/MagnetPluginMDDownloader.java b/com/aelitis/azureus/plugins/magnet/MagnetPluginMDDownloader.java
new file mode 100644
index 0000000..1fa7c7f
--- /dev/null
+++ b/com/aelitis/azureus/plugins/magnet/MagnetPluginMDDownloader.java
@@ -0,0 +1,724 @@
+/*
+ * Created on Mar 9, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.magnet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.*;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLGroup;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
+import org.gudy.azureus2.core3.torrent.TOTorrentCreator;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
+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.BDecoder;
+import org.gudy.azureus2.core3.util.Base32;
+import org.gudy.azureus2.core3.util.ByteFormatter;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.RandomUtils;
+import org.gudy.azureus2.core3.util.TorrentUtils;
+import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
+import org.gudy.azureus2.plugins.disk.DiskManagerEvent;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
+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.download.DownloadPeerListener;
+import org.gudy.azureus2.plugins.peers.Peer;
+import org.gudy.azureus2.plugins.peers.PeerEvent;
+import org.gudy.azureus2.plugins.peers.PeerListener2;
+import org.gudy.azureus2.plugins.peers.PeerManager;
+import org.gudy.azureus2.plugins.peers.PeerManagerEvent;
+import org.gudy.azureus2.plugins.peers.PeerManagerListener2;
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+
+public class 
+MagnetPluginMDDownloader 
+{
+	private static Set<String>	active_set = new HashSet<String>();
+	
+	private PluginInterface		plugin_interface;
+	private byte[]				hash;
+	private String				args;
+	
+	private volatile boolean		started;
+	private volatile boolean		cancelled;
+	private volatile boolean		completed;
+	
+	private List<DiskManagerRequest>	requests = new ArrayList<DiskManagerRequest>();
+	
+	private AESemaphore running_sem 	= new AESemaphore( "MPMDD:run" );
+	private AESemaphore complete_sem 	= new AESemaphore( "MPMDD:comp" );
+
+	protected 
+	MagnetPluginMDDownloader(
+		PluginInterface		_plugin_interface,
+		byte[]				_hash,
+		String				_args )
+	{
+		plugin_interface	= _plugin_interface;
+		hash				= _hash;
+		args				= _args;
+	}
+	
+	protected void
+	start(
+		final DownloadListener		listener )
+	{
+		synchronized( this ){
+			
+			if ( started ){
+	
+				listener.failed( new Exception( "Already started" ));
+				
+				return;
+			}
+			
+			if ( cancelled || completed ){
+
+				listener.failed( new Exception( "Already cancelled/completed" ));
+
+				return;
+			}
+			
+			started = true;
+			
+			new AEThread2( "MagnetPluginMDDownloader" )
+			{
+				public void
+				run()
+				{
+					startSupport( listener );
+				}
+			}.start();
+		}
+	}
+	
+	protected void
+	cancel()
+	{
+		cancelSupport( false );
+	}
+	
+	private void
+	cancelSupport(
+		boolean	internal )
+	{
+		boolean	wait_for_complete 	= !internal;
+
+		try{
+			List<DiskManagerRequest>	to_cancel;
+			
+			synchronized( this ){
+				
+				if ( !started ){
+					
+					Debug.out( "Not started!" );
+					
+					wait_for_complete 	= false;
+				}
+				
+				if ( cancelled || completed ){
+					
+					return;
+				}
+				
+				cancelled	= true;
+				
+				to_cancel = new ArrayList<DiskManagerRequest>( requests );
+				
+				requests.clear();
+			}
+			
+			for ( DiskManagerRequest request: to_cancel ){
+				
+				request.cancel();
+			}
+		}finally{
+					
+			running_sem.releaseForever();
+			
+			if ( wait_for_complete ){
+				
+				complete_sem.reserve();
+			}
+		}
+	}
+	
+	private void
+	startSupport(
+		final DownloadListener		listener )
+	{		
+		String	hash_str = ByteFormatter.encodeString( hash );
+
+		File tmp_dir 		= null;	
+		File data_file 		= null;
+		File torrent_file 	= null;
+
+		DownloadManager download_manager = plugin_interface.getDownloadManager();
+
+		Download download	= null;
+		
+		final Throwable[] error = { null };
+		
+		final ByteArrayOutputStream	result = new ByteArrayOutputStream(32*1024);
+		
+		TOTorrentAnnounceURLSet[]	url_sets = null;
+		
+		try{
+			synchronized( active_set ){
+				
+				if ( active_set.contains( hash_str )){
+					
+					throw( new Exception( "Download already active for hash " + hash_str ));
+				}
+				
+				active_set.add( hash_str );
+			}
+			
+			Download existing_download = download_manager.getDownload( hash );
+			
+			if ( existing_download != null ){
+				
+				throw( new Exception( "download already exists" ));
+			}
+				
+			tmp_dir = AETemporaryFileHandler.createTempDir();
+			
+			int	 rand = RandomUtils.generateRandomIntUpto( 10000 );
+			
+			data_file 		= new File( tmp_dir, hash_str + "_" + rand + ".torrent" );
+			torrent_file 	= new File( tmp_dir, hash_str + "_" + rand + ".metatorrent" );
+
+			RandomAccessFile raf = new RandomAccessFile( data_file, "rw" );
+			
+			byte[] buffer = new byte[256*1024];
+			
+			Arrays.fill( buffer, (byte)0xff );
+			
+			for (long i=0;i<32*1024*1024;i+=buffer.length){
+				
+				raf.write( buffer );
+			}
+			
+			raf.close();
+						
+			URL announce_url = TorrentUtils.getDecentralisedURL( hash );
+			
+			TOTorrentCreator creator = 
+				TOTorrentFactory.createFromFileOrDirWithFixedPieceLength( 
+						data_file, 
+						announce_url,
+						16*1024 );
+	
+			TOTorrent meta_torrent = creator.create();
+			
+			String[] bits = args.split( "&" );
+			
+			List<String>	trackers = new ArrayList<String>();
+
+			String	name = "magnet:" + Base32.encode( hash );
+			
+			for ( String bit: bits ){
+				
+				String[] x = bit.split( "=" );
+				
+				if ( x.length == 2 ){
+					
+					String 	lhs = x[0].toLowerCase();
+					
+					if ( lhs.equals( "tr" )){
+						
+						trackers.add( UrlUtils.decode( x[1] ));
+						
+					}else if ( lhs.equals( "dn" )){
+						
+						name = UrlUtils.decode( x[1] );
+					}
+				}
+			}
+			
+			if ( trackers.size() > 0 ){
+				
+				trackers.add( 0, announce_url.toExternalForm());
+				
+				TOTorrentAnnounceURLGroup ag = meta_torrent.getAnnounceURLGroup();
+				
+				List<TOTorrentAnnounceURLSet> sets = new ArrayList<TOTorrentAnnounceURLSet>();
+				
+				for ( String tracker: trackers ){
+				
+					try{
+						sets.add( ag.createAnnounceURLSet(new URL[]{ new URL( tracker )}));
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+				
+				if ( sets.size() > 0 ){
+					
+					url_sets = sets.toArray( new TOTorrentAnnounceURLSet[ sets.size()]);
+					
+					ag.setAnnounceURLSets( url_sets );
+				}
+			}
+			
+			if ( !data_file.delete()){
+				
+				throw( new Exception( "Failed to delete " + data_file ));
+			}
+			
+			meta_torrent.setHashOverride( hash );
+			
+			TorrentUtils.setFlag( meta_torrent, TorrentUtils.TORRENT_FLAG_METADATA_TORRENT, true );
+			
+			TorrentUtils.setFlag( meta_torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE, true );
+			
+			meta_torrent.serialiseToBEncodedFile( torrent_file );
+						
+			download_manager.clearNonPersistentDownloadState( hash );
+			
+			download = download_manager.addNonPersistentDownloadStopped( PluginCoreUtils.wrap( meta_torrent ), torrent_file, data_file);
+			
+			String	display_name = MessageText.getString( "MagnetPlugin.use.md.download.name", new String[]{ name });
+			
+			PluginCoreUtils.unwrap( download ).getDownloadState().setDisplayName( display_name + ".torrent" );
+			
+			download.addPeerListener(
+				new DownloadPeerListener()
+				{
+					public void
+					peerManagerAdded(
+						final Download			download,
+						final PeerManager		peer_manager )
+					{
+						if ( cancelled || completed ){
+							
+							download.removePeerListener( this );
+							
+							return;
+						}
+						
+						final PEPeerManager pm = PluginCoreUtils.unwrap( peer_manager );
+						
+						peer_manager.addListener(
+							new PeerManagerListener2()
+							{
+								private PeerManagerListener2	pm_listener = this;
+								
+								private int	md_size;
+								
+								public void
+								eventOccurred(
+									PeerManagerEvent	event )
+								{
+									if ( cancelled || completed ){
+										
+										peer_manager.removeListener( this );
+										
+										return;
+									}
+									
+									if ( event.getType() != PeerManagerEvent.ET_PEER_ADDED ){
+										
+										return;
+									}
+									
+									final Peer peer = event.getPeer();
+									
+									peer.addListener(
+										new PeerListener2()
+										{
+											public void
+											eventOccurred(
+												PeerEvent	event )
+											{
+												if ( cancelled || completed || md_size > 0 ){
+													
+													peer.removeListener( this );
+													
+													return;
+												}
+												
+												if ( event.getType() != PeerEvent.ET_STATE_CHANGED ){
+													
+													return;
+												}
+												
+												if ( (Integer)event.getData() != Peer.TRANSFERING ){
+													
+													return;
+												}
+												
+												synchronized( this ){
+													
+													if ( md_size > 0 ){
+														
+														return;
+													}
+												
+													md_size = pm.getTorrentInfoDictSize();
+												
+													if ( md_size > 0 ){
+																								
+														peer_manager.removeListener( pm_listener );
+														
+													}else{
+														
+														return;
+													}
+												}
+										
+												listener.reportProgress( 0, md_size );
+												
+												new AEThread2( "" )
+												{
+													public void
+													run()
+													{
+														DiskManagerChannel channel = null;
+														
+														try{
+															channel = download.getDiskManagerFileInfo()[0].createChannel();
+														
+															final DiskManagerRequest request = channel.createRequest();
+															
+															request.setType( DiskManagerRequest.REQUEST_READ );
+															request.setOffset( 0 );
+															request.setLength( md_size );
+																
+															request.setMaximumReadChunkSize( 16*1024 );
+																				
+															request.addListener(
+																new DiskManagerListener()
+																{
+																	public void
+																	eventOccurred(
+																		DiskManagerEvent	event )
+																	{
+																		int	type = event.getType();
+																		
+																		if ( type == DiskManagerEvent.EVENT_TYPE_FAILED ){
+																			
+																			error[0]	= event.getFailure();
+																			
+																			running_sem.releaseForever();
+																			
+																		}else if ( type == DiskManagerEvent.EVENT_TYPE_SUCCESS ){
+																			
+																			PooledByteBuffer	buffer = null;
+																			
+																			try{
+																				buffer	= event.getBuffer();
+																																									
+																				byte[]	bytes = buffer.toByteArray();
+																					
+																				int	dl_size;
+																				
+																				synchronized( MagnetPluginMDDownloader.this ){
+																					
+																					result.write( bytes );
+																					
+																					dl_size = result.size();
+																					
+																					if ( dl_size == md_size ){
+																						
+																						completed	= true;
+																						
+																						running_sem.releaseForever();
+																					}
+																				}
+																				
+																				if ( !completed ){
+																					
+																					listener.reportProgress( dl_size, md_size );
+																				}
+																				
+																			}catch( Throwable e ){
+																				
+																				error[0] = e;
+										
+																				request.cancel();
+																					
+																				running_sem.releaseForever();
+																				
+																			}finally{
+																				
+																				if ( buffer != null ){
+																					
+																					buffer.returnToPool();
+																				}
+																			}
+																		}else if ( type == DiskManagerEvent.EVENT_TYPE_BLOCKED ){
+																			
+																			//System.out.println( "Waiting..." );
+																		}
+																	}
+																});
+															
+															synchronized( MagnetPluginMDDownloader.this ){
+															
+																if ( cancelled ){
+																	
+																	return;
+																}
+																
+																requests.add( request );
+															}
+															
+															request.run();	
+															
+															synchronized( MagnetPluginMDDownloader.this ){
+																
+																requests.remove( request );
+															}
+														}catch( Throwable e ){
+														
+															error[0] = e;
+															
+															running_sem.releaseForever();
+															
+														}finally{
+															
+															if ( channel != null ){
+																
+																channel.destroy();
+															}
+														}
+													}
+												}.start();
+											}
+										});
+								}
+							});
+					}
+					
+					public void
+					peerManagerRemoved(
+						Download		download,
+						PeerManager		peer_manager )
+					{
+					}
+				});
+		
+			final Download f_download = download;
+			
+			DownloadManagerListener dl_listener = 
+				new DownloadManagerListener()
+				{
+					public void
+					downloadAdded(
+						Download	download )
+					{
+					}
+					
+					public void
+					downloadRemoved(
+						Download	dl )
+					{
+						if ( dl == f_download ){
+							
+							if ( !( cancelled || completed )){
+								
+								error[0] = new Exception( "Download manually removed" );
+								
+								running_sem.releaseForever();
+							}
+						}
+					}
+				};
+				
+			download_manager.addListener( dl_listener, false );
+
+			try{
+			
+				download.moveTo(1);		
+				
+				download.setForceStart( true );
+				
+				download.setFlag( Download.FLAG_DISABLE_AUTO_FILE_MOVE, true );
+	
+				running_sem.reserve();
+				
+			}finally{
+				
+				download_manager.removeListener( dl_listener );
+			}
+				
+			if ( completed ){
+			
+				byte[]	bytes = result.toByteArray();
+				
+				Map	info = BDecoder.decode( bytes );
+				
+				Map	map = new HashMap();
+				
+				map.put( "info", info );
+				
+				TOTorrent torrent = TOTorrentFactory.deserialiseFromMap( map );
+				
+				byte[] final_hash = torrent.getHash();
+				
+				if ( !Arrays.equals( hash, final_hash )){
+					
+					throw( new Exception( "Metadata torrent hash mismatch: expected=" + ByteFormatter.encodeString( hash ) + ", actual=" + ByteFormatter.encodeString( final_hash )));
+				}
+				
+				if ( url_sets != null ){
+					
+					torrent.setAnnounceURL( url_sets[0].getAnnounceURLs()[0] );
+					
+					torrent.getAnnounceURLGroup().setAnnounceURLSets( url_sets );
+					
+				}else{
+					
+					torrent.setAnnounceURL( TorrentUtils.getDecentralisedURL( hash ));
+				}
+				
+				listener.complete( torrent );
+				
+			}else{
+									
+				if ( cancelled ){
+					
+					throw( new Exception( "Download cancelled" ));
+				
+				}else{
+					
+					cancelSupport( true );
+					
+					if ( error[0] != null ){
+						
+						throw( error[0] );
+
+					}else{
+					
+						throw( new Exception( "Download terminated prematurely" ));
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			boolean	was_cancelled = cancelled;
+	
+			cancelSupport( true );
+	
+			if ( !was_cancelled ){
+			
+				listener.failed( e );
+			
+				Debug.out( e );
+			}
+		}finally{
+			
+			try{
+				if ( download != null ){
+					
+					try{
+						download.stop();
+						
+					}catch( Throwable e ){
+					}
+					
+					try{
+						download.remove();
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+				
+				List<DiskManagerRequest>	to_cancel;
+				
+				synchronized( this ){
+										
+					to_cancel = new ArrayList<DiskManagerRequest>( requests );
+					
+					requests.clear();
+				}
+				
+				for ( DiskManagerRequest request: to_cancel ){
+					
+					request.cancel();
+				}
+				
+				if ( torrent_file != null ){
+					
+					torrent_file.delete();
+				}
+				
+				if ( data_file != null ){
+					
+					data_file.delete();
+				}
+				
+				if ( tmp_dir != null ){
+					
+					tmp_dir.delete();
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+				
+			}finally{
+			
+				synchronized( active_set ){
+	
+					active_set.remove( hash_str );
+				}
+				
+				complete_sem.releaseForever();
+			}
+		}
+	}
+	
+	protected interface
+	DownloadListener
+	{
+		public void
+		reportProgress(
+			int		downloaded,
+			int		total_size );
+		
+		public void
+		complete(
+			TOTorrent	torrent );
+		
+		public void
+		failed(
+			Throwable e );
+	}
+}
diff --git a/com/aelitis/azureus/plugins/magnet/MagnetPluginProgressListener.java b/com/aelitis/azureus/plugins/magnet/MagnetPluginProgressListener.java
index 64763b1..9e1ca7e 100644
--- a/com/aelitis/azureus/plugins/magnet/MagnetPluginProgressListener.java
+++ b/com/aelitis/azureus/plugins/magnet/MagnetPluginProgressListener.java
@@ -49,5 +49,8 @@ MagnetPluginProgressListener
 		InetSocketAddress	address );
 	
 	public boolean
+	cancelled();
+	
+	public boolean
 	verbose();
 }
diff --git a/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java b/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
index 34c6f95..e7fded2 100644
--- a/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
+++ b/com/aelitis/azureus/plugins/net/buddy/BuddyPlugin.java
@@ -45,6 +45,7 @@ import org.gudy.azureus2.plugins.messaging.MessageManager;
 import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnection;
 import org.gudy.azureus2.plugins.messaging.generic.GenericMessageHandler;
 import org.gudy.azureus2.plugins.messaging.generic.GenericMessageRegistration;
+import org.gudy.azureus2.plugins.network.ConnectionManager;
 import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
@@ -201,42 +202,11 @@ BuddyPlugin
 	private SESecurityManager	sec_man;
 
 	private GenericMessageRegistration	msg_registration;
+			
+	private RateLimiter	inbound_limiter; 
 		
-	private int	inbound_limit;
-	private int	outbound_limit;
+	private RateLimiter	outbound_limiter; 
 	
-	private RateLimiter	inbound_limiter = 
-		new RateLimiter()
-	{
-		public String 
-		getName() 
-		{
-			return( "buddy_up" );
-		}
-
-		public int 
-		getRateLimitBytesPerSecond() 
-		{
-			return( inbound_limit );
-		}
-	};
-		
-	private RateLimiter	outbound_limiter = 
-		new RateLimiter()
-	{
-		public String 
-		getName() 
-		{
-			return( "buddy_down" );
-		}
-
-		public int 
-		getRateLimitBytesPerSecond() 
-		{
-			return( outbound_limit );
-		}
-	};
-			
 	private boolean		config_dirty;
 	
 	private Random	random = RandomUtils.SECURE_RANDOM;
@@ -285,6 +255,7 @@ BuddyPlugin
 	{		
 		plugin_interface	= _plugin_interface;
 		
+			
 		ta_category		= plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_CATEGORY );
 
 		az2_handler = new BuddyPluginAZ2( this );
@@ -365,8 +336,13 @@ BuddyPlugin
 		
 		protocol_speed.setMinimumRequiredUserMode( Parameter.MODE_ADVANCED );
 		
-		inbound_limit = protocol_speed.getValue()*1024;
+		ConnectionManager cman = plugin_interface.getConnectionManager();
 		
+		int inbound_limit = protocol_speed.getValue()*1024;
+
+		inbound_limiter 	= cman.createRateLimiter( "buddy_up", inbound_limit );	
+		outbound_limiter 	= cman.createRateLimiter( "buddy_down", 0 );
+
 		protocol_speed.addListener(
 				new ParameterListener()
 				{
@@ -374,7 +350,7 @@ BuddyPlugin
 					parameterChanged(
 						Parameter	param )
 					{
-						inbound_limit = protocol_speed.getValue()*1024;
+						inbound_limiter.setRateLimitBytesPerSecond( protocol_speed.getValue()*1024 );
 					}
 				});
 		
@@ -402,7 +378,7 @@ BuddyPlugin
 			});
 		
 			// config end
-		
+				
 		
 		final TableContextMenuItem menu_item_itorrents = 
 			plugin_interface.getUIManager().getTableManager().addContextMenuItem(TableManager.TABLE_MYTORRENTS_INCOMPLETE, "azbuddy.contextmenu");
@@ -2558,8 +2534,11 @@ BuddyPlugin
 							}else{
 								
 								try{
-									int	tcp_port = ((Long)status.get( "t" )).intValue();
-									int udp_port = ((Long)status.get( "u" )).intValue();
+									Long	l_tcp_port = (Long)status.get( "t" );
+									Long	l_udp_port = (Long)status.get( "u" );
+									
+									int	tcp_port = l_tcp_port==null?0:l_tcp_port.intValue();
+									int udp_port = l_udp_port==null?0:l_udp_port.intValue();
 									
 									InetAddress ip = InetAddress.getByAddress((byte[])status.get("i"));
 									
@@ -3729,11 +3708,18 @@ BuddyPlugin
 								{
 									return( false );
 								}
+								
+								public boolean 
+								cancelled() 
+								{
+									return( false );
+								}
 							},
 							hash,
 							"",
 							new InetSocketAddress[0],
-							timeout );
+							timeout,
+							MagnetPlugin.FL_NONE );
 						
 						if ( torrent_data == null ){
 							
@@ -3929,8 +3915,6 @@ BuddyPlugin
 				
 		ByteArrayOutputStream	os = new ByteArrayOutputStream();
 			
-		AZ3Functions.provider az3 = AZ3Functions.getProvider();
-		
 		try{
 			PrintWriter pw = new PrintWriter(new OutputStreamWriter( os, "UTF-8" ));
 			
@@ -3977,16 +3961,6 @@ BuddyPlugin
 				
 				pw.println( "<guid>" + hash_str + "</guid>" );
 				
-				if ( az3 != null ){
-					
-					String cdp = az3.getCDPURL( core_download );
-					
-					if ( cdp != null ){
-						
-						pw.println( "<link>" + escape(cdp) + "</link>" );
-					}
-				}
-				
 				long added = core_download.getDownloadState().getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME);
 				
 				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( added ) + "</pubDate>" );
diff --git a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
index a97d5ca..add9857 100644
--- a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
+++ b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginView.java
@@ -236,7 +236,7 @@ BuddyPluginView
 					{
 						try{
 							plugin.getPluginInterface().getUIManager().openURL(
-									new URL( "http://faq.vuze.com/?View=entry&EntryID=239" ));
+									new URL( "http://wiki.vuze.com" ));
 							
 						}catch( Throwable e ){
 							
diff --git a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
index 9b08c8e..9f37b01 100644
--- a/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
+++ b/com/aelitis/azureus/plugins/net/buddy/swt/BuddyPluginViewInstance.java
@@ -47,7 +47,6 @@ import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.utils.LocaleUtilities;
 import org.gudy.azureus2.ui.swt.Messages;
 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.*;
@@ -203,7 +202,7 @@ BuddyPluginViewInstance
 		
 	    Messages.setLanguageText(control_val_pk, "ConfigView.copy.to.clipboard.tooltip", true);
 
-	    control_val_pk.setCursor(Cursors.handCursor);
+	    control_val_pk.setCursor(main.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 	    control_val_pk.setForeground(Colors.blue);
 	    control_val_pk.addMouseListener(new MouseAdapter() {
 	    	public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTester.java b/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTester.java
index 144b6ed..bdd3ea8 100644
--- a/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTester.java
+++ b/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTester.java
@@ -117,10 +117,16 @@ NetStatusProtocolTester
 
 			ddb = plugin_interface.getDistributedDatabase();
 			
-			ddb.addTransferHandler( transfer_type, this );
+			if ( ddb.isAvailable()){
 			
-			log( "DDB transfer type registered" );
+				ddb.addTransferHandler( transfer_type, this );
 			
+				log( "DDB transfer type registered" );
+				
+			}else{
+				
+				log( "DDB transfer type not registered, DDB unavailable" );
+			}			
 		}catch( Throwable e ){
 			
 			log( "DDB transfer type registration failed", e );
diff --git a/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTesterBT.java b/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTesterBT.java
index 5097866..7cbec42 100644
--- a/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTesterBT.java
+++ b/com/aelitis/azureus/plugins/net/netstatus/NetStatusProtocolTesterBT.java
@@ -41,6 +41,7 @@ import com.aelitis.azureus.core.networkmanager.NetworkConnection;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.networkmanager.OutgoingMessageQueue;
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.ProtocolEndpointTCP;
 import com.aelitis.azureus.core.peermanager.PeerManager;
 import com.aelitis.azureus.core.peermanager.PeerManagerRegistration;
@@ -199,7 +200,7 @@ NetStatusProtocolTesterBT
 				
 		boolean	allow_fallback	= false;
 		
-		ProtocolEndpoint	pe = new ProtocolEndpointTCP( address );
+		ProtocolEndpoint	pe = ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, address );
 		
 		ConnectionEndpoint connection_endpoint	= new ConnectionEndpoint( address );
 
@@ -517,12 +518,15 @@ NetStatusProtocolTesterBT
 					{
 						final String	type = initiator?"Outbound":"Inbound";
 						
-						public final void 
-						connectStarted() 
-						{
+						public int 
+						connectStarted(
+							int default_connect_timeout )
+						{	
 							log( type + " connect start" );
-						}
 
+							return( default_connect_timeout );
+						}
+						
 						public final void 
 						connectSuccess( 
 							ByteBuffer remaining_initial_data ) 
@@ -700,6 +704,12 @@ NetStatusProtocolTesterBT
 						int byte_count ) 
 					{
 					}
+					
+					public boolean 
+					isPriority() 
+					{
+						return true;
+					}
 				});
 
 			connection.getOutgoingMessageQueue().registerQueueListener( 
@@ -856,7 +866,7 @@ NetStatusProtocolTesterBT
 				
 				log( "Closing connection" );
 				
-				connection.close();
+				connection.close( null );
 				
 			}else{
 				
diff --git a/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java b/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
index 1a3422d..a172340 100644
--- a/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
+++ b/com/aelitis/azureus/plugins/removerules/DownloadRemoveRulesPlugin.java
@@ -31,6 +31,7 @@ import java.net.InetAddress;
 import java.util.*;
 
 import org.gudy.azureus2.plugins.torrent.*;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.*;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
 import org.gudy.azureus2.plugins.ui.config.*;
@@ -127,6 +128,28 @@ DownloadRemoveRulesPlugin
 			return;
 		}
 		
+			// auto remove low noise torrents if their data is missing
+		
+		if ( download.getFlag( Download.FLAG_LOW_NOISE )){
+			
+			DiskManagerFileInfo[] files = download.getDiskManagerFileInfo();
+			
+			if ( files.length == 1 ){
+				
+				DiskManagerFileInfo file = files[0];
+				
+					// completed only
+				
+				if ( 	file.getDownloaded() == file.getLength() &&
+						!file.getFile().exists()){
+				
+					log.log( "Removing low-noise download '" + download.getName() + " as data missing" );
+				
+					removeDownload( download, false );
+				}
+			}
+		}
+		
 		DownloadTrackerListener	listener = 
 			new DownloadTrackerListener()
 			{
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/DefaultRankCalculator.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/DefaultRankCalculator.java
index 642f6c2..26e880e 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/DefaultRankCalculator.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/DefaultRankCalculator.java
@@ -299,7 +299,6 @@ public class DefaultRankCalculator implements Comparable {
 
 		DefaultRankCalculator dlData = (DefaultRankCalculator) obj;
 
-		
 		// Test FP.  FP goes to top
 		if (dlData.bIsFirstPriority && !bIsFirstPriority)
 			return 1;
@@ -491,6 +490,9 @@ public class DefaultRankCalculator implements Comparable {
 			if (!dl.isComplete()) {
 				newSR = SR_COMPLETE_STARTS_AT + (10000 - dl.getPosition());
 				dl.setSeedingRank(newSR);
+				// make sure we capture FP being turned off when torrent does from
+				// complete to incomplete
+				isFirstPriority();
 				if ( rules.bDebugLog ){
 					sExplainSR += "  not complete. SetSR " + newSR + "\n";
 				}
@@ -747,8 +749,8 @@ public class DefaultRankCalculator implements Comparable {
 			return false;
 		}
 
-		if (dl.getState() == Download.ST_ERROR
-				|| dl.getState() == Download.ST_STOPPED) {
+		int state = dl.getState();
+		if (state == Download.ST_ERROR || state == Download.ST_STOPPED) {
 			if (rules.bDebugLog)
 				sExplainFP += "Not FP: Download is ERROR or STOPPED\n";
 			return false;
diff --git a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
index 60a176a..fc0b606 100644
--- a/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
+++ b/com/aelitis/azureus/plugins/startstoprules/defaultplugin/StartStopRulesDefaultPlugin.java
@@ -126,7 +126,8 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 	private RecalcSeedingRanksTask recalcSeedingRanksTask;
 
 	/** Map to relate downloadData to a Download */
-	private static Map downloadDataMap = Collections.synchronizedMap(new HashMap());
+	private static Map<Download, DefaultRankCalculator> downloadDataMap = Collections.synchronizedMap(new HashMap<Download, DefaultRankCalculator>());
+
 	/**
 	 * this is used to reduce the number of comperator invocations
 	 * by keeping a mostly sorted copy around, must be nulled whenever the map is changed
@@ -412,7 +413,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 	}
 
 	public static DefaultRankCalculator getRankCalculator(Download dl) {
-		return (DefaultRankCalculator) downloadDataMap.get(dl);
+		return downloadDataMap.get(dl);
 	}
 
 	private void recalcAllSeedingRanks(boolean force) {
@@ -423,8 +424,11 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 		try {
 			this_mon.enter();
 
-			DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) downloadDataMap.values().toArray(
-					new DefaultRankCalculator[0]);
+			DefaultRankCalculator[] dlDataArray;
+			synchronized (downloadDataMap) {
+				dlDataArray = downloadDataMap.values().toArray(
+						new DefaultRankCalculator[0]);
+			}
 
 			// Check Group #1: Ones that always should run since they set things
 			for (int i = 0; i < dlDataArray.length; i++) {
@@ -502,7 +506,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 	private class StartStopDownloadListener implements DownloadListener
 	{
 		public void stateChanged(Download download, int old_state, int new_state) {
-			DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
+			DefaultRankCalculator dlData = downloadDataMap.get(download);
 
 			if (dlData != null) {
 				// force a SR recalc, so that it gets position properly next process()
@@ -530,7 +534,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 		public void positionChanged(Download download, int oldPosition,
 				int newPosition) {
-			DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
+			DefaultRankCalculator dlData = downloadDataMap.get(download);
 			if (dlData != null) {
 				requestProcessCycle(dlData);
 				if (bDebugLog)
@@ -547,7 +551,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 	{
 		public void scrapeResult(DownloadScrapeResult result) {
 			Download dl = result.getDownload();
-			DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(dl);
+			DefaultRankCalculator dlData = downloadDataMap.get(dl);
 
 			// Skip if error (which happens when listener is first added and the
 			// torrent isn't scraped yet)
@@ -585,7 +589,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 			//System.out.println("StartStop: activation request: count = "
 			//		+ event.getActivationCount());
 			Download download = event.getDownload();
-			DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(download);
+			DefaultRankCalculator dlData = downloadDataMap.get(download);
 
 			if (bDebugLog) {
 				log.log(download, LoggerChannel.LT_INFORMATION, ">> somethingChanged: ActivationRequest");
@@ -628,7 +632,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 		public void downloadAdded(Download download) {
 			DefaultRankCalculator dlData = null;
 			if (downloadDataMap.containsKey(download)) {
-				dlData = (DefaultRankCalculator) downloadDataMap.get(download);
+				dlData = downloadDataMap.get(download);
 			} else {
 				dlData = new DefaultRankCalculator(StartStopRulesDefaultPlugin.this,
 						download);
@@ -692,8 +696,11 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 				lLastRunTime = now;
 
-				DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) downloadDataMap.values().toArray(
-						new DefaultRankCalculator[0]);
+				DefaultRankCalculator[] dlDataArray;
+				synchronized (downloadDataMap) {
+					dlDataArray = downloadDataMap.values().toArray(
+							new DefaultRankCalculator[0]);
+				}
 
 				int iNumDLing = 0;
 				int iNumCDing = 0;
@@ -739,7 +746,12 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 	// ConfigurationListener
 	public void configurationSaved() {
-		reloadConfigParams();
+		new AEThread2("reloadConfigParams", true) {
+			// @see org.gudy.azureus2.core3.util.AEThread2#run()
+			public void run() {
+				reloadConfigParams();
+			}
+		}.start();
 	}
 
 	private void reloadConfigParams() {
@@ -822,15 +834,17 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 			// force a recalc on all downloads by setting SR to 0, scheduling
 			// a recalc on next process, and requsting a process cycle
-			Collection allDownloads = downloadDataMap.values();
-			DefaultRankCalculator[] dlDataArray = (DefaultRankCalculator[]) allDownloads.toArray(new DefaultRankCalculator[0]);
+			Collection<DefaultRankCalculator> allDownloads = downloadDataMap.values();
+			DefaultRankCalculator[] dlDataArray = allDownloads.toArray(new DefaultRankCalculator[0]);
 			for (int i = 0; i < dlDataArray.length; i++) {
 				dlDataArray[i].getDownloadObject().setSeedingRank(0);
 			}
 			try {
 				ranksToRecalc_mon.enter();
 
-				ranksToRecalc.addAll(allDownloads);
+				synchronized (downloadDataMap) {
+					ranksToRecalc.addAll(allDownloads);
+				}
 				
 			} finally {
 				ranksToRecalc_mon.exit();
@@ -853,7 +867,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 								if (!(ds instanceof Download))
 									return;
 
-								DefaultRankCalculator dlData = (DefaultRankCalculator) downloadDataMap.get(ds);
+								DefaultRankCalculator dlData = downloadDataMap.get(ds);
 
 								if (dlData != null) {
 									if (bSWTUI)
@@ -1232,11 +1246,14 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 			// pull the data into a local array, so we don't have to lock/synchronize
 			DefaultRankCalculator[] dlDataArray;			
-			if(sortedArrayCache != null && sortedArrayCache.length == downloadDataMap.size())
+			if(sortedArrayCache != null && sortedArrayCache.length == downloadDataMap.size()) {
 				dlDataArray = sortedArrayCache;
-			else
-				dlDataArray = sortedArrayCache = (DefaultRankCalculator[]) downloadDataMap.values().toArray(
-					new DefaultRankCalculator[downloadDataMap.size()]);
+			} else {
+				synchronized (downloadDataMap) {
+					dlDataArray = sortedArrayCache = downloadDataMap.values().toArray(
+							new DefaultRankCalculator[downloadDataMap.size()]);
+				}
+			}
 
 			TotalsStats totals = new TotalsStats(dlDataArray);
 
@@ -1476,8 +1493,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 			vars.numWaitingOrDLing++;
 		}
 
-		if (state == Download.ST_READY || state == Download.ST_DOWNLOADING
-				|| state == Download.ST_WAITING) {
+		if ( state == Download.ST_READY || state == Download.ST_DOWNLOADING	|| state == Download.ST_WAITING ){
 
 			// Stop torrent if over limit
 			boolean bOverLimit = vars.numWaitingOrDLing > maxDLs
@@ -1485,12 +1501,12 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 			boolean bDownloading = state == Download.ST_DOWNLOADING;
 
-			if ((maxDownloads != 0) && bOverLimit &&
-					(globalRateAdjustedActivelyDownloading || !bDownloading ||
-						(bDownloading && totals.maxActive != 0 && !globalRateAdjustedActivelyDownloading &&	totals.activelyCDing + totals.activelyDLing >= totals.maxActive)
-					)
-				)
-			{
+			if (	maxDownloads != 0 && 
+					bOverLimit &&
+					!( download.isChecking() || download.isMoving()) &&
+					(	globalRateAdjustedActivelyDownloading || 
+						!bDownloading ||
+						(bDownloading && totals.maxActive != 0 && !globalRateAdjustedActivelyDownloading &&	totals.activelyCDing + totals.activelyDLing >= totals.maxActive))){
 				try
 				{
 					if (bDebugLog)
@@ -1930,9 +1946,10 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 
 					// not checking AND (at limit of seeders OR rank is set to ignore) AND
 					// (Actively Seeding OR StartingUp OR Seeding a non-active download) 
-					okToStop = !download.isChecking()
-							&& (bOverLimit || rank < DefaultRankCalculator.SR_IGNORED_LESS_THAN)
-							&& (globalRateAdjustedActivelySeeding || !bSeeding || (!globalRateAdjustedActivelySeeding && bSeeding));
+					okToStop = 	!download.isChecking() && 
+								!download.isMoving() &&
+								(bOverLimit || rank < DefaultRankCalculator.SR_IGNORED_LESS_THAN) &&
+								(globalRateAdjustedActivelySeeding || !bSeeding || (!globalRateAdjustedActivelySeeding && bSeeding));
 
 					if (bDebugLog) {
 						if (okToStop) {
@@ -1958,15 +1975,18 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 						}
 					} else {
 						sDebugLine += "\n  NOT queuing: ";
-						if (download.isChecking())
+						if (download.isChecking()){
 							sDebugLine += "can't auto-queue a checking torrent";
-						else if (!bOverLimit)
+						}else if (download.isMoving()){
+							sDebugLine += "can't auto-queue a moving torrent";
+						}else if (!bOverLimit){
 							sDebugLine += "not over limit.  numWaitingOrSeeding("
 									+ vars.numWaitingOrSeeding + ") <= maxSeeders("
 									+ totals.maxSeeders + ")";
-						else
+						}else{
 							sDebugLine += "bActivelySeeding=" + bActivelySeeding
 									+ ";bSeeding" + bSeeding;
+						}
 					}
 				} else {
 					if (bDebugLog)
@@ -1977,7 +1997,7 @@ public class StartStopRulesDefaultPlugin implements Plugin,
 					try {
 						if (state == Download.ST_READY)
 							totals.waitingToSeed--;
-
+						
 						download.stopAndQueue();
 						vars.bStopAndQueued = true;
 						// okToQueue only allows READY and SEEDING state.. and in both cases
diff --git a/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java b/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
index ff2e418..9b86d03 100644
--- a/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
+++ b/com/aelitis/azureus/plugins/tracker/dht/DHTTrackerPlugin.java
@@ -28,6 +28,7 @@ import java.net.UnknownHostException;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPeerSource;
 import org.gudy.azureus2.core3.tracker.protocol.PRHelpers;
@@ -36,8 +37,10 @@ import org.gudy.azureus2.core3.util.AENetworkClassifier;
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
 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.SystemTime;
+import org.gudy.azureus2.core3.util.TimeFormatter;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.Plugin;
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -73,6 +76,8 @@ import com.aelitis.azureus.core.dht.netcoords.DHTNetworkPositionManager;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminASN;
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 import com.aelitis.azureus.plugins.dht.*;
 
 /**
@@ -119,6 +124,8 @@ DHTTrackerPlugin
 	private static final boolean	TRACK_NORMAL_DEFAULT	= true;
 	private static final boolean	TRACK_LIMITED_DEFAULT	= true;
 	
+	private static final boolean	TEST_ALWAYS_TRACK		= false;
+	
 	public static final int	NUM_WANT			= 30;	// Limit to ensure replies fit in 1 packet
 
 	private static final long	start_time = SystemTime.getCurrentTime();
@@ -143,9 +150,9 @@ DHTTrackerPlugin
 		}
 	}
 	
-	private PluginInterface		plugin_interface;
-	
-	private DHTPlugin			dht;
+	private PluginInterface			plugin_interface;
+	private BasicPluginViewModel 	model;
+	private DHTPlugin				dht;
 	
 	private TorrentAttribute 	ta_networks;
 	private TorrentAttribute 	ta_peer_sources;
@@ -153,7 +160,8 @@ DHTTrackerPlugin
 	private Map<Download,Long>		interesting_downloads 	= new HashMap<Download,Long>();
 	private int						interesting_published	= 0;
 	private int						interesting_pub_max		= INTERESTING_PUB_MAX_DEFAULT;
-	private Map<Download,Integer>	running_downloads 		= new HashMap<Download,Integer>();
+	private Map<Download,int[]>		running_downloads 		= new HashMap<Download,int[]>();
+	private Map<Download,int[]>		run_data_cache	 		= new HashMap<Download,int[]>();
 	private Map<Download,RegistrationDetails>	registered_downloads 	= new HashMap<Download,RegistrationDetails>();
 	
 	private Map<Download,Boolean>	limited_online_tracking	= new HashMap<Download,Boolean>();
@@ -168,6 +176,8 @@ DHTTrackerPlugin
 	private BooleanParameter	track_normal_when_offline;
 	private BooleanParameter	track_limited_when_online;
 	
+	private long				current_announce_interval = ANNOUNCE_MIN_DEFAULT;
+	
 	private LoggerChannel		log;
 	
 	private Map<Download,int[]>					scrape_injection_map = new WeakHashMap<Download,int[]>();
@@ -182,6 +192,28 @@ DHTTrackerPlugin
 	
 	private AESemaphore			initialised_sem = new AESemaphore( "DHTTrackerPlugin:init" );
 	
+	private boolean				disable_put;
+	
+	{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"Enable.Proxy", 	
+				"Enable.SOCKS",					
+			}, 
+			new org.gudy.azureus2.core3.config.ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameter_name ) 
+				{
+					boolean	enable_proxy 	= COConfigurationManager.getBooleanParameter("Enable.Proxy");
+				    boolean enable_socks	= COConfigurationManager.getBooleanParameter("Enable.SOCKS");
+				    
+				    disable_put = enable_proxy && enable_socks;
+				}
+			});
+	}
+	
 	public static void
 	load(
 		PluginInterface		plugin_interface )
@@ -203,7 +235,7 @@ DHTTrackerPlugin
 
 		UIManager	ui_manager = plugin_interface.getUIManager();
 
-		final BasicPluginViewModel model = 
+		model = 
 			ui_manager.createBasicPluginViewModel( PLUGIN_RESOURCE_ID );
 		
 		model.setConfigSectionID(PLUGIN_CONFIGSECTION_ID);
@@ -279,7 +311,7 @@ DHTTrackerPlugin
 					}
 				});
 
-		model.getStatus().setText( "Initialising" );
+		model.getStatus().setText( MessageText.getString( "ManagerItem.initializing" ));
 		
 		log.log( "Waiting for Distributed Database initialisation" );
 		
@@ -320,7 +352,7 @@ DHTTrackerPlugin
 															
 																log.log( "DDB Available" );
 																	
-																model.getStatus().setText( "Running" );
+																model.getStatus().setText( MessageText.getString( "DHTView.activity.status.false" ));
 																
 																initialise();
 																	
@@ -328,7 +360,7 @@ DHTTrackerPlugin
 																
 																log.log( "DDB Disabled" );
 																
-																model.getStatus().setText( "Disabled, Distributed database not available" );
+																model.getStatus().setText( MessageText.getString( "dht.status.disabled" ));
 																	
 																notRunning();
 															}
@@ -336,7 +368,7 @@ DHTTrackerPlugin
 																
 															log.log( "DDB Failed", e );
 																
-															model.getStatus().setText( "Failed" );
+															model.getStatus().setText( MessageText.getString( "DHTView.operations.failed" ));
 																
 															notRunning();
 															
@@ -359,7 +391,7 @@ DHTTrackerPlugin
 							
 							log.log( "DDB Plugin missing" );
 							
-							model.getStatus().setText( "Failed" );
+							model.getStatus().setText( MessageText.getString( "DHTView.operations.failed" ) );
 							
 							notRunning();
 						}
@@ -469,21 +501,27 @@ DHTTrackerPlugin
 	addDownload(
 		final Download	download )
 	{
+		Torrent	torrent = download.getTorrent();
+
+		boolean	is_decentralised = false;
+		
+		if ( torrent != null ){
+			
+			is_decentralised = TorrentUtils.isDecentralised( torrent.getAnnounceURL());
+		}
 		
-		// bail on our low noise ones, these don't require decentralised tracking
+			// bail on our low noise ones, these don't require decentralised tracking unless that's what they are
 	
-		if ( download.getFlag( Download.FLAG_LOW_NOISE )){
+		if ( download.getFlag( Download.FLAG_LOW_NOISE ) && !is_decentralised ){
 		
 			return;
 		}
 		
 		if ( track_only_decentralsed ){
 		
-			Torrent	torrent = download.getTorrent();
-
 			if ( torrent != null ){
 				
-				if ( !TorrentUtils.isDecentralised( torrent.getAnnounceURL())){
+				if ( !is_decentralised ){
 					
 					return;
 				}
@@ -493,9 +531,7 @@ DHTTrackerPlugin
 		if ( is_running ){
 			
 			String[]	networks = download.getListAttribute( ta_networks );
-			
-			Torrent	torrent = download.getTorrent();
-			
+						
 			if ( torrent != null && networks != null ){
 				
 				boolean	public_net = false;
@@ -571,9 +607,7 @@ DHTTrackerPlugin
 			checkDownloadForRegistration( download, true );
 			
 		}else{
-			
-			Torrent	torrent = download.getTorrent();
-			
+						
 			if ( torrent != null && torrent.isDecentralised()){
 				
 				download.addListener(
@@ -745,6 +779,8 @@ DHTTrackerPlugin
 				
 				running_downloads.remove( download );
 				
+				run_data_cache.remove( download );
+				
 				limited_online_tracking.remove( download );
 				
 			}finally{
@@ -780,6 +816,8 @@ DHTTrackerPlugin
 		Download		download,
 		boolean			first_time )
 	{
+		boolean	skip_log = false;
+		
 		int	state = download.getState();
 			
 		int	register_type	= REG_TYPE_NONE;
@@ -829,7 +867,7 @@ DHTTrackerPlugin
 							
 					}else{
 						
-						if ( torrent.isDecentralisedBackupEnabled()){
+						if ( torrent.isDecentralisedBackupEnabled() || TEST_ALWAYS_TRACK ){
 								
 							String[]	sources = download.getListAttribute( ta_peer_sources );
 	
@@ -845,7 +883,7 @@ DHTTrackerPlugin
 								}
 							}
 	
-							if ( !ok ){
+							if ( !( ok || TEST_ALWAYS_TRACK )){
 											
 								register_reason = "decentralised peer source disabled";
 								
@@ -862,11 +900,11 @@ DHTTrackerPlugin
 									register_type = REG_TYPE_DERIVED;
 								}
 								
-								if( torrent.isDecentralisedBackupRequested()){
+								if( torrent.isDecentralisedBackupRequested() || TEST_ALWAYS_TRACK ){
 									
 									register_type	= REG_TYPE_FULL;
 									
-									register_reason = "torrent requests decentralised tracking";
+									register_reason = TEST_ALWAYS_TRACK?"testing always track":"torrent requests decentralised tracking";
 									
 								}else if ( track_normal_when_offline.getValue()){
 									
@@ -987,6 +1025,8 @@ DHTTrackerPlugin
 			
 			register_reason	= "not running";
 			
+			skip_log	= true;
+			
 		}else if ( 	state == Download.ST_QUEUED ){
 
 				// leave in whatever state it current is (reg or not reg) to avoid thrashing
@@ -1004,34 +1044,54 @@ DHTTrackerPlugin
 			try{
 				this_mon.enter();
 	
-				Integer	existing_type = (Integer)running_downloads.get( download );
+				int[] run_data = running_downloads.get( download );
 			
 				if ( register_type != REG_TYPE_NONE ){
 				
-					if ( existing_type == null ){
+					if ( run_data == null ){
 						
-						log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-								"Monitoring '" + download.getName() + "': " + register_reason);
+						log( download,	"Monitoring '" + download.getName() + "': " + register_reason);
 						
-						running_downloads.put( download, new Integer( register_type ));
+						int[] cache = run_data_cache.remove( download );
 						
-					}else if ( 	existing_type.intValue() == REG_TYPE_DERIVED &&
-								register_type == REG_TYPE_FULL ){
+						if ( cache == null ){
+						
+							running_downloads.put( download, new int[]{ register_type, 0, 0, 0 });
+							
+						}else{
+							
+							cache[0] = register_type;
+							
+							running_downloads.put( download, cache );
+						}
 						
-							// upgrade
+						query_map.put( download, new Long( SystemTime.getCurrentTime()));
+						
+					}else{
 						
-						running_downloads.put( download, new Integer( register_type ));
+						Integer	existing_type = run_data[0];
 
+						if ( 	existing_type.intValue() == REG_TYPE_DERIVED &&
+								register_type == REG_TYPE_FULL ){
+						
+								// upgrade
+						
+							run_data[0] = register_type;
+						}
 					}
 				}else{
 					
-					if ( existing_type  != null ){
+					if ( run_data  != null ){
 						
-						log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-								"Not monitoring '" + download.getName() + "': "	+ register_reason);
+						if ( !skip_log ){
+							
+							log( download, "Not monitoring: "	+ register_reason);
+						}
 	
 						running_downloads.remove( download );
 						
+						run_data_cache.put( download, run_data );
+						
 							// add back to interesting downloads for monitoring
 						
 						interesting_downloads.put( 
@@ -1041,10 +1101,9 @@ DHTTrackerPlugin
 
 					}else{
 						
-						if ( first_time ){
+						if ( first_time && !skip_log ){
 							
-							log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-									"Not monitoring '" + download.getName() + "': "	+ register_reason);
+							log( download, "Not monitoring: "	+ register_reason);
 						}
 					}
 				}
@@ -1172,11 +1231,11 @@ DHTTrackerPlugin
 				try{ 
 					this_mon.enter();
 				
-					Integer x = (Integer)running_downloads.get( dl );
+					int[] run_data = running_downloads.get( dl );
 					
-					if ( x != null ){
+					if ( run_data != null ){
 						
-						reg_type = x.intValue();
+						reg_type = run_data[0];
 					}
 				}finally{
 					
@@ -1274,11 +1333,11 @@ DHTTrackerPlugin
 			try{ 
 				this_mon.enter();
 			
-				Integer x = (Integer)running_downloads.get( dl );
+				int[] run_data = running_downloads.get( dl );
 				
-				if ( x != null ){
+				if ( run_data != null ){
 					
-					reg_type = x.intValue();
+					reg_type = run_data[0];
 				}
 			}finally{
 				
@@ -1298,7 +1357,7 @@ DHTTrackerPlugin
 			
 			if ( registration == null ){
 				
-				log.log( "Registering download '" + dl.getName() + "' as " + (flags == DHTPlugin.FLAG_SEEDING?"Seeding":"Downloading"));
+				log( dl, "Registering download as " + (flags == DHTPlugin.FLAG_SEEDING?"Seeding":"Downloading"));
 
 				registration = new RegistrationDetails( dl, reg_type, put_details, flags );
 				
@@ -1319,7 +1378,7 @@ DHTTrackerPlugin
 						registration.getFlags() != flags ||
 						!registration.getPutDetails().sameAs( put_details )){
 				
-					log.log((registration==null?"Registering":"Re-registering") + " download '" + dl.getName() + "' as " + (flags == DHTPlugin.FLAG_SEEDING?"Seeding":"Downloading"));
+					log( dl,(registration==null?"Registering":"Re-registering") + " download as " + (flags == DHTPlugin.FLAG_SEEDING?"Seeding":"Downloading"));
 					
 					registration.update( put_details, flags );
 					
@@ -1367,8 +1426,7 @@ DHTTrackerPlugin
 			
 			if ( unregister ){
 				
-				log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
-						"Unregistering download '" + dl.getName() + "'");
+				log( dl, "Unregistering download" );
 								
 				rd_it.remove();
 				
@@ -1415,11 +1473,11 @@ DHTTrackerPlugin
 		
 					query_map.remove( dl );
 					
-					Integer x = (Integer)running_downloads.get( dl );
+					int[] run_data = running_downloads.get( dl );
 					
-					if ( x != null ){
+					if ( run_data != null ){
 						
-						reg_type = x.intValue();
+						reg_type = run_data[0];
 					}
 				}finally{
 					
@@ -1438,9 +1496,7 @@ DHTTrackerPlugin
 				
 				if ( skip ){
 					
-					log.log(dl.getTorrent(), LoggerChannel.LT_INFORMATION,
-							"Deferring announce for '" + dl.getName()
-									+ "' as activity outstanding");
+					log( dl, "Deferring announce as activity outstanding" );
 				}
 				
 				RegistrationDetails	registration = (RegistrationDetails)registered_downloads.get( dl );
@@ -1560,6 +1616,8 @@ DHTTrackerPlugin
 			
 			final trackerTarget target = targets[i];
 
+			int	target_type = target.getType();
+			
 		 	    // don't let a put block an announce as we don't want to be waiting for 
 		  	    // this at start of day to get a torrent running
 		  	    
@@ -1580,17 +1638,34 @@ DHTTrackerPlugin
 				continue;
 			}
 			
-			dht.put( 
+			if ( disable_put ){
+				
+				if ( target_type == REG_TYPE_FULL ){
+					
+					log( download, "Registration of '" + target.getDesc() + "' skipped as disabled due to use of SOCKS proxy");
+				}
+			}else if ( download.getFlag( Download.FLAG_METADATA_DOWNLOAD )){
+				
+				log( download, "Registration of '" + target.getDesc() + "' skipped as metadata download");
+				
+			}else if ( target_type == REG_TYPE_DERIVED && dht.isSleeping()){
+				
+				log( download, "Registration of '" + target.getDesc() + "' skipped as sleeping");
+
+			}else{
+				
+				dht.put( 
 					target.getHash(),
-					"Tracker registration of '" + download.getName() + "'" + target.getDesc() + " -> " + encoded,
+					"Tracker registration of '" + download.getName() + "' " + target.getDesc() + " -> " + encoded,
 					encoded_bytes,
 					flags,
 					false,
 					new DHTPluginOperationListener()
 					{
-						public void
+						public boolean
 						diversified()
 						{
+							return( true );
 						}
 						
 						public void 
@@ -1620,15 +1695,14 @@ DHTTrackerPlugin
 						{
 							if ( target.getType() == REG_TYPE_FULL ){
 								
-								log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-										"Registration of '" + download.getName()
-												+ "'" + target.getDesc() + " completed (elapsed="
-												+ (SystemTime.getCurrentTime() - start) + ")");
+								log( 	download,
+										"Registration of '" + target.getDesc() + "' completed (elapsed="	+ TimeFormatter.formatColonMillis((SystemTime.getCurrentTime() - start)) + ")");
 							}
 							
 								// decreaseActive( dl );
 						}
 					});
+			}
 		}
 	}
 	
@@ -1654,7 +1728,13 @@ DHTTrackerPlugin
 			
 			final trackerTarget target = targets[i];
 	
-			if ( target.getType() == REG_TYPE_FULL && derived_only ){
+			int	target_type = target.getType();
+			
+			if ( target_type == REG_TYPE_FULL && derived_only ){
+				
+				continue;
+				
+			}else if ( target_type == REG_TYPE_DERIVED && dht.isSleeping()){
 				
 				continue;
 			}
@@ -1664,10 +1744,10 @@ DHTTrackerPlugin
 			num_done++;
 			
 			dht.get(target.getHash(), 
-					"Tracker announce for '" + download.getName() + "'" + target.getDesc(),
+					"Tracker announce for '" + download.getName() + "' " + target.getDesc(),
 					isComplete( download )?DHTPlugin.FLAG_SEEDING:DHTPlugin.FLAG_DOWNLOADING,
 					NUM_WANT, 
-					target.getType()==REG_TYPE_FULL?ANNOUNCE_TIMEOUT:ANNOUNCE_DERIVED_TIMEOUT,
+					target_type==REG_TYPE_FULL?ANNOUNCE_TIMEOUT:ANNOUNCE_DERIVED_TIMEOUT,
 					false, false,
 					new DHTPluginOperationListener()
 					{
@@ -1682,9 +1762,10 @@ DHTTrackerPlugin
 						
 						boolean	complete;
 						
-						public void
+						public boolean
 						diversified()
 						{
+							return( true );
 						}
 						
 						public void 
@@ -1813,9 +1894,8 @@ DHTTrackerPlugin
 									(	target.getType() == REG_TYPE_DERIVED && 
 										seed_count + leecher_count > 1 )){
 								
-								log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-										"Get of '" + download.getName() + "'" + target.getDesc() + " completed (elapsed="
-												+ (SystemTime.getCurrentTime() - start)
+								log( 	download,
+										"Get of '" + target.getDesc() + "' completed (elapsed=" + TimeFormatter.formatColonMillis(SystemTime.getCurrentTime() - start)
 												+ "), addresses=" + addresses.size() + ", seeds="
 												+ seed_count + ", leechers=" + leecher_count);
 							}
@@ -1838,14 +1918,30 @@ DHTTrackerPlugin
 							int	announce_max = derived_only?ANNOUNCE_MAX_DERIVED_ONLY:ANNOUNCE_MAX;
 							
 							announce_min = Math.min( announce_min, announce_max );
-							
+								
+							current_announce_interval = announce_min;
+
 							final long	retry = announce_min + peers_found*(announce_max-announce_min)/NUM_WANT;
-																
+							
+							int download_state = download.getState();
+							
+							boolean	we_are_seeding = download_state == Download.ST_SEEDING;
+
 							try{
 								this_mon.enter();
 							
-								if ( running_downloads.containsKey( download )){
+								int[] run_data = running_downloads.get( download );
+								
+								if ( run_data != null ){
 
+									boolean full = target.getType() == REG_TYPE_FULL;
+									
+									int peer_count = we_are_seeding?leecher_count:(seed_count+leecher_count);
+									
+									run_data[1] = full?seed_count:Math.max( run_data[1], seed_count);
+									run_data[2]	= full?leecher_count:Math.max( run_data[2], leecher_count);
+									run_data[3] = full?peer_count:Math.max( run_data[3], peer_count);
+										
 									long	absolute_retry = SystemTime.getCurrentTime() + retry;
 								
 									if ( absolute_retry > max_retry[0] ){
@@ -1870,11 +1966,7 @@ DHTTrackerPlugin
 								
 								this_mon.exit();
 							}
-							
-							int download_state = download.getState();
-							
-							boolean	we_are_seeding = download_state == Download.ST_SEEDING;
-							
+														
 							putDetails put_details = details.getPutDetails();
 							
 							String	ext_address = put_details.getIPOverride();
@@ -1979,7 +2071,7 @@ DHTTrackerPlugin
 										
 										DownloadAnnounceResultPeer peer = temp.remove( rand.nextInt( temp.size()));
 										
-										log.log( "    Injecting derived peer " + peer.getAddress() + " into " + download.getName());
+										log( download, "Injecting derived peer " + peer.getAddress() + " into " + download.getName());
 										
 										Map<Object,Object>	user_data = new HashMap<Object,Object>();
 																				
@@ -2134,6 +2226,26 @@ DHTTrackerPlugin
 								
 								scrape_injection_map.put( download, new int[]{ f_adj_seeds, f_adj_leechers });
 	
+								try{
+									this_mon.enter();
+								
+									int[] run_data = running_downloads.get( download );
+									
+									if ( run_data == null ){
+										
+										run_data = run_data_cache.get( download );
+									}
+									
+									if ( run_data != null ){
+
+										run_data[1] = f_adj_seeds;
+										run_data[2]	= f_adj_leechers;
+									}
+								}finally{
+									
+									this_mon.exit();
+								}
+								
 								download.setScrapeResult(
 									new DownloadScrapeResult()
 									{
@@ -2203,6 +2315,11 @@ DHTTrackerPlugin
 	isComplete(
 		Download	download )
 	{
+		if ( Constants.DOWNLOAD_SOURCES_PRETEND_COMPLETE ){
+			
+			return( true );
+		}
+		
 		boolean	is_complete = download.isComplete();
 		
 		if ( is_complete ){
@@ -2228,6 +2345,16 @@ DHTTrackerPlugin
 		final Download			download,
 		RegistrationDetails		details )
 	{
+		if ( disable_put ){
+			
+			return;
+		}
+		
+		if ( download.getFlag( Download.FLAG_METADATA_DOWNLOAD )){
+			
+			return;
+		}
+		
 		final 	long	start = SystemTime.getCurrentTime();
 		
 		trackerTarget[] targets = details.getTargets( true );
@@ -2245,9 +2372,10 @@ DHTTrackerPlugin
 						"Tracker deregistration of '" + download.getName() + "' " + target.getDesc(),
 						new DHTPluginOperationListener()
 						{
-							public void
+							public boolean
 							diversified()
 							{
+								return( true );
 							}
 							
 							public void 
@@ -2277,9 +2405,9 @@ DHTTrackerPlugin
 							{
 								if ( target.getType() == REG_TYPE_FULL ){
 	
-									log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-									"Unregistration of '" + download.getName() + "' " + target.getDesc() + " completed (elapsed="
-											+ (SystemTime.getCurrentTime() - start) + ")");
+									log( 	download,
+											"Unregistration of '" + target.getDesc() + "' completed (elapsed="
+												+ TimeFormatter.formatColonMillis(SystemTime.getCurrentTime() - start) + ")");
 								}
 								
 								decreaseActive( download );
@@ -2294,6 +2422,16 @@ DHTTrackerPlugin
 		final Download			download,
 		final trackerTarget 	target )
 	{
+		if ( disable_put ){
+			
+			return;
+		}
+		
+		if ( download.getFlag( Download.FLAG_METADATA_DOWNLOAD )){
+			
+			return;
+		}
+		
 		final 	long	start = SystemTime.getCurrentTime();
 		
 		if ( dht.hasLocalKey( target.getHash())){
@@ -2305,9 +2443,10 @@ DHTTrackerPlugin
 					"Tracker deregistration of '" + download.getName() + "' " + target.getDesc(),
 					new DHTPluginOperationListener()
 					{
-						public void
+						public boolean
 						diversified()
 						{
+							return( true );
 						}
 						
 						public void 
@@ -2337,9 +2476,9 @@ DHTTrackerPlugin
 						{
 							if ( target.getType() == REG_TYPE_FULL ){
 
-								log.log(download.getTorrent(), LoggerChannel.LT_INFORMATION,
-								"Unregistration of '" + download.getName() + "' " + target.getDesc() + " completed (elapsed="
-										+ (SystemTime.getCurrentTime() - start) + ")");
+								log( 	download,
+										"Unregistration of '" + target.getDesc() + "' completed (elapsed="
+										+ TimeFormatter.formatColonMillis(SystemTime.getCurrentTime() - start) + ")");
 							}
 							
 							decreaseActive( download );
@@ -2377,9 +2516,9 @@ DHTTrackerPlugin
 					continue;
 				}
 				
-				Integer state = running_downloads.get( download );
+				int[] run_data = running_downloads.get( download );
 
-				if ( state == null || state.intValue() == REG_TYPE_DERIVED ){
+				if ( run_data == null || run_data[0] == REG_TYPE_DERIVED ){
 					
 						// looks like we'll need the scrape below
 					
@@ -2416,9 +2555,9 @@ DHTTrackerPlugin
 					continue;
 				}
 				
-				Integer state = running_downloads.get( download );
+				int[] run_data = running_downloads.get( download );
 				
-				if ( state == null || state.intValue() == REG_TYPE_DERIVED ){
+				if ( run_data == null || run_data[0] == REG_TYPE_DERIVED ){
 					
 					boolean	force =  torrent.wasCreatedByUs();
 					
@@ -2476,7 +2615,21 @@ DHTTrackerPlugin
 			
 			final Download	f_ready_download = ready_download;
 			
-			if ( dht.isDiversified( ready_download.getTorrent().getHash())){
+			final Torrent torrent = ready_download.getTorrent();
+			
+			if ( ready_download.getFlag( Download.FLAG_METADATA_DOWNLOAD )){
+
+				try{
+					this_mon.enter();
+
+					interesting_downloads.remove( f_ready_download );
+					
+				}finally{
+					
+					this_mon.exit();
+				}
+				
+			}else if ( dht.isDiversified( torrent.getHash())){
 				
 				// System.out.println( "presence query for " + f_ready_download.getName() + "-> diversified pre start" );
 
@@ -2496,7 +2649,7 @@ DHTTrackerPlugin
 				final long start 		= now;
 				final long f_next_check = ready_download_next_check;
 				
-				dht.get(	ready_download.getTorrent().getHash(), 
+				dht.get(	torrent.getHash(), 
 							"Presence query for '" + ready_download.getName() + "'",
 							(byte)0,
 							INTERESTING_AVAIL_MAX, 
@@ -2508,10 +2661,12 @@ DHTTrackerPlugin
 								private int 	leechers = 0;
 								private int 	seeds	 = 0;
 								
-								public void
+								public boolean
 								diversified()
 								{
 									diversified	= true;
+									
+									return( false );
 								}
 								
 								public void 
@@ -2551,10 +2706,10 @@ DHTTrackerPlugin
 	
 									int	total = leechers + seeds;
 									
-									log.log( f_ready_download.getTorrent(), LoggerChannel.LT_INFORMATION,
-											"Presence query for '" + f_ready_download.getName() + "': availability="+
+									log( torrent,
+											"Presence query: availability="+
 											(total==INTERESTING_AVAIL_MAX?(INTERESTING_AVAIL_MAX+"+"):(total+"")) + ",div=" + diversified +
-											" (elapsed=" + (SystemTime.getCurrentTime() - start) + ")");
+											" (elapsed=" + TimeFormatter.formatColonMillis(SystemTime.getCurrentTime() - start) + ")");
 											
 									if ( diversified ){
 										
@@ -2585,16 +2740,19 @@ DHTTrackerPlugin
 										
 										interesting_published++;
 										
-										dht.put( 
-												f_ready_download.getTorrent().getHash(),
+										if ( !disable_put ){
+											
+											dht.put( 
+												torrent.getHash(),
 												"Presence store '" + f_ready_download.getName() + "'",
 												"0".getBytes(),	// port 0, no connections
 												(byte)0,
 												new DHTPluginOperationListener()
 												{
-													public void
+													public boolean
 													diversified()
 													{
+														return( true );
 													}
 													
 													public void 
@@ -2624,7 +2782,37 @@ DHTTrackerPlugin
 													{
 													}
 												});
-	
+										}
+									}
+									
+									
+									try{
+										this_mon.enter();
+									
+										int[] run_data = running_downloads.get( f_ready_download );
+										
+										if ( run_data == null ){
+											
+											run_data = run_data_cache.get( f_ready_download );
+										}
+										
+										if ( run_data != null ){
+
+											if ( total < INTERESTING_AVAIL_MAX ){
+											
+												run_data[1] = seeds;
+												run_data[2]	= leechers;
+												run_data[3] = total;
+												
+											}else{
+												
+												run_data[1] = Math.max( run_data[1], seeds );
+												run_data[2] = Math.max( run_data[2], leechers );
+											}
+										}
+									}finally{
+										
+										this_mon.exit();
 									}
 									
 									f_ready_download.setScrapeResult(
@@ -2681,7 +2869,9 @@ DHTTrackerPlugin
 											public URL
 											getURL()
 											{
-												return( f_ready_download.getTorrent().getAnnounceURL());
+												URL	url_to_report = torrent.isDecentralised()?torrent.getAnnounceURL():DEFAULT_URL;
+
+												return( url_to_report );
 											}
 										});
 								}
@@ -2770,7 +2960,10 @@ DHTTrackerPlugin
 		}
 	}
 	
-	/*
+		/**
+		 * This is used by the dhtscraper plugin
+		 */
+	
 	public DownloadScrapeResult
 	scrape(
 		byte[]		hash )
@@ -2788,9 +2981,10 @@ DHTTrackerPlugin
 				false, false,
 				new DHTPluginOperationListener()
 				{
-					public void
+					public boolean
 					diversified()
 					{
+						return( true );
 					}
 					
 					public void 
@@ -2890,7 +3084,6 @@ DHTTrackerPlugin
 					}
 				});
 	}
-	*/
 	
 	protected void
 	increaseActive(
@@ -3257,6 +3450,226 @@ DHTTrackerPlugin
 		return( res );
 	}
 	
+	private void
+	log(
+		Download		download,
+		String			str )
+	{
+		log( download.getTorrent(), str );
+	}
+	
+	private void
+	log(
+		Torrent			torrent,
+		String			str )
+	{
+		log.log( torrent, LoggerChannel.LT_INFORMATION, str );
+	}
+	
+	public TrackerPeerSource
+	getTrackerPeerSource(
+		final Download		download )
+	{
+		return(
+			new TrackerPeerSourceAdapter()
+			{
+				private long	last_fixup;
+				private boolean	updating;
+				private int		status		= ST_UNKNOWN;
+				private long	next_time	= -1;
+				private int[]	run_data;
+				
+				private void
+				fixup()
+				{
+					long now = SystemTime.getMonotonousTime();
+					
+					if ( now - last_fixup > 5*1000 ){
+				
+						try{
+							this_mon.enter();
+							
+							updating 	= false;
+							next_time	= -1;
+							
+							run_data = running_downloads.get( download );
+							
+							if ( run_data != null ){
+								
+								if ( in_progress.containsKey( download )){
+									
+									updating = true;
+								}
+								
+								status = initialised_sem.isReleasedForever()?ST_ONLINE:ST_STOPPED;
+								
+								Long l_next_time = query_map.get( download );
+								
+								if ( l_next_time != null ){
+									
+									next_time = l_next_time.longValue();
+								}
+							}else if ( interesting_downloads.containsKey( download )){
+								
+								status = ST_STOPPED;
+								
+							}else{
+								
+								int dl_state = download.getState();
+								
+								if ( 	dl_state == Download.ST_DOWNLOADING ||
+										dl_state == Download.ST_SEEDING ||
+										dl_state == Download.ST_QUEUED ){
+										
+									status = ST_DISABLED;
+									
+								}else{
+									
+									status = ST_STOPPED;
+								}
+							}
+							
+							if ( run_data == null ){
+								
+								run_data = run_data_cache.get( download );
+							}
+						}finally{
+							
+							this_mon.exit();
+						}
+											
+						String[]	sources = download.getListAttribute( ta_peer_sources );
+
+						boolean	ok = false;
+						
+						if ( sources != null ){
+							
+							for (int i=0;i<sources.length;i++){
+								
+								if ( sources[i].equalsIgnoreCase( "DHT")){
+									
+									ok	= true;
+									
+									break;
+								}
+							}
+						}
+						
+						if ( !ok ){
+							
+							status = ST_DISABLED;
+						}
+						
+						last_fixup = now;
+					}
+				}
+				
+				public int
+				getType()
+				{
+					return( TP_DHT );
+				}
+				
+				public String
+				getName()
+				{
+					return( "DHT: " + model.getStatus().getText());
+				}
+				
+				public int
+				getStatus()
+				{
+					fixup();
+					
+					return( status );
+				}
+				
+				public int
+				getSeedCount()
+				{
+					fixup();
+					
+					if ( run_data == null ){
+						
+						return( -1 );
+					}
+					
+					return( run_data[1] );
+				}
+				
+				public int
+				getLeecherCount()
+				{
+					fixup();
+					
+					if ( run_data == null ){
+						
+						return( -1 );
+					}
+					
+					return( run_data[2] );
+				}
+				
+				public int
+				getPeers()
+				{
+					fixup();
+					
+					if ( run_data == null ){
+						
+						return( -1 );
+					}
+					
+					return( run_data[3] );
+				}
+				
+				public int
+				getSecondsToUpdate()
+				{
+					fixup();
+					
+					if ( next_time < 0 ){
+						
+						return( -1 );
+					}
+					
+					return((int)(( next_time - SystemTime.getCurrentTime())/1000 ));
+				}
+				
+				public int
+				getInterval()
+				{
+					fixup();
+					
+					if ( run_data == null ){
+						
+						return( -1 );
+					}
+					
+					return((int)(current_announce_interval/1000));
+				}
+				
+				public int
+				getMinInterval()
+				{
+					fixup();
+					
+					if ( run_data == null ){
+						
+						return( -1 );
+					}
+					
+					return( ANNOUNCE_MIN_DEFAULT/1000 );
+				}
+				
+				public boolean
+				isUpdating()
+				{
+					return( updating );
+				}
+			});
+	}
+	
 	public static List<Object[]>
 	getVivaldiTargets(
 		byte[]					torrent_hash,
@@ -3467,10 +3880,10 @@ DHTTrackerPlugin
 		{
 			if ( type != REG_TYPE_FULL ){
 			
-				return( " (" + desc + ")" );
+				return( "(" + desc + ")" );
 			}
 			
-			return( "" );
+			return( "(root)" );
 		}
 	}
 	
diff --git a/com/aelitis/azureus/plugins/tracker/local/LocalTrackerPlugin.java b/com/aelitis/azureus/plugins/tracker/local/LocalTrackerPlugin.java
index 7f2b97a..b807474 100644
--- a/com/aelitis/azureus/plugins/tracker/local/LocalTrackerPlugin.java
+++ b/com/aelitis/azureus/plugins/tracker/local/LocalTrackerPlugin.java
@@ -28,9 +28,11 @@ import java.net.InetAddress;
 import java.util.*;
 
 
+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.SHA1Simple;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.download.Download;
@@ -55,6 +57,8 @@ 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.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 
 public class 
 LocalTrackerPlugin
@@ -72,8 +76,9 @@ LocalTrackerPlugin
 	private TorrentAttribute 	ta_networks;
 	private TorrentAttribute 	ta_peer_sources;
 
-	private Map 				downloads 	= new HashMap();
-	private Map					track_times	= new HashMap();
+	private Map<Download,long[]>	downloads 	= new HashMap<Download, long[]>();
+	
+	private Map<String,Map<String,Long>>	track_times	= new HashMap<String, Map<String,Long>>();
 	
 	private String				last_autoadd	= "";
 	private String				last_subnets	= "";
@@ -225,7 +230,7 @@ LocalTrackerPlugin
 		try{
 			mon.enter();
 			
-			track_times.put( instance.getID(), new HashMap());
+			track_times.put( instance.getID(), new HashMap<String, Long>());
 			
 		}finally{
 			
@@ -338,19 +343,19 @@ LocalTrackerPlugin
 
 						try{
 							
-							List	todo = new ArrayList();
+							List<Download>	todo = new ArrayList<Download>();
 							
 							try{
 								mon.enter();
 								
-								Iterator	it = downloads.entrySet().iterator();
+								Iterator<Map.Entry<Download,long[]>>	it = downloads.entrySet().iterator();
 								
 								while( it.hasNext()){
 									
-									Map.Entry	entry = (Map.Entry)it.next();
+									Map.Entry<Download,long[]>	entry = it.next();
 									
-									Download	dl 		= (Download)entry.getKey();
-									long		when	= ((Long)entry.getValue()).longValue();
+									Download	dl 		= entry.getKey();
+									long		when	= entry.getValue()[0];
 									
 									if ( when > current_time || current_time - when > ANNOUNCE_PERIOD ){
 										
@@ -365,7 +370,7 @@ LocalTrackerPlugin
 							
 							for (int i=0;i<todo.size();i++){
 							
-								track((Download)todo.get(i));
+								track(todo.get(i));
 							}
 							
 						}catch( Throwable e ){
@@ -392,20 +397,20 @@ LocalTrackerPlugin
 		try{
 			mon.enter();
 			
-			Long		l_last_track	= (Long)downloads.get( download );
+			long[]	data = downloads.get( download );
 			
-			if ( l_last_track == null ){
+			if ( data == null ){
 				
 				return;
 			}
 			
-			long	last_track = l_last_track.longValue();
+			long	last_track = data[0];
 			
 			if ( last_track > now || now - last_track > RE_ANNOUNCE_PERIOD ){
 					
 				ok	= true;
 	
-				downloads.put( download, new Long( now ));
+				data[0] = now;
 			}
 			
 		}finally{
@@ -480,10 +485,41 @@ LocalTrackerPlugin
 					}
 				});
 		
+		int	total_seeds 	= 0;
+		int	total_leechers	= 0;
+		int	total_peers		= 0;
 		
 		for (int i=0;i<peers.length;i++){
 			
-			handleTrackResult( peers[i] );
+			int res = handleTrackResult( peers[i] );
+			
+			if ( res == 1 ){
+				total_seeds++;
+			}else if ( res == 2 ){
+				total_leechers++;
+			}else if ( res == 3 ){
+				total_seeds++;
+				total_peers++;
+			}else if ( res == 4 ){
+				total_leechers++;
+				total_peers++;
+			}
+		}
+		
+		try{
+			mon.enter();
+
+			long[] data = downloads.get( download );
+			
+			if ( data != null ){
+				
+				data[1] = total_seeds;
+				data[2] = total_leechers;
+				data[3] = total_peers;
+			}
+		}finally{
+			
+			mon.exit();
 		}
 	}
 	
@@ -494,15 +530,26 @@ LocalTrackerPlugin
 		try{
 			mon.enter();
 
-			downloads.put( download, new Long(0));
+			long[] data = downloads.get( download );
+			
+			if ( data == null ){
+				
+				data = new long[4];
+				
+				downloads.put( download, data );
+				
+			}else{
+			
+				data[0] = 0;
+			}
 			
 			String	dl_key = plugin_interface.getUtilities().getFormatters().encodeBytesToString(download.getTorrent().getHash());
 
-			Iterator	it = track_times.values().iterator();
+			Iterator<Map<String,Long>>	it = track_times.values().iterator();
 			
 			while( it.hasNext()){
 				
-				((Map)it.next()).remove( dl_key );
+				it.next().remove( dl_key );
 			}
 		}finally{
 			
@@ -520,7 +567,7 @@ LocalTrackerPlugin
 			});
 	}
 	
-	protected void
+	protected int
 	handleTrackResult(
 		AZInstanceTracked		tracked_inst )
 	{
@@ -539,18 +586,18 @@ LocalTrackerPlugin
 		try{
 			mon.enter();
 			
-			Map	map = (Map)track_times.get( inst.getID() );
+			Map<String,Long>	map = track_times.get( inst.getID() );
 			
 			if ( map == null ){
 				
-				map	= new HashMap();
+				map	= new HashMap<String, Long>();
 				
 				track_times.put( inst.getID(), map );
 			}
 			
 			String	dl_key = plugin_interface.getUtilities().getFormatters().encodeBytesToString(download.getTorrent().getHash());
 			
-			Long	last_track = (Long)map.get( dl_key );
+			Long	last_track = map.get( dl_key );
 			
 			if ( last_track != null ){
 				
@@ -571,14 +618,14 @@ LocalTrackerPlugin
 		
 		if ( skip ){
 		
-			return;
+			return( -1 );
 		}
 		
 		log.log( "Tracked: " + inst.getString() + ": " + download.getName() + ", seed = " + is_seed );
 
 		if ( download.isComplete() && is_seed ){
 			
-			return;
+			return( is_seed?1:0 );
 		}
 		
 		PeerManager	peer_manager = download.getPeerManager();
@@ -593,6 +640,8 @@ LocalTrackerPlugin
 			
 			peer_manager.addPeer( peer_ip, peer_tcp_port, peer_udp_port, false );
 		}
+		
+		return( is_seed?3:2 );
 	}
 	
 	public void
@@ -642,7 +691,18 @@ LocalTrackerPlugin
 				log.log( "Tracking " + download.getName());
 			}
 
-			downloads.put( download, new Long(0));
+			long[] data = downloads.get( download );
+			
+			if ( data == null ){
+				
+				data = new long[4];
+				
+				downloads.put( download, data );
+				
+			}else{
+			
+				data[0] = 0;
+			}
 			
 			download.addListener( this );
 			
@@ -669,6 +729,173 @@ LocalTrackerPlugin
 		}
 	}
 	
+	public TrackerPeerSource
+	getTrackerPeerSource(
+		final Download		download )
+	{
+		return(
+			new TrackerPeerSourceAdapter()
+			{
+				private long[] 		_last_data;
+				private boolean		enabled;
+				private boolean		running;
+				private long		fixup_time;
+				
+				private long[]
+				fixup()
+				{
+					long now = SystemTime.getMonotonousTime();
+					
+					if ( now - fixup_time > 1000 ){
+						
+						try{
+							mon.enter();
+	
+							_last_data = downloads.get( download );
+							
+						}finally{
+							
+							mon.exit();
+						}
+						
+						enabled = LocalTrackerPlugin.this.enabled.getValue();
+						
+						if ( enabled ){
+							
+							int ds = download.getState();
+							
+							running = ds == Download.ST_DOWNLOADING || ds == Download.ST_SEEDING;
+							
+						}else{
+							
+							running = false;
+						}
+						
+						fixup_time = now;
+					}
+					
+					return( _last_data );
+				}
+				
+				public int
+				getType()
+				{
+					return( TP_LAN );
+				}
+				
+				public String
+				getName()
+				{
+					return( MessageText.getString( "tps.lan.details", new String[]{ String.valueOf( instance_manager.getOtherInstanceCount())}));
+				}
+				
+				public int
+				getStatus()
+				{
+					long[] last_data = fixup();
+					
+					if ( last_data == null || !enabled ){
+						
+						return( ST_DISABLED );
+					}
+					
+					if ( running ){
+						
+						return( ST_ONLINE );
+					}
+					
+					return( ST_STOPPED );
+				}
+				
+				public int
+				getSeedCount()
+				{
+					long[] last_data = fixup();
+					
+					if ( last_data == null || !running ){
+						
+						return( -1 );
+					}
+					
+					return((int)last_data[1] );
+				}
+				
+				public int
+				getLeecherCount()
+				{
+					long[] last_data = fixup();
+					
+					if ( last_data == null || !running ){
+						
+						return( -1 );
+					}
+					
+					return((int)last_data[2] );
+				}
+				
+				public int
+				getPeers()
+				{
+					long[] last_data = fixup();
+					
+					if ( last_data == null || !running ){
+						
+						return( -1 );
+					}
+					
+					return((int)last_data[3] );
+				}
+				
+				public int 
+				getSecondsToUpdate() 
+				{
+					long[] last_data = fixup();
+					
+					if ( last_data == null || !running ){
+						
+						return( Integer.MIN_VALUE );
+					}
+					
+					return((int)(( ANNOUNCE_PERIOD - ( SystemTime.getCurrentTime() - last_data[0] ))/1000 ));
+				}
+				
+				public int 
+				getInterval() 
+				{
+					if ( running ){
+					
+						return((int)( ANNOUNCE_PERIOD/1000 ));
+					}
+					
+					return( -1 );
+				}
+				
+				public int 
+				getMinInterval() 
+				{
+					if ( running ){
+					
+						return((int)( RE_ANNOUNCE_PERIOD/1000 ));
+					}
+					
+					return( -1 );
+				}
+				
+				public boolean
+				isUpdating()
+				{
+					int	su = getSecondsToUpdate();
+					
+					if ( su == Integer.MIN_VALUE || su >= 0 ){
+						
+						return( false );
+					}
+					
+					return( true );
+				}
+			});
+	}
+	
 	public void
 	stateChanged(
 		Download		download,
diff --git a/com/aelitis/azureus/plugins/upnp/UPnPPlugin.java b/com/aelitis/azureus/plugins/upnp/UPnPPlugin.java
index 6d5f3df..ab64894 100644
--- a/com/aelitis/azureus/plugins/upnp/UPnPPlugin.java
+++ b/com/aelitis/azureus/plugins/upnp/UPnPPlugin.java
@@ -45,10 +45,12 @@ import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocument;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
 
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.IndentWriter;
 
 import com.aelitis.net.natpmp.NATPMPDeviceAdapter;
 import com.aelitis.net.natpmp.NatPMPDeviceFactory;
@@ -59,7 +61,7 @@ import com.aelitis.net.upnp.services.*;
 
 public class 
 UPnPPlugin
-	implements Plugin, UPnPListener, UPnPMappingListener, UPnPWANConnectionListener
+	implements Plugin, UPnPListener, UPnPMappingListener, UPnPWANConnectionListener, AEDiagnosticsEvidenceGenerator
 {
 	private static final String UPNP_PLUGIN_CONFIGSECTION_ID 	= "UPnP";
 	private static final String NATPMP_PLUGIN_CONFIGSECTION_ID 	= "NATPMP";
@@ -123,6 +125,8 @@ UPnPPlugin
 		plugin_interface	= _plugin_interface;
 		
 		log = plugin_interface.getLogger().getTimeStampedChannel("UPnP");
+		log.setDiagnostic();
+		log.setForce(true);
 
 		UIManager	ui_manager = plugin_interface.getUIManager();
 		
@@ -151,7 +155,7 @@ UPnPPlugin
 					Parameter	param )
 				{
 					try{
-						plugin_interface.getUIManager().openURL( new URL( "http://www.azureuswiki.com/index.php/NATPMP" ));
+						plugin_interface.getUIManager().openURL( new URL( "http://wiki.vuze.com/w/NATPMP" ));
 						
 					}catch( Throwable e ){
 						
@@ -181,7 +185,7 @@ UPnPPlugin
 			// UPNP
 		
 		upnp_config.addLabelParameter2( "upnp.info" );
-		upnp_config.addHyperlinkParameter2("upnp.wiki_link", "http://www.azureuswiki.com/index.php/UPnP");
+		upnp_config.addHyperlinkParameter2("upnp.wiki_link", "http://wiki.vuze.com/w/UPnP");
 		
 		
 		upnp_enable_param = 
@@ -1536,4 +1540,55 @@ UPnPPlugin
 			this.upnp.reset();
 		}
 	}
+	
+	public void
+	generate(
+		IndentWriter		writer )
+	{
+		List<UPnPMapping>		mappings_copy;
+		List<UPnPPluginService>	services_copy;
+		
+		try{
+			this_mon.enter();
+
+			mappings_copy 	= new ArrayList<UPnPMapping>( mappings );
+			
+			services_copy	= new ArrayList<UPnPPluginService>( services );
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+		
+		writer.println( "Mappings" );
+		
+		try{
+			writer.indent();
+			
+			for ( UPnPMapping mapping: mappings_copy ){
+				
+				if ( mapping.isEnabled()){
+				
+					writer.println( mapping.getString());
+				}
+			}
+		}finally{
+			
+			writer.exdent();
+		}
+		
+		writer.println( "Services" );
+		
+		try{
+			writer.indent();
+			
+			for ( UPnPPluginService service: services_copy ){
+				
+				writer.println( service.getString());
+			}
+		}finally{
+			
+			writer.exdent();
+		}
+	}
 }
diff --git a/com/aelitis/azureus/plugins/upnp/UPnPPluginService.java b/com/aelitis/azureus/plugins/upnp/UPnPPluginService.java
index f32c7bf..dc9a5a6 100644
--- a/com/aelitis/azureus/plugins/upnp/UPnPPluginService.java
+++ b/com/aelitis/azureus/plugins/upnp/UPnPPluginService.java
@@ -32,6 +32,7 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.internat.*;
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.logging.*;
 import org.gudy.azureus2.plugins.ui.config.BooleanParameter;
 
@@ -229,7 +230,9 @@ UPnPPluginService
 				
 					// not found - try and establish it + add entry even if we fail so
 					// that we don't retry later
-							
+				
+				String	error_text = null;
+				
 				try{
 					connection.addPortMapping( 
 						mapping.isTCP(), mapping.getPort(), 
@@ -255,9 +258,11 @@ UPnPPluginService
 						
 						log.logAlertRepeatable( LoggerChannel.LT_INFORMATION, text );
 					}
-					
+										
 				}catch( Throwable e ){
 					
+					error_text = Debug.getNestedExceptionMessage( e );
+					
 					String	text = 
 						MessageText.getString( 
 								"upnp.alert.mappingfailed", 
@@ -275,7 +280,13 @@ UPnPPluginService
 					
 					serviceMapping	new_mapping = new serviceMapping( mapping );
 				
+					new_mapping.setError( error_text );
+
 					service_mappings.add( new_mapping );
+					
+				}else{
+					
+					grab_in_progress.setError( error_text );
 				}
 				
 			}else{
@@ -420,6 +431,26 @@ UPnPPluginService
 		}
 	}
 	
+	public String
+	getString()
+	{
+		String str = "name=" + getName() + ",info=" + getInfo() + ",int=" + getAddress() + ":" + getPort() + ",ext=" + getExternalAddress();
+		
+		serviceMapping[] sms = getMappings();
+		
+		for ( serviceMapping sm: sms ){
+			
+			String error = sm.getError();
+			
+			if ( error != null ){
+				
+				str += ":" + sm.getString() + " -> " + error;
+			}
+		}
+		
+		return( str );
+	}
+	
 	public class
 	serviceMapping
 	{
@@ -433,6 +464,8 @@ UPnPPluginService
 		
 		private List		logged_mappings = new ArrayList();
 		
+		private String		error;
+		
 		protected
 		serviceMapping(
 			UPnPWANConnectionPortMapping		device_mapping )
@@ -526,6 +559,19 @@ UPnPPluginService
 			return( internal_host );
 		}
 		
+		private String
+		getError()
+		{
+			return( error );
+		}
+		
+		private void
+		setError(
+			String	_error )
+		{
+			error = _error;
+		}
+		
 		public String
 		getString()
 		{
diff --git a/com/aelitis/azureus/ui/UIFunctions.java b/com/aelitis/azureus/ui/UIFunctions.java
index 84e9497..75a19e5 100644
--- a/com/aelitis/azureus/ui/UIFunctions.java
+++ b/com/aelitis/azureus/ui/UIFunctions.java
@@ -19,17 +19,15 @@
  */
 package com.aelitis.azureus.ui;
 
-import org.gudy.azureus2.core3.download.DownloadManager;
 
 import com.aelitis.azureus.core.AzureusCoreComponent;
 import com.aelitis.azureus.ui.common.updater.UIUpdater;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 
 /**
  * @author TuxPaper
  * @created Jun 14, 2006
  *
- *
- * TODO: Replace showXxxx(..) with showView(ID, ..) + ID Constants
  */
 public interface UIFunctions
 	extends AzureusCoreComponent
@@ -42,7 +40,6 @@ public interface UIFunctions
 
 	
 	public static final int VIEW_CONSOLE = 0;
-	public static final int VIEW_STATS = 1;
 	public static final int VIEW_CONFIG = 4;
 	public static final int VIEW_DM_DETAILS = 5;
 	public static final int VIEW_DM_MULTI_OPTIONS = 6;
@@ -50,10 +47,10 @@ public interface UIFunctions
 	public static final int VIEW_MYTORRENTS = 8;
 	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
+	public static final int ACTION_FULL_UPDATE				= 1;	// arg: String - url; response Boolean - ok
+	public static final int ACTION_UPDATE_RESTART_REQUEST	= 2;	// arg: Boolean - true->no auto-select response Boolean - ok
 	
 
 	/**
@@ -64,11 +61,11 @@ public interface UIFunctions
 	/**
 	 * Bring main window to the front
 	 * 
-	 * @param noTricks Don't try any tricks to force it to the top
+	 * @param tryTricks: try tricks to force it to the top
 	 *
 	 * @since 3.0.1.7
 	 */
-	void bringToFront(boolean noTricks);
+	void bringToFront(boolean tryTricks);
 	
 	/**
 	 * Change/Refresh the language of the UI
@@ -82,11 +79,6 @@ public interface UIFunctions
 
 	
 	/**
-	 * @param manager
-	 */
-	void removeManagerView(DownloadManager dm);
-
-	/**
 	 * @param string
 	 */
 	void setStatusText(String string);
@@ -134,8 +126,15 @@ public interface UIFunctions
 	 */
 	void openView(int viewID, Object datasource);
 	
-	void doSearch(String searchText);
+	void doSearch(String searchText );
 	
+	void doSearch(String searchText, boolean toSubscribe );
+
+	public void
+	installPlugin(
+		String			plugin_id,
+		String			resource_prefix,
+		actionListener	listener );
 	
 	/**
 	 * 
@@ -155,5 +154,17 @@ public interface UIFunctions
 		public void
 		actionComplete(
 			Object		result );
-	}		
+	}
+
+	/**
+	 * Retrieve the MDI (Sidebar, TabbedMDI)
+	 * @return
+	 */
+	public MultipleDocumentInterface getMDI();		
+
+	/**
+	 * Might launch the old-school Mr Slidey
+	 */
+	void forceNotify(int iconID, String title, String text, String details,
+			Object[] relatedObjects, int timeoutSecs);		
 }
diff --git a/com/aelitis/azureus/ui/UIFunctionsManager.java b/com/aelitis/azureus/ui/UIFunctionsManager.java
index 4ff497b..995b975 100644
--- a/com/aelitis/azureus/ui/UIFunctionsManager.java
+++ b/com/aelitis/azureus/ui/UIFunctionsManager.java
@@ -27,14 +27,20 @@ package com.aelitis.azureus.ui;
 public class UIFunctionsManager
 {
 	private static UIFunctions instance = null;
-	
-	public static UIFunctions getUIFunctions() {
+		
+	public static UIFunctions 
+	getUIFunctions() 
+	{
 		return instance;
 	}
 	
-	public static void setUIFunctions(UIFunctions uiFunctions) {
-		instance = uiFunctions;
+	public static void 
+	setUIFunctions(
+		UIFunctions uiFunctions )
+	{		
+		synchronized( UIFunctionsManager.class ){
+		
+			instance = uiFunctions;
+		}
 	}
-	
-	// TODO: Listener to trigger when instance set
-}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/common/ToolBarEnabler.java b/com/aelitis/azureus/ui/common/ToolBarEnabler.java
new file mode 100644
index 0000000..71144d5
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/ToolBarEnabler.java
@@ -0,0 +1,14 @@
+package com.aelitis.azureus.ui.common;
+
+import java.util.Map;
+
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarEnablerBase;
+
+// Change with caution: Some internal plugins use this directly
+public interface ToolBarEnabler
+	extends UIToolBarEnablerBase
+{
+	public void refreshToolBar(Map<String, Boolean> list);
+
+	public boolean toolBarItemActivated(String itemKey);
+}
diff --git a/com/aelitis/azureus/ui/common/ToolBarItem.java b/com/aelitis/azureus/ui/common/ToolBarItem.java
new file mode 100644
index 0000000..be61c69
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/ToolBarItem.java
@@ -0,0 +1,18 @@
+package com.aelitis.azureus.ui.common;
+
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+
+public interface ToolBarItem
+	extends UIToolBarItem
+{
+	public boolean triggerToolBarItem(long activationType, Object datasource);
+
+	public void setDefaultActivationListener(UIToolBarActivationListener toolBarActivation);
+
+	public void setAlwaysAvailable(boolean b);
+
+	public String getTooltipID();
+
+	public UIToolBarActivationListener getDefaultActivationListener();
+}
diff --git a/com/aelitis/azureus/ui/common/table/TableCellCore.java b/com/aelitis/azureus/ui/common/table/TableCellCore.java
index 36d0961..c645192 100644
--- a/com/aelitis/azureus/ui/common/table/TableCellCore.java
+++ b/com/aelitis/azureus/ui/common/table/TableCellCore.java
@@ -98,6 +98,8 @@ public interface TableCellCore extends TableCell, Comparable
 	 * @return the row that this cell belongs to
 	 */
 	public TableRowCore getTableRowCore();
+	
+	public TableColumnCore getTableColumnCore();
 
 	/**
 	 * Trigger all the tooltip listeners that have been added to this cell
@@ -154,8 +156,9 @@ public interface TableCellCore extends TableCell, Comparable
 	 * Set the cursor ID that should be used for the cell
 	 * 
 	 * @param cursor_hand
+	 * @return changed
 	 */
-	public void setCursorID(int cursorID);
+	public boolean setCursorID(int cursorID);
 	
 	/**
 	 * 
@@ -184,4 +187,12 @@ public interface TableCellCore extends TableCell, Comparable
 	 * @since 3.1.1.1
 	 */
 	void redraw();
+
+	/**
+	 * Sets tooltip to be shown in absence of an explicit one
+	 * @param str
+	 */
+	public void setDefaultToolTip(Object tt);
+
+	public Object getDefaultToolTip();
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableColumnCore.java b/com/aelitis/azureus/ui/common/table/TableColumnCore.java
index 2bf6440..d0a8dfc 100644
--- a/com/aelitis/azureus/ui/common/table/TableColumnCore.java
+++ b/com/aelitis/azureus/ui/common/table/TableColumnCore.java
@@ -42,12 +42,9 @@ public interface TableColumnCore
 	 * TableColumnManager.  Some functions can not be run after a column has been
 	 * added.
 	 *
-	 * @param bAdded true - Column has been added<br>
-	 *               false - Column has not been added
-	 *               
 	 * @since 2.1.0.0
 	 */
-	public void setColumnAdded(boolean bAdded);
+	public void setColumnAdded();
 
 	/** 
 	 * Retrieve whether the column has been added to the TableColumnManager
@@ -291,13 +288,20 @@ public interface TableColumnCore
 	void setSortAscending(boolean bAscending);
 
 	/**
+	 * @since 4.7.2.1
+	 * @param bAscending
+	 */
+	
+	void setDefaultSortAscending( boolean bAscending );
+	
+	/**
 	 * @return
 	 *
 	 * @since 3.0.1.1
 	 */
 	boolean hasCellMouseMoveListener();
 
-	void triggerColumnSizeChange();
+	void triggerColumnSizeChange(int diff);
 	
 	void setAutoTooltip(boolean auto_tooltip);
 	boolean doesAutoTooltip();
@@ -323,6 +327,9 @@ public interface TableColumnCore
 	 */
 	void addCellOtherListener(String listenerID, Object listener);
 
+	public void removeCellOtherListener(String listenerID,
+			Object l);
+
 	/**
 	 * @param listenerID
 	 * @return
@@ -354,4 +361,17 @@ public interface TableColumnCore
 	List<TableColumnExtraInfoListener> getColumnExtraInfoListeners();
 
 	void reset();
+
+	String getClipboardText(TableCell cell);
+
+	boolean handlesDataSourceType(Class<?> cla);
+
+	/**
+	 * @param forDataSourceType
+	 *
+	 * @since 4.6.0.1
+	 */
+	public void addDataSourceType(Class<?> forDataSourceType);
+	
+	public boolean showOnlyImage();
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableColumnCoreCreationListener.java b/com/aelitis/azureus/ui/common/table/TableColumnCoreCreationListener.java
new file mode 100644
index 0000000..acc8b32
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/table/TableColumnCoreCreationListener.java
@@ -0,0 +1,34 @@
+/**
+ * Created on Sep 20, 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.common.table;
+
+
+import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
+
+/**
+ * @author TuxPaper
+ * @created Sep 20, 2008
+ *
+ */
+public interface TableColumnCoreCreationListener
+	extends TableColumnCreationListener
+{
+	public TableColumnCore createTableColumnCore(Class<?> forDataSourceType,
+			String tableID, String columnID);
+}
diff --git a/com/aelitis/azureus/ui/common/table/TableRowCore.java b/com/aelitis/azureus/ui/common/table/TableRowCore.java
index b361185..1c0d27b 100644
--- a/com/aelitis/azureus/ui/common/table/TableRowCore.java
+++ b/com/aelitis/azureus/ui/common/table/TableRowCore.java
@@ -36,6 +36,8 @@ public interface TableRowCore extends TableRow
 	/** Invalidates Row */
 	public void invalidate();
 
+	public void invalidate(boolean mustRefresh);
+
 	/** 
 	 * Delete the row 
 	 */
@@ -108,17 +110,14 @@ public interface TableRowCore extends TableRow
 	 * @param bDoGraphics
 	 * @param bVisible
 	 */
-	public List refresh(boolean bDoGraphics, boolean bVisible);
+	public List<TableCellCore> refresh(boolean bDoGraphics, boolean bVisible);
 
 	/**
 	 * like refresh, except a different name to confuse us.
 	 */
 	public void redraw();
 
-	/**
-	 * @param bEvenIfNotVisible
-	 */
-	public void setAlternatingBGColor(boolean bEvenIfNotVisible);
+	public void redraw(boolean doChildren);
 
 	/**
 	 * @return
@@ -141,26 +140,51 @@ public interface TableRowCore extends TableRow
 	public boolean isMouseOver();
 
 	/**
-	 * @param id
+	 * @param length
+	 *
+	 * @since 4.4.0.5
+	 */
+	public void setSubItemCount(int length);
+	
+	public int getSubItemCount();
+
+	public boolean isExpanded();
+
+	public void setExpanded(boolean b);
+	
+	public TableRowCore getParentRowCore();
+
+	/**
 	 * @return
 	 *
-	 * @since 3.0.4.3
+	 * @since 4.4.0.5
 	 */
-	Object getData(String id);
+	public boolean isInPaintItem();
 
 	/**
-	 * @param id
-	 * @param data
+	 * @param indexOf
+	 * @return 
 	 *
-	 * @since 3.0.4.3
+	 * @since 4.4.0.5
 	 */
-	void setData(String id, Object data);
+	TableRowCore linkSubItem(int indexOf);
 
 	/**
-	 * @param height
-	 * @return
+	 * @param datasources
 	 *
-	 * @since 3.0.4.3
+	 * @since 4.4.0.5
 	 */
-	public boolean setDrawableHeight(int height);
+	void setSubItems(Object[] datasources);
+
+	TableRowCore[] getSubRowsWithNull();
+
+	void removeSubRow(Object datasource);
+
+	public int getHeight();
+
+	public TableRowCore getSubRow(int i);
+
+	public void setSortColumn(String columnID);
+	
+	public TableCellCore getSortColumnCell(String hint);
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableSelectedRowsListener.java b/com/aelitis/azureus/ui/common/table/TableSelectedRowsListener.java
index e71088d..d1c07d1 100644
--- a/com/aelitis/azureus/ui/common/table/TableSelectedRowsListener.java
+++ b/com/aelitis/azureus/ui/common/table/TableSelectedRowsListener.java
@@ -3,6 +3,9 @@ package com.aelitis.azureus.ui.common.table;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Listener;
 
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.ui.swt.Utils;
+
 /** 
  * Listener primarily for Menu Selection.  Implement run(TableRowCore) and it
  * will get called for each row the user has selected.
@@ -11,16 +14,21 @@ public abstract class TableSelectedRowsListener
 	extends TableGroupRowRunner
 	implements Listener
 {
-	/**
-	 * 
-	 */
-	private final TableView tv;
+	private final TableView<?> tv;
+	private final boolean getOffSWT;
+
+	public TableSelectedRowsListener(TableView<?> impl, boolean getOffSWT) {
+		tv = impl;
+		this.getOffSWT = getOffSWT;
+	}
 
 	/**
+	 * triggers the event off of the SWT thread
 	 * @param impl
 	 */
-	public TableSelectedRowsListener(TableView impl) {
+	public TableSelectedRowsListener(TableView<?> impl) {
 		tv = impl;
+		this.getOffSWT = true;
 	}
 
 	/** Event information passed in via the Listener.  Accessible in 
@@ -31,8 +39,16 @@ public abstract class TableSelectedRowsListener
 	/** Process the trapped event.  This function does not need to be overidden.
 	 * @param e event information
 	 */
-	public void handleEvent(Event e) {
+	public final void handleEvent(Event e) {
 		event = e;
-		tv.runForSelectedRows(this);
+		if (getOffSWT) {
+			Utils.getOffOfSWTThread(new AERunnable() {
+				public void runSupport() {
+					tv.runForSelectedRows(TableSelectedRowsListener.this);
+				}
+			});
+		} else {
+			tv.runForSelectedRows(this);
+		}
 	}
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableStructureEventDispatcher.java b/com/aelitis/azureus/ui/common/table/TableStructureEventDispatcher.java
index 9b77e22..31233d5 100644
--- a/com/aelitis/azureus/ui/common/table/TableStructureEventDispatcher.java
+++ b/com/aelitis/azureus/ui/common/table/TableStructureEventDispatcher.java
@@ -112,11 +112,11 @@ public class TableStructureEventDispatcher implements
 			}
 	}
 
-	public void columnSizeChanged(TableColumnCore tableColumn) {
+	public void columnSizeChanged(TableColumnCore tableColumn, int diff) {
 			Iterator iter = listeners.iterator();
 			while (iter.hasNext()) {
 				TableStructureModificationListener listener = (TableStructureModificationListener) iter.next();
-				listener.columnSizeChanged(tableColumn);
+				listener.columnSizeChanged(tableColumn, diff);
 			}
 	}
 
diff --git a/com/aelitis/azureus/ui/common/table/TableStructureModificationListener.java b/com/aelitis/azureus/ui/common/table/TableStructureModificationListener.java
index 2896891..b6c3ef9 100644
--- a/com/aelitis/azureus/ui/common/table/TableStructureModificationListener.java
+++ b/com/aelitis/azureus/ui/common/table/TableStructureModificationListener.java
@@ -34,7 +34,7 @@ public interface TableStructureModificationListener<T>
 
 	void columnOrderChanged(int[] iPositions);
 
-	void columnSizeChanged(TableColumnCore tableColumn);
+	void columnSizeChanged(TableColumnCore tableColumn, int diff);
 
 	void columnInvalidate(TableColumnCore tableColumn);
 	
diff --git a/com/aelitis/azureus/ui/common/table/TableView.java b/com/aelitis/azureus/ui/common/table/TableView.java
index 80f9f57..bf3001b 100644
--- a/com/aelitis/azureus/ui/common/table/TableView.java
+++ b/com/aelitis/azureus/ui/common/table/TableView.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator;
 import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
 
 /**
  * @author TuxPaper
@@ -119,9 +120,9 @@ public interface TableView<DATASOURCETYPE>
 	List<DATASOURCETYPE> getDataSources();
 
 	/**
-	 * @return
+	 * @note May not necessarily return DATASOURCETYPE if table has subrows
 	 */
-	DATASOURCETYPE getFirstSelectedDataSource();
+	Object getFirstSelectedDataSource();
 
 	/**
 	 * @return
@@ -146,8 +147,10 @@ public interface TableView<DATASOURCETYPE>
 	 * ommitted.
 	 *
 	 * @return an array containing the selected data sources
+	 * 
+	 * @note May not necessarily return DATASOURCETYPE if table has subrows
 	 */
-	List<DATASOURCETYPE> getSelectedDataSources();
+	List<Object> getSelectedDataSources();
 
 	/** 
 	 * Returns an array of all selected Data Sources.  Null data sources are
@@ -176,8 +179,6 @@ public interface TableView<DATASOURCETYPE>
 	 */
 	boolean isDisposed();
 
-	boolean isTableFocus();
-
 	/**
 	 * Process the queue of datasources to be added and removed
 	 *
@@ -240,6 +241,9 @@ public interface TableView<DATASOURCETYPE>
 	 */
 	void setParentDataSource(Object newDataSource);
 
+
+	Object getParentDataSource();
+
 	/**
 	 * @param iHeight
 	 */
@@ -253,8 +257,6 @@ public interface TableView<DATASOURCETYPE>
 	 */
 	int size(boolean bIncludeQueue);
 
-	void updateLanguage();
-
 	/**
 	 * @return
 	 */
@@ -284,15 +286,6 @@ public interface TableView<DATASOURCETYPE>
 	TableColumnCore[] getVisibleColumns();
 
 	/**
-	 * @param columns
-	 * @param defaultSortColumnID
-	 * @param titleIsMinWidth TODO
-	 */
-	public void setColumnList(TableColumnCore[] columns,
-			String defaultSortColumnID, boolean defaultSortAscending,
-			boolean titleIsMinWidth);
-
-	/**
 	 * @param dataSources
 	 */
 	void removeDataSources(DATASOURCETYPE[] dataSources);
@@ -367,4 +360,61 @@ public interface TableView<DATASOURCETYPE>
 	 * @since 3.1.1.1
 	 */
 	TableColumn getTableColumn(String columnName);
+	
+	void setEnabled(boolean enable);
+
+	boolean canHaveSubItems();
+
+	/**
+	 * @param tableRowImpl
+	 * @return
+	 *
+	 * @since 4.4.0.5
+	 */
+	boolean isSelected(TableRow row);
+
+	boolean isUnfilteredDataSourceAdded(Object ds);
+
+	/**
+	 * @param visible
+	 *
+	 * @since 4.6.0.5
+	 */
+	void setHeaderVisible(boolean visible);
+
+	/**
+	 * @return
+	 *
+	 * @since 4.6.0.5
+	 */
+	boolean getHeaderVisible();
+
+	/**
+	 * 
+	 *
+	 * @since 4.6.0.5
+	 */
+	void processDataSourceQueueSync();
+
+	/**
+	 * 
+	 *
+	 * @since 4.6.0.5
+	 */
+	int getMaxItemShown();
+
+	/**
+	 * @param newIndex
+	 *
+	 * @since 4.6.0.5
+	 */
+	void setMaxItemShown(int newIndex);
+
+	int getRowCount();
+
+	void resetLastSortedOn();
+
+	TableColumnCore[] getAllColumns();
+
+	void removeCountChangeListener(TableCountChangeListener l);
 }
diff --git a/com/aelitis/azureus/ui/common/table/TableViewFilterCheck.java b/com/aelitis/azureus/ui/common/table/TableViewFilterCheck.java
new file mode 100644
index 0000000..0aa6904
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/table/TableViewFilterCheck.java
@@ -0,0 +1,37 @@
+/**
+ * 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 com.aelitis.azureus.ui.common.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);
+
+	public interface TableViewFilterCheckEx<DATASOURCETYPE>
+		extends TableViewFilterCheck<DATASOURCETYPE>
+	{
+		public void viewChanged(TableView<DATASOURCETYPE> view);
+	}
+}
diff --git a/com/aelitis/azureus/ui/common/table/impl/DataSourceCallBackUtil.java b/com/aelitis/azureus/ui/common/table/impl/DataSourceCallBackUtil.java
new file mode 100644
index 0000000..fa645db
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/table/impl/DataSourceCallBackUtil.java
@@ -0,0 +1,159 @@
+package com.aelitis.azureus.ui.common.table.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.ui.common.table.impl.TableViewImpl;
+
+public class DataSourceCallBackUtil
+{
+	public static final long IMMEDIATE_ADDREMOVE_DELAY = 150;
+
+	private static final long IMMEDIATE_ADDREMOVE_MAXDELAY = 2000;
+
+	private static Timer timerProcessDataSources = new Timer("Process Data Sources");
+
+	private static TimerEvent timerEventProcessDS;
+
+	private static List processDataSourcesOutstanding = new ArrayList();
+	
+
+	public static boolean
+	addDataSourceAggregated(
+		addDataSourceCallback		callback )
+	{
+		if ( callback == null ){
+			
+			return( true );
+		}
+		
+		boolean processQueueImmediately = false;
+		
+		List	to_do_now = null;
+		
+		synchronized( timerProcessDataSources ){
+						
+			if ( timerEventProcessDS != null && !timerEventProcessDS.hasRun()){
+				
+					// Push timer forward, unless we've pushed it forward for over x seconds
+				
+				long now = SystemTime.getCurrentTime();
+				
+				if (now - timerEventProcessDS.getCreatedTime() < IMMEDIATE_ADDREMOVE_MAXDELAY) {
+					
+					long lNextTime = now + IMMEDIATE_ADDREMOVE_DELAY;
+										
+					timerProcessDataSources.adjustAllBy( lNextTime - timerEventProcessDS.getWhen());
+					
+					if ( !processDataSourcesOutstanding.contains( callback )){
+						
+						processDataSourcesOutstanding.add( callback );
+					}
+				}else{
+										
+					timerEventProcessDS.cancel();
+					
+					timerEventProcessDS = null;
+
+					processQueueImmediately = true;
+					
+					to_do_now = processDataSourcesOutstanding;
+					
+					processDataSourcesOutstanding = new ArrayList();
+				}
+			}else{
+				
+				if ( !processDataSourcesOutstanding.contains( callback )){
+					
+					processDataSourcesOutstanding.add( callback );
+				}
+
+				timerEventProcessDS = 
+					timerProcessDataSources.addEvent(
+						SystemTime.getCurrentTime() + IMMEDIATE_ADDREMOVE_DELAY,
+						new TimerEventPerformer() 
+						{
+							public void 
+							perform(
+								TimerEvent event ) 
+							{
+								List	to_do;
+																
+								synchronized( timerProcessDataSources ){
+								
+									timerEventProcessDS = null;
+
+									to_do = processDataSourcesOutstanding;
+									
+									processDataSourcesOutstanding = new ArrayList();
+								}
+								
+								for (int i=0;i<to_do.size();i++){
+									
+									try{
+										
+										addDataSourceCallback this_callback = (addDataSourceCallback)to_do.get(i);
+														
+										if (TableViewImpl.DEBUGADDREMOVE ) {
+											this_callback.debug("processDataSourceQueue after "
+													+ (SystemTime.getCurrentTime() - event.getCreatedTime())
+													+ "ms");
+										}
+										
+										this_callback.process();
+										
+									}catch( Throwable e ){
+										
+										Debug.printStackTrace(e);
+									}
+								}
+							}
+						});
+			}
+			
+			if ( to_do_now != null ){
+								
+					// process outside the synchronized block, otherwise we'll end up with deadlocks
+
+				to_do_now.remove( callback );
+				
+				for (int i=0;i<to_do_now.size();i++){
+					
+					try{
+						
+						addDataSourceCallback this_callback = (addDataSourceCallback)to_do_now.get(i);
+
+						if ( TableViewImpl.DEBUGADDREMOVE ){
+							
+							this_callback.debug("Over immediate delay limit, processing queue now");
+						}
+						
+						this_callback.process();
+						
+					}catch( Throwable e ){
+						
+						Debug.printStackTrace(e);
+					}
+				}
+			}
+		}
+		
+		return( processQueueImmediately );
+	}
+	
+	public interface
+	addDataSourceCallback
+	{
+		public void
+		process();
+		
+		public void
+		debug(
+			String		str );
+	}
+	
+	
+
+}
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java b/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
index 899bd2d..9cf9724 100644
--- a/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
+++ b/com/aelitis/azureus/ui/common/table/impl/TableColumnImpl.java
@@ -27,7 +27,6 @@ import java.util.*;
 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.views.table.utils.TableColumnManager;
 
 import com.aelitis.azureus.ui.common.table.*;
 
@@ -39,6 +38,7 @@ import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.plugins.sharing.ShareResource;
 import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
 import org.gudy.azureus2.plugins.ui.UIRuntimeException;
+import org.gudy.azureus2.plugins.ui.config.Parameter;
 import org.gudy.azureus2.plugins.ui.tables.*;
 
 import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
@@ -53,7 +53,7 @@ import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
  * 
  * @author TuxPaper
  * 
- * @see org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager
+ * @see com.aelitis.azureus.ui.common.table.impl.TableColumnManager
  */
 public class TableColumnImpl
 	implements TableColumnCore
@@ -68,6 +68,8 @@ public class TableColumnImpl
 
 	private int iAlignment;
 
+	private int	iDefaultAlignment = -1;
+	
 	private int iType;
 
 	private int iPosition;
@@ -87,23 +89,25 @@ public class TableColumnImpl
 
 	private boolean bCoreDataSource;
 
-	private ArrayList cellRefreshListeners;
+	private ArrayList<TableCellRefreshListener> cellRefreshListeners;
 
-	private ArrayList cellAddedListeners;
+	private ArrayList<TableCellAddedListener> cellAddedListeners;
 
-	private ArrayList cellDisposeListeners;
+	private ArrayList<TableCellDisposeListener> cellDisposeListeners;
 
-	private ArrayList cellToolTipListeners;
+	private ArrayList<TableCellToolTipListener> cellToolTipListeners;
 
-	private ArrayList cellMouseListeners;
+	private ArrayList<TableCellMouseListener> cellMouseListeners;
 
-	private ArrayList cellMouseMoveListeners;
+	private ArrayList<TableCellMouseMoveListener> cellMouseMoveListeners;
 
-	private ArrayList cellVisibilityListeners;
+	private ArrayList<TableCellVisibilityListener> cellVisibilityListeners;
+	
+	private ArrayList<TableCellClipboardListener> cellClipboardListeners;
 	
 	private ArrayList<TableColumnExtraInfoListener> columnExtraInfoListeners;
 
-	private Map mapOtherCellListeners;
+	private Map<String, List<Object>> mapOtherCellListeners;
 	
 	private int iConsecutiveErrCount;
 
@@ -124,6 +128,7 @@ public class TableColumnImpl
 	private long lStatsRefreshZeroCount = 0;
 
 	private boolean bSortAscending;
+	private boolean bDefaultSortAscending;
 	
 	private boolean editable;
 
@@ -149,49 +154,21 @@ public class TableColumnImpl
 
 	private boolean removed;
 	
-	private Class forPluginDataSourceType;
+	private List<Class<?>> forPluginDataSourceTypes = new ArrayList<Class<?>>();
+
+	private String iconID;
+
+	private boolean firstLoad;
+
+	private boolean showOnlyImage;
 
-	/**
-	 * @deprecated
-	 */
 	public TableColumnImpl(String tableID, String columnID) {
-		// Guess forPluginDataSourceType based on tableID
-		Class forPluginDataSourceType = null;
-		if (TableManager.TABLE_MYTORRENTS_ALL_BIG.equals(tableID)
-				|| TableManager.TABLE_MYTORRENTS_UNOPENED.equals(tableID)
-				|| TableManager.TABLE_MYTORRENTS_UNOPENED_BIG.equals(tableID)) {
-			forPluginDataSourceType = Download.class;
-		} else if (TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG.equals(tableID)
-				|| TableManager.TABLE_MYTORRENTS_INCOMPLETE.equals(tableID)) {
-			forPluginDataSourceType = DownloadTypeIncomplete.class;
-		} else if (TableManager.TABLE_MYTORRENTS_COMPLETE.equals(tableID)
-				|| TableManager.TABLE_MYTORRENTS_COMPLETE_BIG.equals(tableID)) {
-			forPluginDataSourceType = DownloadTypeComplete.class;
-		} else if (TableManager.TABLE_TORRENT_PEERS.equals(tableID)) {
-			forPluginDataSourceType = Peer.class;
-		} else if (TableManager.TABLE_TORRENT_FILES.equals(tableID)) {
-			forPluginDataSourceType = DiskManagerFileInfo.class;
-		} else if (TableManager.TABLE_MYTRACKER.equals(tableID)) {
-			forPluginDataSourceType = TrackerTorrent.class;
-		} else if (TableManager.TABLE_MYSHARES.equals(tableID)) {
-			forPluginDataSourceType = ShareResource.class;
-		}
-		init(forPluginDataSourceType, tableID, columnID);
-	}
-
-	/** Create a column object for the specified table.
-	 *
-	 * @param tableID table in which the column belongs to
-	 * @param columnID name/id of the column
-	 */
-	public TableColumnImpl(Class forDataSourceType, String tableID,
-			String columnID) {
-		init(forDataSourceType, tableID, columnID);
+		init(tableID, columnID);
 	}
+
 	
-	private void init(Class forDataSourceType, String tableID,
+	private void init(String tableID,
 			String columnID) {
-		this.forPluginDataSourceType = forDataSourceType;
 		sTableID = tableID;
 		sName = columnID;
 		iType = TYPE_TEXT_ONLY;
@@ -216,7 +193,7 @@ public class TableColumnImpl
 					+ " already added"));
 		}
 
-		this.iAlignment = iAlignment;
+		this.iAlignment = this.iDefaultAlignment =  iAlignment;
 		setPosition(iPosition);
 		this.iWidth = this.iDefaultWidth = iWidth;
 		this.iMinWidth = 16;
@@ -229,7 +206,7 @@ public class TableColumnImpl
 					+ " already added"));
 		}
 
-		this.iAlignment = iAlignment;
+		this.iAlignment = this.iDefaultAlignment = iAlignment;
 		setPosition(iPosition);
 		this.iWidth = this.iDefaultWidth = iWidth;
 		this.iMinWidth = 16;
@@ -280,19 +257,20 @@ public class TableColumnImpl
 		//			iPreferredWidth = iWidth;
 		//		}
 
+		int diff = width - iWidth;
 		iWidth = width;
 		if (iDefaultWidth == 0) {
 			iDefaultWidth = width;
 		}
 
 		if (bColumnAdded && bVisible) {
-			triggerColumnSizeChange();
+			triggerColumnSizeChange(diff);
 		}
 	}
 
-	public void triggerColumnSizeChange() {
+	public void triggerColumnSizeChange(int diff) {
 		TableStructureEventDispatcher tsed = TableStructureEventDispatcher.getInstance(sTableID);
-		tsed.columnSizeChanged(this);
+		tsed.columnSizeChanged(this, diff);
 		if (iType == TYPE_GRAPHIC) {
 			invalidateCells();
 		}
@@ -322,12 +300,23 @@ public class TableColumnImpl
 	}
 
 	public void setAlignment(int alignment) {
+		/*
 		if (bColumnAdded) {
 			throw (new UIRuntimeException("Can't set properties. Column '" + sName
 					+ " already added"));
 		}
-
+		*/
+		
 		iAlignment = alignment;
+		
+		if ( iDefaultAlignment == -1 ){
+			iDefaultAlignment = alignment;
+		}
+		
+		// Commented out because size hasn't changed!
+		//if (bColumnAdded && bVisible) {
+		//	triggerColumnSizeChange();
+		//}
 	}
 
 	public int getAlignment() {
@@ -339,7 +328,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellRefreshListeners == null) {
-				cellRefreshListeners = new ArrayList(1);
+				cellRefreshListeners = new ArrayList<TableCellRefreshListener>(1);
 			}
 
 			cellRefreshListeners.add(listener);
@@ -351,15 +340,15 @@ public class TableColumnImpl
 		}
 	}
 
-	public List getCellRefreshListeners() {
+	public List<TableCellRefreshListener> getCellRefreshListeners() {
 		try {
 			this_mon.enter();
 
 			if (cellRefreshListeners == null) {
-				return (new ArrayList(0));
+				return (new ArrayList<TableCellRefreshListener>(0));
 			}
 
-			return (new ArrayList(cellRefreshListeners));
+			return (new ArrayList<TableCellRefreshListener>(cellRefreshListeners));
 
 		} finally {
 
@@ -398,7 +387,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellAddedListeners == null) {
-				cellAddedListeners = new ArrayList(1);
+				cellAddedListeners = new ArrayList<TableCellAddedListener>(1);
 			}
 
 			cellAddedListeners.add(listener);
@@ -414,12 +403,12 @@ public class TableColumnImpl
 			this_mon.enter();
 			
 			if (mapOtherCellListeners == null) {
-				mapOtherCellListeners = new HashMap(1);
+				mapOtherCellListeners = new HashMap<String, List<Object>>(1);
 			}
 
-			List list = (List) mapOtherCellListeners.get(listenerID);
+			List<Object> list = mapOtherCellListeners.get(listenerID);
 			if (list == null) {
-				list = new ArrayList(1);
+				list = new ArrayList<Object>(1);
 				mapOtherCellListeners.put(listenerID, list);
 			}
 
@@ -431,12 +420,29 @@ public class TableColumnImpl
 		}
 	}
 	
+	public void removeCellOtherListener(String listenerID, Object l) {
+		try {
+			this_mon.enter();
+			
+  		if (mapOtherCellListeners == null) {
+  			return;
+  		}
+  		
+  		mapOtherCellListeners.remove(listenerID);
+
+		} finally {
+
+			this_mon.exit();
+		}
+
+	}
+	
 	public Object[] getCellOtherListeners(String listenerID) {
 		if (mapOtherCellListeners == null) {
 			return null;
 		}
 
-		List list = (List) mapOtherCellListeners.get(listenerID);
+		List<Object> list = mapOtherCellListeners.get(listenerID);
 		if (list == null) {
 			return null;
 		}
@@ -454,7 +460,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellAddedListeners == null) {
-				return (new ArrayList(0));
+				return Collections.emptyList();
 			}
 
 			return (new ArrayList(cellAddedListeners));
@@ -486,7 +492,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellDisposeListeners == null) {
-				cellDisposeListeners = new ArrayList(1);
+				cellDisposeListeners = new ArrayList<TableCellDisposeListener>(1);
 			}
 
 			cellDisposeListeners.add(listener);
@@ -516,7 +522,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellToolTipListeners == null) {
-				cellToolTipListeners = new ArrayList(1);
+				cellToolTipListeners = new ArrayList<TableCellToolTipListener>(1);
 			}
 
 			cellToolTipListeners.add(listener);
@@ -545,7 +551,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellMouseListeners == null) {
-				cellMouseListeners = new ArrayList(1);
+				cellMouseListeners = new ArrayList<TableCellMouseListener>(1);
 			}
 
 			cellMouseListeners.add(listener);
@@ -579,7 +585,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (cellMouseMoveListeners == null) {
-				cellMouseMoveListeners = new ArrayList(1);
+				cellMouseMoveListeners = new ArrayList<TableCellMouseMoveListener>(1);
 			}
 
 			cellMouseMoveListeners.add(listener);
@@ -604,12 +610,42 @@ public class TableColumnImpl
 		}
 	}
 
+	public void addCellClipboardListener(TableCellClipboardListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellClipboardListeners == null) {
+				cellClipboardListeners = new ArrayList<TableCellClipboardListener>(1);
+			}
+
+			cellClipboardListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeCellClipboardListener(TableCellClipboardListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellClipboardListeners == null) {
+				return;
+			}
+
+			cellClipboardListeners.remove(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
 	public void addCellVisibilityListener(TableCellVisibilityListener listener) {
 		try {
 			this_mon.enter();
 
 			if (cellVisibilityListeners == null) {
-				cellVisibilityListeners = new ArrayList(1);
+				cellVisibilityListeners = new ArrayList<TableCellVisibilityListener>(1);
 			}
 
 			cellVisibilityListeners.add(listener);
@@ -655,7 +691,7 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (columnExtraInfoListeners == null) {
-				columnExtraInfoListeners = new ArrayList(1);
+				columnExtraInfoListeners = new ArrayList<TableColumnExtraInfoListener>(1);
 			}
 
 			columnExtraInfoListeners.add(listener);
@@ -718,15 +754,24 @@ public class TableColumnImpl
 		if (listenerObject instanceof TableCellVisibilityListener) {
 			addCellVisibilityListener((TableCellVisibilityListener) listenerObject);
 		}
+
 		if (listenerObject instanceof TableColumnExtraInfoListener) {
 			addColumnExtraInfoListener((TableColumnExtraInfoListener) listenerObject);
 		}
+
+		if (listenerObject instanceof TableCellClipboardListener) {
+			addCellClipboardListener((TableCellClipboardListener) listenerObject);
+		}
 	}
 
 	/* Start of not plugin public API functions */
 	//////////////////////////////////////////////
-	public void setColumnAdded(boolean bAdded) {
-		bColumnAdded = bAdded;
+	public void setColumnAdded() {
+		if (bColumnAdded) {
+			return;
+		}
+		preAdd();
+		bColumnAdded = true;
 	}
 
 	public boolean getColumnAdded() {
@@ -743,7 +788,7 @@ public class TableColumnImpl
 
 	public void invokeCellRefreshListeners(TableCell cell, boolean fastRefresh) throws Throwable {
 		//System.out.println(this + " :: invokeCellRefreshListeners" + cellRefreshListeners);
-		if (cellRefreshListeners == null) {
+		if (cellRefreshListeners == null || cell == null || cell.isDisposed()) {
 			return;
 		}
 		
@@ -752,7 +797,7 @@ public class TableColumnImpl
 		//System.out.println(this + " :: invokeCellRefreshListeners" + cellRefreshListeners.size());
 		for (int i = 0; i < cellRefreshListeners.size(); i++) {
 			
-			TableCellRefreshListener l = (TableCellRefreshListener)cellRefreshListeners.get(i); 
+			TableCellRefreshListener l = cellRefreshListeners.get(i); 
 
 			try {
 				if(l instanceof TableCellLightRefreshListener)
@@ -804,6 +849,27 @@ public class TableColumnImpl
 		}
 	}
 
+	public String getClipboardText(TableCell cell) {
+		if (cellClipboardListeners == null) {
+			return null;
+		}
+		for (int i = 0; i < cellClipboardListeners.size(); i++) {
+			try {
+				String text = ((TableCellClipboardListener) (cellClipboardListeners.get(i))).getClipboardText(cell);
+				
+				if (text != null) {
+					return text;
+				}
+
+			} catch (Throwable e) {
+
+				Debug.printStackTrace(e);
+			}
+		}
+
+		return null;
+	}
+
 	public void invokeCellToolTipListeners(TableCellCore cell, int type) {
 		if (cellToolTipListeners == null) {
 			return;
@@ -831,7 +897,7 @@ public class TableColumnImpl
 	}
 
 	public void invokeCellMouseListeners(TableCellMouseEvent event) {
-		ArrayList listeners = event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE
+		ArrayList<?> listeners = event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE
 				? cellMouseMoveListeners : this.cellMouseListeners;
 		if (listeners == null) {
 			return;
@@ -905,7 +971,9 @@ public class TableColumnImpl
 			
 		TableStructureEventDispatcher tsed = TableStructureEventDispatcher.getInstance(sTableID);
 					
-		tsed.tableStructureChanged(true, forPluginDataSourceType);
+		for (Class<?> cla : forPluginDataSourceTypes) {
+			tsed.tableStructureChanged(true, cla);
+		}
 	}
 
 	public boolean 
@@ -917,6 +985,7 @@ public class TableColumnImpl
 	public final void loadSettings(Map mapSettings) {
 		// Format: Key = [TableID].column.[columnname]
 		// Value[] = { visible, width, position, autotooltip, sortorder }
+ 
 		String itemPrefix = "Column." + sName;
 		String oldItemPrefix = "Table." + sTableID + "." + sName;
 		Object object = mapSettings.get(itemPrefix);
@@ -975,6 +1044,8 @@ public class TableColumnImpl
 				// which we shouldn't do if we aren't the sorting column
 				bSortAscending = sortOrder == 1;
 			}
+		}else{
+			bSortAscending = bDefaultSortAscending;
 		}
 		
 		pos++;
@@ -983,15 +1054,26 @@ public class TableColumnImpl
 			if(userData.size() < 1)
 				userData = null;
 		}
-		
+		pos++;
+		if (list.length >= (pos + 1) && (list[pos] instanceof Number)) {
+			int align = ((Number) list[pos]).intValue();
+			setAlignment( align );
+		}
+		firstLoad = list.length == 0;
 		postConfigLoad();
 	}
 	
+	public boolean isFirstLoad() {
+		return firstLoad;
+	}
+	
 	/* (non-Javadoc)
 	 * @see org.gudy.azureus2.plugins.ui.tables.TableColumn#postLoad()
 	 */
 	public void postConfigLoad() {}
-	
+
+	public void preAdd() {}
+
 	public void preConfigSave() {}
 
 	public final void saveSettings(Map mapSettings) {
@@ -1010,7 +1092,8 @@ public class TableColumnImpl
 			new Integer(iWidth),
 			new Integer(auto_tooltip ? 1 : 0),
 			new Integer(lLastSortValueChange == 0 ? -1 : (bSortAscending ? 1 : 0)),
-			userData != null ? userData : Collections.EMPTY_MAP
+			userData != null ? userData : Collections.EMPTY_MAP,
+			new Integer(iAlignment)
 		}));
 		// cleanup old config
 		sItemPrefix = "Table." + sTableID + "." + sName; 
@@ -1026,8 +1109,8 @@ public class TableColumnImpl
 			this_mon.enter();
 
 			if (sTitleLanguageKey == null) {
-				sTitleLanguageKey = sTableID + ".column." + sName;
-				if (MessageText.keyExists(sTitleLanguageKey)) {
+				if (MessageText.keyExists(sTableID + ".column." + sName)) {
+					sTitleLanguageKey = sTableID + ".column." + sName;
 					return sTitleLanguageKey;
 				}
 
@@ -1073,6 +1156,8 @@ public class TableColumnImpl
 					sTitleLanguageKey = sKeyPrefix;
 					return sTitleLanguageKey;
 				}
+				
+				sTitleLanguageKey = "!" + sName + "!";
 			}
 			return sTitleLanguageKey;
 		} finally {
@@ -1154,6 +1239,7 @@ public class TableColumnImpl
 	}
 
 	public void setLastSortValueChange(long lastSortValueChange) {
+		//System.out.println(getName() + "] setlastSortValueChange via " + Debug.getCompressedStackTrace());
 		lLastSortValueChange = lastSortValueChange;
 	}
 
@@ -1205,7 +1291,7 @@ public class TableColumnImpl
 		}
 	}
 
-	private String getListCountString(List l) {
+	private String getListCountString(List<?> l) {
 		if (l == null) {
 			return "-0";
 		}
@@ -1286,6 +1372,13 @@ public class TableColumnImpl
 		return bSortAscending;
 	}
 
+	public void setDefaultSortAscending( boolean bAscending ){
+		bDefaultSortAscending = bAscending;
+		if ( isFirstLoad()){
+			bSortAscending = bAscending;
+		}
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableColumn#getMinWidth()
 	public int getMinWidth() {
 		if (iMinWidth < 0) {
@@ -1350,7 +1443,14 @@ public class TableColumnImpl
 
 		bVisible = visible;
 		if (bVisible && iPosition == POSITION_INVISIBLE) {
-			iPosition = POSITION_LAST;
+			TableColumnCore[] allColumns = TableColumnManager.getInstance().getAllTableColumnCoreAsArray(
+					null, sTableID);
+			iPosition = 0;
+			for (TableColumnCore tableColumnCore : allColumns) {
+				if (tableColumnCore.getPosition() > iPosition) {
+					iPosition = tableColumnCore.getPosition() + 1;
+				}
+			}
 		}
 		invalidateCells();
 	}
@@ -1417,9 +1517,10 @@ public class TableColumnImpl
 			iPreferredWidth = width;
 		}
 
-		if (bColumnAdded && bVisible) {
-			triggerColumnSizeChange();
-		}
+		// Commented out because size hasn't changed!
+		//if (bColumnAdded && bVisible) {
+		//	triggerColumnSizeChange();
+		//}
 	}
 	
 	public void setAutoTooltip(boolean auto_tooltip) {
@@ -1442,17 +1543,107 @@ public class TableColumnImpl
 		return false;
 	}
 
-	public Class getForDataSourceType() {
-		return forPluginDataSourceType;
-	}
-
-	public void setForDataSourceType(Class forDataSourceType) {
-		this.forPluginDataSourceType = forDataSourceType;
+	public Class[] getForDataSourceTypes() {
+		if (forPluginDataSourceTypes.isEmpty()) {
+			// Guess forPluginDataSourceType based on tableID
+			Class<?> forPluginDataSourceType = null;
+			if (TableManager.TABLE_MYTORRENTS_ALL_BIG.equals(sTableID)
+					|| TableManager.TABLE_MYTORRENTS_UNOPENED.equals(sTableID)
+					|| TableManager.TABLE_MYTORRENTS_UNOPENED_BIG.equals(sTableID)) {
+				forPluginDataSourceType = Download.class;
+			} else if (TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG.equals(sTableID)
+					|| TableManager.TABLE_MYTORRENTS_INCOMPLETE.equals(sTableID)) {
+				forPluginDataSourceType = DownloadTypeIncomplete.class;
+			} else if (TableManager.TABLE_MYTORRENTS_COMPLETE.equals(sTableID)
+					|| TableManager.TABLE_MYTORRENTS_COMPLETE_BIG.equals(sTableID)) {
+				forPluginDataSourceType = DownloadTypeComplete.class;
+			} else if (TableManager.TABLE_TORRENT_PEERS.equals(sTableID)) {
+				forPluginDataSourceType = Peer.class;
+			} else if (TableManager.TABLE_TORRENT_FILES.equals(sTableID)) {
+				forPluginDataSourceType = DiskManagerFileInfo.class;
+			} else if (TableManager.TABLE_MYTRACKER.equals(sTableID)) {
+				forPluginDataSourceType = TrackerTorrent.class;
+			} else if (TableManager.TABLE_MYSHARES.equals(sTableID)) {
+				forPluginDataSourceType = ShareResource.class;
+			}
+			if (forPluginDataSourceType != null) {
+				forPluginDataSourceTypes.add(forPluginDataSourceType);
+			}
+		}
+		return forPluginDataSourceTypes.toArray(new Class[0]);
 	}
 
 	public void reset() {
 		if (iDefaultWidth != 0) {
 			setWidth(iDefaultWidth);
 		}
+		if ( iDefaultAlignment != -1 ){
+			setAlignment( iDefaultAlignment );
+		}
+	}
+
+	public void addDataSourceType(Class<?> cla) {
+		if (cla == null) {
+			return;
+		}
+		if (cla == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.class) {
+			cla = DiskManagerFileInfo.class;
+		}
+		forPluginDataSourceTypes.add(cla);
+	}
+	
+	public void addDataSourceTypes(Class[] datasourceTypes) {
+		if (datasourceTypes == null) {
+			return;
+		}
+		for (Class cla : datasourceTypes) {
+			addDataSourceType(cla);
+		}
+	}
+
+	public boolean handlesDataSourceType(Class<?> cla) {
+		Class[] forPluginDataSourceTypes = getForDataSourceTypes();
+		for (Class<?> forClass : forPluginDataSourceTypes) {
+			if (forClass.isAssignableFrom(cla)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public Class getForDataSourceType() {
+		Class[] forPluginDataSourceTypes = getForDataSourceTypes();
+		return forPluginDataSourceTypes.length > 0 ? forPluginDataSourceTypes[0] : null;
+	}
+	
+	public void setIconReference(String iconID, boolean showOnlyIcon) {
+		this.iconID = iconID;
+		this.showOnlyImage = showOnlyIcon;
+	}
+	
+	public String getIconReference() {
+		return iconID;
+	}
+	
+	public void setMinimumRequiredUserMode(int mode) {
+
+		TableColumnInfo info = TableColumnManager.getInstance().getColumnInfo( this );
+		
+		if ( info != null ){
+			byte	prof;
+			if ( mode == Parameter.MODE_BEGINNER ){
+				prof = TableColumnInfo.PROFICIENCY_BEGINNER;
+			}else if ( mode == Parameter.MODE_INTERMEDIATE ){
+				prof = TableColumnInfo.PROFICIENCY_INTERMEDIATE;
+			}else{
+				prof = TableColumnInfo.PROFICIENCY_ADVANCED;
+			}
+			info.setProficiency( prof );
+		}
+	}
+
+
+	public boolean showOnlyImage() {
+		return showOnlyImage;
 	}
 }
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableColumnManager.java b/com/aelitis/azureus/ui/common/table/impl/TableColumnManager.java
new file mode 100644
index 0000000..7ce2eba
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/table/impl/TableColumnManager.java
@@ -0,0 +1,768 @@
+/*
+ * File    : TableColumnManager.java
+*
+ * 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.common.table.impl;
+
+import java.util.*;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableColumnCoreCreationListener;
+import com.aelitis.azureus.util.MapUtils;
+
+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.*;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnInfoImpl;
+
+
+/** Holds a list of column definitions (TableColumnCore) for 
+ * all the tables in Azureus.
+ *
+ * Column definitions are added via 
+ * PluginInterface.addColumn(TableColumn)
+ * See Use javadoc section for more uses.
+ *
+ * @author Oliver (Original Code)
+ * @author TuxPaper (Modifications to make generic & comments)
+ */
+public class TableColumnManager {
+
+  private static final String CONFIG_FILE = "tables.config";
+	private static TableColumnManager instance;
+  private static AEMonitor 			class_mon 	= new AEMonitor( "TableColumnManager" );
+
+  /* Holds all the TableColumnCore objects.
+   * key   = TABLE_* type (see TableColumnCore)
+   * value = Map:
+   *           key = column name
+   *           value = TableColumnCore object
+   */
+  private Map<String,Map>	items;
+  private AEMonitor 		items_mon 	= new AEMonitor( "TableColumnManager:items" );
+  
+  /**
+   * Holds the order in which the columns are auto-hidden
+   * 
+   * key   = TABLE_* type
+   * value = List of TableColumn, indexed in the order they should be removed
+   */ 
+  private Map autoHideOrder = new LightHashMap();
+
+  /**
+   * key = table; value = map of columns
+   * 
+   * Do not access directly.  Use {@link #getTableConfigMap(String)}
+   * or {@link #saveTableConfigs()}
+   */
+	private Map mapTablesConfig;
+	private long lastTableConfigAccess;
+	private static Comparator<TableColumn> orderComparator;
+	
+	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[]>();
+
+	private static final Map<String, String> mapResetTable_Version;
+	private static final boolean RERESET = false;
+	
+	static {
+		orderComparator = new Comparator<TableColumn>() {
+			public int compare(TableColumn col0, TableColumn col1) {
+				if (col0 == null || col1 == null) {
+					return 0;
+				}
+
+				int iPositionA = col0.getPosition();
+				if (iPositionA < 0)
+					iPositionA = 0xFFFF + iPositionA;
+				int iPositionB = col1.getPosition();
+				if (iPositionB < 0)
+					iPositionB = 0xFFFF + iPositionB;
+
+				int i = iPositionA - iPositionB;
+				if (i != 0 || iPositionA == (0xFFFF + TableColumn.POSITION_LAST)) {
+					return i;
+				}
+				
+				String name0 = col0.getName();
+				String name1 = col1.getName();
+
+				String[] names = getInstance().getDefaultColumnNames(col0.getTableID());
+				if (names != null) {
+					for (String name : names) {
+						if (name.equals(name0)) {
+							return -1;
+						}
+						if (name.equals(name1)) {
+							return 1;
+						}
+					}
+				}
+				return name0.compareTo(name1);
+			}
+		};
+		
+		mapResetTable_Version = new HashMap<String, String>();
+		mapResetTable_Version.put("DeviceLibrary", "4.4.0.7");
+		mapResetTable_Version.put("TranscodeQueue", "4.4.0.7");
+		mapResetTable_Version.put(TableManager.TABLE_MYTORRENTS_COMPLETE_BIG, "4.4.0.7");
+		mapResetTable_Version.put(TableManager.TABLE_MYTORRENTS_ALL_BIG, "4.4.0.7");
+		mapResetTable_Version.put(TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG, "4.4.0.7");
+		mapResetTable_Version.put(TableManager.TABLE_MYTORRENTS_UNOPENED_BIG, "4.6.0.1");
+		mapResetTable_Version.put(TableManager.TABLE_MYTORRENTS_UNOPENED, "4.6.0.1");
+	}
+
+  
+  private TableColumnManager() {
+   items = new HashMap<String,Map>();
+  }
+  
+  /** Retrieve the static TableColumnManager instance
+   * @return the static TableColumnManager instance
+   */
+  public static TableColumnManager getInstance() {
+  	try{
+  		class_mon.enter();
+  	
+  		if(instance == null)
+  			instance = new TableColumnManager();
+  		return instance;
+  	}finally{
+  		
+  		class_mon.exit();
+  	}
+  }
+  
+  /** Adds a column definition to the list
+   * @param item The column definition object
+   */
+  public void addColumns(TableColumnCore[] itemsToAdd) {
+		try {
+			items_mon.enter();
+			for (int i = 0; i < itemsToAdd.length; i++) {
+				TableColumnCore item = itemsToAdd[i];
+				if (item == null || item.isRemoved()){
+					continue;
+				}
+				String name = item.getName();
+				String sTableID = item.getTableID();
+				Map mTypes = (Map) items.get(sTableID);
+				if (mTypes == null) {
+					// LinkedHashMap to preserve order
+					mTypes = new LinkedHashMap();
+					items.put(sTableID, mTypes);
+				}
+				if (!mTypes.containsKey(name)) {
+					mTypes.put(name, item);
+					Map mapColumnConfig = getTableConfigMap(sTableID);
+					item.loadSettings(mapColumnConfig);
+				}
+			}
+			for (int i = 0; i < itemsToAdd.length; i++) {
+				TableColumnCore item = itemsToAdd[i];
+				
+				if (item != null && !item.isRemoved() && !item.getColumnAdded()) {
+					item.setColumnAdded();
+				}
+			}
+		} catch (Exception e) {
+			System.out.println("Error while adding Table Column Extension");
+			Debug.printStackTrace(e);
+		} finally {
+			items_mon.exit();
+		}
+	}
+
+  /** Adds a column definition to the list
+   * @param item The column definition object
+   */
+  public void removeColumns(TableColumnCore[] itemsToRemove) {
+		try {
+			items_mon.enter();
+			for (int i = 0; i < itemsToRemove.length; i++) {
+				TableColumnCore item = itemsToRemove[i];
+				String name = item.getName();
+				String sTableID = item.getTableID();
+				Map mTypes = (Map) items.get(sTableID);
+				if (mTypes != null) {
+					if ( mTypes.remove(name) != null ){
+					}
+				}
+			}
+		} catch (Exception e) {
+			System.out.println("Error while adding Table Column Extension");
+			Debug.printStackTrace(e);
+		} finally {
+			items_mon.exit();
+		}
+	}
+  
+  /** Retrieves TableColumnCore objects of a particular type.
+   * @param sTableID TABLE_* constant.  See {@link TableColumn} for list 
+   * of constants
+   * @param forDataSourceType 
+   *
+   * @return Map of column definition objects matching the supplied criteria.
+   *         key = name
+   *         value = TableColumnCore object
+   */
+  public Map<String, TableColumnCore> getTableColumnsAsMap(
+			Class forDataSourceType, String sTableID) {
+    //System.out.println("getTableColumnsAsMap(" + sTableID + ")");
+    try{
+    	items_mon.enter();
+      Map<String, TableColumnCore> mReturn = new LinkedHashMap();
+    	Map<String, TableColumnCore> mTypes = getAllTableColumnCore(
+					forDataSourceType, sTableID);
+      if (mTypes != null) {
+        mReturn.putAll(mTypes);
+      }
+      //System.out.println("getTableColumnsAsMap(" + sTableID + ") returnsize: " + mReturn.size());
+      return mReturn;
+    }finally{
+    	
+    	items_mon.exit();
+    }
+  }
+  
+  public int getTableColumnCount(String sTableID) {
+    Map mTypes = (Map)items.get(sTableID);
+    if (mTypes == null) {
+    	return 0;
+    }
+    return mTypes.size();
+  }
+
+  
+  public TableColumnCore[] getAllTableColumnCoreAsArray(
+			Class forDataSourceType, String tableID)
+	{
+  	Map mTypes = getAllTableColumnCore(forDataSourceType, tableID);
+		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(
+			Class forDataSourceType, String tableID)
+	{
+		String[] dstColumnIDs = new String[0];
+		if (forDataSourceType != null) {
+  		List listDST = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
+  		if (listDST != null) {
+  			dstColumnIDs = (String[]) listDST.toArray(new String[0]);
+  		}
+  		if (forDataSourceType.equals(DownloadTypeComplete.class)
+  				|| forDataSourceType.equals(DownloadTypeIncomplete.class)) {
+  			listDST = (List) mapDataSourceTypeToColumnIDs.get(Download.class);
+  			if (listDST != null && listDST.size() > 0) {
+  				String[] ids1 = (String[]) listDST.toArray(new String[0]);
+  				String[] ids2 = dstColumnIDs;
+  				dstColumnIDs = new String[ids2.length + ids1.length];
+  				System.arraycopy(ids2, 0, dstColumnIDs, 0, ids2.length);
+  				System.arraycopy(ids1, 0, dstColumnIDs, ids2.length, ids1.length);
+  			}
+  		} else if (forDataSourceType.equals(Download.class)) {
+  			listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeComplete.class);
+  			if (listDST != null && listDST.size() > 0) {
+  				String[] ids = (String[]) listDST.toArray(new String[listDST.size()]);
+  				dstColumnIDs = appendLists(ids, dstColumnIDs);
+  			}
+  			listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeIncomplete.class);
+  			if (listDST != null && listDST.size() > 0) {
+  				String[] ids = (String[]) listDST.toArray(new String[listDST.size()]);
+  				dstColumnIDs = appendLists(ids, dstColumnIDs);
+  			}
+  		}
+		}
+
+		try {
+			items_mon.enter();
+
+			Map mTypes = (Map) items.get(tableID);
+			if (mTypes == null) {
+        mTypes = new LinkedHashMap();
+				items.put(tableID, mTypes);
+			}
+
+			for (int i = 0; i < dstColumnIDs.length; i++) {
+				String columnID = dstColumnIDs[i];
+				if (!mTypes.containsKey(columnID)) {
+					try {
+						TableColumnCreationListener l = mapColumnIDsToListener.get(forDataSourceType
+								+ "." + columnID);
+						TableColumnCore tc = null;
+						if (l instanceof TableColumnCoreCreationListener) {
+							tc = ((TableColumnCoreCreationListener) l).createTableColumnCore(
+									tableID, columnID);
+						}
+						if (tc == null) {
+							tc = new TableColumnImpl(tableID, columnID);
+						}
+
+						l.tableColumnCreated(tc);
+
+						addColumns(new TableColumnCore[] { tc });
+
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+				}
+			}
+
+			return mTypes;
+		} finally {
+			items_mon.exit();
+		}
+	}
+  */
+
+  /**
+   * Will create columns for tableID if needed
+   */
+  private Map<String, TableColumnCore> getAllTableColumnCore(
+			Class forDataSourceType, String tableID) {
+		Map mTypes = null;
+		try {
+			items_mon.enter();
+
+			mTypes = items.get(tableID);
+			if (mTypes == null) {
+				mTypes = new LinkedHashMap();
+				items.put(tableID, mTypes);
+			}
+
+			if (forDataSourceType != null) {
+				Map<Class<?>, List> mapDST = new HashMap<Class<?>, List>();
+				List listDST = mapDataSourceTypeToColumnIDs.get(forDataSourceType);
+				if (listDST != null) {
+					mapDST.put(forDataSourceType, listDST);
+				}
+				if (forDataSourceType.equals(DownloadTypeComplete.class)
+						|| forDataSourceType.equals(DownloadTypeIncomplete.class)) {
+					listDST = mapDataSourceTypeToColumnIDs.get(Download.class);
+					if (listDST != null && listDST.size() > 0) {
+						mapDST.put(Download.class, listDST);
+					}
+				} else if (Download.class.equals(forDataSourceType)) {
+					listDST = mapDataSourceTypeToColumnIDs.get(DownloadTypeComplete.class);
+					if (listDST != null && listDST.size() > 0) {
+						mapDST.put(DownloadTypeComplete.class, listDST);
+					}
+					listDST = mapDataSourceTypeToColumnIDs.get(DownloadTypeIncomplete.class);
+					if (listDST != null && listDST.size() > 0) {
+						mapDST.put(DownloadTypeIncomplete.class, listDST);
+					}
+				}
+				doAddCreate(mTypes, tableID, mapDST);
+			}
+		} finally {
+			items_mon.exit();
+		}
+
+		return mTypes;
+	}
+
+  /** 
+   * Helper for getAllTableColumnCore
+	 * @param types
+	 * @param listDST
+	 *
+	 * @since 4.0.0.5
+	 */
+	private void doAddCreate(Map mTypes, String tableID, Map<Class<?>, List> mapDST) {
+		ArrayList<TableColumnCore> listAdded = new ArrayList<TableColumnCore>();
+		for (Class forDataSourceType : mapDST.keySet()) {
+			List listDST = mapDST.get(forDataSourceType);
+
+			for (Iterator iter = listDST.iterator(); iter.hasNext();) {
+				String columnID = (String) iter.next();
+				if (!mTypes.containsKey(columnID)) {
+					try {
+						TableColumnCreationListener l = mapColumnIDsToListener.get(forDataSourceType
+								+ "." + columnID);
+						TableColumnCore tc = null;
+						if (l instanceof TableColumnCoreCreationListener) {
+							tc = ((TableColumnCoreCreationListener) l).createTableColumnCore(
+									forDataSourceType, tableID, columnID);
+						}
+						if (tc == null) {
+							tc = new TableColumnImpl(tableID, columnID);
+							tc.addDataSourceType(forDataSourceType);
+						}
+
+						if (l != null) {
+							l.tableColumnCreated(tc);
+						}
+
+						listAdded.add(tc);
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+				}
+			}
+		}
+		addColumns(listAdded.toArray(new TableColumnCore[0]));
+	}
+
+		public String[]
+  	getTableIDs()
+  	{
+		try {
+			items_mon.enter();
+
+			Set<String> ids = items.keySet();
+			
+			return( ids.toArray( new String[ids.size()]));
+			
+		} finally {
+			items_mon.exit();
+		}
+	}
+  	
+  public String[] appendLists(String[] list1, String[] list2) {
+  	int size = list1.length + list2.length;
+  	String[] list = new String[size];
+  	System.arraycopy(list1, 0, list, 0, list1.length);
+  	System.arraycopy(list2, 0, list, list1.length, list2.length);
+  	return list;
+  }
+  
+  public TableColumnCore getTableColumnCore(String sTableID,
+                                            String sColumnName) {
+    Map mTypes = (Map)items.get(sTableID);
+    if (mTypes == null)
+      return null;
+    return (TableColumnCore)mTypes.get(sColumnName);
+  }
+  
+  public void ensureIntegrety(String sTableID) {
+    Map mTypes = (Map)items.get(sTableID);
+    if (mTypes == null)
+      return;
+
+    TableColumnCore[] tableColumns = 
+      (TableColumnCore[])mTypes.values().toArray(new TableColumnCore[mTypes.values().size()]);
+
+    Arrays.sort(tableColumns, getTableColumnOrderComparator());
+
+    int iPos = 0;
+    for (int i = 0; i < tableColumns.length; i++) {
+      int iCurPos = tableColumns[i].getPosition();
+      if (iCurPos == TableColumnCore.POSITION_INVISIBLE) {
+      	tableColumns[i].setVisible(false);
+      } else {
+        tableColumns[i].setPositionNoShift(iPos++);
+      }
+    }
+  }
+  
+  public String getDefaultSortColumnName(String tableID) {
+  	Map mapTableConfig = getTableConfigMap(tableID);
+  	Object object = mapTableConfig.get("SortColumn");
+  	if( object instanceof byte[])
+  		object =  new String((byte[])object);
+  	
+  	if (object instanceof String) {
+			return (String) object;
+		}
+
+		String s = COConfigurationManager.getStringParameter(tableID + ".sortColumn");
+		if (s != null) {
+			COConfigurationManager.removeParameter(tableID + ".sortColumn");
+			COConfigurationManager.removeParameter(tableID + ".sortAsc");
+		}
+		return s;
+  }
+  
+  public void setDefaultSortColumnName(String tableID, String columnName) {
+  	Map mapTableConfig = getTableConfigMap(tableID);
+  	mapTableConfig.put("SortColumn", columnName);
+  	saveTableConfigs();
+  }
+
+  private void saveTableConfigs() {
+		if (mapTablesConfig != null) {
+			FileUtil.writeResilientConfigFile(CONFIG_FILE, mapTablesConfig);
+		}
+	}
+
+	/** Saves all the user configurable Table Column settings at once, complete
+   * with a COConfigurationManager.save().
+   *
+   * @param sTableID Table to save settings for
+   */
+  public void saveTableColumns(Class forDataSourceType, String sTableID) {
+  	try {
+  		Map mapTableConfig = getTableConfigMap(sTableID);
+      TableColumnCore[] tcs = getAllTableColumnCoreAsArray(forDataSourceType,
+					sTableID);
+      for (int i = 0; i < tcs.length; i++) {
+        if (tcs[i] != null)
+          tcs[i].saveSettings(mapTableConfig);
+      }
+      saveTableConfigs();
+  	} catch (Exception e) {
+  		Debug.out(e);
+  	}
+  }
+  
+  public boolean loadTableColumnSettings(Class forDataSourceType, String sTableID) {
+  	try {
+  		Map mapTableConfig = getTableConfigMap(sTableID);
+  		int size = mapTableConfig.size();
+  		if (size == 0) {
+  			return false;
+  		}
+  		boolean hasColumnInfo = false;
+  		for (Object key : mapTableConfig.keySet()) {
+				if (key instanceof String) {
+					if (((String) key).startsWith("Column.")) {
+						hasColumnInfo = true;
+						break;
+					}
+				}
+			}
+  		if (!hasColumnInfo) {
+  			return false;
+  		}
+      TableColumnCore[] tcs = getAllTableColumnCoreAsArray(forDataSourceType,
+					sTableID);
+      for (int i = 0; i < tcs.length; i++) {
+        if (tcs[i] != null)
+          tcs[i].loadSettings(mapTableConfig);
+      }
+  	} catch (Exception e) {
+  		Debug.out(e);
+  	}
+  	return true;
+  }
+  
+  public Map getTableConfigMap(String sTableID) {
+		synchronized (this) {
+			String key = "Table." + sTableID;
+
+			lastTableConfigAccess = SystemTime.getMonotonousTime();
+			
+			if (mapTablesConfig == null) {
+				mapTablesConfig = FileUtil.readResilientConfigFile(CONFIG_FILE);
+				
+				if (RERESET) {
+					for (Object map : mapTablesConfig.values()) {
+						((Map) map).remove("last.reset");
+					}
+				}
+
+					// Dispose of tableconfigs after XXs.. saves up to 50k
+				
+				SimpleTimer.addEvent(
+						"DisposeTableConfigMap",
+						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(
+											"DisposeTableConfigMap",
+											SystemTime.getOffsetTime(30000), 
+											this );
+									}
+								}
+							}
+						});
+			}
+
+			Map mapTableConfig = (Map) mapTablesConfig.get(key);
+			if (mapTableConfig == null) {
+				mapTableConfig = new HashMap();
+				mapTablesConfig.put("Table." + sTableID, mapTableConfig);
+			} else {
+				String resetIfLastResetBelowVersion = mapResetTable_Version.get(sTableID);
+				if (resetIfLastResetBelowVersion != null) {
+					String lastReset = MapUtils.getMapString(mapTableConfig,
+							"last.reset", "0.0.0.0");
+					if (Constants.compareVersions(lastReset, resetIfLastResetBelowVersion) < 0) {
+						mapTableConfig.clear();
+						mapTableConfig.put("last.reset", Constants.getBaseVersion());
+						saveTableConfigs();
+						mapResetTable_Version.remove(sTableID);
+					}
+				}
+			}
+
+			return mapTableConfig;
+		}
+	}
+  
+  public void setAutoHideOrder(String sTableID, String[] autoHideOrderColumnIDs) {
+  	ArrayList autoHideOrderList = new ArrayList(autoHideOrderColumnIDs.length);
+  	for (int i = 0; i < autoHideOrderColumnIDs.length; i++) {
+			String sColumnID = autoHideOrderColumnIDs[i];
+			TableColumnCore column = getTableColumnCore(sTableID, sColumnID);
+			if (column != null) {
+				autoHideOrderList.add(column);
+			}
+		}
+  	
+  	autoHideOrder.put(sTableID, autoHideOrderList);
+  }
+  
+  public List getAutoHideOrder(String sTableID) {
+		List list = (List) autoHideOrder.get(sTableID);
+		if (list == null) {
+			return Collections.EMPTY_LIST;
+		}
+		return list;
+	}
+
+	/**
+	 * @param writer
+	 */
+	public void generateDiagnostics(IndentWriter writer) {
+    try{
+     	items_mon.enter();
+     	
+     	writer.println("TableColumns");
+
+     	for (Iterator iter = items.keySet().iterator(); iter.hasNext();) {
+     		String sTableID = (String)iter.next();
+        Map mTypes = (Map)items.get(sTableID);
+
+        writer.indent();
+     		writer.println(sTableID + ": " + mTypes.size() + " columns:");
+     		
+     		writer.indent();
+       	for (Iterator iter2 = mTypes.values().iterator(); iter2.hasNext();) {
+       		TableColumnCore tc = (TableColumnCore)iter2.next();
+       		tc.generateDiagnostics(writer);
+       	}
+        writer.exdent();
+
+        writer.exdent();
+			}
+    } catch (Exception e) {
+    	e.printStackTrace();
+    } finally {
+    	items_mon.exit();
+    }
+	}
+	
+	public static Comparator<TableColumn> getTableColumnOrderComparator()
+	{
+		return orderComparator;
+	}
+
+	/**
+	 * @param forDataSourceType
+	 * @param columnID
+	 * @param listener
+	 *
+	 * @since 3.1.1.1
+	 */
+	public void registerColumn(Class forDataSourceType, String columnID,
+			TableColumnCreationListener listener) {
+		if (listener != null) {
+			mapColumnIDsToListener.put(forDataSourceType + "." + columnID, listener);
+		}
+		try {
+			items_mon.enter();
+
+  		List list = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
+  		if (list == null) {
+  			list = new ArrayList(1);
+  			mapDataSourceTypeToColumnIDs.put(forDataSourceType, list);
+  		}
+  		if (!list.contains(columnID)) {
+  			list.add(columnID);
+  		}
+		} finally {
+			items_mon.exit();
+		}
+	}
+	
+	public void unregisterColumn(Class forDataSourceType, String columnID,
+			TableColumnCreationListener listener) {
+		try {
+			items_mon.enter();
+
+			mapColumnIDsToListener.remove(forDataSourceType + "." + columnID);
+			List list = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
+			if (list != null) {
+				list.remove(columnID);
+			}
+		} finally {
+			items_mon.exit();
+		}
+	}
+
+	public TableColumnInfo getColumnInfo(Class forDataSourceType, String forTableID,
+			String columnID) {
+
+		TableColumnCore column = getTableColumnCore(forTableID, columnID);
+		
+		return column == null ? null : getColumnInfo(column);
+	}
+	
+	public TableColumnInfo getColumnInfo( TableColumnCore column ){
+		
+		TableColumnInfoImpl columnInfo = new TableColumnInfoImpl(column);
+		List<TableColumnExtraInfoListener> listeners = column.getColumnExtraInfoListeners();
+		for (TableColumnExtraInfoListener l : listeners) {
+			l.fillTableColumnInfo(columnInfo);
+		}
+		if (columnInfo.getCategories() == null && !(column instanceof CoreTableColumn)) {
+			columnInfo.addCategories(new String[] { "plugin" });
+			columnInfo.setProficiency( TableColumnInfo.PROFICIENCY_BEGINNER );
+		}
+
+		return columnInfo;
+	}
+}
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableRowCoreSorter.java b/com/aelitis/azureus/ui/common/table/impl/TableRowCoreSorter.java
new file mode 100644
index 0000000..7f6609a
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/table/impl/TableRowCoreSorter.java
@@ -0,0 +1,34 @@
+package com.aelitis.azureus.ui.common.table.impl;
+
+import java.util.Comparator;
+
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+
+public class TableRowCoreSorter
+	implements Comparator<TableRowCore>
+{
+	@SuppressWarnings("null")
+	public int compare(TableRowCore o1, TableRowCore o2) {
+		TableRowCore parent1 = o1.getParentRowCore();
+		TableRowCore parent2 = o2.getParentRowCore();
+		boolean hasParent1 = parent1 != null;
+		boolean hasParent2 = parent2 != null;
+
+		if (parent1 == parent2 || (!hasParent1 && !hasParent2)) {
+			return o1.getIndex() - o2.getIndex();
+		}
+		if (hasParent1 && hasParent2) {
+			return parent1.getIndex() - parent2.getIndex();
+		}
+		if (hasParent1) {
+			if (parent1 == o2) {
+				return 1;
+			}
+			return parent1.getIndex() - o2.getIndex();
+		}
+		if (o1 == parent2) {
+			return 0;
+		}
+		return o1.getIndex() - parent2.getIndex();
+	}
+}
diff --git a/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java b/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
index 39e8e23..07f56d5 100644
--- a/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
+++ b/com/aelitis/azureus/ui/common/table/impl/TableViewImpl.java
@@ -3,20 +3,72 @@
  */
 package com.aelitis.azureus.ui.common.table.impl;
 
-import java.util.Iterator;
+import java.util.*;
 
-import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.config.impl.ConfigurationManager;
+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.plugins.ui.tables.TableRow;
+import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
 
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 
 /**
  * @author TuxPaper
  * @created Feb 6, 2007
  */
 public abstract class TableViewImpl<DATASOURCETYPE>
-	implements TableView<DATASOURCETYPE>
+	implements TableView<DATASOURCETYPE>, TableStructureModificationListener<DATASOURCETYPE>
 {
+	private final static LogIDs LOGID = LogIDs.GUI;
+
+	private static final boolean DEBUG_SORTER = false;
+
+	/** Helpful output when trying to debug add/removal of rows */
+	public final static boolean DEBUGADDREMOVE = System.getProperty(
+			"debug.swt.table.addremove", "0").equals("1");
+
+	public static final boolean DEBUG_SELECTION = false;
+
+	private static final String CFG_SORTDIRECTION = "config.style.table.defaultSortOrder";
+
+	// Shorter name for ConfigManager, easier to read code
+	protected static final ConfigurationManager configMan = ConfigurationManager.getInstance();
+
+	/** 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 
+	 * "Table.<i>TableID</i>"
+	 */
+	protected String tableID;
+
+	/** Prefix for retrieving text from the properties file (MessageText)
+	 * Typically <i>TableID</i> + "View"
+	 */
+	protected String propertiesPrefix;
+	
+	// What type of data is stored in this table
+	private final Class<?> classPluginDataSourceType;
+
+
+	private boolean bReallyAddingDataSources = false;
+
+	private AEMonitor sortColumn_mon = new AEMonitor("TableView:sC");
+
+	/** Sorting functions */
+	private TableColumnCore sortColumn;
+
+	/** TimeStamp of when last sorted all the rows was */
+	private long lLastSortedOn;
+
+	private AEMonitor listeners_mon = new AEMonitor("tablelisteners");
+
+	private ArrayList<TableRowRefreshListener> rowRefreshListeners;
+
 	// List of DataSourceChangedListener
 	private CopyOnWriteList<TableDataSourceChangedListener> listenersDataSourceChanged = new CopyOnWriteList<TableDataSourceChangedListener>();
 
@@ -26,10 +78,124 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 
 	private CopyOnWriteList<TableRefreshListener> listenersRefresh = new CopyOnWriteList<TableRefreshListener>();
 
-	private CopyOnWriteList<TableCountChangeListener> listenersCountChange = new CopyOnWriteList<TableCountChangeListener>(1);
+	private CopyOnWriteList<TableCountChangeListener> listenersCountChange = new CopyOnWriteList<TableCountChangeListener>(
+			1);
 
 	private Object parentDataSource;
 
+	private Object rows_sync = new Object();
+
+	/** Filtered rows in the table */
+	private List<TableRowCore> sortedRows;
+
+	/** Link DataSource to their row in the table.
+	 * key = DataSource
+	 * value = TableRowSWT
+	 */
+	private IdentityHashMap<DATASOURCETYPE, TableRowCore> mapDataSourceToRow;
+
+	private IdentityHashMap<DATASOURCETYPE, String> listUnfilteredDataSources;
+
+	// **** NOTE THE USE OF IdentityHashMap - we have to do this to behave reliably in the face of
+	// some DATASOURCETYPEs (DownloadManagerImpl to mention no names) redefining equals/hashCode
+	// if you quickly remove+add a download with the same hash this can cause borkage here unless
+	// we use identity maps
+	
+	/** Queue added datasources and add them on refresh */
+	private IdentityHashMap<DATASOURCETYPE, String> dataSourcesToAdd = new IdentityHashMap<DATASOURCETYPE, String>(4);
+
+	/** Queue removed datasources and add them on refresh */
+	private IdentityHashMap<DATASOURCETYPE, String> dataSourcesToRemove = new IdentityHashMap<DATASOURCETYPE, String>(4);
+
+	// class used to keep filter stuff in a nice readable parcel
+	public static class filter<DATASOURCETYPE>
+	{
+
+		public TimerEvent eventUpdate;
+
+		public String text = "";
+
+		public long lastFilterTime;
+
+		public boolean regex = false;
+
+		public TableViewFilterCheck<DATASOURCETYPE> checker;
+
+		public String nextText = "";
+	};
+
+	protected filter<DATASOURCETYPE> filter;
+
+	private DataSourceCallBackUtil.addDataSourceCallback processDataSourceQueueCallback = new DataSourceCallBackUtil.addDataSourceCallback() {
+		public void process() {
+			processDataSourceQueue();
+		}
+
+		public void debug(String str) {
+			TableViewImpl.this.debug(str);
+		}
+	};
+
+	
+	/** Basic (pre-defined) Column Definitions */
+	private TableColumnCore[] basicItems;
+
+	/** All Column Definitions.  The array is not necessarily in column order */
+	private TableColumnCore[] tableColumns;
+
+	/** We need to remember the order of the columns at the time we added them
+	 * in case the user drags the columns around.
+	 */
+	private TableColumnCore[] columnsOrdered;
+
+	/**
+	 * Up to date list of selected rows, so we can access rows without being on SWT Thread.
+	 * Guaranteed to have no nulls
+	 */
+	private List<TableRowCore> selectedRows = new ArrayList<TableRowCore>(1);
+
+	private List<Object> listSelectedCoreDataSources;
+
+	private boolean headerVisible = true;
+
+	private boolean menuEnabled = true;
+
+	private boolean provideIndexesOnRemove = false;
+
+
+
+	public TableViewImpl(Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, TableColumnCore[] _basicItems) {
+		classPluginDataSourceType = pluginDataSourceType;
+		propertiesPrefix = _sPropertiesPrefix;
+		tableID = _sTableID;
+		basicItems = _basicItems;
+		mapDataSourceToRow = new IdentityHashMap<DATASOURCETYPE, TableRowCore>();
+		sortedRows = new ArrayList<TableRowCore>();
+		listUnfilteredDataSources = new IdentityHashMap<DATASOURCETYPE,String>();
+		initializeColumnDefs();
+	}
+
+	private void initializeColumnDefs() {
+		// XXX Adding Columns only has to be done once per TableID.  
+		// Doing it more than once won't harm anything, but it's a waste.
+		TableColumnManager tcManager = TableColumnManager.getInstance();
+
+		if (basicItems != null) {
+			if (tcManager.getTableColumnCount(tableID) != basicItems.length) {
+				tcManager.addColumns(basicItems);
+			}
+			basicItems = null;
+		}
+
+		tableColumns = tcManager.getAllTableColumnCoreAsArray(getDataSourceType(),
+				tableID);
+
+		// fixup order
+		tcManager.ensureIntegrety(tableID);
+	}
+
+
 	public void addSelectionListener(TableSelectionListener listener,
 			boolean bFireSelection) {
 		listenersSelection.add(listener);
@@ -65,10 +231,15 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 		}
 	}
 
+	public Object getParentDataSource() {
+		return parentDataSource;
+	}
+
 	/**
 	 * @param selectedRows
 	 */
-	protected void triggerDefaultSelectedListeners(TableRowCore[] selectedRows, int keyMask) {
+	public void triggerDefaultSelectedListeners(TableRowCore[] selectedRows,
+			int keyMask) {
 		for (Iterator iter = listenersSelection.iterator(); iter.hasNext();) {
 			TableSelectionListener l = (TableSelectionListener) iter.next();
 			l.defaultSelected(selectedRows, keyMask);
@@ -101,7 +272,7 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 		}
 	}
 
-	protected void triggerSelectionListeners(TableRowCore[] rows) {
+	public void triggerSelectionListeners(TableRowCore[] rows) {
 		if (rows == null || rows.length == 0) {
 			return;
 		}
@@ -186,11 +357,20 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 		listenersCountChange.remove(listener);
 	}
 
-	protected void triggerListenerRowAdded(TableRowCore row) {
-		for (Iterator iter = listenersCountChange.iterator(); iter.hasNext();) {
-			TableCountChangeListener l = (TableCountChangeListener) iter.next();
-			l.rowAdded(row);
+	public void triggerListenerRowAdded(final TableRowCore[] rows) {
+		if (listenersCountChange.size() == 0) {
+			return;
 		}
+		getOffUIThread(new AERunnable() {
+			public void runSupport() {
+				for (Iterator iter = listenersCountChange.iterator(); iter.hasNext();) {
+					TableCountChangeListener l = (TableCountChangeListener) iter.next();
+					for (TableRowCore row : rows) {
+						l.rowAdded(row);
+					}
+				}
+			}
+		});
 	}
 
 	protected void triggerListenerRowRemoved(TableRowCore row) {
@@ -199,6 +379,62 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 			l.rowRemoved(row);
 		}
 	}
+	
+	public void addRefreshListener(TableRowRefreshListener listener) {
+		try {
+			listeners_mon.enter();
+
+			if (rowRefreshListeners == null) {
+				rowRefreshListeners = new ArrayList<TableRowRefreshListener>(1);
+			}
+
+			rowRefreshListeners.add(listener);
+
+		} finally {
+			listeners_mon.exit();
+		}
+	}
+
+	public void removeRefreshListener(TableRowRefreshListener listener) {
+		try {
+			listeners_mon.enter();
+
+			if (rowRefreshListeners == null) {
+				return;
+			}
+
+			rowRefreshListeners.remove(listener);
+
+		} finally {
+			listeners_mon.exit();
+		}
+	}
+
+	public void invokeRefreshListeners(TableRowCore row) {
+		Object[] listeners;
+		try {
+			listeners_mon.enter();
+			if (rowRefreshListeners == null) {
+				return;
+			}
+			listeners = rowRefreshListeners.toArray();
+
+		} finally {
+			listeners_mon.exit();
+		}
+
+		for (int i = 0; i < listeners.length; i++) {
+			try {
+				TableRowRefreshListener l = (TableRowRefreshListener) listeners[i];
+
+				l.rowRefresh(row);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
 
 	public void runForAllRows(TableGroupRowRunner runner) {
 		// put to array instead of synchronised iterator, so that runner can remove
@@ -211,4 +447,1479 @@ public abstract class TableViewImpl<DATASOURCETYPE>
 			runner.run(rows[i]);
 		}
 	}
+
+	// see common.tableview
+	public void runForAllRows(TableGroupRowVisibilityRunner runner) {
+		if (isDisposed()) {
+			return;
+		}
+
+		// put to array instead of synchronised iterator, so that runner can remove
+		TableRowCore[] rows = getRows();
+
+		for (int i = 0; i < rows.length; i++) {
+			boolean isRowVisible = isRowVisible(rows[i]);
+			runner.run(rows[i], isRowVisible);
+			
+			int numSubRows = rows[i].getSubItemCount();
+			if (numSubRows > 0) {
+				TableRowCore[] subRows = rows[i].getSubRowsWithNull();
+				for (TableRowCore subRow : subRows) {
+					if (subRow != null) {
+						runner.run(subRow, isRowVisible(subRow));
+					}
+				}
+			}
+		}
+	}
+
+
+	/** For each row source that the user has selected, run the code
+	 * provided by the specified parameter.
+	 *
+	 * @param runner Code to run for each selected row/datasource
+	 */
+	public void runForSelectedRows(TableGroupRowRunner runner) {
+		if (isDisposed()) {
+			return;
+		}
+
+		TableRowCore[] rows;
+		synchronized (selectedRows) {
+			rows = selectedRows.toArray(new TableRowCore[0]);
+		}
+		boolean ran = runner.run(rows);
+		if (!ran) {
+			for (int i = 0; i < rows.length; i++) {
+				TableRowCore row = rows[i];
+				runner.run(row);
+			}
+		}
+	}
+
+	public boolean isUnfilteredDataSourceAdded(Object ds) {
+		return listUnfilteredDataSources.containsKey(ds); 
+	}
+
+	@SuppressWarnings("unchecked")
+	public void refilter() {
+		if (filter == null) {
+			return;
+		}
+		if (filter.eventUpdate != null) {
+			filter.eventUpdate.cancel();
+		}
+		filter.eventUpdate = null;
+
+		synchronized (rows_sync) {
+			DATASOURCETYPE[] unfilteredArray = (DATASOURCETYPE[]) listUnfilteredDataSources.keySet().toArray();
+
+			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 = filter.checker.filterCheck(unfilteredArray[i],
+						filter.text, filter.regex);
+				if (!isOurs) {
+					if (bHave) {
+						listRemoves.add(unfilteredArray[i]);
+					}
+				} else {
+					if (!bHave) {
+						listAdds.add(unfilteredArray[i]);
+					}
+				}
+			}
+			if (listRemoves.size() > 0) {
+				removeDataSources((DATASOURCETYPE[]) listRemoves.toArray());
+			}
+			if (listAdds.size() > 0) {
+				addDataSources((DATASOURCETYPE[]) listAdds.toArray(), true);
+			}
+
+			// add back the ones removeDataSources removed
+			for ( DATASOURCETYPE ds: listRemoves ){
+				listUnfilteredDataSources.put(ds,"");
+			}
+		}
+		processDataSourceQueue();
+	}
+
+	public boolean
+	isFiltered(
+		DATASOURCETYPE	ds )
+	{
+		if ( filter == null ){
+			return( true );
+		}
+		
+		return( filter.checker.filterCheck( ds, filter.text, filter.regex ));
+	}
+
+	protected void debug(String s) {
+		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("table");
+		diag_logger.log(SystemTime.getCurrentTime() + ":" + getTableID() + ": " + s);
+
+		System.out.println(Thread.currentThread().getName() + "] " + SystemTime.getCurrentTime() + ": " + getTableID() + ": "
+				+ s);
+	}
+
+	private void _processDataSourceQueue() {
+		Object[] dataSourcesAdd = null;
+		Object[] dataSourcesRemove = null;
+
+		synchronized (rows_sync) {
+			if (dataSourcesToAdd.size() > 0) {
+				boolean removed_something = false;
+				for ( DATASOURCETYPE ds: dataSourcesToRemove.keySet()){
+					
+					if ( dataSourcesToAdd.remove( ds ) != null ){
+						
+						removed_something = true;
+					}
+				}
+				
+				if ( removed_something&& DEBUGADDREMOVE){
+					debug("Saved time by not adding a row that was removed");
+				}
+				
+				dataSourcesAdd = dataSourcesToAdd.keySet().toArray();
+
+				dataSourcesToAdd.clear();
+			}
+
+			if (dataSourcesToRemove.size() > 0) {
+				dataSourcesRemove = dataSourcesToRemove.keySet().toArray();
+				if (DEBUGADDREMOVE && dataSourcesRemove.length > 1) {
+					debug("Streamlining removing " + dataSourcesRemove.length + " rows");
+				}
+				dataSourcesToRemove.clear();
+			}
+		}
+
+		if (dataSourcesAdd != null && dataSourcesAdd.length > 0) {
+			reallyAddDataSources(dataSourcesAdd);
+			if (DEBUGADDREMOVE && dataSourcesAdd.length > 1) {
+				debug("Streamlined adding " + dataSourcesAdd.length + " rows");
+			}
+		}
+
+		if (dataSourcesRemove != null && dataSourcesRemove.length > 0) {
+			reallyRemoveDataSources(dataSourcesRemove);
+		}
+	}
+
+	public void addDataSource(DATASOURCETYPE dataSource) {
+		addDataSource(dataSource, false);
+	}
+
+	private void addDataSource(DATASOURCETYPE dataSource, boolean skipFilterCheck) {
+
+		if (dataSource == null) {
+			return;
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("AddDS: " + dataSource );
+		}
+		synchronized (rows_sync) {
+			listUnfilteredDataSources.put(dataSource,"");
+		}
+
+		if (!skipFilterCheck && filter != null
+				&& !filter.checker.filterCheck(dataSource, filter.text, filter.regex)) {
+			return;
+		}
+
+		if (DataSourceCallBackUtil.IMMEDIATE_ADDREMOVE_DELAY == 0) {
+			reallyAddDataSources(new Object[] {
+				dataSource
+			});
+			return;
+		}
+
+		// In order to save time, we cache entries to be added and process them
+		// in a refresh cycle.  This is a huge benefit to tables that have
+		// many rows being added and removed in rapid succession
+
+		synchronized (rows_sync) {
+			if ( dataSourcesToRemove.remove( dataSource ) != null ){
+				// we're adding, override any pending removal
+				if (DEBUGADDREMOVE) {
+					debug("AddDS: Removed from toRemove.  Total Removals Queued: "
+							+ dataSourcesToRemove.size());
+				}
+			}
+
+			if ( dataSourcesToAdd.containsKey(dataSource)){
+				// added twice.. ensure it's not in the remove list
+				if (DEBUGADDREMOVE) {
+					debug("AddDS: Already There.  Total Additions Queued: "
+							+ dataSourcesToAdd.size());
+				}
+			} else {
+				dataSourcesToAdd.put(dataSource, "");
+				if (DEBUGADDREMOVE) {
+					debug("Queued 1 dataSource to add.  Total Additions Queued: "
+							+ dataSourcesToAdd.size() + "; already=" + sortedRows.size());
+				}
+				refreshenProcessDataSourcesTimer();
+			}
+		}
+	}
+
+	// see common.TableView
+	public void addDataSources(final DATASOURCETYPE dataSources[]) {
+		addDataSources(dataSources, false);
+	}
+
+	public void addDataSources(final DATASOURCETYPE dataSources[],
+			boolean skipFilterCheck) {
+
+		if (dataSources == null) {
+			return;
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("AddDS: " + dataSources.length );
+		}
+		
+		synchronized (rows_sync) {
+			for (DATASOURCETYPE ds : dataSources) {
+				listUnfilteredDataSources.put(ds, null);
+			}
+		}
+
+		if (DataSourceCallBackUtil.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;
+		}
+
+		// In order to save time, we cache entries to be added and process them
+		// in a refresh cycle.  This is a huge benefit to tables that have
+		// many rows being added and removed in rapid succession
+
+		synchronized (rows_sync) {
+			int count = 0;
+
+			for (int i = 0; i < dataSources.length; i++) {
+				DATASOURCETYPE dataSource = dataSources[i];
+				if (dataSource == null) {
+					continue;
+				}
+				if (!skipFilterCheck
+						&& filter != null
+						&& !filter.checker.filterCheck(dataSource, filter.text,
+								filter.regex)) {
+					continue;
+				}
+				dataSourcesToRemove.remove(dataSource); // may be pending removal, override
+
+				if (dataSourcesToAdd.containsKey(dataSource)) {
+				} else {
+					count++;
+					dataSourcesToAdd.put(dataSource, "");
+				}
+			}
+
+			if (DEBUGADDREMOVE) {
+				debug("Queued " + count + " of " + dataSources.length
+						+ " dataSources to add.  Total Queued: " + dataSourcesToAdd.size());
+			}
+
+		}
+
+		refreshenProcessDataSourcesTimer();
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#dataSourceExists(java.lang.Object)
+	public boolean dataSourceExists(DATASOURCETYPE dataSource) {
+		return mapDataSourceToRow.containsKey(dataSource)
+				|| dataSourcesToAdd.containsKey(dataSource);
+	}
+
+	public void processDataSourceQueue() {
+		getOffUIThread(new AERunnable() {
+			public void runSupport() {
+				_processDataSourceQueue();
+			}
+		});
+	}
+
+	public abstract void getOffUIThread(AERunnable runnable);
+
+	public void processDataSourceQueueSync() {
+		_processDataSourceQueue();
+	}
+
+	/**
+	 * @note bIncludeQueue can return an invalid number, such as a negative :(
+	 */
+	public int size(boolean bIncludeQueue) {
+		int size = sortedRows.size();
+
+		if (bIncludeQueue) {
+			if (dataSourcesToAdd != null) {
+				size += dataSourcesToAdd.size();
+			}
+			if (dataSourcesToRemove != null) {
+				size -= dataSourcesToRemove.size();
+			}
+		}
+		return size;
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getRows()
+	public TableRowCore[] getRows() {
+		synchronized (rows_sync) {
+			return sortedRows.toArray(new TableRowCore[0]);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getRow(java.lang.Object)
+	public TableRowCore getRow(DATASOURCETYPE dataSource) {
+		return mapDataSourceToRow.get(dataSource);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getRow(int)
+	public TableRowCore getRow(int iPos) {
+		synchronized (rows_sync) {
+			if (iPos >= 0 && iPos < sortedRows.size()) {
+				TableRowCore row = sortedRows.get(iPos);
+
+				if (row.getIndex() != iPos) {
+					row.setTableItem(iPos);
+				}
+				return row;
+			}
+		}
+		return null;
+	}
+
+	public TableRowCore getRowQuick(int iPos) {
+		try {
+			return sortedRows.get(iPos);
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+	public int indexOf(TableRowCore row) {
+		return sortedRows.indexOf(row);
+	}
+
+	public int getRowCount() {
+		// don't use sortedRows here, it's not always up to date 
+		return mapDataSourceToRow.size();
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getDataSources()
+	public ArrayList<DATASOURCETYPE> getDataSources() {
+		synchronized (rows_sync) {
+			return new ArrayList<DATASOURCETYPE>(mapDataSourceToRow.keySet());
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#removeDataSource(java.lang.Object)
+	public void removeDataSource(final DATASOURCETYPE dataSource) {
+		if (dataSource == null) {
+			return;
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("RemDS: " + dataSource );
+		}
+
+		synchronized (rows_sync) {
+			listUnfilteredDataSources.remove(dataSource);
+		}
+
+		if (DataSourceCallBackUtil.IMMEDIATE_ADDREMOVE_DELAY == 0) {
+			reallyRemoveDataSources(new Object[] {
+				dataSource
+			});
+			return;
+		}
+
+		synchronized (rows_sync) {
+			dataSourcesToAdd.remove(dataSource); // override any pending addition
+			dataSourcesToRemove.put(dataSource, "");
+
+			if (DEBUGADDREMOVE) {
+				debug("Queued 1 dataSource to remove.  Total Queued: "
+						+ dataSourcesToRemove.size());
+			}
+		}
+
+		refreshenProcessDataSourcesTimer();
+	}
+
+	/** Remove the specified dataSource from the table.
+	 *
+	 * @param dataSources data sources to be removed
+	 * @param bImmediate Remove immediately, or queue and remove at next refresh
+	 */
+	public void removeDataSources(final DATASOURCETYPE[] dataSources) {
+		if (dataSources == null || dataSources.length == 0) {
+			return;
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("RemDS: " + dataSources.length );
+		}
+		
+		synchronized (rows_sync) {
+			for ( DATASOURCETYPE ds: dataSources ){
+				listUnfilteredDataSources.remove(ds);
+			}
+		}
+
+		if (DataSourceCallBackUtil.IMMEDIATE_ADDREMOVE_DELAY == 0) {
+			reallyRemoveDataSources(dataSources);
+			return;
+		}
+
+		synchronized (rows_sync) {
+			for (int i = 0; i < dataSources.length; i++) {
+				DATASOURCETYPE dataSource = dataSources[i];
+				dataSourcesToAdd.remove(dataSource); // override any pending addition
+				dataSourcesToRemove.put(dataSource, "");
+			}
+
+			if (DEBUGADDREMOVE) {
+				debug("Queued " + dataSources.length
+						+ " dataSources to remove.  Total Queued: "
+						+ dataSourcesToRemove.size() + " via " + Debug.getCompressedStackTrace(4));
+			}
+		}
+
+		refreshenProcessDataSourcesTimer();
+	}
+
+	private void refreshenProcessDataSourcesTimer() {
+		if (bReallyAddingDataSources || processDataSourceQueueCallback == null) {
+			// when processDataSourceQueueCallback is null, we are disposing
+			return;
+		}
+
+/////////////////////////////////////////////////////////////////////////////////		if (cellEditNotifier != null) {
+/////////////////////////////////////////////////////////////////////////////////			cellEditNotifier.sourcesChanged();
+/////////////////////////////////////////////////////////////////////////////////		}
+
+		boolean processQueueImmediately = DataSourceCallBackUtil.addDataSourceAggregated(processDataSourceQueueCallback);
+
+		if (processQueueImmediately) {
+			processDataSourceQueue();
+		}
+	}
+
+	public void reallyAddDataSources(final Object dataSources[]) {
+		// Note: We assume filterCheck has already run, and the list of dataSources
+		//       all passed the filter
+
+		if (isDisposed()) {
+			return;
+		}
+
+		bReallyAddingDataSources = true;
+		if (DEBUGADDREMOVE) {
+			debug(">>" + " Add " + dataSources.length + " rows;");
+		}
+
+		// Create row, and add to map immediately
+		synchronized (rows_sync) {
+			try {
+  
+  			//long lStartTime = SystemTime.getCurrentTime();
+  
+  			for (int i = 0; i < dataSources.length; i++) {
+  				Object ds = dataSources[i];
+  				if (ds == null) {
+  					if (DEBUGADDREMOVE) {
+  						debug("-- Null DS for " + i);
+  					}
+  					continue;
+  				}
+  
+  				if (mapDataSourceToRow.containsKey(ds)) {
+  					if (DEBUGADDREMOVE) {
+  						debug("-- " + i + " already added: " + ds.getClass());
+  					}
+  					dataSources[i] = null;
+  				} else {
+  					TableRowCore rowCore = createNewRow(ds);
+  					mapDataSourceToRow.put((DATASOURCETYPE) ds, rowCore);
+  				}
+  			}
+  		} catch (Exception e) {
+  			Logger.log(new LogEvent(LOGID, "Error while added row to Table "
+  					+ getTableID(), e));
+  		}
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("--" + " Add " + dataSources.length + " rows;");
+		}
+		
+		addSortedDataSource(dataSources);
+
+		bReallyAddingDataSources = false;
+	}
+
+	public abstract TableRowCore createNewRow(Object object);
+
+	public void delete() {
+		processDataSourceQueueCallback = null;
+	}
+
+	public Object getRowsSync() {
+		return rows_sync;
+	}
+	
+	public void setRowsSync(Object o) {
+		rows_sync = o;
+	}
+
+	public void generate(IndentWriter writer) {
+		writer.println("Diagnostics for " + this + " (" + getTableID() + ")");
+
+		synchronized (rows_sync) {
+			writer.println("DataSources scheduled to Add/Remove: "
+					+ dataSourcesToAdd.size() + "/" + dataSourcesToRemove.size());
+
+			writer.println("TableView: " + mapDataSourceToRow.size() + " datasources");
+			Iterator<DATASOURCETYPE> it = mapDataSourceToRow.keySet().iterator();
+
+			while (it.hasNext()) {
+
+				Object key = it.next();
+
+				writer.println("  " + key + " -> " + mapDataSourceToRow.get(key));
+			}
+
+		}
+	}
+
+	public void removeAllTableRows() {
+		synchronized (rows_sync) {
+			mapDataSourceToRow.clear();
+			sortedRows.clear();
+			
+			dataSourcesToAdd.clear();
+			dataSourcesToRemove.clear();
+			
+			listUnfilteredDataSources.clear();
+
+			selectedRows.clear();
+			listSelectedCoreDataSources = null;
+			
+			if (DEBUGADDREMOVE) {
+				debug("removeAll");
+			}
+		}
+	}
+
+	@SuppressWarnings("null")
+	public void reallyRemoveDataSources(final Object[] dataSources) {
+		final long lStart = SystemTime.getCurrentTime();
+
+		int rows_removed = 0;
+
+		StringBuffer sbWillRemove = null;
+		if (DEBUGADDREMOVE) {
+			debug(">>> Remove rows.  Start w/" + getRowCount()
+					+ "ds;"
+					+ (SystemTime.getCurrentTime() - lStart) + "ms wait");
+
+			sbWillRemove = new StringBuffer("Will soon remove row #");
+		}
+
+		ArrayList<TableRowCore> itemsToRemove = new ArrayList<TableRowCore>();
+		ArrayList<Integer> indexesToRemove = new ArrayList<Integer>();
+
+		int numRemovedHavingSelection = 0;
+		synchronized (rows_sync) {
+  		for (int i = 0; i < dataSources.length; i++) {
+  			if (dataSources[i] == null) {
+  				continue;
+  			}
+  
+  			TableRowCore item = mapDataSourceToRow.get(dataSources[i]);
+  			if (item != null) {
+  				if (isProvideIndexesOnRemove()) {
+    				// use sortedRows position instead of item.getIndex(), because
+    				// getIndex may have a wrong value (unless we fillRowGaps() which
+    				// is more time consuming and we do afterwards anyway)
+    				int index = sortedRows.indexOf(item);
+    				indexesToRemove.add(index);
+    				if (DEBUGADDREMOVE) {
+    					if (i != 0) {
+    						sbWillRemove.append(", ");
+    					}
+    					sbWillRemove.append(index);
+    				}
+  				}
+  
+  				if (item.isSelected()) {
+  					numRemovedHavingSelection++;
+  				}
+  				itemsToRemove.add(item);
+  				mapDataSourceToRow.remove(dataSources[i]);
+  				triggerListenerRowRemoved(item);
+  				sortedRows.remove(item);
+  				selectedRows.remove(item);
+  
+  				rows_removed++;
+  			}
+  		}
+  		if (rows_removed > 0) {
+  			listSelectedCoreDataSources = null;
+  		}
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug(sbWillRemove.toString());
+			debug("#itemsToRemove=" + itemsToRemove.size());
+		}
+
+		uiRemoveRows(itemsToRemove.toArray(new TableRowCore[0]),
+				indexesToRemove.toArray(new Integer[0]));
+
+		// Finally, delete the rows
+		for (Iterator<TableRowCore> iter = itemsToRemove.iterator(); iter.hasNext();) {
+			TableRowCore row = iter.next();
+			row.delete();
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("<< Remove " + itemsToRemove.size() + " rows. now "
+					+ mapDataSourceToRow.size() + "ds");
+		}
+
+		if ( rows_removed > 0 ){
+			
+			tableMutated();
+		}
+	}
+
+	private void
+	tableMutated()
+	{
+		filter f = filter;
+		
+		if ( f != null ){
+			TableViewFilterCheck<DATASOURCETYPE> checker = f.checker;
+			
+			if ( checker instanceof TableViewFilterCheck.TableViewFilterCheckEx ){
+				
+				((TableViewFilterCheck.TableViewFilterCheckEx)checker).viewChanged( this );
+			}
+		}
+	}
+	
+
+	protected void fillRowGaps(boolean bForceDataRefresh) {
+		_sortColumn(bForceDataRefresh, true, false);
+	}
+
+	public void sortColumn(boolean bForceDataRefresh) {
+		_sortColumn(bForceDataRefresh, false, false);
+	}
+
+	protected void _sortColumn(final boolean bForceDataRefresh, final boolean bFillGapsOnly,
+			final boolean bFollowSelected) {
+		if (isDisposed()) {
+			return;
+		}
+
+		try {
+			sortColumn_mon.enter();
+
+			long lTimeStart;
+			if (DEBUG_SORTER) {
+				//System.out.println(">>> Sort.. ");
+				lTimeStart = System.currentTimeMillis();
+			}
+
+			int iNumMoves = 0;
+
+
+			boolean needsUpdate = false;
+
+			synchronized (rows_sync) {
+				if (bForceDataRefresh && sortColumn != null) {
+					String sColumnID = sortColumn.getName();
+					for (Iterator<TableRowCore> iter = sortedRows.iterator(); iter.hasNext();) {
+						TableRowCore row = iter.next();
+						TableCellCore cell = row.getSortColumnCell(sColumnID);
+						if (cell != null) {
+							cell.refresh(true);
+						}
+					}
+				}
+
+				if (!bFillGapsOnly) {
+					if (sortColumn != null
+							&& sortColumn.getLastSortValueChange() >= lLastSortedOn) {
+						lLastSortedOn = SystemTime.getCurrentTime();
+						Collections.sort(sortedRows, sortColumn);
+						if (DEBUG_SORTER) {
+							long lTimeDiff = (System.currentTimeMillis() - lTimeStart);
+							if (lTimeDiff >= 0) {
+								debug("--- Build & Sort took " + lTimeDiff + "ms");
+							}
+						}
+					} else {
+						if (DEBUG_SORTER) {
+							debug("Skipping sort :)");
+						}
+					}
+				}
+
+				for (int i = 0; i < sortedRows.size(); i++) {
+					TableRowCore row = sortedRows.get(i);
+					boolean visible = row.isVisible();
+					if (row.setTableItem(i, visible)) {
+						if (visible) {
+							needsUpdate = true;
+						}
+						iNumMoves++;
+					}
+				}
+			}
+
+			if (DEBUG_SORTER && iNumMoves > 0) {
+				debug("Sort: numMoves= " + iNumMoves + ";needUpdate?" + needsUpdate);
+			}
+
+			if (needsUpdate) {
+				visibleRowsChanged();
+			}
+
+			if (DEBUG_SORTER) {
+				long lTimeDiff = (System.currentTimeMillis() - lTimeStart);
+				if (lTimeDiff >= 500) {
+					debug("<<< Sort & Assign took " + lTimeDiff + "ms with "
+							+ iNumMoves + " rows (of " + sortedRows.size() + ") moved. "
+							+ Debug.getCompressedStackTrace());
+				}
+			}
+		} finally {
+			sortColumn_mon.exit();
+		}
+	}
+
+	public abstract void visibleRowsChanged();
+
+	public abstract void uiRemoveRows(TableRowCore[] rows, Integer[] rowIndexes);
+	
+	public abstract int uiGuessMaxVisibleRows();
+
+	public void resetLastSortedOn() {
+		lLastSortedOn = 0;
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getColumnCells(java.lang.String)
+	public TableCellCore[] getColumnCells(String sColumnName) {
+
+		synchronized (rows_sync) {
+			TableCellCore[] cells = new TableCellCore[sortedRows.size()];
+
+			int i = 0;
+			for (Iterator<TableRowCore> iter = sortedRows.iterator(); iter.hasNext();) {
+				TableRowCore row = iter.next();
+				cells[i++] = row.getTableCellCore(sColumnName);
+			}
+
+			return cells;
+		}
+
+	}
+	
+	private void addSortedDataSource(final Object dataSources[]) {
+
+		if (isDisposed()) {
+			return;
+		}
+
+		TableRowCore[] selectedRows = getSelectedRows();
+			
+		boolean bWas0Rows = getRowCount() == 0;
+		synchronized (rows_sync) {
+			try {
+
+  			if (DEBUGADDREMOVE) {
+  				debug("--" + " Add " + dataSources.length + " rows to SWT");
+  			}
+  
+  			long lStartTime = SystemTime.getCurrentTime();
+  			
+  			final List<TableRowCore> rowsAdded = new ArrayList<TableRowCore>();
+  			
+  			// add to sortedRows list in best position.  
+  			// We need to be in the SWT thread because the rowSorter may end up
+  			// calling SWT objects.
+  			for (int i = 0; i < dataSources.length; i++) {
+  				Object dataSource = dataSources[i];
+  				if (dataSource == null) {
+  					continue;
+  				}
+  
+  				TableRowCore row = mapDataSourceToRow.get(dataSource);
+  				//if ((row == null) || row.isRowDisposed() || sortedRows.indexOf(row) >= 0) {
+  				if (row == null || row.isRowDisposed()) {
+  					continue;
+  				}
+  				if (sortColumn != null) {
+  					TableCellCore cell = row.getSortColumnCell(null);
+  					if (cell != null) {
+  						try {
+  							cell.invalidate();
+  							cell.refresh(true);
+  						} catch (Exception e) {
+  							Logger.log(new LogEvent(LOGID,
+  									"Minor error adding a row to table " + getTableID(), e));
+  						}
+  					}
+  				}
+  
+  				try {
+  					int index = 0;
+  					if (sortedRows.size() > 0) {
+  						// If we are >= to the last item, then just add it to the end
+  						// instead of relying on binarySearch, which may return an item
+  						// in the middle that also is equal.
+  						TableRowCore lastRow = sortedRows.get(sortedRows.size() - 1);
+  						if (sortColumn == null || sortColumn.compare(row, lastRow) >= 0) {
+  							index = sortedRows.size();
+  							sortedRows.add(row);
+  							if (DEBUGADDREMOVE) {
+  								debug("Adding new row to bottom");
+  							}
+  						} else {
+  							index = Collections.binarySearch(sortedRows, row, sortColumn);
+  							if (index < 0) {
+  								index = -1 * index - 1; // best guess
+  							}
+  
+  							if (index > sortedRows.size()) {
+  								index = sortedRows.size();
+  							}
+  
+  							if (DEBUGADDREMOVE) {
+  								debug("Adding new row at position " + index + " of "
+  										+ (sortedRows.size() - 1));
+  							}
+  							sortedRows.add(index, row);
+  						}
+  					} else {
+  						if (DEBUGADDREMOVE) {
+  							debug("Adding new row to bottom (1st Entry)");
+  						}
+  						index = sortedRows.size();
+  						sortedRows.add(row);
+  					}
+  
+  					rowsAdded.add(row);
+  
+  					// XXX Don't set table item here, it will mess up selected rows
+  					//     handling (which is handled in fillRowGaps called later on)
+  					//row.setTableItem(index);
+  					
+  					
+  					//row.setIconSize(ptIconSize);
+  				} catch (Exception e) {
+  					e.printStackTrace();
+  					Logger.log(new LogEvent(LOGID, "Error adding a row to table "
+  							+ getTableID(), e));
+  					try {
+  						if (!sortedRows.contains(row)) {
+  							sortedRows.add(row);
+  						}
+  					} catch (Exception e2) {
+  						Debug.out(e2);
+  					}
+  				}
+  			} // for dataSources
+  
+  			// NOTE: if the listener tries to do something like setSelected,
+  			// it will fail because we aren't done adding.
+  			// we should trigger after fillRowGaps()
+  			triggerListenerRowAdded(rowsAdded.toArray(new TableRowCore[0]));
+  
+  
+  			if (DEBUGADDREMOVE) {
+  				debug("Adding took " + (SystemTime.getCurrentTime() - lStartTime)
+  						+ "ms");
+  			}
+  
+  		} catch (Exception e) {
+  			Logger.log(new LogEvent(LOGID, "Error while adding row to Table "
+  					+ getTableID(), e));
+  		}
+		}
+		refreshenProcessDataSourcesTimer();
+
+		visibleRowsChanged();
+		fillRowGaps(false);
+
+		setSelectedRows(selectedRows);
+		if (DEBUGADDREMOVE) {
+			debug("<< " + size(false));
+		}
+
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableStructureModificationListener#cellInvalidate(com.aelitis.azureus.ui.common.table.TableColumnCore, java.lang.Object)
+	public void cellInvalidate(TableColumnCore tableColumn,
+			DATASOURCETYPE data_source) {
+		cellInvalidate(tableColumn, data_source, true);
+	}
+
+	public void cellInvalidate(TableColumnCore tableColumn,
+			final DATASOURCETYPE data_source, final boolean bMustRefresh) {
+		final String sColumnName = tableColumn.getName();
+
+		runForAllRows(new TableGroupRowRunner() {
+			public void run(TableRowCore row) {
+				TableCellCore cell = row.getTableCellCore(sColumnName);
+				if (cell != null && cell.getDataSource() != null
+						&& cell.getDataSource().equals(data_source)) {
+					cell.invalidate(bMustRefresh);
+				}
+			}
+		});
+	}
+
+	// see common.TableView
+	public void columnInvalidate(final String sColumnName) {
+		TableColumnCore tc = TableColumnManager.getInstance().getTableColumnCore(
+				getTableID(), sColumnName);
+		if (tc != null) {
+			columnInvalidate(tc, tc.getType() == TableColumnCore.TYPE_TEXT_ONLY);
+		}
+	}
+
+	public void columnInvalidate(TableColumnCore tableColumn,
+			final boolean bMustRefresh) {
+		final String sColumnName = tableColumn.getName();
+
+		runForAllRows(new TableGroupRowRunner() {
+			public void run(TableRowCore row) {
+				TableCellCore cell = row.getTableCellCore(sColumnName);
+				if (cell != null) {
+					cell.invalidate(bMustRefresh);
+				}
+			}
+		});
+		resetLastSortedOn();
+		tableColumn.setLastSortValueChange(SystemTime.getCurrentTime());
+	}
+
+	// ITableStructureModificationListener
+	// TableView
+	public void columnInvalidate(TableColumnCore tableColumn) {
+		// We are being called from a plugin (probably), so we must refresh
+		columnInvalidate(tableColumn, true);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getPropertiesPrefix()
+	public String getPropertiesPrefix() {
+		return propertiesPrefix;
+	}
+
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getTableID()
+	public String getTableID() {
+		return tableID;
+	}
+
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getDataSourceType()
+	public Class<?> getDataSourceType() {
+		return classPluginDataSourceType;
+	}
+
+	public void tableStructureChanged(boolean columnAddedOrRemoved,
+			Class forPluginDataSourceType) {
+		if (forPluginDataSourceType != null
+				&& !forPluginDataSourceType.equals(getDataSourceType())) {
+			return;
+		}
+		triggerLifeCycleListener(TableLifeCycleListener.EVENT_DESTROYED);
+
+		DATASOURCETYPE[] unfilteredDS;
+		synchronized (rows_sync) {
+			unfilteredDS = (DATASOURCETYPE[]) listUnfilteredDataSources.keySet().toArray();
+		}
+
+		if (DEBUGADDREMOVE) {
+			debug("TSC: #Unfiltered=" + unfilteredDS.length);
+		}
+		removeAllTableRows();
+		processDataSourceQueueSync();
+
+		if (columnAddedOrRemoved) {
+			tableColumns = TableColumnManager.getInstance().getAllTableColumnCoreAsArray(
+					getDataSourceType(), tableID);
+			ArrayList<TableColumnCore> listVisibleColumns = new ArrayList<TableColumnCore>();
+			for (TableColumnCore column : tableColumns) {
+				if (column.isVisible()) {
+					listVisibleColumns.add(column);
+				}
+			}
+			Collections.sort(listVisibleColumns, new Comparator<TableColumnCore>() {
+				public int compare(TableColumnCore o1, TableColumnCore o2) {
+					if (o1 == o2) {
+						return 0;
+					}
+					int diff = o1.getPosition() - o2.getPosition();
+					return diff;
+				}
+			});
+			columnsOrdered = listVisibleColumns.toArray(new TableColumnCore[0]);
+		}
+		
+		//initializeTableColumns()
+		
+		refreshTable(false);
+		triggerLifeCycleListener(TableLifeCycleListener.EVENT_INITIALIZED);
+		
+		// some implementers re-add datasource on Initialized trigger.
+		// if they do, we don't have to re-add the unfiltlered (if we do, it
+		// could case dups if the new datasources have different derps)
+		if (listUnfilteredDataSources.size() == 0) {
+			addDataSources(unfilteredDS);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getTableColumn(java.lang.String)
+	 */
+	public org.gudy.azureus2.plugins.ui.tables.TableColumn getTableColumn(
+			String sColumnName) {
+		for (int i = 0; i < tableColumns.length; i++) {
+			TableColumnCore tc = tableColumns[i];
+			if (tc.getName().equals(sColumnName)) {
+				return tc;
+			}
+		}
+		return null;
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getVisibleColumns()
+	public TableColumnCore[] getVisibleColumns() {
+		return columnsOrdered;
+	}
+	
+	public TableColumnCore[] getAllColumns() {
+		return tableColumns;
+	}
+
+	protected void setColumnsOrdered(TableColumnCore[] columnsOrdered) {
+		this.columnsOrdered = columnsOrdered;
+	}
+
+	public boolean isColumnVisible(
+			org.gudy.azureus2.plugins.ui.tables.TableColumn column) {
+		if (column == null) {
+			return false;
+		}
+		return column.isVisible();
+	}
+	
+	public void refreshTable(boolean bForceSort) {
+		triggerTableRefreshListeners();
+	}
+
+	/* various selected rows functions */
+	/***********************************/
+
+	public List<Object> getSelectedDataSourcesList() {
+		if (listSelectedCoreDataSources != null) {
+			return listSelectedCoreDataSources;
+		}
+		synchronized (selectedRows) {
+			if (isDisposed() || selectedRows.size() == 0) {
+  			return Collections.emptyList();
+  		}
+  
+  		final ArrayList<Object> l = new ArrayList<Object>(
+  				selectedRows.size());
+  		for (TableRowCore row : selectedRows) {
+  			if (row != null && !row.isRowDisposed()) {
+  				Object ds = row.getDataSource(true);
+  				if (ds != null) {
+  					l.add(ds);
+  				}
+  			}
+  		}
+ 
+  		listSelectedCoreDataSources = l;
+  		return l;
+		}
+	}
+
+	/** Returns an array of all selected Data Sources.  Null data sources are
+	 * ommitted.
+	 *
+	 * @return an array containing the selected data sources
+	 * 
+	 * @TODO TuxPaper: Virtual row not created when using getSelection?
+	 *                  computePossibleActions isn't being calculated right
+	 *                  because of non-created rows when select user selects all
+	 */
+	public List<Object> getSelectedPluginDataSourcesList() {
+		synchronized (selectedRows) {
+  		if (isDisposed() || selectedRows.size() == 0) {
+  			return Collections.emptyList();
+  		}
+  
+  		final ArrayList<Object> l = new ArrayList<Object>(selectedRows.size());
+  		for (TableRowCore row : selectedRows) {
+  			if (row != null && !row.isRowDisposed()) {
+  				Object ds = row.getDataSource(false);
+  				if (ds != null) {
+  					l.add(ds);
+  				}
+  			}
+  		}
+  		return l;
+		}
+	}
+
+	/** Returns an array of all selected Data Sources.  Null data sources are
+	 * ommitted.
+	 *
+	 * @return an array containing the selected data sources
+	 *
+	 **/
+	// see common.TableView
+	public List<Object> getSelectedDataSources() {
+		return new ArrayList<Object>(getSelectedDataSourcesList());
+	}
+
+	// see common.TableView
+	public Object[] getSelectedDataSources(boolean bCoreDataSource) {
+		if (bCoreDataSource) {
+			return getSelectedDataSourcesList().toArray();
+		}
+		return getSelectedPluginDataSourcesList().toArray();
+	}
+
+	/** @see com.aelitis.azureus.ui.common.table.TableView#getSelectedRows() */
+	public TableRowCore[] getSelectedRows() {
+		synchronized (selectedRows) {
+			return selectedRows.toArray(new TableRowCore[0]);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getSelectedRowsSize()
+	public int getSelectedRowsSize() {
+		synchronized (selectedRows) {
+			return selectedRows.size();
+		}
+	}
+
+	/** Returns an list of all selected TableRowSWT objects.  Null data sources are
+	 * ommitted.
+	 *
+	 * @return an list containing the selected TableRowSWT objects
+	 */
+	public List<TableRowCore> getSelectedRowsList() {
+		synchronized (selectedRows) {
+  		final ArrayList<TableRowCore> l = new ArrayList<TableRowCore>(
+  				selectedRows.size());
+  		for (TableRowCore row : selectedRows) {
+  			if (row != null && !row.isRowDisposed()) {
+  				l.add(row);
+  			}
+  		}
+  
+  		return l;
+		}
+	}
+	
+	public boolean isSelected(TableRow row) {
+		synchronized (selectedRows) {
+			return selectedRows.contains(row);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getFocusedRow()
+	public TableRowCore getFocusedRow() {
+		synchronized (selectedRows) {
+			if (selectedRows.size() == 0) {
+				return null;
+			}
+			return selectedRows.get(0);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getFirstSelectedDataSource()
+	public Object getFirstSelectedDataSource() {
+		return getFirstSelectedDataSource(true);
+	}
+	
+	/** Returns the first selected data sources.
+	 *
+	 * @return the first selected data source, or null if no data source is 
+	 *         selected
+	 */
+	public Object getFirstSelectedDataSource(boolean bCoreObject) {
+		synchronized (selectedRows) {
+			if (selectedRows.size() > 0) {
+				return selectedRows.get(0).getDataSource(bCoreObject);
+			}
+		}
+		return null;
+	}
+
+
+	/////
+
+
+	/**
+	 * Invalidate and refresh whole table
+	 */
+	public void tableInvalidate() {
+		runForAllRows(new TableGroupRowVisibilityRunner() {
+			public void run(TableRowCore row, boolean bVisible) {
+				row.invalidate();
+				row.refresh(true, bVisible);
+			}
+		});
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#getHeaderVisible()
+	public boolean getHeaderVisible() {
+		return headerVisible;
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#setHeaderVisible(boolean)
+	public void setHeaderVisible(boolean visible) {
+		headerVisible  = visible;
+	}
+
+
+	// @see org.gudy.azureus2.ui.swt.views.TableViewSWT#getSortColumn()
+	public TableColumnCore getSortColumn() {
+		return sortColumn;
+	}
+
+	protected boolean setSortColumn(TableColumnCore newSortColumn, boolean allowOrderChange) {
+		if (newSortColumn == null) {
+			return false;
+		}
+		sortColumn_mon.enter();
+		try {
+  		boolean isSameColumn = newSortColumn.equals(sortColumn);
+ 			if (allowOrderChange) {
+  			if (!isSameColumn) {
+  				sortColumn = newSortColumn;
+  				
+  				int iSortDirection = configMan.getIntParameter(CFG_SORTDIRECTION);
+  				if (iSortDirection == 0) {
+  					sortColumn.setSortAscending(true);
+  				} else if (iSortDirection == 1) {
+  					sortColumn.setSortAscending(false);
+  				} else {
+  					sortColumn.setSortAscending(!sortColumn.isSortAscending());
+  				}
+
+  				TableColumnManager.getInstance().setDefaultSortColumnName(tableID,
+  						sortColumn.getName());
+  			} else {
+  				sortColumn.setSortAscending(!sortColumn.isSortAscending());
+  			}
+			} else {
+				sortColumn = newSortColumn;
+			}
+ 			if (!isSameColumn) {
+ 				synchronized (rows_sync) {
+					String name = sortColumn.getName();
+					for (Iterator<TableRowCore> iter = sortedRows.iterator(); iter.hasNext();) {
+						TableRowCore row = iter.next();
+						row.setSortColumn(name);
+					}
+				}
+ 			}
+ 			uiChangeColumnIndicator();
+ 			resetLastSortedOn();
+ 			sortColumn(!isSameColumn);
+			return !isSameColumn;
+		} finally {
+			sortColumn_mon.exit();
+		}
+	}
+
+	public void setRowSelected(final TableRowCore row, boolean selected, boolean trigger) {
+		if (row == null || row.isRowDisposed()) {
+			return;
+		}
+		if (isSingleSelection()) {
+			setSelectedRows(new TableRowCore[] { row }, trigger);
+		} else {
+			boolean somethingChanged = false;
+			ArrayList<TableRowCore> newSelectedRows;
+			synchronized (selectedRows) {
+				newSelectedRows = new ArrayList<TableRowCore>(selectedRows);
+				if (selected) {
+					if (!newSelectedRows.contains(row)) {
+						newSelectedRows.add(row);
+						somethingChanged = true;
+					}
+				} else {
+					somethingChanged = newSelectedRows.remove(row);
+				}
+			}
+			
+			if (somethingChanged) {
+				setSelectedRows(newSelectedRows.toArray(new TableRowCore[0]), trigger);
+			}
+		}
+	}
+
+	public void setSelectedRows(final TableRowCore[] newSelectionArray,
+			final boolean trigger) {
+		if (isDisposed()) {
+			return;
+		}
+
+		/**
+		System.out.print(newSelectionArray.length + " Selected Rows: ");
+		for (TableRowCore row : newSelectionArray) {
+			System.out.print(indexOf(row));
+			System.out.print(", ");
+		}
+		System.out.println(" via " + Debug.getCompressedStackTrace(4));
+		/**/
+
+		final List<TableRowCore> oldSelectionList = new ArrayList<TableRowCore>();
+		
+		List<TableRowCore> listNewlySelected;
+		boolean somethingChanged;
+		synchronized (selectedRows) {
+			if (selectedRows.size() == 0 && newSelectionArray.length == 0) {
+				return;
+			}
+
+			oldSelectionList.addAll(selectedRows);
+			listSelectedCoreDataSources = null;
+			selectedRows.clear();
+
+			listNewlySelected = new ArrayList<TableRowCore>(1);
+
+			// We'll remove items still selected from oldSelectionLeft, leaving
+			// it with a list of items that need to fire the deselection event.
+			for (TableRowCore row : newSelectionArray) {
+				if (row == null || row.isRowDisposed()) {
+					continue;
+				}
+
+				boolean existed = false;
+				for (TableRowCore oldRow : oldSelectionList) {
+					if (oldRow == row) {
+						existed = true;
+						if (!selectedRows.contains(row)) {
+							selectedRows.add(row);
+						}
+						oldSelectionList.remove(row);
+						break;
+					}
+				}
+				if (!existed) {
+					if (!selectedRows.contains(row)) {
+						selectedRows.add(row);
+					}
+					if (!listNewlySelected.contains(row)) {
+						listNewlySelected.add(row);
+					}
+				}
+			}
+
+			somethingChanged = listNewlySelected.size() > 0
+					|| oldSelectionList.size() > 0;
+			if (DEBUG_SELECTION) {
+				System.out.println(somethingChanged + "] +"
+						+ listNewlySelected.size() + "/-" + oldSelectionList.size()
+						+ ";  UpdateSelectedRows via " + Debug.getCompressedStackTrace());
+			}
+		}
+		
+		if (somethingChanged) {
+			uiSelectionChanged(listNewlySelected.toArray(new TableRowCore[0]), oldSelectionList.toArray(new TableRowCore[0]));
+		}
+
+		if (trigger && somethingChanged) {
+			if (listNewlySelected.size() > 0) {
+				triggerSelectionListeners(listNewlySelected.toArray(new TableRowCore[0]));
+			}
+			if (oldSelectionList.size() > 0) {
+				triggerDeselectionListeners(oldSelectionList.toArray(new TableRowCore[0]));
+			}
+
+			triggerTabViewsDataSourceChanged(false);
+		}
+
+	}
+	
+	public abstract boolean isSingleSelection();
+	
+	public abstract void uiSelectionChanged(TableRowCore[] newlySelectedRows, TableRowCore[] deselectedRows);
+
+	// @see com.aelitis.azureus.ui.common.table.TableView#setSelectedRows(com.aelitis.azureus.ui.common.table.TableRowCore[])
+	public void setSelectedRows(TableRowCore[] rows) {
+		setSelectedRows(rows, true);
+	}
+
+	public void selectAll() {
+		setSelectedRows(getRows(), true);
+	}
+
+	public String getFilterText() {
+		return filter == null ? "" : filter.text;
+	}
+
+	public boolean isMenuEnabled() {
+		return menuEnabled;
+	}
+
+	public void setMenuEnabled(boolean menuEnabled) {
+		this.menuEnabled = menuEnabled;
+	}
+
+	protected boolean isLastRow(TableRowCore row) {
+		synchronized (rows_sync) {
+			int size = sortedRows.size();
+			return size == 0 ? false : sortedRows.get(size - 1) == row;
+		}
+	}
+
+	public abstract void triggerTabViewsDataSourceChanged(boolean sendParent);
+
+	protected abstract void uiChangeColumnIndicator();
+
+	public boolean isProvideIndexesOnRemove() {
+		return provideIndexesOnRemove;
+	}
+
+	public void setProvideIndexesOnRemove(boolean provideIndexesOnRemove) {
+		this.provideIndexesOnRemove = provideIndexesOnRemove;
+	}
+
+	public boolean isTableSelected() {
+		return SelectedContentManager.getCurrentlySelectedTableView() == this;
+	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/common/updater/UIUpdater.java b/com/aelitis/azureus/ui/common/updater/UIUpdater.java
index 57e370b..69eff15 100644
--- a/com/aelitis/azureus/ui/common/updater/UIUpdater.java
+++ b/com/aelitis/azureus/ui/common/updater/UIUpdater.java
@@ -27,11 +27,29 @@ package com.aelitis.azureus.ui.common.updater;
 public interface UIUpdater
 {
 
-	public void addUpdater(UIUpdatable updateable);
+	public void addUpdater(UIUpdatable updateable );
 
-	public void removeUpdater(UIUpdatable updateable);
+	public boolean isAdded( UIUpdatable updateable );
+	
+	public void removeUpdater(UIUpdatable updateable );
 
 	public void stopIt();
 
 	public void start();
+	
+	public void
+	addListener(
+		UIUpdaterListener		listener );
+	
+	public void
+	removeListener(
+		UIUpdaterListener		listener );
+	
+	public interface
+	UIUpdaterListener
+	{
+		public void
+		updateComplete(
+			int		count );
+	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo.java b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo.java
index b0d1cf7..8cc955c 100644
--- a/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo.java
+++ b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo.java
@@ -41,11 +41,6 @@ public interface ViewTitleInfo
 	
 	public static int TITLE_IMAGE_TOOLTIP = 3;
 
-	/**
-	 * Retreive the skin object related to this view indicator
-	 */
-	public static int TITLE_SKINVIEW = 4;
-
 	public static int TITLE_LOGID	= 7;
 	
 
diff --git a/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo2.java b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo2.java
new file mode 100644
index 0000000..32aba47
--- /dev/null
+++ b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfo2.java
@@ -0,0 +1,33 @@
+/**
+ * Created on Nov 17, 2010
+ *
+ * Copyright 2010 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.common.viewtitleinfo;
+
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+
+/**
+ * @author TuxPaper
+ * @created Nov 17, 2010
+ *
+ */
+public interface ViewTitleInfo2
+	extends ViewTitleInfo
+{
+	public void titleInfoLinked(MultipleDocumentInterface mdi, MdiEntry mdiEntry);
+}
diff --git a/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfoManager.java b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfoManager.java
index 4d5661b..4cb30d4 100644
--- a/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfoManager.java
+++ b/com/aelitis/azureus/ui/common/viewtitleinfo/ViewTitleInfoManager.java
@@ -28,10 +28,20 @@ import java.util.List;
  */
 public class ViewTitleInfoManager
 {
-	public static List listeners = new ArrayList();
+	public static List<ViewTitleInfoListener> listeners = new ArrayList<ViewTitleInfoListener>();
 	
 	public static void addListener(ViewTitleInfoListener l) {
-		listeners.add(l);
+		synchronized (listeners) {
+			if (!listeners.contains(l)) {
+				listeners.add(l);
+			}
+		}
+	}
+	
+	public static void removeListener(ViewTitleInfoListener l) {
+		synchronized (listeners) {
+			listeners.remove(l);
+		}
 	}
 	
 	public static void refreshTitleInfo(ViewTitleInfo titleinfo) {
diff --git a/com/aelitis/azureus/ui/images/30px-mswmp.png b/com/aelitis/azureus/ui/images/30px-mswmp.png
new file mode 100644
index 0000000..f96548a
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-mswmp.png differ
diff --git a/com/aelitis/azureus/ui/images/30px-other.png b/com/aelitis/azureus/ui/images/30px-other.png
new file mode 100644
index 0000000..c5412db
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-other.png differ
diff --git a/com/aelitis/azureus/ui/images/30px-psp.png b/com/aelitis/azureus/ui/images/30px-psp.png
new file mode 100644
index 0000000..e6ef691
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-psp.png differ
diff --git a/com/aelitis/azureus/ui/images/30px-sam.png b/com/aelitis/azureus/ui/images/30px-sam.png
new file mode 100644
index 0000000..74770df
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-sam.png differ
diff --git a/com/aelitis/azureus/ui/images/30px-tivo.png b/com/aelitis/azureus/ui/images/30px-tivo.png
new file mode 100644
index 0000000..44d191e
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-tivo.png differ
diff --git a/com/aelitis/azureus/ui/images/30px-wdtv.png b/com/aelitis/azureus/ui/images/30px-wdtv.png
new file mode 100644
index 0000000..d2cd378
Binary files /dev/null and b/com/aelitis/azureus/ui/images/30px-wdtv.png differ
diff --git a/com/aelitis/azureus/ui/images/Vuze_DVD_Burn_Icon.png b/com/aelitis/azureus/ui/images/Vuze_DVD_Burn_Icon.png
new file mode 100644
index 0000000..8b474a9
Binary files /dev/null and b/com/aelitis/azureus/ui/images/Vuze_DVD_Burn_Icon.png differ
diff --git a/com/aelitis/azureus/ui/images/Vuze_HD_Player_Icon.png b/com/aelitis/azureus/ui/images/Vuze_HD_Player_Icon.png
new file mode 100644
index 0000000..c608de3
Binary files /dev/null and b/com/aelitis/azureus/ui/images/Vuze_HD_Player_Icon.png differ
diff --git a/com/aelitis/azureus/ui/images/Vuze_Play_Now_Icon.png b/com/aelitis/azureus/ui/images/Vuze_Play_Now_Icon.png
new file mode 100644
index 0000000..75e6527
Binary files /dev/null and b/com/aelitis/azureus/ui/images/Vuze_Play_Now_Icon.png differ
diff --git a/com/aelitis/azureus/ui/images/Vuze_Plus_Toolbar_Logo.png b/com/aelitis/azureus/ui/images/Vuze_Plus_Toolbar_Logo.png
new file mode 100644
index 0000000..1a5f4bd
Binary files /dev/null and b/com/aelitis/azureus/ui/images/Vuze_Plus_Toolbar_Logo.png differ
diff --git a/com/aelitis/azureus/ui/images/Vuze_Speed_Test_Icon.png b/com/aelitis/azureus/ui/images/Vuze_Speed_Test_Icon.png
new file mode 100644
index 0000000..7401c6d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/Vuze_Speed_Test_Icon.png differ
diff --git a/com/aelitis/azureus/ui/images/android_icon_32x32.png b/com/aelitis/azureus/ui/images/android_icon_32x32.png
new file mode 100644
index 0000000..61f099e
Binary files /dev/null and b/com/aelitis/azureus/ui/images/android_icon_32x32.png differ
diff --git a/com/aelitis/azureus/ui/images/arrowSmall.gif b/com/aelitis/azureus/ui/images/arrowSmall.gif
deleted file mode 100644
index 29c0618..0000000
Binary files a/com/aelitis/azureus/ui/images/arrowSmall.gif and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/arrow_btn.png b/com/aelitis/azureus/ui/images/arrow_btn.png
new file mode 100644
index 0000000..105f731
Binary files /dev/null and b/com/aelitis/azureus/ui/images/arrow_btn.png differ
diff --git a/com/aelitis/azureus/ui/images/arrow_btn_pressed.png b/com/aelitis/azureus/ui/images/arrow_btn_pressed.png
new file mode 100644
index 0000000..e31d6de
Binary files /dev/null and b/com/aelitis/azureus/ui/images/arrow_btn_pressed.png differ
diff --git a/com/aelitis/azureus/ui/images/bigspin.png b/com/aelitis/azureus/ui/images/bigspin.png
new file mode 100644
index 0000000..5b0f8ff
Binary files /dev/null and b/com/aelitis/azureus/ui/images/bigspin.png differ
diff --git a/com/aelitis/azureus/ui/images/blueline.png b/com/aelitis/azureus/ui/images/blueline.png
deleted file mode 100644
index 9f19fcd..0000000
Binary files a/com/aelitis/azureus/ui/images/blueline.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/bottom_bar_bg.gif b/com/aelitis/azureus/ui/images/bottom_bar_bg.gif
deleted file mode 100644
index 4e0aa67..0000000
Binary files a/com/aelitis/azureus/ui/images/bottom_bar_bg.gif and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/download_arrow.png b/com/aelitis/azureus/ui/images/download_arrow.png
new file mode 100644
index 0000000..133ba02
Binary files /dev/null and b/com/aelitis/azureus/ui/images/download_arrow.png differ
diff --git a/com/aelitis/azureus/ui/images/download_bar_overlay.png b/com/aelitis/azureus/ui/images/download_bar_overlay.png
new file mode 100644
index 0000000..1224769
Binary files /dev/null and b/com/aelitis/azureus/ui/images/download_bar_overlay.png differ
diff --git a/com/aelitis/azureus/ui/images/download_bar_overlay_small.png b/com/aelitis/azureus/ui/images/download_bar_overlay_small.png
new file mode 100644
index 0000000..3d1f8fd
Binary files /dev/null and b/com/aelitis/azureus/ui/images/download_bar_overlay_small.png differ
diff --git a/com/aelitis/azureus/ui/images/entry_buddy_new.png b/com/aelitis/azureus/ui/images/entry_buddy_new.png
deleted file mode 100644
index a644b06..0000000
Binary files a/com/aelitis/azureus/ui/images/entry_buddy_new.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/entry_buddy_req.png b/com/aelitis/azureus/ui/images/entry_buddy_req.png
deleted file mode 100644
index 3bd5900..0000000
Binary files a/com/aelitis/azureus/ui/images/entry_buddy_req.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/entry_buddy_share.png b/com/aelitis/azureus/ui/images/entry_buddy_share.png
deleted file mode 100644
index a98ca51..0000000
Binary files a/com/aelitis/azureus/ui/images/entry_buddy_share.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/entry_thumbsup.png b/com/aelitis/azureus/ui/images/entry_thumbsup.png
deleted file mode 100644
index 2fd11df..0000000
Binary files a/com/aelitis/azureus/ui/images/entry_thumbsup.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/failure.png b/com/aelitis/azureus/ui/images/failure.png
new file mode 100644
index 0000000..6394109
Binary files /dev/null and b/com/aelitis/azureus/ui/images/failure.png differ
diff --git a/com/aelitis/azureus/ui/images/grayhline.png b/com/aelitis/azureus/ui/images/grayhline.png
deleted file mode 100644
index f6f29a5..0000000
Binary files a/com/aelitis/azureus/ui/images/grayhline.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/help-over.png b/com/aelitis/azureus/ui/images/help-over.png
deleted file mode 100644
index 72fc01b..0000000
Binary files a/com/aelitis/azureus/ui/images/help-over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/help.png b/com/aelitis/azureus/ui/images/help.png
deleted file mode 100644
index a84af4c..0000000
Binary files a/com/aelitis/azureus/ui/images/help.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_x.png b/com/aelitis/azureus/ui/images/ic_x.png
similarity index 100%
rename from com/aelitis/azureus/ui/images/sb/ic_x.png
rename to com/aelitis/azureus/ui/images/ic_x.png
diff --git a/com/aelitis/azureus/ui/images/lastsearch.gif b/com/aelitis/azureus/ui/images/lastsearch.gif
deleted file mode 100644
index edef090..0000000
Binary files a/com/aelitis/azureus/ui/images/lastsearch.gif and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/network_closed_preview.png b/com/aelitis/azureus/ui/images/network_closed_preview.png
deleted file mode 100644
index b917975..0000000
Binary files a/com/aelitis/azureus/ui/images/network_closed_preview.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/new_dot.png b/com/aelitis/azureus/ui/images/new_dot.png
index ebb2252..a4cfe7f 100644
Binary files a/com/aelitis/azureus/ui/images/new_dot.png and b/com/aelitis/azureus/ui/images/new_dot.png differ
diff --git a/com/aelitis/azureus/ui/images/notification_icon.png b/com/aelitis/azureus/ui/images/notification_icon.png
deleted file mode 100644
index 298c476..0000000
Binary files a/com/aelitis/azureus/ui/images/notification_icon.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/old_dot.png b/com/aelitis/azureus/ui/images/old_dot.png
index 65fdef3..47f7a2b 100644
Binary files a/com/aelitis/azureus/ui/images/old_dot.png and b/com/aelitis/azureus/ui/images/old_dot.png differ
diff --git a/com/aelitis/azureus/ui/images/play_now_off.png b/com/aelitis/azureus/ui/images/play_now_off.png
new file mode 100644
index 0000000..3c39156
Binary files /dev/null and b/com/aelitis/azureus/ui/images/play_now_off.png differ
diff --git a/com/aelitis/azureus/ui/images/play_now_on.png b/com/aelitis/azureus/ui/images/play_now_on.png
new file mode 100644
index 0000000..befe79d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/play_now_on.png differ
diff --git a/com/aelitis/azureus/ui/images/popup_dvd_drag.png b/com/aelitis/azureus/ui/images/popup_dvd_drag.png
new file mode 100644
index 0000000..e7e2c9d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/popup_dvd_drag.png differ
diff --git a/com/aelitis/azureus/ui/images/popup_warning_icon.png b/com/aelitis/azureus/ui/images/popup_warning_icon.png
new file mode 100644
index 0000000..4142b46
Binary files /dev/null and b/com/aelitis/azureus/ui/images/popup_warning_icon.png differ
diff --git a/com/aelitis/azureus/ui/images/priority_high.png b/com/aelitis/azureus/ui/images/priority_high.png
new file mode 100644
index 0000000..56d0618
Binary files /dev/null and b/com/aelitis/azureus/ui/images/priority_high.png differ
diff --git a/com/aelitis/azureus/ui/images/priority_normal.png b/com/aelitis/azureus/ui/images/priority_normal.png
new file mode 100644
index 0000000..f3fb19c
Binary files /dev/null and b/com/aelitis/azureus/ui/images/priority_normal.png differ
diff --git a/com/aelitis/azureus/ui/images/priority_stopped.png b/com/aelitis/azureus/ui/images/priority_stopped.png
new file mode 100644
index 0000000..b8ea7cd
Binary files /dev/null and b/com/aelitis/azureus/ui/images/priority_stopped.png differ
diff --git a/com/aelitis/azureus/ui/images/qual_hd.png b/com/aelitis/azureus/ui/images/qual_hd.png
deleted file mode 100644
index db201d3..0000000
Binary files a/com/aelitis/azureus/ui/images/qual_hd.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/qual_sd.png b/com/aelitis/azureus/ui/images/qual_sd.png
deleted file mode 100644
index ec9f9db..0000000
Binary files a/com/aelitis/azureus/ui/images/qual_sd.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/remote_ftux.png b/com/aelitis/azureus/ui/images/remote_ftux.png
new file mode 100644
index 0000000..68007b0
Binary files /dev/null and b/com/aelitis/azureus/ui/images/remote_ftux.png differ
diff --git a/com/aelitis/azureus/ui/images/remote_icon.png b/com/aelitis/azureus/ui/images/remote_icon.png
new file mode 100644
index 0000000..c04739b
Binary files /dev/null and b/com/aelitis/azureus/ui/images/remote_icon.png differ
diff --git a/com/aelitis/azureus/ui/images/remote_logo.png b/com/aelitis/azureus/ui/images/remote_logo.png
new file mode 100644
index 0000000..0094ed1
Binary files /dev/null and b/com/aelitis/azureus/ui/images/remote_logo.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-bb.png b/com/aelitis/azureus/ui/images/sb/20px-bb.png
new file mode 100644
index 0000000..87ad8da
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-bb.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-dlna.png b/com/aelitis/azureus/ui/images/sb/20px-dlna.png
new file mode 100644
index 0000000..37df043
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-dlna.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-games.png b/com/aelitis/azureus/ui/images/sb/20px-games.png
new file mode 100644
index 0000000..0a2ece6
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-games.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-itunes.png b/com/aelitis/azureus/ui/images/sb/20px-itunes.png
index 5dd7565..6fcfe33 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-itunes.png and b/com/aelitis/azureus/ui/images/sb/20px-itunes.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-library.png b/com/aelitis/azureus/ui/images/sb/20px-library.png
new file mode 100644
index 0000000..c1af559
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-library.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-mswmp.png b/com/aelitis/azureus/ui/images/sb/20px-mswmp.png
new file mode 100644
index 0000000..72523eb
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-mswmp.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-neo.png b/com/aelitis/azureus/ui/images/sb/20px-neo.png
new file mode 100644
index 0000000..bab8738
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-neo.png 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
index b582db7..9c2e8bf 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-od-bel.png and b/com/aelitis/azureus/ui/images/sb/20px-od-bel.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-other.png b/com/aelitis/azureus/ui/images/sb/20px-other.png
index 45357f7..18e7fb2 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-other.png and b/com/aelitis/azureus/ui/images/sb/20px-other.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-ps3.png b/com/aelitis/azureus/ui/images/sb/20px-ps3.png
index 9706ef6..62135e2 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-ps3.png and b/com/aelitis/azureus/ui/images/sb/20px-ps3.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-psp.png b/com/aelitis/azureus/ui/images/sb/20px-psp.png
index 4a37087..472bfc8 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-psp.png and b/com/aelitis/azureus/ui/images/sb/20px-psp.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-sam.png b/com/aelitis/azureus/ui/images/sb/20px-sam.png
new file mode 100644
index 0000000..44da6b1
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-sam.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-tivo.png b/com/aelitis/azureus/ui/images/sb/20px-tivo.png
index 573b8a8..e0ff6b5 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-tivo.png and b/com/aelitis/azureus/ui/images/sb/20px-tivo.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-upnp.png b/com/aelitis/azureus/ui/images/sb/20px-upnp.png
new file mode 100644
index 0000000..9a39bb0
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-upnp.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-usb.png b/com/aelitis/azureus/ui/images/sb/20px-usb.png
new file mode 100644
index 0000000..2f5c057
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-usb.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-wdtv.png b/com/aelitis/azureus/ui/images/sb/20px-wdtv.png
new file mode 100644
index 0000000..221c1e2
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/20px-wdtv.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-wii.png b/com/aelitis/azureus/ui/images/sb/20px-wii.png
index c21c0cc..d1ec8e0 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-wii.png and b/com/aelitis/azureus/ui/images/sb/20px-wii.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/20px-xbox.png b/com/aelitis/azureus/ui/images/sb/20px-xbox.png
index c2a13d3..9177048 100644
Binary files a/com/aelitis/azureus/ui/images/sb/20px-xbox.png and b/com/aelitis/azureus/ui/images/sb/20px-xbox.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/alltransfers.png b/com/aelitis/azureus/ui/images/sb/alltransfers.png
new file mode 100644
index 0000000..fc8ea35
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/alltransfers.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/alltransfers_selected.png b/com/aelitis/azureus/ui/images/sb/alltransfers_selected.png
new file mode 100644
index 0000000..c6a8664
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/alltransfers_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/android_icon_20x20.png b/com/aelitis/azureus/ui/images/sb/android_icon_20x20.png
new file mode 100644
index 0000000..6a295ca
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/android_icon_20x20.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/boxee.png b/com/aelitis/azureus/ui/images/sb/boxee.png
new file mode 100644
index 0000000..c89c8a3
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/boxee.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/close.png b/com/aelitis/azureus/ui/images/sb/close.png
new file mode 100644
index 0000000..2c2aa0d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/close.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/close_selected.png b/com/aelitis/azureus/ui/images/sb/close_selected.png
new file mode 100644
index 0000000..7c57cdf
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/close_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/devices.png b/com/aelitis/azureus/ui/images/sb/devices.png
new file mode 100644
index 0000000..67082c7
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/devices.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/devices_selected.png b/com/aelitis/azureus/ui/images/sb/devices_selected.png
new file mode 100644
index 0000000..febddcb
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/devices_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/downloading.png b/com/aelitis/azureus/ui/images/sb/downloading.png
new file mode 100644
index 0000000..5732308
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/downloading.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/downloading_selected.png b/com/aelitis/azureus/ui/images/sb/downloading_selected.png
new file mode 100644
index 0000000..7e9ce21
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/downloading_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/downloadingspin.png b/com/aelitis/azureus/ui/images/sb/downloadingspin.png
new file mode 100644
index 0000000..f8cd237
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/downloadingspin.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/downloadingspin_selected.png b/com/aelitis/azureus/ui/images/sb/downloadingspin_selected.png
new file mode 100644
index 0000000..e20f21e
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/downloadingspin_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/dvd.png b/com/aelitis/azureus/ui/images/sb/dvd.png
new file mode 100644
index 0000000..b9a3aa5
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/dvd.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/dvd_disc.png b/com/aelitis/azureus/ui/images/sb/dvd_disc.png
new file mode 100644
index 0000000..1889f79
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/dvd_disc.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/dvd_disc_selected.png b/com/aelitis/azureus/ui/images/sb/dvd_disc_selected.png
new file mode 100644
index 0000000..c2df494
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/dvd_disc_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/dvd_selected.png b/com/aelitis/azureus/ui/images/sb/dvd_selected.png
new file mode 100644
index 0000000..49fcca5
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/dvd_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/file.png b/com/aelitis/azureus/ui/images/sb/file.png
new file mode 100644
index 0000000..428a5bd
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/file.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/file_selected.png b/com/aelitis/azureus/ui/images/sb/file_selected.png
new file mode 100644
index 0000000..8fb2982
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/file_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/gettingstarted.png b/com/aelitis/azureus/ui/images/sb/gettingstarted.png
new file mode 100644
index 0000000..23ada43
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/gettingstarted.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/gettingstarted_selected.png b/com/aelitis/azureus/ui/images/sb/gettingstarted_selected.png
new file mode 100644
index 0000000..97470cb
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/gettingstarted_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/hd.png b/com/aelitis/azureus/ui/images/sb/hd.png
new file mode 100644
index 0000000..e29578d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/hd.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/hd_selected.png b/com/aelitis/azureus/ui/images/sb/hd_selected.png
new file mode 100644
index 0000000..897262c
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/hd_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_activity.png b/com/aelitis/azureus/ui/images/sb/ic_activity.png
deleted file mode 100644
index 5d20590..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_activity.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_add.png b/com/aelitis/azureus/ui/images/sb/ic_add.png
index bb9e9f7..1b4688d 100644
Binary files a/com/aelitis/azureus/ui/images/sb/ic_add.png and b/com/aelitis/azureus/ui/images/sb/ic_add.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_device.png b/com/aelitis/azureus/ui/images/sb/ic_device.png
deleted file mode 100644
index ee8946d..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_device.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_device_int.png b/com/aelitis/azureus/ui/images/sb/ic_device_int.png
index d6c4d38..1f5e942 100644
Binary files a/com/aelitis/azureus/ui/images/sb/ic_device_int.png and b/com/aelitis/azureus/ui/images/sb/ic_device_int.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_games.png b/com/aelitis/azureus/ui/images/sb/ic_games.png
new file mode 100644
index 0000000..e4800df
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/ic_games.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_games_selected.png b/com/aelitis/azureus/ui/images/sb/ic_games_selected.png
new file mode 100644
index 0000000..d265b14
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/ic_games_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_info.png b/com/aelitis/azureus/ui/images/sb/ic_info.png
index 3f61491..384ce91 100644
Binary files a/com/aelitis/azureus/ui/images/sb/ic_info.png and b/com/aelitis/azureus/ui/images/sb/ic_info.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_library.png b/com/aelitis/azureus/ui/images/sb/ic_library.png
deleted file mode 100644
index dcbe475..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_library.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_logview.png b/com/aelitis/azureus/ui/images/sb/ic_logview.png
new file mode 100644
index 0000000..3471854
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/ic_logview.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_rss.png b/com/aelitis/azureus/ui/images/sb/ic_rss.png
deleted file mode 100644
index 42887e0..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_rss.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_search.png b/com/aelitis/azureus/ui/images/sb/ic_search.png
deleted file mode 100644
index 1a1df7b..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_search.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_search_selected.png b/com/aelitis/azureus/ui/images/sb/ic_search_selected.png
deleted file mode 100644
index 943c9a9..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_search_selected.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_vuze.png b/com/aelitis/azureus/ui/images/sb/ic_vuze.png
deleted file mode 100644
index eca4008..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_vuze.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_welcome.png b/com/aelitis/azureus/ui/images/sb/ic_welcome.png
deleted file mode 100644
index 852b941..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_welcome.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_x_over.png b/com/aelitis/azureus/ui/images/sb/ic_x_over.png
deleted file mode 100644
index ee99803..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_x_over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_x_selected.png b/com/aelitis/azureus/ui/images/sb/ic_x_selected.png
deleted file mode 100644
index c238e4f..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_x_selected.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/ic_x_selected_over.png b/com/aelitis/azureus/ui/images/sb/ic_x_selected_over.png
deleted file mode 100644
index b2b0233..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/ic_x_selected_over.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon.png b/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon.png
new file mode 100644
index 0000000..26650c4
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon_selected.png b/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon_selected.png
new file mode 100644
index 0000000..fb1855e
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/left_nav_create_dvd_icon_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/left_nav_dvd_icon.png b/com/aelitis/azureus/ui/images/sb/left_nav_dvd_icon.png
new file mode 100644
index 0000000..61f7fd1
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/left_nav_dvd_icon.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/notifications.png b/com/aelitis/azureus/ui/images/sb/notifications.png
new file mode 100644
index 0000000..f47a8fb
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/notifications.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/notifications_selected.png b/com/aelitis/azureus/ui/images/sb/notifications_selected.png
new file mode 100644
index 0000000..65658f9
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/notifications_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/plugin.png b/com/aelitis/azureus/ui/images/sb/plugin.png
new file mode 100644
index 0000000..863ead7
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/plugin.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/plugin_selected.png b/com/aelitis/azureus/ui/images/sb/plugin_selected.png
new file mode 100644
index 0000000..afbd3a6
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/plugin_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/plus.png b/com/aelitis/azureus/ui/images/sb/plus.png
new file mode 100644
index 0000000..dd4ab6a
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/plus.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/plus_selected.png b/com/aelitis/azureus/ui/images/sb/plus_selected.png
new file mode 100644
index 0000000..dff7b26
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/plus_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/search.png b/com/aelitis/azureus/ui/images/sb/search.png
new file mode 100644
index 0000000..00fea8d
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/search.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/search_selected.png b/com/aelitis/azureus/ui/images/sb/search_selected.png
new file mode 100644
index 0000000..b61b749
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/search_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/subscriptions.png b/com/aelitis/azureus/ui/images/sb/subscriptions.png
new file mode 100644
index 0000000..c281983
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/subscriptions.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/subscriptions_selected.png b/com/aelitis/azureus/ui/images/sb/subscriptions_selected.png
new file mode 100644
index 0000000..e606595
Binary files /dev/null and b/com/aelitis/azureus/ui/images/sb/subscriptions_selected.png differ
diff --git a/com/aelitis/azureus/ui/images/sb/vitality_lft.png b/com/aelitis/azureus/ui/images/sb/vitality_lft.png
deleted file mode 100644
index c47a8ee..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/vitality_lft.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/vitality_mid.png b/com/aelitis/azureus/ui/images/sb/vitality_mid.png
deleted file mode 100644
index 7cf25d7..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/vitality_mid.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/sb/vitality_rgt.png b/com/aelitis/azureus/ui/images/sb/vitality_rgt.png
deleted file mode 100644
index 0fa94f4..0000000
Binary files a/com/aelitis/azureus/ui/images/sb/vitality_rgt.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/separator.gif b/com/aelitis/azureus/ui/images/separator.gif
deleted file mode 100644
index 5e6e085..0000000
Binary files a/com/aelitis/azureus/ui/images/separator.gif and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/subscription_icon.png b/com/aelitis/azureus/ui/images/subscription_icon.png
new file mode 100644
index 0000000..54f734f
Binary files /dev/null and b/com/aelitis/azureus/ui/images/subscription_icon.png differ
diff --git a/com/aelitis/azureus/ui/images/subscription_icon_1616.png b/com/aelitis/azureus/ui/images/subscription_icon_1616.png
new file mode 100644
index 0000000..c8213d3
Binary files /dev/null and b/com/aelitis/azureus/ui/images/subscription_icon_1616.png differ
diff --git a/com/aelitis/azureus/ui/images/subscription_icon_column_hdr.png b/com/aelitis/azureus/ui/images/subscription_icon_column_hdr.png
new file mode 100644
index 0000000..091d100
Binary files /dev/null and b/com/aelitis/azureus/ui/images/subscription_icon_column_hdr.png differ
diff --git a/com/aelitis/azureus/ui/images/subscription_icon_inactive.png b/com/aelitis/azureus/ui/images/subscription_icon_inactive.png
new file mode 100644
index 0000000..fa75186
Binary files /dev/null and b/com/aelitis/azureus/ui/images/subscription_icon_inactive.png differ
diff --git a/com/aelitis/azureus/ui/images/success.png b/com/aelitis/azureus/ui/images/success.png
new file mode 100644
index 0000000..82c3413
Binary files /dev/null and b/com/aelitis/azureus/ui/images/success.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/2nd.png b/com/aelitis/azureus/ui/images/tb/2nd.png
new file mode 100644
index 0000000..86db854
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/2nd.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/2nd.png b/com/aelitis/azureus/ui/images/tb/c/2nd.png
new file mode 100644
index 0000000..86db854
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/2nd.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/sec_l_l.png b/com/aelitis/azureus/ui/images/tb/c/sec_l_l.png
new file mode 100644
index 0000000..1c17aab
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/sec_l_l.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/sec_m.png b/com/aelitis/azureus/ui/images/tb/c/sec_m.png
new file mode 100644
index 0000000..ea7d3d3
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/sec_m.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/sec_r_r.png b/com/aelitis/azureus/ui/images/tb/c/sec_r_r.png
new file mode 100644
index 0000000..19d68e8
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/sec_r_r.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_l_l.png b/com/aelitis/azureus/ui/images/tb/c/view_l_l.png
new file mode 100644
index 0000000..a37bbb7
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_l_l.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_l_m.png b/com/aelitis/azureus/ui/images/tb/c/view_l_m.png
new file mode 100644
index 0000000..aeccf8c
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_l_m.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_l_r.png b/com/aelitis/azureus/ui/images/tb/c/view_l_r.png
new file mode 100644
index 0000000..c79b0bb
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_l_r.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_r_l.png b/com/aelitis/azureus/ui/images/tb/c/view_r_l.png
new file mode 100644
index 0000000..b748aa0
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_r_l.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_r_m.png b/com/aelitis/azureus/ui/images/tb/c/view_r_m.png
new file mode 100644
index 0000000..cc5b0b8
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_r_m.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/c/view_r_r.png b/com/aelitis/azureus/ui/images/tb/c/view_r_r.png
new file mode 100644
index 0000000..9e775ee
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/c/view_r_r.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/download_disabled.png b/com/aelitis/azureus/ui/images/tb/download_disabled.png
deleted file mode 100644
index 076ce28..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/download_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_delete.png b/com/aelitis/azureus/ui/images/tb/ic_delete.png
deleted file mode 100644
index 882eb5b..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_delete.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_delete_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_delete_disabled.png
deleted file mode 100644
index 2ebf6ff..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_delete_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_device.png b/com/aelitis/azureus/ui/images/tb/ic_device.png
deleted file mode 100644
index ea1b095..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_device.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_down.png b/com/aelitis/azureus/ui/images/tb/ic_down.png
deleted file mode 100644
index a49ab29..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_down.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_down_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_down_disabled.png
deleted file mode 100644
index c16bca7..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_down_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_launch.png b/com/aelitis/azureus/ui/images/tb/ic_launch.png
deleted file mode 100644
index 2bef75b..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_launch.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_launch_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_launch_disabled.png
deleted file mode 100644
index edb3c12..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_launch_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_start.png b/com/aelitis/azureus/ui/images/tb/ic_start.png
deleted file mode 100644
index cf4c1a0..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_start.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_start_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_start_disabled.png
deleted file mode 100644
index 6435252..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_start_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_stop.png b/com/aelitis/azureus/ui/images/tb/ic_stop.png
deleted file mode 100644
index 0f079e2..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_stop.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_stop_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_stop_disabled.png
deleted file mode 100644
index 821e9d0..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_stop_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_up.png b/com/aelitis/azureus/ui/images/tb/ic_up.png
deleted file mode 100644
index cc7d382..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_up.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/ic_up_disabled.png b/com/aelitis/azureus/ui/images/tb/ic_up_disabled.png
deleted file mode 100644
index 925e3dc..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/ic_up_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/play_disabled.png b/com/aelitis/azureus/ui/images/tb/play_disabled.png
deleted file mode 100644
index b6d3350..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/play_disabled.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/play_now_plus.png b/com/aelitis/azureus/ui/images/tb/play_now_plus.png
new file mode 100644
index 0000000..9780b47
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/play_now_plus.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/play_now_plus_down.png b/com/aelitis/azureus/ui/images/tb/play_now_plus_down.png
new file mode 100644
index 0000000..6d18d45
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/play_now_plus_down.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/spacer.png b/com/aelitis/azureus/ui/images/tb/spacer.png
deleted file mode 100644
index 288f592..0000000
Binary files a/com/aelitis/azureus/ui/images/tb/spacer.png and /dev/null differ
diff --git a/com/aelitis/azureus/ui/images/tb/stream.png b/com/aelitis/azureus/ui/images/tb/stream.png
new file mode 100644
index 0000000..62f5831
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/stream.png differ
diff --git a/com/aelitis/azureus/ui/images/tb/stream_down.png b/com/aelitis/azureus/ui/images/tb/stream_down.png
new file mode 100644
index 0000000..5deb4fc
Binary files /dev/null and b/com/aelitis/azureus/ui/images/tb/stream_down.png differ
diff --git a/com/aelitis/azureus/ui/images/upload_arrow.png b/com/aelitis/azureus/ui/images/upload_arrow.png
new file mode 100644
index 0000000..7bd599b
Binary files /dev/null and b/com/aelitis/azureus/ui/images/upload_arrow.png differ
diff --git a/com/aelitis/azureus/ui/images/vp_header.png b/com/aelitis/azureus/ui/images/vp_header.png
new file mode 100644
index 0000000..129346b
Binary files /dev/null and b/com/aelitis/azureus/ui/images/vp_header.png differ
diff --git a/com/aelitis/azureus/ui/images/warning.png b/com/aelitis/azureus/ui/images/warning.png
new file mode 100644
index 0000000..735d6a5
Binary files /dev/null and b/com/aelitis/azureus/ui/images/warning.png differ
diff --git a/com/aelitis/azureus/ui/mdi/MdiChildCloseListener.java b/com/aelitis/azureus/ui/mdi/MdiChildCloseListener.java
new file mode 100644
index 0000000..3f32807
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiChildCloseListener.java
@@ -0,0 +1,30 @@
+/**
+ * Created on Nov 16, 2010
+ *
+ * Copyright 2010 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.mdi;
+
+/**
+ * @author TuxPaper
+ * @created Nov 16, 2010
+ *
+ */
+public interface MdiChildCloseListener
+{
+	public void mdiChildEntryClosed(MdiEntry parent, MdiEntry child,
+			boolean user);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiCloseListener.java b/com/aelitis/azureus/ui/mdi/MdiCloseListener.java
new file mode 100644
index 0000000..f4e060b
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiCloseListener.java
@@ -0,0 +1,31 @@
+/**
+ * Created on Sep 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.ui.mdi;
+
+
+public interface MdiCloseListener
+{
+	/**
+	 * Triggered when a {@link MdiEntry} is closed
+	 * 
+	 * @param entry {@link MdiEntry} that is closed
+	 * @param userClosed true if the user closed the entry; false if programmically closed (App close)
+	 */
+	public void mdiEntryClosed(MdiEntry entry, boolean userClosed);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntry.java b/com/aelitis/azureus/ui/mdi/MdiEntry.java
new file mode 100644
index 0000000..5fba93b
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntry.java
@@ -0,0 +1,154 @@
+/**
+ * Created on Aug 13, 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.mdi;
+
+import org.gudy.azureus2.plugins.ui.UIPluginView;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarEnablerBase;
+
+import com.aelitis.azureus.ui.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+
+
+/**
+ * @author TuxPaper
+ * @created Aug 13, 2008
+ *
+ */
+public interface MdiEntry
+{
+
+	public String getParentID();
+
+	public Object getDatasource();
+
+	public boolean isCloseable();
+
+	public Class<? extends UIPluginView> getViewClass();
+
+	public UIPluginView getView();
+
+	public String getId();
+
+	public MdiEntryVitalityImage addVitalityImage(String imageID);
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.1.0.3
+	 */
+	void addListener(MdiCloseListener l);
+
+	void addListener(MdiChildCloseListener l);
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.1.0.3
+	 */
+	void removeListener(MdiCloseListener l);
+
+	void removeListener(MdiChildCloseListener l);
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.1.0.3
+	 */
+	void addListener(MdiEntryOpenListener l);
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.1.0.3
+	 */
+	void removeListener(MdiEntryOpenListener l);
+
+	public void setImageLeftID(String string);
+
+	public void setCollapseDisabled(boolean b);
+
+	public void addListener(MdiEntryDropListener listener);
+
+	public void setDatasource(Object ds);
+
+	public void setLogID(String logID);
+
+	public boolean isAdded();
+
+	public boolean isDisposed();
+
+	public ViewTitleInfo getViewTitleInfo();
+
+	public void setViewTitleInfo(ViewTitleInfo viewTitleInfo);
+
+	public String getLogID();
+
+	public MultipleDocumentInterface getMDI();
+
+	public MdiEntryVitalityImage[] getVitalityImages();
+
+	public boolean close(boolean forceClose);
+
+	public void updateUI();
+
+	public void redraw();
+
+	public void addListener(MdiEntryLogIdListener l);
+
+	public void removeListener(MdiEntryLogIdListener l);
+
+	public void hide();
+
+	public String getTitle();
+	
+	public void setTitle(String title);
+
+	public void setTitleID(String titleID);
+
+	public String getImageLeftID();
+
+	public boolean isExpanded();
+
+	public void setExpanded(boolean expanded);
+	
+	public void setDefaultExpanded(boolean defaultExpanded);
+	
+	public void expandTo();
+
+	public void setParentID(String id);
+
+	public UIToolBarEnablerBase[] getToolbarEnablers();
+
+	/**
+	 * @deprecated For azburn
+	 */
+	public void addToolbarEnabler(ToolBarEnabler enabler);
+
+	public void addToolbarEnabler(UIToolBarEnablerBase enabler);
+
+	public void removeToolbarEnabler(UIToolBarEnablerBase enabler);
+
+	public boolean isSelectable();
+
+	public void setSelectable(boolean selectable);
+
+	public void setPreferredAfterID(String preferredAfterID);
+
+	public String getPreferredAfterID();
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryCreationListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryCreationListener.java
new file mode 100644
index 0000000..2b03c20
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryCreationListener.java
@@ -0,0 +1,6 @@
+package com.aelitis.azureus.ui.mdi;
+
+public interface MdiEntryCreationListener
+{
+	public MdiEntry createMDiEntry(String id);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryDropListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryDropListener.java
new file mode 100644
index 0000000..c94a8c2
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryDropListener.java
@@ -0,0 +1,34 @@
+/**
+ * Created on Feb 13, 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.mdi;
+
+
+/**
+ * @author TuxPaper
+ * @created Feb 13, 2009
+ */
+public interface MdiEntryDropListener
+{
+	/**
+	 * @param entry
+	 * @param droppedObject
+	 * @return true if you handled it, false if you didn't
+	 */
+	public boolean mdiEntryDrop(MdiEntry entry, Object droppedObject);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryLoadedListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryLoadedListener.java
new file mode 100644
index 0000000..41a9eea
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryLoadedListener.java
@@ -0,0 +1,29 @@
+/**
+ * Created on Nov 17, 2010
+ *
+ * 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.mdi;
+
+
+/**
+ * @author TuxPaper
+ * @created Nov 17, 2010
+ */
+public interface MdiEntryLoadedListener
+{
+	public void mdiEntryLoaded(MdiEntry entry);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryLogIdListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryLogIdListener.java
new file mode 100644
index 0000000..1d2b512
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryLogIdListener.java
@@ -0,0 +1,30 @@
+/**
+ * Created on Nov 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.mdi;
+
+
+/**
+ * @author TuxPaper
+ * @created Nov 6, 2008
+ *
+ */
+public interface MdiEntryLogIdListener
+{
+	void mdiEntryLogIdChanged(MdiEntry mdiEntry, String oldID, String newID);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryOpenListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryOpenListener.java
new file mode 100644
index 0000000..2a6c7f2
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryOpenListener.java
@@ -0,0 +1,29 @@
+/**
+ * Created on Dec 3, 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.mdi;
+
+
+/**
+ * @author TuxPaper
+ * @created Dec 3, 2008
+ */
+public interface MdiEntryOpenListener
+{
+	public void mdiEntryOpen(MdiEntry entry);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImage.java b/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImage.java
new file mode 100644
index 0000000..1ec9678
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImage.java
@@ -0,0 +1,48 @@
+/**
+ * Created on Sep 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.mdi;
+
+
+/**
+ * @author TuxPaper
+ * @created Sep 15, 2008
+ */
+public interface MdiEntryVitalityImage
+{
+	public String getImageID();
+
+	public void setImageID(String id );
+	
+	public MdiEntry getMdiEntry();
+	
+	public void addListener(MdiEntryVitalityImageListener l);
+	
+	// Should really be ID
+	public void setToolTip(String tooltip);
+	
+	public void setVisible(boolean visible);
+	
+	public boolean isVisible();
+
+	public void triggerClickedListeners(int x, int y);
+
+	public int getAlignment();
+	
+	public void setAlignment(int a);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImageListener.java b/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImageListener.java
new file mode 100644
index 0000000..4722b57
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiEntryVitalityImageListener.java
@@ -0,0 +1,29 @@
+/**
+ * Created on Sep 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.mdi;
+
+/**
+ * @author TuxPaper
+ * @created Sep 15, 2008
+ *
+ */
+public interface MdiEntryVitalityImageListener
+{
+	public void mdiEntryVitalityImage_clicked(int x, int y);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MdiListener.java b/com/aelitis/azureus/ui/mdi/MdiListener.java
new file mode 100644
index 0000000..051ea97
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MdiListener.java
@@ -0,0 +1,32 @@
+/**
+ * Created on Jul 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.ui.mdi;
+
+
+
+/**
+ * @author TuxPaper
+ * @created Jul 17, 2008
+ *
+ */
+public interface MdiListener
+{
+	public void mdiEntrySelected(MdiEntry newEntry,
+			MdiEntry oldEntry);
+}
diff --git a/com/aelitis/azureus/ui/mdi/MultipleDocumentInterface.java b/com/aelitis/azureus/ui/mdi/MultipleDocumentInterface.java
new file mode 100644
index 0000000..ba88647
--- /dev/null
+++ b/com/aelitis/azureus/ui/mdi/MultipleDocumentInterface.java
@@ -0,0 +1,107 @@
+package com.aelitis.azureus.ui.mdi;
+
+import java.util.List;
+import java.util.Map;
+
+import org.gudy.azureus2.plugins.ui.UIPluginView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+
+public interface MultipleDocumentInterface
+{
+	public static final String SIDEBAR_POS_FIRST = "";
+
+	public static final String SIDEBAR_HEADER_VUZE = "header.vuze";
+
+	public static final String SIDEBAR_HEADER_TRANSFERS = "header.transfers";
+
+	public static final String SIDEBAR_HEADER_DEVICES = "header.devices";
+
+	public static final String SIDEBAR_HEADER_DVD = "header.dvd";
+
+	public static final String SIDEBAR_HEADER_SUBSCRIPTIONS = "header.subscriptions";
+
+	public static final String SIDEBAR_HEADER_PLUGINS = "header.plugins";
+
+	public static final String SIDEBAR_SECTION_PLUGINS = "Plugins";
+
+	public static final String SIDEBAR_SECTION_ABOUTPLUGINS = "About.Plugins";
+
+	public static final String SIDEBAR_SECTION_LIBRARY = "Library";
+
+	public static final String SIDEBAR_SECTION_GAMES = "Games";
+
+	public static final String SIDEBAR_SECTION_BETAPROGRAM = "BetaProgramme";
+
+	public static final String SIDEBAR_SECTION_LIBRARY_DL = "LibraryDL";
+
+	public static final String SIDEBAR_SECTION_LIBRARY_CD = "LibraryCD";
+
+	public static final String SIDEBAR_SECTION_LIBRARY_UNOPENED = "LibraryUnopened";
+
+	public static final String SIDEBAR_SECTION_WELCOME = "Welcome";
+
+	public static final String SIDEBAR_SECTION_PLUS = "Plus";
+
+	public static final String SIDEBAR_SECTION_SUBSCRIPTIONS = "Subscriptions";
+
+	public static final String SIDEBAR_SECTION_DEVICES = "Devices";
+
+	public static final String SIDEBAR_SECTION_BURN_INFO = "BurnInfo";
+
+	public static final String SIDEBAR_SECTION_ACTIVITIES = "Activity";
+
+	public boolean showEntryByID(String id);
+
+	public MdiEntry createEntryFromSkinRef(String parentID, String id,
+			String configID, String title, ViewTitleInfo titleInfo, Object params,
+			boolean closeable, String preferedAfterID);
+
+	public MdiEntry createEntryFromEventListener(String parentID,
+			UISWTViewEventListener l, String id, boolean closeable, Object datasource);
+
+	public MdiEntry getCurrentEntry();
+
+	public MdiEntry getEntry(String id);
+
+	public void addListener(MdiListener l);
+
+	public void removeListener(MdiListener l);
+
+	public void addListener(MdiEntryLoadedListener l);
+
+	public void removeListener(MdiEntryLoadedListener l);
+
+	public boolean isVisible();
+
+	public void closeEntry(String id);
+
+	public MdiEntry[] getEntries();
+
+	public void registerEntry(String id, MdiEntryCreationListener l);
+
+	public boolean entryExists(String id);
+
+	public void removeItem(MdiEntry entry);
+
+	public void setEntryAutoOpen(String id, Object datasource, boolean autoOpen);
+
+	public void showEntry(MdiEntry newEntry);
+
+	public void informAutoOpenSet(MdiEntry entry, Map<String, Object> autoOpenInfo);
+
+	public boolean loadEntryByID(String id, boolean activate);
+
+	public void setPreferredOrder(String[] preferredOrder);
+
+	public String[] getPreferredOrder();
+
+	public MdiEntry createHeader(String id, String title, String preferredAfterID);
+
+	public List<MdiEntry> getChildrenOf(String id);
+
+	public boolean loadEntryByID(String id, boolean activate,
+			boolean onlyLoadOnce, Object datasource);
+
+}
diff --git a/com/aelitis/azureus/ui/selectedcontent/DownloadUrlInfo.java b/com/aelitis/azureus/ui/selectedcontent/DownloadUrlInfo.java
index efaffd9..bdf6165 100644
--- a/com/aelitis/azureus/ui/selectedcontent/DownloadUrlInfo.java
+++ b/com/aelitis/azureus/ui/selectedcontent/DownloadUrlInfo.java
@@ -37,6 +37,8 @@ public class DownloadUrlInfo
 
 	private Map additionalProperties = null;
 
+		// add more fields here -> amend sameAs below
+	
 	/**
 	 * @param url
 	 */
@@ -106,4 +108,37 @@ public class DownloadUrlInfo
 	public Map getAdditionalProperties() {
 		return additionalProperties;
 	}
+	
+	private boolean
+	objectEquals(
+		Object	o1,
+		Object	o2 )
+	{
+		if ( o1 != o2 ){
+			
+			if ( 	o1 == null ||
+					o2 == null ||
+					!o1.equals( o2 )){
+				
+				return( false );
+			}
+		}
+		
+		return( true );
+	}
+	
+	public boolean
+	sameAs(
+		DownloadUrlInfo	other )
+	{
+		if ( other == this ){
+			
+			return( true );
+		}
+		
+		return( objectEquals( dlURL, other.dlURL ) &&
+				objectEquals( referer, other.referer ) &&
+				objectEquals( requestProperties, other.requestProperties ) &&
+				objectEquals( additionalProperties, other.additionalProperties ));
+	}
 }
diff --git a/com/aelitis/azureus/ui/selectedcontent/ISelectedContent.java b/com/aelitis/azureus/ui/selectedcontent/ISelectedContent.java
index a40cd2f..5847b0f 100644
--- a/com/aelitis/azureus/ui/selectedcontent/ISelectedContent.java
+++ b/com/aelitis/azureus/ui/selectedcontent/ISelectedContent.java
@@ -29,29 +29,34 @@ import org.gudy.azureus2.core3.torrent.TOTorrent;
 public interface ISelectedContent
 {
 
-	public abstract String getHash();
+	public String getHash();
 
-	public abstract void setHash(String hash);
+	public void setHash(String hash);
 
-	public abstract DownloadManager getDownloadManager();
+	public DownloadManager getDownloadManager();
 
-	public abstract void setDownloadManager(DownloadManager dm);
+	public int getFileIndex(); 
+		
+	public void setDownloadManager(DownloadManager dm);
 
-	public abstract TOTorrent getTorrent();
+	public TOTorrent getTorrent();
 	
 	public void setTorrent( TOTorrent torrent );
 	
-	public abstract String getDisplayName();
+	public String getDisplayName();
 
-	public abstract void setDisplayName(String displayName);
+	public void setDisplayName(String displayName);
 
 	/**
 	 * @since 3.1.1.1
 	 */
-	public abstract DownloadUrlInfo getDownloadInfo();
+	public DownloadUrlInfo getDownloadInfo();
 
 	/**
 	 * @since 3.1.1.1
 	 */
-	public abstract void setDownloadInfo(DownloadUrlInfo downloadInfo);
+	public void setDownloadInfo(DownloadUrlInfo downloadInfo);
+	
+	public boolean
+	sameAs( ISelectedContent other );
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/selectedcontent/SelectedContent.java b/com/aelitis/azureus/ui/selectedcontent/SelectedContent.java
index 77db9e4..1aaf7c2 100644
--- a/com/aelitis/azureus/ui/selectedcontent/SelectedContent.java
+++ b/com/aelitis/azureus/ui/selectedcontent/SelectedContent.java
@@ -39,12 +39,15 @@ public class SelectedContent implements ISelectedContent
 	private String hash;
 
 	private DownloadManager dm;
+	private int				file_index = -1;
 	private TOTorrent		torrent;
 
 	private String displayName;
 	
 	private DownloadUrlInfo downloadInfo;
 
+		// add more fields and you need to amend sameAs below
+	
 	/**
 	 * @param dm2
 	 * @throws Exception 
@@ -53,6 +56,11 @@ public class SelectedContent implements ISelectedContent
 		setDownloadManager(dm);
 	}
 
+	public SelectedContent(DownloadManager dm, int _file_index ){
+		setDownloadManager(dm);
+		file_index = _file_index;
+	}
+	
 	/**
 	 * 
 	 */
@@ -96,6 +104,9 @@ public class SelectedContent implements ISelectedContent
 		}
 	}
 
+	public int getFileIndex() {
+		return file_index;
+	}
 	
 	public TOTorrent getTorrent() {
 		return( torrent );
@@ -132,4 +143,55 @@ public class SelectedContent implements ISelectedContent
 	public void setDownloadInfo(DownloadUrlInfo info) {
 		this.downloadInfo = info;
 	}
+		
+	public boolean 
+	sameAs(
+		ISelectedContent _other )
+	{
+		if ( _other instanceof SelectedContent ){
+			
+			SelectedContent other = (SelectedContent)_other;
+		
+			if ( hash != other.hash ){
+				
+				if ( 	hash == null ||
+						other.hash == null ||
+						!hash.equals( other.hash )){
+					
+					return( false );
+				}
+			}
+			
+			if ( 	dm != other.dm ||
+					torrent	!= other.torrent || 
+					file_index != other.file_index ){
+				
+				return( false );
+			}
+			
+			if ( displayName != other.displayName ){
+				
+				if ( 	displayName == null ||
+						other.displayName == null ||
+						!displayName.equals( other.displayName )){
+					
+					return( false );
+				}
+			}
+			
+			if ( downloadInfo != other.downloadInfo ){
+				
+				if ( 	downloadInfo == null ||
+						other.downloadInfo == null ||
+						!downloadInfo.sameAs( other.downloadInfo )){
+					
+					return( false );
+				}
+			}
+			
+			return( true );
+		}
+		
+		return( false );
+	}
 }
diff --git a/com/aelitis/azureus/ui/selectedcontent/SelectedContentManager.java b/com/aelitis/azureus/ui/selectedcontent/SelectedContentManager.java
index 5fc7e4f..4daff89 100644
--- a/com/aelitis/azureus/ui/selectedcontent/SelectedContentManager.java
+++ b/com/aelitis/azureus/ui/selectedcontent/SelectedContentManager.java
@@ -18,11 +18,12 @@
 
 package com.aelitis.azureus.ui.selectedcontent;
 
-import java.util.ArrayList;
-import java.util.List;
-
 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.pluginsimpl.local.PluginCoreUtils;
 
+import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.ui.common.table.TableView;
 
 /**
@@ -34,7 +35,7 @@ import com.aelitis.azureus.ui.common.table.TableView;
  */
 public class SelectedContentManager
 {
-	private static List listeners = new ArrayList();
+	private static CopyOnWriteList<SelectedContentListener> listeners = new CopyOnWriteList<SelectedContentListener>();
 
 	private static ISelectedContent[] currentlySelectedContent = new ISelectedContent[0];
 
@@ -53,7 +54,11 @@ public class SelectedContentManager
 	}
 
 	public static void clearCurrentlySelectedContent() {
-		changeCurrentlySelectedContent(null, null, null);
+		changeCurrentlySelectedContentNoTrigger(null, null, null);
+		// Always trigger selected content listeners since toolbar relies it
+		// them to reset the toolbaritems if something that didn't use
+		// SelectedContentManager modified the toolbaritems states
+		triggerSelectedContentListeners();
 	}
 
 	public static void changeCurrentlySelectedContent(String viewID,
@@ -63,7 +68,12 @@ public class SelectedContentManager
 
 	public static void changeCurrentlySelectedContent(String viewID,
 			ISelectedContent[] currentlySelectedContent, TableView tv) {
-		SelectedContentManager.tv = tv;
+		changeCurrentlySelectedContentNoTrigger(viewID, currentlySelectedContent, tv);
+		triggerSelectedContentListeners();
+	}
+
+	private static void changeCurrentlySelectedContentNoTrigger(String viewID,
+			ISelectedContent[] currentlySelectedContent, TableView tv) {
 		if (currentlySelectedContent == null) {
 			currentlySelectedContent = new ISelectedContent[0];
 		}
@@ -84,15 +94,50 @@ public class SelectedContentManager
 			return;
 		}
 
-		SelectedContentManager.currentlySelectedContent = currentlySelectedContent == null
-				? new ISelectedContent[0] : currentlySelectedContent;
-		SelectedContentManager.viewID = viewID;
-
-		Object[] listenerArray = listeners.toArray();
-		for (int i = 0; i < listenerArray.length; i++) {
-			SelectedContentListener l = (SelectedContentListener) listenerArray[i];
-			l.currentlySelectedContentChanged(
-					SelectedContentManager.currentlySelectedContent, viewID);
+		synchronized( SelectedContentManager.class ){
+			boolean	same = SelectedContentManager.tv == tv;
+			
+			if ( same ){
+				
+				same = 
+					SelectedContentManager.viewID == viewID ||
+					( 	SelectedContentManager.viewID != null && 
+						viewID != null &&
+						SelectedContentManager.viewID.equals( viewID ));
+				
+				if ( same ){
+					
+					if ( SelectedContentManager.currentlySelectedContent.length == currentlySelectedContent.length ){
+						
+						for ( int i=0;i<currentlySelectedContent.length && same ;i++){
+							
+							same = currentlySelectedContent[i].sameAs( SelectedContentManager.currentlySelectedContent[i]);
+						}
+				
+						if ( same ){
+														
+							return;
+						}
+					}
+				}
+			}
+			
+			SelectedContentManager.tv = tv;
+			SelectedContentManager.currentlySelectedContent = currentlySelectedContent;
+			SelectedContentManager.viewID = viewID;
+		}
+	}
+	
+	public static void triggerSelectedContentListeners() {
+		for( SelectedContentListener l: listeners ){
+	
+			try{
+				l.currentlySelectedContentChanged( currentlySelectedContent, viewID);
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
 		}
 	}
 
@@ -126,4 +171,35 @@ public class SelectedContentManager
 	public static TableView getCurrentlySelectedTableView() {
 		return tv;
 	}
+
+	public static Object convertSelectedContentToObject(ISelectedContent[] contents) {
+		if (contents == null) {
+			contents = getCurrentlySelectedContent();
+		}
+		if (contents.length == 0) {
+			return null;
+		}
+		if (contents.length == 1) {
+			return selectedContentToObject(contents[0]);
+		}
+		Object[] objects = new Object[contents.length];
+		for (int i = 0; i < contents.length; i++) {
+			ISelectedContent content = contents[i];
+			objects[i] = selectedContentToObject(content);
+		}
+		return objects;
+	}
+	
+	private static Object selectedContentToObject(ISelectedContent content) {
+		Download dl = PluginCoreUtils.wrap(content.getDownloadManager());
+		if (dl == null) {
+			return null;
+		}
+		int i = content.getFileIndex();
+		if (i < 0) {
+			return dl;
+		}
+		return dl.getDiskManagerFileInfo(i);
+	}
+	
 }
diff --git a/com/aelitis/azureus/ui/selectedcontent/SelectedContentV3.java b/com/aelitis/azureus/ui/selectedcontent/SelectedContentV3.java
index e71b622..0482d3a 100644
--- a/com/aelitis/azureus/ui/selectedcontent/SelectedContentV3.java
+++ b/com/aelitis/azureus/ui/selectedcontent/SelectedContentV3.java
@@ -20,7 +20,6 @@ package com.aelitis.azureus.ui.selectedcontent;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.core3.torrent.TOTorrentException;
 
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
@@ -48,6 +47,9 @@ public class SelectedContentV3
 	
 	private DownloadUrlInfo downloadInfo;
 
+		// if you add more fields here be sure to amend 'sameAs' logic below
+	
+	
 	public SelectedContentV3(SelectedContent content) {
 		this.content = content;
 		this.setDownloadManager(content.getDownloadManager());
@@ -79,6 +81,9 @@ public class SelectedContentV3
 		return content.getDownloadManager();
 	}
 
+	public int getFileIndex() {
+		return content.getFileIndex();
+	}
 	public TOTorrent getTorrent(){
 		return content.getTorrent();
 	}
@@ -115,7 +120,7 @@ public class SelectedContentV3
 			}
 			setPlatformContent(PlatformTorrentUtils.isContent(torrent, true));
 			setDisplayName(PlatformTorrentUtils.getContentTitle( torrent ));
-			setCanPlay(PlayUtils.canUseEMP(torrent));
+			setCanPlay(PlayUtils.canUseEMP(torrent, -1));
 			setImageBytes(PlatformTorrentUtils.getContentThumbnail(torrent));
 		}
 	}
@@ -178,4 +183,59 @@ public class SelectedContentV3
 	public void setDownloadInfo(DownloadUrlInfo info) {
 		this.downloadInfo = info;
 	}
+	
+	public boolean 
+	sameAs(
+		ISelectedContent _other ) 
+	{
+		if ( _other == this ){
+			
+			return( true );
+		}
+		
+		if ( _other instanceof SelectedContentV3 ){
+			
+			SelectedContentV3 other = (SelectedContentV3)_other;
+			
+			if ( !content.sameAs( other.content )){
+				
+				return( false );
+			}
+			
+			if ( 	isPlatformContent != other.isPlatformContent ||
+					canPlay != other.canPlay ){
+				
+				return( false );
+			}
+			
+			if ( thumbURL != other.thumbURL ){
+				
+				if ( 	thumbURL == null ||
+						other.thumbURL == null ||
+						!thumbURL.equals( other.thumbURL )){
+					
+					return( false );
+				}
+			}
+			
+			if ( imageBytes != other.imageBytes ){
+				
+				return( false );
+			}
+			
+			if ( downloadInfo != other.downloadInfo ){
+				
+				if ( 	downloadInfo == null ||
+						other.downloadInfo == null ||
+						!downloadInfo.sameAs( other.downloadInfo )){
+					
+					return( false );
+				}
+			}
+			
+			return( true );
+		}
+		
+		return( false );
+	}
 }
diff --git a/com/aelitis/azureus/ui/skin/SkinConstants.java b/com/aelitis/azureus/ui/skin/SkinConstants.java
index f885030..5ac514a 100644
--- a/com/aelitis/azureus/ui/skin/SkinConstants.java
+++ b/com/aelitis/azureus/ui/skin/SkinConstants.java
@@ -27,8 +27,6 @@ package com.aelitis.azureus.ui.skin;
  */
 public class SkinConstants
 {
-	public static final String TABSET_DASHBOARD_LEFT = "hometab-left";
-
 	public static final String VIEWID_BROWSER_BROWSE = "browse";
 
 	public static final String VIEWID_BROWSER_SEARCHRESULTS = "searchresults";
@@ -37,28 +35,17 @@ public class SkinConstants
 
 	public static final String VIEWID_TAB_BAR = "tabbar";
 
-	public static final String VIEWID_LIBRARY = "library-area";
-
 	public static final String VIEWID_TOOLBAR = "global-toolbar";
 
-	public static final String VIEWID_SIDEBAR_LIBRARY = "sidebar-library-area";
-
 	public static final String VIEWID_SIDEBAR_LIBRARY_BIG = "library-big-area";
 
 	public static final String VIEWID_SIDEBAR_LIBRARY_SMALL = "library-small-area";
 
-	public static final String VIEWID_SIDEBAR_LIBRARY_OLD = "library-oldtable-area";
-
-	public static final String VIEWID_SIDEBAR_ACTIVITY_PARENT = "sidebar-activity-area";
-
 	public static final String VIEWID_SIDEBAR_ACTIVITY_BIG = "activity-big-area";
 
 	public static final String VIEWID_SIDEBAR_ACTIVITY_SMALL = "activity-small-area";
 
-	public static final String VIEWID_SIDEBAR = "sidebar";
-
-	public static final String VIEWID_LIBRARY_TOOLBAR = "library-list-button-smalltable";
-	public static final String VIEWID_LIBRARY_TOOLBAR_BIG = "library-list-button-bigtable";
+	public static final String VIEWID_MDI = "mdi";
 
 	public static final String VIEWID_BROWSER_WELCOME = "welcome";
 }
diff --git a/com/aelitis/azureus/ui/skin/SkinProperties.java b/com/aelitis/azureus/ui/skin/SkinProperties.java
index ef00351..21aa313 100644
--- a/com/aelitis/azureus/ui/skin/SkinProperties.java
+++ b/com/aelitis/azureus/ui/skin/SkinProperties.java
@@ -103,10 +103,20 @@ public interface SkinProperties
 
 	/**
 	 * @param subBundle
+	 * @param skinPath TODO
 	 *
 	 * @since 4.0.0.5
 	 */
-	void addResourceBundle(ResourceBundle subBundle);
+	void addResourceBundle(ResourceBundle subBundle, String skinPath);
+
+	/**
+	 * @param subBundle
+	 * @param skinPath
+	 * @param loader
+	 * @since 4315
+	 */
+	
+	void addResourceBundle(ResourceBundle subBundle, String skinPath, ClassLoader loader );
 
 	/**
 	 * @return
diff --git a/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java b/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
index 90e62f9..35b5059 100644
--- a/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
+++ b/com/aelitis/azureus/ui/skin/SkinPropertiesImpl.java
@@ -51,7 +51,7 @@ public class SkinPropertiesImpl
 {
 	private static final LogIDs LOGID = LogIDs.UI3;
 
-	private static final String PATH_SKIN_DEFS = "com/aelitis/azureus/ui/skin/";
+	public static final String PATH_SKIN_DEFS = "com/aelitis/azureus/ui/skin/";
 
 	private static final String FILE_SKIN_DEFS = "skin3.properties";
 
@@ -101,10 +101,38 @@ public class SkinPropertiesImpl
 		}
 	}
 	
-	public void addResourceBundle(ResourceBundle subBundle) {
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath) {
+		addResourceBundle( subBundle, skinPath, classLoader );
+	}
+	
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath, ClassLoader loader ) {
 		try {
+			clearCache();
 			rb.addResourceMessages(subBundle);
-  	} catch (Throwable t) {
+
+			try{
+				String sFiles = subBundle.getString("skin.include");
+				
+				if (sFiles != null && skinPath != null) {
+	  			
+					String[] sFilesArray = Constants.PAT_SPLIT_COMMA.split(sFiles);
+					for (int i = 0; i < sFilesArray.length; i++) {
+						String sFile = (sFilesArray[i].startsWith("/")
+								? sFilesArray[i].substring(1) : skinPath + sFilesArray[i]);
+						sFile = sFile.replaceAll("/", ".");
+						try {
+							ResourceBundle incBundle = ResourceBundle.getBundle(sFile,
+									Locale.getDefault(), loader);
+							rb.addResourceMessages(incBundle);
+						} catch (Throwable t) {
+							Debug.out("Err loading skin include: " + sFile, t);
+						}
+					}
+				}
+			}catch( MissingResourceException e ){
+				// get this if skin.include not defined, which is entirely possible
+			}
+		} catch (Throwable t) {
   		Debug.out("Err loading skin include: " + subBundle, t);
   	}
 	}
@@ -246,7 +274,7 @@ public class SkinPropertiesImpl
 	}
 
 	public int[] getColorValue(String name) {
-		int[] colors = new int[3];
+		int[] colors = new int[4];
 		String value = getValue(name, null);
 
 		if (value == null || value.length() == 0 || value.startsWith("COLOR_")) {
@@ -258,14 +286,25 @@ public class SkinPropertiesImpl
 			if (value.charAt(0) == '#') {
 				// hex color string
 				long l = Long.parseLong(value.substring(1), 16);
-				colors[0] = (int) ((l >> 16) & 255);
-				colors[1] = (int) ((l >> 8) & 255);
-				colors[2] = (int) (l & 255);
+				if (value.length() == 9) {
+					colors = new int[] {
+						(int) ((l >> 24) & 255),
+						(int) ((l >> 16) & 255),
+						(int) ((l >> 8) & 255),
+						(int) (l & 255)
+					};
+				} else {
+  				colors[0] = (int) ((l >> 16) & 255);
+  				colors[1] = (int) ((l >> 8) & 255);
+  				colors[2] = (int) (l & 255);
+  				colors[3] = 255;
+				}
 			} else {
 				StringTokenizer st = new StringTokenizer(value, ",");
 				colors[0] = Integer.parseInt(st.nextToken());
 				colors[1] = Integer.parseInt(st.nextToken());
 				colors[2] = Integer.parseInt(st.nextToken());
+				colors[3] = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : 255;
 			}
 		} catch (Exception e) {
 			//e.printStackTrace();
@@ -293,7 +332,7 @@ public class SkinPropertiesImpl
 			return null;
 		}
 
-		String[] values = s.split("\\s*,\\s*");
+		String[] values = Constants.PAT_SPLIT_COMMAWORDS.split(s);
 		if (values == null) {
 			return new String[] {
 				s
diff --git a/com/aelitis/azureus/ui/skin/skin3.properties b/com/aelitis/azureus/ui/skin/skin3.properties
index 87c7e7a..2c5b52a 100644
--- a/com/aelitis/azureus/ui/skin/skin3.properties
+++ b/com/aelitis/azureus/ui/skin/skin3.properties
@@ -1,7 +1,7 @@
 #TODO: A lot of widgets can be switched to clone
 
 skin.include=skin3_topbar,\
-             skin3_maintabs,\
+             skin3_toolbar,\
              skin3_sidebar,\
              skin3_activities,\
              skin3_tab_browse,\
@@ -9,8 +9,7 @@ skin.include=skin3_topbar,\
              skin3_constants,\
              skin3_sbc_library,\
              skin3_devices,\
-             skin3_devices_od,\
-             skin3_rcm
+             skin3_devices_od
 
 main.shell.widgets=main.shell.area
 
@@ -24,4 +23,10 @@ main.shell.area.widgets=main.area.topbar,\
                    maintabs.statusbarline,\
                    main.area.statusbar
 
+classic.shell.widgets=main.area.topbar,\
+                   classic.area.middle,\
+                   maintabs.statusbarline,\
+                   main.area.statusbar
+
+
 #main.shell.color={color.mainshell}
diff --git a/com/aelitis/azureus/ui/skin/skin3_classic.properties b/com/aelitis/azureus/ui/skin/skin3_classic.properties
new file mode 100644
index 0000000..39d6f3a
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_classic.properties
@@ -0,0 +1,4 @@
+library.header.info.text.style=
+library.header.info.text.shadow=
+color.library.header=
+
diff --git a/com/aelitis/azureus/ui/skin/skin3_close_notification.properties b/com/aelitis/azureus/ui/skin/skin3_close_notification.properties
deleted file mode 100644
index d296b0f..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_close_notification.properties
+++ /dev/null
@@ -1,99 +0,0 @@
-
-
-template.imagedir=com/aelitis/azureus/ui/images
-
-color.links.normal=#3030d0
-#156dff
-color.links.hover=#000080
-
-icon.notification={template.imagedir}/notification_icon.png
-icon.preview={template.imagedir}/network_closed_preview.png
-
-border.left=10
-border.left2=15
-
-close-notification.body.type=container
-close-notification.body.width=400
-close-notification.body.height=260
-close-notification.body.widgets=close-notification.top,\
-                                close-notification.text1,\
-                                close-notification.line1,\
-                                close-notification.text2,\
-                                close-notification.preview,\
-                                close-notification.close-button,\
-                                close-notification.noshowagain
-                                
-close-notification.top.type=container
-close-notification.top.attach.left=0,0
-close-notification.top.attach.right=100,0
-close-notification.top.attach.top=0,0
-close-notification.top.color=#fcfdfd
-close-notification.top.color.style=gradient,#e0e3e5
-close-notification.top.height=43
-close-notification.top.widgets=close-notification.top.image,\
-                               close-notification.top.title,\
-                               close-notification.top.line
-
-	close-notification.top.image.type=image,{icon.notification}
-	close-notification.top.image.attach.left=0,{border.left}
-	close-notification.top.image.attach.top=10,5
-	
-	close-notification.top.title.type=text
-	close-notification.top.title.text={v3.dialog.cnclose.subtitle}
-	close-notification.top.title.text.color=#000000
-	close-notification.top.title.attach.left=close-notification.top.image,15
-	close-notification.top.title.attach.bottom=close-notification.top.image,bottom,0
-	close-notification.top.title.attach.right=100,-10
-	close-notification.top.title.text.size=30px
-	close-notification.top.title.text.style=bold
-	
-	close-notification.top.line.type=container
-	close-notification.top.line.height=1
-	close-notification.top.line.color=COLOR_WIDGET_BORDER
-	close-notification.top.line.attach.top=close-notification.top.image,5
-	close-notification.top.line.attach.left=0,0
-	close-notification.top.line.attach.right=100,0
-	close-notification.top.line.attach.bottom=100,0
-	
-close-notification.text1.type=text,{v3.dialog.cnclose.info1}
-close-notification.text1.attach.top=close-notification.top,5
-close-notification.text1.attach.left=0,{border.left}
-close-notification.text1.attach.right=100,-10
-
-
-close-notification.line1.type=container
-close-notification.line1.height=1
-close-notification.line1.color=COLOR_WIDGET_NORMAL_SHADOW
-close-notification.line1.attach.top=close-notification.text1,5
-close-notification.line1.attach.left=0,0
-close-notification.line1.attach.right=100,0
-
-close-notification.text2.type=text
-close-notification.text2.text={v3.dialog.cnclose.info2}
-close-notification.text2.attach.top=close-notification.line1,10
-close-notification.text2.attach.left=0,{border.left2}
-close-notification.text2.attach.right=close-notification.preview,-10
-close-notification.text2.attach.bottom=close-notification.close-button,-10
-
-close-notification.preview.type=image,{icon.preview}
-close-notification.preview.attach.top=close-notification.line1,10
-close-notification.preview.attach.left=
-close-notification.preview.attach.right=100,-{border.left2}
-
-close-notification.close-button.type=button
-close-notification.close-button.text={Button.close}
-close-notification.close-button.view=close
-close-notification.close-button.attach.top=
-#close-notification.close-button.attach.left=0,{border.left2}
-close-notification.close-button.attach.right=100,-{border.left2}
-close-notification.close-button.attach.bottom=100,-10
-
-close-notification.noshowagain.type=checkbox
-close-notification.noshowagain.view=noshowagain
-close-notification.noshowagain.text={v3.dialog.cnclose.noshow}
-close-notification.noshowagain.v-align=center
-#close-notification.noshowagain.attach.right=100,-{border.left2}
-close-notification.noshowagain.attach.left=0,{border.left2}
-close-notification.noshowagain.attach.top=close-notification.close-button,top,0
-close-notification.noshowagain.attach.bottom=100,-10
-
diff --git a/com/aelitis/azureus/ui/skin/skin3_constants.properties b/com/aelitis/azureus/ui/skin/skin3_constants.properties
index da2b05c..f0d7d01 100644
--- a/com/aelitis/azureus/ui/skin/skin3_constants.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_constants.properties
@@ -16,7 +16,7 @@ template.fill.attach.bottom=100,0
 template.fill.attach.left=0,0
 template.fill.attach.right=100,0
 
-template.tabcontentarea.attach.top=main.area.maintabs,{template.padding}
+template.tabcontentarea.attach.top=0,{template.padding}
 template.tabcontentarea.attach.bottom=100,-{template.padding}
 template.tabcontentarea.attach.left=0,{template.padding}
 template.tabcontentarea.attach.right=100,-{template.padding}
@@ -55,10 +55,10 @@ color.section.header.selected=#F2F2F2
 
 color.table.buttonbar=#000000
 
-color.progress.bg=#8dc9ff
-color.progress.fg=#ebfeff
-color.progress.text=#005acf
-color.progress.border=#005acf
+color.progress.bg=#8ccfff
+color.progress.text=#2678b1
+color.progress.text.drop=#c4e2f8
+color.progress.border=#88aac1
 
 color.rating.good=#608fd4
 color.rating.odd.good.darker=#2e2e2e
@@ -110,11 +110,15 @@ color.maintabs.selected=#ffffff
 color.maintabs.fg=#c2c2c2
 color.maintabs.over=#e0e0e0
 
-color.sidebar.bg=#dfe8ea
-color.sidebar.fg=#2B3D32
+color.sidebar.bg=#d1d5d8
+color.sidebar.fg=#364f67
+color.sidebar.header=#364f67
+color.sidebar.text=#343a3f
 color.sidebar.selected.bg=COLOR_LIST_SELECTION
 color.sidebar.selected.fg=#FFFFFF
 color.sidebar.focus=#FFFFFF
+color.sidebar.drag.bg=#d0deea
+color.sidebar.drag.fg=#2688aa
 
 color.pieceview.alldone=BLUE.FADED.9
 color.pieceview.notdone=#F0F0F0
@@ -127,6 +131,7 @@ color.search.text.bg=#ffffff
 color.search.text.fg=#333333
 color.search.text.fg.default=#999999
 
+color.library.header=#c0cbd4
 
 #===============================================================================
 #main.area.statusbar
@@ -170,16 +175,15 @@ image.torrent.down-mouseonrow={template.imagedir}/torrent_down.png
 image.button.play={template.imagedir}/tb/play.png
 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.button.transcode=multi-index,20,0,{template.imagedir}/tb/2nd.png
+image.button.stream={template.imagedir}/tb/stream.png
+image.button.pstream={template.imagedir}/tb/play_now_plus.png
 
 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.frog={template.imagedir}/entry_frog.png
 
-image.help={template.imagedir}/help.png
-image.separator={template.imagedir}/separator.gif
-
 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
@@ -190,12 +194,16 @@ image.ssearch.dropdown={template.imagedir}/tb/search_btn_small.png
 
 image.toolbar.open={template.imagedir2}/toolbar/open_no_default.gif
 image.toolbar.new={template.imagedir2}/toolbar/new.gif
-image.toolbar.up={template.imagedir}/tb/ic_up.png
-image.toolbar.down={template.imagedir}/tb/ic_down.png
-image.toolbar.run={template.imagedir}/tb/ic_launch.png
-image.toolbar.start={template.imagedir}/tb/ic_start.png
-image.toolbar.stop={template.imagedir}/tb/ic_stop.png
-image.toolbar.remove={template.imagedir}/tb/ic_delete.png
+image.toolbar.top=multi-index,20,7,{template.imagedir}/tb/c/2nd.png
+image.toolbar.bottom=multi-index,20,8,{template.imagedir}/tb/c/2nd.png
+image.toolbar.up=multi-index,20,2,{template.imagedir}/tb/2nd.png
+image.toolbar.down=multi-index,20,3,{template.imagedir}/tb/2nd.png
+image.toolbar.run=multi-index,20,1,{template.imagedir}/tb/2nd.png
+image.toolbar.start=multi-index,20,4,{template.imagedir}/tb/2nd.png
+image.toolbar.stop=multi-index,20,5,{template.imagedir}/tb/2nd.png
+image.toolbar.remove=multi-index,20,6,{template.imagedir}/tb/2nd.png
+image.toolbar.startstop.stop=multi-index,20,5,{template.imagedir}/tb/2nd.png
+image.toolbar.startstop.start=multi-index,20,4,{template.imagedir}/tb/2nd.png
 image.toolbar.spacer={template.imagedir}/tb/spacer.png
 
 image.bullet.arrow.down={template.imagedir}/bullet_arrow_down.png
@@ -203,10 +211,13 @@ image.bullet.arrow.down={template.imagedir}/bullet_arrow_down.png
 image.toolbar.table_normal={template.imagedir}/tb/ic_list_small.png
 image.toolbar.table_large={template.imagedir}/tb/ic_list_big.png
 
+image.toolbar.2nd.m-bg={template.imagedir}/tb/sec_m.png
 image.toolbar.2nd.l-bg={template.imagedir}/tb/sec_l_l.png,{template.imagedir}/tb/sec_m.png
 image.toolbar.2nd.l-bg-down={template.imagedir}/tb/sec_l_l_down.png,{template.imagedir}/tb/sec_m_down.png
 image.toolbar.2nd.r-bg={template.imagedir}/tb/sec_m.png,{template.imagedir}/tb/sec_m.png,{template.imagedir}/tb/sec_r_r.png
 image.toolbar.2nd.r-bg-down={template.imagedir}/tb/sec_m_down.png,{template.imagedir}/tb/sec_m_down.png,{template.imagedir}/tb/sec_r_r_down.png
+image.toolbar.2nd.lr-bg={template.imagedir}/tb/sec_l_l.png,{template.imagedir}/tb/sec_m.png,{template.imagedir}/tb/sec_r_r.png
+image.toolbar.2nd.lr-bg-down={template.imagedir}/tb/sec_l_l_down.png,{template.imagedir}/tb/sec_m_down.png,{template.imagedir}/tb/sec_r_r_down.png
 
 image.toolbar.2nd-view.l-bg={template.imagedir}/tb/view_l_l.png,{template.imagedir}/tb/view_l_m.png,{template.imagedir}/tb/view_l_r.png
 image.toolbar.2nd-view.l-bg-down={template.imagedir}/tb/view_l_l_down.png,{template.imagedir}/tb/view_l_m_down.png,{template.imagedir}/tb/view_l_r_down.png
@@ -214,51 +225,90 @@ image.toolbar.2nd-view.r-bg={template.imagedir}/tb/view_r_l.png,{template.imaged
 image.toolbar.2nd-view.r-bg-down={template.imagedir}/tb/view_r_l_down.png,{template.imagedir}/tb/view_r_m_down.png,{template.imagedir}/tb/view_r_r_down.png
 
 
-image.sidebar.closeitem={template.imagedir}/sb/ic_x.png
+image.sidebar.closeitem={template.imagedir}/sb/close.png
 image.sidebar.expand={template.imagedir}/sb_expand.png
 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
-image.sidebar.vitality.dots=multi,18,{template.imagedir}/sb/ic_loading.png
-image.sidebar.vitality.dl.delay=150
-image.sidebar.vitality.dl=multi,16,{template.imagedir}/sb/ic_download.png
-image.sidebar.vitality.info={template.imagedir}/sb/ic_info.png
-image.sidebar.vitality.info-selected={template.imagedir}/sb/ic_info.png
-image.sidebar.vitality.alert={template.imagedir}/sb/ic_alert.png
-image.sidebar.vitality.alert-selected={template.imagedir}/sb/ic_alert.png
-image.sidebar.vitality.auth={template.imagedir}/sb/ic_auth.png
-image.sidebar.vitality.auth-selected={template.imagedir}/sb/ic_auth.png
-image.sidebar.subs.add={template.imagedir}/sb/ic_add.png
 image.sidebar.sashbg={template.imagedir}/sb/sash_bg.png
-image.sidebar.devices={template.imagedir}/sb/ic_device.png
+image.sidebar.subs.add={template.imagedir}/sb/ic_add.png
+
+image.sidebar.activity={template.imagedir}/sb/notifications.png
+image.sidebar.vuze={template.imagedir}/sb/hd.png
+image.sidebar.subscriptions={template.imagedir}/sb/subscriptions.png
+image.sidebar.rcm={template.imagedir}/sb/ic_rcm.png
+image.sidebar.welcome={template.imagedir}/sb/gettingstarted.png
+image.sidebar.library={template.imagedir}/sb/20px-library.png
+image.sidebar.unopened={template.imagedir}/new_dot.png
+image.sidebar.search={template.imagedir}/sb/search.png
+image.sidebar.games={template.imagedir}/sb/ic_games.png
+image.sidebar.plugin={template.imagedir}/sb/plugin.png
+image.sidebar.aboutdevices={template.imagedir}/sb/devices.png
+image.sidebar.logview={template.imagedir}/sb/ic_logview.png
+image.sidebar.downloading={template.imagedir}/sb/downloading.png
+image.sidebar.details={template.imagedir}/sb/file.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
 image.sidebar.device.1.big={template.imagedir}/30px-ps3.png
 image.sidebar.device.1.small={template.imagedir}/sb/20px-ps3.png
+image.sidebar.device.2.big={template.imagedir}/30px-xbox.png
+image.sidebar.device.2.small={template.imagedir}/sb/20px-xbox.png
 image.sidebar.device.3.big={template.imagedir}/30px-itunes.png
 image.sidebar.device.3.small={template.imagedir}/sb/20px-itunes.png
 image.sidebar.device.4.small={template.imagedir}/sb/20px-wii.png
+image.sidebar.device.4.big={template.imagedir}/30px-other.png
 image.sidebar.device.5.small={template.imagedir}/sb/20px-other.png
+image.sidebar.device.5.big={template.imagedir}/30px-other.png
 image.sidebar.device.6.small={template.imagedir}/sb/20px-other.png
+image.sidebar.device.6.big={template.imagedir}/30px-other.png
 image.sidebar.device.psp.small={template.imagedir}/sb/20px-psp.png
+image.sidebar.device.psp.big={template.imagedir}/30px-psp.png
 image.sidebar.device.tivo.small={template.imagedir}/sb/20px-tivo.png
+image.sidebar.device.tivo.big={template.imagedir}/30px-tivo.png
+image.sidebar.device.samsung.small={template.imagedir}/sb/20px-sam.png
+image.sidebar.device.samsung.big={template.imagedir}/30px-sam.png
+image.sidebar.device.bravia.small={template.imagedir}/sb/20px-sam.png
+image.sidebar.device.bravia.big={template.imagedir}/30px-sam.png
+image.sidebar.device.mswmp.small={template.imagedir}/sb/20px-mswmp.png
+image.sidebar.device.mswmp.big={template.imagedir}/30px-mswmp.png
+image.sidebar.device.android.small={template.imagedir}/sb/android_icon_20x20.png
+image.sidebar.device.android.big={template.imagedir}/android_icon_32x32.png
+image.sidebar.device.usb.small={template.imagedir}/sb/20px-usb.png
+image.sidebar.device.boxee.small={template.imagedir}/sb/boxee.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.device.wdtv.small={template.imagedir}/sb/20px-wdtv.png
+image.sidebar.device.wdtv.big={template.imagedir}/30px-wdtv.png
+image.sidebar.device.bb.small={template.imagedir}/sb/20px-bb.png
+image.sidebar.device.dlna.small={template.imagedir}/sb/20px-dlna.png
+image.sidebar.device.neotv.small={template.imagedir}/sb/20px-neo.png
+image.sidebar.device.upnp.small={template.imagedir}/sb/20px-upnp.png
 
 image.sidebar.turnon={template.imagedir}/sb/btn-turnon.png
 image.sidebar.beta={template.imagedir}/sb/beta.png
 
+image.sidebar.vitality.dots=multi,18,{template.imagedir}/sb/ic_loading.png
+
+image.sidebar.vitality.dl.delay=120
+image.sidebar.vitality.dl=multi,20,{template.imagedir}/sb/downloadingspin.png
+
+# this is used by the antivirus plugin
+image.sidebar.vitality.ul.delay=120
+image.sidebar.vitality.ul=multi,20,{template.imagedir}/sb/downloadingspin.png
+
+image.sidebar.vitality.info={template.imagedir}/sb/ic_info.png
+image.sidebar.vitality.info-selected={template.imagedir}/sb/ic_info.png
+
+image.sidebar.vitality.alert={template.imagedir}/sb/ic_alert.png
+image.sidebar.vitality.alert-selected={template.imagedir}/sb/ic_alert.png
+
+image.sidebar.vitality.auth={template.imagedir}/sb/ic_auth.png
+image.sidebar.vitality.auth-selected={template.imagedir}/sb/ic_auth.png
+
+
 image.device.logo.belkin={template.imagedir}/device_bel_logo.png
 
 image.activity.unread={template.imagedir}/new_dot.png
@@ -276,7 +326,7 @@ image.logo={template.imagedir}/logo-150.png
 
 #Subscription icons
 rss=org/gudy/azureus2/ui/icons/rss.png
-btn_rss_add=org/gudy/azureus2/ui/icons/btn_add_rss.png
+btn_rss_add=org/gudy/azureus2/ui/icons/rss.png
 btn_sidebar_add=com/aelitis/azureus/ui/images/sb/ic_add.png
 icon_check=com/aelitis/azureus/ui/images/icon_bullet_check.png
 rss_bg=com/aelitis/azureus/ui/images/rss_bg.png
@@ -289,6 +339,35 @@ 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
 
+image.statusbar.warning={image.sidebar.vitality.alert}
+
+image.bigspin=multi,18,{template.imagedir}/bigspin.png
+image.bigspin.delay=200
+
+image.sidebar.dvdburn={template.imagedir}/sb/left_nav_dvd_icon.png
+image.sidebar.dvdburn.add={template.imagedir}/sb/left_nav_create_dvd_icon.png
+image.sidebar.plus={template.imagedir}/sb/plus.png
+image.header.plus={template.imagedir}/Vuze_Plus_Toolbar_Logo.png
+image.header.streamplus={template.imagedir}/Vuze_Play_Now_Icon.png
+
+image.sidebar.beta={template.imagedir}/sb/beta.png
+
+image.fileprogress.arrowbtn={template.imagedir}/arrow_btn.png
+image.fileprogress.arrowbtn-pressed={template.imagedir}/arrow_btn_pressed.png
+image.fileprogress.pri.hi={template.imagedir}/priority_high.png
+image.fileprogress.pri.normal={template.imagedir}/priority_normal.png
+image.fileprogress.pri.stopped={template.imagedir}/priority_stopped.png
+image.progress.bg.torrent={template.imagedir}/download_bar_overlay.png
+image.progress.bg.file={template.imagedir}/download_bar_overlay_small.png
+
+image.subscription.column={template.imagedir}/subscription_icon_column_hdr.png
+
+image.torrentspeed.up={template.imagedir}/upload_arrow.png
+image.torrentspeed.down={template.imagedir}/download_arrow.png
+
+image.stream.small.on={template.imagedir}/play_now_on.png
+image.stream.small.off={template.imagedir}/play_now_off.png
+
 #================
 
 table.Media-Mini.row.height=50
diff --git a/com/aelitis/azureus/ui/skin/skin3_devices.properties b/com/aelitis/azureus/ui/skin/skin3_devices.properties
index 3c060f7..a144633 100644
--- a/com/aelitis/azureus/ui/skin/skin3_devices.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_devices.properties
@@ -69,13 +69,13 @@ infobar.line2.text.size=15px
 infobar.line2.attach.left=infobar.image1,10
 infobar.line2.attach.top=infobar.line1,4
 
-infobar.link.type=text,<A HREF="http://vuze.com/devices/learnmore.start">{label.learnmore}</a>
+infobar.link.type=text,<A HREF="/devices/learnmore.start">{label.learnmore}</a>
 infobar.link.text.urlcolor={color.links.normal}
 infobar.link.text.size=15px
 infobar.link.attach.left=infobar.line2,10
 infobar.link.attach.bottom=infobar.line2,0,bottom
 
-infobar.feedback.type=text,<A HREF="http://www.vuze.com/devices/feedback.start">Send Devices Feedback</A>
+infobar.feedback.type=text,<A HREF="/devices/feedback.start">Send Devices Feedback</A>
 infobar.feedback.text.urlcolor={color.links.normal}
 infobar.feedback.attach.right=100,-10
 infobar.feedback.attach.bottom=infobar.line2,-1,bottom
@@ -122,13 +122,13 @@ itunes.line2.text.size=15px
 itunes.line2.attach.left=itunes.image1,10
 itunes.line2.attach.top=itunes.line1,4
 
-itunes.link.type=text,<A HREF="http://vuze.com/devices/learnmore.start">{label.learnmore}</a>
+itunes.link.type=text,<A HREF="/devices/learnmore.start">{label.learnmore}</a>
 itunes.link.text.urlcolor={color.links.normal}
 itunes.link.text.size=15px
 itunes.link.attach.left=itunes.line2,10
 itunes.link.attach.bottom=itunes.line2,0,bottom
 
-itunes.feedback.type=text,<A HREF="http://www.vuze.com/devices/feedback.start">Send Devices Feedback</A>
+itunes.feedback.type=text,<A HREF="/devices/feedback.start">Send Devices Feedback</A>
 itunes.feedback.text.urlcolor={color.links.normal}
 itunes.feedback.attach.right=100,-10
 itunes.feedback.attach.bottom=itunes.line2,-1,bottom
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_deviceadd_mfchooser.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_deviceadd_mfchooser.properties
index d442e7e..689d654 100644
--- a/com/aelitis/azureus/ui/skin/skin3_dlg_deviceadd_mfchooser.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_deviceadd_mfchooser.properties
@@ -43,7 +43,7 @@ shell.top.widgets=shell.top.title,\
 
 shell.subtitle.type=text,{v3.devices.choose.manufacturer.subtitle}
 shell.subtitle.view=subtitle
-shell.subtitle.text.size=+2
+shell.subtitle.text.size=120%
 shell.subtitle.text.style=bold
 shell.subtitle.attach.left=0,{border.left2}
 shell.subtitle.attach.right=100,-{border.left2}
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_devicetemplatechooser.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_devicetemplatechooser.properties
index 6c722db..2016cea 100644
--- a/com/aelitis/azureus/ui/skin/skin3_dlg_devicetemplatechooser.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_devicetemplatechooser.properties
@@ -47,7 +47,7 @@ shell.top.widgets=shell.top.title,\
 
 shell.subtitle.type=text
 shell.subtitle.view=subtitle
-shell.subtitle.text.size=+2
+shell.subtitle.text.size=120%
 shell.subtitle.text.style=bold
 shell.subtitle.attach.left=0,{border.left2}
 shell.subtitle.attach.right=100,-{border.left2}
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_generic.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_generic.properties
new file mode 100644
index 0000000..cc3b268
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_generic.properties
@@ -0,0 +1,128 @@
+template.imagedir=com/aelitis/azureus/ui/images
+
+template.innerborder.x=80
+template.outerborder.x=55
+template.textalpha=230
+color.links.normal=#006eae
+color.links.dark=#003a5c
+color.fadedtext=#666666
+
+color.top=#b7c8d4
+color.title=#005186
+color.line=#ffffff
+color.main=#ecf2f6
+color.line2=#bac8d5
+ 
+shell.type=container
+shell.width=554
+shell.widgets=shell.top,\
+              shell.main,\
+              shell.bottom,\
+              shell.bottomline
+
+shell.top.type=container
+shell.top.color={color.top}
+shell.top.attach.top=0,0
+shell.top.attach.left=0,0
+shell.top.attach.right=100,0
+shell.top.widgets=top.logo,top.title,top.title.logo,top.bline
+shell.top.minheight=65
+
+top.logo.type=image
+top.logo.view=top-logo
+top.logo.attach.left=0,0
+top.logo.attach.top=0,0
+top.logo.attach.bottom=100,-1
+
+top.title.type=text
+top.title.view=top-title
+top.title.align=right
+top.title.text.size=130%
+top.title.text.style=bold
+top.title.text.color={color.title}
+top.title.attach.left=top.logo,20
+top.title.attach.right=100,-20
+top.title.attach.bottom=100,-15
+
+top.bline.type=container
+top.bline.color={color.line}
+top.bline.height=1
+top.bline.attach.left=0,0
+top.bline.attach.right=100,0
+top.bline.attach.bottom=100,0
+
+shell.main.type=container
+shell.main.color={color.main}
+shell.main.attach.left=0,0
+shell.main.attach.right=100,0
+shell.main.attach.bottom=shell.bottomline,0
+shell.main.attach.top=shell.top,0
+shell.main.widgets=main.group
+shell.main.minheight=100
+
+main.group.type=container
+main.group.attach.left=0,0
+main.group.attach.top=0,20
+main.group.attach.right=100,0
+main.group.attach.bottom=100,-5
+main.group.widgets=maintext,maintext.icon,section.extra
+
+maintext.icon.type=image
+maintext.icon.drawmode=left
+maintext.icon.h-padding=7
+maintext.icon.view=text-icon
+maintext.icon.attach.left=0,{template.outerborder.x}
+maintext.icon.attach.top=0,0
+
+maintext.type=text,{remote.pairing.subtitle}
+maintext.view=middle-title
+maintext.text.size=120%
+maintext.text.color=#005186
+maintext.text.style=bold
+maintext.attach.left=maintext.icon
+maintext.attach.top=0,0
+maintext.attach.right=100,-{template.outerborder.x}
+maintext.align=center
+maintext.minheight=40
+
+section.extra.type=container
+section.extra.view=middle-extra
+section.extra.attach.left=0,{template.outerborder.x}
+section.extra.attach.top=maintext,5
+section.extra.attach.bottom=100,0
+section.extra.attach.right=100,-{template.outerborder.x}
+
+###
+
+shell.bottom.type=container
+shell.bottom.view=bottom-area
+shell.bottom.color=#FFFFFF
+shell.bottom.attach.top=
+shell.bottom.attach.bottom=100,0
+shell.bottom.attach.left=0,0
+shell.bottom.attach.right=100,0
+shell.bottom.minheight=40
+
+shell.bottomline.type=container
+shell.bottomline.height=1
+shell.bottomline.color={color.line2}
+shell.bottomline.attach.left=0,0
+shell.bottomline.attach.right=100,0
+shell.bottomline.attach.bottom=shell.bottom,0
+
+####
+
+dlg.generic.test.type=container
+dlg.generic.test.color=#FF00FF
+dlg.generic.test.attach.left=0,0
+dlg.generic.test.attach.right=100,0
+dlg.generic.test.attach.top=0,0
+dlg.generic.test.attach.bottom=100,0
+dlg.generic.test.widgets=dlg.generic.test.txt,dlg.generic.test.btn
+
+dlg.generic.test.txt.type=text,Hello There
+
+dlg.generic.test.btn.type=button
+dlg.generic.test.btn.text=Button!
+dlg.generic.test.btn.attach.left=
+dlg.generic.test.btn.attach.right=100,0
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_register.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_register.properties
new file mode 100644
index 0000000..7a3b724
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_register.properties
@@ -0,0 +1,220 @@
+
+color.links.normal=#006eae
+
+template.imagedir=com/aelitis/azureus/ui/images
+
+image.warn.big={template.imagedir}/popup_warning_icon.png
+image.vp={template.imagedir}/vp_header.png
+image.bigspin=multi,80,{template.imagedir}/bigspin.png
+image.bigspin.delay=250
+image.burn.dlg.header={template.imagedir}/Vuze_DVD_Burn_Icon.png
+image.player.dlg.header={template.imagedir}/Vuze_HD_Player_Icon.png
+image.install.spin=multi,20,{template.imagedir}/sb/downloadingspin.png
+image.install.spin.delay=150
+image.trial.ready={template.imagedir}/popup_dvd_drag.png
+dlg.install.mlab.image={template.imagedir}/Vuze_Speed_Test_Icon.png
+dlg.install.vuzexcode.image={template.imagedir}/Vuze_HD_Player_Icon.png
+dlg.install.azemp.image={template.imagedir}/Vuze_HD_Player_Icon.png
+
+dlg.register.type=container
+dlg.register.attach.top=0,20
+dlg.register.attach.bottom=100,0
+dlg.register.attach.left=0,0
+dlg.register.attach.right=100,0
+dlg.register.widgets=dlg.register.area,dlg.register.link,dlg.register.tos
+
+dlg.register.area.type=container
+dlg.register.area.attach.top=0,0
+dlg.register.area.attach.left=0,0
+dlg.register.area.attach.right=100,0
+dlg.register.area.color=#fffdda
+dlg.register.area.widgets=dlg.register.title,dlg.register.textbox,dlg.register.expirey
+
+dlg.register.title.type=text,{dlg.auth.enter.prompt}
+dlg.register.title.text.color=#000000
+dlg.register.title.attach.left=0,10
+dlg.register.title.attach.top=dlg.register.textbox,0,center
+
+dlg.register.textbox.type=textbox
+dlg.register.textbox.view=key
+dlg.register.textbox.attach.right=100,-15
+dlg.register.textbox.attach.left=dlg.register.title,10
+dlg.register.textbox.attach.top=0,10
+
+dlg.register.expirey.type=text
+dlg.register.expirey.view=register-expirey
+dlg.register.expirey.text.color=#202040
+dlg.register.expirey.text.size=90%
+dlg.register.expirey.attach.top=dlg.register.textbox,3
+dlg.register.expirey.attach.left=dlg.register.textbox,0,left
+dlg.register.expirey.attach.right=dlg.register.textbox,0,right
+dlg.register.expirey.attach.bottom=100,-8
+
+dlg.register.link.type=text
+dlg.register.link.view=register-link
+dlg.register.link.text.urlcolor={color.links.normal}
+dlg.register.link.align=center
+dlg.register.link.attach.top=dlg.register.area,10
+dlg.register.link.attach.left=0,0
+dlg.register.link.attach.right=100,0
+
+dlg.register.tos.type=text,{dlg.auth.tos}
+dlg.register.tos.view=tos-link
+dlg.register.tos.text.size=110%
+dlg.register.tos.text.color=#808080
+dlg.register.tos.text.urlcolor={color.links.normal}
+dlg.register.tos.align=center
+dlg.register.tos.attach.top=dlg.register.link,15
+dlg.register.tos.attach.bottom=100,-1
+dlg.register.tos.attach.left=0,0
+dlg.register.tos.attach.right=100,0
+
+
+
+#######
+
+dlg.register.validating.type=image
+dlg.register.validating.image={image.bigspin}
+dlg.register.validating.drawmode=animate
+dlg.register.validating.attach.left=0,0
+dlg.register.validating.attach.right=100,0
+dlg.register.validating.attach.top=0,20
+dlg.register.validating.attach.bottom=100,-40
+
+dlg.register.success.type=text,{dlg.auth.success.line2}
+dlg.register.success.attach.left=0,0
+dlg.register.success.attach.right=100,0
+dlg.register.success.attach.top=0,20
+
+#######
+
+
+dlg.register.trial.success.type=container
+dlg.register.trial.success.attach.left=0,0
+dlg.register.trial.success.attach.right=100,0
+dlg.register.trial.success.attach.top=0,20
+dlg.register.trial.success.widgets=dlg.register.trial.success.line,dlg.register.trial.success.icon,dlg.register.trial.success.info
+
+dlg.register.trial.success.line.type=container
+dlg.register.trial.success.line.height=1
+dlg.register.trial.success.line.attach.left=0,0
+dlg.register.trial.success.line.attach.right=100,0
+dlg.register.trial.success.line.color=#808080
+
+dlg.register.trial.success.icon.type=image,{image.trial.ready}
+dlg.register.trial.success.icon.attach.left=0,0
+dlg.register.trial.success.icon.attach.top=dlg.register.trial.success.line,20
+dlg.register.trial.success.icon.attach.bottom=100,-20
+
+dlg.register.trial.success.info.type=text,{dlg.auth.trial.success.info}
+dlg.register.trial.success.info.attach.left=dlg.register.trial.success.icon,20
+dlg.register.trial.success.info.attach.right=100,0
+dlg.register.trial.success.info.attach.top=dlg.register.trial.success.icon,0,top
+
+
+#######
+
+dlg.register.install.type=container
+dlg.register.install.widgets=\
+	dlg.register.install.progressbar,\
+	dlg.register.install.progress,\
+	dlg.register.install.spin,\
+	dlg.register.install.pct
+dlg.register.install.attach.left=0,0
+dlg.register.install.attach.right=100,0
+dlg.register.install.attach.top=0,0
+dlg.register.install.attach.bottom=100,-10
+
+dlg.register.install.progressbar.type=container
+dlg.register.install.progressbar.view=progress-bar
+dlg.register.install.progressbar.attach.top=dlg.register.install.progress,15
+dlg.register.install.progressbar.attach.left=0,0
+dlg.register.install.progressbar.attach.right=100,0
+
+dlg.register.install.progress.type=text,{ManagerItem.initializing}
+dlg.register.install.progress.text.style=bold
+dlg.register.install.progress.view=progress-text
+dlg.register.install.progress.attach.left=0,0
+dlg.register.install.progress.attach.right=100,0
+dlg.register.install.progress.attach.top=0,0
+
+dlg.register.install.pct.type=text,
+dlg.register.install.pct.view=install-pct
+dlg.register.install.pct.attach.left=dlg.register.install.spin,5
+dlg.register.install.pct.attach.right=100,0
+dlg.register.install.pct.attach.top=dlg.register.install.spin,0,center
+
+dlg.register.install.spin.type=image
+dlg.register.install.spin.image={image.install.spin}
+dlg.register.install.spin.drawmode=animate
+dlg.register.install.spin.attach.left=0,0
+dlg.register.install.spin.attach.top=dlg.register.install.progressbar,15
+
+#######
+
+dlg.register.revoked.type=container
+dlg.register.revoked.widgets=dlg.register.revoked.info
+dlg.register.revoked.attach.top=0,20
+dlg.register.revoked.attach.bottom=100,-20
+dlg.register.revoked.attach.left=0,0
+dlg.register.revoked.attach.right=100,0
+
+dlg.register.revoked.info.type=text
+dlg.register.revoked.info.text={dlg.auth.revoked.link}
+dlg.register.revoked.info.view=link
+dlg.register.revoked.info.text.urlcolor={color.links.normal}
+dlg.register.revoked.info.align=center
+dlg.register.revoked.info.attach.left=0,0
+dlg.register.revoked.info.attach.right=100,0
+
+#######
+
+dlg.register.cancelled.type=container
+dlg.register.cancelled.widgets=dlg.register.cancelled.info
+dlg.register.cancelled.attach.top=0,20
+dlg.register.cancelled.attach.bottom=100,-20
+dlg.register.cancelled.attach.left=0,0
+dlg.register.cancelled.attach.right=100,0
+
+dlg.register.cancelled.info.type=text
+dlg.register.cancelled.info.text={dlg.auth.cancelled.line2}
+dlg.register.cancelled.info.attach.left=0,0
+dlg.register.cancelled.info.attach.right=100,0
+
+
+#######
+
+dlg.register.denied.type=container
+dlg.register.denied.widgets=dlg.register.denied.info
+dlg.register.denied.attach.top=0,20
+dlg.register.denied.attach.bottom=100,-20
+dlg.register.denied.attach.left=0,0
+dlg.register.denied.attach.right=100,0
+
+dlg.register.denied.info.type=text
+dlg.register.denied.info.text={dlg.auth.denied.link}
+dlg.register.denied.info.view=link
+dlg.register.denied.info.text.urlcolor={color.links.normal}
+dlg.register.denied.info.align=center
+dlg.register.denied.info.attach.left=0,0
+dlg.register.denied.info.attach.right=100,0
+
+#######
+
+dlg.register.trialask.type=container
+dlg.register.trialask.widgets=dlg.register.trialask.info
+dlg.register.trialask.attach.top=0,20
+dlg.register.trialask.attach.bottom=100,-20
+dlg.register.trialask.attach.left=0,0
+dlg.register.trialask.attach.right=100,0
+
+dlg.register.trialask.info.type=text
+#dlg.register.trialask.info.text={dlg.auth.tos}
+dlg.register.trialask.info.view=link
+dlg.register.trialask.info.text.size=110%
+dlg.register.trialask.info.text.color=#808080
+dlg.register.trialask.info.text.urlcolor={color.links.normal}
+dlg.register.trialask.info.align=center
+dlg.register.trialask.info.attach.left=0,0
+dlg.register.trialask.info.attach.right=100,0
+
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_remotepairing.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_remotepairing.properties
new file mode 100644
index 0000000..7d5d057
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_remotepairing.properties
@@ -0,0 +1,244 @@
+template.imagedir=com/aelitis/azureus/ui/images
+icon.spin=multi,18,{template.imagedir}/sb/ic_loading.png
+icon.success={template.imagedir}/success.png
+icon.warning={template.imagedir}/warning.png
+icon.failure={template.imagedir}/failure.png
+
+template.innerborder.x=80
+template.outerborder.x=55
+template.textalpha=230
+color.links.normal=#006eae
+color.links.dark=#003a5c
+color.fadedtext=#666666
+
+color.top=#b3c9d5
+color.title=#005186
+color.line=BLUE.0
+color.main=#ecf2f6
+color.line2=BLUE.2
+ 
+shell.type=container
+shell.width=554
+shell.title=Remote Pairing
+shell.widgets=shell.top,\
+              shell.main,\
+              shell.bottom
+
+shell.top.type=container
+shell.top.color={color.top}
+shell.top.attach.top=0,0
+shell.top.attach.left=0,0
+shell.top.attach.right=100,0
+shell.top.widgets=top.logo,top.title,top.title.logo,top.bline
+
+top.logo.type=image,{template.imagedir}/remote_logo.png
+top.logo.attach.left=0,15
+top.logo.attach.top=0,12
+top.logo.attach.bottom=100,-12
+
+
+top.title.type=text,{remote.pairing.title}
+top.title.text.size=130%
+#top.title.text.style=bold
+top.title.text.color={color.title}
+top.title.attach.left=
+top.title.attach.right=100,-15
+top.title.attach.bottom=100,-11
+
+top.bline.type=container
+top.bline.color={color.line}
+top.bline.height=1
+top.bline.attach.left=0,0
+top.bline.attach.right=100,0
+top.bline.attach.bottom=100,0
+
+shell.main.type=container
+shell.main.color={color.main}
+shell.main.attach.left=0,0
+shell.main.attach.right=100,0
+shell.main.attach.bottom=shell.bottom,0
+shell.main.attach.top=shell.top,0
+shell.main.widgets=main.group
+
+main.group.type=container
+main.group.attach.left=0,0
+main.group.attach.top=0,10
+main.group.attach.right=100,0
+main.group.attach.bottom=100,-5
+main.group.widgets=pair.subtitle,section.code,section.ftux
+
+pair.subtitle.type=text,{remote.pairing.subtitle}
+pair.subtitle.text.size=120%
+pair.subtitle.text.color=#005186
+pair.subtitle.text.style=bold
+pair.subtitle.attach.left=0,{template.outerborder.x}
+pair.subtitle.attach.top=0,5
+pair.subtitle.attach.right=100,-{template.outerborder.x}
+
+###
+
+section.ftux.type=container
+section.ftux.view=pairing-ftux
+section.ftux.widgets=ftux.info
+section.ftux.attach.top=pair.subtitle,15
+section.ftux.attach.left=0,0
+section.ftux.attach.right=100,0
+section.ftux.attach.bottom=100,0
+
+ftux.info.type=image,{template.imagedir}/remote_ftux.png
+ftux.info.align=center
+ftux.info.attach.top=0,0
+ftux.info.attach.left=0,0
+ftux.info.attach.right=100,0
+
+###
+
+section.code.type=container
+section.code.view=pairing-code
+section.code.widgets=pair.title,pair.area.code,pair.status.area,pair.clip,pair.easy
+section.code.attach.top=pair.subtitle,5
+section.code.attach.left=0,0
+section.code.attach.right=100,0
+
+pair.title.type=text,{remote.pairing.instruction}
+pair.title.text.color={color.fadedtext}
+pair.title.text.size=110%
+pair.title.attach.top=0,30
+pair.title.attach.left=0,{template.innerborder.x}
+pair.title.attach.right=100,-{template.innerborder.x}
+
+pair.area.code.type=container
+pair.area.code.view=code-area
+pair.area.code.color=COLOR_INFO_BACKGROUND
+pair.area.code.foreground=COLOR_INFO_FOREGROUND
+pair.area.code.height=50
+pair.area.code.attach.left=0,{template.innerborder.x}
+pair.area.code.attach.right=100,-{template.innerborder.x}
+pair.area.code.attach.top=pair.title,20
+
+pair.clip.type=text,{remote.pairing.functions}
+pair.clip.view=pair-clipboard
+pair.clip.align=center
+pair.clip.text.urlcolor={color.links.normal}
+pair.clip.text.urlcolor-pressed={color.links.dark}
+pair.clip.attach.left=0,{template.innerborder.x}
+pair.clip.attach.right=100,-{template.innerborder.x}
+pair.clip.attach.top=pair.area.code,10
+
+pair.status.area.type=container
+pair.status.area.color=#FFFFFF
+pair.status.area.widgets=pair.status,pair.status.image
+# force height so we can show 2 lines (in most cases)
+pair.status.area.height=20
+pair.status.area.attach.top=pair.clip,10
+pair.status.area.attach.left=0,{template.innerborder.x}
+pair.status.area.attach.right=100,-{template.innerborder.x}
+
+pair.status.image.type=image,foo
+#pair.status.image.align=center
+pair.status.image.view=status-image
+pair.status.image.attach.left=0,3
+pair.status.image.attach.top=0,1
+pair.status.image.attach.bottom=100,-1
+
+pair.status.type=text,{pairing.status.initialising}
+pair.status.view=status-text
+#pair.status.text.color={color.fadedtext}
+pair.status.text.urlcolor={color.links.normal}
+pair.status.text.size=16px
+pair.status.text.size._mac=13px
+#pair.status.align=center
+pair.status.attach.top=pair.status.image,0,center
+pair.status.attach.left=pair.status.image,3
+pair.status.attach.right=100,0
+pair.status.attach.bottom=100,0
+
+pair.easy.type=container
+#pair.easy.color=#d3e0e8
+pair.easy.attach.top=pair.status.area,10
+pair.easy.attach.bottom=100,-10
+pair.easy.attach.left=0,{template.innerborder.x}
+pair.easy.attach.right=100,-{template.innerborder.x}
+pair.easy.widgets=pair.easy.1,pair.easy.2
+
+pair.easy.1.type=text,{remote.pairing.tip.title}
+pair.easy.1.text.style=bold
+pair.easy.1.text.size=90%
+pair.easy.1.attach.left=0,10
+pair.easy.1.attach.right=100,-10
+pair.easy.1.attach.top=0,10
+
+pair.easy.2.type=text,{remote.pairing.tip.text}
+pair.easy.2.text.color={color.fadedtext}
+pair.easy.2.text.urlcolor={color.links.normal}
+pair.easy.2.text.size=90%
+pair.easy.2.attach.left=0,10
+pair.easy.2.attach.right=100,-10
+pair.easy.2.attach.top=pair.easy.1,4
+pair.easy.2.attach.bottom=100,-10
+
+###
+
+shell.bottom.type=container
+shell.bottom.widgets=bottom.area.install,bottom.area.code
+shell.bottom.color=#FFFFFF
+shell.bottom.attach.top=
+shell.bottom.attach.bottom=100,0
+shell.bottom.attach.left=0,0
+shell.bottom.attach.right=100,0
+
+bottom.area.line.type=container
+bottom.area.line.height=1
+bottom.area.line.color={color.line2}
+bottom.area.line.attach.left=0,0
+bottom.area.line.attach.right=100,0
+bottom.area.line.attach.top=0,0
+
+bottom.area.code.type=container
+bottom.area.code.widgets=bottom.area.learnmore2
+bottom.area.code.color={color.main}
+bottom.area.code.view=reset-pair-area
+bottom.area.code.attach.top=0,0
+bottom.area.code.attach.bottom=100,0
+bottom.area.code.attach.left=0,0
+bottom.area.code.attach.right=100,0
+
+bottom.area.learnmore.type=text,{remote.pairing.learnmore}
+bottom.area.learnmore.v-align=center
+bottom.area.learnmore.text.size=80%
+bottom.area.learnmore.view=learn-more
+bottom.area.learnmore.text.urlcolor={color.links.normal}
+bottom.area.learnmore.attach.top=0,1
+bottom.area.learnmore.attach.bottom=100,0
+bottom.area.learnmore.attach.left=0,10
+
+bottom.area.learnmore2.type=text,{remote.pairing.learnmore}
+bottom.area.learnmore2.text.size=80%
+bottom.area.learnmore2.v-align=center
+bottom.area.learnmore2.text.urlcolor={color.links.normal}
+bottom.area.learnmore2.attach.top=0,1
+bottom.area.learnmore2.attach.bottom=100,0
+bottom.area.learnmore2.attach.left=0,10
+
+bottom.area.install.type=container
+bottom.area.install.view=pair-install-area
+bottom.area.install.widgets=bottom.install,bottom.turnon,bottom.area.line,bottom.area.learnmore
+bottom.area.install.attach.top=0,0
+bottom.area.install.attach.bottom=100,0
+bottom.area.install.attach.left=0,0
+bottom.area.install.attach.right=100,0
+
+bottom.install.type=container
+bottom.install.view=pairing-install
+bottom.install.attach.left=bottom.area.learnmore,15
+bottom.install.attach.right=bottom.turnon,-15
+bottom.install.attach.top=bottom.turnon,0,top
+bottom.install.attach.bottom=bottom.turnon,0,bottom
+
+bottom.turnon.type=button
+bottom.turnon.text=Next
+bottom.turnon.view=enable-pairing
+bottom.turnon.attach.left=
+bottom.turnon.attach.right=100,-15
+bottom.turnon.attach.top=0,7
+bottom.turnon.attach.bottom=100,-5
diff --git a/com/aelitis/azureus/ui/skin/skin3_dlg_streamplus.properties b/com/aelitis/azureus/ui/skin/skin3_dlg_streamplus.properties
new file mode 100644
index 0000000..caae2eb
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_dlg_streamplus.properties
@@ -0,0 +1,21 @@
+template.imagedir=com/aelitis/azureus/ui/images
+image.header.streamplus={template.imagedir}/Vuze_Play_Now_Icon.png
+
+dlg.stream.plus.type=container
+dlg.stream.plus.attach.left=0,0
+dlg.stream.plus.attach.right=100,0
+dlg.stream.plus.attach.top=0,20
+dlg.stream.plus.attach.bottom=100,0
+dlg.stream.plus.widgets=\
+	dlg.stream.plus.info
+	
+dlg.stream.plus.info.type=text
+dlg.stream.plus.info.align=center
+dlg.stream.plus.info.text.color=#808080
+dlg.stream.plus.info.text.style=bold
+dlg.stream.plus.info.v-align=center
+dlg.stream.plus.info.view=trial-info
+dlg.stream.plus.info.attach.left=0,0
+dlg.stream.plus.info.attach.right=100,0
+dlg.stream.plus.info.attach.top=0,0
+dlg.stream.plus.info.attach.bottom=100,-20
diff --git a/com/aelitis/azureus/ui/skin/skin3_maintabs.properties b/com/aelitis/azureus/ui/skin/skin3_maintabs.properties
deleted file mode 100644
index ee5cd5b..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_maintabs.properties
+++ /dev/null
@@ -1,358 +0,0 @@
-#===============================================================================
-#main.area.middle
-#===============================================================================
-main.area.middle.type=container
-main.area.middle.widgets=main.area.maintabs,main.area.body
-main.area.middle.attach.top=main.area.topbar,0
-main.area.middle.attach.bottom=maintabs.statusbarline,0
-main.area.middle.attach.left=0,0
-main.area.middle.attach.right=100,0
-
-#################
-# used to be where the main tabs where.  Now it's search and user info
-##################
-
-main.area.maintabs.type=container
-main.area.maintabs.widgets=main.area.topgap,\
-                           main.area.toolbar,\
-													 main.area.toolbar.2nd,\
-													 main.area.toolbar.gap,\
-	                         maintabs.area.search,\
-	                         maintabs.line,\
-                           maintabs.vcenter,\
-                           maintabs.area.sidebarpop
-                           
-main.area.maintabs.view=tabbar
-main.area.maintabs.attach.top=0,0
-main.area.maintabs.attach.left=0,0
-main.area.maintabs.attach.right=100,0
-main.area.maintabs.color=#e1e6e8
-main.area.maintabs.color.style=gradient,#a9b7c0,0.76
-main.area.maintabs.background.drawmode=tile-x
-main.area.maintabs.height=50
-main.area.maintabs.propogateDown=1
-
-
-main.area.topgap.type=container
-main.area.topgap.view=topgap
-main.area.topgap.attach.top=0,0
-main.area.topgap.height=6
-main.area.topgap.attach.right=100,0
-
-maintabs.line.type=container
-maintabs.line.attach.template=template.fill
-maintabs.line.attach.top=
-maintabs.line.height=1
-maintabs.line.color=COLOR_WIDGET_NORMAL_SHADOW
-
-maintabs.vcenter.type=container
-maintabs.vcenter.attach.top=0,0
-maintabs.vcenter.attach.bottom=100,0
-maintabs.vcenter.attach.left=0,0
-maintabs.vcenter.attach.right=
-maintabs.vcenter.width=1
-
-maintabs.area.sidebarpop.type=container
-maintabs.area.sidebarpop.view=sidebar-pop
-maintabs.area.sidebarpop.attach.left=0,0
-maintabs.area.sidebarpop.attach.top=
-maintabs.area.sidebarpop.attach.bottom=100,0
-maintabs.area.sidebarpop.width=0
-maintabs.area.sidebarpop.color=#dfe8ea
-#maintabs.area.sidebarpop.color=COLOR_WIDGET_BACKGROUND
-maintabs.area.sidebarpop.widgets=sidebarpop.dropdown,sidebarpop.expand,sidebarpop.top,sidebarpop.right,sidebarpop.left
-
-sidebarpop.top.type=container
-sidebarpop.top.height=1
-sidebarpop.top.attach.right=100,0
-sidebarpop.top.attach.top=
-sidebarpop.top.attach.left=0,0
-sidebarpop.top.color=COLOR_WIDGET_NORMAL_SHADOW
-
-sidebarpop.right.type=container
-sidebarpop.right.width=1
-sidebarpop.right.attach.top=sidebarpop.top,0
-sidebarpop.right.attach.bottom=100,0
-sidebarpop.right.attach.left=
-sidebarpop.right.attach.right=100,0
-sidebarpop.right.color=COLOR_WIDGET_NORMAL_SHADOW
-
-sidebarpop.left.type=container
-sidebarpop.left.width=1
-sidebarpop.left.attach.top=sidebarpop.top,0
-sidebarpop.left.attach.bottom=100,0
-sidebarpop.left.attach.left=0,0
-sidebarpop.left.attach.right=
-sidebarpop.left.color=COLOR_WIDGET_NORMAL_SHADOW
-
-sidebarpop.dropdown.type=image,{image.sidebar.dropdown}
-sidebarpop.dropdown.view=sidebar-dropdown
-sidebarpop.dropdown.attach.top=sidebarpop.top,1
-sidebarpop.dropdown.attach.left=sidebarpop.expand,4
-sidebarpop.dropdown.attach.right=sidebarpop.right,-3
-sidebarpop.dropdown.attach.bottom=100,-1
-sidebarpop.dropdown.tooltip={sidebar.dropdown.tooltip}
-sidebarpop.dropdown.cursor=hand
-
-sidebarpop.expand.type=image,{image.sidebar.expand}
-sidebarpop.expand.attach.top=sidebarpop.top,1
-sidebarpop.expand.attach.bottom=100,-1
-sidebarpop.expand.attach.left=0,4
-sidebarpop.expand.view=sidebar-expand
-sidebarpop.expand.tooltip={sidebar.expand.tooltip}
-sidebarpop.expand.cursor=hand
-
-
-
-main.area.toolbar.type=container
-main.area.toolbar.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.ToolBarView
-main.area.toolbar.view=global-toolbar
-main.area.toolbar.attach.top=main.area.topgap,-1
-main.area.toolbar.attach.bottom=100,-3
-main.area.toolbar.attach.left=maintabs.area.search,18
-
-main.area.toolbar.gap.type=container
-main.area.toolbar.gap.view=toolbar-gap
-main.area.toolbar.gap.width=18
-main.area.toolbar.gap.attach.left=main.area.toolbar,0
-
-
-main.area.toolbar.2nd.type=container
-main.area.toolbar.2nd.view=global-toolbar-2nd
-main.area.toolbar.2nd.attach.top=main.area.topgap,0
-main.area.toolbar.2nd.attach.bottom=100,-3
-main.area.toolbar.2nd.attach.left=main.area.toolbar.gap,0
-
-maintabs.area.search.type=container
-maintabs.area.search.view=topbar-area-search
-maintabs.area.search.propogate=1
-maintabs.area.search.widgets=widget.search-button1,\
-	                           widget.search-area,\
-	                           widget.search-line
-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=200
-
-widget.search-line.type=container
-widget.search-line.height=1
-widget.search-line.attach.top=
-widget.search-line.attach.bottom=100,0
-widget.search-line.attach.left=0,0
-widget.search-line.attach.right=100,0
-widget.search-line.color=COLOR_WIDGET_NORMAL_SHADOW
-
-
-widget.search-area.type=container
-widget.search-area.widgets=widget.search-text2
-widget.search-area.attach.left=widget.search-button1,0
-widget.search-area.attach.top=0,2
-widget.search-area.attach.right=100,0
-widget.search-area.attach.top-small=0,10
-widget.search-area.background={image.searchbox}
-widget.search-area.background-small={image.ssearchbox}
-widget.search-area.background.drawmode=tile-x
-
-widget.search-text2.type=container
-widget.search-text2.view=search-text
-widget.search-text2.attach.left=0,5
-widget.search-text2.attach.right=100,-6
-widget.search-text2.attach.top=0,6
-widget.search-text2.attach.bottom=100,-3
-
-widget.search-button1.type=image
-widget.search-button1.image={image.search.dropdown}
-widget.search-button1.image-small={image.ssearch.dropdown}
-widget.search-button1.image-over-small={image.ssearch.dropdown}
-widget.search-button1.view=search-dropdown
-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
-
-##########
-
-toolbar.area.item.type=container
-toolbar.area.item.widgets=toolbar.area.item.image,toolbar.area.item.title
-toolbar.area.item.attach.top=0,1
-toolbar.area.item.cursor=hand
-#toolbar.area.item.debug=1
-
-toolbar.area.item.image.type=image
-toolbar.area.item.image.view=toolbar-item-image
-toolbar.area.item.image.attach.left=0,0
-toolbar.area.item.image.attach.right=100,0
-toolbar.area.item.image.attach.top=0,0
-toolbar.area.item.image.attach.bottom=toolbar.area.item.title,0
-toolbar.area.item.image.width=50
-toolbar.area.item.image.height=27
-toolbar.area.item.image.align=center
-toolbar.area.item.image.v-align=top
-toolbar.area.item.image.cursor=hand
-
-toolbar.area.item.title.type=text
-toolbar.area.item.title.view=toolbar-item-title
-toolbar.area.item.title.attach.left=0,2
-toolbar.area.item.title.attach.right=100,-2
-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
-toolbar.area.item.title.width=50
-#toolbar.area.item.title.debug=1
-
-
-toolbar.area.sitem.type=container
-toolbar.area.sitem.widgets=toolbar.area.sitem.imagearea,toolbar.area.sitem.title
-toolbar.area.sitem.propogate=1
-toolbar.area.sitem.attach.top=0,1
-toolbar.area.sitem.cursor=hand
-
-toolbar.area.sitem.imagearea.type=container
-toolbar.area.sitem.imagearea.widgets=toolbar.area.sitem.image
-toolbar.area.sitem.imagearea.attach.bottom=toolbar.area.sitem.title,-1
-#toolbar.area.sitem.imagearea.attach.left=toolbar.area.sitem.title,center
-toolbar.area.sitem.imagearea.attach.left=0,0
-toolbar.area.sitem.imagearea.attach.right=100,0
-toolbar.area.sitem.imagearea.background={template.imagedir}/tb/sec_m.png
-toolbar.area.sitem.imagearea.background-over={template.imagedir}/tb/sec_m.png
-toolbar.area.sitem.imagearea.background-down={template.imagedir}/tb/sec_r_l_down.png,{template.imagedir}/tb/sec_m_down.png,{template.imagedir}/tb/sec_l_r_down.png
-toolbar.area.sitem.imagearea.background.drawmode=tile-x
-toolbar.area.sitem.imagearea.minwidth=38
-
-toolbar.area.sitem.image.type=image
-toolbar.area.sitem.image.view=toolbar-item-image
-toolbar.area.sitem.image.attach.left=0,0
-toolbar.area.sitem.image.attach.right=100,0
-toolbar.area.sitem.image.attach.top=0,2
-toolbar.area.sitem.image.attach.bottom=100,0
-toolbar.area.sitem.image.align=center
-toolbar.area.sitem.image.v-align=center
-toolbar.area.sitem.image.cursor=hand
-toolbar.area.sitem.image.drawmode=center
-toolbar.area.sitem.image.width=1
-
-toolbar.area.sitem.title.type=text
-toolbar.area.sitem.title.view=toolbar-item-title
-toolbar.area.sitem.title.attach.left=0,0
-toolbar.area.sitem.title.attach.right=100,0
-toolbar.area.sitem.title.attach.bottom=100,0
-#toolbar.area.sitem.title.color=#ff0000
-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
-toolbar.area.sitem.title.fgcolor-disabled=#808080
-
-###
-
-toolbar.area.sitem.left.type=container
-toolbar.area.sitem.left.widgets=toolbar.area.sitem.l.imagearea,toolbar.area.sitem.title
-toolbar.area.sitem.left.attach.top=0,1
-toolbar.area.sitem.left.cursor=hand
-toolbar.area.sitem.left.propogate=1
-
-toolbar.area.sitem.l.imagearea.type=container
-toolbar.area.sitem.l.imagearea.widgets=toolbar.area.sitem.image
-toolbar.area.sitem.l.imagearea.attach.bottom=toolbar.area.sitem.title,-1
-toolbar.area.sitem.l.imagearea.attach.left=0,0
-toolbar.area.sitem.l.imagearea.attach.right=100,0
-toolbar.area.sitem.l.imagearea.background={image.toolbar.2nd.l-bg}
-toolbar.area.sitem.l.imagearea.background-over={image.toolbar.2nd.l-bg}
-toolbar.area.sitem.l.imagearea.background-down={image.toolbar.2nd.l-bg-down}
-toolbar.area.sitem.l.imagearea.background.drawmode=tile-x
-toolbar.area.sitem.l.imagearea.minwidth=38
-
-###
-
-toolbar.area.sitem.right.type=container
-toolbar.area.sitem.right.widgets=toolbar.area.sitem.r.imagearea,toolbar.area.sitem.title
-toolbar.area.sitem.right.attach.top=0,1
-toolbar.area.sitem.right.cursor=hand
-toolbar.area.sitem.right.propogate=1
-
-toolbar.area.sitem.r.imagearea.type=container
-toolbar.area.sitem.r.imagearea.widgets=toolbar.area.sitem.image
-toolbar.area.sitem.r.imagearea.attach.bottom=toolbar.area.sitem.title,-1
-toolbar.area.sitem.r.imagearea.attach.left=0,0
-toolbar.area.sitem.r.imagearea.attach.right=100,0
-toolbar.area.sitem.r.imagearea.background={image.toolbar.2nd.r-bg}
-toolbar.area.sitem.r.imagearea.background-over={image.toolbar.2nd.r-bg}
-toolbar.area.sitem.r.imagearea.background-down={image.toolbar.2nd.r-bg-down}
-toolbar.area.sitem.r.imagearea.background.drawmode=tile-x
-toolbar.area.sitem.r.imagearea.minwidth=38
-
-###
-
-toolbar.area.vitem.left.type=container
-toolbar.area.vitem.left.widgets=toolbar.area.vitem.l.imagearea,toolbar.area.vitem.title
-toolbar.area.vitem.left.attach.top=0,1
-toolbar.area.vitem.left.cursor=hand
-toolbar.area.vitem.left.propogate=1
-
-toolbar.area.vitem.l.imagearea.type=container
-toolbar.area.vitem.l.imagearea.widgets=toolbar.area.sitem.image
-toolbar.area.vitem.l.imagearea.attach.bottom=toolbar.area.vitem.title,-1
-toolbar.area.vitem.l.imagearea.attach.left=0,0
-toolbar.area.vitem.l.imagearea.attach.right=100,0
-toolbar.area.vitem.l.imagearea.background={image.toolbar.2nd-view.l-bg}
-toolbar.area.vitem.l.imagearea.background-over={image.toolbar.2nd-view.l-bg}
-toolbar.area.vitem.l.imagearea.background-down={image.toolbar.2nd-view.l-bg-down}
-toolbar.area.vitem.l.imagearea.background.drawmode=tile-x
-toolbar.area.vitem.l.imagearea.minwidth=32
-
-###
-
-toolbar.area.vitem.right.type=container
-toolbar.area.vitem.right.widgets=toolbar.area.vitem.r.imagearea,toolbar.area.vitem.title
-toolbar.area.vitem.right.attach.top=0,1
-toolbar.area.vitem.right.cursor=hand
-toolbar.area.vitem.right.propogate=1
-
-toolbar.area.vitem.r.imagearea.type=container
-toolbar.area.vitem.r.imagearea.widgets=toolbar.area.sitem.image
-toolbar.area.vitem.r.imagearea.attach.bottom=toolbar.area.vitem.title,-1
-toolbar.area.vitem.r.imagearea.attach.left=0,0
-toolbar.area.vitem.r.imagearea.attach.right=100,0
-toolbar.area.vitem.r.imagearea.background={image.toolbar.2nd-view.r-bg}
-toolbar.area.vitem.r.imagearea.background-over={image.toolbar.2nd-view.r-bg}
-toolbar.area.vitem.r.imagearea.background-down={image.toolbar.2nd-view.r-bg-down}
-toolbar.area.vitem.r.imagearea.background.drawmode=tile-x
-toolbar.area.vitem.r.imagearea.minwidth=32
-
-
-toolbar.area.vitem.title.type=text
-toolbar.area.vitem.title.view=toolbar-item-title
-toolbar.area.vitem.title.attach.left=0,0
-toolbar.area.vitem.title.attach.right=100,0
-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=container
-toolbar.area.sitem.left2.attach.top=0,1
-toolbar.area.sitem.left2.attach.left=0,18
-
-toolbar.area.sitem.sep.type=image,{template.imagedir}/tb/sec_sep.png
-toolbar.area.sitem.sep.attach.top=0,1
-
-toolbar.area.item.sep.type=image,{image.toolbar.spacer}
-toolbar.area.item.sep.attach.top=0,0
-toolbar.area.item.sep.attach.left=0,7
-
-toolbar.area.item.sep3.type=image,{image.toolbar.spacer}
-toolbar.area.item.sep3.attach.top=0,0
-toolbar.area.item.sep3.attach.left=0,18
diff --git a/com/aelitis/azureus/ui/skin/skin3_manageCN.properties b/com/aelitis/azureus/ui/skin/skin3_manageCN.properties
deleted file mode 100644
index 530e0c2..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_manageCN.properties
+++ /dev/null
@@ -1,31 +0,0 @@
-
-manageCN.body.type=container
-manageCN.body.title={v3.dialog.cnmanage.title}
-manageCN.body.width=380
-manageCN.body.height=200
-manageCN.body.widgets=manageCN.intro,\
-                      manageCN.list,\
-                      manageCN.button.close
-                      
-manageCN.intro.type=text,{v3.dialog.cnmanage.intro}
-manageCN.intro.attach.top=0,10
-manageCN.intro.attach.left=0,10
-manageCN.intro.attach.right=100,-10
-
-manageCN.list.type=container
-manageCN.list.view=list-area
-manageCN.list.border=1
-manageCN.list.attach.top=manageCN.intro,10
-manageCN.list.attach.bottom=manageCN.button.close,-10
-manageCN.list.attach.left=0,10
-manageCN.list.attach.right=100,-10
-
-manageCN.button.close.type=button
-manageCN.button.close.minwidth=45
-manageCN.button.close.text={Button.close}
-manageCN.button.close.view=close
-manageCN.button.close.attach.top=
-manageCN.button.close.attach.bottom=100,-10
-manageCN.button.close.attach.left=
-manageCN.button.close.attach.right=100,-10
-
diff --git a/com/aelitis/azureus/ui/skin/skin3_rcm.properties b/com/aelitis/azureus/ui/skin/skin3_rcm.properties
deleted file mode 100644
index b7e4ebb..0000000
--- a/com/aelitis/azureus/ui/skin/skin3_rcm.properties
+++ /dev/null
@@ -1,46 +0,0 @@
-rcmview.type=container
-rcmview.onshow.skinviewclass=com.aelitis.azureus.ui.swt.content.SBC_RCMView
-rcmview.widgets=\
-	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.view=title
-rcmview.title.attach.template=template.fill
-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.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 29a5ad9..d0b06ce 100644
--- a/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_sbc_library.properties
@@ -3,35 +3,20 @@
 library.type=container
 library.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_LibraryView
 library.view=sidebar-library-area
-library.widgets=library.wait,library.list,library.top
+library.widgets=library.wait,library.list,library.header
 library.attach.template=template.fill
-library.attach.top=library.top,0
-
-##
-
-
-library.top.type=container
-library.top.view=library-list-info
-library.top.attach.top=0,0
-library.top.attach.left=0,0
-library.top.attach.right=100,0
-library.top.height=40
-library.top.visible=0
-library.top.color=#F1F9F8
-#library.top.widgets=library.top.info
 
 
 ## List
 
 library.list.type=container
 library.list.view=library-list-area
-library.list.attach.top=library.top,0
+library.list.attach.top=library.header,0
 library.list.attach.left=0,0
 library.list.attach.right=100,0
 library.list.attach.bottom=100,0
 
 
-
 library.table.small.type=container
 library.table.small.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_LibraryTableView
 library.table.small.view=library-small-area
@@ -42,44 +27,6 @@ library.table.big.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC
 library.table.big.view=library-big-area
 library.table.big.attach.template=template.fill
 
-####
-
-library.top.info.type=container
-library.top.info.height=40
-library.top.info.color=#F1F9F8
-library.top.info.widgets=library.info.close,library.info.title1,library.info.title2
-library.top.info.attach.template=template.fill
-
-library.info.title2.type=text
-library.info.title2.view=infobar-title-2
-library.info.title2.attach.left=library.info.title1,10
-library.info.title2.attach.top=0,0
-library.info.title2.attach.bottom=100,0
-library.info.title2.attach.right=library.info.close,-15
-library.info.title2.v-align=center
-library.info.title2.text.size=15px
-library.info.title2.text.size._mac=14px
-library.info.title2.text.color=#808080
-
-library.info.title1.type=text
-library.info.title1.view=infobar-title-1
-library.info.title1.attach.left=0,20
-library.info.title1.attach.top=0,0
-library.info.title1.attach.bottom=100,0
-library.info.title1.align=right
-library.info.title1.v-align=center
-library.info.title1.text.size=15px
-library.info.title1.text.size._mac=14px
-library.info.title1.text.color=#808080
-library.info.title1.text.style=bold
-
-library.info.close.type=image,{template.imagedir}/dismissX.gif
-library.info.close.view=close
-library.info.close.cursor=hand
-library.info.close.attach.right=100,-10
-library.info.close.attach.top=0,7
-
-
 ###########
 
 library.wait.type=container
@@ -118,3 +65,38 @@ library.wait.text.width=300
 library.wait.text.attach.left=50,-150
 library.wait.text.attach.top=library.wait.progress,10
 
+#############
+
+library.header.type=container
+library.header.color={color.library.header}
+library.header.attach.template=template.fill
+library.header.attach.bottom=
+library.header.widgets=\
+	library.header.info,\
+	library.header.search,\
+	library.header.categories
+
+library.header.info.type=text
+library.header.info.view=library-info
+library.header.info.attach.template=template.fill
+library.header.info.attach.bottom=library.header.categories
+library.header.info.attach.right=library.header.search,-5
+library.header.info.align=center
+library.header.info.v-align=center
+library.header.info.text.style=bold,shadow
+library.header.info.text.shadow=#FFFFFF80
+library.header.info.height=30
+
+library.header.search.type=textbox
+library.header.search.view=library-filter
+library.header.search.style=search
+library.header.search.width=150
+library.header.search.attach.left=
+library.header.search.attach.right=100,-10
+library.header.search.attach.top=library.header.info,0,center
+library.header.search.message={MyTorrentsView.filter}
+
+library.header.categories.type=container
+#library.header.categories.view=library-categories
+library.header.categories.attach.template=template.fill
+library.header.categories.attach.top=
diff --git a/com/aelitis/azureus/ui/skin/skin3_sidebar.properties b/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
index 8829411..ef6cc0c 100644
--- a/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_sidebar.properties
@@ -1,11 +1,21 @@
 
 main.area.body.type=container
-main.area.body.attach.top=main.area.maintabs,0
+main.area.body.attach.top=main.area.toolbar,0
 main.area.body.attach.bottom=100,0
 main.area.body.attach.left=0,0
 main.area.body.attach.right=100,0
 main.area.body.widgets=main.sidebar.list,main.sidebar.content,main.sidebar.sash
-main.area.body.view=sidebar
+main.area.body.view=mdi
+
+classic.area.body.type=tabfolder
+classic.area.body.style=close
+classic.area.body.border=1
+classic.area.body.view=mdi
+#we create skinviewclass manually to ensure it's there before everything else
+#classic.area.body.onshow.skinviewclass=com.aelitis.azureus.ui.swt.mdi.TabbedMDI
+classic.area.body.attach.template=template.fill
+classic.area.body.attach.top=classic.area.toolbar,0
+
 
 main.sidebar.sash.type=v-mysash,main.sidebar.list,main.sidebar.content
 main.sidebar.sash.noresize=true
@@ -53,7 +63,34 @@ main.sidebar.content.attach.bottom=100,0
 main.sidebar.content.attach.left=main.sidebar.sash
 main.sidebar.content.attach.right=100,0
 
+mdi.content.item.type=container
+mdi.content.item.attach.template=template.fill
+#Important! Needs to be invisible
+mdi.content.item.visible=0
+
 main.area.welcome.type=browser
 main.area.welcome.view=welcome
 main.area.welcome.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.WelcomeView
 main.area.welcome.attach.template=template.fill
+
+
+main.area.beta.type=browser
+main.area.beta.view=welcome
+main.area.beta.url=http://dev.vuze.com/beta.start
+main.area.beta.attach.template=template.fill
+
+main.area.plus.type=browser
+main.area.plus.view=plus-ftux
+main.area.plus.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_PlusFTUX
+main.area.plus.attach.template=template.fill
+
+main.burn.ftux.type=browser
+main.burn.ftux.view=browser
+main.burn.ftux.attach.template=template.fill
+main.burn.ftux.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_BurnFTUX
+
+main.generic.browse.type=browser
+main.generic.browse.view=browser
+main.generic.browse.attach.template=template.fill
+main.generic.browse.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.SBC_GenericBrowsePage
+
diff --git a/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties b/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
index 5f90855..0ec7ce0 100644
--- a/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_tab_searchresults.properties
@@ -26,6 +26,7 @@ searchresultsr.area.wait.align=center
 
 searchresults.area.search-results.type=browser
 searchresults.area.search-results.browser.nolisteners=1
+searchresults.area.search-results.browser.allowPopouts=0
 searchresults.area.search-results.view=searchresults-search-results
 searchresults.area.search-results.attach.bottom=100,0
 searchresults.area.search-results.attach.top=
diff --git a/com/aelitis/azureus/ui/skin/skin3_toolbar.properties b/com/aelitis/azureus/ui/skin/skin3_toolbar.properties
new file mode 100644
index 0000000..5b87e80
--- /dev/null
+++ b/com/aelitis/azureus/ui/skin/skin3_toolbar.properties
@@ -0,0 +1,484 @@
+#===============================================================================
+#main.area.middle
+#===============================================================================
+main.area.middle.type=container
+main.area.middle.widgets=main.area.toolbar,main.area.body
+main.area.middle.attach.top=main.area.topbar,0
+main.area.middle.attach.bottom=maintabs.statusbarline,0
+main.area.middle.attach.left=0,0
+main.area.middle.attach.right=100,0
+
+classic.area.middle.type=container
+classic.area.middle.widgets=classic.area.toolbar,classic.area.body
+classic.area.middle.attach.top=main.area.topbar,0
+classic.area.middle.attach.bottom=maintabs.statusbarline,0
+classic.area.middle.attach.left=0,0
+classic.area.middle.attach.right=100,0
+
+classic.area.toolbar.type=container
+classic.area.toolbar.widgets=main.area.topgap,\
+                           classic.area.toolbar.1st,\
+													 classic.area.toolbar.2nd,\
+													 classic.area.toolbar.gap,\
+                           maintabs.vcenter,\
+                           maintabs.area.sidebarpop
+classic.area.toolbar.view=tabbar
+classic.area.toolbar.attach.top=0,0
+classic.area.toolbar.attach.left=0,10
+classic.area.toolbar.attach.right=100,0
+classic.area.toolbar.height=50
+
+
+main.area.toolbar.type=container
+main.area.toolbar.widgets=main.area.topgap,\
+                           main.area.toolbar.0th,\
+                           main.area.toolbar.1st,\
+													 main.area.toolbar.2nd,\
+													 main.area.toolbar.gap,\
+	                         maintabs.area.search,\
+	                         maintabs.area.search.line,\
+	                         maintabs.bottom.line,\
+                           maintabs.vcenter,\
+                           maintabs.area.sidebarpop,\
+                           maintabs.area.plus
+main.area.toolbar.view=tabbar
+main.area.toolbar.attach.top=0,0
+main.area.toolbar.attach.left=0,0
+main.area.toolbar.attach.right=100,0
+main.area.toolbar.color=#dd6dde3
+main.area.toolbar.color.style=gradient,{color.library.header},0.76
+main.area.toolbar.background.drawmode=tile-x
+main.area.toolbar.height=50
+main.area.toolbar.propogateDown=1
+
+
+main.area.topgap.type=container
+main.area.topgap.view=topgap
+main.area.topgap.attach.top=0,0
+main.area.topgap.height=6
+
+maintabs.bottom.line.type=container
+maintabs.bottom.line.attach.template=template.fill
+maintabs.bottom.line.attach.top=
+maintabs.bottom.line.height=1
+maintabs.bottom.line.color=COLOR_WIDGET_NORMAL_SHADOW
+
+maintabs.vcenter.type=container
+maintabs.vcenter.attach.top=0,0
+maintabs.vcenter.attach.bottom=100,0
+maintabs.vcenter.attach.left=0,0
+maintabs.vcenter.attach.right=
+maintabs.vcenter.width=1
+
+maintabs.area.sidebarpop.type=container
+maintabs.area.sidebarpop.view=sidebar-pop
+maintabs.area.sidebarpop.attach.left=0,0
+maintabs.area.sidebarpop.attach.top=
+maintabs.area.sidebarpop.attach.bottom=100,0
+maintabs.area.sidebarpop.width=0
+maintabs.area.sidebarpop.color=#dfe8ea
+#maintabs.area.sidebarpop.color=COLOR_WIDGET_BACKGROUND
+maintabs.area.sidebarpop.widgets=sidebarpop.dropdown,sidebarpop.expand,sidebarpop.top,sidebarpop.right,sidebarpop.left
+
+sidebarpop.top.type=container
+sidebarpop.top.height=1
+sidebarpop.top.attach.right=100,0
+sidebarpop.top.attach.top=
+sidebarpop.top.attach.left=0,0
+sidebarpop.top.color=COLOR_WIDGET_NORMAL_SHADOW
+
+sidebarpop.right.type=container
+sidebarpop.right.width=1
+sidebarpop.right.attach.top=sidebarpop.top,0
+sidebarpop.right.attach.bottom=100,0
+sidebarpop.right.attach.left=
+sidebarpop.right.attach.right=100,0
+sidebarpop.right.color=COLOR_WIDGET_NORMAL_SHADOW
+
+sidebarpop.left.type=container
+sidebarpop.left.width=1
+sidebarpop.left.attach.top=sidebarpop.top,0
+sidebarpop.left.attach.bottom=100,0
+sidebarpop.left.attach.left=0,0
+sidebarpop.left.attach.right=
+sidebarpop.left.color=COLOR_WIDGET_NORMAL_SHADOW
+
+sidebarpop.dropdown.type=image,{image.sidebar.dropdown}
+sidebarpop.dropdown.view=sidebar-dropdown
+sidebarpop.dropdown.attach.top=sidebarpop.top,1
+sidebarpop.dropdown.attach.left=sidebarpop.expand,4
+sidebarpop.dropdown.attach.right=sidebarpop.right,-3
+sidebarpop.dropdown.attach.bottom=100,-1
+sidebarpop.dropdown.tooltip={sidebar.dropdown.tooltip}
+sidebarpop.dropdown.cursor=hand
+
+sidebarpop.expand.type=image,{image.sidebar.expand}
+sidebarpop.expand.attach.top=sidebarpop.top,1
+sidebarpop.expand.attach.bottom=100,-1
+sidebarpop.expand.attach.left=0,4
+sidebarpop.expand.view=sidebar-expand
+sidebarpop.expand.tooltip={sidebar.expand.tooltip}
+sidebarpop.expand.cursor=hand
+
+
+
+classic.area.toolbar.1st.type=container
+classic.area.toolbar.1st.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.ToolBarView
+classic.area.toolbar.1st.view=global-toolbar
+classic.area.toolbar.1st.attach.top=main.area.topgap,-1
+classic.area.toolbar.1st.attach.bottom=100,-3
+classic.area.toolbar.1st.attach.left=0,13
+
+
+main.area.toolbar.1st.type=container
+main.area.toolbar.1st.onshow.skinviewclass=com.aelitis.azureus.ui.swt.views.skin.ToolBarView
+main.area.toolbar.1st.view=global-toolbar
+main.area.toolbar.1st.attach.top=main.area.topgap,-1
+main.area.toolbar.1st.attach.bottom=100,-3
+main.area.toolbar.1st.attach.left=maintabs.area.search.line,13
+
+maintabs.area.search.line.type=container
+maintabs.area.search.line.width=1
+maintabs.area.search.line.color=#8fa3b8
+maintabs.area.search.line.attach.top=main.area.topgap,6
+maintabs.area.search.line.attach.bottom=100,-11
+maintabs.area.search.line.attach.left=maintabs.area.search,13
+
+main.area.toolbar.gap.type=container
+main.area.toolbar.gap.view=toolbar-gap
+main.area.toolbar.gap.width=28
+main.area.toolbar.gap.attach.left=main.area.toolbar.1st,0
+
+classic.area.toolbar.gap.type=container
+classic.area.toolbar.gap.view=toolbar-gap
+classic.area.toolbar.gap.width=28
+classic.area.toolbar.gap.attach.left=classic.area.toolbar.1st,0
+
+classic.area.toolbar.2nd.type=container
+classic.area.toolbar.2nd.view=global-toolbar-2nd
+classic.area.toolbar.2nd.attach.top=main.area.topgap,0
+classic.area.toolbar.2nd.attach.bottom=100,-3
+#classic.area.toolbar.2nd.attach.left=main.area.toolbar.gap,0
+#classic.area.toolbar.2nd.attach.right=100,-15
+
+
+main.area.toolbar.2nd.type=container
+main.area.toolbar.2nd.view=global-toolbar-2nd
+main.area.toolbar.2nd.attach.top=main.area.topgap,0
+main.area.toolbar.2nd.attach.bottom=100,-3
+main.area.toolbar.2nd.attach.left=main.area.toolbar.gap,0
+
+main.area.toolbar.0th.type=container
+main.area.toolbar.0th.view=global-toolbar-0th
+main.area.toolbar.0th.attach.top=main.area.topgap,0
+main.area.toolbar.0th.attach.bottom=100,-3
+main.area.toolbar.0th.attach.left=0,5
+
+maintabs.area.search.type=container
+maintabs.area.search.view=topbar-area-search
+maintabs.area.search.propogate=1
+maintabs.area.search.widgets=widget.search-button1,\
+	                           widget.search-area,\
+	                           widget.search-line
+maintabs.area.search.attach.left=main.area.toolbar.0th,10
+maintabs.area.search.attach.top=main.area.topgap,0
+maintabs.area.search.attach.bottom=100,0
+maintabs.area.search.width=250
+
+widget.search-line.type=container
+widget.search-line.height=1
+widget.search-line.attach.top=
+widget.search-line.attach.bottom=100,0
+widget.search-line.attach.left=0,0
+widget.search-line.attach.right=100,0
+widget.search-line.color=COLOR_WIDGET_NORMAL_SHADOW
+
+
+widget.search-area.type=container
+widget.search-area.widgets=widget.search-text2
+widget.search-area.attach.left=widget.search-button1,0
+widget.search-area.attach.top=0,2
+widget.search-area.attach.right=100,0
+widget.search-area.attach.top-small=0,10
+widget.search-area.background={image.searchbox}
+widget.search-area.background-small={image.ssearchbox}
+widget.search-area.background.drawmode=tile-x
+
+widget.search-text2.type=container
+widget.search-text2.view=search-text
+widget.search-text2.attach.left=0,5
+widget.search-text2.attach.right=100,-6
+widget.search-text2.attach.top=0,6
+widget.search-text2.attach.bottom=100,-3
+
+widget.search-button1.type=image
+widget.search-button1.image={image.search.dropdown}
+widget.search-button1.image-small={image.ssearch.dropdown}
+widget.search-button1.image-over-small={image.ssearch.dropdown}
+widget.search-button1.view=search-dropdown
+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
+
+##########
+
+toolbar.area.0item.type=container
+toolbar.area.0item.widgets=toolbar.area.0item.image,toolbar.area.item.title
+toolbar.area.0item.attach.top=0,1
+toolbar.area.0item.attach.bottom=100,-1
+toolbar.area.0item.cursor=hand
+#toolbar.area.item.debug=1
+
+toolbar.area.0item.image.type=image
+toolbar.area.0item.image.view=toolbar-item-image
+toolbar.area.0item.image.attach.left=0,0
+toolbar.area.0item.image.attach.right=100,0
+toolbar.area.0item.image.attach.top=0,0
+toolbar.area.0item.image.attach.bottom=toolbar.area.item.title,0
+toolbar.area.0item.image.width=50
+toolbar.area.0item.image.height=27
+toolbar.area.0item.image.align=center
+toolbar.area.0item.image.v-align=center
+toolbar.area.0item.image.cursor=hand
+
+
+##########
+
+toolbar.area.item.type=container
+toolbar.area.item.widgets=toolbar.area.item.image,toolbar.area.item.title
+toolbar.area.item.attach.top=0,1
+toolbar.area.item.cursor=hand
+#toolbar.area.item.debug=1
+
+toolbar.area.item.image.type=image
+toolbar.area.item.image.view=toolbar-item-image
+toolbar.area.item.image.attach.left=0,0
+toolbar.area.item.image.attach.right=100,0
+toolbar.area.item.image.attach.top=0,0
+toolbar.area.item.image.attach.bottom=toolbar.area.item.title,0
+toolbar.area.item.image.width=50
+toolbar.area.item.image.height=27
+toolbar.area.item.image.align=center
+toolbar.area.item.image.v-align=top
+toolbar.area.item.image.cursor=hand
+
+toolbar.area.item.title.type=text
+toolbar.area.item.title.view=toolbar-item-title
+toolbar.area.item.title.attach.left=0,2
+toolbar.area.item.title.attach.right=100,-2
+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
+toolbar.area.item.title.width=55
+#toolbar.area.item.title.debug=1
+
+####### sitem
+
+toolbar.area.sitem.type=container
+toolbar.area.sitem.widgets=toolbar.area.sitem.imagearea,toolbar.area.sitem.title
+toolbar.area.sitem.propogate=1
+toolbar.area.sitem.attach.top=0,1
+toolbar.area.sitem.cursor=hand
+
+toolbar.area.sitem.imagearea.type=container
+toolbar.area.sitem.imagearea.view=toolbar-item-imagearea
+toolbar.area.sitem.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.sitem.imagearea.attach.bottom=toolbar.area.sitem.title,-1
+#toolbar.area.sitem.imagearea.attach.left=toolbar.area.sitem.title,center
+toolbar.area.sitem.imagearea.attach.left=0,0
+toolbar.area.sitem.imagearea.attach.right=100,0
+toolbar.area.sitem.imagearea.background={image.toolbar.2nd.m-bg}
+toolbar.area.sitem.imagearea.background-over={image.toolbar.2nd.m-bg}
+toolbar.area.sitem.imagearea.background-down={template.imagedir}/tb/sec_r_l_down.png,{template.imagedir}/tb/sec_m_down.png,{template.imagedir}/tb/sec_l_r_down.png
+toolbar.area.sitem.imagearea.background.drawmode=tile-x
+toolbar.area.sitem.imagearea.height=25
+toolbar.area.sitem.imagearea.minwidth=38
+
+toolbar.area.sitem.image.type=image
+toolbar.area.sitem.image.view=toolbar-item-image
+toolbar.area.sitem.image.attach.left=0,0
+toolbar.area.sitem.image.attach.right=100,0
+toolbar.area.sitem.image.attach.top=0,2
+toolbar.area.sitem.image.attach.bottom=100,0
+toolbar.area.sitem.image.align=center
+toolbar.area.sitem.image.v-align=center
+toolbar.area.sitem.image.cursor=hand
+toolbar.area.sitem.image.drawmode=center
+toolbar.area.sitem.image.width=1
+
+toolbar.area.sitem.title.type=text
+toolbar.area.sitem.title.view=toolbar-item-title
+toolbar.area.sitem.title.attach.left=0,0
+toolbar.area.sitem.title.attach.right=100,0
+toolbar.area.sitem.title.attach.bottom=100,0
+#toolbar.area.sitem.title.color=#ff0000
+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
+toolbar.area.sitem.title.fgcolor-disabled=#808080
+
+###
+
+toolbar.area.sitem.left.type=container
+toolbar.area.sitem.left.widgets=toolbar.area.sitem.l.imagearea,toolbar.area.sitem.title
+toolbar.area.sitem.left.attach.top=0,1
+toolbar.area.sitem.left.cursor=hand
+toolbar.area.sitem.left.propogate=1
+
+toolbar.area.sitem.l.imagearea.type=container
+toolbar.area.sitem.l.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.sitem.l.imagearea.attach.bottom=toolbar.area.sitem.title,-1
+toolbar.area.sitem.l.imagearea.attach.left=0,0
+toolbar.area.sitem.l.imagearea.attach.right=100,0
+toolbar.area.sitem.l.imagearea.background={image.toolbar.2nd.l-bg}
+toolbar.area.sitem.l.imagearea.background-over={image.toolbar.2nd.l-bg}
+toolbar.area.sitem.l.imagearea.background-down={image.toolbar.2nd.l-bg-down}
+toolbar.area.sitem.l.imagearea.background.drawmode=tile-x
+toolbar.area.sitem.l.imagearea.height=25
+toolbar.area.sitem.l.imagearea.minwidth=38
+
+###
+
+toolbar.area.sitem.right.type=container
+toolbar.area.sitem.right.widgets=toolbar.area.sitem.r.imagearea,toolbar.area.sitem.title
+toolbar.area.sitem.right.attach.top=0,1
+toolbar.area.sitem.right.cursor=hand
+toolbar.area.sitem.right.propogate=1
+
+toolbar.area.sitem.r.imagearea.type=container
+toolbar.area.sitem.r.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.sitem.r.imagearea.attach.bottom=toolbar.area.sitem.title,-1
+toolbar.area.sitem.r.imagearea.attach.left=0,0
+toolbar.area.sitem.r.imagearea.attach.right=100,0
+toolbar.area.sitem.r.imagearea.background={image.toolbar.2nd.r-bg}
+toolbar.area.sitem.r.imagearea.background-over={image.toolbar.2nd.r-bg}
+toolbar.area.sitem.r.imagearea.background-down={image.toolbar.2nd.r-bg-down}
+toolbar.area.sitem.r.imagearea.background.drawmode=tile-x
+toolbar.area.sitem.r.imagearea.minwidth=38
+toolbar.area.sitem.r.imagearea.height=25
+
+###
+
+toolbar.area.vitem.left.type=container
+toolbar.area.vitem.left.widgets=toolbar.area.vitem.l.imagearea,toolbar.area.vitem.title
+toolbar.area.vitem.left.attach.top=0,1
+toolbar.area.vitem.left.cursor=hand
+toolbar.area.vitem.left.propogate=1
+
+toolbar.area.vitem.l.imagearea.type=container
+toolbar.area.vitem.l.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.vitem.l.imagearea.attach.bottom=toolbar.area.vitem.title,-1
+toolbar.area.vitem.l.imagearea.attach.left=0,0
+toolbar.area.vitem.l.imagearea.attach.right=100,0
+toolbar.area.vitem.l.imagearea.background={image.toolbar.2nd-view.l-bg}
+toolbar.area.vitem.l.imagearea.background-small={image.toolbar.2nd-view.l-bg}
+toolbar.area.vitem.l.imagearea.background-over-small={image.toolbar.2nd-view.l-bg}
+toolbar.area.vitem.l.imagearea.background-down-small={image.toolbar.2nd-view.l-bg-down}
+toolbar.area.vitem.l.imagearea.background-over={image.toolbar.2nd-view.l-bg}
+toolbar.area.vitem.l.imagearea.background-down={image.toolbar.2nd-view.l-bg-down}
+toolbar.area.vitem.l.imagearea.background.drawmode=tile-x
+toolbar.area.vitem.l.imagearea.minwidth=32
+toolbar.area.vitem.l.imagearea.height=25
+
+###
+
+toolbar.area.vitem.right.type=container
+toolbar.area.vitem.right.widgets=toolbar.area.vitem.r.imagearea,toolbar.area.vitem.title
+toolbar.area.vitem.right.attach.top=0,1
+toolbar.area.vitem.right.cursor=hand
+toolbar.area.vitem.right.propogate=1
+
+toolbar.area.vitem.r.imagearea.type=container
+toolbar.area.vitem.r.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.vitem.r.imagearea.attach.bottom=toolbar.area.vitem.title,-1
+toolbar.area.vitem.r.imagearea.attach.left=0,0
+toolbar.area.vitem.r.imagearea.attach.right=100,0
+toolbar.area.vitem.r.imagearea.background={image.toolbar.2nd-view.r-bg}
+toolbar.area.vitem.r.imagearea.background-small={image.toolbar.2nd-view.r-bg}
+toolbar.area.vitem.r.imagearea.background-over={image.toolbar.2nd-view.r-bg}
+toolbar.area.vitem.r.imagearea.background-down={image.toolbar.2nd-view.r-bg-down}
+toolbar.area.vitem.r.imagearea.background-over-small={image.toolbar.2nd-view.r-bg}
+toolbar.area.vitem.r.imagearea.background-down-small={image.toolbar.2nd-view.r-bg-down}
+toolbar.area.vitem.r.imagearea.background.drawmode=tile-x
+toolbar.area.vitem.r.imagearea.minwidth=32
+toolbar.area.vitem.r.imagearea.height=25
+
+
+toolbar.area.vitem.title.type=text
+toolbar.area.vitem.title.view=toolbar-item-title
+toolbar.area.vitem.title.attach.left=0,0
+toolbar.area.vitem.title.attach.right=100,0
+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=container
+toolbar.area.sitem.left2.attach.top=0,1
+toolbar.area.sitem.left2.attach.left=0,20
+
+toolbar.area.sitem.sep.type=image,{template.imagedir}/tb/sec_sep.png
+toolbar.area.sitem.sep.attach.top=0,1
+
+toolbar.area.item.sep.type=container
+toolbar.area.item.sep.attach.top=0,0
+toolbar.area.item.sep.attach.left=0,0
+
+toolbar.area.item.sep3.type=container
+toolbar.area.item.sep3.attach.top=0,0
+toolbar.area.item.sep3.attach.left=0,0
+
+classic.toolbar.area.item.sep.type=container
+classic.toolbar.area.item.sep.attach.top=0,0
+classic.toolbar.area.item.sep.attach.left=0,7
+
+classic.toolbar.area.item.sep3.type=container
+classic.toolbar.area.item.sep3.attach.top=0,0
+classic.toolbar.area.item.sep3.attach.left=0,18
+
+###
+
+maintabs.area.plus.type=image,{image.header.plus}
+maintabs.area.plus.view=plus-header
+maintabs.area.plus.align=right
+maintabs.area.plus.attach.right=100,-20
+maintabs.area.plus.attach.left=main.area.toolbar.2nd,10
+maintabs.area.plus.attach.top=maintabs.vcenter,0,center
+maintabs.area.plus.visible=0
+
+##############
+
+toolbar.area.sitem.lr.type=container
+toolbar.area.sitem.lr.widgets=toolbar.area.sitem.lr.imagearea,toolbar.area.sitem.title
+toolbar.area.sitem.lr.attach.top=0,1
+toolbar.area.sitem.lr.cursor=hand
+toolbar.area.sitem.lr.propogate=1
+
+toolbar.area.sitem.lr.imagearea.type=container
+toolbar.area.sitem.lr.imagearea.widgets=toolbar.area.sitem.image
+toolbar.area.sitem.lr.imagearea.attach.bottom=toolbar.area.sitem.title,-1
+toolbar.area.sitem.lr.imagearea.attach.left=0,0
+toolbar.area.sitem.lr.imagearea.attach.right=100,0
+toolbar.area.sitem.lr.imagearea.background={image.toolbar.2nd.lr-bg}
+toolbar.area.sitem.lr.imagearea.background-over={image.toolbar.2nd.lr-bg}
+toolbar.area.sitem.lr.imagearea.background-down={image.toolbar.2nd.lr-bg-down}
+toolbar.area.sitem.lr.imagearea.background.drawmode=tile-x
+toolbar.area.sitem.lr.imagearea.height=25
+toolbar.area.sitem.lr.imagearea.minwidth=38
+
+########
diff --git a/com/aelitis/azureus/ui/skin/skin3_transcodechooser.properties b/com/aelitis/azureus/ui/skin/skin3_transcodechooser.properties
index 5a081ca..b2cc94b 100644
--- a/com/aelitis/azureus/ui/skin/skin3_transcodechooser.properties
+++ b/com/aelitis/azureus/ui/skin/skin3_transcodechooser.properties
@@ -50,7 +50,7 @@ shell.top.widgets=shell.top.title,\
 
 shell.subtitle.type=text
 shell.subtitle.view=subtitle
-shell.subtitle.text.size=+2
+shell.subtitle.text.size=120%
 shell.subtitle.text.style=bold
 shell.subtitle.attach.left=0,{border.left2}
 shell.subtitle.attach.right=100,-{border.left2}
diff --git a/com/aelitis/azureus/ui/swt/Initializer.java b/com/aelitis/azureus/ui/swt/Initializer.java
index 8a959c4..fa91288 100644
--- a/com/aelitis/azureus/ui/swt/Initializer.java
+++ b/com/aelitis/azureus/ui/swt/Initializer.java
@@ -20,19 +20,25 @@
 package com.aelitis.azureus.ui.swt;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Display;
+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.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;
+import org.gudy.azureus2.plugins.PluginEventListener;
 import org.gudy.azureus2.plugins.utils.DelayedTask;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 import org.gudy.azureus2.ui.common.util.UserAlerts;
 import org.gudy.azureus2.ui.swt.*;
@@ -48,29 +54,58 @@ import org.gudy.azureus2.ui.swt.updater2.PreUpdateChecker;
 import org.gudy.azureus2.ui.swt.updater2.SWTUpdateChecker;
 
 import com.aelitis.azureus.core.*;
-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.core.versioncheck.VersionCheckClient;
+import com.aelitis.azureus.core.versioncheck.VersionCheckClientListener;
 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.listener.*;
 import com.aelitis.azureus.ui.swt.browser.msg.MessageDispatcherSWT;
-import com.aelitis.azureus.ui.swt.content.RelatedContentUI;
 import com.aelitis.azureus.ui.swt.devices.DeviceManagerUI;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
 import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
+import com.aelitis.azureus.ui.swt.shells.main.MainWindowFactory;
+import com.aelitis.azureus.ui.swt.shells.main.MainWindowFactory.MainWindowInitStub;
 import com.aelitis.azureus.ui.swt.subscriptions.SubscriptionManagerUI;
 import com.aelitis.azureus.ui.swt.utils.UIMagnetHandler;
+import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.InitialisationFunctions;
 
 /**
  * @author TuxPaper
  * @created May 29, 2006
  *
+ * @notes
+ * The old Initializer would store up LogEvents if the UI had the console set
+ * to auto-open, and send the events to the mainwindow when it was initialized 
+ * This Initializer doesn't do this (yet)
+ 	    final ArrayList logEvents = new ArrayList();
+	    ILogEventListener logListener = null;
+	    if (COConfigurationManager.getBooleanParameter("Open Console", false)) {
+	    	logListener = new ILogEventListener() {
+					public void log(LogEvent event) {
+						logEvents.add(event);
+					}
+	    	};
+	    	Logger.addListener(logListener);
+	    }
+	    final ILogEventListener finalLogListener = logListener;
+ *
+ * The old initializer sets a semaphore when it starts loading IPFilters,
+ * and on AzureusCoreListener.coreStarted would:
+						IpFilterManager ipFilterManager = azureus_core.getIpFilterManager();
+						if (ipFilterManager != null) {
+							String s = MessageText.getString("splash.loadIpFilters");
+	  					do {
+	  						reportCurrentTask(s);
+	  						s += ".";
+	  					} while (!semFilterLoader.reserve(3000));
+						}
  */
 public class Initializer
 	implements IUIIntializer
@@ -81,7 +116,7 @@ public class Initializer
 	// Used in debug to find out how long initialization took
 	public static final long startTime = System.currentTimeMillis();
 
-	private static StartServer startServer;
+	private StartServer startServer;
 
 	private final AzureusCore core;
 
@@ -93,52 +128,43 @@ public class Initializer
 
 	private int curPercent = 0;
 
+  private AESemaphore semFilterLoader = new AESemaphore("filter loader");
+  
 	private AESemaphore init_task = new AESemaphore("delayed init");
 
-	private MainWindow mainWindow;
+	private MainWindowFactory.MainWindowInitStub windowInitStub;;
 	
 	private static Initializer lastInitializer;
 
-	public static void main(final String args[]) {
-		if (Launcher.checkAndLaunch(Initializer.class, args))
-			return;
-
-		if (System.getProperty("ui.temp") == null) {
-			System.setProperty("ui.temp", "az3");
-		}
-
-		org.gudy.azureus2.ui.swt.Main.main(args);
-	}
-
 	/**
-	 * Main Initializer.  Usually called by reflection
+	 * Main Initializer.  Usually called by reflection via
+	 * org.gudy.azureus2.ui.swt.Main(String[])
 	 * @param core
 	 * @param args
 	 */
-	public Initializer(AzureusCore core, boolean createSWTThreadAndRun,
-			String[] args) {
+	public Initializer(final AzureusCore core, StartServer startServer, String[] args) {
 		this.core = core;
 		this.args = args;
+		this.startServer = startServer;
 		lastInitializer = this;
 
-		if (createSWTThreadAndRun) {
-			try {
-				SWTThread.createInstance(this);
-			} catch (SWTThreadAlreadyInstanciatedException e) {
-				Debug.printStackTrace(e);
-			}
-		} else {
-
-			initializePlatformClientMessageContext();
-			new AEThread2("cleanupOldStuff", true) {
-				public void run() {
-					cleanupOldStuff();
+    Thread filterLoaderThread = new AEThread("filter loader", true) {
+			public void runSupport() {
+				try {
+					core.getIpFilterManager().getIPFilter();
+				} finally {
+					semFilterLoader.releaseForever();
 				}
-			}.start();
-
-			PlatformConfigMessenger.login(ContentNetwork.CONTENT_NETWORK_VUZE, 0);
-			// typically the caller will call run() now 
-		}
+			}
+		};
+		filterLoaderThread.setPriority(Thread.MIN_PRIORITY);
+		filterLoaderThread.start();
+
+    try {
+      SWTThread.createInstance(this);
+    } catch(SWTThreadAlreadyInstanciatedException e) {
+    	Debug.printStackTrace( e );
+    }
 	}
 	
 	private void cleanupOldStuff() {
@@ -199,6 +225,37 @@ public class Initializer
 	}
 
 	public void runInSWTThread() {
+		UISwitcherUtil.calcUIMode();
+		
+		try {
+  		initializePlatformClientMessageContext();
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+		new AEThread2("cleanupOldStuff", true) {
+			public void run() {
+				cleanupOldStuff();
+			}
+		}.start();
+
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+
+		if (!uiClassic) {
+			PlatformConfigMessenger.login(0);
+		}
+		
+		VersionCheckClient.getSingleton().addVersionCheckClientListener(true,
+				new VersionCheckClientListener() {
+					public void versionCheckStarted(String reason) {
+						if (VersionCheckClient.REASON_UPDATE_CHECK_START.equals(reason)
+								|| VersionCheckClient.REASON_UPDATE_CHECK_PERIODIC.equals(reason)) {
+							PlatformConfigMessenger.sendVersionServerMap(VersionCheckClient.constructVersionCheckMessage(reason));
+						}
+					}
+				});
+
+		FeatureManagerUI.registerWithFeatureManager();
+
 		COConfigurationManager.setBooleanDefault("ui.startfirst", true);
 		STARTUP_UIFIRST = STARTUP_UIFIRST
 				&& COConfigurationManager.getBooleanParameter("ui.startfirst", true);
@@ -213,8 +270,41 @@ public class Initializer
 		UIConfigDefaultsSWT.initialize();
 
 		UIConfigDefaultsSWTv3.initialize(core);
+		
+		checkInstallID();
+
+		windowInitStub = MainWindowFactory.createAsync( Display.getDefault(), this );
+	}
 
-		mainWindow = new MainWindow(Display.getDefault(), this);
+	/**
+	 * 
+	 *
+	 * @since 4.4.0.5
+	 */
+	private void checkInstallID() {
+		String storedInstallID = COConfigurationManager.getStringParameter("install.id", null);
+		String installID = "";
+		File file = FileUtil.getApplicationFile("installer.log");
+		if (file != null) {
+			try {
+				String s = FileUtil.readFileAsString(file, 1024);
+				String[] split = s.split("[\r\n]");
+				for (int i = 0; i < split.length; i++) {
+					int posEquals = split[i].indexOf('=');
+					if (posEquals > 0 && split[i].length() > posEquals + 1) {
+						installID = split[i].substring(posEquals + 1);
+					}
+				}
+			} catch (IOException e) {
+			}
+		}
+		
+		if (storedInstallID == null || !storedInstallID.equals(installID)) {
+			COConfigurationManager.setParameter("install.id", installID);
+			// different or new installid
+			Utils.launch(ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+					"/install/first.start?iid=" + installID, true));
+		}
 	}
 
 	public void run() {
@@ -240,6 +330,9 @@ public class Initializer
 		new UIMagnetHandler(core);
 		
 		if (!STARTUP_UIFIRST) {
+			// Ensure colors initialized
+			Colors.getInstance();
+
 			UIConfigDefaultsSWT.initialize();
 			UIConfigDefaultsSWTv3.initialize(core);
 		} else {
@@ -345,16 +438,13 @@ public class Initializer
 					reportCurrentTaskByKey("splash.initializeGui");
 	
 					Initializer.this.reportPercent(curPercent + 1);
-					Cursors.init();
-	
-					Initializer.this.reportPercent(curPercent + 1);
 					
 					main_window_will_report_complete = true;
 					
 					if (STARTUP_UIFIRST) {
-						mainWindow.init(core);
+						windowInitStub.init(core);
 					} else {
-						new MainWindow(core, Display.getDefault(), Initializer.this);
+						MainWindowFactory.create( core, Display.getDefault(), Initializer.this );
 					}
 					
 					reportCurrentTaskByKey("splash.openViews");
@@ -409,39 +499,36 @@ public class Initializer
 			
 			public boolean stopRequested(AzureusCore _core)
 					throws AzureusCoreException {
-				return org.gudy.azureus2.ui.swt.mainwindow.Initializer.handleStopRestart(false);
+				return handleStopRestart(false);
 			}
 
 			public boolean restartRequested(final AzureusCore core) {
-				return org.gudy.azureus2.ui.swt.mainwindow.Initializer.handleStopRestart(true);
+				return handleStopRestart(true);
 			}
 
 		});
 
 		reportCurrentTaskByKey("splash.initializeCore");
 
-		try{
-			new SubscriptionManagerUI();
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace(e);
-		}
-		
-		try{
-			RelatedContentUI.getSingleton();
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace(e);
-		}
-		
-		try{
-			new DeviceManagerUI( core );
-				
-		}catch( Throwable e ){
-				
-			Debug.printStackTrace(e);
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+
+		if (!uiClassic) {
+  		try{
+  			new SubscriptionManagerUI();
+  			
+  		}catch( Throwable e ){
+  			
+  			Debug.printStackTrace(e);
+  		}
+
+  		
+  		try{
+  			new DeviceManagerUI( core );
+  				
+  		}catch( Throwable e ){
+  				
+  			Debug.printStackTrace(e);
+  		}
 		}
 		
 		core.start();
@@ -496,11 +583,38 @@ public class Initializer
 				Debug.out(e);
 			}
 
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					SWTThread.getInstance().terminate();
-				}
-			});
+			if (false) {
+				// No Unix as it will dispose before isTerminated is set, causing
+				// a 'user close' flag to be incorrectly set and used
+  			Utils.execSWTThread(new AERunnable() {
+  				public void runSupport() {
+  					SWTThread instance = SWTThread.getInstance();
+  					if (instance == null || instance.isTerminated()) {
+  						return;
+  					}
+  					Shell anyShell = Utils.findAnyShell();
+  					Point location = null;
+  					if (anyShell != null) {
+  						Rectangle bounds = anyShell.getBounds();
+  						location = new Point(bounds.x, bounds.y);
+  					}
+  					Shell[] shells = instance.getDisplay().getShells();
+  					for (Shell shell : shells) {
+  						if (!shell.isDisposed()) {
+  							shell.dispose();
+  						}
+  					}
+      			Shell shell = new Shell(instance.getDisplay(), SWT.BORDER | SWT.TITLE);
+      			Utils.setShellIcon(shell);
+      			shell.setText("Shutting Down Vuze..");
+      			shell.setSize(200, 0);
+      			if (location != null) {
+      				shell.setLocation(location);
+      			}
+      			shell.open();
+  				}
+  			});
+			}
 
 		} finally {
 
@@ -537,6 +651,13 @@ public class Initializer
 					startServer.stopIt();
 				}
 			}
+
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					SWTThread.getInstance().terminate();
+				}
+			});
+
 		}
 	}
 
@@ -631,18 +752,33 @@ public class Initializer
 	{
 		core.getPluginManager().firePluginEvent( PluginEvent.PEV_INITIALISATION_UI_COMPLETES );
 
-		  new DelayedEvent( 
-				  "SWTInitComplete:delay",
-				  2500,
-				  new AERunnable()
-				  {
-					  public void
-					  runSupport()
+		// Old Initializer would delay 8500
+
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+			  new DelayedEvent( 
+					  "SWTInitComplete:delay",
+					  500,
+					  new AERunnable()
 					  {
-					  	//System.out.println("Release Init. Task");
-						  init_task.release();
-					  }
-				  });
+						  public void
+						  runSupport()
+						  {
+						  	/*
+						  	try {
+									String captureSnapshot = new Controller().captureSnapshot(ProfilingModes.SNAPSHOT_WITH_HEAP);
+									System.out.println(captureSnapshot);
+								} catch (Exception e) {
+									// TODO Auto-generated catch block
+									e.printStackTrace();
+								}
+								*/
+						  	//System.out.println("Release Init. Task");
+							  init_task.release();
+						  }
+					  });
+			}
+		});
 	}
 
 	/**
@@ -659,8 +795,38 @@ public class Initializer
 			clientMsgContext.addMessageListener(new DisplayListener(null));
 			clientMsgContext.addMessageListener(new ConfigListener(null));
 		}
+		PluginInitializer.getDefaultInterface().addEventListener(new PluginEventListener() {
+			public void handleEvent(PluginEvent ev) {
+				try {
+  				int type = ev.getType();
+  				String event = null;
+  				if (type == PluginEvent.PEV_PLUGIN_INSTALLED) {
+  					event = "installed";
+  				} else if (type == PluginEvent.PEV_PLUGIN_UNINSTALLED) {
+  					event = "uninstalled";
+  				}
+  				if (event != null && (ev.getValue() instanceof String)) {
+  					PlatformConfigMessenger.logPlugin(event, (String) ev.getValue());
+  				}
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		});
 	}
 
+  public static boolean
+  handleStopRestart(
+  	final boolean	restart )
+  {
+		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (functionsSWT != null) {
+			return functionsSWT.dispose(restart, true);
+		}
+
+		return false;
+	}
+	
 	public static Initializer getLastInitializer() {
 		return lastInitializer;
 	}
diff --git a/com/aelitis/azureus/ui/swt/Sleak.java b/com/aelitis/azureus/ui/swt/Sleak.java
deleted file mode 100644
index ff654ec..0000000
--- a/com/aelitis/azureus/ui/swt/Sleak.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Created on Sep 10, 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 com.aelitis.azureus.ui.swt;
-
-/*
- * Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
- * This file is made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.widgets.List;
-
-import com.aelitis.azureus.launcher.Launcher;
-import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
-
-/**
- * Code to detect swt leak
- *
- */
-public class Sleak
-{
-	Display display;
-
-	Shell shell;
-
-	List list;
-
-	Canvas canvas;
-
-	Button start, stop, check;
-
-	Text text;
-
-	Text label;
-
-	Object[] oldObjects = new Object[0];
-
-	Error[] oldErrors = new Error[0];
-
-	Object[] objects = new Object[0];
-
-	Error[] errors = new Error[0];
-
-	Map all = new HashMap();
-	
-	ArrayList oldNonResources = new ArrayList();
-
-	public void open() {
-		display = Display.getCurrent();
-		shell = new Shell(display);
-		shell.setText("S-Leak");
-		list = new List(shell, SWT.BORDER | SWT.V_SCROLL);
-		list.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshObject();
-			}
-		});
-		text = new Text(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
-		canvas = new Canvas(shell, SWT.BORDER);
-		canvas.addListener(SWT.Paint, new Listener() {
-			public void handleEvent(Event event) {
-				paintCanvas(event);
-			}
-		});
-		check = new Button(shell, SWT.CHECK);
-		check.setText("Stack");
-		check.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				toggleStackTrace();
-			}
-		});
-		start = new Button(shell, SWT.PUSH);
-		start.setText("Snap");
-		start.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshAll();
-			}
-		});
-		stop = new Button(shell, SWT.PUSH);
-		stop.setText("Diff");
-		stop.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshDifference();
-			}
-		});
-		label = new Text(shell, SWT.BORDER | SWT.READ_ONLY + SWT.MULTI);
-		label.setText("0 object(s)");
-		shell.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event e) {
-				layout();
-			}
-		});
-		check.setSelection(false);
-		text.setVisible(false);
-		Point size = shell.getSize();
-		shell.setSize(size.x / 2, size.y / 2);
-		shell.open();
-	}
-
-	void refreshLabel() {
-		int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0, regions = 0, others = 0, composites = 0, labels = 0;
-		for (int i = 0; i < objects.length; i++) {
-			Object object = objects[i];
-			if (object instanceof Color) {
-				colors++;
-			} else if (object instanceof Cursor) {
-				cursors++;
-			} else if (object instanceof Font) {
-				fonts++;
-			} else if (object instanceof GC) {
-				gcs++;
-			} else if (object instanceof Image) {
-				images++;
-			} else if (object instanceof Region) {
-				regions++;
-			} else if (object instanceof Composite) {
-				composites++;
-			} else if (object instanceof Label) {
-				labels++;
-			} else {
-				others++;
-			}
-		}
-		String string = "";
-		if (colors != 0) {
-			string += colors + " Color(s)\n";
-		}
-		if (cursors != 0) {
-			string += cursors + " Cursor(s)\n";
-		}
-		if (fonts != 0) {
-			string += fonts + " Font(s)\n";
-		}
-		if (gcs != 0) {
-			string += gcs + " GC(s)\n";
-		}
-		if (images != 0) {
-			string += images + " Image(s)\n";
-		}
-		if (composites != 0) {
-			string += composites + " composite(s)\n";
-		}
-		if (labels != 0) {
-			string += labels + " label(s)\n";
-		}
-		if (others != 0) {
-			string += others + " Other(s)\n";
-		}
-		/* Currently regions are not counted. */
-		//	if (regions != 0) string += regions + " Region(s)\n";
-		if (string.length() != 0) {
-			string = string.substring(0, string.length() - 1);
-		}
-		label.setText(string);
-	}
-
-	void refreshDifference() {
-		DeviceData info = display.getDeviceData();
-		if (!info.tracking) {
-			MessageBox dialog = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
-			dialog.setText(shell.getText());
-			dialog.setMessage("Warning: Device is not tracking resource allocation");
-			dialog.open();
-		}
-		Object[] newObjects = info.objects;
-		Error[] newErrors = info.errors;
-		Object[] diffObjects = new Object[newObjects.length];
-		Error[] diffErrors = new Error[newErrors.length];
-		int countResourceType = 0;
-		for (int i = 0; i < newObjects.length; i++) {
-			int index = 0;
-			while (index < oldObjects.length) {
-				if (newObjects[i] == oldObjects[index]) {
-					break;
-				}
-				index++;
-			}
-			if (index == oldObjects.length) {
-				diffObjects[countResourceType] = newObjects[i];
-				diffErrors[countResourceType] = newErrors[i];
-				countResourceType++;
-			}
-		}
-
-		Shell[] shells = display.getShells();
-		ArrayList nonResourceList = new ArrayList();
-		for (int i = 0; i < shells.length; i++) {
-			Shell shell = shells[i];
-			if (shell != this.shell) {
-				buildObjectList(shell, nonResourceList);
-			}
-		}
-		oldNonResources = nonResourceList;
-		Object[] nonResources = nonResourceList.toArray();
-		int countNonResources = nonResources.length;
-
-		int total = countResourceType + countNonResources;
-
-		objects = new Object[total];
-		errors = new Error[total];
-		System.arraycopy(diffObjects, 0, objects, 0, countResourceType);
-		System.arraycopy(diffErrors, 0, errors, 0, countResourceType);
-		System.arraycopy(nonResources, 0, objects, countResourceType,
-				countNonResources);
-		list.removeAll();
-		text.setText("");
-		canvas.redraw();
-		for (int i = 0; i < objects.length; i++) {
-			list.add(objectName(objects[i]));
-		}
-		System.out.println(countResourceType);
-		refreshLabel();
-		layout();
-	}
-
-	/**
-	 * @param shell2
-	 * @param list2
-	 */
-	private void buildObjectList(Control control, ArrayList list) {
-		if (!oldNonResources.contains(control)) {
-			list.add(control);
-		}
-
-		if (control instanceof Composite) {
-			Composite c = (Composite) control;
-			Control[] children = c.getChildren();
-			for (int i = 0; i < children.length; i++) {
-				Control control2 = children[i];
-				buildObjectList(control2, list);
-			}
-		}
-	}
-
-	String objectName(Object object) {
-		Date timeAdded = (Date)all.get(object);
-		if (timeAdded == null) {
-			timeAdded = new Date();
-			all.put(object, timeAdded);
-		}
-
-		String string = timeAdded + "] " + object.toString();
-		if (object instanceof Resource) {
-			return string;
-		}
-
-		int index = string.indexOf(" {");
-		if (index == -1) {
-			return string;
-		}
-		string = string.substring(0, index);
-		if (object instanceof Composite) {
-			Control[] children = ((Composite) object).getChildren();
-			string += ": " + children.length + " kids";
-		}
-		return string;
-	}
-
-	void toggleStackTrace() {
-		refreshObject();
-		layout();
-	}
-
-	void paintCanvas(Event event) {
-		canvas.setCursor(null);
-		int index = list.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-		GC gc = event.gc;
-		Object object = objects[index];
-		if (object instanceof Color) {
-			if (((Color) object).isDisposed()) {
-				gc.drawString("Color disposed", 0, 0);
-				return;
-			}
-			gc.setBackground((Color) object);
-			gc.fillRectangle(canvas.getClientArea());
-			return;
-		}
-		if (object instanceof Cursor) {
-			if (((Cursor) object).isDisposed()) {
-				gc.drawString("Cursor disposed", 0, 0);
-				return;
-			}
-			canvas.setCursor((Cursor) object);
-			return;
-		}
-		if (object instanceof Font) {
-			if (((Font) object).isDisposed()) {
-				gc.drawString("Font disposed", 0, 0);
-				return;
-			}
-			gc.setFont((Font) object);
-			FontData[] array = gc.getFont().getFontData();
-			String string = "";
-			String lf = text.getLineDelimiter();
-			for (int i = 0; i < array.length; i++) {
-				FontData data = array[i];
-				String style = "NORMAL";
-				int bits = data.getStyle();
-				if (bits != 0) {
-					if ((bits & SWT.BOLD) != 0) {
-						style = "BOLD ";
-					}
-					if ((bits & SWT.ITALIC) != 0) {
-						style += "ITALIC";
-					}
-				}
-				string += data.getName() + " " + data.getHeight() + " " + style + lf;
-			}
-			gc.drawString(string, 0, 0);
-			return;
-		}
-		//NOTHING TO DRAW FOR GC
-		//	if (object instanceof GC) {
-		//		return;
-		//	}
-		if (object instanceof Image) {
-			if (((Image) object).isDisposed()) {
-				gc.drawString("Image disposed", 0, 0);
-				return;
-			}
-			Image image = (Image) object;
-			gc.drawString(image.getBounds().toString(), 0, 0);
-			gc.drawImage(image, 0, 15);
-			return;
-		}
-		if (object instanceof Region) {
-			if (((Region) object).isDisposed()) {
-				return;
-			}
-			String string = ((Region) object).getBounds().toString();
-			gc.drawString(string, 0, 0);
-			return;
-		}
-
-		if (object instanceof Control) {
-			Control control = (Control) object;
-			if (control.isDisposed()) {
-				return;
-			}
-			Rectangle bounds = control.getBounds();
-			
-			gc.drawString(object.toString(), 0, 0);
-			gc.drawString(bounds.toString(), 0, 20);
-
-			if (object instanceof Widget) {
-				Object data = ((Widget)object).getData("sleak");
-				if (data != null) {
-					gc.drawString(data.toString(), 0, 35);
-				}
-			}
-
-  		
-  		GC gcControl = new GC(control);
-  		try {
-  			Image img = new Image(control.getDisplay(), bounds.width, bounds.height);
-  			gcControl.copyArea(img, 0, 0);
-  			
-  			gc.drawImage(img, 0, 45);
-  			
-  			img.dispose();
-  		} catch (Exception e) {
-  		} finally {
-  			gcControl.dispose();
-  			
-  		}
-			return;
-		}
-	}
-
-	void refreshObject() {
-		int index = list.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-		if (check.getSelection() && index < errors.length && errors[index] == null) {
-			ByteArrayOutputStream stream = new ByteArrayOutputStream();
-			PrintStream s = new PrintStream(stream);
-			errors[index].printStackTrace(s);
-			text.setText(stream.toString());
-			text.setVisible(true);
-			canvas.setVisible(false);
-		} else {
-			canvas.setVisible(true);
-			text.setVisible(false);
-			canvas.redraw();
-		}
-	}
-
-	void refreshAll() {
-		oldObjects = new Object[0];
-		oldErrors = new Error[0];
-		oldNonResources = new ArrayList();
-		refreshDifference();
-		oldObjects = objects;
-		oldErrors = errors;
-	}
-
-	void layout() {
-		Rectangle rect = shell.getClientArea();
-		int width = 0;
-		String[] items = list.getItems();
-		GC gc = new GC(list);
-		for (int i = 0; i < objects.length; i++) {
-			width = Math.max(width, gc.stringExtent(items[i]).x);
-		}
-		gc.dispose();
-		Point size1 = start.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size2 = stop.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size3 = check.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size4 = label.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		width = Math.max(size1.x, Math.max(size2.x, Math.max(size3.x, width)));
-		width = Math.max(64, Math.max(size4.x,
-				list.computeSize(width, SWT.DEFAULT).x));
-		start.setBounds(0, 0, width, size1.y);
-		stop.setBounds(0, size1.y, width, size2.y);
-		check.setBounds(0, size1.y + size2.y, width, size3.y);
-		label.setBounds(0, rect.height - size4.y, width, size4.y);
-		int height = size1.y + size2.y + size3.y;
-		list.setBounds(0, height, width, rect.height - height - size4.y);
-		text.setBounds(width, 0, rect.width - width, rect.height);
-		canvas.setBounds(width, 0, rect.width - width, rect.height);
-	}
-
-	public static void main(String[] args) {
-		if(Launcher.checkAndLaunch(Sleak.class, args))
-			return;
-		DeviceData data = new DeviceData();
-		data.tracking = true;
-		Display display = new Display(data);
-		Sleak sleak = new Sleak();
-		sleak.open();
-		Initializer.main(args);
-		
-		while (!sleak.shell.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-		try {
-			if (!display.isDisposed()) {
-				display.dispose();
-			}
-
-		} catch (Exception e) {
-			// TODO: handle exception
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java b/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
index 01a423d..74190d1 100644
--- a/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
+++ b/com/aelitis/azureus/ui/swt/UIConfigDefaultsSWTv3.java
@@ -25,13 +25,10 @@ import java.util.Map;
 
 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 org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
-import com.aelitis.azureus.ui.skin.SkinConstants;
 
 /**
  * @author TuxPaper
@@ -42,6 +39,10 @@ public class UIConfigDefaultsSWTv3
 {
 	public static void initialize(AzureusCore core) {
 		ConfigurationManager config = ConfigurationManager.getInstance();
+		
+		if ("az2".equalsIgnoreCase(config.getStringParameter("ui", "az3"))) {
+			return;
+		}
 
 		boolean configNeedsSave = false;
 
@@ -55,8 +56,6 @@ public class UIConfigDefaultsSWTv3
 		String sFirstVersion = config.getStringParameter("First Recorded Version");
 
 		final ConfigurationDefaults defaults = ConfigurationDefaults.getInstance();
-		// Always have the wizard complete when running az3
-		defaults.addParameter("Wizard Completed", true);
 
 		defaults.addParameter("ui", "az3");
 
@@ -83,7 +82,7 @@ public class UIConfigDefaultsSWTv3
 			}
 		}
 
-		boolean virginSwitch = config.getBooleanParameter("az3.virgin.switch", false);
+		//boolean virginSwitch = config.getBooleanParameter("az3.virgin.switch", false);
 		boolean immediateSwitch = config.getBooleanParameter(
 				"az3.switch.immediate", false);
 		if (Constants.compareVersions(sFirstVersion, "3.0.0.0") >= 0
@@ -148,11 +147,7 @@ public class UIConfigDefaultsSWTv3
 
 
 		defaults.addParameter("v3.topbar.show.frog", false);
-		defaults.addParameter("v3.topbar.show.plugin", false);
-		defaults.addParameter("ui.toolbar.uiswitcher", false);
-		defaults.addParameter(SkinConstants.VIEWID_PLUGINBAR + ".visible", false);
 		config.removeParameter("v3.home-tab.starttab");
-		defaults.addParameter("v3.topbar.height", 60);
 		defaults.addParameter("MyTorrentsView.table.style", 0);
 		defaults.addParameter("v3.Show Welcome", true);
 		
@@ -162,17 +157,21 @@ public class UIConfigDefaultsSWTv3
 		defaults.addParameter("LibraryDL.viewmode", startAdvanced ? 1 : 0);
 		defaults.addParameter("LibraryUnopened.viewmode", startAdvanced ? 1 : 0);
 		defaults.addParameter("LibraryCD.viewmode", startAdvanced ? 1 : 0);
+		defaults.addParameter("Library.CatInSideBar", startAdvanced ? 1 : 0);
 		
 		defaults.addParameter("list.dm.dblclick", "0");
+		defaults.addParameter("NameColumn.showProgramIcon", startAdvanced);
 
 		//=== defaults used by MainWindow
 		defaults.addParameter("vista.adminquit", false);
-		defaults.addParameter("Password enabled", false);
 		defaults.addParameter("Start Minimized", false);
 		defaults.addParameter("Password enabled", false);
 		defaults.addParameter("ToolBar.showText", true);
+		defaults.addParameter("burninfo.shownonce", false);
+		
+		defaults.addParameter("Table.extendedErase", !Constants.isWindowsXP);
+		defaults.addParameter("Table.useTree", true);
 		
-
 		// by default, turn off some slidey warning
 		// Since they are plugin configs, we need to set the default after the 
 		// plugin sets the default
@@ -192,7 +191,7 @@ public class UIConfigDefaultsSWTv3
 				|| (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");
+			Map<?, ?> map = FileUtil.readResilientConfigFile("tables.config");
 			if (map != null && map.size() > 0) {
   			Object[] keys = map.keySet().toArray();
   			boolean removedSome = false;
@@ -215,6 +214,12 @@ public class UIConfigDefaultsSWTv3
 			}
 		}
 		
+		// AZ3 doesn't have a View->Toolbar, so force enable
+		if (!config.getBooleanParameter("IconBar.enabled")) {
+			config.setParameter("IconBar.enabled", true);
+		}
+
+		
 		if (configNeedsSave) {
 			config.save();
 		}
diff --git a/com/aelitis/azureus/ui/swt/UIFunctionsManagerSWT.java b/com/aelitis/azureus/ui/swt/UIFunctionsManagerSWT.java
index f02da97..d3af489 100644
--- a/com/aelitis/azureus/ui/swt/UIFunctionsManagerSWT.java
+++ b/com/aelitis/azureus/ui/swt/UIFunctionsManagerSWT.java
@@ -29,11 +29,16 @@ import com.aelitis.azureus.ui.UIFunctionsManager;
  */
 public class UIFunctionsManagerSWT extends UIFunctionsManager
 {
-	public static UIFunctionsSWT getUIFunctionsSWT() {
+	public static UIFunctionsSWT 
+	getUIFunctionsSWT() 
+	{
 		UIFunctions uiFunctions = getUIFunctions();
-		if (uiFunctions instanceof UIFunctionsSWT) {
+		
+		if (uiFunctions instanceof UIFunctionsSWT){
+			
 			return (UIFunctionsSWT)uiFunctions;
 		}
+		
 		return null;
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/UIFunctionsSWT.java b/com/aelitis/azureus/ui/swt/UIFunctionsSWT.java
index 7af3a59..edde03f 100644
--- a/com/aelitis/azureus/ui/swt/UIFunctionsSWT.java
+++ b/com/aelitis/azureus/ui/swt/UIFunctionsSWT.java
@@ -19,16 +19,21 @@
  */
 package com.aelitis.azureus.ui.swt;
 
-import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.plugins.PluginView;
-import org.gudy.azureus2.ui.swt.mainwindow.*;
-import org.gudy.azureus2.ui.swt.plugins.*;
+
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainMenu;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainStatusBar;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainWindow;
+import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
 
 import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 
 /**
  * @author TuxPaper
@@ -38,38 +43,9 @@ import com.aelitis.azureus.ui.UIFunctions;
 public interface UIFunctionsSWT
 	extends UIFunctions
 {
-	public static int MAIN_MENU_BAR = MainMenu.MENU_BAR;
-
-	public static int MAIN_MENU_TRANSFER = MainMenu.MENU_TRANSFER;
-
 	public Shell getMainShell();
 
 	/**
-	 * @param view
-	 */
-	void addPluginView(PluginView view);
-
-	/**
-	 * @param view
-	 */
-	void openPluginView(PluginView view);
-
-	/**
-	 * @param view
-	 */
-	public void openPluginView(UISWTPluginView view);
-
-	/**
-	 * @param view
-	 */
-	void addPluginView(UISWTPluginView view);
-
-	/**
-	 * @param view
-	 */
-	public void removePluginView(UISWTPluginView view);
-
-	/**
 	 * @param viewID
 	 * @param l
 	 */
@@ -89,11 +65,6 @@ public interface UIFunctionsSWT
 	/**
 	 * @return
 	 */
-	public UISWTInstanceImpl getSWTPluginInstanceImpl();
-
-	/**
-	 * @return
-	 */
 	public UISWTView[] getPluginViews();
 
 	/**
@@ -107,7 +78,7 @@ public interface UIFunctionsSWT
 	public void openPluginView(String sParentID, String sViewID,
 			UISWTViewEventListener l, Object dataSource, boolean bSetFocus);
 
-	public void openPluginView(final AbstractIView view, final String name);
+	public void openPluginView(final UISWTViewCore view, final String name);
 
 	/**
 	 * @param viewID
@@ -117,25 +88,15 @@ public interface UIFunctionsSWT
 	/**
 	 * @param impl
 	 */
-	public void closePluginView(IView view);
+	public void closePluginView(UISWTViewCore view);
 
 	public void closePluginViews(String sViewID);
 
-	/**
-	 * @deprecated This method has been deprecated; menus should be retrieved directly
-	 * from an instance of IMainMenu.  Because there may be multiple instances of IMainMenu
-	 * in the application this method will not be able to discern which menu to work with.
-	 * This is especially true for OSX where each shell has its own instance of IMainMenu.
-	 * @param id
-	 * @return
-	 */
-	public Menu getMenu(int id);
-
 	public UISWTInstance getUISWTInstance();
 
 	public void refreshTorrentMenu();
 
-	public MainStatusBar getMainStatusBar();
+	public IMainStatusBar getMainStatusBar();
 
 	/**
 	 * Creates the main application menu and attach it to the given <code>Shell</code>;
@@ -164,4 +125,10 @@ public interface UIFunctionsSWT
 	public boolean hasDetailViews();
 	
 	public Shell showCoreWaitDlg();
+	
+	public MultipleDocumentInterfaceSWT getMDISWT();
+
+	public void promptForSearch();
+
+	public UIToolBarManager getToolBarManager();
 }
diff --git a/com/aelitis/azureus/ui/swt/browser/BrowserContext.java b/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
index 3829c30..6c099e5 100644
--- a/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
+++ b/com/aelitis/azureus/ui/swt/browser/BrowserContext.java
@@ -19,9 +19,7 @@
  */
 package com.aelitis.azureus.ui.swt.browser;
 
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
+import java.net.*;
 import java.util.*;
 import java.util.List;
 
@@ -45,8 +43,8 @@ import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 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.messenger.config.PlatformConfigMessenger;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 import com.aelitis.azureus.ui.swt.browser.msg.MessageDispatcherSWT;
@@ -69,7 +67,7 @@ public class BrowserContext
 
 	private static final String KEY_ENABLE_MENU = "browser.menu.enable";
 
-	private Browser browser;
+	private BrowserWrapper browser;
 
 	private Display display;
 
@@ -77,6 +75,8 @@ public class BrowserContext
 	
 	private long pageLoadingStart = 0;
 
+	private long pageLoadingEnd = 0;
+
 	private String lastValidURL = null;
 
 	private final boolean forceVisibleAfterLoad;
@@ -101,6 +101,8 @@ public class BrowserContext
 	
 	private List<String> listJS = new ArrayList<String>(1);
 	
+	private boolean allowPopups = true;
+	
 	/**
 	 * Creates a context and registers the given browser.
 	 * 
@@ -109,10 +111,10 @@ public class BrowserContext
 	 */
 	public 
 	BrowserContext(
-		String 		_id, 
-		Browser 	_browser,
-		Control 	_widgetWaitingIndicator, 
-		boolean 	_forceVisibleAfterLoad ) 
+		String 			_id, 
+		BrowserWrapper 	_browser,
+		Control 		_widgetWaitingIndicator, 
+		boolean 		_forceVisibleAfterLoad ) 
 	{
 		super( _id, null );
 		
@@ -196,7 +198,7 @@ public class BrowserContext
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
-				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+				if (browser == null || browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				
@@ -220,7 +222,7 @@ public class BrowserContext
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
-				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+				if (browser == null || browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				
@@ -262,44 +264,56 @@ public class BrowserContext
 		
 		browser.addOpenWindowListener(new OpenWindowListener() {
 			public void open(WindowEvent event) {
-				if (browser.isDisposed() || browser.getShell().isDisposed()) {
+				if (browser == null || browser.isDisposed() || browser.getShell().isDisposed()) {
 					return;
 				}
 				event.required = true;
-				
-				if (browser.getUrl().contains("js.debug=1")) {
-  				Shell shell = ShellFactory.createMainShell(SWT.SHELL_TRIM);
-  				shell.setLayout(new FillLayout());
+
+				if (browser.getUrl().contains("js.debug=1") || browser.getUrl().contains("ftux/index.php")) {
+					final Shell shell = ShellFactory.createMainShell(SWT.SHELL_TRIM);
+					shell.setLayout(new FillLayout());
+					shell.setSize(920, 500);
 					Browser subBrowser = new Browser(shell,
 							Utils.getInitialBrowserStyle(SWT.NONE));
+					subBrowser.addCloseWindowListener(new CloseWindowListener() {
+						public void close(WindowEvent event) {
+							shell.dispose();
+						}
+					});
 					shell.open();
 					event.browser = subBrowser;
 				} else {
-				
-  				final Browser subBrowser = new Browser(browser,
-  						Utils.getInitialBrowserStyle(SWT.NONE));
-  				subBrowser.addLocationListener(new LocationListener() {
-  					public void changed(LocationEvent arg0) {
-  						// TODO Auto-generated method stub
-  						
-  					}
-  					public void changing(LocationEvent event) {
-  						event.doit = false;
-  						if (!UrlFilter.getInstance().urlIsBlocked(event.location)
-  								&& (event.location.startsWith("http://") || event.location.startsWith("https://"))) {
-  							debug("open sub browser: " + event.location);
-  							Program.launch(event.location);
-  						} else {
-  							debug("blocked open sub browser: " + event.location);
-  						}
-  						Utils.execSWTThreadLater(0, new AERunnable() {
-  							public void runSupport() {
-  								subBrowser.dispose();
-  							}
-  						});
-  					}
-  				});
-					event.browser = subBrowser;
+
+					final BrowserWrapper subBrowser = new BrowserWrapper(browser.getBrowser(),
+							Utils.getInitialBrowserStyle(SWT.NONE));
+					subBrowser.addLocationListener(new LocationListener() {
+						public void changed(LocationEvent arg0) {
+							// TODO Auto-generated method stub
+
+						}
+						public void changing(LocationEvent event) {
+							event.doit = false;
+							boolean doLinkExternally = PlatformConfigMessenger.areLinksExternal(browser.getUrl());
+							if (doLinkExternally) {
+								Program.launch(event.location);
+							} else if (allowPopups()
+									&& !UrlFilter.getInstance().urlIsBlocked(event.location)
+									&& (event.location.startsWith("http://") || event.location.startsWith("https://"))) {
+								debug("open sub browser: " + event.location);
+								Program.launch(event.location);
+							} else {
+								debug("blocked open sub browser: " + event.location);
+							}
+								// parg 2012/10/2 increase delay in case causing crashes
+							
+							Utils.execSWTThreadLater(1000, new AERunnable() {
+								public void runSupport() {
+									subBrowser.dispose();
+								}
+							});
+						}
+					});
+					event.browser = subBrowser.getBrowser();
 				}
 			}
 		});
@@ -344,7 +358,9 @@ public class BrowserContext
 			}
 
 			public void changing(LocationEvent event) {
-				debug("browser.changing " + event.location);
+				// event.top is always false.  changed event has it set though..
+				debug("browser.changing " + event.location + " from "
+						+ browser.getUrl() + ";" + event.top);
 				/*
 				 * The browser might have been disposed already by the time this method is called 
 				 */
@@ -353,7 +369,7 @@ public class BrowserContext
 				}
 				
 				String event_location = event.location;
-				
+
 				//Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Location Changing", "Navigating to " + event_location );
 
 				if (event_location.startsWith("javascript")
@@ -370,6 +386,8 @@ public class BrowserContext
 				String lowerLocation = event_location.toLowerCase();
 				boolean isOurURI = lowerLocation.startsWith("magnet:")
 						|| lowerLocation.startsWith("vuze:")
+						|| lowerLocation.startsWith("bc:")
+						|| lowerLocation.startsWith("bctp:")
 						|| lowerLocation.startsWith("dht:");
 
 				if (isOurURI) {
@@ -387,6 +405,53 @@ public class BrowserContext
 
 				boolean blocked = UrlFilter.getInstance().urlIsBlocked(event_location);
 
+				if (!allowPopups()) {
+					if (blocked) {
+						return;
+					}
+
+					String curURL = browser.getUrl().toLowerCase();
+
+					boolean isPageLoadingOrRecent = isPageLoading()
+							|| (pageLoadingEnd > 0 && pageLoadingEnd + 500 > SystemTime.getCurrentTime())
+							|| event_location.contains(".admonkey.");
+
+					boolean wasSearch = curURL.startsWith(
+							"http://www.google.com/#q")
+							|| curURL.startsWith("http://www.google.com/search")
+							|| PlatformConfigMessenger.areLinksExternal(curURL);
+					boolean isSearch = event_location.startsWith("http://www.google.com/#q")
+							|| (event_location.startsWith("http://www.google.com/search"))
+							|| PlatformConfigMessenger.areLinksExternal(event_location);
+
+					if (wasSearch 
+							&& !isSearch 
+							&& !curURL.equalsIgnoreCase(event_location)
+							&& !event_location.equals("about:blank") 
+							&& !isPageLoadingOrRecent) {
+  					event.doit = false;
+						String[] contentTypes = getContentTypes(event_location, ((Browser)event.widget).getUrl());
+
+						boolean isTorrent = false;
+						for (String s : contentTypes) {
+							
+							if ( s != null ){
+								
+								if ( s.indexOf("torrent") != -1 ) {
+									
+									isTorrent = true;
+								}
+							}
+						}
+						
+						if (!isTorrent || !openTorrent(event)) {
+							Utils.launch(event.location);
+						}
+  					return;
+  				}
+
+				}
+
 				if (blocked) {
 					event.doit = false;
 					new MessageBoxShell(SWT.OK, "URL blocked", "Tried to open "
@@ -410,7 +475,10 @@ public class BrowserContext
 						boolean isVuzeFile	= false;
 						
 						//Try to catch .torrent files
-						if(event_location.endsWith(".torrent")) {
+						// URLs ending in "?torrent" on Amazon S3's Simple Storage Service 
+						// return an auto-generated a torrent based on the url, but only on
+						// GET.  HEAD will fail, so we have to trap and assume
+						if(event_location.endsWith(".torrent") || event_location.endsWith("?torrent")) {
 							isTorrent = true;
 						} else {
 							//If it's not obviously a web page
@@ -422,116 +490,37 @@ public class BrowserContext
 							
 							if ( test_for_torrent || test_for_vuze ){
 								
-								try {
-									//See what the content type is
-									URL url = new URL(event_location);
-									URLConnection conn = url.openConnection();
-									
-										// we're only trying to get the content type so just use head
-									
-									((HttpURLConnection)conn).setRequestMethod("HEAD");
-									
-									String	referer_str = null;
-									
-									try{
-										URL referer = new URL(((Browser)event.widget).getUrl());
+								String[] contentTypes = getContentTypes(event_location, ((Browser)event.widget).getUrl());
 
-										if ( referer != null ){
-											
-											referer_str = referer.toExternalForm();
-
-										}
-									}catch( Throwable e ){
-									}
+								for (String s : contentTypes) {
 									
-									UrlUtils.setBrowserHeaders( conn, referer_str );
-									
-									UrlUtils.connectWithTimeouts( conn, 1500, 5000 );
-									
-									String contentType = conn.getContentType();
-									
-									if ( contentType != null ){
+									if ( s != null ){
 										
-										if ( test_for_torrent && contentType.indexOf("torrent") != -1 ) {
-									
-											isTorrent = true;
-										}
-										
-										if ( test_for_vuze && contentType.indexOf("vuze") != -1 ) {
+										if ( test_for_torrent && s.indexOf("torrent") != -1 ) {
 											
-											isVuzeFile = true;
-										}
-									}
-									
-									String contentDisposition = conn.getHeaderField("Content-Disposition");
-									
-									if (contentDisposition != null ){
-										
-										if ( test_for_torrent && contentDisposition.indexOf(".torrent") != -1) {
-									
 											isTorrent = true;
 										}
 										
-										if ( test_for_vuze && contentDisposition.indexOf(".vuze") != -1) {
+										if ( test_for_vuze && s.indexOf("vuze") != -1 ) {
 											
 											isVuzeFile = true;
 										}
-			
 									}
-									
-								}catch( Throwable e){
 								}
 								
+									
 								//System.out.println( "Test for t/v: " + event_location + " -> " + isTorrent + "/" + isVuzeFile );
 							}
 						}
 						
 						if ( isTorrent ){
 							
-							event.doit = false;
+							openTorrent(event);
 							
-							try {
-								String referer_str = null;
-
-								try{
-									referer_str = new URL(((Browser)event.widget).getUrl()).toExternalForm();
-
-								}catch( Throwable e ){
-								}
-																
-								Map headers = UrlUtils.getBrowserHeaders( referer_str );
-											
-								
-								String cookies = (String) ((Browser)event.widget).getData("current-cookies");
-								
-								if (cookies != null ){
-									
-									headers.put("Cookie", cookies);
-								}
-								
-								String	url = event_location;
-								
-								if ( torrentURLHandler != null ){
-									
-									try{
-										torrentURLHandler.handleTorrentURL(url);
-										
-									}catch( Throwable e ){
-										
-										Debug.printStackTrace(e);
-									}
-								}
-								
-								PluginInitializer.getDefaultInterface().getDownloadManager().addDownload(
-										new URL(url), headers );
-								
-							}catch( Throwable e ){
-								
-								e.printStackTrace();
-							}
 						}else if ( isVuzeFile ){
 							
 							event.doit = false;
+							setPageLoading(false, event.location);
 							
 							try {
 								String referer_str = null;
@@ -560,6 +549,7 @@ public class BrowserContext
 								if ( vf == null ){
 									
 									event.doit = true;
+									setPageLoading(true, event.location);
 									
 								}else{
 									
@@ -592,6 +582,110 @@ public class BrowserContext
 		this.display = browser.getDisplay();
 	}
 
+	protected boolean openTorrent(LocationEvent event) {
+		event.doit = false;
+		setPageLoading(false, event.location);
+		
+		try {
+			String referer_str = null;
+
+			try{
+				referer_str = new URL(((Browser)event.widget).getUrl()).toExternalForm();
+
+			}catch( Throwable e ){
+			}
+											
+			final Map headers = UrlUtils.getBrowserHeaders( referer_str );
+						
+			
+			String cookies = (String) ((Browser)event.widget).getData("current-cookies");
+			
+			if (cookies != null ){
+				
+				headers.put("Cookie", cookies);
+			}
+			
+			final String	url = event.location;
+			
+			if ( torrentURLHandler != null ){
+				
+				try{
+					torrentURLHandler.handleTorrentURL(url);
+					
+				}catch( Throwable e ){
+					
+					Debug.printStackTrace(e);
+				}
+			}
+			
+			Utils.getOffOfSWTThread(new AERunnable() {
+				
+				public void runSupport() {
+					try {
+						PluginInitializer.getDefaultInterface().getDownloadManager().addDownload(
+								new URL(url), headers );
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+				}
+			});
+			
+			return true;
+		}catch( Throwable e ){
+			Debug.out(e);
+			return false;
+		}
+	}
+
+	protected String[] getContentTypes(String event_location, String _referer) {
+		try {
+			//See what the content type is
+			URL url = new URL(event_location);
+			URLConnection conn = url.openConnection();
+
+			// we're only trying to get the content type so just use head
+
+			((HttpURLConnection) conn).setRequestMethod("HEAD");
+
+			String referer_str = null;
+
+			try {
+				URL referer = new URL(_referer);
+
+				if (referer != null) {
+
+					referer_str = referer.toExternalForm();
+
+				}
+			} catch (Throwable e) {
+			}
+			
+
+			UrlUtils.setBrowserHeaders(conn, referer_str);
+
+			UrlUtils.connectWithTimeouts(conn, 1500, 5000);
+
+			String contentType = conn.getContentType();
+			String contentDisposition = conn.getHeaderField("Content-Disposition");
+
+
+			// There's a bug in the ":3" server where a HEAD followed by a GET on the
+			// same content results in a corrupt GET reply
+			String server = conn.getHeaderField("Server");
+			if ("application/x-bittorrent".equals(contentType) && ":3".equals(server)) {
+				Thread.sleep(6000);
+			}
+
+			return new String[] {
+				contentType,
+				contentDisposition
+			};
+		} catch (Throwable e) {
+		}
+
+		return new String[0];
+	}
+
 	/**
 	 * @param b
 	 * @param url 
@@ -599,6 +693,7 @@ public class BrowserContext
 	 * @since 3.1.1.1
 	 */
 	protected void setPageLoading(boolean b, String url) {
+		//System.out.println("SPL: " + b + ";" + url + ";" + Debug.getCompressedStackTrace());
 		// we may get multiple "load done"s (from each frame) which we don't
 		// want to skip
 		if (b && pageLoading) {
@@ -611,7 +706,8 @@ public class BrowserContext
   			pageLoadingStart = SystemTime.getCurrentTime();
   			pageLoadTime = -1;
   		} else if (pageLoadingStart > 0 && url != null) {
-  			pageLoadTime = SystemTime.getCurrentTime() - pageLoadingStart;
+  			pageLoadingEnd = SystemTime.getCurrentTime();
+  			pageLoadTime = pageLoadingEnd - pageLoadingStart;
   			executeInBrowser("clientSetLoadTime(" + pageLoadTime + ");");
   			
   			pageLoadingStart = 0;
@@ -784,7 +880,7 @@ public class BrowserContext
 	}
 
 	public void widgetDisposed(DisposeEvent event) {
-		if (event.widget == browser) {
+		if (event.widget == browser.getBrowser()) {
 			deregisterBrowser();
 		}
 	}
@@ -827,4 +923,12 @@ public class BrowserContext
 	public void setContentNetworkID(long contentNetworkID) {
 		this.contentNetworkID = contentNetworkID;
 	}
+
+	public void setAllowPopups(boolean allowPopups) {
+		this.allowPopups = allowPopups;
+	}
+
+	public boolean allowPopups() {
+		return allowPopups;
+	}
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/browser/BrowserWrapper.java b/com/aelitis/azureus/ui/swt/browser/BrowserWrapper.java
new file mode 100644
index 0000000..fb7970b
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/browser/BrowserWrapper.java
@@ -0,0 +1,277 @@
+/*
+ * Created on Oct 2, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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 org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.CloseWindowListener;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.browser.OpenWindowListener;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.browser.StatusTextListener;
+import org.eclipse.swt.browser.TitleListener;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+public class 
+BrowserWrapper 
+{
+	private Browser		browser;
+	
+	public
+	BrowserWrapper(
+		Composite		composite,
+		int				style )
+	{
+		browser = new Browser( composite, style );
+	}
+	
+	public 
+	BrowserWrapper(
+		Browser		_browser )
+	{
+		browser = _browser;
+	}
+	
+	public Browser
+	getBrowser()
+	{
+		return( browser );
+	}
+	
+	public void
+	setVisible(
+		boolean		visible )
+	{
+		browser.setVisible( visible );
+	}
+	
+	public boolean
+	isVisible()
+	{
+		return( browser.isVisible());
+	}
+	
+	public boolean
+	isDisposed()
+	{
+		return( browser.isDisposed());
+	}
+	
+	public void
+	dispose()
+	{
+		browser.dispose();
+	}
+	
+	public boolean
+	execute(
+		String		str )
+	{
+		//System.out.println( "execute: " + str );
+		
+		return( browser.execute( str ));
+	}
+	
+	public boolean
+	isBackEnabled()
+	{
+		return( browser.isBackEnabled());
+	}
+	
+	public String
+	getUrl()
+	{
+		return( browser.getUrl());
+	}
+	
+	public void
+	setUrl(
+		String		url )
+	{
+		browser.setUrl( url );
+	}
+	
+	public void
+	setText(
+		String		text )
+	{
+		browser.setText( text );
+	}
+	
+	public void
+	setData(
+		String		key,
+		Object		value )
+	{
+		browser.setData(key, value);
+	}
+
+	public Object
+	getData(
+		String	key )
+	{
+		return( browser.getData( key ));
+	}
+	
+	public void
+	back()
+	{
+		browser.back();
+	}
+	
+	public void
+	refresh()
+	{
+		browser.refresh();
+	}
+	
+	public void
+	update()
+	{
+		browser.update();
+	}
+	
+	public Shell
+	getShell()
+	{
+		return( browser.getShell());
+	}
+	
+	public Display
+	getDisplay()
+	{
+		return( browser.getDisplay());
+	}
+	
+	public Composite
+	getParent()
+	{
+		return( browser.getParent());
+	}
+	
+	public Object
+	getLayoutData()
+	{
+		return( browser.getLayoutData());
+	}
+	
+	public void
+	setLayoutData(
+		Object	data )
+	{
+		browser.setLayoutData( data );
+	}
+	
+	public void
+	setFocus()
+	{
+		browser.setFocus();
+	}
+	
+	public void
+	addListener(
+		int			type,
+		Listener	l )
+	{
+		browser.addListener( type, l );
+	}
+	
+	public void
+	addLocationListener(
+		LocationListener		l )
+	{
+		browser.addLocationListener( l );
+	}
+	
+	public void
+	removeLocationListener(
+		LocationListener		l )
+	{
+		browser.removeLocationListener( l );
+	}
+	
+	public void
+	addTitleListener(
+		TitleListener		l )
+	{
+		browser.addTitleListener( l );
+	}
+	
+	public void
+	addProgressListener(
+		ProgressListener		l )
+	{
+		browser.addProgressListener( l );
+	}
+	
+	public void
+	removeProgressListener(
+		ProgressListener		l )
+	{
+		browser.removeProgressListener( l );
+	}
+	
+	public void
+	addOpenWindowListener(
+		OpenWindowListener		l )
+	{
+		browser.addOpenWindowListener( l );
+	}
+	
+	public void
+	addCloseWindowListener(
+		CloseWindowListener		l )
+	{
+		browser.addCloseWindowListener( l );
+	}
+	
+	public void
+	addDisposeListener(
+		DisposeListener		l )
+	{
+		browser.addDisposeListener( l );
+	}
+	
+	public void
+	removeDisposeListener(
+		DisposeListener		l )
+	{
+		browser.removeDisposeListener( l );
+	}
+	
+	public void
+	addStatusTextListener(
+		StatusTextListener		l )
+	{
+		browser.addStatusTextListener( l );
+	}
+	
+	public void
+	removeStatusTextListener(
+		StatusTextListener		l )
+	{
+		browser.removeStatusTextListener( l );
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/ConfigListener.java b/com/aelitis/azureus/ui/swt/browser/listener/ConfigListener.java
index d47d073..3bbf4fd 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/ConfigListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/ConfigListener.java
@@ -37,6 +37,7 @@ import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.MapUtils;
 import com.aelitis.net.magneturi.MagnetURIHandler;
@@ -63,14 +64,14 @@ public class ConfigListener
 
 	public static final String OP_LOG = "log";
 
-	public ConfigListener(String id, Browser browser) {
+	public ConfigListener(String id, BrowserWrapper browser) {
 		super(id);
 	}
 
 	/**
 	 * 
 	 */
-	public ConfigListener(Browser browser) {
+	public ConfigListener(BrowserWrapper browser) {
 		this(DEFAULT_LISTENER_ID, browser);
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java b/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
index 1e9f116..64add18 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/DisplayListener.java
@@ -1,22 +1,17 @@
 package com.aelitis.azureus.ui.swt.browser.listener;
 
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.*;
 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;
@@ -32,15 +27,23 @@ 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.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.selectedcontent.*;
+import com.aelitis.azureus.ui.skin.SkinConstants;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 import com.aelitis.azureus.ui.swt.shells.BrowserWindow;
 import com.aelitis.azureus.ui.swt.skin.*;
-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 com.aelitis.azureus.ui.swt.views.skin.SBC_BurnFTUX;
+import com.aelitis.azureus.ui.swt.views.skin.SBC_PlusFTUX;
+import com.aelitis.azureus.util.*;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
+import org.gudy.azureus2.plugins.ui.*;
 
 public class DisplayListener
 	extends AbstractBrowserMessageListener
@@ -74,9 +77,11 @@ public class DisplayListener
 
 	public static final String OP_OPEN_SEARCH = "open-search";
 
-	private Browser browser;
+	public static final String OP_REGISTER = "open-register";
 
-	public DisplayListener(String id, Browser browser) {
+	private BrowserWrapper browser;
+
+	public DisplayListener(String id, BrowserWrapper browser) {
 		super(id);
 		this.browser = browser;
 	}
@@ -84,7 +89,7 @@ public class DisplayListener
 	/**
 	 * 
 	 */
-	public DisplayListener(Browser browser) {
+	public DisplayListener(BrowserWrapper browser) {
 		this(DEFAULT_LISTENER_ID, browser);
 	}
 
@@ -97,11 +102,15 @@ public class DisplayListener
 		} else if (OP_OPEN_URL.equals(opid)) {
 			Map decodedMap = message.getDecodedMap();
 			String target = MapUtils.getMapString(decodedMap, "target", null);
-			if (target == null && !decodedMap.containsKey("width")) {
-				launchUrl(MapUtils.getMapString(decodedMap, "url", null));
+			if ((target == null || "_blank".equals(target))
+					&& !decodedMap.containsKey("width")) {
+				launchUrl(MapUtils.getMapString(decodedMap, "url", null),
+						MapUtils.getMapBoolean(decodedMap, "append-suffix", false));
 			} else {
 				String ref = message.getReferer();
-				if (target != null && target.equals("browse") && ref != null) {
+				if (target != null
+						&& target.equals(SkinConstants.VIEWID_BROWSER_BROWSE)
+						&& ref != null) {
 					ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetworkForURL(
 							ref);
 					if (cn != null) {
@@ -136,37 +145,6 @@ public class DisplayListener
 			bringToFront();
 		} else if (OP_SWITCH_TO_TAB.equals(opid)) {
 			Map decodedMap = message.getDecodedMap();
-			/*
-			final String viewMode = MapUtils.getMapString(decodedMap, "view-mode",
-					null);
-			if (viewMode != null && viewMode.equals("small")) {
-				final SideBar sb = (SideBar) SkinViewManager.getByClass(SideBar.class);
-				if (sb != null) {
-					sb.addListener(new SideBarListener() {
-						public void sidebarItemSelected(SideBarEntrySWT newSideBarEntry,
-								SideBarEntrySWT oldSideBarEntry) {
-
-							Utils.execSWTThreadLater(0, new AERunnable() {
-
-								public void runSupport() {
-									ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-									if (tb != null) {
-										System.out.println("roar2");
-										ToolBarItem tbSmall = tb.getToolBarItem("modeSmall");
-										if (tbSmall != null && tbSmall.isEnabled()) {
-											tbSmall.triggerToolBarItem();
-										}
-									}
-								}
-							});
-
-							sb.removeListener(this);
-						}
-					});
-				}
-			}
-			*/
-
 			switchToTab(MapUtils.getMapString(decodedMap, "target", ""),
 					MapUtils.getMapString(decodedMap, "source-ref", message.getReferer()));
 		} else if (OP_REFRESH_TAB.equals(opid)) {
@@ -192,6 +170,8 @@ public class DisplayListener
 			if (uif != null) {
 				uif.doSearch(MapUtils.getMapString(decodedMap, "search-text", ""));
 			}
+		} else if (OP_REGISTER.equals(opid)) {
+			FeatureManagerUI.openLicenceEntryWindow(false, null);
 		} else {
 			throw new IllegalArgumentException("Unknown operation: " + opid);
 		}
@@ -338,14 +318,31 @@ public class DisplayListener
 	 * @since 3.0.0.7
 	 */
 	public static void switchToTab(String tabID, String sourceRef) {
-		SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sideBar == null) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
 			return;
 		}
 		if (sourceRef != null) {
-			ContentNetworkUtils.setSourceRef(tabID, sourceRef, false);
+			if (MultipleDocumentInterface.SIDEBAR_SECTION_PLUS.equals(tabID) ||
+					MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO.equals(tabID)) {
+				Pattern pattern = Pattern.compile("http.*//[^/]+/([^.]+)");
+				Matcher matcher = pattern.matcher(sourceRef);
+				
+				String sourceRef2;
+				if (matcher.find()) {
+					sourceRef2 = matcher.group(1);
+				} else {
+					sourceRef2 = sourceRef;
+				}
+				
+				if (MultipleDocumentInterface.SIDEBAR_SECTION_PLUS.equals(tabID)) {
+  				SBC_PlusFTUX.setSourceRef(sourceRef2);
+				} else {
+					SBC_BurnFTUX.setSourceRef(sourceRef2);
+				}
+			}
 		}
-		sideBar.showEntryByTabID(tabID);
+		mdi.showEntryByID(tabID);
 	}
 
 	/**
@@ -424,9 +421,10 @@ public class DisplayListener
 	private static void refreshBrowser(final String browserID) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
+				MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
 
-				SideBarEntrySWT entry = SideBar.getEntry(browserID);
+				BaseMdiEntry entry = (BaseMdiEntry) mdi.getEntrySWT(browserID);
+				//MdiEntrySWT entry = mdi.getEntrySWT(browserID);  // Use when UIs merged
 				SWTSkinObjectBrowser soBrowser = SWTSkinUtils.findBrowserSO(entry.getSkinObject());
 
 				if (soBrowser != null) {
@@ -437,7 +435,7 @@ public class DisplayListener
 				SWTSkin skin = SWTSkinFactory.getInstance();
 				SWTSkinObject skinObject = skin.getSkinObject(browserID);
 				if (skinObject instanceof SWTSkinObjectBrowser) {
-					final Browser browser = ((SWTSkinObjectBrowser) skinObject).getBrowser();
+					final BrowserWrapper browser = ((SWTSkinObjectBrowser) skinObject).getBrowser();
 					if (null != browser && false == browser.isDisposed()) {
 						browser.refresh();
 					}
@@ -446,7 +444,13 @@ public class DisplayListener
 		});
 	}
 
-	private void launchUrl(final String url) {
+	private void launchUrl(String url, boolean appendSuffix) {
+		ContentNetwork cn = ContentNetworkUtils.getContentNetworkFromTarget(null);
+		if (url.startsWith("/")){
+			url = cn.getExternalSiteRelativeURL(url, appendSuffix);
+		} else if (appendSuffix) {
+			url = cn.appendURLSuffix(url, false, true);
+		}
 		if (url.startsWith("http://") || url.startsWith("https://")
 				|| url.startsWith("mailto:")) {
 			Utils.launch(url);
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/ExternalLoginCookieListener.java b/com/aelitis/azureus/ui/swt/browser/listener/ExternalLoginCookieListener.java
index 2e20582..b4a9956 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/ExternalLoginCookieListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/ExternalLoginCookieListener.java
@@ -11,6 +11,7 @@ import org.eclipse.swt.browser.ProgressListener;
 import org.eclipse.swt.browser.StatusTextEvent;
 import org.eclipse.swt.browser.StatusTextListener;
 
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
 import com.aelitis.azureus.ui.swt.browser.CookiesListener;
 
 public class ExternalLoginCookieListener
@@ -21,7 +22,7 @@ implements StatusTextListener,LocationListener,ProgressListener
 	
 	private CookiesListener listener;
 	
-	private Browser browser;
+	private BrowserWrapper browser;
 	
 	private final static String getCookiesCode = 
 		//"{" +
@@ -31,11 +32,10 @@ implements StatusTextListener,LocationListener,ProgressListener
 		"//alert(window.status);\n" +
 		"window.status = '';" +
 		"} catch(e) {" +
-		"alert(e);" +
 		"}" ;
 		//"}";
 	
-	public ExternalLoginCookieListener(CookiesListener _listener,Browser browser) {
+	public ExternalLoginCookieListener(CookiesListener _listener,BrowserWrapper browser) {
 		this.listener = _listener;
 		this.browser = browser;
 		browser.addStatusTextListener(this);
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java b/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
index cfe091c..07908b8 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/MetaSearchListener.java
@@ -35,6 +35,7 @@ import org.gudy.azureus2.core3.global.GlobalManagerListener;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
@@ -48,6 +49,7 @@ import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 import com.aelitis.azureus.core.custom.CustomizationManagerFactory;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
+import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger;
 import com.aelitis.azureus.core.metasearch.*;
 import com.aelitis.azureus.core.metasearch.impl.ExternalLoginListener;
 import com.aelitis.azureus.core.metasearch.impl.ExternalLoginWindow;
@@ -64,9 +66,7 @@ import com.aelitis.azureus.core.vuzefile.VuzeFileComponent;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
 import com.aelitis.azureus.ui.swt.browser.OpenCloseSearchDetailsListener;
 import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.JSONUtils;
-import com.aelitis.azureus.util.UrlFilter;
+import com.aelitis.azureus.util.*;
 
 public class MetaSearchListener extends AbstractBrowserMessageListener {
 	
@@ -112,6 +112,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 	public static final String OP_IS_CUSTOMISED   				= "is-customized";
 
+	public static final String OP_ADD_EXTERNAL_LINKS   				= "add-external-links";
+
 	private static final Set	active_subs_auth = new HashSet();
 	
 	private static final Set	pending_play_now_urls = new HashSet();
@@ -221,7 +223,7 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 			public void
 			run()
 			{
-				TorrentListViewsUtils.playOrStream( download );
+				TorrentListViewsUtils.playOrStream( download, -1 );
 			}
 		}.start();
 	}
@@ -576,6 +578,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 			}catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				Map params = new HashMap();
 				params.put("error",Debug.getNestedExceptionMessage(e));
 
@@ -642,6 +646,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 			}catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				Map params = new HashMap();
 				params.put("error",Debug.getNestedExceptionMessage(e));
 
@@ -700,6 +706,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				
 			}catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				Map params = new HashMap();
 				params.put( "id", new Long( id ));
 				params.put("error",Debug.getNestedExceptionMessage(e));
@@ -744,6 +752,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 					
 				}catch( Throwable e ){
 					
+					Debug.out( e );
+					
 					Map params = new HashMap();
 					params.put( "id", new Long( id ));
 					params.put("error",Debug.getNestedExceptionMessage(e));
@@ -883,6 +893,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 									Engine 		engine,
 									Throwable 	e )
 								{
+									Debug.out( e );
+									
 									Map params = new HashMap();
 									params.put( "id", new Long( id ));
 									params.put( "error", Debug.getNestedExceptionMessage( e ));
@@ -970,6 +982,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 								}catch( Throwable e ){
 									
+									Debug.out( e );
+									
 									Map params = new HashMap();
 									params.put( "id", new Long( id ));
 									params.put( "error", "save failed: " + Debug.getNestedExceptionMessage(e));
@@ -1135,6 +1149,11 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 						Engine engine = metaSearchManager.getMetaSearch().getEngine( engineID );
 						
+						if ( engine != null ){
+							
+							engine.addPotentialAssociation( torrentUrl );
+						}
+						
 						if ( engine != null && engine instanceof WebEngine ){
 							
 							WebEngine webEngine = (WebEngine) engine;
@@ -1223,6 +1242,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "create failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage( "metasearch", "createSubscriptionFailed", result );
@@ -1292,6 +1313,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage("metasearch", "readSubscriptionFailed",result);
@@ -1361,6 +1384,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "update failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage("metasearch", "updateSubscriptionFailed",result);
@@ -1397,6 +1422,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "update failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage("metasearch", "setSubscriptionAutoDownloadFailed",result);
@@ -1456,6 +1483,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 											Subscription			subs,
 											SubscriptionException	error )
 										{
+											Debug.out( error );
+											
 											result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(error));
 	
 											sendBrowserMessage( "metasearch", "readSubscriptionResultsFailed", result );
@@ -1474,6 +1503,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			}catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage("metasearch", "readSubscriptionFailed",result);
@@ -1511,6 +1542,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				Map params = new HashMap();
 
 				params.put( "error", "delete failed: " + Debug.getNestedExceptionMessage(e));
@@ -1557,6 +1590,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "mark failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage("metasearch", "markSubscriptionResultsFailed",result);
@@ -1610,6 +1645,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 									Subscription			subs,
 									SubscriptionException	error )
 								{
+									Debug.out( error );
+									
 									result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(error));
 	
 									sendBrowserMessage( "metasearch", "downloadSubscriptionFailed", result );
@@ -1620,6 +1657,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 				}
 			} catch( Throwable e ){
 				
+				Debug.out( e );
+				
 				result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(e));
 
 				sendBrowserMessage( "metasearch", "downloadSubscriptionFailed", result );
@@ -1633,6 +1672,16 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 			params.put( "is_custom", new Boolean( custom ));
 
 			sendBrowserMessage( "metasearch", "isCustomizedResult", params );
+		}else if( OP_ADD_EXTERNAL_LINKS.equals(opid)) {
+			Map decodedMap = message.getDecodedMap();
+
+			List list = MapUtils.getMapList(decodedMap, "external-links", Collections.EMPTY_LIST);
+			for (Object o : list) {
+				if (o instanceof String) {
+					String link = (String) o;
+					PlatformConfigMessenger.addLinkExternal(link);
+				}
+			}
 		}
 	}
 	
@@ -1772,6 +1821,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 																	Subscription			subs,
 																	SubscriptionException	error )
 																{
+																	Debug.out( error );
+																	
 																	result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(error));
 	
 																	sendBrowserMessage( "metasearch", "readSubscriptionResultsFailed", result );
@@ -1779,6 +1830,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 															});		
 													}catch( Throwable error ){
 														
+														Debug.out( error );
+														
 														result.put( "error", "read failed: " + Debug.getNestedExceptionMessage(error));
 	
 														sendBrowserMessage( "metasearch", "readSubscriptionResultsFailed", result );
@@ -1883,6 +1936,8 @@ public class MetaSearchListener extends AbstractBrowserMessageListener {
 			
 			public void engineFailed(Engine engine, Throwable e) {
 				
+				Debug.out( e );
+				
 				Map params = getParams( engine );
 				
 				params.put( "error", Debug.getNestedExceptionMessage( e ));
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java b/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
index 1b87ba1..e6a0563 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/TorrentListener.java
@@ -82,7 +82,7 @@ public class TorrentListener
 				AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 					public void azureusCoreRunning(AzureusCore core) {
 						TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, playPrepare,
-								bringToFront, false);
+								bringToFront);
 					}
 				});
 			} else {
diff --git a/com/aelitis/azureus/ui/swt/browser/listener/VuzeListener.java b/com/aelitis/azureus/ui/swt/browser/listener/VuzeListener.java
index 527ef1e..bf41f72 100644
--- a/com/aelitis/azureus/ui/swt/browser/listener/VuzeListener.java
+++ b/com/aelitis/azureus/ui/swt/browser/listener/VuzeListener.java
@@ -3,12 +3,14 @@ package com.aelitis.azureus.ui.swt.browser.listener;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.util.Base32;
-
+import org.gudy.azureus2.core3.util.SystemTime;
 
 import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
 import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI.licenceDetails;
 import com.aelitis.azureus.util.MapUtils;
 
 
@@ -18,7 +20,13 @@ public class VuzeListener
 	public static final String DEFAULT_LISTENER_ID = "vuze";
 
 	public static final String OP_LOAD_VUZE_FILE = "load-vuze-file";
+
+	public static final String OP_INSTALL_TRIAL = "install-trial";
+
+	public static final String OP_GET_MODE = "get-mode";
 	
+	public static final String OP_GET_REMAINING = "get-plus-remaining";
+
 	public 
 	VuzeListener() 
 	{
@@ -58,7 +66,42 @@ public class VuzeListener
 					vfh.handleFiles( new VuzeFile[]{ vf }, 0 );
 				}
 			}
+		}else if (OP_INSTALL_TRIAL.equals(opid)) {
+			FeatureManagerUI.createTrial();
+
+		}else if (OP_GET_MODE.equals(opid)) {
+			Map decodedMap = message.getDecodedMap();
+
+			String callback = MapUtils.getMapString(decodedMap, "callback", null);
 			
+			if (callback != null) {
+				
+				context.executeInBrowser(callback + "('" + FeatureManagerUI.getMode() + "')");
+				
+			} else {
+				
+				message.debug("bad or no callback param");
+			}
+		}else if (OP_GET_REMAINING.equals(opid)) {
+			Map decodedMap = message.getDecodedMap();
+
+			String callback = MapUtils.getMapString(decodedMap, "callback", null);
+			
+			if (callback != null) {
+
+				licenceDetails fd = FeatureManagerUI.getFullFeatureDetails();
+				if (fd == null || fd.expiry == 0) {
+					context.executeInBrowser(callback + "()");
+				} else {
+					long ms1 = fd.expiry - SystemTime.getCurrentTime();
+					long ms2 = fd.displayedExpiry - SystemTime.getCurrentTime();
+					context.executeInBrowser(callback + "(" + ms1 + "," + ms2 + ")");
+				}
+				
+			} else {
+				
+				message.debug("bad or no callback param");
+			}
 		}else{
 			
 			throw new IllegalArgumentException("Unknown operation: " + opid);
diff --git a/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java b/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
index f975fa4..843cf60 100644
--- a/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
+++ b/com/aelitis/azureus/ui/swt/browser/msg/MessageDispatcherSWT.java
@@ -26,12 +26,14 @@ import java.util.Map;
 import org.eclipse.swt.browser.*;
 
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.core.messenger.ClientMessageContext;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
 import com.aelitis.azureus.core.messenger.browser.listeners.BrowserMessageListener;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
 import com.aelitis.azureus.util.JSONUtils;
 import com.aelitis.azureus.util.UrlFilter;
 
@@ -45,7 +47,7 @@ public class MessageDispatcherSWT
 
 	private Map<String, BrowserMessageListener> listeners = new HashMap<String, BrowserMessageListener>();
 
-	private Browser browser;
+	private BrowserWrapper browser;
 
 	private BrowserFunction browserFunction;
 
@@ -56,44 +58,49 @@ public class MessageDispatcherSWT
 		this.context = context;
 	}
 
-	public void registerBrowser(final Browser browser) {
+	public void registerBrowser(final BrowserWrapper browser) {
 		this.browser = browser;
 		
-		browserFunction = new BrowserFunction(browser, "sendMessageToAZ") {
-			public Object function(Object[] args) {
-				if (args == null) {
-					context.debug("sendMessageToAZ: arguments null on " + browser.getUrl());
-					return null;
-				}
-				if (args.length != 3 && args.length != 2) {
-					context.debug("sendMessageToAZ: # arguments not 2 or 3 (" + args.length + ") on " + browser.getUrl());
-					return null;
-				}
-				
-				if (!(args[0] instanceof String)) {
-					context.debug("sendMessageToAZ: Param 1 not String");
-					return null;
-				}
-				if (!(args[1] instanceof String)) {
-					context.debug("sendMessageToAZ: Param 2 not String");
-					return null;
-				}
-				Map params = Collections.EMPTY_MAP;
-				if (args.length == 3) {
-  				if (!(args[2] instanceof String)) {
-  					context.debug("sendMessageToAZ: Param 3 not String");
+		try {
+  		browserFunction = new BrowserFunction(browser.getBrowser(), "sendMessageToAZ") {
+  			public Object function(Object[] args) {
+  				if (args == null) {
+  					context.debug("sendMessageToAZ: arguments null on " + browser.getUrl());
   					return null;
   				}
- 
-  				params = JSONUtils.decodeJSON((String)args[2]);
-				}
-				
-
-				BrowserMessage message = new BrowserMessage((String) args[0], (String) args[1], params);
-				dispatch(message);
-				return null;
-			}
-		};
+  				if (args.length != 3 && args.length != 2) {
+  					context.debug("sendMessageToAZ: # arguments not 2 or 3 (" + args.length + ") on " + browser.getUrl());
+  					return null;
+  				}
+  				
+  				if (!(args[0] instanceof String)) {
+  					context.debug("sendMessageToAZ: Param 1 not String");
+  					return null;
+  				}
+  				if (!(args[1] instanceof String)) {
+  					context.debug("sendMessageToAZ: Param 2 not String");
+  					return null;
+  				}
+  				Map<?, ?> params = Collections.EMPTY_MAP;
+  				if (args.length == 3) {
+    				if (!(args[2] instanceof String)) {
+    					context.debug("sendMessageToAZ: Param 3 not String");
+    					return null;
+    				}
+   
+    				params = JSONUtils.decodeJSON((String)args[2]);
+  				}
+  				
+  
+  				BrowserMessage message = new BrowserMessage((String) args[0], (String) args[1], params);
+  				message.setReferer(browser.getUrl());
+  				dispatch(message);
+  				return null;
+  			}
+  		};
+		} catch (Throwable t) {
+			Debug.out(t);
+		}
 	}
 
 	/**
@@ -103,7 +110,7 @@ public class MessageDispatcherSWT
 	 * 
 	 * @param browser {@link Browser} which will no longer send messages
 	 */
-	public void deregisterBrowser(Browser browser) {
+	public void deregisterBrowser(BrowserWrapper browser) {
 		if (browserFunction != null && !browserFunction.isDisposed()) {
 			browserFunction.dispose();
 		}
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionAutoDownload.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionAutoDownload.java
index 210377a..3344447 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionAutoDownload.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionAutoDownload.java
@@ -20,6 +20,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 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.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
@@ -36,6 +37,13 @@ public class ColumnSubscriptionAutoDownload
 {
 	public static String COLUMN_ID = "auto-download";
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionAutoDownload(String sTableID) {
 		super(COLUMN_ID, ALIGN_CENTER, POSITION_LAST, 100, sTableID);
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionCategory.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionCategory.java
index 4ed3ac8..8ad01d4 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionCategory.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionCategory.java
@@ -19,6 +19,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
@@ -34,6 +35,13 @@ public class ColumnSubscriptionCategory
 {
 	public static String COLUMN_ID = "category";
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionCategory(String sTableID) {
 		super(COLUMN_ID, POSITION_LAST, 100, sTableID);
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionLastChecked.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionLastChecked.java
index 8266efe..e1a8ea0 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionLastChecked.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionLastChecked.java
@@ -19,6 +19,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 
 
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
 import org.gudy.azureus2.ui.swt.views.tableitems.ColumnDateSizer;
 
@@ -35,6 +36,14 @@ ColumnSubscriptionLastChecked
 {	
 	public static String COLUMN_ID = "last-checked";
 	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+			CAT_TIME
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
 	public 
 	ColumnSubscriptionLastChecked(
 		String sTableID ) 
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionName.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionName.java
index 1566bb6..0d5db46 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionName.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionName.java
@@ -28,11 +28,10 @@ import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.subscriptions.SubscriptionManagerUI;
-import com.aelitis.azureus.ui.swt.subscriptions.SubscriptionManagerUI.sideBarItem;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 
 import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.plugins.ui.tables.*;
@@ -52,6 +51,13 @@ public class ColumnSubscriptionName
 	int imageWidth = -1;
 	int imageHeight = -1;
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionName(String sTableID) {
 		super(COLUMN_ID, POSITION_LAST, 350, sTableID);
@@ -71,13 +77,6 @@ public class ColumnSubscriptionName
 		if (!cell.setSortValue(name) && cell.isValid()) {
 			return;
 		}
-
-		if (!cell.isShown()) {
-			return;
-		}
-		
-		cell.setText(name);
-		return;
 	}
 	
 	public void cellPaint(GC gc, TableCellSWT cell) {
@@ -92,12 +91,18 @@ public class ColumnSubscriptionName
 		
 		bounds.width -= (imageWidth + 5);
 		
-		GCStringPrinter.printString(gc, cell.getText(), bounds,true,false,SWT.LEFT);
-		gc.drawImage(viewImage, bounds.x + bounds.width, bounds.y + bounds.height / 2 - imageHeight / 2);
+		GCStringPrinter.printString(gc, cell.getSortValue().toString(), bounds,true,false,SWT.LEFT);
+		
+		Subscription sub = (Subscription) cell.getDataSource();
+		
+		if ( sub != null && !sub.isSearchTemplate()){
 
+			gc.drawImage(viewImage, bounds.x + bounds.width, bounds.y + bounds.height / 2 - imageHeight / 2);
+		}
+		
 		imageLoader.releaseImage("ic_view");
 		
-		//gc.drawText(cell.getText(), bounds.x,bounds.y);
+			//gc.drawText(cell.getText(), bounds.x,bounds.y);
 	}
 	
 	public void cellMouseTrigger(TableCellMouseEvent event) {
@@ -108,11 +113,11 @@ public class ColumnSubscriptionName
 			int cellWidth = cell.getWidth();
 			if(event.x > cellWidth - imageWidth - 5 && event.x < cellWidth - 5) {
 				Subscription sub = (Subscription) cell.getDataSource();
-				if(sub != null) {
+				if(sub != null && !sub.isSearchTemplate()){
 					String key = "Subscription_" + ByteFormatter.encodeString(sub.getPublicKey());
-					SideBarEntrySWT entry = SideBar.getEntry(key);
-					if (entry.isInTree()) {
-						entry.getSidebar().showEntryByID(key);
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					if (mdi != null) {
+						mdi.showEntryByID(key);
 					}
 				}
 			}
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbNewResults.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbNewResults.java
index 8eeb6e7..aa5218d 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbNewResults.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbNewResults.java
@@ -19,6 +19,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
@@ -34,11 +35,19 @@ public class ColumnSubscriptionNbNewResults
 {
 	public static String COLUMN_ID = "nb-new-results";
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionNbNewResults(String sTableID) {
 		super(COLUMN_ID, POSITION_LAST, 100, sTableID);
 		setMinWidth(100);
 		setMaxWidth(100);
+		setAlignment(ALIGN_TRAIL);
 	}
 
 	public void refresh(TableCell cell) {
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbResults.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbResults.java
index 6c56f69..8e4a602 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbResults.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNbResults.java
@@ -19,6 +19,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
@@ -34,11 +35,19 @@ public class ColumnSubscriptionNbResults
 {
 	public static String COLUMN_ID = "nb-results";
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionNbResults(String sTableID) {
 		super(COLUMN_ID, POSITION_LAST, 100, sTableID);
 		setMinWidth(100);
 		setMaxWidth(100);
+		setAlignment(ALIGN_TRAIL);
 	}
 
 	public void refresh(TableCell cell) {
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNew.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNew.java
index 02ef582..525015d 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNew.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionNew.java
@@ -20,9 +20,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
-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 org.gudy.azureus2.plugins.ui.tables.*;
 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;
@@ -63,6 +61,13 @@ public class ColumnSubscriptionNew
 		imgBounds = imgNew.getBounds();
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @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) {
 		Subscription sub = (Subscription) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionSubscribers.java b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionSubscribers.java
index d82a0ad..e395703 100644
--- a/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionSubscribers.java
+++ b/com/aelitis/azureus/ui/swt/columns/subscriptions/ColumnSubscriptionSubscribers.java
@@ -19,6 +19,7 @@ package com.aelitis.azureus.ui.swt.columns.subscriptions;
 
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import com.aelitis.azureus.core.subs.Subscription;
@@ -34,6 +35,13 @@ public class ColumnSubscriptionSubscribers
 {
 	public static String COLUMN_ID = "nb-subscribers";
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
 	/** Default Constructor */
 	public ColumnSubscriptionSubscribers(String sTableID) {
 		super(COLUMN_ID, POSITION_INVISIBLE, 100, sTableID);
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
index ae0d20f..030a60f 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnProgressETA.java
@@ -5,19 +5,24 @@ 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.eclipse.swt.widgets.*;
 
+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;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.core3.util.TimeFormatter;
 import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
 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.FilesViewMenuUtil;
+import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
+import org.gudy.azureus2.ui.swt.views.ViewUtils;
 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;
@@ -25,9 +30,12 @@ import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 import com.aelitis.azureus.core.download.DownloadManagerEnhancer;
 import com.aelitis.azureus.core.download.EnhancedDownloadManager;
 import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 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 com.aelitis.azureus.ui.swt.utils.FontUtils;
 
 import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
 import org.gudy.azureus2.plugins.ui.tables.*;
@@ -39,7 +47,8 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  */
 public class ColumnProgressETA
 	extends CoreTableColumn
-	implements TableCellAddedListener, TableCellMouseListener
+	implements TableCellAddedListener, TableCellMouseListener,
+	TableCellRefreshListener, TableCellSWTPaintListener
 {
 	public static final Class DATASOURCE_TYPE = DownloadTypeIncomplete.class;
 
@@ -47,7 +56,7 @@ public class ColumnProgressETA
 
 	private static final int borderWidth = 1;
 
-	private static final int COLUMN_WIDTH = 150;
+	private static final int COLUMN_WIDTH = 200;
 
 	public static final long SHOW_ETA_AFTER_MS = 30000;
 
@@ -59,19 +68,34 @@ public class ColumnProgressETA
 
 	private Color cBG;
 
-	private Color cFG;
-
 	private Color cBorder;
 
 	private Color cText;
 
 	Color textColor;
 
+	private Image imgArrowButton;
+
+	private Image imgPriHi;
+
+	private Image imgPriNormal;
+
+	private Image imgPriStopped;
+
+	private Image imgBGTorrent;
+
+	private Image imgBGfile;
+
+	private Color cTextDrop;
+
+	private ViewUtils.CustomDateFormat cdf;
+
 	/**
 	 * 
 	 */
 	public ColumnProgressETA(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, COLUMN_WIDTH, sTableID);
+		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, COLUMN_WIDTH, sTableID);
+		addDataSourceType(DiskManagerFileInfo.class);
 		initializeAsGraphic(COLUMN_WIDTH);
 		setAlignment(ALIGN_LEAD);
 		setMinWidth(COLUMN_WIDTH);
@@ -83,10 +107,6 @@ public class ColumnProgressETA
 		if (cBG == null) {
 			cBG = Colors.blues[Colors.BLUES_DARKEST];
 		}
-		cFG = skinProperties.getColor("color.progress.fg");
-		if (cFG == null) {
-			cFG = Colors.blues[Colors.BLUES_LIGHTEST];
-		}
 		cBorder = skinProperties.getColor("color.progress.border");
 		if (cBorder == null) {
 			cBorder = Colors.grey;
@@ -95,6 +115,17 @@ public class ColumnProgressETA
 		if (cText == null) {
 			cText = Colors.black;
 		}
+		cTextDrop = skinProperties.getColor("color.progress.text.drop");
+
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		imgArrowButton = imageLoader.getImage("image.fileprogress.arrowbtn");
+		imgPriHi = imageLoader.getImage("image.fileprogress.pri.hi");
+		imgPriNormal = imageLoader.getImage("image.fileprogress.pri.normal");
+		imgPriStopped = imageLoader.getImage("image.fileprogress.pri.stopped");
+		imgBGTorrent = imageLoader.getImage("image.progress.bg.torrent");
+		imgBGfile = imageLoader.getImage("image.progress.bg.file");
+		
+		cdf = ViewUtils.addCustomDateFormat( this );
 	}
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
@@ -103,15 +134,23 @@ public class ColumnProgressETA
 			CAT_ESSENTIAL,
 			CAT_TIME,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public void cellAdded(TableCell cell) {
-		new Cell(cell);
+		cell.setMarginHeight(3);
+		cell.setMarginWidth(8);
 	}
 
 	public void cellMouseTrigger(TableCellMouseEvent event) {
 
-		DownloadManager dm = (DownloadManager) event.cell.getDataSource();
+		Object ds = event.cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			fileInfoMouseTrigger(event);
+			return;
+		}
+
+		DownloadManager dm = (DownloadManager) ds;
 		if (dm == null) {
 			return;
 		}
@@ -136,29 +175,17 @@ public class ColumnProgressETA
 		}
 	}
 
-	private class Cell
-		implements TableCellRefreshListener, TableCellSWTPaintListener
-	{
-		private static final int MAX_PROGRESS_FILL_HEIGHT = 19;
-
-		int lastPercentDone = 0;
+	private static final int MAX_PROGRESS_FILL_HEIGHT = 19;
 
-		long lastETA;
+	public void refresh(TableCell cell) {
+		Object ds = cell.getDataSource();
+		
+		int percentDone = getPercentDone(ds);
 
-		public Cell(TableCell cell) {
-			cell.addListeners(this);
-			cell.setMarginHeight(3);
-		}
+		long sortValue = 0;
 
-		public void refresh(TableCell cell) {
+		if (ds instanceof DownloadManager) {
 			DownloadManager dm = (DownloadManager) cell.getDataSource();
-			if (dm == null) {
-				return;
-			}
-
-			int percentDone = getPercentDone(cell);
-
-			long sortValue = 0;
 
 			long completedTime = dm.getDownloadState().getLongParameter(
 					DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
@@ -167,225 +194,600 @@ public class ColumnProgressETA
 			} else {
 				sortValue = completedTime;
 			}
+		} else if (ds instanceof DiskManagerFileInfo) {
+			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+			int st = fileInfo.getStorageType();
+			if ((st == DiskManagerFileInfo.ST_COMPACT || st == DiskManagerFileInfo.ST_REORDER_COMPACT)
+					&& fileInfo.isSkipped()) {
+				sortValue = 1;
+			} else if (fileInfo.isSkipped()) {
+				sortValue = 2;
+			} else if (fileInfo.getPriority() > 0) {
+
+				int pri = fileInfo.getPriority();
+				sortValue = 4;
+
+				if (pri > 1) {
+					sortValue += pri;
+				}
+			} else {
+				sortValue = 3;
+			}
+			sortValue = (fileInfo.getDownloadManager().getState() * 10000)
+				+ percentDone + sortValue;
+		}
 
-			long eta = getETA(cell);
+		long eta = getETA(cell);
+		long speed = getSpeed(ds);
 
-			if (!cell.setSortValue(sortValue) && cell.isValid()
-					&& lastPercentDone == percentDone && lastETA == eta) {
-				return;
-			}
+		//System.out.println("REFRESH " + sortValue + ";" + ds);
+		boolean sortChanged = cell.setSortValue(sortValue);
+		
+		if (sortChanged) {
+			UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+		}
 
-			lastPercentDone = percentDone;
-			lastETA = eta;
+		long lastETA = 0;
+		long lastSpeed = 0;
+		TableRow row = cell.getTableRow();
+		if (row != null) {
+			Object data = row.getData("lastETA");
+			if (data instanceof Number) {
+				lastETA = ((Number) data).longValue();
+			}
+			row.setData("lastETA", new Long(eta));
+			data = row.getData("lastSpeed");
+			if (data instanceof Number) {
+				lastSpeed = ((Number) data).longValue();
+			}
+			row.setData("lastSpeed", new Long(speed));
+		}
 
+		if (!sortChanged && (lastETA != eta || lastSpeed != speed)) {
 			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 gc, TableCellSWT cell) {
-			DownloadManager dm = (DownloadManager) cell.getDataSource();
-			if (dm == null) {
-				return;
-			}
-			int percentDone = getPercentDone(cell);
-			long eta = getETA(cell);
+	// @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) {
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			fillInfoProgressETA(cell.getTableRowCore(), gc, (DiskManagerFileInfo) ds,
+					cell.getBounds());
+			return;
+		}
 
-			//Compute bounds ...
-			int newWidth = cell.getWidth();
-			if (newWidth <= 0) {
-				return;
-			}
-			int newHeight = cell.getHeight();
+		if( !(ds instanceof DownloadManager )){
+			return;
+		}
+		
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
 
-			Color fgFirst = gc.getForeground();
+		int percentDone = getPercentDone(ds);
+		long eta = getETA(cell);
 
-			Rectangle cellBounds = cell.getBounds();
+		//Compute bounds ...
+		int newWidth = cell.getWidth();
+		if (newWidth <= 0) {
+			return;
+		}
+		int newHeight = cell.getHeight();
 
-			int xStart = cellBounds.x + cell.getMarginWidth();
-			int yStart = cellBounds.y + cell.getMarginHeight();
+		Color fgFirst = gc.getForeground();
 
-			int xRelProgressFillStart = borderWidth;
-			int yRelProgressFillStart = borderWidth;
-			int xRelProgressFillEnd = newWidth - xRelProgressFillStart - borderWidth;
-			int yRelProgressFillEnd = yRelProgressFillStart + 13;
-			boolean showSecondLine = yRelProgressFillEnd + 10 < newHeight;
+		final Color fgOriginal = fgFirst;
+		
+		Rectangle cellBounds = cell.getBounds();
 
-			if (xRelProgressFillEnd < 10 || xRelProgressFillEnd < 10) {
-				return;
-			}
+		int xStart = cellBounds.x;
+		int yStart = cellBounds.y;
 
-			boolean bDrawProgressBar = true;
+		int xRelProgressFillStart = borderWidth;
+		int yRelProgressFillStart = borderWidth;
+		int xRelProgressFillEnd = newWidth - xRelProgressFillStart - borderWidth;
+		int yRelProgressFillEnd = yRelProgressFillStart + 13;
+		boolean showSecondLine = yRelProgressFillEnd + 10 < newHeight;
 
-			String sETALine = null;
+		if (xRelProgressFillEnd < 10 || xRelProgressFillEnd < 10) {
+			return;
+		}
+		String sETALine = null;
 
-			// Draw Progress bar
-			if (bDrawProgressBar && percentDone < 1000) {
-				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");
+		// Draw Progress bar
+		if (percentDone < 1000) {
+			ImageLoader imageLoader = ImageLoader.getInstance();
 
-				gc.drawImage(imgEnd, xStart, yStart + yRelProgressFillStart);
-				gc.drawImage(imgEnd, xStart + xRelProgressFillEnd
-						- xRelProgressFillStart + 1, yStart + yRelProgressFillStart);
+			Rectangle boundsImgBG;
 
-				int limit = ((xRelProgressFillEnd - xRelProgressFillStart) * percentDone) / 1000;
+			if (!ImageLoader.isRealImage(imgBGTorrent)) {
+				boundsImgBG = new Rectangle(0, 0, 0, 13);
+			} else {
+				boundsImgBG = imgBGTorrent.getBounds();
+			}
 
-				gc.drawImage(img1, 0, 0, 1, 13, xStart + xRelProgressFillStart, yStart
-						+ yRelProgressFillStart, limit, 13);
+			if (fontText == null) {
+				fontText = FontUtils.getFontWithHeight(gc.getFont(), gc,
+						boundsImgBG.height - 3);
+			}
 
-				if (limit < xRelProgressFillEnd) {
-					gc.drawImage(img0, 0, 0, 1, 13, xStart + limit + 1, yStart
-							+ yRelProgressFillStart, xRelProgressFillEnd - limit - 1, 13);
-				}
+			if (!showSecondLine) {
+				yRelProgressFillStart = (cellBounds.height / 2)
+						- ((boundsImgBG.height) / 2);
+			}
 
-				imageLoader.releaseImage("dl_bar_end");
-				imageLoader.releaseImage("dl_bar_0");
-				imageLoader.releaseImage("dl_bar_1");
+			yRelProgressFillEnd = yRelProgressFillStart + boundsImgBG.height;
+
+			int progressWidth = newWidth - 2;
+			gc.setForeground(cBorder);
+			gc.drawRectangle(xStart + xRelProgressFillStart - 1, yStart
+					+ yRelProgressFillStart - 1, progressWidth + 1,
+					boundsImgBG.height + 1);
+
+			int pctWidth = (int) (percentDone * (progressWidth - 1) / 1000);
+			gc.setBackground(cBG);
+			gc.fillRectangle(xStart + xRelProgressFillStart, yStart
+					+ yRelProgressFillStart, pctWidth, boundsImgBG.height);
+			gc.setBackground(Colors.white);
+			gc.fillRectangle(xStart + xRelProgressFillStart + pctWidth, yStart
+					+ yRelProgressFillStart, progressWidth - pctWidth, boundsImgBG.height);
+
+			if (boundsImgBG.width > 0) {
+				gc.drawImage(imgBGTorrent, 0, 0, boundsImgBG.width, boundsImgBG.height,
+						xStart + xRelProgressFillStart, yStart + yRelProgressFillStart,
+						progressWidth - 2, boundsImgBG.height);
 			}
+		}
 
-			if (sETALine == null) {
-				if (dm.isUnauthorisedOnTracker()) {
-					sETALine = dm.getTrackerStatus();
-					// fgFirst = Colors.colorError;	pftt, no colours allowed apparently
+		if (sETALine == null ) {
+			if (dm.isUnauthorisedOnTracker()) {
+				sETALine = dm.getTrackerStatus();
+				// fgFirst = Colors.colorError;	pftt, no colours allowed apparently
+			} else {
+				if (dm.isDownloadComplete(true)) {
+					//sETALine = DisplayFormatters.formatByteCountToKiBEtc(dm.getSize());
+				} else if (eta > 0) {
+					String sETA = ViewUtils.formatETA(eta,MyTorrentsView.progress_eta_absolute,cdf.getDateFormat());
+					sETALine = MessageText.getString(
+							"MyTorrents.column.ColumnProgressETA.2ndLine", new String[] {
+								sETA
+							});
 				} else {
-					if (dm.isDownloadComplete(true)) {
-						//sETALine = DisplayFormatters.formatByteCountToKiBEtc(dm.getSize());
-					} else if (eta > 0) {
-						String sETA = TimeFormatter.format(eta);
-						sETALine = MessageText.getString(
-								"MyTorrents.column.ColumnProgressETA.2ndLine", new String[] {
-									sETA
-								});
-					} else {
-						sETALine = DisplayFormatters.formatDownloadStatus(dm);
-					}
+					sETALine = DisplayFormatters.formatDownloadStatus(dm).toUpperCase();
 				}
+			}
 
-				int cursor_id;
+			int cursor_id;
 
-				if (sETALine != null && sETALine.indexOf("http://") == -1) {
+			if (sETALine != null && sETALine.indexOf("http://") == -1) {
 
-					dm.setUserData(CLICK_KEY, null);
+				dm.setUserData(CLICK_KEY, null);
 
-					cursor_id = SWT.CURSOR_ARROW;
+				cursor_id = SWT.CURSOR_ARROW;
 
-				} else {
+			} else {
 
-					dm.setUserData(CLICK_KEY, sETALine);
+				dm.setUserData(CLICK_KEY, sETALine);
 
-					cursor_id = SWT.CURSOR_HAND;
+				cursor_id = SWT.CURSOR_HAND;
 
-					if (!cell.getTableRow().isSelected()) {
+				if (!cell.getTableRow().isSelected()) {
 
-						fgFirst = Colors.blue;
-					}
+					fgFirst = Colors.blue;
 				}
+			}
+
+			((TableCellSWT) cell).setCursorID(cursor_id);
+		}
 
-				((TableCellSWT) cell).setCursorID(cursor_id);
+		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 = (yRelProgressFillEnd - 12) / 2;
+				
+		if (percentDone == 1000 || dm.isDownloadComplete(false)) {
+			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;
 			}
 
-			if (fontText == null) {
-				fontText = Utils.getFontWithHeight(gc.getFont(), gc, 11);
+			if ( getTableID() == TableManager.TABLE_MYTORRENTS_ALL_BIG ){
+			
+				if ( percentDone == 1000 ){
+				
+					gc.setForeground( fgOriginal  );
+					
+				}else{
+					
+					gc.setForeground(Colors.black);
+				}
+			}else{
+				
+				gc.setForeground(cText);
+			}
+			
+			String s = MessageText.getString( "MyTorrents.column.ColumnProgressETA.compon", new String[]{ DisplayFormatters.formatDateShort(value)});
+			
+			if ( percentDone < 1000 ){
+				
+				s = DisplayFormatters.formatPercentFromThousands((int)percentDone) + " " + s; // " " + Character.toLowerCase(s.charAt(0))+s.substring(1);
+			}
+			GCStringPrinter.printString(gc, s, new Rectangle(xStart + 2, yStart,
+					newWidth - 4, newHeight), true, false, SWT.WRAP);
+		} else {
+			long lSpeed = getSpeed(ds);
+			String sSpeed = lSpeed <= 0 ? "" : " ("
+					+ DisplayFormatters.formatByteCountToKiBEtcPerSec(lSpeed, true) + ")";
+
+			String sPercent = DisplayFormatters.formatPercentFromThousands(percentDone);
+
+			Rectangle area = new Rectangle(xStart + xRelProgressFillStart + 3, yStart
+					+ yRelProgressFillStart, xRelProgressFillEnd - xRelProgressFillStart
+					- 6, yRelProgressFillEnd - yRelProgressFillStart);
+			GCStringPrinter sp = new GCStringPrinter(gc, sPercent + sSpeed, area,
+					true, false, SWT.LEFT);
+			if (cTextDrop != null) {
+  			area.x++;
+  			area.y++;
+  			gc.setForeground(cTextDrop);
+  			sp.printString();
+  			area.x--;
+  			area.y--;
 			}
+			gc.setForeground(cText);
+			sp.printString();
+			Point pctExtent = sp.getCalculatedSize();
 
-			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);
+			area.width -= (pctExtent.x + 3);
+			area.x += (pctExtent.x + 3);
+
+			if (!showSecondLine && sETALine != null) {
+				boolean fit = GCStringPrinter.printString(gc, sETALine, area.intersection(cellBounds), true,
+						false, SWT.RIGHT);
+				cell.setToolTip(fit ? null:sETALine);
 			}
-			int middleY = (yRelProgressFillEnd - 12) / 2;
-			if (percentDone == 1000) {
-				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) {
-				long lSpeed = getSpeed(dm);
-				String sSpeed = lSpeed <= 0 ? "" : "("
-						+ DisplayFormatters.formatByteCountToKiBEtcPerSec(lSpeed, true)
-						+ ")";
+		gc.setFont(null);
+	}
 
-				gc.setForeground(cText);
-				String sPercent = DisplayFormatters.formatPercentFromThousands(percentDone);
-				gc.drawText(sSpeed, xStart + 50, yStart + yRelProgressFillStart + 1,
-						true);
-				gc.drawText(sPercent, xStart + 2, yStart + yRelProgressFillStart + 1,
-						true);
+	private int getPercentDone(Object ds) {
+		if (ds instanceof DownloadManager) {
+			return ((DownloadManager) ds).getStats().getDownloadCompleted(true);
+		} else if (ds instanceof DiskManagerFileInfo) {
+			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+			long length = fileInfo.getLength();
+			if (length == 0) {
+				return 1000;
 			}
+			return (int) (fileInfo.getDownloaded() * 1000 / length);
+		}
+		return 0;
+	}
 
-			gc.setFont(null);
+	private long getETA(TableCell cell) {
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			return 0;
 		}
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
 
-		private int getPercentDone(TableCell cell) {
-			DownloadManager dm = (DownloadManager) cell.getDataSource();
-			if (dm == null) {
-				return 0;
-			}
-			return dm.getStats().getDownloadCompleted(true);
+		long diff = SystemTime.getCurrentTime() - dm.getStats().getTimeStarted();
+		if (diff > SHOW_ETA_AFTER_MS) {
+			return dm.getStats().getETA();
 		}
+		return 0;
+	}
 
-		private long getETA(TableCell cell) {
-			DownloadManager dm = (DownloadManager) cell.getDataSource();
-			if (dm == null) {
-				return 0;
-			}
-			long diff = SystemTime.getCurrentTime() - dm.getStats().getTimeStarted();
-			if (diff > SHOW_ETA_AFTER_MS) {
-				return dm.getStats().getETA();
-			}
+	private int getState(TableCell cell) {
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		if (dm == null) {
+			return DownloadManager.STATE_ERROR;
+		}
+		return dm.getState();
+	}
+
+	private boolean isStopped(TableCell cell) {
+		int state = getState(cell);
+		return state == DownloadManager.STATE_QUEUED
+				|| state == DownloadManager.STATE_STOPPED
+				|| state == DownloadManager.STATE_STOPPING
+				|| state == DownloadManager.STATE_ERROR;
+	}
+
+	private long getSpeed(Object ds) {
+		if (!(ds instanceof DownloadManager)) {
 			return 0;
 		}
 
-		private int getState(TableCell cell) {
-			DownloadManager dm = (DownloadManager) cell.getDataSource();
-			if (dm == null) {
-				return DownloadManager.STATE_ERROR;
-			}
-			return dm.getState();
+		return ((DownloadManager) ds).getStats().getDataReceiveRate();
+	}
+
+	public EnhancedDownloadManager getEDM(DownloadManager dm) {
+		DownloadManagerEnhancer dmEnhancer = DownloadManagerEnhancer.getSingleton();
+		if (dmEnhancer == null) {
+			return null;
 		}
+		return dmEnhancer.getEnhancedDownload(dm);
+	}
+
+	private void log(TableCell cell, String s) {
+		System.out.println(((TableRowCore) cell.getTableRow()).getIndex() + ":"
+				+ System.currentTimeMillis() + ": " + s);
+	}
+
+	private Font progressFont;
+
+	private void fillInfoProgressETA(TableRowCore row, GC gc,
+			DiskManagerFileInfo fileInfo, Rectangle cellArea) {
+		long percent = 0;
+		long bytesDownloaded = fileInfo.getDownloaded();
+		long length = fileInfo.getLength();
+
+		if (bytesDownloaded < 0) {
+
+			return;
+
+		} else if (length == 0) {
 
-		private boolean isStopped(TableCell cell) {
-			int state = getState(cell);
-			return state == DownloadManager.STATE_QUEUED
-					|| state == DownloadManager.STATE_STOPPED
-					|| state == DownloadManager.STATE_STOPPING
-					|| state == DownloadManager.STATE_ERROR;
+			percent = 1000;
+
+		} else if (fileInfo.getLength() != 0) {
+
+			percent = (1000 * bytesDownloaded) / length;
 		}
 
-		private long getSpeed(DownloadManager dm) {
-			if (dm == null) {
-				return 0;
+		gc.setAdvanced(true);
+		gc.setTextAntialias(SWT.ON);
+
+		final int BUTTON_WIDTH = imgArrowButton.getBounds().width;
+		final int HILOW_WIDTH = imgPriHi.getBounds().width;
+		final int BUTTON_HEIGHT = imgArrowButton.getBounds().height;
+		final int HILOW_HEIGHT = imgPriHi.getBounds().height;
+		final int PADDING_X = 12;
+		final int PADDING_TEXT = 5;
+		final int PROGRESS_HEIGHT = imgBGfile.getBounds().height;
+		final int PROGRESS_TO_HILOW_GAP = 3;
+		final int HILOW_TO_BUTTON_GAP = 3;
+
+		cellArea.width -= 3;
+
+		int ofsX = PADDING_X;
+		int ofsY = (cellArea.height / 2) - (PROGRESS_HEIGHT / 2) - 1;
+		int progressWidth = cellArea.width - (ofsX * 2) - PROGRESS_TO_HILOW_GAP
+				- HILOW_WIDTH - HILOW_TO_BUTTON_GAP - BUTTON_WIDTH;
+		
+		if ( progressWidth > 0 ){
+			if (progressFont == null) {
+				progressFont = FontUtils.getFontWithHeight(gc.getFont(), gc,
+						PROGRESS_HEIGHT - 2);
 			}
+			gc.setFont(progressFont);
+			gc.setForeground(ColorCache.getSchemedColor(display, fileInfo.isSkipped()
+					? "#95a6b2" : "#88acc1"));
+			gc.drawRectangle(cellArea.x + ofsX, cellArea.y + ofsY - 1, progressWidth,
+					PROGRESS_HEIGHT + 1);
+	
+			int pctWidth = (int) (percent * (progressWidth - 1) / 1000);
+			gc.setBackground(ColorCache.getSchemedColor(display, fileInfo.isSkipped()
+					? "#a6bdce" : "#8ccfff"));
+			gc.fillRectangle(cellArea.x + ofsX + 1, cellArea.y + ofsY, pctWidth,
+					PROGRESS_HEIGHT);
+			gc.setBackground(Colors.white);
+			gc.fillRectangle(cellArea.x + ofsX + pctWidth + 1, cellArea.y + ofsY,
+					progressWidth - pctWidth - 1, PROGRESS_HEIGHT);
+	
+			Rectangle boundsImgBG = imgBGfile.getBounds();
+			gc.drawImage(imgBGfile, boundsImgBG.x, boundsImgBG.y, boundsImgBG.width,
+					boundsImgBG.height, cellArea.x + ofsX + 1,
+					cellArea.y + ofsY, progressWidth - 1, PROGRESS_HEIGHT);
+		}
+		
+		Color colorText = ColorCache.getSchemedColor(display, fileInfo.isSkipped()
+				? "#556875" : "#2678b1");
+
+		Rectangle printBounds = new Rectangle(
+				cellArea.x + PADDING_X + PADDING_TEXT, cellArea.y, progressWidth
+						- (PADDING_TEXT * 2), cellArea.height);
+		ofsY = (cellArea.height / 2) - (BUTTON_HEIGHT / 2) - 1;
+
+		Rectangle buttonBounds = new Rectangle(cellArea.x + cellArea.width
+				- BUTTON_WIDTH - PADDING_X, cellArea.y + ofsY, BUTTON_WIDTH,
+				BUTTON_HEIGHT);
+		row.setData("buttonBounds", buttonBounds);
+
+		ofsY = (cellArea.height / 2) - (HILOW_HEIGHT / 2) - 1;
+		Rectangle hilowBounds = new Rectangle(buttonBounds.x - HILOW_TO_BUTTON_GAP
+				- HILOW_WIDTH, cellArea.y + ofsY, HILOW_WIDTH, HILOW_HEIGHT);
+		row.setData("hilowBounds", hilowBounds);
+
+		gc.setForeground(colorText);
+
+		String s = DisplayFormatters.formatPercentFromThousands((int) percent);
+		GCStringPrinter.printString(gc, s, printBounds, true, false, SWT.LEFT);
+
+		//gc.setForeground(ColorCache.getRandomColor());
+
+		String tmp = null;
+		if (fileInfo.getDownloadManager().getState() == DownloadManager.STATE_STOPPED) {
+			tmp = MessageText.getString("FileProgress.stopped");
+		} else {
+
+			int st = fileInfo.getStorageType();
+			if ((st == DiskManagerFileInfo.ST_COMPACT || st == DiskManagerFileInfo.ST_REORDER_COMPACT)
+					&& fileInfo.isSkipped()) {
+				tmp = MessageText.getString("FileProgress.deleted");
+			} else if (fileInfo.isSkipped()) {
+				tmp = MessageText.getString("FileProgress.stopped");
+			} else if (fileInfo.getPriority() > 0) {
+
+				int pri = fileInfo.getPriority();
+
+				if (pri > 1) {
+					tmp = MessageText.getString("FileItem.high");
+					tmp += " (" + pri + ")";
+				}
+			} else {
+				//tmp = MessageText.getString("FileItem.normal");
+			}
+		}
 
-			return dm.getStats().getDataReceiveRate();
+		if (tmp != null) {
+			GCStringPrinter.printString(gc, tmp.toUpperCase(), printBounds, false,
+					false, SWT.RIGHT);
 		}
 
-		public EnhancedDownloadManager getEDM(DownloadManager dm) {
-			DownloadManagerEnhancer dmEnhancer = DownloadManagerEnhancer.getSingleton();
-			if (dmEnhancer == null) {
-				return null;
-			}
-			return dmEnhancer.getEnhancedDownload(dm);
+		gc.drawImage(imgArrowButton, buttonBounds.x, buttonBounds.y);
+		Image imgPriority = fileInfo.isSkipped() ? imgPriStopped
+				: fileInfo.getPriority() > 0 ? imgPriHi : imgPriNormal;
+		gc.drawImage(imgPriority, hilowBounds.x, hilowBounds.y);
+
+		//System.out.println(cellArea + s + ";" + Debug.getCompressedStackTrace());
+		// make relative to row, because mouse events are
+		hilowBounds.y -= cellArea.y;
+		hilowBounds.x -= cellArea.x;
+		buttonBounds.x -= cellArea.x;
+		buttonBounds.y -= cellArea.y;
+	}
+
+	public void fileInfoMouseTrigger(TableCellMouseEvent event) {
+		if (event.eventType != TableRowMouseEvent.EVENT_MOUSEDOWN) {
+			return;
 		}
+		final Object dataSource = ((TableRowCore) event.row).getDataSource(true);
+		if (dataSource instanceof DiskManagerFileInfo) {
+			final DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) dataSource;
+			Rectangle hilowBounds = (Rectangle) event.row.getData("hilowBounds");
+			if (event.button == 1 && hilowBounds != null
+					&& hilowBounds.contains(event.x, event.y)) {
+				if (fileInfo.getPriority() > 0) {
+					fileInfo.setPriority(0);
+				} else {
+					fileInfo.setPriority(1);
+				}
+				((TableRowCore) event.row).redraw();
+			}
+
+			Rectangle buttonBounds = (Rectangle) event.row.getData("buttonBounds");
 
-		private void log(TableCell cell, String s) {
-			System.out.println(((TableRowCore) cell.getTableRow()).getIndex() + ":"
-					+ System.currentTimeMillis() + ": " + s);
+			if (buttonBounds != null && buttonBounds.contains(event.x, event.y)) {
+				Menu menu = new Menu(Display.getDefault().getActiveShell(), SWT.POP_UP);
+
+				MenuItem itemHigh = new MenuItem(menu, SWT.RADIO);
+				Messages.setLanguageText(itemHigh, "priority.high");
+				itemHigh.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event event) {
+						FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_HIGH,
+								new Object[] {
+									dataSource
+								});
+					}
+				});
+				itemHigh.setSelection(fileInfo.getPriority() != 0); 
+
+				MenuItem itemNormal = new MenuItem(menu, SWT.RADIO);
+				Messages.setLanguageText(itemNormal, "priority.normal");
+				itemNormal.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event event) {
+						FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_NORMAL,
+								new Object[] {
+									dataSource
+								});
+					}
+				});
+				itemNormal.setSelection(fileInfo.getPriority() == 0);
+
+				new MenuItem(menu, SWT.SEPARATOR);
+				
+				boolean canStart = fileInfo.isSkipped() || fileInfo.getDownloadManager().getState() == DownloadManager.STATE_STOPPED;
+
+				MenuItem itemStop = new MenuItem(menu, SWT.PUSH);
+				Messages.setLanguageText(itemStop, "v3.MainWindow.button.stop");
+				itemStop.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event event) {
+						FilesViewMenuUtil.changePriority(
+								FilesViewMenuUtil.PRIORITY_SKIPPED, new Object[] {
+									dataSource
+								});
+					}
+				});
+				itemStop.setEnabled(!canStart);
+
+				MenuItem itemStart = new MenuItem(menu, SWT.PUSH);
+				Messages.setLanguageText(itemStart, "v3.MainWindow.button.start");
+				itemStart.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event event) {
+						if (fileInfo.getDownloadManager().getState() == DownloadManager.STATE_STOPPED) {
+							TorrentUtil.queueDataSources(new Object[] { dataSource }, true);
+						}
+						
+						FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_NORMAL,
+								new Object[] {
+									dataSource
+								});
+					}
+				});
+				itemStart.setEnabled(canStart);
+
+				new MenuItem(menu, SWT.SEPARATOR);
+
+				MenuItem itemDelete = new MenuItem(menu, SWT.PUSH);
+				Messages.setLanguageText(itemDelete, "v3.MainWindow.button.delete");
+				itemDelete.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event event) {
+						FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_DELETE,
+								new Object[] {
+									dataSource
+								});
+					}
+				});
+
+				menu.setVisible(true);
+				event.skipCoreFunctionality = true;
+			}
+			/*
+			if (buttonBounds != null && buttonBounds.contains(event.x, event.y)) {
+				int st = fileInfo.getStorageType();
+				if ((st == DiskManagerFileInfo.ST_COMPACT || st == DiskManagerFileInfo.ST_REORDER_COMPACT)
+						&& fileInfo.isSkipped()) {
+					// deleted: Move to normal
+					fileInfo.setPriority(0);
+					fileInfo.setSkipped(false);
+				} else if (fileInfo.isSkipped()) {
+					// skipped: move to normal
+					fileInfo.setPriority(0);
+					fileInfo.setSkipped(false);
+				} else if (fileInfo.getPriority() > 0) {
+
+					// high: move to skipped
+					fileInfo.setSkipped(true);
+				} else {
+					// normal: move to high
+					fileInfo.setPriority(1);
+				}
+				//((TableRowCore) event.row).invalidate();
+				((TableRowCore) event.row).redraw();
+			}
+			*/
 		}
 	}
+	
+	public void 
+	postConfigLoad() 
+	{
+		super.postConfigLoad();
+		
+		cdf.update();
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnStream.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnStream.java
new file mode 100644
index 0000000..dda0971
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnStream.java
@@ -0,0 +1,234 @@
+/**
+ * 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.torrent;
+
+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.internat.MessageText;
+import org.gudy.azureus2.core3.util.AEThread;
+import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.ThreadPool;
+import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
+import org.gudy.azureus2.plugins.ui.tables.*;
+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.common.table.TableCellCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
+import com.aelitis.azureus.util.DLReferals;
+import com.aelitis.azureus.util.PlayUtils;
+
+/**
+ * @author TuxPaper
+ * @created Sep 25, 2008
+ *
+ */
+public class ColumnStream
+	extends CoreTableColumn
+	implements TableCellSWTPaintListener, TableCellAddedListener,
+	TableCellRefreshListener, TableCellMouseListener, TableCellToolTipListener
+{
+	public static final String COLUMN_ID = "TorrentStream";
+
+	public static final Class[] DATASOURCE_TYPES = {
+		DownloadTypeIncomplete.class,
+		org.gudy.azureus2.plugins.disk.DiskManagerFileInfo.class
+	};
+
+	private static int WIDTH = 62; // enough to fit title
+
+	private static Image imgEnabled;
+
+	private static Image imgDisabled;
+	
+	private static boolean first = true;
+	
+	private static boolean skipPaint = true;
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+			CAT_CONTENT
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	/**
+	 * @param name
+	 * @param tableID
+	 */
+	public ColumnStream(String tableID) {
+		super(COLUMN_ID, tableID);
+		addDataSourceTypes(DATASOURCE_TYPES);
+
+		initializeAsGraphic(WIDTH);
+		setAlignment(ALIGN_CENTER);
+		imgEnabled = ImageLoader.getInstance().getImage("image.stream.small.on");
+		imgDisabled = ImageLoader.getInstance().getImage("image.stream.small.off");
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.impl.TableColumnImpl#preAdd()
+	public void preAdd() {
+		if (!isFirstLoad() || getPosition() >= 0 || getColumnAdded()) {
+			return;
+		}
+		TableColumnManager tcManager = TableColumnManager.getInstance();
+		TableColumnInfo columnInfoTAN = tcManager.getColumnInfo(null, getTableID(),
+				ColumnThumbAndName.COLUMN_ID);
+		if (columnInfoTAN != null) {
+			TableColumn column = columnInfoTAN.getColumn();
+			if (column != null) {
+				int position = column.getPosition();
+				if (position >= 0) {
+					setPosition(position + 1);
+				}
+			}
+		}
+	}
+
+	private boolean noIconForYou(Object ds, TableCell cell) {
+		if (!(ds instanceof DownloadManager)) {
+			return false;
+		}
+		if (!(cell instanceof TableCellCore)) {
+			return false;
+		}
+		DownloadManager dm = (DownloadManager) ds;
+		TableRowCore rowCore = ((TableCellCore) cell).getTableRowCore();
+		if (rowCore == null) {
+			return false;
+		}
+
+		if (dm.getAssumedComplete()
+				|| (dm.getNumFileInfos() > 1 && rowCore.isExpanded())) {
+			return true;
+		}
+		return false;
+	}
+
+	// @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) {
+
+		Object ds = cell.getDataSource();
+		if (noIconForYou(ds, cell)) {
+			return;
+		}
+		
+		Comparable sortValue = cell.getSortValue();
+		if (!(sortValue instanceof Number)) {
+			return;
+		}
+		int sortVal = ((Number) sortValue).intValue();
+		boolean canStream = (sortVal & 2) > 0;
+		boolean canPlay = (sortVal & 1) > 0;
+		Image img = canStream ? imgEnabled : imgDisabled;
+
+		if (!canStream && canPlay) {
+			return;
+		}
+
+		Rectangle cellBounds = cell.getBounds();
+
+		if (img != null && !img.isDisposed()) {
+			Rectangle imgBounds = img.getBounds();
+			gc.drawImage(img, cellBounds.x
+					+ ((cellBounds.width - imgBounds.width) / 2), cellBounds.y
+					+ ((cellBounds.height - imgBounds.height) / 2));
+		}
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void cellAdded(final TableCell cell) {
+		cell.setMarginWidth(0);
+		cell.setMarginHeight(0);
+		
+		synchronized (COLUMN_ID) {
+			if (first) {
+				first = false; 
+				new AEThread2("WaitForMS", true) {
+					public void run() {
+						Object ds = cell.getDataSource();
+						// first call may take forever
+						PlayUtils.canStreamDS(ds, -1);
+						skipPaint = false;
+					}
+				};
+			}
+		}
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void refresh(TableCell cell) {
+		int sortVal;
+		Object ds = cell.getDataSource();
+		if (noIconForYou(ds, cell)) {
+			sortVal = 0;
+		} else {
+			boolean canStream = PlayUtils.canStreamDS(ds, -1);
+			boolean canPlay = PlayUtils.canPlayDS(ds, -1);
+			sortVal = (canStream ? 2 : 0) + (canPlay ? 0 : 1);
+		}
+
+		if (cell.setSortValue(sortVal)) {
+			cell.invalidate();
+		}
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
+	public void cellMouseTrigger(final TableCellMouseEvent event) {
+		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
+				&& event.button == 1) {
+			Object ds = event.cell.getDataSource();
+			if (PlayUtils.canStreamDS(ds, -1)) {
+				TorrentListViewsUtils.playOrStreamDataSource(ds, "column", true, false);
+			}
+		}
+	}
+
+	// @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 (noIconForYou(ds, cell)) {
+			cell.setToolTip(null);
+			return;
+		}
+		if (PlayUtils.canStreamDS(ds, -1) || PlayUtils.canPlayDS(ds, -1)) {
+			cell.setToolTip(null);
+			return;
+		}
+		String id = "TableColumn.TorrentStream.tooltip.disabled";
+		if ((ds instanceof DownloadManager) && ((DownloadManager)ds).getNumFileInfos() > 1) {
+			id = "TableColumn.TorrentStream.tooltip.expand";
+		}
+
+		cell.setToolTip(MessageText.getString(id));
+	}
+
+	// @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/ColumnThumbAndName.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java
index 25956c5..af84494 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbAndName.java
@@ -25,18 +25,19 @@
 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.eclipse.swt.graphics.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.util.Constants;
 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.MenuItemFillListener;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
 import org.gudy.azureus2.plugins.ui.tables.*;
 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
@@ -46,6 +47,8 @@ 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.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.utils.TorrentUIUtilsV3;
 import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3.ContentImageLoadedListener;
@@ -58,12 +61,23 @@ import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3.ContentImageLoadedListe
 public class ColumnThumbAndName
 	extends CoreTableColumn
 	implements TableCellLightRefreshListener, ObfusticateCellText,
-	TableCellDisposeListener, TableCellSWTPaintListener
+	TableCellDisposeListener, TableCellSWTPaintListener,
+	TableCellClipboardListener, TableCellMouseMoveListener
 {
-	public static final Class DATASOURCE_TYPE = Download.class;
+	public static final Class<?>[] DATASOURCE_TYPES = {
+		Download.class,
+		org.gudy.azureus2.plugins.disk.DiskManagerFileInfo.class
+	};
 
 	public static final String COLUMN_ID = "name";
 
+	private static final String ID_EXPANDOHITAREA = "expandoHitArea";
+	private static final String ID_EXPANDOHITAREASHOW = "expandoHitAreaShow";
+
+	private static final boolean NEVER_SHOW_TWISTY = 
+		Constants.isLinux || 
+		!COConfigurationManager.getBooleanParameter("Table.useTree");
+	
 	private boolean showIcon;
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
@@ -71,6 +85,7 @@ public class ColumnThumbAndName
 			CAT_ESSENTIAL,
 			CAT_CONTENT
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	/**
@@ -78,7 +93,9 @@ public class ColumnThumbAndName
 	 * @param sTableID
 	 */
 	public ColumnThumbAndName(String sTableID) {
-		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, 250, sTableID);
+		super(COLUMN_ID, 250, sTableID);
+		setAlignment(ALIGN_LEAD);
+		addDataSourceTypes(DATASOURCE_TYPES);
 		setObfustication(true);
 		setRefreshInterval(INTERVAL_LIVE);
 		initializeAsGraphic(250);
@@ -115,13 +132,39 @@ public class ColumnThumbAndName
 			}
 		});
 
-		COConfigurationManager.addAndFireParameterListener(
-				"NameColumn.showProgramIcon", new ParameterListener() {
+		TableContextMenuItem menuShowIcon = addContextMenuItem(
+				"ConfigView.section.style.showProgramIcon", MENU_STYLE_HEADER);
+		menuShowIcon.setStyle(TableContextMenuItem.STYLE_CHECK);
+		menuShowIcon.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setData(new Boolean(showIcon));
+			}
+		});
+		final String CFG_SHOWPROGRAMICON = "NameColumn.showProgramIcon."
+				+ getTableID();
+		menuShowIcon.addMultiListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				COConfigurationManager.setParameter(CFG_SHOWPROGRAMICON,
+						((Boolean) menu.getData()).booleanValue());
+			}
+		});
+
+		COConfigurationManager.addAndFireParameterListener(CFG_SHOWPROGRAMICON,
+				new ParameterListener() {
 					public void parameterChanged(String parameterName) {
-						setShowIcon(COConfigurationManager.getBooleanParameter("NameColumn.showProgramIcon"));
+						setShowIcon(COConfigurationManager.getBooleanParameter(
+								CFG_SHOWPROGRAMICON,
+								COConfigurationManager.getBooleanParameter("NameColumn.showProgramIcon")));
 					}
 				});
 	}
+	
+	public void reset() {
+		super.reset();
+		
+		COConfigurationManager.removeParameter("NameColumn.showProgramIcon."
+				+ getTableID());
+	}
 
 	public void refresh(TableCell cell) {
 		refresh(cell, false);
@@ -129,32 +172,118 @@ public class ColumnThumbAndName
 
 	public void refresh(TableCell cell, boolean sortOnlyRefresh) {
 		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+			if (fileInfo.isSkipped()
+					&& (fileInfo.getStorageType() == DiskManagerFileInfo.ST_COMPACT || fileInfo.getStorageType() == DiskManagerFileInfo.ST_REORDER_COMPACT)) {
+				TableRowCore row = (TableRowCore) cell.getTableRow();
+				if (row != null) {
+					row.getParentRowCore().removeSubRow(ds);
+				}
+			}
+			return;
+		}
+		DownloadManager dm = (DownloadManager) ds;
 		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();
+		if (ds instanceof DiskManagerFileInfo) {
+			cellPaintFileInfo(gc, cell, (DiskManagerFileInfo) ds);
+			return;
+		}
 
 		Rectangle cellBounds = cell.getBounds();
-		
+
 		int textX = cellBounds.x;
 
+		TableRowCore rowCore = cell.getTableRowCore();
+		if (rowCore != null) {
+			int numSubItems = rowCore.getSubItemCount();
+			int paddingX = 3;
+			int width = 7;
+			
+			boolean	show_twisty;
+			
+			if ( NEVER_SHOW_TWISTY ){
+				
+				show_twisty = false;
+				
+			}else if (numSubItems > 1 ){
+				
+				show_twisty = true;
+			}else{
+				
+				Boolean show = (Boolean)rowCore.getData( ID_EXPANDOHITAREASHOW );
+				
+				if ( show == null ){
+					
+					DownloadManager dm = (DownloadManager)ds;
+					
+					show_twisty = dm.getNumFileInfos() > 1;
+					
+					rowCore.setData( ID_EXPANDOHITAREASHOW, new Boolean( show_twisty ));
+					
+				}else{
+					show_twisty = show;
+				}
+			}
+			
+			if (show_twisty) {
+				int middleY = cellBounds.y + (cellBounds.height / 2) - 1;
+				int startX = cellBounds.x + paddingX;
+				int halfHeight = 2;
+				Color bg = gc.getBackground();
+				gc.setBackground(gc.getForeground());
+				gc.setAntialias(SWT.ON);
+				gc.setAdvanced(true);
+				if (rowCore.isExpanded()) {
+					gc.fillPolygon(new int[] {
+						startX,
+						middleY - halfHeight,
+						startX + width,
+						middleY - halfHeight,
+						startX + (width / 2),
+						middleY + (halfHeight * 2) + 1
+					});
+				} else {
+					gc.fillPolygon(new int[] {
+						startX,
+						middleY - halfHeight,
+						startX + width,
+						middleY + halfHeight,
+						startX,
+						middleY + (halfHeight * 2) + 1
+					});
+				}
+				gc.setBackground(bg);
+				Rectangle hitArea = new Rectangle(paddingX, middleY - halfHeight
+						- cellBounds.y, width, (halfHeight * 4) + 1);
+				rowCore.setData(ID_EXPANDOHITAREA, hitArea);
+
+				cellBounds.x += paddingX * 2 + width;
+				cellBounds.width -= paddingX * 2 + width;
+			}
+		}
+
 		if (!showIcon) {
-			cellPaintName(cell, gc, cellBounds, textX);
+			cellBounds.x += 2;
+			cellBounds.width -= 4;
+			cellPaintName(cell, gc, cellBounds, cellBounds.x);
 			return;
 		}
 
 		Image[] imgThumbnail = TorrentUIUtilsV3.getContentImage(ds,
-				cellBounds.height >= 20,
-				new ContentImageLoadedListener() {
+				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
@@ -166,13 +295,13 @@ public class ColumnThumbAndName
 
 		if (imgThumbnail != null && ImageLoader.isRealImage(imgThumbnail[0])) {
 			try {
-		
+
 				if (cellBounds.height > 30) {
 					cellBounds.y += 1;
 					cellBounds.height -= 3;
 				}
 				Rectangle imgBounds = imgThumbnail[0].getBounds();
-		
+
 				int dstWidth;
 				int dstHeight;
 				if (imgBounds.height > cellBounds.height) {
@@ -185,7 +314,7 @@ public class ColumnThumbAndName
 					dstWidth = imgBounds.width;
 					dstHeight = imgBounds.height;
 				}
-		
+
 				if (cellBounds.height <= 18) {
 					dstWidth = Math.min(dstWidth, cellBounds.height);
 					dstHeight = Math.min(dstHeight, cellBounds.height);
@@ -194,7 +323,7 @@ public class ColumnThumbAndName
 						dstHeight -= 2;
 					}
 				}
-				
+
 				try {
 					gc.setAdvanced(true);
 					gc.setInterpolation(SWT.HIGH);
@@ -205,11 +334,11 @@ public class ColumnThumbAndName
 				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 (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);
@@ -219,11 +348,11 @@ public class ColumnThumbAndName
 				}
 				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 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()) {
@@ -252,32 +381,59 @@ public class ColumnThumbAndName
 						gc.setClipping(lastClipping);
 					}
 				}
-		
+
 				TorrentUIUtilsV3.releaseContentImage(ds);
 			} catch (Throwable t) {
 				Debug.out(t);
 			}
 		}
-		
+
 		cellPaintName(cell, gc, cellBounds, textX);
 	}
 
-	private void cellPaintName(TableCell cell, GC gc, Rectangle cellBounds, int textX) {
+	private void cellPaintFileInfo(GC gc, TableCellSWT cell,
+			DiskManagerFileInfo fileInfo) {
+		Rectangle cellArea = cell.getBounds();
+		//System.out.println(cellArea);
+		int padding = 10 + 20 + (showIcon ? cellArea.height : 0);
+		cellArea.x += padding;
+		cellArea.width -= padding;
+		String prefix = fileInfo.getDownloadManager().getSaveLocation().toString();
+		String s = fileInfo.getFile(true).toString();
+		if (s.startsWith(prefix)) {
+			s = s.substring(prefix.length() + 1);
+		}
+		boolean over = GCStringPrinter.printString(gc, s, cellArea, true, false,
+				SWT.LEFT);
+		cell.setToolTip(over ? null : s);
+	}
+
+	private void cellPaintName(TableCell cell, GC gc, Rectangle cellBounds,
+			int textX) {
 		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			return;
+		}
+		DownloadManager dm = (DownloadManager) ds;
 		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);
+		boolean over = GCStringPrinter.printString(gc, name, new Rectangle(textX,
+				cellBounds.y, cellBounds.x + cellBounds.width - textX,
+				cellBounds.height), true, true, SWT.WRAP);
+		cell.setToolTip(over ? null : name);
 	}
 
 	public String getObfusticatedText(TableCell cell) {
 		String name = null;
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			return null;
+		}
+		DownloadManager dm = (DownloadManager) ds;
 		if (dm != null) {
 			name = dm.toString();
 			int i = name.indexOf('#');
@@ -300,6 +456,7 @@ public class ColumnThumbAndName
 	 */
 	public void setShowIcon(boolean showIcon) {
 		this.showIcon = showIcon;
+		invalidateCells();
 	}
 
 	/**
@@ -309,4 +466,42 @@ public class ColumnThumbAndName
 		return showIcon;
 	}
 
+	public String getClipboardText(TableCell cell) {
+		String name = null;
+		Object ds = cell.getDataSource();
+		if (ds instanceof DiskManagerFileInfo) {
+			return null;
+		}
+		DownloadManager dm = (DownloadManager) ds;
+		if (dm != null)
+			name = dm.getDisplayName();
+		if (name == null)
+			name = "";
+		return name;
+	}
+
+	public void cellMouseTrigger(TableCellMouseEvent event) {
+		if (event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE
+				|| event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN) {
+			TableRow row = event.cell.getTableRow();
+			if (row == null) {
+				return;
+			}
+			Object data = row.getData(ID_EXPANDOHITAREA);
+			if (data instanceof Rectangle) {
+				Rectangle hitArea = (Rectangle) data;
+				boolean inExpando = hitArea.contains(event.x, event.y);
+
+				if (event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE) {
+					((TableCellCore) event.cell).setCursorID(inExpando ? SWT.CURSOR_HAND
+							: SWT.CURSOR_ARROW);
+				} else if (inExpando) { // mousedown
+					if (row instanceof TableRowCore) {
+						TableRowCore rowCore = (TableRowCore) row;
+						rowCore.setExpanded(!rowCore.isExpanded());
+					}
+				}
+			}
+		}
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
index 1540345..ce13550 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnThumbnail.java
@@ -154,7 +154,7 @@ public class ColumnThumbnail
 					}
 				});
 
-		if (imgThumbnail == null) {
+		if (imgThumbnail == null || imgThumbnail[0] == null) {
 			// don't need to release a null image
 			return;
 		}
@@ -194,6 +194,9 @@ public class ColumnThumbnail
 
 				for (int i = 0; i < imgThumbnail.length; i++) {
 					Image image = imgThumbnail[i];
+					if (image == null) {
+						continue;
+					}
 					Rectangle srcBounds = image.getBounds();
 					if (i == 0) {
 						int w = dstWidth;
diff --git a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnUnopened.java b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnUnopened.java
index f79c89e..52fc2c8 100644
--- a/com/aelitis/azureus/ui/swt/columns/torrent/ColumnUnopened.java
+++ b/com/aelitis/azureus/ui/swt/columns/torrent/ColumnUnopened.java
@@ -41,12 +41,13 @@ public class ColumnUnopened
 	implements TableCellAddedListener, TableCellRefreshListener,
 	TableCellMouseListener
 {
-	public static final Class DATASOURCE_TYPE = Download.class;
+	public static final Class<?> DATASOURCE_TYPE = Download.class;
 
 	public static final String COLUMN_ID = "unopened";
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_CONTENT, CAT_ESSENTIAL });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	private static UISWTGraphicImpl graphicCheck;
diff --git a/com/aelitis/azureus/ui/swt/columns/utils/ColumnImageClickArea.java b/com/aelitis/azureus/ui/swt/columns/utils/ColumnImageClickArea.java
index b80b020..2ee726e 100644
--- a/com/aelitis/azureus/ui/swt/columns/utils/ColumnImageClickArea.java
+++ b/com/aelitis/azureus/ui/swt/columns/utils/ColumnImageClickArea.java
@@ -21,8 +21,6 @@ package com.aelitis.azureus.ui.swt.columns.utils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
 
-import org.gudy.azureus2.core3.util.Debug;
-
 import com.aelitis.azureus.ui.common.table.TableCellCore;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
diff --git a/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java b/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
index bd044b2..823c6cf 100644
--- a/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
+++ b/com/aelitis/azureus/ui/swt/columns/utils/TableColumnCreatorV3.java
@@ -6,13 +6,13 @@ 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.table.TableColumnCoreCreationListener;
 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.tableitems.mytorrents.*;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableColumnCoreCreationListener;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.swt.columns.torrent.*;
 import com.aelitis.azureus.ui.swt.columns.vuzeactivity.*;
 
@@ -41,12 +41,16 @@ public class TableColumnCreatorV3
 		final String[] defaultVisibleOrder = {
 			ColumnUnopened.COLUMN_ID,
 			ColumnThumbAndName.COLUMN_ID,
-			"RatingColumn",
-			"azsubs.ui.column.subs",
+			ColumnStream.COLUMN_ID,
 			SizeItem.COLUMN_ID,
+			ColumnProgressETA.COLUMN_ID,
+			//DateCompletedItem.COLUMN_ID,
+			"azsubs.ui.column.subs",
 			StatusItem.COLUMN_ID,
-			ShareRatioItem.COLUMN_ID,
-			DateCompletedItem.COLUMN_ID,
+			ColumnTorrentSpeed.COLUMN_ID,
+			SeedsItem.COLUMN_ID,
+			PeersItem.COLUMN_ID,
+			ShareRatioItem.COLUMN_ID
 		};
 
 		TableColumnManager tcManager = TableColumnManager.getInstance();
@@ -58,9 +62,9 @@ public class TableColumnCreatorV3
 		if (!tcManager.loadTableColumnSettings(Download.class, tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
-			DateCompletedItem tc = (DateCompletedItem) mapTCs.get(DateCompletedItem.COLUMN_ID);
+			ColumnProgressETA tc = (ColumnProgressETA) mapTCs.get(ColumnProgressETA.COLUMN_ID);
 			if (tc != null) {
-				tcManager.setDefaultSortColumnName(tableID, DateCompletedItem.COLUMN_ID);
+				tcManager.setDefaultSortColumnName(tableID, ColumnProgressETA.COLUMN_ID);
 				tc.setSortAscending(false);
 			}
 		}
@@ -88,11 +92,13 @@ public class TableColumnCreatorV3
 	public static TableColumnCore[] createIncompleteDM(String tableID, boolean big) {
 		final String[] defaultVisibleOrder = {
 			ColumnThumbAndName.COLUMN_ID,
-			"azsubs.ui.column.subs",
+			ColumnStream.COLUMN_ID,
 			SizeItem.COLUMN_ID,
+			ColumnFileCount.COLUMN_ID,
 			ColumnProgressETA.COLUMN_ID,
 			SeedsItem.COLUMN_ID,
 			PeersItem.COLUMN_ID,
+			"azsubs.ui.column.subs",
 		};
 
 		TableColumnManager tcManager = TableColumnManager.getInstance();
@@ -139,7 +145,11 @@ public class TableColumnCreatorV3
 	private static void setVisibility(Map mapTCs, String[] defaultVisibleOrder) {
 		for (Iterator iter = mapTCs.values().iterator(); iter.hasNext();) {
 			TableColumnCore tc = (TableColumnCore) iter.next();
-			tc.setVisible(false);
+			Long force_visible = (Long)tc.getUserData( TableColumn.UD_FORCE_VISIBLE );
+			if ( force_visible == null || force_visible==0 ){
+			
+				tc.setVisible(false);
+			}
 		}
 
 		for (int i = 0; i < defaultVisibleOrder.length; i++) {
@@ -205,17 +215,18 @@ public class TableColumnCreatorV3
 			ColumnThumbAndName.COLUMN_ID,
 			"azsubs.ui.column.subs",
 			SizeItem.COLUMN_ID,
+			ColumnProgressETA.COLUMN_ID,
 			StatusItem.COLUMN_ID,
 			DateCompletedItem.COLUMN_ID,
 		};
 
 		TableColumnManager tcManager = TableColumnManager.getInstance();
-		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeIncomplete.class,
+		Map mapTCs = tcManager.getTableColumnsAsMap(DownloadTypeComplete.class,
 				tableID);
 
 		tcManager.setDefaultColumnNames(tableID, defaultVisibleOrder);
 
-		if (!tcManager.loadTableColumnSettings(DownloadTypeIncomplete.class,
+		if (!tcManager.loadTableColumnSettings(DownloadTypeComplete.class,
 				tableID)
 				|| areNoneVisible(mapTCs)) {
 			setVisibility(mapTCs, defaultVisibleOrder);
@@ -342,7 +353,8 @@ public class TableColumnCreatorV3
 		final Map<String, cInfo> c = new LightHashMap<String, cInfo>(7);
 
 		c.put(ColumnUnopened.COLUMN_ID, new cInfo(ColumnUnopened.class, ColumnUnopened.DATASOURCE_TYPE));
-		c.put(ColumnThumbAndName.COLUMN_ID, new cInfo(ColumnThumbAndName.class, ColumnThumbAndName.DATASOURCE_TYPE));
+		c.put(ColumnThumbAndName.COLUMN_ID, new cInfo(ColumnThumbAndName.class, ColumnThumbAndName.DATASOURCE_TYPES));
+		c.put(ColumnStream.COLUMN_ID, new cInfo(ColumnStream.class, ColumnStream.DATASOURCE_TYPES));
 		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));
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
index 1f2bacd..fb57878 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityActions.java
@@ -33,6 +33,9 @@ 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.ui.common.table.TableCellCore;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+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;
@@ -78,7 +81,11 @@ public class ColumnActivityActions
 			return;
 		}
 
-		String text = cell.getText();
+		TableRow row = cell.getTableRow();
+		if (row == null) {
+			return;
+		}
+		String text = (String) row.getData("text");
 
 		if (text != null && text.length() > 0) {
 			if (font == null) {
@@ -139,7 +146,7 @@ public class ColumnActivityActions
 		}
 
 		DownloadManager dm = entry.getDownloadManger();
-		boolean canPlay = PlayUtils.canPlayDS(entry);
+		boolean canPlay = PlayUtils.canPlayDS(entry, -1);
 		boolean canDL = dm == null && entry.getDownloadManger() == null
 				&& (entry.getTorrent() != null || entry.getAssetHash() != null);
 		boolean canRun = !canPlay && dm != null;
@@ -169,7 +176,7 @@ public class ColumnActivityActions
 			sb.append("<A HREF=\"launch\">Launch</A>");
 		}
 
-		cell.setText(sb.toString());
+		cell.getTableRow().setData("text", sb.toString());
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
@@ -180,7 +187,10 @@ public class ColumnActivityActions
 		boolean invalidateAndRefresh = false;
 
 		Rectangle bounds = ((TableCellSWT) event.cell).getBounds();
-		String text = event.cell.getText();
+		String text = (String) event.cell.getTableRow().getData("text");
+		if (text == null) {
+			return;
+		}
 
 		GCStringPrinter sp = null;
 		GC gc = new GC(Display.getDefault());
@@ -207,14 +217,6 @@ public class ColumnActivityActions
 						String referal = null;
 						Object ds = event.cell.getDataSource();
 						if (ds instanceof VuzeActivitiesEntry) {
-							if (((VuzeActivitiesEntry) ds).isDRM()) {
-								if (DataSourceUtils.isPlatformContent(ds)) {
-									TorrentListViewsUtils.viewDetailsFromDS(
-											event.cell.getDataSource(), "activity-dl");
-								}
-								return;
-							}
-
 							referal = DLReferals.DL_REFERAL_DASHACTIVITY + "-"
 									+ ((VuzeActivitiesEntry) ds).getTypeID();
 						}
@@ -224,24 +226,16 @@ public class ColumnActivityActions
 						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(
-											event.cell.getDataSource(), "thumb");
-								}
-								return;
-							}
 							referal = DLReferals.DL_REFERAL_PLAYDASHACTIVITY + "-"
 									+ ((VuzeActivitiesEntry) ds).getTypeID();
 						}
-						TorrentListViewsUtils.playOrStreamDataSource(ds, null, referal);
+						TorrentListViewsUtils.playOrStreamDataSource(ds, referal, false, true );
 						
 					} else if (hitUrl.url.equals("launch")) {
 						// run via play or stream so we get the security warning
 						Object ds = event.cell.getDataSource();
-						TorrentListViewsUtils.playOrStreamDataSource(ds, null,
-								DLReferals.DL_REFERAL_LAUNCH);
+						TorrentListViewsUtils.playOrStreamDataSource(ds,
+								DLReferals.DL_REFERAL_LAUNCH, false, true);
 						
 					} else if (!UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
 						Utils.launch(hitUrl.url);
@@ -250,7 +244,7 @@ public class ColumnActivityActions
 						if (uif != null) {
 							String target = hitUrl.target;
 							if (target == null) {
-								target = ContentNetworkUtils.getTarget(entry.getContentNetwork());
+								target = SkinConstants.VIEWID_BROWSER_BROWSE;
 							}
 							uif.viewURL(hitUrl.url, target, "column.activity.action");
 							return;
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
index 3ea7c48..c0c1d92 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityNew.java
@@ -90,11 +90,9 @@ public class ColumnActivityNew
 		boolean isRead = entry.getReadOn() > 0;
 		int sortVal = isRead ? 1 : 0;
 
-		if (!cell.setSortValue(sortVal) && cell.isValid()) {
-			return;
+		if (cell.setSortValue(sortVal)) {
+			cell.invalidate();
 		}
-
-		cell.invalidate();
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
diff --git a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
index 27449ea..9a31ad7 100644
--- a/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
+++ b/com/aelitis/azureus/ui/swt/columns/vuzeactivity/ColumnActivityText.java
@@ -122,7 +122,7 @@ public class ColumnActivityText
 			gc.setFont(font);
 		}
 		
-		int style = (drawBounds.height < 40) ? 0 : SWT.WRAP;
+		int style = SWT.WRAP;
 
 		GCStringPrinter sp = new GCStringPrinter(gc, text, drawBounds, true, true,
 				style);
@@ -164,15 +164,17 @@ public class ColumnActivityText
 			URLInfo hitUrl = sp.getHitUrl(event.x + bounds.x, event.y + bounds.y);
 			int newCursor;
 			if (hitUrl != null) {
+				boolean ourUrl = UrlFilter.getInstance().urlCanRPC(hitUrl.url)
+						|| hitUrl.url.startsWith("/") || hitUrl.url.startsWith("#");
 				if (event.eventType == TableCellMouseEvent.EVENT_MOUSEDOWN) {
-					if (!UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
+					if (!ourUrl) {
 						Utils.launch(hitUrl.url);
 					} else {
 						UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
 						if (uif != null) {
 							String target = hitUrl.target;
 							if (target == null) {
-								target = ContentNetworkUtils.getTarget(entry.getContentNetwork());
+								target = SkinConstants.VIEWID_BROWSER_BROWSE;
 							}
 							uif.viewURL(hitUrl.url, target, "column.activity.text");
 							return;
@@ -181,7 +183,7 @@ public class ColumnActivityText
 				}
 
 				newCursor = SWT.CURSOR_HAND;
-				if (UrlFilter.getInstance().urlCanRPC(hitUrl.url)) {
+				if (ourUrl) {
 					try {
 						tooltip = hitUrl.title == null ? null : URLDecoder.decode(
 								hitUrl.title, "utf-8");
diff --git a/com/aelitis/azureus/ui/swt/content/RelatedContentEnumerator.java b/com/aelitis/azureus/ui/swt/content/RelatedContentEnumerator.java
deleted file mode 100644
index c152f97..0000000
--- a/com/aelitis/azureus/ui/swt/content/RelatedContentEnumerator.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Created on Jul 14, 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.ui.swt.content;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-
-
-public interface 
-RelatedContentEnumerator 
-{
-	public void
-	enumerate(
-		RelatedContentEnumeratorListener	listener );
-	
-	interface
-	RelatedContentEnumeratorListener
-	{
-		public void
-		contentFound(
-			RelatedContent[]		content );
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java b/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java
deleted file mode 100644
index 6e10c22..0000000
--- a/com/aelitis/azureus/ui/swt/content/RelatedContentUI.java
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * Created on Jul 14, 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.ui.swt.content;
-
-
-
-import java.util.ArrayList;
-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.Debug;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.torrent.Torrent;
-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.config.BooleanParameter;
-import org.gudy.azureus2.plugins.ui.config.ConfigSection;
-import org.gudy.azureus2.plugins.ui.config.IntParameter;
-import org.gudy.azureus2.plugins.ui.config.Parameter;
-import org.gudy.azureus2.plugins.ui.config.ParameterListener;
-import org.gudy.azureus2.plugins.ui.menus.MenuItem;
-import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
-import org.gudy.azureus2.plugins.ui.menus.MenuManager;
-import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarCloseListener;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
-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.Utils;
-import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.content.ContentException;
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.core.content.RelatedContentLookupListener;
-import com.aelitis.azureus.core.content.RelatedContentManager;
-import com.aelitis.azureus.core.content.RelatedContentManagerListener;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
-
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
-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.SkinViewManager.SkinViewManagerListener;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
-
-public class 
-RelatedContentUI 
-{		
-	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;
-	
-	private RelatedContentManager	manager;
-	
-	private boolean			ui_setup;
-	private SideBar			side_bar;
-	private boolean			root_menus_added;
-	private MainViewInfo 	main_view_info;
-	
-	
-	private ByteArrayHashMap<RCMItem>	rcm_item_map = new ByteArrayHashMap<RCMItem>();
-	
-	private AsyncDispatcher	async_dispatcher = new AsyncDispatcher();
-	
-	public 
-	RelatedContentUI()
-	{
-		plugin_interface = PluginInitializer.getDefaultInterface();
-		
-		ui_manager = plugin_interface.getUIManager();
-
-		ui_manager.addUIListener(
-				new UIManagerListener()
-				{
-					public void
-					UIAttached(
-							UIInstance		instance )
-					{
-						if ( instance instanceof UISWTInstance ){
-
-							AzureusCoreFactory.addCoreRunningListener(
-								new AzureusCoreRunningListener() 
-								{
-									public void 
-									azureusCoreRunning(
-										AzureusCore core ) 
-									{
-										uiAttachedAndCoreRunning(core);
-									}
-								});
-						}
-					}
-
-					public void
-					UIDetached(
-							UIInstance		instance )
-					{
-					}
-				});
-	}
-	
-	private void 
-	uiAttachedAndCoreRunning(
-		AzureusCore core ) 
-	{
-		Utils.execSWTThread(
-			new AERunnable() 
-			{
-				public void 
-				runSupport() 
-				{
-					SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-					
-					if ( sideBar != null ){
-						
-						setupUI(sideBar);
-						
-					} else {
-						
-						SkinViewManager.addListener(
-							new SkinViewManagerListener() 
-							{
-								public void 
-								skinViewAdded(
-									SkinView skinview ) 
-								{
-									if (skinview instanceof SideBar) {
-									
-										setupUI((SideBar) skinview);
-										
-										SkinViewManager.RemoveListener(this);
-									}
-								}
-							});
-					}
-				}
-			});
-	}
-	
-	protected void
-	setupUI(
-		SideBar			_side_bar )	
-	{
-		synchronized( this ){
-			
-			if ( ui_setup ){
-				
-				return;
-			}
-			
-			ui_setup = true;
-		}
-		
-		side_bar		= _side_bar;
-
-		try{	
-			manager 	= RelatedContentManager.getSingleton();
-
-			if ( !manager.isUIEnabled()){
-				
-				return;
-			}
-			
-			BasicPluginConfigModel config_model = 
-				ui_manager.createBasicPluginConfigModel(
-					ConfigSection.SECTION_ROOT, "Associations");
-			
-			final BooleanParameter enabled = 
-				config_model.addBooleanParameter2( 
-					"rcm.config.enabled", "rcm.config.enabled",
-					manager.isUIEnabled());
-			
-			enabled.addListener(
-					new ParameterListener()
-					{
-						public void 
-						parameterChanged(
-							Parameter param) 
-						{
-							manager.setUIEnabled( enabled.getValue());
-							
-							buildSideBar();
-						}
-					});
-			
-			final IntParameter max_results = 
-				config_model.addIntParameter2( 
-					"rcm.config.max_results", "rcm.config.max_results",
-					manager.getMaxResults());
-			
-			max_results.addListener(
-					new ParameterListener()
-					{
-						public void 
-						parameterChanged(
-							Parameter param) 
-						{
-							manager.setMaxResults( max_results.getValue());
-						}
-					});
-			
-			final IntParameter max_level = 
-				config_model.addIntParameter2( 
-					"rcm.config.max_level", "rcm.config.max_level",
-					manager.getMaxSearchLevel());
-			
-			max_level.addListener(
-					new ParameterListener()
-					{
-						public void 
-						parameterChanged(
-							Parameter param) 
-						{
-							manager.setMaxSearchLevel( max_level.getValue());
-						}
-					});
-			
-			enabled.addEnabledOnSelection( max_results );
-			enabled.addEnabledOnSelection( max_level );
-			
-			main_view_info = new MainViewInfo();
-
-			hookMenus();
-						
-			buildSideBar();
-			
-			manager.addListener(
-				new RelatedContentManagerListener()
-				{
-					private int last_unread;
-					
-					public void
-					contentFound(
-						RelatedContent[]	content )
-					{
-						check();
-					}
-
-					public void
-					contentChanged(
-						RelatedContent[]	content )
-					{
-						contentChanged();
-					}
-					
-					public void 
-					contentChanged() 
-					{
-						check();
-						
-						List<RCMItem>	items;
-						
-						synchronized( RelatedContentUI.this ){
-							
-							items = new ArrayList<RCMItem>( rcm_item_map.values());
-						}
-						
-						for ( RCMItem item: items ){
-							
-							item.updateNumUnread();
-						}
-					}
-					
-					public void 
-					contentRemoved(
-						RelatedContent[] content ) 
-					{
-						check();
-						
-						List<RCMItem>	items;
-						
-						synchronized( RelatedContentUI.this ){
-							
-							items = new ArrayList<RCMItem>( rcm_item_map.values());
-						}
-						
-						for ( RCMItem item: items ){
-							
-							item.contentRemoved( content );
-						}
-					}
-					
-					public void
-					contentReset()
-					{
-						check();
-					}
-					
-					protected void
-					check()
-					{
-						int	unread = manager.getNumUnread();
-						
-						synchronized( this ){
-							
-							if ( unread == last_unread ){
-								
-								return;
-							}
-							
-							last_unread = unread;
-						}
-						
-						ViewTitleInfoManager.refreshTitleInfo( main_view_info );
-					}
-				});
-			
-		}catch( Throwable e ){
-			
-			Debug.out( e );
-		}
-	}
-	
-	protected void
-	hookMenus()
-	{
-		TableManager	table_manager = plugin_interface.getUIManager().getTableManager();
-
-		String[]	table_ids = {
-				TableManager.TABLE_MYTORRENTS_INCOMPLETE,
-				TableManager.TABLE_MYTORRENTS_COMPLETE,
-				TableManager.TABLE_MYTORRENTS_ALL_BIG,
-				TableManager.TABLE_MYTORRENTS_COMPLETE_BIG,
-				TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG,
-		};
-		
-		for ( String table_id: table_ids ){
-			
-			TableContextMenuItem menu_item = table_manager.addContextMenuItem( table_id, "rcm.contextmenu.lookupassoc");
-		
-			menu_item.setStyle( TableContextMenuItem.STYLE_PUSH );
-
-			MenuItemListener listener = 
-				new MenuItemListener()
-				{
-					public void 
-					selected(
-						MenuItem 	menu, 
-						Object 		target) 
-					{
-						TableRow[]	rows = (TableRow[])target;
-						
-						if ( rows.length > 0 ){
-							
-							Download download = (Download)rows[0].getDataSource();
-							
-							explicitSearch( download );
-						}
-					}
-				};
-				
-				menu_item.addMultiListener( listener );
-		}
-	}
-	
-	protected void
-	explicitSearch(
-		Download		download )
-	{
-		addSearch( download );
-	}
-	
-	protected void
-	buildSideBar()
-	{		
-		final String parent_id = "sidebar." + SideBar.SIDEBAR_SECTION_RELATED_CONTENT;
-
-		final SideBarEntrySWT main_sb_entry = SideBar.getEntry( SideBar.SIDEBAR_SECTION_RELATED_CONTENT );
-
-		if ( main_sb_entry != null ){
-				
-			SideBarEntrySWT subs_entry = SideBar.getEntry( SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS );
-
-			int index = side_bar.getIndexOfEntryRelativeToParent( subs_entry );
-			
-			if ( index >= 0 ){
-				
-				index++;
-			}
-			
-			if ( main_sb_entry.getTreeItem() == null ){
-				
-				if ( manager.isUIEnabled()){
-										
-					side_bar.createEntryFromSkinRef(
-							null,
-							SideBar.SIDEBAR_SECTION_RELATED_CONTENT, "rcmview",
-							main_view_info.getTitle(),
-							main_view_info, null, false, index  );
-					
-					main_sb_entry.setImageLeftID( "image.sidebar.rcm" );
-					
-					main_sb_entry.setDatasource(
-						new RelatedContentEnumerator()
-						{
-							private RelatedContentManagerListener base_listener;
-							
-							private RelatedContentEnumeratorListener current_listener;
-							
-							public void
-							enumerate(
-								RelatedContentEnumeratorListener	listener )
-							{
-								current_listener = listener;
-								
-								if ( base_listener == null ){
-									
-									base_listener = 
-										new RelatedContentManagerListener()
-										{
-											public void
-											contentFound(
-												RelatedContent[]	content )
-											{
-												current_listener.contentFound( content );
-											}
-											
-											public void
-											contentChanged(
-												RelatedContent[]	content )
-											{
-											}
-											
-											public void 
-											contentRemoved(
-												RelatedContent[] 	content ) 
-											{
-											}
-											
-											public void 
-											contentChanged() 
-											{
-											}
-											
-											public void
-											contentReset()
-											{
-											}
-										};
-										
-									manager.addListener( base_listener );
-								}
-								
-								RelatedContent[] current_content = manager.getRelatedContent();
-								
-								listener.contentFound( current_content );
-							}
-						});
-				}else{
-					
-					return;
-				}
-			}else if ( !manager.isUIEnabled()){
-				
-				main_sb_entry.getTreeItem().dispose();
-				
-				return;
-			}
-			
-			if ( !root_menus_added ){
-				
-				root_menus_added = true;
-				
-				MenuManager menu_manager = ui_manager.getMenuManager();
-	
-				MenuItem menu_item = menu_manager.addMenuItem( parent_id, "v3.activity.button.readall" );
-				
-				menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	manager.setAllRead();
-							}
-						});
-				
-				menu_item = menu_manager.addMenuItem( parent_id, "Subscription.menu.deleteall");
-				
-				menu_item.addListener(
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	manager.deleteAll();
-							}
-						});
-				
-				menu_item = menu_manager.addMenuItem( parent_id, "Subscription.menu.reset" );
-				
-				menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-								for ( RCMItem item: rcm_item_map.values()){
-									
-									item.getTreeItem().dispose();
-								}
-								
-						      	manager.reset();
-							}
-						});
-				
-				
-				menu_item = menu_manager.addMenuItem( parent_id, "sep" );
-
-				menu_item.setStyle( MenuItem.STYLE_SEPARATOR );
-				
-				menu_item = menu_manager.addMenuItem( parent_id, "ConfigView.title.short" );
-				
-				menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
-						      	 
-						      	 if ( uif != null ){
-						      		 
-						      		 uif.openView( UIFunctions.VIEW_CONFIG, "Associations" );
-						      	 }
-							}
-						});
-			}
-		}
-	}
-	
-	protected void
-	addSearch(
-		final Download		download )
-	{
-		Torrent	torrent = download.getTorrent();
-		
-		if ( torrent == null ){
-			
-			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( hash );
-				
-				rcm_item_map.put( hash, new_si );
-				
-				Utils.execSWTThread(
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							synchronized( RelatedContentUI.this ){
-
-								if ( new_si.isDestroyed()){
-									
-									return;
-								}
-								
-								RCMView view = new RCMView( SideBar.SIDEBAR_SECTION_RELATED_CONTENT, name );
-								
-								new_si.setView( view );
-								
-								String key = "RCM_" + ByteFormatter.encodeString( hash );
-								
-								SideBarEntrySWT	entry = side_bar.createEntryFromSkinRef(
-										SideBar.SIDEBAR_SECTION_RELATED_CONTENT,
-										key, "rcmview",
-										view.getTitle(),
-										view, null, true, -1 );
-								
-								new_si.setTreeItem( entry.getTreeItem(), entry );
-								
-								/*
-								TreeItem  tree_item = 
-									side_bar.createTreeItemFromIView(
-										SideBar.SIDEBAR_SECTION_RELATED_CONTENT, 
-										view,
-										key, 
-										null, 
-										true, 
-										true,
-										false );
-										
-									SideBarEntrySWT	entry = SideBar.getEntry( key );
-																
-									new_si.setTreeItem( tree_item, entry );
-								*/
-																
-									
-								/*
-								PluginInterface pi = PluginInitializer.getDefaultInterface();
-								UIManager uim = pi.getUIManager();
-								MenuManager menuManager = uim.getMenuManager();
-								
-								MenuItem menuItem;
-								*/
-								
-								new_si.activate();
-							}
-						}
-					});
-			}else{
-				
-				Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								ViewTitleInfoManager.refreshTitleInfo( existing_si.getView());
-								
-								SideBarEntrySWT mainSBEntry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_RELATED_CONTENT );
-								
-								if ( mainSBEntry != null ){
-									
-									ViewTitleInfoManager.refreshTitleInfo( mainSBEntry.getTitleInfo());
-								}
-								
-								existing_si.activate();
-							}
-						});
-			}
-		}
-	}
-	
-	protected class
-	MainViewInfo
-		implements 	ViewTitleInfo
-	{
-		protected
-		MainViewInfo()
-		{
-		}
-		
-		public Object 
-		getTitleInfoProperty(
-			int propertyID ) 
-		{		
-			if ( propertyID == TITLE_TEXT ){
-				
-				return( getTitle());
-				
-			}else if ( propertyID == TITLE_INDICATOR_TEXT ){
-				
-				int	 unread = manager.getNumUnread();
-				
-				if ( unread > 0 ){
-				
-					return( String.valueOf( unread ));
-				}
-				
-			}else if ( propertyID == TITLE_INDICATOR_COLOR ){
-	
-			}
-			
-			return null;
-		}
-		
-		public String
-		getTitle()
-		{
-			return( MessageText.getString("rcm.view.title"));
-		}
-	}
-	
-	protected class
-	RCMView
-		implements 	ViewTitleInfo
-	{
-		private String			parent_key;
-		private String			name;
-		
-		private int				num_unread;
-		
-		protected
-		RCMView(
-			String			_parent_key,
-			String			_name )
-		{
-			parent_key	= _parent_key;
-			name		= _name;
-		}
-		
-		public Object 
-		getTitleInfoProperty(
-			int propertyID ) 
-		{		
-			if ( propertyID == TITLE_TEXT ){
-				
-				return( getTitle());
-				
-			}else if ( propertyID == TITLE_INDICATOR_TEXT ){
-				
-				if ( num_unread > 0 ){
-				
-					return( String.valueOf( num_unread ));
-				}
-				
-			}else if ( propertyID == TITLE_INDICATOR_COLOR ){
-	
-			}
-			
-			return null;
-		}
-		
-		public String
-		getTitle()
-		{
-			return( name );
-		}
-		
-		protected void
-		setNumUnread(
-			int	n )
-		{
-			num_unread = n;
-						
-			ViewTitleInfoManager.refreshTitleInfo( this );
-		}
-	}
-	
-	private static final String SPINNER_IMAGE_ID 	= "image.sidebar.vitality.dl";
-
-	protected static void
-	hideIcon(
-		SideBarVitalityImage	x )
-	{
-		if ( x == null ){
-			return;
-		}
-		
-		x.setVisible( false );
-		x.setToolTip( "" );
-	}
-	
-	protected static void
-	showIcon(
-		SideBarVitalityImage	x ,
-		String					t )
-	{
-		if ( x == null ){
-			return;
-		}
-		
-		x.setToolTip( t );
-		x.setVisible( true );
-	}
-	
-	public class
-	RCMItem
-		implements RelatedContentEnumerator, SideBarCloseListener
-	{	
-		private byte[]				hash;
-		
-		private RCMView				view;
-		private SideBarEntrySWT		sb_entry;
-		private TreeItem			tree_item;
-		private boolean				destroyed;
-		
-		private SideBarVitalityImage	spinner;
-		
-		private List<RelatedContent>	content_list = new ArrayList<RelatedContent>();
-		
-		private int	num_unread;
-		
-		private CopyOnWriteList<RelatedContentEnumeratorListener>	listeners = new CopyOnWriteList<RelatedContentEnumeratorListener>();
-		
-		private boolean	lookup_complete;
-		
-		protected
-		RCMItem(
-			byte[]		_hash )
-		{
-			hash		= _hash;
-		}
-		
-		protected void
-		setTreeItem(
-			TreeItem		_tree_item,
-			SideBarEntrySWT	_sb_entry )
-		{
-			tree_item	= _tree_item;
-			sb_entry	= _sb_entry;
-			
-			sb_entry.setDatasource( this );
-			
-			sb_entry.addListener( this );
-			
-			spinner = sb_entry.addVitalityImage( SPINNER_IMAGE_ID );
-			
-			try{
-				showIcon( spinner, null );
-				
-				manager.lookupContent(
-					hash,
-					new RelatedContentLookupListener()
-					{
-						public void
-						lookupStart()
-						{
-						}
-						
-						public void
-						contentFound(
-							RelatedContent[]	content )
-						{
-							synchronized( RCMItem.this ){
-							
-								if ( !destroyed ){
-								
-									for ( RelatedContent c: content ){
-									
-										if ( !content_list.contains( c )){
-										
-											content_list.add( c );
-										}
-									}
-								}
-							}
-							
-							updateNumUnread();
-							
-							for ( RelatedContentEnumeratorListener listener: listeners ){
-								
-								try{
-									listener.contentFound( content );
-									
-								}catch( Throwable e ){
-									
-									Debug.out( e );
-								}
-							}
-						}
-						
-						public void
-						lookupComplete()
-						{	
-							synchronized( RCMItem.this ){
-								
-								lookup_complete = true;
-							}
-							
-							hideIcon( spinner );
-						}
-						
-						public void
-						lookupFailed(
-							ContentException e )
-						{	
-							lookupComplete();
-						}
-					});
-			}catch( Throwable e ){
-				
-				lookup_complete = true;
-				
-				Debug.out( e );
-				
-				hideIcon( spinner );
-			}
-		}
-		
-		protected void 
-		contentRemoved(
-			RelatedContent[] content ) 
-		{
-			boolean deleted = false;
-			
-			synchronized( RCMItem.this ){
-									
-				for ( RelatedContent c: content ){
-						
-					if ( content_list.remove( c )){
-														
-						deleted = true;
-					}
-				}
-			}
-			
-			if ( deleted ){
-			
-				updateNumUnread();
-			}
-		}
-		
-		protected void
-		updateNumUnread()
-		{
-			synchronized( RCMItem.this ){
-				
-				int	num = 0;
-				
-				for ( RelatedContent c: content_list ){
-					
-					if ( c.isUnread()){
-						
-						num++;
-					}
-				}
-				
-				if ( num != num_unread ){
-					
-					num_unread = num;
-					
-					final int f_num = num;
-										
-					async_dispatcher.dispatch(
-						new AERunnable()
-						{
-							public void
-							runSupport()
-							{
-								if ( async_dispatcher.getQueueSize() > 0 ){
-									
-									return;
-								}
-								
-								view.setNumUnread( f_num );
-							}
-						});
-				}
-			}
-		}
-		
-		public void
-		enumerate(
-			final RelatedContentEnumeratorListener	listener )
-		{
-			RelatedContent[]	already_found;
-			 
-			synchronized( this ){
-				
-				if ( !lookup_complete ){
-					
-					listeners.add( listener );
-				}
-				
-				already_found = content_list.toArray( new RelatedContent[ content_list.size()]);
-			}
-			
-			if ( already_found.length > 0 ){
-				
-				listener.contentFound( already_found );
-			}
-		}
-		
-		protected TreeItem
-		getTreeItem()
-		{
-			return( tree_item );
-		}
-		
-		protected SideBarEntrySWT
-		getSideBarEntry()
-		{
-			return( sb_entry );
-		}
-		
-		protected void
-		setView(
-			RCMView		_view )
-		{
-			view	= _view;
-		}
-		
-		protected RCMView
-		getView()
-		{
-			return( view );
-		}
-		
-		protected boolean
-		isDestroyed()
-		{
-			return( destroyed );
-		}
-		
-		public void 
-		sidebarClosed(
-			SideBarEntry entry )
-		{
-			destroy();
-		}
-		
-		protected void
-		destroy()
-		{
-			synchronized( this ){
-			
-				content_list.clear();
-				
-				destroyed = true;
-			}
-			
-			synchronized( RelatedContentUI.this ){
-					
-				rcm_item_map.remove( hash );
-			}
-		}
-		
-		public void 
-		activate() 
-		{
-			SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
-			
-			if ( sideBar != null && sb_entry != null ){
-				
-				sideBar.showEntryByID(sb_entry.getId());
-			}
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java b/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java
deleted file mode 100644
index cd76cbc..0000000
--- a/com/aelitis/azureus/ui/swt/content/SBC_RCMView.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/**
- * 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.content;
-
-
-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;
-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.*;
-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.content.RelatedContent;
-import com.aelitis.azureus.core.content.RelatedContentManager;
-import com.aelitis.azureus.core.content.RelatedContentManagerListener;
-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;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
-
-
-public class 
-SBC_RCMView
-	extends SkinView
-	implements UIUpdatable, IconBarEnabler, TableViewFilterCheck<RelatedContent>
-{
-	public static final String TABLE_RCM = "RCM";
-
-	private static boolean columnsAdded = false;
-
-	private static RelatedContentManager	manager;
-	
-	static{
-		try{
-			manager = RelatedContentManager.getSingleton();
-			
-		}catch( Throwable e ){
-			
-			Debug.out(e);
-		}
-	}
-	
-	private TableViewSWT<RelatedContent> tv_related_content;
-
-	private SideBarEntrySWT 	sidebar_entry;
-	private Composite			table_parent;
-	private boolean				space_reserved;
-	
-	
-	private Text txtFilter;
-
-	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);
-
-			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;
-	}
-
-
-	private void 
-	initColumns(
-		AzureusCore core ) 
-	{
-		synchronized( SBC_RCMView.class ){
-			
-			if ( columnsAdded ){
-			
-				return;
-			}
-		
-			columnsAdded = true;
-		}
-		
-		UIManager uiManager = PluginInitializer.getDefaultInterface().getUIManager();
-		
-		TableManager tableManager = uiManager.getTableManager();
-		
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_New.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_New(column);
-						}
-					});
-
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Rank.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Rank(column);
-						}
-					});
-		
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Level.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Level(column);
-						}
-					});
-			
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Title.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Title(column);
-						}
-					});
-
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Actions.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Actions(column);
-						}
-					});
-			
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Hash.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Hash(column);
-						}
-					});
-			
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Tracker.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Tracker(column);
-						}
-					});
-			
-		tableManager.registerColumn(
-				RelatedContent.class, 
-				ColumnRC_Size.COLUMN_ID,
-					new TableColumnCreationListener() {
-						public void tableColumnCreated(TableColumn column) {
-							new ColumnRC_Size(column);
-						}
-					});
-		
-		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) {
-							new ColumnRC_LastSeen(column);
-						}
-					});
-	}
-
-	public Object 
-	skinObjectShown(
-		SWTSkinObject 	skinObject, 
-		Object 			params ) 
-	{
-		super.skinObjectShown(skinObject, params);
-
-		SWTSkinObject so_list = getSkinObject("rcm-list");
-		
-		if ( so_list != null ){
-			
-			initTable((Composite) so_list.getControl());
-		}
-		
-		return null;
-	}
-
-	public Object 
-	skinObjectHidden(
-		SWTSkinObject 	skinObject, 
-		Object 			params ) 
-	{
-		synchronized( this ){
-			
-			if ( tv_related_content != null ){
-				
-				tv_related_content.delete();
-				
-				tv_related_content = null;
-			}
-		}
-		
-		Utils.disposeSWTObjects(new Object[] {
-			table_parent,
-		});
-
-		return( super.skinObjectHidden(skinObject, params));
-	}
-
-	public Object
-	skinObjectDestroyed(
-		SWTSkinObject 	skinObject, 
-		Object 			params ) 
-	{
-		synchronized( this ){
-			
-			if ( tv_related_content != null ){
-				
-				tv_related_content.delete();
-				
-				tv_related_content = null;
-			}
-		}
-		
-		Utils.disposeSWTObjects(new Object[] {
-			table_parent,
-		});
-
-		if ( space_reserved ){
-		
-			manager.releaseTemporarySpace();
-		}
-		
-		return( super.skinObjectDestroyed(skinObject, params));
-	}
-	
-	private void 
-	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 );
-		if (txtFilter != null) {
-			tv_related_content.enableFilterCheck(txtFilter, this);
-		}
-		tv_related_content.setRowDefaultHeight(16);
-		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());
-		GridLayout layout = new GridLayout();
-		layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
-		table_parent.setLayout(layout);
-
-		tv_related_content.addSelectionListener(new TableSelectionListener() {
-
-			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( UrlUtils.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();
-				}
-			}
-
-			public void mouseExit(TableRowCore row) {
-			}
-
-			public void mouseEnter(TableRowCore row) {
-			}
-
-			public void focusChanged(TableRowCore focus) {
-				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-				if (uiFunctions != null) {
-					uiFunctions.refreshIconBar();
-				}
-			}
-
-			public void deselected(TableRowCore[] rows) {
-				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-				if (uiFunctions != null) {
-					uiFunctions.refreshIconBar();
-				}
-			}
-
-			public void defaultSelected(TableRowCore[] rows, int stateMask) {
-			}
-		}, false);
-
-		tv_related_content.addLifeCycleListener(
-			new TableLifeCycleListener() 
-			{
-				private Set<RelatedContent>	content_set = new HashSet<RelatedContent>();
-				
-				private int liveness_marker;
-				
-				private RelatedContentManagerListener current_rcm_listener;
-				
-				
-				public void 
-				tableViewInitialized() 
-				{
-					final int current_liveness_marker = ++liveness_marker;
-					
-					current_rcm_listener = 
-						new RelatedContentManagerListener()
-						{
-							public void
-							contentFound(
-								RelatedContent[]	content )
-							{							
-							}
-
-							public void
-							contentChanged(
-								RelatedContent[]	content )
-							{
-								final java.util.List<RelatedContent> hits = new ArrayList<RelatedContent>( content.length );
-
-								synchronized( content_set ){
-									
-									if ( liveness_marker != current_liveness_marker ){
-										
-										return;
-									}							
-								
-									for ( RelatedContent c: content ){
-
-										if ( content_set.contains( c )){
-									
-											hits.add( c );
-										}
-									}
-								}
-								
-								if ( hits.size() > 0 ){
-									
-									for (RelatedContent rc : hits) {
-										TableRowCore row = tv_related_content.getRow(rc);
-										if (row != null) {
-											row.refresh(true);
-										}
-									}
-								}
-							}
-							
-							public void 
-							contentRemoved(
-								final RelatedContent[] content )
-							{
-								final java.util.List<RelatedContent> hits = new ArrayList<RelatedContent>( content.length );
-								
-								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()
-											{
-												public void
-												run()
-												{
-													if ( tv_related_content != null ){
-														
-														tv_related_content.removeDataSources( hits.toArray( new RelatedContent[ hits.size()] ));
-													}
-												}
-											});
-								}
-							}
-							
-							public void
-							contentChanged()
-							{
-								if ( tv_related_content != null ){
-									
-									tv_related_content.refreshTable( false );
-								}
-							}
-							
-							public void
-							contentReset()
-							{
-								if ( tv_related_content != null ){
-									
-									tv_related_content.removeAllTableRows();
-								}
-							}
-						};
-						
-					manager.addListener( current_rcm_listener );
-				
-					Object data_source = sidebar_entry.getDatasource();
-					
-					if ( data_source instanceof RelatedContentEnumerator ){
-						
-						final TableViewSWT<RelatedContent> f_table = tv_related_content;
-						
-						((RelatedContentEnumerator)data_source).enumerate(
-							new RelatedContentEnumerator.RelatedContentEnumeratorListener()
-							{
-								public void
-								contentFound(
-									RelatedContent[]	content )
-								{
-									ArrayList<RelatedContent> new_content = null;
-									
-									synchronized( content_set ){
-										
-										if ( liveness_marker != current_liveness_marker ){
-											
-											return;
-										}
-										
-										for ( RelatedContent c: content ){
-											
-											if ( content_set.contains( c )){
-												
-												if ( new_content == null ){
-													
-													new_content = new ArrayList<RelatedContent>( content.length );
-													
-													for ( RelatedContent c2: content ){
-														
-														if ( c == c2 ){
-															
-															break;
-														}
-														
-														new_content.add( c2 );
-													}
-												}									
-											}else{
-												
-												if ( new_content != null ){
-													
-													new_content.add( c );
-												}
-											}
-										}
-					
-										if ( new_content != null ){
-											
-											content = new_content.toArray( new RelatedContent[ new_content.size()]);
-										}
-										
-										content_set.addAll( Arrays.asList( content ));
-									}
-									
-									if ( content.length > 0 ){
-										
-										final RelatedContent[] f_content = content; 
-										
-										Utils.execSWTThread(
-											new Runnable()
-											{
-												public void
-												run()
-												{
-													if ( tv_related_content == f_table ){
-													
-														synchronized( content_set ){
-															
-															if ( liveness_marker != current_liveness_marker ){
-																
-																return;
-															}
-														}
-														
-														f_table.addDataSources( f_content );
-													}
-												}
-											});
-									}
-								}
-							});
-					}
-				}
-
-				public void 
-				tableViewDestroyed() 
-				{
-					manager.removeListener( current_rcm_listener );
-					
-					synchronized( content_set ){
-						
-						liveness_marker++;
-					
-						content_set.clear();
-					}
-				}
-			});
-
-		tv_related_content.addMenuFillListener(
-			new TableViewSWTMenuFillListener() 
-			{
-				public void 
-				fillMenu(String sColumnName, Menu menu)
-				{
-					Object[] _related_content = tv_related_content.getSelectedDataSources().toArray();
-
-					final RelatedContent[] related_content = new RelatedContent[_related_content.length];
-
-					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"));
-
-					Utils.setMenuItemImage( remove_item, "delete" );
-
-					remove_item.addSelectionListener(new SelectionAdapter() {
-						public void widgetSelected(SelectionEvent e) {
-							manager.delete( related_content );
-						};
-					});
-				}
-
-				public void 
-				addThisColumnSubMenu(
-					String columnName, Menu menuThisColumn) 
-				{
-				}
-			});
-
-		tv_related_content.addKeyListener(
-				new KeyListener()
-				{
-					public void 
-					keyPressed(
-						KeyEvent e )
-					{
-						if ( e.stateMask == 0 && e.keyCode == SWT.DEL ){
-							
-							Object[] selected;
-							
-							synchronized (this) {
-								
-								if ( tv_related_content == null ){
-									
-									selected = new Object[0];
-									
-								}else{
-								
-									selected = tv_related_content.getSelectedDataSources().toArray();
-								}
-							}
-							
-							RelatedContent[] content = new RelatedContent[ selected.length ];
-							
-							for ( int i=0;i<content.length;i++){
-								
-								content[i] = (RelatedContent)selected[i];
-							}
-							
-							manager.delete( content );
-							
-							e.doit = false;
-						}
-					}
-					
-					public void 
-					keyReleased(
-						KeyEvent arg0 ) 
-					{
-					}
-				});
-		tv_related_content.initialize( table_parent );
-
-		control.layout(true);
-	}
-	
-	public boolean 
-	isEnabled(
-		String key )
-	{
-		if ( key.equals( "remove" )){
-	
-			return( tv_related_content.getSelectedDataSources().size() > 0 );
-		}
-		
-		return( false );
-	}
-	
-	public boolean 
-	isSelected(
-		String key )
-	{
-		return( false );
-	}
-	
-	public void 
-	itemActivated(
-		String key )
-	{
-		Object[] _related_content = tv_related_content.getSelectedDataSources().toArray();
-
-		if ( _related_content.length > 0 ){
-			
-			RelatedContent[] related_content = new RelatedContent[_related_content.length];
-	
-			System.arraycopy( _related_content, 0, related_content, 0, related_content.length );
-			
-			manager.delete( related_content );
-		}
-	}
-	
-	
-	public String 
-	getUpdateUIName() 
-	{
-		return( "RCMView" );
-	}
-
-	public void 
-	updateUI() 
-	{
-		if ( tv_related_content != null ){
-			
-			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_Actions.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Actions.java
deleted file mode 100644
index 70cb04f..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Actions.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * Created on Aug 25, 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.content.columns;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.plugins.ui.tables.*;
-import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
-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 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.skin.SWTSkinFactory;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
-
-/**
- * @author TuxPaper
- * @created Aug 25, 2009
- *
- */
-public class ColumnRC_Actions
-	implements TableCellRefreshListener, TableCellMouseMoveListener,
-	TableCellSWTPaintListener
-{
-	public static final String COLUMN_ID = "rc_actions";
-
-	private static Font font = null;
-
-	private Color colorLinkNormal;
-
-	private Color colorLinkHover;
-
-
-	
-	public ColumnRC_Actions(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 215);
-		column.addListeners(this);
-		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
-		column.setType(TableColumn.TYPE_GRAPHIC);
-
-		if (column instanceof TableColumnCore) {
-			((TableColumnCore) column).setUseCoreDataSource(true);
-			((TableColumnCore) column).addCellOtherListener("SWTPaint", this);
-		}
-
-		SWTSkinProperties skinProperties = SWTSkinFactory.getInstance().getSkinProperties();
-		colorLinkNormal = skinProperties.getColor("color.links.normal");
-		colorLinkHover = skinProperties.getColor("color.links.hover");
-	}
-
-	public void cellPaint(GC gc, TableCellSWT cell) {
-		String text = cell.getText();
-
-		if (text != null && text.length() > 0) {
-			if (font == null) {
-				FontData[] fontData = gc.getFont().getFontData();
-				fontData[0].setStyle(SWT.BOLD);
-				font = new Font(gc.getDevice(), fontData);
-			}
-			gc.setFont(font);
-
-			Rectangle bounds = getDrawBounds(cell);
-
-			GCStringPrinter sp = new GCStringPrinter(gc, text, bounds, true, true,
-					SWT.WRAP | SWT.CENTER);
-
-			sp.calculateMetrics();
-
-			if (sp.hasHitUrl()) {
-				URLInfo[] hitUrlInfo = sp.getHitUrlInfo();
-				for (int i = 0; i < hitUrlInfo.length; i++) {
-					URLInfo info = hitUrlInfo[i];
-					// handle fake row when showing in column editor
-
-					info.urlUnderline = cell.getTableRow() == null
-							|| cell.getTableRow().isSelected();
-					if (info.urlUnderline) {
-						info.urlColor = null;
-					} else {
-						info.urlColor = colorLinkNormal;
-					}
-				}
-				int[] mouseOfs = cell.getMouseOffset();
-				if (mouseOfs != null) {
-					Rectangle realBounds = cell.getBounds();
-					URLInfo hitUrl = sp.getHitUrl(mouseOfs[0] + realBounds.x, mouseOfs[1]
-							+ realBounds.y);
-					if (hitUrl != null) {
-						hitUrl.urlColor = colorLinkHover;
-					}
-				}
-			}
-
-			sp.printString(GCStringPrinter.FLAG_FULLLINESONLY);
-		}
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void cellAdded(TableCell cell) {
-		cell.setMarginHeight(0);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell) {
-		RelatedContent rc = (RelatedContent) cell.getDataSource();
-		if (rc == null) {
-			return;
-		}
-		boolean downloadable = rc.getHash() != null;
-
-		if (!cell.setSortValue(downloadable ? 1 : 0) && cell.isValid()) {
-			return;
-		}
-
-		String s;
-		s = "<A HREF=\"search\">" + MessageText.getString("Button.search") + "</A>";
-		if (downloadable) {
-			s += " | <A HREF=\"dl\">"
-					+ MessageText.getString("v3.MainWindow.button.download") + "</A>";
-		}
-		cell.setText(s);
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCellMouseListener#cellMouseTrigger(org.gudy.azureus2.plugins.ui.tables.TableCellMouseEvent)
-	public void cellMouseTrigger(TableCellMouseEvent event) {
-		RelatedContent rc = (RelatedContent) event.cell.getDataSource();
-		if (rc == null) {
-			return;
-		}
-
-		boolean invalidateAndRefresh = event.eventType == event.EVENT_MOUSEEXIT;
-
-		Rectangle bounds = ((TableCellSWT) event.cell).getBounds();
-		String text = event.cell.getText();
-
-		GCStringPrinter sp = null;
-		GC gc = new GC(Display.getDefault());
-		try {
-			if (font != null) {
-				gc.setFont(font);
-			}
-			Rectangle drawBounds = getDrawBounds((TableCellSWT) event.cell);
-			sp = new GCStringPrinter(gc, text, drawBounds, true, true, SWT.WRAP
-					| SWT.CENTER);
-			sp.calculateMetrics();
-		} catch (Exception e) {
-			Debug.out(e);
-		} finally {
-			gc.dispose();
-		}
-
-		if (sp != null) {
-			URLInfo hitUrl = sp.getHitUrl(event.x + bounds.x, event.y + bounds.y);
-			int newCursor;
-			if (hitUrl != null) {
-				if (event.eventType == TableCellMouseEvent.EVENT_MOUSEUP && event.button == 1) {
-					if (hitUrl.url.equals("dl")) {
-						byte[]  hash = rc.getHash();
-						
-						if ( hash != null ){
-							
-							rc.setUnread( false );
-							
-							TorrentOpener.openTorrent( ByteFormatter.encodeString( hash ));
-						}
-						
-					} else if (hitUrl.url.equals("search")) {
-						rc.setUnread( false );
-						
-						String	title = rc.getTitle();
-						
-						MainWindow.doSearch( title );
-					}
-				}
-
-				newCursor = SWT.CURSOR_HAND;
-			} else {
-				newCursor = SWT.CURSOR_ARROW;
-			}
-
-			int oldCursor = ((TableCellSWT) event.cell).getCursorID();
-			if (oldCursor != newCursor) {
-				invalidateAndRefresh = true;
-				((TableCellSWT) event.cell).setCursorID(newCursor);
-			}
-		}
-
-		if (invalidateAndRefresh) {
-			event.cell.invalidate();
-			((TableCellSWT)event.cell).redraw();
-		}
-	}
-
-	private Rectangle getDrawBounds(TableCellSWT cell) {
-		Rectangle bounds = cell.getBounds();
-
-		return bounds;
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java
deleted file mode 100644
index 56bacf4..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Created.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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
deleted file mode 100644
index eaac9f2..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Hash.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-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;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Hash
-	implements TableCellRefreshListener, TableCellAddedListener // , TableCellMouseListener
-{
-	public static final String COLUMN_ID = "rc_hash";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_Hash(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_INVISIBLE, 215);
-		column.addListeners(this);
-		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
-		column.setType(TableColumn.TYPE_TEXT_ONLY);
-		if ( column instanceof TableColumnCore ){
-			((TableColumnCore)column).setUseCoreDataSource( true );
-		}
-	}
-
-	public void cellAdded(TableCell cell) {
-		
-		RelatedContent rc = (RelatedContent) cell.getDataSource();
-		
-		if ( cell instanceof TableCellSWT && rc != null && rc.getHash() != null ){
-		
-			((TableCellSWT)cell).setCursorID( SWT.CURSOR_HAND );
-			
-			cell.setToolTip( MessageText.getString( "rcm.rc_hash.tt" ));
-		}
-	}
-	
-	public void refresh(TableCell cell) {
-		RelatedContent rc = (RelatedContent) cell.getDataSource();
-		if (rc == null) {
-			return;
-		}
-
-		byte[] hash = rc.getHash();
-		
-		if ( hash == null ){
-			
-			return;
-		}
-
-		cell.setText(ByteFormatter.encodeString(hash));
-	}
-	
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
-				&& event.button == 1) {
-			RelatedContent rc = (RelatedContent) event.cell.getDataSource();
-			
-			byte[]  hash = rc.getHash();
-			
-			if ( hash != null ){
-				
-				rc.setUnread( false );
-				
-				TorrentOpener.openTorrent( ByteFormatter.encodeString( 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
deleted file mode 100644
index e6db8ad..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_LastSeen.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_LastSeen
-	implements TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "rc_lastseen";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_LastSeen(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_INVISIBLE, 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 last_seen = rc.getLastSeenSecs();
-
-		if ( cell.setSortValue( last_seen )){
-		
-			cell.setText( DisplayFormatters.formatDateShort( last_seen*1000 ));
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java
deleted file mode 100644
index 922f31e..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Level.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Level
-	implements TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "rc_level";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_Level(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_INVISIBLE, 40 );
-		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;
-		}
-
-		int level = rc.getLevel();
-
-		if ( cell.setSortValue( level )){
-		
-			cell.setText( String.valueOf( level ));
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java
deleted file mode 100644
index db456ba..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_New.java
+++ /dev/null
@@ -1,121 +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.content.columns;
-
-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.ui.swt.views.table.TableCellSWT;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Sep 25, 2008
- *
- */
-public class ColumnRC_New
-	implements TableCellSWTPaintListener, TableCellAddedListener,
-	TableCellRefreshListener, TableCellMouseListener
-{
-	public static final String COLUMN_ID = "rc_new";
-
-	private static int WIDTH = 38; // enough to fit title
-
-	private static Image imgNew;
-
-	private static Image imgOld;
-
-
-	public ColumnRC_New(TableColumn column ) {
-	
-		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, WIDTH );
-		column.addListeners(this);
-		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
-		column.setType(TableColumn.TYPE_GRAPHIC);
-
-		if ( column instanceof TableColumnCore ){
-			
-			((TableColumnCore)column).addCellOtherListener("SWTPaint", this );
-		}
-		
-		imgNew = ImageLoader.getInstance().getImage("image.activity.unread");
-		imgOld = ImageLoader.getInstance().getImage("image.activity.read");
-	}
-
-	public void cellPaint(GC gc, TableCellSWT cell) {
-		RelatedContent entry = (RelatedContent) cell.getDataSource();
-
-		Rectangle cellBounds = cell.getBounds();
-		Image img = entry== null || entry.isUnread() ? imgNew : imgOld;
-
-		if (img != null && !img.isDisposed()) {
-			Rectangle imgBounds = img.getBounds();
-			gc.drawImage(img, cellBounds.x
-					+ ((cellBounds.width - imgBounds.width) / 2), cellBounds.y
-					+ ((cellBounds.height - imgBounds.height) / 2));
-		}
-	}
-
-	public void cellAdded(TableCell cell) {
-		cell.setMarginWidth(0);
-		cell.setMarginHeight(0);
-		
-		if ( cell instanceof TableCellSWT ){
-		
-			((TableCellSWT)cell).setCursorID( SWT.CURSOR_HAND );
-		}
-	}
-
-	public void refresh(TableCell cell) {
-		RelatedContent entry = (RelatedContent) cell.getDataSource();
-
-		if ( entry != null ){
-			
-			boolean unread = entry.isUnread();
-			
-			long sortVal = ((unread ? 2 : 1) << 62) + entry.getLastSeenSecs();
-	
-			if (!cell.setSortValue(sortVal) && cell.isValid()) {
-				return;
-			}
-		}
-	}
-
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
-				&& event.button == 1) {
-			RelatedContent entry = (RelatedContent) event.cell.getDataSource();
-			
-			if ( entry != null ){
-			
-				entry.setUnread(!entry.isUnread());
-			
-				event.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
deleted file mode 100644
index 9f043df..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Peers.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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_Rank.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Rank.java
deleted file mode 100644
index ea85bb2..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Rank.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Rank
-	implements TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "rc_rank";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_Rank(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_CENTER, TableColumn.POSITION_LAST, 40 );
-		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;
-		}
-
-		int rank = rc.getRank();
-
-		if ( cell.setSortValue( rank )){
-		
-			cell.setText( String.valueOf( rank ));
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java
deleted file mode 100644
index 290a1c9..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Seeds.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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_Size.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Size.java
deleted file mode 100644
index 53c0122..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Size.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Size
-	implements TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "rc_size";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_Size(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_TRAIL, TableColumn.POSITION_LAST, 80 );
-		column.addListeners(this);
-		column.setRefreshInterval(TableColumn.INTERVAL_INVALID_ONLY);
-		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 size = rc.getSize();
-
-		if ( size > 0 && cell.setSortValue( size )){
-		
-			cell.setText( DisplayFormatters.formatByteCountToKiBEtc( size ));
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java b/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java
deleted file mode 100644
index d0f2521..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Title.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * 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.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 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;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Title
-	implements TableCellRefreshListener //, TableCellMouseListener, TableCellAddedListener
-{
-	public static final String COLUMN_ID = "rc_title";
-
-	/**
-	 * 
-	 * @param sTableID
-	 */
-	public ColumnRC_Title(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 400);
-		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;
-		}
-
-		String text = rc.getTitle();
-		
-		if ( text == null || text.length() == 0 ){
-			
-			return;
-		}
-
-		cell.setText(text);
-	}
-	
-	/*
-	public void cellAdded(TableCell cell) {
-		
-		RelatedContent rc = (RelatedContent) cell.getDataSource();
-		
-		if ( cell instanceof TableCellSWT && rc != null ){
-		
-			((TableCellSWT)cell).setCursorID( SWT.CURSOR_HAND );
-			
-			cell.setToolTip( MessageText.getString( "rcm.rc_title.tt" ));
-		}
-	}
-	
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
-				&& event.button == 1) {
-			RelatedContent rc = (RelatedContent) event.cell.getDataSource();
-			
-			if ( rc != null ){
-				
-				rc.setUnread( false );
-					
-				String	title = rc.getTitle();
-				
-				MainWindow.doSearch( 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
deleted file mode 100644
index 7408ba4..0000000
--- a/com/aelitis/azureus/ui/swt/content/columns/ColumnRC_Tracker.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * 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.content.columns;
-
-import com.aelitis.azureus.core.content.RelatedContent;
-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.views.table.TableCellSWT;
-
-/**
- * @author TuxPaper
- * @created Feb 26, 2009
- *
- */
-public class ColumnRC_Tracker
-	implements TableCellRefreshListener, TableCellAddedListener // , TableCellMouseListener
-{
-	public static final String COLUMN_ID = "rc_tracker";
-
-
-	public ColumnRC_Tracker(TableColumn column) {
-		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_INVISIBLE, 215);
-		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;
-		}
-
-		String tracker = rc.getTracker();
-		
-		if ( !validTracker( tracker )){
-			
-			return;
-		}
-
-		cell.setText(tracker);
-	}
-	
-	public void cellAdded(TableCell cell) {
-		
-		RelatedContent rc = (RelatedContent) cell.getDataSource();
-		
-		if ( cell instanceof TableCellSWT && rc != null && validTracker(  rc.getTracker())){
-		
-			((TableCellSWT)cell).setCursorID( SWT.CURSOR_HAND );
-			
-			cell.setToolTip( MessageText.getString( "rcm.rc_tracker.tt" ));
-		}
-	}
-	
-	public void cellMouseTrigger(final TableCellMouseEvent event) {
-		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEDOWN
-				&& event.button == 1) {
-			RelatedContent rc = (RelatedContent) event.cell.getDataSource();
-			
-			String tracker = rc.getTracker();
-			
-			if ( validTracker( tracker )){
-				
-				rc.setUnread( false );
-				
-				Utils.launch( "http://" + tracker + "/" );
-			}
-		}
-	}
-	
-	private boolean
-	validTracker(
-		String	tracker )
-	{
-		if ( tracker == null || tracker.length() == 0 ){
-			
-			return( false );
-		}
-		
-		int pos = tracker.lastIndexOf( '.' );
-		
-		if ( pos == -1 ){
-			
-			return( false );
-		}
-		
-		for ( int i=pos+1;i<tracker.length();i++){
-			
-			if ( !Character.isDigit( tracker.charAt( i ))){
-				
-				return( true );
-			}
-		}
-		
-		return( false );
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/devices/DeviceInfoArea.java b/com/aelitis/azureus/ui/swt/devices/DeviceInfoArea.java
index 8a46cbc..29abd87 100644
--- a/com/aelitis/azureus/ui/swt/devices/DeviceInfoArea.java
+++ b/com/aelitis/azureus/ui/swt/devices/DeviceInfoArea.java
@@ -30,22 +30,23 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.installer.*;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.devices.*;
-import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 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;
-
-import org.gudy.azureus2.plugins.PluginException;
-import org.gudy.azureus2.plugins.installer.*;
-import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
 
 /**
  * @author TuxPaper
@@ -55,7 +56,6 @@ import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
 public class DeviceInfoArea
 	extends SkinView
 {
-	private SideBarEntrySWT sidebarEntry;
 	private DeviceMediaRenderer device;
 	private Composite main;
 	private Composite parent;
@@ -63,10 +63,12 @@ public class DeviceInfoArea
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectInitialShow(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
 
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			sidebarEntry = sidebar.getCurrentEntry();
-			device = (DeviceMediaRenderer) sidebarEntry.getDatasource();
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			MdiEntrySWT entry = mdi.getEntryFromSkinObject(skinObject);
+			if (entry != null) {
+				device = (DeviceMediaRenderer) entry.getDatasource();
+			}
 		}
 		
 		parent = (Composite) skinObject.getControl();
diff --git a/com/aelitis/azureus/ui/swt/devices/DeviceInternetView.java b/com/aelitis/azureus/ui/swt/devices/DeviceInternetView.java
index 825d75e..3658eff 100644
--- a/com/aelitis/azureus/ui/swt/devices/DeviceInternetView.java
+++ b/com/aelitis/azureus/ui/swt/devices/DeviceInternetView.java
@@ -37,6 +37,7 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
 
@@ -420,10 +421,34 @@ DeviceInternetView
 	{
 		return( main );
 	}
-	
-	public void
-	delete()
-	{
-		super.delete();
-	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	//swtView = (UISWTView)event.getData();
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java b/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
index 1dab65b..167fbf2 100644
--- a/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
+++ b/com/aelitis/azureus/ui/swt/devices/DeviceManagerUI.java
@@ -18,17 +18,17 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 
-
 package com.aelitis.azureus.ui.swt.devices;
 
 
-
 import java.io.File;
 import java.net.InetAddress;
+import java.net.URL;
 import java.util.*;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
@@ -38,6 +38,7 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.installer.PluginInstaller;
@@ -47,17 +48,16 @@ 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.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 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.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.plugins.*;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -67,26 +67,25 @@ import com.aelitis.azureus.core.devices.*;
 import com.aelitis.azureus.core.devices.DeviceManager.DeviceManufacturer;
 import com.aelitis.azureus.core.devices.DeviceManager.UnassociatedDevice;
 import com.aelitis.azureus.core.download.DiskManagerFileInfoFile;
+import com.aelitis.azureus.core.download.StreamManager;
 import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
+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;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-import com.aelitis.azureus.ui.swt.devices.add.DeviceTemplateChooser;
-import com.aelitis.azureus.ui.swt.devices.add.ManufacturerChooser;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.devices.add.*;
 import com.aelitis.azureus.ui.swt.devices.add.DeviceTemplateChooser.DeviceTemplateClosedListener;
 import com.aelitis.azureus.ui.swt.devices.add.ManufacturerChooser.ClosedListener;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnabler;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnablerSelectedContent;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader.ImageDownloaderListener;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 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.SkinViewManager.SkinViewManagerListener;
 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.SideBarListener;
 
 public class 
 DeviceManagerUI 
@@ -100,7 +99,9 @@ DeviceManagerUI
 	private static final Object	DEVICE_IVIEW_KEY = new Object();
 	
 	private static final String CONFIG_VIEW_TYPE				= "device.sidebar.ui.viewtype";
-	static final String CONFIG_VIEW_HIDE_REND_GENERIC	= "device.sidebar.ui.rend.hidegeneric";
+	
+	public static final String CONFIG_VIEW_HIDE_REND_GENERIC	= "device.sidebar.ui.rend.hidegeneric";
+	public static final String CONFIG_VIEW_SHOW_ONLY_TAGGED		= "device.sidebar.ui.rend.showonlytagged";
 	
 	private static final String SPINNER_IMAGE_ID 	= "image.sidebar.vitality.dl";
 	private static final String INFO_IMAGE_ID		= "image.sidebar.vitality.info";
@@ -109,10 +110,11 @@ DeviceManagerUI
 	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" };
+	//private static final String[] to_copy_indicator_colors = { "#000000", "#000000", "#168866", "#1c5620" };
 	
 	private DeviceManager			device_manager;
 	private DeviceManagerListener	device_manager_listener;
+	private boolean					device_manager_listener_added;
 	
 	private final PluginInterface	plugin_interface;
 	private final UIManager			ui_manager;
@@ -121,7 +123,7 @@ DeviceManagerUI
 	
 	private boolean		ui_setup;
 	
-	private SideBar		side_bar;
+	private MultipleDocumentInterfaceSWT		mdi;
 	private boolean		sidebar_built;
 	
 	private static final int SBV_SIMPLE		= 0;
@@ -129,6 +131,7 @@ DeviceManagerUI
 	
 	private int			side_bar_view_type		= COConfigurationManager.getIntParameter( CONFIG_VIEW_TYPE, SBV_SIMPLE );
 	private boolean		side_bar_hide_rend_gen	= COConfigurationManager.getBooleanParameter( CONFIG_VIEW_HIDE_REND_GENERIC, true );
+	private boolean		side_bar_show_tagged	= COConfigurationManager.getBooleanParameter( CONFIG_VIEW_SHOW_ONLY_TAGGED, false );
 	
 	private int			next_sidebar_id;
 		
@@ -138,6 +141,7 @@ DeviceManagerUI
 	private MenuItemListener properties_listener;
 	private MenuItemListener hide_listener;
 	private MenuItemListener rename_listener;
+	private MenuItemListener export_listener;
 	
 	private MenuItemFillListener	will_remove_listener;
 	private MenuItemListener 		remove_listener;
@@ -145,10 +149,18 @@ DeviceManagerUI
 	private MenuItemFillListener	show_fill_listener;
 	private MenuItemListener 		show_listener;
 
-	
+	private MenuItemFillListener	will_tag_listener;
+	private MenuItemListener 		tag_listener;
+
 	private MenuItemFillListener will_browse_listener;
 	
 	private boolean	offline_menus_setup;
+
+	private MdiEntry mdiEntryOverview;
+
+	private boolean needsAddAllDevices;
+
+	private MdiEntry entryHeader;
 	
 	
 	static {
@@ -159,6 +171,7 @@ DeviceManagerUI
   		} else {
   			DISABLED = Constants.isUnix;
   		}
+  		DISABLED |= Utils.isAZ2UI();
 		} catch (Throwable t) {
 			// Benefit of the doubt?
 			DISABLED = false;
@@ -214,11 +227,11 @@ DeviceManagerUI
 	private void uiAttachedAndCoreRunning(AzureusCore core) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
+				MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
 				
-				if (sideBar != null) {
+				if (mdi != null) {
 					
-					setupUI(sideBar);
+					setupUI(mdi);
 				} else {
 					
 					SkinViewManager.addListener(new SkinViewManagerListener() {
@@ -241,36 +254,57 @@ DeviceManagerUI
 				public boolean 
 				canClose() 
 				{
-					try {
-  					final TranscodeJob job = device_manager.getTranscodeManager().getQueue().getCurrentJob();
-  					
-  					if ( job == null || job.getState() != TranscodeJob.ST_RUNNING ){
-  						
-  						return( true );
-  					}
+					try{
+						if ( device_manager == null ){
+							
+								// not yet init, safe to close
+							
+							return( true );
+						}
+						
+						final TranscodeJob job = device_manager.getTranscodeManager().getQueue().getCurrentJob();
+
+						if ( job == null || job.getState() != TranscodeJob.ST_RUNNING ){
+
+							return( true );
+						}
 
+						if ( job.getTranscodeFile().getDevice().isHidden()){
+							
+							// The assumption here is that if the device is hidden either the user shouldn't be concerned
+							// about the loss of active transcode as either it is something that they don't know about or
+							// alternative canClose listeners have been registered to handle the situation (e.g. burn-in-progress)
+
+							return( true );
+						}
+						
 						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())
+										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")
+										MessageText.getString("UpdateWindow.quit"),
+										MessageText.getString("Content.alert.notuploaded.button.abort")
 								}, 1);
+						
 						mb.open(null);
+						
 						mb.waitUntilClosed();
+						
 						return mb.getResult() == 0;
 
-					} catch (Exception e) {
+					}catch ( Throwable e ){
+						
 						Debug.out(e);
+						
 						return true;
 					}
 				}
@@ -292,7 +326,7 @@ DeviceManagerUI
 	
 	protected void
 	setupUI(
-		SideBar			_side_bar )	
+		MultipleDocumentInterfaceSWT			mdi )	
 	{
 		synchronized( this ){
 			
@@ -304,10 +338,29 @@ DeviceManagerUI
 			ui_setup = true;
 		}
 		
-		side_bar		= _side_bar;
+		this.mdi		= mdi;
 
 		device_manager 	= DeviceManagerFactory.getSingleton();
 		
+		setupMenuListeners();
+
+		mdi.registerEntry(SideBar.SIDEBAR_SECTION_DEVICES,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						if ( sidebar_built ){
+							removeAllDevices();
+							
+							buildSideBar( true );
+						} else {
+							buildSideBar(false);
+						}
+							
+						addAllDevices();
+						return mdiEntryOverview;
+					}
+				});
+
+		
 		device_manager.addListener(new DeviceManagerListener() {
 		
 			public void deviceRemoved(Device device) {
@@ -315,11 +368,7 @@ DeviceManagerUI
 		
 			public void deviceManagerLoaded() {
 				device_manager.removeListener(this);
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						setupUIwithDeviceManager();
-					}
-				});
+				setupUIwithDeviceManager();
 			}
 		
 			public void deviceChanged(Device device) {
@@ -337,96 +386,126 @@ DeviceManagerUI
 	private void
 	setupUIwithDeviceManager()
 	{
-		device_manager_listener = 
-			new DeviceManagerListener()
-			{
-				public void 
-				deviceAdded(
-					Device device ) 
-				{
-					addOrChangeDevice( device );
-				}
-				
-				public void
-				deviceChanged(
-					Device		device )
-				{
-					addOrChangeDevice( device );
-				}
-				
-				public void
-				deviceAttentionRequest(
-					Device		device )
-				{
-					showDevice( device );
-				}
-				
-				public void
-				deviceRemoved(
-					Device		device )
-				{
-					removeDevice( device );
-				}
-				
-				public void 
-				deviceManagerLoaded() {
-				}
-			};
+		boolean	add_all = false;
 		
-			TranscodeManager transMan = device_manager.getTranscodeManager();
-			TranscodeQueue transQ = transMan.getQueue();
-			transQ.addListener(
-			new TranscodeQueueListener()
-			{
-				int	last_job_count = 0;
-				
-				public void
-				jobAdded(
-					TranscodeJob		job )
+		synchronized( this ){
+			
+			device_manager_listener = 
+				new DeviceManagerListener()
 				{
-					check();
-				}
+					public void 
+					deviceAdded(
+						Device device ) 
+					{
+						addOrChangeDevice( device );
+					}
+					
+					public void
+					deviceChanged(
+						Device		device )
+					{
+						addOrChangeDevice( device );
+					}
+					
+					public void
+					deviceAttentionRequest(
+						Device		device )
+					{
+						showDevice( device );
+					}
+					
+					public void
+					deviceRemoved(
+						Device		device )
+					{
+						removeDevice( device );
+					}
+					
+					public void 
+					deviceManagerLoaded() {
+					}
+				};
 				
-				public void
-				jobChanged(
-					TranscodeJob		job )
-				{
-					check();
-				}
+			if ( needsAddAllDevices ){
 				
-				public void
-				jobRemoved(
-					TranscodeJob		job )
-				{
-					check();
-				}
+				add_all = true;
 				
-				protected void
-				check()
+				needsAddAllDevices = false;
+			}
+		}
+		
+		TranscodeManager transMan = device_manager.getTranscodeManager();
+
+		TranscodeQueue transQ = transMan.getQueue();
+
+		transQ.addListener(
+				new TranscodeQueueListener()
 				{
-					int job_count = device_manager.getTranscodeManager().getQueue().getJobCount();
-					
-					if ( job_count != last_job_count ){
-						
-						if ( job_count == 0 || last_job_count == 0 ){
-													
-							SideBarEntrySWT main_sb_entry = SideBar.getEntry( SideBar.SIDEBAR_SECTION_DEVICES );
-	
-							if ( main_sb_entry != null ){
-						
-								ViewTitleInfoManager.refreshTitleInfo( main_sb_entry.getTitleInfo());
+					int	last_job_count = 0;
+
+					public void
+					jobAdded(
+							TranscodeJob		job )
+					{
+						check();
+					}
+
+					public void
+					jobChanged(
+							TranscodeJob		job )
+					{
+						check();
+					}
+
+					public void
+					jobRemoved(
+							TranscodeJob		job )
+					{
+						check();
+					}
+
+					protected void
+					check()
+					{
+						int job_count = device_manager.getTranscodeManager().getQueue().getJobCount();
+
+						if ( job_count != last_job_count ){
+
+							if ( job_count == 0 || last_job_count == 0 ){
+
+								MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+								if ( mdi != null ){
+
+									MdiEntry main_entry = mdi.getEntry( SideBar.SIDEBAR_SECTION_DEVICES );
+
+									if ( main_entry != null ){
+
+										ViewTitleInfoManager.refreshTitleInfo( main_entry.getViewTitleInfo());
+									}
+								}
 							}
+
+							last_job_count = job_count;
 						}
-						
-						last_job_count = job_count;
 					}
-				}
-			});
+				});
 		
 		setupListeners();
 		
-		buildSideBar( false );
+		//buildSideBar( false );
+		
+		setupConfigUI(); // MDIEntry not required
+
+		if ( add_all ){
+			
+			addAllDevices();
+		}
 		
+		setupTranscodeMenus(); // MDIEntry not required
+	}
+	
+	public void setupConfigUI() {
 		BasicPluginConfigModel configModel = ui_manager.createBasicPluginConfigModel(
 				ConfigSection.SECTION_ROOT, "Devices");
 
@@ -504,6 +583,10 @@ DeviceManagerUI
 				"!" + CONFIG_VIEW_HIDE_REND_GENERIC + "!", "devices.sidebar.hide.rend.generic",
 				side_bar_hide_rend_gen );
 		
+		configModel.addBooleanParameter2( 
+				"!" + CONFIG_VIEW_SHOW_ONLY_TAGGED + "!", "devices.sidebar.show.only.tagged",
+				side_bar_show_tagged );
+
 		// transcoding
 		
 			// default dir
@@ -544,6 +627,25 @@ DeviceManagerUI
 				}
 			});
 
+			// disable sleep
+		
+		final BooleanParameter disable_sleep = 
+			configModel.addBooleanParameter2( 
+				"device.config.xcode.disable_sleep", "device.config.xcode.disable_sleep",
+				device_manager.getDisableSleep());
+				
+		
+		disable_sleep.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					device_manager.setDisableSleep( disable_sleep.getValue());
+				}
+			});
+		
 			// itunes
 		
 		final ActionParameter btnITunes = configModel.addActionParameter2("devices.button.installitunes", "UpdateWindow.columns.install");
@@ -579,7 +681,7 @@ DeviceManagerUI
 			"device.xcode.group",
 			new Parameter[]
 			{
-					def_work_dir, max_xcode, btnITunes
+					def_work_dir, max_xcode, disable_sleep, btnITunes
 			});
 		
 			// rss
@@ -633,7 +735,7 @@ DeviceManagerUI
 				{
 					dodm.setOfflineDownloadingEnabled( od_enable.getValue());
 					
-					rebuildSideBar();
+					rebuildSideBarIfExists();
 				}
 			});
 		
@@ -682,6 +784,50 @@ DeviceManagerUI
 				od_enable, od_auto_enable, od_pt_enable,
 			});
 		
+		
+			// play now
+		
+		final StreamManager sm = StreamManager.getSingleton();
+		
+		final IntParameter pn_buffer = 
+			configModel.addIntParameter2( 
+				"device.playnow.buffer", "device.playnow.buffer",
+				sm.getBufferSecs());
+		
+		pn_buffer.addListener(
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param) 
+					{
+						sm.setBufferSecs( pn_buffer.getValue());
+					}
+				});
+		
+		final IntParameter pn_min_buffer = 
+			configModel.addIntParameter2( 
+				"device.playnow.min_buffer", "device.playnow.min_buffer",
+				sm.getMinBufferSecs());
+		
+		pn_min_buffer.addListener(
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param) 
+					{
+						sm.setMinBufferSecs( pn_buffer.getValue());
+					}
+				});
+		
+		configModel.createGroup(
+				"device.playnow.group",
+				new Parameter[]
+				{
+						pn_buffer, pn_min_buffer,
+				});
+			
 		final BooleanParameter tivo_enable = 
 			configModel.addBooleanParameter2( 
 				"device.tivo.enable", "device.tivo.enable", false );
@@ -697,24 +843,14 @@ DeviceManagerUI
 				{
 					device_manager.setTiVoEnabled( tivo_enable.getValue());
 					
-					rebuildSideBar();
+					rebuildSideBarIfExists();
 				}
 			});
 		
-		addAllDevices();
-	
-		setupTranscodeMenus();
-	}
-	
-	protected String
-	getRSSLink(
-		int		port )
-	{
-		return( "http://127.0.0.1:" + port + "/" );
 	}
 	
 	protected void
-	setupListeners()
+	setupMenuListeners()
 	{
 		properties_listener = 
 			new MenuItemListener() 
@@ -724,8 +860,8 @@ DeviceManagerUI
 					MenuItem menu, 
 					Object target) 
 				{
-					if (target instanceof SideBarEntry) {
-						SideBarEntry info = (SideBarEntry) target;
+					if (target instanceof MdiEntry) {
+						MdiEntry info = (MdiEntry) target;
 						Device device = (Device)info.getDatasource();
 					
 						showProperties( device );
@@ -741,9 +877,9 @@ DeviceManagerUI
 					MenuItem menu, 
 					Object target) 
 				{
-					if (target instanceof SideBarEntry){
+					if (target instanceof MdiEntry){
 						
-						SideBarEntry info = (SideBarEntry) target;
+						MdiEntry info = (MdiEntry) target;
 						
 						Device device = (Device)info.getDatasource();
 					
@@ -751,7 +887,60 @@ DeviceManagerUI
 					}
 				}
 			};
-			
+		
+		will_tag_listener = 
+				new MenuItemFillListener() 
+				{
+					public void 
+					menuWillBeShown(
+						MenuItem 	menu, 
+						Object 		targets) 
+					{
+						Object[]	rows;
+						
+						if ( targets instanceof Object[] ){
+							
+							rows = (Object[])targets;
+							
+						}else{
+							
+							rows = new Object[]{ targets };
+						}
+						
+						if ( rows.length > 0 && rows[0] instanceof MdiEntry ){
+													
+							MdiEntry info = (MdiEntry)rows[0];
+						
+							Device device = (Device)info.getDatasource();
+							
+							menu.setData( device.isTagged());
+							
+						}else{
+							
+							menu.setEnabled( false );
+						}
+					}
+				};
+				
+		tag_listener = 
+			new MenuItemListener() 
+			{
+				public void 
+				selected(
+					MenuItem menu, 
+					Object target) 
+				{
+					if (target instanceof MdiEntry){
+						
+						MdiEntry info = (MdiEntry) target;
+						
+						Device device = (Device)info.getDatasource();
+					
+						device.setTagged( !device.isTagged());
+					}
+				}
+			};
+				
 		rename_listener = 
 				new MenuItemListener() 
 				{
@@ -760,9 +949,9 @@ DeviceManagerUI
 						MenuItem menu, 
 						Object target) 
 					{
-						if (target instanceof SideBarEntry){
+						if (target instanceof MdiEntry){
 							
-							SideBarEntry info = (SideBarEntry) target;
+							MdiEntry info = (MdiEntry) target;
 							
 							final Device device = (Device)info.getDatasource();
 							
@@ -788,7 +977,7 @@ DeviceManagerUI
 									
 									if ( input.length() > 0 ){
 										
-										device.setName( input );
+										device.setName( input, false );
 									}
 								}
 							});		
@@ -796,6 +985,25 @@ DeviceManagerUI
 					}
 				};
 
+		export_listener = 
+			new MenuItemListener() 
+			{
+				public void 
+				selected(
+					MenuItem menu, 
+					Object target) 
+				{
+					if ( target instanceof MdiEntry){
+						
+						MdiEntry info = (MdiEntry) target;
+						
+						Device device = (Device)info.getDatasource();
+						
+						export( device );
+					}
+				}
+			};
+			
 		will_remove_listener = 
 				new MenuItemFillListener() 
 				{
@@ -815,9 +1023,9 @@ DeviceManagerUI
 							rows = new Object[]{ targets };
 						}
 						
-						if ( rows.length > 0 && rows[0] instanceof SideBarEntry ){
+						if ( rows.length > 0 && rows[0] instanceof MdiEntry ){
 													
-							SideBarEntry info = (SideBarEntry)rows[0];
+							MdiEntry info = (MdiEntry)rows[0];
 						
 							Device device = (Device)info.getDatasource();
 							
@@ -838,9 +1046,9 @@ DeviceManagerUI
 					MenuItem menu, 
 					Object target) 
 				{
-					if (target instanceof SideBarEntry){
+					if (target instanceof MdiEntry){
 						
-						SideBarEntry info = (SideBarEntry) target;
+						MdiEntry info = (MdiEntry) target;
 						
 						Device device = (Device)info.getDatasource();
 					
@@ -872,9 +1080,9 @@ DeviceManagerUI
 							rows = new Object[]{ targets };
 						}
 						
-						if ( rows.length > 0 && rows[0] instanceof SideBarEntry ){
+						if ( rows.length > 0 && rows[0] instanceof MdiEntry ){
 													
-							SideBarEntry info = (SideBarEntry)rows[0];
+							MdiEntry info = (MdiEntry)rows[0];
 						
 							Device device = (Device)info.getDatasource();
 					
@@ -914,9 +1122,9 @@ DeviceManagerUI
 					MenuItem menu, 
 					Object target) 
 				{
-					if ( target instanceof SideBarEntry ){
+					if ( target instanceof MdiEntry ){
 						
-						SideBarEntry info = (SideBarEntry)target;
+						MdiEntry info = (MdiEntry)target;
 												
 						Object ds = info.getDatasource();
 						
@@ -970,9 +1178,9 @@ DeviceManagerUI
 						
 						for ( Object row: rows ){
 							
-							if ( row instanceof SideBarEntry ){
+							if ( row instanceof MdiEntry ){
 								
-								SideBarEntry info = (SideBarEntry)row;
+								MdiEntry info = (MdiEntry)row;
 														
 								Object ds = info.getDatasource();
 								
@@ -1003,74 +1211,69 @@ DeviceManagerUI
 					}
 			
 				};
-		side_bar.addListener(
-			new SideBarListener()
+	}
+	
+	private void 
+	export(
+		final Device	device ) 
+	{
+		Utils.execSWTThread(
+			new AERunnable() 
 			{
 				public void 
-				sidebarItemSelected(
-					SideBarEntrySWT new_entry,
-					SideBarEntrySWT old_entry	)
+				runSupport()
 				{
-					Object data_source = new_entry.getDatasource();
+					FileDialog dialog = 
+						new FileDialog( Utils.findAnyShell(), SWT.SYSTEM_MODAL | SWT.SAVE );
+					
+					dialog.setFilterPath( TorrentOpener.getFilterPathData() );
+											
+					dialog.setText(MessageText.getString("device.export.select.template.file"));
+					
+					dialog.setFilterExtensions(new String[] {
+							"*.vuze",
+							"*.vuz",
+							Constants.FILE_WILDCARD
+						});
+					dialog.setFilterNames(new String[] {
+							"*.vuze",
+							"*.vuz",
+							Constants.FILE_WILDCARD
+						});
 					
-					if ( data_source instanceof Device ){
+					String path = TorrentOpener.setFilterPathData( dialog.open());
+
+					if ( path != null ){
 						
-						final Device	device = (Device)data_source;
+						String lc = path.toLowerCase();
 						
-						ISelectedContent[] sels = {
-							new ToolBarEnablerSelectedContent( 
-								new ToolBarEnabler()
-								{
-									public boolean 
-									isEnabled(
-										String itemKey )
-									{
-										return( "remove".equals(itemKey));
-									}
-									  
-									public boolean 
-									isSelected(
-										String itemKey )
-									{
-										return( false );
-									}
-									  
-									public void 
-									itemActivated(
-										String itemKey )
-									{
-										MessageBoxShell mb = 
-											new MessageBoxShell(
-												MessageText.getString("message.confirm.delete.title"),
-												MessageText.getString("message.confirm.delete.text",
-														new String[] {
-															device.getName()
-														}), 
-												new String[] {
-													MessageText.getString("Button.yes"),
-													MessageText.getString("Button.no")
-												},
-												1 );
-										
-										mb.open(new UserPrompterResultListener() {
-											public void prompterClosed(int result) {
-												if (result == 0) {
-													device.remove();
-												}
-											}
-										});
-									}
-								})};
-										
-						SelectedContentManager.changeCurrentlySelectedContent("IconBarEnabler", sels );
+						if ( !lc.endsWith( ".vuze" ) && !lc.endsWith( ".vuz" )){
+							
+							path += ".vuze";
+						}
+						
+						try{
+							VuzeFile vf = device.getVuzeFile();
+							
+							vf.write( new File( path ));
+							
+						}catch( Throwable e ){
+							
+							Debug.out( e );
+						}
 					}
 				}
 			});
-		
+	}
+	
+	protected void
+	setupListeners()
+	{
 		COConfigurationManager.addAndFireParameterListeners( 
 			new String[]{
 				CONFIG_VIEW_TYPE,
 				CONFIG_VIEW_HIDE_REND_GENERIC,
+				CONFIG_VIEW_SHOW_ONLY_TAGGED,
 			},
 			new org.gudy.azureus2.core3.config.ParameterListener()
 			{
@@ -1081,15 +1284,17 @@ DeviceManagerUI
 					side_bar_view_type = COConfigurationManager.getIntParameter( CONFIG_VIEW_TYPE, SBV_SIMPLE );
 					
 					side_bar_hide_rend_gen = COConfigurationManager.getBooleanParameter( CONFIG_VIEW_HIDE_REND_GENERIC, true );
+					
+					side_bar_show_tagged = COConfigurationManager.getBooleanParameter( CONFIG_VIEW_SHOW_ONLY_TAGGED, false );
 
-					rebuildSideBar();
+					rebuildSideBarIfExists();
 				}
 			});
 	}
 	
 	protected static void
 	hideIcon(
-		SideBarVitalityImage	x )
+		MdiEntryVitalityImage	x )
 	{
 		if ( x == null ){
 			return;
@@ -1101,7 +1306,7 @@ DeviceManagerUI
 	
 	protected static void
 	showIcon(
-		SideBarVitalityImage	x ,
+		MdiEntryVitalityImage	x ,
 		String					t )
 	{
 		if ( x == null ){
@@ -1113,391 +1318,681 @@ DeviceManagerUI
 	}
 	
 	protected void
+	rebuildSideBarIfExists()
+	{
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		
+		if ( mdi != null ){
+		
+			MdiEntry entry = mdi.getEntry( SideBar.SIDEBAR_HEADER_DEVICES );
+		
+			if (entry != null) {
+			
+				rebuildSideBar();
+			}
+		}
+	}
+
+	protected void
 	rebuildSideBar()
 	{
+			
 		if ( sidebar_built ){
+			removeAllDevices();
 			
-			Utils.execSWTThread(
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							removeAllDevices();
-							
-							buildSideBar( true );
-							
-							addAllDevices();
-						}
-					});
+			buildSideBar( true );
+		} else {
+			buildSideBar(false);
 		}
+			
+		addAllDevices();
 	}
 	
-	protected void
-	buildSideBar(
-		boolean			rebuild )	
-	{		
-		final SideBarEntrySWT main_sb_entry = SideBar.getEntry( SideBar.SIDEBAR_SECTION_DEVICES );
-
-		if ( main_sb_entry != null ){
-				
-			MenuManager menu_manager = ui_manager.getMenuManager();
-
-			if ( !rebuild ){
-
-				addDefaultDropListener( main_sb_entry );
+	private String
+	getHeaderToolTip()
+	{
+		if ( side_bar_hide_rend_gen || side_bar_show_tagged ){
+			
+			Device[] devices = device_manager.getDevices();
+			
+			int generic 	= 0;
+			int	untagged	= 0;
+			
+			for ( Device device: devices ){
 				
-				side_bar.createEntryFromSkinRef(null,
-						SideBar.SIDEBAR_SECTION_DEVICES, "devicesview",
-						MessageText.getString("devices.view.title"),
-						null, null, false, -1);
-
-
-				/* and away you go!
-				SideBarVitalityImage addDevice = main_sb_entry.addVitalityImage("image.sidebar.subs.add");
+				if ( device.isHidden()){
+					
+					continue;
+				}
 				
-				addDevice.setToolTip("Add Device");
+				if ( device.getType() != Device.DT_MEDIA_RENDERER ){
+					
+					continue;
+				}
 				
-				addDevice.addListener(
-					new SideBarVitalityImageListener() 
-					{
-						public void 
-						sbVitalityImage_clicked(
-							int x, int y) 
-						{
-							addNewDevice();
-							//new DevicesWizard( DeviceManagerUI.this );
-						}
-					});
-				*/
+				DeviceMediaRenderer rend = (DeviceMediaRenderer)device;
 				
-				if (device_manager.getTranscodeManager().getProviders().length == 0) {
-					SideBarVitalityImage turnon = main_sb_entry.addVitalityImage("image.sidebar.turnon");
-					turnon.addListener(new SideBarVitalityImageListener() {
-						public void sbVitalityImage_clicked(int x, int y) {
-							DevicesFTUX.ensureInstalled();
-						}
-					});
+				if ( rend.isNonSimple()){
+					
+					generic++;
 				}
-				SideBarVitalityImage beta = main_sb_entry.addVitalityImage("image.sidebar.beta");
-				beta.setAlignment(SWT.LEFT);
 				
-				main_sb_entry.setImageLeftID( "image.sidebar.devices" );
+				if ( !rend.isTagged()){
 					
+					untagged++;
+				}
+			}
+			
+			if ( !side_bar_show_tagged ){
 				
-				main_sb_entry.setTitleInfo(
-					new ViewTitleInfo() 
-					{
-						private int last_indicator = 0;
-						
-						SideBarVitalityImage spinner = main_sb_entry.addVitalityImage( SPINNER_IMAGE_ID );
-						SideBarVitalityImage warning = main_sb_entry.addVitalityImage( ALERT_IMAGE_ID );
-						SideBarVitalityImage info	 = main_sb_entry.addVitalityImage( INFO_IMAGE_ID );
+				untagged = 0;
+			}
+			
+			if ( generic > 0 || untagged > 0 ){
+			
+				return( MessageText.getString( "devices.sidebar.mainheader.tooltip", new String[]{ String.valueOf( generic + untagged )} ));
+			}
+		}
+		
+		return( null );
+	}
+	
+	protected MdiEntry buildSideBar(boolean rebuild) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
 
-						{
-							hideIcon( spinner );
-							hideIcon( warning );
-							hideIcon( info );
-						}
-						
+		if (mdi == null) {
+			return null;
+		}
+
+		if (entryHeader == null) {
+			entryHeader = mdi.getEntry(MultipleDocumentInterface.SIDEBAR_HEADER_DEVICES);
+			if (entryHeader != null) {
+				setupHeader(mdi, entryHeader);
+			}
+		}
+
+		mdiEntryOverview = mdi.getEntry(SideBar.SIDEBAR_SECTION_DEVICES);
+
+		if (mdiEntryOverview == null) {
+			mdiEntryOverview = mdi.createEntryFromSkinRef(
+					SideBar.SIDEBAR_HEADER_DEVICES, SideBar.SIDEBAR_SECTION_DEVICES,
+					"devicesview", MessageText.getString("mdi.entry.about.devices"), 
+					new ViewTitleInfo()
+					{
 						public Object 
 						getTitleInfoProperty(
-							int propertyID ) 
+							int propertyID )
 						{
-							boolean expanded = main_sb_entry.getTreeItem().getExpanded();
-														
-							if ( propertyID == TITLE_TEXT ){
-								
-								return MessageText.getString( "devices.view.title" );
-								
-							}else if ( propertyID == TITLE_INDICATOR_TEXT ){
-																
-								spinner.setVisible( !expanded && device_manager.isBusy());
+							if ( propertyID == TITLE_INDICATOR_TEXT_TOOLTIP ){
+							
+								return( getHeaderToolTip());
+							}
+							
+							return( null );
+						}
+					},
+					null, false, "");
+			
+			mdiEntryOverview.setImageLeftID("image.sidebar.aboutdevices");
+		}
+
+		if (rebuild) {
+			for (categoryView category : categories) {
+				category.destroy();
+			}
+		}
+
+		categories.clear();
+
+		if (side_bar_view_type == SBV_FULL) {
+			buildCategories();
+		}
+
+		sidebar_built = true;
+
+		return mdiEntryOverview;
+	}	
+	
+	private void buildCategories() {
+		MenuManager menu_manager = ui_manager.getMenuManager();
+		// renderers
+
+		categoryView renderers_category = addDeviceCategory(
+				Device.DT_MEDIA_RENDERER, "device.renderer.view.title",
+				"image.sidebar.device.renderer");
+
+		categories.add(renderers_category);
+
+		MenuItem re_menu_item = menu_manager.addMenuItem("sidebar."
+				+ renderers_category.getKey(), "device.show");
+
+		re_menu_item.addListener(show_listener);
+		re_menu_item.addFillListener(show_fill_listener);
+
+		re_menu_item = menu_manager.addMenuItem( "sidebar." + renderers_category.getKey(), "sep_re");
+
+		re_menu_item.setStyle( MenuItem.STYLE_SEPARATOR );
+		
+		re_menu_item = menu_manager.addMenuItem(
+				"sidebar." + renderers_category.getKey(),
+				"device.renderer.remove_all");
+
+		re_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				
+				new AEThread2( "doit" )
+				{
+					public void
+					run()
+					{
+						UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+										
+						long res = ui_manager.showMessageBox(
+								"device.mediaserver.remove_all.title",
+								"device.renderer.remove_all.desc",
+								UIManagerEvent.MT_YES | UIManagerEvent.MT_NO );
+						
+						if ( res == UIManagerEvent.MT_YES ){
+							
+							Device[] devices = device_manager.getDevices();
+							
+							for ( Device d: devices ){
 								
-								if ( !expanded ){
-																	
-									Device[] devices = device_manager.getDevices();
+								if ( d.getType() == Device.DT_MEDIA_RENDERER ){
 									
-									last_indicator = 0;
-									
-									String all_errors = "";
-									String all_infos = "";
-									
-									for ( Device device: devices ){
-										
-										String error = device.getError();
+									if ( d.canRemove()){
 										
-										if ( error != null ){
-											
-											all_errors += (all_errors.length()==0?"":"; ") + error;
-										}
-										
-										String info = device.getInfo();
-										
-										if ( info != null ){
-											
-											all_infos += (all_infos.length()==0?"":"; ") + info;
-										}
-										
-										if ( device instanceof DeviceMediaRenderer ){
-									
-											if ( SHOW_RENDERER_VITALITY ){
-												
-												DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
-												
-												last_indicator += renderer.getCopyToDevicePending() + renderer.getCopyToFolderPending();
-											}
-										}else if ( device instanceof DeviceOfflineDownloader ){
-											
-											if ( SHOW_OD_VITALITY ){
-												
-												DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
-												
-												last_indicator += dod.getTransferingCount();
-											}
-										}
+										d.remove();
 									}
-									
-									if ( all_errors.length() > 0 ){
-										 
-										hideIcon( info );
-										
-										showIcon( warning, all_errors );
-										
-									}else{
-										
-										hideIcon( warning );
-										
-										if ( all_infos.length() > 0 ){
-										
-											showIcon( info, all_infos );
-																						
-										}else{
+								}
+							}
+						}
+					}
+				}.start();
+			}
+		});
+		// media servers
+
+		categoryView media_servers_category = addDeviceCategory(
+				Device.DT_CONTENT_DIRECTORY, "device.mediaserver.view.title",
+				"image.sidebar.device.mediaserver");
+
+		categories.add(media_servers_category);
+
+		MenuItem ms_menu_item = menu_manager.addMenuItem("sidebar."
+				+ media_servers_category.getKey(), "device.show");
+
+		ms_menu_item.addListener(show_listener);
+		ms_menu_item.addFillListener(show_fill_listener);
+
+		ms_menu_item = menu_manager.addMenuItem(
+				"sidebar." + media_servers_category.getKey(),
+				"device.mediaserver.configure");
+
+		ms_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+				if (uif != null) {
+
+					uif.openView(UIFunctions.VIEW_CONFIG, "upnpmediaserver.name");
+				}
+			}
+		});
+		
+		ms_menu_item = menu_manager.addMenuItem( "sidebar." + media_servers_category.getKey(), "sep_ms");
+
+		ms_menu_item.setStyle( MenuItem.STYLE_SEPARATOR );
+		
+		ms_menu_item = menu_manager.addMenuItem(
+				"sidebar." + media_servers_category.getKey(),
+				"device.mediaserver.remove_all");
+
+		ms_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				
+				new AEThread2( "doit" )
+				{
+					public void
+					run()
+					{
+						UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
 										
-											hideIcon( info );
-										}
-									}
-									
-									if ( last_indicator > 0 ){
-																						
-										return( String.valueOf( last_indicator ));
-									}
-								}else{
-									
-									hideIcon( warning );
-									hideIcon( info );
+						long res = ui_manager.showMessageBox(
+								"device.mediaserver.remove_all.title",
+								"device.mediaserver.remove_all.desc",
+								UIManagerEvent.MT_YES | UIManagerEvent.MT_NO );
+						
+						if ( res == UIManagerEvent.MT_YES ){
+							
+							Device[] devices = device_manager.getDevices();
+							
+							for ( Device d: devices ){
 								
-								}
-							}else if ( propertyID == TITLE_INDICATOR_COLOR ){
-									
-								/*
-								if ( last_indicator > 0 ){
+								if ( d.getType() == Device.DT_CONTENT_DIRECTORY ){
 									
-									if ( SHOW_VITALITY ){
+									if ( d.canRemove()){
 										
-										return( to_copy_indicator_colors );
+										d.remove();
 									}
 								}
-								*/
 							}
-
-							return null;
 						}
-					});
+					}
+				}.start();
+			}
+		});
 
-					// devices
-				
-				String parentID = "sidebar." + SideBar.SIDEBAR_SECTION_DEVICES;
-							
-				MenuItem de_menu_item = menu_manager.addMenuItem( parentID, "device.search" );
-			
-				de_menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-								search();
-							}
-						});
-				
-					// show hidden
-				
-				de_menu_item = menu_manager.addMenuItem( parentID, "device.show" );
+		// routers
 
-				de_menu_item.addListener( show_listener );
-				de_menu_item.addFillListener( show_fill_listener );
-				
+		categoryView routers_category = addDeviceCategory(
+				Device.DT_INTERNET_GATEWAY, "device.router.view.title",
+				"image.sidebar.device.router");
 
-					// simple
-				
-				de_menu_item = menu_manager.addMenuItem( parentID, "devices.sidebar.simple" );
-				
-				de_menu_item.setStyle( MenuItem.STYLE_CHECK );
-								
-				de_menu_item.addFillListener(
-					new MenuItemFillListener()
-					{
-						public void 
-						menuWillBeShown(
-							MenuItem menu, 
-							Object data) 
-						{
-							menu.setData( COConfigurationManager.getIntParameter( CONFIG_VIEW_TYPE, SBV_SIMPLE ) == SBV_SIMPLE );
-						}
-					});
-				
-				de_menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-								COConfigurationManager.setParameter( CONFIG_VIEW_TYPE, ((Boolean)menu.getData())?SBV_SIMPLE:SBV_FULL );
-							}
-						});
-				
-				de_menu_item = menu_manager.addMenuItem( parentID, "sep" );
+		categories.add(routers_category);
 
-				de_menu_item.setStyle( MenuItem.STYLE_SEPARATOR );
-				
-					// options 
-				
-				de_menu_item = menu_manager.addMenuItem( parentID, "ConfigView.title.short" );
-				
-				de_menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
-						      	 
-						      	 if ( uif != null ){
-						      		 
-						      		 uif.openView( UIFunctions.VIEW_CONFIG, "Devices" );
-						      	 }
-							}
-						});
+		MenuItem rt_menu_item = menu_manager.addMenuItem("sidebar."
+				+ routers_category.getKey(), "device.show");
 
-				if (Constants.isCVSVersion()) {
-					de_menu_item = menu_manager.addMenuItem(parentID,
-							"!(CVS Only)Show FTUX!");
-					
-					de_menu_item.addListener(new MenuItemListener(){
-						public void selected(MenuItem menu, Object target) {
-							DevicesFTUX.showForDebug();
-						}
-					});
+		rt_menu_item.addListener(show_listener);
+		rt_menu_item.addFillListener(show_fill_listener);
 
+		rt_menu_item = menu_manager.addMenuItem(
+				"sidebar." + routers_category.getKey(), "device.router.configure");
+
+		rt_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+				if (uif != null) {
+
+					uif.openView(UIFunctions.VIEW_CONFIG, "UPnP");
 				}
 			}
-			
-			if ( rebuild ){
-				
-				for ( categoryView category: categories ){
-					
-					category.destroy();
-				}
-			}
-			
-			categories.clear();
-			
-			if ( side_bar_view_type == SBV_FULL ){
-				
-					// renderers
-				
-				categoryView renderers_category 		= addDeviceCategory( Device.DT_MEDIA_RENDERER, "device.renderer.view.title", "image.sidebar.device.renderer" );
-				
-				categories.add( renderers_category );
-				
-				MenuItem re_menu_item = menu_manager.addMenuItem( "sidebar." + renderers_category.getKey(), "device.show" );
-	
-				re_menu_item.addListener( show_listener );
-				re_menu_item.addFillListener( show_fill_listener );
-				
-					// media servers
-				
-				categoryView media_servers_category	= addDeviceCategory( Device.DT_CONTENT_DIRECTORY, "device.mediaserver.view.title", "image.sidebar.device.mediaserver" );
+		});
+
+		// 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");
+
+		categories.add(internet_category);
+	}
+
+	private void setupHeader(MultipleDocumentInterface mdi,
+			final MdiEntry entryHeader) {
+		addDefaultDropListener(entryHeader);
+
+		/* and away you go!
+		SideBarVitalityImage addDevice = entryHeader.addVitalityImage("image.sidebar.subs.add");
+		
+		addDevice.setToolTip("Add Device");
+		
+		addDevice.addListener(
+			new SideBarVitalityImageListener() 
+			{
+				public void 
+				sbVitalityImage_clicked(
+					int x, int y) 
+				{
+					addNewDevice();
+					//new DevicesWizard( DeviceManagerUI.this );
+				}
+			});
+		*/
+
+		// Rollup spinner/warning/info
+		entryHeader.setViewTitleInfo(new ViewTitleInfo() {
+			private int last_indicator = 0;
+
+			MdiEntryVitalityImage spinner = entryHeader.addVitalityImage(SPINNER_IMAGE_ID);
+
+			MdiEntryVitalityImage warning = entryHeader.addVitalityImage(ALERT_IMAGE_ID);
+
+			MdiEntryVitalityImage info = entryHeader.addVitalityImage(INFO_IMAGE_ID);
+
+			{
+				hideIcon(spinner);
+				hideIcon(warning);
+				hideIcon(info);
+			}
+
+			public Object getTitleInfoProperty(int propertyID) {
+				boolean expanded = entryHeader.isExpanded();
+
+				if (propertyID == TITLE_INDICATOR_TEXT) {
+
+					spinner.setVisible(!expanded && device_manager.isBusy( Device.DT_UNKNOWN ));
+
+					if (!expanded) {
+
+						Device[] devices = device_manager.getDevices();
+
+						last_indicator = 0;
+
+						String all_errors = "";
+						String all_infos = "";
+
+						for (Device device : devices) {
+
+							String error = device.getError();
+
+							if (error != null) {
+
+								all_errors += (all_errors.length() == 0 ? "" : "; ") + error;
+							}
+
+							String info = device.getInfo();
+
+							if (info != null) {
+
+								all_infos += (all_infos.length() == 0 ? "" : "; ") + info;
+							}
+
+							if (device instanceof DeviceMediaRenderer) {
+
+								if (SHOW_RENDERER_VITALITY) {
+
+									DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
+
+									last_indicator += renderer.getCopyToDevicePending()
+											+ renderer.getCopyToFolderPending();
+								}
+							} else if (device instanceof DeviceOfflineDownloader) {
+
+								if (SHOW_OD_VITALITY) {
+
+									DeviceOfflineDownloader dod = (DeviceOfflineDownloader) device;
+
+									last_indicator += dod.getTransferingCount();
+								}
+							}
+						}
+
+						if (all_errors.length() > 0) {
+
+							hideIcon(info);
+
+							showIcon(warning, all_errors);
+
+						} else {
+
+							hideIcon(warning);
+
+							if (all_infos.length() > 0) {
+
+								showIcon(info, all_infos);
+
+							} else {
+
+								hideIcon(info);
+							}
+						}
+
+						if (last_indicator > 0) {
+
+							return (String.valueOf(last_indicator));
+						}
+					} else {
+
+						hideIcon(warning);
+						hideIcon(info);
+
+					}
+				} else if (propertyID == TITLE_INDICATOR_COLOR) {
+
+					/*
+					if ( last_indicator > 0 ){
+						
+						if ( SHOW_VITALITY ){
+							
+							return( to_copy_indicator_colors );
+						}
+					}
+					*/
+				} else if (propertyID == TITLE_INDICATOR_TEXT_TOOLTIP ) {
 					
-				categories.add( media_servers_category );
-				
-				MenuItem ms_menu_item = menu_manager.addMenuItem( "sidebar." + media_servers_category.getKey(), "device.show" );
-	
-				ms_menu_item.addListener( show_listener );
-				ms_menu_item.addFillListener( show_fill_listener );
-				
-				ms_menu_item = menu_manager.addMenuItem( "sidebar." + media_servers_category.getKey(), "device.mediaserver.configure");
-				
-				ms_menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
-						      	 
-						      	 if ( uif != null ){
-						      		 
-						      		 uif.openView( UIFunctions.VIEW_CONFIG, "upnpmediaserver.name" );
-						      	 }
+					return( getHeaderToolTip());
+				}
+
+				return null;
+			}
+		});
+
+		///////// Turn On
+		device_manager.addListener(new DeviceManagerListener() {
+
+			public void deviceRemoved(Device device) {
+			}
+
+			public void deviceManagerLoaded() {
+				device_manager.removeListener(this);
+				if (entryHeader == null || entryHeader.isDisposed()) {
+					return;
+				}
+	  		PluginManager pm = AzureusCoreFactory.getSingleton().getPluginManager();
+	  		PluginInterface pi;
+	  		pi = pm.getPluginInterfaceByID("vuzexcode");
+				if (device_manager.getTranscodeManager().getProviders().length == 0 || pi == null) {
+					// provider plugin not installed yet
+
+					final MdiEntryVitalityImage turnon = entryHeader.addVitalityImage("image.sidebar.turnon");
+					if (turnon != null) {
+						turnon.addListener(new MdiEntryVitalityImageListener() {
+							public void mdiEntryVitalityImage_clicked(int x, int y) {
+								DevicesFTUX.ensureInstalled(null);
 							}
 						});
-	
-					// routers
-				
-				categoryView routers_category			= addDeviceCategory( Device.DT_INTERNET_GATEWAY, "device.router.view.title", "image.sidebar.device.router" );
-				
-				categories.add( routers_category );
-				
-				MenuItem rt_menu_item = menu_manager.addMenuItem( "sidebar." + routers_category.getKey(), "device.show" );
-	
-				rt_menu_item.addListener( show_listener );
-				rt_menu_item.addFillListener( show_fill_listener );
+
+						device_manager.getTranscodeManager().addListener(
+								new TranscodeManagerListener() {
+									public void providerAdded(TranscodeProvider provider) {
+										// only triggers when vuzexcode is avail
+										turnon.setVisible(false);
+									}
+
+									public void providerUpdated(TranscodeProvider provider) {
+									}
+
+									public void providerRemoved(TranscodeProvider provider) {
+									}
+								});
+					}
+				} else {
+					// provider plugin installed, but we had a bug in older versions,
+					// so fixup
+					DevicesFTUX.alreadyInstalledFixup();
+				}
+			}
+
+			public void deviceChanged(Device device) {
+			}
+
+			public void deviceAttentionRequest(Device device) {
+			}
+
+			public void deviceAdded(Device device) {
+			}
+		});
+
+		//////// Beta
+
+		MdiEntryVitalityImage beta = entryHeader.addVitalityImage("image.sidebar.beta");
+		if (beta != null) {
+			beta.setAlignment(SWT.LEFT);
+		}
+
+		///////// Menu
+
+		MenuManager menu_manager = ui_manager.getMenuManager();
+
+		createOverallMenu(menu_manager, "sidebar." + SideBar.SIDEBAR_HEADER_DEVICES);
+		createOverallMenu(menu_manager, "sidebar." + SideBar.SIDEBAR_SECTION_DEVICES);
+	}
+
+	private void createOverallMenu(MenuManager menu_manager, String parentID) {
+		MenuItem de_menu_item = menu_manager.addMenuItem(parentID, "device.search");
+
+		de_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				search();
+			}
+		});
+
+			// show generic
+
+		de_menu_item = menu_manager.addMenuItem(parentID, "device.showGeneric");
+		de_menu_item.setStyle(MenuItem.STYLE_CHECK);
+		de_menu_item.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
 				
-				rt_menu_item = menu_manager.addMenuItem( "sidebar." + routers_category.getKey(), "device.router.configure" );
+				boolean is_hidden = COConfigurationManager.getBooleanParameter(CONFIG_VIEW_HIDE_REND_GENERIC, true);
 				
-				rt_menu_item.addListener( 
-						new MenuItemListener() 
-						{
-							public void 
-							selected(
-								MenuItem menu, Object target ) 
-							{
-						      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
-						      	 
-						      	 if ( uif != null ){
-						      		 
-						      		 uif.openView( UIFunctions.VIEW_CONFIG, "UPnP" );
-						      	 }
-							}
-						});
+				menu.setData( !is_hidden );
 				
-					// offline downloaders
+				boolean	enabled = false;
 				
-				if ( device_manager.getOfflineDownlaoderManager().isOfflineDownloadingEnabled()){
+				if ( is_hidden ){
 					
-					categoryView od_category	= addDeviceCategory( Device.DT_OFFLINE_DOWNLOADER, "device.offlinedownloader.view.title", "image.sidebar.device.offlinedownloader" );
+					Device[] devices = device_manager.getDevices();
+										
+					for ( Device d: devices ){
+		
+						if ( d.isHidden()){
+							
+							continue;
+						}
+						
+						if ( d instanceof  DeviceMediaRenderer ){
+							
+							DeviceMediaRenderer rend = (DeviceMediaRenderer)d;
+						
+							if ( rend.isNonSimple()){
+								
+								enabled = true;
+							}
+						}
+					}
+				}else{
 					
-					categories.add( od_category );
+					enabled = true;
 				}
 				
-					// internet
+				menu.setEnabled( enabled );
+			}
+		});
+		de_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				COConfigurationManager.setParameter(CONFIG_VIEW_HIDE_REND_GENERIC,
+						!COConfigurationManager.getBooleanParameter(
+								CONFIG_VIEW_HIDE_REND_GENERIC, true));
+			}
+		});
+
+			// show tagged
+
+		de_menu_item = menu_manager.addMenuItem(parentID, "device.onlyShowTagged");
+		de_menu_item.setStyle(MenuItem.STYLE_CHECK);
+		de_menu_item.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setData(COConfigurationManager.getBooleanParameter(
+						CONFIG_VIEW_SHOW_ONLY_TAGGED, false));
+				
+				Device[] devices = device_manager.getDevices();
+				
+				boolean has_tagged = false;
 				
-				categoryView internet_category	= addDeviceCategory( Device.DT_INTERNET, "MainWindow.about.section.internet", "image.sidebar.device.internet" );
+				for ( Device d: devices ){
+					
+					if ( d.isTagged()){
+						
+						has_tagged = true;
+						
+						break;
+					}
+				}
 				
-				categories.add( internet_category );
+				menu.setEnabled( has_tagged );
 			}
-		}
+		});
 		
-		sidebar_built = true;
+		de_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				COConfigurationManager.setParameter(CONFIG_VIEW_SHOW_ONLY_TAGGED,
+						!COConfigurationManager.getBooleanParameter(
+								CONFIG_VIEW_SHOW_ONLY_TAGGED, false));
+			}
+		});
+		
+			// show hidden
+		
+		de_menu_item = menu_manager.addMenuItem(parentID, "device.show");
+
+		de_menu_item.addListener(show_listener);
+		de_menu_item.addFillListener(show_fill_listener);
+
+			// simple
+
+		de_menu_item = menu_manager.addMenuItem(parentID, "devices.sidebar.simple");
+
+		de_menu_item.setStyle(MenuItem.STYLE_CHECK);
+
+		de_menu_item.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setData(COConfigurationManager.getIntParameter(CONFIG_VIEW_TYPE,
+						SBV_SIMPLE) == SBV_SIMPLE);
+			}
+		});
+
+		de_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				COConfigurationManager.setParameter(CONFIG_VIEW_TYPE,
+						((Boolean) menu.getData()) ? SBV_SIMPLE : SBV_FULL);
+			}
+		});
+
+		de_menu_item = menu_manager.addMenuItem(parentID, "sep");
+
+		de_menu_item.setStyle(MenuItem.STYLE_SEPARATOR);
+
+		// options 
+
+		de_menu_item = menu_manager.addMenuItem(parentID, "MainWindow.menu.view.configuration");
+
+		de_menu_item.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+				if (uif != null) {
+
+					uif.openView(UIFunctions.VIEW_CONFIG, "Devices");
+				}
+			}
+		});
+
+		if (Constants.isCVSVersion()) {
+			de_menu_item = menu_manager.addMenuItem(parentID, "!(CVS Only)Show FTUX!");
+
+			de_menu_item.addListener(new MenuItemListener() {
+				public void selected(MenuItem menu, Object target) {
+					DevicesFTUX.showForDebug();
+				}
+			});
+
+		}
 	}
-	
-	
+
 	/**
 	 * 
 	 *
@@ -1622,6 +2117,11 @@ DeviceManagerUI
 						
 						for ( Device device: devices ){
 							
+							if ( device.isHidden()){
+								
+								continue;
+							}
+							
 							if ( device instanceof TranscodeTarget ){
 								
 								devices_added++;
@@ -1643,6 +2143,22 @@ DeviceManagerUI
 									device_item.setEnabled( false );
 									
 								}else{
+
+									Arrays.sort(profiles, new Comparator<TranscodeProfile>() {
+										public int compare(TranscodeProfile o1, TranscodeProfile o2) {
+											int i1 = o1.getIconIndex();
+											int i2 = o2.getIconIndex();
+											
+											if ( i1 == i2 ){
+											
+												return o1.getName().compareToIgnoreCase(o2.getName());
+											}else{
+												
+												return( i1 - i2 );
+											}
+										}
+									});
+
 									
 									for ( final TranscodeProfile profile: profiles ){
 										
@@ -1893,7 +2409,7 @@ DeviceManagerUI
 				return;
 			}
 			
-			parent_key = SideBar.SIDEBAR_SECTION_DEVICES;
+			parent_key = SideBar.SIDEBAR_HEADER_DEVICES;
 		}
 		
 		if ( parent_key == null ){
@@ -1909,12 +2425,17 @@ DeviceManagerUI
 			
 			DeviceMediaRenderer rend = (DeviceMediaRenderer)device;
 			
-			if ( rend.isGeneric()){
+			if ( rend.isNonSimple()){
 				
 				hide_device = true;
 			}
 		}
 		
+		if ( side_bar_show_tagged && !device.isTagged()){
+				
+			hide_device = true;
+		}
+		
 		if ( hide_device ){
 			
 			removeDevice( device );
@@ -1956,597 +2477,766 @@ DeviceManagerUI
 				if ( !device.isHidden()){
 					
 					final deviceItem new_di = new deviceItem();
-					
+
 					device.setTransientProperty( DEVICE_IVIEW_KEY, new_di );
-					
-					Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								synchronized( DeviceManagerUI.this ){
-	
-									if ( new_di.isDestroyed()){
-										
-										return;
-									}
-									
-									deviceView view = new deviceView( parent, device );
-									
-									new_di.setView( view );
-										
-									String key = parent + "/" + device.getID() + ":" + nextSidebarID();
 
-									final SideBarEntrySWT	entry;
-									
-									int	device_type = device.getType();
-									
-									if ( device_type == Device.DT_MEDIA_RENDERER ){
-
-										entry = 
-											side_bar.createEntryFromSkinRef(
-												parent,
-												key, "devicerendererview",
-												device.getName(),
-												view, null, false, -1);
-										
-										String id = null;
-										
-										int	species = ((DeviceMediaRenderer)device).getRendererSpecies();
-										
-										if ( species != DeviceMediaRenderer.RS_OTHER ){
-										
-											id = "image.sidebar.device." + species + ".small";
-											
-										}else{
-											
-											String	classification = device.getClassification();
-											
-											if ( classification.equals( "sony.PSP")){
-												
-												id = "psp";
-												
-											}else if ( classification.startsWith( "tivo.")){
-												
-												id = "tivo";
-												
-											}else{
-												
-												id = String.valueOf( species );
-											}
-											
-											id = "image.sidebar.device." + id + ".small";
-										}
+					setupEntry(new_di, device, parent);
+				}
+			}else{
+				
+				ViewTitleInfoManager.refreshTitleInfo( existing_di.getView());
+				
+				setStatus( device, existing_di );
+			}
+		}
+	}
+	
+	private void setupEntry(deviceItem new_di, final Device device, String parent) {
+		synchronized( DeviceManagerUI.this ){
+			
+			if ( new_di.isDestroyed()){
+				
+				return;
+			}
+			
+			deviceView view = new deviceView( parent, device );
+			
+			new_di.setView( view );
+			
+			String key = parent + "/" + device.getID() + ":" + nextSidebarID();
+
+			final MdiEntry	entry;
+			
+			int	device_type = device.getType();
+			
+			if ( device_type == Device.DT_MEDIA_RENDERER ){
+
+				entry = 
+						mdi.createEntryFromSkinRef(
+								parent,
+								key, "devicerendererview",
+								device.getName(),
+								view, null, false, null);
+				
+			}else if ( device_type == Device.DT_OFFLINE_DOWNLOADER ){
+				
+				entry = 
+						mdi.createEntryFromSkinRef(
+								parent,
+								key, "devicesodview",
+								device.getName(),
+								view, null, false, null);
+				entry.setExpanded(true);
+
+				
+				DeviceOfflineDownloader dod = (DeviceOfflineDownloader)device;
+				
+				String	id;
+				
+				String manufacturer = dod.getManufacturer();
+				
+				if ( manufacturer.toLowerCase().contains( "vuze" )){
+					
+					id = "vuze";
+
+				}else if ( manufacturer.toLowerCase().contains( "belkin" )){
+					
+					id = "bel";
+					
+				}else{
+					
+					id = "other";
+				}
+				
+				entry.setImageLeftID( "image.sidebar.device.od." + id + ".small" );
+
+			}else{
+				
+				entry = mdi.createEntryFromEventListener(parent, view, key, false,
+						device);
+				entry.setExpanded(true);
+
+			}
+			
+			entry.setDatasource( device );
+			
+			entry.setLogID(parent + "-" + device.getName());
+
+			new_di.setMdiEntry( entry );
+
+			setStatus( device, new_di );
+			
+			if ( device instanceof TranscodeTarget ){
+				
+				entry.addListener(
+						new MdiEntryDropListener()
+						{
+							public boolean 
+							mdiEntryDrop(
+									MdiEntry 		entry, 
+									Object 				payload  )
+							{
+								return handleDrop((TranscodeTarget)device, payload );
+							}
+						});
+			}
+			
+			final MenuManager menu_manager = ui_manager.getMenuManager();
+
+			boolean	need_sep = false;
+			
+			if ( device instanceof TranscodeTarget ){
+				
+				need_sep = true;
+				
+				MenuItem explore_menu_item = menu_manager.addMenuItem("sidebar." + key, "v3.menu.device.exploreTranscodes");
+				
+				explore_menu_item.addListener(new MenuItemListener() {
+					public void selected(MenuItem menu, Object target) {
+		 				ManagerUtils.open( ((TranscodeTarget) device).getWorkingDirectory());
+					}
+				});
+			}
+			
+			if ( device instanceof DeviceMediaRenderer ){
+				
+				need_sep = true;
+				// filter view
+				
+				final DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
+				
+				if ( renderer.canFilterFilesView()){
+					MenuItem filterfiles_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.only.show");
+					filterfiles_menu_item.setStyle(MenuItem.STYLE_CHECK);
+					
+					filterfiles_menu_item.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							menu.setData(new Boolean(renderer.getFilterFilesView()));
+						}
+					});
+					filterfiles_menu_item.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+			 				renderer.setFilterFilesView( (Boolean) menu.getData());
+						}
+					});
+				}
+				
+				// show cats
+				
+				if ( renderer.canShowCategories()){
+					MenuItem showcat_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.show.cat");
+					showcat_menu_item.setStyle(MenuItem.STYLE_CHECK);
+					
+					showcat_menu_item.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							menu.setData(new Boolean(renderer.getShowCategories()));
+						}
+					});
+					showcat_menu_item.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+			 				renderer.setShowCategories( (Boolean) menu.getData());
+						}
+					});
+				}
+
+				// cache files
+				
+				MenuItem alwayscache_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.always.cache");
+				alwayscache_menu_item.setStyle(MenuItem.STYLE_CHECK);
+				
+				alwayscache_menu_item.addFillListener(new MenuItemFillListener() {
+					public void menuWillBeShown(MenuItem menu, Object data) {
+						menu.setData(new Boolean(renderer.getAlwaysCacheFiles()));
+					}
+				});
+				alwayscache_menu_item.addListener(new MenuItemListener() {
+					public void selected(MenuItem menu, Object target) {
+		 				renderer.setAlwaysCacheFiles( (Boolean) menu.getData());
+					}
+				});
+				
+			}
+			
+			if ( need_sep ){
+				
+				menu_manager.addMenuItem("sidebar." + key, "1" ).setStyle( MenuItem.STYLE_SEPARATOR );
+			}
+			
+			need_sep = false;
+			
+			if ( device instanceof DeviceMediaRenderer ){
+				
+				final DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
+
+				if ( renderer.canCopyToFolder()){
+					
+					need_sep = true;
+					
+					MenuItem autocopy_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.autoCopy");
+					autocopy_menu_item.setStyle(MenuItem.STYLE_CHECK);
+					
+					autocopy_menu_item.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							menu.setData(new Boolean(renderer.getAutoCopyToFolder()));
+						}
+					});
+					autocopy_menu_item.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+			 				renderer.setAutoCopyToFolder((Boolean) menu.getData());
+						}
+					});
+					
+					final MenuItem mancopy_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.mancopy");
+					mancopy_menu_item.setStyle(MenuItem.STYLE_PUSH);
+					
+					mancopy_menu_item.addListener(new MenuItemListener() {
+						public void 
+						selected(
+								MenuItem menu, Object target) 
+						{
+							try{
+								renderer.manualCopy();
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					});
+					
+					mancopy_menu_item.addFillListener(
+							new MenuItemFillListener()
+							{
+								public void 
+								menuWillBeShown(
+										MenuItem menu, Object data )
+								{
+									boolean	enabled = false;
+									
+									if ( !renderer.getAutoCopyToFolder()){
 										
-										if ( id != null ){
+										File target = renderer.getCopyToFolder();
 										
-											entry.setImageLeftID(id);
+										if ( target != null && target.exists()){
+											
+											enabled = renderer.getCopyToFolderPending() > 0;
 										}
+									}
+									mancopy_menu_item.setEnabled( enabled );
+								}
+							});
+					
+					MenuItem setcopyto_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.setcopyto");
+					setcopyto_menu_item.setStyle(MenuItem.STYLE_PUSH);
+					
+					
+					setcopyto_menu_item.addListener(new MenuItemListener() {
+						public void 
+						selected(
+								MenuItem menu, Object target) 
+						{
+							Shell shell = Utils.findAnyShell();
+							
+							DirectoryDialog dd = new DirectoryDialog( shell );
+							
+							File existing = renderer.getCopyToFolder();
+							
+							if ( existing != null ){
+								
+								dd.setFilterPath( existing.getAbsolutePath());
+							}
+							
+							dd.setText( MessageText.getString( "devices.xcode.setcopyto.title" ));
+							
+							String	path = dd.open();
+							
+							if ( path != null ){
+								
+								renderer.setCopyToFolder( new File( path ));
+							}
+						}
+					});
+
+
+				}
+				
+				if ( renderer.canAutoStartDevice()){
+					
+					need_sep = true;
+					
+					MenuItem autostart_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.autoStart");
+					autostart_menu_item.setStyle(MenuItem.STYLE_CHECK);
+					
+					autostart_menu_item.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							menu.setData(new Boolean(renderer.getAutoStartDevice()));
+						}
+					});
+					autostart_menu_item.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+			 				renderer.setAutoStartDevice((Boolean) menu.getData());
+						}
+					});
+				}
+				
+				if ( renderer.canAssociate()){
+					
+					need_sep = true;
+					
+					final MenuItem menu_associate = menu_manager.addMenuItem(
+							"sidebar." + key, "devices.associate");
+					
+					menu_associate.setStyle(MenuItem.STYLE_MENU);
+
+					menu_associate.addFillListener(
+							new MenuItemFillListener()
+							{
+								public void 
+								menuWillBeShown(
+										MenuItem menu, Object data )
+								{
+									menu_associate.removeAllChildItems();
+									
+									if ( renderer.isAlive()){
 										
-									}else if ( device_type == Device.DT_OFFLINE_DOWNLOADER ){
+										InetAddress a = renderer.getAddress();
 										
-										entry = 
-											side_bar.createEntryFromSkinRef(
-												parent,
-												key, "devicesodview",
-												device.getName(),
-												view, null, false, -1);
+										String address = a==null?"":a.getHostAddress();
 										
-											
-										DeviceOfflineDownloader dod = (DeviceOfflineDownloader)device;
+										MenuItem menu_none = menu_manager.addMenuItem(
+												menu_associate,
+												"!" + MessageText.getString( "devices.associate.already" ) + ": " + address + "!" );
+
+										menu_none.setEnabled( false );
 										
-										String	id;
+										menu_associate.setEnabled( true );
 										
-										String manufacturer = dod.getManufacturer();
+									}else{
 										
-										if ( manufacturer.toLowerCase().contains( "vuze" )){
-											
-											id = "vuze";
+										UnassociatedDevice[] unassoc = device_manager.getUnassociatedDevices();
+										
+										if ( unassoc.length == 0 ){
 
-										}else if ( manufacturer.toLowerCase().contains( "belkin" )){
-											
-											id = "bel";
+											menu_associate.setEnabled( false );
 											
 										}else{
 											
-											id = "other";
+											menu_associate.setEnabled( true );
+											
+											for ( final UnassociatedDevice un: unassoc ){
+												
+												MenuItem menu_un = menu_manager.addMenuItem(
+														menu_associate,
+														"!" + un.getAddress().getHostAddress() + ": " + un.getDescription() + "!");
+													
+													menu_un.addListener(
+															new MenuItemListener() 
+															{
+																public void 
+																selected(
+																		MenuItem 	menu, 
+																		Object 		target)
+																{
+																	renderer.associate( un );
+																}
+															});
+											}
 										}
-										
-										entry.setImageLeftID( "image.sidebar.device.od." + id + ".small" );
-
-									}else{
-										
-										side_bar.createTreeItemFromIView(
-												parent, 
-												view,
-												key, 
-												device, 
-												false, 
-												false,
-												false );
-
-										entry = SideBar.getEntry( key );
 									}
-									
-									entry.setDatasource( device );
-									
-									entry.setLogID(parent + "-" + device.getName());
+								}
+							});
 
-									new_di.setTreeItem( entry.getTreeItem(), entry );
+				}
+				
+				if ( renderer.canRestrictAccess()){
+					
+					need_sep = true;
+					
+					final MenuItem menu_ra = menu_manager.addMenuItem(
+							"sidebar." + key, "devices.restrict_access");
+					
+					menu_ra.addListener(
+						new MenuItemListener() 
+						{
+							public void 
+							selected(
+								MenuItem menu, 
+								Object target) 
+							{
+								if (target instanceof MdiEntry){
+																		
+									UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
 									
-									setStatus( device, new_di );
-																			
-									if ( device instanceof TranscodeTarget ){
-										
-										entry.addListener(
-											new SideBarDropListener()
-											{
-												public boolean 
-												sideBarEntryDrop(
-													SideBarEntry 		entry, 
-													Object 				payload  )
-												{
-													return handleDrop((TranscodeTarget)device, payload );
-												}
-											});
-									}
+									entry.setMessage( "devices.restrict_access.msg" );
 									
-									final MenuManager menu_manager = ui_manager.getMenuManager();
-
-									boolean	need_sep = false;
+									entry.setPreenteredText( renderer.getAccessRestriction(), false );
 									
-									if ( device instanceof TranscodeTarget ){
-										
-										need_sep = true;
-										
-	  									MenuItem explore_menu_item = menu_manager.addMenuItem("sidebar." + key, "v3.menu.device.exploreTranscodes");
-	  									
-	  									explore_menu_item.addListener(new MenuItemListener() {
-	  										public void selected(MenuItem menu, Object target) {
-	  							 				ManagerUtils.open( ((TranscodeTarget) device).getWorkingDirectory());
-	  										}
-	  									});
-									}
+									entry.maintainWhitespace( false );
 									
-									if ( device instanceof DeviceMediaRenderer ){
-										
-										need_sep = true;
-											// filter view
-										
-										final DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
-										
-										if ( renderer.canFilterFilesView()){
-											MenuItem filterfiles_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.only.show");
-											filterfiles_menu_item.setStyle(MenuItem.STYLE_CHECK);
-	
-											filterfiles_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(renderer.getFilterFilesView()));
-												}
-											});
-											filterfiles_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setFilterFilesView( (Boolean) menu.getData());
-												}
-											});
-										}
-										
-											// show cats
-										
-										if ( renderer.canShowCategories()){
-											MenuItem showcat_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.show.cat");
-											showcat_menu_item.setStyle(MenuItem.STYLE_CHECK);
-	
-											showcat_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(renderer.getShowCategories()));
-												}
-											});
-											showcat_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setShowCategories( (Boolean) menu.getData());
-												}
-											});
+									entry.allowEmptyInput( true );
+									
+									entry.setLocalisedTitle(
+										MessageText.getString("devices.restrict_access.prompt",
+											new String[]{
+										device.getName()
+									}));
+			
+									entry.prompt(new UIInputReceiverListener(){
+										public void UIInputReceiverClosed( UIInputReceiver entry ){
+											if (!entry.hasSubmittedInput()) {
+												return;
+											}
+											String input = entry.getSubmittedInput().trim();
+																							
+											renderer.setAccessRestriction( input );
+											
 										}
+									});		
+								}
+							}
+						});
+				}
+				
+				final TranscodeProfile[] transcodeProfiles = renderer.getTranscodeProfiles();
+				
+				if (transcodeProfiles.length > 0) {
+					Arrays.sort(transcodeProfiles, new Comparator<TranscodeProfile>() {
+						public int compare(TranscodeProfile o1, TranscodeProfile o2) {
+							int i1 = o1.getIconIndex();
+							int i2 = o2.getIconIndex();
+							
+							if ( i1 == i2 ){
+								
+								return o1.getName().compareToIgnoreCase(o2.getName());
+							}else{
+								
+								return( i1 - i2 );
+							}
+						}
+					});
 
-											// cache files
-										
-										MenuItem alwayscache_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.always.cache");
-										alwayscache_menu_item.setStyle(MenuItem.STYLE_CHECK);
-	
-										alwayscache_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(renderer.getAlwaysCacheFiles()));
-												}
-											});
-										alwayscache_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setAlwaysCacheFiles( (Boolean) menu.getData());
-												}
-											});
+					need_sep = true;
 					
+					MenuItem menu_default_profile = menu_manager.addMenuItem(
+							"sidebar." + key, "v3.menu.device.defaultprofile");
+					menu_default_profile.setStyle(MenuItem.STYLE_MENU);
+					
+					MenuItem menu_profile_never = menu_manager.addMenuItem( menu_default_profile, "v3.menu.device.defaultprofile.never");
+					
+					menu_profile_never.setStyle(MenuItem.STYLE_CHECK );
+					menu_profile_never.setData(Boolean.TRUE);
+					menu_profile_never.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+							renderer.setTranscodeRequirement(((Boolean)menu.getData())?TranscodeTarget.TRANSCODE_NEVER:TranscodeTarget.TRANSCODE_WHEN_REQUIRED );
+						}});
+
+
+					menu_profile_never.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							boolean never = renderer.getTranscodeRequirement() == TranscodeTarget.TRANSCODE_NEVER;
+							menu.setData( never );
+						}});
+					
+					MenuItem menu_profile_none = menu_manager.addMenuItem(
+							menu_default_profile, "option.askeverytime");
+					menu_profile_none.setStyle(MenuItem.STYLE_RADIO);
+					menu_profile_none.setData(Boolean.FALSE);
+					menu_profile_none.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+							renderer.setDefaultTranscodeProfile(null);
+						}
+					});
+					
+					menu_profile_none.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							if ( transcodeProfiles.length <= 1 ){
+								menu.setData( Boolean.FALSE );
+								menu.setEnabled( false );
+							}else{
+								TranscodeProfile profile = null;
+								try {
+									profile = renderer.getDefaultTranscodeProfile();
+								} catch (TranscodeException e) {
+								}
+								menu.setData((profile == null) ? Boolean.TRUE
+										: Boolean.FALSE);
+								
+								menu.setEnabled( renderer.getTranscodeRequirement() != TranscodeTarget.TRANSCODE_NEVER  );
+							}
+						}
+					});
+					
+					for (final TranscodeProfile profile : transcodeProfiles) {
+						MenuItem menuItem = menu_manager.addMenuItem(
+								menu_default_profile, "!" + profile.getName() + "!");
+							menuItem.setStyle(MenuItem.STYLE_RADIO);
+							menuItem.setData(Boolean.FALSE);
+							menuItem.addListener(new MenuItemListener() {
+								public void selected(MenuItem menu, Object target) {
+									renderer.setDefaultTranscodeProfile(profile);
+								}
+							});
+							
+							menuItem.addFillListener(new MenuItemFillListener() {
+								public void menuWillBeShown(MenuItem menu, Object data) {
+									if ( transcodeProfiles.length <= 1 ){
+										menu.setData( Boolean.TRUE );
+										menu.setEnabled( false );
+									}else{
+										TranscodeProfile dprofile = null;
+										try {
+											dprofile = renderer.getDefaultTranscodeProfile();
+										} catch (TranscodeException e) {
+										}
+										menu.setData((profile.equals(dprofile))
+												? Boolean.TRUE : Boolean.FALSE);
+										
+										menu.setEnabled( renderer.getTranscodeRequirement() != TranscodeTarget.TRANSCODE_NEVER );
 									}
+								}
+							});
+					}
+				}
+				
+				// publish to RSS feed
+				
+				if ( true ){
+					
+					need_sep = true;
+					
+					final MenuItem rss_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.rsspub");
+					rss_menu_item.setStyle(MenuItem.STYLE_CHECK);
+
+					rss_menu_item.addFillListener(new MenuItemFillListener() {
+						public void menuWillBeShown(MenuItem menu, Object data) {
+							rss_menu_item.setEnabled( device_manager.isRSSPublishEnabled());
+							
+							menu.setData(new Boolean(device_manager.isRSSPublishEnabled() && renderer.isRSSPublishEnabled()));
+						}
+					});
+					rss_menu_item.addListener(new MenuItemListener() {
+						public void selected(MenuItem menu, Object target) {
+			 				renderer.setRSSPublishEnabled((Boolean) menu.getData());
+						}
+					});
+					
+					rss_menu_item.setEnabled( device_manager.isRSSPublishEnabled());
+				}
+			}
+
+			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 );
 									
-									if ( need_sep ){
-									
-										menu_manager.addMenuItem("sidebar." + key, "1" ).setStyle( MenuItem.STYLE_SEPARATOR );
-									}
-									
-									need_sep = false;
+								}catch( Throwable e ){
 									
-									if ( device instanceof DeviceMediaRenderer ){
-	
-										final DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
+									Debug.out( e );
+								}
+							}
+						});
+				
+				MenuItem enabled_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.contextmenu.od.enable" );
+				
+				enabled_menu_item.setStyle(MenuItem.STYLE_CHECK);
 
-										if ( renderer.canCopyToFolder()){
-											
-											need_sep = true;
-											
-											MenuItem autocopy_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.autoCopy");
-											autocopy_menu_item.setStyle(MenuItem.STYLE_CHECK);
-											
-											autocopy_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(renderer.getAutoCopyToFolder()));
-												}
-											});
-											autocopy_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setAutoCopyToFolder((Boolean) menu.getData());
-												}
-											});
-													
-											final MenuItem mancopy_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.mancopy");
-											mancopy_menu_item.setStyle(MenuItem.STYLE_PUSH);
-																			
-											mancopy_menu_item.addListener(new MenuItemListener() {
-												public void 
-												selected(
-													MenuItem menu, Object target) 
-												{
-													try{
-														renderer.manualCopy();
-														
-													}catch( Throwable e ){
-														
-														Debug.out( e );
-													}
-												}
-											});
-											
-											mancopy_menu_item.addFillListener(
-												new MenuItemFillListener()
-												{
-													public void 
-													menuWillBeShown(
-														MenuItem menu, Object data )
-													{
-														boolean	enabled = false;
-													
-														if ( !renderer.getAutoCopyToFolder()){
-															
-															File target = renderer.getCopyToFolder();
-															
-															if ( target != null && target.exists()){
-																
-																enabled = renderer.getCopyToFolderPending() > 0;
-															}
-														}
-														mancopy_menu_item.setEnabled( enabled );
-													}
-												});
-											
-											MenuItem setcopyto_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.setcopyto");
-											setcopyto_menu_item.setStyle(MenuItem.STYLE_PUSH);
-										
-											
-											setcopyto_menu_item.addListener(new MenuItemListener() {
-												public void 
-												selected(
-													MenuItem menu, Object target) 
-												{
-													Shell shell = entry.getTreeItem().getDisplay().getActiveShell();
-													
-													DirectoryDialog dd = new DirectoryDialog( shell );
-													
-													File existing = renderer.getCopyToFolder();
-													
-													if ( existing != null ){
-														
-														dd.setFilterPath( existing.getAbsolutePath());
-													}
-													
-													dd.setText( MessageText.getString( "devices.xcode.setcopyto.title" ));
-													
-													String	path = dd.open();
-													
-													if ( path != null ){
-														
-														renderer.setCopyToFolder( new File( path ));
-													}
-												}
-											});
+				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;
+				
+				MenuItem browse_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.browse");
+				
+				browse_menu_item.setStyle( MenuItem.STYLE_MENU );
+				
+				browse_menu_item.addFillListener( will_browse_listener );
+			}
+			
+			
+			if ( need_sep ){
+				
+				menu_manager.addMenuItem("sidebar." + key, "s2" ).setStyle( MenuItem.STYLE_SEPARATOR );
+			}
+			
+				// rename
+			
+			MenuItem rename_menu_item = menu_manager.addMenuItem("sidebar." + key, "MyTorrentsView.menu.rename" );
+			
+			rename_menu_item.addListener( rename_listener );									
+			
+				// export
+			
+			if ( device.isExportable()){
+				
+				MenuItem export_item = menu_manager.addMenuItem("sidebar." + key,"Subscription.menu.export");
+				
+				export_item.addListener( export_listener );
+			}
+			
+				// hide
+			
+			MenuItem hide_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.hide");
+			
+			hide_menu_item.addListener( hide_listener );
+			
+				// tag
+			
+			MenuItem tag_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.tag");
+			
+			tag_menu_item.setStyle( MenuItem.STYLE_CHECK );
+			
+			tag_menu_item.addFillListener( will_tag_listener );
 
+			tag_menu_item.addListener(tag_listener );
 
-										}
-										
-										if ( renderer.canAutoStartDevice()){
-											
-											need_sep = true;
-											
-											MenuItem autostart_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.autoStart");
-											autostart_menu_item.setStyle(MenuItem.STYLE_CHECK);
-	
-											autostart_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(renderer.getAutoStartDevice()));
-												}
-											});
-											autostart_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setAutoStartDevice((Boolean) menu.getData());
-												}
-											});
-										}
-										
-										if ( renderer.canAssociate()){
-											
-											need_sep = true;
-											
-											final MenuItem menu_associate = menu_manager.addMenuItem(
-													"sidebar." + key, "devices.associate");
-											
-											menu_associate.setStyle(MenuItem.STYLE_MENU);
-
-											menu_associate.addFillListener(
-												new MenuItemFillListener()
-												{
-													public void 
-													menuWillBeShown(
-														MenuItem menu, Object data )
-													{
-														menu_associate.removeAllChildItems();
-														
-														if ( renderer.isAlive()){
-															
-															InetAddress a = renderer.getAddress();
-															
-															String address = a==null?"":a.getHostAddress();
-															
-															MenuItem menu_none = menu_manager.addMenuItem(
-																	menu_associate,
-																	"!" + MessageText.getString( "devices.associate.already" ) + ": " + address + "!" );
+				// remove
+			
+			MenuItem remove_menu_item = menu_manager.addMenuItem("sidebar." + key, "MySharesView.menu.remove");
+			
+			remove_menu_item.addFillListener( will_remove_listener );
+				
+			remove_menu_item.addListener( remove_listener );
+
+				// sep
+			
+			menu_manager.addMenuItem("sidebar." + key, "s3" ).setStyle( MenuItem.STYLE_SEPARATOR );
+			
+			final URL wiki_url = device.getWikiURL();
+			
+			if ( wiki_url != null ){
+				
+				MenuItem wiki_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.wiki");
+
+				wiki_menu_item.addListener(
+					new MenuItemListener()
+					{
+						public void 
+						selected(
+							MenuItem 	menu,
+							Object 		target ) 
+						{
+							Utils.launch( wiki_url.toExternalForm());
+						}
+					});
+			}
+			
+			// props
+			
+			MenuItem menu_item = menu_manager.addMenuItem("sidebar." + key,"Subscription.menu.properties");
+			
+			menu_item.addListener( properties_listener );
+		}
+	}
+
+	protected static String
+	getDeviceImageID(
+		Device		device )
+	{
+		String imageID = device.getImageID();
+		if (imageID != null) {
+			return imageID;
+		}
+		
+		if (!(device instanceof DeviceMediaRenderer)) {
+			return "" + DeviceMediaRenderer.RS_OTHER;
+		}
 
-															menu_none.setEnabled( false );
-															
-															menu_associate.setEnabled( true );
-															
-														}else{
-															
-															UnassociatedDevice[] unassoc = device_manager.getUnassociatedDevices();
-															
-															if ( unassoc.length == 0 ){
+		int	species = ((DeviceMediaRenderer)device).getRendererSpecies();
+		
+		String	id;
+		
+		if ( species != DeviceMediaRenderer.RS_OTHER ){
+		
+			id = String.valueOf( species );
+			
+		}else{
+			
+			String	classification = device.getClassification();
+			
+			if ( classification.equals( "sony.PSP")){
+				
+				id = "psp";
+				
+			}else if ( classification.startsWith( "tivo.")){
+				
+				id = "tivo";
+			
+			}else if ( classification.startsWith( "samsung.")){
 
-																menu_associate.setEnabled( false );
-																
-															}else{
-																
-																menu_associate.setEnabled( true );
-																
-																for ( final UnassociatedDevice un: unassoc ){
-																	
-																	MenuItem menu_un = menu_manager.addMenuItem(
-																			menu_associate,
-																			"!" + un.getAddress().getHostAddress() + ": " + un.getDescription() + "!");
-																	
-																	menu_un.addListener(
-																		new MenuItemListener() 
-																		{
-																			public void 
-																			selected(
-																				MenuItem 	menu, 
-																				Object 		target)
-																			{
-																				renderer.associate( un );
-																			}
-																		});
-																}
-															}
-														}
-													}
-												});
+				id = "samsung";
+				
+			}else if ( classification.startsWith( "western.digital.")){
 
-										}
-										
-										TranscodeProfile[] transcodeProfiles = renderer.getTranscodeProfiles();
-										
-										if (transcodeProfiles.length > 0) {
-											
-											need_sep = true;
-											
-											MenuItem menu_default_profile = menu_manager.addMenuItem(
-													"sidebar." + key, "v3.menu.device.defaultprofile");
-											menu_default_profile.setStyle(MenuItem.STYLE_MENU);
-
-											MenuItem menu_profile_none = menu_manager.addMenuItem(
-												menu_default_profile, "option.askeverytime");
-											menu_profile_none.setStyle(MenuItem.STYLE_RADIO);
-											menu_profile_none.setData(Boolean.FALSE);
-											menu_profile_none.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-													renderer.setDefaultTranscodeProfile(null);
-												}
-											});
-											menu_profile_none.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													TranscodeProfile profile = null;
-													try {
-														profile = renderer.getDefaultTranscodeProfile();
-													} catch (TranscodeException e) {
-													}
-													menu.setData((profile == null) ? Boolean.TRUE
-															: Boolean.FALSE);
-												}
-											});
+				id = "wdtv";
+				
+			}else if ( classification.startsWith( "boxee.")){
 
-											for (final TranscodeProfile profile : transcodeProfiles) {
-												MenuItem menuItem = menu_manager.addMenuItem(
-														menu_default_profile, "!" + profile.getName() + "!");
-												menuItem.setStyle(MenuItem.STYLE_RADIO);
-												menuItem.setData(Boolean.FALSE);
-												menuItem.addListener(new MenuItemListener() {
-													public void selected(MenuItem menu, Object target) {
-														renderer.setDefaultTranscodeProfile(profile);
-													}
-												});
-												menuItem.addFillListener(new MenuItemFillListener() {
-													public void menuWillBeShown(MenuItem menu, Object data) {
-														TranscodeProfile dprofile = null;
-														try {
-															dprofile = renderer.getDefaultTranscodeProfile();
-														} catch (TranscodeException e) {
-														}
-														menu.setData((profile.equals(dprofile))
-																? Boolean.TRUE : Boolean.FALSE);
-													}
-												});
-											}
-										}
-										
-										// publish to RSS feed
-										
-										if ( true ){
-											
-											need_sep = true;
-											
-											MenuItem rss_menu_item = menu_manager.addMenuItem("sidebar." + key, "devices.xcode.rsspub");
-											rss_menu_item.setStyle(MenuItem.STYLE_CHECK);
+				id = "boxee";
 
-											rss_menu_item.addFillListener(new MenuItemFillListener() {
-												public void menuWillBeShown(MenuItem menu, Object data) {
-													menu.setData(new Boolean(device_manager.isRSSPublishEnabled() && renderer.isRSSPublishEnabled()));
-												}
-											});
-											rss_menu_item.addListener(new MenuItemListener() {
-												public void selected(MenuItem menu, Object target) {
-									 				renderer.setRSSPublishEnabled((Boolean) menu.getData());
-												}
-											});
-											
-											rss_menu_item.setEnabled( device_manager.isRSSPublishEnabled());
-										}
-									}
+			}else if ( classification.startsWith( "sony.bravia")){
 
-									if ( device instanceof DeviceOfflineDownloader ){
+				id = "bravia";
+				
+			}else if ( classification.startsWith( "ms_wmp.")){
 
-										final DeviceOfflineDownloader	dod = (DeviceOfflineDownloader)device;
-										
-										need_sep = true;
-										
-										MenuItem configure_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.configure");
-											
+				// update skin3_constants.properties!
+			
+			id = "mswmp";
+				
+			}else if ( classification.toLowerCase().contains( "android")){
 
-										configure_menu_item.addFillListener(new MenuItemFillListener() {
-											public void menuWillBeShown(MenuItem menu, Object data) {
-												menu.setEnabled( dod.isAlive());
-											}
-										});
+				id = "android";
 
-										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);
+			}else if ( classification.toLowerCase().contains( "neotv")){
 
-										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;
-										
-										MenuItem browse_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.browse");
-										
-										browse_menu_item.setStyle( MenuItem.STYLE_MENU );
-										
-										browse_menu_item.addFillListener( will_browse_listener );
-									}
-																	
-									
-									if ( need_sep ){
-									
-										menu_manager.addMenuItem("sidebar." + key, "s2" ).setStyle( MenuItem.STYLE_SEPARATOR );
-									}
-									
-									MenuItem rename_menu_item = menu_manager.addMenuItem("sidebar." + key, "MyTorrentsView.menu.rename" );
-																	
-									rename_menu_item.addListener( rename_listener );									
-									
-									MenuItem hide_menu_item = menu_manager.addMenuItem("sidebar." + key, "device.hide");
-									
-									hide_menu_item.addListener( hide_listener );
-	
-									MenuItem remove_menu_item = menu_manager.addMenuItem("sidebar." + key, "MySharesView.menu.remove");
-									
-									remove_menu_item.addFillListener( will_remove_listener );
- 									
-									remove_menu_item.addListener( remove_listener );
+				id = "neotv";
 
-										// sep
-									
-									menu_manager.addMenuItem("sidebar." + key, "s3" ).setStyle( MenuItem.STYLE_SEPARATOR );
-									
-										// props
-									
-									MenuItem menu_item = menu_manager.addMenuItem("sidebar." + key,"Subscription.menu.properties");
-									
-									menu_item.addListener( properties_listener );
-								}
-							}
-						});
-				}
 			}else{
 				
-				Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								ViewTitleInfoManager.refreshTitleInfo( existing_di.getView());
-								
-								setStatus( device, existing_di );
-							}
-						});
+				if (device.isGenericUSB()) {
+					id = "usb";
+
+				} else {
+
+					id = String.valueOf( species );
+				}
 			}
 		}
+		
+		return( id );
 	}
 	
 	protected void
@@ -2559,40 +3249,29 @@ DeviceManagerUI
 
 			if ( existing_di != null ){
 				
-				Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								synchronized( DeviceManagerUI.this ){
-
-									TreeItem ti = existing_di.getTreeItem();
-									
-									if ( ti != null ){
-										
-										TreeItem x = ti;
-										
-										while( x != null ){
-											
-											x.setExpanded( true );
-											
-											x = x.getParentItem();
-										}
-																				
-										ti.getParent().setSelection( ti );
-									}
-								}
-							}
-						});
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				
+				if ( mdi != null ){
+				
+					mdi.showEntry(existing_di.getMdiEntry());
+				}
 			}
 		}
 	}
 	
 	public static boolean
 	handleDrop(
-		TranscodeTarget			target,
-		final Object			payload )
+		final TranscodeTarget		target,
+		final Object				payload )
+	{
+		return( handleDropSupport( target, payload, true ));
+	}
+	
+	private static boolean
+	handleDropSupport(
+		final TranscodeTarget		target,
+		final Object				payload,
+		final boolean				allow_retry )
 	{
 		if (!(payload instanceof String[]) && !(payload instanceof String)) {
 			return false;
@@ -2613,7 +3292,18 @@ DeviceManagerUI
 			}
 		};
 		
-		deviceChooser.show();
+		deviceChooser.show(
+			new Runnable()
+			{
+				public void
+				run()
+				{
+					if ( allow_retry ){
+					
+						handleDropSupport( target, payload, false );
+					}
+				}
+			});
 		return true;
 	}
 
@@ -2683,7 +3373,8 @@ DeviceManagerUI
 				target,
 				profile,
 				file,
-				transcode_requirement);
+				transcode_requirement,
+				false );
 			
 		}catch( Throwable e ){
 			
@@ -2742,7 +3433,8 @@ DeviceManagerUI
 					target,
 					profile,
 					new DiskManagerFileInfoFile( file ),
-					transcode_requirement );
+					transcode_requirement,
+					false );
 				
 			}catch( Throwable e ){
 				
@@ -2784,7 +3476,7 @@ DeviceManagerUI
 			
 			if ( stuff.startsWith( "DownloadManager\n" ) ||stuff.startsWith( "DiskManagerFileInfo\n" )){
 				
-				String[]	bits = stuff.split( "\n" );
+				String[]	bits =  Constants.PAT_SPLIT_SLASH_N.split(stuff);
 				
 				for (int i=1;i<bits.length;i++){
 					
@@ -2822,7 +3514,7 @@ DeviceManagerUI
 				}
 			}else if ( stuff.startsWith( "TranscodeFile\n" )){
 				
-				String[]	bits = stuff.split( "\n" );
+				String[]	bits =  Constants.PAT_SPLIT_SLASH_N.split(stuff);
 				
 				for (int i=1;i<bits.length;i++){
 					
@@ -2848,56 +3540,63 @@ DeviceManagerUI
 	protected void
 	addAllDevices()
 	{
-		device_manager.addListener( device_manager_listener );
+		synchronized( this ){
+		
+			if ( device_manager_listener == null ){
 			
-		Utils.execSWTThread(
-				new Runnable()
+				needsAddAllDevices = true;
+			
+				return;
+			}
+
+			if ( !device_manager_listener_added ){
+		
+				device_manager_listener_added	= true;
+				
+				device_manager.addListener( device_manager_listener );
+			}
+		}
+			
+			Device[] devices = device_manager.getDevices();
+			
+			Arrays.sort(
+				devices,
+				new Comparator<Device>()
 				{
-					public void
-					run()
+					public int 
+					compare(
+						Device o1, 
+						Device o2) 
 					{
-						Device[] devices = device_manager.getDevices();
-						
-						Arrays.sort(
-							devices,
-							new Comparator<Device>()
-							{
-								public int 
-								compare(
-									Device o1, 
-									Device o2) 
-								{
-									return( o1.getName().compareToIgnoreCase( o2.getName()));
-								}
-							});
-						
-						for ( Device device: devices ){
-							
-							addOrChangeDevice( device );
-						}
+						return( o1.getName().compareToIgnoreCase( o2.getName()));
 					}
 				});
+			
+			for ( Device device: devices ){
+				
+				addOrChangeDevice( device );
+			}
 	}
 	
 	protected void
 	removeAllDevices()
 	{
-		device_manager.removeListener( device_manager_listener );
+		synchronized( this ){
+		
+			if ( device_manager_listener_added ){
+			
+				device_manager_listener_added	= false;
 
-		Utils.execSWTThread(
-				new Runnable()
-				{
-					public void
-					run()
-					{
-						Device[] devices = device_manager.getDevices();
-						
-						for ( Device device: devices ){
-							
-							removeDevice( device );
-						}
-					}
-				});
+				device_manager.removeListener( device_manager_listener );
+			}
+		}
+
+		Device[] devices = device_manager.getDevices();
+		
+		for ( Device device: devices ){
+			
+			removeDevice( device );
+		}
 	}
 	
 	protected void
@@ -2925,48 +3624,40 @@ DeviceManagerUI
 	{
 		String key = "Device_" + category_title + ":" + nextSidebarID();
 		
-		categoryView view;
+		categoryView eventListener;
 		
 		if ( device_type == Device.DT_INTERNET ){
 			
-			view = new DeviceInternetView( this, category_title );
+			eventListener = new DeviceInternetView( this, category_title );
 					
 		}else{
 			
-			view = new categoryViewGeneric( this, device_type, category_title );
+			eventListener = new categoryViewGeneric( this, device_type, category_title );
 		}
 		
-		TreeItem item = 
-			side_bar.createTreeItemFromIView(
-				SideBar.SIDEBAR_SECTION_DEVICES, 
-				view,
-				key, 
-				new Integer( device_type ), 
-				false, 
-				false,
-				true );
-
-		SideBarEntrySWT	entry = SideBar.getEntry( key );
+		MdiEntry entry = mdi.createEntryFromEventListener(
+				SideBar.SIDEBAR_HEADER_DEVICES, eventListener, key, false, new Integer(
+						device_type));
 
 		addDefaultDropListener( entry );
 		
 		entry.setImageLeftID( category_image_id );
 				
-		view.setDetails( entry, item, key );
+		eventListener.setDetails( entry, key );
 		
-		return( view );
+		return( eventListener );
 	}
 	
 	protected void
 	addDefaultDropListener(
-		SideBarEntrySWT		entry )
+		MdiEntry		mainSbEntry )
 	{
-		entry.addListener(
-				new SideBarDropListener()
+		mainSbEntry.addListener(
+				new MdiEntryDropListener()
 				{
 					public boolean 
-					sideBarEntryDrop(
-						SideBarEntry 		entry, 
+					mdiEntryDrop(
+						MdiEntry 		entry, 
 						Object 				payload  )
 					{
 						return handleDrop(null, payload);
@@ -2994,21 +3685,21 @@ DeviceManagerUI
 	
 	protected abstract static class
 	categoryView
-		extends 	AbstractIView
-		implements 	ViewTitleInfo
+		implements 	ViewTitleInfo, UISWTViewEventListener
 	{
 		private DeviceManagerUI	ui;
 		private int				device_type;
 		private String			title;
 			
-		private TreeItem		tree_item;
 		private String			key;
 			
-		private SideBarVitalityImage spinner;
-		private SideBarVitalityImage warning;
-		private SideBarVitalityImage info;
+		private MdiEntryVitalityImage spinner;
+		private MdiEntryVitalityImage warning;
+		private MdiEntryVitalityImage info;
 		
 		private int				last_indicator;
+		private MdiEntry mdiEntry;
+		private UISWTView swtView;
 		
 		protected
 		categoryView(
@@ -3023,22 +3714,22 @@ DeviceManagerUI
 		
 		protected void
 		setDetails(
-			SideBarEntrySWT	_entry,
-			TreeItem		_ti,
+			MdiEntry	entry,
 			String			_key )
 		{
-			tree_item 	= _ti;
+			mdiEntry = entry;
+			
 			key			= _key;
 			
-			spinner = _entry.addVitalityImage( SPINNER_IMAGE_ID );
+			spinner = entry.addVitalityImage( SPINNER_IMAGE_ID );
 
 			hideIcon( spinner );
 			
-			warning = _entry.addVitalityImage( ALERT_IMAGE_ID );
+			warning = entry.addVitalityImage( ALERT_IMAGE_ID );
 
 			hideIcon( warning );
 			
-			info = _entry.addVitalityImage( INFO_IMAGE_ID );
+			info = entry.addVitalityImage( INFO_IMAGE_ID );
 
 			hideIcon( info );
 		}
@@ -3066,7 +3757,7 @@ DeviceManagerUI
 		getTitleInfoProperty(
 			int propertyID ) 
 		{
-			boolean expanded = tree_item != null && tree_item.getExpanded();
+			boolean expanded = mdiEntry != null && mdiEntry.isExpanded();
 			
 			if ( propertyID == TITLE_TEXT ){
 				
@@ -3078,7 +3769,7 @@ DeviceManagerUI
 				
 					if ( spinner != null ){
 					
-						spinner.setVisible( !expanded && ui.getDeviceManager().isBusy());
+						spinner.setVisible( !expanded && ui.getDeviceManager().isBusy( device_type ));
 					}
 					
 					if ( !expanded ){
@@ -3092,6 +3783,11 @@ DeviceManagerUI
 						
 						for ( Device device: devices ){
 							
+							if ( device_type != device.getType()){
+									
+								continue;
+							}
+							
 							String error = device.getError();
 							
 							if ( error != null ){
@@ -3174,9 +3870,7 @@ DeviceManagerUI
 		{
 			if ( Utils.isThisThreadSWT()){
 				
-				tree_item.dispose();
-				
-				delete();
+				mdiEntry.close(false);
 				
 			}else{
 				
@@ -3186,13 +3880,23 @@ DeviceManagerUI
 							public void
 							run()
 							{
-								tree_item.dispose();
-								
-								delete();
+								mdiEntry.close(false);
+																
 							}
 						});
 			}
 		}
+
+		public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	      case UISWTViewEvent.TYPE_CREATE:
+	      	swtView = (UISWTView)event.getData();
+	      	swtView.setTitle(title);
+	        break;
+	    }
+
+	    return true;
+	  }
 	}
 	
 	protected static class
@@ -3245,17 +3949,40 @@ DeviceManagerUI
 			return( composite );
 		}
 		
-		public void
-		delete()
-		{
-			super.delete();
-		}
+		public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	      case UISWTViewEvent.TYPE_CREATE:
+	      	//swtView = (UISWTView)event.getData();
+	        break;
+
+	      case UISWTViewEvent.TYPE_DESTROY:
+	        break;
+
+	      case UISWTViewEvent.TYPE_INITIALIZE:
+	        initialize((Composite)event.getData());
+	        break;
+
+	      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+	      	Messages.updateLanguageForControl(getComposite());
+	        break;
+
+	      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+	        break;
+	        
+	      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	break;
+	        
+	      case UISWTViewEvent.TYPE_REFRESH:
+	        break;
+	    }
+
+	    return true;
+	  }
 	}
 	
 	protected static class
 	deviceView
-		extends 	AbstractIView
-		implements 	ViewTitleInfo, TranscodeTargetListener
+		implements 	ViewTitleInfo, TranscodeTargetListener, UISWTViewEventListener
 	{
 		private String			parent_key;
 		private Device			device;
@@ -3264,6 +3991,7 @@ DeviceManagerUI
 		private Composite		composite;
 		
 		private int last_indicator;
+		private UISWTView swtView;
 
 		protected
 		deviceView(
@@ -3327,6 +4055,33 @@ DeviceManagerUI
 				
 				return( getTitle());
 				
+			} else if (propertyID == TITLE_IMAGEID) {
+				String imageID = null;
+				final String id = getDeviceImageID( device );
+				
+				if ( id != null ){
+					
+					imageID = "image.sidebar.device." + id + ".small";
+
+					if (id.startsWith("http")) {
+						if (ImageLoader.getInstance().imageAdded_NoSWT(id)) {
+							imageID = id;
+						} else {
+  						Utils.execSWTThreadLater(0, new AERunnable() {
+  							public void runSupport() {
+  								ImageLoader.getInstance().getUrlImage(id, new ImageDownloaderListener() {
+  									public void imageDownloaded(Image image, boolean returnedImmediately) {
+  										ViewTitleInfoManager.refreshTitleInfo( deviceView.this );
+  									}
+  								});
+  							}
+  						});
+						}
+					}
+				}
+				
+				return imageID;
+				
 			}else if ( propertyID == TITLE_INDICATOR_TEXT ){
 				
 				if ( device instanceof DeviceMediaRenderer ){
@@ -3368,6 +4123,9 @@ DeviceManagerUI
 				
 					return( new Long( device.isAlive()?1:2 ));
 				}
+			}else if ( propertyID == TITLE_INDICATOR_TEXT_TOOLTIP){
+
+				return( device.getStatus());
 			}
 			
 			return null;
@@ -3407,13 +4165,24 @@ DeviceManagerUI
 			
 			while( key != null ){
 			
-				SideBarEntrySWT parent = SideBar.getEntry( key );
-			
-				if ( parent != null ){
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				
+				if ( mdi == null ){
+					
+					break;
+					
+				}else{
+					
+					MdiEntry parent = mdi.getEntry( key );
 				
-					ViewTitleInfoManager.refreshTitleInfo(parent.getTitleInfo());
+					if ( parent != null ){
 					
-					key = parent.getParentID();
+						ViewTitleInfoManager.refreshTitleInfo(parent.getViewTitleInfo());
+						
+						key = parent.getParentID();
+					} else {
+						key = null;
+					}
 				}
 			}
 		}
@@ -3424,11 +4193,9 @@ DeviceManagerUI
 		{	
 		}
 		
-		public void
+		private void
 		delete()
 		{
-			super.delete();
-			
 			if ( device instanceof DeviceMediaRenderer ){
 				
 				DeviceMediaRenderer	renderer = (DeviceMediaRenderer)device;
@@ -3436,19 +4203,52 @@ DeviceManagerUI
 				renderer.removeListener( this );
 			}
 		}
+
+		public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	      case UISWTViewEvent.TYPE_CREATE:
+	      	swtView = (UISWTView)event.getData();
+	      	swtView.setTitle(getTitle());
+	        break;
+
+	      case UISWTViewEvent.TYPE_DESTROY:
+	        delete();
+	        break;
+
+	      case UISWTViewEvent.TYPE_INITIALIZE:
+	        initialize((Composite)event.getData());
+	        break;
+
+	      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+	      	Messages.updateLanguageForControl(getComposite());
+	      	swtView.setTitle(getTitle());
+	        break;
+
+	      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+	        break;
+	        
+	      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	break;
+	        
+	      case UISWTViewEvent.TYPE_REFRESH:
+	        break;
+	    }
+
+	    return true;
+	  }
+
 	}
 	
 	public class
 	deviceItem
 	{		
 		private deviceView			view;
-		private SideBarEntrySWT		sb_entry;
-		private TreeItem			tree_item;
+		private MdiEntry		sb_entry;
 		private boolean				destroyed;
 		
-		private SideBarVitalityImage	warning;
-		private SideBarVitalityImage	spinner;
-		private SideBarVitalityImage	info;
+		private MdiEntryVitalityImage	warning;
+		private MdiEntryVitalityImage	spinner;
+		private MdiEntryVitalityImage	info;
 		
 		protected
 		deviceItem()
@@ -3456,11 +4256,9 @@ DeviceManagerUI
 		}
 		
 		protected void
-		setTreeItem(
-			TreeItem		_tree_item,
-			SideBarEntrySWT	_sb_entry )
+		setMdiEntry(
+			MdiEntry	_sb_entry )
 		{
-			tree_item	= _tree_item;
 			sb_entry	= _sb_entry;
 			
 			warning = sb_entry.addVitalityImage( ALERT_IMAGE_ID );
@@ -3476,14 +4274,8 @@ DeviceManagerUI
 			hideIcon( info );
 		}
 		
-		protected TreeItem
-		getTreeItem()
-		{
-			return( tree_item );
-		}
-		
-		protected SideBarEntrySWT
-		getSideBarEntry()
+		protected MdiEntry
+		getMdiEntry()
 		{
 			return( sb_entry );
 		}
@@ -3560,33 +4352,19 @@ DeviceManagerUI
 		{
 			destroyed = true;
 			
-			Utils.execSWTThread(
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							synchronized( DeviceManagerUI.this ){
-								
-								if ( tree_item != null && !tree_item.isDisposed()){
-									
-									tree_item.dispose();
-								}
-							}
-							
-							view.delete();
-						}
-					});
+			if (sb_entry != null) {
+				sb_entry.close(false);
+			}
 		}
 		
 		public void 
 		activate() 
 		{
-			SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
 			
-			if ( sideBar != null && sb_entry != null ){
+			if ( mdi != null && sb_entry != null ){
 				
-				sideBar.showEntryByID(sb_entry.getId());
+				mdi.showEntryByID(sb_entry.getId());
 			}
 		}
 	}
diff --git a/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java b/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
index 6f811f4..17c595a 100644
--- a/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
+++ b/com/aelitis/azureus/ui/swt/devices/DevicesFTUX.java
@@ -1,423 +1,502 @@
-/**
- * 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.util.*;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.events.*;
-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.internat.MessageText;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.plugins.PluginException;
-import org.gudy.azureus2.plugins.installer.*;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
-import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
-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.CoreWaiterSWT;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
-import com.aelitis.azureus.core.devices.Device;
-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;
-
-/**
- * @author TuxPaper
- * @created Mar 7, 2009
- *
- */
-public class DevicesFTUX
-{
-	private static final String URL_LEARN_MORE = "http://www.vuze.com/devices/qos.start";
-
-	private static final String URL_DEVICES_INFO = "http://www.vuze.com/devices/turnon.start";
-
-	public static DevicesFTUX instance;
-
-	Shell shell;
-
-	private Browser browser;
-
-	private Button checkITunes;
-
-	private Button btnInstall;
-
-	private Button btnCancel;
-
-	private Composite install_area;
-
-	private Button checkQOS;
-
-	private Composite install_area_parent;
-
-	/**
-	 * @return
-	 *
-	 * @since 4.1.0.5
-	 */
-	private boolean isDisposed() {
-		return shell.isDisposed();
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.1.0.5
-	 */
-	private void setFocus() {
-		shell.forceActive();
-		shell.forceFocus();
-	}
-
-	private void open() {
-		// This is a simple dialog box, so instead of using SkinnedDialog, we'll
-		// just built it old school
-		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM);
-		shell.setText(MessageText.getString("devices.turnon.title"));
-
-		Utils.setShellIcon(shell);
-
-		try {
-			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) {
-		}
-
-		Label lblInfo = new Label(shell, SWT.WRAP);
-		Messages.setLanguageText(lblInfo, "devices.turnon.prepageload");
-
-		checkITunes = new Button(shell, SWT.CHECK);
-		checkITunes.setSelection(true);
-		Messages.setLanguageText(checkITunes, "devices.turnon.itunes");
-
-		checkQOS = new Button(shell, SWT.CHECK);
-		checkQOS.setSelection(true);
-		Messages.setLanguageText(checkQOS, "devices.turnon.qos");
-		
-		Link lblLearnMore = new Link(shell, SWT.NONE);
-		lblLearnMore.setText("<A HREF=\"" + URL_LEARN_MORE + "\">"
-				+ MessageText.getString("label.learnmore") + "</A>");
-		lblLearnMore.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				Utils.launch(e.text);
-			}
-		});
-
-		btnInstall = new Button(shell, SWT.NONE);
-		Messages.setLanguageText(btnInstall, "Button.turnon");
-		btnInstall.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				boolean sendQOS = checkQOS.getSelection();
-				doInstall(checkITunes.getSelection(), sendQOS);
-			}
-		});
-
-		shell.setDefaultButton(btnInstall);
-
-		btnCancel = new Button(shell, SWT.NONE);
-		Messages.setLanguageText(btnCancel, "Button.cancel");
-		btnCancel.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				shell.dispose();
-			}
-		});
-
-		shell.addTraverseListener(new TraverseListener() {
-			public void keyTraversed(TraverseEvent e) {
-				if (e.detail == SWT.TRAVERSE_ESCAPE) {
-					shell.dispose();
-				}
-			}
-		});
-
-		install_area_parent = new Composite(shell, SWT.NONE);
-		install_area_parent.setLayout(new FormLayout());
-		install_area_parent.setVisible(false);
-
-		install_area = new Composite(install_area_parent, SWT.NONE);
-
-		FormLayout formLayout = new FormLayout();
-		formLayout.marginWidth = formLayout.marginHeight = 0;
-		shell.setLayout(formLayout);
-		FormData fd;
-
-		fd = Utils.getFilledFormData();
-		fd.bottom = new FormAttachment(checkITunes, -5);
-		fd.top = new FormAttachment(0, 8);
-		fd.left = new FormAttachment(0, 8);
-		fd.right = new FormAttachment(100, -8);
-		lblInfo.setLayoutData(fd);
-
-		fd = Utils.getFilledFormData();
-		fd.bottom = new FormAttachment(checkITunes, -5);
-		fd.width = 550;
-		fd.height = 490;
-		browser.setLayoutData(fd);
-		
-		fd = new FormData();
-		fd.bottom = new FormAttachment(100, -10);
-		fd.right = new FormAttachment(100, -10);
-		btnCancel.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.bottom = new FormAttachment(100, -10);
-		fd.right = new FormAttachment(btnCancel, -12);
-		btnInstall.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.bottom = new FormAttachment(checkQOS, -3);
-		fd.left = new FormAttachment(0, 10);
-		fd.right = new FormAttachment(btnInstall, -12);
-		checkITunes.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.bottom = new FormAttachment(100, -5);
-		fd.left = new FormAttachment(0, 10);
-		checkQOS.setLayoutData(fd);
-		
-		fd = new FormData();
-		fd.top = new FormAttachment(checkQOS, 0, SWT.CENTER);
-		fd.left = new FormAttachment(checkQOS, 5);
-		lblLearnMore.setLayoutData(fd);
-		
-		fd = new FormData();
-		fd.top = new FormAttachment(browser, 0);
-		fd.bottom = new FormAttachment(100, 0);
-		fd.left = new FormAttachment(0, 0);
-		fd.right = new FormAttachment(100, 0);
-		install_area_parent.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.height = btnInstall.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
-		fd.bottom = new FormAttachment(100, -5);
-		fd.left = new FormAttachment(0, 5);
-		fd.right = new FormAttachment(100, -12);
-		install_area.setLayoutData(fd);
-
-		String url = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(
-				URL_DEVICES_INFO, false, true);
-		browser.setUrl(url);
-		
-		shell.pack();
-		Utils.centreWindow(shell);
-		
-		btnInstall.setFocus();
-		shell.open();
-	}
-
-	/**
-	 * @param sendQos 
-	 * @param selection
-	 *
-	 * @since 4.1.0.5
-	 */
-	protected void doInstall(final boolean itunes, final boolean sendQOS) {
-		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
-				_doInstall(core, itunes, sendQOS);
-			}
-		});
-	}
-	
-	protected void _doInstall(AzureusCore core, boolean itunes, boolean sendQOS) {
-		COConfigurationManager.setParameter(PlatformDevicesMessenger.CFG_SEND_QOS,
-				sendQOS);
-
-		if (sendQOS) {
-  		try {
-  			PlatformDevicesMessenger.qosTurnOn(itunes);
-  		} catch (Throwable ignore) {
-  		}
-  		try {
-  			// catch any devices we found before installing additional plugins
-  			DeviceManager device_manager = DeviceManagerFactory.getSingleton();
-  			Device[] devices = device_manager.getDevices();
-  			for (Device device : devices) {
-  	  		try {
-  	  			PlatformDevicesMessenger.qosFoundDevice(device);
-  	  		} catch (Throwable ignore) {
-  	  		}
-				}
-  		} catch (Throwable ignore) {
-  		}
-		}
-		
-		
-		List<InstallablePlugin> plugins = new ArrayList<InstallablePlugin>(2);
-
-		final PluginInstaller installer = core.getPluginManager().getPluginInstaller();
-
-		StandardPlugin vuze_plugin = null;
-
-		try {
-			vuze_plugin = installer.getStandardPlugin("vuzexcode");
-
-		} catch (Throwable e) {
-		}
-
-		if (vuze_plugin != null && !vuze_plugin.isAlreadyInstalled()) {
-			plugins.add(vuze_plugin);
-		}
-
-		if (itunes) {
-			StandardPlugin itunes_plugin = null;
-
-			try {
-				itunes_plugin = installer.getStandardPlugin("azitunes");
-
-			} catch (Throwable e) {
-			}
-
-			if (itunes_plugin != null && !itunes_plugin.isAlreadyInstalled()) {
-				plugins.add(itunes_plugin);
-			}
-		}
-
-		if (plugins.size() == 0) {
-			close();
-			return;
-		}
-		InstallablePlugin[] installablePlugins = plugins.toArray(new InstallablePlugin[0]);
-
-		try {
-			install_area_parent.setVisible(true);
-			install_area_parent.moveAbove(null);
-
-			Map<Integer, Object> properties = new HashMap<Integer, Object>();
-
-			properties.put(UpdateCheckInstance.PT_UI_STYLE,
-					UpdateCheckInstance.PT_UI_STYLE_SIMPLE);
-
-			properties.put(UpdateCheckInstance.PT_UI_PARENT_SWT_COMPOSITE,
-					install_area);
-
-			properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
-
-			installer.install(installablePlugins, false, properties,
-					new PluginInstallationListener() {
-						public void completed() {
-							close();
-
-							SideBarEntrySWT sb = SideBar.getEntry( SideBar.SIDEBAR_SECTION_DEVICES );
-							SideBarVitalityImage[] vitalityImages = sb.getVitalityImages();
-							for (SideBarVitalityImage vi : vitalityImages) {
-								if (vi.getImageID().contains("turnon")) {
-									vi.setVisible(false);
-								}
-							}
-							
-						}
-
-						public void 
-						cancelled(){
-							close();
-						}
-						
-						public void failed(PluginException e) {
-							
-							Debug.out(e);
-							//Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Error",
-							//		e.toString());
-							close();
-						}
-					});
-
-		} catch (Throwable e) {
-
-			Debug.printStackTrace(e);
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.1.0.5
-	 */
-	protected void close() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (shell != null && !shell.isDisposed()) {
-					shell.dispose();
-				}
-			}
-		});
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 4.1.0.5
-	 */
-	public static boolean ensureInstalled() {
-		DeviceManager device_manager = DeviceManagerFactory.getSingleton();
-
-		if (device_manager.getTranscodeManager().getProviders().length == 0) {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					if (instance == null || instance.isDisposed()) {
-						instance = new DevicesFTUX();
-						instance.open();
-					} else {
-						instance.setFocus();
-					}
-				}
-			});
-			return false;
-		}
-		return true;
-	}
-
-	public static void showForDebug() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (instance == null || instance.isDisposed()) {
-					instance = new DevicesFTUX();
-					instance.open();
-				} else {
-					instance.setFocus();
-				}
-			}
-		});
-	}
-
-}
+/**
+ * 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.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.events.*;
+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.internat.MessageText;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.installer.*;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+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.CoreWaiterSWT;
+
+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.DeviceManager;
+import com.aelitis.azureus.core.devices.DeviceManagerFactory;
+import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
+import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
+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;
+
+/**
+ * @author TuxPaper
+ * @created Mar 7, 2009
+ *
+ */
+public class DevicesFTUX
+{
+	private static final String URL_LEARN_MORE = "/devices/qos.start";
+
+	private static final String URL_DEVICES_INFO = "/devices/turnon.start";
+
+	public static DevicesFTUX instance;
+
+	Shell shell;
+
+	private BrowserWrapper browser;
+
+	private Button checkITunes;
+
+	private Button btnInstall;
+
+	private Button btnCancel;
+
+	private Composite install_area;
+
+	private Button checkQOS;
+
+	private Composite install_area_parent;
+
+	private List<Runnable>	to_fire_on_complete = new ArrayList<Runnable>();
+	
+	/**
+	 * @return
+	 *
+	 * @since 4.1.0.5
+	 */
+	private boolean isDisposed() {
+		return shell.isDisposed();
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	private void setFocus( Runnable fire_on_install ) {
+		
+		synchronized( to_fire_on_complete ){
+			
+			to_fire_on_complete.add( fire_on_install );
+		}
+		shell.forceActive();
+		shell.forceFocus();
+	}
+
+	private void open( Runnable fire_on_install) {
+		
+		synchronized( to_fire_on_complete ){
+			
+			to_fire_on_complete.add( fire_on_install );
+		}
+		
+		// This is a simple dialog box, so instead of using SkinnedDialog, we'll
+		// just built it old school
+		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM);
+		shell.setText(MessageText.getString("devices.turnon.title"));
+
+		Utils.setShellIcon(shell);
+
+		try {
+			browser = new BrowserWrapper( 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) {
+		}
+
+		Label lblInfo = new Label(shell, SWT.WRAP);
+		Messages.setLanguageText(lblInfo, "devices.turnon.prepageload");
+
+		checkITunes = new Button(shell, SWT.CHECK);
+		checkITunes.setSelection(true);
+		Messages.setLanguageText(checkITunes, "devices.turnon.itunes");
+
+		PluginInterface itunes_plugin = null;
+		try {
+			itunes_plugin = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+					"azitunes", true);
+
+		} catch (Throwable e) {
+		}
+		if (itunes_plugin != null && itunes_plugin.getPluginState().isOperational()) {
+			checkITunes.setVisible(false);
+		}
+
+		
+		checkQOS = new Button(shell, SWT.CHECK);
+		checkQOS.setSelection(true);
+		Messages.setLanguageText(checkQOS, "devices.turnon.qos");
+		
+		Link lblLearnMore = new Link(shell, SWT.NONE);
+		lblLearnMore.setText("<A HREF=\"" + URL_LEARN_MORE + "\">"
+				+ MessageText.getString("label.learnmore") + "</A>");
+		lblLearnMore.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(e.text, true);
+				Utils.launch(url);
+			}
+		});
+
+		btnInstall = new Button(shell, SWT.NONE);
+		Messages.setLanguageText(btnInstall, "Button.turnon");
+		btnInstall.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				boolean sendQOS = checkQOS.getSelection();
+				doInstall(checkITunes.getSelection(), sendQOS);
+			}
+		});
+
+		shell.setDefaultButton(btnInstall);
+
+		btnCancel = new Button(shell, SWT.NONE);
+		Messages.setLanguageText(btnCancel, "Button.cancel");
+		btnCancel.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				shell.dispose();
+			}
+		});
+
+		shell.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE) {
+					shell.dispose();
+				}
+			}
+		});
+
+		install_area_parent = new Composite(shell, SWT.NONE);
+		install_area_parent.setLayout(new FormLayout());
+		install_area_parent.setVisible(false);
+
+		install_area = new Composite(install_area_parent, SWT.NONE);
+
+		FormLayout formLayout = new FormLayout();
+		formLayout.marginWidth = formLayout.marginHeight = 0;
+		shell.setLayout(formLayout);
+		FormData fd;
+
+		fd = Utils.getFilledFormData();
+		fd.bottom = new FormAttachment(checkITunes, -5);
+		fd.top = new FormAttachment(0, 8);
+		fd.left = new FormAttachment(0, 8);
+		fd.right = new FormAttachment(100, -8);
+		lblInfo.setLayoutData(fd);
+
+		fd = Utils.getFilledFormData();
+		fd.bottom = new FormAttachment(checkITunes, -5);
+		fd.width = 550;
+		fd.height = 490;
+		browser.setLayoutData(fd);
+		
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -10);
+		fd.right = new FormAttachment(100, -10);
+		btnCancel.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -10);
+		fd.right = new FormAttachment(btnCancel, -12);
+		btnInstall.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(checkQOS, -3);
+		fd.left = new FormAttachment(0, 10);
+		fd.right = new FormAttachment(btnInstall, -12);
+		checkITunes.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -5);
+		fd.left = new FormAttachment(0, 10);
+		checkQOS.setLayoutData(fd);
+		
+		fd = new FormData();
+		fd.top = new FormAttachment(checkQOS, 0, SWT.CENTER);
+		fd.left = new FormAttachment(checkQOS, 5);
+		lblLearnMore.setLayoutData(fd);
+		
+		fd = new FormData();
+		fd.top = new FormAttachment(browser.getBrowser(), 0);
+		fd.bottom = new FormAttachment(100, 0);
+		fd.left = new FormAttachment(0, 0);
+		fd.right = new FormAttachment(100, 0);
+		install_area_parent.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.height = btnInstall.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+		fd.bottom = new FormAttachment(100, -5);
+		fd.left = new FormAttachment(0, 5);
+		fd.right = new FormAttachment(100, -12);
+		install_area.setLayoutData(fd);
+
+		String url = ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL(
+				URL_DEVICES_INFO, true);
+		browser.setUrl(url);
+		
+		shell.pack();
+		Utils.centreWindow(shell);
+		
+		btnInstall.setFocus();
+		shell.open();
+	}
+
+	/**
+	 * @param sendQos 
+	 * @param selection
+	 *
+	 * @since 4.1.0.5
+	 */
+	protected void doInstall(final boolean itunes, final boolean sendQOS) {
+		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				_doInstall(core, itunes, sendQOS);
+			}
+		});
+	}
+	
+	protected void _doInstall(AzureusCore core, boolean itunes, boolean sendQOS) {
+		qosTurnOn(sendQOS, itunes, false);
+		
+		
+		List<InstallablePlugin> plugins = new ArrayList<InstallablePlugin>(2);
+
+		final PluginInstaller installer = core.getPluginManager().getPluginInstaller();
+
+		StandardPlugin vuze_plugin = null;
+
+		try {
+			vuze_plugin = installer.getStandardPlugin("vuzexcode");
+
+		} catch (Throwable e) {
+		}
+
+		if (vuze_plugin != null && !vuze_plugin.isAlreadyInstalled()) {
+			plugins.add(vuze_plugin);
+		}
+
+		if (itunes) {
+			StandardPlugin itunes_plugin = null;
+
+			try {
+				itunes_plugin = installer.getStandardPlugin("azitunes");
+
+			} catch (Throwable e) {
+			}
+
+			if (itunes_plugin != null && !itunes_plugin.isAlreadyInstalled()) {
+				plugins.add(itunes_plugin);
+			}
+		}
+
+		if (plugins.size() == 0) {
+			close();
+			return;
+		}
+		InstallablePlugin[] installablePlugins = plugins.toArray(new InstallablePlugin[0]);
+
+		try {
+			install_area_parent.setVisible(true);
+			install_area_parent.moveAbove(null);
+
+			Map<Integer, Object> properties = new HashMap<Integer, Object>();
+
+			properties.put(UpdateCheckInstance.PT_UI_STYLE,
+					UpdateCheckInstance.PT_UI_STYLE_SIMPLE);
+
+			properties.put(UpdateCheckInstance.PT_UI_PARENT_SWT_COMPOSITE,
+					install_area);
+
+			properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
+
+			installer.install(installablePlugins, false, properties,
+					new PluginInstallationListener() {
+						public void completed() {
+							close();
+
+							MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+							MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_HEADER_DEVICES);
+							MdiEntryVitalityImage[] vitalityImages = entry.getVitalityImages();
+							for (MdiEntryVitalityImage vi : vitalityImages) {
+								if (vi.getImageID().contains("turnon")) {
+									vi.setVisible(false);
+								}
+							}
+							
+							List<Runnable> to_fire;
+							
+							synchronized( to_fire_on_complete ){
+								
+								to_fire = new ArrayList<Runnable>( to_fire_on_complete );
+								
+								to_fire_on_complete.clear();
+							}
+							
+							for ( Runnable r: to_fire ){
+								
+								if ( r != null ){
+									
+									try{
+										Utils.execSWTThread( r );
+										
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+									}
+								}
+							}
+						}
+
+						public void 
+						cancelled(){
+							close();
+						}
+						
+						public void failed(PluginException e) {
+							
+							Debug.out(e);
+							//Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Error",
+							//		e.toString());
+							close();
+						}
+					});
+
+		} catch (Throwable e) {
+
+			Debug.printStackTrace(e);
+		}
+	}
+
+	private static void qosTurnOn(boolean on, boolean itunes, boolean isBugFix) {
+		COConfigurationManager.setParameter(PlatformDevicesMessenger.CFG_SEND_QOS,
+				on);
+		
+		if (!on) {
+			return;
+		}
+
+		try {
+			PlatformDevicesMessenger.qosTurnOn(itunes, isBugFix);
+		} catch (Throwable ignore) {
+		}
+		try {
+			// catch any devices we found before installing additional plugins
+			DeviceManager device_manager = DeviceManagerFactory.getSingleton();
+			Device[] devices = device_manager.getDevices();
+			for (Device device : devices) {
+	  		try {
+	  			PlatformDevicesMessenger.qosFoundDevice(device);
+	  		} catch (Throwable ignore) {
+	  		}
+			}
+		} catch (Throwable ignore) {
+		}
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	protected void close() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (shell != null && !shell.isDisposed()) {
+					shell.dispose();
+				}
+			}
+		});
+	}
+
+	/**
+	 * @return
+	 *
+	 * @since 4.1.0.5
+	 */
+	public static boolean ensureInstalled( final Runnable fire_on_install ) {
+		DeviceManager device_manager = DeviceManagerFactory.getSingleton();
+
+		if (device_manager.getTranscodeManager().getProviders().length == 0) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (instance == null || instance.isDisposed()) {
+						instance = new DevicesFTUX();
+						instance.open( fire_on_install );
+					} else {
+						instance.setFocus( fire_on_install );
+					}
+				}
+			});
+			return false;
+		}
+		return true;
+	}
+
+	public static void showForDebug() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (instance == null || instance.isDisposed()) {
+					instance = new DevicesFTUX();
+					instance.open( null );
+				} else {
+					instance.setFocus( null );
+				}
+			}
+		});
+	}
+
+	public static void alreadyInstalledFixup() {
+		if (!COConfigurationManager.hasParameter(
+				PlatformDevicesMessenger.CFG_SEND_QOS, true)) {
+			// fixup bug where item was turned on via non-dialog way
+			// dialog always set the parameter
+			PluginInterface itunes_plugin = null;
+			try {
+				itunes_plugin = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+						"azitunes", true);
+
+			} catch (Throwable e) {
+			}
+			boolean hasItunes = (itunes_plugin != null && itunes_plugin.getPluginState().isOperational());
+			qosTurnOn(true, hasItunes, true);
+			return;
+		}
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java b/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java
index 9b7b9e9..d398f84 100644
--- a/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java
+++ b/com/aelitis/azureus/ui/swt/devices/DevicesODFTUX.java
@@ -43,6 +43,7 @@ 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;
+import com.aelitis.azureus.util.ConstantsVuze;
 
 /**
  * @author TuxPaper
@@ -52,7 +53,7 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 public class 
 DevicesODFTUX
 {
-	private static final String URL_LEARN_MORE = "http://www.vuze.com/devices/offlinedownloader.start";
+	private static final String URL_LEARN_MORE = "/devices/offlinedownloader.start";
 
 	private DeviceOfflineDownloader		device;
 	
@@ -291,7 +292,9 @@ DevicesODFTUX
 			
 			Debug.out( e );
 		}
-		
+
+		url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(url, true);
+
 		LinkLabel.makeLinkedLabel( link, url );
 		
 		
diff --git a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java
index 7ea9dd0..4a7f67b 100644
--- a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java
+++ b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesODView.java
@@ -19,63 +19,63 @@
 package com.aelitis.azureus.ui.swt.devices;
 
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
 
 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.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 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.plugins.ui.toolbar.UIToolBarItem;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.ui.swt.*;
-
-import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 
 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.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.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.columns.torrent.ColumnThumbnail;
 import com.aelitis.azureus.ui.swt.devices.columns.*;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 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
+	implements UIUpdatable, UIPluginViewToolBarListener
 {
-	public static final String TABLE_RCM = "DevicesOD";
+	public static final String TABLE_ID = "DevicesOD";
 
 	private static boolean columnsAdded = false;
 	
 	private DeviceOfflineDownloader		device;
 	
-	private TableViewSWTImpl<DeviceOfflineDownload> tv_downloads;
+	private TableViewSWT<DeviceOfflineDownload> tv_downloads;
 
-	private SideBarEntrySWT 	sidebar_entry;
+	private MdiEntrySWT 	mdi_entry;
 	private Composite			control_parent;
 	
 
@@ -94,15 +94,15 @@ SBC_DevicesODView
 				}
 			});
 
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
 		
-		if ( sidebar != null ){
+		if ( mdi != null ){
 			
-			sidebar_entry = sidebar.getCurrentEntry();
+			mdi_entry = mdi.getCurrentEntrySWT();
 			
-			sidebar_entry.setIconBarEnabler( this );
+			mdi_entry.addToolbarEnabler( this );
 			
-			device = (DeviceOfflineDownloader)sidebar_entry.getDatasource();
+			device = (DeviceOfflineDownloader)mdi_entry.getDatasource();
 		}
 		
 		return null;
@@ -167,7 +167,20 @@ SBC_DevicesODView
 						new ColumnOD_Remaining(column);
 					}
 				});
-	}
+
+		TableColumnManager tcm = TableColumnManager.getInstance();
+		TableColumnCore[] allTCs = tcm.getAllTableColumnCoreAsArray(
+				DeviceOfflineDownload.class, TABLE_ID);
+		// for now, all columns are default
+		ArrayList<String> names = new ArrayList<String>();
+		for (int i = 0; i < allTCs.length; i++) {
+			TableColumn tc = allTCs[i];
+			if (tc.isVisible()) {
+				names.add(tc.getName());
+			}
+		}
+		tcm.setDefaultColumnNames(TABLE_ID, names.toArray(new String[0]));
+}
 
 	public Object 
 	skinObjectShown(
@@ -249,11 +262,10 @@ SBC_DevicesODView
 		layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
 		enabled_device_parent.setLayout(layout);
 			
-		tv_downloads = 
-			new TableViewSWTImpl<DeviceOfflineDownload>(
+		tv_downloads = TableViewFactory.createTableViewSWT(
 					DeviceOfflineDownload.class, 
-					TABLE_RCM,
-					TABLE_RCM, 
+					TABLE_ID,
+					TABLE_ID, 
 					new TableColumnCore[0], 
 					ColumnOD_Name.COLUMN_ID, 
 					SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL );
@@ -318,7 +330,7 @@ SBC_DevicesODView
 		tv_downloads.addLifeCycleListener(
 			new TableLifeCycleListener() 
 			{
-				private final TableViewSWTImpl<DeviceOfflineDownload>	f_table = tv_downloads;
+				private final TableViewSWT<DeviceOfflineDownload>	f_table = tv_downloads;
 				
 				private Set<DeviceOfflineDownload>	download_set = new HashSet<DeviceOfflineDownload>();
 				
@@ -577,25 +589,44 @@ SBC_DevicesODView
 		
 		control.layout(true);
 	}	
-	
-	public boolean 
-	isEnabled(
-		String key )
-	{
-		return( false );
-	}
-	
-	public boolean 
-	isSelected(
-		String key )
-	{
-		return( false );
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		long stateRemove = 0;
+		if (tv_downloads != null && tv_downloads.getSelectedRowsSize() > 0) {
+			stateRemove = UIToolBarItem.STATE_ENABLED;
+		}
+		list.put("remove", stateRemove);
 	}
 	
-	public void 
-	itemActivated(
-		String key )
-	{
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if (item.getID().equals("remove")) {
+			MessageBoxShell mb = 
+				new MessageBoxShell(
+					MessageText.getString("message.confirm.delete.title"),
+					MessageText.getString("message.confirm.delete.text",
+							new String[] {
+								device.getName()
+							}), 
+					new String[] {
+						MessageText.getString("Button.yes"),
+						MessageText.getString("Button.no")
+					},
+					1 );
+			
+			mb.open(new UserPrompterResultListener() {
+				public void prompterClosed(int result) {
+					if (result == 0) {
+						device.remove();
+					}
+				}
+			});
+			return true;
+		}
+		return false;
 	}
 	
 	public String 
diff --git a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
index eec2c61..ef1d5b0 100644
--- a/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
+++ b/com/aelitis/azureus/ui/swt/devices/SBC_DevicesView.java
@@ -25,10 +25,7 @@ import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
-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.events.*;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
@@ -39,15 +36,19 @@ 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.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 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.plugins.ui.toolbar.UIToolBarItem;
 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.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+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.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
@@ -58,20 +59,22 @@ 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.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 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;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.skin.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
 import com.aelitis.azureus.ui.swt.views.skin.InfoBarUtil;
 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;
+import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
+import com.aelitis.azureus.util.PlayUtils;
 
 /**
  * @author TuxPaper
@@ -80,8 +83,8 @@ import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
  */
 public class SBC_DevicesView
 	extends SkinView
-	implements TranscodeQueueListener, IconBarEnabler, UIUpdatable,
-	TranscodeTargetListener
+	implements TranscodeQueueListener, UIUpdatable,
+	TranscodeTargetListener, DeviceListener, UIPluginViewToolBarListener
 {
 	public static final String TABLE_DEVICES = "Devices";
 
@@ -97,20 +100,21 @@ public class SBC_DevicesView
 
 	private TranscodeQueue transcode_queue;
 
-	private TableViewSWTImpl 	tvDevices;
+	private TableViewSWT<?> 	tvDevices;
 	private DragSource 			dragSource;
 	private DropTarget 			dropTarget;
 	private int					drag_drop_line_start = -1;
 	private TableRowCore[]		drag_drop_rows;
 
 	
-	private TableViewSWTImpl<TranscodeFile> tvFiles;
+	private TableViewSWT<TranscodeFile> tvFiles;
 
-	private SideBarEntrySWT sidebarEntry;
+	private MdiEntrySWT mdiEntry;
 
 	private Composite tableJobsParent;
 
-	private Device device;
+	private Device 	device;
+	private String	device_name;
 
 	private TranscodeTarget transTarget;
 
@@ -128,11 +132,10 @@ public class SBC_DevicesView
 
 		transcode_queue = transcode_manager.getQueue();
 
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			sidebarEntry = sidebar.getCurrentEntry();
-			sidebarEntry.setIconBarEnabler(this);
-			device = (Device) sidebarEntry.getDatasource();
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			mdiEntry = mdi.getCurrentEntrySWT();
+			device = (Device) mdiEntry.getDatasource();
 		}
 
 		if (device instanceof TranscodeTarget) {
@@ -167,6 +170,8 @@ public class SBC_DevicesView
 						speciesID = "psp";
 					}else if ( classification.startsWith( "tivo.")){
 						speciesID = "tivo";
+					}else if ( classification.toLowerCase().contains( "android")){
+						speciesID = "android";
 					}
 				}
 				default:
@@ -203,11 +208,13 @@ public class SBC_DevicesView
 		}
 
 		if (device != null) {
+			device_name = device.getName();
+			
 			SWTSkinObject soTitle = getSkinObject("title");
 			if (soTitle instanceof SWTSkinObjectText) {
 				((SWTSkinObjectText) soTitle).setTextID("device.view.heading",
 						new String[] {
-							device.getName()
+							device_name
 						});
 			}
 		}
@@ -241,6 +248,7 @@ public class SBC_DevicesView
 					public void tableColumnCreated(TableColumn column) {
 						new ColumnThumbnail(column);
 						column.setWidth(70);
+						column.setVisible(false);
 					}
 				});
 		tableManager.registerColumn(TranscodeFile.class, ColumnTJ_Name.COLUMN_ID,
@@ -320,6 +328,26 @@ public class SBC_DevicesView
 						new ColumnTJ_Category(column);
 					}
 				});
+		
+		TableColumnManager tcm = TableColumnManager.getInstance();
+		String[] defaultLibraryColumns = {
+			ColumnTJ_Rank.COLUMN_ID,
+			ColumnTJ_Name.COLUMN_ID,
+			ColumnTJ_Duration.COLUMN_ID,
+			ColumnTJ_Device.COLUMN_ID,
+			ColumnTJ_Status.COLUMN_ID,
+			ColumnTJ_Completion.COLUMN_ID,
+		};
+		tcm.setDefaultColumnNames(TABLE_TRANSCODE_QUEUE, defaultLibraryColumns);
+		
+		String[] defaultQColumns = {
+			ColumnTJ_Name.COLUMN_ID,
+			ColumnTJ_Duration.COLUMN_ID,
+			ColumnTJ_Profile.COLUMN_ID,
+			ColumnTJ_Status.COLUMN_ID,
+			ColumnTJ_Completion.COLUMN_ID,
+		};
+		tcm.setDefaultColumnNames(TABLE_DEVICE_LIBRARY, defaultQColumns);
 	}
 
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectShown(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
@@ -342,6 +370,11 @@ public class SBC_DevicesView
 			initTranscodeQueueTable((Composite) soTranscodeQueue.getControl());
 		}
 
+		if ( device != null ){
+
+			device.addListener( this );
+		}
+		
 		if (device instanceof TranscodeTarget){
 		
 			createDragDrop( tvFiles!=null?tvFiles:tvDevices);
@@ -412,6 +445,11 @@ public class SBC_DevicesView
 			transTarget.removeListener(this);
 		}
 
+		if ( device != null ){
+			
+			device.removeListener( this );
+		}
+		
 		synchronized (this) {
 			if (tvFiles != null) {
 				tvFiles.delete();
@@ -458,11 +496,11 @@ public class SBC_DevicesView
 			}
 		}
 
-		tvFiles = new TableViewSWTImpl<TranscodeFile>(TranscodeFile.class, tableID,
+		tvFiles = TableViewFactory.createTableViewSWT(TranscodeFile.class, tableID,
 				tableID, new TableColumnCore[0], device == null
 						? ColumnTJ_Rank.COLUMN_ID : ColumnTJ_Status.COLUMN_ID, SWT.MULTI
 						| SWT.FULL_SELECTION | SWT.VIRTUAL);
-		tvFiles.setRowDefaultHeight(50);
+		tvFiles.setRowDefaultHeight(25);
 		tvFiles.setHeaderVisible(true);
 		tvFiles.setParentDataSource(device);
 
@@ -562,12 +600,15 @@ public class SBC_DevicesView
 								
 							}else{
 							
-								List<TranscodeFile> selectedDataSources = tvFiles.getSelectedDataSources();
+								List<Object> selectedDataSources = tvFiles.getSelectedDataSources();
 								selected = selectedDataSources.toArray(new TranscodeFile[0]);
 							}
 						}
 						
-						deleteFiles(selected, 0);
+						if ( selected.length > 0 ){
+						
+							deleteFiles(selected, 0);
+						}
 						
 						e.doit = false;
 					}
@@ -582,7 +623,7 @@ public class SBC_DevicesView
 		
 		tvFiles.initialize(tableJobsParent);
 
-		control.layout(true);
+		control.layout(true, true);
 	}
 
 	/**
@@ -612,7 +653,7 @@ public class SBC_DevicesView
 		try {
 			if (files.length == 1) {
 
-				target_file = files[0].getTargetFile().getFile();
+				target_file = files[0].getTargetFile().getFile( true );
 
 				if (!target_file.exists()) {
 
@@ -627,7 +668,7 @@ public class SBC_DevicesView
 		try {
 			if (files.length == 1) {
 
-				source_file = files[0].getSourceFile().getFile();
+				source_file = files[0].getSourceFile().getFile( true );
 
 				if (!source_file.exists()) {
 
@@ -796,9 +837,30 @@ public class SBC_DevicesView
 
 		// remove
 
+		int	comp 	= 0;
+		int	incomp	= 0;
+		
+		for ( TranscodeFile f: files ){
+			
+			if ( f.isComplete()){
+				comp++;
+			}else{
+				incomp++;
+			}
+		}
 		final MenuItem remove_item = new MenuItem(menu, SWT.PUSH);
 
-		remove_item.setText(MessageText.getString("azbuddy.ui.menu.remove"));
+		String	text;
+		
+		if ( comp == 0 ){
+			text = "devices.cancel_xcode"; 
+		}else if ( incomp == 0 ){
+			text = "azbuddy.ui.menu.remove";
+		}else{
+			text = "devices.cancel_xcode_del";
+		}
+		
+		remove_item.setText(MessageText.getString(text));
 
 		Utils.setMenuItemImage(remove_item, "delete");
 
@@ -940,7 +1002,26 @@ public class SBC_DevicesView
 		}
 	}
 
-
+	public void
+	deviceChanged(
+		Device		device )
+	{
+		String name = device.getName();
+		
+		if ( !name.equals( device_name )){
+			
+			device_name = name;
+			
+			// ensure name is up to date
+			SWTSkinObject soTitle = getSkinObject("title");
+			if (soTitle instanceof SWTSkinObjectText) {
+				((SWTSkinObjectText) soTitle).setTextID("device.view.heading",
+						new String[] {
+							name
+						});
+			}
+		}
+	}
 	
 	
 	/**
@@ -950,9 +1031,10 @@ public class SBC_DevicesView
 	 * @since 4.1.0.5
 	 */
 	private void initDeviceListTable(Composite control) {
-		tvDevices = new TableViewSWTImpl(TranscodeProvider.class, TABLE_DEVICES,
-				TABLE_DEVICES, new TableColumnCore[0], ColumnTJ_Rank.COLUMN_ID);
-		tvDevices.setRowDefaultHeight(50);
+		tvDevices = TableViewFactory.createTableViewSWT(TranscodeProvider.class, TABLE_DEVICES,
+				TABLE_DEVICES, new TableColumnCore[0], ColumnTJ_Rank.COLUMN_ID, SWT.SINGLE
+				| SWT.FULL_SELECTION);
+		tvDevices.setRowDefaultHeight(25);
 		tvDevices.setHeaderVisible(true);
 
 		Composite parent = new Composite(control, SWT.NONE);
@@ -986,7 +1068,7 @@ public class SBC_DevicesView
 			if (tvFiles == null) {
 				return;
 			}
-			TableRowCore row = tvFiles.getRow(job.getTranscodeFile());
+			TableRowCore row = tvFiles.getRow( getFileInTable( job.getTranscodeFile()));
 			if (row != null) {
 				row.invalidate();
 				if (row.isVisible()) {
@@ -1008,10 +1090,10 @@ public class SBC_DevicesView
 			if (transTarget == null) {
 				TranscodeFile file = job.getTranscodeFile();
 				if (file != null) {
-					tvFiles.removeDataSource(file);
+					tvFiles.removeDataSource( getFileInTable( file ));
 				}
 			} else {
-				TableRowCore row = tvFiles.getRow(job.getTranscodeFile());
+				TableRowCore row = tvFiles.getRow( getFileInTable( job.getTranscodeFile()));
 				if (row != null) {
 					row.invalidate();
 					if (row.isVisible()) {
@@ -1025,26 +1107,53 @@ public class SBC_DevicesView
 		}
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isEnabled(java.lang.String)
-	public boolean isEnabled(String itemKey) {
+	private TranscodeFile
+	getFileInTable(
+		TranscodeFile		file )
+	{
+		// since table-views were moved to using identity hash maps to manage rows (which is good!) this has broken
+		// removal of files as due to the caching optimisations employed by the device manager muliple file-facades
+		// can be created to denote an actual TranscodeFile :(
+	
+		if ( file == null ){
+			
+			return( null );
+		}
+		
+		if ( tvFiles.getRow( file ) == null ){
+			
+			List<TranscodeFile>	files = tvFiles.getDataSources();
+			
+			for ( TranscodeFile f: files ){
+				
+				if ( f.equals( file )){
+					
+					return( f );
+				}
+			}
+		}
+		
+		return( file );
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
 		Object[] selectedDS;
 		int size;
 		synchronized (this) {
 			if (tvFiles == null) {
-				return false;
+				return;
 			}
 			selectedDS = tvFiles.getSelectedDataSources().toArray();
 			size = tvFiles.size(false);
 		}
 		if (selectedDS.length == 0) {
-
-			return (false);
+			return;
 		}
 
-		if (itemKey.equals("remove")) {
-
-			return (true);
-		}
+		list.put("remove", UIToolBarItem.STATE_ENABLED);
 
 		boolean can_stop = true;
 		boolean can_queue = true;
@@ -1093,88 +1202,143 @@ public class SBC_DevicesView
 			can_stop = can_queue = can_move_down = can_move_up = false;
 		}
 
-		if (itemKey.equals("stop")) {
-
-			return (can_stop);
-		}
-
-		if (itemKey.equals("start")) {
-
-			return (can_queue);
-		}
-
-		if (itemKey.equals("up")) {
-
-			return (can_move_up);
+		if ( can_queue && can_stop ){
+			can_stop = false;
 		}
-
-		if (itemKey.equals("down")) {
-
-			return (can_move_down);
+		
+		list.put("stop", can_stop ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("start", can_queue ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("up", can_move_up ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("down", can_move_down ? UIToolBarItem.STATE_ENABLED : 0);
+		
+		if ( selectedDS.length == 1 ){
+			
+			TranscodeFile f = (TranscodeFile)selectedDS[0];
+			
+			if ( f.isComplete() && f.getStreamURL() != null ){
+				
+				try{
+					if( PlayUtils.canUseEMP( f.getTargetFile())){
+				
+						list.put( "play", UIToolBarItem.STATE_ENABLED );
+					}
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
 		}
-
-		return (false);
-	}
-
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isSelected(java.lang.String)
-	public boolean isSelected(String itemKey) {
-		return false;
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#itemActivated(java.lang.String)
-	public void itemActivated(final String itemKey) {
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
 		// assumed to be on SWT thread, so it's safe to use tvFiles without a sync
 		if (tvFiles == null) {
-			return;
+			return false;
 		}
 
 		TranscodeFile[] selectedDS = tvFiles.getSelectedDataSources().toArray(new TranscodeFile[0]);
 		if (selectedDS.length == 0) {
-			return;
+			return false;
 		}
+		
+		String itemKey = item.getID();
 
 		if (itemKey.equals("remove")) {
 			deleteFiles(selectedDS, 0);
-			return;
+			return true;
 		}
 
+		if ( itemKey.equals( "play" )){
+			
+			if ( selectedDS.length == 1 ){
+				
+				TranscodeFile f = selectedDS[0];
+			
+				if ( TorrentListViewsUtils.openInEMP( f.getName(), f.getStreamURL()) == 0 ){
+				
+					return( true );
+				}
+			}
+		}
+		
 		java.util.List<TranscodeJob> jobs = new ArrayList<TranscodeJob>(
 				selectedDS.length);
 
+		boolean can_stop = true;
+		boolean can_queue = true;
+
 		for (int i = 0; i < selectedDS.length; i++) {
-			TranscodeFile file = (TranscodeFile) selectedDS[i];
+			TranscodeFile file = selectedDS[i];
 			TranscodeJob job = file.getJob();
 			if (job != null) {
 				jobs.add(job);
+				
+				int state = job.getState();
+
+				if (state != TranscodeJob.ST_PAUSED && state != TranscodeJob.ST_RUNNING
+						&& state != TranscodeJob.ST_FAILED && state != TranscodeJob.ST_QUEUED) {
+
+					can_stop = false;
+				}
+
+				if (state != TranscodeJob.ST_PAUSED && state != TranscodeJob.ST_STOPPED
+						&& state != TranscodeJob.ST_FAILED) {
+
+					can_queue = false;
+				}
 			}
 		}
+		
 		if (jobs.size() == 0) {
-			return;
+			return false;
 		}
 
+		if ( can_queue && can_stop ){
+			can_stop = false;
+		}
+		
 		if (itemKey.equals("up") || itemKey.equals("down")) {
 
+			final String f_itemKey = itemKey;
+			
 			Collections.sort(jobs, new Comparator<TranscodeJob>() {
 				public int compare(TranscodeJob j1, TranscodeJob j2) {
 
-					return ((itemKey.equals("up") ? 1 : -1) * (j1.getIndex() - j2.getIndex()));
+					return ((f_itemKey.equals("up") ? 1 : -1) * (j1.getIndex() - j2.getIndex()));
 				}
 			});
 		}
 
+		if ( itemKey.equals( "startstop" )){
+			
+			if ( can_queue ){
+				itemKey = "start";
+			}else if ( can_stop ){
+				itemKey = "stop";
+			}
+			
+		}
+		boolean didSomething = false;
 		boolean forceSort = false;
 		for (TranscodeJob job : jobs) {
 
 			if (itemKey.equals("stop")) {
 
 				job.stop();
+				didSomething = true;
 
 			} else if (itemKey.equals("start")) {
 
+				didSomething = true;
 				job.queue();
 
 			} else if (itemKey.equals("up")) {
 
+				didSomething = true;
 				job.moveUp();
 
 				TableColumnCore sortColumn = tvFiles.getSortColumn();
@@ -1183,6 +1347,7 @@ public class SBC_DevicesView
 
 			} else if (itemKey.equals("down")) {
 
+				didSomething = true;
 				job.moveDown();
 
 				TableColumnCore sortColumn = tvFiles.getSortColumn();
@@ -1190,8 +1355,10 @@ public class SBC_DevicesView
 						&& sortColumn.getName().equals(ColumnTJ_Rank.COLUMN_ID);
 			}
 		}
+		
 		tvFiles.refreshTable(forceSort);
 
+		return didSomething;
 	}
 
 	// @see com.aelitis.azureus.ui.common.updater.UIUpdatable#getUpdateUIName()
@@ -1217,18 +1384,19 @@ public class SBC_DevicesView
 
 	// @see com.aelitis.azureus.core.devices.TranscodeTargetListener#fileChanged(com.aelitis.azureus.core.devices.TranscodeFile, int, java.lang.Object)
 	public void fileChanged(TranscodeFile file, int type, Object data) {
+		TableRowCore row;
 		synchronized (this) {
 			if (tvFiles == null) {
 				return;
 			}
-			TableRowCore row = tvFiles.getRow(file);
-			if (row != null) {
-				row.invalidate();
-				if (row.isVisible()) {
-					UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-					if (uiFunctions != null) {
-						uiFunctions.refreshIconBar();
-					}
+			row = tvFiles.getRow( getFileInTable( file ));
+		}
+		if (row != null) {
+			row.invalidate();
+			if (row.isVisible()) {
+				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+				if (uiFunctions != null) {
+					uiFunctions.refreshIconBar();
 				}
 			}
 		}
@@ -1238,7 +1406,7 @@ public class SBC_DevicesView
 	public void fileRemoved(TranscodeFile file) {
 		synchronized (this) {
 			if (tvFiles != null) {
-				tvFiles.removeDataSource(file);
+				tvFiles.removeDataSource( getFileInTable( file ));
 			}
 		}
 	}
@@ -1342,6 +1510,11 @@ public class SBC_DevicesView
 			} else {
 
 				deleteNoCheck(file);
+
+				int nextIndex = startIndex + 1;
+				if (nextIndex < toRemove.length) {
+					deleteFiles(toRemove, nextIndex);
+				}
 			}
 		} catch (Throwable e) {
 
@@ -1354,7 +1527,18 @@ public class SBC_DevicesView
 
 		if (job != null) {
 
-			job.remove();
+			try{
+				job.remove();
+				
+			}catch( TranscodeActionVetoException e ){
+				
+				UIFunctionsManager.getUIFunctions().forceNotify(
+						UIFunctions.STATUSICON_WARNING, 
+						MessageText.getString( "globalmanager.download.remove.veto" ), 
+						e.getMessage(), null, null, -1 );
+				
+				return;
+			}
 		}
 
 		try {
@@ -1366,7 +1550,7 @@ public class SBC_DevicesView
 	
 	private void 
 	createDragDrop(
-		final TableViewSWTImpl<?>		table )
+		final TableViewSWT<?>		table )
 	{
 		try {
 
@@ -1413,7 +1597,7 @@ public class SBC_DevicesView
 							if ( file.isComplete()){
 								
 								try{
-									eventData += file.getTargetFile().getFile().getAbsolutePath() + "\n";
+									eventData += file.getTargetFile().getFile( true ).getAbsolutePath() + "\n";
 									
 								}catch( Throwable e ){
 									
diff --git a/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java b/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
index 94b577f..7d10b6f 100644
--- a/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
+++ b/com/aelitis/azureus/ui/swt/devices/TranscodeChooser.java
@@ -1,799 +1,859 @@
-/**
- * Created on Mar 1, 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.Arrays;
-import java.util.Comparator;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-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.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;
-import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader.ImageDownloaderListener;
-import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog;
-
-/**
- * @author TuxPaper
- * @created Mar 1, 2009
- *
- */
-public abstract class TranscodeChooser
-{
-	private static final String skinFile = "skin3_transcodechooser";
-
-	private static final String shellSkinObjectID = "shell";
-
-	private Shell shell;
-
-	private SWTSkin skin;
-
-	private Font fontDevice;
-
-	protected TranscodeTarget selectedTranscodeTarget;
-
-	protected TranscodeProfile selectedProfile;
-
-	protected DeviceTemplate selectedDeviceTemplate;
-
-	private SWTSkinObjectContainer soList;
-
-	private Shell mainShell;
-
-	private SWTSkinObjectContainer soBottomContainer;
-
-	private Button btnNoPrompt;
-
-	private int transcodeRequirement;
-
-	private java.util.List<String> listImageIDsToRelease = new ArrayList<String>();
-
-	private SWTSkinObjectText soInfoTitle;
-
-	private SWTSkinObjectText soInfoText;
-
-	private Font fontDeviceDesc;
-
-	private TranscodeProfile[] transcodeProfiles;
-
-	public TranscodeChooser() {
-		this((TranscodeTarget) null);
-	}
-
-	public TranscodeChooser(TranscodeTarget tt) {
-		selectedTranscodeTarget = tt;
-	}
-
-	public TranscodeChooser(TranscodeProfile[] transcodeProfiles) {
-		this.transcodeProfiles = transcodeProfiles;
-	}
-
-	public void show() {
-		// Check if plugin is installed
-		if (!DevicesFTUX.ensureInstalled()) {
-			return;
-		}
-
-		mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
-		shell = ShellFactory.createShell(mainShell, SWT.DIALOG_TRIM | SWT.RESIZE);
-
-		Utils.setShellIcon(shell);
-
-		skin = SWTSkinFactory.getNonPersistentInstance(
-				SkinnedDialog.class.getClassLoader(), "com/aelitis/azureus/ui/skin/",
-				skinFile + ".properties");
-
-		skin.initialize(shell, shellSkinObjectID);
-
-		shell.addTraverseListener(new TraverseListener() {
-			public void keyTraversed(TraverseEvent e) {
-				if (e.detail == SWT.TRAVERSE_ESCAPE) {
-					shell.close();
-				}
-			}
-		});
-
-		shell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				closed();
-			}
-		});
-
-		skin.layout();
-
-		SWTSkinObject soBottom = skin.getSkinObject("bottom");
-		if (soBottom instanceof SWTSkinObjectContainer) {
-			soBottomContainer = (SWTSkinObjectContainer) soBottom;
-
-			soBottomContainer.addListener(new SWTSkinObjectListener() {
-
-				public Object eventOccured(SWTSkinObject skinObject, int eventType,
-						Object params) {
-					if (eventType == EVENT_SHOW) {
-						skinObject.removeListener(this);
-						initBottom();
-					}
-					return null;
-				}
-			});
-			soBottomContainer.setVisible(selectedTranscodeTarget != null);
-		}
-
-		soList = (SWTSkinObjectContainer) skin.getSkinObject("list");
-		if (soList != null) {
-			if (transcodeProfiles != null) {
-				createProfileList(soList, "drop");
-			} else if (selectedTranscodeTarget == null) {
-				createDeviceList(soList);
-			} else {
-				transcodeProfiles = selectedTranscodeTarget.getTranscodeProfiles(); 
-				createProfileList(soList, "drop");
-			}
-		}
-
-		// we may have disposed of shell during device/profile list building
-		// (ex. no devices avail)
-		if (shell.isDisposed()) {
-			return;
-		}
-
-		shell.addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				Utils.disposeSWTObjects(new Object[] {
-					fontDevice,
-					fontDeviceDesc
-				});
-				for (String id : listImageIDsToRelease) {
-					ImageLoader.getInstance().releaseImage(id);
-				}
-			}
-		});
-		shell.open();
-	}
-
-	/**
-	 * @param soBottomContainer2
-	 *
-	 * @since 4.1.0.5
-	 */
-	protected void initBottom() {
-		Composite composite = soBottomContainer.getComposite();
-		btnNoPrompt = new Button(composite, SWT.CHECK);
-		Messages.setLanguageText(btnNoPrompt, "option.rememberthis");
-
-		Label lblXCode = new Label(composite, SWT.NONE);
-		lblXCode.setText(MessageText.getString("device.xcode"));
-
-		final Combo cmbXCode = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
-
-		cmbXCode.add(MessageText.getString("device.xcode.whenreq"));
-		cmbXCode.add(MessageText.getString("device.xcode.always"));
-		cmbXCode.add(MessageText.getString("device.xcode.never"));
-		transcodeRequirement = selectedTranscodeTarget.getTranscodeRequirement();
-		switch (transcodeRequirement) {
-			case TranscodeTarget.TRANSCODE_ALWAYS:
-				cmbXCode.select(1);
-				break;
-
-			case TranscodeTarget.TRANSCODE_NEVER:
-				cmbXCode.select(2);
-				break;
-
-			case TranscodeTarget.TRANSCODE_WHEN_REQUIRED:
-			default:
-				cmbXCode.select(0);
-				break;
-		}
-
-		cmbXCode.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				int i = cmbXCode.getSelectionIndex();
-				switch (i) {
-					case 0:
-						transcodeRequirement = TranscodeTarget.TRANSCODE_WHEN_REQUIRED;
-						break;
-
-					case 1:
-						transcodeRequirement = TranscodeTarget.TRANSCODE_ALWAYS;
-						break;
-
-					case 2:
-						transcodeRequirement = TranscodeTarget.TRANSCODE_NEVER;
-						break;
-				}
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-
-		FormData fd;
-
-		fd = new FormData();
-		fd.left = new FormAttachment(0, 10);
-		fd.top = new FormAttachment(cmbXCode, 0, SWT.CENTER);
-		btnNoPrompt.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.right = new FormAttachment(100, -10);
-		fd.top = new FormAttachment(0, 5);
-		fd.bottom = new FormAttachment(100, -5);
-		cmbXCode.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.right = new FormAttachment(cmbXCode, -5);
-		fd.top = new FormAttachment(cmbXCode, 0, SWT.CENTER);
-		lblXCode.setLayoutData(fd);
-
-		int userMode = COConfigurationManager.getIntParameter("User Mode");
-		if (userMode == 0) {
-			lblXCode.setVisible(false);
-			cmbXCode.setVisible(false);
-		}
-
-		Point computeSize = shell.computeSize(300, SWT.DEFAULT, true);
-		shell.setSize(computeSize);
-	}
-
-	/**
-	 * @param soList
-	 *
-	 * @since 4.1.0.5
-	 */
-	private void createProfileList(SWTSkinObjectContainer soList,
-			String source) {
-		if (selectedTranscodeTarget == null && selectedDeviceTemplate == null) {
-			new MessageBoxShell(SWT.OK, "No Device", "No Device Selected!?").open(null);
-			shell.dispose();
-			return;
-		}
-
-		if (selectedTranscodeTarget != null) {
-			try {
-				PlatformDevicesMessenger.qosTranscodeRequest(selectedTranscodeTarget,
-						source);
-			} catch (Throwable ignore) {
-			}
-
-			try {
-				TranscodeProfile defaultProfile = selectedTranscodeTarget.getDefaultTranscodeProfile();
-				if (defaultProfile != null) {
-					// user chose not to ask
-					selectedProfile = defaultProfile;
-					shell.dispose();
-					return;
-				}
-			} catch (TranscodeException e) {
-			}
-		}
-
-		if (transcodeProfiles.length == 0) {
-			new MessageBoxShell(SWT.OK, "No Profiles", "No Profiles for "
-					+ selectedTranscodeTarget.getDevice().getName()).open(null);
-			shell.dispose();
-			return;
-		}
-
-		if (transcodeProfiles.length == 1) {
-			selectedProfile = transcodeProfiles[0];
-			shell.dispose();
-			return;
-		}
-
-		Arrays.sort(transcodeProfiles, new Comparator<TranscodeProfile>() {
-			public int compare(TranscodeProfile o1, TranscodeProfile o2) {
-				return o1.getName().compareToIgnoreCase(o2.getName());
-			}
-		});
-
-		Composite parent = soList.getComposite();
-		if (parent.getChildren().length > 0) {
-			Utils.disposeComposite(parent, false);
-		}
-
-		soInfoTitle = (SWTSkinObjectText) skin.getSkinObject("info-title");
-		soInfoText = (SWTSkinObjectText) skin.getSkinObject("info-text");
-		resetProfileInfoBox(false);
-
-		RowLayout layout = new RowLayout(SWT.HORIZONTAL);
-		layout.spacing = 0;
-		layout.marginLeft = layout.marginRight = 0;
-		layout.wrap = true;
-		layout.justify = true;
-		layout.fill = true;
-		parent.setLayout(layout);
-
-		Listener listenerMouseInout = new Listener() {
-			public void handleEvent(Event event) {
-				Widget widget = (event.widget instanceof Canvas)
-						? ((Canvas) event.widget).getParent() : event.widget;
-
-				Composite c = TranscodeChooser.this.soList.getComposite();
-				Rectangle bounds = c.getClientArea();
-				c.redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
-
-				TranscodeProfile profile = (TranscodeProfile) widget.getData("obj");
-				if (profile == null) {
-					return;
-				}
-				if (event.type == SWT.MouseEnter) {
-					String description = profile.getDescription();
-					if (description == null || description.length() == 0) {
-						resetProfileInfoBox(true);
-					} else {
-						if (soInfoTitle != null) {
-							soInfoTitle.setTextID(
-									"devices.choose.profile.info.title.selected", new String[] {
-										profile.getName()
-									});
-						}
-						if (soInfoText != null) {
-							soInfoText.setText(description);
-							Point computeSize = shell.computeSize(
-									shell.getClientArea().width, SWT.DEFAULT, true);
-							if (computeSize.y > shell.getSize().y) {
-								shell.setSize(computeSize);
-							}
-						}
-					}
-				}
-			}
-		};
-
-		parent.addListener(SWT.MouseEnter, new Listener() {
-			public void handleEvent(Event event) {
-				resetProfileInfoBox(true);
-			}
-		});
-
-		Listener clickListener = new Listener() {
-			boolean down = false;
-
-			public void handleEvent(Event event) {
-				if (event.type == SWT.MouseDown) {
-					down = true;
-				} else if (event.type == SWT.MouseUp && down) {
-					Widget widget = (event.widget instanceof Label)
-							? ((Label) event.widget).getParent() : event.widget;
-					selectedProfile = (TranscodeProfile) widget.getData("obj");
-					if (selectedProfile == null) {
-						Debug.out("profile is null!");
-					} else {
-						if (btnNoPrompt != null) {
-							if (btnNoPrompt.getSelection()) {
-								selectedTranscodeTarget.setDefaultTranscodeProfile(selectedProfile);
-							}
-						}
-					}
-					shell.dispose();
-					down = false;
-				}
-			}
-		};
-
-		GridData gridData;
-		for (TranscodeProfile profile : transcodeProfiles) {
-			addImageBox(parent, clickListener, listenerMouseInout, profile,
-					profile.getIconURL(), profile.getName());
-		}
-		SWTSkinObjectText soTitle = (SWTSkinObjectText) skin.getSkinObject("title");
-		if (soTitle != null) {
-			soTitle.setTextID("devices.choose.profile.title");
-		}
-
-		SWTSkinObjectText soSubTitle = (SWTSkinObjectText) skin.getSkinObject("subtitle");
-		if (soSubTitle != null) {
-			soSubTitle.setTextID("label.clickone");
-		}
-
-		if (soBottomContainer != null) {
-			soBottomContainer.setVisible(true);
-		}
-
-		SWTSkinObjectContainer soButtonBottomArea = (SWTSkinObjectContainer) skin.getSkinObject("button-bottom");
-		if (soButtonBottomArea != null) {
-			soButtonBottomArea.setVisible(false);
-		}
-
-		Point computeSize = shell.computeSize(600, SWT.DEFAULT, true);
-		shell.setSize(computeSize);
-		Utils.centerWindowRelativeTo(shell, mainShell);
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.1.0.5
-	 */
-	public static void addImageBox(Composite parent, Listener clickListener,
-			Listener listenerMouseInout, Object obj, String iconURL, String name) {
-		GridData gridData;
-		final Shell shell = parent.getShell();
-		final Composite c = new Composite(parent, SWT.NONE);
-		GridLayout clayout = new GridLayout();
-		clayout.marginWidth = clayout.horizontalSpacing = 0;
-		c.setLayout(clayout);
-		c.setCursor(c.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
-		c.addListener(SWT.MouseUp, clickListener);
-		c.addListener(SWT.MouseDown, clickListener);
-		c.setData("obj", obj);
-
-		if (listenerMouseInout != null) {
-			c.addListener(SWT.MouseEnter, listenerMouseInout);
-			c.addListener(SWT.MouseExit, listenerMouseInout);
-		}
-
-		final Canvas lblImage = new Canvas(c, SWT.DOUBLE_BUFFERED);
-		if (listenerMouseInout != null) {
-			lblImage.addListener(SWT.MouseEnter, listenerMouseInout);
-			lblImage.addListener(SWT.MouseExit, listenerMouseInout);
-		}
-		lblImage.addListener(SWT.MouseUp, clickListener);
-		lblImage.addListener(SWT.MouseDown, clickListener);
-		lblImage.setData("obj", obj);
-		lblImage.addListener(SWT.Paint, new Listener() {
-			public void handleEvent(Event event) {
-				Image image = (Image) lblImage.getData("Image");
-				if (image != null) {
-					Rectangle bounds = image.getBounds();
-					Rectangle area = lblImage.getBounds();
-					Rectangle carea = c.getBounds();
-
-					Point ptInDisplay = c.toDisplay(0, 0);
-
-					event.gc.setAdvanced(true);
-					event.gc.setAntialias(SWT.ON);
-					event.gc.setLineWidth(2);
-
-					if (new Rectangle(ptInDisplay.x, ptInDisplay.y, carea.width,
-							carea.height).contains(event.display.getCursorLocation())) {
-						//if (event.display.getCursorControl() == lblImage) {
-
-						Color color1 = ColorCache.getColor(event.gc.getDevice(), 252, 253,
-								255);
-						Color color2 = ColorCache.getColor(event.gc.getDevice(), 169, 195,
-								252);
-						Pattern pattern = new Pattern(event.gc.getDevice(), 0, 0, 0,
-								area.height, color1, 0, color2, 200);
-						event.gc.setBackgroundPattern(pattern);
-
-						event.gc.fillRoundRectangle(0, 0, area.width - 1, area.height - 1,
-								20, 20);
-
-						event.gc.setBackgroundPattern(null);
-						pattern.dispose();
-
-						pattern = new Pattern(event.gc.getDevice(), 0, 0, 0, area.height,
-								color2, 50, color2, 255);
-						event.gc.setForegroundPattern(pattern);
-
-						event.gc.drawRoundRectangle(0, 0, area.width - 1, area.height - 1,
-								20, 20);
-
-						event.gc.setForegroundPattern(null);
-						pattern.dispose();
-					}
-
-					event.gc.drawImage(image, bounds.x, bounds.y, bounds.width,
-							bounds.height, 8, 5, bounds.width, bounds.height);
-
-				} else {
-					Rectangle ca = lblImage.getClientArea();
-					event.gc.drawRectangle(ca.x, ca.y, ca.width - 1, ca.height - 1);
-				}
-			}
-		});
-		gridData = new GridData(GridData.FILL_VERTICAL);
-		gridData.heightHint = 100;
-		gridData.widthHint = 120;
-		if (iconURL != null) {
-			ImageLoader imageLoader = ImageLoader.getInstance();
-			Image image = imageLoader.getUrlImage(iconURL,
-					new ImageDownloaderListener() {
-						public void imageDownloaded(Image image, boolean returnedImmediately) {
-							if (!returnedImmediately) {
-								lblImage.setData("Image", image);
-								Rectangle bounds = image.getBounds();
-								GridData gridData = (GridData) lblImage.getLayoutData();
-								gridData.heightHint = bounds.height + 10;
-								gridData.widthHint = bounds.width + 16;
-								lblImage.setLayoutData(gridData);
-								lblImage.getShell().layout(new Control[] {
-									lblImage
-								});
-								Point computeSize = shell.computeSize(600, SWT.DEFAULT, true);
-								shell.setSize(computeSize);
-							}
-						}
-					});
-			if (image != null) {
-				lblImage.setData("Image", image);
-				Rectangle bounds = image.getBounds();
-				gridData.heightHint = bounds.height + 10;
-				gridData.widthHint = bounds.width + 16;
-			}
-		}
-		lblImage.setLayoutData(gridData);
-
-		Label label = new Label(c, SWT.WRAP | SWT.CENTER);
-		if (listenerMouseInout != null) {
-			label.addListener(SWT.MouseEnter, listenerMouseInout);
-		}
-		label.addListener(SWT.MouseUp, clickListener);
-		label.addListener(SWT.MouseDown, clickListener);
-		gridData = new GridData(GridData.FILL_HORIZONTAL);
-		label.setLayoutData(gridData);
-		String s = name;
-		//s += " (via " + profile.getProvider().getName() + ")";
-		label.setText(s);
-		label.setCursor(c.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
-	}
-
-	/**
-	 * 
-	 *
-	 * @param layout 
-	 * @since 4.1.0.5
-	 */
-	protected void resetProfileInfoBox(boolean layout) {
-		if (soInfoTitle != null) {
-			soInfoTitle.setTextID("devices.choose.profile.info.title");
-		}
-		if (soInfoText != null) {
-			soInfoText.setTextID("devices.choose.profile.info.text");
-			if (layout) {
-				Point computeSize = shell.computeSize(shell.getClientArea().width,
-						SWT.DEFAULT, true);
-				shell.setSize(computeSize);
-			}
-		}
-	}
-
-	private void createDeviceList(SWTSkinObjectContainer soDeviceList) {
-		Composite parent = soDeviceList.getComposite();
-		parent.setBackgroundMode(SWT.INHERIT_FORCE);
-		FormLayout layout = new FormLayout();
-		layout.marginLeft = 10;
-		layout.marginHeight = 15;
-		parent.setLayout(layout);
-
-		DeviceManager device_manager = DeviceManagerFactory.getSingleton();
-		Device[] devices = device_manager.getDevices();
-
-		if (devices.length == 0) {
-			noDevices();
-			return;
-		}
-
-		Arrays.sort(devices, new Comparator<Device>() {
-			public int compare(Device o1, Device o2) {
-				return o1.getName().compareToIgnoreCase(o2.getName());
-			}
-		});
-
-		fontDevice = Utils.getFontWithHeight(parent.getFont(), null, 16, SWT.BOLD);
-		fontDeviceDesc = Utils.getFontWithHeight(parent.getFont(), null, 16,
-				SWT.NONE);
-
-		/**
-		PaintListener paintListener = new PaintListener() {
-			public void paintControl(PaintEvent e) {
-				Rectangle ca = ((Composite) e.widget).getClientArea();
-				e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
-				e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
-				e.gc.setAntialias(SWT.ON);
-				e.gc.fillRoundRectangle(ca.x, ca.y, ca.width - 1, ca.height - 1, 10, 10);
-				e.gc.drawRoundRectangle(ca.x, ca.y, ca.width - 1, ca.height - 1, 10, 10);
-			}
-		};
-		**/
-
-		boolean hide_generic = COConfigurationManager.getBooleanParameter(
-				DeviceManagerUI.CONFIG_VIEW_HIDE_REND_GENERIC, true);
-
-		int numDevices = 0;
-		Button lastButton = null;
-		for (Device device : devices) {
-			if (device.getType() != Device.DT_MEDIA_RENDERER || device.isHidden()
-					|| !(device instanceof DeviceMediaRenderer)) {
-				continue;
-			}
-
-			DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
-
-			if (hide_generic && renderer.isGeneric()) {
-				continue;
-			}
-
-			TranscodeTarget transcodeTarget = (TranscodeTarget) device;
-
-			if (transcodeTarget.getTranscodeProfiles().length == 0) {
-				continue;
-			}
-
-			String imageID = null;
-			if (device instanceof DeviceMediaRenderer) {
-				imageID = "image.sidebar.device."
-						+ ((DeviceMediaRenderer) device).getRendererSpecies() + ".big";
-			}
-
-			lastButton = createDeviceButton(parent, device, device.getName(),
-					device.getShortDescription(), imageID, lastButton);
-			numDevices++;
-		}
-
-		if (numDevices == 0) {
-			noDevices();
-			return;
-		}
-
-		SWTSkinObjectText soTitle = (SWTSkinObjectText) skin.getSkinObject("title");
-		if (soTitle != null) {
-			soTitle.setTextID("devices.choose.device.title");
-		}
-
-		SWTSkinObjectText soSubTitle = (SWTSkinObjectText) skin.getSkinObject("subtitle");
-		if (soSubTitle != null) {
-			soSubTitle.setText("");
-		}
-
-		SWTSkinObjectContainer soButtonBottomArea = (SWTSkinObjectContainer) skin.getSkinObject("button-bottom");
-		if (soButtonBottomArea != null) {
-			soButtonBottomArea.setVisible(true);
-
-			SWTSkinObjectButton soOk = (SWTSkinObjectButton) skin.getSkinObject("ok");
-			if (soOk != null) {
-				shell.setDefaultButton((Button) soOk.getControl());
-				soOk.addSelectionListener(new ButtonListenerAdapter() {
-					public void pressed(SWTSkinButtonUtility buttonUtility,
-							SWTSkinObject skinObject, int stateMask) {
-						transcodeProfiles = selectedTranscodeTarget.getTranscodeProfiles();
-						createProfileList(soList, "chooser");
-					}
-				});
-			}
-
-			SWTSkinObjectButton soCancel = (SWTSkinObjectButton) skin.getSkinObject("cancel");
-			if (soCancel != null) {
-				soCancel.addSelectionListener(new ButtonListenerAdapter() {
-					public void pressed(SWTSkinButtonUtility buttonUtility,
-							SWTSkinObject skinObject, int stateMask) {
-						shell.close();
-					}
-				});
-			}
-		}
-
-		if (soBottomContainer != null) {
-			soBottomContainer.setVisible(false);
-		}
-
-		//shell.pack();
-		Point computeSize = shell.computeSize(400, SWT.DEFAULT, true);
-		shell.setSize(computeSize);
-		shell.layout(true);
-		Utils.centerWindowRelativeTo(shell, mainShell);
-	}
-
-	private Button createDeviceButton(Composite parent, Object deviceObj,
-			String name, String shortDescription, String imageID, Button lastButton) {
-		Button button = new Button(parent, SWT.LEFT | SWT.RADIO);
-		StringBuffer sb = new StringBuffer(name);
-		button.setFont(fontDevice);
-		button.setData("Device", deviceObj);
-		button.addSelectionListener(new SelectionListener() {
-
-			public void widgetSelected(SelectionEvent e) {
-				Object device = e.widget.getData("Device");
-				if (device instanceof TranscodeTarget) {
-					selectedTranscodeTarget = (TranscodeTarget) device;
-				} else if (device instanceof DeviceTemplate) {
-					selectedDeviceTemplate = (DeviceTemplate) device;
-				}
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-		if (lastButton == null) {
-			button.setSelection(true);
-			if (deviceObj instanceof TranscodeTarget) {
-				selectedTranscodeTarget = (TranscodeTarget) deviceObj;
-			}
-		}
-
-		Image imgRenderer = null;
-		if (imageID != null) {
-			listImageIDsToRelease.add(imageID);
-			imgRenderer = ImageLoader.getInstance().getImage(imageID);
-		}
-
-		if (ImageLoader.isRealImage(imgRenderer)) {
-			button.setImage(imgRenderer);
-
-			// buttons are center when they have an image..
-			// fill with a bunch of spaces so it left aligns
-			//char[] c = new char[100];
-			//Arrays.fill(c, ' ');
-			//sb.append(c);
-		} else {
-			sb.insert(0, ' ');
-		}
-
-		button.setText(sb.toString());
-
-		FormData fd = new FormData();
-		fd.left = new FormAttachment(0, 0);
-		if (lastButton == null) {
-			fd.top = new FormAttachment(0, 0);
-		} else {
-			fd.top = new FormAttachment(lastButton, 15);
-		}
-		button.setLayoutData(fd);
-
-		if (shortDescription != null && shortDescription.length() > 0) {
-			Label label = new Label(parent, SWT.None);
-			label.setText("(" + shortDescription + ")");
-
-			fd = new FormData();
-			fd.top = new FormAttachment(button, 0, SWT.CENTER);
-			fd.left = new FormAttachment(button, 5);
-			label.setLayoutData(fd);
-		}
-
-		return button;
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.1.0.5
-	 */
-	private void noDevices() {
-		new MessageBoxShell(
-				SWT.OK,
-				"No Devices Found",
-				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?").open(null);
-		shell.dispose();
-	}
-
-	public abstract void closed();
-
-	public int getTranscodeRequirement() {
-		return transcodeRequirement;
-	}
-}
+/**
+ * Created on Mar 1, 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.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+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.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;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader.ImageDownloaderListener;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog;
+
+/**
+ * @author TuxPaper
+ * @created Mar 1, 2009
+ *
+ */
+public abstract class TranscodeChooser
+{
+	private static final String skinFile = "skin3_transcodechooser";
+
+	private static final String shellSkinObjectID = "shell";
+
+	private Shell shell;
+
+	private SWTSkin skin;
+
+	private Font fontDevice;
+
+	protected TranscodeTarget selectedTranscodeTarget;
+
+	protected TranscodeProfile selectedProfile;
+
+	protected DeviceTemplate selectedDeviceTemplate;
+
+	private SWTSkinObjectContainer soList;
+
+	private Shell mainShell;
+
+	private SWTSkinObjectContainer soBottomContainer;
+
+	private Button btnNoPrompt;
+
+	private int transcodeRequirement;
+
+	private java.util.List<String> listImageIDsToRelease = new ArrayList<String>();
+
+	private SWTSkinObjectText soInfoTitle;
+
+	private SWTSkinObjectText soInfoText;
+
+	private Font fontDeviceDesc;
+
+	private TranscodeProfile[] transcodeProfiles;
+
+	public TranscodeChooser() {
+		this((TranscodeTarget) null);
+	}
+
+	public TranscodeChooser(TranscodeTarget tt) {
+		selectedTranscodeTarget = tt;
+	}
+
+	public TranscodeChooser(TranscodeProfile[] transcodeProfiles) {
+		this.transcodeProfiles = transcodeProfiles;
+	}
+
+	public void show( Runnable fire_on_install ) {
+		// Check if plugin is installed
+		if (!DevicesFTUX.ensureInstalled( fire_on_install )) {
+			return;
+		}
+
+		mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
+		shell = ShellFactory.createShell(mainShell, SWT.DIALOG_TRIM | SWT.RESIZE);
+
+		Utils.setShellIcon(shell);
+
+		skin = SWTSkinFactory.getNonPersistentInstance(
+				SkinnedDialog.class.getClassLoader(), "com/aelitis/azureus/ui/skin/",
+				skinFile + ".properties");
+
+		skin.initialize(shell, shellSkinObjectID);
+
+		shell.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE) {
+					shell.close();
+				}
+			}
+		});
+
+		shell.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				closed();
+			}
+		});
+
+		skin.layout();
+
+		SWTSkinObject soBottom = skin.getSkinObject("bottom");
+		if (soBottom instanceof SWTSkinObjectContainer) {
+			soBottomContainer = (SWTSkinObjectContainer) soBottom;
+
+			soBottomContainer.addListener(new SWTSkinObjectListener() {
+
+				public Object eventOccured(SWTSkinObject skinObject, int eventType,
+						Object params) {
+					if (eventType == EVENT_SHOW) {
+						skinObject.removeListener(this);
+						initBottom();
+					}
+					return null;
+				}
+			});
+			soBottomContainer.setVisible(selectedTranscodeTarget != null);
+		}
+
+		soList = (SWTSkinObjectContainer) skin.getSkinObject("list");
+		if (soList != null) {
+			if (transcodeProfiles != null) {
+				createProfileList(soList);
+			} else if (selectedTranscodeTarget == null) {
+				createDeviceList(soList);
+			} else {
+				transcodeProfiles = selectedTranscodeTarget.getTranscodeProfiles(); 
+				createProfileList(soList);
+			}
+		}
+
+		// we may have disposed of shell during device/profile list building
+		// (ex. no devices avail)
+		if (shell.isDisposed()) {
+			return;
+		}
+
+		shell.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				Utils.disposeSWTObjects(new Object[] {
+					fontDevice,
+					fontDeviceDesc
+				});
+				for (String id : listImageIDsToRelease) {
+					ImageLoader.getInstance().releaseImage(id);
+				}
+			}
+		});
+		Utils.verifyShellRect(shell, true);
+		shell.open();
+	}
+
+	/**
+	 * @param soBottomContainer2
+	 *
+	 * @since 4.1.0.5
+	 */
+	protected void initBottom() {
+		Composite composite = soBottomContainer.getComposite();
+		btnNoPrompt = new Button(composite, SWT.CHECK);
+		Messages.setLanguageText(btnNoPrompt, "option.rememberthis");
+
+		Label lblXCode = new Label(composite, SWT.NONE);
+		lblXCode.setText(MessageText.getString("device.xcode"));
+
+		final Combo cmbXCode = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+		cmbXCode.add(MessageText.getString("device.xcode.whenreq"));
+		cmbXCode.add(MessageText.getString("device.xcode.always"));
+		cmbXCode.add(MessageText.getString("device.xcode.never"));
+		transcodeRequirement = selectedTranscodeTarget.getTranscodeRequirement();
+		switch (transcodeRequirement) {
+			case TranscodeTarget.TRANSCODE_ALWAYS:
+				cmbXCode.select(1);
+				break;
+
+			case TranscodeTarget.TRANSCODE_NEVER:
+				cmbXCode.select(2);
+				break;
+
+			case TranscodeTarget.TRANSCODE_WHEN_REQUIRED:
+			default:
+				cmbXCode.select(0);
+				break;
+		}
+
+		cmbXCode.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				int i = cmbXCode.getSelectionIndex();
+				switch (i) {
+					case 0:
+						transcodeRequirement = TranscodeTarget.TRANSCODE_WHEN_REQUIRED;
+						break;
+
+					case 1:
+						transcodeRequirement = TranscodeTarget.TRANSCODE_ALWAYS;
+						break;
+
+					case 2:
+						transcodeRequirement = TranscodeTarget.TRANSCODE_NEVER;
+						break;
+				}
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		FormData fd;
+
+		fd = new FormData();
+		fd.left = new FormAttachment(0, 10);
+		fd.top = new FormAttachment(cmbXCode, 0, SWT.CENTER);
+		btnNoPrompt.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.right = new FormAttachment(100, -10);
+		fd.top = new FormAttachment(0, 5);
+		fd.bottom = new FormAttachment(100, -5);
+		cmbXCode.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.right = new FormAttachment(cmbXCode, -5);
+		fd.top = new FormAttachment(cmbXCode, 0, SWT.CENTER);
+		lblXCode.setLayoutData(fd);
+
+		int userMode = COConfigurationManager.getIntParameter("User Mode");
+		if (userMode == 0) {
+			lblXCode.setVisible(false);
+			cmbXCode.setVisible(false);
+		}
+
+		Point computeSize = shell.computeSize(shell.getClientArea().width,
+				SWT.DEFAULT, true);
+		shell.setSize(computeSize);
+	}
+
+	/**
+	 * @param soList
+	 *
+	 * @since 4.1.0.5
+	 */
+	private void createProfileList(SWTSkinObjectContainer soList) {
+		if (selectedTranscodeTarget == null && selectedDeviceTemplate == null) {
+			new MessageBoxShell(SWT.OK, "No Device", "No Device Selected!?").open(null);
+			shell.dispose();
+			return;
+		}
+
+		if (selectedTranscodeTarget != null) {
+			try {
+				TranscodeProfile defaultProfile = selectedTranscodeTarget.getDefaultTranscodeProfile();
+				if (defaultProfile != null) {
+					// user chose not to ask
+					
+					if ( selectedTranscodeTarget.getTranscodeRequirement() == TranscodeTarget.TRANSCODE_NEVER ){
+							// take note of never-xcode override
+						selectedProfile = selectedTranscodeTarget.getBlankProfile();
+					}else{
+						selectedProfile = defaultProfile;
+					}
+					shell.dispose();
+					return;
+				}
+			} catch (TranscodeException e) {
+			}
+		}
+
+		if (transcodeProfiles.length == 0 || selectedTranscodeTarget.getTranscodeRequirement() == TranscodeTarget.TRANSCODE_NEVER ){
+			if ( selectedTranscodeTarget != null ){
+				selectedProfile = selectedTranscodeTarget.getBlankProfile();
+				shell.dispose();
+				return;
+			}
+			new MessageBoxShell(SWT.OK, "No Profiles", "No Profiles for "
+					+ selectedTranscodeTarget.getDevice().getName()).open(null);
+			shell.dispose();
+			return;
+		}
+
+		if (transcodeProfiles.length == 1) {
+			selectedProfile = transcodeProfiles[0];
+			
+			shell.dispose();
+			return;
+		}
+
+		Arrays.sort(transcodeProfiles, new Comparator<TranscodeProfile>() {
+			public int compare(TranscodeProfile o1, TranscodeProfile o2) {
+				int i1 = o1.getIconIndex();
+				int i2 = o2.getIconIndex();
+				
+				if ( i1 == i2 ){
+				
+					return o1.getName().compareToIgnoreCase(o2.getName());
+				}else{
+					
+					return( i1 - i2 );
+				}
+			}
+		});
+
+		Composite parent = soList.getComposite();
+		if (parent.getChildren().length > 0) {
+			Utils.disposeComposite(parent, false);
+		}
+
+		soInfoTitle = (SWTSkinObjectText) skin.getSkinObject("info-title");
+		soInfoText = (SWTSkinObjectText) skin.getSkinObject("info-text");
+		resetProfileInfoBox(false);
+
+		RowLayout layout = new RowLayout(SWT.HORIZONTAL);
+		layout.spacing = 0;
+		layout.marginLeft = layout.marginRight = 0;
+		layout.wrap = true;
+		layout.justify = true;
+		layout.fill = true;
+		parent.setLayout(layout);
+
+		Listener listenerMouseInout = new Listener() {
+			public void handleEvent(Event event) {
+				Widget widget = (event.widget instanceof Canvas)
+						? ((Canvas) event.widget).getParent() : event.widget;
+
+				Composite c = TranscodeChooser.this.soList.getComposite();
+				Rectangle bounds = c.getClientArea();
+				c.redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
+
+				TranscodeProfile profile = (TranscodeProfile) widget.getData("obj");
+				if (profile == null) {
+					return;
+				}
+				if (event.type == SWT.MouseEnter) {
+					String description = profile.getDescription();
+					if (selectedTranscodeTarget != null) {
+						if (profile == selectedTranscodeTarget.getBlankProfile()) {
+							description = null;
+						}
+					}
+
+					if (description == null || description.length() == 0) {
+						resetProfileInfoBox(true);
+					} else {
+						if (soInfoTitle != null) {
+							soInfoTitle.setTextID(
+									"devices.choose.profile.info.title.selected", new String[] {
+										profile.getName()
+									});
+						}
+						if (soInfoText != null) {
+							soInfoText.setText(description);
+							Point computeSize = shell.computeSize(
+									shell.getClientArea().width, SWT.DEFAULT, true);
+							if (computeSize.y > shell.getSize().y) {
+								shell.setSize(computeSize);
+							}
+						}
+					}
+				}
+			}
+		};
+
+		parent.addListener(SWT.MouseEnter, new Listener() {
+			public void handleEvent(Event event) {
+				resetProfileInfoBox(true);
+			}
+		});
+
+		Listener clickListener = new Listener() {
+			boolean down = false;
+
+			public void handleEvent(Event event) {
+				if (event.type == SWT.MouseDown) {
+					down = true;
+				} else if (event.type == SWT.MouseUp && down) {
+					Widget widget = (event.widget instanceof Label)
+							? ((Label) event.widget).getParent() : event.widget;
+					selectedProfile = (TranscodeProfile) widget.getData("obj");
+					if (selectedTranscodeTarget != null && selectedProfile == selectedTranscodeTarget.getBlankProfile()) {
+						transcodeRequirement = TranscodeTarget.TRANSCODE_NEVER;
+					}
+					if (selectedProfile == null) {
+						Debug.out("profile is null!");
+					} else {
+						if (btnNoPrompt != null) {
+							if (btnNoPrompt.getSelection()) {
+								if ( transcodeRequirement == TranscodeTarget.TRANSCODE_NEVER ){
+									selectedTranscodeTarget.setTranscodeRequirement( TranscodeTarget.TRANSCODE_NEVER );
+								}else{
+									selectedTranscodeTarget.setDefaultTranscodeProfile(selectedProfile);
+								}
+							}
+						}
+					}
+					shell.dispose();
+					down = false;
+				}
+			}
+		};
+
+		GridData gridData;
+		
+		int	total_images = 0;
+		
+		for (TranscodeProfile profile : transcodeProfiles) {
+			addImageBox(parent, clickListener, listenerMouseInout, profile,
+					profile.getIconURL(), profile.getName());
+			
+			total_images++;
+		}
+		if (selectedTranscodeTarget != null) {
+			addImageBox(parent, clickListener, listenerMouseInout, 
+					selectedTranscodeTarget.getBlankProfile(), "", "Do not transcode");
+			
+			total_images++;
+		}
+		SWTSkinObjectText soTitle = (SWTSkinObjectText) skin.getSkinObject("title");
+		if (soTitle != null) {
+			soTitle.setTextID("devices.choose.profile.title");
+		}
+
+		SWTSkinObjectText soSubTitle = (SWTSkinObjectText) skin.getSkinObject("subtitle");
+		if (soSubTitle != null) {
+			soSubTitle.setTextID("label.clickone");
+		}
+
+		if (soBottomContainer != null) {
+			soBottomContainer.setVisible(true);
+		}
+
+		SWTSkinObjectContainer soButtonBottomArea = (SWTSkinObjectContainer) skin.getSkinObject("button-bottom");
+		if (soButtonBottomArea != null) {
+			soButtonBottomArea.setVisible(false);
+		}
+
+			// once we get to 13 icons (e.g. for iTunes now we have ipad4/ipad mini we increase the width)
+			// to ensure the dialog doesn't get too long
+		
+		Point computeSize = shell.computeSize(total_images>12?800:600, SWT.DEFAULT, true);
+		shell.setSize(computeSize);
+		Utils.centerWindowRelativeTo(shell, mainShell);
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	public static void addImageBox(Composite parent, Listener clickListener,
+			Listener listenerMouseInout, Object obj, String iconURL, String name) {
+		GridData gridData;
+		final Shell shell = parent.getShell();
+		final Composite c = new Composite(parent, SWT.NONE);
+		GridLayout clayout = new GridLayout();
+		clayout.marginWidth = clayout.horizontalSpacing = 0;
+		c.setLayout(clayout);
+		c.setCursor(c.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+		c.addListener(SWT.MouseUp, clickListener);
+		c.addListener(SWT.MouseDown, clickListener);
+		c.setData("obj", obj);
+
+		if (listenerMouseInout != null) {
+			c.addListener(SWT.MouseEnter, listenerMouseInout);
+			c.addListener(SWT.MouseExit, listenerMouseInout);
+		}
+
+		final Canvas lblImage = new Canvas(c, SWT.DOUBLE_BUFFERED);
+		if (listenerMouseInout != null) {
+			lblImage.addListener(SWT.MouseEnter, listenerMouseInout);
+			lblImage.addListener(SWT.MouseExit, listenerMouseInout);
+		}
+		lblImage.addListener(SWT.MouseUp, clickListener);
+		lblImage.addListener(SWT.MouseDown, clickListener);
+		lblImage.setData("obj", obj);
+		lblImage.addListener(SWT.Paint, new Listener() {
+			public void handleEvent(Event event) {
+				Rectangle area = lblImage.getBounds();
+				Rectangle carea = c.getBounds();
+
+				Point ptInDisplay = c.toDisplay(0, 0);
+
+				event.gc.setAdvanced(true);
+				event.gc.setAntialias(SWT.ON);
+				event.gc.setLineWidth(2);
+
+				if (new Rectangle(ptInDisplay.x, ptInDisplay.y, carea.width,
+						carea.height).contains(event.display.getCursorLocation())) {
+					//if (event.display.getCursorControl() == lblImage) {
+
+					Color color1 = ColorCache.getColor(event.gc.getDevice(), 252, 253,
+							255);
+					Color color2 = ColorCache.getColor(event.gc.getDevice(), 169, 195,
+							252);
+					Pattern pattern = new Pattern(event.gc.getDevice(), 0, 0, 0,
+							area.height, color1, 0, color2, 200);
+					event.gc.setBackgroundPattern(pattern);
+
+					event.gc.fillRoundRectangle(0, 0, area.width - 1, area.height - 1,
+							20, 20);
+
+					event.gc.setBackgroundPattern(null);
+					pattern.dispose();
+
+					pattern = new Pattern(event.gc.getDevice(), 0, 0, 0, area.height,
+							color2, 50, color2, 255);
+					event.gc.setForegroundPattern(pattern);
+
+					event.gc.drawRoundRectangle(0, 0, area.width - 1, area.height - 1,
+							20, 20);
+
+					event.gc.setForegroundPattern(null);
+					pattern.dispose();
+				}
+
+				Image image = (Image) lblImage.getData("Image");
+				if (image != null) {
+					Rectangle bounds = image.getBounds();
+					event.gc.drawImage(image, bounds.x, bounds.y, bounds.width,
+							bounds.height, 8, 5, bounds.width, bounds.height);
+				} else {
+					Rectangle ca = lblImage.getClientArea();
+					event.gc.setAdvanced(true);
+					event.gc.setAntialias(SWT.ON);
+					event.gc.setAlpha(50);
+					event.gc.setBackground(event.gc.getForeground());
+					event.gc.fillRoundRectangle(ca.x + 10, ca.y + 5, ca.width - 21,
+							ca.height - 11, 20, 20);
+				}
+			}
+		});
+		gridData = new GridData(GridData.FILL_VERTICAL);
+		gridData.heightHint = 50;
+		gridData.widthHint = 100;
+		if (iconURL != null && iconURL.length() > 0) {
+			ImageLoader imageLoader = ImageLoader.getInstance();
+			Image image = imageLoader.getUrlImage(iconURL,
+					new ImageDownloaderListener() {
+						public void imageDownloaded(Image image, boolean returnedImmediately) {
+							if (!returnedImmediately) {
+								if (lblImage.isDisposed()) {
+									return;
+								}
+								lblImage.setData("Image", image);
+								Rectangle bounds = image.getBounds();
+								GridData gridData = (GridData) lblImage.getLayoutData();
+								gridData.heightHint = bounds.height + 10;
+								gridData.widthHint = bounds.width + 16;
+								lblImage.setLayoutData(gridData);
+								lblImage.getShell().layout(new Control[] {
+									lblImage
+								});
+								Point computeSize = shell.computeSize(600, SWT.DEFAULT, true);
+								shell.setSize(computeSize);
+							}
+						}
+					});
+			if (image != null) {
+				lblImage.setData("Image", image);
+				Rectangle bounds = image.getBounds();
+				gridData.heightHint = bounds.height + 10;
+				gridData.widthHint = bounds.width + 16;
+			}
+		}
+		lblImage.setLayoutData(gridData);
+
+		Label label = new Label(c, SWT.WRAP | SWT.CENTER);
+		if (listenerMouseInout != null) {
+			label.addListener(SWT.MouseEnter, listenerMouseInout);
+		}
+		label.addListener(SWT.MouseUp, clickListener);
+		label.addListener(SWT.MouseDown, clickListener);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		label.setLayoutData(gridData);
+		String s = name;
+		//s += " (via " + profile.getProvider().getName() + ")";
+		label.setText(s);
+		label.setCursor(c.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+	}
+
+	/**
+	 * 
+	 *
+	 * @param layout 
+	 * @since 4.1.0.5
+	 */
+	protected void resetProfileInfoBox(boolean layout) {
+		if (soInfoTitle != null) {
+			soInfoTitle.setTextID("devices.choose.profile.info.title");
+		}
+		if (soInfoText != null) {
+			soInfoText.setTextID("devices.choose.profile.info.text");
+			if (layout) {
+				Point computeSize = shell.computeSize(shell.getClientArea().width,
+						SWT.DEFAULT, true);
+				shell.setSize(computeSize);
+			}
+		}
+	}
+
+	private void createDeviceList(SWTSkinObjectContainer soDeviceList) {
+		Composite parent = soDeviceList.getComposite();
+		parent.setBackgroundMode(SWT.INHERIT_FORCE);
+		FormLayout layout = new FormLayout();
+		layout.marginLeft = 10;
+		layout.marginHeight = 15;
+		parent.setLayout(layout);
+
+		DeviceManager device_manager = DeviceManagerFactory.getSingleton();
+		Device[] devices = device_manager.getDevices();
+
+		if (devices.length == 0) {
+			noDevices();
+			return;
+		}
+
+		Arrays.sort(devices, new Comparator<Device>() {
+			public int compare(Device o1, Device o2) {
+				return o1.getName().compareToIgnoreCase(o2.getName());
+			}
+		});
+
+		fontDevice = FontUtils.getFontWithHeight(parent.getFont(), null, 16, SWT.BOLD);
+		fontDeviceDesc = FontUtils.getFontWithHeight(parent.getFont(), null, 16,
+				SWT.NONE);
+
+		/**
+		PaintListener paintListener = new PaintListener() {
+			public void paintControl(PaintEvent e) {
+				Rectangle ca = ((Composite) e.widget).getClientArea();
+				e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
+				e.gc.setBackground(e.display.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
+				e.gc.setAntialias(SWT.ON);
+				e.gc.fillRoundRectangle(ca.x, ca.y, ca.width - 1, ca.height - 1, 10, 10);
+				e.gc.drawRoundRectangle(ca.x, ca.y, ca.width - 1, ca.height - 1, 10, 10);
+			}
+		};
+		**/
+
+		boolean hide_generic = COConfigurationManager.getBooleanParameter(
+				DeviceManagerUI.CONFIG_VIEW_HIDE_REND_GENERIC, true);
+
+		boolean show_only_tagged = COConfigurationManager.getBooleanParameter(
+				DeviceManagerUI.CONFIG_VIEW_SHOW_ONLY_TAGGED, false);
+
+		int numDevices = 0;
+		Button lastButton = null;
+		for (Device device : devices) {
+			if (device.getType() != Device.DT_MEDIA_RENDERER || device.isHidden()
+					|| !(device instanceof DeviceMediaRenderer)) {
+				continue;
+			}
+
+			DeviceMediaRenderer renderer = (DeviceMediaRenderer) device;
+
+			if (hide_generic && renderer.isNonSimple()) {
+				continue;
+			}
+
+			if ( show_only_tagged && !renderer.isTagged()){
+				continue;
+			}
+			
+			TranscodeTarget transcodeTarget = (TranscodeTarget) device;
+
+			if (transcodeTarget.getTranscodeProfiles().length == 0) {
+				
+				if ( transcodeTarget.getTranscodeRequirement() != TranscodeTarget.TRANSCODE_NEVER ){
+				
+					continue;
+				}
+			}
+
+			String imageID = null;
+			if (device instanceof DeviceMediaRenderer) {
+				imageID = "image.sidebar.device." + DeviceManagerUI.getDeviceImageID( device ) + ".big";
+			}
+
+			lastButton = createDeviceButton(parent, device, device.getName(),
+					device.getShortDescription(), imageID, lastButton);
+			numDevices++;
+		}
+
+		if (numDevices == 0) {
+			noDevices();
+			return;
+		}
+
+		SWTSkinObjectText soTitle = (SWTSkinObjectText) skin.getSkinObject("title");
+		if (soTitle != null) {
+			soTitle.setTextID("devices.choose.device.title");
+		}
+
+		SWTSkinObjectText soSubTitle = (SWTSkinObjectText) skin.getSkinObject("subtitle");
+		if (soSubTitle != null) {
+			soSubTitle.setText("");
+		}
+
+		SWTSkinObjectContainer soButtonBottomArea = (SWTSkinObjectContainer) skin.getSkinObject("button-bottom");
+		if (soButtonBottomArea != null) {
+			soButtonBottomArea.setVisible(true);
+
+			SWTSkinObjectButton soOk = (SWTSkinObjectButton) skin.getSkinObject("ok");
+			if (soOk != null) {
+				shell.setDefaultButton(soOk.getButton());
+				soOk.addSelectionListener(new ButtonListenerAdapter() {
+					public void pressed(SWTSkinButtonUtility buttonUtility,
+							SWTSkinObject skinObject, int stateMask) {
+						transcodeProfiles = selectedTranscodeTarget.getTranscodeProfiles();
+						createProfileList(soList);
+					}
+				});
+			}
+
+			SWTSkinObjectButton soCancel = (SWTSkinObjectButton) skin.getSkinObject("cancel");
+			if (soCancel != null) {
+				soCancel.addSelectionListener(new ButtonListenerAdapter() {
+					public void pressed(SWTSkinButtonUtility buttonUtility,
+							SWTSkinObject skinObject, int stateMask) {
+						shell.close();
+					}
+				});
+			}
+		}
+
+		if (soBottomContainer != null) {
+			soBottomContainer.setVisible(false);
+		}
+
+		//shell.pack();
+		Point computeSize = shell.computeSize(400, SWT.DEFAULT, true);
+		shell.setSize(computeSize);
+		shell.layout(true);
+		Utils.centerWindowRelativeTo(shell, mainShell);
+	}
+
+	private Button createDeviceButton(Composite parent, Object deviceObj,
+			String name, String shortDescription, String imageID, Button lastButton) {
+		Button button = new Button(parent, SWT.LEFT | SWT.RADIO);
+		StringBuffer sb = new StringBuffer(name);
+		button.setFont(fontDevice);
+		button.setData("Device", deviceObj);
+		button.addSelectionListener(new SelectionListener() {
+
+			public void widgetSelected(SelectionEvent e) {
+				Object device = e.widget.getData("Device");
+				if (device instanceof TranscodeTarget) {
+					selectedTranscodeTarget = (TranscodeTarget) device;
+				} else if (device instanceof DeviceTemplate) {
+					selectedDeviceTemplate = (DeviceTemplate) device;
+				}
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		if (lastButton == null) {
+			button.setSelection(true);
+			if (deviceObj instanceof TranscodeTarget) {
+				selectedTranscodeTarget = (TranscodeTarget) deviceObj;
+			}
+		}
+
+		Image imgRenderer = null;
+		if (imageID != null) {
+			listImageIDsToRelease.add(imageID);
+			imgRenderer = ImageLoader.getInstance().getImage(imageID);
+		}
+
+		if (ImageLoader.isRealImage(imgRenderer)) {
+			button.setImage(imgRenderer);
+
+			// buttons are center when they have an image..
+			// fill with a bunch of spaces so it left aligns
+			//char[] c = new char[100];
+			//Arrays.fill(c, ' ');
+			//sb.append(c);
+		} else {
+			sb.insert(0, ' ');
+		}
+
+		button.setText(sb.toString());
+
+		FormData fd = new FormData();
+		fd.left = new FormAttachment(0, 0);
+		if (lastButton == null) {
+			fd.top = new FormAttachment(0, 0);
+		} else {
+			fd.top = new FormAttachment(lastButton, 15);
+		}
+		button.setLayoutData(fd);
+
+		if (shortDescription != null && shortDescription.length() > 0) {
+			Label label = new Label(parent, SWT.None);
+			label.setText("(" + shortDescription + ")");
+
+			fd = new FormData();
+			fd.top = new FormAttachment(button, 0, SWT.CENTER);
+			fd.left = new FormAttachment(button, 5);
+			label.setLayoutData(fd);
+		}
+
+		return button;
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	private void noDevices() {
+		new MessageBoxShell(
+				SWT.OK,
+				"No Devices Found",
+				"We couldn't find any devices.  Maybe you didn't install the Vuze Transcoder Plugin?").open(null);
+		shell.dispose();
+	}
+
+	public abstract void closed();
+
+	public int getTranscodeRequirement() {
+		return transcodeRequirement;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnDevices_Name.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnDevices_Name.java
deleted file mode 100644
index 4bc3226..0000000
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnDevices_Name.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.columns;
-
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
-import com.aelitis.azureus.core.devices.TranscodeProvider;
-
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
-/**
- * @author TuxPaper
- * @created Feb 24, 2009
- *
- */
-public class ColumnDevices_Name
-extends CoreTableColumn
-implements TableCellRefreshListener
-{
-	public static final String COLUMN_ID = "name";
-
-	/**
-	 * @param name
-	 * @param tableID
-	 */
-	public ColumnDevices_Name(String tableID) {
-		super(COLUMN_ID, tableID);
-		setForDataSourceType(TranscodeProvider.class);
-		initialize(ALIGN_LEAD | ALIGN_TOP, POSITION_INVISIBLE, 150, INTERVAL_INVALID_ONLY);
-	}
-
-	public void refresh(TableCell cell) {
-		TranscodeProvider ds = (TranscodeProvider) cell.getDataSource();
-		String name = ds.getName();
-		cell.setText(name);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java
index b7173e8..0bd5ede 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Completion.java
@@ -25,7 +25,6 @@ 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;
@@ -34,6 +33,7 @@ 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 com.aelitis.azureus.ui.swt.utils.FontUtils;
 
 import org.gudy.azureus2.plugins.ui.tables.*;
 
@@ -44,7 +44,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  */
 public class ColumnOD_Completion
 implements TableCellAddedListener, TableCellRefreshListener,
-TableCellDisposeListener, TableCellSWTPaintListener
+TableCellDisposeListener, TableCellSWTPaintListener, TableColumnExtraInfoListener
 {
 	private static final int borderWidth = 1;
 
@@ -69,6 +69,13 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void cellAdded(TableCell cell) {
 		if (marginHeight != -1) {
@@ -160,7 +167,7 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		gcImage.setForeground(textColor);
 
 		if (fontText == null) {
-			fontText = Utils.getFontWithHeight(gcImage.getFont(), gcImage, 10);
+			fontText = FontUtils.getFontWithHeight(gcImage.getFont(), gcImage, 10);
 		}
 		
 		gcImage.setFont(fontText);
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java
index ce1394d..81e556c 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Name.java
@@ -22,6 +22,7 @@ package com.aelitis.azureus.ui.swt.devices.columns;
 import com.aelitis.azureus.core.devices.DeviceOfflineDownload;
 
 import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateCellText;
 
 /**
  * @author TuxPaper
@@ -29,7 +30,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnOD_Name
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener, ObfusticateCellText
 {
 	public static final String COLUMN_ID = "od_name";
 
@@ -38,6 +39,14 @@ public class ColumnOD_Name
 		column.addListeners(this);
 		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
+		column.setObfustication(true);
+	}
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public void refresh(TableCell cell) {
@@ -55,4 +64,17 @@ public class ColumnOD_Name
 
 		cell.setText(text);
 	}
+
+	public String getObfusticatedText(TableCell cell) {
+		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
+		if (od == null) {
+			return null;
+		}
+		String name = od.getDownload().toString();
+		int i = name.indexOf('#');
+		if (i > 0) {
+			name = name.substring(i + 1);
+		}
+		return name;
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java
index ff69a7e..9cacf1d 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Remaining.java
@@ -30,7 +30,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnOD_Remaining
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "od_remaining";
 	
@@ -41,6 +41,12 @@ public class ColumnOD_Remaining
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 		
 	}
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
 
 	public void refresh(TableCell cell) {
 		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java
index 8cdb0cf..2371438 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnOD_Status.java
@@ -33,7 +33,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnOD_Status
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "od_status";
 
@@ -61,6 +61,13 @@ public class ColumnOD_Status
 		});
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	public void refresh(TableCell cell) {
 		DeviceOfflineDownload od = (DeviceOfflineDownload) cell.getDataSource();
 		if (od == null) {
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Category.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Category.java
index 0426ed0..d2fd2a5 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Category.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Category.java
@@ -28,17 +28,24 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnTJ_Category
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "category";
 
 	public ColumnTJ_Category(TableColumn column) {
 		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_INVISIBLE, 80);
 		column.addListeners(this);
-		column.setRefreshInterval(TableColumn.INTERVAL_INVALID_ONLY);
+		column.setRefreshInterval(TableColumn.INTERVAL_LIVE);
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
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 eef8620..76bc0f8 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Completion.java
@@ -18,6 +18,7 @@
  
 package com.aelitis.azureus.ui.swt.devices.columns;
 
+import java.text.NumberFormat;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -28,7 +29,6 @@ import org.eclipse.swt.graphics.*;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 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;
@@ -37,6 +37,7 @@ import com.aelitis.azureus.core.devices.*;
 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 com.aelitis.azureus.ui.swt.utils.FontUtils;
 
 import org.gudy.azureus2.plugins.ui.tables.*;
 
@@ -47,7 +48,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  */
 public class ColumnTJ_Completion
 implements TableCellAddedListener, TableCellRefreshListener,
-TableCellDisposeListener, TableCellSWTPaintListener
+TableCellDisposeListener, TableCellSWTPaintListener, TableColumnExtraInfoListener
 {
 	private static final int borderWidth = 1;
 
@@ -63,6 +64,11 @@ TableCellDisposeListener, TableCellSWTPaintListener
 	
 	Color textColor;
 	
+	NumberFormat percentage_format = NumberFormat.getPercentInstance();
+	{
+		percentage_format.setMinimumFractionDigits(0);
+		percentage_format.setMaximumFractionDigits(0);
+	}
 
 	public ColumnTJ_Completion(final TableColumn column) {
 		column.initialize(TableColumn.ALIGN_LEAD, TableColumn.POSITION_LAST, 145);
@@ -83,6 +89,13 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		});
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void cellAdded(TableCell cell) {
 		if (marginHeight != -1) {
@@ -167,7 +180,7 @@ TableCellDisposeListener, TableCellSWTPaintListener
 		gcImage.setForeground(textColor);
 
 		if (fontText == null) {
-			fontText = Utils.getFontWithHeight(gcImage.getFont(), gcImage, 10);
+			fontText = FontUtils.getFontWithHeight(gcImage.getFont(), gcImage, 10);
 		}
 		
 		gcImage.setFont(fontText);
@@ -180,7 +193,7 @@ TableCellDisposeListener, TableCellSWTPaintListener
 			
 		}else{
 			
-			sText = DisplayFormatters.formatPercentFromThousands(perThouDone);
+			sText = percentage_format.format( perThouDone/1000.0 ); // DisplayFormatters.formatPercentFromThousands(perThouDone);
 			
 			if ( tf != null && perThouDone < 1000 ){
 				
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_CopiedToDevice.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_CopiedToDevice.java
index 569d062..3e7fbab 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_CopiedToDevice.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_CopiedToDevice.java
@@ -27,9 +27,7 @@ import com.aelitis.azureus.core.devices.TranscodeFile;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 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 org.gudy.azureus2.plugins.ui.tables.*;
 
 /**
  * @author TuxPaper
@@ -37,7 +35,7 @@ import org.gudy.azureus2.plugins.ui.tables.TableColumn;
  *
  */
 public class ColumnTJ_CopiedToDevice
-implements TableCellRefreshListener
+implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "copied";
 
@@ -58,6 +56,14 @@ implements TableCellRefreshListener
 			}
 		});
 	}
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Device.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Device.java
index 08df3c6..ccc1e26 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Device.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Device.java
@@ -28,7 +28,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnTJ_Device
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "device";
 
@@ -39,6 +39,13 @@ public class ColumnTJ_Device
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Duration.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Duration.java
index e942150..03e3452 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Duration.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Duration.java
@@ -29,7 +29,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnTJ_Duration
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "duration";
 
@@ -40,6 +40,13 @@ public class ColumnTJ_Duration
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Name.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Name.java
index fcab499..7d79cf7 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Name.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Name.java
@@ -33,7 +33,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  */
 public class ColumnTJ_Name
 	implements TableCellRefreshListener, ObfusticateCellText,
-	TableCellDisposeListener
+	TableCellDisposeListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "transcode_name";
 
@@ -49,6 +49,13 @@ public class ColumnTJ_Name
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
 		if (tf == null) {
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Profile.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Profile.java
index 99c2168..52d307d 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Profile.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Profile.java
@@ -28,7 +28,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnTJ_Profile
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "profile";
 
@@ -39,6 +39,13 @@ public class ColumnTJ_Profile
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Rank.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Rank.java
index 7742ad0..8adfbad 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Rank.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Rank.java
@@ -21,9 +21,7 @@ package com.aelitis.azureus.ui.swt.devices.columns;
 import com.aelitis.azureus.core.devices.TranscodeFile;
 import com.aelitis.azureus.core.devices.TranscodeJob;
 
-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 org.gudy.azureus2.plugins.ui.tables.*;
 
 /**
  * @author TuxPaper
@@ -31,7 +29,7 @@ import org.gudy.azureus2.plugins.ui.tables.TableColumn;
  *
  */
 public class ColumnTJ_Rank
-implements TableCellRefreshListener
+implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "trancode_qpos";
 
@@ -42,6 +40,13 @@ implements TableCellRefreshListener
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
 
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+	
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Resolution.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Resolution.java
index cd2de52..0032e24 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Resolution.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Resolution.java
@@ -28,7 +28,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class ColumnTJ_Resolution
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "resolution";
 
@@ -38,6 +38,13 @@ public class ColumnTJ_Resolution
 		column.setRefreshInterval(TableColumn.INTERVAL_GRAPHIC);
 		column.setType(TableColumn.TYPE_TEXT_ONLY);
 	}
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
diff --git a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Status.java b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Status.java
index d44c455..06c1e5b 100644
--- a/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Status.java
+++ b/com/aelitis/azureus/ui/swt/devices/columns/ColumnTJ_Status.java
@@ -37,7 +37,7 @@ import org.gudy.azureus2.ui.swt.Utils;
  *
  */
 public class ColumnTJ_Status
-	implements TableCellRefreshListener
+	implements TableCellRefreshListener, TableColumnExtraInfoListener
 {
 	public static final String COLUMN_ID = "transcode_status";
 
@@ -53,6 +53,7 @@ public class ColumnTJ_Status
 		"devices.on.demand",		// 8 
 		"devices.ready",			// 9
 		"devices.downloading",		// 10
+		"devices.copying", // 11
 	};
 
 	private static String[] js_resources;
@@ -79,11 +80,19 @@ public class ColumnTJ_Status
 			}
 		});
 	}
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			TableColumn.CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TranscodeFile tf = (TranscodeFile) cell.getDataSource();
-		if (tf == null) {
+		if (tf == null || tf.isDeleted()){
 			return;
 		}
 		TranscodeJob job = tf.getJob();
@@ -107,8 +116,12 @@ public class ColumnTJ_Status
 			}
 			
 			if ( text == null ){
-				
-				if ( tf.getCopyToDeviceFails() > 0 ){
+
+				if ( tf.isCopyingToDevice() ) {
+
+					text = js_resources[11];
+
+				} else if ( tf.getCopyToDeviceFails() > 0 ){
 			
 					text = js_resources[7];
 					
@@ -185,6 +198,8 @@ public class ColumnTJ_Status
 			}
 		}
 		
+		
+		
 		cell.setText( text );
 		cell.setToolTip(tooltip);
 		
diff --git a/com/aelitis/azureus/ui/swt/extlistener/StimulusRPC.java b/com/aelitis/azureus/ui/swt/extlistener/StimulusRPC.java
index a9f2e62..f94f19f 100644
--- a/com/aelitis/azureus/ui/swt/extlistener/StimulusRPC.java
+++ b/com/aelitis/azureus/ui/swt/extlistener/StimulusRPC.java
@@ -36,6 +36,8 @@ import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
 import com.aelitis.azureus.core.messenger.browser.BrowserMessageDispatcher;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfoContentNetwork;
 import com.aelitis.azureus.ui.swt.browser.listener.ConfigListener;
@@ -162,7 +164,7 @@ public class StimulusRPC
 									null));
 
 							TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, playPrepare,
-									bringToFront, false);
+									bringToFront);
 
 							return true;
 						}
@@ -187,10 +189,10 @@ public class StimulusRPC
 							String tabID = MapUtils.getMapString(decodedMap, "tab", "");
 							if (tabID.length() > 0) {
 								// 3.2 TODO: Should we be checking for partial matches?
-								SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-								SideBarEntrySWT entry = sidebar.getCurrentEntry();
+								MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+								MdiEntry entry = mdi.getCurrentEntry();
 								if (entry != null) {
-									return entry.id.equals(tabID);
+									return entry.getId().equals(tabID);
 								}
 							}
 						}
diff --git a/com/aelitis/azureus/ui/swt/feature/FeatureManagerInstallWindow.java b/com/aelitis/azureus/ui/swt/feature/FeatureManagerInstallWindow.java
new file mode 100644
index 0000000..9ec1bd5
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/feature/FeatureManagerInstallWindow.java
@@ -0,0 +1,204 @@
+/*
+ * Created on Mar 6, 2010 11:01:46 AM
+ * Copyright (C) 2010 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.feature;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Shell;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
+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.PluginException;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence.LicenceInstallationListener;
+import org.gudy.azureus2.ui.swt.Utils;
+
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
+import com.aelitis.azureus.ui.swt.skin.SWTSkin;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBox;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBoxListener;
+
+/**
+ * @author TuxPaper
+ * @created Mar 6, 2010
+ *
+ */
+public class FeatureManagerInstallWindow
+	implements LicenceInstallationListener
+{
+	private final static boolean FAKE_DELAY = Constants.IS_CVS_VERSION;
+
+	private VuzeMessageBox box;
+
+	private ProgressBar progressBar;
+
+	private Licence licence;
+
+	private SWTSkinObjectText soProgressText;
+
+	private String progressText;
+
+	private SWTSkinObjectText soInstallPct;
+	
+	public FeatureManagerInstallWindow(Licence licence) {
+		if (!FeatureManagerUI.enabled) {
+			return;
+		}
+		this.licence = licence;
+		licence.addInstallationListener(this);
+	}
+
+	public void open() {
+		if (!FeatureManagerUI.enabled) {
+			return;
+		}
+
+		boolean isTrial = FeatureManagerUI.isTrialLicence(licence);
+		box = new VuzeMessageBox(MessageText.getString("dlg.auth.title"),
+				"", null, 0);
+		box.setSubTitle(MessageText.getString(isTrial ? "dlg.auth.install.subtitle.trial"
+				: "dlg.auth.install.subtitle.plus"));
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource(isTrial ? "image.burn.dlg.header" : "image.vp");
+
+		box.setListener(new VuzeMessageBoxListener() {
+
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.install", "dlg.register.install",
+						soExtra);
+
+				SWTSkinObjectContainer soProgressBar = (SWTSkinObjectContainer) skin.getSkinObject("progress-bar");
+				if (soProgressBar != null) {
+					progressBar = new ProgressBar(soProgressBar.getComposite(),
+							SWT.HORIZONTAL);
+					progressBar.setMinimum(0);
+					progressBar.setMaximum(100);
+					progressBar.setLayoutData(Utils.getFilledFormData());
+				}
+				
+				soInstallPct = (SWTSkinObjectText) skin.getSkinObject("install-pct");
+
+				soProgressText = (SWTSkinObjectText) skin.getSkinObject("progress-text");
+				if (soProgressText != null && progressText != null) {
+					soProgressText.setText(progressText);
+				}
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				licence.removeInstallationListener(FeatureManagerInstallWindow.this);
+			}
+		});
+	}
+
+	public void reportActivity(String licence_key, String install, String activity) {
+		if (FAKE_DELAY) {
+			try {
+				Thread.sleep(80);
+			} catch (InterruptedException e) {
+			}
+		}
+
+		if (soProgressText != null) {
+			String[] split = install.split("/", 2);
+			this.progressText = MessageText.getString("dlg.auth.install.progress",
+					new String[] { split.length == 2 ? split[1] : split[0] });
+			soProgressText.setText(this.progressText);
+		}
+	}
+
+	public void reportProgress(String licence_key, String install,
+			final int percent) {
+		if (FAKE_DELAY) {
+			try {
+				Thread.sleep(80);
+			} catch (InterruptedException e) {
+			}
+		}
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int pct = percent == 100 ? 99 : percent;
+				if (soInstallPct != null) {
+					soInstallPct.setText(MessageText.getString("dlg.auth.install.pct",
+							new String[] {
+								"" + pct
+							}));
+				}
+				if (progressBar != null && !progressBar.isDisposed()) {
+					// never reach 100%!
+					progressBar.setSelection(pct);
+				}
+			}
+		});
+	}
+
+	public void complete(String licence_key) {
+		if (box != null) {
+			box.close(0);
+		}
+		licence.removeInstallationListener(this);
+	}
+
+	public static boolean alreadyFailing = false;
+	public void failed(String licence_key, PluginException error) {
+		if (alreadyFailing) {
+			return;
+		}
+		alreadyFailing = true;
+		UIFunctionsManager.getUIFunctions().promptUser(
+				MessageText.getString( "dlg.auth.install.failed.title" ), 
+				MessageText.getString( "dlg.auth.install.failed.text", new String[]{ licence_key, Debug.getNestedExceptionMessage( error )}),
+				new String[] {
+					MessageText.getString("Button.ok")
+				}, 0, null, null, false, 0, new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						alreadyFailing = false;
+					}
+				});
+				
+		
+		Logger.log(new LogAlert(true, "Error while installing " + licence_key,
+				error));
+		box.close(0);
+		licence.removeInstallationListener(this);
+	}
+
+	public void close() {
+		
+		box.close(0);
+		licence.removeInstallationListener(this);
+	}
+	
+	public void start(String licence_key) {
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/feature/FeatureManagerUI.java b/com/aelitis/azureus/ui/swt/feature/FeatureManagerUI.java
new file mode 100644
index 0000000..1fafd47
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/feature/FeatureManagerUI.java
@@ -0,0 +1,892 @@
+package com.aelitis.azureus.ui.swt.feature;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.config.impl.ConfigurationChecker;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+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.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuManager;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.views.skin.SBC_PlusFTUX;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBox;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBoxListener;
+import com.aelitis.azureus.util.ConstantsVuze;
+
+public class FeatureManagerUI
+{
+	private static final Integer BUTTON_UPGRADE = 0x1000;
+
+	public static boolean enabled = !Constants.isUnix
+			//&& FeatureAvailability.ENABLE_PLUS()
+			|| System.getProperty("fm.ui", "0").equals("1");
+
+	private static FeatureManager featman;
+
+	private static VuzeMessageBox validatingBox;
+
+	private static VuzeMessageBox entryWindow;
+
+	private static FeatureManagerUIListener fml;
+	
+	public static void registerWithFeatureManager() {
+		if (!enabled) {
+			return;
+		}
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+			public void azureusCoreRunning(AzureusCore core) {
+				PluginInterface pi = core.getPluginManager().getDefaultPluginInterface();
+				featman = pi.getUtilities().getFeatureManager();
+
+				fml = new FeatureManagerUIListener(featman);
+				featman.addListener(fml);
+				Licence[] licences = featman.getLicences();
+				for (Licence licence : licences) {
+					fml.licenceAdded(licence);
+				}
+				
+
+				UIManager ui_manager = pi.getUIManager();
+
+				ui_manager.addUIListener(new UIManagerListener() {
+					public void UIDetached(UIInstance instance) {
+					}
+
+					public void UIAttached(UIInstance instance) {
+						if (!(instance instanceof UISWTInstance)) {
+							return;
+						}
+
+						if (!Utils.isAZ2UI()) {
+							addFreeBurnUI();
+						}
+					}
+				});
+			}
+		});
+	}
+
+	private static void addFreeBurnUI() {
+		final MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						String title = FeatureManagerUI.hasFullLicence()
+								? "{mdi.entry.plus.full}" : "{mdi.entry.plus.free}";
+						String placeBelow = mdi.getEntry(MultipleDocumentInterface.SIDEBAR_SECTION_WELCOME) == null
+								? "" : MultipleDocumentInterface.SIDEBAR_SECTION_WELCOME;
+						
+						MdiEntry entry = mdi.createEntryFromSkinRef(
+								MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+								MultipleDocumentInterface.SIDEBAR_SECTION_PLUS,
+								"main.area.plus", title, null, null, true, placeBelow);
+						entry.setImageLeftID("image.sidebar.plus");
+						return entry;
+					}
+				});
+
+		MdiEntry existingEntry = mdi.getEntry(MultipleDocumentInterface.SIDEBAR_HEADER_DVD);
+		if (existingEntry != null) {
+			// abandon all hope, something already added DVD stuff
+			return;
+		}
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+
+						MdiEntry entryAbout = mdi.createEntryFromSkinRef(
+								MultipleDocumentInterface.SIDEBAR_HEADER_DVD,
+								MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO, "main.burn.ftux",
+								"{mdi.entry.about.dvdburn}", null, null,
+								false, null);
+						entryAbout.setImageLeftID("image.sidebar.dvdburn");
+						entryAbout.setExpanded(true);
+
+						entryAbout.addListener(new MdiEntryDropListener() {
+							public boolean mdiEntryDrop(MdiEntry entry, Object droppedObject) {
+								openTrialAskWindow();
+								return true;
+							}
+						});
+
+						MenuManager menuManager = PluginInitializer.getDefaultInterface().getUIManager().getMenuManager();
+						MenuItem menuHide = menuManager.addMenuItem("Sidebar." +
+								MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO,
+								"popup.error.hide");
+						menuHide.addListener(new MenuItemListener() {
+							public void selected(MenuItem menu, Object target) {
+								mdi.closeEntry(MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO);
+							}
+						});
+
+						return entryAbout;
+					}
+				});
+		
+		mdi.addListener(new MdiEntryLoadedListener() {
+			public void mdiEntryLoaded(MdiEntry entry) {
+				if (!entry.getId().equals(MultipleDocumentInterface.SIDEBAR_HEADER_DVD)) {
+					return;
+				}
+				MdiEntryVitalityImage addSub = entry.addVitalityImage("image.sidebar.subs.add");
+				addSub.addListener(new MdiEntryVitalityImageListener() {
+					public void mdiEntryVitalityImage_clicked(int x, int y) {
+						openTrialAskWindow();
+					}
+				});
+			}
+		});
+
+		if (ConfigurationChecker.isNewVersion()
+				&& !ConfigurationChecker.isNewInstall() && !hasFullLicence()) {
+			SBC_PlusFTUX.setSourceRef("startup");
+			mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+		}
+	}
+
+	public static void openTrialAskWindow() {
+		VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.try.trial.title"),
+				MessageText.getString("dlg.try.trial.text"), new String[] {
+					MessageText.getString("Button.turnon"),
+					MessageText.getString("Button.cancel")
+				}, 0);
+		box.setButtonVals(new Integer[] {
+			SWT.OK,
+			SWT.CANCEL,
+		});
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.burn.dlg.header");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				String id = "dlg.register.trialask";
+				SWTSkinObject so = skin.createSkinObject(id, id, soExtra);
+
+				SWTSkinObjectText soLink = (SWTSkinObjectText) skin.getSkinObject(
+						"link", so);
+				if (soLink != null) {
+					soLink.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+						public boolean urlClicked(URLInfo urlInfo) {
+							String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+									"plus_tos.start", true);
+							Utils.launch(url);
+							return true;
+						}
+					});
+				}
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == SWT.OK) {
+					SimpleTimer.addEvent("createTrial", SystemTime.getCurrentTime(),
+							new TimerEventPerformer() {
+								public void perform(TimerEvent event) {
+									createTrial();
+								}
+							});
+				}
+			}
+		});
+	}
+
+	public static void createTrial() {
+		try {
+			Licence[] trial = featman.createLicences(new String[] {
+				"dvdburn_trial"
+			});
+		} catch (Throwable e) {
+			String s = "Creating Trial: " + Debug.getNestedExceptionMessage(e);
+			new MessageBoxShell("Trial Error", s).open(null);
+			Logger.log(new LogAlert(true, s, e));
+		}
+	}
+
+	public static void openLicenceEntryWindow(final boolean trytwo, 
+			final String prefillWith) {
+		if (!enabled) {
+			return;
+		}
+		
+		if (entryWindow != null) {
+			return;
+		}
+		
+		try {
+  		String tryNo = (trytwo ? "2" : "1");
+  		final SWTSkinObjectTextbox[] key = new SWTSkinObjectTextbox[1];
+  		entryWindow = new VuzeMessageBox(
+  				MessageText.getString("dlg.auth.title"),
+  				MessageText.getString("dlg.auth.enter.line.try." + tryNo),
+  				new String[] {
+  					MessageText.getString("Button.agree"),
+  					MessageText.getString("Button.cancel")
+  				}, 0);
+			entryWindow.setButtonVals(new Integer[] {
+				SWT.OK,
+				SWT.CANCEL,
+			});
+  
+  		entryWindow.setSubTitle(MessageText.getString("dlg.auth.enter.subtitle.try."
+  				+ tryNo));
+  		entryWindow.addResourceBundle(FeatureManagerUI.class,
+  				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+  		entryWindow.setIconResource("image.vp");
+  		if (trytwo) {
+  			entryWindow.setTextIconResource("image.warn.big");
+  		}
+  
+  		entryWindow.setListener(new VuzeMessageBoxListener() {
+  			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+  				SWTSkin skin = soExtra.getSkin();
+  				skin.createSkinObject("dlg.register", "dlg.register", soExtra);
+  
+  				SWTSkinObjectText link = (SWTSkinObjectText) skin.getSkinObject(
+  						"register-link", soExtra);
+  				link.setText(MessageText.getString(trytwo ? "dlg.auth.enter.link.try.2" : "dlg.auth.enter.link.try.1"));
+  				link.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+  					public boolean urlClicked(URLInfo urlInfo) {
+  						if (trytwo) {
+    						String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+    								"upgrade.start", true);
+    						Utils.launch(url);
+  						} else {
+  		  				SBC_PlusFTUX.setSourceRef("dlg-activation");
+  
+  		  				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+  							mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+  							entryWindow.close(-2);
+  						}
+  						return true;
+  					}
+  				});
+  
+  				SWTSkinObjectText linkTOS = (SWTSkinObjectText) skin.getSkinObject(
+  						"tos-link", soExtra);
+  				if (linkTOS != null) {
+    				linkTOS.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+  						public boolean urlClicked(URLInfo urlInfo) {
+								String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+										"plus_tos.start", true);
+								Utils.launch(url);
+  							return true;
+  						}
+    				});
+  				}
+  
+  				key[0] = (SWTSkinObjectTextbox) skin.getSkinObject("key", soExtra);
+  				if (key[0] != null) {
+  					if (prefillWith != null) {
+  						key[0].setText(prefillWith);
+  					} else if (!trytwo) {
+    					licenceDetails details = getFullFeatureDetails();
+    					if (details != null && details.licence.getState() != Licence.LS_INVALID_KEY) {
+    						key[0].setText(details.licence.getKey());
+    						if (key[0].getControl() instanceof Text) {
+    							((Text)key[0].getControl()).selectAll();
+    						}
+    						final SWTSkinObjectText soExpirey = (SWTSkinObjectText) skin.getSkinObject("register-expirey");
+    						if (soExpirey != null) {
+    							key[0].getControl().addListener(SWT.Modify, new Listener() {
+    								public void handleEvent(Event event) {
+    									soExpirey.setText("");
+    								}
+    							});
+
+    							int state = details.licence.getState();
+    							if (state == Licence.LS_CANCELLED) {
+    								soExpirey.setText(MessageText.getString("dlg.auth.enter.cancelled"));
+    							} else if (state == Licence.LS_REVOKED) {
+    								soExpirey.setText(MessageText.getString("dlg.auth.enter.revoked"));
+    							} else if (state == Licence.LS_ACTIVATION_DENIED) {
+    								soExpirey.setText(MessageText.getString("dlg.auth.enter.denied"));
+    							} else {
+    								long now = SystemTime.getCurrentTime();
+    								if (details.expiry < now && details.displayedExpiry > now) {
+    									soExpirey.setText(MessageText.getString("plus.notificaiton.OfflineExpiredEntry"));
+    								} else {
+        							soExpirey.setText(MessageText.getString("dlg.auth.enter.expiry",
+        									new String[] {
+        										DisplayFormatters.formatCustomDateOnly(details.displayedExpiry)
+        									}));
+    								}
+    							} 
+    						}
+    					}
+  					}
+  				}
+  			}
+  		});
+  
+  		entryWindow.open(new UserPrompterResultListener() {
+  			public void prompterClosed(int result) {
+  				entryWindow = null;
+  				if (result == SWT.OK) {
+  					try {
+  						Licence licence = featman.addLicence(key[0].getText());
+  						int initialState = licence.getState();
+  						if (initialState == Licence.LS_AUTHENTICATED) {
+  							if ( !licence.isFullyInstalled()){
+  								fml.licenceAdded(licence);	// open installing window
+  							}else{
+  								openLicenceSuccessWindow();
+  							}
+  						}else if (initialState == Licence.LS_PENDING_AUTHENTICATION ) {
+  							fml.licenceAdded(licence);	// open validating window
+  						} else if (initialState == Licence.LS_INVALID_KEY) {
+  							openLicenceFailedWindow(initialState, key[0].getText());
+  						} else if (initialState == Licence.LS_ACTIVATION_DENIED) {
+  							openLicenceActivationDeniedWindow(licence);
+  						} else if (initialState == Licence.LS_CANCELLED) {
+  							openLicenceCancelledWindow(licence);
+  						} else if (initialState == Licence.LS_REVOKED) {
+  							openLicenceRevokedWindow(licence);
+  						}
+  					} catch (Throwable e) {
+  						
+  						String s = Debug.getNestedExceptionMessage(e);
+  						
+  						MessageBoxShell mb = new MessageBoxShell(
+    							SWT.ICON_ERROR | SWT.OK,
+    							"Licence Addition Error",
+    							s );
+  						
+  						mb.open();
+  						
+  						Logger.log(new LogAlert(true, LogAlert.AT_ERROR, "Adding Licence",
+  								e));
+  					}
+  				}
+  			}
+  		});
+		} catch (Exception e) {
+			entryWindow = null;
+		}
+	}
+
+	public static void openLicenceSuccessWindow() {
+		if (!enabled) {
+			return;
+		}
+
+		if (hasFullLicence()) {
+			openFullLicenceSuccessWindow();
+		} else {
+			openTrialLicenceSuccessWindow();
+		}
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	private static void openTrialLicenceSuccessWindow() {
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.trial.success.subtitle"),
+				MessageText.getString("dlg.auth.trial.success.line1"), new String[] {
+					MessageText.getString("Button.goLibrary"),
+				}, 0);
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.burn.dlg.header");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.trial.success",
+						"dlg.register.trial.success", soExtra);
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 0) {
+					SBC_PlusFTUX.setSourceRef("dlg-trial-installed");
+
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY);
+				}
+			}
+		});
+	}
+
+	private static void openFullLicenceSuccessWindow() {
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.title"),
+				MessageText.getString("dlg.auth.success.line1"), new String[] {
+					MessageText.getString("Button.getstarted"),
+				}, 0);
+		box.setSubTitle(MessageText.getString("dlg.auth.success.subtitle"));
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.vp");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.success", "dlg.register.success",
+						soExtra);
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 0) {
+  				SBC_PlusFTUX.setSourceRef("dlg-plus-installed");
+
+  				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+				}
+			}
+		});
+	}
+	
+	public static void openLicenceRevokedWindow(final Licence licence) {
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.revoked"),
+				MessageText.getString("dlg.auth.revoked.line1"), new String[] {
+					MessageText.getString("Button.close"),
+				}, 0);
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.vp");
+		box.setTextIconResource("image.warn.big");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				SWTSkinObject so = skin.createSkinObject("dlg.register.revoked",
+						"dlg.register.revoked", soExtra);
+
+				SWTSkinObjectText soLink = (SWTSkinObjectText) skin.getSkinObject(
+						"link", so);
+				if (soLink != null) {
+					soLink.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+						public boolean urlClicked(URLInfo urlInfo) {
+							String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+									"licence_revoked.start?key="
+											+ UrlUtils.encode(licence.getKey()), true);
+							Utils.launch(url);
+							return true;
+						}
+					});
+				}
+			}
+		});
+
+		box.open(null);
+	}
+
+	public static void openLicenceActivationDeniedWindow(final Licence licence) {
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.denied"),
+				MessageText.getString("dlg.auth.denied.line1"), new String[] {
+					MessageText.getString("Button.close"),
+				}, 0);
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.vp");
+		box.setTextIconResource("image.warn.big");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				SWTSkinObject so = skin.createSkinObject("dlg.register.denied",
+						"dlg.register.denied", soExtra);
+
+				SWTSkinObjectText soLink = (SWTSkinObjectText) skin.getSkinObject(
+						"link", so);
+				if (soLink != null) {
+					soLink.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+						public boolean urlClicked(URLInfo urlInfo) {
+							String url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+									"licence_denied.start?key="
+											+ UrlUtils.encode(licence.getKey()), true);
+							Utils.launch(url);
+							return true;
+						}
+					});
+				}
+			}
+		});
+
+		box.open(null);
+	}
+
+	public static void openLicenceCancelledWindow(final Licence licence) {
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.cancelled"),
+				MessageText.getString("dlg.auth.cancelled.line1"), new String[] {
+					MessageText.getString("Button.close"),
+				}, 0);
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.vp");
+		box.setTextIconResource("image.warn.big");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				SWTSkinObject so = skin.createSkinObject("dlg.register.cancelled",
+						"dlg.register.cancelled", soExtra);
+			}
+		});
+
+		box.open(null);
+	}
+
+
+	protected static void openLicenceFailedWindow(int licenceState, String code) {
+		openLicenceEntryWindow(true, code);
+	}
+
+	public static void openLicenceValidatingWindow() {
+		if (!enabled || validatingBox != null) {
+			return;
+		}
+
+		validatingBox = new VuzeMessageBox(
+				MessageText.getString("dlg.auth.validating.subtitle"), null, null, 0);
+		validatingBox.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		validatingBox.setIconResource("image.vp");
+
+		validatingBox.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.validating",
+						"dlg.register.validating", soExtra);
+			}
+		});
+
+		validatingBox.open(
+			new UserPrompterResultListener()
+			{
+				public void 
+				prompterClosed(
+					int result ) 
+				{
+					validatingBox = null;
+				}
+			});
+	}
+
+	public static void closeLicenceValidatingWindow() {
+		if (validatingBox != null) {
+			validatingBox.close(0);
+			validatingBox = null;
+		}
+	}
+
+	public static void openStreamPlusWindow(final String referal) {
+		String msgidPrefix;
+		String buttonID;
+		long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryTimeStamp();
+		if (plusExpiryTimeStamp <= 0
+				|| plusExpiryTimeStamp >= SystemTime.getCurrentTime()) {
+			msgidPrefix = "dlg.stream.plus.";
+			buttonID = "Button.upgrade";
+		} else {
+			buttonID = "Button.renew";
+			msgidPrefix = "dlg.stream.plus.renew.";
+			if (!MessageText.keyExistsForDefaultLocale(msgidPrefix + "text")) {
+				msgidPrefix = "dlg.stream.plus.";
+			}
+		}
+		final String f_msgidPrefix = msgidPrefix;
+		final VuzeMessageBox box = new VuzeMessageBox(
+				MessageText.getString(msgidPrefix + "title"),
+				MessageText.getString(msgidPrefix + "text"), new String[] {
+					MessageText.getString(buttonID),
+					MessageText.getString("Button.cancel"),
+				}, 0);
+		box.setButtonVals(new Integer[] {
+			BUTTON_UPGRADE,
+			SWT.CANCEL
+		});
+
+		box.setSubTitle(MessageText.getString(msgidPrefix + "subtitle"));
+		box.addResourceBundle(FeatureManagerUI.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_streamplus");
+		box.setIconResource("image.header.streamplus");
+
+		box.setListener(new VuzeMessageBoxListener() {
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.stream.plus", "dlg.stream.plus", soExtra);
+				SWTSkinObject soSubText = skin.getSkinObject("trial-info", soExtra);
+				if (soSubText instanceof SWTSkinObjectText) {
+					((SWTSkinObjectText) soSubText).setTextID(f_msgidPrefix + "subtext");
+				}
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == BUTTON_UPGRADE) {
+					SBC_PlusFTUX.setSourceRef("dlg-stream" + (referal == null ? "" : "-" + referal));
+
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+				}
+			}
+		});
+	}
+	
+	public static String appendFeatureManagerURLParams(String url) {
+		long remainingUses = FeatureManagerUI.getRemaining();
+		long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryDisplayTimeStamp();
+		String plusRenewalCode = FeatureManagerUI.getPlusRenewalCode();
+
+		String newURL = url + (url.contains("?") ? "&" : "?");
+		newURL += "mode=" + FeatureManagerUI.getMode();
+		if (plusExpiryTimeStamp != 0) {
+			newURL += "&remaining_plus="
+					+ (plusExpiryTimeStamp - SystemTime.getCurrentTime());
+		}
+		newURL += "&remaining=" + remainingUses;
+		if (plusRenewalCode != null) {
+			newURL += "&renewal_code=" + plusRenewalCode;
+		}
+
+		return newURL;
+	}
+	
+	public static String getMode() {
+		boolean isFull = hasFullLicence();
+		boolean isTrial = hasFullBurn() && !isFull;
+		return isFull ? "plus" : isTrial ? "trial" : "free";
+	}
+	
+	public static long getPlusExpiryTimeStamp() {
+		licenceDetails fullFeatureDetails = getFullFeatureDetails();
+		if (fullFeatureDetails == null || fullFeatureDetails.expiry == 0) {
+			return 0;
+		}
+		return fullFeatureDetails.expiry;
+	}
+
+	public static long getPlusExpiryDisplayTimeStamp() {
+		licenceDetails fullFeatureDetails = getFullFeatureDetails();
+		if (fullFeatureDetails == null || fullFeatureDetails.expiry == 0) {
+			return 0;
+		}
+		return fullFeatureDetails.displayedExpiry;
+	}
+
+	public static String getPlusRenewalCode() {
+		licenceDetails fullFeatureDetails = getFullFeatureDetails();
+		if (fullFeatureDetails == null || fullFeatureDetails.expiry == 0) {
+			return null;
+		}
+
+		return fullFeatureDetails.getRenewalKey();
+	}
+
+	public static boolean hasFullLicence() {
+		if (featman == null) {
+			//Debug.out("featman null");
+			Set<String> featuresInstalled = UtilitiesImpl.getFeaturesInstalled();
+			return featuresInstalled.contains("dvdburn");
+		}
+		licenceDetails fullFeatureDetails = getFullFeatureDetails();
+		long now = SystemTime.getCurrentTime();
+		return fullFeatureDetails != null && fullFeatureDetails.expiry > now
+				&& fullFeatureDetails.displayedExpiry > now;
+	}
+
+	public static class licenceDetails {
+		public final Licence licence;
+		public long expiry;
+		public long displayedExpiry;
+
+		public licenceDetails(long expiry, long displayedExpiry, Licence licence) {
+			this.expiry = expiry;
+			this.displayedExpiry = displayedExpiry;
+			this.licence = licence;
+		}
+		
+		public String getRenewalKey() {
+			FeatureDetails[] features = licence.getFeatures();
+			if (features == null) {
+				return null;
+			}
+			for (FeatureDetails fd : features) {
+				Object property = fd.getProperty(FeatureDetails.PR_RENEWAL_KEY);
+				if (property instanceof String) {
+					return (String) property;
+				}
+			}
+			return null;
+		}
+	}
+
+	public static licenceDetails getFullFeatureDetails() {
+		if (featman == null) {
+			Debug.out("featman null");
+			return null;
+		}
+
+		TreeMap<Long, Object[]> mapOrder = new TreeMap<Long, Object[]>(
+				Collections.reverseOrder());
+		FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn");
+		// if any of the feature details are still valid, we have a full
+		for (FeatureDetails fd : featureDetails) {
+			Licence licence = fd.getLicence();
+			int state = licence.getState();
+			if (state == Licence.LS_ACTIVATION_DENIED) {
+				mapOrder.put(-1L, new Object[] { licence, Long.valueOf(0) });
+				continue;
+			} else if (state == Licence.LS_CANCELLED) {
+				mapOrder.put(-2L, new Object[] { licence, Long.valueOf(0) });
+				continue;
+			} else if (state == Licence.LS_INVALID_KEY) {
+				mapOrder.put(-3L, new Object[] { licence, Long.valueOf(0) });
+				continue;
+			} else if (state == Licence.LS_REVOKED) {
+				mapOrder.put(-4L, new Object[] { licence, Long.valueOf(0) });
+				continue;
+			} else if (state == Licence.LS_PENDING_AUTHENTICATION) {
+				mapOrder.put(-6L, new Object[] { licence, Long.valueOf(0) });
+				continue;
+			}
+
+			long now = SystemTime.getCurrentTime();
+			Long lValidUntil = (Long) fd.getProperty(FeatureDetails.PR_VALID_UNTIL);
+			Long lValidOfflineUntil = (Long) fd.getProperty(FeatureDetails.PR_OFFLINE_VALID_UNTIL);
+
+			if (lValidUntil == null && lValidOfflineUntil == null) {
+				continue;
+			}
+
+			long minValidUntil = -1;
+			long maxValidUntil = -1;
+			if (lValidUntil != null) {
+				minValidUntil = maxValidUntil = lValidUntil.longValue();
+				if (minValidUntil < now) {
+					mapOrder.put(minValidUntil, new Object[] { licence, Long.valueOf(minValidUntil) });
+					continue;
+				}
+			}
+			if (lValidOfflineUntil != null) {
+				long validOfflineUntil = lValidOfflineUntil.longValue();
+				if (validOfflineUntil < now) {
+					mapOrder.put(validOfflineUntil, new Object[] { licence, Long.valueOf(maxValidUntil) });
+					continue;
+				}
+				if (maxValidUntil == -1 || validOfflineUntil > maxValidUntil) {
+					maxValidUntil = validOfflineUntil;
+				}
+			}
+
+			mapOrder.put(maxValidUntil, new Object[] { licence, minValidUntil });
+		}
+
+		if (mapOrder.size() == 0) {
+			return null;
+		}
+
+		Long firstKey = mapOrder.firstKey();
+		Object[] objects = mapOrder.get(firstKey);
+		Licence licence = (Licence) objects[0];
+		return new licenceDetails(firstKey.longValue(), ((Long) objects[1]).longValue(), licence);
+	}
+	
+	public static boolean isTrialLicence(Licence licence) {
+		if (featman == null) {
+			return false;
+		}
+
+		// if any of the FeatureDetails is a trial, return true
+
+		boolean trial = false;
+		FeatureDetails[] featureDetails = licence.getFeatures();
+		for (FeatureDetails fd : featureDetails) {
+			trial = isTrial(fd);
+			if (trial) {
+				break;
+			}
+		}
+
+		return trial;
+	}
+
+	public static boolean isTrial(FeatureDetails fd) {
+		Long lIsTrial = (Long) fd.getProperty(FeatureDetails.PR_IS_TRIAL);
+		return lIsTrial == null ? false : lIsTrial.longValue() != 0;
+	}
+	
+	public static long getRemaining() {
+		FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn_trial");
+		if (featureDetails == null) {
+			return 0;
+		}
+		for (FeatureDetails fd : featureDetails) {
+			long remainingUses = getRemainingUses(fd);
+			if (remainingUses >= 0) {
+				return remainingUses;
+			}
+		}
+		return 0;
+	}
+
+	private static long getRemainingUses(FeatureDetails fd) {
+		if (fd == null) {
+			return 0;
+		}
+		Long lRemainingUses = (Long) fd.getProperty(FeatureDetails.PR_TRIAL_USES_REMAINING);
+		long remainingUses = lRemainingUses == null ? -1
+				: lRemainingUses.longValue();
+		return remainingUses;
+	}
+
+	/**
+	 * @return
+	 */
+	public static boolean hasFullBurn() {
+		
+		PluginInterface pi = PluginInitializer.getDefaultInterface().getPluginState().isInitialisationComplete()
+				? AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+						"azburn_v") : null;
+		if (pi == null) {
+			// maybe not added yet.. use featman
+			Set<String> featuresInstalled = UtilitiesImpl.getFeaturesInstalled();
+			return featuresInstalled.contains("dvdburn_trial") && !featuresInstalled.contains("dvdburn");
+		}
+		return pi.getPluginState().isOperational();
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/feature/FeatureManagerUIListener.java b/com/aelitis/azureus/ui/swt/feature/FeatureManagerUIListener.java
new file mode 100644
index 0000000..7ad332e
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/feature/FeatureManagerUIListener.java
@@ -0,0 +1,449 @@
+package com.aelitis.azureus.ui.swt.feature;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.PluginInterface;
+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.utils.*;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureManagerListener;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence;
+import org.gudy.azureus2.plugins.utils.FeatureManager.Licence.LicenceInstallationListener;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+
+import com.aelitis.azureus.activities.*;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.skin.SWTSkin;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.views.skin.*;
+
+public class FeatureManagerUIListener
+	implements FeatureManagerListener
+{
+	private final static boolean DEBUG = Constants.IS_CVS_VERSION;
+
+	private static final String ID_ACTIVITY_EXPIRING = "ExpiringEntry";
+	private static final String ID_ACTIVITY_OFFLINE = "OfflineExpiredEntry";
+	private static final String ID_ACTIVITY_EXPIRED = "ExpiredEntry";
+
+	private final FeatureManager featman;
+
+	private String pendingAuthForKey;
+	
+	private Map<String, Object[]> licence_map = new HashMap<String, Object[]>();
+
+	public FeatureManagerUIListener(FeatureManager featman) {
+		if (DEBUG) {
+			System.out.println("FEAT:");
+		}
+		this.featman = featman;
+	}
+
+	public void licenceAdded(Licence licence) {
+		updateUI();
+		
+		mapLicence( licence );
+		
+		if (DEBUG) {
+			System.out.println("FEAT: Licence " + licence.getKey() + " Added with state " + licence.getState());
+		}
+
+		if (licence.getState() == Licence.LS_PENDING_AUTHENTICATION) {
+			pendingAuthForKey = licence.getKey();
+			FeatureManagerUI.openLicenceValidatingWindow();
+		}
+
+		if (licence.isFullyInstalled()) {
+			return;
+		}else{
+			licence.retryInstallation();
+		}
+	}
+
+	public void licenceChanged(Licence licence) {
+		int state = licence.getState();
+
+		boolean stateChanged = true;
+
+		Licence lastLicence = mapLicence( licence );
+			
+		if (lastLicence != null) {
+			stateChanged = lastLicence.getState() != licence.getState();
+			
+			if ( 	( !stateChanged ) && 
+					licence.getState() == Licence.LS_AUTHENTICATED &&
+					lastLicence.isFullyInstalled() != licence.isFullyInstalled()){
+					
+					stateChanged = true;
+				}
+		} else {
+			// licenceChanged gets fired for all licences after listener is added
+			// (via code in FeatureManagerUI)
+			// skip case where licence is already cancelled
+			if (state == Licence.LS_CANCELLED || state == Licence.LS_REVOKED
+					|| state == Licence.LS_ACTIVATION_DENIED) {
+				stateChanged = false;
+			}
+		}
+
+		updateUI();
+		if (DEBUG) {
+			System.out.println("FEAT: License " + licence.getKey()
+					+ " State Changed: " + state + "; changed? " + stateChanged);
+		}
+		
+		if (!stateChanged) {
+			return;
+		}
+	
+		if (state == Licence.LS_PENDING_AUTHENTICATION) {
+			pendingAuthForKey = licence.getKey();
+			FeatureManagerUI.openLicenceValidatingWindow();
+		} else {
+			FeatureManagerUI.closeLicenceValidatingWindow();
+			if (state == Licence.LS_AUTHENTICATED) {
+				if (licence.getKey().equals(pendingAuthForKey)) {
+					if (licence.isFullyInstalled()) {
+						pendingAuthForKey = null;
+						FeatureManagerUI.openLicenceSuccessWindow();
+					} // else assumed install process is taking place
+				}
+			} else if (state == Licence.LS_INVALID_KEY) {
+				FeatureManagerUI.openLicenceFailedWindow(state, licence.getKey());
+				if (licence.getKey().equals(pendingAuthForKey)) {
+					pendingAuthForKey = null;
+				}
+			} else if (state == Licence.LS_REVOKED) {
+				FeatureManagerUI.openLicenceRevokedWindow(licence);
+			} else if (state == Licence.LS_ACTIVATION_DENIED) {
+				FeatureManagerUI.openLicenceActivationDeniedWindow(licence);
+			}
+		}
+	}
+
+	private Licence
+	mapLicence(
+		Licence		licence )
+	{
+		Licence existing_licence;
+		
+		LicenceInstallationListener	new_listener = null;
+		
+		synchronized ( licence_map ){
+			
+			String key = licence.getKey();
+			
+			Object[] entry = licence_map.get( key );
+					
+			if ( entry == null ){
+				
+				existing_licence = null;
+				
+				new_listener = 
+					new LicenceInstallationListener()
+					{
+						FeatureManagerInstallWindow install_window = null;
+	
+						public void start(String licence_key) {
+							if (DEBUG) {
+								System.out.println("FEATINST: START! " + licence_key);
+							}
+							try {
+								Licence licence = featman.addLicence(licence_key);
+	
+								install_window = new FeatureManagerInstallWindow(licence);
+		
+								install_window.open();
+	
+							} catch (PluginException e) {
+								Debug.out(e);
+							}
+						}
+	
+						public void reportProgress(String licenceKey, String install, int percent) {
+							if (DEBUG) {
+								System.out.println("FEATINST: " + install + ": " + percent);
+							}
+						}
+	
+						public void reportActivity(String licenceKey, String install,
+								String activity) {
+							if (DEBUG) {
+								System.out.println("FEAT: ACTIVITY: " + install + ": " + activity);
+							}
+						}
+	
+						public boolean alreadyFailing = false;
+						public void failed(String licenceKey, PluginException error) {
+							if (DEBUG) {
+								System.out.println("FEAT: FAIL: " + licenceKey + ": " + error.toString());
+							}
+		
+							if ( install_window != null ){
+								
+								install_window.close();
+							}
+							
+							if ( licenceKey.equals(pendingAuthForKey)){
+								
+								pendingAuthForKey = null;
+							}
+
+							if (alreadyFailing) {
+								return;
+							}
+							alreadyFailing = true;
+
+							String s = Debug.getNestedExceptionMessage(error);
+							
+							MessageBoxShell mb = new MessageBoxShell(
+									SWT.ICON_ERROR | SWT.OK,
+									"License Addition Error for " + licenceKey,
+									s );
+
+							mb.open( new UserPrompterResultListener() {
+								public void prompterClosed(int result) {
+									alreadyFailing = false;
+								}
+							} );
+						}
+	
+						public void complete(String licenceKey) {
+		
+							if ( licenceKey.equals(pendingAuthForKey)){
+	
+								pendingAuthForKey = null;
+								
+								FeatureManagerUI.openLicenceSuccessWindow();
+							}
+						}
+					};
+					
+				
+				licence_map.put( key, new Object[]{ licence, new_listener });
+				
+			}else{
+				
+				existing_licence = (Licence)entry[0];
+				
+				entry[0] = licence;
+			}
+		}
+
+		if ( new_listener != null ){
+			
+			licence.addInstallationListener( new_listener );
+		}	
+		
+		return( existing_licence );
+	}
+	
+	private void updateUI() {
+		PluginInterface plugin_interface = PluginInitializer.getDefaultInterface();
+
+		UIManager ui_manager = plugin_interface.getUIManager();
+
+		ui_manager.addUIListener(new UIManagerListener() {
+
+			public void UIDetached(UIInstance instance) {
+			}
+
+			public void UIAttached(UIInstance instance) {
+				if (instance instanceof UISWTInstance) {
+					_updateUI();
+				}
+			}
+		});
+	}
+
+	private void _updateUI() {
+		final boolean hasFullLicence = FeatureManagerUI.hasFullLicence();
+
+		try {
+			buildNotifications();
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+		
+		final SWTSkin skin = SWTSkinFactory.getInstance();
+		if (skin != null) {
+			SWTSkinObject soHeader = skin.getSkinObject("plus-header");
+			if (soHeader != null) {
+				soHeader.setVisible(hasFullLicence);
+			}
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+					uif.getMainShell().setText(hasFullLicence ? "Vuze Plus" : "Vuze");
+				}
+			});
+		}
+
+		UIFunctions uif = UIFunctionsManager.getUIFunctions();
+		MultipleDocumentInterface mdi = uif.getMDI();
+		if (mdi != null) {
+			MdiEntry entry = mdi.getEntry(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+			if (entry != null) {
+				entry.setTitleID(hasFullLicence ? "mdi.entry.plus.full"
+						: "mdi.entry.plus.free");
+				SBC_PlusFTUX view = (SBC_PlusFTUX) SkinViewManager.getByClass(SBC_PlusFTUX.class);
+				if (view != null) {
+					view.updateLicenceInfo();
+				}
+				SkinView[] views = SkinViewManager.getMultiByClass(SBC_BurnFTUX.class);
+				if (views != null) {
+					for (SkinView bview : views) {
+						((SBC_BurnFTUX) bview).updateLicenceInfo();
+					}
+				}
+			}
+		}
+	}
+
+	public static void buildNotifications() {
+		VuzeActivitiesManager.addListener(new VuzeActivitiesLoadedListener() {
+			public void vuzeActivitiesLoaded() {
+				_buildNotifications();
+			}
+		});
+	}
+
+	private static void _buildNotifications() {
+		long plusDisplayExpiryTimeStamp = FeatureManagerUI.getPlusExpiryDisplayTimeStamp();
+		long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryTimeStamp();
+		
+		if (plusExpiryTimeStamp <= 0) {
+			return;
+		}
+		
+		long msDisplayLeft = plusDisplayExpiryTimeStamp - SystemTime.getCurrentTime();
+		long daysDisplayLeft = (long) Math.ceil(msDisplayLeft / 86400000.0);
+		long msLeft = plusExpiryTimeStamp - SystemTime.getCurrentTime();
+		long daysLeft = (long) Math.ceil(msLeft / 86400000.0);
+
+		if (daysLeft > 30 || daysDisplayLeft > 30) {
+			VuzeActivitiesEntry entry1 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_EXPIRED);
+			VuzeActivitiesEntry entry2 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_EXPIRING);
+			VuzeActivitiesEntry entry3 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_OFFLINE);
+			if (entry1 != null || entry2 != null || entry3 != null) {
+				VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] {
+					entry1,
+					entry2,
+					entry3,
+				}, true);
+			}
+
+			return;
+		}
+		
+		
+		String s;
+		String id;
+		String ref = "plus_note_" + (daysDisplayLeft >= 0 ? "expiring_" : "expired_")
+				+ Math.abs(daysDisplayLeft);
+		String strA = "TARGET=\"" + MultipleDocumentInterface.SIDEBAR_SECTION_PLUS
+				+ "\" HREF=\"#" + ref + "\"";
+
+		if (daysLeft < 0 && daysDisplayLeft > 0) {
+			// if no days left but our display days > 0, that means we ran out
+			// of offline time and daysDisplayLeft is when the real license expires
+			VuzeActivitiesEntry entry1 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_EXPIRED);
+			VuzeActivitiesEntry entry2 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_EXPIRING);
+			if (entry1 != null || entry2 != null) {
+				VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] {
+					entry1,
+					entry2
+				}, true);
+			}
+
+			String msgID = "plus.notificaiton." + ID_ACTIVITY_OFFLINE;
+			s = MessageText.getString(msgID, new String[] {
+				"" + daysDisplayLeft,
+			});
+			id = ID_ACTIVITY_OFFLINE;
+
+		} else {
+			VuzeActivitiesEntry entry3 = VuzeActivitiesManager.getEntryByID(ID_ACTIVITY_OFFLINE);
+			if (entry3 != null) {
+				VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] {
+					entry3,
+				}, true);
+			}
+
+			if (daysDisplayLeft > 0) {
+  			String msgID = "plus.notificaiton." + ID_ACTIVITY_EXPIRING
+  					+ (daysDisplayLeft == 1 ? ".s" : ".p");
+  			s = MessageText.getString(msgID, new String[] {
+  				"" + daysDisplayLeft,
+  				strA
+  			});
+  			id = ID_ACTIVITY_EXPIRING;
+  		} else {
+  			String msgID = "plus.notificaiton." + ID_ACTIVITY_EXPIRED
+  					+ (daysDisplayLeft == -1 ? ".s" : ".p");
+  			s = MessageText.getString(msgID, new String[] {
+  				"" + -daysDisplayLeft,
+  				strA
+  			});
+  			id = ID_ACTIVITY_EXPIRED;
+  		}
+		}
+		VuzeActivitiesEntry entry = VuzeActivitiesManager.getEntryByID(id);
+		if (entry == null) {
+			boolean existed = VuzeActivitiesManager.isEntryIdRemoved(id);
+			if (existed) {
+				return;
+			}
+
+			entry = new VuzeActivitiesEntry(SystemTime.getCurrentTime(), s,
+					VuzeActivitiesConstants.TYPEID_VUZENEWS);
+			entry.setID(id);
+			entry.setIconID("image.sidebar.plus");
+
+			if (daysLeft < 0 && daysDisplayLeft < 0) {
+				UIFunctionsManager.getUIFunctions().getMDI().showEntryByID(
+						MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+			}
+		} else {
+			entry.setText(s);
+			entry.setTimestamp(SystemTime.getCurrentTime());
+		}
+		VuzeActivitiesManager.addEntries(new VuzeActivitiesEntry[] {
+			entry
+		});
+	}
+
+	public void licenceRemoved(Licence licence) {
+		Object[] entry;
+		
+		synchronized( licence_map ){
+			
+			entry = licence_map.remove(licence.getKey());
+		}
+
+		if ( entry != null ){
+			
+			licence.removeInstallationListener( (LicenceInstallationListener)entry[1] );
+		}
+		
+		updateUI();
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java b/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
index 7ba23fa..90c26eb 100644
--- a/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
+++ b/com/aelitis/azureus/ui/swt/imageloader/ImageLoader.java
@@ -76,7 +76,7 @@ public class ImageLoader
 
 	public static Image noImage;
 
-	private final ConcurrentHashMap<String, ImageLoaderRefInfo> mapImages;
+	private final ConcurrentHashMap<String, ImageLoaderRefInfo> _mapImages;
 
 	private final ArrayList<String> notFound;
 
@@ -91,16 +91,16 @@ public class ImageLoader
 	private File cache_dir = new File(SystemProperties.getUserPath(), "cache" );
 	
 
-	public static ImageLoader getInstance() {
-		if (ImageLoader.instance == null) {
-			ImageLoader.instance = new ImageLoader(Display.getDefault(), null);
+	public static synchronized ImageLoader getInstance() {
+		if (instance == null) {
+			instance = new ImageLoader(Display.getDefault(), null);
 			// always add az2 icons to instance
 			SkinPropertiesImpl skinProperties = new SkinPropertiesImpl(
 					ImageRepository.class.getClassLoader(),
 					"org/gudy/azureus2/ui/icons/", "icons.properties");
-			ImageLoader.instance.addSkinProperties(skinProperties);
+			instance.addSkinProperties(skinProperties);
 		}
-		return ImageLoader.instance;
+		return instance;
 	}
 
 	public ImageLoader(/*ClassLoader classLoader,*/Display display,
@@ -118,7 +118,7 @@ public class ImageLoader
 			}
 		}
 		
-		mapImages = new ConcurrentHashMap<String, ImageLoaderRefInfo>();
+		_mapImages = new ConcurrentHashMap<String, ImageLoaderRefInfo>();
 		notFound = new ArrayList<String>();
 		this.display = display;
 		this.skinProperties = new CopyOnWriteArrayList<SkinProperties>();
@@ -158,6 +158,13 @@ public class ImageLoader
 			if (sKey.endsWith(sSuffix)) {
 				//System.out.println("YAY " + sSuffix + " for " + sKey);
 				String sParentName = sKey.substring(0, sKey.length() - sSuffix.length());
+				/*
+				Image[] images = getImages(sParentName);
+				if (images != null && images.length > 0 && isRealImage(images[0])) {
+					return images;
+				}
+				*/
+				/**/
 				String[] sParentFiles = null;
 				ClassLoader cl = null;
 				for (SkinProperties sp : skinProperties) {
@@ -195,6 +202,7 @@ public class ImageLoader
 						return images;
 					}
 				}
+				/**/
 			}
 		}
 
@@ -218,9 +226,14 @@ public class ImageLoader
 
 		int splitX = 0;
 		int locationStart = 0;
+		int useIndex = -1; // all
 		if (values[0].equals("multi") && values.length > 2) {
 			splitX = Integer.parseInt(values[1]);
 			locationStart = 2;
+		} else if (values[0].equals("multi-index") && values.length > 3) {
+			splitX = Integer.parseInt(values[1]);
+			useIndex = Integer.parseInt(values[2]);
+			locationStart = 3;
 		}
 
 		if (locationStart == 0 || splitX <= 0) {
@@ -240,38 +253,148 @@ public class ImageLoader
 				}
 
 				if (images[i] == null) {
-					images[i] = getNoImage();
+					images[i] = getNoImage( sKey );
 				}
 			}
 		} else {
 			Image image = null;
+			
+			String image_key = null;	// if image in repository then this will be non-null
+
 			String origFile = values[locationStart];
 			int index = origFile.lastIndexOf('.');
+						
 			if (index > 0) {
-				String sTryFile = origFile.substring(0, index) + suffix
-						+ origFile.substring(index);
-				image = loadImage(display, cl, sTryFile, sKey);
-
-				if (image == null) {
-					sTryFile = origFile.substring(0, index) + suffix.replace('-', '_')
+				if (useIndex == -1) {
+					String sTryFile = origFile.substring(0, index) + suffix
 							+ origFile.substring(index);
 					image = loadImage(display, cl, sTryFile, sKey);
+
+						// not in repo
+					
+					if (image == null) {
+						sTryFile = origFile.substring(0, index) + suffix.replace('-', '_')
+								+ origFile.substring(index);
+						image = loadImage(display, cl, sTryFile, sKey);
+						
+							// not in repo
+					}
+				} else {
+					String sTryFile = origFile.substring(0, index) + suffix
+							+ origFile.substring(index);
+
+						// check the cache to see if full image is in there
+						
+					image = getImageFromMap( sTryFile );
+					
+					if ( image == null ){
+						
+						image = loadImage(display, cl, sTryFile, sTryFile);
+						
+						if ( isRealImage(image)){
+							
+							image_key = sTryFile;
+							
+							addImage(image_key, image);
+							
+						} else if (sTryFile.matches(".*[-_]disabled.*")) {
+							
+							String sTryFileNonDisabled = sTryFile.replaceAll("[-_]disabled", "");
+							
+							image = getImageFromMap(sTryFileNonDisabled);
+							
+							if (!isRealImage(image)) {
+																
+								image = loadImage(display, cl, sTryFileNonDisabled,
+										sTryFileNonDisabled);
+								
+								if ( isRealImage(image)) {
+									
+									addImage(sTryFileNonDisabled, image);
+						
+								}
+							}
+							
+							if ( isRealImage(image)){
+																
+								image = fadeImage(image);
+								
+								image_key = sTryFile;
+								
+								addImage(image_key, image);
+								
+								releaseImage(sTryFileNonDisabled);
+							}
+						}
+					}else{
+						
+						image_key = sTryFile;
+					}
 				}
 			}
-			if (image == null) {
-				image = loadImage(display, cl, values[locationStart], sKey);
+			
+			if ( !isRealImage(image)) {
+				
+				String	temp_key = sKey + "-[multi-load-temp]";
+				
+				image = getImageFromMap( temp_key );
+				
+				if ( isRealImage(image)){
+					
+					image_key = temp_key;
+					
+				}else{
+					
+					image = loadImage(display, cl, values[locationStart], sKey);
+					
+					if ( isRealImage(image)) {
+						
+						image_key = temp_key;
+						
+						addImage( image_key, image );
+					}
+				}
 			}
 
-			if (image != null) {
+			if (isRealImage(image)) {
 				Rectangle bounds = image.getBounds();
-				images = new Image[(bounds.width + splitX - 1) / splitX];
-				for (int i = 0; i < images.length; i++) {
-					Image imgBG = Utils.createAlphaImage(display, splitX, bounds.height,
-							(byte) 0);
-					images[i] = Utils.blitImage(display, image, new Rectangle(i * splitX,
-							0, splitX, bounds.height), imgBG, new Point(0, 0));
+				if (useIndex == -1) {
+					images = new Image[(bounds.width + splitX - 1) / splitX];
+					for (int i = 0; i < images.length; i++) {
+						Image imgBG = Utils.createAlphaImage(display, splitX, bounds.height,
+								(byte) 0);
+						int pos = i * splitX;
+						try {
+							images[i] = Utils.blitImage(display, image, new Rectangle(pos, 0,
+									Math.min(splitX, bounds.width - pos), bounds.height), imgBG,
+									new Point(0, 0));
+						} catch (Exception e) {
+							Debug.out(e);
+						}
+						imgBG.dispose();
+					}
+				} else {
+					images = new Image[1];
+					Image imgBG = Utils.createAlphaImage(display, splitX, bounds.height, (byte) 0);
+					try {
+						int pos = useIndex * splitX;
+						images[0] = Utils.blitImage(display, image, new Rectangle(pos, 0,
+								Math.min(splitX, bounds.width - pos), bounds.height), imgBG,
+								new Point(0, 0));
+					} catch (Exception e) {
+						Debug.out(e);
+					}
 					imgBG.dispose();
 				}
+
+				if ( image_key != null ){
+					
+					releaseImage(image_key);
+					
+				}else if ( image != null ){
+					
+					image.dispose();
+				}
 			}
 		}
 
@@ -281,7 +404,7 @@ public class ImageLoader
 	private Image loadImage(Display display, ClassLoader cl, String res,
 			String sKey) {
 		Image img = null;
-
+		
 		//System.out.println("LoadImage " + sKey + " - " + res);
 		if (res == null) {
 			for (int i = 0; i < sSuffixChecks.length; i++) {
@@ -331,39 +454,21 @@ public class ImageLoader
 					InputStream is = cl.getResourceAsStream(res);
 					if (is != null) {
 						img = new Image(display, is);
+						
+						//System.out.println("Loaded image from " + res + " via " + Debug.getCompressedStackTrace());
+						is.close();
 					}
 				}
 
 				if (img == null) {
-					if (sKey.endsWith("-disabled") || sKey.endsWith("_disabled")) {
+					// don't do on sKey.endsWith("-disabled") because caller parseValueString
+					// requires a failure so it can retry with _disabled.  If that fails,
+					// we'll get here (stupid, I know)
+					if (res.contains("_disabled.")) {
 						String id = sKey.substring(0, sKey.length() - 9);
 						Image imgToFade = getImage(id);
 						if (isRealImage(imgToFade)) {
-							ImageData imageData = imgToFade.getImageData();
-							img = new Image(display, imageData);
-							// decrease alpha
-							if (imageData.alphaData != null) {
-								if (disabledOpacity == -1) {
-									for (int i = 0; i < imageData.alphaData.length; i++) {
-										imageData.alphaData[i] = (byte) ((imageData.alphaData[i] & 0xff) >> 3);
-									}
-								} else {
-									for (int i = 0; i < imageData.alphaData.length; i++) {
-										imageData.alphaData[i] = (byte) ((imageData.alphaData[i] & 0xff)
-												* disabledOpacity / 100);
-									}
-								}
-								img = new Image(display, imageData);
-							} else {
-								Rectangle bounds = imgToFade.getBounds();
-								Image bg = Utils.createAlphaImage(display, bounds.width,
-										bounds.height, (byte) 0);
-
-								img = Utils.renderTransparency(display, bg, imgToFade,
-										new Point(0, 0), disabledOpacity == -1 ? 64
-												: disabledOpacity * 255 / 100);
-								bg.dispose();
-							}
+							img = fadeImage(imgToFade);
 						}
 						releaseImage(id);
 					}else if (sKey.endsWith("-gray")) {
@@ -385,14 +490,43 @@ public class ImageLoader
 		return img;
 	}
 
+	private Image fadeImage(Image imgToFade) {
+		ImageData imageData = imgToFade.getImageData();
+		Image img;
+		// decrease alpha
+		if (imageData.alphaData != null) {
+			if (disabledOpacity == -1) {
+				for (int i = 0; i < imageData.alphaData.length; i++) {
+					imageData.alphaData[i] = (byte) ((imageData.alphaData[i] & 0xff) >> 3);
+				}
+			} else {
+				for (int i = 0; i < imageData.alphaData.length; i++) {
+					imageData.alphaData[i] = (byte) ((imageData.alphaData[i] & 0xff)
+							* disabledOpacity / 100);
+				}
+			}
+			img = new Image(display, imageData);
+		} else {
+			Rectangle bounds = imgToFade.getBounds();
+			Image bg = Utils.createAlphaImage(display, bounds.width,
+					bounds.height, (byte) 0);
+
+			img = Utils.renderTransparency(display, bg, imgToFade,
+					new Point(0, 0), disabledOpacity == -1 ? 64
+							: disabledOpacity * 255 / 100);
+			bg.dispose();
+		}
+		return img;
+	}
+
 	public void unLoadImages() {
 		if (DEBUG_UNLOAD) {
-			for (String key : mapImages.keySet()) {
-				Image[] images = mapImages.get(key).getImages();
+			for (String key : _mapImages.keySet()) {
+				Image[] images = _mapImages.get(key).getImages();
 				if (images != null) {
 					for (int i = 0; i < images.length; i++) {
 						Image image = images[i];
-						if (image != null && !image.isDisposed()) {
+						if (isRealImage(image)) {
 							System.out.println("dispose " + image + ";" + key);
 							image.dispose();
 						}
@@ -400,12 +534,12 @@ public class ImageLoader
 				}
 			}
 		} else {
-			for (ImageLoaderRefInfo imageInfo : mapImages.values()) {
+			for (ImageLoaderRefInfo imageInfo : _mapImages.values()) {
 				Image[] images = imageInfo.getImages();
 				if (images != null) {
 					for (int i = 0; i < images.length; i++) {
 						Image image = images[i];
-						if (image != null && !image.isDisposed()) {
+						if (isRealImage(image)) {
 							image.dispose();
 						}
 					}
@@ -414,23 +548,94 @@ public class ImageLoader
 		}
 	}
 
-	public Image[] getImages(String sKey) {
-		if (!Utils.isThisThreadSWT()) {
-			Debug.out("getImages called on non-SWT thread");
+	private ImageLoaderRefInfo
+	getRefInfoFromImageMap(
+		String		key )
+	{
+		return( _mapImages.get(key));
+	}
+	
+	private void
+	putRefInfoToImageMap(
+		String				key,
+		ImageLoaderRefInfo	info )
+	{
+		ImageLoaderRefInfo existing = _mapImages.put( key, info );
+		
+		if ( existing != null ){
+			
+			if ( existing.getImages().length > 0 ){
+				
+				Debug.out( "P: existing found! " + key + " -> " + existing.getString());
+			}
+		}
+	}
+	
+	private ImageLoaderRefInfo
+	putIfAbsentRefInfoToImageMap(
+		String				key,
+		ImageLoaderRefInfo	info )
+	{
+		ImageLoaderRefInfo x = _mapImages.putIfAbsent( key, info );
+		
+		if ( x != null ){
+			
+			if ( x.getImages().length > 0 ){
+				
+				Debug.out( "PIA: existing found! " + key + " -> " + x.getString());
+			}
+		}
+		
+		return( x );
+	}
+	
+	protected Image getImageFromMap(String sKey) {
+		Image[] imagesFromMap = getImagesFromMap(sKey);
+		if (imagesFromMap.length == 0) {
+			return null;
+		}
+		return imagesFromMap[0];
+	}
+
+	protected Image[] getImagesFromMap(String sKey) {
+		if (sKey == null) {
 			return new Image[0];
 		}
+
+		ImageLoaderRefInfo imageInfo = getRefInfoFromImageMap( sKey );
+		if (imageInfo != null && imageInfo.getImages() != null) {
+			imageInfo.addref();
+			if (DEBUG_REFCOUNT) {
+				logRefCount( sKey, imageInfo, true );
+			}
+			return imageInfo.getImages();
+		}
+
+		return new Image[0];
+	}
+
+	public Image[] getImages(String sKey) {
 		//System.out.println("getImages " + sKey);
 		if (sKey == null) {
 			return new Image[0];
 		}
+		
+		if (!Utils.isThisThreadSWT()) {
+			Debug.out("getImages called on non-SWT thread");
+			return new Image[0];
+		}
 
-		ImageLoaderRefInfo imageInfo = mapImages.get(sKey);
+		// ugly hack to show sidebar items that are disabled
+		// note this messes up refcount (increments but doesn't decrement)
+		if (sKey.startsWith("http://") && sKey.endsWith("-gray")) {
+			sKey = sKey.substring(0, sKey.length() - 5);
+		}
+
+		ImageLoaderRefInfo imageInfo = getRefInfoFromImageMap(sKey);
 		if (imageInfo != null && imageInfo.getImages() != null) {
 			imageInfo.addref();
 			if (DEBUG_REFCOUNT) {
-				System.out.println("ImageLoader: ++ refcount of " + sKey + " now "
-						+ imageInfo.getRefCount() + " via "
-						+ Debug.getCompressedStackTrace());
+				logRefCount( sKey, imageInfo, true );
 			}
 			return imageInfo.getImages();
 		}
@@ -491,14 +696,18 @@ public class ImageLoader
 
 			for (int i = 0; i < images.length; i++) {
 				if (images[i] == null) {
-					images[i] = getNoImage();
+					images[i] = getNoImage( sKey );
 				}
 			}
 		} else {
 			images = parseValuesString(cl, sKey, locations, "");
 		}
 
-		mapImages.put(sKey, new ImageLoaderRefInfo(images));
+		ImageLoaderRefInfo info = new ImageLoaderRefInfo(images);
+		putRefInfoToImageMap(sKey, info );
+		if (DEBUG_REFCOUNT) {
+			logRefCount( sKey, info, true );
+		}
 
 		return images;
 	}
@@ -506,7 +715,7 @@ public class ImageLoader
 	public Image getImage(String sKey) {
 		Image[] images = getImages(sKey);
 		if (images == null || images.length == 0 || images[0].isDisposed()) {
-			return getNoImage();
+			return getNoImage( sKey );
 		}
 		return images[0];
 	}
@@ -515,7 +724,7 @@ public class ImageLoader
 		if (sKey == null) {
 			return 0;
 		}
-		ImageLoaderRefInfo imageInfo = mapImages.get(sKey);
+		ImageLoaderRefInfo imageInfo = getRefInfoFromImageMap(sKey);
 		if (imageInfo != null) {
 			imageInfo.unref();
 			if (false && imageInfo.getRefCount() < 0) {
@@ -530,9 +739,7 @@ public class ImageLoader
 										+ (images[0] == noImage)))));
 			}
 			if (DEBUG_REFCOUNT) {
-				System.out.println("ImageLoader: -- refcount of " + sKey + " now "
-						+ imageInfo.getRefCount() + " via "
-						+ Debug.getCompressedStackTrace());
+				logRefCount( sKey, imageInfo, false );
 			}
 			return imageInfo.getRefCount();
 			// TODO: cleanup?
@@ -554,7 +761,7 @@ public class ImageLoader
 			Debug.out("addImage called on non-SWT thread");
 			return;
 		}
-		ImageLoaderRefInfo existing = mapImages.putIfAbsent(key,
+		ImageLoaderRefInfo existing = putIfAbsentRefInfoToImageMap(key,
 				new ImageLoaderRefInfo(image));
 		if (existing != null) {
 			// should probably fail if refcount > 0
@@ -562,15 +769,62 @@ public class ImageLoader
 				image
 			});
 			existing.addref();
+			if (DEBUG_REFCOUNT) {
+				logRefCount( key, existing, true );
+			}
 		}
 	}
 
+	public void addImage(String key, Image[] images) {
+		if (!Utils.isThisThreadSWT()) {
+			Debug.out("addImage called on non-SWT thread");
+			return;
+		}
+		ImageLoaderRefInfo existing = putIfAbsentRefInfoToImageMap(key,
+				new ImageLoaderRefInfo(images));
+		if (existing != null) {
+			// should probably fail if refcount > 0
+			existing.setImages(images);
+			existing.addref();
+			if (DEBUG_REFCOUNT) {
+				logRefCount( key, existing, true );
+			}
+		}
+	}
+	
+	private void
+	logRefCount(
+		String				key,
+		ImageLoaderRefInfo	info,
+		boolean				inc )
+	{
+		if ( true ){
+			return;
+		}
+		if ( inc ){
+			System.out.println("ImageLoader: ++ refcount to "
+					+ info.getRefCount() + " for " + key + " via "
+					+ Debug.getCompressedStackTraceSkipFrames(1));
+		}else{
+			System.out.println("ImageLoader: -- refcount to "
+					+ info.getRefCount() + " for " + key + " via "
+					+ Debug.getCompressedStackTraceSkipFrames(1));
+		}
+	}
+	
+	/*
+	public void removeImage(String key) {
+		// EEP!
+		mapImages.remove(key);
+	}
+	*/
+	
 	public void addImageNoDipose(String key, Image image) {
 		if (!Utils.isThisThreadSWT()) {
 			Debug.out("addImageNoDispose called on non-SWT thread");
 			return;
 		}
-		ImageLoaderRefInfo existing = mapImages.putIfAbsent(key,
+		ImageLoaderRefInfo existing = putIfAbsentRefInfoToImageMap(key,
 				new ImageLoaderRefInfo(image));
 		if (existing != null) {
 			existing.setNonDisposable();
@@ -579,10 +833,18 @@ public class ImageLoader
 				image
 			});
 			existing.addref();
+			if (DEBUG_REFCOUNT) {
+				logRefCount( key, existing, true );
+			}
 		}
 	}
 
-	private static Image getNoImage() {
+	private static Image getNoImage( String key ) {
+		/*
+		if ( key != null ){
+			System.out.println( "Missing image: " + key );
+		}
+		*/
 		if (noImage == null) {
 			Display display = Display.getDefault();
 			final int SIZE = 10;
@@ -599,10 +861,17 @@ public class ImageLoader
 
 	public boolean imageExists(String name) {
 		boolean exists = isRealImage(getImage(name));
-		releaseImage(name);
+		//if (exists) {	// getImage prety much always adds a ref for the 'name' so make sure
+						// we do the corresponding unref here
+			releaseImage(name);
+		//}
 		return exists;
 	}
 
+	public boolean imageAdded_NoSWT(String name) {
+		return _mapImages.containsKey(name);
+	}
+	
 	public boolean imageAdded(String name) {
 		Image[] images = getImages(name);
 		boolean added = images != null && images.length > 0;
@@ -611,7 +880,13 @@ public class ImageLoader
 	}
 
 	public static boolean isRealImage(Image image) {
-		return image != null && image != getNoImage() && !image.isDisposed();
+		if ( image == null || image.isDisposed() ){
+			return( false );
+		}
+		if ( noImage != null ){
+			return( image != noImage );
+		}
+		return( image != getNoImage( null ));
 	}
 
 	public int getAnimationDelay(String sKey) {
@@ -657,7 +932,7 @@ public class ImageLoader
 							is.close();
 						} catch (IOException e) {
 						}
-						mapImages.put(url, new ImageLoaderRefInfo(image));
+						putRefInfoToImageMap(url, new ImageLoaderRefInfo(image));
 						l.imageDownloaded(image, true);
 						return image;
 					} finally {
@@ -677,6 +952,13 @@ public class ImageLoader
 					public void imageDownloaded(final byte[] imageBytes) {
 						Utils.execSWTThread(new AERunnable() {
 							public void runSupport() {
+									// no synchronization here - might have already been
+									// downloaded
+								if (imageExists(url)) {
+									Image image = getImage(url);
+									l.imageDownloaded(image, false);
+									return;
+								}
 								FileUtil.writeBytesAsFile(cache_file.getAbsolutePath(), imageBytes);
 								cached_resources.add( cache_key );
 								InputStream is = new ByteArrayInputStream(imageBytes);
@@ -685,7 +967,7 @@ public class ImageLoader
 									is.close();
 								} catch (IOException e) {
 								}
-								mapImages.put(url, new ImageLoaderRefInfo(image));
+								putRefInfoToImageMap(url, new ImageLoaderRefInfo(image));
 								l.imageDownloaded(image, false);
 							}
 						});
@@ -715,8 +997,8 @@ public class ImageLoader
 			try {
 				writer.println("Non-Disposable:");
 				writer.indent();
-				for (String key : mapImages.keySet()) {
-					ImageLoaderRefInfo info = mapImages.get(key);
+				for (String key : _mapImages.keySet()) {
+					ImageLoaderRefInfo info = _mapImages.get(key);
 					if (!info.isNonDisposable()) {
 						continue;
 					}
@@ -726,8 +1008,8 @@ public class ImageLoader
 				writer.exdent();
 				writer.println("Disposable:");
 				writer.indent();
-				for (String key : mapImages.keySet()) {
-					ImageLoaderRefInfo info = mapImages.get(key);
+				for (String key : _mapImages.keySet()) {
+					ImageLoaderRefInfo info = _mapImages.get(key);
 					if (info.isNonDisposable()) {
 						continue;
 					}
@@ -800,20 +1082,23 @@ public class ImageLoader
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				int numRemoved = 0;
-				for (Iterator<String> iter = mapImages.keySet().iterator(); iter.hasNext();) {
+				for (Iterator<String> iter = _mapImages.keySet().iterator(); iter.hasNext();) {
 					String key = iter.next();
-					ImageLoaderRefInfo info = mapImages.get(key);
+					ImageLoaderRefInfo info = _mapImages.get(key);
 
 					// no one can addref in between canDispose and dispose because
 					// all our addrefs are in SWT threads.
 					if (info != null && info.canDispose()) {
+						if (DEBUG_UNLOAD) {
+							System.out.println("dispose " + key);
+						}
 						iter.remove();
 						numRemoved++;
 
 						Image[] images = info.getImages();
 						for (int j = 0; j < images.length; j++) {
 							Image image = images[j];
-							if (image != null && !image.isDisposed()) {
+							if (isRealImage(image)) {
 								image.dispose();
 							}
 						}
@@ -840,7 +1125,7 @@ public class ImageLoader
 		});
 	}
 
-	public void setButtonImage(Button btn, final String key) {
+	public Image setButtonImage(Button btn, final String key) {
 		Image bg = getImage(key);
 		btn.setImage(bg);
 		btn.addDisposeListener(new DisposeListener() {
@@ -848,6 +1133,8 @@ public class ImageLoader
 				releaseImage(key);
 			}
 		});
+		
+		return( bg );
 	}
 
 	public void setBackgroundImage(Control control, final String key) {
diff --git a/com/aelitis/azureus/ui/swt/imageloader/ImageLoaderRefInfo.java b/com/aelitis/azureus/ui/swt/imageloader/ImageLoaderRefInfo.java
index c3f76a9..4c3ef5d 100644
--- a/com/aelitis/azureus/ui/swt/imageloader/ImageLoaderRefInfo.java
+++ b/com/aelitis/azureus/ui/swt/imageloader/ImageLoaderRefInfo.java
@@ -84,4 +84,28 @@ public class ImageLoaderRefInfo
 	protected void setImages(Image[] images) {
 		this.images = images;
 	}
+	
+	protected String
+	getString()
+	{
+		String img_str = "";
+		
+		for ( Image i: images ){
+		
+			String s;
+			
+			if ( i == null ){
+				
+				s = "null";
+				
+			}else{
+				
+				s = i.toString() + ", disp=" + i.isDisposed();
+			}
+			
+			img_str += (img_str.length()==0?"":",") + s;
+		}
+		
+		return( "rc=" + refcount + ", images=[" + img_str + "]" );
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayout.java b/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayout.java
deleted file mode 100644
index 56ca3a5..0000000
--- a/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayout.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.aelitis.azureus.ui.swt.layout;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Layout;
-
-public class SimpleReorderableListLayout extends Layout {
-	
-	public int margin;
-
-	public boolean wrap;
-	public boolean center;
-	
-	public int borderW = 3;
-	public int borderH = 3;
-	
-	private int itemsPerRow;
-	private int maxHeight = 0;
-	private int maxWidth = 0;
-	
-	private int extraSpacing;
-	
-	private int previouswHint = SWT.DEFAULT;
-	
-	private boolean cached = false;
-	private Point cachedSize = null;
-	
-	protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
-		if(flushCache || ! cached || cachedSize == null) {
-			
-			Control[] controls = composite.getChildren();
-			
-			
-			for(int i = 0 ; i < controls.length ; i++) {
-				Object layoutData = controls[i].getLayoutData();
-				if(layoutData != null && layoutData instanceof SimpleReorderableListLayoutData) {
-					SimpleReorderableListLayoutData sData = (SimpleReorderableListLayoutData) layoutData;
-					if(sData.height > maxHeight) maxHeight = sData.height;
-					if(sData.width > maxWidth) maxWidth = sData.width;
-				}
-			}
-			
-			
-			if((wHint != SWT.DEFAULT || previouswHint != SWT.DEFAULT) && wrap) {
-				if(wHint != SWT.DEFAULT) {
-					previouswHint  = wHint;
-				} else {
-					wHint = previouswHint;
-				}
-				itemsPerRow = 1;
-				int width = 2 * borderW + maxWidth;
-				while(width < wHint) {
-					width += margin + maxWidth;
-					if(width < wHint) {
-						itemsPerRow++;
-					}
-				}
-				if(center) {
-					width = 2 * borderW + (margin + maxWidth) * itemsPerRow - margin;
-					extraSpacing = itemsPerRow == 0 ? 0 : (wHint - width) / (itemsPerRow);
-				} else {
-					extraSpacing = 0;
-				}
-			} else {
-				itemsPerRow = controls.length;
-			}
-			
-			//Avoid dividing by 0 when there are no items
-			int nbRows = itemsPerRow > 0 ? (controls.length+itemsPerRow-1) / itemsPerRow : 1;
-			
-			cached = true;
-			cachedSize = new Point(2 * borderW + (maxWidth+margin) * itemsPerRow - margin, 2 * borderH + (margin + maxHeight) * nbRows - margin);
-			
-		} 
-		
-		return cachedSize;
-		
-	}
-
-	protected void layout(Composite composite, boolean flushCache) {
-		
-		Control[] controls = composite.getChildren();
-		List sortedControls = new ArrayList(controls.length);
-		for(int i = 0 ; i < controls.length ; i++) {
-			sortedControls.add(controls[i]);
-		}
-		
-		Collections.sort(sortedControls,new Comparator() {
-			public int compare(Object o1, Object o2) {
-				Control c1 = (Control) o1;
-				Control c2 = (Control) o2;
-				Object layoutData1 = c1.getLayoutData();
-				Object layoutData2 = c2.getLayoutData();
-				if(layoutData1 == null || ! (layoutData1 instanceof SimpleReorderableListLayoutData) ) return 0;
-				if(layoutData2 == null || ! (layoutData2 instanceof SimpleReorderableListLayoutData) ) return 0;
-				SimpleReorderableListLayoutData data1 = (SimpleReorderableListLayoutData) layoutData1;
-				SimpleReorderableListLayoutData data2 = (SimpleReorderableListLayoutData) layoutData2;
-				return data1.position - data2.position;
-			}
-		});
-		
-		for(int i = 0 ; i < sortedControls.size() ; i++) {
-			int xn = i % itemsPerRow;
-			int yn = i / itemsPerRow;
-			Control control = (Control) sortedControls.get(i);
-			//int x = borderW + (margin + maxWidth + extraSpacing) * xn + extraSpacing;
-			int x = borderW + (margin + maxWidth + extraSpacing) * xn;
-			int y = borderH + (margin + maxHeight) * yn;
-			control.setLocation(x,y);
-			//control.setBounds(x,y,maxWidth,maxHeight);
-			control.setBounds(x,y,maxWidth + extraSpacing,maxHeight);
-		}
-	
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayoutData.java b/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayoutData.java
deleted file mode 100644
index b0f34b1..0000000
--- a/com/aelitis/azureus/ui/swt/layout/SimpleReorderableListLayoutData.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.aelitis.azureus.ui.swt.layout;
-
-public class SimpleReorderableListLayoutData {
-	
-	public int position = 0;
-	
-	public int width;
-	public int height;
-
-}
diff --git a/com/aelitis/azureus/ui/swt/mdi/BaseMDI.java b/com/aelitis/azureus/ui/swt/mdi/BaseMDI.java
new file mode 100644
index 0000000..f94a17c
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/BaseMDI.java
@@ -0,0 +1,508 @@
+package com.aelitis.azureus.ui.swt.mdi;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+
+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.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.UIPluginView;
+import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper;
+import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo;
+import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewEventListenerHolder;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.skin.SkinConstants;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+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.sidebar.SideBar;
+import com.aelitis.azureus.util.ConstantsVuze;
+import com.aelitis.azureus.util.ContentNetworkUtils;
+import com.aelitis.azureus.util.MapUtils;
+
+public abstract class BaseMDI
+	extends SkinView
+	implements MultipleDocumentInterfaceSWT, UIUpdatable
+{
+	protected MdiEntrySWT currentEntry;
+
+	protected Map<String, MdiEntryCreationListener> mapIdToCreationListener = new LightHashMap<String, MdiEntryCreationListener>();
+
+	// Sync changes to entry maps on mapIdEntry
+	protected Map<String, MdiEntrySWT> mapIdToEntry = new LightHashMap<String, MdiEntrySWT>();
+
+	private List<MdiListener> listeners = new ArrayList<MdiListener>();
+
+	private List<MdiEntryLoadedListener> listLoadListeners = new ArrayList<MdiEntryLoadedListener>();
+
+	private static Map<String, Object> mapAutoOpen = new LightHashMap<String, Object>();
+
+	private String[] preferredOrder;
+
+	public void addListener(MdiListener l) {
+		synchronized (listeners) {
+			if (listeners.contains(l)) {
+				return;
+			}
+			listeners.add(l);
+		}
+	}
+
+	public void removeListener(MdiListener l) {
+		synchronized (listeners) {
+			listeners.remove(l);
+		}
+	}
+
+	public void addListener(MdiEntryLoadedListener l) {
+		synchronized (listLoadListeners) {
+			if (listLoadListeners.contains(l)) {
+				return;
+			}
+			listLoadListeners.add(l);
+		}
+		// might be a very rare thread issue here if entry gets loaded while
+		// we are walking through entries
+		MdiEntry[] entries = getEntries();
+		for (MdiEntry entry : entries) {
+			if (entry.isAdded()) {
+				l.mdiEntryLoaded(entry);
+			}
+		}
+	}
+
+	public void removeListener(MdiEntryLoadedListener l) {
+		synchronized (listLoadListeners) {
+			listLoadListeners.remove(l);
+		}
+	}
+	
+	protected void triggerSelectionListener(MdiEntry newEntry, MdiEntry oldEntry) {
+		MdiListener[] array = listeners.toArray(new MdiListener[0]);
+		for (MdiListener l : array) {
+			try {
+				l.mdiEntrySelected(newEntry, oldEntry);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void triggerEntryLoadedListeners(MdiEntry entry) {
+		MdiEntryLoadedListener[] array = listLoadListeners.toArray(new MdiEntryLoadedListener[0]);
+		for (MdiEntryLoadedListener l : array) {
+			try {
+				l.mdiEntryLoaded(entry);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void closeEntry(final String id) {
+		MdiEntry entry = getEntry(id);
+		if (entry != null) {
+			entry.close(false);
+		} else {
+			setEntryAutoOpen(id, null, false);
+		}
+	}
+
+	public abstract MdiEntry createEntryFromEventListener(String parentID,
+			UISWTViewEventListener l, String id, boolean closeable, Object datasource);
+
+	public abstract MdiEntry createEntryFromView(String parentID, UISWTViewCore iview,
+			String id, Object datasource, boolean closeable, boolean show,
+			boolean expand);
+
+	public abstract MdiEntry createEntryFromSkinRef(String parentID, String id,
+			String configID, String title, ViewTitleInfo titleInfo, Object params,
+			boolean closeable, String preferedAfterID);
+
+	public MdiEntry getCurrentEntry() {
+		return currentEntry;
+	}
+
+	public MdiEntrySWT getCurrentEntrySWT() {
+		return currentEntry;
+	}
+
+	public MdiEntry[] getEntries() {
+		return mapIdToEntry.values().toArray(new MdiEntry[0]);
+	}
+
+	public MdiEntrySWT[] getEntriesSWT() {
+		return mapIdToEntry.values().toArray(new MdiEntrySWT[0]);
+	}
+
+	public MdiEntry getEntry(String id) {
+		if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
+			id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
+		}
+		MdiEntry entry = mapIdToEntry.get(id);
+		return entry;
+	}
+
+	public MdiEntrySWT getEntrySWT(String id) {
+		if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
+			id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
+		}
+		MdiEntrySWT entry = mapIdToEntry.get(id);
+		return entry;
+	}
+
+	/**
+	 * @param skinView
+	 * @return 
+	 *
+	 * @since 3.1.1.1
+	 */
+	public MdiEntry getEntryBySkinView(Object skinView) {
+		SWTSkinObject so = ((SkinView)skinView).getMainSkinObject();
+		Object[] sideBarEntries = mapIdToEntry.values().toArray();
+		for (int i = 0; i < sideBarEntries.length; i++) {
+			//MdiEntrySWT entry = (MdiEntrySWT) sideBarEntries[i];
+			BaseMdiEntry entry = (BaseMdiEntry) sideBarEntries[i];
+			SWTSkinObject entrySO = entry.getSkinObject();
+			SWTSkinObject entrySOParent = entrySO == null ? entrySO
+					: entrySO.getParent();
+			if (entrySO == so || entrySO == so.getParent() || entrySOParent == so) {
+				return entry;
+			}
+		}
+		return null;
+	}
+
+	public UISWTViewCore getCoreViewFromID(String id) {
+		if (id == null) {
+			return null;
+		}
+		MdiEntrySWT entry = getEntrySWT(id);
+		if (entry == null) {
+			return null;
+		}
+		return entry.getCoreView();
+	}
+
+	public String getUpdateUIName() {
+		if (currentEntry == null || currentEntry.getView() == null) {
+			return "MDI";
+		}
+		return currentEntry.getView().getViewID();
+	}
+
+	public void registerEntry(String id, MdiEntryCreationListener l) {
+		mapIdToCreationListener.put(id, l);
+
+		Object o = mapAutoOpen.get(id);
+		if (o instanceof Map<?, ?>) {
+			MdiEntryCreationListener mdiEntryCreationListener = mapIdToCreationListener.get(id);
+			if (mdiEntryCreationListener != null) {
+				try {
+					mdiEntryCreationListener.createMDiEntry(id);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+	}
+
+	public abstract boolean showEntryByID(String id);
+
+	@Override
+	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
+		return null;
+	}
+
+	public void updateUI() {
+		MdiEntry currentEntry = getCurrentEntry();
+		if (currentEntry != null) {
+			currentEntry.updateUI();
+		}
+	}
+
+	public boolean entryExists(String id) {
+		if (SkinConstants.VIEWID_BROWSER_BROWSE.equalsIgnoreCase(id)) {
+			id = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
+		}
+		MdiEntry entry = mapIdToEntry.get(id);
+		if (entry == null) {
+			return false;
+		}
+		return entry.isAdded();
+	}
+
+	protected MdiEntry createWelcomeSection() {
+		MdiEntry entry = createEntryFromSkinRef(
+				SIDEBAR_HEADER_VUZE,
+				SIDEBAR_SECTION_WELCOME,
+				"main.area.welcome",
+				MessageText.getString("v3.MainWindow.menu.getting_started").replaceAll(
+						"&", ""), null, null, true, "");
+		entry.setImageLeftID("image.sidebar.welcome");
+		addDropTest(entry);
+		return entry;
+	}
+
+	protected void addDropTest(MdiEntry entry) {
+		if (!Constants.isCVSVersion()) {
+			return;
+		}
+		entry.addListener(new MdiEntryDropListener() {
+			public boolean mdiEntryDrop(MdiEntry entry, Object droppedObject) {
+				String s = "You just dropped " + droppedObject.getClass() + "\n"
+						+ droppedObject + "\n\n";
+				if (droppedObject.getClass().isArray()) {
+					Object[] o = (Object[]) droppedObject;
+					for (int i = 0; i < o.length; i++) {
+						s += "" + i + ":  ";
+						Object object = o[i];
+						if (object == null) {
+							s += "null";
+						} else {
+							s += object.getClass() + ";" + object;
+						}
+						s += "\n";
+					}
+				}
+				new MessageBoxShell(SWT.OK, "test", s).open(null);
+				return true;
+			}
+		});
+	}
+
+	public void setEntryAutoOpen(String id, Object datasource, boolean autoOpen) {
+		if (!autoOpen) {
+			mapAutoOpen.remove(id);
+		} else {
+			LightHashMap<String, Object> map = new LightHashMap<String, Object>(1);
+			map.put("datasource", datasource);
+			mapAutoOpen.put(id, map);
+		}
+	}
+
+	protected void setupPluginViews() {
+
+		// When a new Plugin View is added, check out auto-open list to see if
+		// the user had it open
+		PluginsMenuHelper.getInstance().addPluginAddedViewListener(
+				new PluginAddedViewListener() {
+					// @see org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener#pluginViewAdded(org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo)
+					public void pluginViewAdded(IViewInfo viewInfo) {
+						//System.out.println("PluginView Added: " + viewInfo.viewID);
+						Object o = mapAutoOpen.get(viewInfo.viewID);
+						if (o instanceof Map<?, ?>) {
+							processAutoOpenMap(viewInfo.viewID, (Map<?, ?>) o, viewInfo);
+						}
+					}
+				});
+	}
+
+	public void informAutoOpenSet(MdiEntry entry, Map<String, Object> autoOpenInfo) {
+		mapAutoOpen.put(entry.getId(), autoOpenInfo);
+	}
+
+	public void loadCloseables() {
+		Map<?,?> loadedMap = FileUtil.readResilientConfigFile("sidebarauto.config", true);
+		if (loadedMap.isEmpty()) {
+			return;
+		}
+		BDecoder.decodeStrings(loadedMap);
+		for (Iterator<?> iter = loadedMap.keySet().iterator(); iter.hasNext();) {
+			String id = (String) iter.next();
+			Object o = loadedMap.get(id);
+
+			if (o instanceof Map<?, ?>) {
+				if (!processAutoOpenMap(id, (Map<?, ?>) o, null)) {
+					mapAutoOpen.put(id, o);
+				}
+			}
+		}
+	}
+
+	@SuppressWarnings({
+		"unchecked",
+		"rawtypes"
+	})
+	public void saveCloseables() {
+		// update title
+		for (Iterator<?> iter = mapAutoOpen.keySet().iterator(); iter.hasNext();) {
+			String id = (String) iter.next();
+			Object o = mapAutoOpen.get(id);
+
+			MdiEntry entry = getEntry(id);
+			if (entry != null && entry.isAdded() && (o instanceof Map)) {
+				Map autoOpenInfo = (Map) o;
+
+				String s = entry.getTitle();
+				if (s != null) {
+					autoOpenInfo.put("title", s);
+				}
+			}
+		}
+
+		FileUtil.writeResilientConfigFile("sidebarauto.config", mapAutoOpen);
+	}
+
+	private boolean processAutoOpenMap(String id, Map<?, ?> autoOpenInfo,
+			IViewInfo viewInfo) {
+		//System.out.println("processAutoOpenMap " + id + " via " + Debug.getCompressedStackTrace());
+		try {
+			MdiEntry entry = getEntry(id);
+			if (entry != null) {
+				return true;
+			}
+
+			if (id.equals(SIDEBAR_SECTION_WELCOME)) {
+				createWelcomeSection();
+			}
+			
+			MdiEntryCreationListener mdiEntryCreationListener = mapIdToCreationListener.get(id);
+			if (mdiEntryCreationListener != null) {
+				try {
+					mdiEntryCreationListener.createMDiEntry(id);
+					return true;
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+
+
+			String title = MapUtils.getMapString(autoOpenInfo, "title", id);
+			String parentID = MapUtils.getMapString(autoOpenInfo, "parentID", SIDEBAR_HEADER_PLUGINS);
+			Object datasource = autoOpenInfo.get("datasource");
+
+			if (viewInfo != null) {
+				if (viewInfo.view != null) {
+					entry = createEntryFromView(parentID, viewInfo.view, id, datasource,
+							true, false, true);
+				} else if (viewInfo.event_listener != null) {
+					entry = createEntryFromEventListener(parentID,
+							viewInfo.event_listener, id, true, datasource);
+  				entry.setTitle(title);
+				}
+			}
+
+			if (entry != null && datasource == null) {
+				final MdiEntry fEntry = entry;
+				final String dmHash = MapUtils.getMapString(autoOpenInfo, "dm", null);
+				if (dmHash != null) {
+					AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+						public void azureusCoreRunning(AzureusCore core) {
+							GlobalManager gm = core.getGlobalManager();
+							HashWrapper hw = new HashWrapper(Base32.decode(dmHash));
+							DownloadManager dm = gm.getDownloadManager(hw);
+							if (dm != null) {
+								fEntry.setDatasource(dm);
+							}
+						}
+					});
+				} else {
+					final List<?> listHashes = MapUtils.getMapList(autoOpenInfo, "dms",
+							null);
+					if (listHashes != null) {
+						AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+							public void azureusCoreRunning(AzureusCore core) {
+								List<DownloadManager> listDMS = new ArrayList<DownloadManager>(
+										1);
+								GlobalManager gm = core.getGlobalManager();
+								for (Object oDM : listHashes) {
+									if (oDM instanceof String) {
+										String hash = (String) oDM;
+										DownloadManager dm = gm.getDownloadManager(new HashWrapper(
+												Base32.decode(hash)));
+										if (dm != null) {
+											listDMS.add(dm);
+										}
+									}
+									fEntry.setDatasource(listDMS.toArray(new DownloadManager[0]));
+								}
+							}
+						});
+					}
+				}
+			}
+
+			return entry != null;
+		} catch (Throwable e) {
+			Debug.out(e);
+		}
+		return false;
+	}
+
+	public void removeItem(MdiEntry entry) {
+		String id = entry.getId();
+		synchronized (mapIdToEntry) {
+			mapIdToEntry.remove(id);
+			
+			removeChildrenOf(id);
+		}
+	}
+
+	private void removeChildrenOf(String id) {
+		if (id == null) {
+			return;
+		}
+		synchronized (mapIdToEntry) {
+			MdiEntrySWT[] entriesSWT = getEntriesSWT();
+			for (MdiEntrySWT entry : entriesSWT) {
+				if (id.equals(entry.getParentID())) {
+					mapIdToEntry.remove(entry);
+					removeChildrenOf(entry.getId());
+				}
+			}
+		}
+	}
+	
+	public List<MdiEntry> getChildrenOf(String id) {
+		if (id == null) {
+			return Collections.emptyList();
+		}
+		List<MdiEntry> list = new ArrayList<MdiEntry>(1);
+		synchronized (mapIdToEntry) {
+			MdiEntrySWT[] entriesSWT = getEntriesSWT();
+			for (MdiEntrySWT entry : entriesSWT) {
+				if (id.equals(entry.getParentID())) {
+					list.add(entry);
+				}
+			}
+		}
+		return list;
+	}
+
+	public Object updateLanguage(SWTSkinObject skinObject, Object params) {
+		MdiEntry[] entries = getEntries();
+		
+		for (MdiEntry entry : entries) {
+			if (entry instanceof BaseMdiEntry) {
+				BaseMdiEntry baseEntry = (BaseMdiEntry) entry;
+				baseEntry.updateLanguage();
+			}
+		}
+
+		return null;
+	}
+
+	public void setPreferredOrder(String[] preferredOrder) {
+		this.preferredOrder = preferredOrder;
+	}
+
+	public String[] getPreferredOrder() {
+		return preferredOrder == null ? new String[0] : preferredOrder;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/BaseMdiEntry.java b/com/aelitis/azureus/ui/swt/mdi/BaseMdiEntry.java
new file mode 100644
index 0000000..9c2213a
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/BaseMdiEntry.java
@@ -0,0 +1,924 @@
+package com.aelitis.azureus.ui.swt.mdi;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
+import org.gudy.azureus2.core3.config.impl.ConfigurationParameterNotFoundException;
+import org.gudy.azureus2.core3.download.DownloadManager;
+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.core3.util.LightHashMap;
+import org.gudy.azureus2.plugins.ui.UIPluginView;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarEnablerBase;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
+
+import com.aelitis.azureus.ui.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.viewtitleinfo.*;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+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.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectListener;
+
+public abstract class BaseMdiEntry
+	implements MdiEntrySWT, ViewTitleInfoListener
+{
+	protected final MultipleDocumentInterface mdi;
+
+	protected final String id;
+
+	protected String logID;
+
+	protected Object datasource;
+
+	protected Class<? extends UIPluginView> viewClass;
+
+	protected UISWTViewCore view;
+
+	private String skinRef;
+
+	private List<MdiCloseListener> listCloseListeners = null;
+
+	private List<MdiChildCloseListener> listChildCloseListeners = null;
+
+	private List<MdiEntryLogIdListener> listLogIDListeners = null;
+
+	private List<MdiEntryOpenListener> listOpenListeners = null;
+
+	private List<MdiEntryDropListener> listDropListeners = null;
+
+	protected ViewTitleInfo viewTitleInfo;
+
+	private SWTSkinObject skinObject;
+
+	private String title;
+
+	private String titleID;
+
+	private UISWTViewEventListener eventListener;
+
+	private String parentID;
+
+	private boolean pullTitleFromView;
+
+	private boolean closeable;
+
+	private Boolean isExpanded = null;
+
+	private boolean disposed = false;
+
+	private boolean added = false;
+
+	private String imageLeftID;
+
+	private Image imageLeft;
+
+	private boolean collapseDisabled = false;
+
+	private SWTSkinObject soMaster;
+
+	private Set<UIToolBarEnablerBase> setToolBarEnablers = new HashSet<UIToolBarEnablerBase>(
+			1);
+
+	private String preferredAfterID;
+
+	@SuppressWarnings("unused")
+	private BaseMdiEntry() {
+		mdi = null;
+		id = null;
+		setDefaultExpanded(false);
+	}
+
+	public BaseMdiEntry(MultipleDocumentInterface mdi, String id) {
+		this.mdi = mdi;
+		this.id = id;
+		this.pullTitleFromView = true;
+
+		if (id == null) {
+			logID = "null";
+		} else {
+			int i = id.indexOf('_');
+			if (i > 0) {
+				logID = id.substring(0, i);
+			} else {
+				logID = id;
+			}
+		}
+		setDefaultExpanded(false);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public MdiEntryVitalityImage addVitalityImage(String imageID) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.mdi.MdiEntry#close()
+	 */
+	public boolean close(boolean forceClose) {
+		if (!forceClose && view instanceof UISWTViewImpl) {
+			if (!((UISWTViewImpl) view).requestClose()) {
+				return false;
+			}
+		}
+
+		disposed = true;
+		ViewTitleInfoManager.removeListener(this);
+
+		return true;
+	}
+
+	public Object getDatasourceCore() {
+		return datasource;
+	}
+
+	public Object getDatasource() {
+		return PluginCoreUtils.convert(datasource, false);
+	}
+
+	public void setDatasource(Object datasource) {
+		this.datasource = datasource;
+
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, datasource);
+		}
+
+		if (isAdded()) {
+			if (skinObject != null) {
+				skinObject.triggerListeners(
+						SWTSkinObjectListener.EVENT_DATASOURCE_CHANGED, datasource);
+			}
+		}
+	}
+
+	public UIPluginView getView() {
+		return view;
+	}
+
+	public UISWTViewCore getCoreView() {
+		return view;
+	}
+
+	public Class<? extends UIPluginView> getViewClass() {
+		return viewClass;
+	}
+
+	public void setViewClass(Class<? extends UIPluginView> viewClass) {
+		this.viewClass = viewClass;
+	}
+
+	public String getLogID() {
+		return logID;
+	}
+
+	public MultipleDocumentInterface getMDI() {
+		return mdi;
+	}
+
+	public String getParentID() {
+		return parentID;
+	}
+
+	public void setParentID(String id) {
+		if (id == null || "Tools".equals(id)) {
+			if (getId().equals(MultipleDocumentInterface.SIDEBAR_HEADER_DVD)
+					&& id == null) {
+				id = "";
+			} else {
+				id = MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS;
+			}
+		}
+		if (id.equals(getId())) {
+			Debug.out("Setting Parent to same ID as child! " + id);
+			return;
+		}
+		parentID = id;
+		// ensure parent gets created if it isn't there already
+		mdi.loadEntryByID(parentID, false);
+	}
+
+	public MdiEntryVitalityImage[] getVitalityImages() {
+		return null;
+	}
+
+	public boolean isCloseable() {
+		return closeable;
+	}
+
+	public boolean isCollapseDisabled() {
+		return collapseDisabled;
+	}
+
+	public void setCollapseDisabled(boolean collapseDisabled) {
+		this.collapseDisabled = collapseDisabled;
+		setExpanded(true);
+	}
+
+	public void addListener(MdiCloseListener l) {
+		synchronized (this) {
+			if (listCloseListeners == null) {
+				listCloseListeners = new ArrayList<MdiCloseListener>(1);
+			}
+			listCloseListeners.add(l);
+		}
+	}
+
+	public void removeListener(MdiCloseListener l) {
+		synchronized (this) {
+			if (listCloseListeners != null) {
+				listCloseListeners.remove(l);
+			}
+		}
+	}
+
+	public void triggerCloseListeners(boolean user) {
+		Object[] list = {};
+		synchronized (this) {
+			if (listCloseListeners != null) {
+				list = listCloseListeners.toArray();
+			}
+		}
+		for (int i = 0; i < list.length; i++) {
+			MdiCloseListener l = (MdiCloseListener) list[i];
+			try {
+				l.mdiEntryClosed(this, user);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+
+		MdiEntry parentEntry = mdi.getEntry(parentID);
+		if (parentEntry instanceof BaseMdiEntry) {
+			((BaseMdiEntry) parentEntry).triggerChildCloseListeners(this, user);
+		}
+	}
+
+	public void addListener(MdiChildCloseListener l) {
+		synchronized (this) {
+			if (listChildCloseListeners == null) {
+				listChildCloseListeners = new ArrayList<MdiChildCloseListener>(1);
+			}
+			listChildCloseListeners.add(l);
+		}
+	}
+
+	public void removeListener(MdiChildCloseListener l) {
+		synchronized (this) {
+			if (listChildCloseListeners != null) {
+				listChildCloseListeners.remove(l);
+			}
+		}
+	}
+
+	public void triggerChildCloseListeners(MdiEntry child, boolean user) {
+		if (listChildCloseListeners == null) {
+			return;
+		}
+		Object[] list;
+		synchronized (this) {
+			list = listChildCloseListeners.toArray();
+		}
+		for (int i = 0; i < list.length; i++) {
+			MdiChildCloseListener l = (MdiChildCloseListener) list[i];
+			try {
+				l.mdiChildEntryClosed(this, child, user);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void addListener(MdiEntryLogIdListener l) {
+		synchronized (this) {
+			if (listLogIDListeners == null) {
+				listLogIDListeners = new ArrayList<MdiEntryLogIdListener>(1);
+			}
+			listLogIDListeners.add(l);
+		}
+	}
+
+	public void removeListener(MdiEntryLogIdListener sideBarLogIdListener) {
+		synchronized (this) {
+			if (listLogIDListeners != null) {
+				listLogIDListeners.remove(sideBarLogIdListener);
+			}
+		}
+	}
+
+	protected void triggerLogIDListeners(String oldID) {
+		Object[] list;
+		synchronized (this) {
+			if (listLogIDListeners == null) {
+				return;
+			}
+
+			list = listLogIDListeners.toArray();
+		}
+
+		for (int i = 0; i < list.length; i++) {
+			MdiEntryLogIdListener l = (MdiEntryLogIdListener) list[i];
+			l.mdiEntryLogIdChanged(this, oldID, logID);
+		}
+	}
+
+	public void addListener(MdiEntryOpenListener l) {
+		synchronized (this) {
+			if (listOpenListeners == null) {
+				listOpenListeners = new ArrayList<MdiEntryOpenListener>(1);
+			}
+			listOpenListeners.add(l);
+		}
+
+		if (view != null) {
+			l.mdiEntryOpen(this);
+		}
+	}
+
+	public void removeListener(MdiEntryOpenListener l) {
+		synchronized (this) {
+			if (listOpenListeners != null) {
+				listOpenListeners.remove(l);
+			}
+		}
+	}
+
+	public void triggerOpenListeners() {
+		Object[] list;
+		synchronized (this) {
+			if (listOpenListeners == null) {
+				return;
+			}
+
+			list = listOpenListeners.toArray();
+		}
+		for (int i = 0; i < list.length; i++) {
+			MdiEntryOpenListener l = (MdiEntryOpenListener) list[i];
+			try {
+				l.mdiEntryOpen(this);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void addListener(MdiEntryDropListener l) {
+		synchronized (this) {
+			if (listDropListeners == null) {
+				listDropListeners = new ArrayList<MdiEntryDropListener>(1);
+			}
+			listDropListeners.add(l);
+		}
+	}
+
+	public void removeListener(MdiEntryDropListener l) {
+		synchronized (this) {
+			if (listDropListeners != null) {
+				listDropListeners.remove(l);
+			}
+		}
+	}
+
+	public boolean hasDropListeners() {
+		synchronized (this) {
+			return listDropListeners != null && listDropListeners.size() > 0;
+		}
+	}
+
+	/**
+	 * 
+	 * @param o
+	 * @return true: handled; false: not handled
+	 */
+	public boolean triggerDropListeners(Object o) {
+		boolean handled = false;
+		Object[] list;
+		synchronized (this) {
+			if (listDropListeners == null) {
+				return handled;
+			}
+
+			list = listDropListeners.toArray();
+		}
+		for (int i = 0; i < list.length; i++) {
+			MdiEntryDropListener l = (MdiEntryDropListener) list[i];
+			handled = l.mdiEntryDrop(this, o);
+			if (handled) {
+				break;
+			}
+		}
+		return handled;
+	}
+
+	public void setLogID(String logID) {
+		if (logID == null || logID.equals("" + this.logID)) {
+			return;
+		}
+		String oldID = this.logID;
+		this.logID = logID;
+		triggerLogIDListeners(oldID);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.mdi.MdiEntry#getViewTitleInfo()
+	 */
+	public ViewTitleInfo getViewTitleInfo() {
+		return viewTitleInfo;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.mdi.MdiEntry#setViewTitleInfo(com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo)
+	 */
+	public void setViewTitleInfo(ViewTitleInfo viewTitleInfo) {
+		if (this.viewTitleInfo == viewTitleInfo) {
+			return;
+		}
+		this.viewTitleInfo = viewTitleInfo;
+		// TODO: Need to listen for viewTitleInfo triggers so we can refresh items below
+		if (viewTitleInfo != null) {
+			if (viewTitleInfo instanceof ViewTitleInfo2) {
+				ViewTitleInfo2 vti2 = (ViewTitleInfo2) viewTitleInfo;
+				try {
+					vti2.titleInfoLinked(mdi, this);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+
+			String newTitle = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
+			if (newTitle != null) {
+				setPullTitleFromView(false);
+				setTitle(newTitle);
+			}
+
+			String imageID = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_IMAGEID);
+			if (imageID != null) {
+				setImageLeftID(imageID.length() == 0 ? null : imageID);
+			}
+
+			ViewTitleInfoManager.addListener(this);
+		}
+	}
+
+	/**
+	 * @deprecated For azburn
+	 */
+	// @see com.aelitis.azureus.ui.mdi.MdiEntry#addToolbarEnabler(com.aelitis.azureus.ui.common.ToolBarEnabler)
+	public void addToolbarEnabler(ToolBarEnabler enabler) {
+		addToolbarEnabler((UIToolBarEnablerBase) enabler);
+	}
+
+	public void addToolbarEnabler(UIToolBarEnablerBase enabler) {
+		setToolBarEnablers.add(enabler);
+	}
+
+	public void removeToolbarEnabler(UIToolBarEnablerBase enabler) {
+		setToolBarEnablers.remove(enabler);
+	}
+
+	public UIToolBarEnablerBase[] getToolbarEnablers() {
+		if (view != null) {
+			UIPluginViewToolBarListener listener = view.getToolBarListener();
+			if (listener != null) {
+				return new UIToolBarEnablerBase[] { listener };
+			}
+		}
+		return setToolBarEnablers.toArray(new UIToolBarEnablerBase[0]);
+	}
+
+	public void setCoreView(UISWTViewCore view) {
+		if (this.view != null && view == null) {
+  		this.view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+		}
+		this.view = view;
+		if (view == null) {
+			return;
+		}
+
+		UISWTViewEventListener eventListener = view.getEventListener();
+		if (view instanceof ViewTitleInfo) {
+			setViewTitleInfo((ViewTitleInfo) view);
+		} else if (eventListener instanceof ViewTitleInfo) {
+			setViewTitleInfo((ViewTitleInfo) eventListener);
+		}
+
+		if (view instanceof UIToolBarEnablerBase) {
+			addToolbarEnabler((UIToolBarEnablerBase) view);
+		} else if (eventListener instanceof UIToolBarEnablerBase) {
+			addToolbarEnabler((UIToolBarEnablerBase) eventListener);
+		}
+
+		if (datasource != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, datasource);
+		}
+	}
+
+	public SWTSkinObject getSkinObject() {
+		return skinObject;
+	}
+
+	public void setSkinObject(SWTSkinObject skinObject, SWTSkinObject soMaster) {
+		this.skinObject = skinObject;
+		this.soMaster = soMaster;
+		if (datasource != null) {
+			if (skinObject != null) {
+				skinObject.triggerListeners(
+						SWTSkinObjectListener.EVENT_DATASOURCE_CHANGED, datasource);
+			}
+			if (view != null) {
+				view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, datasource);
+			}
+		}
+	}
+
+	public SWTSkinObject getSkinObjectMaster() {
+		if (soMaster == null) {
+			return skinObject;
+		}
+		return soMaster;
+	}
+
+	public void setSkinRef(String configID, Object params) {
+		skinRef = configID;
+		if (params != null) {
+			setDatasource(params);
+		}
+	}
+
+	public String getSkinRef() {
+		return skinRef;
+	}
+
+	public String getTitle() {
+		if (title != null && !isPullTitleFromView()) {
+			return title;
+		}
+		if (view != null) {
+			return view.getFullTitle();
+		}
+		return title;
+	}
+
+	public void setTitle(String title) {
+		if (title == null) {
+			return;
+		}
+		if (title.startsWith("{") && title.endsWith("}") && title.length() > 2) {
+			setTitleID(title.substring(1, title.length() - 1));
+			return;
+		}
+		if (title.equals(this.title)) {
+			return;
+		}
+		this.title = title;
+		this.titleID = null;
+		redraw();
+	}
+
+	public void setTitleID(String titleID) {
+		String title = MessageText.getString(titleID);
+		setTitle(title.startsWith("{") ? title.substring(1) : title);
+		this.titleID = titleID;
+	}
+
+	public void updateLanguage() {
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_LANGUAGEUPDATE, null);
+		}
+		if (titleID != null) {
+			setTitleID(titleID);
+		} else {
+			if (viewTitleInfo != null) {
+				viewTitleInfoRefresh(viewTitleInfo);
+			}
+			updateUI();
+		}
+	}
+
+	public void show() {
+		if (skinObject == null) {
+			return;
+		}
+
+		SelectedContentManager.clearCurrentlySelectedContent();
+
+		UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uif != null) {
+			//uif.refreshIconBar(); // needed?
+			uif.refreshTorrentMenu();
+		}
+
+		SWTSkinObject skinObject = getSkinObjectMaster();
+		skinObject.setVisible(true);
+		if (skinObject instanceof SWTSkinObjectContainer) {
+			SWTSkinObjectContainer container = (SWTSkinObjectContainer) skinObject;
+			Composite composite = container.getComposite();
+			if (composite != null && !composite.isDisposed()) {
+				composite.setVisible(true);
+				composite.moveAbove(null);
+				//composite.setFocus();
+				//container.getParent().relayout();
+				composite.getParent().layout();
+			}
+			// This causes double show because createSkinObject already calls show
+			//container.triggerListeners(SWTSkinObjectListener.EVENT_SHOW);
+		}
+		if (view != null) {
+			Composite c = view.getComposite();
+			if (c != null && !c.isDisposed()) {
+				c.setData("BaseMDIEntry", this);
+				c.setVisible(true);
+				c.getParent().layout();
+			}
+
+			try {
+				view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void hide() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_hide();
+			}
+		});
+	}
+
+	protected void swt_hide() {
+		SWTSkinObject skinObjectMaster = getSkinObjectMaster();
+		if (skinObjectMaster instanceof SWTSkinObjectContainer) {
+			SWTSkinObjectContainer container = (SWTSkinObjectContainer) skinObjectMaster;
+			Control oldComposite = container.getControl();
+
+			container.setVisible(false);
+			if (oldComposite != null && !oldComposite.isDisposed()) {
+				oldComposite.getShell().update();
+			}
+		}
+		if (view != null) {
+			Composite oldComposite = view.getComposite();
+			if (oldComposite != null && !oldComposite.isDisposed()) {
+
+				oldComposite.setVisible(false);
+				oldComposite.getShell().update();
+			}
+
+			try {
+				view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public UISWTViewEventListener getEventListener() {
+		return eventListener;
+	}
+
+	public void setEventListener(UISWTViewEventListener _eventListener) {
+		this.eventListener = _eventListener;
+
+		if (view != null) {
+			return;
+		}
+		try {
+			setCoreView(new UISWTViewImpl(parentID, id, _eventListener,
+					datasource));
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+
+		if (_eventListener instanceof UISWTViewEventListenerHolder) {
+			UISWTViewEventListenerHolder h = (UISWTViewEventListenerHolder) _eventListener;
+			UISWTViewEventListener delegatedEventListener = h.getDelegatedEventListener(view);
+			if (delegatedEventListener != null) {
+				this.eventListener = delegatedEventListener;
+			}
+		}
+
+		if (eventListener instanceof UIToolBarEnablerBase) {
+			addToolbarEnabler((UIToolBarEnablerBase) eventListener);
+		}
+		if ((eventListener instanceof ViewTitleInfo) && viewTitleInfo == null) {
+			setViewTitleInfo((ViewTitleInfo) eventListener);
+		}
+
+
+		if (eventListener instanceof BasicPluginViewImpl) {
+			if ("image.sidebar.plugin".equals(getImageLeftID())) {
+				setImageLeftID("image.sidebar.logview");
+			}
+		}
+	}
+
+	public boolean isPullTitleFromView() {
+		return pullTitleFromView;
+	}
+
+	public void setPullTitleFromView(boolean pullTitleFromView) {
+		this.pullTitleFromView = pullTitleFromView;
+	}
+
+	public void updateUI() {
+		if (view == null) {
+			return;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (view != null && !isDisposed()) {
+					view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
+				}
+				if (isPullTitleFromView() && isAdded()) {
+					setTitle(view.getFullTitle());
+				}
+			}
+		});
+	}
+
+	public boolean isDisposed() {
+		return disposed;
+	}
+
+	public void setCloseable(boolean closeable) {
+		this.closeable = closeable;
+		if (closeable) {
+			Map<String, Object> autoOpenInfo = new LightHashMap<String, Object>();
+			if (getParentID() != null) {
+				autoOpenInfo.put("parentID", getParentID());
+			}
+			UISWTViewEventListener eventListener = getEventListener();
+			if (eventListener != null) {
+				autoOpenInfo.put("eventListenerClass",
+						eventListener.getClass().getName());
+			}
+			if (getCoreView() != null) {
+				autoOpenInfo.put("title", getCoreView().getFullTitle());
+			}
+			Object datasource = getDatasourceCore();
+			if (datasource instanceof DownloadManager) {
+				try {
+					autoOpenInfo.put(
+							"dm",
+							((DownloadManager) datasource).getTorrent().getHashWrapper().toBase32String());
+				} catch (Throwable t) {
+				}
+			} else if (datasource instanceof DownloadManager[]) {
+				DownloadManager[] dms = (DownloadManager[]) datasource;
+				List<String> list = new ArrayList<String>();
+				for (DownloadManager dm : dms) {
+					try {
+						list.add(dm.getTorrent().getHashWrapper().toBase32String());
+					} catch (Throwable e) {
+					}
+				}
+				autoOpenInfo.put("dms", list);
+			} else if (datasource != null) {
+				autoOpenInfo.put("datasource", datasource.toString());
+			}
+
+			mdi.informAutoOpenSet(this, autoOpenInfo);
+			COConfigurationManager.setParameter("SideBar.AutoOpen." + id, true);
+		} else {
+			COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.mdi.MdiEntry#setDefaultExpanded(boolean)
+	public void setDefaultExpanded(boolean defaultExpanded) {
+		COConfigurationManager.setBooleanDefault("SideBar.Expanded." + id,
+				defaultExpanded);
+	}
+
+	public boolean isExpanded() {
+		return isExpanded == null
+				? COConfigurationManager.getBooleanParameter("SideBar.Expanded." + id)
+				: isExpanded;
+	}
+
+	public void setExpanded(boolean expanded) {
+		isExpanded = expanded;
+		boolean defExpanded = true;
+		try {
+			defExpanded = ConfigurationDefaults.getInstance().getBooleanParameter(
+					"SideBar.Expanded." + id);
+		} catch (ConfigurationParameterNotFoundException e) {
+		}
+		if (isExpanded == defExpanded) {
+			COConfigurationManager.removeParameter("SideBar.Expanded." + id);
+		} else {
+			COConfigurationManager.setParameter("SideBar.Expanded." + id, isExpanded);
+		}
+	}
+
+	public boolean isAdded() {
+		return added;
+	}
+
+	public void setDisposed(boolean b) {
+		disposed = b;
+		added = !b;
+	}
+
+	public void setImageLeftID(String id) {
+		imageLeftID = id;
+		imageLeft = null;
+		redraw();
+	}
+
+	public String getImageLeftID() {
+		return imageLeftID;
+	}
+
+	/**
+	 * @param imageLeft the imageLeft to set
+	 */
+	public void setImageLeft(Image imageLeft) {
+		this.imageLeft = imageLeft;
+		imageLeftID = null;
+		redraw();
+	}
+
+	public Image getImageLeft(String suffix) {
+		if (imageLeft != null) {
+			return imageLeft;
+		}
+		if (imageLeftID == null) {
+			return null;
+		}
+		Image img = null;
+		if (suffix == null) {
+			img = ImageLoader.getInstance().getImage(imageLeftID);
+		} else {
+			img = ImageLoader.getInstance().getImage(imageLeftID + suffix);
+		}
+		if (ImageLoader.isRealImage(img)) {
+//			System.out.println("real" + getTitle() + "/" + img.getBounds() + Debug.getCompressedStackTrace());
+			return img;
+		}
+		return null;
+	}
+
+	public void releaseImageLeft(String suffix) {
+		if (imageLeft != null) {
+			ImageLoader.getInstance().releaseImage(
+					imageLeftID + (suffix == null ? "" : suffix));
+		}
+	}
+
+	public void viewTitleInfoRefresh(ViewTitleInfo titleInfoToRefresh) {
+		if (titleInfoToRefresh == null || this.viewTitleInfo != titleInfoToRefresh) {
+			return;
+		}
+		if (isDisposed()) {
+			return;
+		}
+
+		String newText = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
+		if (newText != null) {
+			setPullTitleFromView(false);
+			setTitle(newText);
+		}
+
+		String imageID = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_IMAGEID);
+		if (imageID != null) {
+			setImageLeftID(imageID.length() == 0 ? null : imageID);
+		}
+
+		redraw();
+
+		String logID = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_LOGID);
+		if (logID != null) {
+			setLogID(logID);
+		}
+	}
+
+	public void build() {
+	}
+
+	public void setPreferredAfterID(String preferredAfterID) {
+		this.preferredAfterID = preferredAfterID;
+	}
+
+	public String getPreferredAfterID() {
+		return preferredAfterID;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/MdiEntrySWT.java b/com/aelitis/azureus/ui/swt/mdi/MdiEntrySWT.java
new file mode 100644
index 0000000..76b1828
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/MdiEntrySWT.java
@@ -0,0 +1,35 @@
+/**
+ * 
+ */
+package com.aelitis.azureus.ui.swt.mdi;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.gudy.azureus2.plugins.ui.UIPluginView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+
+/**
+ * @author TuxPaper
+ * @created Jan 29, 2010
+ *
+ */
+public interface MdiEntrySWT
+	extends MdiEntry
+{
+	//public SWTSkinObject getSkinObject();
+
+	public UIPluginView getView();
+
+	public UISWTViewCore getCoreView();
+
+	public UISWTViewEventListener getEventListener();
+
+	public void addListener(MdiSWTMenuHackListener l);
+
+	public void removeListener(MdiSWTMenuHackListener l);
+
+	void setImageLeft(Image imageLeft);
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/MdiSWTMenuHackListener.java b/com/aelitis/azureus/ui/swt/mdi/MdiSWTMenuHackListener.java
new file mode 100644
index 0000000..c0fb5d0
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/MdiSWTMenuHackListener.java
@@ -0,0 +1,34 @@
+/**
+ * Created on Nov 16, 2010
+ *
+ * Copyright 2010 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.mdi;
+
+import org.eclipse.swt.widgets.Menu;
+
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+
+
+/**
+ * @author TuxPaper
+ * @created Nov 16, 2010
+ *
+ */
+public interface MdiSWTMenuHackListener
+{
+	public void menuWillBeShown(MdiEntry entry, Menu menuTree);
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/MultipleDocumentInterfaceSWT.java b/com/aelitis/azureus/ui/swt/mdi/MultipleDocumentInterfaceSWT.java
new file mode 100644
index 0000000..d98ecf1
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/MultipleDocumentInterfaceSWT.java
@@ -0,0 +1,37 @@
+/**
+ * 
+ */
+package com.aelitis.azureus.ui.swt.mdi;
+
+import org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+
+/**
+ * @author TuxPaper
+ * @created Jan 29, 2010
+ *
+ */
+public interface MultipleDocumentInterfaceSWT
+	extends MultipleDocumentInterface
+{
+	public MdiEntry getEntryBySkinView(Object skinView);
+
+	public UISWTViewCore getCoreViewFromID(String id);
+
+	public MdiEntry createEntryFromEventListener(String parentID,
+			UISWTViewEventListener l, String id, boolean closeable, Object datasource);
+
+	public MdiEntry createEntryFromView(String parentID, UISWTViewCore view,
+			String id, Object datasource, boolean closeable, boolean show,
+			boolean expand);
+
+	public MdiEntrySWT getEntrySWT(String id);
+
+	public MdiEntrySWT getCurrentEntrySWT();
+
+	public MdiEntrySWT getEntryFromSkinObject(PluginUISWTSkinObject skinObject);
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/TabbedEntry.java b/com/aelitis/azureus/ui/swt/mdi/TabbedEntry.java
new file mode 100644
index 0000000..ea933c2
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/TabbedEntry.java
@@ -0,0 +1,422 @@
+package com.aelitis.azureus.ui.swt.mdi;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Cursor;
+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.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
+import com.aelitis.azureus.ui.swt.skin.SWTSkin;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+
+public class TabbedEntry
+	extends BaseMdiEntry implements DisposeListener
+{
+	private CTabItem swtItem;
+
+	private SWTSkin skin;
+
+	private boolean showonSWTItemSet;
+
+	private boolean buildonSWTItemSet;
+
+	private static long uniqueNumber = 0;
+
+	public TabbedEntry(TabbedMDI mdi, SWTSkin skin, String id) {
+		super(mdi, id);
+		this.skin = skin;
+	}
+
+	/* (non-Javadoc)
+	 * @note SideBarEntrySWT is neary identical to this one.  Please keep them
+	 *       in sync until commonalities are placed in BaseMdiEntry
+	 */
+	public void build() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_build();
+				TabbedEntry.super.build();
+			}
+		});
+	}
+	
+	public boolean swt_build() {
+		if (swtItem == null) {
+			buildonSWTItemSet = true;
+			return true;
+		}
+		buildonSWTItemSet = false;
+
+		Control control = swtItem.getControl();
+		if (control == null) {
+			Composite parent = swtItem.getParent();
+			SWTSkinObject soParent = (SWTSkinObject) parent.getData("SkinObject");
+
+			String skinRef = getSkinRef();
+			if (skinRef != null) {
+				Shell shell = parent.getShell();
+				Cursor cursor = shell.getCursor();
+				try {
+					shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+
+//					SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
+//							"MdiContents." + uniqueNumber++, "mdi.content.item",
+//							soParent, getSkinRefParams());
+//					skin.addSkinObject(soContents);
+
+					
+					SWTSkinObject skinObject = skin.createSkinObject(id, skinRef,
+							soParent, getDatasourceCore());
+					
+					control = skinObject.getControl();
+					control.setLayoutData(Utils.getFilledFormData());
+					control.getParent().layout(true);
+					// swtItem.setControl will set the control's visibility based on
+					// whether the control is selected.  To ensure it doesn't set
+					// our control invisible, set selection now
+					CTabItem oldSelection = swtItem.getParent().getSelection();
+					swtItem.getParent().setSelection(swtItem);
+					swtItem.setControl(control);
+					if (oldSelection != null) {
+						swtItem.getParent().setSelection(oldSelection);
+					}
+					setSkinObject(skinObject, skinObject);
+				} finally {
+					shell.setCursor(cursor);
+				}
+			} else if (view != null) {
+				try {
+					SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
+							"MdiIView." + uniqueNumber++, "mdi.content.item",
+							soParent);
+					skin.addSkinObject(soContents);
+
+					parent.setBackgroundMode(SWT.INHERIT_NONE);
+
+					Composite viewComposite = soContents.getComposite();
+					//viewComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+					//viewComposite.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
+
+					boolean doGridLayout = true;
+					UISWTView swtView = view;
+					if (swtView.getControlType() == UISWTViewCore.CONTROLTYPE_SKINOBJECT) {
+						doGridLayout = false;
+					}
+					if (doGridLayout) {
+  					GridLayout gridLayout = new GridLayout();
+  					gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
+  					viewComposite.setLayout(gridLayout);
+  					viewComposite.setLayoutData(Utils.getFilledFormData());
+					}
+
+					UISWTViewCore uiViewCore = view;
+					uiViewCore.setSkinObject(soContents, soContents.getComposite());
+
+					view.initialize(viewComposite);
+					setTitle(view.getFullTitle());
+
+					Composite iviewComposite = view.getComposite();
+					control = iviewComposite;
+					if (doGridLayout) {
+						Object existingLayoutData = iviewComposite.getLayoutData();
+						Object existingParentLayoutData = iviewComposite.getParent().getLayoutData();
+						if (existingLayoutData == null
+								|| !(existingLayoutData instanceof GridData)
+								&& (existingParentLayoutData instanceof GridLayout)) {
+							GridData gridData = new GridData(GridData.FILL_BOTH);
+							iviewComposite.setLayoutData(gridData);
+						}
+					}
+
+					//soContents is invisible, so of course iviwComposite is invisible
+					//We should do the one time layout on the first show..
+					//if (iviewComposite.isVisible()) {
+					//	parent.layout(true, true);
+					//}
+
+					CTabItem oldSelection = swtItem.getParent().getSelection();
+					swtItem.getParent().setSelection(swtItem);
+					swtItem.setControl(soContents.getControl());
+					if (oldSelection != null) {
+						swtItem.getParent().setSelection(oldSelection);
+					}
+					setSkinObject(soContents, soContents);
+				} catch (Exception e) {
+					Debug.out("Error creating sidebar content area for " + id, e);
+					close(true);
+				}
+
+			} else if (viewClass != null) {
+				try {
+					UISWTViewCore view = (UISWTViewCore) viewClass.newInstance();
+
+					if (view != null) {
+						setCoreView(view);
+						// now that we have an view, go through show one more time
+						return swt_build();
+					}
+					close(true);
+					return false;
+				} catch (Exception e) {
+					Debug.out(e);
+					close(true);
+				}
+			}
+
+			if (control != null && !control.isDisposed()) {
+				control.setData("BaseMDIEntry", this);
+				control.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						close(true);
+					}
+				});
+			} else {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#show()
+	 */
+	public void show() {
+		// ensure show order by user execThreadLater
+		// fixes case where two showEntries are called, the first from a non
+		// SWT thread, and the 2nd from a SWT thread.  The first one will run last
+		// showing itself
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				swt_show();
+			}
+		});
+	}
+
+	private void swt_show() {
+		if (swtItem == null) {
+			showonSWTItemSet = true;
+			return;
+		}
+		showonSWTItemSet = false;
+		if (!swt_build()) {
+			return;
+		}
+		
+		triggerOpenListeners();
+
+
+		if (swtItem.getParent().getSelection() != swtItem) {
+			swtItem.getParent().setSelection(swtItem);
+		}
+
+		super.show();
+	}
+
+	/**
+	 * Tabs don't have Vitality Image support (yet)
+	 */
+	public MdiEntryVitalityImage addVitalityImage(String imageID) {
+		return null; // new SideBarVitalityImageSWT(this, imageID);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#isCloseable()
+	 */
+	public boolean isCloseable() {
+		// override.. we don't support non-closeable
+		return true;
+	}
+
+	public void setSwtItem(CTabItem swtItem) {
+		this.swtItem = swtItem;
+		if (swtItem == null) {
+			setDisposed(true);
+			return;
+		}
+		setDisposed(false);
+
+		swtItem.addDisposeListener(this);
+		String title = getTitle();
+		if (title != null) {
+			swtItem.setText(escapeAccelerators(title));
+		} else if (viewClass != null) {
+			swtItem.setText(viewClass.getSimpleName());
+		}
+		if (buildonSWTItemSet) {
+			build();
+		}
+		if (showonSWTItemSet) {
+			show();
+		}
+	}
+
+	public Item getSwtItem() {
+		return swtItem;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#setTitle(java.lang.String)
+	 */
+	public void setTitle(String title) {
+		super.setTitle(title);
+
+		if (swtItem != null) {
+			swtItem.setText(escapeAccelerators(title));
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#getVitalityImages()
+	 */
+	public MdiEntryVitalityImage[] getVitalityImages() {
+		return new MdiEntryVitalityImage[0];
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#close()
+	 */
+	public boolean close(boolean forceClose) {
+    // triggerCloseListener
+		if (!super.close(forceClose)) {
+			return false;
+		}
+
+		Utils.execSWTThread(new Runnable() {
+			public void run() {
+				if (swtItem != null && !swtItem.isDisposed()) {
+					swtItem.dispose();
+					swtItem = null;
+				} else if (view != null) {
+					setCoreView(null);
+
+					triggerCloseListeners(!SWTThread.getInstance().isTerminated());
+				}
+			}
+		});
+		return true;
+	}
+
+	public void redraw() {
+	}
+
+	public void widgetDisposed(DisposeEvent e) {
+		setSwtItem(null);
+
+		triggerCloseListeners(!SWTThread.getInstance().isTerminated());
+
+		UISWTViewCore view = getCoreView();
+		if (view != null) {
+			setCoreView(null);
+		}
+		SWTSkinObject so = getSkinObject();
+		if (so != null) {
+			setSkinObject(null, null);
+			so.getSkin().removeSkinObject(so);
+		}
+		
+		// delay saving of removing of auto-open flag.  If after the delay, we are 
+		// still alive, it's assumed the user invoked the close, and we should
+		// remove the auto-open flag
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				// even though execThreadLater will not run on close of app because
+				// the display is disposed, do a double check of tree disposal just
+				// in case.  We don't want to trigger close listeners or
+				// remove autoopen parameters if the user is closing the app (as
+				// opposed to closing  the sidebar)
+				if (SWTThread.getInstance().isTerminated()) {
+					return;
+				}
+
+				try {
+					COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
+				} catch (Exception e2) {
+					Debug.out(e2);
+				}
+
+				mdi.removeItem(TabbedEntry.this);
+				mdi.setEntryAutoOpen(id, null, false);
+			}
+		});
+	}
+
+	private String escapeAccelerators(String str) {
+		if (str == null) {
+			return (str);
+		}
+
+		return str.replaceAll("&", "&&");
+	}
+	
+	public void expandTo() {
+	}
+	
+	public void viewTitleInfoRefresh(ViewTitleInfo titleInfoToRefresh) {
+		super.viewTitleInfoRefresh(titleInfoToRefresh);
+
+		if (titleInfoToRefresh == null || this.viewTitleInfo != titleInfoToRefresh) {
+			return;
+		}
+		if (isDisposed()) {
+			return;
+		}
+
+		String textIndicator = null;
+		try {
+			textIndicator = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+		if (textIndicator != null) {
+			setPullTitleFromView(false);
+		}
+		
+		String newText = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
+		if (newText != null) {
+			if (textIndicator != null) {
+				newText += " (" + textIndicator + ")";
+			}
+			setPullTitleFromView(false);
+			setTitle(newText);
+		} else if (view != null) {
+			newText = view.getFullTitle();
+			if (textIndicator != null) {
+				newText += " (" + textIndicator + ")";
+			}
+			setTitle(newText);
+		}
+	}
+	
+	// @see com.aelitis.azureus.ui.mdi.MdiEntry#isSelectable()
+	public boolean isSelectable() {
+		return true;
+	}
+
+	// @see com.aelitis.azureus.ui.mdi.MdiEntry#setSelectable(boolean)
+	public void setSelectable(boolean selectable) {
+	}
+
+	// @see com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT#addListener(com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener)
+	public void addListener(MdiSWTMenuHackListener l) {
+		// TODO Auto-generated method stub
+	}
+
+	// @see com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT#removeListener(com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener)
+	public void removeListener(MdiSWTMenuHackListener l) {
+		// TODO Auto-generated method stub
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/mdi/TabbedMDI.java b/com/aelitis/azureus/ui/swt/mdi/TabbedMDI.java
new file mode 100644
index 0000000..51d8df4
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/mdi/TabbedMDI.java
@@ -0,0 +1,460 @@
+package com.aelitis.azureus.ui.swt.mdi;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.util.*;
+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.plugins.PluginUISWTSkinObject;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.views.IViewAlwaysInitialize;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryCreationListener;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectTabFolder;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+public class TabbedMDI
+	extends BaseMDI
+	implements AEDiagnosticsEvidenceGenerator
+{
+	private CTabFolder tabFolder;
+
+	public TabbedMDI() {
+		super();
+		AEDiagnostics.addEvidenceGenerator(this);
+	}
+
+	public Object skinObjectCreated(SWTSkinObject skinObject, Object params) {
+		super.skinObjectCreated(skinObject, params);
+
+		creatMDI();
+
+		try {
+			UIFunctionsManager.getUIFunctions().getUIUpdater().addUpdater(this);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+
+		return null;
+	}
+	
+	// @see com.aelitis.azureus.ui.swt.mdi.BaseMDI#skinObjectInitialShow(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
+	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
+
+		UIManager ui_manager = PluginInitializer.getDefaultInterface().getUIManager();
+		ui_manager.addUIListener(new UIManagerListener() {
+			public void UIDetached(UIInstance instance) {
+			}
+			
+			public void UIAttached(UIInstance instance) {
+				if (instance instanceof UISWTInstance) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							try {
+								loadCloseables();
+							} catch (Throwable t) {
+								Debug.out(t);
+							}
+
+							setupPluginViews();
+						}
+					});
+				}
+			}
+		});
+
+		return super.skinObjectInitialShow(skinObject, params);
+	}
+
+	private void creatMDI() {
+		if (soMain instanceof SWTSkinObjectTabFolder) {
+			tabFolder = ((SWTSkinObjectTabFolder) soMain).getTabFolder();
+		} else {
+			tabFolder = new CTabFolder((Composite) soMain.getControl(), SWT.TOP
+					| SWT.BORDER | SWT.CLOSE);
+		}
+
+		COConfigurationManager.addAndFireParameterListener("GUI_SWT_bFancyTab",
+				new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						Utils.execSWTThread(new AERunnable() {
+							public void runSupport() {
+								boolean simple = !COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab");
+								tabFolder.setSimple(simple);
+							}
+						});
+					}
+				});
+
+		Display display = tabFolder.getDisplay();
+
+		float[] hsb = tabFolder.getBackground().getRGB().getHSB();
+		hsb[2] *= (Constants.isOSX) ? 0.9 : 0.97;
+		tabFolder.setBackground(ColorCache.getColor(display, hsb));
+
+		hsb = tabFolder.getForeground().getRGB().getHSB();
+		hsb[2] *= (Constants.isOSX) ? 1.1 : 0.03;
+		tabFolder.setForeground(ColorCache.getColor(display, hsb));
+
+		tabFolder.setSelectionBackground(new Color[] {
+			display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
+			display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
+			display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)
+		}, new int[] {
+			10,
+			90
+		}, true);
+		tabFolder.setSelectionForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+
+		tabFolder.setSimple(!COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab"));
+
+		tabFolder.setMinimumCharacters(25);
+
+		tabFolder.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				TabbedEntry entry = (TabbedEntry) event.item.getData("TabbedEntry");
+				showEntry(entry);
+			}
+		});
+		
+		tabFolder.getDisplay().addFilter(SWT.KeyDown, new Listener() {
+			public void handleEvent(Event event) {
+				if ( tabFolder.isDisposed()){
+					return;
+				}
+				// Another window has control, skip filter
+				Control focus_control = tabFolder.getDisplay().getFocusControl();
+				if (focus_control != null
+						&& focus_control.getShell() != tabFolder.getShell()) {
+					return;
+				}
+
+				int key = event.character;
+				if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
+						&& event.character > 0)
+					key += 'a' - 1;
+
+				// ESC or CTRL+F4 closes current Tab
+				if (key == SWT.ESC
+						|| (event.keyCode == SWT.F4 && event.stateMask == SWT.CTRL)) {
+					MdiEntry entry = getCurrentEntry();
+					if (entry != null) {
+						entry.close(false);
+					}
+					event.doit = false;
+				} else if (event.keyCode == SWT.F6
+						|| (event.character == SWT.TAB && (event.stateMask & SWT.CTRL) != 0)) {
+					// F6 or Ctrl-Tab selects next Tab
+					// On Windows the tab key will not reach this filter, as it is
+					// processed by the traversal TRAVERSE_TAB_NEXT.  It's unknown
+					// what other OSes do, so the code is here in case we get TAB
+					if ((event.stateMask & SWT.SHIFT) == 0) {
+						event.doit = false;
+						selectNextTab(true);
+						// Shift+F6 or Ctrl+Shift+Tab selects previous Tab
+					} else if (event.stateMask == SWT.SHIFT) {
+						selectNextTab(false);
+						event.doit = false;
+					}
+				}
+			}
+		});
+
+		tabFolder.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				saveCloseables();
+			}
+		});
+	}
+
+	private void selectNextTab(boolean selectNext) {
+		if (tabFolder == null || tabFolder.isDisposed()) {
+			return;
+		}
+
+		final int nextOrPrevious = selectNext ? 1 : -1;
+		int index = tabFolder.getSelectionIndex() + nextOrPrevious;
+		if (index == 0 && selectNext || index == -2 || tabFolder.getItemCount() < 2) {
+			return;
+		}
+		if (index == tabFolder.getItemCount()) {
+			index = 0;
+		} else if (index < 0) {
+			index = tabFolder.getItemCount() - 1;
+		}
+
+		// instead of .setSelection, use showEntry which will ensure view de/activations
+		CTabItem item = tabFolder.getItem(index);
+		MdiEntry entry = (MdiEntry) item.getData("TabbedEntry");
+
+		if (entry != null) {
+			showEntry(entry);
+		}
+	}
+
+	public boolean showEntryByID(String id) {
+		return loadEntryByID(id, true);
+	}
+	
+	// @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#loadEntryByID(java.lang.String, boolean)
+	public boolean loadEntryByID(String id, boolean activate) {
+		return loadEntryByID(id, activate, false, null);
+	}
+
+	public boolean loadEntryByID(String id, boolean activate,
+			boolean onlyLoadOnce, Object datasource) {
+		MdiEntry entry = mapIdToEntry.get(id);
+		if (entry != null) {
+			if (datasource != null) {
+				entry.setDatasource(datasource);
+			}
+			if (activate) {
+				showEntry(entry);
+			}
+			return true;
+		}
+
+		@SuppressWarnings("deprecation")
+		boolean loadedOnce = COConfigurationManager.getBooleanParameter("tab.once." + id, false);
+		if (loadedOnce && onlyLoadOnce) {
+			return false;
+		}
+
+		MdiEntryCreationListener mdiEntryCreationListener = mapIdToCreationListener.get(id);
+		if (mdiEntryCreationListener != null) {
+			entry = mdiEntryCreationListener.createMDiEntry(id);
+			if (entry != null) {
+				if (datasource != null) {
+					entry.setDatasource(datasource);
+				}
+				if (onlyLoadOnce) {
+					COConfigurationManager.setParameter("tab.once." + id, true);
+				}
+				if (activate) {
+					showEntry(entry);
+				}
+				return true;
+			}
+		} else {
+			setEntryAutoOpen(id, datasource, true);
+		}
+
+		
+		return false;
+	}
+
+	public void showEntry(final MdiEntry newEntry) {
+		if (newEntry == null) {
+			return;
+		}
+		MdiEntry oldEntry = currentEntry;
+		if (newEntry == oldEntry) {
+			triggerSelectionListener(newEntry, newEntry);
+			return;
+		}
+
+		if (oldEntry != null) {
+			oldEntry.hide();
+		}
+
+		currentEntry = (MdiEntrySWT) newEntry; // assumed MdiEntrySWT
+
+		((BaseMdiEntry) newEntry).show();
+
+		triggerSelectionListener(newEntry, oldEntry);
+	}
+
+	public void updateUI() {
+		MdiEntry currentEntry = getCurrentEntry();
+		if (currentEntry != null) {
+			currentEntry.updateUI();
+		}
+	}
+	
+	private MdiEntry createEntryFromSkinRef(String parentID, String id,
+			String configID, String title, ViewTitleInfo titleInfo, Object params,
+			boolean closeable, int index) {
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			return oldEntry;
+		}
+
+		TabbedEntry entry = new TabbedEntry(this, skin, id);
+		entry.setTitle(title);
+		entry.setSkinRef(configID, params);
+		setupNewEntry(entry, id, index);
+		return entry;
+	}
+	
+	// @see com.aelitis.azureus.ui.swt.mdi.BaseMDI#createEntryFromSkinRef(java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo, java.lang.Object, boolean, java.lang.String)
+	public MdiEntry createEntryFromSkinRef(String parentID, String id,
+			String configID, String title, ViewTitleInfo titleInfo, Object params,
+			boolean closeable, String preferedAfterID) {
+		// afterid not fully supported yet
+		return createEntryFromSkinRef(parentID, id, configID, title, titleInfo,
+				params, closeable, "".equals(preferedAfterID) ? 0 : -1);
+	}
+
+	public MdiEntry createEntryFromEventListener(String parentID,
+			UISWTViewEventListener l, String id, boolean closeable, Object datasource) {
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			return oldEntry;
+		}
+
+		TabbedEntry entry = new TabbedEntry(this, skin, id);
+
+		entry.setDatasource(datasource);
+		entry.setEventListener(l);
+
+		setupNewEntry(entry, id, -1);
+
+		if (l instanceof IViewAlwaysInitialize) {
+			entry.build();
+		}
+
+		return entry;
+	}
+
+	public MdiEntry createEntryFromView(String parentID, UISWTViewCore view,
+			String id, Object datasource, boolean closeable, boolean show,
+			boolean expand) {
+		if (id == null) {
+			id = view.getClass().getName();
+			int i = id.lastIndexOf('.');
+			if (i > 0) {
+				id = id.substring(i + 1);
+			}
+		}
+
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			if (show) {
+				showEntry(oldEntry);
+			}
+			return oldEntry;
+		}
+
+		TabbedEntry entry = new TabbedEntry(this, skin, id);
+
+		entry.setCoreView(view);
+		entry.setDatasource(datasource);
+
+		setupNewEntry(entry, id, -1);
+
+		if (view instanceof IViewAlwaysInitialize) {
+			entry.build();
+		}
+		
+		if (show) {
+			showEntry(entry);
+		}
+		return entry;
+	}
+
+	private void setupNewEntry(final TabbedEntry entry, final String id,
+			final int index) {
+		synchronized (mapIdToEntry) {
+			mapIdToEntry.put(id, entry);
+		}
+
+		entry.setCloseable(true);
+
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				swt_setupNewEntry(entry, id, index);
+			}
+		});
+	}
+
+	private void swt_setupNewEntry(TabbedEntry entry, String id, int index) {
+		if (index < 0 || index >= tabFolder.getItemCount()) {
+			index = tabFolder.getItemCount();
+		}
+		CTabItem cTabItem = new CTabItem(tabFolder, SWT.CLOSE, index);
+		cTabItem.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				if (tabFolder.getItemCount() == 0) {
+					currentEntry = null;
+				}
+			}
+		});
+		cTabItem.setData("TabbedEntry", entry);
+		entry.setSwtItem(cTabItem);
+	}
+
+	public String getUpdateUIName() {
+		String name = "MDI";
+		MdiEntry entry = getCurrentEntry();
+		if (entry != null) {
+			name += "-" + entry.getId();
+		}
+		return name;
+	}
+
+	public void generate(IndentWriter writer) {
+		MdiEntrySWT[] entries = getEntriesSWT();
+		for (MdiEntrySWT entry : entries) {
+			if (entry == null) {
+				continue;
+			}
+
+			
+			UISWTViewCore view = entry.getCoreView();
+			if (!(view instanceof AEDiagnosticsEvidenceGenerator)) {
+				writer.println("TabbedMdi View (No Generator): " + entry.getId());
+				try {
+					writer.indent();
+
+					writer.println("Parent: " + entry.getParentID());
+					writer.println("Title: " + entry.getTitle());
+				} catch (Exception e) {
+
+				} finally {
+
+					writer.exdent();
+				}
+			}
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT#getEntryFromSkinObject(org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject)
+	public MdiEntrySWT getEntryFromSkinObject(PluginUISWTSkinObject pluginSkinObject) {
+		if (pluginSkinObject instanceof SWTSkinObject) {
+			Control control = ((SWTSkinObject) pluginSkinObject).getControl();
+			while (control != null && !control.isDisposed()) {
+				Object entry = control.getData("BaseMDIEntry");
+				if (entry instanceof BaseMdiEntry) {
+					BaseMdiEntry mdiEntry = (BaseMdiEntry) entry;
+					return mdiEntry;
+				}
+				control = control.getParent();
+			}
+		}
+		return null;
+	}
+	
+	public MdiEntry createHeader(String id, String title, String preferredAfterID) {
+		return null;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/player/PlayerInstallWindow.java b/com/aelitis/azureus/ui/swt/player/PlayerInstallWindow.java
new file mode 100644
index 0000000..169b2bb
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/player/PlayerInstallWindow.java
@@ -0,0 +1,141 @@
+/*
+ * Created on Mar 15, 2010 02:29 PM
+ * Copyright (C) 2010 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.player;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.ProgressBar;
+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 com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBox;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBoxListener;
+
+import org.gudy.azureus2.ui.swt.Utils;
+
+/**
+ * @author Gudy
+ * @created Mar 15, 2010
+ *
+ */
+public class PlayerInstallWindow
+	implements PlayerInstallerListener
+{
+	private final static boolean FAKE_DELAY = Constants.IS_CVS_VERSION;
+
+	private VuzeMessageBox box;
+
+	private ProgressBar progressBar;
+
+	private SWTSkinObjectText soProgressText;
+
+	private String progressText;
+
+	private SWTSkinObjectText soInstallPct;
+	
+	private PlayerInstaller installer;
+
+	public PlayerInstallWindow(PlayerInstaller installer) {
+		
+		this.installer = installer;
+		installer.setListener(this);
+	}
+
+	public void open() {
+		
+		box = new VuzeMessageBox("","", null, 0);
+		box.setSubTitle(MessageText.getString("dlg.player.install.subtitle"));
+		box.addResourceBundle(PlayerInstallWindow.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource("image.player.dlg.header");
+
+		this.progressText = MessageText.getString("dlg.player.install.description");
+		
+		box.setListener(new VuzeMessageBoxListener() {
+
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.install", "dlg.register.install",
+						soExtra);
+
+				SWTSkinObjectContainer soProgressBar = (SWTSkinObjectContainer) skin.getSkinObject("progress-bar");
+				if (soProgressBar != null) {
+					progressBar = new ProgressBar(soProgressBar.getComposite(),
+							SWT.HORIZONTAL);
+					progressBar.setMinimum(0);
+					progressBar.setMaximum(100);
+					progressBar.setLayoutData(Utils.getFilledFormData());
+				}
+				
+				soInstallPct = (SWTSkinObjectText) skin.getSkinObject("install-pct");
+
+				soProgressText = (SWTSkinObjectText) skin.getSkinObject("progress-text");
+				if (soProgressText != null && progressText != null) {
+					soProgressText.setText(progressText);
+				}
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				installer.setListener(null);
+				installer.cancel();
+			}
+		});
+	}
+
+	
+	public void failed() {
+		if (box != null) {
+			box.close(0);
+		}
+	}
+	
+	public void finished() {
+		if (box != null) {
+			box.close(0);
+		}
+	}
+	
+	public void progress(final int percent) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int pct = percent == 100 ? 99 : percent;
+				if (soInstallPct != null) {
+					soInstallPct.setText(MessageText.getString("dlg.auth.install.pct",
+							new String[] {
+								"" + pct
+							}));
+				}
+				if (progressBar != null && !progressBar.isDisposed()) {
+					// never reach 100%!
+					progressBar.setSelection(pct);
+				}
+			}
+		});
+		
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/player/PlayerInstaller.java b/com/aelitis/azureus/ui/swt/player/PlayerInstaller.java
new file mode 100644
index 0000000..6d8bd02
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/player/PlayerInstaller.java
@@ -0,0 +1,181 @@
+package com.aelitis.azureus.ui.swt.player;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.installer.InstallablePlugin;
+import org.gudy.azureus2.plugins.installer.PluginInstallationListener;
+import org.gudy.azureus2.plugins.installer.PluginInstaller;
+import org.gudy.azureus2.plugins.installer.StandardPlugin;
+import org.gudy.azureus2.plugins.update.Update;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+
+public class PlayerInstaller {
+	
+	private PlayerInstallerListener listener;
+	private PluginInstaller installer;
+	private volatile UpdateCheckInstance instance;
+	
+	private boolean	cancelled;
+	
+	public PlayerInstaller() {
+	}
+	
+	public void setListener(PlayerInstallerListener listener) {
+		this.listener = listener;
+	}
+	
+	public void 
+	cancel() 
+	{
+		UpdateCheckInstance to_cancel = null;
+		
+		synchronized( this ){
+			
+			cancelled = true;
+			
+			to_cancel = instance;
+		}
+		
+		if ( to_cancel != null ){
+			
+			to_cancel.cancel();
+		}
+	}
+		
+	public boolean install() {
+		
+		try{
+			
+			installer = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInstaller();
+			
+	 		StandardPlugin sp = installer.getStandardPlugin( "azemp" );
+						
+			Map<Integer, Object> properties = new HashMap<Integer, Object>();
+	
+			properties.put( UpdateCheckInstance.PT_UI_STYLE, UpdateCheckInstance.PT_UI_STYLE_NONE );
+				
+			properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
+
+			final AESemaphore sem = new AESemaphore("emp install");
+			final boolean[] result = new boolean[1];
+		
+			instance = 
+				installer.install(
+					new InstallablePlugin[]{ sp },
+					false,
+					properties,
+					new PluginInstallationListener() {
+
+						public void
+						completed()
+						{
+							result[0] = true;
+							if(listener != null) {
+								listener.finished();
+							}
+							sem.release();
+						}
+						
+						public void
+						cancelled()
+						{
+							result[0] = false;
+							if(listener != null) {
+								listener.finished();
+							}
+							sem.release();
+						}
+						
+						public void
+						failed(
+							PluginException	e )
+						{
+							result[0] = false;
+							if(listener != null) {
+								listener.finished();
+							}
+							sem.release();
+						}
+					});
+		
+			boolean kill_it;
+			
+			synchronized( this ){
+				
+				kill_it = cancelled;
+			}
+
+			if ( kill_it ){
+				
+				instance.cancel();
+				
+				return( false );
+			}
+			
+			instance.addListener(
+				new UpdateCheckInstanceListener() {
+
+					public void
+					cancelled(
+						UpdateCheckInstance		instance )
+					{							
+					}
+					
+					public void
+					complete(
+						UpdateCheckInstance		instance )
+					{
+	  					Update[] updates = instance.getUpdates();
+	 					
+	 					for ( final Update update: updates ){
+	 						
+	 						ResourceDownloader[] rds = update.getDownloaders();
+	 					
+	 						for ( ResourceDownloader rd: rds ){
+	 							
+	 							rd.addListener(
+	 								new ResourceDownloaderAdapter()
+	 								{
+	 									public void
+	 									reportActivity(
+	 										ResourceDownloader	downloader,
+	 										String				activity )
+	 									{
+	 										
+	 									}
+	 									
+	 									public void
+	 									reportPercentComplete(
+	 										ResourceDownloader	downloader,
+	 										int					percentage )
+	 									{
+	 										if(listener != null) {
+	 											listener.progress(percentage);
+	 										}
+	 									}
+	 								});
+	 						}
+	 					}
+					}
+				});
+					
+			sem.reserve();
+			
+			return result[0];
+			
+		}catch( Throwable e ){
+			
+
+		}
+		return false;
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/player/PlayerInstallerListener.java b/com/aelitis/azureus/ui/swt/player/PlayerInstallerListener.java
new file mode 100644
index 0000000..461ac4a
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/player/PlayerInstallerListener.java
@@ -0,0 +1,9 @@
+package com.aelitis.azureus.ui.swt.player;
+
+public interface PlayerInstallerListener {
+	
+	public void finished();
+	
+	public void progress(int percent);
+
+}
diff --git a/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallWindow.java b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallWindow.java
new file mode 100644
index 0000000..40aee51
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallWindow.java
@@ -0,0 +1,153 @@
+/*
+ * Created on Mar 15, 2010 02:29 PM
+ * Copyright (C) 2010 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.plugininstall;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.ProgressBar;
+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 com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBox;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBoxListener;
+
+import org.gudy.azureus2.ui.swt.Utils;
+
+/**
+ * @author Gudy
+ * @created Mar 15, 2010
+ *
+ */
+public class SimplePluginInstallWindow
+	implements SimplePluginInstallerListener
+{
+	private final static boolean FAKE_DELAY = Constants.IS_CVS_VERSION;
+
+	private VuzeMessageBox box;
+
+	private ProgressBar progressBar;
+
+	private SWTSkinObjectText soProgressText;
+
+	private String progressText;
+
+	private SWTSkinObjectText soInstallPct;
+	
+	private SimplePluginInstaller 	installer;
+	private String					resource_prefix;
+
+	public 
+	SimplePluginInstallWindow(
+		SimplePluginInstaller 	_installer, 
+		String 					_resource_prefix ) 
+	{
+		
+		installer 			= _installer;
+		resource_prefix		= _resource_prefix;
+		
+		installer.setListener(this);
+	}
+
+	public void open() {
+		
+		box = new VuzeMessageBox("","", null, 0);
+		box.setSubTitle(MessageText.getString( resource_prefix + ".subtitle" ));
+		box.addResourceBundle(SimplePluginInstallWindow.class,
+				SkinPropertiesImpl.PATH_SKIN_DEFS, "skin3_dlg_register");
+		box.setIconResource( resource_prefix + ".image" );
+
+		this.progressText = MessageText.getString( resource_prefix + ".description" );
+		
+		box.setListener(new VuzeMessageBoxListener() {
+
+			public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+				SWTSkin skin = soExtra.getSkin();
+				skin.createSkinObject("dlg.register.install", "dlg.register.install",
+						soExtra);
+
+				SWTSkinObjectContainer soProgressBar = (SWTSkinObjectContainer) skin.getSkinObject("progress-bar");
+				if (soProgressBar != null) {
+					progressBar = new ProgressBar(soProgressBar.getComposite(),
+							SWT.HORIZONTAL);
+					progressBar.setMinimum(0);
+					progressBar.setMaximum(100);
+					progressBar.setLayoutData(Utils.getFilledFormData());
+				}
+				
+				soInstallPct = (SWTSkinObjectText) skin.getSkinObject("install-pct");
+
+				soProgressText = (SWTSkinObjectText) skin.getSkinObject("progress-text");
+				if (soProgressText != null && progressText != null) {
+					soProgressText.setText(progressText);
+				}
+			}
+		});
+
+		box.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				installer.setListener(null);
+				try {
+					installer.cancel();
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		});
+	}
+
+	
+	public void failed( Throwable e) {
+		if (box != null) {
+			box.close(0);
+		}
+	}
+	
+	public void finished() {
+		if (box != null) {
+			box.close(0);
+		}
+	}
+	
+	public void progress(final int percent) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int pct = percent == 100 ? 99 : percent;
+				if (soInstallPct != null) {
+					soInstallPct.setText(MessageText.getString("dlg.auth.install.pct",
+							new String[] {
+								"" + pct
+							}));
+				}
+				if (progressBar != null && !progressBar.isDisposed()) {
+					// never reach 100%!
+					progressBar.setSelection(pct);
+				}
+			}
+		});
+		
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstaller.java b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstaller.java
new file mode 100644
index 0000000..9fc0545
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstaller.java
@@ -0,0 +1,289 @@
+package com.aelitis.azureus.ui.swt.plugininstall;
+
+import java.util.HashMap;
+import java.util.Map;
+
+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.plugins.PluginException;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.installer.InstallablePlugin;
+import org.gudy.azureus2.plugins.installer.PluginInstallationListener;
+import org.gudy.azureus2.plugins.installer.PluginInstaller;
+import org.gudy.azureus2.plugins.installer.StandardPlugin;
+import org.gudy.azureus2.plugins.update.Update;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.ui.UIFunctions;
+
+public class 
+SimplePluginInstaller 
+{
+	private String						plugin_id;
+	private UIFunctions.actionListener	action_listener;
+	
+	private SimplePluginInstallerListener listener;
+	private PluginInstaller installer;
+	private volatile UpdateCheckInstance instance;
+	
+	private boolean	completed;
+	private boolean	cancelled;
+	
+	public 
+	SimplePluginInstaller(
+		String								_plugin_id,
+		String								_resource_prefix,
+		final UIFunctions.actionListener	_action_listener )
+	{
+		plugin_id 		= _plugin_id;
+		
+		PluginInterface existing = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID( plugin_id );
+		
+		if ( existing != null ){
+			
+			if ( existing.getPluginState().isOperational()){
+				
+				_action_listener.actionComplete( true );
+				
+			}else{
+				
+				_action_listener.actionComplete( new Exception( "Plugin is installed but not operational" ));
+			}
+			
+			return;
+		}
+		
+		action_listener	= 
+			new UIFunctions.actionListener()
+			{
+				private boolean informed = false;
+			
+				public void 
+				actionComplete(
+					Object result )
+				{
+					synchronized( this ){
+						
+						if ( informed ){
+							
+							return;
+						}
+						
+						informed = true;
+					}
+					
+					_action_listener.actionComplete( result );
+				}
+			};
+			
+		SimplePluginInstallWindow window = new SimplePluginInstallWindow( this, _resource_prefix );
+			
+		window.open();
+		
+		AEThread2 installerThread = new AEThread2("plugin installer",true) {
+			public void 
+			run() 
+			{
+				install();
+			}
+		};
+		
+		installerThread.start();	
+	}
+	
+	public void 
+	setListener(
+		SimplePluginInstallerListener listener) 
+	{
+		this.listener = listener;
+	}
+	
+	public void 
+	cancel() 
+	{
+		UpdateCheckInstance to_cancel = null;
+		
+		synchronized( this ){
+			
+			if ( completed ){
+				
+				return;
+			}
+			
+			cancelled = true;
+			
+			to_cancel = instance;
+		}
+		
+		if ( to_cancel != null ){
+			
+			to_cancel.cancel();
+		}
+		
+		action_listener.actionComplete( new Exception( "Cancelled" ));
+	}
+		
+	public boolean 
+	install() 
+	{	
+		try{
+			
+			installer = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInstaller();
+			
+	 		StandardPlugin sp = installer.getStandardPlugin( plugin_id );
+						
+	 		if ( sp == null ){
+	 			
+	 			throw( new Exception( "Unknown plugin" ));
+	 		}
+	 		
+			Map<Integer, Object> properties = new HashMap<Integer, Object>();
+	
+			properties.put( UpdateCheckInstance.PT_UI_STYLE, UpdateCheckInstance.PT_UI_STYLE_NONE );
+				
+			properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
+
+			final AESemaphore sem = new AESemaphore( "plugin-install" );
+			
+			final Object[] result = new Object[]{ null };
+		
+			instance = 
+				installer.install(
+					new InstallablePlugin[]{ sp },
+					false,
+					properties,
+					new PluginInstallationListener() {
+
+						public void
+						completed()
+						{
+							synchronized( SimplePluginInstaller.this ){
+								
+								completed = true;
+							}
+							
+							result[0] = true;
+							
+							if ( listener != null ){
+								
+								listener.finished();
+							}
+							
+							sem.release();
+						}
+						
+						public void
+						cancelled()
+						{
+							result[0] =  new Exception( "Cancelled" );
+							
+							if ( listener != null ){
+								
+								listener.finished();
+							}
+														
+							sem.release();
+						}
+						
+						public void
+						failed(
+							PluginException	e )
+						{
+							result[0] = e;
+							
+							if ( listener != null ){
+								
+								listener.finished();
+							}
+														
+							sem.release();
+						}
+					});
+		
+			boolean kill_it;
+			
+			synchronized( this ){
+				
+				kill_it = cancelled;
+			}
+
+			if ( kill_it ){
+				
+				instance.cancel();
+				
+				action_listener.actionComplete( new Exception( "Cancelled" ));
+				
+				return( false );
+			}
+			
+			instance.addListener(
+				new UpdateCheckInstanceListener() {
+
+					public void
+					cancelled(
+						UpdateCheckInstance		instance )
+					{
+					}
+					
+					public void
+					complete(
+						UpdateCheckInstance		instance )
+					{
+	  					Update[] updates = instance.getUpdates();
+	 					
+	 					for ( final Update update: updates ){
+	 						
+	 						ResourceDownloader[] rds = update.getDownloaders();
+	 					
+	 						for ( ResourceDownloader rd: rds ){
+	 							
+	 							rd.addListener(
+	 								new ResourceDownloaderAdapter()
+	 								{
+	 									public void
+	 									reportActivity(
+	 										ResourceDownloader	downloader,
+	 										String				activity )
+	 									{										
+	 									}
+	 									
+	 									public void
+	 									reportPercentComplete(
+	 										ResourceDownloader	downloader,
+	 										int					percentage )
+	 									{
+	 										if ( listener != null ){
+	 											
+	 											listener.progress(percentage);
+	 										}
+	 									}
+	 								});
+	 						}
+	 					}
+					}
+				});
+					
+			sem.reserve();
+			
+			action_listener.actionComplete( result[0] );
+
+			return( result[0] instanceof Boolean );
+			
+		}catch( Throwable e ){
+			
+			if ( listener != null ){
+				
+				listener.finished();
+			}
+
+			action_listener.actionComplete( e );
+		}
+		
+		return false;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallerListener.java b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallerListener.java
new file mode 100644
index 0000000..70791f9
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/plugininstall/SimplePluginInstallerListener.java
@@ -0,0 +1,11 @@
+package com.aelitis.azureus.ui.swt.plugininstall;
+
+public interface SimplePluginInstallerListener {
+	
+	public void finished();
+	
+	public void progress(int percent);
+	
+	public void failed( Throwable e );
+
+}
diff --git a/com/aelitis/azureus/ui/swt/search/network/NetworkSearch.java b/com/aelitis/azureus/ui/swt/search/network/NetworkSearch.java
deleted file mode 100644
index 4a1055a..0000000
--- a/com/aelitis/azureus/ui/swt/search/network/NetworkSearch.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Created on Jul 11, 2006 8:57:55 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.search.network;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.swt.browser.Browser;
-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.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.ipc.IPCInterface;
-import org.gudy.azureus2.pluginsimpl.local.ipc.IPCInterfaceImpl;
-
-import com.aelitis.azureus.core.AzureusCore;
-
-/**
- * @author PARG!
- * @created Jul 11, 2006
- *
- */
-public class NetworkSearch
-{
-	private static final LogIDs LOGID = LogIDs.GUI;
-
-	public static void search(AzureusCore core, String searchText, Browser browser) {
-		new NetworkSearch(core, searchText, browser);
-	}
-
-	protected NetworkSearch(AzureusCore core, String searchText, Browser browser) {
-		PluginInterface pi = core.getPluginManager().getPluginInterfaceByID(
-				"azsearch", false);
-
-		if (pi == null) {
-
-			Logger.log(new LogEvent(LOGID, "Search plugin not found"));
-
-			return;
-		}
-
-		if (!pi.getPluginState().isOperational()) {
-
-			Logger.log(new LogEvent(LOGID, "Search plugin not operational"));
-
-			return;
-		}
-		
-		Logger.log(new LogEvent(LOGID, "Search plugin functionality disabled"));
-		/*
-
-		Map params = new HashMap();
-
-		params.put("expression", searchText);
-
-		params.put("swtbrowser", browser);
-
-		try {
-			IPCInterface my_ipc = new IPCInterfaceImpl(this);
-
-			pi.getIPC().invoke("search", new Object[] {
-				my_ipc,
-				params
-			});
-
-		} catch (Throwable e) {
-
-			Logger.log(new LogEvent(LOGID, "IPC to search plugin failed", e));
-		}
-		*/
-	}
-
-	public void searchCallback(Map params) {
-		System.out.println("NetworkSearch::callback - " + params);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/AuthorizeWindow.java b/com/aelitis/azureus/ui/swt/shells/AuthorizeWindow.java
deleted file mode 100644
index 6bbc565..0000000
--- a/com/aelitis/azureus/ui/swt/shells/AuthorizeWindow.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Created on Dec 2, 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.shells;
-
-import org.gudy.azureus2.ui.swt.Utils;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.messenger.browser.BrowserMessage;
-import com.aelitis.azureus.core.messenger.browser.listeners.AbstractBrowserMessageListener;
-import com.aelitis.azureus.util.ContentNetworkUtils;
-
-/**
- * @author TuxPaper
- * @created Dec 2, 2008
- *
- */
-public class AuthorizeWindow
-{
-	public static boolean open = false;
-
-	public static boolean openAuthorizeWindow(final ContentNetwork cn) {
-		if (open) {
-			return false;
-		}
-		open = true;
-		try {
-  		String authURL = ContentNetworkUtils.getUrl(cn,
-  				ContentNetwork.SERVICE_AUTHORIZE, new Object[] {
-  					cn.getPersistentProperty(ContentNetwork.PP_SOURCE_REF)
-  				});
-  		BrowserWindow browserWindow = new BrowserWindow(Utils.findAnyShell(),
-  				authURL, 560, 390, false, true);
-  
-  		final Boolean[] b = new Boolean[1];
-  		b[0] = Boolean.FALSE;
-  
-  		ClientMessageContext context = browserWindow.getContext();
-  		context.addMessageListener(new AbstractBrowserMessageListener(
-  				"contentnetwork") {
-  			public void handleMessage(BrowserMessage message) {
-  				String opid = message.getOperationId();
-  
-  				if ("authorize".equals(opid)) {
-  					cn.setPersistentProperty(ContentNetwork.PP_AUTH_PAGE_SHOWN,
-  							Boolean.TRUE);
-  					b[0] = Boolean.TRUE;
-  				}
-  			}
-  		});
-  
-  		browserWindow.waitUntilClosed();
-  
-  		return b[0].booleanValue();
-		} finally {
-			open = false;
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java b/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
index db58364..0b8da40 100644
--- a/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/BrowserWindow.java
@@ -34,6 +34,7 @@ import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.messenger.ClientMessageContext;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
 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.TorrentListener;
@@ -51,7 +52,7 @@ public class BrowserWindow
 
 	private ClientMessageContext context;
 
-	private Browser browser;
+	private BrowserWrapper browser;
 	
 	public BrowserWindow(Shell parent, String url, double wPct, double hPct,
 			boolean allowResize, boolean isModal) {
@@ -116,7 +117,7 @@ public class BrowserWindow
 		});
 
 
-		browser = Utils.createSafeBrowser(shell, SWT.NONE);
+		browser = new BrowserWrapper( Utils.createSafeBrowser(shell, SWT.NONE));
 		
 		if (browser == null) {
 			shell.dispose();
diff --git a/com/aelitis/azureus/ui/swt/shells/RemotePairingWindow.java b/com/aelitis/azureus/ui/swt/shells/RemotePairingWindow.java
new file mode 100644
index 0000000..e762fa0
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/RemotePairingWindow.java
@@ -0,0 +1,673 @@
+/**
+ * Created on Jan 5, 2010
+ *
+ * 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.shells;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+
+import org.gudy.azureus2.plugins.PluginException;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.installer.*;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.pairing.*;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog;
+import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener;
+import com.aelitis.azureus.util.StringCompareUtils;
+
+/**
+ * @author TuxPaper
+ * @created Jan 5, 2010
+ *
+ */
+public class RemotePairingWindow
+	implements PairingManagerListener
+{
+	private static final String PLUGINID_WEBUI = "xmwebui";
+
+	private static final boolean SHOW_SPEW = false;
+
+	private static final boolean DEBUG = false;
+
+	static RemotePairingWindow instance = null;
+
+	private SkinnedDialog skinnedDialog;
+
+	private SWTSkin skin;
+
+	private SWTSkinObjectButton soEnablePairing;
+
+	private PairingManager pairingManager;
+
+	private SWTSkinObject soCodeArea;
+
+	private Font fontCode;
+
+	private String accessCode;
+
+	private Control control;
+
+	private SWTSkinObjectText soStatusText;
+
+	private SWTSkinObject soFTUX;
+
+	private SWTSkinObject soCode;
+
+	private SWTSkinObjectText soToClipboard;
+
+	private boolean hideCode = true;
+
+	private String fallBackStatusText = "";
+
+	private static testPairingClass testPairingClass;
+
+	private PairingTest pairingTest;
+
+	private boolean alreadyTested;
+
+	private String storedToClipboardText;
+
+	private String lastPairingTestError;
+
+	public static void open() {
+		if (DEBUG) {
+			if (testPairingClass == null) {
+				testPairingClass = new testPairingClass();
+			} else {
+				testPairingClass.inc();
+			}
+		}
+
+		synchronized (RemotePairingWindow.class) {
+			if (instance == null) {
+				instance = new RemotePairingWindow();
+			}
+		}
+
+		CoreWaiterSWT.waitForCore(TriggerInThread.SWT_THREAD,
+				new AzureusCoreRunningListener() {
+					public void azureusCoreRunning(AzureusCore core) {
+						instance._open();
+					}
+				});
+	}
+
+	private PluginInterface getWebUI() {
+		return AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+				PLUGINID_WEBUI, true);
+	}
+
+	private void _open() {
+		alreadyTested = false;
+
+		pairingManager = PairingManagerFactory.getSingleton();
+		PluginInterface piWebUI = getWebUI();
+
+		boolean showFTUX = piWebUI == null || !pairingManager.isEnabled();
+
+		if (skinnedDialog == null || skinnedDialog.isDisposed()) {
+			skinnedDialog = new SkinnedDialog("skin3_dlg_remotepairing", "shell",
+					SWT.DIALOG_TRIM);
+
+			skin = skinnedDialog.getSkin();
+
+			soCodeArea = skin.getSkinObject("code-area");
+			control = soCodeArea.getControl();
+
+			soEnablePairing = (SWTSkinObjectButton) skin.getSkinObject("enable-pairing");
+			soEnablePairing.addSelectionListener(new ButtonListenerAdapter() {
+				// @see com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter#pressed(com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility, com.aelitis.azureus.ui.swt.skin.SWTSkinObject, int)
+				public void pressed(SWTSkinButtonUtility buttonUtility,
+						SWTSkinObject skinObject, int stateMask) {
+					skinObject.getControl().setEnabled(false);
+
+					if (!pairingManager.isEnabled()) {
+						// enabling will automatically get access code and trigger
+						// somethingChanged
+						pairingManager.setEnabled(true);
+						if (SHOW_SPEW) {
+							System.out.println("PAIR] SetEnabled");
+						}
+					} else {
+						// fire something changed ourselves, so that accesscode gets
+						// picked up
+						if (SHOW_SPEW) {
+							System.out.println("PAIR] AlreadyEnabled");
+						}
+						somethingChanged(pairingManager);
+					}
+
+					if (getWebUI() == null) {
+						installWebUI();
+					} else {
+						switchToCode();
+					}
+				}
+			});
+
+			soFTUX = skin.getSkinObject("pairing-ftux");
+			soCode = skin.getSkinObject("pairing-code");
+
+			soStatusText = (SWTSkinObjectText) skin.getSkinObject("status-text");
+			soStatusText.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+				public boolean urlClicked(URLInfo urlInfo) {
+					if (urlInfo.url.equals("retry")) {
+						if (DEBUG) {
+							testPairingClass.inc();
+						}
+						alreadyTested = false;
+						testPairing(false);
+						return true;
+					}
+					return false;
+				}
+			});
+
+			pairingManager.addListener(this);
+
+			Font font = control.getFont();
+			GC gc = new GC(control);
+			fontCode = FontUtils.getFontWithHeight(font, gc, Constants.isWindows ? 20
+					: 18, SWT.BOLD);
+			gc.dispose();
+			control.setFont(fontCode);
+
+			control.addPaintListener(new PaintListener() {
+				public void paintControl(PaintEvent e) {
+					Color oldColor = e.gc.getForeground();
+
+					Rectangle printArea = ((Composite) e.widget).getClientArea();
+					int fullWidth = printArea.width;
+					int fullHeight = printArea.height;
+					GCStringPrinter sp = new GCStringPrinter(e.gc,
+							MessageText.getString("remote.pairing.accesscode"), printArea,
+							false, false, SWT.NONE);
+					sp.calculateMetrics();
+					Point sizeAccess = sp.getCalculatedSize();
+
+					String drawAccessCode = accessCode == null ? "      " : accessCode;
+
+					int numBoxes = drawAccessCode == null ? 0 : drawAccessCode.length();
+					int boxSize = 25;
+					int boxSizeAndPadding = 30;
+					int allBoxesWidth = numBoxes * boxSizeAndPadding;
+					int textPadding = 15;
+					printArea.x = (fullWidth - (allBoxesWidth + sizeAccess.x + textPadding)) / 2;
+					printArea.width = sizeAccess.x;
+
+					sp.printString(e.gc, printArea, 0);
+					e.gc.setBackground(Colors.white);
+					e.gc.setForeground(Colors.blue);
+
+					int xStart = printArea.x + sizeAccess.x + textPadding;
+					int yStart = (fullHeight - boxSize) / 2;
+					for (int i = 0; i < numBoxes; i++) {
+						Rectangle r = new Rectangle(xStart + (i * boxSizeAndPadding),
+								yStart, boxSize, boxSize);
+						e.gc.fillRectangle(r);
+						e.gc.setForeground(Colors.blues[Colors.BLUES_DARKEST]);
+						e.gc.drawRectangle(r);
+						if (!hideCode) {
+							e.gc.setForeground(oldColor);
+							GCStringPrinter.printString(e.gc, "" + drawAccessCode.charAt(i),
+									r, false, false, SWT.CENTER);
+						}
+					}
+				}
+			});
+
+			soToClipboard = (SWTSkinObjectText) skin.getSkinObject("pair-clipboard");
+
+			soToClipboard.addUrlClickedListener(new SWTSkinObjectText_UrlClickedListener() {
+				public boolean urlClicked(URLInfo urlInfo) {
+					if (urlInfo.url.equals("new")) {
+						try {
+							accessCode = pairingManager.getReplacementAccessCode();
+						} catch (PairingException e) {
+							// ignore.. if error, lastErrorUpdates will trigger
+						}
+						control.redraw();
+						String s = soToClipboard.getText();
+						int i = s.indexOf("|");
+						if (i > 0) {
+							soToClipboard.setText(s.substring(0, i - 1));
+						}
+					} else if (urlInfo.url.equals("clip")) {
+						ClipboardCopy.copyToClipBoard(accessCode);
+					}
+					return true;
+				}
+			});
+			SWTSkinButtonUtility btnToClipboard = new SWTSkinButtonUtility(
+					soToClipboard);
+			btnToClipboard.addSelectionListener(new ButtonListenerAdapter() {
+				public void pressed(SWTSkinButtonUtility buttonUtility,
+						SWTSkinObject skinObject, int stateMask) {
+				}
+			});
+
+			skinnedDialog.addCloseListener(new SkinnedDialogClosedListener() {
+				public void skinDialogClosed(SkinnedDialog dialog) {
+					skinnedDialog = null;
+					pairingManager.removeListener(RemotePairingWindow.this);
+					Utils.disposeSWTObjects(new Object[] {
+						fontCode
+					});
+					if (pairingTest != null) {
+						pairingTest.cancel();
+					}
+				}
+			});
+
+			if (showFTUX) {
+				soFTUX.getControl().moveAbove(null);
+			}
+		}
+		hideCode = true;
+		skinnedDialog.open();
+		hideCode = false;
+
+		if (showFTUX) {
+			switchToFTUX();
+		} else {
+			switchToCode();
+		}
+	}
+
+	public void switchToFTUX() {
+		SWTSkinObject soPairInstallArea = skin.getSkinObject("pair-install");
+		if (soPairInstallArea != null) {
+			soPairInstallArea.getControl().moveAbove(null);
+		}
+		soFTUX.setVisible(true);
+		soCode.setVisible(false);
+	}
+
+	public void switchToCode() {
+		// use somethingChanged to trigger testPairing if needed
+		somethingChanged(pairingManager);
+
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+
+				if (skinnedDialog == null || skinnedDialog.isDisposed()) {
+					return;
+				}
+
+				SWTSkinObjectImage soImage = (SWTSkinObjectImage) skin.getSkinObject("status-image");
+				if (soImage != null) {
+					soImage.setImageByID("icon.spin", null);
+				}
+
+				SWTSkinObject soPairArea = skin.getSkinObject("reset-pair-area");
+				if (soPairArea != null) {
+					soPairArea.getControl().moveAbove(null);
+				}
+				soFTUX.setVisible(false);
+				soCode.setVisible(true);
+			}
+		});
+	}
+
+	protected void testPairing(boolean delay) {
+		if (SHOW_SPEW) {
+			System.out.println("PAIR] Want testPairing; alreadyTested="
+					+ alreadyTested + ";Delay?" + delay + ";"
+					+ Debug.getCompressedStackTrace());
+		}
+		if (alreadyTested) {
+			return;
+		}
+
+		lastPairingTestError = "";
+		alreadyTested = true;
+
+		storedToClipboardText = soToClipboard.getText();
+		try {
+			hideCode = true;
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					control.redraw();
+					SWTSkinObjectImage soImage = (SWTSkinObjectImage) skin.getSkinObject("status-image");
+					if (soImage != null) {
+						soImage.setImageByID("icon.spin", null);
+					}
+				}
+			});
+			soStatusText.setTextID("remote.pairing.test.running");
+			soStatusText.setTextColor(ColorCache.getColor(control.getDisplay(),
+					"#000000"));
+			soToClipboard.setText(" ");
+
+			final PairingTestListener testListener = new PairingTestListener() {
+				public void testStarted(PairingTest test) {
+				}
+
+				public void testComplete(PairingTest test) {
+					if ( skinnedDialog == null || skinnedDialog.isDisposed()) {
+						return;
+					}
+
+					int outcome = test.getOutcome();
+					String iconID = null;
+					String colorID = "#000000";
+					switch (outcome) {
+						case PairingTest.OT_SUCCESS:
+							fallBackStatusText = MessageText.getString("remote.pairing.test.success");
+							iconID = "icon.success";
+							colorID = "#007305";
+							break;
+
+						case PairingTest.OT_CANCELLED:
+							fallBackStatusText = test.getErrorMessage();
+							iconID = "icon.warning";
+							colorID = "#A97000";
+							break;
+
+						case PairingTest.OT_SERVER_FAILED:
+						case PairingTest.OT_SERVER_OVERLOADED:
+						case PairingTest.OT_SERVER_UNAVAILABLE:
+							fallBackStatusText = MessageText.getString(
+									"remote.pairing.test.unavailable", new String[] {
+										test.getErrorMessage()
+									});
+							iconID = "icon.warning";
+							colorID = "#C98000";
+							break;
+
+						default:
+							fallBackStatusText = MessageText.getString(
+									"remote.pairing.test.fail", new String[] {
+										test.getErrorMessage()
+									});
+							iconID = "icon.failure";
+							colorID = "#c90000";
+							break;
+					}
+
+					hideCode = false;
+					final String fIconID = iconID;
+					somethingChanged(pairingManager);
+					lastPairingTestError = pairingTest.getErrorMessage();
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							control.redraw();
+							SWTSkinObjectImage soImage = (SWTSkinObjectImage) skin.getSkinObject("status-image");
+							if (soImage != null) {
+								soImage.setImageByID(fIconID, null);
+							}
+						}
+					});
+					updateToolTip();
+					soStatusText.setText(fallBackStatusText);
+					soStatusText.setTextColor(ColorCache.getColor(control.getDisplay(),
+							colorID));
+					soToClipboard.setText(storedToClipboardText);
+				}
+			};
+			SimpleTimer.addEvent("testPairing", SystemTime.getOffsetTime(delay ? 5000
+					: 0), new TimerEventPerformer() {
+				public void perform(TimerEvent event) {
+					try {
+						pairingTest = pairingManager.testService(PLUGINID_WEBUI,
+								testListener);
+					} catch (PairingException e) {
+						finishFailedTest();
+
+						soStatusText.setText(Debug.getNestedExceptionMessage(e));
+						Debug.out(e);
+					}
+
+					if (pairingTest == null) {
+						finishFailedTest();
+					}
+				}
+			});
+
+			if (DEBUG) {
+				testListener.testComplete(testPairingClass);
+				return;
+			}
+		} catch (Exception e) {
+			finishFailedTest();
+
+			soStatusText.setText(Debug.getNestedExceptionMessage(e));
+			Debug.out(e);
+		}
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.1.0.5
+	 */
+	protected void updateToolTip() {
+		SWTSkinObjectImage soImage = (SWTSkinObjectImage) skin.getSkinObject("status-image");
+		if (soImage != null) {
+			String s = lastPairingTestError;
+			if (s == null) {
+				s = "";
+			}
+			
+			String status = pairingManager.getStatus();
+			if (status != null && status.length() > 0) {
+				if (s.length() > 0) {
+					s += "\n";
+				}
+				s += "Pairing Status: " + status;
+			}
+			String lastPairingErr = pairingManager.getLastServerError();
+			if (lastPairingErr != null && lastPairingErr.length() > 0) {
+				if (s.length() > 0) {
+					s += "\n";
+				}
+				s += "Pairing Error: " + lastPairingErr;
+			}
+			soImage.setTooltipID("!" + s + "!");
+		}
+	}
+
+	private void finishFailedTest() {
+		hideCode = false;
+		somethingChanged(pairingManager);
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				control.redraw();
+			}
+		});
+		if (storedToClipboardText != null && storedToClipboardText.length() > 0) {
+			soToClipboard.setText(storedToClipboardText);
+		}
+	}
+
+	protected void installWebUI() {
+		final PluginInstaller installer = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInstaller();
+
+		StandardPlugin vuze_plugin = null;
+
+		try {
+			vuze_plugin = installer.getStandardPlugin(PLUGINID_WEBUI);
+
+		} catch (Throwable e) {
+		}
+
+		if (vuze_plugin == null) {
+			return;
+		}
+
+		if (vuze_plugin.isAlreadyInstalled()) {
+			PluginInterface plugin = vuze_plugin.getAlreadyInstalledPlugin();
+			plugin.getPluginState().setDisabled(false);
+			return;
+		}
+
+		try {
+			switchToFTUX();
+
+			final SWTSkinObject soInstall = skin.getSkinObject("pairing-install");
+			final SWTSkinObject soLearnMore = skin.getSkinObject("learn-more");
+			if (soLearnMore != null) {
+				soLearnMore.setVisible(false);
+			}
+
+			Map<Integer, Object> properties = new HashMap<Integer, Object>();
+
+			properties.put(UpdateCheckInstance.PT_UI_STYLE,
+					UpdateCheckInstance.PT_UI_STYLE_SIMPLE);
+
+			properties.put(UpdateCheckInstance.PT_UI_PARENT_SWT_COMPOSITE,
+					soInstall.getControl());
+
+			properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
+
+			installer.install(new InstallablePlugin[] {
+				vuze_plugin
+			}, false, properties, new PluginInstallationListener() {
+				public void completed() {
+					if (soLearnMore != null) {
+						soLearnMore.setVisible(true);
+					}
+					switchToCode();
+				}
+
+				public void cancelled() {
+					Utils.execSWTThread(new AERunnable() {
+
+						public void runSupport() {
+
+							if ( skinnedDialog != null && !skinnedDialog.isDisposed()){
+							
+								skinnedDialog.close();
+								
+								skinnedDialog = null;
+							}
+						}
+					});
+				}
+
+				public void failed(PluginException e) {
+
+					Debug.out(e);
+					//Utils.openMessageBox(Utils.findAnyShell(), SWT.OK, "Error",
+					//		e.toString());
+				}
+			});
+
+		} catch (Throwable e) {
+
+			Debug.printStackTrace(e);
+		}
+	}
+
+	// @see com.aelitis.azureus.core.pairing.PairingManagerListener#somethingChanged(com.aelitis.azureus.core.pairing.PairingManager)
+	public void somethingChanged(PairingManager pm) {
+		if (skinnedDialog.isDisposed()) {
+			return;
+		}
+
+		updateToolTip();
+
+		String lastAccessCode = accessCode;
+
+		accessCode = pairingManager.peekAccessCode();
+		boolean newAccessCode = !StringCompareUtils.equals(lastAccessCode, accessCode);
+		if (accessCode != null && getWebUI() != null && !alreadyTested
+				&& !pm.hasActionOutstanding()) {
+			if (newAccessCode) {
+				// pause while registering..
+				testPairing(true);
+			} else {
+				testPairing(false);
+			}
+		}
+		if (newAccessCode) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					control.redraw();
+				}
+			});
+		}
+	}
+
+	public static class testPairingClass
+		implements PairingTest
+	{
+		int curOutcome = 0;
+
+		int[] testOutcomes = {
+			OT_SUCCESS,
+			OT_FAILED,
+			OT_CANCELLED,
+			OT_SERVER_FAILED,
+			OT_SERVER_OVERLOADED,
+			OT_SERVER_UNAVAILABLE
+		};
+
+		String[] testErrs = {
+			"Success",
+			"Could Not Connect blah blah technical stuff",
+			"You Cancelled (unpossible!)",
+			"Server Failed",
+			"Server Overloaded",
+			"Server Unavailable",
+		};
+
+		public void inc() {
+			curOutcome++;
+			if (curOutcome == testOutcomes.length) {
+				curOutcome = 0;
+			}
+		}
+
+		public int getOutcome() {
+			return testOutcomes[curOutcome];
+		}
+
+		public String getErrorMessage() {
+			return testErrs[curOutcome];
+		}
+
+		public void cancel() {
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java b/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
index 748d1a1..d6861ab 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/DebugMenuHelper.java
@@ -3,19 +3,26 @@ package com.aelitis.azureus.ui.swt.shells.main;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.*;
 
-import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateShell;
 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.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.util.ConstantsVuze;
+import com.aelitis.azureus.ui.swt.skin.SWTSkin;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBox;
+import com.aelitis.azureus.ui.swt.views.skin.VuzeMessageBoxListener;
 
 /**
  * A convenience class for creating the Debug menu
@@ -185,12 +192,117 @@ public class DebugMenuHelper
 		});
 
 		item = new MenuItem(menuDebug, SWT.NONE);
-		item.setText("FB");
+		item.setText("Alerts");
 		item.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
-				UIFunctionsManager.getUIFunctions().viewURL(ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL("facebookshare.start", true), null, null);
+				String text = "This is a  long message with lots of information and "
+						+ "stuff you really should read.  Are you still reading? Good, because "
+						+ "reading <a href=\"http://moo.com\">stimulates</a> the mind.\n\nYeah Baby.";
+
+				LogAlert logAlert = new LogAlert(true, LogAlert.AT_INFORMATION, "Simple");
+				Logger.log(logAlert);
+				logAlert = new LogAlert(true, LogAlert.AT_WARNING, text);
+				logAlert.details = "Details: \n\n" + text;
+				Logger.log(logAlert);
+				logAlert = new LogAlert(true, LogAlert.AT_ERROR, "ShortText");
+				logAlert.details = "Details";
+				Logger.log(logAlert);
+			}
+		});
+
+		item = new MenuItem(menuDebug, SWT.NONE);
+		item.setText("MsgBox");
+		item.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				VuzeMessageBox box = new VuzeMessageBox("Title", "Text", new String[] { "Ok", "Cancel" }, 0);
+				box.setListener(new VuzeMessageBoxListener() {
+					public void shellReady(Shell shell, SWTSkinObjectContainer soExtra) {
+						SWTSkin skin = soExtra.getSkin();
+						skin.createSkinObject("dlg.generic.test", "dlg.generic.test", soExtra);
+						skin.layout(soExtra);
+						shell.layout(true, true);
+					}
+				});
+				box.open(null);
 			}
 		});
+
+		item = new MenuItem(menuDebug, SWT.CASCADE);
+		item.setText("Size");
+		Menu menuSize = new Menu(menuDebug.getParent(), SWT.DROP_DOWN);
+		item.setMenu(menuSize);
+
+		int[] sizes = {
+			640, 430,
+			800, 550,
+			1024, 718,
+			1280, 700,
+		};
+		for (int i = 0; i < sizes.length; i += 2) {
+			final int x = sizes[i];
+			final int y = sizes[i + 1];
+			item = new MenuItem(menuSize, SWT.NONE);
+			item.setText("" + x + "," + y);
+			item.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell().setSize(x, y);
+				}
+			});
+		}
+		
+		item = new MenuItem(menuDebug, SWT.NONE);
+		item.setText("Obfuscated Shell Image");
+		item.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent ev) {
+				Display display = Display.getCurrent();
+				Shell[] shells = display.getShells();
+				for (int i = 0; i < shells.length; i++) {
+					try {
+						Shell shell = shells[i];
+						Image image = null;
+
+						if (shell.isDisposed() || !shell.isVisible()) {
+							continue;
+						}
+
+						if (shell.getData("class") instanceof ObfusticateShell) {
+							ObfusticateShell shellClass = (ObfusticateShell) shell.getData("class");
+
+							try {
+								image = shellClass.generateObfusticatedImage();
+							} catch (Exception e) {
+								Debug.out("Obfuscating shell " + shell, e);
+							}
+						} else {
+
+							Rectangle clientArea = shell.getClientArea();
+							image = new Image(display, clientArea.width, clientArea.height);
+
+							GC gc = new GC(shell);
+							try {
+								gc.copyArea(image, clientArea.x, clientArea.y);
+							} finally {
+								gc.dispose();
+							}
+						}
+
+						if (image != null) {
+							Shell shell2 = new Shell(display);
+							Rectangle bounds = image.getBounds();
+							shell2.setSize(bounds.width, bounds.height);
+							shell2.setBackgroundImage(image);
+							shell2.open();
+						}
+
+					} catch (Exception e) {
+						Logger.log(new LogEvent(LogIDs.GUI,
+								"Creating Obfusticated Image", e));
+					}
+				}
+
+			}
+		});
+
 		
 		return item;
 	}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainHelpers.java b/com/aelitis/azureus/ui/swt/shells/main/MainHelpers.java
new file mode 100644
index 0000000..2ba6cb9
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainHelpers.java
@@ -0,0 +1,59 @@
+/*
+ * Created on Sep 14, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.shells.main;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+
+public class 
+MainHelpers 
+{
+	private static boolean	done_xfer_bar;
+	
+	protected static void
+	initTransferBar()
+	{
+		UIFunctionsSWT ui_functions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		
+		if ( ui_functions == null ){
+			
+			return;
+		}
+		
+		synchronized( MainHelpers.class ){
+			
+			if ( done_xfer_bar ){
+				
+				return;
+			}
+			
+			done_xfer_bar = true;
+		}
+		
+		if ( COConfigurationManager.getBooleanParameter("Open Transfer Bar On Start")){
+			
+			ui_functions.showGlobalTransferBar();
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainMDISetup.java b/com/aelitis/azureus/ui/swt/shells/main/MainMDISetup.java
new file mode 100644
index 0000000..ae18153
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainMDISetup.java
@@ -0,0 +1,312 @@
+package com.aelitis.azureus.ui.swt.shells.main;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.config.impl.ConfigurationChecker;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.CategoryAdderWindow;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.views.stats.StatsView;
+
+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.cnetwork.ContentNetworkManagerFactory;
+import com.aelitis.azureus.core.util.FeatureAvailability;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+import com.aelitis.azureus.ui.swt.views.ViewTitleInfoBetaP;
+import com.aelitis.azureus.ui.swt.views.skin.SBC_ActivityTableView;
+import com.aelitis.azureus.ui.swt.views.skin.SBC_PlusFTUX;
+import com.aelitis.azureus.ui.swt.views.skin.SB_Transfers;
+import com.aelitis.azureus.ui.swt.views.skin.SB_Vuze;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
+import com.aelitis.azureus.util.ConstantsVuze;
+import com.aelitis.azureus.util.ContentNetworkUtils;
+
+public class MainMDISetup
+{
+	public static void setupSideBar(final MultipleDocumentInterface mdi, final MdiListener l) {
+		if (Utils.isAZ2UI()) {
+			setupSidebarClassic(mdi);
+		} else {
+			setupSidebarVuze(mdi);
+		}
+
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				final String CFG_STARTTAB = "v3.StartTab";
+				String startTab;
+				boolean showWelcome = COConfigurationManager.getBooleanParameter("v3.Show Welcome");
+				if (ConfigurationChecker.isNewVersion()) {
+					showWelcome = true;
+				}
+
+				ContentNetwork startupCN = ContentNetworkManagerFactory.getSingleton().getStartupContentNetwork();
+				if (!startupCN.isServiceSupported(ContentNetwork.SERVICE_WELCOME)) {
+					showWelcome = false;
+				}
+
+				if (showWelcome) {
+					startTab = SideBar.SIDEBAR_SECTION_WELCOME;
+				} else {
+					if (!COConfigurationManager.hasParameter(CFG_STARTTAB, true)) {
+						COConfigurationManager.setParameter(CFG_STARTTAB,
+								SideBar.SIDEBAR_SECTION_LIBRARY);
+					}
+					startTab = COConfigurationManager.getStringParameter(CFG_STARTTAB);
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+					if (mdi == null || mdi.getEntry(startTab) == null) {
+						startTab = SideBar.SIDEBAR_SECTION_LIBRARY;
+					}
+				}
+				if (startTab.equals(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS)) {
+					SBC_PlusFTUX.setSourceRef("lastview");
+				}
+				mdi.showEntryByID(startTab);
+				if (l != null) {
+					mdi.addListener(l);
+				}
+			}
+		});
+		
+		COConfigurationManager.addAndFireParameterListener(
+				"Beta Programme Enabled", new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						boolean enabled = COConfigurationManager.getBooleanParameter("Beta Programme Enabled");
+						if (enabled) {
+							mdi.loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_BETAPROGRAM, false);
+						}
+					}
+		});
+		
+		mdi.registerEntry(StatsView.VIEW_ID, new MdiEntryCreationListener() {
+			public MdiEntry createMDiEntry(String id) {
+				MdiEntry entry = mdi.createEntryFromEventListener(
+						MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS,
+						new StatsView(), id, true, null);
+				return entry;
+			}
+		});
+
+		//		System.out.println("Activate sidebar " + startTab + " took "
+		//				+ (SystemTime.getCurrentTime() - startTime) + "ms");
+		//		startTime = SystemTime.getCurrentTime();
+	}
+	
+	private static void setupSidebarClassic(final MultipleDocumentInterface mdi) {
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY,
+				new MdiEntryCreationListener() {
+
+					public MdiEntry createMDiEntry(String id) {
+						boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals(
+								"az2");
+						String title = uiClassic ? "{MyTorrentsView.mytorrents}"
+								: ("{sidebar."
+										+ MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY + "}");
+						MdiEntry entry = mdi.createEntryFromSkinRef(null,
+								MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY, "library",
+								title, null, null, false,
+								MultipleDocumentInterface.SIDEBAR_POS_FIRST);
+						entry.setImageLeftID("image.sidebar.library");
+						return entry;
+					}
+				});
+
+		mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY);
+	}
+
+	
+	private static void setupSidebarVuze(final MultipleDocumentInterface mdi) {
+		MdiEntry entry;
+
+		String[] preferredOrder = new String[] {
+			MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+			MultipleDocumentInterface.SIDEBAR_HEADER_TRANSFERS,
+			MultipleDocumentInterface.SIDEBAR_HEADER_DEVICES,
+			MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS,
+			MultipleDocumentInterface.SIDEBAR_HEADER_DVD,
+			MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS,
+		};
+		mdi.setPreferredOrder(preferredOrder);
+
+		boolean[] disableCollapses = {
+			false,
+			true,
+			false,
+			false,
+			false,
+			false
+		};
+		for (int i = 0; i < preferredOrder.length; i++) {
+			String id = preferredOrder[i];
+			final boolean disableCollapse = disableCollapses[i];
+			mdi.registerEntry(id, new MdiEntryCreationListener() {
+				public MdiEntry createMDiEntry(String id) {
+					MdiEntry entry = mdi.createHeader(id, "sidebar." + id, null);
+					if (disableCollapse) {
+						entry.setCollapseDisabled(true);
+					} else {
+						entry.setDefaultExpanded(true);
+					}
+
+					if (id.equals(MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS)) {
+						entry.addListener(new MdiChildCloseListener() {
+							public void mdiChildEntryClosed(MdiEntry parent, MdiEntry child,
+									boolean user) {
+								if (mdi.getChildrenOf(parent.getId()).size() == 0) {
+									parent.close(true);
+								}
+							}
+						});
+						
+						PluginInterface pi = PluginInitializer.getDefaultInterface();
+						UIManager uim = pi.getUIManager();
+						MenuManager menuManager = uim.getMenuManager();
+						MenuItem menuItem;
+
+						menuItem = menuManager.addMenuItem("sidebar."
+								+ MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS,
+								"label.plugin.options");
+						
+						menuItem.addListener(new MenuItemListener() {
+							public void selected(MenuItem menu, Object target) {
+								UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+								if (uif != null) {
+
+									uif.openView(UIFunctions.VIEW_CONFIG, "plugins");
+								}
+							}
+						});
+					}
+
+					return entry;
+				}
+			});
+		}
+
+		mdi.loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY, false);
+		mdi.loadEntryByID(
+				MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY_UNOPENED, false);
+		mdi.loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_SUBSCRIPTIONS,
+				false);
+		mdi.loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_DEVICES, false);
+
+		entry = mdi.createEntryFromSkinRef(
+				MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+				ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork()),
+				"main.area.browsetab", "{sidebar.VuzeHDNetwork}",
+				null, null, false, null);
+		entry.setImageLeftID("image.sidebar.vuze");
+
+		/*
+		ContentNetworkManager cnm = ContentNetworkManagerFactory.getSingleton();
+		if (cnm != null) {
+			ContentNetwork[] contentNetworks = cnm.getContentNetworks();
+			for (ContentNetwork cn : contentNetworks) {
+				if (cn == null) {
+					continue;
+				}
+				if (cn.getID() == ConstantsVuze.getDefaultContentNetwork().getID()) {
+					cn.setPersistentProperty(ContentNetwork.PP_ACTIVE, Boolean.TRUE);
+					continue;
+				}
+
+				Object oIsActive = cn.getPersistentProperty(ContentNetwork.PP_ACTIVE);
+				boolean isActive = (oIsActive instanceof Boolean)
+						? ((Boolean) oIsActive).booleanValue() : false;
+				if (isActive) {
+					mdi.createContentNetworkSideBarEntry(cn);
+				}
+			}
+		}
+		*/
+
+		if (Constants.isWindows && FeatureAvailability.isGamesEnabled()) {
+			mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_GAMES,
+					new MdiEntryCreationListener() {
+						public MdiEntry createMDiEntry(String id) {
+							MdiEntry entry = mdi.createEntryFromSkinRef(
+									MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+									MultipleDocumentInterface.SIDEBAR_SECTION_GAMES,
+									"main.generic.browse",
+									"{mdi.entry.games}", null, null, true,
+									null);
+							((BaseMdiEntry) entry).setPreferredAfterID(ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork()));
+							String url = ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL(
+									"starts/games.start", false);
+							entry.setDatasource(url);
+							entry.setImageLeftID("image.sidebar.games");
+							return entry;
+						}
+					});
+			mdi.loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_GAMES, false,
+					true, null);
+		}
+
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_ABOUTPLUGINS,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						MdiEntry entry = mdi.createEntryFromSkinRef(
+								MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS,
+								MultipleDocumentInterface.SIDEBAR_SECTION_ABOUTPLUGINS,
+								"main.generic.browse",
+								"{mdi.entry.about.plugins}", null, null,
+								true, MultipleDocumentInterface.SIDEBAR_POS_FIRST);
+						String url = ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL(
+								"plugins", true);
+						entry.setDatasource(url);
+						entry.setImageLeftID("image.sidebar.plugin");
+						return entry;
+					}
+				});
+		//loadEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_ABOUTPLUGINS, true, false);
+
+		// building plugin views needs UISWTInstance, which needs core.
+		final int burnInfoShown = COConfigurationManager.getIntParameter(
+				"burninfo.shown", 0);
+		if (burnInfoShown == 0) {
+			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+				public void azureusCoreRunning(AzureusCore core) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							if (FeatureManagerUI.enabled) {
+								// blah, can't add until plugin initialization is done
+
+								mdi.loadEntryByID(
+										MultipleDocumentInterface.SIDEBAR_SECTION_PLUS, false);
+
+								if (!FeatureManagerUI.hasFullBurn()) {
+									mdi.loadEntryByID(
+											MultipleDocumentInterface.SIDEBAR_SECTION_BURN_INFO,
+											false);
+								}
+
+								COConfigurationManager.setParameter("burninfo.shown",
+										burnInfoShown + 1);
+							}
+						}
+					});
+				}
+			});
+		}
+
+		SBC_ActivityTableView.setupSidebarEntry();
+
+		SB_Transfers.setup(mdi);
+		new SB_Vuze(mdi);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java b/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
index be4a326..1fb58c7 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainMenu.java
@@ -10,18 +10,23 @@ import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
 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.plugins.ui.toolbar.UIToolBarActivationListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
 import org.gudy.azureus2.ui.swt.Messages;
 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.mainwindow.*;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.ui.skin.SkinConstants;
+import com.aelitis.azureus.core.util.FeatureAvailability;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.shells.RemotePairingWindow;
 import com.aelitis.azureus.ui.swt.skin.SWTSkin;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinUtils;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
+import com.aelitis.azureus.ui.swt.views.skin.SBC_PlusFTUX;
 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;
@@ -31,26 +36,18 @@ import com.aelitis.azureus.util.ContentNetworkUtils;
 public class MainMenu
 	implements IMainMenu, IMenuConstants
 {
-	private static final boolean ALLOW_ACTIONBAR_HIDING = false;
-
-	private static final boolean ALLOW_SIDEBAR_HIDING = true;
-
 	final String PREFIX_V2 = "MainWindow.menu";
 
 	final String PREFIX_V3 = "v3.MainWindow.menu";
 
 	private Menu menuBar;
 
-	private final SWTSkin skin;
-
 	/**
 	 * Creates the main menu on the supplied shell
 	 * 
 	 * @param shell
 	 */
 	public MainMenu(SWTSkin skin, final Shell shell) {
-		this.skin = skin;
-
 		if (null == skin) {
 			throw new NullPointerException(
 					"The parameter [SWTSkin skin] can not be null");
@@ -81,12 +78,30 @@ public class MainMenu
 			addTorrentMenu();
 		}
 
-		addWindowMenu();
+		if (!Constants.isWindows) {
+			addWindowMenu();
+		}
 
 		// ===== Debug menu (development only)====
 		if (org.gudy.azureus2.core3.util.Constants.isCVSVersion()) {
-			Menu menuDebug = org.gudy.azureus2.ui.swt.mainwindow.DebugMenuHelper.createDebugMenuItem(menuBar);
-			DebugMenuHelper.createDebugMenuItem(menuDebug);
+			final Menu menuDebug = org.gudy.azureus2.ui.swt.mainwindow.DebugMenuHelper.createDebugMenuItem(menuBar);
+			menuDebug.addMenuListener(new MenuListener() {
+				
+				public void menuShown(MenuEvent e) {
+					MenuItem[] items = menuDebug.getItems();
+					Utils.disposeSWTObjects(items);
+					
+					DebugMenuHelper.createDebugMenuItem(menuDebug);
+					MenuFactory.addSeparatorMenuItem(menuDebug);
+					MenuItem menuItem = new MenuItem(menuDebug, SWT.PUSH);
+					menuItem.setText("Log Views");
+					menuItem.setEnabled(false);
+					PluginsMenuHelper.getInstance().buildPluginLogsMenu(menuDebug);
+				}
+				
+				public void menuHidden(MenuEvent e) {
+				}
+			});
 		}
 
 		addV3HelpMenu();
@@ -127,6 +142,7 @@ public class MainMenu
 		MenuItem openMenuItem = MenuFactory.createOpenMenuItem(fileMenu);
 		Menu openSubMenu = openMenuItem.getMenu();
 		MenuFactory.addOpenTorrentMenuItem(openSubMenu);
+		MenuFactory.addOpenURIMenuItem(openSubMenu);
 		MenuFactory.addOpenTorrentForTrackingMenuItem(openSubMenu);
 		MenuFactory.addOpenVuzeFileMenuItem(openSubMenu);
 
@@ -142,6 +158,18 @@ public class MainMenu
 
 		MenuFactory.addCreateMenuItem(fileMenu);
 
+		if (FeatureManagerUI.enabled) {
+			MenuFactory.addSeparatorMenuItem(fileMenu);
+  		MenuFactory.addMenuItem(fileMenu, "menu.plus", new Listener() {
+  			public void handleEvent(Event event) {
+  				SBC_PlusFTUX.setSourceRef("menu-file");
+
+  				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+  				mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_PLUS);
+  			}
+  		});
+		}
+
 		MenuFactory.addSeparatorMenuItem(fileMenu);
 		MenuFactory.addCloseWindowMenuItem(fileMenu);
 		MenuFactory.addCloseDetailsMenuItem(fileMenu);
@@ -166,7 +194,26 @@ public class MainMenu
 		try {
 			MenuItem viewItem = MenuFactory.createViewMenuItem(menuBar);
 			final Menu viewMenu = viewItem.getMenu();
+			
+			viewMenu.addListener(SWT.Show, new Listener() {
+				public void handleEvent(Event event) {
+					Utils.disposeSWTObjects(viewMenu.getItems());
+					buildSimpleViewMenu(viewMenu);
+				}
+			});
+		} catch (Exception e) {
+			Debug.out("Error creating View Menu", e);
+		}
+	}
 
+	/**
+	 * @param viewMenu
+	 *
+	 * @since 4.5.0.3
+	 */
+	protected void buildSimpleViewMenu(final Menu viewMenu) {
+		try {
+			
 			MenuFactory.addMenuItem(viewMenu, SWT.CHECK, PREFIX_V3 + ".view.sidebar",
 					new Listener() {
 						public void handleEvent(Event event) {
@@ -226,16 +273,51 @@ public class MainMenu
 				}
 			}
 
-			MenuFactory.addSeparatorMenuItem(viewMenu);
+			if (Constants.isWindows) {
+				MenuFactory.addSeparatorMenuItem(viewMenu);
+			}
+
+			boolean needsSep = false;
+			boolean enabled = COConfigurationManager.getBooleanParameter("Beta Programme Enabled");
+			if (enabled) {
+				MenuFactory.addMenuItem(viewMenu, SWT.CHECK, PREFIX_V2 + ".view.beta",
+						new Listener() {
+							public void handleEvent(Event event) {
+								MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+								if (mdi != null) {
+									mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_BETAPROGRAM);
+								}
+							}
+				});
+				needsSep = true;
+			}
+
+			if (Constants.isWindows && FeatureAvailability.isGamesEnabled()) {
+  			MenuFactory.addMenuItem(viewMenu, PREFIX_V3 + ".games", new Listener() {
+  				public void handleEvent(Event event) {
+  					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+  					mdi.showEntryByID(SideBar.SIDEBAR_SECTION_GAMES);
+  				}
+  			});
+				needsSep = true;
+			}
+			
+			needsSep |= PluginsMenuHelper.getInstance().buildViewMenu(viewMenu, viewMenu.getShell());
+
+			if (needsSep) {
+				MenuFactory.addSeparatorMenuItem(viewMenu);
+			}
 
 			MenuFactory.addMenuItem(viewMenu, SWT.RADIO, PREFIX_V3
 					+ ".view.asSimpleList", new Listener() {
 				public void handleEvent(Event event) {
 					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
 					if (tb != null) {
-						ToolBarItem item = tb.getToolBarItem("modeBig");
+						UIToolBarItem item = tb.getToolBarItem("modeBig");
 						if (item != null) {
-							item.triggerToolBarItem();
+							item.triggerToolBarItem(
+									UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL,
+									SelectedContentManager.convertSelectedContentToObject(null));
 						}
 					}
 				}
@@ -245,9 +327,11 @@ public class MainMenu
 				public void handleEvent(Event event) {
 					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
 					if (tb != null) {
-						ToolBarItem item = tb.getToolBarItem("modeSmall");
+						UIToolBarItem item = tb.getToolBarItem("modeSmall");
 						if (item != null) {
-							item.triggerToolBarItem();
+							item.triggerToolBarItem(
+									UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL,
+									SelectedContentManager.convertSelectedContentToObject(null));
 						}
 					}
 				}
@@ -260,9 +344,9 @@ public class MainMenu
 					MenuItem sidebarMenuItem = MenuFactory.findMenuItem(viewMenu,
 							PREFIX_V3 + ".view.sidebar");
 					if (sidebarMenuItem != null) {
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						if (sidebar != null) {
-							sidebarMenuItem.setSelection(sidebar.isVisible());
+						MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+						if (mdi != null) {
+							sidebarMenuItem.setSelection(mdi.isVisible());
 						}
 					}
 
@@ -280,15 +364,10 @@ public class MainMenu
 					if (itemShowAsSimple != null) {
 						ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
 						if (tb != null) {
-							ToolBarItem item = tb.getToolBarItem("modeBig");
-							if (item != null && item.isEnabled()) {
-								itemShowAsSimple.setEnabled(true);
-								itemShowAsSimple.setSelection(!item.getSkinButton().getSkinObject().getSuffix().equals(
-										""));
-							} else {
-								itemShowAsSimple.setEnabled(false);
-								itemShowAsSimple.setSelection(false);
-							}
+							UIToolBarItem item = tb.getToolBarItem("modeBig");
+							long state = item == null ? 0 : item.getState();
+							itemShowAsSimple.setEnabled((state & UIToolBarItem.STATE_ENABLED) > 0);
+							itemShowAsSimple.setSelection((state & UIToolBarItem.STATE_DOWN) > 0);
 						}
 					}
 					MenuItem itemShowAsAdv = MenuFactory.findMenuItem(viewMenu, PREFIX_V3
@@ -296,151 +375,22 @@ public class MainMenu
 					if (itemShowAsAdv != null) {
 						ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
 						if (tb != null) {
-							ToolBarItem item = tb.getToolBarItem("modeSmall");
-							if (item != null && item.isEnabled()) {
-								itemShowAsAdv.setEnabled(true);
-								itemShowAsAdv.setSelection(!item.getSkinButton().getSkinObject().getSuffix().equals(
-										""));
-							} else {
-								itemShowAsAdv.setSelection(false);
-								itemShowAsAdv.setEnabled(false);
-							}
-						}
-					}
-				}
-
-				public void menuHidden(MenuEvent e) {
-				}
-			});
-
-		} catch (Exception e) {
-			Debug.out("Error creating View Menu", e);
-		}
-	}
-
-	/**
-	 * Creates the View menu and all its children
-	 */
-	private void addViewMenu() {
-		try {
-			MenuItem viewItem = MenuFactory.createViewMenuItem(menuBar);
-			final Menu viewMenu = viewItem.getMenu();
-
-			addViewToolBarsMenu(viewMenu);
-
-			//addViewMenuItems(viewMenu);
-
-		} catch (Exception e) {
-			Debug.out("Error creating View Menu", e);
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void addViewToolBarsMenu(Menu parent) {
-		try {
-
-			MenuItem viewToolBarsItem = MenuFactory.createTopLevelMenuItem(parent,
-					PREFIX_V3 + ".view.toolbars");
-			final Menu viewToolBarsMenu = viewToolBarsItem.getMenu();
-
-			if (ALLOW_SIDEBAR_HIDING) {
-				MenuFactory.addMenuItem(viewToolBarsMenu, SWT.CHECK, PREFIX_V3
-						+ ".view.sidebar", new Listener() {
-					public void handleEvent(Event event) {
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						if (sidebar != null) {
-							sidebar.flipSideBarVisibility();
-						}
-					}
-				});
-			}
-
-			if (ALLOW_ACTIONBAR_HIDING) {
-				MenuFactory.addMenuItem(viewToolBarsMenu, SWT.CHECK, PREFIX_V3
-						+ ".view.actionbar", new Listener() {
-					public void handleEvent(Event event) {
-						if (skin != null) {
-							SWTSkinObject so = skin.getSkinObject(SkinConstants.VIEWID_TAB_BAR);
-							if (so != null) {
-								so.setVisible(!so.isVisible());
-							}
+							UIToolBarItem item = tb.getToolBarItem("modeSmall");
+							long state = item == null ? 0 : item.getState();
+							itemShowAsAdv.setEnabled((state & UIToolBarItem.STATE_ENABLED) > 0);
+							itemShowAsAdv.setSelection((state & UIToolBarItem.STATE_DOWN) > 0);
 						}
 					}
-				});
-			}
-
-			/*
-			 * NOTE: The following menu items must be created on-demand because
-			 * their creation code relies on the main window being in proper size already.
-			 * Adding these menus before the window is fully opened will result in improper
-			 * layout of the PluginBar and TabBar
-			 */
-			viewToolBarsMenu.addMenuListener(new MenuListener() {
-
-				public void menuShown(MenuEvent e) {
-
-					MenuItem sidebarMenuItem = MenuFactory.findMenuItem(viewToolBarsMenu,
-							PREFIX_V3 + ".view.sidebar");
-					if (sidebarMenuItem != null) {
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						if (sidebar != null) {
-							sidebarMenuItem.setSelection(sidebar.isVisible());
-						}
-					}
-
-					MenuItem actionbarMenuItem = MenuFactory.findMenuItem(
-							viewToolBarsMenu, PREFIX_V3 + ".view.actionbar");
-					if (actionbarMenuItem != null) {
-						if (skin != null) {
-							SWTSkinObject so = skin.getSkinObject(SkinConstants.VIEWID_TAB_BAR);
-							if (so != null) {
-								actionbarMenuItem.setSelection(so.isVisible());
-							}
-						}
-					}
-
-					if (null == MenuFactory.findMenuItem(viewToolBarsMenu, PREFIX_V3
-							+ ".view." + SkinConstants.VIEWID_PLUGINBAR)) {
-						createViewMenuItem(skin, viewToolBarsMenu, PREFIX_V3 + ".view."
-								+ SkinConstants.VIEWID_PLUGINBAR,
-								SkinConstants.VIEWID_PLUGINBAR + ".visible",
-								SkinConstants.VIEWID_PLUGINBAR, true, 0);
-					}
-
 				}
 
 				public void menuHidden(MenuEvent e) {
-					// Do nothing
 				}
-
 			});
 		} catch (Exception e) {
 			Debug.out("Error creating View Menu", e);
 		}
 	}
 
-	private void addViewMenuItems(Menu viewMenu) {
-
-		MenuFactory.addMenuItem(viewMenu, PREFIX_V3 + ".browse", new Listener() {
-			public void handleEvent(Event event) {
-				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-				sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_BROWSE);
-			}
-		});
-
-		MenuFactory.addMenuItem(viewMenu, PREFIX_V3 + ".library", new Listener() {
-			public void handleEvent(Event event) {
-				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-				sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
-			}
-		});
-
-	}
-
 	/**
 	 * Creates the Tools menu and all its children
 	 */
@@ -452,6 +402,7 @@ public class MainMenu
 		MenuFactory.addMySharesMenuItem(toolsMenu);
 		MenuFactory.addConsoleMenuItem(toolsMenu);
 		MenuFactory.addStatisticsMenuItem(toolsMenu);
+		MenuFactory.addSpeedLimitsToMenu(toolsMenu);
 
 		MenuFactory.addTransferBarToMenu(toolsMenu);
 		MenuFactory.addAllPeersMenuItem(toolsMenu);
@@ -461,10 +412,20 @@ public class MainMenu
 		MenuFactory.addSeparatorMenuItem(toolsMenu);
 		MenuFactory.createPluginsMenuItem(toolsMenu, true);
 
+		addPairingMenu(toolsMenu);
+		
 		MenuFactory.addOptionsMenuItem(toolsMenu);
 
 	}
 
+	private void addPairingMenu(Menu menu) {
+		MenuFactory.addMenuItem(menu, MENU_ID_PAIRING, new Listener() {
+			public void handleEvent(Event e) {
+				RemotePairingWindow.open();
+			}
+		});
+	}
+
 	/**
 	 * Creates the Help menu and all its children
 	 */
@@ -483,8 +444,10 @@ public class MainMenu
 		MenuFactory.addMenuItem(helpMenu, PREFIX_V3 + ".getting_started",
 				new Listener() {
 					public void handleEvent(Event event) {
-						SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-						sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_WELCOME);
+						MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+						if (mdi != null) {
+							mdi.showEntryByID(SideBar.SIDEBAR_SECTION_WELCOME);
+						}
 					}
 				});
 
@@ -492,12 +455,23 @@ public class MainMenu
 				helpMenu,
 				ContentNetworkUtils.getUrl(
 				ConstantsVuze.getDefaultContentNetwork(), ContentNetwork.SERVICE_SUPPORT));
+		
+		MenuFactory.addHealthMenuItem(helpMenu);
 
 		MenuFactory.addReleaseNotesMenuItem(helpMenu);
 
 		if (false == SystemProperties.isJavaWebStartInstance()) {
 			MenuFactory.addSeparatorMenuItem(helpMenu);
 			MenuFactory.addCheckUpdateMenuItem(helpMenu);
+			MenuFactory.addBetaMenuItem(helpMenu);
+		}
+		
+		if (FeatureManagerUI.enabled) {
+  		MenuFactory.addMenuItem(helpMenu, "menu.register", new Listener() {
+  			public void handleEvent(Event event) {
+  				FeatureManagerUI.openLicenceEntryWindow(false, null);
+  			}
+  		});
 		}
 		
 		MenuFactory.addDonationMenuItem(helpMenu);
@@ -506,6 +480,7 @@ public class MainMenu
 		MenuFactory.addConfigWizardMenuItem(helpMenu);
 		MenuFactory.addNatTestMenuItem(helpMenu);
 		MenuFactory.addSpeedTestMenuItem(helpMenu);
+		MenuFactory.addAdvancedHelpMenuItem(helpMenu);
 
 		MenuFactory.addSeparatorMenuItem(helpMenu);
 		MenuFactory.addDebugHelpMenuItem(helpMenu);
@@ -573,13 +548,6 @@ public class MainMenu
 								ContentNetwork.SERVICE_BLOG));
 					}
 				});
-
-		MenuFactory.addMenuItem(communityMenu, MENU_ID_FAQ, new Listener() {
-			public void handleEvent(Event e) {
-				Utils.launch(ContentNetworkUtils.getUrl(
-						ConstantsVuze.getDefaultContentNetwork(), ContentNetwork.SERVICE_FAQ));
-			}
-		});
 	}
 
 	//====================================
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java b/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
index aba389e..29cf0da 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainWindow.java
@@ -1,2346 +1,70 @@
-/*
- * Created on May 29, 2006 2:07:38 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.shells.main;
-
-import java.io.*;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.net.URLDecoder;
-import java.util.*;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.widgets.*;
-
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.config.impl.ConfigurationChecker;
-import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.download.DownloadManagerState;
-import org.gudy.azureus2.core3.global.*;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.logging.*;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-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.ui.sidebar.SideBarEntry;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarOpenListener;
-import org.gudy.azureus2.ui.swt.*;
-import org.gudy.azureus2.ui.swt.associations.AssociationChecker;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateShell;
-import org.gudy.azureus2.ui.swt.donations.DonationWindow;
-import org.gudy.azureus2.ui.swt.mainwindow.*;
-import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
-import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
-import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-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.systray.SystemTraySWT;
-
-import com.aelitis.azureus.activities.VuzeActivitiesManager;
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
-import com.aelitis.azureus.core.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.messenger.PlatformMessenger;
-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.PlatformTorrentUtils;
-import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
-import com.aelitis.azureus.launcher.Launcher;
-import com.aelitis.azureus.ui.IUIIntializer;
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-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.columns.utils.TableColumnCreatorV3;
-import com.aelitis.azureus.ui.swt.extlistener.StimulusRPC;
-import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.utils.PlayNowList;
-import com.aelitis.azureus.ui.swt.views.skin.*;
-import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager.SkinViewManagerListener;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.*;
-import com.aelitis.azureus.util.*;
-
-/**
- * @author TuxPaper
- * @created May 29, 2006
- *
- */
-public class MainWindow
-	implements IMainWindow, ObfusticateShell, SideBarListener,
-	AEDiagnosticsEvidenceGenerator, SideBarLogIdListener
-{
-
-	private static final LogIDs LOGID = LogIDs.GUI;
-
-	protected Shell shell;
-
-	private Display display;
-
-	private AzureusCore core;
-
-	private IUIIntializer uiInitializer;
-
-	private SWTSkin skin;
-
-	private MainMenu menu;
-
-	private UISWTInstanceImpl uiSWTInstanceImpl;
-
-	private UIFunctionsImpl uiFunctions;
-
-	private SystemTraySWT systemTraySWT;
-
-	private static Map mapTrackUsage = null;
-
-	private final static AEMonitor mapTrackUsage_mon = new AEMonitor(
-			"mapTrackUsage");
-
-	private long lCurrentTrackTime = 0;
-
-	private long lCurrentTrackTimeIdle = 0;
-
-	private boolean disposedOrDisposing;
-
-	private DownloadManager[] dms_Startup;
-
-	protected boolean isReady = false;
-
-	private MainStatusBar statusBar;
-
-	private String lastShellStatus = null;
-
-	private Color colorSearchTextBG;
-
-	private Color colorSearchTextFGdef;
-
-	private Color colorSearchTextFG;
-	
-	private boolean delayedCore;
-
-	public static void main(String args[]) {
-		if (Launcher.checkAndLaunch(MainWindow.class, args))
-			return;
-		Initializer.main(new String[0]);
-		//org.gudy.azureus2.ui.swt.Main.main(args);
-	}
-
-	/**
-	 * Old Initializer.  AzureusCore is required to be started
-	 * 
-	 * @param core
-	 * @param display
-	 * @param uiInitializer
-	 */
-	public MainWindow(AzureusCore core, Display display,
-			final IUIIntializer uiInitializer) {
-		delayedCore = false;
-		this.core = core;
-		this.display = display;
-		this.uiInitializer = uiInitializer;
-		AEDiagnostics.addEvidenceGenerator(this);
-
-		disposedOrDisposing = false;
-
-		// Hack for 3014 -> 3016 upgrades on Vista who become an Administrator
-		// user after restart.
-		if (Constants.isWindows
-				&& System.getProperty("os.name").indexOf("Vista") > 0
-				&& !COConfigurationManager.getBooleanParameter("vista.adminquit")) {
-			File fileFromInstall = FileUtil.getApplicationFile("license.txt");
-			if (fileFromInstall.exists()
-					&& fileFromInstall.lastModified() < new GregorianCalendar(2007, 06,
-							13).getTimeInMillis()) {
-				// install older than 3016
-				GlobalManager gm = core.getGlobalManager();
-				if (gm != null
-						&& gm.getDownloadManagers().size() == 0
-						&& gm.getStats().getTotalProtocolBytesReceived() < 1024 * 1024 * 100) {
-					File fileTestWrite = FileUtil.getApplicationFile("testwrite.dll");
-					fileTestWrite.deleteOnExit();
-					try {
-						FileOutputStream fos = new FileOutputStream(fileTestWrite);
-						fos.write(23);
-						fos.close();
-
-						COConfigurationManager.setParameter("vista.adminquit", true);
-						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();
-						}
-						dispose(false, false);
-						return;
-					} catch (Exception e) {
-					}
-				}
-			}
-		}
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				try {
-					createWindow(uiInitializer);
-				} catch (Throwable e) {
-					Logger.log(new LogAlert(false, "Error Initialize MainWindow", e));
-				}
-				if (uiInitializer != null) {
-					uiInitializer.abortProgress();
-				}
-			}
-		});
-
-		// When a download is added, check for new meta data and
-		// un-"wait state" the rating
-		// TODO: smart refreshing of meta data ("Refresh On" attribute)
-		GlobalManager gm = core.getGlobalManager();
-		dms_Startup = (DownloadManager[]) gm.getDownloadManagers().toArray(
-				new DownloadManager[0]);
-		gm.addListener(new GlobalManagerListener() {
-
-			public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
-			}
-
-			public void downloadManagerRemoved(DownloadManager dm) {
-			}
-
-			public void downloadManagerAdded(final DownloadManager dm) {
-				downloadAdded(new DownloadManager[] {
-					dm
-				});
-			}
-
-			public void destroyed() {
-			}
-
-			public void destroyInitiated() {
-			}
-
-		}, false);
-
-		gm.addDownloadWillBeRemovedListener(new GlobalManagerDownloadWillBeRemovedListener() {
-			public void downloadWillBeRemoved(DownloadManager dm,
-					boolean remove_torrent, boolean remove_data)
-
-					throws GlobalManagerDownloadRemovalVetoException {
-				TOTorrent torrent = dm.getTorrent();
-				if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
-
-					String prefix = "v3.mb.deletePurchased.";
-					String title = MessageText.getString(prefix + "title");
-					String text = MessageText.getString(prefix + "text", new String[] {
-						dm.getDisplayName()
-					});
-
-					MessageBoxShell mb = new MessageBoxShell(title, text,
-							new String[] {
-								MessageText.getString(prefix + "button.delete"),
-								MessageText.getString(prefix + "button.cancel")
-							}, 1);
-					mb.setRelatedObject(dm);
-
-					mb.open(null);
-					int result = mb.waitUntilClosed();
-					if (result != 0) {
-						throw new GlobalManagerDownloadRemovalVetoException("", true);
-					}
-				}
-			}
-		});
-
-		Alerts.addListener(new Alerts.AlertListener() {
-
-			public boolean allowPopup(Object[] relatedObjects, int configID) {
-				DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
-						relatedObjects, DownloadManager.class);
-
-				if (dm == null) {
-					return true;
-				}
-				if (dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-					return false;
-				}
-
-				HashWrapper hw;
-				try {
-					hw = dm.getTorrent().getHashWrapper();
-					if (PlayNowList.contains(hw)) {
-						return false;
-					}
-				} catch (TOTorrentException e) {
-				}
-				return true;
-			}
-
-		});
-	}
-
-	/**
-	 * New Initializer.  AzureusCore does not need to be started.
-	 * Use {@link #init(AzureusCore)} when core is available.
-	 * 
-	 * @param display
-	 * @param uiInitializer
-	 */
-	public MainWindow(final Display display, final IUIIntializer uiInitializer) {
-		delayedCore = true;
-		this.display = display;
-		this.uiInitializer = uiInitializer;
-
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				try {
-					createWindow(uiInitializer);
-				} catch (Throwable e) {
-					Logger.log(new LogAlert(false, "Error Initialize MainWindow", e));
-				}
-
-				while (!display.isDisposed() && display.readAndDispatch());
-			}
-		});
-	}
-
-	/**
-	 * Called only on STARTUP_UIFIRST
-	 */
-	public void init(final AzureusCore core) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				_init(core);
-				if (uiInitializer != null) {
-					uiInitializer.abortProgress();
-				}
-			}
-		});
-	}
-
-	/**
-	 * Called only on STARTUP_UIFIRST
-	 */
-	public void _init(AzureusCore core) {
-		this.core = core;
-		AEDiagnostics.addEvidenceGenerator(this);
-
-		disposedOrDisposing = false;
-
-		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open Transfer Bar On Start")) {
-			uiFunctions.showGlobalTransferBar();
-		}
-
-		// Hack for 3014 -> 3016 upgrades on Vista who become an Administrator
-		// user after restart.
-		if (Constants.isWindows
-				&& System.getProperty("os.name").indexOf("Vista") > 0
-				&& !COConfigurationManager.getBooleanParameter("vista.adminquit")) {
-			File fileFromInstall = FileUtil.getApplicationFile("license.txt");
-			if (fileFromInstall.exists()
-					&& fileFromInstall.lastModified() < new GregorianCalendar(2007, 06,
-							13).getTimeInMillis()) {
-				// install older than 3016
-				GlobalManager gm = core.getGlobalManager();
-				if (gm != null
-						&& gm.getDownloadManagers().size() == 0
-						&& gm.getStats().getTotalProtocolBytesReceived() < 1024 * 1024 * 100) {
-					File fileTestWrite = FileUtil.getApplicationFile("testwrite.dll");
-					fileTestWrite.deleteOnExit();
-					try {
-						FileOutputStream fos = new FileOutputStream(fileTestWrite);
-						fos.write(23);
-						fos.close();
-
-						COConfigurationManager.setParameter("vista.adminquit", true);
-						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();
-						}
-						dispose(false, false);
-						return;
-					} catch (Exception e) {
-					}
-				}
-			}
-		}
-
-		StimulusRPC.hookListeners(core, this);
-
-		uiSWTInstanceImpl = new UISWTInstanceImpl(core);
-		uiSWTInstanceImpl.init(uiInitializer);
-
-		VuzeActivitiesManager.initialize(core);
-
-		// When a download is added, check for new meta data and
-		// un-"wait state" the rating
-		// TODO: smart refreshing of meta data ("Refresh On" attribute)
-		GlobalManager gm = core.getGlobalManager();
-		dms_Startup = (DownloadManager[]) gm.getDownloadManagers().toArray(
-				new DownloadManager[0]);
-		gm.addListener(new GlobalManagerListener() {
-
-			public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
-			}
-
-			public void downloadManagerRemoved(DownloadManager dm) {
-			}
-
-			public void downloadManagerAdded(final DownloadManager dm) {
-				downloadAdded(new DownloadManager[] {
-					dm
-				});
-			}
-
-			public void destroyed() {
-			}
-
-			public void destroyInitiated() {
-			}
-
-		}, false);
-
-		gm.addDownloadWillBeRemovedListener(new GlobalManagerDownloadWillBeRemovedListener() {
-			public void downloadWillBeRemoved(DownloadManager dm,
-					boolean remove_torrent, boolean remove_data)
-
-					throws GlobalManagerDownloadRemovalVetoException {
-				TOTorrent torrent = dm.getTorrent();
-				if (PlatformTorrentUtils.isContentDRM(torrent) && remove_data) {
-
-					String prefix = "v3.mb.deletePurchased.";
-					String title = MessageText.getString(prefix + "title");
-					String text = MessageText.getString(prefix + "text", new String[] {
-						dm.getDisplayName()
-					});
-
-					MessageBoxShell mb = new MessageBoxShell(title, text,
-							new String[] {
-								MessageText.getString(prefix + "button.delete"),
-								MessageText.getString(prefix + "button.cancel")
-							}, 1);
-					mb.setRelatedObject(dm);
-
-					mb.open(null);
-					int result = mb.waitUntilClosed();
-					if (result != 0) {
-						throw new GlobalManagerDownloadRemovalVetoException("", true);
-					}
-				}
-			}
-		});
-
-		Alerts.addListener(new Alerts.AlertListener() {
-
-			public boolean allowPopup(Object[] relatedObjects, int configID) {
-				DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
-						relatedObjects, DownloadManager.class);
-
-				if (dm == null) {
-					return true;
-				}
-				if (dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-					return false;
-				}
-
-				HashWrapper hw;
-				try {
-					hw = dm.getTorrent().getHashWrapper();
-					if (PlayNowList.contains(hw)) {
-						return false;
-					}
-				} catch (TOTorrentException e) {
-				}
-				return true;
-			}
-
-		});
-
-		core.triggerLifeCycleComponentCreated(uiFunctions);
-
-		processStartupDMS();
-	}
-
-	private void processStartupDMS() {
-		// must be in a new thread because we don't want to block
-		// initilization or any other add listeners
-		AEThread2 thread = new AEThread2("v3.mw.dmAdded", true) {
-			public void run() {
-				long startTime = SystemTime.getCurrentTime();
-				if (dms_Startup == null || dms_Startup.length == 0) {
-					dms_Startup = null;
-					return;
-				}
-
-				downloadAdded(dms_Startup);
-
-				dms_Startup = null;
-
-				System.out.println("psDMS " + (SystemTime.getCurrentTime() - startTime)
-						+ "ms");
-			}
-		};
-		thread.setPriority(Thread.MIN_PRIORITY);
-		thread.start();
-	}
-
-	private void downloadAdded(final DownloadManager[] dms) {
-		boolean oneIsNotPlatform = false;
-		for (final DownloadManager dm : dms) {
-			if (dm == null) {
-				continue;
-			}
-
-			DownloadManagerState dmState = dm.getDownloadState();
-
-			final TOTorrent torrent = dm.getTorrent();
-			if (torrent == null) {
-				continue;
-			}
-
-			String hash = null;
-			try {
-				hash = torrent.getHashWrapper().toBase32String();
-			} catch (TOTorrentException e) {
-				Debug.out(e);
-			}
-
-			String title = PlatformTorrentUtils.getContentTitle(torrent);
-			if (title != null && title.length() > 0
-					&& dmState.getDisplayName() == null) {
-				dmState.setDisplayName(title);
-			}
-
-			if (ConfigurationChecker.isNewVersion() && dm.getAssumedComplete()) {
-				String lastVersion = COConfigurationManager.getStringParameter("Last Version");
-				if (org.gudy.azureus2.core3.util.Constants.compareVersions(lastVersion,
-						"3.1.1.1") <= 0) {
-					long completedTime = dmState.getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
-					if (completedTime < SystemTime.getOffsetTime(-(1000 * 60))) {
-						PlatformTorrentUtils.setHasBeenOpened(dm, true);
-					}
-				}
-			}
-
-			boolean isContent = PlatformTorrentUtils.isContent(torrent, true)
-					|| PlatformTorrentUtils.getContentNetworkID(torrent) == ContentNetwork.CONTENT_NETWORK_VHDNL;
-
-			if (!oneIsNotPlatform && !isContent
-					&& !dmState.getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-				oneIsNotPlatform = true;
-			}
-
-			final String fHash = hash;
-
-			if (isContent) {
-				long now = SystemTime.getCurrentTime();
-
-				long expiresOn = PlatformTorrentUtils.getExpiresOn(torrent);
-				if (expiresOn > now) {
-					SimpleTimer.addEvent("dm Expirey", expiresOn,
-							new TimerEventPerformer() {
-								public void perform(TimerEvent event) {
-									dm.getDownloadState().setFlag(
-											DownloadManagerState.FLAG_LOW_NOISE, true);
-									ManagerUtils.remove(dm, null, true, true);
-								}
-							});
-				}
-			} // isContent
-		}
-
-		if (oneIsNotPlatform && dms_Startup == null) {
-			DonationWindow.checkForDonationPopup();
-		}
-	}
-
-	/**
-	 * @param uiInitializer 
-	 * 
-	 */
-	protected void createWindow(IUIIntializer uiInitializer) {
-		long startTime = SystemTime.getCurrentTime();
-
-		uiFunctions = new UIFunctionsImpl(this);
-		UIFunctionsManager.setUIFunctions(uiFunctions);
-
-		Utils.disposeComposite(shell);
-
-		increaseProgress(uiInitializer, "splash.initializeGui");
-
-		System.out.println("UIFunctions/ImageLoad took "
-				+ (SystemTime.getCurrentTime() - startTime) + "ms");
-		startTime = SystemTime.getCurrentTime();
-
-		shell = new Shell(display, SWT.SHELL_TRIM);
-		
-
-		if (Constants.isWindows) {
-			try {
-				Class ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer");
-				Method method = ehancerClass.getMethod("initMainShell",
-						new Class[] {
-							Shell.class
-						});
-				method.invoke(null, new Object[] {
-					shell
-				});
-			} catch (Exception e) {
-				Debug.printStackTrace(e);
-			}
-		}
-
-		try {
-			shell.setData("class", this);
-			shell.setText("Vuze");
-			Utils.setShellIcon(shell);
-			Utils.linkShellMetricsToConfig(shell, "window");
-			//Shell activeShell = display.getActiveShell();
-			//shell.setVisible(true);
-			//shell.moveBelow(activeShell);
-
-			System.out.println("new shell took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			PlatformConfigMessenger.addPlatformLoginCompleteListener(new PlatformLoginCompleteListener() {
-				public void platformLoginComplete() {
-					Utils.execSWTThread(new AERunnable() {
-						public void runSupport() {
-							setupUsageTracker();
-						}
-					});
-				}
-			});
-			
-			PlatformDevicesMessenger.setupDeviceSender();
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-
-			skin = SWTSkinFactory.getInstance();
-
-			/*
-			 * KN: passing the skin to the uifunctions so it can be used by UIFunctionsSWT.createMenu()
-			 */
-			uiFunctions.setSkin(skin);
-
-			System.out.println("new shell setup took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			initSkinListeners();
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-			System.out.println("skinlisteners init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			skin.initialize(shell, "main.shell", uiInitializer);
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-			System.out.println("skin init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			menu = new MainMenu(skin, shell);
-			shell.setData("MainMenu", menu);
-
-			System.out.println("MainMenu init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			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.CocoaUIEnhancer");
-
-						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
-							});
-						}
-
-					} catch (Throwable e) {
-
-						Debug.printStackTrace(e);
-					}
-
-				}
-
-				Listener toggleListener = new Listener() {
-					public void handleEvent(Event event) {
-						ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-						if (tb != null) {
-							tb.flipShowText();
-						}
-					}
-				};
-				shell.addListener(SWT.Expand, toggleListener);
-				shell.addListener(SWT.Collapse, toggleListener);
-			}
-
-			System.out.println("createWindow init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-
-			skin.layout();
-
-			System.out.println("skin layout took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			try {
-				Utils.createTorrentDropTarget(shell, false);
-			} catch (Throwable e) {
-				Logger.log(new LogEvent(LOGID, "Drag and Drop not available", e));
-			}
-
-			shell.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					dispose(false, false);
-				}
-			});
-
-			shell.addShellListener(new ShellAdapter() {
-				public void shellClosed(ShellEvent event) {
-					if (disposedOrDisposing) {
-						return;
-					}
-					if (systemTraySWT != null
-							&& COConfigurationManager.getBooleanParameter("Enable System Tray")
-							&& COConfigurationManager.getBooleanParameter("Close To Tray")) {
-
-						minimizeToTray(event);
-					} else {
-						event.doit = dispose(false, false);
-					}
-				}
-
-				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;
-					}
-					if (systemTraySWT != null
-							&& COConfigurationManager.getBooleanParameter("Enable System Tray")
-							&& COConfigurationManager.getBooleanParameter("Minimize To Tray")) {
-
-						minimizeToTray(event);
-					}
-				}
-
-				public void shellDeiconified(ShellEvent e) {
-					if (Constants.isOSX
-							&& COConfigurationManager.getBooleanParameter("Password enabled")) {
-						shell.setVisible(false);
-						if (PasswordWindow.showPasswordWindow(display)) {
-							shell.setVisible(true);
-						}
-					}
-				}
-			});
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-			System.out.println("pre skin widgets init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			if (core != null) {
-				StimulusRPC.hookListeners(core, this);
-			}
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-			System.out.println("hooks init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			initWidgets();
-			System.out.println("skin widgets (1/2) init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-			initWidgets2();
-
-			increaseProgress(uiInitializer, "v3.splash.initSkin");
-			System.out.println("skin widgets init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-			if (sidebar != null) {
-				setupSideBar(sidebar);
-			} else {
-				SkinViewManager.addListener(new SkinViewManagerListener() {
-					public void skinViewAdded(SkinView skinview) {
-						if (skinview instanceof SideBar) {
-							setupSideBar((SideBar) skinview);
-						}
-					}
-				});
-			}
-
-			System.out.println("pre SWTInstance init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			increaseProgress(uiInitializer, "v3.splash.hookPluginUI");
-			startTime = SystemTime.getCurrentTime();
-
-			TableColumnCreatorV3.initCoreColumns();
-
-			System.out.println("Init Core Columns took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			increaseProgress(uiInitializer, "v3.splash.hookPluginUI");
-			startTime = SystemTime.getCurrentTime();
-
-			if (core != null) {
-				// attach the UI to plugins
-				// Must be done before initializing views, since plugins may register
-				// table columns and other objects
-				uiSWTInstanceImpl = new UISWTInstanceImpl(core);
-				uiSWTInstanceImpl.init(uiInitializer);
-				//uiSWTInstanceImpl.addView(UISWTInstance.VIEW_MYTORRENTS,
-				//		"PieceGraphView", new PieceGraphView());
-			}
-
-			System.out.println("SWTInstance init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			increaseProgress(uiInitializer, "splash.initializeGui");
-			startTime = SystemTime.getCurrentTime();
-
-		} catch (Throwable t) {
-			Debug.out(t);
-		} finally {
-
-			String configID = SkinConstants.VIEWID_PLUGINBAR + ".visible";
-			if (false == ConfigurationDefaults.getInstance().doesParameterDefaultExist(
-					configID)) {
-				COConfigurationManager.setBooleanDefault(configID, true);
-			}
-			setVisible(WINDOW_ELEMENT_TOPBAR,
-					COConfigurationManager.getBooleanParameter(configID)
-							&& COConfigurationManager.getIntParameter("User Mode") > 1);
-
-			setVisible(WINDOW_ELEMENT_TABBAR, true);
-
-			shell.layout(true, true);
-
-			System.out.println("shell.layout took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			showMainWindow();
-
-			//================
-
-			increaseProgress(uiInitializer, "splash.initializeGui");
-
-			System.out.println("shell.open took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			processStartupDMS();
-
-			System.out.println("processStartupDMS took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			if (core != null) {
-				VuzeActivitiesManager.initialize(core);
-			}
-
-			System.out.println("vuzeactivities init took "
-					+ (SystemTime.getCurrentTime() - startTime) + "ms");
-			startTime = SystemTime.getCurrentTime();
-
-			NavigationHelper.addListener(new NavigationHelper.navigationListener() {
-				public void processCommand(final int type, final String[] args) {
-					Utils.execSWTThread(new AERunnable() {
-						public void runSupport() {
-
-							UIFunctions uif = UIFunctionsManager.getUIFunctions();
-
-							if (type == NavigationHelper.COMMAND_SWITCH_TO_TAB) {
-								SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-								if (sideBar == null) {
-									return;
-								}
-								ContentNetworkUtils.setSourceRef(args[0], "menu", false);
-								sideBar.showEntryByTabID(args[0]);
-
-								if (uif != null) {
-
-									uif.bringToFront();
-								}
-							} else if (type == NavigationHelper.COMMAND_CONDITION_CHECK) {
-							}
-						}
-					});
-				}
-			});
-		}
-	}
-
-	/**
-	 * @param skinview
-	 *
-	 * @since 3.1.1.1
-	 */
-	protected void setupSideBar(final SideBar sidebar) {
-		// 3.2 TODO: set default sidebar item
-
-		sidebar.addListener(this);
-
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				final String CFG_STARTTAB = "v3.StartTab";
-				String startTab;
-				boolean showWelcome = COConfigurationManager.getBooleanParameter("v3.Show Welcome");
-
-				ContentNetwork startupCN = ContentNetworkManagerFactory.getSingleton().getStartupContentNetwork();
-				if (!startupCN.isServiceSupported(ContentNetwork.SERVICE_WELCOME)) {
-					showWelcome = false;
-				}
-
-				if (showWelcome) {
-					startTab = SideBar.SIDEBAR_SECTION_WELCOME;
-				} else {
-					if (!COConfigurationManager.hasParameter(CFG_STARTTAB, true)) {
-						COConfigurationManager.setParameter(CFG_STARTTAB,
-								SideBar.SIDEBAR_SECTION_LIBRARY);
-					}
-					startTab = COConfigurationManager.getStringParameter(CFG_STARTTAB);
-					if (!SideBar.entryExists(startTab)) {
-						startTab = SideBar.SIDEBAR_SECTION_LIBRARY;
-					}
-				}
-				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");
-		//		startTime = SystemTime.getCurrentTime();
-	}
-
-	/**
-	 * @param uiInitializer
-	 * @param taskKey TODO
-	 *
-	 * @since 3.0.4.3
-	 */
-	private void increaseProgress(IUIIntializer uiInitializer, String taskKey) {
-		if (uiInitializer != null) {
-			uiInitializer.increaseProgress();
-			if (taskKey != null) {
-				uiInitializer.reportCurrentTask(MessageText.getString(taskKey));
-			}
-		}
-		// XXX Disabled because plugin update window will pop up and take control
-		// 		 of the dispatch loop..
-		if (false && Utils.isThisThreadSWT()) {
-			// clean the dispatch loop so the splash screen gets updated
-			int i = 1000;
-			while (display.readAndDispatch() && i > 0) {
-				i--;
-			}
-			//if (i < 999) {
-			//	System.out.println("dispatched " + (1000 - i));
-			//}
-		}
-	}
-
-	public boolean dispose(final boolean for_restart,
-			final boolean close_already_in_progress) {
-		if (disposedOrDisposing) {
-			return true;
-		}
-		return Utils.execSWTThreadWithBool("v3.MainWindow.dispose",
-				new AERunnableBoolean() {
-					public boolean runSupport() {
-						return _dispose(for_restart, close_already_in_progress);
-					}
-				});
-	}
-
-	public boolean _dispose(boolean bForRestart, boolean bCloseAlreadyInProgress) {
-		if (disposedOrDisposing) {
-			return true;
-		}
-
-		isReady = false;
-
-		disposedOrDisposing = true;
-		if (core != null
-				&& !UIExitUtilsSWT.canClose(core.getGlobalManager(), bForRestart)) {
-			disposedOrDisposing = false;
-			return false;
-		}
-
-		UIExitUtilsSWT.uiShutdown();
-
-		if (systemTraySWT != null) {
-			systemTraySWT.dispose();
-		}
-
-		/**
-		 * Explicitly force the transfer bar location to be saved (if appropriate and open).
-		 * 
-		 * We can't rely that the normal mechanism for doing this won't fail (which it usually does)
-		 * when the GUI is being disposed of.
-		 */
-		try {
-  		AllTransfersBar transfer_bar = AllTransfersBar.getBarIfOpen(core.getGlobalManager());
-  		if (transfer_bar != null) {
-  			transfer_bar.forceSaveLocation();
-  		}
-		} catch (Exception ignore) {
-		}
-
-		mapTrackUsage_mon.enter();
-		try {
-			if (mapTrackUsage != null) {
-				String id = getUsageActiveTabID();
-				if (id != null) {
-					if (lastShellStatus == null) {
-						lastShellStatus = id;
-					}
-					updateMapTrackUsage(lastShellStatus);
-				}
-
-				Map map = new HashMap();
-				map.put("version",
-						org.gudy.azureus2.core3.util.Constants.AZUREUS_VERSION);
-				map.put("statsmap", mapTrackUsage);
-
-				FileUtil.writeResilientFile(new File(SystemProperties.getUserPath(),
-						"timingstats.dat"), map);
-			}
-		} finally {
-			mapTrackUsage_mon.exit();
-		}
-
-		if (!SWTThread.getInstance().isTerminated()) {
-			SWTThread.getInstance().getInitializer().stopIt(bForRestart, false);
-		}
-
-		return true;
-	}
-
-	private String getUsageActiveTabID() {
-		try {
-			SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-			if (sidebar != null) {
-				SideBarEntrySWT curEntry = sidebar.getCurrentEntry();
-				if (curEntry == null) {
-					return "none";
-				} else {
-					String id = curEntry.getLogID();
-					return id == null ? "null" : id;
-				}
-			}
-		} catch (Exception e) {
-			String name = e.getClass().getName();
-			int i = name.indexOf('.');
-			if (i > 0) {
-				return name.substring(i);
-			}
-			return name;
-		}
-		return "unknown";
-	}
-
-	/**
-	 * 
-	 */
-	private void setupUsageTracker() {
-		mapTrackUsage_mon.enter();
-		try {
-			File f = new File(SystemProperties.getUserPath(), "timingstats.dat");
-
-			if (COConfigurationManager.getBooleanParameter("Send Version Info")
-					&& PlatformConfigMessenger.allowSendStats()) {
-
-				mapTrackUsage = new HashMap();
-
-				if (f.exists()) {
-					Map oldMapTrackUsage = FileUtil.readResilientFile(f);
-					String version = MapUtils.getMapString(oldMapTrackUsage, "version",
-							null);
-					Map map = MapUtils.getMapMap(oldMapTrackUsage, "statsmap", null);
-					if (version != null && map != null) {
-						PlatformConfigMessenger.sendUsageStats(map, f.lastModified(),
-								version, null);
-					}
-				}
-
-				SimpleTimer.addPeriodicEvent("UsageTracker", 1000,
-						new TimerEventPerformer() {
-							long lLastMouseMove = SystemTime.getCurrentTime();
-
-							Point ptLastMousePos = new Point(0, 0);
-
-							public void perform(TimerEvent event) {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										if (shell == null || shell.isDisposed()
-												|| shell.getDisplay().getActiveShell() == null) {
-											// so when we become active again, we count a few
-											// seconds (if the mouse moves)
-											if (ptLastMousePos.x > 0) {
-												ptLastMousePos.x = 0;
-												ptLastMousePos.y = 0;
-												lLastMouseMove = 0;
-											}
-											return;
-										}
-
-										Point pt = shell.getDisplay().getCursorLocation();
-										if (pt.equals(ptLastMousePos)) {
-											return;
-										}
-										ptLastMousePos = pt;
-
-										long now = SystemTime.getCurrentTime();
-										if (lLastMouseMove > 0) {
-											long diff = now - lLastMouseMove;
-											if (diff < 10000) {
-												lCurrentTrackTime += diff;
-											} else {
-												lCurrentTrackTimeIdle += diff;
-											}
-										}
-
-										lLastMouseMove = now;
-									}
-								});
-							}
-						});
-
-				Listener lActivateDeactivate = new Listener() {
-					long start;
-
-					public void handleEvent(Event event) {
-						if (event.type == SWT.Activate) {
-							lCurrentTrackTimeIdle = 0;
-							if (start > 0 && lastShellStatus != null) {
-								lCurrentTrackTime = SystemTime.getCurrentTime() - start;
-								updateMapTrackUsage(lastShellStatus);
-							}
-							lastShellStatus = null;
-						} else {
-							updateMapTrackUsage(getUsageActiveTabID());
-							if (shell.getMinimized()) {
-								lastShellStatus = "idle-minimized";
-							} else if (!shell.isVisible()) {
-								lastShellStatus = "idle-invisible";
-							} else {
-								lastShellStatus = "idle-nofocus";
-							}
-							start = SystemTime.getCurrentTime();
-						}
-					}
-				};
-				shell.addListener(SWT.Activate, lActivateDeactivate);
-				shell.addListener(SWT.Deactivate, lActivateDeactivate);
-
-			} else {
-				mapTrackUsage = null;
-				// No use keeping old usage stats if we are told no one wants them
-				try {
-					if (f.exists()) {
-						f.delete();
-					}
-				} catch (Exception e) {
-				}
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		} finally {
-			mapTrackUsage_mon.exit();
-		}
-	}
-
-	private void showMainWindow() {
-		boolean isOSX = org.gudy.azureus2.core3.util.Constants.isOSX;
-		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
-		boolean bPassworded = COConfigurationManager.getBooleanParameter("Password enabled");
-		boolean bStartMinimize = bEnableTray
-				&& (bPassworded || COConfigurationManager.getBooleanParameter("Start Minimized"));
-
-		SWTSkinObject soMain = skin.getSkinObject("main");
-		if (soMain != null) {
-			soMain.getControl().setVisible(true);
-		}
-
-		shell.addListener(SWT.Show, new Listener() {
-			public void handleEvent(Event event) {
-				System.out.println("---------SHOWN AT " + SystemTime.getCurrentTime()
-						+ ";" + (SystemTime.getCurrentTime() - Initializer.startTime)
-						+ "ms");
-			}
-		});
-
-		if (!bStartMinimize) {
-			shell.open();
-			if (!isOSX) {
-				shell.forceActive();
-			}
-		} else if (Utils.isCarbon) {
-			shell.setVisible(true);
-			shell.setMinimized(true);
-		}
-		
-
-		if (delayedCore) {
-			// 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()) {
-  			return;
-  		}
-		}
-
-		if (bEnableTray) {
-
-			try {
-				systemTraySWT = new SystemTraySWT();
-
-			} catch (Throwable e) {
-
-				e.printStackTrace();
-				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-						"Upgrade to SWT3.0M8 or later for system tray support."));
-			}
-
-			if (bStartMinimize) {
-				minimizeToTray(null);
-			}
-			//Only show the password if not started minimized
-			//Correct bug #878227
-			else {
-				if (bPassworded) {
-					minimizeToTray(null);
-					setVisible(true); // invokes password
-				}
-			}
-		}
-
-		// do this before other checks as these are blocking dialogs to force order
-
-		if (uiInitializer != null) {
-
-			uiInitializer.initializationComplete();
-		}
-
-		AssociationChecker.checkAssociations();
-
-		// Donation stuff
-		Map map = VersionCheckClient.getSingleton().getMostRecentVersionCheckData();
-		DonationWindow.setInitialAskHours(MapUtils.getMapInt(map,
-				"donations.askhrs", DonationWindow.getInitialAskHours()));
-
-		if (core != null) {
-			core.triggerLifeCycleComponentCreated(uiFunctions);
-		}
-
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				fixupActionBarSize();
-			}
-		});
-
-		System.out.println("---------READY AT " + SystemTime.getCurrentTime() + ";"
-				+ (SystemTime.getCurrentTime() - Initializer.startTime) + "ms");
-		isReady = true;
-		//SESecurityManagerImpl.getSingleton().exitVM(0);
-	}
-
-	public void setVisible(final boolean visible) {
-		setVisible(visible, true);
-	}
-
-	public void setVisible(final boolean visible, final boolean tryTricks) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				boolean currentlyVisible = shell.getVisible() && !shell.getMinimized();
-				if (visible && !currentlyVisible) {
-					if (COConfigurationManager.getBooleanParameter("Password enabled")) {
-						if (!PasswordWindow.showPasswordWindow(display)) {
-							shell.setVisible(false);
-							return;
-						}
-					}
-				}
-
-				ArrayList wasVisibleList = null;
-				boolean bHideAndShow = false;
-				// temp disabled
-				//tryTricks && visible && Constants.isWindows && display.getActiveShell() != shell;
-				if (bHideAndShow) {
-					wasVisibleList = new ArrayList();
-					// We don't want the window to just flash and not open, so:
-					// -Minimize main shell
-					// -Set all shells invisible
-					try {
-						shell.setMinimized(true);
-						Shell[] shells = shell.getDisplay().getShells();
-						for (int i = 0; i < shells.length; i++) {
-							if (shells[i].isVisible()) {
-								wasVisibleList.add(shells[i]);
-								shells[i].setVisible(false);
-							}
-						}
-					} catch (Exception e) {
-					}
-				}
-
-				if (visible) {
-					if (shell.getMinimized()) {
-						shell.setMinimized(false);
-					}
-					if (!currentlyVisible
-							&& COConfigurationManager.getBooleanParameter("window.maximized")) {
-						shell.setMaximized(true);
-					}
-				} else {
-					// XXX hack for release.. should not access param outside Utils.linkShellMetrics
-					COConfigurationManager.setParameter("window.maximized",
-							shell.getMaximized());
-				}
-
-				shell.setVisible(visible);
-				if (visible) {
-					shell.forceActive();
-
-					if (bHideAndShow) {
-						try {
-							Shell[] shells = shell.getDisplay().getShells();
-							for (int i = 0; i < shells.length; i++) {
-								if (shells[i] != shell) {
-									if (wasVisibleList.contains(shells[i])) {
-										shells[i].setVisible(visible);
-									}
-									shells[i].setFocus();
-								}
-							}
-						} catch (Exception e) {
-						}
-					}
-				}
-
-			}
-		});
-	}
-
-	private void minimizeToTray(ShellEvent event) {
-		//Added this test so that we can call this method with null parameter.
-		if (event != null) {
-			event.doit = false;
-		}
-
-		// XXX hack for release.. should not access param outside Utils.linkShellMetrics
-		COConfigurationManager.setParameter("window.maximized",
-				shell.getMaximized());
-		shell.setVisible(false);
-		MiniBarManager.getManager().setAllVisible(true);
-	}
-
-	/**
-	 * Associates every view ID that we use to a class, and creates the class
-	 * on first EVENT_SHOW.
-	 */
-	private void initSkinListeners() {
-		UISkinnableManagerSWT skinnableManagerSWT = UISkinnableManagerSWT.getInstance();
-		skinnableManagerSWT.addSkinnableListener(MessageBoxShell.class.toString(),
-				new UISkinnableSWTListener() {
-					public void skinBeforeComponents(Composite composite,
-							Object skinnableObject, Object[] relatedObjects) {
-						Color colorBG = skin.getSkinProperties().getColor("color.mainshell");
-						Color colorLink = skin.getSkinProperties().getColor(
-								"color.links.normal");
-						Color colorText = skin.getSkinProperties().getColor("color.text.fg");
-
-						//composite.setBackground(colorBG);
-						//composite.setForeground(colorText);
-
-						MessageBoxShell shell = (MessageBoxShell) skinnableObject;
-						//shell.setUrlColor(colorLink);
-
-						TOTorrent torrent = null;
-						DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
-								relatedObjects, DownloadManager.class);
-						if (dm != null) {
-							torrent = dm.getTorrent();
-						} else {
-							torrent = (TOTorrent) LogRelationUtils.queryForClass(
-									relatedObjects, TOTorrent.class);
-						}
-
-						if (torrent != null && shell.getLeftImage() == null) {
-							byte[] contentThumbnail = PlatformTorrentUtils.getContentThumbnail(torrent);
-							if (contentThumbnail != null) {
-								try {
-									ByteArrayInputStream bis = new ByteArrayInputStream(
-											contentThumbnail);
-									final Image img = new Image(Display.getDefault(), bis);
-
-									shell.setLeftImage(img);
-
-									composite.addDisposeListener(new DisposeListener() {
-										public void widgetDisposed(DisposeEvent e) {
-											if (!img.isDisposed()) {
-												img.dispose();
-											}
-										}
-									});
-								} catch (Exception e) {
-
-								}
-							}
-						}
-					}
-
-					public void skinAfterComponents(Composite composite,
-							Object skinnableObject, Object[] relatedObjects) {
-					}
-				});
-
-		skinnableManagerSWT.addSkinnableListener(
-				MessageSlideShell.class.toString(), new UISkinnableSWTListener() {
-
-					public void skinBeforeComponents(Composite composite,
-							Object skinnableObject, Object[] relatedObjects) {
-						if (skinnableObject instanceof MessageSlideShell) {
-							final Image image = new Image(composite.getDisplay(), 250, 300);
-
-							TOTorrent torrent = null;
-							DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
-									relatedObjects, DownloadManager.class);
-							if (dm != null) {
-								torrent = dm.getTorrent();
-							} else {
-								torrent = (TOTorrent) LogRelationUtils.queryForClass(
-										relatedObjects, TOTorrent.class);
-							}
-
-							MessageSlideShell shell = (MessageSlideShell) skinnableObject;
-
-							byte[] contentThumbnail = PlatformTorrentUtils.getContentThumbnail(torrent);
-							GC gc = new GC(image);
-							try {
-								gc.setBackground(gc.getDevice().getSystemColor(
-										SWT.COLOR_WIDGET_BACKGROUND));
-								gc.fillRectangle(image.getBounds());
-
-								if (contentThumbnail != null) {
-
-									try {
-										ByteArrayInputStream bis = new ByteArrayInputStream(
-												contentThumbnail);
-										final Image img = new Image(Display.getDefault(), bis);
-										Rectangle imgBounds = img.getBounds();
-										double pct = 35.0 / imgBounds.height;
-										int w = (int) (imgBounds.width * pct);
-
-										try {
-											gc.setAdvanced(true);
-											gc.setInterpolation(SWT.HIGH);
-										} catch (Exception e) {
-											// not important if we can't set advanced
-										}
-
-										gc.drawImage(img, 0, 0, imgBounds.width, imgBounds.height,
-												0, 265, w, 35);
-										img.dispose();
-									} catch (Exception e) {
-
-									}
-
-								}
-							} finally {
-								gc.dispose();
-							}
-							shell.setImgPopup(image);
-
-							composite.addListener(SWT.Dispose, new Listener() {
-								public void handleEvent(Event event) {
-									if (!image.isDisposed()) {
-										image.dispose();
-									}
-								}
-							});
-						}
-					}
-
-					public void skinAfterComponents(Composite composite,
-							Object skinnableObject, Object[] relatedObjects) {
-						if (true) {
-							return; // temp disable
-						}
-						Color bg = skin.getSkinProperties().getColor("color.mainshell");
-						if (bg != null) {
-							composite.setBackground(bg);
-						}
-						Color fg = skin.getSkinProperties().getColor("color.section.header");
-						if (fg != null) {
-							setChildrenFG(composite, fg);
-						}
-						composite.setBackgroundMode(SWT.INHERIT_DEFAULT);
-					}
-				});
-	}
-
-	private void setChildrenFG(Control parent, Color color) {
-		parent.setForeground(color);
-		if (parent instanceof Composite) {
-			Control[] children = ((Composite) parent).getChildren();
-			for (int i = 0; i < children.length; i++) {
-				Control control = children[i];
-				if (!(control instanceof Button)
-						|| (((Button) control).getStyle() & SWT.CHECK) > 0) {
-					setChildrenFG(control, color);
-				}
-			}
-		}
-	}
-
-	/**
-	 * 
-	 */
-	private void initWidgets() {
-		SWTSkinObject skinObject;
-
-		/*
-		 * Directly loading the buddies viewer since we need to access it
-		 * before it's even shown for the first time
-		 */
-		Class[] forceInits = new Class[] {
-			SideBar.class,
-		};
-		String[] forceInitsIDs = new String[] {
-			SkinConstants.VIEWID_SIDEBAR,
-		};
-
-		for (int i = 0; i < forceInits.length; i++) {
-			Class cla = forceInits[i];
-			String id = forceInitsIDs[i];
-
-			try {
-				skinObject = skin.getSkinObject(id);
-				if (null != skinObject) {
-					SkinView skinView = (SkinView) cla.newInstance();
-					skinView.setMainSkinObject(skinObject);
-					skinObject.addListener(skinView);
-				}
-			} catch (Throwable t) {
-				Debug.out(t);
-			}
-		}
-	}
-
-	private void initWidgets2() {
-		SWTSkinObject skinObject = skin.getSkinObject("statusbar");
-		if (skinObject != null) {
-			final Composite cArea = (Composite) skinObject.getControl();
-
-			statusBar = new MainStatusBar();
-			Composite composite = statusBar.initStatusBar(cArea);
-
-			composite.setLayoutData(Utils.getFilledFormData());
-		}
-
-		skinObject = skin.getSkinObject("search-text");
-		if (skinObject != null) {
-			attachSearchBox(skinObject);
-		}
-
-		skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
-		if (skinObject != null) {
-			Menu topbarMenu = new Menu(shell, SWT.POP_UP);
-
-			if (COConfigurationManager.getIntParameter("User Mode") > 1) {
-				MainMenu.createViewMenuItem(skin, topbarMenu,
-						"v3.MainWindow.menu.view." + SkinConstants.VIEWID_PLUGINBAR,
-						SkinConstants.VIEWID_PLUGINBAR + ".visible",
-						SkinConstants.VIEWID_PLUGINBAR, true, -1);
-			}
-
-			final MenuItem itemShowText = new MenuItem(topbarMenu, SWT.CHECK);
-			Messages.setLanguageText(itemShowText,
-					"v3.MainWindow.menu.showActionBarText");
-			itemShowText.addSelectionListener(new SelectionAdapter() {
-				// @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
-				public void widgetSelected(SelectionEvent e) {
-					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-					if (tb != null) {
-						tb.flipShowText();
-					}
-				}
-			});
-
-			topbarMenu.addMenuListener(new MenuListener() {
-				public void menuShown(MenuEvent e) {
-					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-					if (tb != null) {
-						itemShowText.setSelection(tb.getShowText());
-					}
-				}
-
-				public void menuHidden(MenuEvent e) {
-				}
-			});
-
-			addMenuAndNonTextChildren((Composite) skinObject.getControl(), topbarMenu);
-
-			skinObject = skin.getSkinObject("tabbar");
-			if (skinObject != null) {
-				addMenuAndNonTextChildren((Composite) skinObject.getControl(),
-						topbarMenu);
-			}
-		}
-	}
-
-	private void addMenuAndNonTextChildren(Composite parent, Menu menu) {
-		parent.setMenu(menu);
-
-		Control[] children = parent.getChildren();
-		for (int i = 0; i < children.length; i++) {
-			Control control = children[i];
-			if (control instanceof Composite) {
-				Composite c = (Composite) control;
-				addMenuAndNonTextChildren(c, menu);
-			} else if (!(control instanceof Text)) {
-				control.setMenu(menu);
-			}
-		}
-	}
-
-	/**
-	 * @param skinObject
-	 */
-	private void attachSearchBox(SWTSkinObject skinObject) {
-		Composite cArea = (Composite) skinObject.getControl();
-
-		shell.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event event) {
-				fixupActionBarSize();
-			}
-		});
-
-		final Text text = new Text(cArea, SWT.NONE);
-		FormData filledFormData = Utils.getFilledFormData();
-		text.setLayoutData(filledFormData);
-
-		text.addListener(SWT.Resize, new Listener() {
-			Font lastFont = null;
-
-			public void handleEvent(Event event) {
-				Text text = (Text) event.widget;
-
-				int h = text.getClientArea().height - 2;
-				Font font = Utils.getFontWithHeight(text.getFont(), null, h);
-				if (font != null) {
-					text.setFont(font);
-
-					Utils.disposeSWTObjects(new Object[] {
-						lastFont
-					});
-
-					text.addDisposeListener(new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							Text text = (Text) e.widget;
-							text.setFont(null);
-							Utils.disposeSWTObjects(new Object[] {
-								lastFont
-							});
-						}
-					});
-				}
-			}
-		});
-		text.setTextLimit(254);
-
-		final String sDefault = MessageText.getString("v3.MainWindow.search.defaultText");
-
-		SWTSkinProperties properties = skinObject.getProperties();
-		colorSearchTextBG = properties.getColor("color.search.text.bg");
-		colorSearchTextFG = properties.getColor("color.search.text.fg");
-		colorSearchTextFGdef = properties.getColor("color.search.text.fg.default");
-
-		if (colorSearchTextFGdef != null) {
-			text.setForeground(colorSearchTextFGdef);
-		}
-		if (colorSearchTextBG != null) {
-			text.setBackground(colorSearchTextBG);
-		}
-		text.addMouseListener(new MouseListener() {
-
-			public void mouseUp(MouseEvent e) {
-				Text text = (Text) e.widget;
-				if (text.getText().equals(sDefault)) {
-					if (colorSearchTextFG != null) {
-						text.setForeground(colorSearchTextFG);
-					}
-					text.setText("");
-				}
-			}
-
-			public void mouseDown(MouseEvent e) {
-			}
-
-			public void mouseDoubleClick(MouseEvent e) {
-			}
-		});
-
-		text.addKeyListener(new KeyListener() {
-			public void keyPressed(KeyEvent e) {
-				if (e.stateMask == SWT.MOD1) {
-
-					int key = e.character;
-					if (key <= 26 && key > 0) {
-						key += 'a' - 1;
-					}
-
-					if (key == 'a') {
-						text.selectAll();
-					}
-				}
-
-			}
-
-			public void keyReleased(KeyEvent arg0) {
-				// TODO Auto-generated method stub
-
-			}
-		});
-
-		text.addListener(SWT.KeyDown, new Listener() {
-
-			public void handleEvent(Event event) {
-				if (text.getText().equals(sDefault)) {
-					if (colorSearchTextFG != null) {
-						text.setForeground(colorSearchTextFG);
-					}
-					if (event.character != '\0') {
-						text.setText("");
-					}
-					return;
-				}
-
-				Text text = (Text) event.widget;
-				if (event.keyCode == SWT.ESC) {
-					text.setText("");
-					return;
-				}
-				if (event.character == SWT.CR) {
-					doSearch(text.getText());
-				}
-			}
-		});
-
-		// must be done after layout
-		text.setText(sDefault);
-		//text.selectAll();
-
-		SWTSkinObject searchGo = skin.getSkinObject("search-go");
-		if (searchGo != null) {
-			SWTSkinButtonUtility btnGo = new SWTSkinButtonUtility(searchGo);
-			btnGo.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility,
-						SWTSkinObject skinObject, int stateMask) {
-					String sSearchText = text.getText().trim();
-					doSearch(sSearchText);
-				}
-			});
-		}
-
-		SWTSkinObject so = skin.getSkinObject("sidebar-list");
-		if (so != null
-				&& so.getProperties().getBooleanValue(
-						so.getConfigID() + ".resizeSearch", false)) {
-			Listener l = new Listener() {
-				public void handleEvent(Event event) {
-					SWTSkinObject soSearchArea = skin.getSkinObject("topbar-area-search");
-					if (soSearchArea != null) {
-						Control c = soSearchArea.getControl();
-						Rectangle bounds = ((Control) event.widget).getBounds();
-						FormData fd = (FormData) c.getLayoutData();
-						int newWidth = bounds.width - 1 - c.getBounds().x;
-						if (bounds.width < 125) {
-							return;
-						}
-						fd.width = newWidth;
-						Utils.relayout(c);
-					}
-				}
-			};
-			so.getControl().addListener(SWT.Resize, l);
-		}
-
-		so = skin.getSkinObject("search-dropdown");
-		if (so != null) {
-			SWTSkinButtonUtility btnSearchDD = new SWTSkinButtonUtility(so);
-			btnSearchDD.addSelectionListener(new ButtonListenerAdapter() {
-				public void pressed(SWTSkinButtonUtility buttonUtility,
-						SWTSkinObject skinObject, int stateMask) {
-					String sSearchText = text.getText().trim();
-					doSearch(sSearchText);
-				}
-			});
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.0.0.1
-	 */
-	protected void fixupActionBarSize() {
-		Rectangle clientArea = shell.getClientArea();
-		SWTSkinObject soSearch = skin.getSkinObject("topbar-area-search");
-		if (soSearch == null) {
-			return;
-		}
-		FormData fd = (FormData) soSearch.getControl().getLayoutData();
-		if (fd == null || fd.width <= 0) {
-			return;
-		}
-		if (clientArea.width > 1024 && fd.width == 195) {
-			return;
-		}
-		SWTSkinObject soTabBar = skin.getSkinObject(SkinConstants.VIEWID_TAB_BAR);
-		if (soTabBar == null) {
-			return;
-		}
-		Point size = soTabBar.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		int oldWidth = fd.width;
-		fd.width = clientArea.width - (size.x - oldWidth) - 5;
-		if (fd.width < 100) {
-			fd.width = 100;
-		} else if (fd.width > 195) {
-			fd.width = 195;
-		}
-
-		if (oldWidth != fd.width) {
-			((Composite) soTabBar.getControl()).layout(true, true);
-		}
-	}
-
-	/**
-	 * @param searchText
-	 */
-	//TODO : Tux Move to utils? Could you also add a "mode" or something that would be added to the url
-	// eg: &subscribe_mode=true
-	public static void doSearch(final String sSearchText) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				doSearch(sSearchText, false);
-			}
-		});
-	}
-
-	public static void doSearch(String sSearchText, boolean toSubscribe) {
-		String sDefault = MessageText.getString("v3.MainWindow.search.defaultText");
-		if (sSearchText.equals(sDefault) || sSearchText.length() == 0) {
-			return;
-		}
-
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		String id = "Search";
-		SearchResultsTabArea searchClass = (SearchResultsTabArea) SkinViewManager.getByClass(SearchResultsTabArea.class);
-		if (searchClass != null) {
-			searchClass.anotherSearch(sSearchText, toSubscribe);
-		} else {
-
-			SearchResultsTabArea.SearchQuery sq = new SearchResultsTabArea.SearchQuery();
-			sq.term = sSearchText;
-			sq.toSubscribe = toSubscribe;
-
-			SideBarEntrySWT entry = sidebar.createEntryFromSkinRef(null, id,
-					"main.area.searchresultstab", sSearchText, null, sq, true, -1);
-			if (entry != null) {
-				entry.setImageLeftID("image.sidebar.search");
-			}
-		}
-		sidebar.showEntryByID(id);
-	}
-
-	/**
-	 * 
-	 */
-	private void updateMapTrackUsage(String sTabID) {
-		//System.out.println("UPDATE: " + sTabID);
-		if (mapTrackUsage != null) {
-			mapTrackUsage_mon.enter();
-			try {
-				if (lCurrentTrackTime > 0) {
-					Long currentLength = (Long) mapTrackUsage.get(sTabID);
-					long newLength;
-					if (currentLength == null) {
-						newLength = lCurrentTrackTime;
-					} else {
-						newLength = currentLength.longValue() + lCurrentTrackTime;
-					}
-					if (newLength > 1000) {
-						mapTrackUsage.put(sTabID, new Long(newLength / 1000));
-						//System.out.println("UPDATE: " + sTabID + ";" + newLength);
-					}
-				}
-
-				if (lCurrentTrackTimeIdle > 0) {
-					String id = "idle-" + sTabID;
-					Long currentLengthIdle = (Long) mapTrackUsage.get(id);
-					long newLengthIdle = currentLengthIdle == null
-							? lCurrentTrackTimeIdle : currentLengthIdle.longValue()
-									+ lCurrentTrackTimeIdle;
-					if (newLengthIdle > 1000) {
-						mapTrackUsage.put(id, new Long(newLengthIdle / 1000));
-						//System.out.println("UPDATE: " + id + ";" + newLengthIdle);
-					}
-				}
-			} finally {
-				mapTrackUsage_mon.exit();
-			}
-		}
-
-		lCurrentTrackTime = 0;
-		lCurrentTrackTimeIdle = 0;
-	}
-
-	public static void addUsageStat(String id, long value) {
-		if (id == null) {
-			return;
-		}
-		if (id.length() > 150) {
-			id = id.substring(0, 150);
-		}
-		if (mapTrackUsage != null) {
-			mapTrackUsage_mon.enter();
-			try {
-				Long currentLength = (Long) mapTrackUsage.get(id);
-				long newLength;
-				if (currentLength == null) {
-					newLength = value;
-				} else {
-					newLength = currentLength.longValue() + value;
-				}
-				if (newLength > 1000) {
-					mapTrackUsage.put(id, new Long(newLength / 1000));
-				}
-			} finally {
-				mapTrackUsage_mon.exit();
-			}
-		}
-	}
-
-	public UISWTInstance getUISWTInstanceImpl() {
-		return uiSWTInstanceImpl;
-	}
-
-	/**
-	 * @param url
-	 * @param target
-	 */
-	public void showURL(final String url, String target) {
-
-		if ("_blank".equalsIgnoreCase(target)) {
-			Utils.launch(url);
-			return;
-		}
-
-		if (target.startsWith("tab-")) {
-			target = target.substring(4);
-		}
-
-		SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-
-		// Note; We don't setSourceRef on ContentNetwork here like we do
-		// everywhere else because the source ref should already be set
-		// by the caller
-		String id = sideBar.showEntryByTabID(target);
-		if (id == null) {
-			Utils.launch(url);
-			return;
-		}
-
-		SideBarEntrySWT entry = SideBar.getEntry(id);
-		entry.addListener(new SideBarOpenListener() {
-
-			public void sideBarEntryOpen(SideBarEntry entry) {
-				entry.removeListener(this);
-
-				setVisible(true);
-
-				if (!(entry instanceof SideBarEntrySWT)) {
-					return;
-				}
-				SideBarEntrySWT entrySWT = (SideBarEntrySWT) entry;
-
-				SWTSkinObjectBrowser soBrowser = SWTSkinUtils.findBrowserSO(entrySWT.getSkinObject());
-
-				if (soBrowser != null) {
-					//((SWTSkinObjectBrowser) skinObject).getBrowser().setVisible(false);
-					if (url == null || url.length() == 0) {
-						soBrowser.restart();
-					} else {
-						String fullURL = url;
-						if (UrlFilter.getInstance().urlCanRPC(url)) {
-							// 4010 Tux: This shouldn't be.. either determine ContentNetwork from
-							//           url or target, or do something..
-							fullURL = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(
-									url, false, true);
-						}
-
-						soBrowser.setURL(fullURL);
-					}
-				}
-			}
-		});
-	}
-
-	protected MainStatusBar getMainStatusBar() {
-		return statusBar;
-	}
-
-	public boolean isVisible(int windowElement) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
-			SWTSkinObject skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
-			if (skinObject != null) {
-				return skinObject.isVisible();
-			}
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TABBAR) {
-			SWTSkinObject skinObject = skin.getSkinObject("tabbar");
-			if (skinObject != null) {
-				return skinObject.isVisible();
-			}
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-			//TODO:
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
-			//TODO:
-		}
-
-		return false;
-	}
-
-	public void setVisible(int windowElement, boolean value) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
-
-			SWTSkinUtils.setVisibility(skin, SkinConstants.VIEWID_PLUGINBAR
-					+ ".visible", SkinConstants.VIEWID_PLUGINBAR, value, true, true);
-
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-			//TODO:
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
-			//TODO:
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TABBAR) {
-			SWTSkinUtils.setVisibility(skin, "TabBar.visible",
-					SkinConstants.VIEWID_TAB_BAR, value, true, true);
-		}
-
-	}
-
-	public Rectangle getMetrics(int windowElement) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
-
-			SWTSkinObject skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
-			if (skinObject != null) {
-				return skinObject.getControl().getBounds();
-			}
-
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TABBAR) {
-
-			SWTSkinObject skinObject = skin.getSkinObject("tabbar");
-			if (skinObject != null) {
-				return skinObject.getControl().getBounds();
-			}
-
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-
-			return statusBar.getBounds();
-
-		} else if (windowElement == IMainWindow.WINDOW_CLIENT_AREA) {
-
-			return shell.getClientArea();
-
-		} else if (windowElement == IMainWindow.WINDOW_CONTENT_DISPLAY_AREA) {
-
-			Rectangle r = getMetrics(IMainWindow.WINDOW_CLIENT_AREA);
-			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_TOPBAR).height;
-			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_TABBAR).height;
-			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_STATUSBAR).height;
-			return r;
-
-		}
-
-		return new Rectangle(0, 0, 0, 0);
-	}
-
-	public SWTSkin getSkin() {
-		return skin;
-	}
-
-	public boolean isReady() {
-		return isReady;
-	}
-
-	public Image generateObfusticatedImage() {
-		// 3.2 TODO: Obfusticate! (esp advanced view)
-
-		Image image;
-		Rectangle clientArea = shell.getClientArea();
-		image = new Image(display, clientArea.width, clientArea.height);
-
-		GC gc = new GC(shell);
-		try {
-			gc.copyArea(image, clientArea.x, clientArea.y);
-
-			Control[] children = shell.getChildren();
-			for (int i = 0; i < children.length; i++) {
-				Control control = children[i];
-				SWTSkinObject so = (SWTSkinObject) control.getData("SkinObject");
-				if (so != null) {
-					Image obfusticatedImage = so.generateObfusticatedImage();
-					if (obfusticatedImage != null) {
-						Rectangle bounds = so.getControl().getBounds();
-						gc.drawImage(obfusticatedImage, bounds.x, bounds.y);
-					}
-				}
-			}
-		} finally {
-			gc.dispose();
-		}
-
-		return image;
-	}
-
-	/**
-	 * @param cla
-	 * @param data
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void openView(final String parentID, final Class cla, String id,
-			final Object data, final boolean closeable) {
-		final SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sideBar == null) {
-			return;
-		}
-
-		if (id == null) {
-			id = cla.getName();
-			int i = id.lastIndexOf('.');
-			if (i > 0) {
-				id = id.substring(i + 1);
-			}
-		}
-
-		IView viewFromID = sideBar.getIViewFromID(id);
-		if (viewFromID != null) {
-			sideBar.showEntryByID(id);
-		}
-
-		final String _id = id;
-		Utils.execSWTThreadLater(0, new AERunnable() {
-
-			public void runSupport() {
-				if (sideBar.showEntryByID(_id)) {
-					return;
-				}
-				if (UISWTViewEventListener.class.isAssignableFrom(cla)) {
-					UISWTViewEventListener l = null;
-					try {
-						Constructor<?> constructor = cla.getConstructor(new Class[] {
-							data.getClass()
-						});
-						l = (UISWTViewEventListener) constructor.newInstance(new Object[] {
-							data
-						});
-					} catch (Exception e) {
-					}
-					try {
-						if (l == null) {
-							l = (UISWTViewEventListener) cla.newInstance();
-						}
-						sideBar.createTreeItemFromEventListener(parentID, null, l, _id,
-								closeable, data);
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				} else {
-					sideBar.createTreeItemFromIViewClass(parentID, _id, null, cla,
-							null, null, data, null, true);
-				}
-				sideBar.showEntryByID(_id);
-			}
-		});
-
-	}
-
-	// @see com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarListener#sidebarItemSelected(com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarInfoSWT, com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarInfoSWT)
-	public void sidebarItemSelected(SideBarEntrySWT newSideBarEntry,
-			SideBarEntrySWT oldSideBarEntry) {
-		if (newSideBarEntry == null) {
-			return;
-		}
-
-		if (mapTrackUsage != null && oldSideBarEntry != null) {
-			oldSideBarEntry.removeListener((SideBarLogIdListener) this);
-
-			String id2 = null;
-			SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-			if (sidebar != null) {
-				id2 = oldSideBarEntry.getLogID();
-			}
-			if (id2 == null) {
-				id2 = oldSideBarEntry.id;
-			}
-
-			updateMapTrackUsage(id2);
-		}
-
-		if (mapTrackUsage != null) {
-			newSideBarEntry.addListener((SideBarLogIdListener) this);
-		}
-	}
-
-	// @see com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarLogIdListener#sidebarLogIdChanged(com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT, java.lang.String, java.lang.String)
-	public void sidebarLogIdChanged(SideBarEntrySWT sideBarEntrySWT,
-			String oldID, String newID) {
-		if (oldID == null) {
-			oldID = "null";
-		}
-		updateMapTrackUsage(oldID);
-	}
-
-	// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
-	public void generate(IndentWriter writer) {
-		writer.println("SWT UI");
-
-		try {
-			writer.indent();
-
-			TableColumnManager.getInstance().generateDiagnostics(writer);
-		} finally {
-
-			writer.exdent();
-		}
-	}
-
-	protected void setSelectedLanguageItem() {
-		Messages.updateLanguageForControl(shell);
-
-		if (systemTraySWT != null) {
-			systemTraySWT.updateLanguage();
-		}
-
-		if (statusBar != null) {
-			statusBar.refreshStatusText();
-		}
-
-		// download basket
-
-		skin.triggerLanguageChange();
-
-		if (statusBar != null) {
-			statusBar.updateStatusText();
-		}
-
-		if (menu != null) {
-			MenuFactory.updateMenuText(menu.getMenu(IMenuConstants.MENU_ID_MENU_BAR));
-		}
-	}
-
-	protected MainMenu getMainMenu() {
-		return menu;
-	}
-
+/*
+ * Created on Sep 13, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.shells.main;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.gudy.azureus2.ui.swt.mainwindow.IMainMenu;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainStatusBar;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainWindow;
+
+import com.aelitis.azureus.core.AzureusCore;
+
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+
+
+public interface
+MainWindow
+	extends IMainWindow
+{
+	public void
+	init(
+		AzureusCore		core );
+	
+	
+	public Shell
+	getShell();
+	
+	public IMainMenu 
+	getMainMenu();
+	
+	public IMainStatusBar 
+	getMainStatusBar();
+	
+	public boolean
+	isReady();
+	
+	public void 
+	setVisible(
+		boolean visible, 
+		boolean tryTricks );
+	
+	public UISWTInstanceImpl
+	getUISWTInstanceImpl();
+
+	public void 
+	setSelectedLanguageItem();
+	
+	public boolean 
+	dispose(
+		boolean for_restart,
+		boolean close_already_in_progress );
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainWindowDelayStub.java b/com/aelitis/azureus/ui/swt/shells/main/MainWindowDelayStub.java
new file mode 100644
index 0000000..3a72125
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainWindowDelayStub.java
@@ -0,0 +1,817 @@
+/*
+ * Created on Sep 13, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.shells.main;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.AERunStateHandler;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+import org.gudy.azureus2.ui.swt.UIExitUtilsSWT;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainMenu;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainStatusBar;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainWindow;
+import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
+import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.systray.SystemTraySWT;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreComponent;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
+import com.aelitis.azureus.core.AzureusCoreLifecycleListener;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.ui.IUIIntializer;
+import com.aelitis.azureus.ui.UIFunctions;
+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.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
+
+public class 
+MainWindowDelayStub 
+	implements MainWindow
+{
+	private Display			display;
+	private IUIIntializer	initialiser;
+	
+	private Shell			shell;
+	
+	private AzureusCore		core;
+	private AESemaphore		core_sem = new AESemaphore("");
+	
+	private volatile MainWindow		main_window;
+	
+	private SystemTraySWT	swt_tray;
+	
+	private UIFunctionsSWT	delayed_uif = new UIFunctionsSWTImpl();
+	
+	public
+	MainWindowDelayStub(
+		AzureusCore 			_core, 
+		Display 				_display,
+		IUIIntializer			_uiInitializer )
+	{
+		core		= _core;
+		display		= _display;
+		initialiser	= _uiInitializer;
+		
+		init();
+		
+		core_sem.releaseForever();
+	}
+	
+	public
+	MainWindowDelayStub(
+		Display 		_display, 
+		IUIIntializer 	_uiInitializer )
+	{
+		display		= _display;
+		initialiser	= _uiInitializer;
+		
+		init();
+	}
+	
+	private void
+	init()
+	{		
+		shell = new Shell(display, SWT.SHELL_TRIM);
+	
+		UIFunctionsManagerSWT.setUIFunctions( delayed_uif );
+	
+		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
+
+		if ( bEnableTray ){
+		
+			swt_tray = SystemTraySWT.getTray();
+		}
+		
+		MainHelpers.initTransferBar();
+		
+		if ( initialiser != null ){
+		
+			initialiser.initializationComplete();
+			
+			initialiser.abortProgress();
+		}
+		
+		AERunStateHandler.addListener(
+			new AERunStateHandler.RunStateChangeListener()
+			{
+				private boolean	handled = false;
+				
+				public void 
+				runStateChanged(
+					long run_state )
+				{
+					if ( AERunStateHandler.isDelayedUI() || handled ){
+						
+						return;
+					}
+					
+					handled = true;
+					
+					checkMainWindow();
+				}
+			}, false );
+	}
+	
+	private void
+	log(
+		String	str )
+	{
+		Debug.out( str );
+	}
+	
+	public void
+	init(
+		AzureusCore		_core )
+	{
+		core	= _core;
+				
+		core_sem.releaseForever();
+	}
+		
+	
+		// barp
+	
+	private interface
+	Fixup
+	{
+		public void
+		fix(
+			MainWindow mw );
+	}
+	
+	private interface
+	Fixup2
+	{
+		public Object
+		fix(
+			MainWindow mw );
+	}
+	
+	private interface
+	Fixup3
+	{
+		public void
+		fix(
+			UIFunctionsSWT uif );
+	}
+	
+	private interface
+	Fixup4
+	{
+		public Object
+		fix(
+			UIFunctionsSWT uif );
+	}
+	
+	private void
+	checkMainWindow()
+	{
+		boolean	activated = false;
+		
+		synchronized( this ){
+			
+			if ( main_window == null ){
+				
+				final AESemaphore wait_sem = new AESemaphore( "cmw" );
+				
+				AzureusCoreLifecycleListener listener = 
+					new AzureusCoreLifecycleAdapter()
+					{
+						public void
+						componentCreated(
+							AzureusCore				core,
+							AzureusCoreComponent	component )
+						{
+							if ( component instanceof UIFunctions ){
+								
+								wait_sem.release();
+							}
+						}
+					};
+					
+				core.addLifecycleListener( listener );
+				
+				main_window = new MainWindowImpl( core, display, null );
+				
+				if ( !wait_sem.reserve( 30*1000 )){
+					
+					Debug.out( "Gave up waiting for UIFunction component to be created" );
+				}
+				
+				activated = true;
+			}
+		}
+		
+		if ( activated ){
+			
+			AERunStateHandler.setResourceMode( AERunStateHandler.RS_ALL_ACTIVE );
+		}
+	}
+	
+	private void
+	fixup(
+		Fixup	f )
+	{
+		core_sem.reserve();
+		
+		checkMainWindow();
+		
+		f.fix( main_window );
+	}
+	
+	private Object
+	fixup(
+		Fixup2	f )
+	{
+		core_sem.reserve();
+		
+		checkMainWindow();
+		
+		return( f.fix( main_window ));
+	}
+	
+	private void
+	fixup(
+		Fixup3	f )
+	{
+		core_sem.reserve();
+					
+		checkMainWindow();
+		
+		UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		
+		if ( uif == delayed_uif ){
+			
+			Debug.out( "eh?" );
+			
+		}else{
+			
+			f.fix( uif );
+		}
+	}
+	
+	private Object
+	fixup(
+		Fixup4	f )
+	{
+		core_sem.reserve();
+					
+		checkMainWindow();
+		
+		UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		
+		if ( uif == delayed_uif ){
+			
+			Debug.out( "eh?" );
+			
+			return( null );
+			
+		}else{
+			
+			return( f.fix( uif ));
+		}
+	}
+	
+		// toot
+	
+	public Shell
+	getShell()
+	{		
+		return( shell );
+	}
+
+	public IMainMenu 
+	getMainMenu()
+	{
+		return((IMainMenu)fixup( new Fixup2(){public Object fix( MainWindow mw){ return( mw.getMainMenu()); }}));
+	}
+	
+	
+	public IMainStatusBar 
+	getMainStatusBar()
+	{
+		if ( main_window != null ){
+			
+			return( main_window.getMainStatusBar());
+		}
+				
+		return( null );
+	}
+	
+	public boolean
+	isReady()
+	{
+		log( "isReady" );
+		
+		return( false );
+	}
+	
+	public void 
+	setVisible(
+		final boolean visible, 
+		final boolean tryTricks )
+	{
+		fixup( new Fixup(){public void fix( MainWindow mw){ mw.setVisible( visible, tryTricks ); }});
+	}
+	
+	public UISWTInstanceImpl
+	getUISWTInstanceImpl()
+	{
+		log( "getUISWTInstanceImpl" );
+		
+		return( null );
+	}
+
+	public void 
+	setSelectedLanguageItem()
+	{
+		log( "setSelectedLanguageItem" );	
+	}
+	
+	public boolean 
+	dispose(
+		final boolean for_restart,
+		final boolean close_already_in_progress )
+	{
+		if ( main_window != null ){
+			
+			return( main_window.dispose(for_restart, close_already_in_progress));
+		}
+		
+		log( "dispose" );
+		
+		UIExitUtilsSWT.uiShutdown();
+
+		if ( swt_tray != null ){
+			
+			swt_tray.dispose();
+		}
+		
+		try{
+			AllTransfersBar transfer_bar = AllTransfersBar.getBarIfOpen(core.getGlobalManager());
+			
+			if ( transfer_bar != null ){
+				
+				transfer_bar.forceSaveLocation();
+			}
+		}catch( Exception ignore ){
+		}
+
+		if (!SWTThread.getInstance().isTerminated()) {
+			Utils.getOffOfSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (!SWTThread.getInstance().isTerminated()) {
+						SWTThread.getInstance().getInitializer().stopIt( for_restart, false);
+					}
+				}
+			});
+		}
+
+		return true;
+	}
+	
+	
+	
+	public boolean 
+	isVisible(
+		int windowElement)
+	{
+		log( "isVisible" );
+		
+		return( false );	
+	}
+
+	public void 
+	setVisible(
+		int 		windowElement, 
+		boolean 	value )
+	{
+		log( "setVisible" );	
+	}
+
+	public Rectangle 
+	getMetrics(
+		int windowElement)
+	{
+		log( "getMetrics" );	
+
+		return( null );
+	}
+	
+	private class
+	UIFunctionsSWTImpl
+		implements UIFunctionsSWT
+	{
+		public void 
+		bringToFront()
+		{	
+			fixup( new Fixup3(){public void fix( UIFunctionsSWT uif){ uif.bringToFront(); }});
+		}
+
+		public void 
+		bringToFront(
+			final boolean tryTricks)
+		{	
+			fixup( new Fixup3(){public void fix( UIFunctionsSWT uif){ uif.bringToFront( tryTricks ); }});
+		}
+
+		public void 
+		refreshLanguage()
+		{	
+			log( "refreshLanguage" );
+		}
+
+		public void 
+		refreshIconBar()
+		{	
+			log( "refreshIconBar" );
+		}
+
+		public void 
+		setStatusText(
+			String string )
+		{	
+		}
+
+		public void 
+		setStatusText(
+			int statustype, 
+			String string, 
+			UIStatusTextClickListener l)
+		{	
+			log( "setStatusText" );
+		}
+
+		public boolean 
+		dispose(
+			boolean for_restart, 
+			boolean close_already_in_progress )
+		{
+			return( MainWindowDelayStub.this.dispose( for_restart, close_already_in_progress ));
+		}
+
+		public boolean 
+		viewURL(
+			String url, 
+			String target, 
+			int w, 
+			int h, 
+			boolean allowResize,
+			boolean isModal)
+		{
+			log( "viewURL" );
+			
+			return( false );
+		}
+
+		public boolean 
+		viewURL(
+			String url, 
+			String target, 
+			double wPct, 
+			double hPct,
+			boolean allowResize, 
+			boolean isModal)
+		{
+			log( "viewURL" );
+			
+			return( false );
+		}
+
+		public void 
+		viewURL(
+			String url, 
+			String target, 
+			String sourceRef)
+		{
+			log( "viewURL" );			
+		}
+
+
+		public UIFunctionsUserPrompter 
+		getUserPrompter(
+			String 		title, 
+			String 		text,
+			String[] 	buttons, 
+			int 		defaultOption)
+		{
+			log( "getUserPrompter" );
+			
+			return( null );
+		}
+
+		public void 
+		promptUser(
+			String title, 
+			String text, 
+			String[] buttons,
+			int defaultOption, 
+			String rememberID, 
+			String rememberText,
+			boolean bRememberByDefault, 
+			int autoCloseInMS, 
+			UserPrompterResultListener l)
+		{
+			log( "promptUser" );
+		}
+		
+
+		public UIUpdater 
+		getUIUpdater()
+		{			
+			return( UIUpdaterSWT.getInstance());
+		}
+
+
+		public void 
+		openView(
+			final int 		viewID, 
+			final Object 	datasource )
+		{
+				// OSX Vuze->Preferences menu
+			
+			fixup( new Fixup3(){public void fix( UIFunctionsSWT uif){ uif.openView( viewID, datasource ); }});
+		}
+		
+		public void 
+		doSearch(
+			String searchText )
+		{
+			log( "doSearch" );
+		}
+		
+		public void 
+		doSearch(
+			String searchText, 
+			boolean toSubscribe )
+		{
+			log( "doSearch" );
+		}
+
+		public void
+		installPlugin(
+			String			plugin_id,
+			String			resource_prefix,
+			actionListener	listener )
+		{
+			log( "installPlugin" );
+		}
+		
+
+		public void
+		performAction(
+			final int				action_id,
+			final Object			args,
+			final actionListener	listener )
+		{
+				// auto-update restart prompt (for example)
+			
+			fixup( new Fixup3(){public void fix( UIFunctionsSWT uif){ uif.performAction( action_id, args, listener ); }});
+		}
+		
+		public MultipleDocumentInterface 
+		getMDI()
+		{
+			log( "getMDI" );
+			
+			return( null );
+		}
+
+
+		public void 
+		forceNotify(
+			int iconID, 
+			String title, 
+			String text, 
+			String details,
+			Object[] relatedObjects, 
+			int timeoutSecs)
+		{
+			log( "forceNotify" );
+		}
+		
+		
+		public Shell 
+		getMainShell()
+		{			
+			return( shell );
+		}
+
+
+		public void 
+		addPluginView(
+			String viewID, 
+			UISWTViewEventListener l)
+		{
+			log( "addPluginView" );
+		}
+
+
+		public void 
+		closeDownloadBars()
+		{
+		}
+
+		public boolean 
+		isGlobalTransferBarShown()
+		{
+			if (!AzureusCoreFactory.isCoreRunning()) {
+				return false;
+			}
+			
+			return AllTransfersBar.getManager().isOpen(
+					AzureusCoreFactory.getSingleton().getGlobalManager());
+		}
+
+		public void 
+		showGlobalTransferBar() 
+		{
+			CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+				public void azureusCoreRunning(AzureusCore core) {
+					AllTransfersBar.open(core.getGlobalManager(), getMainShell());
+				}
+			});
+		}
+
+		public void 
+		closeGlobalTransferBar() 
+		{
+			CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+				public void azureusCoreRunning(AzureusCore core) {
+					AllTransfersBar.close(core.getGlobalManager());
+				}
+			});
+		}
+
+
+		public UISWTView[] 
+		getPluginViews()
+		{
+			log( "getPluginViews" );
+			
+			return( null );
+		}
+
+
+		public void 
+		openPluginView(
+			String sParentID, 
+			String sViewID,
+			UISWTViewEventListener l, 
+			Object dataSource, 
+			boolean bSetFocus)
+		{
+			log( "openPluginView" );
+		}
+
+		public void 
+		openPluginView(
+			final UISWTViewCore view, 
+			final String name)
+		{
+			log( "openPluginView" );
+		}
+
+
+		public void 
+		removePluginView(
+			String viewID)
+		{
+			log( "removePluginView" );
+		}
+
+
+		public void 
+		closePluginView(
+			UISWTViewCore view)
+		{
+			log( "closePluginView" );
+		}
+
+		public void 
+		closePluginViews(
+			String sViewID )
+		{
+			log( "closePluginViews" );
+		}
+
+		public UISWTInstance 
+		getUISWTInstance()
+		{
+			log( "getUISWTInstance" );
+			
+			return( null );
+		}
+
+		public void 
+		refreshTorrentMenu()
+		{
+			log( "refreshTorrentMenu" );
+		}
+
+		public IMainStatusBar 
+		getMainStatusBar()
+		{			
+			return( null );
+		}
+
+
+		public IMainMenu 
+		createMainMenu(
+			final Shell shell)
+		{
+				// OSX Vuze->About menu
+
+			return((IMainMenu)fixup( new Fixup4(){public Object fix( UIFunctionsSWT uif){ return( uif.createMainMenu( shell )); }}));
+		}
+
+		public IMainWindow 
+		getMainWindow()
+		{
+			return( MainWindowDelayStub.this );
+		}
+
+		public void 
+		closeAllDetails()
+		{
+			log( "closeAllDetails" );
+		}
+
+
+		public boolean 
+		hasDetailViews()
+		{
+			log( "hasDetailViews" );
+			
+			return( false );
+		}
+		
+		public Shell 
+		showCoreWaitDlg()
+		{
+			return( null );
+		}
+		
+		public MultipleDocumentInterfaceSWT 
+		getMDISWT()
+		{
+			log( "getMDISWT" );
+			
+			return( null );
+		}
+
+		public void 
+		promptForSearch()
+		{
+			log( "promptForSearch" );
+		}
+
+		public UIToolBarManager 
+		getToolBarManager()
+		{
+			log( "getToolBarManager" );
+			
+			return( null );
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainWindowFactory.java b/com/aelitis/azureus/ui/swt/shells/main/MainWindowFactory.java
new file mode 100644
index 0000000..ec82d4a
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainWindowFactory.java
@@ -0,0 +1,90 @@
+/*
+ * Created on Sep 13, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.shells.main;
+
+import org.eclipse.swt.widgets.Display;
+import org.gudy.azureus2.core3.util.AERunStateHandler;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.ui.IUIIntializer;
+
+public class 
+MainWindowFactory 
+{
+	private static final boolean
+	isImmediate()
+	{
+		return( !AERunStateHandler.isDelayedUI());
+	}
+	
+	public static MainWindow
+	create(
+		AzureusCore 			core, 
+		Display 				display,
+		IUIIntializer			uiInitializer )
+	{
+		if ( isImmediate()){
+			
+			return( new MainWindowImpl( core, display, uiInitializer ));
+			
+		}else{
+			
+			return( new MainWindowDelayStub( core, display, uiInitializer ));
+		}
+	}
+	
+	public static MainWindowInitStub
+	createAsync(
+		Display 		display, 
+		IUIIntializer 	uiInitializer )
+	{
+		final MainWindow	window;
+		
+		if ( isImmediate()){
+		
+			window = new MainWindowImpl( display, uiInitializer );
+			
+		}else{
+		
+			window = new MainWindowDelayStub( display, uiInitializer );
+		}
+		
+		return(
+			new MainWindowInitStub()
+			{
+				public void
+				init(
+					AzureusCore		core )
+				{
+					window.init( core );
+				}
+			});
+	}
+	
+	public static interface
+	MainWindowInitStub
+	{
+		public void
+		init(
+			AzureusCore		core );
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/shells/main/MainWindowImpl.java b/com/aelitis/azureus/ui/swt/shells/main/MainWindowImpl.java
new file mode 100644
index 0000000..29ba49d
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/shells/main/MainWindowImpl.java
@@ -0,0 +1,2244 @@
+/*
+ * Created on May 29, 2006 2:07:38 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.shells.main;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.FormData;
+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.ConfigurationChecker;
+import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
+import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
+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.internat.MessageText;
+import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginListener;
+import org.gudy.azureus2.plugins.sharing.ShareException;
+import org.gudy.azureus2.plugins.sharing.ShareManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.associations.AssociationChecker;
+import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateShell;
+import org.gudy.azureus2.ui.swt.debug.UIDebugGenerator;
+import org.gudy.azureus2.ui.swt.donations.DonationWindow;
+import org.gudy.azureus2.ui.swt.mainwindow.*;
+import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
+import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+import org.gudy.azureus2.ui.swt.sharing.progress.ProgressWindow;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.speedtest.SpeedTestSelector;
+import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+import org.gudy.azureus2.ui.swt.welcome.WelcomeWindow;
+import org.gudy.azureus2.ui.systray.SystemTraySWT;
+
+import com.aelitis.azureus.activities.VuzeActivitiesManager;
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger;
+import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger.PlatformLoginCompleteListener;
+import com.aelitis.azureus.core.messenger.config.PlatformDevicesMessenger;
+import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.core.util.FeatureAvailability;
+import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
+import com.aelitis.azureus.ui.IUIIntializer;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.skin.SkinConstants;
+import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
+import com.aelitis.azureus.ui.swt.*;
+import com.aelitis.azureus.ui.swt.columns.utils.TableColumnCreatorV3;
+import com.aelitis.azureus.ui.swt.extlistener.StimulusRPC;
+import com.aelitis.azureus.ui.swt.mdi.BaseMDI;
+import com.aelitis.azureus.ui.swt.mdi.TabbedMDI;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
+import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+import com.aelitis.azureus.ui.swt.views.skin.*;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
+import com.aelitis.azureus.util.*;
+
+/**
+ * @author TuxPaper
+ * @created May 29, 2006
+ *
+ *
+ * TODO:
+ * - MainStatusBar and sidebar components should update when:
+		if (parameterName.equals("config.style.useSIUnits") || parameterName.equals("config.style.forceSIValues")) {
+			updateComponents();
+		}
+ * - IconBarEnabler for "new" and "open"
+ */
+public class MainWindowImpl
+	implements MainWindow, ObfusticateShell, MdiListener,
+	AEDiagnosticsEvidenceGenerator, MdiEntryLogIdListener, UIUpdatable
+{
+
+	private static final LogIDs LOGID = LogIDs.GUI;
+
+	private Shell shell;
+
+	private Display display;
+
+	private AzureusCore core;
+
+	private IUIIntializer uiInitializer;
+
+	private SWTSkin skin;
+
+	private IMainMenu menu;
+
+	private UISWTInstanceImpl uiSWTInstanceImpl;
+
+	private UIFunctionsImpl uiFunctions;
+
+	private SystemTraySWT systemTraySWT;
+
+	private static Map<String, List> mapTrackUsage = null;
+
+	private final static AEMonitor mapTrackUsage_mon = new AEMonitor(
+			"mapTrackUsage");
+
+	private long lCurrentTrackTime = 0;
+
+	private long lCurrentTrackTimeIdle = 0;
+
+	private boolean disposedOrDisposing;
+
+	private DownloadManager[] dms_Startup;
+
+	private boolean isReady = false;
+
+	private MainStatusBar statusBar;
+
+	private String lastShellStatus = null;
+
+	private Color colorSearchTextBG;
+
+	private Color colorSearchTextFGdef;
+
+	private Color colorSearchTextFG;
+	
+	private boolean delayedCore;
+
+	private TrayWindow downloadBasket;
+
+	/**
+	 * Old Initializer.  AzureusCore is required to be started
+	 * 
+	 * @param core
+	 * @param display
+	 * @param uiInitializer
+	 */
+	protected 
+	MainWindowImpl(
+		AzureusCore 			core, 
+		Display 				display,
+		final IUIIntializer		uiInitializer) 
+	{
+		delayedCore = false;
+		this.core = core;
+		this.display = display;
+		this.uiInitializer = uiInitializer;
+		AEDiagnostics.addEvidenceGenerator(this);
+
+		disposedOrDisposing = false;
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				try {
+					createWindow(uiInitializer);
+				} catch (Throwable e) {
+					Logger.log(new LogAlert(false, "Error Initialize MainWindow", e));
+				}
+				if (uiInitializer != null) {
+					uiInitializer.abortProgress();
+				}
+			}
+		});
+
+		// When a download is added, check for new meta data and
+		// un-"wait state" the rating
+		GlobalManager gm = core.getGlobalManager();
+		dms_Startup = (DownloadManager[]) gm.getDownloadManagers().toArray(
+				new DownloadManager[0]);
+		gm.addListener(new GlobalManagerListener() {
+
+			public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
+			}
+
+			public void downloadManagerRemoved(DownloadManager dm) {
+			}
+
+			public void downloadManagerAdded(final DownloadManager dm) {
+				downloadAdded(new DownloadManager[] {
+					dm
+				});
+			}
+
+			public void destroyed() {
+			}
+
+			public void destroyInitiated() {
+			}
+
+		}, false);
+
+		Alerts.addListener(new Alerts.AlertListener() {
+
+			public boolean allowPopup(Object[] relatedObjects, int configID) {
+				DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
+						relatedObjects, DownloadManager.class);
+
+				if (dm == null) {
+					return true;
+				}
+				if (dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
+					return false;
+				}
+
+				return true;
+			}
+
+		});
+	}
+
+	/**
+	 * New Initializer.  AzureusCore does not need to be started.
+	 * Use {@link #init(AzureusCore)} when core is available.
+	 * 
+	 * Called for STARTUP_UIFIRST
+	 * 
+	 * 1) Constructor
+	 * 2) createWindow
+	 * 3) init(core)
+	 * 
+	 * @param display
+	 * @param uiInitializer
+	 */
+	protected MainWindowImpl(final Display display, final IUIIntializer uiInitializer) {
+		//System.out.println("MainWindow: constructor");
+		delayedCore = true;
+		this.display = display;
+		this.uiInitializer = uiInitializer;
+		AEDiagnostics.addEvidenceGenerator(this);
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				//System.out.println("createWindow");
+				try {
+					createWindow(uiInitializer);
+				} catch (Throwable e) {
+					Logger.log(new LogAlert(false, "Error Initialize MainWindow", e));
+				}
+
+				while (!display.isDisposed() && display.readAndDispatch());
+			}
+		});
+	}
+
+	/**
+	 * Called only on STARTUP_UIFIRST
+	 */
+	
+	public void init(final AzureusCore core) {
+		//System.out.println("MainWindow: _init(core)");
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				//System.out.println("_init");
+				_init(core);
+				if (uiInitializer != null) {
+					uiInitializer.abortProgress();
+				}
+			}
+		});
+		UIUpdaterSWT.getInstance().addUpdater(this);
+	}
+
+	/**
+	 * Called only on STARTUP_UIFIRST
+	 */
+	private void _init(AzureusCore core) {
+		//System.out.println("MainWindow: init(core)");
+		this.core = core;
+
+		disposedOrDisposing = false;
+
+		StimulusRPC.hookListeners(core, this);
+
+		uiSWTInstanceImpl = new UISWTInstanceImpl(core);
+		uiSWTInstanceImpl.init(uiInitializer);
+
+		postPluginSetup(core);
+
+		// When a download is added, check for new meta data and
+		// un-"wait state" the rating
+		GlobalManager gm = core.getGlobalManager();
+		dms_Startup = (DownloadManager[]) gm.getDownloadManagers().toArray(
+				new DownloadManager[0]);
+		gm.addListener(new GlobalManagerListener() {
+
+			public void seedingStatusChanged(boolean seeding_only_mode, boolean b) {
+			}
+
+			public void downloadManagerRemoved(DownloadManager dm) {
+			}
+
+			public void downloadManagerAdded(final DownloadManager dm) {
+				downloadAdded(new DownloadManager[] {
+					dm
+				});
+			}
+
+			public void destroyed() {
+			}
+
+			public void destroyInitiated() {
+			}
+
+		}, false);
+
+		Alerts.addListener(new Alerts.AlertListener() {
+
+			public boolean allowPopup(Object[] relatedObjects, int configID) {
+				DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
+						relatedObjects, DownloadManager.class);
+
+				if (dm == null) {
+					return true;
+				}
+				if (dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
+					return false;
+				}
+
+				return true;
+			}
+
+		});
+
+		core.triggerLifeCycleComponentCreated(uiFunctions);
+
+		processStartupDMS();
+	}
+
+	private void postPluginSetup(AzureusCore core) {
+		// we pass core in just as reminder that this function needs core
+		if (core == null) {
+			return;
+		}
+
+		if (!Utils.isAZ2UI()) {
+			VuzeActivitiesManager.initialize(core);
+		}
+
+		if (!Constants.isSafeMode) {
+			
+			if (core.getTrackerHost().getTorrents().length > 0) {
+				Utils.execSWTThreadLater(0, new Runnable() {
+					public void run() {
+						uiFunctions.openView(UIFunctions.VIEW_MYTRACKER, null);
+					}
+				});
+			}
+
+			// share manager init is async so we need to deal with this
+			PluginInterface default_pi = PluginInitializer.getDefaultInterface();
+			try {
+				final ShareManager share_manager = default_pi.getShareManager();
+
+				default_pi.addListener(new PluginListener() {
+					public void initializationComplete() {
+					}
+
+					public void closedownInitiated() {
+						int share_count = share_manager.getShares().length;
+						COConfigurationManager.setParameter("GUI_SWT_share_count_at_close",
+								share_count);
+					}
+
+					public void closedownComplete() {
+					}
+				});
+
+				if (share_manager.getShares().length > 0
+						|| COConfigurationManager.getIntParameter("GUI_SWT_share_count_at_close") > 0) {
+
+					Utils.execSWTThreadLater(0, new Runnable() {
+						public void run() {
+							uiFunctions.openView(UIFunctions.VIEW_MYSHARES, null);
+						}
+					});
+				}
+			} catch (ShareException e) {
+				Debug.out(e);
+			}
+			
+			
+			MainHelpers.initTransferBar();
+			
+			COConfigurationManager.addAndFireParameterListener("IconBar.enabled",
+					new ParameterListener() {
+						public void parameterChanged(String parameterName) {
+							setVisible(WINDOW_ELEMENT_TOOLBAR, COConfigurationManager.getBooleanParameter(parameterName));
+						}
+					});
+		}
+
+		//  share progress window
+		new ProgressWindow( display );
+	}
+
+	private void processStartupDMS() {
+		// must be in a new thread because we don't want to block
+		// initilization or any other add listeners
+		AEThread2 thread = new AEThread2("v3.mw.dmAdded", true) {
+			public void run() {
+				long startTime = SystemTime.getCurrentTime();
+				if (dms_Startup == null || dms_Startup.length == 0) {
+					dms_Startup = null;
+					return;
+				}
+
+				downloadAdded(dms_Startup);
+
+				dms_Startup = null;
+
+				System.out.println("psDMS " + (SystemTime.getCurrentTime() - startTime)
+						+ "ms");
+			}
+		};
+		thread.setPriority(Thread.MIN_PRIORITY);
+		thread.start();
+	}
+
+	private void downloadAdded(final DownloadManager[] dms) {
+		boolean oneIsNotPlatformAndPersistent = false;
+		for (final DownloadManager dm : dms) {
+			if (dm == null) {
+				continue;
+			}
+
+			DownloadManagerState dmState = dm.getDownloadState();
+
+			final TOTorrent torrent = dm.getTorrent();
+			if (torrent == null) {
+				continue;
+			}
+
+			String title = PlatformTorrentUtils.getContentTitle(torrent);
+			if (title != null && title.length() > 0
+					&& dmState.getDisplayName() == null) {
+				dmState.setDisplayName(title);
+			}
+
+			if (ConfigurationChecker.isNewVersion() && dm.getAssumedComplete()) {
+				String lastVersion = COConfigurationManager.getStringParameter("Last Version");
+				if (org.gudy.azureus2.core3.util.Constants.compareVersions(lastVersion,
+						"3.1.1.1") <= 0) {
+					long completedTime = dmState.getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_COMPLETED_TIME);
+					if (completedTime < SystemTime.getOffsetTime(-(1000 * 60))) {
+						PlatformTorrentUtils.setHasBeenOpened(dm, true);
+					}
+				}
+			}
+
+			boolean isContent = PlatformTorrentUtils.isContent(torrent, true)
+					|| PlatformTorrentUtils.getContentNetworkID(torrent) == ContentNetwork.CONTENT_NETWORK_VHDNL;
+
+			if (!oneIsNotPlatformAndPersistent && !isContent
+					&& !dmState.getFlag(DownloadManagerState.FLAG_LOW_NOISE) && dm.isPersistent()) {
+				oneIsNotPlatformAndPersistent = true;
+			}
+
+			if (isContent) {
+				long now = SystemTime.getCurrentTime();
+
+				long expiresOn = PlatformTorrentUtils.getExpiresOn(torrent);
+				if (expiresOn > now) {
+					SimpleTimer.addEvent("dm Expirey", expiresOn,
+							new TimerEventPerformer() {
+								public void perform(TimerEvent event) {
+									dm.getDownloadState().setFlag(
+											DownloadManagerState.FLAG_LOW_NOISE, true);
+									ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+											true, true, null);
+								}
+							});
+				}
+			} // isContent
+		}
+
+		if (oneIsNotPlatformAndPersistent && dms_Startup == null) {
+			DonationWindow.checkForDonationPopup();
+		}
+	}
+
+	/**
+	 * @param uiInitializer 
+	 * 
+	 * called in both delayedCore and !delayedCore
+	 */
+	private void createWindow(IUIIntializer uiInitializer) {
+		//System.out.println("MainWindow: createWindow)");
+
+		long startTime = SystemTime.getCurrentTime();
+
+		UIFunctionsSWT existing_uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
+				
+		uiFunctions = new UIFunctionsImpl(this);
+		
+		UIFunctionsManager.setUIFunctions(uiFunctions);
+
+		Utils.disposeComposite(shell);
+
+		increaseProgress(uiInitializer, "splash.initializeGui");
+
+		System.out.println("UIFunctions/ImageLoad took "
+				+ (SystemTime.getCurrentTime() - startTime) + "ms");
+		startTime = SystemTime.getCurrentTime();
+
+		shell = existing_uif==null?new Shell(display, SWT.SHELL_TRIM):existing_uif.getMainShell();
+
+		if (Constants.isWindows) {
+			try {
+				Class<?> ehancerClass = Class.forName("org.gudy.azureus2.ui.swt.win32.Win32UIEnhancer");
+				Method method = ehancerClass.getMethod("initMainShell",
+						new Class[] {
+							Shell.class
+						});
+				method.invoke(null, new Object[] {
+					shell
+				});
+			} catch (Exception e) {
+				Debug.outNoStack(Debug.getCompressedStackTrace(e, 0, 30), true);
+			}
+		}
+
+		try {
+			shell.setData("class", this);
+			shell.setText("Vuze");
+			Utils.setShellIcon(shell);
+			Utils.linkShellMetricsToConfig(shell, "window");
+			//Shell activeShell = display.getActiveShell();
+			//shell.setVisible(true);
+			//shell.moveBelow(activeShell);
+
+			System.out.println("new shell took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			PlatformConfigMessenger.addPlatformLoginCompleteListener(new PlatformLoginCompleteListener() {
+				public void platformLoginComplete() {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							setupUsageTracker();
+						}
+					});
+				}
+			});
+			
+			try {
+				PlatformDevicesMessenger.setupDeviceSender();
+			} catch (Exception e) {
+				Debug.out("failed to setup device sender ", e);
+			}
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+
+			skin = SWTSkinFactory.getInstance();
+			if (Utils.isAZ2UI()) {
+  			SWTSkinProperties skinProperties = skin.getSkinProperties();
+  			String skinPath = SkinPropertiesImpl.PATH_SKIN_DEFS + "skin3_classic";
+  			ResourceBundle rb = ResourceBundle.getBundle(skinPath);
+  			skinProperties.addResourceBundle(rb, skinPath);
+  			String[] ids = {
+  				"image.toolbar.2nd.m-bg",
+  				"image.toolbar.2nd.r-bg",
+  				"image.toolbar.2nd.l-bg",
+  				"image.toolbar.2nd-view.l-bg",
+  				"image.toolbar.2nd-view.r-bg",
+  				"image.toolbar.start",
+  				"image.toolbar.stop",
+  				"image.toolbar.remove",
+  				"image.toolbar.up",
+  				"image.toolbar.down",
+  			};
+  			for (String id : ids) {
+  				String s = skinProperties.getStringValue(id);
+  				if (s != null) {
+  					skinProperties.addProperty(id, s.replaceAll("/tb/", "/tb/c/"));
+  				}
+  			}
+			}
+
+			/*
+			 * KN: passing the skin to the uifunctions so it can be used by UIFunctionsSWT.createMenu()
+			 */
+			uiFunctions.setSkin(skin);
+
+			System.out.println("new shell setup took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			initSkinListeners();
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+			// 0ms
+			//System.out.println("skinlisteners init took " + (SystemTime.getCurrentTime() - startTime) + "ms");
+			//startTime = SystemTime.getCurrentTime();
+
+			String startID = Utils.isAZ2UI() ? "classic.shell" : "main.shell";
+			skin.initialize(shell, startID, uiInitializer);
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+			System.out.println("skin init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			if (Utils.isAZ2UI()) {
+				menu = new org.gudy.azureus2.ui.swt.mainwindow.MainMenu(shell);
+			} else {
+				menu = new MainMenu(skin, shell);
+			}
+			shell.setData("MainMenu", menu);
+
+			System.out.println("MainMenu init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			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.CocoaUIEnhancer");
+
+						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
+							});
+						}
+
+					} catch (Throwable e) {
+						if (!Constants.isOSX_10_7_OrHigher) {
+							Debug.printStackTrace(e);
+						}
+					}
+
+				}
+
+				Listener toggleListener = new Listener() {
+					public void handleEvent(Event event) {
+						ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
+						if (tb != null) {
+							tb.flipShowText();
+						}
+					}
+				};
+				shell.addListener(SWT.Expand, toggleListener);
+				shell.addListener(SWT.Collapse, toggleListener);
+
+				System.out.println("createWindow init took "
+						+ (SystemTime.getCurrentTime() - startTime) + "ms");
+				startTime = SystemTime.getCurrentTime();
+			}
+
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+
+			skin.layout();
+
+			// 0ms
+			//System.out.println("skin layout took " + (SystemTime.getCurrentTime() - startTime) + "ms");
+			//startTime = SystemTime.getCurrentTime();
+
+			try {
+				Utils.createTorrentDropTarget(shell, false);
+			} catch (Throwable e) {
+				Logger.log(new LogEvent(LOGID, "Drag and Drop not available", e));
+			}
+
+			shell.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					dispose(false, false);
+				}
+			});
+
+			shell.addShellListener(new ShellAdapter() {
+				public void shellClosed(ShellEvent event) {
+					if (disposedOrDisposing) {
+						return;
+					}
+					if (systemTraySWT != null
+							&& COConfigurationManager.getBooleanParameter("Enable System Tray")
+							&& COConfigurationManager.getBooleanParameter("Close To Tray")) {
+
+						minimizeToTray(event);
+					} else {
+						event.doit = dispose(false, false);
+					}
+				}
+
+				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;
+					}
+					if (systemTraySWT != null
+							&& COConfigurationManager.getBooleanParameter("Enable System Tray")
+							&& COConfigurationManager.getBooleanParameter("Minimize To Tray")) {
+
+						minimizeToTray(event);
+					}
+				}
+
+				public void shellDeiconified(ShellEvent e) {
+					if (Constants.isOSX
+							&& COConfigurationManager.getBooleanParameter("Password enabled")) {
+						shell.setVisible(false);
+						if (PasswordWindow.showPasswordWindow(display)) {
+							shell.setVisible(true);
+						}
+					}
+				}
+			});
+			
+			display.addFilter(SWT.KeyDown, new Listener() {
+				public void handleEvent(Event event) {
+					// Another window has control, skip filter
+					Control focus_control = display.getFocusControl();
+					if (focus_control != null && focus_control.getShell() != shell)
+						return;
+
+					int key = event.character;
+					if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
+							&& event.character > 0)
+						key += 'a' - 1;
+
+					if (key == 'l' && (event.stateMask & SWT.MOD1) != 0) {
+						// Ctrl-L: Open URL
+						if (core == null) {
+							return;
+						}
+						GlobalManager gm = core.getGlobalManager();
+						if (gm != null) {
+							OpenTorrentWindow.invokeURLPopup(shell, gm);
+							event.doit = false;
+						}
+					} else if (key == 'f'
+							&& (event.stateMask & (SWT.MOD1 + SWT.SHIFT)) == SWT.MOD1
+									+ SWT.SHIFT) {
+						shell.setFullScreen(!shell.getFullScreen());
+					}
+				}
+			});
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+			System.out.println("pre skin widgets init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			if (core != null) {
+				StimulusRPC.hookListeners(core, this);
+			}
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+			// 0ms
+			//System.out.println("hooks init took " + (SystemTime.getCurrentTime() - startTime) + "ms");
+			//startTime = SystemTime.getCurrentTime();
+
+			initMDI();
+			System.out.println("skin widgets (1/2) init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+			initWidgets2();
+
+			increaseProgress(uiInitializer, "v3.splash.initSkin");
+			System.out.println("skin widgets (2/2) init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			System.out.println("pre SWTInstance init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			increaseProgress(uiInitializer, "v3.splash.hookPluginUI");
+			startTime = SystemTime.getCurrentTime();
+
+			TableColumnCreatorV3.initCoreColumns();
+
+			System.out.println("Init Core Columns took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			increaseProgress(uiInitializer, "v3.splash.hookPluginUI");
+			startTime = SystemTime.getCurrentTime();
+
+			if (core != null) {
+				// attach the UI to plugins
+				// Must be done before initializing views, since plugins may register
+				// table columns and other objects
+				uiSWTInstanceImpl = new UISWTInstanceImpl(core);
+				uiSWTInstanceImpl.init(uiInitializer);
+				//uiSWTInstanceImpl.addView(UISWTInstance.VIEW_MYTORRENTS,
+				//		"PieceGraphView", new PieceGraphView());
+			}
+
+			System.out.println("SWTInstance init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			increaseProgress(uiInitializer, "splash.initializeGui");
+			startTime = SystemTime.getCurrentTime();
+
+		} catch (Throwable t) {
+			Debug.out(t);
+		} finally {
+
+			String configID = SkinConstants.VIEWID_PLUGINBAR + ".visible";
+			if (false == ConfigurationDefaults.getInstance().doesParameterDefaultExist(
+					configID)) {
+				COConfigurationManager.setBooleanDefault(configID, true);
+			}
+			setVisible(WINDOW_ELEMENT_TOPBAR,
+					COConfigurationManager.getBooleanParameter(configID)
+							&& COConfigurationManager.getIntParameter("User Mode") > 1);
+
+			setVisible(WINDOW_ELEMENT_TOOLBAR,
+					COConfigurationManager.getBooleanParameter("IconBar.enabled"));
+
+			shell.layout(true, true);
+
+			System.out.println("shell.layout took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			showMainWindow();
+
+			//================
+
+			increaseProgress(uiInitializer, "splash.initializeGui");
+
+			System.out.println("shell.open took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			processStartupDMS();
+
+			System.out.println("processStartupDMS took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			if (core != null) {
+				postPluginSetup(core);
+			}
+
+			System.out.println("postPluginSetup init took "
+					+ (SystemTime.getCurrentTime() - startTime) + "ms");
+			startTime = SystemTime.getCurrentTime();
+
+			NavigationHelper.addListener(new NavigationHelper.navigationListener() {
+				public void processCommand(final int type, final String[] args) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+
+							UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+							if (type == NavigationHelper.COMMAND_SWITCH_TO_TAB) {
+								MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+								if (mdi == null) {
+									return;
+								}
+								mdi.showEntryByID(args[0]);
+
+								if (uif != null) {
+
+									uif.bringToFront();
+								}
+							} else if (type == NavigationHelper.COMMAND_CONDITION_CHECK) {
+							}
+						}
+					});
+				}
+			});
+		}
+	}
+
+	/**
+	 * @param uiInitializer
+	 * @param taskKey TODO
+	 *
+	 * @since 3.0.4.3
+	 */
+	private void increaseProgress(IUIIntializer uiInitializer, String taskKey) {
+		if (uiInitializer != null) {
+			uiInitializer.increaseProgress();
+			if (taskKey != null) {
+				uiInitializer.reportCurrentTask(MessageText.getString(taskKey));
+			}
+		}
+		// XXX Disabled because plugin update window will pop up and take control
+		// 		 of the dispatch loop..
+		/*
+		if (Utils.isThisThreadSWT()) {
+			// clean the dispatch loop so the splash screen gets updated
+			int i = 1000;
+			while (display.readAndDispatch() && i > 0) {
+				i--;
+			}
+			//if (i < 999) {
+			//	System.out.println("dispatched " + (1000 - i));
+			//}
+		}
+		*/
+	}
+
+	@SuppressWarnings("deprecation")
+	public boolean dispose(final boolean for_restart,
+			final boolean close_already_in_progress) {
+		if (disposedOrDisposing) {
+			return true;
+		}
+		return Utils.execSWTThreadWithBool("v3.MainWindow.dispose",
+				new AERunnableBoolean() {
+					public boolean runSupport() {
+						return _dispose(for_restart, close_already_in_progress);
+					}
+				});
+	}
+
+	private boolean _dispose(final boolean bForRestart, boolean bCloseAlreadyInProgress) {
+		if (disposedOrDisposing) {
+			return true;
+		}
+
+		isReady = false;
+
+		disposedOrDisposing = true;
+		if (core != null
+				&& !UIExitUtilsSWT.canClose(core.getGlobalManager(), bForRestart)) {
+			disposedOrDisposing = false;
+			return false;
+		}
+
+		UIExitUtilsSWT.uiShutdown();
+
+		if (systemTraySWT != null) {
+			systemTraySWT.dispose();
+		}
+
+		/**
+		 * Explicitly force the transfer bar location to be saved (if appropriate and open).
+		 * 
+		 * We can't rely that the normal mechanism for doing this won't fail (which it usually does)
+		 * when the GUI is being disposed of.
+		 */
+		try {
+  		AllTransfersBar transfer_bar = AllTransfersBar.getBarIfOpen(core.getGlobalManager());
+  		if (transfer_bar != null) {
+  			transfer_bar.forceSaveLocation();
+  		}
+		} catch (Exception ignore) {
+		}
+
+		mapTrackUsage_mon.enter();
+		try {
+			if (mapTrackUsage != null) {
+				String id = getUsageActiveTabID();
+				if (id != null) {
+					if (lastShellStatus == null) {
+						lastShellStatus = id;
+					}
+					updateMapTrackUsage(lastShellStatus);
+				}
+
+				Map<String, Object> map = new HashMap<String, Object>();
+				map.put("version",
+						org.gudy.azureus2.core3.util.Constants.AZUREUS_VERSION);
+				map.put("statsmap", mapTrackUsage);
+
+				FileUtil.writeResilientFile(new File(SystemProperties.getUserPath(),
+						"timingstats.dat"), map);
+			}
+		} finally {
+			mapTrackUsage_mon.exit();
+		}
+
+		if (!SWTThread.getInstance().isTerminated()) {
+			Utils.getOffOfSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (!SWTThread.getInstance().isTerminated()) {
+						SWTThread.getInstance().getInitializer().stopIt(bForRestart, false);
+					}
+				}
+			});
+		}
+
+		return true;
+	}
+
+	private String getUsageActiveTabID() {
+		try {
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+			if (mdi != null) {
+				MdiEntry curEntry = mdi.getCurrentEntry();
+				if (curEntry == null) {
+					return "none";
+				}
+				String id = curEntry.getLogID();
+				return id == null ? "null" : id;
+			}
+		} catch (Exception e) {
+			String name = e.getClass().getName();
+			int i = name.indexOf('.');
+			if (i > 0) {
+				return name.substring(i);
+			}
+			return name;
+		}
+		return "unknown";
+	}
+
+	/**
+	 * 
+	 */
+	private void setupUsageTracker() {
+		mapTrackUsage_mon.enter();
+		try {
+			File f = new File(SystemProperties.getUserPath(), "timingstats.dat");
+
+			if (COConfigurationManager.getBooleanParameter("Send Version Info")
+					&& PlatformConfigMessenger.allowSendStats()) {
+
+				mapTrackUsage = new HashMap<String, List>();
+
+				if (f.exists()) {
+					Map<?, ?> oldMapTrackUsage = FileUtil.readResilientFile(f);
+					String version = MapUtils.getMapString(oldMapTrackUsage, "version",
+							null);
+					Map<?, ?> map = MapUtils.getMapMap(oldMapTrackUsage, "statsmap", null);
+					if (version != null && map != null) {
+						PlatformConfigMessenger.sendUsageStats(map, f.lastModified(),
+								version, null);
+					}
+				}
+
+				SimpleTimer.addPeriodicEvent("UsageTracker", 1000,
+						new TimerEventPerformer() {
+							long lLastMouseMove = SystemTime.getCurrentTime();
+
+							Point ptLastMousePos = new Point(0, 0);
+
+							public void perform(TimerEvent event) {
+								Utils.execSWTThread(new AERunnable() {
+									public void runSupport() {
+										if (shell == null || shell.isDisposed()
+												|| shell.getDisplay().getActiveShell() == null) {
+											// so when we become active again, we count a few
+											// seconds (if the mouse moves)
+											if (ptLastMousePos.x > 0) {
+												ptLastMousePos.x = 0;
+												ptLastMousePos.y = 0;
+												lLastMouseMove = 0;
+											}
+											return;
+										}
+
+										Point pt = shell.getDisplay().getCursorLocation();
+										if (pt.equals(ptLastMousePos)) {
+											return;
+										}
+										ptLastMousePos = pt;
+
+										long now = SystemTime.getCurrentTime();
+										if (lLastMouseMove > 0) {
+											long diff = now - lLastMouseMove;
+											if (diff < 10000) {
+												lCurrentTrackTime += diff;
+											} else {
+												lCurrentTrackTimeIdle += diff;
+											}
+										}
+
+										lLastMouseMove = now;
+									}
+								});
+							}
+						});
+
+				Listener lActivateDeactivate = new Listener() {
+					long start;
+
+					public void handleEvent(Event event) {
+						if (event.type == SWT.Activate) {
+							lCurrentTrackTimeIdle = 0;
+							if (start > 0 && lastShellStatus != null) {
+								lCurrentTrackTime = SystemTime.getCurrentTime() - start;
+								updateMapTrackUsage(lastShellStatus);
+							}
+							lastShellStatus = null;
+						} else {
+							updateMapTrackUsage(getUsageActiveTabID());
+							if (shell.getMinimized()) {
+								lastShellStatus = "idle-minimized";
+							} else if (!shell.isVisible()) {
+								lastShellStatus = "idle-invisible";
+							} else {
+								lastShellStatus = "idle-nofocus";
+							}
+							start = SystemTime.getCurrentTime();
+						}
+					}
+				};
+				shell.addListener(SWT.Activate, lActivateDeactivate);
+				shell.addListener(SWT.Deactivate, lActivateDeactivate);
+
+			} else {
+				mapTrackUsage = null;
+				// No use keeping old usage stats if we are told no one wants them
+				try {
+					if (f.exists()) {
+						f.delete();
+					}
+				} catch (Exception e) {
+				}
+			}
+		} catch (Exception e) {
+			Debug.out(e);
+		} finally {
+			mapTrackUsage_mon.exit();
+		}
+	}
+
+	private void showMainWindow() {
+		COConfigurationManager.addAndFireParameterListener("Show Download Basket", new ParameterListener() {
+			public void parameterChanged(String parameterName) {
+				configureDownloadBasket();
+			}
+		});
+
+		boolean isOSX = org.gudy.azureus2.core3.util.Constants.isOSX;
+		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
+		boolean bPassworded = COConfigurationManager.getBooleanParameter("Password enabled");
+		boolean bStartMinimize = bEnableTray
+				&& (bPassworded || COConfigurationManager.getBooleanParameter("Start Minimized"));
+
+		SWTSkinObject soMain = skin.getSkinObject("main");
+		if (soMain != null) {
+			soMain.getControl().setVisible(true);
+		}
+
+		shell.addListener(SWT.Show, new Listener() {
+			public void handleEvent(Event event) {
+				System.out.println("---------SHOWN AT " + SystemTime.getCurrentTime()
+						+ ";" + (SystemTime.getCurrentTime() - Initializer.startTime)
+						+ "ms");
+			}
+		});
+
+		if (!bStartMinimize) {
+			shell.open();
+			if (!isOSX) {
+				shell.forceActive();
+			}
+		} else if (Utils.isCarbon) {
+			shell.setVisible(true);
+			shell.setMinimized(true);
+		}
+		
+
+		if (delayedCore) {
+			// 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
+			try {
+  			long endSWTDispatchOn = SystemTime.getOffsetTime(5000);
+  			while (SystemTime.getCurrentTime() < endSWTDispatchOn
+  					&& !display.isDisposed() && display.readAndDispatch());
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+
+			System.out.println("---------DONE DISPATCH AT "
+  				+ SystemTime.getCurrentTime() + ";"
+  				+ (SystemTime.getCurrentTime() - Initializer.startTime) + "ms");
+  		if (display.isDisposed()) {
+  			return;
+  		}
+		}
+
+		if (bEnableTray) {
+
+			try {
+				systemTraySWT = SystemTraySWT.getTray();
+
+			} catch (Throwable e) {
+
+				e.printStackTrace();
+				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+						"Upgrade to SWT3.0M8 or later for system tray support."));
+			}
+
+			if (bStartMinimize) {
+				minimizeToTray(null);
+			}
+			//Only show the password if not started minimized
+			//Correct bug #878227
+			else {
+				if (bPassworded) {
+					minimizeToTray(null);
+					setVisible(true); // invokes password
+				}
+			}
+		}
+
+		// do this before other checks as these are blocking dialogs to force order
+
+		if (uiInitializer != null) {
+
+			uiInitializer.initializationComplete();
+		}
+			
+		boolean	run_speed_test = false;
+
+		if (!Utils.isAZ2UI() && !COConfigurationManager.getBooleanParameter("SpeedTest Completed")){
+			
+			
+			if ( ConfigurationChecker.isNewInstall()){
+				
+				run_speed_test = true;
+				
+			}else if ( FeatureAvailability.triggerSpeedTestV1()){
+				
+				long	upload_limit	= COConfigurationManager.getLongParameter("Max Upload Speed KBs" );
+				boolean	auto_up			= COConfigurationManager.getBooleanParameter( TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY );
+				
+				if ( auto_up ){
+					
+					if ( upload_limit <= 18 ){
+						
+						run_speed_test = true;
+					}
+				}else{
+					
+					boolean up_seed_limit	= COConfigurationManager.getBooleanParameter("enable.seedingonly.upload.rate" );
+				
+					if ( upload_limit == 0 && !up_seed_limit ){
+						
+						run_speed_test = true;
+					}
+				}
+			}
+		}
+		
+		
+		if ( run_speed_test ){
+
+			SpeedTestSelector.runMLABTest(false,
+				new AERunnable() 
+				{
+					public void 
+					runSupport() 
+					{
+						WelcomeView.setWaitLoadingURL(false);
+					}
+				});
+		}else{
+			
+			WelcomeView.setWaitLoadingURL(false);
+		}
+
+		if (Utils.isAZ2UI()) {
+  		if (!COConfigurationManager.getBooleanParameter("Wizard Completed")) {
+  
+  			CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+  				public void azureusCoreRunning(AzureusCore core) {
+  					new ConfigureWizard(false, ConfigureWizard.WIZARD_MODE_FULL);
+  				}
+  			});
+  		}
+
+			checkForWhatsNewWindow();
+		}
+
+		AssociationChecker.checkAssociations();
+
+		// Donation stuff
+		Map<?, ?> map = VersionCheckClient.getSingleton().getMostRecentVersionCheckData();
+		DonationWindow.setInitialAskHours(MapUtils.getMapInt(map,
+				"donations.askhrs", DonationWindow.getInitialAskHours()));
+
+		if (core != null) {
+			core.triggerLifeCycleComponentCreated(uiFunctions);
+		}
+
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				fixupActionBarSize();
+				SWTSkinObject soPlusHeader = skin.getSkinObject("plus-header");
+				if (soPlusHeader != null) {
+					soPlusHeader.addListener(new SWTSkinObjectListener() {
+						public Object eventOccured(SWTSkinObject skinObject, int eventType,
+								Object params) {
+							if (eventType == SWTSkinObjectListener.EVENT_HIDE
+									|| eventType == SWTSkinObjectListener.EVENT_SHOW) {
+								fixupActionBarSize();
+							}
+							return null;
+						}
+					});
+				}
+			}
+		});
+
+		System.out.println("---------READY AT " + SystemTime.getCurrentTime() + ";"
+				+ (SystemTime.getCurrentTime() - Initializer.startTime) + "ms");
+		isReady = true;
+		//SESecurityManagerImpl.getSingleton().exitVM(0);
+	}
+
+	private void configureDownloadBasket() {
+		if (COConfigurationManager.getBooleanParameter("Show Download Basket")) {
+			if (downloadBasket == null) {
+				downloadBasket = new TrayWindow();
+				downloadBasket.setVisible(true);
+			}
+		} else if (downloadBasket != null) {
+			downloadBasket.setVisible(false);
+			downloadBasket = null;
+		}
+	}
+
+	private void checkForWhatsNewWindow() {
+		final String CONFIG_LASTSHOWN = "welcome.version.lastshown";
+
+		// Config used to store int, such as 2500.  Now, it stores a string
+		// getIntParameter will return default value if parameter is string (user
+		// downgraded)
+		// getStringParameter will bork if parameter isn't really a string
+
+		try {
+			String lastShown = "";
+			boolean bIsStringParam = true;
+			try {
+				lastShown = COConfigurationManager.getStringParameter(CONFIG_LASTSHOWN,
+						"");
+			} catch (Exception e) {
+				bIsStringParam = false;
+			}
+
+			if (lastShown.length() == 0) {
+				// check if we have an old style version
+				int latestDisplayed = COConfigurationManager.getIntParameter(
+						CONFIG_LASTSHOWN, 0);
+				if (latestDisplayed > 0) {
+					bIsStringParam = false;
+					String s = "" + latestDisplayed;
+					for (int i = 0; i < s.length(); i++) {
+						if (i != 0) {
+							lastShown += ".";
+						}
+						lastShown += s.charAt(i);
+					}
+				}
+			}
+
+			if (Constants.compareVersions(lastShown, Constants.getBaseVersion()) < 0) {
+				new WelcomeWindow(shell);
+				if (!bIsStringParam) {
+					// setting parameter to a different value type makes az unhappy
+					COConfigurationManager.removeParameter(CONFIG_LASTSHOWN);
+				}
+				COConfigurationManager.setParameter(CONFIG_LASTSHOWN,
+						Constants.getBaseVersion());
+				COConfigurationManager.save();
+			}
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+	}
+
+
+	private void setVisible(final boolean visible) {
+		setVisible(visible, true);
+	}
+
+	public void setVisible(final boolean visible, final boolean tryTricks) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				boolean currentlyVisible = shell.getVisible() && !shell.getMinimized();
+				if (visible && !currentlyVisible) {
+					if (COConfigurationManager.getBooleanParameter("Password enabled")) {
+						if (!PasswordWindow.showPasswordWindow(display)) {
+							shell.setVisible(false);
+							return;
+						}
+					}
+				}
+				
+				if (!isReady) {
+					return;
+				}
+
+				ArrayList<Shell> wasVisibleList = null;
+				boolean bHideAndShow = false;
+				// temp disabled
+				//tryTricks && visible && Constants.isWindows && display.getActiveShell() != shell;
+				if (bHideAndShow) {
+					wasVisibleList = new ArrayList<Shell>();
+					// We don't want the window to just flash and not open, so:
+					// -Minimize main shell
+					// -Set all shells invisible
+					try {
+						shell.setMinimized(true);
+						Shell[] shells = shell.getDisplay().getShells();
+						for (int i = 0; i < shells.length; i++) {
+							if (shells[i].isVisible()) {
+								wasVisibleList.add(shells[i]);
+								shells[i].setVisible(false);
+							}
+						}
+					} catch (Exception e) {
+					}
+				}
+
+				if (visible) {
+					if (shell.getMinimized()) {
+						shell.setMinimized(false);
+					}
+					if (!currentlyVisible
+							&& COConfigurationManager.getBooleanParameter("window.maximized")) {
+						shell.setMaximized(true);
+					}
+				} else {
+					// XXX hack for release.. should not access param outside Utils.linkShellMetrics
+					COConfigurationManager.setParameter("window.maximized",
+							shell.getMaximized());
+				}
+
+				shell.setVisible(visible);
+				if (visible) {
+					shell.forceActive();
+
+					if (bHideAndShow) {
+						try {
+							Shell[] shells = shell.getDisplay().getShells();
+							for (int i = 0; i < shells.length; i++) {
+								if (shells[i] != shell) {
+									if (wasVisibleList != null
+											&& wasVisibleList.contains(shells[i])) {
+										shells[i].setVisible(visible);
+									}
+									shells[i].setFocus();
+								}
+							}
+						} catch (Exception e) {
+						}
+					}
+				}
+
+			}
+		});
+	}
+
+	private void minimizeToTray(ShellEvent event) {
+		//Added this test so that we can call this method with null parameter.
+		if (event != null) {
+			event.doit = false;
+		}
+
+		// XXX hack for release.. should not access param outside Utils.linkShellMetrics
+		COConfigurationManager.setParameter("window.maximized",
+				shell.getMaximized());
+		shell.setVisible(false);
+		MiniBarManager.getManager().setAllVisible(true);
+	}
+
+	/**
+	 * Associates every view ID that we use to a class, and creates the class
+	 * on first EVENT_SHOW.
+	 */
+	private void initSkinListeners() {
+		UISkinnableManagerSWT skinnableManagerSWT = UISkinnableManagerSWT.getInstance();
+		skinnableManagerSWT.addSkinnableListener(MessageBoxShell.class.toString(),
+				new UISkinnableSWTListener() {
+					public void skinBeforeComponents(Composite composite,
+							Object skinnableObject, Object[] relatedObjects) {
+
+						MessageBoxShell shell = (MessageBoxShell) skinnableObject;
+
+						TOTorrent torrent = null;
+						DownloadManager dm = (DownloadManager) LogRelationUtils.queryForClass(
+								relatedObjects, DownloadManager.class);
+						if (dm != null) {
+							torrent = dm.getTorrent();
+						} else {
+							torrent = (TOTorrent) LogRelationUtils.queryForClass(
+									relatedObjects, TOTorrent.class);
+						}
+
+						if (torrent != null && shell.getLeftImage() == null) {
+							byte[] contentThumbnail = PlatformTorrentUtils.getContentThumbnail(torrent);
+							if (contentThumbnail != null) {
+								try {
+									ByteArrayInputStream bis = new ByteArrayInputStream(
+											contentThumbnail);
+									final Image img = new Image(Display.getDefault(), bis);
+
+									shell.setLeftImage(img);
+
+									composite.addDisposeListener(new DisposeListener() {
+										public void widgetDisposed(DisposeEvent e) {
+											if (!img.isDisposed()) {
+												img.dispose();
+											}
+										}
+									});
+								} catch (Exception e) {
+
+								}
+							}
+						}
+					}
+
+					public void skinAfterComponents(Composite composite,
+							Object skinnableObject, Object[] relatedObjects) {
+					}
+				});
+	}
+
+	private void initMDI() {
+		Class<?> classMDI = Utils.isAZ2UI() ? TabbedMDI.class : SideBar.class;
+
+		try {
+			SWTSkinObject skinObject = skin.getSkinObject(SkinConstants.VIEWID_MDI);
+			if (null != skinObject) {
+				BaseMDI mdi = (BaseMDI) classMDI.newInstance();
+				mdi.setMainSkinObject(skinObject);
+				skinObject.addListener(mdi);
+				MainMDISetup.setupSideBar(mdi, this);
+			}
+		} catch (Throwable t) {
+			Debug.out(t);
+		}
+	}
+
+	private void initWidgets2() {
+		SWTSkinObject skinObject = skin.getSkinObject("statusbar");
+		if (skinObject != null) {
+			final Composite cArea = (Composite) skinObject.getControl();
+
+			statusBar = new MainStatusBar();
+			Composite composite = statusBar.initStatusBar(cArea);
+
+			composite.setLayoutData(Utils.getFilledFormData());
+		}
+
+		skinObject = skin.getSkinObject("search-text");
+		if (skinObject != null) {
+			attachSearchBox(skinObject);
+		}
+
+		skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
+		if (skinObject != null) {
+			Menu topbarMenu = new Menu(shell, SWT.POP_UP);
+
+			if (COConfigurationManager.getIntParameter("User Mode") > 1) {
+				MainMenu.createViewMenuItem(skin, topbarMenu,
+						"v3.MainWindow.menu.view." + SkinConstants.VIEWID_PLUGINBAR,
+						SkinConstants.VIEWID_PLUGINBAR + ".visible",
+						SkinConstants.VIEWID_PLUGINBAR, true, -1);
+			}
+
+			final MenuItem itemShowText = new MenuItem(topbarMenu, SWT.CHECK);
+			Messages.setLanguageText(itemShowText,
+					"v3.MainWindow.menu.showActionBarText");
+			itemShowText.addSelectionListener(new SelectionAdapter() {
+				// @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+				public void widgetSelected(SelectionEvent e) {
+					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
+					if (tb != null) {
+						tb.flipShowText();
+					}
+				}
+			});
+
+			new MenuItem(topbarMenu, SWT.SEPARATOR);
+			
+			final MenuItem itemExport = new MenuItem(topbarMenu, SWT.PUSH);
+			Messages.setLanguageText(itemExport,
+					"search.export.all");
+			itemExport.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					final Shell shell = Utils.findAnyShell();
+					
+					shell.getDisplay().asyncExec(
+						new AERunnable() 
+						{
+							public void 
+							runSupport()
+							{
+								FileDialog dialog = 
+									new FileDialog( shell, SWT.SYSTEM_MODAL | SWT.SAVE );
+								
+								dialog.setFilterPath( TorrentOpener.getFilterPathData() );
+														
+								dialog.setText(MessageText.getString("metasearch.export.select.template.file"));
+								
+								dialog.setFilterExtensions(new String[] {
+										"*.vuze",
+										"*.vuz",
+										org.gudy.azureus2.core3.util.Constants.FILE_WILDCARD
+									});
+								dialog.setFilterNames(new String[] {
+										"*.vuze",
+										"*.vuz",
+										org.gudy.azureus2.core3.util.Constants.FILE_WILDCARD
+									});
+								
+								String path = TorrentOpener.setFilterPathData( dialog.open());
+			
+								if ( path != null ){
+									
+									String lc = path.toLowerCase();
+									
+									if ( !lc.endsWith( ".vuze" ) && !lc.endsWith( ".vuz" )){
+										
+										path += ".vuze";
+									}
+									
+									try{
+										MetaSearchManagerFactory.getSingleton().getMetaSearch().exportEngines(  new File( path ));
+										
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+									}
+								}
+							}
+						});	
+				}
+			});
+			
+			topbarMenu.addMenuListener(new MenuListener() {
+				public void menuShown(MenuEvent e) {
+					ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
+					if (tb != null) {
+						itemShowText.setSelection(tb.getShowText());
+					}
+				}
+
+				public void menuHidden(MenuEvent e) {
+				}
+			});
+
+			addMenuAndNonTextChildren((Composite) skinObject.getControl(), topbarMenu);
+
+			skinObject = skin.getSkinObject("tabbar");
+			if (skinObject != null) {
+				addMenuAndNonTextChildren((Composite) skinObject.getControl(),
+						topbarMenu);
+			}
+		}
+	}
+
+	private void addMenuAndNonTextChildren(Composite parent, Menu menu) {
+		parent.setMenu(menu);
+
+		Control[] children = parent.getChildren();
+		for (int i = 0; i < children.length; i++) {
+			Control control = children[i];
+			if (control instanceof Composite) {
+				Composite c = (Composite) control;
+				addMenuAndNonTextChildren(c, menu);
+			} else if (!(control instanceof Text)) {
+				control.setMenu(menu);
+			}
+		}
+	}
+
+	/**
+	 * @param skinObject
+	 */
+	private void attachSearchBox(SWTSkinObject skinObject) {
+		Composite cArea = (Composite) skinObject.getControl();
+
+		shell.addListener(SWT.Resize, new Listener() {
+			public void handleEvent(Event event) {
+				fixupActionBarSize();
+			}
+		});
+
+		final Text text = new Text(cArea, SWT.NONE);
+		FormData filledFormData = Utils.getFilledFormData();
+		text.setLayoutData(filledFormData);
+
+		text.setData("ObfusticateImage", new ObfusticateImage() {
+			public Image obfusticatedImage(Image image) {
+				Point location = Utils.getLocationRelativeToShell(text);
+				Point size = text.getSize();
+				UIDebugGenerator.obfusticateArea(image, new Rectangle(
+						location.x, location.y, size.x, size.y));
+				return image;
+			}
+		});
+		
+		text.addListener(SWT.Resize, new Listener() {
+			Font lastFont = null;
+
+			public void handleEvent(Event event) {
+				Text text = (Text) event.widget;
+
+				int h = text.getClientArea().height - 2;
+				Font font = FontUtils.getFontWithHeight(text.getFont(), null, h);
+				if (font != null) {
+					text.setFont(font);
+
+					Utils.disposeSWTObjects(new Object[] {
+						lastFont
+					});
+
+					text.addDisposeListener(new DisposeListener() {
+						public void widgetDisposed(DisposeEvent e) {
+							Text text = (Text) e.widget;
+							text.setFont(null);
+							Utils.disposeSWTObjects(new Object[] {
+								lastFont
+							});
+						}
+					});
+				}
+			}
+		});
+		text.setTextLimit(254);
+		
+		if (Constants.isWindows) {
+  		text.addListener(SWT.MouseDown, new Listener() {
+  			public void handleEvent(Event event) {
+  				if (event.count == 3) {
+  					text.selectAll();
+  				}
+  			}
+  		});
+		}
+
+		final String sDefault = MessageText.getString("v3.MainWindow.search.defaultText");
+
+		String tooltip = MessageText.getString( "v3.MainWindow.search.tooltip" );
+		
+		text.setToolTipText( tooltip );
+		
+		SWTSkinProperties properties = skinObject.getProperties();
+		colorSearchTextBG = properties.getColor("color.search.text.bg");
+		colorSearchTextFG = properties.getColor("color.search.text.fg");
+		colorSearchTextFGdef = properties.getColor("color.search.text.fg.default");
+
+		if (colorSearchTextFGdef != null) {
+			text.setForeground(colorSearchTextFGdef);
+		}
+		if (colorSearchTextBG != null) {
+			text.setBackground(colorSearchTextBG);
+		}
+		text.addMouseListener(new MouseListener() {
+
+			public void mouseUp(MouseEvent e) {
+				Text text = (Text) e.widget;
+				if (text.getText().equals(sDefault)) {
+					if (colorSearchTextFG != null) {
+						text.setForeground(colorSearchTextFG);
+					}
+					text.setText("");
+				}
+			}
+
+			public void mouseDown(MouseEvent e) {
+			}
+
+			public void mouseDoubleClick(MouseEvent e) {
+			}
+		});
+
+		text.addKeyListener(new KeyListener() {
+			public void keyPressed(KeyEvent e) {
+				if (e.stateMask == SWT.MOD1) {
+
+					int key = e.character;
+					if (key <= 26 && key > 0) {
+						key += 'a' - 1;
+					}
+
+					if (key == 'a') {
+						text.selectAll();
+					}
+				}
+
+			}
+
+			public void keyReleased(KeyEvent arg0) {
+				// TODO Auto-generated method stub
+
+			}
+		});
+
+		text.addListener(SWT.KeyDown, new Listener() {
+
+			public void handleEvent(Event event) {
+				if (text.getText().equals(sDefault)) {
+					if (colorSearchTextFG != null) {
+						text.setForeground(colorSearchTextFG);
+					}
+					if (event.character != '\0') {
+						text.setText("");
+					}
+					return;
+				}
+
+				Text text = (Text) event.widget;
+				if (event.keyCode == SWT.ESC) {
+					text.setText("");
+					return;
+				}
+				if (event.character == SWT.CR) {
+					uiFunctions.doSearch(text.getText());
+				}
+			}
+		});
+
+		// must be done after layout
+		text.setText(sDefault);
+		//text.selectAll();
+
+		SWTSkinObject searchGo = skin.getSkinObject("search-go");
+		if (searchGo != null) {
+			SWTSkinButtonUtility btnGo = new SWTSkinButtonUtility(searchGo);
+			btnGo.addSelectionListener(new ButtonListenerAdapter() {
+				public void pressed(SWTSkinButtonUtility buttonUtility,
+						SWTSkinObject skinObject, int stateMask) {
+					String sSearchText = text.getText().trim();
+					uiFunctions.doSearch(sSearchText);
+				}
+			});
+		}
+
+		SWTSkinObject so = skin.getSkinObject("sidebar-list");
+		if (so != null
+				&& so.getProperties().getBooleanValue(
+						so.getConfigID() + ".resizeSearch", false)) {
+			Listener l = new Listener() {
+				public void handleEvent(Event event) {
+					SWTSkinObject soSearchArea = skin.getSkinObject("topbar-area-search");
+					if (soSearchArea != null) {
+						Control c = soSearchArea.getControl();
+						Rectangle bounds = ((Control) event.widget).getBounds();
+						FormData fd = (FormData) c.getLayoutData();
+						int newWidth = bounds.width - 1 - c.getBounds().x;
+						if (bounds.width < 125) {
+							return;
+						}
+						fd.width = newWidth;
+						Utils.relayout(c);
+					}
+				}
+			};
+			so.getControl().addListener(SWT.Resize, l);
+		}
+
+		so = skin.getSkinObject("search-dropdown");
+		if (so != null) {
+			SWTSkinButtonUtility btnSearchDD = new SWTSkinButtonUtility(so);
+			btnSearchDD.setTooltipID( "v3.MainWindow.search.tooltip" );
+			btnSearchDD.addSelectionListener(new ButtonListenerAdapter() {
+				public void pressed(SWTSkinButtonUtility buttonUtility,
+						SWTSkinObject skinObject, int stateMask) {
+					String sSearchText = text.getText().trim();
+					uiFunctions.doSearch(sSearchText);
+				}
+			});
+		}
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 4.0.0.1
+	 */
+	private void fixupActionBarSize() {
+		final int MAXWIDTH = 320;
+		Rectangle clientArea = shell.getClientArea();
+		SWTSkinObject soSearch = skin.getSkinObject("topbar-area-search");
+		if (soSearch == null) {
+			return;
+		}
+		FormData fd = (FormData) soSearch.getControl().getLayoutData();
+		if (fd == null || fd.width <= 0) {
+			return;
+		}
+		if (clientArea.width > 1124 && fd.width == MAXWIDTH) {
+			return;
+		}
+		SWTSkinObject soTabBar = skin.getSkinObject(SkinConstants.VIEWID_TAB_BAR);
+		if (soTabBar == null) {
+			return;
+		}
+		Point size = soTabBar.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT);
+		int oldWidth = fd.width;
+		fd.width = clientArea.width - (size.x - oldWidth) - 5;
+		if (fd.width < 100) {
+			fd.width = 100;
+		} else if (fd.width > MAXWIDTH) {
+			fd.width = MAXWIDTH;
+		}
+
+		if (oldWidth != fd.width) {
+			((Composite) soTabBar.getControl()).layout(true, true);
+		}
+	}
+
+
+	/**
+	 * 
+	 */
+	private void updateMapTrackUsage(String sTabID) {
+		//System.out.println("UPDATE: " + sTabID);
+		if (mapTrackUsage != null) {
+			mapTrackUsage_mon.enter();
+			try {
+				if (lCurrentTrackTime > 1000) {
+					addUsageStat(sTabID, lCurrentTrackTime);
+					//System.out.println("UPDATE: " + sTabID + ";" + newLength);
+				}
+
+				if (lCurrentTrackTimeIdle > 1000) {
+					String id = "idle-" + sTabID;
+					addUsageStat(id, lCurrentTrackTimeIdle);
+				}
+			} finally {
+				mapTrackUsage_mon.exit();
+			}
+		}
+
+		lCurrentTrackTime = 0;
+		lCurrentTrackTimeIdle = 0;
+	}
+
+	private static void addUsageStat(String id, long value) {
+		if (id == null) {
+			return;
+		}
+		if (id.length() > 150) {
+			id = id.substring(0, 150);
+		}
+		if (mapTrackUsage != null) {
+			mapTrackUsage_mon.enter();
+			try {
+				List currentLength = mapTrackUsage.get(id);
+				if (currentLength == null) {
+					currentLength = new ArrayList();
+					currentLength.add(1);
+					currentLength.add(value / 100);
+				} else {
+					List oldList = currentLength;
+					currentLength = new ArrayList();
+					currentLength.add(((Number) oldList.get(0)).longValue() + 1);
+					currentLength.add(((Number) oldList.get(1)).longValue() + (value / 1000));
+				}
+				mapTrackUsage.put(id, currentLength);
+			} finally {
+				mapTrackUsage_mon.exit();
+			}
+		}
+	}
+
+	public Shell
+	getShell()
+	{
+		return( shell );
+	}
+	
+	public UISWTInstanceImpl getUISWTInstanceImpl() {
+		return uiSWTInstanceImpl;
+	}
+
+	public MainStatusBar getMainStatusBar() {
+		return statusBar;
+	}
+
+	public boolean isVisible(int windowElement) {
+		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
+			SWTSkinObject skinObject = skin.getSkinObject("tabbar");
+			if (skinObject != null) {
+				return skinObject.isVisible();
+			}
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
+			SWTSkinObject skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
+			if (skinObject != null) {
+				return skinObject.isVisible();
+			}
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
+			//TODO:
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
+			//TODO:
+		}
+
+		return false;
+	}
+
+	public void setVisible(int windowElement, boolean value) {
+		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
+			SWTSkinUtils.setVisibility(skin, "IconBar.enabled",
+					SkinConstants.VIEWID_TAB_BAR, value, true, true);
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
+
+			SWTSkinUtils.setVisibility(skin, SkinConstants.VIEWID_PLUGINBAR
+					+ ".visible", SkinConstants.VIEWID_PLUGINBAR, value, true, true);
+
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
+			//TODO:
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
+			//TODO:
+		}
+
+	}
+
+	public Rectangle getMetrics(int windowElement) {
+		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
+
+			SWTSkinObject skinObject = skin.getSkinObject(SkinConstants.VIEWID_PLUGINBAR);
+			if (skinObject != null) {
+				return skinObject.getControl().getBounds();
+			}
+
+		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
+
+			return statusBar.getBounds();
+
+		} else if (windowElement == IMainWindow.WINDOW_CLIENT_AREA) {
+
+			return shell.getClientArea();
+
+		} else if (windowElement == IMainWindow.WINDOW_CONTENT_DISPLAY_AREA) {
+
+			Rectangle r = getMetrics(IMainWindow.WINDOW_CLIENT_AREA);
+			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_TOPBAR).height;
+			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_TOOLBAR).height;
+			r.height -= getMetrics(IMainWindow.WINDOW_ELEMENT_STATUSBAR).height;
+			return r;
+
+		}
+
+		return new Rectangle(0, 0, 0, 0);
+	}
+
+	private SWTSkin getSkin() {
+		return skin;
+	}
+
+	public boolean isReady() {
+		return isReady;
+	}
+
+	public Image generateObfusticatedImage() {
+		// 3.2 TODO: Obfusticate! (esp advanced view)
+
+		Rectangle shellBounds = shell.getBounds();
+		Rectangle shellClientArea = shell.getClientArea();
+		Image fullImage = new Image(display, shellBounds.width, shellBounds.height);
+		Image subImage = new Image(display, shellClientArea.width, shellClientArea.height);
+
+		GC gc = new GC(display);
+		try {
+			gc.copyArea(fullImage, shellBounds.x, shellBounds.y);
+		} finally {
+			gc.dispose();
+		}
+		GC gcShell = new GC(shell);
+		try {
+			gcShell.copyArea(subImage, 0, 0);
+		} finally {
+			gcShell.dispose();
+		}
+		GC gcFullImage = new GC(fullImage);
+		try {
+			Point location = shell.toDisplay(0, 0);
+			gcFullImage.drawImage(subImage, location.x - shellBounds.x, location.y
+					- shellBounds.y);
+		} finally {
+			gcFullImage.dispose();
+		}
+		subImage.dispose();
+
+		Control[] children = shell.getChildren();
+		for (int i = 0; i < children.length; i++) {
+			Control control = children[i];
+			SWTSkinObject so = (SWTSkinObject) control.getData("SkinObject");
+			if (so instanceof ObfusticateImage) {
+				ObfusticateImage oi = (ObfusticateImage) so;
+				oi.obfusticatedImage(fullImage);
+			}
+		}
+
+		return fullImage;
+	}
+
+	// @see com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarListener#sidebarItemSelected(com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarInfoSWT, com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarInfoSWT)
+	public void mdiEntrySelected(MdiEntry newEntry,
+			MdiEntry oldEntry) {
+		if (newEntry == null) {
+			return;
+		}
+
+		COConfigurationManager.setParameter("v3.StartTab",
+				newEntry.getId());
+
+		if (mapTrackUsage != null && oldEntry != null) {
+			oldEntry.removeListener(this);
+
+			String id2 = null;
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+			if (mdi != null) {
+				id2 = oldEntry.getLogID();
+			}
+			if (id2 == null) {
+				id2 = oldEntry.getId();
+			}
+
+			updateMapTrackUsage(id2);
+		}
+
+		if (mapTrackUsage != null) {
+			newEntry.addListener(this);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.swt.views.skin.sidebar.MdiLogIdListener#sidebarLogIdChanged(com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT, java.lang.String, java.lang.String)
+	public void mdiEntryLogIdChanged(MdiEntry sideBarEntrySWT, String oldID,
+			String newID) {
+		if (oldID == null) {
+			oldID = "null";
+		}
+		updateMapTrackUsage(oldID);
+	}
+
+	// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
+	public void generate(IndentWriter writer) {
+		writer.println("SWT UI");
+
+		try {
+			writer.indent();
+
+			TableColumnManager.getInstance().generateDiagnostics(writer);
+		} finally {
+
+			writer.exdent();
+		}
+	}
+
+	public void setSelectedLanguageItem() {
+		Messages.updateLanguageForControl(shell);
+
+		if (systemTraySWT != null) {
+			systemTraySWT.updateLanguage();
+		}
+
+		if (statusBar != null) {
+			statusBar.refreshStatusText();
+		}
+
+		// download basket
+
+		skin.triggerLanguageChange();
+
+		if (statusBar != null) {
+			statusBar.updateStatusText();
+		}
+
+		if (menu != null) {
+			MenuFactory.updateMenuText(menu.getMenu(IMenuConstants.MENU_ID_MENU_BAR));
+		}
+	}
+
+	public IMainMenu getMainMenu() {
+		return menu;
+	}
+
+	public void updateUI() {
+		//if (shell != null) {
+		//	Utils.setShellIcon(shell);
+		//}
+	}
+
+	public String getUpdateUIName() {
+		return "MainWindow";
+	}
+
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java b/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
index 03ce018..9ef892f 100644
--- a/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
+++ b/com/aelitis/azureus/ui/swt/shells/main/UIFunctionsImpl.java
@@ -19,15 +19,15 @@
  */
 package com.aelitis.azureus.ui.swt.shells.main;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import java.lang.reflect.Constructor;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
@@ -38,36 +38,50 @@ 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.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.plugins.PluginView;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
+import org.gudy.azureus2.core3.util.UrlUtils;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.FileDownloadWindow;
+import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.*;
-import org.gudy.azureus2.ui.swt.mainwindow.MainWindow;
 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
 import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
-import org.gudy.azureus2.ui.swt.plugins.*;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
 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;
 
 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.*;
+import com.aelitis.azureus.ui.common.table.TableView;
 import com.aelitis.azureus.ui.common.updater.UIUpdater;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryOpenListener;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 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.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.plugininstall.SimplePluginInstaller;
 import com.aelitis.azureus.ui.swt.shells.BrowserWindow;
 import com.aelitis.azureus.ui.swt.skin.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
@@ -76,6 +90,8 @@ import com.aelitis.azureus.ui.swt.utils.ColorCache;
 import com.aelitis.azureus.ui.swt.views.skin.*;
 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.ConstantsVuze;
 import com.aelitis.azureus.util.ContentNetworkUtils;
 import com.aelitis.azureus.util.UrlFilter;
 
@@ -92,17 +108,6 @@ public class UIFunctionsImpl
 	private final com.aelitis.azureus.ui.swt.shells.main.MainWindow mainWindow;
 
 	/**
-	 * This isn't presently populated.
-	 * mapPluginViews stores the plugin views that need to be added once the
-	 * oldMainWindow is created.  Currently, we create the oldMainWindow
-	 * at startup.  Once we swtich to delayed oldMainWindow creation, in theory
-	 * the code will work.
-	 */
-	private final Map mapPluginViews = new HashMap();
-
-	private final AEMonitor pluginViews_mon = new AEMonitor("v3.uif.pluginViews");
-
-	/**
 	 * Stores the current <code>SWTSkin</code> so it can be used by {@link #createMenu(Shell)}
 	 */
 	private SWTSkin skin = null;
@@ -117,28 +122,13 @@ public class UIFunctionsImpl
 		this.mainWindow = window;
 		
 		COConfigurationManager.addAndFireParameterListener(
-				"Menu.show.torrent.menu", new ParameterListener() {
+				"show_torrents_menu", new ParameterListener() {
 					public void parameterChanged(String parameterName) {
-						isTorrentMenuVisible = COConfigurationManager.getBooleanParameter("Menu.show.torrent.menu");
+						isTorrentMenuVisible = COConfigurationManager.getBooleanParameter("show_torrents_menu");
 					}
 				});
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#addPluginView(org.gudy.azureus2.plugins.PluginView)
-	public void addPluginView(PluginView view) {
-		try {
-			pluginViews_mon.enter();
-			try {
-				mapPluginViews.put(view, null);
-			} finally {
-				pluginViews_mon.exit();
-			}
-		} catch (Exception e) {
-			Logger.log(new LogEvent(LOGID, "addPluginView", e));
-		}
-
-	}
-
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#addPluginView(java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener)
 	public void addPluginView(final String viewID, final UISWTViewEventListener l) {
 		try {
@@ -155,21 +145,6 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#addPluginView(org.gudy.azureus2.ui.swt.plugins.UISWTPluginView)
-	public void addPluginView(UISWTPluginView view) {
-		try {
-			pluginViews_mon.enter();
-			try {
-				mapPluginViews.put(view, null);
-			} finally {
-				pluginViews_mon.exit();
-			}
-		} catch (Exception e) {
-			Logger.log(new LogEvent(LOGID, "addPluginView", e));
-		}
-
-	}
-
 	// @see com.aelitis.azureus.ui.UIFunctions#bringToFront()
 	public void bringToFront() {
 		bringToFront(true);
@@ -206,24 +181,26 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closePluginView(org.gudy.azureus2.ui.swt.views.IView)
-	public void closePluginView(IView view) {
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closePluginView(org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore)
+	 */
+	public void closePluginView(UISWTViewCore view) {
 		try {
-			SkinView sideBarView = SkinViewManager.getByClass(SideBar.class);
-			if (sideBarView instanceof SideBar) {
-				SideBar sideBar = (SideBar) sideBarView;
-				String id;
-				if (view instanceof UISWTViewImpl) {
-					id = ((UISWTViewImpl)view).getViewID();
-				} else {
-  				id = view.getClass().getName();
-  				int i = id.lastIndexOf('.');
-  				if (i > 0) {
-  					id = id.substring(i + 1);
-  				}
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+			if (mdi == null) {
+				return;
+			}
+			String id;
+			if (view instanceof UISWTViewImpl) {
+				id = ((UISWTViewImpl)view).getViewID();
+			} else {
+				id = view.getClass().getName();
+				int i = id.lastIndexOf('.');
+				if (i > 0) {
+					id = id.substring(i + 1);
 				}
-				sideBar.closeEntry(id);
 			}
+			mdi.closeEntry(id);
 
 		} catch (Exception e) {
 			Logger.log(new LogEvent(LOGID, "closePluginView", e));
@@ -234,11 +211,11 @@ public class UIFunctionsImpl
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closePluginViews(java.lang.String)
 	public void closePluginViews(String sViewID) {
 		try {
-			SkinView sideBarView = SkinViewManager.getByClass(SideBar.class);
-			if (sideBarView instanceof SideBar) {
-				SideBar sideBar = (SideBar) sideBarView;
-				sideBar.closeEntry(sViewID);
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+			if (mdi == null) {
+				return;
 			}
+			mdi.closeEntry(sViewID);
 			
 		} catch (Exception e) {
 			Logger.log(new LogEvent(LOGID, "closePluginViews", e));
@@ -258,15 +235,7 @@ public class UIFunctionsImpl
 
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMainShell()
 	public Shell getMainShell() {
-		return mainWindow.shell;
-	}
-
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMenu(int)
-	public Menu getMenu(int id) {
-		// TODO Auto-generated method stub
-		// XXX Don't use oldMainWindow, menu is global and oldMainWindow
-		//     shouldn't need to be initialized
-		return null;
+		return mainWindow == null ? null : mainWindow.getShell();
 	}
 
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getPluginViews()
@@ -291,17 +260,19 @@ public class UIFunctionsImpl
 		return null;
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(org.gudy.azureus2.ui.swt.views.AbstractIView, java.lang.String)
-	public void openPluginView(AbstractIView view, String name) {
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore, java.lang.String)
+	 */
+	public void openPluginView(UISWTViewCore view, String name) {
 		try {
-			SkinView sideBarView = SkinViewManager.getByClass(SideBar.class);
-			if (sideBarView instanceof SideBar) {
-				SideBar sideBar = (SideBar) sideBarView;
-
-				if (sideBar.createTreeItemFromIView(null, view, name, null, true, true,
-						true) != null) {
-					return;
-				}
+			MultipleDocumentInterfaceSWT mdi = getMDISWT();
+			if (mdi == null) {
+				return;
+			}
+			if (mdi.createEntryFromView(
+					MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS, view, name, null,
+					true, true, true) != null) {
+				return;
 			}
 		} catch (Exception e) {
 			Logger.log(new LogEvent(LOGID, "openPluginView", e));
@@ -309,31 +280,33 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(org.gudy.azureus2.plugins.PluginView)
-	public void openPluginView(PluginView view) {
-		openPluginView(view, view.getPluginViewName());
-	}
-
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(java.lang.String, java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener, java.lang.Object, boolean)
 	public void openPluginView(String sParentID, String sViewID,
 			UISWTViewEventListener l, Object dataSource, boolean bSetFocus) {
 		try {
-			SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
+			MultipleDocumentInterfaceSWT mdi = getMDISWT();
 
-			if (sideBar != null) {
+			if (mdi != null) {
 				
 				String sidebarParentID = null;
 				
 				if (UISWTInstance.VIEW_MYTORRENTS.equals(sParentID)) {
-					sidebarParentID = SideBar.SIDEBAR_SECTION_LIBRARY;
-				} else if (!UISWTInstance.VIEW_MAIN.equals(sParentID)) {
+					sidebarParentID = SideBar.SIDEBAR_HEADER_TRANSFERS;
+				} else if (UISWTInstance.VIEW_MAIN.equals(sParentID)) {
+					sidebarParentID = MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS;
+				} else {
 					System.err.println("Can't find parent " + sParentID + " for " + sViewID);
 				}
 				
-				sideBar.createTreeItemFromEventListener(sidebarParentID, null, l, sViewID,
+				MdiEntry entry = mdi.createEntryFromEventListener(sidebarParentID, l, sViewID,
 						true, dataSource);
 				if (bSetFocus) {
-					sideBar.showEntryByID(sViewID);
+					mdi.showEntryByID(sViewID);
+				} else if (entry instanceof BaseMdiEntry) {
+					// Some plugins (CVS Updater) want their view's composite initialized
+					// on OpenPluginView, otherwise they won't do logic users expect
+					// (like check for new snapshots).  So, enforce loading entry.
+					((BaseMdiEntry) entry).build();
 				}
 			}
 		} catch (Exception e) {
@@ -342,11 +315,6 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(org.gudy.azureus2.ui.swt.plugins.UISWTPluginView)
-	public void openPluginView(UISWTPluginView view) {
-		openPluginView(view, view.getPluginViewName());
-	}
-
 	// @see com.aelitis.azureus.ui.UIFunctions#refreshIconBar()
 	public void refreshIconBar() {
 		try {
@@ -372,27 +340,10 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.UIFunctions#removeManagerView(org.gudy.azureus2.core3.download.DownloadManager)
-	public void removeManagerView(DownloadManager dm) {
-		try {
-			// TODO: ????!
-			
-		} catch (Exception e) {
-			Logger.log(new LogEvent(LOGID, "removeManagerView", e));
-		}
-
-	}
-
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#removePluginView(java.lang.String)
 	public void removePluginView(String viewID) {
 		try {
 
-			pluginViews_mon.enter();
-			try {
-				mapPluginViews.remove(viewID);
-			} finally {
-				pluginViews_mon.exit();
-			}
 			PluginsMenuHelper.getInstance().removePluginViews(viewID);
 
 		} catch (Exception e) {
@@ -401,51 +352,39 @@ public class UIFunctionsImpl
 
 	}
 
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#removePluginView(org.gudy.azureus2.ui.swt.plugins.UISWTPluginView)
-	public void removePluginView(UISWTPluginView view) {
-		try {
-
-			pluginViews_mon.enter();
-			try {
-				mapPluginViews.remove(view);
-			} finally {
-				pluginViews_mon.exit();
-			}
-			PluginsMenuHelper.getInstance().removePluginView(view, view.getPluginViewName());
-
-		} catch (Exception e) {
-			Logger.log(new LogEvent(LOGID, "removePluginView", e));
-		}
-
-	}
-
 	// @see com.aelitis.azureus.ui.UIFunctions#setStatusText(java.lang.String)
-	public void setStatusText(String string) {
-		// TODO Auto-generated method stub
-
-		// XXX Don't use oldMainWindow, status bar is global and oldMainWindow
-		//     shouldn't need to be initialized
+	public void setStatusText(final String string) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				getMainStatusBar().setStatusText(string);
+			}
+		});
 	}
 
 	// @see com.aelitis.azureus.ui.UIFunctions#setStatusText(int, java.lang.String, com.aelitis.azureus.ui.UIStatusTextClickListener)
-	public void setStatusText(int statustype, String string,
-			UIStatusTextClickListener l) {
-		// TODO Auto-generated method stub
-
+	public void setStatusText(final int statustype, final String string,
+			final UIStatusTextClickListener l) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				getMainStatusBar().setStatusText(statustype, string, l);
+			}
+		});
 	}
 
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMainStatusBar()
-	public MainStatusBar getMainStatusBar() {
+	public IMainStatusBar getMainStatusBar() {
 		return mainWindow.getMainStatusBar();
 	}
 	
 	// @see com.aelitis.azureus.ui.UIFunctions#showConfig(java.lang.String)
 	public boolean showConfig(String section) {
 		try {
-			/*
-			 * Show in pop-up in Vuze UI's
-			 */
-			ConfigShell.getInstance().open(section);
+			boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+			if (uiClassic) {
+				openView(SideBar.SIDEBAR_HEADER_PLUGINS, ConfigView.class, null, section, true);
+			} else {
+				ConfigShell.getInstance().open(section);
+			}
 			return true;
 
 		} catch (Exception e) {
@@ -466,17 +405,17 @@ public class UIFunctionsImpl
 	private void _openView(int viewID, Object data) {
 		switch (viewID) {
 			case VIEW_CONSOLE:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, LoggerView.class,
+				openView(SideBar.SIDEBAR_HEADER_PLUGINS, LoggerView.class,
 						null, data, true);
 				break;
 
 			case VIEW_ALLPEERS:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, PeerSuperView.class,
+				openView(SideBar.SIDEBAR_HEADER_TRANSFERS, PeerSuperView.class,
 						null, data, true);
 				break;
 
 			case VIEW_PEERS_STATS:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, ClientStatsView.class,
+				openView(SideBar.SIDEBAR_HEADER_PLUGINS, ClientStatsView.class,
 						null, data, true);
 				break;
 
@@ -498,79 +437,125 @@ public class UIFunctionsImpl
 					}
 				}
 
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_LIBRARY, ManagerView.class,
+				openView(SideBar.SIDEBAR_HEADER_TRANSFERS, ManagerView.class,
 						id, data, true);
 				break;
 
 			case VIEW_DM_MULTI_OPTIONS:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_LIBRARY,
+				openView(SideBar.SIDEBAR_HEADER_TRANSFERS,
 						TorrentOptionsView.class, null, data, true);
 				break;
 
 			case VIEW_MYSHARES:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_LIBRARY,
+				openView(SideBar.SIDEBAR_HEADER_PLUGINS,
 						MySharesView.class, null, data, true);
 				break;
 
 			case VIEW_MYTORRENTS: {
-				SideBar sideBar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-
-				if (sideBar != null) {
-					sideBar.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				if (mdi != null) {
+					mdi.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
 				}
 			}
 				break;
 
 			case VIEW_MYTRACKER:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, MyTrackerView.class,
+				openView(SideBar.SIDEBAR_HEADER_PLUGINS, MyTrackerView.class,
 						null, data, true);
 				break;
 
-			case VIEW_STATS:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS, StatsView.class,
-						null, data, true);
-				break;
-
-			case VIEW_DETAILED_LISTVIEW:
-				mainWindow.openView(SideBar.SIDEBAR_SECTION_TOOLS,
-						DetailedListView.class, null, data, true);
-				break;
-
 			default:
 				break;
 		}
 	}
 
+	private void openView(final String parentID,
+			final Class<? extends UISWTViewEventListener> cla, String id,
+			final Object data, final boolean closeable) {
+		final MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi == null) {
+			return;
+		}
+
+		if (id == null) {
+			id = cla.getName();
+			int i = id.lastIndexOf('.');
+			if (i > 0) {
+				id = id.substring(i + 1);
+			}
+		}
+
+		UISWTViewCore viewFromID = mdi.getCoreViewFromID(id);
+		if (viewFromID != null) {
+			viewFromID.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, data);
+			mdi.showEntryByID(id);
+		}
+
+		final String _id = id;
+		Utils.execSWTThreadLater(0, new AERunnable() {
 
+			public void runSupport() {
+				if (mdi.showEntryByID(_id)) {
+					return;
+				}
+				UISWTViewEventListener l = null;
+				try {
+					Constructor<?> constructor = cla.getConstructor(new Class[] {
+						data.getClass()
+					});
+					l = (UISWTViewEventListener) constructor.newInstance(new Object[] {
+						data
+					});
+				} catch (Exception e) {
+				}
+
+				try {
+					if (l == null) {
+						l = cla.newInstance();
+					}
+					mdi.createEntryFromEventListener(parentID, l, _id, closeable,
+							data);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+				mdi.showEntryByID(_id);
+			}
+		});
+
+	}
 	public UISWTInstance getUISWTInstance() {
 		return mainWindow.getUISWTInstanceImpl();
 	}
 	
 	// @see com.aelitis.azureus.ui.UIFunctions#viewURL(java.lang.String, java.lang.String, java.lang.String)
 	public void viewURL(String url, String target, String sourceRef) {
-		ContentNetworkUtils.setSourceRef(target, sourceRef, false);
 		viewURL(url, target, 0, 0, true, false);
 	}
 
 	public boolean viewURL(final String url, final String target, final int w,
 			final int h, final boolean allowResize, final boolean isModal) {
 
-		mainWindow.shell.getDisplay().syncExec(new AERunnable() {
+		 mainWindow.getShell().getDisplay().syncExec(new AERunnable() {
 			public void runSupport() {
 				String realURL = url;
 				ContentNetwork cn = ContentNetworkUtils.getContentNetworkFromTarget(target);
-				if ( !realURL.startsWith( "http" )){
-					realURL = cn.getSiteRelativeURL(realURL, false );
+				if ( !realURL.startsWith( "http" )
+					&& !realURL.startsWith("#")) {
+					if ("_blank".equals(target)) {
+						realURL = cn.getExternalSiteRelativeURL(realURL, false );
+					} else {
+						realURL = cn.getSiteRelativeURL(realURL, false );
+					}
 				}
 				if (target == null) {
 					if (UrlFilter.getInstance().urlCanRPC(realURL)) {
 						realURL = cn.appendURLSuffix(realURL, false, true);
 					}
-					BrowserWindow window = new BrowserWindow(mainWindow.shell, realURL,
+					BrowserWindow window = new BrowserWindow( mainWindow.getShell(), realURL,
 							w, h, allowResize, isModal);
 					window.waitUntilClosed();
 				} else {
-					mainWindow.showURL(realURL, target);
+					showURL(realURL, target);
 				}
 			}
 		});
@@ -580,53 +565,99 @@ public class UIFunctionsImpl
 	public boolean viewURL(final String url, final String target, final double w,
 			final double h, final boolean allowResize, final boolean isModal) {
 
-		mainWindow.shell.getDisplay().syncExec(new AERunnable() {
+		 mainWindow.getShell().getDisplay().syncExec(new AERunnable() {
 			public void runSupport() {
 				String realURL = url;
 				ContentNetwork cn = ContentNetworkUtils.getContentNetworkFromTarget(target);
 				if ( !realURL.startsWith( "http" )){
-					realURL = cn.getSiteRelativeURL(realURL, false );
+					if ("_blank".equals(target)) {
+						realURL = cn.getExternalSiteRelativeURL(realURL, false );
+					} else {
+						realURL = cn.getSiteRelativeURL(realURL, false );
+					}
 				}
 				if (target == null) {
 					if (UrlFilter.getInstance().urlCanRPC(realURL)) {
 						realURL = cn.appendURLSuffix(realURL, false, true);
 					}
-					BrowserWindow window = new BrowserWindow(mainWindow.shell, realURL,
+					BrowserWindow window = new BrowserWindow( mainWindow.getShell(), realURL,
 							w, h, allowResize, isModal);
 					window.waitUntilClosed();
 				} else {
-					mainWindow.showURL(realURL, target);
+					showURL(realURL, target);
 				}
 			}
 		});
 		return true;
 	}
 
-	public void oldMainWindowInitialized(MainWindow oldMainWindow) {
-		UIFunctionsSWT uiFunctions = oldMainWindow.getUIFunctions();
-		if (uiFunctions == null) {
+	/**
+	 * @param url
+	 * @param target
+	 */
+	
+	private void showURL(final String url, String target) {
+
+		if ("_blank".equalsIgnoreCase(target)) {
+			Utils.launch(url);
 			return;
 		}
 
-		pluginViews_mon.enter();
-		try {
-			for (Iterator iterator = mapPluginViews.keySet().iterator(); iterator.hasNext();) {
-				Object key = iterator.next();
-				if (key instanceof PluginView) {
-					uiFunctions.addPluginView((PluginView) key);
-				} else if (key instanceof UISWTPluginView) {
-					uiFunctions.addPluginView((UISWTPluginView) key);
-				} else if (key instanceof String) {
-					UISWTViewEventListener value = (UISWTViewEventListener) mapPluginViews.get(key);
-					uiFunctions.addPluginView((String) key, value);
+		if (target.startsWith("tab-")) {
+			target = target.substring(4);
+		}
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+		if (MultipleDocumentInterface.SIDEBAR_SECTION_PLUS.equals(target)) {
+			SBC_PlusFTUX.setSourceRef(url.substring(1));
+			mdi.showEntryByID(target);
+			return;
+		}
+		
+		// Note; We don't setSourceRef on ContentNetwork here like we do
+		// everywhere else because the source ref should already be set
+		// by the caller
+		if (mdi == null || !mdi.showEntryByID(target)) {
+			Utils.launch(url);
+			return;
+		}
+
+		MdiEntry entry = mdi.getEntry(target);
+		entry.addListener(new MdiEntryOpenListener() {
+
+			public void mdiEntryOpen(MdiEntry entry) {
+				entry.removeListener(this);
+
+				mainWindow.setVisible( true, true );
+
+				if (!(entry instanceof SideBarEntrySWT)) {
+					return;
+				}
+				SideBarEntrySWT entrySWT = (SideBarEntrySWT) entry;
+
+				SWTSkinObjectBrowser soBrowser = SWTSkinUtils.findBrowserSO(entrySWT.getSkinObject());
+
+				if (soBrowser != null) {
+					//((SWTSkinObjectBrowser) skinObject).getBrowser().setVisible(false);
+					if (url == null || url.length() == 0) {
+						soBrowser.restart();
+					} else {
+						String fullURL = url;
+						if (UrlFilter.getInstance().urlCanRPC(url)) {
+							// 4010 Tux: This shouldn't be.. either determine ContentNetwork from
+							//           url or target, or do something..
+							fullURL = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(
+									url, false, true);
+						}
+
+						soBrowser.setURL(fullURL);
+					}
 				}
 			}
-			mapPluginViews.clear();
-		} finally {
-			pluginViews_mon.exit();
-		}
+		});
 	}
-
+	
 	// @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 void promptUser(String title, String text, String[] buttons,
 			int defaultOption, String rememberID, String rememberText,
@@ -685,14 +716,15 @@ public class UIFunctionsImpl
 						DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
 
 						final DownloadManager[] dm_final = dms;
-						final TableViewSWT tv_final = null;
 						final boolean detailed_view_final = false;
 						if (null == dm_final) {
 							torrentItem.setEnabled(false);
 						} else {
-							torrentItem.setData("downloads", dm_final);
-							torrentItem.setData("TableView", tv_final);
-							torrentItem.setData("is_detailed_view",
+							TableView<?> tv = SelectedContentManager.getCurrentlySelectedTableView();
+
+							torrentItem.getMenu().setData("TableView", tv);
+							torrentItem.getMenu().setData("downloads", dm_final);
+							torrentItem.getMenu().setData("is_detailed_view",
 									Boolean.valueOf(detailed_view_final));
 							torrentItem.setEnabled(true);
 						}
@@ -706,7 +738,14 @@ public class UIFunctionsImpl
 	}
 
 	public IMainMenu createMainMenu(Shell shell) {
-		return new MainMenu(getSkin(), shell);
+		IMainMenu menu;
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+		if (uiClassic) {
+			menu = new org.gudy.azureus2.ui.swt.mainwindow.MainMenu(shell);
+		} else {
+			menu = new MainMenu(skin, shell);
+		}
+		return menu;
 	}
 
 	public SWTSkin getSkin() {
@@ -728,16 +767,16 @@ public class UIFunctionsImpl
 	
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closeAllDetails()
 	public void closeAllDetails() {
-		SkinView sideBarView = SkinViewManager.getByClass(SideBar.class);
-		if (sideBarView instanceof SideBar) {
-			SideBar sideBar = (SideBar) sideBarView;
-			SideBarEntry[] sideBarEntries = sideBar.getEntries();
-			for (int i = 0; i < sideBarEntries.length; i++) {
-				SideBarEntry entry = sideBarEntries[i];
-				String id = entry.getId();
-				if (id != null && id.startsWith("DMDetails_")) {
-					sideBar.closeEntry(id);
-				}
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return;
+		}
+		MdiEntry[] sideBarEntries = mdi.getEntries();
+		for (int i = 0; i < sideBarEntries.length; i++) {
+			MdiEntry entry = sideBarEntries[i];
+			String id = entry.getId();
+			if (id != null && id.startsWith("DMDetails_")) {
+				mdi.closeEntry(id);
 			}
 		}
 
@@ -745,16 +784,17 @@ public class UIFunctionsImpl
 	
 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#hasDetailViews()
 	public boolean hasDetailViews() {
-		SkinView sideBarView = SkinViewManager.getByClass(SideBar.class);
-		if (sideBarView instanceof SideBar) {
-			SideBar sideBar = (SideBar) sideBarView;
-			SideBarEntry[] sideBarEntries = sideBar.getEntries();
-			for (int i = 0; i < sideBarEntries.length; i++) {
-				SideBarEntry entry = sideBarEntries[i];
-				String id = entry.getId();
-				if (id != null && id.startsWith("DMDetails_")) {
-					return true;
-				}
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return false;
+		}
+
+		MdiEntry[] sideBarEntries = mdi.getEntries();
+		for (int i = 0; i < sideBarEntries.length; i++) {
+			MdiEntry entry = sideBarEntries[i];
+			String id = entry.getId();
+			if (id != null && id.startsWith("DMDetails_")) {
+				return true;
 			}
 		}
 
@@ -763,14 +803,54 @@ public class UIFunctionsImpl
 	
 	public void 
 	performAction(
-		int 			action_id, 
-		Object 			args, 
-		actionListener 	listener )
+		int 					action_id, 
+		Object 					args, 
+		final actionListener 	listener )
 	{
 		if ( action_id == ACTION_FULL_UPDATE ){
 			
 			FullUpdateWindow.handleUpdate((String)args, listener );
 			
+		}else if ( action_id == ACTION_UPDATE_RESTART_REQUEST ){
+			
+			String MSG_PREFIX = "UpdateMonitor.messagebox.";
+			
+			String title = MessageText.getString(MSG_PREFIX + "restart.title" );
+			
+			String text = MessageText.getString(MSG_PREFIX + "restart.text" );
+			
+			bringToFront();
+			
+			boolean no_timeout = args instanceof Boolean && ((Boolean)args).booleanValue();
+			
+			int timeout = 180000;
+			
+			if ( no_timeout || !PluginInitializer.getDefaultInterface().getPluginManager().isSilentRestartEnabled()){
+				
+				timeout = -1;
+			}
+			
+			promptUser(
+				title, 
+				text, 
+				new String[] {
+					MessageText.getString("UpdateWindow.restart"),
+					MessageText.getString("UpdateWindow.restartLater")
+				}, 
+				0, 
+				null, 
+				null, 
+				false, 
+				timeout, 
+				new UserPrompterResultListener() 
+				{
+					public void 
+					prompterClosed(
+						int result ) 
+					{
+						listener.actionComplete( result == 0 );
+					}
+				});
 		}else{
 			
 			Debug.out( "Unknown action " + action_id );
@@ -808,7 +888,6 @@ public class UIFunctionsImpl
 			});
 		}
 		
-		AzureusCore core = AzureusCoreFactory.getSingleton();
 		if (!AzureusCoreFactory.isCoreRunning()) {
 			final Initializer initializer = Initializer.getLastInitializer();
 			if (initializer != null) {
@@ -855,8 +934,143 @@ public class UIFunctionsImpl
 		return closeDialog.getShell();
 	}
 	
-	// @see com.aelitis.azureus.ui.UIFunctions#doSearch(java.lang.String)
-	public void doSearch(String searchText) {
-		mainWindow.doSearch(searchText);
+	/**
+	 * @param searchText
+	 */
+	//TODO : Tux Move to utils? Could you also add a "mode" or something that would be added to the url
+	// eg: &subscribe_mode=true
+	public void doSearch(final String sSearchText) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				doSearch(sSearchText, false);
+			}
+		});
+	}
+
+	public void doSearch(String sSearchText, boolean toSubscribe) {
+		String sDefault = MessageText.getString("v3.MainWindow.search.defaultText");
+		if (sSearchText.equals(sDefault) || sSearchText.length() == 0) {
+			return;
+		}
+
+		if ( checkForSpecialSearchTerm( sSearchText )){
+			
+			return;
+		}
+		
+		SearchResultsTabArea.SearchQuery sq = new SearchResultsTabArea.SearchQuery(
+				sSearchText, toSubscribe);
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		String id = "Search";
+		MdiEntry existingEntry = mdi.getEntry(id);
+		if (existingEntry != null && existingEntry.isAdded()) {
+			SearchResultsTabArea searchClass = (SearchResultsTabArea) SkinViewManager.getByClass(SearchResultsTabArea.class);
+			if (searchClass != null) {
+				searchClass.anotherSearch(sSearchText, toSubscribe);
+			}
+			mdi.showEntry(existingEntry);
+			return;
+		}
+
+		final MdiEntry entry = mdi.createEntryFromSkinRef(
+				MultipleDocumentInterface.SIDEBAR_HEADER_VUZE, id,
+				"main.area.searchresultstab", sSearchText, null, sq, true, null);
+		if (entry != null) {
+			entry.setImageLeftID("image.sidebar.search");
+			entry.setDatasource(sq);
+			entry.setViewTitleInfo(new ViewTitleInfo() {
+				public Object getTitleInfoProperty(int propertyID) {
+					if (propertyID == TITLE_TEXT) {
+						SearchResultsTabArea searchClass = (SearchResultsTabArea) SkinViewManager.getByClass(SearchResultsTabArea.class);
+						if (searchClass != null && searchClass.sq != null) {
+							return searchClass.sq.term;
+						}
+					}
+					return null;
+				}
+			});
+		}
+		mdi.showEntryByID(id);
+	}
+	
+	private static boolean
+	checkForSpecialSearchTerm(
+		String		str )
+	{
+		str = str.trim();
+		
+		String hit = UrlUtils.parseTextForURL( str, true, true );
+		
+		if ( hit == null ){
+			
+			return( false );
+		}
+		
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		
+		new FileDownloadWindow( uiFunctions.getMainShell(), str, null, null, true );
+			
+		return( true );
+	}
+
+	
+	public void promptForSearch() {
+		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow("Button.search", "search.dialog.text");
+		entryWindow.prompt(new UIInputReceiverListener() {
+			public void UIInputReceiverClosed(UIInputReceiver receiver) {
+				if (receiver.hasSubmittedInput()) {
+					doSearch(receiver.getSubmittedInput());
+				}
+			}
+		});
+	}
+
+	public MultipleDocumentInterface getMDI() {
+		return (MultipleDocumentInterface) SkinViewManager.getByViewID(SkinConstants.VIEWID_MDI);
+	}
+
+	public MultipleDocumentInterfaceSWT getMDISWT() {
+		return (MultipleDocumentInterfaceSWT) SkinViewManager.getByViewID(SkinConstants.VIEWID_MDI);
+	}
+
+	public void forceNotify(final int iconID, final String title, final String text,
+			final String details, final Object[] relatedObjects, final int timeoutSecs) {
+		
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int swtIconID = SWT.ICON_INFORMATION;
+				switch (iconID) {
+					case STATUSICON_WARNING:
+						swtIconID = SWT.ICON_WARNING;
+						break;
+						
+					case STATUSICON_ERROR:
+						swtIconID = SWT.ICON_ERROR;
+						break;
+				}
+				
+				new MessageSlideShell(SWTThread.getInstance().getDisplay(), swtIconID,
+						title, text, details, relatedObjects, timeoutSecs);
+				
+			}
+		});
+	}
+	
+	public void 
+	installPlugin(
+		String 				plugin_id,
+		String				resource_prefix,
+		actionListener		listener )
+	{
+		new SimplePluginInstaller( plugin_id, resource_prefix, listener );
+	}
+
+	public UIToolBarManager getToolBarManager() {
+		Object tb = SkinViewManager.getByClass(ToolBarView.class);
+		if (tb instanceof UIToolBarManager) {
+			return (UIToolBarManager) tb;
+		}
+		return null;
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java b/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
index ca885e4..69af270 100644
--- a/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
+++ b/com/aelitis/azureus/ui/swt/shells/uiswitcher/UISwitcherWindow.java
@@ -20,7 +20,6 @@
 
 package com.aelitis.azureus.ui.swt.shells.uiswitcher;
 
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,13 +46,6 @@ public class UISwitcherWindow
 {
 	private static String CFG_PREFIX = "window.uiswitcher.";
 
-	private static String RESOURCE_LOC = "com/aelitis/azureus/ui/swt/shells/uiswitcher/images/";
-
-	private static String[] IMAGES = {
-		"NewUI_130.jpg",
-		"ClassicUI_130.jpg"
-	};
-
 	private static String[] IDS = {
 		"NewUI",
 		"ClassicUI"
@@ -65,28 +57,27 @@ public class UISwitcherWindow
 
 	private int ui = -1;
 
-	private List disposeList = new ArrayList();
+	private List<Object> disposeList = new ArrayList<Object>();
 
 	public UISwitcherWindow() {
-		// XXX forcing to allowCancel is temporary
-		this(null, true);
+		this(false, true);
 	}
 
 	/**
 	 * 
 	 */
-	public UISwitcherWindow(Shell parentShell, final boolean allowCancel) {
+	public UISwitcherWindow(boolean standalone, final boolean allowCancel) {
 		final String originalUIMode = UISwitcherUtil.calcUIMode();
 		try {
-			final Image[] images = new Image[IMAGES.length];
-			final Button[] buttons = new Button[IMAGES.length];
+			final Button[] buttons = new Button[IDS.length];
 			GridData gd;
 
 			int style = SWT.BORDER | SWT.TITLE | SWT.RESIZE;
 			if (allowCancel) {
 				style |= SWT.CLOSE;
 			}
-			shell = ShellFactory.createShell(parentShell, style);
+			shell = standalone ? new Shell(Display.getDefault(), style)
+					: ShellFactory.createShell((Shell) null, style);
 			shell.setText(MessageText.getString(CFG_PREFIX + "title"));
 			Utils.setShellIcon(shell);
 
@@ -107,10 +98,6 @@ public class UISwitcherWindow
 				}
 			});
 
-			Display display = shell.getDisplay();
-
-			ClassLoader cl = UISwitcherWindow.class.getClassLoader();
-
 			GridLayout layout = new GridLayout();
 			layout.horizontalSpacing = 0;
 			layout.marginWidth = 5;
@@ -139,7 +126,7 @@ public class UISwitcherWindow
 					for (int i = 0; i < buttons.length; i++) {
 						boolean selected = idx == i;
 						Composite c = buttons[i].getParent();
-						c.getParent().setBackground(
+						c.setBackground(
 								selected ? c.getDisplay().getSystemColor(
 										SWT.COLOR_LIST_SELECTION) : null);
 						Color fg = selected ? c.getDisplay().getSystemColor(
@@ -161,15 +148,18 @@ public class UISwitcherWindow
 			final Font headerFont = new Font(shell.getDisplay(), fontData);
 			disposeList.add(headerFont);
 
-			for (int i = 0; i < IMAGES.length; i++) {
-				String id = IMAGES[i];
+			Composite cCenter = new Composite(shell, SWT.NONE);
+			cCenter.setLayout(new GridLayout());
+			cCenter.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+			
+			for (int i = 0; i < IDS.length; i++) {
 
-				final Composite c = new Composite(shell, SWT.NONE);
+				final Composite c = new Composite(cCenter, SWT.NONE);
 				c.setBackgroundMode(SWT.INHERIT_DEFAULT);
-				gd = new GridData(GridData.FILL_BOTH);
+				gd = new GridData(GridData.FILL_HORIZONTAL);
 				gd.verticalIndent = 0;
 				c.setLayoutData(gd);
-				GridLayout gridLayout = new GridLayout(2, false);
+				GridLayout gridLayout = new GridLayout(1, false);
 				gridLayout.horizontalSpacing = 0;
 				gridLayout.marginWidth = 5;
 				gridLayout.marginHeight = 3;
@@ -179,27 +169,7 @@ public class UISwitcherWindow
 
 				c.addListener(SWT.MouseDown, radioListener);
 
-				Label label = new Label(c, SWT.CENTER);
-				label.addListener(SWT.MouseDown, radioListener);
-
-				try {
-					InputStream is = cl.getResourceAsStream(RESOURCE_LOC + id);
-					if (is != null) {
-						images[i] = new Image(display, is);
-						label.setImage(images[i]);
-						disposeList.add(images[i]);
-					}
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
-
-				Composite c2 = new Composite(c, SWT.NONE);
-				c2.setBackgroundMode(SWT.INHERIT_FORCE);
-				c2.setData("INDEX", new Long(i));
-				c2.setLayout(new GridLayout());
-				c2.setLayoutData(new GridData(GridData.FILL_BOTH));
-
-				buttons[i] = new Button(c2, SWT.RADIO);
+				buttons[i] = new Button(c, SWT.RADIO);
 				buttons[i].setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
 				Messages.setLanguageText(buttons[i], CFG_PREFIX + IDS[i] + ".title");
 				buttons[i].setData("INDEX", new Long(i));
@@ -247,9 +217,10 @@ public class UISwitcherWindow
 					}
 				});
 
-				Label info = new Label(c2, SWT.WRAP);
+				Label info = new Label(c, SWT.WRAP);
 				gd = new GridData(GridData.FILL_BOTH);
 				gd.horizontalIndent = 20;
+				gd.verticalAlignment = SWT.TOP;
 				info.setLayoutData(gd);
 
 				Messages.setLanguageText(info, CFG_PREFIX + IDS[i] + ".text");
@@ -261,20 +232,12 @@ public class UISwitcherWindow
 			radioListener.handleEvent(eventSelectFirst);
 			
 			Composite cBottom = new Composite(shell, SWT.NONE);
-			layout = new GridLayout(2, false);
+			layout = new GridLayout(1, false);
 			layout.marginHeight = 0;
 			layout.marginWidth = 0;
 			cBottom.setLayout(layout);
-			cBottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+			cBottom.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
 			
-			Label lblBottom = new Label(cBottom, SWT.WRAP);
-			Messages.setLanguageText(lblBottom, "window.uiswitcher.bottom.text");
-			gd = Utils.getWrappableLabelGridData(1,
-					GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
-			gd.horizontalIndent = 10;
-			lblBottom.setLayoutData(gd);
-			
-
 			btnOk = new Button(cBottom, SWT.PUSH);
 			Messages.setLanguageText(btnOk, "Button.ok");
 			shell.setDefaultButton(btnOk);
@@ -290,10 +253,20 @@ public class UISwitcherWindow
 				}
 			});
 			gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
-			gd.widthHint = 80;
 			btnOk.setLayoutData(gd);
+			
+			shell.addTraverseListener(new TraverseListener() {
+				public void keyTraversed(TraverseEvent e) {
+					if (e.detail == SWT.TRAVERSE_ESCAPE) {
+						shell.dispose();
+						e.doit = false;
+						return;
+					}
+					e.doit = true;
+				}
+			});
 
-			Point point = shell.computeSize(630, SWT.DEFAULT);
+			Point point = shell.computeSize(400, SWT.DEFAULT);
 			shell.setSize(point);
 			
 			Utils.centreWindow(shell);
@@ -308,7 +281,8 @@ public class UISwitcherWindow
 
 	public static void main(String[] args) {
 		Display display = Display.getDefault();
-		UISwitcherWindow window = new UISwitcherWindow(null, false);
+		UISwitcherWindow window = new UISwitcherWindow(true, true);
+		window.open();
 		Shell shell = window.shell;
 		while (!shell.isDisposed()) {
 			if (!shell.getDisplay().readAndDispatch()) {
diff --git a/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/ClassicUI_130.jpg b/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/ClassicUI_130.jpg
deleted file mode 100644
index 58c55a2..0000000
Binary files a/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/ClassicUI_130.jpg and /dev/null differ
diff --git a/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/NewUI_130.jpg b/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/NewUI_130.jpg
deleted file mode 100644
index f1b2357..0000000
Binary files a/com/aelitis/azureus/ui/swt/shells/uiswitcher/images/NewUI_130.jpg and /dev/null differ
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTColorWithAlpha.java b/com/aelitis/azureus/ui/swt/skin/SWTColorWithAlpha.java
new file mode 100644
index 0000000..995846d
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTColorWithAlpha.java
@@ -0,0 +1,32 @@
+/**
+ * Created on Jun 23, 2010
+ *
+ * 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.skin;
+
+import org.eclipse.swt.graphics.Color;
+
+public class SWTColorWithAlpha {
+	Color color;
+	int alpha;
+
+	public SWTColorWithAlpha(Color color, int alpha) {
+		super();
+		this.color = color;
+		this.alpha = alpha;
+	}
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkin.java b/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
index 7cde2b2..36ebdcb 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkin.java
@@ -51,12 +51,25 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
  */
 public class SWTSkin
 {
+	public static final boolean DEBUG_VISIBILITIES = false;
+
 	private static final SWTSkinObjectListener[] NOLISTENERS = new SWTSkinObjectListener[0];
 
-	static boolean DEBUGLAYOUT = System.getProperty("debuglayout") != null;
+	private static SWTSkin default_instance;
+	
+	protected static synchronized SWTSkin
+	getDefaultInstance()
+	{
+		if ( default_instance == null ){
+			
+			default_instance = new SWTSkin();
+		}
+		
+		return( default_instance );
+	}
+	
+	public boolean DEBUGLAYOUT = System.getProperty("debuglayout") != null;
 	
-	private static int numSkins = 0;
-
 	private Map<SkinProperties, ImageLoader> mapImageLoaders = new ConcurrentHashMap<SkinProperties, ImageLoader>();
 
 	private SWTSkinProperties skinProperties;
@@ -91,34 +104,32 @@ public class SWTSkin
 
 	private CopyOnWriteList<SWTSkinLayoutCompleteListener> listenersLayoutComplete = new CopyOnWriteList<SWTSkinLayoutCompleteListener>();
 
-	private boolean ourSkinProperties = false;
-
 	private int currentSkinObjectcreationCount = 0;
 
 	private ImageLoader imageLoader;
 
 	private String startID;
+	
+	private boolean autoSizeOnLayout = true;
 
 	/**
 	 * 
 	 */
-	public SWTSkin() {
-		ourSkinProperties = true;
-		init(new SWTSkinPropertiesImpl());
+	protected SWTSkin() {
+		init(new SWTSkinPropertiesImpl(), true );
 	}
 
-	public SWTSkin(ClassLoader classLoader, String skinPath, String mainSkinFile) {
-		ourSkinProperties = true;
-		init(new SWTSkinPropertiesImpl(classLoader, skinPath, mainSkinFile));
+	protected SWTSkin(ClassLoader classLoader, String skinPath, String mainSkinFile) {
+		init(new SWTSkinPropertiesImpl(classLoader, skinPath, mainSkinFile), false );
 	}
 
-	private void init(SWTSkinProperties skinProperties) {
-		numSkins++;
+	private void init(SWTSkinProperties skinProperties, boolean is_default) {
+	
 		this.skinProperties = skinProperties;
-		// the first skin gets the default image loader.  We don't add it to
+		// the default skin gets the default image loader.  We don't add it to
 		// the mapImageLoaders because non-skin objects may use the image loader
 		// mapImageLoaders is used to dispose of images when the skin is disposed
-		if (numSkins == 1) {
+		if ( is_default ) {
 			imageLoader = ImageLoader.getInstance();
 			imageLoader.addSkinProperties(skinProperties);
 		} else {
@@ -320,12 +331,6 @@ public class SWTSkin
 	public SWTSkinObject getSkinObject(String sViewID) {
 		SWTSkinObject[] objects = mapPublicViewIDsToSOs.get(sViewID);
 		if (objects == null || objects.length == 0) {
-			if (!Utils.isThisThreadSWT()) {
-				Debug.out("View "
-						+ sViewID
-						+ " does not exist.  Skipping unattach check because not in SWT thread");
-				return null;
-			}
 			return createUnattachedView(sViewID, null);
 		}
 
@@ -342,8 +347,14 @@ public class SWTSkin
 		String unattachedView = skinProperties.getStringValue("UnattachedView."
 				+ viewID);
 		if (unattachedView != null) {
+			if (!Utils.isThisThreadSWT()) {
+				Debug.out("View "
+						+ viewID
+						+ " does not exist.  Skipping unattach check because not in SWT thread");
+				return null;
+			}
 			if (unattachedView.indexOf(',') > 0) {
-				String[] split = unattachedView.split(",");
+				String[] split = Constants.PAT_SPLIT_COMMA.split(unattachedView);
 				String parentID = split[1];
 				SWTSkinObject soParent = getSkinObjectByID(parentID, parent);
 				if (soParent != null) {
@@ -582,6 +593,8 @@ public class SWTSkin
 			shell.setSize(width, height);
 		}
 		
+		// We handle cases where width || height < 0 later in layout()
+		
 		String title = skinProperties.getStringValue(startID + ".title",
 				(String) null);
 		if (title != null) {
@@ -615,14 +628,10 @@ public class SWTSkin
 	 * @since 4.0.0.5
 	 */
 	private void disposeSkin() {
-		numSkins--;
 		for (Iterator<ImageLoader> iter = mapImageLoaders.values().iterator(); iter.hasNext();) {
 			ImageLoader loader = iter.next();
 			loader.unLoadImages();
 		}
-		if (ourSkinProperties) {
-			//skinProperties.dispose();
-		}
 	}
 
 	/**
@@ -644,6 +653,21 @@ public class SWTSkin
 		}
 	}
 	*/
+	
+	public void layout(SWTSkinObject soStart) {
+		if (soStart instanceof SWTSkinObjectContainer) {
+			SWTSkinObjectContainer soContainer = (SWTSkinObjectContainer) soStart;
+			SWTSkinObject[] children = soContainer.getChildren();
+			for (SWTSkinObject so : children) {
+				layout(so);
+			}
+		}
+	
+		if (DEBUGLAYOUT) {
+			System.out.println("attachControl " + soStart.toString());
+		}
+		attachControl(soStart);
+	}
 
 	public void layout() {
 		if (DEBUGLAYOUT) {
@@ -667,15 +691,32 @@ public class SWTSkin
 		// Disabled due to Browser flickering
 		//addPaintListenerToAll(shell);
 
+		if (DEBUGLAYOUT) {
+			System.out.println("====  Applied Layout");
+		}
 		bLayoutComplete = true;
 
 		int width = skinProperties.getIntValue(startID + ".width", -1);
 		int height = skinProperties.getIntValue(startID + ".height", -1);
-		if (width > 0 && height <= 0) {
-			shell.pack();
-			shell.setSize(shell.computeSize(width, SWT.DEFAULT));
+		if (autoSizeOnLayout) {
+  		if (width > 0 && height == -1) {
+  			Point computeSize = shell.computeSize(width, SWT.DEFAULT);
+  			shell.setSize(computeSize);
+  		} else if (height > 0 && width == -1) {
+  			Point computeSize = shell.computeSize(SWT.DEFAULT, height);
+  			shell.setSize(computeSize);
+  		}
+		} else {
+			Point size = shell.getSize();
+			if (width > 0) {
+				size.x = width;
+			}
+			if (height > 0) {
+				size.y = height;
+			}
+			shell.setSize(size);
 		}
-		
+
 		for (SWTSkinLayoutCompleteListener l : listenersLayoutComplete) {
 			l.skinLayoutCompleted();
 		}
@@ -736,6 +777,8 @@ public class SWTSkin
 		if (templateID == null) {
 			//templateID = skinObject.getSkinObjectID();
 		}
+		
+		boolean debugControl = controlToLayout.getData("DEBUG") != null;
 
 		for (int i = 0; i < sDirections.length; i++) {
 			Control control = null;
@@ -861,7 +904,7 @@ public class SWTSkin
 				}
 			}
 
-			if (controlToLayout.getData("DEBUG") != null && attachment != null) {
+			if (debugControl && attachment != null) {
 				if (controlToLayout instanceof Group) {
 					Group group = (Group) controlToLayout;
 					String sValue = properties.getStringValue(prefix + suffix);
@@ -916,24 +959,31 @@ public class SWTSkin
 			}
 		}
 
-		newFormData.height = properties.getIntValue(sConfigID + ".height",
-				newFormData.height);
-		newFormData.width = properties.getIntValue(sConfigID + ".width",
-				newFormData.width);
 		if (!skinObject.getDefaultVisibility()) {
-			if (newFormData.width != 0 && newFormData.height != 0) {
-				controlToLayout.setData("oldSize", new Point(newFormData.width,
-						newFormData.height));
+			if (controlToLayout.getData("oldSize") == null) {
+    		controlToLayout.setData("oldSize", new Point(properties.getIntValue(sConfigID + ".width",
+    				SWT.DEFAULT), properties.getIntValue(sConfigID + ".height",
+    						SWT.DEFAULT)));
 			}
+//			if (newFormData.width != 0 && newFormData.height != 0) {
+//				controlToLayout.setData("oldSize", new Point(newFormData.width,
+//						newFormData.height));
+//			}
 			newFormData.width = 0;
 			newFormData.height = 0;
+		} else {
+  		newFormData.height = properties.getIntValue(sConfigID + ".height",
+  				newFormData.height);
+  		newFormData.width = properties.getIntValue(sConfigID + ".width",
+  				newFormData.width);
 		}
 		controlToLayout.setLayoutData(newFormData);
 		controlToLayout.setData("skin.layedout", "");
+		skinObject.layoutComplete();
 	}
 
 	private SWTSkinObject createContainer(final SWTSkinProperties properties,
-			String sID, final String sConfigID, SWTSkinObject parentSkinObject,
+			String sID, final String sConfigID, String[] sTypeParams, SWTSkinObject parentSkinObject,
 			boolean bForceCreate, boolean bPropogate, SWTSkinObject intoSkinObject) {
 		String[] sItems = properties.getStringArray(sConfigID + ".widgets");
 		final String[] sItemsLater = null; // properties.getStringArray(sConfigID + ".widgets-onshow");
@@ -951,7 +1001,7 @@ public class SWTSkin
 		if (skinObject == null) {
 			if (intoSkinObject == null) {
 				skinObject = new SWTSkinObjectContainer(this, properties, sID,
-						sConfigID, parentSkinObject);
+						sConfigID, sTypeParams, parentSkinObject);
 				addToControlMap(skinObject);
 			} else {
 				skinObject = intoSkinObject;
@@ -982,7 +1032,6 @@ public class SWTSkin
 						Object params) {
 					if (eventType == EVENT_SHOW) {
 						skinObject.removeListener(this);
-						bLayoutComplete = false;
 						addContainerChildren(skinObject, sItemsLater, properties);
 						layout();
 					}
@@ -991,11 +1040,6 @@ public class SWTSkin
 			});
 		}
 		
-
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1020,9 +1064,18 @@ public class SWTSkin
 			properties = new SWTSkinPropertiesParamImpl(properties, paramValues);
 		}
 
+		SWTSkinObject[] soChildren = new SWTSkinObject[sItems.length];
 		for (int i = 0; i < sItems.length; i++) {
 			String sItemID = sItems[i];
-			linkIDtoParent(properties, sItemID, sItemID, skinObject, false, true);
+			soChildren[i] = linkIDtoParent(properties, sItemID, sItemID, skinObject, false, true);
+		}
+		if (bLayoutComplete) {
+			// attach only after all children are added
+			for (SWTSkinObject so : soChildren) {
+				if (so != null) {
+					attachControl(so);
+				}
+			}
 		}
 	}
 
@@ -1085,10 +1138,6 @@ public class SWTSkin
 			}
 		}
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1099,10 +1148,6 @@ public class SWTSkin
 				sConfigID, typeParams, parentSkinObject, bVertical);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1152,7 +1197,7 @@ public class SWTSkin
 
 		SWTSkinObjectTab skinObjectTab = new SWTSkinObjectTab(this, properties,
 				sID, sConfigID, parentSkinObject);
-		createContainer(properties, sID, sConfigID, parentSkinObject, true, true,
+		createContainer(properties, sID, sConfigID, null, parentSkinObject, true, true,
 				skinObjectTab);
 
 		addToControlMap(skinObjectTab);
@@ -1172,10 +1217,6 @@ public class SWTSkin
 			System.out.println("Tab " + sID + " added");
 		}
 
-		if (bLayoutComplete) {
-			attachControl(skinObjectTab);
-		}
-
 		return skinObjectTab;
 	}
 
@@ -1186,10 +1227,6 @@ public class SWTSkin
 				sConfigID, typeParams, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1199,10 +1236,6 @@ public class SWTSkin
 				sConfigID, typeParams, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1287,25 +1320,18 @@ public class SWTSkin
 	 * @return new skin object
 	 */
 	public SWTSkinObject createSkinObject(String sID, String sConfigID,
-			SWTSkinObject parentSkinObject, Object creationParams) {
+			SWTSkinObject parentSkinObject, Object datasource) {
 		SWTSkinObject skinObject = null;
 		Cursor cursor = shell.getCursor();
 		try {
 			shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
 
-			boolean b = bLayoutComplete;
-			bLayoutComplete = false;
-
 			skinObject = linkIDtoParent(skinProperties, sID, sConfigID,
-					parentSkinObject, true, true, creationParams);
-			if (b && skinObject != null) {
-				layout();
-				Control control = skinObject.getParent().getControl();
-				if (control instanceof Composite) {
-					((Composite) control).layout(true);
-				}
-			}
-			bLayoutComplete = b;
+					parentSkinObject, true, true, datasource);
+
+			if (bLayoutComplete) {
+				layout(skinObject);
+    	}
 		} catch (Exception e) {
 			Debug.out("Trying to create " + sID + "." + sConfigID + " on "
 					+ parentSkinObject, e);
@@ -1384,7 +1410,7 @@ public class SWTSkin
 
 	private SWTSkinObject linkIDtoParent(SWTSkinProperties properties,
 			String sID, String sConfigID, SWTSkinObject parentSkinObject,
-			boolean bForceCreate, boolean bAddView, Object creationParams) {
+			boolean bForceCreate, boolean bAddView, Object datasource) {
 		currentSkinObjectcreationCount++;
 
 		SWTSkinObject skinObject = null;
@@ -1429,15 +1455,15 @@ public class SWTSkin
 			}
 
 			if (sType.equals("image")) {
-				skinObject = createImageLabel(properties, sID, sConfigID, null,
-						sTypeParams, parentSkinObject);
+				skinObject = createImageLabel(properties, sID, sConfigID, sTypeParams,
+						parentSkinObject);
 			} else if (sType.equals("image2")) {
 				skinObject = createImageLabel2(properties, sID, parentSkinObject);
 			} else if (sType.equals("container2")) {
 				skinObject = createContainer2(properties, sID, sConfigID,
 						parentSkinObject, bForceCreate, false, null);
 			} else if (sType.equals("container")) {
-				skinObject = createContainer(properties, sID, sConfigID,
+				skinObject = createContainer(properties, sID, sConfigID, sTypeParams,
 						parentSkinObject, bForceCreate, false, null);
 			} else if (sType.equals("text")) {
 				skinObject = createTextLabel(properties, sID, sConfigID, sTypeParams,
@@ -1475,11 +1501,24 @@ public class SWTSkin
 			} else if (sType.equals("checkbox")) {
 				skinObject = createCheckbox(properties, sID, sConfigID, sTypeParams,
 						parentSkinObject);
+			} else if (sType.equals("toggle")) {
+				skinObject = createToggle(properties, sID, sConfigID, sTypeParams,
+						parentSkinObject);
+			} else if (sType.equals("textbox")) {
+				skinObject = createTextbox(properties, sID, sConfigID, sTypeParams,
+						parentSkinObject);
+			} else if (sType.equals("tabfolder")) {
+				skinObject = createTabFolder(properties, sID, sConfigID, sTypeParams,
+						parentSkinObject);
 			} else {
 				System.err.println(sConfigID + ": Invalid type of " + sType);
 			}
 
-			skinObject.setData("CreationParams", creationParams);
+			skinObject.setData("CreationParams", datasource);
+			if (datasource != null) {
+				skinObject.triggerListeners(
+						SWTSkinObjectListener.EVENT_DATASOURCE_CHANGED, datasource);
+			}
 
 			if (bAddView) {
 				String sViewID = skinObject.getViewID();
@@ -1488,9 +1527,6 @@ public class SWTSkin
 				}
 			}
 
-			if (bLayoutComplete) {
-				attachControl(skinObject);
-			}
 		} catch (Exception e) {
 			e.printStackTrace();
 		} finally {
@@ -1521,10 +1557,6 @@ public class SWTSkin
 				configID, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1535,8 +1567,52 @@ public class SWTSkin
 				configID, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
+		return skinObject;
+	}
+
+	private SWTSkinObject createToggle(SWTSkinProperties properties, String id,
+			String configID, String[] typeParams, SWTSkinObject parentSkinObject) {
+
+		SWTSkinObject skinObject = new SWTSkinObjectToggle(this, properties, id,
+				configID, parentSkinObject);
+		addToControlMap(skinObject);
+
+		return skinObject;
+	}
+
+	private SWTSkinObject createTextbox(SWTSkinProperties properties, String id,
+			String configID, String[] typeParams, SWTSkinObject parentSkinObject) {
+
+		SWTSkinObject skinObject = new SWTSkinObjectTextbox(this, properties, id,
+				configID, parentSkinObject);
+		addToControlMap(skinObject);
+
+		return skinObject;
+	}
+
+	private SWTSkinObject createTabFolder(SWTSkinProperties properties, String id,
+			String configID, String[] typeParams, SWTSkinObject parentSkinObject) {
+		String[] sItems = properties.getStringArray(configID + ".widgets");
+
+		if (DEBUGLAYOUT) {
+			System.out.println("createContainer: " + id + ";"
+					+ properties.getStringValue(configID + ".widgets"));
+		}
+
+		SWTSkinObject skinObject = getSkinObjectByID(id, parentSkinObject);
+
+		if (skinObject == null) {
+			skinObject = new SWTSkinObjectTabFolder(this, properties, id,
+					configID, parentSkinObject);
+			addToControlMap(skinObject);
+		} else {
+			if (!(skinObject instanceof SWTSkinObjectContainer)) {
+				return skinObject;
+			}
+		}
+
+		if (sItems != null) {
+			addContainerChildren(skinObject, sItems, properties);
 		}
 
 		return skinObject;
@@ -1556,10 +1632,6 @@ public class SWTSkin
 				sConfigID, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1596,17 +1668,13 @@ public class SWTSkin
 	}
 
 	private SWTSkinObject createImageLabel(SWTSkinProperties properties,
-			String sID, String sConfigID, String sImageID, String[] typeParams,
+			String sID, String sConfigID, String[] typeParams,
 			SWTSkinObject parentSkinObject) {
-		if (sImageID == null) {
-			sImageID = sConfigID;
-			if (typeParams.length > 1) {
-				properties.addProperty(sConfigID + ".image", typeParams[1]);
-				sImageID = typeParams[1];
-			}
+		if (typeParams.length > 1) {
+			properties.addProperty(sConfigID + ".image", typeParams[1]);
 		}
 		SWTSkinObjectImage skinObject = new SWTSkinObjectImage(this, properties,
-				sID, sConfigID, sImageID, parentSkinObject);
+				sID, sConfigID, parentSkinObject);
 		addToControlMap(skinObject);
 
 		return skinObject;
@@ -1678,10 +1746,6 @@ public class SWTSkin
 			}
 		}
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1732,10 +1796,6 @@ public class SWTSkin
 				sID, sConfigID, parentSkinObject);
 		addToControlMap(skinObject);
 
-		if (bLayoutComplete) {
-			attachControl(skinObject);
-		}
-
 		return skinObject;
 	}
 
@@ -1839,4 +1899,12 @@ public class SWTSkin
 		}
 	}
 
+	public void setAutoSizeOnLayout(boolean autoSizeOnLayout) {
+		this.autoSizeOnLayout = autoSizeOnLayout;
+	}
+
+	public boolean isAutoSizeOnLayout() {
+		return autoSizeOnLayout;
+	}
+
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinButtonUtility.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinButtonUtility.java
index 1a49949..ef640d4 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinButtonUtility.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinButtonUtility.java
@@ -1,7 +1,6 @@
 package com.aelitis.azureus.ui.swt.skin;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
@@ -19,7 +18,7 @@ import org.gudy.azureus2.ui.swt.Utils;
  */
 public class SWTSkinButtonUtility
 {
-	ArrayList listeners = new ArrayList();
+	ArrayList<ButtonListenerAdapter> listeners = new ArrayList<ButtonListenerAdapter>();
 
 	private final SWTSkinObject skinObject;
 
@@ -31,15 +30,6 @@ public class SWTSkinButtonUtility
 				SWTSkinObject skinObject, int stateMask) {
 		}
 
-		/**
-		 * 
-		 * @param buttonUtility
-		 *
-		 * @deprecated
-		 */
-		public void pressed(SWTSkinButtonUtility buttonUtility) {
-		}
-		
 		public boolean held(SWTSkinButtonUtility buttonUtility) {
 			return false;
 		}
@@ -56,13 +46,23 @@ public class SWTSkinButtonUtility
 	public SWTSkinButtonUtility(SWTSkinObject skinObject, String imageViewID) {
 		this.skinObject = skinObject;
 		this.imageViewID = imageViewID;
-		
+
+		if (skinObject == null) {
+			Debug.out("Can't make button out of null skinObject");
+			return;
+		}
+		if (skinObject.getControl() == null) {
+			Debug.out("Can't make button out of null skinObject control");
+			return;
+		}
+
 		if (skinObject instanceof SWTSkinObjectButton) {
 			return;
 		}
-		
+
 		Listener l = new Listener() {
 			boolean bDownPressed;
+
 			private TimerEvent timerEvent;
 
 			public void handleEvent(Event event) {
@@ -79,8 +79,7 @@ public class SWTSkinButtonUtility
 										bDownPressed = false;
 
 										boolean stillPressed = true;
-										for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-											ButtonListenerAdapter l = (ButtonListenerAdapter) iter.next();
+										for (ButtonListenerAdapter l : listeners) {
 											stillPressed &= !l.held(SWTSkinButtonUtility.this);
 										}
 										bDownPressed = stillPressed;
@@ -105,9 +104,7 @@ public class SWTSkinButtonUtility
 					return;
 				}
 
-				for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-					ButtonListenerAdapter l = (ButtonListenerAdapter) iter.next();
-					l.pressed(SWTSkinButtonUtility.this);
+				for (ButtonListenerAdapter l : listeners) {
 					l.pressed(SWTSkinButtonUtility.this,
 							SWTSkinButtonUtility.this.skinObject, event.stateMask);
 				}
@@ -125,26 +122,41 @@ public class SWTSkinButtonUtility
 	}
 
 	public boolean isDisabled() {
-		return skinObject.getSuffix().indexOf("-disabled") >= 0;
+		return skinObject == null ? true : skinObject.getSuffix().indexOf(
+				"-disabled") >= 0;
 	}
 
 	private boolean inSetDisabled = false;
-	public void setDisabled(boolean disabled) {
-		if (inSetDisabled) {
+
+	private boolean lastDisabledState = false;
+
+	public void setDisabled(final boolean disabled) {
+		if (inSetDisabled || skinObject == null) {
 			return;
 		}
 		inSetDisabled = true;
 		try {
-  		if (disabled == isDisabled()) {
-  			return;
-  		}
-  		String suffix = disabled ? "-disabled" : "";
-  		skinObject.switchSuffix(suffix, 1, false);
-  
-  		for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-  			ButtonListenerAdapter l = (ButtonListenerAdapter) iter.next();
-  			l.disabledStateChanged(SWTSkinButtonUtility.this, disabled);
-  		}
+			if (disabled == isDisabled()) {
+				return;
+			}
+			if (skinObject instanceof SWTSkinObjectButton) {
+				lastDisabledState = disabled;
+				Utils.execSWTThreadLater(100, new AERunnable() {
+					public void runSupport() {
+						if (lastDisabledState == isDisabled()) {
+							return;
+						}
+						((SWTSkinObjectButton) skinObject).getControl().setEnabled(
+								!lastDisabledState);
+					}
+				});
+			}
+			String suffix = disabled ? "-disabled" : "";
+			skinObject.switchSuffix(suffix, 1, false);
+
+			for (ButtonListenerAdapter l : listeners) {
+				l.disabledStateChanged(SWTSkinButtonUtility.this, disabled);
+			}
 		} finally {
 			inSetDisabled = false;
 		}
@@ -152,7 +164,7 @@ public class SWTSkinButtonUtility
 
 	public void addSelectionListener(ButtonListenerAdapter listener) {
 		if (skinObject instanceof SWTSkinObjectButton) {
-			((SWTSkinObjectButton)skinObject).addSelectionListener(listener);
+			((SWTSkinObjectButton) skinObject).addSelectionListener(listener);
 			return;
 		}
 
@@ -167,8 +179,11 @@ public class SWTSkinButtonUtility
 	}
 
 	public void setTextID(final String id) {
+		if (skinObject == null) {
+			return;
+		}
 		if (skinObject instanceof SWTSkinObjectButton) {
-			((SWTSkinObjectButton)skinObject).setText(MessageText.getString(id));
+			((SWTSkinObjectButton) skinObject).setText(MessageText.getString(id));
 			return;
 		}
 		Utils.execSWTThreadLater(0, new AERunnable() {
@@ -189,6 +204,9 @@ public class SWTSkinButtonUtility
 	}
 
 	public void setImage(final String id) {
+		if (skinObject == null) {
+			return;
+		}
 		if (skinObject instanceof SWTSkinObjectButton) {
 			// TODO implement
 			return;
@@ -196,7 +214,8 @@ public class SWTSkinButtonUtility
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (imageViewID != null) {
-					SWTSkinObject skinImageObject = skinObject.getSkin().getSkinObject(imageViewID, skinObject);
+					SWTSkinObject skinImageObject = skinObject.getSkin().getSkinObject(
+							imageViewID, skinObject);
 					if (skinImageObject instanceof SWTSkinObjectImage) {
 						((SWTSkinObjectImage) skinImageObject).setImageByID(id, null);
 						return;
@@ -217,6 +236,9 @@ public class SWTSkinButtonUtility
 	}
 
 	public void setTooltipID(final String id) {
+		if (skinObject == null) {
+			return;
+		}
 		if (skinObject instanceof SWTSkinObjectButton) {
 			// TODO implement
 			return;
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinFactory.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinFactory.java
index 1e63b47..e58d320 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinFactory.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinFactory.java
@@ -26,21 +26,18 @@ package com.aelitis.azureus.ui.swt.skin;
  */
 public class SWTSkinFactory
 {
-	private static SWTSkin instance = null;
-
-	public static SWTSkin getInstance() {
-		if (instance == null) {
-			instance = new SWTSkin();
-		}
-		return instance;
-	}
-
-	public static void setInstance(SWTSkin skin) {
-		instance = skin;
+	public static SWTSkin 
+	getInstance() 
+	{
+		return( SWTSkin.getDefaultInstance());
 	}
 
-	public static SWTSkin getNonPersistentInstance(ClassLoader classLoader, String skinPath,
-			String mainSkinFile) {
+	public static SWTSkin 
+	getNonPersistentInstance(
+		ClassLoader classLoader, 
+		String 		skinPath,
+		String 		mainSkinFile) 
+	{
 		return new SWTSkin(classLoader, skinPath, mainSkinFile);
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObject.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObject.java
index 0c3bf76..90ebb8e 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObject.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObject.java
@@ -5,14 +5,18 @@ package com.aelitis.azureus.ui.swt.skin;
 
 import org.eclipse.swt.widgets.Control;
 
-import org.gudy.azureus2.ui.swt.debug.ObfusticateShell;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject;
+
+import com.aelitis.azureus.ui.swt.views.skin.SkinView;
 
 /**
  * @author TuxPaper
  * @created Jun 12, 2006
  *
  */
-public interface SWTSkinObject extends ObfusticateShell
+public interface SWTSkinObject
+	extends PluginUISWTSkinObject
 {
 	/**
 	 * Retrieve the associated SWT Control used by the skin object
@@ -172,4 +176,12 @@ public interface SWTSkinObject extends ObfusticateShell
 	public void setDebug(boolean b);
 	
 	public void relayout();
+
+	public void layoutComplete();
+
+	public void setObfusticatedImageGenerator(ObfusticateImage obfusticatedImageGenerator);
+
+	public SkinView getSkinView();
+
+	public void setSkinView(SkinView sv);
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectAdapter.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectAdapter.java
index a76db5a..b24f5a4 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectAdapter.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectAdapter.java
@@ -56,6 +56,10 @@ public class SWTSkinObjectAdapter
 		return null;
 	}
 
+	public Object dataSourceChanged(SWTSkinObject skinObject, Object params) {
+		return null;
+	}
+
 	/* (non-Javadoc)
 	 * @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectListener#eventOccured(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, int, java.lang.Object)
 	 */
@@ -81,6 +85,9 @@ public class SWTSkinObjectAdapter
 				case EVENT_LANGUAGE_CHANGE:
 					return updateLanguage(skinObject, params);
 
+				case EVENT_DATASOURCE_CHANGED:
+					return dataSourceChanged(skinObject, params);
+
 				default:
 					return null;
 			}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
index 8114d38..fd8ea4a 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBasic.java
@@ -13,17 +13,17 @@ import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
-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.*;
+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.debug.ObfusticateImage;
 
 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.utils.ColorCache;
 import com.aelitis.azureus.ui.swt.views.skin.SkinView;
-import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager;
 import com.aelitis.azureus.util.StringCompareUtils;
 
 /**
@@ -32,7 +32,7 @@ import com.aelitis.azureus.util.StringCompareUtils;
  *
  */
 public class SWTSkinObjectBasic
-	implements SWTSkinObject, PaintListener
+	implements SWTSkinObject, PaintListener, ObfusticateImage
 {
 	protected static final int BORDER_ROUNDED = 1;
 
@@ -59,14 +59,14 @@ public class SWTSkinObjectBasic
 
 	protected String[] suffixes = null;
 
-	protected ArrayList listeners = new ArrayList();
+	protected ArrayList<SWTSkinObjectListener> listeners = new ArrayList<SWTSkinObjectListener>();
 
 	protected AEMonitor listeners_mon = new AEMonitor(
 			"SWTSkinObjectBasic::listener");
 
 	private String sViewID;
 
-	private boolean isVisible;
+	private int isVisible = -1;
 
 	protected Color bgColor;
 
@@ -78,7 +78,7 @@ public class SWTSkinObjectBasic
 
 	private int colorFillType;
 
-	private boolean initialized = false;
+	boolean initialized = false;
 
 	boolean paintListenerHooked = false;
 
@@ -101,7 +101,15 @@ public class SWTSkinObjectBasic
 	private Listener resizeGradientBGListener;
 
 	private SkinView skinView;
-	
+
+	private Object datasource;
+
+	private boolean firstVisibility;
+
+	private boolean layoutComplete;
+
+	private ObfusticateImage obfusticatedImageGenerator;
+
 	/**
 	 * @param properties TODO
 	 * 
@@ -126,7 +134,10 @@ public class SWTSkinObjectBasic
 		setDebug(properties.getBooleanValue(sConfigID + ".debug", false));
 	}
 
-	public void setControl(final Control control) {
+	public void setControl(final Control _control) {
+		
+		firstVisibility = properties.getBooleanValue(sConfigID + ".visible", true);
+		
 		if (!Utils.isThisThreadSWT()) {
 			Debug.out("Warning: setControl not called in SWT thread for " + this);
 			Utils.execSWTThread(new AERunnable() {
@@ -181,15 +192,19 @@ public class SWTSkinObjectBasic
 					gc.dispose();
 				}
 				if (painter == null) {
+					// Use TILE_BOTH because a gradient should never set the size of the control
+					// Rather, the gradient image is made based on the control size.  If
+					// we used TILE_X, SWTBGImagePainter would force the height to the
+					// current image, thus preventing any auto-resizing
 					painter = new SWTBGImagePainter(control, null, null,
-							bgImage, SWTSkinUtils.TILE_X);
+							bgImage, SWTSkinUtils.TILE_BOTH);
 				} else {
 					painter.setImage(null, null, bgImage);
 				}
 			}
 		};
 		
-		this.control = control;
+		this.control = _control;
 		control.setData("ConfigID", sConfigID);
 		control.setData("SkinObject", this);
 
@@ -204,21 +219,27 @@ public class SWTSkinObjectBasic
 		final Listener lShowHide = new Listener() {
 			public void handleEvent(final Event event) {
 				final boolean toBeVisible = event.type == SWT.Show;
-				if (toBeVisible == control.isVisible() && isVisible == toBeVisible) {
-					return;
+				if (SWTSkin.DEBUG_VISIBILITIES) {
+					System.out.println(">>swt.show/hide " + ((event.widget).getData("SkinObject")) + ";tobe/is=" + toBeVisible + "/" + isVisible + " via " + Debug.getCompressedStackTrace());
+					//System.out.println(SWTSkinObjectBasic.this + "> swt.show/hide " + ((event.widget).getData("SkinObject")) + ";" + ((Control)event.widget).isVisible() + ";" + Debug.getCompressedStackTrace());
 				}
 
-				//System.out.println(SWTSkinObjectBasic.this + ">show/hide " + ((event.widget).getData("SkinObject")) + ";" + ((Control)event.widget).isVisible() + ";" + Debug.getCompressedStackTrace());
 				// wait until show or hide event is processed to guarantee
 				// isVisible will be correct for listener triggers
 				Utils.execSWTThreadLater(0, new AERunnable() {
 					public void runSupport() {
-						//System.out.println(">>show/hide " + ((event.widget).getData("SkinObject")) + ";" + ((Control) event.widget).isVisible());
+						if (SWTSkin.DEBUG_VISIBILITIES) {
+							//System.out.println(">>swt.show/hide " + ((event.widget).getData("SkinObject")) + ";" + ((Control) event.widget).isVisible());
+						}
 						if (control == null || control.isDisposed()) {
 							setIsVisible(false, true);
 							return;
 						}
 
+						if (toBeVisible == control.isVisible() && (isVisible == 1) == toBeVisible) {
+							return;
+						}
+
 						if (event.widget == control) {
 							setIsVisible(toBeVisible, true);
 							return;
@@ -233,7 +254,6 @@ public class SWTSkinObjectBasic
 				});
 			}
 		};
-		setIsVisible(control.isVisible(), false);
 
 		control.addListener(SWT.Show, lShowHide);
 		control.addListener(SWT.Hide, lShowHide);
@@ -256,14 +276,16 @@ public class SWTSkinObjectBasic
 				String id = getTooltipID(true);
 				if (id == null) {
 					control.setToolTipText(null);
+				} else if (id.startsWith("!") && id.endsWith("!")) {
+					control.setToolTipText(id.substring(1, id.length() - 1));
 				} else {
 					control.setToolTipText(MessageText.getString(id, (String) null));
 				}
 			}
 		});
 		
-		if (skin.isLayoutComplete()) {
-			skin.attachControl(this);
+		if (parent instanceof SWTSkinObjectContainer) {
+			((SWTSkinObjectContainer)parent).childAdded(this);
 		}
 	}
 
@@ -273,11 +295,13 @@ public class SWTSkinObjectBasic
 	 * @since 3.0.4.3
 	 */
 	protected boolean setIsVisible(boolean visible, boolean walkup) {
-		//System.out.println(this + " SET IS VISIBLE " + visible + " via " + Debug.getCompressedStackTrace());
-		if (visible == isVisible) {
+		if ((visible ? 1 : 0) == isVisible) {
 			return false;
 		}
-		isVisible = visible;
+		if (SWTSkin.DEBUG_VISIBILITIES) {
+			System.out.println(this + " SET IS VISIBLE " + visible + " via " + Debug.getCompressedStackTrace(9));
+		}
+		isVisible = visible ? 1 : 0;
 		switchSuffix(null, 0, false);
 		triggerListeners(visible ? SWTSkinObjectListener.EVENT_SHOW
 				: SWTSkinObjectListener.EVENT_HIDE);
@@ -333,24 +357,28 @@ public class SWTSkinObjectBasic
 		String s = properties.getStringValue(sConfigID + sSuffix, (String) null);
 		if (s != null && s.length() > 0) {
 			Image[] images = imageLoader.getImages(sConfigID + sSuffix);
-			if (images.length == 1 && ImageLoader.isRealImage(images[0])) {
-				id = sConfigID + sSuffix;
-				idLeft = id + "-left";
-				idRight = id + "-right";
-			} else if (images.length == 3 && ImageLoader.isRealImage(images[2])) {
-				id = sConfigID + sSuffix;
-				idLeft = id;
-				idRight = id;
-			} else if (images.length == 2 && ImageLoader.isRealImage(images[1])) {
-				id = sConfigID + sSuffix;
-				idLeft = id;
-				idRight = id + "-right";
-			} else {
-				id = sConfigID + sSuffix;
-				//if (sSuffix.length() > 0) {
-				//	setBackground(sConfigID, "");
-				//}
-				return;
+			try{
+				if (images.length == 1 && ImageLoader.isRealImage(images[0])) {
+					id = sConfigID + sSuffix;
+					idLeft = id + "-left";
+					idRight = id + "-right";
+				} else if (images.length == 3 && ImageLoader.isRealImage(images[2])) {
+					id = sConfigID + sSuffix;
+					idLeft = id;
+					idRight = id;
+				} else if (images.length == 2 && ImageLoader.isRealImage(images[1])) {
+					id = sConfigID + sSuffix;
+					idLeft = id;
+					idRight = id + "-right";
+				} else {
+					id = sConfigID + sSuffix;
+					//if (sSuffix.length() > 0) {
+					//	setBackground(sConfigID, "");
+					//}
+					return;
+				}
+			}finally{
+				imageLoader.releaseImage(sConfigID + sSuffix);
 			}
 		} else {
 			if (s != null && painter != null) {
@@ -431,15 +459,28 @@ public class SWTSkinObjectBasic
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObject#setVisible(boolean)
 	public void setVisible(final boolean visible) {
+		if (!layoutComplete) {
+			firstVisibility = visible;
+			setIsVisible(visible, true);
+			return;
+		}
+		if (SWTSkin.DEBUG_VISIBILITIES) {
+			System.out.println(this + " SET VISIBLE(" + visible + ") via "
+					+ Debug.getCompressedStackTrace());
+		}
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (control != null && !control.isDisposed()) {
+					boolean changed = visible != control.isVisible()
+							|| (visible ? 1 : 0) != isVisible;
+
 					Object ld = control.getLayoutData();
 					if (ld instanceof FormData) {
 						FormData fd = (FormData) ld;
 						if (!visible) {
-							if (fd.width != 0 && fd.height != 0) {
+							if (fd.width > 0 && fd.height > 0) {
 								control.setData("oldSize", new Point(fd.width, fd.height));
+								changed = true;
 							}
 							fd.width = 0;
 							fd.height = 0;
@@ -448,17 +489,29 @@ public class SWTSkinObjectBasic
 							Point oldSizePoint = (oldSize instanceof Point) ? (Point) oldSize
 									: new Point(SWT.DEFAULT, SWT.DEFAULT);
 							if (fd.width <= 0) {
+								changed = true;
 								fd.width = oldSizePoint.x;
 							}
 							if (fd.height <= 0) {
+								changed = true;
 								fd.height = oldSizePoint.y;
 							}
 						}
+						if (changed) {
+  						control.setLayoutData(fd);
+  						control.getParent().layout(true);
+  						Utils.relayout(control);
+						}
+					} else if (ld == null && !visible) {
+						FormData fd = new FormData();
+						fd.width = 0;
+						fd.height = 0;
 						control.setLayoutData(fd);
-						control.getParent().layout(true);
-						Utils.relayout(control);
 					}
-					control.setVisible(visible);
+					if (changed || true) { // For some reason this is required even when !changed (on Windows)
+						control.setVisible(visible);
+					}
+					// still need to call setIsVisible to walk up/down
 					setIsVisible(visible, true);
 				}
 			}
@@ -475,14 +528,17 @@ public class SWTSkinObjectBasic
 	}
 
 	public boolean getDefaultVisibility() {
-		return properties.getBooleanValue(sConfigID + ".visible", true);
+		return firstVisibility;
 	}
 
 	public boolean isVisible() {
 		if (control == null || control.isDisposed()) {
 			return false;
 		}
-		return isVisible;
+		if (!layoutComplete) {
+			return firstVisibility;
+		}
+		return isVisible == -1 ? firstVisibility : isVisible == 1;
 	}
 
 	/**
@@ -534,7 +590,7 @@ public class SWTSkinObjectBasic
 
 		if (newSuffixEntry != null) {
   		if (sConfigID == null || control == null || control.isDisposed()
-  				|| !isVisible || (newSuffixEntry != null && fullSuffix.equals(old))) {
+  				|| !isVisible() || (newSuffixEntry != null && fullSuffix.equals(old))) {
   			return fullSuffix;
   		}
 		}
@@ -558,7 +614,7 @@ public class SWTSkinObjectBasic
 					String colorStyle = properties.getStringValue(sConfigID
 							+ ".color.style" + sSuffix);
 					if (colorStyle != null) {
-						String[] split = colorStyle.split(",");
+						String[] split = Constants.PAT_SPLIT_COMMA.split(colorStyle);
 
 						if (split.length > 2) {
 							try {
@@ -582,7 +638,7 @@ public class SWTSkinObjectBasic
 							
 							Device device = Display.getDefault();
 							for (int i = 1; i < split.length; i += 2) {
-								Color colorStop = ColorCache.getColor(device, split[i]);
+								Color colorStop = ColorCache.getSchemedColor(device, split[i]);
 								double posStop = 1;
 								if (i != split.length - 1) {
 									try {
@@ -604,10 +660,8 @@ public class SWTSkinObjectBasic
 					}
 				}
 
-				if (properties.hasKey(sConfigID + ".fgcolor" + sSuffix)) {
-  				Color fg = properties.getColor(sConfigID + ".fgcolor" + sSuffix);
- 					control.setForeground(fg);
-				}
+				Color fg = getColor_SuffixWalkback(sConfigID + ".fgcolor");
+				control.setForeground(fg);
 
 				// Color,[width]
 				String sBorderStyle = properties.getStringValue(sConfigID + ".border"
@@ -615,8 +669,8 @@ public class SWTSkinObjectBasic
 				colorBorder = null;
 				colorBorderParams = null;
 				if (sBorderStyle != null) {
-					String[] split = sBorderStyle.split(",");
-					colorBorder = ColorCache.getColor(control.getDisplay(), split[0]);
+					String[] split = Constants.PAT_SPLIT_COMMA.split(sBorderStyle);
+					colorBorder = ColorCache.getSchemedColor(control.getDisplay(), split[0]);
 					needPaintHook |= colorBorder != null;
 
 					if (split.length > 2) {
@@ -707,8 +761,13 @@ public class SWTSkinObjectBasic
 			listener.eventOccured(this, SWTSkinObjectListener.EVENT_CREATED, null);
 		}
 
-		if (isVisible && initialized) {
-			Utils.execSWTThread(new AERunnable() {
+		if (datasource != null) {
+  		listener.eventOccured(SWTSkinObjectBasic.this,
+  				SWTSkinObjectListener.EVENT_DATASOURCE_CHANGED, datasource);
+		}
+
+		if (isVisible == 1 && initialized) {
+			Utils.execSWTThreadLater(0, new AERunnable() {
 				public void runSupport() {
 					listener.eventOccured(SWTSkinObjectBasic.this,
 							SWTSkinObjectListener.EVENT_SHOW, null);
@@ -730,7 +789,7 @@ public class SWTSkinObjectBasic
 	}
 
 	public SWTSkinObjectListener[] getListeners() {
-		return (SWTSkinObjectListener[]) listeners.toArray(new SWTSkinObjectListener[0]);
+		return listeners.toArray(new SWTSkinObjectListener[0]);
 	}
 
 	public void triggerListeners(int eventType) {
@@ -738,6 +797,11 @@ public class SWTSkinObjectBasic
 	}
 
 	public void triggerListeners(final int eventType, final Object params) {
+		if (SWTSkin.DEBUG_VISIBILITIES) {
+			if (eventType == SWTSkinObjectListener.EVENT_SHOW) {
+				System.out.println("Show " + this + " via " + Debug.getCompressedStackTrace());
+			}
+		}
 		// delay show and hide events while not initialized
 		if (eventType == SWTSkinObjectListener.EVENT_SHOW
 				|| eventType == SWTSkinObjectListener.EVENT_HIDE) {
@@ -746,14 +810,22 @@ public class SWTSkinObjectBasic
 				return;
 			}
 
-			if (eventType == SWTSkinObjectListener.EVENT_SHOW && !isVisible) {
+			if (eventType == SWTSkinObjectListener.EVENT_SHOW && !isVisible()) {
+				if (SWTSkin.DEBUG_VISIBILITIES) {
+					System.out.println("Warning: Show Event when not visible " + this + " via " + Debug.getCompressedStackTrace());
+				}
 				return;
-			} else if (eventType == SWTSkinObjectListener.EVENT_HIDE && isVisible) {
+			} else if (eventType == SWTSkinObjectListener.EVENT_HIDE && isVisible()) {
+				if (SWTSkin.DEBUG_VISIBILITIES) {
+					System.out.println("Warning: Hide Event when visible " + this + " via " + Debug.getCompressedStackTrace());
+				}
 				return;
 			}
 		} else if (eventType == SWTSkinObjectListener.EVENT_CREATED) {
 			//System.out.println("INITIALIZED! " + SWTSkinObjectBasic.this + ";;;" + Debug.getCompressedStackTrace());
 			initialized = true;
+		} else if (eventType == SWTSkinObjectListener.EVENT_DATASOURCE_CHANGED) {
+			datasource = params;
 		}
 		
 		// process listeners added locally
@@ -784,8 +856,8 @@ public class SWTSkinObjectBasic
   		}
 		}
 
-		if (eventType == SWTSkinObjectListener.EVENT_CREATED) {
-			triggerListeners(isVisible ? SWTSkinObjectListener.EVENT_SHOW
+		if (eventType == SWTSkinObjectListener.EVENT_CREATED && isVisible >= 0) {
+			triggerListeners(isVisible() ? SWTSkinObjectListener.EVENT_SHOW
 					: SWTSkinObjectListener.EVENT_HIDE);
 		}
 
@@ -793,9 +865,21 @@ public class SWTSkinObjectBasic
 			String initClass = properties.getStringValue(sConfigID + ".onshow.skinviewclass");
 			if (initClass != null) {
 				try {
-					Class<SkinView> cla = (Class<SkinView>) Class.forName(initClass);
+					String[] initClassItems = Constants.PAT_SPLIT_COMMA.split(initClass);
+					ClassLoader claLoader = this.getClass().getClassLoader();
+					if (initClassItems.length > 1) {
+						try {
+  						PluginInterface pi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByID(initClassItems[1]);
+  						if (pi != null) {
+  							claLoader = pi.getPluginClassLoader();
+  						}
+						} catch (Exception e) {
+							Debug.out(e);
+						}
+					}
+					Class<SkinView> cla = (Class<SkinView>) Class.forName(initClassItems[0], true, claLoader);
 
-					skinView = cla.newInstance();
+					setSkinView(cla.newInstance());
 					skinView.setMainSkinObject(this);
 					
 					// this will fire created and show for us
@@ -820,9 +904,10 @@ public class SWTSkinObjectBasic
 		if (disposed) {
 			return;
 		}
-		if (control != null && !control.isDisposed()) {
-			control.dispose();
-		}
+		Utils.disposeSWTObjects(new Object[] {
+			control
+		});
+
 		if (skinView != null) {
 			removeListener(skinView);
 
@@ -889,7 +974,10 @@ public class SWTSkinObjectBasic
 					? ((Composite) control).getClientArea() : control.getBounds();
 			if (colorFillParams != null) {
   			if (colorFillType == BORDER_ROUNDED_FILL) {
-  				e.gc.fillRoundRectangle(0, 0, bounds.width, bounds.height, colorFillParams[0], colorFillParams[1]);
+					e.gc.fillRoundRectangle(0, 0, bounds.width - 1, bounds.height - 1,
+							colorFillParams[0], colorFillParams[1]);
+					e.gc.drawRoundRectangle(0, 0, bounds.width - 1, bounds.height - 1,
+							colorFillParams[0], colorFillParams[1]);
   			} else if (colorFillType == BORDER_ROUNDED) {
   				Color oldFG = e.gc.getForeground();
   				e.gc.setForeground(bgColor);
@@ -946,9 +1034,23 @@ public class SWTSkinObjectBasic
 		mapData.put(id, data);
 	}
 
-	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateShell#generateObfusticatedImage()
-	public Image generateObfusticatedImage() {
-		return null;
+	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateImage#obfusticatedImage(org.eclipse.swt.graphics.Image, org.eclipse.swt.graphics.Point)
+	public Image obfusticatedImage(Image image) {
+		if (!isVisible()) {
+			return image;
+		}
+		Point ourOfs = Utils.getLocationRelativeToShell(control);
+		if (obfusticatedImageGenerator == null) {
+			if (skinView instanceof ObfusticateImage) {
+				return ((ObfusticateImage) skinView).obfusticatedImage(image);
+			}
+			return image;
+		}
+		return obfusticatedImageGenerator.obfusticatedImage(image);
+	}
+	
+	public void setObfusticatedImageGenerator(ObfusticateImage obfusticatedImageGenerator) {
+		this.obfusticatedImageGenerator = obfusticatedImageGenerator;
 	}
 
 	/**
@@ -981,6 +1083,15 @@ public class SWTSkinObjectBasic
 		}
 	}
 	
+	public void layoutComplete() {
+		if (!layoutComplete) {
+			layoutComplete = true;
+			if (control != null && !control.isDisposed()) {
+				control.setVisible(firstVisibility);
+			}
+		}
+	}
+	
 	class GradientInfo {
 		public Color color;
 		public double startPoint;
@@ -990,4 +1101,31 @@ public class SWTSkinObjectBasic
 			startPoint = d;
 		}
 	}
+	
+	private Color getColor_SuffixWalkback(String id) {
+		int max = suffixes == null ? 0 : suffixes.length;
+		while (max >= 0) {
+			String suffix = "";
+  		for (int i = 0; i < max; i++) {
+  			if (suffixes[i] != null) {
+  				suffix += suffixes[i];
+  			}
+  		}
+  		Color color = properties.getColor(id + suffix);
+  		if (color != null) {
+  			return color;
+  		}
+  		max--;
+		}
+		return null;
+	}
+
+	public SkinView getSkinView() {
+		return skinView;
+	}
+
+	public void setSkinView(SkinView skinView) {
+		this.skinView = skinView;
+	}
+
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
index f952a88..dde9dc3 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectBrowser.java
@@ -34,6 +34,7 @@ import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
 import com.aelitis.azureus.ui.swt.browser.listener.*;
 import com.aelitis.azureus.util.UrlFilter;
@@ -47,7 +48,7 @@ public class SWTSkinObjectBrowser
 	extends SWTSkinObjectBasic
 {
 
-	private Browser browser;
+	private BrowserWrapper browser;
 
 	private Composite cParent;
 
@@ -106,7 +107,7 @@ public class SWTSkinObjectBrowser
 		}
 
 		try {
-			browser = new Browser(cArea, Utils.getInitialBrowserStyle(SWT.NONE));
+			browser = new BrowserWrapper(cArea, Utils.getInitialBrowserStyle(SWT.NONE));
 
 			browser.setLayoutData(Utils.getFilledFormData());
 			browser.getParent().layout(true);
@@ -133,11 +134,18 @@ public class SWTSkinObjectBrowser
 		forceVisibleAfterLoad = properties.getBooleanValue(sConfigID + ".forceVisibleAfterLoad", true);
 		context = new BrowserContext(browserID, browser, widgetIndicator, forceVisibleAfterLoad);
 
-		context.addMessageListener(new TorrentListener());
-		context.addMessageListener(new VuzeListener());
-		context.addMessageListener(new DisplayListener(browser));
-		context.addMessageListener(new ConfigListener(browser));
+		boolean noListeners = properties.getBooleanValue(sConfigID + ".browser.nolisteners", false);
+		
+		if (!noListeners) {
+  		context.addMessageListener(new TorrentListener());
+  		context.addMessageListener(new VuzeListener());
+  		context.addMessageListener(new DisplayListener(browser));
+  		context.addMessageListener(new ConfigListener(browser));
+		}
 
+		boolean popouts = properties.getBooleanValue(sConfigID + ".browser.allowPopouts", true);
+		context.setAllowPopups(popouts);
+		
 		context.addListener(new loadingListener() {
 			public void browserLoadingChanged(boolean loading, String url) {
 				if (loading && browser.isVisible()) {
@@ -157,7 +165,7 @@ public class SWTSkinObjectBrowser
 		}
 	}
 
-	public Browser getBrowser() {
+	public BrowserWrapper getBrowser() {
 		if (browser == null) {
 			init();
 		}
@@ -171,6 +179,9 @@ public class SWTSkinObjectBrowser
 		}
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
+				if (browser.isDisposed()) {
+					return;
+				}
 				if (url == null) {
 					browser.setText("");
 				} else {
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectButton.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectButton.java
index b0f8710..d10a530 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectButton.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectButton.java
@@ -25,10 +25,11 @@ import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.*;
 
 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.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
@@ -44,7 +45,8 @@ public class SWTSkinObjectButton
 	extends SWTSkinObjectBasic
 {
 	private Button button;
-	private ArrayList buttonListeners = new ArrayList(1);
+	private ArrayList<ButtonListenerAdapter> buttonListeners = new ArrayList<ButtonListenerAdapter>(1);
+	private boolean textOverride;
 
 	public SWTSkinObjectButton(SWTSkin skin, final SWTSkinProperties properties,
 			String id, String configID, SWTSkinObject parentSkinObject) {
@@ -57,15 +59,31 @@ public class SWTSkinObjectButton
 			createOn = (Composite) parent.getControl();
 		}
 
+		Control c = null;
+		
+		if (Constants.isWindows) {
+			// Windows SWT Bug: button BG won't draw properly without INHERIT FORCE
+			// create a intermediate composite with forced inherit and put button
+			// in that.
+			createOn = new Composite(createOn, SWT.NONE);
+			createOn.setLayout(new FormLayout());
+			createOn.setBackgroundMode(SWT.INHERIT_FORCE);
+			c = createOn;
+		}
 
 		button = new Button(createOn, SWT.PUSH);
 		
+		if (Constants.isWindows) {
+			button.setLayoutData(Utils.getFilledFormData());
+		} else {
+			c = button;
+		}
+		
 		button.addSelectionListener(new SelectionListener() {
 			public void widgetSelected(SelectionEvent e) {
 				Object[] listeners = buttonListeners.toArray();
 				for (int i = 0; i < listeners.length; i++) {
 					ButtonListenerAdapter l = (ButtonListenerAdapter) listeners[i];
-					l.pressed(null);
 					l.pressed(null, SWTSkinObjectButton.this, e.stateMask);
 				}
 			}
@@ -73,7 +91,7 @@ public class SWTSkinObjectButton
 			public void widgetDefaultSelected(SelectionEvent e) {
 			}
 		});
-		setControl(button);
+		setControl(c);
 	}
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBasic#switchSuffix(java.lang.String, int, boolean)
@@ -87,7 +105,7 @@ public class SWTSkinObjectButton
 		String sPrefix = sConfigID + ".text";
 		String text = properties.getStringValue(sPrefix + suffix);
 		if (text != null) {
-			setText(text);
+			setText(text, true);
 		}
 		
 		return suffix;
@@ -100,12 +118,22 @@ public class SWTSkinObjectButton
 		buttonListeners.add(listener);
 	}
 
+	public void setText(final String text) {
+		setText(text, false);
+	}
+
 	/**
 	 * @param text
 	 *
 	 * @since 3.1.1.1
 	 */
-	public void setText(final String text) {
+	private void setText(final String text, boolean auto) {
+		if (!auto) {
+			textOverride = true;
+		} else if (textOverride) {
+			return;
+		}
+
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (button != null && !button.isDisposed()) {
@@ -133,4 +161,8 @@ public class SWTSkinObjectButton
 		});
 		
 	}
+	
+	public Button getButton() {
+		return button;
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectCheckbox.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectCheckbox.java
index 9bfd8bf..114d005 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectCheckbox.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectCheckbox.java
@@ -59,6 +59,10 @@ public class SWTSkinObjectCheckbox
 		} else {
 			createOn = (Composite) parent.getControl();
 		}
+		
+		// WinXP Classic Theme will not bring though parent's background image
+		// without FORCEing the background mode
+		createOn.setBackgroundMode(SWT.INHERIT_FORCE);
 
 		button = new Button(createOn, SWT.CHECK);
 		checked = false;
@@ -120,4 +124,15 @@ public class SWTSkinObjectCheckbox
 	public boolean isChecked() {
 		return checked;
 	}
+	
+	public void setChecked(boolean b) {
+		checked = b;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (button != null && !button.isDisposed()) {
+					button.setSelection(checked);
+				}
+			}
+		});
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectContainer.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectContainer.java
index c43717a..920e15e 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectContainer.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectContainer.java
@@ -22,9 +22,8 @@ package com.aelitis.azureus.ui.swt.skin;
 import java.util.ArrayList;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
@@ -34,6 +33,9 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AERunnableObject;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.CompositeMinSize;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+
 
 /**
  * A SWTSkinObject that contains other SWTSkinObjects
@@ -49,6 +51,19 @@ public class SWTSkinObjectContainer
 
 	boolean bPropogateDown = false;
 
+	private String[] sTypeParams = null;
+
+	private int minWidth;
+
+	private int minHeight;
+
+	public SWTSkinObjectContainer(SWTSkin skin, SWTSkinProperties properties,
+			String sID, String sConfigID, String[] sTypeParams, SWTSkinObject parent) {
+		super(skin, properties, sID, sConfigID, "container", parent);
+		this.sTypeParams = sTypeParams;
+		createComposite();
+	}
+
 	public SWTSkinObjectContainer(SWTSkin skin, SWTSkinProperties properties,
 			String sID, String sConfigID, SWTSkinObject parent) {
 		super(skin, properties, sID, sConfigID, "container", parent);
@@ -60,9 +75,8 @@ public class SWTSkinObjectContainer
 			SWTSkinObject parent) {
 		super(skin, properties, sID, sConfigID, type, parent);
 
-		triggerListeners(SWTSkinObjectListener.EVENT_CREATED);
-
 		if (control != null) {
+			triggerListeners(SWTSkinObjectListener.EVENT_CREATED);
 			setControl(control);
 		}
 	}
@@ -83,60 +97,31 @@ public class SWTSkinObjectContainer
 			createOn = (Composite) parent.getControl();
 		}
 
-		final int minWidth = properties.getIntValue(sConfigID + ".minwidth", -1);
+		minWidth = properties.getIntValue(sConfigID + ".minwidth", -1);
+		minHeight = properties.getIntValue(sConfigID + ".minheight", -1);
 
 		Composite parentComposite;
-		if (SWTSkin.DEBUGLAYOUT) {
+		if (skin.DEBUGLAYOUT) {
 			System.out.println("linkIDtoParent: Create Composite " + sID + " on "
 					+ createOn);
 			parentComposite = new Group(createOn, style);
 			((Group) parentComposite).setText(sConfigID == null ? sID : sConfigID);
 			parentComposite.setData("DEBUG", "1");
 		} else {
-			// Lovely SWT has a default size of 64x64 if no children have sizes.
-			// Let's fix that..
-			parentComposite = new Composite(createOn, style) {
-				// @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
-				public Point computeSize(int wHint, int hHint, boolean changed) {
-					Point size = super.computeSize(wHint, hHint, changed);
-					if (getChildren().length == 0 && (size.x == 64 || size.y == 64)) {
-						Object ld = getLayoutData();
-						if (ld instanceof FormData) {
-							FormData fd = (FormData) ld;
-							if (fd.width != 0 && fd.height != 0) {
-								Rectangle trim = computeTrim (0, 0, fd.width, fd.height);
-								return new Point(trim.width, trim.height);
-							}
-						}
-						return new Point(1, 1);
-					}
-					if (minWidth > 0 && size.x < minWidth) {
-						size.x = minWidth;
-					}
-					return size;
-				}
-				
-				// @see org.eclipse.swt.widgets.Control#computeSize(int, int)
-				public Point computeSize(int wHint, int hHint) {
-					Point size = super.computeSize(wHint, hHint);
-					if (getChildren().length == 0 && (size.x == 64 || size.y == 64)) {
-						Object ld = getLayoutData();
-						if (ld instanceof FormData) {
-							FormData fd = (FormData) ld;
-							if (fd.width != 0 && fd.height != 0) {
-								Rectangle trim = computeTrim (0, 0, fd.width, fd.height);
-								return new Point(trim.width, trim.height);
-							}
-						}
-						return new Point(1, 1);
-					}
-					if (minWidth > 0 && size.x < minWidth) {
-						size.x = minWidth;
-					}
-					return size;
-				}
-			};
+			if (sTypeParams == null || sTypeParams.length < 2
+					|| !sTypeParams[1].equalsIgnoreCase("group")) {
+  			// Lovely SWT has a default size of 64x64 if no children have sizes.
+  			// Let's fix that..
+  			parentComposite = new CompositeMinSize(createOn, style);
+  			((CompositeMinSize) parentComposite).setMinSize(new Point(minWidth, minHeight));
+			} else {
+  			parentComposite = new Group(createOn, style);
+			}
 		}
+		
+		// setting INHERIT_FORCE here would make the BG of a text box be
+		// this parent's BG (on Win7 at least)
+		//parentComposite.setBackgroundMode(SWT.INHERIT_FORCE);
 
 		parentComposite.setLayout(new FormLayout());
 		control = parentComposite;
@@ -153,7 +138,7 @@ public class SWTSkinObjectContainer
 
 	protected void setViewID(String viewID) {
 		super.setViewID(viewID);
-		if (SWTSkin.DEBUGLAYOUT && control != null) {
+		if (skin.DEBUGLAYOUT && control != null) {
 			((Group) control).setText("[" + viewID + "]");
 		}
 	}
@@ -170,7 +155,7 @@ public class SWTSkinObjectContainer
 							return new SWTSkinObject[0];
 						}
 						Control[] swtChildren = ((Composite) control).getChildren();
-						ArrayList list = new ArrayList(swtChildren.length);
+						ArrayList<SWTSkinObject> list = new ArrayList<SWTSkinObject>(swtChildren.length);
 						for (int i = 0; i < swtChildren.length; i++) {
 							Control childControl = swtChildren[i];
 							SWTSkinObject so = (SWTSkinObject) childControl.getData("SkinObject");
@@ -179,7 +164,7 @@ public class SWTSkinObjectContainer
 							}
 						}
 
-						return (SWTSkinObject[]) list.toArray(new SWTSkinObject[list.size()]);
+						return list.toArray(new SWTSkinObject[list.size()]);
 					}
 				}, 2000);
 		if (so == null) {
@@ -235,7 +220,7 @@ public class SWTSkinObjectContainer
 
 	public void setPropogation(boolean propogate) {
 		bPropogate = propogate;
-		if (SWTSkin.DEBUGLAYOUT) {
+		if (skin.DEBUGLAYOUT) {
 			((Group) control).setText(((Group) control).getText()
 					+ (bPropogate ? ";P" : ""));
 		}
@@ -256,26 +241,110 @@ public class SWTSkinObjectContainer
 			}
 		}
 	}
-	
+
+	protected boolean superSetIsVisible(boolean visible, boolean walkup) {
+		boolean changed = super.setIsVisible(visible, walkup);
+		return changed;
+	}
+
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBasic#setIsVisible(boolean)
 	protected boolean setIsVisible(boolean visible, boolean walkup) {
-		boolean changed = super.setIsVisible(visible, walkup);
+		if (Utils.isThisThreadSWT() && !control.isDisposed()
+				&& !control.getShell().isVisible()) {
+			return false;
+		}
+		boolean changed = super.setIsVisible(visible, walkup && visible);
+
+		if (!changed) {
+			return false;
+		}
 		
 		// Currently we ignore "changed" and set visibility on children to ensure
 		// things display
-		if (!changed || true) {
-  		SWTSkinObject[] children = getChildren();
-  		for (int i = 0; i < children.length; i++) {
-  			if (children[i] instanceof SWTSkinObjectBasic) {
-  				SWTSkinObjectBasic child = ((SWTSkinObjectBasic)children[i]);
-  				Control childControl = child.getControl();
-  				if (childControl != null && !childControl.isDisposed()) {
-  					//child.setIsVisible(visible, false);
-  					child.setIsVisible(childControl.isVisible(), false);
-  				}
-  			}
-  		}
-		}
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				SWTSkinObject[] children = getChildren();
+				if (children.length == 0) {
+					return;
+				}
+				if (SWTSkin.DEBUG_VISIBILITIES) {
+					System.out.println(">> setIsVisible for " + children.length
+							+ " children of " + SWTSkinObjectContainer.this);
+				}
+				for (int i = 0; i < children.length; i++) {
+					if (children[i] instanceof SWTSkinObjectBasic) {
+						SWTSkinObjectBasic child = ((SWTSkinObjectBasic) children[i]);
+						Control childControl = child.getControl();
+						if (childControl != null && !childControl.isDisposed()) {
+							//child.setIsVisible(visible, false);
+							//System.out.println("child control " + child + " is " + (childControl.isVisible() ? "visible" : "invisible"));
+							child.setIsVisible(childControl.isVisible(), false);
+						}
+					}
+				}
+				getComposite().layout();
+				if (SWTSkin.DEBUG_VISIBILITIES) {
+					System.out.println("<< setIsVisible for " + children.length
+							+ " children");
+				}
+			}
+		});
 		return changed;
 	}
+
+	public void childAdded(SWTSkinObject soChild) {
+	}
+	
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBasic#obfusticatedImage(org.eclipse.swt.graphics.Image, org.eclipse.swt.graphics.Point)
+	public Image obfusticatedImage(Image image) {
+		if (!isVisible()) {
+			return image;
+		}
+
+		if (getSkinView() instanceof ObfusticateImage) {
+			image = ((ObfusticateImage) getSkinView()).obfusticatedImage(image);
+		}
+		
+		Control[] swtChildren = ((Composite) control).getChildren();
+		for (int i = 0; i < swtChildren.length; i++) {
+			Control childControl = swtChildren[i];
+
+			SWTSkinObject so = (SWTSkinObject) childControl.getData("SkinObject");
+			if (so instanceof ObfusticateImage) {
+				ObfusticateImage oi = (ObfusticateImage) so;
+				oi.obfusticatedImage(image);
+			} else if (so == null) { 
+				ObfusticateImage oi = (ObfusticateImage) childControl.getData("ObfusticateImage");
+				if (oi != null) {
+					oi.obfusticatedImage(image);
+					continue;
+				}
+				if (childControl instanceof Composite) {
+					obfusticatedImage((Composite) childControl, image);
+				}
+			}
+		}
+
+		return super.obfusticatedImage(image);
+	}
+
+	private void obfusticatedImage(Composite c, Image image) {
+		if (c == null || c.isDisposed() || !c.isVisible()) {
+			return;
+		}
+		Control[] children = c.getChildren();
+		for (Control childControl : children) {
+			if (!childControl.isVisible()) {
+				continue;
+			}
+			ObfusticateImage oi = (ObfusticateImage) childControl.getData("ObfusticateImage");
+			if (oi != null) {
+				oi.obfusticatedImage(image);
+				continue;
+			}
+			if (childControl instanceof Composite) {
+				obfusticatedImage((Composite) childControl, image);
+			}
+		}
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
index 26ce0ad..ef45938 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectImage.java
@@ -29,12 +29,16 @@ public class SWTSkinObjectImage
 
 	protected static final Long DRAW_NORMAL = new Long(0);
 
+	protected static final Long DRAW_LEFT = new Long(7);
+
 	protected static final Long DRAW_TILE = new Long(3);
 
 	protected static final Long DRAW_CENTER = new Long(4);
 
 	protected static final Long DRAW_HCENTER = new Long(5);
 
+	protected static final Long DRAW_ANIMATE = new Long(6);
+
 	private Canvas canvas;
 
 	private boolean customImage;
@@ -50,21 +54,34 @@ public class SWTSkinObjectImage
 	static {
 		paintListener = new PaintListener() {
 			public void paintControl(PaintEvent e) {
-				SWTSkinObject so = (SWTSkinObject) e.widget.getData("SkinObject");
+				//SWTSkinObject so = (SWTSkinObject) e.widget.getData("SkinObject");
 				try {
 					e.gc.setAdvanced(true);
 					e.gc.setInterpolation(SWT.HIGH);
 				} catch (Exception ex) {
 				}
 
-				Canvas control = (Canvas) e.widget;
+				final Canvas control = (Canvas) e.widget;
 				Image imgSrc = (Image) control.getData("image");
+				
+				Long hpadding_obj = (Long) control.getData("hpadding");
+				int hpadding = hpadding_obj == null ? 0 : hpadding_obj.intValue();
+
+				Long drawMode = (Long) control.getData("drawmode");
+				if (drawMode == DRAW_ANIMATE) {
+					Image[] images = (Image[]) control.getData("images");
+					if (images != null) {
+  					int idx = ((Number) control.getData("ImageIndex")).intValue();
+  					imgSrc = images[idx];
+					}
+				}
+
 				Image imgRight = null;
 				Image imgLeft = null;
 				String idToRelease = null;
 				ImageLoader imageLoader = null;
 
-				if (imgSrc == null) {
+				if (imgSrc == null || imgSrc.isDisposed()) {
 					SWTSkinObjectImage soImage = (SWTSkinObjectImage) control.getData("SkinObject");
 					imageLoader = soImage.getSkin().getImageLoader(
 							soImage.getProperties());
@@ -86,14 +103,20 @@ public class SWTSkinObjectImage
 				Rectangle imgSrcBounds = imgSrc.getBounds();
 				Point size = control.getSize();
 
-				Long drawMode = (Long) control.getData("drawmode");
-
 				if (drawMode == DRAW_STRETCH) {
 					e.gc.drawImage(imgSrc, 0, 0, imgSrcBounds.width, imgSrcBounds.height,
 							0, 0, size.x, size.y);
-				} else if (drawMode == DRAW_CENTER || drawMode == DRAW_NORMAL) {
-					e.gc.drawImage(imgSrc, (size.x - imgSrcBounds.width) / 2,
-							(size.y - imgSrcBounds.height) / 2);
+				} else if (drawMode == DRAW_LEFT) {
+					e.gc.drawImage(imgSrc, 0, 0);
+				} else if (drawMode == DRAW_NORMAL || drawMode == DRAW_CENTER
+						|| drawMode == DRAW_ANIMATE) {
+					if ((control.getStyle() & SWT.RIGHT) > 0) {
+  					e.gc.drawImage(imgSrc, size.x - imgSrcBounds.width,
+  							(size.y - imgSrcBounds.height) / 2);
+					} else {
+  					e.gc.drawImage(imgSrc, (size.x - imgSrcBounds.width) / 2,
+  							(size.y - imgSrcBounds.height) / 2);
+					}
 				} else if (drawMode == DRAW_HCENTER) {
 					e.gc.drawImage(imgSrc, (size.x - imgSrcBounds.width) / 2, 0);
 				} else if (drawMode == DRAW_SCALE) {
@@ -148,15 +171,20 @@ public class SWTSkinObjectImage
 	 * 
 	 */
 	public SWTSkinObjectImage(SWTSkin skin, SWTSkinProperties skinProperties,
-			String sID, String sConfigID, String sImageID, SWTSkinObject parent) {
+			String sID, String sConfigID, SWTSkinObject parent) {
 		super(skin, skinProperties, sID, sConfigID, "image", parent);
-		setControl(createImageWidget(sConfigID, sImageID));
 		customImage = false;
 		customImageID = null;
+		setControl(createImageWidget(sConfigID));
 	}
 
-	private Canvas createImageWidget(String sConfigID, String sImageID) {
-		currentImageID = sImageID;
+	private Canvas createImageWidget(String sConfigID) {
+		String propImageID = properties.getStringValue(sConfigID + ".imageid");
+		if (propImageID != null) {
+			currentImageID = customImageID = propImageID;
+		} else {
+			currentImageID = sConfigID;
+		}
 		int style = SWT.WRAP | SWT.DOUBLE_BUFFERED;
 
 		String sAlign = properties.getStringValue(sConfigID + ".align");
@@ -181,6 +209,28 @@ public class SWTSkinObjectImage
 		canvas = new Canvas(createOn, style);
 		canvas.setData("SkinObject", this);
 
+//		 {
+//				public Point computeSize(int wHint, int hHint) {
+//					Object image = canvas.getData("image");
+//					Object imageID = canvas.getData("ImageID");
+//					if (image == null
+//							&& (imageID == null || ((String) imageID).length() == 0)) {
+//						return new Point(0, 0);
+//					}
+//					return super.computeSize(wHint, hHint);
+//				};
+//
+//				public Point computeSize(int wHint, int hHint, boolean changed) {
+//					Object image = canvas.getData("image");
+//					Object imageID = canvas.getData("ImageID");
+//					if (image == null
+//							&& (imageID == null || ((String) imageID).length() == 0)) {
+//						return new Point(0, 0);
+//					}
+//					return super.computeSize(wHint, hHint, changed);
+//				};
+//			};
+
 		Color color = properties.getColor(sConfigID + ".color");
 		if (color != null) {
 			canvas.setBackground(color);
@@ -221,7 +271,7 @@ public class SWTSkinObjectImage
 		});
 
 		// needed to set paint listener and canvas size
-		reallySetImage();
+		swt_reallySetImage();
 
 		return canvas;
 	}
@@ -230,7 +280,11 @@ public class SWTSkinObjectImage
 		super.setVisible(visible);
 
 		if (visible) {
-			reallySetImage();
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					swt_reallySetImage();
+				}
+			});
 		}
 	}
 
@@ -259,13 +313,60 @@ public class SWTSkinObjectImage
 				if (oldImageID != null && canvas.getData("image") != null) {
 					imageLoader.releaseImage(oldImageID);
 				}
+				
+				int hpadding = properties.getIntValue(sConfigID + ".h-padding", 0);
+				canvas.setData("hpadding", new Long(hpadding));
+
 
 				Image[] images = sImageID == null || sImageID.length() == 0 ? null
 						: imageLoader.getImages(sImageID);
 
+				String sDrawMode = properties.getStringValue(sConfigID + ".drawmode");
+				if (sDrawMode == null) {
+					sDrawMode = properties.getStringValue(
+							SWTSkinObjectImage.this.sConfigID + ".drawmode", "");
+				}
+
+				Long drawMode;
+				if (sDrawMode.equals("scale")) {
+					drawMode = DRAW_SCALE;
+				} else if (sDrawMode.equals("stretch")) {
+					drawMode = DRAW_STRETCH;
+				} else if (sDrawMode.equals("center")) {
+					drawMode = DRAW_CENTER;
+				} else if (sDrawMode.equals("h-center")) {
+					drawMode = DRAW_HCENTER;
+				} else if (sDrawMode.equalsIgnoreCase("tile")) {
+					drawMode = DRAW_TILE;
+				} else if (sDrawMode.equalsIgnoreCase("animate")
+						|| (sDrawMode.length() == 0 && images != null && images.length > 3)) {
+					drawMode = DRAW_ANIMATE;
+				} else if (sDrawMode.equalsIgnoreCase("left")) {
+					drawMode = DRAW_LEFT;
+				} else {
+					drawMode = DRAW_NORMAL;
+				}
+				canvas.setData("drawmode", drawMode);
+
 				Image image = null;
 
-				if (images.length == 3) {
+				boolean hasExistingDelay = canvas.getData("delay") != null;
+				canvas.setData("delay", null);
+				if (images == null) {
+					canvas.setData("images", null);
+					image = null;
+				} else if (drawMode == DRAW_ANIMATE) {
+					int animationDelay = ImageLoader.getInstance().getAnimationDelay(sImageID);
+
+					canvas.setData("images", images);
+					canvas.setData("ImageIndex", Long.valueOf(0));
+					canvas.setData("delay", new Long(animationDelay));
+					image = images[0];
+
+					if (!hasExistingDelay) {
+						setupAnimationTrigger(animationDelay);
+					}
+				} else if (images.length == 3) {
 					Image imageLeft = images[0];
 					if (ImageLoader.isRealImage(imageLeft)) {
 						canvas.setData("image-left", imageLeft);
@@ -285,46 +386,28 @@ public class SWTSkinObjectImage
 					image = ImageLoader.noImage;
 				}
 
-				String sDrawMode = properties.getStringValue(sConfigID + ".drawmode");
-				if (sDrawMode == null) {
-					sDrawMode = properties.getStringValue(
-							SWTSkinObjectImage.this.sConfigID + ".drawmode", "");
-				}
 
 				//allowImageDimming = sDrawMode.equalsIgnoreCase("dim");
-
-				Long drawMode;
-				if (sDrawMode.equals("scale")) {
-					drawMode = DRAW_SCALE;
-				} else if (sDrawMode.equals("stretch")) {
-					drawMode = DRAW_STRETCH;
-				} else if (sDrawMode.equals("center")) {
-					drawMode = DRAW_CENTER;
-				} else if (sDrawMode.equals("h-center")) {
-					drawMode = DRAW_HCENTER;
-				} else if (sDrawMode.equalsIgnoreCase("tile")) {
-					drawMode = DRAW_TILE;
-				} else {
-					drawMode = DRAW_NORMAL;
-				}
-				canvas.setData("drawmode", drawMode);
-
+ 
 				Rectangle imgBounds = image.getBounds();
 				if (drawMode != DRAW_CENTER && drawMode != DRAW_HCENTER
 						&& drawMode != DRAW_STRETCH) {
-					canvas.setSize(imgBounds.width, imgBounds.height);
+					canvas.setSize(imgBounds.width + hpadding, imgBounds.height);
+					canvas.setData("oldSize", canvas.getSize());
 				}
 				//canvas.setData("image", image);
 
-				if (drawMode == DRAW_TILE || drawMode == DRAW_NORMAL) {
+				if (drawMode == DRAW_TILE || drawMode == DRAW_NORMAL || drawMode == DRAW_LEFT
+						|| drawMode == DRAW_ANIMATE) {
 					// XXX Huh? A tile of one? :)
 					FormData fd = (FormData) canvas.getLayoutData();
 					if (fd == null) {
-						fd = new FormData(imgBounds.width, imgBounds.height);
+						fd = new FormData(imgBounds.width  + hpadding, imgBounds.height);
 					} else {
-						fd.width = imgBounds.width;
+						fd.width = imgBounds.width + hpadding;
 						fd.height = imgBounds.height;
 					}
+					canvas.setData("oldSize", new Point(fd.width, fd.height));
 					canvas.setLayoutData(fd);
 					Utils.relayout(canvas);
 				}
@@ -333,17 +416,44 @@ public class SWTSkinObjectImage
 				canvas.removePaintListener(paintListener);
 
 				canvas.addPaintListener(paintListener);
-				canvas.setData("ImageID", sImageID);
+				canvas.setData("ImageID", sImageID); 
 
 				canvas.redraw();
 
 				SWTSkinUtils.addMouseImageChangeListeners(canvas);
-				imageLoader.releaseImage(sImageID);
+				if (drawMode != DRAW_ANIMATE) {
+					imageLoader.releaseImage(sImageID);
+				}
 				return null;
 			}
 		});
 	}
 
+	protected void setupAnimationTrigger(int animationDelay) {
+		Utils.execSWTThreadLater(animationDelay, new AERunnable() {
+			public void runSupport() {
+				if (!control.isDisposed()) {
+					Object data = control.getData("delay");
+					if (data == null) {
+						return;
+					}
+
+					Image[] images = (Image[]) control.getData("images");
+					int idx = ((Number) control.getData("ImageIndex")).intValue();
+					idx++;
+					if (idx >= images.length) {
+						idx = 0;
+					}
+					control.setData("ImageIndex", new Long(idx));
+					control.redraw();
+					
+					int delay = ((Number) control.getData("delay")).intValue();
+					setupAnimationTrigger(delay);
+				}
+			}
+		});
+	}
+
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObject#setBackground(java.lang.String, java.lang.String)
 	public void setBackground(String sConfigID, String sSuffix) {
 		// No background for images?
@@ -369,7 +479,7 @@ public class SWTSkinObjectImage
 						: customImageID)
 						+ fSuffix;
 				if (isVisible()) {
-					reallySetImage();
+					swt_reallySetImage();
 				}
 			}
 		});
@@ -377,11 +487,11 @@ public class SWTSkinObjectImage
 		return suffix;
 	}
 
-	protected void reallySetImage() {
+	protected void swt_reallySetImage() {
 		if (currentImageID == null || customImage) {
 			return;
 		}
-
+		
 		ImageLoader imageLoader = skin.getImageLoader(properties);
 		boolean imageExists = imageLoader.imageExists(currentImageID);
 		if (!imageExists && imageLoader.imageExists(currentImageID + ".image")) {
@@ -404,40 +514,73 @@ public class SWTSkinObjectImage
 
 		if (imageExists) {
 			setCanvasImage(currentImageID, null);
+		} else {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					FormData fd = (FormData) canvas.getLayoutData();
+					if (fd == null) {
+						fd = new FormData(0, 0);
+					} else {
+						fd.width = 0;
+						fd.height = 0;
+					}
+					canvas.setLayoutData(fd);
+					if (initialized) {
+						Utils.relayout(canvas);
+					}
+				}
+			});
 		}
 	}
 
-	public void setImage(Image image) {
-		customImage = true;
-		customImageID = null;
-		canvas.setData("image", image);
-		canvas.setData("image-left", null);
-		canvas.setData("image-right", null);
-		canvas.redraw();
-		Utils.relayout(canvas);
+	public void setImage(final Image image) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				customImage = true;
+				customImageID = null;
+				canvas.setData("image", image);
+				canvas.setData("ImageID", null);
+				canvas.setData("image-left", null);
+				canvas.setData("image-right", null);
+
+				canvas.removePaintListener(paintListener);
+				canvas.addPaintListener(paintListener);
+
+				Utils.relayout(canvas);
+				canvas.redraw();
+			}
+		});
 	}
 
-	protected void setImageByID(String sConfigID, AECallback callback) {
+	public void setImageByID(final String imageID, final AECallback callback) {
 		if (customImage == false && customImageID != null
-				&& customImageID.equals(sConfigID)) {
+				&& customImageID.equals(imageID)) {
 			if (callback != null) {
 				callback.callbackFailure(null);
 			}
 			return;
 		}
 		customImage = false;
-		customImageID = sConfigID;
-
-		String sImageID = sConfigID + getSuffix();
-		ImageLoader imageLoader = skin.getImageLoader(properties);
-		Image image = imageLoader.getImage(sImageID);
-		if (ImageLoader.isRealImage(image)) {
-			setCanvasImage(sConfigID, sImageID, callback);
-		} else {
-			setCanvasImage(sConfigID, sConfigID, callback);
+		customImageID = imageID;
+		
+		if (imageID == null) {
+			setCanvasImage(this.sConfigID, null, null);
+			return;
 		}
-		imageLoader.releaseImage(sImageID);
-		return;
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				String fullImageID = imageID + getSuffix();
+				ImageLoader imageLoader = skin.getImageLoader(properties);
+				Image image = imageLoader.getImage(fullImageID);
+				if (ImageLoader.isRealImage(image)) {
+					setCanvasImage(sConfigID, fullImageID, callback);
+				} else {
+					setCanvasImage(sConfigID, imageID, callback);
+				}
+				imageLoader.releaseImage(fullImageID);
+			}
+		});
 	}
 
 	public void setImageUrl(final String url) {
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectListener.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectListener.java
index 7bf60d9..f329d99 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectListener.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectListener.java
@@ -65,6 +65,8 @@ public interface SWTSkinObjectListener
 	 */
 	public static int EVENT_LANGUAGE_CHANGE = 6;
 
+	public static int EVENT_DATASOURCE_CHANGED = 7;
+
 	
 	/**
 	 * Friendly names of events, useful for debug
@@ -76,7 +78,8 @@ public interface SWTSkinObjectListener
 		"Destroy",
 		"Created",
 		"Create Request",
-		"Lang Change"
+		"Lang Change",
+		"DS Change"
 	};
 
 	/**
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
index 1023456..ecac61f 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectSash.java
@@ -31,6 +31,7 @@ import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 
@@ -39,11 +40,7 @@ import org.gudy.azureus2.ui.swt.Utils;
  * Parameters:
  * <dl>
  * <dt>.startpos</dt>
- * <dd>Position in % or pixels of where to start the sash by default</dd>
- * <dt>.resize.container.min</dt>
- * <dd></dd>
- * <dt>.dblclick</dt>
- * <dd></dd>
+ * <dd>Position in pixels of where to start the sash by default</dd>
  * <dt></dt>
  * <dd></dd>
  * </dl>
@@ -73,18 +70,12 @@ public class SWTSkinObjectSash
 
 	protected String sControlAfter;
 
-	private int resizeContainerAboveMin = -1;
-
-	boolean ignoreContainerAboveMin = false;
-
 	private Composite createOn;
 
 	private final boolean isVertical;
 
 	private Sash sash;
 
-	Point lastSize = new Point(0, 0);
-
 	private Composite parentComposite;
 
 	private Composite above = null;
@@ -95,11 +86,11 @@ public class SWTSkinObjectSash
 
 	private int belowMin = 0;
 
-	private double sashPct;
+	private String sBorder;
 
-	private boolean noresize = false;
+	private SWTSkinObject soAbove;
 
-	private String sBorder;
+	private SWTSkinObject soBelow;
 
 	public SWTSkinObjectSash(final SWTSkin skin,
 			final SWTSkinProperties properties, final String sID,
@@ -128,48 +119,16 @@ public class SWTSkinObjectSash
 
 		sash = new Sash(createOn, style);
 
-		noresize = properties.getBooleanValue(sConfigID + ".noresize", false);
-
-		String sMinContainerPos = properties.getStringValue(sConfigID
-				+ ".resize.container.min");
-		if (sMinContainerPos != null) {
-			try {
-				resizeContainerAboveMin = NumberFormat.getInstance().parse(
-						sMinContainerPos).intValue();
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-
-
-		int splitAt = COConfigurationManager.getIntParameter("v3." + sID
-				+ ".splitAt", -1);
 		int splitAtPX = COConfigurationManager.getIntParameter("v3." + sID
 				+ ".splitAtPX", -1);
-		if (noresize && splitAtPX >= 0) {
-			if (splitAtPX < resizeContainerAboveMin) {
-				splitAtPX = resizeContainerAboveMin;
-			}
+		if (splitAtPX >= 0) {
 			sash.setData("PX", new Long(splitAtPX));
-		} else if (!noresize && splitAt >= 0) {
-			sashPct = splitAt / 10000.0;
-			if (sashPct > 1) {
-				sashPct = 1;
-			} else if (sashPct < 0) {
-				sashPct = 0;
-			}
-			sash.setData("PCT", new Double(sashPct));
 		} else {
 			String sPos = properties.getStringValue(sConfigID + ".startpos");
 			if (sPos != null) {
 				try {
 					long l = NumberFormat.getInstance().parse(sPos).longValue();
-					if (sPos.endsWith("%")) {
-						sashPct = (double) l / 100;
-						sash.setData("PCT", new Double(sashPct));
-					} else {
-						sash.setData("PX", new Long(l));
-					}
+					sash.setData("PX", new Long(l));
 				} catch (Exception e) {
 					Debug.out(e);
 				}
@@ -178,7 +137,6 @@ public class SWTSkinObjectSash
 
 		parentComposite = createOn;
 
-
 		SWTSkinObject soInitializeSashAfterCreated = parent == null ? this : parent;
 		soInitializeSashAfterCreated.addListener(new SWTSkinObjectListener() {
 			public Object eventOccured(SWTSkinObject skinObject, int eventType,
@@ -190,46 +148,6 @@ public class SWTSkinObjectSash
 			}
 		});
 
-		String sDblClick = properties.getStringValue(sConfigID + ".dblclick");
-		if (sDblClick != null) {
-			sDblClick = sDblClick.toLowerCase();
-
-			final int dir = (sDblClick.equals("left")) ? SWT.LEFT : SWT.RIGHT;
-			sash.addListener(SWT.MouseDoubleClick, new Listener() {
-				// @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
-
-				public void handleEvent(Event e) {
-					if (below == null || above == null) {
-						return;
-					}
-
-					Double oldPCT = (Double) sash.getData("PCT");
-					if (oldPCT == null) {
-						oldPCT = new Double(-1);
-					}
-					double pct;
-					if (dir == SWT.LEFT) {
-						if (oldPCT.doubleValue() == 1) {
-							pct = 0;
-						} else {
-							pct = 1;
-						}
-					} else {
-						if (oldPCT.doubleValue() == 0) {
-							pct = 1;
-						} else {
-							pct = 0;
-						}
-					}
-
-					setPercent(pct, sash, above, below, bVertical, parentComposite,
-							aboveMin, belowMin);
-					above.getParent().layout();
-				}
-
-			});
-		} // dblclick
-
 		sBorder = properties.getStringValue(sConfigID + ".border", (String) null);
 		if (sBorder != null) {
 			sash.addPaintListener(new PaintListener() {
@@ -268,15 +186,20 @@ public class SWTSkinObjectSash
 		skinObject = skin.getSkinObjectByID(sControlBefore);
 
 		if (skinObject != null) {
+			soAbove = skinObject;
 			above = (Composite) skinObject.getControl();
 			aboveMin = skinObject.getProperties().getIntValue(
-					getConfigID() + ".above"
-							+ (isVertical ? ".minwidth" : ".minheight"), 0);
+					getConfigID() + ".above" + (isVertical ? ".minwidth" : ".minheight"),
+					0);
+			boolean aboveVisible = COConfigurationManager.getBooleanParameter("v3."
+					+ sID + ".aboveVisible", true);
+			soAbove.setVisible(aboveVisible);
 		}
-		
+
 		skinObject = skin.getSkinObjectByID(sControlAfter);
 
 		if (skinObject != null) {
+			soBelow = skinObject;
 			below = (Composite) skinObject.getControl();
 		}
 		if (below == null) {
@@ -284,12 +207,9 @@ public class SWTSkinObjectSash
 		}
 
 		belowMin = skinObject.getProperties().getIntValue(
-				getConfigID() + ".below"
-						+ (isVertical ? ".minwidth" : ".minheight"), 0);
+				getConfigID() + ".below" + (isVertical ? ".minwidth" : ".minheight"), 0);
 
 		Listener l = new Listener() {
-			private boolean skipResize = false;
-
 			public void handleEvent(Event e) {
 				if (e.type == SWT.MouseUp) {
 					if (e.button == 3 || (e.button == 1 && (e.stateMask & SWT.MOD1) > 0)) {
@@ -299,13 +219,7 @@ public class SWTSkinObjectSash
 						}
 						try {
 							long l = NumberFormat.getInstance().parse(sPos).longValue();
-							if (sPos.endsWith("%")) {
-								sashPct = (double) l / 100;
-								sash.setData("PCT", new Double(sashPct));
-							} else {
-								sash.setData("PX", new Long(l));
-								sash.setData("PCT", null);
-							}
+							sash.setData("PX", new Long(l));
 							// FALL THROUGH
 							e.type = SWT.Show;
 						} catch (Exception ex) {
@@ -317,14 +231,14 @@ public class SWTSkinObjectSash
 					}
 				}
 
-				if (e.type == SWT.Resize && skipResize) {
-					return;
-				}
-				if (e.type == SWT.Resize || e.type == SWT.Show) {
-					handleShowResize(e);
+				if (e.type == SWT.Show) {
+					// delay so soAbove's show gets triggered
+					Utils.execSWTThreadLater(0, new AERunnable() {
+						public void runSupport() {
+							handleShow();
+						}
+					});
 				} else if (e.type == SWT.Selection) {
-					skipResize = true;
-
 					if (FASTDRAG && e.detail == SWT.DRAG) {
 						return;
 					}
@@ -347,7 +261,6 @@ public class SWTSkinObjectSash
 								e.doit = false;
 							}
 						}
-						ignoreContainerAboveMin = aboveData.width < resizeContainerAboveMin;
 					} else {
 						aboveData.height = e.y - above.getBorderWidth();
 						if (aboveData.height < aboveMin) {
@@ -365,49 +278,29 @@ public class SWTSkinObjectSash
 
 					parentComposite.layout(true);
 
-					double d;
 					double aboveNewSize;
 					if (isVertical) {
 						aboveNewSize = above.getBounds().width + (sash.getSize().x / 2.0);
-						d = aboveNewSize / parentComposite.getBounds().width;
 					} else {
 						aboveNewSize = above.getBounds().height + (sash.getSize().y / 2.0);
-						d = aboveNewSize / parentComposite.getBounds().height;
-					}
-					sashPct = ensureVisibilityStates(d, above, below, isVertical);
-					sash.setData("PCT", new Double(sashPct));
-					if (noresize) {
-						sash.setData("PX", new Long((long) aboveNewSize));
-					}
-
-					if (e.detail != SWT.DRAG) {
-						COConfigurationManager.setParameter("v3." + sID + ".splitAt",
-								(int) (sashPct * 10000));
 					}
+					sash.setData("PX", new Long((long) aboveNewSize));
 
-					skipResize = false;
 				}
 			}
 		};
-		if (!noresize) {
-			createOn.addListener(SWT.Resize, l);
-		}
 		sash.addListener(SWT.Selection, l);
 		sash.addListener(SWT.MouseUp, l);
 		sash.getShell().addListener(SWT.Show, l);
 
-		Event event = new Event();
-		event.type = SWT.Show;
-
-		handleShowResize(event);
+		handleShow();
 	}
-	
+
 	public void dispose() {
-		if (noresize) {
-			Long px = (Long) sash.getData("PX");
-			if (px != null && px.longValue() != 0) {
-				COConfigurationManager.setParameter("v3." + sID + ".splitAtPX", px.longValue());
-			}
+		Long px = (Long) sash.getData("PX");
+		if (px != null && px.longValue() != 0) {
+			COConfigurationManager.setParameter("v3." + sID + ".splitAtPX",
+					px.longValue());
 		}
 		super.dispose();
 	}
@@ -417,91 +310,33 @@ public class SWTSkinObjectSash
 	 *
 	 * @since 3.1.0.1
 	 */
-	protected void handleShowResize(Event e) {
-		if (!createOn.isVisible() && e.type != SWT.Show) {
-			return;
-		}
-
-		Double l = (Double) sash.getData("PCT");
+	protected void handleShow() {
 		Long px = (Long) sash.getData("PX");
-		if (noresize && px == null && e.type != SWT.Show) {
-			Point size = createOn.getSize();
-			size.x -= createOn.getBorderWidth() * 2;
-			size.x -= sash.getSize().x;
-			px = new Long((long) (size.x * l.doubleValue()));
-			sash.setData("PX", px);
+		if (px == null) {
+			return;
 		}
-		if (l != null && (!noresize || e.type == SWT.Show)) {
-			Point size = createOn.getSize();
-			if (isVertical && size.x == lastSize.x) {
-				return;
-			} else if (!isVertical && size.y == lastSize.y) {
-				return;
+		int newAboveSize;
+		if (soAbove.isVisible()) {
+			newAboveSize = px.intValue();
+			if (newAboveSize < aboveMin) {
+				newAboveSize = aboveMin;
 			}
+		} else {
+			newAboveSize = 0;
+		}
 
-			lastSize = size;
-
-			setPercent(l.doubleValue(), sash, above, below, isVertical,
-					parentComposite, aboveMin, belowMin);
-		} else if (px != null) {
-			int i = (isVertical) ? parentComposite.getSize().x
-					: parentComposite.getSize().y;
-			if (i == 0) {
-				return;
-			}
-			double pctAbove = px.doubleValue() / i;
-
-			FormData aboveData = (FormData) above.getLayoutData();
-			if (aboveData == null) {
-				aboveData = Utils.getFilledFormData();
-				above.setLayoutData(aboveData);
-			}
-			if (isVertical) {
-				int parentWidth = parentComposite.getBounds().width;
-				aboveData.width = (int) (parentWidth * pctAbove);
-				if (parentWidth - aboveData.width < aboveMin) {
-					aboveData.width = parentWidth - aboveMin;
-				}
-				if (noresize) {
-					sash.setData("PX", new Long(aboveData.width));
-				}
-			} else {
-				int parentHeight = parentComposite.getBounds().height;
-				aboveData.height = (int) (parentHeight * pctAbove);
-				if (parentHeight - aboveData.width < aboveMin) {
-					aboveData.height = parentHeight - aboveMin;
-				}
-				if (noresize) {
-					sash.setData("PX", new Long(aboveData.height));
-				}
-			}
-			if (pctAbove >= 0 && pctAbove <= 1.0) {
-				sashPct = pctAbove;
-				sash.setData("PCT", new Double(pctAbove));
-			}
-			ignoreContainerAboveMin = px.longValue() < resizeContainerAboveMin;
-			// layout in resize is not needed (and causes browser widget to blink)
+		FormData aboveData = (FormData) above.getLayoutData();
+		if (aboveData == null) {
+			aboveData = Utils.getFilledFormData();
+			above.setLayoutData(aboveData);
 		}
-		if (e.type == SWT.Show) {
-			parentComposite.layout(true);
+		if (isVertical) {
+			aboveData.width = newAboveSize;
+		} else {
+			aboveData.height = newAboveSize;
 		}
 
-	}
-
-	public void setPercent(double pct) {
-		setPercent(pct, sash, above, below, isVertical, parentComposite, aboveMin,
-				belowMin);
-	}
-
-	public double getPercent() {
-		if (noresize) {
-			Long px = (Long) sash.getData("PX");
-			int i = (isVertical) ? parentComposite.getSize().x
-					: parentComposite.getSize().y;
-
-			return px.doubleValue() / i;
-		}
-		return sashPct;
+		parentComposite.layout(true);
 	}
 
 	/**
@@ -522,18 +357,13 @@ public class SWTSkinObjectSash
 		boolean layoutNeeded = false;
 		if (bVertical) {
 			int parentWidth = parentComposite.getBounds().width
-				- (parentComposite.getBorderWidth() * 2) - sash.getSize().x;
+					- (parentComposite.getBorderWidth() * 2) - sash.getSize().x;
 			int newWidth = (int) (parentWidth * pctAbove);
 			if (newWidth != aboveData.width) {
 				aboveData.width = newWidth;
 				layoutNeeded = true;
 			}
 
-			//System.out.println("ignore=" + ignoreContainerAboveMin + ";above=" + aboveWidth + ";d=" + d);
-			if (!ignoreContainerAboveMin && resizeContainerAboveMin > 0 && pctAbove != 0.0
-					&& pctAbove != 1.0) {
-				minAbove = Math.max(resizeContainerAboveMin, minAbove);
-			}
 			if (pctAbove != 0.0
 					&& parentWidth - aboveData.width - sash.getSize().x < minAbove) {
 				aboveData.width = parentWidth - minAbove - sash.getSize().x;
@@ -543,13 +373,9 @@ public class SWTSkinObjectSash
 			} else if (aboveData.width < belowMin) {
 				layoutNeeded = true;
 				aboveData.width = belowMin;
-			} else {
-				ignoreContainerAboveMin = aboveData.width <= resizeContainerAboveMin;
 			}
 
-			if (noresize) {
-				sash.setData("PX", new Long(aboveData.width));
-			}
+			sash.setData("PX", new Long(aboveData.width));
 		} else {
 			int parentHeight = parentComposite.getBounds().height
 					- (parentComposite.getBorderWidth() * 2) - sash.getSize().y;
@@ -567,67 +393,68 @@ public class SWTSkinObjectSash
 				layoutNeeded = true;
 				aboveData.height = belowMin;
 			}
-			if (noresize) {
-				sash.setData("PX", new Long(aboveData.height));
-			}
+			sash.setData("PX", new Long(aboveData.height));
 		}
 		if (layoutNeeded) {
 			above.getParent().layout();
 		}
-
-		pctAbove = ensureVisibilityStates(pctAbove, above, below, bVertical);
-		sash.setData("PCT", new Double(pctAbove));
-		sashPct = pctAbove;
-		if (sashPct != 0 && sashPct != 100) {
-  		COConfigurationManager.setParameter("v3." + sID + ".splitAt",
-  				(int) (pctAbove * 10000));
-		}
 	}
 
-	private double ensureVisibilityStates(double pct, Composite above,
-			Composite below, boolean bVertical) {
-		if (pct > 1) {
-			pct = 1;
-		} else if (pct < 0) {
-			pct = 0;
-		}
+	public void setBelowSize(final int px) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				int sashHeight = isVertical ? sash.getSize().x : sash.getSize().y;
+				int parentHeight = parentComposite.getBounds().height
+						- (parentComposite.getBorderWidth() * 2);
 
-		int sizeBelow = bVertical ? below.getSize().x : below.getSize().y;
-		int sizeAbove = bVertical ? above.getSize().x : above.getSize().y;
+				int wantAboveSize = parentHeight - sashHeight - px;
+				sash.setData("PX", new Long(wantAboveSize));
+				handleShow();
+			}
+		});
+	}
 
-		if ((pct == 1.0 || sizeBelow <= 1) && below != null && below.getVisible()) {
-			below.setVisible(false);
-			below.setData("SashSetVisibility", new Boolean(true));
-		} else if (below != null && !below.isVisible()
-				&& (below.getData("SashSetVisibility") != null)) {
-			below.setVisible(true);
-			below.setData("SashSetVisibility", null);
-		}
+	public void setAboveSize(final int px) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				sash.setData("PX", new Long(px));
+				handleShow();
+			}
+		});
+	}
 
-		if ((pct == 0.0 || sizeAbove <= 1) && above != null && above.getVisible()) {
-			above.setVisible(false);
-			above.setData("SashSetVisibility", new Boolean(true));
-		} else if (above != null && !above.isVisible()
-				&& (above.getData("SashSetVisibility") != null)) {
-			above.setVisible(true);
-			above.setData("SashSetVisibility", null);
-		}
+	public void resetWidth() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				String sPos = properties.getStringValue(sConfigID + ".startpos");
+				COConfigurationManager.removeParameter("v3." + sID + ".splitAt");
+				COConfigurationManager.removeParameter("v3." + sID + ".splitAtPX");
+				if (sPos != null) {
+					sash.setData("PX", null);
+					try {
+						int l = NumberFormat.getInstance().parse(sPos).intValue();
+						setAboveSize(l);
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+				}
+			}
+		});
+	}
 
-		return pct;
+	public boolean isAboveVisible() {
+		if (soAbove == null || soAbove.isDisposed()) {
+			return false;
+		}
+		return soAbove.isVisible();
 	}
 
-	/**
-	 * @param toolbarHeight
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void setBelowPX(int px) {
-		double sashHeight = sash.getSize().y;
-		double parentHeight = parentComposite.getBounds().height
-				- (parentComposite.getBorderWidth() * 2);
-		
-		double want = parentHeight - sashHeight - px;
-		double pct = want / parentHeight;
-		setPercent(pct);
+	public void setAboveVisible(boolean visible) {
+		if (soAbove == null) {
+			return;
+		}
+		COConfigurationManager.setParameter("v3." + sID + ".aboveVisible", visible);
+		soAbove.setVisible(visible);
+		handleShow();
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTabFolder.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTabFolder.java
new file mode 100644
index 0000000..16b4f13
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTabFolder.java
@@ -0,0 +1,69 @@
+package com.aelitis.azureus.ui.swt.skin;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.widgets.Composite;
+
+import org.gudy.azureus2.core3.util.Constants;
+
+public class SWTSkinObjectTabFolder
+	extends SWTSkinObjectContainer
+{
+
+	private CTabFolder tabFolder;
+
+	public SWTSkinObjectTabFolder(SWTSkin skin, SWTSkinProperties properties,
+			String sID, String sConfigID, SWTSkinObject parent) {
+		super(skin, properties, null, sID, sConfigID, "tabfolder", parent);
+		createTabFolder();
+		
+	}
+
+	private void createTabFolder() {
+		Composite createOn;
+		if (parent == null) {
+			createOn = skin.getShell();
+		} else {
+			createOn = (Composite) parent.getControl();
+		}
+
+		int style = SWT.NONE;
+		if (properties.getIntValue(sConfigID + ".border", 0) == 1) {
+			style = SWT.BORDER;
+		}
+		
+		String sStyle = properties.getStringValue("style");
+		if (sStyle != null && sStyle.length() > 0) {
+			String[] styles = Constants.PAT_SPLIT_COMMA.split(sStyle);
+			for (String aStyle : styles) {
+				if (aStyle.equalsIgnoreCase("close")) {
+					style |= SWT.CLOSE;
+				}
+			}
+		}
+
+		
+		tabFolder = new CTabFolder(createOn, style);
+		
+		triggerListeners(SWTSkinObjectListener.EVENT_CREATED);
+		setControl(tabFolder);
+	}
+
+	protected boolean setIsVisible(boolean visible, boolean walkup) {
+		boolean isVisible = superSetIsVisible(visible, walkup);
+		// Todo: ensure correct tabfolder child comp is visible
+		return isVisible;
+	}
+	
+	public void childAdded(SWTSkinObject soChild) {
+//		super.childAdded(soChild);
+//		CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
+//		tabItem.setText("WOW");
+//		tabItem.setControl(soChild.getControl());
+	}
+
+	public CTabFolder getTabFolder() {
+		return tabFolder;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText.java
index 7bd1d89..d3cd048 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText.java
@@ -19,6 +19,8 @@
  */
 package com.aelitis.azureus.ui.swt.skin;
 
+import org.eclipse.swt.graphics.Color;
+
 /**
  * @author TuxPaper
  * @created Aug 4, 2006
@@ -53,4 +55,20 @@ public interface SWTSkinObjectText
 	 * @since 4.1.0.5
 	 */
 	public String getText();
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.2.0.7
+	 */
+	void addUrlClickedListener(SWTSkinObjectText_UrlClickedListener l);
+
+	/**
+	 * @param l
+	 *
+	 * @since 4.2.0.7
+	 */
+	void removeUrlClickedListener(SWTSkinObjectText_UrlClickedListener l);
+
+	public void setTextColor(Color color);
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText1.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText1.java
index 61b93c0..c928dfc 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText1.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText1.java
@@ -32,9 +32,12 @@ import org.eclipse.swt.widgets.Label;
 
 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.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+
 /**
  * Text Skin Object.  This one uses a label widget.
  * 
@@ -119,7 +122,7 @@ public class SWTSkinObjectText1
 			label.setFont(existingFont);
 		} else {
 			boolean bNewFont = false;
-			int iFontSize = -1;
+			float fontSize = -1;
 			int iFontWeight = -1;
 			String sFontFace = null;
 
@@ -132,19 +135,26 @@ public class SWTSkinObjectText1
 					if (firstChar == '+' || firstChar == '-') {
 						sSize = sSize.substring(1);
 					}
-
-					int iSize = NumberFormat.getInstance(Locale.US).parse(sSize).intValue();
-
-					if (firstChar == '+') {
-						iFontSize = (int) (fd[0].height + iSize);
-					} else if (firstChar == '-') {
-						iFontSize = (int) (fd[0].height - iSize);
+					
+					if (sSize.endsWith("%")) {
+						sSize = sSize.substring(0, sSize.length() - 1);
+						float pctSize = NumberFormat.getInstance(Locale.US).parse(sSize).floatValue();
+						fontSize = FontUtils.getHeight(fd) * pctSize;
 					} else {
-						iFontSize = iSize;
-					}
 
-					if (sSize.endsWith("px")) {
-						iFontSize = Utils.getFontHeightFromPX(label.getFont(), null, iSize);
+  					int iSize = NumberFormat.getInstance(Locale.US).parse(sSize).intValue();
+  
+  					if (firstChar == '+') {
+  						fontSize = (int) (fd[0].height + iSize);
+  					} else if (firstChar == '-') {
+  						fontSize = (int) (fd[0].height - iSize);
+  					} else {
+  						fontSize = iSize;
+  					}
+  
+  					if (sSize.endsWith("px")) {
+  						fontSize = FontUtils.getFontHeightFromPX(label.getFont(), null, iSize);
+  					}
 					}
 
 					bNewFont = true;
@@ -158,7 +168,7 @@ public class SWTSkinObjectText1
 
 			String sStyle = properties.getStringValue(sPrefix + ".style" + suffix);
 			if (sStyle != null) {
-				String[] sStyles = sStyle.toLowerCase().split(",");
+				String[] sStyles = Constants.PAT_SPLIT_COMMA.split(sStyle.toLowerCase());
 				for (int i = 0; i < sStyles.length; i++) {
 					String s = sStyles[i];
 					if (s.equals("bold")) {
@@ -208,8 +218,8 @@ public class SWTSkinObjectText1
 			if (bNewFont) {
 				FontData[] fd = label.getFont().getFontData();
 
-				if (iFontSize > 0) {
-					fd[0].setHeight(iFontSize);
+				if (fontSize > 0) {
+					FontUtils.setFontDataHeight(fd, fontSize);
 				}
 
 				if (iFontWeight >= 0) {
@@ -354,4 +364,22 @@ public class SWTSkinObjectText1
 	public String getText() {
 		return sText;
 	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText#addUrlClickedListener(com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText_UrlClickedListener)
+	public void addUrlClickedListener(SWTSkinObjectText_UrlClickedListener l) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText#removeUrlClickedListener(com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText_UrlClickedListener)
+	public void removeUrlClickedListener(SWTSkinObjectText_UrlClickedListener l) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText#setTextColor(org.eclipse.swt.graphics.Color)
+	public void setTextColor(Color color) {
+		// TODO Auto-generated method stub
+		
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText2.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText2.java
index e6a1225..ff2af66 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText2.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText2.java
@@ -21,6 +21,7 @@ package com.aelitis.azureus.ui.swt.skin;
 
 import java.text.NumberFormat;
 import java.text.ParseException;
+import java.util.ArrayList;
 import java.util.Locale;
 
 import org.eclipse.swt.SWT;
@@ -32,14 +33,15 @@ 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.UrlUtils;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
 
-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.swt.utils.ColorCache;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+import com.aelitis.azureus.util.ConstantsVuze;
 
 /**
  * Text Skin Object.  This one paints text on parent.
@@ -85,6 +87,18 @@ public class SWTSkinObjectText2
 	private GCStringPrinter lastStringPrinter;
 
 	private Color colorUrl;
+	
+	private int alpha = 255;
+	
+	private java.util.List<SWTSkinObjectText_UrlClickedListener> listUrlClickedListeners = new ArrayList<SWTSkinObjectText_UrlClickedListener>();
+
+	private Color colorUrl2;
+
+	private Color explicitColor;
+
+	protected boolean mouseDown;
+
+	private SWTColorWithAlpha colorShadow;
 
 	public SWTSkinObjectText2(SWTSkin skin,
 			final SWTSkinProperties skinProperties, String sID,
@@ -115,8 +129,9 @@ public class SWTSkinObjectText2
 			style |= SWT.TOP;
 		}
 
-		if (skinProperties.getIntValue(sConfigID + ".border", 0) == 1) {
-			style |= SWT.BORDER;
+		int canvasStyle = SWT.DOUBLE_BUFFERED;
+		if (skinProperties.getIntValue(sConfigID + ".border", 0) == 1 || skin.DEBUGLAYOUT) {
+			canvasStyle |= SWT.BORDER;
 		}
 
 		String sAntiAlias = skinProperties.getStringValue(sConfigID + ".antialias",
@@ -136,12 +151,15 @@ public class SWTSkinObjectText2
 			createOn = (Composite) parent.getControl();
 		}
 
-		canvas = new Canvas(createOn, SWT.DOUBLE_BUFFERED) {
+		canvas = new Canvas(createOn, canvasStyle) {
 			Point ptMax = new Point(0, 0);
 
 			// @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
 			public Point computeSize(int wHint, int hHint, boolean changed) {
 				int border = getBorderWidth() * 2;
+				if (border == 0 && (canvas.getStyle() & SWT.BORDER) > 0) {
+					border = 2;
+				}
 				Point pt = new Point(border, border);
 
 				if (sDisplayText == null) {
@@ -166,9 +184,11 @@ public class SWTSkinObjectText2
 					}
 				}
 
+				gc.setAlpha(alpha);
+
 				GCStringPrinter sp = new GCStringPrinter(gc, sDisplayText,
-						new Rectangle(0, 0, wHint == -1 ? 999999 : wHint, hHint == -1
-								? 999999 : hHint), true, false, style & SWT.WRAP);
+						new Rectangle(0, 0, wHint == -1 ? 3000 : wHint, hHint == -1
+								? 3000 : hHint), true, false, style & SWT.WRAP);
 				sp.calculateMetrics();
 				pt = sp.getCalculatedSize();
 				pt.x += border + hpadding * 2;
@@ -228,25 +248,36 @@ public class SWTSkinObjectText2
 		}
 
 		canvas.addMouseListener(new MouseListener() {
+			private String lastDownURL;
+
 			public void mouseUp(MouseEvent e) {
+				mouseDown = false;
 				if (lastStringPrinter != null) {
 					URLInfo hitUrl = lastStringPrinter.getHitUrl(e.x, e.y);
 					if (hitUrl != null) {
+
+						SWTSkinObjectText_UrlClickedListener[] listeners = listUrlClickedListeners.toArray(new SWTSkinObjectText_UrlClickedListener[0]);
+						for (SWTSkinObjectText_UrlClickedListener l : listeners) {
+							if (l.urlClicked(hitUrl)) {
+								return;
+							}
+						}
+
 						String url = hitUrl.url;
 						try {
-  						ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetworkForURL(url);
-  						if (cn != null) {
-  							url = cn.appendURLSuffix(url, false, false);
-  						}
-  						if (url.contains("?")) {
-  							url += "&";
-  						} else {
-  							url += "?";
-  						}
-  						url += "fromWeb=false&os.name=" + UrlUtils.encode(Constants.OSName)
-  								+ "&os.version="
-  								+ UrlUtils.encode(System.getProperty("os.version"))
-  								+ "&java.version=" + UrlUtils.encode(Constants.JAVA_VERSION); 
+							if (url.startsWith("/")) {
+								url = ConstantsVuze.getDefaultContentNetwork().getExternalSiteRelativeURL(
+										url, true);
+							}
+
+							if (url.contains("?")) {
+								url += "&";
+							} else {
+								url += "?";
+							}
+							url += "fromWeb=false&os.version="
+									+ UrlUtils.encode(System.getProperty("os.version"))
+									+ "&java.version=" + UrlUtils.encode(Constants.JAVA_VERSION);
 						} catch (Throwable t) {
 							// ignore
 						}
@@ -256,6 +287,16 @@ public class SWTSkinObjectText2
 			}
 
 			public void mouseDown(MouseEvent e) {
+				mouseDown = true;
+				if (lastStringPrinter != null) {
+					URLInfo hitUrl = lastStringPrinter.getHitUrl(e.x, e.y);
+					String curURL = hitUrl == null ? "" : hitUrl.url;
+					
+					if (curURL.equals(lastDownURL)) {
+						lastDownURL = curURL;
+						canvas.redraw();
+					}
+				}
 			}
 
 			public void mouseDoubleClick(MouseEvent e) {
@@ -271,6 +312,21 @@ public class SWTSkinObjectText2
 				}
 			}
 		});
+		
+		if (skinProperties.getBooleanValue(sConfigID + ".clipboardmenu", false)) {
+			Menu menu = new Menu(canvas);
+			MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
+			Messages.setLanguageText(menuItem, "MyTorrentsView.menu.thisColumn.toClipboard");
+			menuItem.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					ClipboardCopy.copyToClipBoard(getText());
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+			canvas.setMenu(menu);
+		}
 
 		setAlwaysHookPaintListener(true);
 
@@ -279,10 +335,14 @@ public class SWTSkinObjectText2
 
 	public String switchSuffix(String suffix, int level, boolean walkUp,
 			boolean walkDown) {
+		String oldSuffix = getSuffix();
 		suffix = super.switchSuffix(suffix, level, walkUp, walkDown);
 		if (suffix == null) {
 			return null;
 		}
+		if (suffix.equals(oldSuffix)) {
+			return suffix;
+		}
 
 		String sPrefix = sConfigID + ".text";
 
@@ -313,13 +373,28 @@ public class SWTSkinObjectText2
 		Color newColorURL = properties.getColor(sPrefix + ".urlcolor" + suffix);
 		if (newColorURL != null) {
 			colorUrl = newColorURL;
+		} else {
+			colorUrl = properties.getColor(sPrefix + ".urlcolor");
+		}
+
+		Color newColorURL2 = properties.getColor(sPrefix + ".urlcolor-pressed");
+		if (newColorURL2 != null) {
+			colorUrl2 = newColorURL2;
 		}
 
-		Color color = properties.getColor(sPrefix + ".color" + suffix);
-		//System.out.println(this + "; " + sPrefix + ";" + suffix + "; " + color + "; " + text);
-		if (color != null) {
-			canvas.setData("color", color);
+		if ( explicitColor == null ){
+			Color color = properties.getColor(sPrefix + ".color" + suffix);
+			if (debug) {
+			System.out.println(this + "; " + sPrefix + ";" + suffix + "; " + color + "; " + getText());
+			}
+			if (color != null) {
+				canvas.setData("color", color);
+			} else {
+				canvas.setData("color", properties.getColor(sPrefix + ".color"));
+			}
 		}
+		
+		alpha  = properties.getIntValue(sConfigID + ".alpha", 255);
 
 		hpadding = properties.getIntValue(sPrefix + ".h-padding", 0);
 		vpadding = properties.getIntValue(sPrefix + ".v-padding", 0);
@@ -329,7 +404,7 @@ public class SWTSkinObjectText2
 			canvas.setData("font", existingFont);
 		} else {
 			boolean bNewFont = false;
-			int iFontSize = -1;
+			float fontSize = -1;
 			int iFontWeight = -1;
 			String sFontFace = null;
 			FontData[] tempFontData = canvas.getFont().getFontData();
@@ -343,7 +418,7 @@ public class SWTSkinObjectText2
 			String sStyle = properties.getStringValue(sPrefix + ".style" + suffix);
 			if (sStyle != null) {
 				isAllcaps = false;
-				String[] sStyles = sStyle.toLowerCase().split(",");
+				String[] sStyles = Constants.PAT_SPLIT_COMMA.split(sStyle.toLowerCase());
 				for (int i = 0; i < sStyles.length; i++) {
 					String s = sStyles[i];
 
@@ -409,6 +484,12 @@ public class SWTSkinObjectText2
 				this.sDisplayText = isAllcaps && sText != null ? sText.toUpperCase()
 						: sText;
 			}
+			
+			colorShadow = properties.getColorWithAlpha(sPrefix + ".shadow");
+			if (colorShadow.color != null) {
+				hasShadow = true;
+			}
+
 
 			if (iFontWeight >= 0) {
 				tempFontData[0].setStyle(iFontWeight);
@@ -418,26 +499,35 @@ public class SWTSkinObjectText2
 			if (sSize != null) {
 				FontData[] fd = canvas.getFont().getFontData();
 
+				sSize = sSize.trim();
 				try {
 					char firstChar = sSize.charAt(0);
+					char lastChar = sSize.charAt(sSize.length() - 1);
 					if (firstChar == '+' || firstChar == '-') {
 						sSize = sSize.substring(1);
+					} else if (lastChar == '%') {
+						sSize = sSize.substring(0, sSize.length() - 1);
 					}
 
-					double dSize = NumberFormat.getInstance(Locale.US).parse(sSize).doubleValue();
+					float dSize = NumberFormat.getInstance(Locale.US).parse(sSize).floatValue();
 
-					if (firstChar == '+') {
-						iFontSize = (int) (fd[0].height + dSize);
+					if (lastChar == '%') {
+						fontSize = FontUtils.getHeight(fd) * (dSize / 100);
+					} else if (firstChar == '+') {
+						//int curPX = FontUtils.getFontHeightInPX(tempFontData);
+						//fontSize = FontUtils.getFontHeightFromPX(canvas.getDisplay(),
+						//		tempFontData, null, (int) (curPX + dSize));
+						fontSize = (int) (fd[0].height + dSize);
 					} else if (firstChar == '-') {
-						iFontSize = (int) (fd[0].height - dSize);
+						fontSize = (int) (fd[0].height - dSize);
 					} else {
 						if (sSize.endsWith("px")) {
 							//iFontSize = Utils.getFontHeightFromPX(canvas.getFont(), null, (int) dSize);
-							iFontSize = Utils.getFontHeightFromPX(canvas.getDisplay(),
+							fontSize = FontUtils.getFontHeightFromPX(canvas.getDisplay(),
 									tempFontData, null, (int) dSize);
 							//iFontSize = Utils.pixelsToPoint(dSize, canvas.getDisplay().getDPI().y);
 						} else {
-							iFontSize = (int) dSize;
+							fontSize = (int) dSize;
 						}
 					}
 
@@ -453,8 +543,8 @@ public class SWTSkinObjectText2
 			if (bNewFont) {
 				FontData[] fd = canvas.getFont().getFontData();
 
-				if (iFontSize > 0) {
-					fd[0].setHeight(iFontSize);
+				if (fontSize > 0) {
+					FontUtils.setFontDataHeight(fd, fontSize);
 				}
 
 				if (iFontWeight >= 0) {
@@ -497,13 +587,18 @@ public class SWTSkinObjectText2
 				: sText;
 		this.sKey = null;
 		bIsTextDefault = false;
+
 		// Doing execSWTThreadLater delays the relayout for too long at skin startup
 		// Since there are a lot of async execs at skin startup, we generally
 		// see the window a second or two before this async call would get called
 		// (if it were async)
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
+				// lastStringPrinter must be set while in SWT Thread otherwise
+				// sync issues happen
+				lastStringPrinter = null;
 				if (canvas != null && !canvas.isDisposed()) {
+					canvas.setCursor(null);
 					canvas.redraw();
 					if (relayoutOnTextChange) {
 						Utils.relayout(canvas);
@@ -523,6 +618,7 @@ public class SWTSkinObjectText2
 
 		Composite composite = (Composite) control;
 		Rectangle clientArea = composite.getClientArea();
+		
 		clientArea.x += hpadding;
 		clientArea.width -= hpadding * 2;
 		clientArea.y += vpadding;
@@ -535,6 +631,9 @@ public class SWTSkinObjectText2
 			gc.setFont(existingFont);
 		}
 
+		if (debug) {
+			System.out.println("paint " + existingColor + ";" + gc.getForeground());
+		}
 		if (existingColor != null) {
 			gc.setForeground(existingColor);
 		}
@@ -552,28 +651,47 @@ public class SWTSkinObjectText2
 					clientArea.width, clientArea.height);
 
 			Color foreground = gc.getForeground();
-			Color color = ColorCache.getColor(gc.getDevice(), 0, 0, 0);
-			gc.setForeground(color);
-			gc.setAlpha(64);
+			if (colorShadow.color == null) {
+  			Color color = ColorCache.getColor(gc.getDevice(), 0, 0, 0);
+  			gc.setForeground(color);
+  			gc.setAlpha(64);
+			} else {
+				gc.setForeground(colorShadow.color);
+				gc.setAlpha(colorShadow.alpha);
+			}
 			GCStringPrinter.printString(gc, sDisplayText, r, true, false, style);
-			gc.setAlpha(255);
 			gc.setForeground(foreground);
 		}
 
+		gc.setAlpha(alpha);
 		lastStringPrinter = new GCStringPrinter(gc, sDisplayText, clientArea, true,
 				false, style);
 		if (colorUrl != null) {
 			lastStringPrinter.setUrlColor(colorUrl);
 		}
+		if (colorUrl2 != null && mouseDown) {
+			lastStringPrinter.calculateMetrics();
+			Display display = Display.getCurrent();
+			Point cursorLocation = canvas.toControl(display.getCursorLocation());
+			URLInfo hitUrl = lastStringPrinter.getHitUrl(cursorLocation.x, cursorLocation.y);
+			if (hitUrl != null) {
+				hitUrl.urlColor = colorUrl2;
+			}
+		}
+		
 		lastStringPrinter.printString();
 	}
 
 	public void setTextID(String key) {
+		setTextID(key, false);
+	}
+
+	private void setTextID(String key, boolean forceRefresh) {
 		if (key == null) {
 			setText("");
 		}
 
-		else if (key.equals(sKey)) {
+		else if (!forceRefresh && key.equals(sKey)) {
 			return;
 		}
 
@@ -633,7 +751,7 @@ public class SWTSkinObjectText2
 	public void triggerListeners(int eventType, Object params) {
 		if (eventType == SWTSkinObjectListener.EVENT_LANGUAGE_CHANGE) {
 			if (sKey != null) {
-				setTextID(sKey);
+				setTextID(sKey, true);
 			}
 		}
 		super.triggerListeners(eventType, params);
@@ -651,4 +769,26 @@ public class SWTSkinObjectText2
 	public String getText() {
 		return sDisplayText;
 	}
+	
+	public void addUrlClickedListener(SWTSkinObjectText_UrlClickedListener l) {
+		listUrlClickedListeners.add(l);
+	}
+	
+	public void removeUrlClickedListener(SWTSkinObjectText_UrlClickedListener l) {
+		listUrlClickedListeners.remove(l);
+	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText#setTextColor(org.eclipse.swt.graphics.Color)
+	public void setTextColor(final Color color) {
+		explicitColor = color;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (canvas == null || canvas.isDisposed()) {
+					return;
+				}
+				canvas.setData("color", color);
+				canvas.redraw();
+			}
+		});
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText_UrlClickedListener.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText_UrlClickedListener.java
new file mode 100644
index 0000000..f7c1747
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectText_UrlClickedListener.java
@@ -0,0 +1,36 @@
+/**
+ * Created on Jan 15, 2010
+ *
+ * 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.skin;
+
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
+
+/**
+ * @author TuxPaper
+ * @created Jan 15, 2010
+ *
+ */
+public interface SWTSkinObjectText_UrlClickedListener
+{
+	/**
+	 * 
+	 * @param urlInfo
+	 * @return true = url processed; false = do default
+	 */
+	public boolean urlClicked(URLInfo urlInfo);
+}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTextbox.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTextbox.java
new file mode 100644
index 0000000..c237641
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectTextbox.java
@@ -0,0 +1,251 @@
+/**
+ * Created on Sep 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.skin;
+
+import java.util.Arrays;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+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.*;
+
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.ui.swt.Utils;
+
+/**
+ * Native checkbox
+ * 
+ * @author TuxPaper
+ * @created Dec 24, 2008
+ *
+ */
+public class SWTSkinObjectTextbox
+	extends SWTSkinObjectBasic
+{
+	private Text textWidget;
+	
+	private Composite cBubble;
+	
+	private String 	text = "";
+	
+	public SWTSkinObjectTextbox(SWTSkin skin, SWTSkinProperties properties,
+			String id, String configID, SWTSkinObject parentSkinObject) {
+		super(skin, properties, id, configID, "textbox", parentSkinObject);
+
+		Composite createOn;
+		if (parent == null) {
+			createOn = skin.getShell();
+		} else {
+			createOn = (Composite) parent.getControl();
+		}
+		
+		int style = SWT.BORDER;
+		
+		String styleString = properties.getStringValue(sConfigID + ".style");
+		if (styleString != null) {
+			String[] styles = Constants.PAT_SPLIT_COMMA.split(styleString.toLowerCase());
+			Arrays.sort(styles);
+			if (Arrays.binarySearch(styles, "readonly") >= 0) {
+				style |= SWT.READ_ONLY;
+			}
+			if (Arrays.binarySearch(styles, "wrap") >= 0) {
+				style |= SWT.WRAP;
+			}
+			if (Arrays.binarySearch(styles, "multiline") >= 0) {
+				style |= SWT.MULTI | SWT.V_SCROLL;
+			} else {
+				style |= SWT.SINGLE;
+			}
+			if (Arrays.binarySearch(styles, "search") >= 0) {
+				style |= SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL;
+				if (Constants.isWindows) {
+					cBubble = new Composite(createOn, SWT.NONE);
+					cBubble.setLayout(new FormLayout());
+				}
+			}
+		}
+		
+		if ((style & SWT.WRAP) == 0 && (style & SWT.MULTI) > 0) {
+			style |= SWT.H_SCROLL;
+		}
+
+
+		if (cBubble == null) {
+			textWidget = new Text(createOn, style);
+		} else {
+			textWidget = new Text(cBubble, style & ~(SWT.BORDER | SWT.SEARCH));
+			
+			FormData fd = new FormData();
+			fd.top = new FormAttachment(0, 2);
+			fd.bottom = new FormAttachment(100, -2);
+			fd.left = new FormAttachment(0, 17);
+			fd.right = new FormAttachment(100, -14);
+			textWidget.setLayoutData(fd);
+
+			cBubble.addPaintListener(new PaintListener() {
+				public void paintControl(PaintEvent e) {
+					Rectangle clientArea = cBubble.getClientArea();
+					e.gc.setBackground(textWidget.getBackground());
+					e.gc.setAdvanced(true);
+					e.gc.setAntialias(SWT.ON);
+					e.gc.fillRoundRectangle(clientArea.x, clientArea.y,
+							clientArea.width - 1, clientArea.height - 1, clientArea.height,
+							clientArea.height);
+					e.gc.setAlpha(127);
+					e.gc.drawRoundRectangle(clientArea.x, clientArea.y,
+							clientArea.width - 1, clientArea.height - 1, clientArea.height,
+							clientArea.height);
+
+					e.gc.setLineCap(SWT.CAP_ROUND);
+
+					int iconHeight = clientArea.height - 9;
+					if (iconHeight > 13) {
+						iconHeight = 13;
+					}
+					int iconY = clientArea.y + ((clientArea.height - iconHeight + 1) / 2);
+					
+					e.gc.setAlpha(120);
+					e.gc.setLineWidth(2);
+					e.gc.drawOval(clientArea.x + 6, iconY, 7, 6); 
+					e.gc.drawPolyline(new int[] {
+						clientArea.x + 12,
+						iconY + 6,
+						clientArea.x + 15,
+						iconY + iconHeight,
+					});
+					
+					boolean textIsBlank = text.length() == 0;
+					if (!textIsBlank) {
+						//e.gc.setLineWidth(1);
+						e.gc.setAlpha(80);
+						Rectangle rXArea = new Rectangle(clientArea.x + clientArea.width
+								- 16, clientArea.y + 1, 11, clientArea.height - 2);
+						cBubble.setData("XArea", rXArea);
+
+						e.gc.drawPolyline(new int[] {
+							clientArea.x + clientArea.width - 7,
+							clientArea.y + 7,
+							clientArea.x + clientArea.width - (7 + 5),
+							clientArea.y + clientArea.height - 7,
+						});
+						e.gc.drawPolyline(new int[] {
+							clientArea.x + clientArea.width - 7,
+							clientArea.y + clientArea.height - 7,
+							clientArea.x + clientArea.width - (7 + 5),
+							clientArea.y + 7,
+						});
+					}
+				}
+			});
+			
+			cBubble.addListener(SWT.MouseDown, new Listener() {
+				public void handleEvent(Event event) {
+					Rectangle r = (Rectangle) event.widget.getData("XArea");
+					if (r != null && r.contains(event.x, event.y)) {
+						textWidget.setText("");
+					}
+				}
+			});
+			
+				// pick up changes in the text control's bg color and propagate to the bubble
+			
+			textWidget.addPaintListener(
+				new PaintListener()
+				{
+					private Color existing_bg;
+					
+					public void 
+					paintControl(
+						PaintEvent arg0 )
+					{
+						Color current_bg = textWidget.getBackground();
+						
+						if ( current_bg != existing_bg ){
+							
+							existing_bg = current_bg;
+							
+							cBubble.redraw();
+						}
+					}
+				});
+		}
+		
+		textWidget.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				boolean textWasBlank = text.length() == 0;
+				text = textWidget.getText();
+				boolean textIsBlank = text.length() == 0;
+				if (textWasBlank != textIsBlank && cBubble != null) {
+					cBubble.redraw();
+				}
+			}
+		});
+		
+		String message = properties.getStringValue(configID + ".message", (String) null);
+		if (message != null && message.length() > 0) {
+			textWidget.setMessage(message);
+		}
+
+		setControl(cBubble == null ? textWidget : cBubble);
+	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBasic#switchSuffix(java.lang.String, int, boolean)
+	public String switchSuffix(String suffix, int level, boolean walkUp,
+			boolean walkDown) {
+		suffix = super.switchSuffix(suffix, level, walkUp, walkDown);
+
+		if (suffix == null) {
+			return null;
+		}
+
+		String sPrefix = sConfigID + ".text";
+		String text = properties.getStringValue(sPrefix + suffix);
+		if (text != null) {
+			setText(text);
+		}
+
+		return suffix;
+	}
+
+	public void setText(final String val) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (textWidget != null && !textWidget.isDisposed()) {
+					textWidget.setText(val == null ? "" : val);
+					text = val;
+				}
+			}
+		});
+
+	}
+
+	public String getText() {
+		return text;
+	}
+
+	public Text getTextControl() {
+		return textWidget;
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectToggle.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectToggle.java
new file mode 100644
index 0000000..8802fdb
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinObjectToggle.java
@@ -0,0 +1,137 @@
+/**
+ * Created on Sep 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.skin;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.Utils;
+
+/**
+ * Native Toggle
+ * 
+ * @author TuxPaper
+ *
+ */
+public class SWTSkinObjectToggle
+	extends SWTSkinObjectBasic
+{
+	private Button button;
+
+	// stored so we can access it after button is disposed, and so we can
+	// retrieve without being on SWT thread
+	private boolean isToggled;
+
+	private List<SWTSkinToggleListener> buttonListeners = new CopyOnWriteArrayList();
+
+	public SWTSkinObjectToggle(SWTSkin skin, SWTSkinProperties properties,
+			String id, String configID, SWTSkinObject parentSkinObject) {
+		super(skin, properties, id, configID, "toggle", parentSkinObject);
+
+		Composite createOn;
+		if (parent == null) {
+			createOn = skin.getShell();
+		} else {
+			createOn = (Composite) parent.getControl();
+		}
+		
+		// WinXP Classic Theme will not bring though parent's background image
+		// without FORCEing the background mode
+		createOn.setBackgroundMode(SWT.INHERIT_FORCE);
+
+		button = new Button(createOn, SWT.TOGGLE);
+		isToggled = false;
+
+		button.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				isToggled = button.getSelection();
+				for (SWTSkinToggleListener l : buttonListeners) {
+					try {
+						l.toggleChanged(SWTSkinObjectToggle.this, isToggled);
+					} catch (Exception ex) {
+						Debug.out(ex);
+					}
+				}
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		setControl(button);
+	}
+
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBasic#switchSuffix(java.lang.String, int, boolean)
+	public String switchSuffix(String suffix, int level, boolean walkUp,
+			boolean walkDown) {
+		suffix = super.switchSuffix(suffix, level, walkUp, walkDown);
+
+		if (suffix == null) {
+			return null;
+		}
+
+		String sPrefix = sConfigID + ".text";
+		String text = properties.getStringValue(sPrefix + suffix);
+		if (text != null) {
+			setText(text);
+		}
+
+		return suffix;
+	}
+
+	public void addSelectionListener(SWTSkinToggleListener listener) {
+		if (buttonListeners.contains(listener)) {
+			return;
+		}
+		buttonListeners.add(listener);
+	}
+
+	public void setText(final String text) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (button != null && !button.isDisposed()) {
+					button.setText(text);
+				}
+			}
+		});
+
+	}
+
+	public boolean isToggled() {
+		return isToggled;
+	}
+	
+	public void setToggled(boolean b) {
+		isToggled = b;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (button != null && !button.isDisposed()) {
+					button.setSelection(isToggled);
+				}
+			}
+		});
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinProperties.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinProperties.java
index 7e20762..0c03180 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinProperties.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinProperties.java
@@ -43,4 +43,13 @@ public interface SWTSkinProperties
 
 
 	public Color getColor(String name, Color def);
+
+
+	/**
+	 * @param sID
+	 * @return
+	 *
+	 * @since 4.4.0.7
+	 */
+	SWTColorWithAlpha getColorWithAlpha(String sID);
 }
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesClone.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesClone.java
index 9673714..d5bfff1 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesClone.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesClone.java
@@ -84,6 +84,27 @@ public class SWTSkinPropertiesClone
 		properties.addProperty(sCloneConfigID + name, value);
 	}
 
+	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinProperties#getColorWithAlpha(java.lang.String)
+	public SWTColorWithAlpha getColorWithAlpha(String name) {
+		if (name == null) {
+			return null;
+		}
+		if (DEBUG) {
+			checkName(name);
+		}
+		if (name.length() > 0 && name.charAt(0) != '.') {
+			return properties.getColorWithAlpha(name);
+		}
+
+
+		SWTColorWithAlpha val = properties.getColorWithAlpha(sCloneConfigID + name);
+		if (val != null) {
+			return val;
+		}
+
+		return properties.getColorWithAlpha(sTemplateConfigID + name);
+	}
+
 	public Color getColor(String name) {
 		if (name == null) {
 			return null;
@@ -343,10 +364,14 @@ public class SWTSkinPropertiesClone
 	}
 	
 	// @see com.aelitis.azureus.ui.skin.SkinProperties#addResourceBundle(java.util.ResourceBundle)
-	public void addResourceBundle(ResourceBundle subBundle) {
-		properties.addResourceBundle(subBundle);
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath) {
+		properties.addResourceBundle(subBundle, skinPath);
 	}
 	
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath,
+			ClassLoader loader) {
+		properties.addResourceBundle(subBundle, skinPath,loader);
+	}
 	// @see com.aelitis.azureus.ui.skin.SkinProperties#getClassLoader()
 	public ClassLoader getClassLoader() {
 		return properties.getClassLoader();
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesImpl.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesImpl.java
index 6a62c59..8d85433 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesImpl.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesImpl.java
@@ -25,6 +25,8 @@ import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.widgets.Display;
 
 import org.gudy.azureus2.core3.util.LightHashMap;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 import com.aelitis.azureus.ui.skin.SkinPropertiesImpl;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
@@ -38,7 +40,7 @@ public class SWTSkinPropertiesImpl
 	extends SkinPropertiesImpl
 	implements SWTSkinProperties
 {
-	private static Map colorMap = new LightHashMap();
+	private static Map<String, SWTColorWithAlpha> colorMap = new LightHashMap<String, SWTColorWithAlpha>();
 
 	/**
 	 * @param skinPath
@@ -57,18 +59,25 @@ public class SWTSkinPropertiesImpl
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinProperties#getColor(java.lang.String)
 	public Color getColor(String sID) {
+		return getColorWithAlpha(sID).color;
+	}
+
+	public SWTColorWithAlpha getColorWithAlpha(String sID) {
 		Color color;
 		if (colorMap.containsKey(sID)) {
-			return (Color) colorMap.get(sID);
+			return colorMap.get(sID);
 		}
 
+		int alpha = 255;
 		try {
 			int[] rgb = getColorValue(sID);
 			if (rgb[0] > -1) {
-				color = ColorCache.getColor(Display.getCurrent(), rgb[0], rgb[1],
-						rgb[2]);
+				color = ColorCache.getSchemedColor(Utils.getDisplay(), rgb[0], rgb[1], rgb[2]);
+				if (rgb.length > 3) {
+					alpha = rgb[3];
+				}
 			} else {
-				color = ColorCache.getColor(Display.getCurrent(), getStringValue(sID));
+				color = ColorCache.getColor(Utils.getDisplay(), getStringValue(sID));
 			}
 		} catch (Exception e) {
 			//				IMP.getLogger().log(LoggerChannel.LT_ERROR,
@@ -76,11 +85,17 @@ public class SWTSkinPropertiesImpl
 			color = null;
 		}
 
-		colorMap.put(sID, color);
+		SWTColorWithAlpha colorInfo = new SWTColorWithAlpha(color, alpha);
+		colorMap.put(sID, colorInfo);
 
-		return color;
+		return colorInfo;
 	}
 
+	public void clearCache() {
+		super.clearCache();
+		colorMap.clear();
+	}
+	
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinProperties#getColor(java.lang.String, org.eclipse.swt.graphics.Color)
 	public Color getColor(String name, Color def) {
 		Color color = getColor(name);
@@ -89,6 +104,4 @@ public class SWTSkinPropertiesImpl
 		}
 		return color;
 	}
-	
-	
 }
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesParamImpl.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesParamImpl.java
index 5081a67..72b48a7 100644
--- a/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesParamImpl.java
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinPropertiesParamImpl.java
@@ -55,6 +55,10 @@ public class SWTSkinPropertiesParamImpl
 		return properties.getColor(name);
 	}
 
+	public SWTColorWithAlpha getColorWithAlpha(String sID) {
+		return properties.getColorWithAlpha(sID);
+	}
+
 	public int[] getColorValue(String name) {
 		return properties.getColorValue(name);
 	}
@@ -119,10 +123,14 @@ public class SWTSkinPropertiesParamImpl
 	}
 
 	// @see com.aelitis.azureus.ui.skin.SkinProperties#addResourceBundle(java.util.ResourceBundle)
-	public void addResourceBundle(ResourceBundle subBundle) {
-		properties.addResourceBundle(subBundle);
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath) {
+		properties.addResourceBundle(subBundle, skinPath);
 	}
 
+	public void addResourceBundle(ResourceBundle subBundle, String skinPath,
+			ClassLoader loader) {
+		properties.addResourceBundle(subBundle, skinPath,loader);
+	}
 	// @see com.aelitis.azureus.ui.skin.SkinProperties#getClassLoader()
 	public ClassLoader getClassLoader() {
 		return properties.getClassLoader();
diff --git a/com/aelitis/azureus/ui/swt/skin/SWTSkinToggleListener.java b/com/aelitis/azureus/ui/swt/skin/SWTSkinToggleListener.java
new file mode 100644
index 0000000..14b3703
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/skin/SWTSkinToggleListener.java
@@ -0,0 +1,27 @@
+/**
+ * Created on Dec 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.ui.swt.skin;
+
+/**
+ * @author TuxPaper
+ */
+public interface SWTSkinToggleListener
+{
+	public void toggleChanged(SWTSkinObjectToggle so, boolean toggled);
+}
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionMDIEntry.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionMDIEntry.java
new file mode 100644
index 0000000..6654957
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionMDIEntry.java
@@ -0,0 +1,721 @@
+package com.aelitis.azureus.ui.swt.subscriptions;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+
+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.*;
+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.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInputReceiver;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+
+import com.aelitis.azureus.core.metasearch.Engine;
+import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
+import com.aelitis.azureus.core.subs.*;
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+
+public class SubscriptionMDIEntry implements SubscriptionListener
+{
+	private static final String ALERT_IMAGE_ID	= "image.sidebar.vitality.alert";
+	private static final String AUTH_IMAGE_ID	= "image.sidebar.vitality.auth";
+
+	private final MdiEntry mdiEntry;
+
+	MdiEntryVitalityImage spinnerImage;
+
+	private MdiEntryVitalityImage warningImage;
+	private final Subscription subs;
+	private String key;
+
+	public SubscriptionMDIEntry(Subscription subs, MdiEntry entry) {
+		this.subs = subs;
+		this.mdiEntry = entry;
+		key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());
+		setupMdiEntry();
+	}
+	
+	private void setupMdiEntry() {
+		if (mdiEntry == null) {
+			return;
+		}
+
+		mdiEntry.setImageLeftID("image.sidebar.subscriptions");
+		
+		warningImage = mdiEntry.addVitalityImage( ALERT_IMAGE_ID );
+		
+		spinnerImage = mdiEntry.addVitalityImage("image.sidebar.vitality.dots");
+		
+		if (spinnerImage != null) {
+			spinnerImage.setVisible(false);
+		}
+		
+		setWarning();
+
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+		UIManager uim = pi.getUIManager();
+		
+		final MenuManager menuManager = uim.getMenuManager();
+		
+		MenuItem menuItem;
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.forcecheck");
+		menuItem.setText(MessageText.getString("Subscription.menu.forcecheck"));
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				try {
+					subs.getManager().getScheduler().downloadAsync( subs, true );
+				} catch (SubscriptionException e) {
+					Debug.out(e);
+				}
+			}
+		});
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.clearall");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				subs.getHistory().markAllResultsRead();
+				refreshView();
+			}
+		});
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.dirtyall");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				subs.getHistory().markAllResultsUnread();
+				refreshView();
+			}
+		});
+
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.deleteall");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				subs.getHistory().deleteAllResults();
+				refreshView();
+			}
+		});
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.reset");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				subs.getHistory().reset();
+				try{
+					subs.getEngine().reset();
+				}catch( Throwable e ){
+					Debug.printStackTrace(e);
+				}
+				try{
+					subs.getManager().getScheduler().downloadAsync(subs, true);
+					
+				}catch( Throwable e ){
+					
+					Debug.out(e);
+				}
+			}
+		});
+
+		try{
+			Engine engine = subs.getEngine();
+				
+			if ( engine instanceof WebEngine ){
+				
+				if (((WebEngine)engine).isNeedsAuth()){
+					
+					menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.resetauth");
+					menuItem.addListener(new SubsMenuItemListener() {
+						public void selected(MdiEntry info, Subscription subs) {
+							try{
+								Engine engine = subs.getEngine();
+								
+								if ( engine instanceof WebEngine ){
+									
+									((WebEngine)engine).setCookies( null );
+								}
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+							}
+							
+							try{
+								subs.getManager().getScheduler().downloadAsync(subs, true);
+								
+							}catch( Throwable e ){
+								
+								Debug.out(e);
+							}
+						}
+					});
+					
+					menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.setcookies");
+					menuItem.addListener(new SubsMenuItemListener() {
+						public void selected(MdiEntry info, final Subscription subs) {
+							try{
+								Engine engine = subs.getEngine();
+								
+								if ( engine instanceof WebEngine ){
+									
+									final WebEngine we = (WebEngine)engine;
+									
+									UISWTInputReceiver entry = new SimpleTextEntryWindow();
+									
+									String[] req = we.getRequiredCookies();
+									
+									String	req_str = "";
+									
+									for ( String r:req ){
+										
+										req_str += (req_str.length()==0?"":";") + r + "=?";
+									}
+									entry.setPreenteredText( req_str, true );
+									entry.maintainWhitespace(false);
+									entry.allowEmptyInput( false );
+									entry.setTitle("general.enter.cookies");
+									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 ){
+								
+								Debug.printStackTrace(e);
+							}
+						}
+					});
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+		}
+		
+			// sep
+		
+		menuManager.addMenuItem("sidebar." + key,"s1").setStyle( MenuItem.STYLE_SEPARATOR );
+
+			// category
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key, "MyTorrentsView.menu.setCategory");
+		menuItem.setStyle( MenuItem.STYLE_MENU );
+		
+		menuItem.addFillListener(
+				new MenuItemFillListener()
+				{
+					public void 
+					menuWillBeShown(
+						MenuItem 	menu, 
+						Object 		data ) 
+					{		
+						addCategorySubMenu( menuManager, menu );
+					}
+				});
+		
+		
+		if ( subs.isUpdateable()){
+			
+			menuItem = menuManager.addMenuItem("sidebar." + key,"MyTorrentsView.menu.rename");
+			menuItem.addListener(new SubsMenuItemListener() {
+				public void selected(MdiEntry info, final Subscription subs) {
+					UISWTInputReceiver entry = new SimpleTextEntryWindow();
+					entry.setPreenteredText(subs.getName(), false );
+					entry.maintainWhitespace(false);
+					entry.allowEmptyInput( false );
+					entry.setLocalisedTitle(MessageText.getString("label.rename",
+							new String[] {
+								subs.getName()
+							}));
+					entry.prompt(new UIInputReceiverListener() {
+						public void UIInputReceiverClosed(UIInputReceiver entry) {
+							if (!entry.hasSubmittedInput()){
+								
+								return;
+							}
+							
+							String input = entry.getSubmittedInput().trim();
+							
+							if ( input.length() > 0 ){
+								
+								try{
+									subs.setName( input );
+									
+								}catch( Throwable e ){
+									
+									Debug.printStackTrace(e);
+								}
+							}
+						}
+					});
+				}
+			});
+		}
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.upgrade");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				subs.resetHighestVersion();
+			}
+		});
+			
+		menuItem.addFillListener(
+			new MenuItemFillListener()
+			{
+				public void 
+				menuWillBeShown(
+					MenuItem 	menu, 
+					Object 		data ) 
+				{									
+					menu.setVisible( subs.getHighestVersion() > subs.getVersion());
+				}
+			});
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.export");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				export();
+			}
+		});
+		
+			// sep
+		
+		menuManager.addMenuItem("sidebar." + key,"s2").setStyle( MenuItem.STYLE_SEPARATOR );
+		
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.remove");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				removeWithConfirm();
+			}
+		});
+		
+		menuManager.addMenuItem("sidebar." + key,"s3").setStyle( MenuItem.STYLE_SEPARATOR );
+
+		menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.properties");
+		menuItem.addListener(new SubsMenuItemListener() {
+			public void selected(MdiEntry info, Subscription subs) {
+				showProperties();
+			}
+		});
+		
+		subs.addListener(this); 
+	}
+
+	public void subscriptionDownloaded(Subscription subs, boolean auto) {
+	}
+	
+	public void subscriptionChanged(Subscription subs) {
+		mdiEntry.redraw();
+		ViewTitleInfoManager.refreshTitleInfo(mdiEntry.getViewTitleInfo());
+	}
+
+	protected void refreshView() {
+		if (!(mdiEntry instanceof BaseMdiEntry)) {
+			return;
+		}
+		UISWTViewEventListener eventListener = ((BaseMdiEntry)mdiEntry).getEventListener();
+		if (eventListener instanceof SubscriptionView) {
+			SubscriptionView subsView = (SubscriptionView) eventListener;
+			subsView.refreshView();
+		}
+	}
+
+	protected void
+	setWarning()
+	{
+			// possible during initialisation, status will be shown again on complete
+		
+		if ( warningImage == null ){
+			
+			return;
+		}
+		
+		SubscriptionHistory history = subs.getHistory();
+		
+		String	last_error = history.getLastError();
+
+		boolean	auth_fail = history.isAuthFail();
+		
+			// don't report problem until its happened a few times, but not for auth fails as this is a perm error
+		
+		if ( history.getConsecFails() < 3 && !auth_fail ){
+			
+			last_error = null;
+		}
+		
+		boolean	trouble = last_error != null;
+		
+		if ( trouble ){
+		 
+			warningImage.setToolTip( last_error );
+			
+			warningImage.setImageID( auth_fail?AUTH_IMAGE_ID:ALERT_IMAGE_ID );
+			
+			warningImage.setVisible( true );
+			
+		}else{
+			
+			warningImage.setVisible( false );
+			
+			warningImage.setToolTip( "" );
+		}
+	}
+
+	private void 
+	addCategorySubMenu(
+		MenuManager				menu_manager,
+		MenuItem				menu )
+	{
+		menu.removeAllChildItems();
+
+		Category[] categories = CategoryManager.getCategories();
+		
+		Arrays.sort( categories );
+
+		MenuItem m;
+
+		if ( categories.length > 0 ){
+			
+			String	assigned_category = subs.getCategory();
+			
+			final Category uncat = CategoryManager.getCategory( Category.TYPE_UNCATEGORIZED );
+						
+			if ( uncat != null ){
+				
+				m = menu_manager.addMenuItem( menu, uncat.getName());
+				
+				m.setStyle( MenuItem.STYLE_RADIO );
+								
+				m.setData( new Boolean( assigned_category == null ));
+				
+				m.addListener(
+					new MenuItemListener() 
+					{
+						public void
+						selected(
+							MenuItem			menu,
+							Object 				target )
+						{
+							assignSelectedToCategory( uncat );
+						}
+					});
+				
+
+				m = menu_manager.addMenuItem( menu, "sep1" );
+				
+				m.setStyle( MenuItem.STYLE_SEPARATOR );
+			}
+
+			for ( int i=0; i<categories.length; i++ ){
+				
+				final Category cat = categories[i];
+				
+				if ( cat.getType() == Category.TYPE_USER) {
+					
+					m = menu_manager.addMenuItem( menu, "!" + cat.getName() + "!" );
+					
+					m.setStyle( MenuItem.STYLE_RADIO );
+										
+					m.setData( new Boolean( assigned_category != null && assigned_category.equals( cat.getName())));
+					
+					m.addListener(
+						new MenuItemListener() 
+						{
+							public void
+							selected(
+								MenuItem			menu,
+								Object 				target )
+							{
+								assignSelectedToCategory( cat );
+							}
+						});
+				}
+			}
+
+			m = menu_manager.addMenuItem( menu, "sep2" );
+			
+			m.setStyle( MenuItem.STYLE_SEPARATOR );
+		}
+
+		m = menu_manager.addMenuItem( menu, "MyTorrentsView.menu.setCategory.add" );
+		
+		m.addListener(
+				new MenuItemListener() 
+				{
+					public void
+					selected(
+						MenuItem			menu,
+						Object 				target )
+					{
+						addCategory( );
+					}
+				});
+
+	}
+
+	private void 
+	addCategory()	
+	{
+		CategoryAdderWindow adderWindow = new CategoryAdderWindow(Display.getDefault());
+		
+		Category newCategory = adderWindow.getNewCategory();
+		
+		if ( newCategory != null ){
+		
+			assignSelectedToCategory( newCategory );
+		}
+	}
+
+	private void 
+	assignSelectedToCategory(
+		Category 			category )
+	{
+		if ( category.getType() == Category.TYPE_UNCATEGORIZED ){
+		
+			subs.setCategory( null );
+			
+		}else{
+			
+			subs.setCategory( category.getName());
+		}
+	}
+
+	protected void export() {
+		Utils.execSWTThread(
+			new AERunnable() 
+			{
+				public void 
+				runSupport()
+				{
+					FileDialog dialog = 
+						new FileDialog( Utils.findAnyShell(), SWT.SYSTEM_MODAL | SWT.SAVE );
+					
+					dialog.setFilterPath( TorrentOpener.getFilterPathData() );
+											
+					dialog.setText(MessageText.getString("subscript.export.select.template.file"));
+					
+					dialog.setFilterExtensions(new String[] {
+							"*.vuze",
+							"*.vuz",
+							Constants.FILE_WILDCARD
+						});
+					dialog.setFilterNames(new String[] {
+							"*.vuze",
+							"*.vuz",
+							Constants.FILE_WILDCARD
+						});
+					
+					String path = TorrentOpener.setFilterPathData( dialog.open());
+
+					if ( path != null ){
+						
+						String lc = path.toLowerCase();
+						
+						if ( !lc.endsWith( ".vuze" ) && !lc.endsWith( ".vuz" )){
+							
+							path += ".vuze";
+						}
+						
+						try{
+							VuzeFile vf = subs.getVuzeFile();
+							
+							vf.write( new File( path ));
+							
+
+						}catch( Throwable e ){
+							
+							Debug.out( e );
+						}
+					}
+				}
+			});
+	}
+
+	protected void
+	removeWithConfirm( )
+	{
+		MessageBoxShell mb = 
+			new MessageBoxShell(
+				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 );
+		
+		mb.open(new UserPrompterResultListener() {
+			public void prompterClosed(int result) {
+				if (result == 0) {
+					subs.setSubscribed( false );
+				}
+			}
+		});
+	}
+	
+	protected void
+	showProperties()
+	{
+		SubscriptionHistory history = subs.getHistory();
+		
+		SimpleDateFormat df = new SimpleDateFormat();
+		
+		String last_error = history.getLastError();
+		
+		if ( last_error == null ){
+			last_error = "";
+		}
+		
+		String	engine_str;
+		String	auth_str	= String.valueOf(false);
+		
+		try{
+			Engine engine = subs.getEngine();
+			
+			engine_str = engine.getNameEx();
+			
+			if ( engine instanceof WebEngine ){
+			
+				WebEngine web_engine = (WebEngine)engine;
+				
+				if ( web_engine.isNeedsAuth()){
+					
+					auth_str = String.valueOf(true) + ": cookies=" + toString( web_engine.getRequiredCookies());
+				}
+			}
+		}catch( Throwable e ){
+			
+			engine_str 	= "Unknown";
+			auth_str	= "";
+		}
+		
+		String[] keys = {
+				"subs.prop.enabled",
+				"subs.prop.is_public",
+				"subs.prop.is_auto",
+				"subs.prop.is_auto_ok",
+				"subs.prop.update_period",
+				"subs.prop.last_scan",
+				"subs.prop.last_result",
+				"subs.prop.next_scan",
+				"subs.prop.last_error",
+				"subs.prop.num_read",
+				"subs.prop.num_unread",
+				"subs.prop.assoc",
+				"subs.prop.version",
+				"subs.prop.high_version",
+				"subscriptions.listwindow.popularity",
+				"subs.prop.template",
+				"subs.prop.auth",
+				"TableColumn.header.category",
+			};
+		
+		String	category_str;
+		
+		String category = subs.getCategory();
+		
+		if ( category == null ){
+			
+			category_str = MessageText.getString( "Categories.uncategorized" );
+			
+		}else{
+			
+			category_str = category;
+		}
+		
+		int	 check_freq			= history.getCheckFrequencyMins();
+		long last_new_result 	= history.getLastNewResultTime();
+		long next_scan 			= history.getNextScanTime();
+		
+		String[] values = { 
+				String.valueOf( history.isEnabled()),
+				String.valueOf( subs.isPublic()),
+				String.valueOf( history.isAutoDownload()),
+				String.valueOf( subs.isAutoDownloadSupported()),
+				(check_freq==Integer.MAX_VALUE?"":(String.valueOf( history.getCheckFrequencyMins() + " " + MessageText.getString( "ConfigView.text.minutes")))),
+				df.format(new Date( history.getLastScanTime())),
+				( last_new_result==0?"":df.format(new Date( last_new_result ))),
+				( next_scan == Long.MAX_VALUE?"":df.format(new Date( next_scan ))),
+				(last_error.length()==0?MessageText.getString("PeersView.uniquepiece.none"):last_error),
+				String.valueOf( history.getNumRead()),
+				String.valueOf( history.getNumUnread()),
+				String.valueOf( subs.getAssociationCount()),
+				String.valueOf( subs.getVersion()),
+				subs.getHighestVersion() > subs.getVersion()?String.valueOf( subs.getHighestVersion()):null,
+				subs.getCachedPopularity()<=1?null:String.valueOf( subs.getCachedPopularity()),
+				engine_str,
+				auth_str,
+				category_str,
+			};
+		
+		new PropertiesWindow( subs.getName(), keys, values );
+	}
+
+	private String
+	toString(
+		String[]	strs )
+	{
+		String	res = "";
+		
+		for(int i=0;i<strs.length;i++){
+			res += (i==0?"":",") + strs[i];
+		}
+		
+		return( res );
+	}
+	
+
+	public abstract static class SubsMenuItemListener implements MenuItemListener {
+		public final void selected(MenuItem menu, Object target) {
+			if (target instanceof MdiEntry) {
+				MdiEntry info = (MdiEntry) target;
+				Subscription subs = (Subscription) info.getDatasource();
+				
+				try {
+					selected(info, subs);
+				} catch (Throwable t) {
+					Debug.out(t);
+				}
+			}
+		}
+
+		public abstract void selected(MdiEntry info, Subscription subs);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
index 0fc43aa..2869035 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionManagerUI.java
@@ -21,25 +21,12 @@
 
 package com.aelitis.azureus.ui.swt.subscriptions;
 
-import java.io.File;
-import java.text.SimpleDateFormat;
 import java.util.*;
-import java.util.List;
 
 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;
-import org.eclipse.swt.layout.FormLayout;
-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.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginConfigListener;
@@ -47,75 +34,39 @@ import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
 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;
+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.SideBarEntry;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImageListener;
 import org.gudy.azureus2.plugins.ui.tables.*;
-import org.gudy.azureus2.plugins.ui.tables.TableColumn;
 import org.gudy.azureus2.plugins.utils.DelayedTask;
 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.PropertiesWindow;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
-import org.gudy.azureus2.ui.swt.plugins.UISWTInputReceiver;
 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewEventListenerHolder;
 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.messenger.ClientMessageContext;
-import com.aelitis.azureus.core.metasearch.Engine;
-import com.aelitis.azureus.core.metasearch.impl.web.WebEngine;
 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;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-import com.aelitis.azureus.ui.swt.browser.BrowserContext;
-import com.aelitis.azureus.ui.swt.browser.CookiesListener;
-import com.aelitis.azureus.ui.swt.browser.OpenCloseSearchDetailsListener;
-import com.aelitis.azureus.ui.swt.browser.listener.*;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnabler;
-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.SkinViewManager.SkinViewManagerListener;
-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.SideBarListener;
-import com.aelitis.azureus.util.ConstantsVuze;
-import com.aelitis.azureus.util.MapUtils;
-import com.aelitis.azureus.util.UrlFilter;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
 
 public class 
 SubscriptionManagerUI 
 {
-	public static final Object	SUB_IVIEW_KEY 		= new Object();
+	public static final Object	SUB_ENTRYINFO_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 ALERT_IMAGE_ID	= "image.sidebar.vitality.alert";
+	private static final String INFO_IMAGE_ID	= "image.sidebar.vitality.info";
 	
 
-	private static final String EDIT_MODE_MARKER	= "&editMode=1";
+	static final String EDIT_MODE_MARKER	= "&editMode=1";
 	
 	private Graphic	icon_rss_big;
 	private Graphic	icon_rss_small;
@@ -125,28 +76,11 @@ SubscriptionManagerUI
 	private Graphic	icon_rss_some_add_big;
 	private List<Graphic>	icon_list	= new ArrayList<Graphic>();
 	
-	private SubscriptionManager	subs_man;
-	
-	private MenuItemListener markAllResultsListener;
-	private MenuItemListener unmarkAllResultsListener;
-	private MenuItemListener deleteAllResultsListener;
-	private MenuItemListener resetAuthListener;
-	private MenuItemListener setCookieListener;
-	private MenuItemListener resetResultsListener;
-	private MenuItemListener exportListener;
-	private MenuItemListener renameListener;
-	private MenuItemListener removeListener;
-	private MenuItemListener forceCheckListener;
-	private MenuItemListener upgradeListener;
-	private MenuItemListener propertiesListener;
-	
-	
-	private boolean		side_bar_setup;
-
 	private List<TableColumn> columns = new ArrayList<TableColumn>();
 	protected UISWTInstance swt;
 	private UIManager ui_manager;
 	private PluginInterface default_pi;
+	private MdiEntry mdiEntryOverview;
 	
 	public
 	SubscriptionManagerUI()
@@ -155,6 +89,11 @@ SubscriptionManagerUI
 		
 		final TableManager	table_manager = default_pi.getUIManager().getTableManager();
 
+		Utils.getOffOfSWTThread(new AERunnable() {
+			public void runSupport() {
+				SubscriptionManagerFactory.getSingleton();
+			}
+		});
 		
 		if ( Constants.isCVSVersion()){			
 			
@@ -258,6 +197,8 @@ SubscriptionManagerUI
 							MenuItem	menu,
 							Object		target )
 						{	
+							SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
+
 							if ( subs_man == null ){
 								
 								return;
@@ -297,7 +238,7 @@ SubscriptionManagerUI
 							
 							if ( enabled ){
 							
-								Subscription[] subs = subs_man.getSubscriptions();
+								Subscription[] subs = subs_man.getSubscriptions( true );
 								
 								boolean	incomplete = ((TableContextMenuItem)menu).getTableID() == TableManager.TABLE_MYTORRENTS_INCOMPLETE;
 								
@@ -356,26 +297,7 @@ SubscriptionManagerUI
 						
 						swt = (UISWTInstance)instance;
 						
-						SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
-						
-						if ( sideBar != null ){
-							
-							uiQuickInit(sideBar);
-						} else {
-							SkinViewManager.addListener(
-									new SkinViewManagerListener() 
-									{
-										public void 
-										skinViewAdded(
-											SkinView skinview) 
-										{
-											if ( skinview instanceof SideBar ){
-												SkinViewManager.RemoveListener(this);
-												uiQuickInit((SideBar) skinview);
-											}
-										}
-									});
-						}
+						uiQuickInit();
 
         		Utilities utilities = default_pi.getUtilities();
         		
@@ -403,40 +325,46 @@ SubscriptionManagerUI
 				});
 	}
 	
-	void uiQuickInit(final SideBar side_bar) {
-		final SideBarEntrySWT mainSBEntry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS);
-		mainSBEntry.setImageLeftID("image.sidebar.subscriptions");
-		if (!mainSBEntry.isInTree()) {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					side_bar.createTreeItemFromIViewClass(null,
-							SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS,
-							MessageText.getString("subscriptions.view.title"),
-							SubscriptionsView.class, null, null, null, null, false);
-				}
-			});
-		}
+	void uiQuickInit() {
 		
-	}
-
-	void delayedInit() {
-		if (swt == null) {
+		final MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		
+		if ( mdi == null ){
+			
+				// closing down
+			
 			return;
 		}
-		
-		icon_rss_small			= loadGraphic( swt, "btn_rss_subscribe_orange_30x14.png" );
+
+		icon_rss_small			= loadGraphic( swt, "subscription_icon.png" );
 		icon_rss_big			= icon_rss_small;
 
-		//icon_rss_all_add_small	= loadGraphic( swt, "btn_rss_subscribed_green_30x14.png" );
-		icon_rss_all_add_small	= loadGraphic( swt, "btn_rss_subscribed_gray_30x14.png" );
+		icon_rss_all_add_small	= loadGraphic( swt, "subscription_icon_inactive.png" );
 		icon_rss_all_add_big	= icon_rss_all_add_small;
 		
-		// icon_rss_some_add_small	= loadGraphic( swt, "btn_rss_subscribe_green_30x14.png" );
-		icon_rss_some_add_small	= loadGraphic( swt, "btn_rss_subscribed_gray_30x14.png" );
+		icon_rss_some_add_small	= icon_rss_all_add_small;
 		icon_rss_some_add_big	= icon_rss_some_add_small;
 		
-		subs_man = SubscriptionManagerFactory.getSingleton();
+
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_SUBSCRIPTIONS,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						setupSideBar( swt );
+						return mdiEntryOverview;
+					}
+				});
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+		if (uiClassic) {
+			addAllSubscriptions();
+		}
+	}
+
+	void delayedInit() {
+		if (swt == null) {
+			return;
+		}
 		
+		SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
 		subs_man.addListener(
 			new SubscriptionManagerListener()
 			{
@@ -472,6 +400,11 @@ SubscriptionManagerUI
 				}
 			});	
 		
+		createConfigModel();
+	}
+
+	private void createConfigModel() {
+		final SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
 
 		BasicPluginConfigModel configModel = ui_manager.createBasicPluginConfigModel(
 				ConfigSection.SECTION_ROOT, "Subscriptions");
@@ -482,6 +415,42 @@ SubscriptionManagerUI
 				"subscriptions.config.maxresults", 
 				subs_man.getMaxNonDeletedResults());
 			
+			// search
+		
+		final BooleanParameter search_enable = 
+			configModel.addBooleanParameter2( 
+				"subscriptions.search.enable", "subscriptions.search.enable",
+				subs_man.isSearchEnabled());
+		
+		search_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					subs_man.setSearchEnabled( search_enable.getValue());
+				}
+			});
+		
+			// download subs enable
+		
+		final BooleanParameter download_subs_enable = 
+			configModel.addBooleanParameter2( 
+				"subscriptions.dl_subs.enable", "subscriptions.dl_subs.enable",
+				subs_man.isSubsDownloadEnabled());
+		
+		download_subs_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param) 
+				{
+					subs_man.setSubsDownloadEnabled( download_subs_enable.getValue());
+				}
+			});
+		
 			// auto
 		
 		final BooleanParameter auto_start = configModel.addBooleanParameter2(
@@ -568,28 +537,6 @@ SubscriptionManagerUI
 			{
 					rss_enable, rss_view,
 			});
-		
-		SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
-		
-		if ( sideBar != null ){
-			
-			setupSideBar( sideBar, swt );
-		} else {
-			SkinViewManager.addListener(
-					new SkinViewManagerListener() 
-					{
-						public void 
-						skinViewAdded(
-							SkinView skinview) 
-						{
-							if ( skinview instanceof SideBar ){
-								
-								setupSideBar((SideBar) skinview, swt);
-								SkinViewManager.RemoveListener(this);
-							}
-						}
-					});
-		}
 	}
 
 	private void 
@@ -605,6 +552,7 @@ SubscriptionManagerUI
 				{
 					TableCellSWT cell = (TableCellSWT)_cell;
 					
+					SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
 					if ( subs_man == null ){
 						
 						return;
@@ -678,6 +626,7 @@ SubscriptionManagerUI
 						
 						sort_order += 1000*num_unsubscribed + num_subscribed;
 						
+						cell.setMarginHeight(0);
 						cell.setGraphic( graphic );
 						cell.setToolTip( tooltip );
 						
@@ -712,6 +661,7 @@ SubscriptionManagerUI
 						
 						if ( torrent != null ){
 							
+							SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
 							Subscription[] subs = subs_man.getKnownSubscriptions( torrent.getHash());
 							
 							if ( subs.length > 0 ){
@@ -720,6 +670,10 @@ SubscriptionManagerUI
 
 								new SubscriptionWizard(PluginCoreUtils.unwrap(dl));
 								
+								COConfigurationManager.setParameter( "subscriptions.wizard.shown", true );
+
+								refreshTitles( mdiEntryOverview );
+								
 								//new SubscriptionListWindow(PluginCoreUtils.unwrap(dl),true);
 							}
 						}
@@ -735,14 +689,17 @@ SubscriptionManagerUI
 				public void tableColumnCreated(TableColumn result) {
 					result.setAlignment(TableColumn.ALIGN_CENTER);
 					result.setPosition(TableColumn.POSITION_LAST);
-					result.setWidth(72);
+					result.setWidth(32);
 					result.setRefreshInterval(TableColumn.INTERVAL_INVALID_ONLY);
 					result.setType(TableColumn.TYPE_GRAPHIC);
 				
 					result.addCellRefreshListener( subs_refresh_listener );
 					result.addCellMouseListener( subs_mouse_listener );
+					result.setIconReference("image.subscription.column", true);
 					
-					columns.add(result);
+					synchronized (columns) {
+						columns.add(result);
+					}
 				}
 			});
 		
@@ -755,6 +712,7 @@ SubscriptionManagerUI
 				{
 					TableCellSWT cell = (TableCellSWT)_cell;
 					
+					SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
 					if ( subs_man == null ){
 						
 						return;
@@ -808,8 +766,10 @@ SubscriptionManagerUI
 							Download	dl = (Download)cell.getDataSource();
 							
 							Torrent	torrent = dl.getTorrent();
-							
-							if ( torrent != null ){
+
+							SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
+
+							if ( torrent != null && subs_man != null ){
 								
 								byte[]	hash = torrent.getHash();
 								
@@ -821,16 +781,12 @@ SubscriptionManagerUI
 									
 									if ( sub.hasAssociation( hash )){
 										
-										sideBarItem item = (sideBarItem) sub.getUserData(SubscriptionManagerUI.SUB_IVIEW_KEY);
-										
-										if ( item != null ){
-										
-											event.skipCoreFunctionality	= true;
-
-											item.activate();
-											
-											break;
+										String key = "Subscription_" + ByteFormatter.encodeString(sub.getPublicKey());
+										MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+										if ( mdi != null ){
+											mdi.showEntryByID(key);
 										}
+										break;
 									}
 								}
 							}
@@ -852,469 +808,293 @@ SubscriptionManagerUI
 					
 						result.addCellRefreshListener( link_refresh_listener );
 						result.addCellMouseListener( link_mouse_listener );
+						result.setMinimumRequiredUserMode( Parameter.MODE_INTERMEDIATE );
 						
-						columns.add(result);
+						synchronized (columns) {
+							columns.add(result);
+						}
 					}
 				});
 	}
-
+	
 	protected void
 	setupSideBar(
-		final SideBar			side_bar,
 		final UISWTInstance		swt_ui )		
 	{
-		synchronized( this ){
-			
-			if ( side_bar_setup ){
-				
-				return;
-			}
-			
-			side_bar_setup = true;
-		}
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
 		
-		final SideBarEntrySWT mainSBEntry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS);
+		if (mdi == null) {
+			return;
+		}
 		
-		if (mainSBEntry != null) {
-			
-			SideBarVitalityImage addSub 	= mainSBEntry.addVitalityImage("image.sidebar.subs.add");
-			
-			addSub.setToolTip("Add Subscription");
-			
-			addSub.addListener(new SideBarVitalityImageListener() {
-				public void sbVitalityImage_clicked(int x, int y) {
-					new SubscriptionWizard();
-				}
-			});
-			
-			final SideBarVitalityImage warnSub 	= mainSBEntry.addVitalityImage( ALERT_IMAGE_ID );
-			
-			warnSub.setVisible( false );
-			
-			mainSBEntry.setImageLeftID("image.sidebar.subscriptions");
-
-			mainSBEntry.setTitleInfo(
-				new ViewTitleInfo() 
-				{
-					public Object 
-					getTitleInfoProperty(
-						int propertyID ) 
-					{
-						if (propertyID == TITLE_TEXT) {
-							
-							return MessageText.getString("subscriptions.view.title");
-							
-						}else if ( propertyID == TITLE_INDICATOR_TEXT ){
+		mdiEntryOverview = mdi.createEntryFromEventListener(
+				MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS, 
+				new UISWTViewEventListenerHolder(
+						MultipleDocumentInterface.SIDEBAR_SECTION_SUBSCRIPTIONS,
+						SubscriptionsView.class, null, null),
+				MultipleDocumentInterface.SIDEBAR_SECTION_SUBSCRIPTIONS, false, null);
 
-							boolean expanded = mainSBEntry.getTreeItem().getExpanded();
+		if (mdiEntryOverview == null) {
+			return;
+		}
+			
+		mdiEntryOverview.setImageLeftID("image.sidebar.subscriptions");
 
-							if ( expanded ){
-								
-								warnSub.setVisible( false );
-								
-							}else{
-								
-								int		total 	= 0;
-								boolean	warn 	= false;
-								
-								Subscription[] subs = subs_man.getSubscriptions();
-								
-								for ( Subscription s: subs ){
-									
-									SubscriptionHistory history = s.getHistory();
+		MdiEntry headerEntry = mdi.getEntry(MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS);
+		if (headerEntry != null) {
+			setupHeader(mdi, headerEntry);
+		}
 
-									total += history.getNumUnread();
-									
-									String	last_error = history.getLastError();
+		String parentID = "sidebar." + MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS;
 
-									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 ));
-								}
-							}
-						}
-						
-						return null;
+		MenuManager menu_manager = ui_manager.getMenuManager();
+		
+		MenuItem mi = menu_manager.addMenuItem( parentID, "MainWindow.menu.view.configuration" );
+		
+		mi.addListener( 
+				new MenuItemListener() 
+				{
+					public void 
+					selected(
+						MenuItem menu, Object target ) 
+					{
+				      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
+				      	 
+				      	 if ( uif != null ){
+				      		 
+				      		 uif.openView( UIFunctions.VIEW_CONFIG, "Subscriptions" );
+				      	 }
 					}
 				});
-
-			String parentID = "sidebar." + SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS;
-
-			MenuManager menu_manager = ui_manager.getMenuManager();
-			
-			MenuItem mi = menu_manager.addMenuItem( parentID, "ConfigView.title.short" );
-			
-			mi.addListener( 
-					new MenuItemListener() 
-					{
-						public void 
-						selected(
-							MenuItem menu, Object target ) 
-						{
-					      	 UIFunctions uif = UIFunctionsManager.getUIFunctions();
-					      	 
-					      	 if ( uif != null ){
-					      		 
-					      		 uif.openView( UIFunctions.VIEW_CONFIG, "Subscriptions" );
-					      	 }
-						}
-					});
-			if (!mainSBEntry.isInTree()) {
-  			
-				side_bar.createTreeItemFromIViewClass(null,
-  					SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS,
-  					MessageText.getString("subscriptions.view.title"),
-  					SubscriptionsView.class, null, null, null, null, false);
-			}
-		}
-		
-		markAllResultsListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					subs.getHistory().markAllResultsRead();
-					refreshView( subs );
-				}
-			}
-		};
 		
-		unmarkAllResultsListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					subs.getHistory().markAllResultsUnread();
-					refreshView( subs );
+		SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
+		subs_man.addListener(
+			new SubscriptionManagerListener()
+			{
+				public void 
+				subscriptionAdded(
+					Subscription 		subscription ) 
+				{
+					addSubscription( subscription, false );
 				}
-			}
-		};
-		
-		deleteAllResultsListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					subs.getHistory().deleteAllResults();
-					refreshView( subs );
+	
+				public void
+				subscriptionChanged(
+					Subscription		subscription )
+				{
+					changeSubscription( subscription );
 				}
-			}
-		};
-		
-		
-		resetAuthListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					try{
-						Engine engine = subs.getEngine();
-						
-						if ( engine instanceof WebEngine ){
-							
-							((WebEngine)engine).setCookies( null );
-						}
-					}catch( Throwable e ){
-						
-						Debug.printStackTrace(e);
-					}
+				
+				public void 
+				subscriptionSelected(
+					Subscription sub )
+				{	
 					
-					try{
-						subs.getManager().getScheduler().downloadAsync(subs, true);
-						
-					}catch( Throwable e ){
-						
-						Debug.out(e);
+					String key = "Subscription_" + ByteFormatter.encodeString(sub.getPublicKey());
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					if ( mdi != null ){
+						mdi.showEntryByID(key);
 					}
 				}
-			}
-		};
+				
+				public void 
+				subscriptionRemoved(
+					Subscription 		subscription ) 
+				{
+					removeSubscription( subscription );
+				}
+				
+				public void
+				associationsChanged(
+					byte[]		association_hash )
+				{
+					 
+				}
+			});
 		
-		setCookieListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					final Subscription subs = (Subscription) info.getDatasource();
-					try{
-						Engine engine = subs.getEngine();
+		if (!uiClassic) {
+			addAllSubscriptions();
+		}
+
+		mdi.addListener(
+			new MdiListener() 
+			{
+				private long last_select = 0;
+				
+				public void 
+				mdiEntrySelected(
+					MdiEntry new_entry,
+					MdiEntry old_entry ) 
+				{
+					if ( new_entry == old_entry && (new_entry instanceof BaseMdiEntry) ){
 						
-						if ( engine instanceof WebEngine ){
-							
-							final WebEngine we = (WebEngine)engine;
-							
-							UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
-							
-							String[] req = we.getRequiredCookies();
-							
-							String	req_str = "";
+						UISWTViewEventListener eventListener = ((BaseMdiEntry)new_entry).getEventListener();
+						
+						if ( eventListener instanceof SubscriptionView ){
 							
-							for ( String r:req ){
+							try{
 								
-								req_str += (req_str.length()==0?"":";") + r + "=?";
-							}
-							entry.setPreenteredText( req_str, true );
-							entry.maintainWhitespace(false);
-							entry.allowEmptyInput( false );
-							entry.setTitle("general.enter.cookies");
-							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);
-									}
+								if ( SystemTime.getMonotonousTime() - last_select > 1000 ){
+									
+									((SubscriptionView)eventListener).updateBrowser( false );
 								}
-							});
+							}finally{
+								
+								last_select = SystemTime.getMonotonousTime();
+							}
 						}
-					}catch( Throwable e ){
-						
-						Debug.printStackTrace(e);
 					}
 				}
-			}
-		};
-		
-		resetResultsListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					subs.getHistory().reset();
-					try{
-						subs.getEngine().reset();
-					}catch( Throwable e ){
-						Debug.printStackTrace(e);
-					}
-					try{
-						subs.getManager().getScheduler().downloadAsync(subs, true);
-						
-					}catch( Throwable e ){
-						
-						Debug.out(e);
-					}
+			});
+	}
+	
+	private void setupHeader(MultipleDocumentInterface mdi,
+			final MdiEntry headerEntry) {
+
+		MdiEntryVitalityImage addSub = headerEntry.addVitalityImage("image.sidebar.subs.add");
+
+		if (addSub != null) {
+			addSub.setToolTip(MessageText.getString("subscriptions.add.tooltip"));
+
+			addSub.addListener(new MdiEntryVitalityImageListener() {
+				public void mdiEntryVitalityImage_clicked(int x, int y) {
+					new SubscriptionWizard();
+					
+					COConfigurationManager.setParameter( "subscriptions.wizard.shown", true );
+
+					refreshTitles( mdiEntryOverview );
 				}
-			}
-		};
+			});
+		}
+
+		final MdiEntryVitalityImage warnSub = headerEntry.addVitalityImage(ALERT_IMAGE_ID);
+		if (warnSub != null) {
+			warnSub.setVisible(false);
+		}
+
+		final MdiEntryVitalityImage infoSub = headerEntry.addVitalityImage(INFO_IMAGE_ID);
+		if (infoSub != null) {
+			infoSub.setVisible(false);
+		}
+
 		
-		exportListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					final Subscription subs = (Subscription) info.getDatasource();
-					
-					final Shell shell = Utils.findAnyShell();
+		headerEntry.setViewTitleInfo(
+			new ViewTitleInfo() 
+			{
+				private long	last_avail_calc = -1;
+				private int		last_avail;
+				
+				public Object 
+				getTitleInfoProperty(
+					int propertyID) 
+				{
+					Object result = null;
+	
+					// COConfigurationManager.setParameter( "subscriptions.wizard.shown", false );
 					
-					shell.getDisplay().asyncExec(
-						new AERunnable() 
-						{
-							public void 
-							runSupport()
-							{
-								FileDialog dialog = 
-									new FileDialog( shell, SWT.SYSTEM_MODAL | SWT.SAVE );
-								
-								dialog.setFilterPath( TorrentOpener.getFilterPathData() );
-														
-								dialog.setText(MessageText.getString("subscript.export.select.template.file"));
-								
-								dialog.setFilterExtensions(new String[] {
-										"*.vuze",
-										"*.vuz",
-										Constants.FILE_WILDCARD
-									});
-								dialog.setFilterNames(new String[] {
-										"*.vuze",
-										"*.vuz",
-										Constants.FILE_WILDCARD
-									});
-								
-								String path = TorrentOpener.setFilterPathData( dialog.open());
-			
-								if ( path != null ){
-									
-									String lc = path.toLowerCase();
-									
-									if ( !lc.endsWith( ".vuze" ) && !lc.endsWith( ".vuz" )){
-										
-										path += ".vuze";
-									}
-									
-									try{
-										VuzeFile vf = subs.getVuzeFile();
-										
-										vf.write( new File( path ));
-										
-
-									}catch( Throwable e ){
-										
-										Debug.out( e );
+					if (propertyID == TITLE_INDICATOR_TEXT) {
+	
+						boolean expanded = headerEntry.isExpanded();
+	
+						SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
+						Subscription[] subs = subs_man == null ? new Subscription[0] : subs_man.getSubscriptions(true);
+						
+						if ( expanded ){
+	
+							warnSub.setVisible(false);
+	
+						}else{
+	
+							int total = 0;
+							
+							boolean warn = false;
+	
+							String error_str = "";
+	
+							for (Subscription s : subs) {
+	
+								SubscriptionHistory history = s.getHistory();
+	
+								total += history.getNumUnread();
+	
+								String last_error = history.getLastError();
+	
+								if (last_error != null && last_error.length() > 0) {
+	
+									boolean auth_fail = history.isAuthFail();
+	
+									if (history.getConsecFails() >= 3 || auth_fail) {
+	
+										warn = true;
+	
+										if (error_str.length() > 128) {
+	
+											if (!error_str.endsWith(", ...")) {
+	
+												error_str += ", ...";
+											}
+										} else {
+	
+											error_str += (error_str.length() == 0 ? "" : ", ")
+													+ last_error;
+										}
 									}
 								}
 							}
-						});
-				}
-			}
-		};
-		
-		renameListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					final Subscription subs = (Subscription) info.getDatasource();
-					
-					UISWTInputReceiver entry = (UISWTInputReceiver)swt_ui.getInputReceiver();
-					entry.setPreenteredText(subs.getName(), false );
-					entry.maintainWhitespace(false);
-					entry.allowEmptyInput( false );
-					entry.setLocalisedTitle(MessageText.getString("label.rename",
-							new String[] {
-								subs.getName()
-							}));
-					entry.prompt(new UIInputReceiverListener() {
-						public void UIInputReceiverClosed(UIInputReceiver entry) {
-							if (!entry.hasSubmittedInput()){
-								
-								return;
+	
+							warnSub.setVisible(warn);
+							warnSub.setToolTip(error_str);
+							
+							if (total > 0) {
+	
+								result = String.valueOf( total );
 							}
+						}
+						
+						if ( subs.length == 0 && !COConfigurationManager.getBooleanParameter( "subscriptions.wizard.shown", false )){
 							
-							String input = entry.getSubmittedInput().trim();
+							long now = SystemTime.getMonotonousTime();
 							
-							if ( input.length() > 0 ){
+							if ( 	last_avail_calc == -1 ||
+									now - last_avail_calc > 60*1000 ){
 								
-								try{
-									subs.setName( input );
-									
-								}catch( Throwable e ){
-									
-									Debug.printStackTrace(e);
-								}
+								last_avail = subs_man.getKnownSubscriptionCount();
+								
+								last_avail_calc = now;
+							}
+							
+							if ( last_avail > 0 ){
+								
+								infoSub.setVisible( true );
+								
+								infoSub.setToolTip( 
+									MessageText.getString(
+										"subscriptions.info.avail",
+										new String[]{
+											String.valueOf( last_avail )
+										}));
 							}
+						}else{
+							
+							infoSub.setVisible( false );
 						}
-					});
-				}
-			}
-		};
-		
-		removeListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					removeWithConfirm( subs );
-				}
-			}
-		};
-		
-		forceCheckListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-					try{
-						
-						subs.getManager().getScheduler().downloadAsync( subs, true );
-						
-					}catch( Throwable e ){
-						
-						Debug.out( e );
 					}
-				}
-			}
-		};
-		
-		upgradeListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-				
-					subs.resetHighestVersion();
-				}
-			}
-		};
-		
-		propertiesListener = new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				if (target instanceof SideBarEntry) {
-					SideBarEntry info = (SideBarEntry) target;
-					Subscription subs = (Subscription) info.getDatasource();
-				
-					showProperties( subs );
-				}
-			}
-		};
-		
-		subs_man.addListener(
-			new SubscriptionManagerListener()
-			{
-				public void 
-				subscriptionAdded(
-					Subscription 		subscription ) 
-				{
-					addSubscription( side_bar, subscription, true );
-				}
 	
-				public void
-				subscriptionChanged(
-					Subscription		subscription )
-				{
-					changeSubscription( side_bar, subscription );
-				}
-				
-				public void 
-				subscriptionSelected(
-					Subscription subscription )
-				{	
-					sideBarItem item = (sideBarItem)subscription.getUserData(SubscriptionManagerUI.SUB_IVIEW_KEY);
-					
-					if (item != null ){
-					
-						item.activate();
-					}
-				}
-				
-				public void 
-				subscriptionRemoved(
-					Subscription 		subscription ) 
-				{
-					removeSubscription( side_bar, subscription );
-				}
-				
-				public void
-				associationsChanged(
-					byte[]		association_hash )
-				{
-					 
+					return( result );
 				}
 			});
-		
-		Subscription[]	subs = subs_man.getSubscriptions();
+	}
+
+	private void 
+	addAllSubscriptions() 
+	{
+		SubscriptionManager subs_man = SubscriptionManagerFactory.getSingleton();
+		if (subs_man == null) {
+			return;
+		}
+		Subscription[]	subs = subs_man.getSubscriptions( true );
 		
 		Arrays.sort(
 			subs,
@@ -1330,59 +1110,28 @@ SubscriptionManagerUI
 		
 		for (int i=0;i<subs.length;i++){
 			
-			addSubscription( side_bar, subs[i], false );
+			addSubscription( subs[i], false );
 		}
-		
-		side_bar.addListener(
-			new SideBarListener() 
-			{
-				private long last_select = 0;
-				
-				public void 
-				sidebarItemSelected(
-					SideBarEntrySWT new_entry,
-					SideBarEntrySWT old_entry ) 
-				{
-					if ( new_entry == old_entry ){
-						
-						IView view = new_entry.getIView();
-						
-						if ( view instanceof subscriptionView ){
-							
-							try{
-								
-								if ( SystemTime.getMonotonousTime() - last_select > 1000 ){
-									
-									((subscriptionView)view).updateBrowser( false );
-								}
-							}finally{
-								
-								last_select = SystemTime.getMonotonousTime();
-							}
-						}
-					}
-				}
-			});
 	}
-	
+
 	protected void
 	changeSubscription(
-		SideBar				side_bar,
 		final Subscription	subs )
 	{
+		refreshTitles( mdiEntryOverview );
+
 		if ( subs.isSubscribed()){
 			
-			addSubscription( side_bar, subs, false );
+			addSubscription( subs, false );
 			
 		}else{
 			
-			removeSubscription( side_bar, subs);
+			removeSubscription( subs);
 		}
 	}
 	
 	protected void
 	addSubscription(
-		final SideBar			side_bar,
 		final Subscription		subs,
 		final boolean			show )
 	{
@@ -1391,519 +1140,172 @@ SubscriptionManagerUI
 			return;
 		}
 		
+			// hack to hide useless entries
+		
+		String name = subs.getName();
+		
+		if ( name.startsWith( "Search Template: " )){
+			
+			return;
+		}
+	
 		refreshColumns();
 		
-		synchronized( this ){
-				
-			final sideBarItem existing_si = (sideBarItem)subs.getUserData( SUB_IVIEW_KEY );
+		final String key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());				
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+		if ( mdi == null ){
+			
+				// closing down
+			
+			return;
+		}
+		
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
+		if (uiClassic && !show) {
+			mdi.registerEntry(key, new MdiEntryCreationListener() {
+				public MdiEntry createMDiEntry(String id) {
+					return createSubsEntry(subs);
+				}
+			});
+			return;
+		}
+		
+		if (mdi.entryExists(key)) {
+			return;
+		}
+
+		createSubsEntry(subs);
+	}
+	
+	private MdiEntry createSubsEntry(final Subscription subs) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		
+		if ( mdi == null ){
 			
-			if (  existing_si == null ){
+				// closing down
+		
+			return( null );
+		}
 	
-				final sideBarItem new_si = new sideBarItem();
+		ViewTitleInfo viewTitleInfo = new ViewTitleInfo() {
+			public Object 
+			getTitleInfoProperty(
+				int propertyID ) 
+			{
+				switch( propertyID ){
 				
-				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 ){
+					case ViewTitleInfo.TITLE_TEXT:{
+						
+						return( subs.getName());
+					}
+					case ViewTitleInfo.TITLE_INDICATOR_TEXT_TOOLTIP:{
 					
-					Debug.printStackTrace(ex);
+						long	pop = subs.getCachedPopularity();
+						
+						String res = subs.getName();
+						
+						if ( pop > 1 ){
+							
+							res += " (" + MessageText.getString("subscriptions.listwindow.popularity").toLowerCase() + "=" + pop + ")";
+						}
+												
+						return( res );
+					}
+					case ViewTitleInfo.TITLE_INDICATOR_TEXT :{
+						
+						SubscriptionMDIEntry mdi = (SubscriptionMDIEntry) subs.getUserData(SubscriptionManagerUI.SUB_ENTRYINFO_KEY);
+						
+						if ( mdi != null ){
+							
+							mdi.setWarning();
+						}
+
+						if( subs.getHistory().getNumUnread() > 0 ){
+							
+							return ( "" + subs.getHistory().getNumUnread());
+						}
+						
+						return null;
+					}
 				}
-				final Engine engine = e;
 				
-				Utils.execSWTThread(
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							synchronized( SubscriptionManagerUI.this ){
+				return( null );
+			}
+		};
 
-								if ( new_si.isDestroyed()){
-									
-									return;
-								}
-								
-								subscriptionView view = new subscriptionView( subs );
-								
-								new_si.setView( view );
-								
-								String key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());
-								
-								TreeItem  tree_item = 
-									side_bar.createTreeItemFromIView(
-										SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS, 
-										view,
-										key, 
-										subs, 
-										false, 
-										show,
-										false );
-								
-								SideBarEntrySWT	entry = SideBar.getEntry( key );
-																
-								new_si.setTreeItem( tree_item, entry );
-								
-								setStatus( subs, new_si );
-								
-								PluginInterface pi = PluginInitializer.getDefaultInterface();
-								UIManager uim = pi.getUIManager();
-								
-								final MenuManager menuManager = uim.getMenuManager();
-								
-								MenuItem menuItem;
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.forcecheck");
-								menuItem.setText(MessageText.getString("Subscription.menu.forcecheck"));
-								menuItem.addListener(forceCheckListener);
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.clearall");
-								menuItem.addListener(markAllResultsListener);
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.dirtyall");
-								menuItem.addListener(unmarkAllResultsListener);
+		final String key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());
+		
+		MdiEntry entry = mdi.createEntryFromEventListener(
+				MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS,
+				new UISWTViewEventListenerHolder(key, SubscriptionView.class, subs, null),
+				key, false, subs);
+		entry.setViewTitleInfo(viewTitleInfo);
 
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.deleteall");
-								menuItem.addListener(deleteAllResultsListener);
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.reset");
-								menuItem.addListener(resetResultsListener);
+		// This sets up the entry (menu, etc)
+		SubscriptionMDIEntry entryInfo = new SubscriptionMDIEntry(subs, entry);
+		subs.setUserData(SUB_ENTRYINFO_KEY, entryInfo);
 
-								try{
-									if ( engine instanceof WebEngine ){
-										
-										if (((WebEngine)engine).isNeedsAuth()){
-											
-											menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.resetauth");
-											menuItem.addListener(resetAuthListener);
-											
-											menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.setcookies");
-											menuItem.addListener(setCookieListener);
-										}
-									}
-								}catch( Throwable e ){
-									
-									Debug.printStackTrace(e);
-								}
-								
-									// sep
-								
-								menuManager.addMenuItem("sidebar." + key,"s1").setStyle( MenuItem.STYLE_SEPARATOR );
+		return entry;
+	}
+	
+	protected void
+	refreshTitles(
+		MdiEntry		entry )
+	{
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		
+		if ( mdi == null ){
 
-									// category
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key, "MyTorrentsView.menu.setCategory");
-								menuItem.setStyle( MenuItem.STYLE_MENU );
-								
-								menuItem.addFillListener(
-										new MenuItemFillListener()
-										{
-											public void 
-											menuWillBeShown(
-												MenuItem 	menu, 
-												Object 		data ) 
-											{		
-												addCategorySubMenu( menuManager, menu, subs );
-											}
-										});
-								
-								
-								if ( subs.isUpdateable()){
-									
-									menuItem = menuManager.addMenuItem("sidebar." + key,"MyTorrentsView.menu.rename");
-									menuItem.addListener(renameListener);
-								}
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.upgrade");
-								menuItem.addListener(upgradeListener);
-									
-								menuItem.addFillListener(
-									new MenuItemFillListener()
-									{
-										public void 
-										menuWillBeShown(
-											MenuItem 	menu, 
-											Object 		data ) 
-										{									
-											menu.setVisible( subs.getHighestVersion() > subs.getVersion());
-										}
-									});
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.export");
-								menuItem.addListener(exportListener);
-								
-									// sep
-								
-								menuManager.addMenuItem("sidebar." + key,"s2").setStyle( MenuItem.STYLE_SEPARATOR );
-								
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.remove");
-								menuItem.addListener(removeListener);
-								
-								menuManager.addMenuItem("sidebar." + key,"s3").setStyle( MenuItem.STYLE_SEPARATOR );
-
-								menuItem = menuManager.addMenuItem("sidebar." + key,"Subscription.menu.properties");
-								menuItem.addListener(propertiesListener);
-							}
-						}
-					});
-			}else{
-				
-				Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								ViewTitleInfoManager.refreshTitleInfo( existing_si.getView());
-								
-								SideBarEntrySWT mainSBEntry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_SUBSCRIPTIONS);
-								
-								if ( mainSBEntry != null ){
-									
-									ViewTitleInfoManager.refreshTitleInfo( mainSBEntry.getTitleInfo());
-								}
-								
-								setStatus( subs, existing_si );
-							}
-						});
-			}
+			return;
 		}
-	}
-	
-	
-	private void 
-	addCategorySubMenu(
-		MenuManager				menu_manager,
-		MenuItem				menu,
-		final Subscription		subs )
-	{
-		menu.removeAllChildItems();
-
-		Category[] categories = CategoryManager.getCategories();
 		
-		Arrays.sort( categories );
-
-		MenuItem m;
+		while( entry != null ){
+	
+			ViewTitleInfoManager.refreshTitleInfo(entry.getViewTitleInfo());
 
-		if ( categories.length > 0 ){
-			
-			String	assigned_category = subs.getCategory();
+			String key = entry.getParentID();
 			
-			final Category uncat = CategoryManager.getCategory( Category.TYPE_UNCATEGORIZED );
-						
-			if ( uncat != null ){
-				
-				m = menu_manager.addMenuItem( menu, uncat.getName());
-				
-				m.setStyle( MenuItem.STYLE_RADIO );
-								
-				m.setData( new Boolean( assigned_category == null ));
-				
-				m.addListener(
-					new MenuItemListener() 
-					{
-						public void
-						selected(
-							MenuItem			menu,
-							Object 				target )
-						{
-							assignSelectedToCategory( uncat, subs );
-						}
-					});
-				
-
-				m = menu_manager.addMenuItem( menu, "sep1" );
-				
-				m.setStyle( MenuItem.STYLE_SEPARATOR );
-			}
-
-			for ( int i=0; i<categories.length; i++ ){
+			if ( key == null ){
 				
-				final Category cat = categories[i];
-				
-				if ( cat.getType() == Category.TYPE_USER) {
-					
-					m = menu_manager.addMenuItem( menu, "!" + cat.getName() + "!" );
-					
-					m.setStyle( MenuItem.STYLE_RADIO );
-										
-					m.setData( new Boolean( assigned_category != null && assigned_category.equals( cat.getName())));
-					
-					m.addListener(
-						new MenuItemListener() 
-						{
-							public void
-							selected(
-								MenuItem			menu,
-								Object 				target )
-							{
-								assignSelectedToCategory( cat, subs );
-							}
-						});
-				}
+				return;
 			}
-
-			m = menu_manager.addMenuItem( menu, "sep2" );
 			
-			m.setStyle( MenuItem.STYLE_SEPARATOR );
+			entry = mdi.getEntry( key );
 		}
-
-		m = menu_manager.addMenuItem( menu, "MyTorrentsView.menu.setCategory.add" );
-		
-		m.addListener(
-				new MenuItemListener() 
-				{
-					public void
-					selected(
-						MenuItem			menu,
-						Object 				target )
-					{
-						addCategory( subs );
-					}
-				});
-
 	}
 
-	private void 
-	addCategory(
-		Subscription subs  )	
-	{
-		CategoryAdderWindow adderWindow = new CategoryAdderWindow(Display.getDefault());
-		
-		Category newCategory = adderWindow.getNewCategory();
-		
-		if ( newCategory != null ){
-		
-			assignSelectedToCategory( newCategory, subs );
-		}
-	}
-	
-	private void 
-	assignSelectedToCategory(
-		Category 			category,
-		Subscription		subs )
-	{
-		if ( category.getType() == Category.TYPE_UNCATEGORIZED ){
-		
-			subs.setCategory( null );
-			
-		}else{
-			
-			subs.setCategory( category.getName());
-		}
-	}
-	
-	protected void
-	setStatus(
-		Subscription	subs,
-		sideBarItem		sbi )
-	{
-		sbi.setWarning( subs );
-	}
-	
-	protected static void
-	removeWithConfirm(
-		final Subscription	subs )
-	{
-		MessageBoxShell mb = 
-			new MessageBoxShell(
-				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 );
-		
-		mb.open(new UserPrompterResultListener() {
-			public void prompterClosed(int result) {
-				if (result == 0) {
-					subs.remove();
-				}
-			}
-		});
-	}
-	
 	protected void
 	removeSubscription(
-		SideBar				side_bar,
 		final Subscription	subs )
 	{
 		synchronized( this ){
+
+			String key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
 			
-			final sideBarItem existing = (sideBarItem)subs.getUserData( SUB_IVIEW_KEY );
-			
-			if ( existing != null ){
-				
-				subs.setUserData( SUB_IVIEW_KEY, null );
+			if  (mdi != null ){
 				
-				existing.destroy();
-				
-				Utils.execSWTThread(
-						new Runnable()
-						{
-							public void
-							run()
-							{
-								synchronized( SubscriptionManagerUI.this ){
-
-									TreeItem ti = existing.getTreeItem();
-									
-									if ( ti != null ){
-										
-										ti.dispose();
-									}
-								}
-							}
-						});
+				mdi.closeEntry(key);
 			}
+
 		}
 		
 		refreshColumns();
 	}
 	
 	protected void
-	refreshView(
-		Subscription	subs )
-	{		
-		sideBarItem item = (sideBarItem)subs.getUserData( SUB_IVIEW_KEY );
-		
-		if ( item != null ){
-			
-			subscriptionView view = item.getView();
-			
-			if ( view != null ){
-				
-				view.updateBrowser( false );
-			}
-		}
-	}
-	
-	protected void
 	refreshColumns()
 	{
-		for ( Iterator<TableColumn> iter = columns.iterator(); iter.hasNext();){
-			
-			TableColumn column = iter.next();
-			
-			column.invalidateCells();
-		}
-	}
-	
-	protected void
-	showProperties(
-		Subscription		subs )
-	{
-		SubscriptionHistory history = subs.getHistory();
-		
-		SimpleDateFormat df = new SimpleDateFormat();
-		
-		String last_error = history.getLastError();
-		
-		if ( last_error == null ){
-			last_error = "";
-		}
-		
-		String	engine_str;
-		String	auth_str	= String.valueOf(false);
-		
-		try{
-			Engine engine = subs.getEngine();
-			
-			engine_str = engine.getNameEx();
-			
-			if ( engine instanceof WebEngine ){
-			
-				WebEngine web_engine = (WebEngine)engine;
-				
-				if ( web_engine.isNeedsAuth()){
-					
-					auth_str = String.valueOf(true) + ": cookies=" + toString( web_engine.getRequiredCookies());
-				}
-			}
-		}catch( Throwable e ){
-			
-			engine_str 	= "Unknown";
-			auth_str	= "";
-		}
-		
-		String[] keys = {
-				"subs.prop.enabled",
-				"subs.prop.is_public",
-				"subs.prop.is_auto",
-				"subs.prop.is_auto_ok",
-				"subs.prop.update_period",
-				"subs.prop.last_scan",
-				"subs.prop.last_result",
-				"subs.prop.next_scan",
-				"subs.prop.last_error",
-				"subs.prop.num_read",
-				"subs.prop.num_unread",
-				"subs.prop.assoc",
-				"subs.prop.version",
-				"subs.prop.high_version",
-				"subscriptions.listwindow.popularity",
-				"subs.prop.template",
-				"subs.prop.auth",
-				"TableColumn.header.category",
-			};
-		
-		String	category_str;
-		
-		String category = subs.getCategory();
-		
-		if ( category == null ){
-			
-			category_str = MessageText.getString( "Categories.uncategorized" );
-			
-		}else{
-			
-			category_str = category;
-		}
-		
-		String[] values = { 
-				String.valueOf( history.isEnabled()),
-				String.valueOf( subs.isPublic()),
-				String.valueOf( history.isAutoDownload()),
-				String.valueOf( subs.isAutoDownloadSupported()),
-				String.valueOf( history.getCheckFrequencyMins() + " " + MessageText.getString( "ConfigView.text.minutes")),
-				df.format(new Date( history.getLastScanTime())),
-				df.format(new Date( history.getLastNewResultTime())),
-				df.format(new Date( history.getNextScanTime())),
-				(last_error.length()==0?MessageText.getString("PeersView.uniquepiece.none"):last_error),
-				String.valueOf( history.getNumRead()),
-				String.valueOf( history.getNumUnread()),
-				String.valueOf( subs.getAssociationCount()),
-				String.valueOf( subs.getVersion()),
-				subs.getHighestVersion() > subs.getVersion()?String.valueOf( subs.getHighestVersion()):null,
-				subs.getCachedPopularity()<=1?null:String.valueOf( subs.getCachedPopularity()),
-				engine_str,
-				auth_str,
-				category_str,
-			};
-		
-		new PropertiesWindow( subs.getName(), keys, values );
-	}
-	
-	private String
-	toString(
-		String[]	strs )
-	{
-		String	res = "";
-		
-		for(int i=0;i<strs.length;i++){
-			res += (i==0?"":",") + strs[i];
+		synchronized (columns) {
+  		for ( Iterator<TableColumn> iter = columns.iterator(); iter.hasNext();){
+  			
+  			TableColumn column = iter.next();
+  			
+  			column.invalidateCells();
+  		}
 		}
-		
-		return( res );
 	}
 	
 	protected Graphic
@@ -1911,7 +1313,7 @@ SubscriptionManagerUI
 		UISWTInstance	swt,
 		String			name )
 	{
-		Image	image = swt.loadImage( "org/gudy/azureus2/ui/icons/" + name );
+		Image	image = swt.loadImage( "com/aelitis/azureus/ui/images/" + name );
 
 		Graphic graphic = swt.createGraphic(image );
 		
@@ -1919,723 +1321,4 @@ SubscriptionManagerUI
 		
 		return( graphic );
 	}
-	
-	protected static class
-	subscriptionView
-		extends 	AbstractIView
-		implements 	ViewTitleInfo,OpenCloseSearchDetailsListener
-	{
-		private Subscription	subs;
-		
-		private Composite		parent_composite;
-		private Composite		composite;
-				
-		//private Label			info_lab;
-		//private Label			info_lab2;
-		//private StyledText	json_area;
-		//private Composite 		controls;
-		
-		private Browser			mainBrowser;
-		private Browser			detailsBrowser;
-
-		private SideBarVitalityImage spinnerImage;
-		
-		protected
-		subscriptionView(
-			Subscription		_subs )
-		{
-			subs = _subs;
-		}
-		
-		public void delete() {
-			super.delete();
-		}
-		
-		public Object 
-		getTitleInfoProperty(
-			int propertyID ) 
-		{
-			switch( propertyID ){
-			
-				case ViewTitleInfo.TITLE_TEXT:{
-					
-					return( subs.getName());
-				}
-				case ViewTitleInfo.TITLE_INDICATOR_TEXT_TOOLTIP:{
-				
-					long	pop = subs.getCachedPopularity();
-					
-					String res = subs.getName();
-					
-					if ( pop > 1 ){
-						
-						res += " (" + MessageText.getString("subscriptions.listwindow.popularity").toLowerCase() + "=" + pop + ")";
-					}
-					
-					return( res );
-				}
-				case ViewTitleInfo.TITLE_INDICATOR_TEXT :{
-					if(subs.getHistory().getNumUnread() > 0) {
-						return ( "" + subs.getHistory().getNumUnread());
-					}
-					return null;
-				}
-			}
-			
-			return( null );
-		}
-
-		public void 
-		initialize(
-			Composite _parent_composite )
-		{  
-			parent_composite	= _parent_composite;
-			
-			parent_composite.addListener(
-				SWT.Show,
-				new Listener()
-				{
-					public void 
-					handleEvent(
-						Event arg0 )
-					{
-						createBrowsers();
-					}				
-				});
-			
-			parent_composite.addListener(
-					SWT.Hide,
-					new Listener()
-					{
-						public void 
-						handleEvent(
-							Event arg0 )
-						{
-							if (spinnerImage != null) {
-								spinnerImage.setVisible(false);
-							}
-							destroyBrowsers();
-						}				
-					});
-			
-			composite = new Composite( parent_composite, SWT.NULL );
-			
-			composite.setLayout(new FormLayout());
-			
-			//GridData grid_data = new GridData(GridData.FILL_BOTH );
-			//composite.setLayoutData(grid_data);
-			//FormData data;
-
-				// control area
-			
-			/*
-			controls = new Composite(composite, SWT.NONE);
-			GridLayout layout = new GridLayout();
-			layout.numColumns = 1;
-			layout.marginHeight = 0;
-			layout.marginWidth = 0;
-			controls.setLayout(layout);
-			
-			data = new FormData();
-			data.left = new FormAttachment(0,0);
-			data.right = new FormAttachment(100,0);
-			data.top = new FormAttachment(0,0);
-			controls.setLayoutData(data);
-			
-			GridData grid_data;
-
-			info_lab = new Label( controls, SWT.NULL );
-			grid_data = new GridData(GridData.FILL_HORIZONTAL);
-			info_lab.setLayoutData(grid_data);
-		
-				
-			info_lab2 = new Label( controls, SWT.NULL );
-			grid_data = new GridData(GridData.FILL_HORIZONTAL);
-			info_lab2.setLayoutData(grid_data);
-			
-			json_area = new StyledText(controls,SWT.BORDER);
-			grid_data = new GridData(GridData.FILL_HORIZONTAL);
-			grid_data.heightHint = 50;
-			json_area.setLayoutData(grid_data);
-			json_area.setWordWrap(true);
-			*/
-			
-			subs.addListener(
-				new SubscriptionListener()
-				{
-					public void 
-					subscriptionChanged(
-						Subscription subs ) 
-					{
-						Utils.execSWTThread(
-							new Runnable()
-							{
-								public void
-								run()
-								{
-									updateInfo();
-								}
-							});
-					}
-					
-					public void
-					subscriptionDownloaded(
-						Subscription		subs,
-						boolean				auto )
-					{
-						if ( auto ){
-							
-							updateBrowser( true );
-						}
-					}
-				});
-						
-			updateInfo();
-		}
-		  
-		
-		protected void
-		createBrowsers()
-		{
-			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);
-				
-				context.addListener(new BrowserContext.loadingListener(){
-					public void browserLoadingChanged(boolean loading, String url) {
-						if (spinnerImage != null) {
-							spinnerImage.setVisible(loading);
-						}
-					}
-				});
-				
-				context.addMessageListener(new TorrentListener());
-				context.addMessageListener(new VuzeListener());
-				context.addMessageListener(new DisplayListener(mainBrowser));
-				context.addMessageListener(new ConfigListener(mainBrowser));
-				context.addMessageListener(
-						new MetaSearchListener( this ));
-				
-				ContentNetwork contentNetwork = ContentNetworkManagerFactory.getSingleton().getContentNetwork(
-						context.getContentNetworkID());
-				// contentNetwork won't be null because a new browser context
-				// has the default content network
-				
-				String url = contentNetwork.getSubscriptionURL(subs.getID());
-					
-				Boolean	edit_mode = (Boolean)subs.getUserData( SUB_EDIT_MODE_KEY );
-				
-				if ( edit_mode != null ){
-				
-					if ( edit_mode.booleanValue()){
-						
-						url += EDIT_MODE_MARKER;
-					}
-					
-					subs.setUserData( SUB_EDIT_MODE_KEY, null );
-				}
-								
-				mainBrowser.setUrl(url);
-				mainBrowser.setData("StartURL", url);
-				
-				FormData data = new FormData();
-				data.left = new FormAttachment(0,0);
-				data.right = new FormAttachment(100,0);
-				data.top = new FormAttachment(composite,0);
-				data.bottom = new FormAttachment(100,0);
-				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(){
-					public void browserLoadingChanged(boolean loading, String url) {
-						if (spinnerImage != null) {
-							spinnerImage.setVisible(loading);
-						}
-					}
-				});
-				
-				ClientMessageContext.torrentURLHandler url_handler =
-					new ClientMessageContext.torrentURLHandler()
-					{
-						public void 
-						handleTorrentURL(
-							final String url ) 
-						{
-							Utils.execSWTThreadWithObject(
-								"SMUI",
-								new AERunnableObject()
-								{
-									public Object
-									runSupport()
-									{
-										String subscriptionId 		= (String)detailsBrowser.getData("subscription_id");
-										String subscriptionResultId = (String)detailsBrowser.getData("subscription_result_id");
-				
-										if ( subscriptionId != null && subscriptionResultId != null ){
-											
-											Subscription subs = SubscriptionManagerFactory.getSingleton().getSubscriptionByID( subscriptionId );
-										
-											if ( subs != null ){
-												
-												subs.addPotentialAssociation( subscriptionResultId, url );
-											}
-										}
-										
-										return( null );
-									}
-								},
-								10*1000 );
-						}
-					};
-					
-				detailsContext.setTorrentURLHandler( url_handler );
-				
-				TorrentListener torrent_listener = new TorrentListener();
-				
-				torrent_listener.setTorrentURLHandler( url_handler );
-				
-				detailsContext.addMessageListener( torrent_listener );
-				detailsContext.addMessageListener(new VuzeListener());
-				detailsContext.addMessageListener(new DisplayListener(detailsBrowser));
-				detailsContext.addMessageListener(new ConfigListener(detailsBrowser));
-				url = "about:blank";
-				detailsBrowser.setUrl(url);
-				detailsBrowser.setData("StartURL", url);
-				
-				final ExternalLoginCookieListener cookieListener = new ExternalLoginCookieListener(new CookiesListener() {
-					public void cookiesFound(String cookies) {
-						detailsBrowser.setData("current-cookies", cookies);
-					}
-				},detailsBrowser);
-				
-				cookieListener.hook();
-				
-				data = new FormData();
-				data.left = new FormAttachment(0,0);
-				data.right = new FormAttachment(100,0);
-				data.top = new FormAttachment(mainBrowser,0);
-				data.bottom = new FormAttachment(100,0);
-				detailsBrowser.setLayoutData(data);
-								
-				mainBrowser.setVisible( true );
-				detailsBrowser.setVisible( false );
-				//detailsBrowser.set
-				mainBrowser.getParent().layout(true,true);
-				
-				
-				ISelectedContent[] sels = {
-					new SubscriptionSelectedContent( 
-						new ToolBarEnabler()
-						{
-							  public boolean 
-							  isEnabled(
-								  String itemKey )
-							  {
-								  return( "share".equals(itemKey) || "remove".equals(itemKey));
-							  }
-							  
-							  public boolean 
-							  isSelected(
-								  String itemKey )
-							  {
-								  return( false );
-							  }
-							  
-							  public void 
-							  itemActivated(
-								String itemKey )
-							  {
-								  removeWithConfirm( subs );
-							  }
-						}, 
-						subs )};
-								
-				SelectedContentManager.changeCurrentlySelectedContent("IconBarEnabler", sels );
-				
-			}catch( Throwable e ){
-			
-				Debug.printStackTrace(e);
-			}
-		}
-		
-		protected void
-		destroyBrowsers()
-		{
-			if ( mainBrowser != null ){
-			
-				mainBrowser.dispose();
-				
-				mainBrowser = null;
-			}
-			
-			if ( detailsBrowser != null ){
-				
-				detailsBrowser.dispose();
-
-				detailsBrowser = null;
-			}
-		}
-		
-		public void closeSearchResults(final Map params) {
-			Utils.execSWTThread(new AERunnable() {
-
-				public void runSupport() {
-					detailsBrowser.setVisible(false);
-					
-					FormData gd = (FormData) mainBrowser.getLayoutData();
-					gd.bottom = new FormAttachment(100, 0);
-					mainBrowser.setLayoutData(gd);
-		
-					mainBrowser.getParent().layout(true);
-					detailsBrowser.setUrl("about:blank");
-					//mainBrowser.setUrl( (String)mainBrowser.getData( "StartURL" ));
-				}
-			});
-		}
-		
-		public void openSearchResults(final Map params) {
-			Utils.execSWTThread(new AERunnable() {
-
-				public void runSupport() {
-					String url = MapUtils.getMapString(params, "url",
-							"http://google.com/search?q=" + Math.random());
-					if (UrlFilter.getInstance().urlCanRPC(url)) {
-						url = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(url, false, true);
-					}
-					
-					//Gudy, Not Tux, Listener Added
-					String listenerAdded = (String) detailsBrowser.getData("g.nt.la");
-					if(listenerAdded == null) {
-						detailsBrowser.setData("g.nt.la","");
-						detailsBrowser.addProgressListener(new ProgressListener() {
-							public void changed(ProgressEvent event) {}
-							
-							public void completed(ProgressEvent event) {
-								Browser search = (Browser) event.widget;
-								String execAfterLoad = (String) search.getData("execAfterLoad");
-								//Erase it, so that it's only used once after the page loads
-								search.setData("execAfterLoad",null);
-								if(execAfterLoad != null && ! execAfterLoad.equals("")) {
-									//String execAfterLoadDisplay = execAfterLoad.replaceAll("'","\\\\'");
-									//search.execute("alert('injecting script : " + execAfterLoadDisplay + "');");
-									boolean result = search.execute(execAfterLoad);
-									//System.out.println("Injection : " + execAfterLoad + " (" + result + ")");
-								}
-		
-							}
-						});
-					}
-					
-					
-					//Store the "css" match string in the search cdp browser object
-					String execAfterLoad = MapUtils.getMapString(params, "execAfterLoad", null);
-					
-					detailsBrowser.setData("execAfterLoad",execAfterLoad);
-					
-					
-					detailsBrowser.setData("subscription_id", MapUtils.getMapString(params, "subs_id", null));
-					detailsBrowser.setData("subscription_result_id", MapUtils.getMapString(params, "subs_rid", null));
-								
-					detailsBrowser.setUrl(url);
-					detailsBrowser.setData("StartURL", url);
-					detailsBrowser.setVisible(true);
-		
-					FormData data = (FormData) mainBrowser.getLayoutData();
-					data.bottom = null;
-					data.height = MapUtils.getMapInt(params, "top-height", 120);
-					//mainBrowser.setLayoutData(data);
-		
-					mainBrowser.getParent().layout(true,true);
-				}
-			});
-				
-		}
-		
-		protected void
-		updateBrowser(
-			final boolean	is_auto )
-		{
-			if ( mainBrowser != null ){
-				
-				Utils.execSWTThread(
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							if ( mainBrowser != null && mainBrowser.isVisible()){
-							
-								String url = (String)mainBrowser.getData( "StartURL" );
-
-									// see if end of edit process indicated by the subscription being
-									// re-downloaded on auto-mode
-								
-								if ( is_auto && url.endsWith( EDIT_MODE_MARKER )){
-									
-									url = url.substring(0,url.lastIndexOf( EDIT_MODE_MARKER ));
-								
-									mainBrowser.setData( "StartURL", url );
-								}
-								
-								mainBrowser.setUrl( url );
-							}
-						}
-					});
-			}
-		}
-		
-		protected void
-		updateInfo()
-		{
-			/*
-			String	engine_str = "";
-			
-			try{
-				Engine engine = subs.getEngine();
-				
-				engine_str = engine.getString();
-				
-			}catch( Throwable e ){
-				
-				engine_str = Debug.getNestedExceptionMessage(e);
-				
-				Debug.out(e);
-			}
-			
-			info_lab.setText( 
-					"ID=" + subs.getID() +
-					", version=" + subs.getVersion() +
-					", subscribed=" + subs.isSubscribed() +
-					", public=" + subs.isPublic() +
-					", mine=" + subs.isMine() +
-					", popularity=" + subs.getCachedPopularity() +
-					", associations=" + subs.getAssociationCount() +
-					", engine=" + engine_str );
-			
-			SubscriptionHistory history = subs.getHistory();
-			
-			info_lab2.setText( 
-					"History: " + 
-					"enabled=" + history.isEnabled() +
-					", auto=" + history.isAutoDownload() +
-					", last_scan=" + new SimpleDateFormat().format(new Date( history.getLastScanTime())) +
-					", next_scan=" + new SimpleDateFormat().format(new Date( history.getNextScanTime())) +
-					", last_new=" + new SimpleDateFormat().format(new Date( history.getLastNewResultTime())) +
-					", read=" + history.getNumRead() +
-					" ,unread=" + history.getNumUnread() +
-					", error=" + history.getLastError() + " [af=" + history.isAuthFail() + "]" );
-					
-			try{
-			
-				json_area.setText( subs.getJSON());
-				
-			}catch( Throwable e ){
-				
-				e.printStackTrace();
-			}
-			*/
-		}
-		
-		public Composite 
-		getComposite()
-		{ 
-			return( composite );
-		}
-		
-		public String 
-		getFullTitle() 
-		{
-			return( subs.getName());
-		}
-		
-		public void resizeMainBrowser() {
-			if ( mainBrowser != null ){
-				
-				Utils.execSWTThreadLater(0,
-					new Runnable()
-					{
-						public void
-						run()
-						{
-							if ( mainBrowser != null && ! mainBrowser.isDisposed() && mainBrowser.isVisible()){
-							
-								FormData data = (FormData) mainBrowser.getLayoutData();
-								data.bottom = new FormAttachment(100,-1);
-								mainBrowser.getParent().layout(true);
-								Utils.execSWTThreadLater(0,
-										new Runnable() {
-									public void run() {
-										if ( mainBrowser != null && ! mainBrowser.isDisposed() && mainBrowser.isVisible()){
-											
-											FormData data = (FormData) mainBrowser.getLayoutData();
-											data.bottom = new FormAttachment(100,0);
-											mainBrowser.getParent().layout(true);
-										}
-									}
-								}
-								);
-							}
-						}
-					});
-			}
-			
-		}
-		
-		public void resizeSecondaryBrowser() {
-			// TODO Auto-generated method stub
-			
-		}
-
-		/**
-		 * @param spinnerImage
-		 *
-		 * @since 3.1.1.1
-		 */
-		public void setSpinnerImage(SideBarVitalityImage spinnerImage) {
-			this.spinnerImage = spinnerImage;
-		}
-	}
-	
-	public static class
-	sideBarItem
-	{
-		private subscriptionView	view;
-		private SideBarEntrySWT		sb_entry;
-		private TreeItem			tree_item;
-		private boolean				destroyed;
-		
-		private SideBarVitalityImage	warning;
-		private SideBarVitalityImage 	spinnerImage;
-		
-		protected
-		sideBarItem()
-		{
-		}
-		
-		protected void
-		setTreeItem(
-			TreeItem		_tree_item,
-			SideBarEntrySWT	_sb_entry )
-		{
-			tree_item	= _tree_item;
-			sb_entry	= _sb_entry;
-			
-			warning = sb_entry.addVitalityImage( ALERT_IMAGE_ID );
-			
-			spinnerImage = sb_entry.addVitalityImage("image.sidebar.vitality.dots");
-			
-			spinnerImage.setVisible(false);
-			
-			if ( view != null ){
-				
-				view.setSpinnerImage(spinnerImage);
-			}
-		}
-		
-		protected TreeItem
-		getTreeItem()
-		{
-			return( tree_item );
-		}
-		
-		protected void
-		setView(
-			subscriptionView		_view )
-		{
-			view	= _view;
-			
-			if (view != null) {
-				
-				view.setSpinnerImage( spinnerImage );
-			}
-		}
-		
-		protected subscriptionView
-		getView()
-		{
-			return( view );
-		}
-		
-		protected void
-		setWarning(
-			Subscription	subs )
-		{
-				// possible during initialisation, status will be shown again on complete
-			
-			if ( warning == null ){
-				
-				return;
-			}
-			
-			SubscriptionHistory history = subs.getHistory();
-			
-			String	last_error = history.getLastError();
-
-			boolean	auth_fail = history.isAuthFail();
-			
-				// don't report problem until its happened a few times, but not for auth fails as this is a perm error
-			
-			if ( history.getConsecFails() < 3 && !auth_fail ){
-				
-				last_error = null;
-			}
-			
-			boolean	trouble = last_error != null;
-			
-			if ( trouble ){
-			 
-				warning.setToolTip( last_error );
-				
-				warning.setImageID( auth_fail?AUTH_IMAGE_ID:ALERT_IMAGE_ID );
-				
-				warning.setVisible( true );
-				
-			}else{
-				
-				warning.setVisible( false );
-				
-				warning.setToolTip( "" );
-			}
-		}
-		
-		protected boolean
-		isDestroyed()
-		{
-			return( destroyed );
-		}
-		
-		protected void
-		destroy()
-		{
-			destroyed = true;
-		}
-		
-		public void 
-		activate() 
-		{
-			SideBar sideBar = (SideBar)SkinViewManager.getByClass(SideBar.class);
-			
-			if ( sideBar != null && sb_entry != null ){
-				
-				sideBar.showEntryByID(sb_entry.getId());
-			}
-		}
-	}
 }
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
index 716166e..6e1656e 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionSelectedContent.java
@@ -25,35 +25,34 @@ import java.io.File;
 import java.net.URL;
 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.TOTorrentCreator;
 import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
 import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
 
 import com.aelitis.azureus.core.subs.Subscription;
 import com.aelitis.azureus.core.vuzefile.VuzeFile;
+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.swt.toolbar.ToolBarEnablerSelectedContent;
 
 public class 
 SubscriptionSelectedContent 
-	extends ToolBarEnablerSelectedContent
 	implements ISelectedVuzeFileContent
 {
 	private Subscription		subs;
 	
+		// if you add more fields here be sure to amend 'sameAs' logic below
+	
 	private TOTorrent			torrent;
 	
 	protected
 	SubscriptionSelectedContent(
-		IconBarEnabler		_enabler,
 		Subscription		_subs )
 	{
-		super( _enabler );
-		
 		subs	= _subs;
 	}
 		
@@ -136,4 +135,50 @@ SubscriptionSelectedContent
 		
 		return( torrent );
 	}
+
+	public void setHash(String hash) {
+	}
+
+	public DownloadManager getDownloadManager() {
+		return null;
+	}
+
+	public int getFileIndex() {
+		return 0;
+	}
+
+	public void setDownloadManager(DownloadManager dm) {
+	}
+
+	public void setTorrent(TOTorrent torrent) {
+	}
+
+	public void setDisplayName(String displayName) {
+	}
+
+	public DownloadUrlInfo getDownloadInfo() {
+		return null;
+	}
+
+	public void setDownloadInfo(DownloadUrlInfo downloadInfo) {
+	}
+	
+	public boolean 
+	sameAs(
+		ISelectedContent _other ) 
+	{
+		if ( _other == this ){
+			
+			return( true );
+		}
+		
+		if ( _other instanceof SubscriptionSelectedContent ){
+			
+			SubscriptionSelectedContent other = (SubscriptionSelectedContent)_other;
+			
+			return( subs == other.subs );
+		}
+		
+		return( false );
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionView.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionView.java
new file mode 100644
index 0000000..d331620
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionView.java
@@ -0,0 +1,645 @@
+/**
+ * 
+ */
+package com.aelitis.azureus.ui.swt.subscriptions;
+
+import java.util.Map;
+
+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.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Composite;
+
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
+
+import com.aelitis.azureus.core.cnetwork.ContentNetwork;
+import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
+import com.aelitis.azureus.core.messenger.ClientMessageContext;
+import com.aelitis.azureus.core.subs.Subscription;
+import com.aelitis.azureus.core.subs.SubscriptionListener;
+import com.aelitis.azureus.core.subs.SubscriptionManagerFactory;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.browser.BrowserWrapper;
+import com.aelitis.azureus.ui.swt.browser.CookiesListener;
+import com.aelitis.azureus.ui.swt.browser.OpenCloseSearchDetailsListener;
+import com.aelitis.azureus.ui.swt.browser.listener.*;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.util.ConstantsVuze;
+import com.aelitis.azureus.util.MapUtils;
+import com.aelitis.azureus.util.UrlFilter;
+
+public class
+SubscriptionView
+	implements OpenCloseSearchDetailsListener, UIPluginViewToolBarListener,
+	UISWTViewCoreEventListener
+{
+	private Subscription	subs;
+	
+	private Composite		parent_composite;
+	private Composite		composite;
+			
+	//private Label			info_lab;
+	//private Label			info_lab2;
+	//private StyledText	json_area;
+	//private Composite 		controls;
+	
+	private BrowserWrapper			mainBrowser;
+	private BrowserWrapper			detailsBrowser;
+	private SubscriptionMDIEntry 	mdiInfo;
+
+	private UISWTView swtView;
+
+	public
+	SubscriptionView()
+	{
+	}
+	
+
+	protected void refreshView() {
+		if (subs == null) {
+			return;
+		}
+		String key = "Subscription_" + ByteFormatter.encodeString(subs.getPublicKey());
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			MdiEntrySWT entry = mdi.getEntrySWT(key);
+			if (entry != null) {
+				UISWTViewEventListener eventListener = entry.getEventListener();
+				if (eventListener instanceof SubscriptionView) {
+					SubscriptionView subsView = (SubscriptionView) eventListener;
+					subsView.updateBrowser( false );
+				}
+			}
+		}
+	}
+
+
+	private void 
+	initialize(
+		Composite _parent_composite )
+	{  
+		parent_composite	= _parent_composite;
+		
+		composite = new Composite( parent_composite, SWT.NULL );
+		
+		composite.setLayout(new FormLayout());
+		
+		//GridData grid_data = new GridData(GridData.FILL_BOTH );
+		//composite.setLayoutData(grid_data);
+		//FormData data;
+
+			// control area
+		
+		/*
+		controls = new Composite(composite, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		controls.setLayout(layout);
+		
+		data = new FormData();
+		data.left = new FormAttachment(0,0);
+		data.right = new FormAttachment(100,0);
+		data.top = new FormAttachment(0,0);
+		controls.setLayoutData(data);
+		
+		GridData grid_data;
+
+		info_lab = new Label( controls, SWT.NULL );
+		grid_data = new GridData(GridData.FILL_HORIZONTAL);
+		info_lab.setLayoutData(grid_data);
+	
+			
+		info_lab2 = new Label( controls, SWT.NULL );
+		grid_data = new GridData(GridData.FILL_HORIZONTAL);
+		info_lab2.setLayoutData(grid_data);
+		
+		json_area = new StyledText(controls,SWT.BORDER);
+		grid_data = new GridData(GridData.FILL_HORIZONTAL);
+		grid_data.heightHint = 50;
+		json_area.setLayoutData(grid_data);
+		json_area.setWordWrap(true);
+		*/
+		
+		subs.addListener(
+			new SubscriptionListener()
+			{
+				public void 
+				subscriptionChanged(
+					Subscription subs ) 
+				{
+					Utils.execSWTThread(
+						new Runnable()
+						{
+							public void
+							run()
+							{
+								updateInfo();
+							}
+						});
+				}
+				
+				public void
+				subscriptionDownloaded(
+					Subscription		subs,
+					boolean				auto )
+				{
+					if ( auto ){
+						
+						updateBrowser( true );
+					}
+				}
+			});
+					
+		updateInfo();
+	}
+	  
+	
+	protected void
+	createBrowsers()
+	{
+		if (mainBrowser != null && !mainBrowser.isDisposed()) {
+			return;
+		}
+		try{
+			mainBrowser = new BrowserWrapper(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);
+				}
+			});
+			BrowserContext context = 
+				new BrowserContext("browser-window"	+ Math.random(), mainBrowser, null, true);
+			
+			context.addListener(new BrowserContext.loadingListener(){
+				public void browserLoadingChanged(boolean loading, String url) {
+					if (mdiInfo.spinnerImage != null) {
+						mdiInfo.spinnerImage.setVisible(loading);
+					}
+				}
+			});
+			
+			context.addMessageListener(new TorrentListener());
+			context.addMessageListener(new VuzeListener());
+			context.addMessageListener(new DisplayListener(mainBrowser));
+			context.addMessageListener(new ConfigListener(mainBrowser));
+			context.addMessageListener(
+					new MetaSearchListener( this ));
+			
+			ContentNetwork contentNetwork = ContentNetworkManagerFactory.getSingleton().getContentNetwork(
+					context.getContentNetworkID());
+			// contentNetwork won't be null because a new browser context
+			// has the default content network
+			
+			String url = contentNetwork.getSubscriptionURL(subs.getID());
+				
+			Boolean	edit_mode = (Boolean)subs.getUserData( SubscriptionManagerUI.SUB_EDIT_MODE_KEY );
+			
+			if ( edit_mode != null ){
+			
+				if ( edit_mode.booleanValue()){
+					
+					url += SubscriptionManagerUI.EDIT_MODE_MARKER;
+				}
+				
+				subs.setUserData( SubscriptionManagerUI.SUB_EDIT_MODE_KEY, null );
+			}
+							
+			mainBrowser.setUrl(url);
+			mainBrowser.setData("StartURL", url);
+			
+			FormData data = new FormData();
+			data.left = new FormAttachment(0,0);
+			data.right = new FormAttachment(100,0);
+			data.top = new FormAttachment(composite,0);
+			data.bottom = new FormAttachment(100,0);
+			mainBrowser.setLayoutData(data);
+			
+			detailsBrowser = new BrowserWrapper(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);
+				}
+			});
+			BrowserContext detailsContext = 
+				new BrowserContext("browser-window"	+ Math.random(), detailsBrowser, null, false);
+			detailsContext.addListener(new BrowserContext.loadingListener(){
+				public void browserLoadingChanged(boolean loading, String url) {
+					if (mdiInfo.spinnerImage != null) {
+						mdiInfo.spinnerImage.setVisible(loading);
+					}
+				}
+			});
+			
+			ClientMessageContext.torrentURLHandler url_handler =
+				new ClientMessageContext.torrentURLHandler()
+				{
+					public void 
+					handleTorrentURL(
+						final String url ) 
+					{
+						Utils.execSWTThreadWithObject(
+							"SMUI",
+							new AERunnableObject()
+							{
+								public Object
+								runSupport()
+								{
+									String subscriptionId 		= (String)detailsBrowser.getData("subscription_id");
+									String subscriptionResultId = (String)detailsBrowser.getData("subscription_result_id");
+			
+									if ( subscriptionId != null && subscriptionResultId != null ){
+										
+										Subscription subs = SubscriptionManagerFactory.getSingleton().getSubscriptionByID( subscriptionId );
+									
+										if ( subs != null ){
+											
+											subs.addPotentialAssociation( subscriptionResultId, url );
+										}
+									}
+									
+									return( null );
+								}
+							},
+							10*1000 );
+					}
+				};
+				
+			detailsContext.setTorrentURLHandler( url_handler );
+			
+			TorrentListener torrent_listener = new TorrentListener();
+			
+			torrent_listener.setTorrentURLHandler( url_handler );
+			
+			detailsContext.addMessageListener( torrent_listener );
+			detailsContext.addMessageListener(new VuzeListener());
+			detailsContext.addMessageListener(new DisplayListener(detailsBrowser));
+			detailsContext.addMessageListener(new ConfigListener(detailsBrowser));
+			url = "about:blank";
+			detailsBrowser.setUrl(url);
+			detailsBrowser.setData("StartURL", url);
+			
+			final ExternalLoginCookieListener cookieListener = new ExternalLoginCookieListener(new CookiesListener() {
+				public void cookiesFound(String cookies) {
+					if (detailsBrowser != null) {
+						detailsBrowser.setData("current-cookies", cookies);
+					}
+				}
+			},detailsBrowser);
+			
+			cookieListener.hook();
+			
+			data = new FormData();
+			data.left = new FormAttachment(0,0);
+			data.right = new FormAttachment(100,0);
+			data.top = new FormAttachment(mainBrowser.getBrowser(),0);
+			data.bottom = new FormAttachment(100,0);
+			detailsBrowser.setLayoutData(data);
+							
+			mainBrowser.setVisible( true );
+			detailsBrowser.setVisible( false );
+			//detailsBrowser.set
+			mainBrowser.getParent().layout(true,true);
+			
+			
+		}catch( Throwable e ){
+		
+			Debug.printStackTrace(e);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		list.put("share", UIToolBarItem.STATE_ENABLED);
+		list.put("remove", UIToolBarItem.STATE_ENABLED);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if (item.getID().equals("remove")) {
+	  	mdiInfo.removeWithConfirm();
+		}
+		return false;
+	}
+
+	protected void
+	destroyBrowsers()
+	{
+		if ( mainBrowser != null ){
+		
+			mainBrowser.dispose();
+			
+			mainBrowser = null;
+		}
+		
+		if ( detailsBrowser != null ){
+			
+			detailsBrowser.dispose();
+
+			detailsBrowser = null;
+		}
+	}
+	
+	public void closeSearchResults(final Map params) {
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				detailsBrowser.setVisible(false);
+				
+				FormData gd = (FormData) mainBrowser.getLayoutData();
+				gd.bottom = new FormAttachment(100, 0);
+				mainBrowser.setLayoutData(gd);
+	
+				mainBrowser.getParent().layout(true);
+				detailsBrowser.setUrl("about:blank");
+				//mainBrowser.setUrl( (String)mainBrowser.getData( "StartURL" ));
+			}
+		});
+	}
+	
+	public void openSearchResults(final Map params) {
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				String url = MapUtils.getMapString(params, "url",
+						"http://google.com/search?q=" + Math.random());
+				if (UrlFilter.getInstance().urlCanRPC(url)) {
+					url = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(url, false, true);
+				}
+				
+				//Gudy, Not Tux, Listener Added
+				String listenerAdded = (String) detailsBrowser.getData("g.nt.la");
+				if(listenerAdded == null) {
+					final BrowserWrapper browser = detailsBrowser;
+					detailsBrowser.setData("g.nt.la","");
+					detailsBrowser.addProgressListener(new ProgressListener() {
+						public void changed(ProgressEvent event) {}
+						
+						public void completed(ProgressEvent event) {
+								String execAfterLoad = (String) browser.getData("execAfterLoad");
+							//Erase it, so that it's only used once after the page loads
+								browser.setData("execAfterLoad",null);
+							if(execAfterLoad != null && ! execAfterLoad.equals("")) {
+								//String execAfterLoadDisplay = execAfterLoad.replaceAll("'","\\\\'");
+								//search.execute("alert('injecting script : " + execAfterLoadDisplay + "');");
+								boolean result = browser.execute(execAfterLoad);
+								//System.out.println("Injection : " + execAfterLoad + " (" + result + ")");
+							}
+	
+						}
+					});
+				}
+				
+				
+				//Store the "css" match string in the search cdp browser object
+				String execAfterLoad = MapUtils.getMapString(params, "execAfterLoad", null);
+				
+				detailsBrowser.setData("execAfterLoad",execAfterLoad);
+				
+				
+				detailsBrowser.setData("subscription_id", MapUtils.getMapString(params, "subs_id", null));
+				detailsBrowser.setData("subscription_result_id", MapUtils.getMapString(params, "subs_rid", null));
+							
+				detailsBrowser.setUrl(url);
+				detailsBrowser.setData("StartURL", url);
+				detailsBrowser.setVisible(true);
+	
+				FormData data = (FormData) mainBrowser.getLayoutData();
+				data.bottom = null;
+				data.height = MapUtils.getMapInt(params, "top-height", 120);
+				//mainBrowser.setLayoutData(data);
+	
+				mainBrowser.getParent().layout(true,true);
+			}
+		});
+			
+	}
+	
+	protected void
+	updateBrowser(
+		final boolean	is_auto )
+	{
+		if ( mainBrowser != null && !mainBrowser.isDisposed() ){
+			
+			Utils.execSWTThread(
+				new Runnable()
+				{
+					public void
+					run()
+					{
+						if ( mainBrowser != null && !mainBrowser.isDisposed() && mainBrowser.isVisible()){
+						
+							String url = (String)mainBrowser.getData( "StartURL" );
+
+								// see if end of edit process indicated by the subscription being
+								// re-downloaded on auto-mode
+							
+							if ( is_auto && url.endsWith( SubscriptionManagerUI.EDIT_MODE_MARKER )){
+								
+								url = url.substring(0,url.lastIndexOf( SubscriptionManagerUI.EDIT_MODE_MARKER ));
+							
+								mainBrowser.setData( "StartURL", url );
+							}
+							
+							mainBrowser.setUrl( url );
+						}
+					}
+				});
+		}
+	}
+	
+	protected void
+	updateInfo()
+	{
+		/*
+		String	engine_str = "";
+		
+		try{
+			Engine engine = subs.getEngine();
+			
+			engine_str = engine.getString();
+			
+		}catch( Throwable e ){
+			
+			engine_str = Debug.getNestedExceptionMessage(e);
+			
+			Debug.out(e);
+		}
+		
+		info_lab.setText( 
+				"ID=" + subs.getID() +
+				", version=" + subs.getVersion() +
+				", subscribed=" + subs.isSubscribed() +
+				", public=" + subs.isPublic() +
+				", mine=" + subs.isMine() +
+				", popularity=" + subs.getCachedPopularity() +
+				", associations=" + subs.getAssociationCount() +
+				", engine=" + engine_str );
+		
+		SubscriptionHistory history = subs.getHistory();
+		
+		info_lab2.setText( 
+				"History: " + 
+				"enabled=" + history.isEnabled() +
+				", auto=" + history.isAutoDownload() +
+				", last_scan=" + new SimpleDateFormat().format(new Date( history.getLastScanTime())) +
+				", next_scan=" + new SimpleDateFormat().format(new Date( history.getNextScanTime())) +
+				", last_new=" + new SimpleDateFormat().format(new Date( history.getLastNewResultTime())) +
+				", read=" + history.getNumRead() +
+				" ,unread=" + history.getNumUnread() +
+				", error=" + history.getLastError() + " [af=" + history.isAuthFail() + "]" );
+				
+		try{
+		
+			json_area.setText( subs.getJSON());
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+		*/
+	}
+	
+	private Composite 
+	getComposite()
+	{ 
+		return( composite );
+	}
+	
+	private String 
+	getFullTitle() 
+	{
+		if (subs == null) {
+			return "";
+		}
+		return( subs.getName());
+	}
+	
+	public void resizeMainBrowser() {
+		if ( mainBrowser != null ){
+			
+			Utils.execSWTThreadLater(0,
+				new Runnable()
+				{
+					public void
+					run()
+					{
+						if ( mainBrowser != null && ! mainBrowser.isDisposed() && mainBrowser.isVisible()){
+						
+							FormData data = (FormData) mainBrowser.getLayoutData();
+							data.bottom = new FormAttachment(100,-1);
+							mainBrowser.getParent().layout(true);
+							Utils.execSWTThreadLater(0,
+									new Runnable() {
+								public void run() {
+									if ( mainBrowser != null && ! mainBrowser.isDisposed() && mainBrowser.isVisible()){
+										
+										FormData data = (FormData) mainBrowser.getLayoutData();
+										data.bottom = new FormAttachment(100,0);
+										mainBrowser.getParent().layout(true);
+									}
+								}
+							}
+							);
+						}
+					}
+				});
+		}
+		
+	}
+	
+	public void resizeSecondaryBrowser() {
+		// TODO Auto-generated method stub
+		
+	}
+
+
+	private void viewActivated() {
+		if (subs != null && mdiInfo == null) {
+			mdiInfo = (SubscriptionMDIEntry) subs.getUserData(SubscriptionManagerUI.SUB_ENTRYINFO_KEY);
+		}
+		createBrowsers();
+	}
+
+	private void viewDeactivated() {
+		if (mdiInfo.spinnerImage != null) {
+			mdiInfo.spinnerImage.setVisible(false);
+		}
+		destroyBrowsers();
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	viewActivated();
+      	break;
+        
+      case UISWTViewEvent.TYPE_FOCUSLOST:
+      	viewDeactivated();
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        break;
+    }
+
+    return true;
+  }
+
+
+	private void dataSourceChanged(Object data) {
+		if (data instanceof Subscription) {
+			subs = (Subscription) data;
+			mdiInfo = (SubscriptionMDIEntry) subs.getUserData(SubscriptionManagerUI.SUB_ENTRYINFO_KEY);
+		}
+		if (subs != null && swtView != null) {
+    	swtView.setTitle(getFullTitle());
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
index cedaa64..5cc26f5 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionWizard.java
@@ -8,21 +8,38 @@ import org.eclipse.swt.custom.StackLayout;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.TableColumn;
 
 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.AERunnable;
+import org.gudy.azureus2.core3.util.ByteFormatter;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 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 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.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 
 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.subs.*;
 import com.aelitis.azureus.core.subs.SubscriptionUtils.SubscriptionDownloadDetails;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.common.table.TableSelectionListener;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
+import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 public class SubscriptionWizard {
@@ -33,6 +50,7 @@ public class SubscriptionWizard {
 	private static final int MODE_CREATE_RSS = 4;
 	
 	private static final int RANK_COLUMN_WIDTH = 85;
+	private static final String TABLE_SUB_WIZ = "SubscriptionWizard";
 	
 	private final String TITLE_OPT_IN = MessageText.getString("Wizard.Subscription.optin.title");
 	private final String TITLE_SUBSCRIBE = MessageText.getString("Wizard.Subscription.subscribe.title");
@@ -83,6 +101,8 @@ public class SubscriptionWizard {
 	
 	DownloadManager download;
 	private ImageLoader imageLoader;
+	private TableViewSWT<Subscription> tvSubscriptions;
+	private static boolean columnsAdded = false;
 	
 	public SubscriptionWizard() {
 		this(null);
@@ -115,12 +135,10 @@ public class SubscriptionWizard {
 		}
 		availableSubscriptions = (SubscriptionDownloadDetails[]) notYetSubscribed.toArray(new SubscriptionDownloadDetails[notYetSubscribed.size()]);*/
 		availableSubscriptions = SubscriptionUtils.getAllCachedDownloadDetails(core);
-		Arrays.sort(availableSubscriptions,new Comparator() {
-			public int compare(Object o1, Object o2) {
-				if(! (o1 instanceof SubscriptionDownloadDetails && o2 instanceof SubscriptionDownloadDetails)) return 0;
-				SubscriptionDownloadDetails sub1 = (SubscriptionDownloadDetails) o1;
-				SubscriptionDownloadDetails sub2 = (SubscriptionDownloadDetails) o2;
-				return sub1.getDownload().getDisplayName().compareTo(sub2.getDownload().getDisplayName());
+		Arrays.sort(availableSubscriptions,new Comparator<SubscriptionDownloadDetails>() {
+			public int compare(SubscriptionDownloadDetails o1, SubscriptionDownloadDetails o2) {
+				if (o1 == null || o2 == null) return 0;
+				return o1.getDownload().getDisplayName().compareTo(o2.getDownload().getDisplayName());
 			}
 		});
 		
@@ -625,18 +643,90 @@ public class SubscriptionWizard {
 			}
 		});
 		
-		final Table subscriptionTable = new Table(composite, SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.V_SCROLL | SWT.SINGLE);
-		
-		final TableColumn nameColumn = new TableColumn(subscriptionTable, SWT.NONE);
-		final TableColumn rankColumn = new TableColumn(subscriptionTable, SWT.NONE);
-		
+		initColumns();
 		
+		final Composite cTV = new Composite(composite, SWT.NONE);
+		cTV.setLayoutData(Utils.getFilledFormData());
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
+		cTV.setLayout(layout);
 
+		tvSubscriptions = TableViewFactory.createTableViewSWT(Subscription.class,
+				TABLE_SUB_WIZ, TABLE_SUB_WIZ, new TableColumnCore[0], "SubWizRank",
+				SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.V_SCROLL | SWT.SINGLE);
+		tvSubscriptions.setMenuEnabled(false);
+		tvSubscriptions.setHeaderVisible(false);
+		tvSubscriptions.setRowDefaultHeight(20);
+		
+		tvSubscriptions.initialize(cTV);
+
+		tvSubscriptions.getComposite().addListener(SWT.Resize, new Listener() {
+			public void handleEvent(Event event) {
+				org.gudy.azureus2.plugins.ui.tables.TableColumn tcName = tvSubscriptions.getTableColumn("SubWizName");
+				org.gudy.azureus2.plugins.ui.tables.TableColumn tcRank = tvSubscriptions.getTableColumn("SubWizRank");
+				Rectangle clientArea = ((Composite) event.widget).getClientArea();
+				tcName.setWidth(clientArea.width - tcRank.getWidth() - 1);
+			}
+		});
+		tvSubscriptions.addSelectionListener(new TableSelectionListener() {
+			
+			public void selected(TableRowCore[] row) {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						if (tvSubscriptions.getSelectedRowsSize() == 0) {
+							addButton.setEnabled(false);
+						} else {
+							addButton.setEnabled(true);
+							TableRowCore[] rows = tvSubscriptions.getSelectedRows();
+							Subscription subscription = (Subscription) rows[0].getDataSource();
+							if (subscription.isSubscribed()) {
+								addButton.setEnabled(false);
+							} else {
+								addButton.setEnabled(true);
+							}
+							addButton.setData("subscription", subscription);
+						}
+					}
+				});
+			}
+			
+			public void mouseExit(TableRowCore row) {
+			}
+			
+			public void mouseEnter(TableRowCore row) {
+			}
+			
+			public void focusChanged(TableRowCore focus) {
+			}
+			
+			public void deselected(TableRowCore[] rows) {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						if (tvSubscriptions.getSelectedRowsSize() == 0) {
+							addButton.setEnabled(false);
+						}
+					}
+				});
+			}
+			
+			public void defaultSelected(TableRowCore[] rows, int stateMask) {
+			}
+		}, false);
 		
-		//nameColumn.setText("name");
-		//rankColumn.setText("rank");
+
+		UIUpdaterSWT.getInstance().addUpdater(new UIUpdatable() {
+			
+			public void updateUI() {
+				if (tvSubscriptions != null) {
+					tvSubscriptions.refreshTable(false);
+				}
+			}
+			
+			public String getUpdateUIName() {
+				return "SubWiz";
+			}
+		});
 		
-//		subscriptionTable.setHeaderVisible(true);
 		Listener resizeListener = new Listener() {
 			
 			int last_width;
@@ -655,68 +745,35 @@ public class SubscriptionWizard {
 				
 				if(nbColumns == 1) {
 					table.getColumns()[0].setWidth(width);
-				} else {
-					
-					if(width > 100 + RANK_COLUMN_WIDTH) {
-						table.getColumns()[1].setWidth(RANK_COLUMN_WIDTH);
-						table.getColumns()[0].setWidth(width-RANK_COLUMN_WIDTH);
-					} else {
-						table.getColumns()[0].setWidth(100);
-						table.getColumns()[1].setWidth(width-RANK_COLUMN_WIDTH);
-					}
 				}
 				
 				((Table)event.widget).update();
 			}
 		};
 			
-		subscriptionTable.addListener(SWT.Resize , resizeListener);
+		//subscriptionTable.addListener(SWT.Resize , resizeListener);
 		libraryTable.addListener(SWT.Resize , resizeListener);
 		
-		final Listener subscriptionSelectionListener = new Listener() {
-			public void handleEvent(Event event) {
-				if(subscriptionTable.getSelectionCount() == 1) {
-					addButton.setEnabled(true);
-//					TableItem item = subscriptionTable.getSelection()[0];
-					Subscription subscription = subscriptions[subscriptionTable.getSelectionIndex()];
-					if(subscription.isSubscribed()) {
-						addButton.setEnabled(false);
-					} else {
-						addButton.setEnabled(true);
-					}
-					addButton.setData("subscription",subscription);
-				} else {
-					addButton.setEnabled(false);
-				}
-			}
-		};
-		
 		final Listener selectionListener = new Listener() {
 			public void handleEvent(Event event) {
 				TableItem item = (TableItem) event.item;
 				subscriptions = (Subscription[]) item.getData("subscriptions");
 				
+				tvSubscriptions.removeDataSources(tvSubscriptions.getDataSources().toArray(new Subscription[0]));
 				if(subscriptions != null) {
-					Arrays.sort(subscriptions,new Comparator() {
-						public int compare(Object o1, Object o2) {
-							if(! (o1 instanceof Subscription && o2 instanceof Subscription)) return 0;
-							Subscription sub1 = (Subscription) o1;
-							Subscription sub2 = (Subscription) o2;
-							return (int) (sub2.getCachedPopularity() - sub1.getCachedPopularity());
-						}
-					});
-					subscriptionTable.setItemCount(subscriptions.length);
+					tvSubscriptions.addDataSources(subscriptions);
 				}
+				tvSubscriptions.processDataSourceQueueSync();
 				
 				addButton.setEnabled(false);
 				addButton.setData("subscription",null);
-				subscriptionTable.clearAll();			
-				subscriptionTable.deselectAll();
-				if(subscriptionTable.getItemCount() > 0) {
-					subscriptionTable.setSelection(0);
-					subscriptionSelectionListener.handleEvent(null);
+				tvSubscriptions.setSelectedRows(new TableRowCore[0]);
+				if (subscriptions != null && subscriptions.length > 0) {
+					TableRowCore row = tvSubscriptions.getRow(subscriptions[0]);
+					if (row != null) {
+						row.setSelected(true);
+					}
 				}
-				//subscriptionTable.setFocus();
 			}
 		};
 		
@@ -778,117 +835,16 @@ public class SubscriptionWizard {
 		addButton.setData("subscription",null);
 		
 		
-		
-		subscriptionTable.addListener(SWT.Selection,subscriptionSelectionListener );
-		
-
 		final Image rssIcon = imageLoader.getImage("icon_rss");
-		if(availableSubscriptions != null) {
-			subscriptionTable.addListener(SWT.SetData, new Listener() {
-				public void handleEvent(Event event) {
-					  final TableItem item = (TableItem) event.item;
-			          int index = subscriptionTable.indexOf (item);
-			          Subscription subscription = subscriptions[index];
-			          item.setImage(rssIcon);
-			          item.setText(0, subscription.getName());
-			          item.setData("tooltip", subscription.getNameEx());
-			          item.setData("popularity", new Long(subscription.getCachedPopularity()));
-			          if(subscription.isSubscribed()) {
-			        	  item.setForeground(display.getSystemColor(SWT.COLOR_GRAY));
-			        	  subscriptionTable.setSelection(item);
-			          }
-				}
-			});
-			
-		} else {
-			//Test code
-			subscriptionTable.addListener(SWT.SetData, new Listener() {
-				public void handleEvent(Event event) {
-					  TableItem item = (TableItem) event.item;
-			          int index = subscriptionTable.indexOf (item);
-			          item.setImage( rssIcon);
-			          item.setText (0,"sub test " + index);
-			          item.setData("popularity", new Long((int)(700*Math.random() - 100 )));
-			          //item.setText (1,"" + index);
-			          //item.setImage(1, rssIcon);
-				}
-			});
-		}		
-		
-		Listener paintListener = new Listener() {
-			public void handleEvent(Event event) {
-				GC gc = event.gc;
-				TableItem item = (TableItem) event.item;
 
-				switch (event.type) {
-				case SWT.MeasureItem:
-					event.height = 20;
-					break;
-				case SWT.EraseItem:
-					Rectangle bounds = item.getBounds(1);
-					gc.setBackground(item.getBackground(1));
-					gc.setForeground(item.getBackground(1));
-					gc.fillRectangle(bounds);
-					break;
-				case SWT.PaintItem :
-					bounds = item.getBounds(1);
-					bounds.width -= 3;
-					bounds.height -= 7;
-					bounds.x += 1;
-					bounds.y += 3;
-					gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-					gc.fillRectangle(bounds);
-					gc.setForeground(rankingBorderColor);
-					gc.drawRectangle(bounds);
-					bounds.width -= 2;
-					bounds.height -= 2;
-					bounds.x += 1;
-					bounds.y += 1;
-					
-					
-					Long pop = (Long) item.getData("popularity");
-					if(pop != null) {
-						long popularity = pop.longValue();
-						//Rank in pixels between 0 and 80
-						//0 -> no subscriber
-						//80 -> 1000 subscribers
-						
-						int rank = 80 * (int) popularity / 1000;
-						if(rank > 80) rank = 80;
-						if(rank < 5) rank = 5;
-						
-						Rectangle clipping = gc.getClipping();
-						
-						bounds.width = rank;
-						bounds.height -= 1;
-						bounds.x += 1;
-						bounds.y += 1;
-						gc.setClipping(bounds);
-						gc.drawImage(rankingBars, bounds.x, bounds.y);
-						
-						
-						gc.setClipping(clipping);
-						
-					}
-					
-					break;
-				default:
-					break;
-				}
+		libraryTable.addListener(SWT.MeasureItem, new Listener() {
+			public void handleEvent(Event event) {
+				event.height = 20;
 			}
-		};
-		
-			// use this as native one end up with progress image overwriting tooltip
-		
-		new CustomTableTooltipHandler( subscriptionTable );
+		});
 		
-		subscriptionTable.addListener(SWT.EraseItem, paintListener);
-		subscriptionTable.addListener(SWT.PaintItem, paintListener);
-		subscriptionTable.addListener(SWT.MeasureItem, paintListener);
-		libraryTable.addListener(SWT.MeasureItem, paintListener);
-		
-		FormLayout layout = new FormLayout();
-		composite.setLayout(layout);
+		FormLayout formLayout = new FormLayout();
+		composite.setLayout(formLayout);
 		
 		FormData data;
 		
@@ -945,11 +901,121 @@ public class SubscriptionWizard {
 		data.left = new FormAttachment(vsep, 0);
 		data.right = new FormAttachment(100, 0);
 		data.bottom = new FormAttachment(100, 0);
-		subscriptionTable.setLayoutData(data);
+		cTV.setLayoutData(data);
+
 		
 		return composite;
 	}
 	
+	private static void initColumns() {
+		if (columnsAdded) {
+			return;
+		}
+		columnsAdded = true;
+		UIManager uiManager = PluginInitializer.getDefaultInterface().getUIManager();
+		TableManager tableManager = uiManager.getTableManager();
+		tableManager.registerColumn(Subscription.class, "SubWizName",
+				new TableColumnCreationListener() {
+					private Image rssIcon;
+
+					public void tableColumnCreated(
+							org.gudy.azureus2.plugins.ui.tables.TableColumn column) {
+						
+							// this'll get triggered for the Subscriptions Overview table too - easiest fix is to default to hidden there
+						
+						column.setVisible( column.getTableID().equals( "SubscriptionWizard" ));
+						ImageLoader imageLoader = ImageLoader.getInstance();
+						rssIcon = imageLoader.getImage("icon_rss");
+
+						column.addCellAddedListener(new TableCellAddedListener() {
+							public void cellAdded(TableCell cell) {
+								Subscription sub = (Subscription) cell.getDataSource();
+								if (sub.isSubscribed()) {
+									cell.setForeground(0xa0, 0xa0, 0xa0);
+								}
+								cell.setText(sub.getName());
+								((TableCellSWT) cell).setIcon(rssIcon);
+								cell.setToolTip(sub.getNameEx());
+							}
+						});
+					}
+				});
+		tableManager.registerColumn(Subscription.class, "SubWizRank",
+				new TableColumnCreationListener() {
+					public void tableColumnCreated(
+							org.gudy.azureus2.plugins.ui.tables.TableColumn column) {
+						column.setWidthLimits(RANK_COLUMN_WIDTH, RANK_COLUMN_WIDTH);
+						column.setVisible(column.getTableID().equals( "SubscriptionWizard" ));	// as above
+						column.addCellRefreshListener(new TableCellRefreshListener() {
+							public void refresh(TableCell cell) {
+								Subscription sub = (Subscription) cell.getDataSource();
+								cell.setSortValue(sub.getCachedPopularity());
+							}
+						});
+						if (column instanceof TableColumnCore) {
+							TableColumnCore columnCore = (TableColumnCore) column;
+							columnCore.setSortAscending(false);
+							columnCore.addCellOtherListener("SWTPaint",
+									new TableCellSWTPaintListener() {
+										public void cellPaint(GC gc, TableCellSWT cell) {
+											Subscription sub = (Subscription) cell.getDataSource();
+
+											Rectangle bounds = cell.getBounds();
+											bounds.width -= 5;
+											bounds.height -= 7;
+											bounds.x += 2;
+											bounds.y += 3;
+											gc.setBackground(ColorCache.getColor(gc.getDevice(), 255,
+													255, 255));
+											gc.fillRectangle(bounds);
+											gc.setForeground(ColorCache.getColor(gc.getDevice(), 200,
+													200, 200));
+											gc.drawRectangle(bounds);
+											bounds.width -= 2;
+											bounds.height -= 2;
+											bounds.x += 1;
+											bounds.y += 1;
+
+											long popularity = sub.getCachedPopularity();
+											//Rank in pixels between 0 and 80
+											//0 -> no subscriber
+											//80 -> 1000 subscribers
+
+											int rank = 80 * (int) popularity / 1000;
+											if (rank > 80)
+												rank = 80;
+											if (rank < 5)
+												rank = 5;
+
+											Rectangle clipping = gc.getClipping();
+
+											bounds.width = rank;
+											bounds.height -= 1;
+											bounds.x += 1;
+											bounds.y += 1;
+											gc.setClipping(bounds);
+
+											ImageLoader imageLoader = ImageLoader.getInstance();
+											Image rankingBars = imageLoader.getImage("ranking_bars");
+											gc.drawImage(rankingBars, bounds.x, bounds.y);
+											imageLoader.releaseImage("ranking_bars");
+
+											gc.setClipping(clipping);
+										}
+
+									});
+						}
+					}
+				});
+
+		TableColumnManager tcm = TableColumnManager.getInstance();
+		tcm.setDefaultColumnNames(TABLE_SUB_WIZ, new String[] {
+			"SubWizName",
+			"SubWizRank",
+		});
+
+	}
+
 	private void createFonts() {
 		
 		FontData[] fDatas = shell.getFont().getFontData();
@@ -1089,8 +1155,14 @@ public class SubscriptionWizard {
 					
 					user_data.put( SubscriptionManagerUI.SUB_EDIT_MODE_KEY, new Boolean( true ));
 					
-					SubscriptionManagerFactory.getSingleton().createRSS( url_str, url, SubscriptionHistory.DEFAULT_CHECK_INTERVAL_MINS, user_data );
+					Subscription subRSS = SubscriptionManagerFactory.getSingleton().createRSS( url_str, url, SubscriptionHistory.DEFAULT_CHECK_INTERVAL_MINS, user_data );
 					shell.close();
+
+					final String key = "Subscription_" + ByteFormatter.encodeString(subRSS.getPublicKey());				
+
+					MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+					mdi.showEntryByID(key);
+
 				} catch (Throwable e) {
 					
 					Utils.reportError( e );
@@ -1112,7 +1184,7 @@ public class SubscriptionWizard {
 		
 		searchListener = new Listener() {
 			public void handleEvent(Event event) {
-				MainWindow.doSearch(searchInput.getText(),true);
+				UIFunctionsManager.getUIFunctions().doSearch(searchInput.getText(),true);
 				shell.close();
 			}
 		};
diff --git a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
index 214a44f..6d7f4d5 100644
--- a/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
+++ b/com/aelitis/azureus/ui/swt/subscriptions/SubscriptionsView.java
@@ -1,5 +1,7 @@
 package com.aelitis.azureus.ui.swt.subscriptions;
 
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.KeyEvent;
 import org.eclipse.swt.events.KeyListener;
@@ -12,30 +14,37 @@ 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.ByteFormatter;
 import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.IndentWriter;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-import org.gudy.azureus2.ui.swt.views.IView;
 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.TableViewFactory;
 
 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.UIFunctionsManager;
 import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
-import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.columns.subscriptions.*;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.subscriptions.SubscriptionManagerUI.sideBarItem;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnabler;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 public class SubscriptionsView
-	implements UIUpdatable, IView, SubscriptionManagerListener, ToolBarEnabler
+	implements SubscriptionManagerListener, UIPluginViewToolBarListener,
+	UISWTViewCoreEventListener
 {
 	private static final String TABLE_ID = "subscriptions";
 
@@ -46,75 +55,82 @@ public class SubscriptionsView
 	private Font textFont1;
 	
 	private Font textFont2;
+
+	private UISWTView swtView;
 	
 	public SubscriptionsView() {
 	}
 	
 	
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.core.subs.SubscriptionManagerListener#associationsChanged(byte[])
+	 */
 	public void associationsChanged(byte[] association_hash) {
 		// TODO Auto-generated method stub
 		
 	}
 	
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.core.subs.SubscriptionManagerListener#subscriptionSelected(com.aelitis.azureus.core.subs.Subscription)
+	 */
 	public void 
 	subscriptionSelected(
 		Subscription subscription )
 	{		
 	}
 	
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.core.subs.SubscriptionManagerListener#subscriptionAdded(com.aelitis.azureus.core.subs.Subscription)
+	 */
 	public void subscriptionAdded(Subscription subscription) {
 		if ( subscription.isSubscribed()){
 			view.addDataSource(subscription);
 		}
 	}
 	
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.core.subs.SubscriptionManagerListener#subscriptionRemoved(com.aelitis.azureus.core.subs.Subscription)
+	 */
 	public void subscriptionRemoved(Subscription subscription) {
 		view.removeDataSource(subscription);
 		
 	}
 	
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.core.subs.SubscriptionManagerListener#subscriptionChanged(com.aelitis.azureus.core.subs.Subscription)
+	 */
 	public void subscriptionChanged(Subscription subscription) {
-		if ( view.getRow(subscription) == null ){
+		if ( !subscription.isSubscribed()){
+			subscriptionRemoved(subscription);
+		}else if ( view.getRow(subscription) == null ){
 			subscriptionAdded( subscription );
 		}else{
 			view.refreshTable(true);
 		}
 	}
-	
-	public boolean isEnabled(String itemKey) {
-		if("remove".equals(itemKey) ) {
-			return view.getSelectedRowsSize() > 0;
-		}
-		if("share".equals(itemKey) ) {
-			
-			TableRowCore[] rows = view.getSelectedRows();
-			
-			if ( rows.length == 1 ){
-				
-				Subscription subs = (Subscription) rows[0].getDataSource();
-									
-				return( true );
-			}
-			
-			return( false );
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		if ( view == null ){
+			return;	// can happen on first selection it seems
 		}
-		
-		return false;
-	}
-	
-	public String getUpdateUIName() {
-		// TODO Auto-generated method stub
-		return null;
-	}
-	
-	public boolean isSelected(String itemKey) {
-		return false;
+		int numRows = view.getSelectedRowsSize();
+		list.put("remove", numRows > 0 ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("share", numRows == 1 ? UIToolBarItem.STATE_ENABLED : 0);
 	}
-	
-	public void itemActivated(String itemKey) {
-		if("remove".equals(itemKey) ) {
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if("remove".equals(item.getID()) ) {
 			removeSelected();
+			return true;
 		}
+		return false;
 	}
 
 
@@ -129,6 +145,10 @@ public class SubscriptionsView
 	}
 	
 	private void removeSubs(final Subscription[] toRemove, final int startIndex) {
+		if (toRemove == null || startIndex >= toRemove.length) {
+			return;
+		}
+
 		if (toRemove[startIndex] == null) {
 			int nextIndex = startIndex + 1;
 			if (nextIndex < toRemove.length) {
@@ -159,11 +179,11 @@ public class SubscriptionsView
 		mb.open(new UserPrompterResultListener() {
 			public void prompterClosed(int result) {
 				if (result == 0) {
-					toRemove[startIndex].remove();
+					toRemove[startIndex].setSubscribed( false );
 				} else if (result == 2) {
 					for (int i = startIndex; i < toRemove.length; i++) {
 						if (toRemove[i] != null) {
-							toRemove[i].remove();
+							toRemove[i].setSubscribed( false );
 						}
 					}
 					return;
@@ -177,18 +197,8 @@ public class SubscriptionsView
 		});
 	}
 	
-	public void updateUI() {
-		// TODO Auto-generated method stub
-		
-	}
-	
-	public void dataSourceChanged(Object newDataSource) {
-		// TODO Auto-generated method stub
-		
-	}
 	
-	public void delete() {
-		view.delete();
+	private void delete() {
 		if (viewComposite != null && !viewComposite.isDisposed()) {
 			viewComposite.dispose();
 		}
@@ -200,27 +210,15 @@ public class SubscriptionsView
 		}
 	}
 	
-	public void generateDiagnostics(IndentWriter writer) {
-		view.generate(writer);
-	}
-	
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return viewComposite;
 	}
 	
-	public String getData() {
-		return "subscriptions.view.title";
-	}
-	
-	public String getFullTitle() {
-		return MessageText.getString("subscriptions.view.title");
-	}
-	
-	public String getShortTitle() {
-		return MessageText.getString("subscriptions.view.title");
+	private String getFullTitle() {
+		return MessageText.getString("subscriptions.overview");
 	}
 	
-	public void initialize(Composite parent) {
+	private void initialize(Composite parent) {
 		
 		viewComposite = new Composite(parent,SWT.NONE);
 		viewComposite.setLayout(new FormLayout());
@@ -237,7 +235,16 @@ public class SubscriptionsView
 				
 		};
 		
-		view = new TableViewSWTImpl(Subscription.class, TABLE_ID, TABLE_ID,
+		TableColumnManager tcm = TableColumnManager.getInstance();
+		tcm.setDefaultColumnNames(TABLE_ID, new String[] {
+			ColumnSubscriptionNew.COLUMN_ID,
+			ColumnSubscriptionName.COLUMN_ID,
+			ColumnSubscriptionNbNewResults.COLUMN_ID,
+			ColumnSubscriptionNbResults.COLUMN_ID,
+			ColumnSubscriptionAutoDownload.COLUMN_ID,
+		});
+		
+		view = TableViewFactory.createTableViewSWT(Subscription.class, TABLE_ID, TABLE_ID,
 				columns, "name", SWT.SINGLE | SWT.FULL_SELECTION | SWT.VIRTUAL);
 		
 		view.addLifeCycleListener(new TableLifeCycleListener() {
@@ -260,8 +267,11 @@ public class SubscriptionsView
 					
 					Subscription sub = (Subscription) row.getDataSource();
 					if(sub != null) {
-						sideBarItem item = (sideBarItem) sub.getUserData(SubscriptionManagerUI.SUB_IVIEW_KEY);
-						item.activate();
+						String key = "Subscription_" + ByteFormatter.encodeString(sub.getPublicKey());
+						MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+						if (mdi != null) {
+							mdi.showEntryByID(key);
+						}
 					}
 				}
 				
@@ -272,10 +282,10 @@ public class SubscriptionsView
 				
 				for (int i=0;i<rows.length;i++){
 					
-					sels[i] = new SubscriptionSelectedContent(SubscriptionsView.this, (Subscription)rows[i].getDataSource());
+					sels[i] = new SubscriptionSelectedContent((Subscription)rows[i].getDataSource());
 				}
 				
-				SelectedContentManager.changeCurrentlySelectedContent("IconBarEnabler",
+				SelectedContentManager.changeCurrentlySelectedContent(view.getTableID(),
 						sels, view);
 			}
 			
@@ -296,7 +306,7 @@ public class SubscriptionsView
 		view.setRowDefaultHeight(20);
 		
 		view.initialize(viewComposite);
-		
+
 		final Composite composite = new Composite(viewComposite,SWT.BORDER);
 		composite.setBackgroundMode(SWT.INHERIT_DEFAULT);
 		composite.setBackground(ColorCache.getColor(composite.getDisplay(), "#F1F9F8"));
@@ -366,7 +376,7 @@ public class SubscriptionsView
 		
 		data = new FormData();
 		data.left = new FormAttachment(preText,5);
-		data.top = new FormAttachment(preText,0,SWT.TOP);
+		data.top = new FormAttachment(preText,0,SWT.CENTER);
 		image.setLayoutData(data);
 		
 		data = new FormData();
@@ -385,37 +395,62 @@ public class SubscriptionsView
 		data.right = new FormAttachment(100,0);
 		data.top = new FormAttachment(0,0);
 		data.bottom = new FormAttachment(composite,0);		
-		view.getComposite().setLayoutData(data);
+		viewComposite.setLayoutData(data);
 		
 		data = new FormData();
 		data.left = new FormAttachment(0,0);
 		data.right = new FormAttachment(100,0);
 		data.bottom = new FormAttachment(100,0);		
 		composite.setLayoutData(data);
-		
+
 		COConfigurationManager.setBooleanDefault("subscriptions.view.showhelp", true);
 		if(!COConfigurationManager.getBooleanParameter("subscriptions.view.showhelp")) {
 			composite.setVisible(false);
-			data = (FormData) view.getComposite().getLayoutData();
+			data = (FormData) viewComposite.getLayoutData();
 			data.bottom = new FormAttachment(100,0);
 			viewComposite.layout(true);
 		}
-
-	}
-	
-	public void refresh() {
-		view.refreshTable(false);
 	}
 	
-	public void updateLanguage() {
-		view.updateLanguage();
+	private void refresh() {
+		if ( view != null ){
+			view.refreshTable(false);
+		}
 	}
-	
-	
-	
-	
-	
-	
-	
-	
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	//dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
+
 }
diff --git a/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnabler.java b/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnabler.java
deleted file mode 100644
index 9966a6e..0000000
--- a/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnabler.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.aelitis.azureus.ui.swt.toolbar;
-
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
-
-public interface ToolBarEnabler extends IconBarEnabler{
-
-}
diff --git a/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnablerSelectedContent.java b/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnablerSelectedContent.java
deleted file mode 100644
index 9877afd..0000000
--- a/com/aelitis/azureus/ui/swt/toolbar/ToolBarEnablerSelectedContent.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.aelitis.azureus.ui.swt.toolbar;
-
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
-
-import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
-
-public class ToolBarEnablerSelectedContent implements ISelectedContent {
-
-	private IconBarEnabler enabler;
-	
-	public ToolBarEnablerSelectedContent(IconBarEnabler enabler) {
-		this.enabler = enabler;
-	}
-	
-	public DownloadManager getDownloadManager() {
-		return null;
-	}
-
-	public TOTorrent getTorrent() {
-		return null;
-	}
-	public String getDisplayName() {
-		return "";
-	}
-
-	public DownloadUrlInfo getDownloadInfo() {
-		return null;
-	}
-
-	public String getHash() {
-		return null;
-	}
-
-	public void setDownloadManager(DownloadManager dm) {
-
-	}
-
-	public void setTorrent(TOTorrent t ){
-		
-	}
-	
-	public void setDisplayName(String displayName) {
-
-	}
-
-	public void setDownloadInfo(DownloadUrlInfo downloadInfo) {
-
-	}
-
-	public void setHash(String hash) {
-
-	}
-	
-	public IconBarEnabler getIconBarEnabler() {
-		return enabler;
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/toolbar/ToolBarItem.java b/com/aelitis/azureus/ui/swt/toolbar/ToolBarItem.java
deleted file mode 100644
index 5678094..0000000
--- a/com/aelitis/azureus/ui/swt/toolbar/ToolBarItem.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * Created on Jul 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.ui.swt.toolbar;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
-
-/**
- * @author TuxPaper
- * @created Jul 22, 2008
- *
- */
-public class ToolBarItem
-{
-	String imageID;
-
-	String id;
-
-	private SWTSkinButtonUtility skinButton;
-	
-	boolean enabled = true;
-	
-	private String textID;
-	
-	private String tooltipID;
-	
-	private List listeners = Collections.EMPTY_LIST;
-
-	/**
-	 * @param id
-	 * @param image
-	 */
-	public ToolBarItem(String id, String imageid) {
-		super();
-		this.id = id;
-		imageID = imageid;
-	}
-
-	public ToolBarItem(String id, String imageid, String textID) {
-		super();
-		this.id = id;
-		imageID = imageid;
-		this.textID = textID;
-		this.tooltipID = textID + ".tooltip";
-	}
-
-	public void triggerToolBarItem() {
-		Object[] array = listeners.toArray();
-		for (int i = 0; i < array.length; i++) {
-			ToolBarItemListener l = (ToolBarItemListener) array[i];
-			l.pressed(this);
-		}
-	}
-
-
-	public String getId() {
-		return id;
-	}
-
-	public void setSkinButton(SWTSkinButtonUtility btn) {
-		this.skinButton = btn;
-	}
-
-	public SWTSkinButtonUtility getSkinButton() {
-		return skinButton;
-	}
-
-	public boolean isEnabled() {
-		if (skinButton != null) {
-			return !skinButton.isDisabled();
-		}
-		return enabled;
-	}
-
-	public void setEnabled(boolean enabled) {
-		this.enabled = enabled;
-		if (skinButton != null) {
-			skinButton.setDisabled(!enabled);
-		}
-	}
-
-	public String getImageID() {
-		return imageID;
-	}
-
-	public void setImageID(String imageID) {
-		this.imageID = imageID;
-	}
-
-	/**
-	 * @param textID the textID to set
-	 */
-	public void setTextID(String textID) {
-		this.textID = textID;
-	}
-
-	/**
-	 * @return the textID
-	 */
-	public String getTextID() {
-		return textID;
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public boolean triggerToolBarItemHold() {
-		Object[] array = listeners.toArray();
-		for (int i = 0; i < array.length; i++) {
-			ToolBarItemListener l = (ToolBarItemListener) array[i];
-			if (l.held(this)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public String getTooltipID() {
-		return tooltipID;
-	}
-
-	public void setTooltipID(String tooltipID) {
-		this.tooltipID = tooltipID;
-	}
-	
-	public void addListener(ToolBarItemListener l) {
-		synchronized (ToolBarItem.class) {
-  		if (listeners == Collections.EMPTY_LIST) {
-  			listeners = new ArrayList(1);
-  		}
-  		listeners.add(l);
-		}
-	}
-	
-	public void removeListener(ToolBarItemListener l) {
-		synchronized (ToolBarItem.class) {
-  		listeners.remove(l);
-		}
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemListener.java b/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemListener.java
deleted file mode 100644
index 66b76af..0000000
--- a/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemListener.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Created on Oct 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.toolbar;
-
-
-/**
- * @author TuxPaper
- * @created Oct 6, 2008
- *
- */
-public interface ToolBarItemListener
-{
-	public boolean held(ToolBarItem toolBarItem);
-
-	public void pressed(ToolBarItem toolBarItem);
-}
diff --git a/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemSO.java b/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemSO.java
new file mode 100644
index 0000000..9a166f3
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/toolbar/ToolBarItemSO.java
@@ -0,0 +1,227 @@
+/**
+ * Created on Jul 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.ui.swt.toolbar;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectText;
+import com.aelitis.azureus.ui.swt.views.skin.ToolBarView;
+
+/**
+ * @author TuxPaper
+ * @created Jul 22, 2008
+ *
+ */
+public class ToolBarItemSO
+	implements ToolBarItem
+{
+	String imageID = "image.toolbar.run";
+
+	String id;
+
+	private SWTSkinButtonUtility skinButton;
+
+	private SWTSkinObjectText skinTitle;
+
+	boolean enabled = false;
+
+	private String textID;
+
+	private String tooltipID;
+
+	private boolean alwaysAvailable = false;
+
+	private final ToolBarView tbView;
+
+	private UIToolBarActivationListener defaultActivation;
+
+	private final boolean isPluginItem;
+
+	private String groupID = UIToolBarManager.GROUP_MAIN;
+
+	private long defaultState;
+
+	private boolean isDown;
+
+	/**
+	 * @param id
+	 * @param image
+	 */
+	public ToolBarItemSO(ToolBarView tbView, String id, String imageid) {
+		super();
+		this.tbView = tbView;
+		this.id = id;
+		imageID = imageid;
+		isPluginItem = false;
+	}
+
+	public ToolBarItemSO(ToolBarView tbView, String id, String imageid,
+			String textID) {
+		super();
+		this.tbView = tbView;
+		this.id = id;
+		imageID = imageid;
+		this.textID = textID;
+		this.tooltipID = textID + ".tooltip";
+		isPluginItem = false;
+	}
+
+	public ToolBarItemSO(ToolBarView tbView, String id, boolean isPluginItem) {
+		this.tbView = tbView;
+		this.id = id;
+		this.isPluginItem = isPluginItem;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.ToolBarItem#triggerToolBarItem(long, java.lang.Object)
+	 */
+	public boolean triggerToolBarItem(long activationType, Object datasource) {
+		return tbView.triggerToolBarItem(this, activationType, datasource);
+	}
+
+	public String getID() {
+		return id;
+	}
+
+	public void setSkinButton(SWTSkinButtonUtility btn) {
+		this.skinButton = btn;
+		skinButton.setDisabled(!enabled);
+	}
+
+	public SWTSkinButtonUtility getSkinButton() {
+		return skinButton;
+	}
+
+	public void setSkinTitle(SWTSkinObjectText s) {
+		skinTitle = s;
+	}
+
+	public long getState() {
+		long state = (isEnabled() ? STATE_ENABLED : 0) | (isDown ? STATE_DOWN : 0);
+
+		return state;
+	}
+
+	public void setState(long state) {
+		setEnabled((state & STATE_ENABLED) > 0);
+		isDown = (state & STATE_DOWN) > 0;
+		if (skinButton != null) {
+			skinButton.getSkinObject().switchSuffix(isDown ? "-down" : "", 2, false);
+		}
+	}
+
+	private boolean isEnabled() {
+		if (skinButton != null) {
+			return !skinButton.isDisabled();
+		}
+		return enabled;
+	}
+
+	private void setEnabled(boolean enabled) {
+		if (alwaysAvailable && !enabled) {
+			return;
+		}
+		this.enabled = enabled;
+		if (skinButton != null) {
+			skinButton.setDisabled(!enabled);
+		}
+	}
+
+	public String getImageID() {
+		return imageID;
+	}
+
+	public void setImageID(String imageID) {
+		this.imageID = imageID;
+		if (skinButton != null) {
+			skinButton.setImage(imageID);
+		}
+	}
+
+	/**
+	 * @param textID the textID to set
+	 */
+	public void setTextID(String textID) {
+		this.textID = textID;
+		if (skinTitle != null) {
+			skinTitle.setTextID(textID);
+		}
+	}
+
+	/**
+	 * @return the textID
+	 */
+	public String getTextID() {
+		return textID;
+	}
+
+	public String getTooltipID() {
+		return tooltipID;
+	}
+
+	public void setTooltipID(String tooltipID) {
+		this.tooltipID = tooltipID;
+	}
+
+	public void setAlwaysAvailable(boolean alwaysAvailable) {
+		this.alwaysAvailable = alwaysAvailable;
+		if (alwaysAvailable) {
+			setEnabled(true);
+		}
+	}
+
+	public boolean isAlwaysAvailable() {
+		return alwaysAvailable;
+	}
+
+	public void setDefaultActivationListener(
+			UIToolBarActivationListener defaultActivation) {
+		this.defaultActivation = defaultActivation;
+	}
+
+	public UIToolBarActivationListener getDefaultActivationListener() {
+		return defaultActivation;
+	}
+
+	public void dispose() {
+		// ToolBarView will dispose of skinobjects
+		skinButton = null;
+		skinTitle = null;
+	}
+
+	public String getGroupID() {
+		return groupID;
+	}
+
+	public void setGroupID(String groupID) {
+		this.groupID = groupID;
+	}
+
+	public void setDefaultState(long state) {
+		this.defaultState = state;
+	}
+
+	public long getDefaultState() {
+		return defaultState;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/uiupdater/UIUpdaterSWT.java b/com/aelitis/azureus/ui/swt/uiupdater/UIUpdaterSWT.java
index 6397f8f..9c0eb8e 100644
--- a/com/aelitis/azureus/ui/swt/uiupdater/UIUpdaterSWT.java
+++ b/com/aelitis/azureus/ui/swt/uiupdater/UIUpdaterSWT.java
@@ -31,12 +31,16 @@ 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.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainStatusBar;
 import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar;
 
+import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.common.updater.UIUpdatableAlways;
 import com.aelitis.azureus.ui.common.updater.UIUpdater;
+import com.aelitis.azureus.ui.common.updater.UIUpdater.UIUpdaterListener;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * @author TuxPaper
@@ -63,9 +67,9 @@ public class UIUpdaterSWT
 
 	private boolean refreshed = true;
 
-	private ArrayList updateables = new ArrayList();
+	private ArrayList<UIUpdatable> updateables = new ArrayList<UIUpdatable>();
 
-	private ArrayList alwaysUpdateables = new ArrayList();
+	private ArrayList<UIUpdatable> alwaysUpdateables = new ArrayList<UIUpdatable>();
 
 	private AEMonitor updateables_mon = new AEMonitor("updateables");
 
@@ -75,6 +79,9 @@ public class UIUpdaterSWT
 
 	Map averageTimes = DEBUG_TIMER ? new HashMap() : null;
 
+	private int	update_count = 0;
+	private CopyOnWriteList<UIUpdaterListener>		listeners = new CopyOnWriteList<UIUpdaterListener>();
+	
 	public static UIUpdater getInstance() {
 		if (updater == null) {
 			updater = new UIUpdaterSWT();
@@ -137,13 +144,21 @@ public class UIUpdaterSWT
 									"Error while trying to update GUI", e));
 						} finally {
 							refreshed = true;
+							
+							for ( UIUpdaterListener l: listeners ){
+								
+								try{
+									l.updateComplete( ++update_count );
+								}catch( Throwable e ){
+									Debug.out( e );
+								}
+							}
 						}
 					}
 				})) {
 					refreshed = true;
 				}
 			}
-
 			try {
 				Thread.sleep(waitTimeMS);
 			} catch (Exception e) {
@@ -156,6 +171,9 @@ public class UIUpdaterSWT
 	public void parameterChanged(String parameterName) {
 		waitTimeMS = COConfigurationManager.getIntParameter(CFG_REFRESH_INTERVAL);
 		inactiveFactor = COConfigurationManager.getIntParameter(CFG_REFRESH_INACTIVE_FACTOR);
+		if (inactiveFactor == 0) {
+			inactiveFactor = 1;
+		}
 	}
 
 	// @see com.aelitis.azureus.ui.swt.utils.UIUpdater#addUpdater(com.aelitis.azureus.ui.swt.utils.UIUpdatable)
@@ -178,6 +196,18 @@ public class UIUpdaterSWT
 		}
 	}
 
+	public boolean 
+	isAdded(
+		UIUpdatable updateable) 
+	{
+		updateables_mon.enter();
+		try {
+			return( updateables.contains(updateable));
+		} finally {
+			updateables_mon.exit();
+		}
+	}
+	
 	// @see com.aelitis.azureus.ui.swt.utils.UIUpdater#removeUpdater(com.aelitis.azureus.ui.swt.utils.UIUpdatable)
 	public void removeUpdater(UIUpdatable updateable) {
 		updateables_mon.enter();
@@ -197,7 +227,7 @@ public class UIUpdaterSWT
 		COConfigurationManager.removeParameterListener(CFG_REFRESH_INTERVAL, this);
 	}
 
-	private void update(List updateables) {
+	private void update(List<UIUpdatable> updateables) {
 		long start = 0;
 		Map mapTimeMap = DEBUG_TIMER ? new HashMap() : null;
 
@@ -279,7 +309,8 @@ public class UIUpdaterSWT
 		}
 		//System.out.println(SystemTime.getCurrentTime() + "] Refresh " + ttl + "ms");
 
-		MainStatusBar mainStatusBar = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainStatusBar();
+		UIFunctionsSWT uiFunctionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		IMainStatusBar mainStatusBar = uiFunctionsSWT == null ? null : uiFunctionsSWT.getMainStatusBar();
 		if (mainStatusBar != null && mainStatusBar.isMouseOver()) {
 			StringBuffer sb = new StringBuffer();
 			for (Iterator iter = averageTimes.keySet().iterator(); iter.hasNext();) {
@@ -309,4 +340,18 @@ public class UIUpdaterSWT
 			mainStatusBar.setDebugInfo(sb.toString());
 		}
 	}
+	
+	public void
+	addListener(
+		UIUpdaterListener		listener )
+	{
+		listeners.add( listener );
+	}
+	
+	public void
+	removeListener(
+		UIUpdaterListener		listener )
+	{
+		listeners.remove( listener );
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/utils/ColorCache.java b/com/aelitis/azureus/ui/swt/utils/ColorCache.java
index 46d4ead..3e60417 100644
--- a/com/aelitis/azureus/ui/swt/utils/ColorCache.java
+++ b/com/aelitis/azureus/ui/swt/utils/ColorCache.java
@@ -40,7 +40,7 @@ public class ColorCache
 {
 	private final static boolean DEBUG = Constants.isCVSVersion();
 
-	private final static Map mapColors = new HashMap();
+	private final static Map<Long, Color> mapColors = new HashMap<Long, Color>();
 	
 	private final static int SYSTEMCOLOR_INDEXSTART = 17;
 	private final static String[] systemColorNames = {
@@ -72,42 +72,60 @@ public class ColorCache
 		});
 	}
 
-	public static Color getColor(Device device, int red, int green, int blue) {
-		if (mapColors.size() == 0) {
-			for (int i = 1; i <= 16; i++) {
-				Color color = device.getSystemColor(i);
-				Long key = new Long(((long) color.getRed() << 16)
-						+ (color.getGreen() << 8) + color.getBlue());
-				addColor(key, color);
-			}
-			if (DEBUG) {
-				SimpleTimer.addPeriodicEvent("ColorCacheChecker", 60000,
-						new TimerEventPerformer() {
-							public void perform(TimerEvent event) {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										for (Iterator iter = mapColors.keySet().iterator(); iter.hasNext();) {
-											Long key = (Long) iter.next();
-											Color color = (Color) mapColors.get(key);
-											if (color.isDisposed()) {
-												Logger.log(new LogAlert(false, LogAlert.AT_ERROR,
-														"Someone disposed of color "
-																+ Long.toHexString(key.longValue())
-																+ ". Please report this on the "
-																+ "<A HREF=\"http://forum.vuze.com/forum.jspa?forumID=4\">forum</A>"));
-												iter.remove();
-											}
-										}
-									}
-								});
-							}
-						});
+	public static Color getSchemedColor(Device device, int red, int green, int blue) {
+		ensureMapColorsInitialized(device);
+
+		Long key = new Long(((long) red << 16) + (green << 8) + blue + 0x1000000l);
+
+		Color color = mapColors.get(key);
+		if (color == null || color.isDisposed()) {
+			try {
+				if (red < 0) {
+					red = 0;
+				} else if (red > 255) {
+					red = 255;
+				}
+				if (green < 0) {
+					green = 0;
+				} else if (green > 255) {
+					green = 255;
+				}
+				if (blue < 0) {
+					blue = 0;
+				} else if (blue > 255) {
+					blue = 255;
+				}
+				
+	      RGB rgb = new RGB(red, green, blue);
+	      float[] hsb = rgb.getHSB();
+	      hsb[0] += Colors.diffHue;
+	      if (hsb[0] > 360) {
+	      	hsb[0] -= 360;
+	      } else if (hsb[0] < 0) {
+	      	hsb[0] += 360;
+	      }
+	      hsb[1] *= Colors.diffSatPct;
+	      //hsb[2] *= Colors.diffLumPct;
+	      
+	      color = getColor(device, hsb);
+	      mapColors.put(key, color);
+			} catch (IllegalArgumentException e) {
+				Debug.out("One Invalid: " + red + ";" + green + ";" + blue, e);
 			}
 		}
 
+		return color;
+	}
+
+	public static Color getColor(Device device, int red, int green, int blue) {
+		if (device == null || device.isDisposed()) {
+			return null;
+		}
+		ensureMapColorsInitialized(device);
+
 		Long key = new Long(((long) red << 16) + (green << 8) + blue);
 
-		Color color = (Color) mapColors.get(key);
+		Color color = mapColors.get(key);
 		if (color == null || color.isDisposed()) {
 			try {
 				if (red < 0) {
@@ -135,7 +153,52 @@ public class ColorCache
 		return color;
 	}
 
+	private static void ensureMapColorsInitialized(Device device) {
+		if (device == null || device.isDisposed()) {
+			return;
+		}
+		if (mapColors.size() == 0) {
+			for (int i = 1; i <= 16; i++) {
+				Color color = device.getSystemColor(i);
+				Long key = new Long(((long) color.getRed() << 16)
+						+ (color.getGreen() << 8) + color.getBlue());
+				addColor(key, color);
+			}
+			if (DEBUG) {
+				SimpleTimer.addPeriodicEvent("ColorCacheChecker", 60000,
+						new TimerEventPerformer() {
+							public void perform(TimerEvent event) {
+								Utils.execSWTThread(new AERunnable() {
+									public void runSupport() {
+										for (Iterator<Long> iter = mapColors.keySet().iterator(); iter.hasNext();) {
+											Long key = iter.next();
+											Color color = mapColors.get(key);
+											if (color.isDisposed()) {
+												Logger.log(new LogAlert(false, LogAlert.AT_ERROR,
+														"Someone disposed of color "
+																+ Long.toHexString(key.longValue())
+																+ ". Please report this on the "
+																+ "<A HREF=\"http://forum.vuze.com/forum.jspa?forumID=124\">forum</A>"));
+												iter.remove();
+											}
+										}
+									}
+								});
+							}
+						});
+			}
+		}
+	}
+
 	public static Color getColor(Device device, String value) {
+		return getColor(device, value, false);
+	}
+
+	public static Color getSchemedColor(Device device, String value) {
+		return getColor(device, value, true);
+	}
+
+	private static Color getColor(Device device, String value, boolean useScheme) {
 		int[] colors = new int[3];
 
 		if (value == null || value.length() == 0) {
@@ -159,7 +222,7 @@ public class ColorCache
 				if (value.startsWith("COLOR_")) {
 					for (int i = 0; i < systemColorNames.length; i++) {
 						String name = systemColorNames[i];
-						if (name.equals(value)) {
+						if (name.equals(value) && device != null && !device.isDisposed()) {
 							return device.getSystemColor(i + SYSTEMCOLOR_INDEXSTART);
 						}
 					}
@@ -179,7 +242,10 @@ public class ColorCache
 			return null;
 		}
 
-		return getColor(device, colors[0], colors[1], colors[2]);
+		if (!useScheme) {
+			return getColor(device, colors[0], colors[1], colors[2]);
+		}
+		return getSchemedColor(device, colors[0], colors[1], colors[2]);
 	}
 
 	private static void addColor(Long key, Color color) {
diff --git a/com/aelitis/azureus/ui/swt/utils/ColorCache2.java b/com/aelitis/azureus/ui/swt/utils/ColorCache2.java
new file mode 100644
index 0000000..d03ecf6
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/utils/ColorCache2.java
@@ -0,0 +1,204 @@
+/*
+ * Created on Nov 10, 2011
+ * Created by Paul Gardner
+ * 
+ * Copyright 2011 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.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.RGB;
+import org.gudy.azureus2.core3.util.Debug;
+
+public class 
+ColorCache2 
+{
+	private static Map<RGB,CachedColorManaged>	color_map = new HashMap<RGB, CachedColorManaged>();
+	
+	public static CachedColor
+	getColor(
+		Color		c )
+	{
+		return( new CachedColorUnmanaged( c ));
+	}
+
+	public static CachedColor
+	getColor(
+		Device		device,
+		RGB			rgb )
+	{
+		synchronized( color_map ){
+			
+			CachedColorManaged entry = color_map.get( rgb );
+			
+			if ( entry == null ){
+		
+				entry = new CachedColorManaged( new Color( device, rgb ));
+				
+				color_map.put( rgb, entry );
+				
+			}else{
+				
+				entry.addRef();
+			}
+			
+			return( new CachedColorManagedFacade( entry ));
+		}
+	}
+	
+	private static class
+	CachedColorManaged
+	{
+		private Color	color;
+		private int		ref_count;
+		
+		private
+		CachedColorManaged(
+			Color	_color )
+		{
+			color		= _color;
+			ref_count	= 1;
+		}
+		
+		public Color
+		getColor()
+		{
+			return( color );
+		}
+			
+		private void
+		addRef()
+		{
+			ref_count++;
+			
+			//System.out.println( "cc ++: color=" + color + ", refs=" + ref_count );
+		}
+		
+		private void
+		dispose()
+		{
+			ref_count--;
+			
+			//System.out.println( "cc --: color=" + color + ", refs=" + ref_count );
+			
+			if ( ref_count == 0 ){
+												
+				color_map.remove( color.getRGB());
+				
+				color.dispose();
+
+			}else if ( ref_count < 0 ){
+				
+				Debug.out( "already disposed" );
+			}
+		}
+	}
+	
+	private static class
+	CachedColorManagedFacade
+		implements CachedColor
+	{
+		private	CachedColorManaged	delegate;
+		private boolean				disposed;
+		
+		private 
+		CachedColorManagedFacade(
+			CachedColorManaged	_delegate )
+		{
+			delegate = _delegate;
+		}
+		
+		public Color
+		getColor()
+		{
+			return( delegate.getColor());
+		}
+		
+		public boolean
+		isDisposed()
+		{
+			synchronized( color_map ){
+				
+				return( disposed );
+			}
+		}
+		
+		public void
+		dispose()
+		{
+			synchronized( color_map ){
+				
+				if ( !disposed ){
+				
+					disposed = true;
+			
+					delegate.dispose();
+				}
+			}
+		}
+	}
+	
+	private static class
+	CachedColorUnmanaged
+		implements CachedColor
+	{
+		private Color	color;
+		
+		private
+		CachedColorUnmanaged(
+			Color	_color )
+		{
+			color	= _color;
+		}
+		
+		public Color
+		getColor()
+		{
+			return( color );
+		}
+		
+		public boolean
+		isDisposed()
+		{
+			return( color.isDisposed());
+		}
+		
+		public void
+		dispose()
+		{
+			color.dispose();
+		}
+	}
+	
+	public interface
+	CachedColor
+	{
+		public Color
+		getColor();
+
+		public boolean
+		isDisposed();
+
+		public void
+		dispose();
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/utils/ContentNetworkUI.java b/com/aelitis/azureus/ui/swt/utils/ContentNetworkUI.java
deleted file mode 100644
index 0a31b69..0000000
--- a/com/aelitis/azureus/ui/swt/utils/ContentNetworkUI.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Created on Dec 2, 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 java.io.*;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.util.*;
-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.utils.ImageBytesDownloader;
-import com.aelitis.azureus.ui.utils.ImageBytesDownloader.ImageDownloaderListener;
-import com.aelitis.azureus.util.ContentNetworkUtils;
-
-/**
- * @author TuxPaper
- * @created Dec 2, 2008
- *
- */
-public class ContentNetworkUI
-{
-	// If we ever clear mapImages, don't forget to ImageLoderFactory.releaseImage if needed
-	public static Map<Long, Image> mapImages = new HashMap<Long, Image>();
-
-	/**
-	 * @param cn
-	 * @param cnImageLoadedListener
-	 *
-	 * @since 4.0.0.5
-	 */
-	public static Image loadImage(final long contentNetworkID,
-			final ContentNetworkImageLoadedListener cnImageLoadedListener) {
-		Image image = mapImages.get(new Long(contentNetworkID));
-		if (image != null && cnImageLoadedListener != null) {
-			cnImageLoadedListener.contentNetworkImageLoaded(contentNetworkID, image, true);
-			return image;
-		}
-
-		ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetwork(
-				contentNetworkID);
-		if (cn == null) {
-			return image;
-		}
-		String imgURL = ContentNetworkUtils.getUrl(cn, ContentNetwork.SERVICE_GET_ICON);
-		if (imgURL != null) {
-			final File cache = new File(SystemProperties.getUserPath(), "cache"
-					+ File.separator + imgURL.hashCode() + ".ico");
-			boolean loadImage = true;
-			if (cache.exists()) {
-				try {
-					FileInputStream fis = new FileInputStream(cache);
-
-					try {
-						byte[] imageBytes = FileUtil.readInputStreamAsByteArray(fis);
-						InputStream is = new ByteArrayInputStream(imageBytes);
-						image = new Image(Display.getCurrent(), is);
-						try {
-							is.close();
-						} catch (IOException e) {
-						}
-						mapImages.put(new Long(contentNetworkID), image);
-						if (cnImageLoadedListener != null) {
-							cnImageLoadedListener.contentNetworkImageLoaded(contentNetworkID,
-									image, true);
-						}
-					} finally {
-						fis.close();
-					}
-					loadImage = false;
-				} catch (Throwable e) {
-					Debug.printStackTrace(e);
-				}
-
-			}
-			if (loadImage) {
-				ImageBytesDownloader.loadImage(imgURL,
-						new ImageBytesDownloader.ImageDownloaderListener() {
-							public void imageDownloaded(final byte[] imageBytes) {
-								Utils.execSWTThread(new AERunnable() {
-									public void runSupport() {
-										FileUtil.writeBytesAsFile(cache.getAbsolutePath(),
-												imageBytes);
-										InputStream is = new ByteArrayInputStream(imageBytes);
-										Image image = new Image(Display.getCurrent(), is);
-										try {
-											is.close();
-										} catch (IOException e) {
-										}
-										mapImages.put(new Long(contentNetworkID), image);
-										if (cnImageLoadedListener != null) {
-											cnImageLoadedListener.contentNetworkImageLoaded(
-													contentNetworkID, image, false);
-										}
-									}
-								});
-							}
-						});
-			}
-		} else if (contentNetworkID == ContentNetwork.CONTENT_NETWORK_VUZE
-				&& cnImageLoadedListener != null) {
-			image = ImageLoader.getInstance().getImage("image.sidebar.vuze");
-			mapImages.put(new Long(contentNetworkID), image);
-			cnImageLoadedListener.contentNetworkImageLoaded(contentNetworkID, image, true);
-		}
-		return image;
-	}
-	
-	
-
-	public static interface ContentNetworkImageLoadedListener
-	{
-		public void contentNetworkImageLoaded(Long contentNetworkID, Image image, boolean wasReturned);
-	}
-
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/FontUtils.java b/com/aelitis/azureus/ui/swt/utils/FontUtils.java
new file mode 100644
index 0000000..909d2c5
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/utils/FontUtils.java
@@ -0,0 +1,346 @@
+/*
+ * Created on Mar 7, 2010 11:10:45 AM
+ * Copyright (C) 2010 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.utils;
+
+import java.lang.reflect.Method;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.Utils;
+
+/**
+ * @author TuxPaper
+ * @created Mar 7, 2010
+ *
+ */
+public class FontUtils
+{
+
+	private static Method mFontData_SetHeight;
+
+	private static Method mFontData_GetHeightF;
+
+	private static Font fontBold;
+
+	static {
+		try {
+			mFontData_SetHeight = FontData.class.getDeclaredMethod("setHeight",
+					new Class[] {
+						float.class
+					});
+			mFontData_SetHeight.setAccessible(true);
+		} catch (Throwable e) {
+			mFontData_SetHeight = null;
+		}
+
+		try {
+			mFontData_GetHeightF = FontData.class.getDeclaredMethod("getHeightF",
+					new Class[] {
+					});
+			mFontData_GetHeightF.setAccessible(true);
+		} catch (Throwable e) {
+			mFontData_GetHeightF = null;
+		}
+	}
+
+	/**
+	 * 
+	 * @param baseFont
+	 * @param gc Can be null
+	 * @param heightInPixels
+	 * @return
+	 *
+	 * @since 3.0.0.7
+	 */
+	public static float getFontHeightFromPX(Font baseFont, GC gc,
+			int heightInPixels) {
+		Font font = null;
+		Device device = baseFont.getDevice();
+
+		// hack..
+		heightInPixels++;
+
+		// This isn't accurate, but gets us close
+		float[] size = {
+			Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1
+		};
+		if (size[0] <= 0) {
+			return 0;
+		}
+
+		boolean bOurGC = gc == null || gc.isDisposed();
+		try {
+			if (bOurGC) {
+				gc = new GC(device);
+			}
+			FontData[] fontData = baseFont.getFontData();
+
+			font = findFont(gc, font, fontData, size, heightInPixels, SWT.DEFAULT);
+
+		} finally {
+			if (bOurGC) {
+				gc.dispose();
+			}
+			if (font != null && !font.isDisposed()) {
+				font.dispose();
+			}
+		}
+		return size[0];
+	}
+
+	public static float getFontHeightFromPX(Device device, FontData[] fontData,
+			GC gc, int heightInPixels) {
+		Font font = null;
+
+		// hack..
+		heightInPixels++;
+
+		// This isn't accurate, but gets us close
+		float[] size = {
+			Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1
+		};
+		if (size[0] <= 0) {
+			return 0;
+		}
+
+		boolean bOurGC = gc == null || gc.isDisposed();
+		try {
+			if (bOurGC) {
+				gc = new GC(device);
+			}
+
+			font = findFont(gc, font, fontData, size, heightInPixels, SWT.DEFAULT);
+
+		} finally {
+			if (bOurGC) {
+				gc.dispose();
+			}
+			if (font != null && !font.isDisposed()) {
+				font.dispose();
+			}
+		}
+		return size[0];
+	}
+
+	public static Font getFontWithHeight(Font baseFont, GC gc, int heightInPixels) {
+		return getFontWithHeight(baseFont, gc, heightInPixels, SWT.DEFAULT);
+	}
+
+	public static Font getFontWithHeight(Font baseFont, GC gc,
+			int heightInPixels, int style) {
+		Font font = null;
+		Device device = baseFont.getDevice();
+
+		// hack..
+		heightInPixels++;
+
+		// This isn't accurate, but gets us close
+		float[] size = {
+			Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1
+		};
+		if (size[0] <= 0) {
+			size[0] = 2;
+		}
+
+		boolean bOurGC = gc == null || gc.isDisposed();
+		try {
+			if (bOurGC) {
+				gc = new GC(device);
+			}
+			FontData[] fontData = baseFont.getFontData();
+
+			font = findFont(gc, font, fontData, size, heightInPixels, style);
+
+		} finally {
+			if (bOurGC) {
+				gc.dispose();
+			}
+		}
+
+		return font;
+	}
+
+	public static void setFontDataHeight(FontData[] fd, float fontSize) {
+		if (mFontData_SetHeight != null) {
+			try {
+				mFontData_SetHeight.invoke(fd[0], fontSize);
+				return;
+			} catch (Throwable e) {
+			}
+		}
+
+		fd[0].setHeight((int) fontSize);
+	}
+
+	private static Font findFont(GC gc, Font font, FontData[] fontData,
+			float[] size, int heightInPixels, int style) {
+		if (mFontData_SetHeight != null) {
+			return findFontByFloat(gc, font, fontData, size, heightInPixels, style);
+		}
+		return findFontByInt(gc, font, fontData, size, heightInPixels, style);
+	}
+
+	public static Font findFontByInt(GC gc, Font font, FontData[] fontData,
+			float[] returnSize, int heightInPixels, int style) {
+		int size = (int) returnSize[0];
+		do {
+			if (font != null) {
+				size--;
+				font.dispose();
+			}
+			fontData[0].setHeight(size);
+			if (style != SWT.DEFAULT) {
+				fontData[0].setStyle(style);
+			}
+
+			font = new Font(gc.getDevice(), fontData);
+
+			gc.setFont(font);
+
+		} while (font != null
+				&& gc.textExtent(Utils.GOOD_STRING).y > heightInPixels && size > 1);
+
+		returnSize[0] = size;
+		return font;
+	}
+
+	public static Font findFontByFloat(GC gc, Font font, FontData[] fontData,
+			float[] returnSize, int heightInPixels, int style) {
+		float size = returnSize[0];
+		float delta = 2.0f;
+		boolean fits;
+		int numLoops = 0;
+		do {
+			numLoops++;
+			if (font != null) {
+				size -= delta;
+				font.dispose();
+			}
+			try {
+				mFontData_SetHeight.invoke(fontData[0], size);
+			} catch (Throwable e) {
+				Debug.out(e);
+			}
+			if (style != SWT.DEFAULT) {
+				fontData[0].setStyle(style);
+			}
+
+			font = new Font(gc.getDevice(), fontData);
+
+			gc.setFont(font);
+
+			//System.out.println("yay " + size + " = "
+			//		+ gc.textExtent(Utils.GOOD_STRING).y + " (want " + heightInPixels
+			//		+ ")");
+
+			fits = gc.textExtent(Utils.GOOD_STRING).y <= heightInPixels;
+			if (fits && delta > .1) {
+				size += delta;
+				delta /= 2;
+				fits = false;
+			}
+		} while (!fits && size > 1);
+		
+		returnSize[0] = size;
+		return font;
+	}
+
+	public static int getFontHeightInPX(FontData[] fd) {
+		Font font = new Font(Display.getDefault(), fd);
+		try {
+			return getFontHeightInPX(font);
+		} finally {
+			font.dispose();
+		}
+	}
+
+	public static int getFontHeightInPX(Font font) {
+		GC gc = new GC(font.getDevice());
+		try {
+			gc.setFont(font);
+			return gc.textExtent(Utils.GOOD_STRING).y;
+		} finally {
+			gc.dispose();
+		}
+	}
+
+	/**
+	 * Change the height of the installed <code>Font</code> and takes care of disposing
+	 * the new font when the control is disposed
+	 * @param control
+	 * @param height
+	 * @param style one or both of SWT.BOLD, SWT.ITALIC, or SWT.NORMAL
+	 */
+	public static void setFontHeight(Control control, int height, int style) {
+		FontData[] fDatas = control.getFont().getFontData();
+		for (int i = 0; i < fDatas.length; i++) {
+			fDatas[i].height = height;
+			fDatas[i].setStyle(style);
+		}
+		final Font newFont = new Font(control.getDisplay(), fDatas);
+		control.setFont(newFont);
+		control.addDisposeListener(new DisposeListener() {
+
+			public void widgetDisposed(DisposeEvent e) {
+				if (null != newFont && false == newFont.isDisposed()) {
+					newFont.dispose();
+				}
+			}
+		});
+	}
+
+	public static float getHeight(FontData[] fd) {
+		if (mFontData_GetHeightF != null) {
+			try {
+				return ((Number) mFontData_GetHeightF.invoke(fd[0], new Object[] {})).floatValue();
+			} catch (Throwable e) {
+			}
+		}
+
+		return fd[0].getHeight();
+	}
+
+	public static Font getFontPercentOf(Font baseFont, float pct) {
+		FontData[] fontData = baseFont.getFontData();
+		float height = getHeight(fontData) * pct;
+		setFontDataHeight(fontData, height);
+		
+		return new Font(baseFont.getDevice(), fontData);
+	}
+	
+	public static Font getAnyFontBold(GC gc) {
+		if (fontBold == null) {
+			FontData[] fontData = gc.getFont().getFontData();
+			for (int i = 0; i < fontData.length; i++) {
+				FontData fd = fontData[i];
+				fd.setStyle(SWT.BOLD);
+			}
+			fontBold = new Font(gc.getDevice(), fontData);
+		}
+		return fontBold;
+	}
+
+}
diff --git a/com/aelitis/azureus/ui/swt/utils/ImageResizeException.java b/com/aelitis/azureus/ui/swt/utils/ImageResizeException.java
deleted file mode 100644
index cc7462e..0000000
--- a/com/aelitis/azureus/ui/swt/utils/ImageResizeException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.aelitis.azureus.ui.swt.utils;
-
-public class ImageResizeException
-	extends Exception
-{
-
-	public ImageResizeException(String message) {
-		super(message);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/ImageResizer.java b/com/aelitis/azureus/ui/swt/utils/ImageResizer.java
deleted file mode 100644
index e976c85..0000000
--- a/com/aelitis/azureus/ui/swt/utils/ImageResizer.java
+++ /dev/null
@@ -1,612 +0,0 @@
-package com.aelitis.azureus.ui.swt.utils;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-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.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
-{
-
-	static private final int RESIZE_STEPS = 100000;
-
-	static private final int MARGIN = 20;
-
-	private int minWidth, minHeight;
-
-	private int displayWidth, displayHeight;
-
-	private Display display;
-
-	private Shell parent;
-
-	private Shell shell;
-
-	private Cursor cursor;
-
-	private Canvas canvas;
-
-	private Scale scale;
-
-	private long lastUpdate = 0l;
-
-	private Image original;
-
-	private int originalWidth, originalHeight;
-
-	private Image currentImage;
-
-	private Image overlay;
-
-	private Image overlayDragging;
-
-	private Image overlayNotDragging;
-
-	private boolean done;
-
-	private Image result;
-
-	private float zoomRatio;
-
-	private float minZoomRatio;
-
-	private float maxZoomRatio;
-
-	private Point offset;
-
-	private Listener moveImageListener = new Listener() {
-
-		private boolean mouseDown = false;
-
-		private Point pointDown;
-
-		public void handleEvent(Event event) {
-			//System.out.println(event);
-			switch (event.type) {
-				case SWT.MouseDown:
-					mouseDown = true;
-					pointDown = new Point(event.x, event.y);
-					overlay = overlayDragging;
-					drawCurrentImage();
-					break;
-				case SWT.MouseUp:
-					mouseDown = false;
-					overlay = overlayNotDragging;
-					drawCurrentImage();
-					break;
-				case SWT.MouseMove:
-					if (!mouseDown) {
-						break;
-					}
-					offset.x = offset.x + event.x - pointDown.x;
-					offset.y = offset.y + event.y - pointDown.y;
-					insureOffsetIsCorrect();
-
-					pointDown.x = event.x;
-					pointDown.y = event.y;
-					drawCurrentImage();
-					break;
-				case SWT.MouseEnter:
-
-					break;
-				case SWT.MouseExit:
-
-					break;
-			}
-
-		}
-	};
-
-	private ImageResizerListener imageResizerListener;
-
-	public ImageResizer(Display display, int width, int height, Shell parent) {
-		this.parent = parent;
-		this.display = display;
-		this.minWidth = width;
-		this.minHeight = height;
-	}
-
-	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)) {
-			dispose();
-			throw new ImageResizeException(MessageText.getString(
-					"ImageResizer.image.too.small", new String[] {
-						minWidth + "",
-						minHeight + ""
-					}));
-		}
-
-		originalWidth = original.getBounds().width;
-		originalHeight = original.getBounds().height;
-
-		currentImage = new Image(display, internalResize(original,
-				(int) (originalWidth * zoomRatio), (int) (originalHeight * zoomRatio)));
-		offset = new Point(0, 0);
-
-		if (minWidth != original.getBounds().width
-				|| minHeight != original.getBounds().height) {
-
-			displayWidth = minWidth + 2 * (MARGIN + 1);
-			displayHeight = minHeight + 2 * (MARGIN + 1);
-
-			overlay = overlayNotDragging = createOverlayImage((byte) 255, 0x00FFFFFF,
-					(byte) 255, 0x00000000);
-			overlayDragging = createOverlayImage((byte) 80, 0x00FFFFFF, (byte) 255,
-					0x00FFFFFF);
-
-			initUI();
-
-			done = false;
-		} else {
-			result = computeResultImage();
-			l.imageResized(result);
-		}
-	}
-
-	private void initUI() {
-
-		cursor = new Cursor(display, SWT.CURSOR_HAND);
-
-		if (parent != null) {
-			shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-		} else {
-			shell = ShellFactory.createMainShell(SWT.CLOSE | SWT.BORDER);
-		}
-		shell.setText("Thumbnail Assistant");
-
-		Utils.setShellIcon(shell);
-
-		shell.addListener(SWT.Close, new Listener() {
-			public void handleEvent(Event event) {
-				event.doit = false;
-				result = null;
-				done = true;
-				shell = null;
-				dispose();
-				imageResizerListener.imageResized(result);
-			}
-		});
-
-		FormLayout layout = new FormLayout();
-		layout.marginBottom = 5;
-		layout.marginTop = 5;
-		layout.marginLeft = 5;
-		layout.marginRight = 5;
-
-		FormData data;
-		shell.setLayout(layout);
-
-		Label title = new Label(shell, SWT.WRAP);
-		title.setText(MessageText.getString("ImageResizer.title"));
-
-		data = new FormData();
-		data.width = displayWidth;
-		title.setLayoutData(data);
-
-		canvas = new Canvas(shell, SWT.BORDER);
-		canvas.setCursor(cursor);
-		data = new FormData();
-		data.width = displayWidth;
-		data.height = displayHeight;
-		data.top = new FormAttachment(title, 5);
-		canvas.setLayoutData(data);
-
-		canvas.addListener(SWT.MouseDown, moveImageListener);
-		canvas.addListener(SWT.MouseUp, moveImageListener);
-		canvas.addListener(SWT.MouseMove, moveImageListener);
-
-		canvas.addPaintListener(new PaintListener() {
-			public void paintControl(PaintEvent arg0) {
-				drawCurrentImage();
-			}
-		});
-
-		offset.x = (minWidth - currentImage.getBounds().width) / 2;
-		offset.y = (minHeight - currentImage.getBounds().height) / 2;
-
-		Label label = new Label(shell, SWT.WRAP);
-		//The label text depends on the presence of the scale,
-		//Thefore we delay the size computation as well as
-		//Assiging any FormData (layout) to it see (1)
-
-		//The Control to witch the Buttons OK and Cancel are going to be attached
-		//Depends on the presence of the scale
-		Control attach = label;
-
-		if (minZoomRatio < 1) {
-			scale = new Scale(shell, SWT.HORIZONTAL);
-			data = new FormData();
-			data.width = displayWidth;
-			data.top = new FormAttachment(label, 5);
-			scale.setLayoutData(data);
-			scale.setMaximum((int) (RESIZE_STEPS * maxZoomRatio));
-			scale.setMinimum((int) (RESIZE_STEPS * minZoomRatio));
-			scale.setIncrement((int) ((maxZoomRatio - minZoomRatio) * RESIZE_STEPS / 10));
-			scale.setPageIncrement((int) ((maxZoomRatio - minZoomRatio)
-					* RESIZE_STEPS / 10));
-
-			scale.addListener(SWT.Selection, new Listener() {
-				public void handleEvent(Event arg0) {
-					final long timestamp = SystemTime.getCurrentTime();
-					lastUpdate = timestamp;
-
-					final int position = scale.getSelection();
-
-					AEThread t = new AEThread("") {
-						public void runSupport() {
-							try {
-								Thread.sleep(150);
-							} catch (Exception e) {
-								e.printStackTrace();
-							}
-
-							if (timestamp == lastUpdate) {
-								if (display != null && !display.isDisposed()) {
-									display.asyncExec(new Runnable() {
-										public void run() {
-											refreshCurrentImage(position);
-										}
-									});
-								}
-							}
-						}
-					};
-					t.setDaemon(true);
-					t.start();
-
-				}
-			});
-			attach = scale;
-			label.setText(MessageText.getString("ImageResizer.move.image.with.slider"));
-		} else {
-			label.setText(MessageText.getString("ImageResizer.move.image"));
-		}
-
-		// (1) Layout of the label, depending on the text in it
-		int width = label.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
-		if (width > displayWidth) {
-			width = displayWidth;
-		}
-
-		data = new FormData();
-		data.width = width;
-		data.top = new FormAttachment(canvas, 5);
-		data.left = new FormAttachment(canvas, 0, SWT.CENTER);
-		label.setLayoutData(data);
-
-		Button btnCancel = new Button(shell, SWT.PUSH);
-		btnCancel.setText("Cancel");
-		data = new FormData();
-		data.width = 70;
-		data.top = new FormAttachment(attach, 10);
-		data.right = new FormAttachment(100, -10);
-		btnCancel.setLayoutData(data);
-		btnCancel.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event arg0) {
-				result = null;
-				done = true;
-				dispose();
-				imageResizerListener.imageResized(result);
-			}
-		});
-
-		Button btnOk = new Button(shell, SWT.PUSH);
-		btnOk.setText("OK");
-		data = new FormData();
-		data.width = 70;
-		data.top = new FormAttachment(attach, 10);
-		data.right = new FormAttachment(btnCancel, -10);
-		btnOk.setLayoutData(data);
-		btnOk.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event arg0) {
-				result = computeResultImage();
-				done = true;
-				dispose();
-				imageResizerListener.imageResized(result);
-			}
-		});
-
-		shell.setDefaultButton(btnOk);
-		btnOk.setFocus();
-		shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-
-		if (parent != null) {
-			Utils.centerWindowRelativeTo(shell, parent);
-		}
-
-		shell.open();
-		drawCurrentImage();
-
-	}
-
-	private boolean checkSize(Image image) {
-		//If the image is smaller than the minimal size, we shouldn't accept it
-		Rectangle size = image.getBounds();
-		if (size.width < minWidth || size.height < minHeight) {
-			return false;
-		}
-
-		float minHRatio = (float) (minHeight) / size.height;
-		float minWRatio = (float) (minWidth) / size.width;
-
-		float maxHRatio = (float) (minHeight * 4) / size.height;
-		float maxWRatio = (float) (minWidth * 4) / size.width;
-
-		//We must keep the min zoom bigger than the "biggest" ratio (ie, smallest zoom out)
-		minZoomRatio = minHRatio > minWRatio ? minHRatio : minWRatio;
-		maxZoomRatio = maxHRatio > maxWRatio ? maxHRatio : maxWRatio;
-
-		if (maxZoomRatio > 1) {
-			maxZoomRatio = 1;
-		}
-
-		zoomRatio = minZoomRatio;
-
-		return true;
-	}
-
-	private ImageData internalResize(Image image, int newWidth, int newHeight) {
-
-		ImageData srcData = image.getImageData();
-
-		//int width = srcData.width,height = srcData.height;
-
-		ImageData data = srcData;
-		//int newWidth = (int)(width*zoomRatio);
-		//int newHeight = (int)(height*zoomRatio);
-
-		final ImageData copy = new ImageData(newWidth, newHeight, 24,
-				new PaletteData(0x00FF0000, 0x0000FF00, 0x000000FF));
-
-		Image src = new Image(display, srcData);
-		Image dst = new Image(display, copy);
-
-		GC gc = new GC(dst);
-		gc.setAdvanced(true);
-		try {
-			gc.setInterpolation(SWT.HIGH);
-		} catch (Exception e) {
-			// may not be avail
-		}
-		gc.drawImage(src, 0, 0, srcData.width, srcData.height, 0, 0, copy.width,
-				copy.height);
-		//gc.setAlpha(50);
-		//gc.drawImage(src,2,2,srcData.width-2,srcData.height-2,0,0,copy.width,copy.height);
-		gc.dispose();
-
-		data = dst.getImageData();
-
-		src.dispose();
-		dst.dispose();
-
-		return data;
-	}
-
-	private void drawCurrentImage() {
-		GC gcCanvas = new GC(canvas);
-
-		Image temp = new Image(display, displayWidth, displayHeight);
-		GC gc = new GC(temp);
-		gc.drawImage(currentImage, offset.x + MARGIN + 1, offset.y + MARGIN + 1);
-		//gc.setAlpha(128);
-		gc.drawImage(overlay, 0, 0);
-		//gc.setTextAntialias(SWT.ON);
-		//gc.drawText("This is a test", 15, displayHeight-15,true);
-		gc.dispose();
-
-		gcCanvas.drawImage(temp, 0, 0);
-		temp.dispose();
-
-		gcCanvas.dispose();
-	}
-
-	private void insureOffsetIsCorrect() {
-		int minX = minWidth - currentImage.getBounds().width;
-		if (offset.x < minX) {
-			offset.x = minX;
-		}
-
-		int minY = minHeight - currentImage.getBounds().height;
-		if (offset.y < minY) {
-			offset.y = minY;
-		}
-
-		if (offset.x > 0) {
-			offset.x = 0;
-		}
-
-		if (offset.y > 0) {
-			offset.y = 0;
-		}
-
-	}
-
-	private void dispose() {
-		if (shell != null && !shell.isDisposed()) {
-			shell.dispose();
-		}
-
-		if (currentImage != null && !currentImage.isDisposed()) {
-			currentImage.dispose();
-		}
-
-		if (overlayDragging != null && !overlayDragging.isDisposed()) {
-			overlayDragging.dispose();
-		}
-
-		if (overlayNotDragging != null && !overlayNotDragging.isDisposed()) {
-			overlayNotDragging.dispose();
-		}
-
-		if (cursor != null && !cursor.isDisposed()) {
-			cursor.dispose();
-		}
-	}
-
-	private Image computeResultImage() {
-		Image img = new Image(display, minWidth, minHeight);
-
-		/*ImageData srcData = original.getImageData();
-		 ImageData dstData = new ImageData(
-		 currentImage.getBounds().width,
-		 currentImage.getBounds().height,
-		 32,
-		 new PaletteData(0xFF,0xFF00,0xFF0000));
-		 Resample resample = new Resample();		
-		 resample.setFilter(Resample.FILTER_TYPE_LANCZOS3, 7.0f);
-		 resample.process(srcData, dstData);
-		 Image filtered = new Image(display,dstData);
-		 */
-		GC gc = new GC(img);
-		gc.drawImage(currentImage, offset.x, offset.y);
-		gc.dispose();
-		//filtered.dispose();
-		return img;
-	}
-
-	private Image createOverlayImage(final byte marginAlpha,
-			final int marginColor, final byte borderAlpha, final int borderColor) {
-
-		int width = displayWidth;
-		int height = displayHeight;
-
-		ImageData data = new ImageData(width, height, 32, new PaletteData(
-				0x000000FF, 0x0000FF00, 0x00FF0000));
-
-		byte[] transparency = new byte[width * height];
-		int[] pixels = new int[width * height];
-
-		byte rowAlpha[] = new byte[width];
-		int rowPixels[] = new int[width];
-		//Top
-		//Pattern
-		for (int i = 0; i < width; i++) {
-			rowAlpha[i] = marginAlpha;
-			rowPixels[i] = marginColor;
-		}
-		//Fill
-		for (int i = 0; i < MARGIN; i++) {
-			System.arraycopy(rowAlpha, 0, transparency, i * width, width);
-			System.arraycopy(rowPixels, 0, pixels, i * width, width);
-		}
-
-		//Main area
-		//Pattern
-		for (int i = 0; i < MARGIN; i++) {
-			rowAlpha[i] = marginAlpha;
-			rowAlpha[width - i - 1] = marginAlpha;
-		}
-		for (int i = MARGIN; i < width - MARGIN; i++) {
-			rowAlpha[i] = 0;
-		}
-		//Fill
-		for (int i = MARGIN; i < height - MARGIN; i++) {
-			System.arraycopy(rowAlpha, 0, transparency, i * width, width);
-			System.arraycopy(rowPixels, 0, pixels, i * width, width);
-		}
-
-		//Bottom
-		//Pattern
-		for (int i = 0; i < width; i++) {
-			rowAlpha[i] = marginAlpha;
-		}
-		//Fill
-		for (int i = height - MARGIN - 1; i < height; i++) {
-			System.arraycopy(rowAlpha, 0, transparency, i * width, width);
-			System.arraycopy(rowPixels, 0, pixels, i * width, width);
-		}
-
-		//Let's do the border part		
-		for (int i = MARGIN; i < width - MARGIN; i++) {
-			transparency[width * MARGIN + i] = borderAlpha;
-			pixels[width * MARGIN + i] = borderColor;
-		}
-		for (int j = MARGIN; j < height - MARGIN; j++) {
-
-			transparency[j * width + MARGIN] = borderAlpha;
-			pixels[j * width + MARGIN] = borderColor;
-
-			transparency[j * width + width - MARGIN - 1] = borderAlpha;
-			pixels[j * width + width - MARGIN - 1] = borderColor;
-
-		}
-		for (int i = MARGIN; i < width - MARGIN; i++) {
-			transparency[width * (height - MARGIN - 1) + i] = borderAlpha;
-			pixels[width * (height - MARGIN - 1) + i] = borderColor;
-		}
-
-		data.alphaData = transparency;
-		data.setPixels(0, 0, width * height, pixels, 0);
-
-		Image overlay = new Image(display, data);
-
-		return overlay;
-	}
-
-	private void refreshCurrentImage(int position) {
-		float previousZoom = zoomRatio;
-		zoomRatio = (float) position / RESIZE_STEPS;
-		if (zoomRatio > 1) {
-			zoomRatio = 1;
-		}
-		if (zoomRatio < minZoomRatio) {
-			zoomRatio = minZoomRatio;
-		}
-		if (previousZoom != zoomRatio) {
-			Image previous = currentImage;
-			currentImage = new Image(display,
-					internalResize(original, (int) (originalWidth * zoomRatio),
-							(int) (originalHeight * zoomRatio)));
-
-			//float ratio = zoomRatio / previousZoom;
-			offset.x += (previous.getBounds().width - currentImage.getBounds().width) / 2;
-			offset.y += (previous.getBounds().height - currentImage.getBounds().height) / 2;
-
-			if (previous != null && !previous.isDisposed()) {
-				previous.dispose();
-			}
-
-			insureOffsetIsCorrect();
-			drawCurrentImage();
-		}
-	}
-	
-	public interface ImageResizerListener {
-		void imageResized(Image image);
-	}
-
-	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);
-		resizer.resize(img, new  ImageResizerListener() {
-			public void imageResized(Image thumbnail) {
-				System.out.println(thumbnail);
-				
-				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/PlayNowList.java b/com/aelitis/azureus/ui/swt/utils/PlayNowList.java
deleted file mode 100644
index 8b935b5..0000000
--- a/com/aelitis/azureus/ui/swt/utils/PlayNowList.java
+++ /dev/null
@@ -1,52 +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.utils;
-
-import java.util.ArrayList;
-
-import org.gudy.azureus2.core3.util.HashWrapper;
-
-/**
- * @author TuxPaper
- * @created Sep 15, 2007
- *
- */
-public class PlayNowList
-{
-	private static ArrayList playNowList = new ArrayList();
-
-	/**
-	 * @param hw
-	 *
-	 * @since 3.0.1.7
-	 */
-	public static void add(HashWrapper hw) {
-		playNowList.add(hw);
-	}
-
-	public static void remove(HashWrapper hw) {
-		playNowList.remove(hw);
-	}
-	
-	public static boolean contains(HashWrapper hw) {
-		return playNowList.contains(hw);
-	}
-}
diff --git a/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java b/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
index ceadecd..85dbd3c 100644
--- a/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
+++ b/com/aelitis/azureus/ui/swt/utils/TorrentUIUtilsV3.java
@@ -31,6 +31,7 @@ import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 
 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.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
@@ -58,7 +59,6 @@ import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfoContentNetwork;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.browser.listener.DownloadUrlInfoSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader.ImageDownloaderListener;
 import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
 import com.aelitis.azureus.util.*;
 
@@ -77,14 +77,15 @@ public class TorrentUIUtilsV3
 	//catches http://www.vuze.com/download/CHJW43PLS277RC7U3S5XRS2PZ4UUG7RS.torrent
 	private static final Pattern hashPattern = Pattern.compile("download/([A-Z0-9]{32})\\.torrent");
 
+	static ImageLoader imageLoaderThumb;
+
 	public static void loadTorrent(	final DownloadUrlInfo dlInfo, 
 			final boolean playNow, // open player
 			final boolean playPrepare, // as for open player but don't actually open it
-			final boolean bringToFront, final boolean forceDRMtoCDP) {
+			final boolean bringToFront) {
 		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
-				_loadTorrent(core, dlInfo, playNow, playPrepare, bringToFront,
-						forceDRMtoCDP);
+				_loadTorrent(core, dlInfo, playNow, playPrepare, bringToFront);
 			}
 		});
 	}
@@ -93,7 +94,7 @@ public class TorrentUIUtilsV3
 			final DownloadUrlInfo dlInfo, 
 			final boolean playNow, // open player
 			final boolean playPrepare, // as for open player but don't actually open it
-			final boolean bringToFront, final boolean forceDRMtoCDP) {
+			final boolean bringToFront) {
 		if (dlInfo instanceof DownloadUrlInfoSWT) {
 			DownloadUrlInfoSWT dlInfoSWT = (DownloadUrlInfoSWT) dlInfo;
 			dlInfoSWT.invoke(playNow ? "play" : "download");
@@ -117,7 +118,7 @@ public class TorrentUIUtilsV3
 									Debug.outNoStack("loadTorrent already exists.. playing",
 											false);
 
-									TorrentListViewsUtils.playOrStream(dm);
+									TorrentListViewsUtils.playOrStream(dm, -1);
 								} else {
 									Debug.outNoStack("loadTorrent already exists.. preparing",
 											false);
@@ -173,25 +174,8 @@ public class TorrentUIUtilsV3
 										file.deleteOnExit();
 
 										// Do a quick check to see if it's a torrent
-										if (!TorrentUtil.isFileTorrent(file, null, file.getName())) {
-											Matcher m = hashPattern.matcher(inf.getURL());
-											if (m.find()) {
-												String hash = m.group(1);
-
-												ContentNetwork cn = null;
-												if (dlInfo instanceof DownloadUrlInfoContentNetwork) {
-													cn = ((DownloadUrlInfoContentNetwork) dlInfo).getContentNetwork();
-												}
-												if (cn == null) {
-													cn = ConstantsVuze.getDefaultContentNetwork();
-												}
-												TorrentListViewsUtils.viewDetails(cn, hash,
-														"loadtorrent");
-											} else {
-												TorrentUtil.isFileTorrent(file, Utils.findAnyShell(),
-														file.getName());
-											}
-
+										if (!TorrentUtil.isFileTorrent(file, Utils.findAnyShell(),
+												file.getName())) {
 											return;
 										}
 
@@ -217,20 +201,13 @@ public class TorrentUIUtilsV3
 											return;
 										}
 
-										if (forceDRMtoCDP
-												&& (PlatformTorrentUtils.isContentDRM(torrent) || PlatformTorrentUtils.isContentPurchased(torrent))) {
-											TorrentListViewsUtils.viewDetailsFromDS(torrent,
-													"loadtorrent");
-											return;
-										}
-
 										GlobalManager gm = core.getGlobalManager();
 
 										if (playNow || playPrepare) {
 											DownloadManager existingDM = gm.getDownloadManager(hw);
 											if (existingDM != null) {
 												if (playNow) {
-													TorrentListViewsUtils.playOrStream(existingDM);
+													TorrentListViewsUtils.playOrStream(existingDM, -1);
 												} else {
 													PlayUtils.prepareForPlay(existingDM);
 												}
@@ -255,10 +232,6 @@ public class TorrentUIUtilsV3
 										};
 										gm.addListener(l, false);
 
-										if (playNow || playPrepare) {
-											PlayNowList.add(hw);
-										}
-
 										TorrentOpener.openTorrent(file.getAbsolutePath());
 									}
 								}
@@ -282,7 +255,7 @@ public class TorrentUIUtilsV3
 
 					if (playNow || playPrepare) {
 						if (playNow) {
-							TorrentListViewsUtils.playOrStream(dm);
+							TorrentListViewsUtils.playOrStream(dm, -1);
 						} else {
 							PlayUtils.prepareForPlay(dm);
 						}
@@ -347,15 +320,17 @@ public class TorrentUIUtilsV3
 			l.contentImageLoaded(null, true);
 			return null;
 		}
-
-		final ImageLoader imageLoader = ImageLoader.getInstance();
-
+		
+		if (imageLoaderThumb == null) {
+			imageLoaderThumb = new ImageLoader(null, null);
+		}
+		
 		String thumbnailUrl = PlatformTorrentUtils.getContentThumbnailUrl(torrent);
 
 		//System.out.println("thumburl= " + thumbnailUrl);
-		if (thumbnailUrl != null && imageLoader.imageExists(thumbnailUrl)) {
+		if (thumbnailUrl != null && imageLoaderThumb.imageExists(thumbnailUrl)) {
 			//System.out.println("return thumburl");
-			Image image = imageLoader.getImage(thumbnailUrl);
+			Image image = imageLoaderThumb.getImage(thumbnailUrl);
 			l.contentImageLoaded(image, true);
 			return new Image[] { image };
 		}
@@ -370,9 +345,11 @@ public class TorrentUIUtilsV3
 			return null;
 		}
 
-		final String id = "Thumbnail." + hash;
+			// add torrent size here to differentiate meta-data downloads from actuals
+		
+		final String id = "Thumbnail." + hash + "." + torrent.getSize();
 
-		Image image = imageLoader.imageAdded(id) ? imageLoader.getImage(id) : null;
+		Image image = imageLoaderThumb.imageAdded(id) ? imageLoaderThumb.getImage(id) : null;
 		//System.out.println("image = " + image);
 		if (image != null && !image.isDisposed()) {
 			l.contentImageLoaded(image, true);
@@ -416,19 +393,18 @@ public class TorrentUIUtilsV3
 
 			String path = null;
 			if (dm == null) {
-				if (torrent != null) {
-					TOTorrentFile[] files = torrent.getFiles();
-					if (files.length > 0) {
-						path = files[0].getRelativePath();
-					}
+				TOTorrentFile[] files = torrent.getFiles();
+				if (files.length > 0) {
+					path = files[0].getRelativePath();
 				}
 			} else {
-				path = dm.getDownloadState().getPrimaryFile();
+				DiskManagerFileInfo primaryFile = dm.getDownloadState().getPrimaryFile();
+				path = primaryFile == null ? null : primaryFile.getFile(true).getName();
 			}
 			if (path != null) {
 				image = ImageRepository.getPathIcon(path, big, false);
 				
-				if (image != null && torrent != null && !torrent.isSimpleTorrent()) {
+				if (image != null && !torrent.isSimpleTorrent()) {
 					Image[] images = new Image[] {
 						image,
 						ImageRepository.getPathIcon(new File(path).getParent(), false, false)
@@ -438,13 +414,13 @@ public class TorrentUIUtilsV3
 			}
 
 			if (image == null) {
-				imageLoader.addImageNoDipose(id, ImageLoader.noImage);
+				imageLoaderThumb.addImageNoDipose(id, ImageLoader.noImage);
 			} else {
-				imageLoader.addImageNoDipose(id, image);
+				imageLoaderThumb.addImageNoDipose(id, image);
 			}
 		} else {
 			//System.out.println("has mystery image");
-			imageLoader.addImage(id, image);
+			imageLoaderThumb.addImage(id, image);
 		}
 
 		l.contentImageLoaded(image, true);
@@ -452,17 +428,19 @@ public class TorrentUIUtilsV3
 	}
 
 	public static void releaseContentImage(Object datasource) {
+		if (imageLoaderThumb == null) {
+			return;
+		}
+
 		TOTorrent torrent = DataSourceUtils.getTorrent(datasource);
 		if (torrent == null) {
 			return;
 		}
 
-		ImageLoader imageLoader = ImageLoader.getInstance();
-
 		String thumbnailUrl = PlatformTorrentUtils.getContentThumbnailUrl(torrent);
 
 		if (thumbnailUrl != null) {
-			imageLoader.releaseImage(thumbnailUrl);
+			imageLoaderThumb.releaseImage(thumbnailUrl);
 		} else {
 			String hash = null;
 			try {
@@ -473,8 +451,9 @@ public class TorrentUIUtilsV3
 				return;
 			}
 
-			String id = "Thumbnail." + hash;
-			imageLoader.releaseImage(id);
+			String id = "Thumbnail." + hash + "." + torrent.getSize();
+						
+			imageLoaderThumb.releaseImage(id);
 		}
 	}
 
diff --git a/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java b/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
index d031798..3f50f29 100644
--- a/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
+++ b/com/aelitis/azureus/ui/swt/utils/UIMagnetHandler.java
@@ -18,25 +18,12 @@
 
 package com.aelitis.azureus.ui.swt.utils;
 
-import java.util.Map;
-
 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.Constants;
-import org.gudy.azureus2.ui.swt.UISwitcherUtil;
-import org.gudy.azureus2.ui.swt.Utils;
 
-import com.aelitis.azureus.core.*;
-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.azureus.core.AzureusCore;
 import com.aelitis.net.magneturi.MagnetURIHandler;
 
-import org.gudy.azureus2.plugins.PluginInterface;
-
 /**
  * @author TuxPaper
  * @created May 27, 2008
@@ -58,78 +45,5 @@ public class UIMagnetHandler
 
 		MagnetURIHandler magnetURIHandler = MagnetURIHandler.getSingleton();
 		magnetURIHandler.addInfo("get-version-info", val);
-
-		core.addLifecycleListener(new AzureusCoreLifecycleAdapter() {
-			public void componentCreated(final AzureusCore core,
-					AzureusCoreComponent component) {
-				if (component instanceof PluginInterface) {
-					PluginInterface pi = (PluginInterface) component;
-					if (pi.getPlugin() instanceof MagnetPlugin) {
-
-						MagnetPlugin magnetPlugin = (MagnetPlugin) pi.getPlugin();
-						magnetPlugin.addListener(new MagnetPluginListener() {
-							public boolean set(String name, Map values) {
-								if (name.equals("AZMSG") && values != null) {
-									String val = (String) values.get("value");
-									if (val.indexOf(";switch-ui;") > 0) {
-
-										if (COConfigurationManager.getStringParameter("ui", "az3").equals(
-												"az3")) {
-											return false;
-										}
-
-										if (!UISwitcherUtil.isAZ3Avail()) {
-											return false;
-										}
-
-										UIFunctions uif = UIFunctionsManager.getUIFunctions();
-										if (uif == null) {
-											core.addLifecycleListener(new AzureusCoreLifecycleAdapter() {
-												public void componentCreated(AzureusCore core,
-														AzureusCoreComponent component) {
-													if (component instanceof UIFunctions) {
-														uiswitch(core, (UIFunctions) component);
-													}
-												}
-											});
-										} else {
-											uiswitch(core, uif);
-										}
-
-										return true;
-									}
-								}
-								return false;
-							}
-
-							public int get(String name, Map values) {
-								return Integer.MIN_VALUE;
-							}
-						});
-					}
-				}
-			}
-		});
-	}
-
-	private static void uiswitch(final AzureusCore core, final UIFunctions uif) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				uif.bringToFront();
-				uif.promptUser(MessageText.getString("dialog.uiswitch.title"),
-						MessageText.getString("dialog.uiswitch.text"), new String[] {
-							MessageText.getString("dialog.uiswitch.button"),
-						}, 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/PieceGraphView.java b/com/aelitis/azureus/ui/swt/views/PieceGraphView.java
index 3fe6607..bb6a8e4 100644
--- a/com/aelitis/azureus/ui/swt/views/PieceGraphView.java
+++ b/com/aelitis/azureus/ui/swt/views/PieceGraphView.java
@@ -38,17 +38,14 @@ import org.gudy.azureus2.core3.peer.PEPiece;
 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.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.plugins.UISWTView;
 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 /**
  * @author TuxPaper
@@ -186,7 +183,7 @@ public class PieceGraphView
 					if (BLOCK_SIZE <= 0) {
 						BLOCK_SIZE = 1;
 					}
-					// since calc above doesn't account for not splitting squares accross
+					// since calc above doesn't account for not splitting squares across
 					// rows, make sure we can fit.  If we can't, we have to shrink
 					int numCanFit = (bounds.width / BLOCK_SIZE)
 							* (bounds.height / BLOCK_SIZE);
diff --git a/com/aelitis/azureus/ui/swt/views/TopBarView.java b/com/aelitis/azureus/ui/swt/views/TopBarView.java
index 92ac6e2..fbc5b68 100644
--- a/com/aelitis/azureus/ui/swt/views/TopBarView.java
+++ b/com/aelitis/azureus/ui/swt/views/TopBarView.java
@@ -20,7 +20,6 @@ package com.aelitis.azureus.ui.swt.views;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
@@ -36,10 +35,8 @@ 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.plugins.UISWTInstance;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
-import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
 import org.gudy.azureus2.ui.swt.views.stats.VivaldiView;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -61,9 +58,9 @@ import com.aelitis.azureus.ui.swt.views.skin.SkinView;
 public class TopBarView
 	extends SkinView
 {
-	private List topbarViews = new ArrayList();
+	private List<UISWTViewCore> topbarViews = new ArrayList<UISWTViewCore>();
 
-	private IView activeTopBar;
+	private UISWTViewCore activeTopBar;
 
 	private SWTSkin skin;
 
@@ -71,6 +68,8 @@ public class TopBarView
 
 	private Composite cPluginArea;
 
+	private static boolean registeredCoreSubViews = false;
+
 	
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
 		this.skin = skinObject.getSkin();
@@ -112,11 +111,6 @@ public class TopBarView
 		}
 
 		try {
-			IView[] coreTopBarViews = {
-				new ViewDownSpeedGraph(),
-				new ViewUpSpeedGraph(),
-				new VivaldiView(false)
-			};
 
 			cPluginArea = (Composite) skinObject.getControl();
 
@@ -125,9 +119,9 @@ public class TopBarView
 					Object[] views = topbarViews.toArray();
 					for (int i = 0; i < views.length; i++) {
 						try {
-							IView view = (IView) views[i];
+							UISWTViewCore view = (UISWTViewCore) views[i];
 							if (view.getComposite().isVisible()) {
-								view.refresh();
+								view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
 							}
 						} catch (Exception e) {
 							Debug.out(e);
@@ -156,8 +150,10 @@ public class TopBarView
 					Object[] views = topbarViews.toArray();
 					topbarViews.clear();
 					for (int i = 0; i < views.length; i++) {
-						IView view = (IView) views[i];
-						view.delete();
+						UISWTViewCore view = (UISWTViewCore) views[i];
+						if (view != null) {
+							view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+						}
 					}
 				}
 			});
@@ -177,7 +173,7 @@ public class TopBarView
 						if (i < 0) {
 							i = topbarViews.size() - 1;
 						}
-						activateTopBar((IView) topbarViews.get(i));
+						activateTopBar((UISWTViewCore) topbarViews.get(i));
 					}
 				});
 			}
@@ -196,7 +192,7 @@ public class TopBarView
 						if (i >= topbarViews.size()) {
 							i = 0;
 						}
-						activateTopBar((IView) topbarViews.get(i));
+						activateTopBar((UISWTViewCore) topbarViews.get(i));
 					}
 				});
 			}
@@ -221,7 +217,7 @@ public class TopBarView
 								transform.rotate(270);
 								e.gc.setTransform(transform);
 
-								String s = activeTopBar.getShortTitle();
+								String s = activeTopBar.getFullTitle();
 								Point size = e.gc.textExtent(s);
 								e.gc.drawText(s, -size.x, 0, true);
 								//e.gc.drawText(s, 0,0, true);
@@ -247,7 +243,7 @@ public class TopBarView
 					public void widgetSelected(SelectionEvent e) {
 						int i = listPlugins.getSelectionIndex();
 						if (i >= 0 && i < topbarViews.size()) {
-							activateTopBar((IView) topbarViews.get(i));
+							activateTopBar((UISWTViewCore) topbarViews.get(i));
 							COConfigurationManager.setParameter("topbar.viewindex", i);
 						}
 					}
@@ -321,45 +317,42 @@ public class TopBarView
 			int toActiveView = COConfigurationManager.getIntParameter(
 					"topbar.viewindex", 0);
 			int viewIndex = toActiveView;
-			for (int i = 0; i < coreTopBarViews.length; i++) {
-				IView view = coreTopBarViews[i];
-				addTopBarView(view, cPluginArea);
-				if (toActiveView-- == 0) {
-					activateTopBar(view);
-					if (listPlugins != null) {
-						listPlugins.setSelection(viewIndex);
-					}
-				}
-			}
 
 			UISWTInstanceImpl uiSWTinstance = (UISWTInstanceImpl) UIFunctionsManagerSWT.getUIFunctionsSWT().getUISWTInstance();
-			Map pluginViews = null;
-			pluginViews = uiSWTinstance.getViewListeners(UISWTInstance.VIEW_TOPBAR);
-			if (pluginViews != null) {
-				String[] sNames = (String[]) pluginViews.keySet().toArray(new String[0]);
-				for (int i = 0; i < sNames.length; i++) {
-					UISWTViewEventListener l = (UISWTViewEventListener) pluginViews.get(sNames[i]);
-					if (l != null) {
-						try {
-							UISWTViewImpl view = new UISWTViewImpl(UISWTInstance.VIEW_TOPBAR,
-									sNames[i], l);
-							addTopBarView(view, cPluginArea);
-							if (toActiveView-- == 0) {
-								activateTopBar(view);
-								if (listPlugins != null) {
-									listPlugins.setSelection(viewIndex);
-								}
+			
+			if (uiSWTinstance != null && !registeredCoreSubViews ) {
+				uiSWTinstance.addView(UISWTInstance.VIEW_TOPBAR, "ViewDownSpeedGraph",
+						new ViewDownSpeedGraph());
+				uiSWTinstance.addView(UISWTInstance.VIEW_TOPBAR, "ViewUpSpeedGraph",
+						new ViewUpSpeedGraph());
+				uiSWTinstance.addView(UISWTInstance.VIEW_TOPBAR, "ViewDownSpeedGraph",
+						new VivaldiView(false));
+
+				registeredCoreSubViews = true;
+			}
+
+			UISWTViewEventListenerHolder[] pluginViews = uiSWTinstance.getViewListeners(UISWTInstance.VIEW_TOPBAR);
+			for (UISWTViewEventListenerHolder l : pluginViews) {
+				if (l != null) {
+					try {
+						UISWTViewImpl view = new UISWTViewImpl(UISWTInstance.VIEW_TOPBAR,
+								l.getViewID(), l, null);
+						addTopBarView(view, cPluginArea);
+						if (toActiveView-- == 0) {
+							activateTopBar(view);
+							if (listPlugins != null) {
+								listPlugins.setSelection(viewIndex);
 							}
-						} catch (Exception e) {
-							e.printStackTrace();
-							// skip, plugin probably specifically asked to not be added
 						}
+					} catch (Exception e) {
+						e.printStackTrace();
+						// skip, plugin probably specifically asked to not be added
 					}
 				}
 			}
 
 			if (toActiveView >= 0 && topbarViews.size() > 0) {
-				activeTopBar = (IView) topbarViews.get(0);
+				activeTopBar = topbarViews.get(0);
 				activeTopBar.getComposite().setVisible(true);
 			}
 
@@ -374,7 +367,7 @@ public class TopBarView
 	 *
 	 * @since 3.0.1.1
 	 */
-	protected void activateTopBar(IView view) {
+	protected void activateTopBar(UISWTViewCore view) {
 		if (activeTopBar != null) {
 			Composite c = activeTopBar.getComposite();
 			while (c.getParent() != cPluginArea) {
@@ -401,7 +394,7 @@ public class TopBarView
 	 *
 	 * @since 3.0.1.1
 	 */
-	private void addTopBarView(IView view, Composite composite) {
+	private void addTopBarView(UISWTViewCore view, Composite composite) {
 		Composite parent = new Composite(composite, SWT.None);
 		parent.setLayoutData(Utils.getFilledFormData());
 		parent.setLayout(new FormLayout());
diff --git a/com/aelitis/azureus/ui/swt/views/ViewDownSpeedGraph.java b/com/aelitis/azureus/ui/swt/views/ViewDownSpeedGraph.java
index e4e0301..5829d75 100644
--- a/com/aelitis/azureus/ui/swt/views/ViewDownSpeedGraph.java
+++ b/com/aelitis/azureus/ui/swt/views/ViewDownSpeedGraph.java
@@ -29,15 +29,16 @@ import org.eclipse.swt.widgets.Composite;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerStats;
-import org.gudy.azureus2.core3.stats.transfer.OverallStats;
-import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 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.core3.util.TimerEventPeriodic;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
@@ -51,7 +52,7 @@ import com.aelitis.azureus.ui.swt.skin.SWTSkinProperties;
  *
  */
 public class ViewDownSpeedGraph
-	extends AbstractIView
+	implements UISWTViewCoreEventListener
 {
 
 	GlobalManager manager = null;
@@ -65,6 +66,8 @@ public class ViewDownSpeedGraph
 	TimerEventPeriodic	timerEvent;
 	
 	private boolean everRefreshed = false;
+
+	private UISWTView swtView;
 	
 	public ViewDownSpeedGraph() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
@@ -75,7 +78,7 @@ public class ViewDownSpeedGraph
 		});
 	}
 
-	public void periodicUpdate() {
+	private void periodicUpdate() {
 		if (manager == null || stats == null) {
 			return;
 		}
@@ -90,7 +93,7 @@ public class ViewDownSpeedGraph
 		});
 	}
 
-	public void initialize(Composite composite) {
+	private void initialize(Composite composite) {
 		GridData gridData;
 
 		downSpeedCanvas = new Canvas(composite, SWT.DOUBLE_BUFFERED);
@@ -112,22 +115,22 @@ public class ViewDownSpeedGraph
 				skinProperties.getColor("color.topbar.speed.trimmed"));
 	}
 
-	public void delete() {
+	private void delete() {
 		Utils.disposeComposite(downSpeedCanvas);
 		downSpeedGraphic.dispose();
 	}
 
-	public String getFullTitle() {
+	private String getFullTitle() {
 		return "DL Speed";
 	}
 	
 	
 
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return downSpeedCanvas;
 	}
 
-	public void refresh() {
+	private void refresh() {
 		if (!everRefreshed) {
 			everRefreshed = true;
 			timerEvent = SimpleTimer.addPeriodicEvent("TopBarSpeedGraphicView", 1000, new TimerEventPerformer() {
@@ -143,7 +146,31 @@ public class ViewDownSpeedGraph
 		downSpeedGraphic.refresh();
 	}
 
-	public String getData() {
-		return "SpeedView.title.full";
-	}
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/com/aelitis/azureus/ui/swt/views/ViewTitleInfoBetaP.java b/com/aelitis/azureus/ui/swt/views/ViewTitleInfoBetaP.java
new file mode 100644
index 0000000..1dd368f
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/ViewTitleInfoBetaP.java
@@ -0,0 +1,69 @@
+package com.aelitis.azureus.ui.swt.views;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.util.JSONUtils;
+import com.aelitis.azureus.util.MapUtils;
+
+public class ViewTitleInfoBetaP
+	implements ViewTitleInfo
+{
+	private static final String PARAM_LASTPOSTCOUNT = "betablog.numPosts";
+
+	long numNew = 0;
+
+	private long postCount = 0;
+
+	@SuppressWarnings("rawtypes")
+	public ViewTitleInfoBetaP() {
+		SimpleTimer.addEvent("devblog", SystemTime.getCurrentTime(),
+				new TimerEventPerformer() {
+					public void perform(TimerEvent event) {
+						long lastPostCount = COConfigurationManager.getLongParameter(
+								PARAM_LASTPOSTCOUNT, 0);
+						PluginInterface pi = PluginInitializer.getDefaultInterface();
+						try {
+							ResourceDownloader rd = pi.getUtilities().getResourceDownloaderFactory().create(
+									new URL(
+											"http://api.tumblr.com/v2/blog/devblog.vuze.com/info?api_key=C5a8UGiSwPflOrVecjcvwGiOWVsLFF22pC9SgUIKSuQfjAvDAY"));
+							InputStream download = rd.download();
+							Map json = JSONUtils.decodeJSON(FileUtil.readInputStreamAsString(
+									download, 65535));
+							Map mapResponse = MapUtils.getMapMap(json, "response", null);
+							if (mapResponse != null) {
+								Map mapBlog = MapUtils.getMapMap(mapResponse, "blog", null);
+								if (mapBlog != null) {
+									postCount = MapUtils.getMapLong(mapBlog, "posts", 0);
+									numNew = postCount - lastPostCount;
+									ViewTitleInfoManager.refreshTitleInfo(ViewTitleInfoBetaP.this);
+								}
+							}
+
+						} catch (Exception e) {
+						}
+					}
+				});
+	}
+
+	public Object getTitleInfoProperty(int propertyID) {
+		if (propertyID == TITLE_INDICATOR_TEXT && numNew > 0) {
+			return "" + numNew;
+		}
+		return null;
+	}
+
+	public void clearIndicator() {
+		COConfigurationManager.setParameter(PARAM_LASTPOSTCOUNT, postCount);
+		numNew = 0;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/ViewUpSpeedGraph.java b/com/aelitis/azureus/ui/swt/views/ViewUpSpeedGraph.java
index 25dc9e3..0b8253f 100644
--- a/com/aelitis/azureus/ui/swt/views/ViewUpSpeedGraph.java
+++ b/com/aelitis/azureus/ui/swt/views/ViewUpSpeedGraph.java
@@ -29,15 +29,16 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerStats;
-import org.gudy.azureus2.core3.stats.transfer.OverallStats;
-import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 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.core3.util.TimerEventPeriodic;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
@@ -49,7 +50,7 @@ import com.aelitis.azureus.core.AzureusCoreFactory;
  *
  */
 public class ViewUpSpeedGraph
-	extends AbstractIView
+	implements UISWTViewCoreEventListener
 {
 
 	GlobalManager manager = null;
@@ -63,7 +64,9 @@ public class ViewUpSpeedGraph
 	TimerEventPeriodic	timerEvent;
 	
 	private boolean everRefreshed = false;
-	
+
+	private UISWTView swtView;
+
 	public ViewUpSpeedGraph() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
@@ -73,7 +76,7 @@ public class ViewUpSpeedGraph
 		});
 	}
 
-	public void initialize(Composite composite) {
+	private void initialize(Composite composite) {
 		GridData gridData;
 
 		upSpeedCanvas = new Canvas(composite, SWT.DOUBLE_BUFFERED);
@@ -84,7 +87,7 @@ public class ViewUpSpeedGraph
 		//upSpeedGraphic.setAutoAlpha(true);
 	}
 	
-	public void periodicUpdate() {
+	private void periodicUpdate() {
 		if (stats == null || manager == null) {
 			return;
 		}
@@ -99,20 +102,20 @@ public class ViewUpSpeedGraph
 		});
 	}
 
-	public void delete() {
+	private void delete() {
 		Utils.disposeComposite(upSpeedCanvas);
 		upSpeedGraphic.dispose();
 	}
 
-	public String getFullTitle() {
+	private String getFullTitle() {
 		return "UL Speed";
 	}
 
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return upSpeedCanvas;
 	}
 
-	public void refresh() {
+	private void refresh() {
 		if (!everRefreshed) {
 			everRefreshed = true;
 			timerEvent = SimpleTimer.addPeriodicEvent("TopBarSpeedGraphicView", 1000, new TimerEventPerformer() {
@@ -128,7 +131,31 @@ public class ViewUpSpeedGraph
 		upSpeedGraphic.refresh();
 	}
 
-	public String getData() {
-		return "SpeedView.title.full";
-	}
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/Browse.java b/com/aelitis/azureus/ui/swt/views/skin/Browse.java
index 1e3dc9b..7e15d76 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/Browse.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/Browse.java
@@ -20,17 +20,6 @@
 
 package com.aelitis.azureus.ui.swt.views.skin;
 
-import java.util.ArrayList;
-import java.util.List;
-
-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.widgets.Shell;
-
-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;
@@ -39,25 +28,15 @@ import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
 import org.gudy.azureus2.plugins.ui.menus.MenuManager;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarCloseListener;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
-import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-import com.aelitis.azureus.core.messenger.config.PlatformConfigMessenger;
-import com.aelitis.azureus.ui.common.RememberedDecisionsManager;
+import com.aelitis.azureus.ui.mdi.*;
 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.mdi.MultipleDocumentInterfaceSWT;
 import com.aelitis.azureus.ui.swt.skin.*;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-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.ui.swt.views.skin.sidebar.SideBarListener;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.ContentNetworkUtils;
 
@@ -68,32 +47,25 @@ import com.aelitis.azureus.util.ContentNetworkUtils;
  */
 public class Browse
 	extends SkinView
-	implements SideBarCloseListener
+	implements MdiCloseListener
 {
-	protected static final String CFG_SHOWCLOSE = "contentnetwork.close.reminder";
-
 	private SWTSkinObjectBrowser browserSkinObject;
 
 	public SWTSkinObjectBrowser getBrowserSkinObject() {
 		return browserSkinObject;
 	}
 
-	private SWTSkin skin;
-
 	private SWTSkinObject soMain;
 
-	private SideBarVitalityImage vitalityImage;
+	private MdiEntryVitalityImage vitalityImage;
 
 	private ContentNetwork contentNetwork;
 	
-	// Only accessed in SWT thread
-	private static List<Long> listAlreadyCalledLoginRPC = new ArrayList<Long>();
-
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectCreated(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectCreated(SWTSkinObject skinObject, Object params) {
-		final SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			final SideBarEntrySWT entry = sidebar.getEntryBySkinView(this);
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			MdiEntry entry = mdi.getEntryBySkinView(this);
 			if (entry != null) {
 				entry.addListener(this);
 			}
@@ -107,7 +79,6 @@ public class Browse
 	 */
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
 		this.soMain = skinObject;
-		skin = skinObject.getSkin();
 		Object creationParams = skinObject.getData("CreationParams");
 
 		if (creationParams instanceof ContentNetwork) {
@@ -116,32 +87,22 @@ public class Browse
 			contentNetwork = ConstantsVuze.getDefaultContentNetwork();
 		}
 		
-		// Vuze network login happens in Initializer.  The rest can be initialized
-		// when browser area is created (here)
-		long cnID = contentNetwork.getID();
-		if (cnID != ContentNetwork.CONTENT_NETWORK_VUZE) {
-			if (!listAlreadyCalledLoginRPC.contains(new Long(cnID))) { 
-				PlatformConfigMessenger.login(contentNetwork.getID(), 0);
-				listAlreadyCalledLoginRPC.add(new Long(cnID));
-			}
-		}
-
 		browserSkinObject = SWTSkinUtils.findBrowserSO(soMain);
 
-		final SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			final SideBarEntrySWT entry = sidebar.getEntryBySkinView(this);
+		final MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			final MdiEntry entry = mdi.getEntryBySkinView(this);
 			if (entry != null) {
 				vitalityImage = entry.addVitalityImage("image.sidebar.vitality.dots");
 				vitalityImage.setVisible(false);
 
-				sidebar.addListener(new SideBarListener() {
+				mdi.addListener(new MdiListener() {
 					long lastSelect = 0;
 
-					public void sidebarItemSelected(SideBarEntrySWT newSideBarEntry,
-							SideBarEntrySWT oldSideBarEntry) {
-						if (entry == newSideBarEntry) {
-							if (entry == oldSideBarEntry) {
+					public void mdiEntrySelected(MdiEntry newEntry,
+							MdiEntry oldEntry) {
+						if (entry == newEntry) {
+							if (entry == oldEntry) {
 								if (lastSelect < SystemTime.getOffsetTime(-1000)) {
 									if (browserSkinObject != null) {
 										browserSkinObject.restart();
@@ -229,137 +190,13 @@ public class Browse
 					});
 				}
 			});
-
-			if (contentNetwork != ConstantsVuze.getDefaultContentNetwork()) {
-				menuItem = menuManager.addMenuItem(parent, "Remove HD Network");
-				menuItem.addListener(new MenuItemListener() {
-					public void selected(MenuItem menu, Object target) {
-						if (sidebar != null) {
-							final SideBarEntrySWT entry = sidebar.getEntryBySkinView(Browse.this);
-							if (entry != null) {
-								entry.removeListener(Browse.this);
-							}
-							sidebar.closeEntry(ContentNetworkUtils.getTarget(contentNetwork));
-						}
-						contentNetwork.remove();
-					}
-				});
-
-				menuItem = menuManager.addMenuItem(parent, "Reset IP Flag && Close");
-				menuItem.addListener(new MenuItemListener() {
-					public void selected(MenuItem menu, Object target) {
-						contentNetwork.setPersistentProperty(
-								ContentNetwork.PP_AUTH_PAGE_SHOWN, Boolean.FALSE);
-						if (sidebar != null) {
-							final SideBarEntrySWT entry = sidebar.getEntryBySkinView(Browse.this);
-							if (entry != null) {
-								entry.removeListener(Browse.this);
-							}
-							sidebar.closeEntry(ContentNetworkUtils.getTarget(contentNetwork));
-						}
-					}
-				});
-			}
-			menuItem = menuManager.addMenuItem(parent, "Source Ref: "
-					+ contentNetwork.getPersistentProperty(ContentNetwork.PP_SOURCE_REF));
-			menuItem.setEnabled(false);
 		}
 
 		return null;
 	}
 
-	public void sidebarClosed(SideBarEntry entry) {
-		boolean wasActive = false;
-		Object prop = contentNetwork.getPersistentProperty(ContentNetwork.PP_ACTIVE);
-		if (prop instanceof Boolean) {
-			wasActive = ((Boolean) prop).booleanValue();
-		}
-		
+	public void mdiEntryClosed(MdiEntry entry, boolean userClosed) {
 		contentNetwork.setPersistentProperty(ContentNetwork.PP_ACTIVE,
 				Boolean.FALSE);
-		
-		// send sidebar close event to webapp
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				Shell shell = null;
-				
-				String url = ContentNetworkUtils.getUrl(contentNetwork,
-						ContentNetwork.SERVICE_SIDEBAR_CLOSE);
-				if (url == null) {
-					return;
-				}
-				
-				UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-				if (uiFunctions != null) {
-					shell = uiFunctions.getMainShell();
-				}
-				
-				if (shell == null) {
-					return;
-				}
-				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();
-							}
-						});
-					}
-
-					public void changed(ProgressEvent event) {
-					}
-				});
-				
-				browser.setUrl(url);
-			}
-		});
-
-		if (!wasActive) {
-			return;
-		}
-
-		int decision = RememberedDecisionsManager.getRememberedDecision(CFG_SHOWCLOSE);
-		if (decision != 1) {
-			final SkinnedDialog closeDialog = new SkinnedDialog(
-					"skin3_close_notification", "close-notification.body");
-			
-			closeDialog.setTitle(MessageText.getString("v3.dialog.cnclose.title",
-					new String[] {
-						contentNetwork.getName()
-					}));
-			SWTSkin skin = closeDialog.getSkin();
-			SWTSkinObjectButton soButton = (SWTSkinObjectButton) skin.getSkinObject("close");
-
-			if (soButton != null) {
-				soButton.addSelectionListener(new ButtonListenerAdapter() {
-					public void pressed(SWTSkinButtonUtility buttonUtility,
-							SWTSkinObject skinObject, int stateMask) {
-						closeDialog.close();
-					}
-				});
-			}
-
-			closeDialog.addCloseListener(new SkinnedDialogClosedListener() {
-				public void skinDialogClosed(SkinnedDialog dialog) {
-					SWTSkin skin = closeDialog.getSkin();
-					SWTSkinObjectCheckbox soCheck = (SWTSkinObjectCheckbox) skin.getSkinObject("noshowagain");
-					if (soCheck != null && soCheck.isChecked()) {
-						RememberedDecisionsManager.setRemembered(CFG_SHOWCLOSE, 1);
-					}
-				}
-			});
-
-			closeDialog.open();
-		}
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/FakeTableCell.java b/com/aelitis/azureus/ui/swt/views/skin/FakeTableCell.java
deleted file mode 100644
index 1eeea7c..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/FakeTableCell.java
+++ /dev/null
@@ -1,384 +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.events.MouseEvent;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-/**
- * Legacy support for EMP.  Class moved to
- * {@link org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell}
- * 
- * @author TuxPaper
- * @created Jan 1, 2008
- *
- */
-public class FakeTableCell implements TableCell
-{
-	org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell cell;
-
-	public FakeTableCell(TableColumn column) {
-		cell = new org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell(column);
-	}
-
-	public FakeTableCell(TableColumnCore column) {
-		cell = new org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell(column);
-	}
-
-	public void refresh() {
-		cell.refresh();
-		cell.redraw();
-	}
-
-	public void addDisposeListener(TableCellDisposeListener listener) {
-		cell.addDisposeListener(listener);
-	}
-
-	public void addListeners(Object listenerObject) {
-		cell.addListeners(listenerObject);
-	}
-
-	public void addMouseListener(TableCellMouseListener listener) {
-		cell.addMouseListener(listener);
-	}
-
-	public void addMouseMoveListener(TableCellMouseMoveListener listener) {
-		cell.addMouseMoveListener(listener);
-	}
-
-	public void addRefreshListener(TableCellRefreshListener listener) {
-		cell.addRefreshListener(listener);
-	}
-
-	public void addToolTipListener(TableCellToolTipListener listener) {
-		cell.addToolTipListener(listener);
-	}
-
-	public void addVisibilityListener(TableCellVisibilityListener listener) {
-		cell.addVisibilityListener(listener);
-	}
-
-	public int compareTo(Object arg0) {
-		return cell.compareTo(arg0);
-	}
-
-	public void dispose() {
-		cell.dispose();
-	}
-
-	public void doPaint(GC gc, Rectangle bounds) {
-		cell.doPaint(gc, bounds);
-	}
-
-	public boolean equals(Object obj) {
-		return cell.equals(obj);
-	}
-
-	public int[] getBackground() {
-		return cell.getBackground();
-	}
-
-	public Graphic getBackgroundGraphic() {
-		return cell.getBackgroundGraphic();
-	}
-
-	public int getCursorID() {
-		return cell.getCursorID();
-	}
-
-	public Object getDataSource() {
-		return cell.getDataSource();
-	}
-
-	public int[] getForeground() {
-		return cell.getForeground();
-	}
-
-	public Graphic getGraphic() {
-		return cell.getGraphic();
-	}
-
-	public int getHeight() {
-		return cell.getHeight();
-	}
-
-	public int getMaxLines() {
-		return cell.getMaxLines();
-	}
-
-	public String getObfusticatedText() {
-		return cell.getObfusticatedText();
-	}
-
-	public Comparable getSortValue() {
-		return cell.getSortValue();
-	}
-
-	public TableColumn getTableColumn() {
-		return cell.getTableColumn();
-	}
-
-	public String getTableID() {
-		return cell.getTableID();
-	}
-
-	public TableRow getTableRow() {
-		return cell.getTableRow();
-	}
-
-	public TableRowCore getTableRowCore() {
-		return cell.getTableRowCore();
-	}
-
-	public String getText() {
-		return cell.getText();
-	}
-
-	public Object getToolTip() {
-		return cell.getToolTip();
-	}
-
-	public boolean getVisuallyChangedSinceRefresh() {
-		return cell.getVisuallyChangedSinceRefresh();
-	}
-
-	public int getWidth() {
-		return cell.getWidth();
-	}
-
-	public int hashCode() {
-		return cell.hashCode();
-	}
-
-	public void invalidate() {
-		cell.invalidate();
-	}
-
-	public void invalidate(boolean mustRefresh) {
-		cell.invalidate(mustRefresh);
-	}
-
-	public void invokeMouseListeners(TableCellMouseEvent event) {
-		cell.invokeMouseListeners(event);
-	}
-
-	public void invokeToolTipListeners(int type) {
-		cell.invokeToolTipListeners(type);
-	}
-
-	public void invokeVisibilityListeners(int visibility,
-			boolean invokeColumnListeners) {
-		cell.invokeVisibilityListeners(visibility, invokeColumnListeners);
-	}
-
-	public boolean isDisposed() {
-		return cell.isDisposed();
-	}
-
-	public boolean isMouseOver() {
-		return cell.isMouseOver();
-	}
-
-	public boolean isShown() {
-		return cell.isShown();
-	}
-
-	public boolean isUpToDate() {
-		return cell.isUpToDate();
-	}
-
-	public boolean isValid() {
-		return cell.isValid();
-	}
-
-	public void locationChanged() {
-		cell.locationChanged();
-	}
-
-	public void mouseDoubleClick(MouseEvent e) {
-		cell.mouseDoubleClick(e);
-	}
-
-	public void mouseDown(MouseEvent e) {
-		cell.mouseDown(e);
-	}
-
-	public void mouseEnter(MouseEvent e) {
-		cell.mouseEnter(e);
-	}
-
-	public void mouseExit(MouseEvent e) {
-		cell.mouseExit(e);
-	}
-
-	public void mouseHover(MouseEvent e) {
-		cell.mouseHover(e);
-	}
-
-	public void mouseMove(MouseEvent e) {
-		cell.mouseMove(e);
-	}
-
-	public void mouseUp(MouseEvent e) {
-		cell.mouseUp(e);
-	}
-
-	public boolean needsPainting() {
-		return cell.needsPainting();
-	}
-
-	public void paintControl(PaintEvent e) {
-		cell.paintControl(e);
-	}
-
-	public boolean refresh(boolean doGraphics, boolean rowVisible,
-			boolean cellVisible) {
-		return cell.refresh(doGraphics, rowVisible, cellVisible);
-	}
-
-	public boolean refresh(boolean doGraphics, boolean rowVisible) {
-		return cell.refresh(doGraphics, rowVisible);
-	}
-
-	public boolean refresh(boolean doGraphics) {
-		return cell.refresh(doGraphics);
-	}
-
-	public void removeDisposeListener(TableCellDisposeListener listener) {
-		cell.removeDisposeListener(listener);
-	}
-
-	public void removeMouseListener(TableCellMouseListener listener) {
-		cell.removeMouseListener(listener);
-	}
-
-	public void removeMouseMoveListener(TableCellMouseMoveListener listener) {
-		cell.removeMouseMoveListener(listener);
-	}
-
-	public void removeRefreshListener(TableCellRefreshListener listener) {
-		cell.removeRefreshListener(listener);
-	}
-
-	public void removeToolTipListener(TableCellToolTipListener listener) {
-		cell.removeToolTipListener(listener);
-	}
-
-	public void removeVisibilityListener(TableCellVisibilityListener listener) {
-		cell.removeVisibilityListener(listener);
-	}
-
-	public void setControl(Composite composite) {
-		cell.setControl(composite);
-	}
-
-	public void setCursorID(int cursorID) {
-		cell.setCursorID(cursorID);
-	}
-
-	public void setDataSource(Object datasource) {
-		cell.setDataSource(datasource);
-	}
-
-	public void setFillCell(boolean fillCell) {
-		cell.setFillCell(fillCell);
-	}
-
-	public boolean setForeground(int red, int green, int blue) {
-		return cell.setForeground(red, green, blue);
-	}
-
-	public boolean setForeground(int[] rgb) {
-		return cell.setForeground(rgb);
-	}
-
-	public boolean setForegroundToErrorColor() {
-		return cell.setForegroundToErrorColor();
-	}
-
-	public boolean setGraphic(Graphic img) {
-		return cell.setGraphic(img);
-	}
-
-	public void setMarginHeight(int height) {
-		cell.setMarginHeight(height);
-	}
-
-	public void setMarginWidth(int width) {
-		cell.setMarginWidth(width);
-	}
-
-	public void setOrentation(int o) {
-		cell.setOrentation(o);
-	}
-
-	public boolean setSortValue(Comparable valueToSort) {
-		return cell.setSortValue(valueToSort);
-	}
-
-	public boolean setSortValue(float valueToSort) {
-		return cell.setSortValue(valueToSort);
-	}
-
-	public boolean setSortValue(long valueToSort) {
-		return cell.setSortValue(valueToSort);
-	}
-
-	public boolean setText(String text) {
-		return cell.setText(text);
-	}
-
-	public void setToolTip(Object tooltip) {
-		cell.setToolTip(tooltip);
-	}
-
-	public void setUpToDate(boolean upToDate) {
-		cell.setUpToDate(upToDate);
-	}
-
-	public String toString() {
-		return cell.toString();
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMouseOffset()
-	public int[] getMouseOffset() {
-		return cell.getMouseOffset();
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMarginHeight()
-	public int getMarginHeight() {
-		return cell.getMarginHeight();
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMarginWidth()
-	public int getMarginWidth() {
-		return cell.getMarginWidth();
-	}
-}
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 8d0edf4..7c1a8ed 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/MyTorrentsView_Big.java
@@ -1,25 +1,18 @@
 package com.aelitis.azureus.ui.swt.views.skin;
 
-import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
 
 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.download.DownloadTypeComplete;
+import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
 import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
-import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableRowCore;
-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.download.DownloadTypeComplete;
-import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
 
 public class MyTorrentsView_Big
 	extends MyTorrentsView
@@ -27,75 +20,64 @@ public class MyTorrentsView_Big
 	private final int torrentFilterMode;
 
 	public MyTorrentsView_Big(AzureusCore _azureus_core, int torrentFilterMode,
-			TableColumnCore[] basicItems) {
+			TableColumnCore[] basicItems, Text txtFilter, Composite cCats) {
 		this.torrentFilterMode = torrentFilterMode;
-		init(
-				_azureus_core,
-				SBC_LibraryView.getTableIdFromFilterMode(torrentFilterMode, true),
-				torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE ? false : true,
-				basicItems);
-		//setForceHeaderVisible(true);
-	}
-	
-
-	public boolean isOurDownloadManager(DownloadManager dm) {
-		if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-			return false;
-		}
-		
-		if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
-			if (PlatformTorrentUtils.getHasBeenOpened(dm)) {
-				return false;
-			}
-		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
-			return isInCurrentCategory(dm);
-		}
-		
-		return super.isOurDownloadManager(dm);
-	}
-
-	protected TableViewSWT createTableView(TableColumnCore[] basicItems) {
-		String tableID;
-		Class forDataSourceType;
+		this.txtFilter = txtFilter;
+		this.cCategories = cCats;
+		Class<?> forDataSourceType;
 		switch (torrentFilterMode) {
 			case SBC_LibraryView.TORRENTS_COMPLETE:
-				tableID = TableManager.TABLE_MYTORRENTS_COMPLETE_BIG;
 				forDataSourceType = DownloadTypeComplete.class;
 				break;
 
 			case SBC_LibraryView.TORRENTS_INCOMPLETE:
-				tableID = TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG;
 				forDataSourceType = DownloadTypeIncomplete.class;
 				break;
 				
 			case SBC_LibraryView.TORRENTS_UNOPENED:
-				tableID = TableManager.TABLE_MYTORRENTS_UNOPENED_BIG;
 				forDataSourceType = Download.class;
 				break;
 				
 			case SBC_LibraryView.TORRENTS_ALL:
-				tableID = TableManager.TABLE_MYTORRENTS_ALL_BIG;
 				forDataSourceType = Download.class;
 				break;
 
 			default:
-				tableID = "bad";
 				forDataSourceType = null;
 				break;
 		}
-		TableViewSWTImpl tv = new TableViewSWTImpl(forDataSourceType, tableID,
-				"MyTorrentsView_Big", basicItems, "#", SWT.MULTI | SWT.FULL_SELECTION
-						| SWT.VIRTUAL | SWT.BORDER);
-		return tv;
+		init(
+				_azureus_core,
+				SB_Transfers.getTableIdFromFilterMode(torrentFilterMode, true),
+				torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE ? false : true,
+				forDataSourceType, basicItems);
+		//setForceHeaderVisible(true);
 	}
 	
+
+	public boolean isOurDownloadManager(DownloadManager dm) {
+		if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
+			return false;
+		}
+		
+		if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
+			if (PlatformTorrentUtils.getHasBeenOpened(dm)) {
+				return false;
+			}
+		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
+			return isInCurrentCategory(dm);
+		}
+		
+		return super.isOurDownloadManager(dm);
+	}
+
 	// @see org.gudy.azureus2.ui.swt.views.MyTorrentsView#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void defaultSelected(TableRowCore[] rows, int stateMask) {
 		SBC_LibraryTableView.doDefaultClick(rows, stateMask, !isSeedingView);
 	}
 
 	protected int getRowDefaultHeight() {
-		return 36;
+		return 30;
 	}
-
+	
 }
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 cb9aad0..06e3963 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityTableView.java
@@ -20,6 +20,7 @@ package com.aelitis.azureus.ui.swt.views.skin;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.KeyEvent;
@@ -29,20 +30,39 @@ import org.eclipse.swt.widgets.Composite;
 
 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.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuManager;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
 
 import com.aelitis.azureus.activities.*;
+import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.columns.utils.TableColumnCreatorV3;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUIListener;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectListener;
@@ -54,7 +74,7 @@ import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectListener;
  */
 public class SBC_ActivityTableView
 	extends SkinView
-	implements UIUpdatable, IconBarEnabler, VuzeActivitiesListener
+	implements UIUpdatable, UIPluginViewToolBarListener, VuzeActivitiesListener
 {
 	private static final String TABLE_ID_PREFIX = "activity-";
 
@@ -69,7 +89,6 @@ public class SBC_ActivityTableView
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectInitialShow(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
 
-
 		skinObject.addListener(new SWTSkinObjectListener() {
 			public Object eventOccured(SWTSkinObject skinObject, int eventType,
 					Object params) {
@@ -85,22 +104,24 @@ public class SBC_ActivityTableView
 		});
 
 		SWTSkinObject soParent = skinObject.getParent();
-		
-		Object data = soParent.getControl().getData(
-				"ViewMode");
+
+		Object data = soParent.getControl().getData("ViewMode");
 		if (data instanceof Long) {
-			viewMode  = (int) ((Long) data).longValue();
+			viewMode = (int) ((Long) data).longValue();
 		}
-		
+
 		boolean big = viewMode == SBC_ActivityView.MODE_BIGTABLE;
-		
-		tableID = big ? TableManager.TABLE_ACTIVITY_BIG : TableManager.TABLE_ACTIVITY;
-		TableColumnCore[] columns = big ?  TableColumnCreatorV3.createActivityBig(tableID) : TableColumnCreatorV3.createActivitySmall(tableID);
 
-		view = new TableViewSWTImpl<VuzeActivitiesEntry>(VuzeActivitiesEntry.class,
+		tableID = big ? TableManager.TABLE_ACTIVITY_BIG
+				: TableManager.TABLE_ACTIVITY;
+		TableColumnCore[] columns = big
+				? TableColumnCreatorV3.createActivityBig(tableID)
+				: TableColumnCreatorV3.createActivitySmall(tableID);
+
+		view = TableViewFactory.createTableViewSWT(VuzeActivitiesEntry.class,
 				tableID, tableID, columns, "name", SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.VIRTUAL);
-		
+
 		view.setRowDefaultHeight(big ? 50 : 32);
 
 		view.addKeyListener(new KeyListener() {
@@ -117,10 +138,10 @@ public class SBC_ActivityTableView
 					if ((e.stateMask & SWT.CONTROL) > 0) {
 						System.out.println("pull all vuze news entries");
 						VuzeActivitiesManager.clearLastPullTimes();
-						VuzeActivitiesManager.pullActivitiesNow(0);
+						VuzeActivitiesManager.pullActivitiesNow(0, "^F5", true);
 					} else {
 						System.out.println("pull latest vuze news entries");
-						VuzeActivitiesManager.pullActivitiesNow(0);
+						VuzeActivitiesManager.pullActivitiesNow(0, "F5", true);
 					}
 				}
 			}
@@ -137,11 +158,11 @@ public class SBC_ActivityTableView
 					}
 				}
 			}
-			
+
 			public void defaultSelected(TableRowCore[] rows, int stateMask) {
 				if (rows.length == 1) {
 					TorrentListViewsUtils.playOrStreamDataSource(rows[0].getDataSource(),
-							null);
+							false);
 				}
 			}
 
@@ -149,7 +170,6 @@ public class SBC_ActivityTableView
 				selectionChanged();
 			}
 
-			
 			public void selectionChanged() {
 				Utils.execSWTThread(new AERunnable() {
 					public void runSupport() {
@@ -163,17 +183,16 @@ public class SBC_ActivityTableView
 			}
 
 		}, false);
-		
+
 		view.addLifeCycleListener(new TableLifeCycleListener() {
 			public void tableViewInitialized() {
 				view.addDataSources(VuzeActivitiesManager.getAllEntries());
 			}
-		
+
 			public void tableViewDestroyed() {
 			}
 		});
 
-
 		SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
 				skin.getSkinProperties(), getUpdateUIName(), "", soMain);
 
@@ -192,13 +211,15 @@ public class SBC_ActivityTableView
 		view.initialize(viewComposite);
 
 		VuzeActivitiesManager.addListener(this);
-		
+
 		return null;
 	}
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectDestroyed(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectDestroyed(SWTSkinObject skinObject, Object params) {
-		view.delete();
+		if (view != null) {
+			view.delete();
+		}
 		return super.skinObjectDestroyed(skinObject, params);
 	}
 
@@ -209,24 +230,27 @@ public class SBC_ActivityTableView
 
 	// @see com.aelitis.azureus.ui.common.updater.UIUpdatable#updateUI()
 	public void updateUI() {
-		view.refreshTable(false);
+		if (view != null) {
+			view.refreshTable(false);
+		}
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isEnabled(java.lang.String)
-	public boolean isEnabled(String itemKey) {
-		return false;
+	public void refreshToolBarItems(Map<String, Long> list) {
+		list.put("remove",
+				isVisible() && view != null && view.getSelectedRowsSize() > 0
+						? UIToolBarItem.STATE_ENABLED : 0);
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isSelected(java.lang.String)
-	public boolean isSelected(String itemKey) {
-		return false;
-	}
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if (item.getID().equals("remove")) {
+			removeSelected();
+			return true;
+		}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#itemActivated(java.lang.String)
-	public void itemActivated(String itemKey) {
+		return false;
 	}
 
-
 	public ISelectedContent[] getCurrentlySelectedContent() {
 		if (view == null) {
 			return null;
@@ -253,26 +277,35 @@ public class SBC_ActivityTableView
 
 	// @see com.aelitis.azureus.util.VuzeNewsListener#vuzeNewsEntriesAdded(com.aelitis.azureus.util.VuzeNewsEntry[])
 	public void vuzeNewsEntriesAdded(VuzeActivitiesEntry[] entries) {
-		view.addDataSources(entries);
+		if (view != null) {
+			view.addDataSources(entries);
+		}
 	}
 
 	// @see com.aelitis.azureus.util.VuzeNewsListener#vuzeNewsEntriesRemoved(com.aelitis.azureus.util.VuzeNewsEntry[])
 	public void vuzeNewsEntriesRemoved(VuzeActivitiesEntry[] entries) {
-		view.removeDataSources(entries);
-		view.processDataSourceQueue();
+		if (view != null) {
+			view.removeDataSources(entries);
+			view.processDataSourceQueue();
+		}
 	}
 
 	// @see com.aelitis.azureus.util.VuzeActivitiesListener#vuzeNewsEntryChanged(com.aelitis.azureus.util.VuzeActivitiesEntry)
 	public void vuzeNewsEntryChanged(VuzeActivitiesEntry entry) {
+		if (view == null) {
+			return;
+		}
 		TableRowCore row = view.getRow(entry);
 		if (row != null) {
 			row.invalidate();
 		}
 	}
 
-	private void removeEntries(final VuzeActivitiesEntry[] toRemove, final int startIndex) {
+	private void removeEntries(final VuzeActivitiesEntry[] toRemove,
+			final int startIndex) {
 		final VuzeActivitiesEntry entry = toRemove[startIndex];
-		if (entry == null || VuzeActivitiesConstants.TYPEID_HEADER.equals(entry.getTypeID())) {
+		if (entry == null
+				|| VuzeActivitiesConstants.TYPEID_HEADER.equals(entry.getTypeID())) {
 			int nextIndex = startIndex + 1;
 			if (nextIndex < toRemove.length) {
 				removeEntries(toRemove, nextIndex);
@@ -282,10 +315,9 @@ public class SBC_ActivityTableView
 
 		MessageBoxShell mb = new MessageBoxShell(
 				MessageText.getString("v3.activity.remove.title"),
-				MessageText.getString("v3.activity.remove.text",
-						new String[] {
-							entry.getText()
-						}));
+				MessageText.getString("v3.activity.remove.text", new String[] {
+					entry.getText()
+				}));
 		mb.setRemember(tableID + "-Remove", false,
 				MessageText.getString("MessageBoxWindow.nomoreprompting"));
 
@@ -293,17 +325,24 @@ public class SBC_ActivityTableView
 			mb.setButtons(0, new String[] {
 				MessageText.getString("Button.yes"),
 				MessageText.getString("Button.no"),
-			}, new Integer[] { 0, 1 });
+			}, 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 });
+			}, new Integer[] {
+				2,
+				0,
+				1
+			});
 			mb.setRememberOnlyIfButton(1);
 		}
-		
+
 		mb.setHandleHTML(false);
 		mb.open(new UserPrompterResultListener() {
 			public void prompterClosed(int result) {
@@ -314,7 +353,9 @@ public class SBC_ActivityTableView
 					VuzeActivitiesManager.removeEntries(toGroupRemove);
 					return;
 				} else if (result == 0) {
-					VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] { entry } );
+					VuzeActivitiesManager.removeEntries(new VuzeActivitiesEntry[] {
+						entry
+					});
 				}
 
 				int nextIndex = startIndex + 1;
@@ -326,11 +367,89 @@ public class SBC_ActivityTableView
 	}
 
 	protected void removeSelected() {
-		VuzeActivitiesEntry[] selectedEntries = view.getSelectedDataSources().toArray(new VuzeActivitiesEntry[0]);
+		if (view == null) {
+			return;
+		}
+		VuzeActivitiesEntry[] selectedEntries = view.getSelectedDataSources().toArray(
+				new VuzeActivitiesEntry[0]);
 		removeEntries(selectedEntries, 0);
 	}
-	
+
 	public TableViewSWT getView() {
 		return view;
 	}
+
+	public static void setupSidebarEntry() {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+
+		// Put TitleInfo in another class
+		final ViewTitleInfo titleInfoActivityView = new ViewTitleInfo() {
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == TITLE_INDICATOR_TEXT) {
+					int count = 0;
+					VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
+					for (int i = 0; i < allEntries.length; i++) {
+						VuzeActivitiesEntry entry = allEntries[i];
+						if (!entry.isRead()) {
+							count++;
+						}
+					}
+					if (count > 0) {
+						return "" + count;
+					} else {
+						return null;
+					}
+				} else if (propertyID == TITLE_IMAGEID) {
+					return "image.sidebar.activity";
+				}
+				return null;
+			}
+		};
+		VuzeActivitiesManager.addListener(new VuzeActivitiesListener() {
+			public void vuzeNewsEntryChanged(VuzeActivitiesEntry entry) {
+				ViewTitleInfoManager.refreshTitleInfo(titleInfoActivityView);
+			}
+
+			public void vuzeNewsEntriesRemoved(VuzeActivitiesEntry[] entries) {
+				ViewTitleInfoManager.refreshTitleInfo(titleInfoActivityView);
+			}
+
+			public void vuzeNewsEntriesAdded(VuzeActivitiesEntry[] entries) {
+				ViewTitleInfoManager.refreshTitleInfo(titleInfoActivityView);
+			}
+		});
+
+		mdi.createEntryFromSkinRef(MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+				MultipleDocumentInterface.SIDEBAR_SECTION_ACTIVITIES, "activity",
+				"{sidebar." + MultipleDocumentInterface.SIDEBAR_SECTION_ACTIVITIES
+						+ "}", titleInfoActivityView, null, false, null);
+
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+		UIManager uim = pi.getUIManager();
+		MenuManager menuManager = uim.getMenuManager();
+
+		MenuItem menuItem = menuManager.addMenuItem("sidebar."
+				+ MultipleDocumentInterface.SIDEBAR_SECTION_ACTIVITIES,
+				"v3.activity.button.readall");
+		menuItem.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
+				for (int i = 0; i < allEntries.length; i++) {
+					VuzeActivitiesEntry entry = allEntries[i];
+					entry.setRead(true);
+				}
+			}
+		});
+
+		if (Constants.isCVSVersion()) {
+			menuItem = menuManager.addMenuItem("sidebar."
+					+ MultipleDocumentInterface.SIDEBAR_SECTION_ACTIVITIES,
+					"!test update expiry!");
+			menuItem.addListener(new MenuItemListener() {
+				public void selected(MenuItem menu, Object target) {
+					FeatureManagerUIListener.buildNotifications();
+				}
+			});
+		}
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityView.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityView.java
index 4d16453..e84f81e 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_ActivityView.java
@@ -23,13 +23,14 @@ import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
 import com.aelitis.azureus.activities.VuzeActivitiesManager;
+import com.aelitis.azureus.core.messenger.config.PlatformVuzeActivitiesMessenger;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarItemListener;
 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
-import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 
 /**
  * @author TuxPaper
@@ -115,6 +116,11 @@ public class SBC_ActivityView
 
 		return null;
 	}
+	
+	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
+		VuzeActivitiesManager.pullActivitiesNow(0, "shown", true);
+		return super.skinObjectShown(skinObject, params);
+	}
 
 	public int getViewMode() {
 		return viewMode;
@@ -169,7 +175,8 @@ public class SBC_ActivityView
 		}
 
 		
-		SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_ACTIVITIES);
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_ACTIVITIES);
 		if (entry != null) {
 			entry.setLogID(SideBar.SIDEBAR_SECTION_ACTIVITIES + "-" + viewMode);
 		}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_BurnFTUX.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_BurnFTUX.java
new file mode 100644
index 0000000..59caec6
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_BurnFTUX.java
@@ -0,0 +1,147 @@
+/**
+ * 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 org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBrowser;
+import com.aelitis.azureus.util.ConstantsVuze;
+
+/**
+ * @author TuxPaper
+ * @created Oct 1, 2006
+ *
+ */
+public class SBC_BurnFTUX
+	extends SkinView
+{
+	private SWTSkinObjectBrowser browserSkinObject;
+
+	private String url;
+
+	private static String sRef = "user";
+
+	private String entryID;
+
+	private MdiEntry entry;
+
+	private static boolean DEBUG = Constants.IS_CVS_VERSION;
+
+	public Object skinObjectInitialShow(final SWTSkinObject skinObject,
+			Object params) {
+
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			entry = mdi.getEntryFromSkinObject(skinObject);
+			if (entry != null) {
+				entryID = entry.getId();
+			}
+		}
+
+		browserSkinObject = (SWTSkinObjectBrowser) skin.getSkinObject("browser",
+				soMain);
+
+		browserSkinObject.addListener(new loadingListener() {
+
+			public void browserLoadingChanged(boolean loading, String url) {
+				if (!loading) {
+					skinObject.getControl().getParent().layout(true, true);
+				}
+			}
+		});
+
+		if (DEBUG) {
+			System.out.println("BurnFTUX sourceRef is now " + sRef);
+		}
+
+		return null;
+	}
+	
+	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
+		super.skinObjectShown(skinObject, params);
+		buildURL(true);
+		return null;
+	}
+	
+	public Object skinObjectHidden(SWTSkinObject skinObject, Object params) {
+		if (browserSkinObject != null) {
+			browserSkinObject.setURL("about:blank");
+		}
+		sRef = "user";
+		if (DEBUG) {
+			System.out.println("BurnFTUX sourceRef is now " + sRef);
+		}
+		return super.skinObjectHidden(skinObject, params);
+	}
+
+	/**
+	 * @param hasFullLicence
+	 */
+	public void updateLicenceInfo() {
+		buildURL(false);
+	}
+
+	private void buildURL(boolean forceSet) {
+		String suffix = ("?view=" + entryID)
+				+ ("&sourceRef=" + UrlUtils.encode(sRef + "-/plus/ftux/dvd"));
+		String newUrl = ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL(
+				"burn_ftux.start" + suffix, false);
+		newUrl = FeatureManagerUI.appendFeatureManagerURLParams(newUrl);
+		if (!forceSet && newUrl.equals(url)) {
+			return;
+		}
+		
+		url = newUrl;
+
+		if (DEBUG) {
+			System.out.println("URL is now " + url + " via " + Debug.getCompressedStackTrace());
+		}
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		MdiEntry currentEntry = mdi.getCurrentEntry();
+
+		if (browserSkinObject != null && (forceSet || entry == currentEntry)) {
+			browserSkinObject.setURL(url);
+		}
+	}
+
+	public static void setSourceRef(String _sRef) {
+		sRef = _sRef;
+		if (DEBUG) {
+			System.out.println("BurnFTUX sourceRef is now " + sRef);
+		}
+
+		SkinView[] views = SkinViewManager.getMultiByClass(SBC_BurnFTUX.class);
+		if (views != null) {
+			for (SkinView bview : views) {
+				((SBC_BurnFTUX) bview).buildURL(false);
+			}
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_GenericBrowsePage.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_GenericBrowsePage.java
new file mode 100644
index 0000000..f69fcce
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_GenericBrowsePage.java
@@ -0,0 +1,107 @@
+/**
+ * Created on Sep 13, 2010
+ *
+ * Copyright 2010 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.views.skin;
+
+import org.gudy.azureus2.core3.util.SystemTime;
+
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
+import com.aelitis.azureus.ui.mdi.MdiListener;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserContext;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.skin.*;
+
+/**
+ * @author TuxPaper
+ * @created Sep 13, 2010
+ *
+ */
+public class SBC_GenericBrowsePage
+extends SkinView
+{
+	private SWTSkinObjectBrowser browserSkinObject;
+	private MdiEntryVitalityImage vitalityImage;
+	private MdiEntry entry;
+
+	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
+		Object creationParams = skinObject.getData("CreationParams");
+
+		browserSkinObject = SWTSkinUtils.findBrowserSO(soMain);
+
+		final MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			entry = mdi.getEntryBySkinView(this);
+			if (entry != null) {
+				vitalityImage = entry.addVitalityImage("image.sidebar.vitality.dots");
+				vitalityImage.setVisible(false);
+
+				mdi.addListener(new MdiListener() {
+					long lastSelect = 0;
+
+					public void mdiEntrySelected(MdiEntry newEntry,
+							MdiEntry oldEntry) {
+						if (entry == newEntry) {
+							if (entry == oldEntry) {
+								if (lastSelect < SystemTime.getOffsetTime(-1000)) {
+									if (browserSkinObject != null) {
+										browserSkinObject.restart();
+									}
+								}
+							} else {
+								lastSelect = SystemTime.getCurrentTime();
+							}
+						}
+					}
+				});
+			}
+		}
+
+		browserSkinObject.addListener(new SWTSkinObjectListener() {
+		
+			public Object eventOccured(SWTSkinObject skinObject, int eventType,
+					Object params) {
+				if (eventType == EVENT_SHOW) {
+					browserSkinObject.removeListener(this);
+
+					browserSkinObject.addListener(new BrowserContext.loadingListener() {
+						public void browserLoadingChanged(boolean loading, String url) {
+							if (vitalityImage != null) {
+								vitalityImage.setVisible(loading);
+							}
+						}
+					});
+				}
+				return null;
+			}
+		});
+
+		openURL();
+
+		return null;
+	}
+
+	private void openURL() {
+		
+		Object o = entry.getDatasource();
+		if (o instanceof String) {
+			browserSkinObject.setURL((String) o);
+		}
+	}
+}
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 72ea0a2..362b86b 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView.java
@@ -18,54 +18,57 @@
 
 package com.aelitis.azureus.ui.swt.views.skin;
 
-import java.util.Iterator;
-import java.util.List;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
 
 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.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 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.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
 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.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 import org.gudy.azureus2.ui.swt.views.MyTorrentsSuperView;
 import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
 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.impl.TableViewTab;
 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.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;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableRowCore;
 import com.aelitis.azureus.ui.common.table.TableSelectionAdapter;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 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.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedVuzeFileContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 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;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
-import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectTextbox;
 import com.aelitis.azureus.util.DLReferals;
 import com.aelitis.azureus.util.DataSourceUtils;
 import com.aelitis.azureus.util.PlayUtils;
@@ -79,19 +82,23 @@ import com.aelitis.azureus.util.PlayUtils;
  */
 public class SBC_LibraryTableView
 	extends SkinView
-	implements UIUpdatable, IconBarEnabler
+	implements UIUpdatable, ObfusticateImage, UIPluginViewToolBarListener
 {
 	private final static String ID = "SBC_LibraryTableView";
 
-	private IView view;
-
 	private Composite viewComposite;
 	
-	private TableViewSWT tv;
+	private TableViewSWT<?> tv;
 
 	protected int torrentFilterMode = SBC_LibraryView.TORRENTS_ALL;
 
 	private SWTSkinObject soParent;
+
+	private MyTorrentsView torrentView;
+	
+	private UISWTViewEventListener swtViewListener;
+
+	private UISWTViewImpl view;
 	
 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
 		soParent = skinObject.getParent();
@@ -100,13 +107,15 @@ public class SBC_LibraryTableView
 			public void azureusCoreRunning(final AzureusCore core) {
 				Utils.execSWTThread(new AERunnable() {
 					public void runSupport() {
+						if (soParent == null || soParent.isDisposed()) {
+							return;
+						}
 						initShow(core);
 					}
 				});
 			}
   	});
 
-
 		return null;
 	}
 
@@ -115,10 +124,23 @@ public class SBC_LibraryTableView
 		if (data instanceof Long) {
 			torrentFilterMode = (int) ((Long) data).longValue();
 		}
+		
+		data = soParent.getControl().getData("DataSource");
+		
 		boolean useBigTable = useBigTable();
+		
+		SWTSkinObjectTextbox soFilter = (SWTSkinObjectTextbox) skin.getSkinObject(
+				"library-filter", soParent.getParent());
+		Text txtFilter = soFilter == null ? null : soFilter.getTextControl();
+		
+		SWTSkinObjectContainer soCats = (SWTSkinObjectContainer) skin.getSkinObject(
+				"library-categories", soParent.getParent());
+		Composite cCats = soCats == null ? null : soCats.getComposite();
 
 		// columns not needed for small mode, all torrents
-		TableColumnCore[] columns = useBigTable || torrentFilterMode != SBC_LibraryView.TORRENTS_ALL ? getColumns() : null;
+		TableColumnCore[] columns = useBigTable
+				|| torrentFilterMode != SBC_LibraryView.TORRENTS_ALL ? getColumns()
+				: null;
 
 		if (null != columns) {
 			TableColumnManager tcManager = TableColumnManager.getInstance();
@@ -130,24 +152,28 @@ public class SBC_LibraryTableView
 					|| torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE
 					|| torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
 
-				view = new MyTorrentsView_Big(core, torrentFilterMode, columns);
+				swtViewListener = torrentView = new MyTorrentsView_Big(core, torrentFilterMode,
+						columns, txtFilter, cCats);
 
 			} else {
-				//view = new MyTorrentsSuperView_Big();
-				view = new MyTorrentsView_Big(core, torrentFilterMode, columns);
+				swtViewListener = torrentView = new MyTorrentsView_Big(core, torrentFilterMode,
+						columns, txtFilter, cCats);
 			}
 
 		} else {
-			String tableID = SBC_LibraryView.getTableIdFromFilterMode(
+			String tableID = SB_Transfers.getTableIdFromFilterMode(
 					torrentFilterMode, false);
 			if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE) {
-				view = new MyTorrentsView(core, tableID, true, columns);
+				swtViewListener = torrentView = new MyTorrentsView(core, tableID, true, columns, txtFilter,
+						cCats);
 
 			} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE) {
-				view = new MyTorrentsView(core, tableID, false, columns);
+				swtViewListener = torrentView = new MyTorrentsView(core, tableID, false, columns, txtFilter,
+						cCats);
 
 			} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
-				view = new MyTorrentsView(core, tableID, true, columns) {
+				swtViewListener = torrentView = new MyTorrentsView(core, tableID, true, columns, txtFilter,
+						cCats) {
 					public boolean isOurDownloadManager(DownloadManager dm) {
 						if (PlatformTorrentUtils.getHasBeenOpened(dm)) {
 							return false;
@@ -156,7 +182,7 @@ public class SBC_LibraryTableView
 					}
 				};
 			} else {
-				view = new MyTorrentsSuperView() {
+				swtViewListener = new MyTorrentsSuperView(txtFilter, cCats) {
 					public void initializeDone() {
 						MyTorrentsView seedingview = getSeedingview();
 						if (seedingview != null) {
@@ -178,8 +204,8 @@ public class SBC_LibraryTableView
 				};
 			}
 			
-			if (view instanceof MyTorrentsView) {
-				((MyTorrentsView) view).overrideDefaultSelected(new TableSelectionAdapter() {
+			if (torrentView != null) {
+				torrentView.overrideDefaultSelected(new TableSelectionAdapter() {
 					public void defaultSelected(TableRowCore[] rows, int stateMask) {
 						doDefaultClick(rows, stateMask, false);
 					}
@@ -187,16 +213,25 @@ public class SBC_LibraryTableView
 			}
 		}
 
+		if (torrentView != null) {
+			tv = torrentView.getTableView();
+			if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
+				torrentView.setRebuildListOnFocusGain(true);
+			}
+		}
+
+		try {
+			view = new UISWTViewImpl(UISWTInstance.VIEW_MAIN, ID + torrentFilterMode, swtViewListener, data);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+
 		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;
@@ -205,15 +240,6 @@ public class SBC_LibraryTableView
 		view.initialize(viewComposite);
 
 
-		if (tv == null) {
-			if (view instanceof TableViewTab) {
-				TableViewTab tvt = (TableViewTab) view;
-				tv = tvt.getTableView();
-			} else if (view instanceof TableViewSWT) {
-				tv = (TableViewSWT) view;
-			}
-		}
-		
 		SWTSkinObject soSizeSlider = skin.getSkinObject("table-size-slider", soParent.getParent());
 		if (soSizeSlider instanceof SWTSkinObjectContainer) {
 			SWTSkinObjectContainer so = (SWTSkinObjectContainer) soSizeSlider;
@@ -228,92 +254,38 @@ public class SBC_LibraryTableView
 			tv.addRefreshListener(new TableRowRefreshListener() {
 				public void rowRefresh(TableRow row) {
 					TableRowSWT rowCore = (TableRowSWT)row;
-					DownloadManager dm = (DownloadManager) rowCore.getDataSource(true);
+					Object ds = rowCore.getDataSource(true);
+					if (!(ds instanceof DownloadManager)) {
+						return;
+					}
+					DownloadManager dm = (DownloadManager) ds;
 					boolean changed = false;
 					boolean assumedComplete = dm.getAssumedComplete();
 					if (!assumedComplete) {
 						changed |= rowCore.setAlpha(160);
-						changed |= rowCore.setFontStyle(SWT.NORMAL);
 					} else if (!PlatformTorrentUtils.getHasBeenOpened(dm)) {
 						changed |= rowCore.setAlpha(255);
-						changed |= rowCore.setFontStyle(SWT.BOLD);
 					} else {
 						changed |= rowCore.setAlpha(255);
-						changed |= rowCore.setFontStyle(SWT.NORMAL);
 					}
 				}
 			});
 		}
 		
-		if (tv != null) {
-			tv.addKeyListener(new KeyListener() {
-
-				public void keyReleased(KeyEvent e) {
-				}
-
-				public void keyPressed(KeyEvent e) {
-					if (e.character == 15 && 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) {
-								TOTorrent torrent = dm.getTorrent();
-								String contentHash = PlatformTorrentUtils.getContentHash(torrent);
-								if (contentHash != null && contentHash.length() > 0) {
-									ContentNetwork cn = DataSourceUtils.getContentNetwork(torrent);
-									if (cn == null) {
-										new MessageBoxShell(SWT.OK, "coq",
-												"Not in Content Network List").open(null);
-										return;
-									}
-									String url = cn.getTorrentDownloadService(contentHash, "coq");
-									DownloadUrlInfo dlInfo = new DownloadUrlInfoContentNetwork(
-											url, cn);
-									TorrentUIUtilsV3.loadTorrent(dlInfo, false, false,
-											true, false);
-								}
-
-							}
-						}
-					}
-				}
-			});
-		}
-
-		if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
-			SWTSkinObject so = skin.getSkinObject("library-list-button-right",
-					soParent.getParent());
-			if (so != null) {
-				so.setVisible(true);
-				SWTSkinButtonUtility btn = new SWTSkinButtonUtility(so);
-				btn.setTextID("Mark All UnNew");
-				btn.addSelectionListener(new SWTSkinButtonUtility.ButtonListenerAdapter() {
-					public void pressed(SWTSkinButtonUtility buttonUtility,
-							SWTSkinObject skinObject, int stateMask) {
-						TableViewSWT tv = ((MyTorrentsView) view).getTableView();
-						Object[] dataSources = tv.getDataSources().toArray();
-						for (int i = 0; i < dataSources.length; i++) {
-							Object ds = dataSources[i];
-							if (ds instanceof DownloadManager) {
-								PlatformTorrentUtils.setHasBeenOpened((DownloadManager) ds,
-										true);
-								// give user visual indication right away 
-								tv.removeDataSource(ds);
-							}
-						}
-					}
-				});
-			}
-		}
 		viewComposite.getParent().layout(true);
 	}
 
-	public static void doDefaultClick(TableRowCore[] rows, int stateMask,
-			boolean neverPlay) {
+	public static void 
+	doDefaultClick(
+		final TableRowCore[] 	rows, 
+		final int 				stateMask,
+		final boolean 			neverPlay) 
+	{
 		if (rows == null || rows.length != 1) {
 			return;
 		}
-		Object ds = rows[0].getDataSource(true);
+		
+		final Object ds = rows[0].getDataSource(true);
 
 		String mode = COConfigurationManager.getStringParameter("list.dm.dblclick");
 		if (mode.equals("1")) {
@@ -322,14 +294,41 @@ public class SBC_LibraryTableView
 			if (dm != null) {
 				UIFunctionsManager.getUIFunctions().openView(UIFunctions.VIEW_DM_DETAILS, dm);
 				return;
+			}else{
+				DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
+				if (file != null) {
+					UIFunctionsManager.getUIFunctions().openView(UIFunctions.VIEW_DM_DETAILS, file.getDownloadManager());
+					return;
+				}
 			}
-		} else if (mode.equals("2")) {
+		}else if (mode.equals("2")) {
 			// Show in explorer
 			DownloadManager dm = DataSourceUtils.getDM(ds);
 			if (dm != null) {
-  			boolean openMode = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
-  			ManagerUtils.open(dm, openMode);
-  			return;
+				boolean openMode = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
+				ManagerUtils.open(dm, openMode);
+				return;
+			}else{
+				DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
+				if (file != null) {
+					boolean openMode = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
+					ManagerUtils.open(file, openMode);
+					return;
+				}
+			}
+		}else if (mode.equals("3")) {
+			// Launch
+			DownloadManager dm = DataSourceUtils.getDM(ds);
+			if (dm != null) {
+				TorrentUtil.runDataSources(new Object[]{ dm });
+				PlatformTorrentUtils.setHasBeenOpened(dm, true);
+				return;
+			}else{
+				DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
+				if (file != null) {
+					TorrentUtil.runDataSources(new Object[]{ file });
+					return;
+				}
 			}
 		}
 		
@@ -337,10 +336,16 @@ public class SBC_LibraryTableView
 			return;
 		}
 		
-		// fallback
-		if (PlayUtils.canPlayDS(ds) || (stateMask & SWT.CONTROL) > 0) {
-			TorrentListViewsUtils.playOrStreamDataSource(ds, null,
-					DLReferals.DL_REFERAL_DBLCLICK);
+			// fallback
+		
+		if (PlayUtils.canPlayDS(ds, -1) || (stateMask & SWT.CONTROL) > 0) {
+			TorrentListViewsUtils.playOrStreamDataSource(ds,
+					DLReferals.DL_REFERAL_DBLCLICK, false, true );
+		}
+
+		if (PlayUtils.canStreamDS(ds, -1)) {
+			TorrentListViewsUtils.playOrStreamDataSource(ds,
+					DLReferals.DL_REFERAL_DBLCLICK, true, false );
 		}
 	}
 
@@ -355,81 +360,64 @@ public class SBC_LibraryTableView
 				|| !viewComposite.isVisible() || view == null) {
 			return;
 		}
-		view.refresh();
+		view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
 	}
 
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectShown(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
 		super.skinObjectShown(skinObject, params);
 
-		if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED
-				&& AzureusCoreFactory.isCoreRunning()) {
-			if (view instanceof MyTorrentsView) {
-				MyTorrentsView torrentsView = (MyTorrentsView) view;
-				TableViewSWT tv = torrentsView.getTableView();
-				List dms = AzureusCoreFactory.getSingleton().getGlobalManager().getDownloadManagers();
-				for (Iterator iter = dms.iterator(); iter.hasNext();) {
-					DownloadManager dm = (DownloadManager) iter.next();
-
-					if (!torrentsView.isOurDownloadManager(dm)) {
-						tv.removeDataSource(dm);
-					} else {
-						tv.addDataSource(dm);
-					}
-				}
-			}
-		}
-
-		if (view instanceof MyTorrentsView) {
-			((MyTorrentsView)view).updateSelectedContent();
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
 		}
 		
-		updateUI();
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			
+			public void runSupport() {
+				updateUI();
+			}
+		});
 
 		return null;
 	}
 	
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectHidden(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectHidden(SWTSkinObject skinObject, Object params) {
-		if (view instanceof MyTorrentsView) {
-			((MyTorrentsView)view).updateSelectedContent();
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
 		}
+
 		return super.skinObjectHidden(skinObject, params);
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isEnabled(java.lang.String)
-	public boolean isEnabled(String itemKey) {
-		try {
-			if (view != null) {
-				return view.isEnabled(itemKey);
-			}
-		} catch (Throwable t) {
-			Debug.out(t);
+	public void refreshToolBarItems(Map<String, Long> list) {
+		if (view != null) {
+			view.refreshToolBarItems(list);
 		}
-		return false;
-	}
-
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isSelected(java.lang.String)
-	public boolean isSelected(String itemKey) {
-		try {
-			if (view != null) {
-				return view.isSelected(itemKey);
-			}
-		} catch (Throwable t) {
-			Debug.out(t);
+		if (tv == null) {
+			return;
 		}
-		return false;
+		ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
+		boolean has1Selection = currentContent.length == 1;
+		list.put(
+				"play",
+				has1Selection
+						&& (!(currentContent[0] instanceof ISelectedVuzeFileContent))
+						&& PlayUtils.canPlayDS(currentContent[0],
+								currentContent[0].getFileIndex())
+						? UIToolBarItem.STATE_ENABLED : 0);
+		list.put(
+				"stream",
+				has1Selection
+						&& (!(currentContent[0] instanceof ISelectedVuzeFileContent))
+						&& PlayUtils.canStreamDS(currentContent[0],
+								currentContent[0].getFileIndex())
+						? UIToolBarItem.STATE_ENABLED : 0);
 	}
 
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#itemActivated(java.lang.String)
-	public void itemActivated(String itemKey) {
-		try {
-			if (view != null) {
-				view.itemActivated(itemKey);
-			}
-		} catch (Throwable t) {
-			Debug.out(t);
-		}
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
+		// currently stream and play are handled by ToolbarView..
+		return false;
 	}
 
 	/**
@@ -473,8 +461,17 @@ public class SBC_LibraryTableView
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectDestroyed(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectDestroyed(SWTSkinObject skinObject, Object params) {
 		if (view != null) {
-			view.delete();
+  		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
 		}
 		return super.skinObjectDestroyed(skinObject, params);
 	}
+	
+	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateImage#obfusticatedImage(org.eclipse.swt.graphics.Image, org.eclipse.swt.graphics.Point)
+	public Image obfusticatedImage(Image image) {
+		if (view instanceof ObfusticateImage) {
+			ObfusticateImage oi = (ObfusticateImage) view;
+			return oi.obfusticatedImage(image);
+		}
+		return image;
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView_Big.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView_Big.java
index 4f14690..4f58209 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView_Big.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryTableView_Big.java
@@ -34,6 +34,7 @@ public class SBC_LibraryTableView_Big
 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
 			columns = TableColumnCreatorV3.createUnopenedDM(
 					TableManager.TABLE_MYTORRENTS_UNOPENED_BIG, true);
+
 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
 			columns = TableColumnCreatorV3.createAllDM(
 					TableManager.TABLE_MYTORRENTS_ALL_BIG, true);
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 86fcafb..009aba5 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_LibraryView.java
@@ -18,48 +18,44 @@
 
 package com.aelitis.azureus.ui.swt.views.skin;
 
-import java.util.Iterator;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.eclipse.swt.events.PaintEvent;
 import org.eclipse.swt.events.PaintListener;
 import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 
+import org.gudy.azureus2.core3.category.Category;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.download.DownloadManagerListener;
-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.global.GlobalManagerStats;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
+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.PluginInterface;
+import org.gudy.azureus2.plugins.ui.*;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.views.ViewUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
 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;
-import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.InitializerListener;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 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.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;
 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.SideBarVitalityImageSWT;
 
 /**
  * @author TuxPaper
@@ -67,7 +63,7 @@ import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarVitalityImageSWT;
  *
  */
 public class SBC_LibraryView
-	extends SkinView
+	extends SkinView implements UIPluginViewToolBarListener
 {
 	private final static String ID = "library-list";
 
@@ -82,7 +78,7 @@ public class SBC_LibraryView
 	public static final int TORRENTS_INCOMPLETE = 2;
 
 	public static final int TORRENTS_UNOPENED = 3;
-	
+
 	private final static String[] modeViewIDs = {
 		SkinConstants.VIEWID_SIDEBAR_LIBRARY_BIG,
 		SkinConstants.VIEWID_SIDEBAR_LIBRARY_SMALL
@@ -93,58 +89,91 @@ public class SBC_LibraryView
 		"library.table.small"
 	};
 
-	private static final String ID_VITALITY_ACTIVE = "image.sidebar.vitality.dl";
+	private int viewMode = -1;
 
-	private static final String ID_VITALITY_ALERT = "image.sidebar.vitality.alert";
+	private SWTSkinButtonUtility btnSmallTable;
 
-	private static final long DL_VITALITY_REFRESH_RATE = 15000;
+	private SWTSkinButtonUtility btnBigTable;
 
-	private static final boolean DL_VITALITY_CONSTANT = true;
+	private SWTSkinObject soListArea;
 
-	private static int numSeeding = 0;
+	private int torrentFilterMode = TORRENTS_ALL;
 
-	private static int numDownloading = 0;
+	private String torrentFilter;
 
-	private static int numComplete = 0;
+	private SWTSkinObject soWait;
 
-	private static int numIncomplete = 0;
+	private SWTSkinObject soWaitProgress;
 
-	private static int numErrorComplete = 0;
+	private SWTSkinObjectText soWaitTask;
 
-	private static String errorInCompleteTooltip;
+	private int waitProgress = 0;
 
-	private static int numErrorInComplete = 0;
+	private SWTSkinObjectText soLibraryInfo;
 
-	private static String errorCompleteTooltip;
+	private Object datasource;
 
-	private static int numUnOpened = 0;
+	public void setViewMode(int viewMode, boolean save) {
+		if (viewMode >= modeViewIDs.length || viewMode < 0
+				|| viewMode == this.viewMode) {
+			return;
+		}
 
-	private int viewMode = -1;
+		int oldViewMode = this.viewMode;
 
-	private SWTSkinButtonUtility btnSmallTable;
+		this.viewMode = viewMode;
 
-	private SWTSkinButtonUtility btnBigTable;
+		if (oldViewMode >= 0 && oldViewMode < modeViewIDs.length) {
+			SWTSkinObject soOldViewArea = getSkinObject(modeViewIDs[oldViewMode]);
+			//SWTSkinObject soOldViewArea = skin.getSkinObjectByID(modeIDs[oldViewMode]);
+			if (soOldViewArea != null) {
+				soOldViewArea.setVisible(false);
+			}
+		}
 
-	private SWTSkinObject soListArea;
+		SelectedContentManager.clearCurrentlySelectedContent();
 
-	private int torrentFilterMode = TORRENTS_ALL;
+		SWTSkinObject soViewArea = getSkinObject(modeViewIDs[viewMode]);
+		if (soViewArea == null) {
+			soViewArea = skin.createSkinObject(modeIDs[viewMode] + torrentFilterMode,
+					modeIDs[viewMode], soListArea);
+			soViewArea.getControl().setData( "SBC_LibraryView:ViewMode", viewMode );
+			skin.layout();
+			soViewArea.setVisible(true);
+			soViewArea.getControl().setLayoutData(Utils.getFilledFormData());
+		} else {
+			soViewArea.setVisible(true);
+		}
 
-	private String torrentFilter;
+		if (save) {
+			COConfigurationManager.setParameter(torrentFilter + ".viewmode", viewMode);
+		}
 
-	private ToolBarItem itemModeSmall;
+		String entryID = null;
+		if (torrentFilterMode == TORRENTS_ALL) {
+			entryID = SideBar.SIDEBAR_SECTION_LIBRARY;
+		} else if (torrentFilterMode == TORRENTS_COMPLETE) {
+			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_CD;
+		} else if (torrentFilterMode == TORRENTS_INCOMPLETE) {
+			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_DL;
+		} else if (torrentFilterMode == TORRENTS_UNOPENED) {
+			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED;
+		}
 
-	private ToolBarItem itemModeBig;
+		if (entryID != null) {
+			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+			MdiEntry entry = mdi.getEntry(entryID);
+			if (entry != null) {
+				entry.setLogID(entryID + "-" + viewMode);
+			}
+		}
+
+		SB_Transfers.triggerCountRefreshListeners();
+	}
 
-	private SWTSkinObject soWait;
-	
-	private SWTSkinObject soWaitProgress;
-	
-	private SWTSkinObjectText soWaitTask;
-	
-	private int waitProgress = 0;
 
 	// @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) {
+	public Object skinObjectInitialShow(final SWTSkinObject skinObject, Object params) {
 		soWait = null;
 		try {
 			soWait = getSkinObject("library-wait");
@@ -163,13 +192,230 @@ public class SBC_LibraryView
 					}
 				});
 			}
+
+			soLibraryInfo = (SWTSkinObjectText) getSkinObject("library-info");
+			
+			if (soLibraryInfo != null) {
+
+				SB_Transfers.addCountRefreshListener(
+					new SB_Transfers.countRefreshListener() 
+					{						
+						final Map<Composite,ExtraInfoProvider>	extra_info_map = new HashMap<Composite,ExtraInfoProvider>();
+						
+						{
+							soLibraryInfo.getControl().getParent().setData( "ViewUtils:ViewTitleExtraInfo", 
+									new ViewUtils.ViewTitleExtraInfo()
+									{
+										public void
+										update(
+											Composite	reporter,
+											boolean		seeding_view,
+											int			count,
+											int			active )
+										{
+											ExtraInfoProvider	provider = getProvider( reporter );
+											
+											if ( provider == null ){
+												
+												return;
+											}
+																																	
+											if ( provider.value != count || provider.active != active ){
+											
+												provider.value 	= count;
+												provider.active	= active;
+												
+												if ( viewMode == provider.view_mode && provider.enabled ){
+												
+													SB_Transfers.triggerCountRefreshListeners();
+												}
+											}
+										}
+											
+										public void
+										setEnabled(
+											Composite	reporter,
+											boolean		seeding_view,
+											boolean		enabled )
+										{
+											ExtraInfoProvider	provider = getProvider( reporter );
+											
+											if ( provider == null ){
+												
+												return;
+											}	
+											
+											if ( provider.enabled != enabled ){
+
+												provider.enabled = enabled;
+												
+												if ( viewMode == provider.view_mode ){
+												
+													SB_Transfers.triggerCountRefreshListeners();
+												}
+											}
+										}
+										
+										private ExtraInfoProvider
+										getProvider(
+											Composite	reporter )
+										{
+											synchronized( extra_info_map ){
+												
+												ExtraInfoProvider provider = extra_info_map.get( reporter );
+												
+												if ( provider != null ){
+													
+													return( provider );
+												}
+													
+												Composite temp = reporter;
+												
+												while( temp != null ){
+												
+													Integer vm = (Integer)temp.getData( "SBC_LibraryView:ViewMode" );
+													
+													if ( vm != null ){
+														
+														provider = new ExtraInfoProvider( vm );
+														
+														extra_info_map.put( reporter, provider );
+														
+														return( provider );
+													}
+													
+													temp = temp.getParent();
+												}
+												
+												Debug.out( "No view mode found for " + reporter );
+												
+												return( null );
+											}
+										}
+									});
+						}
+						
+						// @see com.aelitis.azureus.ui.swt.views.skin.SBC_LibraryView.countRefreshListener#countRefreshed(com.aelitis.azureus.ui.swt.views.skin.SBC_LibraryView.stats, com.aelitis.azureus.ui.swt.views.skin.SBC_LibraryView.stats)
+						public void 
+						countRefreshed(
+								SB_Transfers.stats statsWithLowNoise,
+								SB_Transfers.stats statsNoLowNoise) 
+						{
+							SB_Transfers.stats stats = viewMode == MODE_SMALLTABLE? statsWithLowNoise : statsNoLowNoise;
+							
+							String s;
+							
+							if (torrentFilterMode == TORRENTS_INCOMPLETE) {
+								String id = "library.incomplete.header";
+								if (stats.numDownloading != 1) {
+									id += ".p";
+								}
+								s = MessageText.getString(id,
+										new String[] {
+										String.valueOf(stats.numDownloading),
+										String.valueOf(stats.numIncomplete - stats.numDownloading),
+								});
+								
+							} else if (torrentFilterMode == TORRENTS_ALL) {
+								if (datasource instanceof Category) {
+									Category cat = (Category) datasource;
+
+									String id = "library.category.header";
+									
+									s = MessageText.getString(id,
+											new String[] {
+											(cat.getType() != Category.TYPE_USER)
+													? MessageText.getString(cat.getName())
+													: cat.getName()
+									});
+									
+
+								} else {
+									String id = "library.all.header";
+									if (stats.numComplete + stats.numIncomplete != 1) {
+										id += ".p";
+									}
+									s = MessageText.getString(id,
+											new String[] {
+											String.valueOf(stats.numComplete + stats.numIncomplete),
+											String.valueOf(stats.numSeeding + stats.numDownloading),
+									});
+									
+								}
+							} else if (torrentFilterMode == TORRENTS_UNOPENED) {
+								String id = "library.unopened.header";
+								if (stats.numUnOpened != 1) {
+									id += ".p";
+								}
+								s = MessageText.getString(id,
+										new String[] {
+										String.valueOf(stats.numUnOpened),
+								});
+							}else{
+								
+								s = "";
+							}
+							
+							synchronized( extra_info_map ){
+								
+								int		filter_total 	= 0;
+								int		filter_active	= 0;
+								
+								boolean	filter_enabled 	= false;
+
+								for ( ExtraInfoProvider provider: extra_info_map.values()){
+									
+									if ( viewMode == provider.view_mode ){
+							
+										if ( provider.enabled ){
+												
+											filter_enabled = true;
+											filter_total	+= provider.value;
+											filter_active	+= provider.active;
+										}
+									}
+								}
+								
+								if ( filter_enabled ){
+									
+									String extra = 
+										MessageText.getString(
+												"filter.header.matches2",
+												new String[]{ String.valueOf( filter_total ), String.valueOf( filter_active )});
+									
+									s += " " + extra;
+								}
+							}
+							
+							soLibraryInfo.setText(s);
+						}
+						
+						class
+						ExtraInfoProvider
+						{	
+							int			view_mode;
+							boolean		enabled;
+							int			value;
+							int			active;
+							
+							private
+							ExtraInfoProvider(
+								int	vm )
+							{
+								view_mode	= vm;
+							}
+						}
+					});
+				
+			}
 		} catch (Exception e) {
 		}
 
-		AzureusCore core = AzureusCoreFactory.getSingleton();
+		//AzureusCore core = AzureusCoreFactory.getSingleton();
 		if (!AzureusCoreFactory.isCoreRunning()) {
 			if (soWait != null) {
 				soWait.setVisible(true);
+				//soWait.getControl().getParent().getParent().getParent().layout(true, true);
 			}
 			final Initializer initializer = Initializer.getLastInitializer();
 			if (initializer != null) {
@@ -188,7 +434,7 @@ public class SBC_LibraryView
 							initializer.removeListener(this);
 						}
 					}
-				
+
 					public void reportCurrentTask(String currentTask) {
 						if (soWaitTask != null && !soWaitTask.isDisposed()) {
 							soWaitTask.setText(currentTask);
@@ -197,19 +443,38 @@ public class SBC_LibraryView
 				});
 			}
 		}
-		
-  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(final AzureusCore core) {
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						if (soWait != null) {
-							soWait.setVisible(false);
+				PluginInterface pi = PluginInitializer.getDefaultInterface();
+				final UIManager uim = pi.getUIManager();
+				uim.addUIListener(new UIManagerListener() {
+					public void UIDetached(UIInstance instance) {
+					}
+
+					public void UIAttached(UIInstance instance) {
+						if (instance instanceof UISWTInstance) {
+							uim.removeUIListener(this);
+							Utils.execSWTThread(new AERunnable() {
+								public void runSupport() {
+									if (soWait != null) {
+										soWait.setVisible(false);
+									}
+									setupView(core, skinObject);
+								}
+							});
 						}
 					}
 				});
 			}
-  	});
+		});
+
+		return null;
+	}
+	
+	
 
+	protected void setupView(AzureusCore core, SWTSkinObject skinObject) {
 		torrentFilter = skinObject.getSkinObjectID();
 		if (torrentFilter.equalsIgnoreCase(SideBar.SIDEBAR_SECTION_LIBRARY_DL)) {
 			torrentFilterMode = TORRENTS_INCOMPLETE;
@@ -223,9 +488,11 @@ public class SBC_LibraryView
 
 		soListArea.getControl().setData("TorrentFilterMode",
 				new Long(torrentFilterMode));
+		soListArea.getControl().setData("DataSource", datasource);
 
-		setViewMode(COConfigurationManager.getIntParameter(torrentFilter
-				+ ".viewmode"), false);
+		setViewMode(
+				COConfigurationManager.getIntParameter(torrentFilter + ".viewmode"),
+				false);
 
 		SWTSkinObject so;
 		so = getSkinObject(ID + "-button-smalltable");
@@ -248,556 +515,91 @@ public class SBC_LibraryView
 					setViewMode(MODE_BIGTABLE, true);
 				}
 			});
-		}
+		} 
 		
-		SkinViewManager.addListener(new SkinViewManager.SkinViewManagerListener() {
-			public void skinViewAdded(SkinView skinview) {
-				if (skinview instanceof ToolBarView) {
-					initToolBarView((ToolBarView) skinview);
-				}
-			}
-		});
-
-		ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-		if (tb != null) {
-			initToolBarView(tb);
-		}
-
-		return null;
+		SB_Transfers.setupViewTitleWithCore(core);
 	}
 
-	protected void initToolBarView(ToolBarView tb) {
-		itemModeSmall = tb.getToolBarItem("modeSmall");
-		if (itemModeSmall != null) {
-			itemModeSmall.addListener(new ToolBarItemListener() {
-				public void pressed(ToolBarItem toolBarItem) {
-					if (isVisible()) {
-						setViewMode(MODE_SMALLTABLE, true);
-					}
-				}
-
-				public boolean held(ToolBarItem toolBarItem) {
-					return false;
-				}
-			});
-		}
-		itemModeBig = tb.getToolBarItem("modeBig");
-		if (itemModeBig != null) {
-			itemModeBig.addListener(new ToolBarItemListener() {
-				public void pressed(ToolBarItem toolBarItem) {
-					if (isVisible()) {
-						setViewMode(MODE_BIGTABLE, true);
-					}
-				}
 
-				public boolean held(ToolBarItem toolBarItem) {
-					return false;
-				}
-			});
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		long stateSmall = UIToolBarItem.STATE_ENABLED;
+		long stateBig = UIToolBarItem.STATE_ENABLED;
+		if (viewMode == MODE_BIGTABLE) {
+			stateBig |= UIToolBarItem.STATE_DOWN;
+		} else {
+			stateSmall |= UIToolBarItem.STATE_DOWN;
 		}
+		list.put("modeSmall", stateSmall);
+		list.put("modeBig", stateBig);
 	}
-
-	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectShown(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
-	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
-		super.skinObjectShown(skinObject, params);
-		
-		ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-		if (tb != null) {
-			ToolBarItem itemModeSmall = tb.getToolBarItem("modeSmall");
-			if (itemModeSmall != null) {
-				itemModeSmall.setEnabled(true);
-				itemModeSmall.getSkinButton().getSkinObject().switchSuffix(
-						viewMode == MODE_BIGTABLE ? "" : "-down");
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		String itemKey = item.getID();
+
+		if (itemKey.equals("modeSmall")) {
+			if (isVisible()) {
+				setViewMode(MODE_SMALLTABLE, true);
+				return true;
 			}
-			ToolBarItem itemModeBig = tb.getToolBarItem("modeBig");
-			if (itemModeBig != null) {
-				itemModeBig.setEnabled(true);
-				itemModeBig.getSkinButton().getSkinObject().switchSuffix(
-						viewMode == MODE_BIGTABLE ? "-down" : "");
+		}
+		if (itemKey.equals("modeBig")) {
+			if (isVisible()) {
+				setViewMode(MODE_BIGTABLE, true);
+				return true;
 			}
 		}
-		return null;
+		return false;
 	}
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectHidden(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectHidden(SWTSkinObject skinObject, Object params) {
 		return super.skinObjectHidden(skinObject, params);
 	}
+	
+	public Object dataSourceChanged(SWTSkinObject skinObject, Object params) {
+		datasource = params;
+		if (soListArea != null) {
+  		soListArea.getControl().setData("DataSource",
+  				params);
+		}
+		
+		return null;
+	}
 
 	public int getViewMode() {
 		return viewMode;
 	}
 
-	public void setViewMode(int viewMode, boolean save) {
-		if (viewMode >= modeViewIDs.length || viewMode < 0
-				|| viewMode == this.viewMode) {
-			return;
-		}
-
-		if (itemModeSmall != null) {
-			itemModeSmall.getSkinButton().getSkinObject().switchSuffix(
-					viewMode == MODE_BIGTABLE ? "" : "-down");
-		}
-		if (itemModeBig != null) {
-			itemModeBig.getSkinButton().getSkinObject().switchSuffix(
-					viewMode == MODE_BIGTABLE ? "-down" : "");
-		}
-
-		int oldViewMode = this.viewMode;
-
-		this.viewMode = viewMode;
-
-		if (oldViewMode >= 0 && oldViewMode < modeViewIDs.length) {
-			SWTSkinObject soOldViewArea = getSkinObject(modeViewIDs[oldViewMode]);
-			//SWTSkinObject soOldViewArea = skin.getSkinObjectByID(modeIDs[oldViewMode]);
-			if (soOldViewArea != null) {
-				soOldViewArea.setVisible(false);
-			}
-		}
+	protected void
+	addHeaderInfoExtender(
+		HeaderInfoExtender	extender )
+	{
 		
-		SelectedContentManager.clearCurrentlySelectedContent();
-
-		SWTSkinObject soViewArea = getSkinObject(modeViewIDs[viewMode]);
-		if (soViewArea == null) {
-			soViewArea = skin.createSkinObject(modeIDs[viewMode] + torrentFilterMode,
-					modeIDs[viewMode], soListArea);
-			skin.layout();
-			soViewArea.setVisible(true);
-			soViewArea.getControl().setLayoutData(Utils.getFilledFormData());
-		} else {
-			soViewArea.setVisible(true);
-		}
-
-		if (save) {
-			COConfigurationManager.setParameter(torrentFilter + ".viewmode", viewMode);
-		}
-
-		String entryID = null;
-		if (torrentFilterMode == TORRENTS_ALL) {
-			entryID = SideBar.SIDEBAR_SECTION_LIBRARY;
-		} else if (torrentFilterMode == TORRENTS_COMPLETE) {
-			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_CD;
-		} else if (torrentFilterMode == TORRENTS_INCOMPLETE) {
-			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_DL;
-		} else if (torrentFilterMode == TORRENTS_UNOPENED) {
-			entryID = SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED;
-		}
-		
-		if (entryID != null) {
-  		SideBarEntrySWT entry = SideBar.getEntry(entryID);
-  		if (entry != null) {
-  			entry.setLogID(entryID + "-" + viewMode);
-  		}
-		}
-	}
-
-	public static void setupViewTitle() {
-
-		final ViewTitleInfo titleInfoDownloading = new ViewTitleInfo() {
-			public Object getTitleInfoProperty(int propertyID) {
-				if (propertyID == TITLE_INDICATOR_TEXT) {
-					if (numIncomplete > 0)
-						return numIncomplete + ""; // + " of " + numIncomplete;
-				}
-
-				if (propertyID == TITLE_INDICATOR_TEXT_TOOLTIP) {
-					return "There are " + numIncomplete + " incomplete torrents, "
-							+ numDownloading + " of which are currently downloading";
-				}
-
-				return null;
-			}
-		};
-		SideBarEntrySWT infoDL = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
-		if (infoDL != null) {
-			SideBarVitalityImage vitalityImage = infoDL.addVitalityImage(ID_VITALITY_ACTIVE);
-			vitalityImage.setVisible(false);
-
-			vitalityImage = infoDL.addVitalityImage(ID_VITALITY_ALERT);
-			vitalityImage.setVisible(false);
-
-			infoDL.setTitleInfo(titleInfoDownloading);
-
-			if (!DL_VITALITY_CONSTANT) {
-  			SimpleTimer.addPeriodicEvent("DLVitalityRefresher",
-  					DL_VITALITY_REFRESH_RATE, new TimerEventPerformer() {
-  						public void perform(TimerEvent event) {
-  							SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
-  							SideBarVitalityImage[] vitalityImages = entry.getVitalityImages();
-  							for (int i = 0; i < vitalityImages.length; i++) {
-  								SideBarVitalityImage vitalityImage = vitalityImages[i];
-  								if (vitalityImage.getImageID().equals(ID_VITALITY_ACTIVE)) {
-  									refreshDLSpinner((SideBarVitalityImageSWT) vitalityImage);
-  								}
-  							}
-  						}
-  					});
-			}
-		}
-
-		final ViewTitleInfo titleInfoSeeding = new ViewTitleInfo() {
-			public Object getTitleInfoProperty(int propertyID) {
-				if (propertyID == TITLE_INDICATOR_TEXT) {
-					return null; //numSeeding + " of " + numComplete;
-				}
-
-				if (propertyID == TITLE_INDICATOR_TEXT_TOOLTIP) {
-					return "There are " + numComplete + " complete torrents, "
-							+ numSeeding + " of which are currently seeding";
-				}
-				return null;
-			}
-		};
-		SideBarEntrySWT infoCD = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_CD);
-		if (infoCD != null) {
-			SideBarVitalityImage vitalityImage = infoCD.addVitalityImage(ID_VITALITY_ALERT);
-			vitalityImage.setVisible(false);
-
-			infoCD.setTitleInfo(titleInfoSeeding);
-		}
-
-		SideBarEntrySWT infoLibraryUn = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED);
-		if (infoLibraryUn != null) {
-			infoLibraryUn.setTitleInfo(new ViewTitleInfo() {
-				public Object getTitleInfoProperty(int propertyID) {
-					if (propertyID == TITLE_INDICATOR_TEXT && numUnOpened > 0) {
-						return "" + numUnOpened;
-					}
-					return null;
-				}
-			});
-		}
-
-		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-			public void azureusCoreRunning(AzureusCore core) {
-				setupViewTitleWithCore(core);
-			}
-		});
-		PlatformTorrentUtils.addHasBeenOpenedListener(new HasBeenOpenedListener() {
-			public void hasBeenOpenedChanged(DownloadManager dm, boolean opened) {
-				recountUnopened();
-				refreshAllLibraries();
-			}
-		});
 	}
 	
-	protected static void setupViewTitleWithCore(AzureusCore core) {
-		final GlobalManager gm = core.getGlobalManager();
-		final DownloadManagerListener dmListener = new DownloadManagerAdapter() {
-			public void stateChanged(DownloadManager dm, int state) {
-				if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-					return;
-				}
-				if (dm.getAssumedComplete()) {
-					boolean isSeeding = dm.getState() == DownloadManager.STATE_SEEDING;
-					Boolean wasSeedingB = (Boolean) dm.getUserData("wasSeeding");
-					boolean wasSeeding = wasSeedingB == null ? false
-							: wasSeedingB.booleanValue();
-					if (isSeeding != wasSeeding) {
-						if (isSeeding) {
-							numSeeding++;
-						} else {
-							numSeeding--;
-						}
-						dm.setUserData("wasSeeding", new Boolean(isSeeding));
-					}
-				} else {
-					boolean isDownloading = dm.getState() == DownloadManager.STATE_DOWNLOADING;
-					Boolean wasDownloadingB = (Boolean) dm.getUserData("wasDownloading");
-					boolean wasDownloading = wasDownloadingB == null ? false
-							: wasDownloadingB.booleanValue();
-					if (isDownloading != wasDownloading) {
-						if (isDownloading) {
-							numDownloading++;
-						} else {
-							numDownloading--;
-						}
-						dm.setUserData("wasDownloading", new Boolean(isDownloading));
-					}
-				}
-				
-				boolean complete = dm.getAssumedComplete();
-				Boolean wasErrorStateB = (Boolean) dm.getUserData("wasErrorState");
-				boolean wasErrorState = wasErrorStateB == null ? false
-						: wasErrorStateB.booleanValue();
-				boolean isErrorState = state == DownloadManager.STATE_ERROR;
-				if (isErrorState != wasErrorState) {
-					int rel = isErrorState ? 1 : -1;
-					if (complete) {
-						numErrorComplete += rel;
-					} else {
-						numErrorInComplete += rel;
-					}
-					updateErrorTooltip();
-					dm.setUserData("wasErrorState", new Boolean(isErrorState));
-				}
-				refreshAllLibraries();
-			}
-			
-			public void completionChanged(DownloadManager dm, boolean completed) {
-				if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-					return;
-				}
-				if (completed) {
-					numComplete++;
-					numIncomplete--;
-					if (dm.getState() == DownloadManager.STATE_ERROR) {
-						numErrorComplete++;
-						numErrorInComplete--;
-					}
-				} else {
-					numIncomplete++;
-					numComplete--;
-					if (dm.getState() == DownloadManager.STATE_ERROR) {
-						numErrorComplete--;
-						numErrorInComplete++;
-					}
-				}
-				recountUnopened();
-				updateErrorTooltip();
-				refreshAllLibraries();
-			}
-			
-			protected void updateErrorTooltip() {
-				if (numErrorComplete < 0) {
-					numErrorComplete = 0;
-				}
-				if (numErrorInComplete < 0) {
-					numErrorInComplete = 0;
-				}
-				
-				if (numErrorComplete > 0 || numErrorInComplete > 0) {
-					
-					String comp_error = null;
-					String incomp_error = null;
-					
-					List downloads = gm.getDownloadManagers();
-					
-					for (int i = 0; i < downloads.size(); i++) {
-						
-						DownloadManager download = (DownloadManager) downloads.get(i);
-						
-						if (download.getState() == DownloadManager.STATE_ERROR) {
-							
-							if (download.getAssumedComplete()) {
-								
-								if (comp_error == null) {
-									
-									comp_error = download.getDisplayName() + ": "
-									+ download.getErrorDetails();
-								} else {
-									
-									comp_error += "...";
-								}
-							} else {
-								if (incomp_error == null) {
-									
-									incomp_error = download.getDisplayName() + ": "
-									+ download.getErrorDetails();
-								} else {
-									
-									incomp_error += "...";
-								}
-							}
-						}
-					}
-					
-					errorCompleteTooltip = comp_error;
-					errorInCompleteTooltip = incomp_error;
-				}
-			}
-		};
+	protected void
+	removeHeaderInfoExtender(
+		HeaderInfoExtender	extender )
+	{
 		
-		gm.addListener(new GlobalManagerAdapter() {
-			public void downloadManagerRemoved(DownloadManager dm) {
-				if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-					return;
-				}
-				recountUnopened();
-				if (dm.getAssumedComplete()) {
-					numComplete--;
-					Boolean wasDownloadingB = (Boolean) dm.getUserData("wasDownloading");
-					if (wasDownloadingB != null && wasDownloadingB.booleanValue()) {
-						numDownloading--;
-					}
-				} else {
-					numIncomplete--;
-					Boolean wasSeedingB = (Boolean) dm.getUserData("wasSeeding");
-					if (wasSeedingB != null && wasSeedingB.booleanValue()) {
-						numSeeding--;
-					}
-				}
-				refreshAllLibraries();
-				dm.removeListener(dmListener);
-			}
-			
-			public void downloadManagerAdded(DownloadManager dm) {
-				if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-					return;
-				}
-				dm.addListener(dmListener, false);
-				
-				recountUnopened();
-				if (dm.getAssumedComplete()) {
-					numComplete++;
-					if (dm.getState() == DownloadManager.STATE_SEEDING) {
-						numSeeding++;
-					}
-				} else {
-					numIncomplete++;
-					if (dm.getState() == DownloadManager.STATE_DOWNLOADING) {
-						dm.setUserData("wasDownloading", new Boolean(true));
-						numSeeding++;
-					} else {
-						dm.setUserData("wasDownloading", new Boolean(false));
-					}
-				}
-				refreshAllLibraries();
-			}
-		}, false);
-		List downloadManagers = gm.getDownloadManagers();
-		for (Iterator iter = downloadManagers.iterator(); iter.hasNext();) {
-			DownloadManager dm = (DownloadManager) iter.next();
-			if (PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
-				continue;
-			}
-			dm.addListener(dmListener, false);
-			if (dm.getAssumedComplete()) {
-				numComplete++;
-				if (dm.getState() == DownloadManager.STATE_SEEDING) {
-					dm.setUserData("wasSeeding", new Boolean(true));
-					numSeeding++;
-				} else {
-					dm.setUserData("wasSeeding", new Boolean(false));
-				}
-			} else {
-				numIncomplete++;
-				if (dm.getState() == DownloadManager.STATE_DOWNLOADING) {
-					numSeeding++;
-				}
-			}
-		}
-
-		recountUnopened();
-	}
-
-	private static void recountUnopened() {
-		if (!AzureusCoreFactory.isCoreRunning()) {
-			return;
-		}
-		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-		List dms = gm.getDownloadManagers();
-		numUnOpened = 0;
-		for (Iterator iter = dms.iterator(); iter.hasNext();) {
-			DownloadManager dm = (DownloadManager) iter.next();
-			if (!PlatformTorrentUtils.getHasBeenOpened(dm) && dm.getAssumedComplete()) {
-				numUnOpened++;
-			}
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	protected static void refreshAllLibraries() {
-		SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
-		SideBarVitalityImage[] vitalityImages = entry.getVitalityImages();
-		for (int i = 0; i < vitalityImages.length; i++) {
-			SideBarVitalityImage vitalityImage = vitalityImages[i];
-			if (vitalityImage.getImageID().equals(ID_VITALITY_ACTIVE)) {
-				vitalityImage.setVisible(numDownloading > 0);
-
-				refreshDLSpinner((SideBarVitalityImageSWT) vitalityImage);
-
-			} else if (vitalityImage.getImageID().equals(ID_VITALITY_ALERT)) {
-				vitalityImage.setVisible(numErrorInComplete > 0);
-				if (numErrorInComplete > 0) {
-					vitalityImage.setToolTip(errorInCompleteTooltip);
-				}
-			}
-		}
-		ViewTitleInfoManager.refreshTitleInfo(entry.getTitleInfo());
-
-		entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_CD);
-		vitalityImages = entry.getVitalityImages();
-		for (int i = 0; i < vitalityImages.length; i++) {
-			SideBarVitalityImage vitalityImage = vitalityImages[i];
-			if (vitalityImage.getImageID().equals(ID_VITALITY_ALERT)) {
-				vitalityImage.setVisible(numErrorComplete > 0);
-				if (numErrorComplete > 0) {
-					vitalityImage.setToolTip(errorCompleteTooltip);
-				}
-			}
-		}
-
-		entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED);
-		ViewTitleInfoManager.refreshTitleInfo(entry.getTitleInfo());
 	}
-
-	public static void refreshDLSpinner(SideBarVitalityImageSWT vitalityImage) {
-		if (DL_VITALITY_CONSTANT) {
-			return;
-		}
-
-		if (vitalityImage.getImageID().equals(ID_VITALITY_ACTIVE)) {
-			if (!vitalityImage.isVisible()) {
-				return;
-			}
-			SpeedManager sm = AzureusCoreFactory.getSingleton().getSpeedManager();
-			if (sm != null) {
-				GlobalManagerStats stats = AzureusCoreFactory.getSingleton().getGlobalManager().getStats();
-
-				int delay = 100;
-				int limit = NetworkManager.getMaxDownloadRateBPS();
-				if (limit <= 0) {
-					limit = sm.getEstimatedDownloadCapacityBytesPerSec().getBytesPerSec();
-				}
-
-				// smoothing
-				int current = stats.getDataReceiveRate() / 10;
-				limit /= 10;
-
-				if (limit > 0) {
-					if (current > limit) {
-						delay = 25;
-					} else {
-						// 40 incrememnts of 5.. max 200
-						current += 39;
-						delay = (40 - (current * 40 / limit)) * 5;
-						if (delay < 35) {
-							delay = 35;
-						} else if (delay > 200) {
-							delay = 200;
-						}
-					}
-					if (vitalityImage instanceof SideBarVitalityImageSWT) {
-						SideBarVitalityImageSWT viSWT = (SideBarVitalityImageSWT) vitalityImage;
-						if (viSWT.getDelayTime() != delay) {
-							viSWT.setDelayTime(delay);
-							//System.out.println("new delay: " + delay + "; via " + current + " / " + limit);
-						}
-					}
-				}
-			}
-		}
+	
+	protected void
+	refreshHeaderInfo()
+	{
+		SB_Transfers.triggerCountRefreshListeners();
 	}
-
-	public static String getTableIdFromFilterMode(int torrentFilterMode,
-			boolean big) {
-		if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE) {
-			return big ? TableManager.TABLE_MYTORRENTS_COMPLETE_BIG
-					: TableManager.TABLE_MYTORRENTS_COMPLETE;
-		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE) {
-			return big ? TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG
-					: TableManager.TABLE_MYTORRENTS_INCOMPLETE;
-		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
-			return big ? TableManager.TABLE_MYTORRENTS_UNOPENED_BIG
-					: TableManager.TABLE_MYTORRENTS_UNOPENED;
-		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
-			return TableManager.TABLE_MYTORRENTS_ALL_BIG;
-		}
-		return null;
+	
+	protected interface
+	HeaderInfoExtender
+	{
+		
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SBC_PlusFTUX.java b/com/aelitis/azureus/ui/swt/views/skin/SBC_PlusFTUX.java
new file mode 100644
index 0000000..2ea148b
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/SBC_PlusFTUX.java
@@ -0,0 +1,148 @@
+/**
+ * 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 org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectBrowser;
+import com.aelitis.azureus.util.ConstantsVuze;
+
+/**
+ * @author TuxPaper
+ * @created Oct 1, 2006
+ *
+ */
+public class SBC_PlusFTUX
+	extends SkinView
+{
+	private SWTSkinObjectBrowser browserSkinObject;
+
+	private String url;
+
+	private static String sRef = "user";
+
+	private static boolean DEBUG = Constants.IS_CVS_VERSION;
+
+	private MdiEntry entry;
+
+	public Object skinObjectInitialShow(final SWTSkinObject skinObject,
+			Object params) {
+
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			entry = mdi.getEntryFromSkinObject(skinObject);
+		}
+
+		browserSkinObject = (SWTSkinObjectBrowser) skin.getSkinObject("plus-ftux",
+				soMain);
+
+		browserSkinObject.addListener(new loadingListener() {
+
+			public void browserLoadingChanged(boolean loading, String url) {
+				if (!loading) {
+					skinObject.getControl().getParent().layout(true, true);
+				}
+			}
+		});
+
+		if (DEBUG) {
+			System.out.println("PlusFTUX sourceRef is now " + sRef);
+		}
+
+		return null;
+	}
+
+	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
+		super.skinObjectShown(skinObject, params);
+		buildURL(true);
+		return null;
+	}
+
+	public Object skinObjectHidden(SWTSkinObject skinObject, Object params) {
+		if (browserSkinObject != null) {
+			browserSkinObject.setURL("about:blank");
+		}
+		sRef = "user";
+		if (DEBUG) {
+			System.out.println("PlusFTUX sourceRef is now " + sRef);
+		}
+		return super.skinObjectHidden(skinObject, params);
+	}
+
+	/**
+	 * @param hasFullLicence
+	 */
+	public void updateLicenceInfo() {
+		buildURL(false);
+	}
+
+	private void buildURL(boolean forceSet) {
+		String sRef2;
+		long plusExpiryTimeStamp = FeatureManagerUI.getPlusExpiryDisplayTimeStamp();
+		if (plusExpiryTimeStamp > 0 && plusExpiryTimeStamp < SystemTime.getCurrentTime()) {
+			sRef2 = "-/plus/renew";
+		} else {
+			sRef2 = "-/plus/ftux";
+		}
+		String suffix = "?sourceRef=" + UrlUtils.encode(sRef + sRef2);
+		String newUrl = ConstantsVuze.getDefaultContentNetwork().getSiteRelativeURL(
+				"plus-ftux.start" + suffix, false);
+		newUrl = FeatureManagerUI.appendFeatureManagerURLParams(newUrl);
+		if (!forceSet && newUrl.equals(url)) {
+			return;
+		}
+		
+		url = newUrl;
+
+		if (DEBUG) {
+  		System.out.println("URL is now " + url + " via "
+  				+ Debug.getCompressedStackTrace());
+		}
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		MdiEntry currentEntry = mdi.getCurrentEntry();
+
+		if (browserSkinObject != null && (forceSet || entry == currentEntry)) {
+			browserSkinObject.setURL(url);
+		}
+	}
+
+	public static void setSourceRef(String _sRef) {
+		sRef = _sRef;
+		
+		if (DEBUG) {
+			System.out.println("PlusFTUX sourceRef is now " + sRef);
+		}
+
+		SBC_PlusFTUX sv = (SBC_PlusFTUX) SkinViewManager.getByClass(SBC_PlusFTUX.class);
+		if (sv != null) {
+			sv.buildURL(false);
+		}
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SB_Transfers.java b/com/aelitis/azureus/ui/swt/views/skin/SB_Transfers.java
new file mode 100644
index 0000000..f41e05f
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/SB_Transfers.java
@@ -0,0 +1,995 @@
+/**
+ * Created on Oct 21, 2010
+ *
+ * Copyright 2010 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.views.skin;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.widgets.Menu;
+
+import org.gudy.azureus2.core3.category.*;
+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.download.DownloadManagerListener;
+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.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.menus.*;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.CategoryAdderWindow;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
+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 org.gudy.azureus2.ui.swt.views.utils.CategoryUIUtils;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.torrent.HasBeenOpenedListener;
+import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
+import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
+
+/**
+ * @author TuxPaper
+ * @created Oct 21, 2010
+ *
+ */
+public class SB_Transfers
+{
+
+	private static final String ID_VITALITY_ACTIVE = "image.sidebar.vitality.dl";
+
+	private static final String ID_VITALITY_ALERT = "image.sidebar.vitality.alert";
+
+	public static class stats
+	{
+		int numSeeding = 0;
+
+		int numDownloading = 0;
+
+		int numComplete = 0;
+
+		int numIncomplete = 0;
+
+		int numErrorComplete = 0;
+
+		String errorInCompleteTooltip;
+
+		int numErrorInComplete = 0;
+
+		String errorCompleteTooltip;
+
+		int numUnOpened = 0;
+
+		int numStoppedAll = 0;
+
+		int numStoppedIncomplete = 0;
+
+		boolean includeLowNoise;
+	};
+
+	private static stats statsWithLowNoise = new stats();
+
+	private static stats statsNoLowNoise = new stats();
+
+	private static List<countRefreshListener> listeners = new ArrayList<countRefreshListener>();
+
+	private static boolean first = true;
+
+	private static CategoryListener categoryListener;
+
+	static {
+		statsNoLowNoise.includeLowNoise = false;
+		statsWithLowNoise.includeLowNoise = true;
+	}
+
+	public static void setup(final MultipleDocumentInterface mdi) {
+
+		mdi.registerEntry(SideBar.SIDEBAR_SECTION_LIBRARY,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						MdiEntry entry = mdi.createEntryFromSkinRef(
+								SideBar.SIDEBAR_HEADER_TRANSFERS,
+								SideBar.SIDEBAR_SECTION_LIBRARY, "library", "{sidebar."
+										+ SideBar.SIDEBAR_SECTION_LIBRARY + "}", null, null, false,
+								"");
+						entry.setImageLeftID("image.sidebar.library");
+						return entry;
+					}
+				});
+
+		mdi.registerEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						return createDownloadingEntry(mdi);
+					}
+				});
+
+		mdi.registerEntry(SideBar.SIDEBAR_SECTION_LIBRARY_CD,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						return createSeedingEntry(mdi);
+					}
+				});
+
+		mdi.registerEntry(SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+						return createUnopenedEntry(mdi);
+					}
+				});
+
+		if (first) {
+			AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+				public void azureusCoreRunning(AzureusCore core) {
+					setupViewTitleWithCore(core);
+				}
+			});
+		}
+		PlatformTorrentUtils.addHasBeenOpenedListener(new HasBeenOpenedListener() {
+			public void hasBeenOpenedChanged(DownloadManager dm, boolean opened) {
+				recountUnopened();
+				refreshAllLibraries();
+			}
+		});
+
+		addMenuUnwatched(SideBar.SIDEBAR_SECTION_LIBRARY);
+
+		mdi.addListener(new MdiEntryLoadedListener() {
+			public void mdiEntryLoaded(MdiEntry entry) {
+				if (MultipleDocumentInterface.SIDEBAR_HEADER_TRANSFERS.equals(entry.getId())) {
+					addHeaderMenu();
+				}
+			}
+		});
+	}
+
+	protected static void addHeaderMenu() {
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+		UIManager uim = pi.getUIManager();
+		MenuManager menuManager = uim.getMenuManager();
+		MenuItem menuItem;
+
+		menuItem = menuManager.addMenuItem("sidebar."
+				+ MultipleDocumentInterface.SIDEBAR_HEADER_TRANSFERS,
+				"MyTorrentsView.menu.setCategory.add");
+		menuItem.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				new CategoryAdderWindow(null);
+			}
+		});
+		menuItem.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setVisible(COConfigurationManager.getBooleanParameter("Library.CatInSideBar"));
+			}
+		});
+
+		menuItem = menuManager.addMenuItem("sidebar."
+				+ MultipleDocumentInterface.SIDEBAR_HEADER_TRANSFERS,
+				"ConfigView.section.style.CatInSidebar");
+		menuItem.setStyle(MenuItem.STYLE_CHECK);
+		menuItem.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				boolean b = COConfigurationManager.getBooleanParameter("Library.CatInSideBar");
+				COConfigurationManager.setParameter("Library.CatInSideBar", !b);
+			}
+		});
+		menuItem.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setVisible(CategoryManager.getCategories().length > 0);
+				menu.setData(Boolean.valueOf(COConfigurationManager.getBooleanParameter("Library.CatInSideBar")));
+			}
+		});
+	}
+
+	protected static MdiEntry createUnopenedEntry(MultipleDocumentInterface mdi) {
+		MdiEntry infoLibraryUn = mdi.createEntryFromSkinRef(
+				SideBar.SIDEBAR_HEADER_TRANSFERS,
+				SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED, "library",
+				"{sidebar.LibraryUnopened}", null, null, false,
+				SideBar.SIDEBAR_SECTION_LIBRARY);
+		infoLibraryUn.setImageLeftID("image.sidebar.unopened");
+
+		addMenuUnwatched(SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED);
+		infoLibraryUn.setViewTitleInfo(new ViewTitleInfo() {
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == TITLE_INDICATOR_TEXT
+						&& statsNoLowNoise.numUnOpened > 0) {
+					return "" + statsNoLowNoise.numUnOpened;
+				}
+				return null;
+			}
+		});
+		return infoLibraryUn;
+	}
+
+	private static void addMenuUnwatched(String id) {
+		PluginInterface pi = PluginInitializer.getDefaultInterface();
+		UIManager uim = pi.getUIManager();
+		MenuManager menuManager = uim.getMenuManager();
+
+		MenuItem menuItem = menuManager.addMenuItem("sidebar." + id,
+				"v3.activity.button.watchall");
+		menuItem.addListener(new MenuItemListener() {
+			public void selected(MenuItem menu, Object target) {
+				CoreWaiterSWT.waitForCore(TriggerInThread.ANY_THREAD,
+						new AzureusCoreRunningListener() {
+							public void azureusCoreRunning(AzureusCore core) {
+								GlobalManager gm = core.getGlobalManager();
+								List<?> downloadManagers = gm.getDownloadManagers();
+								for (Iterator<?> iter = downloadManagers.iterator(); iter.hasNext();) {
+									DownloadManager dm = (DownloadManager) iter.next();
+
+									if (!PlatformTorrentUtils.getHasBeenOpened(dm)
+											&& dm.getAssumedComplete()) {
+										PlatformTorrentUtils.setHasBeenOpened(dm, true);
+									}
+								}
+							}
+						});
+			}
+		});
+	}
+
+	/**
+	 * @param mdi
+	 * @return
+	 *
+	 * @since 4.5.1.1
+	 */
+	protected static MdiEntry createSeedingEntry(MultipleDocumentInterface mdi) {
+		ViewTitleInfo titleInfoSeeding = new ViewTitleInfo() {
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == TITLE_INDICATOR_TEXT) {
+					return null; //numSeeding + " of " + numComplete;
+				}
+
+				if (propertyID == TITLE_INDICATOR_TEXT_TOOLTIP) {
+					return MessageText.getString("sidebar.LibraryCD.tooltip",
+							new String[] {
+								"" + statsNoLowNoise.numComplete,
+								"" + statsNoLowNoise.numSeeding
+							});
+				}
+				return null;
+			}
+		};
+
+		MdiEntry entry = mdi.createEntryFromSkinRef(
+				SideBar.SIDEBAR_HEADER_TRANSFERS, SideBar.SIDEBAR_SECTION_LIBRARY_DL,
+				"library", "{sidebar.LibraryDL}",
+				titleInfoSeeding, null, false, null);
+		entry.setImageLeftID("image.sidebar.downloading");
+
+		MdiEntryVitalityImage vitalityImage = entry.addVitalityImage(ID_VITALITY_ALERT);
+		vitalityImage.setVisible(false);
+
+		entry.setViewTitleInfo(titleInfoSeeding);
+
+		return entry;
+	}
+
+	protected static MdiEntry createDownloadingEntry(MultipleDocumentInterface mdi) {
+		ViewTitleInfo titleInfoDownloading = new ViewTitleInfo() {
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == TITLE_INDICATOR_TEXT) {
+					if (statsNoLowNoise.numIncomplete > 0)
+						return statsNoLowNoise.numIncomplete + ""; // + " of " + numIncomplete;
+				}
+
+				if (propertyID == TITLE_INDICATOR_TEXT_TOOLTIP) {
+					return MessageText.getString("sidebar.LibraryDL.tooltip",
+							new String[] {
+								"" + statsNoLowNoise.numIncomplete,
+								"" + statsNoLowNoise.numDownloading
+							});
+				}
+
+				return null;
+			}
+		};
+		MdiEntry entry = mdi.createEntryFromSkinRef(
+				SideBar.SIDEBAR_HEADER_TRANSFERS, SideBar.SIDEBAR_SECTION_LIBRARY_DL,
+				"library", "{sidebar.LibraryDL}",
+				titleInfoDownloading, null, false, null);
+		entry.setImageLeftID("image.sidebar.downloading");
+
+		MdiEntryVitalityImage vitalityImage = entry.addVitalityImage(ID_VITALITY_ACTIVE);
+		vitalityImage.setVisible(false);
+
+		vitalityImage = entry.addVitalityImage(ID_VITALITY_ALERT);
+		vitalityImage.setVisible(false);
+
+		return entry;
+	}
+
+	protected static void setupViewTitleWithCore(AzureusCore core) {
+		if (!first) {
+			return;
+		}
+		first = false;
+		
+		categoryListener = new CategoryListener() {
+			
+			public void downloadManagerRemoved(Category cat, DownloadManager removed) {
+				RefreshCategorySideBar(cat);
+			}
+			
+			public void downloadManagerAdded(Category cat, DownloadManager manager) {
+				RefreshCategorySideBar(cat);
+			}
+		};
+
+		COConfigurationManager.addAndFireParameterListener("Library.CatInSideBar",
+				new ParameterListener() {
+					private CategoryManagerListener categoryManagerListener;
+
+					public void parameterChanged(String parameterName) {
+						if (Utils.isAZ2UI()) {
+							return;
+						}
+						
+						Category[] categories = CategoryManager.getCategories();
+						if (categories.length == 0) {
+							return;
+						}
+
+						boolean catInSidebar = COConfigurationManager.getBooleanParameter("Library.CatInSideBar");
+						if (catInSidebar) {
+							if (categoryManagerListener != null) {
+								return;
+							}
+
+							categoryManagerListener = new CategoryManagerListener() {
+
+								public void categoryRemoved(Category category) {
+									removeCategory(category);
+								}
+
+								public void categoryChanged(Category category) {
+									RefreshCategorySideBar(category);
+								}
+
+								public void categoryAdded(Category category) {
+									Category[] categories = CategoryManager.getCategories();
+									if (categories.length == 3) {
+		  							for (Category cat : categories) {
+		  								setupCategory(cat);
+		  							}
+									} else {
+										setupCategory(category);
+									}
+								}
+							};
+							CategoryManager.addCategoryManagerListener(categoryManagerListener);
+							if (categories.length > 2) {
+  							for (Category category : categories) {
+  								category.addCategoryListener(categoryListener);
+  								setupCategory(category);
+  							}
+							}
+
+						} else {
+
+							if (categoryManagerListener != null) {
+								CategoryManager.removeCategoryManagerListener(categoryManagerListener);
+								categoryManagerListener = null;
+							}
+							for (Category category : categories) {
+								category.removeCategoryListener(categoryListener);
+								removeCategory(category);
+							}
+						}
+					}
+				});
+
+		final GlobalManager gm = core.getGlobalManager();
+		final DownloadManagerListener dmListener = new DownloadManagerAdapter() {
+			public void stateChanged(DownloadManager dm, int state) {
+				stateChanged(dm, state, statsNoLowNoise);
+				stateChanged(dm, state, statsWithLowNoise);
+			}
+
+			public void stateChanged(DownloadManager dm, int state, stats stats) {
+				if (!stats.includeLowNoise
+						&& PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
+					return;
+				}
+
+				updateDMCounts(dm);
+
+				boolean complete = dm.getAssumedComplete();
+				Boolean wasErrorStateB = (Boolean) dm.getUserData("wasErrorState");
+				boolean wasErrorState = wasErrorStateB == null ? false
+						: wasErrorStateB.booleanValue();
+				boolean isErrorState = state == DownloadManager.STATE_ERROR;
+				if (isErrorState != wasErrorState) {
+					int rel = isErrorState ? 1 : -1;
+					if (complete) {
+						stats.numErrorComplete += rel;
+					} else {
+						stats.numErrorInComplete += rel;
+					}
+					updateErrorTooltip(stats);
+					dm.setUserData("wasErrorState", new Boolean(isErrorState));
+				}
+				refreshAllLibraries();
+			}
+
+			public void completionChanged(DownloadManager dm, boolean completed) {
+				completionChanged(dm, completed, statsNoLowNoise);
+				completionChanged(dm, completed, statsWithLowNoise);
+			}
+
+			public void completionChanged(DownloadManager dm, boolean completed,
+					stats stats) {
+				if (!stats.includeLowNoise
+						&& PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
+					return;
+				}
+
+				updateDMCounts(dm);
+				if (completed) {
+					stats.numComplete++;
+					stats.numIncomplete--;
+					if (dm.getState() == DownloadManager.STATE_ERROR) {
+						stats.numErrorComplete++;
+						stats.numErrorInComplete--;
+					}
+					if (dm.getState() == DownloadManager.STATE_STOPPED) {
+						statsNoLowNoise.numStoppedIncomplete--;
+					}
+
+				} else {
+					stats.numComplete--;
+					stats.numIncomplete++;
+
+					if (dm.getState() == DownloadManager.STATE_ERROR) {
+						stats.numErrorComplete--;
+						stats.numErrorInComplete++;
+					}
+					if (dm.getState() == DownloadManager.STATE_STOPPED) {
+						statsNoLowNoise.numStoppedIncomplete++;
+					}
+				}
+				recountUnopened();
+				updateErrorTooltip(stats);
+				refreshAllLibraries();
+			}
+
+			protected void updateErrorTooltip(stats stats) {
+				if (stats.numErrorComplete < 0) {
+					stats.numErrorComplete = 0;
+				}
+				if (stats.numErrorInComplete < 0) {
+					stats.numErrorInComplete = 0;
+				}
+
+				if (stats.numErrorComplete > 0 || stats.numErrorInComplete > 0) {
+
+					String comp_error = null;
+					String incomp_error = null;
+
+					List<?> downloads = gm.getDownloadManagers();
+
+					for (int i = 0; i < downloads.size(); i++) {
+
+						DownloadManager download = (DownloadManager) downloads.get(i);
+
+						if (download.getState() == DownloadManager.STATE_ERROR) {
+
+							if (download.getAssumedComplete()) {
+
+								if (comp_error == null) {
+
+									comp_error = download.getDisplayName() + ": "
+											+ download.getErrorDetails();
+								} else {
+
+									comp_error += "...";
+								}
+							} else {
+								if (incomp_error == null) {
+
+									incomp_error = download.getDisplayName() + ": "
+											+ download.getErrorDetails();
+								} else {
+
+									incomp_error += "...";
+								}
+							}
+						}
+					}
+
+					stats.errorCompleteTooltip = comp_error;
+					stats.errorInCompleteTooltip = incomp_error;
+				}
+			}
+		};
+
+		gm.addListener(new GlobalManagerAdapter() {
+			public void downloadManagerRemoved(DownloadManager dm) {
+				downloadManagerRemoved(dm, statsNoLowNoise);
+				downloadManagerRemoved(dm, statsWithLowNoise);
+			}
+
+			public void downloadManagerRemoved(DownloadManager dm, stats stats) {
+				if (!stats.includeLowNoise
+						&& PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
+					return;
+				}
+
+				recountUnopened();
+				if (dm.getAssumedComplete()) {
+					stats.numComplete--;
+					Boolean wasDownloadingB = (Boolean) dm.getUserData("wasDownloading");
+					if (wasDownloadingB != null && wasDownloadingB.booleanValue()) {
+						stats.numDownloading--;
+					}
+				} else {
+					stats.numIncomplete--;
+					Boolean wasSeedingB = (Boolean) dm.getUserData("wasSeeding");
+					if (wasSeedingB != null && wasSeedingB.booleanValue()) {
+						stats.numSeeding--;
+					}
+				}
+
+				Boolean wasStoppedB = (Boolean) dm.getUserData("wasStopped");
+				boolean wasStopped = wasStoppedB == null ? false
+						: wasStoppedB.booleanValue();
+				if (wasStopped) {
+					stats.numStoppedAll--;
+					if (!dm.getAssumedComplete()) {
+						stats.numStoppedIncomplete--;
+					}
+				}
+
+				refreshAllLibraries();
+				dm.removeListener(dmListener);
+			}
+
+			public void downloadManagerAdded(DownloadManager dm) {
+				dm.addListener(dmListener, false);
+				recountUnopened();
+
+				downloadManagerAdded(dm, statsNoLowNoise);
+				downloadManagerAdded(dm, statsWithLowNoise);
+				refreshAllLibraries();
+			}
+
+			public void downloadManagerAdded(DownloadManager dm, stats stats) {
+				if (!stats.includeLowNoise
+						&& PlatformTorrentUtils.isAdvancedViewOnly(dm)) {
+					return;
+				}
+
+				if (dm.getAssumedComplete()) {
+					stats.numComplete++;
+					if (dm.getState() == DownloadManager.STATE_SEEDING) {
+						stats.numSeeding++;
+					}
+				} else {
+					stats.numIncomplete++;
+					if (dm.getState() == DownloadManager.STATE_DOWNLOADING) {
+						dm.setUserData("wasDownloading", Boolean.TRUE);
+						stats.numDownloading++;
+					} else {
+						dm.setUserData("wasDownloading", Boolean.FALSE);
+					}
+				}
+			}
+		}, false);
+		List<?> downloadManagers = gm.getDownloadManagers();
+		for (Iterator<?> iter = downloadManagers.iterator(); iter.hasNext();) {
+			DownloadManager dm = (DownloadManager) iter.next();
+			boolean lowNoise = PlatformTorrentUtils.isAdvancedViewOnly(dm);
+			dm.addListener(dmListener, false);
+			int state = dm.getState();
+			if (state == DownloadManager.STATE_STOPPED) {
+				dm.setUserData("wasStopped", Boolean.TRUE);
+				statsWithLowNoise.numStoppedAll++;
+				if (!dm.getAssumedComplete()) {
+					statsWithLowNoise.numStoppedIncomplete++;
+				}
+				if (!lowNoise) {
+					statsNoLowNoise.numStoppedAll++;
+					if (!dm.getAssumedComplete()) {
+						statsNoLowNoise.numStoppedIncomplete++;
+					}
+				}
+			} else {
+				dm.setUserData("wasStopped", Boolean.FALSE);
+			}
+			if (dm.getAssumedComplete()) {
+				statsWithLowNoise.numComplete++;
+				if (!lowNoise) {
+					statsNoLowNoise.numComplete++;
+				}
+				if (state == DownloadManager.STATE_SEEDING) {
+					dm.setUserData("wasSeeding", Boolean.TRUE);
+					statsWithLowNoise.numSeeding++;
+					if (!lowNoise) {
+						statsNoLowNoise.numSeeding++;
+					}
+				} else {
+					dm.setUserData("wasSeeding", Boolean.FALSE);
+				}
+			} else {
+				statsWithLowNoise.numIncomplete++;
+				if (!lowNoise) {
+					statsNoLowNoise.numIncomplete++;
+				}
+				if (state == DownloadManager.STATE_DOWNLOADING) {
+					statsWithLowNoise.numDownloading++;
+					if (!lowNoise) {
+						statsNoLowNoise.numDownloading++;
+					}
+				}
+			}
+		}
+
+		recountUnopened();
+		refreshAllLibraries();
+	}
+
+
+	private static void RefreshCategorySideBar(Category category) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return;
+		}
+
+		MdiEntry entry = mdi.getEntry("Cat."
+				+ Base32.encode(category.getName().getBytes()));
+		if (entry == null) {
+			return;
+		}
+
+		ViewTitleInfoManager.refreshTitleInfo(entry.getViewTitleInfo());
+	}
+
+	private static void setupCategory(final Category category) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return;
+		}
+
+		String name = category.getName();
+		String id = "Cat." + Base32.encode(name.getBytes());
+		if (category.getType() != Category.TYPE_USER) {
+			name = "{" + name + "}";
+		}
+
+		ViewTitleInfo viewTitleInfo = new ViewTitleInfo() {
+
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == TITLE_INDICATOR_TEXT) {
+					if (statsNoLowNoise.numIncomplete > 0) {
+						List<?> dms = category.getDownloadManagers(null);
+						if (dms != null) {
+							return "" + dms.size();
+						}
+					}
+				}
+				return null;
+			}
+		};
+
+		MdiEntry entry = mdi.createEntryFromSkinRef(
+				MultipleDocumentInterface.SIDEBAR_HEADER_TRANSFERS, id, "library",
+				name, viewTitleInfo, category, false, null);
+		if (entry != null) {
+			entry.setImageLeftID("image.sidebar.library");
+		}
+
+		if (entry instanceof SideBarEntrySWT) {
+			final SideBarEntrySWT entrySWT = (SideBarEntrySWT) entry;
+			entrySWT.addListener(new MdiSWTMenuHackListener() {
+				public void menuWillBeShown(MdiEntry entry, Menu menuTree) {
+					CategoryUIUtils.createMenuItems(menuTree, category);
+				}
+			});
+		}
+
+		entry.addListener(new MdiEntryDropListener() {
+			public boolean mdiEntryDrop(MdiEntry entry, Object payload) {
+				if (!(payload instanceof String)) {
+					return false;
+				}
+
+				String dropped = (String) payload;
+				String[] split = Constants.PAT_SPLIT_SLASH_N.split(dropped);
+				if (split.length > 1) {
+					String type = split[0];
+					if (type.startsWith("DownloadManager")) {
+						GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+						for (int i = 1; i < split.length; i++) {
+							String hash = split[i];
+
+							try {
+								DownloadManager dm = gm.getDownloadManager(new HashWrapper(
+										Base32.decode(hash)));
+
+								if (dm != null) {
+									TorrentUtil.assignToCategory(new Object[] {
+										dm
+									}, category);
+								}
+
+							} catch (Throwable t) {
+
+							}
+						}
+					}
+				}
+
+				return true;
+			}
+		});
+	}
+
+	private static void removeCategory(Category category) {
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return;
+		}
+
+		MdiEntry entry = mdi.getEntry("Cat."
+				+ Base32.encode(category.getName().getBytes()));
+
+		if (entry != null) {
+			entry.close(true);
+		}
+	}
+
+	protected static void updateDMCounts(DownloadManager dm) {
+		boolean isSeeding;
+		boolean isDownloading;
+		boolean isStopped;
+
+		Boolean wasSeedingB = (Boolean) dm.getUserData("wasSeeding");
+		boolean wasSeeding = wasSeedingB == null ? false
+				: wasSeedingB.booleanValue();
+		Boolean wasDownloadingB = (Boolean) dm.getUserData("wasDownloading");
+		boolean wasDownloading = wasDownloadingB == null ? false
+				: wasDownloadingB.booleanValue();
+		Boolean wasStoppedB = (Boolean) dm.getUserData("wasStopped");
+		boolean wasStopped = wasStoppedB == null ? false
+				: wasStoppedB.booleanValue();
+
+		if (dm.getAssumedComplete()) {
+			isSeeding = dm.getState() == DownloadManager.STATE_SEEDING;
+			isDownloading = false;
+		} else {
+			isDownloading = dm.getState() == DownloadManager.STATE_DOWNLOADING;
+			isSeeding = false;
+		}
+
+		isStopped = dm.getState() == DownloadManager.STATE_STOPPED;
+		boolean lowNoise = PlatformTorrentUtils.isAdvancedViewOnly(dm);
+
+		if (isDownloading != wasDownloading) {
+			if (isDownloading) {
+				statsWithLowNoise.numDownloading++;
+				if (!lowNoise) {
+					statsNoLowNoise.numDownloading++;
+				}
+			} else {
+				statsWithLowNoise.numDownloading--;
+				if (!lowNoise) {
+					statsNoLowNoise.numDownloading--;
+				}
+			}
+			dm.setUserData("wasDownloading", new Boolean(isDownloading));
+		}
+
+		if (isSeeding != wasSeeding) {
+			if (isSeeding) {
+				statsWithLowNoise.numSeeding++;
+				if (!lowNoise) {
+					statsNoLowNoise.numSeeding++;
+				}
+			} else {
+				statsWithLowNoise.numSeeding--;
+				if (!lowNoise) {
+					statsNoLowNoise.numSeeding--;
+				}
+			}
+			dm.setUserData("wasSeeding", new Boolean(isSeeding));
+		}
+
+		if (isStopped != wasStopped) {
+			if (isStopped) {
+				statsWithLowNoise.numStoppedAll++;
+				if (!dm.getAssumedComplete()) {
+					statsWithLowNoise.numStoppedIncomplete++;
+				}
+				if (!lowNoise) {
+					statsNoLowNoise.numStoppedAll++;
+					if (!dm.getAssumedComplete()) {
+						statsNoLowNoise.numStoppedIncomplete++;
+					}
+				}
+			} else {
+				statsWithLowNoise.numStoppedAll--;
+				if (!dm.getAssumedComplete()) {
+					statsWithLowNoise.numStoppedIncomplete--;
+				}
+				if (!lowNoise) {
+					statsNoLowNoise.numStoppedAll--;
+					if (!dm.getAssumedComplete()) {
+						statsNoLowNoise.numStoppedIncomplete--;
+					}
+				}
+			}
+			dm.setUserData("wasStopped", new Boolean(isStopped));
+		}
+
+	}
+
+	private static void recountUnopened() {
+		if (!AzureusCoreFactory.isCoreRunning()) {
+			return;
+		}
+		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+		List<?> dms = gm.getDownloadManagers();
+		statsNoLowNoise.numUnOpened = 0;
+		for (Iterator<?> iter = dms.iterator(); iter.hasNext();) {
+			DownloadManager dm = (DownloadManager) iter.next();
+			if (!PlatformTorrentUtils.getHasBeenOpened(dm) && dm.getAssumedComplete()) {
+				statsNoLowNoise.numUnOpened++;
+			}
+		}
+		statsWithLowNoise.numUnOpened = statsNoLowNoise.numUnOpened;
+	}
+
+	protected static void addCountRefreshListener(countRefreshListener l) {
+		l.countRefreshed(statsWithLowNoise, statsNoLowNoise);
+		listeners.add(l);
+	}
+
+	public static void triggerCountRefreshListeners() {
+		for (countRefreshListener l : listeners) {
+			l.countRefreshed(statsWithLowNoise, statsNoLowNoise);
+		}
+	}
+
+	/**
+	 * 
+	 *
+	 * @since 3.1.1.1
+	 */
+
+	private static FrequencyLimitedDispatcher refresh_limiter = new FrequencyLimitedDispatcher(
+			new AERunnable() {
+				public void runSupport() {
+					refreshAllLibrariesSupport();
+				}
+			}, 250);
+
+	static {
+		refresh_limiter.setSingleThreaded();
+	}
+
+	private static void refreshAllLibraries() {
+		refresh_limiter.dispatch();
+	}
+
+	private static void refreshAllLibrariesSupport() {
+		for (countRefreshListener l : listeners) {
+			l.countRefreshed(statsWithLowNoise, statsNoLowNoise);
+		}
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		if (mdi == null) {
+			return;
+		}
+
+		if (statsNoLowNoise.numIncomplete > 0) {
+			MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
+			if (entry == null) {
+				mdi.loadEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY_DL, false);
+			}
+		} else {
+			MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
+			if (entry != null) {
+				entry.close(true);
+			}
+		}
+		MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_DL);
+		if (entry != null) {
+			MdiEntryVitalityImage[] vitalityImages = entry.getVitalityImages();
+			for (int i = 0; i < vitalityImages.length; i++) {
+				MdiEntryVitalityImage vitalityImage = vitalityImages[i];
+				String imageID = vitalityImage.getImageID();
+				if (imageID == null) {
+					continue;
+				}
+				if (imageID.equals(ID_VITALITY_ACTIVE)) {
+					vitalityImage.setVisible(statsNoLowNoise.numDownloading > 0);
+
+				} else if (imageID.equals(ID_VITALITY_ALERT)) {
+					vitalityImage.setVisible(statsNoLowNoise.numErrorInComplete > 0);
+					if (statsNoLowNoise.numErrorInComplete > 0) {
+						vitalityImage.setToolTip(statsNoLowNoise.errorInCompleteTooltip);
+					}
+				}
+			}
+			ViewTitleInfoManager.refreshTitleInfo(entry.getViewTitleInfo());
+		}
+
+		entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_CD);
+		if (entry != null) {
+			MdiEntryVitalityImage[] vitalityImages = entry.getVitalityImages();
+			for (int i = 0; i < vitalityImages.length; i++) {
+				MdiEntryVitalityImage vitalityImage = vitalityImages[i];
+				String imageID = vitalityImage.getImageID();
+				if (imageID == null) {
+					continue;
+				}
+				if (imageID.equals(ID_VITALITY_ALERT)) {
+					vitalityImage.setVisible(statsNoLowNoise.numErrorComplete > 0);
+					if (statsNoLowNoise.numErrorComplete > 0) {
+						vitalityImage.setToolTip(statsNoLowNoise.errorCompleteTooltip);
+					}
+				}
+			}
+		}
+
+		entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_LIBRARY_UNOPENED);
+		if (entry != null) {
+			ViewTitleInfoManager.refreshTitleInfo(entry.getViewTitleInfo());
+		}
+	}
+
+	public static String getTableIdFromFilterMode(int torrentFilterMode,
+			boolean big) {
+		if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE) {
+			return big ? TableManager.TABLE_MYTORRENTS_COMPLETE_BIG
+					: TableManager.TABLE_MYTORRENTS_COMPLETE;
+		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE) {
+			return big ? TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG
+					: TableManager.TABLE_MYTORRENTS_INCOMPLETE;
+		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
+			return TableManager.TABLE_MYTORRENTS_ALL_BIG;
+		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
+			return big ? TableManager.TABLE_MYTORRENTS_UNOPENED_BIG
+					: TableManager.TABLE_MYTORRENTS_UNOPENED;
+		}
+		return null;
+	}
+
+	protected static interface countRefreshListener
+	{
+		public void countRefreshed(stats statsWithLowNoise, stats statsNoLowNoise);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SB_Vuze.java b/com/aelitis/azureus/ui/swt/views/skin/SB_Vuze.java
new file mode 100644
index 0000000..295b8f2
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/SB_Vuze.java
@@ -0,0 +1,135 @@
+package com.aelitis.azureus.ui.swt.views.skin;
+
+import java.util.ArrayList;
+
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoListener;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.*;
+import com.aelitis.azureus.ui.swt.views.ViewTitleInfoBetaP;
+
+public class SB_Vuze
+{
+	private ArrayList<MdiEntry> children = new ArrayList<MdiEntry>();
+
+	private ViewTitleInfo titleInfo;
+
+	public SB_Vuze(MultipleDocumentInterface mdi) {
+		setup(mdi);
+	}
+
+	private void setup(final MultipleDocumentInterface mdi) {
+		mdi.registerEntry(MultipleDocumentInterface.SIDEBAR_SECTION_BETAPROGRAM,
+				new MdiEntryCreationListener() {
+					public MdiEntry createMDiEntry(String id) {
+
+						final ViewTitleInfoBetaP viewTitleInfo = new ViewTitleInfoBetaP();
+
+						MdiEntry entry = mdi.createEntryFromSkinRef(
+								MultipleDocumentInterface.SIDEBAR_HEADER_VUZE,
+								MultipleDocumentInterface.SIDEBAR_SECTION_BETAPROGRAM,
+								"main.area.beta", "{Sidebar.beta.title}", viewTitleInfo, null,
+								true, MultipleDocumentInterface.SIDEBAR_POS_FIRST);
+
+						entry.setImageLeftID("image.sidebar.beta");
+
+						entry.addListener(new MdiCloseListener() {
+							public void mdiEntryClosed(MdiEntry entry, boolean userClosed) {
+								viewTitleInfo.clearIndicator();
+							}
+						});
+
+						return entry;
+					}
+				});
+
+		ViewTitleInfoManager.addListener(new ViewTitleInfoListener() {
+			public void viewTitleInfoRefresh(ViewTitleInfo titleInfo) {
+				MdiEntry childrenArray[] = children.toArray(new MdiEntry[0]);
+				for (MdiEntry entry : childrenArray) {
+					if (entry.getViewTitleInfo() == titleInfo) {
+						if (SB_Vuze.this.titleInfo != null) {
+							ViewTitleInfoManager.refreshTitleInfo(SB_Vuze.this.titleInfo);
+						}
+						break;
+					}
+				}
+			}
+		});
+
+		mdi.addListener(new MdiEntryLoadedListener() {
+			public void mdiEntryLoaded(MdiEntry entry) {
+				if (MultipleDocumentInterface.SIDEBAR_HEADER_VUZE.equals(entry.getParentID())) {
+					children.add(entry);
+					entry.addListener(new MdiChildCloseListener() {
+						public void mdiChildEntryClosed(MdiEntry parent, MdiEntry child,
+								boolean user) {
+							children.remove(child);
+						}
+					});
+				}
+				if (!entry.getId().equals(MultipleDocumentInterface.SIDEBAR_HEADER_VUZE)) {
+					return;
+				}
+				setupHeader(entry);
+			}
+		});
+	}
+
+	private void setupHeader(final MdiEntry entry) {
+
+		titleInfo = new ViewTitleInfo() {
+			public Object getTitleInfoProperty(int propertyID) {
+				if (propertyID == ViewTitleInfo.TITLE_INDICATOR_TEXT) {
+					if (entry.isExpanded()) {
+						return null;
+					}
+					StringBuilder sb = new StringBuilder();
+					MdiEntry[] entries = entry.getMDI().getEntries();
+					for (MdiEntry subEntry : entries) {
+						if (entry.getId().equals(subEntry.getParentID())) {
+							ViewTitleInfo titleInfo = subEntry.getViewTitleInfo();
+							if (titleInfo != null) {
+								Object text = titleInfo.getTitleInfoProperty(TITLE_INDICATOR_TEXT);
+								if (text instanceof String) {
+									if (sb.length() > 0) {
+										sb.append(" | ");
+									}
+									sb.append(text);
+								}
+							}
+						}
+					}
+					if (sb.length() > 0) {
+						return sb.toString();
+					}
+				} else if (propertyID == ViewTitleInfo.TITLE_INDICATOR_TEXT_TOOLTIP) {
+					if (entry.isExpanded()) {
+						return null;
+					}
+					StringBuilder sb = new StringBuilder();
+					MdiEntry[] entries = entry.getMDI().getEntries();
+					for (MdiEntry subEntry : entries) {
+						if (entry.getId().equals(subEntry.getParentID())) {
+							ViewTitleInfo titleInfo = subEntry.getViewTitleInfo();
+							if (titleInfo != null) {
+								Object text = titleInfo.getTitleInfoProperty(TITLE_INDICATOR_TEXT);
+								if (text instanceof String) {
+									if (sb.length() > 0) {
+										sb.append("\n");
+									}
+									sb.append(subEntry.getTitle() + ": " + text);
+								}
+							}
+						}
+					}
+					if (sb.length() > 0) {
+						return sb.toString();
+					}
+				}
+				return null;
+			}
+		};
+		entry.setViewTitleInfo(titleInfo);
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java b/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
index 59865f0..9378ccb 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SearchResultsTabArea.java
@@ -21,54 +21,44 @@
 package com.aelitis.azureus.ui.swt.views.skin;
 
 import java.io.File;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Map;
+import java.util.*;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.*;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
+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.*;
 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;
-import org.gudy.azureus2.plugins.ui.menus.*;
-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;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.*;
 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.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.*;
 import com.aelitis.azureus.ui.skin.SkinConstants;
-import com.aelitis.azureus.ui.swt.browser.BrowserContext;
-import com.aelitis.azureus.ui.swt.browser.CookiesListener;
-import com.aelitis.azureus.ui.swt.browser.OpenCloseSearchDetailsListener;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.browser.*;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
 import com.aelitis.azureus.ui.swt.browser.listener.ExternalLoginCookieListener;
 import com.aelitis.azureus.ui.swt.browser.listener.MetaSearchListener;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 import com.aelitis.azureus.ui.swt.skin.*;
-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;
-import com.aelitis.azureus.util.MapUtils;
-import com.aelitis.azureus.util.UrlFilter;
+import com.aelitis.azureus.util.*;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.menus.*;
+import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 
 /**
  * @author TuxPaper
@@ -77,23 +67,28 @@ import com.aelitis.azureus.util.UrlFilter;
  */
 public class SearchResultsTabArea
 	extends SkinView
-	implements ViewTitleInfo, OpenCloseSearchDetailsListener
+	implements OpenCloseSearchDetailsListener
 {
 	private SWTSkinObjectBrowser browserSkinObject;
 
 	private SWTSkin skin;
 
-	private String searchText;
-
 	private boolean searchResultsInitialized = false;
 
 	protected String title;
+	
+	private MdiEntryVitalityImage vitalityImage;
 
-	private MenuItem menuItem;
-
-	private SideBarVitalityImage vitalityImage;
+	private boolean menu_added;
+	
+	public SearchQuery sq;
 
 	public static class SearchQuery {
+		public SearchQuery(String term, boolean toSubscribe) {
+			this.term = term;
+			this.toSubscribe = toSubscribe;
+		}
+
 		public String term;
 		public boolean toSubscribe;
 	}
@@ -149,17 +144,8 @@ public class SearchResultsTabArea
 			}
 		});
 		
-		if (browserSkinObject != null) {
-			Object o = skinObject.getData("CreationParams");
-
-			if(o instanceof String) {
-				anotherSearch((String) o);
-			}
-			
-			if(o instanceof SearchQuery) {
-				SearchQuery sq = (SearchQuery) o;
-				anotherSearch(sq.term,sq.toSubscribe);
-			}
+		if (sq != null) {
+			anotherSearch(sq);
 		}
 		
 		closeSearchResults(null);
@@ -173,18 +159,20 @@ public class SearchResultsTabArea
 		
 		final MenuManager menuManager = uim.getMenuManager();
 
-		if ( menuItem == null ){
-		
-			menuItem = menuManager.addMenuItem("sidebar.Search","Search.menu.engines");
+		if ( !menu_added ){
+			
+			menu_added = true;
+			
+			final MenuItem template_menu = menuManager.addMenuItem("sidebar.Search","Search.menu.engines");
 		
-			menuItem.setStyle( MenuItem.STYLE_MENU );
+			template_menu.setStyle( MenuItem.STYLE_MENU );
 			
-			menuItem.addFillListener(
+			template_menu.addFillListener(
 				new MenuItemFillListener()
 				{
 					public void menuWillBeShown(MenuItem menu, Object data) {
 				
-						menuItem.removeAllChildItems();
+						template_menu.removeAllChildItems();
 						
 						Engine[] engines = MetaSearchManagerFactory.getSingleton().getMetaSearch().getEngines( true, false );
 						
@@ -205,11 +193,11 @@ public class SearchResultsTabArea
 							
 							final Engine engine = engines[i];
 							
-							MenuItem engine_menu = menuManager.addMenuItem( menuItem, "!" + engine.getName() + "!" );
+							MenuItem engine_menu = menuManager.addMenuItem( template_menu, "!" + engine.getName() + "!" );
 							
 							engine_menu.setStyle( MenuItem.STYLE_MENU );
 
-							if ( engine.getSource() != Engine.ENGINE_SOURCE_VUZE ){
+							if ( true || engine.getSource() != Engine.ENGINE_SOURCE_VUZE ){
 								
 								MenuItem mi = menuManager.addMenuItem( engine_menu, "MyTorrentsView.menu.exportmenu" );
 
@@ -337,9 +325,27 @@ public class SearchResultsTabArea
 								MenuItem mi = menuManager.addMenuItem( engine_menu, "Subscription.menu.sep" );
 
 								mi.setStyle( MenuItem.STYLE_SEPARATOR );
-							}
+							}		
+															
+							MenuItem mi = menuManager.addMenuItem( engine_menu, "Button.remove" );
+	
+							mi.addListener(
+								new MenuItemListener()
+								{
+									public void 
+									selected(
+										MenuItem menu, 
+										Object target) 
+									{
+										engine.setSelectionState( Engine.SEL_STATE_DESELECTED );
+									}
+								});
 							
-							MenuItem mi = menuManager.addMenuItem( engine_menu, "Subscription.menu.properties" );
+							mi = menuManager.addMenuItem( engine_menu, "Subscription.menu.sep2" );
+	
+							mi.setStyle( MenuItem.STYLE_SEPARATOR );
+							
+							mi = menuManager.addMenuItem( engine_menu, "Subscription.menu.properties" );
 
 							mi.addListener(
 								new MenuItemListener()
@@ -398,6 +404,68 @@ public class SearchResultsTabArea
 						}
 					}
 				});
+			
+			final MenuItem export_menu = menuManager.addMenuItem("sidebar.Search","search.export.all");
+			
+			
+			export_menu.setStyle( MenuItem.STYLE_PUSH );
+			
+			export_menu.addListener(
+				new MenuItemListener()
+				{
+					public void 
+					selected(
+						MenuItem menu, 
+						Object target) 
+					{
+						final Shell shell = Utils.findAnyShell();
+						
+						shell.getDisplay().asyncExec(
+							new AERunnable() 
+							{
+								public void 
+								runSupport()
+								{
+									FileDialog dialog = 
+										new FileDialog( shell, SWT.SYSTEM_MODAL | SWT.SAVE );
+									
+									dialog.setFilterPath( TorrentOpener.getFilterPathData() );
+															
+									dialog.setText(MessageText.getString("metasearch.export.select.template.file"));
+									
+									dialog.setFilterExtensions(new String[] {
+											"*.vuze",
+											"*.vuz",
+											org.gudy.azureus2.core3.util.Constants.FILE_WILDCARD
+										});
+									dialog.setFilterNames(new String[] {
+											"*.vuze",
+											"*.vuz",
+											org.gudy.azureus2.core3.util.Constants.FILE_WILDCARD
+										});
+									
+									String path = TorrentOpener.setFilterPathData( dialog.open());
+				
+									if ( path != null ){
+										
+										String lc = path.toLowerCase();
+										
+										if ( !lc.endsWith( ".vuze" ) && !lc.endsWith( ".vuz" )){
+											
+											path += ".vuze";
+										}
+										
+										try{
+											MetaSearchManagerFactory.getSingleton().getMetaSearch().exportEngines(  new File( path ));
+											
+										}catch( Throwable e ){
+											
+											Debug.out( e );
+										}
+									}
+								}
+							});							}
+				});
 		}
 	}
 
@@ -409,12 +477,14 @@ public class SearchResultsTabArea
 		browserSkinObject.getContext().addMessageListener(
 				new MetaSearchListener(this));
 		
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			final SideBarEntrySWT entry = sidebar.getEntryBySkinView(this);
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			final MdiEntry entry = mdi.getEntryBySkinView(this);
 			if (entry != null) {
 				vitalityImage = entry.addVitalityImage("image.sidebar.vitality.dots");
-				vitalityImage.setVisible(false);
+				if ( vitalityImage != null ){
+					vitalityImage.setVisible(false);
+				}
 			}
 		}
 		browserSkinObject.addListener(new loadingListener() {
@@ -453,12 +523,12 @@ public class SearchResultsTabArea
 					if (soSearchResults != null) {
 						SWTSkinObjectBrowser browserSkinObject = (SWTSkinObjectBrowser) soSearchResults;
 
-						final Browser browser = browserSkinObject.getBrowser();
+						final BrowserWrapper browser = browserSkinObject.getBrowser();
 						
 						browser.addTitleListener(new TitleListener() {
 							public void changed(TitleEvent event) {
 								if (event.widget.isDisposed()
-										|| ((Browser) event.widget).getShell().isDisposed()) {
+										|| browser.getShell().isDisposed()) {
 									return;
 								}
 								title = event.title;
@@ -491,7 +561,7 @@ public class SearchResultsTabArea
 
 				Control controlTop = browserSkinObject.getControl();
 				Control controlBottom = soSearchResults.getControl();
-				Browser search = ((SWTSkinObjectBrowser) soSearchResults).getBrowser();
+				final BrowserWrapper search = ((SWTSkinObjectBrowser) soSearchResults).getBrowser();
 				String url = MapUtils.getMapString(params, "url",
 						"http://google.com/search?q=" + Math.random());
 				if (UrlFilter.getInstance().urlCanRPC(url)) {
@@ -507,7 +577,7 @@ public class SearchResultsTabArea
 						}
 
 						public void completed(ProgressEvent event) {
-							Browser search = (Browser) event.widget;
+							
 							String execAfterLoad = (String) search.getData("execAfterLoad");
 							//Erase it, so that it's only used once after the page loads
 							search.setData("execAfterLoad", null);
@@ -533,15 +603,16 @@ public class SearchResultsTabArea
 				gd.top = new FormAttachment(controlTop, 0);
 				gd.height = SWT.DEFAULT;
 				controlBottom.setLayoutData(gd);
-				soSearchResults.setVisible(true);
-				controlBottom.setVisible(true);
-				search.setVisible(true);
 
 				gd = (FormData) controlTop.getLayoutData();
 				gd.bottom = null;
 				gd.height = MapUtils.getMapInt(params, "top-height", 120);
 				controlTop.setLayoutData(gd);
 
+				soSearchResults.setVisible(true);
+				controlBottom.setVisible(true);
+				search.setVisible(true);
+
 				controlTop.getParent().layout(true);
 			}
 		});
@@ -559,7 +630,7 @@ public class SearchResultsTabArea
 
 				Control controlTop = browserSkinObject.getControl();
 				Control controlBottom = soSearchResults.getControl();
-				Browser search = ((SWTSkinObjectBrowser) soSearchResults).getBrowser();
+				BrowserWrapper search = ((SWTSkinObjectBrowser) soSearchResults).getBrowser();
 
 				soSearchResults.setVisible(false);
 
@@ -577,7 +648,9 @@ public class SearchResultsTabArea
 				controlTop.setLayoutData(gd);
 
 				controlBottom.getParent().layout(true);
-				search.setUrl("about:blank");
+				if (search != null) {
+					search.setUrl("about:blank");
+				}
 				
 				BrowserContext context = browserSkinObject.getContext();
 				if (context != null) {
@@ -597,33 +670,67 @@ public class SearchResultsTabArea
 		
 	}
 
-	public void anotherSearch(String searchText) {
-		anotherSearch(searchText,false);
+	public Object dataSourceChanged(SWTSkinObject skinObject, Object params) {
+		if (params instanceof SearchQuery) {
+			sq = (SearchQuery) params;
+			if (browserSkinObject != null) {
+				anotherSearch(sq.term, sq.toSubscribe);
+			}
+		}
+
+		return null;
 	}
-	
+
 	public void anotherSearch(String searchText,boolean toSubscribe) {
-		this.searchText = searchText;
+		anotherSearch(new SearchQuery(searchText, toSubscribe));
+	}
+	
+	public void anotherSearch(SearchQuery sq) {
+		this.sq = sq;
 		String url = 
-			ConstantsVuze.getDefaultContentNetwork().getSearchService( searchText );
+			ConstantsVuze.getDefaultContentNetwork().getSearchService( sq.term );
 
 		if (System.getProperty("metasearch", "1").equals("1")) {
 			
-			url = ConstantsVuze.getDefaultContentNetwork().getXSearchService( searchText, toSubscribe );
+			url = ConstantsVuze.getDefaultContentNetwork().getXSearchService( sq.term, sq.toSubscribe );
 		}
 
 		closeSearchResults(null);
+		if (Utils.isThisThreadSWT()) {
+			try {
+  			browserSkinObject.getBrowser().setText("");
+  			final BrowserWrapper browser = browserSkinObject.getBrowser();
+  			final boolean[] done = {false};
+  			browser.addLocationListener(new LocationListener() {
+  				public void changing(LocationEvent event) {
+  				}
+  				
+  				public void changed(LocationEvent event) {
+  					done[0] = true;
+  					browser.removeLocationListener(this);
+  				}
+  			});
+  			browserSkinObject.getBrowser().setUrl("about:blank");
+  			browserSkinObject.getBrowser().refresh();
+  			browserSkinObject.getBrowser().update();
+  			Display display = Utils.getDisplay();
+  			long until = SystemTime.getCurrentTime() + 300;
+  			while (!done[0] && until > SystemTime.getCurrentTime()) {
+  				if (!display.readAndDispatch()) {
+  					display.sleep();
+  				}
+  			}
+			} catch (Throwable t) {
+				
+			}
+		}
 		browserSkinObject.setURL(url);
-		ViewTitleInfoManager.refreshTitleInfo(this);
-	}
 
-	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo#getTitleInfoProperty(int)
-	public Object getTitleInfoProperty(int propertyID) {
-		if (propertyID == TITLE_SKINVIEW) {
-			return this;
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		String id = "Search";
+		MdiEntry entry = mdi.getEntry(id);
+		if (entry != null) {
+			ViewTitleInfoManager.refreshTitleInfo(entry.getViewTitleInfo());
 		}
-		if (propertyID == TITLE_TEXT) {
-			return searchText;
-		}
-		return null;
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SkinView.java b/com/aelitis/azureus/ui/swt/views/skin/SkinView.java
index cf377ff..a198d9c 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SkinView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SkinView.java
@@ -21,9 +21,13 @@
 package com.aelitis.azureus.ui.swt.views.skin;
 
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 
 import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 import com.aelitis.azureus.ui.swt.skin.*;
 
 /**
@@ -58,7 +62,7 @@ public abstract class SkinView
 			try {
 				UIFunctionsManager.getUIFunctions().getUIUpdater().addUpdater(
 						updateable);
-			} catch (Exception e) {
+			} catch ( Throwable e) {
 				Debug.out(e);
 			}
 		}
@@ -120,6 +124,19 @@ public abstract class SkinView
 	public SWTSkinObject getMainSkinObject() {
 		return soMain;
 	}
+	
+	public Object skinObjectCreated(SWTSkinObject skinObject, Object params) {
+		SkinViewManager.add(this);
+
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			MdiEntry entry = mdi.getEntryFromSkinObject(skinObject);
+			if (entry != null && (this instanceof UIPluginViewToolBarListener)) {
+				entry.addToolbarEnabler((UIPluginViewToolBarListener) this);
+			}
+		}
+		return super.skinObjectCreated(skinObject, params);
+	}
 
 	final public void setMainSkinObject(SWTSkinObject main) {
 		if (soMain != null) {
@@ -128,8 +145,8 @@ public abstract class SkinView
 		soMain = main;
 		if (soMain != null) {
 			skin = soMain.getSkin();
+			soMain.setSkinView(this);
 		}
-		SkinViewManager.add(this);
 	}
 
 	final public SWTSkin getSkin() {
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SkinViewManager.java b/com/aelitis/azureus/ui/swt/views/skin/SkinViewManager.java
index c195860..6ee7786 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SkinViewManager.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SkinViewManager.java
@@ -26,7 +26,6 @@ import org.gudy.azureus2.core3.util.AEMonitor2;
 import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectListener;
 
 /**
  * Manages a list of SkinViews currently in use by the app
@@ -47,6 +46,8 @@ public class SkinViewManager
 	 */
 	private static Map<String, SkinView> skinIDs = new HashMap<String, SkinView>();
 	
+	private static Map<String, SkinView> skinViewIDs = new HashMap<String, SkinView>();
+
 	private static List listeners = new ArrayList();
 	
 	/**
@@ -69,6 +70,10 @@ public class SkinViewManager
 		SWTSkinObject mainSkinObject = skinView.getMainSkinObject();
 		if (mainSkinObject != null) {
 			skinIDs.put(mainSkinObject.getSkinObjectID(), skinView);
+			String viewID = mainSkinObject.getViewID();
+			if (viewID != null && viewID.length() > 0) {
+				skinViewIDs.put(viewID, skinView);
+			}
 		}
 
 		triggerViewAddedListeners(skinView);
@@ -95,6 +100,7 @@ public class SkinViewManager
 		SWTSkinObject mainSkinObject = skinView.getMainSkinObject();
 		if (mainSkinObject != null) {
 			skinIDs.remove(mainSkinObject.getSkinObjectID());
+			skinViewIDs.remove(mainSkinObject.getViewID());
 		}
 	}
 
@@ -159,6 +165,24 @@ public class SkinViewManager
 	}
 	
 	/**
+	 * Get the SkinView related to a View ID
+	 *  
+	 * @param viewID
+	 * @return
+	 */
+	public static SkinView getByViewID(String viewID) {
+		SkinView sv = skinViewIDs.get(viewID);
+		if (sv != null) {
+  		SWTSkinObject so = sv.getMainSkinObject();
+  		if (so != null && so.isDisposed()) {
+  			remove(sv);
+  			return null;
+  		}
+		}
+		return sv;
+	}
+	
+	/**
 	 * Listen in on SkinView adds
 	 * 
 	 * @param l
@@ -171,6 +195,21 @@ public class SkinViewManager
 		}
 	}
 	
+	public static void addListener(Class cla, SkinViewManagerListener l) {
+		synchronized (SkinViewManager.class) {
+			if (!listeners.contains(l)) {
+				listeners.add(l);
+			}
+		}
+
+		SkinView[] svs = SkinViewManager.getMultiByClass(cla);
+		if (svs != null) {
+			for (SkinView skinView : svs) {
+				l.skinViewAdded(skinView);
+			}
+		}
+	}
+	
 	public static void RemoveListener(SkinViewManagerListener l) {
 		synchronized (SkinViewManager.class) {
 			listeners.remove(l);
diff --git a/com/aelitis/azureus/ui/swt/views/skin/SkinnedDialog.java b/com/aelitis/azureus/ui/swt/views/skin/SkinnedDialog.java
index 5627fff..4bac043 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/SkinnedDialog.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/SkinnedDialog.java
@@ -25,6 +25,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.widgets.Shell;
 
+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.shell.ShellFactory;
@@ -34,6 +35,8 @@ import com.aelitis.azureus.ui.swt.skin.SWTSkin;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinFactory;
 
 /**
+ * Creates a dialog (shell) and fills it with a skinned layout
+ * 
  * @author TuxPaper
  * @created Dec 23, 2008
  *
@@ -48,22 +51,33 @@ public class SkinnedDialog
 
 	private List<SkinnedDialogClosedListener> closeListeners = new CopyOnWriteArrayList<SkinnedDialogClosedListener>();
 
+	private Shell mainShell;
+
+	protected boolean disposed;
+
 	public SkinnedDialog(String skinFile, String shellSkinObjectID) {
 		this(skinFile, shellSkinObjectID, SWT.DIALOG_TRIM | SWT.RESIZE);
 	}
 
 	public SkinnedDialog(String skinFile, String shellSkinObjectID, int style) {
+		this(SkinnedDialog.class.getClassLoader(), "com/aelitis/azureus/ui/skin/",
+				skinFile, shellSkinObjectID, style);
+	}
+
+	public SkinnedDialog(ClassLoader cla, String skinPath, String skinFile,
+			String shellSkinObjectID, int style) {
 		this.shellSkinObjectID = shellSkinObjectID;
 
-		Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
+		mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
 		shell = ShellFactory.createShell(mainShell, style);
 
 		Utils.setShellIcon(shell);
 
-		skin = SWTSkinFactory.getNonPersistentInstance(
-				SkinnedDialog.class.getClassLoader(), "com/aelitis/azureus/ui/skin/",
+		SWTSkin skin = SWTSkinFactory.getNonPersistentInstance(cla, skinPath,
 				skinFile + ".properties");
 
+		setSkin(skin);
+
 		skin.initialize(shell, shellSkinObjectID);
 
 		shell.addTraverseListener(new TraverseListener() {
@@ -77,22 +91,38 @@ public class SkinnedDialog
 		shell.addDisposeListener(new DisposeListener() {
 			public void widgetDisposed(DisposeEvent e) {
 				//skin.destroy;
-				for (SkinnedDialogClosedListener l : closeListeners) {
-					try {
-						l.skinDialogClosed(SkinnedDialog.this);
-					} catch (Exception e2) {
-						Debug.out(e2);
+				disposed = true;
+				Utils.execSWTThreadLater(0, new AERunnable() {
+					public void runSupport() {
+						for (SkinnedDialogClosedListener l : closeListeners) {
+							try {
+								l.skinDialogClosed(SkinnedDialog.this);
+							} catch (Exception e2) {
+								Debug.out(e2);
+							}
+						}
 					}
-				}
+				});
 			}
 		});
 
-		skin.layout();
+		disposed = false;
+	}
 
-		Utils.centerWindowRelativeTo(shell, mainShell);
+	protected void setSkin(SWTSkin _skin) {
+		skin = _skin;
 	}
 
 	public void open() {
+		if (disposed) {
+			Debug.out("can't opened disposed skinnedialog");
+			return;
+		}
+		skin.layout();
+
+		Utils.verifyShellRect(shell, true);
+		Utils.centerWindowRelativeTo(shell, mainShell);
+
 		shell.open();
 	}
 
@@ -106,7 +136,16 @@ public class SkinnedDialog
 	 * @since 4.0.0.5
 	 */
 	public void close() {
-		shell.close();
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (disposed) {
+					return;
+				}
+				if (shell != null && !shell.isDisposed()) {
+					shell.close();
+				}
+			}
+		});
 	}
 
 	public void addCloseListener(SkinnedDialogClosedListener l) {
@@ -124,7 +163,7 @@ public class SkinnedDialog
 	 * @since 4.0.0.5
 	 */
 	public void setTitle(String string) {
-		if (shell != null && !shell.isDisposed()) {
+		if (!disposed && shell != null && !shell.isDisposed()) {
 			shell.setText(string);
 		}
 	}
@@ -135,4 +174,8 @@ public class SkinnedDialog
 	public Shell getShell() {
 		return shell;
 	}
+	
+	public boolean isDisposed() {
+		return disposed || shell == null || shell.isDisposed();
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java b/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
index 6022ea1..46a7990 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/ToolBarView.java
@@ -18,6 +18,7 @@
 package com.aelitis.azureus.ui.swt.views.skin;
 
 import java.util.*;
+import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Rectangle;
@@ -28,44 +29,36 @@ import org.eclipse.swt.widgets.*;
 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.DownloadManagerListener;
 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.Debug;
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
+import org.gudy.azureus2.core3.util.FrequencyLimitedDispatcher;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarEnablerBase;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
 import org.gudy.azureus2.ui.swt.TorrentUtil;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.views.tableitems.mytorrents.RankItem;
-import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UIToolBarManagerCore;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.devices.DeviceManager;
-import com.aelitis.azureus.core.devices.DeviceManagerFactory;
-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.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.selectedcontent.*;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.devices.DeviceManagerUI;
-import com.aelitis.azureus.ui.swt.devices.TranscodeChooser;
-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.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+import com.aelitis.azureus.ui.swt.skin.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnablerSelectedContent;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
+import com.aelitis.azureus.ui.swt.toolbar.ToolBarItemSO;
 import com.aelitis.azureus.ui.swt.views.skin.SkinViewManager.SkinViewManagerListener;
-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.DLReferals;
 import com.aelitis.azureus.util.PlayUtils;
-
-import org.gudy.azureus2.plugins.ui.UIPluginView;
-import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import com.aelitis.azureus.util.StringCompareUtils;
 
 /**
  * @author TuxPaper
@@ -73,9 +66,14 @@ import org.gudy.azureus2.plugins.ui.tables.TableColumn;
  */
 public class ToolBarView
 	extends SkinView
+	implements UIToolBarManagerCore
 {
+	private static boolean DEBUG = false;
+
 	private static toolbarButtonListener buttonListener;
 
+	private Map<String, List<String>> mapGroupToItemIDs = new HashMap<String, List<String>>();
+	
 	private Map<String, ToolBarItem> items = new LinkedHashMap<String, ToolBarItem>();
 
 	//private GlobalManager gm;
@@ -86,17 +84,25 @@ public class ToolBarView
 
 	private SWTSkinObject skinObject;
 
+	private SWTSkinObject so0th;
 	private SWTSkinObject so2nd;
 
 	private SWTSkinObject soGap;
 
 	private boolean initComplete = false;
 
+	private ArrayList<ToolBarViewListener> listeners = new ArrayList<ToolBarViewListener>(
+			1);
+
 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#showSupport(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectInitialShow(final SWTSkinObject skinObject,
 			Object params) {
+		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals(
+				"az2");
+
 		this.skinObject = skinObject;
 		buttonListener = new toolbarButtonListener();
+		so0th = skinObject.getSkin().getSkinObject("global-toolbar-0th");
 		so2nd = skinObject.getSkin().getSkinObject("global-toolbar-2nd");
 
 		soGap = skinObject.getSkin().getSkinObject("toolbar-gap");
@@ -114,162 +120,165 @@ public class ToolBarView
 			}
 		}
 
-		ToolBarItem item;
+		ToolBarItemSO item;
 
-		// ==download
-		item = new ToolBarItem("download", "image.button.download",
-				"v3.MainWindow.button.download") {
-			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItem()
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
-				}
-				// This is for our CDP pages
-				ISelectedContent[] sc = SelectedContentManager.getCurrentlySelectedContent();
-				if (sc != null && sc.length == 1
-						&& (sc[0].getHash() != null || sc[0].getDownloadInfo() != null)) {
-					TorrentListViewsUtils.downloadDataSource(sc[0], false,
-							DLReferals.DL_REFERAL_TOOLBAR);
+		if (!uiClassic) {
+			
+			// ==OPEN
+			item = new ToolBarItemSO(this, "open", "image.toolbar.open", "Button.add");
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
+					}
+					TorrentOpener.openTorrentWindow( false );
+					return true;
 				}
-			}
-		};
-		addToolBarItem(item);
-
-		// ==play
-		item = new ToolBarItem("play", "image.button.play", "iconBar.play") {
-			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItem()
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
+			});
+			item.setAlwaysAvailable(true);
+			item.setGroupID( GROUP_BIG );
+			addToolBarItem(item, "toolbar.area.0item", so0th);		
+			
+			// ==download
+			item = new ToolBarItemSO(this, "download", "image.button.download",
+					"v3.MainWindow.button.download");
+			item.setGroupID(GROUP_BIG);
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
+					}
+					// This is for our CDP pages
+					ISelectedContent[] sc = SelectedContentManager.getCurrentlySelectedContent();
+					if (sc != null && sc.length == 1
+							&& (sc[0].getHash() != null || sc[0].getDownloadInfo() != null)) {
+						TorrentListViewsUtils.downloadDataSource(sc[0], false,
+								DLReferals.DL_REFERAL_TOOLBAR);
+						return true;
+					}
+					return false;
 				}
-				ISelectedContent[] sc = SelectedContentManager.getCurrentlySelectedContent();
-				if (sc != null) {
-					TorrentListViewsUtils.playOrStreamDataSource(sc[0],
-							this.getSkinButton(), DLReferals.DL_REFERAL_TOOLBAR);
+			});
+			addToolBarItem(item, "toolbar.area.item", soMain);
+
+			// ==play
+			item = new ToolBarItemSO(this, "play", "image.button.play",
+					"iconBar.play");
+			item.setGroupID(GROUP_BIG);
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
+					}
+					ISelectedContent[] sc = SelectedContentManager.getCurrentlySelectedContent();
+					if (sc != null && sc.length > 0) {
+
+						if (PlayUtils.canStreamDS(sc[0], sc[0].getFileIndex())) {
+							TorrentListViewsUtils.playOrStreamDataSource(sc[0],
+									DLReferals.DL_REFERAL_TOOLBAR, true, false);
+						} else {
+							TorrentListViewsUtils.playOrStreamDataSource(sc[0],
+									DLReferals.DL_REFERAL_TOOLBAR, false, true);
+						}
+					}
+					return false;
 				}
-			}
-		};
-		addToolBarItem(item);
+			});
+			addToolBarItem(item, "toolbar.area.item", soMain);
 
-		addSeperator("toolbar.area.item.sep", soMain);
+			addSeperator("toolbar.area.item.sep", soMain);
 
-		lastControl = null;
-		
-		boolean first = true; 
-
-		// ==OPEN
-		//		item = new ToolBarItem("open", "image.toolbar.open", "iconBar.open") {
-		//			public void triggerToolBarItem() {
-		//				TorrentOpener.openTorrentWindow();
-		//			}
-		//		};
-		//		addToolBarItem(item);
-
-		// ==transcode
-		if (!DeviceManagerUI.DISABLED) {
-  		item = new ToolBarItem("transcode", "image.button.transcode",
-  				"iconBar.transcode") {
-  			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItem()
-  			public void triggerToolBarItem() {
-  				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-  				if (viewID == null && triggerIViewToolBar(getId())) {
-  					return;
-  				}
-  				final ISelectedContent[] contents = SelectedContentManager.getCurrentlySelectedContent();
-  				if (contents.length == 0) {
-  					return;
-  				}
-  				TranscodeChooser deviceChooser = new TranscodeChooser() {
-  					public void closed() {
-  						DeviceManager deviceManager = DeviceManagerFactory.getSingleton();
-  						if (selectedTranscodeTarget != null && selectedProfile != null) {
-  							for (int i = 0; i < contents.length; i++) {
-  								ISelectedContent selectedContent = contents[i];
-  
-  								DownloadManager dm = selectedContent.getDownloadManager();
-  								if (dm == null) {
-  									continue;
-  								}
-  								DiskManagerFileInfo[] files = dm.getDiskManagerFileInfo();
-  								for (DiskManagerFileInfo file : files) {
-  									try {
-  										deviceManager.getTranscodeManager().getQueue().add(
-  												selectedTranscodeTarget,
-  												selectedProfile,
-  												(org.gudy.azureus2.plugins.disk.DiskManagerFileInfo) PluginCoreUtils.convert(
-  														file, false));
-  									} catch (TranscodeException e) {
-  										Debug.out(e);
-  									}
-  								}
-  							}
-  						}
-  					}
-  				};
-  				deviceChooser.show();
-  			}
-  		};
-  		addToolBarItem(item, "toolbar.area.sitem.left", so2nd);
-  		addSeperator(so2nd);
-  		first = false;
+			lastControl = null;
+
+		} else {
+
+			lastControl = null;
+
+			// ==OPEN
+			item = new ToolBarItemSO(this, "open", "image.toolbar.open", "Button.add");
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
+					}
+					TorrentOpener.openTorrentWindow( false );
+					return true;
+				}
+			});
+			item.setAlwaysAvailable(true);
+			item.setGroupID("classic");
+			addToolBarItemNoCreate(item);
+
+			// ==SEARCH
+			item = new ToolBarItemSO(this, "search", "search", "Button.search");
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
+					}
+					UIFunctionsManagerSWT.getUIFunctionsSWT().promptForSearch();
+					return true;
+				}
+			});
+			item.setAlwaysAvailable(true);
+			item.setGroupID("classic");
+			addToolBarItemNoCreate(item);
 		}
 
 		// ==run
-		item = new ToolBarItem("run", "image.toolbar.run", "iconBar.run") {
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
+		item = new ToolBarItemSO(this, "run", "image.toolbar.run", "iconBar.run");
+		item.setDefaultActivationListener(new UIToolBarActivationListener() {
+			public boolean toolBarItemActivated(ToolBarItem item,
+					long activationType, Object datasource) {
+				if (activationType != ACTIVATIONTYPE_NORMAL) {
+					return false;
 				}
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("start");
-					}
-				} else {
-					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-					if (dms != null) {
-						TorrentUtil.runTorrents(dms);
+				DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+				if (dms != null) {
+					TorrentUtil.runDataSources(dms);
 
-						for (int i = 0; i < dms.length; i++) {
-							DownloadManager dm = dms[i];
-							PlatformTorrentUtils.setHasBeenOpened(dm, true);
-						}
+					for (int i = 0; i < dms.length; i++) {
+						DownloadManager dm = dms[i];
+						PlatformTorrentUtils.setHasBeenOpened(dm, true);
 					}
+					return true;
 				}
+				return false;
 			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem", so2nd);
-		addSeperator(so2nd);
+		});
+		addToolBarItemNoCreate(item);
+		//addToolBarItem(item, "toolbar.area.sitem", so2nd);
+
+		if (uiClassic) {
+			// ==TOP
+			item = new ToolBarItemSO(this, "top", "image.toolbar.top", "iconBar.top");
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType == ACTIVATIONTYPE_NORMAL) {
+						return moveTop();
+					}
 
-		// ==UP
-		item = new ToolBarItem("up", "image.toolbar.up", "v3.iconBar.up") {
-			public void triggerToolBarItem() {
-				if (!AzureusCoreFactory.isCoreRunning()) {
-					return;
-				}
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
+					return false;
 				}
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("up");
+			});
+			addToolBarItemNoCreate(item);
+		}
+
+		// ==UP
+		item = new ToolBarItemSO(this, "up", "image.toolbar.up", "v3.iconBar.up");
+		item.setDefaultActivationListener(new UIToolBarActivationListener() {
+			public boolean toolBarItemActivated(ToolBarItem item,
+					long activationType, Object datasource) {
+				if (activationType == ACTIVATIONTYPE_NORMAL) {
+					if (!AzureusCoreFactory.isCoreRunning()) {
+						return false;
 					}
-				} else {
 					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
 					if (dms != null) {
 						Arrays.sort(dms, new Comparator<DownloadManager>() {
@@ -285,47 +294,25 @@ public class ToolBarView
 							}
 						}
 					}
+				} else if (activationType == ACTIVATIONTYPE_HELD) {
+					return moveTop();
 				}
+				return false;
 			}
-
-			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItemHold()
-			public boolean triggerToolBarItemHold() {
-				if (!AzureusCoreFactory.isCoreRunning()) {
-					return false;
-				}
-				GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-				DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-				if (dms != null) {
-					gm.moveTop(dms);
-				}
-				return true;
-			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem", so2nd);
-		addSeperator(so2nd);
+		});
+		addToolBarItemNoCreate(item);
 
 		// ==down
-		item = new ToolBarItem("down", "image.toolbar.down", "v3.iconBar.down") {
-			public void triggerToolBarItem() {
-				if (!AzureusCoreFactory.isCoreRunning()) {
-					return;
-				}
-
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
-				}
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("down");
+		item = new ToolBarItemSO(this, "down", "image.toolbar.down",
+				"v3.iconBar.down");
+		item.setDefaultActivationListener(new UIToolBarActivationListener() {
+			public boolean toolBarItemActivated(ToolBarItem item,
+					long activationType, Object datasource) {
+				if (activationType == ACTIVATIONTYPE_NORMAL) {
+					if (!AzureusCoreFactory.isCoreRunning()) {
+						return false;
 					}
-				} else {
+
 					GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
 					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
 					if (dms != null) {
@@ -340,161 +327,167 @@ public class ToolBarView
 								gm.moveDown(dm);
 							}
 						}
+						return true;
 					}
+				} else if (activationType == ACTIVATIONTYPE_HELD) {
+					return moveBottom();
 				}
+				return false;
 			}
-
-			// @see com.aelitis.azureus.ui.swt.toolbar.ToolBarItem#triggerToolBarItemHold()
-			public boolean triggerToolBarItemHold() {
-				if (!AzureusCoreFactory.isCoreRunning()) {
-					return false;
-				}
-
-				GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-				DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-				if (dms != null) {
-					gm.moveEnd(dms);
-				}
-				return true;
-			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem", so2nd);
-		addSeperator(so2nd);
-
-		// ==start
-		item = new ToolBarItem("start", "image.toolbar.start", "iconBar.start") {
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
-				}
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("start");
-					}
-				} else {
-					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-					if (dms != null) {
-						TorrentUtil.queueTorrents(dms, null);
+		});
+		addToolBarItemNoCreate(item);
+
+		if (uiClassic) {
+			// ==BOTTOM
+			item = new ToolBarItemSO(this, "bottom", "image.toolbar.bottom",
+					"iconBar.bottom");
+			item.setDefaultActivationListener(new UIToolBarActivationListener() {
+				public boolean toolBarItemActivated(ToolBarItem item,
+						long activationType, Object datasource) {
+					if (activationType != ACTIVATIONTYPE_NORMAL) {
+						return false;
 					}
+					return moveBottom();
 				}
-			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem", so2nd);
-		//SWTSkinObjectContainer so = (SWTSkinObjectContainer) item.getSkinButton().getSkinObject();
-		//so.setDebugAndChildren(true);
-		addSeperator(so2nd);
-
-		// ==stop
-		item = new ToolBarItem("stop", "image.toolbar.stop", "iconBar.stop") {
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
-				}
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("stop");
+			});
+			addToolBarItemNoCreate(item);
+		}
+		/*
+				// ==start
+				item = new ToolBarItemSO(this, "start", "image.toolbar.start", "iconBar.start");
+				item.setDefaultActivation(new UIToolBarActivationListener() {
+					public boolean toolBarItemActivated(ToolBarItem item, long activationType) {
+						if (activationType != ACTIVATIONTYPE_NORMAL) {
+							return false;
+						}
+						DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+						if (dms != null) {
+							TorrentUtil.queueDataSources(dms, true);
+							return true;
+						}
+						return false;
 					}
-				} else {
-					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-					if (dms != null) {
-						TorrentUtil.stopTorrents(dms, null);
+				});
+				addToolBarItem(item, "toolbar.area.sitem", so2nd);
+				//SWTSkinObjectContainer so = (SWTSkinObjectContainer) item.getSkinButton().getSkinObject();
+				//so.setDebugAndChildren(true);
+				addSeperator(so2nd);
+
+				// ==stop
+				item = new ToolBarItemSO(this, "stop", "image.toolbar.stop", "iconBar.stop");
+				item.setDefaultActivation(new UIToolBarActivationListener() {
+					public boolean toolBarItemActivated(ToolBarItem item, long activationType) {
+						if (activationType != ACTIVATIONTYPE_NORMAL) {
+							return false;
+						}
+		 				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
+						TorrentUtil.stopDataSources(currentContent);
+						return true;
 					}
+				});
+				addToolBarItem(item, "toolbar.area.sitem", so2nd);
+				addSeperator(so2nd);
+		*/
+		// ==startstop
+		item = new ToolBarItemSO(this, "startstop",
+				"image.toolbar.startstop.start", "iconBar.startstop");
+		item.setDefaultActivationListener(new UIToolBarActivationListener() {
+			public boolean toolBarItemActivated(ToolBarItem item,
+					long activationType, Object datasource) {
+				if (activationType != ACTIVATIONTYPE_NORMAL) {
+					return false;
 				}
+				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
+				TorrentUtil.stopOrStartDataSources(currentContent);
+				return true;
 			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem", so2nd);
-		addSeperator(so2nd);
+		});
+		addToolBarItemNoCreate(item);
 
 		// ==remove
-		item = new ToolBarItem("remove", "image.toolbar.remove", "iconBar.remove") {
-			public void triggerToolBarItem() {
-				String viewID = SelectedContentManager.getCurrentySelectedViewID();
-				if (viewID == null && triggerIViewToolBar(getId())) {
-					return;
+		item = new ToolBarItemSO(this, "remove", "image.toolbar.remove",
+				"iconBar.remove");
+		item.setDefaultActivationListener(new UIToolBarActivationListener() {
+			public boolean toolBarItemActivated(ToolBarItem item,
+					long activationType, Object datasource) {
+				if (activationType != ACTIVATIONTYPE_NORMAL) {
+					return false;
 				}
-				boolean isActivityView = "Activity".equals(viewID);
-
-				boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
-				ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
-				if (isIconBarEnabler && currentContent.length > 0
-						&& currentContent[0] != null
-						&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-					ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-					IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-					if (enabler != null) {
-						enabler.itemActivated("remove");
-					}
-				} else if (isActivityView) {
-					SkinView view = SkinViewManager.getBySkinObjectID("Activity");
-					if (view instanceof SBC_ActivityView) {
-						SBC_ActivityView viewActivity = (SBC_ActivityView) view;
-						viewActivity.removeSelected();
-					}
-				} else {
-					DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-					TorrentListViewsUtils.removeDownloads(dms);
+				DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+				if (dms != null) {
+					TorrentUtil.removeDownloads(dms, null);
+					return true;
 				}
+				return false;
 			}
-		};
-		addToolBarItem(item, "toolbar.area.sitem.right", so2nd);
+		});
+		addToolBarItemNoCreate(item);
 
 		///////////////////////
 
-		addSeperator("toolbar.area.item.sep3", so2nd);
-
-		addNonToolBar("toolbar.area.sitem.left2", so2nd);
-
 		// == mode big
-		item = new ToolBarItem("modeBig", "image.toolbar.table_large",
-				"v3.iconBar.view.big");
-		addToolBarItem(item, "toolbar.area.vitem.left", so2nd);
-		item.setEnabled(false);
-
-		Control bigItem = item.getSkinButton().getSkinObject().getControl();
-		SWTSkinObject soTitle = skin.getSkinObject("toolbar-item-title",
-				item.getSkinButton().getSkinObject());
-		if (soTitle instanceof SWTSkinObjectText) {
-			((SWTSkinObjectText) soTitle).setStyle(SWT.RIGHT);
-		}
-
-		addSeperator(so2nd);
+		item = new ToolBarItemSO(this, "modeBig", "image.toolbar.table_large",
+				"v3.iconBar.view.big") {
+			public void setSkinButton(SWTSkinButtonUtility btn) {
+				super.setSkinButton(btn);
+				SWTSkinObject soTitle = skin.getSkinObject("toolbar-item-title",
+						btn.getSkinObject());
+				if (soTitle instanceof SWTSkinObjectText) {
+					((SWTSkinObjectText) soTitle).setStyle(SWT.RIGHT);
+				}
+			}
+		};
+		item.setGroupID("views");
+		addToolBarItemNoCreate(item);
 
 		// == mode small
-		item = new ToolBarItem("modeSmall", "image.toolbar.table_normal",
-				"v3.iconBar.view.small");
-		addToolBarItem(item, "toolbar.area.vitem.right", so2nd);
-		item.setEnabled(false);
+		item = new ToolBarItemSO(this, "modeSmall", "image.toolbar.table_normal",
+				"v3.iconBar.view.small") {
+			
+			public void setSkinButton(SWTSkinButtonUtility btn) {
+				super.setSkinButton(btn);
+				SWTSkinObject soTitle = skin.getSkinObject("toolbar-item-title",
+						btn.getSkinObject());
+				if (soTitle instanceof SWTSkinObjectText) {
+					((SWTSkinObjectText) soTitle).setStyle(SWT.LEFT);
+				}
+			}
+		};
+		item.setGroupID("views");
+		addToolBarItemNoCreate(item);
 
-		Control smallItem = item.getSkinButton().getSkinObject().getControl();
+		
+		//addSeperator(so2nd);
 
-		soTitle = skin.getSkinObject("toolbar-item-title",
-				item.getSkinButton().getSkinObject());
-		if (soTitle instanceof SWTSkinObjectText) {
-			((SWTSkinObjectText) soTitle).setStyle(SWT.LEFT);
+		if (uiClassic) {
+			bulkSetupItems("classic", "toolbar.area.sitem", so2nd);
+			addNonToolBar("toolbar.area.sitem.left2", so2nd);
 		}
-
-		//addSeperator(so2nd);
+		bulkSetupItems(GROUP_MAIN, "toolbar.area.sitem", so2nd);
+		addNonToolBar("toolbar.area.sitem.left2", so2nd);
+		bulkSetupItems("views", "toolbar.area.vitem", so2nd);
+		addNonToolBar("toolbar.area.sitem.left2", so2nd);
 
 		resizeGap();
 
 		SelectedContentManager.addCurrentlySelectedContentListener(new SelectedContentListener() {
+			String lastViewID = null;
 			public void currentlySelectedContentChanged(
 					ISelectedContent[] currentContent, String viewID) {
-				updateCoreItems(currentContent, viewID);
+				if (!StringCompareUtils.equals(lastViewID, viewID)) {
+					lastViewID = viewID;
+					ToolBarItem[] allToolBarItems = getAllSWTToolBarItems();
+					for (int i = 0; i < allToolBarItems.length; i++) {
+						UIToolBarItem toolBarItem = allToolBarItems[i];
+						if (toolBarItem instanceof ToolBarItemSO) {
+							toolBarItem.setState(((ToolBarItemSO) toolBarItem).getDefaultState());
+						} else {
+							toolBarItem.setState(0);
+						}
+					}
+				}
+				refreshCoreToolBarItems();
+				//updateCoreItems(currentContent, viewID);
 				UIFunctionsManagerSWT.getUIFunctionsSWT().refreshTorrentMenu();
 			}
 		});
@@ -509,9 +502,66 @@ public class ToolBarView
 
 		initComplete = true;
 
+		synchronized (listeners) {
+			for (ToolBarViewListener l : listeners) {
+				try {
+					l.toolbarViewInitialized(this);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+
 		return null;
 	}
 
+	public boolean triggerToolBarItem(ToolBarItem item, long activationType,
+			Object datasource) {
+		if (triggerViewToolBar(item, activationType, datasource)) {
+			return true;
+		}
+
+		UIToolBarActivationListener defaultActivation = item.getDefaultActivationListener();
+		if (defaultActivation != null) {
+			return defaultActivation.toolBarItemActivated(item, activationType,
+					datasource);
+		}
+
+		if (DEBUG) {
+			String viewID = SelectedContentManager.getCurrentySelectedViewID();
+			System.out.println("Warning: Fallback of toolbar button " + item.getID()
+					+ " via " + viewID + " view");
+		}
+
+		return false;
+	}
+
+	protected boolean moveBottom() {
+		if (!AzureusCoreFactory.isCoreRunning()) {
+			return false;
+		}
+
+		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+		DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+		if (dms != null) {
+			gm.moveEnd(dms);
+		}
+		return true;
+	}
+
+
+	protected boolean moveTop() {
+		if (!AzureusCoreFactory.isCoreRunning()) {
+			return false;
+		}
+		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+		DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
+		if (dms != null) {
+			gm.moveTop(dms);
+		}
+		return true;
+	}
+
 	/**
 	 * 
 	 *
@@ -540,335 +590,425 @@ public class ToolBarView
 		soGap.getControl().getParent().layout();
 	}
 
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	protected void updateCoreItems(ISelectedContent[] currentContent,
-			String viewID) {
-		String[] itemsNeedingSelection = {};
-
-		String[] itemsNeedingRealDMSelection = {
-			"remove",
-			"up",
-			"down",
-			"top",
-			"bottom",
-			"transcode",
-		};
+	public UIToolBarItem getToolBarItem(String itemID) {
+		return items.get(itemID);
+	}
 
-		String[] itemsRequiring1SelectionWithHash = {
-			"details",
-			"comment",
-		};
+	public ToolBarItemSO getToolBarItemSO(String itemID) {
+		return (ToolBarItemSO) items.get(itemID);
+	}
 
-		String[] itemsRequiring1DMSelection = {};
+	public UIToolBarItem[] getAllToolBarItems() {
+		return items.values().toArray(new ToolBarItem[0]);
+	}
+
+	public ToolBarItem[] getAllSWTToolBarItems() {
+		return items.values().toArray(new ToolBarItem[0]);
+	}
 
-		boolean isActivityView = "Activity".equals(viewID);
-		boolean isIconBarEnabler = "IconBarEnabler".equals(viewID);
+	private FrequencyLimitedDispatcher refresh_limiter = new FrequencyLimitedDispatcher(
+			new AERunnable() {
+				private AERunnable lock = this;
 
-		int numSelection = currentContent.length;
-		boolean hasSelection = numSelection > 0;
-		boolean has1Selection = numSelection == 1;
-		boolean has1SelectionWithHash = has1Selection
-				&& currentContent[0].getHash() != null;
+				private boolean refresh_pending;
 
-		ToolBarItem item;
-		for (int i = 0; i < itemsNeedingSelection.length; i++) {
-			String itemID = itemsNeedingSelection[i];
-			item = getToolBarItem(itemID);
+				public void runSupport() {
+					synchronized (lock) {
 
-			if (item != null) {
-				item.setEnabled(hasSelection);
-			}
-		}
+						if (refresh_pending) {
 
-		TableView tv = SelectedContentManager.getCurrentlySelectedTableView();
-		boolean hasRealDM = tv != null;
-		if (!hasRealDM) {
-			SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-			if (sidebar != null) {
-				SideBarEntrySWT entry = sidebar.getCurrentEntry();
-				if (entry != null) {
-					if (entry.datasource instanceof DownloadManager) {
-						hasRealDM = true;
-					} else if ((entry.iview instanceof UIPluginView)
-							&& (((UIPluginView) entry.iview).getDataSource() instanceof DownloadManager)) {
-						hasRealDM = true;
+							return;
+						}
+						refresh_pending = true;
 					}
-				}
-			}
-		}
 
-		DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
-		boolean isDMSelection = dms != null && dms.length > 0;
+					if (DEBUG) {
+						System.out.println("refreshCoreItems via "
+								+ Debug.getCompressedStackTrace());
+					}
 
-		for (int i = 0; i < itemsNeedingRealDMSelection.length; i++) {
-			String itemID = itemsNeedingRealDMSelection[i];
-			item = getToolBarItem(itemID);
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
 
-			if (item != null) {
-				item.setEnabled(hasSelection && isDMSelection && hasRealDM);
-			}
-		}
-		for (int i = 0; i < itemsRequiring1SelectionWithHash.length; i++) {
-			String itemID = itemsRequiring1SelectionWithHash[i];
-			item = getToolBarItem(itemID);
+							synchronized (lock) {
 
-			if (item != null) {
-				item.setEnabled(has1SelectionWithHash);
-			}
-		}
-		for (int i = 0; i < itemsRequiring1DMSelection.length; i++) {
-			String itemID = itemsRequiring1DMSelection[i];
-			item = getToolBarItem(itemID);
+								refresh_pending = false;
+							}
 
-			if (item != null) {
-				item.setEnabled(has1Selection && isDMSelection);
-			}
-		}
+							_refreshCoreToolBarItems();
+						}
+					});
+				}
+			}, 250);
+
+	private Map<DownloadManager, DownloadManagerListener> dm_listener_map = new HashMap<DownloadManager, DownloadManagerListener>();
+
+	public void refreshCoreToolBarItems() {
+		refresh_limiter.dispatch();
+	}
 
-		boolean canStart = false;
-		boolean canStop = false;
-
-		if (isIconBarEnabler && currentContent.length > 0
-				&& currentContent[0] != null
-				&& currentContent[0] instanceof ToolBarEnablerSelectedContent) {
-			ToolBarEnablerSelectedContent ibeSelected = (ToolBarEnablerSelectedContent) currentContent[0];
-			IconBarEnabler enabler = ibeSelected.getIconBarEnabler();
-			if (enabler != null) {
-
-				String[] TBKEYS = new String[] {
-					"download",
-					"play",
-					"run",
-					"up",
-					"down",
-					"start",
-					"stop",
-					"remove"
-				};
-				//String[] OLD_TBKEYS = new String[] {"run","up","down","start","stop","delete"};
-
-				for (String item_key : TBKEYS) {
-					item = getToolBarItem(item_key);
-					if (item != null) {
-						boolean enabled = enabler.isEnabled(item_key);
-						item.setEnabled(enabled);
-						if (enabled) {
-							if (item_key.equals("start")) {
-								canStart = true;
-							} else if (item_key.equals("stop")) {
-								canStop = true;
+	public void _refreshCoreToolBarItems() {
+
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+
+		if (mdi != null) {
+			UIToolBarItem[] allToolBarItems = getAllToolBarItems();
+			MdiEntrySWT entry = mdi.getCurrentEntrySWT();
+			Map<String, Long> mapStates = new HashMap<String, Long>();
+			if (entry != null) {
+				UIToolBarEnablerBase[] enablers = entry.getToolbarEnablers();
+				for (UIToolBarEnablerBase enabler : enablers) {
+					if (enabler instanceof UIPluginViewToolBarListener) {
+						try{
+							((UIPluginViewToolBarListener) enabler).refreshToolBarItems(mapStates);
+						}catch( Throwable e ){
+							Debug.out( e );	// don't trust them plugins
+						}
+					} else if (enabler instanceof ToolBarEnabler) {
+						Map<String, Boolean> oldMapStates = new HashMap<String, Boolean>();
+						((ToolBarEnabler) enabler).refreshToolBar(oldMapStates);
+
+						for (String key : oldMapStates.keySet()) {
+							Boolean enable = oldMapStates.get(key);
+							Long curState = mapStates.get(key);
+							if (curState == null) {
+								curState = 0L;
+							}
+							if (enable) {
+								mapStates.put(key, curState | UIToolBarItem.STATE_ENABLED);
+							} else {
+								mapStates.put(key, curState & (~UIToolBarItem.STATE_ENABLED));
 							}
 						}
 					}
 				}
 			}
 
-		} else if (isActivityView) {
-			item = getToolBarItem("up");
-			if (item != null) {
-				item.setEnabled(false);
-			}
-			item = getToolBarItem("down");
-			if (item != null) {
-				item.setEnabled(false);
-			}
-			item = getToolBarItem("remove");
-			if (item != null) {
-				SkinView view = SkinViewManager.getBySkinObjectID("Activity");
-				if (view instanceof SBC_ActivityView) {
-					SBC_ActivityView viewActivity = (SBC_ActivityView) view;
-					if (viewActivity.isVisible()) {
-						item.setEnabled(viewActivity.getNumSelected() > 0);
-					} else {
-						item.setEnabled(false);
+			ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
+
+			synchronized (dm_listener_map) {
+
+				Map<DownloadManager, DownloadManagerListener> copy = new HashMap<DownloadManager, DownloadManagerListener>(
+						dm_listener_map);
+
+				for (ISelectedContent content : currentContent) {
+
+					DownloadManager dm = content.getDownloadManager();
+
+					if (dm != null) {
+
+						if (copy.remove(dm) == null) {
+
+							DownloadManagerListener l = new DownloadManagerListener() {
+								public void stateChanged(DownloadManager manager, int state) {
+									refreshCoreToolBarItems();
+								}
+
+								public void downloadComplete(DownloadManager manager) {
+									refreshCoreToolBarItems();
+								}
+
+								public void completionChanged(DownloadManager manager,
+										boolean bCompleted) {
+									refreshCoreToolBarItems();
+								}
+
+								public void positionChanged(DownloadManager download,
+										int oldPosition, int newPosition) {
+									refreshCoreToolBarItems();
+								}
+
+								public void filePriorityChanged(DownloadManager download,
+										DiskManagerFileInfo file) {
+									refreshCoreToolBarItems();
+								}
+							};
+
+							dm.addListener(l, false);
+
+							dm_listener_map.put(dm, l);
+
+							// System.out.println( "Added " + dm.getDisplayName() + " - size=" + dm_listener_map.size());
+						}
 					}
-				} else {
-					item.setEnabled(false);
 				}
 
+				for (Map.Entry<DownloadManager, DownloadManagerListener> e : copy.entrySet()) {
+
+					DownloadManager dm = e.getKey();
+
+					dm.removeListener(e.getValue());
+
+					dm_listener_map.remove(dm);
+
+					// System.out.println( "Removed " + dm.getDisplayName() + " - size=" + dm_listener_map.size());
+				}
 			}
-		} else if (currentContent.length > 0 && hasRealDM) {
-			for (int i = 0; i < currentContent.length; i++) {
-				ISelectedContent content = currentContent[i];
-				DownloadManager dm = content.getDownloadManager();
-				if (!canStart && ManagerUtils.isStartable(dm)) {
-					canStart = true;
+
+			if (!mapStates.containsKey("download")) {
+				for (ISelectedContent content : currentContent) {
+					if (content.getDownloadManager() == null
+							&& content.getDownloadInfo() != null) {
+						mapStates.put("download", UIToolBarItem.STATE_ENABLED);
+						break;
+					}
 				}
-				if (!canStop && ManagerUtils.isStopable(dm)) {
-					canStop = true;
+			}
+			boolean has1Selection = currentContent.length == 1;
+
+			boolean can_play = false;
+			boolean can_stream = false;
+
+			boolean stream_permitted = false;
+
+			if (has1Selection) {
+
+				if (!(currentContent[0] instanceof ISelectedVuzeFileContent)) {
+
+					can_play = PlayUtils.canPlayDS(currentContent[0],
+							currentContent[0].getFileIndex());
+					can_stream = PlayUtils.canStreamDS(currentContent[0],
+							currentContent[0].getFileIndex());
+
+					if (can_stream) {
+
+						stream_permitted = PlayUtils.isStreamPermitted();
+					}
 				}
 			}
-		}
 
-		item = getToolBarItem("run");
-		if (item != null) {
-			boolean canRun = has1Selection;
-			if (canRun) {
-				ISelectedContent content = currentContent[0];
-				DownloadManager dm = content.getDownloadManager();
+			// allow a tool-bar enabler to manually handle play/stream events
 
-				if (dm == null) {
-					canRun = false;
-				} else {
-					TOTorrent torrent = dm.getTorrent();
+			if (mapStates.containsKey("play")) {
+				can_play |= (mapStates.get("play") & UIToolBarItem.STATE_ENABLED) > 0;
+			}
+			if (mapStates.containsKey("stream")) {
+				can_stream |= (mapStates.get("stream") & UIToolBarItem.STATE_ENABLED) > 0;
+			}
 
-					if (torrent == null) {
+			mapStates.put("play", can_play | can_stream
+					? UIToolBarItem.STATE_ENABLED : 0);
 
-						canRun = false;
+			UIToolBarItem pitem = getToolBarItem("play");
 
-					} else if (!dm.getAssumedComplete() && torrent.isSimpleTorrent()) {
+			if (pitem != null) {
 
-						canRun = false;
+				if (can_stream) {
 
-					} else if (PlatformTorrentUtils.useEMP(torrent)
-							&& PlatformTorrentUtils.embeddedPlayerAvail()
-							&& PlayUtils.canProgressiveOrIsComplete(torrent)) {
-						// play button enabled and not UMP.. don't need launch
+					pitem.setImageID(stream_permitted ? "image.button.stream"
+							: "image.button.pstream");
+					pitem.setTextID(stream_permitted ? "iconBar.stream"
+							: "iconBar.pstream");
 
-						canRun = false;
+				} else {
 
-					}
+					pitem.setImageID("image.button.play");
+					pitem.setTextID("iconBar.play");
 				}
 			}
-			item.setEnabled(canRun);
-		}
 
-		item = getToolBarItem("start");
-		if (item != null) {
-			item.setEnabled(canStart);
-		}
-		item = getToolBarItem("stop");
-		if (item != null) {
-			item.setEnabled(canStop);
-		}
-		item = getToolBarItem("play");
-		if (item != null) {
-			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);
-		}
+			UIToolBarItem ssItem = getToolBarItem("startstop");
+			if (ssItem != null) {
+				boolean shouldStopGroup = TorrentUtil.shouldStopGroup(currentContent);
+				ssItem.setTextID(shouldStopGroup ? "iconBar.stop" : "iconBar.start");
+				ssItem.setImageID("image.toolbar.startstop."
+						+ (shouldStopGroup ? "stop" : "start"));
+			}
 
-		if (tv != null) {
-			TableColumn tc = tv.getTableColumn(RankItem.COLUMN_ID);
-			if (tc != null && !tc.isVisible()) {
-				item = getToolBarItem("up");
-				if (item != null) {
-					item.setEnabled(false);
+			for (int i = 0; i < allToolBarItems.length; i++) {
+				UIToolBarItem toolBarItem = allToolBarItems[i];
+				Long state = mapStates.get(toolBarItem.getID());
+				if (state != null) {
+					toolBarItem.setState(state);
 				}
-				item = getToolBarItem("down");
-				if (item != null) {
-					item.setEnabled(false);
+			}
+			
+			if ( ssItem != null ){
+				
+					// fallback to handle start/stop settings when no explicit selected content (e.g. for devices transcode view)
+				
+				if ( currentContent.length == 0 && !mapStates.containsKey( "startstop" )){
+					
+					boolean	can_stop 	= mapStates.containsKey("stop") && (mapStates.get("stop") & UIToolBarItem.STATE_ENABLED) > 0;
+					boolean	can_start 	= mapStates.containsKey("start") && (mapStates.get("start") & UIToolBarItem.STATE_ENABLED) > 0;
+					
+					if ( can_start && can_stop ){
+						
+						can_stop = false;
+					}
+					
+					if ( can_start | can_stop ){
+						ssItem.setTextID(can_stop ? "iconBar.stop" : "iconBar.start");
+						ssItem.setImageID("image.toolbar.startstop."
+								+ (can_stop ? "stop" : "start"));
+						
+						ssItem.setState( 1 );
+						
+					}else{
+						
+						ssItem.setState( 0 );
+					}
 				}
 			}
+			
+			return;
 		}
 	}
 
-	/**
-	 * @param toolBarItem
-	 *
-	 * @since 3.1.1.1
-	 */
-	protected void activateViaSideBar(ToolBarItem toolBarItem) {
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			SideBarEntrySWT entry = sidebar.getCurrentEntry();
-			if (entry.iview != null) {
-				entry.iview.itemActivated(toolBarItem.getId());
+	private boolean triggerViewToolBar(ToolBarItem item, long activationType,
+			Object datasource) {
+		MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+		if (mdi != null) {
+			MdiEntrySWT entry = mdi.getCurrentEntrySWT();
+			UIToolBarEnablerBase[] enablers = entry.getToolbarEnablers();
+			for (UIToolBarEnablerBase enabler : enablers) {
+				if (enabler instanceof UIPluginViewToolBarListener) {
+					if (((UIPluginViewToolBarListener) enabler).toolBarItemActivated(
+							item, activationType, datasource)) {
+						return true;
+					}
+				} else if (enabler instanceof ToolBarEnabler) {
+					if (activationType == UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL
+							&& ((ToolBarEnabler) enabler).toolBarItemActivated(item.getID())) {
+						return true;
+					}
+				}
 			}
 		}
+
+		return false;
 	}
 
-	/**
-	 * @param itemID
-	 * @return
-	 *
-	 * @since 3.1.1.1
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager#createToolBarItem(java.lang.String)
 	 */
-	public ToolBarItem getToolBarItem(String itemID) {
-		return items.get(itemID);
+	public UIToolBarItem createToolBarItem(String id) {
+		return new ToolBarItemSO(this, id, true);
 	}
 
-	public ToolBarItem[] getAllToolBarItems() {
-		return items.values().toArray(new ToolBarItem[0]);
+	public UIToolBarItem createToolBarItem(PluginInterface pi, String id) {
+		return new ToolBarItemSO(this, id, true);
 	}
 
-	public void refreshCoreToolBarItems() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				_refreshCoreToolBarItems();
-			}
-		});
+	public void addToolBarItem(UIToolBarItem item) {
+		if (item instanceof ToolBarItemSO) {
+			ToolBarItemSO itemSO = (ToolBarItemSO) item;
+			itemSO.setGroupID("plugin");
+			//addNonToolBar("toolbar.area.sitem.left2", so2nd);
+			addToolBarItem(itemSO, "toolbar.area.sitem", so2nd);
+		}
 	}
 
-	public void _refreshCoreToolBarItems() {
-		ISelectedContent[] sc = SelectedContentManager.getCurrentlySelectedContent();
-		String sv = SelectedContentManager.getCurrentySelectedViewID();
-		if (sv != null) {
-			updateCoreItems(sc, sv);
-		} 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) {
-					if (entry.iview != null) {
-						enabler = entry.iview;
-					} else {
-						for (int i = 0; i < allToolBarItems.length; i++) {
-							ToolBarItem toolBarItem = allToolBarItems[i];
-							toolBarItem.setEnabled(false);
+	public void addToolBarItemNoCreate(final ToolBarItemSO item) {
+		addToolBarItem(item, null, null);
+	}
+
+	public void addToolBarItem(final ToolBarItemSO item, String templatePrefix,
+			SWTSkinObject soMain) {
+		item.setDefaultState(item.getState());
+		String groupID = item.getGroupID();
+		
+		int position = SWT.RIGHT;
+
+		synchronized (mapGroupToItemIDs) {
+			List<String> list = mapGroupToItemIDs.get(groupID);
+			if (list == null) {
+				list = new ArrayList<String>();
+				mapGroupToItemIDs.put(groupID, list);
+				position = SWT.LEFT;
+			} else if (soMain != null && !groupID.equals(GROUP_BIG)) {
+				// take the last item and change it to RIGHT
+				int size = list.size();
+				String lastID = list.get(size - 1);
+				ToolBarItemSO lastItem = getToolBarItemSO(lastID);
+				if (lastItem != null) {
+					SWTSkinObject so = skin.getSkinObjectByID("toolbar:" + lastItem.getID());
+					if (so != null) {
+						String configID = so.getConfigID();
+						if ((size == 1 && !configID.endsWith(".left")) || !configID.equals(templatePrefix)) {
+    					setupToolBarItem(lastItem, templatePrefix, soMain, size == 1 ? SWT.LEFT
+    							: SWT.CENTER);
 						}
-						return;
 					}
 				}
 
-				for (int i = 0; i < allToolBarItems.length; i++) {
-					ToolBarItem toolBarItem = allToolBarItems[i];
-					toolBarItem.setEnabled(enabler.isEnabled(toolBarItem.getId()));
-				}
+				addSeperator(soMain);
 			}
+			list.add(item.getID());
+		}
+		
+		if (soMain != null) {
+			setupToolBarItem(item, templatePrefix, soMain, groupID.equals(GROUP_BIG)
+					? 0 : position);
+		} else {
+			items.put(item.getID(), item);
 		}
 	}
-
-	private boolean triggerIViewToolBar(String id) {
-		SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-		if (sidebar != null) {
-			SideBarEntrySWT entry = sidebar.getCurrentEntry();
-			IconBarEnabler enabler = entry.getIconBarEnabler();
-			if (enabler == null && entry.iview != null) {
-				enabler = entry.iview;
+	
+	private void bulkSetupItems(String groupID, String templatePrefix, SWTSkinObject soMain) {
+		synchronized (mapGroupToItemIDs) {
+			List<String> list = mapGroupToItemIDs.get(groupID);
+			if (list == null) {
+				return;
+			}
+			for (int i = 0; i < list.size(); i++) {
+				String itemID = list.get(i);
+				SWTSkinObject so = skin.getSkinObjectByID("toolbar:" + itemID);
+				if (so != null) {
+					so.dispose();
+				}
+				ToolBarItemSO item = getToolBarItemSO(itemID);
+				if (item != null) {
+					int position = 0;
+					int size = list.size();
+					if (size == 1) {
+						position = SWT.SINGLE;
+					} else if (i == 0) {
+						position = SWT.LEFT;
+					} else if (i == size - 1) {
+						addSeperator(soMain);
+						position = SWT.RIGHT;
+					} else {
+						addSeperator(soMain);
+					}
+					setupToolBarItem(item, templatePrefix, soMain, position);
+				}
+				
 			}
-			enabler.itemActivated(id);
-			return true;
 		}
-		return false;
 	}
 
-	public void addToolBarItem(final ToolBarItem item) {
-		addToolBarItem(item, "toolbar.area.item", soMain);
-	}
+	private void setupToolBarItem(final ToolBarItemSO item, String templatePrefix,
+			SWTSkinObject soMain, int position) {
+		String templateID = templatePrefix;
+		if (position == SWT.RIGHT) {
+			templateID += ".right";
+		} else if (position == SWT.LEFT) {
+			templateID += ".left";
+		} else if (position == SWT.SINGLE) {
+			templateID += ".lr";
+		}
 
-	public void addToolBarItem(final ToolBarItem item, String templateID,
-			SWTSkinObject soMain) {
-		SWTSkinObject so = skin.createSkinObject("toolbar:" + item.getId(),
-				templateID, soMain);
+		Control attachToControl = this.lastControl;
+		String id = "toolbar:" + item.getID();
+		SWTSkinObject oldSO = skin.getSkinObjectByID(id);
+		if (oldSO != null) {
+			Object layoutData = oldSO.getControl().getLayoutData();
+			if (layoutData instanceof FormData) {
+				FormData fd = (FormData) layoutData;
+				if (fd.left != null) {
+					attachToControl = fd.left.control;
+				}
+			}
+			oldSO.dispose();
+		}
+		SWTSkinObject so = skin.createSkinObject(id, templateID, soMain);
 		if (so != null) {
 			so.setTooltipID(item.getTooltipID());
 
 			if (lastControl != null) {
 				FormData fd = (FormData) so.getControl().getLayoutData();
-				fd.left = new FormAttachment(lastControl);
+				fd.left = new FormAttachment(attachToControl);
 			}
 
 			so.setData("toolbaritem", item);
@@ -881,6 +1021,7 @@ public class ToolBarView
 			SWTSkinObject soTitle = skin.getSkinObject("toolbar-item-title", so);
 			if (soTitle instanceof SWTSkinObjectText) {
 				((SWTSkinObjectText) soTitle).setTextID(item.getTextID());
+				item.setSkinTitle((SWTSkinObjectText) soTitle);
 			}
 
 			if (initComplete) {
@@ -888,8 +1029,8 @@ public class ToolBarView
 			}
 
 			lastControl = item.getSkinButton().getSkinObject().getControl();
-			items.put(item.getId(), item);
 		}
+		items.put(item.getID(), item);
 	}
 
 	private void addSeperator(SWTSkinObject soMain) {
@@ -929,10 +1070,10 @@ public class ToolBarView
 	 */
 	public void setShowText(boolean showText) {
 		this.showText = showText;
-		ToolBarItem[] allToolBarItems = getAllToolBarItems();
+		UIToolBarItem[] allToolBarItems = getAllToolBarItems();
 		for (int i = 0; i < allToolBarItems.length; i++) {
-			ToolBarItem tbi = allToolBarItems[i];
-			SWTSkinObject so = tbi.getSkinButton().getSkinObject();
+			UIToolBarItem tbi = allToolBarItems[i];
+			SWTSkinObject so = ((ToolBarItemSO) tbi).getSkinButton().getSkinObject();
 			SWTSkinObject soTitle = skin.getSkinObject("toolbar-item-title", so);
 			soTitle.setVisible(showText);
 		}
@@ -952,23 +1093,22 @@ public class ToolBarView
 				SWTSkinObject skinObject, int stateMask) {
 			ToolBarItem item = (ToolBarItem) buttonUtility.getSkinObject().getData(
 					"toolbaritem");
-			item.triggerToolBarItem();
+			boolean rightClick = (stateMask & (SWT.BUTTON3 | SWT.MOD4)) > 0;
+			item.triggerToolBarItem(rightClick
+					? UIToolBarActivationListener.ACTIVATIONTYPE_RIGHTCLICK
+					: UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL,
+					SelectedContentManager.convertSelectedContentToObject(null));
 		}
 
 		public boolean held(SWTSkinButtonUtility buttonUtility) {
 			ToolBarItem item = (ToolBarItem) buttonUtility.getSkinObject().getData(
 					"toolbaritem");
 			buttonUtility.getSkinObject().switchSuffix("", 0, false, true);
-			
-			boolean triggerToolBarItemHold = item.triggerToolBarItemHold();
-			return triggerToolBarItemHold;
-		}
 
-		public void disabledStateChanged(SWTSkinButtonUtility buttonUtility,
-				boolean disabled) {
-			ToolBarItem item = (ToolBarItem) buttonUtility.getSkinObject().getData(
-					"toolbaritem");
-			item.setEnabled(!disabled);
+			boolean triggerToolBarItemHold = item.triggerToolBarItem(
+					UIToolBarActivationListener.ACTIVATIONTYPE_HELD,
+					SelectedContentManager.convertSelectedContentToObject(null));
+			return triggerToolBarItemHold;
 		}
 	}
 
@@ -1023,4 +1163,40 @@ public class ToolBarView
 		}
 	}
 
+	public void addListener(ToolBarViewListener l) {
+		synchronized (listeners) {
+			listeners.add(l);
+
+			if (initComplete) {
+				try {
+					l.toolbarViewInitialized(this);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+	}
+
+	public void removeListener(ToolBarViewListener l) {
+		synchronized (listeners) {
+			listeners.remove(l);
+		}
+	}
+
+	public interface ToolBarViewListener
+	{
+		public void toolbarViewInitialized(ToolBarView tbv);
+	}
+
+	public void removeToolBarItem(String id) {
+		UIToolBarItem toolBarItem = items.remove(id);
+		if (toolBarItem instanceof ToolBarItemSO) {
+			ToolBarItemSO item = (ToolBarItemSO) toolBarItem;
+			item.dispose();
+			SWTSkinObject so = skin.getSkinObjectByID("toolbar:" + item.getID());
+			if (so != null) {
+				so.dispose();
+			}
+		}
+	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
index 190af45..d5d06c3 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/TorrentListViewsUtils.java
@@ -21,62 +21,43 @@
 package com.aelitis.azureus.ui.swt.views.skin;
 
 import java.io.File;
-import java.io.IOException;
 import java.lang.reflect.Method;
+import java.net.URL;
 import java.util.Map;
 
-import org.eclipse.swt.program.Program;
+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.ForceRecheckListener;
 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.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.AEThread2;
-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.UrlUtils;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadException;
-import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
-import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.TextViewerWindow;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
 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.download.*;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
+import com.aelitis.azureus.core.util.LaunchManager;
 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;
-import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfoContentNetwork;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.browser.listener.DownloadUrlInfoSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility;
+import com.aelitis.azureus.ui.swt.feature.FeatureManagerUI;
+import com.aelitis.azureus.ui.swt.player.PlayerInstallWindow;
+import com.aelitis.azureus.ui.swt.player.PlayerInstaller;
 import com.aelitis.azureus.ui.swt.utils.TorrentUIUtilsV3;
-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.win32.Win32Utils;
 
 /**
  * @author TuxPaper
@@ -85,139 +66,11 @@ import com.aelitis.azureus.util.win32.Win32Utils;
  */
 public class TorrentListViewsUtils
 {
-
-	public static final boolean ENABLE_ON_HOVER = false;
-
-	/**
-	 * @param dm
-	 *
-	 * @since 3.0.1.5
-	 */
-	public static void stop(DownloadManager dm) {
-		int state = dm.getState();
-		if (state == DownloadManager.STATE_ERROR) {
-			dm.stopIt(DownloadManager.STATE_QUEUED, false, false);
-		} else if (state == DownloadManager.STATE_STOPPED) {
-			ManagerUtils.queue(dm, null);
-		} else {
-			ManagerUtils.stop(dm, null);
-		}
-	}
-
-	public static void viewDetails(TableRowCore row, String ref) {
-		Object ds = row.getDataSource(true);
-		viewDetails(DataSourceUtils.getContentNetwork(ds),
-				DataSourceUtils.getHash(ds), ref);
-	}
-
-	public static boolean canViewDetails(DownloadManager dm) {
-		if (dm == null) {
-			return( false );
-		}
-		if (!PlatformTorrentUtils.isContent(dm.getTorrent(), true)) {
-			return( false );
-		}
-
-		try{
-			return(	canViewDetails(DataSourceUtils.getContentNetwork(dm.getTorrent()),
-						dm.getTorrent().getHashWrapper().toBase32String()));
-		} catch (Throwable e) {
-			Debug.out(e);
-			
-			return( false );
-		}
-	}
+	private static StreamManagerDownload	current_stream;
+	private static TextViewerWindow			stream_viewer;
 	
-	public static void viewDetails(DownloadManager dm, String ref) {
-		if (dm == null) {
-			return;
-		}
-		if (!PlatformTorrentUtils.isContent(dm.getTorrent(), true)) {
-			return;
-		}
-
-		try {
-			viewDetails(DataSourceUtils.getContentNetwork(dm.getTorrent()),
-					dm.getTorrent().getHashWrapper().toBase32String(), ref);
-		} catch (Throwable e) {
-			Debug.out(e);
-		}
-	}
-
-	public static void viewDetails(ContentNetwork cn, String hash, String ref) {
-		if (hash == null || cn == null) {
-			return;
-		}
-
-		String url = cn.getContentDetailsService( hash, ref );
-
-		UIFunctions functions = UIFunctionsManager.getUIFunctions();
-		if (functions != null) {
-			functions.viewURL(url, ContentNetworkUtils.getTarget(cn), ref);
-		}
-	}
-
-	public static boolean canViewDetails(ContentNetwork cn, String hash) {
-		if (hash == null || cn == null ) {
-			return( false );
-		}
-
-		String url = cn.getContentDetailsService( hash, "" );
-
-		UIFunctions functions = UIFunctionsManager.getUIFunctions();
-		
-		return( functions != null && url != null );
-	}
-	
-	public static String
-	getDetailsURL(
-		DownloadManager		dm )
-	{
-		try {
-			ContentNetwork cn = DataSourceUtils.getContentNetwork(dm.getTorrent());
-			
-			if ( cn == null ){
-				
-				return( null );
-			}
-			
-			TOTorrent torrent = dm.getTorrent();
-			
-			if ( torrent == null ){
-				
-				return( null );
-			}
-
-			String hash = torrent.getHashWrapper().toBase32String();
-			
-			String url = cn.getContentDetailsService( hash, "" );
-
-			return( url );
-			
-		}catch(Throwable  e ){
-			
-			Debug.out(e);
-			
-			return( null );
-		}
-	}
-
-	/**
-	 * @param ds
-	 * @param ref
-	 *
-	 * @since 4.0.0.5
-	 */
-	public static void viewDetailsFromDS(Object ds, String ref) {
-		String hash = DataSourceUtils.getHash(ds);
-		if (hash == null) {
-			return;
-		}
-		viewDetails(DataSourceUtils.getContentNetwork(ds), hash, ref);
-	}
-
-
-	public static void playOrStreamDataSource(Object ds, SWTSkinButtonUtility btn) {
+	public static void playOrStreamDataSource(Object ds,
+			boolean launch_already_checked) {
 		String referal = DLReferals.DL_REFERAL_UNKNOWN;
 		if (ds instanceof VuzeActivitiesEntry) {
 			referal = DLReferals.DL_REFERAL_PLAYDASHACTIVITY;
@@ -226,19 +79,25 @@ public class TorrentListViewsUtils
 		} else if (ds instanceof ISelectedContent) {
 			referal = DLReferals.DL_REFERAL_SELCONTENT;
 		}
-		playOrStreamDataSource(ds, btn, referal);
+		playOrStreamDataSource(ds, referal, launch_already_checked, true );
 	}
 
-	public static void playOrStreamDataSource(Object ds,
-			SWTSkinButtonUtility btn, String referal) {
+	public static void playOrStreamDataSource(Object ds, String referal,
+			boolean launch_already_checked, boolean complete_only) {
 
-		DownloadManager dm = DataSourceUtils.getDM(ds);
-		if (dm == null) {
-			downloadDataSource(ds, true, referal);
-		} else {
-			playOrStream(dm, btn);
+		DiskManagerFileInfo fileInfo = DataSourceUtils.getFileInfo(ds);
+		if (fileInfo != null) {
+			playOrStream(fileInfo.getDownloadManager(), fileInfo.getIndex(),
+					complete_only, launch_already_checked, referal);
+		}else{
+		
+			DownloadManager dm = DataSourceUtils.getDM(ds);
+			if (dm == null) {
+				downloadDataSource(ds, true, referal);
+			} else {
+				playOrStream(dm, -1, complete_only, launch_already_checked, referal);
+			}
 		}
-
 	}
 
 	public static void downloadDataSource(Object ds, boolean playNow,
@@ -268,42 +127,77 @@ public class TorrentListViewsUtils
 			TorrentUIUtilsV3.addTorrentToGM(torrent);
 		} else {
 			DownloadUrlInfo dlInfo = DataSourceUtils.getDownloadInfo(ds);
-			if (dlInfo instanceof DownloadUrlInfoSWT) {
-				TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, false,
-						true, true);
+			if (dlInfo != null) {
+				TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, false, true);
 				return;
 			}
 
 			String hash = DataSourceUtils.getHash(ds);
 			if (hash != null) {
-				ContentNetwork cn = DataSourceUtils.getContentNetwork(ds);
-				if (cn == null) {
-					return;
-				}
-				if (ds instanceof VuzeActivitiesEntry) {
-					if (((VuzeActivitiesEntry) ds).isDRM()) {
-						TorrentListViewsUtils.viewDetails(cn, hash, "drm-play");
-						return;
-					}
-				}
-
-				String url = cn.getTorrentDownloadService(hash, referal);
-				dlInfo = new DownloadUrlInfoContentNetwork(url, cn);
-				TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, false, true, true);
-			} else if (dlInfo != null) {
-				TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, false,
-						true, true);
+				dlInfo = new DownloadUrlInfo(UrlUtils.parseTextForMagnets(hash));
+				dlInfo.setReferer(referal);
+				TorrentUIUtilsV3.loadTorrent(dlInfo, playNow, false, true);
+				return;
 			}
 		}
 	}
 
+	// VuzePlayer (2011) calls this
 	public static void playOrStream(final DownloadManager dm,
-			final SWTSkinButtonUtility btn) {
-		_playOrStream(dm, btn);
+			final int file_index, final boolean complete_only,
+			boolean launch_already_checked) {
+		playOrStream(dm, file_index, complete_only, launch_already_checked, null);
+	}
+
+	
+	private static void playOrStream(final DownloadManager dm,
+			final int file_index, final boolean complete_only,
+			boolean launch_already_checked, final String referal) {
+			
+		if (dm == null) {
+			return;
+		}
+		
+		if ( launch_already_checked ){
+		
+			_playOrStream(dm, file_index, complete_only, referal);
+			
+		}else{
+			
+			LaunchManager	launch_manager = LaunchManager.getManager();
+			
+			LaunchManager.LaunchTarget target = launch_manager.createTarget( dm );
+				
+			launch_manager.launchRequest(
+				target,
+				new LaunchManager.LaunchAction()
+				{
+					public void
+					actionAllowed()
+					{
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									_playOrStream(dm, file_index, complete_only, referal);
+								}
+							});
+					}
+					
+					public void
+					actionDenied(
+						Throwable		reason )
+					{
+						Debug.out( "Launch request denied", reason );
+					}
+				});
+		}
 	}
 
 	private static void _playOrStream(final DownloadManager dm,
-			final SWTSkinButtonUtility btn) {
+			final int file_index, boolean complete_only, String referal) {
 
 		if (dm == null) {
 			return;
@@ -314,161 +208,31 @@ public class TorrentListViewsUtils
 		//		}
 
 		final TOTorrent torrent = dm.getTorrent();
-		if (PlayUtils.canUseEMP(torrent)) {
+		if (torrent == null) {
+			return;
+		}
+		if (PlayUtils.canUseEMP(torrent, file_index,complete_only)) {
 			debug("Can use EMP");
 
-			if (openInEMP(dm)) {
+			int open_result = openInEMP(dm,file_index,complete_only,referal);
+			
+			if ( open_result == 0 ){
 				PlatformTorrentUtils.setHasBeenOpened(dm, true);
 				return;
+			}else if ( open_result == 2 ){
+				debug( "Open in EMP abandoned" );
+				return;
 			} else {
 				debug("Open EMP Failed");
 			}
 			// fallback to normal
 		} else {
-			debug("Can't use EMP. torrent says "
-					+ PlatformTorrentUtils.useEMP(torrent));
-		}
-
-		if (btn != null) {
-			btn.setDisabled(true);
-		}
-
-		boolean reenableButton = false;
-		try {
-			if (!PlayUtils.canProgressiveOrIsComplete(torrent)) {
-				return;
-			}
-
-			File file;
-			String sFile = null;
-
-			EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload(
-					dm);
-			if (edm != null) {
-				boolean doProgressive = edm.getProgressiveMode();
-				if (doProgressive && edm.getProgressivePlayETA() > 0) {
-					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());
-  				reenableButton = true;
-  				PlatformTorrentUtils.setHasBeenOpened(dm, true);
-  				return;
-				}
-
-				file = edm.getPrimaryFile().getFile(true);
-				sFile = file.getAbsolutePath();
-			} else {
-				sFile = dm.getDownloadState().getPrimaryFile();
-				file = new File(sFile);
-			}
-			
-			final String sfFile = sFile;
-
-			String ext = FileUtil.getExtension(sFile);
-			
-			try {
-  			if (ext.equalsIgnoreCase(".exe")
-  					&& DataSourceUtils.isPlatformContent(dm)
-  					&& "Game".equalsIgnoreCase(PlatformTorrentUtils.getContentType(dm.getTorrent()))) {
-  				reenableButton = true;
-  				Utils.launch(sFile);
-  				PlatformTorrentUtils.setHasBeenOpened(dm, true);
-  				return;
-  			}
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-
-			final String sPrefix = "v3.mb.openFile.";
-			
-
-			UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (functionsSWT == null) {
-				return;
-			}
-			
-			final Program program = Program.findProgram(ext);
-			String sTextID;
-			String sFileType;
-			if (program == null) {
-				sTextID = sPrefix + "text.unknown";
-				sFileType = ext;
-			} else {
-				sTextID = sPrefix + "text.known";
-				sFileType = program.getName();
-			}
-			
-			String[] buttons = new String[(program == null ? 2 : 3)];
-			buttons[0] = MessageText.getString(sPrefix + "button.guide");
-			buttons[buttons.length-1] = MessageText.getString(sPrefix + "button.cancel");
-			
-			MessageBoxShell mb = null;
-			if(program != null) {
-				buttons[1] = MessageText.getString(sPrefix + "button.play");
-				mb = new MessageBoxShell(MessageText.getString(sPrefix + "title"),
-						MessageText.getString(sTextID, new String[] {
-									dm.getDisplayName(),
-									sFileType,
-									ext
-								}), buttons, 0);
-				mb.setRemember(sPrefix + ".remember_id", false, MessageText.getString(sPrefix
-						+ "remember"));
-				mb.setRememberOnlyIfButton(1);
-				mb.setRelatedObject(dm);
-			} else {
-				mb = new MessageBoxShell(MessageText.getString(sPrefix + "title"),
-						MessageText.getString(sTextID, new String[] {
-							dm.getDisplayName(),
-							sFileType,
-							ext
-						}), buttons, 0);
-				mb.setRelatedObject(dm);
-			}
-
-			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);
-    				}
-    			}
-				}
-			});
-			
-		} finally {
-			if (btn != null && reenableButton) {
-				btn.setDisabled(false);
-			}
+			debug("Can't use EMP.");
 		}
+		
+		// We used to pop up a dialog saying we didn't know how to play the file
+		// But now the play toolbar and play 'default' action aren't even enabled
+		// if we can't use EMP.  So there's no point.
 	}
 
 
@@ -483,74 +247,341 @@ public class TorrentListViewsUtils
 		}
 	}
 
-	private static void runFile(TOTorrent torrent, String runFile) {
-		runFile(torrent, runFile, false);
-	}
-
-	private static void runFile(final TOTorrent torrent, final String runFile,
-			final boolean forceWMP) {
-
-		AEThread2 thread = new AEThread2("runFile", true) {
-			public void run() {
-
-				Utils.execSWTThread(new AERunnable() {
+	
+	private static boolean	emp_installing;
+	
+	/**
+	 * 
+	 * @param dm
+	 * @return 0=good, 1 = fail, 2 = abandon
+	 */
 
-					public void runSupport() {
-						if (PlayUtils.canUseEMP(torrent)) {
-							Debug.out("Shouldn't call runFile with EMP torrent.");
+	private static int 
+	installEMP(
+		String				name,
+		final Runnable		target )
+	{
+		synchronized( TorrentListViewsUtils.class ){
+			
+			if ( emp_installing ){
+				
+				Debug.out( "EMP is already being installed, secondary launch for " + name + " ignored" );
+				
+				return( 2 );
+			}
+			
+			emp_installing = true;
+		}
+		
+		boolean	running = false;
+		
+		try{
+			final PlayerInstaller installer = new PlayerInstaller();
+			
+			final PlayerInstallWindow window = new PlayerInstallWindow(installer);
+			
+			window.open();
+			
+			AEThread2 installerThread = new AEThread2("player installer",true) {
+				public void 
+				run() 
+				{
+					try{
+						if (installer.install()){
+							Utils.execSWTThread(new AERunnable() {
+								
+								public void runSupport() {
+									target.run();
+									
+								}
+							});
 						}
-
-						if (PlatformTorrentUtils.isContentDRM(torrent) || forceWMP) {
-							if (!runInMediaPlayer(runFile)) {
-								Utils.launch(runFile);
-							}
-						} else {
-							Utils.launch(runFile);
+					}finally{
+						
+						synchronized( TorrentListViewsUtils.class ){
+							
+							emp_installing = false;
 						}
-
 					}
-
-				});
-
+				}
+			};
+			
+			installerThread.start();
+			
+			running = true;
+			
+			return( 0 );
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( 1 );
+			
+		}finally{
+			
+			if ( !running ){
+				
+				synchronized( TorrentListViewsUtils.class ){
+					
+					emp_installing = false;
+				}
 			}
-
-		};
-		thread.start();
+		}
+		
 	}
-
 	/**
 	 * New version accepts map with ASX parameters. If the params are null then is uses the
 	 * old version to start the player. If the
 	 *
 	 *
 	 * @param dm - DownloadManager
-	 * @return - boolean
+	 * @return - int: 0 = ok, 1 = fail, 2 = abandon, installation in progress
 	 * @since 3.0.4.4 -
 	 */
-	private static boolean openInEMP(DownloadManager dm) {
-
-		Class epwClass = null;
+	private static int 
+	openInEMP(
+		final DownloadManager dm, final int _file_index, 
+		final boolean complete_only, final String referal ) 
+	{
 		try {
-			// Assumed we have a core, since we are passed a
-			// DownloadManager
-			PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
-					"azemp");
-
-			if (pi == null) {
+			int file_index = -1;
+			
+			if ( _file_index == -1 ){
 
-				return (false);
+				EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload( dm );
+				
+				if (edm != null) {
+					file_index = edm.getPrimaryFileIndex();
+				}
+				
+			}else{
+				
+				file_index = _file_index;
+			}
+			
+			if ( file_index == -1 ){
+				
+				return( 1 );
+			}
+			
+			final int f_file_index = file_index;
+						
+			org.gudy.azureus2.plugins.disk.DiskManagerFileInfo file = PluginCoreUtils.wrap( dm ).getDiskManagerFileInfo()[ file_index ];
+			
+			final URL url;
+			
+			if ((! complete_only ) && file.getDownloaded() != file.getLength()){
+					
+				url = PlayUtils.getMediaServerContentURL( file );
+				
+			}else{
+								
+				url = null;
+			}
+				
+			if ( url != null ){
+					
+				if ( PlayUtils.isStreamPermitted()){
+					
+					final boolean show_debug_window = false;
+					
+					new AEThread2( "stream:async" )
+					{
+						public void
+						run()
+						{
+							StreamManager	sm = StreamManager.getSingleton();
+	
+							synchronized( TorrentListViewsUtils.class ){
+								
+								if ( current_stream != null && !current_stream.isCancelled()){
+									
+									if ( current_stream.getURL().equals( url )){
+										
+										current_stream.setPreviewMode( !current_stream.getPreviewMode());
+										
+										return;
+									}
+									
+									current_stream.cancel();
+									
+									current_stream = null;
+								}
+				
+								if ( show_debug_window && ( stream_viewer == null || stream_viewer.isDisposed())){
+									
+									Utils.execSWTThread(
+										new Runnable()
+										{
+											public void
+											run()
+											{
+												if ( stream_viewer != null ){
+													
+													stream_viewer.close();
+												}
+												
+												stream_viewer = new 
+													TextViewerWindow( "Stream Status", "Debug information for stream process", "", false );
+												
+												stream_viewer.addListener(
+													new TextViewerWindow.TextViewerWindowListener()
+													{
+														public void 
+														closed() 
+														{
+															synchronized( TorrentListViewsUtils.class ){
+																
+																if ( current_stream != null ){
+																	
+																	current_stream.cancel();
+																	
+																	current_stream = null;
+																}
+															}
+														}
+													});
+											}
+										});
+								}
+								
+								current_stream = 
+									sm.stream( 
+										dm, f_file_index, url, false,
+										new StreamManagerDownloadListener()
+										{
+											private long	last_log = 0;
+											
+											public void
+											updateActivity(
+												String		str )
+											{
+												append( "Activity: " + str );
+											}
+											
+											public void
+											updateStats(
+												int			secs_until_playable,
+												int			buffer_secs,
+												long		buffer_bytes,
+												int			target_secs )
+											{
+												long	now = SystemTime.getMonotonousTime();
+												
+												if ( now - last_log >= 1000 ){
+												
+													last_log = now;
+													
+													append( "stats: play in " + secs_until_playable + " sec, buffer=" + DisplayFormatters.formatByteCountToKiBEtc( buffer_bytes ) + "/" + buffer_secs + " sec - target=" + target_secs + " sec" );
+												}
+											}
+											
+											public void
+											ready()
+											{
+												append( "ready" );
+											}
+											
+											public void
+											failed(
+												Throwable 	error )
+											{
+												append( "failed: " + Debug.getNestedExceptionMessage(error));
+												
+												Debug.out( error );
+											}
+											
+											private void
+											append(
+												final String	str )
+											{
+												if ( stream_viewer != null ){
+													
+													Utils.execSWTThread(
+														new Runnable()
+														{
+															public void
+															run()
+															{
+																if ( stream_viewer != null && !stream_viewer.isDisposed()){
+																	
+																	stream_viewer.append( str + "\r\n" );
+																}
+															}
+														});
+												}
+											}
+										});
+								}
+							}
+						}.start();
+		
+				}else{
+					
+					FeatureManagerUI.openStreamPlusWindow(referal);
+					
+				}
+				
+				return( 0 );
+						
+			}
+			
+			synchronized( TorrentListViewsUtils.class ){
+				
+				if ( current_stream != null && !current_stream.isCancelled()){
+										
+					current_stream.cancel();
+					
+					current_stream = null;
+				}
 			}
+			
+			Class epwClass = null;
+			
+			try {
+				// Assumed we have a core, since we are passed a
+				// DownloadManager
+				PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+						"azemp", false );
 
-			epwClass = pi.getPlugin().getClass().getClassLoader().loadClass(
-					"com.azureus.plugins.azemp.ui.swt.emp.EmbeddedPlayerWindowSWT");
+				if (pi == null) {
 
-		} catch (ClassNotFoundException e1) {
-			return false;
-		}
+					return (installEMP(dm.getDisplayName(), new Runnable(){ public void run(){ openInEMP( dm, f_file_index,complete_only,referal ); }}));
+					
+				}else if ( !pi.getPluginState().isOperational()){
+					
+					return( 1 );
+				}
 
-		//Data is passed to the openWindow via download manager.
-		try {
-			debug("EmbeddedPlayerWindowSWT - openWindow");
+				epwClass = pi.getPlugin().getClass().getClassLoader().loadClass(
+						"com.azureus.plugins.azemp.ui.swt.emp.EmbeddedPlayerWindowSWT");
+
+			} catch (ClassNotFoundException e1) {
+				return 1;
+			}
+	
+										
+			try{
+				Method method = epwClass.getMethod("openWindow", new Class[] {
+						File.class, String.class
+					});
+
+				File f = file.getFile( true );
+				
+				method.invoke(null, new Object[] {
+						f, f.getName()
+					});
+					
+				return( 0 );
+					
+			}catch( Throwable e ){
+				debug( "file/name open method missing" );
+			}
+
+			
+				// fall through here if old emp
+			
 			Method method = epwClass.getMethod("openWindow", new Class[] {
 				DownloadManager.class
 			});
@@ -559,7 +590,7 @@ public class TorrentListViewsUtils
 				dm
 			});
 
-			return true;
+			return 0;
 		} catch (Throwable e) {
 			e.printStackTrace();
 			if (e.getMessage() == null
@@ -568,9 +599,54 @@ public class TorrentListViewsUtils
 			}
 		}
 
-		return false;
+		return 1;
 	}//openInEMP
 
+	public static int
+	openInEMP(
+		final String	name,
+		final URL		url )
+	{
+		Class epwClass = null;
+		
+		try {
+
+			PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+					"azemp", false );
+
+			if ( pi == null ){
+
+				return( installEMP( name, new Runnable(){ public void run(){ openInEMP( name, url );}} ));
+				
+			}else if ( !pi.getPluginState().isOperational()){
+				
+				return( 1 );
+			}
+
+			epwClass = pi.getPlugin().getClass().getClassLoader().loadClass(
+					"com.azureus.plugins.azemp.ui.swt.emp.EmbeddedPlayerWindowSWT");
+
+		} catch (ClassNotFoundException e1) {
+			return 1;
+		}
+
+									
+		try{
+			Method method = epwClass.getMethod("openWindow", new Class[] {
+					URL.class, String.class
+				});
+			
+			method.invoke(null, new Object[] {url, name	});
+				
+			return( 0 );
+				
+		}catch( Throwable e ){
+			debug( "URL/name open method missing" );
+			
+			return( 1 );
+		}
+	}
+	
 	/**
 	* @param dm
 	*
@@ -597,7 +673,8 @@ public class TorrentListViewsUtils
 		mb.open(new UserPrompterResultListener() {
 			public void prompterClosed(int i) {
 				if (i == 0) {
-					ManagerUtils.remove(dm, functionsSWT.getMainShell(), true, false);
+					ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+							true, false, null);
 				} else if (i == 1) {
 					dm.forceRecheck(new ForceRecheckListener() {
 						public void forceRecheckComplete(DownloadManager dm) {
@@ -611,235 +688,13 @@ public class TorrentListViewsUtils
 	}
 
 	/**
-	 * @param string
-	 */
-	private static boolean runInMediaPlayer(String mediaFile) {
-
-		if (Constants.isWindows) {
-			String wmpEXE = Win32Utils.getWMP();
-			if (new File(wmpEXE).exists()) {
-				try {
-					Runtime.getRuntime().exec(wmpEXE + " \"" + mediaFile + "\"");
-					return true;
-				} catch (IOException e) {
-					Debug.out("error playing " + mediaFile + " via WMP " + mediaFile, e);
-				}
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * XXX DO NOT USE.  Only for EMP <= 2.0.14 support
-	 * @param dm
-	 * @return
-	 */
-	public static String getMediaServerContentURL(DownloadManager dm) {
-		try {
-			return PlayUtils.getMediaServerContentURL(DownloadManagerImpl.getDownloadStatic(dm));
-		} catch (DownloadException e) {
-		}
-		return null;
-	}
-
-	/**
+	 * Plays or Streams a Download
 	 * 
-	 */
-	public static void playViaMediaServer(Download download) {
-
-		try {
-			final DownloadManager dm = ((DownloadImpl) download).getDownload();
-
-			TOTorrent torrent = dm.getTorrent();
-			runFile(torrent, PlayUtils.getContentUrl(dm), true);
-		} catch (Throwable e) {
-			Logger.log(new LogEvent(LogIDs.UI3, "IPC to media server plugin failed",
-					e));
-		}
-	}
-
-	public static void removeDownloads(final DownloadManager[] dms) {
-		if (dms == null) {
-			return;
-		}
-
-		// 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 (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;
-
-
-			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"));
-
-				final int index = i;
-				mb.open(new UserPrompterResultListener() {
-					
-					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;
-						}
-						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);
-							}
-						}
-					}
-				});
-				return;
-			} else {
-				ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
-						deleteTorrent, deleteData, null);
-			}
-			dms[i] = null;
-		}}
-	}
-
-	public static void removeDownload(final DownloadManager dm,
-				final TableView tableView) {
-
-		debug("removeDownload");
-
-		AERunnable failure = null;
-		if (tableView != null) {
-			tableView.removeDataSource(dm);
-			tableView.processDataSourceQueue();
-
-			failure = new AERunnable() {
-				public void runSupport() {
-					tableView.addDataSource(dm);
-					tableView.processDataSourceQueue();
-				}
-			};
-		}
-		final AERunnable ffailure = failure;
-
-		if (dm.getDownloadState().getFlag(
-				Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE)) {
-			ManagerUtils.remove(dm, null, true, false, failure);
-			return;
-		}
-
-		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()
-					});
-					
-			MessageBoxShell mb = new MessageBoxShell(title, text, new String[] {
-						MessageText.getString("Button.cancel"),
-						MessageText.getString("Button.deleteContent.fromComputer"),
-						MessageText.getString("Button.deleteContent.fromLibrary"),
-					}, 2);
-			mb.setRelatedObject(dm);
-			mb.setLeftImage(ImageLoader.getInstance().getImage("image.trash"));
-
-			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;
-					}
-				}
-			});
-		} else {
-			ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
-					deleteTorrent, deleteData, failure);
-		}
-	}
-
-	/**
 	 * @param dm
-	 *
-	 * @since 3.0.2.3
+	 * @param file_index Index of file in torrent to play.  -1 to auto-pick
+	 * 				"best" play file.
 	 */
-	public static void showHomeHint(final DownloadManager dm) {
-	}
-
-	public static void playOrStream(final DownloadManager dm) {
-		playOrStream(dm, null);
+	public static void playOrStream(final DownloadManager dm, int file_index ) {
+		playOrStream(dm, file_index, PlayUtils.COMPLETE_PLAY_ONLY, false, null );
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBox.java b/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBox.java
new file mode 100644
index 0000000..9bdd6a3
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBox.java
@@ -0,0 +1,577 @@
+package com.aelitis.azureus.ui.swt.views.skin;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.ui.swt.Utils;
+
+import com.aelitis.azureus.ui.UIFunctionsUserPrompter;
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener;
+
+public class VuzeMessageBox
+	implements UIFunctionsUserPrompter, SkinnedDialogClosedListener
+{
+
+	private static final int BUTTON_PADDING = 2;
+
+	private static final int MIN_BUTTON_WIDTH = 50;
+
+	private String title;
+
+	private String text;
+
+	private String[] buttonIDs;
+
+	private Integer[] buttonVals;
+
+	private Button def_button;
+
+	private int defaultButtonPos;
+
+	private int result = -1;
+
+	private ArrayList<UserPrompterResultListener> resultListeners = new ArrayList<UserPrompterResultListener>(1);
+
+	private VuzeMessageBoxListener vuzeMessageBoxListener;
+
+	private SWTSkinObjectContainer soExtra;
+
+	private SkinnedDialog dlg;
+
+	private String iconResource;
+
+	private String subtitle;
+	
+	private java.util.List<rbInfo> listRBs = new ArrayList<rbInfo>();
+
+	private SWTSkin skin;
+
+	private String textIconResource;
+
+	private boolean closed;
+
+	private boolean opened;
+
+	private Button[] buttons;
+
+	private Map<Integer, Boolean> buttonsEnabled = new HashMap<Integer, Boolean>();
+
+	public VuzeMessageBox(final String title, final String text,
+			final String[] buttons, final int defaultOption) {
+		this.title = title;
+		this.text = text;
+		this.buttonIDs = buttons == null ? new String[0] : buttons;
+		this.defaultButtonPos = defaultOption;
+	}
+	
+	public void setButtonEnabled(final int buttonVal, final boolean enable) {
+		buttonsEnabled.put(buttonVal, enable);
+		if (buttons == null) {
+			return;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (buttons == null) {
+					return;
+				}
+				int pos = getButtonPosFromVal(buttonVal);
+				if (pos >= 0 && pos < buttons.length) {
+					Button button = buttons[pos];
+					if (button != null && !button.isDisposed()) {
+						button.setEnabled(enable);
+					}
+				}
+			}
+		});
+	}
+	
+	public void setButtonVals(Integer[] buttonVals) {
+		this.buttonVals = buttonVals;
+		int cancelPos = -1;
+		for (int i = 0; i < buttonVals.length; i++) {
+			Integer val = buttonVals[i];
+			if (val == SWT.CANCEL) {
+				cancelPos = i;
+				break;
+			}
+		}
+		if (cancelPos >= 0) {
+  		if (Constants.isOSX && cancelPos != 0) {
+				String cancelButton = buttonIDs[cancelPos];
+
+				for (int i = cancelPos; i > 0; i--) {
+					if (defaultButtonPos == i) {
+						defaultButtonPos = i - 1;
+					}
+					this.buttonIDs[i] = this.buttonIDs[i - 1];
+					this.buttonVals[i] = this.buttonVals[i - 1];
+				}
+				if (defaultButtonPos == 0) {
+					defaultButtonPos = 1;
+				}
+				buttonIDs[0] = cancelButton;
+				buttonVals[0] = SWT.CANCEL;
+			} // else if (cancelPos != buttons.length - 1) { // TODO: move to end
+		}
+	}
+	
+	private int getButtonVal(int buttonPos) {
+		if (buttonVals == null) {
+			return buttonPos;
+		}
+		if (buttonPos < 0 || buttonPos >= buttonVals.length) {
+			return SWT.CANCEL;
+		}
+		return buttonVals[buttonPos].intValue();
+	}
+
+	
+	public void setSubTitle(String s) {
+		subtitle = s;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#getAutoCloseInMS()
+	 */
+	public int getAutoCloseInMS() {
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#getHtml()
+	 */
+	public String getHtml() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#getRememberID()
+	 */
+	public String getRememberID() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#getRememberText()
+	 */
+	public String getRememberText() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#isAutoClosed()
+	 */
+	public boolean isAutoClosed() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#open(com.aelitis.azureus.ui.UserPrompterResultListener)
+	 */
+	public void open(final UserPrompterResultListener l) {
+		opened = true;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				// catch someone calling close() while we are opening
+				if (closed) {
+					return;
+				}
+				synchronized (VuzeMessageBox.this) {
+					_open(l);
+				}
+			}
+		});
+	}
+
+	protected void _open(UserPrompterResultListener l) {
+		if (l != null) {
+  		synchronized (resultListeners) {
+  			resultListeners.add(l);
+  		}
+		}
+		dlg = new SkinnedDialog("skin3_dlg_generic", "shell", SWT.DIALOG_TRIM) {
+			protected void setSkin(SWTSkin skin) {
+				super.setSkin(skin);
+				
+				//skin.DEBUGLAYOUT = true;
+				
+				VuzeMessageBox.this.skin = skin;
+				synchronized (listRBs) {
+					for (rbInfo rb : listRBs) {
+						addResourceBundle(rb.cla, rb.path, rb.name);
+					}
+					listRBs.clear();
+				}
+
+			}
+			
+			public void open() {
+				
+				super.open();
+				
+					// need to defer setting the default button to here as otherwise it doesn't
+					// work (on windows at least...)
+				
+				if( def_button != null ){
+					def_button.getShell().setDefaultButton(def_button);
+				}
+			}
+		};
+		
+		dlg.setTitle(title);
+		dlg.addCloseListener(this);
+
+		SWTSkinObjectText soTopTitle = (SWTSkinObjectText) skin.getSkinObject("top-title");
+		if (soTopTitle != null) {
+			soTopTitle.setText(subtitle == null ? title : subtitle);
+		}
+
+		SWTSkinObjectText soText = (SWTSkinObjectText) skin.getSkinObject("middle-title");
+		if (soText != null) {
+			soText.setText(text);
+		}
+		
+		if (iconResource != null) {
+  		SWTSkinObjectImage soTopLogo = (SWTSkinObjectImage) dlg.getSkin().getSkinObject("top-logo");
+  		if (soTopLogo != null) {
+  			soTopLogo.setImageByID(iconResource, null);
+  		}
+		}
+		
+		if (textIconResource != null) {
+  		SWTSkinObjectImage soIcon = (SWTSkinObjectImage) dlg.getSkin().getSkinObject("text-icon");
+  		if (soIcon != null) {
+  			soIcon.setImageByID(textIconResource, null);
+  		}
+		}
+		
+		if (iconResource == null && textIconResource == null) {
+			soTopTitle.setStyle(soText.getStyle() & ~(SWT.RIGHT | SWT.CENTER));
+		}
+		
+		SWTSkinObjectContainer soBottomArea = (SWTSkinObjectContainer) skin.getSkinObject("bottom-area");
+		if (soBottomArea != null) {
+			if (buttonIDs.length == 0) {
+				soBottomArea.setVisible(false);
+			} else {
+				createButtons(soBottomArea);
+			}
+		}
+
+		if (vuzeMessageBoxListener != null) {
+			soExtra = (SWTSkinObjectContainer) skin.getSkinObject("middle-extra");
+			try {
+				vuzeMessageBoxListener.shellReady(dlg.getShell(), soExtra);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+
+		if (closed) {
+			return;
+		}
+		dlg.open();
+	}
+
+	private void createButtons(SWTSkinObjectContainer soBottomArea) {
+		FormData fd;
+		Composite cBottomArea = soBottomArea.getComposite();
+		Composite cCenterH = new Composite(cBottomArea, SWT.NONE);
+		fd = new FormData();
+		fd.height = 1;
+		fd.width = 1;
+		fd.left = new FormAttachment(0);
+		fd.right = new FormAttachment(100);
+		cCenterH.setLayoutData(fd);
+
+		Composite cCenterV = new Composite(cBottomArea, SWT.NONE);
+		fd = new FormData();
+		fd.width = 1;
+		fd.height = 1;
+		fd.top = new FormAttachment(0);
+		fd.bottom = new FormAttachment(100);
+		cCenterV.setLayoutData(fd);
+
+		Composite cButtonArea = new Composite(cBottomArea, SWT.NONE);
+		// Fix button BG not right on Win7
+		cButtonArea.setBackgroundMode(SWT.INHERIT_FORCE);
+		fd = new FormData();
+		fd.top = new FormAttachment(cCenterV, 0, SWT.CENTER);
+		fd.left = new FormAttachment(cCenterH, 0, SWT.CENTER);
+		cButtonArea.setLayoutData(fd);
+
+		RowLayout rowLayout = new RowLayout(SWT.HORIZONTAL);
+		rowLayout.center = true;
+		rowLayout.spacing = 8;
+		rowLayout.pack = false;
+		cButtonArea.setLayout(rowLayout);
+
+		buttons = new Button[buttonIDs.length];
+		for (int i = 0; i < buttonIDs.length; i++) {
+			String buttonText = buttonIDs[i];
+			if (buttonText == null) {
+				continue;
+			}
+			Button button = buttons[i] = new Button(cButtonArea, SWT.PUSH);
+			int buttonVal = buttonVals == null || i >= buttonVals.length ? i : buttonVals[i];
+			Boolean b = buttonsEnabled.get(buttonVal);
+			if (b == null) {
+				b = Boolean.TRUE;
+			}
+			button.setEnabled(b);
+			button.setText(buttonText);
+
+			RowData rowData = new RowData();
+			Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+			size.x += BUTTON_PADDING;
+			if (size.x < MIN_BUTTON_WIDTH) {
+				size.x = MIN_BUTTON_WIDTH;
+			}
+			rowData.width = size.x;
+			button.setLayoutData(rowData);
+
+			if (defaultButtonPos == i) {
+				def_button = button;
+			}
+			button.setData("ButtonNo", new Integer(i));
+			button.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event event) {
+					close(((Number) event.widget.getData("ButtonNo")).intValue());
+				}
+			});
+		}
+
+		cBottomArea.getParent().layout(true, true);
+		
+
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setAutoCloseInMS(int)
+	 */
+	public void setAutoCloseInMS(int autoCloseInMS) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setHtml(java.lang.String)
+	 */
+	public void setHtml(String html) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setIconResource(java.lang.String)
+	 */
+	public void setIconResource(String resource) {
+		this.iconResource = resource;
+		if (dlg != null) {
+  		SWTSkinObjectImage soTopLogo = (SWTSkinObjectImage) dlg.getSkin().getSkinObject("top-logo");
+  		if (soTopLogo != null) {
+  			soTopLogo.setImageByID(iconResource, null);
+  		}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setRelatedObject(java.lang.Object)
+	 */
+	public void setRelatedObject(Object relatedObject) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setRelatedObjects(java.lang.Object[])
+	 */
+	public void setRelatedObjects(Object[] relatedObjects) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setRemember(java.lang.String, boolean, java.lang.String)
+	 */
+	public void setRemember(String rememberID, boolean rememberByDefault,
+			String rememberText) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setRememberText(java.lang.String)
+	 */
+	public void setRememberText(String rememberText) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#setUrl(java.lang.String)
+	 */
+	public void setUrl(String url) {
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.UIFunctionsUserPrompter#waitUntilClosed()
+	 */
+	public int waitUntilClosed() {
+		if (opened) {
+			final AESemaphore2 sem = new AESemaphore2("waitUntilClosed");
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (dlg == null) {
+						sem.release();
+						return;
+					}
+					if (!opened) {
+						dlg.open();
+					}
+					Shell shell = dlg.getShell();
+					if (shell == null || shell.isDisposed()) {
+						sem.release();
+						return;
+					}
+
+					shell.addDisposeListener(new DisposeListener() {
+						public void widgetDisposed(DisposeEvent e) {
+							sem.release();
+						}
+					});
+				}
+			});
+
+			if (Utils.isThisThreadSWT()) {
+				// on swt thread, so execSWTThread just ran and we should have a shell
+				if (dlg != null) {
+					Shell shell = dlg.getShell();
+					if (shell != null) {
+						Display d = shell.getDisplay();
+						while (!shell.isDisposed()) {
+							if (!d.readAndDispatch()) {
+								d.sleep();
+							}
+						}
+					}
+					return getButtonVal(result);
+				}
+			}
+			sem.reserve();
+		}
+
+		return getButtonVal(result);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener#skinDialogClosed(com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog)
+	 */
+	public void skinDialogClosed(SkinnedDialog dialog) {
+		synchronized (resultListeners) {
+			int realResult = getButtonVal(result);
+			for (UserPrompterResultListener l : resultListeners) {
+				try {
+					l.prompterClosed(realResult);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			}
+		}
+	}
+
+	public void setListener(VuzeMessageBoxListener l) {
+		this.vuzeMessageBoxListener = l;
+	}
+
+	/**
+	 * @deprecated Since buttons can swap around, you should use {@link #closeWithButtonVal(int)}
+	 */
+	public void close(int buttonNo) {
+		synchronized (VuzeMessageBox.this) {
+  		this.closed = true;
+  		this.result = buttonNo;
+  		if (dlg != null) {
+  			dlg.close();
+  		}
+		}
+	}
+	
+	private int getButtonPosFromVal(int buttonVal) {
+		int pos = buttonVal;
+		if (buttonVals != null) {
+			for (int i = 0; i < buttonVals.length; i++) {
+				int val = buttonVals[i];
+				if (buttonVal == val) {
+					pos = i;
+					break;
+				}
+			}
+		}
+		return pos;
+	}
+
+	public void closeWithButtonVal(int buttonVal) {
+		synchronized (VuzeMessageBox.this) {
+  		this.closed = true;
+  		this.result = getButtonPosFromVal(buttonVal);
+  		if (dlg != null) {
+  			dlg.close();
+  		}
+		}
+	}
+
+	public void addResourceBundle(Class cla, String path, String name) {
+
+		synchronized (listRBs) {
+			if (skin == null) {	
+				listRBs.add(new rbInfo(cla, path, name));
+				return;
+			}
+		}
+
+		String sFile = path + name;
+		ClassLoader loader = cla.getClassLoader();
+		ResourceBundle subBundle = ResourceBundle.getBundle(sFile,
+				Locale.getDefault(), loader);
+		
+
+		SWTSkinProperties skinProperties = skin.getSkinProperties();
+		skinProperties.addResourceBundle(subBundle, path, loader);
+	}
+
+	public void setTextIconResource(String resource) {
+		this.textIconResource = resource;
+		if (dlg != null) {
+  		SWTSkinObjectImage soIcon = (SWTSkinObjectImage) dlg.getSkin().getSkinObject("text-icon");
+  		if (soIcon != null) {
+  			soIcon.setImageByID(textIconResource, null);
+  		}
+		}
+	}
+	
+	public void addListener(UserPrompterResultListener l) {
+		if (l == null) {
+			return;
+		}
+		synchronized (resultListeners) {
+			resultListeners.add(l);
+		}
+	}
+	
+	public void setDefaultButtonByPos(int pos) {
+		if (dlg == null) {
+			defaultButtonPos = pos;
+		}
+	}
+
+	
+	private static class rbInfo {
+		public rbInfo(Class cla, String path, String name) {
+			super();
+			this.cla = cla;
+			this.path = path;
+			this.name = name;
+		}
+		Class cla;
+		String path;
+		String name;
+	}
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBoxListener.java b/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBoxListener.java
new file mode 100644
index 0000000..eb9610f
--- /dev/null
+++ b/com/aelitis/azureus/ui/swt/views/skin/VuzeMessageBoxListener.java
@@ -0,0 +1,10 @@
+package com.aelitis.azureus.ui.swt.views.skin;
+
+import org.eclipse.swt.widgets.Shell;
+
+import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
+
+public interface VuzeMessageBoxListener
+{
+	public void shellReady(Shell shell, SWTSkinObjectContainer soExtra);
+}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java b/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
index 2d1e29b..44b39ab 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/WelcomeView.java
@@ -23,6 +23,10 @@ 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.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.mdi.MdiCloseListener;
 import com.aelitis.azureus.ui.skin.SkinConstants;
 import com.aelitis.azureus.ui.swt.browser.BrowserContext.loadingListener;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
@@ -32,8 +36,6 @@ import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.ContentNetworkUtils;
 
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarCloseListener;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
 
 /**
  * @author TuxPaper
@@ -43,10 +45,24 @@ import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
 public class WelcomeView
 	extends SkinView
 {
+	private static boolean waitLoadingURL = true;
+	
+	private static WelcomeView instance;
+
 	private SWTSkinObjectBrowser browserSkinObject;
 
+	private SWTSkinObject skinObject;
+
+	public Object skinObjectDestroyed(SWTSkinObject skinObject, Object params) {
+		instance = null;
+		return super.skinObjectDestroyed(skinObject, params);
+	}
+
 	public Object skinObjectInitialShow(final SWTSkinObject skinObject,
 			Object params) {
+		
+		this.skinObject = skinObject;
+		instance = this;
 		browserSkinObject = (SWTSkinObjectBrowser) skin.getSkinObject(
 				SkinConstants.VIEWID_BROWSER_WELCOME, soMain);
 
@@ -60,7 +76,27 @@ public class WelcomeView
 		});
 
 		COConfigurationManager.setParameter("v3.Show Welcome", false);
+		
+		openURL();
+
+		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+		MdiEntry entry = mdi.getEntry(SideBar.SIDEBAR_SECTION_WELCOME);
+		entry.addListener(new MdiCloseListener() {
+			public void mdiEntryClosed(MdiEntry entry, boolean userClosed) {
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				if (mdi != null) {
+					mdi.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
+				}
+			}
+		});
 
+		return null;
+	}
+
+	private void openURL() {
+		if (waitLoadingURL) {
+			return;
+		}
 		Object o = skinObject.getData("CreationParams");
 		if (o instanceof String) {
 			browserSkinObject.setURL((String) o);
@@ -69,17 +105,12 @@ public class WelcomeView
 					ConstantsVuze.getDefaultContentNetwork(), ContentNetwork.SERVICE_WELCOME);
 			browserSkinObject.setURL(sURL);
 		}
+	}
 
-		SideBarEntrySWT entry = SideBar.getEntry(SideBar.SIDEBAR_SECTION_WELCOME);
-		entry.addListener(new SideBarCloseListener() {
-			public void sidebarClosed(SideBarEntry entry) {
-				SideBar sidebar = (SideBar) SkinViewManager.getByClass(SideBar.class);
-				if (sidebar != null) {
-					sidebar.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
-				}
-			}
-		});
-
-		return null;
+	public static void setWaitLoadingURL(boolean waitLoadingURL) {
+		WelcomeView.waitLoadingURL = waitLoadingURL;
+		if (!waitLoadingURL && instance != null) {
+			instance.openURL();
+		}
 	}
 }
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 65a7a21..5bde2e3 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBar.java
@@ -18,88 +18,64 @@
 
 package com.aelitis.azureus.ui.swt.views.skin.sidebar;
 
-import java.lang.reflect.Constructor;
-import java.util.*;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
-import org.eclipse.swt.events.*;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
 import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.*;
+import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.*;
-
 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.internat.MessageText;
+import org.gudy.azureus2.core3.config.impl.ConfigurationChecker;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.download.Download;
+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.UIPluginView;
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
-import org.gudy.azureus2.plugins.ui.menus.MenuManager;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarDropListener;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry;
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionHolder;
+import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionRepository;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
 import org.gudy.azureus2.ui.swt.MenuBuildUtils;
 import org.gudy.azureus2.ui.swt.URLTransfer;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.*;
-import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo;
-import org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-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;
-
-import com.aelitis.azureus.activities.VuzeActivitiesEntry;
-import com.aelitis.azureus.activities.VuzeActivitiesListener;
-import com.aelitis.azureus.activities.VuzeActivitiesManager;
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.views.IViewAlwaysInitialize;
+
 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.core.torrent.PlatformTorrentUtils;
-import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.common.table.TableView;
-import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.common.updater.UIUpdater;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoListener;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryCreationListener;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.shells.AuthorizeWindow;
+import com.aelitis.azureus.ui.swt.mdi.BaseMDI;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener;
 import com.aelitis.azureus.ui.swt.skin.*;
 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnabler;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarEnablerSelectedContent;
-import com.aelitis.azureus.ui.swt.toolbar.ToolBarItem;
-import com.aelitis.azureus.ui.swt.utils.ColorCache;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUI;
-import com.aelitis.azureus.ui.swt.utils.ContentNetworkUI.ContentNetworkImageLoadedListener;
-import com.aelitis.azureus.ui.swt.views.skin.*;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
 import com.aelitis.azureus.util.ConstantsVuze;
 import com.aelitis.azureus.util.ContentNetworkUtils;
-import com.aelitis.azureus.util.MapUtils;
 
 /**
  * @author TuxPaper
@@ -107,69 +83,25 @@ import com.aelitis.azureus.util.MapUtils;
  *
  */
 public class SideBar
-	extends SkinView
-	implements UIUpdatable, ViewTitleInfoListener
+	extends BaseMDI
+	implements ObfusticateImage, AEDiagnosticsEvidenceGenerator
 {
-	private static final boolean END_INDENT = Constants.isLinux || Constants.isWindows2000 || Constants.isWindows9598ME;
-	
-	private static final boolean USE_PAINTITEM = Utils.isCocoa || Constants.isWindows;
-	
-	// 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 = !Constants.isWindows;
-	
-	private static final boolean HIDE_NATIVE_EXPANDER = false;
-
-	private static final int SIDEBAR_SPACING = 2;
-
-	public static final String SIDEBAR_SECTION_PLUGINS = "Plugins";
-
-	public static final String SIDEBAR_SECTION_LIBRARY = "Library";
-
-	public static final String SIDEBAR_SECTION_LIBRARY_DL = "LibraryDL";
-
-	public static final String SIDEBAR_SECTION_LIBRARY_CD = "LibraryCD";
-
-	public static final String SIDEBAR_SECTION_LIBRARY_UNOPENED = "LibraryUnopened";
-
-	public static final String SIDEBAR_SECTION_TOOLS = "Tools";
-
-	public static String SIDEBAR_SECTION_BROWSE = "ContentNetwork.1";
-
-	public static final String SIDEBAR_SECTION_WELCOME = "Welcome";
-
-	public static final String SIDEBAR_SECTION_SUBSCRIPTIONS = "Subscriptions";
-
-	public static final String SIDEBAR_SECTION_DEVICES = "Devices";
-	
-	public static final String SIDEBAR_SECTION_RELATED_CONTENT = "RelatedContent";
-
-	public static final boolean SHOW_ALL_PLUGINS = false;
+	protected static final boolean END_INDENT = Constants.isLinux
+			|| Constants.isWindows2000 || Constants.isWindows9598ME;
 
-	public static final boolean SHOW_TOOLS = false;
-	
-	public static final boolean SHOW_DEVICES = true;
+	private static final boolean USE_PAINTITEM = !Utils.isCarbon;
 
-	public static final String SIDEBAR_SECTION_ACTIVITIES = "Activity";
-
-	private static final int IMAGELEFT_SIZE = 20;
-
-	private static final int IMAGELEFT_GAP = 5;
-
-	private static final boolean ALWAYS_IMAGE_GAP = true;
+	// 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 = !Constants.isWindows && !Utils.isGTK;
 
-	private static final String[] default_indicator_colors = {
-		"#000000",
-		"#000000",
-		"#166688",
-		"#1c2056"
-	};
+	protected static final boolean USE_NATIVE_EXPANDER = Utils.isGTK;
 
-	private static final boolean DO_OUR_OWN_TREE_INDENT = false;
+	private static final boolean GAP_BETWEEN_LEVEL_1 = true;
 
 	private SWTSkin skin;
 
-	private SWTSkinObject soSideBarContents;
+	private SWTSkinObjectContainer soSideBarContents;
 
 	private SWTSkinObject soSideBarList;
 
@@ -179,172 +111,62 @@ public class SideBar
 
 	private Font font;
 
-	private SideBarEntrySWT currentSideBarEntry;
-
-	private static Map mapTitleInfoToEntry = new LightHashMap();
-
-	private static Map mapIdToEntries = new LightHashMap();
-
-	private static List listTreeItemsNoTitleInfo = new ArrayList();
-
-	private static DisposeListener disposeTreeItemListener;
-
-	private CopyOnWriteList listeners = new CopyOnWriteList();
-
-	double lastPercent = 0.8;
-
-	private Color bg;
-
-	private Color fg;
-
-	private Color bgSel;
-
-	private Color fgSel;
-
-	private Color colorFocus;
-
-	private Image imgClose;
-
 	private SWTSkinObject soSideBarPopout;
 
 	private SelectionListener dropDownSelectionListener;
 
-	private ImageLoader imageLoader;
-
-	private int maxIndicatorWidth;
-
-	private Image imgCloseSelected;
-
-	private static Map mapAutoOpen = new LightHashMap();
-
-	private Image treeImage;
-
-	private Image lastImage;
-
-	//private Image imgUntwist;
-
-	//private Image imgTwist;
-
-	private Shell shellFade;
-
 	private DropTarget dropTarget;
 
 	protected SideBarEntrySWT draggingOver;
 
-	public static SideBar instance = null;
-
-	static {
-		SIDEBAR_SECTION_BROWSE = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
-
-		disposeTreeItemListener = new DisposeListener() {
-			public void widgetDisposed(final DisposeEvent e) {
-				final TreeItem treeItem = (TreeItem) e.widget;
-				final Tree tree = treeItem.getParent();
-				final int itemIndex = tree.indexOf(treeItem);
-				final String id = (String) treeItem.getData("Plugin.viewID");
-				Utils.execSWTThreadLater(0, new AERunnable() {
-					public void runSupport() {
-						// even though execThreadLater will not run on close off app because
-						// the display is disposed, do a double chek of tree disposal just
-						// in case.  We don't want to trigger close listeners or
-						// remove autoopen parameters if the user is closing the app (as
-						// opposed to closing  the sidebar)
-						if (tree.isDisposed()) {
-							return;
-						}
-
-						listTreeItemsNoTitleInfo.remove(treeItem);
-
-						//TreeItem currentItem = treeItem.getParent().getSelection()[0];
-
-						if (id != null) {
-							try {
-								SideBarEntrySWT entry = getEntry(id);
-								entry.treeItem = null;
-
-								entry.triggerCloseListeners();
-
-								if (entry.iview != null) {
-									IView iviewDelete = entry.iview;
-									entry.iview = null;
-									iviewDelete.delete();
-								}
-								if (entry.skinObject != null) {
-									SWTSkinObject so = entry.skinObject;
-									entry.skinObject = null;
-									so.getSkin().removeSkinObject(so);
-								}
-								COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
-
-								if (Constants.isOSX && !tree.isDisposed()
-										&& tree.getSelectionCount() == 0) {
-
-									if (entry.parentID != null) {
-										entry.getSidebar().showEntryByID(entry.parentID);
-									} else {
-										int i = itemIndex;
-										if (i >= tree.getItemCount() || i < 0) {
-											i = tree.getItemCount() - 1;
-										}
-										TreeItem item = tree.getItem(i);
-										entry.getSidebar().itemSelected(item);
-									}
-								}
-							} catch (Exception e2) {
-								Debug.out(e2);
-							}
-
-							mapAutoOpen.remove(id);
-							mapIdToEntries.remove(id);
+	private Color fg;
 
-							return;
-						}
+	private Color bg;
 
-						// find treeitem..
-						for (Iterator iter = mapIdToEntries.keySet().iterator(); iter.hasNext();) {
-							String id = (String) iter.next();
-							SideBarEntrySWT entry = getEntry(id);
-							if (entry != null && entry.treeItem == treeItem) {
-								iter.remove();
-							}
-						}
+	private List<MdiSWTMenuHackListener> listMenuHackListners;
 
-					}
-				});
-			}
-		};
-	}
+	public static SideBar instance = null;
 
 	public SideBar() {
+		super();
 		if (instance == null) {
 			instance = this;
 		}
+		AEDiagnostics.addEvidenceGenerator(this);
 	}
 
 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectCreated(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
 	public Object skinObjectCreated(SWTSkinObject skinObject, Object params) {
+		super.skinObjectCreated(skinObject, params);
+
 		skin = skinObject.getSkin();
 
-		soSideBarContents = skin.getSkinObject("sidebar-contents");
+		soSideBarContents = (SWTSkinObjectContainer) skin.getSkinObject("sidebar-contents");
 		soSideBarList = skin.getSkinObject("sidebar-list");
 		soSideBarPopout = skin.getSkinObject("sidebar-pop");
 
-		imageLoader = skin.getImageLoader(skinObject.getProperties());
-		imgClose = imageLoader.getImage("image.sidebar.closeitem");
-		imgCloseSelected = imageLoader.getImage("image.sidebar.closeitem-selected");
-		//imgTwist = imageLoader.getImage("image.sidebar.twist");
-		//imgUntwist = imageLoader.getImage("image.sidebar.untwist");
+		if (ConfigurationChecker.isNewVersion()
+				&& Constants.compareVersions(Constants.AZUREUS_VERSION, "4.5.0.4") == 0) {
+			final SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash");
+			if (soSash != null) {
+				soSash.resetWidth();
+			}
+		}
 
 		// addTestMenus();
 
-		ViewTitleInfoManager.addListener(this);
-
 		createSideBar();
-		setupDefaultItems();
 
 		try {
-			UIFunctionsManager.getUIFunctions().getUIUpdater().addUpdater(this);
-		} catch (Exception e) {
+				// don't think this is required as the SideBar constructor (well SkinView) registers it
+			
+			UIUpdater updater = UIFunctionsManager.getUIFunctions().getUIUpdater();
+			
+			if ( !updater.isAdded( this )){
+				
+				updater.addUpdater(this);
+			}
+		} catch ( Throwable  e) {
 			Debug.out(e);
 		}
 
@@ -415,66 +237,32 @@ public class SideBar
 	}
 	*/
 
-	private void addMenuNotifications() {
-		PluginInterface pi = PluginInitializer.getDefaultInterface();
-		UIManager uim = pi.getUIManager();
-		MenuManager menuManager = uim.getMenuManager();
-
-		MenuItem menuItem = menuManager.addMenuItem("sidebar."
-				+ SIDEBAR_SECTION_ACTIVITIES, "v3.activity.button.readall");
-		menuItem.addListener(new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
-				for (int i = 0; i < allEntries.length; i++) {
-					VuzeActivitiesEntry entry = allEntries[i];
-					entry.setRead(true);
-				}
-			}
-		});
-	}
-
-	private void addMenuUnwatched() {
-		PluginInterface pi = PluginInitializer.getDefaultInterface();
-		UIManager uim = pi.getUIManager();
-		MenuManager menuManager = uim.getMenuManager();
-
-		MenuItem menuItem = menuManager.addMenuItem("sidebar."
-				+ SIDEBAR_SECTION_LIBRARY_UNOPENED, "v3.activity.button.watchall");
-		menuItem.addListener(new MenuItemListener() {
-			public void selected(MenuItem menu, Object target) {
-				CoreWaiterSWT.waitForCore(TriggerInThread.ANY_THREAD,
-						new AzureusCoreRunningListener() {
-							public void azureusCoreRunning(AzureusCore core) {
-								GlobalManager gm = core.getGlobalManager();
-								List downloadManagers = gm.getDownloadManagers();
-								for (Iterator iter = downloadManagers.iterator(); iter.hasNext();) {
-									DownloadManager dm = (DownloadManager) iter.next();
-
-									if (!PlatformTorrentUtils.getHasBeenOpened(dm)
-											&& dm.getAssumedComplete()) {
-										PlatformTorrentUtils.setHasBeenOpened(dm, true);
-									}
-								}
-							}
-						});
-			}
-		});
-	}
-
 	/**
 	 * 
 	 *
 	 * @since 3.1.1.1
 	 */
 	public void flipSideBarVisibility() {
+		final SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash");
+		if (soSash == null) {
+			return;
+		}
 		Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
-				SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash");
-				if (soSash.getPercent() == 0) {
-					if (lastPercent != 0) {
-						soSash.setPercent(lastPercent);
-					}
+				soSash.setAboveVisible(!soSash.isAboveVisible());
+				updateSidebarVisibility();
+			}
+		});
+	}
 
+	private void updateSidebarVisibility() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				final SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash");
+				if (soSash == null) {
+					return;
+				}
+				if (soSash.isAboveVisible()) {
 					if (soSideBarPopout != null) {
 						Object ld = soSideBarPopout.getControl().getLayoutData();
 						if (ld instanceof FormData) {
@@ -486,10 +274,6 @@ public class SideBar
 						Utils.relayout(soSideBarPopout.getControl());
 					}
 				} else {
-					// invisible
-					lastPercent = soSash.getPercent();
-					soSash.setPercent(0);
-
 					if (soSideBarPopout != null) {
 						Object ld = soSideBarPopout.getControl().getLayoutData();
 						if (ld instanceof FormData) {
@@ -507,15 +291,38 @@ public class SideBar
 
 	public boolean isVisible() {
 		SWTSkinObjectSash soSash = (SWTSkinObjectSash) skin.getSkinObject("sidebar-sash");
-		return soSash.getPercent() != 0.0;
+		if (soSash == null) {
+			return false;
+		}
+		return soSash.isAboveVisible();
 	}
 
 	// @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) {
-		// force visible on first launch
-		if (!isVisible()) {
-			flipSideBarVisibility();
-		}
+
+		UIManager ui_manager = PluginInitializer.getDefaultInterface().getUIManager();
+		ui_manager.addUIListener(new UIManagerListener() {
+			public void UIDetached(UIInstance instance) {
+			}
+			
+			public void UIAttached(UIInstance instance) {
+				if (instance instanceof UISWTInstance) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							try {
+								loadCloseables();
+							} catch (Throwable t) {
+								Debug.out(t);
+							}
+
+							setupPluginViews();
+						}
+					});
+				}
+			}
+		});
+
+		updateSidebarVisibility();
 		return null;
 	}
 
@@ -526,22 +333,17 @@ public class SideBar
 			Debug.out(e);
 		}
 
-		imageLoader = skin.getImageLoader(skinObject.getProperties());
-		if (imageLoader != null) {
-			imageLoader.releaseImage("image.sidebar.closeitem");
-			imageLoader.releaseImage("image.sidebar.closeitem-selected");
-		}
-
 		return null;
 	}
 
 	private void createSideBar() {
+		if (soSideBarList == null) {
+			return;
+		}
 		Composite parent = (Composite) soSideBarList.getControl();
 
-		// there isn't a SWT.NO_SCROLL in pre 3.4
-		final int NO_SCROLL = 1 << 4;
 		tree = new Tree(parent, SWT.FULL_SELECTION | SWT.V_SCROLL
-				| SWT.DOUBLE_BUFFERED | NO_SCROLL);
+				| SWT.DOUBLE_BUFFERED | SWT.NO_SCROLL);
 		tree.setHeaderVisible(false);
 
 		new SideBarToolTips(this, tree);
@@ -551,242 +353,300 @@ public class SideBar
 		SWTSkinProperties skinProperties = skin.getSkinProperties();
 		bg = skinProperties.getColor("color.sidebar.bg");
 		fg = skinProperties.getColor("color.sidebar.fg");
-		bgSel = skinProperties.getColor("color.sidebar.selected.bg");
-		fgSel = skinProperties.getColor("color.sidebar.selected.fg");
-		colorFocus = skinProperties.getColor("color.sidebar.focus");
 
 		tree.setBackground(bg);
 		tree.setForeground(fg);
-		
-		int fontHeight = 13 + (tree.getItemHeight() > 18 ? tree.getItemHeight() - 18 : 0); 
-
 		FontData[] fontData = tree.getFont().getFontData();
-		Utils.getFontHeightFromPX(tree.getDisplay(), fontData, null, fontHeight - 1);
-		font = new Font(tree.getDisplay(), fontData);
-		tree.setFont(font);
-		//fontData[0].setHeight(fontData[0].getHeight() + 1);
+
+		int fontHeight = (Constants.isOSX ? 11 : 12)
+				+ (tree.getItemHeight() > 18 ? tree.getItemHeight() - 18 : 0);
+
 		fontData[0].setStyle(SWT.BOLD);
-		//fontData[0].setName("Helvetica");
-		Utils.getFontHeightFromPX(tree.getDisplay(), fontData, null, fontHeight);
+		FontUtils.getFontHeightFromPX(tree.getDisplay(), fontData, null, fontHeight);
 		fontHeader = new Font(tree.getDisplay(), fontData);
+		font = FontUtils.getFontWithHeight(tree.getFont(), null, fontHeight);
+
+		tree.setFont(font);
 
 		Listener treeListener = new Listener() {
 			TreeItem lastTopItem = null;
 
 			boolean mouseDowned = false;
 
+			private boolean wasExpanded;
+
 			public void handleEvent(final Event event) {
 				TreeItem treeItem = (TreeItem) event.item;
+				Tree tree = getTree();
 
-				switch (event.type) {
-					case SWT.MeasureItem: {
-						int clientWidth = tree.getClientArea().width;
-						String text = treeItem.getText(event.index);
-						Point size = event.gc.textExtent(text);
-						if (event.x + event.width < clientWidth) {
-							event.width = size.x + event.x; // tree.getClientArea().width;
-							event.x = 0;
-						}
-						
-						if (Constants.isWindows) {
-							event.width = clientWidth - event.x;
-						}
-						int padding = 4;
-						//String id = (String) treeItem.getData("Plugin.viewID");
-						//SideBarEntrySWT entry = getSideBarInfo(id);
-						//if (entry.imageLeft != null) {
-						//padding += 4;
-						//}
+				try {
+					switch (event.type) {
+						case SWT.MeasureItem: {
+							int clientWidth = tree.getClientArea().width;
+							String text = treeItem.getText(event.index);
+							Point size = event.gc.textExtent(text);
+							if (event.x + event.width < clientWidth) {
+								event.width = size.x + event.x; // tree.getClientArea().width;
+								event.x = 0;
+							}
 
-						event.height = 24;// Math.max(event.height, size.y + padding);
+							if (Constants.isWindows) {
+								event.width = clientWidth - event.x;
+							}
 
-						break;
-					}
-					case SWT.PaintItem: {
-						if (USE_PAINTITEM) {
-							String id = (String) ((TreeItem) event.item).getData("Plugin.viewID");
-							//System.out.println("PaintItem: " + event.item + ";" + event.index + ";" + event.detail + ";" + id + ";" + event.getBounds() + ";" + event.gc.getClipping());
-							SideBarEntrySWT entry = getEntry(id);
-							paintSideBar(event, entry);
+							event.height = 20;
+
+							break;
+						}
+						case SWT.PaintItem: {
+							if (USE_PAINTITEM) {
+								SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+								//System.out.println("PaintItem: " + event.item + ";" + event.index + ";" + event.detail + ";" + id + ";" + event.getBounds() + ";" + event.gc.getClipping());
+								if (entry != null) {
+									boolean selected = currentEntry == entry
+											&& entry.isSelectable();
+
+									if (!selected) {
+										event.detail &= ~SWT.SELECTED;
+									} else {
+										event.detail |= SWT.SELECTED;
+									}
+									entry.swt_paintSideBar(event);
+								}
+							}
+							break;
 						}
-						break;
-					}
 
-					case SWT.Paint: {
-						if (HIDE_NATIVE_EXPANDER) {
-							boolean selected = (event.detail & SWT.SELECTED) > 0;
+						case SWT.Paint: {
+							//System.out.println("Paint: " + event.getBounds() + ";" + event.detail + ";" + event.index + ";" + event.gc.getClipping() + "  " + Debug.getCompressedStackTrace());
+							if (!USE_PAINT) {
+								return;
+							}
 							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);
+								SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+								Rectangle itemBounds = entry == null ? null
+										: entry.swt_getBounds();
+
+								// null itemBounds is weird, the entry must be disposed. it 
+								// happened once, so let's check..
+								if (itemBounds != null && entry != null) {
+									event.item = treeItem;
+
+									boolean selected = currentEntry == entry
+											&& entry.isSelectable();
+									event.detail = selected ? SWT.SELECTED : SWT.NONE;
+
+									Rectangle newClip = bounds.intersection(itemBounds);
+									//System.out.println("Paint " + id + " @ " + newClip);
+									event.setBounds(newClip);
+									event.gc.setClipping(newClip);
+
+									entry.swt_paintSideBar(event);
+
 									y = itemBounds.y + itemBounds.height + 1;
-  							} else {
-  								y += tree.getItemHeight();
-  							}
-  
-  							if (y > bounds.y + bounds.height) {
-  								break;
-  							}
-  							treeItem = tree.getItem(new Point(indent, y));
+								} else {
+									y += tree.getItemHeight();
+								}
+
+								if (y > bounds.y + bounds.height) {
+									break;
+								}
+								TreeItem oldTreeItem = treeItem;
+								treeItem = tree.getItem(new Point(indent, y));
+								if (oldTreeItem == treeItem) {
+									break;
+								}
 							}
-						}
 
-						
-						//System.out.println("Paint: " + event.getBounds() + ";" + event.detail + ";" + event.index + ";" + event.gc.getClipping() + "  " + Debug.getCompressedStackTrace());
-						if (!USE_PAINT) {
-							return;
-						}
-						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();
-							
-							// null itemBounds is weird, the entry must be disposed. it 
-							// happened once, so let's check..
-							if (itemBounds != null) {
-  							event.item = treeItem;
-  
-  							boolean selected = tree.getSelectionCount() == 1
-  									&& tree.getSelection()[0].equals(treeItem);
-  							event.detail = selected ? SWT.SELECTED : SWT.NONE;
-  
-  							Rectangle newClip = bounds.intersection(itemBounds);
-  							//System.out.println("Paint " + id + " @ " + newClip);
-  							event.setBounds(newClip);
-  							event.gc.setClipping(newClip);
-  
-  							paintSideBar(event, entry);
-
-  							y = itemBounds.y + itemBounds.height + 1;
-							} else {
-								y += tree.getItemHeight();
+							if (tree.getTopItem() != lastTopItem) {
+								lastTopItem = tree.getTopItem();
+								SideBarEntrySWT[] sideBarEntries = mapIdToEntry.values().toArray(
+										new SideBarEntrySWT[0]);
+								swt_updateSideBarHitAreasY(sideBarEntries);
 							}
 
-							if (y > bounds.y + bounds.height) {
-								break;
+							break;
+						}
+
+						case SWT.EraseItem: {
+							SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+							if (entry == null) {
+								event.detail = 0;
 							}
-							treeItem = tree.getItem(new Point(indent, y));
+							//event.detail &= ~SWT.FOREGROUND;
+							//event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND);
+							event.doit = true;
+							break;
 						}
 
-						if (tree.getTopItem() != lastTopItem) {
-							lastTopItem = tree.getTopItem();
-							SideBarEntrySWT[] sideBarEntries = (SideBarEntrySWT[]) mapIdToEntries.values().toArray(
-									new SideBarEntrySWT[0]);
-							updateSideBarHitAreasY(sideBarEntries);
+						case SWT.Resize: {
+							tree.redraw();
+							break;
 						}
 
-						break;
-					}
+						case SWT.Selection: {
+							if (treeItem == null) {
+								return;
+							}
+							SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+							if (entry != null && entry.isSelectable()) {
+								showEntry(entry);
+							} else if (currentEntry != null) {
+								TreeItem topItem = tree.getTopItem();
+
+								// prevent "jumping" in the case where selection is off screen
+								// setSelection would jump the item on screen, and then
+								// showItem would jump back to where the user was.
+								tree.setRedraw(false);
+								TreeItem ti = ((SideBarEntrySWT) currentEntry).getTreeItem();
+								if (ti != null) {
+									tree.setSelection(ti);
+								}
 
-					case SWT.EraseItem: {
-						//event.detail &= ~SWT.FOREGROUND;
-						//event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND);
-						event.doit = true;
-						break;
-					}
+								tree.setTopItem(topItem);
+								tree.setRedraw(true);
 
-					case SWT.Resize: {
-						tree.redraw();
-						break;
-					}
+								event.doit = false;
+							}
+							break;
+						}
 
-					case SWT.Selection: {
-						itemSelected(treeItem);
-						break;
-					}
+						case SWT.MouseMove: {
+							int indent = END_INDENT ? tree.getClientArea().width - 1 : 0;
+							treeItem = tree.getItem(new Point(indent, event.y));
+							SideBarEntrySWT entry = (SideBarEntrySWT) (treeItem == null
+									? null : treeItem.getData("MdiEntry"));
+
+							int cursorNo = SWT.CURSOR_ARROW;
+							if (treeItem != null) {
+								Rectangle closeArea = (Rectangle) treeItem.getData("closeArea");
+								if (closeArea != null && closeArea.contains(event.x, event.y)) {
+									cursorNo = SWT.CURSOR_HAND;
+								} else if (entry != null && !entry.isCollapseDisabled()
+										&& treeItem.getItemCount() > 0) {
+									cursorNo = SWT.CURSOR_HAND;
+								}
+							}
 
-					case SWT.MouseDown: {
-						mouseDowned = true;
-					}
+							Cursor cursor = event.display.getSystemCursor(cursorNo);
+							if (tree.getCursor() != cursor) {
+								tree.setCursor(cursor);
+							}
 
-					case SWT.MouseUp: {
-						if (!mouseDowned) {
-							return;
-						}
-						mouseDowned = false;
-						if (tree.getItemCount() == 0 || event.button != 1) {
-							return;
-						}
-						int indent = END_INDENT ? tree.getClientArea().width - 1
-								: 0;
-						treeItem = tree.getItem(new Point(indent, event.y));
-						if (treeItem == null) {
-							return;
+							if (treeItem != null) {
+								wasExpanded = entry != null && entry.isExpanded();
+							} else {
+								wasExpanded = false;
+							}
+							break;
 						}
-						String id = (String) treeItem.getData("Plugin.viewID");
-						SideBarEntrySWT entry = getEntry(id);
-
-						Rectangle closeArea = (Rectangle) treeItem.getData("closeArea");
-						if (closeArea != null && closeArea.contains(event.x, event.y)) {
-							treeItem.dispose();
-						} else if (currentSideBarEntry != entry && Constants.isOSX) {
-							itemSelected(entry.treeItem);
+
+						case SWT.MouseDown: {
+							mouseDowned = true;
+							break;
 						}
 
-						SideBarVitalityImage[] vitalityImages = entry.getVitalityImages();
-						for (int i = 0; i < vitalityImages.length; i++) {
-							SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
-							if (!vitalityImage.isVisible()) {
-								continue;
+						case SWT.MouseUp: {
+							if (!mouseDowned) {
+								return;
+							}
+							mouseDowned = false;
+							if (tree.getItemCount() == 0 || event.button != 1) {
+								return;
 							}
-							Rectangle hitArea = vitalityImage.getHitArea();
-							if (hitArea == null) {
-								continue;
+							int indent = END_INDENT ? tree.getClientArea().width - 1 : 0;
+							treeItem = tree.getItem(new Point(indent, event.y));
+							if (treeItem == null) {
+								return;
 							}
-							if (hitArea.contains(event.x, event.y)) {
-								vitalityImage.triggerClickedListeners(event.x, event.y);
-								break;
+							SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+
+							Rectangle closeArea = (Rectangle) treeItem.getData("closeArea");
+							if (closeArea != null && closeArea.contains(event.x, event.y)) {
+								treeItem.dispose();
+								return;
+							} else if (currentEntry != entry && Constants.isOSX) {
+								showEntry(entry);
 							}
-						}
 
-						break;
-					}
+							if (entry != null) {
+								MdiEntryVitalityImage[] vitalityImages = entry.getVitalityImages();
+								for (int i = 0; i < vitalityImages.length; i++) {
+									SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
+									if (vitalityImage == null || !vitalityImage.isVisible()) {
+										continue;
+									}
+									Rectangle hitArea = vitalityImage.getHitArea();
+									if (hitArea == null) {
+										continue;
+									}
+									// setHitArea needs it relative to entry
+									Rectangle itemBounds = entry.swt_getBounds();
+									int relY = event.y - (itemBounds == null ? 0 : itemBounds.y);
+
+									if (hitArea.contains(event.x, relY)) {
+										vitalityImage.triggerClickedListeners(event.x, relY);
+										return;
+									}
+								}
+
+								if (!entry.isCollapseDisabled() && treeItem.getItemCount() > 0) {
+									if (!entry.isSelectable() || event.x < 20) {
+										// Note: On Windows, user can expand row by clicking the invisible area where the OS twisty would be
+  									MdiEntry currentEntry = getCurrentEntry();
+  									if (currentEntry != null
+  											&& entry.getId().equals(currentEntry.getParentID())) {
+  										showEntryByID(SIDEBAR_SECTION_LIBRARY);
+  									}
+  									entry.setExpanded(!wasExpanded);
+  									wasExpanded = !wasExpanded;
+									}
+								}
+							}
 
-					case SWT.Dispose: {
-						fontHeader.dispose();
-						font.dispose();
-						if (dropTarget != null && !dropTarget.isDisposed()) {
-							dropTarget.dispose();
+							break;
 						}
-						saveCloseables();
 
-						break;
-					}
+						case SWT.Dispose: {
+							fontHeader.dispose();
+							font.dispose();
+							if (dropTarget != null && !dropTarget.isDisposed()) {
+								dropTarget.dispose();
+							}
+							saveCloseables();
+
+							break;
+						}
 
-					case SWT.Collapse: {
-						String id = (String) treeItem.getData("Plugin.viewID");
-						SideBarEntrySWT entry = getEntry(id);
+						case SWT.Collapse: {
+							SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
 
-						if (entry.disableCollapse) {
-							tree.setRedraw(false);
-							Display.getDefault().asyncExec(new Runnable() {
-								public void run() {
-									((TreeItem) event.item).setExpanded(true);
-									tree.setRedraw(true);
+							if (entry.isCollapseDisabled()) {
+								tree.setRedraw(false);
+								Display.getDefault().asyncExec(new Runnable() {
+									public void run() {
+										((TreeItem) event.item).setExpanded(true);
+										getTree().setRedraw(true);
+									}
+								});
+							} else {
+								MdiEntry currentEntry = getCurrentEntry();
+								if (currentEntry != null
+										&& entry.getId().equals(currentEntry.getParentID())) {
+									showEntryByID(SIDEBAR_SECTION_LIBRARY);
 								}
-							});
+							}
+							break;
 						}
-						break;
-					}
 
+					}
+				} catch (Exception e) {
+					Debug.out(e);
 				}
 			}
 		};
@@ -805,11 +665,13 @@ public class SideBar
 		tree.addListener(SWT.MouseUp, treeListener);
 		tree.addListener(SWT.MouseDown, treeListener);
 
+		// For cursor
+		tree.addListener(SWT.MouseMove, treeListener);
+
 		// to disable collapsing
 		tree.addListener(SWT.Collapse, treeListener);
 
-		dropTarget = new DropTarget(tree, DND.DROP_DEFAULT | DND.DROP_MOVE
-				| DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE);
+		dropTarget = new DropTarget(tree, DND.DROP_COPY);
 		dropTarget.setTransfer(new Transfer[] {
 			URLTransfer.getInstance(),
 			FileTransfer.getInstance(),
@@ -822,36 +684,52 @@ public class SideBar
 						event.currentDataType);
 			}
 
+			public void dragEnter(DropTargetEvent event) {
+			}
+
+			public void dragOperationChanged(DropTargetEvent event) {
+			}
+
 			// @see org.eclipse.swt.dnd.DropTargetAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
 			public void dragOver(DropTargetEvent event) {
 				TreeItem treeItem = (event.item instanceof TreeItem)
 						? (TreeItem) event.item : null;
 
 				if (treeItem != null) {
-  				String id = (String) treeItem.getData("Plugin.viewID");
-  				SideBarEntrySWT entry = getEntry(id);
-  
-  				draggingOver = entry;
+					SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+
+					draggingOver = entry;
 				} else {
 					draggingOver = null;
 				}
-				if (Constants.isOSX) {
-					tree.redraw();
-				}
-				if ((event.operations & DND.DROP_LINK) > 0)
+				if (draggingOver == null || !draggingOver.hasDropListeners()) {
+
+					boolean isTorrent = TorrentOpener.doesDropHaveTorrents(event);
+
+					if (isTorrent) {
+						event.detail = DND.DROP_COPY;
+					} else {
+						event.detail = DND.DROP_NONE;
+					}
+					draggingOver = null;
+				} else if ((event.operations & DND.DROP_LINK) > 0)
 					event.detail = DND.DROP_LINK;
-				else if ((event.operations & DND.DROP_DEFAULT) > 0)
-					event.detail = DND.DROP_DEFAULT;
 				else if ((event.operations & DND.DROP_COPY) > 0)
 					event.detail = DND.DROP_COPY;
+				else if ((event.operations & DND.DROP_DEFAULT) > 0)
+					event.detail = DND.DROP_COPY;
+
+				if (Constants.isOSX) {
+					tree.redraw();
+				}
 			}
-			
+
 			// @see org.eclipse.swt.dnd.DropTargetAdapter#dragLeave(org.eclipse.swt.dnd.DropTargetEvent)
 			public void dragLeave(DropTargetEvent event) {
 				draggingOver = null;
 				tree.redraw();
 			}
-			
+
 			public void drop(DropTargetEvent event) {
 				draggingOver = null;
 				tree.redraw();
@@ -861,8 +739,7 @@ public class SideBar
 				}
 				TreeItem treeItem = (TreeItem) event.item;
 
-				String id = (String) treeItem.getData("Plugin.viewID");
-				SideBarEntrySWT entry = getEntry(id);
+				SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
 
 				boolean handled = entry.triggerDropListeners(event.data);
 				if (!handled) {
@@ -903,14 +780,12 @@ public class SideBar
 
 				Point ptMouse = tree.toControl(e.display.getCursorLocation());
 
-				int indent = END_INDENT ? tree.getClientArea().width - 1
-						: 0;
+				int indent = END_INDENT ? tree.getClientArea().width - 1 : 0;
 				TreeItem treeItem = tree.getItem(new Point(indent, ptMouse.y));
 				if (treeItem == null) {
 					return;
 				}
-				String id = (String) treeItem.getData("Plugin.viewID");
-				SideBarEntrySWT entry = getEntry(id);
+				SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
 
 				fillMenu(menuTree, entry);
 
@@ -1019,10 +894,13 @@ public class SideBar
 
 			org.eclipse.swt.widgets.MenuItem menuItem = new org.eclipse.swt.widgets.MenuItem(
 					menuDropDown, SWT.RADIO);
-			String id = (String) treeItem.getData("Plugin.viewID");
+			SideBarEntrySWT entry = (SideBarEntrySWT) treeItem.getData("MdiEntry");
+			if (entry == null) {
+				continue;
+			}
+			String id = entry.getId();
 			menuItem.setData("Plugin.viewID", id);
-			SideBarEntrySWT entry = getEntry(id);
-			ViewTitleInfo titleInfo = entry.getTitleInfo();
+			ViewTitleInfo titleInfo = entry.getViewTitleInfo();
 			String ind = "";
 			if (titleInfo != null) {
 				String o = (String) titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT);
@@ -1031,15 +909,15 @@ public class SideBar
 					//ind = "\t" + o;
 				}
 			}
-			menuItem.setText(s + treeItem.getData("text") + ind);
+			menuItem.setText(s + entry.getTitle() + ind);
 			menuItem.addSelectionListener(dropDownSelectionListener);
-			if (currentSideBarEntry != null && currentSideBarEntry.id.equals(id)) {
+			if (currentEntry != null && currentEntry.getId().equals(id)) {
 				menuItem.setSelection(true);
 			}
 
 			TreeItem[] subItems = treeItem.getItems();
 			if (subItems.length > 0) {
-				fillDropDownMenu(menuDropDown, subItems, ++indent);
+				fillDropDownMenu(menuDropDown, subItems, indent + 1);
 			}
 		}
 	}
@@ -1049,7 +927,7 @@ public class SideBar
 	 *
 	 * @since 3.1.0.1
 	 */
-	protected void fillMenu(Menu menuTree, final SideBarEntry entry) {
+	protected void fillMenu(Menu menuTree, final MdiEntry entry) {
 		org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items;
 
 		menu_items = MenuItemManager.getInstance().getAllAsArray("sidebar");
@@ -1061,377 +939,112 @@ public class SideBar
 				}));
 
 		if (entry != null) {
+
 			menu_items = MenuItemManager.getInstance().getAllAsArray(
 					"sidebar." + entry.getId());
 
-			MenuBuildUtils.addPluginMenuItems((Composite) soMain.getControl(),
-					menu_items, menuTree, false, true,
-					new MenuBuildUtils.MenuItemPluginMenuControllerImpl(new Object[] {
-						entry
-					}));
-
-			if (currentSideBarEntry != null
-					&& currentSideBarEntry.datasource instanceof DownloadManager) {
-
-				DownloadManager[] downloads = new DownloadManager[] {
-					(DownloadManager) currentSideBarEntry.datasource
-				};
-
-				org.eclipse.swt.widgets.MenuItem mi = MenuFactory.createTorrentMenuItem(menuTree);
-
-				mi.setData("downloads", downloads);
-				mi.setData("is_detailed_view", new Boolean(true));
-			}
-		}
-	}
-	
-	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;
-			}
-			if (bgSel != null) {
-				gc.setBackground(bgSel);
-			}
-			Color color1;
-			Color color2;
-			if (tree.isFocusControl()) {
-				color1 = ColorCache.getColor(gc.getDevice(), "#166688");
-				color2 = ColorCache.getColor(gc.getDevice(), "#1c2458");
-			} else {
-				color1 = ColorCache.getColor(gc.getDevice(), "#447281");
-				color2 = ColorCache.getColor(gc.getDevice(), "#393e58");
-			}
+			if (menu_items.length == 0) {
 
-			gc.setBackground(color1);
-			gc.fillRectangle(drawBounds.x, drawBounds.y, drawBounds.width, 3);
+				UIPluginView view = entry.getView();
 
-			gc.setForeground(color1);
-			gc.setBackground(color2);
-			//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) {
-				fgText = fg;
-			}
-			if (bg != null) {
-				gc.setBackground(bg);
-			}
-
-			if (sideBarEntry == draggingOver) {
-				gc.setBackground(ColorCache.getColor(gc.getDevice(), "#2688aa"));
-			}
-			
-			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 || Constants.isWindows ? event.gc.getClipping() : event.getBounds();
-		if (drawBounds.isEmpty()) {
-			return;
-		}
-		
-		String text = (String) treeItem.getData("text");
-		if (text == null)
-			text = "";
+				if (view instanceof UISWTView) {
 
-		//Point size = event.gc.textExtent(text);
-		//Rectangle treeBounds = tree.getBounds();
-		GC gc = event.gc;
+					PluginInterface pi = ((UISWTView) view).getPluginInterface();
 
-		gc.setAntialias(SWT.ON);
-		gc.setAdvanced(true);
-		//gc.setClipping((Rectangle) null);
+					if (pi != null) {
 
-		boolean selected = (event.detail & SWT.SELECTED) > 0;
-		Color fgText = paintEntryBG(selected, gc, drawBounds, sideBarEntry);
+						final List<String> relevant_sections = new ArrayList<String>();
 
-		Rectangle treeArea = tree.getClientArea();
+						List<ConfigSectionHolder> sections = ConfigSectionRepository.getInstance().getHolderList();
 
-		gc.setFont(tree.getFont());
+						for (ConfigSectionHolder cs : sections) {
 
-		if (sideBarEntry == null) {
-			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;
-
-		//System.out.println(System.currentTimeMillis() + "] refresh " + sideBarEntry.getId() + "; " + itemBounds + ";clip=" + event.gc.getClipping() + ";eb=" + event.getBounds());
-		if (sideBarEntry.titleInfo != null) {
-			String textIndicator = (String) sideBarEntry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT);
-			if (textIndicator != null) {
-
-				Point textSize = gc.textExtent(textIndicator);
-				Point minTextSize = gc.textExtent("99");
-				if (textSize.x < minTextSize.x + 2) {
-					textSize.x = minTextSize.x + 2;
-				}
+							if (pi == cs.getPluginInterface()) {
 
-				int width = textSize.x + textSize.y / 2 + 2;
-				x1IndicatorOfs += width + SIDEBAR_SPACING;
-				int startX = treeArea.width - x1IndicatorOfs;
+								relevant_sections.add(cs.configSectionGetName());
+							}
+						}
 
-				int textOffsetY = 0;
+						if (relevant_sections.size() > 0) {
 
-				int height = textSize.y + 3;
-				int startY = itemBounds.y + (itemBounds.height - height) / 2;
+							MenuItem mi = pi.getUIManager().getMenuManager().addMenuItem(
+									"sidebar." + entry.getId(),
+									"MainWindow.menu.view.configuration");
 
-				//gc.fillRectangle(startX, startY, width, height);
+							mi.addListener(new MenuItemListener() {
+								public void selected(MenuItem menu, Object target) {
+									UIFunctions uif = UIFunctionsManager.getUIFunctions();
 
-				Pattern pattern;
-				Color color1;
-				Color color2;
+									if (uif != null) {
 
-				String[] colors = (String[]) sideBarEntry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_COLOR);
+										for (String s : relevant_sections) {
 
-				if (colors == null || colors.length != 4) {
-					colors = default_indicator_colors;
-				}
+											uif.openView(UIFunctions.VIEW_CONFIG, s);
+										}
+									}
+								}
+							});
 
-				if (selected) {
-					color1 = ColorCache.getColor(gc.getDevice(), colors[0]);
-					color2 = ColorCache.getColor(gc.getDevice(), colors[1]);
-					pattern = new Pattern(gc.getDevice(), 0, startY, 0, startY + height,
-							color1, 127, color2, 4);
-				} else {
-					color1 = ColorCache.getColor(gc.getDevice(), colors[2]);
-					color2 = ColorCache.getColor(gc.getDevice(), colors[3]);
-					pattern = new Pattern(gc.getDevice(), 0, startY, 0, startY + height,
-							color1, color2);
-				}
-				gc.setBackgroundPattern(pattern);
-				gc.fillRoundRectangle(startX, startY, width, height, textSize.y + 1,
-						height);
-				gc.setBackgroundPattern(null);
-				pattern.dispose();
-				if (maxIndicatorWidth > width) {
-					maxIndicatorWidth = width;
+							menu_items = MenuItemManager.getInstance().getAllAsArray(
+									"sidebar." + entry.getId());
+						}
+					}
 				}
-				gc.setForeground(Colors.white);
-				GCStringPrinter.printString(gc, textIndicator, new Rectangle(startX,
-						startY + textOffsetY, width, height), true, false, SWT.CENTER);
 			}
-		}
-
-		//if (x1IndicatorOfs < 30) {
-		//	x1IndicatorOfs = 30;
-		//}
-
-		if (sideBarEntry.closeable) {
-			Image img = selected ? imgCloseSelected : imgClose;
-			Rectangle closeArea = img.getBounds();
-			closeArea.x = treeArea.width - closeArea.width - SIDEBAR_SPACING
-					- x1IndicatorOfs;
-			closeArea.y = itemBounds.y + (itemBounds.height - closeArea.height) / 2;
-			x1IndicatorOfs += closeArea.width + SIDEBAR_SPACING;
-
-			//gc.setBackground(treeItem.getBackground());
-			//gc.fillRectangle(closeArea);
 
-			gc.drawImage(img, closeArea.x, closeArea.y);
-			treeItem.setData("closeArea", closeArea);
-		}
-
-		SideBarVitalityImage[] vitalityImages = sideBarEntry.getVitalityImages();
-		for (int i = 0; i < vitalityImages.length; i++) {
-			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
-			if (!vitalityImage.isVisible() || vitalityImage.getAlignment() != SWT.RIGHT) {
-				continue;
-			}
-			vitalityImage.switchSuffix(selected ? "-selected" : "");
-			Image image = vitalityImage.getImage();
-			if (image != null && !image.isDisposed()) {
-				Rectangle bounds = image.getBounds();
-				bounds.x = treeArea.width - bounds.width - SIDEBAR_SPACING
-						- x1IndicatorOfs;
-				bounds.y = itemBounds.y + (itemBounds.height - bounds.height) / 2;
-				x1IndicatorOfs += bounds.width + SIDEBAR_SPACING;
-
-				gc.drawImage(image, bounds.x, bounds.y);
-				vitalityImage.setHitArea(bounds);
-			}
-		}
+			MenuBuildUtils.addPluginMenuItems((Composite) soMain.getControl(),
+					menu_items, menuTree, false, true,
+					new MenuBuildUtils.MenuItemPluginMenuControllerImpl(new Object[] {
+						entry
+					}));
 
-		boolean	greyScale = false;
-		
-		if ( sideBarEntry.titleInfo != null ){
-		
-			Object active_state = sideBarEntry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_ACTIVE_STATE);
-		
-			if ( active_state instanceof Long ){
-			
-				greyScale = (Long)active_state == 2;
+			MdiSWTMenuHackListener[] menuHackListeners = getMenuHackListeners();
+			for (MdiSWTMenuHackListener l : menuHackListeners) {
+				try {
+					l.menuWillBeShown(entry, menuTree);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
 			}
-		}
-		
-		String suffix = selected ? "-selected" : null;
-		Image imageLeft = sideBarEntry.getImageLeft(suffix);
-		if (imageLeft == null && selected) {
-			sideBarEntry.releaseImageLeft(suffix);
-			suffix = null;
-			imageLeft = sideBarEntry.getImageLeft(null);
-		}
-		if (imageLeft != null) {
-			Rectangle bounds = imageLeft.getBounds();
-			int x = x0IndicatorOfs + ((IMAGELEFT_SIZE - bounds.width) / 2);
-			int y = itemBounds.y + ((itemBounds.height - bounds.height) / 2);
-			Rectangle clipping = gc.getClipping();
-			gc.setClipping(x0IndicatorOfs, itemBounds.y, IMAGELEFT_SIZE,
-					itemBounds.height);
-			
-			boolean drawn = false;
-			if ( greyScale ){
-				String	imageLeftID = sideBarEntry.getImageLeftID();
-				if ( imageLeftID != null ){
-					Image grey = ImageLoader.getInstance().getImage(imageLeftID + "-gray" );
-				
-					if ( grey != null ){
-						gc.drawImage( grey, x, y);
-						ImageLoader.getInstance().releaseImage(imageLeftID + "-gray" );
-						
-						drawn = true;
+			if (currentEntry instanceof SideBarEntrySWT) {
+				menuHackListeners = ((SideBarEntrySWT) entry).getMenuHackListeners();
+				for (MdiSWTMenuHackListener l : menuHackListeners) {
+					try {
+						l.menuWillBeShown(entry, menuTree);
+					} catch (Exception e) {
+						Debug.out(e);
 					}
 				}
 			}
-			
-			if ( !drawn ){
-				gc.drawImage(imageLeft, x, y);
-			}
-			sideBarEntry.releaseImageLeft(suffix);
-			gc.setClipping(clipping);
-			//			0, 0, bounds.width, bounds.height,
-			//					x0IndicatorOfs, itemBounds.y
-			//							+ ((itemBounds.height - IMAGELEFT_SIZE) / 2), IMAGELEFT_SIZE,
-			//					IMAGELEFT_SIZE);
-
-			x0IndicatorOfs += IMAGELEFT_SIZE + IMAGELEFT_GAP;
-		} else if (ALWAYS_IMAGE_GAP) {
-			x0IndicatorOfs += IMAGELEFT_SIZE + IMAGELEFT_GAP;
-		} else {
-			if (treeItem.getParentItem() != null) {
-				x0IndicatorOfs += 30 - 18;
-			}
-		}
-
-		//		gc.setAdvanced(true);
-		//		gc.setTextAntialias(SWT.ON);
-		//		gc.setAntialias(SWT.ON);
-		//		gc.setInterpolation(SWT.HIGH);
-
-		if (treeItem.getParentItem() == null) {
-			gc.setFont(fontHeader);
-			gc.setForeground(ColorCache.getColor(gc.getDevice(), "#2B2D32"));
 		}
+	}
 
-		gc.setForeground(fgText);
-		Rectangle clipping = new Rectangle(x0IndicatorOfs, itemBounds.y,
-				treeArea.width - x1IndicatorOfs - SIDEBAR_SPACING - x0IndicatorOfs,
-				itemBounds.height);
-		//System.out.println("itemBounds=" + itemBounds + ";event=" + event.getBounds() + ";" + event.gc.getClipping() + ";" + text);
-		if (drawBounds.intersects(clipping)) {
-			//gc.setClipping(clipping);
-
-			if (text.startsWith(" ")) {
-				text = text.substring(1);
-				clipping.x += 30;
-				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;
-			//gc.setClipping((Rectangle) null);
-		}
-		
-		for (int i = 0; i < vitalityImages.length; i++) {
-			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
-			if (!vitalityImage.isVisible() || vitalityImage.getAlignment() != SWT.LEFT) {
-				continue;
+	public void addListener(MdiSWTMenuHackListener l) {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				listMenuHackListners = new ArrayList<MdiSWTMenuHackListener>(1);
 			}
-			vitalityImage.switchSuffix(selected ? "-selected" : "");
-			Image image = vitalityImage.getImage();
-			if (image != null && !image.isDisposed()) {
-				Rectangle bounds = image.getBounds();
-				bounds.x = clipping.x;
-				bounds.y = itemBounds.y + (itemBounds.height - bounds.height) / 2;
-				clipping.x += bounds.width + SIDEBAR_SPACING;
-
-				if (clipping.x > (treeArea.width - x1IndicatorOfs)) {
-					vitalityImage.setHitArea(null);
-					continue;
-				}
-				gc.drawImage(image, bounds.x, bounds.y);
-				vitalityImage.setHitArea(bounds);
+			if (!listMenuHackListners.contains(l)) {
+				listMenuHackListners.add(l);
 			}
 		}
+	}
 
+	public void removeListener(MdiSWTMenuHackListener l) {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				listMenuHackListners = new ArrayList<MdiSWTMenuHackListener>(1);
+			}
+			listMenuHackListners.remove(l);
+		}
+	}
 
-		// 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 && (!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[] {
-					itemBounds.x - xStart,
-					itemBounds.y + yStart,
-					itemBounds.x - xStart + arrowSize,
-					itemBounds.y + yStart,
-					itemBounds.x - xStart + (arrowSize / 2),
-					itemBounds.y + 16,
-				});
-			} else {
-				int xStart = 15;
-				if (Utils.isCocoa) {
-					xStart -= 5;
-				}
-				int arrowSize = 8;
-				int yStart = itemBounds.height - (itemBounds.height + arrowSize) / 2;
-				gc.fillPolygon(new int[] {
-					itemBounds.x - xStart,
-					itemBounds.y + yStart,
-					itemBounds.x - xStart + arrowSize,
-					itemBounds.y + yStart + 4,
-					itemBounds.x - xStart,
-					itemBounds.y + yStart + 8,
-				});
+	public MdiSWTMenuHackListener[] getMenuHackListeners() {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				return new MdiSWTMenuHackListener[0];
 			}
-			gc.setBackground(oldBG);
-			gc.setFont(fontHeader);
+			return listMenuHackListners.toArray(new MdiSWTMenuHackListener[0]);
 		}
 	}
 
@@ -1440,16 +1053,16 @@ public class SideBar
 	 *
 	 * @since 3.1.1.1
 	 */
-	private void updateSideBarHitAreasY(SideBarEntrySWT[] entries) {
+	private void swt_updateSideBarHitAreasY(SideBarEntrySWT[] entries) {
 		for (int x = 0; x < entries.length; x++) {
 			SideBarEntrySWT entry = entries[x];
-			TreeItem treeItem = entry.treeItem;
+			TreeItem treeItem = entry.getTreeItem();
 			if (treeItem == null || treeItem.isDisposed()) {
 				continue;
 			}
-			Rectangle itemBounds = entry.getBounds();
+			Rectangle itemBounds = entry.swt_getBounds();
 
-			if (entry.closeable) {
+			if (entry.isCloseable()) {
 				Rectangle closeArea = (Rectangle) treeItem.getData("closeArea");
 				if (closeArea != null) {
 					closeArea.y = itemBounds.y + (itemBounds.height - closeArea.height)
@@ -1457,7 +1070,7 @@ public class SideBar
 				}
 			}
 
-			SideBarVitalityImage[] vitalityImages = entry.getVitalityImages();
+			MdiEntryVitalityImage[] vitalityImages = entry.getVitalityImages();
 			for (int i = 0; i < vitalityImages.length; i++) {
 				SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
 				if (!vitalityImage.isVisible()) {
@@ -1469,290 +1082,50 @@ public class SideBar
 					if (bounds == null) {
 						continue;
 					}
-					bounds.y = itemBounds.y + (itemBounds.height - bounds.height) / 2;
+					bounds.y = (itemBounds.height - bounds.height) / 2;
 				}
 			}
 		}
 	}
 
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void setupDefaultItems() {
-		TreeItem treeItem;
-
-		// Put TitleInfo in another class
-		final ViewTitleInfo titleInfoActivityView = new ViewTitleInfo() {
-			public Object getTitleInfoProperty(int propertyID) {
-				if (propertyID == TITLE_INDICATOR_TEXT) {
-					int count = 0;
-					VuzeActivitiesEntry[] allEntries = VuzeActivitiesManager.getAllEntries();
-					for (int i = 0; i < allEntries.length; i++) {
-						VuzeActivitiesEntry entry = allEntries[i];
-						if (!entry.isRead()) {
-							count++;
-						}
-					}
-					if (count > 0) {
-						return "" + count;
-					} else {
-						return null;
-					}
-				} else if (propertyID == TITLE_IMAGEID) {
-					return "image.sidebar.activity";
-				}
-				return null;
-			}
-		};
-		VuzeActivitiesManager.addListener(new VuzeActivitiesListener() {
-			public void vuzeNewsEntryChanged(VuzeActivitiesEntry entry) {
-			}
-
-			public void vuzeNewsEntriesRemoved(VuzeActivitiesEntry[] entries) {
-				ViewTitleInfoManager.refreshTitleInfo(titleInfoActivityView);
-			}
-
-			public void vuzeNewsEntriesAdded(VuzeActivitiesEntry[] entries) {
-				ViewTitleInfoManager.refreshTitleInfo(titleInfoActivityView);
-			}
-		});
-
-		SideBarEntrySWT entry;
-		ImageLoader imageLoader = ImageLoader.getInstance();
-
-		entry = createEntryFromSkinRef(null, SIDEBAR_SECTION_LIBRARY, "library",
-				MessageText.getString("sidebar." + SIDEBAR_SECTION_LIBRARY), null,
-				null, false, -1);
-		entry.setImageLeftID("image.sidebar.library");
-		entry.disableCollapse = true;
-
-		createEntryFromSkinRef(SIDEBAR_SECTION_LIBRARY, SIDEBAR_SECTION_LIBRARY_DL,
-				"library", MessageText.getString("sidebar.LibraryDL"), null, null,
-				false, -1);
-
-		createEntryFromSkinRef(SIDEBAR_SECTION_LIBRARY,
-				SIDEBAR_SECTION_LIBRARY_UNOPENED, "library",
-				MessageText.getString("sidebar.LibraryUnopened"), null, null, false, -1);
-		addMenuUnwatched();
-
-		entry = createEntryFromSkinRef(null, SIDEBAR_SECTION_BROWSE,
-				"main.area.browsetab", MessageText.getString("sidebar.VuzeHDNetwork"),
-				null, null, false, -1);
-		entry.setImageLeftID("image.sidebar.vuze");
-
-		ContentNetworkManager cnm = ContentNetworkManagerFactory.getSingleton();
-		if (cnm != null) {
-			ContentNetwork[] contentNetworks = cnm.getContentNetworks();
-			for (ContentNetwork cn : contentNetworks) {
-				if (cn == null) {
-					continue;
-				}
-				if (cn.getID() == ConstantsVuze.getDefaultContentNetwork().getID()) {
-					cn.setPersistentProperty(ContentNetwork.PP_ACTIVE, Boolean.TRUE);
-					continue;
+	protected int indexOf(final MdiEntry entryLibrary) {
+		Object o = Utils.execSWTThreadWithObject("indexOf", new AERunnableObject() {
+			public Object runSupport() {
+				TreeItem treeItem = ((SideBarEntrySWT) entryLibrary).getTreeItem();
+				if (treeItem == null) {
+					return -1;
 				}
-
-				Object oIsActive = cn.getPersistentProperty(ContentNetwork.PP_ACTIVE);
-				boolean isActive = (oIsActive instanceof Boolean)
-						? ((Boolean) oIsActive).booleanValue() : false;
-				if (isActive) {
-					createContentNetworkSideBarEntry(cn);
+				TreeItem parentItem = treeItem.getParentItem();
+				if (parentItem != null) {
+					return parentItem.indexOf(treeItem);
 				}
+				return tree.indexOf(treeItem);
 			}
+		}, 500);
+		if (o instanceof Number) {
+			return ((Number) o).intValue();
 		}
-
-		SideBarEntrySWT entryActivity = createEntryFromSkinRef(null,
-				SIDEBAR_SECTION_ACTIVITIES, "activity",
-				MessageText.getString("sidebar." + SIDEBAR_SECTION_ACTIVITIES),
-				titleInfoActivityView, null, false, -1);
-		addMenuNotifications();
-
-		//entry.setImageLeftID("image.sidebar.subscriptions");
-
-		//new TreeItem(tree, SWT.NONE).setText("Search");
-
-		if (SHOW_TOOLS) {
-			createEntryFromSkinRef(null, SIDEBAR_SECTION_TOOLS, "main.area.hood",
-					"Under The Hood", null, null, false, -1);
-
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					PeerSuperView.class.getSimpleName(), "All Peers",
-					PeerSuperView.class, true);
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					StatsView.class.getSimpleName(), "Stats", StatsView.class, true);
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					MyTrackerView.class.getSimpleName(), "My Tracker",
-					MyTrackerView.class, true);
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					MySharesView.class.getSimpleName(), "My Classic-Shares",
-					MySharesView.class, true);
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					LoggerView.class.getSimpleName(), "Logger", LoggerView.class, true);
-			createTreeItemFromIViewClass(SIDEBAR_SECTION_TOOLS,
-					ConfigView.class.getSimpleName(), "Config", ConfigView.class, true);
-		}
-
-		if (SHOW_ALL_PLUGINS) {
-			SideBarEntrySWT pluginsEntry = createEntryFromSkinRef(null,
-					SIDEBAR_SECTION_PLUGINS, "main.area.plugins", "Plugins", null, null,
-					false, -1);
-
-			IViewInfo[] pluginViewsInfo = PluginsMenuHelper.getInstance().getPluginViewsInfo();
-			for (int i = 0; i < pluginViewsInfo.length; i++) {
-				IViewInfo viewInfo = pluginViewsInfo[i];
-				treeItem = new TreeItem(pluginsEntry.treeItem, SWT.NONE);
-				treeItem.addDisposeListener(disposeTreeItemListener);
-
-				treeItem.setData("text", viewInfo.name);
-				treeItem.setData("Plugin.viewID", viewInfo.viewID);
-				SideBarEntrySWT entryPlugin = getEntry(viewInfo.viewID);
-				entryPlugin.treeItem = treeItem;
-				entryPlugin.iview = viewInfo.view;
-				entryPlugin.eventListener = viewInfo.event_listener;
-			}
-
-			TreeItem itemPluginLogs = new TreeItem(pluginsEntry.treeItem, SWT.NONE);
-			itemPluginLogs.setText("Log Views");
-			IViewInfo[] pluginLogViewsInfo = PluginsMenuHelper.getInstance().getPluginLogViewsInfo();
-			for (int i = 0; i < pluginLogViewsInfo.length; i++) {
-				IViewInfo viewInfo = pluginLogViewsInfo[i];
-				treeItem = new TreeItem(itemPluginLogs, SWT.NONE);
-				treeItem.addDisposeListener(disposeTreeItemListener);
-
-				treeItem.setData("text", viewInfo.name);
-				treeItem.setData("Plugin.viewID", viewInfo.viewID);
-				SideBarEntrySWT entryPlugin = getEntry(viewInfo.viewID);
-				entryPlugin.treeItem = treeItem;
-				entryPlugin.iview = viewInfo.view;
-				entryPlugin.eventListener = viewInfo.event_listener;
-			}
-		}
-
-		SBC_LibraryView.setupViewTitle();
-
-		// building plugin views needs UISWTInstance, which needs core.
-		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener(){
-			public void azureusCoreRunning(AzureusCore core) {
-				Utils.execSWTThread(new AERunnable(){
-					public void runSupport() {
-						setupPluginViews();
-					}
-				});
-			}
-		});
-
-		loadCloseables();
-
-		Composite parent = tree.getParent();
-
-		if (parent.isVisible()) {
-			parent.layout(true, true);
-		}
+		return -1;
 	}
 
-	protected void setupPluginViews() {
-		UISWTInstanceImpl uiSWTInstance = (UISWTInstanceImpl) UIFunctionsManagerSWT.getUIFunctionsSWT().getUISWTInstance();
-		if (uiSWTInstance != null) {
-			Map allViews = uiSWTInstance.getAllViews();
-			Object[] parentIDs = allViews.keySet().toArray();
-			for (int i = 0; i < parentIDs.length; i++) {
-				String parentID = (String) parentIDs[i];
-				Map mapSubViews = (Map) allViews.get(parentID);
-				if (mapSubViews != null) {
-					Object[] viewIDs = mapSubViews.keySet().toArray();
-					for (int j = 0; j < viewIDs.length; j++) {
-						String viewID = (String) viewIDs[j];
-						UISWTViewEventListener l = (UISWTViewEventListener) mapSubViews.get(viewID);
-						if (l != null) {
-							// TODO: Datasource
-							// TODO: Multiple open
-
-							boolean open = COConfigurationManager.getBooleanParameter(
-									"SideBar.AutoOpen." + viewID, false);
-							if (open) {
-								createTreeItemFromEventListener(parentID, null, l, viewID,
-										true, null);
-							}
-						}
-					}
-				}
-			}
+	public MdiEntry createHeader(String id, String titleID, String preferredAfterID) {
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			return oldEntry;
 		}
 
-		PluginsMenuHelper.getInstance().addPluginAddedViewListener(
-				new PluginAddedViewListener() {
-					// @see org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.PluginAddedViewListener#pluginViewAdded(org.gudy.azureus2.ui.swt.mainwindow.PluginsMenuHelper.IViewInfo)
-					public void pluginViewAdded(IViewInfo viewInfo) {
-						//System.out.println("PluginView Added: " + viewInfo.viewID);
-						Object o = mapAutoOpen.get(viewInfo.viewID);
-						if (o instanceof Map) {
-							processAutoOpenMap(viewInfo.viewID, (Map) o, viewInfo);
-						}
-					}
-				});
-	}
-
-	/**
-		 * @param entry
-		 *
-		 * @since 4.1.0.3
-		 */
-	private void addDropTest(SideBarEntrySWT entry) {
-		if (!Constants.isCVSVersion()) {
-			return;
-		}
-		entry.addListener(new SideBarDropListener() {
-			public boolean sideBarEntryDrop(SideBarEntry entry, Object droppedObject) {
-				String s = "You just dropped " + droppedObject.getClass() + "\n"
-						+ droppedObject + "\n\n";
-				if (droppedObject.getClass().isArray()) {
-					Object[] o = (Object[]) droppedObject;
-					for (int i = 0; i < o.length; i++) {
-						s += "" + i + ":  ";
-						Object object = o[i];
-						if (object == null) {
-							s += "null";
-						} else {
-							s += object.getClass() + ";" + object;
-						}
-						s += "\n";
-					}
-				}
-				new MessageBoxShell(SWT.OK, "test", s).open(null);
-				return true;
-			}
-		});
+		SideBarEntrySWT entry = new SideBarEntrySWT(this, skin, id);
+		entry.setSelectable(false);
+		entry.setPreferredAfterID(preferredAfterID);
+		entry.setTitleID(titleID);
 
-	}
+		setupNewEntry(entry, id, true, false);
 
-	/**
-	 * 
-	 *
-	 * @return 
-	 * @since 3.1.1.1
-	 */
-	private SideBarEntrySWT createWelcomeSection() {
-		SideBarEntrySWT entry = createEntryFromSkinRef(null,
-				SIDEBAR_SECTION_WELCOME, "main.area.welcome", MessageText.getString(
-						"v3.MainWindow.menu.getting_started").replaceAll("&", ""), null,
-				null, true, 0);
-		entry.setImageLeftID("image.sidebar.welcome");
-		addDropTest(entry);
 		return entry;
 	}
 
-	public TreeItem createTreeItemFromIView(String parentID, IView iview,
-			String id, Object datasource, boolean closeable, boolean show) {
-
-		return (createTreeItemFromIView(parentID, iview, id, datasource, closeable,
-				show, true));
-	}
-
-	public TreeItem createTreeItemFromIView(String parentID, IView iview,
-			String id, Object datasource, boolean closeable, boolean show,
-			boolean expand) {
+	public MdiEntry createEntryFromView(String parentID, UISWTViewCore iview, String id,
+			Object datasource, boolean closeable, boolean show, boolean expand) {
 		if (id == null) {
 			id = iview.getClass().getName();
 			int i = id.lastIndexOf('.');
@@ -1760,1204 +1133,337 @@ public class SideBar
 				id = id.substring(i + 1);
 			}
 		}
-		TreeItem treeItem = null;
-
-		SideBarEntrySWT entry = getEntry(id);
 
-		if (entry.treeItem != null) {
-			treeItem = entry.treeItem;
-		} else {
-			SideBarEntrySWT sideBarInfoParent = getEntry(parentID);
-			TreeItem parentTreeItem = sideBarInfoParent.treeItem;
-			treeItem = createTreeItem(parentTreeItem, id, datasource, null,
-					iview.getFullTitle(), closeable, -1);
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			if (show) {
+				showEntry(oldEntry);
+			}
+			return oldEntry;
+		}
 
-			setupTreeItem(null, treeItem, id, null, iview.getFullTitle(), null,
-					datasource, closeable, expand);
+		SideBarEntrySWT entry = new SideBarEntrySWT(this, skin, id);
 
-			entry.parentID = parentID;
+		entry.setCoreView(iview);
+		entry.setDatasource(datasource);
+		entry.setParentID(parentID);
 
-			createSideBarContentArea(id, iview, treeItem, datasource, closeable,
-					expand);
+		setupNewEntry(entry, id, expand, closeable);
 
-			iview.dataSourceChanged(datasource);
+		if (iview instanceof IViewAlwaysInitialize) {
+			entry.build();
 		}
 
 		if (show) {
-			showTreeItem(treeItem);
+			showEntry(entry);
 		}
 
-		return treeItem;
+		return entry;
 	}
 
-	public void showTreeItem(TreeItem treeItem) {
-		if (treeItem != null) {
-			treeItem.getParent().select(treeItem);
-			treeItem.getParent().showItem(treeItem);
-			itemSelected(treeItem);
+	private void setupNewEntry(final SideBarEntrySWT entry, final String id,
+			final boolean expandParent, final boolean closeable) {
+		//System.out.println("createItem " + id + ";" + Debug.getCompressedStackTrace());
+		synchronized (mapIdToEntry) {
+			mapIdToEntry.put(id, entry);
 		}
-	}
 
-	public TreeItem createTreeItemFromIViewClass(String parent, String id,
-			String title, Class iviewClass, boolean closeable) {
+		entry.setCloseable(closeable);
+		entry.setParentSkinObject(soSideBarContents);
 
-		return createTreeItemFromIViewClass(parent, id, title, iviewClass, null,
-				null, null, null, closeable);
-	}
+		if (SIDEBAR_HEADER_PLUGINS.equals(entry.getParentID())
+				&& entry.getImageLeftID() == null) {
+			entry.setImageLeftID("image.sidebar.plugin");
+		}
 
-	public TreeItem createTreeItemFromIViewClass(String parent, String id,
-			String title, Class iviewClass, Class[] iviewClassArgs,
-			Object[] iviewClassVals, Object datasource, ViewTitleInfo titleInfo,
-			boolean closeable) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				_setupNewEntry(entry, id, expandParent, closeable);
+			}
+		});
+	}
 
-		SideBarEntrySWT entry = getEntry(id);
-		if (entry.treeItem != null) {
-			return entry.treeItem;
+	protected void _setupNewEntry(SideBarEntrySWT entry, String id,
+			boolean expandParent, boolean closeable) {
+		String parentID = entry.getParentID();
+		MdiEntry parent = getEntry(parentID);
+		TreeItem parentTreeItem = null;
+		if (parent instanceof SideBarEntrySWT) {
+			SideBarEntrySWT parentSWT = (SideBarEntrySWT) parent;
+			parentTreeItem = parentSWT.getTreeItem();
+			if (expandParent) {
+				parentTreeItem.setExpanded(true);
+			}
+		}
+		int index = -1;
+		String preferredAfterID = entry.getPreferredAfterID();
+		if (preferredAfterID != null) {
+			if (preferredAfterID.length() == 0) {
+				index = 0;
+			} else {
+				MdiEntry entryAbove = getEntry(preferredAfterID);
+				if (entryAbove != null) {
+					index = indexOf(entryAbove);
+					if (index >= 0) {
+						index++;
+					}
+					//System.out.println("ENTRY " + id + " is going to go below " + entryAbove.getId() + " at " + index);
+				}
+			}
 		}
 
-		TreeItem parentItem = parent == null ? null : getEntry(parent).treeItem;
-
-		TreeItem treeItem;
-		if (parentItem != null) {
-			treeItem = new TreeItem(parentItem, SWT.NONE);
-		} else {
-			treeItem = new TreeItem(tree, SWT.NONE);
+		if (index == -1 && parent == null) {
+			index = 0;
+			String[] order = getPreferredOrder();
+			for (int i = 0; i < order.length; i++) {
+				String orderID = order[i];
+				if (orderID.equals(id)) {
+					break;
+				}
+				MdiEntry entry2 = getEntry(orderID);
+				if (entry2 != null) {
+					int i2 = indexOf(entry2);
+					if (i2 >= 0) {
+						index = i2 + 1;
+					}
+				}
+			}
 		}
 
-		entry.iviewClass = iviewClass;
-		entry.iviewClassArgs = iviewClassArgs;
-		entry.iviewClassVals = iviewClassVals;
-		entry.closeable = closeable;
-		entry.parentID = parent;
-		setupTreeItem(null, treeItem, id, titleInfo, title, null, datasource,
-				closeable, false );
+		if (GAP_BETWEEN_LEVEL_1 && parentTreeItem == null
+				&& tree.getItemCount() > 0 && index != 0) {
+			createTreeItem(null, index);
+			if (index >= 0) {
+				index++;
+			}
+		}
+		TreeItem treeItem = createTreeItem(parentTreeItem, index);
+		if (treeItem != null) {
+			treeItem.setData("MdiEntry", entry);
+			entry.setTreeItem(treeItem);
 
-		return treeItem;
+			triggerEntryLoadedListeners(entry);
+		}
+		if (GAP_BETWEEN_LEVEL_1 && parentTreeItem == null
+				&& tree.getItemCount() > 1 && index == 0) {
+			createTreeItem(null, ++index);
+		}
 	}
 
-	private TreeItem createTreeItem(Object parentTreeItem, String id,
-			Object datasource, ViewTitleInfo titleInfo, String title,
-			boolean closeable, int index) {
+	private TreeItem createTreeItem(Object parentSwtItem, int index) {
 		TreeItem treeItem;
 
-		if (parentTreeItem == null) {
-			parentTreeItem = tree;
+		if (parentSwtItem == null) {
+			parentSwtItem = tree;
 		}
 
-		if (parentTreeItem instanceof Tree) {
-			Tree tree = (Tree) parentTreeItem;
+		if (parentSwtItem instanceof Tree) {
+			Tree tree = (Tree) parentSwtItem;
 			if (tree.isDisposed()) {
 				return null;
 			}
-			if (index >= 0) {
+			if (index >= 0 && index < tree.getItemCount()) {
 				treeItem = new TreeItem(tree, SWT.NONE, index);
 			} else {
 				treeItem = new TreeItem(tree, SWT.NONE);
 			}
 		} else {
-			if (((TreeItem) parentTreeItem).isDisposed()) {
+			if (((TreeItem) parentSwtItem).isDisposed()) {
 				return null;
 			}
-			if (index >= 0) {
-				treeItem = new TreeItem((TreeItem) parentTreeItem, SWT.NONE, index);
+			if (index >= 0 && index < ((TreeItem) parentSwtItem).getItemCount()) {
+				treeItem = new TreeItem((TreeItem) parentSwtItem, SWT.NONE, index);
 			} else {
-				treeItem = new TreeItem((TreeItem) parentTreeItem, SWT.NONE);
+				treeItem = new TreeItem((TreeItem) parentSwtItem, SWT.NONE);
 			}
 		}
 
 		return treeItem;
 	}
 
-	private void setupTreeItem(final IView iview, TreeItem treeItem, String id,
-			ViewTitleInfo titleInfo, String title, Composite initializeView,
-			Object datasource, boolean closeable, boolean expand) {
-		final SideBarEntrySWT entry = getEntry(id);
-
-		boolean pull = true;
-		if (treeItem.getParentItem() != null && expand) {
-			treeItem.getParentItem().setExpanded(true);
+	public void showEntry(MdiEntry newEntry) {
+		if (tree.isDisposed()) {
+			return;
 		}
-		if (!expand) {
-			treeItem.setExpanded(false);
+
+		if (newEntry == null || !newEntry.isSelectable()) {
+			return;
 		}
-		treeItem.removeDisposeListener(disposeTreeItemListener);
-		treeItem.addDisposeListener(disposeTreeItemListener);
-		treeItem.setData("Plugin.viewID", id);
 
-		if (iview != null) {
-			entry.iview = iview;
+		final SideBarEntrySWT oldEntry = (SideBarEntrySWT) currentEntry;
+
+		//System.out.println("showEntry " + newEntry.getId() + "; was " + (oldEntry == null ? "null" : oldEntry.getId()) + " via " + Debug.getCompressedStackTrace());
+		if (currentEntry == newEntry) {
+			triggerSelectionListener(newEntry, newEntry);
+			return;
 		}
 
-		if (title != null) {
-			treeItem.setData("text", title);
-		} else {
-			if (entry.iview != null) {
-				treeItem.setData("text", entry.iview.getFullTitle());
-			}
+		// show new
+		currentEntry = (MdiEntrySWT) newEntry;
+
+		if (oldEntry != null && oldEntry != newEntry) {
+			oldEntry.redraw();
 		}
 
-		if (titleInfo == null) {
-			if (entry.iview instanceof ViewTitleInfo) {
-				titleInfo = (ViewTitleInfo) entry.iview;
-			} else if (entry.iview instanceof UISWTViewImpl) {
-				UISWTViewEventListener eventListener = ((UISWTViewImpl) entry.iview).getEventListener();
-				if (eventListener instanceof ViewTitleInfo) {
-					titleInfo = (ViewTitleInfo) eventListener;
-				}
-			}
+		if (currentEntry != null) {
+			((BaseMdiEntry) currentEntry).show();
+		}
 
+		// hide old
+		if (oldEntry != null && oldEntry != newEntry) {
+			oldEntry.hide();
+			oldEntry.redraw();
 		}
 
-		if (titleInfo != null) {
-			entry.titleInfo = titleInfo;
+		newEntry.redraw();
+
+		triggerSelectionListener(newEntry, oldEntry);
+	}
+
+	/**
+	 *  @see com.aelitis.azureus.ui.swt.mdi.BaseMDI#createEntryFromEventListener(java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener, java.lang.String, boolean, java.lang.Object)
+	 */
+	public MdiEntry createEntryFromEventListener(String parentID,
+			UISWTViewEventListener l, String id, boolean closeable, Object datasource) {
+
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			return oldEntry;
 		}
 
-		if (entry.titleInfo != null) {
-			mapTitleInfoToEntry.put(entry.titleInfo, entry);
-			String newText = (String) entry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
-			if (newText != null) {
-				pull = false;
-				treeItem.setData("text", newText);
+		SideBarEntrySWT entry = new SideBarEntrySWT(this, skin, id);
+		try {
+			// hack: setEventListner will create the UISWTView.
+			// We need to have the entry available for the view to use
+			// if it wants
+			synchronized (mapIdToEntry) {
+				mapIdToEntry.put(id, entry);
 			}
 
-			String imageID = (String) entry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_IMAGEID);
-			if (imageID != null) {
-				entry.setImageLeftID(imageID.length() == 0 ? null : imageID);
-			}
-			listTreeItemsNoTitleInfo.remove(treeItem);
-		} else {
-			if (!listTreeItemsNoTitleInfo.contains(treeItem)) {
-				listTreeItemsNoTitleInfo.add(treeItem);
+			entry.setParentID(parentID);
+			entry.setDatasource(datasource);
+
+			setupNewEntry(entry, id, false, closeable);
+
+			entry.setEventListener(l);
+
+			if (l instanceof IViewAlwaysInitialize) {
+				entry.build();
 			}
+		} catch (Exception e) {
+			Debug.out(e);
+			entry.close(true);
 		}
 
-		if (treeItem != null) {
-			entry.treeItem = treeItem;
-		}
-		if (datasource != null) {
-			entry.datasource = datasource;
+		return entry;
+	}
+
+	// @see com.aelitis.azureus.ui.swt.mdi.BaseMDI#createEntryFromSkinRef(java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo, java.lang.Object, boolean, java.lang.String)
+	public MdiEntry createEntryFromSkinRef(String parentID, String id,
+			String configID, String title, ViewTitleInfo titleInfo, Object params,
+			boolean closeable, String preferredAfterID) {
+
+		MdiEntry oldEntry = getEntry(id);
+		if (oldEntry != null) {
+			return oldEntry;
 		}
 
-		entry.closeable = closeable;
+		SideBarEntrySWT entry = new SideBarEntrySWT(this, skin, id);
 
-		entry.pullTitleFromIView = pull;
+		entry.setTitle(title);
+		entry.setSkinRef(configID, params);
+		entry.setParentID(parentID);
+		entry.setViewTitleInfo(titleInfo);
+		entry.setPreferredAfterID(preferredAfterID);
 
-		if (closeable) {
-			Map autoOpenInfo = new LightHashMap();
-			if (entry.parentID != null) {
-				autoOpenInfo.put("parentID", entry.parentID);
-			}
-			if (entry.iviewClass != null) {
-				autoOpenInfo.put("iviewClass", entry.iviewClass.getName());
-			}
-			if (entry.eventListener != null) {
-				autoOpenInfo.put("eventlistenerid", id);
-			}
-			if (entry.iview != null) {
-				autoOpenInfo.put("title", entry.iview.getFullTitle());
-			}
-			if (entry.datasource instanceof DownloadManager) {
-				try {
-					autoOpenInfo.put(
-							"dm",
-							((DownloadManager) entry.datasource).getTorrent().getHashWrapper().toBase32String());
-				} catch (Throwable t) {
-				}
-			}
+		setupNewEntry(entry, id, false, closeable);
 
-			mapAutoOpen.put(id, autoOpenInfo);
-		}
-
-		if (initializeView != null) {
-			iview.initialize(initializeView);
-			initializeView.setVisible(false);
-			Composite composite = iview.getComposite();
-			if (composite != null && !composite.isDisposed()) {
-				composite.setVisible(false);
-				composite.addDisposeListener(new DisposeListener() {
-					public void widgetDisposed(DisposeEvent e) {
-						if (entry.treeItem != null && !entry.treeItem.isDisposed()) {
-							try {
-								entry.treeItem.dispose();
-							} catch (NullPointerException npe) {
-								// ignore swt bug
-							}
-						}
-					}
-				});
-			}
-			if (entry.datasource != null) {
-				iview.dataSourceChanged(entry.datasource);
-			}
-			initializeView.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					if (entry.iview != null) {
-						try {
-							entry.iview.delete();
-						} catch (Throwable t) {
-							Debug.out(t);
-						}
-						entry.iview = null;
-					}
-				}
-			});
-		}
-	}
-
-	public static SideBarEntrySWT getEntry(String id) {
-		if ("Browse".equalsIgnoreCase(id)) {
-			id = SIDEBAR_SECTION_BROWSE;
-		}
-		SideBarEntrySWT entry = (SideBarEntrySWT) mapIdToEntries.get(id);
-		if (entry == null) {
-			entry = new SideBarEntrySWT(instance, id);
-			mapIdToEntries.put(id, entry);
-		}
-		return entry;
-	}
-
-	public static boolean entryExists(String id) {
-		if ("Browse".equalsIgnoreCase(id)) {
-			id = SIDEBAR_SECTION_BROWSE;
-		}
-		SideBarEntrySWT entry = (SideBarEntrySWT) mapIdToEntries.get(id);
-		if (entry == null) {
-			return false;
-		}
-		return entry.treeItem != null;
-	}
-
-	/**
-	 * @param treeItem
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void itemSelected(final TreeItem treeItem) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				_itemSelected(treeItem);
-			}
-		});
-	}
-
-	private void disabledViewModes() {
-		ToolBarView tb = (ToolBarView) SkinViewManager.getByClass(ToolBarView.class);
-		if (tb != null) {
-			ToolBarItem itemModeSmall = tb.getToolBarItem("modeSmall");
-			if (itemModeSmall != null) {
-				itemModeSmall.getSkinButton().getSkinObject().switchSuffix("");
-				itemModeSmall.setEnabled(false);
-			}
-			ToolBarItem itemModeBig = tb.getToolBarItem("modeBig");
-			if (itemModeBig != null) {
-				itemModeBig.getSkinButton().getSkinObject().switchSuffix("");
-				itemModeBig.setEnabled(false);
-			}
-		}
-	}
-
-	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);
-			tree.select(treeItem);
-		}
-
-		final String id = (String) treeItem.getData("Plugin.viewID");
-		final SideBarEntrySWT newEntry = getEntry(id);
-
-		if (currentSideBarEntry == newEntry) {
-			triggerSelectionListener(newEntry, newEntry);
-			return;
-		}
-
-		// We'll have an iview if we've previously created one
-		IView newIView = newEntry.iview;
-
-		// Otherwise, we have two ways of creating an IView.. via IViewClass,
-		// or UISWTViewEventListener
-
-		if (newIView == null) {
-			if (newEntry.iviewClass != null) {
-				newIView = createSideBarContentArea(id, newEntry);
-
-				if (newIView == null) {
-					return;
-				}
-
-				setupTreeItem(newIView, treeItem,
-						(String) treeItem.getData("Plugin.viewID"), null,
-						newIView.getFullTitle(), null, null, newEntry.closeable, true);
-			}
-		}
-
-		if (newIView == null && newEntry.eventListener != null) {
-			newIView = createTreeItemFromEventListener(null, treeItem,
-					newEntry.eventListener, id, newEntry.closeable, null);
-		}
-
-		if (newIView != null) {
-
-			if (newIView instanceof ToolBarEnabler) {
-
-				ISelectedContent[] sels = new ISelectedContent[1];
-				sels[0] = new ToolBarEnablerSelectedContent((ToolBarEnabler) newIView);
-				TableView tv = null;
-				if (newIView instanceof TableView) {
-					tv = (TableView) newIView;
-				}
-				SelectedContentManager.changeCurrentlySelectedContent("IconBarEnabler",
-						sels, tv);
-
-			} else {
-
-				SelectedContentManager.clearCurrentlySelectedContent();
-
-			}
-
-			disabledViewModes();
-
-			Utils.execSWTThreadLater(0, new AERunnable() {
-
-				public void runSupport() {
-					flipVisibilityTo(newEntry);
-				}
-			});
-
-		}
-	}
-
-	protected void flipVisibilityTo(SideBarEntrySWT newSideBarInfo) {
-		if (tree.isDisposed()) {
-			return;
-		}
-
-		final SideBarEntrySWT oldEntry = currentSideBarEntry;
-
-		// show new
-		currentSideBarEntry = newSideBarInfo;
-
-		SWTSkinObjectContainer container;
-
-		if (currentSideBarEntry.iview instanceof UISWTViewImpl) {
-			Object ds = ((UISWTViewImpl) currentSideBarEntry.iview).getDataSource();
-			DownloadManager dm = null;
-			if (ds instanceof DownloadManager) {
-				dm = (DownloadManager) ds;
-			} else if (ds instanceof Download) {
-				dm = PluginCoreUtils.unwrap((Download) ds);
-			}
-			if (dm != null) {
-				try {
-					TableView tv = null;
-					if (currentSideBarEntry.iview instanceof TableView) {
-						tv = (TableView) currentSideBarEntry.iview;
-					}
-					SelectedContentManager.changeCurrentlySelectedContent(
-							currentSideBarEntry.id, new ISelectedContent[] {
-								new SelectedContentV3(dm)
-							}, tv);
-				} catch (Exception e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				}
-			}
-		}
-
-		container = (SWTSkinObjectContainer) newSideBarInfo.skinObject;
-		if (container != null) {
-			//container.setVisible(true);
-			Composite composite = container.getComposite();
-			if (composite != null && !composite.isDisposed()) {
-				composite.setVisible(true);
-				composite.moveAbove(null);
-				//composite.setFocus();
-			}
-		}
-		Composite c = currentSideBarEntry.iview.getComposite();
-		if (c != null && !c.isDisposed()) {
-			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()) {
-				lastImage.dispose();
-				lastImage = null;
-			}
-			if (oldEntry.skinObject != null) {
-				container = (SWTSkinObjectContainer) oldEntry.skinObject;
-				if (container != null) {
-					Control oldComposite = container.getControl();
-					doFade(oldComposite);
-
-					container.setVisible(false);
-					if (!oldComposite.isDisposed()) {
-						oldComposite.getShell().update();
-					}
-				}
-			}
-			if (oldEntry.iview != null) {
-				Composite oldComposite = oldEntry.iview.getComposite();
-				if (oldComposite != null && !oldComposite.isDisposed()) {
-					doFade(oldComposite);
-
-					oldComposite.setVisible(false);
-					oldComposite.getShell().update();
-				}
-				
-				if (oldEntry.iview instanceof IViewExtension) {
-					try {
-						((IViewExtension)oldEntry.iview).viewDeactivated();
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				}
-			}
-		}
-
-		triggerSelectionListener(newSideBarInfo, oldEntry);
-	}
-
-	/**
-	 * @param oldComposite
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void doFade(final Control oldComposite) {
-		if (true) {
-			return;
-		}
-		if (oldComposite.isDisposed()
-				|| (shellFade != null && !shellFade.isDisposed())) {
-			return;
-		}
-		final Shell parentShell = oldComposite.getShell();
-		if (parentShell != oldComposite.getDisplay().getActiveShell()) {
-			return;
-		}
-
-		if (lastImage == null || lastImage.isDisposed()) {
-			Rectangle bounds = oldComposite.getBounds();
-			if (bounds.isEmpty()) {
-				return;
-			}
-			lastImage = new Image(oldComposite.getDisplay(), bounds.width,
-					bounds.height);
-			GC gc = new GC(oldComposite);
-			gc.copyArea(lastImage, 0, 0);
-			gc.dispose();
-
-			int style = SWT.NO_TRIM;
-			if (Constants.isOSX) {
-				style |= SWT.ON_TOP;
-			}
-			shellFade = new Shell(soSideBarContents.getControl().getShell(), style);
-			Point pos = soSideBarContents.getControl().toDisplay(0, 0);
-			shellFade.setBackgroundImage(lastImage);
-			shellFade.setLocation(pos);
-			shellFade.setSize(soSideBarContents.getControl().getSize());
-			shellFade.setAlpha(255);
-			shellFade.setVisible(true);
-			shellFade.addListener(SWT.Dispose, new Listener() {
-				public void handleEvent(Event event) {
-					if (lastImage != null && !lastImage.isDisposed()) {
-						lastImage.dispose();
-					}
-				}
-			});
-			Utils.execSWTThreadLater(15, new AERunnable() {
-				long lastTime;
-
-				public void runSupport() {
-					if (shellFade.isDisposed()) {
-						return;
-					}
-					if (lastImage == null || lastImage.isDisposed()
-							|| parentShell != parentShell.getDisplay().getActiveShell()) {
-						shellFade.dispose();
-						return;
-					}
-
-					int alpha = shellFade.getAlpha();
-					alpha -= 50;
-					long now = SystemTime.getCurrentTime();
-
-					if (alpha < 0 || lastImage == null || lastImage.isDisposed()) {
-						shellFade.dispose();
-						return;
-					}
-					shellFade.setAlpha(alpha);
-					//System.out.println(alpha);
-
-					if (lastTime > 0 && now - lastTime > 50) {
-						Utils.execSWTThreadLater(0, this);
-					} else {
-						Utils.execSWTThreadLater(15, this);
-					}
-					lastTime = now;
-				};
-			});
-		}
-	}
-
-	/**
-	 * @param parentID 
-	 * @param l
-	 * @param datasource 
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public IView createTreeItemFromEventListener(String parentID,
-			TreeItem treeItem, UISWTViewEventListener l, String id,
-			boolean closeable, Object datasource) {
-
-		final String originialID = id;
-		SideBarEntrySWT entry = getEntry(id);
-
-		if (entry.treeItem != null && entry.iview != null) {
-			if (entry.eventListener == l) {
-				System.err.println("Already created view " + id);
-			}
-			id = id + "_" + SystemTime.getCurrentTime();
-			entry = getEntry(id);
-		}
-
-		String name = entry.treeItem == null ? id
-				: (String) entry.treeItem.getData("text");
-
-		if (treeItem == null) {
-			TreeItem parentTreeItem = parentID == null ? null
-					: getEntry(parentID).treeItem;
-
-			IViewInfo foundViewInfo = null;
-			IViewInfo[] pluginViewsInfo = PluginsMenuHelper.getInstance().getPluginViewsInfo();
-			for (int i = 0; i < pluginViewsInfo.length; i++) {
-				IViewInfo viewInfo = pluginViewsInfo[i];
-				if (viewInfo.event_listener == l) {
-					foundViewInfo = viewInfo;
-					break;
-				}
-			}
-			if (foundViewInfo == null) {
-				pluginViewsInfo = PluginsMenuHelper.getInstance().getPluginLogViewsInfo();
-				for (int i = 0; i < pluginViewsInfo.length; i++) {
-					IViewInfo viewInfo = pluginViewsInfo[i];
-					if (viewInfo.event_listener == l) {
-						foundViewInfo = viewInfo;
-						break;
-					}
-				}
-			}
-			if (foundViewInfo != null) {
-				IViewInfo[] pluginLogViewsInfo = PluginsMenuHelper.getInstance().getPluginLogViewsInfo();
-				for (int i = 0; i < pluginLogViewsInfo.length; i++) {
-					IViewInfo viewInfo = pluginLogViewsInfo[i];
-					if (viewInfo.event_listener == l) {
-						foundViewInfo = viewInfo;
-						break;
-					}
-				}
-			}
-
-			name = foundViewInfo == null ? id : foundViewInfo.name;
-
-			entry.eventListener = l;
-			entry.parentID = parentID;
-			treeItem = createTreeItem(parentTreeItem, id, datasource, null, name,
-					closeable, -1);
-		}
-
-		IView iview = null;
-		try {
-			iview = new UISWTViewImpl(parentID, id, l, datasource);
-			((UISWTViewImpl) iview).setTitle(name);
-			iview.dataSourceChanged(datasource);
-
-			if (l instanceof UISWTViewEventListenerSkinObject) {
-				((UISWTViewImpl) iview).setUseCoreDataSource(true);
-			}
-
-			Composite parent = (Composite) soSideBarContents.getControl();
-			parent.setBackgroundMode(SWT.INHERIT_NONE);
-
-			Composite viewComposite = new Composite(parent, SWT.NONE);
-			viewComposite.setBackgroundMode(SWT.INHERIT_NONE);
-			viewComposite.setLayoutData(Utils.getFilledFormData());
-			viewComposite.setBackground(parent.getDisplay().getSystemColor(
-					SWT.COLOR_WIDGET_BACKGROUND));
-			viewComposite.setForeground(parent.getDisplay().getSystemColor(
-					SWT.COLOR_WIDGET_FOREGROUND));
-			if (l instanceof UISWTViewEventListenerSkinObject) {
-				viewComposite.setLayout(new FormLayout());
-			} else {
-				GridLayout gridLayout = new GridLayout();
-				gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
-				viewComposite.setLayout(gridLayout);
-			}
-
-			viewComposite.setVisible(false);
-
-			SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
-					skin.getSkinProperties(), viewComposite, "Contents." + id + "."
-							+ (mapIdToEntries.size() + 1), "", "container", soSideBarContents);
-
-			entry.skinObject = soContents;
-			entry.eventListener = l;
-			entry.parentID = parentID;
-
-			setupTreeItem(iview, treeItem, id, null, iview.getFullTitle(),
-					viewComposite, datasource, closeable, true);
-
-			if (parent.isVisible()) {
-				parent.layout(true, true);
-			}
-
-			if (closeable) {
-				COConfigurationManager.setParameter("SideBar.AutoOpen." + id, true);
-			} else {
-				COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
-			}
-
-		} catch (UISWTViewEventCancelledException e) {
-			if (treeItem != null && !treeItem.isDisposed()) {
-				treeItem.dispose();
-			}
-			showEntryByID(originialID);
-		} catch (Exception e) {
-			e.printStackTrace();
-			try {
-				final String id2 = id;
-				l = new UISWTViewEventListener() {
-					public boolean eventOccurred(UISWTViewEvent event) {
-						if (event.getType() == UISWTViewEvent.TYPE_INITIALIZE) {
-							Composite c = (Composite) event.getData();
-							Label label = new Label(c, SWT.CENTER);
-							label.setText("Plugin " + id2 + " did not want to initialize");
-						}
-						return true;
-					}
-				};
-				iview = new UISWTViewImpl("SideBar.Plugins", id, l, datasource);
-				String text = (String) treeItem.getData("text");
-				if (text != null) {
-					((UISWTViewImpl) iview).setTitle(text);
-				}
-
-				Composite parent = (Composite) soSideBarContents.getControl();
-				Composite viewComposite = new Composite(parent, SWT.NONE);
-				viewComposite.setLayoutData(Utils.getFilledFormData());
-				viewComposite.setLayout(new FormLayout());
-				viewComposite.setBackground(parent.getDisplay().getSystemColor(
-						SWT.COLOR_WIDGET_BACKGROUND));
-				viewComposite.setForeground(parent.getDisplay().getSystemColor(
-						SWT.COLOR_WIDGET_FOREGROUND));
-				SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
-						skin.getSkinProperties(), viewComposite, "Contents"
-								+ (mapIdToEntries.size() + 1), "", "container",
-						soSideBarContents);
-
-				entry.skinObject = soContents;
-				entry.eventListener = l;
-
-				setupTreeItem(iview, treeItem, id, null, iview.getFullTitle(),
-						viewComposite, datasource, closeable, true);
-
-				parent.layout(true, true);
-			} catch (Exception e1) {
-				Debug.out(e1);
-			}
-
-			if (!(e instanceof UISWTViewEventCancelledException)) {
-				Debug.out(e);
-			}
-		}
-		return iview;
-	}
-
-	/**
-	 * Creates an IView based on class.  Doesn't add it to the tree
-	 * @param id 
-	 * 
-	 * @param iview
-	 * @param iviewClass
-	 * @param args
-	 *
-	 * @since 3.1.0.1
-	 */
-	private IView createSideBarContentArea(String id, SideBarEntrySWT sideBarInfo) {
-		if (id == null) {
-			return null;
-		}
-		IView iview = null;
-		try {
-			if (sideBarInfo.iviewClassArgs == null) {
-				iview = (IView) sideBarInfo.iviewClass.newInstance();
-			} else {
-				Constructor constructor = sideBarInfo.iviewClass.getConstructor(sideBarInfo.iviewClassArgs);
-				iview = (IView) constructor.newInstance(sideBarInfo.iviewClassVals);
-			}
-
-			createSideBarContentArea(id, iview, sideBarInfo.treeItem,
-					sideBarInfo.datasource, sideBarInfo.closeable, true);
-		} catch (Exception e) {
-			e.printStackTrace();
-			if (iview != null) {
-				iview.delete();
-			}
-			iview = null;
-		}
-
-		return iview;
-	}
-
-	/**
-	 * Take an already created IView and put it into a new Container Skin Object.
-	 * Doesn't add it to the tree
-	 * @param id 
-	 *  
-	 * @param view
-	 * @param closeable 
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	private IView createSideBarContentArea(String id, IView view, TreeItem item,
-			Object datasource, boolean closeable, boolean expand) {
-		try {
-			Composite parent = (Composite) soSideBarContents.getControl();
-
-			SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
-					skin.getSkinProperties(), "Contents" + (mapIdToEntries.size() + 1),
-					"", soSideBarContents);
-
-			Composite viewComposite = soContents.getComposite();
-			viewComposite.setBackground(parent.getDisplay().getSystemColor(
-					SWT.COLOR_WIDGET_BACKGROUND));
-			viewComposite.setForeground(parent.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);
-
-			SideBarEntrySWT entry = getEntry((String) item.getData("Plugin.viewID"));
-			entry.skinObject = soContents;
-
-			setupTreeItem(view, item, id, null, null, viewComposite, datasource,
-					closeable, expand);
-
-			Composite iviewComposite = view.getComposite();
-			Object existingLayout = iviewComposite.getLayoutData();
-			if (existingLayout == null || (existingLayout instanceof GridData)) {
-				GridData gridData = new GridData(GridData.FILL_BOTH);
-				iviewComposite.setLayoutData(gridData);
-			}
-
-			if (iviewComposite.isVisible()) {
-			parent.layout(true, true);
-			}
-
-		} catch (Exception e) {
-			Debug.out("Error creating sidebar content area for " + id, e);
-			if (view != null) {
-				view.delete();
-			}
-			view = null;
-			item.dispose();
-		}
-		return view;
-	}
-
-	public SideBarEntrySWT createEntryFromSkinRef(String parentID,
-			final String id, final String configID, String title,
-			ViewTitleInfo titleInfo, final Object params, boolean closeable, int index) {
-
-		// temp until we start passing ds
-		Object datasource = null;
-
-		SideBarEntrySWT entry = getEntry(id);
-		if (entry.treeItem != null) {
-			return entry;
-		}
-
-		TreeItem treeItem = null;
-
-		UISWTViewEventListener l = new UISWTViewEventListenerSkinObject() {
-			public boolean eventOccurred(UISWTViewEvent event) {
-				switch (event.getType()) {
-					case UISWTViewEvent.TYPE_INITIALIZE: {
-						Composite parent = (Composite) event.getData();
-						SWTSkinObject soParent = (SWTSkinObject) parent.getData("SkinObject");
-						Shell shell = parent.getShell();
-						Cursor cursor = shell.getCursor();
-						try {
-							shell.setCursor(shell.getDisplay().getSystemCursor(
-									SWT.CURSOR_WAIT));
-
-							skinObject = skin.createSkinObject(id, configID, soParent, params);
-							skinObject.getControl().setLayoutData(Utils.getFilledFormData());
-							skinObject.getControl().getParent().layout(true);
-						} finally {
-							shell.setCursor(cursor);
-						}
-					}
-						break;
-					case UISWTViewEvent.TYPE_REFRESH: {
-
-						break;
-					}
-
-					case UISWTViewEvent.TYPE_DESTROY: {
-						break;
-					}
-				}
-				return true;
-			}
-		};
-		entry.eventListener = l;
-
-		TreeItem parentTreeItem = parentID == null ? null
-				: getEntry(parentID).treeItem;
-
-		entry.parentID = parentID;
-
-		treeItem = createTreeItem(parentTreeItem == null ? (Object) tree
-				: (Object) parentTreeItem, id, datasource, titleInfo, title, closeable,
-				index);
-
-		setupTreeItem(null, treeItem, id, titleInfo, title, null, datasource,
-				closeable, true);
-
-		return entry;
-	}
-
-	// @see com.aelitis.azureus.ui.swt.utils.UIUpdatable#getUpdateUIName()
-	public String getUpdateUIName() {
-		if (currentSideBarEntry == null || currentSideBarEntry.iview == null) {
-			return "Sidebar";
-		}
-		if (currentSideBarEntry.iview instanceof UIPluginView) {
-			UIPluginView uiPluginView = (UIPluginView) currentSideBarEntry.iview;
-			return uiPluginView.getViewID();
-		}
-
-		return currentSideBarEntry.iview.getFullTitle();
-	}
+		return entry;
+	}
 
 	// @see com.aelitis.azureus.ui.swt.utils.UIUpdatable#updateUI()
 	public void updateUI() {
-		if (currentSideBarEntry == null || currentSideBarEntry.iview == null
+		if (currentEntry == null || currentEntry.getView() == null
 				|| tree.getSelectionCount() == 0) {
 			return;
 		}
-		currentSideBarEntry.iview.refresh();
-
-		SideBarEntrySWT entry = getEntry(currentSideBarEntry.id);
-		if (entry.pullTitleFromIView && entry.treeItem != null
-				&& !entry.treeItem.isDisposed()) {
-			entry.treeItem.setData("text", currentSideBarEntry.iview.getFullTitle());
-		}
+		currentEntry.updateUI();
 	}
 
-	public static abstract class UISWTViewEventListenerSkinObject
-		implements UISWTViewEventListener
-	{
-		protected SWTSkinObject skinObject;
-
-		public SWTSkinObject getSkinObject() {
-			return skinObject;
-		}
-
-	}
-
-	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoListener#viewTitleInfoRefresh(com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo)
-	public void viewTitleInfoRefresh(final ViewTitleInfo titleIndicator) {
-		if (titleIndicator == null) {
-			return;
-		}
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (tree == null || tree.isDisposed()) {
-					return;
-				}
-
-				SideBarEntrySWT sideBarEntry = (SideBarEntrySWT) mapTitleInfoToEntry.get(titleIndicator);
-				if (sideBarEntry == null) {
-					Object o = titleIndicator.getTitleInfoProperty(ViewTitleInfo.TITLE_SKINVIEW);
-					if (o instanceof SkinView) {
-						SkinView skinView = (SkinView) o;
-						String id = skinView.getMainSkinObject().getSkinObjectID();
-						if (id != null) {
-							for (Iterator iter = listTreeItemsNoTitleInfo.iterator(); iter.hasNext();) {
-								TreeItem searchTreeItem = (TreeItem) iter.next();
-								if (searchTreeItem.isDisposed()) {
-									iter.remove();
-									continue;
-								}
-								String treeItemID = (String) searchTreeItem.getData("Plugin.viewID");
-								if (treeItemID != null && treeItemID.equals(id)) {
-									sideBarEntry = getEntry(treeItemID);
-									if (sideBarEntry.treeItem != null) {
-										sideBarEntry.titleInfo = titleIndicator;
-										mapTitleInfoToEntry.put(titleIndicator, sideBarEntry);
-									}
-									break;
-								}
-							}
-						}
-					}
-
-					if (sideBarEntry == null || sideBarEntry.treeItem == null) {
-						return;
-					}
-				}
-
-				if (sideBarEntry.treeItem == null || sideBarEntry.treeItem.isDisposed()) {
-					return;
-				}
-
-				String newText = (String) titleIndicator.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
-				if (newText != null) {
-					sideBarEntry.pullTitleFromIView = false;
-					sideBarEntry.treeItem.setData("text", newText);
-				}
-
-				String imageID = (String) titleIndicator.getTitleInfoProperty(ViewTitleInfo.TITLE_IMAGEID);
-				if (imageID != null) {
-					sideBarEntry.setImageLeftID(imageID.length() == 0 ? null : imageID);
-				}
-
-				sideBarEntry.redraw();
-
-				String logID = (String) titleIndicator.getTitleInfoProperty(ViewTitleInfo.TITLE_LOGID);
-				if (logID != null) {
-					sideBarEntry.setLogID(logID);
-				}
-			}
-		});
-	}
-
-	public SideBarEntrySWT getCurrentEntry() {
-		return currentSideBarEntry;
-	}
-
-	public void addListener(SideBarListener l) {
-		if (listeners.contains(l)) {
-			return;
-		}
-		listeners.add(l);
-	}
-
-	public void removeListener(SideBarListener l) {
-		listeners.remove(l);
+	public boolean showEntryByID(String id) {
+		return loadEntryByID(id, true);
 	}
 
-	private void triggerSelectionListener(SideBarEntrySWT newSideBarEntry,
-			SideBarEntrySWT oldSideBarEntry) {
-		for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-			SideBarListener l = (SideBarListener) iter.next();
-			l.sidebarItemSelected(newSideBarEntry, oldSideBarEntry);
-		}
+	public boolean loadEntryByID(String id, boolean activate) {
+		return loadEntryByID(id, activate, false, null);
 	}
 
-	public IView getIViewFromID(String id) {
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#loadEntryByID(java.lang.String, boolean, boolean)
+	 */
+	public boolean loadEntryByID(String id, boolean activate,
+			boolean onlyLoadOnce, Object datasource) {
 		if (id == null) {
-			return null;
+			return false;
 		}
-		return getEntry(id).iview;
-	}
-
-	public void saveCloseables() {
-		// update title
-		for (Iterator iter = mapAutoOpen.keySet().iterator(); iter.hasNext();) {
-			String id = (String) iter.next();
-			Object o = mapAutoOpen.get(id);
-
-			if (o instanceof Map) {
-
-				SideBarEntrySWT entry = getEntry(id);
-				Map autoOpenInfo = (Map) o;
-
-				if (entry.treeItem != null && !entry.treeItem.isDisposed()) {
-					String s = (String) entry.treeItem.getData("text");
-					if (s != null) {
-						autoOpenInfo.put("title", s);
-					}
-				}
-
+		MdiEntry entry = getEntry(id);
+		if (entry != null) {
+			if (datasource != null) {
+				entry.setDatasource(datasource);
 			}
-		}
-
-		FileUtil.writeResilientConfigFile("sidebarauto.config", mapAutoOpen);
-	}
-
-	public void loadCloseables() {
-		mapAutoOpen = FileUtil.readResilientConfigFile("sidebarauto.config", true);
-		if (mapAutoOpen.isEmpty()) {
-			return;
-		}
-		BDecoder.decodeStrings(mapAutoOpen);
-		for (Iterator iter = mapAutoOpen.keySet().iterator(); iter.hasNext();) {
-			String id = (String) iter.next();
-			Object o = mapAutoOpen.get(id);
-
-			if (o instanceof Map) {
-				if (!processAutoOpenMap(id, (Map) o, null)) {
-					iter.remove();
-				}
+			if (activate) {
+				showEntry(entry);
 			}
+			return true;
 		}
-	}
-
-	/**
-	 * @param viewInfo 
-	 * @param o
-	 *
-	 * @since 3.1.1.1
-	 */
-	private boolean processAutoOpenMap(String id, Map autoOpenInfo,
-			IViewInfo viewInfo) {
-		try {
-			SideBarEntrySWT entry = getEntry(id);
-			if (entry.treeItem != null) {
-				return true;
-			}
-
-			if (id.equals(SIDEBAR_SECTION_WELCOME)) {
-				createWelcomeSection();
-			}
-
-			String title = MapUtils.getMapString(autoOpenInfo, "title", id);
-			String parentID = (String) autoOpenInfo.get("parentID");
 
-			if (viewInfo != null) {
-				if (viewInfo.view != null) {
-					createTreeItemFromIView(parentID, viewInfo.view, id, null, true,
-							false);
-				} else if (viewInfo.event_listener != null) {
-					createTreeItemFromEventListener(parentID, null,
-							viewInfo.event_listener, id, true, null);
-				}
-				if (entry.iview == null) {
-					createSideBarContentArea(id, entry);
-				}
-			}
-
-			Class cla = Class.forName(MapUtils.getMapString(autoOpenInfo,
-					"iviewClass", ""));
-			if (cla != null) {
-				String dmHash = MapUtils.getMapString(autoOpenInfo, "dm", null);
-				Object ds = null;
-				if (dmHash != null) {
-					HashWrapper hw = new HashWrapper(Base32.decode(dmHash));
-					GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
-					ds = gm.getDownloadManager(hw);
-					// XXX Skip auto open DM for now
-					return false;
-				}
-				createTreeItemFromIViewClass(parentID, id, title, cla, null, null, ds,
-						null, true);
-
-				if (entry.iview == null) {
-					IView view = createSideBarContentArea(id, entry);
-					if (view == null) {
-						return false;
-					}
-				}
-			}
-		} catch (ClassNotFoundException ce) {
-			// ignore
-		} catch (Throwable e) {
-			Debug.out(e);
+		@SuppressWarnings("deprecation")
+		boolean loadedOnce = COConfigurationManager.getBooleanParameter("sb.once."
+				+ id, false);
+		if (loadedOnce && onlyLoadOnce) {
+			return false;
 		}
-		return true;
-	}
 
-	/**
-	 * 
-	 * TODO {@link #showEntryByID(String)} and {@link #showEntryByID(String)}
-	 *      absolutely need to be combined since they do the same thing
-	 *      but have different logic..
-	 */
-	public boolean showEntryByID(String id) {
-		SideBarEntrySWT entry = getEntry(id);
-		if (entry.treeItem != null) {
-			itemSelected(entry.treeItem);
-			return true;
-		}
 		if (id.equals(SIDEBAR_SECTION_WELCOME)) {
-			SideBarEntrySWT entryWelcome = createWelcomeSection();
-			itemSelected(entryWelcome.treeItem);
+			SideBarEntrySWT entryWelcome = (SideBarEntrySWT) createWelcomeSection();
+			if (activate) {
+				showEntry(entryWelcome);
+			}
 			return true;
 		} else if (id.startsWith("ContentNetwork.")) {
 			long networkID = Long.parseLong(id.substring(15));
 			handleContentNetworkSwitch(id, networkID);
 			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * @param tabID
-	 *
-	 * @since 3.1.0.1
-	 * 
-	 * TODO {@link #showEntryByID(String)} and {@link #showEntryByID(String)}
-	 *      absolutely need to be combined since they do the same thing
-	 *      but have different logic..
-	 */
-	public String showEntryByTabID(String tabID) {
-		if (tabID == null) {
-			return null;
-		}
-
-		String id;
-		SideBarEntrySWT entry = getEntry(tabID);
-		if (entry.isInTree()) {
-			id = tabID;
-		} else if (tabID.equals("library") || tabID.equals("minilibrary")) {
+		} else if (id.equals("library") || id.equals("minilibrary")) {
 			id = SIDEBAR_SECTION_LIBRARY;
-		} else if (tabID.equals("activities")) {
+			loadEntryByID(id, activate);
+			return true;
+		} else if (id.equals("activities")) {
 			id = SIDEBAR_SECTION_ACTIVITIES;
-		} else if (tabID.startsWith("ContentNetwork.")) {
-			id = tabID;
-		} else if (tabID.equals(SIDEBAR_SECTION_WELCOME)) {
-			id = tabID;
-		} else {
-			// everything else can go to browse..
-			id = SIDEBAR_SECTION_BROWSE;
-		}
-
-		final String itemID = id;
-
-		entry = getEntry(itemID);
-		if (entry.isInTree()) {
-			itemSelected(entry.treeItem);
-			return id;
+			loadEntryByID(id, activate);
+			return true;
 		}
 
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (tree.isDisposed()) {
-					return;
+		MdiEntryCreationListener mdiEntryCreationListener = mapIdToCreationListener.get(id);
+		if (mdiEntryCreationListener != null) {
+			MdiEntry mdiEntry = mdiEntryCreationListener.createMDiEntry(id);
+			if (datasource != null) {
+				mdiEntry.setDatasource(datasource);
+			}
+			if (mdiEntry instanceof SideBarEntrySWT) {
+				if (onlyLoadOnce) {
+					COConfigurationManager.setParameter("sb.once." + id, true);
 				}
-				showEntryByID(itemID);
+				if (activate) {
+					showEntry(mdiEntry);
+				}
+				return true;
 			}
-		});
-		return id;
+		} else {
+			setEntryAutoOpen(id, datasource, true);
+		}
+
+		return false;
 	}
 
 	/**
@@ -2966,47 +1472,36 @@ public class SideBar
 	 * @since 4.0.0.3
 	 */
 	protected void handleContentNetworkSwitch(String tabID, long networkID) {
+		String defaultID = ContentNetworkUtils.getTarget(ConstantsVuze.getDefaultContentNetwork());
 		try {
 			ContentNetworkManager cnManager = ContentNetworkManagerFactory.getSingleton();
 			if (cnManager == null) {
-				showEntryByID(SIDEBAR_SECTION_BROWSE);
+				showEntryByID(defaultID);
 				return;
 			}
 
 			ContentNetwork cn = cnManager.getContentNetwork(networkID);
 			if (cn == null) {
-				showEntryByID(SIDEBAR_SECTION_BROWSE);
+				showEntryByID(defaultID);
 				return;
 			}
 
 			if (networkID == ContentNetwork.CONTENT_NETWORK_VUZE) {
-				showEntryByID(SIDEBAR_SECTION_BROWSE);
+				showEntryByID(defaultID);
 				cn.setPersistentProperty(ContentNetwork.PP_ACTIVE, Boolean.TRUE);
 				return;
 			}
 
-			boolean doneAuth = false;
-			Object oDoneAuth = cn.getPersistentProperty(ContentNetwork.PP_AUTH_PAGE_SHOWN);
-			if (oDoneAuth instanceof Boolean) {
-				doneAuth = ((Boolean) oDoneAuth).booleanValue();
-			}
-
-			if (!doneAuth && cn.isServiceSupported(ContentNetwork.SERVICE_AUTHORIZE)) {
-				if (!AuthorizeWindow.openAuthorizeWindow(cn)) {
-					return;
-				}
-			}
-
 			createContentNetworkSideBarEntry(cn);
 			showEntryByID(tabID);
 			return;
 		} catch (Exception e) {
 			Debug.out(e);
 		}
-		showEntryByID(SIDEBAR_SECTION_BROWSE);
+		showEntryByID(defaultID);
 	}
 
-	public void createContentNetworkSideBarEntry(ContentNetwork cn) {
+	private void createContentNetworkSideBarEntry(ContentNetwork cn) {
 		String entryID = ContentNetworkUtils.getTarget(cn);
 
 		if (entryExists(entryID)) {
@@ -3014,87 +1509,85 @@ public class SideBar
 		}
 
 		String name = cn.getName();
-		SideBarEntrySWT entryBrowse = getEntry(SIDEBAR_SECTION_BROWSE);
-		int position = entryBrowse == null ? 3
-				: tree.indexOf(entryBrowse.getTreeItem()) + 1;
 
 		Object prop = cn.getProperty(ContentNetwork.PROPERTY_REMOVEABLE);
 		boolean closeable = (prop instanceof Boolean)
 				? ((Boolean) prop).booleanValue() : false;
-		final SideBarEntrySWT entry = createEntryFromSkinRef(null, entryID,
-				"main.area.browsetab", name, null, cn, closeable, position);
-
-		ContentNetworkUI.loadImage(cn.getID(),
-				new ContentNetworkImageLoadedListener() {
-					public void contentNetworkImageLoaded(Long contentNetworkID,
-							Image image, boolean wasReturned) {
-						entry.setImageLeft(image);
-					}
-				});
+		final SideBarEntrySWT entry = (SideBarEntrySWT) createEntryFromSkinRef(
+				SIDEBAR_HEADER_VUZE, entryID, "main.area.browsetab", name, null, cn,
+				closeable, SIDEBAR_SECTION_WELCOME);
+
+		Image image = ImageLoader.getInstance().getImage("image.sidebar.vuze");
+		entry.setImageLeft(image);
+
 		cn.setPersistentProperty(ContentNetwork.PP_ACTIVE, Boolean.TRUE);
 		cn.setPersistentProperty(ContentNetwork.PP_SHOW_IN_MENU, Boolean.TRUE);
 	}
 
-	/**
-	 * @param browse
-	 * @return 
-	 *
-	 * @since 3.1.1.1
-	 */
-	public SideBarEntrySWT getEntryBySkinView(SkinView skinView) {
-		SWTSkinObject so = skinView.getMainSkinObject();
-		Object[] sideBarEntries = mapIdToEntries.values().toArray();
-		for (int i = 0; i < sideBarEntries.length; i++) {
-			SideBarEntrySWT entry = (SideBarEntrySWT) sideBarEntries[i];
-			SWTSkinObject entrySO = entry.getSkinObject();
-			SWTSkinObject entrySOParent = entrySO == null ? entrySO
-					: entrySO.getParent();
-			if (entrySO == so || entrySO == so.getParent() || entrySOParent == so) {
-				return entry;
+	public Font getHeaderFont() {
+		return fontHeader;
+	}
+
+	protected Tree getTree() {
+		return tree;
+	}
+
+	// @see com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT#getEntryFromSkinObject(org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject)
+	public MdiEntrySWT getEntryFromSkinObject(
+			PluginUISWTSkinObject pluginSkinObject) {
+		if (pluginSkinObject instanceof SWTSkinObject) {
+			Control control = ((SWTSkinObject) pluginSkinObject).getControl();
+			while (control != null && !control.isDisposed()) {
+				Object entry = control.getData("BaseMDIEntry");
+				if (entry instanceof BaseMdiEntry) {
+					BaseMdiEntry mdiEntry = (BaseMdiEntry) entry;
+					return mdiEntry;
+				}
+				control = control.getParent();
 			}
 		}
 		return null;
 	}
 
-	public SideBarEntry[] getEntries() {
-		return (SideBarEntry[]) mapIdToEntries.values().toArray(new SideBarEntry[0]);
-	}
+	public void generate(IndentWriter writer) {
+		MdiEntrySWT[] entries = getEntriesSWT();
+		for (MdiEntrySWT entry : entries) {
+			if (entry == null) {
+				continue;
+			}
 
-	public int
-	getIndexOfEntryRelativeToParent(
-		SideBarEntrySWT	entry )
-	{
-		TreeItem[] items = tree.getItems();
-		
-		for (int i=0;i<items.length;i++ ){
-			
-			if ( items[i] == entry.getTreeItem()){
-				
-				return( i );
+			UISWTViewCore view = entry.getCoreView();
+
+			if (!(view instanceof AEDiagnosticsEvidenceGenerator)) {
+				writer.println("Sidebar View (No Generator): " + entry.getId());
+				try {
+					writer.indent();
+
+					writer.println("Parent: " + entry.getParentID());
+					writer.println("Title: " + entry.getTitle());
+				} catch (Exception e) {
+
+				} finally {
+
+					writer.exdent();
+				}
 			}
+			
 		}
-		
-		return( -1 );
-	}
-	
-	protected void linkTitleInfoToEntry(ViewTitleInfo ti, SideBarEntry entry) {
-		mapTitleInfoToEntry.put(ti, entry);
 	}
 
-	/**
-	 * @param id
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void closeEntry(final String id) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				SideBarEntrySWT entry = getEntry(id);
-				if (entry != null && entry.treeItem != null
-						&& !entry.treeItem.isDisposed()) {
-					entry.treeItem.dispose();
-				}
+	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateImage#obfusticatedImage(org.eclipse.swt.graphics.Image)
+	public Image obfusticatedImage(Image image) {
+
+		Rectangle treeBounds = tree.getBounds();
+		SideBarEntrySWT[] sideBarEntries = mapIdToEntry.values().toArray(
+				new SideBarEntrySWT[0]);
+		for (SideBarEntrySWT entry : sideBarEntries) {
+			Rectangle entryBounds = entry.swt_getBounds();
+			if (treeBounds.intersects(entryBounds)) {
+				entry.obfusticatedImage(image);
 			}
-		});
+		}
+		return image;
 	}
 }
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 73c7c6c..8a786d2 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarEntrySWT.java
@@ -15,450 +15,1128 @@
  * 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.views.skin.sidebar;
 
-import java.util.ArrayList;
-import java.util.Collections;
+import java.util.*;
 import java.util.List;
 
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+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.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;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.IconBar.IconBarListener;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.views.IView;
+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.mainwindow.SWTThread;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
-
-import org.gudy.azureus2.plugins.ui.sidebar.*;
+import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
+import com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener;
+import com.aelitis.azureus.ui.swt.skin.*;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+import com.aelitis.azureus.util.MapUtils;
 
 /**
  * @author TuxPaper
  * @created Aug 13, 2008
  *
  */
-public class SideBarEntrySWT implements SideBarEntry
+public class SideBarEntrySWT
+	extends BaseMdiEntry
+	implements DisposeListener, ObfusticateImage
 {
-	final public String id;
-	
-	public String parentID;
+	private static final boolean DO_OUR_OWN_TREE_INDENT = true;
 
-	public Object datasource;
+	private static final int SIDEBAR_SPACING = 2;
 
-	public ViewTitleInfo titleInfo;
+	private static final int IMAGELEFT_SIZE = 20;
 
-	SWTSkinObject skinObject;
+	private static final int IMAGELEFT_GAP = 5;
 
-	TreeItem treeItem;
+	private static final boolean ALWAYS_IMAGE_GAP = true;
 
-	boolean pullTitleFromIView;
+	private static final String[] default_indicator_colors = {
+		"#000000",
+		"#000000",
+		"#166688",
+		"#1c2056"
+	};
 
-	public IView iview;
+	private static long uniqueNumber = 0;
 
-	public boolean closeable;
+	private TreeItem swtItem;
 
-	public UISWTViewEventListener eventListener;
+	@SuppressWarnings("unchecked")
+	private List<SideBarVitalityImageSWT> listVitalityImages = Collections.EMPTY_LIST;
 
-	public Class iviewClass;
+	private final SideBar sidebar;
 
-	public Class[] iviewClassArgs;
+	private int maxIndicatorWidth;
 
-	public Object[] iviewClassVals;
-	
-	public boolean disableCollapse;
-	
-	private List listVitalityImages = Collections.EMPTY_LIST;
+	private Image imgClose;
 
-	private String imageLeftID;
-	
-	private List listCloseListeners = Collections.EMPTY_LIST;
+	private Image imgCloseSelected;
 
-	private List listLogIDListeners = Collections.EMPTY_LIST;
+	private Color bg;
 
-	private List listOpenListeners = Collections.EMPTY_LIST;
+	private Color fg;
 
-	private List listDropListeners = Collections.EMPTY_LIST;
+	private Color bgSel;
 
-	private IconBarEnabler iconBarEnabler;
+	private Color fgSel;
 
-	private final SideBar sidebar;
+	//private Color colorFocus;
+
+	private boolean showonSWTItemSet;
+
+	private final SWTSkin skin;
+
+	private SWTSkinObjectContainer soParent;
+
+	private boolean buildonSWTItemSet;
 	
-	private String logID;
+	private boolean selectable = true;
 
-	private Image imageLeft;
+	private List<MdiSWTMenuHackListener> listMenuHackListners;
 	
-	public SideBarEntrySWT(SideBar sidebar, String id) {
-		this.id = id;
-		
+	private boolean neverPainted = true;
+
+	public SideBarEntrySWT(SideBar sidebar, SWTSkin _skin, String id) {
+		super(sidebar, id);
+		this.skin = _skin;
+
 		if (id == null) {
 			logID = "null";
 		} else {
-  		int i = id.indexOf('_');
-  		if (i > 0) {
-  			logID = id.substring(0, i);
-  		} else {
-  			logID = id;
-  		}
+			int i = id.indexOf('_');
+			if (i > 0) {
+				logID = id.substring(0, i);
+			} else {
+				logID = id;
+			}
 		}
 
 		this.sidebar = sidebar;
+
+		updateColors();
 	}
-	
-	public String getParentID() {
-		return parentID;
+
+	private void updateColors() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				SWTSkinProperties skinProperties = skin.getSkinProperties();
+				bg = skinProperties.getColor("color.sidebar.bg");
+				fg = skinProperties.getColor("color.sidebar."
+						+ (isSelectable() ? "text" : "header"));
+				bgSel = skinProperties.getColor("color.sidebar.selected.bg");
+				fgSel = skinProperties.getColor("color.sidebar.selected.fg");
+				//colorFocus = skinProperties.getColor("color.sidebar.focus");
+			}
+		});
 	}
 
-	public void setParentID(String parentID) {
-		this.parentID = parentID;
+	public TreeItem getTreeItem() {
+		return swtItem;
 	}
 
-	public Object getDatasourceCore() {
-		return datasource;
+	public void setTreeItem(TreeItem treeItem) {
+		if (swtItem != null && treeItem != null) {
+			Debug.out("Warning: Sidebar " + id + " already has a treeitem");
+			return;
+		}
+		this.swtItem = treeItem;
+		setDisposed(false);
+
+		if (treeItem != null) {
+			ImageLoader imageLoader = ImageLoader.getInstance();
+			imgClose = imageLoader.getImage("image.sidebar.closeitem");
+			imgCloseSelected = imageLoader.getImage("image.sidebar.closeitem-selected");
+
+			treeItem.addDisposeListener(this);
+
+			treeItem.getParent().addTreeListener(new TreeListener() {
+				public void treeExpanded(TreeEvent e) {
+					if (e.item == swtItem) {
+						SideBarEntrySWT.super.setExpanded(true);
+					}
+				}
+
+				public void treeCollapsed(TreeEvent e) {
+					if (e.item == swtItem) {
+						SideBarEntrySWT.super.setExpanded(false);
+					}
+				}
+			});
+			
+			// Some/All OSes will auto-set treeitem's expanded flag to false if there
+			// is no children.  To workaround, we store expanded state internally and
+			// set parent to expanded when a child is added
+			TreeItem parentItem = treeItem.getParentItem();
+			if (parentItem != null) {
+				MdiEntry parentEntry = (MdiEntry) parentItem.getData("MdiEntry");
+				if (parentEntry.isExpanded()) {
+					parentItem.setExpanded(true);
+				}
+			}
+
+			setExpanded(isExpanded());
+		}
+		if (buildonSWTItemSet) {
+			build();
+		}
+		if (showonSWTItemSet) {
+			show();
+		}
 	}
 
-	public Object getDatasource() {
-		return PluginCoreUtils.convert(datasource, false);
+	// @see org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry#addVitalityImage(java.lang.String)
+	public MdiEntryVitalityImage addVitalityImage(String imageID) {
+		synchronized (this) {
+		SideBarVitalityImageSWT vitalityImage = new SideBarVitalityImageSWT(this,
+				imageID);
+		if (listVitalityImages == Collections.EMPTY_LIST) {
+			listVitalityImages = new ArrayList<SideBarVitalityImageSWT>(1);
+		}
+		listVitalityImages.add(vitalityImage);
+		return vitalityImage;
+	}
 	}
 
-	public void setDatasource(Object datasource) {
-		this.datasource = datasource;
+	public MdiEntryVitalityImage[] getVitalityImages() {
+		return listVitalityImages.toArray(new MdiEntryVitalityImage[0]);
 	}
 
-	public ViewTitleInfo getTitleInfo() {
-		return titleInfo;
+	public MdiEntryVitalityImage getVitalityImage(int hitX, int hitY) {
+		MdiEntryVitalityImage[] vitalityImages = getVitalityImages();
+		for (int i = 0; i < vitalityImages.length; i++) {
+			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
+			if (!vitalityImage.isVisible()) {
+				continue;
+			}
+			Rectangle hitArea = vitalityImage.getHitArea();
+			if (hitArea != null && hitArea.contains(hitX, hitY)) {
+				return vitalityImage;
+			}
+		}
+		return null;
 	}
 
-	public void setTitleInfo(ViewTitleInfo titleInfo) {
-		this.titleInfo = titleInfo;
-		
-		sidebar.linkTitleInfoToEntry(titleInfo, this);
-		
-		if (treeItem != null && !treeItem.isDisposed()) {
-  		String newText = (String) titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
-  		if (newText != null) {
-  			pullTitleFromIView = false;
-  			treeItem.setData("text", newText);
-  			redraw();
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.mdi.MdiEntry#redraw()
+	 */
+	boolean isRedrawQueued = false;
+	public void redraw() {
+		if (neverPainted) {
+			return;
+		}
+		synchronized (this) {
+  		if (isRedrawQueued) {
+  			return;
   		}
+  		isRedrawQueued = true;
 		}
-	}
 
-	public SWTSkinObject getSkinObject() {
-		return skinObject;
+		//System.out.println("redraw " + Thread.currentThread().getName() + ":" + getId() + " via " + Debug.getCompressedStackTrace());
+		
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				try {
+  				if (swtItem == null || swtItem.isDisposed()) {
+  					return;
+  				}
+  				Tree tree = swtItem.getParent();
+  				if (!tree.isVisible()) {
+  					return;
+  				}
+  				try {
+  					Rectangle bounds = swtItem.getBounds();
+  					Rectangle treeBounds = tree.getBounds();
+  					tree.redraw(0, bounds.y, treeBounds.width, bounds.height, true);
+  				} catch (NullPointerException npe) {
+  					// ignore NPE. OSX seems to be spewing this when the tree size is 0
+  					// or is invisible or something like that
+  				}
+  				//tree.update();
+				} finally {
+					synchronized (SideBarEntrySWT.this) {
+						isRedrawQueued = false;
+					}
+				}
+			}
+		});
 	}
 
-	public void setSkinObject(SWTSkinObject skinObject) {
-		this.skinObject = skinObject;
+	protected Rectangle swt_getBounds() {
+		if (swtItem == null || swtItem.isDisposed()) {
+			return null;
+		}
+		try {
+			Tree tree = swtItem.getParent();
+			Rectangle bounds = swtItem.getBounds();
+			Rectangle treeBounds = tree.getClientArea();
+			return new Rectangle(0, bounds.y, treeBounds.width, bounds.height);
+		} catch (NullPointerException e) {
+			// On OSX, we get erroneous NPE here:
+			//at org.eclipse.swt.widgets.Tree.sendMeasureItem(Tree.java:2443)
+			//at org.eclipse.swt.widgets.Tree.cellSize(Tree.java:274)
+			//at org.eclipse.swt.widgets.Display.windowProc(Display.java:4750)
+			//at org.eclipse.swt.internal.cocoa.OS.objc_msgSend_stret(Native Method)
+			//at org.eclipse.swt.internal.cocoa.NSCell.cellSize(NSCell.java:34)
+			//at org.eclipse.swt.widgets.TreeItem.getBounds(TreeItem.java:467)
+			Debug.outNoStack("NPE @ " + Debug.getCompressedStackTrace(), true);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+		return null;
 	}
 
-	public TreeItem getTreeItem() {
-		return treeItem;
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#setExpanded(boolean)
+	 */
+	public void setExpanded(final boolean expanded) {
+		super.setExpanded(expanded);
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (swtItem != null && !isDisposed()) {
+					swtItem.setExpanded(expanded);
+				}
+			}
+		});
 	}
 
-	public void setTreeItem(TreeItem treeItem) {
-		this.treeItem = treeItem;
-	}
+	public void expandTo() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (swtItem == null || isDisposed()) {
+					return;
+				}
 
-	public boolean isPullTitleFromIView() {
-		return pullTitleFromIView;
+				TreeItem item = swtItem.getParentItem();
+				while (item != null) {
+					item.setExpanded(true);
+					// walk up and make sure parents are expanded
+					item = item.getParentItem();
+				}
+			}
+		});
 	}
 
-	public void setPullTitleFromIView(boolean pullTitleFromIView) {
-		this.pullTitleFromIView = pullTitleFromIView;
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#close()
+	 */
+	public boolean close(boolean force) {
+		if (!super.close(force)) {
+			return false;
+		}
+		
+		// remove immediately from MDI because disposal is on a delay
+		mdi.removeItem(SideBarEntrySWT.this);
+		
+		// dispose will trigger dispose listener, which removed it from BaseMDI
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (swtItem != null) {
+					try {
+  					swtItem.setFont(null);
+  					swtItem.dispose();
+					} catch (Exception e) {
+						// on OSX, SWT does some misguided exceptions on disposal of TreeItem
+						// We occasionally get SWTException of "Widget is Disposed" or
+						// "Argument not valid", as well as NPEs
+						Debug.outNoStack(
+								"Warning on SidebarEntry dispose: " + e.toString(), false);
+					} finally {
+  					swtItem = null;
+					}
+				} else if (view != null) {
+					try {
+	      		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+					} finally {
+						view = null;
+					}
+				}
+			}
+		});
+		return true;
 	}
 
-	public IView getIView() {
-		return iview;
+	public void build() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_build();
+				SideBarEntrySWT.super.build();
+			}
+		});
 	}
 
-	public void setIView(IView iview) {
-		this.iview = iview;
-	}
+	public boolean swt_build() {
+		if (swtItem == null) {
+			buildonSWTItemSet = true;
+			return true;
+		}
+		buildonSWTItemSet = false;
+
+		if (getSkinObject() == null) {
+			Control control = null;
+
+			Composite parent = soParent == null ? Utils.findAnyShell()
+					: soParent.getComposite();
+
+			String skinRef = getSkinRef();
+			if (skinRef != null) {
+				Shell shell = parent.getShell();
+				Cursor cursor = shell.getCursor();
+				try {
+					shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+
+					// wrap skinRef with a container that we control visibility of
+					// (invisible by default)
+					SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
+							"MdiContents." + uniqueNumber++, "mdi.content.item",
+							getParentSkinObject(), null);
+					skin.addSkinObject(soContents);
+
+					SWTSkinObject skinObject = skin.createSkinObject(id, skinRef,
+							soContents, getDatasourceCore());
+					skin.addSkinObject(soContents);
+
+					control = skinObject.getControl();
+					control.setLayoutData(Utils.getFilledFormData());
+					control.getParent().layout(true, true);
+					setSkinObject(skinObject, soContents);
+				} finally {
+					shell.setCursor(cursor);
+				}
+			} else if (view != null) {
+				try {
+					SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
+							"MdiIView." + uniqueNumber++, "mdi.content.item",
+							getParentSkinObject());
+					skin.addSkinObject(soContents);
+
+					parent.setBackgroundMode(SWT.INHERIT_NONE);
+
+					Composite viewComposite = soContents.getComposite();
+					boolean doGridLayout = true;
+					if (view.getControlType() == UISWTViewCore.CONTROLTYPE_SKINOBJECT) {
+						doGridLayout = false;
+					}
+					//					viewComposite.setBackground(parent.getDisplay().getSystemColor(
+					//							SWT.COLOR_WIDGET_BACKGROUND));
+					//					viewComposite.setForeground(parent.getDisplay().getSystemColor(
+					//							SWT.COLOR_WIDGET_FOREGROUND));
+					if (doGridLayout) {
+						GridLayout gridLayout = new GridLayout();
+						gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
+						viewComposite.setLayout(gridLayout);
+						viewComposite.setLayoutData(Utils.getFilledFormData());
+					}
+
+					view.setSkinObject(soContents, soContents.getComposite());
+					view.initialize(viewComposite);
+					swtItem.setText(view.getFullTitle());
+
+					Composite iviewComposite = view.getComposite();
+					control = iviewComposite;
+					// force layout data of IView's composite to GridData, since we set
+					// the parent to GridLayout (most plugins use grid, so we stick with
+					// that instead of form)
+					if (doGridLayout) {
+						Object existingLayoutData = iviewComposite.getLayoutData();
+						Object existingParentLayoutData = iviewComposite.getParent().getLayoutData();
+						if (existingLayoutData == null
+								|| !(existingLayoutData instanceof GridData)
+								&& (existingParentLayoutData instanceof GridLayout)) {
+							GridData gridData = new GridData(GridData.FILL_BOTH);
+							iviewComposite.setLayoutData(gridData);
+						}
+					}
+
+					parent.layout(true, true);
+
+					setSkinObject(soContents, soContents);
+				} catch (Exception e) {
+					Debug.out("Error creating sidebar content area for " + id, e);
+					setCoreView(null);
+					close(true);
+				}
 
-	public boolean isCloseable() {
-		return closeable;
-	}
+			} else if (viewClass != null) {
+				try {
+					UISWTViewCore view = (UISWTViewCore) viewClass.newInstance();
+
+					if (view != null) {
+						setCoreView(view);
+						// now that we have an IView, go through show one more time
+						return swt_build();
+					}
+					close(true);
+					return false;
+				} catch (Throwable e) {
+					Debug.out(e);
+					close(true);
+				}
+			}
 
-	public void setCloseable(boolean closeable) {
-		this.closeable = closeable;
+			if (control != null && !control.isDisposed()) {
+				control.setData("BaseMDIEntry", this);
+				control.addDisposeListener(new DisposeListener() {
+					public void widgetDisposed(DisposeEvent e) {
+						close(true);
+					}
+				});
+			} else {
+				return false;
+			}
+		} // control == null
+		return true;
 	}
 
-	public UISWTViewEventListener getEventListener() {
-		return eventListener;
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#show()
+	 */
+	public void show() {
+		// ensure show order by user execThreadLater
+		// fixes case where two showEntries are called, the first from a non
+		// SWT thread, and the 2nd from a SWT thread.  The first one will run last
+		// showing itself
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				swt_show();
+			}
+		});
 	}
 
-	public void setEventListener(UISWTViewEventListener eventListener) {
-		this.eventListener = eventListener;
-	}
+	private void swt_show() {
+		if (swtItem == null) {
+			showonSWTItemSet = true;
+			return;
+		}
+		showonSWTItemSet = false;
+		if (!swt_build()) {
+			return;
+		}
+		
+		triggerOpenListeners();
 
-	public Class getIViewClass() {
-		return iviewClass;
-	}
+		swtItem.getParent().select(swtItem);
+		swtItem.getParent().showItem(swtItem);
 
-	public void setIViewClass(Class iviewClass) {
-		this.iviewClass = iviewClass;
+		super.show();
 	}
 
-	public Class[] getIViewClassArgs() {
-		return iviewClassArgs;
-	}
+	protected void swt_paintSideBar(Event event) {
+		neverPainted = false;
+		//System.out.println(System.currentTimeMillis() + "] paint " + getId() + ";sel? " + ((event.detail & SWT.SELECTED) > 0));
+		TreeItem treeItem = (TreeItem) event.item;
+		if (treeItem.isDisposed() || isDisposed()) {
+			return;
+		}
+		Rectangle itemBounds = treeItem.getBounds();
+		Rectangle drawBounds = event.gc.getClipping();
+		if (drawBounds.isEmpty()) {
+			drawBounds = event.getBounds();
+		}
 
-	public void setIViewClassArgs(Class[] iviewClassArgs) {
-		this.iviewClassArgs = iviewClassArgs;
-	}
+		String text = getTitle();
+		if (text == null)
+			text = "";
 
-	public Object[] getIViewClassVals() {
-		return iviewClassVals;
-	}
+		//Point size = event.gc.textExtent(text);
+		//Rectangle treeBounds = tree.getBounds();
+		GC gc = event.gc;
 
-	public void setIViewClassVals(Object[] iviewClassVals) {
-		this.iviewClassVals = iviewClassVals;
-	}
+		gc.setAntialias(SWT.ON);
+		gc.setAdvanced(true);
+		//gc.setClipping((Rectangle) null);
 
-	public String getId() {
-		return id;
-	}
+		boolean selected = (event.detail & SWT.SELECTED) > 0;
+		Color fgText = swt_paintEntryBG(event.detail, gc, drawBounds);
 
-	// @see org.gudy.azureus2.plugins.ui.sidebar.SideBarEntry#addVitalityImage(java.lang.String)
-	public SideBarVitalityImage addVitalityImage(String imageID) {
-		SideBarVitalityImageSWT vitalityImage = new SideBarVitalityImageSWT(this, imageID);
-		if (listVitalityImages == Collections.EMPTY_LIST) {
-			listVitalityImages = new ArrayList(1);
+		Tree tree = (Tree) event.widget;
+
+		Rectangle treeArea = tree.getClientArea();
+
+		Font font = tree.getFont();
+		if (font != null && !font.isDisposed()) {
+			gc.setFont(font);
 		}
-		listVitalityImages.add(vitalityImage);
-		return vitalityImage;
-	}
-	
-	public SideBarVitalityImage[] getVitalityImages() {
-		return (SideBarVitalityImage[]) listVitalityImages.toArray(new SideBarVitalityImage[0]);
-	}
-	
-	public SideBarVitalityImage getVitalityImage(int hitX, int hitY) {
-		SideBarVitalityImage[] vitalityImages = getVitalityImages();
+
+		if (DO_OUR_OWN_TREE_INDENT) {
+			TreeItem tempItem = treeItem.getParentItem();
+			int indent;
+			if (!isCollapseDisabled() && tempItem == null && !Utils.isGTK) {
+				indent = 22;
+			} else {
+				indent = 10;
+			}
+			while (tempItem != null) {
+				indent += 10;
+				tempItem = tempItem.getParentItem();
+			}
+			if (SideBar.USE_NATIVE_EXPANDER && Utils.isGTK) {
+				indent += 5;
+			}
+			itemBounds.x = indent;
+		}
+		int x1IndicatorOfs = SIDEBAR_SPACING;
+		int x0IndicatorOfs = itemBounds.x;
+
+		//System.out.println(System.currentTimeMillis() + "] refresh " + getId() + "; " + itemBounds + ";clip=" + event.gc.getClipping() + ";eb=" + event.getBounds());
+		if (viewTitleInfo != null) {
+			String textIndicator = null;
+			try {
+				textIndicator = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+			if (textIndicator != null) {
+
+				Point textSize = gc.textExtent(textIndicator);
+				//Point minTextSize = gc.textExtent("99");
+				//if (textSize.x < minTextSize.x + 2) {
+				//	textSize.x = minTextSize.x + 2;
+				//}
+
+				int width = textSize.x + 10;
+				x1IndicatorOfs += width + SIDEBAR_SPACING;
+				int startX = treeArea.width - x1IndicatorOfs;
+
+				int textOffsetY = 0;
+
+				int height = textSize.y + 1;
+				int startY = itemBounds.y + (itemBounds.height - height) / 2;
+
+				//gc.fillRectangle(startX, startY, width, height);
+
+				//Pattern pattern;
+				//Color color1;
+				//Color color2;
+
+				String[] colors = (String[]) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_COLOR);
+
+				if (colors == null || colors.length != 4) {
+					colors = default_indicator_colors;
+				}
+
+				/*
+				if (selected) {
+					color1 = ColorCache.getColor(gc.getDevice(), colors[0]);
+					color2 = ColorCache.getColor(gc.getDevice(), colors[1]);
+					pattern = new Pattern(gc.getDevice(), 0, startY, 0, startY + height,
+							color1, 127, color2, 4);
+				} else {
+					color1 = ColorCache.getColor(gc.getDevice(), colors[2]);
+					color2 = ColorCache.getColor(gc.getDevice(), colors[3]);
+					pattern = new Pattern(gc.getDevice(), 0, startY, 0, startY + height,
+							color1, color2);
+				}
+				gc.setBackgroundPattern(pattern);
+				*/
+				gc.setBackground(ColorCache.getColor(gc.getDevice(), "#5b6e87"));
+				gc.fillRoundRectangle(startX, startY, width, height, textSize.y * 2 / 3,
+						height * 2 / 3);
+				gc.setBackgroundPattern(null);
+				//pattern.dispose();
+				if (maxIndicatorWidth > width) {
+					maxIndicatorWidth = width;
+				}
+				gc.setForeground(Colors.white);
+				GCStringPrinter.printString(gc, textIndicator, new Rectangle(startX,
+						startY + textOffsetY, width, height), true, false, SWT.CENTER);
+			}
+		}
+
+		//if (x1IndicatorOfs < 30) {
+		//	x1IndicatorOfs = 30;
+		//}
+
+		if (isCloseable()) {
+			Image img = selected ? imgCloseSelected : imgClose;
+			Rectangle closeArea = img.getBounds();
+			closeArea.x = treeArea.width - closeArea.width - SIDEBAR_SPACING
+					- x1IndicatorOfs;
+			closeArea.y = itemBounds.y + (itemBounds.height - closeArea.height) / 2;
+			x1IndicatorOfs += closeArea.width + SIDEBAR_SPACING;
+
+			//gc.setBackground(treeItem.getBackground());
+			//gc.fillRectangle(closeArea);
+
+			gc.drawImage(img, closeArea.x, closeArea.y);
+			treeItem.setData("closeArea", closeArea);
+		}
+
+		MdiEntryVitalityImage[] vitalityImages = getVitalityImages();
 		for (int i = 0; i < vitalityImages.length; i++) {
 			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
-			if (!vitalityImage.isVisible()) {
+			if (vitalityImage == null || !vitalityImage.isVisible()
+					|| vitalityImage.getAlignment() != SWT.RIGHT) {
 				continue;
 			}
-			Rectangle hitArea = vitalityImage.getHitArea();
-			if (hitArea != null && hitArea.contains(hitX, hitY)) {
-				return vitalityImage;
+			vitalityImage.switchSuffix(selected ? "-selected" : "");
+			Image image = vitalityImage.getImage();
+			if (image != null && !image.isDisposed()) {
+				Rectangle bounds = image.getBounds();
+				bounds.x = treeArea.width - bounds.width - SIDEBAR_SPACING
+						- x1IndicatorOfs;
+				bounds.y = itemBounds.y + (itemBounds.height - bounds.height) / 2;
+				x1IndicatorOfs += bounds.width + SIDEBAR_SPACING;
+
+				gc.drawImage(image, bounds.x, bounds.y);
+				// setHitArea needs it relative to entry
+				bounds.y -= itemBounds.y;
+				vitalityImage.setHitArea(bounds);
 			}
 		}
-		return null;
-	}
-	
-	public void redraw() {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				if (treeItem == null || treeItem.isDisposed()) {
-					return;
-				}
-				Tree tree = treeItem.getParent();
-				Rectangle bounds = treeItem.getBounds();
-				Rectangle treeBounds = tree.getBounds();
-				tree.redraw(0, bounds.y, treeBounds.width, bounds.height, true);
-				//tree.update();
+
+		boolean greyScale = false;
+
+		if (viewTitleInfo != null) {
+
+			Object active_state = viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_ACTIVE_STATE);
+
+			if (active_state instanceof Long) {
+
+				greyScale = (Long) active_state == 2;
 			}
-		});
-	}
-	
-	public Rectangle getBounds() {
-		if (treeItem == null || treeItem.isDisposed()) {
-			return null;
 		}
-		Tree tree = treeItem.getParent();
-		Rectangle bounds = treeItem.getBounds();
-		Rectangle treeBounds = tree.getBounds();
-		return new Rectangle(0, bounds.y, treeBounds.width, bounds.height);
-	}
-	
-	public void setImageLeftID(String id) {
-		imageLeftID = id;
-		imageLeft = null;
-	}
-	
-	public String
-	getImageLeftID()
-	{
-		return( imageLeftID );
-	}
-	
-	/**
-	 * @param imageLeft the imageLeft to set
-	 */
-	public void setImageLeft(Image imageLeft) {
-		this.imageLeft = imageLeft;
-		imageLeftID = null;
-		redraw();
-	}
-	
-	public Image getImageLeft(String suffix) {
-		if (imageLeft != null) {
-			return imageLeft;
-		}
-		if (imageLeftID == null) {
-			return null;
+
+		String suffix = selected ? "-selected" : null;
+		Image imageLeft = getImageLeft(suffix);
+		if (imageLeft == null && selected) {
+			releaseImageLeft(suffix);
+			suffix = null;
+			imageLeft = getImageLeft(null);
 		}
-		Image img = null;
-		if (suffix == null) {
-			img = ImageLoader.getInstance().getImage(imageLeftID);
+		if (imageLeft != null) {
+			Rectangle clipping = gc.getClipping();
+			gc.setClipping(x0IndicatorOfs, itemBounds.y, IMAGELEFT_SIZE,
+					itemBounds.height);
+
+			if (greyScale) {
+				greyScale = false;
+				String imageLeftID = getImageLeftID();
+				if (imageLeftID != null) {
+					Image grey = ImageLoader.getInstance().getImage(imageLeftID + "-gray");
+
+					if (grey != null) {
+						imageLeft = grey;
+						gc.setAlpha(160);
+						greyScale = true;
+					}
+				}
+			}
+
+			Rectangle bounds = imageLeft.getBounds();
+			int w = bounds.width;
+			int h = bounds.height;
+			if (w > IMAGELEFT_SIZE) {
+				float pct = IMAGELEFT_SIZE / (float) w;
+				w = IMAGELEFT_SIZE;
+				h *= pct;
+			}
+			int x = x0IndicatorOfs + ((IMAGELEFT_SIZE - w) / 2);
+			int y = itemBounds.y + ((itemBounds.height - h) / 2);
+			
+			gc.setAdvanced(true);
+			gc.setInterpolation(SWT.HIGH);
+			gc.drawImage(imageLeft, 0, 0, bounds.width, bounds.height, x, y, w, h );
+
+			if (greyScale) {
+				String imageLeftID = getImageLeftID();
+  			gc.setAlpha(255);
+  			ImageLoader.getInstance().releaseImage(imageLeftID + "-gray");
+			}
+
+			releaseImageLeft(suffix);
+			gc.setClipping(clipping);
+			//			0, 0, bounds.width, bounds.height,
+			//					x0IndicatorOfs, itemBounds.y
+			//							+ ((itemBounds.height - IMAGELEFT_SIZE) / 2), IMAGELEFT_SIZE,
+			//					IMAGELEFT_SIZE);
+
+			x0IndicatorOfs += IMAGELEFT_SIZE + IMAGELEFT_GAP;
+
+			releaseImageLeft(suffix);
+		} else if (ALWAYS_IMAGE_GAP) {
+			if (isSelectable()) {
+				x0IndicatorOfs += IMAGELEFT_SIZE + IMAGELEFT_GAP;
+			}
 		} else {
-			img = ImageLoader.getInstance().getImage(imageLeftID + suffix);
+			if (treeItem.getParentItem() != null) {
+				x0IndicatorOfs += 30 - 18;
+			}
 		}
-		if (ImageLoader.isRealImage(img)) {
-			return img;
+
+		// Main Text
+		////////////
+
+		Rectangle clipping = new Rectangle(x0IndicatorOfs, itemBounds.y,
+				treeArea.width - x1IndicatorOfs - SIDEBAR_SPACING - x0IndicatorOfs,
+				itemBounds.height);
+
+		if (drawBounds.intersects(clipping)) {
+			int style= SWT.NONE;
+  		if (!isSelectable()) {
+  			Font headerFont = sidebar.getHeaderFont();
+  			if (headerFont != null && !headerFont.isDisposed()) {
+  				gc.setFont(headerFont);
+  			}
+  			text = text.toUpperCase();
+
+    		gc.setForeground(ColorCache.getColor(gc.getDevice(), 255, 255, 255));
+    		gc.setAlpha(100);
+    		clipping.x++;
+    		clipping.y++;
+    		//style = SWT.TOP;
+  			GCStringPrinter sp = new GCStringPrinter(gc, text, clipping, true, false,
+  					style);
+  			sp.printString();
+    		gc.setAlpha(255);
+
+    		clipping.x--;
+    		clipping.y--;
+  			gc.setForeground(fgText);
+  		} else {
+  			gc.setForeground(fgText);
+  		}
+			//gc.setClipping(clipping);
+
+			GCStringPrinter sp = new GCStringPrinter(gc, text, clipping, true, false,
+					style);
+			sp.printString();
+			clipping.x += sp.getCalculatedSize().x + 5;
+			//gc.setClipping((Rectangle) null);
 		}
-		return null;
-	}
-	
-	public void releaseImageLeft(String suffix) {
-		if (imageLeft != null) {
-			ImageLoader.getInstance().releaseImage(imageLeftID + suffix);
+		
+		// Vitality Images
+
+		for (int i = 0; i < vitalityImages.length; i++) {
+			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
+			if (!vitalityImage.isVisible()
+					|| vitalityImage.getAlignment() != SWT.LEFT) {
+				continue;
+			}
+			vitalityImage.switchSuffix(selected ? "-selected" : "");
+			Image image = vitalityImage.getImage();
+			if (image != null && !image.isDisposed()) {
+				Rectangle bounds = image.getBounds();
+				bounds.x = clipping.x;
+				bounds.y = itemBounds.y + (itemBounds.height - bounds.height) / 2;
+				clipping.x += bounds.width + SIDEBAR_SPACING;
+
+				if (clipping.x > (treeArea.width - x1IndicatorOfs)) {
+					vitalityImage.setHitArea(null);
+					continue;
+				}
+				gc.drawImage(image, bounds.x, bounds.y);
+				vitalityImage.setHitArea(bounds);
+			}
 		}
-	}
-	
-	/**
-	 * @param l
-	 *
-	 * @since 4.0.0.5
-	 */
-	public void addListener(SideBarCloseListener l) {
-		if (listCloseListeners == Collections.EMPTY_LIST) {
-			listCloseListeners = new ArrayList(1);
+		
+		// EXPANDO
+
+		// 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 && !isCollapseDisabled()
+				&& !SideBar.USE_NATIVE_EXPANDER) {
+			gc.setAntialias(SWT.ON);
+			Color oldBG = gc.getBackground();
+			gc.setBackground(event.display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+			int baseX = 22; // itemBounds.x;
+			if (treeItem.getExpanded()) {
+				int xStart = 12;
+				int arrowSize = 8;
+				int yStart = itemBounds.height - (itemBounds.height + arrowSize) / 2;
+				gc.fillPolygon(new int[] {
+					baseX - xStart,
+					itemBounds.y + yStart,
+					baseX - xStart + arrowSize,
+					itemBounds.y + yStart,
+					baseX - xStart + (arrowSize / 2),
+					itemBounds.y + yStart + arrowSize,
+				});
+			} else {
+				int xStart = 12;
+				int arrowSize = 8;
+				int yStart = itemBounds.height - (itemBounds.height + arrowSize) / 2;
+				gc.fillPolygon(new int[] {
+					baseX - xStart,
+					itemBounds.y + yStart,
+					baseX - xStart + arrowSize,
+					itemBounds.y + yStart + 4,
+					baseX - xStart,
+					itemBounds.y + yStart + 8,
+				});
+			}
+			gc.setBackground(oldBG);
+			Font headerFont = sidebar.getHeaderFont();
+			if (headerFont != null && !headerFont.isDisposed()) {
+				gc.setFont(headerFont);
+			}
 		}
-		listCloseListeners.add(l);
-	}
-	
-	public void removeListener(SideBarCloseListener l) {
-		listCloseListeners.remove(l);
 	}
 
-	protected void triggerCloseListeners() {
-		Object[] list = listCloseListeners.toArray();
-		for (int i = 0; i < list.length; i++) {
-			SideBarCloseListener l = (SideBarCloseListener) list[i];
-			try {
-				l.sidebarClosed(this);
-			} catch (Exception e) {
-				Debug.out(e);
+	protected Color swt_paintEntryBG(int detail, GC gc, Rectangle drawBounds) {
+		neverPainted = false;
+		Color fgText = Colors.black;
+		boolean selected = (detail & SWT.SELECTED) > 0;
+		//boolean focused = (detail & SWT.FOCUSED) > 0;
+		boolean hot = (detail & SWT.HOT) > 0;
+		if (selected) {
+			//System.out.println("gmmm" + drawBounds + ": " + Debug.getCompressedStackTrace());
+			gc.setClipping((Rectangle) null);
+			if (fgSel != null) {
+				fgText = fgSel;
+			}
+			if (bgSel != null) {
+				gc.setBackground(bgSel);
+			}
+			Color color1;
+			Color color2;
+			if (sidebar.getTree().isFocusControl()) {
+				color1 = ColorCache.getColor(gc.getDevice(), "#166688");
+				color2 = ColorCache.getColor(gc.getDevice(), "#1c2458");
+			} else {
+				color1 = ColorCache.getColor(gc.getDevice(), "#447281");
+				color2 = ColorCache.getColor(gc.getDevice(), "#393e58");
+			}
+
+			gc.setBackground(color1);
+			gc.fillRectangle(drawBounds.x, drawBounds.y, drawBounds.width, 4);
+
+			gc.setForeground(color1);
+			gc.setBackground(color2);
+			Rectangle itemBounds = swt_getBounds();
+			if (itemBounds == null) {
+				return fgText;
+			}
+			// always need to start gradient at the same Y position
+			// +3 is to start gradient off 3 pixels lower
+			gc.fillGradientRectangle(drawBounds.x, itemBounds.y + 3,
+					drawBounds.width, itemBounds.height - 3, true);
+		} else {
+
+			if (fg != null) {
+				fgText = fg;
+			}
+			if (bg != null) {
+				gc.setBackground(bg);
+			}
+
+			if (this == sidebar.draggingOver || hot) {
+				Color c = skin.getSkinProperties().getColor("color.sidebar.drag.bg");
+				gc.setBackground(c);
+			}
+
+			gc.fillRectangle(drawBounds);
+
+			if (this == sidebar.draggingOver) {
+				Color c = skin.getSkinProperties().getColor("color.sidebar.drag.fg");
+				gc.setForeground(c);
+				gc.setLineWidth(5);
+				gc.drawRectangle(drawBounds);
 			}
 		}
+		return fgText;
 	}
 
-	public void addListener(SideBarLogIdListener l) {
-		if (listLogIDListeners == Collections.EMPTY_LIST) {
-			listLogIDListeners = new ArrayList(1);
+	public void widgetDisposed(DisposeEvent e) {
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		imageLoader.releaseImage("image.sidebar.closeitem");
+		imageLoader.releaseImage("image.sidebar.closeitem-selected");
+
+		final TreeItem treeItem = (TreeItem) e.widget;
+		if (treeItem != swtItem) {
+			Debug.out("Warning: TreeItem changed for sidebar " + id);
+			return;
 		}
-		listLogIDListeners.add(l);
-	}
-	
-	public void removeListener(SideBarLogIdListener sideBarLogIdListener) {
-		listLogIDListeners.remove(sideBarLogIdListener);
-	}
 
-	protected void triggerLogIDListeners(String oldID) {
-		Object[] list = listLogIDListeners.toArray();
-		for (int i = 0; i < list.length; i++) {
-			SideBarLogIdListener l = (SideBarLogIdListener) list[i];
-			l.sidebarLogIdChanged(this, oldID, logID);
+		if (swtItem == null) {
+			return;
 		}
-	}
 
-	public void addListener(SideBarOpenListener l) {
-		if (listOpenListeners == Collections.EMPTY_LIST) {
-			listOpenListeners = new ArrayList(1);
+		if (swtItem != null && !Constants.isOSX) {
+			// In theory, the disposal of swtItem will trigger the disposal of the
+			// children.  Let's force it just in case
+			// On OSX this will cause disposal confusion in SWT, and possibly result
+			// in a SIGSEGV crash.
+			TreeItem[] children = swtItem.getItems();
+			for (TreeItem child : children) {
+				if (child.isDisposed()) {
+					continue;
+				}
+				MdiEntry entry = (MdiEntry) child.getData("MdiEntry");
+				if (entry != null) {
+					entry.close(true);
+				}
+			}
 		}
-		listOpenListeners.add(l);
-		if (treeItem != null) {
-			l.sideBarEntryOpen(this);
+		
+		final Tree tree = sidebar.getTree();
+		if (tree.isDisposed() || swtItem.isDisposed() || tree.getShell().isDisposed()) {
+			return;
 		}
-	}
-	
-	public void removeListener(SideBarOpenListener l) {
-		listOpenListeners.remove(l);
-	}
 
-	protected void triggerOpenListeners() {
-		Object[] list = listOpenListeners.toArray();
-		for (int i = 0; i < list.length; i++) {
-			SideBarOpenListener l = (SideBarOpenListener) list[i];
-			l.sideBarEntryOpen(this);
+		setTreeItem(null);
+
+		mdi.removeItem(SideBarEntrySWT.this);
+
+		triggerCloseListeners(!SWTThread.getInstance().isTerminated());
+
+		UISWTViewCore iview = getCoreView();
+		if (iview != null) {
+			setCoreView(null);
+		}
+		SWTSkinObject so = getSkinObject();
+		if (so != null) {
+			setSkinObject(null, null);
+			so.getSkin().removeSkinObject(so);
 		}
+
+		// delay saving of removing of auto-open flag.  If after the delay, we are 
+		// still alive, it's assumed the user invoked the close, and we should
+		// remove the auto-open flag
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				// even though execThreadLater will not run on close of app because
+				// the display is disposed, do a double check of tree disposal just
+				// in case.  We don't want to trigger close listeners or
+				// remove autoopen parameters if the user is closing the app (as
+				// opposed to closing  the sidebar)
+				if (tree.isDisposed()) {
+					return;
+				}
+
+				try {
+					COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
+
+					// OSX doesn't select a treeitem after closing an existing one
+					// Force selection
+					if (Constants.isOSX && !tree.isDisposed()
+							&& tree.getSelectionCount() == 0) {
+
+						String parentid = getParentID();
+						if (parentid != null && mdi.getEntry(parentid) != null) {
+							mdi.showEntryByID(parentid);
+						} else {
+							mdi.showEntryByID(SideBar.SIDEBAR_SECTION_LIBRARY);
+						}
+					}
+				} catch (Exception e2) {
+					Debug.out(e2);
+				}
+
+				mdi.setEntryAutoOpen(id, null, false);
+			}
+		});
 	}
 
-	public void addListener(SideBarDropListener l) {
-		if (listDropListeners == Collections.EMPTY_LIST) {
-			listDropListeners = new ArrayList(1);
-		}
-		listDropListeners.add(l);
+	public void setParentSkinObject(SWTSkinObjectContainer soParent) {
+		this.soParent = soParent;
 	}
-	
-	public void removeListener(SideBarDropListener l) {
-		listDropListeners.remove(l);
+
+	public SWTSkinObjectContainer getParentSkinObject() {
+		return soParent;
 	}
-	
-	protected boolean hasDropListeners() {
-		return listDropListeners != null && listDropListeners.size() > 0;
+
+	public void setSelectable(boolean selectable) {
+		this.selectable = selectable;
+		updateColors();
 	}
 
-	/**
-	 * 
-	 * @param o
-	 * @return true: handled; false: not handled
-	 */
-	protected boolean triggerDropListeners(Object o) {
-		boolean handled = false;
-		Object[] list = listDropListeners.toArray();
-		for (int i = 0; i < list.length; i++) {
-			SideBarDropListener l = (SideBarDropListener) list[i];
-			handled = l.sideBarEntryDrop(this, o);
-			if (handled) {
-				break;
+	public boolean isSelectable() {
+		return selectable;
+	}
+
+	public boolean swt_isVisible() {
+		TreeItem parentItem = swtItem.getParentItem();
+		if (parentItem != null) {
+			MdiEntry parentEntry = (MdiEntry) parentItem.getData("MdiEntry");
+			if (!parentEntry.isExpanded()) {
+				return false;
 			}
 		}
-		return handled;
+		return true; // todo: bounds check
 	}
 
-	public String getLogID() {
-		return logID;
+	public void addListener(MdiSWTMenuHackListener l) {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				listMenuHackListners = new ArrayList<MdiSWTMenuHackListener>(1);
+			}
+			if (!listMenuHackListners.contains(l)) {
+				listMenuHackListners.add(l);
+			}
+		}
 	}
 
-	public void setLogID(String logID) {
-		if (logID == null || logID.equals("" + this.logID)) {
-			return;
+	public void removeListener(MdiSWTMenuHackListener l) {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				listMenuHackListners = new ArrayList<MdiSWTMenuHackListener>(1);
+			}
+			listMenuHackListners.remove(l);
 		}
-		String oldID = this.logID;
-		this.logID = logID;
-		triggerLogIDListeners(oldID);
 	}
-
-	public SideBar getSidebar() {
-		return sidebar;
+	
+	public MdiSWTMenuHackListener[] getMenuHackListeners() {
+		synchronized (this) {
+			if (listMenuHackListners == null) {
+				return new MdiSWTMenuHackListener[0];
+			}
+			return listMenuHackListners.toArray(new MdiSWTMenuHackListener[0]);
+		}
 	}
 
-	/**
-	 * @return
-	 */
-	public boolean isInTree() {
-		return treeItem != null && !treeItem.isDisposed();
-	}
+	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateImage#obfusticatedImage(org.eclipse.swt.graphics.Image)
+	public Image obfusticatedImage(Image image) {
+		Rectangle bounds = swt_getBounds();
+		TreeItem treeItem = getTreeItem();
+		Point location = Utils.getLocationRelativeToShell(treeItem.getParent());
 
-	public IconBarEnabler getIconBarEnabler() {
-		return iconBarEnabler;
-	}
+		bounds.x += location.x;
+		bounds.y += location.y;
+		
+		if (getId().startsWith("DMDetails")) {
+			System.out.println("br");
+		}
+		
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("image", image);
+		map.put("obfuscateSideBar", false);
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_OBFUSCATE, map);
+		}
+
+		if (MapUtils.getMapBoolean(map, "obfuscateSideBar", false)) {
+			int ofs = IMAGELEFT_GAP + IMAGELEFT_SIZE;
+			if (treeItem.getParentItem() != null) {
+				ofs += 10 + SIDEBAR_SPACING;
+			}
+			bounds.x += ofs;
+			bounds.width -= ofs + SIDEBAR_SPACING + 1;
+			bounds.height -= 1;
+			
+			UIDebugGenerator.obfusticateArea(image, bounds);
+		}
+		
 
-	public void setIconBarEnabler(IconBarEnabler iconBarEnabler) {
-		this.iconBarEnabler = iconBarEnabler;
+		return image;
 	}
 }
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarListener.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarListener.java
deleted file mode 100644
index 908c6e7..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Created on Jul 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.ui.swt.views.skin.sidebar;
-
-
-/**
- * @author TuxPaper
- * @created Jul 17, 2008
- *
- */
-public interface SideBarListener
-{
-	/**
-	 * @param newSideBarEntry
-	 * @param oldSideBarEntry
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void sidebarItemSelected(SideBarEntrySWT newSideBarEntry,
-			SideBarEntrySWT oldSideBarEntry);
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarLogIdListener.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarLogIdListener.java
deleted file mode 100644
index f39c075..0000000
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarLogIdListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Created on Nov 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.views.skin.sidebar;
-
-/**
- * @author TuxPaper
- * @created Nov 6, 2008
- *
- */
-public interface SideBarLogIdListener
-{
-	void sidebarLogIdChanged(SideBarEntrySWT sideBarEntrySWT, String oldID,
-			String newID);
-}
diff --git a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarToolTips.java b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarToolTips.java
index 85fe146..318ea3e 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarToolTips.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarToolTips.java
@@ -24,11 +24,16 @@ import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.*;
 
+import org.gudy.azureus2.core3.util.Debug;
+
+import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
 
-import org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage;
 
 /**
  * @author TuxPaper
@@ -48,9 +53,9 @@ public class SideBarToolTips
 
 	private final SideBar sidebar;
 
-	private SideBarEntrySWT sidebarEntry;
+	private MdiEntry mdiEntry;
 
-	private Point lastMouseHoverPos;
+	private Point lastRelMouseHoverPos;
 
 	/**
 	 * Initialize
@@ -103,20 +108,24 @@ public class SideBarToolTips
 		if (tree.getItemCount() == 0) {
 			return;
 		}
-		int indent = tree.getItem(0).getBounds().x;
+		int indent = SideBar.END_INDENT ? tree.getClientArea().width - 1 : 0;
 		TreeItem treeItem = tree.getItem(new Point(indent, mousePos.y));
 		if (treeItem == null) {
 			return;
 		}
-		String id = (String) treeItem.getData("Plugin.viewID");
-		sidebarEntry = SideBar.getEntry(id);
+		mdiEntry = (MdiEntry) treeItem.getData("MdiEntry");
+		if (mdiEntry == null) {
+			return;
+		}
 
-		String sToolTip = getToolTip(mousePos);
-		if (sToolTip == null) {
+		Rectangle itemBounds = treeItem.getBounds();
+		Point relPos = new Point(mousePos.x, mousePos.y - itemBounds.y);
+		String sToolTip = getToolTip(relPos);
+		if (sToolTip == null || sToolTip.length() == 0) {
 			return;
 		}
 
-		lastMouseHoverPos = mousePos;
+		lastRelMouseHoverPos = relPos;
 
 		Display d = tree.getDisplay();
 		if (d == null)
@@ -189,10 +198,13 @@ public class SideBarToolTips
 	 *
 	 * @since 3.1.1.1
 	 */
-	private String getToolTip(Point mousePos) {
-		SideBarVitalityImage[] vitalityImages = sidebarEntry.getVitalityImages();
+	private String getToolTip(Point mousePos_RelativeToItem) {
+		MdiEntryVitalityImage[] vitalityImages = mdiEntry.getVitalityImages();
 		for (int i = 0; i < vitalityImages.length; i++) {
 			SideBarVitalityImageSWT vitalityImage = (SideBarVitalityImageSWT) vitalityImages[i];
+			if (vitalityImage == null) {
+				continue;
+			}
 			String indicatorToolTip = vitalityImage.getToolTip();
 			if (indicatorToolTip == null || !vitalityImage.isVisible()) {
 				continue;
@@ -201,13 +213,14 @@ public class SideBarToolTips
 			if (hitArea == null) {
 				continue;
 			}
-			if (hitArea.contains(mousePos)) {
+			if (hitArea.contains(mousePos_RelativeToItem)) {
 				return indicatorToolTip;
 			}
 		}
 
-		if (sidebarEntry.titleInfo != null) {
-			return (String) sidebarEntry.titleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT_TOOLTIP);
+		if (mdiEntry.getViewTitleInfo() != null) {
+			String tt = (String) mdiEntry.getViewTitleInfo().getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT_TOOLTIP);
+			return tt;
 		}
 
 		return null;
@@ -223,10 +236,10 @@ public class SideBarToolTips
 		if (toolTipLabel == null || toolTipLabel.isDisposed()) {
 			return;
 		}
-		if (sidebarEntry == null || sidebarEntry.titleInfo == null) {
+		if (mdiEntry == null || mdiEntry.getViewTitleInfo() == null) {
 			return;
 		}
-		String sToolTip = getToolTip(lastMouseHoverPos);
+		String sToolTip = getToolTip(lastRelMouseHoverPos);
 		if (sToolTip == null) {
 			return;
 		}
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 cfbbc5d..cc6c1de 100644
--- a/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java
+++ b/com/aelitis/azureus/ui/swt/views/skin/sidebar/SideBarVitalityImageSWT.java
@@ -31,23 +31,22 @@ import org.eclipse.swt.widgets.TreeItem;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.Utils;
 
+import com.aelitis.azureus.ui.mdi.*;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
-import org.gudy.azureus2.plugins.ui.sidebar.*;
-
 /**
  * @author TuxPaper
  * @created Sep 15, 2008
  *
  */
 public class SideBarVitalityImageSWT
-	implements SideBarVitalityImage
+	implements MdiEntryVitalityImage
 {
 	private String imageID;
 
-	private final SideBarEntrySWT sideBarEntry;
+	private final MdiEntry mdiEntry;
 
-	private List listeners = Collections.EMPTY_LIST;
+	private List<MdiEntryVitalityImageListener> listeners = Collections.EMPTY_LIST;
 
 	private String tooltip;
 
@@ -64,86 +63,26 @@ public class SideBarVitalityImageSWT
 	private TimerEventPeriodic timerEvent;
 
 	private Image[] images;
-	
+
 	private int delayTime = -1;
 
 	private String fullImageID;
-	
+
 	private int alignment = SWT.RIGHT;
 
-	/**
-	 * @param imageID
-	 */
-	public 
-	SideBarVitalityImageSWT(
-		SideBarEntrySWT entry, 
-		String 			imageID )
-	{
-		performer = 
-			new TimerEventPerformer() 
-			{		
-				private boolean	exec_pending 	= false;
-				private Object	lock			= this;
-				
-				public void 
-				perform(
-					TimerEvent event ) 
-				{
-					synchronized( lock ){
-						
-						if ( exec_pending ){
-					
-							return;
-						}
-						
-						exec_pending = true;
-					}
-					
-					Utils.execSWTThread(
-						new AERunnable() 
-						{
-							public void 
-							runSupport() 
-							{
-								synchronized( lock ){
-									
-									exec_pending = false;
-								}
-								
-								if (images == null || images.length == 0 || !visible
-										|| hitArea == null) {
-									return;
-								}
-								currentAnimationIndex++;
-								if (currentAnimationIndex >= images.length) {
-									currentAnimationIndex = 0;
-								}
-								TreeItem treeItem = sideBarEntry.getTreeItem();
-								if (treeItem == null || treeItem.isDisposed()) {
-									return;
-								}
-								Tree parent = treeItem.getParent();
-								// 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();
-							}
-						});
-				}
-			};
+	public SideBarVitalityImageSWT(final MdiEntry mdiEntry, String imageID) {
+		this.mdiEntry = mdiEntry;
 
-		this.sideBarEntry = entry;
-		
-		entry.addListener(new SideBarCloseListener() {
-		
-			public void sidebarClosed(SideBarEntry entry) {
+		mdiEntry.addListener(new MdiCloseListener() {
+
+			public void mdiEntryClosed(MdiEntry entry, boolean userClosed) {
 				ImageLoader imageLoader = ImageLoader.getInstance();
 				if (fullImageID != null) {
 					imageLoader.releaseImage(fullImageID);
 				}
 			}
 		});
-		
+
 		setImageID(imageID);
 	}
 
@@ -155,24 +94,24 @@ public class SideBarVitalityImageSWT
 	/**
 	 * @return the sideBarEntry
 	 */
-	public SideBarEntry getSideBarEntry() {
-		return sideBarEntry;
+	public MdiEntry getMdiEntry() {
+		return mdiEntry;
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImage#addListener(org.gudy.azureus2.plugins.ui.sidebar.SideBarVitalityImageListener)
-	public void addListener(SideBarVitalityImageListener l) {
+	public void addListener(MdiEntryVitalityImageListener l) {
 		if (listeners == Collections.EMPTY_LIST) {
-			listeners = new ArrayList(1);
+			listeners = new ArrayList<MdiEntryVitalityImageListener>(1);
 		}
 		listeners.add(l);
 	}
-	
+
 	public void triggerClickedListeners(int x, int y) {
 		Object[] list = listeners.toArray();
 		for (int i = 0; i < list.length; i++) {
-			SideBarVitalityImageListener l = (SideBarVitalityImageListener) list[i];
+			MdiEntryVitalityImageListener l = (MdiEntryVitalityImageListener) list[i];
 			try {
-				l.sbVitalityImage_clicked(x, y);
+				l.mdiEntryVitalityImage_clicked(x, y);
 			} catch (Exception e) {
 				Debug.out(e);
 			}
@@ -189,7 +128,7 @@ public class SideBarVitalityImageSWT
 	}
 
 	/**
-	 * @param bounds
+	 * @param bounds relative to entry
 	 *
 	 * @since 3.1.1.1
 	 */
@@ -219,10 +158,12 @@ public class SideBarVitalityImageSWT
 			timerEvent.cancel();
 		}
 
+		//System.out.println("Gonna redraw because of " + mdiEntry.getId() + " set to " + this.visible + " via " + Debug.getCompressedStackTrace() );
+		
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				if (sideBarEntry != null) {
-					sideBarEntry.redraw();
+				if (mdiEntry != null) {
+					mdiEntry.redraw();
 				}
 			}
 		});
@@ -233,17 +174,67 @@ public class SideBarVitalityImageSWT
 	 *
 	 * @since 3.1.1.1
 	 */
-	private void createTimerEvent() {
+	private synchronized void createTimerEvent() {
 		if (timerEvent != null) {
 			timerEvent.cancel();
 		}
-		if (images.length > 1) {
+		if (images != null && images.length > 1) {
 			ImageLoader imageLoader = ImageLoader.getInstance();
 			int delay = delayTime == -1 ? imageLoader.getAnimationDelay(imageID)
 					: delayTime;
-			
-			timerEvent = SimpleTimer.addPeriodicEvent("Animate " + imageID + suffix,
-					delay, performer);
+
+			if (performer == null) {
+				performer = new TimerEventPerformer() {
+					private boolean exec_pending = false;
+
+					private Object lock = this;
+
+					public void perform(TimerEvent event) {
+						synchronized (lock) {
+
+							if (exec_pending) {
+
+								return;
+							}
+
+							exec_pending = true;
+						}
+
+						Utils.execSWTThread(new AERunnable() {
+							public void runSupport() {
+								synchronized (lock) {
+
+									exec_pending = false;
+								}
+
+								if (images == null || images.length == 0 || !visible
+										|| hitArea == null) {
+									return;
+								}
+								currentAnimationIndex++;
+								if (currentAnimationIndex >= images.length) {
+									currentAnimationIndex = 0;
+								}
+								if (mdiEntry instanceof SideBarEntrySWT) {
+									SideBarEntrySWT sbEntry = (SideBarEntrySWT) mdiEntry;
+
+									TreeItem treeItem = sbEntry.getTreeItem();
+									if (treeItem == null || treeItem.isDisposed()
+											|| !sbEntry.swt_isVisible()) {
+										return;
+									}
+									Tree parent = treeItem.getParent();
+									parent.redraw(hitArea.x, hitArea.y + treeItem.getBounds().y,
+											hitArea.width, hitArea.height, true);
+									parent.update();
+								}
+							}
+						});
+					}
+				};
+			}
+			timerEvent = SimpleTimer.addPeriodicEvent("Animate " + mdiEntry.getId()
+					+ "::" + imageID + suffix, delay, performer);
 		}
 	}
 
@@ -271,25 +262,31 @@ public class SideBarVitalityImageSWT
 		setImageID(imageID);
 	}
 
-	public void setImageID(String id) {
-		ImageLoader imageLoader = ImageLoader.getInstance();
-		String newFullImageID = id + suffix;
-		if (newFullImageID.equals(fullImageID)) {
-			return;
-		}
-		if (fullImageID != null) {
-			imageLoader.releaseImage(fullImageID);
-		}
-		this.imageID = id;
-		images = imageLoader.getImages(newFullImageID);
-		if (images == null || images.length == 0) {
-			imageLoader.releaseImage(newFullImageID);
-			newFullImageID = id;
-			images = imageLoader.getImages(id);
-		}
-		fullImageID = newFullImageID;
-		currentAnimationIndex = 0;
-		createTimerEvent();
+	public void setImageID(final String id) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				ImageLoader imageLoader = ImageLoader.getInstance();
+				String newFullImageID = id + suffix;
+				if (newFullImageID.equals(fullImageID)) {
+					return;
+				}
+				if (fullImageID != null) {
+					imageLoader.releaseImage(fullImageID);
+				}
+				imageID = id;
+				images = imageLoader.getImages(newFullImageID);
+				if (images == null || images.length == 0) {
+					imageLoader.releaseImage(newFullImageID);
+					newFullImageID = id;
+					images = imageLoader.getImages(id);
+				}
+				fullImageID = newFullImageID;
+				currentAnimationIndex = 0;
+				if (isVisible()) {
+					createTimerEvent();
+				}
+			}
+		});
 	}
 
 	/**
@@ -313,7 +310,9 @@ public class SideBarVitalityImageSWT
 			return;
 		}
 		this.delayTime = delayTime;
-		createTimerEvent();
+		if (isVisible()) {
+			createTimerEvent();
+		}
 	}
 
 	/**
diff --git a/com/aelitis/azureus/util/Constants.java b/com/aelitis/azureus/util/Constants.java
deleted file mode 100644
index 248c880..0000000
--- a/com/aelitis/azureus/util/Constants.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Created on Aug 30, 2006
- * Created by Alon Rohter
- * 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, SARL au capital de 30,000 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-package com.aelitis.azureus.util;
-
-
-/**
- * @deprecated Only for UMP
- */
-public class Constants
-{
-	/** @deprecated Used by UMP only.. */
-	public static boolean isOSX = org.gudy.azureus2.core3.util.Constants.isOSX;
-
-	/** @deprecated Used by UMP only.. */
-	public static boolean isWindows = org.gudy.azureus2.core3.util.Constants.isWindows;
-}
diff --git a/com/aelitis/azureus/util/ConstantsV3.java b/com/aelitis/azureus/util/ConstantsV3.java
deleted file mode 100644
index bbe1d64..0000000
--- a/com/aelitis/azureus/util/ConstantsV3.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Created on Aug 30, 2006
- * Created by Alon Rohter
- * 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, SARL au capital de 30,000 euros
- * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
- *
- */
-package com.aelitis.azureus.util;
-
-import com.aelitis.azureus.core.cnetwork.ContentNetwork;
-
-/**
- * @deprecated Only for EMP
- */
-public class ConstantsV3
-{
-	/** @deprecated Used by UMP only.. */
-	public static boolean isOSX = org.gudy.azureus2.core3.util.Constants.isOSX;
-
-	/** @deprecated Used by UMP only.. */
-	public static boolean isWindows = org.gudy.azureus2.core3.util.Constants.isWindows;
-
-	/** @deprecated Use {@link ConstantsVuze#DEFAULT_CONTENT_NETWORK_ID} **/
-	public static final ContentNetwork DEFAULT_CONTENT_NETWORK = ConstantsVuze.getDefaultContentNetwork();
-
-	/** @deprecated Used by UMP only.. */
-	public static final String URL_PREFIX = DEFAULT_CONTENT_NETWORK.getServiceURL(ContentNetwork.SERVICE_SITE);
-}
diff --git a/com/aelitis/azureus/util/ContentNetworkUtils.java b/com/aelitis/azureus/util/ContentNetworkUtils.java
index e06b8a1..c90133a 100644
--- a/com/aelitis/azureus/util/ContentNetworkUtils.java
+++ b/com/aelitis/azureus/util/ContentNetworkUtils.java
@@ -18,9 +18,6 @@
 
 package com.aelitis.azureus.util;
 
-import java.net.MalformedURLException;
-import java.net.URL;
-
 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 
@@ -51,16 +48,6 @@ public class ContentNetworkUtils
 		}
 
 	}
-	public static String getUrl(ContentNetwork cn, int serviceID, Object[] params) {
-		try {
-			if (!cn.isServiceSupported(serviceID)) {
-				return null;
-			}
-			return cn.getServiceURL(serviceID, params);
-		} catch (Throwable t) {
-			return null;
-		}
-	}
 
 	public static ContentNetwork getContentNetworkFromTarget(String target) {
 		ContentNetwork cn = null;
@@ -81,41 +68,4 @@ public class ContentNetworkUtils
 				+ (cn == null ? ConstantsVuze.getDefaultContentNetwork().getID()
 						: cn.getID());
 	}
-
-	public static void setSourceRef(String target, String sourceRef,
-			boolean override) {
-		setSourceRef(getContentNetworkFromTarget(target), sourceRef, override);
-	}
-
-	public static void setSourceRef(ContentNetwork cn, String sourceRef,
-			boolean override) {
-		if (cn == ConstantsVuze.getDefaultContentNetwork()) {
-			return;
-		}
-		// always override old source ref if the content network requires
-		// authorization and the user hasn't authorized yet.
-		if (cn.isServiceSupported(ContentNetwork.SERVICE_AUTHORIZE)) {
-			boolean authShown = false; 
-			Object oAuthShown = cn.getPersistentProperty(ContentNetwork.PP_AUTH_PAGE_SHOWN);
-			if (oAuthShown instanceof Boolean) {
-				authShown = ((Boolean) oAuthShown).booleanValue();
-			}
-			if (!authShown) {
-				override = true;
-			}
-		}
-		
-		String old = (String) cn.getPersistentProperty(ContentNetwork.PP_SOURCE_REF);
-		if (old == null || override) {
-			if (sourceRef != null && sourceRef.startsWith("http")) {
-				// trim down
-				try {
-					URL url = new URL(sourceRef);
-					sourceRef = url.getHost() + url.getPath();
-				} catch (MalformedURLException e) {
-				}
-			}
-			cn.setPersistentProperty(ContentNetwork.PP_SOURCE_REF, sourceRef);
-		}
-	}
 }
diff --git a/com/aelitis/azureus/util/DataSourceUtils.java b/com/aelitis/azureus/util/DataSourceUtils.java
index d9a7c92..6f1239f 100644
--- a/com/aelitis/azureus/util/DataSourceUtils.java
+++ b/com/aelitis/azureus/util/DataSourceUtils.java
@@ -24,6 +24,11 @@ import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.HashWrapper;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadException;
+import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
 import com.aelitis.azureus.core.AzureusCoreFactory;
@@ -37,13 +42,6 @@ import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.selectedcontent.DownloadUrlInfo;
 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
 
-import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadException;
-import org.gudy.azureus2.plugins.torrent.Torrent;
-
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-
 /**
  * @author TuxPaper
  * @created Jun 1, 2008
@@ -51,6 +49,39 @@ import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
  */
 public class DataSourceUtils
 {
+	public static org.gudy.azureus2.core3.disk.DiskManagerFileInfo getFileInfo(
+			Object ds) {
+		try {
+			if (ds instanceof DiskManagerFileInfo) {
+				return PluginCoreUtils.unwrap((DiskManagerFileInfo) ds);
+			} else if (ds instanceof org.gudy.azureus2.core3.disk.DiskManagerFileInfo) {
+				return (org.gudy.azureus2.core3.disk.DiskManagerFileInfo) ds;
+			} else if ((ds instanceof ISelectedContent)
+					&& ((ISelectedContent) ds).getFileIndex() >= 0) {
+				ISelectedContent sc = (ISelectedContent) ds;
+				int idx = sc.getFileIndex();
+				DownloadManager dm = sc.getDownloadManager();
+				return dm.getDiskManagerFileInfoSet().getFiles()[idx];
+			} else if (ds instanceof TranscodeJob) {
+				TranscodeJob tj = (TranscodeJob) ds;
+				try {
+					return PluginCoreUtils.unwrap(tj.getFile());
+				} catch (DownloadException e) {
+				}
+			} else if (ds instanceof TranscodeFile) {
+				TranscodeFile tf = (TranscodeFile) ds;
+				try {
+					DiskManagerFileInfo file = tf.getSourceFile();
+					return PluginCoreUtils.unwrap(file);
+				} catch (DownloadException e) {
+				}
+			}
+
+		} catch (Exception e) {
+			Debug.printStackTrace(e);
+		}
+		return null;
+	}
 
 	public static DownloadManager getDM(Object ds) {
 		try {
@@ -202,8 +233,7 @@ public class DataSourceUtils
 		if (torrent != null) {
 			return PlatformTorrentUtils.isContent(torrent, true);
 		}
-		if ((ds instanceof VuzeActivitiesEntry)
-				&& ((VuzeActivitiesEntry) ds).isPlatformContent()) {
+		if (ds instanceof VuzeActivitiesEntry) {
 			return true;
 		}
 
@@ -232,62 +262,6 @@ public class DataSourceUtils
 		return null;
 	}
 
-	public static ContentNetwork getContentNetwork(Object ds) {
-		long id = -1;
-		try {
-			if (ds instanceof DownloadManager) {
-				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 String) && ((String)ds).length() == 32) {
-				// assume 32 byte string is a hash and that it belongs to the def. network
-				id = ConstantsVuze.getDefaultContentNetwork().getID();
-			} else 	if (ds instanceof TranscodeJob) {
-				TranscodeJob tj = (TranscodeJob) ds;
-				try {
-					DiskManagerFileInfo file = tj.getFile();
-					if (file != null) {
-						Download download = tj.getFile().getDownload();
-						if (download != null) {
-							DownloadManager dm = PluginCoreUtils.unwrap(download);
-							return getContentNetwork(dm);
-						}
-					}
-				} catch (DownloadException e) {
-				}
-			} else if (ds instanceof TranscodeFile) {
-				TranscodeFile tf = (TranscodeFile) ds;
-				try {
-					DiskManagerFileInfo file = tf.getSourceFile();
-					if (file != null) {
-						Download download = file.getDownload();
-						if (download != null) {
-							DownloadManager dm = PluginCoreUtils.unwrap(download);
-							return getContentNetwork(dm);
-						}
-					}
-				} 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());
-			}
-		} catch (Exception e) {
-			Debug.printStackTrace(e);
-		}
-		ContentNetwork cn = ContentNetworkManagerFactory.getSingleton().getContentNetwork(
-				id);
-		return cn;
-	}
-	
 	/**
 	 * @param ds
 	 *
diff --git a/com/aelitis/azureus/util/ImportExportUtils.java b/com/aelitis/azureus/util/ImportExportUtils.java
index 7a45058..9344928 100644
--- a/com/aelitis/azureus/util/ImportExportUtils.java
+++ b/com/aelitis/azureus/util/ImportExportUtils.java
@@ -9,6 +9,12 @@ import java.util.Map;
 import org.gudy.azureus2.core3.util.UrlUtils;
 import org.json.simple.JSONArray;
 
+/**
+ * Note: There's a similarly defined map processing utility class called
+ * {@link MapUtils}.  Since there are differences in implementation, both
+ * have been kept until someone goes through each callee and check if it
+ * can be switched to use just one of them.
+ */
 public final class ImportExportUtils {
 	
 	public final static void
diff --git a/com/aelitis/azureus/util/InitialisationFunctions.java b/com/aelitis/azureus/util/InitialisationFunctions.java
index 849a122..6a402f3 100644
--- a/com/aelitis/azureus/util/InitialisationFunctions.java
+++ b/com/aelitis/azureus/util/InitialisationFunctions.java
@@ -23,23 +23,40 @@
 package com.aelitis.azureus.util;
 
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.cnetwork.ContentNetworkManagerFactory;
 import com.aelitis.azureus.core.content.AzureusPlatformContentDirectory;
 import com.aelitis.azureus.core.content.RelatedContentManager;
+import com.aelitis.azureus.core.devices.Device;
+import com.aelitis.azureus.core.devices.DeviceManager;
 import com.aelitis.azureus.core.devices.DeviceManagerFactory;
+import com.aelitis.azureus.core.devices.DeviceMediaRenderer;
 import com.aelitis.azureus.core.download.DownloadManagerEnhancer;
 import com.aelitis.azureus.core.metasearch.MetaSearchManagerFactory;
+import com.aelitis.azureus.core.metasearch.MetaSearchManagerListener;
 import com.aelitis.azureus.core.peer.cache.CacheDiscovery;
 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.core.util.AZ3Functions;
+import com.aelitis.azureus.core.util.AZ3Functions.provider.TranscodeProfile;
+import com.aelitis.azureus.core.util.AZ3Functions.provider.TranscodeTarget;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.swt.shells.RemotePairingWindow;
+import com.aelitis.azureus.ui.swt.shells.main.MainWindow;
 import com.aelitis.azureus.ui.swt.views.skin.TorrentListViewsUtils;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
 import org.gudy.azureus2.core3.download.DownloadManagerStateAttributeListener;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
@@ -77,10 +94,14 @@ public class InitialisationFunctions
 		NavigationHelper.initialise();
 		
 		RelatedContentManager.preInitialise( core );
-		
+
 		AZ3Functions.setProvider(
 			new AZ3Functions.provider()
 			{
+				public String getDefaultContentNetworkURL(int type, Object[] params) {
+					return ConstantsVuze.getDefaultContentNetwork().getServiceURL(type, params);
+				}
+
 				public void 
 				subscribeToRSS(
 					String		name,
@@ -95,38 +116,182 @@ public class InitialisationFunctions
 						SubscriptionManagerFactory.getSingleton().createSingletonRSS(
 						name, url, interval );
 					
+					if ( !subs.getName().equals( name )){
+					
+						subs.setName( name );
+					}
+					
 					if ( subs.isPublic() != is_public ){
 						
 						subs.setPublic( is_public );
 					}
 					
+					if ( !subs.isSubscribed()){
+						
+						subs.setSubscribed( true );
+					}
 					if ( creator_ref != null ){
 						
 						subs.setCreatorRef( creator_ref );
 					}
 				}
 				
-				public boolean 
-				canShowCDP(
-					org.gudy.azureus2.core3.download.DownloadManager dm ) 
+				public void 
+				openRemotePairingWindow() 
 				{
-					return( TorrentListViewsUtils.canViewDetails( dm ));
+					RemotePairingWindow.open();
 				}
 				
-				public void 
-				showCDP(
-					org.gudy.azureus2.core3.download.DownloadManager	dm,
-					String 												ref )
+				public boolean
+				canPlay(
+					org.gudy.azureus2.core3.download.DownloadManager		dm,
+					int														file_index )
 				{
-					TorrentListViewsUtils.viewDetails( dm, ref );
+					return( PlayUtils.canPlayDS(dm, file_index) || PlayUtils.canStreamDS(dm, file_index));
 				}
 				
-				public String 
-				getCDPURL(
-					org.gudy.azureus2.core3.download.DownloadManager 	dm ) 
+				public void
+				play(
+					org.gudy.azureus2.core3.download.DownloadManager		dm,
+					int														file_index )
 				{
-					return( TorrentListViewsUtils.getDetailsURL( dm ));
+					Object ds = dm;
+					if (file_index >= 0) {
+						DiskManagerFileInfo[] files = dm.getDiskManagerFileInfoSet().getFiles();
+						if (file_index < files.length) {
+							ds = files[file_index];
+						}
+					}
+					
+					if ( PlayUtils.canPlayDS(dm, file_index)){
+						TorrentListViewsUtils.playOrStreamDataSource(ds,
+								DLReferals.DL_REFERAL_PLAYDM, false, true);
+					}
+					if ( PlayUtils.canStreamDS(dm, file_index)){
+						TorrentListViewsUtils.playOrStreamDataSource(ds,
+								DLReferals.DL_REFERAL_PLAYDM, true, false);
+					}
+				}	
+				
+				public TranscodeTarget[]
+           		getTranscodeTargets()
+				{
+					List<TranscodeTarget> result = new ArrayList<TranscodeTarget>();
+					
+					if ( !COConfigurationManager.getStringParameter("ui").equals("az2")){
+
+						try{
+							DeviceManager dm = DeviceManagerFactory.getSingleton();
+						
+							Device[] devices = dm.getDevices();
+							
+							for ( final Device d: devices ){
+								
+								if ( d instanceof DeviceMediaRenderer ){
+									
+									final DeviceMediaRenderer dmr = (DeviceMediaRenderer)d;							
+	
+									boolean	hide_device = d.isHidden();
+									
+									if ( COConfigurationManager.getBooleanParameter( "device.sidebar.ui.rend.hidegeneric", true ) ){
+																			
+										if ( dmr.isNonSimple()){
+											
+											hide_device = true;
+										}
+									}
+									
+									if ( hide_device ){
+										
+										continue;
+									}
+									
+									result.add( 
+										new TranscodeTarget()
+										{
+											public String
+											getName()
+											{
+												return( d.getName());
+											}
+											
+											public TranscodeProfile[]
+											getProfiles()
+											{		
+												List<TranscodeProfile>	ps = new ArrayList<TranscodeProfile>(); 
+	
+												com.aelitis.azureus.core.devices.TranscodeProfile[] profs = dmr.getTranscodeProfiles();	
+												
+												if ( profs.length == 0 ){
+													
+													if ( dmr.getTranscodeRequirement() == com.aelitis.azureus.core.devices.TranscodeTarget.TRANSCODE_NEVER ){
+														
+														ps.add(
+																new TranscodeProfile()
+																{
+																	public String
+																	getUID()
+																	{
+																		return( dmr.getID() + "/" + dmr.getBlankProfile().getName());
+																	}
+																	
+																	public String
+																	getName()
+																	{
+																		return( MessageText.getString( "devices.profile.direct" ));
+																	}
+																});												}
+												}else{
+												
+													for ( final com.aelitis.azureus.core.devices.TranscodeProfile prof: profs ){
+											
+														ps.add(
+															new TranscodeProfile()
+															{
+																public String
+																getUID()
+																{
+																	return( prof.getUID());
+																}
+																
+																public String
+																getName()
+																{
+																	return( prof.getName());
+																}
+															});
+													}
+												}
+												
+												return( ps.toArray( new TranscodeProfile[ ps.size()]));
+											}
+										});					
+								}
+							}
+							
+						}catch( Throwable e ){
+							
+							Debug.out( e );
+						}
+					}
+					
+					Collections.sort(
+						result,
+						new Comparator<TranscodeTarget>()
+						{
+							public int 
+							compare(
+								TranscodeTarget o1,
+								TranscodeTarget o2)
+							{
+								return( o1.getName().compareTo( o2.getName()));
+							}
+						});
+					
+					return( result.toArray( new TranscodeTarget[result.size()]));
 				}
+				               		
+
 			});
 	}
 
@@ -153,6 +318,22 @@ public class InitialisationFunctions
 						
 						Debug.out( e );
 					}
+					
+					try{
+						MetaSearchManagerFactory.getSingleton().addListener(
+							new MetaSearchManagerListener()
+							{
+								public void
+								searchRequest(
+									String		term )
+								{
+									UIFunctionsManager.getUIFunctions().doSearch( term );
+								}
+							});
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
 				}
 			}).queue();
 	}
diff --git a/com/aelitis/azureus/util/PlayUtils.java b/com/aelitis/azureus/util/PlayUtils.java
index 1dea0bb..a60ab22 100644
--- a/com/aelitis/azureus/util/PlayUtils.java
+++ b/com/aelitis/azureus/util/PlayUtils.java
@@ -21,6 +21,7 @@ package com.aelitis.azureus.util;
 import java.io.File;
 import java.lang.reflect.Method;
 import java.net.MalformedURLException;
+import java.net.URL;
 
 import org.eclipse.swt.program.Program;
 
@@ -31,21 +32,26 @@ 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.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadException;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
 
 import com.aelitis.azureus.activities.VuzeActivitiesEntry;
 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.download.StreamManager;
 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentV3;
 
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadException;
-
 /**
  * @author TuxPaper
  * @created Jun 1, 2008
@@ -53,12 +59,28 @@ import org.gudy.azureus2.plugins.download.DownloadException;
  */
 public class PlayUtils
 {
+	public static final boolean COMPLETE_PLAY_ONLY = true;
+	
+	public static final int fileSizeThreshold = 90;
+	
+		/**
+		 * Access to this static is deprecated - use get/setPlayableFileExtensions. For legacy EMP we need
+		 * to keep it public for the moment...
+		 */
+	
+	public static final String playableFileExtensions 	= ".avi .flv .flc .mp4 .divx .h264 .mkv .mov .mp2 .m4v .mp3 .aac, .mts, .m2ts";
+	
+	private static volatile String actualPlayableFileExtensions = playableFileExtensions;
+	
 	
 	private static boolean triedLoadingEmpPluginClass = false;
 
 	private static Method methodIsExternallyPlayable;
+	private static Method methodIsExternallyPlayable2;
 
 	private static PluginInterface piEmp;
+
+	private static Boolean hasQuickTime;
 	
 	//private static Method methodIsExternalPlayerInstalled;
 
@@ -106,28 +128,36 @@ public class PlayUtils
 		return true;
 	}
 
-	public static boolean canUseEMP(TOTorrent torrent) {
-		if (canPlayViaExternalEMP(torrent)) {
-			return true;
-		}
+	public static boolean canUseEMP(DiskManagerFileInfo file ){
+		return( isExternallyPlayable( file ));
+	}
+	
+	public static boolean canUseEMP(TOTorrent torrent, int file_index) {
 		
-		if (!PlatformTorrentUtils.useEMP(torrent)
-				|| !PlatformTorrentUtils.embeddedPlayerAvail()) {
+		return( canUseEMP( torrent, file_index, COMPLETE_PLAY_ONLY ));
+	}
+	
+	public static boolean canUseEMP(TOTorrent torrent, int file_index, boolean complete_only ) {
+		if (torrent == null) { 
 			return false;
 		}
-	
-		return canProgressiveOrIsComplete(torrent);
+
+		if (canPlayViaExternalEMP(torrent, file_index, complete_only)) {
+			return true;
+		}
+		
+		return false;
 	}
 
-	private static boolean canPlay(DownloadManager dm) {
+	private static boolean canPlay(DownloadManager dm, int file_index) {
 		if (dm == null) {
 			return false;
 		}
 		TOTorrent torrent = dm.getTorrent();
-		return canUseEMP(torrent);
+		return canUseEMP(torrent,file_index);
 	}
 
-	private static boolean canPlay(TOTorrent torrent) {
+	private static boolean canPlay(TOTorrent torrent, int file_index) {
 		if (!PlatformTorrentUtils.isContent(torrent, false)) {
 			return false;
 		}
@@ -141,24 +171,34 @@ public class PlayUtils
 	
 	
 		if (dm != null) {
-			return dm.getAssumedComplete() || canUseEMP(torrent);
+			return dm.getAssumedComplete() || canUseEMP(torrent, file_index);
 		}
-		return canUseEMP(torrent);
+		return canUseEMP(torrent, file_index);
 	}
 
-	public static boolean canPlayDS(Object ds) {
+	public static boolean canPlayDS(Object ds, int file_index ) {
+		
+		if ( !( Constants.isWindows || Constants.isOSX )){
+			
+			return( false );
+		}
+		
 		if (ds == null) {
 			return false;
 		}
 		
+		if (ds instanceof org.gudy.azureus2.core3.disk.DiskManagerFileInfo) {
+			org.gudy.azureus2.core3.disk.DiskManagerFileInfo fi = (org.gudy.azureus2.core3.disk.DiskManagerFileInfo) ds;
+			return canPlayDS(fi.getDownloadManager(), fi.getIndex());
+		}
 	
 		DownloadManager dm = DataSourceUtils.getDM(ds);
 		if (dm != null) {
-			return canPlay(dm);
+			return canPlay(dm, file_index);
 		}
 		TOTorrent torrent = DataSourceUtils.getTorrent(ds);
 		if (torrent != null) {
-			return canPlay(torrent);
+			return canPlay(torrent, file_index);
 		}
 		if (ds instanceof VuzeActivitiesEntry) {
 			return ((VuzeActivitiesEntry) ds).isPlayable();
@@ -171,6 +211,91 @@ public class PlayUtils
 		
 		return false;
 	}
+	
+		// stream stuff
+	
+	public static boolean
+	isStreamPermitted()
+	{
+		FeatureManager fm = PluginInitializer.getDefaultInterface().getUtilities().getFeatureManager();
+
+		return( fm.isFeatureInstalled( "core" ));
+	}
+	
+	private static boolean 
+	canStream(
+		DownloadManager 	dm, 
+		int 				file_index ) 
+	{
+		if ( dm == null ){
+			
+			return( false );
+		}
+		
+		org.gudy.azureus2.core3.disk.DiskManagerFileInfo	file;
+		
+		if ( file_index == -1 ){
+			
+			file = dm.getDownloadState().getPrimaryFile();
+			if (file == null) {
+				org.gudy.azureus2.core3.disk.DiskManagerFileInfo[] files = dm.getDiskManagerFileInfoSet().getFiles();
+				if (files.length == 0) {
+					return false;
+				}
+				file = files[0];
+			}
+			
+			file_index = file.getIndex();
+			
+		}else{
+			
+			file = dm.getDiskManagerFileInfoSet().getFiles()[ file_index ];
+		}
+		
+		if ( file.getDownloaded() == file.getLength()){
+			
+			return( false );
+		}
+		
+		if ( !StreamManager.getSingleton().isStreamingUsable()){
+			
+			return( false );
+		}
+		
+		TOTorrent torrent = dm.getTorrent();
+				
+		return( canUseEMP( torrent, file_index, false ));
+	}
+		
+	public static boolean 
+	canStreamDS(
+		Object ds, 
+		int file_index ) 
+	{
+		if ( !( Constants.isWindows || Constants.isOSX )){
+			
+			return( false );
+		}
+		
+		if ( ds == null ){
+			
+			return( false );
+		}
+
+		if (ds instanceof org.gudy.azureus2.core3.disk.DiskManagerFileInfo) {
+			org.gudy.azureus2.core3.disk.DiskManagerFileInfo fi = (org.gudy.azureus2.core3.disk.DiskManagerFileInfo) ds;
+			return canStreamDS(fi.getDownloadManager(), fi.getIndex());
+		}
+
+		DownloadManager dm = DataSourceUtils.getDM(ds);
+		
+		if ( dm != null ){
+			
+			return( canStream( dm, file_index ));
+		}
+		
+		return( false );
+	}
 
 	/**
 	 * @param dmContent
@@ -182,14 +307,11 @@ public class PlayUtils
 		String contentPath;
 		if (dmContent.isDownloadComplete(false)) {
 			//use the file path if download is complete.
-			EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload(
-					dmContent);
-			File file;
-			if (edm != null) {
-				file = edm.getPrimaryFile().getFile(true);
-			} else {
-				file = new File(dmContent.getDownloadState().getPrimaryFile());
+			org.gudy.azureus2.core3.disk.DiskManagerFileInfo primaryFile = dmContent.getDownloadState().getPrimaryFile();
+			if (primaryFile == null) {
+				return null;
 			}
+			File file = primaryFile.getFile(true);
 			try {
 				contentPath = file.toURL().toString();
 			} catch (MalformedURLException e) {
@@ -255,6 +377,48 @@ public class PlayUtils
 		return null;
 	}
 	
+	public static URL getMediaServerContentURL(DiskManagerFileInfo file) {
+		
+		//TorrentListViewsUtils.debugDCAD("enter - getMediaServerContentURL");
+	
+		PluginManager pm = AzureusCoreFactory.getSingleton().getPluginManager();
+		PluginInterface pi = pm.getPluginInterfaceByID("azupnpav", false);
+	
+		if (pi == null) {
+			Logger.log(new LogEvent(LogIDs.UI3, "Media server plugin not found"));
+			return null;
+		}
+	
+		if (!pi.getPluginState().isOperational()) {
+			Logger.log(new LogEvent(LogIDs.UI3, "Media server plugin not operational"));
+			return null;
+		}
+	
+		try {
+			if (hasQuickTime == null) {
+				Program program = Program.findProgram(".qtl");
+				hasQuickTime = program == null ? false
+						: (program.getName().toLowerCase().indexOf("quicktime") != -1);
+			}
+	
+			pi.getIPC().invoke("setQuickTimeAvailable", new Object[] {
+				hasQuickTime
+			});
+	
+			Object url = pi.getIPC().invoke("getContentURL", new Object[] {
+					file
+			});
+			if (url instanceof String) {
+				return new URL( (String) url);
+			}
+		} catch (Throwable e) {
+			Logger.log(new LogEvent(LogIDs.UI3, LogEvent.LT_WARNING,
+					"IPC to media server plugin failed", e));
+		}
+	
+		return null;
+	}
+	
 	/*
 	private static final boolean isExternalEMPInstalled() {
 		if(!loadEmpPluginClass()) {
@@ -289,6 +453,7 @@ public class PlayUtils
 			piEmp = null;
 			triedLoadingEmpPluginClass = false;
 			methodIsExternallyPlayable = null;
+			methodIsExternallyPlayable2 = null;
 		}
 
 		if (!triedLoadingEmpPluginClass) {
@@ -305,10 +470,18 @@ public class PlayUtils
   
   			Class empPluginClass = piEmp.getPlugin().getClass();
 
-  			methodIsExternallyPlayable = empPluginClass.getMethod("isExternallyPlayabale", new Class[] {
+  			methodIsExternallyPlayable = empPluginClass.getMethod("isExternallyPlayable", new Class[] {
   				TOTorrent.class
   			});
   			
+  			try{
+  				methodIsExternallyPlayable2 = empPluginClass.getMethod("isExternallyPlayable", new Class[] {
+  						TOTorrent.class, int.class
+ 	  				});
+  			}catch( Throwable e ){
+  				Logger.log(new LogEvent(LogIDs.UI3, "isExternallyPlayable with file_index not found"));
+  			}
+ 			
   			//methodIsExternalPlayerInstalled = empPluginClass.getMethod("isExternalPlayerInstalled", new Class[] {});
   			
   		} catch (Exception e1) {
@@ -317,19 +490,189 @@ public class PlayUtils
 		}
 		return true;
 	}
+/*	
+	public static File getPrimaryFile(Download d) {
+		DiskManagerFileInfo info = getPrimaryFileInfo(d);
+
+		if ( info == null ){
+			return( null );
+		}else{
+			return( info.getFile( true ));
+		}
+	}
 	
-	private static final boolean canPlayViaExternalEMP(TOTorrent torrent) {
-		if(!loadEmpPluginClass()) {
-			return false;
+	public static int getPrimaryFileIndex(DownloadManager dm ){
+		return( getPrimaryFileIndex( PluginCoreUtils.wrap( dm )));
+	}
+	
+	public static int getPrimaryFileIndex(Download d) {
+		DiskManagerFileInfo info = getPrimaryFileInfo(d);
+		
+		if ( info == null ){
+			return( -1 );
+		}else{
+			return( info.getIndex());
+		}
+	}
+	
+	public static DiskManagerFileInfo getPrimaryFileInfo(Download d) {
+		long size = d.getTorrent().getSize();
+		DiskManagerFileInfo[] infos = d.getDiskManagerFileInfo();
+		for(int i = 0; i < infos.length ; i++) {
+			DiskManagerFileInfo info = infos[i];
+			if ( info.isSkipped() || info.isDeleted()){
+				continue;
+			}
+			if( info.getLength() > (long)fileSizeThreshold * size / 100l) {
+				return info;
+			}
+		}
+		return null;
+	}
+*/	
+	public static boolean isExternallyPlayable(Download d, int file_index, boolean complete_only ) {
+		
+		int primary_file_index = -1;
+
+		if ( file_index == -1 ){
+			
+
+			DownloadManager dm = PluginCoreUtils.unwrap(d);
+			
+			if ( dm == null ) {
+				
+				return( false );
+			}
+			
+			DiskManagerFileInfo file = null;
+			try {
+				file = PluginCoreUtils.wrap(dm.getDownloadState().getPrimaryFile());
+			} catch (DownloadException e) {
+				return false;
+			}
+			
+			if ( file == null ){
+				
+				return( false );
+			}
+						
+			if ( file.getDownloaded() != file.getLength()) {
+				
+				if ( complete_only || getMediaServerContentURL( file ) == null ){
+					
+					return( false );
+				}
+			}
+			
+			primary_file_index = file.getIndex();
+
+		}else{
+			
+			DiskManagerFileInfo file = d.getDiskManagerFileInfo( file_index );
+			
+			if ( file.getDownloaded() != file.getLength()) {
+				
+				if ( complete_only || getMediaServerContentURL( file ) == null ){
+					
+					return( false );
+				}
+			}
+			
+			primary_file_index = file_index;
 		}
 
-		if (methodIsExternallyPlayable == null) {
+		if ( primary_file_index == -1 ){
+			
 			return false;
 		}
 		
+		return( isExternallyPlayable( d.getDiskManagerFileInfo()[primary_file_index] ));
+	}
+	
+	public static String
+	getPlayableFileExtensions()
+	{
+		return( actualPlayableFileExtensions );
+	}
+	
+		/**
+		 * This method available for player plugins to extend playable set if needed
+		 * @param str
+		 */
+	
+	public static void
+	setPlayableFileExtensions(
+		String	str )
+	{
+		actualPlayableFileExtensions = str;
+	}
+	
+	private static boolean
+	isExternallyPlayable(
+		DiskManagerFileInfo	file )
+	{		
+		String	name = file.getFile( true ).getName();
+		
+		int extIndex = name.lastIndexOf(".");
+		
+		if ( extIndex > -1 ){
+			
+			String ext = name.substring(extIndex);
+			
+			if ( ext == null ){
+				
+				return false;
+			}
+			
+			ext = ext.toLowerCase();
+			
+			if ( getPlayableFileExtensions().indexOf(ext) > -1 ){
+				
+				return true;
+			}
+		}
+		
+		return false;
+	}
+	
+	public static boolean isExternallyPlayable(TOTorrent torrent, int file_index, boolean complete_only ) {
+		if (torrent == null) {
+			return false;
+		}
+		try {
+			Download download = AzureusCoreFactory.getSingleton().getPluginManager().getDefaultPluginInterface().getDownloadManager().getDownload(torrent.getHash());
+			if (download != null) {
+				return isExternallyPlayable(download, file_index, complete_only);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		return false;
+	}
+	
+	private static final boolean canPlayViaExternalEMP(TOTorrent torrent, int file_index, boolean complete_only ) {
+		if (torrent == null) {
+			return false;
+		}
+		if(!loadEmpPluginClass() || methodIsExternallyPlayable == null) {
+			return isExternallyPlayable(torrent, file_index, complete_only );
+		}
+		
 		//Data is passed to the openWindow via download manager.
 		try {
 
+			if ( file_index != -1 && methodIsExternallyPlayable2 != null ){
+				
+				try{
+					Object retObj = methodIsExternallyPlayable2.invoke(null, new Object[] {
+							torrent, file_index
+						});
+				}catch( Throwable e ){
+					Logger.log(new LogEvent(LogIDs.UI3, "isExternallyPlayable with file_index failed", e ));
+				}
+			}
+			
 			Object retObj = methodIsExternallyPlayable.invoke(null, new Object[] {
 				torrent
 			});
@@ -347,4 +690,18 @@ public class PlayUtils
 
 		return false;
 	}
+
+	/**
+	 * @deprecated
+	 */
+	public static int getPrimaryFileIndex(Download dl) {
+		EnhancedDownloadManager edm = DownloadManagerEnhancer.getSingleton().getEnhancedDownload( PluginCoreUtils.unwrap(dl) );
+		
+		if ( edm == null ) {
+			
+			return -1;
+		}
+
+		return edm.getPrimaryFileIndex();
+	}
 }
diff --git a/com/aelitis/azureus/util/UrlFilter.java b/com/aelitis/azureus/util/UrlFilter.java
index 7c1142a..9bbc282 100644
--- a/com/aelitis/azureus/util/UrlFilter.java
+++ b/com/aelitis/azureus/util/UrlFilter.java
@@ -61,6 +61,10 @@ public class UrlFilter
 
 	public UrlFilter() {
 		listUrlWhitelist.add(DEFAULT_RPC_WHITELIST);
+		listUrlWhitelist.add("https?://[^/]*\\.vuze\\.com:?[0-9]*/.*");
+		// for +1 button
+		listUrlWhitelist.add("https?://plusone\\.google\\.com/.*");
+		listUrlWhitelist.add("https?://clients[0-9]\\.google\\.com/.*");
 
 		ContentNetworkManager cmn = ContentNetworkManagerFactory.getSingleton();
 		ContentNetwork[] contentNetworks = cmn.getContentNetworks();
diff --git a/com/aelitis/azureus/util/win32/Win32Utils.java b/com/aelitis/azureus/util/win32/Win32Utils.java
deleted file mode 100644
index 9199ce6..0000000
--- a/com/aelitis/azureus/util/win32/Win32Utils.java
+++ /dev/null
@@ -1,49 +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.util.win32;
-
-import org.gudy.azureus2.platform.win32.access.AEWin32Access;
-import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
-
-/**
- * @author TuxPaper
- * @created Feb 13, 2007
- *
- */
-public class Win32Utils
-{
-	/**
-	 * Get the location of Windows Media Player executable
-	 * @return
-	 */
-	public static String getWMP() {
-		AEWin32Access accessor = AEWin32Manager.getAccessor(true);
-		if (accessor == null) {
-			return null;
-		}
-		try {
-			return accessor.readStringValue(AEWin32Access.HKEY_LOCAL_MACHINE,
-					"SOFTWARE\\Microsoft\\Multimedia\\WMPlayer", "Player.Path");
-		} catch (Exception e) {
-		}
-		return null;
-	}
-}
diff --git a/com/aelitis/net/magneturi/MagnetURIHandlerProgressListener.java b/com/aelitis/net/magneturi/MagnetURIHandlerProgressListener.java
index d99985f..cc7d988 100644
--- a/com/aelitis/net/magneturi/MagnetURIHandlerProgressListener.java
+++ b/com/aelitis/net/magneturi/MagnetURIHandlerProgressListener.java
@@ -42,6 +42,9 @@ MagnetURIHandlerProgressListener
 	reportCompleteness(
 		int		percent );
 	
+	public boolean
+	cancelled();
+	
 	public boolean 
 	verbose();
 }
diff --git a/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java b/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
index cc86818..dc40c3a 100644
--- a/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
+++ b/com/aelitis/net/magneturi/impl/MagnetURIHandlerImpl.java
@@ -345,9 +345,17 @@ MagnetURIHandlerImpl
 			
 			arg_str = get.substring( pos+1 );
 			
+			pos = arg_str.lastIndexOf( ' ' );
+			
+			if ( pos >= 0 ){
+				
+				arg_str = arg_str.substring( 0, pos ).trim();
+			}
+			
 			StringTokenizer	tok = new StringTokenizer( arg_str, "&" );
+			
 			if (DEBUG) {
-				System.out.println("params:" + get.substring( pos+1 ));
+				System.out.println("params:" + arg_str );
 			}
 			
 			while( tok.hasMoreTokens()){
@@ -605,53 +613,93 @@ MagnetURIHandlerImpl
 				
 				final boolean verbose = verbose_str != null && verbose_str.equalsIgnoreCase( "true" );
 				
-				for (int i=0;i<listeners.size();i++){
+				final boolean[]	cancel = { false };
 				
-					data = ((MagnetURIHandlerListener)listeners.get(i)).download(
-							new MagnetURIHandlerProgressListener()
+				TimerEventPeriodic	keep_alive = 
+					SimpleTimer.addPeriodicEvent(
+						"MURI:keepalive",
+						5000,
+						new TimerEventPerformer()
+						{
+							public void 
+							perform(
+								TimerEvent event) 
 							{
-								public void
-								reportSize(
-									long	size )
-								{
-									pw.print( "X-Report: " + getMessageText( "torrent_size", String.valueOf( size )) + NL );
-									
-									pw.flush();
-								}
+								pw.print( "X-KeepAlive: YEAH!" + NL );
 								
-								public void
-								reportActivity(
-									String	str )
-								{
-									pw.print( "X-Report: " + str + NL );
-																			
-									pw.flush();
-								}
+								boolean	failed = pw.checkError();
 								
-								public void
-								reportCompleteness(
-									int		percent )
-								{
-									pw.print( "X-Report: " + getMessageText( "percent", String.valueOf(percent)) + NL );
+								if ( failed ){
 									
-									pw.flush();
-								}
-								
-								public boolean 
-								verbose()
-								{
-									return( verbose );
+									synchronized( cancel ){
+									
+										cancel[0]	= true;
+									}
 								}
-							},
-							sha1, 
-							arg_str,
-							s,
-							DOWNLOAD_TIMEOUT );
+							}
+						});
+				
+				try{
+					for (int i=0;i<listeners.size();i++){
 					
-					if ( data != null ){
+						data = ((MagnetURIHandlerListener)listeners.get(i)).download(
+								new MagnetURIHandlerProgressListener()
+								{
+									public void
+									reportSize(
+										long	size )
+									{
+										pw.print( "X-Report: " + getMessageText( "torrent_size", String.valueOf( size )) + NL );
+										
+										pw.flush();
+									}
+									
+									public void
+									reportActivity(
+										String	str )
+									{
+										pw.print( "X-Report: " + str + NL );
+																				
+										pw.flush();
+									}
+									
+									public void
+									reportCompleteness(
+										int		percent )
+									{
+										pw.print( "X-Report: " + getMessageText( "percent", String.valueOf(percent)) + NL );
+										
+										pw.flush();
+									}
+									
+									public boolean 
+									verbose()
+									{
+										return( verbose );
+									}
+									
+									public boolean
+									cancelled()
+									{
+										synchronized( cancel ){
+											
+											return( cancel[0] );
+										}
+									}
+								},
+								sha1, 
+								arg_str,
+								s,
+								DOWNLOAD_TIMEOUT );
 						
-						break;
+						if ( data != null ){
+							
+							break;
+						}
 					}
+				}finally{
+					
+					keep_alive.cancel();
 				}
 				
 				if (Logger.isEnabled())
diff --git a/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java b/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
index 03d8b08..a3009c1 100644
--- a/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
+++ b/com/aelitis/net/natpmp/upnp/impl/NatPMPUPnPRootDeviceImpl.java
@@ -31,14 +31,7 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.ThreadPool;
 
 import com.aelitis.net.natpmp.NatPMPDevice;
-import com.aelitis.net.upnp.UPnP;
-import com.aelitis.net.upnp.UPnPAction;
-import com.aelitis.net.upnp.UPnPDevice;
-import com.aelitis.net.upnp.UPnPException;
-import com.aelitis.net.upnp.UPnPRootDevice;
-import com.aelitis.net.upnp.UPnPRootDeviceListener;
-import com.aelitis.net.upnp.UPnPService;
-import com.aelitis.net.upnp.UPnPStateVariable;
+import com.aelitis.net.upnp.*;
 import com.aelitis.net.upnp.services.UPnPSpecificService;
 import com.aelitis.net.upnp.services.UPnPWANConnection;
 import com.aelitis.net.upnp.services.UPnPWANConnectionListener;
@@ -219,6 +212,10 @@ NatPMPUPnPRootDeviceImpl
 		{
 			return( NatPMPUPnPRootDeviceImpl.this );
 		}
+
+		public UPnPDeviceImage[] getImages() {
+			return new UPnPDeviceImage[0];
+		}
 	}
 	
 	protected class
@@ -263,6 +260,12 @@ NatPMPUPnPRootDeviceImpl
 			return( null );
 		}
 		
+		public boolean 
+		isConnectable() 
+		{
+			return( true );
+		}
+		
 		public UPnPAction[]
 		getActions()
 		
diff --git a/com/aelitis/net/udp/mc/MCGroup.java b/com/aelitis/net/udp/mc/MCGroup.java
index b1f8a8d..6306e5c 100644
--- a/com/aelitis/net/udp/mc/MCGroup.java
+++ b/com/aelitis/net/udp/mc/MCGroup.java
@@ -32,22 +32,17 @@ MCGroup
 	
 	public void
 	sendToGroup(
-		byte[]	data )
-	
-		throws MCGroupException;
+		byte[]	data );
 	
 		/**
 		 * Sends to the group but will replace any occurrence of %AZINTERFACE% in the string with the
 		 * interface being used for the send
 		 * @param param_data
-		 * @throws MCGroupException
 		 */
 	
 	public void
 	sendToGroup(
-		String	param_data )
-	
-		throws MCGroupException;
+		String	param_data );
 	
 	public void
 	sendToMember(
diff --git a/com/aelitis/net/udp/mc/impl/MCGroupImpl.java b/com/aelitis/net/udp/mc/impl/MCGroupImpl.java
index d0edbb6..d6d67a2 100644
--- a/com/aelitis/net/udp/mc/impl/MCGroupImpl.java
+++ b/com/aelitis/net/udp/mc/impl/MCGroupImpl.java
@@ -27,12 +27,15 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AEThread;
 import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
 import org.gudy.azureus2.core3.util.SimpleTimer;
 import org.gudy.azureus2.core3.util.TimerEvent;
 import org.gudy.azureus2.core3.util.TimerEventPerformer;
 
+import com.aelitis.azureus.core.util.NetUtils;
 import com.aelitis.net.udp.mc.MCGroup;
 import com.aelitis.net.udp.mc.MCGroupAdapter;
 import com.aelitis.net.udp.mc.MCGroupException;
@@ -52,7 +55,8 @@ MCGroupImpl
 	private final static int		PACKET_SIZE		= 8192;
 			
 
-	private static Map			singletons	= new HashMap();
+	private static Map<String,MCGroupImpl>			singletons	= new HashMap<String, MCGroupImpl>();
+	
 	private static AEMonitor	class_mon 	= new AEMonitor( "MCGroup:class" );
 
 	public static MCGroupImpl
@@ -132,7 +136,10 @@ MCGroupImpl
 			
 	protected AEMonitor		this_mon	= new AEMonitor( "MCGroup" );
 
-	private Map	current_registrations = new HashMap();
+	private Map<NetworkInterface,Set<InetAddress>>		current_registrations = new HashMap<NetworkInterface, Set<InetAddress>>();
+	
+	private AsyncDispatcher		async_dispatcher = new AsyncDispatcher();
+	
 	
 	public
 	MCGroupImpl(
@@ -187,19 +194,17 @@ MCGroupImpl
 	
 		throws SocketException
 	{
-		Map			new_registrations	= new HashMap();
+		Map<NetworkInterface,Set<InetAddress>>			new_registrations	= new HashMap<NetworkInterface,Set<InetAddress>>();
 		
-		List		changed_interfaces	= new ArrayList();
+		List<NetworkInterface>		changed_interfaces	= new ArrayList<NetworkInterface>();
 		
 		try{
 			this_mon.enter();
 			
-			Enumeration network_interfaces = NetworkInterface.getNetworkInterfaces();
+			List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
 			
-			while (network_interfaces.hasMoreElements()){
-				
-				final NetworkInterface network_interface = (NetworkInterface)network_interfaces.nextElement();
-	
+			for ( final NetworkInterface network_interface: x ){
+					
 				if ( !interfaceSelected( network_interface )){
 					
 					if ( start_of_day ){
@@ -210,22 +215,22 @@ MCGroupImpl
 					continue;
 				}
 				
-				Set old_address_set = (Set)current_registrations.get( network_interface );
+				Set<InetAddress> old_address_set = current_registrations.get( network_interface );
 					
 				if ( old_address_set == null ){
 				
-					old_address_set	= new HashSet();
+					old_address_set	= new HashSet<InetAddress>();
 				}
 				
-				Set	new_address_set = new HashSet();
+				Set<InetAddress>	new_address_set = new HashSet<InetAddress>();
 				
 				new_registrations.put( network_interface, new_address_set );
 				
-				Enumeration ni_addresses = network_interface.getInetAddresses();
+				Enumeration<InetAddress> ni_addresses = network_interface.getInetAddresses();
 				
-				while (ni_addresses.hasMoreElements()){
+				while( ni_addresses.hasMoreElements()){
 					
-					final InetAddress ni_address = (InetAddress)ni_addresses.nextElement();
+					final InetAddress ni_address = ni_addresses.nextElement();
 	
 					new_address_set.add( ni_address );
 
@@ -290,11 +295,11 @@ MCGroupImpl
 						
 						String	addresses_string = "";
 							
-						Enumeration it = network_interface.getInetAddresses();
+						Enumeration<InetAddress> it = network_interface.getInetAddresses();
 						
 						while (it.hasMoreElements()){
 							
-							InetAddress addr = (InetAddress)it.nextElement();
+							InetAddress addr = it.nextElement();
 							
 							addresses_string += (addresses_string.length()==0?"":",") + addr;
 						}
@@ -424,7 +429,7 @@ MCGroupImpl
 		try{
 			this_mon.enter();
 		
-			Set	set = (Set)current_registrations.get( network_interface );
+			Set<InetAddress>	set = (Set<InetAddress>)current_registrations.get( network_interface );
 			
 			if ( set == null ){
 				
@@ -442,29 +447,42 @@ MCGroupImpl
 
 	public void
 	sendToGroup(
-		byte[]	data )
+		final byte[]	data )
+	{	
+			// have debugs showing the send-to-group operation hanging and blocking AZ close, make async
+		
+		async_dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					sendToGroupSupport( data );
+				}
+			});
+	}
 	
-		throws MCGroupException
+	private void
+	sendToGroupSupport(
+		byte[]	data )
 	{	
 		try{
-			Enumeration	x = NetworkInterface.getNetworkInterfaces();
+			List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
 			
-			while( x != null && x.hasMoreElements()){
-				
-				NetworkInterface	network_interface = (NetworkInterface)x.nextElement();
-				
+			for ( final NetworkInterface network_interface: x ){
+								
 				if ( !interfaceSelected( network_interface )){
 					
 					continue;
 				}
 				
-				Enumeration ni_addresses = network_interface.getInetAddresses();
+				Enumeration<InetAddress> ni_addresses = network_interface.getInetAddresses();
 				
 				boolean	ok = false;
 				
 				while( ni_addresses.hasMoreElements()){
 					
-					InetAddress ni_address = (InetAddress)ni_addresses.nextElement();
+					InetAddress ni_address = ni_addresses.nextElement();
 				
 					if ( !( ni_address instanceof Inet6Address || ni_address.isLoopbackAddress())){
 						
@@ -521,36 +539,47 @@ MCGroupImpl
 				}
 			}
 		}catch( Throwable e ){
-			
-			throw( new MCGroupException( "sendToGroup failed", e ));
 		}
 	}
 	
 	public void
 	sendToGroup(
-		String	param_data )
+		final String	param_data )
+	{	
+			// have debugs showing the send-to-group operation hanging and blocking AZ close, make async
+		
+		async_dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					sendToGroupSupport( param_data );
+				}
+			});
+	}
 	
-		throws MCGroupException
+	private void
+	sendToGroupSupport(
+		String	param_data )
 	{	
 		try{
-			Enumeration	x = NetworkInterface.getNetworkInterfaces();
+			List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
 			
-			while( x != null && x.hasMoreElements()){
-				
-				NetworkInterface	network_interface = (NetworkInterface)x.nextElement();
-				
+			for ( NetworkInterface network_interface: x ){
+								
 				if ( !interfaceSelected( network_interface )){
 					
 					continue;
 				}
 				
-				Enumeration ni_addresses = network_interface.getInetAddresses();
+				Enumeration<InetAddress> ni_addresses = network_interface.getInetAddresses();
 								
 				InetAddress	an_address = null;
 				
 				while( ni_addresses.hasMoreElements()){
 					
-					InetAddress ni_address = (InetAddress)ni_addresses.nextElement();
+					InetAddress ni_address = ni_addresses.nextElement();
 				
 					if ( !( ni_address instanceof Inet6Address || ni_address.isLoopbackAddress())){
 						
@@ -609,8 +638,6 @@ MCGroupImpl
 				}
 			}
 		}catch( Throwable e ){
-			
-			throw( new MCGroupException( "sendToGroup failed", e ));
 		}
 	}
 	
@@ -655,7 +682,7 @@ MCGroupImpl
 				byte[] buf = new byte[PACKET_SIZE];
 				
 				DatagramPacket packet = new DatagramPacket(buf, buf.length );
-								
+									
 				socket.receive( packet );
 					
 				successful_accepts++;
diff --git a/com/aelitis/net/udp/uc/PRUDPPacketHandler.java b/com/aelitis/net/udp/uc/PRUDPPacketHandler.java
index e332a47..f189919 100644
--- a/com/aelitis/net/udp/uc/PRUDPPacketHandler.java
+++ b/com/aelitis/net/udp/uc/PRUDPPacketHandler.java
@@ -120,7 +120,11 @@ PRUDPPacketHandler
 		throws PRUDPPacketHandlerException;
 	
 	public void
-	setPrimordialHandler(
+	addPrimordialHandler(
+		PRUDPPrimordialHandler	handler );
+	
+	public void
+	removePrimordialHandler(
 		PRUDPPrimordialHandler	handler );
 	
 	public int
@@ -138,4 +142,18 @@ PRUDPPacketHandler
 	
 	public PRUDPPacketHandlerStats
 	getStats();
+	
+	public PRUDPPacketHandler
+	openSession(
+		InetSocketAddress	target )
+	
+		throws PRUDPPacketHandlerException;
+	
+	public void
+	closeSession()
+	
+		throws PRUDPPacketHandlerException;
+	
+	public void
+	destroy();
 }
diff --git a/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerFactoryImpl.java b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerFactoryImpl.java
index a29e1a4..e362e15 100644
--- a/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerFactoryImpl.java
+++ b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerFactoryImpl.java
@@ -62,7 +62,7 @@ PRUDPPacketHandlerFactoryImpl
 			
 			if ( receiver == null ){
 				
-				receiver = new PRUDPPacketHandlerImpl( port, bind_ip );
+				receiver = new PRUDPPacketHandlerImpl( port, bind_ip, null );
 				
 				receiver_map.put( f_port, receiver );
 			}
@@ -99,7 +99,7 @@ PRUDPPacketHandlerFactoryImpl
 			
 			if ( receiver == null ){
 				
-				receiver = new PRUDPPacketHandlerImpl( port, null );
+				receiver = new PRUDPPacketHandlerImpl( port, null, null );
 				
 				receiver_map.put( f_port, receiver );
 			}
diff --git a/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerImpl.java b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerImpl.java
index acf16c1..f5cf99f 100644
--- a/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerImpl.java
+++ b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerImpl.java
@@ -32,6 +32,8 @@ import java.nio.channels.UnsupportedAddressTypeException;
 import java.util.*;
 
 import org.bouncycastle.util.encoders.Base64;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.logging.LogAlert;
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
@@ -40,6 +42,8 @@ import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminPropertyChangeListener;
+import com.aelitis.azureus.core.util.AEPriorityMixin;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.net.udp.uc.*;
 
 public class 
@@ -53,11 +57,34 @@ PRUDPPacketHandlerImpl
 	private static final long	MAX_SEND_QUEUE_DATA_SIZE	= 2*1024*1024;
 	private static final long	MAX_RECV_QUEUE_DATA_SIZE	= 1*1024*1024;
 	
+	private static boolean	use_socks;
+
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"Enable.Proxy", 	
+				"Enable.SOCKS",
+			}, 
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameter_name ) 
+				{
+					boolean	enable_proxy 	= COConfigurationManager.getBooleanParameter("Enable.Proxy");
+				    boolean enable_socks	= COConfigurationManager.getBooleanParameter("Enable.SOCKS");
+				    
+				    use_socks = enable_proxy && enable_socks;
+				}
+			});
+	}
+  
+	
 	private int				port;
 	private DatagramSocket	socket;
 	
-	private PRUDPPrimordialHandler	primordial_handler;
-	private PRUDPRequestHandler		request_handler;
+	private CopyOnWriteList<PRUDPPrimordialHandler>	primordial_handlers = new CopyOnWriteList<PRUDPPrimordialHandler>();
+	private PRUDPRequestHandler				request_handler;
 	
 	private PRUDPPacketHandlerStatsImpl	stats = new PRUDPPacketHandlerStatsImpl( this );
 	
@@ -103,14 +130,17 @@ PRUDPPacketHandlerImpl
 	
 	private PRUDPPacketHandlerImpl altProtocolDelegate; 
 	
+	private final PacketTransformer	packet_transformer;
 	
 	protected
 	PRUDPPacketHandlerImpl(
-		int				_port,
-		InetAddress		_bind_ip )
+		int					_port,
+		InetAddress			_bind_ip,
+		PacketTransformer	_packet_transformer )
 	{
 		port				= _port;
 		explicit_bind_ip	= _bind_ip;
+		packet_transformer	= _packet_transformer;
 		
 		default_bind_ip = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress();
 		
@@ -154,19 +184,86 @@ PRUDPPacketHandlerImpl
 	}
 	
 	public void
-	setPrimordialHandler(
+	addPrimordialHandler(
 		PRUDPPrimordialHandler	handler )
 	{
-		if ( primordial_handler != null && handler != null ){
+		synchronized( primordial_handlers ){
+			
+			if ( primordial_handlers.contains( handler )){
+				
+				Debug.out( "Primordial handler already added!" );
+				
+				return;
+			}
+			
+			int	priority;
+			
+			if ( handler instanceof AEPriorityMixin ){
+			
+				priority = ((AEPriorityMixin)handler).getPriority();
+				
+			}else{
+				
+				priority = AEPriorityMixin.PRIORITY_NORMAL;
+			}
+			
+			List<PRUDPPrimordialHandler> existing = primordial_handlers.getList();
 			
-			Debug.out( "Primordial handler replaced!" );
+			int	insert_at = -1;
+			
+			for (int i=0;i<existing.size();i++){
+				
+				PRUDPPrimordialHandler e = existing.get( i );
+				
+				int	existing_priority;
+				
+				if ( e instanceof AEPriorityMixin ){
+				
+					existing_priority = ((AEPriorityMixin)e).getPriority();
+					
+				}else{
+					
+					existing_priority = AEPriorityMixin.PRIORITY_NORMAL;
+				}
+				
+				if ( existing_priority < priority ){
+					
+					insert_at = i;
+					
+					break;
+				}
+			}
+			
+			if ( insert_at >= 0 ){
+				
+				primordial_handlers.add( insert_at, handler );
+				
+			}else{
+				
+				primordial_handlers.add( handler );
+			}
 		}
 		
-		primordial_handler	= handler;
+			// if we have an altProtocolDelegate then this shares the list of handlers so no need to add
+	}
+	
+	public void
+	removePrimordialHandler(
+		PRUDPPrimordialHandler	handler )
+	{
+		synchronized( primordial_handlers ){
+			
+			if ( !primordial_handlers.contains( handler )){
+				
+				Debug.out( "Primordial handler not found!" );
+				
+				return;
+			}
+			
+			primordial_handlers.remove( handler );
+		}
 		
-		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
-			delegate.setPrimordialHandler(handler);
+			// if we have an altProtocolDelegate then this shares the list of handlers so no need to remove
 	}
 	
 	public void
@@ -188,8 +285,11 @@ PRUDPPacketHandlerImpl
 		request_handler	= _request_handler;
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
+		
+		if ( delegate != null ){
+			
 			delegate.setRequestHandler(_request_handler);
+		}
 	}
 	
 	public PRUDPRequestHandler
@@ -201,6 +301,11 @@ PRUDPPacketHandlerImpl
 	public int
 	getPort()
 	{
+		if ( port == 0 && socket != null ){
+			
+			return( socket.getLocalPort());
+		}
+		
 		return( port );
 	}
 	
@@ -295,9 +400,9 @@ PRUDPPacketHandlerImpl
 			
 			if(altAddress != null && altProtocolDelegate == null)
 			{
-				altProtocolDelegate = new PRUDPPacketHandlerImpl(port,altAddress);
+				altProtocolDelegate = new PRUDPPacketHandlerImpl(port,altAddress,packet_transformer);
 				altProtocolDelegate.stats = stats;
-				altProtocolDelegate.primordial_handler = primordial_handler;
+				altProtocolDelegate.primordial_handlers = primordial_handlers;
 				altProtocolDelegate.request_handler = request_handler;
 			}
 				
@@ -441,18 +546,16 @@ PRUDPPacketHandlerImpl
 	
 						DatagramPacket packet = new DatagramPacket( buffer, buffer.length, address );
 						
-						socket.receive( packet );
-						
+						receiveFromSocket( packet );
+												
 						long	receive_time = SystemTime.getCurrentTime();
 						
 						successful_accepts++;
 						
 						failed_accepts = 0;
 						
-						PRUDPPrimordialHandler prim_hand = primordial_handler;
-						
-						if ( prim_hand != null ){
-							
+						for ( PRUDPPrimordialHandler prim_hand: primordial_handlers ){
+													
 							if ( prim_hand.packetReceived( packet )){
 						
 									// primordial handlers get their own buffer as we can't guarantee
@@ -461,6 +564,8 @@ PRUDPPacketHandlerImpl
 								buffer	= null;
 								
 								stats.primordialPacketReceived( packet.getLength());
+								
+								break;
 							}
 						}
 						
@@ -563,10 +668,12 @@ PRUDPPacketHandlerImpl
 
 			// make sure we destroy the delegate too if something happend
 			PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-			if(delegate != null)
-				delegate.destroy();
-
 			
+			if ( delegate != null ){
+				
+				delegate.destroy();
+			}
+		
 			NetworkAdmin.getSingleton().removePropertyChangeListener( prop_listener );
 		}
 	}
@@ -847,7 +954,7 @@ PRUDPPacketHandlerImpl
 			if ( e instanceof IOException ){
 			
 					// generally uninteresting
-				
+				//e.printStackTrace();
 			}else{
 							
 				Logger.log(new LogEvent(LOGID, "", e));
@@ -942,9 +1049,12 @@ PRUDPPacketHandlerImpl
 		}
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null && destination_address.getAddress().getClass().isInstance(delegate.explicit_bind_ip))
+		
+		if (	delegate != null && 
+				destination_address.getAddress().getClass().isInstance(delegate.explicit_bind_ip)){
+			
 			return delegate.sendAndReceive(auth, request_packet, destination_address, receiver, timeout, priority);		
-
+		}
 		
 		try{
 			checkTargetAddress( destination_address );
@@ -1034,7 +1144,7 @@ PRUDPPacketHandlerImpl
 							
 								// synchronous write holding lock to block senders
 							
-							socket.send( dg_packet );
+							sendToSocket( dg_packet );
 							
 							stats.packetSent( buffer.length );
 							
@@ -1136,7 +1246,7 @@ PRUDPPacketHandlerImpl
 													
 													r.sent();
 													
-													socket.send( p );
+													sendToSocket( p );
 													
 													stats.packetSent( p.getLength() );
 							
@@ -1180,7 +1290,8 @@ PRUDPPacketHandlerImpl
 					
 					request.sent();
 					if (dg_packet == null) {throw new NullPointerException("dg_packet is null");}
-					socket.send( dg_packet );
+					
+					sendToSocket( dg_packet );
 					
 					// System.out.println( "sent:" + buffer.length );
 					
@@ -1259,12 +1370,14 @@ PRUDPPacketHandlerImpl
 		}
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null && destination_address.getAddress().getClass().isInstance(delegate.explicit_bind_ip))
-		{
+		
+		if (	delegate != null && 
+				destination_address.getAddress().getClass().isInstance(delegate.explicit_bind_ip)){
+		
 			delegate.send(request_packet, destination_address);
+			
 			return;
 		}
-
 		
 		try{
 			checkTargetAddress( destination_address );
@@ -1289,7 +1402,7 @@ PRUDPPacketHandlerImpl
 								+ request_packet.getString()));
 			}
 			
-			socket.send( dg_packet );
+			sendToSocket( dg_packet );
 			
 			stats.packetSent( buffer.length );
 			
@@ -1301,7 +1414,12 @@ PRUDPPacketHandlerImpl
 			
 		}catch( Throwable e ){
 			
-			e.printStackTrace();
+			if ( e instanceof NoRouteToHostException ){
+				
+			}else{
+			
+				e.printStackTrace();
+			}
 			
 			Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "PRUDPPacketHandler: send to " + destination_address + " failed: " + Debug.getNestedExceptionMessage(e)));
 			
@@ -1345,10 +1463,11 @@ PRUDPPacketHandlerImpl
 		}
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
-			delegate.setDelays(_send_delay, _receive_delay, _queued_request_timeout);
-		
 		
+		if ( delegate != null ){
+			
+			delegate.setDelays(_send_delay, _receive_delay, _queued_request_timeout);
+		}
 	}
 	
 	public long
@@ -1360,9 +1479,12 @@ PRUDPPacketHandlerImpl
 		}
 
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
+		
+		if ( delegate != null ){
+			
 			res += delegate.getSendQueueLength();
-
+		}
+		
 		return(res);
 	}
 	
@@ -1370,9 +1492,14 @@ PRUDPPacketHandlerImpl
 	getReceiveQueueLength()
 	{
 		long size = recv_queue.size(); 
+		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
+		
+		if ( delegate != null ){
+			
 			size += delegate.getReceiveQueueLength();
+		}
+		
 		return size;
 	}
 	
@@ -1394,12 +1521,14 @@ PRUDPPacketHandlerImpl
 		}
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null && target.getAddress().getClass().isInstance(delegate.explicit_bind_ip))
-		{
+		
+		if ( 	delegate != null && 
+				target.getAddress().getClass().isInstance(delegate.explicit_bind_ip)){
+		
 			delegate.primordialSend(buffer, target);
+			
 			return;
 		}
-
 		
 		try{
 			checkTargetAddress( target );
@@ -1413,7 +1542,7 @@ PRUDPPacketHandlerImpl
 						"PRUDPPacketHandler: reply packet sent: " + buffer.length + " to " + target ));
 			}
 			
-			socket.send( dg_packet );
+			sendToSocket( dg_packet );
 			
 			stats.primordialPacketSent( buffer.length );
 			
@@ -1423,21 +1552,89 @@ PRUDPPacketHandlerImpl
 		}
 	}
 	
+	private void
+	sendToSocket(
+		DatagramPacket	p )
+	
+		throws IOException
+	{
+		if ( packet_transformer != null ){
+			
+			packet_transformer.transformSend( p );
+		}
+		
+		socket.send( p );
+	}
+	
+	private void
+	receiveFromSocket(
+		DatagramPacket	p )
+	
+		throws IOException
+	{
+		socket.receive( p );
+		
+		if ( packet_transformer != null ){
+			
+			packet_transformer.transformReceive( p );
+		}
+	}
+	
 	public PRUDPPacketHandlerStats
 	getStats()
 	{
 		return( stats );
 	}
 	
-	protected void
+	public void
 	destroy()
 	{
 		destroyed	= true;
 		
 		PRUDPPacketHandlerImpl delegate = altProtocolDelegate;
-		if(delegate != null)
+		
+		if ( delegate != null ){
+			
 			delegate.destroy();
-
+		}
+		
 		destroy_sem.reserve();
 	}
+	
+	
+	public PRUDPPacketHandler
+	openSession(
+		InetSocketAddress		target )
+	
+		throws PRUDPPacketHandlerException
+	{
+		if ( use_socks ){
+			
+			return( new PRUDPPacketHandlerSocks( target ));
+			
+		}else{
+			
+			return( this );
+		}
+	}
+	
+	public void
+	closeSession()
+	
+		throws PRUDPPacketHandlerException
+	{
+	}
+	
+	protected interface
+	PacketTransformer
+	{
+		public void
+		transformSend(
+			DatagramPacket	packet );
+			
+		public void
+		transformReceive(
+			DatagramPacket	packet );
+			
+	}
 }
diff --git a/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerSocks.java b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerSocks.java
new file mode 100644
index 0000000..ffd0a47
--- /dev/null
+++ b/com/aelitis/net/udp/uc/impl/PRUDPPacketHandlerSocks.java
@@ -0,0 +1,547 @@
+/*
+ * Created on Jun 8, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.net.udp.uc.impl;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.Socket;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.HostNameToIPResolver;
+
+import com.aelitis.azureus.core.proxy.AEProxyFactory;
+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.PRUDPPacketHandlerStats;
+import com.aelitis.net.udp.uc.PRUDPPacketReceiver;
+import com.aelitis.net.udp.uc.PRUDPPrimordialHandler;
+import com.aelitis.net.udp.uc.PRUDPRequestHandler;
+
+public class 
+PRUDPPacketHandlerSocks 
+	implements PRUDPPacketHandler, PRUDPPacketHandlerImpl.PacketTransformer
+{
+	private static String	socks_host;
+	private static int		socks_port;
+	private static String	socks_user;
+	private static String	socks_password;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"Proxy.Host",
+				"Proxy.Port",
+				"Proxy.Username",
+				"Proxy.Password",
+			}, 
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameter_name ) 
+				{
+				    socks_host 		= COConfigurationManager.getStringParameter("Proxy.Host").trim();
+					socks_port 		= Integer.parseInt(COConfigurationManager.getStringParameter("Proxy.Port").trim());
+					socks_user 		= COConfigurationManager.getStringParameter("Proxy.Username").trim();
+					socks_password 	= COConfigurationManager.getStringParameter("Proxy.Password").trim();
+							     
+					if ( socks_user.equalsIgnoreCase("<none>")){
+						socks_user = "";
+					}
+						      
+				}
+			});
+	}
+	
+	final private InetSocketAddress		target;
+	
+	private Socket					control_socket;
+	
+	private InetSocketAddress		relay;
+	
+	private PRUDPPacketHandler		delegate;
+	
+	private byte[]	packet_out_header;
+	
+	protected
+	PRUDPPacketHandlerSocks(
+		InetSocketAddress		_target )
+	
+		throws PRUDPPacketHandlerException
+	{
+		target	= _target;
+		
+		boolean	ok = false;
+		
+		try{
+		    delegate = new PRUDPPacketHandlerImpl( 0, null, this );
+
+			control_socket = new Socket( Proxy.NO_PROXY );
+			
+			control_socket.connect( new InetSocketAddress( socks_host, socks_port ));
+		
+			DataOutputStream 	dos = new DataOutputStream( new BufferedOutputStream( control_socket.getOutputStream(), 256 ));
+			DataInputStream 	dis = new DataInputStream( control_socket.getInputStream());
+						
+			dos.writeByte( (byte)5 ); // socks 5
+			dos.writeByte( (byte)2 ); // 2 methods
+			dos.writeByte( (byte)0 ); // no auth
+			dos.writeByte( (byte)2 ); // user/pw
+			
+			dos.flush();
+			
+		    dis.readByte();  // version byte
+		    
+		    byte method = dis.readByte();
+
+		    if ( method != 0 && method != 2 ){
+		    	
+		        throw new IOException( "SOCKS 5: no valid method [" + method + "]" );
+		    }
+
+		      // auth
+		    
+		    if ( method == 2 ) {
+		        
+		    	dos.writeByte( (byte)1 ); // user/pw version
+		    	dos.writeByte( (byte)socks_user.length() ); // user length
+		    	dos.write( socks_user.getBytes() );
+		    	dos.writeByte( (byte)socks_password.length() ); // password length
+		    	dos.write( socks_password.getBytes() );
+
+		    	dos.flush();
+		    	
+		    	dis.readByte();  // version byte
+		    	
+		    	byte status = dis.readByte();
+
+		        if ( status != 0 ){
+		        	
+		        	throw( new IOException( "SOCKS 5: authentication fails [status=" +status+ "]" ));
+		        }
+		    }
+		    
+		    String	mapped_ip;
+		    
+		    if ( target.isUnresolved() || target.getAddress() == null ){
+		    	
+		    		// deal with long "hostnames" that we get for, e.g., I2P destinations
+		    	
+		      	mapped_ip = AEProxyFactory.getAddressMapper().internalise( target.getHostName() );
+		      	
+		    }else{
+		    	  
+		      	mapped_ip = target.getAddress().getHostName();
+		    }
+		    
+		    dos.writeByte( (byte)5 ); // version
+		    dos.writeByte( (byte)3 ); // udp associate
+		    dos.writeByte( (byte)0 ); // reserved
+		    
+	    	dos.writeByte((byte)1);
+	    	dos.write( new byte[4] );
+	    	
+		    dos.writeShort( (short)delegate.getPort()); // port
+		    
+		    dos.flush();
+		    
+		    dis.readByte();	// ver
+		    
+		    byte reply = dis.readByte();
+		    
+		    if ( reply != 0 ){
+		    	
+	        	throw( new IOException( "SOCKS 5: udp association fails [reply=" +reply+ "]" ));
+		    }
+		    
+		    dis.readByte();	// reserved
+		    
+		    InetAddress	relay_address;
+		    
+		    byte atype = dis.readByte();
+		    
+		    if ( atype == 1 ){
+		    	
+		    	byte[]	bytes = new byte[4];
+		    	
+		    	dis.readFully( bytes );
+		    	
+		    	relay_address = InetAddress.getByAddress( bytes );
+		    	
+		    }else if ( atype == 3 ){
+		    	
+		    	byte	len = dis.readByte();
+		    	
+		    	byte[] bytes = new byte[(int)len&0xff ];
+		    	
+		    	dis.readFully( bytes );
+		    	
+		    	relay_address = InetAddress.getByName( new String( bytes ));
+		    	
+		    }else{
+		    	
+		    	byte[]	bytes = new byte[16];
+		    	
+		    	dis.readFully( bytes );
+		    	
+		    	relay_address = InetAddress.getByAddress( bytes );
+
+		    }
+		    
+		    int	relay_port = ((dis.readByte()<<8)&0xff00) | (dis.readByte() & 0x00ff );
+		    	
+		    if ( relay_address.isAnyLocalAddress()){
+		    	
+		    	relay_address = control_socket.getInetAddress();
+		    }
+		    
+		    relay = new InetSocketAddress( relay_address, relay_port );
+		    			    
+		    	// use the maped ip for dns resolution so we don't leak the
+		    	// actual address if this is a secure one (e.g. I2P one)
+		    
+		    ByteArrayOutputStream	baos_temp 		= new ByteArrayOutputStream();
+		    DataOutputStream		dos_temp	= new DataOutputStream( baos_temp );
+	
+		    dos_temp.writeByte(0);	// resv
+		    dos_temp.writeByte(0);	// resv		    
+		    dos_temp.writeByte(0);	// frag (none)
+	
+		    try {
+		    	byte[] ip_bytes = HostNameToIPResolver.syncResolve( mapped_ip ).getAddress();
+	
+		    	dos_temp.writeByte( ip_bytes.length==4?(byte)1:(byte)4 );
+		    	dos_temp.write( ip_bytes );
+	
+		    	
+		    }catch( Throwable e ){
+		    			    	
+		    	dos_temp.writeByte( (byte)3 );  // address type = domain name
+		    	dos_temp.writeByte( (byte)mapped_ip.length() );  // address type = domain name
+		    	dos_temp.write( mapped_ip.getBytes() );
+	
+		    }
+	
+		    dos_temp.writeShort( (short)target.getPort() ); // port
+	
+		    dos_temp.flush();
+		    packet_out_header = baos_temp.toByteArray();
+
+		    	    
+			ok = true;
+			
+			Thread.sleep(1000);
+			
+		}catch( Throwable e ){
+			
+			throw( new PRUDPPacketHandlerException( "socks setup failed: " + Debug.getNestedExceptionMessage(e), e));
+			
+		}finally{
+			
+			if ( !ok ){
+				
+				try{
+					control_socket.close();
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+					
+				}finally{
+					
+					control_socket = null;
+				}
+				
+				if ( delegate != null ){
+					
+					try{
+					    delegate.destroy();
+					    
+					}finally{
+						
+						delegate = null;
+					}
+				}
+			}
+		}
+	}
+	
+	public void
+	transformSend(
+		DatagramPacket	packet )
+	{		
+		byte[]	data 		= packet.getData();
+		int		data_len	= packet.getLength();
+		
+		byte[]	new_data = new byte[data_len+packet_out_header.length];
+		
+		System.arraycopy( packet_out_header, 0, new_data, 0, packet_out_header.length );
+		System.arraycopy( data, 0, new_data, packet_out_header.length, data_len);
+		
+		packet.setData( new_data );
+	}
+		
+	public void
+	transformReceive(
+		DatagramPacket	packet )
+	{
+		byte[]	data 		= packet.getData();
+		int		data_len	= packet.getLength();
+		
+		DataInputStream dis = new DataInputStream( new ByteArrayInputStream( data, 0, data_len ));
+		
+		try{
+			dis.readByte();	// res
+			dis.readByte();	// res
+			dis.readByte();	// assume no frag
+		
+			byte	atype = dis.readByte();
+			
+			int	encap_len = 4;
+			if ( atype == 1 ){
+				
+				encap_len += 4;
+				
+			}else if ( atype == 3 ){
+				
+				encap_len += 1 + (dis.readByte()&0xff);
+				
+			}else{
+				
+				encap_len += 16;
+			}
+			
+			encap_len += 2;	// port
+			
+			byte[]	new_data = new byte[data_len-encap_len];
+			
+			System.arraycopy( data, encap_len, new_data, 0, data_len - encap_len );
+			
+			packet.setData( new_data );
+			
+		}catch( IOException e ){
+			
+			Debug.out( e );
+		}
+	}
+			
+	private void
+	checkAddress(
+		InetSocketAddress			destination )
+	
+		throws PRUDPPacketHandlerException
+	{
+		if ( !destination.equals( target )){
+			
+			throw( new PRUDPPacketHandlerException( "Destination mismatch" ));
+		}
+	}
+	
+	public void
+	sendAndReceive(
+		PRUDPPacket					request_packet,
+		InetSocketAddress			destination_address,
+		PRUDPPacketReceiver			receiver,
+		long						timeout,
+		int							priority )
+	
+		throws PRUDPPacketHandlerException
+	{
+		checkAddress( destination_address );
+		
+		delegate.sendAndReceive( request_packet, relay, receiver, timeout, priority );
+	}
+	
+	public PRUDPPacket
+	sendAndReceive(
+		PasswordAuthentication		auth,
+		PRUDPPacket					request_packet,
+		InetSocketAddress			destination_address )
+	
+		throws PRUDPPacketHandlerException
+	{
+		checkAddress( destination_address );
+		
+		return( delegate.sendAndReceive( auth, request_packet, relay));
+	}
+	
+	public PRUDPPacket
+	sendAndReceive(
+		PasswordAuthentication		auth,
+		PRUDPPacket					request_packet,
+		InetSocketAddress			destination_address,
+		long						timeout_millis )
+	
+		throws PRUDPPacketHandlerException
+	{
+		checkAddress( destination_address );
+		
+		return( delegate.sendAndReceive(auth, request_packet, relay, timeout_millis ));
+	}
+	
+	public PRUDPPacket
+	sendAndReceive(
+		PasswordAuthentication		auth,
+		PRUDPPacket					request_packet,
+		InetSocketAddress			destination_address,
+		long						timeout_millis,
+		int							priority )
+	
+		throws PRUDPPacketHandlerException
+	{
+		checkAddress( destination_address );
+		
+		return( delegate.sendAndReceive(auth, request_packet, relay, timeout_millis, priority ));
+	}
+	
+	public void
+	send(
+		PRUDPPacket					request_packet,
+		InetSocketAddress			destination_address )
+	
+		throws PRUDPPacketHandlerException
+	{
+		checkAddress( destination_address );
+		
+		delegate.send( request_packet, relay );
+	}
+	
+	public PRUDPRequestHandler
+	getRequestHandler()
+	{
+		return( delegate.getRequestHandler());
+	}
+	
+	public void
+	setRequestHandler(
+		PRUDPRequestHandler	request_handler )
+	{
+		delegate.setRequestHandler( request_handler );
+	}
+	
+	public void
+	primordialSend(
+		byte[]				data,
+		InetSocketAddress	target )
+	
+		throws PRUDPPacketHandlerException
+	{
+		throw( new PRUDPPacketHandlerException( "not imp" ));
+	}
+	
+	public void
+	addPrimordialHandler(
+		PRUDPPrimordialHandler	handler )
+	{
+	}
+	
+	public void
+	removePrimordialHandler(
+		PRUDPPrimordialHandler	handler )
+	{
+	}
+	
+	public int
+	getPort()
+	{
+		return( delegate.getPort());
+	}
+	
+	public void
+	setDelays(
+		int		send_delay,
+		int		receive_delay,
+		int		queued_request_timeout )
+	{
+		delegate.setDelays(send_delay, receive_delay, queued_request_timeout);
+	}
+	
+	public void
+	setExplicitBindAddress(
+		InetAddress	address )
+	{
+		delegate.setExplicitBindAddress( address );
+	}
+	
+	public PRUDPPacketHandlerStats
+	getStats()
+	{
+		return( delegate.getStats());
+	}
+	
+	public PRUDPPacketHandler
+	openSession(
+		InetSocketAddress	target )
+	
+		throws PRUDPPacketHandlerException
+	{
+		throw( new PRUDPPacketHandlerException( "not supported" ));
+	}
+	
+	public void
+	closeSession()
+	
+		throws PRUDPPacketHandlerException
+	{	
+		if ( control_socket != null ){
+			
+			try{
+				control_socket.close();
+				
+				control_socket = null;
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		if ( delegate != null ){
+			
+			delegate.destroy();
+		}
+	}
+	
+	public void
+	destroy()
+	{
+		try{
+			closeSession();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+}
diff --git a/com/aelitis/net/upnp/UPnP.java b/com/aelitis/net/upnp/UPnP.java
index 06cde24..25610ea 100644
--- a/com/aelitis/net/upnp/UPnP.java
+++ b/com/aelitis/net/upnp/UPnP.java
@@ -58,6 +58,9 @@ UPnP
 	injectDiscoveryCache(
 		Map				cache );
 	
+	public UPnPSSDP
+	getSSDP();
+	
 		/**
 		 * Logs a message to all registered log listeners
 		 * @param str
diff --git a/com/aelitis/net/upnp/UPnPDevice.java b/com/aelitis/net/upnp/UPnPDevice.java
index 2c24623..5d092d2 100644
--- a/com/aelitis/net/upnp/UPnPDevice.java
+++ b/com/aelitis/net/upnp/UPnPDevice.java
@@ -65,4 +65,7 @@ UPnPDevice
 	
 	public UPnPRootDevice
 	getRootDevice();
+
+	public UPnPDeviceImage[]
+	getImages();
 }
diff --git a/com/aelitis/net/upnp/UPnPDeviceImage.java b/com/aelitis/net/upnp/UPnPDeviceImage.java
new file mode 100644
index 0000000..5c81611
--- /dev/null
+++ b/com/aelitis/net/upnp/UPnPDeviceImage.java
@@ -0,0 +1,9 @@
+package com.aelitis.net.upnp;
+
+public interface UPnPDeviceImage
+{
+	public int getWidth();
+	public int getHeight();
+	public String getLocation();
+	public String getMime();
+}
diff --git a/com/aelitis/net/upnp/UPnPService.java b/com/aelitis/net/upnp/UPnPService.java
index 28830ec..9e6e1fe 100644
--- a/com/aelitis/net/upnp/UPnPService.java
+++ b/com/aelitis/net/upnp/UPnPService.java
@@ -45,6 +45,9 @@ UPnPService
 	
 		throws UPnPException;
 	
+	public boolean
+	isConnectable();
+	
 	public UPnPAction[]
 	getActions()
 	
diff --git a/com/aelitis/net/upnp/impl/SSDPIGD.java b/com/aelitis/net/upnp/impl/SSDPIGD.java
index c4b0cfb..43ebb70 100644
--- a/com/aelitis/net/upnp/impl/SSDPIGD.java
+++ b/com/aelitis/net/upnp/impl/SSDPIGD.java
@@ -32,6 +32,9 @@ import com.aelitis.net.upnp.*;
 public interface 
 SSDPIGD 
 {
+	public UPnPSSDP
+	getSSDP();
+	
 	public void
 	start()
 	
diff --git a/com/aelitis/net/upnp/impl/UPnPImpl.java b/com/aelitis/net/upnp/impl/UPnPImpl.java
index 8fea659..41f4cb6 100644
--- a/com/aelitis/net/upnp/impl/UPnPImpl.java
+++ b/com/aelitis/net/upnp/impl/UPnPImpl.java
@@ -125,6 +125,12 @@ UPnPImpl
 		ssdp.start();
 	}
 	
+	public UPnPSSDP 
+	getSSDP() 
+	{
+		return( ssdp.getSSDP());
+	}
+	
 	public void 
 	injectDiscoveryCache(
 		Map 		cache )
diff --git a/com/aelitis/net/upnp/impl/device/UPnPDeviceImageImpl.java b/com/aelitis/net/upnp/impl/device/UPnPDeviceImageImpl.java
new file mode 100644
index 0000000..bd39efa
--- /dev/null
+++ b/com/aelitis/net/upnp/impl/device/UPnPDeviceImageImpl.java
@@ -0,0 +1,38 @@
+package com.aelitis.net.upnp.impl.device;
+
+import com.aelitis.net.upnp.UPnPDeviceImage;
+
+public class UPnPDeviceImageImpl
+	implements UPnPDeviceImage
+{
+	public int width;
+
+	public int height;
+
+	public String location;
+	
+	public String mime;
+
+	public UPnPDeviceImageImpl(int width, int height, String location, String mime) {
+		this.width = width;
+		this.height = height;
+		this.location = location;
+		this.mime = mime;
+	}
+
+	public int getWidth() {
+		return width;
+	}
+
+	public int getHeight() {
+		return height;
+	}
+
+	public String getLocation() {
+		return location;
+	}
+	
+	public String getMime() {
+		return mime;
+	}
+}
diff --git a/com/aelitis/net/upnp/impl/device/UPnPDeviceImpl.java b/com/aelitis/net/upnp/impl/device/UPnPDeviceImpl.java
index 200a914..84b3ed5 100644
--- a/com/aelitis/net/upnp/impl/device/UPnPDeviceImpl.java
+++ b/com/aelitis/net/upnp/impl/device/UPnPDeviceImpl.java
@@ -22,6 +22,7 @@
 
 package com.aelitis.net.upnp.impl.device;
 
+import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentAttribute;
 import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentNode;
 
 /**
@@ -57,6 +58,7 @@ UPnPDeviceImpl
 	
 	private List		devices		= new ArrayList();
 	private List		services	= new ArrayList();
+	private List<UPnPDeviceImage>		images	= new ArrayList<UPnPDeviceImage>();
 	
 	protected
 	UPnPDeviceImpl(
@@ -110,6 +112,35 @@ UPnPDeviceImpl
 				devices.add( new UPnPDeviceImpl( root_device, indent + "  ", device_nodes[i]));
 			}
 		}
+		
+		SimpleXMLParserDocumentNode	icon_list = device_node.getChild( "iconList" );
+		if (icon_list != null) {
+			SimpleXMLParserDocumentNode[] children = icon_list.getChildren();
+			
+			for (SimpleXMLParserDocumentNode child : children) {
+				if (!"icon".equalsIgnoreCase(child.getName())) {
+					continue;
+				}
+				
+				String oUrl = getOptionalField(child, "url");
+				if (oUrl == null) {
+					continue;
+				}
+				
+				int width = -1;
+				int height = -1;
+				String oWidth = getOptionalField(child, "width");
+				String oHeight = getOptionalField(child, "height");
+				try {
+					width = Integer.parseInt(oWidth);
+					height = Integer.parseInt(oHeight);
+				} catch (Throwable t) {
+				}
+				
+				images.add(new UPnPDeviceImageImpl(width, height, oUrl,
+						getOptionalField(child, "mime")));
+			}
+		}
 	}
 	
 	public String
@@ -222,6 +253,12 @@ UPnPDeviceImpl
 		return( res );
 	}
 	
+	public UPnPDeviceImage[]
+	getImages()
+	{
+		return images.toArray(new UPnPDeviceImage[0]);
+	}
+	
 	protected String
 	getOptionalField(
 		SimpleXMLParserDocumentNode	node,
diff --git a/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java b/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
index 24ebd44..ce99666 100644
--- a/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
+++ b/com/aelitis/net/upnp/impl/device/UPnPRootDeviceImpl.java
@@ -209,7 +209,7 @@ UPnPRootDeviceImpl
 						upnp.logAlert( 
 								"Device '" + model + "', version '" + version + 
 								"' has known problems with UPnP. Please update to the latest software version (see " + 
-								(url==null?"the manufacturer's web site":url) + ") and refer to http://www.azureuswiki.com/index.php/UPnP",
+								(url==null?"the manufacturer's web site":url) + ") and refer to http://wiki.vuze.com/w/UPnP",
 								false,
 								UPnPLogListener.TYPE_ONCE_EVER );
 					}
diff --git a/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java b/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java
index 53831f3..9886df4 100644
--- a/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java
+++ b/com/aelitis/net/upnp/impl/services/UPnPSSOfflineDownloaderImpl.java
@@ -212,6 +212,50 @@ UPnPSSOfflineDownloaderImpl
 		}
 	}
 	
+	public String 
+	addDownloadChunked(
+		String 	client_id, 
+		String 	hash,
+		String	chunk,
+		int		offset,
+		int		total_size )
+			
+		throws UPnPException 
+	{
+		UPnPAction act = service.getAction( "AddDownloadChunked" );
+		
+		if ( act == null ){
+						
+			throw( new UPnPException( "AddDownloadChunked not supported" ));
+			
+		}else{
+					
+			UPnPActionInvocation inv = act.getInvocation();
+						
+			inv.addArgument( "NewClientID", client_id );
+			inv.addArgument( "NewTorrentHash", hash );
+			inv.addArgument( "NewTorrentData", chunk );
+			inv.addArgument( "NewChunkOffset", String.valueOf( offset ));
+			inv.addArgument( "NewTotalLength", String.valueOf( total_size ));
+			
+			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, 
diff --git a/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java b/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
index d12f943..bd82378 100644
--- a/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
+++ b/com/aelitis/net/upnp/impl/services/UPnPServiceImpl.java
@@ -81,6 +81,41 @@ UPnPServiceImpl
 		return( service_type );
 	}
 	
+	public boolean 
+	isConnectable() 
+	{
+		try{
+			URL url = getControlURL();
+			
+			Socket socket = new Socket();
+			
+			try{
+				int	port = url.getPort();
+				
+				if ( port <= 0 ){
+					
+					port = url.getDefaultPort();
+				}
+				
+				socket.connect( new InetSocketAddress( url.getHost(), port ), 5000 );
+				
+				return( true );
+				
+			}finally{
+				
+				try{
+					socket.close();
+					
+				}catch( Throwable e ){
+					
+				}
+			}
+		}catch( Throwable e ){
+						
+			return( false );
+		}
+	}
+	
 	public UPnPAction[]
 	getActions()
 	
diff --git a/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java b/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
index a5f14e9..5df4159 100644
--- a/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
+++ b/com/aelitis/net/upnp/impl/ssdp/SSDPIGDImpl.java
@@ -27,6 +27,7 @@ import java.util.*;
 
 import org.gudy.azureus2.core3.util.*;
 
+import com.aelitis.azureus.core.util.NetUtils;
 import com.aelitis.net.upnp.*;
 import com.aelitis.net.upnp.impl.*;
 
@@ -70,6 +71,12 @@ SSDPIGDImpl
 		ssdp_core.addListener( this );
 	}
 	
+	public SSDPCore
+	getSSDP()
+	{
+		return( ssdp_core );
+	}
+	
 	public void
 	start()
 	
@@ -203,17 +210,15 @@ SSDPIGDImpl
 						
 						int	best_prefix	= 0;
 						
-						Enumeration network_interfaces = NetworkInterface.getNetworkInterfaces();
+						List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
 						
-						while (network_interfaces.hasMoreElements()){
-							
-							NetworkInterface this_ni = (NetworkInterface)network_interfaces.nextElement();
+						for ( final NetworkInterface this_ni: x ){
 													
-							Enumeration ni_addresses = this_ni.getInetAddresses();
+							Enumeration<InetAddress> ni_addresses = this_ni.getInetAddresses();
 							
 							while (ni_addresses.hasMoreElements()){
 								
-								InetAddress this_address = (InetAddress)ni_addresses.nextElement();
+								InetAddress this_address = ni_addresses.nextElement();
 								
 								byte[]	this_bytes = this_address.getAddress();
 								
diff --git a/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java b/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java
index f657c76..83b29fa 100644
--- a/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java
+++ b/com/aelitis/net/upnp/services/UPnPOfflineDownloader.java
@@ -53,6 +53,16 @@ UPnPOfflineDownloader
 	
 		throws UPnPException;
 	
+	public String
+	addDownloadChunked(
+		String		client_id,
+		String		hash_list,
+		String		torrent_chunk,
+		int			offset,
+		int			total_size )
+	
+		throws UPnPException;
+	
 	public String[]
 	updateDownload(
 		String		client_id,
diff --git a/org/apache/commons/lang/Entities.java b/org/apache/commons/lang/Entities.java
index bae0205..735ab01 100644
--- a/org/apache/commons/lang/Entities.java
+++ b/org/apache/commons/lang/Entities.java
@@ -31,7 +31,7 @@ import java.util.TreeMap;
  * @author <a href="mailto:alex at purpletech.com">Alexander Day Chaffee</a>
  * @author <a href="mailto:ggregory at seagullsw.com">Gary Gregory</a>
  * @since 2.0
- * @version $Id: Entities.java,v 1.1 2008/05/02 15:43:01 gudy Exp $
+ * @version $Id: Entities.java,v 1.1 2008-05-02 15:43:01 gudy Exp $
  */
 public class Entities {
 
@@ -649,12 +649,17 @@ public class Entities {
                 String entityName = str.substring(i + 1, semi);
                 int entityValue;
                 if (entityName.charAt(0) == '#') {
-                    char charAt1 = entityName.charAt(1);
-                    if (charAt1 == 'x' || charAt1=='X') {
-                        entityValue = Integer.valueOf(entityName.substring(2), 16).intValue();
-                    } else {
-                        entityValue = Integer.parseInt(entityName.substring(1));
-                    }
+                	try{
+	                    char charAt1 = entityName.charAt(1);
+	                    if (charAt1 == 'x' || charAt1=='X') {
+	                        entityValue = Integer.valueOf(entityName.substring(2), 16).intValue();
+	                    } else {
+	                        entityValue = Integer.parseInt(entityName.substring(1));
+	                    }
+                	}catch( Throwable e ){
+                			// malformed, ignore
+                		entityValue = -1;
+                	}
                 } else {
                     entityValue = this.entityValue(entityName);
                 }
diff --git a/org/eclipse/swt/widgets/Tree2.java b/org/eclipse/swt/widgets/Tree2.java
new file mode 100644
index 0000000..8d444b0
--- /dev/null
+++ b/org/eclipse/swt/widgets/Tree2.java
@@ -0,0 +1,150 @@
+/**
+ * Created on May 12, 2010
+ *
+ * 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.eclipse.swt.widgets;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.Constants;
+
+/**
+ * Windows specific hack to remove expando<P>
+ * 
+ * This class can be safely excluded from non-Windows builds
+ * 
+ * @author TuxPaper
+ * @created May 12, 2010
+ *
+ */
+public class Tree2
+	extends Tree
+{
+	static final Map<Integer, Integer> mapStyleToWidgetStyle = new HashMap<Integer, Integer>(
+			0);
+
+	public Tree2(Composite parent, int style) {
+		super(parent, style);
+	}
+
+	protected void checkSubclass() {
+		// skip check
+	}
+
+	// @see org.eclipse.swt.widgets.Tree#createHandle()
+	void createHandle() {
+		// lucky for us, other platforms have a super.createHandle too
+		super.createHandle();
+		//if (explorerTheme) {
+		//	int bits2 = (int)/*64*/OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0);
+		//	bits2 &= ~OS.TVS_EX_FADEINOUTEXPANDOS;
+		//	OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, 0, bits2);
+		//}
+
+		try {
+			Class<?> claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
+
+			int TVM_GETEXTENDEDSTYLE = ((Number) claOS.getField(
+					"TVM_GETEXTENDEDSTYLE").get(null)).intValue();
+			int TVM_SETEXTENDEDSTYLE = ((Number) claOS.getField(
+					"TVM_SETEXTENDEDSTYLE").get(null)).intValue();
+			int TVS_EX_FADEINOUTEXPANDOS = ((Number) claOS.getField(
+					"TVS_EX_FADEINOUTEXPANDOS").get(null)).intValue();
+
+			Field fldHandle = this.getClass().getField("handle");
+			Class<?> handleType = fldHandle.getType();
+			if (handleType == int.class) {
+				Method methSendMessage = claOS.getMethod("SendMessage", int.class,
+						int.class, int.class, int.class);
+				Number nbits2 = (Number) methSendMessage.invoke(null,
+						fldHandle.get(this), TVM_GETEXTENDEDSTYLE, 0, 0);
+				int bits2 = nbits2.intValue() & (~TVS_EX_FADEINOUTEXPANDOS);
+
+				methSendMessage.invoke(null, ((Number) fldHandle.get(this)).intValue(),
+						TVM_SETEXTENDEDSTYLE, 0, bits2);
+			} else {
+				Method methSendMessage = claOS.getMethod("SendMessage", long.class,
+						int.class, long.class, long.class);
+
+				Number nbits2 = (Number) methSendMessage.invoke(null,
+						fldHandle.get(this), TVM_GETEXTENDEDSTYLE, 0, 0);
+				long bits2 = nbits2.longValue() & (~TVS_EX_FADEINOUTEXPANDOS);
+
+				methSendMessage.invoke(null,
+						((Number) fldHandle.get(this)).longValue(), TVM_SETEXTENDEDSTYLE,
+						0, bits2);
+			}
+
+		} catch (Throwable t) {
+			t.printStackTrace();
+		}
+	}
+
+	int widgetStyle() {
+		/* I was going to go with this code, but OSX doesn't ahve widgetStyle,
+		    so compliling breaks on super call
+		int oldStyle = super.widgetStyle();
+		try {
+			Class<?> claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
+			// & ~(OS.TVS_LINESATROOT | OS.TVS_HASBUTTONS)
+			if (claOS != null) {
+				int TVS_LINESATROOT = ((Number)claOS.getField("TVS_LINESATROOT").get(null)).intValue();
+				int TVS_HASBUTTONS = ((Number)claOS.getField("TVS_HASBUTTONS").get(null)).intValue();
+				oldStyle &= ~(TVS_HASBUTTONS | TVS_LINESATROOT);
+			}
+		} catch (Throwable e) {
+		}
+		return oldStyle;
+		*/
+
+		if (!Constants.isWindows) {
+			return 0;
+		}
+
+		try {
+			Integer widgetStyle = mapStyleToWidgetStyle.get(style);
+			if (widgetStyle != null) {
+				return widgetStyle.intValue();
+			}
+
+			Tree tree = new Tree(parent, style);
+			Method method = Tree.class.getDeclaredMethod("widgetStyle");
+			method.setAccessible(true);
+			int oldStyle = ((Number) method.invoke(tree)).intValue();
+			tree.dispose();
+
+			Class<?> claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
+			// & ~(OS.TVS_LINESATROOT | OS.TVS_HASBUTTONS)
+			if (claOS != null) {
+				int TVS_LINESATROOT = ((Number) claOS.getField("TVS_LINESATROOT").get(
+						null)).intValue();
+				int TVS_HASBUTTONS = ((Number) claOS.getField("TVS_HASBUTTONS").get(
+						null)).intValue();
+				oldStyle &= ~(TVS_HASBUTTONS | TVS_LINESATROOT);
+			}
+			mapStyleToWidgetStyle.put(style, oldStyle);
+			return oldStyle;
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+
+		return 0;
+	}
+}
diff --git a/org/gudy/azureus2/core3/category/Category.java b/org/gudy/azureus2/core3/category/Category.java
index 89ba9bf..c43aea2 100644
--- a/org/gudy/azureus2/core3/category/Category.java
+++ b/org/gudy/azureus2/core3/category/Category.java
@@ -21,6 +21,8 @@
 package org.gudy.azureus2.core3.category;
 
 import java.util.List;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
 
 /** A Category for grouping torrents (DownloadManagers)
@@ -62,7 +64,7 @@ public interface Category {
   /** Retrieve a list of DownloadManagers for this category
    * @return DownloadManager List
    */  
-  public List getDownloadManagers(List all_download_managers);
+  public List<DownloadManager> getDownloadManagers(List<DownloadManager> all_download_managers);
   
   /** Add a DownloadManager to this category.
    *
@@ -97,4 +99,35 @@ public interface Category {
   
   public int
   getUploadSpeed();
+  
+  public static final String AT_AUTO_TRANSCODE_TARGET 	= "at_att";
+  public static final String AT_RSS_GEN					= "at_rss_gen";
+  public static final String AT_UPLOAD_PRIORITY			= "at_up_pri";
+  
+  public String
+  getStringAttribute(
+	String		name );
+  
+  public void
+  setStringAttribute(
+	String		name,
+	String		value );
+  
+  public boolean
+  getBooleanAttribute(
+	String		name );
+  
+  public void
+  setBooleanAttribute(
+	String		name,
+	boolean		value );
+  
+  public int
+  getIntAttribute(
+	String		name );
+  
+  public void
+  setIntAttribute(
+	String		name,
+	int			value );
 }
diff --git a/org/gudy/azureus2/core3/category/CategoryManagerListener.java b/org/gudy/azureus2/core3/category/CategoryManagerListener.java
index 516c882..c58e0ad 100644
--- a/org/gudy/azureus2/core3/category/CategoryManagerListener.java
+++ b/org/gudy/azureus2/core3/category/CategoryManagerListener.java
@@ -44,4 +44,8 @@ CategoryManagerListener
 	public void
 	categoryRemoved(
 		Category category );
+	
+	public void
+	categoryChanged(
+		Category category );
 }
diff --git a/org/gudy/azureus2/core3/category/impl/CategoryImpl.java b/org/gudy/azureus2/core3/category/impl/CategoryImpl.java
index 6e8bcbb..af67ee7 100644
--- a/org/gudy/azureus2/core3/category/impl/CategoryImpl.java
+++ b/org/gudy/azureus2/core3/category/impl/CategoryImpl.java
@@ -23,6 +23,7 @@ package org.gudy.azureus2.core3.category.impl;
 
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.category.Category;
 import org.gudy.azureus2.core3.category.CategoryListener;
@@ -35,11 +36,13 @@ import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 public class CategoryImpl implements Category, Comparable {
   private String sName;
   private int type;
-  private List managers = new ArrayList();
+  private List<DownloadManager> managers = new ArrayList<DownloadManager>();
 
   private int upload_speed;
   private int download_speed;
 
+  private final Map<String,String>	attributes;
+  
   private LimitedRateGroup upload_limiter = 
 	  new LimitedRateGroup()
 	  {
@@ -90,16 +93,18 @@ public class CategoryImpl implements Category, Comparable {
 			}
 		});
 
-  public CategoryImpl(String sName, int maxup, int maxdown ) {
+  public CategoryImpl(String sName, int maxup, int maxdown, Map<String,String> _attributes ) {
     this.sName = sName;
     this.type = Category.TYPE_USER;
     upload_speed	= maxup;
     download_speed	= maxdown;
+    attributes = _attributes;
   }
 
-  public CategoryImpl(String sName, int type) {
+  public CategoryImpl(String sName, int type, Map<String,String> _attributes) {
     this.sName = sName;
     this.type = type;
+    attributes = _attributes;
   }
 
 	public void addCategoryListener(CategoryListener l) {
@@ -118,15 +123,15 @@ public class CategoryImpl implements Category, Comparable {
     return type;
   }
   
-  public List getDownloadManagers(List all_dms) {
+  public List<DownloadManager> getDownloadManagers(List<DownloadManager> all_dms) {
 	  if ( type == Category.TYPE_USER ){
 		  return managers;
-	  }else if ( type == Category.TYPE_ALL ){
+	  }else if ( type == Category.TYPE_ALL || all_dms == null ){
 		  return all_dms;
 	  }else{
-		  List result = new ArrayList();
+		  List<DownloadManager> result = new ArrayList<DownloadManager>();
 		  for (int i=0;i<all_dms.size();i++){
-			  DownloadManager dm = (DownloadManager)all_dms.get(i);
+			  DownloadManager dm = all_dms.get(i);
 			  Category cat = dm.getDownloadState().getCategory();
 			  if ( cat == null || cat.getType() == Category.TYPE_UNCATEGORIZED){
 				  result.add( dm );
@@ -138,7 +143,9 @@ public class CategoryImpl implements Category, Comparable {
   }
   
   public void addManager(DownloadManagerState manager_state) {
-    if (manager_state.getCategory() != this) {
+  	Category manager_cat = manager_state.getCategory();
+		if ((type != Category.TYPE_UNCATEGORIZED && manager_cat != this)
+				|| (type == Category.TYPE_UNCATEGORIZED && manager_cat != null)) {
     	manager_state.setCategory(this);
       // we will be called again by CategoryManager.categoryChange
       return;
@@ -152,11 +159,25 @@ public class CategoryImpl implements Category, Comparable {
     }
     
     if (!managers.contains(manager)) {
-      managers.add(manager);
+    	if (type == Category.TYPE_USER) {
+    		managers.add(manager);
+    	}
       
       manager.addRateLimiter( upload_limiter, true );
       manager.addRateLimiter( download_limiter, false );
       
+      int pri = getIntAttribute( AT_UPLOAD_PRIORITY, -1 );
+      
+      if ( pri >= 0 ){
+    	  
+    	  	// another call-during-construction issue to avoid here
+    	  
+    	  if ( manager.getDownloadState() != null ){
+    	  
+    		  manager.setUploadPriority( pri );
+    	  }
+      }
+      
       category_listeners.dispatch(LDT_CATEGORY_DMADDED, manager);
     }
   }
@@ -174,12 +195,24 @@ public class CategoryImpl implements Category, Comparable {
     	return;
     }
     
-    if (managers.contains(manager) || type != Category.TYPE_USER) {
+    if (type != Category.TYPE_USER || managers.contains(manager)) {
       managers.remove(manager);
       
       manager.removeRateLimiter( upload_limiter, true );
       manager.removeRateLimiter( download_limiter, false );
  
+      int pri = getIntAttribute( AT_UPLOAD_PRIORITY, -1 );
+      
+      if ( pri >= 0 ){
+    	  
+    	  	// another call-during-construction issue to avoid here
+    	  
+    	  if ( manager.getDownloadState() != null ){
+    	  
+    		  manager.setUploadPriority( 0 );
+    	  }
+      }
+      
       category_listeners.dispatch( LDT_CATEGORY_DMREMOVED, manager );
     }
   }
@@ -192,7 +225,7 @@ public class CategoryImpl implements Category, Comparable {
 		  
 		  download_speed = speed;
 		  
-		  CategoryManagerImpl.getInstance().saveCategories();
+		  CategoryManagerImpl.getInstance().saveCategories(this);
 	  }
   }
   
@@ -210,7 +243,7 @@ public class CategoryImpl implements Category, Comparable {
 		  
 		  upload_speed	= speed;
 	  
-		  CategoryManagerImpl.getInstance().saveCategories();
+		  CategoryManagerImpl.getInstance().saveCategories(this);
 	  }
   }
   
@@ -220,6 +253,107 @@ public class CategoryImpl implements Category, Comparable {
 	  return( upload_speed );
   }
   
+  protected void
+  setAttributes(
+	Map<String,String> a )
+  {
+	  attributes.clear();
+	  attributes.putAll( a );
+  }
+  
+  protected Map<String,String>
+  getAttributes()
+  {
+	  return( attributes );
+  }
+  
+  public String
+  getStringAttribute(
+	String		name )
+  {
+	  return( attributes.get(name));
+  }
+  
+  public void
+  setStringAttribute(
+	String		name,
+	String		value )
+  {
+	  String old = attributes.put( name, value );
+	  
+	  if ( old == null || !old.equals( value )){
+	  
+		  CategoryManagerImpl.getInstance().saveCategories(this);
+	  }
+
+  }
+  
+  public int
+  getIntAttribute(
+	String		name )
+  {
+	  return( getIntAttribute( name, 0 ));
+  }
+  
+  private int
+  getIntAttribute(
+	String		name,
+	int			def )
+  {
+	 String str = getStringAttribute( name );
+	 
+	 if ( str == null ){
+		 return( def );
+	 }
+	 return( Integer.parseInt( str ));
+  }
+  
+  public void
+  setIntAttribute(
+	String		name,
+	int			value )
+  {
+	  String	str_val = String.valueOf( value );
+	  
+	  String old = attributes.put( name, str_val );
+	  
+	  if ( old == null || !old.equals( value )){
+	  
+		  if ( name.equals( AT_UPLOAD_PRIORITY )){
+			  
+			  for ( DownloadManager dm: managers ){
+				  
+				  dm.setUploadPriority( value );
+			  }
+		  }
+		  
+		  CategoryManagerImpl.getInstance().saveCategories(this);
+	  }
+
+  }
+  public boolean
+  getBooleanAttribute(
+	String		name )
+  {
+	 String str = getStringAttribute( name );
+	 
+	 return( str != null && str.equals( "true" ));
+  }
+  
+  public void
+  setBooleanAttribute(
+	String		name,
+	boolean		value )
+  {
+	  String old = attributes.put( name, value?"true":"false" );
+	  
+	  if ( old == null || !old.equals( value )){
+	  
+		  CategoryManagerImpl.getInstance().saveCategories(this);
+	  }
+
+  }
+  
   public int compareTo(Object b)
   {
     boolean aTypeIsUser = type == Category.TYPE_USER;
diff --git a/org/gudy/azureus2/core3/category/impl/CategoryManagerImpl.java b/org/gudy/azureus2/core3/category/impl/CategoryManagerImpl.java
index 99765ad..e10867b 100644
--- a/org/gudy/azureus2/core3/category/impl/CategoryManagerImpl.java
+++ b/org/gudy/azureus2/core3/category/impl/CategoryManagerImpl.java
@@ -21,35 +21,69 @@
 
 package org.gudy.azureus2.core3.category.impl;
 
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Map;
 import java.util.Iterator;
 import java.util.HashMap;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.TreeMap;
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Array;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
 
 import org.gudy.azureus2.core3.category.*;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+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.internat.MessageText;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.xml.util.XMLEscapeWriter;
+import org.gudy.azureus2.core3.xml.util.XUXmlWriter;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
+import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageRequest;
+import org.gudy.azureus2.plugins.tracker.web.TrackerWebPageResponse;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 
-public class CategoryManagerImpl  {
-  private static final String UNCAT_NAME = "__uncategorised__";
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.rssgen.RSSGeneratorPlugin;
+
+public class 
+CategoryManagerImpl 
+	implements RSSGeneratorPlugin.Provider 
+{
+  private static final String PROVIDER = "categories";
+
+  private static final String UNCAT_NAME 	= "__uncategorised__";
+  private static final String ALL_NAME 		= "__all__";
   
   private static CategoryManagerImpl catMan;
-  private static Category catAll = null;
-  private static Category catUncategorized = null;
+  private static CategoryImpl catAll = null;
+  private static CategoryImpl catUncategorized = null;
   private static boolean doneLoading = false;
   private static AEMonitor	class_mon	= new AEMonitor( "CategoryManager:class" );
   
-  private Map categories 			= new HashMap();
+  private Map<String,CategoryImpl> categories 			= new HashMap<String,CategoryImpl>();
   private AEMonitor	categories_mon	= new AEMonitor( "Categories" );
   
   private static final int LDT_CATEGORY_ADDED     = 1;
   private static final int LDT_CATEGORY_REMOVED   = 2;
+  private static final int LDT_CATEGORY_CHANGED   = 3;
   private ListenerManager category_listeners = ListenerManager.createManager(
     "CatListenDispatcher",
     new ListenerManagerDispatcher()
@@ -64,8 +98,10 @@ public class CategoryManagerImpl  {
         if ( type == LDT_CATEGORY_ADDED )
           target.categoryAdded((Category)value);
         else if ( type == LDT_CATEGORY_REMOVED )
-          target.categoryRemoved((Category)value);
-      }
+            target.categoryRemoved((Category)value);
+        else if ( type == LDT_CATEGORY_CHANGED )
+            target.categoryChanged((Category)value);
+        }
     });
 
 
@@ -122,18 +158,31 @@ public class CategoryManagerImpl  {
           
           Long l_maxup 		= (Long)mCategory.get( "maxup" );
           Long l_maxdown 	= (Long)mCategory.get( "maxdown" );
+          Map<String,String>	attributes = BDecoder.decodeStrings((Map)mCategory.get( "attr" ));
+          
+          if ( attributes == null ){
+        	  
+        	  attributes = new HashMap<String, String>();
+          }
           
           if ( catName.equals( UNCAT_NAME )){
         	  
         	  catUncategorized.setUploadSpeed(l_maxup==null?0:l_maxup.intValue());
         	  catUncategorized.setDownloadSpeed(l_maxdown==null?0:l_maxdown.intValue());
+        	  catUncategorized.setAttributes( attributes );
+        	  
+          }else if ( catName.equals( ALL_NAME )){
+            	  
+              catAll.setAttributes( attributes );
+
           }else{
 	          categories.put( 
 	        	catName,
 	        	  new CategoryImpl( 
 	        		  catName, 
 	        		  l_maxup==null?0:l_maxup.intValue(),
-	        		  l_maxdown==null?0:l_maxdown.intValue()));
+	        		  l_maxdown==null?0:l_maxdown.intValue(),
+	        			attributes ));
           }
         }
         catch (UnsupportedEncodingException e1) {
@@ -158,25 +207,33 @@ public class CategoryManagerImpl  {
           fin.close();
       }
       catch (Exception e) {}
+      
+      checkConfig();
     }
   }
 
-  public void saveCategories() {
+  protected void saveCategories(Category category ){
+	  saveCategories();
+	  
+      category_listeners.dispatch( LDT_CATEGORY_CHANGED, category );
+  }
+  protected void saveCategories() {
     try{
     	categories_mon.enter();
     
       Map map = new HashMap();
       List list = new ArrayList(categories.size());
 
-      Iterator iter = categories.values().iterator();
+      Iterator<CategoryImpl> iter = categories.values().iterator();
       while (iter.hasNext()) {
-        Category cat = (Category) iter.next();
+        CategoryImpl cat = iter.next();
 
         if (cat.getType() == Category.TYPE_USER) {
           Map catMap = new HashMap();
           catMap.put( "name", cat.getName());
           catMap.put( "maxup", new Long(cat.getUploadSpeed()));
           catMap.put( "maxdown", new Long(cat.getDownloadSpeed()));
+          catMap.put( "attr", cat.getAttributes());
           list.add(catMap);
         }
       }
@@ -185,8 +242,14 @@ public class CategoryManagerImpl  {
       uncat.put( "name", UNCAT_NAME );
       uncat.put( "maxup", new Long(catUncategorized.getUploadSpeed()));
       uncat.put( "maxdown", new Long(catUncategorized.getDownloadSpeed()));
+      uncat.put( "attr", catUncategorized.getAttributes());
       list.add( uncat );
       
+      Map allcat = new HashMap();
+      allcat.put( "name", ALL_NAME );
+      allcat.put( "attr", catAll.getAttributes());
+      list.add( allcat );
+      
       map.put("categories", list);
 
 
@@ -227,15 +290,18 @@ public class CategoryManagerImpl  {
         catch (Exception e) {}
       }
     }finally{
+    	
+    	checkConfig();
+    	 
     	categories_mon.exit();
     }
   }
 
   public Category createCategory(String name) {
     makeSpecialCategories();
-    Category newCategory = getCategory(name);
+    CategoryImpl newCategory = getCategory(name);
     if (newCategory == null) {
-      newCategory = new CategoryImpl(name, 0, 0);
+      newCategory = new CategoryImpl(name, 0, 0, new HashMap<String,String>());
       categories.put(name, newCategory);
       saveCategories();
 
@@ -259,8 +325,8 @@ public class CategoryManagerImpl  {
     return (new Category[0]);
   }
 
-  public Category getCategory(String name) {
-    return (Category)categories.get(name);
+  public CategoryImpl getCategory(String name) {
+    return categories.get(name);
   }
 
   public Category getCategory(int type) {
@@ -273,13 +339,294 @@ public class CategoryManagerImpl  {
 
   private void makeSpecialCategories() {
     if (catAll == null) {
-      catAll = new CategoryImpl("Categories.all", Category.TYPE_ALL);
+      catAll = new CategoryImpl("Categories.all", Category.TYPE_ALL, new HashMap<String,String>());
       categories.put("Categories.all", catAll);
     }
     
     if (catUncategorized == null) {
-      catUncategorized = new CategoryImpl("Categories.uncategorized", Category.TYPE_UNCATEGORIZED);
+      catUncategorized = new CategoryImpl("Categories.uncategorized", Category.TYPE_UNCATEGORIZED, new HashMap<String,String>());
       categories.put("Categories.uncategorized", catUncategorized);
     }
   }
+  
+  
+  
+  private void
+  checkConfig()
+  {
+	  boolean	gen_enabled = false;
+	  
+	  for ( CategoryImpl cat: categories.values()){
+		  
+		  if ( cat.getBooleanAttribute( Category.AT_RSS_GEN )){
+			  
+			  gen_enabled = true;
+			  
+			  break;
+		  }
+	  }
+	  
+	  if ( gen_enabled ){
+		  
+		  RSSGeneratorPlugin.registerProvider( PROVIDER, this  );
+		  
+	  }else{
+		  
+		  RSSGeneratorPlugin.unregisterProvider( PROVIDER );
+	  }
+  }
+  
+	public boolean
+	isEnabled()
+	{
+		return( true );
+	}
+
+	public boolean
+	generate(
+		TrackerWebPageRequest		request,
+		TrackerWebPageResponse		response )
+	
+		throws IOException
+	{
+		URL	url	= request.getAbsoluteURL();
+		
+		String path = url.getPath();
+		
+		int	pos = path.indexOf( '?' );
+		
+		if ( pos != -1 ){
+			
+			path = path.substring(0,pos);
+		}
+		
+		path = path.substring( PROVIDER.length()+1);
+
+		XMLEscapeWriter pw = new XMLEscapeWriter( new PrintWriter(new OutputStreamWriter( response.getOutputStream(), "UTF-8" )));
+
+		pw.setEnabled( false );
+		
+		if ( path.length() <= 1 ){
+			
+			response.setContentType( "text/html; charset=UTF-8" );
+			
+			pw.println( "<HTML><HEAD><TITLE>Vuze Category Feeds</TITLE></HEAD><BODY>" );
+			
+			Map<String,String>	lines = new TreeMap<String, String>();
+			
+			List<CategoryImpl>	cats;
+			
+			try{
+				categories_mon.enter();
+
+				cats = new ArrayList<CategoryImpl>( categories.values());
+
+			}finally{
+			
+				categories_mon.exit();
+			}
+			
+			for ( CategoryImpl c: cats ){
+			
+				if ( c.getBooleanAttribute( Category.AT_RSS_GEN )){
+							
+					String	name = getDisplayName( c );
+					
+					String	cat_url = PROVIDER + "/" + URLEncoder.encode( c.getName(), "UTF-8" );
+				
+					lines.put( name, "<LI><A href=\"" + cat_url + "\">" + name + "</A></LI>" );
+				}
+			}
+			
+			for ( String line: lines.values() ){
+				
+				pw.println( line );
+			}
+			
+			pw.println( "</BODY></HTML>" );
+			
+		}else{
+			
+			String	cat_name = URLDecoder.decode( path.substring( 1 ), "UTF-8" );
+			
+			CategoryImpl	cat;
+			
+			try{
+				categories_mon.enter();
+
+				cat = categories.get( cat_name );
+
+			}finally{
+			
+				categories_mon.exit();
+			}
+			
+			if ( cat == null ){
+				
+				response.setReplyStatus( 404 );
+				
+				return( true );
+			}
+			
+			List<DownloadManager> dms = cat.getDownloadManagers( AzureusCoreFactory.getSingleton().getGlobalManager().getDownloadManagers());
+			
+			List<Download> downloads = new ArrayList<Download>( dms.size());
+			
+			long	dl_marker = 0;
+			
+			for ( DownloadManager dm: dms ){
+				
+				TOTorrent torrent = dm.getTorrent();
+				
+				if ( torrent == null ){
+					
+					continue;
+				}
+				
+				if ( !TorrentUtils.isReallyPrivate( torrent )){
+				
+					dl_marker += dm.getDownloadState().getLongParameter( DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME );
+				
+					downloads.add( PluginCoreUtils.wrap(dm));
+				}
+			}
+			
+			String	config_key = "cat.rss.config." + Base32.encode( cat.getName().getBytes( "UTF-8" ));
+			
+			long	old_marker = COConfigurationManager.getLongParameter( config_key + ".marker", 0 );
+			
+			long	last_modified = COConfigurationManager.getLongParameter( config_key + ".last_mod", 0 );
+			
+			long now = SystemTime.getCurrentTime();
+			
+			if ( old_marker == dl_marker ){
+				
+				if ( last_modified == 0 ){
+					
+					last_modified = now;
+				}
+			}else{
+				
+				COConfigurationManager.setParameter( config_key + ".marker", dl_marker );
+				
+				last_modified = now; 
+			}
+			
+			if ( last_modified == now ){
+				
+				COConfigurationManager.setParameter( config_key + ".last_mod", last_modified );
+			}
+			
+			pw.println( "<?xml version=\"1.0\" encoding=\"utf-8\"?>" );
+			
+			pw.println( "<rss version=\"2.0\" xmlns:vuze=\"http://www.vuze.com\">" );
+			
+			pw.println( "<channel>" );
+			
+			pw.println( "<title>" + escape( getDisplayName( cat )) + "</title>" );
+			
+			Collections.sort(
+					downloads,
+				new Comparator<Download>()
+				{
+					public int 
+					compare(
+						Download d1, 
+						Download d2) 
+					{
+						long	added1 = getAddedTime( d1 )/1000;
+						long	added2 = getAddedTime( d2 )/1000;
+		
+						return((int)(added2 - added1 ));
+					}
+				});
+								
+							
+			pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( last_modified ) + "</pubDate>" );
+		
+			for (int i=0;i<downloads.size();i++){
+				
+				Download download = downloads.get( i );
+				
+				DownloadManager	core_download = PluginCoreUtils.unwrap( download );
+				
+				Torrent torrent = download.getTorrent();
+				
+				byte[] hash = torrent.getHash();
+				
+				String	hash_str = Base32.encode( hash );
+				
+				pw.println( "<item>" );
+				
+				pw.println( "<title>" + escape( download.getName()) + "</title>" );
+				
+				pw.println( "<guid>" + hash_str + "</guid>" );
+				
+				String magnet_url = escape( UrlUtils.getMagnetURI( download.getName(), torrent ));
+
+				pw.println( "<link>" + magnet_url + "</link>" );
+				
+				long added = core_download.getDownloadState().getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME);
+				
+				pw.println(	"<pubDate>" + TimeFormatter.getHTTPDate( added ) + "</pubDate>" );
+				
+				pw.println(	"<vuze:size>" + torrent.getSize()+ "</vuze:size>" );
+				pw.println(	"<vuze:assethash>" + hash_str + "</vuze:assethash>" );
+												
+				pw.println( "<vuze:downloadurl>" + magnet_url + "</vuze:downloadurl>" );
+		
+				DownloadScrapeResult scrape = download.getLastScrapeResult();
+				
+				if ( scrape != null && scrape.getResponseType() == DownloadScrapeResult.RT_SUCCESS ){
+					
+					pw.println(	"<vuze:seeds>" + scrape.getSeedCount() + "</vuze:seeds>" );
+					pw.println(	"<vuze:peers>" + scrape.getNonSeedCount() + "</vuze:peers>" );
+				}
+				
+				pw.println( "</item>" );
+			}
+			
+			pw.println( "</channel>" );
+			
+			pw.println( "</rss>" );
+		}
+		 
+		pw.flush();
+		
+		return( true );
+	}
+		
+	private String
+	getDisplayName(
+		CategoryImpl	c )
+	{
+		if ( c == catAll ){
+			
+			return( MessageText.getString( "Categories.all" ));
+			
+		}else if ( c == catUncategorized ){
+			
+			return( MessageText.getString( "Categories.uncategorized" ));
+			
+		}else{
+			
+			return( c.getName());
+		}
+	}
+	
+	protected long
+	getAddedTime(
+		Download	download )
+	{
+		DownloadManager	core_download = PluginCoreUtils.unwrap( download );
+		
+		return( core_download.getDownloadState().getLongParameter(DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME));
+	}
+	
+	protected String
+	escape(
+		String	str )
+	{
+		return( XUXmlWriter.escapeXML(str));
+	}
 }
diff --git a/org/gudy/azureus2/core3/config/COConfigurationManager.java b/org/gudy/azureus2/core3/config/COConfigurationManager.java
index 2d06ce0..6492ce0 100644
--- a/org/gudy/azureus2/core3/config/COConfigurationManager.java
+++ b/org/gudy/azureus2/core3/config/COConfigurationManager.java
@@ -21,10 +21,18 @@
  
 package org.gudy.azureus2.core3.config;
 
+import java.security.AccessControlException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.net.URL;
 
 import org.gudy.azureus2.core3.config.impl.*;
@@ -47,7 +55,7 @@ COConfigurationManager
 	    long mb_1			= 1*1024*1024;
 	    long mb_32			= 32*mb_1;
 	    int size = (int)(( max_mem_bytes - mb_32 )/mb_1);	    
-	    if( size > 1024 )  size = 1024;  //safety check
+	    if( size > 2000 )  size = 2000;  //safety check
       if( size < 1 )  size = 1;
 	    CONFIG_CACHE_SIZE_MAX_MB = size;
 	}
@@ -64,6 +72,101 @@ COConfigurationManager
 			pre_initialised	= true;
 		
 			try{
+				if ( System.getProperty( "azureus.portable.enable", "false" ).equalsIgnoreCase( "true" )){
+				
+					try{
+						if ( File.separatorChar != '\\' ){
+								
+							throw( new Exception( "Portable only supported on Windows" ));
+						}
+						
+						File portable_root;
+							
+						try{
+							portable_root = new File( "." ).getCanonicalFile();
+	
+						}catch( Throwable e ){
+	
+							portable_root = new File( "." ).getAbsoluteFile();
+						}	
+						
+						if ( !portable_root.canWrite()){
+							
+							throw( new Exception( "can't write to " + portable_root ));
+						}
+						
+						File	root_file = new File( portable_root, "portable.dat" );
+						
+						String	str = portable_root.getAbsolutePath();
+
+						if ( str.length() < 2 || str.charAt(1) != ':' ){
+							
+							throw( new Exception( "drive letter missing in '" + str + "'" ));
+						}														
+						
+						String	root_relative = str.substring( 2 );
+							
+						boolean	write_file = true;
+						
+						if ( root_file.exists()){
+							
+							LineNumberReader lnr = new LineNumberReader( new InputStreamReader( new FileInputStream( root_file ), "UTF-8" ));
+							
+							try{
+								String	 line = lnr.readLine();
+								
+								if ( line != null ){
+									
+									line = line.trim();
+									
+									if ( line.equalsIgnoreCase( root_relative )){
+										
+										write_file = false;
+										
+									}else{
+										
+										throw( new Exception( "root changed - old='" + line + "', new='" + root_relative ));
+									}
+								}
+							}finally{
+								
+								lnr.close();
+							}
+						}
+						
+						if ( write_file ){
+							
+							PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream( root_file ), "UTF-8" ));
+							
+							try{
+								pw.println( root_relative );
+								
+							}finally{
+								
+								pw.close();
+							}
+						}
+						
+						System.setProperty( "azureus.install.path", str );
+						System.setProperty( "azureus.config.path", str );
+						
+						System.setProperty( "azureus.portable.root", str );
+						
+						System.out.println( "Portable setup OK - root=" + root_relative + " (current=" + str + ")" );
+						
+					}catch( Throwable e ){
+						
+						System.err.println( "Portable setup failed: " + e.getMessage());
+						
+						System.setProperty( "azureus.portable.enable", "false" );
+					
+						System.setProperty( "azureus.portable.root", "" );
+					}
+				}else{
+					
+					System.setProperty( "azureus.portable.root", "" );	
+				}
+				
 				/*
 			  	String	handlers = System.getProperty( "java.protocol.handler.pkgs" );
 			  	
@@ -117,7 +220,12 @@ COConfigurationManager
 				
 					// can happen in applet
 				
-				e.printStackTrace();
+				if ( e instanceof AccessControlException ){
+					
+				}else{
+				
+					e.printStackTrace();
+				}
 			}
 		}
 	}
@@ -445,13 +553,13 @@ COConfigurationManager
 		ConfigurationManager.getInstance().removeListener( listener );
 	}
   
-  public static Set
+  public static Set<String>
   getAllowedParameters()
   {
   	return ConfigurationDefaults.getInstance().getAllowedParameters();
   }
   
-  public static Set
+  public static Set<String>
   getDefinedParameters()
   {
   	return ConfigurationManager.getInstance().getDefinedParameters();
@@ -560,6 +668,12 @@ COConfigurationManager
 		return ConfigurationManager.getInstance().removeRGBParameter(parameter);
   }
   
+  public static void
+  resetToDefaults()
+  {
+	  ConfigurationManager.getInstance().resetToDefaults();
+  }
+  
   public interface
   ParameterVerifier
   {
diff --git a/org/gudy/azureus2/core3/config/PriorityParameterListener.java b/org/gudy/azureus2/core3/config/PriorityParameterListener.java
new file mode 100644
index 0000000..0173f74
--- /dev/null
+++ b/org/gudy/azureus2/core3/config/PriorityParameterListener.java
@@ -0,0 +1,36 @@
+/*
+ * Created on Jan 28, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.core3.config;
+
+/**
+ * Instances of this will be invoked before any ParameterListeners are. 
+ * The purpose of this is to allow safe caching of parameter values in the light of other
+ * listeners that may use the cached values and hence must be invoked after the cached value
+ * has been updated. Therefore only ever use this type of listener for this purpose!
+ * @author Paul
+ *
+ */
+public interface 
+PriorityParameterListener
+	extends ParameterListener
+{
+}
diff --git a/org/gudy/azureus2/core3/config/impl/ConfigurationChecker.java b/org/gudy/azureus2/core3/config/impl/ConfigurationChecker.java
index 15a1912..ba25d20 100644
--- a/org/gudy/azureus2/core3/config/impl/ConfigurationChecker.java
+++ b/org/gudy/azureus2/core3/config/impl/ConfigurationChecker.java
@@ -331,19 +331,6 @@ ConfigurationChecker
 		    		changed	= true;
 	    		}
 	    	}
-	    	
-	    		// also, if we now have a default data dir enabled (either explicitly or by
-	    		// above migration fix), and there's no value defined for the dir, then
-	    		// set it to what it would have been before the default was changed to blank
-	    	
-	    	if ( 	COConfigurationManager.getBooleanParameter( "Use default data dir" ) &&
-	    			!COConfigurationManager.doesParameterNonDefaultExist( "Default save path" )){	
-	    		
-	    		COConfigurationManager.setParameter( "Default save path", SystemProperties.getUserPath()+"downloads" );
-	    		
-	    		changed	= true;
-	    	}
-	    	
 	    		    	
 	    	//enable Beginner user mode for first time
 	    	if( !COConfigurationManager.doesParameterNonDefaultExist( "User Mode" ) ) {
@@ -450,6 +437,92 @@ ConfigurationChecker
 	    	}
 	    }
 	    
+	    boolean	randomize_ports = COConfigurationManager.getBooleanParameter( "Listen.Port.Randomize.Enable" );
+	    
+	    if ( randomize_ports ){
+	    	
+	    	String	random_range = COConfigurationManager.getStringParameter( "Listen.Port.Randomize.Range" );
+	    	
+	    	if ( random_range == null || random_range.trim().length() == 0 ){
+	    		
+	    		random_range = RandomUtils.LISTEN_PORT_MIN + "-" + RandomUtils.LISTEN_PORT_MAX;
+	    	}
+	    	
+	    	int	min_port = RandomUtils.LISTEN_PORT_MIN;
+	    	int	max_port = RandomUtils.LISTEN_PORT_MAX;
+	    	
+	    	String[] bits = random_range.split( "-" );
+	    	
+	    	boolean valid = bits.length == 2;
+	    		
+	    	if ( valid ){
+	    		
+	    		String	lhs = bits[0].trim();
+	    		
+	    		if ( lhs.length() > 0 ){
+	    			
+	    			try{
+	    				min_port = Integer.parseInt( lhs );
+	    				
+	    			}catch( Throwable e ){
+	    				
+	    				valid = false;
+	    			}
+	    		}
+	    		
+	    		String	rhs = bits[1].trim();
+	    		
+	    		if ( rhs.length() > 0 ){
+	    			
+	    			try{
+	    				max_port = Integer.parseInt( rhs );
+	    				
+	    			}catch( Throwable e ){
+	    				
+	    				valid = false;
+	    			}
+	    		}
+	    	}
+	    	
+	    	if ( valid ){
+	    		
+			    boolean	randomize_together = COConfigurationManager.getBooleanParameter( "Listen.Port.Randomize.Together" );
+		    		
+		    	if ( randomize_together ){
+		    		
+		    		int port = RandomUtils.generateRandomNetworkListenPort( min_port, max_port );
+		    		
+			    	COConfigurationManager.setParameter( "TCP.Listen.Port", port );
+			    	COConfigurationManager.setParameter( "UDP.Listen.Port", port );
+		    		COConfigurationManager.setParameter( "UDP.NonData.Listen.Port", port );
+	
+		    	}else{
+		    		
+			    	int old_udp1 = COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
+			    	int old_udp2 = COConfigurationManager.getIntParameter( "UDP.NonData.Listen.Port" );
+	
+		    		int port1 = RandomUtils.generateRandomNetworkListenPort( min_port, max_port );
+	
+		    		COConfigurationManager.setParameter( "TCP.Listen.Port", port1 );
+		    		
+		    		int port2 = RandomUtils.generateRandomNetworkListenPort( min_port, max_port );
+	
+			    	COConfigurationManager.setParameter( "UDP.Listen.Port", port2 );
+	
+			    	if ( old_udp1 == old_udp2 ){
+			    		
+			    		COConfigurationManager.setParameter( "UDP.NonData.Listen.Port", port2 );
+	
+			    	}else{
+			    		
+			    		int port3 = RandomUtils.generateRandomNetworkListenPort( min_port, max_port );
+	
+			    		COConfigurationManager.setParameter( "UDP.NonData.Listen.Port", port3 );
+			    	}
+		    	}
+	    	}
+	    }
+	    
 	    int	tcp_port = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
 	    
 	    	// reset invalid ports - single-instance socket port and (small) magnet uri listener port range
@@ -615,12 +688,80 @@ ConfigurationChecker
         ConfigurationManager.getInstance().removeParameter( "General_bEnableLanguageUpdate" );
         changed = true;
       }
+	    
+	    // 4511: confirm.delete.content (boolean) changed to tb..confirm.delete.content (long)
+	    final String CFG_CONFIRM_DELETE_CONTENT = "confirm.delete.content";
+	    if (ConfigurationManager.getInstance().doesParameterNonDefaultExist(CFG_CONFIRM_DELETE_CONTENT) ) {
+	    	boolean confirm = COConfigurationManager.getBooleanParameter(CFG_CONFIRM_DELETE_CONTENT);
+				if (!confirm
+						&& !ConfigurationManager.getInstance().doesParameterNonDefaultExist(
+								"tb.confirm.delete.content")) {
+	    		COConfigurationManager.setParameter("tb.confirm.delete.content", 1);
+	    	}
+	    	COConfigurationManager.removeParameter(CFG_CONFIRM_DELETE_CONTENT);
+	    	changed = true;
+	    }
       
 	    if ( FeatureAvailability.isAutoSpeedDefaultClassic()){
 	    
 	    	ConfigurationDefaults.getInstance().addParameter( SpeedManagerImpl.CONFIG_VERSION, 1 );	// 1 == classic, 2 == beta
 	    }
+	    
+	    int check_level = COConfigurationManager.getIntParameter( "config.checker.level", 0 );
+	    
+	    if ( check_level < 1 ){
+	    	
+	    	COConfigurationManager.setParameter( "config.checker.level", 1 );
+	    	
+	    	changed = true;
+	    	
+		    	// initial setting of auto-config for upload slots etc
+		    
+			String[]	params = { 
+					"Max Uploads", 
+					"enable.seedingonly.maxuploads", 
+					"Max Uploads Seeding",
+					"Max.Peer.Connections.Per.Torrent",
+					"Max.Peer.Connections.Per.Torrent.When.Seeding.Enable",
+					"Max.Peer.Connections.Per.Torrent.When.Seeding",
+					"Max.Peer.Connections.Total",
+					"Max Seeds Per Torrent"
+			};
+			
+			boolean	has_been_set = false;
+			
+			for ( String param: params ){
+			
+				if ( COConfigurationManager.doesParameterNonDefaultExist( param )){
+					
+					has_been_set = true;
+					
+					break;
+				}
+			}
+			
+			if ( has_been_set ){
+				
+				COConfigurationManager.setParameter( "Auto Adjust Transfer Defaults", false );
+			}
+	    }
 	
+	    if ( Constants.isOSX && check_level < 2 ){
+	    	
+	    		// turn on piece-reorder mode for osx
+	    	
+	    	COConfigurationManager.setParameter( "config.checker.level", 2 );
+	    	
+	    	changed = true;
+	    	
+	    	if ( !COConfigurationManager.getBooleanParameter( "Zero New" )){
+	    		
+	    		COConfigurationManager.setParameter( "Enable reorder storage mode", true );
+	    	}
+	    }
+	    
+	    // check_level 3 was used temporarily
+	    
 	    if(changed) {
 	      COConfigurationManager.save();
 	    } 
diff --git a/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java b/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
index 952071f..27e7742 100644
--- a/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
+++ b/org/gudy/azureus2/core3/config/impl/ConfigurationDefaults.java
@@ -33,12 +33,17 @@ import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.host.TRHost;
 import org.gudy.azureus2.core3.tracker.server.TRTrackerServer;
-import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.RandomUtils;
+import org.gudy.azureus2.core3.util.SystemProperties;
+
 import com.aelitis.azureus.core.speedmanager.impl.SpeedManagerImpl;
+import com.aelitis.azureus.core.speedmanager.impl.v2.SMConst;
 import com.aelitis.azureus.core.speedmanager.impl.v2.SpeedLimitConfidence;
 import com.aelitis.azureus.core.speedmanager.impl.v2.SpeedLimitMonitor;
 import com.aelitis.azureus.core.speedmanager.impl.v2.SpeedManagerAlgorithmProviderV2;
-import com.aelitis.azureus.core.speedmanager.impl.v2.SMConst;
 
 /**
  *
@@ -129,6 +134,8 @@ public class ConfigurationDefaults {
 
     def.put("Override Ip", "");
     def.put("Enable incremental file creation", FALSE);
+    def.put("Enable reorder storage mode", FALSE);
+    def.put("Reorder storage mode min MB", new Long( 10 ));
     
     def.put("TCP.Listen.Port", new Long( 6881 ));
     def.put("TCP.Listen.Port.Enable", TRUE );
@@ -140,8 +147,11 @@ public class ConfigurationDefaults {
     def.put("HTTP.Data.Listen.Port", new Long( Constants.isWindows?80:8080 ));
     def.put("HTTP.Data.Listen.Port.Override", ZERO);
     def.put("HTTP.Data.Listen.Port.Enable", FALSE );
+    def.put("Listen.Port.Randomize.Enable", FALSE );
+    def.put("Listen.Port.Randomize.Together", TRUE );
+    def.put("Listen.Port.Randomize.Range", RandomUtils.LISTEN_PORT_MIN + "-" + RandomUtils.LISTEN_PORT_MAX );
     
-    def.put("IPV6 Enable Support", Constants.isOSX?FALSE:TRUE );
+    def.put("IPV6 Enable Support", FALSE );
     def.put("IPV6 Prefer Addresses",FALSE);
     	
     def.put("max active torrents", new Long(4));
@@ -150,8 +160,8 @@ public class ConfigurationDefaults {
     def.put("Newly Seeding Torrents Get First Priority", TRUE);
     
     def.put("Max.Peer.Connections.Per.Torrent", new Long(COConfigurationManager.CONFIG_DEFAULT_MAX_CONNECTIONS_PER_TORRENT));
-    def.put("Max.Peer.Connections.Per.Torrent.When.Seeding", new Long(COConfigurationManager.CONFIG_DEFAULT_MAX_CONNECTIONS_PER_TORRENT));
-    def.put("Max.Peer.Connections.Per.Torrent.When.Seeding.Enable", FALSE );
+    def.put("Max.Peer.Connections.Per.Torrent.When.Seeding", new Long(COConfigurationManager.CONFIG_DEFAULT_MAX_CONNECTIONS_PER_TORRENT/2));
+    def.put("Max.Peer.Connections.Per.Torrent.When.Seeding.Enable", TRUE );
     def.put("Max.Peer.Connections.Total", new Long(COConfigurationManager.CONFIG_DEFAULT_MAX_CONNECTIONS_GLOBAL));
 
     def.put( "Peer.Fast.Initial.Unchoke.Enabled", FALSE );
@@ -186,9 +196,14 @@ public class ConfigurationDefaults {
     def.put( "AutoSpeed Forced Min KBs", new Long(4));
     def.put( "Auto Upload Speed Debug Enabled", FALSE );
     
+    def.put( "Auto Adjust Transfer Defaults", TRUE );	// modified by config checker if user has set own values
+    
+    def.put( "Bias Upload Enable", TRUE );
+    def.put( "Bias Upload Slack KBs", new Long( 5 ));
+    def.put( "Bias Upload Handle No Limit", TRUE );
+    
     def.put( "ASN Autocheck Performed Time", ZERO );
 
-    
     def.put( "LAN Speed Enabled", TRUE );
     def.put( "Max LAN Download Speed KBs", ZERO );
     def.put( "Max LAN Upload Speed KBs", ZERO );
@@ -203,6 +218,8 @@ public class ConfigurationDefaults {
     def.put("Seeding Piece Check Recheck Enable", TRUE );
     def.put("priorityExtensions", "");
     def.put("priorityExtensionsIgnoreCase", FALSE);
+    def.put("quick.view.exts", ".nfo;.txt;.rar" );
+    def.put("quick.view.maxkb", new Long( 64 ));
     
     def.put("Rename Incomplete Files", FALSE );
     def.put("Rename Incomplete Files Extension", ".az!" );
@@ -216,20 +233,36 @@ public class ConfigurationDefaults {
     def.put("Ip Filter Banning Persistent", TRUE);
     def.put("Ip Filter Enable Description Cache", TRUE);
     def.put("Ip Filter Autoload File", "");
+    def.put("Ip Filter Clear On Reload", TRUE );
+    
     def.put("Allow Same IP Peers",FALSE);
     def.put("Use Super Seeding",FALSE);
+    
+    def.put("Start On Login", FALSE );
+    def.put("Start In Low Resource Mode", FALSE );
     def.put("Pause Downloads On Exit", FALSE );
     def.put("Resume Downloads On Start", FALSE );
-        
+    def.put("On Downloading Complete Do", "Nothing" );
+    def.put("On Seeding Complete Do", "Nothing" );
+    def.put("Stop Triggers Auto Reset", TRUE );
+    def.put("Prevent Sleep Downloading", TRUE );
+    def.put("Prevent Sleep FP Seeding", FALSE );
+    
     // SWT GUI Settings
     
     def.put("User Mode", ZERO);
     
     //default data location options
     def.put("Use default data dir", FALSE);	
-		String docPath =  SystemProperties.getDocPath();
-		File f = new File(docPath, "Azureus Downloads");
-		def.put("Default save path", f.getAbsolutePath());
+	String docPath =  SystemProperties.getDocPath();
+	File f = new File(docPath, "Azureus Downloads");
+	
+		// switch to Vuze Downloads for new installs
+	if ( !f.exists()){
+		f = new File(docPath, "Vuze Downloads");
+	}
+	
+	def.put("Default save path", f.getAbsolutePath());
     
     def.put("update.start",TRUE);
     def.put("update.periodic",TRUE);
@@ -303,8 +336,6 @@ public class ConfigurationDefaults {
     def.put( "Popup File Finished", FALSE);
     def.put( "Popup Download Added", FALSE);
     def.put( "Show Timestamp For Alerts", FALSE);
-    def.put( "Use Message Box For Popups", FALSE);
-    def.put( "Suppress Alerts", FALSE);
     
     //default torrent directory option
     def.put( "Save Torrent Files", TRUE );
@@ -336,6 +367,7 @@ public class ConfigurationDefaults {
 	def.put( "Tracker Client Min Announce Interval", ZERO);
 	def.put( "Tracker Client Numwant Limit", new Long(100));
 	def.put( "Tracker Client No Port Announce", FALSE);
+	def.put( "Tracker Client Exclude LAN", TRUE);
 	
     def.put( "Tracker Public Enable", FALSE );
     def.put( "Tracker Log Enable", FALSE );
@@ -428,7 +460,6 @@ public class ConfigurationDefaults {
     def.put( "confirmationOnExit", FALSE );
     def.put( "locale", Locale.getDefault().toString() );
     def.put( "locale.set.complete.count", ZERO);
-    def.put( "Confirm Data Delete", TRUE );
     def.put( "Password Confirm", null );
     def.put( "Auto Update", TRUE );
     def.put( "Alert on close", FALSE );
@@ -436,6 +467,8 @@ public class ConfigurationDefaults {
     def.put( "diskmanager.hashchecking.smallestfirst", TRUE );    
     def.put( "Default Start Torrents Stopped", FALSE);
     def.put( "Server Enable UDP", TRUE); // this actually means the UDP tracker client
+    def.put( "Tracker UDP Probe Enable", TRUE );
+    def.put( "Tracker Client Enable TCP", TRUE );
     def.put( "diskmanager.perf.cache.enable", TRUE);
     def.put( "diskmanager.perf.cache.enable.read", FALSE);
     def.put( "diskmanager.perf.cache.enable.write", TRUE);
@@ -471,8 +504,12 @@ public class ConfigurationDefaults {
     def.put( "config.style.table.defaultSortOrder", ZERO);
     def.put( "Ignore.peer.ports", "0" );
     def.put( "Security.JAR.tools.dir", "" );
-    def.put( "network.max.simultaneous.connect.attempts", new Long( Constants.isWindows?8:24 ));
+    
+    boolean	tcp_half_open_limited = Constants.isWindows && !(Constants.isWindowsVistaSP2OrHigher || Constants.isWindows7OrHigher );
+    
+    def.put( "network.max.simultaneous.connect.attempts", new Long( tcp_half_open_limited?8:24 ));
     def.put( "network.tcp.max.connections.outstanding", new Long( 2048 ));
+    def.put( "network.tcp.connect.outbound.enable", TRUE );  
     def.put( "network.tcp.mtu.size", new Long(1500) );
     def.put( "network.udp.mtu.size", new Long(1500) );
     def.put( "network.tcp.socket.SO_SNDBUF", ZERO );
@@ -489,8 +526,6 @@ public class ConfigurationDefaults {
     def.put( "network.control.read.processor.count", new Long(1));
     def.put( "network.control.write.processor.count", new Long(1));
     def.put( "peermanager.schedule.time", new Long(100));
-    def.put( "confirm_torrent_removal", FALSE );
-    def.put( "add_torrents_silently", FALSE );
     def.put( "enable_small_osx_fonts", TRUE );
     def.put( "Play Download Finished Announcement", FALSE);
     def.put( "Play Download Finished Announcement Text", "Download Complete");
@@ -548,6 +583,14 @@ public class ConfigurationDefaults {
     def.put("MyTorrentsView.menu.show_parent_folder_enabled", FALSE);
     def.put("FileBrowse.usePathFinder", FALSE);
     	
+    def.put( "Beta Programme Enabled", FALSE );
+    def.put( "def.deletetorrent", TRUE );
+    def.put( "tb.confirm.delete.content", Long.valueOf(0) ); // 0=ask; 1=delete content; 2=delete torrent
+    
+    def.put( "br.backup.auto.enable", FALSE );
+    def.put( "br.backup.auto.everydays", 1L );
+    def.put( "br.backup.auto.retain", 5L );
+    
     //temp section for SpeedManagerAlgorithmProviderV2
     
     try{
@@ -668,7 +711,7 @@ public class ConfigurationDefaults {
   	return def.get(key);
   }
   
-  public Set getAllowedParameters() {
+  public Set<String> getAllowedParameters() {
   	return def.keySet();
   }
  
diff --git a/org/gudy/azureus2/core3/config/impl/ConfigurationManager.java b/org/gudy/azureus2/core3/config/impl/ConfigurationManager.java
index fe88654..302915c 100644
--- a/org/gudy/azureus2/core3/config/impl/ConfigurationManager.java
+++ b/org/gudy/azureus2/core3/config/impl/ConfigurationManager.java
@@ -40,19 +40,19 @@ public class
 ConfigurationManager 
 	implements AEDiagnosticsEvidenceGenerator
 {
+  private static final boolean DEBUG_PARAMETER_LISTENERS = false;
+  
   private static ConfigurationManager 	config_temp = null;
   private static ConfigurationManager 	config 		= null;
   private static AEMonitor				class_mon	= new AEMonitor( "ConfigMan:class" );
  
 		  
-  private Map propertiesMap;	// leave this NULL - it picks up errors caused by initialisation sequence errors
+  private Map<String,Object> propertiesMap;	// leave this NULL - it picks up errors caused by initialisation sequence errors
   private List transient_properties     = new ArrayList();
   
-  private List		listeners 			= new ArrayList();
-  private Hashtable parameterListeners 	= new Hashtable();
-  
-  private AEMonitor	this_mon	= new AEMonitor( "ConfigMan");
-  
+  private List<COConfigurationListener>		listenerz 			= new ArrayList<COConfigurationListener>();
+  private Map<String,ParameterListener[]> 	parameterListenerz 	= new HashMap<String,ParameterListener[]>();
+    
   private static FrequencyLimitedDispatcher dirty_dispatcher = 
 	  new FrequencyLimitedDispatcher(
 			  new AERunnable()
@@ -206,6 +206,22 @@ ConfigurationManager
   
   public void load() {
     load("azureus.config");
+    
+    try {
+      String[] keys = propertiesMap.keySet().toArray(new String[0]);
+      for (String key : keys) {
+      	if (key == null) {
+      		continue;
+      	}
+  			if (key.startsWith("SideBar.Expanded.Category.") || key.startsWith("NameColumn.wrapText.")) {
+  				removeParameter(key);
+  			}
+  		}
+    } catch (Exception e) {
+    	// not sure if I can do Debug.out here.. could be in that evil
+    	// preinitialization loop of dooom
+    	e.printStackTrace();
+    }
   }
   
   public void save(String filename) 
@@ -232,16 +248,11 @@ ConfigurationManager
 	
   	FileUtil.writeResilientConfigFile( filename, properties_clone );
     
-  	List	listeners_copy;
+  	List<COConfigurationListener>	listeners_copy;
   	
-    try{
-    	this_mon.enter();
+  	synchronized( listenerz ){
     
-    	listeners_copy = new ArrayList( listeners );
-    	
-    }finally{
-    	
-    	this_mon.exit();
+    	listeners_copy = new ArrayList<COConfigurationListener>( listenerz );
     }
     
 	for (int i=0;i<listeners_copy.size();i++){
@@ -280,10 +291,10 @@ ConfigurationManager
 		return( ConfigurationChecker.isNewInstall());
 	}
 	
-	public Set
+	public Set<String>
 	getDefinedParameters()
 	{
-		return( propertiesMap.keySet());
+		return( new HashSet<String>( propertiesMap.keySet()));
 	}
 	
   public boolean getBooleanParameter(String parameter, boolean defaultValue) {
@@ -756,78 +767,176 @@ ConfigurationManager
     return false;
   }
     
-  private void notifyParameterListeners(String parameter) {
-		LightHashSet parameterListener = (LightHashSet) parameterListeners.get(parameter);
-		if (parameterListener == null) {
+  public void
+  resetToDefaults()
+  {
+	  ConfigurationDefaults def = ConfigurationDefaults.getInstance();
+	  
+	  List<String> def_names = new ArrayList<String>((Set<String>)def.getAllowedParameters());
+	  
+	  for ( String s: def_names ){
+	  
+		  if ( propertiesMap.remove( s ) != null ){
+			 
+			  notifyParameterListeners( s );
+		  }
+	  }
+	  
+	  save();
+  }
+  
+  private void 
+  notifyParameterListeners(
+		String parameter) 
+  {
+	  	ParameterListener[] listeners;
+		
+		synchronized( parameterListenerz ){
+			 
+			 listeners = parameterListenerz.get(parameter);
+		}
+		
+		if ( listeners == null ){
 			return;
 		}
 
-		for (Iterator it = parameterListener.iterator(); it.hasNext();) {
-			ParameterListener listener = (ParameterListener) it.next();
+		for ( ParameterListener listener: listeners ) {
 
-			if (listener != null) {
-				try {
-					listener.parameterChanged(parameter);
-				} catch (Throwable e) {
-					// we're not synchronized so possible but unlikely error here
+			if ( listener != null ){
+				
+				try{
+					listener.parameterChanged( parameter );
+					
+				}catch (Throwable e) {
+					
 					Debug.printStackTrace(e);
 				}
 			}
 		}
 	}
 
-  public void addParameterListener(String parameter, ParameterListener listener){
-  	try{
-  		this_mon.enter();
-  	
-	    if(parameter == null || listener == null)
+  public void 
+  addParameterListener(
+	String 				parameter, 
+	ParameterListener 	new_listener )
+  {
+    if ( parameter == null || new_listener == null ){
+	    	
 	      return;
-	    LightHashSet parameterListener = (LightHashSet) parameterListeners.get(parameter);
-	    if(parameterListener == null) {
-	      parameterListeners.put(parameter, parameterListener = new LightHashSet(1));
+    }
+		    
+	  synchronized( parameterListenerz ){
+  	
+	    ParameterListener[] listeners = parameterListenerz.get( parameter );
+	    
+	    if ( listeners == null ){
+	    		     
+	    	parameterListenerz.put(parameter, new ParameterListener[]{ new_listener } );
+	    	
+	    }else{
+	    
+	    	ParameterListener[]	new_listeners = new ParameterListener[ listeners.length + 1 ];
+	    	
+	    	int	pos;
+	    	
+	    	if ( new_listener instanceof PriorityParameterListener ){
+	    		
+	    		new_listeners[0] = new_listener;
+	    		
+	    		pos = 1;
+	    		
+	    	}else{
+	    		
+	    		new_listeners[ listeners.length ] = new_listener;
+	    		
+	    		pos = 0;
+	    	}
+	    	
+	    	for ( int i=0;i<listeners.length;i++){
+	    		
+	    		ParameterListener existing_listener = listeners[i];
+	    		
+	    		if ( existing_listener == new_listener ){
+	    			
+	    			return;
+	    		}
+	    		
+	    		new_listeners[pos++] = existing_listener;
+	    	}
+	    	
+	    	if ( DEBUG_PARAMETER_LISTENERS ){
+	    	
+	    		System.out.println( parameter + "->" + new_listeners.length );
+	    	}
+	    	
+	    	parameterListenerz.put( parameter, new_listeners );
 	    }
-	    if(!parameterListener.contains(listener))
-	      parameterListener.add(listener); 
-  	}finally{
-  		this_mon.exit();
   	}
   }
 
   public void removeParameterListener(String parameter, ParameterListener listener){
-  	try{
-  		this_mon.enter();
  
-	    if(parameter == null || listener == null)
-	      return;
-	    LightHashSet parameterListener = (LightHashSet) parameterListeners.get(parameter);
-	    if(parameterListener != null) {
-	    	parameterListener.remove(listener);
+    if( parameter == null || listener == null ){
+    	return;
+    }
+    
+    synchronized( parameterListenerz ){
+	    ParameterListener[] listeners = parameterListenerz.get( parameter );
+	    
+	    if ( listeners == null ){
+	    	
+	    	return;
 	    }
-  	}finally{
-  		this_mon.exit();
-  	}
+	    
+	    if ( listeners.length == 1 ){
+	    	
+	    	if ( listeners[0] == listener ){
+	    		
+	    		parameterListenerz.remove( parameter );
+	    	}
+	    }else{
+	    	
+	    	ParameterListener[] new_listeners = new ParameterListener[ listeners.length - 1 ];
+	    	
+	    	int	pos = 0;
+	    	
+	    	for ( int i=0;i<listeners.length;i++){
+	    		
+	    		ParameterListener existing_listener = listeners[i];
+
+	    		if ( existing_listener != listener ){
+	    			
+	    			if ( pos == new_listeners.length ){
+	    				
+	    				return;
+	    			}
+	    			
+	    			new_listeners[pos++] = existing_listener;
+	    		}
+	    	}
+	    	
+	    	if ( DEBUG_PARAMETER_LISTENERS ){
+	    	
+	    		System.out.println( parameter + "->" + new_listeners.length );
+	    	}
+	    	
+	    	parameterListenerz.put( parameter, new_listeners );
+	    }
+    }
   }
 
   public void addListener(COConfigurationListener listener) {
-  	try{
-  		this_mon.enter();
+  	synchronized( listenerz ){
 
-  		listeners.add(listener);
-  		
-  	}finally{
+  		listenerz.add(listener);
   		
-  		this_mon.exit();
   	}
   }
 
   public void removeListener(COConfigurationListener listener) {
-  	try{
-  		this_mon.enter();
+	  synchronized( listenerz ){
   	
-  		listeners.remove(listener);
-  	}finally{
-  		
-  		this_mon.exit();
+  		listenerz.remove(listener);
   	}
   }
   
@@ -840,6 +949,8 @@ ConfigurationManager
 		try{
 			writer.indent();
 		
+			writer.println( "version=" + Constants.AZUREUS_VERSION + ", subver=" + Constants.AZUREUS_SUBVER );
+			
 			writer.println( "System Properties" );
 			
 			try{
@@ -889,29 +1000,57 @@ ConfigurationManager
 			
 			writer.println( "Azureus Config" );
 
+			ConfigurationDefaults defaults = ConfigurationDefaults.getInstance();
+			
 			try{
 				writer.indent();
 			
-				Iterator it = new TreeSet(propertiesMap.keySet()).iterator();
+				Set<String> keys =
+					new TreeSet<String>(
+						new Comparator<String>()
+						{
+							public int 
+							compare(
+								String o1, 
+								String o2) 
+							{
+								return( o1.compareToIgnoreCase( o2 ));
+							}
+						});
 			
+				keys.addAll( propertiesMap.keySet());
+				
+				Iterator<String> it = keys.iterator();
+				
 				while( it.hasNext()){
 					
-					String	key 	= (String)it.next();
+					String	key 	= it.next();
 					
 						// don't dump crypto stuff
 					
-					if ( key.startsWith( CryptoManager.CRYPTO_CONFIG_PREFIX )){
+					if ( key.startsWith( CryptoManager.CRYPTO_CONFIG_PREFIX ) || key.endsWith( ".privx" )){
 						
 						continue;
 					}
 					
 					Object	value	= propertiesMap.get(key);
 					
-					boolean bParamExists = ConfigurationDefaults.getInstance().doesParameterDefaultExist(key.toString());
+					boolean bParamExists = defaults.doesParameterDefaultExist(key.toString());
 					
 					if (!bParamExists){
 						
 						key = "[NoDef] " + key;
+					}else{
+						
+						Object def = defaults.getParameter( key );
+						
+						if ( def != null && value != null ){
+							
+							if ( !BEncoder.objectsAreIdentical( def, value )){
+								
+								key = "-> " + key;
+							}
+						}
 					}
 					
 					if ( value instanceof Long ){
@@ -920,11 +1059,11 @@ ConfigurationManager
 						
 					}else if ( value instanceof List ){
 						
-						writer.println( key + "=" + value + "[list]" );
+						writer.println( key + "=" + BDecoder.decodeStrings((List)BEncoder.clone(value)) + "[list]" );
 						
 					}else if ( value instanceof Map ){
 						
-						writer.println( key + "=" + value + "[map]" );
+						writer.println( key + "=" + BDecoder.decodeStrings((Map)BEncoder.clone(value)) + "[map]" );
 						
 					}else if ( value instanceof byte[] ){
 						
@@ -978,6 +1117,11 @@ ConfigurationManager
 	stringToBytes(
 		String	str )
 	{
+		if ( str == null ){
+			
+			return( null );
+		}
+		
 		try{
 			return( str.getBytes( Constants.DEFAULT_ENCODING ));
 			
diff --git a/org/gudy/azureus2/core3/config/impl/TransferSpeedValidator.java b/org/gudy/azureus2/core3/config/impl/TransferSpeedValidator.java
index aed7ce2..97a487b 100644
--- a/org/gudy/azureus2/core3/config/impl/TransferSpeedValidator.java
+++ b/org/gudy/azureus2/core3/config/impl/TransferSpeedValidator.java
@@ -70,20 +70,20 @@ public final class TransferSpeedValidator
     				AUTO_UPLOAD_ENABLED_CONFIGKEY,
     				AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY
     			},
-    			new ParameterListener()
+    			new PriorityParameterListener()
         		{
         			public void 
         			parameterChanged(
         				String parameterName)
         			{
         				if (parameterName == null || parameterName.equals(UPLOAD_SEEDING_ENABLED_CONFIGKEY)) {
-        					seeding_upload_enabled = COConfigurationManager.getBooleanParameter( parameterName );
+        					seeding_upload_enabled = COConfigurationManager.getBooleanParameter( UPLOAD_SEEDING_ENABLED_CONFIGKEY );
         				}
         				if (parameterName == null || parameterName.equals(AUTO_UPLOAD_ENABLED_CONFIGKEY)) {
-        					auto_upload_enabled = COConfigurationManager.getBooleanParameter(parameterName);
+        					auto_upload_enabled = COConfigurationManager.getBooleanParameter(AUTO_UPLOAD_ENABLED_CONFIGKEY);
         				}
         				if (parameterName == null || parameterName.equals(AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY)) {
-        					auto_upload_seeding_enabled = COConfigurationManager.getBooleanParameter(parameterName);
+        					auto_upload_seeding_enabled = COConfigurationManager.getBooleanParameter(AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY);
         				}
         			}
         		});	
@@ -214,7 +214,7 @@ public final class TransferSpeedValidator
     public static boolean
     isAutoSpeedActive(
     		GlobalManager gm )
-    {
+    {    	
   		// if downloading+seeding is set then we always use this regardless of
   		// only seeding status
 
diff --git a/org/gudy/azureus2/core3/disk/DiskManager.java b/org/gudy/azureus2/core3/disk/DiskManager.java
index e645a44..32bc38a 100644
--- a/org/gudy/azureus2/core3/disk/DiskManager.java
+++ b/org/gudy/azureus2/core3/disk/DiskManager.java
@@ -56,10 +56,19 @@ DiskManager
 	public void
 	start();
 	
-	public void
+		/**
+		 * Stop can go async if the download is in a 'starting' state - if so this method returns true
+		 * @param closing
+		 * @return 
+		 */
+	
+	public boolean
 	stop(
 		boolean	closing );
 	
+	public boolean
+	isStopped();
+	
 	/**
 	  * @return whether all files exist and sizes match
 	  */
@@ -220,12 +229,17 @@ DiskManager
 	getErrorMessage();
   
 	public void
-	downloadEnded();
+	downloadEnded(
+		OperationStatus		op_status );
 
     public void
     downloadRemoved();
 	
-	public void moveDataFiles(File new_parent_dir, String dl_name);
+	public void 
+	moveDataFiles(
+		File 				new_parent_dir, 
+		String 				dl_name, 
+		OperationStatus 	op_status );
 	
 		/**
 		 * returns -1 if no recheck in progress, percentage complete in 1000 notation otherwise
@@ -236,6 +250,14 @@ DiskManager
 	getCompleteRecheckStatus();
   
 		/**
+		 * When a download's data is moving (for completion or removal events) this gives the progress in 1000 notation. -1 if nothing's going on
+		 * @return
+		 */
+	
+	public int
+	getMoveProgress();
+	
+		/**
 		 * method for checking that the block details are sensible
 		 * @param pieceNumber
 		 * @param offset
@@ -261,6 +283,7 @@ DiskManager
 	public boolean 
 	checkBlockConsistencyForRead(
 		String	originator,
+		boolean	peer_request,
 		int 	pieceNumber, 
 		int	 	offset, 
 		int 	length );
@@ -314,4 +337,19 @@ DiskManager
 	public void
 	generateEvidence(
 		IndentWriter		writer );
+	
+	public interface
+	OperationStatus
+	{
+		public void
+		gonnaTakeAWhile(
+			GettingThere	gt );
+	}
+	
+	public interface
+	GettingThere
+	{
+		public boolean
+		hasGotThere();
+	}
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/disk/DiskManagerCheckRequest.java b/org/gudy/azureus2/core3/disk/DiskManagerCheckRequest.java
index c020af7..98cf344 100644
--- a/org/gudy/azureus2/core3/disk/DiskManagerCheckRequest.java
+++ b/org/gudy/azureus2/core3/disk/DiskManagerCheckRequest.java
@@ -46,4 +46,11 @@ DiskManagerCheckRequest
 	public boolean
 	isAdHoc();
 	
+	public void
+	setHash(
+		byte[]		hash );
+	
+	public byte[]
+	getHash();
+	
 }
diff --git a/org/gudy/azureus2/core3/disk/DiskManagerFactory.java b/org/gudy/azureus2/core3/disk/DiskManagerFactory.java
index beb02a3..e2a6f5d 100644
--- a/org/gudy/azureus2/core3/disk/DiskManagerFactory.java
+++ b/org/gudy/azureus2/core3/disk/DiskManagerFactory.java
@@ -28,6 +28,7 @@ package org.gudy.azureus2.core3.disk;
 
 
 import org.gudy.azureus2.core3.disk.impl.DiskManagerImpl;
+import org.gudy.azureus2.core3.disk.impl.DiskManagerUtil;
 import org.gudy.azureus2.core3.disk.impl.resume.RDResumeHandler;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
@@ -114,7 +115,7 @@ DiskManagerFactory
 		DownloadManager			download_manager,
 		DiskManagerListener		listener )
 	{
-		return( DiskManagerImpl.getFileInfoSkeleton( download_manager, listener ));
+		return( DiskManagerUtil.getFileInfoSkeleton( download_manager, listener ));
 	}
 
 	public static void
diff --git a/org/gudy/azureus2/core3/disk/DiskManagerFileInfo.java b/org/gudy/azureus2/core3/disk/DiskManagerFileInfo.java
index a8384d5..532249b 100644
--- a/org/gudy/azureus2/core3/disk/DiskManagerFileInfo.java
+++ b/org/gudy/azureus2/core3/disk/DiskManagerFileInfo.java
@@ -33,15 +33,17 @@ import org.gudy.azureus2.core3.util.DirectByteBuffer;
 public interface 
 DiskManagerFileInfo 
 {
-	public static final int READ = 1;
-	public static final int WRITE = 2;
+	public static final int READ 	= 1;
+	public static final int WRITE 	= 2;
 
-	public static final int	ST_LINEAR	= 1;
-	public static final int	ST_COMPACT	= 2;
+	public static final int	ST_LINEAR			= 1;
+	public static final int	ST_COMPACT			= 2;
+	public static final int	ST_REORDER			= 3;
+	public static final int	ST_REORDER_COMPACT	= 4;
 	
 		// set methods
 		
-	public void setPriority(boolean b);
+	public void setPriority(int p);
 	
 	public void setSkipped(boolean b);
 	 
@@ -90,7 +92,7 @@ DiskManagerFileInfo
 		
 	public int getNbPieces();
 			
-	public boolean isPriority();
+	public int getPriority();
 	
 	public boolean isSkipped();
 	
diff --git a/org/gudy/azureus2/core3/disk/DiskManagerFileInfoSet.java b/org/gudy/azureus2/core3/disk/DiskManagerFileInfoSet.java
index 0e82dfe..3252b12 100644
--- a/org/gudy/azureus2/core3/disk/DiskManagerFileInfoSet.java
+++ b/org/gudy/azureus2/core3/disk/DiskManagerFileInfoSet.java
@@ -27,7 +27,7 @@ package org.gudy.azureus2.core3.disk;
  */
 public interface DiskManagerFileInfoSet {
 	public boolean[] setStorageTypes(boolean[] toChange, int newStroageType);
-	public void setPriority(boolean[] toChange, boolean setPriority);
+	public void setPriority(int[] toChange);
 	public void setSkipped(boolean[] toChange, boolean setSkipped);
 	public DiskManagerFileInfo[] getFiles();
 	public int nbFiles();
diff --git a/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoImpl.java b/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoImpl.java
index 7487848..1a67050 100644
--- a/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoImpl.java
@@ -58,8 +58,9 @@ DiskManagerFileInfoImpl
   private DiskManagerHelper 	diskManager;
   private TOTorrentFile			torrent_file;
   
-  boolean priority = false;  
-  boolean skipped = false;
+  private int 		priority 	= 0;
+  
+  protected boolean 	skipped 	= false;
   
   private CopyOnWriteList	listeners;
   
@@ -69,7 +70,7 @@ DiskManagerFileInfoImpl
   	File				_file,
   	int					_file_index,
 	TOTorrentFile		_torrent_file,
-	boolean				_linear_storage )
+	int					_storage_type )
   
   	throws CacheFileManagerException
   {
@@ -79,14 +80,13 @@ DiskManagerFileInfoImpl
     file		= _file;
     file_index	= _file_index;
     
-  	cache_file = CacheFileManagerFactory.getSingleton().createFile( 
-  						this, _file, _linear_storage?CacheFile.CT_LINEAR:CacheFile.CT_COMPACT );
-  
-  		// if compact storage then the file must be skipped
+    int	cache_st = DiskManagerUtil.convertDMStorageTypeToCache( _storage_type );
+    
+  	cache_file = CacheFileManagerFactory.getSingleton().createFile( this, _file, cache_st);
   	
-  	if ( !_linear_storage ){
+  	if ( cache_st == CacheFile.CT_COMPACT || cache_st == CacheFile.CT_PIECE_REORDER_COMPACT ){
   		
-  		skipped	= true;
+  		skipped = true;
   	}
   }
   
@@ -256,7 +256,7 @@ DiskManagerFileInfoImpl
 	public int
 	getStorageType()
 	{
-		return( diskManager.getStorageType(file_index).equals( "L")?ST_LINEAR:ST_COMPACT );
+		return( DiskManagerUtil.convertDMStorageTypeFromString( diskManager.getStorageType(file_index)));
 	}
 	
 	protected boolean
@@ -314,14 +314,14 @@ DiskManagerFileInfoImpl
   /**
    * @return
    */
-  public boolean isPriority() {
+  public int getPriority() {
 	return priority;
   }
 
   /**
    * @param b
    */
-  public void setPriority(boolean b) {
+  public void setPriority(int b) {
 	priority = b;
 	diskManager.priorityChanged( this );
   }
@@ -337,12 +337,23 @@ DiskManagerFileInfoImpl
    * @param skipped
    */
   public void setSkipped(boolean _skipped) {
+	  
+	int	existing_st = getStorageType();
+	
 	  // currently a non-skipped file must be linear
-	if ( !_skipped && getStorageType() == ST_COMPACT ){
+	
+	if ( !_skipped && existing_st == ST_COMPACT ){
 		if ( !setStorageType( ST_LINEAR )){
 			return;
 		}
 	}
+	
+	if ( !_skipped && existing_st == ST_REORDER_COMPACT ){
+		if ( !setStorageType( ST_REORDER )){
+			return;
+		}
+	}
+	
 	skipped = _skipped;
 	diskManager.skippedFileSetChanged( this );
 	if(!_skipped)
diff --git a/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoSetImpl.java b/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoSetImpl.java
index e306f8c..4ef595f 100644
--- a/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoSetImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/DiskManagerFileInfoSetImpl.java
@@ -23,12 +23,9 @@ import java.util.Arrays;
 
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfoSet;
-import org.gudy.azureus2.core3.disk.impl.DiskManagerImpl.FileSkeleton;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
 import org.gudy.azureus2.core3.util.Debug;
 
-import com.aelitis.azureus.core.diskmanager.cache.CacheFile;
-
 /**
  * @author Aaron Grunthal
  * @create 10.05.2008
@@ -51,7 +48,7 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 		return files.length;
 	}
 
-	public void setPriority(boolean[] toChange, boolean setPriority) {
+	public void setPriority(int[] toChange) {
 		if(toChange.length != files.length)
 			throw new IllegalArgumentException("array length mismatches the number of files");
 
@@ -62,8 +59,9 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 
 		
 			for(int i=0;i<files.length;i++)
-				if(toChange[i])
-					files[i].setPriority(setPriority);
+				if(toChange[i] != 0){
+					files[i].setPriority(toChange[i]);
+				}
 		} finally {
 			dmState.suppressStateSave(false);
 		}
@@ -78,9 +76,53 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 		try	{
 			dmState.suppressStateSave(true);
 			
-			if (!setSkipped && !Arrays.equals(toChange, setStorageTypes(toChange, FileSkeleton.ST_LINEAR)))
-				return;
+			if (!setSkipped ){
+				
+				String[] types = diskManager.getStorageTypes();
+
+				boolean[]	toLinear 	= new boolean[toChange.length];
+				boolean[]	toReorder 	= new boolean[toChange.length];
+				
+				int	num_linear 	= 0;
+				int num_reorder	= 0;
+				
+				for ( int i=0;i<toChange.length;i++){
+					
+					if ( toChange[i] ){
+						
+						int old_type = DiskManagerUtil.convertDMStorageTypeFromString( types[i] );
+						
+						if ( old_type == DiskManagerFileInfo.ST_COMPACT ){
+							
+							toLinear[i] = true;
+							
+							num_linear++;
+							
+						}else if ( old_type == DiskManagerFileInfo.ST_REORDER_COMPACT ){
+							
+							toReorder[i] = true;
+							
+							num_reorder++;
+						}
+					}	
+				}
+				
+				if ( num_linear > 0 ){
+					
+					if (!Arrays.equals(toLinear, setStorageTypes(toLinear, DiskManagerFileInfo.ST_LINEAR))){
+						
+						return;
+					}
+				}
 			
+				if ( num_reorder > 0 ){
+					
+					if (!Arrays.equals(toReorder, setStorageTypes(toReorder, DiskManagerFileInfo.ST_REORDER ))){
+						
+						return;
+					}
+				}
+			}
 			for (int i = 0; i < files.length; i++)
 				if (toChange[i])
 				{
@@ -108,7 +150,7 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 		boolean[] modified = new boolean[files.length];
 		DownloadManagerState	dm_state = diskManager.getDownloadState();
 
-		if (newStroageType == DiskManagerFileInfo.ST_COMPACT)
+		if (newStroageType == DiskManagerFileInfo.ST_COMPACT || newStroageType == DiskManagerFileInfo.ST_REORDER_COMPACT)
 		{
 			Debug.out("Download must be stopped for linear -> compact conversion");
 			return modified;
@@ -122,7 +164,7 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 				if(!toChange[i])
 					continue;
 				
-				int old_type = types[i].equals("L") ? DiskManagerFileInfo.ST_LINEAR : DiskManagerFileInfo.ST_COMPACT;
+				int old_type = DiskManagerUtil.convertDMStorageTypeFromString( types[i] );
 				if (newStroageType == old_type)
 				{
 					modified[i] = true;
@@ -132,14 +174,14 @@ public class DiskManagerFileInfoSetImpl implements DiskManagerFileInfoSet {
 				DiskManagerFileInfoImpl file = files[i];
 				
 				try	{
-					file.getCacheFile().setStorageType(newStroageType == DiskManagerFileInfo.ST_LINEAR ? CacheFile.CT_LINEAR : CacheFile.CT_COMPACT);
+					file.getCacheFile().setStorageType( DiskManagerUtil.convertDMStorageTypeToCache( newStroageType ));
 					modified[i] = true;
 				} catch (Throwable e) {
 					Debug.printStackTrace(e);
 					diskManager.setFailed(file, "Failed to change storage type for '" + file.getFile(true) + "': " + Debug.getNestedExceptionMessage(e));
 					break;
 				} finally {
-					types[i] = file.getCacheFile().getStorageType() == CacheFile.CT_LINEAR ? "L" : "C";
+					types[i] = DiskManagerUtil.convertCacheStorageTypeToString( file.getCacheFile().getStorageType());
 				}
 			}
 			
diff --git a/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java b/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
index a2c46ae..f9539ab 100644
--- a/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/DiskManagerImpl.java
@@ -26,10 +26,10 @@ import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.lang.ref.WeakReference;
 import java.util.*;
 
 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.disk.impl.access.DMAccessFactory;
 import org.gudy.azureus2.core3.disk.impl.access.DMChecker;
@@ -116,6 +116,26 @@ DiskManagerImpl
         return( disk_access_controller );
     }
     
+    private static boolean 	reorder_storage_mode;
+    private static int		reorder_storage_mode_min_mb;
+    
+    static{
+    	COConfigurationManager.addAndFireParameterListeners(
+    		new String[]{
+    			"Enable reorder storage mode",
+    			"Reorder storage mode min MB" },
+    		new ParameterListener()
+    		{
+    			public void 
+    			parameterChanged(
+    				String parameterName ) 
+    			{
+       				reorder_storage_mode 		= COConfigurationManager.getBooleanParameter( "Enable reorder storage mode" );
+       				reorder_storage_mode_min_mb = COConfigurationManager.getIntParameter( "Reorder storage mode min MB" );
+    			}
+    		});
+    }
+    
     private static DiskManagerRecheckScheduler      recheck_scheduler       = new DiskManagerRecheckScheduler();
     private static DiskManagerAllocationScheduler   allocation_scheduler    = new DiskManagerAllocationScheduler();
 
@@ -125,8 +145,6 @@ DiskManagerImpl
     	start_pool.setThreadPriority( Thread.MIN_PRIORITY );
     }
     
-    private static AEMonitor    cache_read_mon  = new AEMonitor( "DiskManager:cacheRead" );
-
     private boolean used    = false;
 
     private boolean started = false;
@@ -175,7 +193,9 @@ DiskManagerImpl
     private long                skipped_but_downloaded;
 
     private boolean				checking_enabled = true;
-    
+
+    private volatile boolean	move_in_progress;
+    private volatile int		move_progress;
 
         // DiskManager listeners
 
@@ -332,6 +352,11 @@ DiskManagerImpl
     start()
     {
         try{
+        	if ( move_in_progress ){
+        		
+        		Debug.out( "start called while move in progress!" );
+        	}
+        	
             start_stop_mon.enter();
 
             if ( used ){
@@ -530,16 +555,21 @@ DiskManagerImpl
         setState( READY );
     }
 
-    public void
+    public boolean
     stop(
     	boolean	closing )
     {
         try{
+        	if ( move_in_progress ){
+        		
+        		Debug.out( "stop called while move in progress!" );
+        	}
+       	
             start_stop_mon.enter();
 
             if ( !started ){
 
-                return;
+                return( false );
             }
 
                 // we need to be careful if we're still starting up as this may be
@@ -567,7 +597,7 @@ DiskManagerImpl
                 
                 saveState( false );
                 
-                return;
+                return( true );
             }
 
             started     = false;
@@ -621,8 +651,29 @@ DiskManagerImpl
 
         // can't be used after a stop so we might as well clear down the listeners
         listeners.clear();
+        
+        return( false );
     }
 
+    public boolean 
+    isStopped() 
+    {
+       	if ( move_in_progress ){
+    		
+    		Debug.out( "isStopped called while move in progress!" );
+    	}
+       	
+        try{
+            start_stop_mon.enter();
+            
+            return( !( started || starting || stopping ));
+            
+        }finally{
+
+            start_stop_mon.exit();
+        }
+    }
+    
     public boolean
     filesExist()
     {
@@ -649,6 +700,8 @@ DiskManagerImpl
 
         String[]    storage_types = getStorageTypes();
 
+  		DownloadManagerState state = download_manager.getDownloadState();
+
         for (int i = 0; i < pm_files.length; i++) {
 
             DMPieceMapperFile pm_info = pm_files[i];
@@ -671,16 +724,11 @@ DiskManagerImpl
             try{
                 if ( file_info == null ){
 
-                    boolean linear = storage_types[i].equals("L");
-
-                    file_info = new DiskManagerFileInfoImpl(
-                                        this,
-                                        new File( root_dir + relative_file.toString()),
-                                        i,
-                                        pm_info.getTorrentFile(),
-                                        linear );
-
-                    close_it    = true;
+                    int storage_type = DiskManagerUtil.convertDMStorageTypeFromString( storage_types[i]);
+            
+                	file_info = createFileInfo( state, pm_info, i, root_dir, relative_file, storage_type );
+                	
+                	close_it = true;
                 }
 
                 try{
@@ -765,6 +813,121 @@ DiskManagerImpl
         return true;
     }
 
+    private DiskManagerFileInfoImpl
+    createFileInfo(
+    	DownloadManagerState		state,
+    	DMPieceMapperFile			pm_info,
+    	int							file_index,
+    	String						root_dir,
+    	File						relative_file,
+    	int							storage_type )
+    
+    	throws Exception
+    {
+       	File target_file = new File( root_dir + relative_file.toString());
+    	
+        try{
+        
+            return( new DiskManagerFileInfoImpl(
+                                this,
+                                target_file,
+                                file_index,
+                                pm_info.getTorrentFile(),
+                                storage_type ));
+            
+        }catch( CacheFileManagerException e ){
+        	
+        		// unfortunately there are files out there with ascii < 32 chars in that are invalid on windows
+        		// but ok on other file systems
+        		// it would be possible to fix this in FileUtil.convertOSSPecificChars but my worry with this is that it
+        		// would potentially break existing downloads, so I whimped out and decided to take the approach of
+        		// detecting the issue and using file-links to work around it
+        	
+        	if ( Debug.getNestedExceptionMessage(e).contains( "volume label syntax is incorrect" )){
+        		
+        		File actual_file = state.getFileLink( target_file );
+        		
+        		if ( actual_file == null ){
+        			
+        			actual_file = target_file;
+        		}
+        		
+        		File temp = actual_file;
+        		
+        		Stack<String>	comps = new Stack<String>();
+        		
+        		boolean	fixed = false;
+        		
+        		while( temp != null ){
+        			
+        			if ( temp.exists()){
+        				
+        				break;
+        			}
+        			
+        			String old_name 	= temp.getName();
+        			String new_name		= "";
+        			
+        			char[] chars = old_name.toCharArray();
+        			
+        			for ( char c: chars ){
+        				
+        				int	i_c = (int)c;
+        				
+        				if ( i_c >= 0 && i_c < 32 ){
+        					
+        					new_name += "_";
+        					
+        				}else{
+        					
+        					new_name += c;
+        				}
+        			}
+        			
+        			comps.push( new_name );
+        			
+        			if ( !old_name.equals( new_name )){
+        				
+        				fixed = true;
+        			}
+        			
+        			temp = temp.getParentFile();
+        		}
+        		
+        		if ( fixed ){
+        			
+        			while( !comps.isEmpty()){
+        				
+        				String comp = comps.pop();
+        				
+        				if ( comps.isEmpty()){
+        				
+        					String prefix = Base32.encode( new SHA1Simple().calculateHash( relative_file.toString().getBytes( "UTF-8" ))).substring( 0, 4 );
+        					
+        					comp = prefix + "_" + comp;
+        				}
+        				
+        				temp = new File( temp, comp );
+        			}
+        			
+           			Debug.outNoStack( "Fixing unsupported file path: " + actual_file.getAbsolutePath() + " -> " + temp.getAbsolutePath());
+           			
+           			state.setFileLink( target_file, temp );
+           			
+                    return(
+                    	new DiskManagerFileInfoImpl(
+                            this,
+                            target_file,
+                            file_index,
+                            pm_info.getTorrentFile(),
+                            storage_type ));
+        		}        		
+        	}
+        	       		
+        	throw( e );
+        }
+    }
+
     private int
     allocateFiles()
     {
@@ -774,6 +937,8 @@ DiskManagerImpl
 
         DiskManagerFileInfoImpl[] allocated_files = new DiskManagerFileInfoImpl[pm_files.length];
 
+        DownloadManagerState	state = download_manager.getDownloadState();
+        
         try{
             allocation_scheduler.register( this );
 
@@ -794,8 +959,19 @@ DiskManagerImpl
 
             String[]    storage_types = getStorageTypes();
 
+			String incomplete_suffix = state.getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
+
             for ( int i=0;i<pm_files.length;i++ ){
 
+            	if ( stopping ){
+            		
+                    this.errorMessage = "File allocation interrupted - download is stopping";
+
+                    setState( FAULTY );
+
+                    return( -1 );
+            	}
+            	
                 final DMPieceMapperFile pm_info = pm_files[i];
 
                 final long target_length = pm_info.getLength();
@@ -805,20 +981,15 @@ DiskManagerImpl
                 DiskManagerFileInfoImpl fileInfo;
 
                 try{
-                    boolean linear = storage_types[i].equals("L");
+                    int storage_type = DiskManagerUtil.convertDMStorageTypeFromString( storage_types[i]);
 
-                    fileInfo = new DiskManagerFileInfoImpl(
-                                    this,
-                                    new File( root_dir + relative_data_file.toString()),
-                                    i,
-                                    pm_info.getTorrentFile(),
-                                    linear );
+                    fileInfo = createFileInfo( state, pm_info, i, root_dir, relative_data_file, storage_type );
 
                     allocated_files[i] = fileInfo;
 
                     pm_info.setFileInfo( fileInfo );
 
-                }catch ( CacheFileManagerException e ){
+                }catch ( Exception e ){
 
                     this.errorMessage = Debug.getNestedExceptionMessage(e) + " (allocateFiles:" + relative_data_file.toString() + ")";
 
@@ -829,7 +1000,6 @@ DiskManagerImpl
 
                 CacheFile   cache_file      = fileInfo.getCacheFile();
                 File        data_file       = fileInfo.getFile(true);
-                String      data_file_name  = data_file.getName();
 
                 String  file_key = data_file.getAbsolutePath();
 
@@ -849,14 +1019,21 @@ DiskManagerImpl
 
                 file_set.add( file_key );
 
-                int separator = data_file_name.lastIndexOf(".");
+                String      ext  = data_file.getName();
+
+                if ( incomplete_suffix != null && ext.endsWith( incomplete_suffix )){
+                	
+                	ext = ext.substring( 0, ext.length() - incomplete_suffix.length());
+                }
+                
+                int separator = ext.lastIndexOf(".");
 
                 if ( separator == -1 ){
 
                     separator = 0;
                 }
 
-                fileInfo.setExtension(data_file_name.substring(separator));
+                fileInfo.setExtension(ext.substring(separator));
 
                     //Added for Feature Request
                     //[ 807483 ] Prioritize .nfo files in new torrents
@@ -876,13 +1053,15 @@ DiskManagerImpl
                                               fileInfo.getExtension().equalsIgnoreCase(extension) :
                                               fileInfo.getExtension().equals(extension);
                         if (bHighPriority)
-                            fileInfo.setPriority(true);
+                            fileInfo.setPriority(1);
                     }
                 }
 
                 fileInfo.setDownloaded(0);
                 
-                boolean compact = cache_file.getStorageType() == CacheFile.CT_COMPACT;
+                int st = cache_file.getStorageType();
+                
+                boolean compact = st == CacheFile.CT_COMPACT || st == CacheFile.CT_PIECE_REORDER_COMPACT;
                 
                 boolean mustExistOrAllocate = ( !compact ) || RDResumeHandler.fileMustExist(download_manager, fileInfo);
                 
@@ -1059,6 +1238,7 @@ DiskManagerImpl
 	            //fully allocate. XFS borks with zero length files though
 	
 	        if ( 	target_length > 0 && 
+	        		!Constants.isWindows && 
 	        		COConfigurationManager.getBooleanParameter("XFS Allocation") ){
 	        	
 	            fileInfo.getCacheFile().setLength( target_length );
@@ -1344,46 +1524,52 @@ DiskManagerImpl
 
                     	// change file modes based on whether or not the file is complete or not
                     
-                    if ( file_done == file_length && this_file.getAccessMode() == DiskManagerFileInfo.WRITE ){
-                        
+                    if ( file_done == file_length ){
+                         
                     	try{
-                    		this_file.setAccessMode(DiskManagerFileInfo.READ);
-                    		
-                    		DownloadManagerState state = download_manager.getDownloadState();
-                    		
-                    		String suffix = state.getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
-                    		
-                    		if ( suffix != null && suffix.length() > 0 ){
-                    			
-                    			File base_file = this_file.getFile( false );
-                    			
-                    			File link = state.getFileLink( base_file );
+                    		try{
+	                      		DownloadManagerState state = download_manager.getDownloadState();
+	                    		
+	                    		String suffix = state.getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
+	                    		
+	                    		if ( suffix != null && suffix.length() > 0 ){
+	                    			
+	                    			File base_file = this_file.getFile( false );
+	                    			
+	                    			File link = state.getFileLink( base_file );
+	                    			
+	                    			if ( link != null ){
+	                    				
+	                    				String	name = link.getName();
+	                    				
+	                    				if ( name.endsWith( suffix ) && name.length() > suffix.length()){
+	                    					
+	                    					String	new_name = name.substring( 0, name.length() - suffix.length());
+	                    					
+	                    					File new_file = new File( link.getParentFile(), new_name );
+	                    					
+	                    					if ( !new_file.exists()){
+	                    						
+	                    						this_file.renameFile( new_name, false );
+	                    						
+	                    						if ( base_file.equals( new_file )){
+	                    							
+	                    							state.setFileLink( base_file, null );
+	                    							
+	                    						}else{
+	                    							
+	                    							state.setFileLink( base_file, new_file );
+	                    						}
+	                    					}
+	                    				}
+	                    			}
+	                    		}
+                    		}finally{
                     			
-                    			if ( link != null ){
-                    				
-                    				String	name = link.getName();
-                    				
-                    				if ( name.endsWith( suffix ) && name.length() > suffix.length()){
-                    					
-                    					String	new_name = name.substring( 0, name.length() - suffix.length());
-                    					
-                    					File new_file = new File( link.getParentFile(), new_name );
-                    					
-                    					if ( !new_file.exists()){
-                    						
-                    						this_file.renameFile( new_name, false );
-                    						
-                    						if ( base_file.equals( new_file )){
-                    							
-                    							state.setFileLink( base_file, null );
-                    							
-                    						}else{
-                    							
-                    							state.setFileLink( base_file, new_file );
-                    						}
-                    					}
-                    				}
-                    			}
+                             	if ( this_file.getAccessMode() == DiskManagerFileInfo.WRITE ){
+
+                               		this_file.setAccessMode( DiskManagerFileInfo.READ );
+                               	}
                     		}
                         }catch ( Throwable e ){
                         
@@ -1693,6 +1879,17 @@ DiskManagerImpl
       return ( checker.getCompleteRecheckStatus());
     }
 
+    public int
+    getMoveProgress()
+    {
+    	if ( move_in_progress ){
+    		
+    		return( move_progress );
+    	}
+    	
+    	return( -1 );
+    }
+    
 	public void
 	setPieceCheckingEnabled(
 		boolean		enabled )
@@ -1792,11 +1989,12 @@ DiskManagerImpl
 	public boolean
 	checkBlockConsistencyForRead(
 		String	originator,
+	    boolean	peer_request,
 	    int 	pieceNumber,
 	    int 	offset,
 	    int 	length )
 	{
-		return( DiskManagerUtil.checkBlockConsistencyForRead(this, originator, pieceNumber, offset, length));
+		return( DiskManagerUtil.checkBlockConsistencyForRead(this, originator, peer_request, pieceNumber, offset, length));
 	}
 	
 	public boolean
@@ -1818,17 +2016,23 @@ DiskManagerImpl
         resume_handler.saveResumeData( interim_save );
     }
 
-    public void downloadEnded() {
-        moveDownloadFilesWhenEndedOrRemoved(false, true);
+    public void downloadEnded( OperationStatus op_status ) {
+        moveDownloadFilesWhenEndedOrRemoved( false, true, op_status );
     }
 
     public void downloadRemoved () {
-        moveDownloadFilesWhenEndedOrRemoved(true, true);
+        moveDownloadFilesWhenEndedOrRemoved(true, true, null );
     }
 
-    private boolean moveDownloadFilesWhenEndedOrRemoved(final boolean removing, final boolean torrent_file_exists) {
+    private boolean 
+    moveDownloadFilesWhenEndedOrRemoved(
+    	final boolean 			removing, 
+    	final boolean 			torrent_file_exists,
+    	final OperationStatus	op_status )
+    {
       try {
         start_stop_mon.enter();
+                
         final boolean ending = !removing; // Just a friendly alias.
 
         /**
@@ -1845,17 +2049,35 @@ DiskManagerImpl
         SaveLocationChange move_details;
         if (removing) {
         	move_details = DownloadManagerMoveHandler.onRemoval(this.download_manager);
+        	
+        }else{
+        	DownloadManagerMoveHandler.onCompletion(
+        		this.download_manager,
+        		new DownloadManagerMoveHandler.MoveCallback()
+        		{
+        			public void 
+        			perform(
+        				SaveLocationChange move_details ) 
+        			{
+        				moveFiles( move_details, true, op_status );
+        			}
+        		});
+        	
+        	move_details = null;
         }
-        else {
-        	move_details = DownloadManagerMoveHandler.onCompletion(this.download_manager);
+        
+        if ( move_details != null ){
+        	
+        	moveFiles( move_details, true, op_status );
         }
         
-        if (move_details != null) {moveFiles(move_details, true);}
         return true;
 
       }
       finally{
+    	      	  
           start_stop_mon.exit();
+          
           if (!removing) {
               try{
                   saveResumeData(false);
@@ -1867,14 +2089,26 @@ DiskManagerImpl
       }
     }
     
-    public void moveDataFiles(File new_parent_dir, String new_name) {
+    public void 
+    moveDataFiles(
+    	File 				new_parent_dir, 
+    	String 				new_name,
+    	OperationStatus		op_status )
+    {
     	SaveLocationChange loc_change = new SaveLocationChange();
-    	loc_change.download_location = new_parent_dir;
-    	loc_change.download_name = new_name;
-    	moveFiles(loc_change, false);
+    	
+    	loc_change.download_location 	= new_parent_dir;
+    	loc_change.download_name 		= new_name;
+    	
+    	moveFiles( loc_change, false, op_status );
     }
 
-    protected void moveFiles(SaveLocationChange loc_change, boolean change_to_read_only) {
+    protected void 
+    moveFiles(
+    	SaveLocationChange 	loc_change, 
+    	boolean 			change_to_read_only,
+    	OperationStatus		op_status )
+    {
     	boolean move_files = false;
     	if (loc_change.hasDownloadChange()) {
     		move_files = !this.isFileDestinationIsItself(loc_change);
@@ -1882,14 +2116,23 @@ DiskManagerImpl
     	
         try {
             start_stop_mon.enter();
-
+            
             /**
              * The 0 suffix is indicate that these are quite internal, and are
              * only intended for use within this method.
              */
             boolean files_moved = true;
             if (move_files) {
-                files_moved = moveDataFiles0(loc_change, change_to_read_only);
+            	try{
+            		move_progress		= 0;
+            		move_in_progress 	= true;
+            		
+            		files_moved = moveDataFiles0(loc_change, change_to_read_only, op_status );
+            		
+            	}finally{
+            		
+            		move_in_progress = false;
+            	}
             }
 
             if (loc_change.hasTorrentChange() && files_moved) {
@@ -1900,8 +2143,8 @@ DiskManagerImpl
             Debug.printStackTrace(e);
         }
         finally{
-
-        start_stop_mon.exit();
+        	  
+        	start_stop_mon.exit();
     }
   }
     
@@ -1932,7 +2175,7 @@ DiskManagerImpl
 	  return false;
   }
 	  
-    private boolean moveDataFiles0(SaveLocationChange loc_change, final boolean change_to_read_only) throws Exception  {
+    private boolean moveDataFiles0(SaveLocationChange loc_change, final boolean change_to_read_only, OperationStatus op_status ) throws Exception  {
     	
     	File move_to_dir_name = loc_change.download_location;
     	if (move_to_dir_name == null) {move_to_dir_name = download_manager.getAbsoluteSaveLocation().getParentFile();}
@@ -1956,307 +2199,572 @@ DiskManagerImpl
     	
         if (isFileDestinationIsItself(loc_change)) {return false;}
         
-    	boolean simple_torrent = download_manager.getTorrent().isSimpleTorrent();
-    	
-    		// absolute save location does not follow links
-    		// 		for simple: /temp/simple.avi
-    		//		for complex: /temp/complex
-    	
-        final File save_location = download_manager.getAbsoluteSaveLocation();
+        final boolean[]	got_there = { false };
+               
+        if ( op_status != null ){
+        	
+       		op_status.gonnaTakeAWhile( 
+        		new GettingThere()
+        		{
+        			public boolean 
+        			hasGotThere() 
+        			{
+        				synchronized( got_there ){
+        					
+        					return( got_there[0] );
+        				}
+        			}
+        		});
+        }
         
-        	// It is important that we are able to get the canonical form of the directory to
-        	// move to, because later code determining new file paths will break otherwise.
+        try{        
+	    	boolean simple_torrent = download_manager.getTorrent().isSimpleTorrent();
+	    	
+	    		// absolute save location does not follow links
+	    		// 		for simple: /temp/simple.avi
+	    		//		for complex: /temp/complex
+	    	
+	        final File save_location = download_manager.getAbsoluteSaveLocation();
+	        
+	        	// It is important that we are able to get the canonical form of the directory to
+	        	// move to, because later code determining new file paths will break otherwise.
+	 
+	        final String move_from_dir	= save_location.getParentFile().getCanonicalFile().getPath();        
+	         
+	         
+	        final File[]    new_files   = new File[files.length];
+	        
+	        File[]    old_files   = new File[files.length];
+	        boolean[] link_only   = new boolean[files.length];
+	
+	        long	total_bytes 		= 0;
+	        
+	        final long[]	file_lengths_to_move	 	= new long[files.length];
+	        
+	        for (int i=0; i < files.length; i++) {
+	
+	            File old_file = files[i].getFile(false);
+		            
+	            File linked_file = FMFileManagerFactory.getSingleton().getFileLink( torrent, old_file );
+	
+	            if ( !linked_file.equals(old_file)){
+	
+	                if ( simple_torrent ){
+	
+	                    // simple torrent, only handle a link if its a simple rename
+	
+	                    if ( linked_file.getParentFile().getCanonicalPath().equals( save_location.getParentFile().getCanonicalPath())){
+	
+	                        old_file  = linked_file;
+	
+	                    }else{
+	
+	                        link_only[i] = true;
+	                    }
+	                    
+	                }else{
+	                      // if we are linked to a file outside of the torrent's save directory then we don't
+	                      // move the file
+	
+	                    if ( linked_file.getCanonicalPath().startsWith( save_location.getCanonicalPath())){
+	
+	                        old_file  = linked_file;
+	
+	                    }else{
+	
+	                        link_only[i] = true;
+	                    }
+	                }
+	            }
+	            
+	            /**
+	             * We are trying to calculate the relative path of the file within the original save
+	             * directory, and then use that to calculate the new save path of the file in the new
+	             * save directory.
+	             * 
+	             * We have three cases which we may deal with:
+	             *   1) Where the file in the torrent has never been moved (therefore, old_file will
+	             *      equals linked_file),
+	             *   2) Where the file in the torrent has been moved somewhere elsewhere inside the save
+	             *      path (old_file will not equal linked_file, but we will overwrite the value of
+	             *      old_file with linked_file),
+	             *   3) Where the file in the torrent has been moved outside of the download path - meaning
+	             *      we set link_only[i] to true. This is just to update the internal reference of where
+	             *      the file should be - it doesn't move the file at all.
+	             *      
+	             * Below, we will determine a new path for the file, but only in terms of where it should be
+	             * inside the new download save location - if the file currently exists outside of the save
+	             * location, we will not move it.
+	             */
+	            
+	            old_files[i] = old_file;
+	            
+	            /**
+	             * move_from_dir should be canonical (see earlier code).
+	             * 
+	             * Need to get canonical form of the old file, because that's what we are using for determining
+	             * the relative path.
+	             */ 
+	            
+	            String old_parent_path = old_file.getCanonicalFile().getParent();
+	            
+	            String sub_path;
+	
+	            /**
+	             * Calculate the sub path of where the file lives compared to the new save location.
+	             * 
+	             * The code here has changed from what it used to be to fix bug 1636342:
+	             *   https://sourceforge.net/tracker/?func=detail&atid=575154&aid=1636342&group_id=84122
+	             */
+	            
+	            if ( old_parent_path.startsWith(move_from_dir)){
+	            	
+	            	sub_path = old_parent_path.substring(move_from_dir.length());
+	            	
+	            }else{
+	            	
+	            	logMoveFileError(move_to_dir, "Could not determine relative path for file - " + old_parent_path);
+	            	
+	            	throw new IOException("relative path assertion failed: move_from_dir=\"" + move_from_dir + "\", old_parent_path=\"" + old_parent_path + "\"");
+	            }
+	            
+	              //create the destination dir
+	            
+	            if ( sub_path.startsWith( File.separator )){
+	            	
+	                sub_path = sub_path.substring(1);
+	            }
+	
+	            	// We may be doing a rename, and if this is a simple torrent, we have to keep the names in sync.
+	            
+	            File new_file;
+	            
+	            if ( new_name == null ){
+	            	
+	            	new_file = new File( new File( move_to_dir, sub_path ), old_file.getName());
+	            	
+	            }else{
+	            	
+	            		// renaming
+	            	
+	            	if ( simple_torrent ){
+	            		
+	                   	new_file = new File( new File( move_to_dir, sub_path ), new_name );
+	                    
+	            	}else{
+	            		
+	            			// subpath includes the old dir name, replace this with new
+	            		
+	            		int	pos = sub_path.indexOf( File.separator );
+	            		String	new_path;
+	            		if (pos == -1) {
+	            			new_path = new_name;
+	            		}
+	            		else {
+	            			// Assertion check.
+	            			String sub_sub_path = sub_path.substring(pos);
+	            			String expected_old_name = sub_path.substring(0, pos);
+	            			new_path = new_name + sub_sub_path;
+	            			boolean assert_expected_old_name = expected_old_name.equals(save_location.getName());
+	            			if (!assert_expected_old_name) {
+	            				Debug.out("Assertion check for renaming file in multi-name torrent " + (assert_expected_old_name ? "passed" : "failed") + "\n" +
+	            						"  Old parent path: " + old_parent_path + "\n" +
+	            						"  Subpath: " + sub_path + "\n" +
+	            						"  Sub-subpath: " + sub_sub_path + "\n" +
+	            						"  Expected old name: " + expected_old_name + "\n" +
+	            						"  Torrent pre-move name: " + save_location.getName() + "\n" +
+	            						"  New torrent name: " + new_name + "\n" +
+	            						"  Old file: " + old_file + "\n" +
+	            						"  Linked file: " + linked_file + "\n" +
+	            						"\n" +
+	            						"  Move-to-dir: " + move_to_dir + "\n" +
+	            						"  New path: " + new_path + "\n" +
+	            						"  Old file [name]: " + old_file.getName() + "\n"
+	            						);
+	            			}
+	            		}
+	            			
+	            		
+	                   	new_file = new File( new File( move_to_dir, new_path ), old_file.getName());
+	            	}
+	            }
+	
+	            new_files[i]  = new_file;
+	
+	            if ( !link_only[i] ){
+	
+		            total_bytes += file_lengths_to_move[i] = old_file.length();
+
+	                if ( new_file.exists()){
+	
+	                    String msg = "" + linked_file.getName() + " already exists in MoveTo destination dir";
+	
+	                    Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
+	
+	                    Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
+	                              LogAlert.AT_ERROR, "DiskManager.alert.movefileexists"),
+	                              new String[] { old_file.getName() });
+	
+	
+	                    Debug.out(msg);
+	
+	                    return false;
+	                }
+	
+	                FileUtil.mkdirs(new_file.getParentFile());
+	            }
+	        }
+	        
+	        String	abs_path = move_to_dir_name.getAbsolutePath();
+	        
+	        String	_average_config_key = null;
+	        
+	        try{
+	        	_average_config_key = "dm.move.target.abps." + Base32.encode( abs_path.getBytes( "UTF-8" ));
+	        	
+	        }catch( Throwable e ){
+	        	
+	        	Debug.out(e );
+	        }
+	        
+	        final String average_config_key	= _average_config_key;
+	        
+	        	// lazy here for rare case where all non-zero length files are links
+	        
+	        if ( total_bytes == 0 ){
+	        	
+	        	total_bytes = 1;
+	        }
+		        
+	        long	done_bytes = 0;
+	        
+	        final Object	progress_lock = new Object();
+	        final int[] 	current_file_index 	= { 0 };
+	        final long[]	current_file_bs		= { 0 };
+	        final long		f_total_bytes		= total_bytes;
+	        
+	        final long[]	last_progress_bytes		= { 0 };
+	        final long[]	last_progress_update 	= { SystemTime.getMonotonousTime() };
+	        
+	        TimerEventPeriodic timer_event1 = 
+	        	SimpleTimer.addPeriodicEvent(
+	        		"MoveFile:speedster",
+	        		1000,
+	        		new TimerEventPerformer()
+	        		{		
+	        			private long	start_time = SystemTime.getMonotonousTime();
+	        			
+	        			private long	last_update_processed;
+	        			
+	        			private long	estimated_speed = 1*1024*1024;	// 1MB/sec default
+	        				
+	        			{
+	        				if ( average_config_key != null ){
+	        				
+	        					long val = COConfigurationManager.getLongParameter( average_config_key, 0 );
+	        					
+	        					if ( val > 0 ){
+	        						
+	        						estimated_speed = val;
+	        					}
+	        				}
+	        			}
+	        			
+	        			public void 
+	        			perform(
+	        				TimerEvent event )
+	        			{
+	        				synchronized( progress_lock ){
+	        					
+	        					int file_index = current_file_index[0];
+
+	  		              		if ( file_index >= new_files.length ){
+
+	  		              			return;
+	  		              		}
+	  		              			  		              		
+	        					long 	now			= SystemTime.getMonotonousTime();
+	        					
+	        					long	last_update = last_progress_update[0];	        					
+        						long	bytes_moved = last_progress_bytes[0];
+
+	        					if ( last_update != last_update_processed ){
+	        						
+	        						last_update_processed = last_update;
+	        					        						
+	        						if ( bytes_moved > 10*1024*1024 ){
+	        						
+		        							// a usable amount of progress
+		        						
+		        						long	elapsed = now - start_time;
+		        						
+		        						estimated_speed = ( bytes_moved * 1000 ) / elapsed;
+		        						
+		        						// System.out.println( "estimated speed: " + estimated_speed );
+	        						}
+	        					}
+	        					
+	        					long	secs_since_last_update  = ( now - last_update ) / 1000;
+	        					
+	        					if ( secs_since_last_update > 2 ){
+	        					
+	        							// looks like we're not getting useful updates, add some in based on
+	        							// elapsed time and average rate
+	        						
+	        						long	file_start_overall		= current_file_bs[0];
+	        						long	file_end_overall 		= file_start_overall + file_lengths_to_move[ file_index ];
+	        						long	bytes_of_file_remaining	= file_end_overall - bytes_moved;
+	        						
+	        						long	pretend_bytes = 0;
+	        						
+	        						long	current_speed	 	= estimated_speed;
+	        						long	current_remaining	= bytes_of_file_remaining;
+	        						long	current_added		= 0;
+	        						
+	        						int		percentage_to_slow_at	= 80;
+	        						
+	        						// System.out.println( "injection pretend progress" );
+	        						
+	        						for (int i=0;i<secs_since_last_update;i++){
+	        								        							
+	        							current_added += current_speed;
+	        							pretend_bytes += current_speed;
+
+	        							// System.out.println( "    pretend=" + pretend_bytes + ", rate=" + percentage_to_slow_at + ", speed=" + current_speed );
+	        					
+	        							if ( current_added > percentage_to_slow_at*current_remaining/100 ){
+	        								
+	        								percentage_to_slow_at = 50;
+	        								
+	        								current_speed = current_speed / 2;
+	        								
+	        								current_remaining = bytes_of_file_remaining - pretend_bytes;
+	        								
+	        								current_added = 0;
+	        								
+	        								if ( current_speed < 1024 ){
+	        									
+	        									current_speed = 1024;
+	        								}
+	        							}
+	        								        							
+	        							if ( pretend_bytes >= bytes_of_file_remaining ){
+	        								
+	        								pretend_bytes = bytes_of_file_remaining;
+	        								
+	        								break;
+	        							}
+	        						}
+	        						
+	        						long	pretend_bytes_moved = bytes_moved + pretend_bytes;
+	        						
+	  		              			move_progress = (int)( 1000*pretend_bytes_moved/f_total_bytes);
+	  		              			
+	  		              			// System.out.println( "pretend prog: " + move_progress );
+	        					}
+	        				}
+	        			}
+	        		});
+	        
+	        TimerEventPeriodic timer_event2 = 
+	        	SimpleTimer.addPeriodicEvent(
+	        		"MoveFile:observer",
+	        		500,
+	        		new TimerEventPerformer()
+	        		{
+	        			public void 
+	        			perform(
+	        				TimerEvent event )
+	        			{
+	        				int			index;
+	        				File		file;
+	        				
+	  		              	synchronized( progress_lock ){
+	  		            	  
+	  		              		index = current_file_index[0];
+
+	  		              		if ( index >= new_files.length ){
+
+	  		              			return;
+	  		              		}
+
+	  		              			// unfortunately file.length() blocks on my NAS until the operation is complete :( 
+
+	  		              		file = new_files[index];
+	  		              	}
+	  		              	
+	  		              	long	file_length = file.length();
+	  		              	
+	  		              	synchronized( progress_lock ){
+	  		              		
+	  		              		if ( index == current_file_index[0]){
+	  		              
+	  		              			long	done_bytes = current_file_bs[0] + file_length;
+	  		            		
+	  		              			move_progress = (int)( 1000*done_bytes/f_total_bytes);
+	  		              			
+	  		              			last_progress_bytes[0]	= done_bytes;
+	  		              			last_progress_update[0]	= SystemTime.getMonotonousTime();
+	  		              		}
+	  		              	} 
+	        			}
+	        		});
+
+        	long	start = SystemTime.getMonotonousTime();
+
+	        try{
+	        	
+		        for (int i=0; i < files.length; i++){
+		
+		            File new_file = new_files[i];
+		
+		            try{
+		
+		              long initial_done_bytes = done_bytes;
+		              		              
+		              files[i].moveFile( new_file, link_only[i] );
+		
+		              synchronized( progress_lock ){
+		            	  
+		            	  current_file_index[0] = i+1;
+
+		            	  done_bytes = initial_done_bytes + file_lengths_to_move[i];
+		            	  
+		            	  current_file_bs[0] = done_bytes;
+		            	  
+			              move_progress = (int)( 1000*done_bytes/total_bytes);
+
+			              last_progress_bytes[0]	= done_bytes;
+		            	  last_progress_update[0]	= SystemTime.getMonotonousTime();
+		              }
+		              		              
+		              if ( change_to_read_only ){
+		
+		                  files[i].setAccessMode(DiskManagerFileInfo.READ);
+		              }
+		
+		            }catch( CacheFileManagerException e ){
+		
+		              String msg = "Failed to move " + old_files[i].toString() + " to destination dir";
+		
+		              Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
+		
+		              Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
+		                              LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
+		                              new String[] { old_files[i].toString(),
+		                                      Debug.getNestedExceptionMessage(e) });
+		
+		                  // try some recovery by moving any moved files back...
+		
+		              for (int j=0;j<i;j++){
+		
+		                  try{
+		                      files[j].moveFile( old_files[j],  link_only[j]);
+		
+		                  }catch( CacheFileManagerException f ){
+		
+		                      Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
+		                                      LogAlert.AT_ERROR,
+		                                      "DiskManager.alert.movefilerecoveryfails"),
+		                                      new String[] { old_files[j].toString(),
+		                                              Debug.getNestedExceptionMessage(f) });
+		
+		                  }
+		              }
+		
+		              return false;
+		            }
+		        }
+	        }finally{
+	        	
+	        	timer_event1.cancel();
+	        	timer_event2.cancel();
+	        }
+	        
+	        long	elapsed_secs = ( SystemTime.getMonotonousTime() - start )/1000;
+	        
+	        if ( total_bytes > 10*1024*1024 && elapsed_secs > 10 ){
+	        	
+	        	long	bps = total_bytes / elapsed_secs;
+	        	
+	        	if ( average_config_key != null ){
+    				
+					COConfigurationManager.setParameter( average_config_key, bps );
+	        	}
+	        }
+	        
+	        //remove the old dir
+	
+	        if (  save_location.isDirectory()){
+	
+	        	TorrentUtils.recursiveEmptyDirDelete( save_location, false );
+	        }
+	
+	        // NOTE: this operation FIXES up any file links
+	
+	        if ( new_name == null ){
+	        	
+	           	download_manager.setTorrentSaveDir( move_to_dir );
+	
+	        }else{
+	        	
+	        	download_manager.setTorrentSaveDir( move_to_dir, new_name );
+	        }
+	        
+	        return true;
+	        
+        }finally{
  
-        final String move_from_dir	= save_location.getParentFile().getCanonicalFile().getPath();        
-         
-         
-        File[]    new_files   = new File[files.length];
-        File[]    old_files   = new File[files.length];
-        boolean[] link_only   = new boolean[files.length];
+        	synchronized( got_there ){
+        		
+        		got_there[0] = true;
+        	}
+        }
+    }
+    
+    private void moveTorrentFile(SaveLocationChange loc_change) {
+    	if (!loc_change.hasTorrentChange()) {return;}
 
-        for (int i=0; i < files.length; i++) {
+		File old_torrent_file = new File(download_manager.getTorrentFileName());
+		File new_torrent_file = loc_change.normaliseTorrentLocation(old_torrent_file);
+		
+		if (!old_torrent_file.exists()) {
+            // torrent file's been removed in the meantime, just log a warning
+            if (Logger.isEnabled())
+                  Logger.log(new LogEvent(this, LOGID, LogEvent.LT_WARNING, "Torrent file '" + old_torrent_file.getPath() + "' has been deleted, move operation ignored" ));
+            return;
+		}
+    	
+    	try {download_manager.setTorrentFile(loc_change.torrent_location, loc_change.torrent_name);}
+    	catch (DownloadManagerException e) {
+            String msg = "Failed to move " + old_torrent_file.toString() + " to " + new_torrent_file.toString();
 
-            File old_file = files[i].getFile(false);
+            if (Logger.isEnabled())
+                Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
 
-            File linked_file = FMFileManagerFactory.getSingleton().getFileLink( torrent, old_file );
+            Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
+                            LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
+                            new String[] { old_torrent_file.toString(),
+                                    new_torrent_file.toString() });
 
-            if ( !linked_file.equals(old_file)){
+            Debug.out(msg);
+       	}
+    }
 
-                if ( simple_torrent ){
+    public TOTorrent
+    getTorrent()
+    {
+        return( torrent );
+    }
 
-                    // simple torrent, only handle a link if its a simple rename
 
-                    if ( linked_file.getParentFile().getCanonicalPath().equals( save_location.getParentFile().getCanonicalPath())){
+    public void
+    addListener(
+        DiskManagerListener l )
+    {
+        listeners.addListener( l );
 
-                        old_file  = linked_file;
-
-                    }else{
-
-                        link_only[i] = true;
-                    }
-                    
-                }else{
-                      // if we are linked to a file outside of the torrent's save directory then we don't
-                      // move the file
-
-                    if ( linked_file.getCanonicalPath().startsWith( save_location.getCanonicalPath())){
-
-                        old_file  = linked_file;
-
-                    }else{
-
-                        link_only[i] = true;
-                    }
-                }
-            }
-            
-            /**
-             * We are trying to calculate the relative path of the file within the original save
-             * directory, and then use that to calculate the new save path of the file in the new
-             * save directory.
-             * 
-             * We have three cases which we may deal with:
-             *   1) Where the file in the torrent has never been moved (therefore, old_file will
-             *      equals linked_file),
-             *   2) Where the file in the torrent has been moved somewhere elsewhere inside the save
-             *      path (old_file will not equal linked_file, but we will overwrite the value of
-             *      old_file with linked_file),
-             *   3) Where the file in the torrent has been moved outside of the download path - meaning
-             *      we set link_only[i] to true. This is just to update the internal reference of where
-             *      the file should be - it doesn't move the file at all.
-             *      
-             * Below, we will determine a new path for the file, but only in terms of where it should be
-             * inside the new download save location - if the file currently exists outside of the save
-             * location, we will not move it.
-             */
-            
-            old_files[i] = old_file;
-            
-            /**
-             * move_from_dir should be canonical (see earlier code).
-             * 
-             * Need to get canonical form of the old file, because that's what we are using for determining
-             * the relative path.
-             */ 
-            
-            String old_parent_path = old_file.getCanonicalFile().getParent();
-            
-            String sub_path;
-
-            /**
-             * Calculate the sub path of where the file lives compared to the new save location.
-             * 
-             * The code here has changed from what it used to be to fix bug 1636342:
-             *   https://sourceforge.net/tracker/?func=detail&atid=575154&aid=1636342&group_id=84122
-             */
-            
-            if ( old_parent_path.startsWith(move_from_dir)){
-            	
-            	sub_path = old_parent_path.substring(move_from_dir.length());
-            	
-            }else{
-            	
-            	logMoveFileError(move_to_dir, "Could not determine relative path for file - " + old_parent_path);
-            	
-            	throw new IOException("relative path assertion failed: move_from_dir=\"" + move_from_dir + "\", old_parent_path=\"" + old_parent_path + "\"");
-            }
-            
-              //create the destination dir
-            
-            if ( sub_path.startsWith( File.separator )){
-            	
-                sub_path = sub_path.substring(1);
-            }
-
-            	// We may be doing a rename, and if this is a simple torrent, we have to keep the names in sync.
-            
-            File new_file;
-            
-            if ( new_name == null ){
-            	
-            	new_file = new File( new File( move_to_dir, sub_path ), old_file.getName());
-            	
-            }else{
-            	
-            		// renaming
-            	
-            	if ( simple_torrent ){
-            		
-                   	new_file = new File( new File( move_to_dir, sub_path ), new_name );
-                    
-            	}else{
-            		
-            			// subpath includes the old dir name, replace this with new
-            		
-            		int	pos = sub_path.indexOf( File.separator );
-            		String	new_path;
-            		if (pos == -1) {
-            			new_path = new_name;
-            		}
-            		else {
-            			// Assertion check.
-            			String sub_sub_path = sub_path.substring(pos);
-            			String expected_old_name = sub_path.substring(0, pos);
-            			new_path = new_name + sub_sub_path;
-            			boolean assert_expected_old_name = expected_old_name.equals(save_location.getName());
-            			if (!assert_expected_old_name) {
-            				Debug.out("Assertion check for renaming file in multi-name torrent " + (assert_expected_old_name ? "passed" : "failed") + "\n" +
-            						"  Old parent path: " + old_parent_path + "\n" +
-            						"  Subpath: " + sub_path + "\n" +
-            						"  Sub-subpath: " + sub_sub_path + "\n" +
-            						"  Expected old name: " + expected_old_name + "\n" +
-            						"  Torrent pre-move name: " + save_location.getName() + "\n" +
-            						"  New torrent name: " + new_name + "\n" +
-            						"  Old file: " + old_file + "\n" +
-            						"  Linked file: " + linked_file + "\n" +
-            						"\n" +
-            						"  Move-to-dir: " + move_to_dir + "\n" +
-            						"  New path: " + new_path + "\n" +
-            						"  Old file [name]: " + old_file.getName() + "\n"
-            						);
-            			}
-            		}
-            			
-            		
-                   	new_file = new File( new File( move_to_dir, new_path ), old_file.getName());
-            	}
-            }
-
-            new_files[i]  = new_file;
-
-            if ( !link_only[i] ){
-
-                if ( new_file.exists()){
-
-                    String msg = "" + linked_file.getName() + " already exists in MoveTo destination dir";
-
-                    Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
-
-                    Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
-                              LogAlert.AT_ERROR, "DiskManager.alert.movefileexists"),
-                              new String[] { old_file.getName() });
-
-
-                    Debug.out(msg);
-
-                    return false;
-                }
-
-                FileUtil.mkdirs(new_file.getParentFile());
-            }
-        }
-
-        for (int i=0; i < files.length; i++){
-
-            File new_file = new_files[i];
-
-            try{
-
-              files[i].moveFile( new_file, link_only[i] );
-
-              if ( change_to_read_only ){
-
-                  files[i].setAccessMode(DiskManagerFileInfo.READ);
-              }
-
-            }catch( CacheFileManagerException e ){
-
-              String msg = "Failed to move " + old_files[i].toString() + " to destination dir";
-
-              Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
-
-              Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
-                              LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
-                              new String[] { old_files[i].toString(),
-                                      Debug.getNestedExceptionMessage(e) });
-
-                  // try some recovery by moving any moved files back...
-
-              for (int j=0;j<i;j++){
-
-                  try{
-                      files[j].moveFile( old_files[j],  link_only[j]);
-
-                  }catch( CacheFileManagerException f ){
-
-                      Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
-                                      LogAlert.AT_ERROR,
-                                      "DiskManager.alert.movefilerecoveryfails"),
-                                      new String[] { old_files[j].toString(),
-                                              Debug.getNestedExceptionMessage(f) });
-
-                  }
-              }
-
-              return false;
-            }
-        }
-
-        //remove the old dir
-
-        if (  save_location.isDirectory()){
-
-        	TorrentUtils.recursiveEmptyDirDelete( save_location, false );
-        }
-
-        // NOTE: this operation FIXES up any file links
-
-        if ( new_name == null ){
-        	
-           	download_manager.setTorrentSaveDir( move_to_dir );
-
-        }else{
-        	
-        	download_manager.setTorrentSaveDir( move_to_dir, new_name );
-        }
-        
-        return true;
-
-    }
-    
-    private void moveTorrentFile(SaveLocationChange loc_change) {
-    	if (!loc_change.hasTorrentChange()) {return;}
-
-		File old_torrent_file = new File(download_manager.getTorrentFileName());
-		File new_torrent_file = loc_change.normaliseTorrentLocation(old_torrent_file);
-		
-		if (!old_torrent_file.exists()) {
-            // torrent file's been removed in the meantime, just log a warning
-            if (Logger.isEnabled())
-                  Logger.log(new LogEvent(this, LOGID, LogEvent.LT_WARNING, "Torrent file '" + old_torrent_file.getPath() + "' has been deleted, move operation ignored" ));
-            return;
-		}
-    	
-    	try {download_manager.setTorrentFile(loc_change.torrent_location, loc_change.torrent_name);}
-    	catch (DownloadManagerException e) {
-            String msg = "Failed to move " + old_torrent_file.toString() + " to " + new_torrent_file.toString();
-
-            if (Logger.isEnabled())
-                Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, msg));
-
-            Logger.logTextResource(new LogAlert(this, LogAlert.REPEATABLE,
-                            LogAlert.AT_ERROR, "DiskManager.alert.movefilefails"),
-                            new String[] { old_torrent_file.toString(),
-                                    new_torrent_file.toString() });
-
-            Debug.out(msg);
-       	}
-    }
-
-    public TOTorrent
-    getTorrent()
-    {
-        return( torrent );
-    }
-
-
-    public void
-    addListener(
-        DiskManagerListener l )
-    {
-        listeners.addListener( l );
-
-        int params[] = {getState(), getState()};
+        int params[] = {getState(), getState()};
 
         listeners.dispatch( l, LDT_STATECHANGED, params);
     }
@@ -2307,12 +2815,11 @@ DiskManagerImpl
             }else{
 
                 PlatformManager mgr = PlatformManagerFactory.getPlatformManager();
-                
-                if( 	Constants.isOSX &&
-                		torrent_save_file.length() > 0 &&
-                		COConfigurationManager.getBooleanParameter("Move Deleted Data To Recycle Bin" ) &&
+                if( Constants.isOSX &&
+                      torrent_save_file.length() > 0 &&
+                      COConfigurationManager.getBooleanParameter("Move Deleted Data To Recycle Bin" ) &&
                 		(! force_no_recycle ) &&
-                		mgr.hasCapability(PlatformManagerCapabilities.RecoverableFileDelete) ) {
+                      mgr.hasCapability(PlatformManagerCapabilities.RecoverableFileDelete) ) {
 
                     try
                     {
@@ -2430,8 +2937,8 @@ DiskManagerImpl
 
     private static void
     deleteDataFileContents(
-        TOTorrent 	torrent,
-        String 		torrent_save_dir,
+        TOTorrent torrent,
+        String torrent_save_dir,
         String 		torrent_save_file,
         boolean		force_no_recycle )
 
@@ -2537,38 +3044,7 @@ DiskManagerImpl
   private void
   loadFilePriorities()
   {
-      loadFilePriorities( download_manager, fileset );
-  }
-
-  private static void
-  loadFilePriorities(
-    DownloadManager         download_manager,
-    DiskManagerFileInfoSet   fileSet )
-  {
-    //  TODO: remove this try/catch.  should only be needed for those upgrading from previous snapshot
-    try {
-    	DiskManagerFileInfo[] files = fileSet.getFiles();
-    	
-        if ( files == null ) return;
-        List file_priorities = (List)download_manager.getData( "file_priorities" );
-        if ( file_priorities == null ) return;
-        
-        boolean[] toSkip = new boolean[files.length];
-        boolean[] prio = new boolean[files.length];
-        
-        for (int i=0; i < files.length; i++) {
-            DiskManagerFileInfo file = files[i];
-            if (file == null) return;
-            int priority = ((Long)file_priorities.get( i )).intValue();
-            if ( priority == 0 ) toSkip[i] = true;
-            else if (priority == 1) prio[i] = true;
-        }
-        
-        fileSet.setPriority(prio, true);
-        fileSet.setSkipped(toSkip, true);
-        
-    }
-    catch (Throwable t) {Debug.printStackTrace( t );}
+      DiskManagerUtil.loadFilePriorities( download_manager, fileset );
   }
 
   protected void
@@ -2582,19 +3058,7 @@ DiskManagerImpl
     DownloadManager         download_manager,
     DiskManagerFileInfo[]   files )
   {
-    if ( files == null ) return;
-    List file_priorities = new ArrayList(files.length);
-    for (int i=0; i < files.length; i++) {
-      DiskManagerFileInfo file = files[i];
-      if (file == null) return;
-      boolean skipped = file.isSkipped();
-      boolean priority = file.isPriority();
-      int value = -1;
-      if ( skipped ) value = 0;
-      else if ( priority ) value = 1;
-      file_priorities.add( i, new Long(value));
-    }
-    download_manager.setData( "file_priorities", file_priorities );
+	  DiskManagerUtil.storeFilePriorities ( download_manager, files );
   }
 
   protected static void
@@ -2624,39 +3088,6 @@ DiskManagerImpl
       }
   }
 
-  protected static void
-  loadFileDownloaded(
-    DownloadManager             download_manager,
-    DiskManagerFileInfoHelper[] files )
-  {
-      DownloadManagerState  state = download_manager.getDownloadState();
-
-      Map   details = state.getMapAttribute( DownloadManagerState.AT_FILE_DOWNLOADED );
-
-      if ( details == null ){
-
-          return;
-      }
-
-      List  downloaded = (List)details.get( "downloaded" );
-
-      if ( downloaded == null ){
-
-          return;
-      }
-
-      try{
-          for (int i=0;i<files.length;i++){
-
-              files[i].setDownloaded(((Long)downloaded.get(i)).longValue());
-          }
-     }catch( Throwable e ){
-
-         Debug.printStackTrace(e);
-     }
-
-  }
-
   public void
   saveState()
   {
@@ -2709,738 +3140,65 @@ DiskManagerImpl
     	return( getStorageType( download_manager , fileIndex));
     }
 
-    // Used by DownloadManagerImpl too.
+    	// Used by DownloadManagerImpl too.
+    
     public static String[] getStorageTypes(DownloadManager download_manager) {
         DownloadManagerState state = download_manager.getDownloadState();
         String[] types = state.getListAttribute(DownloadManagerState.AT_FILE_STORE_TYPES);
         if (types.length == 0) {
+        	TOTorrentFile[] files = download_manager.getTorrent().getFiles();
             types = new String[download_manager.getTorrent().getFiles().length];
-            for (int i=0; i<types.length; i++){
-                types[i] = "L";
+            
+         	if ( reorder_storage_mode ){
+        		
+        		int	existing = state.getIntAttribute( DownloadManagerState.AT_REORDER_MIN_MB );
+        		
+        		if ( existing < 0 ){
+        			
+        			existing = reorder_storage_mode_min_mb;
+        			
+        			state.setIntAttribute( DownloadManagerState.AT_REORDER_MIN_MB, existing );
+        		}
+                  		
+        		for (int i=0; i<types.length; i++){
+                           		
+            		if ( files[i].getLength()/(1024*1024) >= existing ){
+            			            			
+            			types[i] = "R";
+            			
+            		}else{
+            			
+            			types[i] = "L";
+            		}
+            	}
+          	}else{
+         		
+         		for (int i=0; i<types.length; i++){
+         			
+         			types[i] = "L";
+         		}
             }
+         	
+			state.setListAttribute(DownloadManagerState.AT_FILE_STORE_TYPES, types );
         }
+        
         return( types );
     }
     
-    // Used by DownloadManagerImpl too.
+    	// Used by DownloadManagerImpl too.
+    
     public static String getStorageType(DownloadManager download_manager, int fileIndex) {
         DownloadManagerState state = download_manager.getDownloadState();
         String type = state.getListAttribute(DownloadManagerState.AT_FILE_STORE_TYPES,fileIndex);
         
-        return type != null ? type : "L";
-    }
-    
-    private static boolean
-    setFileLink(
-        DownloadManager         download_manager,
-        DiskManagerFileInfo[]   info,
-        DiskManagerFileInfo     file_info,
-        File                    from_file,
-        File                    to_link )
-    {
-            // existing link is that for the TO_LINK and will come back as TO_LINK if no link is defined
-
-        File    existing_link = FMFileManagerFactory.getSingleton().getFileLink( download_manager.getTorrent(), to_link );
-
-        if ( !existing_link.equals( to_link )){
-
-                // where we're mapping to is already linked somewhere else. Only case we support
-                // is where this is a remapping of the same file back to where it came from
-
-            if ( !from_file.equals( to_link )){
-
-                Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
-                                "Attempt to link to existing link '" + existing_link.toString()
-                                        + "'"));
-
-                return( false );
-            }
-        }
-
-        File    existing_file = file_info.getFile( true );
-
-        if ( to_link.equals( existing_file )){
-
-                // already pointing to the right place
-
-            return( true );
-        }
-
-        for (int i=0;i<info.length;i++){
-
-            if ( to_link.equals( info[i].getFile( true ))){
-
-                Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
-                                "Attempt to link to existing file '" + info[i].getFile(true)
-                                        + "'"));
-
-                return( false );
-            }
-        }
-
-        if ( to_link.exists()){
-
-            if ( !existing_file.exists()){
-
-                    // using a new file, make sure we recheck
-
-                download_manager.recheckFile( file_info );
-
-            }else{
-
-                if ( FileUtil.deleteWithRecycle( 
-                		existing_file,
-                		download_manager.getDownloadState().getFlag( DownloadManagerState.FLAG_LOW_NOISE ))){
-
-                        // new file, recheck
-
-                    download_manager.recheckFile( file_info );
-
-                }else{
-
-                    Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
-                            "Failed to delete '" + existing_file.toString() + "'"));
-
-                    return( false );
-                }
-            }
-        }else{
-
-            if ( existing_file.exists()){
-
-                if ( !FileUtil.renameFile( existing_file, to_link )){
-
-                    Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
-                        "Failed to rename '" + existing_file.toString() + "'" ));
-
-                    return( false );
-                }
-            }
-        }
-
-        DownloadManagerState    state = download_manager.getDownloadState();
-
-        state.setFileLink( from_file, to_link );
-
-        state.save();
-
-        return( true );
-    }
-    
-    static abstract class FileSkeleton implements DiskManagerFileInfoHelper {
-        protected boolean priority;
-        protected boolean skipped;
-    	protected long    downloaded;
-    }
-    
-    public static DiskManagerFileInfoSet
-    getFileInfoSkeleton(
-        final DownloadManager       download_manager,
-        final DiskManagerListener   listener )
-    {
-        TOTorrent   torrent = download_manager.getTorrent();
-
-        if ( torrent == null ){
-
-            return( new DiskManagerFileInfoSetImpl(new DiskManagerFileInfoImpl[0],null) );
-        }
-
-        String  tempRootDir = download_manager.getAbsoluteSaveLocation().getParent();
-        
-        if(tempRootDir == null) // in case we alraedy are at the root
-        	tempRootDir = download_manager.getAbsoluteSaveLocation().getPath();
-        
-
-        if ( !torrent.isSimpleTorrent()){
-        	tempRootDir += File.separator + download_manager.getAbsoluteSaveLocation().getName();
+        if ( type != null ){
+        	
+        	return( type );
         }
-
-        tempRootDir    += File.separator;
         
-        final String root_dir = tempRootDir;
-
-        try{
-            final LocaleUtilDecoder locale_decoder = LocaleTorrentUtil.getTorrentEncoding( torrent );
-
-            TOTorrentFile[] torrent_files = torrent.getFiles();
-
-            final FileSkeleton[]   res = new FileSkeleton[ torrent_files.length ];
-            
-            final DiskManagerFileInfoSet fileSetSkeleton = new DiskManagerFileInfoSet() {
-
-				public DiskManagerFileInfo[] getFiles() {
-					return res;
-				}
-
-				public int nbFiles() {
-					return res.length;
-				}
-
-				public void setPriority(boolean[] toChange, boolean setPriority) {
-					if(toChange.length != res.length)
-						throw new IllegalArgumentException("array length mismatches the number of files");
-					
-					for(int i=0;i<res.length;i++)
-						if(toChange[i])
-							res[i].priority = setPriority;
-					
-					storeFilePriorities( download_manager, res);
-					
-					
-					
-					for(int i=0;i<res.length;i++)
-						if(toChange[i])
-							listener.filePriorityChanged(res[i]);
-				}
-
-				public void setSkipped(boolean[] toChange, boolean setSkipped) {
-					if(toChange.length != res.length)
-						throw new IllegalArgumentException("array length mismatches the number of files");
-					
-            		if (!setSkipped && !Arrays.equals(toChange,setStorageTypes(toChange, FileSkeleton.ST_LINEAR))){
-            			return;
-            		}
-            		
-					for(int i=0;i<res.length;i++)
-						if(toChange[i])
-							res[i].skipped = setSkipped;
-					
-					if(!setSkipped)
-						DiskManagerUtil.doFileExistenceChecks(this, toChange, download_manager, true);
-					
-					storeFilePriorities( download_manager, res);
-					
-					for(int i=0;i<res.length;i++)
-						if(toChange[i])
-							listener.filePriorityChanged(res[i]);
-				}
-
-				public boolean[] setStorageTypes(boolean[] toChange, int newStroageType) {
-					if(toChange.length != res.length)
-						throw new IllegalArgumentException("array length mismatches the number of files");
-					
-					String[] types = getStorageTypes(download_manager);
-					boolean[] modified = new boolean[res.length];
-					boolean[] toSkip = new boolean[res.length];
-					int toSkipCount = 0;
-					DownloadManagerState dmState = download_manager.getDownloadState();
-					
-					try {
-						dmState.suppressStateSave(true);
-
-						for(int i=0;i<res.length;i++)
-						{
-							if(!toChange[i])
-								continue;
-
-
-							final int idx = i;
-
-							int old_type = types[i].equals( "L")?FileSkeleton.ST_LINEAR:FileSkeleton.ST_COMPACT;
-
-							//System.out.println(old_type + " <> " + newStroageType);
-
-							if ( newStroageType == old_type )
-							{
-								modified[i] = true;
-								continue;
-							}
-
-							try{
-								File    target_file = res[i].getFile( true );
-
-								// if the file doesn't exist then this is the start-of-day, most likely
-								// being called from the torrent-opener, so we don't need to do any
-								// file fiddling (in fact, if we do, we end up leaving zero length
-								// files for dnd files which then force a recheck when the download
-								// starts for the first time)
-
-								if ( target_file.exists()){
-
-									CacheFile cache_file =
-										CacheFileManagerFactory.getSingleton().createFile(
-											new CacheFileOwner()
-											{
-												public String
-												getCacheFileOwnerName()
-												{
-													return( download_manager.getInternalName());
-												}
-
-												public TOTorrentFile
-												getCacheFileTorrentFile()
-												{
-													return( res[idx].getTorrentFile() );
-												}
-
-												public File
-												getCacheFileControlFileDir()
-												{
-													return( download_manager.getDownloadState().getStateFile( ));
-												}
-												public int
-												getCacheMode()
-												{
-													return( CacheFileOwner.CACHE_MODE_NORMAL );
-												}
-											},
-											target_file,
-											newStroageType==FileSkeleton.ST_LINEAR?CacheFile.CT_LINEAR:CacheFile.CT_COMPACT );
-
-									cache_file.close();
-
-									toSkip[i] = newStroageType == FileSkeleton.ST_COMPACT && !res[i].isSkipped();
-									if(toSkip[i])
-										toSkipCount++;
-								}
-
-
-								modified[i] = true;
-
-							}catch( Throwable e ){
-
-								Debug.printStackTrace(e);
-
-								Logger.log(
-									new LogAlert(download_manager,
-										LogAlert.REPEATABLE,
-										LogAlert.AT_ERROR,
-										"Failed to change storage type for '" + res[i].getFile(true) +"': " + Debug.getNestedExceptionMessage(e)));
-
-								// download's not running - tag for recheck
-
-								RDResumeHandler.recheckFile( download_manager, res[i] );
-
-							}
-
-							types[i] = newStroageType== FileSkeleton.ST_LINEAR?"L":"C";
-						}
-						
-						/*
-						 * set storage type and skipped before we do piece clearing and file
-						 * clearing checks as those checks work better when skipped/stype is set
-						 * properly
-						 */
-						dmState.setListAttribute( DownloadManagerState.AT_FILE_STORE_TYPES, types);
-						if(toSkipCount > 0)
-							setSkipped(toSkip, true);
-						
-						
-						for(int i=0;i<res.length;i++)
-						{
-							if(!toChange[i])
-								continue;
-							
-							// download's not running, update resume data as necessary
-
-							int cleared = RDResumeHandler.storageTypeChanged( download_manager, res[i] );
-
-							// try and maintain reasonable figures for downloaded. Note that because
-							// we don't screw with the first and last pieces of the file during
-							// storage type changes we don't have the problem of dealing with
-							// the last piece being smaller than torrent piece size
-
-							if (cleared > 0)
-							{
-								res[i].downloaded = res[i].downloaded - cleared * res[i].getTorrentFile().getTorrent().getPieceLength();
-								if (res[i].downloaded < 0) res[i].downloaded = 0;
-							}
-						}
-
-						storeFileDownloaded( download_manager, res, true );
-
-						DiskManagerUtil.doFileExistenceChecks(this, toChange, download_manager, newStroageType == FileSkeleton.ST_LINEAR);
-
-					} finally {
-						dmState.suppressStateSave(false);
-						dmState.save();
-					}
-					
-					return modified;
-				}
-            };
-
-            for (int i=0;i<res.length;i++){
-
-                final TOTorrentFile torrent_file    = torrent_files[i];
-
-                final int file_index = i;
-
-                FileSkeleton info = new FileSkeleton() {
-
-                	private CacheFile   read_cache_file;
-                	// do not access this field directly, use lazyGetFile() instead 
-                	private WeakReference dataFile = new WeakReference(null);
-
-                	public void
-                	setPriority(boolean b)
-                	{
-                		priority    = b;
-
-                		storeFilePriorities( download_manager, res );
-
-                		listener.filePriorityChanged( this );
-                	}
-
-                	public void
-                	setSkipped(boolean _skipped)
-                	{
-                		if ( !_skipped && getStorageType() == ST_COMPACT ){
-                			if ( !setStorageType( ST_LINEAR )){
-                				return;
-                			}
-                		}
-
-                		skipped = _skipped;
-
-                		storeFilePriorities( download_manager, res );
-                		
-                		if(!_skipped)
-                		{
-                			boolean[] toCheck = new boolean[fileSetSkeleton.nbFiles()];
-                			toCheck[file_index] = true;
-                			DiskManagerUtil.doFileExistenceChecks(fileSetSkeleton, toCheck, download_manager, true);                			
-                		}
-                		
-
-                		listener.filePriorityChanged( this );
-                	}
-
-                	public int
-                	getAccessMode()
-                	{
-                		return( READ );
-                	}
-
-                	public long
-                	getDownloaded()
-                	{
-                		return( downloaded );
-                	}
-
-                	public void
-                	setDownloaded(
-                		long    l )
-                	{
-                		downloaded  = l;
-                	}
-
-                	public String
-                	getExtension()
-                	{
-                		String    data_name   = lazyGetFile().getName();
-                		int separator = data_name.lastIndexOf(".");
-                		if (separator == -1)
-                			separator = 0;
-                		return data_name.substring(separator);
-                	}
-
-                	public int
-                	getFirstPieceNumber()
-                	{
-                		return( torrent_file.getFirstPieceNumber());
-                	}
-
-                	public int
-                	getLastPieceNumber()
-                	{
-                		return( torrent_file.getLastPieceNumber());
-                	}
-
-                	public long
-                	getLength()
-                	{
-                		return( torrent_file.getLength());
-                	}
-
-                	public int
-                	getIndex()
-                	{
-                		return( file_index );
-                	}
-
-                	public int
-                	getNbPieces()
-                	{
-                		return( torrent_file.getNumberOfPieces());
-                	}
-
-                	public boolean
-                	isPriority()
-                	{
-                		return( priority );
-                	}
-
-                	public boolean
-                	isSkipped()
-                	{
-                		return( skipped );
-                	}
-
-                	public DiskManager
-                	getDiskManager()
-                	{
-                		return( null );
-                	}
-
-                	public DownloadManager
-                	getDownloadManager()
-                	{
-                		return( download_manager );
-                	}
-
-                	public File
-                	getFile(
-                		boolean follow_link )
-                	{
-                		if ( follow_link ){
-
-                			File link = getLink();
-
-                			if ( link != null ){
-
-                				return( link );
-                			}
-                		}
-                		return lazyGetFile();
-                	}
-
-                	private File lazyGetFile()
-                	{
-                		File toReturn = (File)dataFile.get();
-                		if(toReturn != null)
-                			return toReturn;
-
-                		TOTorrent tor = download_manager.getTorrent();
-
-                		String  path_str = root_dir;
-                		File simpleFile = null;
-
-                		// for a simple torrent the target file can be changed
-
-                		if ( tor.isSimpleTorrent()){
-
-                			simpleFile = download_manager.getAbsoluteSaveLocation();
-
-                		}else{
-                			byte[][]path_comps = torrent_file.getPathComponents();
-
-                			for (int j=0;j<path_comps.length;j++){
-
-                				String comp;
-                				try
-                				{
-                					comp = locale_decoder.decodeString( path_comps[j] );
-                				} catch (UnsupportedEncodingException e)
-                				{
-                					Debug.printStackTrace(e);
-                					comp = "undecodableFileName"+file_index;
-                				}
-
-                				comp = FileUtil.convertOSSpecificChars( comp,  j != path_comps.length-1 );
-
-                				path_str += (j==0?"":File.separator) + comp;
-                			}
-                		}
-
-                		dataFile = new WeakReference(toReturn = simpleFile != null ? simpleFile : new File( path_str ));
-
-                		//System.out.println("new file:"+toReturn);
-                		return toReturn;
-                	}
-
-                	public TOTorrentFile
-                	getTorrentFile()
-                	{
-                		return( torrent_file );
-                	}
-
-                	public boolean
-                	setLink(
-                		File    link_destination )
-                	{
-                		/**
-                		 * If we a simple torrent, then we'll redirect the call to the download and move the
-                		 * data files that way - that'll keep everything in sync.
-                		 */  
-                		if (download_manager.getTorrent().isSimpleTorrent()) {
-                			try {
-                				download_manager.moveDataFiles(link_destination.getParentFile(), link_destination.getName());
-                				return true;
-                			}
-                			catch (DownloadManagerException e) {
-                				// What should we do with the error?
-                				return false;
-                			}
-                		}
-                		return setLinkAtomic(link_destination);
-                	}
-
-                	public boolean
-                	setLinkAtomic(
-                		File    link_destination )
-                	{
-                		return( setFileLink( download_manager, res, this, lazyGetFile(), link_destination ));
-                	}
-
-                	public File
-                	getLink()
-                	{
-                		return( download_manager.getDownloadState().getFileLink( lazyGetFile() ));
-                	}
-
-                	public boolean setStorageType(int type) {
-                		boolean[] change = new boolean[res.length];
-                		change[file_index] = true;
-                		return fileSetSkeleton.setStorageTypes(change, type)[file_index];
-                	}
-
-                	public int
-                	getStorageType()
-                	{
-                		return( DiskManagerImpl.getStorageType(download_manager, file_index).equals("L")?ST_LINEAR:ST_COMPACT );
-                	}
-
-                	public void
-                	flushCache()
-                	{
-                	}
-
-                	public DirectByteBuffer
-                	read(
-                		long    offset,
-                		int     length )
-
-                	throws IOException
-                	{
-                		try{
-                			cache_read_mon.enter();
-
-                			if ( read_cache_file == null ){
-
-                				try{
-                					int type = DiskManagerImpl.getStorageType(download_manager, file_index).equals( "L")?ST_LINEAR:ST_COMPACT;
-
-                					read_cache_file =
-                						CacheFileManagerFactory.getSingleton().createFile(
-                							new CacheFileOwner()
-                							{
-                								public String
-                								getCacheFileOwnerName()
-                								{
-                									return( download_manager.getInternalName());
-                								}
-
-                								public TOTorrentFile
-                								getCacheFileTorrentFile()
-                								{
-                									return( torrent_file );
-                								}
-
-                								public File
-                								getCacheFileControlFileDir()
-                								{
-                									return( download_manager.getDownloadState().getStateFile( ));
-                								}
-                								public int
-                								getCacheMode()
-                								{
-                									return( CacheFileOwner.CACHE_MODE_NORMAL );
-                								}
-                							},
-                							getFile( true ),
-                							type==ST_LINEAR?CacheFile.CT_LINEAR:CacheFile.CT_COMPACT );
-
-                				}catch( Throwable e ){
-
-                					Debug.printStackTrace(e);
-
-                					throw( new IOException( e.getMessage()));
-                				}
-                			}
-                		}finally{
-
-                			cache_read_mon.exit();
-                		}
-
-                		DirectByteBuffer    buffer =
-                			DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_DM_READ, length );
-
-                		try{
-                			read_cache_file.read( buffer, offset, CacheFile.CP_READ_CACHE );
-
-                		}catch( Throwable e ){
-
-                			buffer.returnToPool();
-
-                			Debug.printStackTrace(e);
-
-                			throw( new IOException( e.getMessage()));
-                		}
-
-                		return( buffer );
-                	}
-
-                	public void
-                	close()
-                	{
-                		if ( read_cache_file != null ){
-
-                			try{
-                				read_cache_file.close();
-
-                			}catch( Throwable e ){
-
-                				Debug.printStackTrace(e);
-                			}
-
-                			read_cache_file = null;
-                		}
-                	}
-
-                	public void
-                	addListener(
-                		DiskManagerFileInfoListener listener )
-                	{
-                		if ( getDownloaded() == getLength()){
-
-                			try{
-                				listener.dataWritten( 0, getLength());
-
-                				listener.dataChecked( 0, getLength());
-
-                			}catch( Throwable e ){
-
-                				Debug.printStackTrace(e);
-                			}
-                		}
-                	}
-
-                	public void
-                	removeListener(
-                		DiskManagerFileInfoListener listener )
-                	{
-                	}
-                };
-
-                res[i]  = info;
-            }
-
-            loadFilePriorities( download_manager, fileSetSkeleton);
-
-            loadFileDownloaded( download_manager, res );
-
-            return( fileSetSkeleton );
-
-        }catch( Throwable e ){
-
-            Debug.printStackTrace(e);
-
-            return( new DiskManagerFileInfoSetImpl(new DiskManagerFileInfoImpl[0],null) );
-
-        }
+        return( getStorageTypes( download_manager )[fileIndex]);
     }
-
+    
     public static void
     setFileLinks(
         DownloadManager         download_manager,
diff --git a/org/gudy/azureus2/core3/disk/impl/DiskManagerUtil.java b/org/gudy/azureus2/core3/disk/impl/DiskManagerUtil.java
index 39fcffe..25f020d 100644
--- a/org/gudy/azureus2/core3/disk/impl/DiskManagerUtil.java
+++ b/org/gudy/azureus2/core3/disk/impl/DiskManagerUtil.java
@@ -24,17 +24,35 @@
 package org.gudy.azureus2.core3.disk.impl;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
-import org.gudy.azureus2.core3.disk.DiskManager;
-import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.core3.disk.DiskManagerFileInfoSet;
+import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.disk.impl.resume.RDResumeHandler;
 import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerException;
+import org.gudy.azureus2.core3.download.DownloadManagerState;
+import org.gudy.azureus2.core3.internat.LocaleTorrentUtil;
+import org.gudy.azureus2.core3.internat.LocaleUtilDecoder;
+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.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFile;
+import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.core.diskmanager.cache.CacheFile;
+import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerFactory;
+import com.aelitis.azureus.core.diskmanager.cache.CacheFileOwner;
+import com.aelitis.azureus.core.diskmanager.file.FMFileManagerFactory;
 
 public class 
 DiskManagerUtil 
@@ -113,6 +131,7 @@ DiskManagerUtil
 	checkBlockConsistencyForRead(
 		DiskManager	dm,
 		String		originator,
+		boolean		peer_request,
 		int 		pieceNumber,
 		int 		offset,
 		int 		length)
@@ -122,7 +141,7 @@ DiskManagerUtil
 			return( false );
 		}
 		
-		if (length > max_read_block_size) {
+		if (length > max_read_block_size && peer_request) {
 			if (Logger.isEnabled())
 				Logger.log(new LogEvent(dm, LOGID, LogEvent.LT_ERROR,
 						"Read invalid: " + originator + " length=" + length + " > " + max_read_block_size));
@@ -172,11 +191,13 @@ DiskManagerUtil
 				File currentFile = files[i].getFile(true);
 				if(!RDResumeHandler.fileMustExist(dm, files[i]))
 				{
-					if(types[i].equals("C"))
+					int	st = convertDMStorageTypeFromString( types[i] );
+					if( st == DiskManagerFileInfo.ST_COMPACT || st == DiskManagerFileInfo.ST_REORDER_COMPACT ){
 						currentFile.delete();
-				} else if(allowAlloction && types[i].equals("L") && !currentFile.exists())	{
+					}
+				} else if(allowAlloction && !currentFile.exists())	{
 					/*
-					 * file must exist, does not exist and we just changed to linear
+					 * file must exist, does not exist and we probably just changed to linear
 					 * mode, assume that (re)allocation of adjacent files is necessary
 					 */
 					dm.setDataAlreadyAllocated(false);
@@ -188,5 +209,993 @@ DiskManagerUtil
 		}
 	}
 
+	private static AEMonitor    cache_read_mon  = new AEMonitor( "DiskManager:cacheRead" );
+
+	private static boolean
+	setFileLink(
+	    DownloadManager         download_manager,
+	    DiskManagerFileInfo[]   info,
+	    DiskManagerFileInfo     file_info,
+	    File                    from_file,
+	    File                    to_link )
+	{
+	        // existing link is that for the TO_LINK and will come back as TO_LINK if no link is defined
+	
+	    File    existing_link = FMFileManagerFactory.getSingleton().getFileLink( download_manager.getTorrent(), to_link );
+	
+	    if ( !existing_link.equals( to_link )){
+	
+	            // where we're mapping to is already linked somewhere else. Only case we support
+	            // is where this is a remapping of the same file back to where it came from
+	
+	        if ( !from_file.equals( to_link )){
+	
+	            Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
+	                            "Attempt to link to existing link '" + existing_link.toString()
+	                                    + "'"));
+	
+	            return( false );
+	        }
+	    }
+	
+	    File    existing_file = file_info.getFile( true );
+	
+	    if ( to_link.equals( existing_file )){
+	
+	            // already pointing to the right place
+	
+	        return( true );
+	    }
+	
+	    for (int i=0;i<info.length;i++){
+	
+	        if ( to_link.equals( info[i].getFile( true ))){
+	
+	            Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
+	                            "Attempt to link to existing file '" + info[i].getFile(true)
+	                                    + "'"));
+	
+	            return( false );
+	        }
+	    }
+	
+	    if ( to_link.exists()){
+	
+	        if ( !existing_file.exists()){
+	
+	                // using a new file, make sure we recheck
+	
+	            download_manager.recheckFile( file_info );
+	
+	        }else{
+	
+                if ( FileUtil.deleteWithRecycle( 
+            		existing_file,
+            		download_manager.getDownloadState().getFlag( DownloadManagerState.FLAG_LOW_NOISE ))){
+	
+	                    // new file, recheck
+	
+	                download_manager.recheckFile( file_info );
+	
+	            }else{
+	
+	                Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
+	                        "Failed to delete '" + existing_file.toString() + "'"));
+	
+	                return( false );
+	            }
+	        }
+	    }else{
+	
+	        if ( existing_file.exists()){
+	
+	            if ( !FileUtil.renameFile( existing_file, to_link )){
+	
+	                Logger.log(new LogAlert(download_manager, LogAlert.REPEATABLE, LogAlert.AT_ERROR,
+	                    "Failed to rename '" + existing_file.toString() + "'" ));
+	
+	                return( false );
+	            }
+	        }
+	    }
+	
+	    DownloadManagerState    state = download_manager.getDownloadState();
+	
+	    state.setFileLink( from_file, to_link );
+	
+	    state.save();
+	
+	    return( true );
+	}
+
+	static abstract class FileSkeleton implements DiskManagerFileInfoHelper {
+	    protected int     priority;
+	    protected boolean skipped;
+		protected long    downloaded;
+	}
+
+	public static DiskManagerFileInfoSet
+	getFileInfoSkeleton(
+	    final DownloadManager       download_manager,
+	    final DiskManagerListener   listener )
+	{
+	    TOTorrent   torrent = download_manager.getTorrent();
+	
+	    if ( torrent == null ){
+	
+	        return( new DiskManagerFileInfoSetImpl(new DiskManagerFileInfoImpl[0],null) );
+	    }
+	
+	    String  tempRootDir = download_manager.getAbsoluteSaveLocation().getParent();
+	    
+	    if(tempRootDir == null) // in case we alraedy are at the root
+	    	tempRootDir = download_manager.getAbsoluteSaveLocation().getPath();
+	    
+	
+	    if ( !torrent.isSimpleTorrent()){
+	    	tempRootDir += File.separator + download_manager.getAbsoluteSaveLocation().getName();
+	    }
+	
+	    tempRootDir    += File.separator;
+	    
+	    final String root_dir = StringInterner.intern(tempRootDir) ;
+	
+	    try{
+	        final LocaleUtilDecoder locale_decoder = LocaleTorrentUtil.getTorrentEncoding( torrent );
+	
+	        TOTorrentFile[] torrent_files = torrent.getFiles();
+	
+	        final FileSkeleton[]   res = new FileSkeleton[ torrent_files.length ];
+	        
+			final String incomplete_suffix = download_manager.getDownloadState().getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
+
+	        final DiskManagerFileInfoSet fileSetSkeleton = new DiskManagerFileInfoSet() {
+	
+				public DiskManagerFileInfo[] getFiles() {
+					return res;
+				}
+	
+				public int nbFiles() {
+					return res.length;
+				}
+	
+				public void setPriority(int[] toChange) {
+					if(toChange.length != res.length)
+						throw new IllegalArgumentException("array length mismatches the number of files");
+					
+					for(int i=0;i<res.length;i++)
+						res[i].priority = toChange[i];
+					
+					DiskManagerImpl.storeFilePriorities( download_manager, res);
+					
+					
+					
+					for(int i=0;i<res.length;i++)
+						if(toChange[i] != 0 )
+							listener.filePriorityChanged(res[i]);
+				}
+	
+				public void setSkipped(boolean[] toChange, boolean setSkipped) {
+					if(toChange.length != res.length)
+						throw new IllegalArgumentException("array length mismatches the number of files");
+					
+	        		if (!setSkipped ){
+	    				String[] types = DiskManagerImpl.getStorageTypes(download_manager);
+
+	    				boolean[]	toLinear 	= new boolean[toChange.length];
+	    				boolean[]	toReorder 	= new boolean[toChange.length];
+	    				
+	    				int	num_linear 	= 0;
+	    				int num_reorder	= 0;
+	    				
+	    				for ( int i=0;i<toChange.length;i++){
+	    					
+	    					if ( toChange[i] ){
+	    						
+	    						int old_type = DiskManagerUtil.convertDMStorageTypeFromString( types[i] );
+	    						
+	    						if ( old_type == DiskManagerFileInfo.ST_COMPACT ){
+	    							
+	    							toLinear[i] = true;
+	    							
+	    							num_linear++;
+	    							
+	    						}else if ( old_type == DiskManagerFileInfo.ST_REORDER_COMPACT ){
+	    							
+	    							toReorder[i] = true;
+	    							
+	    							num_reorder++;
+	    						}
+	    					}	
+	    				}
+	    				
+	    				if ( num_linear > 0 ){
+	    					
+	    					if (!Arrays.equals(toLinear, setStorageTypes(toLinear, DiskManagerFileInfo.ST_LINEAR))){
+	    						
+	    						return;
+	    					}
+	    				}
+	    			
+	    				if ( num_reorder > 0 ){
+	    					
+	    					if (!Arrays.equals(toReorder, setStorageTypes(toReorder, DiskManagerFileInfo.ST_REORDER ))){
+	    						
+	    						return;
+	    					}
+	    				}
+	        		}
+	        		
+					for(int i=0;i<res.length;i++)
+						if(toChange[i])
+							res[i].skipped = setSkipped;
+					
+					if(!setSkipped)
+						doFileExistenceChecks(this, toChange, download_manager, true);
+					
+					DiskManagerImpl.storeFilePriorities( download_manager, res);
+					
+					for(int i=0;i<res.length;i++)
+						if(toChange[i])
+							listener.filePriorityChanged(res[i]);
+				}
+	
+				public boolean[] setStorageTypes(boolean[] toChange, int newStorageType) {
+					if(toChange.length != res.length)
+						throw new IllegalArgumentException("array length mismatches the number of files");
+					
+					String[] types = DiskManagerImpl.getStorageTypes(download_manager);
+					boolean[] modified = new boolean[res.length];
+					boolean[] toSkip = new boolean[res.length];
+					int toSkipCount = 0;
+					DownloadManagerState dmState = download_manager.getDownloadState();
+					
+					try {
+						dmState.suppressStateSave(true);
+	
+						for(int i=0;i<res.length;i++)
+						{
+							if(!toChange[i])
+								continue;
+	
+	
+							final int idx = i;
+	
+							int old_type = DiskManagerUtil.convertDMStorageTypeFromString( types[i] );
+	
+							//System.out.println(old_type + " <> " + newStroageType);
+	
+							if ( newStorageType == old_type )
+							{
+								modified[i] = true;
+								continue;
+							}
+	
+							try{
+								File    target_file = res[i].getFile( true );
+	
+								// if the file doesn't exist then this is the start-of-day, most likely
+								// being called from the torrent-opener, so we don't need to do any
+								// file fiddling (in fact, if we do, we end up leaving zero length
+								// files for dnd files which then force a recheck when the download
+								// starts for the first time)
+	
+								if ( target_file.exists()){
+	
+									CacheFile cache_file =
+										CacheFileManagerFactory.getSingleton().createFile(
+											new CacheFileOwner()
+											{
+												public String
+												getCacheFileOwnerName()
+												{
+													return( download_manager.getInternalName());
+												}
+	
+												public TOTorrentFile
+												getCacheFileTorrentFile()
+												{
+													return( res[idx].getTorrentFile() );
+												}
+	
+												public File
+												getCacheFileControlFileDir()
+												{
+													return( download_manager.getDownloadState().getStateFile( ));
+												}
+												public int
+												getCacheMode()
+												{
+													return( CacheFileOwner.CACHE_MODE_NORMAL );
+												}
+											},
+											target_file,
+											DiskManagerUtil.convertDMStorageTypeToCache( newStorageType ));
+	
+									cache_file.close();
+	
+									toSkip[i] = ( newStorageType == FileSkeleton.ST_COMPACT || newStorageType == FileSkeleton.ST_REORDER_COMPACT )&& !res[i].isSkipped();
+									if(toSkip[i])
+										toSkipCount++;
+								}
+	
+	
+								modified[i] = true;
+	
+							}catch( Throwable e ){
+	
+								Debug.printStackTrace(e);
+	
+								Logger.log(
+									new LogAlert(download_manager,
+										LogAlert.REPEATABLE,
+										LogAlert.AT_ERROR,
+										"Failed to change storage type for '" + res[i].getFile(true) +"': " + Debug.getNestedExceptionMessage(e)));
+	
+								// download's not running - tag for recheck
+	
+								RDResumeHandler.recheckFile( download_manager, res[i] );
+	
+							}
+	
+							types[i] = DiskManagerUtil.convertDMStorageTypeToString( newStorageType );
+						}
+						
+						/*
+						 * set storage type and skipped before we do piece clearing and file
+						 * clearing checks as those checks work better when skipped/stype is set
+						 * properly
+						 */
+						dmState.setListAttribute( DownloadManagerState.AT_FILE_STORE_TYPES, types);
+						if(toSkipCount > 0)
+							setSkipped(toSkip, true);
+						
+						
+						for(int i=0;i<res.length;i++)
+						{
+							if(!toChange[i])
+								continue;
+							
+							// download's not running, update resume data as necessary
+	
+							int cleared = RDResumeHandler.storageTypeChanged( download_manager, res[i] );
+	
+							// try and maintain reasonable figures for downloaded. Note that because
+							// we don't screw with the first and last pieces of the file during
+							// storage type changes we don't have the problem of dealing with
+							// the last piece being smaller than torrent piece size
+	
+							if (cleared > 0)
+							{
+								res[i].downloaded = res[i].downloaded - cleared * res[i].getTorrentFile().getTorrent().getPieceLength();
+								if (res[i].downloaded < 0) res[i].downloaded = 0;
+							}
+						}
+	
+						DiskManagerImpl.storeFileDownloaded( download_manager, res, true );
+	
+						doFileExistenceChecks(this, toChange, download_manager, newStorageType == FileSkeleton.ST_LINEAR || newStorageType == FileSkeleton.ST_REORDER );
+	
+					} finally {
+						dmState.suppressStateSave(false);
+						dmState.save();
+					}
+					
+					return modified;
+				}
+	        };
+	
+	        for (int i=0;i<res.length;i++){
+	
+	            final TOTorrentFile torrent_file    = torrent_files[i];
+	
+	            final int file_index = i;
+	
+	            FileSkeleton info = new FileSkeleton() {
+	
+	            	private CacheFile   read_cache_file;
+	            	// do not access this field directly, use lazyGetFile() instead 
+	            	private WeakReference dataFile = new WeakReference(null);
+	
+	            	public void
+	            	setPriority(int b)
+	            	{
+	            		priority    = b;
+	
+	            		DiskManagerImpl.storeFilePriorities( download_manager, res );
+	
+	            		listener.filePriorityChanged( this );
+	            	}
+	
+	            	public void
+	            	setSkipped(boolean _skipped)
+	            	{
+	            		if ( !_skipped && getStorageType() == ST_COMPACT ){
+	            			if ( !setStorageType( ST_LINEAR )){
+	            				return;
+	            			}
+	            		}
+	
+	            		if ( !_skipped && getStorageType() == ST_REORDER_COMPACT ){
+	            			if ( !setStorageType( ST_REORDER )){
+	            				return;
+	            			}
+	            		}
+
+	            		skipped = _skipped;
+	
+	            		DiskManagerImpl.storeFilePriorities( download_manager, res );
+	            		
+	            		if(!_skipped)
+	            		{
+	            			boolean[] toCheck = new boolean[fileSetSkeleton.nbFiles()];
+	            			toCheck[file_index] = true;
+	            			doFileExistenceChecks(fileSetSkeleton, toCheck, download_manager, true);                			
+	            		}
+	            		
+	
+	            		listener.filePriorityChanged( this );
+	            	}
+	
+	            	public int
+	            	getAccessMode()
+	            	{
+	            		return( READ );
+	            	}
+	
+	            	public long
+	            	getDownloaded()
+	            	{
+	            		return( downloaded );
+	            	}
+	
+	            	public void
+	            	setDownloaded(
+	            		long    l )
+	            	{
+	            		downloaded  = l;
+	            	}
+	
+	            	public String
+	            	getExtension()
+	            	{
+	            		String    ext   = lazyGetFile().getName();
+	            		
+	                    if ( incomplete_suffix != null && ext.endsWith( incomplete_suffix )){
+	                    	
+	                    	ext = ext.substring( 0, ext.length() - incomplete_suffix.length());
+	                    }
+
+	            		int separator = ext.lastIndexOf(".");
+	            		if (separator == -1)
+	            			separator = 0;
+	            		return ext.substring(separator);
+	            	}
+	
+	            	public int
+	            	getFirstPieceNumber()
+	            	{
+	            		return( torrent_file.getFirstPieceNumber());
+	            	}
+	
+	            	public int
+	            	getLastPieceNumber()
+	            	{
+	            		return( torrent_file.getLastPieceNumber());
+	            	}
+	
+	            	public long
+	            	getLength()
+	            	{
+	            		return( torrent_file.getLength());
+	            	}
+	
+	            	public int
+	            	getIndex()
+	            	{
+	            		return( file_index );
+	            	}
+	
+	            	public int
+	            	getNbPieces()
+	            	{
+	            		return( torrent_file.getNumberOfPieces());
+	            	}
+	
+	            	public int
+	            	getPriority()
+	            	{
+	            		return( priority );
+	            	}
+	
+	            	public boolean
+	            	isSkipped()
+	            	{
+	            		return( skipped );
+	            	}
+	
+	            	public DiskManager
+	            	getDiskManager()
+	            	{
+	            		return( null );
+	            	}
+	
+	            	public DownloadManager
+	            	getDownloadManager()
+	            	{
+	            		return( download_manager );
+	            	}
+	
+	            	public File
+	            	getFile(
+	            		boolean follow_link )
+	            	{
+	            		if ( follow_link ){
+	
+	            			File link = getLink();
+	
+	            			if ( link != null ){
+	
+	            				return( link );
+	            			}
+	            		}
+	            		return lazyGetFile();
+	            	}
+	
+	            	private File lazyGetFile()
+	            	{
+	            		File toReturn = (File)dataFile.get();
+	            		if(toReturn != null)
+	            			return toReturn;
+	
+	            		TOTorrent tor = download_manager.getTorrent();
+	
+	            		String  path_str = root_dir;
+	            		File simpleFile = null;
+	
+	            		// for a simple torrent the target file can be changed
+	
+	            		if ( tor.isSimpleTorrent()){
+	
+	            			simpleFile = download_manager.getAbsoluteSaveLocation();
+	
+	            		}else{
+	            			byte[][]path_comps = torrent_file.getPathComponents();
+	
+	            			for (int j=0;j<path_comps.length;j++){
+	
+	            				String comp;
+	            				try
+	            				{
+	            					comp = locale_decoder.decodeString( path_comps[j] );
+	            				} catch (UnsupportedEncodingException e)
+	            				{
+	            					Debug.printStackTrace(e);
+	            					comp = "undecodableFileName"+file_index;
+	            				}
+	
+	            				comp = FileUtil.convertOSSpecificChars( comp,  j != path_comps.length-1 );
+	
+	            				path_str += (j==0?"":File.separator) + comp;
+	            			}
+	            		}
+	
+	            		dataFile = new WeakReference(toReturn = simpleFile != null ? simpleFile : new File( path_str ));
+	
+	            		//System.out.println("new file:"+toReturn);
+	            		return toReturn;
+	            	}
+	
+	            	public TOTorrentFile
+	            	getTorrentFile()
+	            	{
+	            		return( torrent_file );
+	            	}
+	            	
+                	public boolean
+                	setLink(
+                		File    link_destination )
+                	{
+                		/**
+                		 * If we a simple torrent, then we'll redirect the call to the download and move the
+                		 * data files that way - that'll keep everything in sync.
+                		 */  
+                		if (download_manager.getTorrent().isSimpleTorrent()) {
+                			try {
+                				download_manager.moveDataFiles(link_destination.getParentFile(), link_destination.getName());
+                				return true;
+                			}
+                			catch (DownloadManagerException e) {
+                				// What should we do with the error?
+                				return false;
+                			}
+                		}
+                		return setLinkAtomic(link_destination);
+                	}
+
+                	public boolean
+                	setLinkAtomic(
+                		File    link_destination )
+                	{
+                		return( setFileLink( download_manager, res, this, lazyGetFile(), link_destination ));
+                	}
+
+                	public File
+                	getLink()
+                	{
+                		return( download_manager.getDownloadState().getFileLink( lazyGetFile() ));
+                	}
+
+                	public boolean setStorageType(int type) {
+                		boolean[] change = new boolean[res.length];
+                		change[file_index] = true;
+                		return fileSetSkeleton.setStorageTypes(change, type)[file_index];
+                	}
+
+                	public int
+                	getStorageType()
+                	{
+                		return( DiskManagerUtil.convertDMStorageTypeFromString( DiskManagerImpl.getStorageType(download_manager, file_index)));
+                	}
+
+                	public void
+                	flushCache()
+                	{
+                	}
+
+                	public DirectByteBuffer
+                	read(
+                		long    offset,
+                		int     length )
+
+                		throws IOException
+                	{
+                		CacheFile temp;;
+                		
+                		try{
+                			cache_read_mon.enter();
+
+                			if ( read_cache_file == null ){
+
+                				try{
+                					int type = convertDMStorageTypeFromString( DiskManagerImpl.getStorageType(download_manager, file_index));
+
+                					read_cache_file =
+                						CacheFileManagerFactory.getSingleton().createFile(
+                							new CacheFileOwner()
+                							{
+                								public String
+                								getCacheFileOwnerName()
+                								{
+                									return( download_manager.getInternalName());
+                								}
+
+                								public TOTorrentFile
+                								getCacheFileTorrentFile()
+                								{
+                									return( torrent_file );
+                								}
+
+                								public File
+                								getCacheFileControlFileDir()
+                								{
+                									return( download_manager.getDownloadState().getStateFile( ));
+                								}
+                								public int
+                								getCacheMode()
+                								{
+                									return( CacheFileOwner.CACHE_MODE_NORMAL );
+                								}
+                							},
+                							getFile( true ),
+                							convertDMStorageTypeToCache( type ));
+
+                				}catch( Throwable e ){
+
+                					Debug.printStackTrace(e);
+
+                					throw( new IOException( e.getMessage()));
+                				}
+                			}
+                			
+                			temp = read_cache_file;
+                			
+                		}finally{
+
+                			cache_read_mon.exit();
+                		}
+
+                		DirectByteBuffer    buffer =
+                			DirectByteBufferPool.getBuffer( DirectByteBuffer.AL_DM_READ, length );
+
+                		try{
+                			temp.read( buffer, offset, CacheFile.CP_READ_CACHE );
+
+                		}catch( Throwable e ){
+
+                			buffer.returnToPool();
+
+                			Debug.printStackTrace(e);
+
+                			throw( new IOException( e.getMessage()));
+                		}
+
+                		return( buffer );
+                	}
+
+                	public void
+                	close()
+                	{
+                		CacheFile temp;
+                	
+                   		try{
+                			cache_read_mon.enter();
+
+                			temp = read_cache_file;
+                			
+                			read_cache_file = null;
+                			
+                   		}finally{
+                   			
+                   			cache_read_mon.exit();
+                   		}
+                   		
+                		if ( temp != null ){
+
+                			try{
+                				temp.close();
+
+                			}catch( Throwable e ){
+
+                				Debug.printStackTrace(e);
+                			}
+                		}
+                	}
+	
+	            	public void
+	            	addListener(
+	            		DiskManagerFileInfoListener listener )
+	            	{
+	            		if ( getDownloaded() == getLength()){
+	
+	            			try{
+	            				listener.dataWritten( 0, getLength());
+	
+	            				listener.dataChecked( 0, getLength());
+	
+	            			}catch( Throwable e ){
+	
+	            				Debug.printStackTrace(e);
+	            			}
+	            		}
+	            	}
+	
+	            	public void
+	            	removeListener(
+	            		DiskManagerFileInfoListener listener )
+	            	{
+	            	}
+	            };
+	
+	            res[i]  = info;
+	        }
+	
+	        loadFilePriorities( download_manager, fileSetSkeleton);
+	
+	        loadFileDownloaded( download_manager, res );
+	
+	        return( fileSetSkeleton );
+	
+	    }catch( Throwable e ){
+	
+	        Debug.printStackTrace(e);
+	
+	        return( new DiskManagerFileInfoSetImpl(new DiskManagerFileInfoImpl[0],null) );
+	
+	    }
+	}
+
+	public static int
+	convertDMStorageTypeFromString(
+		String		str )
+	{
+		char c = str.charAt(0);
+		
+		switch( c ){
+			case 'L':{
+				return( DiskManagerFileInfo.ST_LINEAR );
+			}
+			case 'C':{
+				return( DiskManagerFileInfo.ST_COMPACT );
+			}
+			case 'R':{
+				return( DiskManagerFileInfo.ST_REORDER );
+			}
+			case 'X':{
+				return( DiskManagerFileInfo.ST_REORDER_COMPACT );
+			}
+		}
+		
+		Debug.out( "eh?" );
+		
+		return( DiskManagerFileInfo.ST_LINEAR );
+	}
+	
+	public static String
+	convertDMStorageTypeToString(
+		int		dm_type )
+	{
+		switch( dm_type ){
+			case DiskManagerFileInfo.ST_LINEAR:{
+				return( "L" );
+			}
+			case DiskManagerFileInfo.ST_COMPACT:{
+				return( "C" );
+			}
+			case DiskManagerFileInfo.ST_REORDER:{
+				return( "R" );
+			}
+			case DiskManagerFileInfo.ST_REORDER_COMPACT:{
+				return( "X" );
+			}
+		}
+		
+		Debug.out( "eh?" );
+		
+		return( "?" );
+	}
+	
+	public static String
+	convertCacheStorageTypeToString(
+		int		cache_type )
+	{
+		switch( cache_type ){
+			case CacheFile.CT_LINEAR:{
+				return( "L" );
+			}
+			case CacheFile.CT_COMPACT:{
+				return( "C" );
+			}
+			case CacheFile.CT_PIECE_REORDER:{
+				return( "R" );
+			}
+			case CacheFile.CT_PIECE_REORDER_COMPACT:{
+				return( "X" );
+			}
+		}
+		
+		Debug.out( "eh?" );
+		
+		return( "?" );
+	}
+	public static int
+	convertDMStorageTypeToCache(
+		int	dm_type )
+	{
+		switch( dm_type ){
+			case DiskManagerFileInfo.ST_LINEAR:{
+				return( CacheFile.CT_LINEAR );
+			}
+			case DiskManagerFileInfo.ST_COMPACT:{
+				return( CacheFile.CT_COMPACT );
+			}
+			case DiskManagerFileInfo.ST_REORDER:{
+				return( CacheFile.CT_PIECE_REORDER );
+			}
+			case DiskManagerFileInfo.ST_REORDER_COMPACT:{
+				return( CacheFile.CT_PIECE_REORDER_COMPACT );
+			}
+		}
+		
+		Debug.out( "eh?" );
+		
+		return( CacheFile.CT_LINEAR );
+	}
+	
+	protected static void
+	storeFilePriorities(
+		DownloadManager         download_manager,
+		DiskManagerFileInfo[]   files )
+	{
+		if ( files == null ) return;
+		// bit confusing this: priorities are stored as
+		// >= 1   : priority, 1 = high, 2 = higher etc
+		// 0      : skipped
+		// -1     : normal priority
+		// <= -2  : negative priority , so -2 -> priority -1, -3 -> priority -2 etc
+
+		List file_priorities = new ArrayList(files.length);
+		for (int i=0; i < files.length; i++) {
+			DiskManagerFileInfo file = files[i];
+			if (file == null) return;
+			boolean skipped = file.isSkipped();
+			int priority = file.getPriority();
+			int value;
+			if ( skipped ){
+				value = 0;
+			}else if ( priority > 0 ){
+				value = priority;
+			}else{
+				value = priority - 1;
+				if ( value > 0 ){
+					value = Integer.MIN_VALUE;
+				}
+			}
+			file_priorities.add( i, Long.valueOf(value));
+		}
+		
+	   download_manager.setData( "file_priorities", file_priorities );
+	}
+	  
+	static void
+	loadFilePriorities(
+		DownloadManager         download_manager,
+		DiskManagerFileInfoSet   fileSet )
+	{
+		//  TODO: remove this try/catch.  should only be needed for those upgrading from previous snapshot
+		try {
+			DiskManagerFileInfo[] files = fileSet.getFiles();
+
+			if ( files == null ) return;
+			List file_priorities = (List)download_manager.getData( "file_priorities" );
+			if ( file_priorities == null ) return;
+
+			boolean[] toSkip = new boolean[files.length];
+			int[] prio = new int[files.length];
+
+			for (int i=0; i < files.length; i++) {
+				DiskManagerFileInfo file = files[i];
+				if (file == null) return;
+				int priority = ((Long)file_priorities.get( i )).intValue();
+				if ( priority == 0 ){
+					toSkip[i] = true;
+				}else{
+					if ( priority < 0 ){
+						priority++;
+					}
+					prio[i] = priority;
+				}
+			}
+
+			fileSet.setPriority(prio);
+			fileSet.setSkipped(toSkip, true);
+
+		}
+		catch (Throwable t) {Debug.printStackTrace( t );}
+	}
+
+	protected static void
+	  loadFileDownloaded(
+	    DownloadManager             download_manager,
+	    DiskManagerFileInfoHelper[] files )
+	  {
+	      DownloadManagerState  state = download_manager.getDownloadState();
+	
+	      Map   details = state.getMapAttribute( DownloadManagerState.AT_FILE_DOWNLOADED );
+	
+	      if ( details == null ){
+	
+	          return;
+	      }
+	
+	      List  downloaded = (List)details.get( "downloaded" );
+	
+	      if ( downloaded == null ){
+	
+	          return;
+	      }
+	
+	      try{
+	          for (int i=0;i<files.length;i++){
+	
+	              files[i].setDownloaded(((Long)downloaded.get(i)).longValue());
+	          }
+	     }catch( Throwable e ){
+	
+	         Debug.printStackTrace(e);
+	     }
+	
+	  }
+
 
 }
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 9cad18d..b86fc80 100644
--- a/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/access/impl/DMCheckerImpl.java
@@ -337,8 +337,10 @@ DMCheckerImpl
 			  						break;
 			  					}
 			  					
+			  					final DiskManagerCheckRequest this_request = createCheckRequest( i, request.getUserData());
+			  					
 			  					enqueueCheckRequest( 
-			  						createCheckRequest( i, request.getUserData()),
+			  						this_request,
 			  	       				new DiskManagerCheckRequestListener()
 									{
 					  	       			public void 
@@ -642,9 +644,14 @@ DMCheckerImpl
 						return;
 					}
 					
-					if ( all_compact && ( cache_file.getStorageType() != CacheFile.CT_COMPACT || file_info.getNbPieces() <= 2 )){
+					if ( all_compact ){
+						
+						int st = cache_file.getStorageType();
 						
-						all_compact = false;
+						if (( st != CacheFile.CT_COMPACT && st != CacheFile.CT_PIECE_REORDER_COMPACT ) || file_info.getNbPieces() <= 2 ){
+										
+							all_compact = false;
+						}
 					}
 				}
 				
@@ -722,111 +729,143 @@ DMCheckerImpl
 					   		this_mon.exit();
 					   	}
 						
-						try{
-					    	final	DirectByteBuffer	f_buffer	= buffer;
-					    	
-						   	ConcurrentHasher.getSingleton().addRequest(
-					    			buffer.getBuffer(DirectByteBuffer.SS_DW),
-									new ConcurrentHasherRequestListener()
-									{
-					    				public void
-										complete(
-											ConcurrentHasherRequest	hash_request )
-					    				{
-					    					int	async_result	= 3; // cancelled
-					    						    		    					
-					    					try{
-					    						
-												byte[] testHash = hash_request.getResult();
-														    								
-												if ( testHash != null ){
+					   	if ( buffer.getFlag( DirectByteBuffer.FL_CONTAINS_TRANSIENT_DATA )){
+					   		
+					   		try{
+					   			buffer.returnToPool();
+					   			
+					   			listener.checkCompleted( request, false );
+					   			
+					   		}finally{
+					   			
+					   			try{
+    								this_mon.enter();
+    							
+    								async_checks--;
+    								
+    								if ( stopped ){
+    									  
+    									async_check_sem.release();
+    								}
+    							}finally{
+    								
+    								this_mon.exit();
+    							}
+					   		}
+					   	}else{
+							try{
+						    	final	DirectByteBuffer	f_buffer	= buffer;
+						    	
+							   	ConcurrentHasher.getSingleton().addRequest(
+						    			buffer.getBuffer(DirectByteBuffer.SS_DW),
+										new ConcurrentHasherRequestListener()
+										{
+						    				public void
+											complete(
+												ConcurrentHasherRequest	hash_request )
+						    				{
+						    					int	async_result	= 3; // cancelled
+						    						    		    					
+						    					try{
+						    						
+													byte[] actual_hash = hash_request.getResult();
+															    								
+													if ( actual_hash != null ){
 															
-				    								async_result = 1; // success
-				    								
-				    								for (int i = 0; i < testHash.length; i++){
-				    									
-				    									if ( testHash[i] != required_hash[i]){
-				    										
-				    										async_result = 2; // failed;
-				    										
-				    										break;
-				    									}
-				    								}
-												}
-					    					}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();
+														request.setHash( actual_hash );
+														
+					    								async_result = 1; // success
+					    								
+					    								for (int i = 0; i < actual_hash.length; i++){
+					    									
+					    									if ( actual_hash[i] != required_hash[i]){
 					    										
-					    										CacheFile	cache_file = file_info.getCacheFile();
+					    										async_result = 2; // failed;
 					    										
-					    										cache_file.setPieceComplete( pieceNumber, f_buffer );
+					    										break;
 					    									}
-					    								}catch( Throwable e ){
-					    									
-					    									f_buffer.returnToPool();
-					    									
-					    									Debug.out( e );
-					    									
-					    									listener.checkFailed( request, e );
-					    									
-					    									return;
 					    								}
-					    							}
-					    							
-						    						f_buffer.returnToPool();
-	
-						    						if ( async_result == 1 ){
-						    							
-						    							listener.checkCompleted( request, true );
+													}
+						    					}finally{
+						    						
+						    						try{
+						    							if ( async_result == 1 ){
 						    							
-						    						}else if ( async_result == 2 ){
+						    								try{
+						    									for (int i = 0; i < pieceList.size(); i++) {
+						    										
+						    										DMPieceMapEntry piece_entry = pieceList.get(i);
+						    											
+						    										DiskManagerFileInfoImpl	file_info = piece_entry.getFile();
+						    										
+						    											// edge case here for skipped zero length files that have been deleted
+						    										
+						    										if ( file_info.getLength() > 0 || !file_info.isSkipped()){
+	
+						    											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;
+						    								}
+						    							}
 						    							
-						    							listener.checkCompleted( request, false );
+							    						f_buffer.returnToPool();
+		
+							    						if ( async_result == 1 ){
+							    							
+							    							listener.checkCompleted( request, true );
+							    							
+							    						}else if ( async_result == 2 ){
+							    							
+							    							listener.checkCompleted( request, false );
+							    							
+							    						}else{
+							    							
+							    							listener.checkCancelled( request );
+							    						}
+							    						
+						    						}finally{
 						    							
-						    						}else{
+						    							try{
+						    								this_mon.enter();
 						    							
-						    							listener.checkCancelled( request );
+						    								async_checks--;
+						    								
+						    								if ( stopped ){
+						    									  
+						    									async_check_sem.release();
+						    								}
+						    							}finally{
+						    								
+						    								this_mon.exit();
+						    							}
 						    						}
-						    						
-					    						}finally{
-					    							
-					    							try{
-					    								this_mon.enter();
-					    							
-					    								async_checks--;
-					    								
-					    								if ( stopped ){
-					    									  
-					    									async_check_sem.release();
-					    								}
-					    							}finally{
-					    								
-					    								this_mon.exit();
-					    							}
-					    						}
-					    					}
-					    				}
-					    				
-									},
-									request.isLowPriority());
-						
-					    	
-						}catch( Throwable e ){
+						    					}
+						    				}
+						    				
+										},
+										request.isLowPriority());
 							
-							Debug.printStackTrace(e);
-							
-    						buffer.returnToPool();
-    						
-    						listener.checkFailed( request, e );
-						}
+						    	
+							}catch( Throwable e ){
+								
+								Debug.printStackTrace(e);
+								
+	    						buffer.returnToPool();
+	    						
+	    						listener.checkFailed( request, e );
+							}
+					   	}
 					}
 					  
 					public void 
diff --git a/org/gudy/azureus2/core3/disk/impl/access/impl/DiskManagerCheckRequestImpl.java b/org/gudy/azureus2/core3/disk/impl/access/impl/DiskManagerCheckRequestImpl.java
index fbf6998..ec11266 100644
--- a/org/gudy/azureus2/core3/disk/impl/access/impl/DiskManagerCheckRequestImpl.java
+++ b/org/gudy/azureus2/core3/disk/impl/access/impl/DiskManagerCheckRequestImpl.java
@@ -34,6 +34,8 @@ DiskManagerCheckRequestImpl
 	private boolean	low_priority;
 	private boolean	ad_hoc		= true;
 	
+	private byte[]	hash;
+	
 	public 
 	DiskManagerCheckRequestImpl(
 		int		_piece_number,
@@ -86,4 +88,17 @@ DiskManagerCheckRequestImpl
 	{
 		return( ad_hoc );
 	}
+	
+	public void
+	setHash(
+		byte[]		_hash )
+	{
+		hash	= _hash;
+	}
+	
+	public byte[]
+	getHash()
+	{
+		return( hash );
+	}
 }
diff --git a/org/gudy/azureus2/core3/disk/impl/resume/RDResumeHandler.java b/org/gudy/azureus2/core3/disk/impl/resume/RDResumeHandler.java
index 0d39536..d4cd86d 100644
--- a/org/gudy/azureus2/core3/disk/impl/resume/RDResumeHandler.java
+++ b/org/gudy/azureus2/core3/disk/impl/resume/RDResumeHandler.java
@@ -30,6 +30,10 @@ import org.gudy.azureus2.core3.disk.DiskManagerCheckRequest;
 import org.gudy.azureus2.core3.disk.DiskManagerCheckRequestListener;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.disk.DiskManagerPiece;
+import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
+import org.gudy.azureus2.core3.disk.DiskManagerReadRequestListener;
+import org.gudy.azureus2.core3.disk.DiskManagerWriteRequest;
+import org.gudy.azureus2.core3.disk.DiskManagerWriteRequestListener;
 import org.gudy.azureus2.core3.disk.impl.DiskManagerFileInfoImpl;
 import org.gudy.azureus2.core3.disk.impl.DiskManagerImpl;
 import org.gudy.azureus2.core3.disk.impl.DiskManagerRecheckInstance;
@@ -43,7 +47,9 @@ 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.util.AESemaphore;
+import org.gudy.azureus2.core3.util.ByteArrayHashMap;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
 
 import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerException;
 
@@ -56,6 +62,14 @@ RDResumeHandler
 {
 	private static final LogIDs LOGID = LogIDs.DISK;
 
+	private static final boolean TEST_RECHECK_FAILURE_HANDLING	= false;
+	
+	static{
+		if ( TEST_RECHECK_FAILURE_HANDLING ){
+			Debug.out( "**** test recheck failure enabled ****" );
+		}
+	}
+	
 	private static final byte		PIECE_NOT_DONE			= 0;
 	private static final byte		PIECE_DONE				= 1;
 	private static final byte		PIECE_RECHECK_REQUIRED	= 2;
@@ -139,6 +153,8 @@ RDResumeHandler
 
         final AESemaphore	 run_sem = new AESemaphore( "RDResumeHandler::checkAllPieces:runsem", 2 );
 
+        final List<DiskManagerCheckRequest>	failed_pieces = new ArrayList<DiskManagerCheckRequest>();
+        
 		try{
 			boolean	resume_data_complete = false;
 			
@@ -401,6 +417,21 @@ RDResumeHandler
 													DiskManagerCheckRequest 	request,
 													boolean						passed )
 												{
+													if ( TEST_RECHECK_FAILURE_HANDLING && (int)(Math.random()*10) == 0 ){
+														
+														disk_manager.getPiece(request.getPieceNumber()).setDone(false);
+														
+														passed  = false;
+													}
+													
+													if ( !passed ){
+														
+														synchronized( failed_pieces ){
+														
+															failed_pieces.add( request );
+														}
+													}
+													
 													complete();
 												}
 												 
@@ -538,6 +569,21 @@ RDResumeHandler
 											DiskManagerCheckRequest 	request,
 											boolean						passed )
 										{
+											if ( TEST_RECHECK_FAILURE_HANDLING && (int)(Math.random()*10) == 0 ){
+												
+												disk_manager.getPiece(request.getPieceNumber()).setDone(false);
+												
+												passed  = false;
+											}
+											
+											if ( !passed ){
+												
+												synchronized( failed_pieces ){
+													
+													failed_pieces.add( request );
+												}
+											}
+											
 											complete();
 										}
 										 
@@ -580,6 +626,146 @@ RDResumeHandler
 						pending_check_num--;
 					}
 				}
+				
+				if ( failed_pieces.size() > 0 && !TEST_RECHECK_FAILURE_HANDLING ){
+					
+					byte[][] piece_hashes = disk_manager.getTorrent().getPieces();
+					
+					ByteArrayHashMap<Integer>	hash_map = new ByteArrayHashMap<Integer>();
+					
+					for ( int i=0;i<piece_hashes.length;i++){
+						
+						hash_map.put( piece_hashes[i], i );
+					}
+										
+					for ( DiskManagerCheckRequest request: failed_pieces ){
+						
+						while( ! stopped ){
+							
+							if ( recheck_inst.getPermission()){
+								
+								break;
+							}
+						}
+
+						if ( stopped ){
+							
+							break;
+						}
+						
+						byte[] hash = request.getHash();
+						
+						if ( hash != null ){
+							
+							final Integer target_index = hash_map.get( hash );
+							
+							int		current_index 	= request.getPieceNumber();
+							
+							int		piece_size		= disk_manager.getPieceLength( current_index );
+							
+							if ( 	target_index != null && 
+									target_index != current_index &&
+									disk_manager.getPieceLength( target_index ) == piece_size &&
+									!disk_manager.isDone( target_index )){
+																
+								final AESemaphore sem = new AESemaphore( "PieceReorder" );
+								
+								disk_manager.enqueueReadRequest(
+									disk_manager.createReadRequest( current_index, 0, piece_size ),
+									new DiskManagerReadRequestListener()
+									{
+										public void 
+										readCompleted( 
+											DiskManagerReadRequest 	request, 
+											DirectByteBuffer 		data )
+										{
+											try{
+												disk_manager.enqueueWriteRequest(
+													disk_manager.createWriteRequest( target_index, 0, data, null ),
+													new DiskManagerWriteRequestListener()
+													{
+														public void 
+														writeCompleted( 
+															DiskManagerWriteRequest 	request )
+														{
+															try{
+																DiskManagerCheckRequest	check_request = disk_manager.createCheckRequest( target_index, null );
+																
+																check_request.setLowPriority( true );
+										
+																checker.enqueueCheckRequest(
+																		check_request, 
+																		new DiskManagerCheckRequestListener()
+																		{
+																			public void 
+																			checkCompleted( 
+																				DiskManagerCheckRequest 	request,
+																				boolean						passed )
+																			{
+																				sem.release();
+																			}
+																			 
+																			public void
+																			checkCancelled(
+																				DiskManagerCheckRequest		request )
+																			{
+																				sem.release();
+																			}
+																			
+																			public void 
+																			checkFailed( 
+																				DiskManagerCheckRequest 	request, 
+																				Throwable		 			cause )
+																			{
+																				sem.release();
+																			}
+																		});
+															}catch( Throwable e ){
+																
+																sem.release();
+															}
+														}
+														  
+														public void 
+														writeFailed( 
+															DiskManagerWriteRequest 	request, 
+															Throwable		 			cause )
+														{
+															sem.release();
+														}
+													});
+											}catch( Throwable e ){
+												
+												sem.release();
+											}
+										}
+
+										public void 
+										readFailed( 
+											DiskManagerReadRequest 	request, 
+											Throwable		 		cause )
+										{
+											sem.release();
+										}
+
+										public int
+										getPriority()
+										{
+											return( -1 );
+										}
+										
+										public void 
+										requestExecuted(
+											long 	bytes )
+										{
+										}
+									});
+								
+								sem.reserve();
+							}
+						}
+					}
+				}
 			}finally{
 				
 				check_in_progress	= false;
@@ -1009,7 +1195,7 @@ RDResumeHandler
 			DiskManagerFileInfo currentFile = files[i];
 			if(currentFile.getLastPieceNumber() < firstPiece)
 				continue;
-			if (currentFile.getIndex() == file.getIndex() && resumePieces != null && file.getStorageType() != DiskManagerFileInfo.ST_COMPACT)
+			if (currentFile.getIndex() == file.getIndex() && resumePieces != null && file.getStorageType() != DiskManagerFileInfo.ST_COMPACT && file.getStorageType() != DiskManagerFileInfo.ST_REORDER_COMPACT)
 				for (int j = firstPiece; j <= lastPiece && !sharesAnyNeededPieces; j++)
 					sharesAnyNeededPieces |= resumePieces[j] != PIECE_NOT_DONE;
 			if (currentFile.getFirstPieceNumber() > lastPiece)
diff --git a/org/gudy/azureus2/core3/download/DownloadManager.java b/org/gudy/azureus2/core3/download/DownloadManager.java
index 3f917e9..97f50c2 100644
--- a/org/gudy/azureus2/core3/download/DownloadManager.java
+++ b/org/gudy/azureus2/core3/download/DownloadManager.java
@@ -22,6 +22,7 @@
 package org.gudy.azureus2.core3.download;
 
 import java.io.File;
+import java.util.List;
 
 import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
@@ -38,6 +39,7 @@ import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
 import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
 
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
 
 public interface
 DownloadManager
@@ -170,10 +172,15 @@ DownloadManager
     public DiskManager
     getDiskManager();
 
+  	/**
+  	 * @deprecated use getDiskManagerFileInfoSet() instead 
+  	 */
     public DiskManagerFileInfo[]
     getDiskManagerFileInfo();
     
     public DiskManagerFileInfoSet getDiskManagerFileInfoSet();
+    
+    public int getNumFileInfos();
 
     public PEPeerManager
     getPeerManager();
@@ -428,6 +435,8 @@ DownloadManager
     
     public int getMaxUploads();
     
+    public void setUploadPriority( int pri );
+    
 	/**
 	 * Returns the max uploads depending on whether the download is seeding and it has a separate
 	 * rate for this
@@ -564,6 +573,9 @@ DownloadManager
     public PEPeer[]
     getCurrentPeers();
 
+    public List<TrackerPeerSource>
+    getTrackerPeerSources();
+    
     	/**
     	 * Gives the download an opportunity to schedule seeding mode piece rechecks if desired
     	 * @return true if a piece has been rechecked
@@ -577,6 +589,10 @@ DownloadManager
 		LimitedRateGroup	group,
 		boolean				upload );
 	
+	public LimitedRateGroup[]
+	getRateLimiters(
+		boolean				upload );
+	
 	public void
 	removeRateLimiter(
 		LimitedRateGroup	group,
@@ -663,6 +679,13 @@ DownloadManager
     removeActivationListener(
     	DownloadManagerActivationListener listener );
 
+    public void
+    addTPSListener(
+    	DownloadManagerTPSListener		listener );
+    
+    public void
+    removeTPSListener(
+    	DownloadManagerTPSListener		listener );
     
     public void
     generateEvidence(
@@ -705,5 +728,8 @@ DownloadManager
      * @since 3.0.5.3
      */
     public void setTorrentFile(File new_parent_dir, String new_name) throws DownloadManagerException;
-
+    
+    public void
+    fireGlobalManagerEvent(
+    	int		event_type );
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/download/DownloadManagerState.java b/org/gudy/azureus2/core3/download/DownloadManagerState.java
index 990289c..47636ed 100644
--- a/org/gudy/azureus2/core3/download/DownloadManagerState.java
+++ b/org/gudy/azureus2/core3/download/DownloadManagerState.java
@@ -26,6 +26,7 @@ import java.io.File;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.category.Category;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.plugins.download.Download;
@@ -57,19 +58,25 @@ DownloadManagerState
 	public static final String AT_SECRETS				 	= "secrets";
 	public static final String AT_RESUME_STATE		 		= "resumecomplete";
 	public static final String AT_PRIMARY_FILE		 		= "primaryfile";
+	public static final String AT_PRIMARY_FILE_IDX		 	= "primaryfileidx";
 	public static final String AT_TIME_SINCE_DOWNLOAD		= "timesincedl";
 	public static final String AT_TIME_SINCE_UPLOAD			= "timesinceul";
 	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 final String AT_REORDER_MIN_MB			= "reordermb";
+	public static final String AT_MD_INFO_DICT_SIZE			= "mdinfodictsize";
+	public static final String AT_FILE_OTHER_HASHES			= "fileotherhashes";
+	public static final String AT_CANONICAL_SD_DMAP			= "canosavedir";
+
 	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 )},
+		{ AT_REORDER_MIN_MB,						new Integer( -1 )},
 	};
 	
 	public static final long FLAG_ONLY_EVER_SEEDED						= Download.FLAG_ONLY_EVER_SEEDED;
@@ -79,6 +86,9 @@ DownloadManagerState
 	public static final long FLAG_LOW_NOISE								= Download.FLAG_LOW_NOISE;
 	public static final long FLAG_ALLOW_PERMITTED_PEER_SOURCE_CHANGES	= Download.FLAG_ALLOW_PERMITTED_PEER_SOURCE_CHANGES;
 	public static final long FLAG_DO_NOT_DELETE_DATA_ON_REMOVE  		= Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE;
+	public static final long FLAG_FORCE_DIRECT_DELETE			  		= Download.FLAG_FORCE_DIRECT_DELETE;
+	public static final long FLAG_DISABLE_IP_FILTER				  		= Download.FLAG_DISABLE_IP_FILTER;
+	public static final long FLAG_METADATA_DOWNLOAD				  		= Download.FLAG_METADATA_DOWNLOAD;
 	
 	
 	public static final String	PARAM_MAX_PEERS							= "max.peers";
@@ -94,9 +104,11 @@ DownloadManagerState
 	public static final String	PARAM_MAX_UPLOAD_WHEN_BUSY				= "max.upload.when.busy";
 	public static final String  PARAM_DND_FLAGS							= "dndflags";
 	public static final String  PARAM_RANDOM_SEED						= "rand";
+	public static final String	PARAM_UPLOAD_PRIORITY					= "up.pri";
 	
-	public static final int DEFAULT_MAX_UPLOADS	= 4;
-	public static final int MIN_MAX_UPLOADS		= 2;
+	public static final int DEFAULT_MAX_UPLOADS		= 4;
+	public static final int MIN_MAX_UPLOADS			= 2;
+	public static final int DEFAULT_UPLOAD_PRIORITY	= 0;
 	
 	public static Object[][] PARAMETERS = {
 		{ PARAM_MAX_PEERS,							new Integer( 0 ) },
@@ -112,6 +124,7 @@ DownloadManagerState
 		{ PARAM_MAX_UPLOAD_WHEN_BUSY,				new Long( 0 ) },
 		{ PARAM_DND_FLAGS, 							new Long( 0 ) },
 		{ PARAM_RANDOM_SEED, 						new Long( 0 ) },
+		{ PARAM_UPLOAD_PRIORITY, 					new Integer( DEFAULT_UPLOAD_PRIORITY ) },
 	};
 	
 	public TOTorrent
@@ -209,8 +222,8 @@ DownloadManagerState
 	
 	public String getRelativeSavePath();
 
-	public void setPrimaryFile(String fileFullPath);
-	public String getPrimaryFile();
+	public void setPrimaryFile(DiskManagerFileInfo dmfi);
+	public DiskManagerFileInfo getPrimaryFile();
 
 	public String
 	getTrackerClientExtensions();
diff --git a/org/gudy/azureus2/core3/download/DownloadManagerStats.java b/org/gudy/azureus2/core3/download/DownloadManagerStats.java
index 1450aa0..7ccfe9c 100644
--- a/org/gudy/azureus2/core3/download/DownloadManagerStats.java
+++ b/org/gudy/azureus2/core3/download/DownloadManagerStats.java
@@ -89,9 +89,14 @@ DownloadManagerStats
    * @return total bytes uploaded
    */
 	public long	getTotalDataBytesSent();
-  
+  	
 	public long getTotalProtocolBytesSent();
 	
+	/*
+	 * Resets the total bytes sent/received - will stop and start the download if it is running
+	 */
+	public void resetTotalBytesSentReceived( long sent, long received );
+
 	public long getRemaining();
 	
 	public long
diff --git a/org/gudy/azureus2/core3/download/DownloadManagerTPSListener.java b/org/gudy/azureus2/core3/download/DownloadManagerTPSListener.java
new file mode 100644
index 0000000..34de2cf
--- /dev/null
+++ b/org/gudy/azureus2/core3/download/DownloadManagerTPSListener.java
@@ -0,0 +1,29 @@
+/*
+ * Created on Dec 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 org.gudy.azureus2.core3.download;
+
+public interface 
+DownloadManagerTPSListener 
+{
+	public void
+	trackerPeerSourcesChanged();
+}
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
index c47251e..d68191b 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerController.java
@@ -24,10 +24,12 @@ package org.gudy.azureus2.core3.download.impl;
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.ref.WeakReference;
 import java.net.InetSocketAddress;
 import java.util.*;
 
 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.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerDiskListener;
@@ -53,12 +55,14 @@ import org.gudy.azureus2.plugins.network.ConnectionManager;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.networkmanager.NetworkConnection;
+import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.peermanager.PeerManager;
 import com.aelitis.azureus.core.peermanager.PeerManagerRegistration;
 import com.aelitis.azureus.core.peermanager.PeerManagerRegistrationAdapter;
 import com.aelitis.azureus.core.peermanager.peerdb.PeerItemFactory;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
+import com.aelitis.azureus.plugins.extseed.ExternalSeedPeer;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
 
 public class 
@@ -71,10 +75,26 @@ DownloadManagerController
 	
 	private static long skeleton_builds;
 	
+	private static boolean	tracker_stats_exclude_lan;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListener(
+			"Tracker Client Exclude LAN",
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String name) 
+				{
+					tracker_stats_exclude_lan = COConfigurationManager.getBooleanParameter( name );
+				}
+			});
+	}
+	
 	private static ExternalSeedPlugin	ext_seed_plugin;
 	private static boolean				ext_seed_plugin_tried;
 	
-	private static ExternalSeedPlugin
+	protected static ExternalSeedPlugin
 	getExternalSeedPlugin()
 	{
 		if ( !ext_seed_plugin_tried ){
@@ -140,8 +160,9 @@ DownloadManagerController
 	
 	private AEMonitor	disk_listeners_mon	= new AEMonitor( "DownloadManagerController:DL" );
 	
-	protected AEMonitor	this_mon		= new AEMonitor( "DownloadManagerController" );
-	protected AEMonitor	state_mon		= new AEMonitor( "DownloadManagerController:State" );
+	private AEMonitor	control_mon		= new AEMonitor( "DownloadManagerController" );
+	private AEMonitor	state_mon		= new AEMonitor( "DownloadManagerController:State" );
+	private AEMonitor	facade_mon		= new AEMonitor( "DownloadManagerController:Facade" );
 	
 	private DownloadManagerImpl			download_manager;
 	private DownloadManagerStatsImpl	stats;
@@ -170,7 +191,7 @@ DownloadManagerController
 	private PeerManagerRegistration	peer_manager_registration;
 	private PEPeerManager 			peer_manager;
 	
-	private List	external_rate_limiters_cow;
+	private List<Object[]>	external_rate_limiters_cow;
 	
 	private String errorDetail;
 
@@ -191,6 +212,26 @@ DownloadManagerController
 	
 	private long		priority_connection_count;
 	
+	private static final int				HTTP_SEEDS_MAX	= 64;
+	private LinkedList<ExternalSeedPeer>	http_seeds = new LinkedList<ExternalSeedPeer>();
+	
+	private int	md_info_dict_size;
+	private volatile WeakReference<byte[]>	md_info_dict_ref = new WeakReference<byte[]>( null );
+	
+	private static final int MD_INFO_PEER_HISTORY_MAX 		= 128;
+
+	private Map<String,int[]>	md_info_peer_history = 
+		new LinkedHashMap<String,int[]>(MD_INFO_PEER_HISTORY_MAX,0.75f,true)
+		{
+			protected boolean 
+			removeEldestEntry(
+		   		Map.Entry<String,int[]> eldest) 
+			{
+				return size() > MD_INFO_PEER_HISTORY_MAX;
+			}
+		};
+	
+	
 	
 	protected
 	DownloadManagerController(
@@ -220,7 +261,8 @@ DownloadManagerController
 			setState( initial_state, true );
 		}
 		
-	
+		DownloadManagerState state = download_manager.getDownloadState();
+
 		TOTorrent torrent = download_manager.getTorrent();
 
 		if (torrent != null) {
@@ -228,13 +270,27 @@ DownloadManagerController
 			try{
 				peer_manager_registration = PeerManager.getSingleton().registerLegacyManager( torrent.getHashWrapper(), this );
 				
+				md_info_dict_size = state.getIntAttribute( DownloadManagerState.AT_MD_INFO_DICT_SIZE );
+					
+				if ( md_info_dict_size == 0 ){
+					
+					try{
+						md_info_dict_size = BEncoder.encode((Map)torrent.serialiseToMap().get( "info" )).length;
+					
+					}catch( Throwable e ){
+						
+						md_info_dict_size = -1;
+					}
+					
+					state.setIntAttribute( DownloadManagerState.AT_MD_INFO_DICT_SIZE, md_info_dict_size );
+				}
+				
 			}catch( TOTorrentException e ){
 				
 				Debug.printStackTrace(e);
 			}
 		}
 			
-		DownloadManagerState state = download_manager.getDownloadState();
 		if (state.parameterExists(DownloadManagerState.PARAM_DND_FLAGS)) {
 			long flags = state.getLongParameter(DownloadManagerState.PARAM_DND_FLAGS);
 			cached_complete_excluding_dnd = (flags & STATE_FLAG_COMPLETE_NO_DND) != 0;
@@ -250,7 +306,7 @@ DownloadManagerController
 		DiskManager	dm;
 		
 		try{
-			this_mon.enter();
+			control_mon.enter();
 		
 			if ( getState() != DownloadManager.STATE_READY ){
 			
@@ -283,6 +339,8 @@ DownloadManagerController
 				
 				peer_manager.stopAll();
 				
+				DownloadManagerRateController.removePeerManager( peer_manager );
+				
 				peer_manager	= null;
 			}
 			
@@ -299,7 +357,7 @@ DownloadManagerController
 		
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 	
 		}
 		
@@ -316,6 +374,8 @@ DownloadManagerController
 		tracker_client.setAnnounceDataProvider(
 	    		new TRTrackerAnnouncerDataProvider()
 	    		{
+	    			final private PEPeerManagerStats	pm_stats = temp.getStats();
+	    			
 	    			private long	last_reported_total_received;
 	    			private long	last_reported_total_received_data;
 	    			private long	last_reported_total_received_discard;
@@ -330,14 +390,15 @@ DownloadManagerController
 	    			public long
 	    			getTotalSent()
 	    			{
-	    				return(temp.getStats().getTotalDataBytesSentNoLan());
+	    				return( tracker_stats_exclude_lan?pm_stats.getTotalDataBytesSentNoLan():pm_stats.getTotalDataBytesSent());
 	    			}
+	    			
 	    			public long
 	    			getTotalReceived()
 	    			{
-	    				long received 	= temp.getStats().getTotalDataBytesReceivedNoLan();
-	    				long discarded 	= temp.getStats().getTotalDiscarded();
-	    				long failed		= temp.getStats().getTotalHashFailBytes();
+	    				long received 	= tracker_stats_exclude_lan?pm_stats.getTotalDataBytesReceivedNoLan():pm_stats.getTotalDataBytesReceived();
+	    				long discarded 	= pm_stats.getTotalDiscarded();
+	    				long failed		= pm_stats.getTotalHashFailBytes();
 	    				
 	    				long verified = received - ( discarded + failed );
 
@@ -385,7 +446,7 @@ DownloadManagerController
 	    			public long 
 	    			getFailedHashCheck() 
 	    			{
-	    				return( temp.getStats().getTotalHashFailBytes());
+	    				return( pm_stats.getTotalHashFailBytes());
 	    			}
 	    			
 					public String
@@ -401,6 +462,18 @@ DownloadManagerController
 					}
 					
 					public int 
+					getPendingConnectionCount() 
+					{
+						return( temp.getPendingPeerCount());
+					}
+					
+					public int
+					getConnectedConnectionCount()
+					{
+						return( temp.getNbPeers() + temp.getNbSeeds());
+					}
+					
+					public int 
 					getUploadSpeedKBSec(
 						boolean estimate ) 
 					{
@@ -528,25 +601,27 @@ DownloadManagerController
 	    		});
 	    
 		
-		List	limiters;
+		List<Object[]>	limiters;
 		
 		try{
-			this_mon.enter();
+			control_mon.enter();
 		
 			peer_manager = temp;
 
+			DownloadManagerRateController.addPeerManager( peer_manager );
+			
 			limiters = external_rate_limiters_cow;
 			
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 		}
 		
 		if ( limiters != null ){
 			
 			for (int i=0;i<limiters.size();i++){
 				
-				Object[]	entry = (Object[])limiters.get(i);
+				Object[]	entry = limiters.get(i);
 				
 				temp.addRateLimiter((LimitedRateGroup)entry[0],((Boolean)entry[1]).booleanValue());
 			}
@@ -583,7 +658,7 @@ DownloadManagerController
 	  					DiskManager	dm;
 	  					
 	  					try{
-	  						this_mon.enter();
+	  						control_mon.enter();
 	  					
 		  					dm = getDiskManager();
 
@@ -595,7 +670,8 @@ DownloadManagerController
 		  					}
 		  					
 	  					}finally{
-	  						this_mon.exit();
+	  						
+	  						control_mon.exit();
 	  					}
 	  					
 	  					try{
@@ -703,7 +779,7 @@ DownloadManagerController
 		DiskManagerListener		listener ) 
 	{
 		try{
-			this_mon.enter();
+			control_mon.enter();
 		
 			int	entry_state = getState();
 				
@@ -742,7 +818,7 @@ DownloadManagerController
 	  	  			  	  	
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 		
 			download_manager.informStateChanged();
 		}
@@ -765,7 +841,7 @@ DownloadManagerController
 	forceRecheck(final ForceRecheckListener l) 
 	{
 		try{
-			this_mon.enter();
+			control_mon.enter();
 		
 			if ( getDiskManager() != null || !canForceRecheck() ){
 				
@@ -799,7 +875,7 @@ DownloadManagerController
 	  		
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 		}
 	}  	  
   
@@ -840,7 +916,7 @@ DownloadManagerController
 		final int stateAfterStopping	= _stateAfterStopping;
 		
 		try{
-			this_mon.enter();
+			control_mon.enter();
 		
 			int	state = getState();
 		  
@@ -908,27 +984,54 @@ DownloadManagerController
 					  peer_manager.stopAll(); 
 					  
 					  stats.saveSessionTotals();
+					  
+					  DownloadManagerRateController.removePeerManager( peer_manager );
 					}
 					
 						// do this even if null as it also triggers tracker actions
 					
 					download_manager.informStopped( peer_manager, stateAfterStopping==DownloadManager.STATE_QUEUED );
-						
+											
 					peer_manager	= null;
 
 					DiskManager	dm = getDiskManager();
 					
 					if ( dm != null ){
 						
-						dm.stop( closing );
+						boolean went_async = dm.stop( closing );
+
+						if ( went_async ){
+							
+							int	wait_count = 0;
 
+							// Delay by 10ms, hoping for really short stop
+							Thread.sleep(10);
+
+							while( !dm.isStopped()){
+							
+								wait_count++;
+								
+								if ( wait_count > 2*60*10 ){
+									
+									Debug.out( "Download stop took too long to complete" );
+									
+									break;
+									
+								}else if ( wait_count % 200 == 0 ){
+									
+									Debug.out( "Waiting for download to stop - elapsed=" + wait_count + " sec" );
+								}
+								
+								Thread.sleep(100);
+							}
+						}
+						
 						stats.setCompleted(stats.getCompleted());
 						stats.setDownloadCompleted(stats.getDownloadCompleted(true));
 			      
 					  		// we don't want to update the torrent if we're seeding
 					  
 						if ( !download_manager.getAssumedComplete()){
-					  	
 							download_manager.getDownloadState().save();
 						}			  					  
 					  							  
@@ -949,6 +1052,20 @@ DownloadManagerController
 					   download_manager.deleteTorrentFile();
 				   }
          
+				   List<ExternalSeedPeer> to_remove = new ArrayList<ExternalSeedPeer>();
+
+				   synchronized( http_seeds ){
+
+					   to_remove.addAll( http_seeds );
+					   
+					   http_seeds.clear();
+				   }
+					
+				   for ( ExternalSeedPeer peer: to_remove ){
+					   
+					   peer.remove();
+				   }
+				   
 				   		// only update the state if things haven't gone wrong
 				   
 				   if ( getState() == DownloadManager.STATE_STOPPING ){
@@ -967,7 +1084,7 @@ DownloadManagerController
 		
 		}finally{
 		
-			this_mon.exit();
+			control_mon.exit();
 			
 			download_manager.informStateChanged();
 		}
@@ -1097,7 +1214,7 @@ DownloadManagerController
   		boolean		_inform_changed )
   	{   
   			// we bring this call out of the monitor block to prevent a potential deadlock whereby we chain
-  			// state_mon -> this_mon (there exist numerous dependencies this_mon -> state_mon...
+  			// state_mon -> control_mon (there exist numerous dependencies control_mon -> state_mon...
   		
   		boolean	call_filesExist	= false;
   		
@@ -1328,9 +1445,9 @@ DownloadManagerController
 		PEPeerManager	pm;
 		
 		try{
-			this_mon.enter();
+			control_mon.enter();
 			
-			ArrayList	new_limiters = new ArrayList( external_rate_limiters_cow==null?1:external_rate_limiters_cow.size()+1);
+			ArrayList<Object[]>	new_limiters = new ArrayList<Object[]>( external_rate_limiters_cow==null?1:external_rate_limiters_cow.size()+1);
 			
 			if ( external_rate_limiters_cow != null ){
 				
@@ -1345,7 +1462,7 @@ DownloadManagerController
 			
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 		}	
 		
 		if ( pm != null ){
@@ -1354,6 +1471,37 @@ DownloadManagerController
 		}
 	}
 	
+	public LimitedRateGroup[] 
+	getRateLimiters(
+		boolean	upload )
+	{
+		try{
+			control_mon.enter();
+						
+			if ( external_rate_limiters_cow == null ){
+			
+				return( new LimitedRateGroup[0] );
+				
+			}else{
+			
+				List<LimitedRateGroup> 	result = new ArrayList<LimitedRateGroup>();
+				
+				for ( Object[] entry: external_rate_limiters_cow ){
+					
+					if ((Boolean)entry[1] == upload ){
+						
+						result.add((LimitedRateGroup)entry[0] );
+					}
+				}
+				
+				return( result.toArray( new LimitedRateGroup[ result.size() ]));
+			}
+		}finally{
+			
+			control_mon.exit();
+		}
+	}
+	 
 	public void
 	removeRateLimiter(
 		LimitedRateGroup	group,
@@ -1362,15 +1510,15 @@ DownloadManagerController
 		PEPeerManager	pm;
 		
 		try{
-			this_mon.enter();
+			control_mon.enter();
 			
 			if ( external_rate_limiters_cow != null ){
 				
-				ArrayList	new_limiters = new ArrayList( external_rate_limiters_cow.size()-1);
+				ArrayList<Object[]>	new_limiters = new ArrayList<Object[]>( external_rate_limiters_cow.size()-1);
 				
 				for (int i=0;i<external_rate_limiters_cow.size();i++){
 					
-					Object[]	entry = (Object[])external_rate_limiters_cow.get(i);
+					Object[]	entry = external_rate_limiters_cow.get(i);
 					
 					if ( entry[0] != group ){
 						
@@ -1392,7 +1540,7 @@ DownloadManagerController
 			
 		}finally{
 			
-			this_mon.exit();
+			control_mon.exit();
 		}	
 	
 		if ( pm != null ){
@@ -1879,6 +2027,35 @@ DownloadManagerController
 		return( stats.getDownloadRateLimitBytesPerSecond());
 	}
 	
+		// these per-download rates are not easy to implement as we either have per-peer limits or global limits, with the download-limits being implemented
+		// by adding them to all peers as peer-limits. So for the moment we stick with global (non-lan) limits 
+	
+	public int 
+	getPermittedBytesToReceive()
+	{
+		return( NetworkManager.getSingleton().getRateHandler( false, false ).getCurrentNumBytesAllowed());
+	}
+	
+	public void 
+	permittedReceiveBytesUsed( 
+		int bytes )
+	{
+		NetworkManager.getSingleton().getRateHandler( false, false ).bytesProcessed( bytes );
+	}
+	
+	public int 
+	getPermittedBytesToSend()
+	{
+		return( NetworkManager.getSingleton().getRateHandler( true, false ).getCurrentNumBytesAllowed());
+	}
+	
+	public void	
+	permittedSendBytesUsed(	
+		int bytes )
+	{
+		NetworkManager.getSingleton().getRateHandler( true, false ).bytesProcessed( bytes );
+	}
+	
 	public int
 	getMaxUploads()
 	{
@@ -1908,6 +2085,12 @@ DownloadManagerController
 		return( download_manager.getMaxSeedConnections());
 	}
 	
+	public int
+	getUploadPriority()
+	{
+		return( download_manager.getUploadPriority());
+	}
+
 	public boolean
 	isExtendedMessagingEnabled()
 	{
@@ -1957,6 +2140,74 @@ DownloadManagerController
 		return( download_manager.getNATStatus() == ConnectionManager.NAT_OK );
 	}
 	
+	public boolean 
+	isMetadataDownload() 
+	{
+		return( download_manager.getDownloadState().getFlag( DownloadManagerState.FLAG_METADATA_DOWNLOAD ));
+	}
+	
+	public int 
+	getTorrentInfoDictSize() 
+	{
+		return( md_info_dict_size );
+	}
+	
+	public byte[]
+	getTorrentInfoDict(
+		PEPeer		peer )		
+	{
+		try{
+			String ip = peer.getIp();
+			
+			synchronized( md_info_peer_history ){
+			
+				int	now_secs = (int)( SystemTime.getMonotonousTime()/1000 );
+				
+				int[]	stats = md_info_peer_history.get( ip );
+				
+				if ( stats == null ){
+					
+					stats = new int[]{ now_secs, 0 };
+					
+					md_info_peer_history.put( ip, stats );
+				}
+				
+				if ( now_secs - stats[0] > 5*60 ){
+					
+					stats[1] = 16*1024;
+					
+				}else{
+					
+					int	bytes = stats[1];
+					
+					if ( bytes >= md_info_dict_size*3 ){
+						
+						return( null );
+					}
+					
+					stats[1] = bytes + 16*1024;
+				}
+			}
+			
+			byte[] data = md_info_dict_ref.get();
+			
+			if ( data == null ){
+			
+				TOTorrent torrent = download_manager.getTorrent();
+		
+				data = BEncoder.encode((Map)torrent.serialiseToMap().get( "info" ));
+			
+				md_info_dict_ref = new WeakReference<byte[]>( data );
+			}
+			
+			return( data );
+			
+		}catch( Throwable e ){
+			
+			return( null );
+		}
+	}
+	
 	public void
 	addPeer(
 		PEPeer	peer )
@@ -2044,6 +2295,61 @@ DownloadManagerController
 		return download_manager.getPosition();
 	}
 	
+	public void 
+	statsRequest(
+		PEPeer 		originator, 
+		Map 		request,
+		Map			reply )
+	{	
+		GlobalManager	gm = download_manager.getGlobalManager();
+
+		gm.statsRequest( request, reply );
+		
+		Map	info = new HashMap();
+		
+		reply.put( "dl", info );
+		
+		try{
+			info.put( "u_lim", new Long( getUploadRateLimitBytesPerSecond()));
+			info.put( "d_lim", new Long( getDownloadRateLimitBytesPerSecond()));
+			
+			info.put( "u_rate", new Long( stats.getProtocolSendRate() + stats.getDataSendRate()));
+			info.put( "d_rate", new Long( stats.getProtocolReceiveRate() + stats.getDataReceiveRate()));
+			
+			info.put( "u_slot", new Long( getMaxUploads()));
+			info.put( "c_max", new Long( getMaxConnections()));
+			
+			info.put( "c_leech", new Long( download_manager.getNbPeers()));
+			info.put( "c_seed", new Long( download_manager.getNbSeeds()));
+			
+			PEPeerManager pm = peer_manager;
+			
+			if ( pm != null ){
+				
+				info.put( "c_rem", pm.getNbRemoteTCPConnections());
+				info.put( "c_rem_utp", pm.getNbRemoteUTPConnections());
+				info.put( "c_rem_udp", pm.getNbRemoteUDPConnections());
+				
+				List<PEPeer> peers = pm.getPeers();
+				
+				List<Long>	slot_up = new ArrayList<Long>();
+				
+				info.put( "slot_up", slot_up );
+				
+				for ( PEPeer p: peers ){
+					
+					if ( !p.isChokedByMe()){
+						
+						long up = p.getStats().getDataSendRate() + p.getStats().getProtocolSendRate();
+						
+						slot_up.add( up );
+					}
+				}
+			}
+		}catch( Throwable e ){
+		}
+	}
+	
 	public void
 	addHTTPSeed(
 		String	address,
@@ -2071,7 +2377,29 @@ DownloadManagerController
 	
 				config.put("httpseeds-params", params);
 	
-				plugin.addSeed( org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl.getDownloadStatic( download_manager ), config);
+				List<ExternalSeedPeer> new_seeds = plugin.addSeed( org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl.getDownloadStatic( download_manager ), config);
+				
+				if ( new_seeds.size() > 0 ){
+					
+					List<ExternalSeedPeer> to_remove = new ArrayList<ExternalSeedPeer>();
+					
+					synchronized( http_seeds ){
+						
+						http_seeds.addAll( new_seeds );
+						
+						while( http_seeds.size() > HTTP_SEEDS_MAX ){
+							
+							ExternalSeedPeer x = http_seeds.removeFirst();
+							
+							to_remove.add( x );
+						}
+					}
+					
+					for (ExternalSeedPeer peer: to_remove ){
+						
+						peer.remove();
+					}
+				}
 			}
 		}catch( Throwable e ){
 			
@@ -2163,8 +2491,8 @@ DownloadManagerController
 			return delegate.nbFiles();
 		}
 
-		public void setPriority(boolean[] toChange, boolean setPriority) {
-			delegate.setPriority(toChange, setPriority);
+		public void setPriority(int[] toChange) {
+			delegate.setPriority(toChange);
 		}
 
 		public void setSkipped(boolean[] toChange, boolean setSkipped) {
@@ -2184,7 +2512,7 @@ DownloadManagerController
 			final List delayed_prio_changes = new ArrayList(0);
 			
 			try {
-				this_mon.enter();
+				facade_mon.enter();
 				if (files_facade_destroyed)	return;
 
 				DiskManager dm = DownloadManagerController.this.getDiskManager();
@@ -2236,7 +2564,7 @@ DownloadManagerController
 				delegate = active;
 				
 			} finally {
-				this_mon.exit();
+				facade_mon.exit();
 			}
 			
 			fileFacadeSet.facadeFiles = info;
@@ -2265,7 +2593,7 @@ DownloadManagerController
 		
 		protected void destroyFileInfo() {
 			try {
-				this_mon.enter();
+				facade_mon.enter();
 				if (fileFacadeSet == null || files_facade_destroyed)
 					return;
 
@@ -2274,7 +2602,7 @@ DownloadManagerController
 				for (int i = 0; i < facadeFiles.length; i++)
 					facadeFiles[i].close();
 			} finally {
-				this_mon.exit();
+				facade_mon.exit();
 			}
 		}
 	}
@@ -2321,7 +2649,7 @@ DownloadManagerController
 
 		public void 
 		setPriority(
-			boolean b )
+			int b )
 		{
 			delegate.setPriority(b);
 		}
@@ -2410,10 +2738,10 @@ DownloadManagerController
 			return( delegate.getNbPieces());
 		}
 				
-		public boolean 
-		isPriority()
+		public int 
+		getPriority()
 		{
-			return( delegate.isPriority());
+			return( delegate.getPriority());
 		}
 		
 		public boolean 
@@ -2458,13 +2786,13 @@ DownloadManagerController
 			throws	Exception
 		{
 			try{
-				this_mon.enter();
+				facade_mon.enter();
 				
 				delegate.flushCache();
 				
 			}finally{
 				
-				this_mon.exit();
+				facade_mon.exit();
 			}
 		}
 		
@@ -2476,13 +2804,13 @@ DownloadManagerController
 			throws IOException
 		{
 			try{
-				this_mon.enter();
+				facade_mon.enter();
 			
 				return( delegate.read( offset, length ));
 				
 			}finally{
 				
-				this_mon.exit();
+				facade_mon.exit();
 			}
 		}
 		
@@ -2490,13 +2818,13 @@ DownloadManagerController
 		close()
 		{
 			try{
-				this_mon.enter();
+				facade_mon.enter();
 
 				delegate.close();
 				
 			}finally{
 				
-				this_mon.exit();
+				facade_mon.exit();
 			}
 		}
 		
@@ -2566,7 +2894,7 @@ DownloadManagerController
 
 		public void stateChanged(int oldDMState, int newDMState) {
 			try {
-				this_mon.enter();
+				control_mon.enter();
 
 				if (getDiskManager() == null) {
 
@@ -2582,7 +2910,7 @@ DownloadManagerController
 				}
 			} finally {
 
-				this_mon.exit();
+				control_mon.exit();
 			}
 
 			
@@ -2604,7 +2932,7 @@ DownloadManagerController
 						boolean update_only_seeding = false;
 
 						try {
-							this_mon.enter();
+							control_mon.enter();
 
 							DiskManager dm = getDiskManager();
 
@@ -2629,7 +2957,7 @@ DownloadManagerController
 							}
 						} finally {
 
-							this_mon.exit();
+							control_mon.exit();
 
 							download_manager.informStateChanged();
 						}
@@ -2650,7 +2978,7 @@ DownloadManagerController
 				} else { // Faulty
 
 					try {
-						this_mon.enter();
+						control_mon.enter();
 
 						DiskManager dm = getDiskManager();
 
@@ -2664,7 +2992,7 @@ DownloadManagerController
 						}
 					} finally {
 
-						this_mon.exit();
+						control_mon.exit();
 					}
 
 					download_manager.setAssumedComplete(false);
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerDefaultPaths.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerDefaultPaths.java
index d4193bf..d76a7dd 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerDefaultPaths.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerDefaultPaths.java
@@ -31,15 +31,19 @@ public class DownloadManagerDefaultPaths extends DownloadManagerMoveHandlerUtils
 			if (on_event) {return null;}
 			
 			DownloadManager dm = ((DownloadImpl)d).getDownload();
-			return determinePaths(dm, UPDATE_FOR_MOVE_DETAILS[1], for_move); // 1 - incomplete downloads
+			return determinePaths(dm, UPDATE_FOR_MOVE_DETAILS[1], for_move, false); // 1 - incomplete downloads
 		}
 		public SaveLocationChange onCompletion(Download d, boolean for_move, boolean on_event) {
 			DownloadManager dm = ((DownloadImpl)d).getDownload();
-			return determinePaths(dm, COMPLETION_DETAILS, for_move);
+			return determinePaths(dm, COMPLETION_DETAILS, for_move, false);
+		}
+		public SaveLocationChange testOnCompletion(Download d, boolean for_move, boolean on_event) {
+			DownloadManager dm = ((DownloadImpl)d).getDownload();
+			return determinePaths(dm, COMPLETION_DETAILS, for_move, true );
 		}
 		public SaveLocationChange onRemoval(Download d, boolean for_move, boolean on_event) {
 			DownloadManager dm = ((DownloadImpl)d).getDownload();
-			return determinePaths(dm, REMOVAL_DETAILS, for_move);
+			return determinePaths(dm, REMOVAL_DETAILS, for_move, false );
 		}
 		public boolean isInDefaultSaveDir(Download d) {
 			DownloadManager dm = ((DownloadImpl)d).getDownload();
@@ -220,8 +224,8 @@ public class DownloadManagerDefaultPaths extends DownloadManagerMoveHandlerUtils
     /**
      * This does the guts of determining appropriate file paths.
      */
-    private static SaveLocationChange determinePaths(DownloadManager dm, MovementInformation mi, boolean check_source) {
-		boolean proceed = !check_source || mi.source.matchesDownload(dm, mi);
+    private static SaveLocationChange determinePaths(DownloadManager dm, MovementInformation mi, boolean check_source, boolean is_test) {
+		boolean proceed = !check_source || mi.source.matchesDownload(dm, mi, is_test );
 		if (!proceed) {
 			logInfo("Cannot consider " + describe(dm, mi) +
 			    " - does not match source criteria.", dm);
@@ -304,7 +308,7 @@ public class DownloadManagerDefaultPaths extends DownloadManagerMoveHandlerUtils
 
     private static class SourceSpecification extends ParameterHelper {
 
-		public boolean matchesDownload(DownloadManager dm, ContextDescriptor context) {
+		public boolean matchesDownload(DownloadManager dm, ContextDescriptor context, boolean ignore_completeness ) {
 			if (this.getBoolean("default dir")) {
 				logInfo("Checking if " + describe(dm, context) + " is inside default dirs.", dm);
 				File[] default_dirs = getDefaultDirs();
@@ -331,7 +335,7 @@ public class DownloadManagerDefaultPaths extends DownloadManagerMoveHandlerUtils
 
 			// Does it work for incomplete downloads?
   			if (!dm.isDownloadComplete(false)) {
-  				boolean can_move = this.getBoolean("incomplete dl");
+  				boolean can_move = ignore_completeness || this.getBoolean("incomplete dl");
   				String log_message = describe(dm, context) + " is incomplete which is " +
   			    	((can_move) ? "" : "not ") + "an appropriate state.";
   				if (!can_move) {
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
index 1010d0b..c3f3d21 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerImpl.java
@@ -40,6 +40,7 @@ import org.gudy.azureus2.core3.disk.DiskManagerFactory;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfoSet;
 import org.gudy.azureus2.core3.disk.impl.DiskManagerImpl;
+import org.gudy.azureus2.core3.disk.impl.DiskManagerUtil;
 import org.gudy.azureus2.core3.download.*;
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerStats;
@@ -49,24 +50,35 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.peer.PEPeerSource;
 import org.gudy.azureus2.core3.peer.PEPiece;
 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.torrent.TOTorrentListener;
 import org.gudy.azureus2.core3.tracker.client.*;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
 import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
 import org.gudy.azureus2.plugins.download.savelocation.SaveLocationChange;
 import org.gudy.azureus2.plugins.network.ConnectionManager;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 
+import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.AzureusCoreOperation;
 import com.aelitis.azureus.core.AzureusCoreOperationTask;
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
 import com.aelitis.azureus.core.peermanager.control.PeerControlSchedulerFactory;
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 import com.aelitis.azureus.core.util.CaseSensitiveFileMap;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
+import com.aelitis.azureus.plugins.tracker.dht.DHTTrackerPlugin;
+import com.aelitis.azureus.plugins.tracker.local.LocalTrackerPlugin;
 
 /**
  * @author Olivier
@@ -203,18 +215,16 @@ DownloadManagerImpl
 	
 		// one static async manager for them all
 	
-	private static ListenerManager	peer_listeners_aggregator 	= ListenerManager.createAsyncManager(
+	private static ListenerManager<DownloadManagerPeerListener>	peer_listeners_aggregator 	= ListenerManager.createAsyncManager(
 			"DM:PeerListenAggregatorDispatcher",
-			new ListenerManagerDispatcher()
+			new ListenerManagerDispatcher<DownloadManagerPeerListener>()
 			{
 				public void
 				dispatch(
-					Object		_listener,
-					int			type,
-					Object		value )
+					DownloadManagerPeerListener		listener,
+					int								type,
+					Object							value )
 				{
-					DownloadManagerPeerListener	listener = (DownloadManagerPeerListener)_listener;
-					
 					if ( type == LDT_PE_PEER_ADDED ){
 						
 						listener.peerAdded((PEPeer)value);
@@ -234,13 +244,15 @@ DownloadManagerImpl
 				}
 			});
 
-	private ListenerManager	peer_listeners 	= ListenerManager.createManager(
+	private static Object TPS_Key = new Object();
+	
+	private ListenerManager<DownloadManagerPeerListener>	peer_listeners 	= ListenerManager.createManager(
 			"DM:PeerListenDispatcher",
-			new ListenerManagerDispatcher()
+			new ListenerManagerDispatcher<DownloadManagerPeerListener>()
 			{
 				public void
 				dispatch(
-					Object		listener,
+					DownloadManagerPeerListener		listener,
 					int			type,
 					Object		value )
 				{
@@ -296,6 +308,8 @@ DownloadManagerImpl
 				}
 			});	
 	
+	private List<DownloadManagerTPSListener>	tps_listeners;
+	
 	private AEMonitor	piece_listeners_mon	= new AEMonitor( "DM:DownloadManager:PeiceL" );
 	
 	private List	current_pieces	= new ArrayList();
@@ -395,10 +409,10 @@ DownloadManagerImpl
 								peer_listeners_mon.exit();
 							}
 															
-							new AEThread( "DM:torrentChangeFlusher", true )
+							new AEThread2( "DM:torrentChangeFlusher", true )
 							{
 								public void
-								runSupport()
+								run()
 								{
 									for (int i=0;i<peers.size();i++){
 										
@@ -406,24 +420,6 @@ DownloadManagerImpl
 										
 										peer.getManager().removePeer( peer, "Private torrent: tracker changed" );
 									}
-									
-										// force through a stop on old url
-									
-									try{
-										TRTrackerAnnouncer an = TRTrackerAnnouncerFactory.create( torrent, true );
-										
-										an.cloneFrom( announcer );
-										
-										an.setTrackerURL( old_url );
-										
-										an.stop( false );
-										
-										an.destroy();
-										
-									}catch( Throwable e ){
-										
-										Debug.printStackTrace(e);
-									}
 								}
 							}.start();
 						}
@@ -499,7 +495,7 @@ DownloadManagerImpl
     private int		current_upload_when_busy_bps;
     private long	last_upload_when_busy_update;
     private long	last_upload_when_busy_dec_time;
-    
+    private int		upload_priority;
     private int		crypto_level = NetworkManager.CRYPTO_OVERRIDE_NONE;
     
 	// Only call this with STATE_QUEUED, STATE_WAITING, or STATE_STOPPED unless you know what you are doing
@@ -556,14 +552,45 @@ DownloadManagerImpl
 						persistent && !_recovered, _open_for_seeding, _has_ever_been_started,
 						_initialState );		
 
-		if ( torrent != null && _initialisation_adapter != null ){
+		if ( torrent != null ){
 			
-			try{
-				_initialisation_adapter.initialised( this );
+			if ( _open_for_seeding && !_recovered ){
 				
-			}catch( Throwable e ){
+				Map<Integer,File>	linkage = TorrentUtils.getInitialLinkage( torrent );
+				
+				if ( linkage.size() > 0 ){
+				
+					DownloadManagerState	dms = getDownloadState();
+										
+					DiskManagerFileInfo[]	files = getDiskManagerFileInfoSet().getFiles();
 					
-				Debug.printStackTrace(e);
+					try{
+						dms.suppressStateSave( true );
+
+						for ( Map.Entry<Integer,File> entry: linkage.entrySet()){
+					
+							int	index 	= entry.getKey();
+							File target = entry.getValue();
+								
+							dms.setFileLink( files[index].getFile( false ), target );
+							
+						}
+					}finally{
+							
+						dms.suppressStateSave( false );
+					}
+				}
+			}
+			
+			if ( _initialisation_adapter != null ){
+			
+				try{
+					_initialisation_adapter.initialised( this );
+					
+				}catch( Throwable e ){
+						
+					Debug.printStackTrace(e);
+				}
 			}
 		}
 	}
@@ -650,7 +677,7 @@ DownloadManagerImpl
 				 	// if its a simple torrent and an explicit save file wasn't supplied, use
 				 	// the torrent name itself
 
-				 display_name = FileUtil.convertOSSpecificChars(locale_decoder.decodeString(torrent.getName()),false);
+				 display_name = FileUtil.convertOSSpecificChars(TorrentUtils.getLocalisedName(torrent),false);
 				 
 				 internal_name = ByteFormatter.nicePrint(torrent.getHash(),true);
 	
@@ -739,25 +766,26 @@ DownloadManagerImpl
 				 	// final validity test must be based of potentially linked target location as file
 				 	// may have been re-targetted
 	
-				 File	linked_target = getSaveLocation();
-				 
-				 if ( !linked_target.exists()){
 				 	
-				 		// if this isn't a new torrent then we treat the absence of the enclosing folder
-				 		// as a fatal error. This is in particular to solve a problem with the use of
-				 		// externally mounted torrent data on OSX, whereby a re-start with the drive unmounted
-				 		// results in the creation of a local diretory in /Volumes that subsequently stuffs
-				 		// up recovery when the volume is mounted
+					// if this isn't a new torrent then we treat the absence of the enclosing folder
+					// as a fatal error. This is in particular to solve a problem with the use of
+				 	// externally mounted torrent data on OSX, whereby a re-start with the drive unmounted
+				 	// results in the creation of a local diretory in /Volumes that subsequently stuffs
+				 	// up recovery when the volume is mounted
 				 	
-				 		// changed this to only report the error on non-windows platforms 
+				 	// changed this to only report the error on non-windows platforms 
 				 	
-				 	if ( !(new_torrent || Constants.isWindows )){
+				if ( !(new_torrent || Constants.isWindows )){
 				 		
-							// another exception here - if the torrent has never been started then we can
-							// fairly safely continue as its in a stopped state
+						// another exception here - if the torrent has never been started then we can
+						// fairly safely continue as its in a stopped state
 						
-						if ( has_ever_been_started ){
+					if ( has_ever_been_started ){
 				 		
+						 File	linked_target = getSaveLocation();
+							 
+						 if ( !linked_target.exists()){
+
 							throw (new NoStackException(
 									MessageText.getString("DownloadManager.error.datamissing")
 											+ " " + Debug.secretFileName(linked_target.toString())));
@@ -765,6 +793,22 @@ DownloadManagerImpl
 				 	}
 				 }	
 				 
+		 		// propagate properties from torrent to download
+			 
+				boolean	low_noise = TorrentUtils.getFlag( torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE );
+				
+				if ( low_noise ){
+					
+					download_manager_state.setFlag( DownloadManagerState.FLAG_LOW_NOISE, true );
+				}
+					
+				boolean	metadata_dl = TorrentUtils.getFlag( torrent, TorrentUtils.TORRENT_FLAG_METADATA_TORRENT );
+				
+				if ( metadata_dl ){
+					
+					download_manager_state.setFlag( DownloadManagerState.FLAG_METADATA_DOWNLOAD, true );
+				}
+
 				 	// if this is a newly introduced torrent trash the tracker cache. We do this to
 				 	// prevent, say, someone publishing a torrent with a load of invalid cache entries
 				 	// in it and a bad tracker URL. This could be used as a DOS attack
@@ -772,16 +816,7 @@ DownloadManagerImpl
 				 if ( new_torrent ){
 				 	
 					download_manager_state.setLongParameter( DownloadManagerState.PARAM_DOWNLOAD_ADDED_TIME, SystemTime.getCurrentTime());
-					 
-				 		// propagate initial properties from torrent to download
-					 
-					boolean	low_noise = TorrentUtils.getFlag( torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE );
-					
-					if ( low_noise ){
-						
-						download_manager_state.setFlag( DownloadManagerState.FLAG_LOW_NOISE, true );
-					}
-							
+					 					
 					Map peer_cache = TorrentUtils.getPeerCache( torrent );
 					
 					if ( peer_cache != null ){
@@ -946,15 +981,40 @@ DownloadManagerImpl
 			
 			if ( torrent_save_location != null ){
 				
-				try{
-					torrent_save_location = torrent_save_location.getCanonicalFile();
+				boolean	already_done = false;
+				
+				String cache = download_manager_state.getAttribute( DownloadManagerState.AT_CANONICAL_SD_DMAP );
+				
+				if ( cache != null ){
 					
-				}catch( Throwable e ){
+					String key = torrent_save_location.getAbsolutePath() + "\n";
 					
-					torrent_save_location = torrent_save_location.getAbsoluteFile();
+					if ( cache.startsWith( key )){
+						
+						torrent_save_location = new File( cache.substring( key.length()));
+						
+						already_done = true;
+					}
 				}
 				
-				// update cached stuff in case something changed
+				if ( !already_done ){
+					
+					String key = torrent_save_location.getAbsolutePath() + "\n";
+
+					try{
+						torrent_save_location = torrent_save_location.getCanonicalFile();
+						
+					}catch( Throwable e ){
+						
+						torrent_save_location = torrent_save_location.getAbsoluteFile();
+					}
+					
+					download_manager_state.setAttribute( 
+						DownloadManagerState.AT_CANONICAL_SD_DMAP,
+						key + torrent_save_location.getAbsolutePath());
+				}
+					// update cached stuff in case something changed
+				
 				getSaveLocation();
 			}
 			
@@ -999,6 +1059,9 @@ DownloadManagerImpl
 
 		max_uploads = Math.max( max_uploads, DownloadManagerState.MIN_MAX_UPLOADS );
 		max_uploads_when_seeding = Math.max( max_uploads_when_seeding, DownloadManagerState.MIN_MAX_UPLOADS );
+		
+		upload_priority							= getDownloadState().getIntParameter( DownloadManagerState.PARAM_UPLOAD_PRIORITY );
+
 	}
 	
 	protected int
@@ -1037,6 +1100,12 @@ DownloadManagerImpl
 		return( max_uploads_when_seeding );
 	}
 	
+	protected int
+	getUploadPriority()
+	{
+		return( upload_priority );
+	}
+	
 	public int
 	getMaxUploads()
 	{
@@ -1050,6 +1119,13 @@ DownloadManagerImpl
 		download_manager_state.setIntParameter( DownloadManagerState.PARAM_MAX_UPLOADS, max );
 	}
 	
+	public void
+	setUploadPriority(
+		int	priority )
+	{
+		download_manager_state.setIntParameter( DownloadManagerState.PARAM_UPLOAD_PRIORITY, priority );
+	}
+	
 	public int
 	getEffectiveMaxUploads()
 	{
@@ -1619,22 +1695,32 @@ DownloadManagerImpl
  		controller.startDownload( getTrackerClient() ); 
   	}
   	
-  	public void
-  	stopIt(
-  		int		state_after_stopping,
-  		boolean	remove_torrent,
-  		boolean	remove_data )
-  	{
-  		try{
-  			download_manager_state.setLongAttribute( DownloadManagerState.AT_TIME_STOPPED, SystemTime.getCurrentTime());
+	public void 
+	stopIt(
+			int state_after_stopping, 
+			boolean remove_torrent,
+			boolean remove_data) 
+	{
+		try {
+			boolean closing = state_after_stopping == DownloadManager.STATE_CLOSED;
+			int curState = getState();
+			boolean alreadyStopped = curState == STATE_STOPPED
+					|| curState == STATE_STOPPING || curState == STATE_ERROR;
+			boolean skipSetTimeStopped = alreadyStopped
+					|| (closing && curState == STATE_QUEUED);
+
+			if (!skipSetTimeStopped) {
+				download_manager_state.setLongAttribute(
+						DownloadManagerState.AT_TIME_STOPPED, SystemTime.getCurrentTime());
+			}
 
-  			controller.stopIt( state_after_stopping, remove_torrent, remove_data );
-  			
-  		}finally{
-  			
-			download_manager_state.setActive( false );
-  		}
-  	}
+			controller.stopIt(state_after_stopping, remove_torrent, remove_data);
+
+		} finally {
+
+			download_manager_state.setActive(false);
+		}
+	}
   	
 	public boolean
 	pause()
@@ -2093,7 +2179,10 @@ DownloadManagerImpl
 				response = scraper.scrape(torrent);
    
 			}else{
-    			    			
+    			   
+				URL							backup_url 		= null;
+				TRTrackerScraperResponse	backup_response = null;
+				
 					// we use a fixed seed so that subsequent scrapes will randomise
     				// in the same order, as required by the spec. Note that if the
     				// torrent's announce sets are edited this all works fine (if we
@@ -2131,10 +2220,23 @@ DownloadManagerImpl
 								// Exit if online
 							
 							if (status == TRTrackerScraperResponse.ST_ONLINE) {
-
-								active_url	= url;
 								
-								break;
+								if ( response.isDHTBackup()){
+								
+										// we'll use this if we don't find anything better
+									
+									backup_url		= url;
+									backup_response	= response;
+									
+									response = null;
+									
+									continue;
+								}else{
+									
+									active_url	= url;
+
+									break;
+								}
 							}
 
 								// Scrape 1 at a time to save on outgoing connections
@@ -2163,7 +2265,15 @@ DownloadManagerImpl
     		
 				if ( response == null ){
     			
-					response = non_null_response;
+					if ( backup_response != null ){
+						
+						response 	= backup_response;
+						active_url	= backup_url;
+						
+					}else{
+						
+						response = non_null_response;
+					}
 				}
 			}
 		}
@@ -2277,12 +2387,22 @@ DownloadManagerImpl
 		return controller.getDiskManagerFileInfoSet();
 	}
   
+	/**
+	 * @deprecated use getDiskManagerFileInfoSet() instead 
+	 */
 	public DiskManagerFileInfo[]
    	getDiskManagerFileInfo()
 	{
 		return( controller.getDiskManagerFileInfo());
 	}
 	
+	public int getNumFileInfos() {
+		// probably faster than controller.getDiskManagerFileInfoSet().nbFiles()
+		// (especially when the facade isn't filled yet)
+		return torrent == null ? 0 : torrent.isSimpleTorrent() ? 1
+				: torrent.getFiles().length;
+	}
+	
 	public PEPeerManager
 	getPeerManager()
 	{
@@ -2836,7 +2956,7 @@ DownloadManagerImpl
 		  
 			int nbSeeds = getNbSeeds();
 			int nbPeers = getNbPeers();
-			int nbRemotes = peerManager.getNbRemoteConnectionsExcludingUDP();
+			int nbRemotes = peerManager.getNbRemoteTCPConnections() + peerManager.getNbRemoteUTPConnections();
 			
 			TRTrackerAnnouncerResponse	announce_response = tc.getLastResponse();
 			
@@ -2908,7 +3028,7 @@ DownloadManagerImpl
 	  
 		if ( tc != null && peerManager != null && (state == STATE_DOWNLOADING || state == STATE_SEEDING)) {
 		  			
-			if ( peerManager.getNbRemoteConnectionsExcludingUDP() > 0 ){
+			if ( peerManager.getNbRemoteTCPConnections() > 0 || peerManager.getNbRemoteUTPConnections() > 0 ){
 				
 				return( ConnectionManager.NAT_OK );
 			}
@@ -2941,7 +3061,7 @@ DownloadManagerImpl
 			
 				// tracker's ok but no remotes - give it some time
 			
-			if ( SystemTime.getCurrentTime() - peerManager.getTimeStarted() < 3*60*1000 ){
+			if ( SystemTime.getCurrentTime() - peerManager.getTimeStarted( false ) < 3*60*1000 ){
 				
 				return ConnectionManager.NAT_UNKNOWN;
 			}
@@ -2958,6 +3078,22 @@ DownloadManagerImpl
 						
 					return ConnectionManager.NAT_UNKNOWN;
 				}
+				
+					// can't expect incoming if we're seeding and there are no peers
+				
+				if ( state == STATE_SEEDING  && scrape_response.getPeers() == 0 ){
+					
+					return ConnectionManager.NAT_UNKNOWN;
+				}
+			}else{
+				
+					// no scrape and we're seeding - don't use this as sign of badness as
+					// we can't determine
+				
+				if ( state == STATE_SEEDING ){
+					
+					return ConnectionManager.NAT_UNKNOWN;
+				}
 			}
 				
 			return ConnectionManager.NAT_BAD;
@@ -2998,17 +3134,20 @@ DownloadManagerImpl
 	protected void 
 	deleteDataFiles() 
 	{
+		DownloadManagerState state = getDownloadState();
+		
 		DiskManagerFactory.deleteDataFiles(
 			torrent, 
 			torrent_save_location.getParent(), 
 			torrent_save_location.getName(),
-			getDownloadState().getFlag( DownloadManagerState.FLAG_LOW_NOISE ));
+			( 	state.getFlag( DownloadManagerState.FLAG_LOW_NOISE ) ||
+				state.getFlag( DownloadManagerState.FLAG_FORCE_DIRECT_DELETE )));
 		
 		// Attempted fix for bug 1572356 - apparently sometimes when we perform removal of a download's data files,
 		// it still somehow gets processed by the move-on-removal rules. I'm making the assumption that this method
 		// is only called when a download is about to be removed.
 		
-		this.getDownloadState().setFlag(DownloadManagerState.FLAG_DISABLE_AUTO_FILE_MOVE, true);
+		state.setFlag(DownloadManagerState.FLAG_DISABLE_AUTO_FILE_MOVE, true);
 	}
   
 	protected void 
@@ -3205,9 +3344,13 @@ DownloadManagerImpl
 	  finally {if (is_paused) {this.resume();}}
   	}
   
-  private void moveDataFilesSupport0(
-			File new_parent_dir, 
-			String new_filename) throws DownloadManagerException {
+  private void 
+  moveDataFilesSupport0(
+	File 		new_parent_dir, 
+	String 		new_filename )
+  
+  	throws DownloadManagerException 
+  {
 	  if (!canMoveDataFiles()){
 		  throw new DownloadManagerException("canMoveDataFiles is false!");
 	  }
@@ -3320,7 +3463,7 @@ DownloadManagerImpl
 			  }
 		  }
 	  }else{
-		  dm.moveDataFiles( new_save_location.getParentFile(), new_save_location.getName());
+		  dm.moveDataFiles( new_save_location.getParentFile(), new_save_location.getName(), null );
 	  }
   }
   
@@ -3417,6 +3560,13 @@ DownloadManagerImpl
 	  controller.addRateLimiter( group, upload );
   }
 
+  public LimitedRateGroup[] 
+  getRateLimiters(
+	boolean	upload )
+  {
+	  return( controller.getRateLimiters( upload ));
+  }
+  
   public void
   removeRateLimiter(
 	  LimitedRateGroup	group,
@@ -3502,6 +3652,758 @@ DownloadManagerImpl
 		return( false );
   }
   
+  	public List<TrackerPeerSource> 
+  	getTrackerPeerSources() 
+  	{	  
+  		try{
+  			this_mon.enter();
+
+  			Object[] tps_data = (Object[])getUserData( TPS_Key );
+
+  			List<TrackerPeerSource>	tps;
+  			
+  			if ( tps_data == null ){
+
+  				tps = new ArrayList<TrackerPeerSource>();
+
+  				TOTorrentListener tol =
+  					new TOTorrentListener()
+					{
+						public void 
+						torrentChanged(
+							TOTorrent	torrent,
+							int 		type ) 
+						{
+							if ( type == TOTorrentListener.CT_ANNOUNCE_URLS ){
+
+								List<DownloadManagerTPSListener>	to_inform = null;
+								
+						 		try{
+						  			this_mon.enter();
+
+						  			torrent.removeListener( this );
+						  			
+						  			setUserData( TPS_Key, null );
+
+						  			if ( tps_listeners != null ){
+						  				
+						  				to_inform = new ArrayList<DownloadManagerTPSListener>( tps_listeners );
+						  			}
+						  		}finally{
+
+						  			this_mon.exit();
+						  		}
+						  		
+						  		if ( to_inform != null ){
+						  			
+						  			for ( DownloadManagerTPSListener l: to_inform ){
+						  				
+						  				try{
+						  				
+						  					l.trackerPeerSourcesChanged();
+						  					
+						  				}catch( Throwable e ){
+						  					
+						  					Debug.out(e);
+						  				}
+						  			}
+						  		}
+							}
+						}
+					};
+					
+  				setUserData( TPS_Key, new Object[]{ tps, tol });
+
+  					// tracker peer sources
+  				
+  				TOTorrent t = getTorrent();
+
+  				if ( t != null ){
+
+  					t.addListener( tol );
+  					
+  					TOTorrentAnnounceURLSet[] sets = t.getAnnounceURLGroup().getAnnounceURLSets();
+  					
+  					if ( sets.length == 0 ){
+  						
+  						sets = new TOTorrentAnnounceURLSet[]{ t.getAnnounceURLGroup().createAnnounceURLSet( new URL[]{ torrent.getAnnounceURL()})};
+  					}
+  					  
+  						// source per set
+  					
+					for ( final TOTorrentAnnounceURLSet set: sets ){
+						
+						final URL[] urls = set.getAnnounceURLs();
+						
+						if ( urls.length == 0 || TorrentUtils.isDecentralised( urls[0] )){
+							
+							continue;
+						}
+						
+						tps.add( 
+							new TrackerPeerSource()
+							{
+								private TrackerPeerSource _delegate;
+								
+			 					private TRTrackerAnnouncer		ta;
+			  					private long					ta_fixup;
+
+			  					private long		last_scrape_time;
+			  					private int[]		last_scrape;
+			  					
+								private TrackerPeerSource
+								fixup()
+								{
+									long	now = SystemTime.getMonotonousTime();
+									
+									if ( now - ta_fixup > 1000 ){
+										
+										TRTrackerAnnouncer current_ta = getTrackerClient();
+										
+										if ( current_ta == ta ){
+											
+											if ( current_ta != null && _delegate == null ){
+												
+												_delegate = current_ta.getTrackerPeerSource( set );
+											}
+										}else{
+											
+											if ( current_ta == null ){
+												
+												_delegate = null;
+												
+											}else{
+												
+												_delegate = current_ta.getTrackerPeerSource( set );
+											}
+											
+											ta = current_ta;
+										}
+										
+										ta_fixup	= now;
+									}
+									
+									return( _delegate );
+								}
+								
+								protected int[]
+								getScrape()
+								{
+									long now = SystemTime.getMonotonousTime();
+									
+									if ( now - last_scrape_time > 30*1000 || last_scrape == null ){
+
+										TRTrackerScraper	scraper = globalManager.getTrackerScraper();
+
+										int	max_peers = -1;
+										int max_seeds = -1;
+										
+										for ( URL u: urls ){
+										
+											TRTrackerScraperResponse resp = scraper.peekScrape(torrent, u );
+											
+											if ( resp != null ){
+												
+												if ( !resp.isDHTBackup()){
+													
+													int peers = resp.getPeers();
+													int seeds = resp.getSeeds();
+													
+													if ( peers > max_peers ){
+													
+														max_peers = peers;
+													}
+													
+													if ( seeds > max_seeds ){
+														
+														max_seeds = seeds;
+													}
+												}
+											}
+										}
+										
+										last_scrape = new int[]{ max_seeds, max_peers }; 
+										
+										last_scrape_time = now;
+									}
+									
+									return( last_scrape );
+								}
+								
+								public int
+								getType()
+								{
+									return( TrackerPeerSource.TP_TRACKER );
+								}
+								
+								public String
+								getName()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( urls[0].toExternalForm());
+									}
+									
+									return( delegate.getName());
+								}
+								
+								public int 
+								getStatus()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( ST_STOPPED );
+									}
+									
+									return( delegate.getStatus());
+								}
+								
+								public String 
+								getStatusString()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( null );
+									}
+									
+									return( delegate.getStatusString());
+								}
+								
+								public int
+								getSeedCount()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( getScrape()[0] );
+									}
+									
+									int seeds = delegate.getSeedCount();
+									
+									if ( seeds < 0 ){
+										
+										seeds = getScrape()[0];
+									}
+									
+									return( seeds );
+								}
+								
+								public int
+								getLeecherCount()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( getScrape()[1] );
+									}
+									
+									int leechers = delegate.getLeecherCount();
+									
+									if ( leechers < 0 ){
+										
+										leechers = getScrape()[1];
+									}
+									
+									return( leechers );						
+								}
+	
+								public int
+								getPeers()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( -1 );
+									}
+									
+									return( delegate.getPeers());							
+								}
+
+								public int
+								getInterval()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( -1 );
+									}
+									
+									return( delegate.getInterval());							
+								}
+								
+								public int
+								getMinInterval()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( -1 );
+									}
+									
+									return( delegate.getMinInterval());							
+								}
+								
+								public boolean
+								isUpdating()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( false );
+									}
+									
+									return( delegate.isUpdating());							
+								}
+								
+								public int
+								getSecondsToUpdate()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( -1 );
+									}
+									
+									return( delegate.getSecondsToUpdate());
+								}
+								
+								public boolean
+								canManuallyUpdate()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+										
+										return( false );
+									}
+									
+									return( delegate.canManuallyUpdate());
+								}
+								
+								public void
+								manualUpdate()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate != null ){
+										
+										delegate.manualUpdate();
+									}
+								}
+							});
+					}
+					
+						// cache peer source
+					
+					tps.add( 
+							new TrackerPeerSourceAdapter()
+							{
+								private TrackerPeerSource _delegate;
+								
+			 					private TRTrackerAnnouncer		ta;
+			 					private boolean					enabled;
+			  					private long					ta_fixup;
+
+								private TrackerPeerSource
+								fixup()
+								{
+									long	now = SystemTime.getMonotonousTime();
+									
+									if ( now - ta_fixup > 1000 ){
+										
+										TRTrackerAnnouncer current_ta = getTrackerClient();
+										
+										if ( current_ta == ta ){
+											
+											if ( current_ta != null && _delegate == null ){
+												
+												_delegate = current_ta.getCacheTrackerPeerSource();
+											}
+										}else{
+											
+											if ( current_ta == null ){
+												
+												_delegate = null;
+												
+											}else{
+												
+												_delegate = current_ta.getCacheTrackerPeerSource();
+											}
+											
+											ta = current_ta;
+										}
+										
+										enabled = controller.isPeerSourceEnabled( PEPeerSource.PS_BT_TRACKER );
+										
+										ta_fixup	= now;
+									}
+									
+									return( _delegate );
+								}
+								
+								public int
+								getType()
+								{
+									return( TrackerPeerSource.TP_TRACKER );
+								}
+								
+								public String
+								getName()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null ){
+									
+										return( MessageText.getString( "tps.tracker.cache" ));
+									}
+									
+									return( delegate.getName());
+								}
+								
+								public int 
+								getStatus()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( !enabled ){
+										
+										return( ST_DISABLED );
+									}
+									
+									if ( delegate == null ){
+									
+										return( ST_STOPPED );
+									}
+									
+									return( ST_ONLINE );
+								}
+	
+								public int
+								getPeers()
+								{
+									TrackerPeerSource delegate = fixup();
+									
+									if ( delegate == null || !enabled ){
+									
+										return( -1 );
+									}
+									
+									return( delegate.getPeers());							
+								}
+							});
+  				}
+  			
+	  				// http seeds
+	  			
+	  			try{
+	  				ExternalSeedPlugin esp = DownloadManagerController.getExternalSeedPlugin();
+	  				
+	  				if ( esp != null ){
+	  					  					
+						tps.add( esp.getTrackerPeerSource( PluginCoreUtils.wrap( this ) ));
+	 				}
+	  			}catch( Throwable e ){
+	  			}
+	  			
+	  				// dht
+	  			
+	  			try{
+	  				
+					PluginInterface dht_pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass(DHTTrackerPlugin.class);
+	
+	  			    if ( dht_pi != null ){
+	  			    	
+	  			    	tps.add(((DHTTrackerPlugin)dht_pi.getPlugin()).getTrackerPeerSource( PluginCoreUtils.wrap( this )));
+	  			    }
+				}catch( Throwable e ){
+	  			}
+	  			
+					// LAN
+				
+				try{
+					
+					PluginInterface lt_pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass(LocalTrackerPlugin.class);
+	
+					if ( lt_pi != null ){
+						
+	  			    	tps.add(((LocalTrackerPlugin)lt_pi.getPlugin()).getTrackerPeerSource( PluginCoreUtils.wrap( this )));
+					
+					}
+					
+				}catch( Throwable e ){
+					
+				}
+				
+					// Plugin
+				
+				try{
+				
+					tps.add(((DownloadImpl)PluginCoreUtils.wrap( this )).getTrackerPeerSource());
+					
+				}catch( Throwable e ){
+					
+				}
+				
+					// PEX...
+				
+				tps.add(
+					new TrackerPeerSourceAdapter()
+					{
+						private PEPeerManager		_pm;
+						private TrackerPeerSource	_delegate;
+						
+						private TrackerPeerSource 
+						fixup()
+						{
+							PEPeerManager pm = getPeerManager();
+							
+							if ( pm == null ){
+								
+								_delegate 	= null;
+								_pm			= null;
+								
+							}else if ( pm != _pm ){
+								
+								_pm	= pm;
+								
+								_delegate = pm.getTrackerPeerSource();
+							}
+							
+							return( _delegate );
+						}
+						
+						public int
+						getType()
+						{
+							return( TP_PEX );
+						}
+						
+						public int
+						getStatus()
+						{
+							TrackerPeerSource delegate = fixup();
+							
+							if ( delegate == null ){
+								
+								return( ST_STOPPED );
+								
+							}else{
+								
+								return( delegate.getStatus());
+							}
+						}
+						
+						public String 
+						getName() 
+						{
+							TrackerPeerSource delegate = fixup();
+							
+							if ( delegate == null ){
+								
+								return( "" );
+								
+							}else{
+								
+								return( delegate.getName());
+							}	
+						}
+						
+						public int 
+						getPeers() 
+						{
+							TrackerPeerSource delegate = fixup();
+							
+							if ( delegate == null ){
+								
+								return( -1 );
+								
+							}else{
+								
+								return( delegate.getPeers());
+							}	
+						}
+					});
+				
+					// incoming
+				
+				tps.add(
+						new TrackerPeerSourceAdapter()
+						{
+							private long				fixup_time;
+						
+							private PEPeerManager		_pm;
+							private int					tcp;
+							private int					udp;
+							private int					utp;
+							private int					total;
+							private boolean				enabled;
+							
+							private PEPeerManager 
+							fixup()
+							{
+								long	now = SystemTime.getMonotonousTime();
+								
+								if ( now - fixup_time > 1000 ){
+	
+									PEPeerManager pm = _pm = getPeerManager();
+									
+									if ( pm != null ){
+										
+										tcp 	= pm.getNbRemoteTCPConnections();
+										udp		= pm.getNbRemoteUDPConnections();
+										utp		= pm.getNbRemoteUTPConnections();
+										total	= pm.getStats().getTotalIncomingConnections();
+									}
+									
+									enabled = controller.isPeerSourceEnabled( PEPeerSource.PS_INCOMING );
+									
+									fixup_time = now;
+								}
+								
+								return( _pm );
+							}
+							
+							public int
+							getType()
+							{
+								return( TP_INCOMING );
+							}
+							
+							public int
+							getStatus()
+							{
+								PEPeerManager delegate = fixup();
+								
+								if ( delegate == null ){
+									
+									return( ST_STOPPED );
+									
+								}else if ( !enabled ){
+									
+									return( ST_DISABLED );
+										
+								}else{
+								
+									return( ST_ONLINE );
+								}
+							}
+							
+							public String 
+							getName() 
+							{
+								PEPeerManager delegate = fixup();
+								
+								if ( delegate == null || !enabled ){
+									
+									return( "" );
+									
+								}else{
+									
+									return( 
+										MessageText.getString( 
+											"tps.incoming.details",
+											new String[]{ String.valueOf( tcp ), String.valueOf( udp + utp ), String.valueOf( total )} ));
+								}	
+							}
+							
+							public int 
+							getPeers() 
+							{
+								PEPeerManager delegate = fixup();
+								
+								if ( delegate == null || !enabled ){
+									
+									return( -1 );
+									
+								}else{
+									
+									return( tcp + udp );
+								}	
+							}
+						});
+				
+ 			}else{
+  				
+  				tps = (List<TrackerPeerSource>)tps_data[0];
+  			}
+ 
+  			return( tps );
+
+  		}finally{
+
+  			this_mon.exit();
+  		}
+  	}
+
+    public void
+    addTPSListener(
+    	DownloadManagerTPSListener		listener )
+    {
+    	try{
+    		this_mon.enter();
+    		
+    		if ( tps_listeners == null ){
+    			
+    			tps_listeners = new ArrayList<DownloadManagerTPSListener>(1);
+    		}
+    		
+    		tps_listeners.add( listener );
+    		
+    	}finally{
+    		
+    		this_mon.exit();
+    	}
+    }	
+    
+    public void
+    removeTPSListener(
+    	DownloadManagerTPSListener		listener )
+    {
+       	try{
+    		this_mon.enter();
+    		
+    		if ( tps_listeners != null ){
+    		 		
+    			tps_listeners.remove( listener );
+    			
+    			if ( tps_listeners.size() == 0 ){
+    				
+    				tps_listeners = null;
+    				
+    	  			Object[] tps_data = (Object[])getUserData( TPS_Key );
+
+    	  			if ( tps_data != null ){
+		  			
+    	 				TOTorrent t = getTorrent();
+
+    	 				if ( t != null ){
+    	 					
+    	 					t.removeListener( (TOTorrentListener)tps_data[1] );
+    	 				}
+    	 				
+    	  				setUserData( TPS_Key, null );
+    	  			}
+    			}
+    		}
+    	}finally{
+    		
+    		this_mon.exit();
+    	}
+    }
+    
   private byte[]
   getIdentity()
   {
@@ -3749,10 +4651,8 @@ DownloadManagerImpl
 	public int[] getStorageType(DiskManagerFileInfo[] info) {
 		String[] types = DiskManagerImpl.getStorageTypes(this);
 		int[] result = new int[info.length];
-		boolean is_linear;
 		for (int i=0; i<info.length; i++) {
-			is_linear = types[info[i].getIndex()].equals("L");
-			result[i] = is_linear ? DiskManagerFileInfo.ST_LINEAR : DiskManagerFileInfo.ST_COMPACT;
+			result[i] = DiskManagerUtil.convertDMStorageTypeFromString( types[info[i].getIndex()]);
 		}
 		return result;
 	}
@@ -3798,4 +4698,10 @@ DownloadManagerImpl
 		this.renameTorrent(new_path.getName());
 	}
 
+	public void 
+	fireGlobalManagerEvent(
+		int eventType ) 
+	{
+		globalManager.fireGlobalManagerEvent( eventType, this );
+	}
 }
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerMoveHandler.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerMoveHandler.java
index a2b2aab..b78c89a 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerMoveHandler.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerMoveHandler.java
@@ -71,7 +71,7 @@ public class DownloadManagerMoveHandler extends DownloadManagerMoveHandlerUtils
 		}
 	}
 	
-	public static SaveLocationChange onCompletion(DownloadManager dm) {
+	public static SaveLocationChange onCompletion(DownloadManager dm, MoveCallback callback ) {
 		if (!isApplicableDownload(dm)) {return null;}
 		
 		if (dm.getDownloadState().getFlag(DownloadManagerState.FLAG_MOVE_ON_COMPLETION_DONE)) {
@@ -86,6 +86,14 @@ public class DownloadManagerMoveHandler extends DownloadManagerMoveHandlerUtils
 			return null;
 		}
 		
+			// give caller the opportunity to perform the action *before* we set the completion-done
+			// flag...
+		
+		if ( callback != null && sc != null ){
+			
+			callback.perform( sc );
+		}
+		
 		logInfo("Setting completion flag on " + describe(dm) + ", may have been set before.", dm);
 		dm.getDownloadState().setFlag(DownloadManagerState.FLAG_MOVE_ON_COMPLETION_DONE, true);
 		return sc;
@@ -148,4 +156,11 @@ public class DownloadManagerMoveHandler extends DownloadManagerMoveHandlerUtils
 		if (s != null && s.trim().length()!=0) {addFile(l, new File(s));}
 	}
 	
+	public interface
+	MoveCallback
+	{
+		public void
+		perform(
+			SaveLocationChange		details );
+	}
 }
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerRateController.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerRateController.java
new file mode 100644
index 0000000..e40f87d
--- /dev/null
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerRateController.java
@@ -0,0 +1,667 @@
+/*
+ * Created on May 12, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.core3.download.impl;
+
+import java.util.*;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.peer.PEPeerManagerStats;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.core3.util.SimpleTimer;
+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 com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
+import com.aelitis.azureus.core.networkmanager.NetworkManager;
+import com.aelitis.azureus.core.speedmanager.SpeedManager;
+import com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate;
+import com.aelitis.azureus.core.speedmanager.SpeedManagerPingMapper;
+
+
+public class 
+DownloadManagerRateController 
+{
+	private static AzureusCore		core;
+	private static SpeedManager		speed_manager;
+	
+	private static Map<PEPeerManager,PMState>		pm_map = new HashMap<PEPeerManager, PMState>();
+	
+	private static TimerEventPeriodic	timer;
+	
+	private static AsyncDispatcher	dispatcher = new AsyncDispatcher( "DMCRateController" );
+	
+	private static boolean	enable;
+	private static boolean 	enable_limit_handling;
+	private static int		slack_bytes_per_sec;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"Bias Upload Enable",
+				"Bias Upload Handle No Limit",
+				"Bias Upload Slack KBs",
+			},
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String parameterName) 
+				{
+					enable				 	= COConfigurationManager.getBooleanParameter( "Bias Upload Enable" );
+					enable_limit_handling 	= COConfigurationManager.getBooleanParameter( "Bias Upload Handle No Limit" ) && enable;
+					slack_bytes_per_sec		= COConfigurationManager.getIntParameter( "Bias Upload Slack KBs" )*1024;
+				}
+			});
+	}
+	
+
+	private static volatile int rate_limit	= 0;
+	
+	private static LimitedRateGroup 
+		limiter = 
+			new LimitedRateGroup()
+			{
+				public String 
+				getName()
+				{
+					return( "DMRC" );
+				}
+		
+				public int 
+				getRateLimitBytesPerSecond()
+				{
+					return( rate_limit );
+				}
+			};
+	
+	private static final int TIMER_MILLIS			= 1000;
+			
+	private static final int WAIT_AFTER_CHOKE_PERIOD	= 10*1000;
+	private static final int WAIT_AFTER_CHOKE_TICKS		= WAIT_AFTER_CHOKE_PERIOD/TIMER_MILLIS;
+
+	private static final int DEFAULT_UP_LIMIT	= 250*1024;
+	private static final int MAX_UP_DIFF	= 15*1024;
+	private static final int MAX_DOWN_DIFF	= 10*1024;
+	private static final int MIN_DIFF	= 2*1024;
+				
+	private static final int		SAMPLE_COUNT			= 5;
+	private static int				sample_num;
+	private static double			incomplete_samples;
+	private static double			complete_samples;
+	
+	private static int	ticks_to_sample_start;
+	
+	private static int		last_rate_limit;
+	private static double	last_incomplete_average;
+	private static double	last_complete_average;
+	private static double	last_overall_average;
+
+
+	
+	private static int	tick_count				= 0;
+	private static int	last_tick_processed 	= -1;
+	
+	private static long pm_last_bad_limit;
+	private static int	latest_choke;
+	private static int	wait_until_tick;
+	
+	public static String
+	getString()
+	{
+		if ( enable ){
+			
+			String	str = "reserved=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( slack_bytes_per_sec );
+			
+			if ( enable_limit_handling ){
+			
+				str += ", limit=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( rate_limit );
+				
+				str += 	", last[choke=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( latest_choke ) + 
+						", ratio=" + DisplayFormatters.formatDecimal(last_incomplete_average/last_complete_average, 2) + "]";
+			
+				return( str );
+				
+			}else{
+				
+				return( str );
+			}
+		}else{
+			
+			return( "Disabled" );
+		}
+	}
+	
+	public static void
+	addPeerManager(
+		final PEPeerManager		pm )
+	{
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					if ( core == null ){
+						
+						core = AzureusCoreFactory.getSingleton();
+						
+						speed_manager = core.getSpeedManager();
+					}
+					
+					boolean	is_complete = !pm.hasDownloadablePiece();
+					
+					PEPeerManagerStats pm_stats = pm.getStats();
+
+					long	up_bytes = pm_stats.getTotalDataBytesSentNoLan() + pm_stats.getTotalProtocolBytesSentNoLan();
+
+					if ( is_complete ){
+						
+						pm.addRateLimiter( limiter, true );
+					}
+					
+					pm_map.put( pm, new PMState( pm, is_complete, up_bytes ));
+										
+					if ( timer == null ){
+						
+						timer = 
+							SimpleTimer.addPeriodicEvent( 
+								"DMRC", 
+								TIMER_MILLIS,
+								new TimerEventPerformer()
+								{
+									public void 
+									perform(
+										TimerEvent event ) 
+									{
+										dispatcher.dispatch(
+											new AERunnable()
+											{
+												public void
+												runSupport()
+												{
+													update();
+												}
+											});
+									}
+								});
+					}
+				}
+			});
+	}
+	
+	public static void
+	removePeerManager(
+		final PEPeerManager		pm )
+	{
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					pm_map.remove( pm );
+					
+					if ( pm_map.size() == 0 ){
+						
+						timer.cancel();
+						
+						timer = null;
+						
+						rate_limit = 0;
+					}
+				}
+			});
+	}
+	
+	private static void
+	update()
+	{
+		tick_count++;
+		
+		if ( 	(!enable_limit_handling ) ||  pm_map.size() == 0 ||  
+				NetworkManager.isSeedingOnlyUploadRate() ||  NetworkManager.getMaxUploadRateBPSNormal() != 0 || 
+				core == null || speed_manager == null || speed_manager.getSpeedTester() == null ){
+			
+			rate_limit = 0;
+			
+			return;
+		}
+						
+		int	num_complete 	= 0;
+		int	num_incomplete 	= 0;
+		
+		int	num_interesting = 0;
+		
+		int i_up_total	= 0;
+		int c_up_total	= 0;
+		
+		long	mono_now = SystemTime.getMonotonousTime();
+		
+		for ( Map.Entry<PEPeerManager, PMState> entry: pm_map.entrySet()){
+			
+			PEPeerManager	pm 		= entry.getKey();
+			PMState			state 	= entry.getValue();
+			
+			boolean	is_complete = !pm.hasDownloadablePiece();
+			
+			PEPeerManagerStats pm_stats = pm.getStats();
+	
+			long	up_bytes = pm_stats.getTotalDataBytesSentNoLan() + pm_stats.getTotalProtocolBytesSentNoLan();
+						
+			long	diff = state.setBytesUp( up_bytes );
+			
+			if ( is_complete ){
+								
+				num_complete++;
+				
+				c_up_total += diff;
+				
+			}else{
+								
+				num_incomplete++;
+				
+				i_up_total += diff;
+				
+				if ( state.isInteresting( mono_now )){
+					
+					num_interesting++;
+				}
+			}
+				
+			if ( state.isComplete() != is_complete ){
+			
+				if ( is_complete ){
+					
+					pm.addRateLimiter( limiter, true );
+					
+				}else{
+					
+					pm.removeRateLimiter( limiter, true );
+				}
+				
+				state.setComplete( is_complete );
+			}
+		}
+		
+		if ( num_incomplete == 0 || num_complete == 0 || num_interesting == 0 ){
+			
+			rate_limit = 0;
+			
+			return;
+		}
+		
+		boolean	skipped_tick = false;
+		
+		if ( last_tick_processed != tick_count - 1 ){
+						
+			pm_last_bad_limit 	= 0;
+			latest_choke		= 0;
+			wait_until_tick		= 0;
+
+			ticks_to_sample_start	= 0;
+			sample_num				= 0;
+			incomplete_samples		= 0;
+			complete_samples		= 0;
+			
+			skipped_tick = true;
+		}
+		
+		last_tick_processed = tick_count;
+		
+		if ( skipped_tick || tick_count < wait_until_tick ){
+			
+			return;
+		}
+		
+		try{
+			long	real_now = SystemTime.getCurrentTime();
+			
+			SpeedManagerPingMapper mapper = speed_manager.getActiveMapper();
+			
+			if ( rate_limit == 0 ){
+				
+				rate_limit = speed_manager.getEstimatedUploadCapacityBytesPerSec().getBytesPerSec();
+				
+				if ( rate_limit == 0 ){
+					
+					rate_limit = DEFAULT_UP_LIMIT;
+				}
+			}
+			
+			SpeedManagerLimitEstimate last_bad = mapper.getLastBadUploadLimit();
+						
+			if ( last_bad != null ){
+				
+				int last_bad_limit = last_bad.getBytesPerSec();
+								
+				if ( last_bad_limit != pm_last_bad_limit ){
+					
+					pm_last_bad_limit = last_bad_limit;
+			
+					SpeedManagerLimitEstimate[] bad_ups = mapper.getBadUploadHistory();
+		
+					int		total 	= last_bad.getBytesPerSec();
+					int		count	= 1;
+					
+					for ( SpeedManagerLimitEstimate bad: bad_ups ){
+						
+						long	t = bad.getWhen();
+						
+						if ( real_now - t <= 30*1000 && bad.getBytesPerSec() != last_bad_limit ){
+							
+							total += bad.getBytesPerSec();
+							
+							count++;
+						}
+					}
+					
+					latest_choke = total/count;
+						
+					int	new_rate_limit;
+					
+					if ( rate_limit == 0 ){
+						
+						new_rate_limit = latest_choke/2;
+						
+					}else{
+						
+						new_rate_limit = rate_limit/2;
+					}
+					
+					if ( new_rate_limit < slack_bytes_per_sec ){
+						
+						new_rate_limit = slack_bytes_per_sec;
+					}
+					
+					rate_limit = new_rate_limit;
+					
+					wait_until_tick = tick_count + WAIT_AFTER_CHOKE_TICKS;
+					
+					ticks_to_sample_start 	= 0;
+					sample_num 				= 0;
+					complete_samples		= 0;
+					incomplete_samples		= 0;
+					last_rate_limit			= 0;
+					
+					return;
+				}
+			}
+			
+			if ( ticks_to_sample_start > 0 ){
+				
+				ticks_to_sample_start--;
+				
+			}else if ( sample_num < SAMPLE_COUNT ){
+				
+				complete_samples 	+= c_up_total;
+				incomplete_samples	+= i_up_total;
+				
+				sample_num++;
+				
+			}else{
+					
+				double	incomplete_average 	= incomplete_samples / SAMPLE_COUNT;
+				double	complete_average 	= complete_samples / SAMPLE_COUNT;
+				double	overall_average 	= ( complete_samples + incomplete_samples ) / SAMPLE_COUNT;
+				
+				int	action = -1;
+
+				try{
+					
+					if ( last_rate_limit == 0 ){
+						
+						action = 1;
+						
+					}else{
+						
+						double overall_change = overall_average - last_overall_average;
+						
+						if ( overall_change < 0 ){
+														
+							if ( rate_limit < last_rate_limit ){
+							
+								// System.out.println( "average decreased" );
+
+								action = 1;
+								
+							}else{
+								
+								action = 0;
+							}
+						}else{
+							
+							double last_ratio 	= last_incomplete_average / last_complete_average;
+							double ratio		= incomplete_average / complete_average;
+							
+							// System.out.println( "rate=" + rate_limit + "/" + last_rate_limit + ", ratio=" + ratio + "/" + last_ratio );
+							
+							if ( rate_limit < last_rate_limit && ratio >= last_ratio ){
+								
+								action = -1;
+								
+							}else if ( rate_limit > last_rate_limit && ratio <= last_ratio ){
+								
+								double i_up_change = incomplete_average - last_incomplete_average;
+								
+								if ( i_up_change >= 1024 ){
+								
+									action = -1;
+									
+								}else{
+									
+									action = 1;
+								}
+								
+							}else{
+								
+								action = 1;
+							}
+						}
+					}
+					
+				}finally{
+															
+					int	new_rate_limit;
+
+					if ( action > 0 ){
+						
+						int	ceiling = latest_choke==0?DEFAULT_UP_LIMIT:latest_choke;
+						
+						int	diff = ( ceiling - rate_limit )/4;
+
+						if ( diff > MAX_UP_DIFF ){
+							
+							diff = MAX_UP_DIFF;
+							
+						}else if ( diff < MIN_DIFF ){
+							
+							diff = MIN_DIFF;
+						}
+
+						new_rate_limit = rate_limit + diff;
+						
+						if ( new_rate_limit > 100*1024*1024 ){
+							
+							new_rate_limit = 100*1024*1024;
+						}
+					}else if ( action < 0 ){
+						
+						int	diff = rate_limit/5;
+
+						if ( diff > MAX_DOWN_DIFF ){
+							
+							diff = MAX_DOWN_DIFF;
+							
+						}else if ( diff < MIN_DIFF ){
+							
+							diff = MIN_DIFF;
+						}
+
+						new_rate_limit = rate_limit - diff;
+						
+						if ( new_rate_limit < slack_bytes_per_sec ){
+							
+							new_rate_limit = slack_bytes_per_sec;
+						}
+					}else{
+						
+						new_rate_limit = rate_limit;
+					}
+					
+					last_rate_limit			= rate_limit;
+					last_overall_average 	= overall_average;
+					last_complete_average	= complete_average;
+					last_incomplete_average	= incomplete_average;
+					
+					rate_limit = new_rate_limit;
+					
+					sample_num = 0;
+					complete_samples	= 0;
+					incomplete_samples	= 0;
+				}
+			}
+	
+		}finally{
+			
+			// System.out.println( "rate=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( rate_limit ) + ", last_choke=" + latest_choke );
+		}
+	}
+	
+	private static class
+	PMState
+	{
+		final private PEPeerManager	manager;
+		
+		private boolean			complete;
+		private long			bytes_up;
+		
+		private boolean			interesting;
+		private long			last_interesting_calc;
+		
+		private
+		PMState(
+			PEPeerManager	_manager,
+			boolean			_complete,
+			long			_bytes_up )
+		{
+			manager		= _manager;
+			complete 	= _complete;
+			bytes_up	= _bytes_up;
+		}
+		
+		private boolean
+		isComplete()
+		{
+			return( complete );
+		}
+		
+		private void
+		setComplete(
+			boolean	c )
+		{
+			complete = c;
+		}
+		
+		private long
+		setBytesUp(
+			long	b )
+		{
+			long diff = b - bytes_up;
+			
+			bytes_up = b;
+			
+			return( diff );
+		}
+		
+		private boolean
+		isInteresting(
+			long		now )
+		{
+			boolean	calc;
+					
+			if ( last_interesting_calc == 0 ){
+		
+				calc = true;
+				
+			}else if ( !interesting ){
+				
+				calc = now - last_interesting_calc >= 5*1000;
+				
+			}else{
+				
+				calc = now - last_interesting_calc >= 60*1000;
+			}
+			
+			if ( calc ){
+				
+				last_interesting_calc = now;
+				
+				PEPeerManagerStats stats = manager.getStats();
+				
+					// not interesting if stalled downloading
+				
+				long dl_rate = stats.getDataReceiveRate();
+				
+				if ( dl_rate < 5*1024 ){
+					
+					interesting = false;
+					
+				}else{
+					
+						// not interesting if we have nobody to seed to!
+					
+					if ( manager.getNbPeersUnchoked() < 3 ){
+						
+						interesting = false;
+						
+					}else{
+						
+							// see if the download has a manually imposed upload limit and if
+							// we are close to it
+						
+						int limit = manager.getUploadRateLimitBytesPerSecond();
+						
+						if ( 	limit > 0 &&
+								( stats.getDataSendRate() + stats.getProtocolSendRate() ) >= ( limit - (5*1024))){
+							
+							interesting = false;
+							
+						}else{
+							
+							interesting = true;
+						}
+					}
+				}
+			}
+			
+			return( interesting );
+		}
+	}
+}
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
index 05aa6c5..0f3cca1 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerStateImpl.java
@@ -23,8 +23,10 @@
 package org.gudy.azureus2.core3.download.impl;
 
 import java.io.*;
+import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.GZIPOutputStream;
 
@@ -35,6 +37,8 @@ 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.*;
+import org.gudy.azureus2.core3.ipfilter.IpFilterManager;
+import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
 import org.gudy.azureus2.core3.logging.LogRelation;
@@ -133,8 +137,6 @@ DownloadManagerStateImpl
 	
 	private AEMonitor	this_mon	= new AEMonitor( "DownloadManagerState" );
 	
-	private boolean firstPrimaryFileRead = true;
-	
 	private int supressWrites = 0;
 
 	private static ThreadLocal		tls_wbr	= 
@@ -146,7 +148,7 @@ DownloadManagerStateImpl
 				return( new ArrayList(1));
 			}
 		};
-
+		
 	private static DownloadManagerState
 	getDownloadState(
 		DownloadManagerImpl				download_manager,
@@ -526,6 +528,19 @@ DownloadManagerStateImpl
         	}
         }
         
+        long flags = getFlags();
+        
+        if (( flags & FLAG_DISABLE_IP_FILTER ) != 0 ){
+        	
+        	try{
+        		IpFilterManagerFactory.getSingleton().getIPFilter().addExcludedHash( torrent.getHash());
+        		
+        	}catch( Throwable e ){
+        		
+        		Debug.out( e );
+        	}
+        }
+        
         if ( version < VER_CURRENT ){
         	
         	setIntAttribute( AT_VERSION, VER_CURRENT );
@@ -869,6 +884,24 @@ DownloadManagerStateImpl
 		if ( old_value != new_value ){
 			
 			setLongAttribute( AT_FLAGS, new_value );
+			
+			if (( old_value & FLAG_DISABLE_IP_FILTER ) != ( new_value & FLAG_DISABLE_IP_FILTER )){
+		      
+	        	try{
+	        		if (( new_value & FLAG_DISABLE_IP_FILTER ) != 0 ){
+	        		
+	        			IpFilterManagerFactory.getSingleton().getIPFilter().addExcludedHash( torrent.getHash());
+	        			
+	        		}else{
+	        			
+	        			IpFilterManagerFactory.getSingleton().getIPFilter().removeExcludedHash( torrent.getHash());
+
+	        		}
+	        	}catch( Throwable e ){
+	        		
+	        		Debug.out( e );
+	        	}
+	        }
 		}
 	}
 	
@@ -1156,19 +1189,16 @@ DownloadManagerStateImpl
 	setCategory(
 		Category 	cat ) 
 	{
-		if ( cat == CategoryManager.getCategory(Category.TYPE_UNCATEGORIZED)){
-			
-			cat	= null;
-		}
-		
 		if ( cat == category ){
-			
 			return;
 		}
 	  
 		if (cat != null && cat.getType() != Category.TYPE_USER){
 	    
 			cat = null;
+			if (cat == category) {
+				return;
+			}
 		}
 		
 		Category oldCategory = (category == null)?CategoryManager.getCategory(Category.TYPE_UNCATEGORIZED):category;
@@ -1183,9 +1213,13 @@ DownloadManagerStateImpl
 		if (category != null ){
 			
 			category.addManager( this );
+
+		} else {
+
+			CategoryManager.getCategory(Category.TYPE_UNCATEGORIZED).addManager(this);
 		}
   	
-		if ( category != null && category.getType() == Category.TYPE_USER ){
+		if ( category != null ){
 			
 			setStringAttribute( AT_CATEGORY, category.getName());
 			
@@ -1228,16 +1262,15 @@ DownloadManagerStateImpl
     	return this.getStringAttribute(AT_RELATIVE_SAVE_PATH);
     }
 	
-	public String getPrimaryFile() {
-		String sPrimary = this.getStringAttribute(AT_PRIMARY_FILE);
-		// Only recheck when file doesn't exists if this is the first check
-		// of the session, because the file may never exist and we don't want
-		// to continuously go through the fileinfos
-		if (sPrimary == null
-				|| sPrimary.length() == 0
-				|| (firstPrimaryFileRead && !new File(sPrimary).exists() 
-						&& download_manager.getStats().getDownloadCompleted(true) != 0)) {
-			DiskManagerFileInfo[] fileInfo = download_manager.getDiskManagerFileInfo();
+	public DiskManagerFileInfo getPrimaryFile() {
+		int primaryIndex = -1;
+		DiskManagerFileInfo[] fileInfo = download_manager.getDiskManagerFileInfoSet().getFiles();
+		if (hasAttribute(AT_PRIMARY_FILE_IDX)) {
+			primaryIndex = getIntAttribute(AT_PRIMARY_FILE_IDX);
+		}
+		
+		if (primaryIndex < 0 || primaryIndex >= fileInfo.length) {
+			primaryIndex = -1;
 			if (fileInfo.length > 0) {
 				int idxBiggest = -1;
 				long lBiggest = -1;
@@ -1252,28 +1285,25 @@ DownloadManagerStateImpl
 					}
 				}
 				if (idxBiggest >= 0) {
-					sPrimary = fileInfo[idxBiggest].getFile(true).getPath();
+					primaryIndex = idxBiggest;
 				}
 			}
-			// System.out.println("calc getPrimaryFile " + sPrimary + ": " + download_manager.getDisplayName());
+			if (primaryIndex >= 0) {
+				setPrimaryFile(fileInfo[primaryIndex]);
+			}
 		}
 
-		if (sPrimary == null) {
-			sPrimary = "";
-		}
-		
-		if (firstPrimaryFileRead) {
-			firstPrimaryFileRead = false;
+		if (primaryIndex >= 0) {
+			return fileInfo[primaryIndex];
 		}
-		setPrimaryFile(sPrimary);
-		return sPrimary;
+		return null;
 	}
     
 	/**
 	 * @param primary
 	 */
-	public void setPrimaryFile(String fileFullPath) {
-		this.setStringAttribute(AT_PRIMARY_FILE, fileFullPath);
+	public void setPrimaryFile(DiskManagerFileInfo dmfi) {
+		setIntAttribute(AT_PRIMARY_FILE_IDX, dmfi.getIndex());
 	}
 
 	public String[]
@@ -1543,6 +1573,8 @@ DownloadManagerStateImpl
 	  
 	  // links stuff
 	  
+	private volatile WeakReference<CaseSensitiveFileMap>	file_link_cache 	= null;
+	private int												file_cache_inhibit 	= 0;
 	
 	public void
 	setFileLink(
@@ -1580,7 +1612,23 @@ DownloadManagerStateImpl
 			list.add( str );
 		}
 		
-		setListAttribute( AT_FILE_LINKS, list );
+		try{
+			synchronized( this ){
+				
+				file_cache_inhibit++;
+		
+				file_link_cache = null;		// ensure write-listeners get recent state
+			}
+			
+			setListAttribute( AT_FILE_LINKS, list );
+			
+		}finally{
+			
+			synchronized( this ){
+				
+				file_cache_inhibit--;
+			}
+		}
 	}
 	
 	public void
@@ -1611,7 +1659,23 @@ DownloadManagerStateImpl
 		
 		if ( changed ){
 	
-			setListAttribute( AT_FILE_LINKS, list );
+			try{
+				synchronized( this ){
+					
+					file_cache_inhibit++;
+			
+					file_link_cache = null;		// ensure write-listeners get recent state
+				}
+							
+				setListAttribute( AT_FILE_LINKS, list );
+			
+			}finally{
+				
+				synchronized( this ){
+					
+					file_cache_inhibit--;
+				}
+			}
 		}
 	}
 	
@@ -1619,7 +1683,29 @@ DownloadManagerStateImpl
 	getFileLink(
 		File	link_source )
 	{
-		return((File)getFileLinks().get(link_source));
+		CaseSensitiveFileMap map = null;
+		
+		WeakReference<CaseSensitiveFileMap> ref = file_link_cache;
+		
+		if ( ref != null ){
+			
+			map = ref.get();
+		}
+		
+		if ( map == null ){
+					
+			map = getFileLinks();
+			
+			synchronized( this ){
+				
+				if ( file_cache_inhibit == 0 ){
+				
+					file_link_cache = new WeakReference<CaseSensitiveFileMap>( map );
+				}
+			}
+		}
+		
+		return((File)map.get(link_source));
 	}
 					
 	public CaseSensitiveFileMap
@@ -2305,7 +2391,10 @@ DownloadManagerStateImpl
 			
 			writer.println( "parameters=" + parameters );
 			
-			writer.println("primary file=" + Debug.secretFileName(getPrimaryFile()));
+			DiskManagerFileInfo primaryFile = getPrimaryFile();
+			if (primaryFile != null) {
+				writer.println("primary file=" + Debug.secretFileName(primaryFile.getFile(true).getAbsolutePath()));
+			}
 			
 		}finally{
 			
@@ -2672,15 +2761,13 @@ DownloadManagerStateImpl
 		}
 
 		// @see org.gudy.azureus2.core3.download.DownloadManagerState#getPrimaryFile()
-		
-		public String getPrimaryFile() {
+		public DiskManagerFileInfo getPrimaryFile() {
 			// TODO Auto-generated method stub
 			return null;
 		}
-
-		// @see org.gudy.azureus2.core3.download.DownloadManagerState#setPrimaryFile(java.lang.String)
 		
-		public void setPrimaryFile(String relativeFile) {
+		// @see org.gudy.azureus2.core3.download.DownloadManagerState#setPrimaryFile(org.gudy.azureus2.core3.disk.DiskManagerFileInfo)
+		public void setPrimaryFile(DiskManagerFileInfo dmfi) {
 			// TODO Auto-generated method stub
 			
 		}
@@ -2794,6 +2881,7 @@ DownloadManagerStateImpl
 			
 			cache.put( "hash", state.getHash());
 			cache.put( "name", state.getName());
+			cache.put( "utf8name", state.getUTF8Name() == null ? "" : state.getUTF8Name());
 			cache.put( "comment", state.getComment());
 			cache.put( "createdby", state.getCreatedBy());
 			cache.put( "size", new Long( state.getSize()));
@@ -2927,7 +3015,10 @@ DownloadManagerStateImpl
 				
 				if ( realSets.length != sets.length ){
 					
-					Debug.out("Cached announce group state does not match real state");
+					// not a major issue - since we now allow the cached groups and persisted ones to
+					// drift (see DNS changes) the cached ones will be accurate and the persisted ones
+					// will be re-adjusted should they become visible
+					// Debug.out("Cached announce group state does not match real state");
 					
 				}else{
 				
@@ -3197,6 +3288,32 @@ DownloadManagerStateImpl
 	   		return(("Error - " + Debug.getNestedExceptionMessage( fixup_failure )).getBytes());
     	}
 
+		public String getUTF8Name() {
+			Map	c = cache;
+			
+			if ( c != null ){
+
+				byte[] name = (byte[])c.get( "utf8name" );
+				if (name != null) {
+					String utf8name;
+					try {
+						utf8name = new String(name, "utf8");
+					} catch (UnsupportedEncodingException e) {
+						return null;
+					}
+					if (utf8name.length() == 0) {
+						return null;
+					}
+					return utf8name;
+				}
+			}
+
+			if (fixup()) {
+				return delegate.getUTF8Name();
+			}
+			return null;
+		}
+
     	public boolean
     	isSimpleTorrent()
     	{
@@ -3305,6 +3422,12 @@ DownloadManagerStateImpl
 	   		return( false );
     	}
     	
+    	public boolean 
+    	isDecentralised() 
+    	{
+    		return( TorrentUtils.isDecentralised( getAnnounceURL()));
+    	}
+    	
     	public URL
     	getAnnounceURL()
        	{
@@ -3764,6 +3887,26 @@ DownloadManagerStateImpl
    	   		throw( fixup_failure );
        	}
 
+       public void
+       addListener(
+    	  TOTorrentListener		l )
+       {
+    	   if ( fixup()){
+    		   
+    		   delegate.addListener( l );
+    	   }
+       }
+       
+       public void
+       removeListener(
+    	  TOTorrentListener		l )
+       {
+    	   if ( fixup()){
+    		   
+    		   delegate.removeListener( l );
+    	   }
+       }
+       
        public AEMonitor
        getMonitor()
       	{
diff --git a/org/gudy/azureus2/core3/download/impl/DownloadManagerStatsImpl.java b/org/gudy/azureus2/core3/download/impl/DownloadManagerStatsImpl.java
index 4a0692f..a4304ae 100644
--- a/org/gudy/azureus2/core3/download/impl/DownloadManagerStatsImpl.java
+++ b/org/gudy/azureus2/core3/download/impl/DownloadManagerStatsImpl.java
@@ -231,10 +231,18 @@ DownloadManagerStatsImpl
 	public long 
 	getTimeStarted() 
 	{
+		return( getTimeStarted( false ));
+	}
+	
+	private long 
+	getTimeStarted(
+		boolean mono ) 
+	{
 		PEPeerManager	pm = download_manager.getPeerManager();
 		
-		if (pm != null){
-			return pm.getTimeStarted();
+		if ( pm != null ){
+			
+			return pm.getTimeStarted( mono );
 		}
 		
 		return -1;
@@ -243,11 +251,18 @@ DownloadManagerStatsImpl
 	public long 
 	getTimeStartedSeeding() 
 	{
+		return( getTimeStartedSeeding( false ));
+	}
+	
+	private long 
+	getTimeStartedSeeding(
+		boolean mono ) 
+	{
 		PEPeerManager	pm = download_manager.getPeerManager();
 		
 		if (pm != null){
 		 
-			return pm.getTimeStartedSeeding();
+			return( pm.getTimeStartedSeeding( mono ));
 		}
 		
 		return -1;
@@ -292,6 +307,37 @@ DownloadManagerStatsImpl
 		return(saved_protocol_bytes_downloaded);
 	} 
   
+	public void 
+	resetTotalBytesSentReceived(
+		long 	new_sent,
+		long	new_received )
+	{
+		boolean running = download_manager.getPeerManager() != null;
+		
+		if ( running ){
+			
+			download_manager.stopIt( DownloadManager.STATE_STOPPED, false, false );
+		}
+		
+		
+		if ( new_sent >= 0 ){
+			
+			saved_data_bytes_uploaded		= new_sent;
+			saved_protocol_bytes_uploaded	= 0;
+		}
+		
+		if ( new_received >= 0 ){
+			
+			saved_data_bytes_downloaded			= new_received;
+			saved_protocol_bytes_downloaded		= 0;
+		}
+
+		if ( running ){
+			
+			download_manager.setStateWaiting();
+		}
+	}
+	
 	public long 
 	getTotalDataBytesSent() 
 	{
@@ -424,11 +470,11 @@ DownloadManagerStatsImpl
 	public long 
 	getSecondsDownloading() 
 	{
-	  long lTimeStartedDL = getTimeStarted();
+	  long lTimeStartedDL = getTimeStarted( true );
 	  if (lTimeStartedDL >= 0) {
-  	  long lTimeEndedDL = getTimeStartedSeeding();
+  	  long lTimeEndedDL = getTimeStartedSeeding( true );
   	  if (lTimeEndedDL == -1) {
-  	    lTimeEndedDL = SystemTime.getCurrentTime();
+  	    lTimeEndedDL = SystemTime.getMonotonousTime();
   	  }
   	  if (lTimeEndedDL > lTimeStartedDL) {
     	  return saved_SecondsDownloading + ((lTimeEndedDL - lTimeStartedDL) / 1000);
@@ -440,10 +486,10 @@ DownloadManagerStatsImpl
 	public long 
 	getSecondsOnlySeeding() 
 	{
-	  long lTimeStarted = getTimeStartedSeeding();
+	  long lTimeStarted = getTimeStartedSeeding( true );
 	  if (lTimeStarted >= 0) {
 	    return saved_SecondsOnlySeeding + 
-	           ((SystemTime.getCurrentTime() - lTimeStarted) / 1000);
+	           ((SystemTime.getMonotonousTime() - lTimeStarted) / 1000);
 	  }
 	  return saved_SecondsOnlySeeding;
 	}
@@ -514,7 +560,7 @@ DownloadManagerStatsImpl
 					
 					long	now = SystemTime.getCurrentTime();
 					
-					long	elapsed = now - pm.getTimeStarted();
+					long	elapsed = now - pm.getTimeStarted( false );
 					
 					if ( elapsed < 0 ){
 						
@@ -555,7 +601,7 @@ DownloadManagerStatsImpl
 					
 					long	now = SystemTime.getCurrentTime();
 					
-					long	elapsed = now - pm.getTimeStarted();
+					long	elapsed = now - pm.getTimeStarted( false );
 					
 					if ( elapsed < 0 ){
 						
@@ -674,6 +720,8 @@ DownloadManagerStatsImpl
 				+ "],dl_comp=" + downloadCompleted
 				+ ",remaining=" + getRemaining());
 	
+			writer.println( "down_lim=" + getDownloadRateLimitBytesPerSecond() +
+							",up_lim=" + getUploadRateLimitBytesPerSecond());
 		}finally{
 			
 			writer.exdent();
diff --git a/org/gudy/azureus2/core3/global/GlobalManager.java b/org/gudy/azureus2/core3/global/GlobalManager.java
index f1991d0..2a9f27a 100644
--- a/org/gudy/azureus2/core3/global/GlobalManager.java
+++ b/org/gudy/azureus2/core3/global/GlobalManager.java
@@ -22,6 +22,7 @@
 package org.gudy.azureus2.core3.global;
 
 import java.util.List;
+import java.util.Map;
 
 import com.aelitis.azureus.core.AzureusCoreComponent;
 
@@ -133,7 +134,7 @@ public interface GlobalManager extends AzureusCoreComponent {
 	 * Retrieve a list of {@link DownloadManager}s that GlobalManager is handling
 	 * @return a list of {@link DownloadManager}s
 	 */
-	public List getDownloadManagers();
+	public List<DownloadManager> getDownloadManagers();
 
 	/**
 	 * Retrieve the DownloadManager associated with a TOTorrent object
@@ -220,6 +221,10 @@ public interface GlobalManager extends AzureusCoreComponent {
 	 */
 	public void resumeDownload(DownloadManager dm);
 
+	public void 
+	clearNonPersistentDownloadState(
+		byte[] hash );
+	
 	/**
 	 * Retrieve whether a DownloadManager is in a paused state
 	 * 
@@ -370,6 +375,19 @@ public interface GlobalManager extends AzureusCoreComponent {
 	removeDownloadManagerInitialisationAdapter(
 		DownloadManagerInitialisationAdapter	adapter );
 
+	public void
+	addEventListener(
+		GlobalManagerEventListener 		listener );
+	
+	public void
+	removeEventListener(
+		GlobalManagerEventListener 		listener );
+
+	public void 
+	fireGlobalManagerEvent(
+		int					type, 
+		DownloadManager 	param );
+	
 	/**
 	 * @param listener
 	 */
@@ -407,6 +425,11 @@ public interface GlobalManager extends AzureusCoreComponent {
 	 */
 	MainlineDHTProvider getMainlineDHTProvider();
 
+	public void 
+	statsRequest(
+		Map 		request,
+		Map			reply );
+
 	/**
 	 * @param manager
 	 * @return
@@ -414,4 +437,7 @@ public interface GlobalManager extends AzureusCoreComponent {
 	 * @since 4.0.0.5
 	 */
 	boolean contains(DownloadManager manager);
+	
+	public void
+	saveState();
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/global/GlobalManagerEvent.java b/org/gudy/azureus2/core3/global/GlobalManagerEvent.java
new file mode 100644
index 0000000..bff7a60
--- /dev/null
+++ b/org/gudy/azureus2/core3/global/GlobalManagerEvent.java
@@ -0,0 +1,36 @@
+/*
+ * Created on Jul 6, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.core3.global;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+
+public interface 
+GlobalManagerEvent 
+{
+	public static final int ET_REQUEST_ATTENTION = 1;
+	
+	public int	
+	getEventType();
+	
+	public DownloadManager
+	getDownload();
+}
diff --git a/org/gudy/azureus2/core3/global/GlobalManagerEventListener.java b/org/gudy/azureus2/core3/global/GlobalManagerEventListener.java
new file mode 100644
index 0000000..9121ff9
--- /dev/null
+++ b/org/gudy/azureus2/core3/global/GlobalManagerEventListener.java
@@ -0,0 +1,30 @@
+/*
+ * Created on Jul 6, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.core3.global;
+
+public interface 
+GlobalManagerEventListener 
+{
+	public void
+	eventOccurred(
+		GlobalManagerEvent		event );
+}
diff --git a/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java b/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
index ac89054..f4c68f6 100644
--- a/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
+++ b/org/gudy/azureus2/core3/global/impl/GlobalManagerImpl.java
@@ -29,12 +29,14 @@ package org.gudy.azureus2.core3.global.impl;
 import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
 import java.net.URL;
 import java.util.*;
 
 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.config.impl.TransferSpeedValidator;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.*;
 import org.gudy.azureus2.core3.download.impl.DownloadManagerAdapter;
@@ -52,8 +54,13 @@ import org.gudy.azureus2.core3.tracker.util.TRTrackerUtilsListener;
 import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.helpers.TorrentFolderWatcher;
+import com.aelitis.azureus.core.networkmanager.NetworkManager;
+import com.aelitis.azureus.core.networkmanager.impl.tcp.TCPNetworkManager;
 import com.aelitis.azureus.core.peermanager.control.PeerControlSchedulerFactory;
+import com.aelitis.azureus.core.speedmanager.SpeedManager;
+import com.aelitis.azureus.core.speedmanager.impl.SpeedManagerImpl;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 
 import org.gudy.azureus2.plugins.network.ConnectionManager;
@@ -80,8 +87,9 @@ public class GlobalManagerImpl
 	private static final int LDT_DESTROY_INITIATED		= 3;
 	private static final int LDT_DESTROYED				= 4;
     private static final int LDT_SEEDING_ONLY           = 5;
+    private static final int LDT_EVENT		            = 6;
 	
-	private ListenerManager	listeners 	= ListenerManager.createAsyncManager(
+	private ListenerManager	listeners_and_event_listeners 	= ListenerManager.createAsyncManager(
 		"GM:ListenDispatcher",
 		new ListenerManagerDispatcher()
 		{
@@ -91,30 +99,42 @@ public class GlobalManagerImpl
 				int			type,
 				Object		value )
 			{
-				GlobalManagerListener	target = (GlobalManagerListener)_listener;
-		
-				if ( type == LDT_MANAGER_ADDED ){
-					
-					target.downloadManagerAdded((DownloadManager)value);
-					
-				}else if ( type == LDT_MANAGER_REMOVED ){
-					
-					target.downloadManagerRemoved((DownloadManager)value);
-					
-				}else if ( type == LDT_DESTROY_INITIATED ){
-					
-					target.destroyInitiated();
+				if ( type == LDT_EVENT ){
 					
-				}else if ( type == LDT_DESTROYED ){
+					if ( _listener instanceof GlobalManagerEventListener ){
 					
-					target.destroyed();
-                    
-				}else if ( type == LDT_SEEDING_ONLY ){
-                    
-					boolean	[] temp = (boolean[])value;
+						((GlobalManagerEventListener)_listener ).eventOccurred( (GlobalManagerEvent)value );
+					}	
+				}else{
 					
-                    target.seedingStatusChanged( temp[0], temp[1] );
-                }
+					if ( _listener instanceof GlobalManagerListener ){
+						
+						GlobalManagerListener	target = (GlobalManagerListener)_listener;
+				
+						if ( type == LDT_MANAGER_ADDED ){
+							
+							target.downloadManagerAdded((DownloadManager)value);
+							
+						}else if ( type == LDT_MANAGER_REMOVED ){
+							
+							target.downloadManagerRemoved((DownloadManager)value);
+							
+						}else if ( type == LDT_DESTROY_INITIATED ){
+							
+							target.destroyInitiated();
+							
+						}else if ( type == LDT_DESTROYED ){
+							
+							target.destroyed();
+		                    
+						}else if ( type == LDT_SEEDING_ONLY ){
+		                    
+							boolean	[] temp = (boolean[])value;
+							
+		                    target.seedingStatusChanged( temp[0], temp[1] );
+		                }
+					}
+				}
 			}
 		});
 	
@@ -191,6 +211,7 @@ public class GlobalManagerImpl
 	
 	private boolean	force_start_non_seed_exists;
 	private int 	nat_status				= ConnectionManager.NAT_UNKNOWN;
+	private long	nat_status_last_good	= -1;
 	private boolean	nat_status_probably_ok;
 		
    private CopyOnWriteList	dm_adapters = new CopyOnWriteList();
@@ -216,6 +237,7 @@ public class GlobalManagerImpl
     private int initSaveResumeLoopCount = 60*1000 / waitTime;
     private int natCheckLoopCount		= 30*1000 / waitTime;
     private int seedPieceCheckCount		= 30*1000 / waitTime;
+    private int oneMinuteThingCount		= 60*1000 / waitTime;
            
     private AESemaphore	run_sem = new AESemaphore( "GM:Checker:run");
     
@@ -269,20 +291,35 @@ public class GlobalManagerImpl
 	        	seedPieceRecheck();
 	        }
 	        
-	        for (Iterator it=managers_cow.iterator();it.hasNext();) {
-          	
-	        	DownloadManager manager = (DownloadManager)it.next();
-            
-	        	if ( loopFactor % saveResumeLoopCount == 0 ) {
-	        		
-	        		manager.saveResumeData();
-	        	}
+        	if ( loopFactor % saveResumeLoopCount == 0 ) {
+
+		        for (Iterator it=managers_cow.iterator();it.hasNext();) {
+	          	
+		        	DownloadManager manager = (DownloadManager)it.next();
+	            
+		        		
+		        	manager.saveResumeData();
+		       	}
 	        	
 		            /*
 		             * seeding rules have been moved to StartStopRulesDefaultPlugin
 		             */
-	        }        
-
+	        }  
+        	
+        	if ( loopFactor % oneMinuteThingCount == 0 ) {
+        		
+        		try{
+	        		if ( !HttpURLConnection.getFollowRedirects()){
+	        			
+	        			Debug.outNoStack( "Something has set global 'follow redirects' to false!!!!" );
+	        			
+	        			HttpURLConnection.setFollowRedirects( true );
+	        		}
+        		}catch( Throwable e ){
+        			
+        			Debug.out( e );
+        		}
+        	}
       	}catch( Throwable e ){
       		
       		Debug.printStackTrace( e );
@@ -547,6 +584,30 @@ public class GlobalManagerImpl
 				}
     		}
     	});
+    
+    TorrentUtils.addTorrentURLChangeListener(
+    	new TorrentUtils.TorrentAnnounceURLChangeListener()
+    	{
+    		public void
+    		changed()
+    		{
+				Logger.log( new LogEvent(LOGID, "Announce URL details have changed, updating trackers" ));
+
+				List	managers = managers_cow;
+				
+				for (int i=0;i<managers.size();i++){
+					
+					DownloadManager	manager = (DownloadManager)managers.get(i);
+					
+					TRTrackerAnnouncer client = manager.getTrackerClient();
+					
+					if ( client != null ){
+						
+						client.resetTrackerUrl( false );
+					}
+				}
+    		}
+    	});
   }
   
   public void loadExistingTorrentsNow(boolean async)
@@ -793,7 +854,12 @@ public class GlobalManagerImpl
 		return manager;
 	}
 
-
+	public void 
+	clearNonPersistentDownloadState(
+		byte[] hash )
+	{
+		saved_download_manager_state.remove( new HashWrapper( hash ));
+	}
 
    protected DownloadManager 
    addDownloadManager(
@@ -812,7 +878,7 @@ public class GlobalManagerImpl
       	
         if (existing_index != -1) {
         	
-        	DownloadManager existing = (DownloadManager)managers_cow.get(existing_index);
+        	DownloadManager existing = managers_cow.get(existing_index);
                 	
         	download_manager.destroy( true );
         	
@@ -822,10 +888,16 @@ public class GlobalManagerImpl
         DownloadManagerStats dm_stats = download_manager.getStats();
 
         HashWrapper hashwrapper = null;
-				try {
-					hashwrapper = download_manager.getTorrent().getHashWrapper();
-				} catch (Exception e1) { }
-				
+        
+        try{
+        	TOTorrent torrent = download_manager.getTorrent();
+        	
+        	if ( torrent != null ){
+        	
+        		hashwrapper = torrent.getHashWrapper();
+        	}
+        } catch (Exception e1) { }
+
         Map	save_download_state	= (Map)saved_download_manager_state.get(hashwrapper);
         
       	long saved_data_bytes_downloaded	= 0;
@@ -1000,7 +1072,7 @@ public class GlobalManagerImpl
         if (download_manager.getPosition() == -1) {
 	        int endPosition = 0;
 	        for (int i = 0; i < managers_cow.size(); i++) {
-	          DownloadManager dm = (DownloadManager) managers_cow.get(i);
+	          DownloadManager dm = managers_cow.get(i);
 	          boolean dmIsCompleted = dm.isDownloadComplete(false);
 	          if (dmIsCompleted == isCompleted)
 	            endPosition++;
@@ -1015,7 +1087,7 @@ public class GlobalManagerImpl
 	      // downloads config file, we should set to onlySeeding
 	      download_manager.requestAssumedCompleteMode();
 
-	      List	new_download_managers = new ArrayList( managers_cow );
+	      List<DownloadManager>	new_download_managers = new ArrayList<DownloadManager>( managers_cow );
 	      
 	      new_download_managers.add(download_manager);
         
@@ -1046,7 +1118,7 @@ public class GlobalManagerImpl
         }
 
         if (notifyListeners) {
-        	listeners.dispatch( LDT_MANAGER_ADDED, download_manager );
+        	listeners_and_event_listeners.dispatch( LDT_MANAGER_ADDED, download_manager );
         }
         
         download_manager.addListener(this);
@@ -1085,7 +1157,7 @@ public class GlobalManagerImpl
     }
   }
 
-  public List getDownloadManagers() {
+  public List<DownloadManager> getDownloadManagers() {
     return managers_cow;
   }
     
@@ -1126,6 +1198,7 @@ public class GlobalManagerImpl
   		}
 			GlobalManagerDownloadRemovalVetoException gmv = new GlobalManagerDownloadRemovalVetoException("Error running veto check");
 			gmv.initCause(e);
+			Debug.out(e);
 			throw gmv;
   	}
   }
@@ -1200,7 +1273,7 @@ public class GlobalManagerImpl
 	
     fixUpDownloadManagerPositions();
     
-    listeners.dispatch( LDT_MANAGER_REMOVED, manager );
+    listeners_and_event_listeners.dispatch( LDT_MANAGER_REMOVED, manager );
     
     manager.removeListener(this);
     
@@ -1336,7 +1409,7 @@ public class GlobalManagerImpl
 	
     for ( int i=0;i<nbDownloads;i++){
     	
-      DownloadManager manager = (DownloadManager)managers.get(i);
+      DownloadManager manager = managers.get(i);
       
       long	now = SystemTime.getCurrentTime();
       
@@ -1899,13 +1972,17 @@ public class GlobalManagerImpl
   private void triggerAddListener(List downloadsToAdd) {
 		try {
 			managers_mon.enter();
-			List listenersCopy = listeners.getListenersCopy();
+			List listenersCopy = listeners_and_event_listeners.getListenersCopy();
 
 			for (int j = 0; j < listenersCopy.size(); j++) {
-				GlobalManagerListener gmListener = (GlobalManagerListener) listenersCopy.get(j);
-				for (int i = 0; i < downloadsToAdd.size(); i++) {
-					DownloadManager dm = (DownloadManager) downloadsToAdd.get(i);
-					gmListener.downloadManagerAdded(dm);
+				Object listener = listenersCopy.get(j);
+				
+				if ( listener instanceof GlobalManagerListener ){
+					GlobalManagerListener gmListener = (GlobalManagerListener)listener;
+					for (int i = 0; i < downloadsToAdd.size(); i++) {
+						DownloadManager dm = (DownloadManager) downloadsToAdd.get(i);
+						gmListener.downloadManagerAdded(dm);
+					}
 				}
 			}
 		} finally {
@@ -1914,7 +1991,12 @@ public class GlobalManagerImpl
 		}
   }
 
-
+  public void
+  saveState()
+  {
+	  saveDownloads( true );
+  }
+  
   protected void 
   saveDownloads(
   	boolean	immediate ) 
@@ -1954,7 +2036,7 @@ public class GlobalManagerImpl
 	    Map map = new HashMap();
 	    List list = new ArrayList(managers_cow.size());
 	    for (int i = 0; i < managers_cow.size(); i++) {
-	      DownloadManager dm = (DownloadManager) managers_cow.get(i);
+	      DownloadManager dm = managers_cow.get(i);
 	      
 	      	DownloadManagerStats dm_stats = dm.getStats();
 		      Map dmMap = new HashMap();
@@ -2299,13 +2381,13 @@ public class GlobalManagerImpl
 		t.start();
 		*/
 
-  		listeners.dispatch( LDT_DESTROYED, null, true );
+  		listeners_and_event_listeners.dispatch( LDT_DESTROYED, null, true );
   }
   	
   public void 
   informDestroyInitiated()  
   {
-  	listeners.dispatch( LDT_DESTROY_INITIATED, null, true );		
+	  listeners_and_event_listeners.dispatch( LDT_DESTROY_INITIATED, null, true );		
   }
   	
  	public void
@@ -2326,7 +2408,7 @@ public class GlobalManagerImpl
 				
 		}else{			
 							
-			listeners.addListener(listener);
+			listeners_and_event_listeners.addListener(listener);
 			
 			if (!trigger) {
 				return;
@@ -2353,8 +2435,46 @@ public class GlobalManagerImpl
  	removeListener(
 		GlobalManagerListener	listener )
 	{			
-		listeners.removeListener(listener);
+		listeners_and_event_listeners.removeListener(listener);
+	}
+	
+	public void
+	addEventListener(
+		GlobalManagerEventListener 		listener )
+	{
+		listeners_and_event_listeners.addListener( listener );
+	}
+	
+	public void
+	removeEventListener(
+		GlobalManagerEventListener 		listener )
+	{
+		listeners_and_event_listeners.removeListener( listener );
 	}
+
+	
+	public void 
+	fireGlobalManagerEvent(
+		final int 				type, 
+		final DownloadManager 	param )
+	{
+		listeners_and_event_listeners.dispatch(
+			LDT_EVENT,
+			new GlobalManagerEvent()
+			{
+				public int	
+				getEventType()
+				{
+					return( type );
+				}
+				
+				public DownloadManager
+				getDownload()
+				{
+					return( param );
+				}
+			});
+ 	}
 	
 	public void
 	addDownloadWillBeRemovedListener(
@@ -2543,7 +2663,7 @@ public class GlobalManagerImpl
 		      
 		      // System.out.println( "dispatching " + seeding_only_mode + "/" + potentially_seeding_only_mode );
 		      
-		      listeners.dispatch( LDT_SEEDING_ONLY, new boolean[]{ seeding_only_mode, potentially_seeding_only_mode });
+		      listeners_and_event_listeners.dispatch( LDT_SEEDING_ONLY, new boolean[]{ seeding_only_mode, potentially_seeding_only_mode });
 		  }
 	  }
   }
@@ -2622,10 +2742,22 @@ public class GlobalManagerImpl
         	}
         }
         
+        long now = SystemTime.getMonotonousTime();
+        
         if ( num_ok > 0 ){
         	
         	nat_status = ConnectionManager.NAT_OK;
         	
+        	nat_status_last_good = now;
+        	
+        }else if ( nat_status_last_good != -1 && now - nat_status_last_good < 30*60*1000 ){
+        	
+        	nat_status = ConnectionManager.NAT_OK;
+        	
+        }else if ( nat_status_last_good != -1 && SystemTime.getCurrentTime() - TCPNetworkManager.getSingleton().getLastIncomingNonLocalConnectionTime() < 30*60*1000 ){
+        	
+        	nat_status = ConnectionManager.NAT_OK;
+        	
         }else if ( num_probably_ok > 0 || nat_status_probably_ok ){
         	
         	nat_status 				= ConnectionManager.NAT_PROBABLY_OK;
@@ -2749,6 +2881,10 @@ public class GlobalManagerImpl
 							}
 						}
 						
+						if (Constants.isOSX) {
+							fixLongFileName(manager);
+						}
+						
 						if ( COConfigurationManager.getBooleanParameter( "Rename Incomplete Files")){
 							
 							String	ext = COConfigurationManager.getStringParameter( "Rename Incomplete Files Extension" ).trim();
@@ -2774,7 +2910,11 @@ public class GlobalManagerImpl
 										
 										File existing_link = state.getFileLink( base_file );
 										
-										if ( existing_link == null || !existing_link.exists()){
+										if ( existing_link == null && base_file.exists()){
+											
+												// file already exists, do nothing as probably adding for seeding
+											
+										}else if ( existing_link == null || !existing_link.exists()){
 											
 											File	new_link;
 											
@@ -2802,6 +2942,106 @@ public class GlobalManagerImpl
 				});
 	}
 	
+	private void fixLongFileName(DownloadManager manager) {
+		// "File name too long" test
+		// Note: This only addresses the case where the filename is too
+		//       long, not the parent directory
+		DiskManagerFileInfo[] fileInfos = manager.getDiskManagerFileInfo();
+
+		DownloadManagerState state = manager.getDownloadState();
+
+		try {
+			state.suppressStateSave(true);
+
+			for (int i = 0; i < fileInfos.length; i++) {
+
+				DiskManagerFileInfo fileInfo = fileInfos[i];
+
+				File base_file = fileInfo.getFile(false);
+
+				File existing_link = state.getFileLink(base_file);
+
+				if (existing_link == null && !base_file.exists()) {
+
+					String name = base_file.getName();
+					String ext = FileUtil.getExtension(name);
+					int extLength = ext.length();
+					name = name.substring(0, name.length() - extLength);
+
+					// Java appears to be pretending
+					// each unicode character is 3 bytes long.  If the limit
+					// on a name is 256 two byte characters, then in theory,
+					// the limit is 170 unicode characters.  Instead of assuming
+					// that's the case, let's just walk back until the name
+					// is accepted.
+					// Bail at 50 just for the fun of it (plus most filenames
+					// are short, so we can skip the Canonical call)
+					int origLength = name.length();
+					if (origLength > 50) {
+						File parentFile = base_file.getParentFile();
+
+						// We don't get "File name too long" on getCanonicalPath 
+						// unless the dir is there 
+						// I Wonder if we should remove the dirs after using them
+						// FMFileImpl will create dirs again
+						parentFile.mkdirs();
+
+						File newFile = null;
+						boolean first = true;
+						while (name.length() > 50) {
+							try {
+								newFile = new File(parentFile, name + ext);
+								newFile.getCanonicalPath();
+
+								if (first) {
+									break;
+								}
+
+								// it worked, but the new name might already exist
+								int fixNameID = 0xFF; // always 3 digits :)
+								boolean redo;
+								do {
+									redo = false;
+									for (int j = 0; j < i; j++) {
+										DiskManagerFileInfo convertedFileInfo = fileInfos[j];
+										if (newFile.equals(convertedFileInfo.getFile(true))) {
+											do {
+												fixNameID++;
+												if (fixNameID >= 0xFFF) {
+													// exit, will fail later :(
+													break;
+												}
+												name = name.substring(0, name.length() - 3)
+														+ Integer.toHexString(fixNameID);
+												newFile = new File(parentFile, name + ext);
+											} while (newFile.equals(convertedFileInfo.getFile(true)));
+											redo = fixNameID <= 0xFFF;
+											break;
+										}
+									}
+								} while (redo);
+
+								if (fixNameID <= 0xFFF) {
+									state.setFileLink(base_file, newFile);
+								}
+								break;
+							} catch (IOException e) {
+								first = false;
+								name = name.substring(0, name.length() - 1);
+							} catch (Throwable t) {
+								Debug.out(t);
+							}
+						}
+					}
+
+				}
+			}
+		} finally {
+
+			state.suppressStateSave(false);
+		}
+	}
+
 	public void
 	addDownloadManagerInitialisationAdapter(
 		DownloadManagerInitialisationAdapter	adapter )
@@ -2934,4 +3174,111 @@ public class GlobalManagerImpl
 	public MainlineDHTProvider getMainlineDHTProvider() {
 		return this.provider;
 	}
+	
+	public void
+	statsRequest(
+		Map		request,
+		Map		reply )
+	{
+		AzureusCore core = AzureusCoreFactory.getSingleton();
+		
+		Map	glob = new HashMap();
+		
+		reply.put( "gm", glob );
+		
+		try{
+			glob.put( "u_rate", new Long( stats.getDataAndProtocolSendRate()));
+			glob.put( "d_rate", new Long( stats.getDataAndProtocolReceiveRate()));
+			
+			glob.put( "d_lim", new Long( TransferSpeedValidator.getGlobalDownloadRateLimitBytesPerSecond()));
+			
+			boolean auto_up = TransferSpeedValidator.isAutoSpeedActive(this) && TransferSpeedValidator.isAutoUploadAvailable( core );
+	
+			glob.put( "auto_up", new Long(auto_up?COConfigurationManager.getLongParameter( SpeedManagerImpl.CONFIG_VERSION ):0));
+	
+			long up_lim = NetworkManager.getMaxUploadRateBPSNormal();
+	
+			boolean	seeding_only = NetworkManager.isSeedingOnlyUploadRate();
+			
+			glob.put( "so", new Long(seeding_only?1:0));
+			
+			if ( seeding_only ){
+				
+				up_lim = NetworkManager.getMaxUploadRateBPSSeedingOnly();
+			}
+			
+			glob.put( "u_lim", new Long( up_lim ));
+			
+			SpeedManager sm = core.getSpeedManager();
+			
+			if ( sm != null ){
+				
+				glob.put( "u_cap", new Long( sm.getEstimatedUploadCapacityBytesPerSec().getBytesPerSec()));
+				glob.put( "d_cap", new Long( sm.getEstimatedDownloadCapacityBytesPerSec().getBytesPerSec()));
+			}
+			
+			List<DownloadManager> dms = getDownloadManagers();
+			
+			int	comp 	= 0;
+			int	incomp	= 0;
+			
+			long comp_up 		= 0;
+			long incomp_up		= 0;
+			long incomp_down	= 0;
+			
+			for ( DownloadManager dm: dms ){
+				
+				int state = dm.getState();
+				
+				if ( state == DownloadManager.STATE_SEEDING || state == DownloadManager.STATE_DOWNLOADING ){
+					
+					DownloadManagerStats stats = dm.getStats();
+					
+					if ( dm.isDownloadComplete( false )){
+						
+						comp++;
+						
+						comp_up += stats.getProtocolSendRate() + stats.getDataSendRate();
+						
+					}else{
+						
+						incomp++;
+						
+						incomp_up 	+= stats.getProtocolSendRate() + stats.getDataSendRate();
+						incomp_down += stats.getProtocolReceiveRate() + stats.getDataReceiveRate();
+					}
+				}
+			}
+			
+			glob.put( "dm_i", new Long( incomp ));
+			glob.put( "dm_c", new Long( comp ));
+			
+			glob.put( "dm_i_u", new Long( incomp_up ));
+			glob.put( "dm_i_d", new Long( incomp_down ));
+			glob.put( "dm_c_u", new Long( comp_up ));
+
+			glob.put( "nat", new Long( nat_status ));
+			
+			boolean	request_limiting = COConfigurationManager.getBooleanParameter( "Use Request Limiting" );
+			
+			glob.put( "req_lim", new Long( request_limiting?1:0 ));
+
+			if ( request_limiting ){
+				
+				glob.put( "req_focus", new Long( COConfigurationManager.getBooleanParameter( "Use Request Limiting Priorities" )?1:0 ));
+			}
+			
+			boolean bias_up = COConfigurationManager.getBooleanParameter( "Bias Upload Enable" );
+			
+			glob.put( "bias_up", new Long( bias_up?1:0 ));
+			
+			if ( bias_up ){
+			
+				glob.put( "bias_slack", new Long( COConfigurationManager.getLongParameter( "Bias Upload Slack KBs" )));
+				
+				glob.put( "bias_ulim", new Long( COConfigurationManager.getBooleanParameter( "Bias Upload Handle No Limit" )?1:0 ));
+			}
+		}catch( Throwable e ){
+		}
+	}
 }
diff --git a/org/gudy/azureus2/core3/html/HTMLChunk.java b/org/gudy/azureus2/core3/html/HTMLChunk.java
index e254b35..68c3f3c 100644
--- a/org/gudy/azureus2/core3/html/HTMLChunk.java
+++ b/org/gudy/azureus2/core3/html/HTMLChunk.java
@@ -31,10 +31,4 @@ HTMLChunk
 {
 	public String
 	getContent();
-	
-	public HTMLTable[]
-	getTables();
-	
-	public String[]
-	getLinks();
 }
diff --git a/org/gudy/azureus2/core3/html/HTMLPage.java b/org/gudy/azureus2/core3/html/HTMLPage.java
index 00541e2..5dda167 100644
--- a/org/gudy/azureus2/core3/html/HTMLPage.java
+++ b/org/gudy/azureus2/core3/html/HTMLPage.java
@@ -35,4 +35,8 @@ HTMLPage
 {
 	public URL
 	getMetaRefreshURL();
+	
+	public URL
+	getMetaRefreshURL(
+		URL		base_url );
 }
diff --git a/org/gudy/azureus2/core3/html/HTMLTable.java b/org/gudy/azureus2/core3/html/HTMLTable.java
deleted file mode 100644
index 98770be..0000000
--- a/org/gudy/azureus2/core3/html/HTMLTable.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html;
-
-/**
- * @author parg
- *
- */
-
-public interface 
-HTMLTable 
-	extends HTMLChunk
-{
-	public HTMLTableRow[]
-	getRows();
-}
diff --git a/org/gudy/azureus2/core3/html/HTMLTableCell.java b/org/gudy/azureus2/core3/html/HTMLTableCell.java
deleted file mode 100644
index f8f7dd1..0000000
--- a/org/gudy/azureus2/core3/html/HTMLTableCell.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html;
-
-/**
- * @author parg
- *
- */
-public interface 
-HTMLTableCell 
-	extends HTMLChunk
-{
-	public String
-	getContent();
-}
diff --git a/org/gudy/azureus2/core3/html/HTMLTableRow.java b/org/gudy/azureus2/core3/html/HTMLTableRow.java
deleted file mode 100644
index 84f7d78..0000000
--- a/org/gudy/azureus2/core3/html/HTMLTableRow.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html;
-
-/**
- * @author parg
- *
- */
-public interface 
-HTMLTableRow 
-	extends HTMLChunk
-{
-	public HTMLTableCell[]
-	getCells();
-}
diff --git a/org/gudy/azureus2/core3/html/HTMLUtils.java b/org/gudy/azureus2/core3/html/HTMLUtils.java
index 9ef95b7..0ea56b3 100644
--- a/org/gudy/azureus2/core3/html/HTMLUtils.java
+++ b/org/gudy/azureus2/core3/html/HTMLUtils.java
@@ -394,7 +394,12 @@ HTMLUtils
 				
 				if ( href.startsWith("\"")){
 					
-					href = href.substring(1,href.length()-1);
+					int endQuotePos = href.indexOf('\"', 1);
+					if (endQuotePos == -1) {
+						href = href.substring(1,href.length()-1);
+					} else {
+						href = href.substring(1,endQuotePos);
+					}
 				}
 				
 				current_url = href;
diff --git a/org/gudy/azureus2/core3/html/impl/HTMLChunkImpl.java b/org/gudy/azureus2/core3/html/impl/HTMLChunkImpl.java
index bad8010..b844efd 100644
--- a/org/gudy/azureus2/core3/html/impl/HTMLChunkImpl.java
+++ b/org/gudy/azureus2/core3/html/impl/HTMLChunkImpl.java
@@ -57,109 +57,13 @@ HTMLChunkImpl
 		content	= str;
 	}
 	
-	public String[]
-	getLinks()
-	{
-		int	pos	= 0;
-
-		List	res = new ArrayList();
-		
-		while(true){
-			
-			int	p1 = content.indexOf( "<", pos );
-			
-			if ( p1 == -1 ){
-				
-				break;
-			}
-			
-			p1++;
-			
-			int	p2 = content.indexOf( ">", p1 );
-			
-			if ( p2 == -1 ){
-				
-				break;
-			}
-			
-			pos	= p2;
-			
-			String	tag 	= content.substring( p1, p2 ).trim();
-			
-			String	lc_tag 	= tag.toLowerCase( MessageText.LOCALE_ENGLISH );
-						
-			if ( lc_tag.startsWith("a " )){
-				
-				int	hr_start = lc_tag.indexOf( "href");
-				
-				if ( hr_start == -1 ){
-					
-					continue;
-				}
-				
-				hr_start = lc_tag.indexOf("=", hr_start);
-				
-				if ( hr_start == -1 ){
-					
-					continue;
-				}
-				
-				hr_start += 1;
-				
-				while( 	hr_start < lc_tag.length() &&
-						Character.isWhitespace(lc_tag.charAt(hr_start))){
-					
-					hr_start++;
-				}
-				
-				int hr_end = hr_start;
-				
-				while(	hr_end < lc_tag.length() &&
-						!Character.isWhitespace(lc_tag.charAt(hr_end))){
-										
-					hr_end++;
-				}
-				
-				String	href = tag.substring(hr_start, hr_end ).trim();
-				
-				if ( href.startsWith("\"")){
-					
-					href = href.substring(1,href.length()-1);
-				}
-				
-				res.add( href );
-			}
-		}
-		
-		String[]	res_array = new String[res.size()];
-		
-		res.toArray( res_array );
-		
-		return( res_array );
-	}
-	
-	public HTMLTable[]
-	getTables()
-	{
-		String[]	tables = getTagPairContent( "table" );
-		
-		HTMLTable[]	res = new HTMLTable[tables.length];
-		
-		for (int i=0;i<tables.length;i++){
-			
-			res[i] = new HTMLTableImpl( tables[i] );
-		}
-		
-		return( res );
-	}
-	
 		/**
 		 * this just returns the tags themselves.
 		 * @param tag
 		 * @return
 		 */
 	
-	public String[]
+	protected String[]
 	getTags(
 		String	tag_name )
 	{
@@ -199,82 +103,6 @@ HTMLChunkImpl
 		return( x );
 	}
 	
-	public String[]
-	getTagPairContent(
-		String	tag_name )
-	{
-		tag_name = tag_name.toLowerCase( MessageText.LOCALE_ENGLISH );
-		
-		String	lc_content = content.toLowerCase( MessageText.LOCALE_ENGLISH );
-		
-		int	pos	= 0;
-
-		List	res = new ArrayList();
-		
-		int	level 		= 0;
-		int	start_pos	= -1;
-		
-		while(true){
-			
-			int	start_tag_start = lc_content.indexOf( "<" + tag_name,  pos );
-			int end_tag_start	= lc_content.indexOf( "</" + tag_name, pos );
-			
-			if ( level == 0 ){
-				
-				if ( start_tag_start == -1 ){
-					
-					break;
-				}
-				
-				start_pos = start_tag_start;
-				
-				level	= 1;
-				
-				pos		= start_pos+1;
-				
-			}else{
-				
-				if ( end_tag_start == -1 ){
-					
-					break;
-				}
-				
-				if ( start_tag_start == -1 || end_tag_start < start_tag_start ){
-					
-					if ( level == 1 ){
-						
-						String	tag_contents = content.substring( start_pos + tag_name.length() + 1, end_tag_start );
-						
-						res.add( tag_contents );
-						
-						// System.out.println( "got tag:" + tag_contents );						
-					}
-					
-					level--;
-					
-					pos	= end_tag_start + 1;
-					
-				}else{
-					
-					if ( start_tag_start == -1 ){
-						
-						break;
-					}
-					
-					level++;
-					
-					pos = start_tag_start+1;
-				}
-			}
-		}
-		
-		String[]	res_array = new String[res.size()];
-		
-		res.toArray( res_array );
-		
-		return( res_array );
-	}
-	
 	public String
 	getContent()
 	{
diff --git a/org/gudy/azureus2/core3/html/impl/HTMLPageImpl.java b/org/gudy/azureus2/core3/html/impl/HTMLPageImpl.java
index 5f351c4..ae57e20 100644
--- a/org/gudy/azureus2/core3/html/impl/HTMLPageImpl.java
+++ b/org/gudy/azureus2/core3/html/impl/HTMLPageImpl.java
@@ -94,10 +94,16 @@ HTMLPageImpl
 			}
 		}
 	}
-	
 	public URL
 	getMetaRefreshURL()
 	{
+		return( getMetaRefreshURL( null ));
+	}
+	
+	public URL
+	getMetaRefreshURL(
+		URL		base_url )
+	{
 	       // "<META HTTP-EQUIV=\"refresh\" content=\"5; URL=xxxxxxx>";
 	       
 		String[]	tags = getTags( "META" );
@@ -124,7 +130,33 @@ HTMLPageImpl
 					e2 = e1;
 				
 					try{
-						return( new URL(tag.substring(url_start, e2).trim()));
+						String mr_url = tag.substring(url_start, e2).trim();
+						
+						String lc = mr_url.toLowerCase();
+						
+						if ( ! ( lc.startsWith( "http:" ) || lc.startsWith( "https:" ))){
+							
+							if ( base_url != null ){
+								
+								String s = base_url.toExternalForm();
+								
+								int p = s.indexOf( '?' );
+								
+								if ( p != -1 ){
+									
+									s = s.substring( 0, p );
+								}
+								
+								if ( s.endsWith( "/" ) && mr_url.startsWith( "/" )){
+									
+									mr_url = mr_url.substring( 1 );
+								}
+								
+								mr_url = s + mr_url;
+							}
+						}
+						
+						return( new URL( mr_url ));
 						
 					}catch( MalformedURLException e ){
 						
diff --git a/org/gudy/azureus2/core3/html/impl/HTMLTableCellImpl.java b/org/gudy/azureus2/core3/html/impl/HTMLTableCellImpl.java
deleted file mode 100644
index 1c95697..0000000
--- a/org/gudy/azureus2/core3/html/impl/HTMLTableCellImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html.impl;
-
-/**
- * @author parg
- *
- */
-
-import org.gudy.azureus2.core3.html.*;
-
-public class 
-HTMLTableCellImpl 
-	extends		HTMLChunkImpl
-	implements 	HTMLTableCell
-{
-	String	raw_content;
-	
-	protected
-	HTMLTableCellImpl(
-		String	str )
-	{
-		raw_content		= str;
-		
-		int	pos = str.indexOf(">");
-		
-		String	content = str.substring( pos+1 );
-		
-		setContent( content );
-	}
-}
diff --git a/org/gudy/azureus2/core3/html/impl/HTMLTableImpl.java b/org/gudy/azureus2/core3/html/impl/HTMLTableImpl.java
deleted file mode 100644
index c0b57ff..0000000
--- a/org/gudy/azureus2/core3/html/impl/HTMLTableImpl.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html.impl;
-
-/**
- * @author parg
- *
- */
-
-import org.gudy.azureus2.core3.html.*;
-
-public class 
-HTMLTableImpl
-	extends		HTMLChunkImpl
-	implements 	HTMLTable
-{	
-	protected
-	HTMLTableImpl(
-		String	_content )
-	{
-		super( _content );
-	}
-	
-	public HTMLTableRow[]
-	getRows()
-	{
-		String[]	rows = getTagPairContent("tr");
-		
-		HTMLTableRowImpl[]	res = new HTMLTableRowImpl[ rows.length ];
-		
-		for (int i=0;i<rows.length;i++){
-			
-			res[i] = new HTMLTableRowImpl( rows[i] );
-		}
-		
-		return( res );
-	}
-}
diff --git a/org/gudy/azureus2/core3/html/impl/HTMLTableRowImpl.java b/org/gudy/azureus2/core3/html/impl/HTMLTableRowImpl.java
deleted file mode 100644
index be3a6fc..0000000
--- a/org/gudy/azureus2/core3/html/impl/HTMLTableRowImpl.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.core3.html.impl;
-
-/**
- * @author parg
- *
- */
-
-import org.gudy.azureus2.core3.html.*;
-
-public class 
-HTMLTableRowImpl
-	extends		HTMLChunkImpl
-	implements 	HTMLTableRow
-{
-	protected
-	HTMLTableRowImpl(
-		String	str )
-	{
-		super(str);
-	}
-	
-	public HTMLTableCell[]
-	getCells()
-	{
-		String[]	rows = getTagPairContent("td");
-		
-		HTMLTableCellImpl[]	res = new HTMLTableCellImpl[ rows.length ];
-		
-		for (int i=0;i<rows.length;i++){
-			
-			res[i] = new HTMLTableCellImpl( rows[i] );
-		}
-		
-		return( res );
-	}
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/internat/IntegratedResourceBundle.java b/org/gudy/azureus2/core3/internat/IntegratedResourceBundle.java
index b5fb6f4..adca1aa 100644
--- a/org/gudy/azureus2/core3/internat/IntegratedResourceBundle.java
+++ b/org/gudy/azureus2/core3/internat/IntegratedResourceBundle.java
@@ -107,15 +107,16 @@ IntegratedResourceBundle
 	private Map	used_messages;
 	private List null_values;
 	
-	private int		clean_count	= 0;
-	private boolean	one_off_discard_done;
+	private boolean		messages_dirty;
+	private int			clean_count	= 0;
+	private boolean		one_off_discard_done;
 	
 	private File		scratch_file_name;
 	private InputStream	scratch_file_is;
 
 	private final int initCapacity;
 	
-
+	private Map<String,String>	added_strings;
 	
 	public 
 	IntegratedResourceBundle(
@@ -335,6 +336,8 @@ IntegratedResourceBundle
 			
 			if ( bundle != null ){
 				
+				messages_dirty = true;
+				
 				if ( bundle instanceof IntegratedResourceBundle ){
 					
 					messages.putAll(((IntegratedResourceBundle)bundle).getMessages());
@@ -365,19 +368,45 @@ IntegratedResourceBundle
 			return( true );
 		}
 		
-		if ( scratch_file_is == null ){
+		if ( scratch_file_is == null || messages_dirty ){
 			
 			File temp_file = null;
 			
 			FileOutputStream	fos = null;
 			
+				// we have a previous cache, discard 
+			
+			if ( scratch_file_is != null ){
+				
+					// System.out.println( "discard cache file " + scratch_file_name + " for " + this );
+				
+				try{
+					scratch_file_is.close();
+										
+				}catch( Throwable e ){	
+					
+					scratch_file_name = null;
+					
+				}finally{
+					
+					scratch_file_is = null;
+				}
+			}
+			
 			try{
 				Properties props = new Properties();
 				
 				props.putAll( messages );
 				
-				temp_file = AETemporaryFileHandler.createTempFile();
-
+				if ( scratch_file_name == null ){
+				
+					temp_file = AETemporaryFileHandler.createTempFile();
+					
+				}else{
+					
+					temp_file = scratch_file_name;
+				}
+				
 				fos = new FileOutputStream( temp_file );
 				
 				props.store( fos, "message cache" );
@@ -386,9 +415,13 @@ IntegratedResourceBundle
 				
 				fos = null;
 				
+					// System.out.println( "wrote cache file " + temp_file + " for " + this );
+				
 				scratch_file_name	= temp_file;
 				scratch_file_is 	= new FileInputStream( temp_file );
 				
+				messages_dirty		= false;
+				
 			}catch( Throwable e ){
 				
 				if ( fos != null ){
@@ -412,7 +445,13 @@ IntegratedResourceBundle
 			
 			if ( clean_count >= 2 ){
 		
-			
+				/*
+				if ( messages != null ){
+				
+					System.out.println( "messages discarded  " + scratch_file_name + " for " + this );
+				}
+				*/
+				
 					// throw away full message map after 2 ticks
 			
 				messages = null;
@@ -420,6 +459,8 @@ IntegratedResourceBundle
 		
 			if ( clean_count == 5 && !one_off_discard_done){
 
+					// System.out.println( "used discard " + scratch_file_name + " for " + this );
+				
 				one_off_discard_done = true;
 				
 					// one off discard of used_messages to clear out any that were
@@ -455,48 +496,62 @@ IntegratedResourceBundle
 				return( messages );
 			}
 			
-			if ( scratch_file_is == null ){
-				
-				return( new LightHashMap());
-			}
-			
-			Properties p = new Properties();
+			Map	result;
 			
-			InputStream	fis = scratch_file_is;
-			
-			try{
-								
-				p.load( fis );
-				
-				fis.close();
+			if ( scratch_file_is == null ){
 				
-				scratch_file_is = new FileInputStream( scratch_file_name );
+				result = new LightHashMap();
 				
-				messages = new LightHashMap();
+			}else{
+			
+					// System.out.println( "read cache file " + scratch_file_name + " for " + this );
+
 				
-				messages.putAll( p );
+				Properties p = new Properties();
 				
-				return( messages );
+				InputStream	fis = scratch_file_is;
 				
-			}catch( Throwable e ){
-				
-				if ( fis != null ){
+				try{
+									
+					p.load( fis );
 					
-					try{
-						fis.close();
+					fis.close();
+					
+					scratch_file_is = new FileInputStream( scratch_file_name );
+					
+					messages = new LightHashMap();
+					
+					messages.putAll( p );
+					
+					result = messages;
+					
+				}catch( Throwable e ){
+					
+					if ( fis != null ){
 						
-					}catch( Throwable f ){
+						try{
+							fis.close();
+							
+						}catch( Throwable f ){
+						}
 					}
+					
+					Debug.out( "Failed to load message bundle scratch file", e );
+					
+					scratch_file_name.delete();
+					
+					scratch_file_is = null;
+					
+					result = new LightHashMap();
 				}
+			}
+			
+			if ( added_strings != null ){
 				
-				Debug.out( "Failed to load message bundle scratch file", e );
-				
-				scratch_file_name.delete();
-				
-				scratch_file_is = null;
-				
-				return( new LightHashMap());
+				result.putAll( added_strings );
 			}
+			
+			return( result );
 		}
 	}
 	
@@ -504,12 +559,24 @@ IntegratedResourceBundle
 	getString()
 	{
 		return( locale + ": use=" + used_messages.size() + ",map=" + (messages==null?"":String.valueOf(messages.size())) 
-				+ (null_values == null ? "" : ",null=" + null_values.size()));
+				+ (null_values == null ? "" : ",null=" + null_values.size()) + ",added=" + (added_strings==null?"":added_strings.size()));
 	}
 	
 	public void
 	addString(String key, String value) {
-		messages.put(key, value);
+		synchronized( bundle_map ){
+			if ( added_strings == null ){
+				
+				added_strings = new HashMap<String, String>();
+			}
+			
+			added_strings.put( key, value );
+			
+			if ( messages != null ){
+				
+				messages.put( key, value );
+			}
+		}
 	}
 
 	public boolean getUseNullList() {
diff --git a/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java b/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
index dc8f207..1bdca17 100644
--- a/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
+++ b/org/gudy/azureus2/core3/internat/LocaleTorrentUtil.java
@@ -108,6 +108,13 @@ public class LocaleTorrentUtil
 
 		throws TOTorrentException, UnsupportedEncodingException
 	{
+		return getTorrentEncoding(torrent, true);
+	}
+	
+	static public LocaleUtilDecoder getTorrentEncoding(TOTorrent torrent, boolean saveToFileAllowed)
+
+	throws TOTorrentException, UnsupportedEncodingException
+	{
 		String encoding = torrent.getAdditionalStringProperty("encoding");
 		if (TOTorrent.ENCODING_ACTUALLY_UTF8_KEYS.equals(encoding)) {
 			encoding = "utf8";
@@ -204,7 +211,7 @@ public class LocaleTorrentUtil
 
 		torrent.setAdditionalStringProperty("encoding", selected_decoder.getName());
 
-		if (bSaveToFile) {
+		if (bSaveToFile && saveToFileAllowed) {
 			TorrentUtils.writeToFile(torrent);
 		}
 
diff --git a/org/gudy/azureus2/core3/internat/MessageText.java b/org/gudy/azureus2/core3/internat/MessageText.java
index 8358049..c465906 100644
--- a/org/gudy/azureus2/core3/internat/MessageText.java
+++ b/org/gudy/azureus2/core3/internat/MessageText.java
@@ -203,7 +203,9 @@ public class MessageText {
 	  RESOURCE_BUNDLE	= bundle;
 	  
 	  Iterator	keys = RESOURCE_BUNDLE.getKeysLight();
-	  
+
+		String ui_suffix = getUISuffix();
+
 	  String	platform_suffix = getPlatformSuffix();
 	  
 	  Set platformKeys = new HashSet();
@@ -212,6 +214,11 @@ public class MessageText {
 		  String	key = (String)keys.next();
 		  if ( key.endsWith( platform_suffix ))
 			  platformKeys.add( key );
+		  else if ( key.endsWith(ui_suffix )) {
+				RESOURCE_BUNDLE.addString(
+						key.substring(0, key.length() - ui_suffix.length()),
+						RESOURCE_BUNDLE.getString(key));
+		  }
 	  }
 	  
 	  platform_specific_keys = platformKeys;
@@ -317,11 +324,15 @@ public class MessageText {
 
 		String value = RESOURCE_BUNDLE.getString(key);
 
+		return expandValue(value);
+	}
+  
+  public static String expandValue(String value) {
 		// Replace {*} with a lookup of *
 		if (value != null && value.indexOf('}') > 0) {
 			Matcher matcher = PAT_PARAM_ALPHA.matcher(value);
 			while (matcher.find()) {
-				key = matcher.group(1);
+				String key = matcher.group(1);
 		    try {
 		    	String text = getResourceBundleString(key);
 					if (text != null) {
@@ -332,9 +343,8 @@ public class MessageText {
 		    }
 			}
 		}
-
 		return value;
-	}
+  }
 
   /**
    * Gets the localization key suffix for the running platform
@@ -357,6 +367,11 @@ public class MessageText {
      else
        return "._unknown";
   }
+  
+	private static String getUISuffix() {
+		return "az2".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"))
+				? "._classic" : "._vuze";
+	}
 
   /**
    * Process a sequence of words, and translate the ones containing at least one '.', unless it's an ending dot.
@@ -626,7 +641,16 @@ public class MessageText {
         // Get the jarURL
         // XXX Is there a better way to get the JAR name?
         ClassLoader cl = MessageText.class.getClassLoader();
-        String sJar = cl.getResource(bundleFolder + extension).toString();
+       
+        URL u = cl.getResource(bundleFolder + extension);
+
+        if ( u == null ){
+        	
+        		// might be missing entirely
+        	
+        	return( false );
+        }
+        String sJar = u.toString();
         sJar = sJar.substring(0, sJar.length() - prefix.length() - extension.length());
         URL jarURL = new URL(sJar);
 
@@ -731,8 +755,12 @@ public class MessageText {
   //         - function to add another ResourceBundle, adds to hashtable
   public static boolean integratePluginMessages(String localizationPath, ClassLoader classLoader) {
 		boolean integratedSuccessfully = false;
-		if (null != localizationPath && localizationPath.length() != 0 && !pluginLocalizationPaths.containsKey(localizationPath))
-		{
+		
+			// allow replacement of localisation paths so that updates of unloadable plugins
+			// replace messages
+		
+		if ( localizationPath != null && localizationPath.length() != 0 ){
+		
 			synchronized (pluginLocalizationPaths)
 			{
 				pluginLocalizationPaths.put(localizationPath, classLoader);
diff --git a/org/gudy/azureus2/core3/ipchecker/natchecker/NatChecker.java b/org/gudy/azureus2/core3/ipchecker/natchecker/NatChecker.java
index c8aec8d..2c8f3f2 100644
--- a/org/gudy/azureus2/core3/ipchecker/natchecker/NatChecker.java
+++ b/org/gudy/azureus2/core3/ipchecker/natchecker/NatChecker.java
@@ -22,6 +22,7 @@
 package org.gudy.azureus2.core3.ipchecker.natchecker;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
@@ -29,6 +30,7 @@ import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.ByteBuffer;
 import java.util.Map;
+import java.util.Properties;
 
 import com.aelitis.azureus.core.*;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
@@ -42,6 +44,9 @@ import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 
 import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.clientid.ClientIDException;
+import org.gudy.azureus2.plugins.clientid.ClientIDGenerator;
+import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
 
 import com.aelitis.azureus.plugins.upnp.*;
 
@@ -172,7 +177,25 @@ public class NatChecker {
       }
       
       URL url = new URL( urlStr );
+      
+      Properties	http_properties = new Properties();
+
+      http_properties.put( ClientIDGenerator.PR_URL, url );
+      http_properties.put( ClientIDGenerator.PR_RAW_REQUEST, true );
+
+      try{
+    	  ClientIDManagerImpl.getSingleton().generateHTTPProperties( http_properties );
+
+      }catch( ClientIDException e ){
+
+    	  throw( new IOException( e.getMessage()));
+      }
+
+      url = (URL)http_properties.get( ClientIDGenerator.PR_URL );
+      
+     
       HttpURLConnection con = (HttpURLConnection)url.openConnection();
+      
       con.connect();
       
       ByteArrayOutputStream message = new ByteArrayOutputStream();
diff --git a/org/gudy/azureus2/core3/ipchecker/natchecker/NatCheckerServer.java b/org/gudy/azureus2/core3/ipchecker/natchecker/NatCheckerServer.java
index c7e6196..6290e92 100644
--- a/org/gudy/azureus2/core3/ipchecker/natchecker/NatCheckerServer.java
+++ b/org/gudy/azureus2/core3/ipchecker/natchecker/NatCheckerServer.java
@@ -186,7 +186,7 @@ public class NatCheckerServer extends AEThread {
 	            		  Debug.out( "Nat check write failed", t );
 	            	  }
 	
-	            	  connection.close();
+	            	  connection.close( null );
 	              }
 	              
 	              public boolean
@@ -196,7 +196,7 @@ public class NatCheckerServer extends AEThread {
 	              }
 	            },
 	            new MessageStreamFactory() {
-	              public MessageStreamEncoder createEncoder() {  return new AZMessageEncoder(false);  /* unused */}
+	              public MessageStreamEncoder createEncoder() {  return new AZMessageEncoder(AZMessageEncoder.PADDING_MODE_NONE);  /* unused */}
 	              public MessageStreamDecoder createDecoder() {  return new AZMessageDecoder();  /* unused */}
 	            });
 	      }
diff --git a/org/gudy/azureus2/core3/ipfilter/IpFilter.java b/org/gudy/azureus2/core3/ipfilter/IpFilter.java
index 4c3088d..181a990 100644
--- a/org/gudy/azureus2/core3/ipfilter/IpFilter.java
+++ b/org/gudy/azureus2/core3/ipfilter/IpFilter.java
@@ -129,6 +129,14 @@ IpFilter
 	public void
 	clearBannedIps();
 	
+	public void
+	addExcludedHash(
+		byte[]		hash );
+	
+	public void
+	removeExcludedHash(
+		byte[]		hash );
+	
 	public boolean
 	isEnabled();
 
@@ -167,4 +175,7 @@ IpFilter
 	public void
 	removeExternalHandler(
 		IpFilterExternalHandler	handler );
+
+	void reloadSync()
+			throws Exception;
 }
diff --git a/org/gudy/azureus2/core3/ipfilter/impl/IpFilterImpl.java b/org/gudy/azureus2/core3/ipfilter/impl/IpFilterImpl.java
index 97d6c4d..a1b5f01 100644
--- a/org/gudy/azureus2/core3/ipfilter/impl/IpFilterImpl.java
+++ b/org/gudy/azureus2/core3/ipfilter/impl/IpFilterImpl.java
@@ -80,6 +80,8 @@ IpFilterImpl
 	private boolean	ip_filter_enabled;
 	private boolean	ip_filter_allow;
 	
+	private ByteArrayHashMap<String>	excluded_hashes = new ByteArrayHashMap<String>();
+	
 	{
 	
 	  COConfigurationManager.addAndFireParameterListeners(
@@ -175,12 +177,21 @@ IpFilterImpl
 	{
 		reload(true);
 	}
-	
+
+	public void
+	reloadSync()
+		throws Exception
+	{
+		reload(false);
+	}
+
 	public void
 	reload(boolean allowAsyncDownloading)
 		throws Exception
 	{
-		range_manager.clearAllEntries();
+		if ( COConfigurationManager.getBooleanParameter( "Ip Filter Clear On Reload" )){	
+			range_manager.clearAllEntries();
+		}
 		markAsUpToDate();
 		loadFilters(allowAsyncDownloading, false);
 	}
@@ -481,6 +492,14 @@ IpFilterImpl
 	  	return false;
 	  }
 	  	  
+	  if ( torrent_hash != null ){
+		
+		  if ( excluded_hashes.containsKey( torrent_hash )){
+			  
+			  return( false );
+		  }
+	  }
+	  
 	  boolean allow = ip_filter_allow;
 	  
 	  IpRange	match = (IpRange)range_manager.isInRange( ipAddress );
@@ -599,6 +618,15 @@ IpFilterImpl
 	  	return false;
 	  }
 	  	  
+	  
+	  if ( torrent_hash != null ){
+		  
+		  if ( excluded_hashes.containsKey( torrent_hash )){
+			  
+			  return( false );
+		  }
+	  }
+
 	  boolean allow = ip_filter_allow;
 	  
 	  IpRange	match = (IpRange)range_manager.isInRange( ipAddress );
@@ -1229,6 +1257,49 @@ IpFilterImpl
 		}
 	}
 	
+	public void
+	addExcludedHash(
+		byte[]		hash )
+	{
+		synchronized( this ){
+			
+			ByteArrayHashMap<String>	copy = new ByteArrayHashMap<String>();
+			
+			for ( byte[] k : excluded_hashes.keys()){
+				
+				copy.put( k, "" );
+			}
+			
+			copy.put( hash, "" );
+			
+			excluded_hashes = copy;
+		}
+		
+		Logger.log( new LogEvent(LOGID, "Added " + ByteFormatter.encodeString( hash ) + " to excluded set" ));
+
+	}
+	
+	public void
+	removeExcludedHash(
+		byte[]		hash )
+	{
+		synchronized( this ){
+			
+			ByteArrayHashMap<String>	copy = new ByteArrayHashMap<String>();
+			
+			for ( byte[] k : excluded_hashes.keys()){
+				
+				copy.put( k, "" );
+			}
+			
+			copy.remove( hash );
+			
+			excluded_hashes = copy;
+		}
+		
+		Logger.log( new LogEvent(LOGID, "Removed " + ByteFormatter.encodeString( hash ) + " from excluded set" ));
+	}
+	
 	public boolean
 	isEnabled()
 	{
diff --git a/org/gudy/azureus2/core3/logging/LogAlert.java b/org/gudy/azureus2/core3/logging/LogAlert.java
index 879d637..a37a535 100644
--- a/org/gudy/azureus2/core3/logging/LogAlert.java
+++ b/org/gudy/azureus2/core3/logging/LogAlert.java
@@ -23,7 +23,6 @@ import com.aelitis.azureus.core.util.GeneralUtils;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import java.util.ArrayList;
-import java.util.regex.Pattern;
 
 /**
  * @author TuxPaper
@@ -54,6 +53,10 @@ public class LogAlert implements org.gudy.azureus2.plugins.logging.LogAlert {
 		// -1 -> default
 	public int	timeoutSecs	= -1;
 	
+	public String details;
+	
+	public boolean forceNotify;
+	
 	/**
 	 * @param type
 	 * @param text
diff --git a/org/gudy/azureus2/core3/logging/impl/LoggerImpl.java b/org/gudy/azureus2/core3/logging/impl/LoggerImpl.java
index 140222e..2127fb0 100644
--- a/org/gudy/azureus2/core3/logging/impl/LoggerImpl.java
+++ b/org/gudy/azureus2/core3/logging/impl/LoggerImpl.java
@@ -198,6 +198,12 @@ public class LoggerImpl {
 		//	new Exception("No logging check done!").printStackTrace(psOldErr);
 		//}
 		
+		/* ever wondered where a log is coming from? turn on log-to-file and breakpoint here
+		if ( event.text.startsWith( "Added Listener")){
+			int n=0;
+		}
+		*/
+		
 		if (bLogToStdOut && psOldOut != null)
 			psOldOut.println(event.text);
 
@@ -265,6 +271,14 @@ public class LoggerImpl {
 				alertLogger = AEDiagnostics.getLogger("alerts");
 			}
 		}
+		
+		Throwable error = alert.getError();
+		
+		if ( error != null ){
+			
+			logText += " (" + Debug.getNestedExceptionMessage( error ) + ")";
+		}
+		
 		alertLogger.log(logText);
 
 		alertHistory.add(alert);
diff --git a/org/gudy/azureus2/core3/peer/PEPeer.java b/org/gudy/azureus2/core3/peer/PEPeer.java
index eed5f15..f8d61be 100644
--- a/org/gudy/azureus2/core3/peer/PEPeer.java
+++ b/org/gudy/azureus2/core3/peer/PEPeer.java
@@ -27,7 +27,10 @@ package org.gudy.azureus2.core3.peer;
 
 
 import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
 
+import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.plugins.network.Connection;
 
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
@@ -145,6 +148,8 @@ PEPeer
    * @return true if I am choked by the peer, false if not
    */
 	public boolean isChokingMe();
+	
+	public boolean isUnchokeOverride();
 
   /**
    * Am I choking the peer.
@@ -232,6 +237,10 @@ PEPeer
 		LimitedRateGroup	limiter,
 		boolean				upload );
 	
+	public LimitedRateGroup[]
+	getRateLimiters(
+		boolean				upload );
+	
 	public void
 	removeRateLimiter(
 		LimitedRateGroup	limiter,
@@ -274,6 +283,9 @@ PEPeer
   public String
   getEncryption();
   
+  public String
+  getProtocol();
+  
   /**
    * Get the list of messages that this peer and us both understand.
    * @return messages available for use, or null of supported is yet unknown or unavailable
@@ -281,14 +293,16 @@ PEPeer
   public Message[] getSupportedMessages();
   
   /**
-   * Sets the reserved piece for piece picking by this peer
+   * adds the reserved piece for piece picking by this peer
    */
-  public void setReservedPieceNumber(int pieceNumber);
+  public void addReservedPieceNumber(int pieceNumber);
+  
+  public void removeReservedPieceNumber(int pieceNumber);
   
   /**
-   * Get the reserved piece for piece picking by this peer
+   * Get the reserved pieces for piece picking by this peer
    */
-  public int getReservedPieceNumber();
+  public int[] getReservedPieceNumbers();
   
   public int getIncomingRequestCount();
   public int getOutgoingRequestCount();
@@ -322,6 +336,16 @@ PEPeer
   public long
   getBytesRemaining();
   
+  	/**
+  	 * Enable suspended lazy bitfield for this peer - we will appear incomplete until this is disabled, at
+  	 * which point (well, fairly soon after) the bitfield will be completed  
+  	 * @param enable
+  	 */
+  
+  public void
+  setSuspendedLazyBitFieldEnabled(
+		boolean	enable );
+  
   /**
    * Get the time since this connection was first established.
    * NOTE: This method will always return 0 at any time before
@@ -363,6 +387,14 @@ PEPeer
 	        		 
 	public void
 	clearRequestHint();
+
+	public void
+	sendStatsRequest(
+		Map		request );
+	
+	public void
+	sendRejectRequest(
+		DiskManagerReadRequest	request );
 	
 	public void
 	setHaveAggregationEnabled(
diff --git a/org/gudy/azureus2/core3/peer/PEPeerManager.java b/org/gudy/azureus2/core3/peer/PEPeerManager.java
index 6e4ecc6..905619a 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerManager.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerManager.java
@@ -41,6 +41,7 @@ import org.gudy.azureus2.plugins.peers.PeerDescriptor;
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.peermanager.peerdb.PeerExchangerItem;
 import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
 
 
 public interface 
@@ -81,6 +82,10 @@ PEPeerManager
 	
 	public boolean hasDownloadablePiece();
 	
+    public int	getBytesQueuedForUpload();
+    public int	getNbPeersWithUploadQueued();
+    public int	getNbPeersWithUploadBlocked();
+    public int	getNbPeersUnchoked();
     
     /** Often better to use getPiece(pieceNumber)
      */
@@ -113,9 +118,9 @@ PEPeerManager
 	public String getElapsedTime();
 	
 	// Time Started in ms
-	public long getTimeStarted();
+	public long getTimeStarted( boolean mono_time );
 
-	public long getTimeStartedSeeding();
+	public long getTimeStartedSeeding( boolean mono_time );
 	
 	public void
 	addListener(
@@ -125,7 +130,7 @@ PEPeerManager
 	removeListener(
 		PEPeerManagerListener	l );
   
-	public void addPiece(PEPiece piece, int pieceNumber);
+	public void addPiece(PEPiece piece, int pieceNumber, PEPeer for_peer );
   
   public boolean needsMD5CheckOnCompletion(int pieceNumber);
   
@@ -133,6 +138,16 @@ PEPeerManager
   isSeeding();
   
   public boolean
+  isMetadataDownload();
+	
+  public int
+  getTorrentInfoDictSize();
+  
+  public void
+  setTorrentInfoDictSize(
+	int	size );
+  
+  public boolean
   isSuperSeedMode();
   
   public boolean
@@ -144,7 +159,9 @@ PEPeerManager
   public boolean
   seedPieceRecheck();
   
-  public int getNbRemoteConnectionsExcludingUDP();
+  public int getNbRemoteTCPConnections();
+  public int getNbRemoteUDPConnections();
+  public int getNbRemoteUTPConnections();
   
   public long getLastRemoteConnectionTime();
   
@@ -196,6 +213,9 @@ PEPeerManager
 	getPeers(
 		String	address );
 	
+	public int
+	getPendingPeerCount();
+	
 	public PeerDescriptor[]
    	getPendingPeers();
 	
@@ -368,6 +388,9 @@ PEPeerManager
 		LimitedRateGroup	group,
 		boolean				upload );
 	
+	public TrackerPeerSource
+	getTrackerPeerSource();
+	
 	public boolean
 	isPeerSourceEnabled(
 		String	peer_source );
@@ -379,4 +402,16 @@ PEPeerManager
 	generateEvidence(
 		IndentWriter		writer );
 	
+	public void
+	setStatsReceiver(
+		StatsReceiver	receiver );
+	
+	public interface
+	StatsReceiver
+	{
+		public void
+		receiveStats(
+			PEPeer		peer,
+			Map			stats );
+	}
 }
diff --git a/org/gudy/azureus2/core3/peer/PEPeerManagerAdapter.java b/org/gudy/azureus2/core3/peer/PEPeerManagerAdapter.java
index 8a67c4b..01bf2f8 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerManagerAdapter.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerManagerAdapter.java
@@ -22,6 +22,8 @@
 
 package org.gudy.azureus2.core3.peer;
 
+import java.util.Map;
+
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequestListener;
 import org.gudy.azureus2.core3.logging.LogRelation;
@@ -56,6 +58,18 @@ PEPeerManagerAdapter
 	public boolean
 	isPeerExchangeEnabled();
 	
+	public boolean
+	isMetadataDownload();
+	
+	public int
+	getUploadPriority();
+	
+	public int
+	getTorrentInfoDictSize();
+	
+	public byte[]
+	getTorrentInfoDict(
+		PEPeer		peer );
 		/**
 		 * See NetworkManager.CRYPTO_OVERRIDE constants
 		 * @return
@@ -134,6 +148,12 @@ PEPeerManagerAdapter
 		PEPeer		peer,
 		int			bytes );
 	
+	public void 
+	statsRequest(
+		PEPeer			 	originator, 
+		Map 				request,
+		Map					reply );
+
 	public PeerManagerRegistration
 	getPeerManagerRegistration();
 	
@@ -167,4 +187,10 @@ PEPeerManagerAdapter
 	
 	public boolean
 	hasPriorityConnection();
+	
+	public int getPermittedBytesToReceive();
+	public void permittedReceiveBytesUsed( int bytes );
+	
+	public int getPermittedBytesToSend();
+	public void	permittedSendBytesUsed(	int bytes );
 }
diff --git a/org/gudy/azureus2/core3/peer/PEPeerManagerListener.java b/org/gudy/azureus2/core3/peer/PEPeerManagerListener.java
index c918d72..b75ba74 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerManagerListener.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerManagerListener.java
@@ -46,6 +46,17 @@ PEPeerManagerListener
    */
   public void peerRemoved( PEPeerManager manager, PEPeer peer );
   
+  /**
+   * piece activated
+   * @param peice
+   * @param for_peer maybe null if not for a particular peer
+   */
+  
+  public void pieceAdded( PEPeerManager manager, PEPiece piece, PEPeer for_peer );
+  
+  public void pieceRemoved( PEPeerManager manager, PEPiece piece );
+  
+  
   public void peerDiscovered( PEPeerManager manager, PeerItem peer, PEPeer finder );
   
   public void peerSentBadData( PEPeerManager manager, PEPeer peer, int piece_number );
diff --git a/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java b/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
index 28bae6d..a831a50 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerManagerStats.java
@@ -37,6 +37,8 @@ PEPeerManagerStats
   
   	public void haveNewPiece(int pieceLength);
   
+  	public void haveNewConnection( boolean incoming );
+  	
 	public long getDataReceiveRate();
 	public long getProtocolReceiveRate();
   
@@ -62,4 +64,13 @@ PEPeerManagerStats
 	
 	public int getTimeSinceLastDataReceivedInSeconds();
 	public int getTimeSinceLastDataSentInSeconds();
+	
+	public int getTotalIncomingConnections();
+	public int getTotalOutgoingConnections();
+	
+	public int getPermittedBytesToReceive();
+	public void permittedReceiveBytesUsed( int bytes );
+	
+	public int getPermittedBytesToSend();
+	public void	permittedSendBytesUsed(	int bytes );
 }
diff --git a/org/gudy/azureus2/core3/peer/PEPeerStats.java b/org/gudy/azureus2/core3/peer/PEPeerStats.java
index 5af4cde..87ee8c5 100644
--- a/org/gudy/azureus2/core3/peer/PEPeerStats.java
+++ b/org/gudy/azureus2/core3/peer/PEPeerStats.java
@@ -179,4 +179,13 @@ PEPeerStats
   public void setDownloadRateLimitBytesPerSecond( int bytes );
   public int getUploadRateLimitBytesPerSecond();
   public int getDownloadRateLimitBytesPerSecond();
+  
+  	// external rate control
+  
+  public int getPermittedBytesToSend();
+  public void permittedSendBytesUsed( int num );
+  
+  public int getPermittedBytesToReceive();
+  public void permittedReceiveBytesUsed( int num );
+  
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/peer/PEPiece.java b/org/gudy/azureus2/core3/peer/PEPiece.java
index 5e8d8c9..26d6be8 100644
--- a/org/gudy/azureus2/core3/peer/PEPiece.java
+++ b/org/gudy/azureus2/core3/peer/PEPiece.java
@@ -80,7 +80,7 @@ PEPiece
 	public int			getAvailability();
 
 	public boolean		hasUnrequestedBlock();
-	public int[]		getAndMarkBlocks(PEPeer peer, int nbWanted, boolean enable_hints );
+	public int[]		getAndMarkBlocks(PEPeer peer, int nbWanted, int[] request_hint, boolean reverse_order );
 	
 	public void 		getAndMarkBlock(PEPeer peer, int index);
 	public Object		getRealTimeData();
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerControl.java b/org/gudy/azureus2/core3/peer/impl/PEPeerControl.java
index 7e766af..1600f1a 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerControl.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerControl.java
@@ -27,6 +27,8 @@ package org.gudy.azureus2.core3.peer.impl;
  */
 
 
+import java.util.Map;
+
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 
@@ -73,11 +75,18 @@ PEPeerControl
 		int	crypto_level );
 	
 	public int
+	getUploadPriority();
+	
+	public int
 	getHiddenPiece();
 	
 	public void addPeerTransport( PEPeerTransport transport );
 	
 	public int
+	getConnectTimeout(
+		int		ct_def );
+	
+	public int
 	getMaxConnections();
     
     public boolean 
@@ -100,6 +109,16 @@ PEPeerControl
 		PEPeerTransport		originator,
 		int					piece_number );
 	
+	public void
+	statsRequest(
+		PEPeerTransport		originator,
+		Map					request );
+	
+	public void
+	statsReply(
+		PEPeerTransport		originator,
+		Map					reply );
+	
 	public boolean isRTA();
 	
 	public void
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java b/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
index f840481..084fb43 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerManagerStatsImpl.java
@@ -57,7 +57,8 @@ PEPeerManagerStatsImpl
   
 	private final Average overallSpeed = Average.getInstance(5000, 100); //average over 100s, update every 5s
 
-
+	private int	total_incoming;
+	private int total_outgoing;
 
 	public 
 	PEPeerManagerStatsImpl(
@@ -239,4 +240,56 @@ PEPeerManagerStatsImpl
 		
 		return( now - last_data_sent_seconds );
 	}
+	
+ 	public void 
+ 	haveNewConnection( 
+ 		boolean incoming )
+ 	{
+ 		if ( incoming ){
+ 			
+ 			total_incoming++;
+ 			
+ 		}else{
+ 			
+ 			total_outgoing++;
+ 		}
+ 	}
+
+	public int 
+	getTotalIncomingConnections()
+	{
+		return( total_incoming );
+	}
+	
+	public int 
+	getTotalOutgoingConnections()
+	{
+		return( total_outgoing );
+	}
+	
+	public int 
+	getPermittedBytesToReceive()
+	{
+		return( adapter.getPermittedBytesToReceive());
+	}
+	
+	public void 
+	permittedReceiveBytesUsed( 
+		int bytes )
+	{
+		adapter.permittedReceiveBytesUsed(bytes);
+	}
+	
+	public int 
+	getPermittedBytesToSend()
+	{
+		return( adapter.getPermittedBytesToSend());
+	}
+	
+	public void 
+	permittedSendBytesUsed( 
+		int bytes )
+	{
+		adapter.permittedSendBytesUsed(bytes);
+	}
 }
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerStatsImpl.java b/org/gudy/azureus2/core3/peer/impl/PEPeerStatsImpl.java
index 6ef006d..c714d7b 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerStatsImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerStatsImpl.java
@@ -28,6 +28,9 @@ package org.gudy.azureus2.core3.peer.impl;
 
 import org.gudy.azureus2.core3.peer.*;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.pluginsimpl.local.network.ConnectionImpl;
+
+import com.aelitis.azureus.core.networkmanager.NetworkManager;
 
 public class 
 PEPeerStatsImpl 
@@ -204,4 +207,38 @@ PEPeerStatsImpl
     public void setDownloadRateLimitBytesPerSecond( int bytes ){owner.setDownloadRateLimitBytesPerSecond( bytes );}
     public int getUploadRateLimitBytesPerSecond(){return owner.getUploadRateLimitBytesPerSecond();}
     public int getDownloadRateLimitBytesPerSecond(){return owner.getDownloadRateLimitBytesPerSecond();}
+    
+    public int 
+    getPermittedBytesToSend()
+    {
+    	return(NetworkManager.getSingleton().getRateHandler(
+    		((ConnectionImpl)owner.getPluginConnection()).getCoreConnection(),
+    		true ).getCurrentNumBytesAllowed());
+    }
+    
+    public void 
+    permittedSendBytesUsed( 
+    	int num )
+    {
+    	NetworkManager.getSingleton().getRateHandler(
+        	((ConnectionImpl)owner.getPluginConnection()).getCoreConnection(),
+        	true ).bytesProcessed( num );
+    }
+    
+    public int 
+    getPermittedBytesToReceive()
+    {
+    	return(NetworkManager.getSingleton().getRateHandler(
+        	((ConnectionImpl)owner.getPluginConnection()).getCoreConnection(),
+        	false ).getCurrentNumBytesAllowed());
+    }
+    
+    public void 
+    permittedReceiveBytesUsed( 
+    	int num )
+    {
+       	NetworkManager.getSingleton().getRateHandler(
+        	((ConnectionImpl)owner.getPluginConnection()).getCoreConnection(),
+        	false ).bytesProcessed( num );
+    }
 }
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java b/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
index 1a5259a..ccf25a8 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPeerTransport.java
@@ -26,6 +26,7 @@
 package org.gudy.azureus2.core3.peer.impl;
 
 import java.util.List;
+import java.util.Map;
 
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.peer.PEPeer;
@@ -68,6 +69,14 @@ PEPeerTransport
 	sendBadPiece(
 		int		piece_number );
 	
+	public void
+	sendStatsRequest(
+		Map		request );
+	
+	public void
+	sendStatsReply(
+		Map		reply );
+			
 		/**
 		 * Two methods that allow a peer to aggregate the individual requests generated during an
 		 * allocation cycle if so desired
@@ -185,6 +194,8 @@ PEPeerTransport
   public long getTimeSinceLastDataMessageSent();
   
   
+  public long getUnchokedForMillis();
+  
   /**
    * Do any peer exchange processing/updating.
    */
diff --git a/org/gudy/azureus2/core3/peer/impl/PEPieceImpl.java b/org/gudy/azureus2/core3/peer/impl/PEPieceImpl.java
index 5842a15..46afcce 100644
--- a/org/gudy/azureus2/core3/peer/impl/PEPieceImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/PEPieceImpl.java
@@ -370,50 +370,112 @@ public class PEPieceImpl
 	 * TODO: this should return the largest span equal or smaller than nbWanted
 	 * OR, probably a different method should do that, so this one can support 'more sequential' picking
 	 */
-	public int[] getAndMarkBlocks(PEPeer peer, int nbWanted, boolean enable_request_hints )
-	{
-		final String ip =peer.getIp();
-        final boolean[] written =dmPiece.getWritten();
-		int blocksFound =0;
+	public int[] 
+	getAndMarkBlocks(
+		PEPeer 		peer, 
+		int 		nbWanted, 
+		int[]		request_hint,
+		boolean 	reverse_order )	
+	{
+		final String ip = peer.getIp();
 		
-		if ( enable_request_hints ){
-			
-			int[]	request_hint = peer.getRequestHint();
+        final boolean[] written = dmPiece.getWritten();
+		
+		if ( request_hint != null ){
+					
+				// try to honour the hint first
+							
+			int	hint_block_start 	= request_hint[1] / DiskManager.BLOCK_SIZE;
+			int	hint_block_end	 	= ( request_hint[1] + request_hint[2] -1 )/ DiskManager.BLOCK_SIZE;
 			
-			if ( request_hint != null && request_hint[0] == dmPiece.getPieceNumber()){
+			if ( reverse_order ){
 				
-					// try to honour the hint first
+				for ( int i = Math.min( nbBlocks-1, hint_block_end ); i >= hint_block_start; i--){
+					
+					int blocksFound = 0;
+					int	block_index	= i;
 				
-				int	hint_block_start 	= request_hint[1] / DiskManager.BLOCK_SIZE;
-				int hint_block_count	=  ( request_hint[2] + DiskManager.BLOCK_SIZE-1 ) / DiskManager.BLOCK_SIZE;
+					while ( blocksFound < nbWanted &&
+							block_index < nbBlocks &&
+							!downloaded[ block_index ] &&
+							requested[block_index] == null &&
+							( written == null || !written[block_index] )){
+					
+						requested[ block_index ] = ip;
+						blocksFound++;
+						block_index--;
+					}
+					if ( blocksFound > 0 ){		
+						return new int[] {block_index+1, blocksFound};
+					}
+				}
+			}else{
+				for (int i = hint_block_start; i < nbBlocks && i <= hint_block_end; i++){
+					
+					int blocksFound = 0;
+					int	block_index	= i;
 				
-				for (int i =hint_block_start; i < nbBlocks && i <hint_block_start + hint_block_count; i++)
-				{
-					while (blocksFound <nbWanted &&(i +blocksFound) <nbBlocks &&!downloaded[i +blocksFound]
-					    &&requested[i +blocksFound] ==null &&(written ==null ||!written[i]))
-					{
-						requested[i +blocksFound] =ip;
+					while ( blocksFound < nbWanted &&
+							block_index < nbBlocks &&
+							!downloaded[ block_index ] &&
+							requested[block_index] == null &&
+							( written == null || !written[block_index] )){
+					
+						requested[ block_index ] = ip;
 						blocksFound++;
+						block_index++;
 					}
-					if (blocksFound >0){
-												
+					if ( blocksFound > 0 ){		
 						return new int[] {i, blocksFound};
 					}
 				}
 			}
 		}
 		
-		// scan piece to find first free block
-		for (int i =0; i <nbBlocks; i++)
-		{
-			while (blocksFound <nbWanted &&(i +blocksFound) <nbBlocks &&!downloaded[i +blocksFound]
-			    &&requested[i +blocksFound] ==null &&(written ==null ||!written[i]))
-			{
-				requested[i +blocksFound] =ip;
-				blocksFound++;
+			// scan piece to find first free block
+		
+		if ( reverse_order ){
+			
+			for (int i=nbBlocks-1; i >= 0; i-- ){
+			
+				int blocksFound = 0;
+				int	block_index = i;
+				
+				while (	blocksFound < nbWanted &&
+						block_index >= 0 &&
+						!downloaded[block_index] &&
+						requested[block_index] == null &&
+						( written == null || !written[block_index] )){
+				
+					requested[block_index] = ip;
+					blocksFound++;
+					block_index--;
+				}
+				if ( blocksFound > 0 ){
+					return new int[] {block_index+1, blocksFound};
+				}
+			}
+		}else{
+			
+			for (int i =0; i <nbBlocks; i++){
+			
+				int blocksFound = 0;
+				int	block_index = i;
+				
+				while (	blocksFound < nbWanted &&
+						block_index < nbBlocks &&
+						!downloaded[ block_index ] &&
+						requested[ block_index ] == null &&
+						( written == null || !written[block_index] )){
+				
+					requested[block_index] = ip;
+					blocksFound++;
+					block_index++;
+				}
+				if ( blocksFound > 0 ){
+					return new int[] {i, blocksFound};
+				}
 			}
-			if (blocksFound >0)
-				return new int[] {i, blocksFound};
 		}
 		return new int[] {-1, 0};
 	}
diff --git a/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java b/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
index 5657c49..790b223 100644
--- a/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
+++ b/org/gudy/azureus2/core3/peer/impl/control/PEPeerControlImpl.java
@@ -33,6 +33,8 @@ import java.util.*;
 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.disk.DiskManager.GettingThere;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.ipfilter.*;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.peer.*;
@@ -47,6 +49,8 @@ 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.network.Connection;
+import org.gudy.azureus2.plugins.network.OutgoingMessageQueue;
 import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.plugins.peers.PeerDescriptor;
 
@@ -69,6 +73,8 @@ 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.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 import com.aelitis.azureus.core.util.FeatureAvailability;
 import com.aelitis.azureus.core.util.bloom.BloomFilter;
 import com.aelitis.azureus.core.util.bloom.BloomFilterFactory;
@@ -91,6 +97,14 @@ DiskManagerCheckRequestListener, IPFilterListener
 {
 	private static final LogIDs LOGID = LogIDs.PEER;
 
+	private static final boolean TEST_PERIODIC_SEEDING_SCAN_FAIL_HANDLING	= false;
+	
+	static{
+		if ( TEST_PERIODIC_SEEDING_SCAN_FAIL_HANDLING ){
+			Debug.out( "**** test periodic scan failure enabled ****" );
+		}
+	}
+	
 	private static final int WARNINGS_LIMIT = 2;
 
 	private static final int	CHECK_REASON_DOWNLOADED		= 1;
@@ -170,6 +184,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 	private final DiskManager           disk_mgr;
 	private final DiskManagerPiece[]    dm_pieces;
 
+	private PEPeerManager.StatsReceiver	stats_receiver;
+	
 	private final PiecePicker	piecePicker;
 	private long				lastNeededUndonePieceChange;
 
@@ -188,10 +204,13 @@ DiskManagerCheckRequestListener, IPFilterListener
 	private PEPeerManagerStats        _stats;
 	//private final TRTrackerAnnouncer _tracker;
 	//  private int _maxUploads;
-	private int		_seeds, _peers,_remotesNoUdpNoLan;
+	private int		_seeds, _peers,_remotesTCPNoLan, _remotesUDPNoLan, _remotesUTPNoLan;
+	private int 	_tcpPendingConnections, _tcpConnectingConnections;
 	private long last_remote_time;
 	private long	_timeStarted;
-	private long	_timeStartedSeeding = -1;
+	private long	_timeStarted_mono;
+	private long	_timeStartedSeeding 		= -1;
+	private long	_timeStartedSeeding_mono 	= -1;
 	private long	_timeFinished;
 	private Average	_averageReceptionSpeed;
 
@@ -228,7 +247,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 	private List<Object[]>	external_rate_limiters_cow;
 	
+	private int	bytes_queued_for_upload;
+	private int	connections_with_queued_data;
+	private int	connections_with_queued_data_blocked;
+	private int	connections_unchoked;
 	
+
 	private List<PEPeer> sweepList = Collections.emptyList();
 	private int nextPEXSweepIndex = 0;
 
@@ -324,6 +348,11 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 	private final int	partition_id;
 	
+	private final boolean	is_metadata_download;
+	private int				metadata_infodict_size;
+	
+	private GettingThere	finish_in_progress;
+	
 	public 
 	PEPeerControlImpl(
 		byte[]					_peer_id,
@@ -336,6 +365,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 		disk_mgr 		= _diskManager;
 		partition_id	= _partition_id;
 		
+		is_metadata_download	= adapter.isMetadataDownload();
+		
+		if ( !is_metadata_download ){
+			metadata_infodict_size	= adapter.getTorrentInfoDictSize();
+		}
+		
 		_nbPieces =disk_mgr.getNbPieces();
 		dm_pieces =disk_mgr.getPieces();
 		
@@ -381,7 +416,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 			final DiskManagerPiece dmPiece =dm_pieces[i];
 			if (!dmPiece.isDone() &&dmPiece.getNbWritten() >0)
 			{
-				addPiece(new PEPieceImpl(this, dmPiece, 0), i, true );
+				addPiece(new PEPieceImpl(this, dmPiece, 0), i, true, null );
 			}
 		}
 
@@ -420,7 +455,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 		UploadSlotManager.getSingleton().registerHelper( upload_helper );
 
 		lastNeededUndonePieceChange =Long.MIN_VALUE;
-		_timeStarted = SystemTime.getCurrentTime();
+		_timeStarted 		= SystemTime.getCurrentTime();
+		_timeStarted_mono 	= SystemTime.getMonotonousTime();
 
 		is_running = true;
 
@@ -510,11 +546,39 @@ DiskManagerCheckRequestListener, IPFilterListener
 	public void
 	schedule()
 	{
-		try {
+		if ( finish_in_progress != null ){
+			
+			// System.out.println( "Finish in prog" );
+			
+			if ( finish_in_progress.hasGotThere()){
+				
+				finish_in_progress = null;
+				
+				// System.out.println( "Finished" );
+			}else{
+				
+				return;
+			}
+		}
+		
+		try{
+				// first off update the stats so they can be used by subsequent steps
+			
+			updateStats();
+
 			updateTrackerAnnounceInterval();
+			
 			doConnectionChecks();
+			
 			processPieceChecks();
 
+			if ( finish_in_progress != null ){
+				
+					// get off the scheduler thread while potentially long running operations complete
+				
+				return;
+			}
+			
 			// note that seeding_mode -> torrent totally downloaded, not just non-dnd files
 			// complete, so there is no change of a new piece appearing done by a means such as
 			// background periodic file rescans
@@ -526,14 +590,19 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 			checkBadPieces();
 
-			updateStats();
-
 			checkInterested();      // see if need to recheck Interested on all peers
 
 			piecePicker.updateAvailability();
 
 			checkCompletionState();	// pick up changes in completion caused by dnd file changes
 
+			if ( finish_in_progress != null ){
+				
+					// get off the scheduler thread while potentially long running operations complete
+
+				return;
+			}
+			
 			checkSeeds();
 
 			if(!seeding_mode) {
@@ -654,6 +723,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 		return( result );
 	}
 
+	public int
+	getPendingPeerCount()
+	{
+		return( peer_database.getDiscoveredPeerCount());
+	}
+	
 	public PeerDescriptor[]
   	getPendingPeers()
   	{
@@ -906,7 +981,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 			int	http_port = peer.getHTTPPort();
 
-			if ( http_port != 0 ){
+			if ( http_port != 0 && !seeding_mode ){
 
 				adapter.addHTTPSeed( peer.getAddress(), http_port );
 			}
@@ -1221,6 +1296,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 				final Object[]	data = (Object[])it.next();
 
+				//bah
+				
 				processPieceCheckResult((DiskManagerCheckRequest)data[0],((Integer)data[1]).intValue());
 
 			}
@@ -1383,19 +1460,55 @@ DiskManagerCheckRequestListener, IPFilterListener
 		
 		bad_piece_reported = piece_number;
 	}
+	
+	public void
+	setStatsReceiver(
+		PEPeerManager.StatsReceiver	receiver )
+	{
+		stats_receiver = receiver;
+	}
+	
+	public void 
+	statsRequest(
+		PEPeerTransport 	originator, 
+		Map 				request )
+	{
+		Map		reply = new HashMap();
+		
+		adapter.statsRequest( originator, request, reply );
+		
+		if ( reply.size() > 0 ){
+			
+			originator.sendStatsReply( reply );
+		}
+	}
+	
+	public void 
+	statsReply(
+		PEPeerTransport 	originator, 
+		Map 				reply )
+	{	
+		PEPeerManager.StatsReceiver receiver = stats_receiver;
+		
+		if ( receiver != null ){
+			
+			receiver.receiveStats( originator, reply );
+		}
+	}
 
 	/**
 	 * This method checks if the downloading process is finished.
 	 *
 	 */
+	
 	private void 
 	checkFinished(
-			boolean start_of_day )
+		final boolean start_of_day )
 	{
 		final boolean all_pieces_done =disk_mgr.getRemainingExcludingDND() ==0;
 
-		if (all_pieces_done)
-		{
+		if ( all_pieces_done ){
+		
 			seeding_mode	= true;
 			
 			prefer_udp_bloom = null;
@@ -1425,7 +1538,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 				disk_mgr.enqueueCompleteRecheckRequest(req, this);
 			}
 
-			_timeStartedSeeding = SystemTime.getCurrentTime();
+			_timeStartedSeeding 		= SystemTime.getCurrentTime();
+			_timeStartedSeeding_mono 	= SystemTime.getMonotonousTime();
 
 			try{
 				disk_mgr.saveResumeData(false);
@@ -1433,10 +1547,52 @@ DiskManagerCheckRequestListener, IPFilterListener
 			}catch( Throwable e ){
 				Debug.out( "Failed to save resume data", e );
 			}
+			
 			adapter.setStateSeeding( start_of_day );
-			disk_mgr.downloadEnded();
-		} else
-		{
+			
+			final AESemaphore waiting_it = new AESemaphore( "PEC:DE" );
+			
+			new AEThread2( "PEC:DE" ){
+				public void
+				run()
+				{
+					try{
+						disk_mgr.downloadEnded(
+							new DiskManager.OperationStatus()
+							{
+								public void 
+								gonnaTakeAWhile(
+									GettingThere gt ) 
+								{
+									boolean	async_set = false;
+									
+									synchronized( PEPeerControlImpl.this ){
+										
+										if ( finish_in_progress == null ){
+											
+											finish_in_progress = gt;
+											
+											async_set = true;
+										}
+									}
+										
+									if ( async_set ){
+									
+										waiting_it.release();
+									}
+								}
+							});
+					}finally{
+						
+						waiting_it.release();
+					}
+				}
+			}.start();
+			
+			waiting_it.reserve();
+						
+		}else{
+			
 			seeding_mode = false;
 		}
 	}
@@ -1457,13 +1613,15 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 				seeding_mode = false;
 
-				_timeStartedSeeding = -1;
-				_timeFinished		= 0;
+				_timeStartedSeeding 		= -1;
+				_timeStartedSeeding_mono 	= -1;
+				_timeFinished				= 0;
 
 				Logger.log(
 						new LogEvent(	disk_mgr.getTorrent(), LOGID,
 								"Turning off seeding mode for PEPeerManager"));
 			}
+						
 		}else{
 
 			if ( dm_done ){
@@ -1475,6 +1633,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 					Logger.log(
 							new LogEvent(	disk_mgr.getTorrent(), LOGID,
 									"Turning on seeding mode for PEPeerManager"));
+				
 				}
 			}
 		}
@@ -1611,6 +1770,30 @@ DiskManagerCheckRequestListener, IPFilterListener
 		return( piecePicker.hasDownloadablePiece());
 	}
 
+	public int
+	getBytesQueuedForUpload()
+	{
+		return( bytes_queued_for_upload );
+	}
+	
+	public int	
+	getNbPeersWithUploadQueued()
+	{
+		return( connections_with_queued_data );
+	}
+	    
+	public int	
+	getNbPeersWithUploadBlocked()
+	{
+		return( connections_with_queued_data_blocked );
+	}
+	
+	public int
+	getNbPeersUnchoked()
+	{
+		return( connections_unchoked );
+	}
+	
 	public int[] getAvailability() 
 	{
 		return piecePicker.getAvailability();
@@ -1786,29 +1969,108 @@ DiskManagerCheckRequestListener, IPFilterListener
 		}
 
 		//calculate seeds vs peers
-		final ArrayList peer_transports = peer_transports_cow;
+		final ArrayList<PEPeer> peer_transports = peer_transports_cow;
 
+		int	new_pending_tcp_connections 	= 0;
+		int new_connecting_tcp_connections	= 0;
+		
 		int	new_seeds = 0;
 		int new_peers = 0;
-		int newTcpRemotes = 0;
-
-		for (Iterator it=peer_transports.iterator();it.hasNext();){
+		int new_tcp_incoming 	= 0;
+		int new_udp_incoming  	= 0;
+		int new_utp_incoming  	= 0;
+		
+		int	bytes_queued 	= 0;
+		int	con_queued		= 0;
+		int con_blocked		= 0;
+		int con_unchoked	= 0;
+		
+		for ( Iterator<PEPeer> it=peer_transports.iterator();it.hasNext();){
+			
 			final PEPeerTransport pc = (PEPeerTransport) it.next();
-			if (pc.getPeerState() == PEPeer.TRANSFERING) {
+			
+			if ( pc.getPeerState() == PEPeer.TRANSFERING) {
+				
+				if ( !pc.isChokedByMe()){
+					
+					con_unchoked++;
+				}
+				
+				Connection connection = pc.getPluginConnection();
+				
+				if ( connection != null ){
+					
+					OutgoingMessageQueue mq = connection.getOutgoingMessageQueue();
+					
+					int q = mq.getDataQueuedBytes() + mq.getProtocolQueuedBytes();
+					
+					bytes_queued += q;
+					
+					if ( q > 0 ){
+						
+						con_queued++;
+						
+						if ( mq.isBlocked()){
+							
+							con_blocked++;
+						}
+					}
+				}
+				
 				if (pc.isSeed())
 					new_seeds++;
 				else
 					new_peers++;
 
-				if(pc.isIncoming() && pc.isTCP() && !pc.isLANLocal()) {
-					newTcpRemotes++;
+				if ( pc.isIncoming() && !pc.isLANLocal()){
+										
+					if ( pc.isTCP() ) {
+				
+						new_tcp_incoming++;
+						
+					}else{
+						
+						String protocol = pc.getProtocol();
+						
+						if ( protocol.equals( "UDP" )){
+						
+							new_udp_incoming++;
+							
+						}else{
+							
+							new_utp_incoming++;
+						}
+					}
+				}
+			}else{				
+				if ( pc.isTCP()){
+					
+					int c_state = pc.getConnectionState();
+
+					if ( c_state == PEPeerTransport.CONNECTION_PENDING ){
+						
+						new_pending_tcp_connections++;
+						
+					}else if ( c_state == PEPeerTransport.CONNECTION_CONNECTING ){
+						
+						new_connecting_tcp_connections++;
+					}
 				}
 			}
 		}
 
 		_seeds = new_seeds;
 		_peers = new_peers;
-		_remotesNoUdpNoLan = newTcpRemotes;
+		_remotesTCPNoLan = new_tcp_incoming;
+		_remotesUDPNoLan = new_udp_incoming;
+		_remotesUTPNoLan = new_utp_incoming;
+		_tcpPendingConnections = new_pending_tcp_connections;
+		_tcpConnectingConnections = new_connecting_tcp_connections;
+		
+		bytes_queued_for_upload 				= bytes_queued;
+		connections_with_queued_data			= con_queued;
+		connections_with_queued_data_blocked	= con_blocked;
+		connections_unchoked					= con_unchoked;
 	}
 	/**
 	 * The way to unmark a request as being downloaded, or also 
@@ -1819,8 +2081,9 @@ DiskManagerCheckRequestListener, IPFilterListener
 	{
 		final int pieceNumber =request.getPieceNumber();  //get the piece number
 		PEPiece pe_piece = pePieces[pieceNumber];
-		if (pe_piece != null )
+		if (pe_piece != null ){
 			pe_piece.clearRequested(request.getOffset() /DiskManager.BLOCK_SIZE);
+		}
 	}
 
 
@@ -1831,8 +2094,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 	}
 
 	public byte[][]
-	              getSecrets(
-	            		  int	crypto_level )
+	getSecrets(
+		int	crypto_level )
 	{
 		return( adapter.getSecrets( crypto_level ));
 	}
@@ -2125,7 +2388,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 			int 			offset, 
 			int 			length) 
 	{
-		if ( disk_mgr.checkBlockConsistencyForRead(originator.getIp(),pieceNumber, offset, length)){
+		if ( disk_mgr.checkBlockConsistencyForRead(originator.getClient() + ": " + originator.getIp(), true, pieceNumber, offset, length)){
 
 			if ( enable_seeding_piece_rechecks && isSeeding()){
 
@@ -2155,7 +2418,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 			int 			offset, 
 			int 			length) 
 	{
-		return( disk_mgr.checkBlockConsistencyForHint(originator.getIp(),pieceNumber, offset, length ));
+		return( disk_mgr.checkBlockConsistencyForHint(originator.getClient() + ": " + originator.getIp(),pieceNumber, offset, length ));
 	}
 
 	public boolean 
@@ -2165,7 +2428,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 		int 				offset, 
 		DirectByteBuffer 	data) 
 	{
-		return disk_mgr.checkBlockConsistencyForWrite(originator.getIp(),pieceNumber, offset, data);
+		return disk_mgr.checkBlockConsistencyForWrite(originator.getClient() + ": " + originator.getIp(),pieceNumber, offset, data);
 	}
 
 	public int getAvailability(int pieceNumber)
@@ -2219,11 +2482,20 @@ DiskManagerCheckRequestListener, IPFilterListener
 		return _seeds;
 	}
 
-	public int getNbRemoteConnectionsExcludingUDP() 
+	public int getNbRemoteTCPConnections() 
 	{
-		return _remotesNoUdpNoLan;
+		return _remotesTCPNoLan;
 	}
 
+	public int getNbRemoteUDPConnections() 
+	{
+		return _remotesUDPNoLan;
+	}
+	public int getNbRemoteUTPConnections() 
+	{
+		return _remotesUTPNoLan;
+	}
+	
 	public long getLastRemoteConnectionTime()
 	{
 		return( last_remote_time );
@@ -2364,7 +2636,11 @@ DiskManagerCheckRequestListener, IPFilterListener
 		}
 
 		if( added ) {
-			if ( peer.isIncoming()){
+			boolean incoming = peer.isIncoming();
+			
+			_stats.haveNewConnection( incoming );
+			
+			if ( incoming ){
 				long	connect_time = SystemTime.getCurrentTime();
 
 				if ( connect_time > last_remote_time ){
@@ -2658,19 +2934,22 @@ DiskManagerCheckRequestListener, IPFilterListener
 			superSeedPieces[piece].peerLeft();
 		}
 
-		int	reserved_piece = pc.getReservedPieceNumber();
+		int[]	reserved_pieces = pc.getReservedPieceNumbers();
 
-		if ( reserved_piece >= 0 ){
+		if ( reserved_pieces != null ){
 
-			PEPiece	pe_piece = pePieces[reserved_piece];
-
-			if ( pe_piece != null ){
-
-				String	reserved_by = pe_piece.getReservedBy();
-
-				if ( reserved_by != null && reserved_by.equals( pc.getIp())){
-
-					pe_piece.setReservedBy( null );
+			for ( int reserved_piece: reserved_pieces ){
+				
+				PEPiece	pe_piece = pePieces[reserved_piece];
+	
+				if ( pe_piece != null ){
+	
+					String	reserved_by = pe_piece.getReservedBy();
+	
+					if ( reserved_by != null && reserved_by.equals( pc.getIp())){
+	
+						pe_piece.setReservedBy( null );
+					}
 				}
 			}
 		}
@@ -2689,12 +2968,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 	 * @param piece PEPiece invoked; notifications of it's invocation need to be done
 	 * @param pieceNumber of the PEPiece 
 	 */
-	public void addPiece(final PEPiece piece, final int pieceNumber)
+	public void addPiece(final PEPiece piece, final int pieceNumber, PEPeer for_peer )
 	{
-		addPiece( piece, pieceNumber, false );
+		addPiece( piece, pieceNumber, false, for_peer );
 	}
 
-	protected void addPiece(final PEPiece piece, final int pieceNumber, final boolean force_add )
+	protected void addPiece(final PEPiece piece, final int pieceNumber, final boolean force_add, PEPeer for_peer )
 	{
 		pePieces[pieceNumber] =(PEPieceImpl)piece;
 		nbPiecesActive++;
@@ -2702,6 +2981,18 @@ DiskManagerCheckRequestListener, IPFilterListener
 			// deal with possible piece addition by scheduler loop after closdown started
 			adapter.addPiece(piece);
 		}
+		
+		final ArrayList peer_manager_listeners = peer_manager_listeners_cow;
+
+		for( int i=0; i < peer_manager_listeners.size(); i++ ) {
+			try{
+				((PEPeerManagerListener)peer_manager_listeners.get(i)).pieceAdded(this, piece, for_peer );
+						
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+		}
 	}
 
 	/** Sends messages to listeners that the piece is no longer active.  All closing
@@ -2712,9 +3003,28 @@ DiskManagerCheckRequestListener, IPFilterListener
 	public void removePiece(PEPiece pePiece, int pieceNumber) {
 		if ( pePiece != null ){
 		adapter.removePiece(pePiece);
+		} else {
+			pePiece = pePieces[pieceNumber];
 		}
 		pePieces[pieceNumber] =null;
 		nbPiecesActive--;
+		
+		if (pePiece == null) {
+			Debug.outNoStack("Trying to remove piece " + pieceNumber + " when piece is null");
+			return;
+		}
+		
+		final ArrayList peer_manager_listeners = peer_manager_listeners_cow;
+
+		for( int i=0; i < peer_manager_listeners.size(); i++ ) {
+			try{
+				((PEPeerManagerListener)peer_manager_listeners.get(i)).pieceRemoved(this, pePiece );
+						
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+		}
 	}
 
 	public int getNbActivePieces()
@@ -2727,12 +3037,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 	}
 
 //	Returns time started in ms
-	public long getTimeStarted() {
-		return _timeStarted;
+	public long getTimeStarted( boolean mono) {
+		return mono?_timeStarted_mono:_timeStarted;
 	}
 
-	public long getTimeStartedSeeding() {
-		return _timeStartedSeeding;
+	public long getTimeStartedSeeding( boolean mono) {
+		return mono?_timeStartedSeeding_mono:_timeStartedSeeding;
 	}
 
 	private byte[] computeMd5Hash(DirectByteBuffer buffer)
@@ -2783,6 +3093,11 @@ DiskManagerCheckRequestListener, IPFilterListener
 
 	public void checkCompleted(DiskManagerCheckRequest request, boolean passed)
 	{
+		if ( TEST_PERIODIC_SEEDING_SCAN_FAIL_HANDLING && ((Integer) request.getUserData()).intValue() == CHECK_REASON_SEEDING_CHECK ){
+			
+			passed = false;	
+		}
+		
 		try
 		{
 			piece_check_result_list_mon.enter();
@@ -2893,7 +3208,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 			
 			final PEPieceImpl pePiece =pePieces[pieceNumber];
 
-			if ( outcome == 1 ){
+			if ( outcome == 1 || is_metadata_download ){
 			
 			//  the piece has been written correctly
 				 
@@ -3016,7 +3331,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 									PEPeerTransport pt =getTransportFromAddress(writer);
 									
 									if (	pt !=null &&
-											pt.getReservedPieceNumber() ==-1 &&
+											pt.getReservedPieceNumbers() == null &&
 											!ip_filter.isInRange(writer, getDisplayName(),getTorrentHash())){
 									
 									bestWriter = writer;
@@ -3029,11 +3344,11 @@ DiskManagerCheckRequestListener, IPFilterListener
 							
 							if ( bestWriter !=null ){
 	
-							pePiece.setReservedBy(bestWriter);
+								pePiece.setReservedBy(bestWriter);
 								
-								bestWriter_transport.setReservedPieceNumber(pePiece.getPieceNumber());
+								bestWriter_transport.addReservedPieceNumber(pePiece.getPieceNumber());
 								
-							pePiece.setRequestable();
+								pePiece.setRequestable();
 								
 								for (int i =0; i <pePiece.getNbBlocks(); i++ ){
 								
@@ -3246,42 +3561,50 @@ DiskManagerCheckRequestListener, IPFilterListener
 		int	max_reads 		= 0;
 		int	max_reads_index = 0;
 
-		for (int i=0;i<dm_pieces.length;i++){
-
-				// skip dnd pieces
-			
-			DiskManagerPiece	dm_piece = dm_pieces[i];
+		if ( TEST_PERIODIC_SEEDING_SCAN_FAIL_HANDLING ){
 			
-			if ( !dm_piece.isDone()){
-				
-				continue;
-			}
-			
-			int	num = dm_piece.getReadCount()&0xffff;
-
-			if ( num > SEED_CHECK_WAIT_MARKER ){
-
-				// recently been checked, skip for a while
+			max_reads_index = (int)(Math.random()*dm_pieces.length);;
+			max_reads = dm_pieces[ max_reads_index ].getNbBlocks()*3;
 
-					num--;
-
-				if ( num == SEED_CHECK_WAIT_MARKER ){
+		}else{
 
-					num = 0;
+			for (int i=0;i<dm_pieces.length;i++){
+	
+					// skip dnd pieces
+				
+				DiskManagerPiece	dm_piece = dm_pieces[i];
+				
+				if ( !dm_piece.isDone()){
+					
+					continue;
 				}
-
-				dm_piece.setReadCount((short)num);
-
-			}else{
-
-				if ( num > max_reads ){
-
-					max_reads 		= num;
-					max_reads_index = i;
+				
+				int	num = dm_piece.getReadCount()&0xffff;
+	
+				if ( num > SEED_CHECK_WAIT_MARKER ){
+	
+					// recently been checked, skip for a while
+	
+						num--;
+	
+					if ( num == SEED_CHECK_WAIT_MARKER ){
+	
+						num = 0;
+					}
+	
+					dm_piece.setReadCount((short)num);
+	
+				}else{
+	
+					if ( num > max_reads ){
+	
+						max_reads 		= num;
+						max_reads_index = i;
+					}
 				}
 			}
 		}
-
+		
 		if ( max_reads > 0 ){
 
 			DiskManagerPiece	dm_piece = dm_pieces[ max_reads_index ];
@@ -3410,6 +3733,25 @@ DiskManagerCheckRequestListener, IPFilterListener
 		return( seeding_mode );
 	}
 
+	public boolean
+	isMetadataDownload()
+	{
+		return( is_metadata_download );
+	}
+	
+	public int
+	getTorrentInfoDictSize()
+	{
+		return( metadata_infodict_size );
+	}
+	  
+	public void
+	setTorrentInfoDictSize(
+		int		size )
+	{
+		metadata_infodict_size	= size;
+	}
+	  
 	public boolean isInEndGameMode() {
 		return piecePicker.isInEndGameMode();
 	}
@@ -3531,6 +3873,8 @@ DiskManagerCheckRequestListener, IPFilterListener
 		//Find a piece
 		boolean found = false;
 		SuperSeedPiece piece = null;
+		boolean loopdone = false;  // add loop status
+		
 		while(!found) {
 			piece = superSeedPieces[superSeedModeCurrentPiece];
 			if(piece.getLevel() > 0) {
@@ -3538,12 +3882,18 @@ DiskManagerCheckRequestListener, IPFilterListener
 				superSeedModeCurrentPiece++;
 				if(superSeedModeCurrentPiece >= _nbPieces) {
 					superSeedModeCurrentPiece = 0;
-
-					//quit superseed mode
-					superSeedMode = false;
-					closeAndRemoveAllPeers( "quiting SuperSeed mode", true );
-
-					return;
+					
+					if (loopdone) {  // if already been here, has been full loop through pieces, quit
+						//quit superseed mode
+						superSeedMode = false;
+						closeAndRemoveAllPeers( "quiting SuperSeed mode", true );
+						return;
+					}
+					else {                                                                                  
+						// loopdone==false --> first time here --> go through the pieces                    
+						// for a second time to check if reserved pieces have got freed due to peers leaving
+						loopdone = true;                                                                    
+					}				
 				}
 			} else {
 				found = true;
@@ -3566,6 +3916,7 @@ DiskManagerCheckRequestListener, IPFilterListener
 	}
 
 	public void updateSuperSeedPiece(PEPeer peer,int pieceNumber) {
+		// currently this gets only called from bitfield scan function in PEPeerTransportProtocol
 		if (!superSeedMode)
 			return;
 		superSeedPieces[pieceNumber].peerHasPiece(null);
@@ -3635,7 +3986,85 @@ DiskManagerCheckRequestListener, IPFilterListener
 		}
 	}
 
-
+	public int
+	getConnectTimeout(
+		int		ct_def )
+	{
+		if ( ct_def <= 0 ){
+			
+			return( ct_def );
+		}
+		
+		if ( seeding_mode ){
+			
+				// seeding mode connections are already de-prioritised so nothing to do
+			
+			return( ct_def );
+		}
+		
+		int max_sim_con = TCPConnectionManager.MAX_SIMULTANIOUS_CONNECT_ATTEMPTS;
+		
+			// high, let's not mess with things
+		
+		if ( max_sim_con >= 50 ){
+			
+			return( ct_def );
+		}
+		
+			// we have somewhat limited outbound connection limits, see if it makes sense to
+			// reduce the connect timeout to prevent connection stall due to a bunch getting
+			// stuck 'connecting' for a long time and stalling us
+		
+		int	connected			= _seeds + _peers;
+		int	connecting			= _tcpConnectingConnections;
+		int queued				= _tcpPendingConnections;
+		
+		int	not_yet_connected 	= peer_database.getDiscoveredPeerCount();
+		
+		int	max = getMaxConnections();
+		
+		int	potential = connecting + queued + not_yet_connected;
+		
+		/*
+		System.out.println( 
+				"connected=" + connected + 
+				", queued=" + queued +
+				", connecting=" + connecting +
+				", queued=" + queued +
+				", not_yet=" + not_yet_connected +
+				", max=" + max );
+		*/
+		
+			// not many peers -> don't amend
+		
+		int	lower_limit = max/4;
+		
+		if ( potential <= lower_limit || max == lower_limit ){
+		
+			return( ct_def );
+		}
+		
+			// if we got lots of potential, use minimum delay
+		
+		final int MIN_CT = 7500;
+		
+		if ( potential >= max ){
+			
+			return( MIN_CT );
+		}
+	
+			// scale between MIN and ct_def
+		
+		int pos 	= potential - lower_limit;
+		int	scale 	= max - lower_limit;
+			
+		int res =  MIN_CT + ( ct_def - MIN_CT )*(scale - pos )/scale;
+		
+		// System.out.println( "scaled->" + res );
+		
+		return( res );
+	}
+	
 	private void doConnectionChecks() 
 	{
 		//every 1 second
@@ -4273,6 +4702,12 @@ DiskManagerCheckRequestListener, IPFilterListener
 		return( hidden_piece );
 	}
 	
+	public int
+	getUploadPriority()
+	{
+		return( adapter.getUploadPriority());
+	}
+	
 	public void IPBlockedListChanged(IpFilter filter) {
 		Iterator	it = peer_transports_cow.iterator();
 		
@@ -4474,6 +4909,43 @@ DiskManagerCheckRequestListener, IPFilterListener
 		}
 	}
 	
+	public TrackerPeerSource
+	getTrackerPeerSource()
+	{
+		return(
+			new TrackerPeerSourceAdapter()
+			{
+				public int
+				getType()
+				{
+					return( TP_PEX );
+				}
+				
+				public int
+				getStatus()
+				{
+					return( isPeerExchangeEnabled()?ST_ONLINE:ST_DISABLED );
+				}
+				
+				public String
+				getName()
+				{
+					return( 
+						MessageText.getString( "tps.pex.details", 
+							new String[]{ 
+								String.valueOf( peer_transports_cow.size()), 
+								String.valueOf( peer_database.getExchangedPeerCount()),
+								String.valueOf( peer_database.getDiscoveredPeerCount())}));
+				}
+				
+				public int
+				getPeers()
+				{
+					return( peer_database.getExchangedPeersUsed());
+				}
+			});
+	}
+	
 	public void
 	generateEvidence(
 			IndentWriter		writer )
diff --git a/org/gudy/azureus2/core3/peer/impl/control/SuperSeedPiece.java b/org/gudy/azureus2/core3/peer/impl/control/SuperSeedPiece.java
index 8aa3d45..6047118 100644
--- a/org/gudy/azureus2/core3/peer/impl/control/SuperSeedPiece.java
+++ b/org/gudy/azureus2/core3/peer/impl/control/SuperSeedPiece.java
@@ -54,20 +54,28 @@ public class SuperSeedPiece {
   public void peerHasPiece(PEPeer peer) {
   	try{
   		class_mon.enter();
-  	
-	    if(level < 2) {
-	      firstReceiver = peer;
-	      timeFirstDistributed = SystemTime.getCurrentTime();
-	      //numberOfPeersWhenFirstReceived = manager.getNbPeers();
-	    } else {
-	      if(peer != null && firstReceiver != null) {
-	        timeToReachAnotherPeer = (int) (SystemTime.getCurrentTime() - timeFirstDistributed);
-	        firstReceiver.setUploadHint(timeToReachAnotherPeer);
-	      }
-	    }
-	    level = 2;
-  	}finally{
-  		
+  			//System.out.println("piece: #"+pieceNumber+" , old level:"+level+", timeFirstDistributed:"+timeFirstDistributed+ "/ timetoreachanotherpeer:"+timeToReachAnotherPeer);
+  			if(level < 2) {
+  				// first time that somebody tells us this piece exists elsewhere
+  				// if peer=null, it is due to bitfield scan, so firstreceiver gets NULL	   	 
+  				firstReceiver = peer;
+  				timeFirstDistributed = SystemTime.getCurrentTime();
+  				//numberOfPeersWhenFirstReceived = manager.getNbPeers();
+  				level = 2;
+  			}
+  			else {
+  				// level=2 or 3 and we arrive here when somebody has got the piece, either BT_HAVE or bitfield scan
+  				// if we are here due to bitfield scan, 'peer' = null --> do nothing
+  				// if level=2 --> mark piece redistributed, set speedstatus of firstreceiver, bump level to 3
+  				// if level=3 --> this piece has been already seen at 3rd party earlier, do nothing
+  				if(peer != null && firstReceiver != null && level==2) {
+  					timeToReachAnotherPeer = (int) (SystemTime.getCurrentTime() - timeFirstDistributed);
+  					firstReceiver.setUploadHint(timeToReachAnotherPeer);
+  					level = 3;
+  				}
+  			}  			
+  	}
+  	finally{  		
   		class_mon.exit();
   	}
   }
@@ -100,10 +108,13 @@ public class SuperSeedPiece {
   
   public void updateTime() {
     if(level < 2)
+   	// not yet distributed, no effect on speed status
       return;
     if(timeToReachAnotherPeer > 0)
+   	// piece has been seen elsewhere, no effect on speed status any more
       return;
     if(firstReceiver == null)
+   	// piece was found due to bitfield scan, no idea how it got distributed
       return;
     int timeToSend = (int) (SystemTime.getCurrentTime() - timeFirstDistributed);
     if(timeToSend > firstReceiver.getUploadHint())
diff --git a/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java b/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
index 79514bf..74748ac 100644
--- a/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
+++ b/org/gudy/azureus2/core3/peer/impl/transport/PEPeerTransportProtocol.java
@@ -48,9 +48,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;
 import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
 import com.aelitis.azureus.core.peermanager.messaging.Message;
 import com.aelitis.azureus.core.peermanager.messaging.MessageManager;
@@ -106,21 +104,22 @@ implements PEPeerTransport
 
 	private long lastNeededUndonePieceChange;
 
-	protected boolean choked_by_other_peer = true;
-	/** total time the other peer has unchoked us while not snubbed */
-	protected long unchokedTimeTotal;
-	/** the time at which the other peer last unchoked us when not snubbed */
-	protected long unchokedTime;
+	private boolean really_choked_by_other_peer = true;
+	private boolean effectively_choked_by_other_peer = true;
+	private long	effectively_unchoked_time = -1;
+	
 	protected boolean choking_other_peer = true;
 	private boolean interested_in_other_peer = false;
 	private boolean other_peer_interested_in_me = false;
 	private long snubbed =0;
-
+	
 	/** lazy allocation; null until needed */
 	private volatile BitFlags	peerHavePieces =null; 
 	private volatile boolean	availabilityAdded =false;
 	private volatile boolean	received_bitfield;
 
+	private int[]	piece_priority_offsets;
+	
 	private boolean handshake_sent;
 
 	private boolean seeding = false;
@@ -137,7 +136,7 @@ implements PEPeerTransport
 	protected volatile boolean closing = false;
 	private volatile int current_peer_state;
 
-	protected NetworkConnection connection;
+	final private NetworkConnection connection;
 	private OutgoingBTPieceMessageHandler outgoing_piece_message_handler;
 	private OutgoingBTHaveMessageAggregator outgoing_have_message_aggregator;
 	private Connection	plugin_connection;
@@ -155,7 +154,7 @@ implements PEPeerTransport
 	private int uniquePiece = -1;
 
 	//When downloading a piece in exclusivity mode the piece number being downloaded
-	private int reservedPiece = -1;
+	private int[] reserved_pieces = null;
 
 	//Spread time (0 secs , fake default)
 	private int spreadTimeHint = 0 * 1000;
@@ -172,26 +171,43 @@ implements PEPeerTransport
 
 	private int messaging_mode = MESSAGING_BT_ONLY;
 	private Message[] supported_messages = null;
-	private byte	other_peer_bitfield_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_cancel_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_choke_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_handshake_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_bt_have_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_az_have_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_interested_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_keep_alive_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_pex_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_piece_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_unchoke_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_uninterested_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte	other_peer_request_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-	private byte  	other_peer_bt_lt_ext_version    = BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_bitfield_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_cancel_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_choke_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_handshake_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_bt_have_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_az_have_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_interested_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_keep_alive_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_pex_version				= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_piece_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_unchoke_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_uninterested_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_request_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_suggest_piece_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_have_all_version			= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_have_none_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_reject_request_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_allowed_fast_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte  	other_peer_bt_lt_ext_version    	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
 	private byte	other_peer_az_request_hint_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
 	private byte	other_peer_az_bad_piece_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
-  
-	private boolean ut_pex_enabled = false;
-	private boolean ml_dht_enabled = false;
+	private byte	other_peer_az_stats_request_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_az_stats_reply_version	= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	private byte	other_peer_az_metadata_version		= BTMessageFactory.MESSAGE_VERSION_INITIAL;
+	
+	private static final boolean DEBUG_FAST = false;
+	
+	private boolean ut_pex_enabled 			= false;
+	private boolean fast_extension_enabled 	= false;
+	private boolean ml_dht_enabled 			= false;
 
+	private static final int	ALLOWED_FAST_PIECE_OFFERED_NUM		= 10;
+	private static final int	ALLOWED_FAST_OTHER_PEER_PIECE_MAX	= 10;
+	
+	private static final Object	KEY_ALLOWED_FAST_RECEIVED 	= new Object();
+	private static final Object	KEY_ALLOWED_FAST_SENT 		= new Object();
+	
 	private final AEMonitor closing_mon	= new AEMonitor( "PEPeerTransportProtocol:closing" );
 	private final AEMonitor general_mon  	= new AEMonitor( "PEPeerTransportProtocol:data" );
 
@@ -296,6 +312,8 @@ implements PEPeerTransport
 	
 	private static final byte[] sessionSecret;
 	
+	private static boolean enable_upload_bias;
+	
 	static {
 		rnd.setSeed(SystemTime.getHighPrecisionCounter());
 		sessionSecret = new byte[20];
@@ -304,7 +322,8 @@ implements PEPeerTransport
 		COConfigurationManager.addAndFireParameterListeners(
 				new String[]{ 
 					"Use Lazy Bitfield",
-					"Peer.Fast.Initial.Unchoke.Enabled" },
+					"Peer.Fast.Initial.Unchoke.Enabled",
+					"Bias Upload Enable" },
 				new ParameterListener()
 				{
 					public final void 
@@ -318,6 +337,8 @@ implements PEPeerTransport
 						ENABLE_LAZY_BITFIELD |= COConfigurationManager.getBooleanParameter( "Use Lazy Bitfield" );
 						
 						fast_unchoke_new_peers 		= COConfigurationManager.getBooleanParameter( "Peer.Fast.Initial.Unchoke.Enabled" );
+						
+						enable_upload_bias 			= COConfigurationManager.getBooleanParameter( "Bias Upload Enable" );
 					}
 				});
 	}
@@ -342,10 +363,17 @@ implements PEPeerTransport
 
 	private boolean request_hint_supported;
 	private boolean bad_piece_supported;
+	private boolean stats_request_supported;
+	private boolean stats_reply_supported;
+	private boolean az_metadata_supported;
 
 	private boolean have_aggregation_disabled;
 
+	private volatile boolean	manual_lazy_bitfield_control;
+	private volatile int[]		manual_lazy_haves;
 
+	private final boolean is_metadata_download;
+	
 	//INCOMING
 	public 
 	PEPeerTransportProtocol( 
@@ -361,6 +389,8 @@ implements PEPeerTransport
 		
 		incoming = true;
 
+		is_metadata_download = manager.isMetadataDownload();
+		
 		diskManager =manager.getDiskManager();
 		piecePicker =manager.getPiecePicker();
 		nbPieces =diskManager.getNbPieces();
@@ -393,9 +423,10 @@ implements PEPeerTransport
 				ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM,
 				new NetworkConnection.ConnectionListener() 
 				{
-					public final void 
-					connectStarted() {
+					public final int 
+					connectStarted( int ct ){
 						connection_state = PEPeerTransport.CONNECTION_CONNECTING;
+						return( ct );
 					}
 
 					public final void connectSuccess( ByteBuffer remaining_initial_data ) {  //will be called immediately
@@ -466,8 +497,10 @@ implements PEPeerTransport
 			byte			_crypto_level,
 			Map				_initial_user_data )
 	{
-
 		manager = _manager;
+		
+		is_metadata_download = manager.isMetadataDownload();
+
 		diskManager =manager.getDiskManager();
 		piecePicker =manager.getPiecePicker();
 		nbPieces =diskManager.getNbPieces();
@@ -501,6 +534,7 @@ implements PEPeerTransport
 
 		if( port < 0 || port > 65535 ) {
 			closeConnectionInternally( "given remote port is invalid: " + port );
+			connection = null;
 			return;
 		}
 
@@ -510,7 +544,12 @@ implements PEPeerTransport
 				_require_crypto_handshake || 
     			NetworkManager.getCryptoRequired( manager.getAdapter().getCryptoLevel()); 
 
-		if( isLANLocal() )  use_crypto = false;  //dont bother with PHE for lan peers
+		boolean	lan_local = isLANLocal();
+		
+		if ( lan_local ){
+			
+			use_crypto = false;  //dont bother with PHE for lan peers
+		}
 
 		InetSocketAddress	endpoint_address;
 		ProtocolEndpoint	pe;
@@ -519,13 +558,31 @@ implements PEPeerTransport
 
 			endpoint_address = new InetSocketAddress( ip, tcp_listen_port );
 
-			pe = new ProtocolEndpointTCP( endpoint_address );
+			int	protocol;
+			
+			if ( lan_local || !AERunStateHandler.isUDPNetworkOnly()){
+				
+				protocol = ProtocolEndpoint.PROTOCOL_TCP;
+				
+			}else{
+				
+				if ( ProtocolEndpointFactory.isHandlerRegistered( ProtocolEndpoint.PROTOCOL_UTP )){
+				
+					protocol = ProtocolEndpoint.PROTOCOL_UTP;
+					
+				}else{
+				
+					protocol = ProtocolEndpoint.PROTOCOL_TCP;
+				}
+			}
+			
+			pe = ProtocolEndpointFactory.createEndpoint( protocol, endpoint_address );
 
 		}else{
 
 			endpoint_address = new InetSocketAddress( ip, udp_listen_port );
 
-			pe = new ProtocolEndpointUDP( endpoint_address );
+			pe = ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_UDP, endpoint_address );
 		}
 
 		ConnectionEndpoint connection_endpoint	= new ConnectionEndpoint( endpoint_address );
@@ -625,10 +682,18 @@ implements PEPeerTransport
 				{
 					private boolean	connect_ok;
 					
-					public final void 
-					connectStarted() 
+					public final int 
+					connectStarted(
+						int		default_connect_timeout ) 
 					{
 						connection_state = PEPeerTransport.CONNECTION_CONNECTING;
+												
+						if ( default_connect_timeout <= 0 ){
+							
+							return( default_connect_timeout );
+						}
+						
+						return( manager.getConnectTimeout( default_connect_timeout ));
 					}
 
 					public final void 
@@ -816,7 +881,7 @@ implements PEPeerTransport
 		}
 
 		if( connection != null ) {  //can be null if close is called within ::<init>::, like when the given port is invalid
-			connection.close();
+			connection.close( reason );
 		}
 
 		if ( ip_resolver_request != null ){
@@ -908,8 +973,6 @@ implements PEPeerTransport
 			peerSessionID = oldTransport.peerSessionID;
 			peer_stats = oldTransport.peer_stats;
 			peer_stats.setPeer(this);
-			unchokedTimeTotal += oldTransport.unchokedTimeTotal;
-			unchokedTime += oldTransport.unchokedTime;
 			setSnubbed(oldTransport.isSnubbed());
 			snubbed = oldTransport.snubbed;
 			last_good_data_time = oldTransport.last_good_data_time;
@@ -986,7 +1049,7 @@ implements PEPeerTransport
 				if (supports_ltep && !supports_azmp) {
 					Logger.log(new LogAlert(this, LogAlert.UNREPEATABLE, LogAlert.AT_ERROR,
 						"AZMP support has failed in Azureus, please report this in the " + 
-						"<a href=\"http://forum.vuze.com/forum.jspa?forumID=4\">CVS bug report forum</a>.\n" +
+						"<a href=\"http://forum.vuze.com/forum.jspa?forumID=124\">bug report forum</a>.\n" +
 						"Debug data: " + ByteFormatter.nicePrint(reserved)
 					));
 				}
@@ -996,10 +1059,6 @@ implements PEPeerTransport
 		}
 	}
 
-	// We could do this in a more automated way in future, but hardcoded is simple and quick,
-	// so we'll do that instead. :)
-	static Map lt_ext_map = UTPeerExchange.ENABLED ? Collections.singletonMap("ut_pex", new Integer(1) ) : Collections.EMPTY_MAP; 
-
 	private void sendLTHandshake() {
 		String client_name = Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION;
 		int localTcpPort = TCPNetworkManager.getSingleton().getTCPListeningPortNumber();
@@ -1011,17 +1070,29 @@ implements PEPeerTransport
 		boolean require_crypto = NetworkManager.getCryptoRequired( manager.getAdapter().getCryptoLevel());
 		
 		Map data_dict = new HashMap();
-		data_dict.put("m", lt_ext_map);
+
 		data_dict.put("v", client_name);
 		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));
+		data_dict.put("upload_only", new Long(manager.isSeeding() && !( ENABLE_LAZY_BITFIELD || manual_lazy_bitfield_control )? 1L : 0L));
+		
+		int metainfo_size = is_metadata_download?0:manager.getTorrentInfoDictSize();
+		
+		if ( metainfo_size > 0 ){
+			
+			data_dict.put("metadata_size", new Integer(metainfo_size));
+		}
+		
 		InetAddress defaultV6 = NetworkAdmin.getSingleton().hasIPV6Potential(true) ? NetworkAdmin.getSingleton().getDefaultPublicAddressV6() : null;
-		if(defaultV6 != null)
+		
+		if(defaultV6 != null){
 			data_dict.put("ipv6",defaultV6.getAddress());
-		LTHandshake lt_handshake = new LTHandshake(
-				data_dict, other_peer_bt_lt_ext_version
-		);
+		}
+		
+		LTHandshake lt_handshake = new LTHandshake(data_dict, other_peer_bt_lt_ext_version );
+		
+		lt_handshake.addDefaultExtensionMappings( true, is_metadata_download || metainfo_size > 0 );
+		
 		connection.getOutgoingMessageQueue().addMessage(lt_handshake, false);
 	}
 
@@ -1067,11 +1138,12 @@ implements PEPeerTransport
 				local_udp_port,
 				local_udp2_port,
 				NetworkAdmin.getSingleton().hasIPV6Potential(true) ? NetworkAdmin.getSingleton().getDefaultPublicAddressV6() : null,
+				is_metadata_download?0:manager.getTorrentInfoDictSize(),
 				avail_ids,
 				avail_vers,
 				require_crypto ? AZHandshake.HANDSHAKE_TYPE_CRYPTO : AZHandshake.HANDSHAKE_TYPE_PLAIN,
 				other_peer_handshake_version,
-				manager.isSeeding() && !ENABLE_LAZY_BITFIELD);        
+				manager.isSeeding() && ! ( ENABLE_LAZY_BITFIELD || manual_lazy_bitfield_control ));        
 
 		connection.getOutgoingMessageQueue().addMessage( az_handshake, false );
 	}
@@ -1080,7 +1152,7 @@ implements PEPeerTransport
 
 	public boolean isDownloadPossible()
 	{
-		if (!closing &&!choked_by_other_peer)
+		if (!closing &&!effectively_choked_by_other_peer)
 		{
 			if (lastNeededUndonePieceChange <piecePicker.getNeededUndonePieceChange())
 			{
@@ -1102,7 +1174,7 @@ implements PEPeerTransport
 	}
 
 	public boolean transferAvailable() {
-		return (!choked_by_other_peer && interested_in_other_peer);
+		return (!effectively_choked_by_other_peer && interested_in_other_peer);
 	}
 
 
@@ -1178,41 +1250,74 @@ implements PEPeerTransport
 	}
 
 
-	public DiskManagerReadRequest request(final int pieceNumber, final int pieceOffset, final int pieceLength) {
-		final DiskManagerReadRequest request =manager.createDiskManagerRequest(pieceNumber, pieceOffset, pieceLength);
-		if (current_peer_state != TRANSFERING) {
+	public DiskManagerReadRequest 
+	request(
+		final int pieceNumber, 
+		final int pieceOffset, 
+		final int pieceLength) 
+	{
+		final DiskManagerReadRequest request = manager.createDiskManagerRequest(pieceNumber, pieceOffset, pieceLength);
+		
+		if ( current_peer_state != TRANSFERING ){
+			
 			manager.requestCanceled(request);
+			
 			return null;
 		}	
+		
 		boolean added =false;
+		
 		try{
 			requested_mon.enter();
 
-			if (!requested.contains(request))
-			{
+			if (!requested.contains(request)){
+				
 				requested.add(request);
-				added =true;
+				
+				added = true;
 			}
 		}finally{
 
 			requested_mon.exit();
 		}
 
-		if (added)
-		{
-            connection.getOutgoingMessageQueue().addMessage( new BTRequest( pieceNumber, pieceOffset, pieceLength, other_peer_request_version ), false );
-			_lastPiece =pieceNumber;
+		if ( added ){
+		
+			if ( is_metadata_download ){
+				
+				if ( az_metadata_supported ){
+					
+					connection.getOutgoingMessageQueue().addMessage( new AZMetaData( pieceNumber, other_peer_request_version ), false );
+
+				}else{
+					
+					connection.getOutgoingMessageQueue().addMessage( new UTMetaData( pieceNumber, other_peer_request_version ), false );
+				}
+			}else{
+            
+				connection.getOutgoingMessageQueue().addMessage( new BTRequest( pieceNumber, pieceOffset, pieceLength, other_peer_request_version ), false );
+			}
+			
+			_lastPiece = pieceNumber;
 
+			if ( DEBUG_FAST ){
+				if ( really_choked_by_other_peer ){
+				
+					System.out.println( "Sending allow-fast request for " + pieceNumber + "/" + pieceOffset + "/" + pieceLength + " to " + getIp());		
+				}
+			}
+			
 			try{
 				recent_outgoing_requests_mon.enter();
 
 				recent_outgoing_requests.put( request, null );
+				
 			}finally{
 				recent_outgoing_requests_mon.exit();
 			}
-			return request;
 		}
-		return null;
+		
+		return request;
 	}
 
 	public int
@@ -1239,6 +1344,10 @@ implements PEPeerTransport
 	}
 
 
+	private void sendHaveNone() {
+		connection.getOutgoingMessageQueue().addMessage( new BTHaveNone( other_peer_have_none_version ), false );
+	}
+	
 	public void sendHave( int pieceNumber ) {
 		if ( current_peer_state != TRANSFERING || pieceNumber == manager.getHiddenPiece()) return;
 		//only force if the other peer doesn't have this piece and is not yet interested or we;ve disabled
@@ -1259,12 +1368,7 @@ implements PEPeerTransport
 		choking_other_peer = true;
 		is_optimistic_unchoke = false;
 		
-		if(outgoing_piece_message_handler != null)
-		{
-			outgoing_piece_message_handler.removeAllPieceRequests();
-			outgoing_piece_message_handler.destroy();
-			outgoing_piece_message_handler = null;
-		}
+		destroyPieceMessageHandler();
 	}
 
 
@@ -1272,8 +1376,20 @@ implements PEPeerTransport
 		if ( current_peer_state != TRANSFERING ) return;
 
 		//System.out.println( "["+(System.currentTimeMillis()/1000)+"] " +connection + " unchoked");
-		if(outgoing_piece_message_handler == null)
-		{
+		
+		createPieceMessageHandler();
+
+		choking_other_peer = false;	// set this first as with pseudo peers we can effectively synchronously act
+		// on the unchoke advice and we don't want that borking with choked still set
+
+    connection.getOutgoingMessageQueue().addMessage( new BTUnchoke(other_peer_unchoke_version), false );
+	}
+
+	private void
+	createPieceMessageHandler()
+	{
+		if ( outgoing_piece_message_handler == null ){
+			
 			outgoing_piece_message_handler = new OutgoingBTPieceMessageHandler(
 				this,
 				connection.getOutgoingMessageQueue(),
@@ -1288,15 +1404,17 @@ implements PEPeerTransport
 			},
 			other_peer_piece_version);
 		}
-
-
-
-		choking_other_peer = false;	// set this first as with pseudo peers we can effectively synchronously act
-		// on the unchoke advice and we don't want that borking with choked still set
-
-    connection.getOutgoingMessageQueue().addMessage( new BTUnchoke(other_peer_unchoke_version), false );
 	}
-
+	
+	private void
+	destroyPieceMessageHandler()
+	{
+		if (outgoing_piece_message_handler != null ){
+			outgoing_piece_message_handler.removeAllPieceRequests();
+			outgoing_piece_message_handler.destroy();
+			outgoing_piece_message_handler = null;
+		}
+	}
 
 	private void sendKeepAlive() {
 		if ( current_peer_state != TRANSFERING ) return;
@@ -1381,13 +1499,25 @@ implements PEPeerTransport
 	 */
 	private void sendBitField()
 	{
-		if (closing)
+		if (closing){
 			return;
-
-		//In case we're in super seed mode, we don't send our bitfield
-		if (manager.isSuperSeedMode())
+		}
+		
+			//In case we're in super seed mode, we don't send our bitfield
+		
+		if (manager.isSuperSeedMode()){
+		
+				// trying this to see if it fixes issue with libtorrent (v0.15.9.0) 
+			
+			sendHaveNone();
+			
 			return;
-
+		}
+		
+		if ( is_metadata_download ){
+			return;
+		}
+		
 		//create bitfield
 		final DirectByteBuffer buffer =DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG, (nbPieces +7) /8);
 		final DiskManagerPiece[] pieces =diskManager.getPieces();
@@ -1398,7 +1528,7 @@ implements PEPeerTransport
 		HashSet	lazies 		= null;
 		int[]	lazy_haves	= null;
 		
-		if (ENABLE_LAZY_BITFIELD)
+		if (ENABLE_LAZY_BITFIELD || manual_lazy_bitfield_control )
 		{
 			int bits_in_first_byte = Math.min(num_pieces, 8);
 			int last_byte_start_bit = (num_pieces / 8) * 8;
@@ -1510,30 +1640,56 @@ implements PEPeerTransport
 		
 		if ( lazy_haves != null ){
 			
-			final int[]	f_lazy_haves = lazy_haves;
-						
-			SimpleTimer.addEvent("LazyHaveSender", SystemTime.getCurrentTime() + 1000 + rnd.nextInt(2000), new TimerEventPerformer()
-			{
-				int	next_have	= 0;
+			if ( manual_lazy_bitfield_control ){
+				
+				manual_lazy_haves = lazy_haves;
+				
+			}else{
+			
+				sendLazyHaves( lazy_haves, false );
+			}
+		}
+	}
+	
+	protected void
+	sendLazyHaves(
+		final int[]	lazy_haves,
+		boolean		immediate )
+	{
+		if ( immediate ){
+			
+			if ( current_peer_state == TRANSFERING ){
 
-				public void perform(TimerEvent event) {
-					int lazy_have = f_lazy_haves[next_have++];
-					// System.out.println( "LazyDone: " + getIp() + " -> " +
-					// lazy_have );
+				for ( int lazy_have: lazy_haves ){
 					
-					if ( current_peer_state == TRANSFERING ){
-						
-						connection.getOutgoingMessageQueue().addMessage(new BTHave(lazy_have, other_peer_bt_have_version), false);
+					connection.getOutgoingMessageQueue().addMessage(new BTHave(lazy_have, other_peer_bt_have_version), false);
+				}
+			}
+		}else{
+			
+			SimpleTimer.addEvent(
+				"LazyHaveSender", 
+				SystemTime.getCurrentTime() + 1000 + rnd.nextInt(2000), 
+				new TimerEventPerformer()
+				{
+					int	next_have	= 0;
+		
+					public void perform(TimerEvent event) {
 						
-						if (next_have < f_lazy_haves.length && current_peer_state == TRANSFERING){
+						if ( current_peer_state == TRANSFERING ){
 						
-							SimpleTimer.addEvent("LazyHaveSender", SystemTime.getCurrentTime() + rnd.nextInt(2000), this);
+							int lazy_have = lazy_haves[next_have++];
+	
+							connection.getOutgoingMessageQueue().addMessage(new BTHave(lazy_have, other_peer_bt_have_version), false);
+							
+							if ( next_have < lazy_haves.length && current_peer_state == TRANSFERING ){
+							
+								SimpleTimer.addEvent("LazyHaveSender", SystemTime.getCurrentTime() + rnd.nextInt(2000), this);
+							}
 						}
 					}
-				}
-			});
+				});
 		}
-
 	}
 
 
@@ -1561,16 +1717,14 @@ implements PEPeerTransport
 	public PEPeerStats getStats() {  return peer_stats;  }
 
 	public int[]
-	           getPriorityOffsets()
+	getPriorityOffsets()
 	{
-		// normal peer has no special priority requirements
-
-		return( null );
+		return( piece_priority_offsets );
 	}
 
 	public boolean
 	requestAllocationStarts(
-			int[]	base_priorities )
+		int[]	base_priorities )
 	{
 		return( false );
 	}
@@ -1595,7 +1749,8 @@ implements PEPeerTransport
 		return false;
 	}
 
-	public boolean isChokingMe() {  return choked_by_other_peer;  }
+	public boolean isChokingMe() {  return effectively_choked_by_other_peer;  }
+	public boolean isUnchokeOverride() {return really_choked_by_other_peer && !effectively_choked_by_other_peer; }
 	public boolean isChokedByMe() {  return choking_other_peer;  }
 	/**
 	 * @return true if the peer is interesting to us
@@ -1616,9 +1771,11 @@ implements PEPeerTransport
 
 			seeding	= s;
 
-			if ( peer_exchange_item != null && s){
+		    PeerExchangerItem pex_item = peer_exchange_item;
 
-				peer_exchange_item.seedStatusChanged();
+			if ( pex_item != null && s){
+
+				pex_item.seedStatusChanged();
 			}
 		}
 	}
@@ -1646,19 +1803,11 @@ implements PEPeerTransport
 				{
 					snubbed =0;
 					manager.decNbPeersSnubbed();
-					if (!choked_by_other_peer)
-						unchokedTime =now;
 				}
 			} else if (snubbed ==0)
 			{
 				snubbed =now;
 				manager.incNbPeersSnubbed();
-				if (!choked_by_other_peer)
-				{
-					final long unchoked =now -unchokedTime;
-					if (unchoked >0)
-						unchokedTimeTotal +=unchoked;
-				}
 			}
 		}
 	}
@@ -1829,23 +1978,6 @@ implements PEPeerTransport
 		finally{  requested_mon.exit();  }
 	}
 
-	/** @deprecated no longer used by CVS code
-	 */		
-	protected void
-	addRequest(
-			DiskManagerReadRequest	request )
-	{
-		try{
-			requested_mon.enter();
-
-			requested.add(request);
-		}finally{
-
-			requested_mon.exit();
-		}
-		_lastPiece =request.getPieceNumber();
-	}
-
 	protected void
 	removeRequest(
 			DiskManagerReadRequest	request )
@@ -1918,6 +2050,18 @@ implements PEPeerTransport
 		//PEPeerTransport.CONNECTION_CONNECTING are handled by the ConnectDisconnectManager
 		//so we don't need to deal with them here.
 
+		if ( connection != null ){
+		
+			connection.getOutgoingMessageQueue().setPriorityBoost(
+				manager.getUploadPriority() > 0 ||
+				( enable_upload_bias && !manager.isSeeding()));
+		}
+		
+		if ( fast_extension_enabled ){
+			
+			checkAllowedFast();
+		}
+		
 		final long now =SystemTime.getCurrentTime();
 		//make sure we time out stalled connections
 		if( connection_state == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED ) {
@@ -2149,6 +2293,31 @@ implements PEPeerTransport
 			}
 
 			if( close ) {
+				if ( Constants.IS_CVS_VERSION ){
+					try{
+						List<PEPeer> peers = manager.getPeers();
+						String dup_str = "?";
+						boolean	dup_ip = false;
+						for ( PEPeer p: peers ){
+							if ( p == this ){
+								continue;
+							}
+							byte[] id = p.getId();
+							if ( Arrays.equals( id, peer_id )){
+								dup_ip	= p.getIp().equals( getIp());
+								dup_str = p.getClient() + "/" + p.getClientNameFromExtensionHandshake() + "/" + p.getIp() + "/" + p.getPort();
+								break;
+							}
+						}
+						String my_str = getClient() + "/" + getIp() + "/" + getPort();
+						
+						if ( !dup_ip){
+							Debug.outNoStack( 
+								"Duplicate peer id detected: id=" + ByteFormatter.encodeString( peer_id ) + ": this=" + my_str + ",other=" + dup_str );
+						}
+					}catch( Throwable e ){
+					}
+				}
 				closeConnectionInternally( "peer matches already-connected peer id" );
 				handshake.destroy();
 				return;
@@ -2225,7 +2394,17 @@ implements PEPeerTransport
       }
 		 */
 		
-		this.ml_dht_enabled = (handshake_reserved_bytes[7] & 1) == 1; 
+		this.ml_dht_enabled = (handshake_reserved_bytes[7] & 0x01 ) == 1; 
+		
+			// disable fast if we have per-torrent upload limit as it is non-trivial to enforce for choked fast-start
+			// transfers as peer is in the multi-peer upload group (as choked) and in this mode the limit isn't
+			// enforced (see http://forum.vuze.com/thread.jspa?threadID=105262)
+		
+		fast_extension_enabled = 
+			BTHandshake.FAST_EXTENSION_ENABLED &&
+			manager.getUploadRateLimitBytesPerSecond() == 0 &&
+			(handshake_reserved_bytes[7] & 0x04) != 0;
+				
 		messaging_mode = decideExtensionProtocol(handshake);
 
 		//extended protocol processing
@@ -2244,9 +2423,18 @@ implements PEPeerTransport
 			this.ml_dht_enabled = false;
         
 			Transport transport = connection.getTransport();
-			boolean enable_padding = transport.isTCP() && transport.isEncrypted();
+			int padding_mode;
+			if ( transport.isEncrypted()){
+				if ( transport.isTCP()){
+					padding_mode = AZMessageEncoder.PADDING_MODE_NORMAL;
+				}else{
+					padding_mode = AZMessageEncoder.PADDING_MODE_MINIMAL;
+				}
+			}else{
+				padding_mode = AZMessageEncoder.PADDING_MODE_NONE;
+			}
 			connection.getIncomingMessageQueue().setDecoder(new AZMessageDecoder());
-			connection.getOutgoingMessageQueue().setEncoder(new AZMessageEncoder(enable_padding));
+			connection.getOutgoingMessageQueue().setEncoder(new AZMessageEncoder(padding_mode));
 
 			// We will wait until we get the Az handshake before considering the connection
 			// initialised.
@@ -2390,11 +2578,23 @@ implements PEPeerTransport
 	  if(AddressUtils.isGlobalAddressV6(handshake.getIPv6()))
 		  alternativeAddress = handshake.getIPv6();
 		  
-	  
-	  
 	  LTMessageEncoder encoder = (LTMessageEncoder)connection.getOutgoingMessageQueue().getEncoder();
 	  encoder.updateSupportedExtensions(handshake.getExtensionMapping());
-	  this.ut_pex_enabled = UTPeerExchange.ENABLED && encoder.supportsUTPEX();
+	  this.ut_pex_enabled = encoder.supportsUTPEX();
+
+	  if ( is_metadata_download ){
+		  
+		  if ( encoder.supportsUTMetaData()){
+			  
+			  int	mds = handshake.getMetadataSize();
+			  
+			  if ( mds > 0 ){
+				  
+				  spoofMDAvailability( mds );
+			  }
+		  }
+	  }
+	  
 	  
 	  /**
 	   * Grr... this is one thing which I'm sure I had figured out much better than it is here...
@@ -2497,6 +2697,16 @@ implements PEPeerTransport
 					other_peer_uninterested_version = supported_version;
 				else if (id == BTMessage.ID_BT_REQUEST)
 					other_peer_request_version = supported_version;
+				else if (id == BTMessage.ID_BT_SUGGEST_PIECE)
+					other_peer_suggest_piece_version = supported_version;
+				else if (id == BTMessage.ID_BT_HAVE_ALL)
+					other_peer_have_all_version = supported_version;
+				else if (id == BTMessage.ID_BT_HAVE_NONE)
+					other_peer_have_none_version = supported_version;
+				else if (id == BTMessage.ID_BT_REJECT_REQUEST)
+					other_peer_reject_request_version = supported_version;
+				else if (id == BTMessage.ID_BT_ALLOWED_FAST)
+					other_peer_allowed_fast_version = supported_version;
 				else if (id == AZMessage.ID_AZ_PEER_EXCHANGE)
 					other_peer_pex_version = supported_version;
 				else if (id == AZMessage.ID_AZ_REQUEST_HINT)
@@ -2505,6 +2715,12 @@ implements PEPeerTransport
 					other_peer_az_have_version = supported_version;
 				else if (id == AZMessage.ID_AZ_BAD_PIECE)
 					other_peer_az_bad_piece_version = supported_version;
+				else if (id == AZMessage.ID_AZ_STAT_REQUEST)
+					other_peer_az_stats_request_version = supported_version;
+				else if (id == AZMessage.ID_AZ_STAT_REPLY)
+					other_peer_az_stats_reply_version = supported_version;
+				else if (id == AZMessage.ID_AZ_METADATA)
+					other_peer_az_metadata_version = supported_version;
 				else if (id == BTMessage.ID_BT_DHT_PORT)
 					this.ml_dht_enabled = true;
 				else
@@ -2516,6 +2732,16 @@ implements PEPeerTransport
 			}
 		}
 
+		if ( is_metadata_download ){
+			
+			int	 mds = handshake.getMetadataSize();
+			
+			if ( mds > 0 ){
+				
+				  manager.setTorrentInfoDictSize( mds );
+			}
+		}
+		
 		supported_messages = (Message[]) messages.toArray(new Message[messages.size()]);
 		
 		if(outgoing_piece_message_handler != null){
@@ -2529,6 +2755,30 @@ implements PEPeerTransport
 		this.initPostConnection(handshake);
 	}
   
+  	private void
+  	spoofMDAvailability(
+  		int		mds )
+  	{
+		  int	md_pieces = ( mds + 16*1024 - 1 )/(16*1024);
+		  
+		  manager.setTorrentInfoDictSize( mds );
+		  
+		  BitFlags tempHavePieces = new BitFlags(nbPieces);
+
+		  for ( int i=0;i<md_pieces;i++){
+			  
+			  tempHavePieces.set(i);
+		  }
+
+		  peerHavePieces = tempHavePieces;
+
+		  addAvailability();
+		  
+		  really_choked_by_other_peer = false;
+		  
+		  calculatePiecePriorities();
+  	}
+  	
   	private void initPostConnection(Message handshake) {
 		changePeerState(PEPeer.TRANSFERING);
 		connection_state = PEPeerTransport.CONNECTION_FULLY_ESTABLISHED;
@@ -2538,68 +2788,199 @@ implements PEPeerTransport
 		sendMainlineDHTPort();
   	}
 
-
-	protected void decodeBitfield( BTBitfield bitfield )
+	protected void 
+	decodeHaveAll( 
+		BTHaveAll have_all )
 	{
+		have_all.destroy();
+		
 		received_bitfield = true;
 
-		final DirectByteBuffer field =bitfield.getBitfield();
-
-		final byte[] dataf =new byte[(nbPieces +7) /8];
-
-		if( field.remaining( DirectByteBuffer.SS_PEER ) < dataf.length ) {
-			final String error = toString() + " has sent invalid Bitfield: too short [" +field.remaining( DirectByteBuffer.SS_PEER )+ "<" +dataf.length+ "]";
-			Debug.out( error );
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, error ));
-			bitfield.destroy();
+		if ( is_metadata_download ){
+			
 			return;
 		}
-
-		field.get( DirectByteBuffer.SS_PEER, dataf );
-
+		
 		try{
 			closing_mon.enter();
-			if (closing)
-				bitfield.destroy();
-			else
-			{
+			
+			if ( !closing ){
+			
 				final BitFlags tempHavePieces;
-				if (peerHavePieces ==null)
-				{
-					tempHavePieces =new BitFlags(nbPieces);
-				} else
-				{
-					tempHavePieces =peerHavePieces;
+				
+				if ( peerHavePieces ==null ){
+				
+					tempHavePieces = new BitFlags(nbPieces);
+					
+				}else{
+				
+					tempHavePieces = peerHavePieces;
+					
 					removeAvailability();
 				}
-				for (int i =0; i <nbPieces; i++)
-				{
-					final int index =i /8;
-					final int bit =7 -(i %8);
-					final byte bData =dataf[index];
-					final byte b =(byte) (bData >>bit);
-					if ((b &0x01) ==1)
-					{
-						tempHavePieces.set(i);
-						manager.updateSuperSeedPiece(this,i);
-					}
+				
+				tempHavePieces.setAll();
+				
+				for ( int i=0; i<nbPieces; i++ ){
+					
+					manager.updateSuperSeedPiece( this, i );
 				}
 
-				bitfield.destroy();
+				peerHavePieces = tempHavePieces;
+				
+				addAvailability();
+
+				checkSeed();
+				
+				checkInterested();
+			}
+		}finally{
+			
+			closing_mon.exit();
+		}
+	}
+
+	protected void 
+	decodeHaveNone( 
+		BTHaveNone have_none )
+	{
+		have_none.destroy();
+		
+		received_bitfield = true;
+
+		if ( is_metadata_download ){
+			
+			return;
+		}
+		
+		try{
+			closing_mon.enter();
+			
+			if ( !closing ){
+			
+				final BitFlags tempHavePieces;
+				
+				if ( peerHavePieces ==null ){
+				
+					tempHavePieces = new BitFlags(nbPieces);
+					
+				}else{
+				
+					tempHavePieces = peerHavePieces;
+					
+					removeAvailability();
+				}
+				
+				tempHavePieces.clear();
+				
+				peerHavePieces = tempHavePieces;
+				
+					//some of these kinda pointless but whatever
+				
+				addAvailability();
+
+				checkSeed();
+				
+				checkInterested();
+				
+				checkFast( tempHavePieces );
+			}
+		}finally{
+			
+			closing_mon.exit();
+		}
+	}
+	
+	protected void decodeBitfield( BTBitfield bitfield )
+	{
+		received_bitfield = true;
+
+		if ( is_metadata_download ){
+			
+			bitfield.destroy();
+			
+			return;
+		}
+		
+		final DirectByteBuffer field =bitfield.getBitfield();
+
+		final byte[] dataf =new byte[(nbPieces +7) /8];
+
+		if( field.remaining( DirectByteBuffer.SS_PEER ) < dataf.length ) {
+			final String error = toString() + " has sent invalid Bitfield: too short [" +field.remaining( DirectByteBuffer.SS_PEER )+ "<" +dataf.length+ "]";
+			Debug.out( error );
+			if (Logger.isEnabled())
+				Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR, error ));
+			bitfield.destroy();
+			return;
+		}
+
+		field.get( DirectByteBuffer.SS_PEER, dataf );
+
+		try{
+			closing_mon.enter();
+			if (closing)
+				bitfield.destroy();
+			else
+			{
+				final BitFlags tempHavePieces;
+				if (peerHavePieces ==null)
+				{
+					tempHavePieces =new BitFlags(nbPieces);
+				} else
+				{
+					tempHavePieces =peerHavePieces;
+					removeAvailability();
+				}
+				for (int i =0; i <nbPieces; i++)
+				{
+					final int index =i /8;
+					final int bit =7 -(i %8);
+					final byte bData =dataf[index];
+					final byte b =(byte) (bData >>bit);
+					if ((b &0x01) ==1)
+					{
+						tempHavePieces.set(i);
+						manager.updateSuperSeedPiece(this,i);
+					}
+				}
+
+				bitfield.destroy();
 
 				peerHavePieces =tempHavePieces;
 				addAvailability();
 
 				checkSeed();
 				checkInterested();
+				
+				checkFast( tempHavePieces );
 			}
 		}
 		finally{
 			closing_mon.exit();
 		}
 	}
-
+	
+	public void
+	setSuspendedLazyBitFieldEnabled(
+		boolean	enable )
+	{
+		manual_lazy_bitfield_control	= enable;
+		
+		if ( !enable ){
+			
+			int[] pending = manual_lazy_haves;
+			
+			manual_lazy_haves = null;
+			
+			if ( pending != null ){
+				
+				sendLazyHaves( pending, true );
+			}
+		}
+	}
+	  
+	  
 	protected void decodeMainlineDHTPort(BTDHTPort port) {
 		int i_port = port.getDHTPort();
 		port.destroy();
@@ -2614,28 +2995,34 @@ implements PEPeerTransport
 
 	protected void decodeChoke( BTChoke choke ) {    
 		choke.destroy();
-		if (!choked_by_other_peer)
+		
+		if ( is_metadata_download ){
+			return;
+		}
+		
+		if (!really_choked_by_other_peer)
 		{
-			choked_by_other_peer = true;
+			really_choked_by_other_peer = true;
+			calculatePiecePriorities();
 			cancelRequests();
-			final long unchoked =SystemTime.getCurrentTime() -unchokedTime;
-			if (unchoked >0 &&!isSnubbed())
-				unchokedTimeTotal +=unchoked;
 		}
 	}
 
 
 	protected void decodeUnchoke( BTUnchoke unchoke ) {
 		unchoke.destroy();
-		if (choked_by_other_peer)
+		
+		if ( is_metadata_download ){
+			return;
+		}
+		
+		if (really_choked_by_other_peer)
 		{
-			choked_by_other_peer = false;
-			if (!isSnubbed())
-				unchokedTime =SystemTime.getCurrentTime();
+			really_choked_by_other_peer = false;
+			calculatePiecePriorities();
 		}
 	}
 
-
 	protected void 
 	decodeInterested( 
 		BTInterested interested ) 
@@ -2676,6 +3063,11 @@ implements PEPeerTransport
 		final int pieceNumber =have.getPieceNumber();
 		have.destroy();
 
+		if ( is_metadata_download ){
+			
+			return;
+		}
+		
 		if ((pieceNumber >=nbPieces) ||(pieceNumber <0)) {
 			closeConnectionInternally("invalid pieceNumber: " +pieceNumber);
 			return;
@@ -2810,6 +3202,7 @@ implements PEPeerTransport
   		  connection.getOutgoingMessageQueue().addMessage( bp, false );
         }
     }
+    
     protected void 
     decodeAZBadPiece( 
     	AZBadPiece bad_piece )
@@ -2821,7 +3214,52 @@ implements PEPeerTransport
         manager.badPieceReported( this, piece_number );
     }
 
+    public void
+    sendStatsRequest(
+  	  Map		request )
+    {
+  	  if ( stats_request_supported ){
+  		  
+  		  AZStatRequest	sr = new AZStatRequest( request, other_peer_az_stats_request_version );
+  		  
+  		  connection.getOutgoingMessageQueue().addMessage( sr, false );
+        }
+    }
 
+    protected void 
+    decodeAZStatsRequest( 
+    	AZStatRequest request )
+    {
+        Map req = request.getRequest();
+        
+        request.destroy();
+    
+        manager.statsRequest( this, req );
+    }
+    
+    public void
+    sendStatsReply(
+  	  Map		reply )
+    {
+  	  if ( stats_reply_supported ){
+  		  
+  		  AZStatReply	sr = new AZStatReply( reply, other_peer_az_stats_reply_version );
+  		  
+  		  connection.getOutgoingMessageQueue().addMessage( sr, false );
+        }
+    }
+
+    protected void 
+    decodeAZStatsReply( 
+    	AZStatReply reply )
+    {
+        Map rep = reply.getReply();
+        
+        reply.destroy();
+    
+        manager.statsReply( this, rep );
+    }
+    
 	protected void decodeRequest( BTRequest request ) {
 		final int number = request.getPieceNumber();
 		final int offset = request.getPieceOffset();
@@ -2838,20 +3276,89 @@ implements PEPeerTransport
 			return;
 		}
 		
-		if( !choking_other_peer ) {
-			outgoing_piece_message_handler.addPieceRequest( number, offset, length );
-			allowReconnect = true;
+		boolean	request_ok = false;
+		
+		if ( choking_other_peer ){
+			
+			try{
+				general_mon.enter();
+				
+				int[][] pieces = (int[][])getUserData( KEY_ALLOWED_FAST_SENT );
+				
+				if ( pieces != null ){
+				
+					for (int i=0;i<pieces.length;i++){
+						
+						if ( pieces[i][0] == number ){
+							
+							if ( pieces[i][1] >= length ){
+								
+								 pieces[i][1] -= length;
+								 
+								 if ( DEBUG_FAST ){
+									 System.out.println( "Permitting fast-allowed request for " + number + "/" + offset + "/" + length + " to " + getIp());
+								 }
+								 
+								 request_ok = true;
+								 
+								 createPieceMessageHandler();
+								 
+								 break;
+							}
+						}
+					}			
+				}
+			}finally{
+				
+				general_mon.exit();
+			}
+		}else{
+			
+			request_ok = true;
 		}
-		else {
+		
+		if ( request_ok ){
+		
+			if ( outgoing_piece_message_handler == null || !outgoing_piece_message_handler.addPieceRequest( number, offset, length )){
+				
+				sendRejectRequest( number, offset, length );
+			}
+			
+			allowReconnect = true;
+			
+		}else{
 			if (Logger.isEnabled())
 				Logger.log(new LogEvent(this, LOGID, "decodeRequest(): peer request for piece #"
 						+ number + ":" + offset + "->" + (offset + length -1)
 						+ " ignored as peer is currently choked."));
+			
+			sendRejectRequest( number, offset, length );
 		}
 	}
 
-
-
+	public void
+	sendRejectRequest(
+		DiskManagerReadRequest	request )
+	{
+		sendRejectRequest( request.getPieceNumber(), request.getOffset(), request.getLength());
+	}
+	
+	private void
+	sendRejectRequest(
+		int		number,
+		int		offset,
+		int		length )
+	{
+		if ( fast_extension_enabled && !closing ){
+			
+			// System.out.println( "Sending reject request " + number + "/" + offset + "/" + length + " to " + getIp());
+			
+			BTRejectRequest	reject = new BTRejectRequest( number, offset, length, other_peer_reject_request_version );
+	  		  
+	  		connection.getOutgoingMessageQueue().addMessage( reject, false );
+		}
+	}
+	
 	protected void decodePiece( BTPiece piece ) {
 		final int pieceNumber = piece.getPieceNumber();
 		final int offset = piece.getPieceOffset();
@@ -2897,6 +3404,12 @@ implements PEPeerTransport
 			return;
 		}
 
+	  if ( DEBUG_FAST ){
+		  if ( fast_extension_enabled && really_choked_by_other_peer ){
+
+			  System.out.println( "Received allow-fast piece for " + pieceNumber + "/" + offset + "/" + length + " from " + getIp());
+		  }
+	  }
 		final DiskManagerReadRequest request = manager.createDiskManagerRequest( pieceNumber, offset, length );
 		boolean piece_error = true;
 
@@ -2993,172 +3506,498 @@ implements PEPeerTransport
 			}
 		}
 
-		if( piece_error )
-			piece.destroy();
-		else
-			allowReconnect = true;		
-	}
+		if( piece_error )
+			piece.destroy();
+		else
+			allowReconnect = true;		
+	}
+
+
+
+	protected void 
+	decodeCancel( 
+		BTCancel cancel ) 
+	{
+		int number = cancel.getPieceNumber();
+		int offset = cancel.getPieceOffset();
+		int length = cancel.getLength();
+		cancel.destroy();
+		if(outgoing_piece_message_handler != null)
+			outgoing_piece_message_handler.removePieceRequest( number, offset, length );
+	}
+
+	protected void 
+	decodeRejectRequest( 
+		BTRejectRequest reject ) 
+	{
+		int number = reject.getPieceNumber();
+		int offset = reject.getPieceOffset();
+		int length = reject.getLength();
+		reject.destroy();
+		
+		final DiskManagerReadRequest request = manager.createDiskManagerRequest( number, offset, length );
+
+		if ( hasBeenRequested( request )){
+			
+			removeRequest( request );
+			
+			manager.requestCanceled( request );
+		
+				// if fast-allowed block rejected, remove from set so we don't re-request it
+			
+			try{
+				general_mon.enter();
+				
+				List<Integer> pieces = (List<Integer>)getUserData( KEY_ALLOWED_FAST_RECEIVED );
+				
+				if ( pieces != null ){
+					
+					pieces.remove( new Integer( number ));
+					
+					if ( pieces.size() == 0 ){
+						
+						setUserData( KEY_ALLOWED_FAST_RECEIVED, null );
+					}
+				}
+				
+				int[]	priorities = piece_priority_offsets;
+	
+				if ( priorities != null ){
+					
+					priorities[number] = Integer.MIN_VALUE;
+				}
+				
+				calculatePiecePriorities();
+				
+			}finally{
+				
+				general_mon.exit();
+			}
+		}
+	}
+
+	private void 
+	decodeAllowedFast( 
+		BTAllowedFast	allowed ) 
+	{
+		int	piece = allowed.getPieceNumber();
+		
+		allowed.destroy();
+				
+		if ( piecePicker.getNbPiecesDone() > ALLOWED_FAST_OTHER_PEER_PIECE_MAX ){
+			
+				// we have too many pieces already, ignore
+			
+			return;
+		}
+		
+		if ( DEBUG_FAST ){
+			System.out.println( "Received allow-fast " + piece + " from " + getIp());
+		}
+		
+		try{
+			general_mon.enter();
+			
+			List<Integer> pieces = (List<Integer>)getUserData( KEY_ALLOWED_FAST_RECEIVED );
+			
+			if ( pieces == null ){
+			
+				pieces = new ArrayList<Integer>( ALLOWED_FAST_OTHER_PEER_PIECE_MAX );
+				
+				setUserData( KEY_ALLOWED_FAST_RECEIVED, pieces );
+			}
+			
+			if ( pieces.size() < ALLOWED_FAST_OTHER_PEER_PIECE_MAX * 2 ){
+				
+				Integer i = new Integer( piece );
+						
+				if ( !pieces.contains( i ) && i >=0 && i < nbPieces ){
+					
+					pieces.add( i );
+				
+					calculatePiecePriorities();
+				}
+			}
+		}finally{
+			
+			general_mon.exit();
+		}
+	}
+	
+	private void
+	sendAllowFast(
+		int		number )
+	{
+		if ( fast_extension_enabled ){
+			
+			if ( DEBUG_FAST ){
+				System.out.println( "Sending allow-fast " + number + " to " + getIp());
+			}
+			
+			BTAllowedFast	af = new BTAllowedFast( number, other_peer_allowed_fast_version );
+	  		  
+	  		connection.getOutgoingMessageQueue().addMessage( af, false );
+		}
+	}
+
+	protected void
+	calculatePiecePriorities()
+	{
+		try{
+			general_mon.enter();
+			
+			if ( really_choked_by_other_peer ){
+				
+				List<Integer> pieces = (List<Integer>)getUserData( KEY_ALLOWED_FAST_RECEIVED );
+
+				if ( pieces == null ){
+					
+					effectively_choked_by_other_peer = true;
+					
+					piece_priority_offsets	= null;
+					
+				}else{
+										
+					int[]	priorities = piece_priority_offsets;
+					
+					if ( priorities == null ){
+						
+						priorities = new int[nbPieces];
+					
+						Arrays.fill( priorities, Integer.MIN_VALUE );
+					}
+					
+					for ( int i: pieces ){
+						
+						priorities[i] = 0;
+					}
+										
+					piece_priority_offsets = priorities;
+					
+					if ( effectively_choked_by_other_peer ){
+						
+						effectively_choked_by_other_peer = false;
+					
+						effectively_unchoked_time	= SystemTime.getMonotonousTime();
+					}
+				}
+			}else{
+				
+				if ( effectively_choked_by_other_peer ){
+				
+					effectively_choked_by_other_peer = false;
+				
+					effectively_unchoked_time	= SystemTime.getMonotonousTime();
+				}
+				
+				piece_priority_offsets = null;
+			}
+		}finally{
+			
+			general_mon.exit();
+		}
+	}
+
+	protected void
+	checkFast(
+		BitFlags	flags )
+	{		
+		if ( 	fast_extension_enabled &&
+				!(isSeed() || isRelativeSeed()) &&
+				PeerClassifier.fullySupportsFE( client_peer_id )){
+			
+				// if already has enough pieces then bail
+			
+			if ( flags.nbSet >= ALLOWED_FAST_OTHER_PEER_PIECE_MAX ){
+				
+				return;
+			}
+			
+			int[][] pieces;
+			
+			try{
+				general_mon.enter();
+				
+				pieces = (int[][])getUserData( KEY_ALLOWED_FAST_SENT );
+				
+				if ( pieces == null ){
+				
+					List<Integer> l_pieces = generateFastSet( ALLOWED_FAST_PIECE_OFFERED_NUM );
+					
+					pieces = new int[l_pieces.size()][2];
+					
+					int	piece_size = diskManager.getPieceLength();
+					
+					for ( int i=0;i<l_pieces.size(); i++ ){
+						
+						int	piece_number = l_pieces.get(i);
+						
+						pieces[i] = new int[]{ piece_number, piece_size*2 };
+					}
+					
+					setUserData( KEY_ALLOWED_FAST_SENT, pieces );
+				}
+			}finally{
+				
+				general_mon.exit();
+			}
+			
+			for ( int i=0;i<pieces.length;i++){
+				
+				int	piece_number = pieces[i][0];
+				
+				if ( !flags.flags[ piece_number ] ){
+				
+					sendAllowFast( piece_number );
+				}
+			}
+		}
+	}
+	
+	private void
+	checkAllowedFast()
+	{
+		try{
+			general_mon.enter();
+
+			if ( piecePicker.getNbPiecesDone() > ALLOWED_FAST_OTHER_PEER_PIECE_MAX ){
+		
+				List<Integer> pieces = (List<Integer>)getUserData( KEY_ALLOWED_FAST_RECEIVED );
+
+				if ( pieces != null ){
+					
+					if ( DEBUG_FAST ){
+						System.out.println( "Clearing down fast received for " + getIp());
+					}
+					
+					setUserData( KEY_ALLOWED_FAST_RECEIVED, null );
+					
+					calculatePiecePriorities();
+				}
+			}
+		
+			BitFlags flags = peerHavePieces;
+		
+			if ( flags != null && flags.nbSet >= ALLOWED_FAST_OTHER_PEER_PIECE_MAX ){
+				
+				int[][] pieces = (int[][])getUserData( KEY_ALLOWED_FAST_SENT );
+
+				if ( pieces != null ){
+					
+					if ( DEBUG_FAST ){
+						System.out.println( "Clearing down fast sent for " + getIp());
+					}
+					
+					setUserData( KEY_ALLOWED_FAST_SENT, null );
+				}
+			}
+		}finally{
+			
+			general_mon.exit();
+		}
+	}
+	
+	private void registerForMessageHandling() {
+
+		//INCOMING MESSAGES
+		connection.getIncomingMessageQueue().registerQueueListener( 
+			new IncomingMessageQueue.MessageQueueListener() 
+			{
+				public final boolean 
+				messageReceived( 
+					Message message ) 
+				{      
+					if (Logger.isEnabled())
+						Logger.log(new LogEvent(PEPeerTransportProtocol.this, LogIDs.NET,
+								"Received [" + message.getDescription() + "] message"));
+					final long now =SystemTime.getCurrentTime();
+					last_message_received_time =now;
+					if( message.getType() == Message.TYPE_DATA_PAYLOAD ) {
+						last_data_message_received_time =now;
+					}
+
+					String	message_id = message.getID();
+					
+					if( message_id.equals( BTMessage.ID_BT_PIECE ) ) {
+						decodePiece( (BTPiece)message );
+						return true;
+					}
 
+					if( closing ) {
+						message.destroy();
+						return true;
+					}
 
+					if(message_id.equals( BTMessage.ID_BT_KEEP_ALIVE ) ) {
+						message.destroy();
 
-	protected void decodeCancel( BTCancel cancel ) {
-		int number = cancel.getPieceNumber();
-		int offset = cancel.getPieceOffset();
-		int length = cancel.getLength();
-		cancel.destroy();
-		if(outgoing_piece_message_handler != null)
-			outgoing_piece_message_handler.removePieceRequest( number, offset, length );
-	}
+						//make sure they're not spamming us
+						if( !message_limiter.countIncomingMessage( message.getID(), 6, 60*1000 ) ) {  //allow max 6 keep-alives per 60sec
+							System.out.println( manager.getDisplayName() + ": Incoming keep-alive message flood detected, dropping spamming peer connection." +PEPeerTransportProtocol.this );
+							closeConnectionInternally( "Incoming keep-alive message flood detected, dropping spamming peer connection." );
+						}
 
+						return true;
+					}
 
+					if( message_id.equals( BTMessage.ID_BT_HANDSHAKE ) ) {
+						decodeBTHandshake( (BTHandshake)message );
+						return true;
+					}
 
-	private void registerForMessageHandling() {
+					if( message_id.equals( AZMessage.ID_AZ_HANDSHAKE ) ) {
+						decodeAZHandshake( (AZHandshake)message );
+						return true;
+					}
 
-		//INCOMING MESSAGES
-		connection.getIncomingMessageQueue().registerQueueListener( new IncomingMessageQueue.MessageQueueListener() {
-			public final boolean messageReceived( Message message ) {      
+					if (message_id.equals(LTMessage.ID_LT_HANDSHAKE)) {
+						decodeLTHandshake((LTHandshake)message);
+						return true;
+					}
 
-				if (Logger.isEnabled())
-					Logger.log(new LogEvent(PEPeerTransportProtocol.this, LogIDs.NET,
-							"Received [" + message.getDescription() + "] message"));
-				final long now =SystemTime.getCurrentTime();
-				last_message_received_time =now;
-				if( message.getType() == Message.TYPE_DATA_PAYLOAD ) {
-					last_data_message_received_time =now;
-				}
-            
-        String	message_id = message.getID();
+					if( message_id.equals( BTMessage.ID_BT_BITFIELD ) ) {
+						decodeBitfield( (BTBitfield)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_PIECE ) ) {
-					decodePiece( (BTPiece)message );
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_CHOKE ) ) {
+						decodeChoke( (BTChoke)message );
+						if( choking_other_peer ) {
+							connection.enableEnhancedMessageProcessing( false, manager.getPartitionID());  //downgrade back to normal handler
+						}
+						return true;
+					}
 
-				if( closing ) {
-					message.destroy();
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_UNCHOKE ) ) {
+						decodeUnchoke( (BTUnchoke)message );
+						connection.enableEnhancedMessageProcessing( true, manager.getPartitionID() );  //make sure we use a fast handler for the resulting download
+						return true;
+					}
 
-        if(message_id.equals( BTMessage.ID_BT_KEEP_ALIVE ) ) {
-					message.destroy();
+					if( message_id.equals( BTMessage.ID_BT_INTERESTED ) ) {
+						decodeInterested( (BTInterested)message );
+						return true;
+					}
 
-					//make sure they're not spamming us
-					if( !message_limiter.countIncomingMessage( message.getID(), 6, 60*1000 ) ) {  //allow max 6 keep-alives per 60sec
-						System.out.println( manager.getDisplayName() + ": Incoming keep-alive message flood detected, dropping spamming peer connection." +PEPeerTransportProtocol.this );
-						closeConnectionInternally( "Incoming keep-alive message flood detected, dropping spamming peer connection." );
+					if( message_id.equals( BTMessage.ID_BT_UNINTERESTED ) ) {
+						decodeUninterested( (BTUninterested)message );
+						return true;
 					}
 
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_HAVE ) ) {
+						decodeHave( (BTHave)message );
+						return true;
+					}
 
+					if( message_id.equals( BTMessage.ID_BT_REQUEST ) ) {
+						decodeRequest( (BTRequest)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_HANDSHAKE ) ) {
-					decodeBTHandshake( (BTHandshake)message );
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_CANCEL ) ) {
+						decodeCancel( (BTCancel)message );
+						return true;
+					}
 
-        if( message_id.equals( AZMessage.ID_AZ_HANDSHAKE ) ) {
-					decodeAZHandshake( (AZHandshake)message );
-					return true;
-				}
-        
-        if (message_id.equals(LTMessage.ID_LT_HANDSHAKE)) {
-        	decodeLTHandshake((LTHandshake)message);
-        	return true;
-        }
+					if( message_id.equals( BTMessage.ID_BT_SUGGEST_PIECE ) ) {
+						decodeSuggestPiece( (BTSuggestPiece)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_BITFIELD ) ) {
-					decodeBitfield( (BTBitfield)message );
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_HAVE_ALL ) ) {
+						decodeHaveAll( (BTHaveAll)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_CHOKE ) ) {
-					decodeChoke( (BTChoke)message );
-					if( choking_other_peer ) {
-						connection.enableEnhancedMessageProcessing( false, manager.getPartitionID());  //downgrade back to normal handler
+					if( message_id.equals( BTMessage.ID_BT_HAVE_NONE ) ) {
+						decodeHaveNone( (BTHaveNone)message );
+						return true;
 					}
-					return true;
-				}
 
-        if( message_id.equals( BTMessage.ID_BT_UNCHOKE ) ) {
-					decodeUnchoke( (BTUnchoke)message );
-					connection.enableEnhancedMessageProcessing( true, manager.getPartitionID() );  //make sure we use a fast handler for the resulting download
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_REJECT_REQUEST ) ) {
+						decodeRejectRequest( (BTRejectRequest)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_INTERESTED ) ) {
-					decodeInterested( (BTInterested)message );
-					return true;
-				}
+					if( message_id.equals( BTMessage.ID_BT_ALLOWED_FAST ) ) {
+						decodeAllowedFast( (BTAllowedFast)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_UNINTERESTED ) ) {
-					decodeUninterested( (BTUninterested)message );
-					return true;
-				}
+					if (message_id.equals(BTMessage.ID_BT_DHT_PORT)) {
+						decodeMainlineDHTPort((BTDHTPort)message);
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_HAVE ) ) {
-					decodeHave( (BTHave)message );
-					return true;
-				}
+					if( message_id.equals( AZMessage.ID_AZ_PEER_EXCHANGE ) ) {
+						decodePeerExchange( (AZPeerExchange)message );
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_REQUEST ) ) {
-					decodeRequest( (BTRequest)message );
-					return true;
-				}
+					if (message_id.equals(LTMessage.ID_UT_PEX)) {
+						decodePeerExchange((UTPeerExchange)message);
+						return true;
+					}
 
-        if( message_id.equals( BTMessage.ID_BT_CANCEL ) ) {
-					decodeCancel( (BTCancel)message );
-					return true;
-				}
-        
-        if (message_id.equals(BTMessage.ID_BT_DHT_PORT)) {
-        	decodeMainlineDHTPort((BTDHTPort)message);
-        	return true;
-        }
+					if( message_id.equals( AZMessage.ID_AZ_REQUEST_HINT ) ) {        	
+						decodeAZRequestHint( (AZRequestHint)message );
+						return true;
+					}
 
-        if( message_id.equals( AZMessage.ID_AZ_PEER_EXCHANGE ) ) {
-					decodePeerExchange( (AZPeerExchange)message );
-					return true;
-				}
-        
-        if (message_id.equals(LTMessage.ID_UT_PEX)) {
-        	decodePeerExchange((UTPeerExchange)message);
-        	return true;
-        }
+					if( message_id.equals( AZMessage.ID_AZ_HAVE ) ) {        	
+						decodeAZHave((AZHave)message );
+						return true;
+					}
 
-        if( message_id.equals( AZMessage.ID_AZ_REQUEST_HINT ) ) {        	
-					decodeAZRequestHint( (AZRequestHint)message );
-            return true;
-        }
-        
-        if( message_id.equals( AZMessage.ID_AZ_HAVE ) ) {        	
-            decodeAZHave((AZHave)message );
-            return true;
-        }
-        
-        if( message_id.equals( AZMessage.ID_AZ_BAD_PIECE ) ) {        	
-            decodeAZBadPiece((AZBadPiece)message );
-					return true;
+					if( message_id.equals( AZMessage.ID_AZ_BAD_PIECE ) ) {        	
+						decodeAZBadPiece((AZBadPiece)message );
+						return true;
+					}
+					
+					if( message_id.equals( AZMessage.ID_AZ_STAT_REQUEST ) ) {        	
+						decodeAZStatsRequest((AZStatRequest)message );
+						return true;
+					}
+					
+					if( message_id.equals( AZMessage.ID_AZ_STAT_REPLY ) ) {        	
+						decodeAZStatsReply((AZStatReply)message );
+						return true;
+					}	
+
+					if (message_id.equals(LTMessage.ID_UT_METADATA)) {
+						decodeMetaData((UTMetaData)message);
+						return true;
+					}
+					if( message_id.equals( AZMessage.ID_AZ_METADATA ) ) {        	
+						decodeMetaData((AZMetaData)message );
+						return true;
+					}
+
+					return false;
 				}
-				return false;
-			}
 
-			public final void protocolBytesReceived( int byte_count ) {
-				//update stats
-				peer_stats.protocolBytesReceived( byte_count );
-				manager.protocolBytesReceived( PEPeerTransportProtocol.this, byte_count );
-			}
+				public final void protocolBytesReceived( int byte_count ) {
+					//update stats
+					peer_stats.protocolBytesReceived( byte_count );
+					manager.protocolBytesReceived( PEPeerTransportProtocol.this, byte_count );
+				}
 
-			public final void dataBytesReceived( int byte_count ) {
-				// Observe that the peer is sending data so that if theyre so slow that the whole
-				// data block times out, we don't think theyre not sending anything at all
-				last_data_message_received_time =SystemTime.getCurrentTime();
+				public final void dataBytesReceived( int byte_count ) {
+					// Observe that the peer is sending data so that if theyre so slow that the whole
+					// data block times out, we don't think theyre not sending anything at all
+					last_data_message_received_time =SystemTime.getCurrentTime();
 
-				//update stats
-				peer_stats.dataBytesReceived( byte_count );
+					//update stats
+					peer_stats.dataBytesReceived( byte_count );
 
-				manager.dataBytesReceived( PEPeerTransportProtocol.this, byte_count );
-			}
+					manager.dataBytesReceived( PEPeerTransportProtocol.this, byte_count );
+				}
+				
+				public boolean 
+				isPriority() 
+				{
+					return( false );
+				}
 		});
 
 
@@ -3183,7 +4022,7 @@ implements PEPeerTransport
 					connection.enableEnhancedMessageProcessing( true, manager.getPartitionID() );  //so make sure we use a fast handler
 				}
 				else if( message.getID().equals( BTMessage.ID_BT_CHOKE ) ) { // is done sending piece data
-					if( choked_by_other_peer ) {
+					if( effectively_choked_by_other_peer ) {
 						connection.enableEnhancedMessageProcessing( false, manager.getPartitionID() );  //so downgrade back to normal handler
 					}
 				}
@@ -3217,16 +4056,22 @@ implements PEPeerTransport
 
 	public void
 	addRateLimiter(
-			LimitedRateGroup	limiter,
-			boolean				upload )
+		LimitedRateGroup	limiter,
+		boolean				upload )
 	{
 		connection.addRateLimiter( limiter, upload );
 	}
 
+	public LimitedRateGroup[] 
+	getRateLimiters(boolean upload) 
+	{
+		return( connection.getRateLimiters( upload ));
+	}
+	
 	public void
 	removeRateLimiter(
-			LimitedRateGroup	limiter,
-			boolean				upload )
+		LimitedRateGroup	limiter,
+		boolean				upload )
 	{
 		connection.removeRateLimiter( limiter, upload );
 	}
@@ -3267,6 +4112,19 @@ implements PEPeerTransport
 		return( received_bitfield );
 	}
 
+	public long
+	getUnchokedForMillis()
+	{
+		long	time = effectively_unchoked_time;
+		
+		if ( effectively_choked_by_other_peer || time < 0 ){
+			
+			return( -1 );
+		}
+		
+		return( SystemTime.getMonotonousTime() - time );
+	}
+	
 	public String
 	getEncryption()
 	{
@@ -3280,6 +4138,19 @@ implements PEPeerTransport
 		return( transport.getEncryption( false ));
 	}
 
+	public String
+	getProtocol()
+	{
+		Transport	transport = connection.getTransport();
+
+		if ( transport == null ){
+
+			return( "" );
+		}
+
+		return( transport.getProtocol());
+	}
+	
 	public void 
 	addListener( 
 			PEPeerListener listener ) 
@@ -3362,23 +4233,43 @@ implements PEPeerTransport
 		//peer exchange registration
 		if( manager.isPeerExchangeEnabled()) {
 			//try and register all connections for their peer exchange info
-			if(peer_exchange_item == null && canBePeerExchanged()){
-				peer_exchange_item = manager.createPeerExchangeConnection( this );
+		    PeerExchangerItem pex_item = peer_exchange_item;
+
+			if(pex_item == null && canBePeerExchanged()){
+				pex_item = peer_exchange_item = manager.createPeerExchangeConnection( this );
 			}
 			
-			if( peer_exchange_item != null ) {
+			if( pex_item != null ) {
 				//check for peer exchange support
 				if(ut_pex_enabled || peerSupportsMessageType(AZMessage.ID_AZ_PEER_EXCHANGE)) {
 					peer_exchange_supported = true;
+					
+					pex_item.enableStateMaintenance();
 				}
 				else {  //no need to maintain internal states as we wont be sending/receiving peer exchange messages
-					peer_exchange_item.disableStateMaintenance();
+					pex_item.disableStateMaintenance();
 				}
 			}
 		}
 
-		request_hint_supported = peerSupportsMessageType( AZMessage.ID_AZ_REQUEST_HINT );
+		request_hint_supported 	= peerSupportsMessageType( AZMessage.ID_AZ_REQUEST_HINT );
 		bad_piece_supported 	= peerSupportsMessageType( AZMessage.ID_AZ_BAD_PIECE );
+		stats_request_supported = peerSupportsMessageType( AZMessage.ID_AZ_STAT_REQUEST );
+		stats_reply_supported 	= peerSupportsMessageType( AZMessage.ID_AZ_STAT_REPLY );
+		az_metadata_supported 	= peerSupportsMessageType( AZMessage.ID_AZ_METADATA );
+		
+		if ( is_metadata_download ){
+
+			if ( az_metadata_supported ){
+
+				int	mds = manager.getTorrentInfoDictSize();
+
+				if ( mds > 0 ){
+
+					spoofMDAvailability( mds );
+				}
+			}
+		}
 	}
 
 	private boolean
@@ -3416,10 +4307,11 @@ implements PEPeerTransport
 	public void updatePeerExchange() {
 		if ( current_peer_state != TRANSFERING ) return;
 		if( !peer_exchange_supported )  return;
+	    PeerExchangerItem pex_item = peer_exchange_item;
 
-		if( peer_exchange_item != null && manager.isPeerExchangeEnabled()) {
-			final PeerItem[] adds = peer_exchange_item.getNewlyAddedPeerConnections();
-			final PeerItem[] drops = peer_exchange_item.getNewlyDroppedPeerConnections();  
+		if( pex_item != null && manager.isPeerExchangeEnabled()) {
+			final PeerItem[] adds = pex_item.getNewlyAddedPeerConnections();
+			final PeerItem[] drops = pex_item.getNewlyDroppedPeerConnections();  
 
 			if( (adds != null && adds.length > 0) || (drops != null && drops.length > 0) ) {
 				if (ut_pex_enabled) {
@@ -3436,41 +4328,56 @@ implements PEPeerTransport
 
 	protected void decodePeerExchange( AZStylePeerExchange exchange ) {
 		
-		// if we're seeding ignore µT-PEXed seeds, Az won't send them in the first place 
-		final PeerItem[] added = exchange instanceof UTPeerExchange ? ((UTPeerExchange)exchange).getAddedPeers(!manager.isSeeding()) : exchange.getAddedPeers();
-		final PeerItem[] dropped = exchange.getDroppedPeers();
+			// if we're seeding ignore µT-PEXed seeds, Az won't send them in the first place 
+		
+		PeerItem[] added = exchange instanceof UTPeerExchange ? ((UTPeerExchange)exchange).getAddedPeers(!( manager.isSeeding() || Constants.DOWNLOAD_SOURCES_PRETEND_COMPLETE )) : exchange.getAddedPeers();
+		PeerItem[] dropped = exchange.getDroppedPeers();
+
+		int	max_added	= exchange.getMaxAllowedPeersPerVolley(!has_received_initial_pex, true);
+		int max_dropped = exchange.getMaxAllowedPeersPerVolley(!has_received_initial_pex, false);
+		
+		exchange.destroy();
+
+			//make sure they're not spamming us
 		
-		//make sure they're not spamming us
 		if( !message_limiter.countIncomingMessage( exchange.getID(), 7, 120*1000 ) ) {  //allow max 7 PEX per 2min  //TODO reduce max after 2308 release?
 			System.out.println( manager.getDisplayName() + ": Incoming PEX message flood detected, dropping spamming peer connection." +PEPeerTransportProtocol.this );
 			closeConnectionInternally( "Incoming PEX message flood detected, dropping spamming peer connection." );
 			return;
 		}
 
-		exchange.destroy();
-
-    if(		( added != null   && added.length   > exchange.getMaxAllowedPeersPerVolley(!this.has_received_initial_pex, true)) ||
-    		( dropped != null && dropped.length > exchange.getMaxAllowedPeersPerVolley(!this.has_received_initial_pex, false))) {
+		if(		( added != null   && added.length  > max_added ) ||
+				( dropped != null && dropped.length > max_dropped )) {
     	
-			//drop these too-large messages as they seem to be used for DOS by swarm poisoners
-   			closeConnectionInternally( "Invalid PEX message received: too large, dropping likely poisoner peer connection." );
-			return;
+				// log these too-large messages and ignore them - if the swarm really is this large then
+				// we'll discover the peers soon anyway
+    	
+    		if (Logger.isEnabled()){
+    			Logger.log(
+    				new LogEvent(this, LOGID,
+    				"Invalid PEX message received: too large, ignoring this exchange. (added=" + (added==null?0:added.length) + ",dropped=" + (dropped==null?0:dropped.length) +")" ));
+    		}
+    		
+    		added 	= null;
+    		dropped	= null;
 		}
     
-    this.has_received_initial_pex = true;
+    	has_received_initial_pex = true;
 
-		if( peer_exchange_supported && peer_exchange_item != null && manager.isPeerExchangeEnabled()){
+    	PeerExchangerItem pex_item = peer_exchange_item;
+    
+		if( peer_exchange_supported && pex_item != null && manager.isPeerExchangeEnabled()){
 			if( added != null ) {
 				for( int i=0; i < added.length; i++ ) {
 					PeerItem pi = added[i];
 					manager.peerDiscovered( this, pi );
-					peer_exchange_item.addConnectedPeer( pi );
+					pex_item.addConnectedPeer( pi );
 				}
 			}
 
 			if( dropped != null ) {
 				for( int i=0; i < dropped.length; i++ ) {
-					peer_exchange_item.dropConnectedPeer( dropped[i] );
+					pex_item.dropConnectedPeer( dropped[i] );
 				}
 			}
 		}
@@ -3482,6 +4389,129 @@ implements PEPeerTransport
 		}
 	}
 
+	protected void 
+	decodeMetaData( 
+		AZUTMetaData metadata ) 
+	{
+		try{
+			final int BLOCK_SIZE = 16*1024;
+			
+			int	type = metadata.getMessageType();
+		
+			if ( type == UTMetaData.MSG_TYPE_REQUEST ){
+				
+				int	piece = metadata.getPiece();
+				
+				int total_size = manager.getTorrentInfoDictSize();
+				
+				byte[] data = total_size<=0?null:manager.getAdapter().getTorrentInfoDict( this );
+				
+				UTMetaData	reply ;
+				
+				int	offset = piece*BLOCK_SIZE;
+				
+				if ( is_metadata_download || data == null || offset >= data.length ){
+					
+					reply = new UTMetaData( piece, null, 0, other_peer_bt_lt_ext_version );
+
+				}else{
+					
+					int	to_send = Math.min( data.length - offset, BLOCK_SIZE );
+					
+					// System.out.println( "Sending ut_metadata: " + offset + "/" + to_send );
+					
+					reply = new UTMetaData( piece, ByteBuffer.wrap( data, offset, to_send ), total_size, other_peer_bt_lt_ext_version );
+				}
+				
+				connection.getOutgoingMessageQueue().addMessage( reply, false );
+
+			}else if ( type == UTMetaData.MSG_TYPE_DATA ){
+				
+				int	piece_number 		= metadata.getPiece();
+				DirectByteBuffer data 	= metadata.getMetadata();
+							
+				int	data_size 	= data.remaining( DirectByteBuffer.SS_PEER );
+				
+				int total_size	= manager.getTorrentInfoDictSize();
+
+				int	piece_count 	= (total_size+BLOCK_SIZE-1)/BLOCK_SIZE;
+				int	last_piece_size	= total_size%BLOCK_SIZE;
+				
+				if ( last_piece_size == 0 ){
+					
+					last_piece_size = BLOCK_SIZE;
+				}
+				
+				boolean	good = false;
+				
+				if ( piece_number < piece_count ){
+					
+					int	expected_size = piece_number==piece_count-1?last_piece_size:BLOCK_SIZE;
+					
+					if ( data_size == expected_size ){
+						
+						DiskManagerReadRequest request = manager.createDiskManagerRequest( piece_number, 0, BLOCK_SIZE );
+						
+						if ( hasBeenRequested( request )){
+							
+							good = true;
+							
+							metadata.setMetadata( null );
+							
+							removeRequest( request );
+							
+							long now = SystemTime.getCurrentTime();
+							
+							resetRequestsTime( now );
+							
+							manager.writeBlock( piece_number, 0, data, this, false);
+							
+							if ( last_good_data_time !=-1 && now -last_good_data_time <=60 *1000 ){
+								
+								setSnubbed( false );
+							}
+							
+							last_good_data_time = now;
+							
+							requests_completed++;
+						}
+					}
+				}
+				
+				if ( ! good ){
+					
+					peer_stats.bytesDiscarded( data_size );
+					
+					manager.discarded( this, data_size );
+					
+					requests_discarded++;
+					
+					printRequestStats();
+					
+					if (Logger.isEnabled())
+						Logger.log(new LogEvent(this, LOGID, LogEvent.LT_ERROR,
+								"metadata piece discarded as invalid."));
+					
+				}
+			}else{
+				
+				int	piece = metadata.getPiece();
+				
+				final DiskManagerReadRequest request = manager.createDiskManagerRequest( piece, 0, 16*1024 );
+
+				if ( hasBeenRequested( request )){
+					
+					removeRequest( request );
+					
+					manager.requestCanceled( request );
+				}
+			}
+		}finally{
+			
+			metadata.destroy();
+		}
+	}
+	
 	public boolean
 	sendRequestHint(
 			int		piece_number,
@@ -3504,8 +4534,36 @@ implements PEPeerTransport
 	}
 
 	protected void
+	decodeSuggestPiece(
+		BTSuggestPiece	hint )
+	{
+		int	piece_number 	= hint.getPieceNumber();
+		int	offset			= 0;
+		int	length			= manager.getPieceLength( piece_number );
+		int	life			= REQUEST_HINT_MAX_LIFE;
+
+		hint.destroy();
+
+		if ( life > REQUEST_HINT_MAX_LIFE ){
+
+			life = REQUEST_HINT_MAX_LIFE;
+		}
+
+		if ( manager.validateHintRequest( this, piece_number, offset, length )){
+
+			if ( request_hint == null ){ 
+
+				// we ignore life time currently as once hinted we don't accept another hint
+				// until that one is satisfied. This is to prevent too many pieces starting
+
+				request_hint = new int[]{ piece_number, offset, length };
+			}
+		}
+	}
+	
+	protected void
 	decodeAZRequestHint(
-			AZRequestHint	hint )
+		AZRequestHint	hint )
 	{
 		int	piece_number 	= hint.getPieceNumber();
 		int	offset			= hint.getOffset();
@@ -3545,14 +4603,77 @@ implements PEPeerTransport
 
 	public PeerItem getPeerItemIdentity() {  return peer_item_identity;  }
 
-	public int getReservedPieceNumber() {
-		return reservedPiece;
-	}
-
-	public void setReservedPieceNumber(int pieceNumber) {
-		reservedPiece = pieceNumber;
-	}
-
+	public int[]
+   	getReservedPieceNumbers() 
+   	{
+   		return( reserved_pieces );
+   	}
+    
+ 	public void 
+ 	addReservedPieceNumber(int piece_number) 
+ 	{
+ 		int[]	existing = reserved_pieces;
+ 		
+ 		if ( existing == null ){
+ 			
+ 			reserved_pieces = new int[]{ piece_number };
+ 			
+ 		}else{
+ 			
+ 			int[] updated = new int[existing.length+1];
+ 			
+ 			System.arraycopy( existing, 0, updated, 0, existing.length );
+ 					
+ 			updated[existing.length] = piece_number;
+ 			
+ 			reserved_pieces = updated;
+ 		}
+ 	}
+
+ 	public void 
+ 	removeReservedPieceNumber(int piece_number) 
+ 	{
+ 		int[]	existing = reserved_pieces;
+ 		
+ 		if ( existing != null ){
+ 			
+ 			if ( existing.length == 1 ){
+ 				
+ 				if ( existing[0] == piece_number ){
+ 				
+ 					reserved_pieces = null;
+ 				}
+ 			}else{
+ 				
+ 				int[] updated = new int[existing.length-1];
+ 				
+ 				int		pos 	= 0;
+ 				boolean	found 	= false;
+ 				
+ 				for (int i=0;i<existing.length;i++){
+ 				
+ 					int	pn = existing[i];
+ 					
+ 					if ( found || pn != piece_number ){
+ 						
+ 						if ( pos == updated.length ){
+ 							
+ 							return;
+ 						}
+ 						
+ 						updated[pos++] = pn;
+ 						
+ 					}else{
+ 						
+ 						found = true;
+ 					}
+ 				}
+ 				
+ 				reserved_pieces = updated;
+ 			}
+ 		}
+ 	}
+ 	
 	public int 
 	getIncomingRequestCount()
 	{
@@ -3682,12 +4803,6 @@ implements PEPeerTransport
 		return( connection.getEndpoint().getProtocols()[0].getType() == ProtocolEndpoint.PROTOCOL_TCP );
 	}
 
-	public long getUnchokedTimeTotal()
-	{
-		if (choked_by_other_peer)
-			return unchokedTimeTotal;
-		return unchokedTimeTotal +(SystemTime.getCurrentTime() -unchokedTime);
-	}
 
 	public void setUploadRateLimitBytesPerSecond( int bytes ){ connection.setUploadLimit( bytes ); }
 	public void setDownloadRateLimitBytesPerSecond( int bytes ){ connection.setDownloadLimit( bytes ); }
@@ -3732,17 +4847,77 @@ implements PEPeerTransport
 			return( priority_connection );
 		}
 	}
+		
+	protected static List<Integer>
+	generateFastSet(
+		byte[]		hash,
+		String		ip,
+		int			num_pieces,
+		int			num_required )
+	{
+		List<Integer>	res = new ArrayList<Integer>();
+							
+		try{
+			byte[]	address = InetAddress.getByName( ip ).getAddress();
+			
+				// no IPv6 support yet
+
+			if ( address.length == 4 ){
+				
+				byte[]	bytes = new byte[24];
+				
+				System.arraycopy( address, 0, bytes, 0, 3 );
+				System.arraycopy( hash, 0, bytes, 4, 20 );
+				
+				num_required = Math.min( num_required, num_pieces );
+				
+				while( res.size() < num_required ){
+					
+					bytes = new SHA1Simple().calculateHash( bytes );
+					
+					int	pos = 0;
+				
+					while( pos < 20 && res.size() < num_required ){
+						
+						long	index = (bytes[pos++] << 24 )&0xff000000L | 
+										(bytes[pos++] << 16 )&0x00ff0000L | 
+										(bytes[pos++] << 8  )&0x0000ff00L | 
+										bytes[pos++]&0x000000ffL;
+		
+						Integer i = new Integer((int)( index%num_pieces ));
+						
+						if ( !res.contains(i)){
+						
+							res.add( i );
+						}
+					}
+				}
+			}
+		}catch( Throwable e ){
 			
+			Debug.out( "Fast set generation failed", e );
+		}
+		
+		return( res );
+	}
+	
+	protected List<Integer>
+	generateFastSet(
+		int		num )
+	{
+		return( generateFastSet( manager.getHash(), getIp(), nbPieces, num ));	
+	}
+	
 	public void
 	generateEvidence(
 			IndentWriter	writer )
 	{
 		writer.println( 
 				"ip=" + getIp() + ",in=" + isIncoming() + ",port=" + getPort() + ",cli=" + client + ",tcp=" + getTCPListenPort() + ",udp=" + getUDPListenPort() + 
-				",oudp=" + getUDPNonDataListenPort() + ",p_state=" + getPeerState() + ",c_state=" + getConnectionState() + ",seed=" + isSeed() + "partialSeed=" + isRelativeSeed() + ",pex=" + peer_exchange_supported + ",closing=" + closing );
-		writer.println( "    choked=" + choked_by_other_peer + ",choking=" + choking_other_peer + ",unchoke_time=" + unchokedTime + ", unchoke_total=" + unchokedTimeTotal + ",is_opt=" + is_optimistic_unchoke ); 
+				",oudp=" + getUDPNonDataListenPort() + ",prot=" + getProtocol() + ",p_state=" + getPeerState() + ",c_state=" + getConnectionState() + ",seed=" + isSeed() + ",partialSeed=" + isRelativeSeed() + ",pex=" + peer_exchange_supported + ",closing=" + closing );
+		writer.println( "    choked=" + effectively_choked_by_other_peer + "/" + really_choked_by_other_peer + ",choking=" + choking_other_peer + ",is_opt=" + is_optimistic_unchoke ); 
 		writer.println( "    interested=" + interested_in_other_peer + ",interesting=" + other_peer_interested_in_me + ",snubbed=" + snubbed );
-		writer.println( "    lp=" + _lastPiece + ",up=" + uniquePiece + ",rp=" + reservedPiece );
+		writer.println( "    lp=" + _lastPiece + ",up=" + uniquePiece + ",rp=" + reserved_pieces );
 		writer.println( 
 				"    last_sent=" + last_message_sent_time + "/" + last_data_message_sent_time + 
 				",last_recv=" + last_message_received_time + "/" + last_data_message_received_time + "/" + last_good_data_time );
@@ -3792,4 +4967,23 @@ implements PEPeerTransport
 			return false;
 		}
 	}
+	
+	public static void
+	main(
+		String[]		args )
+	{
+		byte[]	 hash = new byte[20];
+		
+		Arrays.fill( hash, (byte)0xAA );
+
+		try{
+			List<Integer> res = generateFastSet( hash, "80.4.4.200", 9, 5 );
+
+			System.out.println( res );
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
 }
diff --git a/org/gudy/azureus2/core3/security/SESecurityManager.java b/org/gudy/azureus2/core3/security/SESecurityManager.java
index 95579e2..f8525c3 100644
--- a/org/gudy/azureus2/core3/security/SESecurityManager.java
+++ b/org/gudy/azureus2/core3/security/SESecurityManager.java
@@ -229,4 +229,10 @@ SESecurityManager
 	{
 		SESecurityManagerImpl.getSingleton().removeCertificateListener(l);
 	}
+	
+	public static Class[]
+	getClassContext()
+	{
+		return( SESecurityManagerImpl.getSingleton().getClassContext());
+	}
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/security/impl/SESecurityManagerImpl.java b/org/gudy/azureus2/core3/security/impl/SESecurityManagerImpl.java
index 12b2c8b..fd8b8b1 100644
--- a/org/gudy/azureus2/core3/security/impl/SESecurityManagerImpl.java
+++ b/org/gudy/azureus2/core3/security/impl/SESecurityManagerImpl.java
@@ -113,6 +113,7 @@ SESecurityManagerImpl
 	
 	protected boolean	 exit_vm_permitted	= false;
 	
+	private	AzureusSecurityManager	my_sec_man;
 	
 	protected AEMonitor	this_mon	= new AEMonitor( "SESecurityManager" );
 	
@@ -144,7 +145,7 @@ SESecurityManagerImpl
 	
 		// debug SSL with -Djavax.net.debug=ssl
 	
-		keystore_name 	= FileUtil.getUserFile(SESecurityManager.SSL_KEYS).getAbsolutePath();
+		keystore_name 		= FileUtil.getUserFile(SESecurityManager.SSL_KEYS).getAbsolutePath();
 		truststore_name 	= FileUtil.getUserFile(SESecurityManager.SSL_CERTS).getAbsolutePath();
 		
 		System.setProperty( "javax.net.ssl.trustStore", truststore_name );
@@ -192,6 +193,8 @@ SESecurityManagerImpl
 		
 		ensureStoreExists( truststore_name );
 		
+		initEmptyTrustStore();
+		
 		/*
 			try{
 				Certificate c = createSelfSignedCertificate( "Dummy", "CN=fred,OU=wap,O=wip,L=here,ST=there,C=GB", 512 );
@@ -219,6 +222,45 @@ SESecurityManagerImpl
 		*/
 	}
 	
+	private void
+	initEmptyTrustStore()
+	{
+		try{
+			File	target = new File( truststore_name );
+
+			if ( target.exists() && target.length() > 2*1024 ){
+				
+					// doesn't look very empty, bail!
+				
+				return;
+			}
+			
+			KeyStore keystore = getTrustStore();
+			
+			if ( keystore.size() == 0 ){
+				
+				File cacerts = new File( new File( new File( System.getProperty( "java.home" ), "lib" ), "security" ), "cacerts" );
+				
+				if ( cacerts.exists()){
+					
+					
+					FileUtil.copyFile( cacerts, target );
+					
+					try{
+						getTrustStore();
+						
+					}catch( Throwable e ){
+						
+						target.delete();
+						
+						ensureStoreExists( truststore_name );
+					}
+				}
+			}
+		}catch( Throwable e ){
+		}
+	}
+	
 	public String
 	getKeystoreName()
 	{
@@ -246,75 +288,10 @@ SESecurityManagerImpl
 		try{
 			final SecurityManager	old_sec_man	= System.getSecurityManager();
 			
-			System.setSecurityManager(
-				new SecurityManager()
-				{
-					public void checkAccept(String host, int port) {
-						// do nothing
-					}
-					
-					public void checkRead(String file) {
-						// do nothing
-					}
-					
-					public void checkWrite(String file) {
-						// do nothing
-					}
-					
-					public void 
-					checkExit(int status) 
-					{
-						if ( old_sec_man != null ){
-						
-							old_sec_man.checkExit( status );
-						}
-						
-						if ( !exit_vm_permitted ){
-							
-							throw( new SecurityException( "VM exit operation prohibited"));
-						}
-					}
-					
-					public void 
-					checkPermission(Permission perm)
-					{						
-						if ( perm instanceof RuntimePermission && perm.getName().equals( "stopThread")){
-							
-							synchronized( stoppable_threads ){
-								
-								if ( stoppable_threads.contains( Thread.currentThread())){
-									
-									return;
-								}
-							}
-							
-							throw( new SecurityException( "Thread.stop operation prohibited"));
-						}
-						
-						if ( old_sec_man != null ){
-							
-							old_sec_man.checkPermission( perm );
-						}
-					}
-					
-					public void 
-					checkPermission(
-						Permission 	perm, 
-						Object 		context) 
-					{
-						
-						if ( perm instanceof RuntimePermission && perm.getName().equals( "stopThread")){
-							
-							throw( new SecurityException( "Thread.stop operation prohibited"));
-						}
-						
-						if ( old_sec_man != null ){
-							
-							old_sec_man.checkPermission( perm, context );
-						}
-					}
-	
-				});
+			my_sec_man = new AzureusSecurityManager( old_sec_man );
+			
+			System.setSecurityManager( my_sec_man );
+
 		}catch( Throwable e ){
 			
 			Debug.printStackTrace(e);
@@ -1289,6 +1266,130 @@ SESecurityManagerImpl
 		}
 	}
 	
+	public Class[]
+	getClassContext()
+	{
+		if ( my_sec_man == null ){
+			
+			return( new Class[0] );
+		}
+		
+		return( my_sec_man.getClassContext());
+	}
+	
+	private final class
+	AzureusSecurityManager
+		extends SecurityManager
+	{
+		private SecurityManager	old_sec_man;
+		
+		private
+		AzureusSecurityManager(
+			SecurityManager		_old_sec_man )
+		{
+			old_sec_man 	= _old_sec_man;
+		}
+		
+		public void checkAccept(String host, int port) {
+			// do nothing
+		}
+		
+		public void checkRead(String file) {
+			// do nothing
+		}
+		
+		public void checkWrite(String file) {
+			// do nothing
+		}
+		
+		public void checkConnect(String host, int port) {
+		}
+
+		public void 
+		checkExit(int status) 
+		{
+			if ( old_sec_man != null ){
+			
+				old_sec_man.checkExit( status );
+			}
+			
+			if ( !exit_vm_permitted ){
+				
+				String	prop = System.getProperty( "azureus.security.manager.permitexit", "0" );
+
+				if ( prop.equals( "0" )){
+				
+					throw( new SecurityException( "VM exit operation prohibited"));
+				}
+			}
+		}
+		
+		public void 
+		checkPermission(
+			Permission perm )
+		{						
+			checkPermission( perm, null );
+		}
+		
+		public void 
+		checkPermission(
+			Permission 	perm, 
+			Object 		context) 
+		{
+			if ( perm instanceof RuntimePermission ){
+				
+				String name = perm.getName();
+			
+				if ( name.equals( "stopThread")){
+				
+					synchronized( stoppable_threads ){
+						
+						if ( stoppable_threads.contains( Thread.currentThread())){
+							
+							return;
+						}
+					}
+					
+					throw( new SecurityException( "Thread.stop operation prohibited"));
+					
+				}else if ( name.equals( "setSecurityManager" )){
+					
+					throw( new SecurityException( "Permission Denied"));
+				}
+			}
+			
+			if ( old_sec_man != null ){
+				
+				if ( context == null ){
+				
+					old_sec_man.checkPermission( perm );
+					
+				}else{
+					
+					old_sec_man.checkPermission( perm, context );
+				}
+			}
+		}
+
+		public Class[]
+		getClassContext()
+		{
+			Class[] res = super.getClassContext();
+			
+			if ( res.length <= 3 ){
+				
+				return( new Class[0] );
+			}
+			
+			Class[] trimmed = new Class[res.length-3];
+			
+			System.arraycopy( res, 3, trimmed, 0, trimmed.length );
+			
+			return( trimmed );
+		}
+		
+	};
+	
 	public static void
 	main(
 		String[]	args )
diff --git a/org/gudy/azureus2/core3/torrent/TOTorrent.java b/org/gudy/azureus2/core3/torrent/TOTorrent.java
index 3115869..ae40671 100644
--- a/org/gudy/azureus2/core3/torrent/TOTorrent.java
+++ b/org/gudy/azureus2/core3/torrent/TOTorrent.java
@@ -131,6 +131,9 @@ TOTorrent
 	  * @exception	can fail if re-reading of piece hashes for space spacing fails 
 	  */
 	
+	public boolean
+	isDecentralised();
+	
 	public byte[][]
 	getPieces()
 	
@@ -338,6 +341,14 @@ TOTorrent
 		  
 	   throws TOTorrentException;
 
+   public void
+   addListener(
+	  TOTorrentListener		l );
+   
+   public void
+   removeListener(
+	  TOTorrentListener		l );
+   
    public AEMonitor
    getMonitor();
 
@@ -347,4 +358,11 @@ TOTorrent
 	  */
 	public void
 	print();
+
+	/**
+	 * Retrieves the utf8 name of the torrent ONLY if the torrent specified one
+	 * in it's info map.  Otherwise, returns null (you'll have to use getName()
+	 * and decode it yourself)
+	 */
+	String getUTF8Name();
 }
diff --git a/org/gudy/azureus2/core3/torrent/TOTorrentCreator.java b/org/gudy/azureus2/core3/torrent/TOTorrentCreator.java
index b035221..e0252a8 100644
--- a/org/gudy/azureus2/core3/torrent/TOTorrentCreator.java
+++ b/org/gudy/azureus2/core3/torrent/TOTorrentCreator.java
@@ -30,11 +30,29 @@ package org.gudy.azureus2.core3.torrent;
 public interface 
 TOTorrentCreator 
 {
+		/**
+		 * A 'layout descriptor' is a file that explicitly details the construction of the torrent from a collection of files, rather than relying
+		 * on a natural file system structure.
+		 * The file is bencoded and consists of a Map with a List<Map> called 'file_map'. The sub-maps have two entries: <logical_path>, <target>
+		 * <logical_path> is a list of Strings that correspond to a virtual folder structure and the logical file name
+		 * <target> is the absolute path of the physical file or dir
+		 * @param b
+		 */
+	
+	public void
+	setFileIsLayoutDescriptor(
+		boolean		b );
+	
 	public TOTorrent
 	create()
 	
 		throws TOTorrentException;
 	
+	public long
+	getTorrentDataSizeFromFileOrDir()
+	
+		throws TOTorrentException;
+		
 	public void
 	cancel();
 	
diff --git a/org/gudy/azureus2/core3/torrent/TOTorrentFactory.java b/org/gudy/azureus2/core3/torrent/TOTorrentFactory.java
index 5ad86a0..33c3b76 100644
--- a/org/gudy/azureus2/core3/torrent/TOTorrentFactory.java
+++ b/org/gudy/azureus2/core3/torrent/TOTorrentFactory.java
@@ -144,7 +144,7 @@ TOTorrentFactory
 	
 		throws TOTorrentException
 	{
-		return( TOTorrentCreateImpl.create( file, announce_url, add_hashes, piece_length ));
+		return( new TOTorrentCreatorImpl( file, announce_url, add_hashes, piece_length ));
 	}
 	
 		// construction methods: variable piece size	
@@ -207,7 +207,7 @@ TOTorrentFactory
 	
 		throws TOTorrentException
 	{
-		return( TOTorrentCreateImpl.create(
+		return( new TOTorrentCreatorImpl(
 					file, announce_url, add_hashes, piece_min_size, piece_max_size,
 					piece_num_lower, piece_num_upper ));
 
@@ -215,9 +215,16 @@ TOTorrentFactory
 	
 	public static long
 	getTorrentDataSizeFromFileOrDir(
-		File			file_or_dir )
+		File			file_or_dir_or_desc,
+		boolean			is_layout_descriptor )
+	
+		throws TOTorrentException
 	{
-		return( TOTorrentCreateImpl.getTorrentDataSizeFromFileOrDir( file_or_dir ));
+		TOTorrentCreatorImpl	creator = new TOTorrentCreatorImpl( file_or_dir_or_desc );
+		
+		creator.setFileIsLayoutDescriptor( is_layout_descriptor );
+		
+		return( creator.getTorrentDataSizeFromFileOrDir());
 	}	
 	
 	public static long
diff --git a/org/gudy/azureus2/core3/torrent/TOTorrentListener.java b/org/gudy/azureus2/core3/torrent/TOTorrentListener.java
new file mode 100644
index 0000000..383fabe
--- /dev/null
+++ b/org/gudy/azureus2/core3/torrent/TOTorrentListener.java
@@ -0,0 +1,33 @@
+/*
+ * Created on Dec 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 org.gudy.azureus2.core3.torrent;
+
+public interface 
+TOTorrentListener 
+{
+	public static final int CT_ANNOUNCE_URLS	= 1;
+	
+	public void
+	torrentChanged(
+		TOTorrent		torrent,
+		int				change_type );
+}
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentAnnounceURLGroupImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentAnnounceURLGroupImpl.java
index e42e50c..520c86f 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentAnnounceURLGroupImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentAnnounceURLGroupImpl.java
@@ -52,6 +52,8 @@ TOTorrentAnnounceURLGroupImpl
 		new_sets[new_sets.length-1] = set;
 		
 		sets = new_sets;
+		
+		torrent.fireChanged( TOTorrentListener.CT_ANNOUNCE_URLS );
 	}
 	
 	public TOTorrentAnnounceURLSet[]
@@ -65,6 +67,8 @@ TOTorrentAnnounceURLGroupImpl
 		TOTorrentAnnounceURLSet[]	_sets )
 	{
 		sets = _sets;	
+		
+		torrent.fireChanged( TOTorrentListener.CT_ANNOUNCE_URLS );
 	}
 		
 	
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreateImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreateImpl.java
index f9c00ac..3ab7be8 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreateImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreateImpl.java
@@ -24,6 +24,7 @@ package org.gudy.azureus2.core3.torrent.impl;
 import java.io.*;
 import java.net.*;
 import java.util.*;
+import java.util.zip.GZIPOutputStream;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.*;
@@ -34,72 +35,31 @@ TOTorrentCreateImpl
 	extends		TOTorrentImpl
 	implements	TOTorrentFileHasherListener
 {	
-	protected File							torrent_base;
-	protected long							piece_length;
+	private File							torrent_base;
+	private long							piece_length;
 	
-	protected TOTorrentFileHasher			file_hasher;
+	private TOTorrentFileHasher			file_hasher;
 	
-	protected long	total_file_size		= -1;
-	protected long	total_file_count	= 0;
+	private long	total_file_size		= -1;
+	private long	total_file_count	= 0;
 	
-	protected long							piece_count;
-	protected boolean						add_other_hashes;
+	private long							piece_count;
+	private boolean							add_other_hashes;
 	
-	protected List							progress_listeners = new ArrayList();
+	private List<TOTorrentProgressListener>							progress_listeners = new ArrayList<TOTorrentProgressListener>();
 	
-	protected int	reported_progress;
+	private int	reported_progress;
 		
-	protected Set	ignore_set = new HashSet();
+	private Set<String>	ignore_set = new HashSet<String>();
 	
-	protected boolean	cancelled;
-	
-	public static TOTorrentCreator
-	create(
-		File						_torrent_base,
-		URL							_announce_url,
-		boolean						_add_other_hashes,
-		long						_piece_length )
-		
-		throws TOTorrentException
-	{
-		TOTorrentCreateImpl	t = 
-			new TOTorrentCreateImpl(
-					_torrent_base,
-					_announce_url,
-					_add_other_hashes,
-					_piece_length );
-		
-		return( new TOTorrentCreatorImpl( t ));
-	}
-	
-	public static TOTorrentCreator
-	create(	
-		File						_torrent_base,
-		URL							_announce_url,
-		boolean						_add_other_hashes,
-		long						_piece_min_size,
-		long						_piece_max_size,
-		long						_piece_num_lower,
-		long						_piece_num_upper )
-	
-		throws TOTorrentException
-	{
-		TOTorrentCreateImpl	t = 
-			new TOTorrentCreateImpl(
-					_torrent_base,
-					_announce_url,
-					_add_other_hashes,
-					_piece_min_size,
-					_piece_max_size,
-					_piece_num_lower,
-					_piece_num_upper );
-		
-		return( new TOTorrentCreatorImpl( t ));
-	}
+	private Map<String,File>	linkage_map;
+	private Map<String,String>	linked_tf_map = new HashMap<String, String>();
 	
+	private boolean	cancelled;
 	
 	protected
 	TOTorrentCreateImpl(
+		Map<String,File>			_linkage_map,
 		File						_torrent_base,
 		URL							_announce_url,
 		boolean						_add_other_hashes,
@@ -109,6 +69,7 @@ TOTorrentCreateImpl
 	{
 		super( _torrent_base.getName(), _announce_url, _torrent_base.isFile());
 			
+		linkage_map 		= _linkage_map;
 		torrent_base		= _torrent_base;
 		piece_length		= _piece_length;
 		add_other_hashes	= _add_other_hashes;
@@ -116,6 +77,7 @@ TOTorrentCreateImpl
 	
 	protected
 	TOTorrentCreateImpl(	
+		Map<String,File>			_linkage_map,
 		File						_torrent_base,
 		URL							_announce_url,
 		boolean						_add_other_hashes,
@@ -128,6 +90,7 @@ TOTorrentCreateImpl
 	{
 		super( _torrent_base.getName(), _announce_url, _torrent_base.isFile());
 		
+		linkage_map 		= _linkage_map;
 		torrent_base		= _torrent_base;
 		add_other_hashes	= _add_other_hashes;
 		
@@ -140,8 +103,49 @@ TOTorrentCreateImpl
 	create()
 	
 		throws TOTorrentException
-	{
+	{			
 		constructFixed( torrent_base, piece_length );
+		
+		if ( linkage_map.size() != linked_tf_map.size()){
+			
+			throw( new TOTorrentException( "TOTorrentCreate: unresolved linkages: required=" + linkage_map + ", resolved=" + linked_tf_map,
+					TOTorrentException.RT_DECODE_FAILS));
+		}
+		
+		if ( linked_tf_map.size() > 0 ){
+			
+			Map	m = getAdditionalMapProperty( TOTorrent.AZUREUS_PRIVATE_PROPERTIES );
+			
+			if ( m == null ){
+				
+				m = new HashMap();
+				
+				setAdditionalMapProperty( TOTorrent.AZUREUS_PRIVATE_PROPERTIES, m );
+			}
+			
+			if ( linked_tf_map.size() < 100 ){
+			
+				m.put( TorrentUtils.TORRENT_AZ_PROP_INITIAL_LINKAGE, linked_tf_map );
+				
+			}else{
+				
+				ByteArrayOutputStream baos = new ByteArrayOutputStream( 100*1024 );
+				
+				try{
+					GZIPOutputStream gos = new GZIPOutputStream( baos );
+					
+					gos.write( BEncoder.encode( linked_tf_map ));
+					
+					gos.close();
+					
+					m.put( TorrentUtils.TORRENT_AZ_PROP_INITIAL_LINKAGE2, baos.toByteArray() );
+					
+				}catch( Throwable e ){
+					
+					throw( new TOTorrentException( "Failed to serialise linkage", TOTorrentException.RT_WRITE_FAILS ));
+				}
+			}
+		}
 	}
 	
 	protected void
@@ -192,8 +196,15 @@ TOTorrentCreateImpl
 		}
 		
 		if ( getSimpleTorrent()){
-							
-			long length = file_hasher.add( _torrent_base );
+						
+			File link = linkage_map.get( _torrent_base.getName());
+			
+			if ( link != null ){
+				
+				linked_tf_map.put( "0", link.getAbsolutePath());
+			}
+			
+			long length = file_hasher.add( link==null?_torrent_base:link );
 		
 			setFiles( new TOTorrentFileImpl[]{ new TOTorrentFileImpl( this, 0, length, new byte[][]{ getName()})});
 			
@@ -201,13 +212,13 @@ TOTorrentCreateImpl
 
 		}else{
 		
-			Vector	encoded = new Vector();
+			List<TOTorrentFileImpl>	encoded = new ArrayList<TOTorrentFileImpl>();
 		
-			processDir( file_hasher, _torrent_base, encoded, "" );
+			processDir( file_hasher, _torrent_base, encoded, _torrent_base.getName(), "" );
 		
 			TOTorrentFileImpl[] files = new TOTorrentFileImpl[ encoded.size()];
 		
-			encoded.copyInto( files );
+			encoded.toArray( files );
 		
 			setFiles( files );
 		}
@@ -229,10 +240,11 @@ TOTorrentCreateImpl
 	
 	protected void
 	processDir(
-		TOTorrentFileHasher	hasher,
-		File				dir,
-		Vector				encoded,
-		String				root )
+		TOTorrentFileHasher			hasher,
+		File						dir,
+		List<TOTorrentFileImpl>		encoded,
+		String						base_name,
+		String						root )
 		
 		throws TOTorrentException
 	{
@@ -247,7 +259,7 @@ TOTorrentCreateImpl
 			// sort contents so that multiple encodes of a dir always
 			// generate same torrent
 		
-		List file_list = new ArrayList(Arrays.asList(dir_file_list));
+		List<File> file_list = new ArrayList<File>(Arrays.asList(dir_file_list));
 		
 		Collections.sort(file_list);
 		
@@ -268,7 +280,7 @@ TOTorrentCreateImpl
 						file_name = root + File.separator + file_name ;
 					}
 					
-					processDir( hasher, file, encoded, file_name );
+					processDir( hasher, file, encoded, base_name, file_name );
 					
 				}else{
 						
@@ -279,9 +291,16 @@ TOTorrentCreateImpl
 							file_name = root + File.separator + file_name;
 						}
 						
-						long length = hasher.add( file );
+						File link = linkage_map.get( base_name + File.separator + file_name );
+						
+						if ( link != null ){
 							
-						TOTorrentFileImpl	tf = new TOTorrentFileImpl( this, offset, length, file_name);
+							linked_tf_map.put( String.valueOf( encoded.size()), link.getAbsolutePath());
+						}
+						
+						long length = hasher.add( link==null?file:link );
+							
+						TOTorrentFileImpl	tf = new TOTorrentFileImpl( this, offset, length, file_name );
 						
 						offset += length;
 						
@@ -297,7 +316,7 @@ TOTorrentCreateImpl
 							tf.setAdditionalProperty( "ed2k", ed2k_digest );
 						}
 						
-						encoded.addElement( tf );
+						encoded.add( tf );
 					}
 				}
 			}
@@ -357,7 +376,7 @@ TOTorrentCreateImpl
 	{
 		report( "Torrent.create.progress.parsingfiles" );
 		
-		long res = getTotalFileSizeSupport( file );
+		long res = getTotalFileSizeSupport( file, "" );
 		
 		report( "Torrent.create.progress.totalfilesize", res );
 
@@ -368,7 +387,8 @@ TOTorrentCreateImpl
 	
 	protected long
 	getTotalFileSizeSupport(
-		File				file )
+		File				file,
+		String				root )
 		
 		throws TOTorrentException
 	{
@@ -391,7 +411,14 @@ TOTorrentCreateImpl
 				
 				total_file_count++;
 			
-				return( file.length());
+				if ( root.length() > 0 ){
+					
+					name = root + File.separator + name;
+				}
+				
+				File link = linkage_map.get( name );
+				
+				return( link==null?file.length():link.length());
 				
 			}else{
 				
@@ -410,9 +437,17 @@ TOTorrentCreateImpl
 			
 			long	length = 0;
 			
+			if ( root.length() == 0 ){
+				
+				root = name;
+			}else{
+				
+				root = root + File.separator + name;
+			}
+			
 			for (int i=0;i<dir_files.length;i++){
 				
-				length += getTotalFileSizeSupport( dir_files[i] );
+				length += getTotalFileSizeSupport( dir_files[i], root );
 			}
 			
 			return( length );
@@ -452,49 +487,7 @@ TOTorrentCreateImpl
 			}
 		}
 	}
-	
-	protected static long
-	getTorrentDataSizeFromFileOrDirSupport(
-		File				file )
-	{
-		String	name = file.getName();
-		
-		if ( name.equals( "." ) || name.equals( ".." )){
-			
-			return( 0 );
-		}
-		
-		if ( !file.exists()){
-		
-			return(0);
-		}
-		
-		if ( file.isFile()){
-						
-			return( file.length());
-			
-		}else{
-			
-			File[]	dir_files = file.listFiles();
-			
-			long	length = 0;
-			
-			for (int i=0;i<dir_files.length;i++){
-				
-				length += getTorrentDataSizeFromFileOrDirSupport( dir_files[i] );
-			}
-			
-			return( length );
-		}
-	}
-	
-	public static long
-	getTorrentDataSizeFromFileOrDir(
-		File			file_or_dir )
-	{
-		return( getTorrentDataSizeFromFileOrDirSupport( file_or_dir ));
-	}	
-	
+
 	public static long
 	getComputedPieceSize(
 		long 	total_size,
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreatorImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreatorImpl.java
index 8de742b..686d2dd 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreatorImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentCreatorImpl.java
@@ -27,19 +27,87 @@ package org.gudy.azureus2.core3.torrent.impl;
  *
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+
 import org.gudy.azureus2.core3.torrent.*;
+import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
+import org.gudy.azureus2.core3.util.BDecoder;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.FileUtil;
 
 public class
 TOTorrentCreatorImpl
 	implements TOTorrentCreator
 {
+	private File					torrent_base;
+	private URL						announce_url;
+	private boolean					add_other_hashes;
+	private long					piece_length;
+	private long 					piece_min_size;
+	private long 					piece_max_size;
+	private long 					piece_num_lower;
+	private long 					piece_num_upper;
+	
+	private boolean					is_desc;
+	
+	private Map<String,File>		linkage_map		= new HashMap<String, File>();
+	private File					descriptor_dir;
+	
 	private TOTorrentCreateImpl		torrent;
+
+	private List<TOTorrentProgressListener>	listeners = new ArrayList<TOTorrentProgressListener>();
 	
-	protected
+	public 
 	TOTorrentCreatorImpl(
-		TOTorrentCreateImpl		_torrent )
+		File						_torrent_base )
 	{
-		torrent	= _torrent;
+		torrent_base 		= _torrent_base;
+	}
+		
+	public 
+	TOTorrentCreatorImpl(
+		File						_torrent_base,
+		URL							_announce_url,
+		boolean						_add_other_hashes,
+		long						_piece_length )
+		
+		throws TOTorrentException
+	{
+		torrent_base 		= _torrent_base;
+		announce_url		= _announce_url;
+		add_other_hashes	= _add_other_hashes;
+		piece_length		= _piece_length;	
+	}
+	
+	public 
+	TOTorrentCreatorImpl(	
+		File						_torrent_base,
+		URL							_announce_url,
+		boolean						_add_other_hashes,
+		long						_piece_min_size,
+		long						_piece_max_size,
+		long						_piece_num_lower,
+		long						_piece_num_upper )
+	
+		throws TOTorrentException
+	{
+		torrent_base 		= _torrent_base;
+		announce_url		= _announce_url;
+		add_other_hashes	= _add_other_hashes;
+		piece_min_size		= _piece_min_size;	
+		piece_max_size		= _piece_max_size;	
+		piece_num_lower		= _piece_num_lower;	
+		piece_num_upper		= _piece_num_upper;	
+	}
+	
+	public void
+	setFileIsLayoutDescriptor(
+		boolean		b )
+	{
+		is_desc	= b;
 	}
 	
 	public TOTorrent
@@ -47,28 +115,420 @@ TOTorrentCreatorImpl
 	
 		throws TOTorrentException
 	{
-		torrent.create();
+		try{
+			if ( announce_url == null ){
+				
+				throw( new TOTorrentException( "Skeleton creator", TOTorrentException.RT_WRITE_FAILS ));
+			}
+			
+			File	base_to_use;
+			
+			if ( is_desc ){
+				
+				base_to_use = createLayoutMap();
+				
+			}else{
+				
+				base_to_use = torrent_base;
+			}
+			
+			if ( piece_length > 0 ){
+				
+				torrent = 
+					new TOTorrentCreateImpl(
+							linkage_map,
+							base_to_use,
+							announce_url,
+							add_other_hashes,
+							piece_length );
+			}else{
+				
+				torrent = 
+					new TOTorrentCreateImpl(
+							linkage_map,
+							base_to_use,
+							announce_url,
+							add_other_hashes,
+							piece_min_size,
+							piece_max_size,
+							piece_num_lower,
+							piece_num_upper );
+			}
+			
+			for ( TOTorrentProgressListener l: listeners ){
+				
+				torrent.addListener( l );
+			}
+			
+			torrent.create();
+			
+			return( torrent );
+			
+		}finally{
+			
+			if ( is_desc ){
+				
+				destroyLayoutMap();
+			}
+		}
+	}
+	
+	private List<DescEntry>
+	readDescriptor()
+	
+		throws TOTorrentException
+	{
+		try{
+			int		top_files		= 0;
+			int		top_entries		= 0;
+			
+			String 	top_component 	= null;
+			
+			Map	map = BDecoder.decode( FileUtil.readFileAsByteArray( torrent_base ));
+			
+			List<Map>	file_map = (List<Map>)map.get( "file_map" );
+			
+			if ( file_map == null ){
+				
+				throw( new TOTorrentException( "Invalid descriptor file", TOTorrentException.RT_READ_FAILS ));
+			}
+			
+			List<DescEntry>	desc_entries = new ArrayList<DescEntry>();
+			
+			BDecoder.decodeStrings( file_map );
+			
+			for ( Map m: file_map ){
+				
+				List<String>	logical_path 	= (List<String>)m.get( "logical_path" );				
+				String			target			= (String)m.get( "target" );
+				
+				if ( logical_path == null || target == null ){
+					
+					throw( new TOTorrentException( "Invalid descriptor file: entry=" + m, TOTorrentException.RT_READ_FAILS ));
+				}
+				
+				if ( logical_path.size() == 0 ){
+					
+					throw( new TOTorrentException( "Logical path must have at least one entry: " + m, TOTorrentException.RT_READ_FAILS ));
+				}
+
+				for ( int i=0;i<logical_path.size();i++ ){
+					
+					logical_path.set( i, FileUtil.convertOSSpecificChars( logical_path.get(i), i < logical_path.size()-1));
+				}
+				
+				File	tf = new File( target );
+				
+				if ( !tf.exists()){
+					
+					throw( new TOTorrentException( "Invalid descriptor file: file '" + tf + "' not found" + m, TOTorrentException.RT_READ_FAILS ));
+					
+				}else{
+					
+					String str = logical_path.get(0);
+					
+					if ( logical_path.size() == 1 ){
+						
+						top_entries++;
+					}
+					
+					if ( top_component != null && !top_component.equals( str )){
+					
+						throw( new TOTorrentException( "Invalid descriptor file: multiple top level elements specified", TOTorrentException.RT_READ_FAILS ));
+					}
+					
+					top_component = str;
+				}
+				
+				desc_entries.add( new DescEntry( logical_path, tf ));
+			}
+			
+			if ( top_entries > 1 ){
+				
+				throw( new TOTorrentException( "Invalid descriptor file: exactly one top level entry required", TOTorrentException.RT_READ_FAILS ));
+			}
+			
+			if ( desc_entries.isEmpty()){
+				
+				throw( new TOTorrentException( "Invalid descriptor file: no mapping entries found", TOTorrentException.RT_READ_FAILS ));
+			}
+			
+			return( desc_entries );
+			
+		}catch( IOException e ){
+			
+			throw( new TOTorrentException( "Invalid descriptor file: " + Debug.getNestedExceptionMessage( e ), TOTorrentException.RT_READ_FAILS ));
+
+		}
+	}
+	
+	private void
+	mapDirectory(
+		int			prefix_length,
+		File		target,
+		File		temp )
+	
+		throws IOException
+	{
+		File[]	files = target.listFiles();
 		
-		return( torrent );
+		for ( File f: files ){
+
+			String	file_name = f.getName();
+			
+			if ( file_name.equals( "." ) || file_name.equals( ".." )){
+				
+				continue;
+			}
+			
+			File t = new File( temp, file_name);
+
+			if ( f.isDirectory()){
+
+				if ( !t.isDirectory()){
+				
+					t.mkdirs();
+				}
+				
+				mapDirectory( prefix_length, f, t );
+				
+			}else{
+				
+				if ( !t.exists()){
+					
+					t.createNewFile();
+					
+				}else{
+					
+					throw( new IOException( "Duplicate file: " + t ));
+				}
+				
+				linkage_map.put( t.getAbsolutePath().substring( prefix_length ), f );
+			}
+		}
+	}
+	
+	private File
+	createLayoutMap()
+	
+		throws TOTorrentException
+	{
+			// create a directory/file hierarchy that mirrors that prescribed by the descriptor
+			// along with a linkage map to be applied during construction
+		
+		if ( descriptor_dir != null ){
+			
+			return( descriptor_dir );
+		}
+		
+		try{
+			descriptor_dir = AETemporaryFileHandler.createTempDir();
+			
+			File	top_level_file = null;
+			
+			List<DescEntry>	desc_entries	= readDescriptor();
+			
+			for ( DescEntry entry: desc_entries ){
+				
+				List<String>	logical_path	= entry.getLogicalPath();
+				File			target			= entry.getTarget();
+				
+				File temp = descriptor_dir;
+				
+				int	prefix_length = descriptor_dir.getAbsolutePath().length() + 1;
+				
+				for ( int i=0;i<logical_path.size();i++ ){
+					
+					temp = new File( temp, logical_path.get( i ));
+					
+					if ( top_level_file == null ){
+						
+						top_level_file = temp;
+					}
+				}
+				
+				if ( target.isDirectory()){
+				
+					if ( !temp.isDirectory()){
+						
+						if ( !temp.mkdirs()){
+							
+							throw( new TOTorrentException( "Failed to create logical directory: " + temp, TOTorrentException.RT_WRITE_FAILS ));
+						}
+					}
+					
+					mapDirectory( prefix_length, target, temp );
+					
+				}else{
+					
+					File p = temp.getParentFile();
+					
+					if ( !p.isDirectory()){
+						
+						if ( !p.mkdirs()){
+							
+							throw( new TOTorrentException( "Failed to create logical directory: " + p, TOTorrentException.RT_WRITE_FAILS ));
+						}
+					}
+					
+					if ( temp.exists()){
+					
+						throw( new TOTorrentException( "Duplicate file: " + temp, TOTorrentException.RT_WRITE_FAILS ));
+						
+					}else{
+						
+						temp.createNewFile();
+						
+						linkage_map.put( temp.getAbsolutePath().substring( prefix_length ), target );
+					}
+				}
+			}
+					
+			return( top_level_file );
+			
+		}catch( TOTorrentException e ){
+			
+			throw( e );
+			
+		}catch( Throwable e ){
+			
+			throw( new TOTorrentException( Debug.getNestedExceptionMessage( e ), TOTorrentException.RT_WRITE_FAILS ));
+		}
+	}
+	
+	private void
+	destroyLayoutMap()
+	{
+		if ( descriptor_dir != null && descriptor_dir.exists()){
+			
+			if ( !FileUtil.recursiveDelete( descriptor_dir )){
+				
+				Debug.out( "Failed to delete descriptor directory '" + descriptor_dir + "'" );
+			}
+		}
+	}
+	
+	public long
+	getTorrentDataSizeFromFileOrDir()
+	
+		throws TOTorrentException
+	{
+		if ( is_desc ){
+			
+			List<DescEntry>	desc_entries	= readDescriptor();
+			
+			long	result = 0;
+			
+			for ( DescEntry entry: desc_entries ){
+				
+				result += getTorrentDataSizeFromFileOrDir( entry.getTarget());
+			}
+			
+			return( result );
+			
+		}else{
+		
+			return( getTorrentDataSizeFromFileOrDir( torrent_base ));
+		}
+	}
+	
+	private long
+	getTorrentDataSizeFromFileOrDir(
+		File				file )
+	{
+		String	name = file.getName();
+		
+		if ( name.equals( "." ) || name.equals( ".." )){
+			
+			return( 0 );
+		}
+		
+		if ( !file.exists()){
+		
+			return(0);
+		}
+		
+		if ( file.isFile()){
+					
+			return( file.length());
+				
+		}else{
+			
+			File[]	dir_files = file.listFiles();
+			
+			long	length = 0;
+			
+			for (int i=0;i<dir_files.length;i++){
+				
+				length += getTorrentDataSizeFromFileOrDir( dir_files[i] );
+			}
+			
+			return( length );
+		}
 	}
 	
 	public void
 	cancel()
 	{
-		torrent.cancel();
+		if ( torrent != null ){
+		
+			torrent.cancel();
+		}
 	}
 	
 	public void
 	addListener(
 		TOTorrentProgressListener	listener )
 	{
-		torrent.addListener( listener );
+		if ( torrent == null ){
+			
+			listeners.add( listener );
+			
+		}else{
+		
+			torrent.addListener( listener );
+		}
 	}
 	
 	public void
 	removeListener(
 		TOTorrentProgressListener	listener )
 	{
-		torrent.removeListener( listener );
+		if ( torrent == null ){
+			
+			listeners.remove( listener );
+			
+		}else{
+			
+			torrent.removeListener( listener );
+		}
+	}
+	
+	private static class
+	DescEntry
+	{
+		private List<String>	logical_path;
+		private File			target;
+		
+		private
+		DescEntry(
+			List<String>		_l,
+			File				_t )
+		{
+			logical_path	= _l;
+			target			= _t;
+		}
+		
+		private List<String>
+		getLogicalPath()
+		{
+			return( logical_path );
+		}
+		
+		private File
+		getTarget()
+		{
+			return( target );
+		}
 	}
 }
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
index a20d6b9..30ebd67 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentDeserialiseImpl.java
@@ -27,6 +27,9 @@ import java.net.*;
 import java.util.*;
 
 import org.gudy.azureus2.core3.html.HTMLUtils;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.torrent.*;
 import org.gudy.azureus2.core3.util.*;
 
@@ -207,7 +210,11 @@ TOTorrentDeserialiseImpl
 		throws TOTorrentException
 	{
 		try{
-			Map meta_data = BDecoder.decode(bytes);
+			BDecoder decoder = new BDecoder();
+			
+			decoder.setVerifyMapOrder( true );
+			
+			Map meta_data = decoder.decodeByteArray( bytes );
 	
 			// print( "", "", meta_data );
 			
@@ -266,6 +273,12 @@ TOTorrentDeserialiseImpl
 							if ( announce_url.indexOf( "://" ) == -1 ){
 								
 								announce_url = "http:/" + (announce_url.startsWith("/")?"":"/") + announce_url;
+								
+							}else if ( announce_url.startsWith( "utp:" )){
+								
+								// common typo for udp
+								
+								announce_url = "udp" + announce_url.substring( 3 );
 							}
 							
 							try{
@@ -274,6 +287,8 @@ TOTorrentDeserialiseImpl
 									
 							}catch( MalformedURLException f ){
 									
+								Debug.out( "Invalid announce url: " + announce_url );
+								
 								bad_announce	= true;
 							}
 						}
@@ -307,6 +322,17 @@ TOTorrentDeserialiseImpl
 							
 							Object temp = announce_list.get(i);
 							
+								// sometimes we just get a byte[]! turn into a list
+							
+							if ( temp instanceof byte[] ){
+							
+								List l = new ArrayList();
+								
+								l.add( temp );
+								
+								temp = l;
+							}
+							
 							if ( temp instanceof List ){
 								
 								List	set = (List)temp;
@@ -334,6 +360,12 @@ TOTorrentDeserialiseImpl
 						            	if ( url_str.indexOf( "://" ) == -1 ){
 												
 						            		url_str = "http:/" + (url_str.startsWith("/")?"":"/") + url_str;
+						            		
+										}else if ( url_str.startsWith( "utp:" )){
+										
+												// common typo
+											
+											url_str = "udp" + url_str.substring( 3 );
 										}
 								         
 										try{
@@ -346,7 +378,7 @@ TOTorrentDeserialiseImpl
 							       
 										}catch( MalformedURLException f ){
 					
-											Debug.printStackTrace( f );
+											Debug.out( "Invalid url: " + url_str, f );
 										} 
 									}
 								}
@@ -358,14 +390,14 @@ TOTorrentDeserialiseImpl
 									urls.copyInto( url_array );
 									
 									addTorrentAnnounceURLSet( url_array );
-								}
+								}								
 							}else{
 								
-								Debug.out( "Torrent has invalid url-list entry (" + temp + ") - ignoring" );
+								Debug.out( "Torrent has invalid url-list entry (" + temp + ") - ignoring: meta=" + meta_data );
 							}
 						}
             
-			            	//if the original announce url isn't found, add it to the list
+			            	// if the original announce url isn't found, add it to the list
 							// watch out for those invalid torrents with announce url missing
 						
 			            if ( !announce_url_found && announce_url != null && announce_url.length() > 0) {
@@ -376,7 +408,9 @@ TOTorrentDeserialiseImpl
 			              	urls.copyInto( url_array );
 			              	addTorrentAnnounceURLSet( url_array );
 			              }
-			              catch (Exception e) { Debug.printStackTrace( e ); }
+			              catch( Exception e ){ 
+			            	  Debug.out( "Invalid URL '" + announce_url + "' - meta=" + meta_data, e ); 
+			              }
 			            }
 					}
 				}else if ( key.equalsIgnoreCase( TK_COMMENT )){
@@ -466,7 +500,7 @@ 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 ));
@@ -536,11 +570,14 @@ TOTorrentDeserialiseImpl
 					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++){
-					
-						path_comps[j] = (byte[])paths.get(j);
+					byte[][]	path_comps = null;
+					if (paths != null) {
+  					path_comps = new byte[paths.size()][];
+  					
+  					for (int j=0;j<paths.size();j++){
+  					
+  						path_comps[j] = (byte[])paths.get(j);
+  					}
 					}
 					
 					TOTorrentFileImpl file;
@@ -639,6 +676,31 @@ TOTorrentDeserialiseImpl
 				if ( ho != null ){
 					
 					setHashOverride( ho );
+					
+				}else{
+					
+					if ( info instanceof LightHashMapEx ){
+													
+						LightHashMapEx	info_ex = (LightHashMapEx)info;
+							
+						if ( info_ex.getFlag( LightHashMapEx.FL_MAP_ORDER_INCORRECT )){
+						
+							String name = getUTF8Name();
+							
+							if ( name == null ){
+								
+								name = new String(getName());
+							}
+							
+							String	message = MessageText.getString( "torrent.decode.info.order.bad", new String[]{ name });
+							
+							LogAlert alert = new LogAlert( this, LogAlert.UNREPEATABLE, LogAlert.AT_WARNING, message);
+							
+							alert.forceNotify = true;
+							
+							Logger.log( alert );
+						}
+					}
 				}
 			}catch( Throwable e ){
 				
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
index af3877e..017d2ce 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentFileImpl.java
@@ -152,15 +152,24 @@ TOTorrentFileImpl
 	
 		throws TOTorrentException
 	{
-		for (int i=0;i<path_components.length;i++){
+		byte[][][] to_do = { path_components, path_components_utf8 };
+		
+		for (byte[][] pc: to_do ){
 			
-			byte[] comp = path_components[i];
-			if (comp.length == 2 && comp[0] == (byte) '.' && comp[1] == (byte) '.')
-				throw (new TOTorrentException("Torrent file contains illegal '..' component", TOTorrentException.RT_DECODE_FAILS));
-
-			// intern directories as they're likely to repeat
-			if(i < (path_components.length - 1))
-				path_components[i] = StringInterner.internBytes(path_components[i]);
+			if ( pc == null ){
+				continue;
+			}
+		
+			for (int i=0;i<pc.length;i++){
+				
+				byte[] comp = pc[i];
+				if (comp.length == 2 && comp[0] == (byte) '.' && comp[1] == (byte) '.')
+					throw (new TOTorrentException("Torrent file contains illegal '..' component", TOTorrentException.RT_DECODE_FAILS));
+	
+				// intern directories as they're likely to repeat
+				if(i < (pc.length - 1))
+					pc[i] = StringInterner.internBytes(pc[i]);
+			}
 		}
 	}
 	
@@ -234,9 +243,34 @@ TOTorrentFileImpl
 	}
 	
 	public String getRelativePath() {
-		if (torrent == null)
+		if (torrent == null) {
 			return "";
+		}
 		String sRelativePath = "";
+		
+		byte[][] pathComponentsUTF8 = getPathComponentsUTF8();
+		if (pathComponentsUTF8 != null) {
+			for (int j = 0; j < pathComponentsUTF8.length; j++) {
+
+				try {
+					String comp;
+					try {
+						comp =  new String(pathComponentsUTF8[j], "utf8");
+					} catch (UnsupportedEncodingException e) {
+						System.out.println("file - unsupported encoding!!!!");
+						comp = "UnsupportedEncoding";
+					}
+	
+					comp = FileUtil.convertOSSpecificChars(comp, j != pathComponentsUTF8.length-1 );
+	
+					sRelativePath += (j == 0 ? "" : File.separator) + comp;
+				} catch (Exception ex) {
+					Debug.out(ex);
+				}
+
+			}
+			return sRelativePath;
+		}
 
 		LocaleUtilDecoder decoder = null;
 		try {
@@ -295,12 +329,14 @@ TOTorrentFileImpl
 		
 		byte[][]	path_comps = getPathComponentsBasic();
 		
-		for (int j=0;j<path_comps.length;j++){
-			
-			path.add( path_comps[j]);
+		if (path_comps != null) {
+  		for (int j=0;j<path_comps.length;j++){
+  			
+  			path.add( path_comps[j]);
+  		}
 		}
 		
-		if ( isUTF8()){
+		if (path_comps != null && isUTF8()){
 			
 			List utf8_path = new ArrayList();
 			
diff --git a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
index 4c0eab6..438fd18 100644
--- a/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
+++ b/org/gudy/azureus2/core3/torrent/impl/TOTorrentImpl.java
@@ -93,6 +93,8 @@ TOTorrentImpl
 	private boolean				created;
 	private boolean				serialising;
 	
+	private List<TOTorrentListener>	listeners;
+	
 	protected AEMonitor this_mon 	= new AEMonitor( "TOTorrent" );
 
 	/** 
@@ -316,7 +318,9 @@ TOTorrentImpl
 		
 		Map	root = new HashMap();
 		
-		writeStringToMetaData( root, TK_ANNOUNCE, announce_url.toString());
+			// seen a NPE here, not sure of cause so handling null announce_url in case
+		
+		writeStringToMetaData( root, TK_ANNOUNCE, (announce_url==null?TorrentUtils.getDecentralisedEmptyURL():announce_url).toString());
 		
 		TOTorrentAnnounceURLSet[] sets = announce_group.getAnnounceURLSets();
 		
@@ -476,6 +480,17 @@ TOTorrentImpl
 		torrent_name	= _name;
 	}
 	
+	public String
+	getUTF8Name()
+	{
+		try {
+			return torrent_name_utf8 == null ? null : new String(torrent_name_utf8,
+					"utf8");
+		} catch (UnsupportedEncodingException e) {
+			return null;
+		}
+	}
+	
 	protected void
 	setNameUTF8(
 		byte[]	_name )
@@ -539,10 +554,26 @@ TOTorrentImpl
 		if (s0.equals(s1))
 			return false;
 		
+		if ( newURL == null ){
+			
+				// anything's better than null...
+			
+			newURL = TorrentUtils.getDecentralisedEmptyURL();
+		}
+		
 		announce_url	= StringInterner.internURL(newURL);
+		
+		fireChanged( TOTorrentListener.CT_ANNOUNCE_URLS );
+		
 		return true;
 	}
 
+	public boolean 
+	isDecentralised() 
+	{
+		return( TorrentUtils.isDecentralised( getAnnounceURL()));
+	}
+	
 	public long
 	getCreationDate()
 	{
@@ -684,12 +715,14 @@ TOTorrentImpl
 			}
 		}
 		
+		/* support this for fixing borked torrents
 		if ( !TorrentUtils.isDecentralised( announce_url )){
 			
 			throw( new TOTorrentException( 
 						"Hash override can only be set on decentralised torrents",
 						TOTorrentException.RT_HASH_FAILS ));
 		}
+		*/
 		
 		torrent_hash_override = hash;
 		
@@ -1215,6 +1248,81 @@ TOTorrentImpl
 		}
 	}
 	
+	protected void
+	fireChanged(
+		int	type )
+	{
+		List<TOTorrentListener> to_fire = null;
+		
+		try{
+			this_mon.enter();
+			
+			if ( listeners != null ){
+				
+				to_fire = new ArrayList<TOTorrentListener>( listeners );
+			}
+		}finally{
+			
+			this_mon.exit();
+		}
+		
+		if ( to_fire != null ){
+			
+			for ( TOTorrentListener l: to_fire ){
+				
+				try{
+					l.torrentChanged( this, type );
+					
+				}catch( Throwable e ){
+					
+					Debug.out(e);
+				}
+			}
+		}
+	}
+	
+ 	public void
+	addListener(
+		TOTorrentListener		l )
+	{
+ 		try{
+			this_mon.enter();
+			
+			if ( listeners == null ){
+				
+				listeners = new ArrayList<TOTorrentListener>();
+			}
+			
+			listeners.add( l );
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
+
+	public void
+	removeListener(
+		TOTorrentListener		l )
+	{
+ 		try{
+			this_mon.enter();
+			
+			if ( listeners != null ){
+				
+				listeners.remove( l );
+				
+				if ( listeners.size() == 0 ){
+					
+					listeners = null;
+				}
+			}
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
+	
 	public AEMonitor
 	getMonitor()
 	{
diff --git a/org/gudy/azureus2/core3/torrent/test/Main.java b/org/gudy/azureus2/core3/torrent/test/Main.java
deleted file mode 100644
index 1f0edbd..0000000
--- a/org/gudy/azureus2/core3/torrent/test/Main.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * File    : Main.java
- * Created : 5 Oct. 2003
- * 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.core3.torrent.test;
-
-
-import java.io.*;
-import java.net.*;
-
-import org.gudy.azureus2.core3.security.SESecurityManager;
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.util.Debug;
-
-public class 
-Main
-{
-	static int TT_ENCODE		= 1;
-	static int TT_DECODE		= 2;
-	static int TT_CREATE		= 3;
-	
-	static void
-	usage()
-	{
-		System.err.println( "Usage: encode|decode|create" );
-		
-		SESecurityManager.exitVM(1);
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		int	test_type= 0;
-		
-		if ( args.length != 1 ){
-			
-			usage();
-		}
-		
-		if ( args[0].equalsIgnoreCase( "encode" )){
-			
-			test_type = TT_ENCODE;
-			
-		}else if ( args[0].equalsIgnoreCase( "decode" )){
-			
-			test_type = TT_DECODE;
-			
-		}else if ( args[0].equalsIgnoreCase( "create" )){
-			
-			test_type = TT_CREATE;
-						
-		}else{
-			
-			usage();
-		}
-		
-		try{
-			if ( test_type == TT_ENCODE ){
-				
-				/*
-				File f = new File("D:\\az2060-broken.torrent");
-						
-				TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile( f );
-			
-				TOTorrentAnnounceURLSet set = torrent.getAnnounceURLGroup().createAnnounceURLSet(new URL[]{ new URL("http://localhost:6970/announce"), new URL("http://localhost:6969/announce")});
-				
-				torrent.getAnnounceURLGroup().setAnnounceURLSets( new TOTorrentAnnounceURLSet[]{ set });
-				
-				torrent.setAdditionalStringProperty( "Wibble", "wobble" );
-				
-				torrent.print();
-			
-				torrent.serialiseToBEncodedFile( new File("c:\\temp\\test2.torrent"));
-				
-				*/
-			
-			}else if ( test_type == TT_DECODE ){
-							 
-				File f = new File("c:\\temp\\az3008-broken.torrent" );
-			
-				TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile( f );
-			
-				// System.out.println( "\turl group sets = " + torrent.getAnnounceURLGroup().getAnnounceURLSets().length);
-				
-				torrent.print();		
-				
-			}else if ( test_type == TT_CREATE ){
-			
-				TOTorrentProgressListener list = new TOTorrentProgressListener()
-					{
-						public void
-						reportProgress(
-							int		p )
-						{
-							System.out.println( "" + p );
-						}
-						public void
-						reportCurrentTask(
-							String	task_description )
-						{
-							System.out.println( "task = " + task_description );
-						}				
-					};
-				
-				boolean	do_file 	= false;
-				boolean	do_fixed	= false;
-				
-				TOTorrent t;
-				
-				if ( do_fixed ){
-					
-					if ( do_file ){
-						
-						TOTorrentCreator c = TOTorrentFactory.createFromFileOrDirWithFixedPieceLength( 
-								new File("c:\\temp\\test.wmf"), 
-								new URL( "http://127.0.0.1:6969/announce" ),
-								1024*10 );
-						
-						c.addListener( list );
-						
-						t = c.create();
-					}else{
-		
-						TOTorrentCreator c = TOTorrentFactory.createFromFileOrDirWithFixedPieceLength( 
-								new File("c:\\temp\\scans"), 
-								new URL("http://127.0.0.1:6969/announce" ), 
-								1024*256 ); 
-								
-						
-						c.addListener( list );
-						
-						t = c.create();
-					}
-				}else{
-					if ( do_file ){
-						
-						TOTorrentCreator c = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength( 
-								new File("c:\\temp\\test.wmf"), 
-								new URL( "http://127.0.0.1:6969/announce" ));
-								
-						
-						
-						c.addListener( list );
-						
-						t = c.create();
-						
-					}else{
-		
-						TOTorrentCreator c = TOTorrentFactory.createFromFileOrDirWithComputedPieceLength( 
-								new File("c:\\temp\\qqq"), 
-								new URL("http://127.0.0.1:6969/announce" )); 
-								
-						
-						
-						c.addListener( list );
-						
-						t = c.create();
-								
-						t.setCreationDate( 12345L );
-						
-						t.setComment( "poo pee plop mcjock");
-					}
-				}
-				
-				t.print();
-				
-				t.serialiseToBEncodedFile( new File("c:\\temp\\test.torrent" ));						 
-			}
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-			
-		}
-	}
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/core3/torrentdownloader/TorrentDownloaderFactory.java b/org/gudy/azureus2/core3/torrentdownloader/TorrentDownloaderFactory.java
index 05c41e5..23843f8 100644
--- a/org/gudy/azureus2/core3/torrentdownloader/TorrentDownloaderFactory.java
+++ b/org/gudy/azureus2/core3/torrentdownloader/TorrentDownloaderFactory.java
@@ -22,12 +22,14 @@
 
 package org.gudy.azureus2.core3.torrentdownloader;
 
+import java.io.File;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.global.GlobalManager;
 import org.gudy.azureus2.core3.torrentdownloader.impl.TorrentDownloaderImpl;
 import org.gudy.azureus2.core3.torrentdownloader.impl.TorrentDownloaderManager;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.UrlUtils;
 
 /**
  *
@@ -63,12 +65,9 @@ public class TorrentDownloaderFactory {
 	String 								url,
 	String								referrer,
 	String 								fileordir, 
-	boolean 							logged) 
+	boolean 							logged ) 
   {
-    TorrentDownloaderImpl dl = getClass(logged);
-    if (dl!=null)
-      dl.init(callback, url, referrer, null, fileordir);
-    return dl;
+	  return( create( callback, url, referrer, null, fileordir, logged ));
   }
   
   public static TorrentDownloader 
@@ -76,9 +75,9 @@ public class TorrentDownloaderFactory {
   		TorrentDownloaderCallBackInterface 	callback, 
 		String 								url,
 		String								referrer,
-		String 								fileordir) 
+		String 								fileordir ) 
   {
-    return create(callback, url, referrer, fileordir, false);
+    return create(callback, url, referrer, fileordir, false );
   }
   
   public static TorrentDownloader 
@@ -89,10 +88,19 @@ public class TorrentDownloaderFactory {
 		Map									request_properties,
 		String 								fileordir) 
   {
-	   TorrentDownloaderImpl dl = getClass(false);
-	    if (dl!=null)
-	      dl.init(callback, url, referrer, request_properties, fileordir);
-	    return dl;
+	  return( create( callback, url, referrer, request_properties, fileordir, false ));
+  }
+  
+  private static TorrentDownloader 
+  create(
+  		TorrentDownloaderCallBackInterface 	callback, 
+		String 								url,
+		String								referrer,
+		Map									request_properties,
+		String 								fileordir,
+		boolean								logged )
+  {
+	  return( new TorrentDownloadRetrier( callback, url, referrer, request_properties, fileordir, logged ));
   }
   
   public static TorrentDownloader create(TorrentDownloaderCallBackInterface callback, String url, boolean logged) {
@@ -138,4 +146,281 @@ public class TorrentDownloaderFactory {
   public static TorrentDownloader downloadManaged(String url) {
     return TorrentDownloaderManager.getInstance().download(url);
   }
+  
+  	private static class
+  	TorrentDownloadRetrier
+  		implements TorrentDownloader
+  	{
+		final private String 								url;
+		final private String								referrer;
+		final private Map									request_properties;
+		final private String 								fileordir;
+		final private boolean								logged;
+  		
+		private volatile TorrentDownloaderImpl	delegate;
+		
+		private volatile boolean	cancelled;
+		
+		private volatile boolean	sdp_set;
+		private volatile String		sdp_path;
+		private volatile String		sdp_file;
+		
+		private volatile boolean	dfoc_set;
+		private volatile boolean	dfoc;
+		private volatile boolean	irc_set;
+		private volatile boolean	irc;
+		
+  		private
+  		TorrentDownloadRetrier(
+  			final TorrentDownloaderCallBackInterface 	_callback, 
+  			String 										_url,
+  			String										_referrer,
+  			Map											_request_properties,
+  			String 										_fileordir,
+  			boolean										_logged )
+  		{
+  			url					= _url;
+  			referrer			= _referrer;
+  			request_properties	= _request_properties;
+  			fileordir			= _fileordir;
+  			logged				= _logged;
+
+  			TorrentDownloaderCallBackInterface callback			= 
+  				new TorrentDownloaderCallBackInterface()
+  				{
+  					private TorrentDownloaderCallBackInterface	original_callback = _callback;
+  					
+  					private boolean no_retry = original_callback == null;
+  					
+  					private boolean	init_reported 	= false;
+  					private boolean	start_reported	= false;
+  					
+  					public void 
+  					TorrentDownloaderEvent(
+  						int 				state, 
+  						TorrentDownloader 	_delegate )
+  					{
+  						if ( _delegate != delegate ){
+  							
+  							return;
+  						}
+  						
+  						if ( state == STATE_INIT ){
+  							
+  							if ( init_reported ){
+  								
+  								return;
+  							}
+  							
+  							init_reported = true;
+  						}
+  						
+ 						if ( state == STATE_START ){
+  							
+  							if ( start_reported ){
+  								
+  								return;
+  							}
+  							
+  							start_reported = true;
+  						}
+ 						
+  						if ( cancelled ){
+  							
+  							no_retry = true;
+  						}
+  						
+  						if ( no_retry ){
+  							
+  							if ( original_callback != null ){
+  								
+  								original_callback.TorrentDownloaderEvent( state, TorrentDownloadRetrier.this );
+  							}
+  							
+  							return;
+  						}
+  					
+  						if ( 	state == STATE_FINISHED ||
+  								state == STATE_DUPLICATE ||
+  								state == STATE_CANCELLED ){
+  					
+							if ( original_callback != null ){
+  								
+  								original_callback.TorrentDownloaderEvent( state, TorrentDownloadRetrier.this );
+  							}
+							
+  							no_retry = true;
+  							
+  							return;
+  						}
+  						
+  						if ( state == STATE_ERROR ){
+  							
+  							String lc_url = url.toLowerCase().trim();
+  							
+  							String	retry_url = null;
+  							
+  							if ( lc_url.startsWith( "http" )){
+  							
+  								retry_url = UrlUtils.parseTextForURL( url.substring( 5 ), true );
+  							}
+  							
+  							if ( retry_url != null ){
+  													
+	  				 			delegate = TorrentDownloaderFactory.getClass( logged );  		  
+	  				  			
+	  				 			if ( sdp_set ){
+	  				 				
+	  				 				delegate.setDownloadPath( sdp_path, sdp_file );
+	  				 			}
+	  				 			
+	  				 			if ( dfoc_set ){
+	  				 				
+	  				 				delegate.setDeleteFileOnCancel( dfoc );
+	  				 			}
+	  				 			
+	  				 			if ( irc_set ){
+	  				 				
+	  				 				delegate.setIgnoreReponseCode( irc );
+	  				 			}
+	  				 			
+	  				  			delegate.init( this, retry_url, referrer, request_properties, fileordir );
+	  				  			
+	  							no_retry	= true;
+	  							
+	  							delegate.start();
+	  							
+	  							return;
+	  							
+  							}else{
+  								
+	  							no_retry	= true;
+  							}
+  						}						
+  						
+						if ( original_callback != null ){
+								
+							original_callback.TorrentDownloaderEvent( state, TorrentDownloadRetrier.this );
+						}
+  					}
+  					 
+  				};
+
+  			delegate = TorrentDownloaderFactory.getClass( logged );  		  
+  			
+  			delegate.init( callback, url, referrer, request_properties, fileordir );
+  		}
+  		
+  		public void 
+  		start()
+  		{
+  			delegate.start();
+  		}
+
+  		public void 
+  		cancel()
+  		{
+  			cancelled = true;
+  			
+  			delegate.cancel();
+  		}
+
+  		public void 
+  		setDownloadPath(
+  			String path, 
+  			String file)
+  		{
+  			sdp_set			= true;
+ 			sdp_path		= path;
+  			sdp_file		= file;
+
+  			delegate.setDownloadPath(path, file); 			
+   		}
+
+  		public int 
+  		getDownloadState()
+  		{
+  			return( delegate.getDownloadState());
+  		}
+
+  		public File 
+  		getFile()
+  		{
+  			return( delegate.getFile());
+  		}
+
+  		public int 
+  		getPercentDone()
+  		{
+  			return( delegate.getPercentDone());
+  		}
+  		
+  		public int 
+  		getTotalRead()
+  		{
+  			return( delegate.getTotalRead());
+  		}
+  		
+  		public String 
+  		getError()
+  		{
+  			return( delegate.getError());
+  		}
+  		
+  		public String 
+  		getStatus()
+  		{
+  			return( delegate.getStatus());
+  		}
+
+  		public String 
+  		getURL()
+  		{
+  			return( delegate.getURL());
+  		}
+  		
+  		public int 
+  		getLastReadCount()
+  		{
+  			return( delegate.getLastReadCount());
+  		}
+  		
+  		public byte[] 
+  		getLastReadBytes()
+  		{
+  			return( delegate.getLastReadBytes());
+  		}
+  		
+  		public boolean 
+  		getDeleteFileOnCancel()
+  		{
+  			return( delegate.getDeleteFileOnCancel());
+  		}
+  		
+  		public void 
+  		setDeleteFileOnCancel(
+  			boolean deleteFileOnCancel )
+  		{
+  			dfoc_set	= true;
+  			dfoc		= deleteFileOnCancel;
+  			
+  			delegate.setDeleteFileOnCancel( deleteFileOnCancel );
+  		}
+  		
+  		public boolean 
+  		isIgnoreReponseCode()
+  		{
+  			return( delegate.isIgnoreReponseCode());
+  		}
+  		
+  		public void 
+  		setIgnoreReponseCode(
+  			boolean ignoreReponseCode)
+  		{
+  			irc_set	= true;
+  			irc		= ignoreReponseCode;
+  			
+  			delegate.setIgnoreReponseCode( ignoreReponseCode );
+  		}
+  	}
 }
diff --git a/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java b/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
index e8693a4..19863b7 100644
--- a/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
+++ b/org/gudy/azureus2/core3/torrentdownloader/impl/TorrentDownloaderImpl.java
@@ -28,15 +28,20 @@ import java.io.*;
 
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.net.URLConnection;
 import java.net.URLDecoder;
+import java.net.UnknownHostException;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.InflaterInputStream;
 
 import javax.net.ssl.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloaderCallBackInterface;
 import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloader;
@@ -45,6 +50,8 @@ import org.gudy.azureus2.core3.util.protocol.magnet.MagnetConnection;
 import org.gudy.azureus2.core3.util.protocol.magnet.MagnetConnection2;
 import org.gudy.azureus2.core3.torrent.*;
 
+import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
+
 
 /**
  * @author Tobias Minich
@@ -58,7 +65,7 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
   private String 	file_str;
   
   private URL url;
-  private HttpURLConnection con;
+  private URLConnection con;
   private String error = "Ok";
   private String status = "";
   private TorrentDownloaderCallBackInterface iface;
@@ -106,6 +113,17 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
     referrer			= _referrer;
     request_properties	= _request_properties;
     file_str			= _file;
+    
+    if ( referrer == null || referrer.length() == 0 ){
+    	
+    	try{
+    			// maybe can't do any harm here setting referer - fixes some download issues...
+    		
+    		referrer = url_str;
+    		
+    	}catch( Throwable e ){
+    	}
+    }
   }
 
   public void notifyListener() {
@@ -168,103 +186,124 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
     	}
 	  
     	for (int i=0;i<2;i++){
-      	try{
-      
-	      if ( protocol.equals("https")){
-	      	
-	      	// see ConfigurationChecker for SSL client defaults
-	      	
-	      	HttpsURLConnection ssl_con = (HttpsURLConnection)url.openConnection();
-	      	
-	      	// allow for certs that contain IP addresses rather than dns names
-	      	
-	      	ssl_con.setHostnameVerifier(
-	      			new HostnameVerifier()
-	      			{
-	      				public boolean
-	      				verify(
-	      					String		host,
-							SSLSession	session )
-	      				{
-	      					return( true );
-	      				}
-	      			});
-	      	
-	      	con = ssl_con;
-	      	
-	      }else{
-	      	
-	      	con = (HttpURLConnection) url.openConnection();
-	      	
-	      }
-	      
-	      con.setRequestProperty("User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION);     
-	      
-	      if ( referrer != null && referrer.length() > 0 ){
-	      
-	      	con.setRequestProperty( "Referer", referrer );
-	      }
-	      
-	      if ( request_properties != null ){
-	    	  
-	    	  Iterator it = request_properties.entrySet().iterator();
-	    	  
-	    	  while( it.hasNext()){
-	    		
-	    		  Map.Entry	entry = (Map.Entry)it.next();
-	    		  
-	    		  String	key 	= (String)entry.getKey();
-	    		  String	value	= (String)entry.getValue();
-	    		  
-	    		  	// currently this code doesn't support gzip/deflate...
-	    		  
-	    		  if ( !key.equalsIgnoreCase( "Accept-Encoding" )){
-	    			  	    			    			  
-	    			  con.setRequestProperty( key, value );
-	    		  }
-	    	  }
-	      }
-	      
-	      this.con.connect();
-	      
-	      break;
-	      
-      	}catch( SSLException e ){
-      		
-      		if ( i == 0 ){
-				
-      			if ( SESecurityManager.installServerCertificates( url ) != null ){
-      				
-      				// certificate has been installed
+    		try{
+
+    			if ( protocol.equals("https")){
+
+    				// see ConfigurationChecker for SSL client defaults
+
+    				HttpsURLConnection ssl_con = (HttpsURLConnection)url.openConnection();
+
+    				// allow for certs that contain IP addresses rather than dns names
+
+    				ssl_con.setHostnameVerifier(
+    						new HostnameVerifier()
+    						{
+    							public boolean
+    							verify(
+    									String		host,
+    									SSLSession	session )
+    							{
+    								return( true );
+    							}
+    						});
+
+    				con = ssl_con;
+
+    			}else{
+
+    				con = url.openConnection();
+
+    			}
+
+				if ( con instanceof HttpURLConnection ){
 					
-      				continue;	// retry with new certificate
-      			}
-      		}
+						// we want this true but some plugins (grrr) set the global default not to follow
+						// redirects
+				
+					((HttpURLConnection)con).setInstanceFollowRedirects( true );
+				}
+				
+    			con.setRequestProperty("User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION);     
 
-      		throw( e );
-      		
-      	}catch( IOException e ){
-      		
-      		if ( i == 0 ){
-      			
-      			URL retry_url = UrlUtils.getIPV4Fallback( url );
-      			
-      			if ( retry_url != null ){
-      				
-      				url = retry_url;
-      				
-      			}else{
-      				
-      				throw( e );
-      			}
-      		}
-      	}
+    			if ( referrer != null && referrer.length() > 0 ){
+
+    				con.setRequestProperty( "Referer", referrer );
+    			}
+
+    			if ( request_properties != null ){
+
+    				Iterator it = request_properties.entrySet().iterator();
+
+    				while( it.hasNext()){
+
+    					Map.Entry	entry = (Map.Entry)it.next();
+
+    					String	key 	= (String)entry.getKey();
+    					String	value	= (String)entry.getValue();
+
+    					// currently this code doesn't support gzip/deflate...
+
+    					if ( !key.equalsIgnoreCase( "Accept-Encoding" )){
+
+    						con.setRequestProperty( key, value );
+    					}
+    				}
+    			}
+
+    			this.con.connect();
+    			
+    			String magnetURI = con.getHeaderField("Magnet-Uri");
+    			if (magnetURI != null) {
+    				closeConnection();
+    				url_str = magnetURI;
+    				runSupport();
+    				return;
+    			}
+
+    			break;
+
+    		}catch( SSLException e ){
+
+    			if ( i == 0 ){
+
+    				if ( SESecurityManager.installServerCertificates( url ) != null ){
+
+    					// certificate has been installed
+
+    					continue;	// retry with new certificate
+    				}
+    			}
+
+    			throw( e );
+
+    		}catch( IOException e ){
+
+    			if ( i == 0 ){
+
+    				URL retry_url = UrlUtils.getIPV4Fallback( url );
+
+    				if ( retry_url != null ){
+
+    					url = retry_url;
+
+    				}else{
+
+    					throw( e );
+    				}
+    			}
+    			
+    			if ( e instanceof UnknownHostException ){
+    				
+    				throw( e );
+    			}
+    		}
       }
       
-  		int response = this.con.getResponseCode();
+  		int response = con instanceof HttpURLConnection?((HttpURLConnection)con).getResponseCode():HttpURLConnection.HTTP_OK;
     	if (!ignoreReponseCode) {
         if ((response != HttpURLConnection.HTTP_ACCEPTED) && (response != HttpURLConnection.HTTP_OK)) {
-          this.error(response, Integer.toString(response) + ": " + this.con.getResponseMessage());
+          this.error(response, Integer.toString(response) + ": " + ((HttpURLConnection)con).getResponseMessage());
           return;
         }
     	}
@@ -280,15 +319,36 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 			}
 	*/
       filename = this.con.getHeaderField("Content-Disposition");
-      if ((filename!=null) && filename.toLowerCase().matches(".*attachment.*")) // Some code to handle b0rked servers.
-        while (filename.toLowerCase().charAt(0)!='a')
+      
+      if ((filename!=null) && filename.toLowerCase().matches(".*attachment.*")){ // Some code to handle b0rked servers.
+    	  
+        while (filename.toLowerCase().charAt(0)!='a'){
+        	
           filename = filename.substring(1);
-      if ((filename == null) || !filename.toLowerCase().startsWith("attachment") || (filename.indexOf('=') == -1)) {
+        }
+      }
+      
+      	// see if we can grab the filename directly (thanks Angel)
+      
+      Pattern p = Pattern.compile(".*filename=\\\"(.*)\\\"");
+      
+      Matcher m = null;
+      
+      if ( filename != null && ((m = p.matcher( filename )) != null) && m.matches()){
+    	  
+           filename = m.group(1).trim();
+           
+      }else if (	filename == null || 
+    		  		!filename.toLowerCase().startsWith("attachment") || 
+    		  		filename.indexOf('=') == -1 ) {
+    	  
         String tmp = this.url.getFile();
-        if (tmp.length() == 0 || tmp.equals("/")) {
+        
+        if ( tmp.length() == 0 || tmp.equals("/")){
+        	
         	filename = url.getHost();
-        }
-        else if ( tmp.startsWith("?")){
+        	
+        }else if ( tmp.startsWith("?")){
         
         	// probably a magnet URI - use the hash
         	// magnet:?xt=urn:sha1:VGC53ZWCUXUWVGX7LQPVZIYF4L6RXSU6
@@ -360,7 +420,7 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
         
         filename = URLDecoder.decode(filename, Constants.DEFAULT_ENCODING );
         
-        	// not sure of this piece of logic here but I'm not changing it at the moment
+        	// this code removes any parent directories from the filename we've extracted
         
         File temp = new File(filename);
         filename = temp.getName();
@@ -400,7 +460,7 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
       this.state = STATE_INIT;
       this.notifyListener();
     } catch (java.net.MalformedURLException e) {
-      this.error(0, "Exception while parsing URL '" + url + "':" + e.getMessage());
+      this.error(0, "Exception while parsing URL '" + url_str + "':" + e.getMessage());
     } catch (java.net.UnknownHostException e) {
       this.error(0, "Exception while initializing download of '" + url + "': Unknown Host '" + e.getMessage() + "'");
     } catch (java.io.IOException ioe) {
@@ -425,111 +485,140 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
       
     	notifyListener();
   
-        Thread	status_reader = 
-        	new AEThread( "TorrentDownloader:statusreader" )
-			{
-        		public void
-				runSupport()
-        		{
-        			boolean changed_status	= false;
-        			String	last_status		= "";
-        			
-        			boolean	sleep = false;
-        			
-        			while( true ){
-        				
-        				try{
-        					if ( sleep ){
-        					
-        						Thread.sleep(50);
-        						
-        						sleep = false;
-        					}
-        					
-        					try{
-        						this_mon.enter();
-        						
-        						if ( !status_reader_run[0] ){
-        						
-        							break;
-        						}
-        					}finally{
-        						
-        						this_mon.exit();
-        					}
-        					
-        					String	s = con.getResponseMessage();
-        					  
-        					if ( s.equals( last_status )){
-        						
-        						sleep = true;
-        						
-        					}else{
-        						
-        						last_status = s;
-        						
-        						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{
-        							
-        							error(con.getResponseCode(), s.substring(6));
-        						}
-        						
-        						changed_status	= true;
-        					} 
-        				}catch( Throwable e ){
-        					
-        					break;
-        				}
-        			}
-        			
-        			if ( changed_status ){
-        				
-        				setStatus( "" );
-        			}
-        		}
-			};
+    	if ( con instanceof HttpURLConnection ){
+    		
+	        Thread	status_reader = 
+	        	new AEThread( "TorrentDownloader:statusreader" )
+				{
+	        		public void
+					runSupport()
+	        		{
+	        			HttpURLConnection http_con = (HttpURLConnection)con;
+	        			
+	        			boolean changed_status	= false;
+	        			String	last_status		= "";
+	        			
+	        			boolean	sleep = false;
+	        			
+	        			long	last_progress_update = SystemTime.getMonotonousTime();
+	        			
+	        			while( true ){
+	        				
+	        				try{
+	        					if ( sleep ){
+	        					
+	        						Thread.sleep(50);
+	        						
+	        						sleep = false;
+	        					}
+	        					
+	        					try{
+	        						this_mon.enter();
+	        						
+	        						if ( !status_reader_run[0] ){
+	        						
+	        							break;
+	        						}
+	        					}finally{
+	        						
+	        						this_mon.exit();
+	        					}
+	        					
+	        					String	s = http_con.getResponseMessage();
+	        					  
+	        					if ( s.equals( last_status )){
+	        						
+	        						sleep = true;
+	        						
+	        					}else{
+	        						
+	        						last_status = s;
+	        						
+	        						String lc_s = s.toLowerCase();
+	        						
+	        						if ( !lc_s.startsWith("error:")){
+	        							
+	        							if ( s.toLowerCase().indexOf( "alive" ) != -1 ){
+	        								
+	        								if ( percentDone < 10 ){
+	        									
+	        									percentDone++;
+	        								}
+	        							}
+	        							
+	        							boolean progress_update = false;
+	        							
+	        	     					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());
+	                							
+	                							progress_update = true;
+	                							
+	                						}catch( Throwable e ){
+	                							
+	                						}
+	                					}
+	                					
+	                					if ( lc_s.startsWith("received")){
+	                						
+	                						progress_update = true;
+	                					}
+	                					
+	                					if ( progress_update ){
+	                						
+	                						long now = SystemTime.getMonotonousTime();
+	                						
+	                						if ( now - last_progress_update < 250 ){
+	                							
+	                							continue;
+	                						}
+	                					
+	                						last_progress_update = now;
+	                					}
+	                					
+	        							setStatus(s);
+	        						}else{
+	        							
+	        							error(http_con.getResponseCode(), s.substring(6));
+	        						}
+	        						
+	        						changed_status	= true;
+	        					} 
+	        				}catch( Throwable e ){
+	        					
+	        					break;
+	        				}
+	        			}
+	        			
+	        			if ( changed_status ){
+	        				
+	        				setStatus( "" );
+	        			}
+	        		}
+				};
+				
+			status_reader.setDaemon( true );
 			
-		status_reader.setDaemon( true );
-		
-		status_reader.start();
-  
+			status_reader.start();
+    	}
+    	
 		InputStream in;
 			
 		try{
@@ -538,7 +627,11 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 		} catch (FileNotFoundException e) {
 			if (ignoreReponseCode) {
 
-				in = this.con.getErrorStream();
+				if (con instanceof HttpURLConnection) {
+					in = ((HttpURLConnection)con).getErrorStream();
+				} else {
+					in = null;
+				}
 			} else {
 
 				throw e;
@@ -577,12 +670,14 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 		    	
 	    	this.file = new File(this.directoryname, filename);
 
-	    	boolean useTempFile = false;
-	    	try {
-	    		this.file.createNewFile();
-	    		useTempFile = !this.file.exists();
-	    	} catch (Throwable t) {
-	    		useTempFile = true;
+	    	boolean useTempFile = file.exists();
+	    	if (!useTempFile) {
+  	    	try {
+  	    		this.file.createNewFile();
+  	    		useTempFile = !this.file.exists();
+  	    	} catch (Throwable t) {
+  	    		useTempFile = true;
+  	    	}
 	    	}
 	    	
 	    	if (useTempFile) {
@@ -644,24 +739,55 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 	          	// it to something more useful
 	          
 	          try{
-	          	if ( !filename.toLowerCase().endsWith(".torrent" )){
-	
-	          		TOTorrent	torrent = TorrentUtils.readFromFile( file, false );
-	          		
-	          		String	name = TorrentUtils.getLocalisedName( torrent ) + ".torrent";
-	          		
-	          		File	new_file	= new File( directoryname, name );
-	          		
-	          		if ( file.renameTo( new_file )){
-	          			
-	          			filename	= name;
-					
-	          			file	= new_file;
-	          		}
-	          	}
+	        	  if ( !filename.toLowerCase().endsWith(".torrent" )){
+
+	        		  TOTorrent	torrent = TorrentUtils.readFromFile( file, false );
+
+	        		  String	name = TorrentUtils.getLocalisedName( torrent ) + ".torrent";
+
+	        		  File	new_file	= new File( directoryname, name );
+
+	        		  if ( file.renameTo( new_file )){
+
+	        			  filename	= name;
+
+	        			  file	= new_file;
+	        		  }
+	        	  }
 	          }catch( Throwable e ){
-	          		
-	          	Debug.printStackTrace( e );
+
+	        	  boolean is_vuze_file = false;
+
+	        	  try{
+	        		  if ( filename.toLowerCase().endsWith( ".vuze" )){
+
+	        			  is_vuze_file = true;
+	        			  
+	        		  }else{
+	        			  
+	        			  if ( VuzeFileHandler.getSingleton().loadVuzeFile( file ) != null ){
+
+	        				  is_vuze_file = true;
+
+	        				  String	name = filename + ".vuze";
+
+	        				  File	new_file	= new File( directoryname, name );
+
+	        				  if ( file.renameTo( new_file )){
+
+	        					  filename	= name;
+
+	        					  file	= new_file;
+	        				  }
+	        			  }
+	        		  }
+	        	  }catch( Throwable f ){	          		
+	        	  }
+
+	        	  if ( !is_vuze_file ){
+
+	        		  Debug.printStackTrace( e );
+	        	  }
 	          }
 	          
 	          TorrentUtils.setObtainedFrom( file, original_url );
@@ -670,14 +796,20 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
 	        }
 	        this.notifyListener();
 	      }
-      } catch (Exception e) {
+      } catch( Throwable e){
     	  
+      	String url_log_string = this.url_str.toString().replaceAll( "\\Q&pause_on_error=true\\E", "" );
+
+        String log_msg = MessageText.getString(
+              	"torrentdownload.error.dl_fail",
+              	new String[]{ url_log_string , file==null?filename:file.getAbsolutePath(), e.getMessage() });
+
     	if ( !cancel ){
     		
-    		Debug.out("'" + this.directoryname + "' '" +  filename + "'", e);
+    		Debug.out( log_msg );
     	}
-      	
-        this.error(0, "Exception while downloading '" + this.url.toString() + "':" + e.getMessage());
+      		
+        this.error(	0, log_msg );
       }
   }
 
@@ -781,8 +913,14 @@ public class TorrentDownloaderImpl extends AEThread implements TorrentDownloader
   protected void
   closeConnection()
   {
-	if ( con instanceof MagnetConnection || con instanceof MagnetConnection2 ){
-	  	con.disconnect();
+	if ( con instanceof MagnetConnection ){
+	  	((MagnetConnection)con).disconnect();
+
+	} else if ( con instanceof MagnetConnection2 ){
+	  	((MagnetConnection2)con).disconnect();
+
+	} else if (con instanceof HttpURLConnection) {
+		((HttpURLConnection)con).disconnect();
 	}
   }
   
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncer.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncer.java
index 94b7699..47aff27 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncer.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncer.java
@@ -28,6 +28,8 @@ import org.gudy.azureus2.core3.torrent.*;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
 
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
 public interface 
 TRTrackerAnnouncer 
 {
@@ -62,11 +64,7 @@ TRTrackerAnnouncer
 	public void
 	setTrackerURL(
 		URL		url );
-		
-	public void
-	setTrackerURLs(
-		TOTorrentAnnounceURLSet[]		sets );
-	
+			
 	public void
 	resetTrackerUrl(
 		boolean	shuffle );
@@ -74,11 +72,7 @@ TRTrackerAnnouncer
 	public void
 	setIPOverride(
 		String		override );
-	
-	public void
-	cloneFrom(
-		TRTrackerAnnouncer	other );
-	
+		
 	public void
 	clearIPOverride();
 	
@@ -119,6 +113,9 @@ TRTrackerAnnouncer
 	public String
 	getStatusString();
 	
+	public TRTrackerAnnouncer
+	getBestAnnouncer();
+	
 	public TRTrackerAnnouncerResponse
 	getLastResponse();
 	
@@ -152,7 +149,19 @@ TRTrackerAnnouncer
 		String		ip,
 		int			tcp_port );
 	
+		/**
+		 * Gets a delegate tracker peer source for reporting against
+		 * @param set
+		 * @return
+		 */
+		
+	public TrackerPeerSource 
+	getTrackerPeerSource(
+		TOTorrentAnnounceURLSet		set );
 	
+	public TrackerPeerSource 
+	getCacheTrackerPeerSource();
+
 	/**
 	 * This method forces all listeners to get an explicit "urlChanged" event to get them
 	 * to re-examine the tracker
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerDataProvider.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerDataProvider.java
index 4150e0d..213af39 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerDataProvider.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerDataProvider.java
@@ -51,6 +51,12 @@ TRTrackerAnnouncerDataProvider
 	getMaxNewConnectionsAllowed();
 	
 	public int
+	getPendingConnectionCount();
+	
+	public int
+	getConnectedConnectionCount();
+	
+	public int
 	getUploadSpeedKBSec(
 		boolean	estimate );
 	
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerResponsePeer.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerResponsePeer.java
index a071a3f..5738da8 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerResponsePeer.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerAnnouncerResponsePeer.java
@@ -35,4 +35,8 @@ TRTrackerAnnouncerResponsePeer
 	
 	public int
 	getUploadSpeed();
+	
+	public int
+	compareTo( 
+		TRTrackerAnnouncerResponsePeer	other );
 }
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraper.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraper.java
index c475832..d87ade6 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraper.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraper.java
@@ -33,6 +33,8 @@ import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
 public interface 
 TRTrackerScraper 
 {
+	public static final int REFRESH_MINIMUM_SECS		= 2*60;
+	
 	public TRTrackerScraperResponse
 	scrape(
 		TOTorrent		torrent );
@@ -59,6 +61,11 @@ TRTrackerScraper
 		URL						url,
 		DownloadScrapeResult	result );
 	
+	public TRTrackerScraperResponse
+	peekScrape(
+		TOTorrent		torrent,
+		URL				target_url );
+	
 	public void
 	remove(
 		TOTorrent		torrent );
diff --git a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperResponse.java b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperResponse.java
index 5d1bfcc..de82db7 100644
--- a/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperResponse.java
+++ b/org/gudy/azureus2/core3/tracker/client/TRTrackerScraperResponse.java
@@ -81,6 +81,9 @@ TRTrackerScraperResponse
 	public URL
 	getURL();
 	
+	public boolean
+	isDHTBackup();
+	
 	public String
 	getString();
 }
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerHelper.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerHelper.java
new file mode 100644
index 0000000..5cb8e70
--- /dev/null
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerHelper.java
@@ -0,0 +1,49 @@
+/*
+ * Created on Dec 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 org.gudy.azureus2.core3.tracker.client.impl;
+
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+
+public interface 
+TRTrackerAnnouncerHelper
+	extends TRTrackerAnnouncer
+{
+	public TOTorrentAnnounceURLSet[]
+	getAnnounceSets();
+	
+	public void
+	setAnnounceSets(
+		TOTorrentAnnounceURLSet[]		sets );
+	
+	public boolean
+	isUpdating();
+	
+	public long
+	getInterval();
+	
+	public long
+	getMinInterval();
+	
+	public int
+	getTimeUntilNextUpdate();
+}
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerImpl.java
index 2035f32..d834123 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerImpl.java
@@ -32,10 +32,13 @@ import java.util.List;
 import java.util.Map;
 
 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.peer.PEPeerSource;
 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.TRTrackerAnnouncerException;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerListener;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponsePeer;
@@ -45,7 +48,12 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.LightHashMap;
 import org.gudy.azureus2.core3.util.ListenerManager;
 import org.gudy.azureus2.core3.util.ListenerManagerDispatcher;
+import org.gudy.azureus2.plugins.clientid.ClientIDException;
 import org.gudy.azureus2.plugins.download.DownloadAnnounceResultPeer;
+import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 
 /**
  * @author parg
@@ -65,6 +73,23 @@ TRTrackerAnnouncerImpl
 	protected static final int LDT_URL_CHANGED			= 2;
 	protected static final int LDT_URL_REFRESH			= 3;
 	
+	private static final String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+	private static final int	   	key_id_length	= 8;
+
+	private static String
+	createKeyID()
+	{
+		String	key_id = "";
+		
+		for (int i = 0; i < key_id_length; i++) {
+			int pos = (int) ( Math.random() * chars.length());
+		    key_id +=  chars.charAt(pos);
+		}
+		
+		return( key_id );
+	}
+	
 	protected ListenerManager<TRTrackerAnnouncerListener>	listeners 	= ListenerManager.createManager(
 			"TrackerClient:ListenDispatcher",
 			new ListenerManagerDispatcher<TRTrackerAnnouncerListener>()
@@ -98,22 +123,65 @@ TRTrackerAnnouncerImpl
 
 	private Map	tracker_peer_cache		= new LinkedHashMap();	// insertion order - most recent at end
 	private AEMonitor tracker_peer_cache_mon 	= new AEMonitor( "TRTrackerClientClassic:PC" );
+	private int	cache_peers_used;
 	
-	private TOTorrent		torrent;
+	final private TOTorrent						torrent;
+	final private byte[]						peer_id;
+	final private String						tracker_key;
+	final private int							udp_key;
+		
 	
 	protected
 	TRTrackerAnnouncerImpl(
 		TOTorrent	_torrent )
+	
+		throws TRTrackerAnnouncerException
 	{
 		torrent	= _torrent;
+		
+		tracker_key	= createKeyID();
+	    
+		udp_key	= (int)(Math.random() *  0xFFFFFFFFL );
+		
+		try{
+			peer_id		= ClientIDManagerImpl.getSingleton().generatePeerID( torrent, false );
+		
+		}catch( ClientIDException e ){
+
+			 throw( new TRTrackerAnnouncerException( "TRTrackerAnnouncer: Peer ID generation fails", e ));
+		}
 	}
 
+	public TOTorrent
+	getTorrent()
+	{
+		return( torrent );
+	}
+	
 	public Helper
 	getHelper()
 	{
 		return(
 			new Helper()
 			{
+				public byte[]
+				getPeerID()
+				{
+					return( peer_id );
+				}
+				
+				public String
+				getTrackerKey()
+				{
+					return( tracker_key );
+				}
+				
+				public int
+				getUDPKey()
+				{
+					return( udp_key );
+				}
+				
 				public void
 				addToTrackerCache(
 					TRTrackerAnnouncerResponsePeerImpl[]		peers )
@@ -150,9 +218,10 @@ TRTrackerAnnouncerImpl
 					
 				public void
 				informResponse(
+					TRTrackerAnnouncerHelper		helper,
 					TRTrackerAnnouncerResponse		response )
 				{
-					listeners.dispatch( LDT_TRACKER_RESPONSE, response );
+					TRTrackerAnnouncerImpl.this.informResponse( helper, response );
 				}
 				
 				public void
@@ -168,7 +237,7 @@ TRTrackerAnnouncerImpl
 				public void
 				informURLRefresh()
 				{
-					listeners.dispatch( LDT_URL_REFRESH, null );
+					TRTrackerAnnouncerImpl.this.informURLRefresh();
 				}
 				
 			 	public void
@@ -187,6 +256,12 @@ TRTrackerAnnouncerImpl
 			});
 	}
 	
+	public byte[]
+	getPeerId()
+	{
+		return( peer_id );
+	}
+	
  	public static byte[]
 	getAnonymousPeerId(
 		String	my_ip,
@@ -490,10 +565,25 @@ TRTrackerAnnouncerImpl
 		return( res );
 	}
 	
+	protected abstract int
+	getPeerCacheLimit();
+	
 	protected TRTrackerAnnouncerResponsePeer[]
 	getPeersFromCache(
 		int	num_want )
 	{
+		int	limit = getPeerCacheLimit();
+		
+		if ( limit <= 0 ){
+			
+			return( new TRTrackerAnnouncerResponsePeer[0] );
+		}
+		
+			// limit peers returned to avoid multi-tracker torrents from getting swamped
+			// by out-of-date peers from a failed tracker
+		
+		num_want = Math.min( limit, num_want );
+		
 		try{
 			tracker_peer_cache_mon.enter();
 	
@@ -540,6 +630,8 @@ TRTrackerAnnouncerImpl
 						"TRTrackerClient: returned " + res.length + " cached peers"));
 			}
 		    
+			cache_peers_used += res.length;
+			
 			return( res );
 			
 		}finally{
@@ -548,6 +640,40 @@ TRTrackerAnnouncerImpl
 		}
 	} 
 	
+	public TrackerPeerSource 
+	getCacheTrackerPeerSource()
+	{
+		return(
+			new TrackerPeerSourceAdapter()
+			{
+				public String
+				getName()
+				{
+					return( MessageText.getString( "tps.tracker.cache1", new String[]{ String.valueOf( cache_peers_used )}));
+				}
+				
+				public int
+				getPeers()
+				{
+					return( tracker_peer_cache.size() );
+				}
+			});
+	}
+
+	protected void
+	informResponse(
+		TRTrackerAnnouncerHelper		helper,
+		TRTrackerAnnouncerResponse		response )
+	{
+		listeners.dispatch( LDT_TRACKER_RESPONSE, response );
+	}
+
+	protected void
+	informURLRefresh()
+	{
+		listeners.dispatch( LDT_URL_REFRESH, null );
+	}
+	
  	public void
 	addListener(
 		TRTrackerAnnouncerListener	l )
@@ -565,6 +691,15 @@ TRTrackerAnnouncerImpl
 	public interface
 	Helper
 	{
+		public byte[]
+		getPeerID();
+		
+		public String
+		getTrackerKey();
+		
+		public int
+		getUDPKey();
+		
 		public void
 		addToTrackerCache(
 			TRTrackerAnnouncerResponsePeerImpl[]		peers );
@@ -586,6 +721,7 @@ TRTrackerAnnouncerImpl
 		
 		public void
 		informResponse(
+			TRTrackerAnnouncerHelper		helper,
 			TRTrackerAnnouncerResponse		response );
 		
 		public void
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerMuxer.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerMuxer.java
index c00e506..3fd3e8b 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerMuxer.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerMuxer.java
@@ -22,163 +22,1163 @@
 package org.gudy.azureus2.core3.tracker.client.impl;
 
 import java.net.URL;
+import java.util.*;
 
+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.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.TRTrackerAnnouncerDataProvider;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerException;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
 import org.gudy.azureus2.core3.tracker.client.impl.bt.TRTrackerBTAnnouncerImpl;
 import org.gudy.azureus2.core3.tracker.client.impl.dht.TRTrackerDHTAnnouncerImpl;
+import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.IndentWriter;
+import org.gudy.azureus2.core3.util.SimpleTimer;
+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.TorrentUtils;
 import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
 
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+
 public class 
 TRTrackerAnnouncerMuxer
 	extends TRTrackerAnnouncerImpl
 {
-	private TRTrackerAnnouncer	main_announcer;
+	private static final int ACT_CHECK_INIT_DELAY			= 2500;
+	private static final int ACT_CHECK_INTERIM_DELAY		= 10*1000;
+	private static final int ACT_CHECK_IDLE_DELAY			= 30*1000;
+	private static final int ACT_CHECK_SEEDING_SHORT_DELAY		= 60*1000;
+	private static final int ACT_CHECK_SEEDING_LONG_DELAY		= 3*60*1000;
+	
+	
+	private String[]			networks;
+	private boolean				is_manual;
+	
+	private long				create_time = SystemTime.getMonotonousTime();
+	
+	private CopyOnWriteList<TRTrackerAnnouncerHelper>	announcers 	= new CopyOnWriteList<TRTrackerAnnouncerHelper>();
+	private Set<TRTrackerAnnouncerHelper>				activated	= new HashSet<TRTrackerAnnouncerHelper>();
+	private long										last_activation_time;
+	private Set<String>									failed_urls	= new HashSet<String>();
+	
+	private volatile TimerEvent					event;
+	
+	private TRTrackerAnnouncerDataProvider		provider;
+	private String								ip_override;
+	private boolean								complete;
+	private boolean								stopped;
+	private boolean								destroyed;
+	
+	private TRTrackerAnnouncerHelper			last_best_active;
+	private long								last_best_active_set_time;
+	
+	private Map<String,StatusSummary>			recent_responses = new HashMap<String,StatusSummary>();
+	
+	private TRTrackerAnnouncerResponse			last_response_informed;
+
 	
 	protected
 	TRTrackerAnnouncerMuxer(
-		TOTorrent		torrent,
-		String[]		networks,
-		boolean			manual )
+		TOTorrent		_torrent,
+		String[]		_networks,
+		boolean			_manual )
+	
+		throws TRTrackerAnnouncerException
+	{
+		super( _torrent );
+		
+		try{	
+			last_response_informed = new TRTrackerAnnouncerResponseImpl( null, _torrent.getHashWrapper(), TRTrackerAnnouncerResponse.ST_OFFLINE, TRTrackerAnnouncer.REFRESH_MINIMUM_SECS, "Initialising" );
+			
+		}catch( TOTorrentException e ){
+			
+			Logger.log(new LogEvent( _torrent, LOGID, "Torrent hash retrieval fails", e));
+			
+			throw( new TRTrackerAnnouncerException( "TRTrackerAnnouncer: URL encode fails"));	
+		}
+
+		networks	= _networks;
+		is_manual 	= _manual;
+			
+		split();
+	}
+	
+	protected void
+	split()
+	
+		throws TRTrackerAnnouncerException
+	{
+		TRTrackerAnnouncerHelper to_activate = null;
+		
+		synchronized( this ){
+			
+			if ( stopped || destroyed ){
+				
+				return;
+			}
+			
+			TOTorrent torrent = getTorrent();
+					
+			TOTorrentAnnounceURLSet[]	sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
+			
+				// sanitise dht entries
+			
+			if ( sets.length == 0 ){
+				
+				sets = new TOTorrentAnnounceURLSet[]{ torrent.getAnnounceURLGroup().createAnnounceURLSet( new URL[]{ torrent.getAnnounceURL()})};
+				
+			}else{
+				
+				boolean	found_decentralised = false;
+				boolean	modified			= false;
+				
+				for ( int i=0;i<sets.length;i++ ){
+					
+					TOTorrentAnnounceURLSet set = sets[i];
+					
+					URL[] urls = set.getAnnounceURLs().clone();
+					
+					for (int j=0;j<urls.length;j++){
+						
+						URL u = urls[j];
+						
+						if ( u != null && TorrentUtils.isDecentralised( u )){
+														
+							if ( found_decentralised ){
+								
+								modified = true;
+								
+								urls[j] = null;
+								
+							}else{
+								
+								found_decentralised = true;
+							}
+						}
+					}
+				}
+				
+				if ( modified ){
+					
+					List<TOTorrentAnnounceURLSet> s_list = new ArrayList<TOTorrentAnnounceURLSet>();
+					
+					for ( TOTorrentAnnounceURLSet set: sets ){
+						
+						URL[] urls = set.getAnnounceURLs();
+						
+						List<URL> u_list = new ArrayList<URL>( urls.length );
+						
+						for ( URL u: urls ){
+							
+							if ( u != null ){
+								
+								u_list.add( u );
+							}
+						}
+						
+						if ( u_list.size() > 0 ){
+							
+							s_list.add( torrent.getAnnounceURLGroup().createAnnounceURLSet( u_list.toArray( new URL[ u_list.size() ])));
+						}
+					}
+					
+					sets = s_list.toArray( new TOTorrentAnnounceURLSet[ s_list.size() ]);
+				}
+			}
+			
+			List<TOTorrentAnnounceURLSet[]>	new_sets = new ArrayList<TOTorrentAnnounceURLSet[]>();
+			
+			if ( is_manual || sets.length < 2 ){
+					
+				new_sets.add( sets );
+				
+			}else{
+				
+				List<TOTorrentAnnounceURLSet> list = new ArrayList<TOTorrentAnnounceURLSet>( Arrays.asList( sets ));
+				
+					// often we have http:/xxxx/ and udp:/xxxx/ as separate groups - keep these together
+								
+				while( list.size() > 0 ){
+					
+					TOTorrentAnnounceURLSet set1 = list.remove(0);
+					
+					boolean	done = false;
+					
+					URL[] urls1 = set1.getAnnounceURLs();
+					
+					if ( urls1.length == 1 ){
+						
+						URL url1 = urls1[0];
+						
+						String prot1 = url1.getProtocol().toLowerCase();
+						String host1	= url1.getHost();
+						
+						for (int i=0;i<list.size();i++){
+							
+							TOTorrentAnnounceURLSet set2 = list.get(i);
+							
+							URL[] urls2 = set2.getAnnounceURLs();
+							
+							if ( urls2.length == 1 ){
+								
+								URL url2 = urls2[0];
+								
+								String prot2 = url2.getProtocol().toLowerCase();
+								String host2 = url2.getHost();
+				
+								if ( host1.equals( host2 )){
+									
+									if (	( prot1.equals( "udp" ) && prot2.startsWith( "http" )) ||
+											( prot2.equals( "udp" ) && prot1.startsWith( "http" ))){
+										
+										list.remove( i );
+										
+										new_sets.add( new TOTorrentAnnounceURLSet[]{ set1, set2 });
+										
+										done	= true;
+									}
+								}
+							}
+						}
+					}
+					
+					if ( !done ){
+						
+						new_sets.add( new TOTorrentAnnounceURLSet[]{ set1 });
+					}
+				}
+			}
+			
+				// work out the difference
+			
+			Iterator<TOTorrentAnnounceURLSet[]> ns_it = new_sets.iterator();
+			
+			List<TRTrackerAnnouncerHelper> existing_announcers 	= announcers.getList();
+			List<TRTrackerAnnouncerHelper> new_announcers 		= new ArrayList<TRTrackerAnnouncerHelper>();
+			
+				// first look for unchanged sets
+			
+			while( ns_it.hasNext()){
+				
+				TOTorrentAnnounceURLSet[] ns = ns_it.next();
+				
+				Iterator<TRTrackerAnnouncerHelper> a_it = existing_announcers.iterator();
+					
+				while( a_it.hasNext()){
+					
+					TRTrackerAnnouncerHelper a = a_it.next();
+					
+					TOTorrentAnnounceURLSet[] os = a.getAnnounceSets();
+					
+					if ( same( ns, os )){
+						
+						ns_it.remove();
+						a_it.remove();
+						
+						new_announcers.add( a );
+						
+						break;
+					}
+				}
+			}
+					
+				// reuse existing announcers
+			
+				// first remove dht ones from the equation
+			
+			TRTrackerAnnouncerHelper 	existing_dht_announcer 	= null;
+			TOTorrentAnnounceURLSet[]	new_dht_set				= null;
+
+			ns_it = new_sets.iterator();
+			
+			while( ns_it.hasNext()){
+				
+				TOTorrentAnnounceURLSet[] x = ns_it.next();
+				
+				if ( TorrentUtils.isDecentralised( x[0].getAnnounceURLs()[0])){
+					
+					new_dht_set = x;
+						
+					ns_it.remove();
+					
+					break;
+				}
+			}
+			
+			Iterator<TRTrackerAnnouncerHelper>	an_it = existing_announcers.iterator();
+			
+			while( an_it.hasNext()){
+				
+				TRTrackerAnnouncerHelper a = an_it.next();
+				
+				TOTorrentAnnounceURLSet[] x = a.getAnnounceSets();
+				
+				if ( TorrentUtils.isDecentralised( x[0].getAnnounceURLs()[0])){
+					
+					existing_dht_announcer = a;
+						
+					an_it.remove();
+					
+					break;
+				}
+			}
+	
+			if ( existing_dht_announcer != null && new_dht_set != null ){
+				
+				new_announcers.add( existing_dht_announcer );
+				
+			}else if ( existing_dht_announcer != null ){
+				
+				activated.remove( existing_dht_announcer );
+				
+				existing_dht_announcer.destroy();
+				
+			}else if ( new_dht_set != null ){
+				
+				TRTrackerAnnouncerHelper a = create( torrent, new_dht_set );
+				
+				new_announcers.add( a );
+			}
+
+				// now do the non-dht ones
+			
+			ns_it = new_sets.iterator();
+
+			while( ns_it.hasNext() && existing_announcers.size() > 0 ){
+				
+				TRTrackerAnnouncerHelper a = existing_announcers.remove(0);
+				
+				TOTorrentAnnounceURLSet[] s = ns_it.next();
+				
+				ns_it.remove();
+				
+				if ( 	activated.contains( a ) &&
+						torrent.getPrivate() && 
+						a instanceof TRTrackerBTAnnouncerImpl ){
+					
+					URL url = a.getTrackerURL();
+				
+					if ( url != null ){
+						
+						forceStop((TRTrackerBTAnnouncerImpl)a, url );
+					}
+				}
+				
+				a.setAnnounceSets( s );
+				
+				new_announcers.add( a );
+			}
+			
+				// create any new ones required
+			
+			ns_it = new_sets.iterator();
+			
+			while( ns_it.hasNext()){
+				
+				TOTorrentAnnounceURLSet[] s = ns_it.next();
+				
+				TRTrackerAnnouncerHelper a = create( torrent, s );
+				
+				new_announcers.add( a );
+			}
+			
+				// finally fix up the announcer list to represent the new state
+			
+			Iterator<TRTrackerAnnouncerHelper>	a_it = announcers.iterator();
+				
+			while( a_it.hasNext()){
+				
+				TRTrackerAnnouncerHelper a = a_it.next();
+				
+				if ( !new_announcers.contains( a )){
+					
+					a_it.remove();
+					
+					try{
+						if ( 	activated.contains( a ) &&
+								torrent.getPrivate() && 
+								a instanceof TRTrackerBTAnnouncerImpl ){
+							
+							URL url = a.getTrackerURL();
+						
+							if ( url != null ){
+								
+								forceStop((TRTrackerBTAnnouncerImpl)a, url );
+							}
+						}
+					}finally{
+						
+						if (Logger.isEnabled()) {
+							Logger.log(new LogEvent(getTorrent(), LOGID, "Deactivating " + getString( a.getAnnounceSets())));
+						}
+
+						activated.remove( a );
+												
+						a.destroy();
+					}
+				}
+			}
+			
+			a_it = new_announcers.iterator();
+			
+			while( a_it.hasNext()){
+				
+				TRTrackerAnnouncerHelper a = a_it.next();
+				
+				if ( !announcers.contains( a )){
+					
+					announcers.add( a );
+				}
+			}
+			
+			if ( !is_manual && announcers.size() > 0 ){
+				
+				if ( activated.size() == 0 ){
+					
+					TRTrackerAnnouncerHelper a = announcers.get(0);
+					
+					if (Logger.isEnabled()) {
+						Logger.log(new LogEvent(getTorrent(), LOGID, "Activating " + getString( a.getAnnounceSets())));
+					}
+
+					activated.add( a );
+					
+					last_activation_time = SystemTime.getMonotonousTime();
+					
+					if ( provider != null ){
+						
+						to_activate = a;
+					}
+				}
+				
+				setupActivationCheck( ACT_CHECK_INIT_DELAY );
+			}
+		}
+		
+		if ( to_activate != null ){
+			
+			if ( complete ){
+				
+				to_activate.complete( true );
+				
+			}else{
+				
+				to_activate.update( false );
+			}
+		}
+	}
+	
+	protected void
+	setupActivationCheck(
+		int		delay )
+	{
+		if ( announcers.size() > activated.size()){
+			
+			event = SimpleTimer.addEvent(
+				"TRMuxer:check",
+				SystemTime.getOffsetTime( delay ),
+				new TimerEventPerformer()
+				{
+					public void 
+					perform(
+						TimerEvent event )
+					{
+						checkActivation( false );
+					}
+				});
+		}
+	}
+	
+	protected void
+	checkActivation(
+		boolean		force )
+	{
+		synchronized( this ){
+			
+			int	next_check_delay;
+			
+			if ( 	destroyed || 
+					stopped || 
+					announcers.size() <= activated.size()){
+
+				return;
+			}
+			
+			if ( provider == null ){
+				
+				next_check_delay = ACT_CHECK_INIT_DELAY;
+				
+			}else{
+
+				boolean	activate = force;
+														
+				boolean	seeding = provider.getRemaining() == 0;
+
+				if ( seeding && activated.size() > 0 ){
+				
+						// when seeding we only activate on tracker fail or major lack of connections
+						// as normally we rely on downloaders rotating and finding us
+
+					int	connected	= provider.getConnectedConnectionCount();
+
+					if ( connected < 1 ){
+						
+						activate = SystemTime.getMonotonousTime() - last_activation_time >= 60*1000;
+						
+						next_check_delay = ACT_CHECK_SEEDING_SHORT_DELAY;
+						
+					}else if ( connected < 3 ){
+						
+						next_check_delay = ACT_CHECK_SEEDING_LONG_DELAY;
+						
+					}else{
+						
+						next_check_delay = 0;
+					}
+				}else{
+					
+					int	allowed		= provider.getMaxNewConnectionsAllowed();	
+					int	pending		= provider.getPendingConnectionCount();
+					int	connected	= provider.getConnectedConnectionCount();
+					
+					int	online = 0;
+					
+					for ( TRTrackerAnnouncerHelper a: activated ){
+						
+						TRTrackerAnnouncerResponse response = a.getLastResponse();
+						
+						if ( 	response != null && 
+								response.getStatus() == TRTrackerAnnouncerResponse.ST_ONLINE ){
+							
+							online++;
+						}
+					}
+					
+					/*
+					System.out.println( 
+						"checkActivation: announcers=" + announcers.size() + 
+						", active=" + activated.size() +
+						", online=" + online +
+						", allowed=" + allowed +
+						", pending=" + pending +
+						", connected=" + connected +
+						", seeding=" + seeding );
+					*/
+					
+					if ( online == 0 ){
+						
+						activate = true;
+						
+							// no trackers online, start next and recheck soon
+						
+						next_check_delay = ACT_CHECK_INIT_DELAY;
+						
+					}else{
+						
+						int	potential = connected + pending;
+						
+						if ( potential < 10 ){
+							
+								// minimal connectivity 
+							
+							activate = true;
+							
+							next_check_delay = ACT_CHECK_INIT_DELAY;
+
+						}else if ( allowed >= 5 && pending < 3*allowed/4 ){
+							
+								// not enough to fulfill our needs
+							
+							activate = true;
+							
+							next_check_delay = ACT_CHECK_INTERIM_DELAY;
+							
+						}else{
+								// things look good, recheck in a bit
+							
+							next_check_delay = ACT_CHECK_IDLE_DELAY;
+						}
+					}
+				}
+					
+				if ( activate ){
+					
+					for ( TRTrackerAnnouncerHelper a: announcers ){
+						
+						if ( !activated.contains( a )){
+							
+							if (Logger.isEnabled()) {
+								Logger.log(new LogEvent(getTorrent(), LOGID, "Activating " + getString( a.getAnnounceSets())));
+							}
+							
+							activated.add( a );
+							
+							last_activation_time = SystemTime.getMonotonousTime();
+							
+							if ( complete ){
+								
+								a.complete( true );
+								
+							}else{
+								
+								a.update( false );
+							}
+							
+							break;
+						}
+					}
+				}
+			}
+			
+			if ( next_check_delay > 0 ){
+			
+				setupActivationCheck( next_check_delay );
+			}
+		}
+	}
+	
+	private String
+	getString(
+		TOTorrentAnnounceURLSet[]	sets )
+	{
+		StringBuffer str = new StringBuffer();
+		
+		str.append( "[" );
+		
+		int	num1 = 0;
+		
+		for ( TOTorrentAnnounceURLSet s: sets ){
+			
+			if ( num1++ > 0 ){
+				str.append( ", ");
+			}
+			
+			str.append( "[" );
+
+			URL[]	urls = s.getAnnounceURLs();
+			
+			int	num2 = 0;
+			
+			for ( URL u: urls ){
+				
+				if ( num2++ > 0 ){
+					str.append( ", ");
+				}
+				
+				str.append( u.toExternalForm());
+			}
+			
+			str.append( "]" );
+		}
+		
+		str.append( "]" );
+		
+		return( str.toString());
+	}
+	
+	private boolean
+	same(
+		TOTorrentAnnounceURLSet[]	s1,
+		TOTorrentAnnounceURLSet[]	s2 )
+	{
+		boolean	res = sameSupport( s1, s2 );
+		
+		// System.out.println( "same->" + res + ": " + getString(s1) + "/" + getString(s2));
+		
+		return( res );
+	}
+	
+	private boolean
+	sameSupport(
+		TOTorrentAnnounceURLSet[]	s1,
+		TOTorrentAnnounceURLSet[]	s2 )
+	{
+		if ( s1.length != s2.length ){
+			
+			return( false );
+		}
+		
+		for (int i=0;i<s1.length;i++){
+			
+			URL[] u1 = s1[i].getAnnounceURLs();
+			URL[] u2 = s2[i].getAnnounceURLs();
+			
+			if ( u1.length != u2.length ){
+				
+				return( false );
+			}
+			
+			if ( u1.length == 1 ){
+				
+				return( u1[0].toExternalForm().equals( u2[0].toExternalForm()));
+			}
+			
+			Set<String> set1 = new HashSet<String>();
+			
+			for ( URL u: u1 ){
+				
+				set1.add( u.toExternalForm());
+			}
+			
+			Set<String> set2 = new HashSet<String>();
+			
+			for ( URL u: u2 ){
+				
+				set2.add( u.toExternalForm());
+			}
+			
+			if ( !set1.equals( set2 )){
+				
+				return( false );
+			}
+		}
+		
+		return( true );
+	}
+	
+	protected void
+	forceStop(
+		final TRTrackerBTAnnouncerImpl		announcer,
+		final URL							url )
+	{
+		if (Logger.isEnabled()) {
+			Logger.log(new LogEvent(getTorrent(), LOGID, "Force stopping " + url + " as private torrent" ));
+		}
+		
+		new AEThread2( "TRMux:fs", true )
+		{
+			public void
+			run()
+			{
+				try{
+					TRTrackerBTAnnouncerImpl an = 
+						new TRTrackerBTAnnouncerImpl( getTorrent(), new TOTorrentAnnounceURLSet[0], networks, true, getHelper());
+					
+					an.cloneFrom( announcer );
+					
+					an.setTrackerURL( url );
+					
+					an.stop( false );
+					
+					an.destroy();
+					
+				}catch( Throwable e ){
+					
+				}
+			}
+		}.start();
+	}
+	
+	
+	protected TRTrackerAnnouncerHelper
+	create(
+		TOTorrent						torrent,
+		TOTorrentAnnounceURLSet[]		sets )
 	
 		throws TRTrackerAnnouncerException
 	{
-		super( torrent );
+		TRTrackerAnnouncerHelper announcer;
 		
-		TOTorrentAnnounceURLSet[]	sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
+		boolean	decentralised;
 		
-		if ( TorrentUtils.isDecentralised( torrent )){
+		if ( sets.length == 0 ){
 			
-			main_announcer	= new TRTrackerDHTAnnouncerImpl( torrent, networks, manual, getHelper());
+			decentralised = TorrentUtils.isDecentralised( torrent.getAnnounceURL());
 			
 		}else{
 			
+			decentralised = TorrentUtils.isDecentralised( sets[0].getAnnounceURLs()[0]);
+		}
+		
+		if ( decentralised ){
+			
+			announcer	= new TRTrackerDHTAnnouncerImpl( torrent, networks, is_manual, getHelper());
+			
+		}else{
+			
+			announcer = new TRTrackerBTAnnouncerImpl( torrent, sets, networks, is_manual, getHelper());
+		}
+		
+		for ( TOTorrentAnnounceURLSet set: sets ){
+			
+			URL[] urls = set.getAnnounceURLs();
+			
+			for ( URL u: urls ){
+				
+				String key = u.toExternalForm();
+				
+				StatusSummary summary = recent_responses.get( key );
+				
+				if ( summary == null ){
+					
+					summary = new StatusSummary( announcer, u );
+										
+					recent_responses.put( key, summary );
+					
+				}else{
+					
+					summary.setHelper( announcer );
+				}
+			}
+		}
+		
+		if ( provider != null ){
+			
+			announcer.setAnnounceDataProvider( provider );
+		}
+		
+		if ( ip_override != null ){
+			
+			announcer.setIPOverride( ip_override );
+		}
+		
+		return( announcer );
+	}
+	
+	
+	public TRTrackerAnnouncerResponse
+	getLastResponse()
+	{
+		TRTrackerAnnouncerResponse	result = null;
+		
+		TRTrackerAnnouncerHelper best = getBestActive();
+		
+		if ( best != null ){
+			
+			result = best.getLastResponse();
+		}
+		
+		if ( result == null ){
+			
+			result = last_response_informed;
+		}
+		
+		return( result );
+	}
+	
 
-			main_announcer = new TRTrackerBTAnnouncerImpl( torrent, sets, networks, manual, getHelper());
+	@Override
+	protected void
+	informResponse(
+		TRTrackerAnnouncerHelper		helper,
+		TRTrackerAnnouncerResponse		response )
+	{
+		URL	url = response.getURL();
+		
+			// can be null for external plugins (e.g. mldht...)
+		
+		if ( url != null ){
+			
+			synchronized( this ){
+				
+				String key = url.toExternalForm();
+				
+				StatusSummary summary = recent_responses.get( key );
+			
+				if ( summary != null ){
+				
+					summary.updateFrom( response );
+				}
+			}
+		}
+		
+		last_response_informed = response;
+		
+			// force recalc of best active next time
+		
+		last_best_active_set_time = 0;
+		
+		super.informResponse( helper, response );
+		
+		if ( response.getStatus() != TRTrackerAnnouncerResponse.ST_ONLINE ){
+			
+			URL	u = response.getURL();
+			
+			if ( u != null ){
+				
+				String s = u.toExternalForm();
+				
+				synchronized( failed_urls ){
+					
+					if ( failed_urls.contains( s )){
+						
+						return;
+					}
+					
+					failed_urls.add( s );
+				}
+			}
+			
+			checkActivation( true );
 		}
 	}
 	
+	public boolean
+	isManual()
+	{
+		return( is_manual );
+	}
+
 	public void
 	setAnnounceDataProvider(
-		TRTrackerAnnouncerDataProvider		provider )
+		TRTrackerAnnouncerDataProvider		_provider )
 	{
-		main_announcer.setAnnounceDataProvider( provider );
+		List<TRTrackerAnnouncerHelper>	to_set;
+		
+		synchronized( this ){
+			
+			provider	= _provider;
+			
+			to_set = announcers.getList();
+		}
 		
-		//System.out.println( "announcer set" );
+		for ( TRTrackerAnnouncer announcer: to_set ){
+		
+			announcer.setAnnounceDataProvider( provider );
+		}
 	}
 	
-	public TOTorrent
-	getTorrent()
+	protected TRTrackerAnnouncerHelper
+	getBestActive()
 	{
-		return( main_announcer.getTorrent());
+		long	now = SystemTime.getMonotonousTime();
+		
+		if ( now - last_best_active_set_time < 1000 ){
+			
+			return( last_best_active );
+		}
+		
+		last_best_active = getBestActiveSupport();
+		
+		last_best_active_set_time = now;
+		
+		return( last_best_active );
+	}
+	
+	protected TRTrackerAnnouncerHelper
+	getBestActiveSupport()
+	{
+		List<TRTrackerAnnouncerHelper> x = announcers.getList();
+		
+		TRTrackerAnnouncerHelper error_resp = null;
+		
+		for ( TRTrackerAnnouncerHelper announcer: x ){
+			
+			TRTrackerAnnouncerResponse response = announcer.getLastResponse();
+			
+			if ( response != null ){
+				
+				int	resp_status = response.getStatus();
+				
+				if ( resp_status == TRTrackerAnnouncerResponse.ST_ONLINE ){
+					
+					return( announcer );
+					
+				}else if ( error_resp == null && resp_status == TRTrackerAnnouncerResponse.ST_REPORTED_ERROR ){
+					
+					error_resp = announcer;
+				}
+			}
+		}
+		
+		if ( error_resp != null ){
+			
+			return( error_resp );
+		}
+		
+		if ( x.size() > 0 ){
+			
+			return( x.get(0));
+		}
+		
+		return( null );
 	}
 	
 	public URL
 	getTrackerURL()
 	{
-		return( main_announcer.getTrackerURL());
+		TRTrackerAnnouncerHelper	active = getBestActive();
+		
+		if ( active != null ){
+			
+			return( active.getTrackerURL());
+		}
+		
+		return( null );
 	}
 	
 	public void
 	setTrackerURL(
 		URL		url )
 	{
-		main_announcer.setTrackerURL( url );
-	}
+		List<List<String>> groups = new ArrayList<List<String>>();
 		
-	public void 
-	setTrackerURLs(
-		TOTorrentAnnounceURLSet[] 	sets ) 
-	{
-		Debug.out( "Not implemented" );
+		List<String> group = new ArrayList<String>();
+		
+		group.add( url.toExternalForm());
+		
+		groups.add( group );
+		
+		TorrentUtils.listToAnnounceGroups( groups, getTorrent());
+		
+		resetTrackerUrl( false );
 	}
 	
 	public void
 	resetTrackerUrl(
 		boolean	shuffle )
 	{
-		main_announcer.setTrackerURLs( getTorrent().getAnnounceURLGroup().getAnnounceURLSets());
+		try{
+			split();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+		
+		for ( TRTrackerAnnouncer announcer: announcers ){
 		
-		main_announcer.resetTrackerUrl( shuffle );
+			announcer.resetTrackerUrl( shuffle );
+		}
 	}
 	
 	public void
 	setIPOverride(
 		String		override )
 	{
-		main_announcer.setIPOverride( override );
-	}
-	
-	public void
-	cloneFrom(
-		TRTrackerAnnouncer	other )
-	{
-		main_announcer.cloneFrom( other );
+		List<TRTrackerAnnouncerHelper>	to_set;
+		
+		synchronized( this ){
+			
+			to_set	= announcers.getList();
+			
+			ip_override	= override;
+		}
+		
+		for ( TRTrackerAnnouncer announcer: to_set ){
+		
+			announcer.setIPOverride( override );
+		}
 	}
 	
 	public void
 	clearIPOverride()
 	{
-		main_announcer.clearIPOverride();
-	}
-	
-	public byte[]
-	getPeerId()
-	{
-		return( main_announcer.getPeerId());
+		List<TRTrackerAnnouncerHelper>	to_clear;
+		
+		synchronized( this ){
+			
+			to_clear	= announcers.getList();
+			
+			ip_override	= null;
+		}
+		
+		for ( TRTrackerAnnouncer announcer: to_clear ){
+		
+			announcer.clearIPOverride();
+		}
 	}
 	
 	public void
 	setRefreshDelayOverrides(
 		int		percentage )
 	{
-		main_announcer.setRefreshDelayOverrides( percentage );
+		for ( TRTrackerAnnouncer announcer: announcers ){
+		
+			announcer.setRefreshDelayOverrides( percentage );
+		}
 	}
 	
 	public int
 	getTimeUntilNextUpdate()
 	{
-		return( main_announcer.getTimeUntilNextUpdate());
+		TRTrackerAnnouncerHelper	active = getBestActive();
+
+		if ( active != null ){
+			
+			return( active.getTimeUntilNextUpdate());
+		}
+		
+		return( Integer.MAX_VALUE );
 	}
 	
 	public int
 	getLastUpdateTime()
 	{
-		return( main_announcer.getLastUpdateTime());
-	}
+		TRTrackerAnnouncerHelper	active = getBestActive();
+
+		if ( active != null ){
 			
+			return( active.getLastUpdateTime());
+		}
+		
+		return( 0 );
+	}	
+	
 	public void
 	update(
 		boolean	force )
 	{
-		main_announcer.update(force);
+		List<TRTrackerAnnouncerHelper> to_update;
+		
+		synchronized( this ){
+						
+			to_update = is_manual?announcers.getList():new ArrayList<TRTrackerAnnouncerHelper>( activated );
+		}
 		
-		//System.out.println( "update" );
+		for ( TRTrackerAnnouncer announcer: to_update ){
+		
+			announcer.update(force);
+		}
 	}
 	
 	public void
 	complete(
 		boolean	already_reported )
 	{
-		main_announcer.complete(already_reported);
+		List<TRTrackerAnnouncerHelper> to_complete;
 		
-		//System.out.println( "complete" );
+		synchronized( this ){
+			
+			complete	= true;
+			
+			to_complete = is_manual?announcers.getList():new ArrayList<TRTrackerAnnouncerHelper>( activated );
+		}
+		
+		for ( TRTrackerAnnouncer announcer: to_complete ){
+		
+			announcer.complete( already_reported );
+		}
 	}
 	
 	public void
 	stop(
 		boolean	for_queue )
 	{
-		main_announcer.stop( for_queue );
+		List<TRTrackerAnnouncerHelper> to_stop;
+		
+		synchronized( this ){
+			
+			stopped	= true;
+			
+			to_stop = is_manual?announcers.getList():new ArrayList<TRTrackerAnnouncerHelper>( activated );
+			
+			activated.clear();
+		}
+		
+		for ( TRTrackerAnnouncer announcer: to_stop ){
 		
-		//System.out.println( "stop" );
+			announcer.stop( for_queue );
+		}
 	}
 	
 	public void
@@ -186,53 +1186,518 @@ TRTrackerAnnouncerMuxer
 	{
 		TRTrackerAnnouncerFactoryImpl.destroy( this );
 
-		main_announcer.destroy();
+		List<TRTrackerAnnouncerHelper> to_destroy;
 		
-		//System.out.println( "destroy" );
+		synchronized( this ){
+			
+			destroyed = true;
+			
+			to_destroy = announcers.getList();
+		}
+		
+		for ( TRTrackerAnnouncer announcer: to_destroy ){
+		
+			announcer.destroy();
+		}
+		
+		TimerEvent	ev = event;
+		
+		if ( ev != null ){
+			
+			ev.cancel();
+		}
 	}
 	
 	public int
 	getStatus()
 	{
-		return( main_announcer.getStatus());
-	}
-	
-	public boolean
-	isManual()
-	{
-		return( main_announcer.isManual());
+		TRTrackerAnnouncer	max_announcer = getBestAnnouncer();
+		
+		return( max_announcer==null?-1:max_announcer.getStatus());
 	}
-	
+		
 	public String
 	getStatusString()
-	{
-		return( main_announcer.getStatusString());
+	{		
+		TRTrackerAnnouncer	max_announcer = getBestAnnouncer();
+		
+		return( max_announcer==null?"":max_announcer.getStatusString());
 	}
 	
-	public TRTrackerAnnouncerResponse
-	getLastResponse()
+	public TRTrackerAnnouncer
+	getBestAnnouncer()
 	{
-		return( main_announcer.getLastResponse());
+		int	max = -1;
+		
+		TRTrackerAnnouncer	max_announcer = null;
+		
+		for ( TRTrackerAnnouncer announcer: announcers ){
+			
+			int	status = announcer.getStatus();
+			
+			if ( status > max ){
+				
+				max_announcer 	= announcer;
+				max				= status;
+			}
+		}
+		
+		return( max_announcer==null?this:max_announcer );
 	}
 	
-	
 	public void
 	refreshListeners()
 	{
-		main_announcer.refreshListeners();	
+		informURLRefresh();
 	}
 	
 	public void
 	setAnnounceResult(
 		DownloadAnnounceResult	result )
 	{
-		main_announcer.setAnnounceResult(result);
+			// this is only used for setting DHT results
+		
+		for ( TRTrackerAnnouncer announcer: announcers ){
+			
+			if ( announcer instanceof TRTrackerDHTAnnouncerImpl ){
+				
+				announcer.setAnnounceResult( result );
+				
+				return;
+			}
+		}
+		
+			// TODO: we should always create a DHT entry and have it denote DHT tracking for all circustances
+			// have the DHT plugin set it to offline if disabled
+		
+		List<TRTrackerAnnouncerHelper> x = announcers.getList();
+		
+		if ( x.size() > 0 ){
+			
+			x.get(0).setAnnounceResult( result );
+		}
 	}
 		
+	protected int
+	getPeerCacheLimit()
+	{
+		synchronized( this ){
+			
+			if ( activated.size() < announcers.size()){
+				
+				return( 0 );
+			}
+		}
+		
+		if ( SystemTime.getMonotonousTime() - create_time < 15*1000 ){
+			
+			return( 0 );
+		}
+		
+		TRTrackerAnnouncer active = getBestActive();
+		
+		if ( active != null && provider != null && active.getStatus() == TRTrackerAnnouncerResponse.ST_ONLINE ){
+			
+			if ( 	provider.getMaxNewConnectionsAllowed() > 0 &&
+					provider.getPendingConnectionCount() == 0 ){
+				
+				return( 5 );
+				
+			}else{
+				
+				return( 0 );
+			}
+		}
+		
+		return( 10 );
+	}
+	
+	public TrackerPeerSource 
+	getTrackerPeerSource(
+		final TOTorrentAnnounceURLSet		set )
+	{
+		URL[]	urls = set.getAnnounceURLs();
+		
+		final String[] url_strs = new String[ urls.length ];
+		
+		for ( int i=0;i<urls.length;i++ ){
+			
+			url_strs[i] = urls[i].toExternalForm();
+		}
+		
+		return( 
+			new TrackerPeerSource()
+			{
+				private StatusSummary		_summary;
+				private boolean				enabled;
+				private long				fixup_time;
+				
+				private StatusSummary
+				fixup()
+				{
+					long now = SystemTime.getMonotonousTime();
+					
+					if ( now - fixup_time > 1000 ){
+												
+						long			most_recent	= 0;
+						StatusSummary	summary	 	= null;
+						
+						synchronized( TRTrackerAnnouncerMuxer.this ){
+						
+							for ( String str: url_strs ){
+							
+								StatusSummary s = recent_responses.get( str );
+								
+								if ( s != null ){
+									
+									if ( summary == null || s.getTime() > most_recent ){
+										
+										summary		= s;
+										most_recent	= s.getTime();
+									}
+								}
+							}	
+						}
+						
+						if ( provider != null ){
+						
+							enabled = provider.isPeerSourceEnabled( PEPeerSource.PS_BT_TRACKER );
+						}
+						
+						if ( summary != null ){
+							
+							_summary = summary;
+						}
+						
+						fixup_time = now;
+					}
+					
+					return( _summary );
+				}
+				
+				public int
+				getType()
+				{
+					return( TrackerPeerSource.TP_TRACKER );
+				}
+				
+				public String
+				getName()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						String str =summary.getURL().toExternalForm();
+						
+						int pos = str.indexOf( '?' );
+						
+						if ( pos != -1 ){
+							
+							str = str.substring( 0, pos );
+						}
+						
+						return( str );
+					}
+					
+					return( url_strs[0] );
+				}
+				
+				public int
+				getStatus()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( !enabled ){
+						
+						return( ST_DISABLED );
+					}
+					
+					if ( summary != null ){
+						
+						return( summary.getStatus());
+					}
+					
+					return( ST_QUEUED );
+				}
+				
+				public String
+				getStatusString()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null && enabled ){
+						
+						return( summary.getStatusString());
+					}
+					
+					return( null );
+				}
+						
+				public int
+				getSeedCount()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						return( summary.getSeedCount());
+					}
+					
+					return( -1 );
+				}
+				
+				public int
+				getLeecherCount()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						return( summary.getLeecherCount());
+					}
+					
+					return( -1 );
+				}			
+				
+				public int
+				getPeers()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						return( summary.getPeers());
+					}
+					
+					return( -1 );
+				}			
+
+				public int
+				getSecondsToUpdate()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						return( summary.getSecondsToUpdate());
+					}
+					
+					return( -1 );
+				}
+				
+				public int
+				getInterval()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						return( summary.getInterval());
+					}
+					
+					return( -1 );
+				}
+				
+				public int
+				getMinInterval()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null && enabled ){
+						
+						return( summary.getMinInterval());
+					}
+					
+					return( -1 );
+				}
+				
+				public boolean
+				isUpdating()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null && enabled  ){
+						
+						return( summary.isUpdating());
+					}
+					
+					return( false );
+				}
+				
+				public boolean
+				canManuallyUpdate()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary == null ){
+						
+						return( false );
+					}
+					
+					return( summary.canManuallyUpdate());
+				}
+				
+				public void
+				manualUpdate()
+				{
+					StatusSummary summary = fixup();
+					
+					if ( summary != null ){
+						
+						summary.manualUpdate();
+					}
+				}
+			});
+	}
+	
 	public void 
 	generateEvidence(
 		IndentWriter writer )
 	{
-		main_announcer.generateEvidence(writer);
+		for ( TRTrackerAnnouncer announcer: announcers ){
+		
+			announcer.generateEvidence(writer);
+		}
+	}
+	
+	private static class
+	StatusSummary
+	{
+		private TRTrackerAnnouncerHelper		helper;
+		
+		private long		time;
+		private URL			url;
+		private int			status;
+		private String		status_str;
+		private int			seeds		= -1;
+		private int			leechers	= -1;
+		private int			peers		= -1;
+		
+		private int			interval;
+		private int			min_interval;
+		
+		protected 
+		StatusSummary(
+			TRTrackerAnnouncerHelper		_helper,
+			URL								_url )
+		{
+			helper	= _helper;
+			url		= _url;
+			
+			status = TrackerPeerSource.ST_QUEUED;
+		}
+		
+		protected void
+		setHelper(
+			TRTrackerAnnouncerHelper		_helper )
+		{
+			helper	= _helper;
+		}
+		
+		protected void
+		updateFrom(
+			TRTrackerAnnouncerResponse		response )
+		{			
+			time	= SystemTime.getMonotonousTime();
+			
+			int	state = response.getStatus();
+			
+			if ( state == TRTrackerAnnouncerResponse.ST_ONLINE ){
+				
+				status = TrackerPeerSource.ST_ONLINE;
+			
+				seeds		= response.getScrapeCompleteCount();
+				leechers	= response.getScrapeIncompleteCount();
+				peers		= response.getPeers().length;
+				
+			}else{
+				
+				status = TrackerPeerSource.ST_ERROR;
+			}
+			
+			status_str = response.getStatusString();
+			
+			interval 		= (int)helper.getInterval();
+			min_interval 	= (int)helper.getMinInterval();
+		}
+		
+		public long
+		getTime()
+		{
+			return( time );
+		}
+		
+		public URL
+		getURL()
+		{
+			return( url );
+		}
+		
+		public int
+		getStatus()
+		{
+			return( status );
+		}
+		
+		public String
+		getStatusString()
+		{
+			return( status_str );
+		}
+		
+		public int
+		getSeedCount()
+		{
+			return( seeds );
+		}
+		
+		public int
+		getLeecherCount()
+		{
+			return( leechers );
+		}
+		
+		public int
+		getPeers()
+		{
+			return( peers );
+		}
+		
+		public boolean
+		isUpdating()
+		{
+			return( helper.isUpdating());
+		}
+		
+		public int
+		getInterval()
+		{
+			return( interval );
+		}
+		
+		public int
+		getMinInterval()
+		{
+			return( min_interval );
+		}
+		
+		public int
+		getSecondsToUpdate()
+		{
+			return( helper.getTimeUntilNextUpdate());
+		}
+		
+		public boolean
+		canManuallyUpdate()
+		{
+			return( ((SystemTime.getCurrentTime() / 1000 - helper.getLastUpdateTime() >= TRTrackerAnnouncer.REFRESH_MINIMUM_SECS)));
+		}
+		
+		public void
+		manualUpdate()
+		{
+			helper.update( true );
+		}
 	}
 }
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponseImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponseImpl.java
index 5094530..89dd3c8 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponseImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponseImpl.java
@@ -37,6 +37,7 @@ TRTrackerAnnouncerResponseImpl
 	private long			time_to_wait;
 	private String			failure_reason;
 	
+	private boolean			was_udp_probe		= false;
 	private int				scrape_complete		= -1;
 	private int				scrape_incomplete	= -1;
 	
@@ -111,6 +112,11 @@ TRTrackerAnnouncerResponseImpl
 		}else if  (status == ST_ONLINE ){
 			
 			str = "OK";
+			
+			if ( was_udp_probe ){
+				
+				str += " (UDP Probe)";
+			}
 		}else{
 			
 			str = "Failed";
@@ -124,10 +130,25 @@ TRTrackerAnnouncerResponseImpl
 		return( str );
 	}
 	
-	public void setFailurReason(String reason) {
+	public void 
+	setFailureReason(
+		String reason) 
+	{
 		failure_reason = reason;
 	}
 	
+	public void
+	setWasProbe()
+	{
+		was_udp_probe = true;
+	}
+	
+	public boolean
+	wasProbe()
+	{
+		return( was_udp_probe );
+	}
+	
 	public long
 	getTimeToWait()
 	{
@@ -197,7 +218,7 @@ TRTrackerAnnouncerResponseImpl
 	print()
 	{
 		System.out.println( "TRTrackerResponse::print");
-		System.out.println( "\tstatus = " + getStatus());
+		System.out.println( "\tstatus = " + getStatus() + ", probe = " + was_udp_probe );
 		System.out.println( "\tfail msg = " + getAdditionalInfo());
 		System.out.println( "\tpeers:" );
 		
@@ -215,7 +236,7 @@ TRTrackerAnnouncerResponseImpl
 	public String
 	getString()
 	{
-		String	str = "url=" + url + ", status=" + getStatus();
+		String	str = "url=" + url + ", status=" + getStatus() + ", probe=" + was_udp_probe;
 		
 		if ( getStatus() != ST_ONLINE ){
 			
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponsePeerImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponsePeerImpl.java
index dca1108..7d46dd9 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponsePeerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerAnnouncerResponsePeerImpl.java
@@ -24,6 +24,7 @@ package org.gudy.azureus2.core3.tracker.client.impl;
 
 import org.gudy.azureus2.core3.tracker.client.*;
 import org.gudy.azureus2.core3.util.StringInterner;
+import org.gudy.azureus2.plugins.download.DownloadAnnounceResultPeer;
 
 public class 
 TRTrackerAnnouncerResponsePeerImpl
@@ -122,6 +123,20 @@ TRTrackerAnnouncerResponsePeerImpl
 		return( address + ":" + tcp_port );
 	}
 	
+	public int 
+	compareTo(
+		TRTrackerAnnouncerResponsePeer other ) 
+	{
+		return( getString2( this ).compareTo( getString2( other )));
+	}
+	
+	private String
+	getString2(
+		TRTrackerAnnouncerResponsePeer	peer )
+	{
+		return( peer.getAddress() + ":" + peer.getPort() + ":" + peer.getHTTPPort() + ":" + peer.getUDPPort());
+	}
+	
 	public String
 	getString()
 	{
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
index 4277a2b..9b350ba 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperImpl.java
@@ -157,6 +157,26 @@ TRTrackerScraperImpl
 	}
 		
 	public TRTrackerScraperResponse
+	peekScrape(
+		TOTorrent		torrent,
+		URL				target_url )
+	{
+		if ( torrent == null ){
+			
+			return null;
+		}
+
+		if ( TorrentUtils.isDecentralised( torrent )){
+			
+			return( dht_scraper.peekScrape( torrent, target_url ));
+			
+		}else{
+			
+			return( bt_scraper.peekScrape( torrent, target_url ));
+		}
+	}
+	
+	public TRTrackerScraperResponse
 	scrape(
 		TRTrackerAnnouncer	tracker_client )
 	{
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperResponseImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperResponseImpl.java
index 2a13db3..e00ac15 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperResponseImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/TRTrackerScraperResponseImpl.java
@@ -181,6 +181,9 @@ TRTrackerScraperResponseImpl
     return !(seeds == -1 && peers == -1);
   }
   
+  public abstract void
+  setDHTBackup(
+		boolean	is_backup );
   
   /**
 	 * add the same, random value per session so that azureus peers diverge over
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 f69a504..bf54790 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTAnnouncerImpl.java
@@ -65,6 +65,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.azureus.core.tracker.TrackerPeerSource;
 import com.aelitis.net.udp.uc.*;
 
 
@@ -77,10 +78,10 @@ import com.aelitis.net.udp.uc.*;
  */
 public class 
 TRTrackerBTAnnouncerImpl
-	implements TRTrackerAnnouncer
+	implements TRTrackerAnnouncerHelper
 {
 	public final static LogIDs LOGID = LogIDs.TRACKER;
-		
+	
 	private static final int OVERRIDE_PERIOD			= 10*1000;
 	 
 	protected static Timer	tracker_timer = new Timer( "Tracker Timer", 32);
@@ -89,7 +90,9 @@ TRTrackerBTAnnouncerImpl
 	
 	private static int userMinInterval = 0;
 	private static int userMaxNumwant = 100;
-	private static boolean udpAnnounceEnabled = true;
+	private static boolean tcpAnnounceEnabled;
+	private static boolean udpAnnounceEnabled;
+	private static boolean udpProbeEnabled;
 
     static{
 	  	PRUDPTrackerCodecs.registerCodecs();
@@ -97,7 +100,9 @@ TRTrackerBTAnnouncerImpl
 	  		new String[] {
 	  			"Tracker Client Min Announce Interval",
 	  			"Tracker Client Numwant Limit",
-	  			"Server Enable UDP"
+	  			"Tracker Client Enable TCP",
+	  			"Server Enable UDP",
+	  			"Tracker UDP Probe Enable"
 	  			},
 	  		new ParameterListener()
 	  		{
@@ -105,7 +110,9 @@ TRTrackerBTAnnouncerImpl
 	  			{
 	  				userMinInterval = COConfigurationManager.getIntParameter("Tracker Client Min Announce Interval");
 	  				userMaxNumwant = COConfigurationManager.getIntParameter("Tracker Client Numwant Limit");
+					tcpAnnounceEnabled = COConfigurationManager.getBooleanParameter("Tracker Client Enable TCP");
 	  				udpAnnounceEnabled = COConfigurationManager.getBooleanParameter("Server Enable UDP");
+					udpProbeEnabled  = COConfigurationManager.getBooleanParameter("Tracker UDP Probe Enable");
 	  			}	  		
 	  		});
     }
@@ -129,7 +136,11 @@ TRTrackerBTAnnouncerImpl
 	private long				current_time_to_wait_secs;
 	private boolean				manual_control;
   
-	private long min_interval = 0;
+	private long		tracker_interval;
+	private long		tracker_min_interval;
+	
+	
+	private long 		min_interval = 0;
 	
 	private int  failure_added_time = 0;
     private long failure_time_last_updated = 0;
@@ -160,17 +171,13 @@ TRTrackerBTAnnouncerImpl
 	private String tracker_peer_id_str = "&peer_id=";
 	
 	private byte[] data_peer_id;
-	
-	private String 					key_id			= "";
-	private static final int	   	key_id_length	= 8;
-	private int						key_udp;
-	
-	
+		
 	
 	private int announceCount;
 	private int announceFailCount;
 	
 	private byte autoUDPprobeEvery = 1;
+	private int autoUDPProbeSuccessCount;
 	
   
 	private String tracker_id = "";
@@ -188,21 +195,6 @@ TRTrackerBTAnnouncerImpl
 	private boolean	destroyed;
 		
 
-
-	static final String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-	public static String
-	createKeyID()
-	{
-		String	key_id = "";
-		
-		for (int i = 0; i < key_id_length; i++) {
-			int pos = (int) ( Math.random() * chars.length());
-		    key_id +=  chars.charAt(pos);
-		}
-		
-		return( key_id );
-	}
 	
   public 
   TRTrackerBTAnnouncerImpl(
@@ -227,24 +219,20 @@ TRTrackerBTAnnouncerImpl
 		//Create our unique peerId
 	
 	try{
-	    tracker_peer_id = ClientIDManagerImpl.getSingleton().generatePeerID( torrent, true );
+		data_peer_id = helper.getPeerID();
 	
 	    if ( COConfigurationManager.getBooleanParameter("Tracker Separate Peer IDs")){
-	    	
-	    	data_peer_id = ClientIDManagerImpl.getSingleton().generatePeerID( torrent, false );
+	       	
+	    	tracker_peer_id = ClientIDManagerImpl.getSingleton().generatePeerID( torrent, true );
 	    	
 	    }else{
 	    	
-	    	data_peer_id	= tracker_peer_id;
+	    	tracker_peer_id	= data_peer_id;
 	    }
 	}catch( ClientIDException e ){
 
 		 throw( new TRTrackerAnnouncerException( "TRTrackerAnnouncer: Peer ID generation fails", e ));
 	}
-
-    key_id	= createKeyID();
-    
-	key_udp	= (int)(Math.random() *  0xFFFFFFFFL );
 	
 	try {
 	
@@ -362,24 +350,15 @@ TRTrackerBTAnnouncerImpl
   	
 	public void
 	cloneFrom(
-		TRTrackerAnnouncer	_other )
+		TRTrackerBTAnnouncerImpl	other )
 	{
-		if ( _other instanceof TRTrackerBTAnnouncerImpl ){
-			
-			TRTrackerBTAnnouncerImpl	other = (TRTrackerBTAnnouncerImpl)_other;
-			
-			data_peer_id			= other.data_peer_id;
-			tracker_peer_id			= other.tracker_peer_id;
-			tracker_peer_id_str		= other.tracker_peer_id_str;
-			tracker_id				= other.tracker_id;
-			key_id					= other.key_id;
-			key_udp					= other.key_udp;
-	
-			announce_data_provider	= other.announce_data_provider;
-		}else{
-			
-			Debug.out( "Incompatible type" );
-		}
+		helper					= other.helper;
+		data_peer_id			= other.data_peer_id;
+		tracker_peer_id			= other.tracker_peer_id;
+		tracker_peer_id_str		= other.tracker_peer_id_str;
+		tracker_id				= other.tracker_id;
+
+		announce_data_provider	= other.announce_data_provider;
 	}
 	
 	protected long
@@ -472,6 +451,12 @@ TRTrackerBTAnnouncerImpl
   		return( tracker_status_str );
   	}
   	
+	public TRTrackerAnnouncer
+	getBestAnnouncer()
+	{
+		return( this );
+	}
+	
 	public void
 	setRefreshDelayOverrides(
 		int		percentage )
@@ -535,6 +520,24 @@ TRTrackerBTAnnouncerImpl
 		}
 	}
 	
+	public boolean
+	isUpdating()
+	{
+		return( update_in_progress );
+	}
+	
+	public long
+	getInterval()
+	{
+		return( tracker_interval );
+	}
+	
+	public long
+	getMinInterval()
+	{
+		return( tracker_min_interval );
+	}
+	
 	public int
 	getTimeUntilNextUpdate()
 	{
@@ -754,6 +757,10 @@ TRTrackerBTAnnouncerImpl
 						
 						tracker_status_str = MessageText.getString("PeerManager.status.ok");
 
+						if ( response.wasProbe()){
+							
+							tracker_status_str += " (" + MessageText.getString( "label.udp_probe" ) + ")"; 
+						}
 					}else{
 						
 						tracker_status_str = MessageText.getString("PeerManager.status.ps_disabled");
@@ -770,7 +777,7 @@ TRTrackerBTAnnouncerImpl
 				
 				last_response = response;
 				
-				helper.informResponse( response );
+				helper.informResponse( this, response );
 				
 				return( response.getTimeToWait());
 			}
@@ -930,12 +937,21 @@ TRTrackerBTAnnouncerImpl
 		  
 		  URL	request_url = null;
 		  
+		  if ( last_failure_resp != null ){
+			  
+			  	// report this now as it is about to be lost
+			  
+			  helper.informResponse( this, last_failure_resp );
+		  }
+		  
 		  try{
 		  
 		  	request_url = constructUrl(evt,original_url);
 			  			
 		  	URL[]	tracker_url = { original_url };
 		  	
+		  	int	prev_udp_probes_ok = autoUDPProbeSuccessCount;
+		  	
 		  	byte[]	result_bytes = updateOld( tracker_url, request_url);
 		  	
 		  	lastUsedUrl = tracker_url[0];	// url may have redirected, use this value as it will be correct
@@ -946,6 +962,10 @@ TRTrackerBTAnnouncerImpl
 			
 		    if ( resp_status == TRTrackerAnnouncerResponse.ST_ONLINE ){
 					
+		    	if ( autoUDPProbeSuccessCount > prev_udp_probes_ok ){
+		    		
+		    		resp.setWasProbe();
+		    	}
 		    	try{
 		    			// tracker looks ok, make any redirection permanent
 		    		
@@ -1108,14 +1128,21 @@ TRTrackerBTAnnouncerImpl
 			  		
 			  			// if we have multiple tracker URLs then do something sensible about
 			  		
-			  		if ( protocol.equalsIgnoreCase("udp") && udpAnnounceEnabled ){
+			  		if ( protocol.equalsIgnoreCase("udp")){
+			  			
+			  			if ( udpAnnounceEnabled ){
 			  			
-						udpAnnounceURL = reqUrl;
+			  				udpAnnounceURL = reqUrl;
+			  				
+			  			}else{
+			  				
+			  				throw( new IOException( "UDP Tracker protocol disabled" ));
+			  			}
 						
 					}else if (	protocol.equalsIgnoreCase("http") && 
 								!az_tracker	&& 
 								announceCount % autoUDPprobeEvery == 0 && 
-								udpAnnounceEnabled ){
+								udpProbeEnabled && udpAnnounceEnabled ){
 						
 							// if we don't know this tracker supports UDP then don't probe on
 							// first announce as we don't want a large delay on torrent startup
@@ -1130,9 +1157,15 @@ TRTrackerBTAnnouncerImpl
 							// skip probe
 							
 						}else{
-							udpAnnounceURL = new URL(reqUrl.toString().replaceFirst("^http", "udp"));
 							
-							udp_probe = true;
+				  			String	tracker_network	= AENetworkClassifier.categoriseAddress( reqUrl.getHost()); 
+
+				  			if ( tracker_network == AENetworkClassifier.AT_PUBLIC ){
+
+				  				udpAnnounceURL = new URL(reqUrl.toString().replaceFirst("^http", "udp"));
+							
+				  				udp_probe = true;
+				  			}
 						}
 					}
 			  				
@@ -1168,6 +1201,7 @@ TRTrackerBTAnnouncerImpl
 							}
 							
 							autoUDPprobeEvery = 1;
+							autoUDPProbeSuccessCount++;
 						}
 					}
 			  		
@@ -1175,7 +1209,24 @@ TRTrackerBTAnnouncerImpl
 			  		
 			  		if ( udpAnnounceURL == null){
 			  			
-			  			failure_reason = announceHTTP( tracker_url, reqUrl, message );
+			  			boolean	failed = false;
+			  			
+			  			if ( !az_tracker && !tcpAnnounceEnabled ){
+			  				
+			  				String	tracker_network	= AENetworkClassifier.categoriseAddress( reqUrl.getHost()); 
+
+				  			if ( tracker_network == AENetworkClassifier.AT_PUBLIC ){
+				  				
+				  				failure_reason = "HTTP Tracker protocol disabled";
+				  				
+				  				failed = true;
+				  			}
+			  			}
+			  			
+			  			if ( !failed ){
+			  			
+			  				failure_reason = announceHTTP( tracker_url, reqUrl, message );
+			  			}
 			  		}
 	
 			  			// if we've got some kind of response then return it
@@ -1188,6 +1239,11 @@ TRTrackerBTAnnouncerImpl
 					if ( failure_reason == null ){
 						
 						failure_reason = "No data received from tracker";
+						
+						if ( reqUrl.getProtocol().equalsIgnoreCase( "udp" )){
+						
+							errorLevel = false;
+						}
 					}
 				}catch( SSLException e ){
 					
@@ -1215,8 +1271,10 @@ TRTrackerBTAnnouncerImpl
 					}
 				}catch( IOException e ){
 					
-					if(e instanceof UnknownHostException)
+					if ( e instanceof UnknownHostException || e instanceof ConnectException ){
+						
 						errorLevel = false;
+					}
 					
 		     		if ( i == 0 && protocol.toLowerCase().startsWith( "http" )){
 		      			
@@ -1332,6 +1390,14 @@ TRTrackerBTAnnouncerImpl
  		}
  		
  		
+		if ( con instanceof HttpURLConnection ){
+			
+				// we want this true but some plugins (grrr) set the global default not to follow
+				// redirects
+		
+			((HttpURLConnection)con).setInstanceFollowRedirects( true );
+		}
+		
  		String	user_agent = (String)http_properties.get( ClientIDGenerator.PR_USER_AGENT );
  		
  		if ( user_agent != null ){
@@ -1513,221 +1579,229 @@ TRTrackerBTAnnouncerImpl
  			PRUDPPacketHandler handler = PRUDPPacketHandlerFactory.getHandler( UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber());
  			
  			InetSocketAddress destination = new InetSocketAddress(reqUrl.getHost(),reqUrl.getPort()==-1?80:reqUrl.getPort());
+
+ 			handler = handler.openSession( destination );
  			
- 			for (int retry_loop=0;retry_loop<PRUDPPacketTracker.DEFAULT_RETRY_COUNT;retry_loop++){
- 				
- 				try{
- 			
-		 			PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
-		 			
-		 			PRUDPPacket reply = handler.sendAndReceive( auth, connect_request, destination, timeout );
-		 			
-		 			if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_CONNECT ){
-		 			
-		 				PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect)reply;
-		 				
-		 				long	my_connection = connect_reply.getConnectionId();
-		 			
-		 				PRUDPPacketRequest request;
-		 				
-		 				if ( PRUDPPacketTracker.VERSION == 1 ){
-		 					
-		 					PRUDPPacketRequestAnnounce announce_request = new PRUDPPacketRequestAnnounce( my_connection );
-		 		
-		 					request = announce_request;
-		 					
-			 					// bit of a hack this...
-			 				
-			 				String	url_str = reqUrl.toString();
-			 				
-			 				int		p_pos = url_str.indexOf("?");
-			 				
-			 				url_str	= url_str.substring(p_pos+1);
-			 				
-			 				String event_str = getURLParam( url_str, "event" );
+ 			try{
+	 			
+	 			for (int retry_loop=0;retry_loop<PRUDPPacketTracker.DEFAULT_RETRY_COUNT;retry_loop++){
+	 				
+	 				try{
+	 			
+			 			PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
+			 			
+			 			PRUDPPacket reply = handler.sendAndReceive( auth, connect_request, destination, timeout );
+			 			
+			 			if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_CONNECT ){
+			 			
+			 				PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect)reply;
 			 				
-			 				int	event = PRUDPPacketRequestAnnounce.EV_UPDATE;
+			 				long	my_connection = connect_reply.getConnectionId();
+			 			
+			 				PRUDPPacketRequest request;
 			 				
-			 				if ( event_str != null ){
+			 				if ( PRUDPPacketTracker.VERSION == 1 ){
 			 					
-			 					if ( event_str.equals( "started" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_STARTED;
-			 						
-			 					}else if ( event_str.equals( "stopped" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_STOPPED;
-			 						
-			 					}else if ( event_str.equals( "completed" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
-			 					}
-			 				}
-			 				
-			 				String	ip_str = getURLParam( url_str, "ip" );
-			 				
-			 				int	ip = 0;
-			 				
-			 				if ( ip_str != null ){
+			 					PRUDPPacketRequestAnnounce announce_request = new PRUDPPacketRequestAnnounce( my_connection );
+			 		
+			 					request = announce_request;
 			 					
-			 					ip = PRHelpers.addressToInt( ip_str);
-			 				}
-			 				
-			 				announce_request.setDetails(
-			 					torrent_hash.getBytes(),
-			 					tracker_peer_id,
-								getLongURLParam( url_str, "downloaded" ), 
-								event,
-								ip,
-								(int)getLongURLParam( url_str, "numwant" ), 
-								getLongURLParam( url_str, "left" ), 
-								(short)getLongURLParam( url_str, "port" ),
-								getLongURLParam( url_str, "uploaded" ));
-		 				
-		 				}else{
-		 					PRUDPPacketRequestAnnounce2 announce_request = new PRUDPPacketRequestAnnounce2( my_connection );
-		 					
-		 					request = announce_request;
-		 					
-		 					// bit of a hack this...
-			 				
-			 				String	url_str = reqUrl.toString();
+				 					// bit of a hack this...
+				 				
+				 				String	url_str = reqUrl.toString();
+				 				
+				 				int		p_pos = url_str.indexOf("?");
+				 				
+				 				url_str	= url_str.substring(p_pos+1);
+				 				
+				 				String event_str = getURLParam( url_str, "event" );
+				 				
+				 				int	event = PRUDPPacketRequestAnnounce.EV_UPDATE;
+				 				
+				 				if ( event_str != null ){
+				 					
+				 					if ( event_str.equals( "started" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_STARTED;
+				 						
+				 					}else if ( event_str.equals( "stopped" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_STOPPED;
+				 						
+				 					}else if ( event_str.equals( "completed" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
+				 					}
+				 				}
+				 				
+				 				String	ip_str = getURLParam( url_str, "ip" );
+				 				
+				 				int	ip = 0;
+				 				
+				 				if ( ip_str != null ){
+				 					
+				 					ip = PRHelpers.addressToInt( ip_str);
+				 				}
+				 				
+				 				announce_request.setDetails(
+				 					torrent_hash.getBytes(),
+				 					tracker_peer_id,
+									getLongURLParam( url_str, "downloaded" ), 
+									event,
+									ip,
+									(int)getLongURLParam( url_str, "numwant" ), 
+									getLongURLParam( url_str, "left" ), 
+									(short)getLongURLParam( url_str, "port" ),
+									getLongURLParam( url_str, "uploaded" ));
 			 				
-			 				int		p_pos = url_str.indexOf("?");
-			 				
-			 				url_str	= url_str.substring(p_pos+1);
-			 				
-			 				String event_str = getURLParam( url_str, "event" );
-			 				
-			 				int	event = PRUDPPacketRequestAnnounce.EV_UPDATE;
-			 				
-			 				if ( event_str != null ){
+			 				}else{
+			 					PRUDPPacketRequestAnnounce2 announce_request = new PRUDPPacketRequestAnnounce2( my_connection );
 			 					
-			 					if ( event_str.equals( "started" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_STARTED;
-			 						
-			 					}else if ( event_str.equals( "stopped" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_STOPPED;
-			 						
-			 					}else if ( event_str.equals( "completed" )){
-			 						
-			 						event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
-			 					}
-			 				}
-			 				
-			 				String	ip_str = getURLParam( url_str, "ip" );
-			 				
-			 				int	ip = 0;
-			 				
-			 				if ( ip_str != null ){
+			 					request = announce_request;
 			 					
-			 					ip = PRHelpers.addressToInt( ip_str);
+			 					// bit of a hack this...
+				 				
+				 				String	url_str = reqUrl.toString();
+				 				
+				 				int		p_pos = url_str.indexOf("?");
+				 				
+				 				url_str	= url_str.substring(p_pos+1);
+				 				
+				 				String event_str = getURLParam( url_str, "event" );
+				 				
+				 				int	event = PRUDPPacketRequestAnnounce.EV_UPDATE;
+				 				
+				 				if ( event_str != null ){
+				 					
+				 					if ( event_str.equals( "started" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_STARTED;
+				 						
+				 					}else if ( event_str.equals( "stopped" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_STOPPED;
+				 						
+				 					}else if ( event_str.equals( "completed" )){
+				 						
+				 						event = PRUDPPacketRequestAnnounce.EV_COMPLETED;
+				 					}
+				 				}
+				 				
+				 				String	ip_str = getURLParam( url_str, "ip" );
+				 				
+				 				int	ip = 0;
+				 				
+				 				if ( ip_str != null ){
+				 					
+				 					ip = PRHelpers.addressToInt( ip_str);
+				 				}
+				 				
+				 				announce_request.setDetails(
+				 					torrent_hash.getBytes(),
+				 					tracker_peer_id,
+									getLongURLParam( url_str, "downloaded" ), 
+									event,
+									ip,
+									helper.getUDPKey(),
+									(int)getLongURLParam( url_str, "numwant" ), 
+									getLongURLParam( url_str, "left" ), 
+									(short)getLongURLParam( url_str, "port" ),
+									getLongURLParam( url_str, "uploaded" ));	
 			 				}
 			 				
-			 				announce_request.setDetails(
-			 					torrent_hash.getBytes(),
-			 					tracker_peer_id,
-								getLongURLParam( url_str, "downloaded" ), 
-								event,
-								ip,
-								key_udp,
-								(int)getLongURLParam( url_str, "numwant" ), 
-								getLongURLParam( url_str, "left" ), 
-								(short)getLongURLParam( url_str, "port" ),
-								getLongURLParam( url_str, "uploaded" ));	
-		 				}
-		 				
-		 				reply = handler.sendAndReceive( auth, request, destination );
-		 			
-		 				if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_ANNOUNCE ){
-		 					
-		 					if ( auth != null ){
-		 						
-		 						SESecurityManager.setPasswordAuthenticationOutcome( UDP_REALM, reqUrl, true );
-		 					}
-		 					
-		 					if ( PRUDPPacketTracker.VERSION == 1 ){
-			 					PRUDPPacketReplyAnnounce	announce_reply = (PRUDPPacketReplyAnnounce)reply;
-			 					
-			 					Map	map = new HashMap();
-			 					
-			 					map.put( "interval", new Long( announce_reply.getInterval()));
+			 				reply = handler.sendAndReceive( auth, request, destination );
+			 			
+			 				if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_ANNOUNCE ){
 			 					
-			 					int[]	addresses 	= announce_reply.getAddresses();
-			 					short[]	ports		= announce_reply.getPorts();
-			 					
-			 					List	peers = new ArrayList();
-			 					
-			 					map.put( "peers", peers );
-			 					
-			 					for (int i=0;i<addresses.length;i++){
+			 					if ( auth != null ){
 			 						
-			 						Map	peer = new HashMap();
-			 						
-			 						peers.add( peer );
-			 						
-			 						peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
-			 						peer.put( "port", new Long( ports[i]));
+			 						SESecurityManager.setPasswordAuthenticationOutcome( UDP_REALM, reqUrl, true );
 			 					}
 			 					
-			 					byte[] data = BEncoder.encode( map );
-			 					
-			 					message.write( data );
-			 					
-			 					return( null );
-			 					
-		 					}
-		 					
-			 					PRUDPPacketReplyAnnounce2	announce_reply = (PRUDPPacketReplyAnnounce2)reply;
-			 					
-			 					Map	map = new HashMap();
-			 					
-			 					map.put( "interval", new Long( announce_reply.getInterval()));
-			 					
-			 					int[]	addresses 	= announce_reply.getAddresses();
-			 					short[]	ports		= announce_reply.getPorts();
-			 					
-			 					map.put( "complete", new Long(announce_reply.getSeeders()));
-			 					map.put( "incomplete", new Long(announce_reply.getLeechers()));
-			 					
-			 					List	peers = new ArrayList();
-			 					
-			 					map.put( "peers", peers );
-			 					
-			 					for (int i=0;i<addresses.length;i++){
-			 						
-			 						Map	peer = new HashMap();
-			 						
-			 						peers.add( peer );
-			 						
-			 						peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
-			 						peer.put( "port", new Long( ports[i]));
+			 					if ( PRUDPPacketTracker.VERSION == 1 ){
+				 					PRUDPPacketReplyAnnounce	announce_reply = (PRUDPPacketReplyAnnounce)reply;
+				 					
+				 					Map	map = new HashMap();
+				 					
+				 					map.put( "interval", new Long( announce_reply.getInterval()));
+				 					
+				 					int[]	addresses 	= announce_reply.getAddresses();
+				 					short[]	ports		= announce_reply.getPorts();
+				 					
+				 					List	peers = new ArrayList();
+				 					
+				 					map.put( "peers", peers );
+				 					
+				 					for (int i=0;i<addresses.length;i++){
+				 						
+				 						Map	peer = new HashMap();
+				 						
+				 						peers.add( peer );
+				 						
+				 						peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
+				 						peer.put( "port", new Long( ports[i]));
+				 					}
+				 					
+				 					byte[] data = BEncoder.encode( map );
+				 					
+				 					message.write( data );
+				 					
+				 					return( null );
+				 					
 			 					}
 			 					
-			 					byte[] data = BEncoder.encode( map );
+				 					PRUDPPacketReplyAnnounce2	announce_reply = (PRUDPPacketReplyAnnounce2)reply;
+				 					
+				 					Map	map = new HashMap();
+				 					
+				 					map.put( "interval", new Long( announce_reply.getInterval()));
+				 					
+				 					int[]	addresses 	= announce_reply.getAddresses();
+				 					short[]	ports		= announce_reply.getPorts();
+				 					
+				 					map.put( "complete", new Long(announce_reply.getSeeders()));
+				 					map.put( "incomplete", new Long(announce_reply.getLeechers()));
+				 					
+				 					List	peers = new ArrayList();
+				 					
+				 					map.put( "peers", peers );
+				 					
+				 					for (int i=0;i<addresses.length;i++){
+				 						
+				 						Map	peer = new HashMap();
+				 						
+				 						peers.add( peer );
+				 						
+				 						peer.put( "ip", PRHelpers.intToAddress(addresses[i]).getBytes());
+				 						peer.put( "port", new Long( ports[i]));
+				 					}
+				 					
+				 					byte[] data = BEncoder.encode( map );
+				 					
+				 					message.write( data );
+				 					
+				 					return( null );
 			 					
-			 					message.write( data );
-			 					
-			 					return( null );
-		 					
-		 				}
-		 			
-		 				failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
-		 				
-		 			}else{
-		 				
-		 				failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
-		 			}
-		 		}catch( PRUDPPacketHandlerException e ){
-		 			
-		 			if ( e.getMessage() == null || e.getMessage().indexOf("timed out") == -1 ){
-		 				
-		 				throw( e );
-		 			}
-		 		}
- 			}
+			 				}
+			 			
+			 				failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
+			 				
+			 			}else{
+			 				
+			 				failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
+			 			}
+			 		}catch( PRUDPPacketHandlerException e ){
+			 			
+			 			if ( e.getMessage() == null || e.getMessage().indexOf("timed out") == -1 ){
+			 				
+			 				throw( e );
+			 			}
+			 		}
+	 			}
+	 		}finally{
+	 		
+	 			handler.closeSession();
+	 		}
  			
  		}catch( Throwable e ){
  		
@@ -1792,7 +1866,7 @@ TRTrackerBTAnnouncerImpl
   		class_name = class_name.substring(pos+1);
   	}
   	
-  	String str = class_name + ":" + e.getMessage();
+  	String str = class_name + ":" + Debug.getNestedExceptionMessage(e);
   	
   	if ( str.indexOf( "timed out") != -1 ){
   		
@@ -1834,7 +1908,15 @@ TRTrackerBTAnnouncerImpl
   	request.append(port_details);
   	request.append("&uploaded=").append(announce_data_provider.getTotalSent());
   	request.append("&downloaded=").append(announce_data_provider.getTotalReceived());
-  	request.append("&left=").append(announce_data_provider.getRemaining());
+  	
+  	if ( Constants.DOWNLOAD_SOURCES_PRETEND_COMPLETE ){
+  		
+  	 	request.append("&left=0");
+  	  
+  	}else{
+  	
+  		request.append("&left=").append(announce_data_provider.getRemaining());
+  	}
   	
   		// 3017: added at request of tracker admins who want to be able to monitor swarm poisoning
   	
@@ -1990,7 +2072,7 @@ TRTrackerBTAnnouncerImpl
 	
     if ( COConfigurationManager.getBooleanParameter("Tracker Key Enable Client", true )){
       	
-      	request.append( "&key=").append(key_id);
+      	request.append( "&key=").append( helper.getTrackerKey());
     }
     
 	String	ext = announce_data_provider.getExtensions();
@@ -2043,6 +2125,43 @@ TRTrackerBTAnnouncerImpl
 		}
 	}
 	
+		// bah, issue with an i2p tracker regarding what is passed it seems: truncate to minimum required and order for the moment...
+	
+	if ( tracker_network == AENetworkClassifier.AT_I2P ){
+	
+		String	temp = request.toString();
+		
+		int	pos = temp.indexOf( '?' );
+		
+		String head = temp.substring( 0, pos );
+		String tail = temp.substring( pos+1 );
+		
+		String[]	bits = tail.split( "&" );
+		
+		Map<String,String>	map = new HashMap<String, String>();
+		
+		for ( String bit: bits ){
+			
+			String[] arg = bit.split( "=" );
+		
+			map.put( arg[0], arg[1] );
+		}
+		
+		tail = "";
+		
+		for ( String str: new String[]{ "info_hash", "peer_id", "port", "ip", "uploaded", "downloaded", "left", "compact", "event" }){
+			
+			String val = map.get( str );
+			
+			if ( val != null ){
+				
+				tail += (tail.length()==0?"":"&") + str + "=" + map.get( str );
+			}
+		}
+		
+		request = new StringBuffer( head + "?" + tail );		
+	}
+	
     return new URL( request.toString());
   }
 
@@ -2056,7 +2175,9 @@ TRTrackerBTAnnouncerImpl
 
     int MAX_PEERS = 100;
     
-    int maxAllowed = announce_data_provider.getMaxNewConnectionsAllowed();
+    	// ask for a bit more than our max to allow for connections failures
+    
+    int maxAllowed = 3*announce_data_provider.getMaxNewConnectionsAllowed()/2;
     
     if ( maxAllowed < 0 || maxAllowed > MAX_PEERS ) {
       maxAllowed = MAX_PEERS;
@@ -2122,12 +2243,18 @@ TRTrackerBTAnnouncerImpl
 	}
   
 	public void
-	setTrackerURLs(
+	setAnnounceSets(
 		TOTorrentAnnounceURLSet[]		_set )
 	{
 		announce_urls = _set;
 	}
 	
+	public TOTorrentAnnounceURLSet[]
+	getAnnounceSets()
+	{
+		return( announce_urls );
+	}
+	
 	public void
 	resetTrackerUrl(
 		boolean		shuffle )
@@ -2269,8 +2396,10 @@ TRTrackerBTAnnouncerImpl
 	 		try{
 					   //parse the metadata
 				
+	 			Map metaData = null;
+	 			
 	 			try{
-	 				Map metaData = BDecoder.decode(data);
+	 				metaData = BDecoder.decode(data);
 	 				
  					// obey any peers source restrictions
 	 				
@@ -2352,7 +2481,7 @@ TRTrackerBTAnnouncerImpl
 					long	time_to_wait;
 										
 					try {
-						time_to_wait = ((Long) metaData.get("interval")).longValue();
+						tracker_interval = time_to_wait = ((Long) metaData.get("interval")).longValue();
 						
 						Long raw_min_interval = (Long) metaData.get("min interval");
 
@@ -2368,7 +2497,7 @@ TRTrackerBTAnnouncerImpl
 						}
 
 						if (raw_min_interval != null) {
-							min_interval = raw_min_interval.longValue();
+							tracker_min_interval = min_interval = raw_min_interval.longValue();
 							
 							// ignore useless values
 							// Note: Many trackers set min_interval and interval the same.
@@ -2448,8 +2577,9 @@ TRTrackerBTAnnouncerImpl
 				   
 				   	//System.out.println("Response from Announce: " + new String(data));
 				   
-				   Long incomplete_l 	= (Long)metaData.get("incomplete");
-				   Long complete_l 		= (Long)metaData.get("complete");
+				   Long incomplete_l 	= getLong( metaData, "incomplete");
+				   Long complete_l 		= getLong( metaData, "complete");
+				   Long downloaded_l 	= getLong( metaData, "downloaded");
 				   
 				   if ( incomplete_l != null || complete_l != null  ){
 				   
@@ -2829,9 +2959,10 @@ TRTrackerBTAnnouncerImpl
 								
 								String ip = new String((byte[]) s_ip, Constants.DEFAULT_ENCODING); 
 								
-									//get the peer port number
+									//get the peer port number - should be Long but have seen byte[] on occasion
+								
+								int peer_port = s_port instanceof byte[]?Integer.parseInt(new String((byte[])s_port)):((Long) s_port).intValue();
 								
-								int peer_port = ((Long) s_port).intValue();
                                 // try to repair invalid peer ports; worst that can happen is we
                                 // still can't make outgoing connections that we already can't make
                                 if (peer_port >65535)
@@ -2924,8 +3055,9 @@ TRTrackerBTAnnouncerImpl
 											"ANNOUNCE CompactPeers: num=" + (meta_peers.length/entry_size)));
 						   }
 
+					  	int	peers_length = meta_peers.length;
 				    	
-				    	for (int i=0;i<meta_peers.length;i+=entry_size){
+				    	for (int i=0;i<(peers_length/entry_size)*entry_size;i+=entry_size){
 				    		
 				    		peer_number++;
 				    		
@@ -3109,7 +3241,7 @@ TRTrackerBTAnnouncerImpl
 						int incomplete = incomplete_l == null ? 0 : incomplete_l.intValue();
 
 						if (complete < 0 || incomplete < 0) {
-							resp.setFailurReason(MessageText.getString(
+							resp.setFailureReason(MessageText.getString(
 									"Tracker.announce.ignorePeerSeed",
 									new String[] { (complete < 0
 											? MessageText.getString("MyTorrentsView.seeds") + " == "
@@ -3118,7 +3250,7 @@ TRTrackerBTAnnouncerImpl
 													? MessageText.getString("MyTorrentsView.peers")
 															+ " == " + incomplete + ". " : "") }));
 						} else {
-
+							
 							resp.setScrapeResult( complete, incomplete );
 
 							TRTrackerScraper scraper = TRTrackerScraperFactory.getSingleton();
@@ -3140,6 +3272,11 @@ TRTrackerBTAnnouncerImpl
 										scrapeResponse.setNextScrapeStartTime(lNewNextScrapeTime);
 
 									scrapeResponse.setSeedsPeers(complete, incomplete);
+
+									if ( downloaded_l != null ){
+										
+										scrapeResponse.setCompleted( downloaded_l.intValue());
+									}
 								}
 							}
 						}
@@ -3149,6 +3286,23 @@ TRTrackerBTAnnouncerImpl
 
 				}catch( IOException e ){
 					
+					if ( metaData != null ){
+						
+						byte[]	failure_reason_bytes = (byte[]) metaData.get("failure reason");
+				     	
+			     			// explicit failure from the tracker
+			     	
+						failure_reason = new String( failure_reason_bytes, Constants.DEFAULT_ENCODING);
+                        				
+						return( 
+								new TRTrackerAnnouncerResponseImpl( 
+										url, 
+										torrent_hash, 
+										TRTrackerAnnouncerResponse.ST_REPORTED_ERROR, 
+										Math.max( tracker_interval, getErrorRetryInterval()), 
+										failure_reason ));
+					}
+					
 						// decode could fail if the tracker's returned, say, an HTTP response
 						// indicating server overload
 	 				 				
@@ -3180,6 +3334,21 @@ TRTrackerBTAnnouncerImpl
 		return( new TRTrackerAnnouncerResponseImpl( url, torrent_hash, TRTrackerAnnouncerResponse.ST_OFFLINE, getErrorRetryInterval(), failure_reason ));
   	}
   	
+  	private Long
+  	getLong(
+  		Map		map,
+  		String	key )
+  	{
+  		Object o = map.get( key );
+  		
+  		if ( o instanceof Long ){
+  			
+  			return((Long)o);
+  		}
+  		
+  		return( null );
+  	}
+  	
 	protected void
 	informURLChange(
 		URL		old_url,
@@ -3403,10 +3572,14 @@ TRTrackerBTAnnouncerImpl
 		if ( 	last_response == null ||
 				last_response.getStatus() != TRTrackerAnnouncerResponse.ST_ONLINE ){
 			
-			tracker_status_str	= status + " (" + result.getURL() + ")";
+			URL result_url = result.getURL();
+			
+			boolean	update_is_dht	= TorrentUtils.isDecentralised( result_url );
+
+			tracker_status_str	= status + " (" + (update_is_dht?MessageText.getString( "dht.backup.only" ):(result_url==null?"<null>":result_url.getHost())) + ")";
 		}
 		
-		helper.informResponse( response );
+		helper.informResponse( this, response );
 	}
 	
 	public void 
@@ -3443,6 +3616,23 @@ TRTrackerBTAnnouncerImpl
 		return( helper.getTrackerResponseCache());
 	}
 	
+	public TrackerPeerSource 
+	getTrackerPeerSource(
+		TOTorrentAnnounceURLSet set) 
+	{
+		Debug.out( "not implemented" );
+		
+		return null;
+	}
+	
+	public TrackerPeerSource 
+	getCacheTrackerPeerSource()
+	{
+		Debug.out( "not implemented" );
+		
+		return null;
+	}
+	
 	public void 
 	generateEvidence(
 		IndentWriter writer )
@@ -3462,6 +3652,10 @@ TRTrackerBTAnnouncerImpl
 			
 			writer.println( "secs_to_wait: " + current_time_to_wait_secs  + (manual_control?" - manual":""));
 			
+			writer.println( "t_interval: " + tracker_interval );
+			
+			writer.println( "t_min_interval: " + tracker_min_interval );
+			
 			writer.println( "min_interval: " + min_interval );
 			
 			writer.println( "min_interval_override: " + min_interval_override );
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperImpl.java
index f4877a1..78cd0f4 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperImpl.java
@@ -24,11 +24,14 @@ package org.gudy.azureus2.core3.tracker.client.impl.bt;
 
 import java.net.URL;
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
-import org.gudy.azureus2.core3.tracker.client.impl.*;
+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.TorrentUtils;
 import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
 
 /**
@@ -90,12 +93,19 @@ TRTrackerBTScraperImpl
 			
 			TRTrackerScraperResponseImpl resp =	tracker_checker.getHashData( torrent, url );
 			
-				// only override details if underlying scrape is failing
+			URL result_url = result.getURL();
 			
-			if ( resp != null && resp.getStatus() == TRTrackerScraperResponse.ST_ERROR ){
-				
-				resp.setSeedsPeers( result.getSeedCount(), result.getNonSeedCount());
+			boolean	update_is_dht	= TorrentUtils.isDecentralised( result_url );
+			
+				// only override details if underlying scrape is failing or this is an update
+				// to an existing dht-backup result
 			
+			if ( 	resp != null && 
+					( 	resp.getStatus() == TRTrackerScraperResponse.ST_ERROR ) ||
+						resp.isDHTBackup() && update_is_dht ){
+				
+				resp.setDHTBackup( update_is_dht );
+				
 				resp.setScrapeStartTime( result.getScrapeStartTime());
 				
 					// leave nextScrapeStartTime alone as we still want the existing
@@ -105,7 +115,10 @@ TRTrackerBTScraperImpl
 						result.getResponseType()==DownloadScrapeResult.RT_SUCCESS?
 								TRTrackerScraperResponse.ST_ONLINE:
 								TRTrackerScraperResponse.ST_ERROR,
-						result.getStatus() + " (" + result.getURL() + ")"); 
+						result.getStatus() + " (" + (update_is_dht?MessageText.getString( "dht.backup.only" ):(result_url==null?"<null>":result_url.getHost())) + ")");
+
+				// call this last before dispatching listeners as it does another dispatch by itself ~~
+				resp.setSeedsPeers( result.getSeedCount(), result.getNonSeedCount());
 			
 				scraper.scrapeReceived( resp );
 			}
@@ -136,6 +149,21 @@ TRTrackerBTScraperImpl
 	}
 	
 	public TRTrackerScraperResponse
+	peekScrape(
+		TOTorrent		torrent,
+		URL				target_url )
+	{
+		if ( torrent == null ){
+			
+			return null;
+		}
+
+		TRTrackerScraperResponse	res = tracker_checker.peekHashData( torrent, target_url );
+				
+		return( res );
+	}
+	
+	public TRTrackerScraperResponse
 	scrape(
 		TRTrackerAnnouncer	tracker_client )
 	{
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperResponseImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperResponseImpl.java
index 6a58e6e..993b16f 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperResponseImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TRTrackerBTScraperResponseImpl.java
@@ -38,54 +38,71 @@ public class
 TRTrackerBTScraperResponseImpl
 	extends TRTrackerScraperResponseImpl
 {
-	  private TrackerStatus ts;
+	private TrackerStatus ts;
 
-	  protected 
-	  TRTrackerBTScraperResponseImpl(
-	  		TrackerStatus _ts,
-            HashWrapper _hash) 
-	  {
-	  	this(_ts, _hash, -1, -1, -1,-1);
-	  }
-
-	  protected 
-	  TRTrackerBTScraperResponseImpl(
-	  		TrackerStatus _ts,
-	  		HashWrapper _hash,
-            int  _seeds, 
-            int  _peers,
-            int completed,
-            long _scrapeStartTime)  
-	  {
-	  	super( _hash, _seeds, _peers, completed, _scrapeStartTime );
-	  	
-	  	ts	= _ts;
-	  }
+	private boolean	is_dht_backup;
 	  
-	  public TrackerStatus getTrackerStatus() {
-	    return ts;
-	  }
+	protected 
+	TRTrackerBTScraperResponseImpl(
+		TrackerStatus _ts,
+		HashWrapper _hash) 
+	{
+		this(_ts, _hash, -1, -1, -1,-1);
+	}
+
+	protected 
+	TRTrackerBTScraperResponseImpl(
+		TrackerStatus _ts,
+		HashWrapper _hash,
+		int  _seeds, 
+		int  _peers,
+		int completed,
+		long _scrapeStartTime)  
+	{
+		super( _hash, _seeds, _peers, completed, _scrapeStartTime );
+
+		ts	= _ts;
+	}
+
+	public TrackerStatus 
+	getTrackerStatus() 
+	{
+		return ts;
+	}
 
 	public void 
 	setSeedsPeers(
-		int iSeeds, int iPeers) 
+		int iSeeds, int iPeers ) 
 	{
 		setSeeds( iSeeds );
 		setPeers( iPeers );
-		
+
 		if (isValid()){
 			setStatus(TRTrackerScraperResponse.ST_ONLINE);
 			setStatus( MessageText.getString("Scrape.status.ok"));
 		} else {
 			setStatus(TRTrackerScraperResponse.ST_INITIALIZING);
 		}
-		    // XXX Is this a good idea?
+		// XXX Is this a good idea?
 		ts.scrapeReceived(this);
 	}
-		
-	  public URL
-	  getURL()
-	  {
-	  	return( ts.getTrackerURL());
-	  }
+
+	public URL
+	getURL()
+	{
+		return( ts.getTrackerURL());
+	}
+
+	public void 
+	setDHTBackup(
+		boolean	is_backup )
+	{
+		is_dht_backup	= is_backup;
+	}
+	
+	public boolean 
+	isDHTBackup() 
+	{	
+		return is_dht_backup;
+	}
 }
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 4d5589c..229c454 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerChecker.java
@@ -191,6 +191,41 @@ public class TrackerChecker implements AEDiagnosticsEvidenceGenerator, SystemTim
     return data;
   }
   
+  protected TRTrackerScraperResponseImpl 
+  peekHashData(
+  	TOTorrent  	torrent,
+	URL			target_url )
+  {
+    try{
+    	URL trackerUrl = target_url==null?torrent.getAnnounceURL():target_url;
+      
+    	if ( trackerUrl == null ){
+    		return( null );
+        }
+      
+        String	url_str = trackerUrl.toString();
+          
+        try{
+            trackers_mon.enter();
+        	
+            TrackerStatus  ts = (TrackerStatus) trackers.get(url_str);
+        
+            if ( ts != null ){
+    	      
+    	      return( ts.getHashData( torrent.getHashWrapper()));      
+            }
+        }finally{
+          	
+            trackers_mon.exit();
+        }
+      
+    } catch(TOTorrentException e) {
+    	Debug.printStackTrace( e );
+    }
+    
+    return null;
+  }  
+  
   /** Removes the scrape task and data associated with the TOTorrent's
    * Announce URL, announce-list data and hash.
    */
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 31883c4..69da09d 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/bt/TrackerStatus.java
@@ -30,6 +30,7 @@ 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;
@@ -82,19 +83,29 @@ public class TrackerStatus {
 	private final static int		GROUP_SCRAPES_MS				= 60 * 15 * 1000;
 	private final static int		GROUP_SCRAPES_LIMIT				= 20;
 	
+	private static boolean tcpScrapeEnabled; 
+	private static boolean udpScrapeEnabled; 
+	private static boolean udpProbeEnabled; 
+
 	static
 	{
 		PRUDPTrackerCodecs.registerCodecs();
-	  	COConfigurationManager.addAndFireParameterListener("Server Enable UDP", new ParameterListener()
-		{
+		
+	  	COConfigurationManager.addAndFireParameterListeners(
+	  		new String[]{
+	  			"Tracker Client Enable TCP",
+	  			"Server Enable UDP",
+	  			"Tracker UDP Probe Enable"
+	  		}, new ParameterListener()
+	  		{
 			public void parameterChanged(final String parameterName) {
-				udpScrapeEnabled = COConfigurationManager.getBooleanParameter("Server Enable UDP");
-			}
-		});
+					tcpScrapeEnabled = COConfigurationManager.getBooleanParameter("Tracker Client Enable TCP");
+					udpScrapeEnabled = COConfigurationManager.getBooleanParameter("Server Enable UDP");
+					udpProbeEnabled  = COConfigurationManager.getBooleanParameter("Tracker UDP Probe Enable");
+				}
+			});
 	}
-	
-	private static boolean udpScrapeEnabled = true; 
-	
+		
 	private byte					autoUDPscrapeEvery				= 1;
 	private int						scrapeCount;
 	
@@ -359,7 +370,7 @@ public class TrackerStatus {
 					.getBooleanParameter("Tracker Client Scrape Enable");
 			boolean disable_stopped_scrapes = !COConfigurationManager
 					.getBooleanParameter("Tracker Client Scrape Stopped Enable");
-
+			
 			byte[]	scrape_reply = null;
 			
 			try {
@@ -486,13 +497,44 @@ public class TrackerStatus {
 		  		
 		  		boolean auto_probe = false;
 		  		
-		  		if(protocol.equalsIgnoreCase("udp") && udpScrapeEnabled)
-		  			udpScrapeURL = reqUrl;
-		  		else if(protocol.equalsIgnoreCase("http") && !az_tracker && scrapeCount % autoUDPscrapeEvery == 0 && udpScrapeEnabled) {
-		  			udpScrapeURL = new URL(reqUrl.toString().replaceFirst("^http", "udp"));
-		  			auto_probe = true;
+		  		if (protocol.equalsIgnoreCase("udp")){
+		  			
+		  			if ( udpScrapeEnabled ){
+		  		
+		  				udpScrapeURL = reqUrl;
+		  				
+		  			}else{
+		  				
+		  				throw( new IOException( "UDP Tracker protocol disabled" ));
+		  				
+		  			}
+		  		}else if ( protocol.equalsIgnoreCase("http") && 
+		  				!az_tracker && 
+		  				scrapeCount % autoUDPscrapeEvery == 0 && 
+		  				udpProbeEnabled && udpScrapeEnabled ){
+		  			
+		  			String	tracker_network	= AENetworkClassifier.categoriseAddress( reqUrl.getHost()); 
+
+		  			if ( tracker_network == AENetworkClassifier.AT_PUBLIC ){ 
+		  			
+		  				udpScrapeURL = new URL(reqUrl.toString().replaceFirst("^http", "udp"));
+		  			
+		  				auto_probe = true;
+		  			}
 		  		}
+		  		
+		  		if ( udpScrapeURL == null ){
 		  			
+		  			if ( !az_tracker && !tcpScrapeEnabled ){
+		  					
+		  				String	tracker_network	= AENetworkClassifier.categoriseAddress( reqUrl.getHost()); 
+
+			  			if ( tracker_network == AENetworkClassifier.AT_PUBLIC ){
+		  				
+			  				throw( new IOException( "HTTP Tracker protocol disabled" ));
+			  			}
+		  			}
+		  		}
 		  		
 		  		try{
 		  				// set context in case authentication dialog is required
@@ -686,7 +728,7 @@ public class TrackerStatus {
 											+ MessageText.getString(SSErr + "nohash"));
 							// notifiy listeners
 							scraper.scrapeReceived(response);
-						} else {
+						} else if (!disable_stopped_scrapes || scraper.isTorrentRunning(response.getHash())) {
 							// This tracker doesn't support multiple hash requests.
 							// revert status to what it was
 
@@ -984,168 +1026,205 @@ public class TrackerStatus {
 
 
 	protected URL 
-  scrapeHTTP(
-  	URL 					reqUrl, 
-	ByteArrayOutputStream 	message )
-  
-  	throws IOException
-  {
-	URL	redirect_url = null;
-	
-  	TRTrackerUtils.checkForBlacklistedURLs( reqUrl );
-  	
-    reqUrl = TRTrackerUtils.adjustURLForHosting( reqUrl );
+	scrapeHTTP(
+		URL 					reqUrl, 
+		ByteArrayOutputStream 	message )
 
-    reqUrl = AddressUtils.adjustURL( reqUrl );
-    
-  	// System.out.println( "scraping " + reqUrl.toString());
-  	
-	Properties	http_properties = new Properties();
-		
-	http_properties.put( ClientIDGenerator.PR_URL, reqUrl );
-		
-	try{
-		ClientIDManagerImpl.getSingleton().generateHTTPProperties( http_properties );
-		
-	}catch( ClientIDException e ){
-		
-		throw( new IOException( e.getMessage()));
-	}
-	
-	reqUrl = (URL)http_properties.get( ClientIDGenerator.PR_URL );
+		throws IOException
+	{
+			// loop to possibly retry update on SSL certificate install
 
-  	InputStream is = null;
-  	
-  	try{
-	  	HttpURLConnection con = null;
-
-	  	if ( reqUrl.getProtocol().equalsIgnoreCase("https")){
-	  		
-	  			// see ConfigurationChecker for SSL client defaults
-	  		
-	  		HttpsURLConnection ssl_con = (HttpsURLConnection)reqUrl.openConnection();
-	  		
-	  			// allow for certs that contain IP addresses rather than dns names
-	  		
-	  		ssl_con.setHostnameVerifier(
-	  				new HostnameVerifier() {
-	  					public boolean verify(String host, SSLSession session) {
-	  						return( true );
-	  					}
-	  				});
-	  		
-	  		con = ssl_con;
-	  		
-	  	} else {
-	  		con = (HttpURLConnection) reqUrl.openConnection();
-	  	}
-
-		String	user_agent = (String)http_properties.get( ClientIDGenerator.PR_USER_AGENT );
- 		
- 		if ( user_agent != null ){
- 			
- 			con.setRequestProperty("User-Agent", user_agent );
- 		}
- 		
- 			// some trackers support gzip encoding of replies
- 		
-	    con.addRequestProperty("Accept-Encoding","gzip");
-	    
-	    con.setRequestProperty("Connection", "close" );
-	    
-	  	con.connect();
+		for ( int i=0;i<2;i++ ){	
 
-	  	is = con.getInputStream();
-	
-		String	resulting_url_str = con.getURL().toString();
-			
-		if ( !reqUrl.toString().equals( resulting_url_str )){
-			
-				// some kind of redirect has occurred. Unfortunately we can't get at the underlying
-				// redirection reason (temp, perm etc) so we support the use of an explicit indicator
-				// in the resulting url
-			
-			String	marker = "permredirect=1";
-			
-			int	pos = resulting_url_str.indexOf( marker );
-		
-			if ( pos != -1 ){
+			URL	redirect_url = null;
+
+			TRTrackerUtils.checkForBlacklistedURLs( reqUrl );
+
+			reqUrl = TRTrackerUtils.adjustURLForHosting( reqUrl );
+
+			reqUrl = AddressUtils.adjustURL( reqUrl );
+
+			// System.out.println( "scraping " + reqUrl.toString());
+
+			Properties	http_properties = new Properties();
+
+			http_properties.put( ClientIDGenerator.PR_URL, reqUrl );
+
+			try{
+				ClientIDManagerImpl.getSingleton().generateHTTPProperties( http_properties );
+
+			}catch( ClientIDException e ){
+
+				throw( new IOException( e.getMessage()));
+			}
+
+			reqUrl = (URL)http_properties.get( ClientIDGenerator.PR_URL );
+
+			InputStream is = null;
+
+			try{
+				HttpURLConnection con = null;
+
+				if ( reqUrl.getProtocol().equalsIgnoreCase("https")){
+
+					// see ConfigurationChecker for SSL client defaults
+
+					HttpsURLConnection ssl_con = (HttpsURLConnection)reqUrl.openConnection();
+
+					// allow for certs that contain IP addresses rather than dns names
+
+					ssl_con.setHostnameVerifier(
+							new HostnameVerifier() {
+								public boolean verify(String host, SSLSession session) {
+									return( true );
+								}
+							});
+
+					con = ssl_con;
+
+				}else{
+					
+					con = (HttpURLConnection) reqUrl.openConnection();
+				}
+
+				if ( con instanceof HttpURLConnection ){
+					
+						// we want this true but some plugins (grrr) set the global default not to follow
+						// redirects
 				
-				pos = pos-1;	// include the '&' or '?'
+					((HttpURLConnection)con).setInstanceFollowRedirects( true );
+				}
 				
-				try{
-					redirect_url = 
-						new URL( resulting_url_str.substring(0,pos));
-								
-				}catch( Throwable e ){
-					Debug.printStackTrace(e);
+				String	user_agent = (String)http_properties.get( ClientIDGenerator.PR_USER_AGENT );
+
+				if ( user_agent != null ){
+
+					con.setRequestProperty("User-Agent", user_agent );
+				}
+
+				// some trackers support gzip encoding of replies
+
+				con.addRequestProperty("Accept-Encoding","gzip");
+
+				con.setRequestProperty("Connection", "close" );
+
+				con.connect();
+
+				is = con.getInputStream();
+
+				String	resulting_url_str = con.getURL().toString();
+
+				if ( !reqUrl.toString().equals( resulting_url_str )){
+
+					// some kind of redirect has occurred. Unfortunately we can't get at the underlying
+					// redirection reason (temp, perm etc) so we support the use of an explicit indicator
+					// in the resulting url
+
+					String	marker = "permredirect=1";
+
+					int	pos = resulting_url_str.indexOf( marker );
+
+					if ( pos != -1 ){
+
+						pos = pos-1;	// include the '&' or '?'
+
+						try{
+							redirect_url = 
+								new URL( resulting_url_str.substring(0,pos));
+
+						}catch( Throwable e ){
+							Debug.printStackTrace(e);
+						}
+					}
+				}
+
+				String encoding = con.getHeaderField( "content-encoding");
+
+				boolean	gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
+
+				// System.out.println( "encoding = " + encoding );
+
+				if ( gzip ){
+
+					is = new GZIPInputStream( is );
+				}
+
+				byte[]	data = new byte[1024];
+
+				int num_read = 0;
+
+				while( true ){
+
+					try {
+						int	len = is.read(data);
+
+						if ( len > 0 ){
+
+							message.write(data, 0, len);
+
+							num_read += len;
+
+							if ( num_read > 128*1024 ){
+
+								// someone's sending us junk, bail out
+
+								message.reset();
+
+								throw( new Exception( "Tracker response invalid (too large)" ));
+
+							}
+						}else if ( len == 0 ){
+
+							Thread.sleep(20);
+
+						}else{
+
+							break;
+						}
+					} catch (Exception e) {
+
+						if (Logger.isEnabled())
+							Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+									"Error from scrape interface " + scrapeURL + " : "
+									+ Debug.getNestedExceptionMessage(e)));
+
+						return( null );
+					}
+				}
+			}catch( SSLException e ){
+
+				// e.printStackTrace();
+
+				// try and install certificate regardless of error (as this changed in JDK1.5
+				// and broke this...)
+
+				if ( i == 0 ){//&& e.getMessage().indexOf("No trusted certificate found") != -1 ){
+
+					if ( SESecurityManager.installServerCertificates( reqUrl ) != null ){
+
+						// certificate has been installed
+
+						continue;	// retry with new certificate
+
+					}
+				}
+
+				throw( e );
+				
+			}finally{
+				
+				if (is != null) {
+					try {
+						is.close();
+					} catch (IOException e1) { }
 				}
 			}
+
+			return( redirect_url );
 		}
 		
-	  	String encoding = con.getHeaderField( "content-encoding");
-	  	
-	  	boolean	gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
-	  	
-	  	// System.out.println( "encoding = " + encoding );
-	  	
-	  	if ( gzip ){
-	  		
-	  		is = new GZIPInputStream( is );
-	  	}
-	  	
-	  	byte[]	data = new byte[1024];
-	  	
-	  	int num_read = 0;
-	  	
-	  	while( true ){
-	  		
-	  		try {
-				int	len = is.read(data);
-					
-				if ( len > 0 ){
-					
-					message.write(data, 0, len);
-					
-					num_read += len;
-					
-					if ( num_read > 128*1024 ){
-						
-							// someone's sending us junk, bail out
-					   
-						message.reset();
-						
-						throw( new Exception( "Tracker response invalid (too large)" ));
-						
-					}
-				}else if ( len == 0 ){
-					
-					Thread.sleep(20);
-					
-				}else{
-					
-					break;
-				}
-	  		} catch (Exception e) {
-	  			
-	  			if (Logger.isEnabled())
-						Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-								"Error from scrape interface " + scrapeURL + " : "
-										+ Debug.getNestedExceptionMessage(e)));
-
-	  			return( null );
-	  		}
-	  	}
-	  } finally {
-	  	if (is != null) {
-        try {
-	  		  is.close();
-  	  	} catch (IOException e1) { }
-  	  }
-	  }
-	  
-	  return( redirect_url );
-  }
+		throw( new IOException( "Shouldn't get here" ));
+	}
   
   protected boolean scrapeUDP(URL reqUrl, ByteArrayOutputStream message, List hashes, boolean do_auth_test) throws Exception {
 		Map rootMap = new HashMap();
@@ -1200,145 +1279,152 @@ public class TrackerStatus {
 		PRUDPPacketHandler handler = PRUDPPacketHandlerFactory.getHandler( port );
 		
 		InetSocketAddress destination = new InetSocketAddress(reqUrl.getHost(),reqUrl.getPort()==-1?80:reqUrl.getPort());
-		
-		String	failure_reason = null;
-		
-		for (int retry_loop=0;retry_loop<PRUDPPacketTracker.DEFAULT_RETRY_COUNT;retry_loop++){
-		
-			try{
-				PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
-				
-				PRUDPPacket reply = handler.sendAndReceive( auth, connect_request, destination );
-				
-				if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_CONNECT ){
-					
-					PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect)reply;
+
+		handler = handler.openSession( destination );
+
+		try{			
+			String	failure_reason = null;
+			
+			for (int retry_loop=0;retry_loop<PRUDPPacketTracker.DEFAULT_RETRY_COUNT;retry_loop++){
+			
+				try{
+					PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
 					
-					long	my_connection = connect_reply.getConnectionId();
+					PRUDPPacket reply = handler.sendAndReceive( auth, connect_request, destination );
 					
-					PRUDPPacketRequestScrape scrape_request = new PRUDPPacketRequestScrape( my_connection, hashes );
+					if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_CONNECT ){
+						
+						PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect)reply;
+						
+						long	my_connection = connect_reply.getConnectionId();
+						
+						PRUDPPacketRequestScrape scrape_request = new PRUDPPacketRequestScrape( my_connection, hashes );
+										
+						reply = handler.sendAndReceive( auth, scrape_request, destination );
+						
+						if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_SCRAPE ){
+		
+							auth_ok	= true;
+		
+							if ( PRUDPPacketTracker.VERSION == 1 ){
+								PRUDPPacketReplyScrape	scrape_reply = (PRUDPPacketReplyScrape)reply;
+								
+								/*
+								int	interval = scrape_reply.getInterval();
+								
+								if ( interval != 0 ){
 									
-					reply = handler.sendAndReceive( auth, scrape_request, destination );
-					
-					if ( reply.getAction() == PRUDPPacketTracker.ACT_REPLY_SCRAPE ){
-	
-						auth_ok	= true;
-	
-						if ( PRUDPPacketTracker.VERSION == 1 ){
-							PRUDPPacketReplyScrape	scrape_reply = (PRUDPPacketReplyScrape)reply;
-							
-							/*
-							int	interval = scrape_reply.getInterval();
-							
-							if ( interval != 0 ){
+									map.put( "interval", new Long(interval ));
+								}
+								*/
 								
-								map.put( "interval", new Long(interval ));
-							}
-							*/
-							
-							byte[][]	reply_hashes 	= scrape_reply.getHashes();
-							int[]		complete 		= scrape_reply.getComplete();
-							int[]		downloaded 		= scrape_reply.getDownloaded();
-							int[]		incomplete 		= scrape_reply.getIncomplete();
-							
-					
-							for (int i=0;i<reply_hashes.length;i++){
+								byte[][]	reply_hashes 	= scrape_reply.getHashes();
+								int[]		complete 		= scrape_reply.getComplete();
+								int[]		downloaded 		= scrape_reply.getDownloaded();
+								int[]		incomplete 		= scrape_reply.getIncomplete();
+								
+						
+								for (int i=0;i<reply_hashes.length;i++){
+									
+									Map	file = new HashMap();
+									
+									byte[]	resp_hash = reply_hashes[i];
+									
+									// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
+								
+									files.put( new String(resp_hash, Constants.BYTE_ENCODING), file );
+									
+									file.put( "complete", new Long(complete[i]));
+									file.put( "downloaded", new Long(downloaded[i]));
+									file.put( "incomplete", new Long(incomplete[i]));
+								}
+								
+								byte[] data = BEncoder.encode( rootMap );
+								
+								message.write( data );
 								
-								Map	file = new HashMap();
+								return true;
+							}else{
+								PRUDPPacketReplyScrape2	scrape_reply = (PRUDPPacketReplyScrape2)reply;
 								
-								byte[]	resp_hash = reply_hashes[i];
+								
+								/*
+								int	interval = scrape_reply.getInterval();
+								
+								if ( interval != 0 ){
+									
+									map.put( "interval", new Long(interval ));
+								}
+								*/
+								
+								int[]		complete 	= scrape_reply.getComplete();
+								int[]		downloaded 	= scrape_reply.getDownloaded();
+								int[]		incomplete 	= scrape_reply.getIncomplete();
+								
+								int i=0;
+								for(Iterator it = hashes.iterator();it.hasNext() && i < complete.length;i++)
+								{
+									HashWrapper hash = (HashWrapper)it.next();
+									Map file = new HashMap();
+									file.put( "complete", new Long(complete[i]));
+									file.put( "downloaded", new Long(downloaded[i]));
+									file.put( "incomplete", new Long(incomplete[i]));
+									files.put( new String(hash.getBytes(), Constants.BYTE_ENCODING), file );
+								}
 								
 								// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
-							
-								files.put( new String(resp_hash, Constants.BYTE_ENCODING), file );
 								
-								file.put( "complete", new Long(complete[i]));
-								file.put( "downloaded", new Long(downloaded[i]));
-								file.put( "incomplete", new Long(incomplete[i]));
-							}
-							
-							byte[] data = BEncoder.encode( rootMap );
-							
-							message.write( data );
-							
-							return true;
-						}else{
-							PRUDPPacketReplyScrape2	scrape_reply = (PRUDPPacketReplyScrape2)reply;
-							
-							
-							/*
-							int	interval = scrape_reply.getInterval();
-							
-							if ( interval != 0 ){
+								byte[] data = BEncoder.encode( rootMap );
 								
-								map.put( "interval", new Long(interval ));
-							}
-							*/
-							
-							int[]		complete 	= scrape_reply.getComplete();
-							int[]		downloaded 	= scrape_reply.getDownloaded();
-							int[]		incomplete 	= scrape_reply.getIncomplete();
-							
-							int i=0;
-							for(Iterator it = hashes.iterator();it.hasNext() && i < complete.length;i++)
-							{
-								HashWrapper hash = (HashWrapper)it.next();
-								Map file = new HashMap();
-								file.put( "complete", new Long(complete[i]));
-								file.put( "downloaded", new Long(downloaded[i]));
-								file.put( "incomplete", new Long(incomplete[i]));
-								files.put( new String(hash.getBytes(), Constants.BYTE_ENCODING), file );
+								message.write( data );
+								
+								return true;
 							}
+						}else{
 							
-							// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
-							
-							byte[] data = BEncoder.encode( rootMap );
+							failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
 							
-							message.write( data );
+							if (Logger.isEnabled())
+									Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+											"Response from scrape interface "+ reqUrl +" : " + failure_reason));
 							
-							return true;
+							break;
 						}
 					}else{
-						
+		
 						failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
 						
 						if (Logger.isEnabled())
-								Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-										"Response from scrape interface "+ reqUrl +" : " + failure_reason));
-						
+								Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Response from scrape interface "+ reqUrl +" : "
+												+ ((PRUDPPacketReplyError) reply).getMessage()));
+					
 						break;
 					}
-				}else{
-	
-					failure_reason = ((PRUDPPacketReplyError)reply).getMessage();
+		
+				}catch( PRUDPPacketHandlerException e ){
 					
-					if (Logger.isEnabled())
-							Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Response from scrape interface "+ reqUrl +" : "
-											+ ((PRUDPPacketReplyError) reply).getMessage()));
-				
-					break;
-				}
-	
-			}catch( PRUDPPacketHandlerException e ){
-				
-				if ( e.getMessage() == null || e.getMessage().indexOf("timed out") == -1 ){
+					if ( e.getMessage() == null || e.getMessage().indexOf("timed out") == -1 ){
+						
+						throw( e );
+					}
 					
-					throw( e );
+					failure_reason	= "Timeout";
 				}
-				
-				failure_reason	= "Timeout";
 			}
-		}
 		
-		if ( failure_reason != null ){
-			
-			rootMap.put( "failure reason", failure_reason.getBytes());
-			rootMap.remove("files");
+			if ( failure_reason != null ){
+				
+				rootMap.put( "failure reason", failure_reason.getBytes());
+				rootMap.remove("files");
+				
+				byte[] data = BEncoder.encode( rootMap );
+				message.write( data );
+			}
+		}finally{
 			
-			byte[] data = BEncoder.encode( rootMap );
-			message.write( data );
+			handler.closeSession();
 		}
-		
+
 		return false;
 	}finally{
 		if ( auth != null ){
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTAnnouncerImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTAnnouncerImpl.java
index 7ddba49..bd9c5fa 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTAnnouncerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTAnnouncerImpl.java
@@ -23,7 +23,12 @@
 package org.gudy.azureus2.core3.tracker.client.impl.dht;
 
 import java.net.URL;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
 
 
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -37,6 +42,7 @@ import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerException;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerListener;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponsePeer;
+import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerAnnouncerHelper;
 import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerAnnouncerImpl;
 import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerAnnouncerResponseImpl;
 import org.gudy.azureus2.core3.tracker.client.impl.TRTrackerAnnouncerResponsePeerImpl;
@@ -44,11 +50,14 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.HashWrapper;
 import org.gudy.azureus2.core3.util.IndentWriter;
 import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.clientid.ClientIDException;
 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.tracker.TrackerPeerSource;
+
 /**
  * @author parg
  *
@@ -56,7 +65,7 @@ import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
 
 public class 
 TRTrackerDHTAnnouncerImpl
-	implements TRTrackerAnnouncer
+	implements TRTrackerAnnouncerHelper
 {
 	public final static LogIDs LOGID = LogIDs.TRACKER;
 
@@ -116,8 +125,7 @@ TRTrackerDHTAnnouncerImpl
 	public void
 	setAnnounceDataProvider(
 		TRTrackerAnnouncerDataProvider		provider )
-	{
-		
+	{	
 	}
 	
 	public boolean
@@ -135,7 +143,7 @@ TRTrackerDHTAnnouncerImpl
 	public URL
 	getTrackerURL()
 	{
-		return( torrent.getAnnounceURL());
+		return( TorrentUtils.getDecentralisedURL( torrent ));
 	}
 	
 	public void
@@ -144,27 +152,28 @@ TRTrackerDHTAnnouncerImpl
 	{
 		Debug.out( "Not implemented" );
 	}
-		
-	public void 
-	setTrackerURLs(
-		TOTorrentAnnounceURLSet[] 	sets ) 
+	
+	public void
+	setAnnounceSets(
+		TOTorrentAnnounceURLSet[]		_set )
 	{
 		Debug.out( "Not implemented" );
 	}
 	
-	public void
-	resetTrackerUrl(
-		boolean	shuffle )
+	public TOTorrentAnnounceURLSet[]
+	getAnnounceSets()
 	{
+		return( new TOTorrentAnnounceURLSet[]{
+					torrent.getAnnounceURLGroup().createAnnounceURLSet( 
+							new URL[]{ TorrentUtils.getDecentralisedURL( torrent )})} );
 	}
 	
 	public void
-	cloneFrom(
-		TRTrackerAnnouncer	other )
+	resetTrackerUrl(
+		boolean	shuffle )
 	{
-		data_peer_id	= other.getPeerId();
 	}
-	
+		
 	public void
 	setIPOverride(
 		String		override )
@@ -213,8 +222,6 @@ TRTrackerDHTAnnouncerImpl
 		boolean	force )
 	{
 		state = TS_DOWNLOADING;
-		
-		checkCache();
 	}	
 	
 	public void
@@ -248,12 +255,36 @@ TRTrackerDHTAnnouncerImpl
 		return( tracker_status_str );
 	}
 	
+	public TRTrackerAnnouncer
+	getBestAnnouncer()
+	{
+		return( this );
+	}
+	
 	public TRTrackerAnnouncerResponse
 	getLastResponse()
 	{
 		return( last_response );
 	}
 	
+	public boolean 
+	isUpdating() 
+	{
+		return( false );
+	}
+	
+	public long
+	getInterval()
+	{
+		return( -1 );
+	}
+	
+	public long
+	getMinInterval()
+	{
+		return( -1 );
+	}
+	
 	public void
 	refreshListeners()
 	{	
@@ -320,24 +351,40 @@ TRTrackerDHTAnnouncerImpl
 		}
 		
 		last_response = response;
-				
-		helper.informResponse( response );
-	}
-	
-	protected void
-	checkCache()
-	{
-		if ( last_response.getStatus() != TRTrackerAnnouncerResponse.ST_ONLINE ){
+			
+		TRTrackerAnnouncerResponsePeer[] peers = response.getPeers();
+		
+		if ( peers == null || peers.length < 5 ){
 			
 		     TRTrackerAnnouncerResponsePeer[]	cached_peers = helper.getPeersFromCache(100);
 
 		     if ( cached_peers.length > 0 ){
 		     	
-		     	last_response.setPeers( cached_peers );
-		     	
-				helper.informResponse( last_response );
+		    	 Set<TRTrackerAnnouncerResponsePeer>	new_peers = 
+		    		 new TreeSet<TRTrackerAnnouncerResponsePeer>(
+			    		new Comparator<TRTrackerAnnouncerResponsePeer>()
+			    		{
+			    			public int 
+			    			compare(
+			    				TRTrackerAnnouncerResponsePeer o1,
+			    				TRTrackerAnnouncerResponsePeer o2 ) 
+			    			{
+			    				return( o1.compareTo( o2 ));
+			    			}		    			
+			    		});
+		    	 
+		    	 if ( peers != null ){
+		    		 
+		    		 new_peers.addAll( Arrays.asList( peers ));
+		    	 }
+		    	 
+	    		 new_peers.addAll( Arrays.asList( cached_peers ));
+
+		    	 response.setPeers( new_peers.toArray( new TRTrackerAnnouncerResponsePeer[new_peers.size()]) );
 		     }
 		}
+		
+		helper.informResponse( this, response );
 	}
 	
 	public void 
@@ -374,6 +421,23 @@ TRTrackerDHTAnnouncerImpl
 		return( helper.getTrackerResponseCache());
 	}
 	
+	public TrackerPeerSource 
+	getTrackerPeerSource(
+		TOTorrentAnnounceURLSet set) 
+	{
+		Debug.out( "not implemented" );
+		
+		return null;
+	}
+	
+	public TrackerPeerSource 
+	getCacheTrackerPeerSource()
+	{
+		Debug.out( "not implemented" );
+		
+		return null;
+	}
+	
 	public void 
 	generateEvidence(
 		IndentWriter writer )
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 557b170..26822fa 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperImpl.java
@@ -173,6 +173,27 @@ TRTrackerDHTScraperImpl
 	}
 	
 	public TRTrackerScraperResponse
+	peekScrape(
+		TOTorrent		torrent,
+		URL				unused_target_url )
+	{
+		if ( torrent != null ){
+
+			try{
+				HashWrapper hw = torrent.getHashWrapper();
+				
+				return( responses.get( hw ));
+				
+			}catch( TOTorrentException e ){
+				
+				Debug.printStackTrace(e);
+			}
+		}
+		
+		return( null );
+	}
+	
+	public TRTrackerScraperResponse
 	scrape(
 		TRTrackerAnnouncer	tracker_client )
 	{
diff --git a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperResponseImpl.java b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperResponseImpl.java
index cba1f80..92b286e 100644
--- a/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperResponseImpl.java
+++ b/org/gudy/azureus2/core3/tracker/client/impl/dht/TRTrackerDHTScraperResponseImpl.java
@@ -62,4 +62,17 @@ TRTrackerDHTScraperResponseImpl
 	{
 		return( url );
 	}
+	
+	public void
+	setDHTBackup(
+		boolean	is_backup )
+	{
+		// we're never a backup
+	}
+	
+	public boolean 
+	isDHTBackup() 
+	{	
+		return false;
+	}
 }
diff --git a/org/gudy/azureus2/core3/tracker/host/TRHost.java b/org/gudy/azureus2/core3/tracker/host/TRHost.java
index 53b8663..e2cde74 100644
--- a/org/gudy/azureus2/core3/tracker/host/TRHost.java
+++ b/org/gudy/azureus2/core3/tracker/host/TRHost.java
@@ -25,6 +25,8 @@ package org.gudy.azureus2.core3.tracker.host;
  * @author parg
  */
 
+import java.net.InetAddress;
+
 import org.gudy.azureus2.core3.torrent.*;
 import org.gudy.azureus2.core3.tracker.server.*;
 
@@ -51,6 +53,9 @@ TRHost
 	public String
 	getName();
 	
+	public InetAddress
+	getBindIP();
+	
 	public TRHostTorrent
 	hostTorrent(
 		TOTorrent		torrent,
diff --git a/org/gudy/azureus2/core3/tracker/host/TRHostAuthenticationListener.java b/org/gudy/azureus2/core3/tracker/host/TRHostAuthenticationListener.java
index 5565247..7c9c620 100644
--- a/org/gudy/azureus2/core3/tracker/host/TRHostAuthenticationListener.java
+++ b/org/gudy/azureus2/core3/tracker/host/TRHostAuthenticationListener.java
@@ -34,6 +34,7 @@ TRHostAuthenticationListener
 {
 	public boolean
 	authenticate(
+		String		headers,
 		URL			resource,
 		String		user,
 		String		password );
diff --git a/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java b/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
index 237732d..93e529f 100644
--- a/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
+++ b/org/gudy/azureus2/core3/tracker/host/impl/TRHostExternalTorrent.java
@@ -73,6 +73,10 @@ TRHostExternalTorrent
 		return( name );
 	}
 	
+	public String getUTF8Name() {
+		return null;
+	}
+
 	
 	public boolean
 	isSimpleTorrent()
@@ -124,6 +128,12 @@ TRHostExternalTorrent
 		return( false );
 	}
 	
+	public boolean 
+	isDecentralised() 
+	{
+		return( TorrentUtils.isDecentralised( getAnnounceURL()));
+	}
+	
 	public URL
 	getAnnounceURL()
 	{
@@ -444,6 +454,18 @@ TRHostExternalTorrent
 		throw( new TOTorrentException("External Torrent", TOTorrentException.RT_WRITE_FAILS ));
 	}
 
+ 	public void
+	addListener(
+		TOTorrentListener		l )
+	{
+	}
+
+	public void
+	removeListener(
+		TOTorrentListener		l )
+	{
+	}
+	
    	public AEMonitor
 	getMonitor()
    	{
diff --git a/org/gudy/azureus2/core3/tracker/host/impl/TRHostImpl.java b/org/gudy/azureus2/core3/tracker/host/impl/TRHostImpl.java
index d43ad73..9e0492e 100644
--- a/org/gudy/azureus2/core3/tracker/host/impl/TRHostImpl.java
+++ b/org/gudy/azureus2/core3/tracker/host/impl/TRHostImpl.java
@@ -518,6 +518,12 @@ TRHostImpl
 		}
 	}
 	
+	public InetAddress 
+	getBindIP()
+	{
+		return( null );
+	}
+	
 	protected TRTrackerServer
 	startServer(
 		int		protocol,
@@ -1218,6 +1224,7 @@ TRHostImpl
 	
 	public boolean
 	authenticate(
+		String		headers,
 		URL			resource,
 		String		user,
 		String		password )
@@ -1225,7 +1232,7 @@ TRHostImpl
 		for (int i=0;i<auth_listeners.size();i++){
 			
 			try{
-				boolean res = auth_listeners.get(i).authenticate( resource, user, password );
+				boolean res = auth_listeners.get(i).authenticate( headers, resource, user, password );
 				
 				if ( res ){
 					
diff --git a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce.java b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce.java
index 7c1bf71..a06a943 100644
--- a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce.java
+++ b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce.java
@@ -143,10 +143,10 @@ PRUDPPacketRequestAnnounce
 		return( left );
 	}
 	
-	public short
+	public int
 	getPort()
 	{
-		return( port );
+		return( port&0x0000ffff );
 	}
 	
 	public long
diff --git a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce2.java b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce2.java
index a98135e..f235b70 100644
--- a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce2.java
+++ b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestAnnounce2.java
@@ -146,10 +146,10 @@ PRUDPPacketRequestAnnounce2
 		return( left );
 	}
 	
-	public short
+	public int
 	getPort()
 	{
-		return( port );
+		return( port &0x0000ffff );
 	}
 	
 	public long
diff --git a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestScrape.java b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestScrape.java
index e64c14e..db6ff72 100644
--- a/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestScrape.java
+++ b/org/gudy/azureus2/core3/tracker/protocol/udp/PRUDPPacketRequestScrape.java
@@ -72,7 +72,7 @@ PRUDPPacketRequestScrape
 		throws IOException
 	{
 		super( PRUDPPacketTracker.ACT_REQUEST_SCRAPE, con_id, trans_id );
-		
+		hashes = new ArrayList();
 		byte[] hash;
 		while(is.read(hash = new byte[20]) == 20)
 			hashes.add(hash);
diff --git a/org/gudy/azureus2/core3/tracker/server/TRTrackerServer.java b/org/gudy/azureus2/core3/tracker/server/TRTrackerServer.java
index 91e1c4f..a2eaa41 100644
--- a/org/gudy/azureus2/core3/tracker/server/TRTrackerServer.java
+++ b/org/gudy/azureus2/core3/tracker/server/TRTrackerServer.java
@@ -21,6 +21,7 @@
 
 package org.gudy.azureus2.core3.tracker.server;
 
+import java.net.InetAddress;
 import java.util.Set;
 
 import org.gudy.azureus2.core3.util.Constants;
@@ -28,7 +29,7 @@ import org.gudy.azureus2.core3.util.Constants;
 public interface 
 TRTrackerServer 
 {
-	public static final String	DEFAULT_NAME	= Constants.AZUREUS_NAME;
+	public static final String	DEFAULT_NAME	= Constants.APP_NAME;
 	
 	public static final int DEFAULT_MIN_RETRY_DELAY 		= 120;
 	public static final int DEFAULT_MAX_RETRY_DELAY 		= 3600;
@@ -54,6 +55,9 @@ TRTrackerServer
 	public String
 	getHost();
 	
+	public InetAddress
+	getBindIP();
+	
 	public void
 	setReady();
 	
diff --git a/org/gudy/azureus2/core3/tracker/server/TRTrackerServerAuthenticationListener.java b/org/gudy/azureus2/core3/tracker/server/TRTrackerServerAuthenticationListener.java
index 22bb8ad..2384a13 100644
--- a/org/gudy/azureus2/core3/tracker/server/TRTrackerServerAuthenticationListener.java
+++ b/org/gudy/azureus2/core3/tracker/server/TRTrackerServerAuthenticationListener.java
@@ -42,6 +42,7 @@ TRTrackerServerAuthenticationListener
 	
 	public boolean
 	authenticate(
+		String		headers,
 		URL			resource,
 		String		user,
 		String		password );
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/TRTrackerServerImpl.java b/org/gudy/azureus2/core3/tracker/server/impl/TRTrackerServerImpl.java
index 8575ac8..6ab432e 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/TRTrackerServerImpl.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/TRTrackerServerImpl.java
@@ -28,6 +28,7 @@ package org.gudy.azureus2.core3.tracker.server.impl;
 
 
 import java.util.*;
+import java.net.InetSocketAddress;
 import java.net.URL;
 import java.net.URLDecoder;
 
@@ -467,15 +468,19 @@ TRTrackerServerImpl
 	
 	public boolean
 	performExternalAuthorisation(
-		URL			resource,
-		String		user,
-		String		password )
+		InetSocketAddress	remote_ip,
+		String				headers,
+		URL					resource,
+		String				user,
+		String				password )
 	{
+		headers = headers.trim() + "\r\nX-Real-IP: " + remote_ip.getAddress().getHostAddress() + "\r\n\r\n";
+		
 		for (int i=0;i<auth_listeners.size();i++){
 			
 			try{
 				
-				if ( ((TRTrackerServerAuthenticationListener)auth_listeners.get(i)).authenticate( resource, user, password )){
+				if ( ((TRTrackerServerAuthenticationListener)auth_listeners.get(i)).authenticate( headers, resource, user, password )){
 					
 					return( true );
 				}
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/dht/TRTrackerServerDHT.java b/org/gudy/azureus2/core3/tracker/server/impl/dht/TRTrackerServerDHT.java
index 006db12..47781f3 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/dht/TRTrackerServerDHT.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/dht/TRTrackerServerDHT.java
@@ -22,6 +22,8 @@
 
 package org.gudy.azureus2.core3.tracker.server.impl.dht;
 
+import java.net.InetAddress;
+
 import org.gudy.azureus2.core3.tracker.server.TRTrackerServerRequestListener;
 import org.gudy.azureus2.core3.tracker.server.impl.TRTrackerServerImpl;
 
@@ -60,6 +62,12 @@ TRTrackerServerDHT
 		return( false );
 	}
 	
+	public InetAddress 
+	getBindIP()
+	{
+		return( null );
+	}
+	
 	public void
 	addRequestListener(
 		TRTrackerServerRequestListener	l )
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerProcessorTCP.java b/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerProcessorTCP.java
index e23c6d0..81ae27f 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerProcessorTCP.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerProcessorTCP.java
@@ -172,7 +172,7 @@ TRTrackerServerProcessorTCP
 						
 							// check non-tracker authentication
 							
-						String user = doAuthentication( url_path, input_header, os, false );
+						String user = doAuthentication( remote_address, url_path, input_header, os, false );
 						
 						if ( user == null ){
 							
@@ -189,11 +189,11 @@ TRTrackerServerProcessorTCP
 					
 					if ( redirect.length() > 0 ){
 						
-						os.write( ("HTTP/1.1 301 Moved Permanently" + NL + "Location: " + redirect + NL + NL).getBytes() );
+						os.write( ("HTTP/1.1 301 Moved Permanently" + NL + "Location: " + redirect + NL + "Connection: close" + NL +  "Content-Length: 0" + NL + NL).getBytes() );
 						
 					}else{
 						
-						os.write( ("HTTP/1.1 404 Not Found" + NL + NL + "Page not found." + NL).getBytes() );
+						os.write( ("HTTP/1.1 404 Not Found" + NL + "Connection: close" + NL + "Content-Length: 0" + NL + NL ).getBytes() );
 					}
 					
 					os.flush();
@@ -205,7 +205,7 @@ TRTrackerServerProcessorTCP
 				
 					// check tracker authentication
 					
-				if ( doAuthentication( url_path, input_header, os, true ) == null ){
+				if ( doAuthentication( remote_address, url_path, input_header, os, true ) == null ){
 					
 					return ( false );
 				}
@@ -596,9 +596,20 @@ TRTrackerServerProcessorTCP
 							String	key 	= (String)entry.getKey();
 							String	value 	= (String)entry.getValue();
 							
+							if ( key.equalsIgnoreCase( "connection" )){
+								
+								if ( !value.equalsIgnoreCase( "close" )){
+									
+									Debug.out( "Ignoring 'Connection' header" );
+									
+									continue;
+								}
+							}
 							resp += key + ": " + value + NL;
 						}
 
+						resp += "Connection: close" + NL;
+
 						byte[]	payload = null;
 						
 						if ( error_entries != null ){
@@ -606,8 +617,11 @@ TRTrackerServerProcessorTCP
 							payload = BEncoder.encode( error_entries );
 							
 							resp += "Content-Length: " + payload.length + NL;
+						}else{
+							
+							resp += "Content-Length: 0" + NL;
 						}
-						
+												
 						resp += NL;
 
 						os.write( resp.getBytes());
@@ -785,10 +799,11 @@ TRTrackerServerProcessorTCP
 	
 	protected String
 	doAuthentication(
-		String			url_path,
-		String			header,
-		OutputStream	os,
-		boolean			tracker )
+		InetSocketAddress	remote_ip,
+		String				url_path,
+		String				header,
+		OutputStream		os,
+		boolean				tracker )
 		
 		throws IOException
 	{
@@ -826,7 +841,7 @@ TRTrackerServerProcessorTCP
 						
 						URL	resource = new URL( resource_str );
 					
-						if ( server.performExternalAuthorisation( resource, "", "" )){
+						if ( server.performExternalAuthorisation( remote_ip, header, resource, "", "" )){
 							
 							return( "" );
 						}
@@ -864,7 +879,7 @@ TRTrackerServerProcessorTCP
 						
 						URL	resource = new URL( resource_str );
 					
-						if ( server.performExternalAuthorisation( resource, user, pw )){
+						if ( server.performExternalAuthorisation( remote_ip, header, resource, user, pw )){
 							
 							return( user );
 						}
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerTCP.java b/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerTCP.java
index e74516f..888790e 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerTCP.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/tcp/TRTrackerServerTCP.java
@@ -213,7 +213,7 @@ TRTrackerServerTCP
 							
 							DOSEntry	this_entry = (DOSEntry)dos_list.get(i);
 							
-							String ts = new SimpleDateFormat("hh:mm:ss - ").format( new Date(this_entry.last_time ));
+							String ts = new SimpleDateFormat("HH:mm:ss - ").format( new Date(this_entry.last_time ));
 						
 							pw.println( ts + this_entry.ip );
 						}
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServer.java b/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServer.java
index ec7024f..24a9fad 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServer.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServer.java
@@ -51,6 +51,7 @@ TRBlockingServer
 {
 	private static final LogIDs LOGID = LogIDs.TRACKER;
 
+	private InetAddress		current_bind_ip;
 	private ServerSocket	server_socket;
 	
 	private volatile boolean	closed;
@@ -104,12 +105,20 @@ TRBlockingServer
 					}else{
 						SSLServerSocket ssl_server_socket;
 						
-						if ( bind_ip == null ){
+						if ( _bind_ip != null ){
+							
+							current_bind_ip = _bind_ip;
+							
+							ssl_server_socket = (SSLServerSocket)factory.createServerSocket(  getPort(), 128, _bind_ip );
+
+						}else if ( bind_ip == null ){
 							
 							ssl_server_socket = (SSLServerSocket)factory.createServerSocket( getPort(), 128 );
 							
 						}else{
 							
+							current_bind_ip = bind_ip;
+							
 							ssl_server_socket = (SSLServerSocket)factory.createServerSocket(  getPort(), 128, bind_ip );
 						}
 		
@@ -172,6 +181,8 @@ TRBlockingServer
 					
 					if ( _bind_ip != null ){
 					
+						current_bind_ip = _bind_ip;
+						
 						ss = new ServerSocket(  port, 1024, _bind_ip );
 
 					}else if ( bind_ip == null ){
@@ -180,6 +191,8 @@ TRBlockingServer
 						
 					}else{
 						
+						current_bind_ip = bind_ip;
+						
 						ss = new ServerSocket(  port, 1024, bind_ip );
 					}
 					
@@ -229,6 +242,12 @@ TRBlockingServer
 		}
 	}
 		
+	public InetAddress
+	getBindIP()
+	{
+		return( current_bind_ip );
+	}
+	
 	protected void
 	acceptLoop(
 		ServerSocket	ss )
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServerProcessor.java b/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServerProcessor.java
index 5739d7f..f90286b 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServerProcessor.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/tcp/blocking/TRBlockingServerProcessor.java
@@ -32,8 +32,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.net.Socket;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
 
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.tracker.server.TRTrackerServerException;
@@ -85,9 +83,17 @@ TRBlockingServerProcessor
 				
 				setTaskState( "entry" );
 				
-				try{										
-					socket.setSoTimeout( SOCKET_TIMEOUT );
-											
+				try{	
+					if ( keep_alive ){
+						
+						socket.setSoTimeout( KEEP_ALIVE_SOCKET_TIMEOUT );
+						
+						setTimeoutsDisabled( true );
+						
+					}else{
+					
+						socket.setSoTimeout( SOCKET_TIMEOUT );
+					}					
 				}catch ( Throwable e ){
 														
 					// e.printStackTrace();
@@ -375,17 +381,7 @@ TRBlockingServerProcessor
 					 // e.printStackTrace();
 				}
 				
-				if ( keep_alive ){
-					
-					try{				
-						socket.setSoTimeout( KEEP_ALIVE_SOCKET_TIMEOUT );
-												
-					}catch ( Throwable e ){
-					}
-											
-					setTimeoutsDisabled( true );
-					
-				}else{
+				if ( !keep_alive ){
 					
 					break;
 				}
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 0141b2b..2361a06 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
@@ -73,6 +73,8 @@ TRNonBlockingServer
 	private long	last_connections;
 	*/
 	
+	private InetAddress	current_bind_ip;
+	
 	private long	total_timeouts;
 	private long	total_connections;
 	
@@ -137,10 +139,14 @@ TRNonBlockingServer
 					
 				}else{
 	
+					current_bind_ip = _bind_ip;
+					
 					address = new InetSocketAddress( _bind_ip, _port );			
 				}
 			}else{
 				
+				current_bind_ip = _bind_ip;
+
 				address = new InetSocketAddress(  _bind_ip, _port );	
 			}
 			
@@ -213,6 +219,12 @@ TRNonBlockingServer
 		}
 	}
 	
+	public InetAddress 
+	getBindIP()
+	{
+		return( current_bind_ip );
+	}
+	
 	public void
 	setImmediateClose(
 		boolean	immediate )
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerProcessorUDP.java b/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerProcessorUDP.java
index 82ac6c2..9256573 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerProcessorUDP.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerProcessorUDP.java
@@ -55,7 +55,10 @@ TRTrackerServerProcessorUDP
 	private DatagramSocket			socket;
 	private DatagramPacket			request_dg;
 	
-	private static Map				connection_id_map 	= new LinkedHashMap();
+	private static Map<Long,connectionData>				connection_id_map 	= new LinkedHashMap<Long,connectionData>();
+	private static Map<String,List<connectionData>>		connection_ip_map 	= new HashMap<String,List<connectionData>>();
+	private static long									last_timeout_check;
+	
 	private static SecureRandom		random				= RandomUtils.SECURE_RANDOM;
 	private static AEMonitor		random_mon 			= new AEMonitor( "TRTrackerServerUDP:rand" );
 
@@ -218,6 +221,11 @@ TRTrackerServerProcessorUDP
 							
 							Object[] x = handleAnnounceAndScrape( client_ip_address, request, TRTrackerServerRequest.RT_ANNOUNCE );
 							
+							if ( x == null ){
+								
+								throw( new Exception( "Connection ID mismatch" ));
+							}
+							
 							reply 	= (PRUDPPacket)x[0];
 							torrent	= (TRTrackerServerTorrentImpl)x[1];
 					
@@ -227,6 +235,11 @@ TRTrackerServerProcessorUDP
 							
 							Object[] x = handleAnnounceAndScrape( client_ip_address, request, TRTrackerServerRequest.RT_SCRAPE );
 							
+							if ( x == null ){
+								
+								throw( new Exception( "Connection ID mismatch" ));
+							}
+
 							reply 	= (PRUDPPacket)x[0];
 							torrent	= (TRTrackerServerTorrentImpl)x[1];
 		
@@ -307,36 +320,82 @@ TRTrackerServerProcessorUDP
 			
 			Long	new_key = new Long(id);
 			
-			connectionData	new_data = new connectionData( client_address );
+			connectionData	new_data = new connectionData( client_address, id );
 			
 				// check for timeouts
 			
-			Iterator	it = connection_id_map.keySet().iterator();
-			
-			while(it.hasNext()){
+			if ( new_data.getTime() - last_timeout_check > 500 ){
 				
-				Long	key = (Long)it.next();
+				last_timeout_check = new_data.getTime();
 				
-				connectionData	data = (connectionData)connection_id_map.get(key);
-			
-				if ( new_data.getTime() - data.getTime() > CONNECTION_ID_LIFETIME ){
-					
-					// System.out.println( "TRTrackerServerProcessorUDP: conection id timeout" );
-					
-					it.remove();
+				Iterator<Long>	it = connection_id_map.keySet().iterator();
+							
+				while(it.hasNext()){
 					
-				}else{
-						// insertion order into map is time based - LinkedHashMap returns keys in same order
+					Long	key = it.next();
 					
-					break;
-				}
-			}	
+					connectionData	data = connection_id_map.get(key);
+				
+					if ( new_data.getTime() - data.getTime() > CONNECTION_ID_LIFETIME ){
+						
+						// System.out.println( "TRTrackerServerProcessorUDP: connection id timeout" );
+						
+						it.remove();
+						
+						List<connectionData> cds = connection_ip_map.get( client_address );
+
+						if ( cds != null ){
+							
+							Iterator<connectionData> it2 = cds.iterator();
+								
+							while( it2.hasNext()){
+								
+								if ( it2.next().getID() == key ){
+									
+									it2.remove();
+									
+									break;
+								}
+							}
+							
+							if ( cds.size() == 0 ){
+								
+								connection_ip_map.remove( client_address );
+							}
+						}
 						
+					}else{
+							// insertion order into map is time based - LinkedHashMap returns keys in same order
+						
+						break;
+					}
+				}
+			}
+				
+			List<connectionData> cds = connection_ip_map.get( client_address );
+			
+			if ( cds == null ){
+			
+				cds = new ArrayList<connectionData>();
+				
+				connection_ip_map.put( client_address, cds );
+			}
+			
+			cds.add( new_data );
+			
+			if ( cds.size() > 512 ){
+				
+				connectionData dead = cds.remove(0);
+				
+				connection_id_map.remove( dead.getID());
+			}
+			
 			connection_id_map.put( new_key, new_data );
 			
-			// System.out.println( "TRTrackerServerProcessorUDP: allocated:" + id + ", conection id map size = " + connection_id_map.size());
+			// System.out.println( "TRTrackerServerProcessorUDP: allocated:" + id + ", connection id map size = " + connection_id_map.size());
 			
 			return( id );
+			
 		}finally{
 			
 			random_mon.exit();
@@ -363,9 +422,10 @@ TRTrackerServerProcessorUDP
 				
 			}else{
 				
-					// single shot id, can't be reused
-				
-				connection_id_map.remove( key );
+				if ( SystemTime.getMonotonousTime() - data.getTime() > CONNECTION_ID_LIFETIME ){
+					
+					return( false );
+				}
 			}
 			
 			boolean	ok = data.getAddress().equals( client_address );
@@ -373,6 +433,7 @@ TRTrackerServerProcessorUDP
 			// System.out.println( "TRTrackerServerProcessorUDP: tested:" + id + "/" + client_address + " -> " + ok );
 			
 			return( ok );
+			
 		}finally{
 			
 			random_mon.exit();
@@ -689,24 +750,34 @@ TRTrackerServerProcessorUDP
 	protected static class
 	connectionData
 	{
-		protected String		address;
-		protected long			time;
+		private String		address;
+		private long		id;
+		private long		time;
 		
-		protected
+		private
 		connectionData(
-			String		_address )
+			String		_address,
+			long		_id )
 		{
 			address	= _address;
-			time	= SystemTime.getCurrentTime();
+			id		= _id;
+			
+			time	= SystemTime.getMonotonousTime();
 		}
 		
-		protected String
+		private String
 		getAddress()
 		{
 			return( address );
 		}
 		
-		protected long
+		private long
+		getID()
+		{
+			return( id );
+		}
+		
+		private long
 		getTime()
 		{
 			return( time );
diff --git a/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerUDP.java b/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerUDP.java
index b80d3d2..7fb7a9e 100644
--- a/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerUDP.java
+++ b/org/gudy/azureus2/core3/tracker/server/impl/udp/TRTrackerServerUDP.java
@@ -47,7 +47,8 @@ TRTrackerServerUDP
 
 	private ThreadPool	thread_pool;
 	
-	private int		port;
+	private int				port;
+	private InetAddress		current_bind_ip;
 	
 	private DatagramSocket	dg_socket;
 	
@@ -80,6 +81,8 @@ TRTrackerServerUDP
 				
 			}else{
 				
+				current_bind_ip = bind_ip;
+				
 				address = new InetSocketAddress( bind_ip, port);
 
 				socket = new DatagramSocket(address);
@@ -115,6 +118,12 @@ TRTrackerServerUDP
 		}
 	}
 	
+	public InetAddress 
+	getBindIP()
+	{
+		return( current_bind_ip );
+	}
+	
 	protected void
 	recvLoop(
 		DatagramSocket		socket,
diff --git a/org/gudy/azureus2/core3/util/AEDiagnostics.java b/org/gudy/azureus2/core3/util/AEDiagnostics.java
index 770cafc..89bf9eb 100644
--- a/org/gudy/azureus2/core3/util/AEDiagnostics.java
+++ b/org/gudy/azureus2/core3/util/AEDiagnostics.java
@@ -40,7 +40,6 @@ import com.aelitis.azureus.core.util.Java15Utils;
  */
 
 import java.io.*;
-import java.lang.reflect.Method;
 import java.util.*;
 
 public class 
@@ -122,7 +121,7 @@ AEDiagnostics
 	protected static boolean	logging_enabled;
 	protected static boolean	loggers_enabled;
 	
-	private static List		evidence_generators	= new ArrayList();
+	private static List<AEDiagnosticsEvidenceGenerator>		evidence_generators	= new ArrayList<AEDiagnosticsEvidenceGenerator>();
 		
 	public static synchronized void
 	startup(
@@ -241,6 +240,8 @@ AEDiagnostics
 			
 			AEThreadMonitor.initialise();
 			
+			AEMemoryMonitor.initialise();
+			
 		}catch( Throwable e ){
 			
 				// with webui we don't have the file stuff so this fails with class not found
@@ -323,7 +324,7 @@ AEDiagnostics
 	getLogger(
 		String		name )
 	{
-		AEDiagnosticsLogger	logger = (AEDiagnosticsLogger)loggers.get(name);
+		AEDiagnosticsLogger	logger = loggers.get(name);
 		
 		if ( logger == null ){
 			
@@ -405,6 +406,8 @@ AEDiagnostics
 	   		{	"iFW_Xfilter",		"y", },
 	   		{	"gapsp",			"y", },
 	   		{	"WSOCKHK",			"n", },
+	   		{	"InjHook12",		"n", },
+	   		{	"FPServiceProvider","n", },
 	};
 
 	public static void
@@ -524,7 +527,7 @@ AEDiagnostics
 				
 				String	alcohol_dll = "AxShlex";
 				
-				List	matches = new ArrayList();
+				List<String>	matches = new ArrayList<String>();
 				
 				while( true ){
 					
@@ -569,7 +572,7 @@ AEDiagnostics
 				
 				for (int i=0;i<matches.size();i++){
 					
-					String	dll = (String)matches.get(i);
+					String	dll = matches.get(i);
 					
 					String	detail = MessageText.getString( "platform.win32.baddll." + dll );
 					
@@ -601,6 +604,16 @@ AEDiagnostics
 	}
 	
 	public static void
+	removeEvidenceGenerator(
+		AEDiagnosticsEvidenceGenerator	gen )
+	{
+		synchronized( evidence_generators ){
+			
+			evidence_generators.remove( gen );
+		}
+	}
+	
+	public static void
 	generateEvidence(
 		PrintWriter		_writer )
 	{
@@ -611,7 +624,7 @@ AEDiagnostics
 			for (int i=0;i<evidence_generators.size();i++){
 				
 				try{
-					((AEDiagnosticsEvidenceGenerator)evidence_generators.get(i)).generate( writer );
+					evidence_generators.get(i).generate( writer );
 					
 				}catch( Throwable e ){
 					
diff --git a/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java b/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
index d416904..7941a4b 100644
--- a/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
+++ b/org/gudy/azureus2/core3/util/AEDiagnosticsLogger.java
@@ -34,6 +34,8 @@ import java.util.GregorianCalendar;
 import java.util.LinkedList;
 import java.util.TimeZone;
 
+import org.gudy.azureus2.core3.logging.Logger;
+
 /**
  * @author parg
  *
@@ -105,10 +107,17 @@ AEDiagnosticsLogger
 		}
 	}
 	
-	protected void
-	setForced()
+	public void
+	setForced(
+		boolean		_force )
 	{
-		force = true;
+		force = _force;
+	}
+	
+	public boolean
+	isForced()
+	{
+		return( force );
 	}
 	
 	protected String
@@ -166,12 +175,18 @@ AEDiagnosticsLogger
 		if ( stderr ){
 			
 			System.err.println( str );
+
+			// Logger dumps the stderr, but if it's not setup, do it outselves
+			if (Logger.getOldStdErr() == null) {
+				log( str );
+			}
+
 		}else{
 			
 			System.out.println( str );
+			log( str );
 		}
 		
-		log( str );
 	}
 	
 	public void
diff --git a/org/gudy/azureus2/core3/util/AEGenericCallback.java b/org/gudy/azureus2/core3/util/AEGenericCallback.java
new file mode 100644
index 0000000..25f6345
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/AEGenericCallback.java
@@ -0,0 +1,9 @@
+package org.gudy.azureus2.core3.util;
+
+public interface 
+AEGenericCallback 
+{
+	public Object
+	invoke(
+		Object		arg );
+}
diff --git a/org/gudy/azureus2/core3/util/AEMemoryMonitor.java b/org/gudy/azureus2/core3/util/AEMemoryMonitor.java
new file mode 100644
index 0000000..1306234
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/AEMemoryMonitor.java
@@ -0,0 +1,356 @@
+/*
+ * Created on Sep 9, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.core3.util;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.util.List;
+
+import javax.management.Notification;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationListener;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
+
+public class 
+AEMemoryMonitor 
+{
+	private static final long MB = 1024*1024;
+
+	private static long	max_heap_mb;
+	
+	protected static void
+	initialise()
+	{
+		try{
+			List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
+		
+			MemoryPoolMXBean 	pool_to_monitor = null;
+			long				ptm_size		= 0;
+			
+			long	overall_max = 0;
+			
+			for ( MemoryPoolMXBean pool: pools ){
+			
+				long pool_max = pool.getUsage().getMax();
+				
+				if ( pool_max > 0 ){
+					
+					if ( pool.getType() == MemoryType.HEAP ){
+					
+						overall_max += pool_max;
+					}
+				}
+				
+				if ( pool.getType() == MemoryType.HEAP && pool.isCollectionUsageThresholdSupported()){
+				
+					long max = pool.getUsage().getMax();
+					
+					if ( max > ptm_size ){
+						
+						pool_to_monitor = pool;
+						ptm_size		= max;
+					}
+				}
+			}
+			
+			max_heap_mb = (overall_max+MB-1)/MB;
+
+			if ( pool_to_monitor != null ){
+
+				long max = pool_to_monitor.getUsage().getMax();
+				
+				long threshold = max*3/4;
+				
+				threshold = Math.min( threshold, 5*1024*1024 );
+				
+				MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
+
+				NotificationEmitter emitter = (NotificationEmitter) mbean;
+
+				
+				emitter.addNotificationListener(
+					new NotificationListener()
+					{
+						private long	last_mb_log = Long.MAX_VALUE;
+						
+						private boolean increase_tried;
+						
+						public void 
+						handleNotification(
+							Notification 	notification, 
+							Object 			handback ) 
+						{
+							MemoryPoolMXBean pool = (MemoryPoolMXBean)handback;
+
+							long used 	= pool.getCollectionUsage().getUsed();
+							long max 	= pool.getUsage().getMax();
+							
+							long avail = max-used;
+							
+							if ( avail < 0 ){
+								avail = 0;
+							}
+							
+							long	mb = (avail+MB-1)/(MB);
+							
+							if ( mb <= 4 ){
+								
+								synchronized( this ){
+									
+									if ( mb >= last_mb_log ){
+										
+										return;
+									}
+									
+									last_mb_log = mb;
+								}
+								
+								Runtime runtime = Runtime.getRuntime();
+								
+								Debug.out( "MemMon: notify triggered: pool=" + pool.getName() + 
+											", used=" + used + 
+											", max=" + max + 
+											": runtime free=" + runtime.freeMemory() + ", tot=" + runtime.totalMemory() + ", max=" + runtime.maxMemory());
+
+	 							Logger.logTextResource(
+	 								new LogAlert(
+	 									LogAlert.REPEATABLE, 
+	 									LogAlert.AT_WARNING,
+										"memmon.low.warning"), 
+										new String[] {
+	 										(mb==0?"< ":"") + DisplayFormatters.formatByteCountToKiBEtc( Math.max(1,mb)*MB, true ),
+	 										DisplayFormatters.formatByteCountToKiBEtc( max_heap_mb*MB, true )});
+	 							
+	 							if ( mb == 1 && !increase_tried ){
+	 								
+	 								increase_tried = true;
+	 							
+	 								if ( COConfigurationManager.getBooleanParameter( "jvm.heap.auto.increase.enable", true )){
+
+		 								PlatformManager platform = PlatformManagerFactory.getPlatformManager();
+	
+		 								if ( platform.hasCapability( PlatformManagerCapabilities.AccessExplicitVMOptions )){
+		 									
+		 									try{
+		 										String[] options = platform.getExplicitVMOptions();
+	
+		 										long	max_mem = getJVMLongOption( options, "-Xmx" );
+	
+		 										if ( max_mem <= 0 ){
+		 											
+		 											max_mem = getMaxHeapMB()*MB;
+		 										}
+		 										
+		 										final long HEAP_AUTO_INCREASE_MAX 	= 256*MB;
+		 										final long HEAP_AUTO_INCREASE_BY	= 16*MB;
+		 										
+		 										if ( max_mem > 0 && max_mem < HEAP_AUTO_INCREASE_MAX ){
+		 												 							 												
+	 												max_mem += HEAP_AUTO_INCREASE_BY;
+	 												
+	 												if ( max_mem > HEAP_AUTO_INCREASE_MAX ){
+	 													
+	 													max_mem = HEAP_AUTO_INCREASE_MAX;
+	 												}
+	 												
+	 												long	last_increase = COConfigurationManager.getLongParameter( "jvm.heap.auto.increase.last", 0 );
+	 												
+	 												if ( max_mem > last_increase ){
+	 													
+	 													COConfigurationManager.setParameter( "jvm.heap.auto.increase.last", max_mem );
+	 															
+		 												options = setJVMLongOption( options, "-Xmx", max_mem );
+		 												
+		 												platform.setExplicitVMOptions( options );
+		 												
+		 					 							Logger.logTextResource(
+		 						 								new LogAlert(
+		 						 									LogAlert.REPEATABLE, 
+		 						 									LogAlert.AT_WARNING,
+		 															"memmon.heap.auto.increase.warning"),
+		 															new String[] {
+		 					 											DisplayFormatters.formatByteCountToKiBEtc( max_mem, true )});
+	 												}
+	 											}
+		 									
+		 									}catch( Throwable e ){
+		 										
+		 										Debug.out( e );
+		 									}
+		 								}
+	 								}
+	 							}
+							}
+						}
+					},
+					null, pool_to_monitor );
+
+				pool_to_monitor.setCollectionUsageThreshold( threshold );
+
+			}
+		}catch( Throwable e ){
+		
+			Debug.out( e );
+		}
+		
+		if ( max_heap_mb == 0 ){
+			
+			max_heap_mb = ( Runtime.getRuntime().maxMemory()+MB-1)/MB;
+		}
+	}
+	
+	public static long
+	getMaxHeapMB()
+	{
+		return( max_heap_mb );
+	}
+	
+	public static  long
+	getJVMLongOption(
+		String[]	options,
+		String		prefix )
+	{		
+		long	value = -1;
+		
+		for ( String option: options ){
+			
+			try{
+				if ( option.startsWith( prefix )){
+					
+					String	val = option.substring( prefix.length());
+					
+					value = decodeJVMLong( val );
+				}
+			}catch( Throwable e ){
+					
+				Debug.out( "Failed to process option '" + option + "'", e );
+			}
+		}
+		
+		return( value );
+	}
+	
+	public static  String[]
+	setJVMLongOption(
+		String[]	options,
+		String		prefix,
+		long		val )
+	{
+		String new_option = prefix + encodeJVMLong( val );
+				
+		for (int i=0;i<options.length;i++){
+			
+			String option = options[i];
+			
+			if ( option.startsWith( prefix )){
+			
+				options[i] = new_option;
+				
+				new_option = null;
+			}
+		}
+		
+		if ( new_option != null ){
+		
+			String[] new_options = new String[options.length+1];
+		
+			System.arraycopy( options, 0, new_options, 0, options.length );
+			
+			new_options[options.length] = new_option;
+			
+			options = new_options;
+		}
+		
+		return( options );
+	}
+		
+	public static  long
+	decodeJVMLong(
+		String		val )
+	
+		throws Exception
+	{
+		long	 mult = 1;
+		
+		char last_char = Character.toLowerCase( val.charAt( val.length()-1 ));
+		
+		if ( !Character.isDigit( last_char )){
+			
+			val = val.substring( 0, val.length()-1 );
+			
+			if ( last_char == 'k' ){
+					
+				mult	= 1024;
+				
+			}else if ( last_char == 'm' ){
+				
+				mult	= 1024*1024;
+				
+			}else if ( last_char == 'g' ){
+				
+				mult	= 1024*1024*1024;
+				
+			}else{
+				
+				throw( new Exception( "Invalid size unit '" + last_char + "'" ));
+			}
+		}
+		
+		return( Long.parseLong( val ) * mult );
+	}
+	
+	public static String
+	encodeJVMLong(
+		long	val )
+	{
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ));
+		}
+		
+		val = val/1024;
+		
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ) + "k" );
+		}
+		
+		val = val/1024;
+		
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ) + "m" );
+		}
+		
+		val = val/1024;
+		
+		return( String.valueOf( val ) + "g" );
+	}
+}
diff --git a/org/gudy/azureus2/core3/util/AERunStateHandler.java b/org/gudy/azureus2/core3/util/AERunStateHandler.java
new file mode 100644
index 0000000..370a204
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/AERunStateHandler.java
@@ -0,0 +1,156 @@
+/*
+ * Created on Sep 18, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.core3.util;
+
+import java.util.Iterator;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+
+import com.aelitis.azureus.core.util.CopyOnWriteList;
+
+public class 
+AERunStateHandler 
+{
+	public static final long		RS_DELAYED_UI			= 0x00000001;
+	public static final long		RS_UDP_NET_ONLY			= 0x00000002;
+	public static final long		RS_DHT_SLEEPING			= 0x00000004;
+	
+	public static final long		RS_ALL_ACTIVE			= 0x00000000;
+	public static final long		RS_ALL_LOW				= 0xffffffff;
+	
+	private static boolean	start_low = COConfigurationManager.getBooleanParameter( "Start In Low Resource Mode" );
+	
+	private static long	current_mode = start_low?RS_ALL_LOW:RS_ALL_ACTIVE;
+	
+	private static AsyncDispatcher	dispatcher = new AsyncDispatcher(2500);
+	
+	private static CopyOnWriteList<RunStateChangeListener>	listeners = new CopyOnWriteList<RunStateChangeListener>();
+	
+	public static boolean
+	isDelayedUI()
+	{
+		return( ( current_mode & RS_DELAYED_UI ) != 0 );
+	}
+	
+	public static boolean
+	isUDPNetworkOnly()
+	{
+		return( ( current_mode & RS_UDP_NET_ONLY ) != 0 );
+	}
+	
+	public static boolean
+	isDHTSleeping()
+	{
+		return( ( current_mode & RS_DHT_SLEEPING ) != 0 );
+	}
+	
+	public static long
+	getResourceMode()
+	{
+		return( current_mode );
+	}
+	
+	public static void
+	setResourceMode(
+		final long		new_mode )
+	{
+		synchronized( dispatcher ){
+			
+			if ( new_mode == current_mode ){
+				
+				return;
+			}
+		
+			current_mode = new_mode;
+			
+			final Iterator<RunStateChangeListener> it = listeners.iterator();
+			
+			dispatcher.dispatch(
+				new AERunnable()
+				{
+					public void
+					runSupport()
+					{
+						while( it.hasNext()){
+							
+							try{								
+								it.next().runStateChanged( new_mode );
+								
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+						
+					}
+				});
+		}
+	}
+	
+	public static void
+	addListener(
+		final RunStateChangeListener	l,
+		boolean							fire_now )
+	{
+		synchronized( dispatcher ){
+
+			listeners.add( l );
+			
+			if ( fire_now ){
+				
+				dispatcher.dispatch(
+					new AERunnable()
+					{
+						public void
+						runSupport()
+						{
+							try{
+								l.runStateChanged( current_mode );
+
+							}catch( Throwable e ){
+								
+								Debug.out( e );
+							}
+						}
+					});
+			}
+		}
+	}
+	
+	public static void
+	removeListener(
+		RunStateChangeListener	l )
+	{
+		synchronized( dispatcher ){
+
+			listeners.remove( l );
+		}
+	}
+	
+	public interface
+	RunStateChangeListener
+	{
+		public void
+		runStateChanged(
+			long		run_state );
+	}
+}
diff --git a/org/gudy/azureus2/core3/util/AERunnableObject.java b/org/gudy/azureus2/core3/util/AERunnableObject.java
index f188e03..6ee5fb2 100644
--- a/org/gudy/azureus2/core3/util/AERunnableObject.java
+++ b/org/gudy/azureus2/core3/util/AERunnableObject.java
@@ -44,7 +44,7 @@ public abstract class AERunnableObject
 			Debug.out(id, e);
 		} finally {
 			if (sem != null) {
-				sem.release();
+				sem.releaseForever();
 			}
 		}
 	}
diff --git a/org/gudy/azureus2/core3/util/AETemporaryFileHandler.java b/org/gudy/azureus2/core3/util/AETemporaryFileHandler.java
index 3755511..92ac1b1 100644
--- a/org/gudy/azureus2/core3/util/AETemporaryFileHandler.java
+++ b/org/gudy/azureus2/core3/util/AETemporaryFileHandler.java
@@ -34,6 +34,8 @@ import java.io.IOException;
 public class 
 AETemporaryFileHandler 
 {
+    private static final boolean PORTABLE = System.getProperty( "azureus.portable.root", "" ).length() > 0;
+
 	private static final String	PREFIX = "AZU";
 	private static final String	SUFFIX = ".tmp";
 	
@@ -158,6 +160,34 @@ AETemporaryFileHandler
 		return( File.createTempFile( PREFIX, SUFFIX, tmp_dir ));
 	}
 	
+	public static File
+	createSemiTempFile()
+	
+		throws IOException
+	{
+		if ( PORTABLE ){
+			
+			try{
+				File stmp_dir = FileUtil.getUserFile( "tmp2" );
+	
+				if ( !stmp_dir.exists()){
+					
+					stmp_dir.mkdirs();
+				}
+				
+				if ( stmp_dir.canWrite()){
+					
+					return( File.createTempFile( PREFIX, null, stmp_dir ));
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		return( File.createTempFile( PREFIX, null ));
+	}
+	
 	public static File 
 	createTempDir()
 	
diff --git a/org/gudy/azureus2/core3/util/AEThread2.java b/org/gudy/azureus2/core3/util/AEThread2.java
index cbc7bec..f0c64e4 100644
--- a/org/gudy/azureus2/core3/util/AEThread2.java
+++ b/org/gudy/azureus2/core3/util/AEThread2.java
@@ -60,6 +60,13 @@ AEThread2
 	
 	public
 	AEThread2(
+		String		_name )
+	{
+		this( _name, true );
+	}
+	
+	public
+	AEThread2(
 		String		_name,
 		boolean		_daemon )
 	{
@@ -163,6 +170,11 @@ AEThread2
 	}
 	
 	public boolean
+	isAlive() {
+		return wrapper == null ? false : wrapper.isAlive();
+	}
+	
+	public boolean
 	isCurrentThread()
 	{
 		return( wrapper == Thread.currentThread());
@@ -345,7 +357,7 @@ AEThread2
 
 						daemon_threads.addLast( this );
 
-						setName( "AEThead2:parked[" + daemon_threads.size() + "]" );
+						setName( "AEThread2:parked[" + daemon_threads.size() + "]" );
 						
 						// System.out.println( "AEThread2: queue=" + daemon_threads.size() + ",creates=" + total_creates + ",starts=" + total_starts );
 					}
diff --git a/org/gudy/azureus2/core3/util/AddressUtils.java b/org/gudy/azureus2/core3/util/AddressUtils.java
index 7163c09..a6871d8 100644
--- a/org/gudy/azureus2/core3/util/AddressUtils.java
+++ b/org/gudy/azureus2/core3/util/AddressUtils.java
@@ -26,6 +26,7 @@ import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.URL;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -299,6 +300,8 @@ AddressUtils
 		try {
 			is_lan_local = isLANLocalAddress( HostNameToIPResolver.syncResolve( address ));
 			
+		}catch( UnknownHostException e ){
+			
 		}catch( Throwable t ){
 			
 			t.printStackTrace();  
diff --git a/org/gudy/azureus2/core3/util/AsyncDispatcher.java b/org/gudy/azureus2/core3/util/AsyncDispatcher.java
index 2406532..efd0c69 100644
--- a/org/gudy/azureus2/core3/util/AsyncDispatcher.java
+++ b/org/gudy/azureus2/core3/util/AsyncDispatcher.java
@@ -27,22 +27,42 @@ import java.util.LinkedList;
 public class 
 AsyncDispatcher 
 {
-	private AEThread2	thread;
-	private LinkedList	queue 		= new LinkedList();
-	private AESemaphore	queue_sem 	= new AESemaphore( "AsyncDispatcher" );
+	private String					name;
+	private AEThread2				thread;
+	private int						priority	= Thread.NORM_PRIORITY;
+	private LinkedList<AERunnable>	queue 		= new LinkedList<AERunnable>();
+	private AESemaphore				queue_sem 	= new AESemaphore( "AsyncDispatcher" );
+	
+	private int						num_priority;
 	
 	private int quiesce_after_millis;
 	
 	public
 	AsyncDispatcher()
 	{
-		this( 10000 );
+		this( "AsyncDispatcher", 10000 );
+	}
+	
+	public
+	AsyncDispatcher(
+		String		name )
+	{
+		this( name, 10000 );
 	}
 	
 	public
 	AsyncDispatcher(
-		int	_quiesce_after_millis )
+		int		quiesce_after_millis )
 	{
+		this( "AsyncDispatcher", quiesce_after_millis );
+	}
+	
+	public
+	AsyncDispatcher(
+		String		_name,
+		int			_quiesce_after_millis )
+	{
+		name					= _name;
 		quiesce_after_millis	= _quiesce_after_millis;
 	}
 	
@@ -50,14 +70,31 @@ AsyncDispatcher
 	dispatch(
 		AERunnable	target )
 	{
+		dispatch( target, false );
+	}
+	
+	public void
+	dispatch(
+		AERunnable	target,
+		boolean		is_priority )
+	{
 		synchronized( this ){
 			
-			queue.add( target );
+			if ( is_priority ){
+			
+				queue.add( num_priority, target );
+				
+				num_priority++;
+				
+			}else{
+			
+				queue.add( target );
+			}
 			
 			if ( thread == null ){
 				
 				thread = 
-					new AEThread2( "AsyncDispatcher", true )
+					new AEThread2( name, true )
 					{
 						public void
 						run()
@@ -67,7 +104,7 @@ AsyncDispatcher
 								queue_sem.reserve( quiesce_after_millis );
 								
 								AERunnable	to_run = null;
-								
+																
 								synchronized( AsyncDispatcher.this ){
 									
 									if ( queue.isEmpty()){
@@ -77,7 +114,12 @@ AsyncDispatcher
 										break;
 									}
 									
-									to_run = (AERunnable)queue.removeFirst();
+									to_run = queue.removeFirst();
+									
+									if ( num_priority > 0 ){
+										
+										num_priority--;
+									}
 								}
 								
 								try{
@@ -91,6 +133,8 @@ AsyncDispatcher
 						}
 					};
 					
+				thread.setPriority( priority );
+				
 				thread.start();
 			}
 		}
@@ -115,4 +159,20 @@ AsyncDispatcher
 			return( queue.size());
 		}
 	}
+	
+	public void
+	setPriority(
+		int		p )
+	{
+		priority = p;
+	}
+	
+	public boolean
+	isDispatchThread()
+	{
+		synchronized( this ){
+			
+			return( thread != null && thread.isCurrentThread());
+		}
+	}
 }
diff --git a/org/gudy/azureus2/core3/util/BDecoder.java b/org/gudy/azureus2/core3/util/BDecoder.java
index aee5caf..fea7896 100644
--- a/org/gudy/azureus2/core3/util/BDecoder.java
+++ b/org/gudy/azureus2/core3/util/BDecoder.java
@@ -25,9 +25,11 @@ package org.gudy.azureus2.core3.util;
 import java.io.*;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 
 /**
@@ -39,13 +41,34 @@ import java.util.Map;
  */
 public class BDecoder 
 {
-	private static final int MAX_BYTE_ARRAY_SIZE	= 8*1024*1024;
+	public static final int MAX_BYTE_ARRAY_SIZE	= 16*1024*1024;
 	private static final int MAX_MAP_KEY_SIZE		= 64*1024;
 	
 	private static final boolean TRACE	= false;
 	
 	private boolean recovery_mode;
-
+	private boolean	verify_map_order;
+	
+	private final static byte[]	PORTABLE_ROOT;
+	
+	static{
+		byte[]	portable = null;
+		
+		try{
+			String root = System.getProperty( "azureus.portable.root", "" );
+			
+			if ( root.length() > 0 ){
+				
+				portable = root.getBytes( "UTF-8" );
+			}
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+		
+		PORTABLE_ROOT = portable;
+	}
+	
 	public static Map
 	decode(
 		byte[]	data )
@@ -87,7 +110,7 @@ public class BDecoder
 
 		throws IOException 
 	{ 
-		return( decode(new BDecoderInputStreamArray(data)));
+		return( decode(new BDecoderInputStreamArray(data),true));
 	}
 
 	public Map 
@@ -98,9 +121,29 @@ public class BDecoder
 
 		throws IOException 
 	{ 
-		return( decode(new BDecoderInputStreamArray(data, offset, length )));
+		return( decode(new BDecoderInputStreamArray(data, offset, length ),true));
 	}
+	
+	public Map 
+	decodeByteArray(
+		byte[] 	data,
+		int		offset,
+		int		length,
+		boolean internKeys)
 
+		throws IOException 
+	{ 
+		return( decode(new BDecoderInputStreamArray(data, offset, length ),internKeys));
+	}
+	
+	// used externally 
+	public Map decodeByteBuffer(ByteBuffer buffer, boolean internKeys) throws IOException {
+		InputStream is = new BDecoderInputStreamArray(buffer);
+		Map result = decode(is,internKeys);
+		buffer.position(buffer.limit()-is.available());
+		return result;
+	}
+	
 	public Map 
 	decodeStream(
 		BufferedInputStream data )  
@@ -117,7 +160,7 @@ public class BDecoder
 
 		throws IOException 
 	{
-		Object	res = decodeInputStream(data, 0, internKeys);
+		Object	res = decodeInputStream(data, "", 0, internKeys);
 
 		if ( res == null ){
 
@@ -133,11 +176,11 @@ public class BDecoder
 
 	private Map 
 	decode(
-		InputStream data ) 
+		InputStream data, boolean internKeys ) 
 
 		throws IOException 
 	{
-		Object res = decodeInputStream(data, 0, true);
+		Object res = decodeInputStream(data, "", 0, internKeys);
 
 		if ( res == null ){
 
@@ -151,12 +194,15 @@ 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
+	// reuseable objects for key decoding
 	private ByteBuffer keyBytesBuffer = ByteBuffer.allocate(32);
+	private CharBuffer keyCharsBuffer = CharBuffer.allocate(32);
+	private CharsetDecoder keyDecoder = Constants.BYTE_CHARSET.newDecoder();
 
 	private Object 
 	decodeInputStream(
 		InputStream dbis,
+		String		context,
 		int			nesting,
 		boolean internKeys) 
 
@@ -181,9 +227,11 @@ public class BDecoder
 		case 'd' :
 				//create a new dictionary object
 			
-			Map tempMap = new LightHashMap();
+			LightHashMap tempMap = new LightHashMap();
 
 			try{
+				byte[]	prev_key = null;
+				
 					//get the key   
 				
 				while (true) {
@@ -198,27 +246,82 @@ public class BDecoder
 					
 					// decode key strings manually so we can reuse the bytebuffer
 
-					int keyLength = (int)getNumberFromStream(dbis, ':');
+					int keyLength = (int)getPositiveNumberFromStream(dbis, ':');
 
-					ByteBuffer keyBytes;
+					if ( keyLength > MAX_MAP_KEY_SIZE ){
+						byte[] remaining = new byte[128];
+						getByteArrayFromStream(dbis, 128, remaining);
+						String msg = "dictionary key is too large, max=" + MAX_MAP_KEY_SIZE + ": value=" + new String(remaining);
+						System.err.println( msg );
+						throw( new IOException( msg ));
+					}
+					
 					if(keyLength < keyBytesBuffer.capacity())
 					{
-						keyBytes = keyBytesBuffer;
-						keyBytes.position(0).limit(keyLength);
+						keyBytesBuffer.position(0).limit(keyLength);
+						keyCharsBuffer.position(0).limit(keyLength);
 					} else {
-						keyBytes = keyBytesBuffer = ByteBuffer.allocate(keyLength);
+						keyBytesBuffer = ByteBuffer.allocate(keyLength);
+						keyCharsBuffer = CharBuffer.allocate(keyLength);
 					}
 					
-					getByteArrayFromStream(dbis, keyLength, keyBytes.array());						
-
-					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 ));
+					getByteArrayFromStream(dbis, keyLength, keyBytesBuffer.array());						
+					
+					if ( verify_map_order ){
+						
+						byte[] current_key = new byte[keyLength];
+						
+						System.arraycopy( keyBytesBuffer.array(), 0, current_key, 0, keyLength );
+						
+						if ( prev_key != null ){
+							
+							int	len = Math.min( prev_key.length, keyLength );
+							
+							int	state = 0;
+							
+							for ( int i=0;i<len;i++){
+								
+								int	cb = current_key[i]&0x00ff;
+								int	pb = prev_key[i]&0x00ff;
+								
+								if ( cb > pb ){
+									state = 1;
+									break;
+								}else if ( cb < pb ){
+									state = 2;
+									break;
+								}
+							}
+							
+							if ( state == 0){
+								if ( prev_key.length > keyLength ){
+									
+									state = 2;
+								}
+							}
+							
+							if ( state == 2 ){
+								
+								// Debug.out( "Dictionary order incorrect: prev=" + new String( prev_key ) + ", current=" + new String( current_key ));
+								
+								if (!( tempMap instanceof LightHashMapEx )){
+									
+									LightHashMapEx x = new LightHashMapEx( tempMap );
+									
+									x.setFlag( LightHashMapEx.FL_MAP_ORDER_INCORRECT, true );
+									
+									tempMap = x;
+								}
+							}
+						}
+						
+						prev_key = current_key;
 					}
 					
-					CharBuffer	cb = Constants.BYTE_CHARSET.decode(keyBytes);
-					String key = new String(cb.array(),0,cb.limit());
+					keyDecoder.reset();
+					keyDecoder.decode(keyBytesBuffer,keyCharsBuffer,true);
+					keyDecoder.flush(keyCharsBuffer);
+					String key = new String(keyCharsBuffer.array(),0,keyCharsBuffer.limit());
 					
 					// keys often repeat a lot - intern to save space
 					if (internKeys)
@@ -228,7 +331,7 @@ public class BDecoder
 
 					//decode value
 
-					Object value = decodeInputStream(dbis,nesting+1,internKeys);
+					Object value = decodeInputStream(dbis,key,nesting+1,internKeys);
 					
 					// value interning is too CPU-intensive, let's skip that for now
 					/*if(value instanceof byte[] && ((byte[])value).length < 17)
@@ -283,9 +386,7 @@ public class BDecoder
 				}
 			}
 
-			if (tempMap instanceof LightHashMap)
-				((LightHashMap) tempMap).compactify(-0.9f);
-
+			tempMap.compactify(-0.9f);
 
 				//return the map
 			
@@ -299,8 +400,10 @@ public class BDecoder
 			try{
 					//create the key
 				
+				String context2 = PORTABLE_ROOT==null?context:(context+"[]");
+				
 				Object tempElement = null;
-				while ((tempElement = decodeInputStream(dbis, nesting+1, internKeys)) != null) {
+				while ((tempElement = decodeInputStream(dbis, context2, nesting+1, internKeys)) != null) {
 						//add the element
 					tempList.add(tempElement);
 				}
@@ -348,7 +451,7 @@ public class BDecoder
 				//move back one
 			dbis.reset();
 				//get the string
-			return getByteArrayFromStream(dbis);
+			return getByteArrayFromStream(dbis, context );
 
 		default :{
 
@@ -400,6 +503,53 @@ public class BDecoder
 	/** only create the array once per decoder instance (no issues with recursion as it's only used in a leaf method)
 	 */
 	private final char[] numberChars = new char[32];
+
+	/**
+	 * @note will break (likely return a negative) if number >
+	 * {@link Integer#MAX_VALUE}.  This check is intentionally skipped to
+	 * increase performance
+	 */
+	private int
+	getPositiveNumberFromStream(
+			InputStream	dbis,
+			char	parseChar)
+
+	throws IOException 
+	{
+		int tempByte = dbis.read();
+		if (tempByte < 0) {
+			return -1;
+		}
+		if (tempByte != parseChar) {
+
+			int value = tempByte - '0';
+			
+			tempByte = dbis.read();
+			// optimized for single digit cases
+			if (tempByte == parseChar) {
+				return value;
+			}
+			if (tempByte < 0) {
+				return -1;
+			}
+
+			while (true) {
+				// Base10 shift left --> v*8 + v*2 = v*10
+				value = (value << 3) + (value << 1) + (tempByte - '0');
+				// For bounds check:
+				// if (value < 0) return something;
+				tempByte = dbis.read();
+				if (tempByte == parseChar) {
+					return value;
+				}
+				if (tempByte < 0) {
+					return -1;
+				}
+			}
+		} else {
+			return 0;
+		}
+	}
 	
 	private long 
 	getNumberFromStream(
@@ -623,11 +773,12 @@ public class BDecoder
 
 	private byte[] 
 	getByteArrayFromStream(
-		InputStream dbis )
+		InputStream dbis,
+		String		context )
 		
 		throws IOException 
 	{
-		int length = (int) getNumberFromStream(dbis, ':');
+		int length = (int) getPositiveNumberFromStream(dbis, ':');
 
 		if (length < 0) {
 			return null;
@@ -645,6 +796,52 @@ public class BDecoder
 		
 		getByteArrayFromStream(dbis, length, tempArray);		
 		
+		if ( PORTABLE_ROOT != null && length >= PORTABLE_ROOT.length && tempArray[1] == ':' && tempArray[2] == '\\' && context != null ){
+			
+			boolean	mismatch = false;
+			
+			for ( int i=2;i<PORTABLE_ROOT.length;i++){
+				
+				if ( tempArray[i] != PORTABLE_ROOT[i] ){
+					
+					mismatch = true;
+					
+					break;
+				}
+			}
+			
+			if ( !mismatch ){
+								
+				context = context.toLowerCase( Locale.US );
+				
+					// always a chance a hash will match the root so we just pick on relevant looking
+					// entries...
+				
+				if ( 	context.contains( "file" ) || 
+						context.contains( "link" ) || 
+						context.contains( "dir" ) || 
+						context.contains( "folder" ) || 
+						context.contains( "path" ) || 
+						context.contains( "save" ) || 
+						context.contains( "torrent" )){
+					
+					tempArray[0] = PORTABLE_ROOT[0];
+	
+					/*
+					String	test = new String( tempArray, 0, tempArray.length > 80?80:tempArray.length );
+	
+					System.out.println( "mapped " + context + "->" + tempArray.length + ": " + test );
+					*/
+					
+				}else{
+												
+					String	test = new String( tempArray, 0, tempArray.length > 80?80:tempArray.length );
+							
+					System.out.println( "Portable: not mapping " + context + "->" + tempArray.length + ": " + test );
+				}
+			}
+		}
+		
 		return tempArray; 
 	}
 
@@ -661,6 +858,13 @@ public class BDecoder
 	}	
 
 	public void
+	setVerifyMapOrder(
+		boolean	b )
+	{
+		verify_map_order = b;
+	}
+	
+	public void
 	setRecoveryMode(
 		boolean	r )
 	{
@@ -975,18 +1179,25 @@ public class BDecoder
 	
 		extends InputStream
 	{
-		final private byte[]		buffer;
-		final private int			count;
-
-		private int	pos;
-		private int	mark;
+		final private byte[] bytes;
+		private int pos = 0;
+		private int markPos;
+		private int overPos;
 
+		
+		public BDecoderInputStreamArray(ByteBuffer buffer) {
+			bytes = buffer.array();
+			pos = buffer.arrayOffset() + buffer.position();
+			overPos = pos + buffer.remaining();
+		}
+		
+		
 		private
 		BDecoderInputStreamArray(
 			byte[]		_buffer )
 		{
-			buffer	= _buffer;
-			count	= buffer.length;
+			bytes = _buffer;
+			overPos = bytes.length;
 		}
 
 		private
@@ -995,10 +1206,14 @@ public class BDecoder
 			int			_offset,
 			int			_length )
 		{
-			buffer		= _buffer;
-			pos			= _offset;
-			count 		= Math.min( _offset + _length, _buffer.length );
-			mark		= _offset;
+			if (_offset == 0) {
+				bytes = _buffer;
+				overPos = _length;
+			} else {
+				bytes = _buffer;
+				pos = _offset;
+				overPos = Math.min(_offset + _length, bytes.length);
+			}
 		}
 		
 		public int
@@ -1006,7 +1221,10 @@ public class BDecoder
 
 			throws IOException
 		{
-			return (pos < count) ? (buffer[pos++] & 0xff) : -1;
+			if (pos < overPos) {
+				return bytes[pos++] & 0xFF;
+			}
+			return -1;
 		}
 
 		public int
@@ -1026,26 +1244,15 @@ public class BDecoder
 
 			throws IOException
 		{
-			if ( pos >= count ){
-
-				return( -1 );
-			}
-
-			if ( pos + length > count ){
-				
-				length = count - pos;
-			}
-
-			if (length <= 0){
-
-				return( 0 );
+			
+			if (pos < overPos) {
+				int toRead = Math.min(length, overPos - pos);
+				System.arraycopy(bytes, pos, b, offset, toRead);
+				pos += toRead;
+				return toRead;
 			}
+			return -1;
 
-			System.arraycopy(buffer, pos, b, offset, length);
-
-			pos += length;
-
-			return( length );
 		}
 
 		public int
@@ -1053,7 +1260,7 @@ public class BDecoder
 
 			throws IOException
 		{
-			return( count - pos );
+			return overPos - pos;
 		}
 
 		public boolean
@@ -1066,7 +1273,7 @@ public class BDecoder
 		mark(
 			int	limit )
 		{
-			mark	= pos;
+			markPos = pos;
 		}
 
 		public void
@@ -1074,7 +1281,7 @@ public class BDecoder
 
 			throws IOException
 		{
-			pos	= mark;
+			pos = markPos;
 		}
 	}
 
diff --git a/org/gudy/azureus2/core3/util/BEncoder.java b/org/gudy/azureus2/core3/util/BEncoder.java
index b5e6a7b..ae6c881 100644
--- a/org/gudy/azureus2/core3/util/BEncoder.java
+++ b/org/gudy/azureus2/core3/util/BEncoder.java
@@ -42,6 +42,8 @@ BEncoder
 	
 	private static final byte[] MINUS_1_BYTES = "-1".getBytes();
 	
+	private static volatile int non_ascii_logs;
+
     public static byte[] 
     encode(
     	Map object ) 
@@ -91,23 +93,21 @@ BEncoder
             object = ((BEncodableObject)object).toBencodeObject();
         }
 
-        if ( object instanceof String || object instanceof Float){
+        if ( object instanceof String || object instanceof Float || object instanceof Double ){
         	
-            String tempString = (object instanceof String) ? (String)object : String.valueOf((Float)object);
+            String tempString = (object instanceof String) ? (String)object : String.valueOf(object);
 
             	// usually this is simpler to encode by hand as chars < 0x80 map directly in UTF-8
             
             boolean	simple = true;
             
-            char[] chars = tempString.toCharArray();
-            
-            int	char_count = chars.length;
+            int	char_count = tempString.length();
             
             byte[]	encoded = new byte[char_count];
             
             for (int i=0;i<char_count;i++){
             	
-            	char c = chars[i];
+            	char c = tempString.charAt(i);
             	
             	if ( c < 0x80 ){
             		
@@ -192,7 +192,7 @@ BEncoder
 							try
 							{
 								encodeObject(Constants.BYTE_CHARSET.encode(key));
-								if (!encodeObject(tempMap.get(key)))
+								if (!encodeObject(value))
 									encodeObject("");
 							} catch (UnsupportedEncodingException e)
 							{
@@ -200,6 +200,28 @@ BEncoder
 							}
 						} else
 						{
+								// if we put non-ascii chars in as keys we can get horrible expanding
+								// config issues as we cycle through decode/encode cycles with certain
+								// characters
+							
+							if ( Constants.IS_CVS_VERSION ){
+								char[]	chars = key.toCharArray();
+								
+								for ( char c: chars ){
+
+									if (c >= '\u0080'){
+
+										if ( non_ascii_logs < 50 ){
+											
+											non_ascii_logs++;
+											
+											Debug.out( "Non-ASCII key: " + key );
+										}
+										
+										break;
+									}
+								}
+							}
 							encodeObject(key); // Key goes in as UTF-8
 							if (!encodeObject(value))
 								encodeObject("");
@@ -265,7 +287,7 @@ BEncoder
     	   	// ideally we'd bork here but I don't want to run the risk of breaking existing stuff so just log
     	   
     	   
-    	   Debug.out( "Attempt to encode a null value" );
+    	   Debug.out( "Attempt to encode a null value: sofar=" + getEncodedSoFar());
     	   return false;
     	   
        }else{
@@ -411,6 +433,12 @@ BEncoder
     	writeBytes( bb.array(), bb.arrayOffset() + bb.position(), bb.remaining());
     }
 
+    private String
+    getEncodedSoFar()
+    {
+    	return( new String( toByteArray()));
+    }
+    
     private byte[]
     toByteArray()
     {
diff --git a/org/gudy/azureus2/core3/util/BrokenMd5Hasher.java b/org/gudy/azureus2/core3/util/BrokenMd5Hasher.java
index df952c7..61f425d 100644
--- a/org/gudy/azureus2/core3/util/BrokenMd5Hasher.java
+++ b/org/gudy/azureus2/core3/util/BrokenMd5Hasher.java
@@ -17,7 +17,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc.,  59 Temple Plac(int)e, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: BrokenMd5Hasher.java,v 1.1 2005/11/16 13:36:23 parg Exp $
+ * $Id: BrokenMd5Hasher.java,v 1.1 2005-11-16 13:36:23 parg Exp $
  *
  ********************************************************************************/
 
@@ -36,7 +36,7 @@ import java.nio.ByteOrder;
  *
  * @author emarant
  * @version $Revision: 1.1 $
- * <br>Last changed by $Author: parg $ on $Date: 2005/11/16 13:36:23 $
+ * <br>Last changed by $Author: parg $ on $Date: 2005-11-16 13:36:23 $
  */
 public final class BrokenMd5Hasher {
     
diff --git a/org/gudy/azureus2/core3/util/ByteFormatter.java b/org/gudy/azureus2/core3/util/ByteFormatter.java
index 180e4dc..3b9886a 100644
--- a/org/gudy/azureus2/core3/util/ByteFormatter.java
+++ b/org/gudy/azureus2/core3/util/ByteFormatter.java
@@ -273,4 +273,30 @@ public class ByteFormatter
 			| (array[1] << 8) & 0x000000000000ff00l
 			| array[0] & 0x00000000000000ffl;
 	}
+  
+  public static byte[]
+  intToByteArray(
+		long	v )
+  {
+	 return( new byte[]{
+      (byte)(v >>> 24),
+      (byte)(v >>> 16),
+      (byte)(v >>>  8),
+      (byte)(v >>>  0)});  
+  }
+  
+  public static byte[]
+  longToByteArray(
+		 long	v )
+  {
+	  return( new byte[]{
+		  (byte)(v >>> 56),
+		  (byte)(v >>> 48),
+		  (byte)(v >>> 40),
+		  (byte)(v >>> 32),
+		  (byte)(v >>> 24),
+		  (byte)(v >>> 16),
+		  (byte)(v >>>  8),
+		  (byte)(v >>>  0)});  
+  }
 }
diff --git a/org/gudy/azureus2/core3/util/Constants.java b/org/gudy/azureus2/core3/util/Constants.java
index 55c5267..af2a4bd 100644
--- a/org/gudy/azureus2/core3/util/Constants.java
+++ b/org/gudy/azureus2/core3/util/Constants.java
@@ -20,9 +20,14 @@
  */
 package org.gudy.azureus2.core3.util;
 
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
 import java.nio.charset.Charset;
+import java.security.AccessControlException;
 import java.util.Locale;
 import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.regex.Pattern;
 
 /**
  *  
@@ -34,11 +39,11 @@ public class
 Constants 
 {
   public static final String EMPTY_STRING = "";
-  public static final String SF_WEB_SITE			= "http://azureus.sourceforge.net/";
+  public static final String SF_WEB_SITE			= "http://plugins.vuze.com/";
  
-  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 AELITIS_TORRENTS		= "http://cf1.vuze.com/torrent/torrents/";
+  public static final String AELITIS_FILES			= "http://cf1.vuze.com/torrent/files/";
+  public static final String AZUREUS_WIKI 			= "http://wiki.vuze.com/w/";
   
   public static final String  VERSION_SERVER_V4 	= "version.vuze.com";
   public static final String  VERSION_SERVER_V6 	= "version6.vuze.com";
@@ -58,26 +63,55 @@ Constants
   
   public static final String DEFAULT_ENCODING 	= "UTF8";
   public static final String BYTE_ENCODING 		= "ISO-8859-1";
-  public static Charset	BYTE_CHARSET;
-  public static Charset	DEFAULT_CHARSET;
+  public static final Charset	BYTE_CHARSET;
+  public static final Charset	DEFAULT_CHARSET;
 
   static{
+	  Charset	bc 	= null;
+	  Charset	dc	= null;
+	  
 	  try{
-	  	BYTE_CHARSET 	= Charset.forName( Constants.BYTE_ENCODING );
-	 	DEFAULT_CHARSET = Charset.forName( Constants.DEFAULT_ENCODING );
+	  	bc 	= Charset.forName( Constants.BYTE_ENCODING );
+	 	dc	= Charset.forName( Constants.DEFAULT_ENCODING );
 
 	}catch( Throwable e ){
 		
 		e.printStackTrace();
 	}
+	
+  	BYTE_CHARSET 	= bc;
+  	DEFAULT_CHARSET	= dc;
   }
   
   public static final Locale LOCALE_ENGLISH = new Locale("en", "");
   
+  static{
+	  try{
+		  String	timezone = System.getProperty( "azureus.timezone", null );
+		  
+		  if ( timezone != null ){
+			
+			  TimeZone.setDefault( TimeZone.getTimeZone( timezone ));
+		  }  
+		}catch( Throwable e ){
+						
+				// can happen in applet
+		
+			if ( e instanceof AccessControlException ){
+				
+			}else{
+			
+				e.printStackTrace();
+			}
+		}
+  }
+  
   public static final String INFINITY_STRING	= "\u221E"; // "oo";pa  
   public static final int    CRAPPY_INFINITY_AS_INT  = 365*24*3600; // seconds (365days)
   public static final long   CRAPPY_INFINITE_AS_LONG = 10000*365*24*3600; // seconds (10k years)
   
+  public static boolean DOWNLOAD_SOURCES_PRETEND_COMPLETE	= false;
+	  
   	// keep the CVS style constant coz version checkers depend on it!
   	// e.g. 2.0.8.3
     //      2.0.8.3_CVS
@@ -85,8 +119,10 @@ Constants
   
   public static String APP_NAME = "Vuze";
   public static final String AZUREUS_NAME	  = "Azureus";
-  public static final String AZUREUS_VERSION  = "4.3.0.6";  //4.3.0.7_CVS
-  public static final byte[] VERSION_ID       = ("-" + "AZ" + "4306" + "-").getBytes();  //MUST be 8 chars long!
+  public static final String AZUREUS_VERSION  = "4.8.0.0";
+  public static final String BUILD_VERSION  = "@build.version@";   //Ant replace
+  public static final String AZUREUS_SUBVER	  = "";
+  public static final byte[] VERSION_ID       = ("-" + "AZ" + "4800" + "-").getBytes();  //MUST be 8 chars long!
 
   private static final boolean FORCE_NON_CVS = System.getProperty( "az.force.noncvs", "0" ).equals( "1" );
   
@@ -99,7 +135,6 @@ Constants
   public static final boolean isSolaris			= OSName.equalsIgnoreCase("SunOS");
   public static final boolean isFreeBSD			= OSName.equalsIgnoreCase("FreeBSD");
   public static final boolean isWindowsXP		= OSName.equalsIgnoreCase("Windows XP");
-  public static final boolean isWindowsVista 	= OSName.equalsIgnoreCase("Windows Vista");
   public static final boolean isWindows95		= OSName.equalsIgnoreCase("Windows 95");
   public static final boolean isWindows98		= OSName.equalsIgnoreCase("Windows 98");
   public static final boolean isWindows2000		= OSName.equalsIgnoreCase("Windows 2000");
@@ -112,10 +147,35 @@ Constants
   // If it isn't windows or osx, it's most likely an unix flavor
   public static final boolean isUnix = !isWindows && !isOSX;
  
-  
+  public static final boolean isWindowsVista;
+  public static final boolean isWindowsVistaSP2OrHigher;
   public static final boolean isWindowsVistaOrHigher;
+  public static final boolean isWindows7OrHigher;
+  
+  
+  // Common Patterns
+	public static final Pattern PAT_SPLIT_COMMAWORDS = Pattern.compile("\\s*,\\s*");
+	public static final Pattern PAT_SPLIT_COMMA = Pattern.compile(",");
+	public static final Pattern PAT_SPLIT_DOT = Pattern.compile("\\.");
+	public static final Pattern PAT_SPLIT_SPACE = Pattern.compile(" ");
+	public static final Pattern PAT_SPLIT_SLASH_N = Pattern.compile("\n");
+	
+  
+  public static final boolean is64Bit;
   
   static{
+	  boolean _is64Bit;
+	  
+	  try{
+		  _is64Bit = System.getProperty( "os.arch" ).contains( "64" );
+		  
+	  }catch( Throwable e ){
+		  
+		  _is64Bit = false;
+	  }
+	  
+	  is64Bit = _is64Bit;
+	  
 	  if ( isWindows ){
 
 		  Float ver = null;
@@ -126,16 +186,83 @@ Constants
 		  }catch (Throwable e){
 		  }
 
-		  isWindowsVistaOrHigher = ver != null && ver.floatValue() >= 6;
+		  boolean vista_sp2_or_higher	= false;
+
+		  if ( ver == null ){
+			  
+			  isWindowsVista			= false;
+			  isWindowsVistaOrHigher 	= false;
+			  isWindows7OrHigher		= false;
+			  
+		  }else{
+			  float f_ver = ver.floatValue();
+			  	
+			  isWindowsVista			= f_ver == 6;
+			  isWindowsVistaOrHigher 	= f_ver >= 6;
+			  isWindows7OrHigher	 	= f_ver >= 6.1f;
 		  
+			  if ( isWindowsVista ){
+			  
+		            LineNumberReader lnr = null;
+		            
+		    	    try{
+		    	        Process p = 
+		    	        	Runtime.getRuntime().exec( 
+		    	        		new String[]{
+		    	        				"reg",
+		    	        				"query",
+		    	        				"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion",
+		    	        				"/v",
+		    	        				"CSDVersion" });
+		              
+		    	        lnr = new LineNumberReader( new InputStreamReader( p.getInputStream()));
+		    	        		    	        
+		    	        while( true ){
+		    	        	
+		    	        	String	line = lnr.readLine();
+		    	        	
+		    	        	if ( line == null ){
+		    	        		
+		    	        		break;
+		    	        	}
+		    	        	
+		    	            if ( line.matches( ".*CSDVersion.*" )){
+		    	            	
+		    	            	vista_sp2_or_higher = line.matches( ".*Service Pack [2-9]" );
+		    	            	
+		    	                break;
+		    	            }
+		    	        }
+		    	    }catch( Throwable e ){
+		    	    	
+		    	    }finally{
+		    	    	
+		                if ( lnr != null ){
+		                	
+		                    try{
+		                    	lnr.close();
+		                        
+		                    }catch( Throwable e ){
+		                    }
+		                }
+		            }
+		    	}
+		  }
+		  
+		  isWindowsVistaSP2OrHigher = vista_sp2_or_higher;
 	  }else{
 		  
-		  isWindowsVistaOrHigher = false;
+		  isWindowsVista			= false;
+		  isWindowsVistaSP2OrHigher	= false;
+		  isWindowsVistaOrHigher 	= false;
+		  isWindows7OrHigher 		= false;
 	  }
   }
   
   public static final boolean isOSX_10_5_OrHigher;
   public static final boolean isOSX_10_6_OrHigher;
+  public static final boolean isOSX_10_7_OrHigher;
+  public static final boolean isOSX_10_8_OrHigher;
   
   static{
 	  if ( isOSX ){
@@ -160,11 +287,15 @@ Constants
 		  
 		  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 );
+		  isOSX_10_7_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 7 );
+		  isOSX_10_8_OrHigher = first_digit > 10 || ( first_digit == 10 && second_digit >= 8 );
 		  
 	  }else{
 		  
 		  isOSX_10_5_OrHigher = false;
 		  isOSX_10_6_OrHigher = false;
+		  isOSX_10_7_OrHigher = false;
+		  isOSX_10_8_OrHigher = false;
 	  }
   }
   
@@ -254,6 +385,20 @@ Constants
   	}
   }
   
+	public static boolean
+  	isCurrentVersionLT(
+  		String	version )
+  	{
+  		return( compareVersions( AZUREUS_VERSION, version ) < 0 );
+  	}
+	
+  	public static boolean
+  	isCurrentVersionGE(
+  		String	version )
+  	{
+  		return( compareVersions( AZUREUS_VERSION, version ) >= 0 );
+  	}
+  	
 		/**
 		 * compare two version strings of form n.n.n.n (e.g. 1.2.3.4)
 		 * @param version_1	
@@ -267,6 +412,9 @@ Constants
 		String		version_2 )
 	{	
 		try{
+			version_1 = version_1.replaceAll( "_CVS", "_B100" );
+			version_2 = version_2.replaceAll( "_CVS", "_B100" );
+			
 			if ( version_1.startsWith("." )){
 				version_1 = "0" + version_1;
 			}
diff --git a/org/gudy/azureus2/core3/util/Debug.java b/org/gudy/azureus2/core3/util/Debug.java
index 6c57078..a6db752 100644
--- a/org/gudy/azureus2/core3/util/Debug.java
+++ b/org/gudy/azureus2/core3/util/Debug.java
@@ -23,6 +23,7 @@ package org.gudy.azureus2.core3.util;
 
 import java.io.*;
 import java.net.UnknownHostException;
+import java.rmi.ConnectException;
 import java.util.*;
 
 /**
@@ -31,9 +32,11 @@ import java.util.*;
 public class Debug {
   
 	private static AEDiagnosticsLogger	diag_logger	= AEDiagnostics.getLogger( "debug" );
+	
+	private static boolean STOP_AT_INITIALIZER = System.getProperty("debug.stacktrace.full", "0").equals("0");
 
 	static{
-		diag_logger.setForced();
+		diag_logger.setForced( true );
 	}
   
   /**
@@ -82,6 +85,14 @@ public class Debug {
    * line number, appending the stacktrace of the given exception.
    */
   public static void out(final String _debug_msg, final Throwable _exception) {
+  	if ((_exception instanceof ConnectException) && _exception.getMessage().startsWith("No route to host")) {
+  		diagLoggerLog(_exception.toString());
+  		return;
+  	}
+  	if ((_exception instanceof UnknownHostException)) {
+  		diagLoggerLog(_exception.toString());
+  		return;
+  	}
     String header = "DEBUG::";
     header = header + new Date(SystemTime.getCurrentTime()).toString() + "::";
     String className;
@@ -100,7 +111,7 @@ public class Debug {
       methodName = first_line.getMethodName() + "::";
       lineNumber = first_line.getLineNumber();
       
-    	trace_trace_tail = getCompressedStackTrace(e, 3, 200);
+    	trace_trace_tail = getCompressedStackTrace(e, 3, 200, false);
     }
     
     diagLoggerLogAndOut(header+className+(methodName)+lineNumber+":", true);
@@ -175,34 +186,74 @@ public class Debug {
 		return getCompressedStackTrace(t, frames_to_skip, 200);
 	}
 
+
 	public static String 
 	getCompressedStackTrace(
 		Throwable t,
 		int frames_to_skip, 
 		int iMaxLines) 
 	{
-		String sStackTrace = "";
+		return getCompressedStackTrace(t, frames_to_skip, iMaxLines, true);
+	}
+
+	
+	public static String 
+	getCompressedStackTrace(
+		Throwable t,
+		int frames_to_skip, 
+		int iMaxLines,
+		boolean showErrString) 
+	{
+		StringBuffer sbStackTrace = new StringBuffer(showErrString ? (t.toString() + "; ") : "");
 		StackTraceElement[]	st = t.getStackTrace();
 
+		if (iMaxLines < 0) {
+			iMaxLines = st.length + iMaxLines;
+			if (iMaxLines < 0) {
+				iMaxLines = 1;
+			}
+		}
 		int iMax = Math.min(st.length, iMaxLines + frames_to_skip);
 		for (int i = frames_to_skip; i < iMax; i++) {
 
-			if (i > frames_to_skip)
-				sStackTrace += ",";
-
-			String cn = st[i].getClassName();
-			cn = cn.substring( cn.lastIndexOf(".")+1);
+			if (i > frames_to_skip) {
+				sbStackTrace.append(", ");
+			}
 
-			sStackTrace += cn +"::"+st[i].getMethodName()+"::"+st[i].getLineNumber();
+			String classname = st[i].getClassName();
+			String cnShort = classname.substring( classname.lastIndexOf(".")+1);
+
+			if (Constants.IS_CVS_VERSION) {
+				if (STOP_AT_INITIALIZER
+						&& st[i].getClassName().equals(
+								"com.aelitis.azureus.ui.swt.Initializer")) {
+					sbStackTrace.append("Initializer");
+					break;
+				}
+				// Formatted so it's clickable in eclipse
+				sbStackTrace.append(st[i].getMethodName());
+				sbStackTrace.append(" (");
+				sbStackTrace.append(classname);
+				sbStackTrace.append(".java:");
+				sbStackTrace.append(st[i].getLineNumber());
+				sbStackTrace.append(')');
+			} else {
+				sbStackTrace.append(cnShort);
+				sbStackTrace.append("::");
+				sbStackTrace.append(st[i].getMethodName());
+				sbStackTrace.append("::");
+				sbStackTrace.append(st[i].getLineNumber());
+			}
 		}
 
 		Throwable cause = t.getCause();
 
 		if (cause != null) {
-			sStackTrace += "\n\tCaused By: " + getCompressedStackTrace(cause, 0);
+			sbStackTrace.append("\n\tCaused By: ");
+			sbStackTrace.append(getCompressedStackTrace(cause, 0));
 		}
 
-		return sStackTrace;
+		return sbStackTrace.toString();
 	}
 
 	public static String getStackTrace(boolean bCompressed, boolean bIncludeSelf) {
@@ -226,7 +277,7 @@ public class Debug {
 		try {
 			throw new Exception();
 		} catch (Exception e) {
-			trace_trace_tail = getCompressedStackTrace(e, frames_to_skip, iMaxLines);
+			trace_trace_tail = getCompressedStackTrace(e, frames_to_skip, iMaxLines, false);
 		}
 
 		return (trace_trace_tail);
@@ -393,15 +444,27 @@ public class Debug {
 	}
 	
 	public static String
+	getCompressedStackTraceSkipFrames(
+		int	frames_to_skip )
+	{
+		return( getCompressedStackTrace( new Throwable(), frames_to_skip+1, 200, false ));
+	}
+	
+	public static String
 	getCompressedStackTrace()
 	{
-		return( getCompressedStackTrace( new Throwable(), 2 ));
+		return( getCompressedStackTrace( new Throwable(), 1, 200, false ));
 	}
 
+	/**
+	 * 
+	 * @param iMaxLines Max # of stack lines.  If < 0, chops off -MaxLines entries from end
+	 * @return
+	 */
 	public static String
 	getCompressedStackTrace(int iMaxLines)
 	{
-		return( getCompressedStackTrace( new Throwable(), 2, iMaxLines ));
+		return( getCompressedStackTrace( new Throwable(), 1, iMaxLines, false ));
 	}
 
 	public static String
@@ -439,6 +502,14 @@ public class Debug {
 		Throwable e,
 		Object context)
 	{
+  	if ((e instanceof ConnectException) && e.getMessage().startsWith("No route to host")) {
+  		diagLoggerLog(e.toString());
+  		return;
+  	}
+  	if ((e instanceof UnknownHostException)) {
+  		diagLoggerLog(e.toString());
+  		return;
+  	}
 		String header = "DEBUG::";
 		header = header + new Date(SystemTime.getCurrentTime()).toString() + "::";
 		String className	= "?::";
diff --git a/org/gudy/azureus2/core3/util/DirectByteBuffer.java b/org/gudy/azureus2/core3/util/DirectByteBuffer.java
index 112b6c0..913e83c 100644
--- a/org/gudy/azureus2/core3/util/DirectByteBuffer.java
+++ b/org/gudy/azureus2/core3/util/DirectByteBuffer.java
@@ -70,7 +70,13 @@ DirectByteBuffer
     public static final byte        AL_MSG_LT_EXT_MESSAGE = 27;
     public static final byte        AL_MSG_LT_HANDSHAKE   = 28;
     public static final byte        AL_MSG_UT_PEX         = 29;
-    public static final byte        AL_MSG_BT_DHT_PORT    = 30;
+    public static final byte        AL_MSG_BT_DHT_PORT    		= 30;
+    public static final byte        AL_MSG_BT_REJECT_REQUEST    = 31;
+    public static final byte        AL_MSG_BT_SUGGEST_PIECE   	= 32;
+    public static final byte        AL_MSG_BT_ALLOWED_FAST    	= 33;
+    public static final byte        AL_MSG_UT_METADATA 	        = 34;
+    public static final byte        AL_MSG_AZ_METADATA 	        = 35;
+
     
 	public static final String[] AL_DESCS =
 	{ "None", "Ext", "Other", "PeerRead", "PeerLen",
@@ -90,7 +96,15 @@ DirectByteBuffer
     "AZPayload",
     "File",
     "MsgCrypt",
-    "LTExtMsg","LTExtHandshake","UTPEX", "BTDHTPort"};
+    "LTExtMsg",
+    "LTExtHandshake",
+    "UTPEX", 
+    "BTDHTPort",
+    "BTRejectRequest",
+    "BTSuggestPiece",
+    "BTAllowedFast",
+    "UTMetaData",
+    "AZMetaData" };
 	 
     
     
@@ -149,7 +163,10 @@ DirectByteBuffer
 			"write(fc)",	"read(sc)",		"write(sc)",	"getBuffer",		"getShort",
 			"putShort",
 		};
-			
+		
+	public static final byte	FL_NONE						= 0x00;
+	public static final byte	FL_CONTAINS_TRANSIENT_DATA	= 0x01;
+	
 	protected static final boolean	TRACE				= AEDiagnostics.TRACE_DIRECT_BYTE_BUFFERS;
 	protected static final int		TRACE_BUFFER_SIZE	= 64;		// must be even
 	
@@ -157,6 +174,7 @@ DirectByteBuffer
 	private ByteBuffer 				buffer;
 	private DirectByteBufferPool	pool;
 	private byte					allocator;
+	private byte					flags;
 	private boolean                 was_returned_to_pool = false;
   
 	
@@ -214,6 +232,20 @@ DirectByteBuffer
 		return( res );
 	}
 	
+	public void
+	setFlag(
+		byte		flag )
+	{
+		flags |= flag;
+	}
+	
+	public boolean
+	getFlag(
+		byte		flag )
+	{
+		return((flags&flag)!=0);
+	}
+	
 	protected void
 	traceUsage(
 		byte		subsystem,
diff --git a/org/gudy/azureus2/core3/util/DirectByteBufferPoolReal.java b/org/gudy/azureus2/core3/util/DirectByteBufferPoolReal.java
index a1c3577..861e08e 100644
--- a/org/gudy/azureus2/core3/util/DirectByteBufferPoolReal.java
+++ b/org/gudy/azureus2/core3/util/DirectByteBufferPoolReal.java
@@ -288,39 +288,59 @@ DirectByteBufferPoolReal
 	
 					//	check if the buffers in this pool are big enough
 	      
-				if (reqVal.compareTo(keyVal) <= 0) {
+				if ( reqVal.compareTo(keyVal) <= 0 ){
 	      	
-	   
 					ArrayList bufferPool = (ArrayList)buffersMap.get(keyVal);
-	            
-					synchronized ( poolsLock ) { 
 	        
-						//	make sure we don't remove a buffer when running compaction
-						//if there are no free buffers in the pool, create a new one.
-						//otherwise use one from the pool
-	        	
-						if (bufferPool.isEmpty()) {
-	          	
-							buff = allocateNewBuffer(keyVal.intValue());
-	            
-						}else{
-	          	
-							synchronized ( bufferPool ) {
-	            	
-								buff = (ByteBuffer)bufferPool.remove(bufferPool.size() - 1);
+					while( true ){
+						
+						synchronized ( poolsLock ) { 
+		        
+							// make sure we don't remove a buffer when running compaction
+							// if there are no free buffers in the pool, create a new one.
+							// otherwise use one from the pool
+		        	
+							if ( bufferPool.isEmpty()){
+		          	
+								buff = allocateNewBuffer(keyVal.intValue());
+		            
+								if ( buff == null ){
+									
+									Debug.out( "allocateNewBuffer for " + _length + " returned null" );
+								}
+								
+								break;
+								
+							}else{
+		          	
+								synchronized ( bufferPool ) {
+		            	
+									buff = (ByteBuffer)bufferPool.remove(bufferPool.size() - 1);
+								}
+								
+								if ( buff == null ){
+									
+									Debug.out( "buffer pool for " + _length + " contained null entry" ); 
+									
+								}else{
+									
+									break;
+								}
 							}
 						}
 					}
-			
+					
 					break;
 				}
 			}
 		
 			if ( buff == null ){
-						      
-			    Debug.out("Unable to find an appropriate buffer pool");
+					
+				String str = "Unable to find an appropriate buffer pool for " + _length;
+				
+			    Debug.out( str );
 			    
-			    throw( new RuntimeException( "Unable to find an appropriate buffer pool" ));
+			    throw( new RuntimeException( str ));
 			}
 			
 			res = new DirectByteBuffer( _allocator, buff, this );		   
@@ -393,6 +413,11 @@ DirectByteBufferPoolReal
 	{		
 		ByteBuffer	buff = ddb.getBufferInternal();
 		
+		if ( buff == null ){
+			
+			Debug.out( "Returned dbb has null delegate" );
+		}
+		
 		int	capacity = buff.capacity();
 
 		bytesIn += capacity;
diff --git a/org/gudy/azureus2/core3/util/DisplayFormatters.java b/org/gudy/azureus2/core3/util/DisplayFormatters.java
index 2a535a2..e95ba98 100644
--- a/org/gudy/azureus2/core3/util/DisplayFormatters.java
+++ b/org/gudy/azureus2/core3/util/DisplayFormatters.java
@@ -211,7 +211,12 @@ DisplayFormatters
     per_sec = getResourceString( "Formats.units.persec", "/s" );
 
     units_base10 = 
-    	new String[]{ getUnit( "B"), getUnit("KB"), getUnit( "MB" ), getUnit( "GB"), getUnit( "TB" ) };
+    	new String[]{ 
+    		getUnit( use_units_rate_bits?"bit":"B"), 
+    		getUnit( use_units_rate_bits?"kbit":"KB"), 
+    		getUnit( use_units_rate_bits?"Mbit":"MB" ), 
+    		getUnit( use_units_rate_bits?"Gbit":"GB"), 
+    		getUnit( use_units_rate_bits?"Tbit":"TB" )};
     
     for (int i = 0; i <= unitsStopAt; i++) {
       units[i] 		= units[i];
@@ -255,6 +260,8 @@ DisplayFormatters
 	private static String	ManagerItem_queued;
 	private static String	ManagerItem_error;
 	private static String	ManagerItem_forced;
+	private static String	ManagerItem_moving;
+	
 	private static String	yes;
 	private static String	no;
 	
@@ -280,6 +287,7 @@ DisplayFormatters
 		ManagerItem_queued				= getResourceString( "ManagerItem.queued", "queued" );
 		ManagerItem_error				= getResourceString( "ManagerItem.error", "error" );
 		ManagerItem_forced				= getResourceString( "ManagerItem.forced", "forced" );
+		ManagerItem_moving				= getResourceString( "ManagerItem.moving", "moving" );
 		yes								= getResourceString( "GeneralView.yes", "Yes" );
 		no								= getResourceString( "GeneralView.no", "No" );
 	}
@@ -487,6 +495,10 @@ DisplayFormatters
 	formatByteCountToBase10KBEtc(
 			long n) 
 	{
+		if ( use_units_rate_bits ){
+			n *= 8;
+		}
+		
 		if (n < 1000){
 			
 			return n + units_base10[UNIT_B];
@@ -530,42 +542,18 @@ DisplayFormatters
 
     /**
      * Print the BITS/second in an international format.
-     * @param n -
+     * @param n - always formatted using SI (i.e. decimal) prefixes
      * @return String in an internationalized format.
      */
     public static String
     formatByteCountToBitsPerSec(
-            long n)
-    {
-        return formatBitCountToKiBEtcLocalImpl(n,true,true,-1,true);
-    }
-
-    /**
-     * NOTE: This method is a copy of formatByteCountToKiBEtc. Since the "use_units_rate_bits" member is
-     * static it cannot be used in a local context. Thus this method. More refactoring of this area
-     * should be done. Also need testing of the method to make sure units are accurate.
-     *
-     * Takes a long value that is bytes/bits download and converts it into internationalized units.
-     * @param n - value
-     * @param rate - true if in ? per second. Otherwise false.
-     * @param bTruncateZeros - true if truncating zeros.
-     * @param precision - negative value if same as units.
-     * @param useBits - true if using BITS, otherwise using BYTES.
-     * @return String - with units internationalized properly.
-     */
-    public static
-    String formatBitCountToKiBEtcLocalImpl(
-        long	n,
-        boolean	rate,
-        boolean bTruncateZeros,
-        int precision,
-        boolean useBits)
+        long n)
     {
-        double dbl = (rate && useBits) ? n * 8 : n;
+        double dbl = n * 8;
 
         int unitIndex = UNIT_B;
 
-        long	div = force_si_values?1024:(use_si_units?1024:1000);
+        long	div = 1000;
         
         while (dbl >= div && unitIndex < unitsStopAt){
 
@@ -573,24 +561,78 @@ DisplayFormatters
           unitIndex++;
         }
 
-      if (precision < 0) {
-          precision = UNITS_PRECISION[unitIndex];
-      }
+        int  precision = UNITS_PRECISION[unitIndex];
 
-        return formatDecimal(dbl, precision, bTruncateZeros, rate)
-                + units_bits[unitIndex] + (rate?per_sec:"");
+        return( formatDecimal(dbl, precision, true, true) + units_bits[unitIndex] + per_sec );
     }
 
+    public static String
+    formatETA(long eta) 
+    {
+    	return( formatETA( eta, false ));
+    }
 
-   public static String
-   formatETA(long eta) 
-   {
-     if (eta == 0) return PeerManager_status_finished;
-     if (eta == -1) return "";
-     if (eta > 0) return TimeFormatter.format(eta);
-
-     return PeerManager_status_finishedin + " " + TimeFormatter.format(eta * -1);
-   }
+    private static final SimpleDateFormat abs_df = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
+    
+    public static String
+    formatETA(long eta,boolean abs ) 
+    {
+    	if (eta == 0) return PeerManager_status_finished;
+    	if (eta == -1) return "";
+    	if (eta > 0){
+    		if ( abs && !(eta == Constants.CRAPPY_INFINITY_AS_INT || eta >= Constants.CRAPPY_INFINITE_AS_LONG )){
+    		
+    			long now 	= SystemTime.getCurrentTime();
+    			long then 	= now + eta*1000;
+    			
+    			if ( eta > 5*60 ){
+    				
+    				then = (then/(60*1000))*(60*1000);
+    			}
+    			
+      			String	str1 = abs_df.format(new Date( now ));
+      			String	str2 = abs_df.format(new Date( then ));
+
+      			int	len = Math.min(str1.length(), str2.length())-2;
+      			
+      			int	diff_at = len;
+      			
+      			for ( int i=0; i<len; i++){
+      				
+      				char	c1 = str1.charAt( i );
+      				
+      				if ( c1 != str2.charAt(i)){
+      					
+      					diff_at = i;
+      					
+      					break;
+      				}
+      			}
+      			
+      			String	res;
+      			
+      			if ( diff_at >= 11 ){
+      				
+      				res = str2.substring( 11 );
+      				
+      			}else if ( diff_at >= 5 ){
+      				
+      				res = str2.substring( 5 );
+      				
+      			}else{
+      				
+      				res = str2;
+      			}
+      			
+      			return( res  );
+      			
+    		}else{
+    			return TimeFormatter.format(eta);
+    		}
+    	}
+
+    	return PeerManager_status_finishedin + " " + TimeFormatter.format(eta * -1);
+    }
 
 
 	public static String
@@ -655,24 +697,36 @@ DisplayFormatters
 
 				DiskManager diskManager = manager.getDiskManager();
 
-				if ((diskManager != null)
-						&& diskManager.getCompleteRecheckStatus() != -1) {
-
-					int done = diskManager.getCompleteRecheckStatus();
-
-					if (done == -1) {
-						done = 1000;
+				if ( diskManager != null ){
+						
+					int	mp = diskManager.getMoveProgress();
+					
+					if ( mp != -1 ){
+						
+						tmp = ManagerItem_moving + ": "	+ formatPercentFromThousands( mp );
+						
+					}else{
+						int done = diskManager.getCompleteRecheckStatus();
+	
+						if ( done != -1 ){
+	
+							tmp = ManagerItem_seeding + " + " + ManagerItem_checking + ": "	+ formatPercentFromThousands(done);
+						}
 					}
-
-					tmp = ManagerItem_seeding + " + " + ManagerItem_checking + ": "
-							+ formatPercentFromThousands(done);
-
-				} else if (manager.getPeerManager() != null
-						&& manager.getPeerManager().isSuperSeedMode()) {
-					tmp = ManagerItem_superseeding;
-				} else {
-					tmp = ManagerItem_seeding;
 				}
+				
+				if ( tmp == "" ){
+					
+					if (manager.getPeerManager() != null && manager.getPeerManager().isSuperSeedMode()) {
+					
+						tmp = ManagerItem_superseeding;
+						
+					}else{
+						
+						tmp = ManagerItem_seeding;
+					}
+				}
+				
 				break;
 			}
 			case DownloadManager.STATE_STOPPED:
diff --git a/org/gudy/azureus2/core3/util/FileUtil.java b/org/gudy/azureus2/core3/util/FileUtil.java
index bdbe10d..522c49c 100644
--- a/org/gudy/azureus2/core3/util/FileUtil.java
+++ b/org/gudy/azureus2/core3/util/FileUtil.java
@@ -27,6 +27,7 @@ import java.lang.reflect.Method;
 import java.net.SocketTimeoutException;
 import java.net.URI;
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -39,6 +40,7 @@ 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.pluginsimpl.local.PluginInitializer;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
@@ -493,7 +495,7 @@ public class FileUtil {
 					  
 					  tempOS.getFD().sync();
 				  }
-				  
+					  
 				  baos.close();
 				  baos = null;
 
@@ -511,15 +513,24 @@ public class FileUtil {
 						  }
 					  }
 					  
+					  if (file.exists()) {
+					  	Debug.out(file + " still exists after delete attempt");
+					  }
+					  
 					  if ( temp.renameTo( file )){
 						  
 						  return( true );
 						  
-					  }else{
-						  
-						 Debug.out( "Save of '" + file_name + "' fails - couldn't rename " + temp.getAbsolutePath() + " to " + file.getAbsolutePath());
+					  }
 
+					  // rename failed, sleep a little and try again
+					  Thread.sleep(50);
+					  if ( temp.renameTo( file )){
+					  	//System.err.println("2nd attempt of rename succeeded for " + temp.getAbsolutePath() + " to " + file.getAbsolutePath());
+					  	return true;
 					  }
+
+				  	Debug.out( "Save of '" + file_name + "' fails - couldn't rename " + temp.getAbsolutePath() + " to " + file.getAbsolutePath());
 				  }
 					  
 				  return( false );
@@ -1293,7 +1304,7 @@ public class FileUtil {
 	
 	        		File jar_file = FileUtil.getJarFileFromURL(url_str);
 	        		
-	        		if ( jar_file.exists()){
+	        		if ( jar_file != null && jar_file.exists()){
 	        			
 	        			return( jar_file );
 	        		}
@@ -1337,7 +1348,21 @@ public class FileUtil {
         		
         			//        System.out.println("jarName: " + jarName);
         		
-        		URI uri = URI.create(jarName);
+        		URI uri;
+        		
+        		try{
+        			uri = URI.create(jarName);
+        			
+        			if ( !new File(uri).exists()){
+        				
+        				throw( new FileNotFoundException());
+        			}
+        		}catch( Throwable e ){
+
+        			jarName = "file:/" + UrlUtils.encode( jarName.substring( 6 ));
+        		
+        			uri = URI.create(jarName);
+        		}
         		
         		File jar = new File(uri);
         		
@@ -1578,7 +1603,21 @@ public class FileUtil {
     	}
     }
     
-    
+    public static boolean
+    writeStringAsFile(
+    	File		file,
+    	String		text )
+    {
+    	try{
+    		return( writeBytesAsFile2( file.getAbsolutePath(), text.getBytes( "UTF-8" )));
+    		
+    	}catch( Throwable e ){
+    		
+    		Debug.out( e );
+    		
+    		return( false );
+    	}
+    }
     
     public static void 
     writeBytesAsFile( 
@@ -1605,10 +1644,14 @@ public class FileUtil {
     		
     		FileOutputStream out = new FileOutputStream( file );
 
-    		out.write( file_data );
+    		try{
+    			out.write( file_data );
 
-    		out.close();
-    		
+     		}finally{
+     			
+       			out.close();
+    		}
+     		
     		return( true );
     		
     	}catch( Throwable t ){
@@ -1860,6 +1903,16 @@ public class FileUtil {
 	public static byte[]
 	readInputStreamAsByteArray(
 		InputStream		is )
+	   	
+	   	throws IOException
+	{
+		return( readInputStreamAsByteArray( is, Integer.MAX_VALUE ));
+	}
+	
+	public static byte[]
+	readInputStreamAsByteArray(
+		InputStream		is,
+		int				size_limit )
 	
 		throws IOException
 	{
@@ -1877,6 +1930,11 @@ public class FileUtil {
 			}
 			
 			baos.write( buffer, 0, len );
+			
+			if ( baos.size() > size_limit ){
+				
+				throw( new IOException( "size limit exceeded" ));
+			}
 		}
 		
 		return( baos.toByteArray());
@@ -1924,10 +1982,148 @@ public class FileUtil {
 	{
 		try
 		{
-			return ((Long)reflectOnUsableSpace.invoke(f, null)).longValue();
+			return ((Long)reflectOnUsableSpace.invoke(f)).longValue();
 		} catch (Exception e)
 		{
 			return -1;
 		}		
 	}
+	
+	public static boolean
+	canReallyWriteToAppDirectory()
+	{		
+		if ( !FileUtil.getApplicationFile("bogus").getParentFile().canWrite()){
+			
+			return( false );
+		}
+		
+			// handle vista+ madness
+		
+		if ( Constants.isWindowsVistaOrHigher ){
+			
+			try{
+				File write_test = FileUtil.getApplicationFile( "_az_.dll" );
+					
+					// should fail if no perms, but sometimes it's created in
+					// virtualstore (if ran from java(w).exe for example)
+				
+				FileOutputStream fos = new FileOutputStream( write_test );
+				
+				fos.write(32);
+				
+				fos.close();
+
+				write_test.delete();
+
+					// look for a file to try and rename. Unfortunately someone renamed License.txt to GPL.txt and screwed this up in 3020...
+			
+				File rename_test = FileUtil.getApplicationFile( "License.txt" );
+			
+				if ( !rename_test.exists()){
+					
+					rename_test = FileUtil.getApplicationFile( "GPL.txt" );
+				}
+				
+				if ( !rename_test.exists()){
+					
+					File[] files = write_test.getParentFile().listFiles();
+					
+					if ( files != null ){
+						
+						for ( File f: files ){
+							
+							String name = f.getName();
+							
+							if ( name.endsWith( ".txt" ) || name.endsWith( ".log" )){
+								
+								rename_test = f;
+								
+								break;
+							}
+						}
+					}
+				}
+				
+				if ( rename_test.exists()){
+					
+					File target = new File( rename_test.getParentFile(), rename_test.getName() + ".bak" );
+					
+					target.delete();
+					
+					rename_test.renameTo( target );
+
+					if ( rename_test.exists()){
+						
+						return( false );
+					}
+
+					target.renameTo( rename_test );
+					
+				}else{
+					
+					Debug.out( "Failed to find a suitable file for the rename test" );
+					
+						// let's assume we can't to be on the safe side
+					
+					return( false );
+				}
+			}catch ( Throwable e ){
+				
+				return( false );
+			}
+		}
+		
+		return( true );
+	}
+	
+		/**
+		 * Gets the encoding that should be used when writing script files (currently only
+		 * tested for windows as this is where an issue can arise...)
+		 * We also only test based on the user-data directory name to see if an explicit
+		 * encoding switch is requried...
+		 * @return null - use default
+		 */
+	
+	private static boolean 	sce_checked;
+	private static String	script_encoding;
+	
+	public static String
+	getScriptCharsetEncoding()
+	{
+		synchronized( FileUtil.class ){
+		
+			if ( sce_checked ){
+				
+				return( script_encoding );
+			}
+			
+			sce_checked = true;
+			
+			String	file_encoding 	= System.getProperty( "file.encoding", null );
+			String	jvm_encoding	= System.getProperty( "sun.jnu.encoding", null );
+			
+			if ( file_encoding == null || jvm_encoding == null || file_encoding.equals( jvm_encoding )){
+				
+				return( null );
+			}
+			
+			try{
+				
+				String	test_str = SystemProperties.getUserPath();
+								
+				if ( !new String( test_str.getBytes( file_encoding ), file_encoding ).equals( test_str )){
+			
+					if ( new String( test_str.getBytes( jvm_encoding ), jvm_encoding ).equals( test_str )){
+						
+						Debug.out( "Script encoding determined to be " + jvm_encoding + " instead of " + file_encoding );
+						
+						script_encoding = jvm_encoding;
+					}
+				}
+			}catch( Throwable e ){
+			}
+			
+			return( script_encoding );
+		}
+	}
 }
diff --git a/org/gudy/azureus2/core3/util/FrequencyLimitedDispatcher.java b/org/gudy/azureus2/core3/util/FrequencyLimitedDispatcher.java
index b610540..53f8762 100644
--- a/org/gudy/azureus2/core3/util/FrequencyLimitedDispatcher.java
+++ b/org/gudy/azureus2/core3/util/FrequencyLimitedDispatcher.java
@@ -41,9 +41,60 @@ FrequencyLimitedDispatcher
 	}
 	
 	public void
+	setSingleThreaded()
+	{
+		final AERunnable old_target = target;
+		
+		target =
+			new AERunnable()
+			{
+				private boolean	running;
+				private boolean	pending;
+				
+				public void
+				runSupport()
+				{
+					synchronized( this ){
+						
+						if ( running ){
+							
+							pending = true;
+							
+							return;
+						}
+						
+						running = true;
+					}
+					
+					try{
+						old_target.runSupport();
+						
+					}finally{
+						
+						boolean	was_pending;
+						
+						synchronized( this ){
+							
+							running = false;
+							
+							was_pending = pending;
+							
+							pending = false;
+						}
+						
+						if ( was_pending ){
+							
+							dispatch();
+						}
+					}
+				}
+			};
+	}
+	
+	public void
 	dispatch()
 	{
-		long	now = SystemTime.getCurrentTime();
+		long	now = SystemTime.getMonotonousTime();
 		
 		boolean	run_it	= false;
 		
@@ -72,7 +123,7 @@ FrequencyLimitedDispatcher
 								public void
 								runSupport()
 								{
-									long	now = SystemTime.getCurrentTime();
+									long	now = SystemTime.getMonotonousTime();
 
 									synchronized( FrequencyLimitedDispatcher.this ){
 
diff --git a/org/gudy/azureus2/core3/util/IndentWriter.java b/org/gudy/azureus2/core3/util/IndentWriter.java
index 5746ea2..c748fa2 100644
--- a/org/gudy/azureus2/core3/util/IndentWriter.java
+++ b/org/gudy/azureus2/core3/util/IndentWriter.java
@@ -27,11 +27,14 @@ import java.io.PrintWriter;
 public class 
 IndentWriter 
 {
-	private static final String	INDENT_STRING	= "    ";
+	private static final String	INDENT_STRING		= "    ";
+	private static final String	INDENT_STRING_HTML	= "    ";
 	
 	private PrintWriter		pw;
 	private String			indent	= "";
 	
+	private boolean			html;
+	
 	private boolean			force;
 	
 	public
@@ -42,10 +45,24 @@ IndentWriter
 	}
 	
 	public void
+	setHTML(
+		boolean	_html )
+	{
+		html = _html;
+	}
+	
+	public void
 	println(
 		String	str )
 	{
-		pw.println( indent + str );
+		if ( html ){
+			
+			pw.print( indent + str + "<br>" );
+
+		}else{
+			
+			pw.println( indent + str );
+		}
 		
 		if ( force ){
 			
@@ -56,7 +73,7 @@ IndentWriter
 	public void
 	indent()
 	{
-		indent += INDENT_STRING;
+		indent += html?INDENT_STRING_HTML:INDENT_STRING;
 	}
 	
 	public void
@@ -64,10 +81,16 @@ IndentWriter
 	{
 		if ( indent.length() > 0 ){
 			
-			indent = indent.substring(INDENT_STRING.length());
+			indent = indent.substring((html?INDENT_STRING_HTML:INDENT_STRING).length());
 		}
 	}
 	
+	public String
+	getTab()
+	{
+		return( html?INDENT_STRING_HTML:INDENT_STRING );
+	}
+	
 	public void
 	setForce(
 		boolean	b )
diff --git a/org/gudy/azureus2/core3/util/LightHashMapEx.java b/org/gudy/azureus2/core3/util/LightHashMapEx.java
new file mode 100644
index 0000000..090d5e4
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/LightHashMapEx.java
@@ -0,0 +1,64 @@
+/*
+ * Created on Feb 28, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.core3.util;
+
+import java.util.AbstractMap;
+
+
+
+public class
+LightHashMapEx<S,T> 
+	extends LightHashMap<S,T> implements Cloneable 
+{
+	public static final byte FL_MAP_ORDER_INCORRECT	= 0x01;
+	
+	private byte		flags;
+	
+	public
+	LightHashMapEx(
+		AbstractMap<S,T>	m )
+	{
+		super( m );
+	}
+	
+	public void
+	setFlag(
+		byte		flag,
+		boolean		set )
+	{
+		if ( set ){
+			
+			flags |= flag;
+			
+		}else{
+			
+			flags &= ~flag;
+		}
+	}
+	
+	public boolean
+	getFlag(
+		byte	flag )
+	{
+		return((flags&flag) != 0 );
+	}
+}
diff --git a/org/gudy/azureus2/core3/util/ListenerManager.java b/org/gudy/azureus2/core3/util/ListenerManager.java
index e3ffc15..c7bfeca 100644
--- a/org/gudy/azureus2/core3/util/ListenerManager.java
+++ b/org/gudy/azureus2/core3/util/ListenerManager.java
@@ -109,11 +109,20 @@ ListenerManager<T>
 	addListener(
 		T		listener )
 	{
+		if (listener == null) {
+
+			Debug.out("Trying to add null listener to " + name);
+			return;
+		}
+
 		synchronized( this ){
 			
 			ArrayList<T>	new_listeners	= new ArrayList<T>( listeners );
 			
 			if (new_listeners.contains(listener)) {
+				if ( Constants.IS_CVS_VERSION ){
+					Debug.out( "check this out" );
+				}
 				Logger.log(new LogEvent(LogIDs.CORE, LogEvent.LT_WARNING,
 						"addListener called but listener already added for " + name
 								+ "\n\t" + Debug.getStackTrace(true, false)));
@@ -121,6 +130,9 @@ ListenerManager<T>
 			new_listeners.add( listener );
 			
 			if (new_listeners.size() > 50) {
+				if ( Constants.IS_CVS_VERSION ){
+					Debug.out( "check this out" );
+				}
 				Logger.log(new LogEvent(LogIDs.CORE, LogEvent.LT_WARNING,
 						"addListener: over 50 listeners added for " + name
 								+ "\n\t" + Debug.getStackTrace(true, false)));
diff --git a/org/gudy/azureus2/core3/util/MD5.java b/org/gudy/azureus2/core3/util/MD5.java
deleted file mode 100644
index 85beb26..0000000
--- a/org/gudy/azureus2/core3/util/MD5.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Created on 16 avr. 2004
- * Created by Olivier Chalouhi
- * 
- * 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
- * 
- * Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
- */
-package org.gudy.azureus2.core3.util;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.MessageDigest;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class MD5 {
-  
-  private int h0,h1,h2,h3;
-  private int length;
-  private ByteBuffer finalBuffer;
-  
-  public MD5() {
-    finalBuffer = ByteBuffer.allocate(64);
-    finalBuffer.position(0);
-    finalBuffer.limit(64);
-    
-    reset();
-  }
-  
-  public void transform(ByteBuffer M) {    
-    int x0 , x1 , x2 , x3 ,  x4 , x5 , x6 , x7 , x8 , x9 ,
-    x10, x11, x12, x13, x14, x15;
-    
-    int a,b,c,d;
-    
-    /*
-     * Crazy byte order for MD5 ... took me hours to find out
-     * where the problem was .... words (32 bits) must be read starting
-     * with the least significant byte !
-     */
-    ByteOrder order = M.order();
-    M.order(ByteOrder.LITTLE_ENDIAN);
-    
-    x0 = M.getInt();
-    x1 = M.getInt();
-    x2 = M.getInt();
-    x3 = M.getInt();
-    x4 = M.getInt();
-    x5 = M.getInt();
-    x6 = M.getInt();
-    x7 = M.getInt();
-    x8 = M.getInt();
-    x9 = M.getInt();
-    x10 = M.getInt();
-    x11 = M.getInt();
-    x12 = M.getInt();
-    x13 = M.getInt();
-    x14 = M.getInt();
-    x15 = M.getInt();
-    
-    M.order(order);
-    
-    a = h0 ; b = h1 ; c = h2 ; d = h3 ;
-    
-    
-    a += ((b & c) | ( ~b & d)) + x0 + 0xd76aa478;
-    a = b + ((a << 7) | (a >>> 25));
-    d += ((a & b) | ( ~a & c)) + x1 + 0xe8c7b756;
-    d = a + ((d << 12) | (d >>> 20));
-    c += ((d & a) | ( ~d & b)) + x2 + 0x242070db;
-    c = d + ((c << 17) | (c >>> 15));
-    b += ((c & d) | ( ~c & a)) + x3 + 0xc1bdceee;
-    b = c + ((b << 22) | (b >>> 10));
-    a += ((b & c) | ( ~b & d)) + x4 + 0xf57c0faf;
-    a = b + ((a << 7) | (a >>> 25));
-    d += ((a & b) | ( ~a & c)) + x5 + 0x4787c62a;
-    d = a + ((d << 12) | (d >>> 20));
-    c += ((d & a) | ( ~d & b)) + x6 + 0xa8304613;
-    c = d + ((c << 17) | (c >>> 15));
-    b += ((c & d) | ( ~c & a)) + x7 + 0xfd469501;
-    b = c + ((b << 22) | (b >>> 10));
-    a += ((b & c) | ( ~b & d)) + x8 + 0x698098d8;
-    a = b + ((a << 7) | (a >>> 25));
-    d += ((a & b) | ( ~a & c)) + x9 + 0x8b44f7af;
-    d = a + ((d << 12) | (d >>> 20));
-    c += ((d & a) | ( ~d & b)) + x10 + 0xffff5bb1;
-    c = d + ((c << 17) | (c >>> 15));
-    b += ((c & d) | ( ~c & a)) + x11 + 0x895cd7be;
-    b = c + ((b << 22) | (b >>> 10));
-    a += ((b & c) | ( ~b & d)) + x12 + 0x6b901122;
-    a = b + ((a << 7) | (a >>> 25));
-    d += ((a & b) | ( ~a & c)) + x13 + 0xfd987193;
-    d = a + ((d << 12) | (d >>> 20));
-    c += ((d & a) | ( ~d & b)) + x14 + 0xa679438e;
-    c = d + ((c << 17) | (c >>> 15));
-    b += ((c & d) | ( ~c & a)) + x15 + 0x49b40821;
-    b = c + ((b << 22) | (b >>> 10));
-    
-    a += ((b & d) | (c & ~d)) + x1 + 0xf61e2562;
-    a = b + ((a << 5) | (a >>> 27));
-    d += ((a & c) | (b & ~c)) + x6 + 0xc040b340;
-    d = a + ((d << 9) | (d >>> 23));
-    c += ((d & b) | (a & ~b)) + x11 + 0x265e5a51;
-    c = d + ((c << 14) | (c >>> 18));
-    b += ((c & a) | (d & ~a)) + x0 + 0xe9b6c7aa;
-    b = c + ((b << 20) | (b >>> 12));
-    a += ((b & d) | (c & ~d)) + x5 + 0xd62f105d;
-    a = b + ((a << 5) | (a >>> 27));
-    d += ((a & c) | (b & ~c)) + x10 + 0x2441453;
-    d = a + ((d << 9) | (d >>> 23));
-    c += ((d & b) | (a & ~b)) + x15 + 0xd8a1e681;
-    c = d + ((c << 14) | (c >>> 18));
-    b += ((c & a) | (d & ~a)) + x4 + 0xe7d3fbc8;
-    b = c + ((b << 20) | (b >>> 12));
-    a += ((b & d) | (c & ~d)) + x9 + 0x21e1cde6;
-    a = b + ((a << 5) | (a >>> 27));
-    d += ((a & c) | (b & ~c)) + x14 + 0xc33707d6;
-    d = a + ((d << 9) | (d >>> 23));
-    c += ((d & b) | (a & ~b)) + x3 + 0xf4d50d87;
-    c = d + ((c << 14) | (c >>> 18));
-    b += ((c & a) | (d & ~a)) + x8 + 0x455a14ed;
-    b = c + ((b << 20) | (b >>> 12));
-    a += ((b & d) | (c & ~d)) + x13 + 0xa9e3e905;
-    a = b + ((a << 5) | (a >>> 27));
-    d += ((a & c) | (b & ~c)) + x2 + 0xfcefa3f8;
-    d = a + ((d << 9) | (d >>> 23));
-    c += ((d & b) | (a & ~b)) + x7 + 0x676f02d9;
-    c = d + ((c << 14) | (c >>> 18));
-    b += ((c & a) | (d & ~a)) + x12 + 0x8d2a4c8a;
-    b = c + ((b << 20) | (b >>> 12));
-    a += (b ^ c ^ d) + x5 + 0xfffa3942;
-    a = b + ((a << 4) | (a >>> 28));
-    d += (a ^ b ^ c) + x8 + 0x8771f681;
-    d = a + ((d << 11) | (d >>> 21));
-    c += (d ^ a ^ b) + x11 + 0x6d9d6122;
-    c = d + ((c << 16) | (c >>> 16));
-    b += (c ^ d ^ a) + x14 + 0xfde5380c;
-    b = c + ((b << 23) | (b >>> 9));
-    a += (b ^ c ^ d) + x1 + 0xa4beea44;
-    a = b + ((a << 4) | (a >>> 28));
-    d += (a ^ b ^ c) + x4 + 0x4bdecfa9;
-    d = a + ((d << 11) | (d >>> 21));
-    c += (d ^ a ^ b) + x7 + 0xf6bb4b60;
-    c = d + ((c << 16) | (c >>> 16));
-    b += (c ^ d ^ a) + x10 + 0xbebfbc70;
-    b = c + ((b << 23) | (b >>> 9));
-    a += (b ^ c ^ d) + x13 + 0x289b7ec6;
-    a = b + ((a << 4) | (a >>> 28));
-    d += (a ^ b ^ c) + x0 + 0xeaa127fa;
-    d = a + ((d << 11) | (d >>> 21));
-    c += (d ^ a ^ b) + x3 + 0xd4ef3085;
-    c = d + ((c << 16) | (c >>> 16));
-    b += (c ^ d ^ a) + x6 + 0x4881d05;
-    b = c + ((b << 23) | (b >>> 9));
-    a += (b ^ c ^ d) + x9 + 0xd9d4d039;
-    a = b + ((a << 4) | (a >>> 28));
-    d += (a ^ b ^ c) + x12 + 0xe6db99e5;
-    d = a + ((d << 11) | (d >>> 21));
-    c += (d ^ a ^ b) + x15 + 0x1fa27cf8;
-    c = d + ((c << 16) | (c >>> 16));
-    b += (c ^ d ^ a) + x2 + 0xc4ac5665;
-    b = c + ((b << 23) | (b >>> 9));
-    a += (c ^ (b  | ~d)) + x0 + 0xf4292244;
-    a = b + ((a << 6) | (a >>> 26));
-    d += (b ^ (a  | ~c)) + x7 + 0x432aff97;
-    d = a + ((d << 10) | (d >>> 22));
-    c += (a ^ (d  | ~b)) + x14 + 0xab9423a7;
-    c = d + ((c << 15) | (c >>> 17));
-    b += (d ^ (c  | ~a)) + x5 + 0xfc93a039;
-    b = c + ((b << 21) | (b >>> 11));
-    a += (c ^ (b  | ~d)) + x12 + 0x655b59c3;
-    a = b + ((a << 6) | (a >>> 26));
-    d += (b ^ (a  | ~c)) + x3 + 0x8f0ccc92;
-    d = a + ((d << 10) | (d >>> 22));
-    c += (a ^ (d  | ~b)) + x10 + 0xffeff47d;
-    c = d + ((c << 15) | (c >>> 17));
-    b += (d ^ (c  | ~a)) + x1 + 0x85845dd1;
-    b = c + ((b << 21) | (b >>> 11));
-    a += (c ^ (b  | ~d)) + x8 + 0x6fa87e4f;
-    a = b + ((a << 6) | (a >>> 26));
-    d += (b ^ (a  | ~c)) + x15 + 0xfe2ce6e0;
-    d = a + ((d << 10) | (d >>> 22));
-    c += (a ^ (d  | ~b)) + x6 + 0xa3014314;
-    c = d + ((c << 15) | (c >>> 17));
-    b += (d ^ (c  | ~a)) + x13 + 0x4e0811a1;
-    b = c + ((b << 21) | (b >>> 11));
-    a += (c ^ (b  | ~d)) + x4 + 0xf7537e82;
-    a = b + ((a << 6) | (a >>> 26));
-    d += (b ^ (a  | ~c)) + x11 + 0xbd3af235;
-    d = a + ((d << 10) | (d >>> 22));
-    c += (a ^ (d  | ~b)) + x2 + 0x2ad7d2bb;
-    c = d + ((c << 15) | (c >>> 17));
-    b += (d ^ (c  | ~a)) + x9 + 0xeb86d391;
-    b = c + ((b << 21) | (b >>> 11));
-
-    
-    h0 += a;
-    h1 += b;
-    h2 += c;
-    h3 += d;    
-  }
-  
-  /**
-   * Resets the MD5 to initial state for a new message digest calculation.
-   * Must be called before starting a new hash calculation.
-   */
-  public void reset() {
-    h0 = 0x67452301;
-    h1 = 0xEFCDAB89;
-    h2 = 0x98BADCFE;
-    h3 = 0x10325476;   
-    
-    length = 0;
-    
-    finalBuffer.clear();
-  }
-  
-  private void completeFinalBuffer(ByteBuffer buffer) {
-    if(finalBuffer.position() == 0) 
-      return;
-    
-    while(buffer.remaining() > 0 && finalBuffer.remaining() > 0) {
-      finalBuffer.put(buffer.get());
-    }
-    
-    if(finalBuffer.remaining() == 0) {
-      finalBuffer.position(0);
-      transform(finalBuffer);
-      finalBuffer.position(0);
-    }
-  }
-  
-  
-  /**
-   * Starts or continues a MD5 message digest calculation.
-   * Only the remaining bytes of the given ByteBuffer are used.
-   * @param buffer input data
-   */
-  public void update(ByteBuffer buffer) {
-    length += buffer.remaining();
-    //Save current position to leave given buffer unchanged
-    int position = buffer.position();
-    
-    //Complete the final buffer if needed
-    completeFinalBuffer(buffer);
-    
-    while(buffer.remaining() >= 64) {
-      transform(buffer);
-    }
-    
-    if(buffer.remaining() != 0) {
-      finalBuffer.put(buffer);
-    }
-    
-    buffer.position(position);
-  }
-  
-  
-  /**
-   * Finishes the MD5-1 message digest calculation.
-   * @return 16-byte hash result
-   */
-  public byte[] digest() {
-    byte[] result = new byte[16];
-    
-    finalBuffer.put((byte)0x80);
-    if(finalBuffer.remaining() < 8) {
-      while(finalBuffer.remaining() > 0) {
-        finalBuffer.put((byte)0);
-      }
-      finalBuffer.position(0);
-      transform(finalBuffer);
-      finalBuffer.position(0);
-    }
-    
-    while(finalBuffer.remaining() > 8) {
-      finalBuffer.put((byte)0);
-    }
-    
-    finalBuffer.putLong(length << 3);
-    finalBuffer.position(0);
-    transform(finalBuffer);
-    
-    finalBuffer.position(0);
-    finalBuffer.putInt(h3);
-    finalBuffer.putInt(h2);
-    finalBuffer.putInt(h1);
-    finalBuffer.putInt(h0);    
-    finalBuffer.position(0);
-    
-    for(int i  = 0 ; i < 16 ; i++) {
-     result[15-i] = finalBuffer.get(); 
-    }
-    
-    return result;
-  }
-  
-  
-  /**
-   * Finishes the MD5 message digest calculation, by first performing a final update
-   * from the given input buffer, then completing the calculation as with digest().
-   * @param buffer input data
-   * @return 16-byte hash result
-   */
-  public byte[] digest(ByteBuffer buffer) {
-    update( buffer );
-    return digest();
-  }
-  
-  public static void main(String args[]) throws Exception {
-    MD5 md5Gudy = new MD5();
-    BrokenMd5Hasher md5Jmule = new BrokenMd5Hasher();
-    MessageDigest md5Sun = MessageDigest.getInstance("MD5");
-    
-    ByteBuffer bhashJ = ByteBuffer.allocate(16);
-    
-    
-    System.out.println("Gudy : " + ByteFormatter.nicePrint(md5Gudy.digest()));
-    md5Gudy.reset();
-    md5Jmule.finalDigest(bhashJ);
-    bhashJ.rewind();      
-    byte hashJ[] = bhashJ.array();
-    System.out.println("Jmule: " + ByteFormatter.nicePrint(hashJ));
-    System.out.println("Sun: " + ByteFormatter.nicePrint(md5Sun.digest()));
-    
-    for(int i = 0 ; i < 1 ; i++) {
-      ByteBuffer test = ByteBuffer.allocate(i);
-      while(test.remaining() > 0) {
-        test.put((byte)(Math.random() * 256));
-      }
-      test.rewind();
-      byte hashG[] = md5Gudy.digest(test);
-      md5Gudy.reset();
-      
-      md5Jmule.update(test);      
-      bhashJ.rewind();
-      md5Jmule.finalDigest(bhashJ);
-      bhashJ.rewind();      
-      hashJ = bhashJ.array();
-      test.rewind();
-      
-      md5Sun.update(test.array());
-      byte hashS[] = md5Sun.digest();
-      
-      System.out.println("Gudy : " + ByteFormatter.nicePrint(hashG));
-      System.out.println("Jmule: " + ByteFormatter.nicePrint(hashJ));
-      System.out.println("Sun: " + ByteFormatter.nicePrint(hashS));
-      //boolean same = true;
-
-      //System.out.println(i + " : " + same);      
-    }
-  }
-  
-}
diff --git a/org/gudy/azureus2/core3/util/RARTOCDecoder.java b/org/gudy/azureus2/core3/util/RARTOCDecoder.java
new file mode 100644
index 0000000..5b1c8fa
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/RARTOCDecoder.java
@@ -0,0 +1,462 @@
+/*
+ * Created on Oct 8, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.core3.util;
+
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class 
+RARTOCDecoder 
+{
+	private DataProvider		provider;
+	
+	public 
+	RARTOCDecoder(
+		DataProvider		_provider )
+	{
+		provider	= _provider;
+	}
+	
+	public void
+	analyse(
+		TOCResultHandler		result_handler )
+		
+		throws IOException
+	{
+		try{
+			analyseSupport( result_handler );
+			
+			result_handler.complete();
+			
+		}catch( Throwable e ){
+			
+			IOException ioe;
+			
+			if ( e instanceof IOException ){
+				
+				ioe = (IOException)e ;
+				
+			}else{
+				
+				ioe = new IOException( "Analysis failed: " + Debug.getNestedExceptionMessage( e ));
+			}
+			
+			result_handler.failed( ioe  );
+				
+			throw( ioe );
+		}
+	}
+	
+	private void
+	analyseSupport(
+		TOCResultHandler		result_handler )
+		
+		throws IOException
+	{
+			// http://acritum.com/winrar/rar-format
+		
+		byte[]	 header_buffer = new byte[7];	// marker block always 7 bytes
+		
+		readFully( header_buffer );
+		
+		if ( !new String( header_buffer ).startsWith( "Rar!" )){
+			
+			throw( new IOException( "Not a rar file" ));
+		}
+		
+			// read archive header
+		
+		readFully( header_buffer );
+		
+		int	archive_header_size	= getShort( header_buffer, 5 );
+
+		if ( archive_header_size > 1024 ){
+			
+			throw( new IOException( "Invalid archive header" ));
+		}
+		
+		provider.skip( archive_header_size - 7 );	// skip over archive header 
+				
+		while( true ){
+			
+				// read next 7 bytes of header record
+			
+			int	read = provider.read( header_buffer );
+			
+			if ( read < 7 ){
+				
+					// seen some short archive, just bail
+				
+				break;
+			}
+		
+			int	block_type	= header_buffer[2]&0xff;
+			
+			int	entry_flags	= getShort( header_buffer, 3 );
+			int	header_size	= getShort( header_buffer, 5 );
+
+			//System.out.println( "type=" + Integer.toString( block_type, 16 ) + ", flags: " + Integer.toString( entry_flags, 16 ) + ", hs=" + header_size);
+
+			if ( block_type < 0x70 || block_type > 0x90 ){
+			
+				throw( new IOException( "invalid header, archive corrupted"));
+			}
+			
+				// ignore crc in first 2 bytes
+			
+			if ( block_type == 0x74 ){
+				
+				boolean	password = ( entry_flags & 0x004 ) != 0;
+				
+				/* in theory if this is set then there should be an optional 4 byte ADD_SIZE here but it doesn't work out
+				if ( ( entry_flags & 0x8000 ) != 0 ){
+					
+					provider.skip( 4 );
+				}
+				*/
+				
+				byte[]	buffer = new byte[25];	// read up until potential optional HIGH_PACK entries
+				
+				readFully( buffer );
+				
+				long	comp_size	= getInteger( buffer, 0 );	// pack size
+				long	act_size	= getInteger( buffer, 4 );  // uncompressed size
+				
+					// 1 byte host_os
+					// 4 bytes crc
+					// 4 bytes file time
+					// 1 byte unrar version
+					// 1 byte method 
+					// total = 11
+				
+				int extended_length = 0;
+				
+				if ( ( entry_flags & 0x0100 ) != 0 ){
+					
+						// extended size info available
+					
+					extended_length = 8;
+					
+					byte[]	extended_size_info = new byte[8];
+					
+					readFully( extended_size_info );
+					
+					comp_size |= getInteger( extended_size_info, 0 ) << 32;
+					act_size  |= getInteger( extended_size_info, 4 ) << 32;
+				}
+				
+					// 19 -  4-comp+4-act+11
+				
+				int	name_length = getShort( buffer, 19 );
+				
+				if ( name_length > 32*1024 ){
+					
+					
+					throw( new IOException( "name length too large: " + name_length ));
+				}
+				
+					// 4 byte attr
+				
+				byte[] name = new byte[name_length];
+				
+				readFully( name );
+				
+				String	decoded_name;
+				
+				if ( ( entry_flags & 0x0200 ) != 0 ){
+				
+					int	zero_pos = -1;
+					
+					for (int i=0;i<name.length;i++){
+						
+						if ( name[i] == 0 ){
+					
+							zero_pos = i;
+							
+							break;
+						}
+					}
+					
+					if ( zero_pos == -1 ){
+						
+						decoded_name =  new String( name, "UTF-8" );
+						
+					}else{
+					
+						decoded_name =  decodeName( name, zero_pos + 1 );
+						
+						if ( decoded_name == null ){
+						
+							decoded_name =  new String( name, 0, zero_pos , "UTF-8" );
+						}
+					}
+				}else{
+					
+					decoded_name =  new String( name, "UTF-8" );
+				}
+				
+				if ( ( entry_flags & 0xe0 ) == 0xe0 ){
+					
+						// directory
+					
+				}else{
+				
+					result_handler.entryRead( decoded_name, act_size, password );
+				}
+				
+				provider.skip( header_size - ( 7 + 25 + extended_length + name_length ) + comp_size );
+				
+			}else if ( block_type == 0x7b ){
+				
+					// end of archive
+				
+				break;
+				
+			}else{
+				
+				provider.skip( archive_header_size - 7 );
+				
+				if ( ( entry_flags & 0x8000 ) != 0 ){
+					
+					provider.skip( 4 );
+				}
+			}
+		}
+	}
+	
+	private String
+	decodeName(
+		byte[]		b_data,
+		int			pos )
+	{
+		try{
+			int Flags		= 0;
+			int FlagBits	= 0;
+			
+			byte[]	Name 		= b_data;
+			byte[] 	EncName 	= b_data;
+			int 	EncSize 	= b_data.length;
+			int 	MaxDecSize 	= 4096;
+	
+			int[] NameW = new int[MaxDecSize];
+	
+			int EncPos = pos;
+			int DecPos = 0;
+			
+			byte HighByte = EncName[EncPos++];
+			
+			while ( EncPos<EncSize && DecPos<MaxDecSize ){
+				
+				if ( FlagBits ==0 ){
+					
+					Flags		= EncName[EncPos++];
+					FlagBits	= 8;
+				}
+				
+				switch((Flags>>6)&0x03){
+				
+					case 0:{
+						NameW[DecPos++]=EncName[EncPos++]&0xff;
+						
+						break;
+					}
+					case 1:{
+						NameW[DecPos++]=(EncName[EncPos++]&0xff)+((HighByte<<8)&0xff00);
+						
+						break;
+					}
+					case 2:{
+						NameW[DecPos++]=(EncName[EncPos++]&0xff)+((EncName[EncPos++]<<8)&0xff00);
+											
+						break;
+					}
+					case 3:{
+						int Length = EncName[EncPos++]&0xff;
+						
+						if ((Length & 0x80) != 0){
+							
+							byte Correction = EncName[EncPos++];
+							
+							for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++){
+								
+								NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+((HighByte<<8)&0xff00);
+							}
+						}else{
+							for (Length+=2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++){
+								
+								NameW[DecPos]=Name[DecPos]&0xff;
+							}
+						}
+						
+						break;
+					}
+				}
+				
+				Flags		<<=2;
+				FlagBits	-=2;
+			}
+	
+			byte[] 	temp = new byte[DecPos*2];
+	
+			for (int i=0;i<DecPos;i++){
+				
+				temp[i*2] 	= (byte)(( NameW[i]>>8 ) & 0xff);
+				temp[i*2+1] = (byte)(( NameW[i] ) & 0xff);
+			}
+	
+			return( new String( temp, "UTF-16BE" ));
+			
+		}catch( Throwable e ){
+			
+			Debug.outNoStack( "Failed to decode name: " + ByteFormatter.encodeString( b_data ) + " - " + Debug.getNestedExceptionMessage( e ));
+			
+			return( null );
+		}
+	}
+	private void
+	readFully(
+		byte[]	buffer )
+	
+		throws IOException
+	{
+		if ( provider.read( buffer ) != buffer.length ){
+			
+			throw( new IOException( "unexpected end-of-file" ));
+		}
+	}
+	
+	public interface
+	TOCResultHandler
+	{
+		public void
+		entryRead(
+			String		name,
+			long		size,
+			boolean		password )
+		
+			throws IOException;
+		
+		public void
+		complete();
+		
+		public void
+		failed(
+			IOException error );
+	}
+	
+	public interface
+	DataProvider
+	{
+		public int
+		read(
+			byte[]		buffer )
+		
+			throws IOException;
+		
+		public void
+		skip(
+			long		bytes )
+		
+			throws IOException;
+	}
+	
+	public static void
+	main(
+		String[]	args )
+	{
+		try{
+			final FileInputStream fis = new FileInputStream( "C:\\temp\\mp.part6.rar" );
+			
+			RARTOCDecoder decoder = 
+				new RARTOCDecoder(
+					new DataProvider()
+					{
+						public int
+						read(
+							byte[]		buffer )
+						
+							throws IOException
+						{
+							return( fis.read( buffer ));
+						}
+						
+						public void
+						skip(
+							long		bytes )
+						
+							throws IOException
+						{
+							fis.skip( bytes );
+						}
+					});
+			
+			decoder.analyse(
+				new TOCResultHandler()
+				{
+					public void
+					entryRead(
+						String		name,
+						long		size,
+						boolean		password )
+					{
+						System.out.println( name + ": " + size + (password?" protected":""));
+					}
+					
+					public void
+					complete()
+					{
+						System.out.println( "complete" );
+					}
+					
+					public void
+					failed(
+						IOException error )
+					{
+						System.out.println( "failed: " + Debug.getNestedExceptionMessage( error ));
+					}
+				});
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
+	
+	private static int
+	getShort(
+		byte[]	buffer,
+		int		pos )
+	{
+		return((( buffer[pos+1]  << 8 ) & 0xff00 ) | ( buffer[pos] & 0xff ));
+	}
+	
+	private static long
+	getInteger(
+		byte[]	buffer,
+		int		pos )
+	{
+		return(((( buffer[pos+3]  << 24 ) & 0xff000000 ) |
+				(( buffer[pos+2]  << 16 ) & 0xff0000 ) |
+				(( buffer[pos+1]  << 8 )  & 0xff00 ) | 
+				( buffer[pos] & 0xff )) & 0xffffffffL );
+	}
+}
diff --git a/org/gudy/azureus2/core3/util/RandomUtils.java b/org/gudy/azureus2/core3/util/RandomUtils.java
index 210f6ec..bbebc67 100644
--- a/org/gudy/azureus2/core3/util/RandomUtils.java
+++ b/org/gudy/azureus2/core3/util/RandomUtils.java
@@ -78,18 +78,55 @@ RandomUtils
 	 * NOTE: Will return a valid non-privileged port number >= LISTEN_PORT_MIN and <= LISTEN_PORT_MAX.
 	 * @return random port number
 	 */
+	
 	public static int 
 	generateRandomNetworkListenPort() 
 	{
+		return( generateRandomNetworkListenPort( LISTEN_PORT_MIN, LISTEN_PORT_MAX ));
+	}
+	
+	public static int 
+	generateRandomNetworkListenPort(
+		int		min_port,
+		int		max_port ) 
+	{
+		if ( min_port > max_port ){
+			int temp 	= min_port;
+			min_port	= max_port;
+			max_port	= temp;
+		}
+		
+		if ( max_port > LISTEN_PORT_MAX ){
+			
+			max_port = LISTEN_PORT_MAX;
+		}
+		
+		if ( max_port < 1 ){
+			
+			max_port = 1;
+		}
+		
+		if ( min_port < 1 ){
+			
+			min_port = 1;
+		}
+		
+		if ( min_port > max_port ){
+			
+			min_port = max_port;
+		}
+		
 			// DON'T use NetworkManager methods to get the ports here else startup can hang
 		
 		int	existing_tcp	= COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
 		int existing_udp	= COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
 		int existing_udp2	= COConfigurationManager.getIntParameter( "UDP.NonData.Listen.Port" );
 		
-		while( true ){
-			int min 	= LISTEN_PORT_MIN;
-			int port 	= min + RANDOM.nextInt( LISTEN_PORT_MAX + 1 - min );
+		int port = min_port;
+		
+		for ( int i=0;i<100;i++ ){
+			int min 	= min_port;
+			port 		= min + RANDOM.nextInt( max_port + 1 - min );
 			
 				// skip magnet ports
 			
@@ -103,6 +140,8 @@ RandomUtils
 				return port;
 			}
 		}
+		
+		return( port );
 	}
 
 	/**
diff --git a/org/gudy/azureus2/core3/util/ShellUtilityFinder.java b/org/gudy/azureus2/core3/util/ShellUtilityFinder.java
new file mode 100644
index 0000000..3aaec87
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/ShellUtilityFinder.java
@@ -0,0 +1,30 @@
+package org.gudy.azureus2.core3.util;
+
+import java.io.File;
+
+public class ShellUtilityFinder {
+	
+	
+	public static String getChMod() {
+		return findCommand("chmod");
+	}
+	
+	public static String getNice() {
+		return findCommand("nice");
+	}
+	
+	public static String
+	findCommand(
+	  String name )
+	{
+	  final String[] locations = { "/bin", "/usr/bin" };
+	  for ( String s: locations ){
+	      File f = new File( s, name );
+	      if ( f.exists() && f.canRead()){
+	          return( f.getAbsolutePath());
+	      }
+	  }
+	  return( name );
+	} 
+
+}
diff --git a/org/gudy/azureus2/core3/util/StringInterner.java b/org/gudy/azureus2/core3/util/StringInterner.java
index 5bb2df9..39b7b54 100644
--- a/org/gudy/azureus2/core3/util/StringInterner.java
+++ b/org/gudy/azureus2/core3/util/StringInterner.java
@@ -38,6 +38,8 @@ import com.aelitis.azureus.core.util.HashCodeUtils;
 public class 
 StringInterner
 {
+	public static boolean DISABLE_INTERNING = false;
+	
 	private static final int SCHEDULED_CLEANUP_INTERVAL = 60*1000;
 	
 	private static final boolean TRACE_CLEANUP = false;
@@ -137,6 +139,10 @@ StringInterner
 	 */
 	public static Object internObject(Object toIntern)
 	{
+		if ( DISABLE_INTERNING ){
+			return( toIntern );
+		}
+		
 		if(toIntern == null)
 			return null;
 		
@@ -167,6 +173,10 @@ StringInterner
 
 	public static String intern(String toIntern) {
 		
+		if ( DISABLE_INTERNING ){
+			return( toIntern );
+		}
+		
 		if(toIntern == null)
 			return null;
 		
@@ -188,21 +198,22 @@ StringInterner
 			{
 				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;
+				try{
+					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;
+					}
+				}finally{
+					managedSetLock.readLock().lock();
+					managedSetLock.writeLock().unlock();
 				}
-				managedSetLock.readLock().lock();
-				managedSetLock.writeLock().unlock();
-
 			}
 		} finally {
 			managedSetLock.readLock().unlock();
@@ -221,6 +232,10 @@ StringInterner
 	
 	public static byte[] internBytes(byte[] toIntern) {
 		
+		if ( DISABLE_INTERNING ){
+			return( toIntern );
+		}
+		
 		if(toIntern == null)
 			return null;
 		
@@ -240,18 +255,21 @@ StringInterner
 			{
 				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;
+				try{
+					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;
+					}
+				}finally{
+					managedSetLock.readLock().lock();
+					managedSetLock.writeLock().unlock();
 				}
-				managedSetLock.readLock().lock();
-				managedSetLock.writeLock().unlock();
 			}
 		} finally
 		{
@@ -278,6 +296,10 @@ StringInterner
 	 */
 	public static File internFile(File toIntern) {
 		
+		if ( DISABLE_INTERNING ){
+			return( toIntern );
+		}
+		
 		if(toIntern == null)
 			return null;
 		
@@ -297,18 +319,21 @@ StringInterner
 			{
 				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;
+				try{
+					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;
+					}
+				}finally{
+					managedSetLock.readLock().lock();
+					managedSetLock.writeLock().unlock();
 				}
-				managedSetLock.readLock().lock();
-				managedSetLock.writeLock().unlock();
 			}
 		} finally
 		{
@@ -332,6 +357,10 @@ StringInterner
 	
 	public static URL internURL(URL toIntern) {
 		
+		if ( DISABLE_INTERNING ){
+			return( toIntern );
+		}
+		
 		if(toIntern == null)
 			return null;
 		
@@ -351,19 +380,21 @@ StringInterner
 			{
 				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;
+				try{
+					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;
+					}
+				}finally{
+					managedSetLock.readLock().lock();
+					managedSetLock.writeLock().unlock();
 				}
-				
-				managedSetLock.readLock().lock();
-				managedSetLock.writeLock().unlock();
 			}
 		} finally
 		{
@@ -637,8 +668,15 @@ StringInterner
 			{
 				URL my = getURL();
 				URL other = ((WeakURLEntry) obj).getURL();
+				
+				if ( my == other ){
+					return( true );
+				}
+				if ( my == null || other == null ){
+					return( false );
+				}
 				// use string compare as URL.equals tries to resolve hostnames
-				return my == null ? false : my.toExternalForm().equals(other.toExternalForm());
+				return my.toExternalForm().equals(other.toExternalForm());
 			}
 			return false;
 		}
diff --git a/org/gudy/azureus2/core3/util/SystemProperties.java b/org/gudy/azureus2/core3/util/SystemProperties.java
index 128b9d6..4be64d9 100644
--- a/org/gudy/azureus2/core3/util/SystemProperties.java
+++ b/org/gudy/azureus2/core3/util/SystemProperties.java
@@ -55,12 +55,29 @@ public class SystemProperties {
   private static final 	String WIN_DEFAULT = "Application Data";
   private static final 	String OSX_DEFAULT = "Library" + SEP + "Application Support";
   
+  
+  private static final boolean PORTABLE = System.getProperty( "azureus.portable.root", "" ).length() > 0;
+	
   	private static String user_path;
   	private static String app_path;
   	
 	public static void
 	determineApplicationName()
 	{
+		String explicit_name = System.getProperty( "azureus.app.name", null );
+		
+		if ( explicit_name != null ){
+			
+			explicit_name = explicit_name.trim();
+			
+			if ( explicit_name.length() > 0 ){
+				
+				setApplicationName( explicit_name );
+				
+				return;
+			}
+		}
+		
 			// try and infer the application name. this is only required on OSX as the app name
 			// is a component of the "application path" used to find plugins etc.
 
@@ -178,6 +195,18 @@ public class SystemProperties {
 		return( APPLICATION_ENTRY_POINT );
 	}
 	
+		/**
+		 * This is used by third-party apps that want explicit control over the user-path
+		 * @param _path
+		 */
+	
+	public static void
+	setUserPath(
+		String		_path )
+	{
+		user_path	= _path;
+	}
+	
   /**
    * Returns the full path to the user's home azureus directory.
    * Under unix, this is usually ~/.azureus/
@@ -203,7 +232,7 @@ public class SystemProperties {
 
 		try {
 			if (temp_user_path != null) {
-
+				
 				if (!temp_user_path.endsWith(SEP)) {
 
 					temp_user_path += SEP;
@@ -319,7 +348,7 @@ public class SystemProperties {
 	  }
 	  
 	  String temp_app_path = System.getProperty("azureus.install.path", System.getProperty("user.dir"));
-    
+		
 	  if ( !temp_app_path.endsWith(SEP)){
 		  
 		  temp_app_path += SEP;
@@ -416,6 +445,11 @@ public class SystemProperties {
   }
   
   public static String getDocPath() {
+	  if ( PORTABLE ){
+		 
+		  return( getUserPath());
+	  }
+	  
 		File fDocPath = null;
 		try {
 			PlatformManager platformManager = PlatformManagerFactory.getPlatformManager();
diff --git a/org/gudy/azureus2/core3/util/SystemTime.java b/org/gudy/azureus2/core3/util/SystemTime.java
index e77f19c..d5b360d 100644
--- a/org/gudy/azureus2/core3/util/SystemTime.java
+++ b/org/gudy/azureus2/core3/util/SystemTime.java
@@ -36,6 +36,13 @@ public class SystemTime {
 	// the HPC doesn't jump backward but can jump forward in time
 	private static final boolean		SOD_IT_LETS_USE_HPC = false;//	= Constants.isCVSVersion();
 	
+	private static volatile List		systemTimeConsumers		= new ArrayList();
+	private static volatile List		monotoneTimeConsumers	= new ArrayList();
+	private static volatile List		clock_change_list		= new ArrayList();
+	private static long					hpc_base_time;
+	private static long					hpc_last_time;
+	private static boolean				no_hcp_logged;
+
 	static
 	{
 		try
@@ -64,13 +71,6 @@ public class SystemTime {
 		}
 	}
 
-	private static volatile List		systemTimeConsumers		= new ArrayList();
-	private static volatile List		monotoneTimeConsumers	= new ArrayList();
-	private static volatile List		clock_change_list		= new ArrayList();
-	private static long					hpc_base_time;
-	private static long					hpc_last_time;
-	private static boolean				no_hcp_logged;
-
 	protected interface SystemTimeProvider {
 		public long getTime();
 
diff --git a/org/gudy/azureus2/core3/util/ThreadPool.java b/org/gudy/azureus2/core3/util/ThreadPool.java
index 6fcc9a3..1385ff0 100644
--- a/org/gudy/azureus2/core3/util/ThreadPool.java
+++ b/org/gudy/azureus2/core3/util/ThreadPool.java
@@ -122,7 +122,9 @@ ThreadPool
 	private boolean	queue_when_full;
 	private List	task_queue	= new ArrayList();
 	
-	AESemaphore	thread_sem;
+	private AESemaphore		thread_sem;
+	private int				reserved_target;
+	private int				reserved_actual;
 	
 	private int			thread_priority	= Thread.NORM_PRIORITY;
 	private boolean		warn_when_full;
@@ -435,6 +437,64 @@ ThreadPool
 		return( thread_sem.getValue() == 0 );
 	}
 	
+	public void
+	setMaxThreads(
+		int		max )
+	{
+		if ( max > max_size ){
+			
+			Debug.out( "should support this sometime..." );
+			
+			return;
+		}
+		
+		setReservedThreadCount( max_size - max );
+	}
+	
+	public void
+	setReservedThreadCount(
+		int		res )
+	{
+		synchronized( this ){
+	
+			if ( res < 0 ){
+				
+				res = 0;
+				
+			}else if ( res > max_size ){
+				
+				res = max_size;
+			}
+			
+			int	 diff =  res - reserved_actual;
+			
+			while( diff < 0 ){
+			
+				thread_sem.release();
+				
+				reserved_actual--;
+				
+				diff++;
+			}
+			
+			while( diff > 0 ){
+				
+				if ( thread_sem.reserveIfAvailable()){
+					
+					reserved_actual++;
+			
+					diff--;
+					
+				}else{
+					
+					break;
+				}
+			}
+			
+			reserved_target = res;
+		}
+	}
+	
 	protected void
 	checkTimeouts()
 	{
@@ -507,8 +567,8 @@ ThreadPool
 		if(!busy.contains(toRelease.worker) || toRelease.manualRelease != ThreadPoolTask.RELEASE_MANUAL_ALLOWED)
 			throw new IllegalStateException("task already released or not manually releasable");
 
-		synchronized (this)
-		{
+		synchronized( this ){
+		
 			long elapsed = SystemTime.getCurrentTime() - toRelease.worker.run_start_time;
 			if (elapsed > WARN_TIME && LOG_WARNINGS)
 				DebugLight.out(toRelease.worker.getWorkerName() + ": terminated, elapsed = " + elapsed + ", state = " + toRelease.worker.state);
@@ -523,10 +583,20 @@ ThreadPool
 					busy_pools.remove(this);
 				}
 
-			if(busy.size() == 0)
-				thread_sem.release();
-			else
-				new threadPoolWorker();		
+			if ( busy.size() == 0){
+				
+				if ( reserved_target > reserved_actual ){
+					
+					reserved_actual++;
+					
+				}else{
+					
+					thread_sem.release();
+				}
+			}else{
+				
+				new threadPoolWorker();
+			}
 		}
 
 	}
@@ -680,8 +750,20 @@ ThreadPool
 				DebugLight.printStackTrace(e);
 			} finally
 			{
-				if(autoRelease)
-					thread_sem.release();
+				if ( autoRelease){
+					
+					synchronized (ThreadPool.this){
+						
+						if ( reserved_target > reserved_actual ){
+							
+							reserved_actual++;
+							
+						}else{
+							
+							thread_sem.release();
+						}
+					}
+				}
 				
 				tls.set(null);
 			}
diff --git a/org/gudy/azureus2/core3/util/TimeFormatter.java b/org/gudy/azureus2/core3/util/TimeFormatter.java
index 73ddd6f..86d8ab7 100644
--- a/org/gudy/azureus2/core3/util/TimeFormatter.java
+++ b/org/gudy/azureus2/core3/util/TimeFormatter.java
@@ -56,6 +56,15 @@ public class TimeFormatter {
 		http_date_format.setTimeZone(TimeZone.getTimeZone("GMT"));
 	}
 	
+	private static final SimpleDateFormat cookie_date_format = 
+		new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US );
+
+	static{
+			// see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
+		
+		cookie_date_format.setTimeZone(TimeZone.getTimeZone("GMT"));
+	}
+	
 	/**
 	 * Format time into two time sections, the first chunk trimmed, the second
 	 * with always with 2 digits.  Sections are *d, **h, **m, **s.  Section
@@ -115,7 +124,30 @@ public class TimeFormatter {
 		
 		return( time_secs + "." + twoDigits( hundredths) + TIME_SUFFIXES[0]);
 	}
+	
+	/**
+	 * @param time millis 
+	 */
 
+	public static String formatColonMillis( long time )
+	{
+		if ( time > 0 ){
+			if ( time < 1000 ){
+				time = 1;
+			}else{
+				time = time / 1000;
+			}
+		}
+		
+		String str = formatColon( time );
+		
+		if ( str.startsWith( "00:" )){
+			
+			str = str.substring( 3 );
+		}
+		
+		return( str );
+	}
 	
 	/**
 	 * Format time into "[[# y] # d] 00:00:00" format
@@ -123,6 +155,7 @@ public class TimeFormatter {
 	 * @param time time in seconds
 	 * @return
 	 */
+	
     public static String formatColon(long time)
     {
       if (time == Constants.CRAPPY_INFINITY_AS_INT || time >= Constants.CRAPPY_INFINITE_AS_LONG) return Constants.INFINITY_STRING;
@@ -212,6 +245,16 @@ public class TimeFormatter {
     }
     
     public static String
+    getCookieDate(
+    	long		millis )
+    {
+		synchronized( cookie_date_format ){
+			
+			return( cookie_date_format.format(new Date( millis )));
+		}
+    }
+    
+    public static String
     milliStamp()
     {
     	long nanos = SystemTime.getHighPrecisionCounter();
diff --git a/org/gudy/azureus2/core3/util/TimerEvent.java b/org/gudy/azureus2/core3/util/TimerEvent.java
index 1122db3..54778a6 100644
--- a/org/gudy/azureus2/core3/util/TimerEvent.java
+++ b/org/gudy/azureus2/core3/util/TimerEvent.java
@@ -60,6 +60,16 @@ TimerEvent
 		performer	= _performer;
 		
 		created 	= _created;
+		
+		if ( Constants.IS_CVS_VERSION ){
+			
+				// sanity check - seems we sometimes use 0 to denote 'now'
+			
+			if ( when != 0 && when <= 7*24*60*60*1000 ){
+				
+				Debug.out( "You sure you want to schedule an event in the past? Time should be absolute!" );
+			}
+		}
 	}
 		
 	public void
diff --git a/org/gudy/azureus2/core3/util/TorrentUtils.java b/org/gudy/azureus2/core3/util/TorrentUtils.java
index 4168087..3e8b002 100644
--- a/org/gudy/azureus2/core3/util/TorrentUtils.java
+++ b/org/gudy/azureus2/core3/util/TorrentUtils.java
@@ -29,9 +29,13 @@ package org.gudy.azureus2.core3.util;
 import java.io.*;
 import java.net.*;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.GZIPInputStream;
 
 import com.aelitis.azureus.core.*;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
+import com.aelitis.azureus.core.util.DNSUtils;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
@@ -40,12 +44,66 @@ import org.gudy.azureus2.core3.logging.LogRelation;
 import org.gudy.azureus2.core3.torrent.*;
 import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.download.*;
+import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.ResourceDownloaderFactoryImpl;
 
 
 public class 
 TorrentUtils 
 {
-	public static final int TORRENT_FLAG_LOW_NOISE	= 0x00000001;
+	static{
+		AEDiagnostics.addEvidenceGenerator(
+			new AEDiagnosticsEvidenceGenerator()
+			{
+				public void 
+				generate(
+					IndentWriter writer) 
+				{
+					writer.println( "DNS TXT Records" );
+					
+					try{
+						writer.indent();
+
+						Set<String> names = COConfigurationManager.getDefinedParameters();
+						
+						String prefix = "dns.txts.cache.";
+						
+						for ( String name: names ){
+							
+							if ( name.startsWith( prefix )){
+								
+								try{
+									String tracker = new String( Base32.decode( name.substring( prefix.length())), "UTF-8" );
+
+									String str = "";
+
+									List<byte[]> txts = (List<byte[]>)COConfigurationManager.getListParameter( name, null );
+
+									if ( txts != null ){
+										
+										for ( byte[] txt: txts ){
+											
+											str += (str.length()==0?"":", ") + new String( txt, "UTF-8" );
+										}
+									}
+									
+									writer.println( tracker + " -> [" + str + "]" );
+									
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}
+						}
+					}finally{
+						
+						writer.exdent();
+					}
+				}
+			});
+	}
+	
+	public static final int TORRENT_FLAG_LOW_NOISE			= 0x00000001;
+	public static final int TORRENT_FLAG_METADATA_TORRENT	= 0x00000002;
 	
 	private static final String		TORRENT_AZ_PROP_DHT_BACKUP_ENABLE		= "dht_backup_enable";
 	private static final String		TORRENT_AZ_PROP_DHT_BACKUP_REQUESTED	= "dht_backup_requested";
@@ -55,6 +113,8 @@ TorrentUtils
 	public static final String		TORRENT_AZ_PROP_OBTAINED_FROM			= "obtained_from";
 	public static final String		TORRENT_AZ_PROP_PEER_CACHE				= "peer_cache";
 	public static final String		TORRENT_AZ_PROP_PEER_CACHE_VALID		= "peer_cache_valid";
+	public static final String		TORRENT_AZ_PROP_INITIAL_LINKAGE			= "initial_linkage";
+	public static final String		TORRENT_AZ_PROP_INITIAL_LINKAGE2		= "initial_linkage2";
 	
 	private static final String		MEM_ONLY_TORRENT_PATH		= "?/\\!:mem_only:!\\/?";
 	
@@ -63,21 +123,46 @@ TorrentUtils
 	private static final List	created_torrents;
 	private static final Set	created_torrents_set;
 	
-	private static ThreadLocal		tls	= 
-		new ThreadLocal()
+	private static ThreadLocal<Map<String,Object>>		tls	= 
+		new ThreadLocal<Map<String,Object>>()
 		{
-			public Object
+			public Map<String,Object>
 			initialValue()
 			{
-				return( new HashMap());
+				return( new HashMap<String,Object>());
 			}
 		};
 		
-	private static volatile Set		ignore_set;
+	private static volatile Set<String>		ignore_set;
 	
 	private static boolean bSaveTorrentBackup;
 	
-	private static CopyOnWriteList	torrent_attribute_listeners = new CopyOnWriteList();
+	private static CopyOnWriteList<torrentAttributeListener>			torrent_attribute_listeners 	= new CopyOnWriteList<torrentAttributeListener>();
+	private static CopyOnWriteList<TorrentAnnounceURLChangeListener>	torrent_url_changed_listeners 	= new CopyOnWriteList<TorrentAnnounceURLChangeListener>();
+	
+	private static AsyncDispatcher	dispatcher = new AsyncDispatcher();
+	
+	private static final boolean			TRACE_DNS = false;
+	private static int						DNS_HISTORY_TIMEOUT	= 4*60*60*1000;
+	
+	private static Map<String,DNSTXTEntry>	dns_mapping = new HashMap<String, DNSTXTEntry>();
+	private static volatile int				dns_mapping_seq_count;
+	private static ThreadPool				dns_threads	= new ThreadPool( "DNS:lookups", 16, true );
+
+	static{
+		SimpleTimer.addPeriodicEvent(
+			"TU:dnstimer",
+			DNS_HISTORY_TIMEOUT/2,
+			new TimerEventPerformer()
+			{
+				public void 
+				perform(
+					TimerEvent event )
+				{
+					checkDNSTimeouts();
+				}
+			});
+	}
 	
 	static {
 		COConfigurationManager.addAndFireParameterListener("Save Torrent Backup",
@@ -164,7 +249,7 @@ TorrentUtils
 	    	
 		}catch (TOTorrentException e){
       
-			Debug.outNoStack( e.getMessage() );
+			// Debug.outNoStack( e.getMessage() );
 			
 			File torrentBackup = new File(file.getParent(), file.getName() + ".bak");
 			
@@ -488,6 +573,143 @@ TorrentUtils
 		return( errorDetail );
 	}
 	
+	public static String
+	announceGroupsToText(
+		TOTorrent	torrent )
+	{
+		URL	announce_url = torrent.getAnnounceURL();
+		
+		String announce_url_str = announce_url==null?"":announce_url.toString().trim();
+		
+		TOTorrentAnnounceURLGroup group = torrent.getAnnounceURLGroup();
+		
+		TOTorrentAnnounceURLSet[]	sets = group.getAnnounceURLSets();
+		
+		if ( sets.length == 0 ){
+		
+			return( announce_url_str );
+			
+		}else{
+			
+			StringBuffer	sb = new StringBuffer(1024);
+			
+			boolean	announce_found = false;
+			
+			for (int i=0;i<sets.length;i++){
+											
+				TOTorrentAnnounceURLSet	set = sets[i];
+				
+				URL[]	urls = set.getAnnounceURLs();
+				
+				if ( urls.length > 0 ){
+				
+					for (int j=0;j<urls.length;j++){
+				
+						String	str = urls[j].toString().trim();
+						
+						if ( str.equals( announce_url_str )){
+							
+							announce_found = true;
+						}
+						
+						sb.append( str );
+						sb.append( "\r\n" );
+					}
+					
+					sb.append( "\r\n" );
+				}
+			}
+			
+			String result = sb.toString().trim();
+		
+			if ( !announce_found ){
+				
+				if ( announce_url_str.length() > 0 ){
+					
+					if ( result.length() == 0 ){
+						
+						result = announce_url_str;
+						
+					}else{
+						
+						result = "\r\n\r\n" + announce_url_str;
+					}
+				}
+			}
+			
+			return( result );
+		}
+	}
+
+	public static String
+	announceGroupsToText(
+		List<List<String>>	group )
+	{
+		StringBuffer	sb = new StringBuffer(1024);
+			
+		for ( List<String> urls: group ){
+			
+			if ( sb.length() > 0 ){
+				
+				sb.append( "\r\n" );
+			}
+			
+			for ( String str: urls ){
+				
+				sb.append( str );
+				sb.append( "\r\n" );
+			}
+		}
+		
+		return( sb.toString().trim());
+	}
+	
+	public static List<List<String>>
+	announceTextToGroups(
+		String	text )
+	{
+		List<List<String>>	groups = new ArrayList<List<String>>();
+		
+		String[]	lines = text.split( "\n" );
+		
+		List<String>	current_group = new ArrayList<String>();
+		
+		Set<String>	hits = new HashSet<String>();
+		
+		for( String line: lines ){
+			
+			line = line.trim();
+			
+			if ( line.length() == 0 ){
+				
+				if ( current_group.size() > 0 ){
+					
+					groups.add( current_group );
+					
+					current_group = new ArrayList<String>();
+				}
+			}else{
+				String lc_line = line.toLowerCase();
+				
+				if ( hits.contains( lc_line )){
+					
+					continue;
+				}
+				
+				hits.add( lc_line );
+				
+				current_group.add( line );
+			}
+		}
+		
+		if ( current_group.size() > 0 ){
+			
+			groups.add( current_group );
+		}
+		
+		return( groups );
+	}
+	
 	public static List<List<String>>
 	announceGroupsToList(
 		TOTorrent	torrent )
@@ -878,7 +1100,14 @@ TorrentUtils
 	getLocalisedName(
 		TOTorrent		torrent )
 	{
+		if (torrent == null) {
+			return "";
+		}
 		try{
+			String utf8Name = torrent.getUTF8Name();
+			if (utf8Name != null) {
+				return utf8Name;
+			}
 			
 			LocaleUtilDecoder decoder = LocaleTorrentUtil.getTorrentEncodingIfAvailable( torrent );
 			
@@ -901,13 +1130,13 @@ TorrentUtils
 	setTLSTorrentHash(
 		HashWrapper		hash )
 	{
-		((Map)tls.get()).put( "hash", hash );
+		tls.get().put( "hash", hash );
 	}
 	
 	public static TOTorrent
 	getTLSTorrent()
 	{
-		HashWrapper	hash = (HashWrapper)((Map)tls.get()).get("hash");
+		HashWrapper	hash = (HashWrapper)(tls.get()).get("hash");
 		
 		if ( hash != null ){
 			
@@ -933,13 +1162,13 @@ TorrentUtils
 	setTLSDescription(
 		String		desc )
 	{
-		((Map)tls.get()).put( "desc", desc );
+		tls.get().put( "desc", desc );
 	}
 	
 	public static String
 	getTLSDescription()
 	{
-		return((String)((Map)tls.get()).get( "desc" ));
+		return((String)tls.get().get( "desc" ));
 	}
 	
 		/**
@@ -950,16 +1179,20 @@ TorrentUtils
 	public static Object
 	getTLS()
 	{
-		return( tls.get());
+		return( new HashMap<String,Object>(tls.get()));
 	}
 	
 	public static void
 	setTLS(
 		Object	obj )
 	{
-		Map	m = (Map)obj;
+		Map<String,Object>	m = (Map<String,Object>)obj;
+		
+		Map<String,Object> tls_map = tls.get();
 		
-		((Map)tls.get()).putAll(m);
+		tls_map.clear();
+		
+		tls_map.putAll(m);
 	}
 	
 	public static URL
@@ -976,20 +1209,42 @@ TorrentUtils
 		}
 	}
 	
-	public static void
-	setDecentralised(
+	public static URL
+	getDecentralisedURL(
+		byte[]		hash )
+	{
+		try{
+			return( new URL( "dht://" + ByteFormatter.encodeString( hash ) + ".dht/announce" ));
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( getDecentralisedEmptyURL());
+		}
+	}
+	
+	public static URL
+	getDecentralisedURL(
 		TOTorrent	torrent )
 	{
-	   	try{
-	   		byte[]	hash = torrent.getHash();
-	     		
-	   		torrent.setAnnounceURL( new URL( "dht://" + ByteFormatter.encodeString( hash ) + ".dht/announce" ));
+		try{
+			return( new URL( "dht://" + ByteFormatter.encodeString( torrent.getHash()) + ".dht/announce" ));
 			
 		}catch( Throwable e ){
 			
-			Debug.printStackTrace( e );
+			Debug.out( e );
+			
+			return( getDecentralisedEmptyURL());
 		}
 	}
+
+	public static void
+	setDecentralised(
+		TOTorrent	torrent )
+	{
+   		torrent.setAnnounceURL( getDecentralisedURL( torrent ));
+	}
 		
 	public static boolean
 	isDecentralised(
@@ -1000,7 +1255,7 @@ TorrentUtils
 			return( false );
 		}
 		
-		return( isDecentralised( torrent.getAnnounceURL()));
+		return( torrent.isDecentralised());
 	}
 	
 
@@ -1199,6 +1454,51 @@ TorrentUtils
 		return(( flags.intValue() & flag ) != 0 );
 	}
 	
+	public static Map<Integer,File>
+	getInitialLinkage(
+		TOTorrent		torrent )
+	{
+		Map<Integer,File>	result = new HashMap<Integer, File>();
+		
+		try{
+			Map	pp = torrent.getAdditionalMapProperty( TOTorrent.AZUREUS_PRIVATE_PROPERTIES );
+			
+			if ( pp != null ){
+				
+				Map<String,String> links;
+				
+				byte[]	g_data = (byte[])pp.get( TorrentUtils.TORRENT_AZ_PROP_INITIAL_LINKAGE2 );
+				
+				if ( g_data == null ){
+				
+					links = (Map<String,String>)pp.get( TorrentUtils.TORRENT_AZ_PROP_INITIAL_LINKAGE );
+					
+				}else{
+					
+					links = (Map<String,String>)BDecoder.decode(new BufferedInputStream( new GZIPInputStream( new ByteArrayInputStream( g_data ))));
+
+				}
+				if ( links != null ){//&& TorrentUtils.isCreatedTorrent( torrent )){
+					
+					links = BDecoder.decodeStrings( links );
+					
+					for ( Map.Entry<String,String> entry: links.entrySet()){
+						
+						int		file_index 	= Integer.parseInt( entry.getKey());
+						String	file		= entry.getValue();
+					
+						result.put( file_index, new File( file ));
+					}
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to read linkage map", e );
+		}
+		
+		return( result );
+	}
+	
 	public static void
 	setPluginStringProperty(
 		TOTorrent		torrent,
@@ -1415,19 +1715,19 @@ TorrentUtils
 		}
 	}
 	
-	public static Set
+	public static Set<String>
 	getIgnoreSet()
 	{
 		return(getIgnoreSetSupport(false));
 	}
 	
-	public static synchronized Set
+	public static synchronized Set<String>
 	getIgnoreSetSupport(
 		boolean	force )
 	{
 		if ( ignore_set == null || force ){
 			
-			Set		new_ignore_set	= new HashSet();
+			Set<String>		new_ignore_set	= new HashSet<String>();
 		    
 			String	ignore_list = COConfigurationManager.getStringParameter( "File.Torrent.IgnoreFiles", TOTorrent.DEFAULT_IGNORE_FILES );
 			
@@ -1559,6 +1859,14 @@ TorrentUtils
 		
 		private long			last_pieces_read_time	= SystemTime.getCurrentTime();
 		
+		private URL							url_mod_last_pre;
+		private URL							url_mod_last_post;
+		private int							url_mod_last_seq;
+		
+		private List<URL>					urlg_mod_last_pre;
+		private TOTorrentAnnounceURLGroup	urlg_mod_last_post;
+		private int							urlg_mod_last_seq;
+		
 		protected
 		torrentDelegate(
 			TOTorrent		_delegate,
@@ -1673,8 +1981,106 @@ TorrentUtils
 			return( delegate.isCreated());
 		}
 		
+		public boolean 
+		isDecentralised() 
+		{
+    		URL	url = getAnnounceURLSupport();
+    		
+    		return( TorrentUtils.isDecentralised( url ));
+		}
+		
+	   	public URL
+    	getAnnounceURL()
+    	{
+    		URL	url = getAnnounceURLSupport();
+    		
+    		int	seq = dns_mapping_seq_count;
+    		
+    		if ( 	url == url_mod_last_pre && 
+    				url_mod_last_post != null && 
+    				seq == url_mod_last_seq ){
+    			
+    			// System.out.println( "using old url: " + url + " -> " + url_mod_last_post );
+    			
+    			return( url_mod_last_post );
+    		}
+    		
+      		url_mod_last_post 		= applyDNSMods( url );
+      		url_mod_last_pre		= url;
+    		url_mod_last_seq		= seq;
+    		
+    		return( url_mod_last_post );
+    	}
+    	
+       	public TOTorrentAnnounceURLGroup
+    	getAnnounceURLGroup()
+    	{
+       		TOTorrentAnnounceURLGroup group = getAnnounceURLGroupSupport();
+       	
+       		int	seq = dns_mapping_seq_count;
+       		
+       		if ( seq == urlg_mod_last_seq && urlg_mod_last_pre != null && urlg_mod_last_post != null ){
+       		
+      			TOTorrentAnnounceURLSet[]	sets = group.getAnnounceURLSets();
+ 
+      			Iterator<URL>	it = urlg_mod_last_pre.iterator();
+ 
+      			boolean	match = true;
+      			
+ outer:
+      			for (int i=0;i<sets.length;i++){
+      					
+      				URL[]	urls = sets[i].getAnnounceURLs();
+  
+   					for ( int j=0;j<urls.length;j++){
+      						
+   						if ( !it.hasNext()){
+   							
+   							match = false;
+   							
+   							break outer;
+   						}
+   						
+   						if ( it.next() != urls[j] ){
+   							
+   							match = false;
+   							
+   							break;
+   						}
+      				}
+      			}
+      			
+      			if ( !it.hasNext() && match ){
+      						
+      	    		// System.out.println( "using old urlg: " + group + " -> " + urlg_mod_last_post );
+      	    			
+      	    		return( urlg_mod_last_post );
+      			}
+       		}
+
+       		List<URL>		url_list = new ArrayList<URL>();
+       		
+ 			TOTorrentAnnounceURLSet[]	sets = group.getAnnounceURLSets();
+ 			   		
+  			for (int i=0;i<sets.length;i++){
+  					
+  				URL[]	urls = sets[i].getAnnounceURLs();
+  				
+  				for ( URL u: urls ){
+  					
+  					url_list.add( u );
+  				}
+  			}
+  			
+       		urlg_mod_last_post	= applyDNSMods( getAnnounceURL(), group );
+       		urlg_mod_last_pre	= url_list;
+       		urlg_mod_last_seq	= seq;
+       		
+       		return( urlg_mod_last_post );
+    	}
+       	
 		public URL
-		getAnnounceURL()
+		getAnnounceURLSupport()
 		{
 			return( delegate.getAnnounceURL());
 		}
@@ -1688,7 +2094,7 @@ TorrentUtils
 			
 		
 		public TOTorrentAnnounceURLGroup
-		getAnnounceURLGroup()
+		getAnnounceURLGroupSupport()
 		{
 			return( delegate.getAnnounceURLGroup());
 		}
@@ -2249,6 +2655,20 @@ TorrentUtils
 			}
 		}
 
+	 	public void
+		addListener(
+			TOTorrentListener		l )
+		{
+	 		delegate.addListener( l );
+		}
+
+		public void
+		removeListener(
+			TOTorrentListener		l )
+		{
+	 		delegate.removeListener( l );
+		}
+		
 		public AEMonitor
 		getMonitor()
 		{
@@ -2273,6 +2693,10 @@ TorrentUtils
 				return ((LogRelation)delegate).getQueryableInterfaces();
 			return super.getQueryableInterfaces();
 		}
+
+		public String getUTF8Name() {
+			return delegate.getUTF8Name();
+		}
 	}
 
 	/**
@@ -2532,6 +2956,27 @@ TorrentUtils
 		}
 	}
 		
+	public static TOTorrent
+	download(
+		URL		url )
+	
+		throws IOException
+	{
+		try{
+			byte[] bytes = FileUtil.readInputStreamAsByteArray( new ResourceDownloaderFactoryImpl().create( url ).download(), BDecoder.MAX_BYTE_ARRAY_SIZE );
+			
+			return( TOTorrentFactory.deserialiseFromBEncodedByteArray( bytes ));
+			
+		}catch( IOException e ){
+			
+			throw((IOException)e);
+			
+		}catch( Throwable e ){
+			
+			throw( new IOException( Debug.getNestedExceptionMessage( e )));
+		}
+	}
+	
 	private static void
 	fireAttributeListener(
 		TOTorrent		torrent,	
@@ -2566,13 +3011,710 @@ TorrentUtils
 		torrent_attribute_listeners.remove( listener );
 	}
 	
-	public interface
-	torrentAttributeListener
+	public static void
+	addTorrentURLChangeListener(
+		TorrentAnnounceURLChangeListener	listener )
 	{
-		public void
-		attributeSet(
-			TOTorrent	torrent,
-			String		attribute,
-			Object		value );
+		torrent_url_changed_listeners.add( listener );
+	}
+	
+	public static void
+	removeTorrentURLChangeListener(
+		TorrentAnnounceURLChangeListener	listener )
+	{
+		torrent_url_changed_listeners.remove( listener );
+	}
+	
+	
+	
+	private static final Pattern txt_pattern = Pattern.compile( "(UDP|TCP):([0-9]+)");
+		
+	private static DNSTXTEntry
+	getDNSTXTEntry(
+		URL		url )
+	{
+		if ( isDecentralised( url )){
+			
+			return( null );
+		}
+		
+		String host = url.getHost();
+		
+		String	tracker_network	= AENetworkClassifier.categoriseAddress( host ); 
+
+		if ( tracker_network != AENetworkClassifier.AT_PUBLIC ){
+			
+			return( null );
+		}
+		
+		return( getDNSTXTEntry( host, false, null ));
+	}
+	
+	private static void
+	checkDNSTimeouts()
+	{
+		final List<String>	hosts = new ArrayList<String>();
+		
+		long now = SystemTime.getMonotonousTime();
+		
+		synchronized( dns_mapping ){
+
+			for ( Map.Entry<String,DNSTXTEntry> entry: dns_mapping.entrySet()){
+				
+				DNSTXTEntry txt_entry = entry.getValue();
+				
+				if ( now - txt_entry.getCreateTime() > DNS_HISTORY_TIMEOUT ){
+					
+					hosts.add( entry.getKey());
+				}
+			}
+		}
+		
+		if ( hosts.size() > 0 ){
+			
+			new AEThread2( "DNS:updates" )
+			{
+				public void
+				run()
+				{
+					for ( String host: hosts ){
+						
+						getDNSTXTEntry( host, true, null );
+					}
+				}
+			}.start();
+		}
+	}
+	
+	private static DNSTXTEntry
+	getDNSTXTEntry(
+		final String			host,
+		boolean					force_update,
+		final List<String>		already_got_records )
+	{
+		if ( TRACE_DNS ){
+			System.out.println( "Getting DNS records for " + host + ", force=" + force_update + ", got=" + already_got_records );
+		}
+		
+		DNSTXTEntry		txt_entry;
+		DNSTXTEntry		old_txt_entry;
+		
+		boolean			is_new = false;
+		
+		synchronized( dns_mapping ){
+		
+			old_txt_entry = txt_entry = dns_mapping.get( host );
+				
+			if ( txt_entry != null && SystemTime.getMonotonousTime() - txt_entry.getCreateTime() > DNS_HISTORY_TIMEOUT ){
+				
+				force_update = true;
+			}
+			
+			if ( force_update || txt_entry == null ){
+			
+				txt_entry = new DNSTXTEntry();
+				
+				dns_mapping.put( host, txt_entry );
+				
+				is_new = true;
+			}
+		}
+		
+		if ( is_new ){
+			
+			String _config_key = "";
+			
+			try{
+				_config_key = "dns.txts.cache." + Base32.encode( host.getBytes( "UTF-8" ));
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+
+			final String config_key	= _config_key;
+			
+			if ( TRACE_DNS ){
+				System.out.println( "Updating DNS records for " + host );
+			}
+			
+			try{
+				List<String> txts;
+
+				if ( already_got_records != null ){
+					
+					txts = already_got_records;
+					
+				}else{
+
+					final AESemaphore lookup_sem = new AESemaphore( "DU:ls" );
+					
+					final Object[]	result = { null, null };
+					
+					final DNSTXTEntry	f_txt_entry = txt_entry;
+					
+					dns_threads.run(
+						new AERunnable()
+						{
+							public void
+							runSupport()
+							{
+								try{
+									List<String> txts = DNSUtils.getTXTRecords( host );
+									
+									if ( TRACE_DNS ){
+										System.out.println( "Actual lookup: " + host + " -> " + txts );
+									}
+									
+									synchronized( result ){
+										
+										if ( result[0] == null ){
+											
+											result[1] = txts;
+											
+											return;
+										}
+									}
+									
+										// they gave up waiting
+									
+									try{										
+										List txts_cache = new ArrayList();
+										
+										for ( String str: txts ){
+											
+											txts_cache.add( str.getBytes( "UTF-8" ));
+										}
+										
+										List old_txts_cache = COConfigurationManager.getListParameter( config_key, null );
+
+										boolean	same = false;
+										
+										if ( old_txts_cache != null ){
+											
+											same = old_txts_cache.size() == txts_cache.size();
+											
+											if ( same ){
+												
+												for ( int i=0;i<old_txts_cache.size();i++){
+													
+													if ( !Arrays.equals((byte[])old_txts_cache.get(i),(byte[])txts_cache.get(i))){
+														
+														same = false;
+														
+														break;
+													}
+												}
+											}
+										}
+										
+										if ( !same ){
+											
+											COConfigurationManager.setParameter( config_key, txts_cache );
+										
+											f_txt_entry.getSemaphore().reserve();
+											
+											if ( already_got_records == null ){
+												
+												getDNSTXTEntry( host, true, txts );
+											}
+										}
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+									}
+
+								}finally{
+									
+									lookup_sem.release();
+								}
+							}
+						});
+					
+					List txts_cache = COConfigurationManager.getListParameter( config_key, null );
+
+						// if we have a cache and this isn't a force update and start of day then well just go with the cache
+					
+					if ( old_txt_entry != null || txts_cache == null || force_update ){
+					
+						lookup_sem.reserve( 2500 );
+					}
+					
+					synchronized( result ){
+							
+						result[0] = "";
+							
+						txts = (List<String>)result[1];
+					}
+					
+					try{					
+						if ( txts == null ){
+						
+							txts = new ArrayList<String>();
+							
+							if ( txts_cache == null ){
+								
+								if ( TRACE_DNS ){
+									System.out.println( "    No cache" );
+								}	
+							}else{
+								
+								for ( Object o: txts_cache ){
+									
+									txts.add( new String((byte[])o, "UTF-8" ));
+								}
+								
+								if ( TRACE_DNS ){
+									System.out.println( "    Using cache: " + txts );
+								}
+							}
+						}else{
+							
+							txts_cache = new ArrayList();
+							
+							for ( String str: txts ){
+								
+								txts_cache.add( str.getBytes( "UTF-8" ));
+							}
+							
+							COConfigurationManager.setParameter( config_key, txts_cache );
+						}
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}
+				
+				boolean	found_bt = false;
+							
+				for ( String txt: txts ){
+					
+					if ( txt.startsWith( "BITTORRENT" )){
+						
+						found_bt = true;
+						
+						Matcher matcher = txt_pattern.matcher( txt.substring( 10 ));
+						
+						while( matcher.find()){
+							
+							boolean is_tcp	= matcher.group(1).startsWith( "T" );
+							Integer	port	= Integer.parseInt( matcher.group(2));
+							
+							txt_entry.addPort( is_tcp, port );
+						}
+					}
+				}
+		
+				txt_entry.setHasRecords( found_bt );
+				
+				if ( old_txt_entry == null ){
+					
+					dns_mapping_seq_count++;
+					
+					if ( TRACE_DNS ){
+						System.out.println( "    New DNS override for " + host + ": " + txt_entry.getString());
+					}
+				}else{
+					
+					if ( !old_txt_entry.sameAs( txt_entry )){
+					
+						if ( TRACE_DNS ){
+							System.out.println( "    Updated DNS override for " + host + ": " + txt_entry.getString());
+						}
+						
+						dns_mapping_seq_count++;
+						
+						dispatcher.dispatch(
+							new AERunnable()
+							{
+								public void
+								runSupport()
+								{
+									for ( TorrentAnnounceURLChangeListener l: torrent_url_changed_listeners ){
+										
+										try{
+											l.changed();
+											
+										}catch( Throwable e ){
+											
+											Debug.out(e );
+										}
+									}
+								}
+							});
+					}
+				}
+			}finally{
+				
+				txt_entry.getSemaphore().releaseForever();
+			}
+		}
+				
+		txt_entry.getSemaphore().reserve();
+		
+		return( txt_entry );
+	}
+	
+	private static URL
+	applyDNSMods(
+		URL		url )
+	{
+		DNSTXTEntry txt_entry = getDNSTXTEntry( url );
+		
+		if ( txt_entry != null && txt_entry.hasRecords()){
+			
+			boolean url_is_tcp 	= url.getProtocol().toLowerCase().startsWith( "http" );
+			int		url_port	= url.getPort();
+			
+			if ( url_port == -1 ){
+				
+				url_port = url.getDefaultPort();
+			}
+			
+			List<DNSTXTPortInfo>	ports = txt_entry.getPorts();
+			
+			if ( ports.size() == 0 ){
+				
+				return( UrlUtils.setHost( url, url.getHost() + ".disabled_by_tracker" ));
+				
+			}else{
+			
+				DNSTXTPortInfo	first_port 	= ports.get(0);
+						
+				if ( url_port != first_port.getPort()){
+				
+					url = UrlUtils.setPort( url, first_port.getPort());
+				}
+				
+				if ( url_is_tcp == first_port.isTCP()){
+					
+					return( url );
+					
+				}else{
+				
+					return( UrlUtils.setProtocol( url, first_port.isTCP()?"http":"udp" ));
+				}
+			}
+		}else{
+		
+			return( url );
+		}
+	}
+	
+	private static TOTorrentAnnounceURLGroup
+	applyDNSMods(
+		URL								announce_url,
+		TOTorrentAnnounceURLGroup		group )
+	{
+		Map<String,Object[]>	dns_maps = new HashMap<String, Object[]>();
+
+		DNSTXTEntry announce_txt_entry = getDNSTXTEntry( announce_url );
+
+		if ( announce_txt_entry != null && announce_txt_entry.hasRecords()){
+			
+			dns_maps.put( announce_url.getHost(), new Object[]{ announce_url, announce_txt_entry });
+		}
+		
+		TOTorrentAnnounceURLSet[] sets = group.getAnnounceURLSets();
+		
+		List<TOTorrentAnnounceURLSet>	mod_sets = new ArrayList<TOTorrentAnnounceURLSet>();
+					
+		for ( TOTorrentAnnounceURLSet set: sets ){
+			
+			URL[] urls = set.getAnnounceURLs();
+			
+			List<URL>	mod_urls = new ArrayList<URL>();
+			
+			for ( URL url: urls ){
+				
+				DNSTXTEntry txt_entry = getDNSTXTEntry( url );
+
+				if ( txt_entry == null || !txt_entry.hasRecords()){
+
+					mod_urls.add( url );
+					
+				}else{
+					
+						// remove any affected entries here, we'll add them in if needed later
+					
+					dns_maps.put( url.getHost(), new Object[]{ url, txt_entry });
+				}
+			}
+			
+			if ( mod_urls.size() != urls.length ){
+				
+				if ( mod_urls.size() > 0 ){
+					
+					mod_sets.add( group.createAnnounceURLSet( mod_urls.toArray( new URL[ mod_urls.size()])));
+				}
+			}else{
+				
+				mod_sets.add( set );
+			}
+		}
+		
+		if ( dns_maps.size() > 0 ){
+			
+			for( Map.Entry<String,Object[]> entry: dns_maps.entrySet()){
+				
+				Object[] stuff		= entry.getValue();
+				
+				URL			url = (URL)stuff[0];
+				DNSTXTEntry	dns	= (DNSTXTEntry)stuff[1];
+				
+				List<DNSTXTPortInfo> ports = dns.getPorts();
+				
+				if ( ports.size() > 0 ){
+				
+					List<URL>	urls = new ArrayList<URL>();
+					
+					for ( DNSTXTPortInfo port: ports ){
+					
+						int		url_port 	= url.getPort();
+						boolean url_is_tcp 	= url.getProtocol().toLowerCase().startsWith( "http" );
+
+						if ( url_port != port.getPort()){
+							
+							url = UrlUtils.setPort( url, port.getPort());
+						}
+						
+						if ( url_is_tcp != port.isTCP()){
+						
+							url = UrlUtils.setProtocol( url, port.isTCP()?"http":"udp" );
+						}
+						
+						urls.add( url );
+					}
+					
+					if ( urls.size() > 0 ){
+					
+						mod_sets.add( group.createAnnounceURLSet( urls.toArray( new URL[ urls.size()])));
+					}
+				}
+			}
+			
+			return( new URLGroup( group, mod_sets ));
+			
+		}else{
+			
+			return( group );
+		}
+	}
+	
+	public interface
+	torrentAttributeListener
+	{
+		public void
+		attributeSet(
+			TOTorrent	torrent,
+			String		attribute,
+			Object		value );
+	}
+	
+	public interface
+	TorrentAnnounceURLChangeListener
+	{
+		public void
+		changed();
+	}
+	
+	private static class
+	URLGroup
+		implements TOTorrentAnnounceURLGroup
+	{
+		private TOTorrentAnnounceURLGroup		delegate;
+		private TOTorrentAnnounceURLSet[]		sets;
+		
+		private
+		URLGroup(
+			TOTorrentAnnounceURLGroup		_delegate,
+			List<TOTorrentAnnounceURLSet>	mod_sets )
+		{
+			delegate	= _delegate;
+			
+			sets = mod_sets.toArray( new TOTorrentAnnounceURLSet[mod_sets.size()]);
+		}
+
+		public TOTorrentAnnounceURLSet[]
+       	getAnnounceURLSets()
+		{
+			return( sets );
+		}
+       	
+       	public void
+       	setAnnounceURLSets(
+       		TOTorrentAnnounceURLSet[]	_sets )
+       	{
+       		sets = _sets;
+       		
+       		delegate.setAnnounceURLSets(_sets );
+       	}
+       		
+       	public TOTorrentAnnounceURLSet
+       	createAnnounceURLSet(
+       		URL[]	urls )
+       	{
+       		return( delegate.createAnnounceURLSet( urls ));	
+       	}
+	}
+	
+	private static class
+	DNSTXTEntry
+	{
+		private long					create_time = SystemTime.getMonotonousTime();
+		
+		private AESemaphore				sem = new AESemaphore( "DNSTXTEntry" );
+		
+		private boolean					has_records;
+		private List<DNSTXTPortInfo>	ports = new ArrayList<DNSTXTPortInfo>();
+		
+		private long
+		getCreateTime()
+		{
+			return( create_time );
+		}
+		
+		private AESemaphore
+		getSemaphore()
+		{
+			return( sem );
+		}
+		
+		private void
+		setHasRecords(
+			boolean	has )
+		{
+			has_records = has;
+		}
+		
+		private boolean
+		hasRecords()
+		{
+			return( has_records );
+		}
+		
+		private void
+		addPort(
+			boolean	is_tcp,
+			int		port )
+		{
+			ports.add( new DNSTXTPortInfo( is_tcp, port ));
+		}
+		
+		private List<DNSTXTPortInfo>
+		getPorts()
+		{
+			return( ports );
+		}
+		
+		private boolean
+		sameAs(
+			DNSTXTEntry		other )
+		{
+			if ( has_records != other.has_records ){
+				
+				return( false );
+			}
+			
+			if ( ports.size() != other.ports.size()){
+				
+				return( false );
+			}
+			
+			for ( int i=0;i<ports.size();i++ ){
+				
+				if ( !ports.get(i).sameAs( other.ports.get(i))){
+					
+					return( false );
+				}
+			}
+			
+			return( true );
+		}	
+		
+		private String
+		getString()
+		{
+			if ( has_records ){
+				
+				if ( ports.size() == 0 ){
+					
+					return( "Deny all" );
+					
+				}else{
+				
+					String	res = "";
+					
+					for ( DNSTXTPortInfo port: ports ){
+						
+						res += (res.length()==0?"":", ") + port.getString();
+					}
+					
+					return( "Permit " + res );
+				}
+			}else{
+				
+				return( "No records" );
+			}
+		}
+	}
+	
+	private static class
+	DNSTXTPortInfo
+	{
+		private boolean	is_tcp;
+		private int		port;
+		
+		private
+		DNSTXTPortInfo(
+			boolean	_is_tcp,
+			int		_port )
+		{
+			is_tcp 	= _is_tcp;
+			port	= _port;
+		}
+		
+		private boolean
+		sameAs(
+			DNSTXTPortInfo		other )
+		{
+			return( is_tcp == other.is_tcp && port == other.port );
+		}
+		
+		private boolean
+		isTCP()
+		{
+			return( is_tcp );
+		}
+		
+		private int
+		getPort()
+		{
+			return( port );
+		}
+		
+		private String
+		getString()
+		{
+			return( (is_tcp?"TCP" :"UDP ") + port );
+		}
+	}
+	
+	public static void
+	main(
+		String[]	args )
+	{
+		try{
+			//URL url = new URL( "http://tracker.openbittorrent.com/");
+			URL url = new URL( "http://inferno.demonoid.com:3413/announce");
+			
+			System.out.println( applyDNSMods( url ));
+			
+			Thread.sleep( 1000*1000 );
+			
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
 	}
 }
diff --git a/org/gudy/azureus2/core3/util/UrlUtils.java b/org/gudy/azureus2/core3/util/UrlUtils.java
index 1ae646e..55db5bc 100644
--- a/org/gudy/azureus2/core3/util/UrlUtils.java
+++ b/org/gudy/azureus2/core3/util/UrlUtils.java
@@ -23,14 +23,18 @@ import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.*;
+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.bouncycastle.util.encoders.Base64;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.plugins.torrent.Torrent;
+import org.gudy.azureus2.plugins.torrent.TorrentAnnounceURLList;
+import org.gudy.azureus2.plugins.torrent.TorrentAnnounceURLListSet;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
 import org.gudy.azureus2.plugins.utils.resourceuploader.ResourceUploader;
 
@@ -75,6 +79,83 @@ public class UrlUtils
 		return( "magnet:?xt=urn:btih:" + Base32.encode( hash ));
 	}
 
+	public static String
+	getMagnetURI(
+		String		name,
+		Torrent		torrent )
+	{
+		String	magnet_str = getMagnetURI( torrent.getHash()) + "&dn=" + UrlUtils.encode(name);
+
+		List<String>	tracker_urls = new ArrayList<String>();
+		
+		URL announce_url = torrent.getAnnounceURL();
+		
+		if ( !TorrentUtils.isDecentralised( announce_url )){
+			
+			tracker_urls.add( announce_url.toExternalForm());
+		}
+		
+		TorrentAnnounceURLList list = torrent.getAnnounceURLList();
+		
+		TorrentAnnounceURLListSet[] sets = list.getSets();
+		
+		for ( TorrentAnnounceURLListSet set: sets ){
+			
+			URL[] set_urls = set.getURLs();
+			
+			if ( set_urls.length > 0 ){
+				
+				URL set_url = set_urls[0];
+				
+				if ( !TorrentUtils.isDecentralised( set_url )){
+					
+					String str = set_url.toExternalForm();
+					
+					if ( !tracker_urls.contains( str )){
+					
+						tracker_urls.add( str );
+					}
+				}
+			}
+		}
+		
+		for ( String str: tracker_urls ){
+			
+			magnet_str += "&tr=" + UrlUtils.encode( str );
+		}
+		
+		List<String>	ws_urls = new ArrayList<String>();
+
+		Object obj = torrent.getAdditionalProperty( "url-list" );
+							
+		if ( obj instanceof byte[] ){
+            
+			try{
+				ws_urls.add( new URL( new String((byte[])obj, "UTF-8" )).toExternalForm());
+				
+			}catch( Throwable e ){							
+			}
+		}else if ( obj instanceof List ){
+			
+			List<byte[]> l = (List<byte[]>)obj;
+			
+			for ( byte[] b: l ){
+				
+				try{
+					ws_urls.add( new URL( new String((byte[])b, "UTF-8" )).toExternalForm());
+					
+				}catch( Throwable e ){							
+				}
+			}
+		}
+		
+		for ( String str: ws_urls ){
+			
+			magnet_str += "&ws=" + UrlUtils.encode( str );
+		}	
+		
+		return( magnet_str );
+	}
 		/**
 		 * returns magnet uri if input is base 32 or base 16 encoded sha1 hash, null otherwise
 		 * @param base_hash
@@ -212,6 +293,11 @@ public class UrlUtils
 			return null;
 		}
 
+		if (accept_magnets
+				&& (text.startsWith("bc://") || text.startsWith("bctp://"))) {
+			return parseTextForMagnets(text);
+		}
+
 		// accept raw hash of 40 hex chars
 		if (accept_magnets && text.matches("^[a-fA-F0-9]{40}$")) {
 			// convert from HEX to raw bytes
@@ -246,11 +332,105 @@ public class UrlUtils
 				return "magnet:?xt=urn:btih:" + Base32.encode(infohash);
 			}
 		}
-
+		
 		return null;
 	}
 
-	public static String parseHTMLforURL(String text) {
+	public static String
+	parseTextForMagnets(
+		String		text )
+	{
+		if (text.startsWith("magnet:")) {
+			return text;
+		}
+
+		// accept raw hash of 40 hex chars
+		if (text.matches("^[a-fA-F0-9]{40}$")) {
+			// convert from HEX to raw bytes
+			byte[] infohash = ByteFormatter.decodeString(text.toUpperCase());
+			// convert to BASE32
+			return "magnet:?xt=urn:btih:" + Base32.encode(infohash);
+		}
+
+		// accept raw hash of 32 base-32 chars
+		if (text.matches("^[a-zA-Z2-7]{32}$")) {
+			return "magnet:?xt=urn:btih:" + text;
+		}
+		
+		Pattern pattern;
+		Matcher matcher;
+
+		pattern = Pattern.compile("bc://bt/([a-z0-9=\\+/]+)", Pattern.CASE_INSENSITIVE);
+		matcher = pattern.matcher(text.replaceAll(" ", "+"));
+		if (matcher.find()) {
+			String base64 = matcher.group(1);
+			byte[] decode = Base64.decode(base64);
+			if (decode != null && decode.length > 0) {
+				// Format is AA/<name>/<size>/<hash>/ZZ
+				try {
+					String decodeString = new String(decode, "utf8");
+					pattern = Pattern.compile("AA.*/(.*)/ZZ", Pattern.CASE_INSENSITIVE);
+					matcher = pattern.matcher(decodeString);
+					if (matcher.find()) {
+						String hash = matcher.group(1);
+						String magnet = parseTextForMagnets(hash);
+						if (magnet != null) {
+							pattern = Pattern.compile("AA/(.*)/[0-9]+", Pattern.CASE_INSENSITIVE);
+							matcher = pattern.matcher(decodeString);
+							if (matcher.find()) {
+								String name = matcher.group(1);
+								return magnet + "&dn=" + encode(name);
+							}
+							return magnet;
+						}
+					}
+				} catch (UnsupportedEncodingException e) {
+				}
+			}
+		}
+
+		pattern = Pattern.compile("bctp://task/(.*)", Pattern.CASE_INSENSITIVE);
+		matcher = pattern.matcher(text);
+		if (matcher.find()) {
+			// Format is <name>/<size>/<hash>
+			String decodeString = matcher.group(1);
+			String magnet = parseTextForMagnets(decodeString);
+			if (magnet != null) {
+				pattern = Pattern.compile("(.*)/[0-9]+", Pattern.CASE_INSENSITIVE);
+				matcher = pattern.matcher(decodeString);
+				if (matcher.find()) {
+					String name = matcher.group(1);
+					return magnet + "&dn=" + encode(name);
+				}
+				return magnet;
+			}
+		}
+
+		// accept raw hash of 32 base-32 chars, with garbage around it
+		if (true) {
+			text = "!" + text + "!";
+			pattern = Pattern.compile("[^a-zA-Z2-7][a-zA-Z2-7]{32}[^a-zA-Z2-7]");
+			matcher = pattern.matcher(text);
+			if (matcher.find()) {
+				String hash = text.substring(matcher.start() + 1, matcher.start() + 33);
+				return "magnet:?xt=urn:btih:" + hash;
+			}
+
+			pattern = Pattern.compile("[^a-fA-F0-9][a-fA-F0-9]{40}[^a-fA-F0-9]");
+			matcher = pattern.matcher(text);
+			if (matcher.find()) {
+				String hash = text.substring(matcher.start() + 1, matcher.start() + 41);
+				// convert from HEX to raw bytes
+				byte[] infohash = ByteFormatter.decodeString(hash.toUpperCase());
+				// convert to BASE32
+				return "magnet:?xt=urn:btih:" + Base32.encode(infohash);
+			}
+		}
+		
+		return( null );
+	}
+	
+	private static String parseHTMLforURL(String text) {
 		if (text == null) {
 			return null;
 		}
@@ -289,14 +469,30 @@ public class UrlUtils
 				"magnet%3A//%3Fmooo",
 				"magnet:?xt=urn:btih:" + Base32.encode(infohash),
 				"aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd",
-				"magnet:?dn=OpenOffice.org_2.0.3_Win32Intel_install.exe&xt=urn:sha1:PEMIGLKMNFI4HZ4CCHZNPKZJNMAAORKN&xt=urn:tree:tiger:JMIJVWHCQUX47YYH7O4XIBCORNU2KYKHBBC6DHA&xt=urn:ed2k:1c0804541f34b6583a383bb8f2cec682&xl=96793015&xs=http://mirror.switch.ch/ftp/mirror/OpenOffice/stable/2.0.3/OOo_2.0.3_Win32Intel_install.exe"
+				"magnet:?dn=OpenOffice.org_2.0.3_Win32Intel_install.exe&xt=urn:sha1:PEMIGLKMNFI4HZ4CCHZNPKZJNMAAORKN&xt=urn:tree:tiger:JMIJVWHCQUX47YYH7O4XIBCORNU2KYKHBBC6DHA&xt=urn:ed2k:1c0804541f34b6583a383bb8f2cec682&xl=96793015&xs=http://mirror.switch.ch/ftp/mirror/OpenOffice/stable/2.0.3/OOo_2.0.3_Win32Intel_install.exe",
 				};
 		for (int i = 0; i < test.length; i++) {
-			System.out.println("decode: " + test[i] + " -> " + URLDecoder.decode(test[i]));
+			System.out.println("URLDecoder.decode: " + test[i] + " -> " + URLDecoder.decode(test[i]));
+			System.out.println("decode: " + test[i] + " -> " + decode(test[i]));
 			System.out.println("isURL: " + test[i] + " -> " + isURL(test[i]));
 			System.out.println("parse: " + test[i] + " -> " + parseTextForURL(test[i], true));
 		}
 
+		String[] testEncode = {
+			"a b"
+		};
+		for (int i = 0; i < testEncode.length; i++) {
+			String txt = testEncode[i];
+			try {
+				System.out.println("URLEncoder.encode: " + txt + " -> "
+						+ URLEncoder.encode(txt, "UTF8"));
+			} catch (UnsupportedEncodingException e) {
+			}
+			System.out.println("URLEncoder.encode: " + txt + " -> "
+					+ URLEncoder.encode(txt));
+			System.out.println("encode: " + txt + " -> " + encode(txt));
+		}
+
 	}
 
 	/**
@@ -413,7 +609,8 @@ public class UrlUtils
 	
 	private static String	last_headers = COConfigurationManager.getStringParameter( "metasearch.web.last.headers", null );
 	
-	private static final String default_headers = "SG9zdDogbG9jYWxob3N0OjQ1MTAwClVzZXItQWdlbnQ6IE1vemlsbGEvNS4wIChXaW5kb3dzOyBVOyBXaW5kb3dzIE5UIDUuMTsgZW4tVVM7IHJ2OjEuOC4xLjE0KSBHZWNrby8yMDA4MDQwNCBGaXJlZm94LzIuMC4wLjE0CkFjY2VwdDogdGV4dC94bWwsYXBwbGljYXRpb24veG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCx0ZXh0L2h0bWw7cT0wLjksdGV4dC9wbGFpbjtxPTAuOCxpbWFnZS9wbmcsKi8qO3E9MC41CkFjY2VwdC1MYW5ndWFnZTogZW4tdXMsZW47cT0wLjUKQWNjZXB0LUVuY29kaW5nOiBnemlwLGRlZmxhdGUKQWNjZXB0LUNoYXJzZXQ6IElTTy04ODU5LTEsdXRmLTg7cT0w [...]
+	// private static final String default_headers = "SG9zdDogbG9jYWxob3N0OjQ1MTAwClVzZXItQWdlbnQ6IE1vemlsbGEvNS4wIChXaW5kb3dzOyBVOyBXaW5kb3dzIE5UIDUuMTsgZW4tVVM7IHJ2OjEuOC4xLjE0KSBHZWNrby8yMDA4MDQwNCBGaXJlZm94LzIuMC4wLjE0CkFjY2VwdDogdGV4dC94bWwsYXBwbGljYXRpb24veG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCx0ZXh0L2h0bWw7cT0wLjksdGV4dC9wbGFpbjtxPTAuOCxpbWFnZS9wbmcsKi8qO3E9MC41CkFjY2VwdC1MYW5ndWFnZTogZW4tdXMsZW47cT0wLjUKQWNjZXB0LUVuY29kaW5nOiBnemlwLGRlZmxhdGUKQWNjZXB0LUNoYXJzZXQ6IElTTy04ODU5LTEsdXRmLTg7c [...]
+	private static final String default_headers = "QWNjZXB0OiB0ZXh0L2h0bWwsYXBwbGljYXRpb24veGh0bWwreG1sLGFwcGxpY2F0aW9uL3htbDtxPTAuOSwqLyo7cT0wLjgKQWNjZXB0LUNoYXJzZXQ6IElTTy04ODU5LTEsdXRmLTg7cT0wLjcsKjtxPTAuMwpBY2NlcHQtRW5jb2Rpbmc6IGd6aXAsZGVmbGF0ZQpBY2NlcHQtTGFuZ3VhZ2U6IGVuLVVTLGVuO3E9MC44CkNhY2hlLUNvbnRyb2w6IG1heC1hZ2U9MApDb25uZWN0aW9uOiBrZWVwLWFsaXZlClVzZXItQWdlbnQ6IE1vemlsbGEvNS4wIChXaW5kb3dzIE5UIDYuMTsgV09XNjQpIEFwcGxlV2ViS2l0LzUzNi4xMSAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS8yMC4wLjExMzIu [...]
 
 	public static void
 	setBrowserHeaders(
@@ -735,6 +932,62 @@ public class UrlUtils
 		}
 	}
 	
+	public static URL
+	setProtocol(
+		URL			u,
+		String		protocol )
+	{
+		String str = u.toExternalForm();
+		
+		int pos = str.indexOf( ":" );
+		
+		try{
+			return( new URL( protocol + str.substring( pos )));
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( u );
+		}
+	}
+	
+	public static URL
+	getBaseURL(
+		URL		u )
+	{
+		StringBuffer result = new StringBuffer();
+		result.append(u.getProtocol());
+		result.append(":");
+		String authority=u.getAuthority();
+		if (authority != null && authority.length() > 0) {
+			result.append("//");
+			int pos = authority.indexOf( '@' );
+			if ( pos != -1 ){
+				result.append(authority.substring(0,pos+1));
+				authority = authority.substring(pos+1);
+			}
+			pos = authority.lastIndexOf(':');
+			int	port = u.getPort();
+			if ( port == -1 ){
+				port = u.getDefaultPort();
+			}
+			if ( pos == -1 ){
+				result.append(authority + ":" + port );
+			}else{
+				result.append(authority.substring(0,pos+1) + port );				
+			}
+		}
+
+		try{
+			return( new URL( result.toString()));
+		}catch( Throwable e ){
+			Debug.out(e);
+			return(u);
+		}
+	}
+	
+	
 		/**
 		 * Returns an explicit IPv4 url if the supplied one has both IPv6 and IPv4 addresses
 		 * @param url
@@ -780,7 +1033,7 @@ public class UrlUtils
 	
 	public static long
 	getContentLength(
-		HttpURLConnection	con )
+		URLConnection	con )
 	{
 		long res = con.getContentLength();
 		
diff --git a/org/gudy/azureus2/core3/util/jar/Test.java b/org/gudy/azureus2/core3/util/jar/Test.java
deleted file mode 100644
index 0b50f11..0000000
--- a/org/gudy/azureus2/core3/util/jar/Test.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Created on 07-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 org.gudy.azureus2.core3.util.jar;
-
-/**
- * @author parg
- *
- */
-
-import java.io.*;
-
-import org.gudy.azureus2.core3.security.*;
-import org.gudy.azureus2.core3.util.Debug;
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String[]		args )
-	{
-		try{
-			SESecurityManager.initialise();
-			
-			System.out.println( System.getProperty( "java.home" ));
-			
-			String	alias = "Azureus"; // SESecurityManager.DEFAULT_ALIAS;
-			
-			// SEKeyDetails	kd = SESecurityManager.getKeyDetails( alias );
-			// WUJarSigner signer = new WUJarSigner(alias, (PrivateKey)kd.getKey(), kd.getCertificateChain());
-			
-			AEJarSigner2 signer = 
-				new AEJarSigner2(
-						alias,
-						SESecurityManager.getKeystoreName(),
-						SESecurityManager.getKeystorePassword());
-			
-			FileOutputStream	fos = new FileOutputStream( "c:\\temp\\sj.jar");
-			
-			signer.signJarFile( new File( "c:\\temp\\si.jar"), fos );
-			
-			fos.close();
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-		
-		System.out.println("normal exit");
-	}
-}
diff --git a/org/gudy/azureus2/core3/util/protocol/bc/Handler.java b/org/gudy/azureus2/core3/util/protocol/bc/Handler.java
new file mode 100644
index 0000000..7f5c8fe
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/protocol/bc/Handler.java
@@ -0,0 +1,82 @@
+/*
+ * File    : Handler.java
+ * Created : 19-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 org.gudy.azureus2.core3.util.protocol.bc;
+
+/**
+ * @author parg
+ *
+ */
+
+import java.io.IOException;
+import java.net.*;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.UrlUtils;
+
+public class 
+Handler 
+	extends URLStreamHandler 
+{
+	public URLConnection 
+	openConnection(URL u)
+	{	
+		URL magnet_url;
+		
+		try{
+			String str = UrlUtils.parseTextForMagnets( u.toExternalForm());
+			
+			if ( str == null ){
+				
+				Debug.out( "Failed to transform bc url '" + u + "'" );
+				
+				return( null );
+			}else{
+			
+				magnet_url = new URL( str );
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( "Failed to transform bc url '" + u + "'", e );
+			
+			return( null );
+		}
+		
+			//	System.out.println( "Transformed " + u + " -> " + magnet_url );
+		
+		try{
+			return( magnet_url.openConnection());
+			
+		}catch( MalformedURLException e ){
+			
+			Debug.printStackTrace(e);
+			
+			return( null );
+			
+		}catch( IOException  e ){
+			
+			Debug.printStackTrace(e);
+			
+			return( null );
+		}
+	}
+
+}
diff --git a/org/gudy/azureus2/core3/util/protocol/vuze/Handler.java b/org/gudy/azureus2/core3/util/protocol/vuze/Handler.java
new file mode 100644
index 0000000..bacf6c1
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/protocol/vuze/Handler.java
@@ -0,0 +1,41 @@
+/*
+ * File    : Handler.java
+ * Created : 19-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 org.gudy.azureus2.core3.util.protocol.vuze;
+
+/**
+ * @author parg
+ *
+ */
+
+import java.net.*;
+
+public class 
+Handler 
+	extends URLStreamHandler 
+{
+	public URLConnection 
+	openConnection(URL u)
+	{	
+		return new VuzeURLConnection(u);
+	}
+
+}
diff --git a/org/gudy/azureus2/core3/util/protocol/vuze/VuzeURLConnection.java b/org/gudy/azureus2/core3/util/protocol/vuze/VuzeURLConnection.java
new file mode 100644
index 0000000..138ce62
--- /dev/null
+++ b/org/gudy/azureus2/core3/util/protocol/vuze/VuzeURLConnection.java
@@ -0,0 +1,166 @@
+/*
+ * File    : UDPURLConnection.java
+ * Created : 19-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 org.gudy.azureus2.core3.util.protocol.vuze;
+
+/**
+ * @author parg
+ *
+ */
+
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.*;
+
+import org.gudy.azureus2.core3.util.Constants;
+
+import com.aelitis.azureus.core.vuzefile.VuzeFile;
+import com.aelitis.azureus.core.vuzefile.VuzeFileHandler;
+
+
+class 
+VuzeURLConnection 
+	extends HttpURLConnection 
+{
+	private URL		url;
+	
+	private int		response_code	= HTTP_OK;
+	private String	response_msg	= "OK";
+	
+	private InputStream					input_stream;
+	private Map<String,List<String>> 	headers = new HashMap<String, List<String>>();
+
+	VuzeURLConnection(
+		URL 	u )
+	{
+		super(u);
+		
+		url		= u;
+	}
+
+	public void 
+	connect() 
+		throws IOException 
+	{
+		String str = url.toExternalForm();
+		
+		int	pos = str.indexOf( "=" );
+		
+		str = str.substring( pos+1 );
+		
+		byte[]	bytes = str.getBytes( Constants.BYTE_ENCODING );
+		
+		VuzeFile vf = VuzeFileHandler.getSingleton().loadVuzeFile( bytes );
+		
+		if ( vf == null ){
+			
+			throw( new IOException( "Invalid vuze file" ));
+		}
+		
+		input_stream = new ByteArrayInputStream( bytes );
+	}
+	
+   public Map<String,List<String>> 
+    getHeaderFields() 
+    {
+        return( headers );
+    }
+    
+    public String
+    getHeaderField(
+    	String	name )
+    {
+    	List<String> values = headers.get( name );
+    	
+    	if ( values == null || values.size() == 0 ){
+    		
+    		return( null );
+    	}
+    	
+    	return( values.get( values.size()-1 ));
+    }
+    
+    public void
+    setHeaderField(
+    	String	name,
+    	String	value )
+    {
+       	List<String> values = headers.get( name );
+       	
+       	if ( values == null ){
+       		
+       		values = new ArrayList<String>();
+       		
+       		headers.put( name, values );
+       	}
+
+       	values.add( value );
+    }
+    
+	public InputStream
+	getInputStream()
+	
+		throws IOException
+	{
+		if ( input_stream == null ){
+			
+			connect();
+		}
+		
+		return( input_stream );
+	}
+	
+	public void
+	setResponse(
+		int		_code,
+		String	_msg )
+	{
+		response_code		= _code;
+		response_msg		= _msg;
+	}
+	
+	public int
+	getResponseCode()
+	{
+		return( response_code );
+	}
+	
+	public String
+	getResponseMessage()
+	{
+		return( response_msg );
+	}
+		
+	public boolean
+	usingProxy()
+	{
+		return( false );
+	}
+	
+	public void
+	disconnect()
+	{
+	}
+}
diff --git a/org/gudy/azureus2/core3/util/test/Md5AlgorithmHelper.java b/org/gudy/azureus2/core3/util/test/Md5AlgorithmHelper.java
deleted file mode 100644
index 60a1e01..0000000
--- a/org/gudy/azureus2/core3/util/test/Md5AlgorithmHelper.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * File    : Md5AlgorithmHelper.java
- * Created : 16 avr. 2004
- * By      : Olivier
- * 
- * 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.core3.util.test;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class Md5AlgorithmHelper {
-  
-  public static final int S11 = 7;
-  public static final int S12 = 12;
-  public static final int S13 = 17;
-  public static final int S14 = 22;
-  public static final int S21 = 5;
-  public static final int S22 = 9;
-  public static final int S23 = 14;
-  public static final int S24 = 20;
-  public static final int S31 = 4;
-  public static final int S32 = 11;
-  public static final int S33 = 16;
-  public static final int S34 = 23;
-  public static final int S41 = 6;
-  public static final int S42 = 10;
-  public static final int S43 = 15;
-  public static final int S44 = 21;
-  
-  public static void main(String args[]) {    
-    /* Round 1 */
-    String a = "a";
-    String b = "b";
-    String c = "c";
-    String d = "d";
-    
-    pFF (a, b, c, d, 0, S11, "0xd76aa478"); /* 1 */
-    pFF (d, a, b, c, 1, S12, "0xe8c7b756"); /* 2 */
-    pFF (c, d, a, b, 2, S13, "0x242070db"); /* 3 */
-    pFF (b, c, d, a, 3, S14, "0xc1bdceee"); /* 4 */
-    pFF (a, b, c, d, 4, S11, "0xf57c0faf"); /* 5 */
-    pFF (d, a, b, c, 5, S12, "0x4787c62a"); /* 6 */
-    pFF (c, d, a, b, 6, S13, "0xa8304613"); /* 7 */
-    pFF (b, c, d, a, 7, S14, "0xfd469501"); /* 8 */
-    pFF (a, b, c, d, 8, S11, "0x698098d8"); /* 9 */
-    pFF (d, a, b, c, 9, S12, "0x8b44f7af"); /* 10 */
-    pFF (c, d, a, b, 10, S13,"0xffff5bb1"); /* 11 */
-    pFF (b, c, d, a, 11, S14,"0x895cd7be"); /* 12 */
-    pFF (a, b, c, d, 12, S11,"0x6b901122"); /* 13 */
-    pFF (d, a, b, c, 13, S12,"0xfd987193"); /* 14 */
-    pFF (c, d, a, b, 14, S13,"0xa679438e"); /* 15 */
-    pFF (b, c, d, a, 15, S14,"0x49b40821"); /* 16 */
-
-   /* Round 2 */
-    pGG (a, b, c, d, 1, S21, "0xf61e2562"); /* 17 */
-    pGG (d, a, b, c, 6, S22, "0xc040b340"); /* 18 */
-    pGG (c, d, a, b, 11, S23,"0x265e5a51"); /* 19 */
-    pGG (b, c, d, a, 0, S24, "0xe9b6c7aa"); /* 20 */
-    pGG (a, b, c, d, 5, S21, "0xd62f105d"); /* 21 */
-    pGG (d, a, b, c, 10, S22,"0x02441453"); /* 22 */
-    pGG (c, d, a, b, 15, S23,"0xd8a1e681"); /* 23 */
-    pGG (b, c, d, a, 4, S24, "0xe7d3fbc8"); /* 24 */
-    pGG (a, b, c, d, 9, S21, "0x21e1cde6"); /* 25 */
-    pGG (d, a, b, c, 14, S22,"0xc33707d6"); /* 26 */
-    pGG (c, d, a, b, 3, S23, "0xf4d50d87"); /* 27 */
-    pGG (b, c, d, a, 8, S24, "0x455a14ed"); /* 28 */
-    pGG (a, b, c, d, 13, S21,"0xa9e3e905"); /* 29 */
-    pGG (d, a, b, c, 2, S22, "0xfcefa3f8"); /* 30 */
-    pGG (c, d, a, b, 7, S23, "0x676f02d9"); /* 31 */
-    pGG (b, c, d, a, 12, S24,"0x8d2a4c8a"); /* 32 */
-
-    /* Round 3 */
-    pHH (a, b, c, d, 5, S31, "0xfffa3942"); /* 33 */
-    pHH (d, a, b, c, 8, S32, "0x8771f681"); /* 34 */
-    pHH (c, d, a, b, 11, S33,"0x6d9d6122"); /* 35 */
-    pHH (b, c, d, a, 14, S34,"0xfde5380c"); /* 36 */
-    pHH (a, b, c, d, 1, S31, "0xa4beea44"); /* 37 */
-    pHH (d, a, b, c, 4, S32, "0x4bdecfa9"); /* 38 */
-    pHH (c, d, a, b, 7, S33, "0xf6bb4b60"); /* 39 */
-    pHH (b, c, d, a, 10, S34,"0xbebfbc70"); /* 40 */
-    pHH (a, b, c, d, 13, S31,"0x289b7ec6"); /* 41 */
-    pHH (d, a, b, c, 0, S32, "0xeaa127fa"); /* 42 */
-    pHH (c, d, a, b, 3, S33, "0xd4ef3085"); /* 43 */
-    pHH (b, c, d, a, 6, S34, "0x04881d05"); /* 44 */
-    pHH (a, b, c, d, 9, S31, "0xd9d4d039"); /* 45 */
-    pHH (d, a, b, c, 12, S32,"0xe6db99e5"); /* 46 */
-    pHH (c, d, a, b, 15, S33,"0x1fa27cf8"); /* 47 */
-    pHH (b, c, d, a, 2, S34, "0xc4ac5665"); /* 48 */
-
-    /* Round 4 */
-    pII (a, b, c, d, 0, S41, "0xf4292244"); /* 49 */
-    pII (d, a, b, c, 7, S42, "0x432aff97"); /* 50 */
-    pII (c, d, a, b, 14, S43,"0xab9423a7"); /* 51 */
-    pII (b, c, d, a, 5, S44, "0xfc93a039"); /* 52 */
-    pII (a, b, c, d, 12, S41,"0x655b59c3"); /* 53 */
-    pII (d, a, b, c, 3, S42, "0x8f0ccc92"); /* 54 */
-    pII (c, d, a, b, 10, S43,"0xffeff47d"); /* 55 */
-    pII (b, c, d, a, 1, S44, "0x85845dd1"); /* 56 */
-    pII (a, b, c, d, 8, S41, "0x6fa87e4f"); /* 57 */
-    pII (d, a, b, c, 15, S42,"0xfe2ce6e0"); /* 58 */
-    pII (c, d, a, b, 6, S43, "0xa3014314"); /* 59 */
-    pII (b, c, d, a, 13, S44,"0x4e0811a1"); /* 60 */
-    pII (a, b, c, d, 4, S41, "0xf7537e82"); /* 61 */
-    pII (d, a, b, c, 11, S42,"0xbd3af235"); /* 62 */
-    pII (c, d, a, b, 2, S43, "0x2ad7d2bb"); /* 63 */
-    pII (b, c, d, a, 9, S44, "0xeb86d391"); /* 64 */
-  }
-  
-  public static String F(String x,String y,String z) {
-    return "((" + x + " & " + y + ") | ( ~" + x + " & " + z + "))";
-  }
-  
-  public static String G(String x,String y,String z) {
-    return "((" + x + " & " + z + ") | (" + y + " & ~" + z + "))";
-  }
-  
-  public static String H(String x,String y,String z) {
-    return "(" + x + " ^ " + y +  " ^ " + z + ")";
-  }
-  
-  public static String I(String x,String y,String z) {
-    return "(" + y + " ^ (" + x + "  | ~" + z + "))";
-  }
-  
-  public static String rotateLeft(String x,int n) {
-    return "((" + x + " << " + n + ") | (" + x + " >>> " + (32-n) + "))"; 
-  }
-  
-  public static int T(int i) {
-    return (int) (4294967296.0 * Math.abs(Math.sin(i)));
-  }
-  
-  public static String pFF(String a,String b,String c,String d,int x, int s, String Ti) {
-    String result =  a + " += " + F(b,c,d) + " + x" + x + " + " + Ti + ";";
-    result += "\n";
-    result += a + " = " + b + " + " + rotateLeft(a,s) + ";";
-    System.out.println(result);
-    return result;
-  }
-  
-  public static String pGG(String a,String b,String c,String d,int x, int s, String Ti) {
-    String result =  a + " += " + G(b,c,d) + " + x" + x + " + " + Ti + ";";
-    result += "\n";
-    result += a + " = " + b + " + " + rotateLeft(a,s) + ";";
-    System.out.println(result);
-    return result;
-  }
-  
-  public static String pHH(String a,String b,String c,String d,int x, int s, String Ti) {
-    String result =  a + " += " + H(b,c,d) + " + x" + x + " + " + Ti + ";";
-    result += "\n";
-    result += a + " = " + b + " + " + rotateLeft(a,s) + ";";
-    System.out.println(result);
-    return result;
-  }
-  
-  public static String pII(String a,String b,String c,String d,int x, int s, String Ti) {
-    String result =  a + " += " + I(b,c,d) + " + x" + x + " + " + Ti + ";";
-    result += "\n";
-    result += a + " = " + b + " + " + rotateLeft(a,s) + ";";
-    System.out.println(result);
-    return result;
-  }
-  
-}
diff --git a/org/gudy/azureus2/core3/util/test/SHA1Old.java b/org/gudy/azureus2/core3/util/test/SHA1Old.java
deleted file mode 100644
index 6185a5f..0000000
--- a/org/gudy/azureus2/core3/util/test/SHA1Old.java
+++ /dev/null
@@ -1,475 +0,0 @@
- /*
- * Created on Apr 12, 2004
- * Created by Olivier Chalouhi
- * Modified Apr 13, 2004 by Alon Rohter
- * 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.core3.util.test;
-
-import java.nio.ByteBuffer;
-
-
-/**
- * SHA-1 message digest class.
- */
-public final class SHA1Old {
-
-  private int h0,h1,h2,h3,h4;
-  private ByteBuffer finalBuffer;
-  
-  private ByteBuffer saveBuffer;
-  private int s0,s1,s2,s3,s4;
-  
-  long length;
-  long saveLength;
-  
-  
-  /**
-   * Create a new SHA-1 message digest hasher.
-   */
-  public SHA1Old() {
-    finalBuffer = ByteBuffer.allocate(64);
-    finalBuffer.position(0);
-    finalBuffer.limit(64);
-    
-    saveBuffer = ByteBuffer.allocate(64);
-    saveBuffer.position(0);
-    saveBuffer.limit(64);
-    
-    reset();
-  }
-  
-  
-  private void transform(ByteBuffer M) {
-    int w0 , w1 , w2 , w3 ,  w4 , w5 , w6 , w7 , w8 , w9 ,
-    w10, w11, w12, w13, w14, w15;
-    
-    int a,b,c,d,e;
-    
-    w0 = M.getInt();
-    w1 = M.getInt();
-    w2 = M.getInt();
-    w3 = M.getInt();
-    w4 = M.getInt();
-    w5 = M.getInt();
-    w6 = M.getInt();
-    w7 = M.getInt();
-    w8 = M.getInt();
-    w9 = M.getInt();
-    w10 = M.getInt();
-    w11 = M.getInt();
-    w12 = M.getInt();
-    w13 = M.getInt();
-    w14 = M.getInt();
-    w15 = M.getInt();
-    
-    a = h0 ; b = h1 ; c = h2 ; d = h3 ; e = h4;
-    e += ((a << 5) | ( a >>> 27)) + w0 + ((b & c) | ((~b ) & d)) + 0x5A827999 ;
-    b = (b << 30) | (b >>> 2) ;
-    d += ((e << 5) | ( e >>> 27)) + w1 + ((a & b) | ((~a ) & c)) + 0x5A827999 ;
-    a = (a << 30) | (a >>> 2) ;
-    c += ((d << 5) | ( d >>> 27)) + w2 + ((e & a) | ((~e ) & b)) + 0x5A827999 ;
-    e = (e << 30) | (e >>> 2) ;
-    b += ((c << 5) | ( c >>> 27)) + w3 + ((d & e) | ((~d ) & a)) + 0x5A827999 ;
-    d = (d << 30) | (d >>> 2) ;
-    a += ((b << 5) | ( b >>> 27)) + w4 + ((c & d) | ((~c ) & e)) + 0x5A827999 ;
-    c = (c << 30) | (c >>> 2) ;
-    e += ((a << 5) | ( a >>> 27)) + w5 + ((b & c) | ((~b ) & d)) + 0x5A827999 ;
-    b = (b << 30) | (b >>> 2) ;
-    d += ((e << 5) | ( e >>> 27)) + w6 + ((a & b) | ((~a ) & c)) + 0x5A827999 ;
-    a = (a << 30) | (a >>> 2) ;
-    c += ((d << 5) | ( d >>> 27)) + w7 + ((e & a) | ((~e ) & b)) + 0x5A827999 ;
-    e = (e << 30) | (e >>> 2) ;
-    b += ((c << 5) | ( c >>> 27)) + w8 + ((d & e) | ((~d ) & a)) + 0x5A827999 ;
-    d = (d << 30) | (d >>> 2) ;
-    a += ((b << 5) | ( b >>> 27)) + w9 + ((c & d) | ((~c ) & e)) + 0x5A827999 ;
-    c = (c << 30) | (c >>> 2) ;
-    e += ((a << 5) | ( a >>> 27)) + w10 + ((b & c) | ((~b ) & d)) + 0x5A827999 ;
-    b = (b << 30) | (b >>> 2) ;
-    d += ((e << 5) | ( e >>> 27)) + w11 + ((a & b) | ((~a ) & c)) + 0x5A827999 ;
-    a = (a << 30) | (a >>> 2) ;
-    c += ((d << 5) | ( d >>> 27)) + w12 + ((e & a) | ((~e ) & b)) + 0x5A827999 ;
-    e = (e << 30) | (e >>> 2) ;
-    b += ((c << 5) | ( c >>> 27)) + w13 + ((d & e) | ((~d ) & a)) + 0x5A827999 ;
-    d = (d << 30) | (d >>> 2) ;
-    a += ((b << 5) | ( b >>> 27)) + w14 + ((c & d) | ((~c ) & e)) + 0x5A827999 ;
-    c = (c << 30) | (c >>> 2) ;
-    e += ((a << 5) | ( a >>> 27)) + w15 + ((b & c) | ((~b ) & d)) + 0x5A827999 ;
-    b = (b << 30) | (b >>> 2) ;
-    w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w0 + ((a & b) | ((~a ) & c)) + 0x5A827999 ;
-    a = (a << 30) | (a >>> 2) ;
-    w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w1 + ((e & a) | ((~e ) & b)) + 0x5A827999 ;
-    e = (e << 30) | (e >>> 2) ;
-    w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w2 + ((d & e) | ((~d ) & a)) + 0x5A827999 ;
-    d = (d << 30) | (d >>> 2) ;
-    w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w3 + ((c & d) | ((~c ) & e)) + 0x5A827999 ;
-    c = (c << 30) | (c >>> 2) ;
-    w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w4 + (b ^ c ^ d) + 0x6ED9EBA1 ;
-    b = (b << 30) | (b >>> 2) ;
-    w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w5 + (a ^ b ^ c) + 0x6ED9EBA1 ;
-    a = (a << 30) | (a >>> 2) ;
-    w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w6 + (e ^ a ^ b) + 0x6ED9EBA1 ;
-    e = (e << 30) | (e >>> 2) ;
-    w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w7 + (d ^ e ^ a) + 0x6ED9EBA1 ;
-    d = (d << 30) | (d >>> 2) ;
-    w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w8 + (c ^ d ^ e) + 0x6ED9EBA1 ;
-    c = (c << 30) | (c >>> 2) ;
-    w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w9 + (b ^ c ^ d) + 0x6ED9EBA1 ;
-    b = (b << 30) | (b >>> 2) ;
-    w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w10 + (a ^ b ^ c) + 0x6ED9EBA1 ;
-    a = (a << 30) | (a >>> 2) ;
-    w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w11 + (e ^ a ^ b) + 0x6ED9EBA1 ;
-    e = (e << 30) | (e >>> 2) ;
-    w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w12 + (d ^ e ^ a) + 0x6ED9EBA1 ;
-    d = (d << 30) | (d >>> 2) ;
-    w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w13 + (c ^ d ^ e) + 0x6ED9EBA1 ;
-    c = (c << 30) | (c >>> 2) ;
-    w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w14 + (b ^ c ^ d) + 0x6ED9EBA1 ;
-    b = (b << 30) | (b >>> 2) ;
-    w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w15 + (a ^ b ^ c) + 0x6ED9EBA1 ;
-    a = (a << 30) | (a >>> 2) ;
-    w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w0 + (e ^ a ^ b) + 0x6ED9EBA1 ;
-    e = (e << 30) | (e >>> 2) ;
-    w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w1 + (d ^ e ^ a) + 0x6ED9EBA1 ;
-    d = (d << 30) | (d >>> 2) ;
-    w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w2 + (c ^ d ^ e) + 0x6ED9EBA1 ;
-    c = (c << 30) | (c >>> 2) ;
-    w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w3 + (b ^ c ^ d) + 0x6ED9EBA1 ;
-    b = (b << 30) | (b >>> 2) ;
-    w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w4 + (a ^ b ^ c) + 0x6ED9EBA1 ;
-    a = (a << 30) | (a >>> 2) ;
-    w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w5 + (e ^ a ^ b) + 0x6ED9EBA1 ;
-    e = (e << 30) | (e >>> 2) ;
-    w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w6 + (d ^ e ^ a) + 0x6ED9EBA1 ;
-    d = (d << 30) | (d >>> 2) ;
-    w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w7 + (c ^ d ^ e) + 0x6ED9EBA1 ;
-    c = (c << 30) | (c >>> 2) ;
-    w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w8 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;
-    b = (b << 30) | (b >>> 2) ;
-    w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w9 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ;
-    a = (a << 30) | (a >>> 2) ;
-    w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w10 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ;
-    e = (e << 30) | (e >>> 2) ;
-    w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w11 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ;
-    d = (d << 30) | (d >>> 2) ;
-    w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w12 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ;
-    c = (c << 30) | (c >>> 2) ;
-    w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w13 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;
-    b = (b << 30) | (b >>> 2) ;
-    w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w14 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ;
-    a = (a << 30) | (a >>> 2) ;
-    w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w15 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ;
-    e = (e << 30) | (e >>> 2) ;
-    w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w0 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ;
-    d = (d << 30) | (d >>> 2) ;
-    w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w1 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ;
-    c = (c << 30) | (c >>> 2) ;
-    w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w2 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;
-    b = (b << 30) | (b >>> 2) ;
-    w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w3 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ;
-    a = (a << 30) | (a >>> 2) ;
-    w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w4 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ;
-    e = (e << 30) | (e >>> 2) ;
-    w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w5 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ;
-    d = (d << 30) | (d >>> 2) ;
-    w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w6 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ;
-    c = (c << 30) | (c >>> 2) ;
-    w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w7 + ((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;
-    b = (b << 30) | (b >>> 2) ;
-    w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w8 + ((a & b) | (a & c) | (b & c)) + 0x8F1BBCDC ;
-    a = (a << 30) | (a >>> 2) ;
-    w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w9 + ((e & a) | (e & b) | (a & b)) + 0x8F1BBCDC ;
-    e = (e << 30) | (e >>> 2) ;
-    w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w10 + ((d & e) | (d & a) | (e & a)) + 0x8F1BBCDC ;
-    d = (d << 30) | (d >>> 2) ;
-    w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w11 + ((c & d) | (c & e) | (d & e)) + 0x8F1BBCDC ;
-    c = (c << 30) | (c >>> 2) ;
-    w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w12 + (b ^ c ^ d) + 0xCA62C1D6 ;
-    b = (b << 30) | (b >>> 2) ;
-    w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w13 + (a ^ b ^ c) + 0xCA62C1D6 ;
-    a = (a << 30) | (a >>> 2) ;
-    w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w14 + (e ^ a ^ b) + 0xCA62C1D6 ;
-    e = (e << 30) | (e >>> 2) ;
-    w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w15 + (d ^ e ^ a) + 0xCA62C1D6 ;
-    d = (d << 30) | (d >>> 2) ;
-    w0 = w13 ^ w8 ^ w2 ^ w0; w0 = (w0 << 1) | (w0 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w0 + (c ^ d ^ e) + 0xCA62C1D6 ;
-    c = (c << 30) | (c >>> 2) ;
-    w1 = w14 ^ w9 ^ w3 ^ w1; w1 = (w1 << 1) | (w1 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w1 + (b ^ c ^ d) + 0xCA62C1D6 ;
-    b = (b << 30) | (b >>> 2) ;
-    w2 = w15 ^ w10 ^ w4 ^ w2; w2 = (w2 << 1) | (w2 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w2 + (a ^ b ^ c) + 0xCA62C1D6 ;
-    a = (a << 30) | (a >>> 2) ;
-    w3 = w0 ^ w11 ^ w5 ^ w3; w3 = (w3 << 1) | (w3 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w3 + (e ^ a ^ b) + 0xCA62C1D6 ;
-    e = (e << 30) | (e >>> 2) ;
-    w4 = w1 ^ w12 ^ w6 ^ w4; w4 = (w4 << 1) | (w4 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w4 + (d ^ e ^ a) + 0xCA62C1D6 ;
-    d = (d << 30) | (d >>> 2) ;
-    w5 = w2 ^ w13 ^ w7 ^ w5; w5 = (w5 << 1) | (w5 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w5 + (c ^ d ^ e) + 0xCA62C1D6 ;
-    c = (c << 30) | (c >>> 2) ;
-    w6 = w3 ^ w14 ^ w8 ^ w6; w6 = (w6 << 1) | (w6 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w6 + (b ^ c ^ d) + 0xCA62C1D6 ;
-    b = (b << 30) | (b >>> 2) ;
-    w7 = w4 ^ w15 ^ w9 ^ w7; w7 = (w7 << 1) | (w7 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w7 + (a ^ b ^ c) + 0xCA62C1D6 ;
-    a = (a << 30) | (a >>> 2) ;
-    w8 = w5 ^ w0 ^ w10 ^ w8; w8 = (w8 << 1) | (w8 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w8 + (e ^ a ^ b) + 0xCA62C1D6 ;
-    e = (e << 30) | (e >>> 2) ;
-    w9 = w6 ^ w1 ^ w11 ^ w9; w9 = (w9 << 1) | (w9 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w9 + (d ^ e ^ a) + 0xCA62C1D6 ;
-    d = (d << 30) | (d >>> 2) ;
-    w10 = w7 ^ w2 ^ w12 ^ w10; w10 = (w10 << 1) | (w10 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w10 + (c ^ d ^ e) + 0xCA62C1D6 ;
-    c = (c << 30) | (c >>> 2) ;
-    w11 = w8 ^ w3 ^ w13 ^ w11; w11 = (w11 << 1) | (w11 >>> 31) ;
-    e += ((a << 5) | ( a >>> 27)) + w11 + (b ^ c ^ d) + 0xCA62C1D6 ;
-    b = (b << 30) | (b >>> 2) ;
-    w12 = w9 ^ w4 ^ w14 ^ w12; w12 = (w12 << 1) | (w12 >>> 31) ;
-    d += ((e << 5) | ( e >>> 27)) + w12 + (a ^ b ^ c) + 0xCA62C1D6 ;
-    a = (a << 30) | (a >>> 2) ;
-    w13 = w10 ^ w5 ^ w15 ^ w13; w13 = (w13 << 1) | (w13 >>> 31) ;
-    c += ((d << 5) | ( d >>> 27)) + w13 + (e ^ a ^ b) + 0xCA62C1D6 ;
-    e = (e << 30) | (e >>> 2) ;
-    w14 = w11 ^ w6 ^ w0 ^ w14; w14 = (w14 << 1) | (w14 >>> 31) ;
-    b += ((c << 5) | ( c >>> 27)) + w14 + (d ^ e ^ a) + 0xCA62C1D6 ;
-    d = (d << 30) | (d >>> 2) ;
-    w15 = w12 ^ w7 ^ w1 ^ w15; w15 = (w15 << 1) | (w15 >>> 31) ;
-    a += ((b << 5) | ( b >>> 27)) + w15 + (c ^ d ^ e) + 0xCA62C1D6 ;
-    c = (c << 30) | (c >>> 2) ;
-
-    h0 += a;
-    h1 += b;
-    h2 += c;
-    h3 += d;
-    h4 += e;
-  }
-  
-  
-  private void completeFinalBuffer(ByteBuffer buffer) {
-    if(finalBuffer.position() == 0) 
-      return;
-    
-    while(buffer.remaining() > 0 && finalBuffer.remaining() > 0) {
-      finalBuffer.put(buffer.get());
-    }
-    
-    if(finalBuffer.remaining() == 0) {
-      finalBuffer.position(0);
-      transform(finalBuffer);
-      finalBuffer.position(0);
-    }
-  }
-  
-  
-  
-  /**
-   * Resets the SHA-1 to initial state for a new message digest calculation.
-   * Must be called before starting a new hash calculation.
-   */
-  public void reset() {
-    h0 = 0x67452301;
-    h1 = 0xEFCDAB89;
-    h2 = 0x98BADCFE;
-    h3 = 0x10325476;    
-    h4 = 0xC3D2E1F0;    
-    
-    length = 0;
-    
-    finalBuffer.clear();
-  }
-  
-  
-  /**
-   * Starts or continues a SHA-1 message digest calculation.
-   * Only the remaining bytes of the given ByteBuffer are used.
-   * @param buffer input data
-   */
-  public void update(ByteBuffer buffer) {
-    length += buffer.remaining();
-    //Save current position to leave given buffer unchanged
-    int position = buffer.position();
-    
-    //Complete the final buffer if needed
-    completeFinalBuffer(buffer);
-    
-    while(buffer.remaining() >= 64) {
-      transform(buffer);
-    }
-    
-    if(buffer.remaining() != 0) {
-      finalBuffer.put(buffer);
-    }
-    
-    buffer.position(position);
-  }
-  
-  
-  /**
-   * Finishes the SHA-1 message digest calculation.
-   * @return 20-byte hash result
-   */
-  public byte[] digest() {
-    byte[] result = new byte[20];
-    
-    finalBuffer.put((byte)0x80);
-    if(finalBuffer.remaining() < 8) {
-      while(finalBuffer.remaining() > 0) {
-        finalBuffer.put((byte)0);
-      }
-      finalBuffer.position(0);
-      transform(finalBuffer);
-      finalBuffer.position(0);
-    }
-    
-    while(finalBuffer.remaining() > 8) {
-      finalBuffer.put((byte)0);
-    }
-    
-    finalBuffer.putLong(length << 3);
-    finalBuffer.position(0);
-    transform(finalBuffer);
-    
-    finalBuffer.position(0);
-    finalBuffer.putInt(h0);
-    finalBuffer.putInt(h1);
-    finalBuffer.putInt(h2);
-    finalBuffer.putInt(h3);
-    finalBuffer.putInt(h4);    
-    finalBuffer.position(0);
-    
-    for(int i  = 0 ; i < 20 ; i++) {
-     result[i] = finalBuffer.get(); 
-    }
-    
-    return result;
-  }
-  
-  
-  /**
-   * Finishes the SHA-1 message digest calculation, by first performing a final update
-   * from the given input buffer, then completing the calculation as with digest().
-   * @param buffer input data
-   * @return 20-byte hash result
-   */
-  public byte[] digest(ByteBuffer buffer) {
-    update( buffer );
-    return digest();
-  }
-  
-  
-  
-  /**
-   * Save the current digest state.
-   * This allows the resuming of a SHA-1 calculation, even after a digest calculation
-   * is finished with digest().
-   */
-  public void saveState() {
-    s0=h0;
-    s1=h1;
-    s2=h2;
-    s3=h3;
-    s4=h4;
-    
-    saveLength = length;
-    
-    int position = finalBuffer.position();
-    
-    finalBuffer.position(0);
-    finalBuffer.limit(position);
-    
-    saveBuffer.clear();
-    saveBuffer.put(finalBuffer);
-    saveBuffer.flip();
-    
-    finalBuffer.limit(64);
-    finalBuffer.position( position );
-  }
-  
-  
- /**
-  * Restore the digest to its previously-saved state.
-  */
-  public void restoreState() {
-    h0=s0;
-    h1=s1;
-    h2=s2;
-    h3=s3;
-    h4=s4;
-    
-    length = saveLength;
-    
-    finalBuffer.clear();
-    finalBuffer.put(saveBuffer);
-  }
- 
-  
-}
diff --git a/org/gudy/azureus2/core3/util/test/SHA1SpeedTest.java b/org/gudy/azureus2/core3/util/test/SHA1SpeedTest.java
deleted file mode 100644
index 7cab21e..0000000
--- a/org/gudy/azureus2/core3/util/test/SHA1SpeedTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Created on Mar 12, 2004
- * Created by Alon Rohter
- * Copyright (C) 2004, 2005, 2006 Aelitis, 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.core3.util.test;
-
-import java.nio.*;
-import java.util.Arrays;
-import java.util.Random;
-
-// import org.gudy.azureus2.core3.util.SHA1;
-import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.core3.util.SHA1;
-
-/**
- */
-public class SHA1SpeedTest {
-
-	private static final int	BUFF_MAX_SIZE	= 4 * 1024 * 1024;
-
-	private static final int[]	LOOPS			= { 1000000, 30000, 15000, 4000, 3000, 2000, 1200, 800 };
-	private static final int[]	TESTS			= { 1, 16, 64, 256, 512, 1024, 2048, 4096 };
-	
-	private static final int TEST_SPEED_FACTOR = 1; // use larger numbers for less tests
-
-	public static void main(String[] args)
-	{
-		
-		Random rnd = new Random();
-
-		SHA1Old oldsha = new SHA1Old();
-		SHA1 newsha = new SHA1();
-
-		ByteBuffer dBuffer = ByteBuffer.allocateDirect(BUFF_MAX_SIZE);
-		ByteBuffer hBuffer = ByteBuffer.allocate(BUFF_MAX_SIZE);
-
-		for (int i = 0; i < BUFF_MAX_SIZE; i++)
-		{
-			byte b = (byte) (rnd.nextInt()&0xFF);
-			dBuffer.put(b);
-		}
-		
-		dBuffer.rewind();
-		hBuffer.put(dBuffer);
-		hBuffer.rewind();
-		dBuffer.rewind();
-		
-
-		// allow time for setting thread to high-priority
-		try
-		{
-			System.out.println("Setting high thread priority to decrease test jitter");
-			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
-			Thread.sleep(2000);
-		} catch (Exception ignore)
-		{
-		}
-
-		for (int t = 0; t < TESTS.length; t++)
-		{
-
-			int buffsize = TESTS[t] * 1024;
-
-			dBuffer.position(0);
-			dBuffer.limit(buffsize);
-			hBuffer.position(0);
-			hBuffer.limit(buffsize);
-
-			
-			int loops = LOOPS[t]/TEST_SPEED_FACTOR;
-
-			String info = " [" + buffsize / 1024 + "KB, " + loops + "x] = ";
-
-			double totalMBytes = ((double) buffsize / (1024 * 1024)) * loops;
-
-			
-			long time;
-			double speed;
-
-			
-			System.out.println("direct:");
-			
-			System.out.print("Old SHA1");
-			time = System.currentTimeMillis();
-			for (int i = 0; i < loops; i++)
-			{
-				oldsha.reset();
-				oldsha.digest(dBuffer);
-			}
-			time = System.currentTimeMillis() - time;
-			speed = totalMBytes / (time / (double)1024);
-			System.out.println(info + time + " ms @ " + speed + " MiB/s");
-
-			
-			System.out.print("New SHA1 ");
-			time = System.currentTimeMillis();
-			for (int i = 0; i < loops; i++)
-			{
-				newsha.reset();
-				newsha.digest(dBuffer);
-			}
-			time = System.currentTimeMillis() - time;
-			speed = totalMBytes / (time / (double)1024);
-			System.out.println(info + time + " ms @ " + speed + " MiB/s");
-
-			System.out.println("heap:");
-			
-			System.out.print("Old SHA1");
-			time = System.currentTimeMillis();
-			for (int i = 0; i < loops; i++)
-			{
-				oldsha.reset();
-				oldsha.digest(hBuffer);
-			}
-			time = System.currentTimeMillis() - time;
-			speed = totalMBytes / (time / (double)1024);
-			System.out.println(info + time + " ms @ " + speed + " MiB/s");
-
-			
-			System.out.print("New SHA1 ");
-			time = System.currentTimeMillis();
-			for (int i = 0; i < loops; i++)
-			{
-				newsha.reset();
-				newsha.digest(hBuffer);
-			}
-			time = System.currentTimeMillis() - time;
-			speed = totalMBytes / (time / (double)1024);
-			System.out.println(info + time + " ms @ " + speed + " MiB/s");
-
-			System.out.println();
-		}
-		
-		
-		System.out.println("performing randomized buffer windowing checks, this may take a while");
-		
-		byte[] oldd;
-		byte[] newd;
-		byte[] oldh;
-		byte[] newh;
-		
-		int size;
-		int offset;
-		
-		ByteBuffer dview;
-		ByteBuffer hview;
-		
-		for(int i=0;i<LOOPS[1]/TEST_SPEED_FACTOR;i++)
-		{
-			size = rnd.nextInt(BUFF_MAX_SIZE);
-			offset = rnd.nextInt(BUFF_MAX_SIZE-size-1);
-			
-			hBuffer.limit(offset+size);
-			hBuffer.position(offset);
-			dBuffer.limit(offset+size);
-			dBuffer.position(offset);
-			
-			oldsha.reset();
-			newsha.reset();
-			oldh = oldsha.digest(hBuffer);
-			newh = newsha.digest(hBuffer);
-			oldsha.reset();
-			newsha.reset();
-			oldd = oldsha.digest(dBuffer);
-			newd = newsha.digest(dBuffer);
-			
-			
-			if(!Arrays.equals(oldh, newh) || !Arrays.equals(oldd, newd) || !Arrays.equals(oldd, oldh))
-			{
-				System.out.println("hash mismatch at offset: "+offset+" size: "+size);
-				System.out.println("\t\t"+ByteFormatter.nicePrint(oldh));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(newh));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(oldd));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(newd));
-			}
-				
-			if(hBuffer.limit() != offset+size || dBuffer.limit() != offset+size || hBuffer.position() != offset || dBuffer.position() != offset)
-				System.out.println("buffer does not match its original state");
-			
-			dview = dBuffer.slice();
-			hview = hBuffer.slice();
-			
-			oldsha.reset();
-			newsha.reset();
-			oldh = oldsha.digest(hview);
-			newh = newsha.digest(hview);
-			oldsha.reset();
-			newsha.reset();
-			oldd = oldsha.digest(dview);
-			newd = newsha.digest(dview);
-			
-			
-			if(!Arrays.equals(oldh, newh) || !Arrays.equals(oldd, newd) || !Arrays.equals(oldd, oldh))
-			{
-				System.out.println("(view) hash mismatch at offset: "+offset+" size: "+size);
-				System.out.println("\t\t"+ByteFormatter.nicePrint(oldh));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(newh));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(oldd));
-				System.out.println("\t\t"+ByteFormatter.nicePrint(newd));
-			}
-				
-			if(hview.limit() != hview.capacity() || dview.limit() != dview.capacity() || hview.position() != 0 || dview.position() != 0)
-				System.out.println("view buffer does not match its original state");
-		}
-		System.out.println("DONE");
-
-	}
-
-}
diff --git a/org/gudy/azureus2/core3/util/test/SHA1Verification.java b/org/gudy/azureus2/core3/util/test/SHA1Verification.java
deleted file mode 100644
index d27cfcf..0000000
--- a/org/gudy/azureus2/core3/util/test/SHA1Verification.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Created on Apr 4, 2004
- * Created by Alon Rohter
- * 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.core3.util.test;
-
-
-import java.io.*;
-import java.nio.*;
-import java.nio.channels.*;
-import java.util.*;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.FileUtil;
-import org.gudy.azureus2.core3.util.SHA1;
-import java.security.MessageDigest;
-
-/**
- * 
- */
-public class SHA1Verification {
-  
-  public static final String dirname = "D:" + System.getProperty("file.separator") + "testdir";
-  
-  public static void main(String[] args) {
-    if (! new File( dirname ).exists())  createTestFiles();
-    runTests();
-  }
-
-  public static void createTestFiles() {
-    try {
-      System.out.println("Creating test files ... ");
-      Random rand = new Random();
-      String rootname = "f-";
-      
-      long[] sizes = { 0, 1, 50000000 };
-    
-      File testdir = new File( dirname );
-      FileUtil.mkdirs(testdir);
-   
-
-      
-      for (int i=0; i < sizes.length; i++) {
-        long size = sizes[i];
-        File file = new File( testdir, rootname + String.valueOf( size ));
-        System.out.println( file.getName() + "...");
-        FileChannel fc = new RandomAccessFile( file, "rw" ).getChannel();
-        
-        long position = 0;
-        while ( position < size ) {
-          long remaining = size - position;
-          if ( remaining > 1024000 ) remaining = 1024000;
-          byte[] buffer = new byte[ new Long(remaining).intValue() ];
-          rand.nextBytes( buffer );
-          ByteBuffer bb = ByteBuffer.wrap( buffer );
-          position += fc.write( bb );
-        }
-        
-        fc.close();
-      }
-      System.out.println("DONE\n");
-    }
-    catch (Exception e) { Debug.printStackTrace( e ); }
-  }
-  
-  
-	public static void runTests() {
-    try {
-    
-      //SHA1 sha1Jmule = new SHA1();
-      MessageDigest sha1Sun = MessageDigest.getInstance("SHA-1");
-      SHA1 sha1Gudy = new SHA1();
-      //SHA1Az shaGudyResume = new SHA1Az();
-    
-      ByteBuffer buffer = ByteBuffer.allocate( 1024 * 1024 );
-    
-      File dir = new File( dirname );
-      File[] files = dir.listFiles();
-
-      for (int i=0; i < files.length; i++) {
-        FileChannel fc = new RandomAccessFile( files[i], "r" ).getChannel();
-        
-        System.out.println("Testing " + files[i].getName() + " ...");
-        
-        while( fc.position() < fc.size() ) {
-         fc.read( buffer );
-         buffer.flip();
-         
-         byte[] raw = new byte[ buffer.limit() ];
-         System.arraycopy( buffer.array(), 0, raw, 0, raw.length );
-
-         sha1Gudy.update( buffer );
-         sha1Gudy.saveState();
-         ByteBuffer bb = ByteBuffer.wrap( new byte[56081] );
-         sha1Gudy.digest( bb );
-         sha1Gudy.restoreState();
-         
-         sha1Sun.update( raw );
-         
-         buffer.clear();
-        }
-        
-        byte[] sun = sha1Sun.digest();
-        sha1Sun.reset();
-        
-        byte[] gudy = sha1Gudy.digest();
-        sha1Gudy.reset();
-        
-        if ( Arrays.equals( sun, gudy ) ) {
-          System.out.println("  SHA1-Gudy: OK");
-        }
-        else {
-          System.out.println("  SHA1-Gudy: FAILED");
-        }
-        
-        buffer.clear();
-        fc.close();
-        System.out.println();
-      }
-    
-    }
-    catch (Throwable e) { Debug.printStackTrace( e );}
-  }
-	
-
-}
diff --git a/org/gudy/azureus2/core3/util/test/Sha1AlgorithmHelper.java b/org/gudy/azureus2/core3/util/test/Sha1AlgorithmHelper.java
deleted file mode 100644
index f98a052..0000000
--- a/org/gudy/azureus2/core3/util/test/Sha1AlgorithmHelper.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * File    : Sha1AlgorithmHelper.java
- * Created : 12 mars 2004
- * By      : Olivier
- *
- * 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.core3.util.test;
-
-/**
- * @author Olivier
- * 
- */
-public class Sha1AlgorithmHelper {
-  
-  public static void main(String args[]) {
-    algorithm2NoShift();
-  }    
-  
-  //SHA1 Algorithm v2 using only 16 ints and changing variable meaning
-  //Over a period of 5 iterations.
-  
-  // A SHA-1 Basic operation can be discribed as:
-  // temp = F(a,b,c,d,e);
-  // e = d ; d = c ; c = G(b) ; b = a ; a = temp;
-  // The Goal of changing the variable meaning is to remove the allocations
-  // made.
-  // In order to do, let's replace the role of :
-  //
-  // e by d,
-  // d by c,
-  // c by b
-  // b by a
-  // a by e
-  //
-  // If we rewrite the 1st equation, we can see that :
-  // e = F(a,b,c,d,e); and b = G(b);
-  // However, next line will be :
-  // d = F(b,c,d,e,a); and a = G(a);
-  // Next will be :
-  // c = F(c,d,e,a,b); and e = G(e);
-  // b = F(d,e,a,b,c); and d = G(d);
-  // a = F(e,a,b,c,d); and c = G(c);
-  // And we loop to first 'kind' where :
-  // e = F(a,b,c,d,e), and b = G(b);
-  
-  // On 80th iteration (that is for t=79), we've looped 80 = 5 * 16,
-  // so we're back to the classic representation of variables a,b,c,d,e
-  // and we can directly use them to increment the h0,h1,h2,h3,h4 variables.
-  
-  public static void algorithm2NoShift() {
-    String variables = "abcde";
-    int mask = 0x0000000F;
-    for(int t = 0 ; t <= 79 ; t++) {
-      String a = "" + variables.charAt((85-t)%5);
-      String b = "" + variables.charAt((85-t+1)%5);
-      String c = "" + variables.charAt((85-t+2)%5);
-      String d = "" + variables.charAt((85-t+3)%5);
-      String e = "" + variables.charAt((85-t+4)%5);
-      
-      int s = t & mask;
-      if(t >= 16) {
-        System.out.println("w" + s + " = w" + ((s+13) & mask) + " ^ w" + ((s+8) & mask) + " ^ w" + ((s+2) & mask) + " ^ w" + s + "; w" + s + " = (w" + s + " << 1) | (w" + s + " >>> 31) ;");        
-      }
-      System.out.print(e + " += ((" + a + " << 5) | ( " + a + " >>> 27)) + w" + s + " + ");
-      int ft = t / 20;
-      if(ft == 0) {
-        System.out.println("((" + b +" & " + c + ") | ((~" + b +" ) & " + d + ")) + 0x5A827999 ;");
-      }
-      if(ft == 1) {
-        System.out.println("(" + b +" ^ " + c + " ^ " + d + ") + 0x6ED9EBA1 ;");
-      }
-      if(ft == 2) {
-        System.out.println("((" + b +" & " + c + ") | (" + b + " & " + d + ") | (" + c + " & " + d + ")) + 0x8F1BBCDC ;");
-      }
-      if(ft == 3) {
-        System.out.println("(" + b + " ^ " + c + " ^ " + d + ") + 0xCA62C1D6 ;");
-      }
-      System.out.println(b + " = (" + b + " << 30) | (" + b + " >>> 2) ;");
-    }
-  }
-  
-  
-  //SHA1 Algorithm v2 using only 16 ints (+ a,b,c,d,e and temp)
-  public static void algorithm2() {
-    int mask = 0x0000000F;
-  	for(int t = 0 ; t <= 79 ; t++) {
-  		int s = t & mask;
-      if(t >= 16) {
-        System.out.println("w" + s + " = w" + ((s+13) & mask) + " ^ w" + ((s+8) & mask) + " ^ w" + ((s+2) & mask) + " ^ w" + s + "; w" + s + " = (w" + s + " << 1) | (w" + s + " >>> 31) ;");        
-      }
-      System.out.print("temp = ((a << 5) | (a >>> 27)) + e + w" + s + " + ");
-      int ft = t / 20;
-      if(ft == 0) {
-        System.out.println("((b & c) | ((~b) & d)) + 0x5A827999 ;");
-      }
-      if(ft == 1) {
-        System.out.println("(b ^ c ^ d) + 0x6ED9EBA1 ;");
-      }
-      if(ft == 2) {
-        System.out.println("((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;");
-      }
-      if(ft == 3) {
-        System.out.println("(b ^ c ^ d) + 0xCA62C1D6 ;");
-      }
-      System.out.println("e=d ; d=c ; c = (b << 30) | (b >>> 2) ; b=a ; a=temp;");
-  	}
-  }
-  
-  public static void part1() {
-    for(int t = 16 ; t <= 79 ; t++) {
-    	System.out.println( "w" + t + " = w" + (t-3) + " ^ w" + (t-8) + " ^ w" + (t-14) + " ^ w" + (t-16) + ";");
-    	System.out.println( "w" + t + " = (w" + t + " << 1) | (w" + t + " >>> 31);");
-    }
-  }
-  
-  public static void part2() {
-  	for(int t=0; t<= 79 ; t++) {
-      int fn = t / 20;      
-      System.out.print("temp = ((a << 5) | (a >>> 27)) + e + w" + t + " + ");
-      if(fn == 0) {
-        System.out.println("((b & c) | ((~b) & d)) + 0x5A827999 ;");
-      }
-      if(fn == 1) {
-        System.out.println("(b ^ c ^ d) + 0x6ED9EBA1 ;");
-      }
-      if(fn == 2) {
-        System.out.println("((b & c) | (b & d) | (c & d)) + 0x8F1BBCDC ;");
-      }
-      if(fn == 3) {
-        System.out.println("(b ^ c ^ d) + 0xCA62C1D6 ;");
-      }
-      System.out.println("e = d ; d = c ; c = (b<<30) | (b >>> 2); b = a; a = temp;");
-  	}
-  }
-
-}
diff --git a/org/gudy/azureus2/core3/util/test/SystemClockSpeedup.java b/org/gudy/azureus2/core3/util/test/SystemClockSpeedup.java
deleted file mode 100644
index 73be994..0000000
--- a/org/gudy/azureus2/core3/util/test/SystemClockSpeedup.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Created on Apr 11, 2004
- * Created by Alon Rohter
- * 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.core3.util.test;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-
-public class SystemClockSpeedup {
-	public static void main(String[] args) {
-		for (int i=0; i < 20; i++) {
-      new tester().start();
-		}
-	}
-    
-   
-    
-  public static class tester extends Thread {
-    public void run() {
-        try {
-            int count = 0;
-            while (true) {
-                System.currentTimeMillis();
-                count++;
-                if (count == 30000) {
-                    count = 0;
-                    Thread.sleep(100);
-                }
-            }
-        } catch (Exception e) {
-        	Debug.printStackTrace( e );
-        }
-    }
-  }
-
-    
-    
-    
-    
-}
diff --git a/org/gudy/azureus2/core3/xml/util/XMLEscapeWriter.java b/org/gudy/azureus2/core3/xml/util/XMLEscapeWriter.java
new file mode 100644
index 0000000..0bf7b06
--- /dev/null
+++ b/org/gudy/azureus2/core3/xml/util/XMLEscapeWriter.java
@@ -0,0 +1,59 @@
+/*
+ * Created on Jan 5, 2011
+ * Created by Paul Gardner
+ * 
+ * Copyright 2011 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.core3.xml.util;
+
+import java.io.PrintWriter;
+
+public class 
+XMLEscapeWriter
+	extends PrintWriter
+{
+	private boolean	enabled = true;
+	
+	public
+	XMLEscapeWriter(
+		PrintWriter	pw )
+	{
+		super( pw );
+	}
+	
+	public void
+	print(
+		String	str )
+	{
+		if ( enabled ){
+		
+			super.print( XUXmlWriter.escapeXML( str ));
+			
+		}else{
+			
+			super.print( str );
+		}
+	}
+	
+	public void
+	setEnabled(
+		boolean		b )
+	{
+		enabled	= b;
+	}
+}
diff --git a/org/gudy/azureus2/internat/MessagesBundle.properties b/org/gudy/azureus2/internat/MessagesBundle.properties
index 28c236d..7a2fd8d 100644
--- a/org/gudy/azureus2/internat/MessagesBundle.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle.properties
@@ -1,4 +1,4 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
 MainWindow.menu.file.open.torrent=Torrent File...
 MainWindow.menu.file.open.torrent.keybinding=Meta+O
 Main.parameter.usage=Usage : java org.gudy.azureus2.cl.Main [parameters] \"file.torrent\" \"save path"
@@ -28,7 +28,7 @@ MainWindow.menu.file.folder.keybinding=Meta+Shift+O
 MainWindow.dialog.choose.folder=Choose the directory containing the torrent files
 MainWindow.menu.view=&View
 MainWindow.menu.view.show=Show
-MainWindow.menu.view.mytorrents=&My Torrents
+MainWindow.menu.view.mytorrents=&{library.name}
 MainWindow.menu.view.mytorrents.keybinding=Meta+1
 MainWindow.menu.view.open_global_transfer_bar=Transfers Bar
 MainWindow.menu.view.configuration=&Options...
@@ -51,13 +51,10 @@ MainWindow.menu.help=&Help
 MainWindow.menu.help.about=About Vuze
 MainWindow.menu.torrent=T&orrent
 MainWindow.about.title=About
-MainWindow.about.section.developers=Developers
-MainWindow.about.section.translators=Translators
 MainWindow.about.section.system=System
 MainWindow.about.section.internet=Internet
 MainWindow.about.internet.homepage=Vuze Homepage
 MainWindow.about.internet.sourceforge=Sourceforge Project Page
-MainWindow.about.internet.sourceforgedownloads=Sourceforge Downloads
 MainWindow.about.internet.bugreports=Bug Reports
 MainWindow.about.internet.forumdiscussion=Forums
 MainWindow.about.internet.wiki=Vuze Wiki FAQ
@@ -67,7 +64,7 @@ MainWindow.status.latestversion=Latest
 MainWindow.status.latestversion.clickupdate=Click to update
 MainWindow.status.unknown=unknown
 MainWindow.status.checking=checking
-MyTorrentsView.mytorrents=My Torrents
+MyTorrentsView.mytorrents={library.name}
 TableColumn.header.name=Name
 TableColumn.header.size=Size
 TableColumn.header.done=Done
@@ -99,7 +96,7 @@ MyTorrentsView.menu.setpriority.low=&Low
 MyTorrentsView.menu.start=&Start
 MyTorrentsView.menu.stop=Sto&p
 MyTorrentsView.menu.remove=&Remove
-MyTorrentsView.menu.changeTracker=&Add Tracker URL
+MyTorrentsView.menu.changeTracker=&Add Tracker URL(s)
 TrayWindow.menu.exit=E&xit
 TrayWindow.menu.show=&Show Vuze
 SystemTray.menu.exit=E&xit
@@ -176,7 +173,7 @@ ConfigView.label.openconsole=Open Console on startup
 ConfigView.label.openconfig=Open Options on startup
 ConfigView.label.startminimized=Start minimized
 ConfigView.section.irc=IRC
-ConfigView.label.ircwiki=Please read http://www.azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=Please read http://wiki.vuze.com/w/Rules_for_IRC
 ConfigView.label.ircserver=Server
 ConfigView.label.ircchannel=Channel
 ConfigView.label.irclogin=Nickname
@@ -196,10 +193,10 @@ ConfigView.title.full=Options
 ConfigView.title.full._mac=Preferences
 ConsoleView.title.short=Console
 ConsoleView.title.full=Console
-FileItem.write=write
-FileItem.read=read
-FileItem.normal=normal
-FileItem.high=high
+FileItem.write=Write
+FileItem.read=Read
+FileItem.normal=Normal
+FileItem.high=High
 FileItem.donotdownload=Do not download
 FileItem.delete=Delete
 FilesView.name=Name
@@ -226,6 +223,7 @@ GeneralView.section.availability=Availability
 GeneralView.label.status.pieces_available=Pieces Status
 GeneralView.section.transfer=Transfer
 GeneralView.section.info=Info
+TorrentInfoView.title.full={GeneralView.section.info}
 GeneralView.title.short=General
 GeneralView.title.full=General
 GeneralView.label.timeelapsed=Time Elapsed : 
@@ -338,8 +336,8 @@ IrcView.help=Valid commands are :\n . /help : displays this message\n . /nick |
 PasswordWindow.title=Vuze is locked
 PasswordWindow.passwordprotected=Vuze is password protected.\nTo show Vuze window, please enter your password here :
 Button.ok=&OK
-TrackerChangerWindow.title=Add Tracker
-TrackerChangerWindow.newtracker=Enter new tracker url
+TrackerChangerWindow.title=Add Tracker(s)
+TrackerChangerWindow.newtracker=Enter new tracker url(s) - comma separate if more than one
 PeersView.discarded=Discarded
 PeersView.discarded.info=Data you somehow received although you didn't need it, so you got rid of it.
 discarded=discarded
@@ -406,12 +404,14 @@ ConfigView.label.showpopuponclose=Show confirmation popup when stopping seeding
 ConfigView.label.startNumSeeds=\nStart seeding if there is less than\n - Overrides all other rules
 ConfigView.label.seeds=seeds
 ConfigView.section.seeding=Seeding
-MyTorrentsView.menu.removeand=Remo&ve and
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletetorrent=Delete &Torrent File
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletedata=Delete &Data
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deleteboth=Delete &Both
 deletedata.title=Delete Content
-deletedata.message1=Are you sure you want to permanently delete '%1'?
+# used for more than just "delete data"
 deletedata.noprompt=Don't prompt me again
 MainWindow.menu.file.configure=Configuration &Wizard...
 configureWizard.title=Configuration Wizard
@@ -433,11 +433,6 @@ configureWizard.transfer.maxUpSpeed=Max Up Speed (KB/s)
 configureWizard.transfer.maxActiveTorrents=Max Active
 configureWizard.transfer.maxDownloads=Max Downloads
 configureWizard.transfer.maxUploadsPerTorrent=Max Uploads per Torrent
-configureWizard.nat.title=NAT / Server Port
-configureWizard.nat.message=In order to get the best out of Vuze it's highly recommended to be fully accessible from the internet. \
-This tool lets you test and / or change the port used to accept incoming peer connections.\n\nNOTE: This tool only tests for TCP connections. \
-The Distributed DB requires incoming UDP connections as well, but will automatically notify you if it discovers a blocking firewall.\n\nNOTE: TCP port 6880 \
-is reserved internally, so it cannot be used.
 configureWizard.nat.test=Test
 configureWizard.nat.testing=Testing port
 configureWizard.nat.ok=OK !
@@ -580,7 +575,7 @@ IPChecker.external.service.discoveryvip.url=http://ip.discoveryvip.com/
 IPChecker.external.service.discoveryvip.description=Discoveryvip - IP address checking only
 IPChecker.external.httpinvalidresponse=Invalid HTTP response
 IPChecker.external.loadingwebpage= Loading web page
-IPChecker.external.analysingresponse=Analysing response
+IPChecker.external.analysingresponse=Analyzing response
 IPChecker.external.addressextracted=Extracted IP address
 IPChecker.external.httploadfail=Failed to load page
 IPChecker.external.timeout=Timeout occurred
@@ -611,7 +606,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=Dynamic and Static DNS service provider\n(no freely available 'check address' service)
 ConfigView.section.tracker.publicenable=Enable external torrents
 ConfigView.label.playdownloadspeech=Speak when a download is finished
-ConfigView.label.playdownloadspeech.info=Speech Services currently works best with English
 #
 # Tooltips
 #
@@ -760,8 +754,8 @@ health.explain.red=means that you're not connected to any peer while downloading
 health.explain.blue=when seeding, it means that you're not yet connected to any peer\nwhen downloading, it means that you are connected to some peers but the tracker is down
 health.explain.yellow=means that the tracker is ok, you're connected to peers, but you don't have any remote connection.\nYou may have a NAT problem if your torrents stay on yellow status all the time
 health.explain.green=means that everything is going fine.
-ConfigView.section.style.alwaysRefreshMyTorrents=Always refresh My Torrents
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=This option will refresh the My Torrents view even if not displayed (useful for some mirc plugins)
+ConfigView.section.style.alwaysRefreshMyTorrents=Always refresh {library.name}
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=This option will refresh the {library.name} view even if not displayed (useful for some mirc plugins)
 #
 #2.0.7.0
 #
@@ -774,7 +768,7 @@ security.certtruster.prompt=Do you want to trust it?
 security.certtruster.yes=Yes
 security.certtruster.no=No
 ConfigView.section.tracker.torrentsperpage=How many torrents per page ?  [0: unlimited]
-MainWindow.menu.file.share=Classic-&Share
+MainWindow.menu.file.share=&Share
 MainWindow.menu.file.share.file=&File...
 MainWindow.menu.file.share.dir=F&older...
 MainWindow.menu.file.share.dircontents=Folder &Contents...
@@ -784,21 +778,19 @@ MainWindow.dialog.share.sharedir=Select Folder To Share
 MainWindow.dialog.share.sharedircontents=Select Folder Contents To Share
 MainWindow.dialog.share.sharedircontents.recursive=Recursive
 globalmanager.download.remove.veto=Removal Action Vetoed
-plugin.sharing.download.remove.veto=This download is the result of a resource being classically-shared.\nTo remove the download remove the associated classic-share: go to Tools->My Classic-Shares.
+plugin.sharing.download.remove.veto=This download is the result of a resource being shared.\nTo remove the download remove the associated share: go to Tools->My Shares.
 ConfigView.section.tracker.main=Main
 ConfigView.section.tracker.web=Web
 ConfigView.label.prioritizefirstpiece=Prioritize first and last piece of file(s)
 ConfigView.label.prioritizefirstpiece.tooltip=Attempts to download the very beginning and very end of a file first.\nFor support of early previewing.
-ConfigView.section.file.confirm_data_delete=Confirm when deleting data
-ConfigView.section.file.confirm_data_delete.tooltip=Confirm data deletion when using 'Remove and Delete...'
 ConfigView.section.file.delete.include_files_outside_save_dir=When deleting data, allow files linked outside torrent save directory to be removed also
 TrayWindow.menu.startalldownloads=Start All Downloads
 SystemTray.menu.startalltransfers=Start All Transfers
-sharing.progress.title=Classic-Sharing Progress
+sharing.progress.title=Sharing Progress
 sharing.progress.hide=Hide
-MainWindow.menu.view.myshares=My Classic-Shares
+MainWindow.menu.view.myshares=My Shares
 MainWindow.menu.view.myshares.keybinding=Meta+3
-MySharesView.title.full=My Classic Shares
+MySharesView.title.full=My Shares
 MySharesView.name=Name
 MySharesView.type=Type
 MySharesView.type.file=File
@@ -809,20 +801,20 @@ MySharesView.menu.remove=Remove
 ConfigView.section.tracker.extensions=Extensions
 ConfigView.section.tracker.sendpeerids=Send peer identity to downloaders
 ConfigView.section.tracker.enableudp=Enable UDP tracker protocol
-plugin.sharing.torrent.remove.veto=This tracker registration is the result of a resource being classically-shared.\nTo remove the download remove the associated classic-share: go to Tools->My Classic-Shares.
+plugin.sharing.torrent.remove.veto=This tracker registration is the result of a resource being shared.\nTo remove the download remove the associated share: go to Tools->My Shares.
 plugin.download.remove.veto.notstopped=Download can't be removed as it is not stopped
-plugin.sharing.remove.veto=This classic-share is a sub-share of a 'directory contents' share and can't be explicitly deleted.\n Delete the root classic-share
+plugin.sharing.remove.veto=This share is a sub-share of a 'directory contents' share and can't be explicitly deleted.\n Delete the root share
 GeneralView.label.hash.tooltip=Click to copy the hash to the clipboard
 ConfigView.section.tracker.maxpeersreturned=Maximum peers returned [0: unlimited]
 ConfigView.label.serverport=Incoming TCP / UDP listen port
 ConfigView.label.serverport.tooltip=Port must within 1-65535 range, and not 6880 as that is reserved for internal Vuze use.
 configureWizard.nat.server.tcp_listen_port=Incoming TCP Listen Port
-ConfigView.section.sharing=Classic-Sharing
-ConfigView.section.sharing.usessl=Use SSL for classic-shared resources (requires Tracker configuration)
+ConfigView.section.sharing=Sharing
+ConfigView.section.sharing.usessl=Use SSL for shared resources (requires Tracker configuration)
 ConfigView.section.style.dropdiraction=Drag and Drop action for directories
 ConfigView.section.style.dropdiraction.opentorrents=Open Torrents
-ConfigView.section.style.dropdiraction.sharefolder=Classically-Share Directory
-ConfigView.section.style.dropdiraction.sharefoldercontents=Classically-Share Contents
+ConfigView.section.style.dropdiraction.sharefolder=Share Directory
+ConfigView.section.style.dropdiraction.sharefoldercontents=Share Contents
 #
 # 2.0.7.x
 #
@@ -934,7 +926,7 @@ StartStopRules.ratioMet=Peers:Seed OK
 StartStopRules.shareRatioMet=Share Ratio OK
 StartStopRules.waiting=Waiting
 StartStopRules.firstPriority=1st Priority
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Classically-Share Contents (Recursive)
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Share Contents (Recursive)
 DownloadManager.error.unabletostartserver=Unable to Start Server - check incoming port configuration / firewall permissions for application to act as server
 GeneralView.label.creationdate=Created On : 
 ConfigView.section.tracker.announcescrapepercentage=Scrape interval as %age of announce\ne.g. 200 = 2:1. 0 = let peer decide
@@ -1035,7 +1027,7 @@ ConfigView.upload.abbreviated=U:
 ConfigView.complete.abbreviated=C:
 TableColumn.header.secondsseeding=Seeding For
 TableColumn.header.secondsseeding.info=Total amount of time you have been seeding.
-TableColumn.header.secondsdownloading=DLing For
+TableColumn.header.secondsdownloading=Downloading For
 TableColumn.header.secondsdownloading.info=Amount of time you have been downloading.
 ConfigView.section.tracker.udpversion=UDP Protocol Version (1 or 2)
 window.updateswt.title=Your SWT Version is too old!
@@ -1068,12 +1060,12 @@ Scrape.status.initializing=Waiting to scrape...
 Scrape.status.scraping.queued=Scraping queued...
 ConfigView.label.minSpeedForActiveSeeding=Don't count completed torrent as using a slot if speed is below
 ConfigView.section.stats.exportpeers=Export peer details
-MainWindow.menu.view.irc.moved=Irc is now available as a plugin, see http://azureus.sourceforge.net/plugin_list.php. When installed use the view->plugins->IRC menu to access it.
+MainWindow.menu.view.irc.moved=Irc is now available as a plugin, see http://plugins.vuze.com/plugin_list.php. When installed use the view->plugins->IRC menu to access it.
 MyTrackerView.webui.contextmenu.copyurl=Copy torrent URL to clipboard
 ConfigView.section.file.torrent.ignorefiles=Files to ignore when creating/deleting torrents\n - e.g. .DS_Store;Thumbs.db
 Torrent.create.progress.ignoringfile=Ignoring file
 ConfigView.section.style.useUnitsRateBits=Use bits instead of bytes for byte-based rate values (KiB/s->Kibit/s etc.)
-ConfigView.section.interface.resetassoc=Reset explorer file associations (.torrent)
+ConfigView.section.interface.resetassoc=Reset explorer file associations (.torrent) and magnet handler (magnet:?xt=...)
 ConfigView.section.interface.resetassocbutton=Reset
 ConfigView.section.interface.checkassoc=Check associations on startup
 dialog.associations.title=Association Check
@@ -1114,7 +1106,6 @@ ConfigView.pluginlist.whereToPutOr=For shared plugins use:
 MainWindow.statusText.checking=Checking for Updates
 TableColumn.header.OnlyCDing4=OnlyCDing4
 TableColumn.header.OnlyCDing4.info=Amount of time the torrent has been only seeding.  Excludes the time the torrent was downloading (and seeding).
-ConfigView.section.style.alternateTablePainting=Use alternate method to paint graphic table columns (may require a restart)
 UpdateWindow.status.restartMaybeNeeded=Restart may be required
 ConfigView.pluginlist.shared=shared
 PeersView.host=Host Name
@@ -1155,19 +1146,18 @@ ConfigView.section.plugins.xml_http_if=XML/HTTP Interface
 webui.passwordenable=Enable password
 webui.user=User name
 webui.password=Password
-webui.port=Port (*)
-webui.protocol=Protocol (*)
-webui.homepage=Home page (*)
-webui.rootdir=Root directory (*)
-webui.rootres=Root resource (*)
-webui.mode=Mode (*)
+webui.port=Port
+webui.protocol=Protocol
+webui.homepage=Home page
+webui.rootdir=Root directory
+webui.rootres=Root resource
+webui.mode=Mode
 webui.mode.info=Mode can be\n\t"full"\t= all operations available (default)\n\t"view"\t= view only (but can update refresh frequency)
-webui.access=Access (*)
+webui.access=Access
 webui.access.info=Access can be\n\t\"local"\t= meaning only the local machine can connect\n\t"all"\t= unrestricted access (default)\n\tIP\t= e.g. 192.168.0.2\t\t\tone IP only\n\tIP1-IP2\t= e.g. 192.168.0.1-192.168.0.255\tinclusive range of IPs
 GeneralView.label.maxdownloadspeed=Down Limit
 Security.keystore.corrupt=Keystore '%1' failed to load, please delete it and recreate/re-import the certificates
 Security.keystore.empty=Keystore is empty. Please create a self-signed certificate (see Tools->Options->Security) or import an existing certificate into '%1'
-webui.restart.info=Changes to parameters marked with a (*) require a restart to take effect
 GeneralView.label.maxdownloadspeed.tooltip=max download speed [0: unlimited]
 ConfigView.section.UPnP=UPnP
 upnp.enable=Enable UPnP
@@ -1199,7 +1189,7 @@ Peers.column.UpDownRatio.info=Peer's "Uploaded : Downloaded" Ratio
 Peers.column.UpRatio=Up Ratio
 Peers.column.UpRatio.info=Peer's "Upload from you : Uploaded from other" ratio
 upnp.releasemappings=Release mappings on closedown
-webui.upnpenable=Enable UPnP for this port (*)
+webui.upnpenable=Enable UPnP for this port
 ConfigView.section.file.friendly.hashchecking=Friendly hash checking
 ConfigView.section.file.friendly.hashchecking.tooltip=A slightly slower, but much less stressful on cpu/system, piece hashchecking mode.
 ConfigView.section.tracker.seedretention=Max seeds retained per torrent [0: unlimited] 
@@ -1239,8 +1229,11 @@ MainWindow.menu.transfers=T&ransfers
 MainWindow.menu.transfers.startalltransfers=St&art All
 MainWindow.menu.transfers.stopalltransfers=St&op All
 MainWindow.menu.transfers.pausetransfers=&Pause
+MainWindow.menu.transfers.pausetransfers.keybinding=Meta+P
 MainWindow.menu.transfers.pausetransfers.keybinding.mac=Meta+.
 MainWindow.menu.transfers.resumetransfers=&Resume
+MainWindow.menu.transfers.resumetransfers.keybinding=Meta+R
+MainWindow.menu.transfers.resumetransfers.keybinding.mac=Meta+Shift+.
 ConfigView.label.experimental.osx.kernel.panic.fix=Experimental fix for kernel panics on dual-cpu OSX systems [requires restart]
 SystemTray.menu.pausetransfers=Pause Transfers
 SystemTray.menu.resumetransfers=Resume Transfers
@@ -1293,7 +1286,7 @@ authenticator.torrent=Torrent
 ConfigView.section.proxy.peer.same=Use same proxy settings for tracker and peer communications proxy 
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=Max simultaneous outbound connection attempts
 ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Max number of new outbound connection establishments Vuze should attempt any given time.\nNOTE: WindowsXP Service Pack 2 (SP2) imposes a system-wide limit of 10 simultaneous connect attempts.\nDefault value is 8.
-ConfigView.section.file.perf.cache.size.explain=The cache is used to reduce reads from/writes to disk. Unless you are using the java option '-XX:MaxDirectMemorySize' to explicitly set the memory available for cache and network IO use, you should keep this value at least %1 below your maximum VM size. The current maximum VM size is %2. For instructions on how to change this, see MemoryUsage in the wiki on %3. Failure to use sensible settings will result in 'out of memory' errors. More tha [...]
+ConfigView.section.file.perf.cache.size.explain=The cache is used to reduce reads from/writes to disk. Unless you are using the java option '-XX:MaxDirectMemorySize' to explicitly set the memory available for cache and network IO use, you should keep this value at least %1 below your maximum VM size. The current maximum VM size is %2. For instructions on how to change this, see MemoryUsage in the wiki at %3. Failure to use sensible settings will result in 'out of memory' errors. More tha [...]
 MyTorrentsView.menu.setSpeed.unlimit=No limit
 MyTorrentsView.menu.setSpeed.unlimited=Unlimited
 MyTorrentsView.menu.setSpeed.disable=Disable Upload
@@ -1344,10 +1337,10 @@ DownloadManager.error.operationcancancelled=Operation cancelled
 Torrent.create.progress.cancelled=Operation cancelled
 sharing.progress.cancel=Cancel
 wizard.maketorrents.autoopen=Open the torrent for seeding when done
-ConfigView.section.sharing.rescanenable=Enable periodic rescanning of classic-shares for changes
+ConfigView.section.sharing.rescanenable=Enable periodic rescanning of shares for changes
 ConfigView.section.sharing.rescanperiod=Rescan period (secs)
 ConfigView.section.connection.advanced=Advanced Network Settings
-ConfigView.section.connection.advanced.url=http://www.azureuswiki.com/index.php/AdvancedNetworkSettings
+ConfigView.section.connection.advanced.url=http://wiki.vuze.com/w/UG_Options#Advanced_Network_Settings
 ConfigView.section.connection.advanced.mtu=Line Maximum Transmission Unit (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=Socket SO_RCVBUF size [0: use OS default]
@@ -1356,18 +1349,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF size [0: use O
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Sets the standard socket SO_SNDBUF value (in bytes), i.e. the TCP send window size.\nVuze leaves this unset by default, meaning the defaults for the underlying OS are used.\nNOTE: Linux doubles the given value.
 ConfigView.section.connection.advanced.IPDiffServ=Outgoing packet DiffServ value (TOS field)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Sets the DiffServ part of the type-of-service (TOS) field in the IP header for outgoing packets.\nHexadecimal values can be specified by prefixing them with '0x', e.g. 0x10.\nVuze leaves this unset by default, meaning the defaults for the underlying OS are used.\nNOTE: Underlying network implementations may ignore this value, so this option is highly dependent on OS and JRE versions.
-ConfigView.section.interface.confirm_torrent_removal=Show confirmation dialog on torrent removal
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirm when Removing a torrent from the MyTorrents view.
-MyTorrentsView.confirm_torrent_removal=Are you sure you want to remove?\n
 TableColumn.header.seed_to_peer_ratio=Seed2PeerRatio
 TableColumn.header.seed_to_peer_ratio.info=Total swarm seeds to peers ratio
 PeersView.connected_time=Connected Time
 PeersView.connected_time.info=Total time connected with peer
-ConfigView.section.interface.display.add_torrents_silently=Add torrents silently
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Add torrent downloads without activating main Vuze window.
 TableColumn.header.maxdownspeed=Max Down Speed
 TableColumn.header.maxdownspeed.info=Max Download Speed per torrent
-PeersGraphicView.title=Swarm
+PeersGraphicView.title.full=Swarm
 ConfigView.section.tracker.passwordwebhttpsonly=Only allow access via HTTPS
 TableColumn.header.torrentpath=Torrent Location
 TableColumn.header.torrentpath.info=Location of the Torrent on disk
@@ -1424,8 +1412,6 @@ UpdateWindow.restartLater=Restart Vuze Later
 MainWindow.menu.file.restart=Restart Vuze
 MainWindow.dialog.restartconfirmation.title=Restart Vuze
 MainWindow.dialog.restartconfirmation.text=Do you really want to restart Vuze
-deletetorrent.message1=You are about to delete the TORRENT for :\n
-deletetorrent.message2=\nAre you sure you want to proceed?
 ConfigView.label.prioritizemostcompletedfiles=Further prioritize High priority files according to % complete and size of file
 splash.plugin.init=Initializing Plugin:
 splash.plugin.UIinit=Initializing Plugin GUI: %1  
@@ -1477,7 +1463,7 @@ MyTorrentsView.menu.advancedmenu=Advanced
 MyTorrentsView.menu.networks=Networks
 MyTorrentsView.menu.peersource=Peers Sources
 ConfigView.section.sharing.permitdht=Allow decentralized tracking when tracker is unavailable
-ConfigView.section.sharing.protocol=Protocol for classically-shared resources
+ConfigView.section.sharing.protocol=Protocol for shared resources
 PeersView.Messaging=Messaging
 PeersView.Messaging.info=Indicates what messaging system is in use.
 ConfigView.label.queue.newseedsmovetop=Move newly completed torrents to the front of the seeding list
@@ -1505,7 +1491,7 @@ ConfigView.section.logging.netinfo=Generate network info
 ConfigView.section.logging.statsinfo=Generate stats info
 ConfigView.section.logging.generatediagnostics.info=Generate diagnostic information and copy to the clipboard and log file, if configured
 ConfigView.section.sharing.privatetorrent=Private torrent - only accept peers from the tracker
-MainWindow.menu.tools.nattest=&NAT / Firewall Test
+MainWindow.menu.tools.nattest=&NAT / Firewall Test...
 Button.apply=Apply
 Button.close=Close
 window.welcome.title=Welcome to Vuze %1
@@ -1599,7 +1585,6 @@ VivaldiView.title.full_v6=Vivaldi IPv6
 MyTrackerView.date_added=Added
 ConfigView.section.tracker.portbackup=Backup ports (';' separated)
 ConfigView.label.playfilespeech=Speak when a file is finished
-ConfigView.label.playfilespeech.info=Speech Services currently works best with English
 ConfigView.label.playfilefinished=Play a sound when a file is finished
 ConfigView.label.backupconfigfiles=Backup configuration files for recovery purposes
 ConfigView.section.tracker.client.scrapesingleonly=Disable per-tracker scrape aggregation (can help with trackers that report 'URL too long' (414) errors) 
@@ -1695,7 +1680,7 @@ FilesView.skip.confirm.delete.text=Truncate file '%1' to save space?
 FilesView.rename.failed.title=Rename/Retarget failed
 FilesView.rename.failed.text=The operation failed, probably due to invalid target selection
 
-diagnostics.log_found=Vuze did not shutdown tidily. Check for any <A HREF="%1">diagnostic log files</A>. Also read the wiki article <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">Vuze Disappears</A> for more information.
+diagnostics.log_found=Vuze did not shutdown tidily. Check for any <A HREF="%1">diagnostic log files</A>. Also read the wiki article <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Disappears</A> for more information.
 ManagerItem.paused=Paused
 
 Utils.link.visit=Please visit
@@ -1870,7 +1855,7 @@ ConfigView.section.connection.encryption.encrypt.fallback_info=Enabling either f
 ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Allow non-encrypted outgoing connections if encrypted connection attempt fails
 ConfigView.section.connection.encryption.encrypt.fallback_incoming=Allow non-encrypted incoming connections
 ConfigView.section.connection.encryption=Transport Encryption
-upnp.selectedinterfaces=Selected interfaces (';' seperated, e.g. eth0;eth1) [blank: all]
+upnp.selectedinterfaces=Selected interfaces (';' separated, e.g. eth0;eth1) [blank: all]
 ConfigView.section.style.defaultSortOrder=Default Sort Order
 ConfigView.section.style.defaultSortOrder.desc=Descending
 ConfigView.section.style.defaultSortOrder.asc=Ascending
@@ -1883,7 +1868,7 @@ plugins.basicview.config=Config
 TorrentOptionsView.param.max.uploads=Maximum number of upload slots [minimum: 2]
 MyTorrentsView.dialog.setPosition.title=Set Position
 MyTorrentsView.dialog.setPosition.text=Enter position to set selected torrents to:
-MyTorrentsView.menu.reposition.manual=Reposition..
+MyTorrentsView.menu.reposition.manual=Reposition...
 ConfigView.section.connection.advanced.info.link=Please visit here for details
 ConfigView.section.connection.advanced.socket.group=Socket Options
 ConfigView.section.connection.advanced.bind_port=Bind to local port [0: disabled]
@@ -1899,7 +1884,7 @@ ConfigView.section.style.dataStatsOnly=Show data statistics only (hide protocol
 ConfigView.section.style.separateProtDataStats=Show separate data and protocol statistics as 'data (protocol)'
 MyTorrentsView.dialog.setFilter.title=Modify Filter
 MyTorrentsView.dialog.setFilter.text=The %1 section will be filtered by the text you specify below.  Use the | (pipe) symbol to filter on multiple phrases. 
-MyTorrentsView.filter.tooltip=Ctrl+X to switch between RegEx and normal search modes.\nUse the | (pipe) symbol to filter on multiple phrases.
+MyTorrentsView.filter.tooltip=Use the '|' symbol to filter on multiple phrases.\nCtrl+X to switch between RegEx and normal search modes.\nIn RegEx mode prefix with '!' for 'not'.\nPrefix with\n\t'c:' to search comments\n\t't:' for tracker hosts\n\t'f:' to search file names
 MyTorrentsView.clearFilter.tooltip=Clear Filter
 MyTorrentsView.menu.filter=Filter List...
 ConfigView.section.file.resume.recheck.all=On crash-restart check entire file for completed pieces (Otherwise only pieces active at last save are checked)
@@ -1925,7 +1910,7 @@ Plugin.localtracker.networks=\ \ \ \ Local networks
 
 MainWindow.menu.view.plugins.logViews=Log Views
 
-SpeedView.stats.autospeed=Automatic Upload Speed
+SpeedView.stats.autospeed=Automatic Upload Speed (Display capped at %1 ms)
 SpeedView.stats.autospeed.disabled=This Feature is either disabled (you need the DHT) or not in use (manual upload speed selected)
 SpeedView.stats.idlePing=Idle Ping:
 SpeedView.stats.maxPing=Max Ping:
@@ -1985,7 +1970,7 @@ DHTTransport.report.send_complete=send complete
 DHTTransport.report.send_timeout=send timeout
 
 ConfigView.section.transfer.autospeed.enabledebug=Log debug information
-TableColumn.header.date_added=Date added
+TableColumn.header.date_added=Date Added
 TableColumn.header.date_added.info=Date the torrent was added
 
 ConfigView.section.file.hashchecking.smallestfirst=Recheck smallest downloads first
@@ -2006,6 +1991,8 @@ platform.win32.baddll.AxShlex=Alcohol 120%
 platform.win32.baddll.iFW_Xfilter=iolo Personal Firewall
 platform.win32.baddll.gapsp=Neoteris
 platform.win32.baddll.WSOCKHK=Net Nanny
+platform.win32.baddll.InjHook12=Torrent Ratio Keeper
+platform.win32.baddll.FPServiceProvider=FoxyProxy Video Utility
 
 upnp.ignorebaddevices=Ignore devices that fail to respond correctly
 upnp.ignorebaddevices.info=Currently ignored devices: %1
@@ -2042,7 +2029,7 @@ natpmp.info=NAT-PMP is Apple's alternative to UPnP and is supported by recent Ai
 natpmp.enable=Enable (note that it must also be enabled in the Airport configuration to work)
 
 ConfigView.section.tracker.host.addurls=Ensure this tracker's URLs are present in hosted torrents
-ConfigView.filter=search for options here
+ConfigView.filter=type filter text
 ConfigView.section.files.move=Completion Moving
 ConfigView.section.file.defaultdir.section=Default Directory Options
 ConfigView.section.file.defaultdir.auto=Automatically download to default directory (No Prompt)
@@ -2122,30 +2109,19 @@ UIDebugGenerator.complete.text=The debug file can be found at '%1'.\n\nClick OK
 ConfigView.section.style.showProgramIcon=Show program icon in name column
 ConfigView.section.style.showProgramIcon.tooltip=View may need re-opening for changes to take effect
 
-swt.alert.cant.update=SWT library loaded from "%3" can't be automatically updated from version %1 to %2 (must be loaded from "%4"). Please see <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">the wiki</A> for details.
+swt.alert.cant.update=SWT library loaded from "%3" can't be automatically updated from version %1 to %2 (must be loaded from "%4"). Please see <A HREF="http://wiki.vuze.com/w/SWT_Cant_Auto_Update">the wiki</A> for details.
 authenticator.savepassword=Remember my password
 ConfigView.section.security.clearpasswords=Reset remembered passwords
 ConfigView.section.security.clearpasswords.button=Reset
 
-Content.alert.notuploaded.title=Upload Not Complete
-Content.alert.notuploaded.text=Upload of '%1' is not complete. If you %2 now, people will not be able to completely download your published work.\n\nAre you sure you want to %2?
-Content.alert.notuploaded.multi.title=Uploads Not Complete
-Content.alert.notuploaded.multi.text=%1 of your published content are not completely seeded. If you %2 now, people will not be able to completely download your published work. Are you sure you want to %2?\n\nContent not completely seeded:\n%3
-Content.alert.notuploaded.stop=stop
-Content.alert.notuploaded.quit=quit Vuze
-
 TorrentInfoView.torrent.encoding=Torrent encoding
-TorrentInfoView.columns=Columns from 'My Torrents' view
+TorrentInfoView.columns=Columns from '{library.name}' view
 
 progress.window.title=Operation In Progress
 progress.window.msg.filemove=Please wait while the file move/rename completes
 
 ConfigView.label.popup.timestamp=Add timestamps to popup alerts
 ConfigView.label.popup.autohide=Automatically hide non-error popup alerts after x seconds (set to 0 to disable auto hiding)
-ConfigView.label.popup.suppress_alerts=Suppress alerts
-ConfigView.label.popup.use_message_boxes=Use popup message boxes rather than the standard popup alert box.
-ConfigView.label.popup.show=Show all popup alerts logged so far (if any)
-ConfigView.label.popup.show.button=Show
 
 ConfigView.label.please.visit.here=Please visit here for details
 ConfigView.section.ipfilter.enable.descriptionCache=Store IP descriptions in scratch file
@@ -2154,9 +2130,9 @@ ConfigView.section.ipfilter.enable.descriptionCache.tooltip=When disabled, descr
 OpenTorrentWindow.filesInfo=%1 of %2 will be downloaded.
 OpenTorrentWindow.diskUsage=%1 of %2
 
-ConfigView.label.openmytorrents=Open 'My Torrents' on startup
+ConfigView.label.openmytorrents=Open '{library.name}' on startup
 ConfigView.label.open_transfer_bar_on_start=Open Transfer Bar on startup
-ConfigView.section.style.DNDalwaysInIncomplete=Always show torrents with 'Do Not Download' files in Incomplete section of My Torrents  
+ConfigView.section.style.DNDalwaysInIncomplete=Always show torrents with 'Do Not Download' files in Incomplete section of {library.name}  
 
 OpenTorrentWindow.mb.noGlobalDestDir.title=Destination Directory not found
 OpenTorrentWindow.mb.noGlobalDestDir.text=The destination directory '%1' is invalid.
@@ -2228,7 +2204,7 @@ Peers.column.maxdownspeed=Max Down Speed
 MyTorrents.items.DownSpeedLimit.disabled=No download
 
 Peers.column.lan=LAN
-upnp.selectedaddresses=Addresses (';' seperated, '-' prefix=deny, '+' =allow) [blank: any]
+upnp.selectedaddresses=Addresses (';' separated, '-' prefix=deny, '+' =allow) [blank: any]
 upnp.alert.multipledevice.warning=Multiple UPnP devices have been detected - check if all require port mapping (see UPnP log and configuration)
 
 UpdateMonitor.messagebox.restart.title=Software Update
@@ -2317,16 +2293,15 @@ SpeedTestWizard.stage.message.connect.stats=Connection stats: peers=%1, down_ok=
 window.uiswitcher.title=Vuze UI Chooser
 window.uiswitcher.text=Please select a user interface below that best suits your needs.
 window.uiswitcher.NewUI.title=Vuze
-window.uiswitcher.NewUI.text=* Recommended for beginners and new users.\n\n* Easy, intuitive graphical interface\n\n* Required interface to publish on Vuze platform
+window.uiswitcher.NewUI.text=* Recommended for beginners and new users.\n\n* Easy, intuitive graphical interface
 window.uiswitcher.ClassicUI.title=Classic Interface
-window.uiswitcher.ClassicUI.text=* Retains functionality of 2.x series client\n\n* Vuze content layer will not be loaded
-window.uiswitcher.bottom.text=Your selection can easily be changed again by selecting the Vuze UI Chooser button
+window.uiswitcher.ClassicUI.text=* Retains functionality of 2.x series client\n\n* Classic tabbed display
 iconBar.switch.tooltip=Vuze UI Chooser
 
 VivaldiView.notAvailable=Vivaldi View not available
 
 restart.error=Restart failed:\n%1\nSee <A HREF="{restart.error.url}">restarting issues</a>.
-restart.error.url=http://www.azureuswiki.com/index.php/Restarting_Issues
+restart.error.url=http://wiki.vuze.com/w/Restarting_Issues
 restart.error.oom=Out of Memory
 restart.error.fnf='%1' not found in '%2'
 restart.error.pnf=Path '%1' not found
@@ -2414,29 +2389,12 @@ and use the (X) button on the Published Content panel in the Publish tab.\
 v3.mb.delPublished.delete=&Delete
 v3.mb.delPublished.cancel=&Cancel
 
-
-v3.mb.openFile.title=Open File
-v3.mb.openFile.text.known=This content is not currently supported by the Vuze Player. Check the community-created <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> for help.\n\nFile Type Appears to be: %2 (%3)\n
-v3.mb.openFile.text.unknown=This content is not currently supported by the Vuze Player.  Check the community-created <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> for help.\n\nFile Extension : %2\n
-v3.mb.openFile.button.play=Play
-v3.mb.openFile.button.cancel=Cancel
-v3.mb.openFile.button.guide=Read Playback Guide
-v3.mb.openFile.remember=Always open files without asking me
-v3.mb.openFile.guideurl=http://www.azureuswiki.com/index.php/Playback_Guide
-
 v3.mb.PlayFileNotFound.title=File Not Found
 v3.mb.PlayFileNotFound.text=The files for '%1' are either deleted or missing.
 v3.mb.PlayFileNotFound.button.remove=Remove from Vuze
 v3.mb.PlayFileNotFound.button.redownload=Redownload Data
 v3.mb.PlayFileNotFound.button.find=Manually Find..
 
-v3.mb.deletePurchased.title=Remove Purchased Content
-v3.mb.deletePurchased.text=Are you sure you want to delete the content '%1'?\
-\n\n\
-This is content you either purchased, or you were required to login to download.
-v3.mb.deletePurchased.button.delete=&Delete
-v3.mb.deletePurchased.button.cancel=&Cancel
-
 v3.topbar.menu.show.logo=Logo
 v3.topbar.menu.show.plugin=Plugin Area
 v3.topbar.menu.show.search=Search
@@ -2547,13 +2505,13 @@ It is highly recommended that you quit Vuze now and switch to this script \
 ('%2').\
 \n\n\
 If you have heavily modified your Vuze startup script, please see \
-<A HREF="{unix.script.new.manual.url}">AzureusWiki: Unix Script</A>.\
+<A HREF="{unix.script.new.manual.url}">VuzeWiki: Unix Script</A>.\
 \n\n\
 If you installed Vuze from a distro (yum, apt-get, etc), \
 it's recommended you re-install Vuze using the package on \
-<A HREF="http://azureus.sourceforge.net">Vuze Sourceforge Page</A> \
+<A HREF="http://www.vuze.com/download/">Vuze Download Page</A> \
 (You will still get the same UI you have now)
-unix.script.new.manual.url=http://azureuswiki.com/index.php/Unix_Startup_Script
+unix.script.new.manual.url=http://wiki.vuze.com/w/Unix_Startup_Script
 unix.script.new.button.quit=Quit Now
 unix.script.new.button.continue=I'll Do It Later
 unix.script.new.button.asknomore=Don't Tell Me Again
@@ -2562,8 +2520,6 @@ unix.script.new.auto.title=New Vuze Startup Script
 unix.script.new.auto.text=A new Vuze Startup Script is available.\n\n\
 It is highly recommended that you restart Vuze now.
 
-Content.alert.notuploaded.button.stop=&Stop
-Content.alert.notuploaded.button.continue=&Continue Seeding
 Content.alert.notuploaded.button.abort=&Don't Quit
 
 ConfigView.label.checkOnSeeding=Perform low resource re-check of pieces when seeding
@@ -2588,7 +2544,7 @@ ConfigTransferAutoSpeed.auto.speed.beta=Auto-Speed(beta)
 ConfigTransferAutoSpeed.data.update.frequency=Update Frequency
 
 Alert.failed.update=Installation of at least one component failed. See <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
-Alert.failed.update.url=http://azureuswiki.com/index.php/Failed_Update
+Alert.failed.update.url=http://wiki.vuze.com/w/Failed_Update
 
 OpenTorrentWindow.mb.existingFiles.partialList= (Partial list.  More files already exist)
 
@@ -2640,7 +2596,7 @@ Progress.reporting.no.history.to.display=There are no detail messages to display
 Progress.reporting.detail.history.limit=The detail message limit (%1) for this ProgressReporter has been exceeded; subsequent messages will not be added to history
 Progress.reporting.statusbar.button.tooltip=Show the Progress Reporting Window
 
-webui.bindip=Bind IP - normally not required (*)
+webui.bindip=Bind IP - normally not required
 
 v3.MainWindow.text.log.in=Sign In
 v3.MainWindow.text.log.out=Sign Out
@@ -2657,8 +2613,8 @@ Progress.reporting.window.remove.now.tooltip=Remove all completed, failed, or ca
 
 dhttracker.tracklimitedwhenonline=However, perform low resource tracking when online for swarm cross-population
 
-TorrentOptionsView.multi.title.short=Torrent Options
-TorrentOptionsView.multi.title.full=Torrent Options
+TorrentOptionsView.multi.title.short=Torrent(s) Options/Info
+TorrentOptionsView.multi.title.full=Torrent(s) Options/Info
 
 MyTorrentsView.menu.open_parent_folder=Open Containing Folder
 ConfigView.section.style.use_show_parent_folder=Use "%1" instead of "%2" in torrent menus
@@ -2668,7 +2624,7 @@ PeerManager.status.ps_disabled=Tracker peer source is disabled
 ConfigView.section.stats.exportfiles=Export file details
  
 updater.cant.write.to.app.title=Can't Write To Application Folder
-updater.cant.write.to.app.details=The folder "%1" is not writable.\n\nThis will prevent future software updates from being applied.\n\nPlease <a href="http://www.azureuswiki.com/index.php/Failed_Update">see the wiki for details</a>.
+updater.cant.write.to.app.details=The folder "%1" is not writable.\n\nThis will prevent future software updates from being applied.\n\nPlease <a href="http://wiki.vuze.com/w/Failed_Update">see the wiki for details</a>.
 
 plugin.install.class_version_error=This plugin requires a newer version of Java to run.
 
@@ -2705,12 +2661,6 @@ OpenTorrentWindow.mb.notTorrent.cannot.display=Unable to properly display the da
 MainWindow.menu.window.zoom.maximize=Maximize
 MainWindow.menu.window.zoom.restore=Restore
 
-ImageResizer.image.too.small=The image provided is too small, please choose a different one (has to be at least %1 x %2)
-ImageResizer.title=This tool lets you preview how your thumbnail is going to look like on the Vuze Platform
-ImageResizer.move.image=Move the image by dragging it
-ImageResizer.move.image.with.slider=Move the image by dragging it, resize it by using the slider below
-
-
 security.crypto.title=Encryption Key Access
 security.crypto.encrypt=Please enter a password to protect your newly generated encryption key. Please do not forget this password, there is no way of recovering it if you do!
 security.crypto.decrypt=Please enter the password to unlock your encryption key.
@@ -2822,10 +2772,6 @@ metasearch.addtemplate.dup.desc=Search template %1 is already installed
 metasearch.export.select.template.file=Save Template
 metasearch.import.select.template.file=Open Template
 
-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
-
 azbuddy.tracker.enabled=Enable 'Friends Boost' to prioritise downloading with your friends 
 azbuddy.protocolspeed=KB/s max friend protocol overhead
 
@@ -2894,8 +2840,8 @@ subscript.add.upgrade.title=Upgrade Subscription?
 subscript.add.upgrade.desc=Are you sure you want to upgrade subscription '%1'?
 subscript.add.upgradeto.desc=Version %1 of subscription '%2' is available.\nDo you want to update?
 
-azsubs.contextmenu.addassoc=Add subscription association
-azsubs.contextmenu.lookupassoc=Lookup subscription associations
+azsubs.contextmenu.addassoc=Add Subscription Association
+azsubs.contextmenu.lookupassoc=Lookup Subscription Associations
 
 iconBar.start=Start
 iconBar.stop=Stop
@@ -2904,8 +2850,8 @@ iconBar.up=Up
 iconBar.down=Down
 iconBar.run=Launch
 iconBar.editcolumns=Column Setup
-iconBar.top=Move top
-iconBar.bottom=Move bottom
+iconBar.top=Top
+iconBar.bottom=Bottom
 iconBar.queue=Start
 iconBar.open=Add Torrent
 iconBar.share=Share
@@ -2951,9 +2897,7 @@ TableColumn.header.Thumbnail.info=The thumbnail image for Vuze content; for all
 
 v3.MainWindow.menu.getting_started=&Getting Started
 MainWindow.menu.community=&Community
-MainWindow.menu.help.faq=&Frequently Asked Questions (FAQ)
-MainWindow.menu.help.faq.keybinding.mac=Meta+?
-MainWindow.menu.community.wiki=Community &Wiki
+MainWindow.menu.community.wiki=Community &Wiki && FAQ
 MainWindow.menu.community.forums=Community Fo&rums
 MainWindow.menu.community.blog=Vuze &Blog
 MainWindow.menu.help.support=&Help and Support
@@ -2973,8 +2917,8 @@ Subscription.menu.forcecheck=Update Now
 Subscription.menu.clearall=Mark All Results As Read
 Subscription.menu.remove=Delete
 
-sidebar.Library=My Library
-sidebar.LibraryDL=Downloading
+sidebar.Library={library.name}
+sidebar.LibraryDL=Downloading...
 sidebar.LibraryCD=Completed
 
 MySeeders.bigView.header={sidebar.LibraryCD}
@@ -2987,7 +2931,7 @@ v3.MainWindow.menu.showActionBarText=Show Text
 
 subscript.import.fail.title=Import Failed
 subscript.import.fail.desc=Details: %1
-Subscription.menu.export=Export
+Subscription.menu.export=Export...
 subscript.export.select.template.file=Save Subscription
 
 Button.remove=Remove
@@ -2995,7 +2939,7 @@ Button.send=Send
 Button.back=Back
 
 
-sidebar.LibraryUnopened=Unwatched
+sidebar.LibraryUnopened=New
 TableColumn.header.unopened=New
 Unopened.bigView.header=New
 
@@ -3043,13 +2987,13 @@ Wizard.Subscription.rss.subtitle3=Once saved, you'll receive live updates in you
 Wizard.Subscription.subscribe.library=Content in your Library
 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>
+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://wiki.vuze.com/w/FAQ_Subscriptions">Read more</A>
 
 
 message.confirm.delete.title=Confirm Delete
 message.confirm.delete.text=Are you sure you want to delete '%1'?\
 
-Subscription.menu.properties=Properties
+Subscription.menu.properties=Properties...
 props.window.title=Properties for '%1'
 
 subs.prop.enabled={azbuddy.enabled}
@@ -3094,14 +3038,13 @@ subscription.version.bad=Subscription '%1' can't be installed until you upgrade
 
 statusbar.feedback=Send Feedback   
 statusbar.feedback.tooltip=Click here to send feedback
-UnopenedView.header={Unopened.bigView.header}
 
 sidebar.Activity=Notifications
 
 v3.activity.button.watchall=Mark All Watched
 
 subscriptions.view.help.1=Add Subscriptions wherever you see
-subscriptions.view.help.2=Get free live updates whenever new content is available for download. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Learn More</A>.
+subscriptions.view.help.2=Get free live updates whenever new content is available for download. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Learn More</A>.
 
 sidebar.sash.tooltip=F7 to quicky hide/show sidebar
 sidebar.expand.tooltip=Expand the Sidebar
@@ -3165,15 +3108,6 @@ azbuddy.ui.menu.cat_subs=Subscribe
 subs.prop.update_period=Update period
 azbuddy.enable_cat_pub=Public categories that ALL your friends can subscribe to (',' separated) 
 
-v3.dialog.cnclose.title=%1 Closed
-v3.dialog.cnclose.subtitle=Notification
-v3.dialog.cnclose.info1=You have closed an HD Network
-v3.dialog.cnclose.info2=If you would like to reopen this HD Network, you may do so in the "HD Networks" menu at the top of your screen. 
-v3.dialog.cnclose.noshow=Do not show again
-
-v3.dialog.cnmanage.title=Manage HD Networks Menu
-v3.dialog.cnmanage.intro=You can choose from the list below which content networks you wish to display in the "HD Networks" menu
-
 azbuddy.ui.table.read_cat=Cat read
 
 TableColumn.header.#=#
@@ -3311,7 +3245,7 @@ devices.downloading=Downloading
 TableColumn.header.duration=Duration
 TableColumn.header.resolution=Resolution
 devices.xcode.autoStart=Automatically Start When Needed
-option.askeverytime=Ask every time
+option.askeverytime=Ask Every Time
 option.rememberthis=Remember this setting
 devices.associate=Associate With
 devices.associate.already=Already associated
@@ -3343,7 +3277,7 @@ xcode.deletedata.title=Delete Transcoded Content
 xcode.deletedata.message=Are you sure you want to permanently delete the copy of '%1' transcoded for '%2'%3?
 xcode.deletedata.message.2=\n(a copy may still exist in '%1')
 v3.deviceview.infobar.line1=Drag-and-drop videos from your Library to the device of your choice.
-v3.deviceview.infobar.line2=Play your videos on any of your screens - iPhone, iPod, TV
+v3.deviceview.infobar.line2=Play your videos on any of your screens - iPad, iPhone, iPod, TV
 v3.deviceview.infobar.line1.generic=Drag-and-drop videos from your Library to %1 in your Sidebar.
 v3.deviceview.infobar.line2.itunes=Videos will appear in your iTunes Movies folder when they're ready to play.
 v3.deviceview.infobar.line2.xbox=Stream videos by going to your Xbox 360 and selecting My XBox -> Video Library -> Vuze.
@@ -3359,7 +3293,7 @@ device.config.xcode.workdir=Default working directory for transcoded files
 MyTorrentsView.menu.clear_alloc_data=Clear Allocation State
 DiskManager.error.nospace=Insufficient disk space
 DiskManager.error.nospace_fat32={DiskManager.error.nospace} - check {wiki.fat32}
-wiki.fat32=http://www.azureuswiki.com/index.php/FAT32_file_size_limit
+wiki.fat32=http://wiki.vuze.com/w/FAT32_file_size_limit
 
 ConfigView.section.file.rename.incomplete=Add suffix to incomplete files
 subscriptions.config.auto=Auto-download
@@ -3384,10 +3318,6 @@ device.rss.port=RSS feed port
 device.rss.view=Click to view RSS feed
 device.rss.localonly=Restrict access to this computer only
 
-rcm.rc_tracker.tt=Click to browser the tracker
-rcm.rc_hash.tt=Click to download this content
-rcm.rc_title.tt=Click to search for this content
-
 devices.xcode.autoCopy=Automatically Copy to Folder
 devices.xcode.setcopyto=Set Copy to Folder...
 devices.xcode.setcopyto.title=Choose copy-to location
@@ -3397,7 +3327,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/filter bar in Library (My Torrents)
+ConfigView.label.alwaysShowLibraryHeader=Always show header/filter bar in {library.name}
 devices.cat.show=Show categories
 devices.tivo.machine=TiVo machine name
 
@@ -3459,15 +3389,17 @@ devices.od.turnon.text3=Please connect a Hard Drive to the %1 to turn on this fe
 devices.od.turnon.learn=Learn more >
 devices.router=router
 devices.od=offline downloader
-webui.pairingenable=Enable pairing
+webui.pairingenable=Enable pairing for this plugin (test options will be enabled once the current pairing details are successfully published)
 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.ipv4=Public IPv4 address
+pairing.ipv6=Public IPv6 address
+pairing.local.ipv4=Local IPv4 address
+pairing.local.ipv6=Local IPv6 address
 pairing.host=Host address (DNS name)
 
 pairing.group.explicit=Explicit Attributes
@@ -3485,36 +3417,15 @@ 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 (*)
+webui.enable=Enable
 ConfigView.section.rss=Local RSS etc.
-subscriptions.rss.enable=Create RSS Feeds from subscrptions
+subscriptions.rss.enable=Create RSS Feeds from subscriptions
 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
@@ -3530,11 +3441,629 @@ ClientStats.column.name={TableColumn.header.name}
 MainWindow.menu.view.clientstats={ClientStats.title.full}
 
 Scrape.status.cached=Cached scrape
-network.ipv6.enable.support=Enable IPv6 support
+network.ipv6.enable.support=Enable IPv6 support (Java7 required under Windows)
 ConfigView.section.plugins.magnetplugin=Magnet URI Handler
 MagnetPlugin.use.lookup.service=Use the Vuze secondary lookup service if magnet lookup via DHT fails
 MagnetPlugin.report.secondarylookup=Trying secondary lookup service
 MagnetPlugin.report.secondarylookup.ok=Secondary lookup succeeded
 MagnetPlugin.report.secondarylookup.fail=Secondary lookup failed: no sources found
 
+TrackerView.title.short=Sources
+TrackerView.title.full=Sources
+Trackers.column.type=Type
+Trackers.column.name=Details
+Trackers.column.status=Status
+Trackers.column.seeds=Seeds
+Trackers.column.seeds.info=Seeds in the swarm
+Trackers.column.leechers=Leechers
+Trackers.column.leechers.info=Leechers in the swarm
+Trackers.column.peers=Peers
+Trackers.column.peers.info=Peers returned by the tracker
+Trackers.column.interval=Interval
+Trackers.column.interval.info=Re-query interval in secs: interval (min interval)
+Trackers.column.updatein=Next
+Trackers.column.updatein.info=Time to next update
+
+tps.status.available=Available
+tps.status.unavailable=Unavailable
+tps.type.dht=DHT
+tps.type.pex=PEX
+tps.lan.details=%1 local clients discovered
+tps.pex.details=Connected to %1 peers (pending: pex=%2, other=%3)
+tps.tracker.cache=Peer cache
+tps.tracker.cache1=Peer cache: used=%1
+dht.status.disabled=Disabled, distributed database not available
+tps.type.incoming=Incoming
+tps.incoming.details=Current: TCP=%1, UDP=%2; Total ever=%3
+tps.type.plugin=Plugin
+
+group.auto=Auto
+ConfigView.label.autoadjust=Automatically adjust these setting based on connection speed
+
+ConfigView.label.start=Startup
+ConfigView.label.stop=Shutdown
+ConfigView.label.start.onlogin=Start Vuze on login
+ConfigView.label.stop.seedcomp=When seeding is complete
+ConfigView.label.stop.downcomp=When downloading is complete
+ConfigView.label.stop.Nothing=Do Nothing
+ConfigView.label.stop.QuitVuze=Shutdown Vuze
+ConfigView.label.stop.Sleep=Standby Computer
+ConfigView.label.stop.Hibernate=Hibernate Computer
+ConfigView.label.stop.Shutdown=Shutdown Computer
+
+core.shutdown.alert=Action '%1' triggered as %2
+core.shutdown.dl=downloads completed
+core.shutdown.se=seeding completed
+
+pairing.last.error=Last error
+MainWindow.menu.pairing=Remote Pairing
+
+ConfigView.section.startstop={ConfigView.label.start} & {ConfigView.label.stop}
+ConfigView.label.pauseresume=Auto-pause/resume
+
+update.now.title=Update Required
+update.now.desc=Vuze needs to apply updates to complete migration.\n\nAfter closing this dialog you may be prompted by Windows to complete the update process.\n\nA restart of Vuze will NOT be required.
+
+ConfigView.label.jvm=Java Options
+
+platform.jvmopt.sunonly=Only Sun JVMs are supported (current vendor=%1)
+platform.jvmopt.configerror=Can't manage the JVM options due to a configuration error
+platform.jvmopt.nolinkfile=Can't manage the JVM options as migration is not complete
+platform.jvmopt.nolink=Can't manage the JVM options as prohibited by existing configuration
+platform.jvmopt.accesserror=Failed to access JVM options file: %1
+
+pairing.status.noservices=No remote services enabled
+webui.pairingtest=\tClick to test pairing
+webui.connectiontest=\tClick to test connection
+ConfigView.section.connection.pairing.url=http://wiki.vuze.com/w/UG_Options#Pairing
+
+jvm.info=A restart of Vuze is required if options are amended. *** Warning - amending the JVM options incorrectly can cause Vuze to fail to start or perform poorly ***\n
+jvm.show.file=The local JVM options file is '%1' - Only edit directly for recovery purposes
+jvm.reset=Reset JVM options to installation defaults
+jvm.error=There was an error access the JVM options: %1
+jvm.max.mem=Max Heap memory size [blank=default,min=%1]
+jvm.min.mem=Min Heap memory size [blank=default,min=%1]
+ConfigView.section.invalid.value.title=Invalid Value
+ConfigView.section.invalid.value=Invalid value '%1' entered for '%2': %3
+
+Button.dismiss=Dismiss
+webui.pairing.autoauth=Enable default password protection: username=vuze, password=<pairing access code>
+
+ConfigView.label.stop.autoreset=Automatically reset actions to '%1' once triggered
+
+remote.pairing.title=Remote Pairing
+remote.pairing.subtitle=Vuze Remote gives you the power to control Vuze from any computer or mobile browser - anytime, anywhere.
+remote.pairing.instruction=Simply enter the code below into the spaces provided in any remote app.
+remote.pairing.functions=<A HREF="clip">Copy code to clipboard</A>   |   <A HREF="new">Get a new code</A>
+remote.pairing.tip.title=Tip: Two easy ways to use Vuze Remote:
+remote.pairing.tip.text=Vuze Remote Toolbar: Go to <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\n\
+Vuze Remote Mobile: Go to <A HREF="http://remote.vuze.com/">remote.vuze.com</A> in your mobile browser.
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">Pairing FAQs</A>
+remote.pairing.accesscode=Access Code:
+remote.pairing.test.running=Testing remote connectivity...
+remote.pairing.test.success=Vuze is accessible via remote.
+remote.pairing.test.unavailable=Oops, couldn't determine your remote connectivity. <A HREF="retry">Try again</A>
+remote.pairing.test.fail=Vuze isn't accessible outside your local network.  <A HREF="/pairing_error_faq.start">Learn more</A>
+
+update.fail.app.changed.title=Update Failure
+update.fail.app.changed=Vuze needs to be upgraded but the process can not be performed automatically as the application name has been changed to '%1'.\n\nPlease go to http://www.vuze.com/ and download the latest installer.
+webui.port.override=Port override: only required if public port differs from internal due to NAT configuration
+
+MainWindow.status.warning.tooltip=Click here for details
+
+search.dialog.text=Enter text to search for new torrents:
+
+core.not.available=Vuze is still initialising, please try again when it has completed
+
+dlg.auth.title=Activation
+
+dlg.auth.enter.subtitle.try.1=Almost there.
+dlg.auth.enter.line.try.1=Enter your activation code below to complete your upgrade to Vuze Plus.
+dlg.auth.enter.line.try.2=Sorry, we couldn't validate your activation code. Please check the number and try entering it again.
+dlg.auth.enter.prompt=Vuze Plus Activation Code:
+
+Button.validate=Validate
+Button.getstarted=Get Started
+Button.install={swt.install.window.ok}
+Button.goLibrary=Go to {library.name}
+
+dlg.auth.success.subtitle=Congratulations!
+dlg.auth.success.line1=Thank you for upgrading to Vuze Plus.
+dlg.auth.success.line2=You are now able to burn unlimited playable DVDs, scan your files for viruses, and stream videos you are downloading - all with no ads!
+dlg.auth.trial.success.line1=Vuze is ready to create DVDs.
+dlg.auth.trial.success.subtitle=DVD Burn is Ready
+dlg.auth.trial.success.info=Drag video files from your library into "Create New DVD." If you had already added a video before installing the components, please add it again.
+
+dlg.auth.revoked=Activation Code Revoked
+dlg.auth.revoked.line1=Your Vuze Plus Activation Code has been revoked. Please click below to get more information.
+dlg.auth.revoked.link=<A HREF="info">Information on Revoked Activation codes</A>
+
+dlg.auth.denied=Activation Code Denied
+dlg.auth.denied.line1=Your Vuze Plus Activation Code has been denied. Please click below to get more information.
+dlg.auth.denied.link=<A HREF="info">Information on Denied Activation codes</A>
+
+dlg.auth.cancelled=Activation Code Cancelled
+dlg.auth.cancelled.line1=Your Vuze Plus Activation has been cancelled.
+dlg.auth.cancelled.line2=If you feel this is in error, please contact support via the directions in your receipt e-mail.
+
+dlg.auth.enter.subtitle.try.2=Validation failed
+dlg.auth.enter.link.try.2=<A HREF="link">Click here</A> if you haven't purchased your copy of Vuze Plus yet.
+dlg.auth.enter.link.try.1=Don't have an activation code? <A HREF="upgrade">Upgrade now</A>.
+dlg.auth.enter.expiry=Current activation code expires on %1.
+dlg.auth.enter.revoked=Current activation code has been revoked.
+dlg.auth.enter.cancelled=Current activation code has been cancelled.
+dlg.auth.enter.denied=Current acivation code has been denied.
+
+dlg.auth.validating.subtitle=Validating...
+
+dlg.try.trial.title=Try DVD Burn
+dlg.try.trial.text=Vuze needs to install the plugin necessary to burn playable DVDs from your videos.  Click Turn On to proceed.
+dlg.auth.tos=I have read and accepted the <A HREF="tos">Terms of Service.</A>
+
+dlg.auth.install=
+dlg.auth.install.subtitle.plus=Installing Vuze Plus...
+dlg.auth.install.subtitle.trial=Installing DVD Burn
+dlg.auth.install.progress=Installing %1 components...
+dlg.auth.install.pct=%1% done
+
+mdi.entry.plus.full=Vuze Plus
+mdi.entry.plus.free=Vuze Plus
+mdi.entry.dvdburn=DVD Burn
+mdi.entry.dvdburn.new=Create New DVD
+
+menu.plus=Vuze Plus
+menu.register=Vuze Plus Activation
+
+dlg.auth.trial.title=DVD Burn Trial
+
+dlg.player.install.subtitle=Installation
+dlg.player.install.description=Installing additional playback component...
+
+devices.xcode.remove.vetoed=Transcoding of '%1' is in progress, the download can not be removed until this is complete or the transcode is cancelled from the 'Devices' page.
+
+Button.agree=I Agree
+
+dlg.auth.install.failed.title=Activation Failed
+dlg.auth.install.failed.text=Activation of code '%1' failed due to a server error.\n\nPlease retry the activation later (reported error was '%2')
+ 
+device.status.online=Device is online
+device.itunes.status.running=iTunes is running
+device.itunes.status.notrunning=iTunes is not running
+device.itunes.status.notinstalled=iTunes is not installed
+
+OpenTorrentWindow.mb.notTorrent.retry=Magnet Lookup
+ConfigView.section.ipfilter.clear.on.reload=Clear filters when reloading. During the reload process IPs will not be blocked. If unchecked, recent un-blocks will not take effect until restart.
+view.waiting.core=View will be available once Vuze Core is done loading..
+
+devices.profile.direct=Direct
+cat.autoxcode=Auto-Device
+ConfigView.section.tables=Tables
+ConfigView.section.style.useTree=Show Files in {library.name} views (Requires Restart)
+ConfigView.section.mode.resetdefaults=Reset configuration to default values (restart recommended)
+resetconfig.warn.title=Confirm Action
+resetconfig.warn=This will result in all modifications you have made to your Vuze configuration being lost.\nProceed with configuration reset?
+
+ConfigView.label.xfer.bias_up=Increase download speeds by biasing upload capacity to incomplete downloads
+ConfigView.label.xfer.bias_slack=KB/s minimum reserved for complete downloads
+ConfigView.label.xfer.bias_no_limit=Attempt to apply bias when there is no effective global upload limit
+ 
+SpeedView.stats.upload=Upload data queued:
+SpeedView.stats.upload_details=%1
+SpeedView.stats.con=Connection details:
+SpeedView.stats.con_details=total=%1, unchoked=%2, queued=%3, blocked=%4
+
+SpeedView.stats.upbias=Upload bias:
+ 
+dlg.install.mlab.subtitle=Installing
+dlg.install.mlab.description=Please wait while the speed test component is installed
+ 
+dial.up=Dial Up 
+auto.mode=Auto (recommended)
+manual.mode=Manual
+configureWizard.transfer2.hint=Setting your upload limit too high or too low will affect download performance!
+configureWizard.transfer2.message=Bittorrent is based on a tit-for-tat protocol - in general the faster you upload, the faster you download - so to download fast, and quickly get a good share ratio, you need a good upload speed.\n\nHowever, if you upload too fast for your connection, you can overload it resulting in slower overall throughput and impacts on other applications contending for network resources.\n\nIt is therefore important to set a balanced upload limit.\n\nUse this panel t [...]
+configureWizard.transfer2.group=Mode
+configureWizard.transfer2.test.info=Select to perform a comprehensive speed test
+configureWizard.transfer2.test=Run Test
+configureWizard.transfer2.mselect=Select your connection UPLOAD speed limit
+configureWizard.transfer2.mselect.info=The xxx/<value> entries denote an upload connection speed of <value> bits-per-second.\nFor example, if you have an ADSL connection with 768 Kbps downstream speed and 384 Kbps upstream, select 'xxx/384 kbit/sec'.\nRound down to the nearest value if your exact speed isn't shown.
+configureWizard.transfer2.rate.unchanged=Current settings will be used
+configureWizard.transfer2.rate.changed=Connection limit=%1\nApplied limit will be %2 (max active torrents=%3, max downloading=%4)
+
+speedtest.wizard.select.title=Select the type of speed test to run
+speedtest.wizard.select.group=Test Type
+speedtest.wizard.select.general=General speed test (recommended)
+speedtest.wizard.select.bt=Bittorrent specific speed test
+
+FileItem.storage.reorder=Reorder
+ConfigView.label.piecereorder=Append data to files as downloaded and reorder pieces as the download progresses.
+ConfigView.label.piecereorderminmb=Only reorder files larger than this (in MB)
+
+configureWizard.transfer2.current=<Current Settings>
+
+ConfigView.section.style.extendedErase=Draw grid lines and fill blank areas
+
+iconBar.stream=Play Now
+FilesView.menu.setpriority.numeric=Numeric...
+FilesView.dialog.priority.title=Enter Numeric Priority
+FilesView.dialog.priority.text=0=Normal, 1=High, 2=Higher...
+
+beta.wizard.title=Beta Version Setup
+beta.wizard.intro.title=Enrollment selection
+beta.wizard.info=Enrolling in the Vuze beta program gives you early access to the up-and-coming features in the client.\n\nThis gives you a chance to experiment with these features and help shape the way they are implemented - your feedback is hugely useful to us!\n\nBy their nature beta versions can be unstable, however selecting this option will give you access to relatively stable releases. If you want bleeding edge builds then please use the existing 'Beta Updater' plugin.
+beta.wizard.link=Click here to access the beta release web page 
+beta.wizard.link.url=http://dev.vuze.com
+beta.wizard.off=I'm happy with release versions, no thanks!
+beta.wizard.on=Update me with the latest stable beta versions please.
+beta.wizard.version=You are currently running version %1
+beta.wizard.disable.title=Reinstall Required
+beta.wizard.disable.text=Thank you for trying the beta versions!\n\nPlease download and install the latest release version to leave the beta program
+beta.wizard.forum=Use the Vuze forums to give feedback and  report bugs
+beta.wizard.forum.url=http://www.vuze.com/forum_beta.start
+
+dlg.install.vuzexcode.subtitle=Installing Media Analyzer component
+dlg.install.vuzexcode.description=Please wait while the Media Analyzer component is installed
+
+dlg.install.azemp.subtitle={dlg.player.install.subtitle}
+dlg.install.azemp.description={dlg.player.install.description}
+
+TableColumn.header.filecount=Files
+TableColumn.header.torrentspeed=Speed
+
+FileProgress.deleted=Deleted
+FileProgress.stopped={ManagerItem.stopped}
+priority.high=High Priority
+priority.normal=Normal Priority
+label.wrap.text=Wrap Text
+ScrapeInfoView.title=Primary Tracker
+Column.seedspeers.started=%1 of %2
+Column.seedspeers.notstarted=%2
+Column.seedspeers.started.noscrape=%1
+Column.seedspeers.notstarted.noscrape=
+#connected to more seeds/peers than tracker reports
+Column.seedspeers.started.over=%1
+
+library.all.header.p=%1 items: %2 active
+library.incomplete.header.p=%1 items downloading, %2 waiting to download
+library.unopened.header.p=%1 items
+library.all.header=%1 item: %2 active
+library.incomplete.header=%1 item downloading, %2 waiting to download
+library.unopened.header=%1 item
+
+ConfigView.section.style.status.show_rategraphs=Show rate history graphs under download/upload text
+device.error.mountrequired="%1" Needs Mounting on Your Device
+v3.deviceview.infobar.line2.android=Enable USB mount on your phone to properly transfer the videos.
+
+MyTorrents.column.ColumnProgressETA.compon=Completed on %1
+
+Sidebar.beta.title=Beta Program
+MainWindow.menu.beta.on=Join Beta Program...
+MainWindow.menu.beta.off=Leave Beta Program...
+Button.sendNow=Send Now
+Button.sendManual=Manual Send (create .zip)
+
+deletecontent.also.deletetorrent=Delete .torrent  file as well
+ConfigView.section.file.deletion.section=File Deletion
+ConfigView.section.file.delete.torrent=By default, delete .torrent file when deleting content
+ConfigView.section.file.delete.confirm=Confirm deleting content via Toolbar and Delete key
+menu.delete.options={iconBar.remove}...
+menu.delete.options.keybinding=DEL
+
+MainWindow.menu.view.beta=Beta Program
+
+ConfigView.section.server.enableudpprobe=Enable UDP tracker probe for HTTP trackers
+
+memmon.low.warning=Memory is running low, you have %1 remaining out of %2.\nPerformance will be degraded and ultimately Vuze will stop working\nSee <a href="http://wiki.vuze.com/w/Java_VM_memory_usage">the Wiki</a> for details on how to increase the available memory.
+jvm.max.mem.current=Current Heap maximum is %1
+jvm.max.direct.mem=Max Direct memory size [blank=default,min=%1]
+jvm.max.direct.mem.info=Note: this is setting *Direct* memory, it is more common to need to update the *Heap* memory above
+jvm.options.summary=Summary of current explicit options:
+memmon.heap.auto.increase.warning=Heap memory has been increased to %1. This will take effect when Vuze is restarted.
+device.showGeneric=Show Generic Devices
+
+mdi.entry.games=Games
+v3.MainWindow.menu.games={mdi.entry.games}
+Peers.column.Protocol=Protocol
+devices.copying=Copying to device
+devices.cancel_xcode=Cancel Conversion
+
+sidebar.header.vuze=Vuze
+sidebar.header.transfers=Files
+sidebar.header.devices=Device Playback
+sidebar.header.subscriptions=Subscriptions
+sidebar.header.plugins=Plugins & Extras
+sidebar.header.dvd={mdi.entry.dvdburn}
+mdi.entry.about.devices=In Progress
+mdi.entry.about.plugins=About Plugins
+mdi.entry.about.dvdburn=Get Started
+
+ConfigView.section.file.tb.delete=When deleting via Delete key or Toolbar:
+ConfigView.tb.delete.ask=Ask
+ConfigView.tb.delete.content=Delete without asking
+ConfigView.tb.delete.torrent=Only remove from Library
+
+search.export.all=Export All Search Templates...
+subscriptions.search.enable=Enable searching of subscription results (restart required)
+
+devices.cancel_xcode_del=Cancel Conversion/Remove
+
+subscriptions.add.tooltip=Add Subscription
+subscriptions.overview=Subscriptions Overview
+
+configureWizard.nat.title=NAT / Server Port Test
+configureWizard.nat.message=In order to get the best out of Vuze it's highly recommended to be fully accessible from the internet. \
+This tool lets you test and / or change the ports used to accept incoming connections.\n\n \
+NOTE: TCP port 6880 is reserved internally, so it cannot be used.
+configureWizard.nat.server.udp_listen_port=Incoming UDP Listen Port
+
+v3.menu.device.defaultprofile.never=Never Transcode
+
+subscriptions.info.avail=You haven't added any subscriptions yet. %1 are available for your library.
+
+subscriptions.dl_subs.enable=Download subscriptions from other clients when needed
+
+# Will be used for {library.name} in classic view
+library.name._classic=My Torrents
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Library
+ConfigView.section.style.units=Display Units
+ConfigView.section.style.library={library.name}
+ConfigView.section.style.CatInSidebar=Show Categories in Sidebar
+library.category.header=Category '%1'
+
+device.import.title=Import Device?
+device.import.desc=Are you sure you want to import device '%1'?
+device.import.dup.title=Duplicate Device
+device.import.dup.desc=Device '%1' is already present.
+
+stream.analysing.media=Analyzing Media
+device.export.select.template.file=Export Device
+
+dlg.stream.plus.subtext=Tired of waiting for your downloads to complete?  Watch sooner with Play Now, a Vuze Plus feature that lets you watch a video while it continues to download.
+dlg.stream.plus.text=Upgrade to Vuze Plus and play your videos as they download.
+dlg.stream.plus.title={Button.upgrade}
+dlg.stream.plus.subtitle={Button.upgrade}
+
+dlg.stream.plus.renew.subtext={dlg.stream.plus.subtext}
+dlg.stream.plus.renew.text=Renew your Vuze Plus subscription to continue to play your videos as they download.
+dlg.stream.plus.renew.title=Vuze Plus Renewal
+dlg.stream.plus.renew.subtitle=Vuze Plus Renewal
+
+
+Button.upgrade=Upgrade
+Button.renew=Renew
+iconBar.pstream={iconBar.stream}
+
+stream.analysing.media.preview=Analyzing Media (Preview Mode)
+devices.restrict_access=Restrict Access...
+devices.restrict_access.prompt=Restrict Access to '%1'
+devices.restrict_access.msg=Comma separated list of IPs to permit [or deny if prefixed with -]
+
+TableColumn.header.TorrentStream={iconBar.stream}
+TableColumn.TorrentStream.tooltip.disabled=Play Now does not support files of this type
+TableColumn.TorrentStream.tooltip.expand=Expand row to see Play Now for individual files
+
+table.columns.reset=Reset Columns
+plus.notificaiton.ExpiringEntry.s=Your Vuze Plus subscription will expire in %1 day: <A %2>Renew Now</A>
+plus.notificaiton.ExpiringEntry.p=Your Vuze Plus subscription will expire in %1 days: <A %2>Renew Now</A>
+plus.notificaiton.ExpiredEntry.s=Your Vuze Plus subscription has expired: <A %2>Renew Now</A>
+plus.notificaiton.ExpiredEntry.p={plus.notificaiton.ExpiredEntry.s}
+plus.notificaiton.OfflineExpiredEntry=You have been offline for too many days. Vuze Plus has been deactivated.
+
+rss.internal.test.url=Click to view the local home page
+cat.rss.gen=Create local RSS feed
+dht.backup.only=DHT backup only
+
+TableColumn.header.ipfilter=IP Filter Enabled
+MyTorrentsView.menu.ipf_enable=Enable IP Filter
+devices.sidebar.mainheader.tooltip=%1 devices are hidden as generic or un-tagged.\nUse right-click options to reveal
+device.mediaserver.remove_all=Remove all Media Servers
+device.mediaserver.remove_all.title=Confirm Removal
+device.mediaserver.remove_all.desc=Are you sure you want to remove all Media Severs?
+device.renderer.remove_all=Remove all Renderers
+device.renderer.remove_all.desc=Are you sure you want to remove all Renderers AND their transcodes?
+MyTorrentsView.menu.create_personal_share=Create Personal Share
+
+device.tag=Tag Device
+device.onlyShowTagged=Only Show Tagged Devices
+devices.sidebar.show.only.tagged=Only show tagged devices
+
+filter.header.matches1=(Search results: %1)
+filter.header.matches2=(Search results: %1, %2 active)
+
+ipfilter.disabled=IP Filters Disabled
+ipfilter.options=IP Filter Options...
+
+TableColumn.header.eta_next=Next ETA
+
+subscriptions.column.SubWizName={FilesView.name}
+subscriptions.column.SubWizRank=Rank
+
+SubscriptionWizard.column.SubWizName={FilesView.name}
+SubscriptionWizard.column.SubWizRank={subscriptions.column.SubWizRank}
+
+torrentdownload.error.dl_fail=Failed to download '%1' to '%2': %3
+
+MainWindow.menu.speed_limits=Speed Limits
+MainWindow.menu.speed_limits.profile=Enter Profile Name
+MainWindow.menu.speed_limits.profiles=Profiles
+MainWindow.menu.speed_limits.load=Apply...
+MainWindow.menu.speed_limits.view=View...
+MainWindow.menu.speed_limits.delete=Delete
+MainWindow.menu.speed_limits.view_current=View Current...
+MainWindow.menu.speed_limits.save_current=Save Current As...
+MainWindow.menu.speed_limits.reset=Clear Current Limits
+MainWindow.menu.speed_limits.info.title=Speed Limits Details
+MainWindow.menu.speed_limits.info.prof=Settings for profile '%1'
+MainWindow.menu.speed_limits.info.curr=Current settings
+MainWindow.menu.speed_limits.schedule=Schedule...
+MainWindow.menu.speed_limits.schedule.title=Speed Limits Schedule
+MainWindow.menu.speed_limits.schedule.msg=Current rules that control the automatic application of speed-limit profiles
+MainWindow.menu.speed_limits.schedule.err=The following errors were reported, please re-edit to fix!
+
+torrent.decode.info.order.bad=Torrent Warning: Torrent '%1' is incorrectly formatted and may generate an incorrect hash.\n\nSee <a href=\"http://wiki.vuze.com/w/Torrent_Info_Order_Bad\">the Vuze Wiki</a> for more details and a possible solution
+MainWindow.menu.advanced_tools=Advanced
+torrent.fix.corrupt=Fix Corrupted Torrent...
+torrent.fix.corrupt.browse=Open Torrent
+torrent.fix.corrupt.result.title=Operation Result
+torrent.fix.corrupt.result.nothing=The torrent appears to be valid!
+torrent.fix.corrupt.result.fixed=New torrent hash of %1 calculated.\nHit OK to save the torrent.
+FilesView.header={FilesView.title.full}
+MyTorrentsView.menu.sl_add_to_prof=Add To/Update Profile
+MyTorrentsView.menu.sl_remove_from_prof=Remove From Profile
+
+MagnetPlugin.use.md.download=Enable download-based metadata transfer
+MagnetPlugin.use.md.download.delay=\tdelay [secs]
+MagnetPlugin.report.md.starts=Metadata download created
+MagnetPlugin.report.md.progress=Metadata download progress: %1
+MagnetPlugin.report.md.done=Metadata download completed
+MagnetPlugin.use.md.download.name=Metadata download for %1
+
+OpenTorrentWindow.addFiles.magnet=Add &Magnet
+MainWindow.menu.file.open.uri=URL, Magnet or Hash...
+MainWindow.menu.file.open.uri.keybinding=Meta+U
+Button.open=Open
+
+plugin.init.load.failed=Error loading plugin '%1' from %2
+plugin.init.load.failed.classmissing=Uninstall the plugin via 'Tools->Plugins->Uninstallation Wizard' and then re-install it.
+v3.MainWindow.search.tooltip=Enter your search terms, magnet link, hash or torrent URL and hit enter!
+
+device.playnow.group=Play Now
+device.playnow.buffer=Buffer size before playback starts [sec]
+device.playnow.min_buffer=Buffer size at which rebuffering occurs [sec]
+
+ConfigView.section.backuprestore=Backup & Restore
+ConfigView.section.br.overview=Configure your backup requirements for Vuze. This will allow recovery of your configuration in the case of a serious error, such as a disk failure.\n\nIf possible backup to a separate physical drive from the one you normally run Vuze from!\n\nNote that the operations here only apply to Vuze configuration data, you will need to manage the backup of downloaded files yourself.\n\n 
+br.backup=Backup
+br.backup.manual.info=Manually backup configuration
+br.backup.folder.title=Select Backup Folder
+br.backup.folder.info=Choose the folder that the backup will be written to
+br.restore=Restore
+br.restore.info=Restore your configuration from a backup
+br.restore.warning.title=Loss of Configuration Warning!
+br.restore.warning.info=Restoring your configuration will completely replace your existing one.\nConsider backing it up before hand!
+br.backup.progress=Backup/Restore Results
+br.restore.folder.title=Select Restore Folder
+br.restore.folder.info=Select the folder containing a previous backup
+br.backup.auto.enable=Enable automatic backups
+br.backup.auto.dir.select=Please choose the default backup directory
+br.backup.auto.everydays=Backup frequency [days]
+br.backup.auto.retain=Number of backups to retain
+br.backup.auto.now=Test run auto-backup now
+br.test=Test
+
+TorrentOptionsView.param.upload.priority=Upload priority [0=default;1=prioritized]
+cat.upload.priority=Upload Priority
+cat.options=Current Torrents Options/Info...
+br.backup.last.time=Last backup occurred at
+br.backup.last.error=Last backup error:
+br.backup.setup.info=Please consider setting up automatic configuration backup.\nSee Tools->Options->Backup & Restore
+MainWindow.about.internet.contributors=Contributors
+
+FileItem.low={SpeedTestWizard.name.conf.level.low}
+FilePriority.invalid.title=Invalid Priority
+FilePriority.invalid.text=Invalid value entered, integer required: %1
+
+MyTorrentsView.menu.trackername.editprefs=Edit Preferred Display Trackers...
+trackername.prefs.title=Enter Preferred Display For Multi-tracker Torrents
+trackername.prefs.message=Semicolon separated list of tracker host names\nFor example: a.b.com; c.d.net
+
+device.wiki=Wiki Hints and Tips...
+device.wiki.itunes=http://wiki.vuze.com/w/Devices_iTunes_Tips
+MagnetPlugin.report.ddb_disabled=DDB is disabled
+
+ConfigView.option.dm.dblclick.launch={iconBar.run}
+
+ConfigView.section.style.enableHeaderHeight=Custom Header Height
+ConfigView.section.style.customDateFormat=Custom Date Format
+br.backup.notify=Notify when backup is complete
+
+sidebar.LibraryCD.tooltip=There are %1 complete torrent(s), %2 of which is/are currently seeding
+sidebar.LibraryDL.tooltip=There are %1 incomplete torrent(s), %2 of which is/are currently downloading
+
+ConfigView.section.style.launch=Launch Helpers
+ConfigView.label.lh.info=By default launching a file uses the application registered for the file's type.\nOverride this behaviour by defining explicit applications for given file extensions [comma separated list].
+ConfigView.label.lh.ext=Extensions
+ConfigView.label.lh.prog=Application
+pairing.config.icon.show=Show Vuze Remote remote icon in status bar
+pairing.ui.icon.show=Show Icon
+pairing.ui.icon.tip=Vuze Remote Connection Status
+ManagerItem.moving=Moving
+
+wizard.newtorrent.byo=Build Your Own
+wizard.newtorrent.byo.info=Drop a selection of files and/or directories onto the area below to build a torrent. Double-click or F2 to edit names.
+wizard.newtorrent.byo.help=Build your own torrent from a selection of files and directories
+wizard.newtorrent.byo.editname.title=Edit Item Name
+wizard.newtorrent.byo.editname.text=Enter the name of the item as it appears in the torrent
+wizard.newtorrent.byo.addcontainer.title=Add Container
+wizard.newtorrent.byo.addcontainer.text=Enter the name of the container as it appears in the torrent
+
+label.torrent.structure=Torrent Structure
+label.original.file=Original File
+button.add.container=Add Container
+label.container.display=<container>
+
+TableColumn.header.torrentrelpath=Torrent Path
+TableColumn.header.torrentrelpath.info=Relative location of the file in the torrent
+TableColumn.header.torrentfileindex=File Index
+TableColumn.header.torrentfileindex.info=Index of the file in the torrent
+
+label.information={wizard.information}
+label.protocol={Peers.column.Protocol}
+ConfigView.section.tracker.client.enabletcp=Enable HTTP/HTTPS tracker client protocol
+label.udp_probe=UDP Probe
+
+MyTorrentsView.menu.eta.abs=Show ETA as an absolute time
+
+ConfigView.label.sleep=Sleep
+ConfigView.label.sleep.info=Prevent the computer from sleeping/suspending while...
+ConfigView.label.sleep.download=Downloading
+ConfigView.label.sleep.fpseed='First Priority' seeding is active 
+
+TableColumn.header.fileext=File Type
+TableColumn.header.fileext.info=File type/extension of the download's primary file
+
+TableColumn.header.crc32=CRC-32
+TableColumn.header.crc32.info=CRC-32 Checksum for the file (must be fully downloaded; click to calculate)
+FilesView.crc32.calculate=Calculate CRC-32 Checksum(s)
+TableColumn.header.md5=MD5
+TableColumn.header.md5.info=MD5 hash for the file (must be fully downloaded; click to calculate)
+FilesView.md5.calculate=Calculate MD5 hash(s)
+FilesView.click=Click...
+FilesView.click.info=Click to calculate; use right-click menu for multiple calculations 
+
+ConfigView.section.connection.port.rand.enable=Randomize listen ports on startup
+ConfigView.section.connection.port.rand.range=Port Range [min-max]
+ConfigView.section.connection.port.rand.together=Same port for TCP and UDP
+
+ConfigView.label.start.inlrm=Start in low resoruce usage mode (deactivated UI, constrained network and memory usage etc)
+
+wizard.multitracker.edit.text=Edit As Text
+wizard.multitracker.edit.text.title=Enter Tracker Details
+wizard.multitracker.edit.text.msg=Enter one tracker per line. Separate different groups (tiers) with a blank line.
+
+MainWindow.menu.quick_view=Quick View
+quick.view.no.files=No Applicable Files
+ConfigView.label.quickviewexts=Quick-view file extensions
+ConfigView.label.quickviewmaxkb=Max file size [KB]
+MainWindow.menu.quick_view.msg=Contents of file '%1' within download '%2'
+quick.view.scheduled.title=Quick View Scheduled
+quick.view.scheduled.text=The selected file has been prioritised and will auto-open for viewing when complete.
+label.dont.show.again=Don't show me this message again
+label.plugin.options=Plugin Options...
+TableColumn.header.torrent_created=Torrent Created
+TableColumn.header.torrent_created.info=Date the torrent was created, when available
+
+pairing.ui.icon.tip.no.recent=No Recent Connections
+label.access.denied=Access Denied
+label.date.format=Date Format
+label.table.default=Table Default
+
+device.config.xcode.disable_sleep=Prevent computer sleep when transcoding
+label.aggregate.info=Aggregated Information
+label.options.and.info=Options/Info...
+ConfigView.section.tracker.client.exclude_lan=Exclude LAN transfer data statistics
+
+ConfigView.pluginlist.uninstallSelected=Uninstall Selected
+
 #PLEASE LEAVE ME AT VERY BOTTOM!
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ar_SA.properties b/org/gudy/azureus2/internat/MessagesBundle_ar_SA.properties
index c8dcbb3..33f6e3c 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ar_SA.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ar_SA.properties
@@ -26,12 +26,9 @@ ConfigView.section.language=\u0627\u0644\u0644\u063a\u0629
 MainWindow.menu.help=\u0645\u0633\u0627\u0639\u062f\u0629
 MainWindow.menu.help.about=\u062d\u0648\u0644 \u0623\u0632\u0648\u0631\u064a\u0648\u0633
 MainWindow.about.title=\u062d\u0648\u0644
-MainWindow.about.section.developers=\u0627\u0644\u0645\u0635\u0646\u0651\u0639\u0648\u0646
-MainWindow.about.section.translators=\u0627\u0644\u0645\u062a\u0631\u062c\u0645\u0648\u0646
 MainWindow.about.section.internet=\u0627\u0646\u062a\u0631\u0646\u062a
 MainWindow.about.internet.homepage=\u0627\u0644\u0635\u0641\u062d\u0629 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629 \u0644\u0640 \u0622\u0632\u0648\u0631\u064a\u0648\u0633
 MainWindow.about.internet.sourceforge=Sourceforge \u0635\u0641\u062d\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u064a
-MainWindow.about.internet.sourceforgedownloads=Sourceforge \u062a\u062d\u0645\u064a\u0644 \u0628\u0631\u0627\u0645\u062c
 MainWindow.about.internet.bugreports=\u062a\u0642\u0627\u0631\u064a\u0631 \u0627\u0644\u0623\u062e\u0637\u0627\u0621
 MainWindow.about.internet.forumdiscussion=\u0627\u0644\u0645\u0646\u062a\u062f\u0649 \u0627\u0644\u0639\u0627\u0645
 MainWindow.dialog.choose.savepath=\u0627\u062e\u062a\u0631 \u0645\u0633\u0627\u0631 \u0627\u0644\u062a\u0633\u062c\u064a\u0644
@@ -262,8 +259,6 @@ IrcView.errormsg=Wrong Syntax on /msg : /msg user text
 IrcView.help=Valid commands are :\n . /help : displays this message\n . /nick | /name : changes your name \n . /me action : sends an action \n . /msg nick message : sends a private message to \n . /r message : reply to last private message\n . /join #channel : changes current channel 
 PasswordWindow.title=Vuze is locked 
 Button.ok=Ok 
-TrackerChangerWindow.title=Add Tracker 
-TrackerChangerWindow.newtracker=Enter new tracker url 
 PeersView.discarded=Discarded 
 discarded=discarded 
 MyTorrentsView.#=# 
@@ -325,7 +320,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Delete .torrent
 MyTorrentsView.menu.removeand.deletedata=Delete Data 
 MyTorrentsView.menu.removeand.deleteboth=Delete Both 
 deletedata.title=!!! Warning !!! 
-deletedata.message1=You are about to delete the DATA from :\n 
 MainWindow.menu.file.configure=Configuration Wizard 
 configureWizard.title=Configuration Wizard 
 configureWizard.welcome.title=Welcome to the Vuze Configuration Wizard 
@@ -344,7 +338,6 @@ configureWizard.transfer.maxActiveTorrents=Max Active
 configureWizard.transfer.maxDownloads=Max Downloads 
 configureWizard.transfer.maxUploadsPerTorrent=Max Uploads per Torrent 
 configureWizard.nat.title=NAT / Server Ports 
-configureWizard.nat.message=In order to get the best out of BitTorrent, it's highly recommended to be fully accessible from the internet. Default bittorrent ports range from 6881 to 6889. This tool lets you test and / or change those default ports. If you have some active downloads, some ports may not be accessible. 
 configureWizard.nat.test=Test 
 configureWizard.nat.testing=Testing port 
 configureWizard.nat.ok=Ok 
diff --git a/org/gudy/azureus2/internat/MessagesBundle_bg_BG.properties b/org/gudy/azureus2/internat/MessagesBundle_bg_BG.properties
index a921c9e..8f2366a 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_bg_BG.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_bg_BG.properties
@@ -1,4 +1,4 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
 MainWindow.menu.file.open.torrent=\u0422\u043e\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b\u0085\u2026
 Main.parameter.usage=\u0423\u043f\u043e\u0442\u0440\u0435\u0431\u0430: java org.gudy.azureus2.cl.Main [\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438] "file.torrent" "\u043f\u044a\u0442 \u0437\u0430 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435"
 Main.parameter.maxUploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u043a\u0430\u0447\u0432\u0430\u043d\u0438\u044f
@@ -14,7 +14,7 @@ MainWindow.menu.file.closetab=\u0417\u0430\u0442\u0432\u0430\u0440\u044f\u043d\u
 MainWindow.menu.file.closewindow=\u0417\u0430\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 &\u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446
 MainWindow.menu.file.exit=\u0418\u0437&\u0445\u043e\u0434
 MainWindow.dialog.choose.file=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b
-MainWindow.menu.file.folder=&\u041f\u0430\u043f\u043a\u0430\u0085\u2026
+MainWindow.menu.file.folder=&\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0085\u2026
 MainWindow.dialog.choose.folder=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 MainWindow.menu.view=\u0418&\u0437\u0433\u043b\u0435\u0434
 MainWindow.menu.view.show=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435
@@ -37,13 +37,10 @@ MainWindow.menu.help=\u041f&\u043e\u043c\u043e\u0449
 MainWindow.menu.help.about=\u0417\u0430 Vuze
 MainWindow.menu.torrent=\u0422\u043e\u0440\u0435\u043d\u0442
 MainWindow.about.title=\u041e\u0442\u043d\u043e\u0441\u043d\u043e
-MainWindow.about.section.developers=\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u0446\u0438
-MainWindow.about.section.translators=\u041f\u0440\u0435\u0432\u043e\u0434\u0430\u0447\u0438
 MainWindow.about.section.system=\u0421\u0438\u0441\u0442\u0435\u043c\u0430
 MainWindow.about.section.internet=\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442
 MainWindow.about.internet.homepage=\u041d\u0430\u0447\u0430\u043b\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 Vuze
 MainWindow.about.internet.sourceforge=\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 Sourceforge \u0437\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0438
-MainWindow.about.internet.sourceforgedownloads=\u0417\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u043e\u0442 Sourceforge
 MainWindow.about.internet.bugreports=\u0414\u043e\u043a\u043b\u0430\u0434\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u0435\u0438\u0437\u043f\u0440\u0430\u0432\u043d\u043e\u0441\u0442\u0438
 MainWindow.about.internet.forumdiscussion=\u0424\u043e\u0440\u0443\u043c\u0438
 MainWindow.about.internet.wiki=\u0427\u0417\u0412 Vuze Wiki
@@ -107,6 +104,7 @@ PeersView.pieces=\u041f\u0430\u0440\u0447\u0435\u0442\u0430
 PeersView.%=\u0412 % \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 PeersView.downloadspeed=\u0421\u0432\u0430\u043b\u044f\u043d\u0435 \u0441
 PeersView.download=\u0421\u0432\u0430\u043b\u044f\u043d\u0435
+PeersView.download.info=\u041e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u043e\u0442 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f.
 PeersView.I2=\u0418 (\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0437\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f)
 PeersView.I2.info=\u0414\u0430\u043b\u0438 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f\u0442 \u0441\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0432\u0430 \u043e\u0442 \u043c\u0435\u0441\u0442\u043d\u043e \u043d\u0430\u043b\u0438\u0447\u043d\u043e\u0442\u043e?
 PeersView.C2=C (\u0440\u0430\u0437\u043e\u0447\u0430\u0440\u043e\u0432\u0430\u043d\u0435 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f)
@@ -118,7 +116,7 @@ PeersView.upload.info=\u041e\u0431\u043e\u0431\u0449\u0435\u043d\u043e \u043a\u0
 PeersView.statup=\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435
 PeersView.statup.info=\u0418\u0437\u0447\u0438\u0441\u043b\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f
 PeersView.S=\u0421
-PeersView.S.info=\u0421\u043a\u0430\u0441\u0442\u0440\u0435\u043d: \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0441\u043a\u0430\u0441\u0442\u0440\u0435\u043d \u0440\u044a\u0447\u043d\u043e \u0438\u043b\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e (\u0437\u0430 \u0442\u043e\u0432\u0430, \u0447\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u044f \u0434\u [...]
+PeersView.S.info=\u0421\u043c\u044a\u043c\u0440\u0435\u043d: \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0441\u043c\u044a\u043c\u0440\u0435\u043d \u0440\u044a\u0447\u043d\u043e \u0438\u043b\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e (\u0437\u0430 \u0442\u043e\u0432\u0430, \u0447\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0432\u044f \u0434\u0430\u043d\u [...]
 PeersView.downloadspeedoverall=\u041e\u0431\u0449\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
 PeersView.optunchoke=\u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u0440\u0430\u0437\u043e\u0447\u0430\u0440\u043e\u0432\u0430\u043d\u0435
 PeersView.client=\u041a\u043b\u0438\u0435\u043d\u0442
@@ -129,7 +127,7 @@ PeersView.title.full=\u0420\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u043
 AllPeersView.title.full=\u0412\u0441\u0438\u0447\u043a\u0438 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 ConfigView.section.files=\u0424\u0430\u0439\u043b\u043e\u0432\u0435
 ConfigView.label.usefastresume=\u0420\u0435\u0436\u0438\u043c \u0437\u0430 \u0431\u044a\u0440\u0437\u043e \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0435\u043d\u0438\u0435
-ConfigView.label.incrementalfile=\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u043d\u043e \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 [\u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u043f\u0440\u0438 FAT32 \u043f\u043e\u0434 \u041b\u0438\u043d\u0443\u043a\u0441]
+ConfigView.label.incrementalfile=\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u043d\u043e \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 (\u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u043f\u0440\u0438 FAT32 \u043f\u043e\u0434 \u041b\u0438\u043d\u0443\u043a\u0441)
 ConfigView.label.defaultsavepath=\u0417\u0430\u043f\u0438\u0441 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0434\u0430\u043d\u043d\u0438
 ConfigView.button.browse=&\u041f\u0440\u0435\u0433\u043b\u0435\u0434\u0085\u2026
 ConfigView.dialog.choosedefaultsavepath=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435
@@ -137,9 +135,9 @@ ConfigView.section.server=\u0412\u0440\u044a\u0437\u043a\u0430
 ConfigView.section.global=\u041e\u0431\u0449\u043e
 ConfigView.label.disconnetseed=\u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0441\u044f\u0432\u043a\u0438\u0442\u0435 \u043f\u0440\u0438 \u0441\u0435\u0435\u043d\u0435
 ConfigView.label.switchpriority=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043d\u0438\u0441\u044a\u043a \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0440\u0438 \u0441\u0435\u0435\u043d\u0435
-ConfigView.label.maxdownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u043e \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n - \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0435 \u043f\u043e-\u0432\u0438\u0441\u043e\u043a\u043e \u043e\u0442 \u0431\u0440\u043e\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0 [...]
+ConfigView.label.maxdownloads=\u041c\u0430\u043a\u0441. \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0435 \u043f\u043e-\u0432\u0438\u0441\u043e\u043a\u043e \u043e\u0442 \u0431\u0440\u043e\u044f \u043c\u0430\u043a\u0441. \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u0442\u043e\u0440\u [...]
 ConfigView.label.maxdownloads.tooltip=\u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e \u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0442\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0443\u043a \u0431\u0440\u043e\u0439 \u0441 \u0435\u0434\u043d\u043e \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.\n\u0417\u0430\u0432\u044a\u0440\u0448\u0435\u043d \u0442\u043e\u0440\u0435\u043d\u0442, \u043e\u0442 [...]
-ConfigView.label.maxactivetorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n\u041d\u043e\u0432\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0437\u0430\u043f\u043e\u0447\u0432\u0430\u0442 \u043f\u0440\u0438 \u0441\u0432\u0430\u043b\u044f\u [...]
+ConfigView.label.maxactivetorrents=\u041c\u0430\u043a\u0441. \u0431\u0440\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n\u041d\u043e\u0432\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0437\u0430\u043f\u043e\u0447\u0432\u0430\u0442 \u043f\u0440\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0435/\u0441\u0435\u0435\u043d [...]
 ConfigView.label.priorityExtensions=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u043e\u0432\u0438\u0448\u0430\u0432\u0430\u043d\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u0440\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0435\n - \u043f\u0440.: .txt;.nfo;.jpg
 ConfigView.section.transfer=\u0422\u0440\u0430\u043d\u0441\u0444\u0435\u0440
 ConfigView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0433\u043d\u0435\u0437\u0434\u0430 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
@@ -160,12 +158,12 @@ ConfigView.label.openconsole=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u
 ConfigView.label.openconfig=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 '\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f' \u043f\u0440\u0438 \u043d\u0430\u0447\u0430\u043b\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435
 ConfigView.label.startminimized=\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u0430\u043d
 ConfigView.section.irc=\u041c\u0440\u0435\u0436\u0430 IRC
-ConfigView.label.ircwiki=\u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0447\u0435\u0442\u0435 http://www.azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=\u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0447\u0435\u0442\u0435 http://wiki.vuze.com/w/Rules_for_IRC
 ConfigView.label.ircserver=\u0421\u044a\u0440\u0432\u044a\u0440
 ConfigView.label.ircchannel=\u041a\u0430\u043d\u0430\u043b
 ConfigView.label.irclogin=\u041f\u0440\u044f\u043a\u043e\u0440
 ConfigView.group.irctitle=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 IRC
-ConfigView.boolean.ircsendinfo=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0438\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043b\u0438\u0447\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e) \u0434\u043e\n \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0438\u0442\u0435 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b, \u0437\u0430 \u0434\u0430 \u0438\u043c \u0441\u0435 \u04 [...]
+ConfigView.boolean.ircsendinfo=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0438\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043c\u0435\u0441\u0442\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e) \u0434\u043e\n \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0438\u0442\u0435 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b, \u0437\u0430 \u0434\u0430 \u0438\u043c \u0441\u043 [...]
 ConfigView.boolean.irclog=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0434\u043d\u0435\u0432\u043d\u0438\u043a \u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0442\u0430 \u043f\u043e \u043a\u0430\u043d\u0430\u043b (\u0432 IRC_log.htm)
 ConfigView.section.security=\u0421\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442
 ConfigView.label.password=\u0417\u0430\u0449\u0438\u0442\u0430 \u043d\u0430 Vuze \u0441 \u043f\u0430\u0440\u043e\u043b\u0430\n\u0429\u0435 \u0441\u0435 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043f\u0440\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043e\u0442 \u0438\u043a\u043e\u043d\u0430 \u0438 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435.
@@ -277,7 +275,7 @@ PeerManager.status.finished=\u0417\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u04
 PeerManager.status.finishedin=\u0417\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u0437\u0430
 MainWindow.upgrade.assistant=\u041f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
 MainWindow.upgrade.newerversion=\u0418\u043c\u0430 \u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Vuze \u043d\u0430 \u0440\u0430\u0437\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
-MainWindow.upgrade.explanation=\u0422\u043e\u0437\u0438 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0449\u0435 \u0441\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0432 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u043d\u0430 Vuze \u0438 \u0449\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 Vuze
+MainWindow.upgrade.explanation=\u0422\u043e\u0437\u0438 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0449\u0435 \u0441\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043d\u0430 Vuze \u0438 \u0449\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 Vuze
 MainWindow.upgrade.explanation.manual=\u0420\u044a\u0447\u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u0438 \u043a\u0430\u0442\u043e \u0441\u0435 \u0437\u0430\u0442\u0432\u043e\u0440\u0438 Vuze, \u0441\u0432\u0430\u043b\u0438 \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0 [...]
 MainWindow.upgrade.step1=\u0421\u0442\u044a\u043f\u043a\u0430 1: \u0421\u0432\u0430\u043b\u044f \u0441\u0435 \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f
 MainWindow.upgrade.step2=\u0421\u0442\u044a\u043f\u043a\u0430 2: \u0417\u0430\u0442\u0432\u0430\u0440\u044f \u0441\u0435 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0438 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Vuze
@@ -321,8 +319,6 @@ IrcView.help=\u0412\u0430\u043b\u0438\u0434\u043d\u0438 \u043a\u043e\u043c\u0430
 PasswordWindow.title=Vuze \u0435 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d
 PasswordWindow.passwordprotected=Vuze \u0435 \u0437\u0430\u0449\u0438\u0442\u0435\u043d \u0441 \u043f\u0430\u0440\u043e\u043b\u0430.\n\u0417\u0430 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446\u0430 \u043d\u0430 \u0410zureus \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u043f\u0430\u0440\u043e\u043b\u0430: 
 Button.ok=&\u0414\u0430
-TrackerChangerWindow.title=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0442\u0440\u0430\u043a\u0435\u0440
-TrackerChangerWindow.newtracker=\u041d\u043e\u0432 URL \u043d\u0430 \u0442\u0440\u0430\u043a\u0435\u0440
 PeersView.discarded=\u0418\u0437\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u043e
 PeersView.discarded.info=\u0414\u0430\u043d\u043d\u0438, \u043a\u043e\u0438\u0442\u043e \u043d\u044f\u043a\u0430\u043a \u0441\u0438 \u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438, \u043d\u043e \u043d\u0435 \u0441\u0430 \u0431\u0438\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0438 \u0438 \u0441\u0430 \u043c\u0430\u0445\u043d\u0430\u0442\u0438.
 discarded=\u0438\u0437\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u043e
@@ -370,7 +366,7 @@ Torrent.create.progress.totalfilecount=\u041e\u0431\u0449 \u0431\u0440\u043e\u04
 Torrent.create.progress.parsingfiles=\u0420\u0430\u0437\u0431\u043e\u0440 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
 Torrent.create.progress.hashing=\u0420\u0430\u0437\u0431\u044a\u0440\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
 MainWindow.upgrade.downloadingfrom=\u0421\u0432\u0430\u043b\u044f\u043d\u0435 \u043e\u0442: 
-MainWindow.menu.view.ipFilter=&IP \u0424\u0438\u043b\u0442\u0440\u0438
+MainWindow.menu.view.ipFilter=&IP \u0444\u0438\u043b\u0442\u0440\u0438
 ConfigView.section.ipfilter=IP \u0444\u0438\u043b\u0442\u0440\u0438
 ConfigView.section.ipfilter.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
 ConfigView.section.ipfilter.start=\u041d\u0430\u0447\u0430\u043b\u0435\u043d IP
@@ -389,19 +385,21 @@ ConfigView.label.showpopuponclose=\u0414\u0438\u0430\u043b\u043e\u0433 \u0437\u0
 ConfigView.label.startNumSeeds=\n\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0435\u0435\u043d\u0435 \u043f\u0440\u0438 \u043f\u043e-\u043c\u0430\u043b\u043a\u043e \u043e\u0442\n - \u043f\u0440\u0435\u0432\u044a\u0437\u043c\u043e\u0433\u0432\u0430 \u043e\u0441\u0442\u0430\u043d\u0430\u043b\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430
 ConfigView.label.seeds=\u043f\u043e\u0441\u044f\u0432\u043a\u0438
 ConfigView.section.seeding=\u0421\u0435\u0435\u043d\u0435
-MyTorrentsView.menu.removeand=\u041f\u0440\u0435\u043c\u0430\u0445&\u0432\u0430\u043d\u0435 \u0438
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletetorrent=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 &\u0442\u043e\u0440\u0435\u043d\u0442
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletedata=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 &\u0434\u0430\u043d\u043d\u0438
-MyTorrentsView.menu.removeand.deleteboth=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434&\u0432\u0430\u0442\u0430
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=&\u041a\u043e\u043c\u043f\u043b\u0435\u043a\u0442\u043d\u043e \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435
 deletedata.title=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435
-deletedata.message1=\u041f\u0440\u0435\u0434 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0414\u0410\u041d\u041d\u0418 \u043e\u0442:\n
+# used for more than just "delete data"
 deletedata.noprompt=\u0411\u0435\u0437 \u043d\u043e\u0432\u043e \u043f\u043e\u0434\u0441\u0435\u0449\u0430\u043d\u0435
 MainWindow.menu.file.configure=\u0421\u044a\u0432\u0435\u0442\u043d\u0438\u043a \u0437\u0430 &\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0085\u2026
 configureWizard.title=\u0421\u044a\u0432\u0435\u0442\u043d\u0438\u043a \u0437\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 configureWizard.welcome.title=\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0442 \u0421\u044a\u0432\u0435\u0442\u043d\u0438\u043a\u0430 \u0437\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 Vuze
 configureWizard.welcome.message=\u0421\u044a\u0432\u0435\u0442\u043d\u0438\u043a \u0437\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 Vuze \u0437\u0430 \u043d\u0430\u0439-\u043e\u0431\u0449\u0430 \u0443\u043f\u043e\u0442\u0440\u0435\u0431\u0430. \u0412\u044a\u0437\u043c\u043e\u0436\u043d\u0430 \u0435 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0432 \u0434\u0435\u0442\u [...]
 configureWizard.transfer.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440 \u0438 \u0432\u0440\u044a\u0437\u043a\u0430
-configureWizard.transfer.hint=\u041f\u0440\u0435\u043f\u043e\u0440\u044a\u043a\u0430: \u043f\u043e-\u0434\u043e\u0431\u0440\u0435 \u0434\u0430 \u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438 \u043f\u043e-\u0432\u0438\u0441\u043e\u043a\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043e\u0442 \u043d\u0430\u043b\u0438\u0447\u043d\u0430\u0442\u0430.
+configureWizard.transfer.hint=\u041f\u0440\u0435\u043f\u043e\u0440\u044a\u043a\u0430: \u0434\u0430 \u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438 \u043c\u0430\u043b\u043a\u043e \u043f\u043e-\u043d\u0438\u0441\u043a\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043e\u0442 \u0442\u0430\u0437\u0438 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f\u0442\u0430.
 configureWizard.transfer.message=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u043f\u043e-\u0434\u043e\u043b\u0443. \u0410\u043a\u043e \u043d\u0435 \u0441\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u044a\u0447\u043d\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435, \u0449\u0435 \u0441\u0435 \u043d\u0430\u043c\u0430\u043b\u0438 \u0441\u043a\u043e\u0440\u0 [...]
 configureWizard.transfer.connection=\u041b\u0438\u043d\u0438\u044f
 configureWizard.transfer.connection.0=\u0414\u0440\u0443\u0433\u0430
@@ -412,23 +410,21 @@ configureWizard.transfer.connection.4=adsl/cable xxx/384 kb/s
 configureWizard.transfer.connection.5=adsl/cable xxx/512 kb/s
 configureWizard.transfer.connection.6=adsl/cable xxx/768 kb/s
 configureWizard.transfer.connection.7=adsl/cable xxx/1024 kb/s
-configureWizard.transfer.maxUpSpeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 (KB/s)
-configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u0438
-configureWizard.transfer.maxDownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
-configureWizard.transfer.maxUploadsPerTorrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u043e \u043a\u0430\u0447\u0432\u0430\u043d\u0438\u044f \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
-configureWizard.nat.title=NAT/\u0441\u044a\u0440\u0432\u044a\u0440\u0435\u043d \u043f\u043e\u0440\u0442
-configureWizard.nat.message=\u0417\u0430 \u043d\u0430\u0439-\u0434\u043e\u0431\u0440\u0438 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438 \u043e\u0442 Vuze, \u0441\u0435 \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0434\u0430 \u0438\u043c\u0430 \u043f\u044a\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430 \u043e\u0442 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442. \u0422\u043e\u04 [...]
+configureWizard.transfer.maxUpSpeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 (KB/s)
+configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441. \u0430\u043a\u0442\u0438\u0432\u043d\u0438
+configureWizard.transfer.maxDownloads=\u041c\u0430\u043a\u0441. \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
+configureWizard.transfer.maxUploadsPerTorrent=\u041c\u0430\u043a\u0441. \u043a\u0430\u0447\u0432\u0430\u043d\u0438\u044f \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 configureWizard.nat.test=\u0422\u0435\u0441\u0442
 configureWizard.nat.testing=\u0422\u0435\u0441\u0442 \u043d\u0430 \u043f\u043e\u0440\u0442
 configureWizard.nat.ok=\u0414\u0430!
 configureWizard.nat.ko=\u0413\u0440\u0435\u0448\u043a\u0430 \u0432 NAT
 configureWizard.nat.unable=\u041d\u0435\u0432\u044a\u0437\u043c\u043e\u0436\u0435\u043d \u0442\u0435\u0441\u0442: \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u0435\u043d \u043f\u043e\u0440\u0442 \u0438\u043b\u0438 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u0437\u0430 \u0442\u0435\u0441\u0442 \u043d\u0435 \u0443\u0441\u043f\u044f.\n\u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e \u0435 \u0434\u0440\u0443\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u04 [...]
 configureWizard.file.title=\u0422\u043e\u0440\u0435\u043d\u0442\u0438/\u0444\u0430\u0439\u043b\u043e\u0432\u0435
-configureWizard.file.message1=Vuze \u0449\u0435 \u0437\u0430\u043f\u0438\u0448\u0435 \u043e\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0442\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u043f\u0430\u043f\u043a\u0430, \u043a\u043e\u044f\u0442\u043e \u0441\u0435 \u0438\u0437\u0431\u0438\u0440\u0430 \u0442\u0443\u043a:
+configureWizard.file.message1=Vuze \u0449\u0435 \u0437\u0430\u043f\u0438\u0448\u0435 \u043e\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u0442\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u043a\u043e\u044f\u0442\u043e \u0441\u0435 \u0438\u0437\u0431\u0438\u0440\u0430 \u0442\u0443\u043a:
 configureWizard.file.path=\u041f\u044a\u0442
 configureWizard.file.browse=\u041f\u0440\u0435\u0433\u043b\u0435\u0434
-configureWizard.file.message2=Vuze \u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438 \u0441 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0432\u0435\u0434\u043d\u0430\u0433\u0430, \u0430\u043a\u043e \u043c\u0443 \u0431\u044a\u0434\u0430\u0442 \u0434\u043e\u0431\u0430\u0432\u0435\u043d\u0438 \u043a\u0440\u0430\u0442\u043a\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u044a\u043c \u0442\u043e\u0440\u0435\u043d\u0442\u0438\u044 [...]
-configureWizard.file.fastResume=\u0414\u0430 \u043c\u043e\u0436\u0435 \u0431\u044a\u0440\u0437\u043e \u0434\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438
+configureWizard.file.message2=Vuze \u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u043e\u0434\u043d\u043e\u0432\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0438\u0442\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0435\u0434\u043d\u0430\u0433\u0430, \u0430\u043a\u043e \u043c\u0443 \u0431\u044a\u0434\u0430\u0442 \u0434\u043e\u0431\u0430\u0432\u0435\u043d\u0438 \u043c\u0430\u043b\u043a\u043e \u0434\u0430\u043d\u043d\u0438 \u0437\u0430 \u043f\u043e\u0434\u043d\u043e\u0432\u044 [...]
+configureWizard.file.fastResume=\u0421 \u0431\u044a\u0440\u0437\u043e \u043f\u043e\u0434\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435
 configureWizard.file.invalidPath=\u0413\u0440\u0435\u0448\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
 configureWizard.finish.title=\u0417\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e
 configureWizard.finish.message=Vuze \u0432\u0435\u0447\u0435 \u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d, \u043f\u0440\u0438\u044f\u0442\u043d\u043e \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435!
@@ -474,7 +470,7 @@ importTorrentWizard.process.outputfileexists.message=\u0418\u0437\u0445\u043e\u0
 importTorrentWizard.process.torrentfail.title=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 importTorrentWizard.process.importfail.title=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 importTorrentWizard.process.unknownfail.title=\u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430
-ConfigView.label.bindip=\u041f\u0440\u0438\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043b\u043e\u043a\u0430\u043b\u0435\u043d IP \u0430\u0434\u0440\u0435\u0441
+ConfigView.label.bindip=\u041f\u0440\u0438\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043b\u043e\u043a\u0430\u043b\u0435\u043d IP \u0430\u0434\u0440\u0435\u0441 \u0438\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
 ConfigView.label.xfs.allocation=\u0417\u0430\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043f\u043e \u043c\u0435\u0442\u043e\u0434 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u043d \u0437\u0430 XFS
 ConfigView.label.xfs.allocation.tooltip=\u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0430\u0442\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f \u043d\u0430 /usr/sbin/xfs_io \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430. \u0412 \u043f\u043e\u0432\u0435\u0447\u0435\u0442\u043e Linux \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0446\u0438\u0438 \u0435 \u0447\u0430\u0441\u0442 \u043e\ [...]
 xfs.allocation.xfs_io.not.found=\u0417\u0430\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 XFS \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438, /usr/sbin/xfs_io \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438. \u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0430 \u0438\u043d\u0441\ [...]
@@ -584,7 +580,6 @@ IPChecker.external.service.no-ip.name=\u0423\u0441\u043b\u0443\u0433\u0430 \u043
 IPChecker.external.service.no-ip.description=\u0414\u043e\u0441\u0442\u0430\u0432\u0447\u0438\u043a \u043d\u0430 \u0443\u0441\u043b\u0443\u0433\u0430 \u0437\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u043d \u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u043d DNS\n(\u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 'check address' \u043d\u0435 \u0435 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0434\u043e\u0441\u0442\u044a\u043f\u043d\u0430)
 ConfigView.section.tracker.publicenable=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u044a\u043d\u0448\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 ConfigView.label.playdownloadspeech=\u0413\u043b\u0430\u0441\u043e\u0432\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0438\u0435 \u043f\u0440\u0438 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435
-ConfigView.label.playdownloadspeech.info=\u0423\u0441\u043b\u0443\u0433\u0438\u0442\u0435 \u0437\u0430 \u0440\u0435\u0447 \u043d\u0430\u0439-\u0434\u043e\u0431\u0440\u0435 \u0440\u0430\u0431\u043e\u0442\u044f\u0442 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430
 #
 # Tooltips
 #
@@ -672,7 +667,7 @@ iconBar.stop.tooltip=\u0421\u0442\u043e\u043f
 iconBar.remove.tooltip=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435
 iconBar.openNoDefault.tooltip=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b (\u0431\u0435\u0437 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435)
 iconBar.openURL.tooltip=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 URL
-iconBar.openFolder.tooltip=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u043f\u0430\u043f\u043a\u0430
+iconBar.openFolder.tooltip=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
 iconBar.new.tooltip=\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 iconBar.up.tooltip=\u041f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043f\u043e-\u0433\u043e\u0440\u0435
 iconBar.down.tooltip=\u041f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043f\u043e-\u0434\u043e\u043b\u0443
@@ -704,11 +699,11 @@ ConfigView.section.file.decoder.prompt.tooltip=\u0414\u0438\u0430\u043b\u043e\u0
 MyTorrentsView.menu.moveTop=&\u041d\u0430\u0439-\u0433\u043e\u0440\u0435
 MyTorrentsView.menu.moveEnd=\u041d\u0430\u0439-\u0434\u043e\u043b&\u0443
 ConfigView.label.moveonlyusingdefaultsave=\u0441\u0430\u043c\u043e \u0430\u043a\u043e \u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
-ConfigView.label.moveonlyusingdefaultsave.tooltip=\u0414\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c\u0435\u0441\u0442\u0438 \u0441\u0430\u043c\u043e \u0430\u043a\u043e \u0441\u0432\u0430\u043b\u0435\u043d\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438 \u0441\u0430 \u0432 \u043f\u0430\u043f\u043a\u0430\u0442\u0430 \u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
+ConfigView.label.moveonlyusingdefaultsave.tooltip=\u0414\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c\u0435\u0441\u0442\u0438 \u0441\u0430\u043c\u043e \u0430\u043a\u043e \u0441\u0432\u0430\u043b\u0435\u043d\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438 \u0441\u0430 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
 ConfigView.label.watchtorrentfolder=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u043d \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 ConfigView.label.watchtorrentfolder.tooltip=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u043d\u043e\u0432\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0440\u0435\u0434\u043e\u0432\u043d\u043e
 ConfigView.label.watchtorrentfolderinterval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b
-ConfigView.label.watchtorrentfolderinterval.tooltip=\u041f\u0430\u0443\u0437\u0430\u0442\u0430 \u0434\u043e \u043d\u043e\u0432\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u043f\u043a\u0430\u0442\u0430
+ConfigView.label.watchtorrentfolderinterval.tooltip=\u041f\u0430\u0443\u0437\u0430\u0442\u0430 \u0434\u043e \u043d\u043e\u0432\u043e \u0441\u043a\u0430\u043d\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430
 ConfigView.dialog.choosewatchtorrentfolderpath=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0437\u0430 \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 ConfigView.label.startwatchedtorrentsstopped=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043f\u0440\u0435\u043d\u0438\u0442\u0435
 ConfigView.label.startwatchedtorrentsstopped.tooltip=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0432 \u0421\u041f\u0420\u042f\u041d\u041e \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435
@@ -747,21 +742,19 @@ security.certtruster.no=\u041d\u0435
 ConfigView.section.tracker.torrentsperpage=\u0411\u0440\u043e\u0439 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430?  [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 MainWindow.menu.file.share=&\u0421\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
 MainWindow.menu.file.share.file=&\u0424\u0430\u0439\u043b\u0085\u2026
-MainWindow.menu.file.share.dir=&\u041f\u0430\u043f\u043a\u0430\u0085\u2026
-MainWindow.menu.file.share.dircontents=\u0421&\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0430\u043f\u043a\u0430\u0085\u2026
-MainWindow.menu.file.share.dircontentsrecursive=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0430\u043f\u043a\u0430\u2026 (&\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e)
+MainWindow.menu.file.share.dir=&\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0085\u2026
+MainWindow.menu.file.share.dircontents=\u0421&\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0085\u2026
+MainWindow.menu.file.share.dircontentsrecursive=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u2026 (&\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e)
 MainWindow.dialog.share.sharefile=\u0424\u0430\u0439\u043b \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
-MainWindow.dialog.share.sharedir=\u041f\u0430\u043f\u043a\u0430 \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
-MainWindow.dialog.share.sharedircontents=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u0430\u043f\u043a\u0430 \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
+MainWindow.dialog.share.sharedir=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
+MainWindow.dialog.share.sharedircontents=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0437\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
 MainWindow.dialog.share.sharedircontents.recursive=\u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e
 globalmanager.download.remove.veto=\u0412\u0435\u0442\u043e \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435
-plugin.sharing.download.remove.veto=\u0422\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441.\n\u0417\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e, \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c [...]
+plugin.sharing.download.remove.veto=\u0422\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441.\n\u0417\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e, \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c [...]
 ConfigView.section.tracker.main=\u0413\u043b\u0430\u0432\u043d\u043e
 ConfigView.section.tracker.web=\u0423\u0435\u0431
 ConfigView.label.prioritizefirstpiece=\u041f\u043e-\u0432\u0438\u0441\u043e\u043a \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0437\u0430 \u043f\u044a\u0440\u0432\u043e \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u043f\u0430\u0440\u0447\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b(\u043e\u0432\u0435)
 ConfigView.label.prioritizefirstpiece.tooltip=\u041e\u043f\u0438\u0442\u0432\u0430 \u0441\u0435 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u043f\u044a\u0440\u0432\u043e \u043d\u0430 \u0441\u0430\u043c\u0438\u0442\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u0440\u0430\u0439 \u043d\u0430 \u0444\u0430\u0439\u043b.\n\u0417\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u0435\u043d \u043f\u0440\u0435\u0433\u043b\u0435\u0434 \u0432 \u0440\u0430\u043d\u0435\u043d \u0441\u0442\u0430\u [...]
-ConfigView.section.file.confirm_data_delete=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0442\u0440\u0438\u0435\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438
-ConfigView.section.file.confirm_data_delete.tooltip=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0442\u0440\u0438\u0435\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438 \u0441 '\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0085\u2026'
 ConfigView.section.file.delete.include_files_outside_save_dir=\u041f\u0440\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438 \u0434\u0430 \u0441\u0435 \u0442\u0440\u0438\u044f\u0442 \u0438 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0438\u0437\u0432\u044a\u043d \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u0437\u0430 \u0437\u0430\u043f\u0438\u0 [...]
 TrayWindow.menu.startalldownloads=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u0432\u0441\u0438\u0447\u043a\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
 SystemTray.menu.startalltransfers=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u0432\u0441\u0438\u0447\u043a\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0438
@@ -779,7 +772,7 @@ MySharesView.menu.remove=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\
 ConfigView.section.tracker.extensions=\u0420\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u044f
 ConfigView.section.tracker.sendpeerids=\u0418\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435 \u0441\u0430\u043c\u043e\u043b\u0438\u0447\u043d\u043e\u0441\u0442\u0442\u0430 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d \u043a\u044a\u043c \u0441\u0432\u0430\u043b\u044f\u0449\u0438\u0442\u0435
 ConfigView.section.tracker.enableudp=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 UDP \u0442\u0440\u0430\u043a\u0435\u0440\u0441\u043a\u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b
-plugin.sharing.torrent.remove.veto=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0442\u043e\u0437\u0438 \u0442\u0440\u0430\u043a\u0435\u0440 \u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441.\n\u0417\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u0 [...]
+plugin.sharing.torrent.remove.veto=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0442\u043e\u0437\u0438 \u0442\u0440\u0430\u043a\u0435\u0440 \u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441.\n\u0417\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u0 [...]
 plugin.download.remove.veto.notstopped=\u0421\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0435, \u0437\u0430\u0449\u043e\u0442\u043e \u043d\u0435 \u0435 \u0441\u043f\u0440\u044f\u043d\u043e
 plugin.sharing.remove.veto=\u0422\u043e\u0432\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 \u0435 \u043f\u043e\u0434-\u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 '\u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f' \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0442\u0440\u04 [...]
 GeneralView.label.hash.tooltip=\u0421 \u043f\u043e\u0441\u043e\u0447\u0432\u0430\u043d\u0435 \u0441\u0435 \u043a\u043e\u043f\u0438\u0440\u0430 \u0440\u0430\u0437\u0431\u044a\u0440\u043a\u0432\u0430\u043d\u0435\u0442\u043e \u0432 \u043a\u043b\u0438\u043f\u0431\u043e\u0440\u0434\u0430
@@ -809,13 +802,13 @@ ConfigView.label.importdirectory=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u044
 ConfigView.label.minPeersToBoostNoSeeds.tooltip=\u0412\u0441\u0435\u043a\u0438 \u0442\u043e\u0440\u0435\u043d\u0442 \u0431\u0435\u0437 \u043f\u043e\u0441\u044f\u0432\u043a\u0438 \u0438\u043b\u0438 \u0441 \u043f\u043e-\u043c\u0430\u043b\u043a\u043e \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438 \u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043e\u0442\u043e\n\u0449\u0435 \u0431\u044a\u0434\u0435 \u043a\u044a\u043c \u043a\u0440\u0430\u044f \u043d\u [...]
 ConfigView.label.minPeersToBoostNoSeeds=\u041f\u043e-\u043d\u0438\u0441\u044a\u043a \u043f\u043e\u0441\u044f\u0432\u043a\u043e\u0432 \u0440\u0430\u043d\u0433 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0431\u0435\u0437 \u043f\u043e\u0441\u044f\u0432\u043a\u0438 \u0438\u043b\u0438 \u0441 \u043f\u043e-\u043c\u0430\u043b\u043a\u043e \u043e\u0442
 ConfigView.label.minSeedingTime.tooltip=\u041f\u043e\u0441\u044f\u0432\u043a\u043e\u0432\u0438\u0442\u0435 \u0440\u0430\u043d\u0433\u043e\u0432\u0435 \u0441\u0435 \u043a\u043e\u043b\u0435\u0431\u0430\u044f\u0442 \u0447\u0435\u0441\u0442\u043e \u0432 \u043a\u0440\u0430\u0442\u044a\u043a \u043f\u0435\u0440\u0438\u043e\u0434 \u043a\u0430\u0442\u043e \u043f\u043e\u043d\u044f\u043a\u043e\u0433\u0430 \u043a\u0430\u0440\u0430\u0442 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u0434\u0430 \u0437\ [...]
-ConfigView.label.minSeedingTime=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u0432\u0440\u0435\u043c\u0435 \u0437\u0430 \u0441\u0435\u0435\u043d\u0435 [s]
+ConfigView.label.minSeedingTime=\u041c\u0438\u043d. \u0432\u0440\u0435\u043c\u0435 \u0437\u0430 \u0441\u0435\u0435\u043d\u0435 [s]
 ConfigView.label.minSpeedForActiveDL.tooltip=\u0413\u043d\u0435\u0437\u0434\u043e \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0432\u0438\u043d\u0430\u0433\u0438 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0437\u0430 \u043d\u0430\u0447\u0430\u043b\u043d\u0438\u0442\u0435 30 \u0441\u0435\u043a\u0443\u043d\u0434\u0438\n\u0441\u043b\u0435\u0434 \u0437\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043d\u0435\u043f\u044a\u043b\u043 [...]
 ConfigView.label.minSpeedForActiveDL=\u0414\u0430 \u043d\u0435 \u0441\u0435 \u0441\u0447\u0438\u0442\u0430, \u0447\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u044a\u0442 \u043f\u043e\u043b\u0437\u0432\u0430 \u0433\u043d\u0435\u0437\u0434\u043e \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435, \u0430\u043a\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430 \u0435 \u043f\u043e\u0434
 ConfigView.label.peers=\u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 ConfigView.label.queue.debuglog=\u0414\u043d\u0435\u0432\u043d\u0438\u043a \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043e\u0442\u0441\u0442\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u0435\u0438\u0437\u043f\u0440\u0430\u0432\u043d\u043e\u0441\u0442\u0438
 ConfigView.label.queue.debuglog.info=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043d\u0435\u0438\u0437\u043f\u0440\u0430\u0432\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u043e\u0442\u0441\u0442\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u0437\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u043a\u044a\u043c \u043a\u043e\u043d\u0437\u043e\u043b\u0430/\u0434\u043d\u0435\u0432\u043d\u0438\u043a.\n\u041c\u0430\u043a\u0430\u0440 \u0438 \u0442\u0440\u0443\u0 [...]
-ConfigView.label.queue.minQueueingShareRatio=\u0414\u0430 \u043d\u0435 \u0435 \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0438\u043b\u0438 \u0441\u043f\u0440\u0435 \u0442\u043e\u0440\u0435\u043d\u0442 \u0434\u043e\u043a\u0430\u0442\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u0442\u043e \u043c\u0443 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435
+ConfigView.label.queue.minQueueingShareRatio=\u0422\u043e\u0440\u0435\u043d\u0442\u044a\u0442 \u0434\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430 \u0438\u043b\u0438 \u0441\u043f\u0440\u044f\u043d \u0434\u043e \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u043d\u0435 \u043d\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
 ConfigView.label.ratio=\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435
 ConfigView.label.removeOnStop=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441\u043b\u0435\u0434 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0442\u043e \u043c\u0443 \u0441\u043f\u0438\u0440\u0430\u043d\u0435
 ConfigView.label.savedirectory=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0437\u0430 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435
@@ -934,9 +927,9 @@ GeneralView.label.in_swarm=\u0432 \u0440\u043e\u044f\u043a\u0430
 ManagerItem.initializing=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435
 AlertMessageBox.error=\u0413\u0440\u0435\u0448\u043a\u0430
 AlertMessageBox.warning=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435
-AlertMessageBox.comment=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
+AlertMessageBox.comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 AlertMessageBox.information=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
-AlertMessageBox.unread=\u0418\u043c\u0430 \u043d\u0435\u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0449\u0436\u0435\u043d\u0438\u044f - \u0434\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0442\u0443\u043a \u0437\u0430 \u043f\u0440\u0435\u0433\u043b\u0435\u0434.
+AlertMessageBox.unread=\u0418\u043c\u0430 \u043d\u0435\u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f - \u0434\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0442\u0443\u043a \u0437\u0430 \u043f\u0440\u0435\u0433\u043b\u0435\u0434.
 SharedPortServer.alert.selectorfailed=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0432\u0430\u0447 \u0437\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0438 \u0434\u0430\u043d\u043d\u0438.\n\u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u0434\u0430\u043b\u0438 \u0437\u0430\u0449\u0438\u0442\u043d\u0430\u0442\u0430 \ [...]
 Tracker.alert.listenfail=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0441\u043b\u0443\u0448\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0440\u0442 %1.\n\u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u0434\u0430\u043b\u0438 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0438 \u043d\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u04 [...]
 DiskManager.alert.movefileexists=\u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u043f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\n\u0424\u0430\u0439\u043b %1 \u0432\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0432 \u043a\u0440\u0430\u0439\u043d\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e [...]
@@ -986,8 +979,8 @@ ConfigView.section.style.colorOverride.altRow=\u041f\u0440\u043e\u043c\u044f\u04
 ConfigView.section.file.save.peers.enable=\u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0438\u0442\u0435 \u0441 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438 \u0437\u0430 \u0431\u044a\u0440\u0437\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435
 ConfigView.section.file.save.peers.max=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438 \u0437\u0430 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 ConfigView.section.file.save.peers.pertorrent=\u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
-ConfigView.label.max_peers_per_torrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u0440\u044a\u0437\u043a\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.label.max_peers_total=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u0440\u044a\u0437\u043a\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u043e [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ConfigView.label.max_peers_per_torrent=\u041c\u0430\u043a\u0441. \u0432\u0440\u044a\u0437\u043a\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ConfigView.label.max_peers_total=\u041c\u0430\u043a\u0441. \u0432\u0440\u044a\u0437\u043a\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u043e [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 ConfigView.section.style.colorOverrides.reset=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u0446\u0432\u044f\u0442
 ConfigView.section.language.info=\u041f\u0440\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 \u0449\u0435 \u0441\u0435 \u043f\u0440\u0430\u0432\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0438\u043d\u0430\u0433\u0438, \u043a\u043e\u0433\u0430\u0442\u043e Vuze \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430.
 ConfigView.section.language.enableUpdate=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0437 \u0443\u0435\u0431
@@ -1037,7 +1030,7 @@ Scrape.status.initializing=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u043
 Scrape.status.scraping.queued=\u041e\u0441\u0442\u044a\u0440\u0433\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u2026
 ConfigView.label.minSpeedForActiveSeeding=\u0414\u0430 \u043d\u0435 \u0441\u0435 \u0441\u0447\u0438\u0442\u0430, \u0447\u0435 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d \u0442\u043e\u0440\u0435\u043d\u0442 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0433\u043d\u0435\u0437\u0434\u043e, \u0430\u043a\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430 \u0435 \u043f\u043e\u0434
 ConfigView.section.stats.exportpeers=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u0437\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d
-MainWindow.menu.view.irc.moved=IRC \u0435 \u043d\u0430 \u0440\u0430\u0437\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0442\u043e \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u0432\u0436. http://azureus.sourceforge.net/plugin_list.php. \u0421\u043b\u0435\u0434 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043c\u0435\u043d\u044e '\u0418\u0437\u0433\u043b\u04 [...]
+MainWindow.menu.view.irc.moved=IRC \u0435 \u043d\u0430 \u0440\u0430\u0437\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0442\u043e \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u0432\u0436. http://azureus.sourceforge.net/plugin_list.php. \u0421\u043b\u0435\u0434 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043c\u0435\u043d\u044e '\u0418\u043d\u0441\u0442\u04 [...]
 MyTrackerView.webui.contextmenu.copyurl=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 URL \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 \u0432 \u043a\u043b\u0438\u043f\u0431\u043e\u0440\u0434\u0430
 ConfigView.section.file.torrent.ignorefiles=\u0424\u0430\u0439\u043b\u043e\u0432\u0435 \u0437\u0430 \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u0432\u0430\u043d\u0435 \u043f\u0440\u0438 \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\n\u043f\u0440. .DS_Store;Thumbs.db;Desktop.ini
 Torrent.create.progress.ignoringfile=\u041f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b
@@ -1052,13 +1045,13 @@ ConfigView.label.seeding.autoStart0Peers=\u0410\u0432\u0442\u043e\u043c\u0430\u0
 ConfigView.label.seeding.autoStart0Peers.tooltip=\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u0442\u0440\u0430\u043a\u0435\u0440\u044a\u0442 \u0432\u0438\u043d\u0430\u0433\u0438 \u043f\u043e\u043a\u0430\u0437\u0432\u0430 \u043f\u043e\u0441\u044f\u0432\u043a\u0438 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0441 0 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438.
 dialog.associations.prompt=Vuze \u043d\u0435 \u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 BitTorrent \u0444\u0430\u0439\u043b\u043e\u0432\u0435.\n\u0414\u0430 \u0441\u0435 \u0430\u0441\u043e\u0446\u0438\u0438\u0440\u0430\u0442 \u043b\u0438 .torrent \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0441 Vuze?
 dialog.associations.askagain=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435
-ConfigView.section.plugins.update=\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430
-Plugin.pluginupdate.enablecheck=\u0421 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430
+ConfigView.section.plugins.update=\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438
+Plugin.pluginupdate.enablecheck=\u0421 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438\u0442\u0435
 plugins.basicview.status=\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435:
 plugins.basicview.activity=\u0414\u0435\u0439\u043d\u043e\u0441\u0442:
 plugins.basicview.progress=\u0420\u0430\u0437\u0432\u0438\u0442\u0438\u0435:
 plugins.basicview.log=\u0414\u043d\u0435\u0432\u043d\u0438\u043a:
-ConfigView.label.maxdownloadspeed=KB/s \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ConfigView.label.maxdownloadspeed=KB/s \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u0430 \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 splash.loadingTorrent=\u0417\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 
 splash.of=\u043e\u0442
 ConfigView.section.plugins.irc=\u041c\u0440\u0435\u0436\u0430 IRC
@@ -1083,7 +1076,6 @@ ConfigView.pluginlist.whereToPutOr=\u0417\u0430 \u0441\u043f\u043e\u0434\u0435\u
 MainWindow.statusText.checking=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438
 TableColumn.header.OnlyCDing4=\u0421\u0430\u043c\u043e \u0441\u0435\u0435\u043d\u0435 \u0437\u0430
 TableColumn.header.OnlyCDing4.info=\u0412\u0440\u0435\u043c\u0435\u0442\u043e \u043f\u0440\u0435\u0437 \u043a\u043e\u0435\u0442\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u044a\u0442 \u0441\u0430\u043c\u043e \u0435 \u0441\u044f\u0442. \u041d\u0435 \u0432\u043a\u043b\u044e\u0447\u0432\u0430 \u0432\u0440\u0435\u043c\u0435\u0442\u043e \u043f\u0440\u0435\u0437 \u043a\u043e\u0435\u0442\u043e \u0435 \u0441\u0432\u0430\u043b\u044f\u043d \u0438 \u0441\u044f\u0442.
-ConfigView.section.style.alternateTablePainting=\u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430 \u0438\u0437\u0440\u0438\u0441\u0443\u0432\u0430\u043d\u0435 \u043a\u043e\u043b\u043e\u043d\u0438\u0442\u0435 \u043d\u0430 \u0433\u0440\u0430\u0444\u0438\u0447\u043d\u0430\u0442\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 (\u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0438\u0441\u043a\u043 [...]
 UpdateWindow.status.restartMaybeNeeded=\u041c\u043e\u0436\u0435 \u0434\u0430 \u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0440\u0435\u0441\u0442\u0430\u0440\u0442
 ConfigView.pluginlist.shared=\u0441\u043f\u043e\u0434\u0435\u043b\u0435\u043d
 PeersView.host=\u0418\u043c\u0435 \u043d\u0430 \u043f\u043e\u0434\u0441\u043b\u043e\u043d
@@ -1136,7 +1128,6 @@ webui.access.info=\u0414\u043e\u0441\u0442\u044a\u043f\u044a\u0442 \u043c\u043e\
 GeneralView.label.maxdownloadspeed=\u041c\u0430\u043a\u0441. \u0421\u0432.
 Security.keystore.corrupt=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0435 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u0442\u043e \u0437\u0430 \u043a\u043b\u044e\u0447\u043e\u0432\u0435 '%1', \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0442\u0440\u0438\u0435 \u0438 \u0434\u0430 \u0441\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0430\u0442 \u043e\u0442\u043d\ [...]
 Security.keystore.empty=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435\u0442\u043e \u0437\u0430 \u043a\u043b\u044e\u0447\u043e\u0432\u0435 \u0435 \u043f\u0440\u0430\u0437\u043d\u043e. \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435 \u0441\u0430\u043c\u043e\u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 (\u0434\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 '\u0418\ [...]
-webui.restart.info=\u041f\u0440\u043e\u043c\u044f\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u043e\u0442\u0431\u0435\u043b\u044f\u0437\u0430\u043d\u0438 \u0441  (*) \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435
 GeneralView.label.maxdownloadspeed.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 ConfigView.section.UPnP=UPnP \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 upnp.enable=\u0421 UPnP
@@ -1203,8 +1194,6 @@ MyTrackerView.badnat.info=\u041f\u043e\u0441\u044f\u0432\u043a\u0438/\u0440\u043
 ConfigView.section.tracker.natchecktimeout=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 [s]
 ConfigView.section.file.perf.cache.enable=\u041f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0438\u0441\u043a\u043e\u0432 \u043a\u0435\u0448
 ConfigView.section.file.perf.cache.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0430 \u043a\u0435\u0448\u0430 \u0432 %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=\u0422&\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0438
 MainWindow.menu.transfers.startalltransfers=&\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438
 MainWindow.menu.transfers.stopalltransfers=&\u0421\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438
@@ -1222,10 +1211,10 @@ TransferStatsView.title.full=\u0422\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0
 CacheView.title.full=\u0411\u0443\u0444\u0435\u0440
 CacheView.general.size=\u041f\u044a\u043b\u0435\u043d \u0440\u0430\u0437\u043c\u0435\u0440
 CacheView.general.inUse=\u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0441\u0435
-CacheView.general.title=\u041a\u0435\u0448 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
+CacheView.general.title=\u0411\u0443\u0444\u0435\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
 CacheView.reads.title=\u0412/\u0418 \u043f\u0440\u043e\u0447\u0438\u0442\u0438
 CacheView.reads.fromFile=\u041e\u0442 \u0444\u0430\u0439\u043b
-CacheView.reads.fromCache=\u041e\u0442 \u043a\u0435\u0448
+CacheView.reads.fromCache=\u041e\u0442 \u0431\u0443\u0444\u0435\u0440
 CacheView.reads.hits=\u041f\u043e\u043f\u0430\u0434\u0435\u043d\u0438\u044f
 CacheView.writes.title=\u0412/\u0418 \u0437\u0430\u043f\u0438\u0441\u0438
 CacheView.writes.toCache=\u0412 \u0431\u0443\u0444\u0435\u0440
@@ -1257,7 +1246,7 @@ Security.jar.tools_not_found=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u
 Security.jar.signfail=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 JAR - %1
 ConfigView.section.security.toolsinfo=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u0442\u0435 JAR \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0437\u0430 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u043d\u0430 \u043d\u044f\u043a\u043e\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441  [...]
 ConfigView.section.security.toolsdir=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430 'tools.jar'
-ConfigView.section.security.choosetoolssavedir=\u041f\u0430\u043f\u043a\u0430, \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430 'tools.jar'
+ConfigView.section.security.choosetoolssavedir=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430 'tools.jar'
 authenticator.torrent=\u0422\u043e\u0440\u0435\u043d\u0442
 ConfigView.section.proxy.peer.same=\u0415\u0434\u043d\u0438 \u0438 \u0441\u044a\u0449\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0442\u0440\u0430\u043a\u0435\u0440\u0441\u043a\u0438 \u043a\u043e\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0442\u0435\u0437\u0438 \u0441 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u043e\u043f\u0438\u0442\u0438 \u0437\u0430 \u0438\u0437\u0445\u043e\u0434\u044f\u0449\u0438 \u0432\u0440\u044a\u0437\u043a\u0438 
@@ -1323,18 +1312,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=\u0420\u0430\u0437\u043c\u0435\
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0437\u0430 \u0446\u043e\u043a\u044a\u043b SO_SNDBUF (\u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u0435), \u0442.\u0435. \u0440\u0430\u0437\u043c\u0435\u0440\u044a\u0442 \u043d\u0430 TCP \u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446 \u0437\u0430 \u0438\u0437\u043f\u [...]
 ConfigView.section.connection.advanced.IPDiffServ=\u0421\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0437\u0430 DiffServ \u043d\u0430 \u0438\u0437\u0445\u043e\u0434\u044f\u0449\u0438 \u043f\u0430\u043a\u0435\u0442\u0438 (TOS \u043f\u043e\u043b\u0435)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430 DiffServ \u0447\u0430\u0441\u0442\u0442\u0430 \u043e\u0442 TOS \u043f\u043e\u043b\u0435\u0442\u043e \u0432 IP \u0437\u0430\u0433\u043b\u0430\u0432\u043a\u0430\u0442\u0430 \u043d\u0430 \u0438\u0437\u0445\u043e\u0434\u044f\u0449\u0438\u0442\u0435 \u043f\u0430\u043a\u0435\u0442\u0438.\n\u0428\u0435\u0441\u0442\u043d\u0430\u0434\u0435\u0441\u0435\u0442\u0438\u0447\u043d\u043 [...]
-ConfigView.section.interface.confirm_torrent_removal=\u0414\u0438\u0430\u043b\u043e\u0433 \u0437\u0430 \u043f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442 \u043e\u0442 \u0438\u0437\u0433\u043b\u0435\u0434 \u041c\u0435\u0441\u0442\u043d\u0438 \u0422\u043e\u0440\u0435\u043d\u0442\u0438
-MyTorrentsView.confirm_torrent_removal=\u0414\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0435 \u043b\u0438?\n
 TableColumn.header.seed_to_peer_ratio=\u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0435\u0435\u043d\u0435/\u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 TableColumn.header.seed_to_peer_ratio.info=\u041e\u0431\u0449\u043e \u0437\u0430 \u0440\u043e\u044f\u043a\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0435\u0435\u043d\u0435/\u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 PeersView.connected_time=\u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430
 PeersView.connected_time.info=\u041e\u0431\u0449\u043e\u0442\u043e \u0432\u0440\u0435\u043c\u0435 \u043d\u0430 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442 \u0441 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438\u044f
-ConfigView.section.interface.display.add_torrents_silently=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0442\u0438\u0445\u043e\u043c\u044a\u043b\u043a\u043e\u043c
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u0431\u0435\u0437 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0438\u044f \u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446 \u043d\u0430 Vuze.
 TableColumn.header.maxdownspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
 TableColumn.header.maxdownspeed.info=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
-PeersGraphicView.title=\u0420\u043e\u044f\u043a
+PeersGraphicView.title.full=\u0420\u043e\u044f\u043a
 ConfigView.section.tracker.passwordwebhttpsonly=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u0441\u0430\u043c\u043e \u0447\u0440\u0435\u0437 HTTPS
 TableColumn.header.torrentpath=\u041c\u044f\u0441\u0442\u043e \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
 TableColumn.header.torrentpath.info=\u041c\u044f\u0441\u0442\u043e \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u0432\u044a\u0440\u0445\u0443 \u0434\u0438\u0441\u043a\u0430
@@ -1361,8 +1345,8 @@ installPluginsWizard.finish.explanation=\u0418\u0437\u0431\u0440\u0430\u043d\u04
 installPluginsWizard.details.loading=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u0437\u0430 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438\u0085\u2026
 installPluginsWizard.mode.file=\u041f\u043e \u0444\u0430\u0439\u043b
 installPluginsWizard.installMode.title=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0432\u0438\u0434\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f
-installPluginsWizard.installMode.user=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430(\u0438\u0442\u0435) \u0437\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b
-installPluginsWizard.installMode.shared=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430(\u0438\u0442\u0435) \u0437\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438
+installPluginsWizard.installMode.user=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430/\u0438 \u0437\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b
+installPluginsWizard.installMode.shared=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430/\u0438 \u0437\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438
 installPluginsWizard.file.title=\u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u0437\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u043a\u043e\u044f\u0442\u043e \u0434\u0430 \u0441\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430
 installPluginsWizard.file.file=\u0424\u0430\u0439\u043b:
 installPluginsWizard.file.invalidfile=\u0424\u0430\u0439\u043b\u044a\u0442 \u043d\u0435 \u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0437\u0430 Vuze.
@@ -1391,8 +1375,6 @@ UpdateWindow.restartLater=\u041f\u043e-\u043a\u044a\u0441\u0435\u043d \u0440\u04
 MainWindow.menu.file.restart=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Vuze
 MainWindow.dialog.restartconfirmation.title=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Vuze?
 MainWindow.dialog.restartconfirmation.text=\u041d\u0430\u0438\u0441\u0442\u0438\u043d\u0430 \u043b\u0438 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 Vuze?
-deletetorrent.message1=\u041f\u0440\u0435\u0434 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0422\u041e\u0420\u0415\u041d\u0422 \u0437\u0430:\n
-deletetorrent.message2=\n\u0414\u0430 \u0431\u044a\u0434\u0435 \u043b\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u0435\u043d\u043e?
 ConfigView.label.prioritizemostcompletedfiles=\u041f\u043e\u0441\u043b\u0435\u0434\u0432\u0430\u0449\u043e \u043f\u043e\u0432\u0438\u0448\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u0432\u0438\u0441\u043e\u043a \u0442\u0430\u043a\u044a\u0432 \u0441\u043f\u043e\u0440\u0435\u0434 % \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e\u0441\u0442 \u0438 \u0440\u0430\u0437 [...]
 splash.plugin.init=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430: 
 splash.plugin.UIinit=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0413\u041f\u0418 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430: %1  
@@ -1558,10 +1540,11 @@ TableColumn.header.commenticon.info=\u041f\u043e\u043a\u0430\u0437\u0432\u0430 \
 MyTrackerView.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f
 MainWindow.menu.file.open.torrentfortracking=\u0422\u043e\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b\u0085\u2026 (\u0437\u0430 \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u044f\u0432\u0430\u043d\u0435 \u0441\u0430\u043c\u043e)
 VivaldiView.title.full=\u0412\u0438\u0432\u0430\u043b\u0434\u0438
+VivaldiView.title.fullcvs=\u0412\u0438\u0432\u0430\u043b\u0434\u0438 CVS
+VivaldiView.title.full_v6=\u0412\u0438\u0432\u0430\u043b\u0434\u0438 IPv6
 MyTrackerView.date_added=\u0414\u043e\u0431\u0430\u0432\u0435\u043d\u043e
 ConfigView.section.tracker.portbackup=\u0417\u0430\u043f\u0430\u0300\u0441 \u043d\u0430 \u043f\u043e\u0440\u0442\u043e\u0432\u0435 (';' \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b)
 ConfigView.label.playfilespeech=\u0413\u043b\u0430\u0441\u043e\u0432\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u0438\u0435 \u043f\u0440\u0438 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d \u0444\u0430\u0439\u043b
-ConfigView.label.playfilespeech.info=\u0423\u0441\u043b\u0443\u0433\u0438\u0442\u0435 \u0437\u0430 \u0440\u0435\u0447 \u043d\u0430\u0439-\u0434\u043e\u0431\u0440\u0435 \u0440\u0430\u0431\u043e\u0442\u044f\u0442 \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430
 ConfigView.label.playfilefinished=\u0417\u0432\u0443\u043a\u043e\u0432 \u0441\u0438\u0433\u043d\u0430\u043b \u043f\u0440\u0438 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d \u0444\u0430\u0439\u043b
 ConfigView.label.backupconfigfiles=\u0417\u0430\u043f\u0430\u0441 \u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0437\u0430 \u0432\u044a\u0437\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043f\u0440\u0438 \u043d\u0443\u0436\u0434\u0430
 ConfigView.section.tracker.client.scrapesingleonly=\u0417\u0430\u0431\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430\u0442\u0440\u0443\u043f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043e\u0441\u0442\u044a\u0440\u0433\u0432\u0430\u043d\u0438\u044f \u0437\u0430 \u0442\u0440\u0430\u043a\u0435\u0440 \u043f\u043e\u043e\u0442\u0434\u0435\u043b\u043d\u043e (\u043f\u043e\u043c\u0430\u0433\u0430 \u043f\u0440\u0438 \u0442\u0440\u0430\u043a\u0435\u0440\u0438 \u0438\u0437\u04 [...]
@@ -1622,7 +1605,7 @@ configureWizard.welcome.usermodes=\u041e\u043f\u0438\u0442\u044a\u0442 \u043d\u0
 FilesView.skip.confirm.delete.text=\u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b '%1' \u0437\u0430 \u0438\u043a\u043e\u043d\u043e\u043c\u0438\u044f \u043d\u0430 \u043c\u044f\u0441\u0442\u043e?
 FilesView.rename.failed.title=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435\u0442\u043e/\u0441\u043c\u044f\u043d\u0430\u0442\u0430 \u043d\u0430 \u0446\u0435\u043b\u0442\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438
 FilesView.rename.failed.text=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0437\u0430\u0440\u0430\u0434\u0438 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u0435\u043d \u0438\u0437\u0431\u043e\u0440 \u043d\u0430 \u0446\u0435\u043b
-diagnostics.log_found=\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u0430 \u0441 Vuze \u043d\u0435 \u0435 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u043e. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435 \u0437\u0430 <A HREF="%1">\u0434\u043d\u0435\u0432\u043d\u0438\u0446\u0438 \u0441 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430</A>. \u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u044 [...]
+diagnostics.log_found=\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u0430 \u0441 Vuze \u043d\u0435 \u0435 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u043e. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435 \u0437\u0430 <A HREF="%1">\u0434\u043d\u0435\u0432\u043d\u0438\u0446\u0438 \u0441 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430</A>. \u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u044 [...]
 ManagerItem.paused=\u0412 \u043f\u0430\u0443\u0437\u0430
 Utils.link.visit=\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438
 ConfigView.section.connection.serverport.wiki=\u0418\u0437\u0431\u0440\u0430\u043d\u0438 \u0434\u043e\u0431\u0440\u0438 \u043f\u043e\u0440\u0442\u043e\u0432\u0435
@@ -1631,7 +1614,7 @@ installPluginsWizard.installMode.info.title=\u0418\u043d\u0444\u043e\u0440\u043c
 installPluginsWizard.installMode.info.text=\u041d\u0435 \u0441\u0430 \u043d\u0443\u0436\u043d\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u0437\u0430 \u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u043e Vuze, \u043d\u043e \u0442\u0435 \u043f\u0440\u0438\u0431\u0430\u0432\u044f\u0442 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u04 [...]
 Views.plugins.Distributed.DB.title=\u0420\u0430\u0437\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0411\u0414
 Views.plugins.Distributed.Tracker.title=\u0420\u0430\u0437\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0442\u0440\u0430\u043a\u0435\u0440
-Views.plugins.Plugin.Update.title=\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430
+Views.plugins.Plugin.Update.title=\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438
 Views.plugins.UPnP.title=UPnP \u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430
 Views.plugins.UPnP.title.tooltip=\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u0435\u043d\u043e \u041f\u0440\u0438\u0441\u044a\u0435\u0434\u0438\u043d\u044f\u0432\u0430\u043d\u0435 \u0438 \u041f\u043e\u043b\u0437\u0432\u0430\u043d\u0435
 openUrl.url.info=\u041f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 HTTP, HTTPS, magnet \u0438 raw hex infohash \u043d\u0438\u0437\u043e\u0432\u0435
@@ -1646,7 +1629,7 @@ MainWindow.nat.status.probok=NAT \u043f\u0440\u043e\u0431\u0430 \u043d\u043e\u04
 MainWindow.nat.status.tooltip.probok=\u0414\u043e\u0441\u0435\u0433\u044a\u0442 \u0431\u0435\u0448\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u0435\u043d, \u043d\u043e \u043d\u044f\u043c\u0430 \u0441\u043a\u043e\u0440\u043e\u0448\u043d\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438 TCP \u0432\u0440\u044a\u0437\u043a\u0438
 MainWindow.nat.status.bad=\u0417\u0430\u0434 \u0437\u0430\u0449\u0438\u0442\u043d\u0430 \u0441\u0442\u0435\u043d\u0430
 MainWindow.nat.status.tooltip.bad=\u041f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0434\u043e\u0301\u0441\u0435\u0433\u0430 \u043f\u0440\u0438 \u0437\u0430\u0449\u0438\u0442\u043d\u0430 \u0441\u0442\u0435\u043d\u0430/NAT \u043f\u0440\u0435\u0437 TCP. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 Wiki \u0437\u0430 \u043f\u043e\u043c\u043e\u0449
-plugin.installer.recommended.plugin=\u041f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0438\u0442\u0435\u043b\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 - \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430 \u0438 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430, \u0430\u043a\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e
+plugin.installer.recommended.plugin=\u041f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 - \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430 \u0438 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430, \u0430\u043a\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e
 LoggerView.pause=\u041f\u0430\u0443\u0437\u0430 \u043d\u0430 \u0434\u043d\u0435\u0432\u043d\u0438\u043a\u0430
 LoggerView.clear=\u0418\u0437&\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435
 LoggerView.filter=\u0424\u0438\u043b\u0442\u044a\u0440
@@ -1691,7 +1674,7 @@ MyTorrentsView.dialog.setNumber.download=\u0441\u0432\u0430\u043b\u044f\u043d\u0
 MyTorrentsView.dialog.setNumber.inKbps=\u0432 %1
 OpenTorrentWindow.torrentLocation=\u0422\u043e\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0435:
 OpenTorrentWindow.addFiles.URL=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 &URL
-OpenTorrentWindow.addFiles.Folder=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 &\u043f\u0430\u043f\u043a\u0430
+OpenTorrentWindow.addFiles.Folder=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 &\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
 OpenTorrentWindow.addFiles.Clipboard=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043e\u0442 \u043a\u043b\u0438\u043f&\u0431\u043e\u0440\u0434\u0430
 OpenTorrentWindow.changeDestination=\u041f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u043e\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u0442\u043e
 OpenTorrentWindow.fileList=\u0424\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0442\u043e\u0440\u0435\u043d\u0442\u0438:
@@ -1851,7 +1834,7 @@ MagnetPlugin.decentral_disabled=<\u0431\u0435\u0437 \u0434\u0435\u0446\u0435\u04
 MagnetPlugin.decentral_backup_disabled=<\u0431\u0435\u0437 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d \u0437\u0430\u043f\u0430\u0300\u0441>
 MagnetPlugin.report.waiting_ddb=\u0438\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u0437\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u0420\u0411\u0414\u2026
 MagnetPlugin.report.searching=\u0442\u044a\u0440\u0441\u0435\u043d\u0435\u2026
-MagnetPlugin.report.found=\u043d\u0430\u043c\u0435\u0442\u0435\u043d %1
+MagnetPlugin.report.found=\u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438 %1
 MagnetPlugin.report.alive=%1 \u0435 \u0436\u0438\u0432
 MagnetPlugin.report.dead=%1 \u0435 \u043c\u044a\u0440\u0442\u044a\u0432
 MagnetPlugin.report.tunnel=\u043f\u043e \u0442\u0443\u043d\u0435\u043b \u0434\u043e %1
@@ -1896,7 +1879,7 @@ upnp.ignorebaddevices=\u041f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u04
 upnp.ignorebaddevices.info=\u0422\u0435\u043a\u0443\u0449\u043e \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u043d\u0430\u0442\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430: %1
 upnp.ignorebaddevices.reset=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441 \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u043d\u0430\u0442\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
 upnp.ignorebaddevices.reset.action=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430
-upnp.ignorebaddevices.alert=UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e, \u043d\u0430\u043c\u0438\u0440\u0430\u0449\u043e \u0441\u0435 \u043d\u0430 %1 \u0435 \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u043d\u0430\u0442\u043e \u043f\u043e\u0440\u0430\u0434\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0438. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u04 [...]
+upnp.ignorebaddevices.alert=UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e, \u043d\u0430\u043c\u0438\u0440\u0430\u0449\u043e \u0441\u0435 \u043d\u0430 %1 \u0435 \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u043d\u0430\u0442\u043e \u043f\u043e\u0440\u0430\u0434\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0438. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u04 [...]
 TorrentOptionsView.param.max.uploads.when.busy=KB/s \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u043d\u0435 \u043d\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u043e\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 [0: \u0438\u0437\u043a\u043b\u044e\u0447\u04 [...]
 UpdateMonitor.messagebox.verification.failed.title=\u041f\u0440\u043e\u0432\u0430\u043b \u0432 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430
 UpdateMonitor.messagebox.verification.failed.text=\u0423\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 '%1' \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438: %2
@@ -1918,7 +1901,7 @@ ConfigView.section.NATPMP=NAT-PMP \u0437\u0430 \u041c\u0430\u043a
 natpmp.info=NAT-PMP \u0435 \u0430\u043b\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430\u0442\u0430 \u043d\u0430 Apple \u0437\u0430 UPnP \u0438 \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u043e\u0442 \u043f\u043e-\u043d\u043e\u0432\u0438\u0442\u0435 Airport \u0441\u0442\u0430\u043d\u0446\u0438\u0438\n\nUPnP \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043f\u0443\u0441\u043d\u0430\u0442\u043e, \u0437\u0430 \u0434\u0430 \u0441\u0435  [...]
 natpmp.enable=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0432\u0430\u043d\u0435 (\u0449\u0435 \u0440\u0430\u0431\u043e\u0442\u0438, \u0430\u043a\u043e \u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 Airport \u0441\u0442\u0430\u043d\u0446\u0438\u044f\u0442\u0430)
 ConfigView.section.tracker.host.addurls=\u0423\u0442\u0432\u044a\u0440\u0436\u0434\u0430\u0432\u0430\u043d\u0435, \u0447\u0435 \u0442\u0440\u0430\u043a\u0435\u0440\u0441\u043a\u0438\u0442\u0435 URL-\u0442\u0430 \u043f\u0440\u0438\u0441\u044a\u0441\u0442\u0432\u0430\u0442 \u0432 \u043f\u043e\u0434\u0441\u043b\u043e\u043d\u0435\u043d\u0438\u0442\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
-ConfigView.filter=\u0432\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0442\u0435\u043a\u0441\u0442 \u0437\u0430 \u0444\u0438\u043b\u0442\u044a\u0440
+ConfigView.filter=\u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 ConfigView.section.files.move=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435\u0442\u043e
 ConfigView.section.file.defaultdir.section=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
 ConfigView.section.file.defaultdir.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 (\u0431\u0435\u0437 \u043f\u043e\u0434\u0441\u0435\u0449\u0430\u043d\u0435)
@@ -1961,8 +1944,11 @@ MainWindow.menu.view.iconbar=\u041b\u0435\u043d\u0442\u0430 \u0441 \u0438\u043d\
 MyTorrentsView.menu.rename=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435
 MyTorrentsView.menu.rename.displayed=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e\u0442\u043e \u0438\u043c\u0435
 MyTorrentsView.menu.rename.save_path=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u044a\u0442\u044f \u0437\u0430 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435
+AdvRenameWindow.title=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+AdvRenameWindow.message=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u043d\u043e\u0432\u043e \u0438\u043c\u0435 \u0437\u0430 \u0442\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435.
+AdvRenameWindow.rename.torrent=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 MyTorrentsView.menu.rename.displayed.enter.title=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e\u0442\u043e \u0438\u043c\u0435
-MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u043c\u0435 \u0437\u0430 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u0437\u0430 \u0442\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435.\n\u041f\u0440\u0438 \u043d\u0435\u0432\u044a\u0432\u0435\u0434\u0435\u043d \u0442\u0435\u043a\u0441\u0442 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u044 [...]
+MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u043c\u0435 \u0437\u0430 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u0437\u0430 \u0442\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435.
 MyTorrentsView.menu.edit_comment=\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 MyTorrentsView.menu.edit_comment.enter.title=\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
 MyTorrentsView.menu.edit_comment.enter.message=\u0412\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440 \u0437\u0430 \u0442\u043e\u0432\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435.
@@ -1972,26 +1958,16 @@ UIDebugGenerator.complete.title=\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d
 UIDebugGenerator.complete.text=\u0414\u0430 \u0441\u0435 \u0438\u0437\u043f\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043b '%1' \u0434\u043e az-bugreports at Vuze-inc.com\n\n\u0414\u0430 \u0441\u0435 \u043d\u0430\u0442\u0438\u0441\u043d\u0435 '\u0414\u0430' \u0437\u0430 \u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446 \u043a\u044a\u043c \u0442\u043e\u0437\u0438 \u0444\u0430\u0439\u043b.
 ConfigView.section.style.showProgramIcon=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043d\u0430 \u0438\u043a\u043e\u043d\u0430 \u0432 \u043a\u043e\u043b\u043e\u043d\u0430\u0442\u0430 \u0437\u0430 \u0438\u043c\u0435
 ConfigView.section.style.showProgramIcon.tooltip=\u0418\u0437\u0433\u043b\u0435\u0434\u044a\u0442 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043e\u0442\u043d\u043e\u0432\u043e, \u0437\u0430 \u0434\u0430 \u0432\u043b\u044f\u0437\u0430\u0442 \u0432 \u0441\u0438\u043b\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435
-swt.alert.cant.update=SWT \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430 \u0437\u0430\u0440\u0435\u0434\u0435\u043d\u0430 \u043e\u0442 "%3" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u044f %1 \u043a\u044a\u043c %2 (\u0434\u0430 \u0441\u0435 \u [...]
+swt.alert.cant.update=SWT \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430 \u0437\u0430\u0440\u0435\u0434\u0435\u043d\u0430 \u043e\u0442 "%3" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u044f %1 \u043a\u044a\u043c %2 (\u0434\u0430 \u0441\u0435 \u [...]
 authenticator.savepassword=\u0417\u0430\u043f\u043e\u043c\u043d\u044f\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430
 ConfigView.section.security.clearpasswords=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u0438
 ConfigView.section.security.clearpasswords.button=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430
-Content.alert.notuploaded.title=\u041d\u0435\u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u043a\u0430\u0447\u0432\u0430\u043d\u0435
-Content.alert.notuploaded.text=%1 \u043e\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u043e\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0435 \u0441\u0430 \u043d\u0430\u043f\u044a\u043b\u043d\u043e \u043f\u043e\u0441\u044f\u0442\u0438. \u0410\u043a\u043e \u0441\u0435 %2 \u0441\u0435\u0433\u0430, \u0434\u0440\u0443\u0433\u0438\u0442\u0435 \u043d\u044f\u043c\u0430 \u0434\u0430 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0432 [...]
-Content.alert.notuploaded.multi.title=\u041d\u0435\u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0438 \u043a\u0430\u0447\u0432\u0430\u043d\u0438\u044f
-Content.alert.notuploaded.multi.text=%1 \u043e\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u043e\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0435 \u0441\u0430 \u043d\u0430\u043f\u044a\u043b\u043d\u043e \u043f\u043e\u0441\u044f\u0442\u0438. \u0410\u043a\u043e \u0441\u0435 %2 \u0441\u0435\u0433\u0430, \u0434\u0440\u0443\u0433\u0438\u0442\u0435 \u043d\u044f\u043c\u0430 \u0434\u0430 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441 [...]
-Content.alert.notuploaded.stop=\u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438
-Content.alert.notuploaded.quit=\u0438\u0437\u043b\u0435\u0437\u0435 \u043e\u0442 Vuze
 TorrentInfoView.torrent.encoding=\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 TorrentInfoView.columns=\u041a\u043e\u043b\u043e\u043d\u0438 \u043e\u0442 \u0438\u0437\u0433\u043b\u0435\u0434 '\u041c\u0435\u0441\u0442\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438'
 progress.window.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435
 progress.window.msg.filemove=\u0414\u0430 \u0441\u0435 \u0438\u0437\u0447\u0430\u043a\u0430 \u0434\u043e \u0437\u0430\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435 \u043f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435\u0442\u043e/\u043f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0444\u0430\u0439\u043b\u0430
 ConfigView.label.popup.timestamp=\u0421 \u0432\u0440\u0435\u043c\u0435-\u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u0432\u044a\u0440\u0445\u0443 \u0438\u0437\u0441\u043a\u0430\u0447\u0430\u0449\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
 ConfigView.label.popup.autohide=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0441\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0441\u043a\u0430\u0447\u0430\u0449\u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f, \u043a\u043e\u0438\u0442\u043e \u043d\u0435 \u0441\u0430 \u0433\u0440\u0435\u0448\u043a\u0438 [s] [0: \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u043e]
-ConfigView.label.popup.suppress_alerts=\u041f\u043e\u0442\u0438\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
-ConfigView.label.popup.use_message_boxes=\u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0441\u043a\u0430\u0447\u0430\u0449\u0438 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u0434\u0438\u0430\u043b\u043e\u0433 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438 \u0438\u0437\u0441\u043a\u0430\u0447\u0430\u0449\u0438 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u044f.
-ConfigView.label.popup.show=\u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0438 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f (\u0430\u043a\u043e \u0438\u043c\u0430)
-ConfigView.label.popup.show.button=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435
 ConfigView.label.please.visit.here=\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438 \u0442\u0443\u043a \u0437\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
 ConfigView.section.ipfilter.enable.descriptionCache=\u0421\u044a\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 IP \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f\u0442\u0430 \u0432\u044a\u0432 \u0444\u0430\u0439\u043b
 ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u0410\u043a\u043e \u043d\u0435 \u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u043e, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f\u0442\u0430 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043c\u043d\u044f\u0442
@@ -2020,7 +1996,7 @@ ConfigView.section.connection.http.portoverride=\u0422\u0440\u0430\u043a\u0435\u
 window.update.noupdates.title=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438\u0442\u0435 \u043e\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438
 window.update.noupdates.text=\u041d\u044f\u043c\u0430 \u043d\u0430\u043b\u0438\u0447\u043d\u0438 \u043d\u043e\u0432\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f.\n\n\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f!
 ConfigView.label.bindip.details=\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: 192.168.1.5;eth0;eth1[2] \u0449\u0435 \u043f\u0440\u0438\u0432\u044a\u0440\u0436\u0435 \u0443\u043a\u0430\u0300\u0437\u0430\u043d\u0438\u044f IP \u043a\u044a\u043c \u0432\u0441\u0438\u0447\u043a\u0438 IP-\u0442\u0430 \u043d\u0430 1-\u0432\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 3-\u0442\u0438\u044f IP \u043d\u0430 2-\u0440\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0 [...]
-ConfigView.label.mindownloads=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
+ConfigView.label.mindownloads=\u041c\u0438\u043d. \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
 UI.cannot_submit_blank_text=\u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442.
 crypto.alert.as.warning=\u041c\u0440\u0435\u0436\u0430 '%1' \u0435 \u0441 \u043d\u0430\u043b\u043e\u0436\u0435\u043d \u043e\u0444\u043e\u0440\u043c\u0435\u043d \u0442\u0440\u0430\u0444\u0438\u043a \u0437\u0430 \u043d\u0430\u043c\u0430\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044f\u043d\u0435\u0442\u043e \u043f\u0440\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0435. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e [...]
 ConfigView.section.interface.alerts=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
@@ -2121,7 +2097,6 @@ window.uiswitcher.text=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u043d\u0430\
 window.uiswitcher.NewUI.text=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u044f \u043d\u0430\u0439-\u0440\u0430\u0444\u0438\u043d\u0438\u0440\u0430\u043d \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.\n\n\u041f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0441\u0435 \u0437\u0430 \u043d\u043e\u0432\u0438 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0449\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438.
 window.uiswitcher.ClassicUI.title=\u041a\u043b\u0430\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
 window.uiswitcher.ClassicUI.text=\u0417\u0430 \u043d\u0435\u0436\u0435\u043b\u0430\u0435\u0449\u0438\u0442\u0435 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u043d\u043e\u0432\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, Vuze \u0449\u0435 \u0440\u0430\u0431\u043e\u0442\u0438 \u043f\u043e \u0441\u044a\u0449\u0438\u044f \u043d\u0430\u0447\u0438\u043d, \u043a\u0430\u043a\u0442\u043e \u043f\u0440\u0438 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u043e [...]
-window.uiswitcher.bottom.text=\u0418\u0437\u0431\u043e\u0440\u044a\u0442 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u0435\u043d \u0447\u0440\u0435\u0437 \u0431\u0443\u0442\u043e\u043d\u0430 "UI" \u0437\u0430 \u0438\u0437\u0431\u043e\u0440 \u043d\u0430 \u0413\u041f\u0418 \u043d\u0430 Vuze
 iconBar.switch.tooltip=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0413\u041f\u0418 \u0437\u0430 Vuze
 VivaldiView.notAvailable=\u041d\u044f\u043c\u0430 Vivaldi \u0438\u0437\u0433\u043b\u0435\u0434
 restart.error=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442:\n%1\n\u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 <A HREF="{restart.error.url}">restarting issues</a>.
@@ -2148,12 +2123,7 @@ TableColumn.header.SpeedGraphic=\u0421\u043a\u043e\u0440\u043e\u0441\u0442
 TableColumn.header.AzProduct=\u041e\u0442
 TableColumn.header.MediaThumb=\u041d\u043e\u0441\u0438\u0442\u0435\u043b
 TableColumn.header.ProgressETA=\u0420\u0430\u0437\u0432\u0438\u0442\u0438\u0435
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
 TableColumn.header.name.ext=\u0422\u0438\u043f \u043d\u0430 \u0444\u0430\u0439\u043b: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
 v3.MainWindow.tab.home=\u041d\u0430\u0447\u0430\u043b\u043e
 v3.MainWindow.tab.browse=\u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
 v3.MainWindow.tab.library=\u041c\u0435\u0441\u0442\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
@@ -2187,22 +2157,11 @@ v3.mb.delPublished.title=\u0421\u043f\u0438\u0440\u0430\u043d\u0435 \u0441\u0435
 v3.mb.delPublished.text=\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415: \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u0442\u043e \u041d\u0415 \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u043e\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 '%1' \u043e\u0442 <A HREF="%2">%3</A> .\n\n\u0414\u0430 \u0441\u0435 \u043d\u0430\u0442\u0438\u0441\u043d\u0435 '\u0418\u0437\u0442\u0440\u0438\u0432\u0430 [...]
 v3.mb.delPublished.delete=&\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435
 v3.mb.delPublished.cancel=&\u041e\u0442\u043a\u0430\u0437
-v3.mb.openFile.title=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b
-v3.mb.openFile.text.known=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e \u043d\u0435 \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u0437\u0430\u0441\u0435\u0433\u0430 \u043e\u0442 Vuze \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u044f. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u0438\u044f<a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u041d\u04 [...]
-v3.mb.openFile.text.unknown=\u0421\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e \u043d\u0435 \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u0437\u0430\u0441\u0435\u0433\u0430 \u043e\u0442 Vuze \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u044f. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 \u0434\u0440\u0438\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u0438\u044f <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u041d\ [...]
-v3.mb.openFile.button.play=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435
-v3.mb.openFile.button.cancel=\u041e\u0442\u043a\u0430\u0437
-v3.mb.openFile.button.guide=\u041f\u0440\u043e\u0447\u0438\u0442 \u043d\u0430 \u043d\u0430\u0440\u044a\u0447\u043d\u0438\u043a\u0430 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435
-v3.mb.openFile.remember=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0431\u0435\u0437 \u0437\u0430\u043f\u0438\u0442\u0432\u0430\u043d\u0435
 v3.mb.PlayFileNotFound.title=\u041d\u0435\u043d\u0430\u043c\u0435\u0440\u0435\u043d \u0444\u0430\u0439\u043b
 v3.mb.PlayFileNotFound.text=\u0424\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0437\u0430 '%1' \u0441\u0430 \u0438\u0437\u0442\u0440\u0438\u0442\u0438 \u0438\u043b\u0438 \u043b\u0438\u043f\u0441\u0432\u0430\u0442.
 v3.mb.PlayFileNotFound.button.remove=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043e\u0442 Vuze
 v3.mb.PlayFileNotFound.button.redownload=\u041d\u0430\u043d\u043e\u0432\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438
 v3.mb.PlayFileNotFound.button.find=\u0420\u044a\u0447\u043d\u043e \u043d\u0430\u043c\u0438\u0440\u0430\u043d\u0435\u2026
-v3.mb.deletePurchased.title=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0440\u044a\u0447\u0430\u043d\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
-v3.mb.deletePurchased.text=\u0414\u0430 \u0441\u0435 \u0438\u0437\u0442\u0440\u0438\u0435 \u043b\u0438 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e '%1' \u043d\u0430\u0438\u0441\u0442\u0438\u043d\u0430?\n\n\u0422\u043e\u0432\u0430 \u0435 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435, \u043a\u043e\u0435\u0442\u043e \u0435 \u043f\u043e\u0440\u044a\u0447\u0430\u043d\u043e \u0438\u043b\u0438 \u0435 \u0438\u0437\u0438\u0441\u043a\u0430\u043d\u043e \u [...]
-v3.mb.deletePurchased.button.delete=&\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435
-v3.mb.deletePurchased.button.cancel=&\u041e\u0442\u043a\u0430\u0437
 v3.topbar.menu.show.logo=Vuze \u043b\u043e\u0433\u043e
 v3.topbar.menu.show.plugin=\u0417\u043e\u043d\u0430 \u0437\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438
 v3.topbar.menu.show.search=\u0422\u044a\u0440\u0441\u0435\u043d\u0435
@@ -2210,7 +2169,6 @@ v3.topbar.menu.show.frog=Vuze \u043b\u043e\u0433\u043e
 splash.initializeCore=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u044f\u0434\u0440\u043e\u0442\u043e
 splash.initializeUIElements=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u0413\u041f\u0418 \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0438
 ConfigView.section.transfer.autospeedbeta=\u0410\u0432\u0442\u043e-\u0421\u043a\u043e\u0440\u043e\u0441\u0442-\u0411\u0435\u0442\u0430
-#
 ConfigView.section.ipfilter.peerblocking.group=\u0411\u043b\u043e\u043a\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 ConfigView.section.ipfilter.autoload.group=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435
 ConfigView.section.ipfilter.autoload.file=IP \u0444\u0438\u043b\u0442\u044a\u0440 \u043e\u0442 \u0444\u0430\u0439\u043b \u0437\u0430 \u0430\u0432\u0442\u043e-\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435
@@ -2281,14 +2239,12 @@ PiecesView.DistributionView.weDownload=\u041f\u0430\u0440\u0447\u0435\u0442\u043
 PeersView.gain=\u0414\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0435
 PeersView.gain.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u0442\u043e \u0441\u0432\u0430\u043b\u0435\u043d\u0438 - \u043a\u0430\u0447\u0435\u043d\u0438 \u0434\u0430\u043d\u043d\u0438
 unix.script.new.title=\u0418\u043c\u0430 \u043d\u043e\u0432 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 Vuze
-unix.script.new.text=\u0418\u043c\u0430 \u043d\u043e\u0432 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 Vuze \u0438 \u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u043a\u0430\u0442\u043e '%1'.\n\n\u0421\u0438\u043b\u043d\u043e \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0435 \u0438\u0437\u043b\u0438\u0437\u0430\u043d\u0435\u0442\u043e \u043e\u0442 Vuze \u0432\u0435\u0434\u043d\u0430 [...]
+unix.script.new.text=\u0418\u043c\u0430 \u043d\u043e\u0432 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 Vuze \u0438 \u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u043a\u0430\u0442\u043e '%1'.\n\n\u0421\u0438\u043b\u043d\u043e \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0435 \u0438\u0437\u043b\u0438\u0437\u0430\u043d\u0435\u0442\u043e \u043e\u0442 Vuze \u0432\u0435\u0434\u043d\u0430 [...]
 unix.script.new.button.quit=\u0418\u0437\u043b\u0438\u0437\u0430\u043d\u0435 \u0441\u0435\u0433\u0430
 unix.script.new.button.continue=\u041f\u043e-\u043a\u044a\u0441\u043d\u043e
 unix.script.new.button.asknomore=\u0411\u0435\u0437 \u043f\u043e\u0432\u0442\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u0442\u043e
 unix.script.new.auto.title=\u041d\u043e\u0432 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 Vuze
 unix.script.new.auto.text=\u0418\u043c\u0430 \u043d\u043e\u0432 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 Vuze.\n\n\u0421\u0438\u043b\u043d\u043e \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 Vuze \u0432\u0435\u0434\u043d\u0430\u0433\u0430.
-Content.alert.notuploaded.button.stop=&\u0421\u0442\u043e\u043f
-Content.alert.notuploaded.button.continue=&\u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0435\u0435\u043d\u0435
 Content.alert.notuploaded.button.abort=&\u0414\u0430 \u043d\u0435 \u0441\u0435 \u043e\u0442\u043a\u0430\u0437\u0432\u0430
 ConfigView.label.checkOnSeeding=\u0421 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0430\u0440\u0447\u0435\u0442\u0430 \u043f\u0440\u0438 \u043c\u0430\u043b\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0438 \u043f\u0440\u0438 \u0441\u0435\u0435\u043d\u0435
 ConfigView.label.ui_switcher=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0431\u043e\u0440 \u043d\u0430 \u0413\u041f\u0418 \u0437\u0430 Vuze
@@ -2307,7 +2263,7 @@ ConfigTransferAutoSpeed.algorithm=\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u04
 ConfigTransferAutoSpeed.auto.speed.classic=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442 (\u043a\u043b\u0430\u0441\u0438\u043a)
 ConfigTransferAutoSpeed.auto.speed.beta=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442 (\u0431\u0435\u0442\u0430)
 ConfigTransferAutoSpeed.data.update.frequency=\u0427\u0435\u0441\u0442\u043e\u0442\u0430 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
-Alert.failed.update=\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u043d\u0430\u0439-\u043c\u0430\u043b\u043a\u043e 1 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0435 \u0443\u0441\u043f\u044f. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438 <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A>
+Alert.failed.update=\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u043d\u0430\u0439-\u043c\u0430\u043b\u043a\u043e 1 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0435 \u0443\u0441\u043f\u044f. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438 <A HREF="{Alert.failed.update.url}">VuzeWiki: Failed Update</A>
 OpenTorrentWindow.mb.existingFiles.partialList=(\u041d\u0435\u043f\u044a\u043b\u0435\u043d \u0441\u043f\u0438\u0441\u044a\u043a. \u041e\u0449\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0442)
 TableColumn.header.bad_avail_time.info=\u041a\u043e\u0433\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0435 \u0431\u0438\u043b\u043e \u043d\u0430\u043b\u0438\u0447\u043d\u043e \u043f\u044a\u043b\u043d\u043e \u043a\u043e\u043f\u0438\u0435 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
 TableColumn.header.bad_avail_time=\u0412\u0438\u0434\u044f\u043d\u043e \u043f\u044a\u043b\u043d\u043e \u043a\u043e\u043f\u0438\u0435
@@ -2360,28 +2316,22 @@ Progress.reporting.window.remove.now.tooltip=\u041f\u0440\u0435\u043c\u0430\u044
 dhttracker.tracklimitedwhenonline=\u0421 \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u044f\u0432\u0430\u043d\u0435 \u0437\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0438\u0433 \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0438 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0430  \u043d\u0430 \u043b\u0438\u043d\u0438\u044f \u0437\u0430 \u043a\u0440\u044a\u0441\u0442\u043e\u0441\u0430\u043d\u043e \u043d\u0430\u0441\u0438\u0449\u0430\u043d\u0435 \u043d\u0430 \u0440\u043e\u044f\u043a\u0430
 TorrentOptionsView.multi.title.short=\u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 TorrentOptionsView.multi.title.full=\u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
-MyTorrentsView.menu.open_parent_folder=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430\u0442\u0430 \u043f\u0430\u043f\u043a\u0430
+MyTorrentsView.menu.open_parent_folder=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
 ConfigView.section.style.use_show_parent_folder=\u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 "%1" \u0432\u043c\u0435\u0441\u0442\u043e "%2" \u0432 \u0442\u043e\u0440\u0435\u043d\u0442 \u043c\u0435\u043d\u044e\u0442\u0430\u0442\u0430
-ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0442\u0430\u0437\u0438 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u043e [...]
+ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0442\u0430\u0437\u0438 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0432 \u043f\u0440\u0430 [...]
 PeerManager.status.ps_disabled=\u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d \u0442\u0440\u0430\u043a\u0435\u0440 \u043d\u0430 \u0438\u0437\u0442\u043e\u0447\u043d\u0438\u0446\u0438 \u043e\u0442 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
 ConfigView.section.stats.exportfiles=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0444\u0430\u0439\u043b
-updater.cant.write.to.app.title=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 \u0432 \u043f\u0430\u043f\u043a\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e
-updater.cant.write.to.app.details=\u0412 \u043f\u0430\u043f\u043a\u0430 "%1" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430.\n\n\u0422\u043e\u0432\u0430 \u0449\u0435 \u043f\u043e\u043f\u0440\u0435\u0447\u0438 \u0431\u044a\u0434\u0435\u0449\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0438.\n\n\u0414\u04 [...]
+updater.cant.write.to.app.title=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e
+updater.cant.write.to.app.details=\u0412 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f "%1" \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430.\n\n\u0422\u043e\u0432\u0430 \u0449\u0435 \u043f\u043e\u043f\u0440\u0435\u0447\u0438 \u0431\u044a\u0434\u0435\u0449\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430 \u0431\u044a\u0434\u0430\u0442 \u043f\u0440\u0438\u043b\u0430\u0433\u0 [...]
 plugin.install.class_version_error=\u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430 \u043f\u043e-\u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Java.
 v3.MainWindow.tab.minilibrary=\u0421\u0432\u0430\u043b\u044f\u043d\u0438\u044f
 v3.MainWindow.tab.events=\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442
 button.columnsetup.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043b\u043e\u043d\u0438
 v3.activity.remove.title=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
 v3.activity.remove.text=\u0414\u0430 \u0441\u0435 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0435 \u043b\u0438 \u043d\u0430\u0438\u0441\u0442\u0438\u043d\u0430 \u0441\u044a\u0431\u0438\u0442\u0438\u0435 '%1'?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
 v3.MainWindow.menu.file.closewindow=\u0417\u0430\u0442\u0432\u0430\u0440\u044f\u043d\u0435
 Menu.show.torrent.menu=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0435\u043d\u044e '\u0422\u043e\u0440\u0435\u043d\u0442\u0438'
 Menu.show.torrent.menu.tooltip=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0435\u043d\u044e '\u0422\u043e\u0440\u0435\u043d\u0442\u0438' \u0432 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0442\u043e \u043c\u0435\u043d\u044e
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
 Views.plugins.aznetstatus.title=\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043c\u0440\u0435\u0436\u0430
 plugin.aznetstatus.pingtarget=Ping/trace route \u043d\u0430 \u0446\u0435\u043b
 ConfigView.section.style.usePathFinder=\u0421 '\u0422\u044a\u0440\u0441\u0430\u0447 \u043d\u0430 \u043f\u044a\u0442' \u0432\u043c\u0435\u0441\u0442\u043e '\u0422\u044a\u0440\u0441\u0430\u0447'
@@ -2394,10 +2344,6 @@ v3.splash.hookPluginUI=\u0417\u0430\u043a\u0430\u0447\u0430\u043d\u0435 \u0437\u
 OpenTorrentWindow.mb.notTorrent.cannot.display=\u0414\u0430\u043d\u043d\u0438\u0442\u0435 \u043d\u0435 \u043c\u043e\u0436\u0430\u0445\u0430 \u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044f\u0442 \u043a\u0430\u043a\u0442\u043e \u0442\u0440\u044f\u0431\u0432\u0430
 MainWindow.menu.window.zoom.maximize=\u041c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440\u0430\u043d\u0435
 MainWindow.menu.window.zoom.restore=\u0412\u044a\u0437\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435
-ImageResizer.image.too.small=\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u0435 \u0442\u0432\u044a\u0440\u0434\u0435 \u043c\u0430\u043b\u043a\u043e, \u0434\u0430 \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 \u0434\u0440\u0443\u0433\u043e (\u0434\u0430 \u0431\u044a\u0434\u0435 \u043f\u043e\u043d\u0435 %1 x %2)
-ImageResizer.title=\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u0449 \u043f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u0443\u043c\u0430\u043b\u0435\u043d\u0438\u044f \u0438\u0437\u0433\u043b\u0435\u0434 \u0432\u044a\u0432 \u0432\u0438\u0434\u0430, \u0432 \u043a\u043e\u0439\u0442\u043e \u0441\u0435 \u043f\u043e\u043a\u0430\u0437\u0432\u0430 \u0432\u044a\u0432 Vuze
-ImageResizer.move.image=\u041f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u0441\u0442\u0430\u0432\u0430 \u0441 \u0432\u043b\u0430\u0447\u0435\u043d\u0435
-ImageResizer.move.image.with.slider=\u041f\u0440\u0435\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u0441\u0442\u0430\u0432\u0430 \u0441 \u0432\u043b\u0430\u0447\u0435\u043d\u0435, \u0430 \u043c\u0430\u0449\u0430\u0431\u0438\u0440\u0430\u043d\u0435 \u0441 \u043f\u043b\u044a\u0437\u0433\u0430\u0447\u0430 \u043e\u0442\u0434\u043e\u043b\u0443
 security.crypto.title=\u0414\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043a\u043b\u044e\u0447 \u0437\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0435
 security.crypto.encrypt=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u043f\u0430\u0440\u043e\u043b\u0430 \u0437\u0430 \u0437\u0430\u0449\u0438\u0442\u0430 \u043d\u0430 \u043d\u043e\u0432\u043e\u0441\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u0438\u044f \u043a\u043b\u044e\u0447 \u0437\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0435. \u0414\u0430 \u043d\u0435 \u0441\u0435 \u0437\u0430\u0431\u0440\u0430\u0432\u044f \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u [...]
 security.crypto.decrypt=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u043f\u0430\u0440\u043e\u043b\u0430 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043a\u043b\u044e\u0447\u0430 \u0437\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0435.
@@ -2425,7 +2371,7 @@ ConfigView.section.security.resetkey.error.title=\u041f\u0440\u043e\u0432\u0430\
 ConfigView.section.security.resetkey.error=\u041f\u0440\u043e\u0432\u0430\u043b\u0438 \u0441\u0435 \u043f\u0440\u0435\u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043a\u043b\u044e\u0447\u043e\u0432\u0435\u0442\u0435
 ConfigView.section.security.unlockkey.error=\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430 - \u043f\u0440\u043e\u0432\u0430\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043a\u043b\u044e\u0447
 ConfigView.copy.to.clipboard.tooltip=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u043a\u043b\u0438\u043f-\u0431\u043e\u0440\u0434\u0430
-Views.plugins.azbuddy.title=\u041f\u0440\u0438\u044f\u0442\u0435\u043b\u0438
+Views.plugins.azbuddy.title=\u0414\u0440\u0443\u0436\u043a\u0438
 Browser.popup.error.no.access=\u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u043e\u043f\u0438\u0442 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u0440\u0435\u0441\u0443\u0440\u0441.\n\u0414\u0430 \u0441\u0435 \u043e\u043f\u0438\u0442\u0430 \u043f\u043e-\u043a\u044a\u0441\u043d\u043e.\n
 ConfigView.label.queue.stoponcebandwidthmet=\u0414\u0430 \u043d\u0435 \u0441\u0435 \u0437\u0430\u043f\u043e\u0447\u0432\u0430\u0442 \u043f\u043e\u0432\u0435\u0447\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0430\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435/\u0441\u0432\u0430\u0 [...]
 ConfigView.section.style.forceMozilla=Vuze \u0434\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 Mozilla \u0437\u0430 \u0431\u0440\u0430\u0443\u0437\u044a\u0440\u0441\u043a\u0438 \u043f\u0440\u0438\u0441\u043f\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u0438\u044f [\u0438\u0437\u0438\u0441\u043a\u0432\u0430 XULRunner \u0438\u043b\u0438 Firefox 3; \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442]
@@ -2443,6 +2389,7 @@ azbuddy.ui.add=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435
 azbuddy.ui.new_buddy=\u041d\u043e\u0432 \u043a\u043b\u044e\u0447 \u043d\u0430 \u0434\u0440\u0443\u0436\u043a\u0430:
 azbuddy.ui.table.name=\u0418\u043c\u0435
 azbuddy.ui.table.online=\u041d\u0430 \u043b\u0438\u043d\u0438\u044f
+azbuddy.ui.table.last_ygm=\u041d\u043e\u0432\u0430 \u043f\u043e\u0449\u0430
 azbuddy.ui.table.last_msg=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u0435
 azbuddy.ui.menu.remove=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435
 azbuddy.ui.menu.copypk=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043e\u0431\u0449 \u043a\u043b\u044e\u0447
@@ -2493,9 +2440,6 @@ metasearch.addtemplate.dup.title=\u0414\u0443\u0431\u043b\u0438\u0440\u0430\u043
 metasearch.addtemplate.dup.desc=\u0428\u0430\u0431\u043b\u043e\u043d \u0437\u0430 \u0442\u044a\u0440\u0441\u0435\u043d\u0435 %1 \u0432\u0435\u0447\u0435 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d
 metasearch.export.select.template.file=\u0417\u0430\u043f\u0438\u0441 \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d
 metasearch.import.select.template.file=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d
-dialog.uiswitch.title=\u041f\u0440\u0435\u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043a\u044a\u043c Vuze \u0413\u041f\u0418
-dialog.uiswitch.text=\u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0430\u043a\u0442\u0438\u0432\u0435\u043d Vuze \u0413\u041f\u0418 \u0437\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0442\u0430\u0437\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f.\n\nVuze \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430.
-dialog.uiswitch.button=\u041f\u0440\u0435\u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043a\u044a\u043c Vuze \u0413\u041f\u0418
 azbuddy.tracker.enabled=\u0421 '\u041b\u0430\u043d\u0441\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0434\u0440\u0443\u0436\u043a\u0430' \u0441\u0435 \u0434\u0430\u0432\u0430 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u0441 \u0434\u0440\u0443\u0436\u043a\u0438 
 azbuddy.protocolspeed=KB/s \u043c\u0430\u043a\u0441. \u0431\u0430\u043b\u0430\u0441\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0437\u0430 \u0434\u0440\u0443\u0436\u043a\u0430
 v3.MainWindow.button.download=\u0421\u0432\u0430\u043b\u044f\u043d\u0435
@@ -2509,7 +2453,7 @@ azbuddy.tracker.bbb.status.title.tooltip=\u0418\u0437\u0431\u043e\u0440 \u0437\u
 azbuddy.tracker.bbb.status.idle=\u0411\u0435\u0437 \u043b\u0430\u043d\u0441\u0438\u0440\u0430\u043d\u0435
 azbuddy.tracker.bbb.status.nli=\u0418\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u0432\u043f\u0438\u0441\u0432\u0430\u043d\u0435
 azbuddy.tracker.bbb.status.in=\u041c\u0435\u0441\u0442\u043d\u043e \u043b\u0430\u043d\u0441\u0438\u0440\u0430\u043d\u0435
-azbuddy.tracker.bbb.status.out=\u041b\u0430\u043d\u0441\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0434\u0440\u0443\u0436\u043a\u0438
+azbuddy.tracker.bbb.status.out=\u0422\u0435\u043a\u0443\u0449\u043e \u043b\u0430\u043d\u0441\u0438\u0440\u0430\u043d\u0438 \u0434\u0440\u0443\u0436\u043a\u0438
 v3.MainWindow.search.go.tooltip=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0442\u044a\u0440\u0441\u0435\u043d\u0435\u0442\u043e
 v3.MainWindow.search.last.tooltip=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435
 metasearch.addtemplate.done.title=\u0414\u043e\u0431\u0430\u0432\u0435\u043d \u0448\u0430\u0431\u043b\u043e\u043d
@@ -2561,7 +2505,7 @@ iconBar.share=\u0421\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435
 iconBar.share.tooltip=\u0421\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
 iconBar.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
 iconBar.comment=\u041a\u043e\u043c\u0435\u043d\u0442\u0430\u0440
-iconBar.play=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435
+iconBar.play=\u0418\u0437\u043f\u044a\u043b\u043d.
 iconBar.queue.tooltip=\u041d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430
 v3.MainWindow.menu.view.sidebar=\u0421\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0430 \u043b\u0435\u043d\u0442\u0430
 v3.MainWindow.menu.view.actionbar=\u041b\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0442\u0430
@@ -2614,7 +2558,7 @@ Button.send=\u0418\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435
 Button.back=\u041d\u0430\u0437\u0430\u0434
 sidebar.LibraryUnopened=\u041d\u0435 \u0441\u043b\u0435\u0434\u0435\u043d\u0438
 TableColumn.header.unopened=\u041d\u043e\u0432\u043e
-Unopened.bigView.header=\u041d\u043e\u0432\u043e
+Unopened.bigView.header=\u041d\u043e\u0432
 Subscription.menu.deleteall=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438
 Subscription.menu.reset=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u0432 \u043d\u0430\u0447\u0430\u043b\u043d\u043e \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435
 ConfigView.section.Subscriptions=\u0410\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
@@ -2629,7 +2573,6 @@ Subscription.menu.resetauth=\u041d\u0430\u043d\u043e\u0432\u043e \u043f\u043e\u0
 Search.menu.engines=\u0428\u0430\u0431\u043b\u043e\u043d\u0438
 Wizard.Subscription.title=\u0410\u0431\u043e\u043d\u0438\u0440\u0430\u043d\u0435
 Wizard.Subscription.optin.title=\u0414\u0430 \u0438\u043c\u0430 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
-#what you've watched? Discover more with a single click...
 Wizard.Subscription.subscribe.title=\u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
 Wizard.Subscription.create.title=\u041d\u043e\u0432 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442
 Button.search=\u0422\u044a\u0440\u0441\u0435\u043d\u0435
@@ -2708,13 +2651,14 @@ v3.MainWindow.menu.view.asSimpleList=\u041e\u043f\u0440\u043e\u0441\u0442\u0435\
 v3.MainWindow.menu.view.asAdvancedList=\u0420\u0430\u0437\u0448\u0438\u0440\u0435\u043d \u0441\u043f\u0438\u0441\u044a\u043a
 v3.MainWindow.menu.view.statusbar=\u041b\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u0442\u043e
 Subscription.menu.dirtyall=\u041e\u0442\u043c\u044f\u0442\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438 \u043a\u0430\u0442\u043e \u043d\u0435\u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u0438
-configureWizard.file.message3=Vuze \u0449\u0435 \u0441\u0432\u0430\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043f\u0430\u043f\u043a\u0430, \u043a\u043e\u044f\u0442\u043e \u0441\u0435 \u0438\u0437\u0431\u0438\u0440\u0430 \u0442\u0443\u043a:
+configureWizard.file.message3=Vuze \u0449\u0435 \u0441\u0432\u0430\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u043a\u043e\u044f\u0442\u043e \u0441\u0435 \u0438\u0437\u0431\u0438\u0440\u0430 \u0442\u0443\u043a:
 v3.deleteContent.applyToAll=\u041f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u0442\u043e \u0437\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 %1 \u0438\u0437\u0431\u0440\u0430\u043d\u0438 \u043d\u0435\u0449\u0430
 ConfigView.label.seeding.firstPriority.ignoreIdleHours=\u0422\u043e\u0440\u0435\u043d\u0442\u0438, \u043a\u043e\u0438\u0442\u043e \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u0442 \u043d\u0438\u0449\u043e \u0437\u0430
 v3.MainWindow.menu.contentnetworks=HD &\u041c\u0440\u0435\u0436\u0438
 v3.MainWindow.menu.contentnetworks.about=\u0417\u0430 HD \u043c\u0440\u0435\u0436\u0438\u0442\u0435
+Peers.column.as=\u0410\u0421
 Peers.column.as.info=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0410\u0421 (\u0410\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u0430 \u0421\u0438\u0441\u0442\u0435\u043c\u0430) \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d
-ConfigTransferAutoSpeed.auto.speed.neural=\u041d\u0435\u0432\u0440\u0430\u043b\u0433\u0438\u0447\u0435\u043d \u043c\u0435\u0442\u043e\u0434 (Gudy \u0430\u043b\u0444\u0430)
+ConfigTransferAutoSpeed.auto.speed.neural=\u041d\u0435\u0432\u0440\u0430\u043b\u0435\u043d \u043c\u0435\u0442\u043e\u0434 (Gudy \u0430\u043b\u0444\u0430)
 ConfigView.label.autoopen.downloadbars=\u0410\u0432\u0442\u043e-\u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u043b\u0435\u043d\u0442\u0438 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u043f\u0440\u0438
 ConfigView.label.autoopen=\u0410\u0432\u0442\u043e-\u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435
 ConfigView.label.autoopen.detailstab=\u0410\u0432\u0442\u043e-\u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 '\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438' \u043f\u0440\u0438
@@ -2731,13 +2675,6 @@ azbuddy.ui.menu.cat.set_msg=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u04
 azbuddy.ui.menu.cat_subs=\u0410\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442
 subs.prop.update_period=\u041f\u0435\u0440\u0438\u043e\u0434 \u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
 azbuddy.enable_cat_pub=\u041e\u0431\u0449\u043e\u0434\u043e\u0441\u0442\u044a\u043f\u043d\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0437\u0430 \u043a\u043e\u0438\u0442\u043e \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0430\u0431\u043e\u043d\u0438\u0440\u0430\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u0434\u0440\u0443\u0436\u043a\u0438 (',' \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438) 
-v3.dialog.cnclose.title=%1 \u0435 \u0437\u0430\u0442\u0432\u043e\u0440\u0435\u043d\u0430
-v3.dialog.cnclose.subtitle=\u0418\u0437\u0432\u0435\u0441\u0442\u0438\u0435
-v3.dialog.cnclose.info1=\u0417\u0430\u0442\u0432\u043e\u0440\u0435\u043d\u0430 \u0435 HD \u043c\u0440\u0435\u0436\u0430
-v3.dialog.cnclose.info2=\u0417\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0442\u0430\u0437\u0438 HD \u043c\u0440\u0435\u0436\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043c\u0435\u043d\u044e\u0442\u043e 'HD \u041c\u0440\u0435\u0436\u0438'.
-v3.dialog.cnclose.noshow=\u0411\u0435\u0437 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043e\u0442\u043d\u043e\u0432\u043e
-v3.dialog.cnmanage.title=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u0435\u043d\u044e 'HD \u041c\u0440\u0435\u0436\u0438'
-v3.dialog.cnmanage.intro=\u041e\u0442 \u0434\u043e\u043b\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u044a\u043a \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 \u043a\u043e\u0438 \u043c\u0440\u0435\u0436\u0438 \u0437\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u0442 \u0432 \u043c\u0435\u043d\u044e 'HD \u041c\u0440\u0435\u0436\u0438'
 azbuddy.ui.table.read_cat=\u041f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u0438 \u043a\u0430\u0442.
 TableColumn.header.#=\u2116
 TableColumn.header.#.info=\u2116 \u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f/\u043f\u043e\u0434\u0440\u0435\u0436\u0434\u0430\u043d\u0435
@@ -2748,7 +2685,7 @@ TableColumn.header.health.info=\u041a\u043e\u043b\u043a\u043e \u0437\u0434\u0440
 TableColumn.header.maxuploads.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438, \u043a\u044a\u043c \u043a\u043e\u0438\u0442\u043e \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u0435 \u043a\u0430\u0447\u0432\u0430
 TableColumn.header.name.info=\u0418\u043c\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
 TableColumn.header.unopened.info=\u0424\u043b\u0430\u0433 \u0437\u0430 \u0438\u043d\u0434\u0438\u043a\u0430\u0446\u0438\u044f \u0434\u0430\u043b\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u044a\u0442 \u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u043d (\u043e\u0442\u0432\u0430\u0440\u044f\u043d)
-TableColumn.header.savepath.info=\u0426\u0435\u043b\u0435\u0432\u0430\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0438\u043b\u0438 \u0444\u0430\u0439\u043b \u0437\u0430 \u0434\u0430\u043d\u043d\u0438\u0442\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.savepath.info=\u0426\u0435\u043b\u0435\u0432\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0438\u043b\u0438 \u0444\u0430\u0439\u043b \u0437\u0430 \u0434\u0430\u043d\u043d\u0438\u0442\u0435 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
 TableColumn.header.SeedingRank.info=\u0420\u0430\u043d\u0433, \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u0449 \u043a\u043e\u043b\u043a\u043e \u043c\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u044a\u0442 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435\u0435\u043d\u0435. \u041f\u043e-\u0432\u0438\u0441\u043e\u043a\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0437\u043d\u0430\u0447\u0438 \u043f\u043e-\u0433\u043e\u043b\u044f\u043c\u0430 \u043d\u0443\u0 [...]
 TableColumn.header.shareRatio.info=\u041a\u043e\u043b\u043a\u043e \u0435 \u043a\u0430\u0447\u0435\u043d\u043e (\u0441\u043f\u043e\u0434\u0435\u043b\u0435\u043d\u043e) \u0441\u043f\u0440\u044f\u043c\u043e \u0441\u0432\u0430\u043b\u0435\u043d\u043e\u0442\u043e.
 TableColumn.header.size.info=\u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u0432\u044a\u0440\u0445\u0443 \u0434\u0438\u0441\u043a\u0430
@@ -2805,15 +2742,498 @@ device.upnp.present_url=\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u
 ConfigView.label.maxStalledSeeding=\u041c\u0430\u043a\u0441. '\u0437\u0430\u043f\u044a\u043d\u0430\u0442\u0438' [0:\u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 device.search.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
 devices.sidebar.simple=\u041e\u043f\u0440\u043e\u0441\u0442\u0435\u043d \u0438\u0437\u0433\u043b\u0435\u0434
-devices.xcode.working_dir=\u0417\u043e\u043d\u0430 \u0437\u0430 \u043a\u0440\u044a\u0441\u0442\u043e\u0441\u0430\u043d\u0438 \u043a\u043e\u0434\u043e\u0432\u0435
-devices.xcode.prof_def=\u041a\u0440\u044a\u0441\u0442\u043e\u0441\u0430\u043d \u043a\u043e\u0434 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
-devices.xcode.profs=\u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u0437\u0430 \u043a\u0440\u044a\u0441\u0442\u043e\u0441\u0430\u043d\u0438 \u043a\u043e\u0434\u043e\u0432\u0435
+devices.xcode.working_dir=\u0417\u043e\u043d\u0430 \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435
+devices.xcode.prof_def=\u041f\u0440\u043e\u0444\u0438\u043b \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
+devices.xcode.profs=\u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u0437\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435
 device.lastseen=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0432\u0438\u0434\u044f\u043d\u043e
-devices.contextmenu.xcode=\u041a\u0440\u044a\u0441\u0442\u043e\u0441\u0430\u043d \u043a\u043e\u0434 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.contextmenu.xcode=\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
 devices.device=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
 devices.profile=\u041f\u0440\u043e\u0444\u0438\u043b
 General.percent=%
 devices.installed=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u043e
 devices.comp.missing=\u041d\u0435 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0430 Vuze \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430
 devices.state=\u041a\u0430\u043a \u0435
-i18n.bg_BG.Contact=Andrey Marinov andreshko at hotmail.bg
+MainWindow.menu.help.donate=&\u0414\u0430\u0440\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430
+DonationWindow.noload.title=\u0414\u0430\u0440\u0435\u043d\u0438\u044f
+DonationWindow.noload.text=\u041f\u0440\u043e\u0437\u043e\u0440\u0435\u0446\u044a\u0442 \u0437\u0430 \u0434\u0430\u0440\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u043e\u0436\u0430 \u0434\u0430 \u0441\u0435 \u0437\u0430\u0440\u0435\u0434\u0438. \u0414\u0430 \u0441\u0435 \u043e\u043f\u0438\u0442\u0430 \u043f\u043e-\u043a\u044a\u0441\u043d\u043e.
+devices.xcode.only.show=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u0441\u0430\u043c\u043e \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.quit.transcoding.title=\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435
+device.quit.transcoding.text='%1' \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430 \u0437\u0430 '%2' \u0438 \u0435 %3% \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d.\n\u041f\u0440\u0438 \u0438\u0437\u0445\u043e\u0434 \u0432 \u0442\u043e\u0437\u0438 \u043c\u043e\u043c\u0435\u043d\u0442 \u0449\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u043e\u0447\u043d\u0435 \u043e\u0442\u043d\u0430\u04 [...]
+download.removerules.unauthorised.data=\t\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438
+device.config.xcode.maxbps=\u041c\u0430\u043a\u0441. KB/sec \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+device.xcode=\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435
+device.xcode.always=\u0412\u0438\u043d\u0430\u0433\u0438
+device.xcode.whenreq=\u041a\u043e\u0433\u0430\u0442\u043e \u0441\u0435 \u0438\u0437\u0438\u0441\u043a\u0432\u0430
+device.xcode.never=\u041d\u0438\u043a\u043e\u0433\u0430
+devices.copy.pending=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u0437\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b
+devices.sidebar.hide.rend.generic=\u0421\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0431\u0430\u0437\u043e\u0432\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+v3.devicesview.infobar.text2=\u0417\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043a\u044a\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0432\u043b\u0430\u0447\u0438 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043e\u0442 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u0431\u0438 [...]
+iconBar.transcode=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+iconBar.transcode.tooltip=\u041c\u0435\u0434\u0438\u044f\u0442\u0430 \u0434\u0430 \u0435 \u0434\u043e\u0441\u0442\u044a\u043f\u043d\u0430 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.retry.copy=\u041d\u043e\u0432 \u043e\u043f\u0438\u0442 \u0437\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435
+devices.copy.fail=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.on.demand=\u041f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0432\u0430\u043d\u0435
+devices.ready=\u0413\u043e\u0442\u043e\u0432\u043e
+TableColumn.header.trancode_qpos=\u2116
+TableColumn.header.trancode_qpos.info=\u041c\u044f\u0441\u0442\u043e \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0437\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435
+TableColumn.header.profile=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+TableColumn.header.profile.info=\u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d \u043f\u0440\u043e\u0444\u0438\u043b \u0437\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435
+TableColumn.header.copied=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u043e
+TableColumn.header.device=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+TableColumn.header.device.info=\u0426\u0435\u043b\u0435\u0432\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+TableColumn.header.trancode_completion=\u0420\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u043d\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u043d\u0435\u0442\u043e
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=\u0418\u0437\u0433
+v3.iconBar.view.big.tooltip=\u041f\u0440\u043e\u0441\u0442 \u0441\u043f\u0438\u0441\u044a\u043a
+# This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=\u043b\u0435\u0434
+v3.iconBar.view.small.tooltip=\u0420\u0430\u0437\u0448\u0438\u0440\u0435\u043d \u0441\u043f\u0438\u0441\u044a\u043a
+general.dont.ask.again=\u0411\u0435\u0437 \u043d\u043e\u0432\u043e \u043f\u0438\u0442\u0430\u043d\u0435
+general.na.short=\u041d\u044f\u043c\u0430
+v3.menu.device.exploreTranscodes=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+v3.menu.device.exploreTranscodes._windows=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 Explorer
+v3.menu.device.exploreTranscodes._mac=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432\u044a\u0432 Finder
+v3.menu.device.defaultprofile=\u041f\u0440\u043e\u0444\u0438\u043b \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435
+devices.button.installitunes=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u043d\u0430 iTunes
+device.itunes.install=\u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d iTunes
+device.itunes.start=\u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 iTunes \u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0438 \u0430\u0432\u0442\u043e-\u0441\u0442\u0430\u0440\u0442
+device.itunes.install_problem=\u0418\u043c\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 iTunes
+devices.downloading=\u0421\u0432\u0430\u043b\u044f\u043d\u0435
+TableColumn.header.duration=\u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442
+TableColumn.header.resolution=\u0420\u0430\u0441\u0442\u0435\u0440
+devices.xcode.autoStart=\u0410\u0432\u0442\u043e-\u0441\u0442\u0430\u0440\u0442, \u043a\u043e\u0433\u0430\u0442\u043e \u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e
+option.askeverytime=\u041f\u0438\u0442\u0430\u043d\u0435 \u0432\u0441\u0435\u043a\u0438 \u043f\u044a\u0442
+option.rememberthis=\u0417\u0430\u043f\u043e\u043c\u043d\u044f\u043d\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0442\u0430
+devices.associate=\u0410\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f \u0441
+devices.associate.already=\u0418\u043c\u0430 \u0430\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f
+devices.always.cache=\u0411\u0443\u0444\u0435\u0440\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043d\u0435-\u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+devices.turnon.prepageload=\u0417\u0430 \u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u0430\u0437\u0438 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0441\u0435 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438.
+devices.turnon.itunes=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u0437\u0430 iTunes (\u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u0437\u0430 Apple \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430)
+devices.turnon.qos=\u0421\u043f\u043e\u0434\u0435\u043b\u044f\u043d\u0435 \u0441 Vuze \u043d\u0430 \u0430\u043d\u0438\u043d\u0438\u043c\u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.turnon.title=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+devices.choose.device.title=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430 \u0442\u043e\u0432\u0430 \u0432\u0438\u0434\u0435\u043e:
+devices.choose.profile.info.text=\u0421\u043b\u0435\u0434 \u0438\u0437\u0431\u043e\u0440\u0430 Vuze \u0449\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438 \u0434\u0430\u043b\u0438 \u0432\u0438\u0434\u0435\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u044a\u0442 \u0449\u0435 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438 \u043d\u0430 \u0438\u0437\u0431\u0440\u0430\u043d\u043e\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0438\u043b\u0438 \u043d\u [...]
+devices.choose.profile.info.title.selected=%1 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438:
+devices.view.heading=\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0435\u0434\u0438\u044f \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.view.heading=\u041c\u0435\u0434\u0438\u044f \u0437\u0430 %1
+devices.choose.device.info.title=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430 \u0437\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.choose.device.info.text=\u0421\u043b\u0435\u0434\u0432\u0430\u0449\u0438\u044f\u0442 \u043f\u044a\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0430 \u0441\u0435 \u0432\u043b\u0430\u0447\u0430\u0442 \u0438 \u043f\u0443\u0441\u043a\u0430\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0430\u0442\u0430 \u043b\u [...]
+label.clickone=\u041f\u043e\u0441\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0435\u0434\u043d\u043e
+Button.turnon=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435
+ConfigView.label.dm.dblclick=\u0418\u0437\u0431\u043e\u0440 \u0441 \u043c\u0438\u0448\u043a\u0430 \u0432 \u0438\u0437\u0433\u043b\u0435\u0434 \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u0438:
+ConfigView.option.dm.dblclick.play=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
+ConfigView.option.dm.dblclick.details=\u041e\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434 \u0441 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0442\u043e\u0440\u0435\u043d\u0442
+ConfigView.option.dm.dblclick.show=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b
+ConfigView.option.dm.dblclick.show._mac=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b(\u043e\u0432\u0435) \u0432\u044a\u0432 Finder
+ConfigView.option.dm.dblclick.show._windows=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b(\u043e\u0432\u0435) \u0432 Explorer
+subscriptions.column.auto-download=\u0410\u0432\u0442\u043e-\u0441\u0432\u0430\u043b\u044f\u043d\u0435
+xcode.deletedata.title=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
+xcode.deletedata.message=\u041d\u0430\u0438\u0441\u0442\u0438\u043d\u0430 \u043b\u0438 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0442\u0440\u0438\u0435 \u043a\u043e\u043f\u0438\u0435\u0442\u043e \u043d\u0430 '%1' \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u043e \u0437\u0430 '%2'%3?
+xcode.deletedata.message.2=\n(\u043a\u043e\u043f\u0438\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u043c\u0430 \u0432\u0441\u0435 \u043e\u0449\u0435 \u0432 '%1')
+v3.deviceview.infobar.line1=\u0412\u043b\u0430\u0447\u0435\u043d\u0435/\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043e\u0442 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e \u0438\u0437\u0431\u043e\u0440.
+v3.deviceview.infobar.line2=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043d\u0430 \u043a\u043e\u0439 \u0434\u0430 \u0435 \u0435\u043a\u0440\u0430\u043d - iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=\u0412\u043b\u0430\u0447\u0435\u043d\u0435/\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043e\u0442 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0432 %1 \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0430\u0442\u0430 \u043b\u0435\u043d\u0442\u0430.
+v3.deviceview.infobar.line2.itunes=\u0412\u0438\u0434\u0435\u043e-\u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0449\u0435 \u0441\u0435 \u043f\u043e\u044f\u0432\u044f\u0442 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f 'iTunes Movies', \u043a\u043e\u0433\u0430\u0442\u043e \u0441\u0430 \u0433\u043e\u0442\u043e\u0432\u0438 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435.
+v3.deviceview.infobar.line2.xbox=\u0417\u0430 \u043f\u0440\u0430\u0432\u0435\u043d\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0435\u0437 Xbox 360 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 My XBox \u2192 Video Library \u2192 Vuze.
+v3.deviceview.infobar.line2.ps3=\u0417\u0430 \u043f\u0440\u0430\u0432\u0435\u043d\u0435 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0435\u0437 PS3 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 Videos \u2192 Vuze.
+devices.copy_url=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 URL \u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043b\u0438\u043f-\u0431\u043e\u0440\u0434\u0430
+devices.converting=\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u043d\u0435
+Button.reload=\u041f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435
+devices.auto.start=\u0410\u0432\u0442\u043e-\u0441\u0442\u0430\u0440\u0442
+Subscription.menu.setcookies=\u041d\u0430\u0441\u0442\u043e\u0439\u0432\u0430\u043d\u0435 \u043d\u0430 \u0431\u0438\u0441\u043a\u0432\u0438\u0442\u043a\u0438
+general.enter.cookies=\u0411\u0438\u0441\u043a\u0432\u0438\u0442\u043a\u0438 \u0437\u0430 \u0432\u043b\u0438\u0437\u0430\u043d\u0435
+device.config.xcode.workdir=\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+MyTorrentsView.menu.clear_alloc_data=\u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0437\u0430\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e
+DiskManager.error.nospace=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u044a\u0447\u043d\u043e \u043c\u044f\u0441\u0442\u043e \u043d\u0430 \u0434\u0438\u0441\u043a\u0430
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - \u0434\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 {wiki.fat32}
+ConfigView.section.file.rename.incomplete=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0430\u0432\u043a\u0430 \u0437\u0430 \u043d\u0435\u043f\u044a\u043b\u043d\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+subscriptions.config.auto=\u0421\u0430\u043c\u043e-\u0441\u0432\u0430\u043b\u044f\u043d\u0435
+subscriptions.config.autostartdls=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0437\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f\u0442\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u044f\u043d\u0435 (\u0432\u043c\u0435\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u0432 \u0441\u043f\u0440\u044f\u043d\u043e \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435)
+subscriptions.config.autostart.min=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u0441\u0430\u043c\u043e, \u0430\u043a\u043e >= MB [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+subscriptions.config.autostart.max=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435 \u0441\u0430\u043c\u043e, \u0430\u043a\u043e <= MB [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+dlg.corewait.title=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u044f\u0434\u0440\u043e\u0442\u043e
+dlg.corewait.text=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435\u2026\n\n\u0417\u0430\u044f\u0432\u043a\u0430\u0442\u0430 \u0449\u0435 \u0441\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0438 \u0441\u043b\u0435\u0434 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0430 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 Vuze.
+library.core.wait=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435\u2026\n\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Vuze \u043a\u043b\u0438\u0435\u043d\u0442\u0430.
+ConfigView.label.StartUIBeforeCore=\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0413\u041f\u0418 \u043f\u0440\u0435\u0434\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u044f\u0434\u0440\u043e\u0442\u043e
+general.add.friends=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0438
+general.all.friends=\u0412\u0441\u0438\u0447\u043a\u0438 \u043f\u0440\u0438\u044f\u0442\u0435\u043b\u0438
+friend.mod.subs=\u0414\u044f\u0441\u043d\u043e \u043f\u043e\u0441\u043e\u0447\u0432\u0430\u043d\u0435 \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
+TableColumn.header.class=\u041a\u043b\u0430\u0441
+device.rss.group=\u041c\u0435\u0441\u0442\u043d\u0430 \u0435\u043c\u0438\u0441\u0438\u044f
+devices.xcode.rsspub=\u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u0435\u043c\u0438\u0441\u0438\u044f
+device.rss.enable=\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0435\u043c\u0438\u0441\u0438\u044f \u043e\u0442 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 - \u043f\u0440\u0430\u0432\u0438 \u0434\u043e\u0441\u0442\u044a\u043f\u043d\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e \u0437\u0430 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430 [...]
+device.rss.port=\u041f\u043e\u0440\u0442 \u0437\u0430 \u0435\u043c\u0438\u0441\u0438\u044f
+device.rss.view=\u041e\u043d\u0430\u0433\u043b\u0435\u0434\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0435\u043c\u0438\u0441\u0438\u044f
+device.rss.localonly=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0441\u0430\u043c\u043e \u0437\u0430 \u0442\u043e\u0437\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440
+devices.xcode.autoCopy=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
+devices.xcode.setcopyto=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u2026
+devices.xcode.setcopyto.title=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u043c\u044f\u0441\u0442\u043e, \u0432 \u043a\u043e\u0435\u0442\u043e \u0434\u0430 \u0441\u0435 \u043a\u043e\u043f\u0438\u0440\u0430
+devices.copy.folder.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
+devices.copy.folder.dest=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
+TableColumn.menu.maxuploads=\u0411\u0440. \u043c\u0430\u043a\u0441. \u043a\u0430\u0447\u0432\u0430\u043d\u0438\u044f
+devices.xcode.mancopy=\u0420\u044a\u0447\u043d\u043e \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+devices.xcode.show.cat=\u041e\u0442\u0434\u0435\u043b\u044f\u043d\u0435 \u0441\u043f\u043e\u0440\u0435\u0434 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u0442\u0430
+ConfigView.label.alwaysShowLibraryHeader=\u0412\u0438\u043d\u0430\u0433\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u0437\u0430\u0433\u043b\u0430\u0432\u043d\u0430/\u0444\u0438\u043b\u0442\u044a\u0440 \u043b\u0435\u043d\u0442\u0430 \u0432 \u041c\u0435\u0441\u0442\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+devices.cat.show=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
+devices.tivo.machine=\u0418\u043c\u0435 \u043d\u0430 TiVo \u043c\u0430\u0448\u0438\u043d\u0430
+devices.info.copypending=%1 \u0444\u0430\u0439\u043b\u0430 \u0447\u0430\u043a\u0430\u0442 \u0437\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435
+device.error.xcodefail=\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438
+device.error.copyfail=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 1 \u0438\u043b\u0438 \u043f\u043e\u0432\u0435\u0447\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f
+device.error.copytonotset='\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f' \u043d\u0435 \u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043e
+device.error.copytomissing='\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f' "%1" \u043d\u0435 \u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043e
+device.error.copytonowrite='\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f' "%1" \u043d\u044f\u043c\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d \u0437\u0430\u043f\u0438\u0441
+device.error.copyfail2=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 1 \u0438\u043b\u0438 \u043f\u043e\u0432\u0435\u0447\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+v3.deviceview.infobar.line2.tivo=\u041f\u043e\u0442\u043e\u0447\u043d\u043e \u0432\u0438\u0434\u0435\u043e-\u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441\u0435 \u043f\u0443\u0441\u043a\u0430\u0442 \u043a\u0430\u0442\u043e \u043e\u0442 TiVo \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0435 Vuze \u0432 Now Playing List.
+v3.deviceview.infobar.line2.psp=\u0412\u0438\u0434\u0435\u043e-\u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0449\u0435 \u0441\u0435 \u043a\u043e\u043f\u0438\u0440\u0430\u0442, \u043a\u043e\u0433\u0430\u0442\u043e \u0441\u0435 \u0441\u0432\u044a\u0440\u0436\u0435 PSP.
+devices.info.copypending2=%1 \u0444\u0430\u0439\u043b\u0430 \u0447\u0430\u043a\u0430\u0442 \u0437\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435, \u0434\u0430 \u0441\u0435 \u0441\u0432\u044a\u0440\u0436\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+subscriptions.column.nb-subscribers=\u0410\u0431\u043e\u043d\u0430\u0442\u0438
+device.offlinedownloader.view.title=\u041d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+device.od.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+device.odauto.enable=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f\u0442\u0430
+device.odpt.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0447\u0430\u0441\u0442\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
+devices.contextmenu.od=\u041d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+devices.contextmenu.od.auto=<\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e>
+devices.contextmenu.od.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435
+devices.contextmenu.od.enabled=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+devices.od.view.heading=\u0421\u0432\u0430\u043b\u044f\u043d\u0438\u044f \u043f\u043e \u0433\u0440\u0430\u0444\u0438\u043a \u0437\u0430 \u043d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+DevicesOD.column.od_completion=\u0420\u0430\u0437\u0432\u0438\u0442\u0438\u0435 \u043d\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0430
+devices.od.idle=\u041d\u0435\u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0435\u043d\u043e
+device.od.turnon.title=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u0437\u0430 \u043d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+device.is.disabled=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u043d\u0435 \u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+device.configure=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d\u0435\u2026
+device.od.error.notfound=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0438\u0437\u0433\u043b\u0435\u0436\u0434\u0430 \u043d\u0435 \u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e
+device.od.error.opfailstatus=\u041f\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u043f\u0440\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 %1: \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 %2
+device.od.error.opfailexcep=\u041f\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u043f\u0440\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 %1: \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 %2
+device.od.error.nospace=\u041d\u044f\u043c\u0430 \u043c\u044f\u0441\u0442\u043e \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0438\u043b\u0438 \u043d\u0435 \u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e \u0432\u044a\u043d\u0448\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e 
+device.od.space=\u041d\u0430\u043b\u0438\u0447\u043d\u043e \u043c\u044f\u0441\u0442\u043e
+ConfigView.section.style.forceSIValues=\u041d\u0430\u0441\u0438\u043b\u0435\u043d\u043e \u043f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043a\u0430\u0442\u043e IEC \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442\u0438 \u0431\u0435\u0437 \u043e\u0433\u043b\u0435\u0434 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0437\u0435\u043d\u0438\u0442\u0435 \u0435\u0434\u0438\u043d\u0438\u0446\u0438 \u0437\u0430\u0440\u0430\u0434\u0438 \u0441\u044a\u0432\u043c\u0435\u0441\u0442\u0438\ [...]
+ConfigView.label.enableSystrayToolTip=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0437\u0430 \u0441\u0432\u0430\u043b\u0430\u043d\u0435\u0442\u043e \u043f\u0440\u0438 \u043f\u0440\u0435\u043c\u0438\u043d\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430
+devices.activation=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+button.nothanks=\u041d\u0435, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f
+devices.od.turnon.text1=\u0418\u043c\u0430 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442 \u0441 %1.
+devices.od.turnon.text2=\u0414\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438 \u043b\u0438 %1 \u0434\u0430 \u0441\u0432\u0430\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u0435, \u043a\u043e\u0433\u0430\u0442\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f?
+devices.od.turnon.text3=\u0414\u0430 \u0441\u0435 \u0441\u0432\u044a\u0440\u0436\u0435 \u0442\u0432\u044a\u0440\u0434 \u0434\u0438\u0441\u043a \u043a\u044a\u043c %1 \u0437\u0430 \u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u0430\u0437\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f.
+devices.od.turnon.learn=\u041f\u043e\u0432\u0435\u0447\u0435 >
+devices.router=\u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440
+devices.od=\u041d\u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+webui.pairingenable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e
+webui.group.access=\u041a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0434\u043e\u0441\u0442\u044a\u043f
+ConfigView.section.Pairing=\u0421\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435
+pairing.accesscode=\u041a\u043e\u0434 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f
+pairing.ac.getnew=\u0417\u0430\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432 \u043a\u043e\u0434 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f
+pairing.ac.getnew.create=\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435
+pairing.ipv4=IPv4 \u0430\u0434\u0440\u0435\u0441
+pairing.ipv6=IPv6 \u0430\u0434\u0440\u0435\u0441
+pairing.local.ipv4=\u041c\u0435\u0441\u0442\u0435\u043d IPv4 \u0430\u0434\u0440\u0435\u0441
+pairing.local.ipv6=\u041c\u0435\u0441\u0442\u0435\u043d IPv6 \u0430\u0434\u0440\u0435\u0441
+pairing.host=Host \u0430\u0434\u0440\u0435\u0441 (DNS \u0438\u043c\u0435)
+pairing.group.explicit=\u0418\u0437\u0440\u0438\u0447\u043d\u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0438
+pairing.explicit.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435
+pairing.explicit.info=\u041d\u043e\u0440\u043c\u0430\u043b\u043d\u043e \u043d\u0435 \u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0438\u0437\u0440\u0438\u0447\u043d\u0438 IP \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0438, \u0437\u0430\u0449\u043e\u0442\u043e \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442 \u0430\u0432\u0442\u043e\u0 [...]
+pairing.op.fail=\u0421\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438
+pairing.alloc.fail=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u0437\u0430\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432 \u043a\u043e\u0434 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f\n%1
+pairing.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 Vuze \u0438 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f/\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0438
+pairing.status.info=\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+pairing.status.registered=\u0423\u0441\u043f\u0435\u0448\u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f (%1)
+pairing.status.pending=\u0410\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0449\u0435 \u0441\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u0438 \u0432 %1
+pairing.status.initialising=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435
+pairing.status.disabled=\u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d
+pairing.view.registered=\u041f\u043e\u0441\u043e\u0447\u0432\u0430\u043d\u0435 \u0437\u0430 \u043f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u0437\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0442\u0430
+webui.pairing.info.n=\u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0435 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 "\u0412\u0440\u044a\u0437\u043a\u0430" \u2192 "\u0421\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435" \u0437\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0442\u0430\u0437\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f.
+webui.pairing.info.y=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0435 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e. \u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u0438 "\u0412\u0440\u044a\u0437\u043a\u0430" \u2192 "\u0421\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435" \u0437\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438.
+webui.enable=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 (*)
+ConfigView.section.rss=\u041c\u0435\u0441\u0442\u043d\u0438 \u0435\u043c\u0438\u0441\u0438\u0438 \u0438 \u0434\u0440.
+subscriptions.rss.enable=\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0435\u043c\u0438\u0441\u0438\u0438 \u043e\u0442 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
+device.tivo.enable=\u0421 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u043d\u0430 TiVo
+Button.removeAll=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u0432\u0441\u0438\u0447\u043a\u0438
+label.rename=\u041f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 %1
+pairing.server.warning.title=\u0421\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u0449\u0438\u044f \u0441\u0435 \u0441\u044a\u0440\u0432\u044a\u0440
+wizard.webseedseditor.edit.title=\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043d\u0430 \u043f\u043e\u0441\u044f\u0432\u043a\u0438\u0442\u0435 \u043f\u0440\u0435\u0437 HTTP
+wizard.webseedseditor.edit.newseed=\u041d\u043e\u0432\u0430 \u043f\u043e\u0441\u044f\u0432\u043a\u0430
+MyTorrentsView.menu.editWebSeeds=\u0420\u0435\u0434\u0430\u043a\u0446\u0438\u044f \u043d\u0430 \u043f\u043e\u0441\u044f\u0432\u043a\u0438\u0442\u0435 \u043f\u0440\u0435\u0437 HTTP
+ClientStats.title.full=\u041a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438
+ClientStats.column.count=\u0411\u0440\u043e\u044f\u0447
+Scrape.status.cached=\u0411\u0443\u0444\u0435\u0440\u0438\u0440\u0430\u043d\u043e \u043e\u0441\u0442\u044a\u0440\u0433\u0432\u0430\u043d\u0435
+network.ipv6.enable.support=\u0421 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u043d\u0430 IPv6
+ConfigView.section.plugins.magnetplugin=\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430 Magnet URI
+MagnetPlugin.use.lookup.service=\u0414\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u043d\u0430 Vuze \u0437\u0430 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435, \u0430\u043a\u043e magnet \u0442\u044a\u0440\u0441\u0435\u043d\u0435\u0442\u043e \u043f\u0440\u0435\u0437 DHT \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438
+MagnetPlugin.report.secondarylookup=\u041e\u043f\u0438\u0442 \u0441 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430 \u0437\u0430 \u0432\u0442\u043e\u0440\u0438\u0447\u043d\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435
+MagnetPlugin.report.secondarylookup.ok=\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0442\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u0443\u0441\u043f\u044f
+MagnetPlugin.report.secondarylookup.fail=\u0412\u0442\u043e\u0440\u0438\u0447\u043d\u043e\u0442\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438: \u043d\u044f\u043c\u0430 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438 \u0438\u0437\u0442\u043e\u0447\u043d\u0438\u0446\u0438
+TrackerView.title.short=\u0418\u0437\u0442\u043e\u0447\u043d\u0438\u0446\u0438
+TrackerView.title.full=\u0418\u0437\u0442\u043e\u0447\u043d\u0438\u0446\u0438
+Trackers.column.type=\u0422\u0438\u043f
+Trackers.column.name=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+Trackers.column.status=\u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+Trackers.column.seeds=\u041f\u043e\u0441\u044f\u0432\u043a\u0438
+Trackers.column.seeds.info=\u041f\u043e\u0441\u044f\u0432\u043a\u0438 \u0432 \u0440\u043e\u044f\u043a\u0430
+Trackers.column.leechers=\u041f\u0438\u044f\u0432\u0438\u0446\u0438
+Trackers.column.leechers.info=\u041f\u0438\u044f\u0432\u0438\u0446\u0438 \u0432 \u0440\u043e\u044f\u043a\u0430
+Trackers.column.peers=\u0420\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
+Trackers.column.peers.info=\u0420\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438 \u0441\u043f\u043e\u0440\u0435\u0434 \u0442\u0440\u0430\u043a\u0435\u0440\u0430
+Trackers.column.interval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b
+Trackers.column.interval.info=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0437\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0442\u044a\u0440\u0441\u0435\u043d\u0435, s: \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b (\u043c\u0438\u043d. \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b)
+Trackers.column.updatein=\u041d\u0430\u043f\u0440\u0435\u0434
+Trackers.column.updatein.info=\u0412\u0440\u0435\u043c\u0435 \u0434\u043e \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
+tps.status.available=\u041d\u0430\u043b\u0438\u0447\u043d\u043e
+tps.status.unavailable=\u041d\u0435 \u0435 \u043d\u0430\u043b\u0438\u0447\u043d\u043e
+tps.type.dht=\u0420\u0411\u0414
+tps.lan.details=%1 \u043c\u0435\u0441\u0442\u043d\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0438 \u0441\u0430 \u043e\u0442\u043a\u0440\u0438\u0442\u0438
+tps.pex.details=\u0421\u0432\u044a\u0440\u0437\u0430\u043d \u0441 %1 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438 (\u0447\u0430\u043a\u0430\u0449\u0438: pex=%2, \u0434\u0440\u0443\u0433\u0438=%3)
+tps.tracker.cache=\u0411\u0443\u0444\u0435\u0440 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438
+tps.tracker.cache1=\u0411\u0443\u0444\u0435\u0440 \u043d\u0430 \u0440\u0430\u0432\u043d\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0435\u043d\u0438: \u0431\u0440\u043e\u0439=%1
+dht.status.disabled=\u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u0420\u0411\u0414 \u043d\u0435 \u0435 \u043d\u0430\u043b\u0438\u0447\u043d\u0430
+tps.type.incoming=\u0412\u0445\u043e\u0434\u044f\u0449\u0438
+tps.incoming.details=\u0422\u0435\u043a\u0443\u0449\u043e: TCP=%1, UDP=%2; \u041e\u0431\u0449\u043e \u043e\u0442\u043d\u0430\u0447\u0430\u043b\u043e=%3
+tps.type.plugin=\u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430
+group.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e
+ConfigView.label.autoadjust=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0441\u043f\u043e\u0440\u0435\u0434 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430
+ConfigView.label.start=\u041f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435
+ConfigView.label.stop=\u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435
+ConfigView.label.start.onlogin=\u0421\u0442\u0430\u0440\u0442 \u043d\u0430 Vuze \u043f\u0440\u0438 \u0432\u043f\u0438\u0441\u0432\u0430\u043d\u0435
+ConfigView.label.stop.seedcomp=\u041f\u0440\u0438 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u0441\u0435\u0435\u043d\u0435
+ConfigView.label.stop.downcomp=\u041f\u0440\u0438 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+ConfigView.label.stop.Nothing=\u0411\u0435\u0437 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+ConfigView.label.stop.QuitVuze=\u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 Vuze
+ConfigView.label.stop.Sleep=\u041f\u0440\u0435\u0441\u0442\u043e\u0439 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430
+ConfigView.label.stop.Hibernate=\u041f\u0440\u0438\u0441\u043f\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430
+ConfigView.label.stop.Shutdown=\u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430
+core.shutdown.alert=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 '%1' \u0435 \u043f\u0443\u0441\u043d\u0430\u0442\u043e \u043a\u0430\u0442\u043e %2
+core.shutdown.dl=\u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
+core.shutdown.se=\u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0438 \u043f\u043e\u0441\u044f\u0432\u043a\u0438
+pairing.last.error=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430
+MainWindow.menu.pairing=\u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435
+ConfigView.label.pauseresume=\u0410\u0432\u0442\u043e-\u043f\u0430\u0443\u0437\u0430/\u043f\u043e\u0434\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435
+update.now.title=\u0418\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
+update.now.desc=Vuze \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0434\u0430 \u0441\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0430\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430 \u0437\u0430\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u0442\u0430.\n\n\u0421\u043b\u0435\u0434 \u0437\u0430\u0442\u0432\u0430\u0440\u044f\u043d\u0435 \u043d\u0430 \u0442\u043e\u0437\u0438 \u0434\u04 [...]
+ConfigView.label.jvm=\u0412\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 Java
+platform.jvmopt.sunonly=\u041f\u043e\u0434\u0434\u044a\u0440\u0436\u0430\u0442 \u0441\u0435 \u0441\u0430\u043c\u043e JVM \u043d\u0430 Sun (\u0442\u0435\u043a\u0443\u0449 \u0434\u043e\u0441\u0442\u0430\u0432\u0447\u0438\u043a=%1)
+platform.jvmopt.configerror=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0442 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u043d\u0430 JVM \u0437\u0430\u0440\u0430\u0434\u0438 \u0433\u0440\u0435\u0448\u043a\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u0442\u0430
+platform.jvmopt.nolinkfile=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0442 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u043d\u0430 JVM \u0437\u0430\u0440\u0430\u0434\u0438 \u043d\u0435\u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0430 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f
+platform.jvmopt.nolink=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0442 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u043d\u0430 JVM \u0437\u0430\u0440\u0430\u0434\u0438 \u0437\u0430\u0431\u0440\u0430\u043d\u0430 \u043e\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u0442\u0430
+platform.jvmopt.accesserror=\u041f\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 JVM: %1
+pairing.status.noservices=\u041d\u044f\u043c\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0438 \u0443\u0441\u043b\u0443\u0433\u0438
+webui.pairingtest=\t\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0437\u0430 \u043f\u0440\u043e\u0431\u0430 \u043d\u0430 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e
+webui.connectiontest=\t\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0437\u0430 \u043f\u0440\u043e\u0431\u0430 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430
+jvm.info=Vuze \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430, \u0430\u043a\u043e \u0441\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u044f\u0442 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435. *** \u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435 - \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u [...]
+jvm.show.file=\u041c\u0435\u0441\u0442\u043d\u0438\u044f\u0442 \u0444\u0430\u0439\u043b \u0441 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 JVM \u0435 '%1' - \u0434\u0430 \u0441\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u043e \u0441\u0430\u043c\u043e \u043f\u0440\u0438 \u0432\u044a\u0437\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435
+jvm.reset=JVM \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u0434\u0430 \u0441\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u043e\u043d\u043d\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0449\u0438\u0442\u0435 \u0441\u0435
+jvm.error=\u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u044a\u043f\u0430 \u0434\u043e \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u043d\u0430 JVM: %1
+jvm.max.mem=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043c\u0435\u0442 [\u043f\u0440\u0430\u0437\u043d\u043e=\u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435,\u043c\u0438\u043d.=%1]
+jvm.min.mem=\u041c\u0438\u043d. \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043c\u0435\u0442 [\u043f\u0440\u0430\u0437\u043d\u043e=\u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435,\u043c\u0438\u043d.=%1]
+ConfigView.section.invalid.value.title=\u041d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442
+ConfigView.section.invalid.value=\u0412\u044a\u0432\u0435\u0434\u0435\u043d\u0430 \u0435 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 '%1' \u0437\u0430 '%2': %3
+Button.dismiss=\u041f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u043e
+webui.pairing.autoauth=\u0421\u044a\u0441 \u0437\u0430\u0449\u0438\u0442\u0430 \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435: \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b=vuze, \u043f\u0430\u0440\u043e\u043b\u0430=<\u043a\u043e\u0434 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u043d\u0430 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435\u0442\u043e>
+ConfigView.label.stop.autoreset=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430 \u043f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0442\u0430 \u043a\u0430\u0442\u043e '%1' \u043f\u0440\u0438 \u043f\u0443\u0441\u043a\u0430\u043d\u0435
+remote.pairing.title=\u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435
+remote.pairing.subtitle=Vuze Remote \u0434\u0430\u0432\u0430 \u0432\u043b\u0430\u0441\u0442 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 Vuze \u043e\u0442 \u0432\u0441\u0435\u043a\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u0438\u043b\u0438 \u043c\u043e\u0431\u0438\u043b\u0435\u043d \u0431\u0440\u0430\u0443\u0437\u044a\u0440 \u043f\u043e \u0432\u0441\u044f\u043a\u043e \u0432\u0440\u0435\u043c\u0435 \u0438 \u043d\u0430\u0432\u0441\u044f\u043a\u044a\u04 [...]
+remote.pairing.instruction=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u0441\u043b\u0435\u0434\u043d\u0438\u044f\u0442 \u043a\u043e\u0434 \u0432 \u043f\u0440\u0430\u0437\u043d\u043e\u0442\u043e \u043c\u044f\u0441\u0442\u043e \u0434\u043e\u0441\u0442\u044a\u043f\u043d\u043e \u043e\u0442 \u043d\u044f\u043a\u043e\u0435 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.
+remote.pairing.functions=<A HREF="clip">\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u0434\u0430 \u0432 \u043a\u043b\u0438\u043f\u0431\u043e\u0440\u0434\u0430</A>   |   <A HREF="new">\u041f\u043e\u043b\u0443\u0447\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432 \u043a\u043e\u0434</A>
+remote.pairing.tip.title=\u041f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430: 2 \u043b\u0435\u0441\u043d\u0438 \u043d\u0430\u0447\u0438\u043d\u0430 \u0437\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 Vuze Remote:
+remote.pairing.tip.text=Vuze Remote \u043b\u0435\u043d\u0442\u0430 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438: \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438 <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nVuze Remote \u043c\u043e\u0431\u0438\u043b\u0435\u043d: \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u0435\u0442\u0438 <A HREF="http://remote.vuze.com/">remote.vuze.com</A> \u0447\u0440\u0435\u0437 \u043c\u043e\u04 [...]
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">\u0427\u0417\u0412 \u0437\u0430 \u0441\u0434\u0432\u043e\u044f\u0432\u0430\u043d\u0435</A>
+remote.pairing.accesscode=\u041a\u043e\u0434 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f:
+remote.pairing.test.running=\u041f\u0440\u043e\u0431\u0430 \u043d\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0430 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442\u2026
+remote.pairing.test.success=Vuze \u0435 \u0434\u043e\u0441\u0442\u044a\u043f\u0435\u043d \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e.
+remote.pairing.test.unavailable=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0430 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442. <A HREF="retry">\u041d\u043e\u0432 \u043e\u043f\u0438\u0442</A>
+remote.pairing.test.fail=Vuze \u043d\u0435 \u0435 \u0434\u043e\u0441\u0442\u044a\u043f\u0435\u043d \u0438\u0437\u0432\u044a\u043d \u043b\u043e\u043a\u0430\u043b\u043d\u0430\u0442\u0430 \u043c\u0440\u0435\u0436\u0430.  <A HREF="/pairing_error_faq.start">\u041f\u043e\u0432\u0435\u0447\u0435</A>
+update.fail.app.changed.title=\u041f\u0440\u043e\u0432\u0430\u043b \u043d\u0430 \u043d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e
+update.fail.app.changed=Vuze \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u043d\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u044a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u044a\u0440\u0448\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e, \u0437\u0430\u0449\u043e\u0442\u043e \u0438\u043c\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u04 [...]
+webui.port.override=\u041f\u0440\u0435\u0432\u044a\u0437\u043c\u043e\u0433\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0440\u0442: \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u0441\u0430\u043c\u043e, \u0430\u043a\u043e \u0432\u044a\u043d\u0448\u043d\u0438\u044f\u0442 \u043f\u043e\u0440\u0442 \u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0435\u043d \u043e\u0442 \u0432\u044a\u0442\u0440\u0435\u0448\u043d\u0438\u044f \u0437\u0430\u0440\u0430\u0434\u0438 NAT \u043a\u043e\u [...]
+MainWindow.status.warning.tooltip=\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0442\u0443\u043a \u0437\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+search.dialog.text=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u0442\u0435\u043a\u0441\u0442 \u0437\u0430 \u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438:
+core.not.available=Vuze \u0432\u0441\u0435 \u043e\u0449\u0435 \u0441\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430, \u0434\u0430 \u0441\u0435 \u043e\u043f\u0438\u0442\u0430 \u043e\u0442\u043d\u043e\u0432\u043e \u0441\u043b\u0435\u0434 \u0437\u0430\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435\u0442\u043e \u043c\u0443.
+dlg.auth.title=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f
+dlg.auth.enter.subtitle.try.1=\u041f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u043e.
+dlg.auth.enter.line.try.1=\u0414\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0434\u0435 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0438\u044f\u0442 \u043a\u043e\u0434 \u0437\u0430 \u0437\u0430\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435 \u043d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0434\u043e Vuze \u041f\u043b\u044e\u0441.
+dlg.auth.enter.line.try.2=\u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0442\u0430 \u043d\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0438\u044f \u043a\u043e\u0434. \u0414\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u043d\u043e\u043c\u0435\u0440\u0430 \u0438 \u0434\u0430 \u0441\u0435 \u043e\u043f\u0438\u0442\u0430 \u04 [...]
+dlg.auth.enter.prompt=Vuze \u041f\u043b\u044e\u0441 \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f:
+Button.validate=\u0412\u0430\u043b\u0438\u0434\u0438\u0440\u0430\u043d\u0435
+Button.getstarted=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435
+Button.goLibrary=\u041a\u044a\u043c \u041c\u0435\u0441\u0442\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+dlg.auth.success.subtitle=\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f!
+dlg.auth.success.line1=\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u043d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0434\u043e Vuze \u041f\u043b\u044e\u0441.
+dlg.auth.success.line2=\u0412\u0435\u0447\u0435 \u0435 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435\u0442\u043e \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u043c\u0438 DVD-\u0442\u0430, \u043f\u0440\u043e\u0443\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0437\u0430 \u0432\u0438\u0440\u0443\ [...]
+dlg.auth.trial.success.line1=Vuze \u0435 \u0433\u043e\u0442\u043e\u0432 \u0434\u0430 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 DVD-\u0442\u0430.
+dlg.auth.trial.success.subtitle=DVD \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435\u0442\u043e \u0435 \u0432 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442
+dlg.auth.trial.success.info=\u041c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0432\u043b\u0430\u0447\u0430\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430 \u0434\u043e "\u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 DVD." \u0410\u043a\u043e \u0432\u0435\u0447\u0435 \u0435 \u0434\u043e\u0431\u0430\u0432\u0435\u043d\u043e \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0435\u0434\u04 [...]
+dlg.auth.revoked=\u041a\u043e\u0434\u044a\u0442 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d
+dlg.auth.revoked.line1=\u0422\u043e\u0437\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u0435\u043d \u043a\u043e\u0434 \u0437\u0430 Vuze \u041f\u043b\u044e\u0441 \u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u043f\u043e-\u0434\u043e\u043b\u0443 \u0437\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f.
+dlg.auth.revoked.link=<A HREF="info">\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0438 \u043a\u043e\u0434\u043e\u0432\u0435</A>
+dlg.auth.denied=\u041e\u0442\u0445\u0432\u044a\u0440\u043b\u0435\u043d \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435
+dlg.auth.denied.line1=\u041a\u043e\u0434\u044a\u0442 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043d\u0430 Vuze \u041f\u043b\u044e\u0441 \u0435 \u043e\u0442\u0445\u0432\u044a\u0440\u043b\u0435\u043d. \u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u043f\u043e-\u0434\u043e\u043b\u0443 \u0437\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f.
+dlg.auth.denied.link=<A HREF="info">\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043e\u0442\u0445\u0432\u044a\u0440\u043b\u0435\u043d\u0438 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u043d\u0438 \u043a\u043e\u0434\u043e\u0432\u0435</A>
+dlg.auth.cancelled=\u041a\u043e\u0434\u044a\u0442 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u0435 \u043e\u0442\u043a\u0430\u0437\u0430\u043d
+dlg.auth.cancelled.line1=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 Vuze \u041f\u043b\u044e\u0441 \u0435 \u043e\u0442\u043a\u0430\u0437\u0430\u043d\u0430.
+dlg.auth.cancelled.line2=\u041f\u0440\u0438 \u0441\u044a\u043c\u043d\u0435\u043d\u0438\u044f \u0437\u0430 \u0433\u0440\u0435\u0448\u043a\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u0442\u044a\u0440\u0441\u0438 \u043f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u0447\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f\u0442\u0430 \u0432 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u0449\u043e \u0444\u04 [...]
+dlg.auth.enter.subtitle.try.2=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442 \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438.
+dlg.auth.enter.link.try.2=<A HREF="link">\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0442\u0443\u043a</A>, \u0430\u043a\u043e \u043d\u0435 \u0435 \u0437\u0430\u043a\u0443\u043f\u0435\u043d \u0432\u0441\u0435 \u043e\u0449\u0435 Vuze \u041f\u043b\u044e\u0441.
+dlg.auth.enter.link.try.1=\u041d\u044f\u043c\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u043e\u043d\u0435\u043d \u043a\u043e\u0434? <A HREF="upgrade">\u041d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0441\u0435\u0433\u0430</A>.
+dlg.auth.enter.expiry=\u0422\u0435\u043a\u0443\u0449\u0438\u044f\u0442 \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0438\u0437\u0442\u0438\u0447\u0430 \u043d\u0430 %1.
+dlg.auth.enter.revoked=\u0422\u0435\u043a\u0443\u0449\u0438\u044f\u0442 \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d.
+dlg.auth.enter.cancelled=\u0422\u0435\u043a\u0443\u0449\u0438\u044f\u0442 \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0435 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0435\u043d.
+dlg.auth.enter.denied=\u0422\u0435\u043a\u0443\u0449\u0438\u044f\u0442 \u043a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0435 \u043e\u0442\u0445\u0432\u044a\u0440\u043b\u0435\u043d.
+dlg.auth.validating.subtitle=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u2026
+dlg.try.trial.title=\u0418\u0437\u043f\u0440\u043e\u0431\u0432\u0430\u043d\u0435 \u043d\u0430 DVD \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435
+dlg.try.trial.text=Vuze \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430 \u0434\u043e\u0431\u0430\u0432\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0437\u0430 \u0437\u0430\u043f\u0438\u0441 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e-\u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043a\u0430\u0442\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u043c\u0438 DVD-\u0442\u0430. \u0414\u0430 \u0441\u0435 \u04 [...]
+dlg.auth.tos=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u0435 \u0438 \u043f\u0440\u0438\u0435\u043c\u0430\u043d\u0435 \u043d\u0430 <A HREF="tos">\u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0442\u0430 \u043d\u0430 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430.</A>
+dlg.auth.install.subtitle.plus=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Vuze \u041f\u043b\u044e\u0441\u2026
+dlg.auth.install.subtitle.trial=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 DVD Burn
+dlg.auth.install.progress=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 %1 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0438\u2026
+dlg.auth.install.pct=%1% \u0433\u043e\u0442\u043e\u0432\u043e
+mdi.entry.plus.full=Vuze \u041f\u043b\u044e\u0441
+mdi.entry.plus.free=Vuze \u041f\u043b\u044e\u0441
+mdi.entry.dvdburn=DVD \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435
+mdi.entry.dvdburn.new=\u0417\u0430\u043f\u0438\u0441 \u043d\u0430 \u043d\u043e\u0432\u043e DVD
+menu.plus=Vuze \u041f\u043b\u044e\u0441
+menu.register=Vuze \u041f\u043b\u044e\u0441 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f
+dlg.auth.trial.title=\u041f\u0440\u043e\u0431\u043d\u043e DVD \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435
+dlg.player.install.subtitle=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435
+dlg.player.install.description=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u043d \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435\u2026
+devices.xcode.remove.vetoed=\u041f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 '%1' \u0435 \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0435. \u0421\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0430\u0442\u043e \u0434\u043e\u043a\u0430\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u044a\u0442 \u043d\u0435 \u0437\u0430 [...]
+Button.agree=\u0421\u044a\u0433\u043b\u0430\u0441\u0438\u0435
+dlg.auth.install.failed.title=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f\u0442\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438
+dlg.auth.install.failed.text=\u041a\u043e\u0434 \u0437\u0430 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f '%1' \u0441\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0438 \u0437\u0430\u0440\u0430\u0434\u0438 \u0433\u0440\u0435\u0448\u043a\u0430 \u0432 \u0441\u044a\u0440\u0432\u044a\u0440\u0430.\n\n\u0414\u0430 \u0441\u0435 \u043e\u043f\u0438\u0442\u0430 \u043e\u0442\u043d\u043e\u0432\u043e \u0441 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f\u0442\u0430 \u043f\u043e-\u043a [...]
+device.status.online=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u0442\u043e \u0435 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e
+device.itunes.status.running=iTunes \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d
+device.itunes.status.notrunning=iTunes \u043d\u0435 \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d
+device.itunes.status.notinstalled=iTunes \u043d\u0435 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d
+OpenTorrentWindow.mb.notTorrent.retry=\u0422\u044a\u0440\u0441\u0435\u043d\u0435 \u043d\u0430 Magnet
+ConfigView.section.ipfilter.clear.on.reload=\u0411\u0435\u0437 \u0444\u0438\u043b\u0442\u0440\u0438 \u043f\u0440\u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0430 \u043d\u0430 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 IP-\u0442\u0430\u0442\u0430 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d\u0438. \u0411\u0435\u0437 \u043e\u0 [...]
+view.waiting.core=\u0418\u0437\u0433\u043b\u0435\u0434\u044a\u0442 \u0449\u0435 \u0435 \u043d\u0430\u043b\u0438\u0447\u0435\u043d \u0441\u043b\u0435\u0434 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u044f\u0434\u0440\u043e\u0442\u043e \u043d\u0430 Vuze\u2026
+devices.profile.direct=\u0414\u0438\u0440\u0435\u043a\u0442\u043d\u043e
+cat.autoxcode=\u0410\u0432\u0442\u043e-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+ConfigView.section.tables=\u0422\u0430\u0431\u043b\u0438\u0446\u0438
+ConfigView.section.style.useTree=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0432 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430/\u041c\u0435\u0441\u0442\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 (\u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+ConfigView.section.mode.resetdefaults=\u041f\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u0441\u044a\u0441 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 (\u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+resetconfig.warn.title=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+resetconfig.warn=\u0422\u043e\u0432\u0430 \u0449\u0435 \u043f\u0440\u0435\u0434\u0438\u0437\u0432\u0438\u043a\u0430 \u0437\u0430\u0433\u0443\u0431\u0430 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u0435\u043d\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 Vuze.\n\u0414\u0430 \u0441\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u0438 \u043b\u04 [...]
+ConfigView.label.xfer.bias_up=\u0423\u0432\u0435\u043b\u0438\u0447\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\u0442\u0435 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0447\u0440\u0435\u0437 \u0442\u043e\u043b\u0435\u0440\u0430\u043d\u0441 \u043d\u0430 \u043a\u0430\u043f\u0430\u0446\u0438\u0442\u0435\u0442\u0430 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u0432\u044a\u0440\u0445\u0443 \u043d\u0435\u0437\u0430\u0432 [...]
+ConfigView.label.xfer.bias_slack=KB/s \u0437\u0430\u043f\u0430\u0437\u0435\u043d \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0437\u0430 \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0438\u044f
+ConfigView.label.xfer.bias_no_limit=\u041e\u043f\u0438\u0442 \u0437\u0430 \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u043b\u0435\u0440\u0430\u043d\u0441, \u043a\u043e\u0433\u0430\u0442\u043e \u043d\u044f\u043c\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u043e \u043e\u0431\u0449\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435\u0442\u043e
+SpeedView.stats.upload=\u0414\u0430\u043d\u043d\u0438 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435:
+SpeedView.stats.con=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430:
+SpeedView.stats.con_details=\u043e\u0431\u0449\u043e=%1, \u0441 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0430\u0442\u043e \u043f\u043e\u0442\u0438\u0441\u043a\u0430\u043d\u0435=%2, \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430=%3, \u0431\u043b\u043e\u043a\u0438\u0440\u0430\u043d\u0438=%4
+SpeedView.stats.upbias=\u0422\u043e\u043b\u0435\u0440\u0430\u043d\u0441 \u043d\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435:
+dlg.install.mlab.subtitle=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435
+dlg.install.mlab.description=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u0437\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0437\u0430 \u0442\u0435\u0441\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442
+dial.up=\u041d\u0430\u0431\u0438\u0440\u0430\u043d\u0435
+auto.mode=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e (\u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0441\u0435)
+manual.mode=\u0420\u044a\u0447\u043d\u043e
+configureWizard.transfer2.hint=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430 \u043c\u043d\u043e\u0433\u043e \u0433\u043e\u043b\u044f\u043c\u043e \u0438\u043b\u0438 \u043c\u0430\u043b\u043a\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u0449\u0435 \u043f\u043e\u0432\u043b\u0438\u044f\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044f\u043d\u0435\u0442\u043e \u04 [...]
+configureWizard.transfer2.message=Bittorrent \u0435 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 "\u0442\u0430\u043d\u0442\u043e \u0437\u0430 \u0442\u0430\u043d\u0442\u043e" \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b. \u041d\u0430\u0439-\u043e\u0431\u0449\u043e, \u043a\u043e\u043b\u043a\u043e\u0442\u043e \u043f\u043e-\u0431\u044a\u0440\u0437\u043e \u0441\u0435 \u043a\u0430\u0447\u0432\u0430, \u0442\u043e\u043b\u043a\u043e\u0432\u0430 \u043f\u043e-\u0431\u044a\u0440\u0437 [...]
+configureWizard.transfer2.group=\u0420\u0435\u0436\u0438\u043c
+configureWizard.transfer2.test.info=\u0418\u0437\u0431\u043e\u0440 \u0437\u0430 \u0438\u0437\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0434\u0440\u043e\u0431\u0435\u043d \u0442\u0435\u0441\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430
+configureWizard.transfer2.test=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0442\u0435\u0441\u0442\u0430
+configureWizard.transfer2.mselect=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0442\u0430 \u0437\u0430 \u041a\u0410\u0427\u0412\u0410\u041d\u0415 \u043f\u0440\u0438 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0432\u0440\u044a\u0437\u043a\u0430
+configureWizard.transfer2.mselect.info=xxx/<\u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 <\u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442> b/s \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435.\n\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430 ADSL \u0432\u0440\u044a\u0437\u043a\u0430 768 Kbps \u0441\u043a\u043e\u0440 [...]
+configureWizard.transfer2.rate.unchanged=\u0429\u0435 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
+configureWizard.transfer2.rate.changed=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 = %1\n\u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u043e\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0449\u0435 \u0435 %2 (\u043c\u0430\u043a\u0441. \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438 = %3, \u043c\u0430\u043a\u0441. \u0437\u0430 \u0 [...]
+speedtest.wizard.select.title=\u0418\u0437\u0431\u043e\u0440 \u043d\u0430 \u0442\u0438\u043f\u0430 \u0442\u0435\u0441\u0442 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435
+speedtest.wizard.select.group=\u0422\u0438\u043f \u043d\u0430 \u0442\u0435\u0441\u0442\u0430
+speedtest.wizard.select.general=\u041e\u0431\u0449 \u0442\u0435\u0441\u0442 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 (\u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0441\u0435)
+speedtest.wizard.select.bt=\u0422\u0435\u0441\u0442 \u0437\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u043d \u0437\u0430 Bittorrent
+FileItem.storage.reorder=\u041f\u0440\u0435\u043f\u043e\u0434\u0440\u0435\u0436\u0434\u0430\u043d\u0435
+ConfigView.label.piecereorder=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438 \u043a\u044a\u043c \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043f\u0440\u0438 \u0441\u0432\u0430\u043b\u044f\u043d\u0435 \u0438 \u043f\u0440\u0435\u043d\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u0447\u0435\u0442\u0430 \u0434\u043e\u043a\u0430\u0442\u043e  \u0442\u0435\u0447\u0435 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u04 [...]
+ConfigView.label.piecereorderminmb=\u041f\u0440\u0435\u043f\u043e\u0434\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u0441\u0430\u043c\u043e \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043f\u043e-\u0433\u043e\u043b\u0435\u043c\u0438 \u043e\u0442 (MB)
+configureWizard.transfer2.current=<\u0422\u0435\u043a\u0443\u0449\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438>
+ConfigView.section.style.extendedErase=\u0418\u0437\u0447\u0435\u0440\u0442\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0440\u0435\u0436\u0430 \u0438 \u0437\u0430\u043f\u044a\u043b\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0430\u0437\u043d\u0438 \u0437\u043e\u043d\u0438
+iconBar.stream=\u041f\u043e\u0442\u043e\u043a
+FilesView.menu.setpriority.numeric=\u0427\u0438\u0441\u043b\u043e\u0432\u2026
+FilesView.dialog.priority.title=\u0412\u044a\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0447\u0438\u0441\u043b\u043e\u0432 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+FilesView.dialog.priority.text=0=\u041d\u043e\u0440\u043c\u0430\u043b\u043d\u043e, 1=\u0412\u0438\u0441\u043e\u043a\u043e, 2=\u041f\u043e-\u0432\u0438\u0441\u043e\u043a\u043e\u2026
+beta.wizard.title=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0431\u0435\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f
+beta.wizard.intro.title=\u0421\u0435\u043a\u0446\u0438\u044f \u0437\u0430 \u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435
+beta.wizard.info=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u0432 \u0431\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430 \u043d\u0430 Vuze \u0434\u0430\u0432\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u044f\u0449\u0438 \u0432\u044a\u [...]
+beta.wizard.link=\u0414\u0430 \u0441\u0435 \u043f\u043e\u0441\u043e\u0447\u0438 \u0442\u0443\u043a \u0437\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u0441 \u0431\u0435\u0442\u0430 \u0438\u0437\u0434\u0430\u043d\u0438\u044f\u0442\u0430 
+beta.wizard.off=\u041e\u0442\u043a\u0430\u0437, \u0449\u0435 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0441\u0430\u043c\u043e \u0440\u0435\u0434\u043e\u0432\u043d\u0438 \u0438\u0437\u0434\u0430\u043d\u0438\u044f.
+beta.wizard.on=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0437\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0430\u0442\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u043d\u0430 \u0431\u0435\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f.
+beta.wizard.version=\u0422\u0435\u043a\u0443\u0449\u043e \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0432\u0435\u0440\u0441\u0438\u044f %1
+beta.wizard.disable.title=\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0435 \u043f\u0440\u0435\u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435
+beta.wizard.disable.text=\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0443\u043f\u043e\u0442\u0440\u0435\u0431\u0430\u0442\u0430 \u043d\u0430 \u0431\u0435\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435!\n\n\u0417\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u044f\u0432\u0430\u043d\u0435 \u043e\u0442 \u0431\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430 \u0434\u0430 \u0441\u0435 \u0441\u0432 [...]
+beta.wizard.forum=\u0414\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0444\u043e\u0440\u0443\u043c\u0438\u0442\u0435 \u043d\u0430 Vuze \u0437\u0430 \u043e\u0442\u0437\u0438\u0432\u0438 \u0438 \u0434\u043e\u043a\u043b\u0430\u0434\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u0435\u0438\u0437\u043f\u0440\u0430\u0432\u043d\u043e\u0441\u0442\u0438.
+dlg.install.vuzexcode.subtitle=\u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0437\u0430 \u043c\u0435\u0434\u0438\u0435\u043d \u0430\u043d\u0430\u043b\u0438\u0437
+dlg.install.vuzexcode.description=\u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u0437\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0437\u0430 \u043c\u0435\u0434\u0438\u0435\u043d \u0430\u043d\u0430\u043b\u0438\u0437
+TableColumn.header.filecount=\u0424\u0430\u0439\u043b\u043e\u0432\u0435
+TableColumn.header.torrentspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442
+FileProgress.deleted=\u0418\u0437\u0442\u0440\u0438\u0442\u043e
+priority.high=\u0412\u0438\u0441\u043e\u043a \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+priority.normal=\u041d\u043e\u0440\u043c\u0430\u043b\u0435\u043d \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+label.wrap.text=\u0421\u043c\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u0435\u043a\u0441\u0442
+ScrapeInfoView.title=\u041e\u0441\u043d\u043e\u0432\u0435\u043d \u0442\u0440\u0430\u043a\u0435\u0440
+Column.seedspeers.started=%1 \u043e\u0442 %2
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430: %2 \u0430\u043a\u0442\u0438\u0432\u043d\u0438
+library.incomplete.header.p=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441\u0435 \u0441\u0432\u0430\u043b\u044f\u0442, %2 \u0447\u0430\u043a\u0430\u0442 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+library.unopened.header.p=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430
+library.all.header=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430: %2 \u0430\u043a\u0442\u0438\u0432\u043d\u043e
+library.incomplete.header=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441\u0435 \u0441\u0432\u0430\u043b\u044f, %2 \u0447\u0430\u043a\u0430 \u0437\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435
+library.unopened.header=%1 \u043e\u0442 \u0441\u043f\u0438\u0441\u044a\u043a\u0430
+ConfigView.section.style.status.show_rategraphs=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u0438\u0441\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043d\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f\u0442\u0430 \u043a\u0430\u0442\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043f\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435/\u043a\u0430\u0447\u0432\u0430\u043d\u0435
+device.error.mountrequired="%1" \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043c\u043e\u043d\u0442\u0438\u0440\u0430\u043d\u0435 \u0432\u044a\u0440\u0445\u0443 \u043c\u0435\u0441\u0442\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+v3.deviceview.infobar.line2.android=\u0414\u0430 \u0441\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u0430\u043d\u0435 \u043f\u0440\u0435\u0437 USB \u043e\u0442 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0442\u0440\u0430\u043d\u0441\u0444\u0435\u0440 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u0444\u0430\u0439\u043b\u043e\u0432\u0435.
+MyTorrents.column.ColumnProgressETA.compon=\u0417\u0430\u0432\u044a\u0440\u0448\u0435\u043d \u043d\u0430 %1
+Sidebar.beta.title=\u0411\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430
+MainWindow.menu.beta.on=\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u0432 \u0431\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430\u2026
+MainWindow.menu.beta.off=\u0418\u0437\u043b\u0438\u0437\u0430\u043d\u0435 \u043e\u0442 \u0431\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430\u2026
+Button.sendNow=\u0418\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435 \u0441\u0435\u0433\u0430
+Button.sendManual=\u0420\u044a\u0447\u043d\u043e \u0438\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435 (\u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 .zip)
+deletecontent.also.deletetorrent=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u0438 \u043d\u0430 .torrent \u0444\u0430\u0439\u043b
+ConfigView.section.file.deletion.section=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435
+ConfigView.section.file.delete.torrent=\u041f\u043e \u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435 \u0434\u0430 \u0441\u0435 \u0442\u0440\u0438\u0435 .torrent \u0444\u0430\u0439\u043b\u044a\u0442 \u043f\u0440\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435
+ConfigView.section.file.delete.confirm=\u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0437\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u0447\u0440\u0435\u0437 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0438 \u0431\u0443\u0442\u043e\u043d\u0430 \u0437\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0 [...]
+MainWindow.menu.view.beta=\u0411\u0435\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430
+ConfigView.section.server.enableudpprobe=\u0421 UDP \u0442\u0440\u0430\u043a\u0435\u0440\u0441\u043a\u0430 \u043f\u0440\u043e\u0431\u0430 \u0437\u0430 HTTP \u0442\u0440\u0430\u043a\u0435\u0440\u0438
+memmon.low.warning=\u0421\u0432\u044a\u0440\u0448\u0432\u0430 \u043f\u0430\u043c\u0435\u0442\u0442\u0430, \u043e\u0441\u0442\u0430\u0432\u0430\u0442 %1 \u043e\u0442 %2.\n\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044f\u043d\u0435\u0442\u043e \u0449\u0435 \u0441\u0435 \u0432\u043b\u043e\u0448\u0438 \u0438 \u043d\u0430\u043a\u0440\u0430\u044f Vuze \u0449\u0435 \u0441\u043f\u0440\u0435 \u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0438\n\u0414\u0430 \u0441\u0435 \u0432\u0438\u0434\u04 [...]
+jvm.max.mem.current=\u0422\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u043c\u0430\u043a\u0441. \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0430 \u043f\u0430\u043c\u0435\u0442 \u0435 %1
+jvm.max.direct.mem=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u0430 \u043f\u0430\u043c\u0435\u0442 [\u043f\u0440\u0430\u0437\u043d\u043e=\u043f\u043e-\u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043d\u0435,\u043c\u0438\u043d.=%1]
+jvm.max.direct.mem.info=\u0412\u0430\u0436\u043d\u043e: \u0442\u0443\u043a \u0441\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430 *\u0434\u0438\u0440\u0435\u043a\u0442\u043d\u0430* \u043f\u0430\u043c\u0435\u0442, \u043d\u043e \u043f\u043e-\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0430 \u0435 \u043d\u0443\u0436\u0434\u0430\u0442\u0430 \u043e\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 *\u0438\u0437\u043f\u044a\u043b\u043 [...]
+jvm.options.summary=\u041e\u0431\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0442\u0435 \u0438\u0437\u0440\u0438\u0447\u043d\u0438 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:
+memmon.heap.auto.increase.warning=\u0418\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0430\u0442\u0430 \u043f\u0430\u043c\u0435\u0442 \u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0430 \u043d\u0430 %1. \u0429\u0435 \u0432\u043b\u0435\u0437\u0435 \u0432 \u0441\u0438\u043b\u0430 \u0441\u043b\u0435\u0434 \u0440\u0435\u0441\u0442\u0430\u0440\u0442 \u043d\u0430 Vuze.
+device.showGeneric=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+mdi.entry.games=\u0418\u0433\u0440\u0438
+Peers.column.Protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b
+devices.copying=\u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u0432 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.cancel_xcode=\u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0432\u0430\u043d\u0435\u0442\u043e
+sidebar.header.transfers=\u0422\u0440\u0430\u043d\u0441\u0444\u0435\u0440\u0438
+sidebar.header.devices=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+sidebar.header.subscriptions=\u0410\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
+sidebar.header.plugins=\u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0438 \u0434\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u044f
+mdi.entry.about.devices=\u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0437 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+mdi.entry.about.plugins=\u0417\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438\u0442\u0435
+mdi.entry.about.dvdburn=\u0417\u0430\u043f\u043e\u0447\u0432\u0430\u043d\u0435
+ConfigView.section.file.tb.delete=\u041f\u0440\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u0441 \u0431\u0443\u0442\u043e\u043d "\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435" \u043e\u0442 \u043b\u0435\u043d\u0442\u0430\u0442\u0430 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438:
+ConfigView.tb.delete.ask=\u041f\u0438\u0442\u0430\u043d\u0435
+ConfigView.tb.delete.content=\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u0431\u0435\u0437 \u043f\u0438\u0442\u0430\u043d\u0435
+ConfigView.tb.delete.torrent=\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 \u043e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0442\u0430
+search.export.all=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u043d\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0442\u0435 \u0437\u0430 \u0442\u044a\u0440\u0441\u0435\u043d\u0435\u2026
+subscriptions.search.enable=\u0421 \u0442\u044a\u0440\u0441\u0435\u043d\u0435 \u0432 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438 \u043e\u0442 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438 (\u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+devices.cancel_xcode_del=\u041e\u0442\u043a\u0430\u0437 \u043e\u0442 \u043f\u0440\u0435\u0432\u0440\u044a\u0449\u0430\u043d\u0435/\u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435
+subscriptions.add.tooltip=\u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442
+subscriptions.overview=\u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438
+configureWizard.nat.title=NAT/\u0441\u044a\u0440\u0432\u044a\u0440\u0435\u043d \u043f\u043e\u0440\u0442
+configureWizard.nat.message=\u0417\u0430 \u043d\u0430\u0439-\u0434\u043e\u0431\u0440\u0438 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0438 \u043e\u0442 Vuze, \u0441\u0435 \u043f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0432\u0430 \u0434\u0430 \u0438\u043c\u0430 \u043f\u044a\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430\u0442\u0430 \u043e\u0442 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442. \u0422\u043e\u04 [...]
+configureWizard.nat.server.udp_listen_port=\u0412\u0445\u043e\u0434\u044f\u0449 UDP \u043f\u043e\u0440\u0442 \u0437\u0430 \u0441\u043b\u0443\u0448\u0430\u043d\u0435
+v3.menu.device.defaultprofile.never=\u041d\u0438\u043a\u043e\u0433\u0430 \u0434\u0430 \u043d\u0435 \u0441\u0435 \u043f\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0430
+subscriptions.info.avail=\u041d\u0435 \u0441\u0430 \u0434\u043e\u0431\u0430\u0432\u0435\u043d\u0438 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438 \u0432\u0441\u0435 \u043e\u0449\u0435. \u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u0441\u0430 %1 \u0437\u0430 \u043c\u0435\u0441\u0442\u043d\u0430\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430.
+subscriptions.dl_subs.enable=\u0421\u0432\u0430\u043b\u044f\u043d\u0435 \u043d\u0430 \u0430\u0431\u043e\u043d\u0430\u043c\u0435\u043d\u0442\u0438 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0438 \u043f\u0440\u0438 \u043d\u0443\u0436\u0434\u0430
+# Will be used for {library.name} in classic view
+library.name._classic=\u041c\u0435\u0441\u0442\u043d\u0438 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=\u041c\u0435\u0441\u0442\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+ConfigView.section.style.units=\u0421 \u043c\u0435\u0440\u043d\u0438 \u0435\u0434\u0438\u043d\u0438\u0446\u0438
+ConfigView.section.style.CatInSidebar=\u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0430\u0442\u0430 \u043b\u0435\u043d\u0442\u0430
+library.category.header=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f '%1'
+device.import.title=\u0418\u043c\u043f\u043e\u0440\u0442 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e?
+device.import.desc=\u0414\u0430 \u0441\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u0438 \u043b\u0438 \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e '%1'?
+device.import.dup.title=\u0414\u0443\u0431\u043b\u0438\u0440\u0430\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.import.dup.desc=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e '%1' \u0432\u0435\u0447\u0435 \u043f\u0440\u0438\u0441\u044a\u0441\u0442\u0432\u0430.
+stream.analysing.media=\u0410\u043d\u0430\u043b\u0438\u0437 \u043d\u0430 \u043d\u043e\u0441\u0438\u0442\u0435\u043b
+device.export.select.template.file=\u0415\u043a\u0441\u043f\u043e\u0440\u0442 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+dlg.stream.plus.subtext=\u041c\u043e\u0436\u0435 \u0434\u0430 \u043d\u0435 \u0441\u0435 \u0447\u0430\u043a\u0430 \u0441\u0432\u0430\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u0446\u044f\u043b\u043e\u0442\u043e \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0435\u0434\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435.\n\u041c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438 \u0438 \u043f\u043e-\u0441\u043a\u043e\u0440\u043e \u04 [...]
+dlg.stream.plus.text=\u0421\u043b\u0435\u0434 \u043d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0434\u043e Vuze \u041f\u043b\u044e\u0441 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0432\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u0430\u0442\u043e \u0441\u0435 \u0441\u0432\u0430\u043b\u044f.
+dlg.stream.plus.title=\u041d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435
+dlg.stream.plus.subtitle=\u041d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435
+Button.upgrade=\u041d\u0430\u0434\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435
+stream.analysing.media.preview=\u0410\u043d\u0430\u043b\u0438\u0437 \u043d\u0430 \u043d\u043e\u0441\u0438\u0442\u0435\u043b (\u043e\u043d\u0430\u0433\u043b\u0435\u0434\u044f\u0432\u0430\u043d\u0435)
diff --git a/org/gudy/azureus2/internat/MessagesBundle_bs_BA.properties b/org/gudy/azureus2/internat/MessagesBundle_bs_BA.properties
index c85f421..651c8aa 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_bs_BA.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_bs_BA.properties
@@ -26,10 +26,7 @@ ConfigView.section.language=Jezik
 MainWindow.menu.help=Pomoc
 MainWindow.menu.help.about=O Vuze
 MainWindow.about.title=O
-MainWindow.about.section.developers=Programeri
-MainWindow.about.section.translators=Prevodioci
 MainWindow.about.internet.sourceforge=Sourceforge Project Stranica
-MainWindow.about.internet.sourceforgedownloads=Download sa Sourceforge
 MainWindow.about.internet.bugreports=Posalji Bug
 MainWindow.about.internet.forumdiscussion=Forum
 MainWindow.about.internet.wiki=Wiki FAQ Vuze
@@ -278,8 +275,6 @@ IrcView.help=Dostupne komande :\n . /help : pokazi ovu poruku\n . /nick | /name
 PasswordWindow.title=Vuze je zakljucan
 PasswordWindow.passwordprotected=Vuze je zasticen sa sifrom.\nUnesi sifru :
 Button.ok=Ok 
-TrackerChangerWindow.title=Dodaj tracker
-TrackerChangerWindow.newtracker=Unesite novi URL trackera
 PeersView.discarded=Odbacen
 PeersView.discarded.info=Podatci koji su primljeni ali ne trebaju, tako da su izbrisani.
 discarded=Odbijeno
@@ -351,7 +346,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Izbrisi .torrent
 MyTorrentsView.menu.removeand.deletedata=Izbrisi podatke
 MyTorrentsView.menu.removeand.deleteboth=Sve izbrisi
 deletedata.title=!!! Paznja !!!
-deletedata.message1=Brisete PODATKE od :\n
 MainWindow.menu.file.configure=Pomocnik konfiguracije
 configureWizard.title=Pomocnik Konfiguracije
 configureWizard.welcome.title=Dobrodosli na Pomocnicku Konfiguraciju Azureus-a
@@ -373,7 +367,6 @@ configureWizard.transfer.maxActiveTorrents=Max Aktivni
 configureWizard.transfer.maxDownloads=Max brzina download-a
 configureWizard.transfer.maxUploadsPerTorrent=Max brzina Upload-a po Torrent-u
 configureWizard.nat.title=NAT / Port od Servera
-configureWizard.nat.message=Za optimalnu upotrebu BitTorrent-a, morate biti totalno dostupni Internet-u. BitTorrent upotrebljava standardni port 6881-6889. Ovo omogucava probu ili promijenu tih portova. Ako imate preuzimanje u toku neki portovi nece moci da se probaju.
 configureWizard.nat.test=Proba
 configureWizard.nat.testing=Proba port-a
 configureWizard.nat.ok=Ok
@@ -682,8 +675,6 @@ plugin.sharing.download.remove.veto=Preuzimanje je razdvojeno. Ako se zaustavi t
 ConfigView.section.tracker.main=Glavno
 ConfigView.label.prioritizefirstpiece=Prioritet za prva parcica fajla
 ConfigView.label.prioritizefirstpiece.tooltip=Proba da preuzima prvo pocetak fajla.\nMoze da omoguci pregled fajla.
-ConfigView.section.file.confirm_data_delete=Potrvdi pre brisanja podataka
-ConfigView.section.file.confirm_data_delete.tooltip=Potvrdi kada je korisceno "Skini i izbrisi..."
 TrayWindow.menu.startalldownloads=Start sva preuzimanja
 sharing.progress.title=Napredak dijeljenja
 sharing.progress.hide=Sakri
@@ -979,7 +970,6 @@ ConfigView.pluginlist.whereToPut=Stavi bilo koji dodatak u njihov folder ispod:
 ConfigView.pluginlist.whereToPutOr=Za podijeljenje dodatka upotrebi:
 MainWindow.statusText.checking=Provijeri za Updates
 TableColumn.header.OnlyCDing4.info=Koliko puta je torrent samo deljen. Izkljuceno kada je preuzimat (i deljen).
-ConfigView.section.style.alternateTablePainting=Upotrebi drugu metodu za farbanje grafike (restart potreban)
 UpdateWindow.status.restartMaybeNeeded=Potrebno ponovo pokretanje
 ConfigView.pluginlist.shared=dijeljeno
 PeersView.host=Host Ime
@@ -1146,8 +1136,6 @@ ConfigView.label.openstatsonstart=Otvori Statistiku pri startu
 installPluginsWizard.details.loading=Opis se puni, molimo vas pricekajte...
 Button.abort=prekinuti
 MainWindow.dialog.restartconfirmation.text=Dali zelite da restart Vuze
-deletetorrent.message1=Brisete TORRENT od :\n
-deletetorrent.message2=\nJeste sigurni da zelite nastavi?
 ConfigView.label.prioritizemostcompletedfiles=Prioritize most completed files
 ConfigView.section.style.osx_small_fonts=Upotreba mali slova [restartovanje programa potrebno]
 ConfigView.group.scrape=scrape
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ca_AD.properties b/org/gudy/azureus2/internat/MessagesBundle_ca_AD.properties
index 5773cee..157c706 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ca_AD.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ca_AD.properties
@@ -1,137 +1,154 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
 MainWindow.menu.file.open.torrent=Fitxer .torrent
-Main.parameter.usage=\u00das : java org.gudy.azureus2.cl.Main [par\u00e0metres] "fitxer.torrent" "ruta desc\u00e0rrega"
+MainWindow.menu.file.open.torrent.keybinding=Meta+O 
+Main.parameter.usage=\u00das : java org.gudy.azureus2.cl.Main [par\u00e0metres] "fitxer.torrent" "desa el cam\u00ed"
 Main.parameter.maxUploads=Nombre m\u00e0xim de desc\u00e0rregues simult\u00e0nies
 Main.parameter.maxSpeed=Velocitat m\u00e0xima de c\u00e0rrega en bytes/seg
 MainWindow.menu.file=&Fitxer
-MainWindow.menu.file.open=Obrir
-MainWindow.menu.file.create=Crear un .torrent
+MainWindow.menu.file.open=Obre
+MainWindow.menu.file.create=Crea un torrent &nou...
+MainWindow.menu.file.create.keybinding=Meta+N 
 MainWindow.menu.file.create.fromfile=Des d'un fitxer
 MainWindow.menu.file.create.fromdir=&Des d'una carpeta
-MainWindow.menu.file.export=Exportar un .torrent...
+MainWindow.menu.file.export=Exporta un torrent XML...
+MainWindow.menu.file.export.keybinding=Meta+E 
 MainWindow.menu.file.export.keybinding.mac=Meta+Maj+E
-MainWindow.menu.file.import=Importar un .torrent...
+MainWindow.menu.file.import=Importa un torrent XML...
+MainWindow.menu.file.import.keybinding=Meta+I 
 MainWindow.menu.file.import.keybinding.mac=Meta+Maj+I
-MainWindow.menu.file.closetab=Tancar E&tiqueta
+MainWindow.menu.file.closetab=Tanca l'e&tiqueta
 MainWindow.menu.file.closetab.keybinding=Meta+T
-MainWindow.menu.file.closewindow=Tancar &Finestra
+MainWindow.menu.file.closewindow=Tanca la &finestra
 MainWindow.menu.file.closewindow.keybinding=Meta+Shift+F
-MainWindow.menu.file.exit=Sortir
-MainWindow.dialog.choose.file=Seleccioneu el fitxer .torrent
+MainWindow.menu.file.exit=Surt
+MainWindow.menu.file.exit.keybinding=Alt+F4 
+MainWindow.dialog.choose.file=Seleccioneu el fitxer torrent
 MainWindow.menu.file.folder=&Carpeta
 MainWindow.menu.file.folder.keybinding=Meta+Shift+C
-MainWindow.dialog.choose.folder=Seleccioni la carpeta
+MainWindow.dialog.choose.folder=Seleccioneu la carpeta
 MainWindow.menu.view=&Visualitzaci\u00f3
-MainWindow.menu.view.show=Mostrar
-MainWindow.menu.view.mytorrents=Els meus Torrents
+MainWindow.menu.view.show=Mostra
+MainWindow.menu.view.mytorrents=Biblioteca
+MainWindow.menu.view.mytorrents.keybinding=Meta+1 
 MainWindow.menu.view.open_global_transfer_bar=Barra de transfer\u00e8ncies
-MainWindow.menu.view.configuration=Configuraci\u00f3
-MainWindow.menu.view.console=C\u00f2nsola
-MainWindow.menu.view.irc=Client IRC
+MainWindow.menu.view.configuration=&Opcions...
+MainWindow.menu.view.configuration.keybinding=Meta+, 
+MainWindow.menu.view.console=Cons&ola
+MainWindow.menu.view.console.keybinding=Meta+4 
+MainWindow.menu.view.irc=Client &IRC
 MainWindow.menu.view.allpeers=Tots els iguals
 MainWindow.menu.view.detailedlist=Llista &detallada
-MainWindow.menu.closealldetails=Tancar tots els detalls
-MainWindow.menu.closealldownloadbars=Tancar les barres de desc\u00e0rrega
-MainWindow.menu.language=Idioma
-ConfigView.section.language=Idioma
+MainWindow.menu.closealldetails=Tanca tots els detalls
+MainWindow.menu.closealldownloadbars=Tanca les barres de desc\u00e0rrega
+MainWindow.menu.language=&Llengua
+ConfigView.section.language=Llengua
 MainWindow.menu.window=&Finestra
-MainWindow.menu.window.minimize=&Minimitzar
-MainWindow.menu.window.alltofront=Porta-ho tot a &Davant
+MainWindow.menu.window.minimize=&Minimitza
+MainWindow.menu.window.minimize.keybinding=Meta+M 
+MainWindow.menu.window.zoom=&Zoom 
+MainWindow.menu.window.alltofront=Porta-ho tot al davant
 MainWindow.menu.help=Ajuda
-MainWindow.menu.help.about=Sobre Vuze
-MainWindow.about.title=Sobre
-MainWindow.about.section.developers=Desenvolupadors
-MainWindow.about.section.translators=Traductors
+MainWindow.menu.help.about=Quant al Vuze
+MainWindow.menu.torrent=T&orrent 
+MainWindow.about.title=Quant al Vuze
 MainWindow.about.section.system=Sistema
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.homepage=P\u00e0gina de Vuze
 MainWindow.about.internet.sourceforge=P\u00e0gina del projecte en Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Desc\u00e0rregues des de Sourceforge
 MainWindow.about.internet.bugreports=Informe de fallades
-MainWindow.about.internet.forumdiscussion=F\u00f2rum General
+MainWindow.about.internet.forumdiscussion=F\u00f2rum general
 MainWindow.about.internet.wiki=Preguntes m\u00e9s freq\u00fcents al Wiki del Vuze
-MainWindow.dialog.choose.savepath=Seleccioni la carpeta per a la desc\u00e0rrega
+MainWindow.dialog.choose.savepath=Seleccioneu la carpeta per a la desc\u00e0rrega
 MainWindow.dialog.choose.savepath_forallfiles=Seleccioneu la carpeta per a tots els fitxers
-MainWindow.status.latestversion=Ultima versi\u00f3
-MainWindow.status.latestversion.clickupdate=Clic per a actualitzar
+MainWindow.status.latestversion=Darrera versi\u00f3
+MainWindow.status.latestversion.clickupdate=Feu clic per actualitzar
 MainWindow.status.unknown=Desconegut
 MainWindow.status.checking=Comprovant
-MyTorrentsView.mytorrents=Els meus Torrents
+MyTorrentsView.mytorrents=Biblioteca
 TableColumn.header.name=Nom
 TableColumn.header.size=Mida
 TableColumn.header.done=Completat
 TableColumn.header.done.info=Percentatge fet de la feina actual
 TableColumn.header.status=Estat
-TableColumn.header.status.info=Lo que est\u00e0 fent el torrent
+TableColumn.header.status.info=Qu\u00e8 est\u00e0 fent el torrent
 TableColumn.header.seeds=Llavors
-TableColumn.header.seeds.info=# llavors connectades a (# llavors total)
+TableColumn.header.seeds.info=Nre. de llavors connectades a (nre. de llavors total)
 TableColumn.header.peers=Iguals
-TableColumn.header.peers.info=# Iguals connectats a (# Iguals total)
+TableColumn.header.peers.info=Nre. d'guals connectats a (nre. total d'iguals)
+TableColumn.header.completed=Completat
+TableColumn.header.completed.info=Nre. de parells que han finalitzat la desc\u00e0rrega del torrent segons la informaci\u00f3 del rastrejador
 TableColumn.header.downspeed=Vel. desc\u00e0rrega
-TableColumn.header.upspeed=Vel. c\u00e0rrega
-TableColumn.header.eta=Estimaci\u00f3 Temps Acabar
-TableColumn.header.tracker=Estat Rastrejador
+TableColumn.header.upspeed=Velocitat de c\u00e0rrega
+TableColumn.header.eta=Temps estimat de compleci\u00f3
+TableColumn.header.tracker=Estat del rastrejador
 TableColumn.header.tracker.info=Estat del rastrejador
-TableColumn.header.trackernextaccess=Acc\u00e9s al seg\u00fcent rastrejador
-TableColumn.header.trackernextaccess.info=Quan farem el seg\u00fcent acces al rastrejador
+TableColumn.header.trackernextaccess=Acc\u00e9s al rastrejador seg\u00fcent
+TableColumn.header.trackernextaccess.info=Quan es faci el proper acc\u00e9s al rastrejador
 TableColumn.header.priority=Prioritat
 TableColumn.header.priority.info=Determina quanta amplada de banda de desc\u00e0rrega cal donar al torrent
-MyTorrentsView.menu.showdetails=Mostrar &Detalls
-MyTorrentsView.menu.showdownloadbar=Mostrar &Barra de desc\u00e0rrega
-MyTorrentsView.menu.open=&Obrir
-MyTorrentsView.menu.setpriority=Establir &Prioritat
+MyTorrentsView.menu.showdetails=Mostra els &detalls
+MyTorrentsView.menu.showdownloadbar=Mostra la &barra de desc\u00e0rrega
+MyTorrentsView.menu.open=&Obre
+MyTorrentsView.menu.setpriority=Estableix la &prioritat
 MyTorrentsView.menu.setpriority.high=&Alta
 MyTorrentsView.menu.setpriority.low=&Baixa
-MyTorrentsView.menu.start=&Iniciar
-MyTorrentsView.menu.stop=A&turar
-MyTorrentsView.menu.remove=T&reure
-MyTorrentsView.menu.changeTracker=&Afegir URL de rastrejador
-TrayWindow.menu.exit=Sortir
-TrayWindow.menu.show=Mostrar Azureu&s
-SystemTray.menu.exit=&Sortir
-SystemTray.menu.closealldownloadbars=Tancar barres de desc\u00e0rrega
-SystemTray.menu.show=&Mostrar Vuze
-PeersView.ip.info=IP de l'Igual
+MyTorrentsView.menu.start=&Inicia
+MyTorrentsView.menu.stop=A&tura
+MyTorrentsView.menu.remove=Elimina
+MyTorrentsView.menu.changeTracker=&Afegeix una URL de rastrejador
+TrayWindow.menu.exit=Surt
+TrayWindow.menu.show=Mostra el Vuze
+SystemTray.menu.exit=Surt
+SystemTray.menu.closealldownloadbars=Tanca les barres de desc\u00e0rrega
+SystemTray.menu.open_global_transfer_bar=Mostra la barra de transfer\u00e8ncies
+SystemTray.menu.show=&Mostra el Vuze
+PeersView.ip=Adre\u00e7a IP
+PeersView.ip.info=Adre\u00e7a IP de l'igual
+PeersView.port=Port 
 PeersView.port.info=Port que fa servir
 PeersView.T.info=L (local): heu establert la connexi\u00f3, R (remot): l'igual ha establert la connexi\u00f3.
-PeersView.I1=I
+PeersView.T.L.tooltip=Heu establert la connexi\u00f3
+PeersView.T.R.tooltip=L'igual ha establert la connexi\u00f3
+PeersView.I1=I (interessant per l'igual)
 PeersView.I1.info=Esteu interessat en el que t\u00e9 l'altre igual?
 PeersView.C1=C
 PeersView.C1.info=Quan l'igual us est\u00e0 bloquejant per descarregar
 PeersView.pieces=Peces
-PeersView.downloadspeed=Vel. desc\u00e0rrega
+PeersView.%=% 
+PeersView.downloadspeed=Velocitat de desc\u00e0rrega
 PeersView.download=Rebut
-PeersView.I2=I
+PeersView.I2=I (interessant per a l'igual)
 PeersView.I2.info=L'igual est\u00e0 interessat en el que vosaltres teniu?
 PeersView.C2=C
 PeersView.C2.info=Quan esteu bloquejant l'igual per descarregar
-PeersView.uploadspeed=Vel. c\u00e0rrega
+PeersView.uploadspeed=Velocitat de c\u00e0rrega
 PeersView.uploadspeed.info=La vostra velocitat de c\u00e0rrega respecte de l'igual
-PeersView.upload=Pujat
+PeersView.upload=Carregat
 PeersView.upload.info=La vostra c\u00e0rrega global cap a l'igual.
 PeersView.statup=C\u00e0rrega mitjana
 PeersView.statup.info=Un valor estimat de la velocitat de c\u00e0rrega de l'igual
 PeersView.S.info=Desanimat: Un Igual pot ser "desanimat" manualment, o autom\u00e0ticament (perqu\u00e8 no distribueix dades a prou velocitat)
 PeersView.downloadspeedoverall=Desc\u00e0rrega mitjana
 PeersView.optunchoke=Prefer\u00e8ncia
-PeersView.client.info=Tipus de client BT que fa servir l'Igual
+PeersView.client=Client 
+PeersView.client.info=Tipus de client BT que fa servir l'igual
 PeersView.menu.snubbed=De&sanimat
 PeersView.title.short=Detalls
 PeersView.title.full=Detalls
 AllPeersView.title.full=Tots iguals
 ConfigView.section.files=Fitxers
-ConfigView.label.usefastresume=Usar la manera de resumir r\u00e0pidament
+ConfigView.label.usefastresume=Fes servir el mode de reprendre r\u00e0pidament
 ConfigView.label.incrementalfile=Activa la creaci\u00f3 incremental de fitxers [Requerit per FAT32 sota Linux]
-ConfigView.label.defaultsavepath=Ruta de desc\u00e0rrega per defecte
-ConfigView.button.browse=Examinar...
-ConfigView.dialog.choosedefaultsavepath=Seleccioni la carpeta per a les desc\u00e0rregues
-ConfigView.section.server=Servidor
+ConfigView.label.defaultsavepath=Desa a la carpeta de dades per defecte
+ConfigView.button.browse=Explora...
+ConfigView.dialog.choosedefaultsavepath=Seleccioneu la carpeta per a les desc\u00e0rregues
+ConfigView.section.server=Connexi\u00f3
 ConfigView.section.global=Global
-ConfigView.label.disconnetseed=Desconnectar llavors al compartir
-ConfigView.label.switchpriority=Establir prioritat baixa autom\u00e0ticament al servir
+ConfigView.label.disconnetseed=Desconnecta les llavors en compartir
+ConfigView.label.switchpriority=Estableix la prioritat baixa autom\u00e0ticament quan sembris
 ConfigView.label.maxdownloads=Desc\u00e0rregues m\u00e0ximes simult\u00e0nies
-ConfigView.label.maxdownloads.tooltip=Sempre podreu tenir actius descarregant el nombre que poseu aqu\u00ed amb una sola excepci\u00f3,\nun torrent completat que tingui primera prioritat pot posar-se davant d'un canal de desc\u00e0rrega actiu si \u00e9s absolutament necessari.
-ConfigView.label.maxactivetorrents=Torrents m\u00e0xims actius (0 : il\u00edmitat)\nEls nous torrents no s'iniciaran si est\u00e0 descarregant/servint m\u00e9s de
+ConfigView.label.maxdownloads.tooltip=Sempre podreu tenir actius descarregant el nombre que introdu\u00efu amb una sola excepci\u00f3,\nun torrent completat que tingui prioritat m\u00e0xima es pot posar al davant d'un canal de desc\u00e0rrega actiu si \u00e9s absolutament necessari.
+ConfigView.label.maxactivetorrents=Torrents m\u00e0xims actius (0 : il\u00b7limitat)\nEls nous torrents no s'iniciaran si n'esteu descarregant/sembrant m\u00e9s
 ConfigView.label.priorityExtensions=Canvia autom\u00e0ticament a alta prioritat fitxers d'extensi\u00f3\n (ex: .txt;.nfo;.jpg)
 ConfigView.section.transfer=Transfer\u00e8ncia
 ConfigView.label.maxuploads=C\u00e0rregues m\u00e0ximes per torrent
@@ -139,42 +156,44 @@ ConfigView.label.maxuploadspeed=Velocitat m\u00e0xima de c\u00e0rrega (global)
 ConfigView.label.saveresumeinterval=Desa'n una c\u00f2pia autom\u00e0ticament cada
 ConfigView.unlimited=Sense l\u00edmit
 ConfigView.section.display=Visualitzaci\u00f3
-ConfigView.label.opendetails=Obrir autom\u00e0ticament la barra de detalls
-ConfigView.label.openbar=Obrir autom\u00e0ticament la barra de desc\u00e0rrega
-ConfigView.label.closetotray=Posar icona en safata al tancar
-ConfigView.label.minimizetotray=Posar icona en safata al minimitzar
+ConfigView.label.opendetails=Obre autom\u00e0ticament la barra de detalls
+ConfigView.label.openbar=Obre autom\u00e0ticament la barra de desc\u00e0rrega
+ConfigView.label.use_old_speed_menus=Fes servir l'estil antic dels men\u00fas de velocitat [cal reiniciar]
+ConfigView.label.closetotray=Posa la icona a la safata del sistema quan tanquis
+ConfigView.label.minimizetotray=Posa la icona a la safata quan minimitzis
 ConfigView.section.general=General 
-ConfigView.section.start=Comen\u00e7ar
-ConfigView.label.showsplash=Mostrar pantalla emergent a l'inici
-ConfigView.label.autoupdate=Obrir el di\u00e0leg d'actualitzacions per a veure si n'hi ha alguna disponible
-ConfigView.label.openconsole=Obrir la c\u00f2nsola en l'inici
-ConfigView.label.openconfig=Obrir la configuraci\u00f3 en l'inici
-ConfigView.label.startminimized=Comen\u00e7ar minimitzat
-ConfigView.section.irc=Client Irc
-ConfigView.label.ircwiki=Si us plau llegiu http://www.azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.section.start=Comen\u00e7a
+ConfigView.label.showsplash=Mostra la pantalla emergent a l'inici
+ConfigView.label.autoupdate=Obre el di\u00e0leg d'actualitzacions per veure si n'hi ha alguna de disponible
+ConfigView.label.openconsole=Obre la consola a l'inici
+ConfigView.label.openconfig=Obre la configuraci\u00f3 a l'inici
+ConfigView.label.startminimized=Comen\u00e7a minimitzat
+ConfigView.section.irc=Client IRC
+ConfigView.label.ircwiki=Llegiu http://wiki.vuze.com/w/Rules_for_IRC
 ConfigView.label.ircserver=Servidor
 ConfigView.label.ircchannel=Sala
 ConfigView.label.irclogin=\u00c0lies
 ConfigView.group.irctitle=Configuraci\u00f3 IRC
-ConfigView.boolean.ircsendinfo=Perm\u00eds per transmtre (an\u00f2nimament) la vostra configuraci\u00f3 als\n operadors del canal per tal que us puguin ajudar
+ConfigView.boolean.ircsendinfo=Permet que es transmeti (an\u00f2nimament) la configuraci\u00f3 que teniu als\n operadors del canal per tal que us puguin ajudar
 ConfigView.boolean.irclog=Habilita el registre de l'activitat del canal (a IRC_log.htm)
 ConfigView.section.security=Seguretat
-ConfigView.label.password=Protegir Vuze usant contrassenya\nAl restaurar Vuze se't preguntar\u00e0 la contrassenya
-ConfigView.label.passwordconfirm=Contrassenya (confirmar)
-ConfigView.label.passwordmatch=Contrassenya activada :
+ConfigView.label.password=Protegeix el Vuze amb una contrasenya\nQuan restaureu el Vuze se us preguntar\u00e0 la contrasenya
+ConfigView.label.passwordconfirm=Contrasenya (confirma-la)
+ConfigView.label.passwordmatch=Contrasenya activada:
 ConfigView.label.passwordmatchnone=No 
-ConfigView.label.passwordmatchno=No / Les contrassenyes no concorden
-ConfigView.label.passwordmatchyes=Si
+ConfigView.label.passwordmatchno=No / Les contrasenyes no coincideixen
+ConfigView.label.passwordmatchyes=S\u00ed
 ConfigView.button.save=Desa
-ConfigView.title.short=Config.
-ConfigView.title.full=Configuraci\u00f3
-ConsoleView.title.short=C\u00f2nsola
-ConsoleView.title.full=C\u00f2nsola
+ConfigView.title.short=Opcions
+ConfigView.title.full=Opcions
+ConfigView.title.full._mac=Prefer\u00e8ncies
+ConsoleView.title.short=Consola
+ConsoleView.title.full=Consola
 FileItem.write=Escriptura
 FileItem.read=Lectura
-FileItem.normal=Normal
+FileItem.normal=Normal 
 FileItem.high=Alta
-FileItem.donotdownload=No descarregar
+FileItem.donotdownload=No el descarreguis
 FileItem.delete=Esborra
 FilesView.name=Nom
 FilesView.name.fastRename=Reanomenada r\u00e0pida
@@ -182,55 +201,58 @@ FilesView.size=Mida
 FilesView.done=Completat
 FilesView.%=% 
 FilesView.firstpiece=# primera pe\u00e7a
-FilesView.numberofpieces=# de peces
+FilesView.numberofpieces=Nre. de peces
 FilesView.pieces=Peces
 FilesView.mode=Manera
 FilesView.priority=Prioritat
-FilesView.menu.open=Obrir
+FilesView.menu.open=Obre
 FilesView.menu.setpriority=Establir prioritat
 FilesView.menu.setpriority.high=Alta
 FilesView.menu.setpriority.normal=Normal
-FilesView.menu.setpriority.skipped=No descarregar
+FilesView.menu.setpriority.skipped=No el &descarreguis
 FilesView.title.short=Fitxers
-FilesView.title.full=Ftixers
+FilesView.title.full=Fitxers
 GeneralView.section.downloaded=Descarregat
 GeneralView.label.status.file=Estat del fitxer
-GeneralView.label.status.pieces=Estat peces
+GeneralView.label.status.pieces=Estat de les peces
 GeneralView.section.availability=Disponibilitat
-GeneralView.label.status.pieces_available=Estat Peces
+GeneralView.label.status.pieces_available=Estat de les peces
 GeneralView.section.transfer=Transfer\u00e8ncia
 GeneralView.section.info=Informaci\u00f3
-GeneralView.label.timeelapsed=Temps actiu :
-GeneralView.label.remaining=Restant :
-GeneralView.label.downloaded=Descarregat :
-GeneralView.label.downloadspeed=Vel. desc\u00e0rrega :
-GeneralView.label.maxuploads=C\u00e0rrega m\u00e0xims :
-GeneralView.label.maxuploads.tooltip=M\u00e0xim nombre d'iguals no embussats en un moment donat.
+TorrentInfoView.title.full={GeneralView.section.info} 
+GeneralView.title.short=General 
+GeneralView.title.full=General 
+GeneralView.label.timeelapsed=Temps actiu:
+GeneralView.label.remaining=Restant:
+GeneralView.label.downloaded=Descarregat:
+GeneralView.label.downloadspeed=Vel. desc\u00e0rrega:
+GeneralView.label.maxuploads=C\u00e0rrega m\u00e0xims:
+GeneralView.label.maxuploads.tooltip=Nombre m\u00e0xim d'iguals no embussats en un moment donat.
 GeneralView.label.uploaded=Enviat :
 GeneralView.label.uploadspeed=Vel. c\u00e0rrega:
-GeneralView.label.seeds=Llavors :
-GeneralView.label.peers=Clients :
+GeneralView.label.seeds=Llavors:
+GeneralView.label.peers=Clients:
 GeneralView.label.completed=Completat: 
-GeneralView.label.totalspeed=Velocitat total :
+GeneralView.label.totalspeed=Velocitat de l'eixam:
 GeneralView.label.totalspeed.tooltip=Velocitat total de tots els clients amb els quals esteu connectat.
 GeneralView.label.averagespeed=mitjana
-GeneralView.label.filename=Nom :
-GeneralView.label.totalsize=Mida total :
-GeneralView.label.savein=Desat a:
-GeneralView.label.hash=Hash :
-GeneralView.label.numberofpieces=# de peces :
-GeneralView.label.size=Mida de la pe\u00e7a :
-GeneralView.label.tracker=Rastrejador :
-GeneralView.label.updatein=Actualitzat en :
-GeneralView.label.trackerurl=URL del rastrejador :
-GeneralView.label.trackerurlupdate=Actualizaci\u00f3 manual
-GeneralView.label.comment=Comentaris :
+GeneralView.label.filename=Nom:
+GeneralView.label.totalsize=Mida total:
+GeneralView.label.savein=Ubicaci\u00f3:
+GeneralView.label.hash=Hash:
+GeneralView.label.numberofpieces=Nre. de peces :
+GeneralView.label.size=Mida de la pe\u00e7a:
+GeneralView.label.tracker=Rastrejador:
+GeneralView.label.updatein=Actualitza d'aqu\u00ed a:
+GeneralView.label.trackerurl=URL del rastrejador:
+GeneralView.label.trackerurlupdate=Actualitzaci\u00f3 manual
+GeneralView.label.comment=Comentari del torrent:
 GeneralView.label.user_comment=Comentari de l'usuari: 
 GeneralView.label.status=Estatus:
 ManagerItem.waiting=Esperant
 ManagerItem.allocating=Establint
 ManagerItem.checking=Comprovant
-ManagerItem.ready=Preparat
+ManagerItem.ready=Esperant altres torrents per la la cua
 ManagerItem.downloading=Descarregant
 ManagerItem.seeding=Compartint
 ManagerItem.stopped=Aturat
@@ -239,22 +261,23 @@ ManagerItem.high=Alta
 ManagerItem.low=Baixa
 MinimizedWindow.name=Nom:
 MinimizedWindow.all_transfers=Transfer\u00e8ncies del Vuze
+PiecesView.#=Nre.
 PiecesView.size=Mida
 PiecesView.numberofblocks=# de blocs
 PiecesView.blocks=Blocs
 PiecesView.completed=Completats
 PiecesView.availability=Disponibilitat
 PiecesView.reservedby=Reservat
-PiecesView.writers=Contribuidors de Bloc
+PiecesView.writers=Bloca col\u00b7laboradors
 PiecesView.title.short=Peces
 PiecesView.title.full=Peces
-SystemTray.tooltip.seeding=%1 Sembrant,
+SystemTray.tooltip.seeding=%1 sembrant,
 SystemTray.tooltip.downloading=%1 descarregant,
 DownloadManager.error.filenotfound=No es troba el fitxer
 DownloadManager.error.fileempty=El fitxer .torrent est\u00e0 buit
 DownloadManager.error.filetoobig=El fitxer .torrent \u00e9s molt gran
 DownloadManager.error.filewithouttorrentinfo=No hi ha informaci\u00f3 al fitxer .torrent
-DownloadManager.error.unsupportedencoding=Codificaci\u00f3 no suportada
+DownloadManager.error.unsupportedencoding=Codificaci\u00f3 no possible
 DownloadManager.error.ioerror=Error d'E/S
 DownloadManager.error.sha1=Error d'Algoritme (SHA1)
 PeerManager.status.offline=Desconnectat
@@ -262,25 +285,25 @@ PeerManager.status.ok=Actiu
 PeerManager.status.checking=Comprovant
 PeerManager.status.finished=Completat
 PeerManager.status.finishedin=Completat
-MainWindow.upgrade.assistant=Assistent d'actualitzaci\u00f3
-MainWindow.upgrade.newerversion=Hi ha disponible una nova versi\u00f3 d'Vuze per a descarregar
-MainWindow.upgrade.explanation=Aquest assistent descarregar\u00e0 la nova versi\u00f3 en la carpeta de Vuze i despr\u00e9s reiniciar\u00e0 Vuze
+MainWindow.upgrade.assistant=Auxiliar d'actualitzaci\u00f3
+MainWindow.upgrade.newerversion=Hi ha disponible una nova versi\u00f3 del Vuze per descarregar
+MainWindow.upgrade.explanation=Aquest auxiliar descarregar\u00e0 la nova versi\u00f3 a la carpeta del Vuze i despr\u00e9s el reiniciar\u00e0 
 MainWindow.upgrade.explanation.manual=Podeu fer una actualitzaci\u00f3 manual tancant el Vuze, descarregant la nova versi\u00f3 i reiniciant el programa
-MainWindow.upgrade.step1=Pas 1: Desc\u00e0rrega de la nova versi\u00f3
-MainWindow.upgrade.step2=Pas 2: Tancar aquesta versi\u00f3 per a reiniciar en la nova versi\u00f3 de Vuze
-MainWindow.upgrade.hint1=Truc:\tSi mantens pressionat alguns segons Acabar i despr\u00e9s el deixes anar, el proc\u00e9s ser\u00e0 autom\u00e0tic
-MainWindow.upgrade.hint2=Truc:\tSi voleu tancar el Vuze m\u00e9s endavant, premeu Cancel\u00b7la i\n\trenanomeneu Azureus2-new.jar l'Azureus2.jar despr\u00e9s de tancar
-MainWindow.upgrade.error.downloading.hint=Error:\tImposible descarregar la nova versi\u00f3, si us plau actualitzi manualment
+MainWindow.upgrade.step1=Pas 1: Descarregueu de la nova versi\u00f3
+MainWindow.upgrade.step2=Pas 2: Tanqueu aquesta versi\u00f3 per reiniciar amb la nova versi\u00f3 del Vuze
+MainWindow.upgrade.hint1=Truc:\tSi manteniu pressionat alguns segons Acabar i despr\u00e9s el deixeu anar, el proc\u00e9s ser\u00e0 autom\u00e0tic
+MainWindow.upgrade.hint2=Truc:\tSi voleu tancar el Vuze m\u00e9s endavant, premeu Cancel\u00b7la i\n\tRenanomeneu Azureus2-new.jar l'Azureus2.jar despr\u00e9s de tancar
+MainWindow.upgrade.error.downloading.hint=Error:\t\u00c9s impossible descarregar la versi\u00f3 nova. Actualitzeu-la manualment
 MainWindow.upgrade.section.info=Nova versi\u00f3 disponible
 MainWindow.upgrade.section.manual=Actualitzaci\u00f3  manual
 MainWindow.upgrade.section.automatic=Actualitzaci\u00f3 autom\u00e0tica
 MainWindow.upgrade.tooltip.progressbar=El progr\u00e9s de la desc\u00e0rrega es mostra aqu\u00ed
 Button.next=Seg\u00fcent
 Button.finish=Acaba
-Button.cancel=Cancel\u00b7lar
+Button.cancel=Cancel\u00b7la
 LocaleUtil.title=Trieu la codificaci\u00f3
 LocaleUtil.section.chooseencoding=Trieu la codificaci\u00f3 per al fitxer
-LocaleUtil.label.chooseencoding=Si us plau, seleccioneu la millor codificaci\u00f3 corresponent
+LocaleUtil.label.chooseencoding=Seleccioneu la millor codificaci\u00f3 corresponent
 LocaleUtil.label.hint.doubleclick=Truc: feu doble clic en una fila per triar la codificaci\u00f3 i tancar el quadre de di\u00e0leg
 LocaleUtil.label.checkbox.rememberdecision=Recorda decisions per als fitxers restants
 LocaleUtil.column.encoding=Codificaci\u00f3
@@ -290,50 +313,52 @@ IrcClient.connected=Connectat a
 IrcClient.joining=Unint se a
 IrcClient.channel=Sala
 IrcClient.joined=Unit correctament
+IrcClient.error=Error 
 IrcClient.hasjoined=s'ha unit
 IrcClient.haskicked=ha estat patejat
 IrcClient.hasleft=s'en ha anat
 IrcClient.nowknown=\u00e9s ara conegut com
 IrcClient.topicforchannel=Tema per a la sala
 IrcClient.disconnected=Desconnectat de
-IrcClient.noNick=No tens un \u00e0lies especificat. Si us plau aneu a la pantalla de 'Configuraci\u00f3'
-IrcView.actionnotsupported=Aquesta acci\u00f3 no est\u00e0 suportada
+IrcClient.noNick=No teniu un \u00e0lies especificat. Aneu a la pantalla de 'Configuraci\u00f3'
+IrcView.actionnotsupported=Aquesta acci\u00f3 no \u00e9s possible
 IrcView.clientsconnected=Usuaris
 IrcView.privateto=Per a
 IrcView.privatefrom=De
-IrcView.noticefrom=Av\u00eds :
+IrcView.noticefrom=Av\u00eds:
 IrcView.errormsg=Sintaxi incorrecta en /msg : /msg usuari missatge
-IrcView.help=Els comandos valids s\u00f3n :\n . /help : mostra aquest missatge\n . /nick | /name : canvia el teu \u00e0lies \n . /me acci\u00f3 : envia una acci\u00f3 \n ./ msg \u00e0lies missatge : envia un missatge privat \n . /r missatge : respon a l'ultim missatge privat \n . /join #sala : canvia la sala actual
-PasswordWindow.title=Vuze est\u00e0 protegit per contrassenya
-PasswordWindow.passwordprotected=Vuze est\u00e0 protegit per contrassenya.\nPer restaurar Vuze si us plau tipee la seva contrassenya aqu\u00ed :
-Button.ok=Ok
-TrackerChangerWindow.title=Canviar rastrejador
-TrackerChangerWindow.newtracker=Ingressi la nova url del rastrejador
+IrcView.help=Les ordres v\u00e0lides s\u00f3n :\n . /help : mostra aquest missatge\n . /nick | /name : canvia l'\u00e0lies \n . /me acci\u00f3 : envia una acci\u00f3 \n ./ msg \u00e0lies missatge : envia un missatge privat \n . /r missatge : respon l'\u00faltim missatge privat \n . /join #sala : canvia la sala actual
+PasswordWindow.title=El Vuze est\u00e0 protegit amb una contrasenya
+PasswordWindow.passwordprotected=El Vuze est\u00e0 protegit amb una contrasenya.\nPer restaurar el Vuze, teclegeu la contrasenya:
+Button.ok=D'acord
+TrackerChangerWindow.title=Afegeix un rastrejador
+TrackerChangerWindow.newtracker=Introdu\u00efu la nova URL del rastrejador
 PeersView.discarded=Rebutjat
 PeersView.discarded.info=Dades que heu rebut encara que no les necessiteu, aix\u00ed us en podeu desfer.
 discarded=rebutjat
-MyTorrentsView.menu.move=&Moure
+MyTorrentsView.#=Nre.
+MyTorrentsView.menu.move=&Mou
 MyTorrentsView.menu.moveUp=Am&unt
 MyTorrentsView.menu.moveDown=&Avall
-GeneralView.label.hashfails=Fallada el Hash :
-GeneralView.label.shareRatio=Terme mitj\u00e0 compartit :
-ConfigView.section.downloadManagement=Administrador de Desc\u00e0rrega
-ConfigView.label.startRatioPeers=Comen\u00e7ar a compartir quan hagi menys de 1 llavor
-ConfigView.text.neverStop=No detenir mai
-ConfigView.text.neverStart=No comen\u00e7ar mai
-ConfigView.text.peers=Parells
-ConfigView.label.checkOncompletion=Comprovar peces una vegada descarregades
+GeneralView.label.hashfails=Fallada del Hash:
+GeneralView.label.shareRatio=Terme mitj\u00e0 compartit:
+ConfigView.section.downloadManagement=Administrador de les desc\u00e0rregues
+ConfigView.label.startRatioPeers=Comen\u00e7a a compartir quan hagi menys de 1 llavor
+ConfigView.text.neverStop=No aturis mai
+ConfigView.text.neverStart=No comencis mai
+ConfigView.text.peers=Iguals
+ConfigView.label.checkOncompletion=Comprova les peces una vegada descarregades
 wizard.title=Crea un .torrent
 wizard.previous=< Anterior
 wizard.next=Seg\u00fcent >
 wizard.finish=Acabar
-wizard.mode=Rastrejador / Modus
+wizard.mode=Rastrejador / Mode
 wizard.tracker=Rastrejador:
 wizard.invalidurl=Aquesta URL no \u00e9s valida
 wizard.singlefile=Fitxer
-wizard.singlefile.help=Crea un .torrent des d'un fitxer
+wizard.singlefile.help=Crea un torrent des d'un fitxer
 wizard.directory=Carpeta
-wizard.directory.help=Crea un .torrent des d'una carpeta
+wizard.directory.help=Crea un torrent des d'una carpeta
 wizard.choosefile=Seleccioneu el fitxer
 wizard.file=Fitxer:
 wizard.browse=Examina...
@@ -341,52 +366,55 @@ wizard.choosedirectory=Seleccioneu la carpeta
 wizard.invalidfile=Fitxer no v\u00e0lid!
 wizard.invaliddirectory=Carpeta no v\u00e0lida!
 wizard.torrentFile=Fitxer .torrent
-wizard.choosetorrent=Si us plau seleccioneu el fitxer .torrent que voleu crear
+wizard.choosetorrent=Seleccioneu el fitxer .torrent que voleu crear
 wizard.information=Informaci\u00f3
 wizard.notimplemented=No implementat encara
 wizard.progresstitle=Creant fitxer .torrent
 wizard.savingfile=Desant el fitxer...
 wizard.filesaved=Fitxer desat.
 wizard.close=Tanca
-Torrent.create.progress.piecelength=Longitud de pe\u00e7a: 
+Torrent.create.progress.piecelength=Longitud de la pe\u00e7a: 
 Torrent.create.progress.piececount=Quantitat de peces:
 Torrent.create.progress.totalfilesize=Mida total del fitxer:
 Torrent.create.progress.totalfilecount=Quantitat total de fitxers:
-Torrent.create.progress.parsingfiles=Analitzant fitxers
-Torrent.create.progress.hashing=Hashing fitxers
+Torrent.create.progress.parsingfiles=Analitzant els fitxers
+Torrent.create.progress.hashing=Resumint els fitxers
 MainWindow.upgrade.downloadingfrom=Descarregant des de:
-MainWindow.menu.view.ipFilter=Filtres de Ip
-ConfigView.section.ipfilter=Filtres de IP
+MainWindow.menu.view.ipFilter=Filtres d' adreces &IP
+ConfigView.section.ipfilter=Filtres d'adre\u00e7a IP
 ConfigView.section.ipfilter.description=Descripci\u00f3
-ConfigView.section.ipfilter.start=Ip inicial
-ConfigView.section.ipfilter.end=Ip final
-ConfigView.section.ipfilter.add=Afegir
-ConfigView.section.ipfilter.remove=Treure
+ConfigView.section.ipfilter.start=Adre\u00e7a IP d'inici
+ConfigView.section.ipfilter.end=Adre\u00e7a IP final
+ConfigView.section.ipfilter.add=Afegeix
+ConfigView.section.ipfilter.remove=Elimina
 ConfigView.section.ipfilter.edit=Edita
 ConfigView.section.ipfilter.save=Desa
 ConfigView.section.ipfilter.editFilter=Edita els filtres
-ConfigView.section.ipfilter.enable=Activar
-PeersView.menu.close=Tan&car
+ConfigView.section.ipfilter.enable=Habilita
+PeersView.menu.close=Tan&ca
 seedmore.title=No hi ha suficient llavors per a aquest .torrent
 seedmore.shareratio=El teu terme mitj\u00e0 compartit per a aquest .torrent \u00e9s de
 seedmore.uploadmore=No conv\u00e9 tenir una proporci\u00f3 de dades compartides de menys del 100% a la xarxa bittorrent.\nHaur\u00edeu de fer servir m\u00e9s aquest torrent.\nSegur que voleu seguir?
-ConfigView.label.showpopuponclose=Demanar confirmaci\u00f3 al detenir compartint amb un terme mitj\u00e0 compartit menor de 1
-ConfigView.label.startNumSeeds=\nComen\u00e7ar a compartir si hi ha menys de
+ConfigView.label.showpopuponclose=Demana la confirmaci\u00f3 qua s'aturi el compartint amb un terme mitj\u00e0 compartit de menys de 1
+ConfigView.label.startNumSeeds=\nComen\u00e7a a compartir si hi ha menys de
 ConfigView.label.seeds=llavors
 ConfigView.section.seeding=Sembrant
-MyTorrentsView.menu.removeand=&Treure i
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletetorrent=Esborra el fitxer &torrent
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletedata=Esborra les &dades
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deleteboth=Esborra'ls tots dos
 deletedata.title=Esborra el contingut
-deletedata.message1=Esteu a punt d'esborrar les dades contingudes a:\n
-MainWindow.menu.file.configure=&Assistent de Configuraci\u00f3 ...
-configureWizard.title=Assistent de configuraci\u00f3
-configureWizard.welcome.title=Benvingut a l'assistent de configuraci\u00f3 d'Vuze
-configureWizard.welcome.message=Aquest assistent t'ajudar\u00e0 a configurar les opcions m\u00e9s com\u00fans d'Azureus. Pot modificar amb major profunditat aquestes opcions en el men\u00fa Vistes>Configuraci\u00f3.
+# used for more than just "delete data"
+deletedata.noprompt=No m'ho tornis a preguntar
+MainWindow.menu.file.configure=&Auxiliar de configuraci\u00f3...
+configureWizard.title=Auxiliar de configuraci\u00f3
+configureWizard.welcome.title=Benvingut a l'auxiliar de configuraci\u00f3 del Vuze
+configureWizard.welcome.message=Aquest auxiliar us ajudar\u00e0 a configurar les opcions m\u00e9s comunes del Vuze. Podeu modificar m\u00e9s detalladament aquestes opcions al men\u00fa Eines > Opcions.
 configureWizard.transfer.title=Configuraci\u00f3 de la connexi\u00f3 i les transfer\u00e8ncies
-configureWizard.transfer.hint=Truc : posar una mica menys de la velocitat real de la l\u00ednia \u00e9s la millor opci\u00f3.
-configureWizard.transfer.message=Si us plau, trieu una connexi\u00f3 de la llista seg\u00fcent. Aneu amb compte de no permetre massa velocitat de c\u00e0rrega, ja que far\u00e0 que la velocitat de desc\u00e0rrega sigui lenta. Com que les velocitats de c\u00e0rrega nom\u00e9s compten per al torrent que esteu descarregant, voler descarregar massa torrents igualment provocar\u00e0 petites velocitats de desc\u00e0rrega. Us recomanem de fer servir 5 kB/s per torrent com a m\u00ednim ESTRICTE. [...]
+configureWizard.transfer.hint=La millor opci\u00f3 \u00e9s fer servir menys velocitat que la velocitat real que tingui la l\u00ednia.
+configureWizard.transfer.message=Trieu una connexi\u00f3 de la llista seg\u00fcent. Aneu amb compte de no permetre gaire velocitat de c\u00e0rrega, ja que far\u00e0 que la velocitat de desc\u00e0rrega sigui lenta. Com que les velocitats de c\u00e0rrega nom\u00e9s compten per al torrent que esteu descarregant, voler descarregar massa torrents igualment far\u00e0 que les velocitats de desc\u00e0rrega siguin baixes. Us recomanem de fer servir 5 kB/s per torrent com a m\u00ednim ESTRICTE. Co [...]
 configureWizard.transfer.connection=L\u00ednia
 configureWizard.transfer.connection.0=Personalitzat
 configureWizard.transfer.connection.1=m\u00f2dem/isdn
@@ -396,45 +424,43 @@ configureWizard.transfer.connection.4=adsl/cable xxx/384 kbps
 configureWizard.transfer.connection.5=adsl/cable xxx/512 kbps 
 configureWizard.transfer.connection.6=adsl/cable xxx/768 kbps 
 configureWizard.transfer.connection.7=adsl/cable xxx/1024 kbps 
-configureWizard.transfer.maxUpSpeed=Vel.M\u00e0x.Pujar (kB/s)
+configureWizard.transfer.maxUpSpeed=Vel. m\u00e0x. c\u00e0rrega (kB/s)
 configureWizard.transfer.maxActiveTorrents=M\u00e0x. Actius
-configureWizard.transfer.maxDownloads=M\u00e0x. Desc\u00e0rregues
+configureWizard.transfer.maxDownloads=Nre. m\u00e0x. de desc\u00e0rregues
 configureWizard.transfer.maxUploadsPerTorrent=Nombre m\u00e0xim de c\u00e0rregues per torrent
-configureWizard.nat.title=NAT / Ports del servidor
-configureWizard.nat.message=Si voleu obtenir el millor de BitTorrent, \u00e9s altament recomanable que el vostre ordinador tingui acc\u00e9s complet des d'Internet. El rang de ports per defecte de BitTorrent va des del 6881 fins al 6889. Aquesta eina us permet provar i canviar aquests ports. Si teniu alguna desc\u00e0rrega activa, \u00e9s possible que alguns ports no siguin accessibles.
 configureWizard.nat.test=Prova
 configureWizard.nat.testing=Provant ports
-configureWizard.nat.ok=Ok
+configureWizard.nat.ok=D'acord
 configureWizard.nat.ko=Error de NAT
 configureWizard.nat.unable=No s'ha pogut comprovar
 configureWizard.file.title=Torrents / Fitxers
-configureWizard.file.message1=El Vuze desar\u00e0 els .torrent oberts en una carpeta espec\u00edfica. La podeu triar aqu\u00ed:
+configureWizard.file.message1=El Vuze desar\u00e0 els .torrent oberts en una carpeta concreta. La podeu triar aqu\u00ed:
 configureWizard.file.path=Ruta
-configureWizard.file.browse=Examinar
-configureWizard.file.message2=El Vuze \u00e9s capa\u00e7 de resumir instant\u00e0niament els teus fitxers afegint algunes dades de resum als teus .torrents. Si fas servir aquesta caracter\u00edstica, tamb\u00e9 podr\u00e0s resumir peces de fitxers descarregats parcialment.
-configureWizard.file.fastResume=Activar resum r\u00e0pid
+configureWizard.file.browse=Examina
+configureWizard.file.message2=El Vuze \u00e9s capa\u00e7 de reprendre instant\u00e0niament els fitxers afegint algunes dades de represa als .torrents. Si fas servir aquesta caracter\u00edstica, tamb\u00e9 podr\u00e0s reprendre peces de fitxers descarregats parcialment.
+configureWizard.file.fastResume=Habilita la represa r\u00e0pida
 configureWizard.file.invalidPath=Carpeta inv\u00e0lida
 configureWizard.finish.title=Completat
 configureWizard.finish.message=El Vuze est\u00e0 configurat. Gaudeix-ne!
 wizard.close.confirmation=Confirmaci\u00f3
-wizard.close.message=Voleu que l'assistent es carregui la propera vegada que inicieu el Vuze
+wizard.close.message=Voleu que l'auxiliar es carregui la propera vegada que inicieu el Vuze
 exportTorrentWizard.title=Exportar un .torrent
 exportTorrentWizard.torrentfile.title=Selecci\u00f3 del fitxer .torrent
 exportTorrentWizard.torrentfile.message=Seleccioneu el fitxer .torrent per exportar
 exportTorrentWizard.torrentfile.path=Ruta
 exportTorrentWizard.torrentfile.browse=Examinar
-exportTorrentWizard.torrentfile.invalidPath=Ftixer .torrent inv\u00e0lid
+exportTorrentWizard.torrentfile.invalidPath=Fitxer .torrent inv\u00e0lid
 exportTorrentWizard.exportfile.title=Exporta els fitxers seleccionats
 exportTorrentWizard.exportfile.message=Ingressar la carpeta \u00f3n es va a exportar
 exportTorrentWizard.exportfile.path=Ruta
 exportTorrentWizard.exportfile.browse=Examinar
-exportTorrentWizard.exportfile.invalidPath=Ftixer .torrent inv\u00e0lid
+exportTorrentWizard.exportfile.invalidPath=Fitxer .torrent inv\u00e0lid
 exportTorrentWizard.finish.title=Completat
 exportTorrentWizard.finish.message=El proc\u00e9s d'exportaci\u00f3 s'ha completat correctament
-exportTorrentWizard.process.inputfilebad.title=Ftixer .torrent inv\u00e0lid
+exportTorrentWizard.process.inputfilebad.title=Fitxer .torrent inv\u00e0lid
 exportTorrentWizard.process.inputfilebad.message=S'ha produ\u00eft un erroe quan s'estava accedint als fitxers:
 exportTorrentWizard.process.outputfileexists.title=El fitxer existeix
-exportTorrentWizard.process.outputfileexists.message=El ftixer de sortida ja existeix. El voleu sobreescriure?
+exportTorrentWizard.process.outputfileexists.message=El fitxer de sortida ja existeix. El voleu sobreescriure?
 exportTorrentWizard.process.torrentfail.title=va Fallar la lectura del .torrent
 exportTorrentWizard.process.exportfail.title=El proc\u00e9s d'exportaci\u00f3 va fallar
 exportTorrentWizard.process.unknownfail.title=Error inesperat
@@ -443,7 +469,7 @@ importTorrentWizard.torrentfile.title=Selecci\u00f3 del fitxer .torrent
 importTorrentWizard.torrentfile.message=Seleccioneu el fitxer .torrent per importar
 importTorrentWizard.torrentfile.path=Ruta
 importTorrentWizard.torrentfile.browse=Examinar
-importTorrentWizard.torrentfile.invalidPath=Ftixer .torrent inv\u00e0lid
+importTorrentWizard.torrentfile.invalidPath=Fitxer .torrent inv\u00e0lid
 importTorrentWizard.importfile.title=Selecci\u00f3 de fitxers per importar
 importTorrentWizard.importfile.message=Selecciona el fitxer xml per importar
 importTorrentWizard.importfile.path=Ruta
@@ -452,31 +478,35 @@ importTorrentWizard.importfile.invalidPath=El fitxer per importar \u00e9s inv\u0
 importTorrentWizard.finish.title=Completat
 importTorrentWizard.finish.message=El proc\u00e9s d'importaci\u00f3 s'ha completat correctament
 importTorrentWizard.process.inputfilebad.title=El fitxer per importar \u00e9s inv\u00e0lid
-importTorrentWizard.process.inputfilebad.message=S'ha produ\u00eft un error quan s'estava accedint als ftixers:
+importTorrentWizard.process.inputfilebad.message=S'ha produ\u00eft un error quan s'estava accedint als fitxers:
 importTorrentWizard.process.outputfileexists.title=El fitxer existeix
 importTorrentWizard.process.outputfileexists.message=El fitxer de sortida existeix. El voleu sobreescriure?
 importTorrentWizard.process.torrentfail.title=Errors d'escriptura del Torrent
 importTorrentWizard.process.importfail.title=Errors al importar el Torrent
 importTorrentWizard.process.unknownfail.title=Error inesperat
-ConfigView.label.bindip=Enlla\u00e7ar a una adre\u00e7a IP local or interface
-ConfigView.label.zeronewfiles=Quan es creen els fitxers nous assignar l'espai i posar-lo a zero
+ConfigView.label.bindip=Enlla\u00e7a una adre\u00e7a IP local o interf\u00edcie
+ConfigView.label.zeronewfiles=Quan es creen els fitxers nous assigna l'espai i posa'l a zero
 ConfigView.label.zeronewfiles.tooltip=Minimitza fragmentaci\u00f3
 ConfigView.section.stats=Estad\u00edstiques
 ConfigView.section.stats.enable=Activat
 ConfigView.section.stats.defaultsavepath=Carpeta per desar les estad\u00edstiques
-ConfigView.section.stats.choosedefaultsavepath=Si us plau, trieu la carpeta on voleu desar les estad\u00edstiques
+ConfigView.section.stats.choosedefaultsavepath=Trieu la carpeta on voleu desar les estad\u00edstiques
 ConfigView.section.stats.savefreq=Freq\u00fc\u00e8ncia de desada
+ConfigView.section.stats.minutes=min 
+ConfigView.section.stats.hours=h 
 ConfigView.section.stats.seconds=seg
 ConfigView.section.stats.savefile=Nom del fitxer d'estad\u00edsitiques
 MyTorrentsView.menu.export=&XML Exportar...
-MyTorrentsView.menu.host=&Hoste...
+MyTorrentsView.menu.host=Ordinador...
 ManagerItem.finishing=Acabant
-ConfigView.dialog.choosedefaulttorrentpath=Seleccioneu la carpeta de .torrent per defecte
+ConfigView.dialog.choosedefaulttorrentpath=Seleccioneu la carpeta per defecte dels torrents
 ConfigView.dialog.choosemovepath=Seleccioneu la carpeta on ho voleu moure
 ConfigView.label.movecompleted=Mou els fitxers completats
+ConfigView.label.moveremoved=Mou els fitxers complets (quan s'eliminin)
 ConfigView.label.savetorrents=Des els fitxers torrent
-MainWindow.menu.view.mytracker=El meu Rastrejador
-MyTrackerView.title.full=El meu Rastrejador
+MainWindow.menu.view.mytracker=El meu ras&trejador
+MainWindow.menu.view.mytracker.keybinding=Meta+2 
+MyTrackerView.title.full=Rastrejador
 MyTrackerView.name=Nom
 MyTrackerView.tracker=Rastrejador
 MyTrackerView.status=Estat
@@ -489,212 +519,227 @@ MyTrackerView.uploaded=Carregat
 MyTrackerView.downloaded=Descarregat
 MyTrackerView.left=Deixat
 ConfigView.section.style=Interf\u00edcie
+ConfigView.label.set_ui_transfer_speeds.description=Podeu triar aquest opci\u00f3 per definir manualment les velocitats de c\u00e0rrega i desc\u00e0rrega disponibles a la barra d'estat a la safata del sistema.\nEls valors s'han de separar amb comes. 
+ConfigView.label.set_ui_transfer_speeds.description.download=Indiqueu les velocitat de desc\u00e0rrega (en kB/s)
+ConfigView.label.set_ui_transfer_speeds.description.upload=Indiqueu les velocitats de desc\u00e0rrega (en kB/s)
 ConfigView.section.style.useCustomTabs=Fer servir Etiquetes tancables (requereix reiniciar)
-MainWindow.menu.view.plugins=Complements
-fileDownloadWindow.saveTorrentIn=Desa el ftixer torrent a
-fileDownloadWindow.title=Vuze - Descarregador Torrent
-fileDownloadWindow.downloading=Descarregant de :
-fileDownloadWindow.status=Estat :
+MainWindow.menu.view.plugins=Connectors
+fileDownloadWindow.saveTorrentIn=Desa el fitxer torrent a
+fileDownloadWindow.title=Vuze - Descarregador de torrents
+fileDownloadWindow.downloading=Descarregant de:
+fileDownloadWindow.status=Estat:
 fileDownloadWindow.state_initializing=Inicialitzant
 fileDownloadWindow.state_downloading=Descarregant
 fileDownloadWindow.state_error=Error: 
 MainWindow.menu.file.open.url=URL
-openUrl.title=Vuze - Obrir Url
+MainWindow.menu.file.open.url.keybinding=Meta+L 
+openUrl.title=Vuze - Obre la URL
 openUrl.url=URL:
-MyTorrentsView.menu.host.error.title=Allotjar el Torrent ha fallat 
-MyTorrentsView.menu.host.error.message=Ha passat el seg\u00fcent error quan allotjavem el torrent
-ConfigView.section.tracker=rastrejador
+MyTorrentsView.menu.host.error.title=L'hostatjament del torrent ha fallat 
+MyTorrentsView.menu.host.error.message=S'ha produ\u00eft l'error seg\u00fcent en hostatjar el torrent
+ConfigView.section.tracker=Rastrejador
 ConfigView.section.tracker.pollinterval=Interval per consutar clients al rastrejador (segons)
 ConfigView.section.tracker.publishenable=Publicar detalls del torrent a "/"
-ConfigView.section.tracker.ip=Adre\u00e7a IP Externa del rastrejador
+ConfigView.section.tracker.ip=Adre\u00e7a IP externa del rastrejador
 ConfigView.section.style.enableXPStyle=Activa estil XP (necessita reiniciar)
-ConfigView.section.tracker.checkip=Comprovar adre\u00e7a...
-ipCheckerWizard.title=Assistent per a comprovar la teva adre\u00e7a IP
+IPChecker.external.service.dyndns.url=http://www.dyndns.org/ 
+ConfigView.section.tracker.checkip=Busca una adre\u00e7a IP externa...
+ipCheckerWizard.title=Auxiliar per a comprovar l'adre\u00e7a IP
 ipCheckerWizard.service=Servei
-ipCheckerWizard.chooseService=Si us plau tria un comprovador d'adreces IP dels llistats a continuaci\u00f3
-ipCheckerWizard.explanations=Pots fer servir l'assistent per a trobar la teva direcci\u00f3 IP externa. Si la teva adre\u00e7a IP \u00e9s din\u00e0mica, recomanem que obris un compte amb un prove\u00efdor de DNS din\u00e0mic. Alguns dels prove\u00efdors d'aquests serveis estan llistats a continuaci\u00f3, f\u00e9s servir l'enlla\u00e7 per a obrir un nou compte. Despr\u00e9s emplena el camp 'IP address' amb el teu servidor din\u00e1mic (ex. myhostname.dyndns.org). Necessitar\u00e0s un pro [...]
+ipCheckerWizard.chooseService=Trieu un comprovador d'adreces IP de les llistes seg\u00fcents
+ipCheckerWizard.explanations=Podeu fer servir l'auxiliar per trobar l'adre\u00e7a IP externa. Si la vostra adre\u00e7a IP \u00e9s din\u00e0mica, us recomanem que obriu un compte amb un prove\u00efdor de DNS din\u00e0mic. Alguns dels prove\u00efdors d'aquests serveis s\u00f3n a la llista que hi ha a continuaci\u00f3. Feu servir l'enlla\u00e7 per obrir un compte nou. Despr\u00e9s empleneu el camp 'Adre\u00e7a IP' amb el servidor din\u00e0mic (p. ex. myhostname.dyndns.org). Necessitareu un  [...]
 ipCheckerWizard.service.description=Descripci\u00f3 :
-ipCheckerWizard.service.url=Enlla\u00e7 :
+ipCheckerWizard.service.url=Enlla\u00e7:
 ipCheckerWizard.progresstitle=Comprovant IP
 ipCheckerWizard.checkComplete=IP completada :
 ipCheckerWizard.checkFailed=Va fallar, ra\u00f3 :
-wizard.tracker.local=Usar el rastrejador intern de Vuze
-wizard.tracker.external=Usar un rastrejador extern
-wizard.tracker.howToLocal=\tAnar a 'Configuraci\u00f3>rastrejador' per a habilitar-ho
+wizard.tracker.local=Fes servir el rastrejador intern del Vuze
+wizard.tracker.external=Fes servir un rastrejador extern
+wizard.tracker.howToLocal=\tAneu a 'Configuraci\u00f3 > Rastrejador' per habilitar-lo
 wizard.announceUrl=Adre\u00e7a URL d'anunci :
-IPChecker.external.service.discoveryvip.description=Discoveryvip - Comprovaci\u00f3 d'adre\u00e7a IP \u00fanica
+IPChecker.external.service.discoveryvip.name=Discoveryvip 
+IPChecker.external.service.discoveryvip.url=http://ip.discoveryvip.com/ 
+IPChecker.external.service.discoveryvip.description=Discoveryvip - Nom\u00e9s la cerca de l'adre\u00e7a IP 
 IPChecker.external.httpinvalidresponse=Resposta HTTP inv\u00e0lida
 IPChecker.external.loadingwebpage=Carregant la p\u00e0gina web
 IPChecker.external.analysingresponse=Analitzant resposta
 IPChecker.external.addressextracted=Adreces IP extretes
 IPChecker.external.httploadfail=Fallada al carregar la p\u00e0gina
 IPChecker.external.timeout=Fora de temps
-IPChecker.external.ipnotfound=L'Adre\u00e7a IP no es troba
+IPChecker.external.ipnotfound=No es troba l'adre\u00e7a IP
 ConfigView.section.tracker.pollintervalmin=M\u00ednim
 ConfigView.section.tracker.pollintervalmax=M\u00e0xim
-ConfigView.section.tracker.pollintervalincby=Incrementar per
-ConfigView.section.tracker.pollintervalincper=Cada 'n' Clients
+ConfigView.section.tracker.pollintervalincby=Incrementa per
+ConfigView.section.tracker.pollintervalincper=Cada 'n' clients
 splash.loadingImages=Carregant imatges
-splash.initializeGui=Iniciant finestra principal
-splash.openViews=Obrint vistes
-splash.plugin=Carregant complement :
+splash.initializeGui=Inicialitzant la finestra principal
+splash.openViews=Obrint les vistes
+splash.plugin=Carregant el connector:
 configureWizard.nat.tooManyPorts=Massa ports per a provar (9 m\u00e1xim)
-ConfigView.section.color=Esquema de Color
+ConfigView.section.color=Esquema de colors
 MyTorrentsView.menu.publish=&Publica...
 MyTrackerView.status.published=Publicat
 MyTrackerView.completed=Completat
-MainWindow.menu.file.open.torrentnodefault=Fitxer torrent... (No desis per defecte)
+MainWindow.menu.file.open.torrentnodefault=Fitxer torrent... (per defecte no es desa)
+MainWindow.menu.file.open.torrentnodefault.keybinding.mac=Meta+Opt+O 
 wizard.comment=Comentaris
-ConfigView.label.movetorrent=Moure .torrent
+ConfigView.label.movetorrent=Mou .torrent
+ConfigView.label.movepartialdownloads=Mou encara que alguns fitxers estiguin marcats com a 'No el descarreguis'
 ConfigView.label.subdir_is_in_default=Quan creguis que les desc\u00e0rregues ja existeixen a la carpeta per defecte, considera tamb\u00e9 les subcarpetes 
-ConfigView.section.file.decoder.label=Codificacio per defecte del torrent\nselecci\u00f3 requerida
+ConfigView.section.file.decoder.label=Codificaci\u00f3 per defecte del torrent quan calgui seleccionar
 ConfigView.section.file.decoder.nodecoder=Cap
-IPChecker.external.service.no-ip.description=Subministrador de servei DNS est\u00e0tic i din\u00e0mic\n(na hi ha servei gratuit de comprovaci\u00f3 d'adreces)
-ConfigView.section.tracker.publicenable=Activar .torrents externs
+IPChecker.external.service.no-ip.name=Sense adre\u00e7a IP
+IPChecker.external.service.no-ip.url=http://www.no-ip.com/ 
+IPChecker.external.service.no-ip.description=Subministrador de servei DNS est\u00e0tic i din\u00e0mic\n(na hi ha servei gratu\u00eft de comprovaci\u00f3 d'adreces)
+ConfigView.section.tracker.publicenable=Habilita els torrents externs
 ConfigView.label.playdownloadspeech=Parla quan s'acaba una desc\u00e0rrega
-ConfigView.label.playdownloadspeech.info=Actualment els Serveis de Parla van millor en angl\u00e8s
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=Mostra el nombre de c\u00f2pies disponible de cada pe\u00e7a.\nSi el nombre de la dreta \u00e9s m\u00e9s petit que 1, no esteu veient una c\u00f2pia sencera del fitxer (i podeu tenir problemes per completar la desc\u00e0rrega).
-GeneralView.label.trackerurl.tooltip=Cliqui per copiar la URL de l'anunci al portapapers
-GeneralView.label.trackerurlopen.tooltip=Cliqui per obrir la p\u00e0gina principal del rastrejador
+GeneralView.label.status.pieces_available.tooltip=Mostra el nombre de c\u00f2pies disponible de cada pe\u00e7a.\nSi el nombre de la dreta \u00e9s m\u00e9s petit que 1, no esteu veient tota una c\u00f2pia del fitxer (i podeu tenir problemes per completar la desc\u00e0rrega).
+GeneralView.label.trackerurl.tooltip=Cliqueu aqu\u00ed per copiar la URL de l'anunci al porta-retalls
+GeneralView.label.trackerurlopen.tooltip=Cliqueu per obrir la p\u00e0gina principal del rastrejador
 #
 # 2.0.4.4
 #
 ConfigView.section.style.guiUpdate=Actualitzar GUI cada
-ConfigView.section.style.graphicsUpdate=Actualitzar barres Grafiques cada N GUI actualitzaci\u00f3(ns)
-ConfigView.section.style.reOrderDelay=Re-Ordenar taules cada N GUI actualitzaci\u00f3(ns)
+ConfigView.section.style.graphicsUpdate=Actualitza les barres gr\u00e0fiques cada N GUI actualitzaci\u00f3/ons
+ConfigView.section.style.reOrderDelay=Reordena les taules cada N GUI actualitzaci\u00f3/ons
 ConfigView.section.style.reOrderDelay.never=Mai
 ConfigView.section.logging=Registrant...
 ConfigView.section.logging.enable=Activa anotacions al fitxer
 ConfigView.section.logging.logdir=Carpeta del fitxer d'anotacions
-ConfigView.section.logging.choosedefaultsavepath=Si us plau, selecioneu la carpeta per desar
+ConfigView.section.logging.choosedefaultsavepath=Selecioneu la carpeta per desar
 GeneralView.label.updatein.querying=Preguntant...
-configureWizard.nat.sharePort=Usar un \u00fanic port compartit per a tots els .torrent
+configureWizard.nat.sharePort=Fes servir un port  \u00fanic compartit per a tots els torrents
 ConfigView.section.logging.maxsize=Mida m\u00e0xima del fitxer d'anotacions
-ConfigView.section.tracker.passwordenableweb=Activar password en la Web del rastrejador
-ConfigView.section.tracker.passwordenabletorrent=Activar password en torrents
-ConfigView.section.tracker.username=Nom d'Usuari
-ConfigView.section.tracker.password=Mot clau
+ConfigView.section.tracker.passwordenableweb=Habilita la contrasenya a la p\u00e0gina web del rastrejador
+ConfigView.section.tracker.passwordenabletorrent=Habilita la contrasenya per als torrents
+ConfigView.section.tracker.username=Nom d'usuari
+ConfigView.section.tracker.password=Contrasenya
 columnChooser.title=Trieu les columnes per mostrar
-columnChooser.move=Arrossegui les files per re-ordenarles
-columnChooser.apply=Aplicar
+columnChooser.move=Arrossegueu les files per reordenar-les
+columnChooser.apply=Aplica
 columnChooser.columnname=Nom Columna
 columnChooser.columndescription=Descripci\u00f3
-TableColumn.header.shareRatio=Rati Compartir
+TableColumn.header.shareRatio=R\u00e0tio de compartici\u00f3
 MyTorrentsView.menu.editTableColumns=&Columnes per mostrar
 wizard.operationfailed=L'operaci\u00f3 ha fallat
 authenticator.title=Requereix identificaci\u00f3
 authenticator.realm=Domini
 authenticator.tracker=Rastrejador
-authenticator.user=Nom de l'Usuari
-authenticator.password=Mot clau
-ConfigView.label.allowSendVersion=Permetre a Vuze enviar un n\u00famero de versi\u00f3 an\u00f3nima i identificador aleatori mentre comprova la nova versi\u00f3
-wizard.hint.mode=Hint:\tPodeu arrossegar i deixar anar un \u00fanic fitxer o carpeta a l'assistent\n\tper triar un fitxer o carpeta
+authenticator.user=Nom d'usuari
+authenticator.password=Contrasenya
+ConfigView.label.allowSendVersion=Permet que el Vuze envi\u00ef un n\u00famero de versi\u00f3 an\u00f2nima i un identificador aleatori mentre comprova la nova versi\u00f3
+wizard.hint.mode=Hint:\tPodeu arrossegar i deixar anar un \u00fanic fitxer o carpeta a l'auxiliar\n\tper triar un fitxer o una carpeta
 wizard.hint.file=Hint:\tPodeu triar un sol fitxer arrossegant i deixant anar
 wizard.hint.directory=Hint:\tPodeu triar un \u00fanica carpeta arrossegant i deixant anar
-MainWindow.menu.help.checkupdate=&Cercar actualitzacions del programa
+MainWindow.menu.help.checkupdate=&Cerca actualitzacions del programa
 TableColumn.header.down=Descarregat
 TableColumn.header.up=Carregat
-ConfigView.section.tracker.passwordenabletorrent.info=Necessita client BitTorrent adequat (ex. Vuze
-ConfigView.section.style.confirmationOnExit=Mostrar di\u00e0leg de confirmaci\u00f3 al sortir
-MainWindow.dialog.exitconfirmation.title=Sortir d'Vuze
-MainWindow.dialog.exitconfirmation.text=Realment vol sortir d'Vuze
-SystemTray.menu.stopalltransfers=Aturar &Totes les Transfer\u00e8ncies
-TrayWindow.menu.stopalldownloads=&Aturar Totes les Desc\u00e0rregues
-ConfigView.section.tracker.sslport.info=Miri el FAQ per m\u00e9s informaci\u00f3
-wizard.tracker.ssl=Fer servir SSL
-ConfigView.label.playdownloadfinished=Tocar un s\u00f3 quan es finalitza la desc\u00e0rrega
+ConfigView.section.tracker.passwordenabletorrent.info=Necessita client BitTorrent adequat (p. ex. Vuze)
+ConfigView.section.style.confirmationOnExit=Mostrar di\u00e0leg de confirmaci\u00f3 quan surtis
+MainWindow.dialog.exitconfirmation.title=Surt del Vuze
+MainWindow.dialog.exitconfirmation.text=Segur que voleu sortir del Vuze?
+SystemTray.menu.stopalltransfers=Atura &totes les transfer\u00e8ncies
+TrayWindow.menu.stopalldownloads=&Atura totes les desc\u00e0rregues
+ConfigView.section.tracker.sslport.info=Consulteu les PMF per a m\u00e9s informaci\u00f3
+wizard.tracker.ssl=Fes servir SSL
+ConfigView.label.playdownloadfinished=Fes un so quan finalitzi la desc\u00e0rrega
+ConfigView.label.popupdownloadfinished=Mostra amb un anunci emergent que s'ha completat una desc\u00e0rrega
+ConfigView.label.popupfilefinished=Mostra un anunci emergent per alertar que s'ha completat un fitxer
 TableColumn.header.pieces=Peces
 TableColumn.header.pieces.info=Barra gr\u00e0fica representant quines peces heu descarregat
 TableColumn.header.completion=Completat
-TableColumn.header.completion.info=Representaci\u00f3 Gr\u00e0fica del % descarregat
+TableColumn.header.completion.info=Representaci\u00f3 gr\u00e0fica del % descarregat
 ConfigView.section.style.showdownloadbasket=Mostrar Cistell de Desc\u00e0rregues (Arrossegar i Deixar .torrents)
-ConfigView.section.style.alwaysShowTorrentFiles=Mostra sempre ftixers Torrent en Detalls/Fitxers
-wizard.multitracker=Afegeix informaci\u00f3 Multi-rastrejador al torrent
-wizard.multitracker.title=Multi-rastrejador
-wizard.multitracker.configuration=Configuraci\u00f3 Multi-rastrejador
+ConfigView.section.style.alwaysShowTorrentFiles=Mostra sempre fitxers torrents en Detalls/Fitxers
+wizard.multitracker=Afegeix informaci\u00f3 multirastrejador al torrent
+wizard.multitracker.title=Multirastrejador
+wizard.multitracker.configuration=Configuraci\u00f3 del multirastrejador
 wizard.multitracker.new=Nou...
 wizard.multitracker.edit=Edita...
 wizard.multitracker.delete=Esborra
-wizard.multitracker.group=Grup del Rastrejador
-wizard.multitracker.edit.title=Editor Multi-rastrejador
+wizard.multitracker.group=Grup del rastrejador
+wizard.multitracker.edit.title=Editor del multirastrejador
 wizard.multitracker.edit.name=Nom
 wizard.multitracker.edit.save=Desa
 wizard.multitracker.edit.newgroup=Nou Grup
 wizard.multitracker.edit.deletegroup=Esborra
-wizard.multitracker.edit.newtracker=Nou Rastrejador
+wizard.multitracker.edit.newtracker=Rastrejador nou
 wizard.multitracker.edit.deletetracker=Esborra
 wizard.multitracker.edit.edit=Edita
-wizard.addingmt=Afegint informaci\u00f3 Multi-rastrejador
+wizard.addingmt=Afegint informaci\u00f3 multirastrejador
 wizard.multitracker.noannounce=La URL d'anunci no \u00e9s present en la vostre llista de rastrejadors
-MyTorrentsView.menu.recheck=&For\u00e7ar Re-comprovar
-iconBar.showDownloadBar.tooltip=Mostrar Barra de Desc\u00e0rrega
-iconBar.start.tooltip=Comen\u00e7ar
-iconBar.stop.tooltip=Aturar
-iconBar.remove.tooltip=Treure
-iconBar.openNoDefault.tooltip=Obre un fitxer .torrent (no desar per defecte)
-iconBar.openURL.tooltip=Obrir una URL
-iconBar.openFolder.tooltip=Obrir una carpeta
-iconBar.new.tooltip=Crear un torrent
-iconBar.up.tooltip=Moure amunt
-iconBar.down.tooltip=Moure a baix
-iconBar.run.tooltip=Obrir
-iconBar.host.tooltip=Hoste
+MyTorrentsView.menu.recheck=&For\u00e7a la recomprovaci\u00f3
+iconBar.showDownloadBar.tooltip=Mostra la barra de desc\u00e0rrega
+iconBar.start.tooltip=Comen\u00e7a els torrents seleccionats
+iconBar.stop.tooltip=Atura els torrents seleccionats
+iconBar.remove.tooltip=Elimina els torrents seleccionats
+iconBar.openNoDefault.tooltip=Obre un fitxer .torrent (per defecte, no es desa)
+iconBar.openURL.tooltip=Obre una URL
+iconBar.openFolder.tooltip=Obre una carpeta
+iconBar.new.tooltip=Crea un torrent
+iconBar.up.tooltip=Mou amunt
+iconBar.down.tooltip=Mou avall
+iconBar.run.tooltip=Obre amb l'aplicaci\u00f3 per defecte
+iconBar.host.tooltip=Ordinador
 iconBar.publish.tooltip=Publica
+iconBar.editcolumns.tooltip=Configuraci\u00f3 de les columnes
 MyTorrentsView.menu.editTracker=&Edita la URL del rastrejador 
-GeneralView.menu.selectTracker=Seleccionar
+GeneralView.menu.selectTracker=Selecciona
 ConfigView.section.stats.xslfile=Nom del fitxer XSL
-ConfigView.section.stats.xslfiledetails=Aix\u00f2 s'inclour\u00e0 a la capcalera del ftixer d'estats amb una etiqueta
+ConfigView.section.stats.xslfiledetails=Aix\u00f2 s'inclour\u00e0 a la cap\u00e7alera del fitxer d'estats amb una etiqueta
 ConfigView.label.savetorrentbackup=Desa'n una c\u00f2pia
-ConfigView.section.tracker.forceport=Forca torrents externs allotjats en el port per defecte
+ConfigView.section.tracker.forceport=For\u00e7a els torrents externs hostatjats al port per defecte
 ConfigView.section.ipfilter.allow=PERMETRE aquests intervals (defecte \u00e9s PROHIBIR)
 ConfigView.section.ipfilter.list.inrange=\u00e9s entre limits
 ConfigView.section.ipfilter.list.notinrange=no \u00e9s entre limits
-ConfigView.section.ipfilter.list.title=Llista de IPs bloquejades
-ConfigView.label.allowsameip=Permetre M\u00faltiples connexions des de la mateixa IP
+ConfigView.section.ipfilter.list.title=Llista d'adreces IP bloquejades
+ConfigView.label.allowsameip=Permet m\u00faltiples connexions des de la mateixa IP
 ConfigView.label.allowsameip.tooltip=Nom\u00e9s marcar-ho quan es necessiti.\nQuan est\u00e0 desactivat \u00e9s una proteccio contra"leecher"
-ManagerItem.superseeding=Super-Sembrant
-ConfigView.label.userSuperSeeding=Fer Servir Super-Sembrant
-PeersView.uniquepiece=Pe\u00e7a (Modus Super-Sembrant)
+ManagerItem.superseeding=Supersembrant
+ConfigView.label.userSuperSeeding=Fes servir la supersembra
+PeersView.uniquepiece=Pe\u00e7a (mode supersembra)
 PeersView.uniquepiece.none=Cap
-PeersView.timetosend=Estafi per reenviar la Peca (Modus Super-Sembrant)
-ConfigView.section.style.addurlsilently=Obrir URL silenciosament (sense di\u00e0leg)
+PeersView.timetosend=Temps per reenviar la pe\u00e7a (mode supersembra)
+ConfigView.section.style.addurlsilently=Obre URL silenciosament (sense di\u00e0leg)
 ConfigView.section.style.addurlsilently.tooltip=Av\u00eds: si s'activa la finestra principal es pot fer invisible un altre cop!\nsi perdeu la icona de la safata, heu de desactivar aquesta opci\u00f3.
 ConfigView.section.file.decoder.prompt=Pregunta sempre quan hi hagi possibilitats de triar la codificaci\u00f3
 ConfigView.section.file.decoder.prompt.tooltip=Mostra sempre el di\u00e0leg quan hi hagi possibilitats de triar la codificaci\u00f3
-MyTorrentsView.menu.moveTop=A Dal&t
-MyTorrentsView.menu.moveEnd=A &Baix
+MyTorrentsView.menu.moveTop=A dal&t
+MyTorrentsView.menu.moveEnd=A &baix
 ConfigView.label.moveonlyusingdefaultsave=si \u00e9s a la carpeta de dades per defecte
-ConfigView.label.moveonlyusingdefaultsave.tooltip=Moure nom\u00e9s si el torrent \u00e9s en directori defecte de dades
-ConfigView.label.watchtorrentfolder=Importar nous .torrents autom\u00e0ticament
-ConfigView.label.watchtorrentfolder.tooltip=Mirar regularment si hi ha nous torrents
-ConfigView.label.watchtorrentfolderinterval=Int\u00e8rval
+ConfigView.label.moveonlyusingdefaultsave.tooltip=Mou nom\u00e9s si el torrent \u00e9s en directori defecte de dades
+ConfigView.label.watchtorrentfolder=Importa torrents nous autom\u00e0ticament
+ConfigView.label.watchtorrentfolder.tooltip=Mira regularment si hi ha nous torrents
+ConfigView.label.watchtorrentfolderinterval=Interval 
 ConfigView.label.watchtorrentfolderinterval.tooltip=Temps d'espera fins a tornar a comprovar la carpeta
-ConfigView.dialog.choosewatchtorrentfolderpath=Seleccioneu la carpeta des d'on importem .torrent
-ConfigView.label.startwatchedtorrentsstopped=Comen\u00e7ar aturat
-ConfigView.label.startwatchedtorrentsstopped.tooltip=Afegir torrents nous en estat ATURAT
-ConfigView.section.plugins=Complements
-wizard.maketorrent.filesize=Mida del fitxer(s)
-wizard.maketorrent.piececount=Comptador de Peces
+ConfigView.dialog.choosewatchtorrentfolderpath=Seleccioneu la carpeta des d'on voleu importar el .torrent
+ConfigView.label.startwatchedtorrentsstopped=Comen\u00e7a aturat
+ConfigView.label.startwatchedtorrentsstopped.tooltip=Afegeix torrents nous en estat ATURAT
+ConfigView.section.plugins=Connectors
+wizard.maketorrent.filesize=Mida del/s fitxer/s
+wizard.maketorrent.piececount=Comptador de peces
 wizard.maketorrent.piecesize=Mida Peca
-MainWindow.menu.view.stats=E&stadistiques
+wizard.maketorrent.auto=Autom\u00e0tic
+MainWindow.menu.view.stats=E&stad\u00edstiques
+MainWindow.menu.view.stats.keybinding=Meta+5 
 SpeedView.title.full=Activitat
 SpeedView.downloadSpeed.title=Velocitat de desc\u00e0rrega
 SpeedView.uploadSpeed.title=Velocitat de c\u00e0rrega
 ConfigView.section.style.useSIUnits=Fer servir unitats IEC (KB -> KiB etc.)
-iconBar.top.tooltip=Moure al principi
-iconBar.bottom.tooltip=Moure al final
+iconBar.top.tooltip=Mou a dalt de tot
+iconBar.bottom.tooltip=Mou a baix de tot
 TableColumn.header.health=Salut
-MyTorrentsView.menu.health=Sobre Salut
+MyTorrentsView.menu.health=Sobre la salut
 health.explain.grey=significa que el seu torrent no est\u00e0 en marxa (descarregant o pujant)
-health.explain.red=Significa que mentre descarreguem, no estem conectat a cap igual 
-health.explain.blue=Estar sembrant implica que mentre descarreguem\nno estem connectat a cap igual, i aix\u00f2 significa que haur\u00edem d'estar connectat a alguns iguals per\u00f2 el rastrejador est\u00e0 aturat
-health.explain.yellow=significa que el rastrejador \u00e9s correcte i que esteu connectats a iguals, per\u00f2 no teniu cap connexi\u00f3 remota.\nPotser teniu un problema NAT si els torrents romanen en estat groc tota l'estona
+health.explain.red=Significa que mentre descarreguem, no estem connectats a cap igual 
+health.explain.blue=Estar sembrant implica que mentre descarreguem\nno estem connectat a cap igual, i aix\u00f2 significa que haur\u00edem d'estar connectats a alguns iguals per\u00f2 el rastrejador est\u00e0 aturat
+health.explain.yellow=Significa que el rastrejador \u00e9s correcte i que esteu connectats a iguals, per\u00f2 no teniu cap connexi\u00f3 remota.\nPotser teniu un problema NAT si els torrents romanen en estat groc tota l'estona.
 health.explain.green=significa que tot va b\u00e9
-ConfigView.section.style.alwaysRefreshMyTorrents=Sempre refrescar Els meus Torrents
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aquesta opci\u00f3 refrescar\u00e0 la vista Els meus Torrents incl\u00fas si no es mostra (t\u00e9 \u00fas per alguns complements mirc)
+ConfigView.section.style.alwaysRefreshMyTorrents=Refresca sempre la {library.name}
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aquesta opci\u00f3 refrescar\u00e0 la vista de la biblioteca fins i tot si no es mostra (\u00e9s \u00fatil per alguns connectors mirc)
 #
 #2.0.7.0
 #
@@ -705,28 +750,29 @@ security.certtruster.issuedto=Em\u00e8s per A:
 security.certtruster.issuedby=Em\u00e8s per:
 security.certtruster.prompt=Us en refieu?
 security.certtruster.yes=S\u00ed
+security.certtruster.no=No 
 ConfigView.section.tracker.torrentsperpage=Quants torrents per p\u00e0gina?  [0: il\u00b7limitat]
-MainWindow.menu.file.share=&Compartir
+MainWindow.menu.file.share=&Comparteix de manera cl\u00e0ssica
 MainWindow.menu.file.share.file=&Fitxer...
 MainWindow.menu.file.share.dir=C&arpeta...
-MainWindow.menu.file.share.dircontents=C&ontingut Carpeta...
-MainWindow.menu.file.share.dircontentsrecursive=Contingut Carpeta... (&Recursiu)
+MainWindow.menu.file.share.dircontents=C&ontingut de la carpeta...
+MainWindow.menu.file.share.dircontentsrecursive=Contingut de la carpeta... (&Recursiu)
 MainWindow.dialog.share.sharefile=Seleccioneu el fitxer per compartir
-MainWindow.dialog.share.sharedir=Seleccioni Carpeta a Compartir
-MainWindow.dialog.share.sharedircontents=Seleccioni Contingut de Carpeta a Compartir
+MainWindow.dialog.share.sharedir=Seleccioneu la carpeta per compartir
+MainWindow.dialog.share.sharedircontents=Seleccioneu el contingut de la carpeta per compartir
 MainWindow.dialog.share.sharedircontents.recursive=Recursiu
 globalmanager.download.remove.veto=Acci\u00f3 d'eliminaci\u00f3 prohibida 
 plugin.sharing.download.remove.veto=Aquesta desc\u00e0rrega \u00e9s el resultat de compartir un recurs.\nPer treure la desc\u00e0rrega tregui el recurs compartit associat
 ConfigView.section.tracker.main=Principal
-ConfigView.label.prioritizefirstpiece=D\u00f3na prioritat a la primera i l'\u00faltima pe\u00e7a del fitxer(s)
+ConfigView.section.tracker.web=P\u00e0gina web
+ConfigView.label.prioritizefirstpiece=D\u00f3na prioritat a la primera i l'\u00faltima pe\u00e7a del/s fitxer/s
 ConfigView.label.prioritizefirstpiece.tooltip=Intenta descarregar l'aut\u00e8ntic inici i final del fitxer.\nPer suportar la vista pr\u00e8via prematura.
-ConfigView.section.file.confirm_data_delete=Confirmar quan esborrem dades
-ConfigView.section.file.confirm_data_delete.tooltip=Confirmar quan esborrem dades fent servir 'Treure i Borrar...'
 TrayWindow.menu.startalldownloads=Comencar Totes les Desc\u00e0rregues
-SystemTray.menu.startalltransfers=Comen\u00e7ar Totes les Transfer\u00e8ncies
+SystemTray.menu.startalltransfers=Comen\u00e7a totes les transfer\u00e8ncies
 sharing.progress.title=Progr\u00e9s de Compartir
 sharing.progress.hide=Amagar
 MainWindow.menu.view.myshares=Compartits
+MainWindow.menu.view.myshares.keybinding=Meta+3 
 MySharesView.title.full=Compartits
 MySharesView.name=Nom
 MySharesView.type=Tipus
@@ -734,154 +780,155 @@ MySharesView.type.file=Fitxer
 MySharesView.type.dir=Carpeta
 MySharesView.type.dircontents=Contingut de la carpeta
 MySharesView.type.dircontentsrecursive=Contingut de la carpeta (recursiu)
-MySharesView.menu.remove=Treure
+MySharesView.menu.remove=Elimina
+ConfigView.section.tracker.extensions=Extensions 
 ConfigView.section.tracker.sendpeerids=Enviar identitat de l'Igual als descarregadors
-ConfigView.section.tracker.enableudp=Activar protocol UDP del rastrejador
-plugin.sharing.torrent.remove.veto=Aquest registre del rastrejador \u00e9s el resultat de compartir un recurs.\nPer treure la desc\u00e0rrega tregui el recurs associat
+ConfigView.section.tracker.enableudp=Habilita el protocol UDP del rastrejador
+plugin.sharing.torrent.remove.veto=Aquest registre del rastrejador \u00e9s el resultat de compartir un recurs.\nPer eliminar la desc\u00e0rrega elimineu el recurs que s'hi associa.
 plugin.download.remove.veto.notstopped=No es pot treure la desc\u00e0rrega si no est\u00e0 aturada
 plugin.sharing.remove.veto=Aquest compartit \u00e9s un sub-compartit d'un 'contingut de carpeta' i no es pot eliminar.\nElimineu el compartit principal
-GeneralView.label.hash.tooltip=Cliqui per copiar el hash al portapapers
+GeneralView.label.hash.tooltip=Cliqueu aqui\u00ed per copiar el hash al porta-retalls
 ConfigView.section.tracker.maxpeersreturned=M\u00e0xim d'iguals tornats [0: il\u00b7limitat]
-ConfigView.label.serverport=Escoltar port TCP d'entrada
+ConfigView.label.serverport=Escolta el port TCP d'entrada
 configureWizard.nat.server.tcp_listen_port=Escoltar port TCP entrant
 ConfigView.section.sharing=Compartint
 ConfigView.section.sharing.usessl=Fes servir SSL per als recursos compartits (cal que configureu el rastrejador)
 ConfigView.section.style.dropdiraction=Acci\u00f3 d'arrossegar i deixar anar per carpetes
-ConfigView.section.style.dropdiraction.opentorrents=Obrir Torrents
+ConfigView.section.style.dropdiraction.opentorrents=Obre els torrents
 ConfigView.section.style.dropdiraction.sharefolder=Comparteix carpeta
 ConfigView.section.style.dropdiraction.sharefoldercontents=Compartir Contingut
 #
 # 2.0.7.x
 #
 Categories.all=Tots
-Categories.uncategorized=No Catalogat
-CategoryAddWindow.message=Entrar un nom nou de Categoria
-CategoryAddWindow.title=Afegir una nova Categoria
-ConfigView.label.autoSeedingIgnoreInfo=Els torrents ignorats van al final de la cua de sembrat. Ells no son arrencats autom\u00e8ticament\nLes Regles d'Ignorar no s'apliquen a torrents que cumpleixen el criteri de Primera Prioritat.\nA menys de que s'arrenquin d'una altra manera, feu servir un valor 0 per desactivar la regla.
+Categories.uncategorized=No catalogat
+CategoryAddWindow.message=Introdu\u00efui un nom nou de categoria
+CategoryAddWindow.title=Afegeix una categoria nova
+ConfigView.label.autoSeedingIgnoreInfo=Els torrents ignorats van al final de la cua de sembrat i no arrencaran autom\u00e0ticament\nLes regles d'ignorar no s'apliquen als torrents que compleixen el criteri de prioritat m\u00e0xima.\nSi no \u00e9s que arrenquen d'una altra manera, feu servir un valor 0 per desactivar la regla.
 ConfigView.label.directory=Carpeta
-ConfigView.label.disconnetseed.tooltip=Quan sembrem un torrent, desconecta els clients que no estan sembrant. No necessiten parlar amb vosaltres
-ConfigView.label.ignoreCase=Ignorar Maj./Min.
-ConfigView.label.ignoreSeeds=Ignorar torrents amb al menys
+ConfigView.label.disconnetseed.tooltip=Quan se sembri un torrent, desconnecta els clients que no estiguin sembrant. No necessiten parlar amb vosaltres.
+ConfigView.label.ignoreCase=Ignora la caixa
+ConfigView.label.ignoreSeeds=Ignorar torrents amb almenys
 ConfigView.label.importdirectory=Carpeta d'importaci\u00f3
 ConfigView.label.minPeersToBoostNoSeeds.tooltip=Qualsevol torrent sense llavors i tenint menys iguals que els que vosaltres especifiqueu\nes posar\u00e0 al final de la cua
 ConfigView.label.minPeersToBoostNoSeeds=Grau de sembrat m\u00e9s petit per torrents sense llavors i menys de
 ConfigView.label.minSeedingTime.tooltip=Els graus de sembrat poden variar sovint en un per\u00edode curt de temps. De vegades fan que el torrent arrenqui autom\u00e0ticament, s'aturi i despr\u00e9s es posi en cua autom\u00e0ticament\nAix\u00f2 alleugereix el problema for\u00e7ant rl torrent a romandre sembrant durant un per\u00edode de temps determinat. Encara el podeu aturar manualment si ho voleu.
-ConfigView.label.minSeedingTime=Min\u00edm temps de sembrat en segons
+ConfigView.label.minSeedingTime=Temps m\u00ednim de sembra en segons
 ConfigView.label.minSpeedForActiveDL.tooltip=Un canal de desc\u00e0rrega sempre es fa servir durant els 30 segons inicials\ndespr\u00e9s que el torrent incomplet arrenqui.
-ConfigView.label.minSpeedForActiveDL=No comptar el torrent com fent servir un canal de desc\u00e0rrega si la velocitat \u00e9s per sota de
+ConfigView.label.minSpeedForActiveDL=No comptis el torrent com a usuari d'un canal de desc\u00e0rrega si la velocitat \u00e9s per sota dels
 ConfigView.label.peers=iguals
-ConfigView.label.queue.debuglog=Anota informaci\u00f3 depuraci\u00f3
-ConfigView.label.queue.debuglog.info=Afegeix informaci\u00f3 de depuraci\u00f3 de la cua a la consola i al fitxer d'anotacions.\nEncara que \u00e9s encriptada, la informaci\u00f3 de depuraci\u00f3 us mostra l'estat dels torrents i per qu\u00e8 estan o no iniciant o en cua.
-ConfigView.label.queue.minQueueingShareRatio=No posis en cua o paris un torrent fins que arribi al seu rati de compartir.
-ConfigView.label.ratio=rati
-ConfigView.label.removeOnStop=Treure el torrent de la llista despr\u00e9s de que aquest es pari autom\u00e0ticament
+ConfigView.label.queue.debuglog=Anota la informaci\u00f3 depuraci\u00f3
+ConfigView.label.queue.debuglog.info=Afegeix informaci\u00f3 de depuraci\u00f3 de la cua a la consola i al fitxer d'anotacions.\nTot i que est\u00e0 encriptada, la informaci\u00f3 de depuraci\u00f3 us mostra l'estat dels torrents i per qu\u00e8 s'estan iniciant o no, o s\u00f3n a la cua.
+ConfigView.label.queue.minQueueingShareRatio=No posis a la cua o aturis un torrent fins que arribi a la r\u00e0tio de compartir.
+ConfigView.label.ratio=r\u00e0tio
+ConfigView.label.removeOnStop=Elimina el torrent de la llista despr\u00e9s que s'aturi autom\u00e0ticament
 ConfigView.label.savedirectory=Carpeta per desar
 ConfigView.label.seeding.autoReposition.tooltip=Si est\u00e0 habilitat, l'ordre dels torrents (la columna #) canviar\u00e0 per estar d'acord amb el grau de sembrat\nAix\u00f2 \u00e9s \u00fatil si no voleu veure els nombres de grau de sembrat, per\u00f2 encara voleu saber l'ordre en qu\u00e8 comen\u00e7aran els torrents complets.
-ConfigView.label.seeding.autoReposition=Reordenar els torrents autom\u00e0ticament segons el seu grau de sembrat
+ConfigView.label.seeding.autoReposition=Reordena els torrents autom\u00e0ticament segons el grau de sembrat
 ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=Sovint els torrents amb poques llavors i molts iguals vol dir que probablement no hi ha una c\u00f2pia completa ajuntant els iguals.\nAleshores, podeu no voler que les regles de sembrat pretenguin que hi ha una c\u00f2pia completa (i aix\u00ed incorrectament reduir el grau)
 ConfigView.label.seeding.fakeFullCopySeedStart=per\u00f2 nom\u00e9s torrents amb al menys
-ConfigView.label.seeding.ignore=Regles d'Ignorar
-ConfigView.label.seeding.ignore0Peers=Ignorar torrents amb 0 iguals
-ConfigView.label.seeding.ignoreRatioPeers=Ignorar torrents que tenen al menys 1 igual per cada
-ConfigView.label.seeding.ignoreShareRatio=Ignorar torrents que tenen un rati de compartir de
-ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignorar un torrent incl\u00fas si\ncompleix les regles de Primera Prioritat
+ConfigView.label.seeding.ignore=Regles d'ignorar
+ConfigView.label.seeding.ignore0Peers=Ignora els torrents amb 0 iguals
+ConfigView.label.seeding.ignoreRatioPeers=Ignora els torrents que tenen almenys una llavor per a cada un
+ConfigView.label.seeding.ignoreShareRatio=Ignora els torrents que tenen una relaci\u00f3 de compartir de
+ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignora un torrent fins i tot si\ncompleix les regles de prioritat m\u00e0xima
 ConfigView.label.seeding.ignore.header.rule=Regla
 ConfigView.label.seeding.ignore.header.value=Valor
-ConfigView.label.seeding.firstPriority.info=Els torrents amb Primera Prioritat sempre estaran al principi de la cua.\nQualsevol torrent que cumpl\u00f1eixi els criteris de Primera Prioritat no s'aturar\u00e0 i es posar\u00e0 en cua autom\u00e0ticament.\nUn torrent que compleixi la Primera Prioritat agafar\u00e0 un Canal de Desc\u00e0rrega Simult\u00e0ni si el necessita.
-ConfigView.label.seeding.firstPriority.FP=Primera Prioritat
-ConfigView.label.seeding.firstPriority=Donem Primera Prioritat als torrents amb
+ConfigView.label.seeding.firstPriority.info=Els torrents amb prioritat m\u00e0xima sempre seran al principi de la cua.\nQualsevol torrent que compleixi els criteris de prioritat m\u00e0xima no s'aturar\u00e0 i es posar\u00e0 autom\u00e0ticament a la cua.\nUn torrent que compleixi la prioritat m\u00e0xima agafar\u00e0 un canal simultani de desc\u00e0rrega si el necessita.
+ConfigView.label.seeding.firstPriority.FP=Prioritat m\u00e0xima
+ConfigView.label.seeding.firstPriority=La prioritat m\u00e0xima ser\u00e0 per als torrents amb
 ConfigView.label.seeding.firstPriority.following=de els seg\u00fcents:
-ConfigView.label.seeding.firstPriority.shareRatio=Un rati de compartir per sota de
+ConfigView.label.seeding.firstPriority.shareRatio=Una relaci\u00f3 de compartir per sota de
 ConfigView.label.seeding.firstPriority.seedingMinutes=Un temps d'espera canviant de descarregant a sembrant
-ConfigView.label.seeding.firstPriority.DLMinutes=Un temps d'espera des de que comen\u00e7a la desc\u00e0rrega
+ConfigView.label.seeding.firstPriority.DLMinutes=Un temps d'espera des que comen\u00e7a la desc\u00e0rrega
 ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Suposant que hi ha una c\u00f2pia completa per a X iguals, redu\u00efu el grau de torrents amb molts iguals.\nM\u00e9s aproximadament, els torrents amb molts d'iguals tenen molt de tr\u00e0nsit.\nAix\u00f2 no canvia el nombre de llavors que es mostra.
-ConfigView.label.seeding.numPeersAsFullCopy=Fer veure que hi ha 1 c\u00f2pia completa per cada un\n(0: no fer-ho veure)
-ConfigView.label.seeding.preferLargerSwarms.tooltip=Si principalment esteu sembrant torrents amb iguals que estan encallats, t\u00e9 sentit preferir eixams m\u00e9s grans\nQuan principalment esteu sembrant torrents amb una alta disponibilitat, \u00e9s millor tenir eixams petits.
-ConfigView.label.seeding.preferLargerSwarms=Quan els torrents tenen el mateix grau, preferir els eixams m\u00e9s grans
+ConfigView.label.seeding.numPeersAsFullCopy=Fes veure que hi ha 1 c\u00f2pia completa per a cadascun\n(0: no ho facis veure)
+ConfigView.label.seeding.preferLargerSwarms.tooltip=Si principalment esteu sembrant torrents amb iguals que estan encallats, t\u00e9 sentit preferir eixams m\u00e9s grans\nQuan principalment esteu sembrant torrents amb una alta disponibilitat, \u00e9s millor tenir els eixams petits.
+ConfigView.label.seeding.preferLargerSwarms=Quan els torrents tenen el mateix grau, prioritza els eixams m\u00e9s grans
 ConfigView.label.seeding.rankType.none.tooltip=Ordre basat en # de columna
 ConfigView.label.seeding.rankType.none=Cap
 ConfigView.label.seeding.rankType.peerSeed.options=Opcions de Rati de Sembrat a Iguals
-ConfigView.label.seeding.rankType.peerSeed.tooltip=Rati m\u00e9s gran = Nivell m\u00e9s alt
-ConfigView.label.seeding.rankType.peerSeed=Rati de Sembrat a Iguals
-ConfigView.label.seeding.rankType.seed.fallback=Tornar a Rati Iguals/Llavors despr\u00e9s de\n(0 : No tornar mai
-ConfigView.label.seeding.rankType.seed.options=Opcions de compte de Llavors
-ConfigView.label.seeding.rankType.seed.tooltip=Menys Llavors = Nivell m\u00e9s alt
-ConfigView.label.seeding.rankType.seed=Nom\u00e9s compte de Llavors
-ConfigView.label.seeding.rankType.timedRotation.tooltip=Tots els torrents completats s'alternaran al modus sembrant.\nLa duraci\u00f3 del temps de sembrat \u00e9s establert per 'Temps M\u00ednim Sembrant'
+ConfigView.label.seeding.rankType.peerSeed.tooltip=R\u00e0tio m\u00e9s gran = nivell m\u00e9s alt
+ConfigView.label.seeding.rankType.peerSeed=Relaci\u00f3 d'hom\u00f2legs:llavor
+ConfigView.label.seeding.rankType.seed.fallback=Torna a la relaci\u00f3 hom\u00f2legs: llavor despr\u00e9s de\n(0 : no hi tornis mai)
+ConfigView.label.seeding.rankType.seed.options=Opcions exclusives de recompte de llavors
+ConfigView.label.seeding.rankType.seed.tooltip=Menys llavors = nivell m\u00e9s alt
+ConfigView.label.seeding.rankType.seed=Nom\u00e9s recompte delllavors
+ConfigView.label.seeding.rankType.timedRotation.tooltip=Tots els torrents completats s'alternaran al modus sembrant.\nLa duraci\u00f3 del temps de sembrat \u00e9s establert pel 'Temps m\u00ednim de sembra'
 ConfigView.label.seeding.rankType.timedRotation=Rotaci\u00f3 temporitzada
-ConfigView.label.seeding.rankType.tooltip=Els torrents amb nivell m\u00e9s alt s'arrenquen autom\u00e0ticament.\nQuan un altre torrent arriva a un nivell m\u00e9s alt, el de menys nivell es para i va endarrera de la cua.\n\nNom\u00e9s estan disponibles per arrancar autom\u00e0ticament els torrents en un estat 'en Cua'.\nMai son arrancats autom\u00e0ticament els torrents parats.
+ConfigView.label.seeding.rankType.tooltip=Els torrents amb nivell m\u00e9s alt arrenquen autom\u00e0ticament.\nQuan un altre torrent arriba a un nivell m\u00e9s alt, el de menys nivell s'atura i va enrere a la cua.\n\nNom\u00e9s estan disponibles per arrencar autom\u00e0ticament els torrents en l'estat de ser a la cua.\nEls torrents aturats mai no arrencaran autom\u00e0ticament.
 ConfigView.label.seeding.rankType=Valora els torrents complets per obrir-los autom\u00e0ticament d'acord amb:
-ConfigView.label.stopAfterMinutes=Un cop canviat a sembrant, aturar despr\u00e9s d'un temps de
-ConfigView.label.switchpriority.tooltip=Prioritat baixa redueix la quantitat d'ample de banda en desc\u00e0rrega permesa al torrent.
-ConfigView.pluginlist.info=S'han identificat els seg\u00fcents complements. Alguns complements pot ser no tenen etiquetes de configuraci\u00f3.
-ConfigView.pluginlist.noplugins=No s'han trobat complements.
+ConfigView.label.stopAfterMinutes=Un cop canviat a sembrant, atura al cap d'un temps 
+ConfigView.label.switchpriority.tooltip=La prioritat baixa redueix la quantitat d'amplada de banda en la desc\u00e0rrega permesa al torrent.
+ConfigView.pluginlist.info=S'han identificat els seg\u00fcents connectors. Alguns connectors pot ser que no tinguin etiquetes de configuraci\u00f3.
+ConfigView.pluginlist.noplugins=No s'han trobat connectors.
 ConfigView.section.pluginslist=Llista
 ConfigView.section.queue.seeding=Sembrant
-ConfigView.section.queue.seeding.autoStarting=Auto-arrancar
-ConfigView.section.queue.seeding.ignore=Regles d'Ignorar
-ConfigView.section.queue.seeding.firstPriority=Primera Prioritat
+ConfigView.section.queue.seeding.autoStarting=Arrencant autom\u00e0ticament
+ConfigView.section.queue.seeding.ignore=Regles d'ignorar
+ConfigView.section.queue.seeding.firstPriority=Prioritat m\u00e0xima
 ConfigView.section.queue.main=Principal
-ConfigView.section.queue=En Cua
+ConfigView.section.queue=A la cua
 ConfigView.section.torrents=Torrents 
 ConfigView.text.all=tots
 ConfigView.text.hours=hores
-ConfigView.text.ignoreRule=Regles d'Ignorar
-ConfigView.text.ignore=Ignorar
+ConfigView.text.ignoreRule=Regles d'ignorar
+ConfigView.text.ignore=Ignora
 ConfigView.text.minutes=minuts
-ConfigView.text.neverIgnore=No Ignorar mai
+ConfigView.text.neverIgnore=No ignoris mai
 ConfigView.text.any=qualsevol
 DownloadManager.error.datamissing=Dades Perdudes
 MainWindow.menu.file.open.torrentforseeding=Fitxer torrent... (per sembrar)
-MainWindow.menu.language.refresh=&Refrescar
+MainWindow.menu.language.refresh=&Refresca
 ManagerItem.forced=For\u00e7at
-ManagerItem.queued=En Cua
+ManagerItem.queued=A la cua
 MySeedersView.header=Torrents complets
-TableColumn.header.availability.info=# c\u00f2pies completes que es veuen
+TableColumn.header.availability.info=Nre. de c\u00f2pies completes que es veuen
 TableColumn.header.availability=Disponibilitat
 TableColumn.header.category=Categoria
 MyTorrentsView.header=Torrents incomplets
-TableColumn.header.maxuploads=# M\u00e0x. Desc\u00e0rregues
-MyTorrentsView.menu.category.delete=&Esborra Categoria
-MyTorrentsView.menu.forceStart=&For\u00e7a Arrancar
-MyTorrentsView.menu.queue=En &Cua
-MyTorrentsView.menu.setCategory.add=&Afegir Categoria...
-MyTorrentsView.menu.setCategory=Assignar Categoria
+TableColumn.header.maxuploads=Nre. m\u00e0x. de desc\u00e0rregues
+MyTorrentsView.menu.category.delete=&Esborra la categoria
+MyTorrentsView.menu.forceStart=&For\u00e7a l'arrencada
+MyTorrentsView.menu.queue=A la &cua
+MyTorrentsView.menu.setCategory.add=&Afegeix una categoria...
+MyTorrentsView.menu.setCategory=Assigna una categoria
 TableColumn.header.savepath=Ruta de desada
-TableColumn.header.SeedingRank=Grau Sembrant
+TableColumn.header.SeedingRank=Grau de sembra
 TableColumn.header.totalspeed.info=Velocitat total de tots els iguals amb els quals esteu connectats
 TableColumn.header.totalspeed=Velocitat total
-splash.initializePlugins=Inicialitzant Complements
-StartStopRules.SPratioMet=LL:I Rati OK
-StartStopRules.FP0Peers=FP / 0 Iguals
-StartStopRules.0Peers=0 Iguals
-StartStopRules.numSeedsMet=# Llavors OK
-StartStopRules.ratioMet=Iguals:Llavor OK
-StartStopRules.shareRatioMet=Rati Compartir OK
+splash.initializePlugins=Inicialitzant els connectors
+StartStopRules.SPratioMet=R\u00e0tio llavors : iguals OK
+StartStopRules.FP0Peers=FP / 0 iguals
+StartStopRules.0Peers=0 iguals
+StartStopRules.numSeedsMet=Nre. de llavors OK
+StartStopRules.ratioMet=Iguals : llavor OK
+StartStopRules.shareRatioMet=R\u00e0tio de compartici\u00f3 correcte
 StartStopRules.waiting=Esperant
-StartStopRules.firstPriority=1a. Prioritat
+StartStopRules.firstPriority=1a prioritat
 ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Compartir Contingut (Recursiu)
-DownloadManager.error.unabletostartserver=No es pot arrancar el Servidor - comprobi la configuraci\u00f3 del port entrant / i els permisos del tallafocs per la aplicaci\u00f3 que actua com a servidor
-GeneralView.label.creationdate=Creat en : 
-ConfigView.section.tracker.announcescrapepercentage=Interval a Agafar com % d'edat de l'anunci\nex. 200 = 2:1. 0 = deixa decidir a l'Igual
+DownloadManager.error.unabletostartserver=No pot arrencar el servidor. Comproveula la configuraci\u00f3 del port entrant i els permisos del tallafocs per a l'aplicaci\u00f3 que actua com a servidor
+GeneralView.label.creationdate=Data de creaci\u00f3: 
+ConfigView.section.tracker.announcescrapepercentage=Interval de scrape com % d'edat de l'anunci\nex. 200 = 2:1. 0 = deixa decidir a l'igual
 ManagerItem.stopping=Aturant
-ConfigView.section.tracker.announcecacheperiod=Cach\u00e9 de l'anunci (milisegs)
-ConfigView.section.tracker.scrapecacheperiod=Cach\u00e9 d'Agafar(milisegs)
-ConfigView.section.tracker.scrapeandcache=Agafar i cach\u00e9
-ConfigView.section.tracker.announcecacheminpeers=Cach\u00e9 Anunci activa threshold de l'Igual
-fileDownloadWindow.retry=Reintentar
+ConfigView.section.tracker.announcecacheperiod=Mem\u00f2ria cau de l'anunci (mil\u00b7lisegons)
+ConfigView.section.tracker.scrapecacheperiod=Mem\u00f2ria cau de l'esb\u00f3s (mil\u00b7lisegons)
+ConfigView.section.tracker.scrapeandcache=Esbossa i desa a la mem\u00f2ria cau
+fileDownloadWindow.retry=Reintenta
 MyTrackerView.bytesin=Bytes Entrants
 MyTrackerView.bytesinave=Mitjana entrant
 MyTrackerView.bytesout=Bytes Sortint
 MyTrackerView.bytesoutave=Mitjana sortint
 ConfigView.section.file.max_open_files=Nre. m\u00e0xim de fitxers oberts per lectura/escriptura\n[0: il\u00b7limitat]
-ConfigView.section.file.max_open_files.tooltip=\u00datil si descarregueu torrents que contenen centenars/milers de ftixer, i esteu arribant al l\u00edmit dels gestors de ftixers del sistema operatiu.
-ConfigView.section.proxy=Intermediari
-ConfigView.section.proxy.enable_proxy=Activar intermediari a les comunicacions del rastrejador [reinciar requerit]
-ConfigView.section.proxy.host=Hoste
-ConfigView.section.proxy.username=Nom d'Usuari
-ConfigView.section.proxy.password=Mot clau
+ConfigView.section.file.max_open_files.tooltip=\u00c9s \u00fatil si descarregueu torrents que contenen centenars/milers de fitxers, i esteu arribant al l\u00edmit dels gestors de fitxers del sistema operatiu.
+ConfigView.section.proxy=Opcions del servidor intermediari
+ConfigView.section.proxy.enable_proxy=Activa un intermediari a les comunicacions del rastrejador [cal reinciar]
+ConfigView.section.proxy.host=Ordinador
+ConfigView.section.proxy.port=Port 
+ConfigView.section.proxy.username=Nom d'usuari
+ConfigView.section.proxy.password=Contrasenya
 ConfigView.section.proxy.enable_socks=Jo tinc un intermediari SOCKS
-wizard.createtorrent.extrahashes=Afegir hashes per altres xarxes (ex. Gnutella2, eDonkey2000)
+wizard.createtorrent.extrahashes=Afegeix resums per a altres xarxes (ex. Gnutella2, eDonkey2000)
 GeneralView.label.connected=connectats
 GeneralView.label.in_swarm=en eixam
 ManagerItem.initializing=Inicialitzant
@@ -890,76 +937,83 @@ AlertMessageBox.warning=Alerta
 AlertMessageBox.comment=Informaci\u00f3
 AlertMessageBox.information=Informaci\u00f3
 AlertMessageBox.unread=Teniu misstages d'alerta pendents de llegir. Feu clic aqu\u00ed per mostrar-los.
-SharedPortServer.alert.selectorfailed=No es pot establir l'escolta per les dades entrants.\nComprovi que la configuraci\u00f3 del tallafocs permet que java(w).exe actui com un 'servidor'
-Tracker.alert.listenfail=No es pot establir l'escolta en el port %1.\nComprobi que les altres aplicacions no estiguin fent servir ja aquest port.\nTambe comprobi que no hi hagi en marxa una altra copia d'Azureus.
+SharedPortServer.alert.selectorfailed=No es pot establir l'escolta per les dades entrants.\nComproveu que la configuraci\u00f3 del tallafocs permet que java(w).exe actui com un 'servidor'
+Tracker.alert.listenfail=No es pot establir l'escolta en el port %1.\nComproveu que les altres aplicacions no estiguin fent servir ja aquest port.\nComproveu tamb\u00e9 que no hi hagi en marxa una altra c\u00f2pia del Vuze
 DiskManager.alert.movefileexists=Error en moure els fitxers completats\nEl fitxer %1 ja existeix a la carpeta de destinaci\u00f3
 DiskManager.alert.movefilefails=Error en moure fitxers completats\nMoure el fitxer %1 ha fallat, %2
 DiskManager.alert.movefilerecoveryfails=Error recuperant despr\u00e9s de moure ha fallat\nRecuperaci\u00f3 del fitxer %1 ha fallat, %2
 ConfigView.section.tracker.logenable=Apunta les estad\u00edstiques peri\u00f2diques al 'tracker.log'
 SpeedView.stats.title=Estats
+SpeedView.stats.total=Total 
 SpeedView.stats.session=Aquesta Sessi\u00f3
-SpeedView.stats.downloaded=Descarregat
+SpeedView.stats.session.tooltip=Total (protocol)
+SpeedView.stats.downloaded=Descarregat (protocol)
 SpeedView.stats.uploaded=Carregat (protocol)
-SpeedView.stats.uptime=Temps Pujant
+SpeedView.stats.ratio=R\u00e0tio
+SpeedView.stats.uptime=Temps de c\u00e0rrega
 SpeedView.stats.now=Ara
+SpeedView.stats.now.tooltip=Total (protocol)
 AutoMigration.useralert=Resultats de migraci\u00f3 autom\u00e0tica de fitxers/carpetes de configuraci\u00f3 d'usuari Vuze \n\n%1\nAlgunes fallades s'han de moure manualment.\nNO US OBLIDEU D'ACTUALITZAR LES C\u00d2PIES DE SEGURETAT DE LES CONFIGURACIONS SI LES HEU MOGUDES!
 #
 # > 2.0.8.0
 #
-OpenTorrentWindow.title=Obrir Torrent(s)
+OpenTorrentWindow.title=Obre el/s torrent/s
 OpenTorrentWindow.message=Experimental 
 OpenTorrentWindow.addFiles=&Afegeix fitxers
 OpenTorrentWindow.dataLocation=Ubicaci\u00f3 per desar dades:
-OpenTorrentWindow.startMode=Modus Afegir
-OpenTorrentWindow.startMode.queued=En Cua
+OpenTorrentWindow.startMode=Mode d'afegida
+OpenTorrentWindow.startMode.queued=A la cua
 OpenTorrentWindow.startMode.stopped=Aturat
-OpenTorrentWindow.startMode.forceStarted=For\u00e7ar Arrancar
+OpenTorrentWindow.startMode.forceStarted=For\u00e7a l'arrencada
 OpenTorrentWindow.addPosition=Posici\u00f3 de Cua
 OpenTorrentWindow.addPosition.first=Primer
 OpenTorrentWindow.addPosition.last=\u00daltim
 TableColumn.header.remaining.info=Quantitat que falta per descarregar
-TableColumn.header.remaining=Faltant
-ConfigView.section.tracker.enablecompact=Activar protocol d'anunci compacte
-ConfigView.section.tracker.enablekey=Activar pas de clau al rastrejador per seguretat millorada
-ConfigView.section.file.perf=Opcions Rendiment
+TableColumn.header.remaining=Falta
+ConfigView.section.tracker.enablecompact=Habilita el protocol d'anunci compacte
+ConfigView.section.tracker.enablekey=Habilita l'intercanvi de contrasenya al rastrejador per aconseguir seguretat millorada
+ConfigView.section.file.perf=Opcions de rendiment
 ConfigView.section.file.perf.explain=Av\u00eds - canvis sense sentit en aquests par\u00e0metres poden afectar negativament el rendiment de desc\u00e0rrega. Cal reiniciar.\nSi teniu us quedeu sense mem\u00f2ria, plantegeu-vos de limitar les connexions per torrent. (Consulteu la configuraci\u00f3 de la transfer\u00e8ncia.)
-ConfigView.section.file.max_open_files.explain=Obrint massa ftixers podeu causar problemes al sistema operatiu a causa dels recursos limitats com gestors de fitxes. Aix\u00f2 limita el nombre de ftixers oberts al mateix temps.
-popup.error.hide=Amagar
+ConfigView.section.file.max_open_files.explain=Si hi ha massa fitxers oberts el sistema operatiu pot tenir problemes a causa dels recursos limitats com els gestors de fitxes. Aix\u00f2 limita el nombre de fitxers que es poden obrir alhora.
+popup.error.hide=Amaga
 popup.error.details=Detalls
-ConfigView.section.style.colorOverrides=Sobreescriu Colors
-ConfigView.section.style.colorOverride.progressBar=Barra de Progr\u00e9s
-MainWindow.status.tooOld=\u00e9s vell, si us plau actualitza-ho
+ConfigView.section.style.colorOverrides=Sobreescriu els colors
+ConfigView.section.style.colorOverride.progressBar=Barra de progr\u00e9s
+ConfigView.section.style.colorOverride.error=Error 
+MainWindow.status.tooOld=\u00e9s vell, actualitzeu-lo.
 ConfigView.section.style.colorOverride.warning=Av\u00eds
-ConfigView.section.style.colorOverride.altRow=Files Alternades
+ConfigView.section.style.colorOverride.altRow=Files alternatives
 ConfigView.section.file.save.peers.enable=Desa les connexions amb iguals per reconnectar-hi f\u00e0cilment
 ConfigView.section.file.save.peers.max=M\u00e0xim iguals per desar [0: il\u00b7limitat]
+ConfigView.section.file.save.peers.pertorrent=per torrent 
 ConfigView.label.max_peers_per_torrent=Nre. m\u00e0xim de connexions per torrent [0: il\u00b7limitat]
 ConfigView.label.max_peers_total=Nre. m\u00e0xim de connexions globament [0: il\u00b7limitat]
-ConfigView.section.style.colorOverrides.reset=Restablir Color
-ConfigView.section.language.info=Quan s'activa, es far\u00e0 una comprovaci\u00f3 d'actualitzaci\u00f3 quan arrenca Azureus.
-ConfigView.section.language.enableUpdate=Permet l'actualitzaci\u00f3 Web
-ConfigView.section.language.UpdateURL=URL d'Actualitzaci\u00f3
-ConfigView.section.language.UpdateNow=Actualitza Ara!
+ConfigView.section.style.colorOverrides.reset=Reinicialitza els colors
+ConfigView.section.language.info=Quan s'activa, es far\u00e0 una comprovaci\u00f3 d'actualitzaci\u00f3 quan arrenca el Vuze.
+ConfigView.section.language.enableUpdate=Activa l'actualitzaci\u00f3 web
+ConfigView.section.language.UpdateURL=URL de l'actualitzaci\u00f3
+ConfigView.section.language.UpdateNow=Actualitza-ho ara
 Button.revert=Desfer
 MyTorrentsView.menu.changeDirectory=Canvia la carpeta de dades
 GenericText.column=columna
-MyTorrentsView.menu.thisColumn.remove=Treu Columna
-MyTorrentsView.menu.thisColumn.toClipboard=Copia Texte al Portapapers
+MyTorrentsView.menu.thisColumn.remove=Elimina la columna
+MyTorrentsView.menu.thisColumn.toClipboard=Copia el text al porta-retalls
 MyTorrentsView.menu.tracker=Rastrejador
 ConfigView.download.abbreviated=D: 
+ConfigView.upload.abbreviated=C:
 ConfigView.complete.abbreviated=C: 
 TableColumn.header.secondsseeding=Sembrant durant
 TableColumn.header.secondsseeding.info=Temps total que heu estat sembrant.
-TableColumn.header.secondsdownloading=Temps Enlla\u00e7
+TableColumn.header.secondsdownloading=Temps de desc\u00e0rrega
 TableColumn.header.secondsdownloading.info=Temps total que heu estat descarregant.
 ConfigView.section.tracker.udpversion=Versi\u00f3 Protocol UDP (1 or 2)
 window.updateswt.title=La seva Versi\u00f3 SWT \u00e9s massa vella!
-window.updateswt.text=La vostra Versi\u00f3 SWT \u00e9s massa antiga!\nSWT \u00e9s la llibreria gr\u00e0fica que fa servir el Vuze i la versi\u00f3 que teniu \u00e9s massa vella per funcionar amb aquesta versi\u00f3 del Vuze. Cliqueu el bot\u00f3 Fet per actualitzar el SWT.
+window.updateswt.text=La versi\u00f3 SWT que teniu \u00e9s massa antiga!\nSWT \u00e9s la llibreria gr\u00e0fica que fa servir el Vuze i la versi\u00f3 que teniu \u00e9s massa vella per funcionar amb aquesta versi\u00f3 del Vuze. Cliqueu al bot\u00f3 Fet per actualitzar el SWT.
 window.updateswt.status=Estat
 window.updateswt.failed=L'actualitzaci\u00f3 ha fallat. Premeu OK un altre cop per reiniciar.
-window.updateswt.status.downloading.updater=Descarregant el Modul Actualitzador
+window.updateswt.status.downloading.updater=Descarregant el m\u00f2dul actualitzador
 window.updateswt.status.finding=Buscant la ultima Versi\u00f3 SWT 
-window.updateswt.status.downloading=Descarregant la ultima Versi\u00f3 SWT 
+window.updateswt.status.downloading=Descarregant l'\u00faltima versi\u00f3 SWT 
 window.updateswt.status.done=Reiniciant
 window.updateswt.ok=D'acord
 window.updateswt.cancel=Cancel\u00b7la
@@ -968,207 +1022,212 @@ swt.updater.urlsgetter.downloading=Agafant una llista de miralls des de
 swt.updater.urlsgetter.platform=SWT per la plataforma : 
 window.updateswt.ignore=Ignora
 ConfigView.section.style.useFancyTabs=Fer Servir Etiquetes Extravagants
-splash.initializeGM=Inicialitzant el Gestor Global de Torrents
-splash.loadingTorrents=Carregant Torrents
-MyTorrentsView.menu.thisColumn.sort=&Classificar
-Scrape.status.error.badURL=URL Anunci no segueix les specifications d'Scrape.
+splash.initializeGM=Inicialitzant el gestor global de torrents
+splash.loadingTorrents=Carregant torrents
+splash.firstMessageNoI18N=(: Vuze :) 
+MyTorrentsView.menu.thisColumn.sort=&Classifica
+Scrape.status.error.badURL=L'URL d'anunci no segueix les especificacions d'Scrape.
 Scrape.status.error.nohash=No hi ha Hash a la resposta.
-Scrape.status.error.invalid=Resposta Invalida.
+Scrape.status.error.invalid=Resposta inv\u00e0lida.
 Scrape.status.nextScrapeAt=Seg\u00fcent scrape a %1
-Scrape.status.initializing=Esperant per Scrape
+Scrape.status.scraping=Fent l'esborrany...
+Scrape.status.initializing=Esperant el retall...
+Scrape.status.scraping.queued=Esborrany a la cua...
 ConfigView.label.minSpeedForActiveSeeding=No comptis el torrent complet com fent servir un canal si la velocitat \u00e9s per sota dels
 ConfigView.section.stats.exportpeers=Exportar detalls d'Iguals
-MainWindow.menu.view.irc.moved=Irc est\u00e0 disponible com un complement. Vegeu http://azureus.sourceforge.net/plugin_list.php. Quan l'hagueu instal\u00b7lat feu servir el men\u00fa Visualitzaci\u00f3 >Complements > IRC per accedir-hi.
-MyTrackerView.webui.contextmenu.copyurl=Copiar URL del torrent al portapapers
+MainWindow.menu.view.irc.moved=L'IRC est\u00e0 disponible com un connector. Vegeu http://plugins.vuze.com/plugin_list.php. Quan l'hagueu instal\u00b7lat feu servir el men\u00fa Visualitzaci\u00f3 > Connectos > IRC per accedir-hi.
+MyTrackerView.webui.contextmenu.copyurl=Copia la URL del torrent al porta-retalls
 ConfigView.section.file.torrent.ignorefiles=Fitxers per ignorar quan creem torrents\nex. .DS_Store;Thumbs.db
-Torrent.create.progress.ignoringfile=Ignorant fitxer
-ConfigView.section.style.useUnitsRateBits=Fer servir bits en comptes de bytes per valors de rati basats en byte (KiB/s->Kibit/s etc.)
-ConfigView.section.interface.resetassoc=Ref\u00e9s les associacions de ftixers a l'Explorador  (.torrent)
+Torrent.create.progress.ignoringfile=Ignorant el fitxer
+ConfigView.section.style.useUnitsRateBits=Fes servir bits en comptes de bytes per valors de r\u00e0tio basats en byte (KiB/s->Kibit/s etc.)
+ConfigView.section.interface.resetassoc=Ref\u00e9s les associacions de fitxers a l'Explorador  (.torrent)
 ConfigView.section.interface.resetassocbutton=Refer
 ConfigView.section.interface.checkassoc=Comprova les associacions de fitxers en comen\u00e7ar
 dialog.associations.title=Comprova Associaci\u00f3
 Button.yes=S\u00ed
 Button.no=&No 
-ConfigView.label.seeding.autoStart0Peers=Auto-arrancar tots els torrents completats amb 0 iguals
+ConfigView.label.seeding.autoStart0Peers=Arrenca autom\u00e0ticament tots els torrents completats amb 0 iguals
 ConfigView.label.seeding.autoStart0Peers.tooltip=Activeu-ho si voleu que el rastrejador sempre llisti les llavors per als torrents amb 0 iguals
 dialog.associations.prompt=El Vuze no \u00e9s l'applicaci\u00f3 per defecte per a fitxers BitTorrent.\nVoleu associar fitxers .torrent amb elVuze?
 dialog.associations.askagain=Comprova al comen\u00e7ar
-ConfigView.section.plugins.update=Actualitzaci\u00f3 de Complements
-Plugin.pluginupdate.enablecheck=Activa comprovaci\u00f3 d'Actualitzaci\u00f3 de Complements
+ConfigView.section.plugins.update=Actualitzaci\u00f3 dels connectors
+Plugin.pluginupdate.enablecheck=Habilita la comprovaci\u00f3 de l'actualitzaci\u00f3 dels connectors
 plugins.basicview.status=Estat:
 plugins.basicview.activity=Activitat:
 plugins.basicview.progress=Progr\u00e9s:
-plugins.basicview.log=Anotar
+plugins.basicview.log=Anota:
 ConfigView.label.maxdownloadspeed=KB/s m\u00e0x velocitat de desc\u00e0rrega global [0: il\u00b7limitat]
-splash.loadingTorrent=Carregant Torrent 
+splash.loadingTorrent=Carregant torrent 
 splash.of=de
-UpdateWindow.title=Actualitzador d'Vuze
-UpdateWindow.header=Els seg\u00fcents components necessiten una actualitzaci\u00f3 :
+ConfigView.section.plugins.irc=IRC 
+UpdateWindow.title=Actualitzador del Vuze
+UpdateWindow.header=Cal actualitzar els components seg\u00fcents:
 UpdateWindow.columns.install=Instal\u00b7la
 UpdateWindow.columns.name=Nom
 UpdateWindow.columns.version=Versi\u00f3
 UpdateWindow.columns.size=Mida
 UpdateWindow.cancel=Cancel\u00b7la
-UpdateWindow.quit=Sortir
-UpdateWindow.close=Tancar
-UpdateWindow.ok=Actualitzar
-UpdateWindow.restart=Reiniciar
+UpdateWindow.quit=Surt
+UpdateWindow.close=Tanca
+UpdateWindow.ok=Actualitza
+UpdateWindow.restart=Reinicia
 UpdateWindow.status.downloading=Descarregant
 UpdateWindow.status.done=Fet
 UpdateWindow.status.failed=Fallat
-UpdateWindow.status.restartNeeded=Requerit Reiniciar!
-ConfigView.pluginlist.broken=Trencat
-ConfigView.pluginlist.whereToPut=Poseu els complements espec\u00edfics de l'usuari a la seva carpeta a:
-ConfigView.pluginlist.whereToPutOr=Pels complements compartits feu servir:
-MainWindow.statusText.checking=Comprovant Actualitzacions
+UpdateWindow.status.restartNeeded=Cal reiniciar
+ConfigView.pluginlist.broken=Malm\u00e8s
+ConfigView.pluginlist.whereToPut=Poseu els connectors concrets de l'usuari a la carpeta corresponent a:
+ConfigView.pluginlist.whereToPutOr=Pels connectors compartits feu servir:
+MainWindow.statusText.checking=Comprovant les actualitzacions
 TableColumn.header.OnlyCDing4=NomesSembrant*
-TableColumn.header.OnlyCDing4.info=Quantitat de temps que el torrent ha estat nom\u00e9s sembrant. Exclueix el temps que el torrent estava descarregant (i sembrant).
-ConfigView.section.style.alternateTablePainting=Fes servir un m\u00e8tode alternatiu per pintar les columnes de taules gr\u00e0fiques (pot requerir un reinici)
-UpdateWindow.status.restartMaybeNeeded=Pot requerir Reiniciar
+TableColumn.header.OnlyCDing4.info=Quantitat de temps que el torrent nom\u00e9s s'ha estat sembrant. Exclou el temps que el torrent s'ha estat descarregant (i sembrant).
+UpdateWindow.status.restartMaybeNeeded=Pot caldre reiniciar
 ConfigView.pluginlist.shared=compartit
-PeersView.host=Nom Host
-PeersView.host.info=El nom de host de l'Igual, quan est\u00e0 disponible (pot afectar al rendiment)
-MainWindow.menu.help.whatsnew=Qu\u00e8 hi ha de Nou ?
-ConfigView.label.checkonstart=Comprovar l'\u00faltima versi\u00f3 quan Vuze arrenca
-ConfigView.label.periodiccheck=Cercar peri\u00f3dicament la ultima versi\u00f3
-ConfigView.label.opendialog=Autom\u00e0ticament obrir l'Ajudant de Actualitzaci\u00f3 quan hi ha una actualitzaci\u00f3 disponible
-MainWindow.updateavail=Cliqui aqu\u00ed per Actualitzacions
-MainWindow.status.latestversionunchecked=Comprovaci\u00f3 de Versi\u00f3 desactivada
+PeersView.host=Nom de l'ordinador
+PeersView.host.info=El nom de l'ordinador de l'igual, on est\u00e0 disponible (pot afectar el rendiment)
+MainWindow.menu.help.whatsnew=Qu\u00e8 hi ha de nou?
+ConfigView.label.checkonstart=Comprova l'\u00faltima versi\u00f3 quan el Vuze arrenqui
+ConfigView.label.periodiccheck=Cerca l'\u00faltima versi\u00f3 de manera peri\u00f2dica
+ConfigView.label.opendialog=Obre autom\u00e0ticament l'auxiliar d'actualitzaci\u00f3 quan hi hagi una actualitzaci\u00f3 disponible
+MainWindow.updateavail=Feu clic aqu\u00ed per a les actualitzacions
+MainWindow.status.unofficialversion=Vuze Beta 
+MainWindow.status.latestversionunchecked=Comprovaci\u00f3 de versi\u00f3 desactivada
 GeneralView.label.updatein.stopped=Aturat
-StartStopRules.menu.viewDebug=Veure Informaci\u00f3 de depuraci\u00f3
-ConfigView.section.style.doNotUseGB=No fer servir unitat GB
+StartStopRules.menu.viewDebug=Visualitza la informaci\u00f3 de depuraci\u00f3
+ConfigView.section.style.doNotUseGB=No facis servir la unitat GB
 ConfigView.section.style.doNotUseGB.tooltip=Si es marca, Vuze continuar\u00e0 fent servir MB incl\u00fas per mides m\u00e9s grans de 1024MB
-MainWindow.menu.help.plugins=Agafar Complements
-ConfigView.section.plugins.TrackerWeb=Web rastrejador
+MainWindow.menu.help.plugins=Aconsegueix connectors
+ConfigView.section.plugins.TrackerWeb=P\u00e0gina web del rastrejador
 ConfigView.section.tracker.enablecategories=Separar torrents per categoria
-health.explain.share=significa que el torrent \u00e9s allotjat o publicat
-ConfigView.section.tracker.createcert=Crear certificat auto-signat
-ConfigView.section.tracker.createbutton=Crear
-security.certcreate.title=Crear certificat auto-signat
-security.certcreate.intro=Aquest di\u00e0leg li deixa crear un certificat auto-signat
-security.certcreate.alias=Alies
+health.explain.share=significa que el torrent \u00e9s hostatjat o publicat
+ConfigView.section.tracker.createcert=Crea un certificat autosignat
+ConfigView.section.tracker.createbutton=Crea
+security.certcreate.title=Crea un certificat autosignat
+security.certcreate.intro=Aquest di\u00e0leg us deixa crear un certificat autosignat
+security.certcreate.alias=\u00c0lies
 security.certcreate.strength=For\u00e7a
-security.certcreate.firstlastname=Nom i Cognoms
-security.certcreate.orgunit=Unitat Organitzativa 
+security.certcreate.firstlastname=Nom i cognoms
+security.certcreate.orgunit=Unitat organitzativa 
 security.certcreate.org=Organitzaci\u00f3
-security.certcreate.city=Ciutat o Poble
-security.certcreate.state=Estat o Provincia
-security.certcreate.country=Codi pais de dues lletres
-security.certcreate.ok=Crear
+security.certcreate.city=Ciutat, poble o municipi
+security.certcreate.state=Estat o prov\u00edncia
+security.certcreate.country=Codi estatal de dues lletres
+security.certcreate.ok=Crea
 security.certcreate.cancel=Cancel\u00b7la
-security.certcreate.createok=Certificat creat satisfactoriament
+security.certcreate.createok=El certificat s'ha creat satisfact\u00f2riament
 security.certcreate.createfail=Ha fallat la creaci\u00f3 del certificat
 ConfigView.section.plugins.webui=Interf\u00edcie Swing Web
 ConfigView.section.plugins.xml_http_if=Intef\u00edcie XML/HTTP
-webui.passwordenable=Activar password
-webui.user=Nom de l'Usuari
-webui.password=Mot Clau
+webui.passwordenable=Habilita una contrasenya
+webui.user=Nom d'usuari
+webui.password=Contrasenya
+webui.port=Port 
+webui.protocol=Protocol 
 webui.homepage=P\u00e0gina Home (*)
 webui.rootdir=Carpeta arrel (*)
 webui.rootres=Recurs arrel (*)
-webui.mode=Modus (*)
-webui.mode.info=Modus pot ser\n\t"full"\t= disponibles totes les operacions (defecte)\n\t"view"\t= nomes veure (pero pot actualitzar la frequencia de refresc)
+webui.mode=Mode 
+webui.mode.info=El mode pot ser\n\t"full"\t= disponibles totes les operacions (defecte)\n\t"view"\t= nom\u00e9s veure (per\u00f2 pot actualitzar la freq\u00fc\u00e8ncia de refrescament)
 webui.access=Acc\u00e9s (*)
-webui.access.info=L'acc\u00e9s pot ser\n\t"local"\t= significant que nom\u00e9s pot connectar la m\u00e0quina local\n\t"totes"\t= acc\u00e9s no restringit (defecte)\n\tIP\t= ex. 192.168.0.2\t\t\tuna IP nom\u00e9s\n\tIP1-IP2\t= ex. 192.168.0.1-192.168.0.255\tinterval inclosiu de IPs
-GeneralView.label.maxdownloadspeed=M\u00e0x Desc\u00e0rrega
-Security.keystore.corrupt=Magatzem de claus '%1' no es pot carregar, si us plau borreu-lo i torni a crear o a importar els certificats
-Security.keystore.empty=Magatzem de claus \u00e9s buit. Si us plau crear un certificat auto-signat (vegi Eines->Opcions->Seguretat) o importi un certificat existent dintre de '%1'
-webui.restart.info=Els Canvis a parametres marcats amb un (*) requereixen reiniciar per tenir efecte
+webui.access.info=L'acc\u00e9s pot ser\n\t"local"\t = significa que nom\u00e9s pot connectar la m\u00e0quina local\n\t"totes"\t = acc\u00e9s no restringit (defecte)\n\tIP\t = ex. 192.168.0.2\t\t\tuna adre\u00e7a IP nom\u00e9s\n\tIP1-IP2\t = ex. 192.168.0.1-192.168.0.255\tinterval inclosiu d'adreces IP.
+GeneralView.label.maxdownloadspeed=M\u00e0x. desc\u00e0rrega
+Security.keystore.corrupt=Magatzem de claus '%1' no es pot carregar, esborreu-lo i torneu a crear o a importar els certificats
+Security.keystore.empty=El magatzem de claus \u00e9s buit. Creeu un certificat autosignat (vegeu: Eines > Opcions > Seguretat) o importeu un certificat existent a '%1'
 GeneralView.label.maxdownloadspeed.tooltip=Velocitat m\u00e0xima de desc\u00e0rrega [0: il\u00b7limitat]
-upnp.enable=Activar UPnP
-upnp.info=Universal Plug and Play (UPnP) permet el mapa autom\u00e0tic de ports en routers amb UPnP activat.
+ConfigView.section.UPnP=UPnP 
+upnp.enable=Habilita UPnP
+upnp.info=Plug and Play universal (UPnP) permet el mapa autom\u00e0tic de ports en routers amb UPnP activat.
 upnp.mapping.dataport=Port entrant de dades de l'Igual
 upnp.mapping.tcptrackerport=Port TCP del rastrejador
 upnp.mapping.udptrackerport=Port UDP del rastrejador
-upnp.alert.differenthost=UPnP: Mapejat de '%1' ha estat reservat per '%2' - si us plau seleccioni un port diferent
-upnp.alert.mappingok=UPnP: Mapejat de '%1' establert
-upnp.alert.mappingfailed=UPnP: Mapejat de '%1' fallat
-upnp.alertsuccess=Informa de mapejats satisfactoris
+upnp.alert.differenthost=UPnP: El mapatge de '%1' ha estat reservat per '%2'. Seleccioneu un altre port 
+upnp.alert.mappingok=UPnP: Mapatge de '%1' establert
+upnp.alert.mappingfailed=UPnP: Mapatge de '%1' fallat
+upnp.alertsuccess=Informa dels mapatges satisfactoris
 upnp.alert.lostdevice=UPnP: S'ha perdut la connexi\u00f3 al servei '%1' en el dispositiu UPnP '%2'
-upnp.grabports=Mapejar ports inclos si pertanyen a un altre ordinador
-upnp.refresh.label=Refrescar els mapejats
-upnp.refresh.button=Refrescar
-upnp.alert.mappinggrabbed=UPnP: Mapejat '%1' establert - agafat des de '%2'
+upnp.grabports=Fes un mapatge dels ports encara que pertanyin a un altre ordinador
+upnp.refresh.label=Refresca els mapatges
+upnp.refresh.button=Refresca
+upnp.alert.mappinggrabbed=UPnP: Mapatge '%1' establert - agafat des de '%2'
 upnp.mapping.tcpssltrackerport=Port TCP SSL del rastrejador
 upnp.alertothermappings=Informa de ports que pertanyen a altres ordinadors
 upnp.alertdeviceproblems=Informa de problemes amb el dispositiu UPnP
 upnp.wiki_link=P\u00e0gina Wiki del Vuze a UPnP
-ConfigView.pluginlist.coreplugins=S'han carregat els seg\u00fcents complements interns
+ConfigView.pluginlist.coreplugins=S'han carregat els connector interns seg\u00fcents:
 Peers.column.DLedFromOthers=Des d'altres
 Peers.column.DLedFromOthers.info=Quantitat de dades descarregades des d'altres mentre estaven connectats amb vosaltres
-Peers.column.UpDownRatio=Pujat:Baixat
+Peers.column.UpDownRatio=Carregat : descarregat
 Peers.column.UpDownRatio.info=R\u00e0tio d'iguals "Carregat : Descarregat"
 Peers.column.UpRatio=R\u00e0tio c\u00e0rrega
 Peers.column.UpRatio.info=R\u00e0tio d'iguals "Carregat meu : Carregat dels altres"
-upnp.releasemappings=Lliberar mapejats al tancar
-webui.upnpenable=Activar UPnP per aquest port (*)
+upnp.releasemappings=Allibera els mapatges quan tanquis
+webui.upnpenable=Habilita UPnP per aquest port (*)
 ConfigView.section.file.friendly.hashchecking=Comprovaci\u00f3 de hash amistosa
-ConfigView.section.file.friendly.hashchecking.tooltip=Un modus de comprovar el hash lleugerament mes lent, pero amb molt menys esfor\u00e7 de cpu/sistema.
+ConfigView.section.file.friendly.hashchecking.tooltip=Un mode de comprovaci\u00f3 del hash lleugerament m\u00e9s lent, per\u00f2 amb molt menys esfor\u00e7 de CPU/sistema.
 ConfigView.section.tracker.seedretention=M\u00e0xim de llavors retingudes per torrent [0: il\u00b7limitat] 
 ConfigView.section.tracker.seedretention.info=Nota: Les estad\u00edstiques de c\u00e0rrega es perdran per les llavors no retingudes
-ConfigView.section.tracker.port=Activar rastrejador en port HTTP
-ConfigView.section.tracker.sslport=Activar rastrejador en port HTTPS
-ConfigView.section.tracker.publicenable.info=Permet que els altres cre\u00efn torrents que fan servir el nostre rastrejador\nsense que nosaltres els allotgem o publiquem
-Button.clear=Netejar
-MainWindow.IPs.tooltip=\u00daltima actualitzaci\u00f3 de la llista de filtres: %1\nTotal IPFiltres a la llista - Nombre de IPs bloquejades/vetat/dolentes aquesta sessi\u00f3.\nDoble clic per detalls.
+ConfigView.section.tracker.port=Habilita el rastrejador al port HTTP
+ConfigView.section.tracker.sslport=Habilita el rastrejador al port HTTPS
+ConfigView.section.tracker.publicenable.info=Permet que els altres cre\u00efn torrents que fan servir el vostre rastrejador\nsense que els hostatgeu o publiqueu
+Button.clear=Neteja
+MainWindow.IPs.tooltip=\u00daltima actualitzaci\u00f3 de la llista de filtres: %1\nNre. total de filtres d'adreces IP a la llista - Nombre d'adreces IP bloquejades/vetades/dolentes durant aquesta sessi\u00f3.\nFeu doble clic per visualitzar-ne els detalls.
 ConfigView.section.ipfilter.list.banned=ha estat vetat
 ConfigView.section.ipfilter.list.baddata=ha enviat dades dolentes: vegades =
-Button.reset=Restablir
+Button.reset=Restableix
 ConfigView.section.ipfilter.bannedinfo=IPs que han enviat dades dolentes - vetat si excedeix els l\u00edmits
 ConfigView.section.ipfilter.blockedinfo=IPs que han estat bloquejades a causa dels filtres IP
-download.removerules.name=Regles de Treure
-download.removerules.unauthorised.info=Torrents no autoritzats s\u00f3n aquells que la resposta de l'anunci cont\u00e9 tant "not authoris(z)ed" o "unauthoris(z)ed" en la resposta de fallada
-download.removerules.unauthorised=Autom\u00e0ticament treure torrents no autoritzats
+download.removerules.name=Regles d'eliminaci\u00f3
+download.removerules.unauthorised.info=Els torrents no autoritzats s\u00f3n els que contenen "not authoris(z)ed" a la resposta de l'anunci o "unauthoris(z)ed" a la resposta de fallada.
+download.removerules.unauthorised=Elimina autom\u00e0ticament els torrents no autoritzats
 download.removerules.unauthorised.seedingonly=\tNom\u00e9s si est\u00e0 sembrant
 download.removerules.removed.ok=Eliminaci\u00f3 autom\u00e0tica del torrent '%1' satisfact\u00f2ria. S'ha fet a causa de les regles d'eliminaci\u00f3 de torrents.
-download.removerules.updatetorrents=Treure torrents d'actualitzaci\u00f3 d'Vuze si l'eixam ho requereix
-ConfigView.label.defaultstarttorrentsstopped=Afegir per defecte els nous torrents en estat aturat
-ConfigView.section.server.enableudp=Activa protocol UDP del rastrejador client.
+download.removerules.updatetorrents=Elimina els torrents d'actualitzaci\u00f3 del Vuze si l'eixam ho requereix
+ConfigView.label.defaultstarttorrentsstopped=Afegeix per defecte els nous torrents en estat aturat
+ConfigView.section.server.enableudp=Activa el protocol UDP del rastrejador client.
 upnp.mapping.dataportudp=Port UDP client rastrejador
-ConfigView.section.file.decoder.showlax=Mostrar codificacions menys normals
-ConfigView.section.file.decoder.showall=Considerar totes les codificacions possibles
-MainWindow.status.updowndetails.tooltip=Detalls de velocitat c\u00e0rrega/desc\u00e0rrega - Cliqueu al bot\u00f3 dret per canviar-ho i feu doble clic per obrir les estad\u00edstiques
-TrackerClient.announce.warningmessage=Rastrejador per '%1' ha tornat l'avis '%2'
-ConfigView.section.tracker.natcheckenable=Comprovi la connectivitat del 'port de dades entrant' i informi als iguals de fallades
+ConfigView.section.file.decoder.showlax=Mostra les codificacions menys normals
+ConfigView.section.file.decoder.showall=Considera totes les codificacions possibles
+MainWindow.status.updowndetails.tooltip=Detalls de velocitat c\u00e0rrega/desc\u00e0rrega. Cliqueu al bot\u00f3 dret per canviar-ho i feu doble clic per obrir les estad\u00edstiques
+TrackerClient.announce.warningmessage=El rastrejador per '%1' ha tornat l'av\u00eds '%2'
+ConfigView.section.tracker.natcheckenable=Comprova la connectivitat del 'port de dades entrant' i informa els iguals de fallades
 ConfigView.section.tracker.publishenabledetails=Publiqueu el fitxer torrent i els detalls dels iguals
 ConfigView.section.tracker.publishenablepeerdetails=Publiqui detalls dels Iguals
 MyTrackerView.badnat=NAT dolenta
 MyTrackerView.badnat.info=Llavors/Iguals que han fallat en comprovaci\u00f3 de NAT, si activada
 ConfigView.section.tracker.natchecktimeout=Comprova temps l\u00edmit (segons)
-ConfigView.section.file.perf.cache.enable=Activa cach\u00e9 de disc
-ConfigView.section.file.perf.cache.size=Mida del cach\u00e9 en %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
+ConfigView.section.file.perf.cache.enable=Habilita la mem\u00f2ria cau del disc
+ConfigView.section.file.perf.cache.size=Mida de la mem\u00f2ria cau %1
 MainWindow.menu.transfers=T&ransfer\u00e8ncies
-MainWindow.menu.transfers.startalltransfers=&Arrancar Tot
-MainWindow.menu.transfers.stopalltransfers=A&turar Tot
-MainWindow.menu.transfers.pausetransfers=&Pausa
-MainWindow.menu.transfers.resumetransfers=&Resumir
-ConfigView.label.experimental.osx.kernel.panic.fix=Arreglo experimental per kernel panics sobre sistemes dual-cpu OSX [requireix re-arrancar]
-SystemTray.menu.pausetransfers=Pausa Transfer\u00e8ncies
-SystemTray.menu.resumetransfers=Resumir Transfer\u00e8ncies
+MainWindow.menu.transfers.startalltransfers=&Arrenca-ho tot
+MainWindow.menu.transfers.stopalltransfers=A&tura-ho tot
+MainWindow.menu.transfers.pausetransfers=Fes una pausa
+MainWindow.menu.transfers.pausetransfers.keybinding.mac=Meta+. 
+MainWindow.menu.transfers.resumetransfers=&Repr\u00e8n
+ConfigView.label.experimental.osx.kernel.panic.fix=Arranjament experimental per kernel panics sobre sistemes dual-cpu OSX [requireix reinicialitzaci\u00f3]
+SystemTray.menu.pausetransfers=Fes una pausa a les transfer\u00e8ncies
+SystemTray.menu.resumetransfers=Repr\u00e8n les transfer\u00e8ncies
 ConfigView.section.file.truncate.too.large=Parteix els fitxers existents que s\u00f3n massa llargs
-ConfigView.section.file.perf.cache.trace=Apunta operacions del cach\u00e9 per prop\u00f2sits de diagnostic
-ConfigView.section.interface.enabletray=Activar la safata del sistema (es necessita reengegar)
+ConfigView.section.file.perf.cache.trace=Apunta les operacions de la mem\u00f2ria cau amb finalitat de diagnosi
+ConfigView.section.interface.enabletray=Habilita la safata del sistema [us caldr\u00e0 reiniciar]
 PeerManager.status.error=Error 
 Stats.title.full=Estad\u00edstiques
 TransferStatsView.title.full=Transfer\u00e8ncies
-CacheView.title.full=Cach\u00e9
+CacheView.title.full=Mem\u00f2ria cau
 CacheView.general.size=Mida total
 CacheView.general.inUse=En \u00fas
-CacheView.general.title=Info de cach\u00e9
+CacheView.general.title=Informaci\u00f3 de la mem\u00f2ria cau
 CacheView.reads.title=Lectures E/S
 CacheView.reads.fromFile=Des de fitxer
-CacheView.reads.fromCache=Des de Cach\u00e9
+CacheView.reads.fromCache=Des de la mem\u00f2ria cau
 CacheView.reads.hits=Encerts
 CacheView.writes.title=Escriptures E/S
-CacheView.writes.toCache=Cap a Cach\u00e9
+CacheView.writes.toCache=A la mem\u00f2ria cau
 CacheView.writes.toFile=Cap a fitxer
 CacheView.writes.hits=Desat
 CacheView.speeds.title=Transfer\u00e8ncia Dades
 CacheView.speeds.reads=Lectures
 CacheView.speeds.writes=Escriptures
-CacheView.speeds.fromCache=Des de/Cap a Cach\u00e9
+CacheView.speeds.fromCache=Des de/A la mem\u00f2ria cau
 CacheView.speeds.fromFile=Des de/Cap a fitxer
 CacheView.reads.#=Nre.
 CacheView.reads.amount=Quantitat
@@ -1176,240 +1235,241 @@ CacheView.reads.avgsize=Mida mitjana
 openUrl.referrer=P\u00e0gina referida a URL :
 openUrl.referrer.info=Nom\u00e9s necessari per llocs web que ho manen aix\u00ed
 ConfigView.label.maxuploadspeedseeding=KB/s m\u00e0x. velocitat c\u00e0rrega global quan nom\u00e9s estem sembrant [0: il\u00b7limitat]
-ConfigView.label.transfer.ignorepeerports=Ignorar Iguals amb aquests ports de dades (';' separats, p.ex. 0;25)
-ConfigView.section.proxy.enable_socks.peer=Activeu l'intermediari de comunicacions amb iguals (connexions sortints nom\u00e9s) [cal reiniciar]
-ConfigView.section.proxy.peer.informtracker=Informar al rastrejador dels l\u00edmits
+ConfigView.label.transfer.ignorepeerports=Ignora els iguals amb aquests ports de dades (';' separats, p.ex. 0;25)
+ConfigView.section.proxy.enable_socks.peer=Habilita l'intermediari de comunicacions amb iguals (connexions sortints nom\u00e9s) [cal reiniciar]
+ConfigView.section.proxy.peer.informtracker=Informa el rastrejador dels l\u00edmits
 ConfigView.section.proxy.socks.version=Versi\u00f3 SOCKS
 PiecesView.legend.written=Escrit
 PiecesView.legend.requested=Demanat
 PiecesView.legend.downloaded=Descarregat, pendent d'escriure
-PiecesView.legend.incache=Dades son al Cach\u00e9
+PiecesView.legend.incache=Les dades s\u00f3n a la mem\u00f2ria cau
 PiecesView.typeItem.0=Lent
 PiecesView.typeItem.1=R\u00e0pid
 PiecesView.type=Tipus
 Security.jar.tools_not_found=Signar JAR falla - 'tools.jar' no trobat a %1. Veure Eines->Opcions->Seguretat per detalls.
 Security.jar.signfail=Signar JAR falla - %1
-ConfigView.section.security.toolsinfo=El fitxers JAR signats es fan servir per suportar alguns complements, per exemple el Swing Web Interface (quan s'ha configurat per fer-ho).\nPer signar fitxers JAR cal tenir acc\u00e9s al fitxer 'tools.jar' prove\u00eft amb la instal\u00b7laci\u00f3 del Sun JDK (no JRE).\nSi nom\u00e9s teniu instal\u00b7lat el JRE, si us plau instal\u00b7leu el JDK.\nNormalment el Vuze us pot trobar el fitxer. De totes maneres, si falla podeu esciure el nom de la car [...]
+ConfigView.section.security.toolsinfo=El fitxers JAR signats es fan servir per suportar alguns connectors, per exemple el Swing Web Interface (quan s'ha configurat per fer-ho).\nPer signar fitxers JAR cal tenir acc\u00e9s al fitxer 'tools.jar' prove\u00eft amb la instal\u00b7laci\u00f3 del Sun JDK (no JRE).\nSi nom\u00e9s teniu instal\u00b7lat el JRE, si us plau instal\u00b7leu el JDK.\nNormalment el Vuze us pot trobar el fitxer. De totes maneres, si falla, podeu escriure el nom de la ca [...]
 ConfigView.section.security.toolsdir=Carpeta que cont\u00e9 'tools.jar'
-ConfigView.section.security.choosetoolssavedir=Seleccioni carpeta que cont\u00e9 'tools.jar'
+ConfigView.section.security.choosetoolssavedir=Seleccioneu la carpeta que cont\u00e9 'tools.jar'
 authenticator.torrent=Torrent 
-ConfigView.section.proxy.peer.same=Fer servir la mateixa configuraci\u00f3 d'intermediari per les comunicacions del rastrejador i dels Iguals
+ConfigView.section.proxy.peer.same=Fes servir la mateixa configuraci\u00f3 de l'intermediari per a les comunicacions del rastrejador i dels iguals
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=Nre. m\u00e0xim de connexions simult\u00e0nies sortint [0: desactivar sortida]
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Nombre m\u00e0xim de noves connexions sortints que Vuze ha d'intentar en tot moment.\nNOTA: WindowsXP Service Pack 2 (SP2) imposa un l\u00edmit per tot el sistema de 10 intents simultanis.\nEl valor per defecte \u00e9s 8. El valor 0 desactiva totalment les connexions sortints.
-ConfigView.section.file.perf.cache.size.explain=El cach\u00e9 es fa servir per reduir lectures i escriptures al disc. A menys que feu servir l'opci\u00f3 Java '-XX:MaxDirectMemorySize' per posar la mem\u00f2ria disponible per fer servir en cach\u00e9 i E/S de xarxa, heu de mantenir aquest valor almenys %1 per sota de la mida VM m\u00e0xima. La mida VM m\u00e0xima actual \u00e9s %2. Per instruccions sobre com canviar-ho, aneu a MemoryUsage a la Wiki a %3. Les fallades en fer servir config [...]
-MyTorrentsView.menu.setSpeed.unlimit=Sense limit
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Nombre m\u00e0xim de noves connexions sortints que el Vuze ha d'intentar sempre.\nNOTA: el WindowsXP Service Pack 2 (SP2) imposa un l\u00edmit per a tots els sistemas de 10 intents simultanis.\nEl valor per defecte \u00e9s de 8. El valor 0 desactiva totalment les connexions sortints.
+ConfigView.section.file.perf.cache.size.explain=La mem\u00f2ria cau es fa servir per reduir lectures i escriptures al disc. Si no \u00e9s que feu servir l'opci\u00f3 Java '-XX:MaxDirectMemorySize' per posar la mem\u00f2ria disponible per fer servir a la mem\u00f2ria cau i E/S de la xarxa, heu de mantenir aquest valor almenys %1 per sota de la mida VM m\u00e0xima. La mida VM m\u00e0xima actual \u00e9s %2. Per a instruccions sobre com canviar aquests valors, aneu a MemoryUsage a la Wiki a  [...]
+MyTorrentsView.menu.setSpeed.unlimit=No limitis
 MyTorrentsView.menu.setSpeed.unlimited=Il\u00b7limitat
-MyTorrentsView.menu.setSpeed.disable=Desactiva la c\u00e0rrega
-MyTorrentsView.menu.setSpeed.disabled=Desactivat
+MyTorrentsView.menu.setSpeed.disable=Inhabilita la c\u00e0rrega
+MyTorrentsView.menu.setSpeed.disabled=Inhabilitat
 MyTorrentsView.menu.setSpeed.in=entrada
 MyTorrentsView.menu.setSpeed.slots=canals de
 GeneralView.label.maxuploadspeed=M\u00e0x. c\u00e0rrega
-GeneralView.label.maxuploadspeed.tooltip=m\u00e0xima velocitat c\u00e0rrega [0 : il\u00b7limitat]
+GeneralView.label.maxuploadspeed.tooltip=velocitat m\u00e0xima dec\u00e0rrega [0: il\u00b7limitat]
 MyTorrents.items.UpSpeedLimit.disabled=No carreguis
 MyTorrents.items.UpSpeedLimit.unlimited=Il\u00b7limitat
 TableColumn.header.maxupspeed=M\u00e0x. velocitat c\u00e0rrega
 TableColumn.header.maxupspeed.info=Velocitat m\u00e0xima de c\u00e0rrega per torrent
-ConfigView.section.file.perf.cache.enable.write=Cach\u00e9 de dades en desc\u00e0rrega per redu\u00efr escriptures a disc i tamb\u00e9 redu\u00efr lectures demanades per comprovaci\u00f3 de peces
+ConfigView.section.file.perf.cache.enable.write=La mem\u00f2ria cau de les dades de desc\u00e0rrega serveix per reduir l'escriptura al disc i reduir tamb\u00e9 les lectures demanades per a la comprovaci\u00f3 de peces.
 ConfigView.section.file.perf.cache.enable.read=Fer lectures anticipades per reduir lectures a disc quan pujem dades
-ConfigView.section.tracker.separatepeerids=Fer servir identitats diferents per comunicaci\u00f3\ndel rastrejador i de dades
+ConfigView.section.tracker.separatepeerids=Fes servir altres identitats per a la comunicaci\u00f3\ndel rastrejador i de dades
 ConfigView.section.tracker.separatepeerids.info=Augmenta l'anonimat si descarreguem i sembrem an\u00f3nimament\nmentre fem servir una connexi\u00f3 no-an\u00f3nima del rastrejador
 ConfigView.section.interface.wavlocation=Ubicaci\u00f3 del fitxer .wav
 ConfigView.section.interface.wavlocation.info=Seleccioneu el fitxer .wav, o deixeu-ho en blanc pel so definit per defecte
 ConfigView.section.tracker.server=Servidor
-ConfigView.section.tracker.client.connecttimeout=Temps l\u00edmit Connexi\u00f3 (segons)
-ConfigView.section.tracker.client.readtimeout=Temps l\u00edmit Lectura (segons)
+ConfigView.section.tracker.client=Client 
+ConfigView.section.tracker.client.connecttimeout=Temps l\u00edmit de connexi\u00f3 (segons)
+ConfigView.section.tracker.client.readtimeout=Temps l\u00edmit de lectura (segons)
 MainWindow.menu.tools=&Eines
 FilesView.path=Ruta
 FilesView.fullpath=Mostra la ruta completa
 FilesView.remaining=Peces Faltants
-TableColumn.header.trackername=Nom del Rastrejador
-TableColumn.header.trackername.info=Nom del rastrejador basat en URL de l'anunci
+TableColumn.header.trackername=Nom del rastrejador
+TableColumn.header.trackername.info=Nom del rastrejador basat en la URL de l'anunci
 ConfigView.group.override=Opcions de sobreescriptura
-ConfigView.section.file.perf.cache.notsmallerthan=No feu cach\u00e9 de ftixers m\u00e9s petits que (en %1)
-PeersView.menu.blockupload=Bloquejar c\u00e0rrega
+ConfigView.section.file.perf.cache.notsmallerthan=No facis la mem\u00f2ria cau dels fitxers que siguin m\u00e9s petits que (en %1)
+PeersView.menu.blockupload=Bloca la c\u00e0rrega
 PeersView.menu.kickandban=Patejar i Bloquejar
 PeersView.menu.kickandban.reason=Igual bloquejat manualment
 PeersView.state=Estat
 PeersView.state.info=Estat de la connexi\u00f3 amb l'Igual
 PeersView.state.pending=Pendent
 PeersView.state.connecting=Connectant
-PeersView.state.handshake=Esperant per handshake
+PeersView.state.handshake=Esperant el handshake
 PeersView.state.established=Completament establert
 ConfigView.section.tracker.processinglimits=Processant l\u00edmits
 ConfigView.section.tracker.maxgettime=M\u00e0xim temps per processar GET (segons) [0: il\u00b7limitat]
 ConfigView.section.tracker.maxgettime.info=Usat per anuncis and scrapes
 ConfigView.section.tracker.maxposttimemultiplier=AGAFA multiplicador de temps per POST-processament [0: il\u00b7limitat]
 ConfigView.section.tracker.maxposttimemultiplier.info=Es fa servir per sotmetre formularis i c\u00e0rregues
-ConfigView.section.tracker.maxthreads=M\u00e0xim peticions concurrents
+ConfigView.section.tracker.maxthreads=Nre. m\u00e0xim de peticions concurrents
 DownloadManager.error.operationcancancelled=Operaci\u00f3 cancel\u00b7lada
 Torrent.create.progress.cancelled=Operaci\u00f3 cancel\u00b7lada
 sharing.progress.cancel=Cancel\u00b7la
 wizard.maketorrents.autoopen=Obre el torrent per sembrar quan completat
 ConfigView.section.sharing.rescanenable=Habilita el reescaneig peri\u00f2dic dels compartits per canvis
 ConfigView.section.sharing.rescanperiod=Periode de Re-scan (segons)
-ConfigView.section.connection.advanced=Opcions de xarxa avan\u00e7ades
-ConfigView.section.connection.advanced.mtu=Unitat M\u00e0xima Transmissi\u00f3 de la Linia (MTU)
-ConfigView.section.connection.advanced.mtu.tooltip=Mida m\u00e0xima d'un paquet que pot ser transferit en una frame sobre una xarxa.\nVuze fa servir MTU-40 (MSS) per optimitzacions de pujar packet-payload.\nValors recomanats:\n  576 - Conexions linia telef\u00f3nica\n1492 - Conexions banda ample PPPoE\n1500 - Conexions banda ample Ethernet, DSL i Cable
+ConfigView.section.connection.advanced=Opcions avan\u00e7ades de xarxa
+ConfigView.section.connection.advanced.url=http://wiki.vuze.com/w/UG_Options#Advanced_Network_Settings 
+ConfigView.section.connection.advanced.mtu=Unitat m\u00e0xima de transmissi\u00f3 de la l\u00ednia (MTU)
+ConfigView.section.connection.advanced.mtu.tooltip=Mida m\u00e0xima d'un paquet que pot ser transferit en una frame sobre una xarxa.\nVuze fa servir MTU-40 (MSS) per optimitzacions de pujar packet-payload.\nValors recomanats:\n  576 - Connexions l\u00ednia telef\u00f2nica\n1492 - Connexions banda ampla PPPoE\n1500 - Connexions banda ampla Ethernet, DSL i cable
 ConfigView.section.connection.advanced.SO_RCVBUF=Mida del s\u00f2col SO_RCVBUF [0: usar defalt OS]
 ConfigView.section.connection.advanced.SO_SNDBUF=Mida del s\u00f2col SO_SNDBUF [0: usar defalt OS]
-ConfigView.section.interface.confirm_torrent_removal=Mostra el di\u00e0leg de confirmaci\u00f3 quan esborris un torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmar quan s'esborri un torrent de la vista "Els meus Torrents".
-MyTorrentsView.confirm_torrent_removal=Est\u00e0 seguir de que el vol treure ?\n
-TableColumn.header.seed_to_peer_ratio.info=Rati Total de llavors a l'eixam per Iguals
-PeersView.connected_time=Temps Connectat
+TableColumn.header.seed_to_peer_ratio.info=Relaci\u00f3 total de llavors a l'eixam per iguals
+PeersView.connected_time=Temps de connexi\u00f3
 PeersView.connected_time.info=Temps Total connectat amb l'Igual
-ConfigView.section.interface.display.add_torrents_silently=Afegir torrents silenciosament
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Afegir desc\u00e0rregues de torrent sense activar la pantalla principal d'Vuze
-TableColumn.header.maxdownspeed=M\u00e0x Velocitat Desc\u00e0rrega
-TableColumn.header.maxdownspeed.info=M\u00e0x Velocitat Desc\u00e0rrega per torrent
-PeersGraphicView.title=Eixam
-ConfigView.section.tracker.passwordwebhttpsonly=Nom\u00e9s permetre acc\u00e9s via HTTPS
-TableColumn.header.torrentpath=Ubicaci\u00f3 Torrent
-TableColumn.header.torrentpath.info=Ubicaci\u00f3 del Torrent en disc
+TableColumn.header.maxdownspeed=Velocitat m\u00e0x. de desc\u00e0rrega
+TableColumn.header.maxdownspeed.info=Velocitat m\u00e0x. de desc\u00e0rrega per torrent
+PeersGraphicView.title.full=Eixam
+ConfigView.section.tracker.passwordwebhttpsonly=Permet nom\u00e9s l'acc\u00e9s via HTTPS
+TableColumn.header.torrentpath=Ubicaci\u00f3 del torrent
+TableColumn.header.torrentpath.info=Ubicaci\u00f3 del torrent al disc
 ConfigView.section.sharing.torrentcomment=Comentari per torrents generats
 ConfigView.label.copyanddeleteratherthanmove=Copia i esborra les dades originals en comptes de moure-les en una sola operaci\u00f3 - pot ajudar a evitar p\u00e8dues de dades en alguns sistemes de fitxers
-ConfigView.label.openstatsonstart=Obrir estad\u00edstiques al comen\u00e7ar
-swt.install.window.title=Complement instal\u00b7lador del Vuze
+ConfigView.label.openstatsonstart=Obre les estad\u00edstiques en comen\u00e7ar
+swt.install.window.title=Instal\u00b7lador de components i connectors del Vuze
 swt.install.window.ok=Instal\u00b7la
-swt.install.window.header=S'han seleccionat els components seg\u00fcents per a instal\u00b7laci\u00f3:
-swt.uninstall.window.title=Complement Treure d'Vuze
-swt.uninstall.window.ok=Treu
-swt.uninstall.window.header=Els seg\u00fcents components han sigut seleccionats per treure :
-installPluginsWizard.title=Instal\u00b7la complements
-installPluginsWizard.mode.title=Si us plau, trieu un m\u00e8tode d'instal\u00b7laci\u00f3
+swt.install.window.header=Els components seg\u00fcents s'han seleccionat per a la instal\u00b7laci\u00f3:
+swt.uninstall.window.title=Eliminador de component/connector del Vuze
+swt.uninstall.window.ok=Elimina
+swt.uninstall.window.header=Els components seg\u00fcents s'han seleccionat per a l'eliminaci\u00f3:
+installPluginsWizard.title=Instal\u00b7la els connectors
+installPluginsWizard.mode.title=Trieu un m\u00e8tode d'instal\u00b7laci\u00f3
 installPluginsWizard.mode.list=Per llista des de sourceforge.net
-installPluginsWizard.list.title=Llista de complements instal\u00b7lables
-installPluginsWizard.list.loading=Esperi Si us plau mentre es carrega la llista de complements.
-installPluginsWizard.list.loaded=Si us plau, trieu els complements que vol instal\u00b7lar.
+installPluginsWizard.list.title=Llista de connectors instal\u00b7lables
+installPluginsWizard.list.loading=Espereu mentre es carrega la llista dels connectors.
+installPluginsWizard.list.loaded=Trieu els connectors que voleu instal\u00b7lar.
 installPluginsWizard.list.name=Nom
 installPluginsWizard.list.version=Versi\u00f3
-installPluginsWizard.list.description=Descripci\u00f3 del Complement
+installPluginsWizard.list.description=Descripci\u00f3 del connector
 installPluginsWizard.finish.title=Instal\u00b7laci\u00f3 en progr\u00e9s
-installPluginsWizard.finish.explanation=Els complements seleccionats s'instal\u00b7laran fent sevir l'assistent d'actualitzaci\u00f3.\n\nSi us plau, tingueu paci\u00e8ncia, aix\u00f2 pot tardar un moment a apar\u00e8ixer.\n\nPer un informe de progr\u00e9s, feu doble clic a l'esquerra de la barra d'estat.
+installPluginsWizard.finish.explanation=Els connectors seleccionats s'instal\u00b7laran fent sevir l'auxiliar d'actualitzaci\u00f3.\n\nTingueu paci\u00e8ncia, aix\u00f2 pot tardar una estona a apar\u00e8ixer.\n\nPer visualitzar-ne un informe de progr\u00e9s, feu doble clic a l'esquerra de la barra d'estat.
 installPluginsWizard.details.loading=Carregant detalls, esperi si us plau ...
 installPluginsWizard.mode.file=Per fitxer
-installPluginsWizard.installMode.title=Si us plau trieu el tipus d'instal\u00b7laci\u00f3
-installPluginsWizard.installMode.user=Instal\u00b7la el(s) complement(s) nom\u00e9s per a mi
-installPluginsWizard.installMode.shared=Instal\u00b7la el(s) complement(s) per a tots els usuaris
-installPluginsWizard.file.title=Si us plau, trieu el complement que voleu  instal\u00b7lar
-installPluginsWizard.file.file=Ftixer:
-installPluginsWizard.file.invalidfile=El ftixer no \u00e9s un complement v\u00e0lid del Vuze.
-installPluginsWizard.file.browse=Trii...
-uninstallPluginsWizard.title=Desinstal\u00b7la complements
-uninstallPluginsWizard.list.title=Llista de complements instal\u00b7lats
-uninstallPluginsWizard.list.loaded=Si us plau, trieu els complements que voleu desinstal\u00b7lar.
+installPluginsWizard.installMode.title=Trieu el tipus d'instal\u00b7laci\u00f3
+installPluginsWizard.installMode.user=Instal\u00b7la el connector o els connectors nom\u00e9s per a mi
+installPluginsWizard.installMode.shared=Instal\u00b7la el connector o connectors per a tots els usuaris
+installPluginsWizard.file.title=Trieu el connector que voleu instal\u00b7lar
+installPluginsWizard.file.file=Fitxer:
+installPluginsWizard.file.invalidfile=El fitxer no \u00e9s un connector v\u00e0lid del Vuze.
+installPluginsWizard.file.no_such_file=No hi ha cap fitxer amb aquest nom.
+installPluginsWizard.file.browse=Trieu...
+uninstallPluginsWizard.title=Desinstal\u00b7la els connectors
+uninstallPluginsWizard.list.title=Llista dels connectors instal\u00b7lats
+uninstallPluginsWizard.list.loaded=Trieu els connectors que voleu desinstal\u00b7lar.
 installPluginsWizard.list.nullversion=No hi ha Versi\u00f3
 uninstallPluginsWizard.finish.title=Desinstal\u00b7laci\u00f3 en progr\u00e9s
-uninstallPluginsWizard.finish.explanation=Els components seleccionats seran desinstal\u00b7lats fent servir l'assistent d'actualitzaci\u00f3.
-MainWindow.menu.plugins.installPlugins=Assistent d'instal\u00b7laci\u00f3...
-MainWindow.menu.plugins.uninstallPlugins=Assistent de desinstal\u00b7laci\u00f3...
+uninstallPluginsWizard.finish.explanation=Els components seleccionats seran desinstal\u00b7lats fent servir l'auxiliar d'actualitzaci\u00f3.
+MainWindow.menu.plugins.installPlugins=Auxiliar d'instal\u00b7laci\u00f3...
+MainWindow.menu.plugins.uninstallPlugins=Auxiliar de desinstal\u00b7laci\u00f3...
 ConfigView.section.ipfilter.totalIPs=%1 IPs bloquejades en total, que \u00e9s el %2 de l'internet.
 update.instance.install=Comprovant la instal\u00b7laci\u00f3
 update.instance.uninstall=Comprovant la desinstal\u00b7laci\u00f3
-update.instance.update=Cercant Actualitzacions
-MainWindow.status.update.tooltip=Faci Doble-clic per informaci\u00f3 de progr\u00e9s
+update.instance.update=Cercant actualitzacions
+MainWindow.status.update.tooltip=Feu doble clic per a la informaci\u00f3 del progr\u00e9s
 updater.progress.window.title=Tasques actuals d'instal\u00b7laci\u00f3
-updater.progress.window.info=Premi 'Abortar' per acabar totes les feines pendents
-Button.abort=Abortar
-ConfigView.section.ipfilter.enablebanning=Vetar iguals que constantment envien dades dolentes
-Network.alert.acceptfail=Han ocurregud massa fallades seguides en el port %1, %2 - proc\u00e9s abandonat. Si us plau comprovi la configuraci\u00f3 del tallafocs per aquest port per assegurar-se de que est\u00e0 activat per rebre.
+updater.progress.window.info=Premeu 'Interromp' per acabar totes les feines pendents
+Button.abort=Interromp
+ConfigView.section.ipfilter.enablebanning=Veta els iguals que constantment envien dades dolentes
+Network.alert.acceptfail=Hi ha hagut massa fallades seguides al port %1, %2 - proc\u00e9s abandonat. Comproveu la configuraci\u00f3 del tallafocs per aquest port per assegurar-vos que est\u00e0 habilitat per rebre connexions.
 MyShares.column.category=Categoria
-UpdateWindow.restartLater=Reiniciar m\u00e9s tard
-MainWindow.menu.file.restart=Reiniciar Vuze
-MainWindow.dialog.restartconfirmation.title=Reiniciar Vuze
+UpdateWindow.restartLater=Reinicia m\u00e9s tard
+MainWindow.menu.file.restart=Reinicia el Vuze
+MainWindow.dialog.restartconfirmation.title=Reinicia el Vuze
 MainWindow.dialog.restartconfirmation.text=Segur que voleu reiniciar el Vuze?
-deletetorrent.message1=Esteu a punt d'esborrar el TORRENT per a:\n
-deletetorrent.message2=\nEsta segur de que vol seguir?
 ConfigView.label.prioritizemostcompletedfiles=D\u00f3na prioritat als fitxers m\u00e9s complets
-splash.plugin.init=Inicialitzant Complement: 
+splash.plugin.init=Inicialitzant el connector:
+splash.plugin.UIinit=Inicialitzant el connector GUI: %1  
 ConfigView.section.style.osx_small_fonts=Fer servir lletra petita [requireix reiniciar]
-ConfigView.section.tracker.tcpnonblocking=Fer servir E/S sense bloquejar per el proc\u00e9s TCP del rastrejador. Seleccionant aquesta opci\u00f3 requereix que la web del rastrejador vagi en un altre port. Experimental!
+ConfigView.section.tracker.tcpnonblocking=Fes servir E/S sense bloquejar per el proc\u00e9s TCP del rastrejador. Seleccionar aquesta opci\u00f3 requereix que la p\u00e0gina web del rastrejador vagi en un altre port. \u00c9s experimental!
 ConfigView.section.tracker.nonblocking=Opcions de No-bloquejar
-ConfigView.section.tracker.nonblockingconcmax=M\u00e0xim connexions concurrents [0: il\u00b7limitat]
+ConfigView.section.tracker.nonblockingconcmax=Nre. m\u00e0xim connexions concurrents [0: il\u00b7limitat]
 MyTorrentsView.menu.exportmenu=Exportar
 MyTorrentsView.menu.exporttorrent=Torrent... 
 ConfigView.group.scrape=Connexi\u00f3
-ConfigView.section.tracker.client.scrapeinfo=Desactivar scraping far\u00e0 que no funcionin moltes de les regles de cua dels torrents\nja que aquestes van segons la informaci\u00f2 de l'eixam recuperada per els rastrejadors d'scraping.
-ConfigView.section.tracker.client.scrapeenable=Activar scraping
-ConfigView.section.tracker.client.scrapestoppedenable=Fer Scrape dels torrents que no estan en marxa
-Scrape.status.disabled=Desactivar scraping
+ConfigView.section.tracker.client.scrapeinfo=Inhabilitar l'esborrany far\u00e0 que no funcionin moltes de les regles de cua dels torrents\nja que van d'acord amb la informaci\u00f3 de l'eixam recuperada pels rastrejadors d'esborranys.
+ConfigView.section.tracker.client.scrapeenable=Habilita l'esborrany
+ConfigView.section.tracker.client.scrapestoppedenable=Fes Scrape dels torrents que no estan en marxa
+Scrape.status.disabled=Retall inhabilitat
 MyTorrentsView.menu.explore=Mostra el fitxer
 MyTorrentsView.menu.explore._mac=Mostra-ho al cercador
 MyTorrentsView.menu.explore._windows=Mostra-ho a l'explorador
-wizard.maketorrents.autohost=Allotjar el torrent en el rastrejador intern
-ConfigView.label.overrideip=Establir IP enviada al rastrejador (NAT)
-ConfigView.label.overrideip.tooltip=Informar al rastrejador de diferents adreces IP que la que venen els paquets sortints- Deixi en blanc per no fer servir aquesta opci\u00f3.
+wizard.maketorrents.autohost=Hostatja el torrent al rastrejador intern
+ConfigView.label.overrideip=Estableix la IP enviada al rastrejador (NAT)
+ConfigView.label.overrideip.tooltip=Informa el rastrejador d'altres adreces IP de les quals provenen els paquets sortints. Deixeu-ho en blanc si no voleu fer servir aquesta opci\u00f3.
 ConfigView.section.connection.group.networks=Xarxes
-ConfigView.section.connection.group.networks.info=Seleccioni les xarxes permeses per defecte per transmissio de dades igual a igual
-ConfigView.section.connection.networks.prompt=Demani una seleccio quan s'afegeix una desc\u00e0rrega amb un rastrejador an\u00f2nim
-ConfigView.section.connection.networks.Public=Xarxa IP P\u00fablica (no an\u00f2nim)
+ConfigView.section.connection.group.networks.info=Seleccioneu les xarxes permeses per defecte per a la transmissi\u00f3 de dades igual a igual
+ConfigView.section.connection.networks.prompt=Demana una selecci\u00f3 quan s'afegeix una desc\u00e0rrega amb un rastrejador an\u00f2nim
+ConfigView.section.connection.networks.Public=Xarxa IP p\u00fablica (no an\u00f2nim)
 ConfigView.section.connection.networks.I2P=Xarxa I2P
-ConfigView.section.connection.networks.Tor=Xarxa 'The Onion Router (Tor)'
+ConfigView.section.connection.networks.Tor=Xarxa 'The Onion Router (TOR)'
 TableColumn.header.networks=Xarxes
 TableColumn.header.networks.info=Xarxes permeses per comunicaci\u00f3 de dades igual a igual
-Scrape.status.networkdisabled=Xarxa no activada
+Scrape.status.networkdisabled=Xarxa no habilitada
 ConfigView.section.tracker.server.group.networks=Xarxes
-ConfigView.section.tracker.server.group.networks.info=Seleccioni les Xarxes per les que el rastrejador acceptar\u00e0 Iguals
+ConfigView.section.tracker.server.group.networks.info=Selecciona les xarxes per les quals el rastrejador acceptar\u00e0 iguals
 window.networkselection.title=Selecci\u00f3 de xarxes
-window.networkselection.info=El torrent seg\u00fcent t\u00e9 rastrejador(s) que suporten les xarxes seg\u00fcents.\nSeleccioneu les que activem per comunicaci\u00f3 amb el rastrejador i els Iguals.\nSi un rastrejador an\u00f2nim que suporta clients p\u00fablics activa tant les xarxes an\u00f2nima com p\u00fablica.\nActivar la xarxa p\u00fablica t\u00e9 la conseq\u00fc\u00e8ncia \u00f2bvia de la p\u00e8rdua d'anonimat!
-plugins.basicview.clear=Netejar
-ConfigView.section.connection.group.peersources=Origens d'Iguals
+window.networkselection.info=El torrent seg\u00fcent t\u00e9 un rastrejador que suporta les xarxes seg\u00fcents o m\u00e9s d'un.\nSeleccioneu les que cal habilitar per comunicar al rastrejador i els iguals.\nSi es tracta d'un rastrejador an\u00f2nim que suporta clients p\u00fablics, habilita tant la xarxa an\u00f2nima com la xarxa p\u00fablica.\nHabilitar la xarxa p\u00fablica comporta \u00f2bviament perdre l'anonimat
+window.networkselection.description=Torrent:
+plugins.basicview.clear=Esborra
+ConfigView.section.connection.group.peersources=Origen dels iguals
 ConfigView.section.connection.group.peersources.info=Seleccioneu els or\u00edgens permesos per defecte per connexions amb iguals
 ConfigView.section.connection.peersource.Tracker=Des d'un rastrejador
-ConfigView.section.connection.peersource.DHT=Rastrejador Descentralitzat
-ConfigView.section.connection.peersource.PeerExchange=Prove\u00eft per un altre Igual
-ConfigView.section.connection.peersource.Plugin=Afegit per un complement
+ConfigView.section.connection.peersource.DHT=Rastrejador descentralitzat
+ConfigView.section.connection.peersource.PeerExchange=Prove\u00eft per un altre igual
+ConfigView.section.connection.peersource.Plugin=Afegit per un connector
 ConfigView.section.connection.peersource.Incoming=Connexi\u00f3 entrant
 PeersView.source=Origen
 PeersView.source.info=L'origen d'aquest igual
-TableColumn.header.peersources=Origens d'Iguals
-TableColumn.header.peersources.info=Or\u00edgens d'Iguals permesos per establir connexions entre iguals
+TableColumn.header.peersources=Or\u00edgens dels iguals
+TableColumn.header.peersources.info=Or\u00edgens dels iguals permesos per establir connexions entre iguals
 wizard.tracker.dht=Descentralitzat (clients Vuze nom\u00e9s)
 MyTorrentsView.menu.advancedmenu=Avan\u00e7at
 MyTorrentsView.menu.networks=Xarxes
-MyTorrentsView.menu.peersource=Origens d'Iguals
-ConfigView.section.sharing.permitdht=Permetre rastreig descentralitzat quan el rastrejador no \u00e9s disponible
+MyTorrentsView.menu.peersource=Origens dels iguals
+ConfigView.section.sharing.permitdht=Permet el rastreig descentralitzat quan el rastrejador noestigui disponible
 ConfigView.section.sharing.protocol=Protocol per a recursos compartits
 PeersView.Messaging=Missatges
-PeersView.Messaging.info=Suporta missatges API avan\u00e7ats.
+PeersView.Messaging.info=Indica quin sistema de missatgeria es fa servir.
 ConfigView.label.queue.newseedsmovetop=Mou els nous torrents complets davant de la llista de sembra.
-ConfigView.label.seeding.firstPriority.ignore.info=Vagi amb compte que fent servir aquestes regles pot fer aturar un torrent\ntant aviat com la desc\u00e0rrega acaba.
-ConfigView.label.seeding.firstPriority.ignore=Ignorar les anteriors regles de Primera Prioritat per:
+ConfigView.label.seeding.firstPriority.ignore.info=Aneu amb compte que fent servir aquestes regles perqu\u00e8 poden fer aturar un torrent\ntan bon punt acaba la desc\u00e0rrega.
+ConfigView.label.seeding.firstPriority.ignore=Ignora les regles de prioritat m\u00e0xima anteriors per:
 ConfigView.label.seeding.firstPriority.ignoreSPRatio=Torrents amb un rati Llavors a Iguals per sobre de
 ConfigView.label.seeding.firstPriority.ignore0Peer=Torrents amb 0 Iguals
-ConfigView.section.tracker.sendjavaversionandos=Envia versi\u00f3 Java i nom del Sistema Operatiu
-MagnetPlugin.contextmenu.exporturi=Copia URI Magnet al portapapers
-ConfigView.section.plugins.dht=Base de Dades Distribuida
-dht.info=Aquest complement soporta rastreix descentralitzat, aprart d'altres coses, - desactivant-lo pot redu\u00efr la seva habilitat per descarregar
-dht.enabled=Activa la base de dades distribuida
+ConfigView.section.tracker.sendjavaversionandos=Envia versi\u00f3 Java i nom del sistema operatiu
+MagnetPlugin.contextmenu.exporturi=Copia la URI Magnet al porta-retalls
+ConfigView.section.plugins.dht=Base de dades distribu\u00efda
+dht.info=Aquest connector suporta el rastreig descentralitzat, a m\u00e9s d'altres coses, - el fet inhabilitar-lo pot reduir la capacitat de desc\u00e0rrega
+dht.enabled=Habilita la base de dades distribu\u00efda
 dht.portdefault=Fes servir el port per defecte
-dht.port=Port UDP per la base de dades 
+dht.port=Port UDP per a la base de dades 
 dht.execute.command=Diagnosticar Ordre
-dht.execute.info=Premi aqu\u00ed per executar l'Ordre
-dht.execute=Executar
-dht.logging=Activar tra\u00e7a d'activitat
-ConfigView.section.plugins.dhttracker=Rastrejador Distribuit
-dhttracker.tracknormalwhenoffline=Nom\u00e9s rastrejar torrents normals quan el seu rastrejador no est\u00e0 disponible
+dht.execute.info=Premeu aqu\u00ed per executar l'ordre
+dht.execute=Executa
+dht.logging=Habilita la tra\u00e7a d'activitat
+ConfigView.section.plugins.dhttracker=Rastrejador distribu\u00eft
+dhttracker.tracknormalwhenoffline=Nom\u00e9s rastreja els torrents normals quan el rastrejador no estigui disponible
+ConfigView.section.file.nativedelete._mac=Fes servir la paperera quan suprimeixis fitxers
+ConfigView.section.file.nativedelete._windows=Mou els fitxers suprimits a la paperera de reciclatge
 ConfigView.section.logging.generatediagnostics=Generar
 ConfigView.section.logging.netinfo=Genera informaci\u00f3 de la xarxa
-ConfigView.section.logging.statsinfo=Genera informaci\u00f3 d'estats
+ConfigView.section.logging.statsinfo=Genera la informaci\u00f3 d'estat
 ConfigView.section.logging.generatediagnostics.info=Genera informaci\u00f3 de diagn\u00f2stic i copia al porta-retalls i el fitxer log, si es configura
 ConfigView.section.sharing.privatetorrent=Torrent privat - nom\u00e9s accepta iguals del tracker
 MainWindow.menu.tools.nattest=Prova &NAT / Tallafocs
-Button.apply=Aplicar
-Button.close=Tancar
+Button.apply=Aplica
+Button.close=Tanca
 window.welcome.title=Benvinguts a Vuze %1
 #file can be a URL or a path in the jar
-MainWindow.menu.help.releasenotes=Notes de la Distribuci\u00f3
-dht.reseed.label=Normalment no cal resembrar la dase de Dades Distribuida. Tanmateix, si hi ha un nombre baix de contactes aix\u00f2 pot fer-se servir per re-integrar-los.\nDeixu-ho ne blanc per no engegar amb iguals connectats, o b\u00e9 escriviu un IP i un port per tal d'expl\u00edcitament engegar des d'un igual connectat.
+window.welcome.file=/changelog.txt 
+MainWindow.menu.help.releasenotes=Notes de la versi\u00f3
+dht.reseed.label=Normalment no cal resembrar la base de dades distribu\u00efda, per\u00f2 si hi ha un nombre baix de contactes es pot fer servir per reintegrar-los. Deixeu-ho en blanc per no engegar amb iguals connectats, o b\u00e9 escriviu una IP i un port per tal d'engegar expl\u00edcitament des d'un igual connectat.
 dht.reseed.group=Resembrar
 dht.reseed.ip=Adre\u00e7a IP
 dht.reseed.port=Port 
 dht.reseed=Resembrar
-dht.reseed.info=Resembrar bse de dades
+dht.reseed.info=Resembra la base de dades
 dht.diagnostics.group=Diagn\u00f2stics
-DHTView.title.full=Base de Dades Dsitribu\u00efda
-DHTView.title.fullcvs=CVS de la Base de Dades Dsitribu\u00efda
+DHTView.title.full=Base de dades disitribu\u00efda
+DHTView.title.fullcvs=CVS de la base de dades distribu\u00efda
 DHTView.general.title=General 
 DHTView.general.uptime=Temps sembra:
 DHTView.general.users=Usuaris:
@@ -1418,7 +1478,7 @@ DHTView.general.leaves=Abandonaments:
 DHTView.general.contacts=Contactes:
 DHTView.general.replacements=Substitucions:
 DHTView.general.live=Vius:
-DHTView.general.unknown=Inconegut:
+DHTView.general.unknown=Desconegut:
 DHTView.general.dying=Moribunds:
 DHTView.transport.title=Detalls de Transport
 DHTView.transport.packets=Paquets
@@ -1427,23 +1487,27 @@ DHTView.transport.received=Rebuts
 DHTView.transport.sent=Tramesos
 DHTView.transport.in=De :
 DHTView.transport.out=Vers :
-DHTView.operations.title=Detalls Operatius
+DHTView.operations.title=Detalls operatius
 DHTView.operations.sent=Tram\u00e8s
 DHTView.operations.ok=D'acord
 DHTView.operations.failed=Fallida
 DHTView.operations.received=Rebut
 DHTView.operations.ping=Ping 
-DHTView.operations.findNode=Trobar Node
-DHTView.operations.findValue=Trobar Valor
-DHTView.operations.store=Emmegatzemar
+DHTView.operations.findNode=Cerca el node
+DHTView.operations.findValue=Cerca el valor
+DHTView.operations.store=Emmegatzema
 DHTView.activity.title=Activitat
 DHTView.activity.status=Estat
-DHTView.activity.status.true=En cua
+DHTView.activity.status.true=A la cua
 DHTView.activity.status.false=Funcionant
 DHTView.activity.type=Tipus
+DHTView.activity.type.1=Obtenci\u00f3 interna
+DHTView.activity.type.2=Obtenci\u00f3 externa
+DHTView.activity.type.3=Posada interna
+DHTView.activity.type.4=Posada externa
 DHTView.activity.target=Objectiu
 DHTView.activity.details=Detalls
-DHTView.db.title=Base de Dades
+DHTView.db.title=Base de dades
 DHTView.db.keys=Claus
 DHTView.db.values=Valors
 DHTView.db.local=Local 
@@ -1451,44 +1515,56 @@ DHTView.db.direct=Directe
 DHTView.db.indirect=Indirecte
 DHTView.db.divfreq=Div. Freq.
 DHTView.db.divsize=Div. Mida
-MainWindow.dht.status.tooltip=Quan funciona la Base de Dades Distribu\u00efda es mostra le nombre estimat d'usuaris actuals
-MainWindow.dht.status.disabled=Inhbilitat
-MainWindow.dht.status.failed=Fallida
-MainWindow.dht.status.initializing=Inicialitzaci\u00f3
-MainWindow.dht.status.users=%1 Usuaris
+MainWindow.dht.status.tooltip=Quan funciona la base de dades distribu\u00efda es mostra el nombre estimat d'usuaris actuals
+MainWindow.dht.status.disabled=DHT inhbilitat
+MainWindow.dht.status.failed=Fallada de DHT
+MainWindow.dht.status.initializing=Inicialitzaci\u00f3 de DHT
+MainWindow.dht.status.users=%1 usuaris
 MainWindow.dht.status.unreachable=Tallafocs DHT
-MainWindow.dht.status.unreachabletooltip=Sembla que hi ha un problema amb la correspond\u00e8ncia de ports (NAT) UDP  de la Base de Dades Distribu\u00efda
+MainWindow.dht.status.unreachabletooltip=Sembla que hi ha un problema amb la correspond\u00e8ncia de ports (NAT) UDP  de la base de dades distribu\u00efda
+MyTorrentsView.menu.setUpSpeed=Estableix la velocitat de c\u00e0rrega
+MyTorrentsView.menu.setDownSpeed=Estableix la velocitat de desc\u00e0rrega
 ConfigView.section.tracker.client.showwarnings=Mostrar missatges d'av\u00eds declarats pels trackers
-dht.advanced=Habilitar cofiguraci\u00f3 avan\u00e7ada
+dht.advanced=Habilita la configuraci\u00f3 avan\u00e7ada
 dht.advanced.group=Configuraci\u00f3 avan\u00e7ada
-dht.advanced.label=Nom\u00e9s si sabeu el que us feu podeu modificar-ne els valors
-dht.override.ip=Substituir adre\u00e7a externa IP
+dht.advanced.label=Modifiqueu-ne els valors nom\u00e9s si sabeu exactament qu\u00e8 esteu fent
+dht.override.ip=Substitueix l'adre\u00e7a externa IP
 ConfigView.section.logging.loggerenable=Habilita el registre
-ConfigView.section.ipfilter.blockbanning=Prohibir un bloc de 256 adreces quan altres tantes del bloc ja han estat prohibides
+ConfigView.section.ipfilter.blockbanning=Prohibeix un bloc de 256 adreces quan altres tantes del bloc ja han estat prohibides
 MyTrackerView.passive=Passiu
-TableColumn.header.swarm_average_speed=Velocitat Mitjana Eixam
+TableColumn.header.swarm_average_speed=Velocitat mitjana de l'eixam
+TableColumn.header.swarm_average_speed.info=Velocitat mitjana dels iguals a l'eixam
+TableColumn.header.comment=Comenta
+TableColumn.header.commenticon=Icona de comentari
 MyTrackerView.category=Categoria
-MainWindow.menu.file.open.torrentfortracking=Fitxer Torrent File... (Nom\u00e9s Tracking)
+MainWindow.menu.file.open.torrentfortracking=Fitxer torrent... (nom\u00e9s tracking)
+VivaldiView.title.full=Vivaldi 
+VivaldiView.title.fullcvs=Vivaldi CVS 
+VivaldiView.title.full_v6=Vivaldi IPv6 
 MyTrackerView.date_added=Afegit
 ConfigView.section.tracker.portbackup=Ports de c\u00f2pia de seguretat (seprats amb ';' )
-ConfigView.label.playfilespeech=Paralr quan  s'ha acabat el fitxer
-ConfigView.label.playfilefinished=Fer un so quan s'ha acabat el fitxer
-ConfigView.label.backupconfigfiles=Fer c\u00f2pia de seguretat dels fitxers de configuraci\u00f3 per tal de poder fer llur recuperaci\u00f3
-ConfigView.section.tracker.client.scrapesingleonly=Inhabilitar agregaci\u00f3 scrape per tracker scrape (pot fer servei amb trackers que declaren  errors  'URL masa llarga' (414)) 
-dht.ipfilter.log=Enregistrar violacions del Filtre IP
-ActivityView.legend.limit=L\u00edmit ratio
-ActivityView.legend.achieved=Ratio assolida
+ConfigView.label.playfilespeech=Parla quan s'hagi acabat el fitxer
+ConfigView.label.playfilefinished=Fes un so quan s'ha enllestit el fitxer
+ConfigView.label.backupconfigfiles=Fes una c\u00f2pia de seguretat dels fitxers de configuraci\u00f3 per tal de poder-los recuperar
+ConfigView.section.tracker.client.scrapesingleonly=Inhabilita la suma de raspats per rastrejador (pot ser \u00fatil amb rastrejadors que presenten l'error (414) 'URL massa llarga') 
+dht.ipfilter.log=Enregistra les violacions del filtre d'adreces IP
+ConfigView.label.seeding.addForSeedingDLCopyCount=Considereu les desc\u00e0rregues 'afegides per a la sembra' per tenir descarregat aquest nombre de c\u00f2pies
+ActivityView.legend.limit=L\u00edmit de la r\u00e0tio
+ActivityView.legend.achieved=R\u00e0tio assolida
+ActivityView.legend.overhead=R\u00e0tio elevada
 ActivityView.legend.peeraverage=Mitjana
-ActivityView.legend.swarmaverage=Mitjana eixam
+ActivityView.legend.swarmaverage=Mitjana de l'eixam
 ActivityView.legend.trimmed=Retallat (suspensius)
-MyTorrentsView.menu.movemenu=Mou fitxers
+MyTorrentsView.menu.movemenu=Mou els fitxers
 MyTorrentsView.menu.movedata=Mou fitxers de dades...
 MyTorrentsView.menu.movetorrent=Mou fitxers torrent...
+MyTorrentsView.menu.movedata.dialog=Tria una localitzaci\u00f3 nova
 DHTView.operations.data=Dades
 DHTView.general.reachable=A l'abast:
 DHTView.general.rendezvous=Cites:
 ConfigView.label.queue.maxactivetorrentswhenseeding=M\u00e0xim quan sembreu [0:sense l\u00edmit]
-Views.plugins.IRC.title=IRC - Suport T\u00e8cnic En L\u00ednia
+IrcView.title.short=IRC 
+Views.plugins.IRC.title=IRC - suport t\u00e8cnic en l\u00ednia
 Formats.units.persec=/s 
 Formats.units.TiB=TiB 
 Formats.units.Tibit=Tibit 
@@ -1505,12 +1581,12 @@ Formats.units.Mbit=Mbit
 Formats.units.KiB=KiB 
 Formats.units.Kibit=Kibit 
 Formats.units.kB=kB 
-Formats.units.KB=KB 
+Formats.units.KB=kB
 Formats.units.kbit=kbit 
 Formats.units.B=B 
 Formats.units.bit=bit 
-Formats.units.alot=Molt !!!
-ConfigView.section.ipfilter.persistblocking=Desar deatall d'IP entre execucions
+Formats.units.alot=Molt!!!
+ConfigView.section.ipfilter.persistblocking=Desa els detalls de les adreces IP entre execucions
 FilesView.menu.rename=Canviar Nom o Objectiu
 FilesView.menu.rename_only=Reanomena r\u00e0pidament
 FilesView.menu.retarget=Mou els fitxers
@@ -1522,38 +1598,58 @@ FilesView.rename.filename.title=Reanomena el fitxer
 FilesView.rename.filename.text=Tria un nom nou per al fitxer
 ConfigView.higher.mode.available=Hi ha m\u00e9s opcions disponibles a les configuracions d'usuari avan\u00e7at
 ConfigView.section.mode=Mode 
-ConfigView.section.mode.beginner.text=Tot el que necessiteu per descarregar torrents.\nUtilitzeu aquest mode si els voleu gestionar.
-ConfigView.section.mode.advanced.text=Acc\u00e9s a les prefer\u00e8ncies de la xarxa.\n this mode if you know what MTU or non blocking I/O are...
+ConfigView.section.mode.title=Compet\u00e8ncia de l'usuari
+ConfigView.section.mode.beginner=Principiant
+ConfigView.section.mode.beginner.wiki.definitions=Vocabulari b\u00e0sic de BitTorrent
+ConfigView.section.mode.intermediate=Intermedi
+ConfigView.section.mode.intermediate.wiki.host=Hostatjant fitxers
+ConfigView.section.mode.intermediate.wiki.publish=Publicant fitxers
+ConfigView.section.mode.advanced=Avan\u00e7at
+ConfigView.section.mode.advanced.wiki.main=P\u00e0gina principal Wiki
+ConfigView.section.mode.beginner.text=Tot el que necessiteu per descarregar torrents.\nFeu servir aquest mode si nom\u00e9s voleu gestionar els torrents.
+ConfigView.section.mode.intermediate.text=Accediu a les funcions del rastrejador.\nFeu servir aquesta funci\u00f3 si voleu crear el vostre propi rastrejador i hostatjar/publicar fitxers.
+ConfigView.section.mode.advanced.text=Accediu a la configuraci\u00f3 de la xarxa.\nFeu servir aquest mode si sabeu qu\u00e8 s\u00f3n la MTU o la I/O no bloquejant...
 Files.column.storagetype=Tipus Emmegatzematge
 Files.column.fileext=Tipus
 FileItem.storage.linear=Linial
-FileItem.storage.compact=Compacte
+FileItem.storage.compact=Compacta
 MessageBoxWindow.rememberdecision=Recordar-ne la decisi\u00f3
-ConfigView.section.interface.cleardecisions=Esborra la mem\u00f2iria d'opcions de di\u00e0leg
+ConfigView.section.interface.cleardecisions=Esborra la mem\u00f2ria d'opcions de di\u00e0leg
 ConfigView.section.interface.cleardecisionsbutton=Esborra
-configureWizard.welcome.usermodes=El par\u00e0metre efici\u00e8ncia d'usuari determinar\u00e0 el nivell de les opcions que es mostren a Eines > Opcions. Cal que el configureu adequadament.
-FilesView.skip.confirm.delete.text=Truncar fitxer '%1' per estalviar espai?
+ConfigView.section.interface.cleartrackers=Esborra els rastrejadors recordats
+ConfigView.section.interface.cleartrackersbutton=Esborra
+ConfigView.section.interface.clearsavepaths=Esborra els camins de desada recordats
+ConfigView.section.interface.clearsavepathsbutton=Esborra
+configureWizard.welcome.usermodes=El par\u00e0metre de compet\u00e8ncia de l'usuari determinar\u00e0 el nivell de les opcions que es mostren a Eines > Opcions. Cal que el configureu adequadament.
+FilesView.skip.confirm.delete.text=Voleu truncar el fitxer '%1' per estalviar espai?
 FilesView.rename.failed.title=Canvi de nom/objecctiu ha fet falla
 FilesView.rename.failed.text=L'operaci\u00f3 ha fallat, probablement a causa d'una selecci\u00f3 inv\u00e0lida d'objectiu
-diagnostics.log_found=El Vuze no s'ha aturat correctament. Si us plau, comproveu %1 per a ftixers d'anotacions de diagn\u00f2stics i considereu la possibilitat d'informar-ne a l'equip Vuze si \u00e9s el resultat d'un error d'aplicaci\u00f3.
-ManagerItem.paused=Pausa
-Utils.link.visit=Visiteu
+diagnostics.log_found=El Vuze no s'ha aturat correctament. Comproveu els fitxers de diagn\u00f2stic <A HREF="%1">diagnostic log files</A. A m\u00e9s llegiu l'article del wiki <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Disappears</A> per a m\u00e9s informaci\u00f3.
+ManagerItem.paused=En pausa
+Utils.link.visit=Visiteu els enlla\u00e7os
 ConfigView.section.connection.serverport.wiki=Ports recomanats
 ConfigView.section.transfer.speeds.wiki=Configuraci\u00f3 de velocitat \u00e9s bona
-installPluginsWizard.installMode.info.text=No cal tenir el m\u00f2duls d'Vuze nom\u00e9s aporten funcionalitats complement\u00e0ries, automatizaci\u00f3 i control remot.
-Views.plugins.Distributed.DB.title=BD Distribu\u00efda
-Views.plugins.Distributed.Tracker.title=Tracker Distribu\u00eft
-Views.plugins.Plugin.Update.title=Actualitzaci\u00f3 M\u00f2duls
-TableColumn.header.swarm_average_completion=Compelci\u00f3 Mitjana dels Iguals
-GeneralView.label.swarm_average_completion=Compleci\u00f3 Mitjana:
+installPluginsWizard.installMode.info.title=Informaci\u00f3
+installPluginsWizard.installMode.info.text=No cal tenir connectors perqu\u00e8 el Vuze funcioni correctament, nom\u00e9s aporten funcionalitats complement\u00e0ries per diversi\u00f3, automatitzaci\u00f3 i control remot.\nLlegiu les caracter\u00edstiques de cada connector abans de decidir-vos a instal\u00b7lar-lo.\nLa majoria dels connectors es poden provar se manera segura, per\u00f2 no cobrecarregueu la configuraci\u00f3 amb connector que no penseu fer servir. 
+Views.plugins.Distributed.DB.title=Base de dades distribu\u00efda
+Views.plugins.Distributed.Tracker.title=Rastrejador distribu\u00eft
+Views.plugins.Plugin.Update.title=Actualitzaci\u00f3 dels m\u00f2duls
+Views.plugins.UPnP.title=UPnP 
+TableColumn.header.swarm_average_completion=Compleci\u00f3 mitjana dels iguals
+TableColumn.header.swarm_average_completion.info=Percentatge mitj\u00e0 de compleci\u00f3 dels iguals a l'eixam
+GeneralView.label.swarm_average_completion=Compleci\u00f3 mitjana:
+GeneralView.label.swarm_average_completion.tooltip=Percentatge mitj\u00e0 de compleci\u00f3 d'iguals a l'eixam
+MainWindow.nat.status.unknown=NAT 
+MainWindow.nat.status.ok=El NAT \u00e9s correcte
 MainWindow.nat.status.tooltip.ok=NAT (TCP) correcte
-MainWindow.nat.status.tooltip.probok=NAT correcte,tanmateix no hi ha hagut recientment connexions TCP
+MainWindow.nat.status.probok=El NAT \u00e9s correcte?
+MainWindow.nat.status.tooltip.probok=L'accessibilitat \u00e9s correcta, encara que no hi ha hagut connexions TCP recents
 MainWindow.nat.status.bad=Tallafocs
 MainWindow.nat.status.tooltip.bad=Possible problema NAT (TCP), cal consultar el Wiki si persisteix
 plugin.installer.recommended.plugin=M\u00f2dul recomenat - feu consulta i instal\u00b7laci\u00f3 si cal
 LoggerView.pause=Atura el registre
 LoggerView.clear=Esborra
-LoggerView.filter=Filtre
+LoggerView.filter=Filtra
 LoggerView.filter.uncheckAll=Desmarca totes les categories
 LoggerView.filter.checkAll=Marca totes les categories
 LoggerView.loggingDisabled=El registre no est\u00e0 habilitat
@@ -1562,7 +1658,7 @@ ConfigView.section.logging.log1type=Rebut
 ConfigView.section.logging.log2type=Enviat
 ConfigView.section.logging.level=Nivell de registre
 ConfigView.section.logging.showLogsFor=Mostra %1 registres per a les categories seg\u00fcents:
-ConfigView.pluginlist.column.loadAtStartup=Carrega-ho en comen\u00e7ar
+ConfigView.pluginlist.column.loadAtStartup=Carrega'l en comen\u00e7ar
 ConfigView.pluginlist.column.type=Tipus
 ConfigView.pluginlist.column.type.perUser=Per usuari
 ConfigView.pluginlist.column.type.shared=Compartit
@@ -1570,20 +1666,32 @@ ConfigView.pluginlist.column.type.builtIn=Fet a
 ConfigView.pluginlist.column.name=Nom
 ConfigView.pluginlist.column.version=Versi\u00f3
 ConfigView.pluginlist.column.directory=Carpeta
-ConfigView.pluginlist.column.isOperational=Operativa?
+ConfigView.pluginlist.column.isOperational=Operatiu?
+PeersView.BlockView.Avail.Have=Tots dos en tenen
+PeersView.BlockView.Avail.NoHave=L'igual en t\u00e9; vosaltres, no
+PeersView.BlockView.NoAvail.Have=En teniu; l'igual, no
+PeersView.BlockView.NoAvail.NoHave=Tampoc no en t\u00e9
+PeersView.BlockView.Transfer=Transferint
+PeersView.BlockView.NextRequest=Propera sol\u00b7licitud
+PeersView.BlockView.title=Mapa de les peces
+PeersView.BlockView.AvailCount=Recompte de la disponibilitat
 MyTorrentsView.dialog.NumberError.title=Nombre inv\u00e0lid o irrecognoscible
 MyTorrentsView.dialog.NumberError.text=El nombre que heu introdu\u00eft \u00e9s inv\u00e0lid o no es reconeix
 MyTorrentsView.menu.manual=&Manual... 
 MyTorrentsView.menu.manual.per_torrent=Manual (per torrent) 
 MyTorrentsView.menu.manual.shared_torrents=Manual (entre torrents)
+MyTorrentsView.dialog.setSpeed.title=Defineix la velocitat %1 
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
+MyTorrentsView.dialog.setNumber.text=Introdu\u00efu el nombre %1 per canviar %2 a:
 MyTorrentsView.dialog.setNumber.upload=c\u00e0rrega
 MyTorrentsView.dialog.setNumber.download=descarrega
+MyTorrentsView.dialog.setNumber.inKbps=en %1
 OpenTorrentWindow.torrentLocation=Torrents per descarregar :\n(un fitxer torrent per l\u00ednia)
 OpenTorrentWindow.addFiles.URL=Afegeix &URL
 OpenTorrentWindow.addFiles.Folder=Afegeix &carpeta
 OpenTorrentWindow.addFiles.Clipboard=Afegeix del &porta-retalls
 OpenTorrentWindow.changeDestination=Canvia la destinaci\u00f3
+OpenTorrentWindow.fileList=Fitxers als torrents:
 OpenTorrentWindow.torrentTable.name=Nom
 OpenTorrentWindow.torrentTable.saveLocation=Desa la ubicaci\u00f3
 OpenTorrentWindow.fileTable.fileName=Nom fitxer
@@ -1593,156 +1701,431 @@ OpenTorrentWindow.startMode.seeding=Sembrant
 OpenTorrentWindow.fileList.changeDestination=Canvia la destinaci\u00f3
 OpenTorrentWindow.mb.badSize.title=Fitxer incompatible
 OpenTorrentWindow.mb.badSize.text='%1' no \u00e9s '%2' i no es pot fer servir per sembrar
+OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> ja s'ha afegit com a '%2'
+OpenTorrentWindow.mb.alreadyExists.default.name=Suport
 OpenTorrentWindow.mb.alreadyExists.title=Ja existeix
 OpenTorrentWindow.mb.openError.title=Error en obrir
 OpenTorrentWindow.mb.openError.text='%1' no es pot obrir:
 OpenTorrentWindow.torrent.remove=Elimina el torrent de la llista
-OpenTorrentWindow.torrent.options=Les caracter\u00edsitques seg\u00fcents s'aplicaran als torrents que seleccioneu a continuaci\u00f3:
+OpenTorrentWindow.torrent.options=La configuraci\u00f3 seg\u00fcent s'aplicar\u00e0 als torrents que seleccioneu a continuaci\u00f3:
 OpenTorrentWindow.xOfTotal=(%1 de %2)
-iconBar.open.tooltip=Obre un ftixer .torrent
+iconBar.open.tooltip=Obre un fitxer .torrent
 LocaleUtil.column.text=Text desconegut
 LoggerView.realtime=Actualitza-ho en temps real
+ConfigView.section.file.writemblimit=Nombre m\u00e0xim de peticions d'escriptura a la cua (a %1)
+ConfigView.section.file.writemblimit.explain=Quan la velocitat d'escriptura del disc \u00e9s m\u00e9s baixa que la velocitat de desc\u00e0rrega, aquest par\u00e0metre limita la quantitat de dades de la cua abans que la velocitat de desc\u00e0rrega disminueixi.
+ConfigView.section.file.readmblimit.explain=Aquest par\u00e0metre limita la quantitat de mem\u00f2ria que es far\u00e0 servir per emmagatzemar lectures que estan pendents de processar.
 Button.moveUp=Mou a&munt
 Button.moveDown=Mou a&vall
-ConfigView.notAvailableForMode=Aquesta secci\u00f3 \u00e9s per al mode %1 o superior. No est\u00e0 disponible per al mode %2.
+ConfigView.notAvailableForMode=Aquesta secci\u00f3 \u00e9s per al mode '%1' o superior. No est\u00e0 disponible per al mode '%2'.
 health.explain.error=S'ha proodu\u00eft un error amb aquest torrent. Vegeu la columna d'estat o or the tooltip on the icon for the error.
-MyTorrentsView.menu.clear_resume_data=Esborra les dades de resum
+GeneralView.label.trackerscrapeupdate=Rastrejador scrape
+PeersView.piece=Pe\u00e7a
+PiecesView.priority=Prioritat
+PiecesView.speed=Velocitat
+TableColumn.header.AvgAvail.info=Suma de la disponibilitat de peces entre el nombre de peces, dividit pel nombre de connexions 
+TableColumn.header.AvgAvail=Mitjana disponibles/pe\u00e7a
+MyTorrentsView.menu.checkfilesexist=Explora els fitxers exitents
+MyTorrentsView.menu.rescanfile=Comprova peri\u00f2dicament les peces incompletes
+MyTorrentsView.menu.clear_resume_data=Esborra les dades de represa
+Plugin.extseed.name=Llavors externes
+ConfigView.section.transfer.lan=LAN 
+ConfigView.section.transfer.lan.tooltip=Configuraci\u00f3 espec\u00edfica per a LAN
+ConfigView.section.transfer.lan.uploadrate=kB/s velocitat m\u00e0xima de c\u00e0rrega LAN [0: il\u00b7limitat]
+ConfigView.section.transfer.lan.downloadrate=kB/s velocitat m\u00e0xima de desc\u00e0rrega LAN [0: il\u00b7limitat]
+TorrentOptionsView.title.short=Opcions
+TorrentOptionsView.title.full=Opcions
+TorrentOptionsView.param.max.peers=Nombre m\u00e0xim de connexions [0: il\u00b7limitat]
+ConfigView.section.connection.encryption.require_encrypted_transport=Requereix transport encriptat
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=For\u00e7a l'\u00fas de les connexions encriptades amb altres iguals.
+ConfigView.section.connection.encryption.min_encryption_level=Nivell d'encriptaci\u00f3 m\u00ednim
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=Pla. La conformitat de connexi\u00f3 nom\u00e9s\nRC4. Flux de dades complet\nL'encriptaci\u00f3 m\u00e9s alta necessita m\u00e9s CPU.
 Peers.column.Encryption=Encriptaci\u00f3
 Peers.column.Encryption.info=Nivell d'encriptaci\u00f3 en \u00fas
-MainWindow.sr.status.tooltip.ok=R\u00e0tio de compartir %1 CORRECTE
-MainWindow.sr.status.tooltip.poor=R\u00e0tio de compartir %1 pobre: < 0,9
-MainWindow.sr.status.tooltip.bad=R\u00e0tio de compartir %1 dolent: < 0,5
-ConfigView.section.connection.encryption=Encritaci\u00f3 del transport
+ConfigView.section.connection.encryption.encrypt.info=Si l'encriptaci\u00f3 est\u00e0 habilitada no us podreu connectar als client cicompatibles si no configureu les opcions alternatives 
+ConfigView.section.connection.encryption.encrypt.info.link=Entreu per veure'n els detalls
+MainWindow.sr.status.tooltip.ok=R\u00e0tio de compartir %1 CORRECTA
+MainWindow.sr.status.tooltip.poor=R\u00e0tio de compartir %1 pobra: < 0,9
+MainWindow.sr.status.tooltip.bad=R\u00e0tio de compartir %1 dolenta: < 0,5
+ConfigView.section.style.status=\u00c0rea d'estat:
+ConfigView.section.style.status.show_sr=R\u00e0tio de compartici\u00f3
+ConfigView.section.style.status.show_nat=Estat del NAT
+ConfigView.section.style.status.show_ddb=Estat DDB
+ConfigView.section.style.status.show_ipf=Estat del filtre d'adreces IP
+ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Permet les connexions sortints no encriptades si l'intent de connexi\u00f3 encriptada falla
+ConfigView.section.connection.encryption.encrypt.fallback_incoming=Permet les connexions entrants no encriptades
+ConfigView.section.connection.encryption=Encriptaci\u00f3 del transport
 upnp.selectedinterfaces=Interf\u00edcies seleccionades (separades per ';', p.ex. eth0;eth1) [blanc: tot]
+ConfigView.section.style.defaultSortOrder=Criteri predetermiant d'ordenaci\u00f3
+ConfigView.section.style.defaultSortOrder.desc=Descendent
+ConfigView.section.style.defaultSortOrder.asc=Ascendent
+ConfigView.section.style.defaultSortOrder.flip=Fes l'oposat de l'ordre previ
+LoggerView.autoscroll=Despla\u00e7a autom\u00e0ticament
 Button.selectAll=Selecciona'ls tots
 Button.markSelected=Marca selecci\u00f3
 Button.unmarkSelected=Desmarca els seleccionats
+plugins.basicview.config=Configuraci\u00f3
 TorrentOptionsView.param.max.uploads=Nombre m\u00e0xim de buits de c\u00e0rrega  [m\u00ednm: 2]
-ConfigView.section.connection.advanced.info.link=Entra per als detalls
+MyTorrentsView.dialog.setPosition.title=Defineix la posici\u00f3
+MyTorrentsView.dialog.setPosition.text=Indrodu\u00efu la posici\u00f3 per definir els torrents seleccionats a:
+MyTorrentsView.menu.reposition.manual=Reposiciona...
+ConfigView.section.connection.advanced.info.link=Feu clic per veure'n els detalls
+ConfigView.section.connection.advanced.socket.group=Opcions del s\u00f2col
+ConfigView.section.connection.advanced.bind_port=Vincula-ho al port local [0: inhabilitat]
+ConfigView.section.connection.advanced.bind_port.tooltip=Les connexions de sortida del s\u00f2col es vincularan localment al port que heu proporcionat.\nHabilitar aquesta opci\u00f3 pot ajudar a la inestabilitat de l'encaminador NAT.
+ConfigView.section.proxy.group.tracker=Comunicacions del rastrejador
+ConfigView.section.proxy.group.peer=Comunicacions dels hom\u00f2legs
+Pieces.column.Requested=Sol\u00b7licitat
 Pieces.column.Requested.info=Mostra-ho si es poden fer m\u00e9s sol\u00b7licituds a la pe\u00e7a o no (*)
 MyTorrentsView.filter=Filtre:
 popup.error.hideall=Amagueu-ho tot
+ConfigView.section.style.dataStatsOnly=Mostra nom\u00e9s les dades estad\u00edstiques (amaga les estad\u00edstiques del protocol)
+ConfigView.section.style.separateProtDataStats=Mostra separadment les estad\u00edstiques de les dades i el protocol 'dades (protocol)'
 MyTorrentsView.dialog.setFilter.title=Modifica el filtre
 MyTorrentsView.dialog.setFilter.text=La secci\u00f3 %1 es filtrar\u00e0 segons el text que especifiqueu. Fer servir el s\u00edmbol | (barra vertical) per filtrar segons diverses frases. 
+MyTorrentsView.filter.tooltip=Feu servir el s\u00edmbol '|' per filtrar en diverses frases.\nCtrl+X per canviar entre els modes de cerca RegEx i els normals.\nEn el mode RegEx mode feu servir el prefix '!' per expressar 'no'.\nFeu servir el prefix amb\n\t'c:' per cercar comentaris\n\t't:' per als hostatjadors del rastrejador\n\t'f:' per cercar noms de fitxers
 MyTorrentsView.clearFilter.tooltip=Esborra el filtre
 MyTorrentsView.menu.filter=Llista de filtres...
 ConfigureWizard.language.choose=Tria una llengua de la llista seg\u00fcent:
+popup.closing.in=La finestra es tancar\u00e0 autom\u00e0ticament d'aqu\u00ed a %1 segons
+popup.more.waiting=%1 missatges m\u00e9s.
 # > 2402
+popup.next=> 
+popup.previous=< (%1) 
+popup.download.finished=Ha acabat la desc\u00e0rrega de "%1".
+popup.file.finished=Ha acabat la desc\u00e0rrega de "%1".
 ConfigView.auto=Autom\u00e0tic
-MainWindow.menu.view.plugins.logViews=Vistes de registre
+Plugin.localtracker.autoadd=Iguals expl\u00edcits
+Plugin.localtracker.networks.info=Considera locals les xarxes seg\u00fcents [xarxes separades per ';' per exemple 145.227.*.*]
+Plugin.localtracker.networks=Xarxes locals
+MainWindow.menu.view.plugins.logViews=Vistes de registre 
 SpeedView.stats.autospeed=Velocitat autom\u00e0tica de c\u00e0rrega
-SpeedView.stats.autospeed.disabled=Aquesta caracter\u00edsitca est\u00e0 deshabilitada (necessiteu el DHT) o no es fa servir (s'ha seleccionat la velocitat manual de c\u00e0rrega)
+SpeedView.stats.autospeed.disabled=Aquesta caracter\u00edsitca est\u00e0 inhabilitada (necessiteu el DHT) o no es fa servir (s'ha seleccionat la velocitat manual de c\u00e0rrega)
+SpeedView.stats.currentPing=Ping actual:
 ConfigView.pluginlist.unloadSelected=Descarrega la selecci\u00f3
-ConfigView.pluginlist.scan=Cerca nous complements
+ConfigView.pluginlist.scan=Cerca connectors nous
+ConfigView.section.transfer.autospeed=Autovelocitat (cl\u00e0ssic)
+ConfigView.section.transfer.autospeed.tooltip=Configuraci\u00f3 espec\u00edfica per a autovelocitat
+ConfigView.section.transfer.autospeed.info=L'autovelocitat ajusta autom\u00e0ticament la velocitat d'enviament per evitar sobrecarregar la connexi\u00f3 a la xarxa.\n\nAquesta opci\u00f3 nom\u00e9s s'aplicar\u00e0 quan la velocitat de c\u00e0rrega autom\u00e0tica sigui activa i quan la bse de dades distribu\u00efda tamb\u00e9 ho sigui.\n
+ConfigView.section.transfer.autospeed.minupload=%1 velocitat m\u00ednima de c\u00e0rrega
+ConfigView.section.transfer.autospeed.maxupload=%1 velocitat m\u00e0xima de c\u00e0rrega [0: il\u00b7limitada]
+ConfigView.section.transfer.autospeed.enableauto=Habilita durant la desc\u00e0rrega i la sembra
+ConfigView.section.transfer.autospeed.enableautoseeding=Habilita nom\u00e9s durant la sembra
 ConfigView.pluginlist.column.unloadable=No es pot carregar
+TableColumn.header.filesdone=Fitxers enllestits
+MagnetPlugin.decentral_backup_disabled=<c\u00f2pia de seguretat descentralitzada inhabilitada>
+MagnetPlugin.report.searching=cercant...
+MagnetPlugin.report.found=trobat %1
+MagnetPlugin.report.alive=%1 \u00e9s viu
+MagnetPlugin.report.dead=%1 \u00e9s mort
+MagnetPlugin.report.downloading=descarregant de %1
+MagnetPlugin.report.error=error %1 
 MagnetURLHandler.report.no_sources=no s'han trobat recursos per al torrent
 MagnetURLHandler.report.torrent_size=mida del torrent: %1
 MagnetURLHandler.report.percent=complet: %1%
 MagnetURLHandler.report.error=error %1 
-DHTTransport.report.request_all=demanant la transfer\u00e8ncia sencera de %1
+DHTTransport.report.request_all=demanant tota la transfer\u00e8ncia de %1
 DHTTransport.report.received_bit=rebut %1 de %2 des de %3
 DHTTransport.report.complete=complet
-DHTTransport.report.rerequest_all=tornant a demanar la transfer\u00e8ncia sencera de%1
+DHTTransport.report.timeout=temps d'espera, sense resposta de %1
+DHTTransport.report.rerequest_all=tornant a demanar tota la transfer\u00e8ncia de%1
 DHTTransport.report.rerequest_bit=tornant a demanar %1 de %2 des de %3
-DHTTransport.report.sending=enviant dades
+DHTTransport.report.timeout_some=temps d'espera, %1 paquets rebuts de %2 per\u00f2 incomplet
+DHTTransport.report.sending=enviant les dades
 DHTTransport.report.resending=reenviant dades
 DHTTransport.report.send_complete=enviament complet
+DHTTransport.report.send_timeout=envia el temps d'espera
+ConfigView.section.transfer.autospeed.enabledebug=Informaci\u00f3 de la depuraci\u00f3 del registre
+TableColumn.header.date_added=Data d'afegida
+TableColumn.header.date_added.info=Data en qu\u00e8 es va afegir el torrent
+ConfigView.section.file.hashchecking.smallestfirst=Torna a comprovar primer les desc\u00e0rregues m\u00e9s petites 
+platform.win32.baddll.info=El Vuze ha detectat la pres\u00e8ncia de '%1', que forma part de '%2' i se sap que provoca problemes greus com la fallada de l'aplicaci\u00f3 i un \u00fas alt de la CPU. Si en veieu, desinstal\u00b7leu el programari o configureu-lo perqu\u00e8 no afecti el Vuze. 
+platform.win32.baddll.niphk=Antivirus Norman
+platform.win32.baddll.nvappfilter=Tallafocs NVidia
+platform.win32.baddll.mclsp=Servei de privadesa de McAfee 
+platform.win32.baddll.InjHook12=Controlador de la r\u00e0tio del torrent
+upnp.ignorebaddevices.info=Dispositius ignorats actualment: %1
+upnp.ignorebaddevices.reset=Reinicialitza la llista de dispositius ignorats
+upnp.ignorebaddevices.reset.action=Reinicialitza
+TorrentOptionsView.param.max.uploads.when.busy=Velocitat de c\u00e0rrega m\u00e0xima en kB/s quan s'arribi al l\u00edmit de c\u00e0rrega global [0: inhabilitat]
 UpdateMonitor.messagebox.verification.failed.title=La verificaci\u00f3 de la instal\u00b7laci\u00f3 ha fallat
-UpdateMonitor.messagebox.verification.failed.text=La verificati\u00f3 de '%1' ha fallat: %2
+UpdateMonitor.messagebox.verification.failed.text=La verificaci\u00f3 de '%1' ha fallat: %2
 UpdateMonitor.messagebox.accept.unverified.title=Accepta la instal\u00b7laci\u00f3 no comprovada
-UpdateMonitor.messagebox.accept.unverified.text=No es pot comporvar que '%1' sigui un complement oficial del Vuze.\nSi no ho \u00e9s, NO continueu.\nEl voleu seguir instal\u00b7lant?
+UpdateMonitor.messagebox.accept.unverified.text=No es pot comporvar que '%1' sigui un connector oficial del Vuze.\nSi no ho \u00e9s, NO continueu.\nEl voleu seguir instal\u00b7lant?
 FileView.BlockView.title=Peces del fitxer
 FileView.BlockView.Done=Fet
 FileView.BlockView.Active=Actiu
+upnp.portchange.alert=Els ports seg\u00fcents han canviat per evitar problemes del dispositiu UPnP: %1 [port antic = %2] %3 [port antic = %4]
+ConfigView.section.proxy.username.info=Si el servidor intermediari demana autenticaci\u00f3 fins i tot quan no n'hi ha cap de definida, fes servir la cadena "<none>" com a nom d'usuari.
+MainWindow.menu.help.debug=Genera informaci\u00f3 de depuraci\u00f3 (registre de fallada)
 DownloadManager.error.badsize=Mida incorrecta
 ConfigView.section.NATPMP=NAT-PMP 
+ConfigView.section.tracker.host.addurls=Assegureu-vos que aquestes URL del restrejador estan presents als torrents hostatjats
 ConfigView.filter=cerca opcions aqu\u00ed
+ConfigView.section.file.defaultdir.section=Opcions per defecte de la carpeta
+ConfigView.section.file.defaultdir.ask=Directori per defecte:
+ConfigView.section.file.config.section=Opcions de configuraci\u00f3
+ConfigView.section.file.config.currentdir=Carpeta actual de configuraci\u00f3:
+TorrentOptionsView.param.reset.to.default=Estableix les opcions als valors per defecte
+TorrentOptionsView.param.reset.button=Reinicialitza
+natpmp.routeraddress=Adre\u00e7a de l'estaci\u00f3 [blanc: autom\u00e0tic]
+ConfigView.section.transfer.autospeed.maxinc=%1 augment m\u00e0xim per cicle
+ConfigView.section.transfer.autospeed.maxdec=%1 disminuci\u00f3 m\u00e0xima per cicle
+ConfigView.section.transfer.autospeed.enabledownadj=Habilita l'ajustament de la velocitat de desc\u00e0rrega
+ConfigView.section.transfer.autospeed.downadjratio=R\u00e0tio de velocitat de desc\u00e0rrega : c\u00e0rrega (per exemple, 2.0: vol dir que el l\u00edmit de la velocitat de desc\u00e0rrega \u00e9s el doble que el l\u00edmit de la velocitat de c\u00e0rrega)
+ConfigView.section.transfer.autospeed.reset=Reinicialitza els valors avan\u00e7ats
+ConfigView.section.transfer.autospeed.reset.button=Reinicialitza
 PeerColumn.activationCount=Iguals intentant connectar: %1
+PeersView.incomingreqcount=Sol. entrants
+PeersView.outgoingreqcount=Sol. sortints
+PeersView.outgoingreqcount.info=Recompte de les sol\u00b7licituds sortints que s'han fet per igual 
+upnp.mapping.dhtudp=Base de dades distribu\u00efda
+ConfigView.section.connection.nondata.udp.same=Fes servir el mateix port UDP per a la base de dades distribu\u00efda i el rastrejador UDP 
+ConfigView.section.connection.tcp.enable=Habilita TCP
+ConfigView.section.connection.udp.enable=Habilita UDP
+ConfigView.section.style.showiconbar=Mostra la barra d'eines
 MainWindow.menu.view.iconbar=Barra d'eines
-MyTorrentsView.menu.rename=Reanomena
+MyTorrentsView.menu.rename=Reanomena...
 MyTorrentsView.menu.rename.displayed=Canvia el nom que es mostra
+MyTorrentsView.menu.rename.save_path=Reanomena el cam\u00ed de desada
+AdvRenameWindow.title=Reanomena la desc\u00e0rrega
+AdvRenameWindow.message=Introdu\u00efu un nom per aquesta desc\u00e0rrega.
+AdvRenameWindow.rename.torrent=Reanomena el torrent
 MyTorrentsView.menu.rename.displayed.enter.title=Canvia el nom que es mostra
-MyTorrentsView.menu.rename.displayed.enter.message=Introdu\u00efu un nom nou per mostrar per aquesta desc\u00e0rrega.
+MyTorrentsView.menu.rename.displayed.enter.message=Introdueix un nom nou per mostrar per aquesta desc\u00e0rrega.
 MyTorrentsView.menu.edit_comment=Edita el comentari
-authenticator.savepassword=Recorda la contrasenya
+MyTorrentsView.menu.edit_comment.enter.title=Edita el comentari
+MyTorrentsView.menu.edit_comment.enter.message=Introdueix un comentari a aquesta desc\u00e0rrega.
+UIDebugGenerator.messageask.title=Generador de depuraci\u00f3
+UIDebugGenerator.messageask.text=Introdu\u00efu una descripci\u00f3 de l'errada de la qual esteu informant
+UIDebugGenerator.complete.title=Generaci\u00f3 de la depuraci\u00f3 completa
+ConfigView.section.style.showProgramIcon=Mostra la icona del programa a la columna del nom
+ConfigView.section.style.showProgramIcon.tooltip=Perqu\u00e8 els canvis siguin efectius pot ser que calgui tornar a obrir la visualitzaci\u00f3
+authenticator.savepassword=Recorda'm la contrasenya
 ConfigView.section.security.clearpasswords=Esborra les contrasenyes desades
 ConfigView.section.security.clearpasswords.button=Esborra
-Content.alert.notuploaded.title=Actualitzaci\u00f3 no completada
-Content.alert.notuploaded.text=L'actualitzaci\u00f3 de '%1' no s'ha completat. Si %2 ara, people will not be able to completely download your published work.\n\nSegur que voleu %2?
-Content.alert.notuploaded.multi.title=C\u00e0rregues no completes
-Content.alert.notuploaded.stop=atura
-Content.alert.notuploaded.quit=surt del Vuze
-ConfigView.label.please.visit.here=Entra per veure'n els detalls
+TorrentInfoView.torrent.encoding=Codificant el torrent
+TorrentInfoView.columns=Visualitza les columnes de la 'Biblioteca'
+progress.window.title=Operaci\u00f3 en funcionament
+progress.window.msg.filemove=Espereu que es completi el canvi d'ubicaci\u00f3 o de nom
+ConfigView.label.please.visit.here=Feu clic aqu\u00ed per veure'n els detalls
 OpenTorrentWindow.filesInfo=%1 de %2 es descarregar\u00e0.
 OpenTorrentWindow.diskUsage=%1 de %2
 ConfigView.label.openmytorrents=Obre 'Els meus torrents' en entrar
 ConfigView.label.open_transfer_bar_on_start=Obre la barra de transfer\u00e8ncia quan obris
+ConfigView.section.style.DNDalwaysInIncomplete=Mostra sempre els torrents amb els fitxers 'No el descarreguis' a la secci\u00f3 d'incomplets de la biblioteca {library.name}  
 OpenTorrentWindow.mb.noGlobalDestDir.title=Carpeta de destinaci\u00f3
 OpenTorrentWindow.mb.noGlobalDestDir.text=La carpeta de destinaci\u00f3 '%1' no \u00e9s v\u00e0lida.
 OpenTorrentWindow.mb.noDestDir.title=No s'ha trobat la carpeta de destinaci\u00f3
 OpenTorrentWindow.mb.noDestDir.text=La carpeta de destinaci\u00f3 '%1' per al torrent '%2' no existeix o no \u00e9s v\u00e0lida.
 OpenTorrentWindow.mb.notValid.title=Obre el torrent
-OpenTorrentWindow.mb.notValid.text=No es pot obrir el torrent '%1'. Si obriu en mode de sembra, si us plau assegureu-vos que el fitxer de dades torrent exsiteix.
+OpenTorrentWindow.mb.notValid.text=No es pot obrir el torrent '%1'. Si obriu en mode de sembra, assegureu-vos que el fitxer de dades torrent exsiteix.
 OpenTorrentWindow.mb.notTorrent.title=Obre el torrent
 OpenTorrentWindow.mb.notTorrent.text=No es pot obrir '%1'. no sembla que sigui un fitxer .torrent.\n\nAlgunes de les dades rebudes:\n%2
 ConfigView.label.pause.downloads.on.exit=Atura les desc\u00e0rregues quan surtis
-ConfigView.label.resume.downloads.on.start=Resumeix les desc\u00e0rregues en pausa en comen\u00e7ar despr\u00e9s de completar la inicialitzaci\u00f3
+ConfigView.label.resume.downloads.on.start=Repr\u00e8n les desc\u00e0rregues en pausa en comen\u00e7ar despr\u00e9s de completar la inicialitzaci\u00f3
+UIDebugGenerator.message.cancel.title=S'ha cancel\u00b7lat la generaci\u00f3 de la informaci\u00f3 de depuraci\u00f3
+ConfigView.section.connection.group.http=HTTP 
+ConfigView.section.connection.http.enable=Habilita
+ConfigView.section.connection.http.port=N\u00famero del port entrant
 window.update.noupdates.title=Resultats de cerca d'actualitzacions
 window.update.noupdates.text=No teniu actualitzacions pendents.\n\nFelicitats!
+ConfigView.label.mindownloads=Desc\u00e0rregues m\u00ednimes simult\u00e0nies
 UI.cannot_submit_blank_text=Hi has d'introduir un valor
-OpenTorrentWindow.mb.existingFiles.title=El(s) fitxer(s) ja existeix(en)!
+ConfigView.section.interface.alerts=Alertes
+ConfigView.label.popupdownloadadded=Mostra amb un anunci emergent que s'ha afegit una desc\u00e0rrega
+popup.download.added=S'ha afegit "%1" a la llista de desc\u00e0rrega.
+MessageBoxWindow.nomoreprompting=No m'ho tornis a preguntar
+TorrentOptionsView.param.max.seeds=Nombre m\u00e0xim de connexions de llavors [0: l\u00edmit de connexi\u00f3]
+TorrentOptionsView.param.alternative.value.enable=Alterna el valor quan sembris
+ConfigView.section.proxy.check.on.start=Comprova l'estat del servidor intermediari a l'inici
+TransferStatsView.legend.pingaverage=Mitjana
+TransferStatsView.legend.ping1=Objectiu 1
+TransferStatsView.legend.ping2=Objectiu 2
+TransferStatsView.legend.ping3=Objectiu 3
+ConfigView.section.interface.enabletray._mac=Habilita la icona de la barra d'estat [us caldr\u00e0 reiniciar]
+ConfigView.label.closetotray._mac=El tancament ho minimitza a la icona de la barra d'estat
+ConfigView.label.minimizetotray._mac=La minimitzaci\u00f3 minimitza a la icona de la barra d'estat
+OpenTorrentWindow.mb.existingFiles.title=El/s fitxer/s ja existeix/en!
+OpenTorrentWindow.mb.existingFiles.text=Alguns dels fitxers ja existeixen a la carpeta o carpetes de destinaci\u00f3 que heu especificat:\n\n%1\nSi continueu, el Vuze cercar\u00e0 els fitxers superiors per a les dades correctes i els sobreescriur\u00e0 si ho creu necessari.
+splash.unloadingTorrents=Descarregant els torrents
+splash.unloadingTorrent=Descarregant el torrent
+ConfigView.section.file.defaultdir.autorename=Reanomena autom\u00e0ticament les dades del torrent si els fitxers en cam\u00ed semblen diferents
 alert.raised.at.close=(Missatge d'un tancament anterior del Vuze)
+Plugin.trackerpeerauth.name=Autoritzaci\u00f3 del seguiment d'iguals
 Peers.column.maxupspeed=Vel. m\u00e0x. c\u00e0r.
 Peers.column.maxdownspeed=Vel. m\u00e0x. desc.
 MyTorrents.items.DownSpeedLimit.disabled=No descarregat
 Peers.column.lan=LAN 
+upnp.selectedaddresses=Adreces (';' separades, '-' prefix = denega, '+' = permet) [blanc: qualsevol]
 UpdateMonitor.messagebox.restart.title=Actualitzaci\u00f3 de programari
 UpdateMonitor.messagebox.restart.text=El Vuze acaba de completar una actaulitzaci\u00f3 important i s'ha de reiniciar per tal que la instal\u00b7laci\u00f3 es pugui completar.
+PiecesView.BlockView.Have=En t\u00e9
+PiecesView.BlockView.NoHave=No en t\u00e9
+PiecesView.BlockView.Header=%1 columnes, %2 files, %3 peces
+ConfigView.section.update.autodownload=Descarrega autom\u00e0ticament les actualitzacions i quan la instal\u00b7laci\u00f3 estigui a punt
 Peers.column.peer_id=ID d'igual
 Peers.column.peer_id.info=ID de l'igual en fromat lectura
 Peers.column.peer_byte_id=ID d'igual
 Peers.column.peer_byte_id.info=ID de l'igual en bytes
+Peers.column.handshake_reserved=Bytes reservats per a la conformitat de connexi\u00f3
+Peers.column.handshake_reserved.info=Indica quins bits reservats corresponen a la conformitat de connexi\u00f3 BT
 Peers.column.client_identification=Identificaci\u00f3 del client
 ConfigView.label.openbar.incomplete=Barres de desc\u00e0rrega: obre autom\u00e0ticament les desc\u00e0rregues
 ConfigView.label.openbar.complete=obre autom\u00e0ticament les llavors
+ConfigView.label.transferbar.remember_location=Recorda la darrera localitzaci\u00f3 de la barra de transfer\u00e8ncies
 MainWindow.menu.tools.speedtest=Prova de velocitat...
+speedtest.wizard.title=Prova de velocitat
+speedtest.wizard.run=Activa la prova de velocitat
 speedtest.wizard.test.mode.updown=c\u00e0rrega i desc\u00e0rrega
 speedtest.wizard.test.mode.up=c\u00e0rrega
+speedtest.wizard.test.mode.down=desc\u00e0rrega
 SpeedTestWizard.test.panel.currinfo=Provant l'amplada de banda BitTorrent.
 SpeedTestWizard.test.panel.label=Prova de velocitat del Vuze:
+SpeedTestWizard.test.panel.already.running=La prova ja funciona!
+SpeedTestWizard.test.panel.not.accepted=La sol\u00b7licitud de prova no s'ha acceptat:
+SpeedTestWizard.test.panel.abort=Interromp
+SpeedTestWizard.test.panel.abort.countdown=interromp la prova d'aqu\u00ed a:
+SpeedTestWizard.test.panel.test.countdown=la prova acabar\u00e0 d'aqu\u00ed a:
+SpeedTestWizard.test.panel.testfailed=La prova ha fallat
+SpeedTestWizard.test.panel.aborted=Prova interrompuda manualment
+SpeedTestWizard.test.panel.enc.label=Premeu aqu\u00ed per fer la prova amb encriptaci\u00f3:
+SpeedTestWizard.test.panel.standard=est\u00e0ndard
+SpeedTestWizard.test.panel.encrypted=encriptat
+SpeedTestWizard.set.upload.button.apply=Aplica
 SpeedTestWizard.set.upload.result=Resultat de l'\u00faltima prova
+SpeedTestWizard.set.upload.bytes.per.sec=kBytes/seg
 SpeedTestWizard.set.upload.bits.per.sec=bits/s
+SpeedTestWizard.finish.panel.title=Prova de velocitat finalitzada!
+SpeedTestWizard.finish.panel.click.close=Heu finalitzat l'auxiliar de la prova de velocitat. Cliqueu "Tanca" per sortir.
 SpeedTestWizard.finish.panel.max.upload=C\u00e0rrega m\u00e0x.:
+SpeedTestWizard.finish.panel.max.seeding.upload=C\u00e0rrega m\u00e0xima durant la sembra:
+SpeedTestWizard.finish.panel.max.download=Desc\u00e0rrega m\u00e0x.:
+SpeedTestWizard.finish.panel.enabled=habilitat
+SpeedTestWizard.finish.panel.disabled=inhabilitat
+SpeedTestWizard.abort.message.scheduled.in=prova planificada d'aqu\u00ed a... %1 segons
+SpeedTestWizard.abort.message.unsupported.type=Tipus de prova no campatible
+SpeedTestWizard.abort.message.manual.abort=Interromput manualment
+SpeedTestWizard.abort.message.scheduling.failed=La planificaci\u00f3 de la prova ha fallat
+SpeedTestWizard.abort.message.download.added=La desc\u00e0rrega %1 s'ha afegit durant la prova
+SpeedTestWizard.abort.message.execution.failed=L'execuci\u00f3 de la prova ha fallat
+SpeedTestWizard.abort.message.failed.peers=Ha fallat la connexi\u00f3 als iguals
+SpeedTestWizard.stage.message.requesting=sol\u00b7licitant la prova...
+SpeedTestWizard.stage.message.preparing=preparant la prova...
+SpeedTestWizard.stage.message.starting=iniciant la prova...
+SpeedTestWizard.stage.message.connect.stats=Estad\u00edstiques de la connexi\u00f3: iguals =%1, desc\u00e0rregues correctes = %2, c\u00e0rregues correctes = %3
 window.uiswitcher.text=Seleccioneu la interf\u00edcie d'usuari que s'adapti millor a les vostres necessitats.
-window.uiswitcher.NewUI.text=* Recomanat per a principiants i usuaris novells.\n\n* F\u00e0cil amb interf\u00edcie gr\u00e0fica intu\u00eftiva\n\n* Interf\u00edcie necess\u00e0ria per a poder publicar en la plataforma Vuze
+window.uiswitcher.NewUI.title=Vuze 
+window.uiswitcher.NewUI.text=* Recomanat per a principiants i usuaris novells.\n\n* F\u00e0cil amb interf\u00edcie gr\u00e0fica intu\u00eftiva\n\n* Interf\u00edcie necess\u00e0ria per poder publicar la plataforma del Vuze
+window.uiswitcher.ClassicUI.title=Interf\u00edcie cl\u00e0ssica
+VivaldiView.notAvailable=La vista Vivaldi no est\u00e0 disponible
+restart.error.url=http://wiki.vuze.com/w/Restarting_Issues 
+restart.error.oom=No hi ha mem\u00f2ria disponible
+restart.error.fnf='%1' no \u00e9s a '%2'
+restart.error.pnf=No es troba la ruta '%1' 
+restart.error.bad=Format de fitxer incorrecte per a '%1'
+restart.error.denied=S'ha denegat l'acc\u00e9s quan s'ha intentat executar '%1'. Assegureu-vos que teniu dret d'execuci\u00f3 d'aquest programa.
+TableColumn.header.date_completed=Data de compleci\u00f3
+TableColumn.menu.date_added.reset=Reinicialitza la data
 ConfigView.interface.start.advanced=Comen\u00e7a en visualitzaci\u00f3 avan\u00e7ada (AZ 2.x)
 MyTorrents.column.ColumnQuality=Qualitat
 MyTorrents.column.ColumnSpeed=Velocitat
 MyTorrents.column.ColumnProgressETA.2ndLine=Temps: %1
 MyTorrents.column.ColumnProgressETA.PlayableIn=Reprodu\u00efble d'aqu\u00ed a %1
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
+TableColumn.header.Quality=Qualitat
+TableColumn.header.Speed=Velocitat
+TableColumn.header.SpeedGraphic=Velocitat
+TableColumn.header.AzProduct=Des de
+TableColumn.header.MediaThumb=Suport
+TableColumn.header.ProgressETA=Progr\u00e9s
+TableColumn.header.name.ext=Tipus de fitxer: %1
+TableColumn.header.DateCompleted={TableColumn.header.date_completed} 
+v3.MainWindow.tab.home=Consola
+v3.MainWindow.tab.browse=Al Vuze
+v3.MainWindow.tab.library=Biblioteca
 v3.MainWindow.tab.publish=Publica
+v3.MainWindow.tab.advanced=Avan\u00e7at
+v3.MainWindow.menu.home=Consola
+v3.MainWindow.menu.browse=Al Vuze
+v3.MainWindow.menu.library=Biblioteca
 v3.MainWindow.menu.publish=&Publica
+v3.MainWindow.menu.advanced=&Avan\u00e7at
+v3.MainWindow.menu.view.searchbar=Barra de cerca
+v3.MainWindow.menu.view.tabbar=Barra de pestanyes
+v3.MainWindow.currentDL=Desc\u00e0rregues actuals
+v3.MainWindow.button.stream=Transmet
+v3.MainWindow.button.stop=Atura
+v3.MainWindow.button.start=Comen\u00e7a
+v3.MainWindow.button.pause=Fes una pausa
+v3.MainWindow.button.resume=Repr\u00e8n
+v3.MainWindow.button.delete=Esborra
+v3.MainWindow.button.comment=Comenta
+v3.MainWindow.button.viewdetails=Mostra els detalls
+v3.MainWindow.button.play=Visualitza
+v3.MainWindow.button.cancel=Cancel\u00b7la
+v3.MainWindow.button.preview=Previsualitza
+v3.MainWindow.view.wait=La visualitzaci\u00f3 s'est\u00e0 inicialitzant. Espereu.
+v3.MainWindow.xofx=%1 de %2
+v3.MainWindow.Loading=S'est\u00e0 carregant... Espereu
+v3.filter-bar=Filtre del t\u00edtol:
+v3.MainWindow.search.defaultText=Cerca...
 v3.mb.delPublished.title=Deixa de sembrar el contingut
-v3.mb.delPublished.text=ATENCI\u00d3: Aquesta acci\u00f3 NO esborrar\u00e0 els continguts que heu publicat '%1' de <A HREF="%2">%3</A> .\n\nClicque "Esborra" nom\u00e9s si voleu mantenir el contingut publicat i descarregable, per\u00f2 voleu alliberar amplada de banda. Assegureu-vos que el proc\u00e9s de c\u00e0rrega s'ha completat abans de fer-ho (<A HREF="%4">how</A>?).\n\nCliqueu "Cancel\u00b7la" si voleu eliminar completament el contingut publicat de %3, i feu servir el bot\u00f3 (X) [...]
+v3.mb.delPublished.text=ATENCI\u00d3: Aquesta acci\u00f3 NO esborrar\u00e0 els continguts que heu publicat '%1' de <A HREF="%2">%3</A> .\n\nCliqueu "Esborra" nom\u00e9s si voleu mantenir el contingut publicat i descarregable, per\u00f2 voleu alliberar amplada de banda. Assegureu-vos que el proc\u00e9s de c\u00e0rrega s'ha completat abans de fer-ho (<A HREF="%4">how</A>?).\n\nCliqueu "Cancel\u00b7la" si voleu eliminar completament el contingut publicat de %3, i feu servir el bot\u00f3 (X) [...]
 v3.mb.delPublished.delete=&Esborra
 v3.mb.delPublished.cancel=&Cancel\u00b7la
-#
-splash.loadIpFilters=Carregant filtres IP...
+v3.mb.PlayFileNotFound.title=El fitxer no hi \u00e9s
+v3.mb.PlayFileNotFound.text=Els fitxers '%1' no es troben o s'han eliminat.
+v3.mb.PlayFileNotFound.button.remove=Elimina del Vuze
+v3.mb.PlayFileNotFound.button.redownload=Torna a descarregar les dades
+v3.mb.PlayFileNotFound.button.find=Cerca manualment...
+v3.topbar.menu.show.logo=Logotip
+v3.topbar.menu.show.plugin=\u00c0rea de connectors
+v3.topbar.menu.show.search=Cerca
+splash.initializeCore=Inicialitzant l'\u00e0nima
+splash.initializeUIElements=Inicialitzant els elements UI
+ConfigView.section.transfer.autospeedbeta=Velocitat autom\u00e0tica beta
+ConfigView.section.ipfilter.peerblocking.group=Blocatge d'iguals
+ConfigView.section.ipfilter.autoload.group=Carregant autom\u00e0ticament
+ConfigView.section.ipfilter.autoload.loadnow=Carrega ara
+splash.loadIpFilters=Carregant els filtres d'adreces IP...
 SpeedTestWizard.set.upload.title=Ajusta els l\u00edmits de c\u00e0rrega i desc\u00e0rrega
+SpeedTestWizard.set.download.label=L\u00edmit de velocitat de desc\u00e0rrega:
 SpeedTestWizard.set.upload.label=L\u00edmit de velocitat de c\u00e0rrega:
+SpeedTestWizard.name.conf.level.absolute=Absolut
+SpeedTestWizard.name.conf.level.high=Alt
+SpeedTestWizard.name.conf.level.med=Mitj\u00e0
 SpeedTestWizard.name.conf.level.low=Baixa
+SpeedTestWizard.name.conf.level.none=Cap
+ConfigView.section.transfer.select=Autovelocitat
+ConfigView.section.transfer.select.v2=Autovelocitat (beta)
+mb.azmustclose.title=Error a l'inici
+network.bindError=La vinculaci\u00f3 del s\u00f2col del servidor ha fallat perqu\u00e8 no \u00e9s compatible amb les adreces disponibles. Comproveu la configuraci\u00f3 de vinculaci\u00f3 a l'adre\u00e7a IP.
+network.enforce.ipbinding=For\u00e7a les vinculacions d'adreces IP encara que no hi hagi interf\u00edcies disponibles, impedeix la connexi\u00f3 si cap de les interf\u00edcies especificades no \u00e9s disponible. 
 DHTView.title.full_v6=Base de dades distribu\u00efda IPv6
 ConfigView.pluginlist.loadSelected=Carrega la selecci\u00f3
-SpeedView.stats.estupcap=Velocitat de c\u00e0rrega
+SpeedView.stats.asn=Xarxa:
+SpeedView.stats.estupcap=Velocitat de c\u00e0rrega:
+SpeedView.stats.estdowncap=L\u00edmit de desc\u00e0rrega:
+SpeedView.stats.unknown=Desconegut
+SpeedView.stats.estimate=Estimat
+SpeedView.stats.measured=Mesurat
+SpeedView.stats.measuredmin=M\u00edn. mesurat
+SpeedView.stats.manual=Arreglat
+ConfigView.section.transfer.autospeed.networks=Detalls de la xarxa
+ConfigView.section.transfer.autospeed.resetnetwork=Reinicialitza els detalls de la xarxa
+ConfigView.section.transfer.autospeed.network.info=Els l\u00edmits de sobre es calculen autom\u00e0ticament normalment durant la desc+arrega o s\u00f3n el resultat de la prova de velocitat. Si els voleu especificar manualment, feu servir les opcions de sota.\nTots els l\u00edmits que no siguin 'fixats' s'ajustaran posteriorment de manera autom\u00e0tica si cal. \nIntrodu\u00efu-ne el valor i seleccioneu-ne el tipus. Noteu que les velocitats s\u00f3n a %1.
+dialog.uiswitcher.restart.title=Commutador UI: cal reiniciar el Vuze
+dialog.uiswitcher.restart.text=El Vuze necessita reiniciar-se per canviar al nou mode UI.
+TrayWindow.menu.close=Tanca la cistella de desc\u00e0rrega
 # Used for peers which we can't determine.
 PeerSocket.unknown=Desconegut
+PeerSocket.fake_client=FALS
+PeerSocket.bad_peer_id=Identificaci\u00f3 de l'igual incorrecta
+PeerSocket.mismatch_id=no es correspon
 PeerSocket.unknown_az_style=Desconegut %1/%2
 PeerSocket.unknown_shadow_style=Desconegut %1/%2
+OpenTorrentWindow.mb.askCreateDir.title=La carpeta de destinaci\u00f3 no existeix
+OpenTorrentWindow.mb.askCreateDir.text=La carpeta de destinaci\u00f3  '%1' no existeix.\n\nLa voleu crear?
 ConfigTransferAutoSpeed.upload.capacity.usage=\u00das de la capacitat de c\u00e0rrega
 ConfigTransferAutoSpeed.mode=Mode: 
 ConfigTransferAutoSpeed.capacity.used=% \u00fas de capacitat
@@ -1753,11 +2136,25 @@ ConfigTransferAutoSpeed.ping.time.bad=Dolent:
 ConfigTransferAutoSpeed.adjustment.interval=Interval d'ajustament:
 ConfigTransferAutoSpeed.skip.after.adjust=Surt despr\u00e9s d'ajustar:
 GeneralView.label.distributedCopies=C\u00f2pies distribu\u00efdes:
+PiecesView.DistributionView.title=Distribuci\u00f3 de les peces
+PiecesView.DistributionView.NoAvl=Peces no disponibles
+PiecesView.DistributionView.weHave=Peces que teniu
+PiecesView.DistributionView.theyHave=Peces que t\u00e9 l'igual
+PiecesView.DistributionView.weDownload=Peces que esteu descarregant
+PeersView.gain=Guany
 PeersView.gain.info=Quantitat de dades descarregades i carregades
-Content.alert.notuploaded.button.stop=&Atura
-Content.alert.notuploaded.button.continue=&Continua sembrant
+unix.script.new.title=Hi ha disponible un nou script d'inici del Vuze
+unix.script.new.manual.url=http://wiki.vuze.com/w/Unix_Startup_Script 
+unix.script.new.button.quit=Surt ara
+unix.script.new.button.continue=Ho far\u00e9 m\u00e9s endavant
+unix.script.new.button.asknomore=No m'ho tornis a dir
+unix.script.new.auto.title=Nou script d'inici del Vuze
+unix.script.new.auto.text=Hi ha disponible un nou script d'inici del Vuze.\n\n\u00c9s altament recomanable que reinicieu ara el Vuze.
 Content.alert.notuploaded.button.abort=&No surtis
+ConfigView.label.ui_switcher_button=Mostra
 SpeedTestWizard.set.upload.hint=Ajusta els l\u00edmits de c\u00e0rrega i desc\u00e0rrega als que fa servir l'algoritme de velocitat autom\u00e0tica del Vuze.
+SpeedTestWizard.finish.panel.auto.speed=La velocitat autom\u00e0tica \u00e9s:
+SpeedTestWizard.finish.panel.auto.speed.seeding=La velocitat autom\u00e0tica mentre se sembra \u00e9s: 
 ConfigTransferAutoSpeed.add.comment.to.log.group=Afegeix un comentari al registre de depuraci\u00f3
 ConfigTransferAutoSpeed.add.comment.to.log=Afegeix el comentari:
 ConfigTransferAutoSpeed.log.button=Registre
@@ -1767,55 +2164,145 @@ ConfigTransferAutoSpeed.auto.speed.classic=Velocitat autom\u00e0tica (cl\u00e0ss
 ConfigTransferAutoSpeed.auto.speed.beta=Velocitat autom\u00e0tica (beta)
 ConfigTransferAutoSpeed.data.update.frequency=Freq\u00fc\u00e8ncia d'actualitzaci\u00f3
 Alert.failed.update=La instal\u00b7laci\u00f3 d'almenys un component ha fallat. Vegeu <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
-ConfigView.label.announceport=Canviar el port d'anunci del rastrejador
+Alert.failed.update.url=http://wiki.vuze.com/w/Failed_Update 
+TableColumn.header.bad_avail_time=C\u00f2pia completa visualitzada
+MyTorrentsView.menu.exporthttpseeds=Exporta les URL de la llavor HTTP al porta-retalls
+SWT.alert.erroringuithread=S'ha produ\u00eft un error no gestionat a la IGU. Se us podr\u00e0 notificar si hi ha m\u00e9s errors.
+ConfigView.label.announceport=Canvia el port d'anunci del rastrejador
+ConfigView.label.maxseedspertorrent=Nombre m\u00e0xim de llavors per torrent per defecte [0: il\u00b7limitat]
+wizard.webseed=Afegeix llavors HTTP al torrent
+wizard.webseed.title=Llavors HTTP
+wizard.webseed.configuration=Configuraci\u00f3 de les llavors HTTP
+wizard.webseed.adding=Afegint llavors HTTP
 GeneralView.label.private=Torrent privat:
 GeneralView.yes=S\u00ed
 GeneralView.no=No 
+ConfigView.label.userequestlimitingpriorities=Prioritza la velocitat de desc\u00e0rrega a la cap\u00e7alera de la cua de desc\u00e0rrega quan s'arribi al l\u00edmit de la velocitat de desc\u00e0rrega
 Peers.column.timetocomplete=Temps restant
 Peers.column.timetocomplete.info=Time que falta perqu\u00e8 l'igual estigui complet
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Mostra el progr\u00e9s de desc\u00e0rrega de fitxers a la barra d'estat en comptes de fer-ho en el di\u00e0leg d'una finestra emergent
 FileDownload.canceled=La desc\u00e0rrega del fitxer torrent ha estat cancel\u00b7lada correctament per l'usuari: %1
+Progress.reporting.status.canceled=Cancel\u00b7lat
+Progress.reporting.status.finished=Acabat
+Progress.reporting.status.retrying=Tornant-ho a intentar...
+Progress.reporting.action.label.retry.tooltip=Intenta l'operaci\u00f3 de nou
+Progress.reporting.action.label.remove.tooltip=Elimina aquest informe de progr\u00e9s de l'historial
+Progress.reporting.action.label.cancel.tooltip=Cancel\u00b7la l'operaci\u00f3
+Progress.reporting.action.label.detail=Detalls
+Progress.reporting.default.error=Fallada
+Progress.reporting.no.reports.to.display=Actualment no hi ha informes de progr\u00e9s per mostrar.
+Progress.reporting.no.history.to.display=No hi ha missatges de detalls per mostrar.
+Progress.reporting.statusbar.button.tooltip=Mostra la finestra dels informes de progr\u00e9s
+webui.bindip=Vincula l'adre\u00e7a IP - normalment no cal
+v3.MainWindow.text.log.in=Inicia la sessi\u00f3
+v3.MainWindow.text.log.out=Tanca la sessi\u00f3
+v3.MainWindow.text.get.started=Inscriu-te al Vuze
+v3.MainWindow.text.my.account=Informaci\u00f3 del compte
+v3.MainWindow.text.my.profile=Perfil
 OpenTorrentWindow.simple.open=Ubicaci\u00f3 del torrent (fitxer, URL, hash)
+Progress.reporting.window.remove.auto=Elimina autom\u00e0ticament els elemets inactius
+Progress.reporting.window.remove.auto.tooltip=Elimina autom\u00e0ticament tots els processos complets, erronis o cancel\u00b7lats de la vista
+Progress.reporting.window.remove.now=Elimina els elements inactius
+Progress.reporting.window.remove.now.tooltip=Elimina de la visualitzaci\u00f3 els processos que s'han completat, que han fallat o que s'han cancel\u00b7lat
+TorrentOptionsView.multi.title.short=Opcions del torrent
+TorrentOptionsView.multi.title.full=Opcions del torrent
 MyTorrentsView.menu.open_parent_folder=Obre la carpeta de contingut
+ConfigView.section.style.use_show_parent_folder=Fes servir "%1" en comptes de "%2" als men\u00fas dels torrents
+PeerManager.status.ps_disabled=El recurs de seguiment d'iguals est\u00e0 inhabilitat
+ConfigView.section.stats.exportfiles=Exporta els detalls del fitxer
 updater.cant.write.to.app.title=No es pot escriure a la carpeta de l'aplicaci\u00f3
-updater.cant.write.to.app.details=No es pot escriure a la carpeta "%1".\n\nAix\u00f2 impedir\u00e0 que s'apliquin les instal\u00b7lacions de programari.\n\nSi us plau, <a href="http://www.azureuswiki.com/index.php/Failed_Update">consulteu la Wiki per als detalls</a>.
+updater.cant.write.to.app.details=No es pot escriure a la carpeta "%1".\n\nAix\u00f2 impedir\u00e0 que s'apliquin les instal\u00b7lacions de programari.\n\nPer als detalls, consulteu la Wiki. <a href="http://wiki.vuze.com/w/Failed_Update"></a>.
+plugin.install.class_version_error=Aquest connector necessita una versi\u00f3 m\u00e9s nova de Java per funcionar
+v3.MainWindow.tab.minilibrary=Desc\u00e0rregues
 v3.MainWindow.tab.events=Notificacions
 button.columnsetup.tooltip=Actualitza la columna
 v3.activity.remove.title=Esborra la notificaci\u00f3
 v3.activity.remove.text=Segur que voleu eliminar aquesta noitificaci\u00f3?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
+v3.MainWindow.menu.file.closewindow=Tanca
+v3.MainWindow.menu.file.closewindow.keybinding=Meta+W 
 Menu.show.torrent.menu=Mostra el men\u00fa dels torrents
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
+Menu.show.torrent.menu.tooltip=Mostra el men\u00fa de torrents a dalt de la barra de men\u00fa d'aplicacions
+Views.plugins.aznetstatus.title=Estat de la xarxa
 menu.sortByColumn=Ordena per %1 
 MyTorrentsView.menu.manual.per_peer=Manual (per igual)
 MyTorrentsView.menu.manual.shared_peers=Manual (entre iguals)
-OpenTorrentWindow.mb.notTorrent.cannot.display=No es pode mostrar les dades correctament
+v3.button.removeActivityEntry=Elimina la notificaci\u00f3
+OpenTorrentWindow.mb.notTorrent.cannot.display=No es poden mostrar les dades correctament
 MainWindow.menu.window.zoom.maximize=Maximitza
 MainWindow.menu.window.zoom.restore=Restaura
-security.crypto.encrypt=Si us plau, introdu\u00efu una contrasenya per protegir la clau d'encriptaci\u00f3 que acabeu de generar. Atenci\u00f3, no us oblideu d'aquesta contrasenya, ja que no la podreu recuperar!
-security.crypto.decrypt=Si us plau, introdu\u00efu la contrasenya per desbloquejar la clau d'encrotaci\u00f3.
+security.crypto.title=Acc\u00e9s a la clau d'encriptaci\u00f3
+security.crypto.encrypt=Introdu\u00efu una contrasenya per protegir la clau d'encriptaci\u00f3 que acabeu de generar. Atenci\u00f3, no us oblideu d'aquesta contrasenya, ja que no la podreu recuperar!
+security.crypto.decrypt=Introdu\u00efu la contrasenya per desbloquejar la clau d'encriptaci\u00f3.
 security.crypto.password=Contrasenya
 security.crypto.password2=Repetiu la contrasenya
 security.crypto.persist_for=Per\u00edode de validesa de la contrasenya
+security.crypto.persist_for.dont_save=No ho desis
+security.crypto.persist_for.session=Aquesta sessi\u00f3
+security.crypto.persist_for.day=1 dia
+security.crypto.persist_for.week=1 setmana
+security.crypto.persist_for.30days=30 dies
+security.crypto.persist_for.forever=Sempre
+security.crypto.password.mismatch.title=Error de contrasenya
+security.crypto.password.mismatch=Els valors de la contrasenya que heu entrat no coincideixen. Torneu-los a introduir.
+ConfigView.section.security.group.crypto=Claus p\u00fabliques/privades
+ConfigView.section.security.resetkey=Reinicialitza les claus
+ConfigView.section.security.resetkey.warning.title=Alerta de p\u00e8rdua de dades
+ConfigView.section.security.resetkey.warning=Esteu segurs que voleu reinicialitzar les claus d'encriptaci\u00f3? Si ho feu, tota la informaci\u00f3 encriptada que les fan servir ES PERDR\u00c0 DEFINITIVAMENT. A m\u00e9s a m\u00e9s, altres iguals que tinguin la vostra clau p\u00fablica no es podran comunicar m\u00e9s amb vosaltres sense obtenir una clau nova. Per tant, si no esteu segurs del que esteu a punt de fer, no ho feu. 
+ConfigView.section.security.unlockkey=Desbloqueja les claus expl\u00edcitament
+ConfigView.section.security.unlockkey.button=Desbloqueja
+ConfigView.section.security.publickey=Clau p\u00fablica
+ConfigView.section.security.publickey.undef=Pendent de definir
+ConfigView.section.security.resetkey.error.title=Operaci\u00f3 fallida
+ConfigView.section.security.resetkey.error=La reinicialitzaci\u00f3 de les claus a fallat
 ConfigView.section.security.unlockkey.error=La clau de desboqueig ha fallat. La constrasenya \u00e9s incorrecta
 ConfigView.copy.to.clipboard.tooltip=Copia-ho al porta-retalls
+Views.plugins.azbuddy.title=Amics
 Browser.popup.error.no.access=S'ha produ\u00eft un error quan s'intentava accedir a un recurs remot.\nSi us plau, intenteu-ho una altra vegada d'aqu\u00ed a un moment.\n
 ConfigView.label.queue.stoponcebandwidthmet=No comencis m\u00e9s torrents quan s'arribi al l\u00edmit de velocitat de c\u00e0rrega/desc\u00e0rrega
+ConfigView.section.style.forceMozilla=For\u00e7a el Vuze a fer servir el Mozilla per als ginys del navegador [Es necessita el XULRunner o el Firefox 3.] [Cal reiniciar.]
 azbuddy.name=Amics
-azbuddy.enabled=Deshabilitat
-azbuddy.disabled=El complement est\u00e0 deshabilitat. Si el voleu habilitar, feu-ho des de la confiuguraci\u00f3 dels complements.
+azbuddy.enabled=Inhabilitat
+azbuddy.disabled=El connector est\u00e0 inhabilitat. Si el voleu habilitar, feu-ho des de la confiuguraci\u00f3 dels connectors.
 azbuddy.nickname=Sobrenom
 azbuddy.msglog.title=Informaci\u00f3 de l'amic
 azbuddy.addtorrent.title=Accepteu la desc\u00e0rrega?
 azbuddy.addtorrent.msg=L'amic '%1' us ha enviat '%2'.\nVoleu afegir aquesta desc\u00e0rrega?
 azbuddy.contextmenu=Envia-ho a l'amic
+azbuddy.ui.mykey=La meva clau:
+azbuddy.ui.add=Afegeix
+azbuddy.ui.new_buddy=La clau de la nova amistat:
+azbuddy.ui.table.name=Nom
+azbuddy.ui.table.online=En l\u00ednia
+azbuddy.ui.table.last_ygm=YGM 
+azbuddy.ui.table.last_msg=L'\u00faltim missatge
+azbuddy.ui.menu.remove=Suprimeix
+azbuddy.ui.menu.copypk=Copia la clau p\u00fablica
+azbuddy.ui.menu.send=Envia un missatge
+azbuddy.ui.menu.send_msg=Introdu\u00efu el text que voleu enviar a l'amic o amics
+azbuddy.ui.menu.ping=Ping 
+azbuddy.ui.menu.ygm=Envia YGM
+azbuddy.ui.menu.enc=Encripta el porta-retalls
+azbuddy.ui.menu.dec=Desencripta el porta-retalls
+azbuddy.ui.menu.sign=Signa el porta-retalls
+azbuddy.ui.menu.verify=Verifica el porta-retalls
+azbuddy.ui.table.lastseen=L'\u00faltim visualitzat
 Button.retry=To&rna-ho a intentar
 Button.ignore=&Ignora
+azbuddy.ui.table.msg_in=Missatge entrant
+azbuddy.ui.table.msg_out=Missatge sortint
+v3.MainWindow.menu.view.footer=Peu
 azbuddy.downspeed=KB/s velocitat m\u00e0xima de desc\u00e0rrega de l'amic [0: il\u00b7limitat]
-security.crypto.badpw=La contrasenya indicada \u00e9s incorrecta
+security.crypto.badpw=La contrasenya que heu indicat \u00e9s incorrecta
+ConfigView.section.security.backupkeys=Fes una c\u00f2pia de seguretat de les claus a un fitxer
+ConfigView.section.security.backupkeys.button=Fes una c\u00f2pia de seguretat
+ConfigView.section.security.restorekeys=Restaura les claus des d'un fitxer
+ConfigView.section.security.restorekeys.button=Restaura
+ConfigView.section.security.op.error.title=Operaci\u00f3 fallida
+ConfigView.section.security.op.error=La compleci\u00f3 de l'operaci\u00f3 ha fallat:\n    %1
+ConfigView.section.security.restart.title=Cal reiniciar
+ConfigView.section.security.restart.msg=El Vuze es reiniciar\u00e0 immediatament per completar l'operaci\u00f3. 
+azbuddy.ui.table.msg_queued=A la cua
+azbuddy.ui.menu.chat=Xat
 azbuddy.chat.title=Xat del Vuze
 azbuddy.chat.says=%1 diu:
 Button.bar.show=Mostra
@@ -1824,46 +2311,102 @@ Button.bar.share=Comparteix
 Button.bar.add=Afegeix
 Button.bar.edit=Edita
 Button.bar.edit.cancel=Edici\u00f3 feta
+v3.MainWindow.menu.view.pluginbar=Barra de connectors
 MainWindow.dialog.select.vuze.file=Selecciona un fitxer del Vuze
 MainWindow.menu.file.open.vuze=Fitxer del Vuze...
 metasearch.addtemplate.title=Voleu instal\u00b7lar la plantilla de cerca?
 metasearch.addtemplate.desc=Segur que voleu instal\u00b7lar una plantilla de cerca anomenada '%1'?
+v3.share.private.title=Compartint el torrent
+v3.share.private.text=El torrent seleccionat est\u00e0 marcat com a torrent privat. \n\nNo podeu compartir torrents privats.
 metasearch.addtemplate.dup.title=Duplica la plantilla
 metasearch.addtemplate.dup.desc=La plantilla de cerca %1 ja est\u00e0 instal\u00b7lada
 metasearch.export.select.template.file=Desa la plantilla
 metasearch.import.select.template.file=Obre la plantilla
+azbuddy.tracker.enabled=Habilita l'elevador d'amics per prioritzar les desc\u00e0rregues amb els amics
 azbuddy.protocolspeed=KB/s m\u00e0x friend protocol overhead
+v3.MainWindow.button.download=Descarr.
+v3.MainWindow.button.run=Llan\u00e7a el fitxer descarregat
 v3.activity.header.downloads=Desc\u00e0rregues
 v3.activity.header.vuze.news=Not\u00edcies del Vuze
 message.taking.too.long=Sembla que tarda m\u00e9s del que caldria\nPremeu 'ESC' si voleu cancel\u00b7lar l'operaci\u00f3
 message.status.success=\u00c8xit
+azbuddy.tracker.bbb.status.title=Elevaci\u00f3 d'amics
+azbuddy.tracker.bbb.status.title.tooltip=Feu doble clic per a detalls
+azbuddy.tracker.bbb.status.idle=Sense elevaci\u00f3
 azbuddy.tracker.bbb.status.nli=Cal que us registreu
+azbuddy.tracker.bbb.status.in=M'estan elevant
+azbuddy.tracker.bbb.status.out=Amics elevats actualment
+v3.MainWindow.search.go.tooltip=Executa la cerca
+v3.MainWindow.search.last.tooltip=Torna als resultats de la cerca
 metasearch.addtemplate.done.title=Pantilla afegida
 metasearch.addtemplate.done.desc=La plantilla '%1' s'ha afegit correctament.\nEs far\u00e0 servir en la propera cerca!
 ConfigView.section.security.nopw=No heu indicat cap contrasenya
-ConfigView.section.security.nopw_v=No hi ha cap contrasenya disponible. Si us plau, registreu-vos al Vuze
-fileplugininstall.install.title=Voleu instal\u00b7lar el complement?
-fileplugininstall.install.desc=Segur que voleu instal\u00b7lar el complement '%1', versi\u00f3 %2?
-fileplugininstall.duplicate.title=Complement de duplicaci\u00f3
-fileplugininstall.duplicate.desc=El complement '%1', versi\u00f3 %2 ja s'ha instal\u00b7lat.
+ConfigView.section.security.nopw_v=No hi ha cap contrasenya disponible. Registreu-vos al Vuze
+fileplugininstall.install.title=Voleu instal\u00b7lar el connector?
+fileplugininstall.install.desc=Segur que voleu instal\u00b7lar el connector '%1', versi\u00f3 %2?
+fileplugininstall.duplicate.title=Connector de duplicaci\u00f3
+fileplugininstall.duplicate.desc=El connector '%1', versi\u00f3 %2 ja s'ha instal\u00b7lat.
 azbuddy.online_status=Connectat
 azbuddy.os_online=Connectat
 azbuddy.os_away=No hi s\u00f3c
 azbuddy.os_not_avail=No disponible
 azbuddy.os_busy=Ocupat
 azbuddy.os_offline=Desconnectat
+azbuddy.ui.menu.disconnect=Desconnecta
 azbuddy.enable_chat_notif=Habilita les nostificacions de xat
+progress.window.msg.progress=Espereu que l'operaci\u00f3 es completi
+ConfigView.section.connection.advanced.read_select=Llegiu la selecci\u00f3 del temps d'espera (mil\u00b7lisegons, per defecte: %1)
+ConfigView.section.connection.advanced.read_select_min=Llegiu la selecci\u00f3 de l'espera m\u00ednima (mil\u00b7lisegons, per defecte: %1)
+ConfigView.section.connection.advanced.write_select=Escriviu la selecci\u00f3 del temps d'espera (mil\u00b7lisegons, per defecte: %1)
+ConfigView.section.connection.advanced.write_select_min=Escriviu la selecci\u00f3 de l'espera m\u00ednima (mil\u00b7lisegons, per defecte: %1)
 DetailedListView.title=Llista detallada
+plugins.init.force_enabled=El Vuze ha detectat que el connector "%1" est\u00e0 inhabilitat. S'ha reinicialitzat per permetre que el Vuze treballi correctament.
+ConfigView.section.connection.prefer.udp=Prioritza les connexions UDP
+subscript.add.title=Voleu instal\u00b7lar la subscripci\u00f3?
+subscript.add.desc=Segur que voleu instal\u00b7lar la subscripci\u00f3 '%1'?
+subscript.add.dup.title=Duplica la subscripci\u00f3
+subscript.add.dup.desc=La subscripci\u00f3 '%1' ja est\u00e0 instal\u00b7lada.
+subscript.add.upgrade.title=Voleu actualitzar la subscripci\u00f3?
+subscript.add.upgrade.desc=Segur que voleu actualitzar la subscripci\u00f3 '%1'?
+subscript.add.upgradeto.desc=Hi ha disponible la versi\u00f3 %1 de la subscripci\u00f3 '%2'.\nLa voleu actualitzar?
 azsubs.contextmenu.addassoc=Afegeix una associaci\u00f3 de subscripci\u00f3
 azsubs.contextmenu.lookupassoc=Cerca associacions de subscripci\u00f3
+iconBar.start=Comen\u00e7a
+iconBar.stop=Atura
+iconBar.remove=Esborra
+iconBar.up=Amunt
 iconBar.down=Avall
+iconBar.run=Llan\u00e7a
 iconBar.editcolumns=Configuraci\u00f3 de la columna
+iconBar.top=A dalt
+iconBar.bottom=A baix
+iconBar.queue=Comen\u00e7a
+iconBar.open=Afegeix un torrent
+iconBar.share=Comparteix
+iconBar.share.tooltip=Comaprateix el contingut
 iconBar.details=Detalls
-iconBar.comment=Comentari
-iconBar.queue.tooltip=Cua
+iconBar.comment=Comenta
+iconBar.play=Visualitza
+iconBar.queue.tooltip=Comen\u00e7a els torrents seleccionats (la cua)
 v3.MainWindow.menu.view.sidebar=Barra lateral
+v3.MainWindow.menu.view.sidebar.keybinding=F7 
+v3.MainWindow.menu.view.actionbar=Barra d'acci\u00f3
+v3.MainWindow.menu.view.toolbars=Barres d'eines
+ump.install=Actualitzaci\u00f3 r\u00e0pida en progr\u00e9s\nPer aquest v\u00eddeo, cal instal\u00b7lar un petit complement de reproducci\u00f3.
+subscriptions.listwindow.title=Cercador de subscripcions
+subscriptions.listwindow.loadingtext=Cercant subscripcions relacionades amb %1
+subscriptions.listwindow.failed=No s'ha trobat cap subscripci\u00f3
+subscriptions.listwindow.popularity=Popularitat
+subscriptions.listwindow.popularity.unknown=Desconegut
+subscriptions.listwindow.name=Nom
+subscriptions.listwindow.subscribe=Subscriu-m'hi
+TableColumn.header.azsubs.ui.column.subs=Subscriu-t'hi
+subscriptions.listwindow.popularity.reading=Llegint...
+PluginDeprecation.view=Depura el connector
+TableColumn.header.Thumbnail=Icona
+TableColumn.header.Thumbnail.info=La imatge en miniatura per al conitngut del Vuze; per a tota la resta de continguts, el sistema operatiu disposa d'aquestes icones.
+v3.MainWindow.menu.getting_started=Per comen\u00e7ar
 MainWindow.menu.community=&Comunitat
-MainWindow.menu.help.faq=&FAQ
 MainWindow.menu.community.wiki=&Wiki de la comunitat
 MainWindow.menu.community.forums=F\u00f2&rums de la comunitat
 MainWindow.menu.community.blog=&Blog del Vuze
@@ -1878,75 +2421,171 @@ Button.preview=Previsualitzaci\u00f3
 Subscription.menu.forcecheck=Actualitza-ho ara
 Subscription.menu.clearall=Marca tots els resultats com a llegits
 Subscription.menu.remove=Esborra
-sidebar.Library=La biblioteca
-sidebar.LibraryDL=Descarregant
+sidebar.Library=Biblioteca
+sidebar.LibraryDL=Descarregant...
 sidebar.LibraryCD=Complet
+MySeeders.bigView.header={sidebar.LibraryCD} 
+MyTorrents.bigView.header={sidebar.LibraryDL} 
 authenticator.location=Localitzaci\u00f3
 authenticator.details=Detalls
+v3.MainWindow.menu.showActionBarText=Mostra el text
+subscript.import.fail.title=La importaci\u00f3 ha fallat
+subscript.import.fail.desc=Detalls: %1
 Subscription.menu.export=Exporta
+subscript.export.select.template.file=Desa la subscripci\u00f3
 Button.remove=Esborra
 Button.send=Envia
 Button.back=Enrere
-sidebar.LibraryUnopened=No visualitzat
+sidebar.LibraryUnopened=Nous
+TableColumn.header.unopened=Nou
 Unopened.bigView.header=Nou
 Subscription.menu.deleteall=Esborra tots els resultats
 Subscription.menu.reset=Recupera l'estat incial
 ConfigView.section.Subscriptions=Subscripcions
 subscriptions.config.maxresults=Nombre m\u00e0xim de resultats per subscripci\u00f3 [0: il\u00b7limitat]
 v3.activity.button.readall=Marca'ls tots com a llegits
+TableColumn.header.activityNew=Nou
+TableColumn.header.activityType=Tipus
+TableColumn.header.activityText=Missatge
+TableColumn.header.activityDate=Data d'afegida
+TableColumn.header.activityActions=Accions
 Subscription.menu.resetauth=Esborraels detalls d'identificaci\u00f3
-#what you've watched? Discover more with a single click...
+Search.menu.engines=Plantilles
+Wizard.Subscription.title=Subscriu-t'hi
+Wizard.Subscription.optin.title=Habilita les subscripcions
+Wizard.Subscription.subscribe.title=Subscripcions disponibles
 Wizard.Subscription.create.title=Crea una subscrpci\u00f3 nova
 Button.search=Cerca
 Button.save=Desa
 Button.add=Afegeix
 Button.createNewSubscription=Crea una subscrpci\u00f3 nova
 Button.availableSubscriptions=Subscripcions disponibles
+Wizard.Subscription.optin.description=Amb les subscripcions habilitades el Vuze us mostrar\u00e0 les subscripcions relacionades amb el contingut de la biblioteca i us comunicar\u00e0 quan el contingut subscrit estigui disponible per a la desc\u00e0rrega.\n\nVoleu activar les subscripcions?
+Wizard.Subscription.create.rss=RSS 
 Wizard.Subscription.create.search=Cerca
+Wizard.Subscription.search.subtitle1=Cliqueu a la cerca per comen\u00e7ar a crear la subscripci\u00f3:
+Wizard.Subscription.search.subtitle2=Qu\u00e8 puc buscar?
+Wizard.Subscription.search.subtitle2.sub1=Pel\u00b7l\u00edcules en alta definici\u00f3, programes de televisi\u00f3, pel\u00b7l\u00edcules, tr\u00e0ilers a la xarxa Vuze
+Wizard.Subscription.search.subtitle2.sub2=Torrents de la xarxa
+Wizard.Subscription.rss.subtitle1=Escriu o enganxa la URL a sota:
 Wizard.Subscription.rss.subtitle2=Alguns publicadors proporcionen canals RSS del seu contingut. Localitzeu la URL al web del publicador, copieu i enganxeu la URL al camp de sota, i cliqueu a Desa.
+Wizard.Subscription.rss.subtitle3=Un cop desat, rebreu les actualitzacions a la barra lateral sempre que hi hagi resultats nous disponibles pel canal RSS.
+Wizard.Subscription.subscribe.library=Contingut a la biblioteca
+Wizard.Subscription.subscribe.subscriptions=Subscripcions relacionades
+Wizard.Subscription.subscribe.library.empty=No hi ha subscripcions disponibles?\n \nBusqueu el bot\u00f3 taronja de subscripci\u00f3 a la xarxa Vuze d'alta definici\u00f3.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Llegiu-ne m\u00e9s coses</A>
 message.confirm.delete.title=Confirma esborrar
 message.confirm.delete.text=Segur que voleu esborrar '%1'?
 Subscription.menu.properties=Propietats
-externalLogin.wait=Carregant la p\u00e0gina. Si us plau, espereu...
-sidebar.VuzeHDNetwork=Xarxa Vuze HD
+props.window.title=Propietats de '%1'
+subs.prop.enabled={azbuddy.enabled} 
+subs.prop.is_auto=Descarrega autom\u00e0ticament els resultats nous
+subs.prop.last_scan=Darrera actualitzaci\u00f3 amb \u00e8xit
+subs.prop.last_result=Darrer nou resultat trobat
+subs.prop.last_error=Darrer error
+subs.prop.num_read=Nombre de resultats llegits
+subs.prop.num_unread=Nombre de resultats no llegits
+subs.prop.template=Plantilla
+subs.prop.auth=Cal autenticaci\u00f3
+externalLogin.wait=S'est\u00e0 carregant la p\u00e0gina. Espereu...
+TableColumn.menu.date_added.time=Mostra/amaga el temps
+MyLibrary.bigView.header={sidebar.Library} 
+sidebar.VuzeHDNetwork=Xarxa Vuze d'alta definici\u00f3
+subs.prop.assoc=Associacions
+subs.prop.version=Versi\u00f3
 subscriptions.column.new.info=Indicat si hi ha un o m\u00e9s resultats nous
 subscriptions.column.name=Subscripci\u00f3
 subscriptions.column.nb-results=Resultats totals
 subscriptions.column.nb-new-results=Resultats nous
 subscriptions.column.last-checked=\u00daltima comprovaci\u00f3
+subscriptions.view.title=Subscripcions
+subs.prop.is_public=P\u00fablic
+subs.prop.high_version=S'ha trobat la versi\u00f3 m\u00e9s nova
 Subscription.menu.upgrade=Habilita l'actualitzaci\u00f3 a la versi\u00f3 m\u00e9s nova
 metasearch.template.version.bad=La plantilla de cerca '%1' no es pot instal\u00b7lar fins que no s'actualitzi el Vuze
 metasearch.addtemplate.failed.title=La instal\u00b7laci\u00f3 ha fallat
 metasearch.addtemplate.failed.desc=La instal\u00b7laci\u00f3 de la plantilla de cerca '%1' ha fallat
 subscription.version.bad=La subscipci\u00f3 '%1' no es pot instal\u00b7lar fins que no actualitzeu el Vuze
+statusbar.feedback=Envia retroacci\u00f3
+statusbar.feedback.tooltip=Cliqueu aqu\u00ed per enviar la retroacci\u00f3
 sidebar.Activity=Notificacions
 v3.activity.button.watchall=Marca'ls tots com a vistos
+subscriptions.view.help.2=Aconseguiu actualitzacions a temps real sempre que hi hagi nou contingut disponible per a la desc\u00e0rrega. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Per saber-ne m\u00e9s</A>.
 sidebar.sash.tooltip=F7 per amagar/mostrar la barra lateral
+sidebar.expand.tooltip=Expandeix la barra lateral
 sidebar.dropdown.tooltip=Mostra la barra lateral en format men\u00fa
+subscript.all.subscribed=Esteu subscrits a aquest contingut
+subscript.some.subscribed=Esteu subscrit a algunes subscripcions per aquest contingut.\nFeu clic per veure'n d'altres de disponibles
+subscript.none.subscribed=Feu clic per veure les subscripcions disponibles per aquest contingut
+v3.iconBar.up={iconBar.up} 
+v3.iconBar.up.tooltip=Mou amunt\nMantingues premut el bot\u00f3 del ratol\u00ed per moure-ho a dalt de tot
+v3.iconBar.down={iconBar.down} 
+v3.iconBar.down.tooltip=Mou avall\nMantingues premut el bot\u00f3 del ratol\u00ed per moure-ho a baix de tot
+TableColumn.header.azsubs.ui.column.subs_link=Associaci\u00f3
+TableColumn.header.azsubs.ui.column.subs_link.info=Associat a les subscripcions
 Button.deleteContent.fromLibrary=Elimina de la biblioteca
 Button.deleteContent.fromComputer=Esborra de l'ordinador
+v3.deleteContent.message=\nVoleu eliminar '%1' de l'ordinador o nom\u00e9s el voleu eliminar de la biblioteca del Vuze?
+v3.MainWindow.menu.view.toolbartext=Text de la barra d'eines
+v3.MainWindow.menu.view.asSimpleList=Llista simple
+v3.MainWindow.menu.view.asAdvancedList=Llista avan\u00e7ada
+v3.MainWindow.menu.view.statusbar=Barra d'estat
 Subscription.menu.dirtyall=Marca tots els resultats com a no llegits
 configureWizard.file.message3=El Vuze descarregar\u00e0 fitxers en una carpeta espe\u00edfica, que podeu triar:
+v3.deleteContent.applyToAll=Aplica l'acci\u00f3 a totes les %1 entrades seleccionades 
+v3.MainWindow.menu.contentnetworks=Xarxes d'alta definici\u00f3
 v3.MainWindow.menu.contentnetworks.about=Sobre les xarxes HD
 Peers.column.as=AS/ASN 
 Peers.column.as.info=Detalls de l'AS (Sistema Aut\u00f2nom) de l'igual
-ConfigView.label.autoopen=Obertura autom\u00e0tica
+ConfigView.label.autoopen.downloadbars=Obre autom\u00e0ticament la barra de desc\u00e0rrega quan
+ConfigView.label.autoopen=Obre autom\u00e0ticament
+ConfigView.label.autoopen.detailstab=Obre autom\u00e0ticament la finestra de detalls quan
+ConfigView.label.autoopen.dl={ManagerItem.downloading} 
+ConfigView.label.autoopen.cd={ManagerItem.seeding} 
+ConfigView.label.systray=Safata del sistema
+ConfigView.label.systray._mac=Icona de la barra d'estat
 v3.MainWindow.menu.contentnetworks.manage=&Gestiona les xarxes HD
+azbuddy.ui.menu.cat=Categories 
 azbuddy.ui.menu.cat.share=Habilita les subscripcions amb amics
+azbuddy.ui.menu.cat.set=Introdu\u00efu les categories
+azbuddy.ui.menu.cat.set_msg=Separeu les categories a la llista per comes, o 'All' ('Tots')
+azbuddy.ui.menu.cat_subs=Subscriu-m'hi
+subs.prop.update_period=Per\u00edode d'actualitzaci\u00f3
 azbuddy.enable_cat_pub=Categories p\u00fabliques a les quals TOTS els amics es poden subscriure (separades per ',') 
-v3.dialog.cnclose.info2=Si voleu tornar a obrir aquesta xarxa HD, ho heu de fer al men\u00fa "Xarxes HD" de la part superior de la pantalla. 
-v3.dialog.cnmanage.title=Gestiona el men\u00fa de xarxes HD
-v3.dialog.cnmanage.intro=Podeu triar de la llista seg\u00fcent quins coninguts de la xarxa voleu mostrar al men\u00fa de xarxes HD
-TableColumn.header.maxuploads.info=M\u00e0xim # of peers to simultaneously upload to
+TableColumn.header.#=Nre.
+TableColumn.header.#.info=N\u00famero de posici\u00f3/ordre
+TableColumn.header.category.info=Nom de la categoria a la qual pertany el torrent
+TableColumn.header.DateCompleted.info=Data de compleci\u00f3 de la desc\u00e0rrega del torrent
+TableColumn.header.AzProduct.info=Xarxa de contingut des de la qual s'ha originat el torrent
+TableColumn.header.maxuploads.info=Nre. m\u00e0x. d'iguals per carregar simult\u00e0niament
+TableColumn.header.name.info=Nom del torrent
+TableColumn.header.unopened.info=Marca per indicar quin torrent s'ha visualitzat (obert)
+TableColumn.header.savepath.info=La carpeta de destinaci\u00f3 o el fitxer per a les dades del torrent
+TableColumn.header.shareRatio.info=El que heu carregat (compartit) en comparaci\u00f3 amb el que heu descarregat.
+TableColumn.header.size.info=Mida del contingut dels torrents al disc
+TableColumn.header.azsubs.ui.column.subs.info=Bot\u00f3 que us permet la subscripci\u00f3 al canal que cont\u00e9 els torrents relacionats
 TableColumn.header.upspeed.info=Velocitat de c\u00e0rrega actual
+TableColumn.header.downspeed.info=Velocitat de desc\u00e0rrega actual
+TableColumn.header.up.info=La quantitat actual de dades s'ha enviat als altres usuaris
+TableColumn.header.down.info=Quantitat actual de dades rebudes d'altres usuaris
+TableColumn.header.ProgressETA.info=Combina les columnes de l'estatus, la compleci\u00f3, el temps estimat de compleci\u00f3 i la velocitat de desc\u00e0rrega en una columna amb l\u00ednies m\u00faltiples.
+TableColumn.header.eta.info=Temps estimat abans que el torrent s'hagi descarregat
+Pieces.column.#=Nre.
+Pieces.column.#.info=N\u00famero de pe\u00e7a
 Peers.column.%=% 
 Peers.column.%.info=Percentatge del torrent que l'igual ha descarregat
+TableColumn.header.download.info=Quantitat de dades rebudes de l'igual
 TableColumn.header.upload.info=Quantitat de dades que heu enviat al epeer
+TableColumn.header.lan.info=Marca-ho per indicar que l'igual \u00e9s a la teva LAN
 Peers.column.pieces.info=Barra gr\u00e0fica que representa quines peces l'igual ha descarregat
+TableColumn.header.TableColumnNameInfo=Columna de nom i descripci\u00f3
+TableColumn.header.TableColumnSample=Mostra
+TableColumn.header.TableColumnInfo=Columna de descripci\u00f3
+TableColumn.header.TableColumnChosenColumn=Columna triada
+subs.prop.is_auto_ok=Descarrega autom\u00e0ticament els permesos
 label.learnmore=Per saber-ne m\u00e9s coses
 ColumnSetup.title=Configuraci\u00f3 de la columna per a '%1'
-ColumnSetup.explain=Explore les columns disponibles de l'esquerra i afegeix-les a la llista de columnes visibles de la dreta. Expandeix o redueix la llista de columnes disponibles fent servir la secci\u00f3 del filtre del bot\u00f3 esquerre. Podeu arrossegar i deixar anar, o fer servir les dreceres del teclat.
-ColumnSetup.chosencolumns=Columns triades
+ColumnSetup.explain=Explora les columnes disponibles de l'esquerra i afegeix-les a la llista de columnes visibles de la dreta. Expandeix o redueix la llista de columnes disponibles fent servir la secci\u00f3 del filtre del bot\u00f3 esquerre. Podeu arrossegar i deixar anar, o fer servir les dreceres del teclat.
+ColumnSetup.chosencolumns=Columnes triades
 ColumnSetup.proficiency=Professionalitat:
 ColumnSetup.categories=Categories: 
 ColumnSetup.filters=Filtres
@@ -1954,58 +2593,611 @@ ColumnSetup.availcolumns=%1 columnes disponibles
 ColumnSetup.availcolumns.filteredby=%1 columnes disponibles filtrades per %2
 devices.view.title=Dispositius
 device.mediaserver.view.title=Servidor de mitjans
+device.router.view.title=Encaminadors
 device.model.desc=Descripci\u00f3 del model
 device.model.name=Nom del model
 device.model.num=N\u00famero del model
 device.manu.desc=Fabricant
+device.router.is_mapping=Mapatge autom\u00e0tic dels ports
+device.router.req_map=Mapatges necessaris
+device.router.configure=Configura UPnP
 device.mediaserver.configure=Configura el servidor de mitjans
 device.hide=Amaga el dispositiu
+device.show=Mostra els dispositius ocults
+device.search=Cerca dispositius
+device.router.con_type=Connexi\u00f3: %1
 device.browse=Navega
 device.upnp.desc_url=Descripci\u00f3 del dispositiu
 device.upnp.present_url=Administraci\u00f3 del dispositiu
+ConfigView.section.Devices={devices.view.title} 
 devices.sidebar.simple=Visualitzaci\u00f3 simple
-device.lastseen=\u00daltima visualitzaci\u00f3
+devices.xcode.working_dir=\u00c0rea de transcodificaci\u00f3
+devices.xcode.prof_def=Perfil de transcodificaci\u00f3 per defecte
+devices.xcode.profs=Perfils de transcodificaci\u00f3 disponibles
+device.lastseen=Darrera visualitzaci\u00f3
+devices.contextmenu.xcode=Transcodi per a dispositiu
 devices.device=Dispositiu
 devices.profile=Perfil
 General.percent=Percentatge
 devices.installed=Instal\u00b7lat
+devices.comp.missing=El suport del Vuze no est\u00e0 instal\u00b7lat
 devices.state=Estat
-MainWindow.menu.help.donate=F\u00e9s una &donaci\u00f3 (\u20ac,$,...)
-DonationWindow.noload.title=Donaci\u00f3
+MainWindow.menu.help.donate=Feu un &donatiu (\u20ac, $...)
+DonationWindow.noload.title=Donatiu
 DonationWindow.noload.text=La finestra de donaci\u00f3 no s'ha pogut obrir. Si su plau, intenteu-ho d'aqu\u00ed a una estona.
+devices.xcode.only.show=Mostra nom\u00e9s els fitxers de trasncodificaci\u00f3 al dispositiu
+device.quit.transcoding.title=Transcodificaci\u00f3 en proc\u00e9s
 download.removerules.unauthorised.data=\tEsborra les dades
+device.config.xcode.maxbps=R\u00e0tio de transcodificaci\u00f3 m\u00e0xima en kB/s [0: il\u00b7limitat]
+device.xcode=Transcodifica
 device.xcode.always=Sempre
 device.xcode.whenreq=Quan se sol\u00b7liciti
 device.xcode.never=Mai
 devices.copy.pending=La c\u00f2pia del fitxer est\u00e0 pendent
 devices.sidebar.hide.rend.generic=Amaga els dispositius gen\u00e8rics
+v3.devicesview.infobar.text2=Per transcodificar el contingut a un dispositiu, arrossegueu el contingut de la biblioteca als dispositius de la barra lateral. Per visualitzar les transcodificacions completes, feu clic al dispositiu individual de la dreta.
+iconBar.transcode=Dispositiu
+iconBar.transcode.tooltip=Fes que un dispositiu pugui accedir a un fitxer multim\u00e8dia
+device.retry.copy=Torna a intentar la c\u00f2pia
 devices.copy.fail=La c\u00f2pia al dispositiu ha fallat
 devices.ready=Fet
+TableColumn.header.trancode_qpos=Nre.
+TableColumn.header.trancode_qpos.info=Posici\u00f3 a la cua de transcodificaci\u00f3
+TableColumn.header.profile=Dispositiu
+TableColumn.header.profile.info=Perfil de transcodificaci\u00f3 utilitzat
+TableColumn.header.copied=Copiat
+TableColumn.header.device=Dispositiu
+TableColumn.header.device.info=Dispositiu objectiu
+TableColumn.header.trancode_completion=Progr\u00e9s de conversi\u00f3
+TableColumn.header.transcode_name={TableColumn.header.name} 
+TableColumn.header.transcode_status={TableColumn.header.status} 
 # This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=Visual
+v3.iconBar.view.big.tooltip=Visualitza com una llista simple
 # This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=itzaci\u00f3
+v3.iconBar.view.small.tooltip=Visualitza com una llista avan\u00e7ada
 general.dont.ask.again=No ho tornis a preguntar
+general.na.short=No disponible
+v3.menu.device.exploreTranscodes=Mostra els fitxers
+v3.menu.device.exploreTranscodes._windows=Mostra els fitxers a l'Explorer
+v3.menu.device.exploreTranscodes._mac=Mostra els fitxers al Finder
+v3.menu.device.defaultprofile=Perfil per defecte
 devices.button.installitunes=Instal\u00b7la la integraci\u00f3 amb l'iTunes
 device.itunes.install=Cal que instal\u00b7leu l'iTunes
-device.itunes.start=Cal que inicieu l'iTunes o que deshabiliteu l'obertura autom\u00e0tica
+device.itunes.start=Cal que inicieu l'iTunes o que n'habiliteu l'obertura autom\u00e0tica
 device.itunes.install_problem=Sembla que hi ha algun problema amb la integraci\u00f3 de l'iTunes
 devices.downloading=Descarregant
+TableColumn.header.duration=Durada
+TableColumn.header.resolution=Resoluci\u00f3
 devices.xcode.autoStart=Obre autom\u00e0ticament quan es necessiti
 option.askeverytime=Pregunta-ho cada vegada
 option.rememberthis=Recorda aquesta caracter\u00edstica
 devices.associate=Associat amb
+devices.associate.already=Ja hi est\u00e0 associat
+devices.turnon.prepageload=Per activar aquesta caracter\u00edstica, cal instal\u00b7lar components extra.
 devices.turnon.itunes=Inclou suport per a l'iTunes (us cal per als dispositiu d'Apple)
+devices.turnon.qos=Comparteix les estad\u00edstiques del dispositiu de manera an\u00f2nima amb el Vuze
 devices.turnon.title=Activa el suport del dipositiu
+devices.choose.device.title=Seleccioneu un dispositiu de reproducci\u00f3 per aquest v\u00eddeo:
+devices.choose.profile.title={devices.choose.device.title} 
+devices.choose.profile.info.text=Desrp\u00e9s de la selecci\u00f3, el Vuze detectar\u00e0 quin format de v\u00eddeo es reproduir\u00e0 al dispositiu seleccionat i crear\u00e0 una c\u00f2pia compatible amb els dispositiu quan calgui.\n\nPasseu per sobre del dispositiu seleccionat per veure'n els detalls.
+devices.choose.profile.info.title.selected=Detalls de %1:
+devices.view.heading=Convertint suports per a la reproducci\u00f3 dels dispositius
 device.view.heading=Mitjans per a %1
 devices.choose.device.info.title=Tipus de dispositiu
-devices.choose.device.info.text=La porpera vegada, simplement arrossega i dexa anr fitxer al dispositiu que vulguis de la barra lateral.
+devices.choose.device.info.text=La propera vegada, simplement arrossega el fitxer i deixa'l anar al dispositiu que vulguis de la barra lateral.
+label.clickone=Feu clic a un element
 Button.turnon=Connecta
+ConfigView.section.interface.password={ConfigView.section.tracker.password} 
+ConfigView.label.dm.dblclick=Feu doble clic a les visualitzacions dels torrents:
 ConfigView.option.dm.dblclick.play=Reprodueix-ne el contingut
 ConfigView.option.dm.dblclick.details=Obre la visualitzaci\u00f3 dels detalls del torrent
 ConfigView.option.dm.dblclick.show=Mostra el fitxer
-ConfigView.option.dm.dblclick.show._mac=Mostra el(s) fitxer(s) al cercador
-ConfigView.option.dm.dblclick.show._windows=Mostra el(s) fitxer(s) a l'explorador
+ConfigView.option.dm.dblclick.show._mac=Mostra el/s fitxer/s al cercador
+ConfigView.option.dm.dblclick.show._windows=Mostra el/s fitxer/s a l'explorador
 subscriptions.column.auto-download=Descarrega autom\u00e0ticament
+xcode.deletedata.title=Esborra el contingut transcodificat
+xcode.deletedata.message=Segur que voleu esborrar permanentment la c\u00f2pia de '%1' transcodificada per '%2'%3?
+v3.deviceview.infobar.line1=Arrossegueu i deixeu anar els v\u00eddeos de la biblioteca al dispositiu que trieu.
+v3.deviceview.infobar.line2=Reprodueix els v\u00eddeos a qualsevol de les pantalles - iPad, iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=Arrossegueu i deixeu anar els v\u00eddeos de la biblioteca a %1 de la barra lateral.
+v3.deviceview.infobar.line2.itunes=Els v\u00eddeos apareixeran a la carpeta de pel\u00b7l\u00edcules de l'iTunes quan estiguin preparats per a la reproducci\u00f3.
 devices.copy_url=Copia el flux URL al porta-retalls
 devices.converting=Convertint
 Button.reload=Torna a carregar
 devices.auto.start=Obertura autom\u00e0tica
+Subscription.menu.setcookies=Defineix les galetes
+general.enter.cookies=Entra les galetes
+device.config.xcode.workdir=Directori funcional per defecte per als fitxers transcodificats
+MyTorrentsView.menu.clear_alloc_data=Esborra l'estat d'assignaci\u00f3
+DiskManager.error.nospace=Espai al disc insuficient
+DiskManager.error.nospace_fat32={DiskManager.error.nospace}. Comproveu {wiki.fat32}
+wiki.fat32=http://wiki.vuze.com/w/FAT32_file_size_limit 
+ConfigView.section.file.rename.incomplete=Afegeix un sufix als fitxers incomplets
+subscriptions.config.auto=Descarrega autom\u00e0ticament
+subscriptions.config.autostartdls=Comen\u00e7a autom\u00e0ticament les desc\u00e0rregues quan s'afegeixin (s'oposa a tenir-les en estat d'aturada)
+subscriptions.config.autostart.min=Comen\u00e7a nom\u00e9s si >= MB [0: il\u00b7limitat]
+subscriptions.config.autostart.max=Comen\u00e7a nom\u00e9s si <= MB [0: il\u00b7limitat]
+dlg.corewait.text=Un moment. n\nLa vostra petici\u00f3 es processar\u00e0 quan el Vuze hagi completat la inicialitzaci\u00f3
+library.core.wait=Un moment...\nEl client del Vuze s'est\u00e0 inicialitzant
+general.add.friends=Afegeix amics!
+general.all.friends=Tots els amics
+friend.mod.subs=Feu clic al bot\u00f3 dret per gestionar les subscripcions
+device.rss.group=Canal RSS local
+devices.xcode.rsspub=Publica el canal RSS
+device.rss.enable=Crea un canal RSS de contingut transcodificat. Aix\u00f2 permet que els lectors del canal RSS puguin accedir al contingut 
+device.rss.port=Port del canal RSS
+device.rss.view=Clica per veure el canal RSS
+device.rss.localonly=Restringeix l'acc\u00e9s nom\u00e9s a aquest ordinador
+rcm.rc_tracker.tt=Clica per explorar el seguiment
+rcm.rc_hash.tt=Cliqueu per descarregar aquest contingut
+rcm.rc_title.tt=Clica per cercar aquest contingut
+devices.xcode.autoCopy=Copia autom\u00e0ticament a la carpeta
+devices.xcode.setcopyto=Definiu la carpeta de c\u00f2pia...
+devices.xcode.setcopyto.title=Trieu la ubicaci\u00f3 de la c\u00f2pia
+devices.copy.folder.auto=Copia autom\u00e0ticament els fitxers a la carpeta
+devices.copy.folder.dest=Copia a la carpeta
+TableColumn.menu.maxuploads=Nre. m\u00e0x. de c\u00e0rregues
+devices.xcode.mancopy=Copia els fitxers manualment
+devices.xcode.show.cat=Separa per categories
+ConfigView.label.alwaysShowLibraryHeader=Mostra sempre la barra de cap\u00e7alera/flitre a la Biblioteca {library.name}
+devices.cat.show=Mostra les categories
+devices.info.copypending=%1 fitxer/s esperant la c\u00f2pia
+device.error.xcodefail=La transcodificaci\u00f3 ha fallat
+device.error.copyfail=Un fitxer o m\u00e9s d'un no s'han pogut copiar a la carpeta
+device.error.copytonotset='Copia a la carpeta' no definit
+device.error.copytomissing=No es troba 'Copia a la carpeta' "%1" 
+device.error.copytonowrite='Copia a la carpeta ' "%1" no s'hi pot escriure
+device.error.copyfail2=Un fitxer o m\u00e9s d'un no s'han pogut copiar al dispositiu
+devices.info.copypending2=%1 fitxer/s esperant la c\u00f2pia. Connecteu el dispositiu
+subscriptions.column.nb-subscribers=Subscriptors
+subscriptions.column.category={TableColumn.header.category} 
+device.offlinedownloader.view.title=Descarregadors fora de l\u00ednia
+device.xcode.group={device.xcode} 
+device.od.group={device.offlinedownloader.view.title} 
+device.od.enable=Habilita els dispositius de desc\u00e0rrega fora de l\u00ednia
+device.odauto.enable=Gestiona les desc\u00e0rregues autom\u00e0ticament
+device.odpt.enable=Inclou els torrents privats
+devices.contextmenu.od=Descarregant fora de l\u00ednia
+devices.contextmenu.od.auto=<Autom\u00e0tic>
+devices.contextmenu.od.enable=Habilita
+devices.contextmenu.od.enabled=Habilitat
+devices.od.view.heading=Desc\u00e0rregues planificades per a la desc\u00e0rrega fora de l\u00ednia
+DevicesOD.column.od_name={TableColumn.header.name} 
+DevicesOD.column.od_status={MyTrackerView.status} 
+DevicesOD.column.od_completion=Progr\u00e9s de transfer\u00e8ncia
+DevicesOD.column.od_remaining={TableColumn.header.remaining} 
+devices.od.xfering={PeersView.BlockView.Transfer} 
+devices.od.idle=Inactiu
+device.od.turnon.title=Activa el suport del descarregador fora de l\u00ednia
+device.is.disabled=El dispositiu est\u00e0 inhabilitat
+device.configure=Configura...
+device.od.error.notfound=Sembla que el dispositiu est\u00e0 fora de l\u00ednia
+device.od.error.opfailstatus=El dispositiu no ha pogut processar l'ordre %1: estatus %2
+device.od.error.opfailexcep=El dispositiu no ha pogut processar l'ordre %1: excepci\u00f3 %2
+device.od.error.nospace=No hi ha espai disponible al dispositiu o el disc extern no est\u00e0 connectat
+device.od.space=Espai disponible
+ConfigView.label.enableSystrayToolTip=Mostra l'estat de la desc\u00e0rrega al punter
+devices.activation=Activaci\u00f3 del dispositiu
+button.nothanks=No, gr\u00e0cies
+devices.od.turnon.text1=S'ha detectat que us heu connectat a un %1.
+devices.od.turnon.text2=Voleu que %1 segueixi descarregant els fitxers quan l'ordinador sigui fora de l\u00ednia?
+devices.od.turnon.text3=Si us plau connecteu un disc dur al %1 per tal d'activar aquesta caracter\u00edstica.
+devices.od.turnon.learn=Per saber-ne m\u00e9s coses >
+devices.router=encaminador
+devices.od=Descarregador fora de l\u00ednia
+webui.group.access=Control d'acc\u00e9s
+ConfigView.section.Pairing=Aparellant
+pairing.accesscode=Codi d'acc\u00e9s
+pairing.ac.getnew=Ubica un nou codi d'acc\u00e9s
+pairing.ac.getnew.create=Crea
+pairing.ipv4=Adre\u00e7a IPv4 p\u00fablica
+pairing.ipv6=Adre\u00e7a IPv6 p\u00fablica
+pairing.local.ipv4=Adre\u00e7a local IPv4 
+pairing.local.ipv6=Adre\u00e7a local IPv6 
+pairing.host=Adre\u00e7a de l'ordinador (nom del DNS)
+pairing.group.explicit=Atributs expl\u00edcits
+pairing.explicit.enable=Habilita
+pairing.explicit.info=Normalment no cal indicar les caracter\u00edstiques de l'adre\u00e7a IP i es poden derivar autom\u00e0ticament.\nPodeu fer servir la caracter\u00edstica 'ordinador', per exemple, si teniu un compte DynDNS i el programari de client adequat per mantenir l'adre\u00e7a IP din\u00e0mica registrada correctament.
+pairing.op.fail=Ha fallat l'operaci\u00f3 d'aparellament
+pairing.enable=Habilita l'aparellament del Vuze i les interf\u00edcies/aplicacions remotes
+pairing.status.info=Estatus
+pairing.status.registered=Actualitzat correctament (%1)
+pairing.status.pending=L'actualitzaci\u00f3 es dur\u00e0 a terme a %1
+pairing.status.initialising=Inicialitzant
+pairing.status.disabled=Inhabilitat
+pairing.view.registered=Feu clic aqu\u00ed per visualitzar els detalls actuals del registre
+webui.enable=Habilita
+ConfigView.section.rss=RSS local, etc.
+subscriptions.rss.enable=Crea un canal RSS des de les subscripcions
+Button.removeAll=Elimina'ls tots
+label.rename=Reanomena %1
+RCM.column.rc_new={TableColumn.header.unopened} 
+RCM.column.rc_rank=Rang
+RCM.column.rc_actions={TableColumn.header.activityActions} 
+RCM.column.rc_created=Creat
+RCM.column.rc_hash=Resum
+RCM.column.rc_lastseen=Darrera visualitzaci\u00f3
+RCM.column.rc_level=Nivell
+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=Rastrejador
+RCM.column.rc_title={TableColumn.header.name} 
+rcm.view.heading=Descobertes de l'eixam
+rcm.view.title={rcm.view.heading} 
+RCMView.header={rcm.view.heading} 
+rcm.contextmenu.lookupassoc={rcm.view.heading} 
+ConfigView.section.Associations={rcm.view.heading} 
+rcm.config.enabled=Habilita
+rcm.config.max_results=Resultats m\u00e0xims
+rcm.config.max_level=Nivell m\u00e0xim
+rcm.search.provider=Eixam
+pairing.server.warning.title=Missatge del servidor d'aparellament
+wizard.webseedseditor.edit.title=Editor de les llavors HTTP
+wizard.webseedseditor.edit.newseed=Llavor nova
+ClientStats.title.full=Estad\u00edstiques dels clients
+ClientStats.column.count=Recompte
+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} 
+TrackerView.title.short=Recursos
+TrackerView.title.full=Recursos
+Trackers.column.type=Tipus
+Trackers.column.name=Detalls
+Trackers.column.status=Estat
+Trackers.column.seeds=Llavors
+Trackers.column.seeds.info=Llavors a l'eixam
+Trackers.column.peers=Iguals
+Trackers.column.interval=Interval 
+Trackers.column.updatein=Seg\u00fcent
+tps.status.available=Disponible
+tps.status.unavailable=No disponible
+tps.type.dht=DHT 
+tps.lan.details=S'han descobert %1 clients locals
+tps.incoming.details=Actual: TCP=%1, UDP=%2; Total sempre=%3
+group.auto=Autom\u00e0tic
+ConfigView.label.autoadjust=Ajusta autom\u00e0ticament aquesta opci\u00f3 d'acord amb la velocitat de connexi\u00f3
+ConfigView.label.start=Inici
+ConfigView.label.stop=Atura
+ConfigView.label.start.onlogin=Comen\u00e7a el Vuze a l'inici de sessi\u00f3
+ConfigView.label.stop.seedcomp=Quan la sembra sigui completa
+ConfigView.label.stop.downcomp=Quan la desc\u00e0rrega sigui completa
+ConfigView.label.stop.Nothing=No facis res
+ConfigView.label.stop.QuitVuze=Atura el Vuze
+ConfigView.label.stop.Hibernate=Posa l'ordinador en hibernaci\u00f3
+ConfigView.label.stop.Shutdown=Atura l'ordinador
+core.shutdown.dl=S'han completat les desc\u00e0rregues
+core.shutdown.se=sembra completa
+pairing.last.error=\u00daltim error
+MainWindow.menu.pairing=Aparellament remot
+ConfigView.section.startstop={ConfigView.label.start} & {ConfigView.label.stop} 
+ConfigView.label.pauseresume=Fes una pausa autom\u00e0tica / repr\u00e8n
+update.now.title=Cal actualitzar
+ConfigView.label.jvm=Opcions de Java
+pairing.status.noservices=No hi ha serveis remots habilitats
+webui.connectiontest=\tFeu clic aqu\u00ed per a la connexi\u00f3 de la prova
+ConfigView.section.connection.pairing.url=http://wiki.vuze.com/w/UG_Options#Pairing 
+jvm.reset=Reinicia les opcions JVM als valors per defecte de la instal\u00b7laci\u00f3
+ConfigView.section.invalid.value.title=Valor no v\u00e0lid
+ConfigView.section.invalid.value=Valor '%1' inv\u00e0lid, introdu\u00eft per '%2': %3
+Button.dismiss=Rebutja
+webui.pairing.autoauth=Habilita la protecci\u00f3 amb contrasenya per defecte: nom d'usuari = vuze, contrasenya = <pairing access code>
+ConfigView.label.stop.autoreset=Reinicialitza autom\u00e0ticament les accions a '%1' un cop s'ha activat
+remote.pairing.title=Aparellament remot
+remote.pairing.instruction=Introdu\u00efu el codi aqu\u00ed a sota a l'espai proporcionat a qualsevol aplicaci\u00f3 remota.
+remote.pairing.functions=<A HREF="clip">Copia el codi al porta-retalls</A>   |   <A HREF="new">Aconseguiu un codi nou</A>
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">PMF sobre l'aparellament</A>
+remote.pairing.accesscode=Codi d'acc\u00e9s:
+remote.pairing.test.running=Provant la connectivitat remota...
+remote.pairing.test.success=El Vuze \u00e9s accessible de manera remota.
+remote.pairing.test.unavailable=No \u00e9s possible determinar la connectivitat remota. <A HREF="retry">Proveu-ho una altra vegada</A>
+remote.pairing.test.fail=El Vuze no \u00e9s accessible fora de la vostra xarxa local.  <A HREF="/pairing_error_faq.start">Consulteu-ne m\u00e9s informaci\u00f3</A>
+update.fail.app.changed.title=Fallada de l'actualitzaci\u00f3
+MainWindow.status.warning.tooltip=Feu clic aqu\u00ed per als detalls
+search.dialog.text=Introdu\u00efu el text per cercar torrents nous:
+core.not.available=El Vuze encara s'est\u00e0 inicialitzant. Intenteu-ho de nou quan la inicialitzaci\u00f3 s'hagi acabat
+dlg.auth.title=Activaci\u00f3
+dlg.auth.enter.line.try.1=Introdu\u00efu a sota el codi d'activaci\u00f3 per completar l'actualitzaci\u00f3 al Vuze Plus.
+dlg.auth.enter.line.try.2=No s'ha pogut validar el codi d'activaci\u00f3. Comproveu-ne el n\u00famero i intenteu d'introduir-lo de nou.
+dlg.auth.enter.prompt=Codi d'activaci\u00f3 del Vuze Plus:
+Button.validate=Valida
+Button.getstarted=Per comen\u00e7ar
+Button.install={swt.install.window.ok} 
+Button.goLibrary=V\u00e9s a {library.name}
+dlg.auth.success.subtitle=Felicitats!
+dlg.auth.success.line2=Ara ja podeu gravar DVD de manera il\u00b7limitada, explorar els fitxers per cercar-hi virus i reproduir els v\u00eddeos que esteu descarregant. I tot aix\u00f2 sense anuncis!
+dlg.auth.trial.success.line1=El Vuze est\u00e0 preparat per crear DVD.
+dlg.auth.trial.success.subtitle=La gravaci\u00f3 del DVD \u00e9s a punt
+dlg.auth.revoked=Codi d'activaci\u00f3 revocat
+dlg.auth.revoked.line1=El vostre codi d'activaci\u00f3 del Vuze Plus ha estat revocat. Cliqueu a sota per a m\u00e9s informaci\u00f3.
+dlg.auth.denied=Codi d'activaci\u00f3 denegat
+dlg.auth.denied.line1=El codi d'activaci\u00f3 del Vuze Plus ha estat denegat. Cliqueu a sota per a m\u00e9s informaci\u00f3.
+dlg.auth.denied.link=<A HREF="info">Informaci\u00f3 sobre la denegaci\u00f3 dels codis d'activaci\u00f3</A>
+dlg.auth.cancelled=Codi d'activaci\u00f3 cancel\u00b7lat
+dlg.auth.cancelled.line1=La vostra activaci\u00f3 del Vuze Plus s'ha cancel\u00b7lat.
+dlg.auth.cancelled.line2=Si creieu que \u00e9s un error, contacteu amb l'equip de suport mitjan\u00e7ant les adreces del correu que heu rebut.
+dlg.auth.enter.subtitle.try.2=La validaci\u00f3 ha fallat
+dlg.auth.enter.expiry=El codi d'activaci\u00f3 actual ven\u00e7 d'aqu\u00ed a %1.
+dlg.auth.enter.cancelled=El codi d'activaci\u00f3 actual s'ha cancel\u00b7lat.
+dlg.auth.enter.denied=El codi d'activaci\u00f3 actual s'ha denegat.
+dlg.auth.validating.subtitle=Validant...
+dlg.try.trial.title=Proveu la gravaci\u00f3 de DVD
+dlg.try.trial.text=El Vuze necessita instal\u00b7lar el connector per gravar DVD executables dels v\u00eddeos. Cliqueu a l'activaci\u00f3 per continuar.
+dlg.auth.tos=He llegit i accepto <A HREF="tos">les condicions del servei</A>
+dlg.auth.install.subtitle.trial=Instal\u00b7lant la gravaci\u00f3 de DVD 
+dlg.auth.install.progress=Instal\u00b7lant %1 components...
+dlg.auth.install.pct=%1% fet
+mdi.entry.plus.full=Vuze Plus 
+mdi.entry.plus.free=Vuze Plus 
+mdi.entry.dvdburn=Gravaci\u00f3 de DVD
+mdi.entry.dvdburn.new=Crea un DVD nou
+menu.plus=Vuze Plus 
+menu.register=Activaci\u00f3 del Vuze Plus
+dlg.auth.trial.title=Prova de gravaci\u00f3 de DVD
+dlg.player.install.subtitle=Instal\u00b7laci\u00f3
+dlg.player.install.description=Instal\u00b7lant el connector addicional de reproducci\u00f3...
+Button.agree=D'acord
+dlg.auth.install.failed.title=L'activaci\u00f3 ha fallat
+dlg.auth.install.failed.text=El codi d'activaci\u00f3 '%1' ha fallat per culpa d'un error del servidor.\n\nSi us plau, intententeu l'activaci\u00f3 d'aqu\u00ed a una estona (l'error detectat ha estat '%2')
+device.status.online=El dispositiu \u00e9s fora de l\u00ednia
+device.itunes.status.running=L'iTunes funciona
+device.itunes.status.notrunning=L'iTunes no funciona
+device.itunes.status.notinstalled=L'iTunes no est\u00e0 instal\u00b7lat
+ConfigView.section.ipfilter.clear.on.reload=Esborra els filtres quan recarreguis. Durant el proc\u00e9s de rec\u00e0rrega, no es bloquejaran les adreces IP. Si est\u00e0 desactivat, els desbloquejos recents no seran efectius fins que es reinici\u00ef.
+view.waiting.core=La visualitzaci\u00f3 ser\u00e0 disponible quan el Vuze Core hagi finalitzat la c\u00e0rrega.
+devices.profile.direct=Directe
+cat.autoxcode=Dispositiu autom\u00e0tic
+ConfigView.section.tables=Taules
+ConfigView.section.style.useTree=Mostra els fitxers a les visualitzacions de la biblioteca {library.name} [us caldr\u00e0 reiniciar]
+ConfigView.section.mode.resetdefaults=Reinicialitza la configuraci\u00f3 als valors per defecte (\u00e9s recomanable reiniciar)
+resetconfig.warn.title=Confirmeu l'acci\u00f3
+resetconfig.warn=Es perdran totes les modificacions que heu fet a configuraci\u00f3 del Vuze.\nSegur que voleu seguir reiniciant la configuraci\u00f3?
+ConfigView.label.xfer.bias_slack=kB/s m\u00ednims reservats per a les desc\u00e0rregues completes
+SpeedView.stats.upload_details=%1 
+SpeedView.stats.con=Detalls de la connexi\u00f3:
+dlg.install.mlab.subtitle=Instal\u00b7lant
+dlg.install.mlab.description=Espereu que s'instal\u00b7li el component de la prova de velocitat 
+auto.mode=Autom\u00e0tic (recomanat)
+manual.mode=Manual 
+configureWizard.transfer2.group=Mode 
+configureWizard.transfer2.test.info=Selecciona-ho per realitzar una prova completa de velocitat
+configureWizard.transfer2.test=Prova de funcionament
+configureWizard.transfer2.mselect=Selecciona el l\u00edmit de velocitat de la connnexi\u00f3 de C\u00c0RREGA
+configureWizard.transfer2.rate.unchanged=Es far\u00e0 servir la configuraci\u00f3 actual
+configureWizard.transfer2.rate.changed=L\u00edmit de connexi\u00f3 = %1\nEl l\u00edmit aplicat ser\u00e0 de %2 (nre. m\u00e0x. de torrents actius = %3, m\u00e0x. de desc\u00e0rrega = %4)
+speedtest.wizard.select.title=Seleccioneu el tipus de prova de velocitat que voleu fer servir
+speedtest.wizard.select.group=Tipus de prova
+speedtest.wizard.select.general=Prova de velocitat general (recomanada)
+speedtest.wizard.select.bt=Prova de velocitat concreta per a Bittorrent
+FileItem.storage.reorder=Reordena
+configureWizard.transfer2.current=<Configuraci\u00f3 actual>
+ConfigView.section.style.extendedErase=Dibuixa les l\u00ednies de la graella i omple les \u00e0rees en blanc
+iconBar.stream=Visualitza'l ara
+FilesView.menu.setpriority.numeric=Num\u00e8ric...
+FilesView.dialog.priority.title=Introdu\u00efu el n\u00famero de la prioritat
+FilesView.dialog.priority.text=0=normal, 1=alta, 2=m\u00e9s alta...
+beta.wizard.title=Configuraci\u00f3 de la versi\u00f3 beta
+beta.wizard.info=Incorporar-se al programa beta del Vuze us d\u00f3na acc\u00e9s a les caracter\u00edstiques m\u00e9s noves i recents del client. \n\nAix\u00f2 us d\u00f3na la possibilitat d'experimentar i provar aquestes caracter\u00edstiques i ajudar a millorar la manera com s'implmenten. Qualsevol comentari i opini\u00f3 \u00e9s d'una gran ajuda!\n\nA causa de la seva naturalesa, les versions beta poden ser inestables, tot i que seleccionant aquesta opci\u00f3 podreu accedir a version [...]
+beta.wizard.link=Feu clic aqu\u00ed per accedir a la p\u00e0gina web de la versi\u00f3 beta
+beta.wizard.link.url=http://dev.vuze.com 
+beta.wizard.off=Estic satisfet amb les versions de llan\u00e7ant. No m'interessa.
+beta.wizard.on=Si us plau, actualitzeu-me amb la darrera versi\u00f3 beta estable.
+beta.wizard.version=Esteu fent servir la versi\u00f3 %1
+beta.wizard.disable.title=Cal reinstal\u00b7lar-ho
+beta.wizard.disable.text=Gr\u00e0cies per provar la versi\u00f3 beta! \n\nSi us plau descarregueu i instal\u00b7leu la darrera versi\u00f3 per abandonar el programa beta
+beta.wizard.forum=Fes servir els f\u00f2rums del Vuze per fer comentaris, opiniar i informar d'errors
+beta.wizard.forum.url=http://www.vuze.com/forum_beta.start 
+dlg.install.vuzexcode.subtitle=Instal\u00b7lant el component d'an\u00e0lisi de suports
+dlg.install.vuzexcode.description=Espereu mentre el component d'an\u00e0lisi de suports s'instal\u00b7la
+dlg.install.azemp.subtitle={dlg.player.install.subtitle} 
+dlg.install.azemp.description={dlg.player.install.description} 
+TableColumn.header.filecount=Nre. de fitxers
+TableColumn.header.torrentspeed=Velocitat
+FileProgress.deleted=Esborrat
+FileProgress.stopped={ManagerItem.stopped} 
+priority.high=Prioritat alta
+priority.normal=Prioritat normal
+ScrapeInfoView.title=Rastrejador primari
+Column.seedspeers.started=%1 de %2
+Column.seedspeers.notstarted=%2 
+Column.seedspeers.started.noscrape=%1 
+#connected to more seeds/peers than tracker reports
+Column.seedspeers.started.over=%1 
+library.all.header.p=%1 elements; d'actius, %2
+library.incomplete.header.p=Descarregant %1 elements, %2 esperant la desc\u00e0rrega
+library.unopened.header.p=%1 elements
+library.all.header=%1 elements: %2 actius
+library.incomplete.header=Descarregant %1 elements, %2 elements esperant la desc\u00e0rrega
+library.unopened.header=%1 element
+MyTorrents.column.ColumnProgressETA.compon=Data de compleci\u00f3: %1
+Sidebar.beta.title=Programa beta
+MainWindow.menu.beta.on=Afegiu-vos al programa beta
+MainWindow.menu.beta.off=Abandona el programa beta...
+Button.sendNow=Envia-ho ara
+Button.sendManual=Enviament manual (crea un .zip)
+deletecontent.also.deletetorrent=Esborra tamb\u00e9 el fitxer .torrent
+ConfigView.section.file.deletion.section=Supressi\u00f3 del fitxer
+ConfigView.section.file.delete.torrent=Per defecte, esborra el fitxer torrent quan n'esborris el contingut
+menu.delete.options={iconBar.remove}... 
+menu.delete.options.keybinding=DEL 
+MainWindow.menu.view.beta=Programa beta
+jvm.options.summary=Resum de les opcions expl\u00edcites actuals:
+device.showGeneric=Mostra els dispositius gen\u00e8rics
+mdi.entry.games=Jocs
+v3.MainWindow.menu.games={mdi.entry.games} 
+Peers.column.Protocol=Protocol 
+devices.copying=Copiant al dispositiu
+devices.cancel_xcode=Cancel\u00b7la la conversi\u00f3
+sidebar.header.vuze=Vuze 
+sidebar.header.transfers=Fitxers
+sidebar.header.devices=Reproducci\u00f3 del dispositiu
+sidebar.header.subscriptions=Subscripcions
+sidebar.header.plugins=Connectors i extres
+sidebar.header.dvd={mdi.entry.dvdburn} 
+mdi.entry.about.devices=En funcionament
+mdi.entry.about.plugins=Sobre els connectors
+mdi.entry.about.dvdburn=Per comen\u00e7ar
+ConfigView.tb.delete.ask=Pregunta
+ConfigView.tb.delete.content=Elimina sense preguntar
+ConfigView.tb.delete.torrent=Elimina nom\u00e9s de la biblioteca
+search.export.all=Exporta totes les plantilles de cerca...
+subscriptions.search.enable=Habilita la cerca de resultats de subscripci\u00f3 (cal reiniciar)
+devices.cancel_xcode_del=Cancel\u00b7la la conversi\u00f3 / Elimina-la
+subscriptions.add.tooltip=Afegeix la subscripci\u00f3
+subscriptions.overview=Visi\u00f3 general de les subscripcions
+configureWizard.nat.title=NAT / Ports del servidor
+configureWizard.nat.message=Si voleu obtenir el millor de BitTorrent, \u00e9s altament recomanable que el vostre ordinador tingui acc\u00e9s complet des d'Internet. El rang de ports per defecte de BitTorrent va des del 6881 fins al 6889. Aquesta eina us permet provar i canviar aquests ports. Si teniu alguna desc\u00e0rrega activa, \u00e9s possible que alguns ports no siguin accessibles.
+v3.menu.device.defaultprofile.never=No transcodifiquis mai
+subscriptions.info.avail=Encara no heu afegir cap subscripci\u00f3. N'hi ha %1 de disponibles de la biblioteca.
+subscriptions.dl_subs.enable=Descarrega les subscripcions d'altres clients quan calgui
+# Will be used for {library.name} in classic view
+library.name._classic=Els meus torrents
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Biblioteca
+ConfigView.section.style.units=Mostra les unitats
+ConfigView.section.style.library=Biblioteca
+ConfigView.section.style.CatInSidebar=Mostra les categories a la barra lateral
+library.category.header=Categoria '%1'
+device.import.title=Vols importar el dispositiu?
+device.import.desc=Segur que voleu importar el dispositiu '%1'?
+device.import.dup.title=Duplica el dispositiu
+device.import.dup.desc=El dispositiu '%1' encara hi \u00e9s.
+stream.analysing.media=Analitzant els suports
+device.export.select.template.file=Exporta el dispositiu
+dlg.stream.plus.subtext=Us heu cansat d'esperar la compleci\u00f3 de les desc\u00e0rregues?  Visualitzeu-les m\u00e9s de pressa amb l'opci\u00f3 de 'Reprodueix ara', una funci\u00f3 del Vuze Plus que us permet visualitzar el v\u00eddeo mentre continua la desc\u00e0rrega.
+dlg.stream.plus.text=Actualitza el Vuze Plus i reprodueix els v\u00eddeos quan es descarreguin.
+dlg.stream.plus.title=Actualitza
+dlg.stream.plus.subtitle=Actualitza
+dlg.stream.plus.renew.subtext={dlg.stream.plus.subtext} 
+dlg.stream.plus.renew.text=Renoveu la subscripci\u00f3 del Vuze Plus per continuar reproduint els v\u00eddeos quan es descarreguin. 
+dlg.stream.plus.renew.title=Renovaci\u00f3 del Vuze Plus
+Button.upgrade=Actualitza
+Button.renew=Renova
+iconBar.pstream={iconBar.stream} 
+stream.analysing.media.preview=Analitzant els suports (mode de previsualitzaci\u00f3)
+devices.restrict_access=Acc\u00e9s restringit...
+devices.restrict_access.prompt=Acc\u00e9s restingit a '%1'
+TableColumn.header.TorrentStream={iconBar.stream} 
+TableColumn.TorrentStream.tooltip.disabled=La visualitzaci\u00f3 no admet aquest tipus de fitxers
+TableColumn.TorrentStream.tooltip.expand=Expandeix la fila per mostrar l'opci\u00f3 de visualitzaci\u00f3 per als fitxers individuals
+table.columns.reset=Reinicialitza les columnes
+plus.notificaiton.ExpiredEntry.p={plus.notificaiton.ExpiredEntry.s} 
+rss.internal.test.url=Feu clic aqu\u00ed per visualitzar la p\u00e0gina principal local
+cat.rss.gen=Crea el prove\u00efdor de RSS local
+dht.backup.only=Nom\u00e9s c\u00f2pia de seguretat DHT 
+TableColumn.header.ipfilter=Filtre d'adreces IP habilitat
+device.mediaserver.remove_all=Elimina tots els servidors multim\u00e8dia
+device.mediaserver.remove_all.title=Confirma l'eliminaci\u00f3
+device.mediaserver.remove_all.desc=Segur que voleu eliminar tots els servidors multim\u00e8dia?
+device.tag=Dispositiu d'etiquetatge
+device.onlyShowTagged=Mostra nom\u00e9s els dispositius etiquetats
+devices.sidebar.show.only.tagged=Mostra nom\u00e9s els dispositius etiquetats
+filter.header.matches1=(Resultats de la cerca: %1)
+filter.header.matches2=(Resultats de la cerca: %1, %2 d'actius)
+ipfilter.disabled=Filtres d'adreces IP deshabilitats
+ipfilter.options=Opcions del filtre d'adreces IP...
+subscriptions.column.SubWizName={FilesView.name} 
+subscriptions.column.SubWizRank={RCM.column.rc_rank} 
+SubscriptionWizard.column.SubWizName={FilesView.name} 
+torrentdownload.error.dl_fail=Ha fallat la desc\u00e0rrega de '%1' a '%2': %3
+MainWindow.menu.speed_limits=L\u00edmits de velocitat
+MainWindow.menu.speed_limits.profile=Introdueix un nom de perfil
+MainWindow.menu.speed_limits.profiles=Perfils
+MainWindow.menu.speed_limits.load=Aplica...
+MainWindow.menu.speed_limits.view=Visualitza...
+MainWindow.menu.speed_limits.delete=Esborra
+MainWindow.menu.speed_limits.view_current=Mostra els l\u00edmits actuals
+MainWindow.menu.speed_limits.save_current=Desa els l\u00edmits actuals com...
+MainWindow.menu.speed_limits.reset=Esborra els l\u00edmits actuals
+MainWindow.menu.speed_limits.info.title=Detalls dels l\u00edmits de velocitat
+MainWindow.menu.speed_limits.info.prof=Configuraci\u00f3 per al perfil '%1'
+MainWindow.menu.speed_limits.info.curr=Configuraci\u00f3 actual
+MainWindow.menu.speed_limits.schedule=Planifica...
+MainWindow.menu.speed_limits.schedule.title=Planifica els l\u00edmits de velocitat
+MainWindow.menu.speed_limits.schedule.msg=Normes vigents que controlen l'aplicaci\u00f3 autom\u00e0tica dels perfils de l\u00edmit de velocitat
+MainWindow.menu.speed_limits.schedule.err=S'ha informat dels errors seg\u00fcents. Feu-ne la reedici\u00f3 per resoldre'ls
+MainWindow.menu.advanced_tools=Avan\u00e7at
+torrent.fix.corrupt=Arregla el torrent malm\u00e8s...
+torrent.fix.corrupt.browse=Obre el torrent
+torrent.fix.corrupt.result.title=Resultat de l'operaci\u00f3
+torrent.fix.corrupt.result.nothing=Sembla que el torrent \u00e9s v\u00e0lid.
+FilesView.header={FilesView.title.full} 
+MyTorrentsView.menu.sl_remove_from_prof=Elimina del perfil
+MainWindow.menu.file.open.uri.keybinding=Meta+U 
+Button.open=Obre
+plugin.init.load.failed=Error de c\u00e0rrega del connector '%1' des de %2
+plugin.init.load.failed.classmissing=Desinstal\u00b7leu el connector via 'Eines > Connectors > Auxiliar de desintal\u00b7laci\u00f3' i tot seguit torneu-lo a instal\u00b7lar.
+device.playnow.group=Visualitza'l ara
+device.playnow.buffer=Mida de la mem\u00f2ria interm\u00e8dia abans de comen\u00e7ar la reproducci\u00f3 [segons]
+device.playnow.min_buffer=Mida de la mem\u00f2ria interm\u00e8dia en qu\u00e8 t\u00e9 lloc la rememoritzaci\u00f3 interm\u00e8dia [segons]
+ConfigView.section.backuprestore=Fes un c\u00f2pia de seguretat i restaura
+ConfigView.section.br.overview=Configureu els requisits per a la c\u00f2pia de seguretat del Vuze. Us permetr\u00e0 recuperar la configuraci\u00f3 en cas que es produeixi un error greu, com una fallada del disc.\n\nSi \u00e9s possible feu una c\u00f2pia de seguretat a una unitat separada de la que normalment es fa servir per executar el Vuze.\n\nTingueu en compte que les operacions que feu aqu\u00ed nom\u00e9s s'apliquen a les dades de configuraci\u00f3 del Vuze, i que haureu de gestiona [...]
+br.backup=C\u00f2pia de seguretat
+br.backup.manual.info=Configuraci\u00f3 manual de la c\u00f2pia de seguretat
+br.backup.folder.title=Seleccioneu la carpeta de la c\u00f2pia de seguretat
+br.backup.folder.info=Tria la carpeta en qu\u00e8 es gravar\u00e0 la c\u00f2pia de seguretat 
+br.restore=Restaura
+br.restore.info=Restaura la configuraci\u00f3 des d'una c\u00f2pia de seguretat
+br.restore.warning.title=Alerta de p\u00e8rdua de configuraci\u00f3!
+br.restore.warning.info=La restauraci\u00f3 de la configuraci\u00f3 substituir\u00e0 completament la que teniu actualment.\nConsidereu la possibilitat de fer-ne una c\u00f2pia de seguretat.
+br.backup.progress=Resultats de la c\u00f2pia de seguretat / restauraci\u00f3
+br.restore.folder.title=Selecciona la carpeta de restauraci\u00f3
+br.restore.folder.info=Seleccioneu la carpeta que cont\u00e9 la c\u00f2pia de seguretat anterior
+br.backup.auto.enable=Habilita les c\u00f2pies de seguretat autom\u00e0tiques
+br.backup.auto.dir.select=Trieu la carpeta per defecte de la c\u00f2pia de seguretat
+br.backup.auto.everydays=Freq\u00fc\u00e8ncia de les c\u00f2pies de seguretat [dies]
+br.backup.auto.retain=Nombre de c\u00f2pies de seguretat que voleu conservar
+br.backup.auto.now=Prova ara l'execuci\u00f3 de la c\u00f2pia de seguretat autom\u00e0tica 
+br.test=Prova
+TorrentOptionsView.param.upload.priority=Prioritat de c\u00e0rrega [0 = per defecte; 1 = prioritari]
+cat.upload.priority=Prioritat de c\u00e0rrega
+cat.options=Opcions de la desc\u00e0rrega actual...
+br.backup.last.time=L'\u00faltima c\u00f2pia de seguretat es va fer 
+br.backup.last.error=\u00daltim error de la c\u00f2pia de seguretat:
+br.backup.setup.info=Considereu establir la configuraci\u00f3 autom\u00e0tica de la c\u00f2pia de seguretat .\nVegeu 'Eines > Opcions > Fes una c\u00f2pia de seguretat i restaura'
+MainWindow.about.internet.contributors=Col\u00b7laboradors
+FileItem.low={SpeedTestWizard.name.conf.level.low} 
+FilePriority.invalid.title=Prioritat inv\u00e0lida
+FilePriority.invalid.text=Heu entrat un nombre inv\u00e0lid, cal que introdu\u00efu un nombre sencer: %1
+trackername.prefs.message=Llista dels noms de l'hostatjador del rastrejador separada per punt i coma\nPer exemple: a.b.com; c.d.net
+device.wiki=Wiki de suggeriments i consells...
+device.wiki.itunes=http://wiki.vuze.com/w/Devices_iTunes_Tips 
+ConfigView.option.dm.dblclick.launch={iconBar.run} 
+ConfigView.section.style.enableHeaderHeight=Personalitza l'al\u00e7ada de la cap\u00e7alera
+ConfigView.section.style.customDateFormat=Personalitza el format de la data
+br.backup.notify=Notifica la compleci\u00f3 de la c\u00f2pia de seguretat
+sidebar.LibraryCD.tooltip=Hi ha %1 torrent/s complet/s, %2 dels quals estan sembrant actualment
+sidebar.LibraryDL.tooltip=Hi ha %1 torrent&/s incomplet/s, %2 dels quals estan sembrant actualment
+ConfigView.label.lh.ext=Extensions 
+pairing.config.icon.show=Mostra la icona del Vuze Remot a la barra d'estat
+pairing.ui.icon.show=Mostra la icona
+pairing.ui.icon.tip=Estat de la connexi\u00f3 remota del Vuze
+wizard.newtorrent.byo=Feu-ho vosaltres mateixos
+wizard.newtorrent.byo.help=Feu el vostre torrent a partir d'una selecci\u00f3 de fitxers i carpetes
+wizard.newtorrent.byo.editname.title=Edita el nom de l'element
+wizard.newtorrent.byo.editname.text=Introdueix el nom de l'element com apareix al torrent
+wizard.newtorrent.byo.addcontainer.title=Afegeix un contenidor
+wizard.newtorrent.byo.addcontainer.text=Introdu\u00efu el nom del contenidor tal com apareix al torrent
+label.torrent.structure=Estructura del torrent
+label.original.file=Fitxer original
+button.add.container=Afegeix un contenidor
+label.container.display=<contenidor>
+TableColumn.header.torrentrelpath=Cam\u00ed del torrent
+TableColumn.header.torrentrelpath.info=Localitzaci\u00f3 relativa del fitxer al torrent
+TableColumn.header.torrentfileindex=\u00cdndex del fitxer
+TableColumn.header.torrentfileindex.info=\u00cdndex del fitxer al torrent
+label.information={wizard.information} 
+label.protocol={Peers.column.Protocol} 
+ConfigView.section.tracker.client.enabletcp=Habilita el protocol del client del rastrejador HTTP/HTTPS
+ConfigView.label.sleep.download=Descarregant
+TableColumn.header.fileext=Tipus de fitxer
+TableColumn.header.fileext.info=Tipus de fitxer / extensi\u00f3 del fitxer principal de la desc\u00e0rrega
+FilesView.click=Feu clic a...
+FilesView.click.info=Feu clic aqu\u00ed per calcular; feu servir el bot\u00f3 dret del ratol\u00ed per a c\u00e0lculs m\u00faltiples 
+ConfigView.section.connection.port.rand.range=Rang de ports [m\u00edn.-m\u00e0x.]
+ConfigView.section.connection.port.rand.together=El mateix port per a TCP i UDP
diff --git a/org/gudy/azureus2/internat/MessagesBundle_cs_CZ.properties b/org/gudy/azureus2/internat/MessagesBundle_cs_CZ.properties
index 1e39170..2bcd5e1 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_cs_CZ.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_cs_CZ.properties
@@ -1,278 +1,291 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=.torrent soubor
-Main.parameter.usage=Pou\u017eit\u00ed : java org.gudy.azureus2.cl.Main [parametry] "soubor.torrent" "c\u00edlov\u00e1 slo\u017eka"
-Main.parameter.maxUploads=Maxim\u00e1ln\u00ed po\u010det simult\u00e1ln\u00edch upload\u016f
-Main.parameter.maxSpeed=Maxim\u00e1ln\u00ed rychlost uploadu (B/s)
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=Soubor Torrent...
+Main.parameter.usage=Pou\u017eit\u00ed : java org.gudy.azureus2.cl.Main [parametry] "soubor.torrent" "cesta ulo\u017een\u00ed"
+Main.parameter.maxUploads=Maxim\u00e1ln\u00ed po\u010det soub\u011b\u017en\u00fdch odes\u00edl\u00e1n\u00ed
+Main.parameter.maxSpeed=Maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed v bajtech/sek
 MainWindow.menu.file=&Soubor
 MainWindow.menu.file.open=&Otev\u0159\u00edt
-MainWindow.menu.file.create=&Vytvo\u0159it Torrent
-MainWindow.menu.file.create.fromfile=Ze &souboru
-MainWindow.menu.file.create.fromdir=Ze s&lo\u017eky
-MainWindow.menu.file.export=&Exportovat Torrent do XML...
-MainWindow.menu.file.import=&Importovat Torrent z XML...
-MainWindow.menu.file.closetab=Zav\u0159\u00edt &Tab
+MainWindow.menu.file.create=&Nov\u00fd Torrent...
+MainWindow.menu.file.create.fromfile=Ze &Souboru
+MainWindow.menu.file.create.fromdir=Z &Adres\u00e1\u0159e
+MainWindow.menu.file.export=&Exportovat XML Torrent...
+MainWindow.menu.file.import=&Importovat XML Torrent...
+MainWindow.menu.file.closetab=Zav\u0159\u00edt &Kartu
 MainWindow.menu.file.closewindow=Zav\u0159\u00edt &Okno
 MainWindow.menu.file.exit=&Konec
 MainWindow.dialog.choose.file=Vyberte .torrent soubor
-MainWindow.menu.file.folder=S&lo\u017eku
-MainWindow.dialog.choose.folder=Vyberte slo\u017eku s .torrent soubory
+MainWindow.menu.file.folder=&Adres\u00e1\u0159...
+MainWindow.dialog.choose.folder=Vyberte adres\u00e1\u0159 obsahuj\u00edc\u00ed soubory torrent
 MainWindow.menu.view=&Zobrazit
 MainWindow.menu.view.show=Zobrazit
-MainWindow.menu.view.mytorrents=&Moje Torrenty
+MainWindow.menu.view.open_global_transfer_bar=Li\u0161ta P\u0159enos\u016f
 MainWindow.menu.view.configuration=&Nastaven\u00ed
-MainWindow.menu.view.console=&Konzola
-MainWindow.menu.closealldetails=Schovat v\u0161echny &Detaily
-MainWindow.menu.closealldownloadbars=Schovat v\u0161echny &Informa\u010dn\u00ed prou\u017eky
+MainWindow.menu.view.console=&Konzole
+MainWindow.menu.view.allpeers=V\u0161ichni Klienti
+MainWindow.menu.view.detailedlist=&Seznam Podrobnost\u00ed
+MainWindow.menu.closealldetails=Zav\u0159\u00edt V\u0161echny &Podrobnosti
+MainWindow.menu.closealldownloadbars=Zav\u0159\u00edt V\u0161echny &Li\u0161ty Stahov\u00e1n\u00ed
 MainWindow.menu.language=&Jazyk
 ConfigView.section.language=Jazyk
 MainWindow.menu.window=&Okno
 MainWindow.menu.window.minimize=&Minimalizovat
 MainWindow.menu.window.zoom=&Zv\u011bt\u0161it
-MainWindow.menu.window.alltofront=P\u0159esunot v\u0161e na &za\u010d\u00e1tek
+MainWindow.menu.window.alltofront=P\u0159esunout V\u0161e &Dop\u0159edu
 MainWindow.menu.help=&N\u00e1pov\u011bda
-MainWindow.menu.help.about=&O programu Vuze
+MainWindow.menu.help.about=O Vuze
 MainWindow.about.title=O programu Vuze
 MainWindow.about.section.developers=V\u00fdvoj\u00e1\u0159i
 MainWindow.about.section.translators=P\u0159ekladatel\u00e9
 MainWindow.about.section.system=Syst\u00e9m
-MainWindow.about.internet.homepage=Domovsk\u00e1 str\u00e1nka programu Vuze
-MainWindow.about.internet.sourceforge=Sourceforge - Str\u00e1nka projetku
-MainWindow.about.internet.sourceforgedownloads=Sourceforge - Downloads
+MainWindow.about.internet.homepage=Domovsk\u00e1 str\u00e1nka Vuze
+MainWindow.about.internet.sourceforge=Str\u00e1nka projektu na Sourceforge
+MainWindow.about.internet.sourceforgedownloads=Sourceforge - Ke Sta\u017een\u00ed
 MainWindow.about.internet.bugreports=Hl\u00e1\u0161en\u00ed chyb
 MainWindow.about.internet.forumdiscussion=Diskusn\u00ed f\u00f3ra
 MainWindow.about.internet.wiki=Vuze Wiki \u010dast\u00e9 dotazy
-MainWindow.dialog.choose.savepath=Vyberte c\u00edlovou slo\u017eku
-MainWindow.dialog.choose.savepath_forallfiles=Vyberte c\u00edlovou slo\u017eku pro V\u0160ECHNY soubory
+MainWindow.dialog.choose.savepath=Vyberte cestu pro ulo\u017een\u00ed
+MainWindow.dialog.choose.savepath_forallfiles=Vyberte cestu pro ulo\u017een\u00ed pro V\u0160ECHNY soubory
 MainWindow.status.latestversion=Nejnov\u011bj\u0161\u00ed
-MainWindow.status.latestversion.clickupdate=Klin\u011bte pro update
+MainWindow.status.latestversion.clickupdate=Klikn\u011bte pro aktualizaci
 MainWindow.status.unknown=nezn\u00e1m\u00fd
 MainWindow.status.checking=zji\u0161\u0165uji
-MyTorrentsView.mytorrents=Moje Torrenty
 TableColumn.header.name=N\u00e1zev 
 TableColumn.header.size=Velikost 
 TableColumn.header.done=Hotovo 
-TableColumn.header.done.info=Ud\u00e1v\u00e1 na kolik procent je pr\u00e1v\u011b prob\u00edhaj\u00edc\u00ed \u00fakol dokon\u010den
+TableColumn.header.done.info=Kolik Procent je ze sou\u010dasn\u00e9ho \u00fakolu hotovo
 TableColumn.header.status=Stav 
 TableColumn.header.status.info=Ud\u00e1v\u00e1, co se s torrentem pr\u00e1v\u011b d\u011bje
 TableColumn.header.seeds=Zdroje 
-TableColumn.header.seeds.info=Ud\u00e1v\u00e1 po\u010det p\u0159ipojen\u00fdch zdroj\u016f (celkov\u00fd po\u010det zdroj\u016f)
+TableColumn.header.seeds.info=Po\u010det zdroj\u016f, ke kter\u00fdm jste p\u0159ipojeni (celkov\u00fd po\u010det zdroj\u016f)
 TableColumn.header.peers=Klienti 
-TableColumn.header.peers.info=Ud\u00e1v\u00e1 po\u010det p\u0159ipojen\u00fdch klient\u016f (celkov\u00fd po\u010det klient\u016f)
-TableColumn.header.downspeed=Download rychlost 
-TableColumn.header.upspeed=Upload rychlost 
-TableColumn.header.eta=Zb\u00fdv\u00e1 
-TableColumn.header.tracker=Server
-TableColumn.header.tracker.info=Ud\u00e1v\u00e1 stav serveru
-TableColumn.header.trackernextaccess=Dal\u0161\u00ed tracker je p\u0159\u00edstupn\u00fd
-TableColumn.header.trackernextaccess.info=Nastavit p\u0159istup dal\u0161\u00edho servru
+TableColumn.header.peers.info=Po\u010det klient\u016f, ke kter\u00fdm jste p\u0159ipojeni (celkov\u00fd po\u010det klient\u016f)
+TableColumn.header.completed=Dokon\u010deno
+TableColumn.header.completed.info=Po\u010det klient\u016f, kte\u0159\u00ed dokon\u010dili stahov\u00e1n\u00ed torrentu, jak je hl\u00e1\u0161eno trackerem
+TableColumn.header.downspeed=Rychlost Stahov\u00e1n\u00ed
+TableColumn.header.upspeed=Rychlost Odes\u00edl\u00e1n\u00ed
+TableColumn.header.eta=\u010cas dokon\u010den\u00ed
+TableColumn.header.tracker=Stav Trackeru
+TableColumn.header.tracker.info=Stav trackeru
+TableColumn.header.trackernextaccess=Dal\u0161\u00ed p\u0159\u00edstup ke trackeru
+TableColumn.header.trackernextaccess.info=Kdy se provede dal\u0161\u00ed p\u0159\u00edstup ke trackeru
 TableColumn.header.priority=Priorita 
-TableColumn.header.priority.info=Ur\u010duje, jak velk\u00fd datov\u00fd tok pro upload je torrentu vyhrazen
-TableColumn.header.seeds.fullcopycalc=%2 p\u0159ezet\u00ed upln\u00fdch kopi\u00ed pro %1 peers
-MyTorrentsView.menu.showdetails=&Zobrazit Detaily 
-MyTorrentsView.menu.showdownloadbar=Zobrazit &Informa\u010dn\u00ed prou\u017eek 
-MyTorrentsView.menu.open=&Otev\u0159\u00edt 
-MyTorrentsView.menu.setpriority=Nastavit &prioritu 
+TableColumn.header.priority.info=Ur\u010duje, jak velk\u00e1 \u0161\u00ed\u0159ka p\u00e1sma odes\u00edl\u00e1n\u00ed je torrentu d\u00e1na
+TableColumn.header.seeds.fullcopycalc=%2 p\u0159edpokl\u00e1dan\u00fdch \u00fapln\u00fdch kopi\u00ed pro %1 klient\u016f
+MyTorrentsView.menu.showdetails=&Zobrazit Podrobnosti
+MyTorrentsView.menu.showdownloadbar=Zobrazit Li\u0161tu &Stahov\u00e1n\u00ed
+MyTorrentsView.menu.open=&Otev\u0159\u00edt Soubor
+MyTorrentsView.menu.setpriority=Nastavit &Prioritu 
 MyTorrentsView.menu.setpriority.high=&Vysok\u00e1 
 MyTorrentsView.menu.setpriority.low=&N\u00edzk\u00e1 
-MyTorrentsView.menu.start=&Start 
-MyTorrentsView.menu.stop=Sto&p 
-MyTorrentsView.menu.remove=O&debrat 
-MyTorrentsView.menu.changeTracker=P\u0159idat URL &Servru 
+MyTorrentsView.menu.start=&Spustit
+MyTorrentsView.menu.stop=&Zastavit
+MyTorrentsView.menu.remove=&Odebrat 
+MyTorrentsView.menu.changeTracker=P\u0159idat URL &Trackeru
 TrayWindow.menu.exit=&Konec 
 TrayWindow.menu.show=&Zobrazit Vuze
 SystemTray.menu.exit=&Konec 
-SystemTray.menu.closealldownloadbars=Schovat v\u0161echny &Informa\u010dn\u00ed prou\u017eky
+SystemTray.menu.closealldownloadbars=Zav\u0159\u00edt V\u0161echny Li\u0161ty &Stahov\u00e1n\u00ed
+SystemTray.menu.open_global_transfer_bar=Zobrazit Li\u0161tu P\u0159enos\u016f
 SystemTray.menu.show=&Zobrazit Vuze
-PeersView.ip.info=IP adresa p\u0159ipojen\u00e9ho u\u017eivatele
-PeersView.port.info=Pou\u017eit\u00fd port
-PeersView.T.info=L (lok\u00e1ln\u00ed): P\u0159ipojen\u00ed bylo nav\u00e1z\u00e1no odsud, R (vzd\u00e1len\u00e9): P\u0159ipojen\u00ed bylo nav\u00e1z\u00e1no zven\u010d\u00ed
-PeersView.T.L.tooltip=P\u0159ipojen\u00ed bylo nav\u00e1z\u00e1no odsud
-PeersView.T.R.tooltip=P\u0159ipojen\u00ed bylo nav\u00e1z\u00e1no zven\u010d\u00ed
-PeersView.I1=I (Klient m\u00e1 pro mne zaj\u00edmav\u00e9 \u010d\u00e1sti)
-PeersView.I1.info=M\u00e1 klient pro mne zaj\u00edmav\u00e9 \u010d\u00e1sti?
-PeersView.C1=C (Vybr\u00e1n klientem)
-PeersView.C1.info=Ud\u00e1v\u00e1, jestli klient zastavuje Va\u0161e stahov\u00e1n\u00ed od n\u011bj
+PeersView.ip.info=IP adresa klienta
+PeersView.port.info=Pou\u017e\u00edvan\u00fd port
+PeersView.T.info=L (m\u00edstn\u00ed): Vy jste nav\u00e1zali p\u0159ipojen\u00ed, R (vzd\u00e1len\u00e9): klient nav\u00e1zal spojen\u00ed.
+PeersView.T.L.tooltip=Nav\u00e1zali jste spojen\u00ed
+PeersView.T.R.tooltip=Klient nav\u00e1zal spojen\u00ed
+PeersView.I1=J\u00e1 (Zaujat klientem)
+PeersView.I1.info=Zaj\u00edm\u00e1te se, co jin\u00fd klient m\u00e1?
+PeersView.C1=C (\u0160krcen klientem)
+PeersView.C1.info=Zda-li klient V\u00e1m br\u00e1n\u00ed od stahov\u00e1n\u00ed
 PeersView.pieces=D\u00edly
-PeersView.downloadspeed=Download rychlost
-PeersView.download=P\u0159ijato
-PeersView.I2=I (Klient se zaj\u00edm\u00e1 o m\u00e9 \u010d\u00e1sti)
-PeersView.I2.info=Zaj\u00edm\u00e1 se klient o m\u00e9 \u010d\u00e1sti?
-PeersView.C2=C (Klient je vybr\u00e1n)
-PeersView.C2.info=Ud\u00e1v\u00e1, jestli blokujete klienta od stahov\u00e1n\u00ed
-PeersView.uploadspeed=Upload rychlost
-PeersView.uploadspeed.info=Rychlost odes\u00edl\u00e1n\u00ed ke klientovi
+PeersView.downloadspeed=Rychlost Stahov\u00e1n\u00ed
+PeersView.download=Sta\u017eeno
+PeersView.download.info=Va\u0161e celkov\u00e9 sta\u017een\u00ed od klienta.
+PeersView.I2=J\u00e1 (Zaj\u00edmav\u00fd pro klienta)
+PeersView.I2.info=Zaj\u00edm\u00e1 se klient o to, co m\u00e1te?
+PeersView.C2=C (\u0160krt\u00edm klienta)
+PeersView.C2.info=Zda-li blokujete klienta od stahov\u00e1n\u00ed
+PeersView.uploadspeed=Rychlost Stahov\u00e1n\u00ed
+PeersView.uploadspeed.info=Va\u0161e rychlost odes\u00edl\u00e1n\u00ed ke klientovi
 PeersView.upload=Odesl\u00e1no
-PeersView.upload.info=Celkov\u00e9 mno\u017estv\u00ed odeslan\u00fdch dat klientovi
-PeersView.statup=Stav Up
-PeersView.statup.info=Odhadovan\u00e1 celkov\u00e1 rychlost odes\u00edl\u00e1n\u00ed klienta
-PeersView.S.info=Nespolehliv\u00fd: Klient m\u016f\u017ee b\u00fdt ozna\u010den "nespolehliv\u00fdm" manualn\u011b nebo automaticky (za nedostate\u010dn\u011b rychl\u00e9 odes\u00edl\u00e1n\u00ed dat)
-PeersView.downloadspeedoverall=Celkov\u00e1 Download rychlost
+PeersView.upload.info=Celkov\u00e9 odesl\u00e1n\u00ed klientovi
+PeersView.statup=Stav Odes\u00edl\u00e1n\u00ed
+PeersView.statup.info=Odhadovan\u00e1 hodnota rychlosti odes\u00edl\u00e1n\u00ed klienta
+PeersView.S=N
+PeersView.S.info=Nespolehliv\u00fd: Klient m\u016f\u017ee b\u00fdt ozna\u010den "nespolehliv\u00fdm" ru\u010dn\u011b nebo automaticky (za nedostate\u010dn\u011b rychl\u00e9 odes\u00edl\u00e1n\u00ed dat)
+PeersView.downloadspeedoverall=Celkov\u00e1 Rychlost Stahov\u00e1n\u00ed
 PeersView.optunchoke=Opt. uvoln\u011bn\u00ed
 PeersView.client=Klient
-PeersView.client.info=BitTorrent program, kter\u00fd klient pou\u017e\u00edv\u00e1
-PeersView.menu.snubbed=&Ned\u016fv\u011bryhodn\u00fd
-PeersView.title.short=Zdroje
-PeersView.title.full=Zdroje
+PeersView.client.info=Typ BT klienta, kter\u00fd klient pou\u017e\u00edv\u00e1
+PeersView.menu.snubbed=&Nespolehliv\u00fd
+PeersView.title.short=Klienti
+PeersView.title.full=Klienti
+AllPeersView.title.full=V\u0161ichni Klienti
 ConfigView.section.files=Soubory
-ConfigView.label.usefastresume=Pou\u017e\u00edvat m\u00f3d rychl\u00e9ho obnoven\u00ed
+ConfigView.label.usefastresume=Pou\u017e\u00edt Re\u017eim Rychl\u00e9ho Pokra\u010dov\u00e1n\u00ed
 ConfigView.label.incrementalfile=Povolit postupn\u00e9 vytv\u00e1\u0159en\u00ed soubor\u016f [Nutn\u00e9 p\u0159i pou\u017e\u00edv\u00e1n\u00ed souborov\u00e9ho syst\u00e9mu FAT32 v Linuxu]
-ConfigView.label.defaultsavepath=Ukl\u00e1dat do v\u00fdchoz\u00ed slo\u017eky
-ConfigView.button.browse=Proch\u00e1zet...
-ConfigView.dialog.choosedefaultsavepath=Vyberte v\u00fdchoz\u00ed c\u00edlovou slo\u017eku 
-ConfigView.section.server=Server 
+ConfigView.label.defaultsavepath=Ukl\u00e1dat do v\u00fdchoz\u00edho adres\u00e1\u0159e dat
+ConfigView.button.browse=&Proch\u00e1zet...
+ConfigView.dialog.choosedefaultsavepath=Vyberte pros\u00edm v\u00fdchoz\u00ed adres\u00e1\u0159 pro ulo\u017een\u00ed
+ConfigView.section.server=P\u0159ipojen\u00ed
 ConfigView.section.global=Obecn\u00e9 
-ConfigView.label.disconnetseed=Kdy\u017e jsem zdroj, odpojit ostatn\u00ed zdroje 
-ConfigView.label.switchpriority=Kdy\u017e jsem zdroj, automaticky p\u0159epnout na n\u00edzkou prioritu
-ConfigView.label.maxdownloads=Max. po\u010det simult\u00e1ln\u00edch download\u016f [0: neomezen\u011b]
-ConfigView.label.maxdownloads.tooltip=V\u017edy budete schopen aktivn\u011b stahovat po\u010det, kter\u00fd poskytnete.\nKompletn\u00ed  torrent odpov\u00eddaj\u00edc\u00ed prvn\u00ed priorit\u011b m\u016f\u017ee p\u0159evz\u00edt download slotem.
-ConfigView.label.maxactivetorrents=Max. po\u010det aktivn\u00edch Torrent\u016f [0: neomezen\u011b]\n - Nov\u00e9 Torrenty se automaticky nespust\u00ed, pokud jich stahujete/distribujete v\u00edc
-ConfigView.label.priorityExtensions=Zv\u00fd\u0161it prioritu pro soubory s p\u0159\u00edponou\n - nap\u0159\u00edklad: .txt;.nfo;.jpg 
+ConfigView.label.disconnetseed=Odpojit ostatn\u00ed zdroje p\u0159i distribuci
+ConfigView.label.switchpriority=P\u0159i distribuci automaticky p\u0159epnout na n\u00edzkou prioritu
+ConfigView.label.maxdownloads=Max. simult\u00e1nn\u00edch stahov\u00e1n\u00ed [0: neomezen\u011b]\n - Nem\u016f\u017ee b\u00fdt v\u00fd\u0161e ne\u017e po\u010det max aktivn\u00edch torrent\u016f
+ConfigView.label.maxdownloads.tooltip=V\u017edy budete schopni aktivn\u011b stahovat po\u010det, kter\u00fd zde zad\u00e1te, s jednou v\u00fdj\u00edmkou.\nDokon\u010den\u00fd torrent shoduj\u00edc\u00ed se s Prvn\u00ed Prioritou m\u016f\u017ee p\u0159evz\u00edt pozici aktivn\u00edho stahov\u00e1n\u00ed, pokud je to absolutn\u011b nutn\u00e9.
+ConfigView.label.maxactivetorrents=Max. aktivn\u00edch torrent\u016f [0: neomezen\u011b]\n - Nov\u00e9 torrenty nebudou automaticky spu\u0161t\u011bny, pokud jich v\u00edce stahujete/distribuujete
+ConfigView.label.priorityExtensions=Automaticky up\u0159ednost\u0148ovat soubory s \n - nap\u0159.: .txt;.nfo;.jpg 
 ConfigView.section.transfer=P\u0159enos 
-ConfigView.label.maxuploads=V\u00fdchoz\u00ed max.upload\u016f na torrent 
-ConfigView.label.maxuploadspeed=Celkov\u00e1 max.rychlost uploadu v KB/s [0: neomezen\u011b]
+ConfigView.label.maxuploads=V\u00fdchoz\u00ed max. pozic odes\u00edl\u00e1n\u00ed na torrent
+ConfigView.label.maxuploadspeed=Celkov\u00e1 max rychlost odes\u00edl\u00e1n\u00ed v KB/s [0: neomezen\u011b]
 ConfigView.label.saveresumeinterval=Ukl\u00e1dat data pro obnoven\u00ed ka\u017ed\u00fdch 
 ConfigView.unlimited=Neomezen\u011b
 ConfigView.section.display=Zobrazen\u00ed 
-ConfigView.label.opendetails=Automaticky zobrazovat tabulku s detaily (Detaily)
-ConfigView.label.openbar=Automaticky zobrazovat informa\u010dn\u00ed prou\u017eek 
-ConfigView.label.closetotray=Zav\u0159en\u00ed programu jej minimalizuje do syst\u00e9mov\u00e9 li\u0161ty.
-ConfigView.label.minimizetotray=Minimalizovat do syst\u00e9mov\u00e9 li\u0161ty.
+ConfigView.label.opendetails=Automaticky otev\u0159\u00edt li\u0161tu podrobnost\u00ed
+ConfigView.label.openbar=Automaticky otev\u0159\u00edt li\u0161tu stahov\u00e1n\u00ed
+ConfigView.label.use_old_speed_menus=Pou\u017e\u00edt starom\u00f3dn\u00ed menu rychlosti [vy\u017eaduje restart]
+ConfigView.label.closetotray=Zav\u0159en\u00ed minimalizuje do Syst\u00e9mov\u00e9 Li\u0161ty.
+ConfigView.label.minimizetotray=Minimalizace minimalizuje do Syst\u00e9mov\u00e9 Li\u0161ty
 ConfigView.section.general=Obecn\u00e9 
 ConfigView.section.start=Spu\u0161t\u011bn\u00ed 
 ConfigView.label.showsplash=Zobrazit uv\u00edtac\u00ed obrazovku 
-ConfigView.label.autoupdate=Zobrazit dialogov\u00e9 okno o nov\u00e9 verzi, pokud je dostupn\u00e1.
-ConfigView.label.openconsole=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt konzoli (Konzole)
-ConfigView.label.openconfig=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt nastaven\u00ed (Nastaven\u00ed)
-ConfigView.label.startminimized=Spustit Azurea minimalizovan\u011b 
-ConfigView.section.irc=IRC 
-ConfigView.label.ircwiki=Pros\u00edm \u010dt\u011bte na http://www.azureuswiki.com/index.php/Rules_for_IRC
-ConfigView.label.ircserver=Server 
+ConfigView.label.autoupdate=Otev\u0159\u00edt dialogov\u00e9 okno Aktualizace, pokud je nov\u00e1 verze dostupn\u00e1.
+ConfigView.label.openconsole=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt Konzoli
+ConfigView.label.openconfig=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt Nastaven\u00ed
+ConfigView.label.startminimized=Spustit minimalizovan\u011b 
+ConfigView.label.ircwiki=Pros\u00edm p\u0159e\u010dt\u011bte si http://www.azureuswiki.com/index.php/Rules_for_IRC
 ConfigView.label.ircchannel=Kan\u00e1l 
 ConfigView.label.irclogin=P\u0159ezd\u00edvka 
 ConfigView.group.irctitle=IRC Nastaven\u00ed
-ConfigView.boolean.ircsendinfo=Povolit odesl\u00e1n\u00ed Va\u0161eho nastaven\u00ed (anonymn\u011b) \n kan\u00e1lov\u00e9mu operatorovi pro pomoc.
-ConfigView.boolean.irclog=Povolit z\u00e1pis o \u010dinnosti kan\u00e1lu (in IRC_log.htm)
+ConfigView.boolean.ircsendinfo=Povolit odesl\u00e1n\u00ed Va\u0161eho nastaven\u00ed (anonymn\u011b)\n oper\u00e1tor\u016fm kan\u00e1lu pro usnadn\u011bn\u00ed jejich pomoci V\u00e1m.
+ConfigView.boolean.irclog=Povolit z\u00e1pis o \u010dinnosti kan\u00e1lu (do IRC_log.htm)
 ConfigView.section.security=Zabezpe\u010den\u00ed 
-ConfigView.label.password=Chr\u00e1nit Vuze heslem\n - Bude po\u017eadov\u00e1no p\u0159i obnoven\u00ed z ikonky a p\u0159i spu\u0161t\u011bn\u00ed 
-ConfigView.label.passwordconfirm=Heslo (znovu - potvrzen\u00ed) 
-ConfigView.label.passwordmatch=Heslo je aktivn\u00ed : 
+ConfigView.label.password=Chr\u00e1nit Vuze pou\u017eit\u00edm hesla\n - Bude po\u017eadov\u00e1no p\u0159i obnoven\u00ed z ikonky a p\u0159i spu\u0161t\u011bn\u00ed 
+ConfigView.label.passwordconfirm=Heslo (potvrzen\u00ed) 
+ConfigView.label.passwordmatch=Heslo aktivov\u00e1no : 
 ConfigView.label.passwordmatchnone=Ne 
 ConfigView.label.passwordmatchno=Ne / Hesla se neshoduj\u00ed
 ConfigView.label.passwordmatchyes=Ano 
 ConfigView.button.save=Ulo\u017eit 
 ConfigView.title.short=Nastaven\u00ed 
 ConfigView.title.full=Nastaven\u00ed 
+ConfigView.title.full._mac=Mo\u017enosti
 ConsoleView.title.short=Konzole 
 ConsoleView.title.full=Konzole 
 FileItem.write=Z\u00e1pis 
 FileItem.read=\u010cten\u00ed 
-FileItem.normal=norm\u00e1ln\u00ed 
-FileItem.high=vysok\u00e1 
+FileItem.normal=Norm\u00e1ln\u00ed 
+FileItem.high=Vysok\u00e1 
 FileItem.donotdownload=Nestahovat 
+FileItem.delete=Smazat
 FilesView.name=Jm\u00e9no 
+FilesView.name.fastRename=Rychl\u00e9 P\u0159ejmenov\u00e1n\u00ed
 FilesView.size=Velikost 
 FilesView.done=Hotovo 
 FilesView.%=% 
 FilesView.firstpiece=Prvn\u00ed d\u00edl \u010d. 
 FilesView.numberofpieces=Po\u010det d\u00edl\u016f 
 FilesView.pieces=D\u00edly 
-FilesView.mode=M\u00f3d 
+FilesView.mode=Re\u017eim
 FilesView.priority=Priorita 
 FilesView.menu.open=&Otev\u0159\u00edt 
 FilesView.menu.setpriority=Nastavit &prioritu 
 FilesView.menu.setpriority.high=&Vysok\u00e1 
-FilesView.menu.setpriority.normal=&Normaln\u00ed 
+FilesView.menu.setpriority.normal=&Norm\u00e1ln\u00ed 
 FilesView.menu.setpriority.skipped=Ne&stahovat 
 FilesView.title.short=Soubory 
 FilesView.title.full=Soubory
 GeneralView.section.downloaded=Sta\u017eeno 
-GeneralView.label.status.file=Stav souboru 
-GeneralView.label.status.pieces=Sta\u017een\u00e9 d\u00edly 
+GeneralView.label.status.file=Stav Souboru 
+GeneralView.label.status.pieces=Stav D\u00edl\u016f
 GeneralView.section.availability=Dostupnost
-GeneralView.label.status.pieces_available=Dostupnost d\u00edl\u016f 
-GeneralView.section.transfer=P\u0159esun 
+GeneralView.label.status.pieces_available=Stav D\u00edl\u016f
+GeneralView.section.transfer=P\u0159enos
 GeneralView.section.info=Informace 
 GeneralView.title.short=Torrent 
 GeneralView.title.full=Torrent 
 GeneralView.label.timeelapsed=Uplynul\u00fd \u010das: 
 GeneralView.label.remaining=Zb\u00fdvaj\u00edc\u00ed \u010das : 
 GeneralView.label.downloaded=Sta\u017eeno : 
-GeneralView.label.downloadspeed=Rychlost downloadu : 
-GeneralView.label.maxuploads=Maximum upload\u016f:
-GeneralView.label.maxuploads.tooltip=Maxim\u00e1ln\u00ed po\u010det u\u017eivatel\u016f, kte\u0159\u00ed uvoln\u00ed p\u0159ipojen\u00ed v dan\u00e9m \u010dase.
+GeneralView.label.downloadspeed=Rychlost Stahov\u00e1n\u00ed : 
+GeneralView.label.maxuploads=Pozic Odes\u00edl\u00e1n\u00ed:
+GeneralView.label.maxuploads.tooltip=Maxim\u00e1ln\u00ed po\u010det u\u017eivatel\u016f, kte\u0159\u00ed budou uvoln\u011bny v dan\u00e9m \u010dase.
 GeneralView.label.uploaded=Odesl\u00e1no:
-GeneralView.label.uploadspeed=Rychlost uploadu:
+GeneralView.label.uploadspeed=Rychlost Odes\u00edl\u00e1n\u00ed:
 GeneralView.label.seeds=Zdroje : 
 GeneralView.label.peers=Klienti : 
+GeneralView.label.completed=Dokon\u010deno :
 GeneralView.label.totalspeed=Celkov\u00e1 rychlost:
-GeneralView.label.totalspeed.tooltip=Celkov\u00e1 rychlost v\u0161ech p\u0159ipojen\u00fdch klient\u016f.
+GeneralView.label.totalspeed.tooltip=Celkov\u00e1 (a pr\u016fm\u011brn\u00e1) rychlost v\u0161ech klient\u016f, ke kter\u00fdm jste p\u0159ipojeni.
 GeneralView.label.averagespeed=pr\u016fm\u011br
 GeneralView.label.filename=N\u00e1zev : 
 GeneralView.label.totalsize=Celkov\u00e1 velikost: 
-GeneralView.label.savein=C\u00edl : 
+GeneralView.label.savein=Ulo\u017eit Do :
 GeneralView.label.numberofpieces=Po\u010det d\u00edl\u016f : 
-GeneralView.label.size=Velikost d\u00edlu : 
-GeneralView.label.tracker=Stav trackeru : 
+GeneralView.label.size=Velikost : 
+GeneralView.label.tracker=Stav Trackeru : 
 GeneralView.label.updatein=Aktualizovat za: 
 GeneralView.label.trackerurl=URL Trackeru:
-GeneralView.label.trackerurlupdate=Aktualizovat server
-GeneralView.label.comment=Koment\u00e1\u0159 : 
-ManagerItem.waiting=\u010cek\u00e1n\u00ed
-ManagerItem.allocating=Alokace m\u00edsta
-ManagerItem.checking=Ov\u011b\u0159ov\u00e1n\u00ed
-ManagerItem.ready=P\u0159ipraven
-ManagerItem.downloading=Stahov\u00e1n\u00ed
-ManagerItem.seeding=Distribuce
+GeneralView.label.trackerurlupdate=Aktualizovat Tracker
+GeneralView.label.comment=Koment\u00e1\u0159 Torrentu : 
+GeneralView.label.user_comment=Koment\u00e1\u0159 U\u017eivatele:
+GeneralView.label.status=Stav :
+ManagerItem.waiting=\u010cek\u00e1m
+ManagerItem.allocating=P\u0159id\u011bluji
+ManagerItem.checking=Ov\u011b\u0159uji
+ManagerItem.ready=\u010cek\u00e1m na ostatn\u00ed torrenty, aby byly ve front\u011b
+ManagerItem.downloading=Stahuji
+ManagerItem.seeding=Distribuuji
 ManagerItem.stopped=Zastaveno
 ManagerItem.error=Chyba
 ManagerItem.high=vysok\u00e1
 ManagerItem.low=n\u00edzk\u00e1
 MinimizedWindow.name=N\u00e1zev:
+MinimizedWindow.all_transfers=P\u0159enosy Vuze
+PiecesView.#=\u010c.
 PiecesView.size=Velikost
 PiecesView.numberofblocks=Po\u010det blok\u016f
 PiecesView.blocks=Bloky
-PiecesView.completed=P\u0159ijato
+PiecesView.completed=Dokon\u010deno
 PiecesView.availability=Dostupnost
-PiecesView.reservedby=Z\u00e1lo\u017en\u00ed
-PiecesView.writers=Blokovan\u00ed p\u0159ip\u011bvatel\u00e9
+PiecesView.reservedby=Vyhrazeno
+PiecesView.writers=P\u0159isp\u011bvatel\u00e9 Blok\u016f
 PiecesView.title.short=D\u00edly
 PiecesView.title.full=D\u00edly
 SystemTray.tooltip.seeding=%1 distribuov\u00e1no,
 SystemTray.tooltip.downloading=%1 stahov\u00e1no,
-DownloadManager.error.filenotfound=Soubor nenalezen
+DownloadManager.error.filenotfound=Soubor Nenalezen
 DownloadManager.error.fileempty=Torrent soubor je pr\u00e1zdn\u00fd
 DownloadManager.error.filetoobig=Torrent soubor je moc velk\u00fd
 DownloadManager.error.filewithouttorrentinfo=Informace o Torrentu nebyly v souboru nalezeny
 DownloadManager.error.unsupportedencoding=Nepodporovan\u00e9 k\u00f3dov\u00e1n\u00ed
-DownloadManager.error.ioerror=Chyba V/V
-DownloadManager.error.sha1=Algoritmus nen\u00ed podporov\u00e1n (SHA1)
+DownloadManager.error.ioerror=Chyba IO
+DownloadManager.error.sha1=Chyba - \u017d\u00e1dn\u00fd takov\u00fd Algoritmus (SHA1) neexistuje
 PeerManager.status.offline=Chyba p\u0159ipojen\u00ed
-PeerManager.status.checking=Aktualizace
+PeerManager.status.checking=Kontrola
 PeerManager.status.finished=Dokon\u010deno
 PeerManager.status.finishedin=Dokon\u010deno za
-MainWindow.upgrade.assistant=Pr\u016fvodce aktualizac\u00ed
-MainWindow.upgrade.newerversion=Je k dispozici nov\u00e1 verze programu Azureus.
-MainWindow.upgrade.explanation=Tento pr\u016fvodce v\u00e1m pom\u016f\u017ee aktualizovat Azureus. St\u00e1hne novou verzi a restartuje program.
-MainWindow.upgrade.explanation.manual=Novou verzi m\u016f\u017eete nainstalovat ru\u010dn\u011b, zav\u0159en\u00edm programu, sta\u017een\u00edm nov\u00e9 verze do slo\u017eky programu a jeho op\u011btovn\u00fdm spu\u0161t\u011bn\u00edm.
-MainWindow.upgrade.step1=Krok 1: Sta\u017een\u00ed nov\u00e9 verze
-MainWindow.upgrade.step2=Krok 2: Zav\u0159en\u00ed t\u00e9to verze a spu\u0161t\u011bn\u00ed nov\u00e9 verze programu
-MainWindow.upgrade.hint1=Tip : Tla\u010d\u00edtkem Dokon\u010dit m\u016f\u017eete prov\u00e9st cel\u00fd proces automaticky
-MainWindow.upgrade.hint2=Tip : Pokud chcete ukon\u010dit Vuze pozd\u011bji, pou\u017eijte tla\u010d\u00edtko Storno.\n\tPo ukon\u010den\u00ed programu pak p\u0159ejmenujte soubor Azureus2-new.jar na Azureus2.jar
-MainWindow.upgrade.error.downloading.hint=Chyba : Nepoda\u0159ilo se st\u00e1hnout novou verzi programu Azureus. Aktualizujte pros\u00edm program ru\u010dn\u011b.
-MainWindow.upgrade.section.info=Dostupn\u00e1 nov\u00e1 verze programu
-MainWindow.upgrade.section.manual=Ru\u010dn\u00ed aktualizace
-MainWindow.upgrade.section.automatic=Automatick\u00e1 aktualizace
+MainWindow.upgrade.assistant=Pr\u016fvodce Aktualizac\u00ed
+MainWindow.upgrade.newerversion=Je k dispozici nov\u00e1 verze Vuze dostupn\u00e1 ke sta\u017een\u00ed
+MainWindow.upgrade.explanation=Tento pr\u016fvodce V\u00e1m st\u00e1hne novou verzi do Va\u0161eho adres\u00e1\u0159e Vuze a pak ho restartuje
+MainWindow.upgrade.explanation.manual=Aktualizovat m\u016f\u017eete ru\u010dn\u011b zav\u0159en\u00edm Vuze a st\u00e1hnut\u00edm nov\u00e9 Verze a pak Vuze restartujte
+MainWindow.upgrade.step1=Krok 1: St\u00e1hn\u011bte novou verzi
+MainWindow.upgrade.step2=Krok 2: Zav\u0159ete tuto verzi a spus\u0165te novou verzi Vuze
+MainWindow.upgrade.hint1=Tip:\tStisknut\u00edm Dokon\u010dit provede v\u0161echno automaticky
+MainWindow.upgrade.hint2=Tip:\tPokud chcete Vuze zav\u0159\u00edt pozd\u011bji, stiskn\u011bte Zru\u0161it a \n\tpo zav\u0159en\u00ed p\u0159ejmenujte Azureus2-new.jar na Azureus2.jar
+MainWindow.upgrade.error.downloading.hint=Chyba:\tNelze st\u00e1hnout novou verzi, pros\u00edm aktualizujte ru\u010dn\u011b
+MainWindow.upgrade.section.info=Nov\u00e1 Verze Je Dostupn\u00e1
+MainWindow.upgrade.section.manual=Ru\u010dn\u00ed Aktualizace
+MainWindow.upgrade.section.automatic=Automatick\u00e1 Aktualizace
 MainWindow.upgrade.tooltip.progressbar=Pr\u016fb\u011bh stahov\u00e1n\u00ed je zobrazen zde
 Button.next=Dal\u0161\u00ed 
 Button.finish=Dokon\u010dit 
-Button.cancel=Storno 
+Button.cancel=&Storno 
 LocaleUtil.title=Vyberte k\u00f3dov\u00e1n\u00ed 
-LocaleUtil.section.chooseencoding=Vyberte k\u00f3dov\u00e1n\u00ed pro soubor 
+LocaleUtil.section.chooseencoding=Vyberte k\u00f3dov\u00e1n\u00ed pro jm\u00e9no souboru
 LocaleUtil.label.chooseencoding=Vyberte k\u00f3dov\u00e1n\u00ed, kter\u00e9 nejv\u00edce odpov\u00edd\u00e1
-LocaleUtil.label.hint.doubleclick=Tip: Poklep\u00e1n\u00ed na \u0159\u00e1dek vybere k\u00f3dov\u00e1n\u00ed a zav\u0159e dialog
-LocaleUtil.label.checkbox.rememberdecision=Pamatovat nastaven\u00ed pro ostatn\u00ed soubory
+LocaleUtil.label.hint.doubleclick=Tip: Kliknut\u00edm dvakr\u00e1t na \u0159\u00e1dek vybere k\u00f3dov\u00e1n\u00ed a zav\u0159e dialogov\u00e9 okno
+LocaleUtil.label.checkbox.rememberdecision=Pamatovat si rozhodnut\u00ed pro zb\u00fdvaj\u00edc\u00ed jm\u00e9na soubor\u016f
 LocaleUtil.column.encoding=K\u00f3dov\u00e1n\u00ed
-IrcClient.defaultChannel=#Azureus-U\u017eivatel\u00e9
 IrcClient.copyright=Vuze pou\u017e\u00edv\u00e1 PircBot Java IRC API - http://www.jibble.org/pircbot.php 
 IrcClient.connecting=P\u0159ipojov\u00e1n\u00ed k 
 IrcClient.connected=P\u0159ipojeno k 
@@ -286,71 +299,68 @@ IrcClient.hasleft=ode\u0161el
 IrcClient.nowknown=je nyn\u00ed zn\u00e1m jako 
 IrcClient.topicforchannel=T\u00e9ma pro kan\u00e1l 
 IrcClient.disconnected=Odpojeno od 
-IrcClient.noNick=P\u0159ezd\u00edvka nen\u00ed nastavena. Pou\u017eijte 'Nastaven\u00ed' 
-IrcView.actionnotsupported=Tato akce nen\u00ed podporov\u00e1na 
+IrcClient.noNick=P\u0159ezd\u00edvka nen\u00ed nastavena. Pros\u00edm p\u0159ejd\u011bte do Zobrazen\u00ed 'Volby'
+IrcView.actionnotsupported=Tato \u010dinnost nen\u00ed podporov\u00e1na 
 IrcView.clientsconnected=u\u017eivatel\u016f 
 IrcView.privateto=Pro
 IrcView.privatefrom=Od
 IrcView.noticefrom=Ozn\u00e1men\u00ed : 
-IrcView.errormsg=\u0160patn\u00e1 syntaxe /msg : /msg u\u017eivatel zpr\u00e1va 
-IrcView.help=Pou\u017eiteln\u00e9 p\u0159\u00edkazy jsou :\n . /help : zobraz\u00ed tuto n\u00e1pov\u011bdu\n . /nick | /name : zm\u011bn\u00ed va\u0161i p\u0159ezd\u00edvku \n . /me \u00fakon : po\u0161le jako \u00fakon \n . /msg u\u017eivatel zpr\u00e1va : po\u0161le privatn\u00ed zpr\u00e1vu \n . /r message : odpov\u011b\u010f na posledn\u00ed privatn\u00ed zpr\u00e1vu\n . /join #kan\u00e1l : zm\u011bnit aktu\u00e1ln\u00ed kan\u00e1l  
+IrcView.errormsg=\u0160patn\u00e1 syntaxe v /msg : /msg u\u017eivatel text
+IrcView.help=Pou\u017eiteln\u00e9 p\u0159\u00edkazy jsou :\n . /help : zobraz\u00ed tuto n\u00e1pov\u011bdu\n . /nick | /name : zm\u011bn\u00ed Va\u0161e jm\u00e9no \n . /me \u010dinnost : po\u0161le \u010dinnost \n . /msg p\u0159ezd\u00edvka zpr\u00e1va : po\u0161le soukromou zpr\u00e1vu <p\u0159ezd\u00edvce> \n . /r zpr\u00e1va : odpov\u011b\u010f na posledn\u00ed soukromou zpr\u00e1vu\n . /join #kan\u00e1lB : (neklikejte sem, to je p\u0159\u00edklad) : zm\u011bn\u00ed sou\u010dasn\u00 [...]
 PasswordWindow.title=Vuze je uzam\u010den
-PasswordWindow.passwordprotected=Vuze je chr\u00e1n\u011bn heslem.\nNa zobrazen\u00ed hlavn\u00edho okna, vypl\u0148te heslo : 
-Button.ok=OK !
-TrackerChangerWindow.title=P\u0159idat Tracker
-TrackerChangerWindow.newtracker=Nov\u00e1 URL Trackeru
+PasswordWindow.passwordprotected=Vuze je chr\u00e1n\u011bn heslem.\nPro zobrazen\u00ed okna Vuze pros\u00edm zadejte sem Va\u0161e heslo :
 PeersView.discarded=Zahozeno
-PeersView.discarded.info=Data, kter\u00e1 v\u00e1m byla doru\u010dena a p\u0159itom nebyla pot\u0159eba a tak byla zahozena.
+PeersView.discarded.info=Data, kter\u00e1 v\u00e1m byla n\u011bjak doru\u010dena, i kdy\u017e jste je nepot\u0159ebovali, a tak jste se jich zbavili.
 discarded=zahozeno
 MyTorrentsView.#=\u010d\u00edslo
-MyTorrentsView.menu.move=Posunout
+MyTorrentsView.menu.move=&P\u0159esunout
 MyTorrentsView.menu.moveUp=&Nahoru
-MyTorrentsView.menu.moveDown=&Dolu
+MyTorrentsView.menu.moveDown=&Dol\u016f
 GeneralView.label.hashfails=Nesouhlas\u00edc\u00ed Hash : 
 GeneralView.label.shareRatio=Pom\u011br sd\u00edlen\u00ed : 
 ConfigView.section.downloadManagement=Spr\u00e1vce stahov\u00e1n\u00ed 
-ConfigView.label.startRatioPeers=Za\u010d\u00edt sd\u00edlet, kdy\u017e je m\u00e9n\u011b ne\u017e 1 zdroj na
-ConfigView.text.neverStop=Nikdy neukon\u010dit 
-ConfigView.text.neverStart=Nikdy neza\u010d\u00edt 
-ConfigView.text.peers=klient\u016f 
+ConfigView.label.startRatioPeers=Za\u010d\u00edt distribuovat, kdy\u017e je m\u00e9n\u011b ne\u017e 1 zdroj na
+ConfigView.text.neverStop=Nikdy Nezastavit
+ConfigView.text.neverStart=Nikdy Nespustit
+ConfigView.text.peers=Klient\u016f 
 ConfigView.label.checkOncompletion=Po dokon\u010den\u00ed stahov\u00e1n\u00ed znovu zkontrolovat d\u00edly
-wizard.title=Vytvo\u0159it Torrent 
+wizard.title=Vytvo\u0159it torrent 
 wizard.previous=< Zp\u011bt 
 wizard.next=Dal\u0161\u00ed > 
 wizard.finish=Dokon\u010dit 
-wizard.mode=Tracker / M\u00f3d 
+wizard.mode=Tracker / Re\u017eim
 wizard.tracker=Tracker: 
-wizard.invalidurl=Tato URL je neplatn\u00e1 
+wizard.invalidurl=Tato URL nen\u00ed platn\u00e1 
 wizard.singlefile=Jeden soubor 
-wizard.singlefile.help=Vytvo\u0159it Torrent z jednoho souboru 
-wizard.directory=Slo\u017eka 
-wizard.directory.help=Vytvo\u0159it Torrent ze slo\u017eky
+wizard.singlefile.help=Vytvo\u0159it torrent z jednoho souboru 
+wizard.directory=Adres\u00e1\u0159
+wizard.directory.help=Vytvo\u0159it torrent z adres\u00e1\u0159e
 wizard.choosefile=Vyberte soubor 
 wizard.file=Soubor : 
 wizard.browse=Proch\u00e1zet... 
-wizard.choosedirectory=Vyberte slo\u017eku
-wizard.invalidfile=Neplatn\u00fd soubor! 
-wizard.invaliddirectory=Neplatn\u00e1 slo\u017eka! 
+wizard.choosedirectory=Vyberte adres\u00e1\u0159
+wizard.invalidfile=Neplatn\u00fd Soubor! 
+wizard.invaliddirectory=Neplatn\u00fd Adres\u00e1\u0159! 
 wizard.torrentFile=Torrent soubor
-wizard.choosetorrent=Ulo\u017eit torrent soubor jako
+wizard.choosetorrent=Pros\u00edm vyberte soubor torrent k vytvo\u0159en\u00ed
 wizard.information=Informace 
-wizard.notimplemented=Nen\u00ed zat\u00edm implementov\u00e1no 
-wizard.progresstitle=Vytv\u00e1\u0159en\u00ed Torrent souboru 
-wizard.savingfile=Ukl\u00e1d\u00e1n\u00ed souboru... 
+wizard.notimplemented=Nen\u00ed zat\u00edm zavedeno
+wizard.progresstitle=Vytv\u00e1\u0159\u00edm Torrent souboru 
+wizard.savingfile=Ukl\u00e1d\u00e1m Soubor... 
 wizard.filesaved=Soubor ulo\u017een. 
 wizard.close=Zav\u0159\u00edt 
 Torrent.create.progress.piecelength=Velikost d\u00edlu: 
 Torrent.create.progress.piececount=Po\u010det d\u00edl\u016f: 
-Torrent.create.progress.totalfilesize=Celkov\u00e1 velikost: 
-Torrent.create.progress.totalfilecount=Po\u010det soubor\u016f: 
-Torrent.create.progress.parsingfiles=Anal\u00fdza soubor\u016f 
-Torrent.create.progress.hashing=Vytv\u00e1\u0159en\u00ed Hash 
-MainWindow.upgrade.downloadingfrom=Stahov\u00e1n\u00ed z : 
-MainWindow.menu.view.ipFilter=&IP filtry
+Torrent.create.progress.totalfilesize=Celkov\u00e1 velikost souboru: 
+Torrent.create.progress.totalfilecount=Celkov\u00fd po\u010det soubor\u016f: 
+Torrent.create.progress.parsingfiles=Analyzuji soubory
+Torrent.create.progress.hashing=Hashuji soubory
+MainWindow.upgrade.downloadingfrom=Stahuji z : 
+MainWindow.menu.view.ipFilter=&IP Filtry
 ConfigView.section.ipfilter=IP filtry
 ConfigView.section.ipfilter.description=Popis 
-ConfigView.section.ipfilter.start=Prvn\u00ed IP 
-ConfigView.section.ipfilter.end=Posledn\u00ed IP 
+ConfigView.section.ipfilter.start=Po\u010d\u00e1te\u010dn\u00ed IP 
+ConfigView.section.ipfilter.end=Kone\u010dn\u00e1 IP 
 ConfigView.section.ipfilter.add=P\u0159idat 
 ConfigView.section.ipfilter.remove=Odebrat 
 ConfigView.section.ipfilter.edit=Upravit 
@@ -358,26 +368,29 @@ ConfigView.section.ipfilter.save=Ulo\u017eit
 ConfigView.section.ipfilter.editFilter=Upravit filtr 
 ConfigView.section.ipfilter.enable=Povolit 
 PeersView.menu.close=&Zav\u0159\u00edt 
-seedmore.title=Torrent nen\u00ed dostate\u010dn\u011b distribuov\u00e1n 
-seedmore.shareratio=Pom\u011br stahov\u00e1n\u00ed tohoto torrentu je 
-seedmore.uploadmore=Pro BitTorrent s\u00ed\u0165 nen\u00ed dobr\u00e9 m\u00edt Pom\u011br sd\u00edlen\u00ed pod 100%.\nNechejte tento torrent sd\u00edlet je\u0161t\u011b chv\u00edli.\nOpravdu si p\u0159ejete torrent zastavit?
-ConfigView.label.showpopuponclose=Zobrazit varov\u00e1n\u00ed o nedostate\u010dn\u00e9 distribuci p\u0159i ukon\u010dov\u00e1n\u00ed torrentu, pokud m\u00e1te pom\u011br sd\u00edlen\u00ed pod 1
-ConfigView.label.startNumSeeds=\nZa\u010d\u00edt sd\u00edlet, pokud je m\u00e9n\u011b ne\u017e\n - Anuluje ostatn\u00ed nastaven\u00ed
+seedmore.title=Torrent nen\u00ed dostate\u010dn\u011b distribuov\u00e1n
+seedmore.shareratio=V\u00e1\u0161 pom\u011br v tomto torrentu je 
+seedmore.uploadmore=M\u00edt pom\u011br sd\u00edlen\u00ed pod 100 procent nen\u00ed dobr\u00e9 pro s\u00ed\u0165 bittorrent.\nM\u011bli byste nechat tento torrent distribuovat je\u0161t\u011b chvilku d\u00e9le.\nJste si jisti, \u017ee chcete pokra\u010dovat?
+ConfigView.label.showpopuponclose=Zobrazit vyskakuj\u00edc\u00ed potvrzen\u00ed, p\u0159i zastavov\u00e1n\u00ed distribuce s pom\u011brem sd\u00edlen\u00ed ni\u017e\u0161\u00edm ne\u017e 1
+ConfigView.label.startNumSeeds=\nZa\u010d\u00edt distribuovat, pokud je m\u00e9n\u011b ne\u017e\n - Potla\u010d\u00ed v\u0161echna ostatn\u00ed pravidla
 ConfigView.label.seeds=zdroji
 ConfigView.section.seeding=Distribuce 
-MyTorrentsView.menu.removeand=Odebrat a 
-MyTorrentsView.menu.removeand.deletetorrent=Smazat .&torrent 
-MyTorrentsView.menu.removeand.deletedata=Smazat &data 
-MyTorrentsView.menu.removeand.deleteboth=Smazat .torrent &i data
-deletedata.title=!!! Upozorn\u011bn\u00ed !!! 
-deletedata.message1=Chyst\u00e1te se smazat data z :\n 
-MainWindow.menu.file.configure=Spustit Pr\u016fvodce nastaven\u00ed 
-configureWizard.title=Pr\u016fvodce nastaven\u00ed
-configureWizard.welcome.title=V\u00edtejte v Pr\u016fvodci nastaven\u00ed 
-configureWizard.welcome.message=Tento pr\u016fvodce V\u00e1m pom\u016f\u017ee nastavit Vuze pro ka\u017edodenn\u00ed pou\u017e\u00edv\u00e1n\u00ed. Podrobn\u011bj\u0161\u00ed nastaven\u00ed m\u016f\u017eete prov\u00e9st pomoc\u00ed nab\u00eddky N\u00e1stroje > Nastaven\u00ed
-configureWizard.transfer.title=Nastaven\u00ed p\u0159ipojen\u00ed a p\u0159enos\u016f 
-configureWizard.transfer.hint=Tip : Nejlep\u0161\u00ed je nastavit o n\u011bco pomalej\u0161\u00ed linku, ne\u017e je Va\u0161e fyzick\u00e9 p\u0159ipojen\u00ed
-configureWizard.transfer.message=Vyberte zp\u016fsob p\u0159ipojen\u00ed. M\u011bjte v\u0161ak na pam\u011bti, \u017ee nepovolen\u00ed rychl\u00e9ho uploadu (odes\u00edl\u00e1n\u00ed)  m\u016f\u017ee v\u00e9st k pomal\u00fdm download\u016fm (stahov\u00e1n\u00edm). Jeliko\u017e se uploady po\u010d\u00edtaj\u00ed pro ka\u017ed\u00fd torrent ZVL\u00c1\u0160\u0164, vede snaha st\u00e1hnout p\u0159\u00edli\u0161 mnoho torrent\u016f najednou tak\u00e9 k pomalej\u0161\u00edmu stahov\u00e1n\u00e [...]
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletetorrent=Smazat &Torrent Soubor
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletedata=Smazat &Data 
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=Smazat &Oba
+deletedata.title=Smazat Obsah
+# used for more than just "delete data"
+deletedata.noprompt=U\u017e se nikdy neptat
+MainWindow.menu.file.configure=&Pr\u016fvodce Nastaven\u00edm...
+configureWizard.title=Pr\u016fvodce Nastaven\u00edm
+configureWizard.welcome.title=V\u00edtejte v Pr\u016fvodci Nastaven\u00edm Vuze
+configureWizard.welcome.message=Tento pr\u016fvodce V\u00e1m pom\u016f\u017ee nastavit Vuze pro ka\u017edodenn\u00ed pou\u017e\u00edv\u00e1n\u00ed. Nastaven\u00ed m\u016f\u017eete zm\u011bnit v\u00edce do hloubky pou\u017eit\u00edm menu N\u00e1stroje->Nastaven\u00ed
+configureWizard.transfer.title=Nastaven\u00ed P\u0159ipojen\u00ed a P\u0159enos\u016f 
+configureWizard.transfer.hint=Tip : Pou\u017eit\u00edm men\u0161\u00ed rychlosti, ne\u017e je Va\u0161e rychlost p\u0159ipojen\u00ed, je nejlep\u0161\u00ed nastaven\u00ed.
+configureWizard.transfer.message=Vyberte, pros\u00edm, n\u00ed\u017ee zp\u016fsob p\u0159ipojen\u00ed. M\u011bjte v\u0161ak na pam\u011bti, \u017ee kdy\u017e nedovol\u00edte dostate\u010dn\u011b rychl\u00e9 odes\u00edl\u00e1n\u00ed, budete m\u00edt pomal\u00e9 stahov\u00e1n\u00ed. Jeliko\u017e se rychlost odes\u00edl\u00e1n\u00ed po\u010d\u00edt\u00e1 pro ka\u017ed\u00fd torrent, kter\u00fd stahujete, ZVL\u00c1\u0160\u0164, vede snaha st\u00e1hnout p\u0159\u00edli\u0161 mnoho torrent\u01 [...]
 configureWizard.transfer.connection=P\u0159ipojen\u00ed 
 configureWizard.transfer.connection.0=Vlastn\u00ed 
 configureWizard.transfer.connection.1=Modem 
@@ -387,91 +400,91 @@ configureWizard.transfer.connection.4=ADSL/Kabel xxx/384 kbps
 configureWizard.transfer.connection.5=ADSL/Kabel xxx/512 kbps 
 configureWizard.transfer.connection.6=ADSL/Kabel xxx/768 kbps 
 configureWizard.transfer.connection.7=ADSL/Kabel xxx/1024 kbps 
-configureWizard.transfer.maxUpSpeed=Maxim\u00e1ln\u00ed rychlost uploadu (KB/s) 
-configureWizard.transfer.maxActiveTorrents=Maximum aktivn\u00edch torrent\u016f 
-configureWizard.transfer.maxDownloads=Maximum stahovan\u00fdch torrent\u016f 
-configureWizard.transfer.maxUploadsPerTorrent=Maximum upload\u016f na torrent 
-configureWizard.nat.title=NAT / Server Port 
-configureWizard.nat.message=Abyste ziskali co nejv\u00edce z BitTorrent s\u00edt\u011b, m\u011bli byste b\u00fdti p\u0159istupn\u00ed z internetu. V\u00fdchoz\u00ed BitTorrent port je 6881. Tento n\u00e1stroj v\u00e1m umo\u017en\u00ed tento port zm\u011bnit a n\u00e1sledn\u011b ho otestovat. 
+configureWizard.transfer.maxUpSpeed=Maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed (KB/s) 
+configureWizard.transfer.maxActiveTorrents=Maximum Aktivn\u00edch
+configureWizard.transfer.maxDownloads=Maximum Stahov\u00e1n\u00ed
+configureWizard.transfer.maxUploadsPerTorrent=Maximum Odes\u00edl\u00e1n\u00ed na Torrent
 configureWizard.nat.test=Zkusit 
-configureWizard.nat.testing=Testuji port 
-configureWizard.nat.ok=OK!
+configureWizard.nat.testing=Zkou\u0161\u00edm port 
 configureWizard.nat.ko=Chyba NAT
-configureWizard.nat.unable=Nelze otestovat: Zad\u00e1n neplatn\u00fd port nebo selhalo testov\u00e1n\u00ed.\n Port m\u016f\u017ee b\u00fdt ji\u017e pou\u017e\u00edv\u00e1n jin\u00fdm programem.
+configureWizard.nat.unable=Nelze vyzkou\u0161et: Zad\u00e1n neplatn\u00fd port nebo zkou\u0161ec\u00ed slu\u017eba selhala.\n Port m\u016f\u017ee b\u00fdt ji\u017e pou\u017e\u00edv\u00e1n jin\u00fdm programem.
 configureWizard.file.title=Torrenty / Soubory 
-configureWizard.file.message1=Vuze si bude ukl\u00e1dat v\u0161echny otev\u0159en\u00e9 torrent soubory do zde ur\u010den\u00e9 slo\u017eky:
+configureWizard.file.message1=Vuze bude otev\u0159en\u00e9 torrenty ukl\u00e1dat do ur\u010den\u00e9ho adres\u00e1\u0159e, kter\u00fd m\u016f\u017eete nastavit zde:
 configureWizard.file.path=Cesta: 
 configureWizard.file.browse=Proch\u00e1zet... 
-configureWizard.file.message2=Vuze je schopn\u00fd rychle obnovit torrent a skoro okam\u017eit\u011b pokra\u010dovat v distribuci/stahov\u00e1n\u00ed. Aby tak mohl fungovat, mus\u00ed si k torrent\u016fm ukl\u00e1dat dodate\u010dn\u00e1 data.
-configureWizard.file.fastResume=Povolit rychl\u00e9 obnoven\u00ed
-configureWizard.file.invalidPath=Neplatn\u00e1 slo\u017eka! 
-configureWizard.finish.title=Hotovo 
-configureWizard.finish.message=Vuze je nastaven, p\u0159ejeme p\u0159ijemnou z\u00e1bavu! 
+configureWizard.file.message2=Vuze je schopn\u00fd pokra\u010dovat na Va\u0161ich souborech okam\u017eit\u011b a skoro okam\u017eit\u011b, p\u0159id\u00e1n\u00edm n\u011bjak\u00fdch dat do Va\u0161ich torrent\u016f pro pokra\u010dov\u00e1n\u00ed. Pou\u017eit\u00edm t\u00e9to funkce, m\u016f\u0159ete tak\u00e9 pokra\u010dovat v \u010d\u00e1ste\u010dn\u011b st\u00e1hnut\u00fdch d\u00edlech
+configureWizard.file.fastResume=Povolit rychl\u00e9 Pokra\u010dov\u00e1n\u00ed
+configureWizard.file.invalidPath=Neplatn\u00fd adres\u00e1\u0159!
+configureWizard.finish.title=Dokon\u010deno
+configureWizard.finish.message=Vuze je nastaven, p\u0159ejeme p\u0159\u00edjemnou z\u00e1bavu! 
 wizard.close.confirmation=Potvrzen\u00ed 
-wizard.close.message=Opravdu chcete otev\u0159\u00edt tohoto pr\u016fvodce p\u0159i dal\u0161\u00edm spu\u0161t\u011bn\u00ed?
-exportTorrentWizard.title=Exportovat torrent do XML
-exportTorrentWizard.torrentfile.title=V\u00fdb\u011br torrentu 
+wizard.close.message=Chcete nahr\u00e1t tohoto pr\u016fvodce p\u0159i p\u0159\u00ed\u0161t\u00edm spu\u0161t\u011bn\u00ed Vuze?
+exportTorrentWizard.title=Exportovat XML torrent
+exportTorrentWizard.torrentfile.title=V\u00fdb\u011br Vstupn\u00edho Torrentu 
 exportTorrentWizard.torrentfile.message=Vyberte torrent soubor k exportu
 exportTorrentWizard.torrentfile.path=Cesta: 
 exportTorrentWizard.torrentfile.browse=Proch\u00e1zet... 
 exportTorrentWizard.torrentfile.invalidPath=Neplatn\u00fd torrent soubor
-exportTorrentWizard.exportfile.title=Exportovan\u00fd soubor
-exportTorrentWizard.exportfile.message=Vypl\u0148te n\u00e1zev exportovan\u00e9ho XML souboru
-exportTorrentWizard.exportfile.path=Cesta: 
-exportTorrentWizard.exportfile.browse=Proch\u00e1zet... 
+exportTorrentWizard.exportfile.title=V\u00fdb\u011br Exportovan\u00e9ho Souboru
+exportTorrentWizard.exportfile.message=Zadejte n\u00e1zev souboru XML do kter\u00e9ho exportovat
+exportTorrentWizard.exportfile.path=Cesta
+exportTorrentWizard.exportfile.browse=Proch\u00e1zet
 exportTorrentWizard.exportfile.invalidPath=Neplatn\u00fd exportovan\u00fd soubor 
 exportTorrentWizard.finish.title=Hotovo 
 exportTorrentWizard.finish.message=Export byl \u00fasp\u011b\u0161n\u011b dokon\u010den 
-exportTorrentWizard.process.inputfilebad.title=Soubor torrentu je chybn\u00fd
-exportTorrentWizard.process.inputfilebad.message=Chyba p\u0159i \u010dten\u00ed vstupn\u00edho souboru:
+exportTorrentWizard.process.inputfilebad.title=Torrent Soubor je Neplatn\u00fd
+exportTorrentWizard.process.inputfilebad.message=Chyba p\u0159i p\u0159\u00edstupu ke vstupn\u00edmu souboru:
 exportTorrentWizard.process.outputfileexists.title=Soubor existuje 
 exportTorrentWizard.process.outputfileexists.message=V\u00fdstupn\u00ed soubor ji\u017e existuje - p\u0159epsat? 
-exportTorrentWizard.process.torrentfail.title=Chyba p\u0159i \u010dten\u00ed torrentu 
+exportTorrentWizard.process.torrentfail.title=\u010cten\u00ed Torrentu Selhalo
 exportTorrentWizard.process.exportfail.title=Chyba p\u0159i exportu torrentu 
 exportTorrentWizard.process.unknownfail.title=Neo\u010dek\u00e1van\u00e1 chyba 
 importTorrentWizard.title=Importovat Torrent z XML
-importTorrentWizard.torrentfile.title=V\u00fdb\u011br Torrentu
-importTorrentWizard.torrentfile.message=Vyberte torrent soubor k importu
+importTorrentWizard.torrentfile.title=V\u00fdb\u011br Vstupn\u00edho Torrentu
+importTorrentWizard.torrentfile.message=Vyberte torrent soubor, do kter\u00e9ho importovat
 importTorrentWizard.torrentfile.path=Cesta:
 importTorrentWizard.torrentfile.browse=Proch\u00e1zet...
-importTorrentWizard.torrentfile.invalidPath=Neplatn\u00fd .torrent soubor
-importTorrentWizard.importfile.title=Importovan\u00fd soubor 
-importTorrentWizard.importfile.message=Vypl\u0148te n\u00e1zev importovan\u00e9ho XML souboru
+importTorrentWizard.torrentfile.invalidPath=Neplatn\u00fd torrent soubor
+importTorrentWizard.importfile.title=V\u00fdb\u011br Importovan\u00e9ho Souboru
+importTorrentWizard.importfile.message=Vypl\u0148te n\u00e1zev XML souboru pro import
 importTorrentWizard.importfile.path=Cesta: 
 importTorrentWizard.importfile.browse=Proch\u00e1zet...
-importTorrentWizard.importfile.invalidPath=Naplatn\u00fd importovan\u00fd soubor 
+importTorrentWizard.importfile.invalidPath=Neplatn\u00fd importovan\u00fd soubor 
 importTorrentWizard.finish.title=Hotovo 
 importTorrentWizard.finish.message=Import byl \u00fasp\u011b\u0161n\u011b dokon\u010den
-importTorrentWizard.process.inputfilebad.title=Neplatn\u00fd soubor importu
-importTorrentWizard.process.inputfilebad.message=Chyba p\u0159i \u010dten\u00ed vstupn\u00edho souboru: 
+importTorrentWizard.process.inputfilebad.title=Neplatn\u00fd Importovan\u00fd Soubor
+importTorrentWizard.process.inputfilebad.message=Stala se chyba p\u0159i p\u0159\u00edstupu k vstupn\u00edmu souboru:
 importTorrentWizard.process.outputfileexists.title=Soubor existuje 
 importTorrentWizard.process.outputfileexists.message=V\u00fdstupn\u00ed soubor ji\u017e existuje - p\u0159epsat?
 importTorrentWizard.process.torrentfail.title=Chyba p\u0159i z\u00e1pisu torrentu 
-importTorrentWizard.process.importfail.title=Chyba p\u0159i importu torrentu 
+importTorrentWizard.process.importfail.title=Import Torrentu Selhal
 importTorrentWizard.process.unknownfail.title=Neo\u010dek\u00e1van\u00e1 chyba
-ConfigView.label.bindip=Sv\u00e1zat s lok\u00e1ln\u00ed IP adresou or interface
-ConfigView.label.zeronewfiles=P\u0159i vytv\u00e1\u0159en\u00ed alokovat a vynulovat soubory
+ConfigView.label.bindip=Sv\u00e1zat s lok\u00e1ln\u00ed IP adresou nebo rozhran\u00edm
+ConfigView.label.xfs.allocation=P\u0159id\u011blovat nov\u00e9 soubory pou\u017eit\u00edm specifick\u00e9 metody pro souborov\u00fd syst\u00e9m XFS
+ConfigView.label.xfs.allocation.tooltip=Ujist\u011bte se pros\u00edm, \u017ee /usr/sbin/xfs_io je spr\u00e1vn\u011b nainstalov\u00e1n ve Va\u0161em syst\u00e9mu. Na v\u011bt\u0161ine Linuxov\u00fdch distribuc\u00ed je zahrnut v bal\u00ed\u010dku "xfsprogs".
+xfs.allocation.xfs_io.not.found=P\u0159id\u011blov\u00e1n\u00ed souboru XFS selhalo proto\u017ee /usr/sbin/xfs_io nem\u016f\u017ee b\u00fdt spu\u0161t\u011bn. Ujist\u011bte se, \u017ee je na Va\u0161em syst\u00e9mu spr\u00e1vn\u011b nainstalov\u00e1n. P\u016fvodn\u00ed chyba byla : "%1".
+ConfigView.label.zeronewfiles=P\u0159id\u011blovat a vynulovat nov\u00e9 soubory p\u0159i vytv\u00e1\u0159en\u00ed
 ConfigView.label.zeronewfiles.tooltip=Sni\u017euje fragmentaci
-ConfigView.section.stats=Statistika 
+ConfigView.section.stats=Statistiky
 ConfigView.section.stats.enable=Povolit 
-ConfigView.section.stats.defaultsavepath=Slo\u017eka pro statistiky 
-ConfigView.section.stats.choosedefaultsavepath=Vyberte slo\u017eku, kam se budou ukl\u00e1dat statistick\u00e9 informace
+ConfigView.section.stats.defaultsavepath=\u00dalo\u017en\u00fd adres\u00e1\u0159 pro statistiky
+ConfigView.section.stats.choosedefaultsavepath=Vyberte , pros\u00edm, adres\u00e1\u0159 pro ulo\u017een\u00ed statistik
 ConfigView.section.stats.savefreq=Frekvence ukl\u00e1d\u00e1n\u00ed
 ConfigView.section.stats.minutes=min 
 ConfigView.section.stats.hours=hod 
+ConfigView.section.stats.seconds=sek
 ConfigView.section.stats.savefile=Jm\u00e9no souboru se statistikami
-MyTorrentsView.menu.export=&Exportovat do XML...
+ConfigView.section.stats.graph_update_dividers=Zobrazit svislou \u010d\u00e1ru ka\u017ed\u00fdch 60 aktualizac\u00ed
 MyTorrentsView.menu.host=&Hostovat... 
-ManagerItem.finishing=Dokon\u010dov\u00e1n\u00ed 
-ConfigView.dialog.choosedefaulttorrentpath=Vyberte v\u00fdchoz\u00ed slo\u017eku pro torrent soubory
-ConfigView.dialog.choosemovepath=Vyberte slo\u017eku, kam chcete slo\u017eku p\u0159esunout
-ConfigView.label.movecompleted=P\u0159esouvat dokon\u010den\u00e9 soubory do jin\u00e9 slo\u017eky
-ConfigView.label.moveremoved=P\u0159esunout dokon\u010den\u00e9 soubory (p\u0159i odstran\u011bn\u00ed)
+ManagerItem.finishing=Dokon\u010duji
+ConfigView.dialog.choosedefaulttorrentpath=Vyberte pros\u00edm v\u00fdchoz\u00ed adres\u00e1\u0159 pro torrenty
+ConfigView.dialog.choosemovepath=Vyberte, pros\u00edm, adres\u00e1\u0159, kam chcete p\u0159esunout
+ConfigView.label.movecompleted=P\u0159esunout dokon\u010den\u00e9 soubory (po st\u00e1hnut\u00ed)
+ConfigView.label.moveremoved=P\u0159esunout dokon\u010den\u00e9 soubory (kdy\u017e jsou odstra\u0148ov\u00e1na)
 ConfigView.label.savetorrents=Ukl\u00e1dat .torrent soubory 
-MainWindow.menu.view.mytracker=M\u016fj &Servr
-MyTrackerView.title.full=M\u016fj server
+MainWindow.menu.view.mytracker=M\u016fj &Tracker
+MyTrackerView.title.full=M\u016fj Tracker
 MyTrackerView.name=N\u00e1zev 
-MyTrackerView.tracker=Server
 MyTrackerView.status=Stav 
 MyTrackerView.status.started=B\u011b\u017e\u00ed
 MyTrackerView.status.stopped=Zastaveno
@@ -482,138 +495,139 @@ MyTrackerView.uploaded=Odesl\u00e1no
 MyTrackerView.downloaded=Sta\u017eeno
 MyTrackerView.left=Zb\u00fdv\u00e1
 ConfigView.section.style=Rozhran\u00ed
-ConfigView.label.set_ui_transfer_speeds=P\u0159epsat vybrateln\u00e9 p\u0159enosov\u00e9 rychlosti
-ConfigView.label.set_ui_transfer_speeds.description=M\u016f\u017eete si vybrat manu\u00e1ln\u011b definovat v\u00fdchoz\u00ed rychlost stahov\u00e1n\u00ed a odes\u00edl\u00e1n\u00ed dostupn\u00e9 na stavov\u00e9m \u0159\u00e1dku na syst\u00e9mov\u00e9 li\u0161t\u011b\n Hodnoty mus\u00ed b\u00fdt odd\u011bleny \u010d\u00e1rkou (",")
-ConfigView.section.style.useCustomTabs=Pou\u017e\u00edvat zav\u00edrateln\u00e9 z\u00e1lo\u017eky (vy\u017eaduje restart programu)
-MainWindow.menu.view.plugins=&Dopl\u0148ky 
-fileDownloadWindow.saveTorrentIn=Ulo\u017eit Torrent do souboru 
-fileDownloadWindow.title=Vuze - Stahov\u00e1n\u00ed torrentu
-fileDownloadWindow.downloading=Stahovan\u00ed od : 
+ConfigView.label.set_ui_transfer_speeds=P\u0159epsat vybrateln\u00e9 rychlosti p\u0159enosu
+ConfigView.label.set_ui_transfer_speeds.description=M\u016f\u017eete si vybrat, \u017ee ru\u010dn\u011b ur\u010d\u00edte v\u00fdchoz\u00ed dostupn\u00e9 rychlosti stahov\u00e1n\u00ed a odes\u00edl\u00e1n\u00ed, dostupn\u00e9 na li\u0161t\u011b stavu v syst\u00e9mov\u00e9 li\u0161t\u011b.\nHodnoty mus\u00ed b\u00fdt odd\u011bleny \u010d\u00e1rkou.
+ConfigView.label.set_ui_transfer_speeds.description.download=Nastavit rychlosti stahov\u00e1n\u00ed (v KB/s)
+ConfigView.label.set_ui_transfer_speeds.description.upload=Nastavit rychlosti odesl\u00e1n\u00ed (v KB/s)
+ConfigView.section.style.useCustomTabs=Pou\u017e\u00edvat uzav\u00edrateln\u00e9 z\u00e1lo\u017eky (vy\u017eaduje restart)
+MainWindow.menu.view.plugins=&Z\u00e1suvn\u00e9 Moduly
+fileDownloadWindow.saveTorrentIn=Ulo\u017eit Torrent Soubor Do
+fileDownloadWindow.title=Vuze - Torrent Klient
+fileDownloadWindow.downloading=Stahovan\u00ed Od :
 fileDownloadWindow.status=Stav : 
-fileDownloadWindow.state_initializing=Inicializace 
+fileDownloadWindow.state_initializing=Spou\u0161t\u011bn\u00ed
 fileDownloadWindow.state_downloading=Stahov\u00e1n\u00ed 
 fileDownloadWindow.state_error=Chyba : 
-MainWindow.menu.file.open.url=&URL 
-openUrl.title=Vuze - Otev\u0159\u00edt URL 
+MainWindow.menu.file.open.url=&Um\u00edst\u011bn\u00ed...
+openUrl.title=Otev\u0159\u00edt Um\u00edst\u011bn\u00ed
 openUrl.url=URL : 
-MyTorrentsView.menu.host.error.title=Hostv\u00e1n\u00ed torrentu se nepoda\u0159ilo
+MyTorrentsView.menu.host.error.title=Hostov\u00e1n\u00ed Torrentu Selhalo
 MyTorrentsView.menu.host.error.message=P\u0159i hostov\u00e1n\u00ed torrentu nastala n\u00e1sleduj\u00edc\u00ed chyba
-ConfigView.section.tracker=Server 
-ConfigView.section.tracker.pollinterval=Interval mezi dotazy klienta trackeru (sec)
-ConfigView.section.tracker.publishenable=Publikovat detaily o Torrentech do "<tracker_url>"
-ConfigView.section.tracker.ip=Ve\u0159ejn\u00e1 IP adresa trackeru
-ConfigView.section.style.enableXPStyle=Povolit XP styl (vy\u017eaduje restart programu)
-IPChecker.external.service.dyndns.description=Dynamick\u00fd DNS S\u00ed\u0165 srvis, LLC
-ConfigView.section.tracker.checkip=Zjistit ve\u0159ejnou IP adresu...
-ipCheckerWizard.title=Pr\u016fvodce kontrolou IP adresy
+ConfigView.section.tracker.pollinterval=Interval z\u00edsk\u00e1n\u00ed klient\u016f trackeru (sek)
+ConfigView.section.tracker.publishenable=Publikovat podrobnosti torrentu do "<tracker_url>"
+ConfigView.section.tracker.ip=Extern\u00ed IP adresa Trackeru
+ConfigView.section.style.enableXPStyle=Povolit XP styl (vy\u017eaduje restart)
+ConfigView.section.tracker.checkip=Automaticky zjistit extern\u00ed IP adresu...
+ipCheckerWizard.title=Pr\u016fvodce Kontrolou IP
 ipCheckerWizard.service=Slu\u017eba
-ipCheckerWizard.chooseService=Vyberte slu\u017ebu, kter\u00e1 bude pou\u017eita ke kontrole IP adresy
-ipCheckerWizard.explanations=Tento pr\u016fvodce V\u00e1m pom\u016f\u017ee zjistit Va\u0161i ve\u0159ejnou IP adresu. Pokud m\u00e1te dynamickou IP adresu, doporu\u010dujeme V\u00e1m zalo\u017eit si \u00fa\u010det u n\u011bkter\u00e9 spole\u010dnosti poskytuj\u00edc\u00ed dynamick\u00e9 DNS z\u00e1znamy. Na pomoc je zde seznam n\u011bkolika spole\u010dnost\u00ed s odkazy, kde si takovou slu\u017ebu m\u016f\u017eete z\u0159\u00eddit (pokud tuto slu\u017ebu nab\u00edz\u00ed). Pot\u00e9 vyp [...]
+ipCheckerWizard.chooseService=Pros\u00edm Vyberte Slu\u017ebu Zji\u0161t\u011bn\u00ed IP ze seznamu slu\u017eeb
+ipCheckerWizard.explanations=Tohoto pr\u016fvodce m\u016f\u017eete pou\u017e\u00edt pro zji\u0161t\u011bn\u00ed jak\u00e1 je Va\u0161e extern\u00ed IP adresa. Pokud Va\u0161e IP adresa je dynamick\u00e1, doporu\u010dujeme si otev\u0159\u00edt \u00fa\u010det u Dynamick\u00e9 Slu\u017eby DNS. N\u011bkter\u00e9 takov\u00e9 slu\u017eby jsou vypsan\u00e9 n\u00ed\u017ee, pou\u017eijte poskytnut\u00fd odkaz pro vytvo\u0159en\u00ed \u00fa\u010dtu (kde je to mo\u017en\u00e9). Pak vypl\u0148te pol [...]
 ipCheckerWizard.service.description=Popis :
 ipCheckerWizard.service.url=Odkaz :
-ipCheckerWizard.progresstitle=Kontrola IP adresy
+ipCheckerWizard.progresstitle=Kontroluji IP
 ipCheckerWizard.checkComplete=Zji\u0161t\u011bn\u00e1 IP adresa :
-ipCheckerWizard.checkFailed=Chyba :
-wizard.tracker.local=Pou\u017e\u00edvat vestav\u011bn\u00fd Tracker
-wizard.tracker.external=Pou\u017e\u00edvat ve\u0159ejn\u00fd Tracker
-wizard.tracker.howToLocal=\tK povolen\u00ed pou\u017eijte dialog 'Nastaven\u00ed>Tracker'
+ipCheckerWizard.checkFailed=Selhalo, d\u016fvod :
+wizard.tracker.local=Pou\u017e\u00edvat Zabudovan\u00fd Tracker Vuze
+wizard.tracker.external=Pou\u017e\u00edvat extern\u00ed Tracker
+wizard.tracker.howToLocal=\tPro povolen\u00ed jd\u011bte do 'N\u00e1stroje->Nastaven\u00ed->Tracker'
 wizard.announceUrl=Oznamovac\u00ed URL :
-IPChecker.external.service.discoveryvip.name=Objeven\u00ed VIP
-IPChecker.external.service.discoveryvip.description=Objeven\u00ed VIP - Pouze zji\u0161t\u011bn\u00ed IP adresy
+IPChecker.external.service.discoveryvip.description=Discoveryvip - Pouze zji\u0161t\u011bn\u00ed IP adresy
 IPChecker.external.httpinvalidresponse=Neplatn\u00e1 odezva HTTP
-IPChecker.external.loadingwebpage=Na\u010d\u00edt\u00e1n\u00ed str\u00e1nky
-IPChecker.external.analysingresponse=Anal\u00fdza odpov\u011bdi
+IPChecker.external.loadingwebpage=Na\u010d\u00edt\u00e1m internetovou str\u00e1nku
+IPChecker.external.analysingresponse=Analyzuji odpov\u011b\u010f
 IPChecker.external.addressextracted=Nalezen\u00e1 IP adresa
 IPChecker.external.httploadfail=Nepoda\u0159ilo se na\u010d\u00edst str\u00e1nku
 IPChecker.external.timeout=Vypr\u0161el \u010dasov\u00fd limit
 IPChecker.external.ipnotfound=IP adresa nenalezena
 ConfigView.section.tracker.pollintervalincby=Zvy\u0161ovat o
 ConfigView.section.tracker.pollintervalincper=Ka\u017ed\u00fdch 'n' klient\u016f
-splash.loadingImages=Na\u010d\u00edt\u00e1n\u00ed obr\u00e1zk\u016f
-splash.initializeGui=Inicializace hlavn\u00edho okna
-splash.openViews=Otev\u00edr\u00e1n\u00ed z\u00e1lo\u017eek
-splash.plugin=Na\u010d\u00edt\u00e1n\u00ed dopl\u0148ku : 
-configureWizard.nat.tooManyPorts=P\u0159\u00edli\u0161 mnoho port\u016f na testov\u00e1n\u00ed (maxim\u00e1ln\u011b 9) 
-ConfigView.section.color=Barevn\u00e9 sch\u00e9ma
+splash.loadingImages=Na\u010d\u00edt\u00e1m obr\u00e1zky
+splash.initializeGui=Zav\u00e1d\u00edm Hlavn\u00ed Okno
+splash.openViews=Otev\u00edr\u00e1n\u00ed Zobrazen\u00ed
+splash.plugin=Na\u010d\u00edt\u00e1m Z\u00e1suvn\u00fd Modul:
+configureWizard.nat.tooManyPorts=P\u0159\u00edli\u0161 mnoho port\u016f ke zkou\u0161en\u00ed (maxim\u00e1ln\u011b 9) 
+ConfigView.section.color=Barevn\u00e9 Sch\u00e9ma
 MyTorrentsView.menu.publish=Publikovat... 
 MyTrackerView.status.published=Publikov\u00e1n
-MyTrackerView.completed=Dokon\u010den\u00ed 
-MainWindow.menu.file.open.torrentnodefault=.torrent soubor (Nestahovat do v\u00fdchoz\u00ed slo\u017eky) 
+MyTrackerView.completed=Dokon\u010deno
+MainWindow.menu.file.open.torrentnodefault=Soubor Torrent...(\u017d\u00e1dn\u00e9 V\u00fdchoz\u00ed Ukl\u00e1d\u00e1n\u00ed)
 wizard.comment=Koment\u00e1\u0159
-ConfigView.label.movetorrent=P\u0159esunout i .torrent
-ConfigView.label.movepartialdownloads=Move when some files are flagged "Do Not Download" 
-ConfigView.section.file.decoder.label=V\u00fdchoz\u00ed k\u00f3dov\u00e1n\u00ed .torrent souboru, pokud je pot\u0159eba vybrat
+ConfigView.label.movetorrent=P\u0159esunout .torrent
+ConfigView.label.movepartialdownloads=P\u0159esunout, kdy\u017e jsou n\u011bkter\u00e9 soubory ozna\u010deny jako "Nestahovat"
+ConfigView.label.subdir_is_in_default=P\u0159i zva\u017eov\u00e1n\u00ed, jestli stahov\u00e1n\u00ed existuj\u00ed ve v\u00fdchoz\u00edm adres\u00e1\u0159i, tak\u00e9 zv\u00e1\u017eit podadres\u00e1\u0159e
+ConfigView.section.file.decoder.label=V\u00fdchoz\u00ed k\u00f3dov\u00e1n\u00ed torrentu, pokud je pot\u0159eba vybrat
 ConfigView.section.file.decoder.nodecoder=\u017d\u00e1dn\u00e9 
 IPChecker.external.service.no-ip.name=No-IP 
 IPChecker.external.service.no-ip.url=http://www.no-ip.com/ 
-IPChecker.external.service.no-ip.description=Poskytovatel dynamick\u00e9ho a statick\u00e9ho DNS\n(nepodporuje voln\u011b slu\u017ebu zji\u0161t\u011bn\u00ed adresy) 
-ConfigView.section.tracker.publicenable=Povolit ve\u0159ejn\u00e9 torrenty
-ConfigView.label.playdownloadspeech=Ozn\u00e1mit, kdy je download (stahov\u00e1n\u00ed) ukon\u010den
-ConfigView.label.playdownloadspeech.info=Hovorov\u00e9 slu\u017eby pracuji jen v anglick\u00e9m jazyce
+IPChecker.external.service.no-ip.description=Poskytovatel dynamick\u00e9 a statick\u00e9 slu\u017eby DNS\n(\u017e\u00e1dn\u00e1 voln\u011b dostupn\u00e1 slu\u017eba 'zji\u0161t\u011bn\u00ed adresy')
+ConfigView.section.tracker.publicenable=Povolit extern\u00ed torrenty
+ConfigView.label.playdownloadspeech=Promluvit, kdy\u017e je stahov\u00e1n\u00ed dokon\u010deno
+ConfigView.label.playdownloadspeech.info=Hlasov\u00e9 Slu\u017eby sou\u010dasn\u011b funguj\u00ed nejl\u00e9pe v Angli\u010dtin\u011b
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=Zobrazuje po\u010det dostupn\u00fdch kopi\u00ed ka\u017ed\u00e9ho d\u00edlu.\nPokud je \u010d\u00edslo vpravo men\u0161\u00ed ne\u017e 1, nejsou dostupn\u00e9 v\u0161echny d\u00edly souboru (a m\u016f\u017eete m\u00edt probl\u00e9m dokon\u010dit stahov\u00e1n\u00ed)
+GeneralView.label.status.pieces_available.tooltip=Zobrazuje po\u010det dostupn\u00fdch kopi\u00ed ka\u017ed\u00e9ho d\u00edlu.\nPokud je \u010d\u00edslo vpravo men\u0161\u00ed ne\u017e 1, nevid\u00edte jednu celou kopii souboru (a m\u016f\u017eete m\u00edt probl\u00e9m stahov\u00e1n\u00ed dokon\u010dit)
 GeneralView.label.trackerurl.tooltip=Kliknut\u00edm zkop\u00edrujete Oznamovac\u00ed URL do schr\u00e1nky
-GeneralView.label.trackerurlopen.tooltip=Kliknut\u00edm otev\u0159ete hlavn\u00ed str\u00e1nku serveru
+GeneralView.label.trackerurlopen.tooltip=Kliknut\u00edm otev\u0159ete hlavn\u00ed str\u00e1nku trackeru
 #
 # 2.0.4.4
 #
-ConfigView.section.style.guiUpdate=Aktualizovat UI (u\u017eivatelsk\u00e9 rozhran\u00ed) ka\u017ed\u00fdch
-ConfigView.section.style.graphicsUpdate=Aktualizovat grafy ka\u017ed\u00fdch N aktualizac\u00ed UI
-ConfigView.section.style.reOrderDelay=Se\u0159azovat tabulky ka\u017ed\u00fdch N aktualizac\u00ed UI [0: zak\u00e1zano]
+ConfigView.section.style.guiUpdate=Aktualizovat grafick\u00e9 rozhran\u00ed ka\u017ed\u00fdch
+ConfigView.section.style.inactiveUpdate=Aktualizovat hlavn\u00ed okno ka\u017ed\u00fdch N aktualizac\u00ed rozhran\u00ed, kdy\u017e okno nen\u00ed aktivn\u00ed
+ConfigView.section.style.graphicsUpdate=Aktualizovat Grafick\u00e9 Li\u0161ty ka\u017ed\u00fdch N aktualizac\u00ed rozhran\u00ed
+ConfigView.section.style.reOrderDelay=Znovu se\u0159adit tabulky ka\u017ed\u00fdch N aktualizac\u00ed rozhran\u00ed [0: nikdy]
 ConfigView.section.style.reOrderDelay.never=Nikdy
-ConfigView.section.logging=Protokoly
-ConfigView.section.logging.enable=Zapisovat protokoly do souboru
-ConfigView.section.logging.logdir=Slo\u017eka s protokoly
-ConfigView.section.logging.choosedefaultsavepath=Vyberte slo\u017eku pro ulo\u017een\u00ed
+ConfigView.section.logging=Z\u00e1znam
+ConfigView.section.logging.enable=Povolit z\u00e1znam do souboru
+ConfigView.section.logging.logdir=Adres\u00e1\u0159 se soubory z\u00e1znamu
+ConfigView.section.logging.choosedefaultsavepath=Vyberte pros\u00edm adres\u00e1\u0159 pro ulo\u017een\u00ed
 GeneralView.label.updatein.querying=dotazov\u00e1n\u00ed...
 configureWizard.nat.sharePort=Pou\u017e\u00edvat jeden sd\u00edlen\u00fd port pro v\u0161echny torrenty
-ConfigView.section.logging.maxsize=Max. velikost souboru protokolu
-ConfigView.section.tracker.passwordenableweb=Povolit u\u017e\u00edv\u00e1n\u00ed hesel na trackeru
-ConfigView.section.tracker.passwordenabletorrent=Povolit u\u017e\u00edv\u00e1n\u00ed hesel na torrentech
+ConfigView.section.logging.maxsize=Maxim\u00e1ln\u00ed velikost souboru z\u00e1znamu
+ConfigView.section.tracker.passwordenableweb=Povolit heslo na web trackeru
+ConfigView.section.tracker.passwordenabletorrent=Povolit heslo na torrentech
 ConfigView.section.tracker.username=U\u017eivatelsk\u00e9 jm\u00e9no
 ConfigView.section.tracker.password=Heslo
-columnChooser.title=Zobrazovan\u00e9 sloupce
-columnChooser.move=Po\u0159ad\u00ed sloupc\u016f zm\u011bn\u00edte p\u0159eta\u017een\u00edm polo\u017eek
+columnChooser.title=Zvolte sloupce k zobrazen\u00ed
+columnChooser.move=T\u00e1hnut\u00edm \u0159\u00e1dk\u016f je p\u0159eskup\u00edte
 columnChooser.apply=Pou\u017e\u00edt
-columnChooser.columnname=N\u00e1zev sloupce 
+columnChooser.columnname=N\u00e1zev Sloupce 
 columnChooser.columndescription=Popis 
 TableColumn.header.shareRatio=Pom\u011br sd\u00edlen\u00ed
-MyTorrentsView.menu.editTableColumns=Nastaven\u00ed sloupc\u016f
-wizard.operationfailed=Operace se nezda\u0159ila
-authenticator.title=Po\u017eadov\u00e1na autentizace
+MyTorrentsView.menu.editTableColumns=&Nastaven\u00ed Sloupc\u016f
+wizard.operationfailed=Operace selhala
+authenticator.title=Vy\u017eadov\u00e1no ov\u011b\u0159en\u00ed
 authenticator.realm=Oblast
-authenticator.tracker=Server
 authenticator.user=U\u017eivatelsk\u00e9 jm\u00e9no
 authenticator.password=Heslo
-ConfigView.label.allowSendVersion=P\u0159i kontrole nov\u00e9 verze povolit anonymn\u00ed odes\u00edl\u00e1n\u00ed \u010d\u00edsla verze Azurea a n\u00e1hodn\u00e9ho ID.
-wizard.hint.mode=Tip:\tSoubor nebo slo\u017eku m\u016f\u017eete vybrat i jejich p\u0159eta\u017een\u00edm\n\t(Drag and Drop) na toto okno
-wizard.hint.file=Tip:\tSoubor lze vybrat i jeho p\u0159eta\u017een\u00edm na toto okno
-wizard.hint.directory=Tip:\tSlo\u017eku lze vybrat i jej\u00edm p\u0159eta\u017een\u00edm na toto okno
-MainWindow.menu.help.checkupdate=&Kontrola nov\u00e9 verze
-TableColumn.header.down=P\u0159ijato
+ConfigView.label.allowSendVersion=Povolit Vuze, aby anonymn\u011b odes\u00edlal \u010d\u00edslo verze a n\u00e1hodn\u00e9 id p\u0159i kontrole nov\u00e9 verze.
+ConfigView.label.version.info.link=Nav\u0161tivte toto pro podrobnosti jak\u00e1 data jsou pos\u00edl\u00e1na na server p\u0159i kontrole verze
+wizard.hint.mode=Tip:\tJednotliv\u00fd soubor nebo adres\u00e1\u0159 m\u016f\u017eete T\u00e1hnou a Pustit do tohoto pr\u016fvodce\n\tke zvolen\u00ed souboru nebo adres\u00e1\u0159e
+wizard.hint.file=Tip:\tJednotliv\u00fd soubor si m\u016f\u017eete vybrat pomoc\u00ed T\u00e1hni a Pus\u0165
+wizard.hint.directory=Tip:\tJednotliv\u00fd adres\u00e1\u0159 si m\u016f\u017eete vybrat pomoc\u00ed T\u00e1hni a Pus\u0165
+MainWindow.menu.help.checkupdate=&Zkontrolovat Aktualizace...
+TableColumn.header.down=Sta\u017eeno
 TableColumn.header.up=Odesl\u00e1no
-ConfigView.section.tracker.passwordenabletorrent.info=Vy\u017eaduje podporu BitTorrent klientem (nap\u0159.: Vuze
-ConfigView.section.style.confirmationOnExit=Potvrzovat ukon\u010den\u00ed programu
-MainWindow.dialog.exitconfirmation.title=Ukon\u010dit Azurea?
-MainWindow.dialog.exitconfirmation.text=Opravdu chcete ukon\u010dit Azurea?
-SystemTray.menu.stopalltransfers=Zastavit &v\u0161echny p\u0159enosy
-TrayWindow.menu.stopalldownloads=Zastavit v\u0161echny Torrenty
-ConfigView.section.tracker.sslport.info=Pro v\u00edce informac\u00ed nahl\u00e9dn\u011bte do FAQ
-wizard.tracker.ssl=Pou\u017e\u00edvat SSL
-ConfigView.label.playdownloadfinished=P\u0159ehr\u00e1t zvuk p\u0159i dokon\u010den\u00ed stahov\u00e1n\u00ed
-ConfigView.label.popupdownloadfinished=Varov\u00e1n\u00ed vysko\u010d\u00ed, kdy\u017e je dokon\u010deno stahov\u00e1n\u00ed torrentu
-ConfigView.label.popupfilefinished=Varov\u00e1n\u00ed vysko\u010d\u00ed, kdy\u017e je dokon\u010deno stahov\u00e1n\u00ed souboru
+ConfigView.section.tracker.passwordenabletorrent.info=Vy\u017eaduje vhodn\u00fd BitTorrent klient (nap\u0159.: Vuze)
+ConfigView.section.style.confirmationOnExit=Zobrazit dialogov\u00e9 okno potvrzen\u00ed p\u0159i ukon\u010den\u00ed
+MainWindow.dialog.exitconfirmation.title=Ukon\u010dit Vuze
+MainWindow.dialog.exitconfirmation.text=Opravdu chcete ukon\u010dit Vuze
+SystemTray.menu.stopalltransfers=Zastavit &V\u0161echny P\u0159enosy
+TrayWindow.menu.stopalldownloads=Zastavit &V\u0161echny Torrenty
+ConfigView.section.tracker.sslport.info=Pro v\u00edce informac\u00ed nahl\u00e9dn\u011bte do nej\u010dast\u011bj\u0161\u00edch ot\u00e1zek
+wizard.tracker.ssl=Pou\u017e\u00edt SSL
+ConfigView.label.playdownloadfinished=P\u0159ehr\u00e1t zvuk, kdy\u017e je stahov\u00e1n\u00ed dokon\u010deno
+ConfigView.label.popupdownloadfinished=Hl\u00e1\u0161en\u00ed vysko\u010d\u00ed, kdy\u017e je dokon\u010deno stahov\u00e1n\u00ed
+ConfigView.label.popupfilefinished=Hl\u00e1\u0161en\u00ed vysko\u010d\u00ed, kdy\u017e je soubor dokon\u010den
 TableColumn.header.pieces=D\u00edly
-TableColumn.header.pieces.info=Grafick\u00e1 reprezentace informace o sta\u017een\u00fdch d\u00edlech
-TableColumn.header.completion=Dokon\u010deno
-TableColumn.header.completion.info=Grafick\u00e1 presentace kolik % m\u00e1te sta\u017eeno
-ConfigView.section.style.showdownloadbasket=Zobrazit T\u00e1hni a spus\u0165 c\u00edl pro .torrent soubory
-ConfigView.section.style.alwaysShowTorrentFiles=V\u017edy zobrazovat seznam soubor\u016f v okn\u011b Detaily/Soubory
-wizard.multitracker=K Torrentu p\u0159idat informaci o V\u00edcen\u00e1sobn\u00e9m -Trackeru
-wizard.multitracker.title=V\u00edcen\u00e1sobn\u00fd -Tracker 
-wizard.multitracker.configuration=Nastaven\u00ed V\u00edcen\u00e1sobn\u00e9ho -Trackeru
+TableColumn.header.pieces.info=Grafick\u00e1 li\u0161ta sd\u011bluj\u00edc\u00ed, kter\u00e9 d\u00edly jste st\u00e1hli
+TableColumn.header.completion=Dokon\u010den\u00ed
+TableColumn.header.completion.info=Grafick\u00e9 zastoupen\u00ed %, kter\u00e1 m\u00e1te sta\u017eena
+ConfigView.section.style.showdownloadbasket=Zobrazit Ko\u0161\u00edk Stahov\u00e1n\u00ed (.torrenty T\u00e1hni a Pus\u0165)
+ConfigView.section.style.alwaysShowTorrentFiles=V\u017edy zobrazovat soubory Torrent v Podrobnostech/Souborech
+wizard.multitracker=P\u0159idat Mnoho-Trackerovou informaci do torrentu
+wizard.multitracker.title=Multi-Tracker 
+wizard.multitracker.configuration=Nastaven\u00ed Multi-Trackeru
 wizard.multitracker.new=Nov\u00fd... 
 wizard.multitracker.edit=Upravit... 
 wizard.multitracker.delete=Smazat 
@@ -621,85 +635,85 @@ wizard.multitracker.group=Skupina Tracker\u016f
 wizard.multitracker.edit.title=Editor Multi-Trackeru 
 wizard.multitracker.edit.name=N\u00e1zev 
 wizard.multitracker.edit.save=Ulo\u017eit 
-wizard.multitracker.edit.newgroup=Nov\u00e1 skupina 
+wizard.multitracker.edit.newgroup=Nov\u00e1 Skupina 
 wizard.multitracker.edit.deletegroup=Smazat 
 wizard.multitracker.edit.newtracker=Nov\u00fd Tracker 
 wizard.multitracker.edit.deletetracker=Smazat 
 wizard.multitracker.edit.edit=Upravit 
-wizard.addingmt=P\u0159id\u00e1v\u00e1n\u00ed informac\u00ed o Multi-Trackeru
-wizard.multitracker.noannounce=Oznamovac\u00ed URL nen\u00ed p\u0159\u00edtomna ve va\u0161em seznamu Tracker\u016f
-MyTorrentsView.menu.recheck=P\u0159ekontrolovat
-iconBar.showDownloadBar.tooltip=Zobrazit Informa\u010dn\u00ed prou\u017eek 
-iconBar.start.tooltip=Start 
-iconBar.stop.tooltip=Stop 
-iconBar.remove.tooltip=Odebrat 
-iconBar.openNoDefault.tooltip=Otev\u0159\u00edt .torrent soubor (Nestahovat do v\u00fdchoz\u00ed slo\u017eky) 
+wizard.addingmt=P\u0159id\u00e1v\u00e1m informace o Mnoho-Trackeru
+wizard.multitracker.noannounce=Oznamovac\u00ed URL nen\u00ed p\u0159\u00edtomna ve Va\u0161em seznamu tracker\u016f
+MyTorrentsView.menu.recheck=Vynutit &P\u0159ekontrolov\u00e1n\u00ed
+iconBar.showDownloadBar.tooltip=Zobrazit Li\u0161tu Stahov\u00e1n\u00ed
+iconBar.start.tooltip=Spustit vybran\u00e9 torrenty
+iconBar.stop.tooltip=Zastavit vybran\u00e9 torrenty
+iconBar.remove.tooltip=Odebrat vybran\u00e9 torrenty
+iconBar.openNoDefault.tooltip=Otev\u0159\u00edt .torrent soubor (\u017e\u00e1dn\u00e9 v\u00fdchoz\u00ed ulo\u017een\u00ed) 
 iconBar.openURL.tooltip=Otev\u0159\u00edt URL 
-iconBar.openFolder.tooltip=Otev\u0159\u00edt slo\u017eku 
+iconBar.openFolder.tooltip=Otev\u0159\u00edt Adres\u00e1\u0159
 iconBar.new.tooltip=Vytvo\u0159it Torrent 
-iconBar.up.tooltip=Posunout nahoru 
+iconBar.up.tooltip=P\u0159esunout nahoru 
 iconBar.down.tooltip=Posunout dol\u016f
-iconBar.run.tooltip=Otev\u0159\u00edt 
+iconBar.run.tooltip=Otev\u0159\u00edt pomoc\u00ed v\u00fdchoz\u00ed aplikace
 iconBar.host.tooltip=Hostovat
 iconBar.publish.tooltip=Publikovat
-MyTorrentsView.menu.editTracker=Zm\u011bnit URL Trackeru/\u016f
+iconBar.editcolumns.tooltip=Nastaven\u00ed Sloupc\u016f
+MyTorrentsView.menu.editTracker=&Upravit URL Trackeru/\u016f
 GeneralView.menu.selectTracker=Vybrat
 ConfigView.section.stats.xslfile=Jm\u00e9no XSL souboru
-ConfigView.section.stats.xslfiledetails=Toto bude obsa\u017eeno v souboru se stastistikami pomoc\u00ed tagu <?xml-stylesheet>
-ConfigView.label.savetorrentbackup=Vytv\u00e1\u0159et z\u00e1lohy 
-ConfigView.section.tracker.forceport=Donutit extern\u00ed torrenty pou\u017e\u00edvat v\u00fdchoz\u00ed port
-ConfigView.section.ipfilter.allow=POVOLIT pouze tyto IP adresy (norm\u00e1ln\u011b jsou tyto ZAK\u00c1Z\u00c1NY)
+ConfigView.section.stats.xslfiledetails=Toto bude obsa\u017eeno v hlavi\u010dce souboru se statistikami pomoc\u00ed tagu <?xml-stylesheet>
+ConfigView.label.savetorrentbackup=Ulo\u017eit Z\u00e1lohu 
+ConfigView.section.tracker.forceport=Donutit hostovan\u00e9 extern\u00ed torrenty na v\u00fdchoz\u00ed port
+ConfigView.section.ipfilter.allow=POVOLIT pouze tyto rozsahy (standardn\u011b jsou ZAK\u00c1Z\u00c1NY)
 ConfigView.section.ipfilter.list.inrange=byla v rozsahu 
 ConfigView.section.ipfilter.list.notinrange=nebyla v \u017e\u00e1dn\u00e9m rozsahu
-ConfigView.section.ipfilter.list.title=Seznam zablokovan\u00fdch IP adres
-ConfigView.label.allowsameip=Povolit v\u00edce p\u0159ipojen\u00ed z jedn\u00e9 IP adresy
-ConfigView.label.allowsameip.tooltip=Zapn\u011bte pouze pokud to OPRAVDU pot\u0159ebujete.\nSlou\u017e\u00ed jako ochrana proti podvodn\u00edk\u016fm (kdy\u017e je vypnuto).
+ConfigView.section.ipfilter.list.title=Blokovan\u00e9 IP
+ConfigView.label.allowsameip=Povolit v\u00edce p\u0159ipojen\u00ed ze stejn\u00e9 IP adresy
+ConfigView.label.allowsameip.tooltip=Za\u0161krtn\u011bte pouze pokud to OPRAVDU pot\u0159ebujete.\nSlou\u017e\u00ed jako ochrana proti stahuj\u00edc\u00edm (kdy\u017e je vypnuto).
 ManagerItem.superseeding=Super-Distribuce 
-ConfigView.label.userSuperSeeding=Pou\u017e\u00edvat superdistribuci (Superseeding)
-PeersView.uniquepiece=D\u00edl (m\u00f3d Superdistribuce) 
+ConfigView.label.userSuperSeeding=Pou\u017e\u00edt Superdistribuci
+PeersView.uniquepiece=D\u00edl (Re\u017eim Superdistribuce) 
 PeersView.uniquepiece.none=\u017d\u00e1dn\u00fd
-PeersView.timetosend=\u010cas do znovuzasl\u00e1n\u00ed d\u00edlu (m\u00f3d Superdistribuce)
-ConfigView.section.style.addurlsilently=Otev\u00edrat URL bez dialogu 
-ConfigView.section.style.addurlsilently.tooltip=Automaticky stahovat URL adresy p\u0159i\u0161l\u00fdch torrent\u016f bez otev\u00edr\u00e1n\u00ed potvrzovac\u00edho dialogov\u00e9ho okna
-ConfigView.section.file.decoder.prompt=V\u017edy, kdy je mo\u017en\u00e9, zeptat se na k\u00f3dov\u00e1n\u00ed
-ConfigView.section.file.decoder.prompt.tooltip=Poka\u017ed\u00e9, kdy je mo\u017en\u00e9 vybrat k\u00f3dov\u00e1n\u00ed, bude zobrazen dialog s jeho v\u00fdb\u011brem
-MyTorrentsView.menu.moveTop=Nej&v\u00fd\u0161e 
-MyTorrentsView.menu.moveEnd=Nej&n\u00ed\u017ee 
-ConfigView.label.moveonlyusingdefaultsave=pouze z v\u00fdchoz\u00ed slo\u017eky
-ConfigView.label.moveonlyusingdefaultsave.tooltip=P\u0159esunout pouze pokud jsou sta\u017een\u00e1 data ve v\u00fdchoz\u00ed slo\u017ece
-ConfigView.label.watchtorrentfolder=Automaticky p\u0159id\u00e1vat nov\u00e9 torrenty ze slo\u017eky
-ConfigView.label.watchtorrentfolder.tooltip=Pravideln\u011b kontroluje slo\u017eku na p\u0159itomnost nov\u00fdch .torrent soubor\u016f
-ConfigView.label.watchtorrentfolderinterval=Interval 
-ConfigView.label.watchtorrentfolderinterval.tooltip=Prodleva mezi kontrolami slo\u017eky na nov\u00e9 torrenty
-ConfigView.dialog.choosewatchtorrentfolderpath=Vyberte kontrolovanou slo\u017eku na .torrent soubory
-ConfigView.label.startwatchedtorrentsstopped=P\u0159idat zastaven\u00e9
-ConfigView.label.startwatchedtorrentsstopped.tooltip=P\u0159id\u00e1 nov\u00e9 Torrenty v ZASTAVEN\u00c9M stavu
-ConfigView.section.plugins=Dopl\u0148ky
+PeersView.timetosend=\u010cas do znovu zasl\u00e1n\u00ed D\u00edlu (Re\u017eim Superdistribuce)
+ConfigView.section.style.addurlsilently=Otev\u00edrat p\u0159edan\u00e1 URL potichu
+ConfigView.section.style.addurlsilently.tooltip=Automaticky stahovat p\u0159edan\u00e9/upu\u0161t\u011bn\u00e9 .torrent URL bez otev\u0159en\u00ed potvrzovac\u00edho dialogov\u00e9ho r\u00e1me\u010dku.
+ConfigView.section.file.decoder.prompt=V\u017edy se zeptat, pokud je volba k\u00f3dov\u00e1n\u00ed dostupn\u00e1
+ConfigView.section.file.decoder.prompt.tooltip=Poka\u017ed\u00e9 zobrazit dialogov\u00e9 okno, kdy\u017e je volba k\u00f3dov\u00e1n\u00ed dostupn\u00e1
+MyTorrentsView.menu.moveTop=Na &Vrchol
+MyTorrentsView.menu.moveEnd=&Na konec
+ConfigView.label.moveonlyusingdefaultsave=pouze pokud jsou ve v\u00fdchoz\u00edm adres\u00e1\u0159i
+ConfigView.label.moveonlyusingdefaultsave.tooltip=P\u0159esunout pouze pokud jsou sta\u017een\u00e1 data ve v\u00fdchoz\u00edm adres\u00e1\u0159i
+ConfigView.label.watchtorrentfolder=Automaticky importovat nov\u00e9 .torrenty
+ConfigView.label.watchtorrentfolder.tooltip=Pravideln\u011b hled\u00e1 nov\u00e9 .torrenty
+ConfigView.label.watchtorrentfolderinterval.tooltip=Prodleva, ne\u017e bude adres\u00e1\u0159 znovu prohled\u00e1n
+ConfigView.dialog.choosewatchtorrentfolderpath=Vyberte pros\u00edm adres\u00e1\u0159 pro import .torrent
+ConfigView.label.startwatchedtorrentsstopped=Za\u010d\u00edt jako zastaven\u00fd
+ConfigView.label.startwatchedtorrentsstopped.tooltip=P\u0159id\u00e1 nov\u00e9 .torrenty v ZASTAVEN\u00c9M stavu
+ConfigView.section.plugins=Z\u00e1suvn\u00e9 Moduly
 wizard.maketorrent.filesize=Velikost souboru/\u016f 
 wizard.maketorrent.piececount=Po\u010det d\u00edl\u016f 
 wizard.maketorrent.piecesize=Velikost d\u00edlu 
 wizard.maketorrent.auto=Auto 
 MainWindow.menu.view.stats=Statistiky 
 SpeedView.title.full=Aktivita 
-SpeedView.downloadSpeed.title=Rychlost downloadu 
-SpeedView.uploadSpeed.title=Rychlost stahov\u00e1n\u00ed 
-ConfigView.section.style.useSIUnits=Pou\u017e\u00edvat jednotky soustavy SI (KB -> KiB, atd.)
+SpeedView.downloadSpeed.title=Rychlost Stahov\u00e1n\u00ed
+SpeedView.uploadSpeed.title=Rychlost Odes\u00edl\u00e1n\u00ed
+ConfigView.section.style.useSIUnits=Pou\u017e\u00edt jednotky IEC (KB -> KiB, atd.)
 iconBar.top.tooltip=P\u0159esunout \u00fapln\u011b nahoru
 iconBar.bottom.tooltip=P\u0159esunout \u00fapln\u011b dol\u016f
 TableColumn.header.health=Zdrav\u00ed 
-MyTorrentsView.menu.health=O Zdrav\u00ed Torrentu 
-health.explain.grey=znamen\u00e1, \u017ee V\u00e1\u0161 torrent neb\u011b\u017e\u00ed (ani download, ani upload)
+MyTorrentsView.menu.health=O Zdrav\u00ed
+health.explain.grey=znamen\u00e1, \u017ee V\u00e1\u0161 torrent neb\u011b\u017e\u00ed (ani stahov\u00e1n\u00ed, ani odes\u00edl\u00e1n\u00ed)
 health.explain.red=znamen\u00e1, \u017ee nejste p\u0159i stahov\u00e1n\u00ed p\u0159ipojeni k \u017e\u00e1dn\u00e9mu klientovi
-health.explain.blue=znamen\u00e1 p\u0159i distribuci, \u017ee nejste p\u0159ipojeni k \u017e\u00e1dnemu klientovi\np\u0159i stahov\u00e1n\u00ed znamen\u00e1, \u017ee jste p\u0159ipojeni k n\u011bjak\u00fdm klient\u016fm, ale Tracker nen\u00ed dostupn\u00fd
-health.explain.yellow=znamen\u00e1, \u017ee Tracker je v po\u0159\u00e1dku, jste p\u0159ipojen ke klient\u016fm, ale neexistuje \u017eadn\u00e9 p\u0159ipojen\u00ed zven\u010d\u00ed.\nPokud st\u00e1le vid\u00edte tuto \u017elutou u Va\u0161ich Torrent\u016f, pak nejsp\u00ed\u0161 m\u00e1te probl\u00e9my s NAT
-health.explain.green=znamen\u00e1, \u017ee v\u0161e je v po\u0159\u00e1dku
-ConfigView.section.style.alwaysRefreshMyTorrents=Neust\u00e1le obnovovat Moje Torrenty
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Obnovovat okno Moje Torrenty, i kdy\u017e nen\u00ed zobrazeno (pro n\u011bkter\u00e9 dopl\u0148ky mIrc)
+health.explain.blue=p\u0159i distribuci znamen\u00e1, \u017ee nejste p\u0159ipojeni k \u017e\u00e1dn\u00e9mu klientovi\np\u0159i stahov\u00e1n\u00ed znamen\u00e1, \u017ee jste p\u0159ipojeni k n\u011bjak\u00fdm klient\u016fm, ale Tracker nen\u00ed dostupn\u00fd
+health.explain.yellow=znamen\u00e1, \u017ee Tracker je v po\u0159\u00e1dku, jste p\u0159ipojen ke klient\u016fm, ale neexistuje \u017eadn\u00e9 vzd\u00e1len\u00e9 p\u0159ipojen\u00ed.\nPokud st\u00e1le vid\u00edte tuto \u017elutou u Va\u0161ich Torrent\u016f, pak nejsp\u00ed\u0161 m\u00e1te probl\u00e9my s NAT
+health.explain.green=znamen\u00e1, \u017ee v\u0161e b\u011b\u017e\u00ed v po\u0159\u00e1dku
+ConfigView.section.style.alwaysRefreshMyTorrents=Neust\u00e1le obnovovat {library.name}
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Tato volba obnov\u00ed zobrazen\u00ed {library.name}, i kdy\u017e nen\u00ed zobrazena (u\u017eite\u010dn\u00e9 pro jist\u00e9 z\u00e1suvn\u00e9 moduly mIRC)
 #
 #2.0.7.0
 #
-security.certtruster.title=Varov\u00e1n\u00ed bezpe\u010dnostn\u00edho certifik\u00e1tu
-security.certtruster.intro=Certifik\u00e1t byl vyd\u00e1n spole\u010dnost\u00ed, kter\u00e9 jste se rozhodli ned\u016fv\u011b\u0159ovat
+security.certtruster.title=Varov\u00e1n\u00ed Bezpe\u010dnostn\u00edho Certifik\u00e1tu
+security.certtruster.intro=Certifik\u00e1t bezpe\u010dnosti byl vyd\u00e1n spole\u010dnost\u00ed, kter\u00e9 ned\u016fv\u011b\u0159ujete
 security.certtruster.resource=Zdroj:
 security.certtruster.issuedto=Vyd\u00e1no pro:
 security.certtruster.issuedby=Vydal:
@@ -707,311 +721,318 @@ security.certtruster.prompt=Chcete certifik\u00e1tu d\u016fv\u011b\u0159ovat?
 security.certtruster.yes=Ano
 security.certtruster.no=Ne
 ConfigView.section.tracker.torrentsperpage=Kolik torrent\u016f na str\u00e1nku ?  [0: neomezen\u011b]
-MainWindow.menu.file.share=Sd\u00edlet
+MainWindow.menu.file.share=Klasick\u00e9 &Sd\u00edlen\u00ed
 MainWindow.menu.file.share.file=&Soubor...
-MainWindow.menu.file.share.dir=S&lo\u017eku...
-MainWindow.menu.file.share.dircontents=&Obsah slo\u017eky...
-MainWindow.menu.file.share.dircontentsrecursive=Obsah slo\u017eky (&Rekurzivn\u011b)...
-MainWindow.dialog.share.sharefile=Vyberte soubor ke sd\u00edlen\u00ed
-MainWindow.dialog.share.sharedir=Vyberte slo\u017eku ke sd\u00edlen\u00ed
-MainWindow.dialog.share.sharedircontents=Vyberte slo\u017eku, jej\u00ed\u017e obsah bude sd\u00edlen
+MainWindow.menu.file.share.dir=A&dres\u00e1\u0159e...
+MainWindow.menu.file.share.dircontents=&Obsah Adres\u00e1\u0159e...
+MainWindow.menu.file.share.dircontentsrecursive=Obsah Adres\u00e1\u0159e... (&Rekurzivn\u011b)
+MainWindow.dialog.share.sharefile=Vyberte Soubor Pro Sd\u00edlen\u00ed
+MainWindow.dialog.share.sharedir=Vyberte Adres\u00e1\u0159 Pro Sd\u00edlen\u00ed
+MainWindow.dialog.share.sharedircontents=Vyberte Obsah Adres\u00e1\u0159e, Kter\u00fd Bude Sd\u00edlen
 MainWindow.dialog.share.sharedircontents.recursive=Rekurzivn\u011b
-globalmanager.download.remove.veto=Odebr\u00e1n\u00ed zam\u00edtnuto
-plugin.sharing.download.remove.veto=Tato polo\u017eka vznikla sd\u00edlen\u00edm.\nK odebr\u00e1n\u00ed polo\u017eky je pot\u0159eba odebrat p\u0159idru\u017een\u00e9 sd\u00edlen\u00ed: go to Tools->My Classic-Shares. 
+globalmanager.download.remove.veto=\u010cinnost Odebr\u00e1n\u00ed Vetov\u00e1na
+plugin.sharing.download.remove.veto=Toto stahov\u00e1n\u00ed je v\u00fdsledek zdroje, kter\u00fd je klasicky sd\u00edlen.\nK odstran\u011bn\u00ed stahov\u00e1n\u00ed, odstra\u0148te spojen\u00e9 klasick\u00e9 sd\u00edlen\u00ed: jd\u011bte do N\u00e1stroje->M\u00e1 Klasick\u00e1 Sd\u00edlen\u00ed.
 ConfigView.section.tracker.main=Hlavn\u00ed
-ConfigView.label.prioritizefirstpiece=V\u011bt\u0161\u00ed priorita pro prvn\u00ed a posledn\u00ed d\u00edly soubor\u016f
-ConfigView.label.prioritizefirstpiece.tooltip=Vuze se pokus\u00ed st\u00e1hnout za\u010d\u00e1tek souboru jako prvn\u00ed.\nUmo\u017en\u00ed rychl\u00e9 ov\u011b\u0159en\u00ed a n\u00e1hled.
-ConfigView.section.file.confirm_data_delete=Potvrzovat maz\u00e1n\u00ed dat
-ConfigView.section.file.confirm_data_delete.tooltip=Vy\u017eadovat potvrzen\u00ed akce p\u0159i pou\u017eit\u00ed "Odebrat a smazat ..."
-TrayWindow.menu.startalldownloads=Spustit v\u0161echny Torrenty
-SystemTray.menu.startalltransfers=Spustit v\u0161echny p\u0159enosy
-sharing.progress.title=Proces sd\u00edlen\u00ed
+ConfigView.label.prioritizefirstpiece=Up\u0159ednost\u0148ovat nejd\u0159\u00edve prvn\u00ed a posledn\u00ed d\u00edl soubor\u016f
+ConfigView.label.prioritizefirstpiece.tooltip=Pokus\u00ed se st\u00e1hnout \u00fapln\u00fd za\u010d\u00e1tek a konec souboru jako prvn\u00ed.\nPro podporu \u010dasn\u00e9ho nahl\u00ed\u017een\u00ed.
+ConfigView.section.file.delete.include_files_outside_save_dir=P\u0159i maz\u00e1n\u00ed dat umo\u017enit, aby soubory propojen\u00e9 mimo adres\u00e1\u0159 ulo\u017een\u00ed torrentu, byly tak\u00e9 odstran\u011bny
+TrayWindow.menu.startalldownloads=Spustit V\u0161echny Torrenty
+SystemTray.menu.startalltransfers=Spustit V\u0161echny P\u0159enosy
+sharing.progress.title=Pr\u016fb\u011bh Klasick\u00e9ho Sd\u00edlen\u00ed
 sharing.progress.hide=Skr\u00fdt
-MainWindow.menu.view.myshares=M\u00e1 Sd\u00edlen\u00ed
-MySharesView.title.full=M\u00e1 Sd\u00edlen\u00ed
+MainWindow.menu.view.myshares=M\u00e1 Klasick\u00e1 Sd\u00edlen\u00ed
+MySharesView.title.full=M\u00e1 Klasick\u00e1 Sd\u00edlen\u00ed
 MySharesView.name=N\u00e1zev
 MySharesView.type=Typ
 MySharesView.type.file=Soubor
-MySharesView.type.dir=Slo\u017eka
-MySharesView.type.dircontents=Obsah slo\u017eky
-MySharesView.type.dircontentsrecursive=Obsah slo\u017eky (rekurzivn\u011b)
+MySharesView.type.dir=Adres\u00e1\u0159
+MySharesView.type.dircontents=Obsah adres\u00e1\u0159e
+MySharesView.type.dircontentsrecursive=Obsah adres\u00e1\u0159e (rekurzivn\u011b)
 MySharesView.menu.remove=Odebrat
 ConfigView.section.tracker.extensions=Roz\u0161\u00ed\u0159en\u00ed
-ConfigView.section.tracker.sendpeerids=Pos\u00edlat klient\u016fm jejich ozna\u010den\u00ed (identitu)
-ConfigView.section.tracker.enableudp=Povolit UDP Tracker Protokol 
-plugin.sharing.torrent.remove.veto=Tato polo\u017eka Trackeru vznikla sd\u00edlen\u00edm.\nK odebr\u00e1n\u00ed polo\u017eky je pot\u0159eba odebrat p\u0159idru\u017een\u00e9 sd\u00edlen\u00ed: go to Tools->My Classic-Shares.
-plugin.download.remove.veto.notstopped=Torrent nem\u016f\u017ee b\u00fdt odebr\u00e1n, proto\u017ee nen\u00ed zastaven
-plugin.sharing.remove.veto=Tato sd\u00edlen\u00e1 polo\u017eka je v\u00fdsledek "Sd\u00edlen\u00e9 slo\u017eky" a nem\u016f\u017ee b\u00fdt samostatn\u011b odstran\u011bna.\n Odeberte ko\u0159enovou slo\u017eku
+ConfigView.section.tracker.sendpeerids=Poslat identitu klienta stahuj\u00edc\u00edm
+ConfigView.section.tracker.enableudp=Povolit UDP tracker protokol 
+plugin.sharing.torrent.remove.veto=Tato registrace trackeru je v\u00fdsledkem zdroje, kter\u00fd je klasicky sd\u00edlen.\nK odstran\u011bn\u00ed stahov\u00e1n\u00ed, odstra\u0148te spojen\u00e9 klasick\u00e9 sd\u00edlen\u00ed: jd\u011bte do N\u00e1stroje->M\u00e1 Klasick\u00e1 Sd\u00edlen\u00ed.
+plugin.download.remove.veto.notstopped=Stahov\u00e1n\u00ed nem\u016f\u017ee b\u00fdt odebr\u00e1no, proto\u017ee nen\u00ed zastaveno
+plugin.sharing.remove.veto=Toto klasick\u00e9 sd\u00edlen\u00ed je podsd\u00edlen\u00ed sd\u00edlen\u00ed 'obsahu adres\u00e1\u0159e' a nem\u016f\u017ee b\u00fdt jednozna\u010dn\u011b smaz\u00e1no.\nSma\u017ete ko\u0159en klasick\u00e9ho sd\u00edlen\u00ed
 GeneralView.label.hash.tooltip=Kliknut\u00edm zkop\u00edrujete Hash do schr\u00e1nky
 ConfigView.section.tracker.maxpeersreturned=Maxim\u00e1ln\u00ed po\u010det vr\u00e1cen\u00fdch klient\u016f [0: neomezen\u011b]
-ConfigView.label.serverport=P\u0159\u00edchoz\u00ed TCP port
-ConfigView.label.serverport.tooltip=Port mus\u00ed b\u00fdt v rozsahu 1-65535, ne 6880 ten je rezervovan\u00fd pro vnit\u0159n\u00ed pot\u0159ebul Azurea.
+ConfigView.label.serverport=P\u0159\u00edchoz\u00ed naslouchaj\u00edc\u00ed TCP / UDP port
+ConfigView.label.serverport.tooltip=Port mus\u00ed b\u00fdt v rozsahu 1-65535, ne 6880 ten je rezervovan\u00fd pro vnit\u0159n\u00ed pou\u017eit\u00ed Vuze.
 configureWizard.nat.server.tcp_listen_port=P\u0159\u00edchoz\u00ed naslouchan\u00fd TCP port
-ConfigView.section.sharing=Sd\u00edlen\u00ed
-ConfigView.section.sharing.usessl=Pro sd\u00edlen\u00e9 soubory pou\u017e\u00edvat SSL (vy\u017eaduje nastaven\u00ed Trackeru)
-ConfigView.section.style.dropdiraction=P\u0159eta\u017een\u00ed (T\u00e1hni a spus\u0165) slo\u017eky
+ConfigView.section.sharing=Klasick\u00e9 Sd\u00edlen\u00ed
+ConfigView.section.sharing.usessl=Pou\u017e\u00edt SSL pro klasicky sd\u00edlen\u00e9 zdroje (vy\u017eaduje nastaven\u00ed Trackeru)
+ConfigView.section.style.dropdiraction=\u010cinnost T\u00e1hni a spus\u0165 pro adres\u00e1\u0159e
 ConfigView.section.style.dropdiraction.opentorrents=Otev\u0159e torrenty
-ConfigView.section.style.dropdiraction.sharefolder=Nasd\u00edl\u00ed slo\u017eku
-ConfigView.section.style.dropdiraction.sharefoldercontents=Nasd\u00edl\u00ed obsah slo\u017eky
+ConfigView.section.style.dropdiraction.sharefolder=Klasick\u00e9 Sd\u00edlen\u00ed Adres\u00e1\u0159e
+ConfigView.section.style.dropdiraction.sharefoldercontents=Klasick\u00e9 Sd\u00edlen\u00ed Obsahu
 #
 # 2.0.7.x
 #
 Categories.all=V\u0161e
 Categories.uncategorized=Neza\u0159azen\u00e9
-CategoryAddWindow.message=Jm\u00e9no nov\u00e9 kategorie
-CategoryAddWindow.title=P\u0159idat novou kategorii
-ConfigView.label.autoSeedingIgnoreInfo=Ignorovan\u00e9 torrenty jdou nakonec distribu\u010dn\u00ed fronty a nejsou automaticky spu\u0161t\u011bny. Pravidla ignorov\u00e1n\u00ed se nevztahuj\u00ed na torrenty, pro kter\u00e9 plat\u00ed pravidla top priority. Pokud nen\u00ed ud\u00e1no jinak, pak hodnota 0 znamen\u00e1 vypnut\u00ed pravidla.
-ConfigView.label.directory=Slo\u017eka
-ConfigView.label.disconnetseed.tooltip=P\u0159i distribuci odpojit v\u0161echny distribuj\u00edc\u00ed klienty.\nNen\u00ed nutn\u00e9 b\u00fdt s nimi v kontaktu (ni\u017e\u0161\u00ed p\u0159enos dat).
+CategoryAddWindow.message=Zadejte jm\u00e9no nov\u00e9 kategorie
+CategoryAddWindow.title=P\u0159idat Novou Kategorii
+ConfigView.label.autoSeedingIgnoreInfo=Ignorovan\u00e9 torrenty jdou nakonec distribu\u010dn\u00ed fronty. Nejsou automaticky spu\u0161t\u011bny.\nPravidla ignorov\u00e1n\u00ed se nevztahuj\u00ed na torrenty, kter\u00e9 spl\u0148uj\u00ed krit\u00e9ria Prvn\u00ed Priority.\nPokud nen\u00ed ud\u00e1no jinak, pou\u017eijte hodnotu 0 pro zak\u00e1z\u00e1n\u00ed pravidla.
+ConfigView.label.directory=Adres\u00e1\u0159
+ConfigView.label.disconnetseed.tooltip=P\u0159i distribuci torrentu, odpojit v\u0161echny klienty, kte\u0159\u00ed tak\u00e9 distribuuj\u00ed.\nNen\u00ed nutn\u00e9, aby s V\u00e1mi mluvily.
 ConfigView.label.ignoreCase=Ignorovat velikost p\u00edsmen
-ConfigView.label.ignoreSeeds=Ignorovat torrenty a alespo\u0148
-ConfigView.label.importdirectory=Slo\u017eka importu
-ConfigView.label.minPeersToBoostNoSeeds.tooltip=Jak\u00fdkoliv torrent bez zdroj\u016f maj\u00edc\u00ed m\u00e9n\u011b stahuj\u00edc\u00edch ne\u017e nastav\u00edte,\nbude posunut na konec fronty.
-ConfigView.label.minPeersToBoostNoSeeds=Ni\u017e\u0161\u00ed hodnocen\u00ed pro torrenty bez zdroj\u016f nebo s m\u00e9n\u011b ne\u017e
-ConfigView.label.minSeedingTime.tooltip=Hodnocen\u00ed se m\u016f\u017ee \u010dasto v kr\u00e1tk\u00fdch intervalech m\u011bnit; n\u011bkdy jsou torrenty spu\u0161t\u011bny, jen aby se z\u00e1hy zase ukon\u010dily a byly zp\u011bt za\u0159azeny do fronty.\nToto nastaven\u00ed obch\u00e1z\u00ed probl\u00e9m donucen\u00edm torrent\u016f z\u016fstat v distribuci po nastaven\u00fd \u010das.\nPokud chcete, m\u016f\u017eete torrent kdykoliv zastavit ru\u010dn\u011b.
+ConfigView.label.ignoreSeeds=Ignorovat torrenty s alespo\u0148
+ConfigView.label.importdirectory=Adres\u00e1\u0159 importu
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=Jak\u00e9koliv torrenty bez zdroj\u016f maj\u00edc\u00ed m\u00e9n\u011b stahuj\u00edc\u00edch ne\u017e nastav\u00edte,\nbudou posunuty  sm\u011brem ke konci fronty.
+ConfigView.label.minPeersToBoostNoSeeds=Ni\u017e\u0161\u00ed Hodnocen\u00ed Distribuce pro torrenty bez zdroj\u016f nebo s m\u00e9n\u011b ne\u017e
+ConfigView.label.minSeedingTime.tooltip=Hodnocen\u00ed Distribuce se m\u016f\u017ee \u010dasto v kr\u00e1tk\u00fdch intervalech m\u011bnit, co\u017e zp\u016fsob\u00ed, \u017ee n\u011bkdy jsou torrenty spu\u0161t\u011bny, jen aby se z\u00e1hy zase ukon\u010dily a byly zp\u011bt za\u0159azeny do fronty.\nToto nastaven\u00ed zm\u00edr\u0148uje probl\u00e9m donucen\u00edm torrent\u016f z\u016fstat v distribuci po nastaven\u00fd \u010das.Pokud chcete, m\u016f\u017eete torrent kdykoliv zastavi [...]
 ConfigView.label.minSeedingTime=Minim\u00e1ln\u00ed \u010das distribuce v sekund\u00e1ch
-ConfigView.label.minSpeedForActiveDL.tooltip=Prvn\u00edch 30 sekund je ka\u017ed\u00fd nedokon\u010den\u00fd torrent pova\u017eov\u00e1n za stahuj\u00edc\u00ed
-ConfigView.label.minSpeedForActiveDL=Rychlost stahov\u00e1n\u00ed, pod kterou se nepo\u010d\u00edt\u00e1 torrent jako aktivn\u011b stahuj\u00edc\u00ed
+ConfigView.label.minSpeedForActiveDL.tooltip=Pozice stahov\u00e1n\u00ed je v\u017edy pou\u017eita pro prvn\u00edch 30 sekund\npot\u00e9 je nedokon\u010den\u00fd torrent spu\u0161t\u011bn
+ConfigView.label.minSpeedForActiveDL=Nepo\u010d\u00edtat torrent jako pou\u017e\u00edvaj\u00edc\u00ed pozici stahov\u00e1n\u00ed, pokud je rychlost ni\u017e\u0161\u00ed ne\u017e
 ConfigView.label.peers=klient\u016f
 ConfigView.label.queue.debuglog=Zapisovat informace o lad\u011bn\u00ed programu
-ConfigView.label.queue.debuglog.info=P\u0159idat seznam vyla\u010fovac\u00edch informac\u00ed do konzole/zaznamen\u00e1vac\u00edho souboru.\nA\u010dkoli zak\u00f3dovan\u011b, ladic\u00ed informace ud\u00e1v\u00e1j\u00ed stav torrent\u016f a pro\u010d byly/nebyly \u010di spu\u0161t\u011bny/za\u0159azeny do fronty.
+ConfigView.label.queue.debuglog.info=P\u0159id\u00e1 lad\u00edc\u00ed informace fronty do konzole/souboru z\u00e1znamu.\nI kdy\u017e jsou slo\u017eit\u00e9, lad\u00edc\u00ed informace V\u00e1m sd\u011bluj\u00ed stav torrent\u016f a pro\u010d jsou spu\u0161t\u011bny/nespu\u0161t\u011bny/ve frotn\u011b.
 ConfigView.label.queue.minQueueingShareRatio=Neza\u0159azovat do fronty ani nezastavovat torrent, dokud pom\u011br sd\u00edlen\u00ed nedos\u00e1hne
-ConfigView.label.ratio=Pom\u011br
-ConfigView.label.removeOnStop=Jakmile je torrent zastaven, odebrat ho ze seznamu
-ConfigView.label.savedirectory=Slo\u017eka pro torrenty
-ConfigView.label.seeding.autoReposition.tooltip=Pokud je za\u0161krtnuto, je po\u0159ad\u00ed torrent\u016f (sloupec '#') upravov\u00e1no podle seeding po\u0159ad\u00ed\nPokud v\u00e1s nezaj\u00edmaj\u00ed hodnoty seeding po\u0159ad\u00ed, pak t\u00edmto zp\u016fsobem vid\u00edte, v jak\u00e9m po\u0159ad\u00ed budou dokon\u010den\u00e9 torrenty spou\u0161t\u011bny.
-ConfigView.label.seeding.autoReposition=Automaticky \u0159adit torrenty podle jejich hodnocen\u00ed
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u010casto torrenty s m\u00e1l\u00fdm po\u010dtem distribuuj\u00edc\u00edch a velk\u00fdm po\u010dtem stahuj\u00edc\u00edch znamenaj\u00ed, \u017ee nen\u00ed mezi klienty roz\u0161\u00ed\u0159en\u00e1 cel\u00e1 kopie souboru.\nProto nen\u00ed vhodn\u00e9 aby pravidla distribuce p\u0159edpokl\u00e1dala dal\u0161\u00ed cel\u00e9 kopie (a tak nespr\u00e1vn\u011b sni\u017eovala hodnocen\u00ed torrentu)
+ConfigView.label.ratio=pom\u011br
+ConfigView.label.removeOnStop=Odstranit torrent ze seznamu, pot\u00e9, co je automaticky zastaven
+ConfigView.label.savedirectory=Adres\u00e1\u0159 pro ulo\u017een\u00ed
+ConfigView.label.seeding.autoReposition.tooltip=Pokud je zapnuto, je po\u0159ad\u00ed torrent\u016f (sloupec '#') upravov\u00e1no, aby se shodovalo s Hodnocen\u00edm Distribuce\nToto je u\u017eite\u010dn\u00e9, kdy\u017e se V\u00e1m nel\u00edb\u00ed vid\u011bt \u010d\u00edsla Hodnocen\u00ed Distribuce, ale st\u00e1le chcete v\u011bd\u011bt po\u0159ad\u00ed, v kter\u00fdch budou dokon\u010den\u00e9 torrenty spou\u0161t\u011bny.
+ConfigView.label.seeding.autoReposition=Automaticky \u0159adit torrenty podle jejich Hodnocen\u00ed Distribuce
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u010casto torrenty s mal\u00fdm po\u010dtem zdroj\u016f a velk\u00fdm po\u010dtem stahuj\u00edc\u00edch znamen\u00e1, \u017ee pravd\u011bpodobn\u011b nen\u00ed p\u0159\u00edtomna mezi klienty \u00fapln\u00e1 kopie.\nTud\u00ed\u017e byste nemuseli cht\u00edt, aby pravidla distribuce p\u0159edst\u00edrala, \u017ee existuje \u00fapln\u00e1 kopie (a t\u00edm nespr\u00e1vn\u011b sni\u017eovala jejich hodnocen\u00ed)
 ConfigView.label.seeding.fakeFullCopySeedStart=ale pouze pro torrenty s alespo\u0148
-ConfigView.label.seeding.ignore=Ignorovat pravidla
+ConfigView.label.seeding.ignore=Pravidla Ignorov\u00e1n\u00ed
 ConfigView.label.seeding.ignore0Peers=Ignorovat torrenty s 0 klienty
-ConfigView.label.seeding.ignoreRatioPeers=Ignorovat torrenty s alespo\u0148 1 distributorem na
+ConfigView.label.seeding.ignoreRatioPeers=Ignorovat torrenty s alespo\u0148 1 distributorem na ka\u017ed\u00e9
 ConfigView.label.seeding.ignoreShareRatio=Ignorovat torrenty s pom\u011brem sd\u00edlen\u00ed
-ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignorovat torrent, i kdy\u017e\n plat\u00ed pravidla top priority
+ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignorovat torrent, i kdy\u017e\n plat\u00ed pravidlo Prvn\u00ed Priority
 ConfigView.label.seeding.ignore.header.rule=Pravidlo
 ConfigView.label.seeding.ignore.header.value=Hodnota
-ConfigView.label.seeding.firstPriority.info=Torrenty ur\u010den\u00e9 pravidly top priority budou v\u017edy na za\u010d\u00e1tku fronty. \u017d\u00e1dn\u00fd z t\u011bchto torrent\u016f nebude automaticky zastaven a za\u0159azen zp\u011bt do fronty. Torrenty s top prioritou si t\u00e9\u017e vezmou simult\u00e1nn\u00ed slot na stahov\u00e1n\u00ed, pokud ho pot\u0159ebuj\u00ed.
-ConfigView.label.seeding.firstPriority.FP=Top priorita
-ConfigView.label.seeding.firstPriority=Top priorita plat\u00ed pro torrenty s
+ConfigView.label.seeding.firstPriority.info=Torrenty s Prvn\u00ed Prioritou budou v\u017edy na za\u010d\u00e1tku fronty.\nJak\u00e9koliv torrenty, shoduj\u00edc\u00ed se s krit\u00e9riem Prvn\u00ed Priority nebudou automaticky zastaveny a za\u0159azeny do fronty.\nTorrent hoduj\u00edc\u00ed se s krit\u00e9riem Prvn\u00ed Priority tak\u00e9 m\u016f\u017ee zabrat pozici Soub\u011b\u017en\u00e9ho Stahov\u00e1n\u00ed, pokud pot\u0159ebuje.
+ConfigView.label.seeding.firstPriority.FP=Prvn\u00ed Priorita
+ConfigView.label.seeding.firstPriority=Prvn\u00ed priorita plat\u00ed pro torrenty s
 ConfigView.label.seeding.firstPriority.following=z n\u00e1sleduj\u00edc\u00edch pravidel:
 ConfigView.label.seeding.firstPriority.shareRatio=Pom\u011br sd\u00edlen\u00ed pod
-ConfigView.label.seeding.firstPriority.seedingMinutes=\u010cas od zm\u011bny stahov\u00e1n\u00ed v distribuci
-ConfigView.label.seeding.firstPriority.DLMinutes=\u010cas od za\u010d\u00e1tku stahov\u00e1n\u00ed 
-ConfigView.label.seeding.numPeersAsFullCopy.tooltip=P\u0159edpokl\u00e1d\u00e1n\u00edm existence jedn\u00e9 cel\u00e9 kopie na X klient\u016f sn\u00ed\u017e\u00edte hodnocen\u00ed torrent\u016f s velk\u00fdm po\u010dtem klient\u016f.\nTyto Torrenty pravd\u011bpodobn\u011b budou m\u00edt i velk\u00fd provoz.\nToto nastaven\u00ed nezm\u011bn\u00ed zobrazen\u00ed informace "po\u010det zdroj\u016f" 
-ConfigView.label.seeding.numPeersAsFullCopy=P\u0159edpokl\u00e1dat existenci alespo\u0148 jedn\u00e9 cel\u00e9 kopie pro ka\u017ed\u00fdch\n(0 : nep\u0159edpokl\u00e1dat)
-ConfigView.label.seeding.preferLargerSwarms.tooltip=Pokud distribuujete torrenty klient\u016fm s pomal\u00fdm \u010di \u010d\u00e1ste\u010dn\u011b blokovan\u00fdm p\u0159ipojen\u00edm k internetu, pom\u016f\u017ee preferov\u00e1n\u00ed torrent\u016f s v\u011bt\u0161\u00edm po\u010dtem \u00fa\u010dastn\u00edk\u016f.\nPokud distribuujete torrenty s velkou roz\u0161\u00ed\u0159enost\u00ed d\u00edl\u016f, pak je v\u00fdhodn\u00e9 preferovat torrenty s men\u0161\u00edm po\u010dtem \u00fa\u010 [...]
-ConfigView.label.seeding.preferLargerSwarms=Kdy\u017e maj\u00ed dva torrenty stejn\u00e9 hodnocen\u00ed, preferovat ten s v\u011bt\u0161\u00edm po\u010dtem \u00fa\u010dastn\u00edk\u016f
-ConfigView.label.seeding.rankType.none.tooltip=Po\u0159ad\u00ed zalo\u017eeno na sloupci '#' (Po\u010det)
-ConfigView.label.seeding.rankType.none=\u017d\u00e1dn\u00e9
-ConfigView.label.seeding.rankType.peerSeed.options=Distrubuto\u0159i:stahuj\u00edc\u00ed - ukazatel mo\u017enost\u00ed
-ConfigView.label.seeding.rankType.peerSeed.tooltip=Vy\u0161\u0161\u00ed pom\u011br = vy\u0161\u0161\u00ed hodnocen\u00ed
-ConfigView.label.seeding.rankType.peerSeed=Pom\u011br stahuj\u00edc\u00ed:distributo\u0159i
-ConfigView.label.seeding.rankType.seed.fallback=Sn\u00ed\u017eit pom\u011br popt\u00e1vky:nab\u00eddky podle\n(0 : Nikdy nesn\u00ed\u017eit)
-ConfigView.label.seeding.rankType.seed.options=Po\u010det nab\u00eddky dle volby
-ConfigView.label.seeding.rankType.seed.tooltip=M\u00e9n\u011b distributor\u016f = vy\u0161\u0161\u00ed hodnocen\u00ed
-ConfigView.label.seeding.rankType.seed=Po\u010det distributor\u016f
-ConfigView.label.seeding.rankType.timedRotation.tooltip=V\u0161echny dokon\u010den\u00e9 torrenty ve front\u011b se budou st\u0159\u00eddat v distribuci.\n\u010cas, po kter\u00fd budou  poka\u017ed\u00e9 distribuov\u00e1ny je nastaven pomoc\u00ed 'Minim\u00e1ln\u00ed \u010das distribuce'
-ConfigView.label.seeding.rankType.timedRotation=St\u0159\u00edd\u00e1n\u00ed po \u010dasov\u00fdch intervalech
-ConfigView.label.seeding.rankType.tooltip=Automaticky jsou spu\u0161t\u011bny torrenty s nejvy\u0161\u0161\u00edm ohodnocen\u00edm.\nPokud n\u011bkter\u00fd torrent dos\u00e1hne vy\u0161\u0161\u00edho hodnocen\u00ed, je ten s ni\u017e\u0161\u00edm pozastaven a vrac\u00ed se zp\u011bt do fronty.\n\nAutomatick\u00e9 spu\u0161t\u011bn\u00ed je umo\u017en\u011bno jen torrent\u016fm ve front\u011b.\nZastaven\u00e9 torrenty nejsou nikdy automaticky spu\u0161t\u011bny.
-ConfigView.label.seeding.rankType=Hodnocen\u00ed dokon\u010den\u00fdch torrent\u016f pro automatick\u00e9 spou\u0161t\u011bn\u00ed zalo\u017een\u00e9 na:
-ConfigView.label.stopAfterMinutes=Zastavit distribuci po ur\u010den\u00e9m \u010dase
-ConfigView.label.switchpriority.tooltip=N\u00edzk\u00e1 priorita sni\u017euje torrentu p\u0159id\u011blen\u00fd pr\u016ftok dat sm\u011brem ven
-ConfigView.pluginlist.info=Byly nalezeny n\u00e1sleduj\u00edc\u00ed dopl\u0148ky. N\u011bkter\u00e9 z nich nemusej\u00ed m\u00edt konfigura\u010dn\u00ed dialog.
-ConfigView.pluginlist.noplugins=Nebyly nalezeny \u017e\u00e1dn\u00e9 dopl\u0148ky.
+ConfigView.label.seeding.firstPriority.seedingMinutes=Uplynul\u00fd \u010das od zm\u011bny ze stahov\u00e1n\u00ed na distribuci
+ConfigView.label.seeding.firstPriority.DLMinutes=Uplynul\u00fd \u010das od za\u010d\u00e1tku stahov\u00e1n\u00ed
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=P\u0159edst\u00edr\u00e1n\u00edm existence jedn\u00e9 cel\u00e9 kopie na X klient\u016f sn\u00ed\u017e\u00edte hodnocen\u00ed torrent\u016f s vysok\u00fdm po\u010dtem klient\u016f.\nPravd\u011bpodobn\u011b torrenty s vysok\u00fdm po\u010dtem klient\u016f maj\u00ed tak\u00e9 velk\u00fd provoz.\nToto nastaven\u00ed nezm\u011bn\u00ed zobrazen\u00ed "# zdroj\u016f".
+ConfigView.label.seeding.numPeersAsFullCopy=P\u0159edst\u00edrat existenci jedn\u00e9 cel\u00e9 kopie pro ka\u017ed\u00fdch\n(0 : Nep\u0159edpokl\u00e1dat)
+ConfigView.label.seeding.preferLargerSwarms.tooltip=Pokud hlavn\u011b distribuujete torrenty klient\u016fm, kte\u0159\u00ed jsou "zasekl\u00ed". up\u0159ednost\u0148ov\u00e1n\u00edm velk\u00e9ho po\u010dtu \u00fa\u010dastn\u00edk\u016f je dobr\u00fd n\u00e1pad\nKdy\u017e hlavn\u011b distribuujete torrenty s vysokou dostupnost\u00ed, je lep\u0161\u00ed up\u0159ednost\u0148ovat torrenty s men\u0161\u00edm po\u010dtem \u00fa\u010dastn\u00edk\u016f.
+ConfigView.label.seeding.preferLargerSwarms=Kdy\u017e torrenty maj\u00ed stejn\u00e9 hodnocen\u00ed, preferovat ten s v\u011bt\u0161\u00edm po\u010dtem \u00fa\u010dastn\u00edk\u016f
+ConfigView.label.seeding.rankType.none.tooltip=Po\u0159ad\u00ed zalo\u017eeno na sloupci '#'
+ConfigView.label.seeding.rankType.none=Ni\u010deho
+ConfigView.label.seeding.rankType.peer.tooltip=v\u00edce klient\u016f a m\u00e9n\u011b zdroj\u016f = vy\u0161\u0161\u00ed hodnocen\u00ed\nToto hodnocen\u00ed zmen\u0161uje po\u010det torrent\u016f, kter\u00e9 pot\u0159ebuj\u00ed b\u00fdt aktivn\u00ed pro maximalizaci odes\u00edl\u00e1n\u00ed
+ConfigView.label.seeding.rankType.peer=V\u00e1\u017een\u00e9ho Po\u010dtu Klient\u016f
+ConfigView.label.seeding.rankType.peerSeed.options=Mo\u017enosti Pom\u011br Klienti:Distributo\u0159i
+ConfigView.label.seeding.rankType.peerSeed.tooltip=Vy\u0161\u0161\u00ed Pom\u011br = Vy\u0161\u0161\u00ed Hodnocen\u00ed
+ConfigView.label.seeding.rankType.peerSeed=Pom\u011br Klienti:Distributo\u0159i
+ConfigView.label.seeding.rankType.seed.fallback=Vr\u00e1tit se na Pom\u011br Klienti:Distributo\u0159i po\n(0 : Nikdy Se Nevracet)
+ConfigView.label.seeding.rankType.seed.options=Mo\u017enosti Pouze Po\u010det Distributor\u016f
+ConfigView.label.seeding.rankType.seed.tooltip=M\u00e9n\u011b Distributor\u016f = Vy\u0161\u0161\u00ed Hodnocen\u00ed
+ConfigView.label.seeding.rankType.seed=Pouze Po\u010det Distributor\u016f
+ConfigView.label.seeding.rankType.timedRotation.tooltip=V\u0161echny dokon\u010den\u00e9 torrenty ve front\u011b se budou st\u0159\u00eddat v re\u017eimu distribuce.\nD\u00e9lka distribuce je nastavena podle 'Minim\u00e1ln\u00ed D\u00e9lka Distribuce'
+ConfigView.label.seeding.rankType.timedRotation=\u010casovan\u00fd Ob\u011bh
+ConfigView.label.seeding.rankType.tooltip=Torrenty s nejvy\u0161\u0161\u00edm hodnocen\u00edm jsou spu\u0161t\u011bny automaticky.\nKdy\u017e jin\u00fd torrent z\u00edsk\u00e1 vy\u0161\u0161\u00ed hodnocen\u00ed, ten s ni\u017e\u0161\u00edm bude zastaven a je za\u0159azen zp\u00e1tky do fronty.\n\nPouze torrenty ve stavu Ve Front\u011b jsou dostupn\u00e9 pro automatick\u00e9 spu\u0161t\u011bn\u00ed.\nZastaven\u00e9 torrenty nejsou nikdy automaticky spu\u0161t\u011bny.
+ConfigView.label.seeding.rankType=Hodnotit dokon\u010den\u00e9 torrenty pro automatick\u00e9 spou\u0161t\u011bn\u00ed podle:
+ConfigView.label.stopAfterMinutes=Jakmile p\u0159epnuto na distribuci, zastavit po ur\u010dit\u00e9 dob\u011b
+ConfigView.label.switchpriority.tooltip=N\u00edzk\u00e1 priorita sni\u017euje mno\u017estv\u00ed \u0161\u00ed\u0159ky p\u00e1sma odesl\u00e1n\u00ed p\u0159id\u011blen\u00e9 torrentu.
+ConfigView.pluginlist.info=N\u00e1sleduj\u00edc\u00ed z\u00e1suvn\u00e9 moduly byly rozpozn\u00e1ny. N\u011bkter\u00e9 z\u00e1suvn\u00e9 moduly nemus\u00ed m\u00edt karty nastaven\u00ed.
+ConfigView.pluginlist.noplugins=Nebyly nalezeny \u017e\u00e1dn\u00e9 z\u00e1suvn\u00e9 moduly.
 ConfigView.section.pluginslist=Seznam
 ConfigView.section.queue.seeding=Distribuce
 ConfigView.section.queue.seeding.autoStarting=Automatick\u00e9 spou\u0161t\u011bn\u00ed
 ConfigView.section.queue.seeding.ignore=Pravidla ignorov\u00e1n\u00ed
-ConfigView.section.queue.seeding.firstPriority=Top priorita
+ConfigView.section.queue.seeding.firstPriority=Prvn\u00ed priorita
 ConfigView.section.queue.main=Hlavn\u00ed
 ConfigView.section.queue=Fronta
 ConfigView.section.torrents=Torrenty
 ConfigView.text.all=v\u0161emi
 ConfigView.text.hours=hodin
-ConfigView.text.ignoreRule=Ignorovat pravidlo
+ConfigView.text.ignoreRule=Pravidlo Ignorov\u00e1n\u00ed
 ConfigView.text.ignore=Ignorovat
 ConfigView.text.minutes=minut
-ConfigView.text.neverIgnore=Nikdy neignorovat
+ConfigView.text.neverIgnore=Nikdy Neignorovat
 ConfigView.text.any=jak\u00fdmkoliv
 DownloadManager.error.datamissing=Chyb\u011bj\u00edc\u00ed data
-MainWindow.menu.file.open.torrentforseeding=.torrent soubor (pro distribuci)
+MainWindow.menu.file.open.torrentforseeding=Soubor torrent...(Pro Distribuci)
 MainWindow.menu.language.refresh=&Obnovit
 ManagerItem.forced=Vynucen\u00e9
 ManagerItem.queued=Ve front\u011b
-MySeedersView.header=Dokon\u010den\u00e9/Distribuovan\u00e9 Torrenty
-TableColumn.header.availability.info=Po\u010det dostupn\u00fdch kopi\u00ed
+MySeedersView.header=Dokon\u010den\u00e9 Torrenty
+TableColumn.header.availability.info=Po\u010det vid\u011bn\u00fdch dostupn\u00fdch kopi\u00ed
 TableColumn.header.availability=Dostupnost
 TableColumn.header.category=Kategorie
-MyTorrentsView.header=Nedokon\u010den\u00e9/stahovan\u00e9 torrenty
-TableColumn.header.maxuploads=Maximum upload\u016f
-MyTorrentsView.menu.category.delete=O&debrat kategorii
+MyTorrentsView.header=Nedokon\u010den\u00e9 Torrenty
+TableColumn.header.maxuploads=Max Po\u010det Odes\u00edl\u00e1n\u00ed
+MyTorrentsView.menu.category.delete=&Smazat Kategorii
 MyTorrentsView.menu.forceStart=&Vynutit spu\u0161t\u011bn\u00ed
 MyTorrentsView.menu.queue=Za\u0159adit do &fronty
-MyTorrentsView.menu.setCategory.add=&P\u0159idat kategorii..
-MyTorrentsView.menu.setCategory=Nastavit Kategorii
-TableColumn.header.savepath=C\u00edlov\u00e1 slo\u017eka
-TableColumn.header.totalspeed.info=Celkov\u00e1 rychlost klient\u016f, ke kter\u00fdm jste p\u0159ipojeni
+MyTorrentsView.menu.setCategory.add=&P\u0159idat Kategorii..
+MyTorrentsView.menu.setCategory=P\u0159id\u011blit Kategorii
+TableColumn.header.savepath=Cesta Ulo\u017een\u00ed
+TableColumn.header.SeedingRank=Hodnocen\u00ed Distribuce
+TableColumn.header.totalspeed.info=Celkov\u00e1 rychlost v\u0161ech klient\u016f, ke kter\u00fdm jste p\u0159ipojeni
 TableColumn.header.totalspeed=Celkov\u00e1 rychlost
-splash.initializePlugins=Inicializace Dopl\u0148k\u016f
-StartStopRules.SPratioMet=S:P Pom\u011br OK
-StartStopRules.FP0Peers=FP / 0 Stahujic\u00edch
-StartStopRules.0Peers=0 stahuj\u00edc\u00edch
+splash.initializePlugins=Zav\u00e1d\u00edm Z\u00e1suvn\u00e9 Moduly
+StartStopRules.SPratioMet=Pom\u011br D:K OK
+StartStopRules.FP0Peers=1. P / 0 Stahuj\u00edc\u00edch
+StartStopRules.0Peers=0 Klient\u016f
 StartStopRules.numSeedsMet=Po\u010det distributor\u016f v po\u0159\u00e1dku
 StartStopRules.ratioMet=Pom\u011br klienti:distrubuto\u0159i v po\u0159\u00e1dku
 StartStopRules.shareRatioMet=Pom\u011br sd\u00edlen\u00ed OK
-StartStopRules.waiting=\u010cek\u00e1n\u00ed
-StartStopRules.firstPriority=Top Priorita
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Nasd\u00edl\u00ed obsah slo\u017eky (Rekurzivn\u011b)
-DownloadManager.error.unabletostartserver=Server nelze spustit - zkontrolujte nastaven\u00ed p\u0159\u00edchoz\u00edho portu / nastaven\u00ed firewallu, aby umo\u017enil aplikaci b\u00fdt serverem
+StartStopRules.waiting=\u010cek\u00e1m
+StartStopRules.firstPriority=1. Priorita
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Klasick\u00e9 Sd\u00edlen\u00ed Obsahu (Rekurzivn\u011b)
+DownloadManager.error.unabletostartserver=Server nelze spustit - zkontrolujte nastaven\u00ed p\u0159\u00edchoz\u00edho portu / opr\u00e1vn\u011bn\u00ed firewallu, aby umo\u017enil aplikaci se chovat jako server
 GeneralView.label.creationdate=Vytvo\u0159eno :
-ConfigView.section.tracker.announcescrapepercentage=Interval mezi Scrapy jako st\u00e1\u0159\u00ed ozn\u00e1men\u00ed\nnap\u0159. 200 = 2:1. 0 = a\u0165 rozhodne klient
-ManagerItem.stopping=Zastavov\u00e1n\u00ed
-ConfigView.section.tracker.announcecacheperiod=Ozn\u00e1mit vyrovn\u00e1vac\u00ed pam\u011bt (ms)
+ConfigView.section.tracker.announcescrapepercentage=Interval Scrapu jako %age ozn\u00e1men\u00ed\nnap\u0159. 200 = 2:1. 0 = a\u0165 rozhodne klient
+ManagerItem.stopping=Zastavuji
+ConfigView.section.tracker.announcecacheperiod=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 ozn\u00e1men\u00ed (ms)
 ConfigView.section.tracker.scrapecacheperiod=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 scrape (ms)
-ConfigView.section.tracker.scrapeandcache=Scrape a vyrovn\u00e1vac\u00ed pam\u011bt
-ConfigView.section.tracker.announcecacheminpeers=Povolit ozn\u00e1men\u00ed p\u0159ekro\u010den\u00ed velikosti vyrovn\u00e1vac\u00ed pam\u011bti
+ConfigView.section.tracker.scrapeandcache=Scrape a vyrovn\u00e1vac\u00ed pam\u011b\u0165
+ConfigView.section.tracker.announcecacheminpeers=Hranice klient\u016f povolen\u00e1 ve vyrovn\u00e1vac\u00ed pam\u011bti ozn\u00e1men\u00ed
 MyTrackerView.scrapes=Scrapy
 fileDownloadWindow.retry=Znovu
-MyTrackerView.bytesin=Do (Byty)
-MyTrackerView.bytesinave=Do (pr\u016fm\u011br)
-MyTrackerView.bytesout=Ven (Byty)
-MyTrackerView.bytesoutave=Ven (pr\u016fm\u011br)
+MyTrackerView.bytesin=Bajty Do
+MyTrackerView.bytesinave=Do Pr\u016fm\u011br
+MyTrackerView.bytesout=Bajty Ven
+MyTrackerView.bytesoutave=Ven Pr\u016fm\u011br
 ConfigView.section.file.max_open_files=Maximum otev\u0159en\u00fdch soubor\u016f pro \u010dten\u00ed/z\u00e1pis\n[0: neomezen\u011b]
-ConfigView.section.file.max_open_files.tooltip=Pou\u017eijte v p\u0159\u00edpad\u011b, \u017ee stahujete torrenty se stovkami/tis\u00edci soubory a dosahujete limit OS pro po\u010det otev\u0159en\u00fdch soubor\u016f.
+ConfigView.section.file.max_open_files.tooltip=U\u017eite\u010dn\u00e9, pokud stahujete torrenty se stovkami/tis\u00edci soubor\u016f uvnit\u0159 a dosahujete limitu po\u010dtu obslu\u017en\u00fdch rutin soubor\u016f OS.
 ConfigView.section.proxy=Mo\u017enosti proxy
-ConfigView.section.proxy.enable_proxy=Pou\u017e\u00edt proxy server (je t\u0159eba restartovat Vuze
-ConfigView.section.proxy.host=Server
+ConfigView.section.proxy.enable_proxy=Povolit komunikace trackeru p\u0159es proxy [vy\u017eadov\u00e1n restart]
+ConfigView.section.proxy.host=Hostitel
 ConfigView.section.proxy.username=U\u017eivatelsk\u00e9 jm\u00e9no
 ConfigView.section.proxy.password=Heslo
-ConfigView.section.proxy.enable_socks=M\u00e1m SOCKS proxy server
-wizard.createtorrent.extrahashes=P\u0159idat hash hodnoty pro ostatn\u00ed s\u00edt\u011b (nap\u0159.: Gnutella2, eDonkey2000)
+ConfigView.section.proxy.enable_socks=M\u00e1m SOCKS proxy
+wizard.createtorrent.extrahashes=P\u0159idat hash pro ostatn\u00ed s\u00edt\u011b (nap\u0159.: Gnutella2, eDonkey2000)
 GeneralView.label.connected=p\u0159ipojeno
 GeneralView.label.in_swarm=celkem
-ManagerItem.initializing=Inicializace
+ManagerItem.initializing=Spou\u0161t\u00edm
 AlertMessageBox.error=Chyba
 AlertMessageBox.warning=Varov\u00e1n\u00ed
-AlertMessageBox.comment=Informace
+AlertMessageBox.comment=Koment\u00e1\u0159
 AlertMessageBox.information=Informace
-SharedPortServer.alert.selectorfailed=Nepoda\u0159ilo se otev\u0159\u00edt port pro p\u0159ichoz\u00ed data.\nZkontrolujte nastaven\u00ed firewallu, zda umo\u017enuje java(w).exe jednat jako 'server'
-Tracker.alert.listenfail=Nepoda\u0159\u00edlo se naslouchat na portu %1.\nZkontrolujte, jestli ostatn\u00ed aplikace nepou\u017e\u00edvaj\u00ed tento port.\nT\u00e9\u017e zkontrolujte, jestli u\u017e jeden Vuze neb\u011b\u017e\u00ed.
-DiskManager.alert.movefileexists=Chyba p\u0159i p\u0159esunu dokon\u010den\u00fdch soubor\u016f\nSoubor %1 v c\u00edlov\u00e9 slo\u017ece ji\u017e existuje
+AlertMessageBox.unread=M\u00e1te nep\u0159e\u010dten\u00e9 varovn\u00e9 zpr\u00e1vy - klikn\u011bte zde pro jejich zobrazen\u00ed.
+SharedPortServer.alert.selectorfailed=Nepoda\u0159ilo se zajistit poslucha\u010de pro p\u0159\u00edchoz\u00ed data.\nZkontrolujte, jestli nastaven\u00ed firewallu dovoluj\u00ed java(w).exe se chovat jako 'server'
+Tracker.alert.listenfail=Nelze vytvo\u0159it naslouch\u00e1n\u00ed na portu %1.\nZkontrolujte, jestli ostatn\u00ed aplikace tenot port ji\u017e nevyu\u017e\u00edvaj\u00ed.\nTak\u00e9 zkontrolujte, jestli neb\u011b\u017e\u00ed jin\u00e1 kopie Vuze.
+DiskManager.alert.movefileexists=Chyba p\u0159i p\u0159esunu dokon\u010den\u00fdch soubor\u016f\nSoubor %1 v c\u00edlov\u00e9m adres\u00e1\u0159i ji\u017e existuje
 DiskManager.alert.movefilefails=Chyba p\u0159i p\u0159esunu dokon\u010den\u00fdch soubor\u016f\nP\u0159esun souboru %1 se nezda\u0159il, %2
 DiskManager.alert.movefilerecoveryfails=Chyba p\u0159i obnov\u011b z nepoveden\u00e9ho p\u0159esunu\nObnova souboru %1 se nezda\u0159ila, %2
-ConfigView.section.tracker.logenable=Pravideln\u011b zapisovat statistiku do 'tracker.log'
-SpeedView.stats.title=Statistika
+ConfigView.section.tracker.logenable=Zaznamen\u00e1vat pravidelnou statistiku do 'tracker.log'
+SpeedView.stats.title=Statistiky
 SpeedView.stats.total=Celkem
-SpeedView.stats.session=Toto spu\u0161t\u011bn\u00ed
-SpeedView.stats.session.tooltip=Celkov\u00fd  (protocol)
-SpeedView.stats.downloaded=P\u0159ijato
-SpeedView.stats.uploaded=Odesl\u00e1no
+SpeedView.stats.session=Tuto Relaci
+SpeedView.stats.session.tooltip=Celkov\u00e1 (Protokol)
+SpeedView.stats.downloaded=St\u00e1hnuto (Protokol)
+SpeedView.stats.uploaded=Odesl\u00e1no (Protokol)
 SpeedView.stats.ratio=Pom\u011br
-SpeedView.stats.uptime=Spu\u0161t\u011bno (hod)
+SpeedView.stats.uptime=Doba Provozu
 SpeedView.stats.now=Nyn\u00ed
-SpeedView.stats.now.tooltip=Celkov\u00fd (protokol)
-AutoMigration.useralert=V\u00fdsledky automatick\u00e9 migrace konfigura\u010dn\u00edch soubor\u016f:\n\n%1\n%2NEP\u0158ESUNUT\u00c9 SOUBORY MUS\u00cd P\u0158ESUNUTY RU\u010cN\u011a.
+SpeedView.stats.now.tooltip=Celkov\u00e1 (Protokol)
+AutoMigration.useralert=V\u00fdsledky automatick\u00e9ho p\u0159esunu konfigura\u010dn\u00edch soubor\u016f/adres\u00e1\u0159\u016f:\n\n%1\nJak\u00e1koli selh\u00e1n\u00ed mus\u00ed b\u00fdt p\u0159esunuta ru\u010dn\u011b.\nNEZAPOME\u0147TE AKTUALIZOVAT VA\u0160E CESTY PRO ULO\u017dEN\u00cd V KONFIGURACI, POKUD BYLY P\u0158ESUNUTY!
 #
 # > 2.0.8.0
 #
 OpenTorrentWindow.title=Otev\u0159\u00edt Torrent(y)
 OpenTorrentWindow.message=Experiment\u00e1ln\u00ed
-OpenTorrentWindow.addFiles=&P\u0159idat soubory
+OpenTorrentWindow.addFiles=&P\u0159idat Soubory
 OpenTorrentWindow.dataLocation=Um\u00edst\u011bn\u00ed pro ulo\u017een\u00ed dat:
-OpenTorrentWindow.startMode=Stav
+OpenTorrentWindow.startMode=Re\u017eim P\u0159id\u00e1n\u00ed
 OpenTorrentWindow.startMode.queued=Za\u0159adit do fronty
 OpenTorrentWindow.startMode.stopped=Zastaven\u00e9
 OpenTorrentWindow.startMode.forceStarted=Vynucen\u00e9 spu\u0161t\u011bn\u00ed
-OpenTorrentWindow.addPosition=P\u0159idat do fronty
-OpenTorrentWindow.addPosition.first=Na za\u010d\u00e1tek
-OpenTorrentWindow.addPosition.last=Na konec
-TableColumn.header.remaining.info=Objem dat zb\u00fdvaj\u00edc\u00ed ke st\u00e1\u017een\u00ed
+OpenTorrentWindow.addPosition=Pozice Ve Front\u011b
+OpenTorrentWindow.addPosition.first=Prvn\u00ed
+OpenTorrentWindow.addPosition.last=Posledn\u00ed
+TableColumn.header.remaining.info=Mno\u017estv\u00ed zb\u00fdvaj\u00edc\u00ed ke sta\u017een\u00ed
 TableColumn.header.remaining=Zb\u00fdv\u00e1
-ConfigView.section.tracker.enablecompact=Pou\u017e\u00edvat kompaktn\u00ed oznamovac\u00ed protokol
-ConfigView.section.tracker.enablekey=Pro v\u011bt\u0161\u00ed bezpe\u010dnost pos\u00edlat trackeru kl\u00ed\u010d
+ConfigView.section.tracker.enablecompact=Pou\u017e\u00edvat celistv\u00fd oznamovac\u00ed protokol
+ConfigView.section.tracker.enablekey=Povolit p\u0159ed\u00e1v\u00e1n\u00ed kl\u00ed\u010de trackeru pro lep\u0161\u00ed bezpe\u010dnost
 ConfigView.section.file.perf=Nastaven\u00ed v\u00fdkonu
-ConfigView.section.file.perf.explain=Varov\u00e1n\u00ed - neodborn\u00e9 zm\u011bny t\u011bchto parametr\u016f m\u016f\u017eou v\u00e1\u017ene ovlivnit v\u00fdkon stahov\u00e1n\u00ed. Po zm\u011bn\u011b je t\u0159eba program restartovat.\nPokud m\u00e1te probl\u00e9my s nedostatkem pam\u011bti, zkuste omezit po\u010det p\u0159ipojen\u00ed na torrent (v\u00edce v Nastaven\u00ed->P\u0159enos)
-ConfigView.section.file.max_open_files.explain=Otev\u0159en\u00ed p\u0159\u00edli\u0161 mnoha soubor\u016f m\u016f\u017ee zp\u016fsobit probl\u00e9my opera\u010dn\u00edmu syst\u00e9mu kv\u016fli nedostatku zdroj\u016f. Toto omez\u00ed  po\u010det najednou otev\u0159en\u00fdch soubor\u016f.
+ConfigView.section.file.perf.explain=Varov\u00e1n\u00ed - neodborn\u00e9 zm\u011bny t\u011bchto parametr\u016f m\u016f\u017eou v\u00e1\u017en\u011b ovlivnit v\u00fdkon stahov\u00e1n\u00ed. Restart je vy\u017eadov\u00e1n.\nPokud m\u00e1te probl\u00e9my "nedostatek pam\u011bti", zkuste omezit po\u010det p\u0159ipojen\u00ed na torrent (Pod\u00edvejte se na Nastaven\u00ed P\u0159enosu)
+ConfigView.section.file.max_open_files.explain=Otev\u0159en\u00edm p\u0159\u00edli\u0161 mnoha soubor\u016f m\u016f\u017ee zp\u016fsobit probl\u00e9my opera\u010dn\u00edho syst\u00e9mu kv\u016fli nedostatku zdroj\u016f jako obslu\u017en\u00e9 rutiny soubor\u016f. Toto omez\u00ed po\u010det najednou otev\u0159en\u00fdch soubor\u016f.
 popup.error.hide=Skr\u00fdt
-popup.error.details=Detaily
-ConfigView.section.style.colorOverrides=Zm\u011bna barev
-ConfigView.section.style.colorOverride.progressBar=Diagram postupu
+popup.error.details=Podrobnosti
+ConfigView.section.style.colorOverrides=Potla\u010den\u00ed Barev
+ConfigView.section.style.colorOverride.progressBar=Li\u0161ta Postupu
 ConfigView.section.style.colorOverride.error=Chyba
 MainWindow.status.tooOld=je moc zastaral\u00fd, pros\u00edme aktualizujte jej.
 ConfigView.section.style.colorOverride.warning=Varov\u00e1n\u00ed
 ConfigView.section.style.colorOverride.altRow=Lich\u00e9 \u0159\u00e1dky
-ConfigView.section.file.save.peers.enable=Ukl\u00e1dat adresy p\u0159ipojen\u00fdch klient\u016f pro rychlej\u0161\u00ed spou\u0161t\u011bn\u00ed
+ConfigView.section.file.save.peers.enable=Ukl\u00e1dat adresy p\u0159ipojen\u00fdch klient\u016f pro rychlej\u0161\u00ed znovu spojen\u00ed
 ConfigView.section.file.save.peers.max=Maximum ulo\u017een\u00fdch klient\u016f [0: neomezen\u011b]
 ConfigView.section.file.save.peers.pertorrent=na torrent
-ConfigView.label.max_peers_per_torrent=Maximum p\u0159ipojen\u00ed na torrent [0: neomezen\u011b]
-ConfigView.label.max_peers_total=Celkov\u00e9 max.p\u0159ipojen\u00ed [0: neomezen\u011b]
-ConfigView.section.style.colorOverrides.reset=P\u016fvodn\u00ed barva
-ConfigView.section.language.info=Pokud je aktualizace povolena,kontrola nov\u00fdch dostupn\u00fdch verz\u00ed bude provedena p\u0159i ka\u017ed\u00e9m spu\u0161t\u011bn\u00ed Azurea.
+ConfigView.label.max_peers_per_torrent=Max v\u00fdchoz\u00edch p\u0159ipojen\u00ed na torrent [0: neomezen\u011b]
+ConfigView.label.max_peers_total=Max p\u0159ipojen\u00ed celkov\u011b [0: neomezen\u011b]
+ConfigView.section.style.colorOverrides.reset=Resetovat Barvu
+ConfigView.section.language.info=Pokud je zapnuto, kontrola aktualizace bude provedena poka\u017ed\u00e9, kdy\u017e je Vuze spu\u0161t\u011bn.
 ConfigView.section.language.enableUpdate=Povolit aktualizace z internetu
-ConfigView.section.language.UpdateURL=URL s aktualizac\u00ed
-ConfigView.section.language.UpdateNow=Aktualizovat!
+ConfigView.section.language.UpdateURL=Aktualiza\u010dn\u00ed URL
+ConfigView.section.language.UpdateNow=Aktualizovat Te\u010f!
 Button.revert=Vr\u00e1tit
-MyTorrentsView.menu.changeDirectory=Zm\u011bnit cestu k soubor\u016fm
+MyTorrentsView.menu.changeDirectory=Zm\u011bnit Datov\u00fd Adres\u00e1\u0159
 GenericText.column=sloupec
-MyTorrentsView.menu.thisColumn.remove=Odebrat sloupec
-MyTorrentsView.menu.thisColumn.toClipboard=Kop\u00edrovat text do schr\u00e1nky
-TableColumn.header.secondsseeding=Doba distribuce
-TableColumn.header.secondsseeding.info=Doba, po kterou torrent distribuujete
+MyTorrentsView.menu.thisColumn.remove=Odebrat Sloupec
+MyTorrentsView.menu.thisColumn.toClipboard=Kop\u00edrovat Text Do Schr\u00e1nky
+MyTorrentsView.menu.thisColumn.autoTooltip=V\u017edycky zobrazovat popisek
+ConfigView.download.abbreviated=S:
+ConfigView.upload.abbreviated=O:
+ConfigView.complete.abbreviated=D:
+TableColumn.header.secondsseeding=D\u00e9lka distribuce
+TableColumn.header.secondsseeding.info=Celkov\u00e9 mno\u017estv\u00ed \u010dasu, po kter\u00fd distribuujete.
 TableColumn.header.secondsdownloading=D\u00e9lka stahov\u00e1n\u00ed
-TableColumn.header.secondsdownloading.info=Doba, po kterou torrent stahujete
+TableColumn.header.secondsdownloading.info=Mno\u017estv\u00ed \u010dasu po kter\u00fd stahujete.
 ConfigView.section.tracker.udpversion=Verze UDP Protokolu (1 nebo 2)
-window.updateswt.title=Va\u0161e verze SWT knihovny je zastaral\u00e1!
-window.updateswt.text=Va\u0161e verze SWT knihovny je zastaral\u00e1!\nSWT je grafick\u00e1 knihovna pou\u017e\u00edvan\u00e1 programem Azureus. Tato knihovna je zastaral\u00e1 pro b\u011bh nejnov\u011bj\u0161\u00ed verze programu Azureus. Tla\u010d\u00edtkem OK aktualizujete Va\u0161\u00ed SWT knihovnu.
+window.updateswt.title=Va\u0161e Verze SWT je p\u0159\u00edli\u0161 star\u00e1!
+window.updateswt.text=Va\u0161e Verze SWT je p\u0159\u00edli\u0161 star\u00e1!\nSWT je grafick\u00e1 knihovna pou\u017e\u00edvan\u00e1 Vuze a verze, kterou m\u00e1te je p\u0159\u00edli\u0161 star\u00e1 pro b\u011bh nejnov\u011bj\u0161\u00ed verze Vuze. Klikn\u011bte na OK pro aktualizaci Va\u0161\u00ed SWT.
 window.updateswt.status=Stav
-window.updateswt.failed=Aktualizace selhala, stiskn\u011bte OK pro znovusta\u017een\u00ed.
-window.updateswt.status.downloading.updater=Stahov\u00e1n\u00ed Aktualiza\u010dn\u00edho modulu
-window.updateswt.status.finding=Hled\u00e1n\u00ed nejnov\u011bj\u0161\u00ed verze SWT
-window.updateswt.status.downloading=Stahov\u00e1n\u00ed nejnovej\u0161i verze SWT
+window.updateswt.failed=Aktualizace selhala, stiskn\u011bte znovu OK pro restartov\u00e1n\u00ed.
+window.updateswt.status.downloading.updater=Stahuji Aktualiza\u010dn\u00ed Modul
+window.updateswt.status.finding=Hled\u00e1n\u00ed nejnov\u011bj\u0161\u00ed Verze SWT
+window.updateswt.status.downloading=Stahuji Nejnov\u011bj\u0161\u00ed Verzi SWT
 window.updateswt.status.done=Restartuji
-window.updateswt.ok=OK !!
 window.updateswt.cancel=Zru\u0161it
-swt.updater.downloader.downloading=Stahov\u00e1n\u00ed SWT z
-swt.updater.urlsgetter.downloading=Stahuji seznam mirror\u016f z
+swt.updater.downloader.downloading=Stahuji SWT z
+swt.updater.urlsgetter.downloading=Z\u00edsk\u00e1v\u00e1m seznam mirror\u016f z
 swt.updater.urlsgetter.platform=SWT pro platformu :
 window.updateswt.ignore=Ignorovat
-ConfigView.section.style.useFancyTabs=Pou\u017e\u00edvat ozdobn\u00e9 z\u00e1lo\u017eky
-splash.initializeGM=Inicializace globaln\u00edho torrent mana\u017eeru
-splash.loadingTorrents=Na\u010d\u00edt\u00e1n\u00ed Torrent\u016f
+ConfigView.section.style.useFancyTabs=Pou\u017e\u00edvat Ozdobn\u00e9 Z\u00e1lo\u017eky
+splash.initializeGM=Zav\u00e1d\u00edm Glob\u00e1ln\u00edho Spr\u00e1vce Torrent\u016f
+splash.loadingTorrents=Na\u010d\u00edt\u00e1m Torrenty
 MyTorrentsView.menu.thisColumn.sort=&Se\u0159adit 
 Scrape.status.ok=Scrape OK.
-Scrape.status.error=Scrape: 
+Scrape.status.error=Chyba Scrape:
 Scrape.status.error.badURL=Oznamovac\u00ed URL neodpov\u00edd\u00e1 Scrape specifikaci.
-Scrape.status.error.nohash=V odpov\u011bd\u00ed chyb\u00ed hash hodnota.
+Scrape.status.error.nohash=V odpov\u011bd\u00ed chyb\u00ed hash.
 Scrape.status.error.invalid=Neplatn\u00e1 odpov\u011b\u010f.
 Scrape.status.nextScrapeAt=Dal\u0161\u00ed Scrape v %1
 Scrape.status.scraping=Scrapuji...
 Scrape.status.initializing=\u010cek\u00e1n\u00ed na Scrape
-ConfigView.label.minSpeedForActiveSeeding=Nepo\u010d\u00edtat vyu\u017eit\u00ed slotu, pokud je rychlost dokon\u010den\u00e9ho torrentu pod
-ConfigView.section.stats.exportpeers=Exportovat detaily o klientech
-MainWindow.menu.view.irc.moved=IRC klient je nyn\u00ed dostupn\u00fd jako plugin; nav\u0161tivte http://azureus.sourceforge.net/plugin_list.php. Po nainstalov\u00e1n\u00ed pou\u017eijte menu Zobrazit->Dopl\u0148ky->IRC.
-MyTrackerView.webui.contextmenu.copyurl=Kop\u00edrovat URL Torrentu do schr\u00e1nky
-ConfigView.section.file.torrent.ignorefiles=Ignorovan\u00e9 soubory p\u0159i vytv\u00e1\u0159en\u00ed torrent\u016f\nnap\u0159. .DS_Store;Thumbs.db
+Scrape.status.scraping.queued=Scrapov\u00e1n\u00ed ve front\u011b...
+ConfigView.label.minSpeedForActiveSeeding=Nepo\u010d\u00edtat dokon\u010den\u00fd torrent jako vyu\u017e\u00edvaj\u00edc\u00ed pozici, pokud je rychlost ni\u017e\u0161\u00ed ne\u017e
+ConfigView.section.stats.exportpeers=Exportovat podrobnosti klient\u016f
+MainWindow.menu.view.irc.moved=IRC je nyn\u00ed dostupn\u00e9 jako z\u00e1suvn\u00fd modul, nav\u0161tivte http://plugins.vuze.com/plugin_list.php. Po nainstalov\u00e1n\u00ed pro zobrazen\u00ed pou\u017eijte menu Zobrazit->Z\u00e1suvn\u00e9 Moduly->IRC.
+MyTrackerView.webui.contextmenu.copyurl=Kop\u00edrovat URL torrentu do schr\u00e1nky
+ConfigView.section.file.torrent.ignorefiles=Soubory, kter\u00e9 ignorovat p\u0159i vytv\u00e1\u0159en\u00ed/maz\u00e1n\u00ed torrent\u016f\n - nap\u0159. .DS_Store;Thumbs.db
 Torrent.create.progress.ignoringfile=Ignoruji soubor
-ConfigView.section.style.useUnitsRateBits=Pro rychlostn\u00ed p\u0159enosy pou\u017e\u00edvat bity misto byt\u016f (KiB/s->Kibit/s atd.)
-ConfigView.section.interface.resetassoc=Obnovit v\u00fdchoz\u00ed nastaven\u00ed asociace soubor\u016f (.torrent)
-ConfigView.section.interface.resetassocbutton=Obnovit
-ConfigView.section.interface.checkassoc=P\u0159i startu kontrolovat asociace soubor\u016f
+ConfigView.section.style.useUnitsRateBits=Pro hodnoty rychlosti na z\u00e1klad\u011b bajt\u016f pou\u017e\u00edt bity (KiB/s->Kibit/s atd.)
+ConfigView.section.interface.resetassoc=Resetovat asociace soubor\u016f pr\u016fzkumn\u00edka (.torrent) a obslu\u017en\u00e1 rutina magnet  (magnet:?xt=...)
+ConfigView.section.interface.resetassocbutton=Resetovat
+ConfigView.section.interface.checkassoc=P\u0159i startu kontrolovat asociace
 dialog.associations.title=Kontrola asociace soubor\u016f
-Button.yes=Ano
+Button.yes=&Ano
 Button.no=Ne
 ConfigView.label.seeding.autoStart0Peers=Automaticky spou\u0161t\u011bt v\u0161echny dokon\u010den\u00e9 torrenty s 0 klienty
-ConfigView.label.seeding.autoStart0Peers.tooltip=Zapnut\u00edm doc\u00edl\u00edte, aby Tracker st\u00e1le vypisoval seznam distributor\u016f pro torrenty s 0 klienty.
-dialog.associations.prompt=Vuze nen\u00ed v\u00fdchoz\u00ed aplikace pro BitTorrent soubory.\nP\u0159ejete si nastavit Vuze jako v\u00fdchoz\u00ed aplikaci pro .torrent soubory?
+ConfigView.label.seeding.autoStart0Peers.tooltip=Zapn\u011bte, pokud chcete, aby tracker v\u017edy zobrazoval zdroje pro torrenty s 0 klienty
+dialog.associations.prompt=Vuze nen\u00ed v\u00fdchoz\u00ed aplikace pro BitTorrent soubory.\nP\u0159ejete si asociovat soubory .torrent s Vuze?
 dialog.associations.askagain=Zkontrolovat p\u0159i startu
-ConfigView.section.plugins.update=Aktualizace dopl\u0148k\u016f
-Plugin.pluginupdate.enablecheck=Povolit kontrolu nov\u00fdch verz\u00ed dopl\u0148k\u016f
+ConfigView.section.plugins.update=Aktualizace Z\u00e1suvn\u00fdch Modul\u016f
+Plugin.pluginupdate.enablecheck=Povolit kontrolu nov\u00fdch verz\u00ed z\u00e1suvn\u00e9ho modulu
 plugins.basicview.status=Stav:
 plugins.basicview.activity=Aktivita:
 plugins.basicview.progress=Postup:
-plugins.basicview.log=Protokol:
-ConfigView.label.maxdownloadspeed=KB/s celkov\u00e9 max.rychlosti downloadu [0: neomezen\u011b]
-splash.loadingTorrent=Na\u010d\u00edt\u00e1n\u00ed Torrentu
+plugins.basicview.log=Z\u00e1znam:
+ConfigView.label.maxdownloadspeed=Celkov\u00e1 max rychlost stahov\u00e1n\u00ed v KB/s [0: neomezen\u011b]
+splash.loadingTorrent=Na\u010d\u00edt\u00e1m Torrent
 splash.of=z
-UpdateWindow.title=Aktualizace programu Vuze
-UpdateWindow.header=Je t\u0159eba aktualizovat n\u00e1sleduj\u00edc\u00ed komponenty :
+UpdateWindow.title=Aktualizace Vuze
+UpdateWindow.header=N\u00e1sleduj\u00edc\u00ed sou\u010d\u00e1sti pot\u0159ebuj\u00ed aktualizovat:
 UpdateWindow.columns.install=Instalovat
 UpdateWindow.columns.name=N\u00e1zev
 UpdateWindow.columns.version=Verze
@@ -1020,147 +1041,147 @@ UpdateWindow.cancel=Storno
 UpdateWindow.quit=Konec
 UpdateWindow.close=Zav\u0159\u00edt
 UpdateWindow.ok=Aktualizovat
-UpdateWindow.restart=Restartovat
+UpdateWindow.restart=Restartovat Vuze Te\u010f
 UpdateWindow.status.downloading=Stahov\u00e1n\u00ed
 UpdateWindow.status.done=Hotovo
 UpdateWindow.status.failed=Chyba
-UpdateWindow.status.restartNeeded=Bude t\u0159eba restartovat Vuze
+UpdateWindow.status.restartNeeded=Restart bude vy\u017eadov\u00e1n!
 ConfigView.pluginlist.broken=Nefunk\u010dn\u00ed
-ConfigView.pluginlist.whereToPut=U\u017eivatelsk\u00e9 dopl\u0148ky um\u00edst\u011bte do slo\u017eky (ka\u017ed\u00fd do zvl\u00e1\u0161tn\u00ed podslo\u017eky):
-ConfigView.pluginlist.whereToPutOr=Pro sd\u00edlen\u00e9 dopl\u0148ky pou\u017eijte slo\u017eku:
-MainWindow.statusText.checking=Kontrola aktualizac\u00ed
+ConfigView.pluginlist.whereToPut=Umist\u011bte jak\u00fdkoli u\u017eivatelsk\u00fd z\u00e1suvn\u00fd modul do vlastn\u00edho adres\u00e1\u0159e pod:
+ConfigView.pluginlist.whereToPutOr=Pro sd\u00edlen\u00e9 z\u00e1suvn\u00e9 moduly pou\u017eijte:
+MainWindow.statusText.checking=Kontroluji Aktualizace
 TableColumn.header.OnlyCDing4=Pouze distribuov\u00e1no po
-TableColumn.header.OnlyCDing4.info=Mno\u017estv\u00ed \u010dasu, po kter\u00e9 byl torrent distribuov\u00e1n. Nezapo\u010d\u00edt\u00e1n \u010das, po kter\u00fd se torrent z\u00e1rove\u0148 stahoval i odes\u00edlal.
-ConfigView.section.style.alternateTablePainting=Pou\u017e\u00edt alternativn\u00ed metodu pro barevnost grafiky tabulek a sloupc\u016f (m\u016f\u017ee vy\u017eadovat restartovat)
-UpdateWindow.status.restartMaybeNeeded=Je nutn\u00e9 restartovat
-ConfigView.pluginlist.shared=Sd\u00edlet
+TableColumn.header.OnlyCDing4.info=Mno\u017estv\u00ed \u010dasu, po kter\u00e9 byl torrent pouze distribuov\u00e1n. Nezapo\u010d\u00edt\u00e1n \u010das, po kter\u00fd byl torrent stahov\u00e1n (a distribuov\u00e1n).
+UpdateWindow.status.restartMaybeNeeded=Restart m\u016f\u017ee b\u00fdt vy\u017eadov\u00e1n
+ConfigView.pluginlist.shared=sd\u00edlen\u00e9
 PeersView.host=N\u00e1zev hostitele
-PeersView.host.info=Jm\u00e9no hostitela the peer, ke k dispozici (m\u016f\u017ee ovlivnit v\u00fdkon)
+PeersView.host.info=Jm\u00e9no hostitele klienta, kde je dispozici (m\u016f\u017ee ovlivnit v\u00fdkon)
 MainWindow.menu.help.whatsnew=Co je nov\u00e9ho
-ConfigView.label.checkonstart=Za\u010d\u00edn\u00e1 kontrola posledn\u00ed verze Azurea.
+ConfigView.label.checkonstart=Zkontrolovat posledn\u00ed verze, p\u0159i spu\u0161t\u011bn\u00ed Vuze.
 ConfigView.label.periodiccheck=Pravideln\u00e1 kontrola posledn\u00ed verze
-ConfigView.label.opendialog=Pokud je dostupn\u00e1 aktualizace otev\u0159i aktualiza\u010dn\u00edho asistenta
-MainWindow.updateavail=Klikni zde pro updates
+ConfigView.label.opendialog=Automaticky otev\u0159\u00edt Aktualiza\u010dn\u00edho Asistenta, kdy\u017e je dostupn\u00e1 aktualizace
+MainWindow.updateavail=Klikn\u011bte zde pro aktualizace
 MainWindow.status.latestversionunchecked=Kontrola verze je zak\u00e1z\u00e1na
-GeneralView.label.updatein.stopped=Zastavit
-StartStopRules.menu.viewDebug=Zobrazit lad\u00edc\u00ed informace
+GeneralView.label.updatein.stopped=Zastaveno
+StartStopRules.menu.viewDebug=Zobrazit Informace O Lad\u011bn\u00ed
 ConfigView.section.style.doNotUseGB=Nepou\u017e\u00edvat jednotku GB
 ConfigView.section.style.doNotUseGB.tooltip=Pokud je za\u0161krtnuto, Vuze bude pokra\u010dovat v pou\u017e\u00edv\u00e1n\u00ed jednotek MB i pro velikosti p\u0159esahuj\u00edc\u00ed 1024MB (1GB)
-MainWindow.menu.help.plugins=Z\u00edskat pluginy
-ConfigView.section.plugins.TrackerWeb=Webov\u00fd server
+MainWindow.menu.help.plugins=Z\u00edskat Z\u00e1suvn\u00e9 Moduly
+ConfigView.section.plugins.TrackerWeb=Webov\u00fd Tracker
 ConfigView.section.tracker.enablecategories=Rozd\u011blit torrenty podle kategorie
-health.explain.share=znamen\u00e1, \u017ee torrent je bu\u010f hostitel nebo publikov\u00e1n\u00fd
-ConfigView.section.tracker.createcert=Vytvo\u0159it podepsan\u00fd certifik\u00e1t
+health.explain.share=znamen\u00e1, \u017ee torrent je bu\u010f hostitel nebo publikovan\u00fd
+ConfigView.section.tracker.createcert=Vytvo\u0159it certifik\u00e1t podepsan\u00fd s\u00e1m sebou
 ConfigView.section.tracker.createbutton=Vytvo\u0159it
-security.certcreate.title=Vytvo\u0159it vlastn\u00ed podepsan\u00fd certifik\u00e1t
-security.certcreate.intro=Tento dialog  V\u00e1m pom\u016f\u017ee vytvo\u0159it podepsan\u00fd certifik\u00e1t
+security.certcreate.title=Vytvo\u0159it Certifik\u00e1t Podepsan\u00fd S\u00e1m Sebou
+security.certcreate.intro=Toto dialogov\u00e9 okno V\u00e1m umo\u017e\u0148uje vytvo\u0159it certifik\u00e1t podepsan\u00fd s\u00e1m sebou
+security.certcreate.alias=P\u0159ezd\u00edvka
 security.certcreate.strength=S\u00edla
 security.certcreate.firstlastname=Jm\u00e9no a p\u0159\u00edjmen\u00ed
 security.certcreate.orgunit=Organiza\u010dn\u00ed jednotka
 security.certcreate.org=Organizace
 security.certcreate.city=M\u011bsto nebo m\u00edsto
 security.certcreate.state=St\u00e1t nebo provincie
-security.certcreate.country=Dvojp\u00edsmenn\u00fd k\u00f3d zem\u011b (nap\u0159 CZ)
+security.certcreate.country=Dvojp\u00edsmenn\u00fd k\u00f3d zem\u011b
 security.certcreate.ok=Vytvo\u0159it
 security.certcreate.cancel=Zru\u0161it
-security.certcreate.createok=\u00dasp\u011b\u0161n\u00e9 vytvo\u0159en\u00ed certifik\u00e1tu
-security.certcreate.createfail=Chyba vytvo\u0159en\u00e9ho certifik\u00e1tu
+security.certcreate.createok=Certifik\u00e1t byl \u00fasp\u011b\u0161n\u011b vytvo\u0159en
+security.certcreate.createfail=Vytvo\u0159en\u00ed certifik\u00e1tu selhalo
 ConfigView.section.plugins.webui=Swing Web rozhran\u00ed
 ConfigView.section.plugins.xml_http_if=XML/HTTP rozhran\u00ed
 webui.passwordenable=Povolit Heslo
 webui.user=U\u017eivatelsk\u00e9 jm\u00e9no
 webui.password=Heslo
-webui.protocol=Protokol (*)
-webui.homepage=Dom\u00e1c\u00ed str\u00e1nka (*)
-webui.rootdir=Ko\u0159enov\u00fd adres\u00e1\u0159 (*)
-webui.rootres=Ko\u0159enov\u00e9 zdroje (*)
-webui.mode=M\u00f3d (*)
-webui.mode.info=M\u00f3d m\u00fa\u017ee b\u00fdt\t"full"\t= v\u0161echny dosa\u017eiteln\u00e9 operace (standartn\u011bt)\n\t"zobrazit"\t= zobrazit jen p\u0159i aktualizaci  (nebo obnoven\u00ed frekvence)
-webui.access=P\u0159\u00edstup (*)
-webui.access.info=P\u0159\u00edstup m\u00fa\u017ee b\u00fdt\n\t"m\u00edstn\u00ed"\t= v\u00fdznam jen u m\u00edstn\u00edho stroje p\u0159i p\u0159ipojen\u00ed\n\t"v\u0161e"\t= voln\u00fd p\u0159\u00edstup (standartn\u00ed)\n\tIP\t= e.g. 192.168.0.2\t\t\tone IP pouze\n\tIP1-IP2\t= e.g. 192.168.0.1-192.168.0.255\texlusivn\u00ed rozsah  IPs
+webui.protocol=Protokol
+webui.homepage=Dom\u00e1c\u00ed str\u00e1nka
+webui.rootdir=Ko\u0159enov\u00fd adres\u00e1\u0159
+webui.rootres=Ko\u0159enov\u00fd zdroj
+webui.mode=Re\u017eim
+webui.mode.info=Re\u017eim m\u016f\u017ee b\u00fdt\n\t"full"\t= v\u0161echny operace jsou dostupn\u00e9 (v\u00fdchoz\u00ed)\n\t"view"\t= pouze zobrazen\u00ed (ale m\u016f\u017ee aktualizovat frekvenci obnoven\u00ed)
+webui.access=P\u0159\u00edstup
+webui.access.info=P\u0159\u00edstup m\u016f\u017ee b\u00fdt\n\t"local"\t= znamen\u00e1, \u017ee pouze m\u00edstn\u00ed stroj se m\u016f\u017ee p\u0159ipojit\n\t"all"\t= neomezen\u00fd p\u0159\u00edstup (v\u00fdchoz\u00ed)\n\tIP\t= nap\u0159. 192.168.0.2\t\t\tpouze jedna IP\n\tIP1-IP2\t= nap\u0159. 192.168.0.1-192.168.0.255\tuzav\u0159en\u00fd rozsah IP
 GeneralView.label.maxdownloadspeed=Max odes.
-Security.keystore.corrupt=Keystore '%1' selhalo na\u010dten\u00ed, pros\u00edm sma\u017ete to a obnovte/re-importujte certifik\u00e1t
-Security.keystore.empty=Keystore je pr\u00e1zdn\u00e9. Pros\u00edm vytvo\u0159te podepsan\u00fd certifik\u00e1t (pod\u00edvej se N\u00e1stroje ->Mo\u017enosti->Bezpe\u010dnost) nebo importuj existuj\u00edc\u00ed certifik\u00e1t  '%1'
-webui.restart.info=Zm\u011bnit ozna\u010den\u00e9 parametry  (*) efekty se projev\u00ed po\u017eaduje restartovat 
-GeneralView.label.maxdownloadspeed.tooltip=Max rychlost stahov\u00e1n\u00ed [0: bneomezen\u011b]
+Security.keystore.corrupt=Sklad kl\u00ed\u010d\u016f '%1' nelze na\u010d\u00edst, pros\u00edm sma\u017ete ho a znovu ho vytvo\u0159te/importujte certifik\u00e1ty
+Security.keystore.empty=Sklad kl\u00ed\u010d\u016f je pr\u00e1zdn\u00fd. Pros\u00edm vytvo\u0159te certifik\u00e1t podepsan\u00fd s\u00e1m sebou (Pod\u00edvejte se na N\u00e1stroje->Nastaven\u00ed->Zabezpe\u010den\u00ed) nebo importujte existuj\u00edc\u00ed certifik\u00e1t do '%1'
+GeneralView.label.maxdownloadspeed.tooltip=Max rychlost stahov\u00e1n\u00ed [0: neomezen\u011b]
 upnp.enable=Povolit UPnP
-upnp.info=Univers\u00e1ln\u00ed  Plug and Play (UPnP) povoluje automat. mapov\u00e1n\u00ed portu UPnP povoleno routers.
-upnp.mapping.dataport=Odchoz\u00ed Peer Data Port
-upnp.mapping.tcptrackerport=TCP server  Port
-upnp.mapping.udptrackerport=UDP serve  Port
-upnp.alert.differenthost=UPnP: Mapuji '%1' rezervaci '%2' - pros\u00edm vyberte port
-upnp.alert.mappingok=UPnP: Mapuji '%1' ustanoven\u00ed
-upnp.alert.mappingfailed=UPnP: Mapuji '%1' po\u0161kozen\u00e9
-upnp.alertsuccess=Zpr\u00e1va \u00fasp\u011b\u0161n\u00e9h mapov\u00e1n\u00ed
-upnp.alert.lostdevice=UPnP: ztracen\u00e9 p\u0159ipojen\u00ed - udr\u017eba  '%1' on UPnP ovlada\u010d '%2'
-upnp.grabports=Mapov\u00e1n\u00ed  port\u00fa na jin\u00e9m po\u010d\u00edta\u010di
+upnp.info=Univers\u00e1ln\u00ed Plug and Play (UPnP) povoluje automatick\u00e9 mapov\u00e1n\u00ed port\u016f na routerech, kter\u00e9 maj\u00ed povolen\u00e9 UPnP.
+upnp.mapping.dataport=Odchoz\u00ed Port Dat Klient\u016f
+upnp.mapping.tcptrackerport=TCP Port Trackeru
+upnp.mapping.udptrackerport=UDP Port Trackeru
+upnp.alert.differenthost=UPnP: Mapov\u00e1n\u00ed '%1' bylo rezervov\u00e1no '%2' - pros\u00edm vyberte jin\u00fd port
+upnp.alert.mappingok=UPnP: Mapov\u00e1n\u00ed '%1' vytvo\u0159eno
+upnp.alert.mappingfailed=UPnP: Mapov\u00e1n\u00ed '%1' selhalo
+upnp.alertsuccess=Nahl\u00e1sit \u00fasp\u011b\u0161n\u00e1 mapov\u00e1n\u00ed
+upnp.alert.lostdevice=UPnP: ztracen\u00e9 p\u0159ipojen\u00ed p\u0159i obsluze '%1' na UPnP za\u0159\u00edzen\u00ed '%2'
+upnp.grabports=Mapovat porty, i kdy\u017e jsou vlastn\u011bn\u00e9 jin\u00fdm po\u010d\u00edta\u010dem
 upnp.refresh.label=Obnovit mapov\u00e1n\u00ed
 upnp.refresh.button=Obnovit
-upnp.alert.mappinggrabbed=UPnP: Mapuji '%1' ustanoven\u00ed propadli\u0161t\u011b z '%2'
-upnp.mapping.tcpssltrackerport=TCP SSL server  Port
-upnp.alertothermappings=Zpr\u00e1va o portech jin\u00fdch po\u010d\u00edta\u010d\u016f
-upnp.alertdeviceproblems=Zpr\u00e1va o probl\u00e9mu v UPnP ovlada\u010di
-blank.resource=Zdroje
-ConfigView.pluginlist.coreplugins=N\u00e1sleduj\u00edc\u00ed dopln\u011bk je aktualizov\u00e1n:
-Peers.column.DLedFromOthers=Dal\u0161\u00ed
-Peers.column.DLedFromOthers.info=Mno\u017estv\u00ed dat sta\u017een\u00fdch od jin\u00fdch po dobu p\u0159ipojen\u00ed
-Peers.column.UpDownRatio=Odesl\u00e1no:sta\u017eeno
-Peers.column.UpDownRatio.info=Klient\u016fv pom\u011br "odesl\u00e1no:sta\u017eeno"
+upnp.alert.mappinggrabbed=UPnP: Mapov\u00e1n\u00ed '%1' vytvo\u0159eno - sebr\u00e1no z '%2'
+upnp.mapping.tcpssltrackerport=TCP SSL Port Trackeru
+upnp.alertothermappings=Nahl\u00e1sit porty vlastn\u011bn\u00e9 jin\u00fdmi po\u010d\u00edta\u010di
+upnp.alertdeviceproblems=Nahl\u00e1sit probl\u00e9my se za\u0159\u00edzen\u00edm UPnP
+upnp.trace_to_log=Vypsat v\u0161echny informace o lad\u011bn\u00ed do z\u00e1znamu
+upnp.wiki_link=Str\u00e1nka Vuze Wiki o UPnP
+upnp.refresh_mappings_on_bad_nat=Automaticky obnovit mapov\u00e1n\u00ed kdy\u017e je stav NAT "Za firewallem"
+blank.resource=zdroj
+ConfigView.pluginlist.coreplugins=N\u00e1sleduj\u00edc\u00ed vestav\u011bn\u00e9 z\u00e1suvn\u00e9 moduly jsou na\u010dteny:
+Peers.column.DLedFromOthers=Od Ostatn\u00edch
+Peers.column.DLedFromOthers.info=Mno\u017estv\u00ed dat sta\u017een\u00fdch od ostatn\u00edch, zat\u00edmco jsou k V\u00e1m p\u0159ipojeni
+Peers.column.UpDownRatio=Odesl\u00e1no:Sta\u017eeno
+Peers.column.UpDownRatio.info=Klient\u016fv Pom\u011br "odesl\u00e1no:sta\u017eeno"
 Peers.column.UpRatio=Pom\u011br odeslan\u00fdch dat
-Peers.column.UpRatio.info=Klient\u016fv pom\u011br "sta\u017eeno od V\u00e1s:sta\u017eeno od ostatn\u00edch"
-upnp.releasemappings=Vyd\u00e1n\u00edzastaven\u00ed  mapov\u00e1n\u00ed
-webui.upnpenable=Povolit UPnP tento port (*)
-ConfigView.section.file.friendly.hashchecking=Kontrola hash \u010dekejte
-ConfigView.section.file.friendly.hashchecking.tooltip=M\u00edrn\u011b pomalej\u0161\u00ed, m\u00e9n\u011b n\u00e1ro\u010dn\u00e9 na procesor a syst\u00e9m, m\u00f3d kontrolov\u00e1n\u00ed hashe.
-ConfigView.section.tracker.seedretention=Maxim\u00e1ln\u00ed po\u010det klient\u016f na jeden torrent [0: neomezen\u011b]
-ConfigView.section.tracker.seedretention.info=Pozn\u00e1mka: Upload statistika bude ztracena pro odpojen\u00ed
-ConfigView.section.tracker.port=Povolit serveru  HTTP port
-ConfigView.section.tracker.sslport=Povolit servru HTTPS port
-ConfigView.section.tracker.publicenable.info=Povol\u00ed vytvo\u0159it ostatn\u00edm torrenty, kter\u00e9 pou\u017eije V\u00e1\u0161 tracker\nbez jejich hostov\u00e1n\u00ed/publikov\u00e1n\u00ed
+Peers.column.UpRatio.info=Klient\u016fv pom\u011br "Odesl\u00e1no od V\u00e1s : Odesl\u00e1no od ostatn\u00edch"
+upnp.releasemappings=P\u0159i ukon\u010den\u00ed uvolnit mapov\u00e1n\u00ed
+webui.upnpenable=Povolit UPnP pro tento port
+ConfigView.section.file.friendly.hashchecking=P\u0159\u00edv\u011btiv\u00e1 kontrola hash
+ConfigView.section.file.friendly.hashchecking.tooltip=M\u00edrn\u011b pomalej\u0161\u00ed, ale m\u00e9n\u011b n\u00e1ro\u010dn\u00e1 na procesor/syst\u00e9m, re\u017eim kontroly hash d\u00edl\u016f.
+ConfigView.section.tracker.seedretention=Maximum udr\u017een\u00fdch distribuc\u00ed na jeden torrent [0: neomezen\u011b]
+ConfigView.section.tracker.seedretention.info=Pozn\u00e1mka: Statistiky odes\u00edl\u00e1n\u00ed budou ztraceny u neudr\u017een\u00fdch distribuc\u00ed
+ConfigView.section.tracker.port=Povolit tracker na portu HTTP
+ConfigView.section.tracker.sslport=Povolit tracker na portu HTTPS
+ConfigView.section.tracker.publicenable.info=Toto povol\u00ed ostatn\u00edm vytv\u00e1\u0159et torrenty, kter\u00e9 pou\u017e\u00edvaj\u00ed V\u00e1\u0161 tracker\n ani\u017e by je hostovali/publikovali
 Button.clear=Smazat
-MainWindow.IPs.tooltip={\u010cas posledn\u00ed aktualizace IP Filtr\u016f} Po\u010det IP Filtr\u016f - Po\u010det zablokovan\u00fdch IP adres p\u0159i tomto spu\u0161t\u011bn\u00ed\nPoklep\u00e1n\u00edm zobraz\u00edte dal\u0161\u00ed informace
-ConfigView.section.ipfilter.list.banned=IP adrese tohoto u\u017eivatele je blokov\u00e1no p\u0159ipojen\u00ed se k V\u00e1m
-ConfigView.section.ipfilter.list.baddata=poslal neplatn\u00e1 data =
+MainWindow.IPs.tooltip=\u010cas posledn\u00ed aktualizace seznamu filtru: %1\nCelkov\u011b IP Filtr\u016f v seznamu - Po\u010det blokovan\u00fdch/zak\u00e1zan\u00fdch/\u0161patn\u00fdch IP v t\u00e9to relaci.\nDvakr\u00e1t klikn\u011bte pro podrobnosti.
+ConfigView.section.ipfilter.list.banned=byla zak\u00e1z\u00e1na
+ConfigView.section.ipfilter.list.baddata=poslal \u0161patn\u00e1 data: v\u00fdskyty =
 Button.reset=Zru\u0161it
-ConfigView.section.ipfilter.bannedinfo=IP adresy kter\u00e9 poslaly neplatn\u00e1 data budou zablokov\u00e1ny pokud p\u0159es\u00e1hnou limit
-ConfigView.section.ipfilter.blockedinfo=IP adresy, kter\u00e9 jsou zablokov\u00e1ny va\u0161imi IP filtry
-download.removerules.name=Odstran\u011bn\u00ed pravidel
-download.removerules.unauthorised.info=Neautorizov\u00e9 torrenty jsou ty, kde je ozn\u00e1men obsah odezvy  bu\u010f "neopr\u00e1vn\u011bn\u00ed" nebo "neautorizov\u00e1n\u00e9", nebo chyb\u011bj\u00edc\u00ed odezva
-download.removerules.unauthorised=Automatick\u00e9 odstran\u011bn\u00ed neautorizovan\u00fdch torrent\u016f
-download.removerules.unauthorised.seedingonly=\tJen p\u0159i distrubuci
-download.removerules.removed.ok=Automatick\u00e9 odstran\u011bn\u00ed torrentu '%1' prob\u011bhlo \u00fasp\u011b\u0161n\u011b. Toto bylo zp\u016fsobeno pravidly na odstran\u011bn\u00ed torrentu.
-download.removerules.updatetorrents=Vuze swarm po\u017eaduje odstran\u011bn\u00ed aktualizac\u00ed torrentu
-ConfigView.label.defaultstarttorrentsstopped=Implicitn\u011b p\u0159id\u00e1vej torrenty v zastaven\u00e9m stavu
+ConfigView.section.ipfilter.bannedinfo=IP adresy kter\u00e9 poslaly \u0161patn\u00e1 data - zak\u00e1z\u00e1ny pokud p\u0159es\u00e1hnou limit
+ConfigView.section.ipfilter.blockedinfo=IP adresy, kter\u00e9 jsou zablokov\u00e1ny IP filtry
+download.removerules.name=Pravidla Odstran\u011bn\u00ed
+download.removerules.unauthorised.info=Neschv\u00e1len\u00e9 torrenty jsou ty, kde odpov\u011b\u010f ozn\u00e1men\u00ed obsahuje bu\u010f "nen\u00ed ov\u011b\u0159eno" nebo "neov\u011b\u0159eno" v "odpov\u011bdi selh\u00e1n\u00ed"
+download.removerules.unauthorised=Automatick\u00e9 odstran\u011bn\u00ed neschv\u00e1len\u00fdch torrent\u016f
+download.removerules.unauthorised.seedingonly=\tJen p\u0159i distribuci
+download.removerules.removed.ok=Automatick\u00e9 odstran\u011bn\u00ed torrentu '%1' prob\u011bhlo \u00fasp\u011b\u0161n\u011b. Toto bylo zp\u016fsobeno pravidly odstran\u011bn\u00ed torrentu.
+download.removerules.updatetorrents=Odstranit aktualiza\u010dn\u00ed torrenty Vuze, jak vy\u017eaduje po\u010det \u00fa\u010dastn\u00edl\u016f
+ConfigView.label.defaultstarttorrentsstopped=Standardn\u011b p\u0159id\u00e1vat nov\u00e9 torrenty ve stavu zastaveno
 ConfigView.section.server.enableudp=Povolit UDP tracker klient protokol.
-upnp.mapping.dataportudp=UDP server klient port
-ConfigView.section.file.decoder.showlax=Zobrazit men\u0161\u00ed pravd\u011bpodobnost zak\u00f3dov\u00e1n\u00ed
-ConfigView.section.file.decoder.showall=Po\u017eadovat v\u0161e zakodovan\u011b
-MainWindow.status.updowndetails.tooltip=Detaily rychlost\u00ed stahov\u00e1n\u00ed/odes\u00edl\u00e1n\u00ed\nPrav\u00fdm tla\u010d\u00edtkem rychlosti zm\u011b\u0148\u00edte, dvojklikem prav\u00fdm tla\u010d\u00edtkem otev\u0159ete statistiky.
-TrackerClient.announce.warningmessage=Sever pro '%1' vrac\u00ed varov\u00e1n\u00ed '%2'
-ConfigView.section.tracker.natcheckenable=Kontroluje spojen\u00edschopnost portu na p\u0159\u00edchoz\u00ed data a oznamuje klient\u016fm selh\u00e1n\u00ed
-ConfigView.section.tracker.publishenabledetails=Publikovat .torrent soubor a detaily o zdroj\u00edch
-ConfigView.section.tracker.publishenablepeerdetails=Publikovat detaily u\u017eivatele
-MyTrackerView.badnat=Chyba NAT
-MyTrackerView.badnat.info=Distrubuj\u00edc\u00ed/klienti, kter\u00fdm selhala kontrola NAT, pokud je tato mo\u017enost povolena
-ConfigView.section.tracker.natchecktimeout=Kontrola p\u0159ekro\u010den\u00ed \u010das. limitu (sec)
-ConfigView.section.file.perf.cache.enable=Spustit diskovou pam\u011b\u0165
+upnp.mapping.dataportudp=UDP port klient\u016f trackeru
+ConfigView.section.file.decoder.showlax=Zobrazit m\u00e9n\u011b pravd\u011bpodobn\u00e1 k\u00f3dov\u00e1n\u00ed
+ConfigView.section.file.decoder.showall=Zv\u00e1\u017eit v\u0161echny mo\u017en\u00e1 k\u00f3dov\u00e1n\u00ed
+MainWindow.status.updowndetails.tooltip=Podrobnosti rychlost\u00ed stahov\u00e1n\u00ed/odes\u00edl\u00e1n\u00ed\nPrav\u00fdm tla\u010d\u00edtkem rychlosti pro zm\u011bnu, Dvojit\u00fdm kliknut\u00edm otev\u0159ete statistiky.
+TrackerClient.announce.warningmessage=Tracker pro '%1' vr\u00e1til varov\u00e1n\u00ed '%2'
+ConfigView.section.tracker.natcheckenable=Zkontrolovat p\u0159ipojitelnost "p\u0159\u00edchoz\u00edho datov\u00e9ho portu" a nahl\u00e1sit chyby klient\u016fm
+ConfigView.section.tracker.publishenabledetails=Publikovat v\u0161echny podrobnosti torrentu
+ConfigView.section.tracker.publishenablepeerdetails=Publikovat podrobnosti klienta
+MyTrackerView.badnat=\u0160patn\u00fd NAT
+MyTrackerView.badnat.info=Distributo\u0159i/Klienti, kte\u0159\u00ed nepro\u0161li kontrolou NAT, pokud je povoleno
+ConfigView.section.tracker.natchecktimeout=\u010casov\u00fd limit kontroly (sek)
+ConfigView.section.file.perf.cache.enable=Povolit vyrovn\u00e1vac\u00ed pam\u011b\u0165 disku
 ConfigView.section.file.perf.cache.size=Velikost vyrovn\u00e1vac\u00ed pam\u011bti v %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
-MainWindow.menu.transfers=P&\u0159enos
-MainWindow.menu.transfers.startalltransfers=Sp&ustit v\u0161e
-MainWindow.menu.transfers.stopalltransfers=St&op v\u0161e
-MainWindow.menu.transfers.pausetransfers=&Pauza
+MainWindow.menu.transfers=&P\u0159enosy
+MainWindow.menu.transfers.startalltransfers=Sp&ustit V\u0161e
+MainWindow.menu.transfers.stopalltransfers=Z&astavit V\u0161e
+MainWindow.menu.transfers.pausetransfers=&Pozastavit
 MainWindow.menu.transfers.resumetransfers=&Pokra\u010dovat
-ConfigView.label.experimental.osx.kernel.panic.fix=Experiment\u00e1ln\u00ed z\u00e1plata kv\u016fli panice j\u00e1dra na dvouprocesorov\u00fdch OSX syst\u00e9mech [vy\u017eaduje restart]
-SystemTray.menu.pausetransfers=Pauza v p\u0159enosu
-SystemTray.menu.resumetransfers=Znovu spustit p\u0159enos
-ConfigView.section.file.truncate.too.large=O\u0159\u00edzne existujic\u00ed velk\u00e9 soubory
-ConfigView.section.file.perf.cache.trace=Opera\u010dn\u00ed stopa vyrovn\u00e1vac\u00ed pam\u011bti pro diagnostick\u00e9 \u00fa\u010dely
-ConfigView.section.interface.enabletray=Povolit zobrazen\u00ed v syst\u00e9mov\u00e9 li\u0161t\u011b (vy\u017eaduje restart)
+ConfigView.label.experimental.osx.kernel.panic.fix=Experiment\u00e1ln\u00ed oprava kv\u016fli panice j\u00e1dra na dvouprocesorov\u00fdch OSX syst\u00e9mech [vy\u017eaduje restart]
+SystemTray.menu.pausetransfers=Pozastavit P\u0159enosy
+SystemTray.menu.resumetransfers=Pokra\u010dovat v P\u0159enosech
+ConfigView.section.file.truncate.too.large=O\u0159\u00edzne existuj\u00edc\u00ed soubory, kter\u00e9 jsou p\u0159\u00edli\u0161 velk\u00e9
+ConfigView.section.file.perf.cache.trace=Sledovat operace vyrovn\u00e1vac\u00ed pam\u011bti pro diagnostick\u00e9 \u00fa\u010dely
+ConfigView.section.interface.enabletray=Povolit Syst\u00e9movou Li\u0161tu [vy\u017eaduje restart]
 PeerManager.status.error=Chyba
-Stats.title.full=Statistika
-TransferStatsView.title.full=P\u0159enos
+Stats.title.full=Statistiky
+TransferStatsView.title.full=P\u0159enosy
 CacheView.title.full=Vyrovn\u00e1vac\u00ed pam\u011b\u0165
 CacheView.general.size=Celkov\u00e1 velikost
 CacheView.general.inUse=Pou\u017e\u00edv\u00e1 se
@@ -1168,8 +1189,8 @@ CacheView.general.title=Info o vyrovn\u00e1vac\u00ed pam\u011bti
 CacheView.reads.title=I/O \u010dten\u00ed
 CacheView.reads.fromFile=Ze souboru
 CacheView.reads.fromCache=Z vyrov. pam\u011bti
-CacheView.reads.hits=Hity
-CacheView.writes.title=I/O z\u00e1pisy
+CacheView.reads.hits=Z\u00e1sahy
+CacheView.writes.title=I/O Z\u00e1pisy
 CacheView.writes.toCache=Do vyrov. pam\u011bti
 CacheView.writes.toFile=Do souboru
 CacheView.writes.hits=Ulo\u017eeno
@@ -1178,674 +1199,1986 @@ CacheView.speeds.reads=\u010cten\u00ed
 CacheView.speeds.writes=Z\u00e1pisy
 CacheView.speeds.fromCache=Z/do vyrov. pam\u011bti
 CacheView.speeds.fromFile=Ze/do souboru
+CacheView.reads.#=\u010d.
 CacheView.reads.amount=Mno\u017estv\u00ed
 CacheView.reads.avgsize=Pr\u016fm. velikost
-openUrl.referrer=Referen\u010dn\u00ed str\u00e1nka URL :
-openUrl.referrer.info=Po\u017eadov\u00e1n p\u0159\u00edstupov\u00fd mand\u00e1t na  web sites
-ConfigView.label.maxuploadspeedseeding=KB/s glob\u00e1ln\u00ed max. rychlost uploadu pokud pouze distrubujete [0: neomezen\u011b]
-ConfigView.label.transfer.ignorepeerports=Ignorovat klienty s t\u00edmto datov\u00fdm vstupn\u00edm portem (odd\u011blte st\u0159edn\u00edkem ";", nap\u0159\u00edklad: 0;25)
-ConfigView.section.proxy.enable_socks.peer=Povolen\u00ed proxy pro komunikaci (odchoz\u00ed p\u0159ipojen\u00ed) [je t\u0159eba restartovat Vuze
-ConfigView.section.proxy.peer.informtracker=Informovat server o omezen\u00ed
+openUrl.referrer=Odkazuj\u00edc\u00ed str\u00e1nka URL :
+openUrl.referrer.info=Vy\u017eadov\u00e1n pouze pro internetov\u00e9 str\u00e1nky, kter\u00e9 ho na\u0159izuj\u00ed
+ConfigView.label.maxuploadspeedseeding=Alternativn\u00ed rychlost, kdy\u017e pouze distribuujete
+ConfigView.label.transfer.ignorepeerports=Ignorovat klienty s t\u011bmito datov\u00fdmi porty (odd\u011blen\u00e9 ';', nap\u0159.: 0;25)
+ConfigView.section.proxy.enable_socks.peer=Povolit komunikaci klient\u016f p\u0159es proxy (pouze odchoz\u00ed p\u0159ipojen\u00ed) [vy\u017eadov\u00e1n restart]
+ConfigView.section.proxy.peer.informtracker=Informovat tracker o omezen\u00ed
 ConfigView.section.proxy.socks.version=Verze SOCKS
-PiecesView.legend.written=Z\u00e1pisov\u00e1n\u00ed
+PiecesView.legend.written=Zaps\u00e1n
 PiecesView.legend.requested=Po\u017eadovan\u00fd
-PiecesView.legend.downloaded=Sta\u017eeno, zaps\u00e1ny nevy\u0159e\u0161en\u00e9
-PiecesView.legend.incache=Data ve vyrovn\u00e1vac\u00ed pam\u011bti
+PiecesView.legend.downloaded=Sta\u017eeno, \u010dek\u00e1 na z\u00e1pis
+PiecesView.legend.incache=Data jsou ve Vyrovn\u00e1vac\u00ed Pam\u011bti
 PiecesView.typeItem.0=Pomal\u00e9
 PiecesView.typeItem.1=Rychl\u00e9
 PiecesView.type=Typ
-Security.jar.tools_not_found=JAR selh\u00e1n\u00ed podpisu - 'n\u00e1stroje.jar' nenelazen %1. Zkontroluj N\u00e1stroje->Mo\u017enosti->Zabezpe\u010den\u00ed detaily.
-Security.jar.signfail=JAR selh\u00e1n\u00ed podpisu - %1
-ConfigView.section.security.toolsinfo=Ozna\u010den\u00e9 JAR soubory se pou\u017e\u00edvaj\u00ed pro podporu n\u011bkter\u00fdch plugin\u016f jako nap\u0159. Swing Web Interface (pokud je to tak nakonfigurov\u00e1no).\nPro pou\u017eit\u00ed JAR soubor\u016f je nezbytn\u00e9 m\u00edt p\u0159\u00edstup k  'tools.jar', kter\u00fd najdete v instalaci Sun JDK (ne JRE).\nJestli\u017ee jste naistalovali  jen JRE, pak naistalujte i JDK.\nVuze pro V\u00e1s v\u011bt\u0161inou soubor najde s\u00e1m [...]
-ConfigView.section.security.toolsdir=Adres\u00e1\u0159 obsahujic\u00ed 'tools.jar'
-ConfigView.section.security.choosetoolssavedir=Vyberte slo\u017eku obsahujic\u00ed 'tools.jar'
-ConfigView.section.proxy.peer.same=Pou\u017eit\u00ed stejn\u00e9 proxy nastaven\u00ed pro server i u\u017eivatele u\u017e\u00edvaj\u00edc\u00ed proxy
-ConfigView.section.connection.network.max.simultaneous.connect.attempts=Maxim\u00e1ln\u00ed po\u010det pokus\u016f simult\u00e1nn\u00edho odchoz\u00edho p\u0159ipojen\u00ed
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Maxim\u00e1ln\u00ed po\u010det nov\u00fdch odchoz\u00edch nav\u00e1zan\u00fdch p\u0159ipojen\u00ed. Vuze se bude pokou\u0161et o p\u0159ipojen\u00ed kdykoli.\nPozn\u00e1mka  Windows XP Service Pack 2 (SP2) celosyst\u00e9mov\u011b nastavuje limit 10 simultann\u00edch spojen\u00ed.\nStandarni hodnota  je 8. Hodnota  0 zak\u00e1\u017ee odchoz\u00ed spojen\u00ed \u00fapln\u011b.
-ConfigView.section.file.perf.cache.size.explain=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 je vyu\u017eita pro redukci \u010dten\u00ed a z\u00e1pisu na disk. Jestli\u017ee nepou\u017e\u00edvate Java mo\u017enosti '-XX:MaxDirectMemorySize' pro implicitn\u011b nastavenou pam\u011b\u0165 dosa\u017eitelnou pro vyrovn\u00e1vac\u00ed pam\u011b\u0165 a  s\u00ed\u0165 IO, pou\u017eijte  tuto hodnotu nejm\u00e9n\u011b  %1 pod Va\u0161i maxim\u00e1ln\u00ed velikost  virtu\u00e1ln\u00ed pam\u011bti. Sou [...]
+Security.jar.tools_not_found=Podepisov\u00e1n\u00ed JAR selhalo - 'tools.jar' nebyl nalezen v %1. Pod\u00edvejte se na N\u00e1stroje->Nastaven\u00ed->Zabezpe\u010den\u00ed pro podrobnosti.
+Security.jar.signfail=Podepisov\u00e1n\u00ed JAR selhalo - %1
+ConfigView.section.security.toolsinfo=Podepsan\u00e9 JAR soubory se pou\u017e\u00edvaj\u00ed pro podporu n\u011bkter\u00fdch z\u00e1suvn\u00fdch modul\u016f jako nap\u0159. Swing Web Interface (pokud je tak nastaven).\nAbyste mohli podepsat JAR soubory je nezbytn\u00e9 m\u00edt p\u0159\u00edstup k  'tools.jar', kter\u00fd najdete v instalaci Sun JDK (ne JRE).\nJestli\u017ee jste nainstalovali jen JRE, pak naistalujte i JDK.\nVuze norm\u00e1ln\u011b najde soubor pro V\u00e1s s\u00e1m. Nic [...]
+ConfigView.section.security.toolsdir=Adres\u00e1\u0159 obsahuj\u00edc\u00ed 'tools.jar'
+ConfigView.section.security.choosetoolssavedir=Vyberte adres\u00e1\u0159 obsahuj\u00edc\u00ed 'tools.jar'
+ConfigView.section.proxy.peer.same=Pou\u017eit\u00ed stejn\u00e9 nastaven\u00ed proxy pro komunikaci trackeru i klienta p\u0159es proxy
+ConfigView.section.connection.network.max.simultaneous.connect.attempts=Max pokus\u016f o simult\u00e1nn\u00ed odchoz\u00ed p\u0159ipojen\u00ed
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Maxim\u00e1ln\u00ed po\u010det nov\u00fdch odchoz\u00edch nav\u00e1zan\u00ed p\u0159ipojen\u00ed, o kter\u00e9 by se Vuze m\u011bl kdykoli  pokou\u0161et.\nPOZN\u00c1MKA: Windows XP Service Pack 2 (SP2) zav\u00e1d\u00ed celosyst\u00e9mov\u00fd limit 10 simult\u00e1nn\u00edch pokus\u016f o spojen\u00ed.\nStandardn\u00ed hodnota je 8.
+ConfigView.section.file.perf.cache.size.explain=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 je vyu\u017eita pro redukci \u010dten\u00ed z/z\u00e1pisu na disk. Jestli\u017ee nepou\u017e\u00edv\u00e1te volbu Java '-XX:MaxDirectMemorySize' pro jasn\u00e9 nastaven\u00ed dostupn\u00e9 pam\u011bti pro vyrovn\u00e1vac\u00ed pam\u011b\u0165 a pou\u017eit\u00ed IO s\u00edt\u011b, m\u011bli byste tuto hodnotu nechat alespo\u0148 na %1 pod maxim\u00e1ln\u00ed velikost\u00ed Va\u0161\u00ed virtu\u00e1ln\u [...]
 MyTorrentsView.menu.setSpeed.unlimit=\u017d\u00e1dn\u00fd limit
-MyTorrentsView.menu.setSpeed.unlimited=Bez limitu
-MyTorrentsView.menu.setSpeed.disable=Zak\u00e1zan\u00fd upload
+MyTorrentsView.menu.setSpeed.unlimited=Neomezen\u011b
+MyTorrentsView.menu.setSpeed.disable=Zak\u00e1zat Stahov\u00e1n\u00ed
 MyTorrentsView.menu.setSpeed.disabled=Zak\u00e1zan\u00fd
 MyTorrentsView.menu.setSpeed.in=v
-MyTorrentsView.menu.setSpeed.slots=sloty z
-GeneralView.label.maxuploadspeed=Max stah.
+MyTorrentsView.menu.setSpeed.slots=pozice 
+GeneralView.label.maxuploadspeed=Limit odes.
 GeneralView.label.maxuploadspeed.tooltip=Maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed [0 : neomezen\u011b]
-MyTorrents.items.UpSpeedLimit.disabled=\u017d\u00e1dn\u00fd upload
-MyTorrents.items.UpSpeedLimit.unlimited=neomezen\u011b
-TableColumn.header.maxupspeed=Maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed
-TableColumn.header.maxupspeed.info=Maxim\u00e1ln\u00ed rychlost stahov\u00e1n\u00ed na jeden torrent
-ConfigView.section.file.perf.cache.enable.write=Zapisovat sta\u017een\u00e1 data do vyrovn\u00e1vac\u00ed pam\u011bti pro sn\u00ed\u017een\u00ed aktivity harddisku
-ConfigView.section.file.perf.cache.enable.read=Vykon\u00e1vat na\u010d\u00edt\u00e1n\u00ed soubor\u016f dop\u0159edu pro redukci aktivity harddisku p\u0159i odes\u00edl\u00e1n\u00ed dat
-ConfigView.section.tracker.separatepeerids=Pou\u017e\u00edt r\u016fzn\u00e9 identity pro tracker a datov\u00fd p\u0159enos
-ConfigView.section.tracker.separatepeerids.info=Zv\u00fd\u0161\u00ed anonymitu jestli stahujete/distribujete anonymn\u011b\np\u0159i pou\u017eit\u00ed neanonmn\u00edho spojen\u00ed trackeru
+MyTorrents.items.UpSpeedLimit.disabled=\u017d\u00e1dn\u00e9 odes\u00edl\u00e1n\u00ed
+MyTorrents.items.UpSpeedLimit.unlimited=Neomezen\u011b
+TableColumn.header.maxupspeed=Maxim\u00e1ln\u00ed Rychlost Odes\u00edl\u00e1n\u00ed
+TableColumn.header.maxupspeed.info=Limit rychlosti odes\u00edl\u00e1n\u00ed nastaven\u00fd na klienta
+ConfigView.section.file.perf.cache.enable.write=Uchov\u00e1vat sta\u017een\u00e1 data pro sn\u00ed\u017een\u00ed z\u00e1pisu na disk a tak\u00e9 sn\u00ed\u017e\u00ed \u010dten\u00ed z disku pot\u0159ebn\u00e9 pro kontrolu d\u00edl\u016f
+ConfigView.section.file.perf.cache.enable.read=Prov\u00e1d\u011bt \u010dten\u00ed dop\u0159edu, pro sn\u00ed\u017een\u00ed \u010dten\u00ed z disku p\u0159i odes\u00edl\u00e1n\u00ed
+ConfigView.section.tracker.separatepeerids=Pou\u017e\u00edt r\u016fzn\u00e9 identity klient\u016f pro trackerovou a datovou komunikaci
+ConfigView.section.tracker.separatepeerids.info=Zvy\u0161uje anonymitu kdy\u017e stahujete/distribuujete anonymn\u011b\nzat\u00edmco pou\u017e\u00edv\u00e1te neanonymn\u00ed p\u0159ipojen\u00ed k trackeru
 ConfigView.section.interface.wavlocation=Um\u00edst\u011bn\u00ed  .wav souboru
 ConfigView.section.interface.wavlocation.info=Vyberte .wav soubor nebo ponechte pr\u00e1zdn\u00e9 pro v\u00fdchoz\u00ed zvuk
 ConfigView.section.tracker.client=Klient
-ConfigView.section.tracker.client.connecttimeout=P\u0159ekro\u010den\u00ed \u010dasov\u00e9ho limitu (sec)
-ConfigView.section.tracker.client.readtimeout=Na\u010dten\u00ed p\u0159ekro\u010den\u00ed \u010das. limitu (sec)
+ConfigView.section.tracker.client.connecttimeout=\u010casov\u00fd limit spojen\u00ed (sek)
+ConfigView.section.tracker.client.readtimeout=\u010casov\u00fd limit \u010dten\u00ed (sek)
 MainWindow.menu.tools=&N\u00e1stroje
 FilesView.path=Cesta
-FilesView.fullpath=Zobrazit celou cestu
+FilesView.fullpath=Zobrazit \u00daplnou Cestu
 FilesView.remaining=Zb\u00fdvaj\u00edc\u00ed d\u00edly
 TableColumn.header.trackername=N\u00e1zev trackeru
-TableColumn.header.trackername.info=N\u00e1zev serveru zalo\u017een\u00fd na ozn\u00e1men\u00ed URL
-ConfigView.group.override=P\u0159epsat mo\u017enosti
-ConfigView.section.file.perf.cache.notsmallerthan=Do vyrovn\u00e1vac\u00ed pam\u011bti nejdou men\u0161\u00ed soubory ne\u017e (v %1)
+TableColumn.header.trackername.info=N\u00e1zev trackeru zalo\u017een\u00fd na oznamovac\u00ed URL
+ConfigView.group.override=Potla\u010dit Mo\u017enosti
+ConfigView.section.file.perf.cache.notsmallerthan=Do vyrovn\u00e1vac\u00ed pam\u011bti se neukl\u00e1daj\u00ed men\u0161\u00ed soubory ne\u017e (v %1)
 PeersView.menu.blockupload=Blokov\u00e1n\u00ed odes\u00edl\u00e1n\u00ed
-PeersView.menu.kickandban=Vykopnout a zablokovat u\u017eivatele
-PeersView.menu.kickandban.reason=Klient byl manu\u00e1ln\u011b zablokov\u00e1n
+PeersView.menu.kickandban=Vykopnout a Zak\u00e1zat
+PeersView.menu.kickandban.reason=Klient byl ru\u010dn\u011b zak\u00e1z\u00e1n
 PeersView.state=Stav
-PeersView.state.info=Stav  peer p\u0159ipojen\u00ed
-PeersView.state.pending=\u010cek\u00e1 na obslou\u017een\u00ed
-PeersView.state.connecting=Navazuje se
-PeersView.state.handshake=\u010cek\u00e1 na souhlas
+PeersView.state.info=Stav p\u0159ipojen\u00ed klienta
+PeersView.state.pending=Nevy\u0159\u00edzen\u00fd
+PeersView.state.connecting=P\u0159ipojov\u00e1n\u00ed
+PeersView.state.handshake=\u010cek\u00e1 na zah\u00e1jen\u00ed komunikace
 PeersView.state.established=Spojen\u00ed nav\u00e1z\u00e1no
-ConfigView.section.tracker.processinglimits=Limit pro zpracov\u00e1n\u00ed
-ConfigView.section.tracker.maxgettime=Maxim\u00e1ln\u00ed \u010das pro zpracov\u00e1n\u00ed GET  (sec) [0: neomezeno]
+ConfigView.section.tracker.processinglimits=Limity pro zpracov\u00e1n\u00ed
+ConfigView.section.tracker.maxgettime=Maxim\u00e1ln\u00ed \u010das pro zpracov\u00e1n\u00ed GET (sek) [0: neomezeno]
 ConfigView.section.tracker.maxgettime.info=Pou\u017eito pro ozn\u00e1men\u00ed a scrapy
-ConfigView.section.tracker.maxposttimemultiplier=\u010casov\u00fd n\u00e1sobitel GET pro zpracov\u00e1n\u00ed POST  [0: bezlimitu]
-ConfigView.section.tracker.maxposttimemultiplier.info=Pou\u017eito pro formu pod\u0159\u00edzen\u00ed a odes\u00edl\u00e1n\u00ed
-ConfigView.section.tracker.maxthreads=Maxim\u00e1ln\u00ed po\u010det soub\u011b\u017en\u00fdch po\u017eadavk\u016f
-DownloadManager.error.operationcancancelled=Operace je zru\u0161ena
+ConfigView.section.tracker.maxposttimemultiplier=\u010casov\u00fd n\u00e1sobitel GET pro zpracov\u00e1n\u00ed POST [0: neomezen\u011b]
+ConfigView.section.tracker.maxposttimemultiplier.info=Pou\u017eito pro odesl\u00e1n\u00ed formul\u00e1\u0159\u016f a odes\u00edl\u00e1n\u00ed
+ConfigView.section.tracker.maxthreads=Max soub\u011b\u017en\u00fdch po\u017eadavk\u016f
+DownloadManager.error.operationcancancelled=Operace zru\u0161ena
 Torrent.create.progress.cancelled=Operace zru\u0161ena
 sharing.progress.cancel=Zru\u0161it
-wizard.maketorrents.autoopen=Otev\u0159ete torrent pro seeding, kdy\u017e je dokon\u010den
-ConfigView.section.sharing.rescanenable=Povolit pravideln\u00e9 skenov\u00e1n\u00ed sd\u00edlen\u00ed pro zm\u011bny
-ConfigView.section.sharing.rescanperiod=Obnoven\u00ed skenov\u00e1n\u00ed (sekundy)
-ConfigView.section.connection.advanced=Pokro\u010dil\u00e9 nastaven\u00ed s\u00edt\u011b
-ConfigView.section.connection.advanced.mtu=Maxim\u00e1ln\u00ed p\u0159enosov\u00e1 jednotka (MTU)
-ConfigView.section.connection.advanced.mtu.tooltip=Maxim\u00e1ln\u00ed velikost paketu, p\u0159en\u00e1\u0161en\u00e9ho v jednom framu p\u0159es s\u00ed\u0165.\nVuze pou\u017e\u00edv\u00e1 MTU-40 (MSS) pro optim\u00e1ln\u011b vyu\u017eit\u00e9 zat\u00ed\u017een\u00ed odes\u00edlan\u00e9ho paketu.\nDoporu\u010den\u00e9 hodnoty:\n  576 - Vyt\u00e1\u010den\u00e9 p\u0159ipojen\u00ed\n1492 - PPPoE \u0161irokop\u00e1sm\u00e9 p\u0159ipojen\u00ed\n1500 - Ethernet, DSL a kabelov\u00e9 \u0161iroko [...]
-ConfigView.section.connection.advanced.SO_RCVBUF=Velikost socketu SO_RCVBUF [0: pou\u017e\u00edt OS standart]
-ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Nastav\u00ed standartn\u00ed hodnotu socketu SO_RCVBUF (v bytech), co\u017e znamen\u00e1, \u017ee TCP p\u0159ijme velikost a pom\u011br okna.\nVuze toto nech\u00e1v\u00e1 na v\u00fdchoz\u00edch hodnot\u00e1ch (pro z\u00e1kladn\u00ed opera\u010dn\u00ed syst\u00e9m).\nPozn\u00e1mka : V Linuxu jsou hodnoty dvakr\u00e1t vy\u0161\u0161\u00ed.
-ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF velikost [0: pou\u017e\u00edt OS standart]
-ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Nastav\u00ed standartn\u00ed hodnotu socketu SO_SNDBUF (v bytech), co\u017e znamen\u00e1, \u017ee TCP po\u0161le velikost okna.\nVuze toto nastaven\u00ed nech\u00e1v\u00e1 na v\u00fdchoz\u00edch hodnot\u00e1ch (pro z\u00e1kladn\u00ed opera\u010dn\u00ed syst\u00e9m).\nPozn\u00e1mka : Pozn\u00e1mka : V Linuxu jsou hodnoty dvakr\u00e1t vy\u0161\u0161\u00ed.
-ConfigView.section.interface.confirm_torrent_removal=Zobrazit potvrzovac\u00ed dialog odstran\u011bn\u00ed  torrentu
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Potvr\u010fte p\u0159i odstran\u011bn\u00ed torrentu z Moje Torrenty.
-MyTorrentsView.confirm_torrent_removal=Jste si jist\u00ed, \u017ee to chceta odstranit?\n
+wizard.maketorrents.autoopen=Otev\u0159\u00edt torrent pro distribuci, kdy\u017e je dokon\u010den
+ConfigView.section.sharing.rescanenable=Povolit pravideln\u00e9 znovu prozkoum\u00e1n\u00ed klasick\u00fdch sd\u00edlen\u00ed pro zm\u011bny
+ConfigView.section.sharing.rescanperiod=Interval znovu prohl\u00ed\u017een\u00ed (sekundy)
+ConfigView.section.connection.advanced=Pokro\u010dil\u00e9 Nastaven\u00ed S\u00edt\u011b
+ConfigView.section.connection.advanced.mtu=Maxim\u00e1ln\u00ed P\u0159enosov\u00e1 Jednotka \u0158\u00e1dku (MTU)
+ConfigView.section.connection.advanced.mtu.tooltip=Maxim\u00e1ln\u00ed velikost paketu, p\u0159en\u00e1\u0161en\u00e9ho v jednom r\u00e1mci p\u0159es s\u00ed\u0165.\nVuze pou\u017e\u00edv\u00e1 MTU-40 (MSS) pro optim\u00e1ln\u011b vyu\u017eit\u00e9 zat\u00ed\u017een\u00ed odes\u00edlan\u00e9ho paketu.\nDoporu\u010den\u00e9 hodnoty:\n  576 - Vyt\u00e1\u010den\u00e9 p\u0159ipojen\u00ed\n1492 - PPPoE \u0161irokop\u00e1sm\u00e9 p\u0159ipojen\u00ed\n1500 - Ethernet, DSL a kabelov\u00e9 \u0161 [...]
+ConfigView.section.connection.advanced.SO_RCVBUF=Velikost socketu SO_RCVBUF [0: pou\u017e\u00edt v\u00fdchoz\u00ed v OS]
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Nastav\u00ed standardn\u00ed hodnotu socketu SO_RCVBUF (v bajtech), to je velikost okna p\u0159ijet\u00ed TCP a pom\u011br.\nVuze toto nech\u00e1v\u00e1 standardn\u011b nenastaveno, co\u017e znamen\u00e1, \u017ee v\u00fdchoz\u00ed hodnoty z\u00e1kladn\u00edho OS jsou pou\u017eity.\nPozn\u00e1mka: Linux zdvojuje zadanou hodnotu.
+ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF velikost [0: pou\u017e\u00edt v\u00fdchoz\u00ed v OS]
+ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Nastav\u00ed standardn\u00ed hodnotu socketu SO_RCVBUF (v bajtech), to je velikost okna odesl\u00e1n\u00ed TCP.\nVuze toto nech\u00e1v\u00e1 standardn\u011b nenastaveno, co\u017e znamen\u00e1, \u017ee v\u00fdchoz\u00ed hodnoty z\u00e1kladn\u00edho OS jsou pou\u017eity.\nPozn\u00e1mka: Linux zdvojuje zadanou hodnotu.
+ConfigView.section.connection.advanced.IPDiffServ=Hodnota DiffServ odchoz\u00edho paketu (pole TOS)
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=Nastav\u00ed \u010d\u00e1st DiffServ z pole typ slu\u017eby (TOS) v hlavi\u010dce IP odchoz\u00edho paketu.\n \u0160estn\u00e1ctkov\u00e9 hodnoty m\u016f\u017eou b\u00fdt zad\u00e1ny pomoc\u00ed p\u0159edpony '0x' nap\u0159. 0x10.\n Vuze toto nech\u00e1v\u00e1 standardn\u011b nenastaveno, co\u017e znamen\u00e1, \u017ee v\u00fdchoz\u00ed hodnoty z\u00e1kladn\u00edho OS jsou pou\u017eity.\nPOZN\u00c1MKA: Z\u00e1kladn\u00ed zaveden\u [...]
 TableColumn.header.seed_to_peer_ratio=Pom\u011br distrubuj\u00edc\u00ed/stahuj\u00edc\u00ed
-TableColumn.header.seed_to_peer_ratio.info=Pom\u011br distrubuj\u00edc\u00ed/stahuj\u00edc\u00ed v cel\u00e9m torrentu
+TableColumn.header.seed_to_peer_ratio.info=Celkov\u00fd pom\u011br distrubuj\u00edc\u00ed/stahuj\u00edc\u00ed \u00fa\u010dastn\u00edk\u016f torrentu
 PeersView.connected_time=\u010cas p\u0159ipojen\u00ed
-PeersView.connected_time.info=Celkov\u00fd \u010das p\u0159ipojen\u00ed s peer
-ConfigView.section.interface.display.add_torrents_silently=P\u0159idat torrenty
-ConfigView.section.interface.display.add_torrents_silently.tooltip=P\u0159idat stahov\u00e1n\u00ed torrent\u016f bez aktivace v hlavn\u00edm okn\u011b Azureus.
-TableColumn.header.maxdownspeed=Maxim\u00e1ln\u00ed rychlost stahov\u00e1n\u00ed
-TableColumn.header.maxdownspeed.info=Maxim\u00e1ln\u00ed rychlost stahov\u00e1n\u00ed na jeden torrent
+PeersView.connected_time.info=Celkov\u00fd \u010das p\u0159ipojen\u00ed s klientem
+TableColumn.header.maxdownspeed=Maxim\u00e1ln\u00ed Rychlost Stahov\u00e1n\u00ed
+TableColumn.header.maxdownspeed.info=Limit rychlosti stahov\u00e1n\u00ed nastaven\u00fd na klienta
+PeersGraphicView.title.full=Po\u010det \u00da\u010dastn\u00edk\u016f
 ConfigView.section.tracker.passwordwebhttpsonly=Povolit p\u0159\u00edstup jen p\u0159es HTTPS
 TableColumn.header.torrentpath=Um\u00edst\u011bn\u00ed Torrentu
-TableColumn.header.torrentpath.info=Um\u00edst\u011bn\u00ed Torrentu na  disku
-ConfigView.section.sharing.torrentcomment=Koment\u00e1\u0159 pro generov\u00e1n\u00ed torrent\u016f
-ConfigView.label.copyanddeleteratherthanmove=Rad\u011bji origin\u00e1ln\u00ed data nejprve zkop\u00edrujte a a\u017e potom sma\u017ete m\u00edsto p\u0159esouv\u00e1n\u00ed v jedin\u00e9 operaci. \nZabr\u00e1n\u00edte tak ztr\u00e1t\u00e1m dat na n\u011bkter\u00fdch souborov\u00fdch syst\u00e9mech.\n
-ConfigView.label.openstatsonstart=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt statistiky (Statistika)
-swt.install.window.title=Instal\u00e1tor Vuze plugin\u016f
+TableColumn.header.torrentpath.info=Um\u00edst\u011bn\u00ed Torrentu na disku
+ConfigView.section.sharing.torrentcomment=Koment\u00e1\u0159 pro vytvo\u0159en\u00e9 torrenty
+ConfigView.label.copyanddeleteratherthanmove=Rad\u011bji origin\u00e1ln\u00ed data nejprve zkop\u00edrujte a a\u017e potom sma\u017ete m\u00edsto p\u0159esouv\u00e1n\u00ed v jedin\u00e9 operaci - m\u016f\u017eete se tak vyhnout ztr\u00e1t\u011b dat na n\u011bkter\u00fdch souborov\u00fdch syst\u00e9mech
+ConfigView.label.openstatsonstart=Po spu\u0161t\u011bn\u00ed otev\u0159\u00edt Statistiky
+swt.install.window.title=Instal\u00e1tor Vuze Sou\u010d\u00e1st\u00ed/Z\u00e1suvn\u00fdch modul\u016f
 swt.install.window.ok=Instalovat
 swt.install.window.header=N\u00e1sleduj\u00edc\u00ed sou\u010d\u00e1sti byly vybr\u00e1ny pro instalaci :
-swt.uninstall.window.title=Odinstal\u00e1tor Vuze plugin\u016f
+swt.uninstall.window.title=Odstra\u0148ova\u010d Vuze Sou\u010d\u00e1st\u00ed/Z\u00e1suvn\u00fdch modul\u016f
 swt.uninstall.window.ok=Odstranit
-swt.uninstall.window.header=N\u00e1sleduj\u00edc\u00ed sou\u010dasti byly vybr\u00e1ny pro odstran\u011bn\u00ed :
-installPluginsWizard.title=Instalace  dopl\u0148k\u016f
+swt.uninstall.window.header=N\u00e1sleduj\u00edc\u00ed sou\u010d\u00e1sti byly vybr\u00e1ny pro odstran\u011bn\u00ed :
+installPluginsWizard.title=Instalovat Z\u00e1suvn\u00e9 Moduly
 installPluginsWizard.mode.title=Pros\u00edm vyberte metodu instalace
 installPluginsWizard.mode.list=Ze seznamu na sourceforge.net
-installPluginsWizard.list.title=Seznam instalovan\u00fdch dopl\u0148k\u016f
-installPluginsWizard.list.loading=Pros\u00edm \u010dekejte, na\u010d\u00edt\u00e1m seznam plugin\u016f.
-installPluginsWizard.list.loaded=Pros\u00edm vyberte si pluginy, kter\u00e9 si p\u0159ejete nainstalovat.
+installPluginsWizard.list.title=Seznam Z\u00e1suvn\u00fdch modul\u016f mo\u017en\u00fdch nainstalovat
+installPluginsWizard.list.loading=Pros\u00edm \u010dekejte, ne\u017e se na\u010dte seznam Z\u00e1suvn\u00fdch Modul\u016f.
+installPluginsWizard.list.loaded=Pros\u00edm vyberte si z\u00e1suvn\u00e9 moduly, kter\u00e9 si p\u0159ejete nainstalovat.
 installPluginsWizard.list.name=N\u00e1zev
 installPluginsWizard.list.version=Verze
-installPluginsWizard.list.description=Popis dopl\u0148k\u016f
+installPluginsWizard.list.description=Popis z\u00e1suvn\u00e9ho modulu
 installPluginsWizard.finish.title=Instalace pr\u00e1v\u011b prob\u00edh\u00e1
-installPluginsWizard.finish.explanation=Vybran\u00e9 pluginy budou nainstalov\u00e1ny pou\u017eit\u00edm Update Assistenta.\n\nPros\u00edm m\u011bjte strpen\u00ed, tato operace m\u016f\u017ee chv\u00edli trvat.\n\nPro v\u00edce informac\u00ed  dvakr\u00e1t klikn\u011bte nalevo do stavov\u00e9m \u0159\u00e1dku.
+installPluginsWizard.finish.explanation=Vybran\u00e9 Z\u00e1suvn\u00e9 Moduly budou nainstalov\u00e1ny pomoc\u00ed Asistenta Aktualizace.\n\nPros\u00edm m\u011bjte strpen\u00ed, m\u016f\u017ee to chv\u00edli trvat, ne\u017e se zobraz\u00ed.\n\nPro hl\u00e1\u0161en\u00ed o postupu, dvakr\u00e1t klikn\u011bte nalevo od li\u0161ty stavu.
 installPluginsWizard.details.loading=Pros\u00edm \u010dekejte, na\u010d\u00edt\u00e1m detaily...
 installPluginsWizard.mode.file=Ze souboru
 installPluginsWizard.installMode.title=Pros\u00edm vyberte typ instalace
-installPluginsWizard.installMode.user=Nainstaluje plugin(y) jen pro pr\u00e1v\u011b p\u0159ihl\u00e1\u0161en\u00e9ho u\u017eivatele
-installPluginsWizard.installMode.shared=Nainstaluje plugin(y) pro v\u0161echny u\u017eivatele
-installPluginsWizard.file.title=Pros\u00edm vyhledejte plugin, kter\u00fd chcete nainstalovat
+installPluginsWizard.installMode.user=Nainstalovat z\u00e1suvn\u00fd modul(y) pouze pro V\u00e1s
+installPluginsWizard.installMode.shared=Nainstalovat z\u00e1suvn\u00fd modul(y) pro v\u0161echny u\u017eivatele
+installPluginsWizard.file.title=Pros\u00edm vyhledejte z\u00e1suvn\u00fd modul, kter\u00fd chcete nainstalovat
 installPluginsWizard.file.file=Soubor :
-installPluginsWizard.file.invalidfile=Toto nen\u00ed platn\u00fd Vuze plugin.
+installPluginsWizard.file.invalidfile=Toto nen\u00ed platn\u00fd z\u00e1suvn\u00fd modul Vuze.
+installPluginsWizard.file.no_such_file=\u017d\u00e1dn\u00fd soubor se zadan\u00fdm jm\u00e9nem neexistuje.
 installPluginsWizard.file.browse=Prohl\u00ed\u017eet...
-uninstallPluginsWizard.title=Odinstalace Plugin\u016f
-uninstallPluginsWizard.list.title=Instalovat sezna Plugin\u016f
-uninstallPluginsWizard.list.loaded=Pros\u00edm vyberte plugins k odinstalov\u00e1n\u00ed.
+uninstallPluginsWizard.title=Odinstalace Z\u00e1suvn\u00fdch Modul\u016f
+uninstallPluginsWizard.list.title=Seznam Instalovan\u00fdch Z\u00e1suvn\u00fdch Modul\u016f
+uninstallPluginsWizard.list.loaded=Pros\u00edm vyberte z\u00e1suvn\u00e9 moduly, kter\u00e9 chcete odinstalovat.
 installPluginsWizard.list.nullversion=\u017d\u00e1dn\u00e1 verze
-uninstallPluginsWizard.finish.title=Postup odinstalace
-uninstallPluginsWizard.finish.explanation=Vybran\u00e9 Pluginy budou odinstalov\u00e1ny po\u017e\u00edv\u00e1n\u00edm Update Asistenta.
+uninstallPluginsWizard.finish.title=Prob\u00edh\u00e1 Odinstalace
+uninstallPluginsWizard.finish.explanation=Vybran\u00e9 Z\u00e1suvn\u00e9 Moduly budou odinstalov\u00e1ny pou\u017eit\u00edm Aktualiza\u010dn\u00edho Asistenta.
 MainWindow.menu.plugins.installPlugins=Instala\u010dn\u00ed pr\u016fvodce.....
 MainWindow.menu.plugins.uninstallPlugins=Pr\u016fvodce odinstalac\u00ed...
-ConfigView.section.ipfilter.totalIPs=%1 Celkov\u011b blokovano IP, kter\u00e9 tvo\u0159\u00ed %2 z internetu.
-update.instance.install=\u010cekejte instaluji
-update.instance.uninstall=\u010cekejte odinstaluji
-update.instance.update=\u010cekejte aktualizuji
-MainWindow.status.update.tooltip=Dvakr\u00e1t klikni pro zobrazen\u00ed informac\u00ed
-updater.progress.window.title=Aktu\u00e1ln\u00ed instala\u010dn\u00ed \u00fakoly
-updater.progress.window.info=Stiskem  'Abort' ukon\u010d\u00ed v\u0161echny vyjime\u010dn\u00e9 \u00fakoly
+ConfigView.section.ipfilter.totalIPs=%1 IP celkov\u011b blokov\u00e1no, kter\u00e9 tvo\u0159\u00ed %2 internetu.
+update.instance.install=Kontroluji Instalaci
+update.instance.uninstall=Kontroluji Odinstalaci
+update.instance.update=Kontroluji Aktualizace
+MainWindow.status.update.tooltip=Dvakr\u00e1t klikn\u011bte pro zobrazen\u00ed informac\u00ed o pr\u016fb\u011bhu
+updater.progress.window.title=Aktu\u00e1ln\u00ed \u00dakoly Instalace
+updater.progress.window.info=Stiskn\u011bte 'P\u0159eru\u0161it' pro ukon\u010den\u00ed v\u0161ech nedokon\u010den\u00fdch \u00fakol\u016f
 Button.abort=P\u0159eru\u0161it
 ConfigView.section.ipfilter.enablebanning=Blokovat u\u017eivatele, kte\u0159\u00ed opakovan\u011b pos\u00edlaj\u00ed \u0161patn\u00e1 data
-Network.alert.acceptfail=Velk\u00fd po\u010det po sob\u011b jdouc\u00edch poruch na  portu %1, %2 - zpracov\u00e1n\u00ed ukon\u010deno. Pros\u00edm zkontrolujte nastaven\u00ed internetov\u00e9 ochrany a ujist\u011bte se, \u017ee m\u00e1te na tomto portu povoleno navazov\u00e1n\u00ed p\u0159ipojen\u00ed.
+Network.alert.acceptfail=Ud\u00e1l se velk\u00fd po\u010det po sob\u011b jdouc\u00edch selh\u00e1n\u00ed na portu %1, %2 - zpracov\u00e1n\u00ed ukon\u010deno. Pros\u00edm zkontrolujte nastaven\u00ed firewallu, abyste se ujistili, \u017ee m\u00e1 povoleny p\u0159\u00edchoz\u00ed p\u0159ipojen\u00ed.
 MyShares.column.category=Kategorie
-UpdateWindow.restartLater=Restartovat pozd\u011bji
+UpdateWindow.restartLater=Restartovat Vuze Pozd\u011bji
 MainWindow.menu.file.restart=Restartovat  Vuze
-MainWindow.dialog.restartconfirmation.title=Restartovat  Azurea?
-MainWindow.dialog.restartconfirmation.text=Chcete restartovat Azurea?
-deletetorrent.message1=Chcete smazat TORRENT z :\n
-deletetorrent.message2=\nJste si jist\u00fd, \u017ee chete pokra\u010dovat?
-ConfigView.label.prioritizemostcompletedfiles=Up\u0159ednost\u0148ovat jen dokon\u010den\u00e9 soubory
-splash.plugin.init=Aktualizace Plugin: 
-ConfigView.section.style.osx_small_fonts=Pou\u017e\u00edt mal\u00e9 fonty [vy\u017eaduje restart]
-ConfigView.section.tracker.tcpnonblocking=Pou\u017e\u00edvejte neblokov\u00e1n\u00ed I/O pro zpracov\u00e1n\u00ed TCP trackeru. Vybr\u00e1n\u00ed t\u00e9to volby vy\u017eaduje p\u0159id\u011blen\u00ed alternativn\u00edho portu pro server. Experiment\u00e1ln\u00ed mo\u017enost!
-ConfigView.section.tracker.nonblocking=Neblokujic\u00ed mo\u017enosti
-ConfigView.section.tracker.nonblockingconcmax=Maximum soub\u011b\u017en\u00fdch p\u0159ipojen\u00ed [0: bezlimitu]
-ConfigView.group.scrape=Probl\u00e9m
-ConfigView.section.tracker.client.scrapeinfo=Zak\u00e1z\u00e1n\u00edm scraping zabr\u00e1nite torrent\u016fm \u0159azen\u00ed se do fronty dle pravidel spoleh\u00e1j\u00edc\u00ed jen na informace swarmu z\u00edskan\u00e9 scrapingem tracker\u016f.
+MainWindow.dialog.restartconfirmation.title=Restartovat Vuze
+MainWindow.dialog.restartconfirmation.text=Opravdu chcete restartovat Vuze
+ConfigView.label.prioritizemostcompletedfiles=Up\u0159ednost\u0148ovat d\u00e1le soubory s Vysokou prioritou podle % dokon\u010den\u00ed a velikosti souboru
+splash.plugin.init=Zav\u00e1d\u00edm Z\u00e1suvn\u00fd Modul:
+splash.plugin.UIinit=Zav\u00e1d\u00edm Rozhran\u00ed Z\u00e1suvn\u00e9ho Modulu: %1
+ConfigView.section.style.osx_small_fonts=Pou\u017e\u00edt mal\u00e9 p\u00edsmo [vy\u017eaduje restart]
+ConfigView.section.tracker.tcpnonblocking=Pou\u017e\u00edt neblokuj\u00edc\u00ed I/O pro zpracov\u00e1n\u00ed TCP trackeru. Vybr\u00e1n\u00ed t\u00e9to volby vy\u017eaduje, aby internet trackeru b\u011b\u017eel na alternativn\u00edm portu. Experiment\u00e1ln\u00ed!
+ConfigView.section.tracker.nonblocking=Neblokuj\u00edc\u00ed mo\u017enosti
+ConfigView.section.tracker.nonblockingconcmax=Maximum soub\u011b\u017en\u00fdch p\u0159ipojen\u00ed [0: neomezen\u011b]
+MyTorrentsView.menu.exportmenu=Exportovat
+ConfigView.section.tracker.client.scrapeinfo=Zak\u00e1z\u00e1n\u00edm scrapingu zabr\u00e1n\u00ed mnoho pravidl\u016fm za\u0159azov\u00e1n\u00ed torrent\u016f do fronty fungovat, proto\u017ee spol\u00e9haj\u00ed na informace o mno\u017estv\u00ed \u00fa\u010dastn\u00edk\u016f z\u00edskan\u00e9 scrapov\u00e1n\u00edm tracker\u016f.
 ConfigView.section.tracker.client.scrapeenable=Povolit scraping
-ConfigView.section.tracker.client.scrapestoppedenable=Scrape torrenty, kter\u00e9 neb\u011b\u017e\u00ed
+ConfigView.section.tracker.client.scrapestoppedenable=Scrapovat torrenty, kter\u00e9 neb\u011b\u017e\u00ed
 Scrape.status.disabled=Scrape zak\u00e1z\u00e1n
 MyTorrentsView.menu.explore=Zobrazit soubor
-MyTorrentsView.menu.explore._mac=Zobrazit vyhled\u00e1v\u00e1n\u00ed
-MyTorrentsView.menu.explore._windows=Zobrazit Explorer
-wizard.maketorrents.autohost=Hostitel torrent\u016f m\u00e1 vytvo\u0159en\u00fd server
-ConfigView.label.overrideip=IP adresa pos\u00edlan\u00e1 trackeru - Pou\u017eijte pouze pokud v\u00edte, pro\u010d to pot\u0159ebujete! 
-ConfigView.label.overrideip.tooltip=Informace pro sever z r\u016fzn\u00fdch  IP adres pro odch\u00e1zej\u00edc\u00ed a p\u0159ich\u00e1zej\u00edc\u00ed pakety.  Tuto volbu nepou\u017e\u00edvejte.
+MyTorrentsView.menu.explore._mac=Zobrazit Ve Vyhled\u00e1va\u010di
+MyTorrentsView.menu.explore._windows=Zobrazit V Pr\u016fzkumn\u00edku
+wizard.maketorrents.autohost=Hostovat torrent na zabudovan\u00e9m trackeru
+ConfigView.label.overrideip=Potla\u010dit IP ozn\u00e1men\u00ed trackeru - odd\u011blte st\u0159edn\u00edkem, pokud je toto pro v\u00edce s\u00edt\u00ed
+ConfigView.label.overrideip.tooltip=Informuje tracker o r\u016fzn\u00fdch IP adres\u00e1ch, ne\u017e z kter\u00fdch odch\u00e1zej\u00ed a p\u0159ich\u00e1zej\u00ed pakety. Nechejte pr\u00e1zdnou pokud tuto volbu nechcete pou\u017e\u00edvat.
 ConfigView.section.connection.group.networks=S\u00edt\u011b
-ConfigView.section.connection.group.networks.info=Vyberte standartn\u00ed povolen\u00e9 s\u00ed\u0165\u011b pro p\u0159enos dat mezi klienty
-ConfigView.section.connection.networks.prompt=Vyzvat k v\u00fdb\u011bru, kdy\u017e je p\u0159id\u00e1no stahov\u00e1n\u00ed z anonymn\u00edho trackeru
+ConfigView.section.connection.group.networks.info=Vyberte standardn\u00ed povolen\u00e9 s\u00edt\u011b pro p\u0159enos dat mezi klienty
+ConfigView.section.connection.networks.prompt=Vyzvat k v\u00fdb\u011bru, kdy\u017e je p\u0159id\u00e1no stahov\u00e1n\u00ed s anonymn\u00edm trackerem
 ConfigView.section.connection.networks.Public=Ve\u0159ejn\u00e1 IP s\u00ed\u0165 (neanonymn\u00ed)
 ConfigView.section.connection.networks.I2P=I2P s\u00ed\u0165 
-ConfigView.section.connection.networks.Tor=Router (Tor) s\u00ed\u0165
-TableColumn.header.networks=S\u00ed\u0165
-TableColumn.header.networks.info=S\u00ed\u0165 povoluje  peer-peer data spojen\u00ed
+ConfigView.section.connection.networks.Tor=S\u00ed\u0165 Onion Router (Tor)
+TableColumn.header.networks=S\u00edt\u011b
+TableColumn.header.networks.info=S\u00edt\u011b povolen\u00e9 pro komunikaci dat klient ke klientovi
 Scrape.status.networkdisabled=S\u00ed\u0165 nen\u00ed povolena
 ConfigView.section.tracker.server.group.networks=S\u00edt\u011b
-ConfigView.section.tracker.server.group.networks.info=Vyberte s\u00edt\u011b pro kter\u00e9 tracker p\u0159ijme stahuji\u00edc\u00ed u\u017eivatele
-window.networkselection.title=Vybrat s\u00ed\u0165
-window.networkselection.info=Torrent uvedeny dole v seznamu servru(u) podporuje n\u00e1sleduj\u00edc\u00ed s\u00edt\u011b.\nPovolte jeden server pro p\u0159\u00edm\u00e9 p\u0159ipojen\u00ed.\nJestli je to anonimn\u00ed server, kter\u00fd podporuje ve\u0159ejn\u00e9 klienty povol\u00edte anonimn\u00ed publikov\u00e1n\u00ed na s\u00edti.\nPovolen\u00ed ve\u0159ejn\u00e9 s\u00edt\u011b m\u00e1 z\u0159ejm\u011b za n\u00e1sledek odstran\u011bn\u00ed anonymity!
+ConfigView.section.tracker.server.group.networks.info=Vyberte s\u00edt\u011b pro kter\u00e9 tracker bude p\u0159ij\u00edmat klienty
+window.networkselection.title=Zvolen\u00ed S\u00edt\u011b
+window.networkselection.info=Torrent uveden\u00e9 n\u00ed\u017ee maj\u00ed tracker(y), kter\u00fd podporuje n\u00e1sleduj\u00edc\u00ed s\u00edt\u011b.\nVyberte ty, kter\u00e9 maj\u00ed b\u00fdt povoleny pro komunikaci s trackerem a klientem.\nJestli je to anonymn\u00ed tracker, kter\u00fd podporuje ve\u0159ejn\u00e9 klienty povolte anonymn\u00ed i ve\u0159ejn\u00e9 s\u00edt\u011b.\nPovolen\u00edm ve\u0159ejn\u00e9 s\u00edt\u011b m\u00e1 jasn\u00fd n\u00e1sledek odstran\u011bn\u00ed anonymity!
 plugins.basicview.clear=Vy\u010distit
-ConfigView.section.connection.group.peersources=Stahujic\u00ed zdroje
+ConfigView.section.connection.group.peersources=Zdroje Klient\u016f
 ConfigView.section.connection.group.peersources.info=Vyberte standartn\u00ed p\u0159\u00edpustn\u00e9 zdroje pro p\u0159ipojen\u00ed klient\u016f
-ConfigView.section.connection.peersource.Tracker=Ze trackeru
+ConfigView.section.connection.peersource.Tracker=Z trackeru
 ConfigView.section.connection.peersource.DHT=Decentralizovan\u00e9 stahov\u00e1n\u00ed
-ConfigView.section.connection.peersource.PeerExchange=Dodan\u00fd jin\u00fdm u\u017eivatelem
-ConfigView.section.connection.peersource.Plugin=P\u0159idan\u00fd p\u0159es plugin
+ConfigView.section.connection.peersource.PeerExchange=Dodan\u00fd jin\u00fdm klientem
+ConfigView.section.connection.peersource.Plugin=P\u0159idan\u00fd p\u0159es z\u00e1suvn\u00fd modul
 ConfigView.section.connection.peersource.Incoming=P\u0159\u00edchoz\u00ed p\u0159ipojen\u00ed
-PeersView.source=Zdroje
-PeersView.source.info=Zdroje od u\u017eivatel\u016f
-TableColumn.header.peersources=Klienti
-TableColumn.header.peersources.info=Klienti, kte\u0159\u00ed maj\u00ed povoleno nav\u00e1z\u00e1n\u00ed p\u0159ipojen\u00ed
-wizard.tracker.dht=Decentralizovan\u011b jen (klienty Azureusu )
+PeersView.source=Zdroj
+PeersView.source.info=Zdroj tohoto klienta
+TableColumn.header.peersources=Zdroje Klient\u016f
+TableColumn.header.peersources.info=Zdroje klient\u016f, kter\u00fdm je povoleno vytvo\u0159it spojen\u00ed klient\u016f
+wizard.tracker.dht=Decentralizovan\u00fd (pouze Vuze klienti)
 MyTorrentsView.menu.advancedmenu=Pokro\u010dil\u00e9
 MyTorrentsView.menu.networks=S\u00edt\u011b
-MyTorrentsView.menu.peersource=Zdroje klient\u016f
-ConfigView.section.sharing.permitdht=Povolit decentralizovanou distrubuci, kdy\u017e je server nedostupn\u00fd
-ConfigView.section.sharing.protocol=Protokol pro spole\u010dn\u00e9 sd\u00edlen\u00ed zdroj\u016f
+MyTorrentsView.menu.peersource=Zdroje Klient\u016f
+ConfigView.section.sharing.permitdht=Povolit decentralizovanou sledov\u00e1n\u00ed, kdy\u017e je tracker nedostupn\u00fd
+ConfigView.section.sharing.protocol=Protokol pro klasicky sd\u00edlen\u00e9 zdroje
 PeersView.Messaging=Zpr\u00e1vy
-PeersView.Messaging.info=Podporuje pokro\u010dil\u00e9 zpr\u00e1vy API.
-ConfigView.label.queue.newseedsmovetop=Zobrazit nov\u00e9 kompletn\u00ed torrenty na za\u010d\u00e1tku stahovac\u00edho seznamu
-ConfigView.label.seeding.firstPriority.ignore.info=M\u011bjte na pam\u011bti, \u017ee pou\u017e\u00edt\u00ed t\u011bchto pravidel, m\u016f\u017ee m\u00edt za n\u00e1sledek zastaven\u00ed  torrentu hned jak bude stahov\u00e1n\u00ed ukon\u010deno.
-ConfigView.label.seeding.firstPriority.ignore=Ignorovat pravidla top priority pro:
+PeersView.Messaging.info=Uv\u00e1d\u00ed, kter\u00fd syst\u00e9m odes\u00edl\u00e1n\u00ed zpr\u00e1v se pou\u017e\u00edv\u00e1.
+ConfigView.label.queue.newseedsmovetop=P\u0159esunout nov\u011b dokon\u010den\u00e9 torrenty do fronty seznamu distribuce
+ConfigView.label.seeding.firstPriority.ignore.info=M\u011bjte na pam\u011bti, \u017ee pou\u017eit\u00edm t\u011bchto pravidel, m\u016f\u017ee torrent zastavit\n hned jak je stahov\u00e1n\u00ed dokon\u010deno.
+ConfigView.label.seeding.firstPriority.ignore=Ignorovat pravidla Prvn\u00ed Priority v\u00fd\u0161e pro:
 ConfigView.label.seeding.firstPriority.ignoreSPRatio=Torrenty s pom\u011brem distribuj\u00edc\u00ed/stahuj\u00edc\u00ed v\u011bt\u0161\u00edm ne\u017e
 ConfigView.label.seeding.firstPriority.ignore0Peer=Torrenty s 0 u\u017eivateli
-ConfigView.section.tracker.sendjavaversionandos=Poslat versi Java a n\u00e1zev opera\u010dn\u00edho syst\u00e9mu
-MagnetPlugin.contextmenu.exporturi=Kop\u00edrovat Magnet URI do schr\u00e1nky
-ConfigView.section.plugins.dht=Distrubuovan\u00e1 datab\u00e1ze
-dht.info=Tento dopln\u011bk podporuje decentralizovan\u00e9 distribuov\u00e1n\u00ed, mezi dal\u0161\u00edmi v\u011bcmi, - zak\u00e1z\u00e1n\u00ed bude redukovat Va\u0161i schopnost stahovat
-dht.enabled=Povolit distribuci database
-dht.portdefault=Pou\u017eijte standartn\u00ed port
-dht.port=UDP port pro database
-dht.execute.command=Diagnostiku p\u0159\u00edkaz\u016f
-dht.execute.info=Stiskni k vykon\u00e1n\u00ed p\u0159\u00edkazu
+ConfigView.section.tracker.sendjavaversionandos=Poslat verzi Java a n\u00e1zev OS
+MagnetPlugin.contextmenu.exporturi=Kop\u00edrovat Magnet URI do Schr\u00e1nky
+ConfigView.section.plugins.dht=Distribuovan\u00e1 Datab\u00e1ze
+dht.info=Tento z\u00e1suvn\u00fd modul podporuje decentralizovan\u00e9 sledov\u00e1n\u00ed, mezi dal\u0161\u00edmi v\u011bcmi, - zak\u00e1z\u00e1n\u00edm zmen\u0161\u00edte Va\u0161i schopnost stahovat
+dht.enabled=Povolit distribuovanou datab\u00e1zi
+dht.portdefault=Pou\u017e\u00edt v\u00fdchoz\u00ed port
+dht.port=UDP port pro datab\u00e1zi
+dht.execute.command=Diagnostick\u00fd p\u0159\u00edkaz
+dht.execute.info=Stisknout k vykon\u00e1n\u00ed p\u0159\u00edkazu
 dht.execute=Spustit
-dht.logging=Povolit sledov\u00e1n\u00ed aktivit
-ConfigView.section.plugins.dhttracker=Distribuovan\u00fd server
-dhttracker.tracknormalwhenoffline=Jen stopa pro norm\u00e1ln\u00ed torrenty, kdy\u017e je jejich sever nedostupn\u00fd
+dht.logging=Povolit sledov\u00e1n\u00ed aktivity
+ConfigView.section.plugins.dhttracker=Distribuovan\u00fd Tracker
+dhttracker.tracknormalwhenoffline=Sledovat norm\u00e1ln\u00ed torrenty pouze, kdy\u017e je jejich tracker nedostupn\u00fd
 ConfigView.section.file.nativedelete._mac=Pou\u017e\u00edt Ko\u0161 p\u0159i maz\u00e1n\u00ed soubor\u016f
-ConfigView.section.file.nativedelete._windows=P\u0159esunout smazan\u00e9 soubory do ko\u0161e
-ConfigView.section.logging.generatediagnostics=Generovat
-ConfigView.section.logging.generatediagnostics.info=Generovat diagnostick\u00e9 informace a kop\u00edrovat je do schr\u00e1nky a do zaznamen\u00e1vac\u00edho souboru, jestli je nasteveno
-ConfigView.section.sharing.privatetorrent=Soukrom\u00fd torrent - p\u0159ijme jen u\u017eivatele ze trackeru
-MainWindow.menu.tools.nattest=Test &NAT / internetov\u00e9 ochrany
+ConfigView.section.file.nativedelete._windows=P\u0159esunout smazan\u00e9 soubory do Ko\u0161e
+ConfigView.section.logging.generatediagnostics=Vytvo\u0159it
+ConfigView.section.logging.netinfo=Vytvo\u0159it informace o s\u00edti
+ConfigView.section.logging.statsinfo=Vytvo\u0159it informace o statistice
+ConfigView.section.logging.generatediagnostics.info=Vytvo\u0159it diagnostick\u00e9 informace a zkop\u00edrovat je do schr\u00e1nky a souboru z\u00e1znamu, pokud je tak nastaveno
+ConfigView.section.sharing.privatetorrent=Soukrom\u00fd torrent - klienty p\u0159ij\u00edmat pouze z trackeru
+MainWindow.menu.tools.nattest=Zkou\u0161ka &NAT / Firewallu...
 Button.apply=Pou\u017e\u00edt
 Button.close=Zav\u0159\u00edt
-window.welcome.title=V\u00edtejte v Azureu %1
+window.welcome.title=V\u00edtejte ve Vuze %1
 #file can be a URL or a path in the jar
 MainWindow.menu.help.releasenotes=Pozn\u00e1mky o vyd\u00e1n\u00ed
-dht.reseed.label=Norm\u00e1ln\u00ed znovudistribuce datab\u00e1ze nen\u00ed nutn\u00e9. Nicm\u00e9n\u011b je-li po\u010det p\u0159ipojen\u00ed n\u00edzk\u00fd, m\u016f\u017eete pou\u017e\u00edt znovuintegraci.\nPonechte pole pr\u00e1zdn\u00e9 pro samozaveden\u00ed p\u0159ipojen\u00fdch klient\u016f nebo vpi\u0161te IP adresu a port pro vylou\u010den\u00ed samozaveden\u00ed od zn\u00e1m\u00e9ho klienta.
-dht.reseed.group=Znovudistribuovat
+dht.reseed.label=V\u011bt\u0161inou znovudistribuce datab\u00e1ze nen\u00ed nutn\u00e1. Nicm\u00e9n\u011b je-li po\u010det p\u0159ipojen\u00ed n\u00edzk\u00fd, toto m\u016f\u017ee b\u00fdt pou\u017e\u00edto pro znovuintegraci.\nPonechte pr\u00e1zdn\u00e9 pro zaveden\u00ed od  p\u0159ipojen\u00fdch klient\u016f nebo zadejte IP adresu a port pro v\u00fdslovn\u00e9 zaveden\u00ed od zn\u00e1m\u00e9ho klienta.
+dht.reseed.group=Znovu distribuovat
 dht.reseed.ip=IP adresa
-dht.reseed=Znovudistribuovat
-dht.reseed.info=Znovudistribuovat datab\u00e1zi
+dht.reseed=Znovu distribuovat
+dht.reseed.info=Znovu distribuovat datab\u00e1zi
 dht.diagnostics.group=Diagnostika
-DHTView.title.full=Distribuce Database
-DHTView.title.fullcvs=Distribuce Database CVS
+DHTView.title.full=Distribuovan\u00e1 Datab\u00e1ze
+DHTView.title.fullcvs=Distribuovan\u00e1 Datab\u00e1ze CVS
 DHTView.general.title=Hlavn\u00ed
-DHTView.general.uptime=Doba provozuschopnosti:
-DHTView.general.users=U\u017eivatel:
-DHTView.general.nodes=Uzel: 
-DHTView.general.leaves=Odchoz\u00ed:
-DHTView.general.contacts=kontakty:
+DHTView.general.uptime=Doba spu\u0161t\u011bn\u00ed:
+DHTView.general.users=U\u017eivatel\u00e9:
+DHTView.general.nodes=Uzly: 
+DHTView.general.leaves=Opou\u0161t\u011bj\u00edc\u00ed:
+DHTView.general.contacts=Kontakty:
 DHTView.general.replacements=Nahrazen\u00ed:
-DHTView.general.live=Funk\u010dn\u00ed:
+DHTView.general.live=\u017div\u00ed:
 DHTView.general.unknown=Nezn\u00e1m\u00ed:
 DHTView.general.dying=Um\u00edraj\u00edc\u00ed:
-DHTView.transport.title=Detaily p\u0159enosu
+DHTView.transport.title=Podrobnosti p\u0159enosu
 DHTView.transport.packets=Pakety
-DHTView.transport.bytes=Byt\u016f
+DHTView.transport.bytes=Bajt\u016f
 DHTView.transport.received=P\u0159ijato
 DHTView.transport.sent=Odesl\u00e1no
 DHTView.transport.in=Vstup:
 DHTView.transport.out=V\u00fdstup:
-DHTView.operations.title=Detaily operace
+DHTView.operations.title=Podrobnosti operace
 DHTView.operations.sent=Odesl\u00e1no
 DHTView.operations.failed=Ne\u00fasp\u011b\u0161n\u011b
 DHTView.operations.received=P\u0159ijato
-DHTView.operations.ping=Odezva serveru
-DHTView.operations.findNode=Naj\u00edt uzel
-DHTView.operations.findValue=Naj\u00edt hodnotu
+DHTView.operations.ping=Odezva
+DHTView.operations.findNode=Naj\u00edt Uzel
+DHTView.operations.findValue=Naj\u00edt Hodnotu
 DHTView.operations.store=Ulo\u017ei\u0161t\u011b
-DHTView.activity.title=Aktivita
+DHTView.activity.title=\u010cinnost
 DHTView.activity.status=Stav
 DHTView.activity.status.true=Ve front\u011b
-DHTView.activity.status.false=Spustit
+DHTView.activity.status.false=B\u011b\u017e\u00ed
 DHTView.activity.type=Typ
 DHTView.activity.type.1=Vnit\u0159n\u00ed  Get
 DHTView.activity.type.2=Vn\u011bj\u0161\u00ed Get
 DHTView.activity.type.3=Vnit\u0159n\u00ed Put
 DHTView.activity.type.4=Vn\u011bj\u0161\u00ed Put
 DHTView.activity.target=C\u00edl
-DHTView.activity.details=Detaily
+DHTView.activity.details=Podrobnosti
 DHTView.db.title=Datab\u00e1ze
-DHTView.db.keys=Kl\u00ed\u010d
-DHTView.db.values=Hodnota
+DHTView.db.keys=Kl\u00ed\u010de
+DHTView.db.values=Hodnoty
 DHTView.db.local=M\u00edstn\u00ed
-DHTView.db.direct=P\u0159\u00edm\u00e9 spoejn\u00ed
-DHTView.db.indirect=Nep\u0159\u00edm\u00e9 spojen\u00ed
-DHTView.db.divfreq=Frekvence Div.
-DHTView.db.divsize=Velikost Div.
-MainWindow.dht.status.tooltip=Kdy\u017e je spu\u0161t\u011bna distribuovan\u00e1 datab\u00e1ze, je zobrazen aktu\u00e1ln\u00ed po\u010det p\u0159ipojen\u00fdch u\u017eivatel\u016f.
-MainWindow.dht.status.disabled=Zak\u00e1z\u00e1no
-MainWindow.dht.status.failed=Selh\u00e1n\u00ed
-MainWindow.dht.status.initializing=Inicializace
-MainWindow.dht.status.users=%1 U\u017eivatel\u00e9
-MainWindow.dht.status.unreachable=K DHT se nelze p\u0159ipojit kv\u016fli Va\u0161\u00ed internetov\u00e9 ochran\u011b.
-MainWindow.dht.status.unreachabletooltip=V distribuovan\u00e9 datab\u00e1zi pravd\u011bpodobn\u011b je probl\u00e9m s UDP portem mapov\u00e1n\u00ed  (NAT/firewall).
-MyTorrentsView.menu.setUpSpeed=nastavit rychlost odes\u00edl\u00e1n\u00ed
-MyTorrentsView.menu.setDownSpeed=Nastavit rychlost stahov\u00e1n\u00ed
-ConfigView.section.tracker.client.showwarnings=Zobrazit v\u00fdstra\u017en\u00e9 zpr\u00e1vy trackeru
-dht.advanced=Povolit pokro\u010dil\u00e9 nastaven\u00ed
-dht.advanced.group=Pokro\u010dil\u00e9 nastaven\u00ed
-dht.advanced.label=Pou\u017eijte tyto hodnoty, jestli\u017ee skute\u010dn\u011b v\u00edte, co d\u011bl\u00e1te
-dht.override.ip=Ov\u011b\u0159it extern\u00ed  IP adresu
-ConfigView.section.logging.loggerenable=Povolit logov\u00e1n\u00ed
+DHTView.db.direct=P\u0159\u00edm\u00e9
+DHTView.db.indirect=Nep\u0159\u00edm\u00e9
+DHTView.db.divfreq=D\u011blen\u00ed Frekvence
+DHTView.db.divsize=Velikost D\u011blen\u00ed
+MainWindow.dht.status.tooltip=Kdy\u017e distribuovan\u00e1 datab\u00e1ze b\u011b\u017e\u00ed, toto zobrazuje odhadnut\u00fd po\u010det u\u017eivatel\u016f, kte\u0159\u00ed jsou v sou\u010dasnosti online.
+MainWindow.dht.status.disabled=DHT Zak\u00e1z\u00e1no
+MainWindow.dht.status.failed=DHT Selhalo
+MainWindow.dht.status.initializing=Spou\u0161t\u011bn\u00ed DHT
+MainWindow.dht.status.users=%1 u\u017eivatel\u016f
+MainWindow.dht.status.unreachable=DHT Je Za Firewallem
+MainWindow.dht.status.unreachabletooltip=Vypad\u00e1 to, \u017ee je probl\u00e9m s mapov\u00e1n\u00edm portu UDP Distribuovan\u00e9 Datab\u00e1ze (NAT/firewall)
+MyTorrentsView.menu.setUpSpeed=Nastavit Rychlost Odes\u00edl\u00e1n\u00ed
+MyTorrentsView.menu.setDownSpeed=Nastavit Rychlost Stahov\u00e1n\u00ed
+ConfigView.section.tracker.client.showwarnings=Zobrazit varovn\u00e9 zpr\u00e1vy hl\u00e1\u0161en\u00e9 trackerem
+dht.advanced=Povolit pokro\u010dil\u00e1 nastaven\u00ed
+dht.advanced.group=Pokro\u010dil\u00e1 nastaven\u00ed
+dht.advanced.label=Tyto hodnoty upravte pouze, pokud skute\u010dn\u011b v\u00edte, co d\u011bl\u00e1te
+dht.override.ip=Potla\u010dit extern\u00ed IP adresu
+ConfigView.section.logging.loggerenable=Povolit z\u00e1znam
 ConfigView.section.ipfilter.blockbanning=Zak\u00e1zat blok 256 IP adres, pokud alespo\u0148 toto mno\u017estv\u00ed z bloku bylo zak\u00e1z\u00e1no
 MyTrackerView.passive=Pasivn\u00ed
-TableColumn.header.swarm_average_speed=Swarm Pr\u016fm\u011brn\u00e1 rychlost
-TableColumn.header.swarm_average_speed.info=Pr\u016fm\u011brn\u00e1 rychlost  peers in the swarm
+TableColumn.header.swarm_average_speed=Pr\u016fm\u011brn\u00e1 Rychlost \u00da\u010dastn\u00edk\u016f
+TableColumn.header.swarm_average_speed.info=Pr\u016fm\u011brn\u00e1 rychlost klient\u016f v po\u010dtu \u00fa\u010dastn\u00edk\u016f
+TableColumn.header.comment=Koment\u00e1\u0159
+TableColumn.header.comment.info=U\u017eivatelem stanoven\u00fd koment\u00e1\u0159 pro stahov\u00e1n\u00ed
+TableColumn.header.commenticon=Ikona Koment\u00e1\u0159e
+TableColumn.header.commenticon.info=Zobraz\u00ed ikonu, pokud m\u00e1 stahov\u00e1n\u00ed u\u017eivatelem stanoven\u00fd koment\u00e1\u0159
 MyTrackerView.category=Kategorie
-MainWindow.menu.file.open.torrentfortracking=Torrent Soubory... (Tracking Only)
+MainWindow.menu.file.open.torrentfortracking=Soubor Torrent...(Pouze pro Sledov\u00e1n\u00ed)
 MyTrackerView.date_added=P\u0159id\u00e1no
-ConfigView.section.tracker.portbackup=Z\u00e1lo\u017en\u00ed port (odd\u011blte st\u0159edn\u00edkem ";")
-ConfigView.label.playfilespeech=Ozn\u00e1mit kdy\u017e je soubor ukon\u010den
-ConfigView.label.playfilespeech.info=Hovorov\u00e9 slu\u017eby pracuji jen s angli\u010dtinou
-ConfigView.label.playfilefinished=P\u0159ehraje zvuk p\u0159i ukon\u010den\u00ed souboru
-ConfigView.label.backupconfigfiles=Z\u00e1lo\u017en\u00ed konfigura\u010dn\u00ed soubory pro obnoven\u00ed
-ConfigView.section.tracker.client.scrapesingleonly=Zak\u00e1zat scrape agregaci pro ka\u017ed\u00fd torrent (m\u016f\u017ee pomoci tracker\u016fm, kter\u00e9 hl\u00e1s\u00ed chybu 'URL too long' (414)) 
+ConfigView.section.tracker.portbackup=Z\u00e1lo\u017en\u00ed porty (odd\u011blte ";")
+ConfigView.label.playfilespeech=Promluvit, kdy\u017e je soubor dokon\u010den
+ConfigView.label.playfilespeech.info=Hlasov\u00e9 Slu\u017eby sou\u010dasn\u011b funguj\u00ed nejl\u00e9pe v Angli\u010dtin\u011b
+ConfigView.label.playfilefinished=P\u0159ehr\u00e1t zvuk, kdy\u017e je soubor dokon\u010den
+ConfigView.label.backupconfigfiles=Z\u00e1lo\u017en\u00ed konfigura\u010dn\u00ed soubory pro \u00fa\u010dely obnoven\u00ed
+ConfigView.section.tracker.client.scrapesingleonly=Zak\u00e1zat hromad\u011bn\u00ed scrape pro ka\u017ed\u00fd tracker (m\u016f\u017ee pomoci tracker\u016fm, kter\u00e9 hl\u00e1s\u00ed chyby 'URL too long' (414)) 
 dht.ipfilter.log=Zapisovat naru\u0161en\u00ed IP Filtru 
-ConfigView.label.seeding.addForSeedingDLCopyCount=P\u0159id\u00e1 do stahovac\u00edho seznamu  downloads, a vyp\u00ed\u0161e po\u010det sta\u017een\u00fdch kopii
-ActivityView.legend.limit=Rychlostn\u00ed  limit
+ConfigView.label.seeding.addForSeedingDLCopyCount=Pova\u017eovat, \u017ee stahov\u00e1n\u00ed 'p\u0159idan\u00e1 pro distribuci' st\u00e1hla takov\u00fd po\u010det kopi\u00ed
+ActivityView.legend.limit=Rychlostn\u00ed limit
 ActivityView.legend.achieved=Dosa\u017een\u00e1 rychlost
+ActivityView.legend.overhead=Rychlost zpracov\u00e1n\u00ed
 ActivityView.legend.peeraverage=Pr\u016fm\u011br
-ActivityView.legend.swarmaverage=Pr\u016fm\u011br sd\u00edlen\u00ed
-MyTorrentsView.menu.movemenu=P\u0159esunout soubor
-MyTorrentsView.menu.movedata=P\u0159esunout datov\u00e9 soubory....
-MyTorrentsView.menu.movetorrent=P\u0159esunout torrent soubory...
-MyTorrentsView.menu.movedata.dialog=Vyberta nov\u00e9 um\u00edst\u011bn\u00ed
+ActivityView.legend.swarmaverage=Pr\u016fm\u011br po\u010dtu \u00fa\u010dastn\u00edk\u016f
+ActivityView.legend.trimmed=Limit (te\u010dkovan\u011b)
+MyTorrentsView.menu.movemenu=P\u0159esunout Soubory
+MyTorrentsView.menu.movedata=P\u0159esunout Datov\u00e9 Soubory....
+MyTorrentsView.menu.movetorrent=P\u0159esunout Torrent Soubor...
+MyTorrentsView.menu.movedata.dialog=Vyberte nov\u00e9 um\u00edst\u011bn\u00ed
 DHTView.general.reachable=Dosa\u017eiteln\u00fd:
 DHTView.general.rendezvous=Setk\u00e1n\u00ed:
-ConfigView.label.queue.maxactivetorrentswhenseeding=Max. po\u010det stah. u\u017eivatel\u016f [0: neomezen\u011b]
-Views.plugins.IRC.title=IRC - Online Technick\u00e1 popora
-Formats.units.persec=za s
+ConfigView.label.queue.maxactivetorrentswhenseeding=Max kdy\u017e pouze distribuujete [0:neomezen\u011b]
+Views.plugins.IRC.title=IRC - Online Technick\u00e1 podpora
 Formats.units.alot=Hodn\u011b !!!
-ConfigView.section.ipfilter.persistblocking=Ulo\u017eit blokovan\u00e9 detaily IP adres po restartu
+ConfigView.section.ipfilter.persistblocking=Ulo\u017eit blokovan\u00e9 podrobnosti IP po restartech
 FilesView.menu.rename=P\u0159ejmenovat nebo zm\u011bnit c\u00edl
+FilesView.menu.rename_only=Rychle P\u0159ejmenovat
+FilesView.menu.retarget=P\u0159esunout Soubory
 FilesView.rename.choose.path=Vyberte nov\u00fd nebo existuj\u00edc\u00ed soubor
-FilesView.rename.confirm.delete.title=Potvr\u010fte  smaz\u00e1n\u00ed
-FilesView.rename.confirm.delete.text=Potvr\u010fte smaz\u00e1n\u00ed origin\u00e1ln\u00edho souboru '%1'
-ConfigView.section.mode=M\u00f3d
+FilesView.rename.choose.path.dir=Vyberte nov\u00fd nebo existuj\u00edc\u00ed adres\u00e1\u0159
+FilesView.rename.confirm.delete.title=Potvr\u010fte Smaz\u00e1n\u00ed
+FilesView.rename.confirm.delete.text=Potvr\u010fte smaz\u00e1n\u00ed p\u016fvodn\u00edho souboru '%1'
+FilesView.rename.filename.title=P\u0159ejmenovat soubor
+FilesView.rename.filename.text=Zvolte nov\u00e9 jm\u00e9no souboru
+ConfigView.higher.mode.available=Dal\u0161\u00ed mo\u017enosti jsou dostupn\u00e9 ve vy\u0161\u0161\u00edch u\u017eivatelsk\u00fdch re\u017eimech
+ConfigView.section.mode=Re\u017eim
 ConfigView.section.mode.title=U\u017eivatelsk\u00e9 znalosti
 ConfigView.section.mode.beginner=Za\u010d\u00e1te\u010dn\u00edk
-ConfigView.section.mode.beginner.wiki.definitions=BitTorrent slovn\u00edk
+ConfigView.section.mode.beginner.wiki.definitions=Slovn\u00edk Bittorent
 ConfigView.section.mode.intermediate=St\u0159edn\u011b zku\u0161en\u00fd
-ConfigView.section.mode.intermediate.wiki.host=Nab\u00edzen\u00e9 soubory
-ConfigView.section.mode.intermediate.wiki.publish=Publikovan\u00e9 soubory
+ConfigView.section.mode.intermediate.wiki.host=Hostov\u00e1n\u00ed Soubor\u016f
+ConfigView.section.mode.intermediate.wiki.publish=Publikov\u00e1n\u00ed Soubor\u016f
 ConfigView.section.mode.advanced=Pokro\u010dil\u00e9
 ConfigView.section.mode.advanced.wiki.main=Hlavn\u00ed str\u00e1nka Wiki
-ConfigView.section.mode.beginner.text=Obsahuje v\u0161e, co pot\u0159ebujete na stahov\u00e1n\u00ed torrent\u016f.\nPou\u017eijte tento m\u00f3d pokud chcete pouze stahovat a \u0159\u00eddit Va\u0161e torrenty.
-ConfigView.section.mode.intermediate.text=P\u0159\u00edstup k funkc\u00edm serveru.\nPou\u017eijte tento m\u00f3d, jestli\u017ee chcete vytvo\u0159it sv\u016fj server a hostovat/publkovat Va\u0161e soubory.
-ConfigView.section.mode.advanced.text=P\u0159\u00edstup k s\u00ed\u0165ov\u00e9mu nastaven\u00ed.\nPou\u017eijte tento m\u00f3d jen jestli v\u00edte co to je MTU nebo neblokovan\u00e9 I/O...
-Files.column.storagetype=Typ ulo\u017een\u00ed
+ConfigView.section.mode.beginner.text=Obsahuje v\u0161e, co pot\u0159ebujete ke stahov\u00e1n\u00ed torrent\u016f.\nPou\u017eijte tento re\u017eim pokud chcete pouze spravovat Va\u0161e torrenty.
+ConfigView.section.mode.intermediate.text=P\u0159\u00edstup k funkc\u00edm trackeru.\nPou\u017eijte tento re\u017eim, jestli\u017ee chcete vytvo\u0159it sv\u016fj tracker a hostovat/publikovat Va\u0161e soubory.
+ConfigView.section.mode.advanced.text=P\u0159\u00edstup k s\u00ed\u0165ov\u00e9mu nastaven\u00ed.\nPou\u017eijte tento re\u017eim pokud v\u00edte co to je MTU nebo neblokuj\u00edc\u00ed I/O...
+Files.column.storagetype=Typ Ulo\u017een\u00ed
+Files.column.fileext=Typ
 FileItem.storage.linear=Line\u00e1rn\u00ed
 FileItem.storage.compact=Kompaktn\u00ed
-MessageBoxWindow.rememberdecision=Zapamatovat moje rozhodnut\u00ed
-ConfigView.section.interface.cleardecisions=Smazat ulo\u017een\u00e9 dialogy
+MessageBoxWindow.rememberdecision=Zapamatovat si moje rozhodnut\u00ed
+ConfigView.section.interface.cleardecisions=Smazat zapamatovan\u00e9 rozhodnut\u00ed dialogov\u00fdch oken
 ConfigView.section.interface.cleardecisionsbutton=Vy\u010distit
-configureWizard.welcome.usermodes=Toto nastaven\u00ed odbornosti u\u017eivatele ur\u010d\u00ed, jak\u00e9 mo\u017enosti se budou zobrazovat v menu N\u00e1stroje > Mo\u017enosti. Je ve va\u0161em z\u00e1jmu nastavit \u00farove\u0148 podle skute\u010dnosti.
-FilesView.skip.confirm.delete.text=Zmen\u0161it soubor  '%1' pro ulo\u017een\u00ed?
-FilesView.rename.failed.title=P\u0159ejmenovat/\u0161patn\u00e9 zad\u00e1n\u00ed c\u00edle
-FilesView.rename.failed.text=Tato operace selhala, pravd\u011bpodobn\u011b kv\u016fli volb\u011b neplatn\u00e9ho c\u00edle
-diagnostics.log_found=Vuzenebyl ukon\u010den spr\u00e1vn\u011b. Pros\u00edm zkontrolujte %1 diagnostiku zaznamen\u00e1vac\u00edho souboru a zva\u017ete, zda tuto zpr\u00e1vu nahl\u00e1s\u00edte Vuze t\u00fdmu technick\u00e9 podpory, pokud jste chybu nezavinil Vy s\u00e1m. Tak\u00e9 zkontrolujte sekci 'Vuze Disappears' (ne\u010dekan\u00e1 vypnut\u00ed Azurea) ve Wiki (menu N\u00e1pov\u011bda).
-ManagerItem.paused=Pauza
-Utils.link.visit=\u010cekejte Pros\u00edm
+ConfigView.section.interface.cleartrackers=Vy\u010distit zapamatovan\u00e9 trackery
+ConfigView.section.interface.cleartrackersbutton=Vy\u010distit
+ConfigView.section.interface.clearsavepaths=Vy\u010distit zapamatovan\u00e9 cesty ulo\u017een\u00ed
+ConfigView.section.interface.clearsavepathsbutton=Vy\u010distit
+configureWizard.welcome.usermodes=Toto nastaven\u00ed Odbornosti U\u017eivatele ur\u010d\u00ed, jak\u00e1 \u00farove\u0148 mo\u017enost\u00ed se bude zobrazovat v menu N\u00e1stroje > Mo\u017enosti. Je ve Va\u0161em nejlep\u0161\u00edm z\u00e1jmu ji nastavit podle skute\u010dnosti.
+FilesView.skip.confirm.delete.text=O\u0159\u00edznout soubor '%1' k u\u0161et\u0159en\u00ed m\u00edsta?
+FilesView.rename.failed.title=P\u0159ejmenov\u00e1n\u00ed/Znovu zad\u00e1n\u00ed c\u00edle selhalo
+FilesView.rename.failed.text=Operace selhala, pravd\u011bpodobn\u011b kv\u016fli volb\u011b neplatn\u00e9ho c\u00edle
+diagnostics.log_found=Vuze nebyl ukon\u010den spr\u00e1vn\u011b. Zkontrolujte jak\u00e9koli <A HREF="%1">soubory se z\u00e1znamem diagnostiky</A>. Tak\u00e9 si p\u0159e\u010dt\u011bte \u010dl\u00e1nek wiki <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Zmizel</A> pro v\u00edce informac\u00ed.
+ManagerItem.paused=Pozastaveno
+Utils.link.visit=Nav\u0161tivte pros\u00edm
 ConfigView.section.connection.serverport.wiki=V\u00fdb\u011br dobr\u00fdch port\u016f
-ConfigView.section.transfer.speeds.wiki=Dob\u0159e nastaven\u00e1 rychlost
+ConfigView.section.transfer.speeds.wiki=Nastaven\u00ed pro dobrou rychlost
 installPluginsWizard.installMode.info.title=Informace
-installPluginsWizard.installMode.info.text=K pr\u00e1ci Azurea nepot\u0159ebujete tento dopln\u011bk, zm\u011bn\u00ed se jen dopl\u0148kov\u00e9 rysy, automatizace nebo d\u00e1lkov\u00e9 ovl\u00e1d\u00e1n\u00ed.\nPros\u00edm p\u0159e\u010dt\u011bte si ka\u017ed\u00fd popis dopl\u0148ku pe\u010dliv\u011b p\u0159edt\u00edm, ne\u017e se rozhodnete jej nainstalovat.\nV\u011bt\u0161ina plugin\u016f je bezpe\u010dn\u00e1 a d\u016fkladn\u011b ov\u011b\u0159en\u00e1, av\u0161ak nedoporu\u010duje [...]
-Views.plugins.Distributed.DB.title=Distribuce DB
-Views.plugins.Distributed.Tracker.title=Distribuce servru
-openUrl.url.info=Podporuje http, https, magnet and hexadecim\u00e1ln\u00ed  infohash \u0159et\u011bzce
-TableColumn.header.swarm_average_completion=Pr\u016fm\u011brn\u00e9 dokon\u010den\u00ed klient\u016f
-TableColumn.header.swarm_average_completion.info=Pr\u016fm\u011brn\u00e9 procento dokon\u010den\u00ed stahov\u00e1n\u00ed klienty v torrentu
+installPluginsWizard.installMode.info.text=Z\u00e1suvn\u00e9 moduly ke spr\u00e1vn\u00e9mu fungov\u00e1n\u00ed Vuze nepot\u0159ebujete, p\u0159in\u00e1\u0161ej\u00ed pouze dopl\u0148kov\u00e9 funkce pro z\u00e1bavu, automatizaci nebo d\u00e1lkov\u00e9 ovl\u00e1d\u00e1n\u00ed.\nTak\u017ee si pros\u00edm pe\u010dliv\u011b p\u0159e\u010dt\u011bte ka\u017ed\u00fd popis z\u00e1suvn\u00e9ho modulu p\u0159edt\u00edm, ne\u017e se je rozhodnete nainstalovat.\nV\u011bt\u0161ina z\u00e1suvn\u00fdch [...]
+Views.plugins.Distributed.DB.title=Distribuovan\u00e1 DB
+Views.plugins.Distributed.Tracker.title=Distribuovan\u00fd Tracker
+Views.plugins.Plugin.Update.title=Aktualizace Z\u00e1suvn\u00e9ho Modulu
+openUrl.url.info=Podporuje http, https, magnet a \u0161estn\u00e1ctkov\u00e9 infohash \u0159et\u011bzce
+TableColumn.header.swarm_average_completion=Pr\u016fm\u011brn\u00e9 Dokon\u010den\u00ed Klient\u016f
+TableColumn.header.swarm_average_completion.info=Pr\u016fm\u011brn\u00e9 procento dokon\u010den\u00ed klient\u016f v po\u010dtu \u00fa\u010dastn\u00edk\u016f
 GeneralView.label.swarm_average_completion=Pr\u016fm\u011br dokon\u010den\u00ed:
-GeneralView.label.swarm_average_completion.tooltip=Pr\u016fm\u011br dokon\u010den\u00ed v procentech (klient\u016f torrentu)
-MainWindow.nat.status.tooltip.unknown=Dosa\u017eitelnost ostatn\u00edch u\u017eivatel\u016f p\u0159es internetovou ochranu/NAT je nezn\u00e1m\u00e1 (TCP), pravd\u011bpodobn\u011b proto\u017ee nejsou spu\u0161t\u011bny \u017e\u00e1dn\u00e9 torrenty
-MainWindow.nat.status.ok=NAT je v po\u0159\u00e1dku
+GeneralView.label.swarm_average_completion.tooltip=Pr\u016fm\u011brn\u00e9 dokon\u010den\u00ed v procentech klient\u016f v po\u010dtu \u00fa\u010dastn\u00edk\u016f
+MainWindow.nat.status.tooltip.unknown=Stav dosa\u017eitelnosti Firewall/NAT je nezn\u00e1m\u00fd (TCP)
 MainWindow.nat.status.tooltip.ok=Dosa\u017eitelnost je v po\u0159\u00e1dku (TCP)
-MainWindow.nat.status.tooltip.probok=Dosa\u017eitelnost je v po\u0159\u00e1dku, ale nep\u0159ich\u00e1zej\u00ed \u017e\u00e1dn\u00e9 TCP p\u0159ipojen\u00ed
-MainWindow.nat.status.bad=Internetov\u00e1 ochrana
-MainWindow.nat.status.tooltip.bad=Zji\u0161t\u011bn\u00fd probl\u00e9m s internetovou ochranou/NAT (TCP). Informace a n\u00e1pov\u011bdu najdete na Wiki
-plugin.installer.recommended.plugin=Doporu\u010den\u00fd plugin - pros\u00edm pohl\u00e9dn\u011bte si ho, v p\u0159\u00edpad\u011b nutnosti a nainstalujte
-LoggerView.pause=Pause z\u00e1pisu
+MainWindow.nat.status.tooltip.probok=Dosa\u017eitelnost je v po\u0159\u00e1dku, nicm\u00e9n\u011b nejsou \u017e\u00e1dn\u00e1 ned\u00e1vn\u00e1 p\u0159\u00edchoz\u00ed TCP p\u0159ipojen\u00ed
+MainWindow.nat.status.bad=Za Firewallem
+MainWindow.nat.status.tooltip.bad=Probl\u00e9m dostupnosti (TCP) Firewall/NAT. Prohl\u00e9dn\u011bte si Wiki pro n\u00e1pov\u011bdu
+plugin.installer.recommended.plugin=Doporu\u010den\u00fd z\u00e1suvn\u00fd modul - zhodno\u0165te ho a instalujte ho v p\u0159\u00edpad\u011b pot\u0159eby
+LoggerView.pause=Pozastavit z\u00e1znam
 LoggerView.clear=&Vy\u010distit
 LoggerView.filter=Filtr
-LoggerView.filter.uncheckAll=Nekontrolovat v\u0161echny kategorie
-LoggerView.filter.checkAll=Kontrola v\u0161ech kategori\u00ed
-LoggerView.loggingDisabled=Z\u00e1pis nen\u00ed  povolen
+LoggerView.filter.uncheckAll=Od\u0161krtnout V\u0161echny Kategorie
+LoggerView.filter.checkAll=Za\u0161krtnout V\u0161echny Kategorie
+LoggerView.loggingDisabled=Z\u00e1znam nen\u00ed povolen.
+LoggerView.includeOnly=Zobrazovat pouze \u0159\u00e1dky, kter\u00e9 se shoduj\u00ed s t\u00edmto regul\u00e1rn\u00edm v\u00fdrazem:
+LoggerView.excludeAll=Nezobrazovat \u0159\u00e1dky, shoduj\u00edc\u00ed se s t\u00edmto regul\u00e1rn\u00edm v\u00fdrazem:
 ConfigView.section.logging.log0type=Informace
 ConfigView.section.logging.log1type=Varov\u00e1n\u00ed
 ConfigView.section.logging.log2type=Chyba
-ConfigView.section.logging.filter=Filtrovat kdy\u017e zapisuji do souboru
-ConfigView.section.logging.level=\u00darove\u0148 log
-ConfigView.section.logging.showLogsFor=Zobrazit %1 logy z n\u00e1sleduj\u00edcich kategori\u00ed:
+ConfigView.section.logging.filter=Filtrovat p\u0159i z\u00e1znamu do souboru
+ConfigView.section.logging.level=\u00darove\u0148 Z\u00e1znamu
+ConfigView.section.logging.showLogsFor=Zobrazit %1 z\u00e1znam\u016f z n\u00e1sleduj\u00edc\u00edch kategori\u00ed:
+ConfigView.pluginlist.column.loadAtStartup=Na\u010d\u00edst p\u0159i Spu\u0161t\u011bn\u00ed
 ConfigView.pluginlist.column.type=Typ
-ConfigView.pluginlist.column.type.perUser=Ka\u017ed\u00fd u\u017eivatel
-ConfigView.pluginlist.column.type.shared=Sd\u00edlet
-ConfigView.pluginlist.column.type.builtIn=Zapojit
-ConfigView.pluginlist.column.name=Jm\u00e9no/N\u00e1zev
+ConfigView.pluginlist.column.type.perUser=Individu\u00e1ln\u00ed
+ConfigView.pluginlist.column.type.shared=Sd\u00edlen\u00fd
+ConfigView.pluginlist.column.type.builtIn=Vestav\u011bn\u00fd
+ConfigView.pluginlist.column.name=N\u00e1zev
 ConfigView.pluginlist.column.version=Verze
 ConfigView.pluginlist.column.directory=Adres\u00e1\u0159
-ConfigView.pluginlist.column.isOperational=Opera\u010dn\u00ed?
-PeersView.BlockView.Avail.Have=Oba maj\u00ed
-PeersView.BlockView.Avail.NoHave=Klient m\u00e1, Vy nem\u00e1te
-PeersView.BlockView.NoAvail.Have=Vy m\u00e1te, klient nem\u00e1
-PeersView.BlockView.NoAvail.NoHave=Ani jeden z v\u00e1s nem\u00e1
-PeersView.BlockView.Transfer=P\u0159enosy
+ConfigView.pluginlist.column.isOperational=Funguje?
+PeersView.BlockView.Avail.Have=Oba m\u00e1te
+PeersView.BlockView.Avail.NoHave=Klient m\u00e1; Vy nem\u00e1te
+PeersView.BlockView.NoAvail.Have=Vy m\u00e1te; Klient nem\u00e1
+PeersView.BlockView.NoAvail.NoHave=Ani jeden nem\u00e1
+PeersView.BlockView.Transfer=P\u0159en\u00e1\u0161en\u00ed
 PeersView.BlockView.NextRequest=Dal\u0161\u00ed po\u017eadavek
-PeersView.BlockView.title=Mapov\u00e1n\u00ed
-PeersView.BlockView.AvailCount=Dostupn\u00fd po\u010det
-MyTorrentsView.dialog.NumberError.title=\u0160patn\u00e9 nebo nezn\u00e1m\u00e9 \u010d\u00edslo
-MyTorrentsView.dialog.NumberError.text=\u010c\u00edslo, kter\u00e9 jste vlo\u017eili je \u0161patn\u00e9 nebo nezn\u00e1m\u00e9.
-MyTorrentsView.menu.manual=&Manu\u00e1l
-MyTorrentsView.dialog.setSpeed.title=Set %1 rychlost
+PeersView.BlockView.title=Mapa D\u00edl\u016f
+PeersView.BlockView.AvailCount=Po\u010det Dostupnosti
+MyTorrentsView.dialog.NumberError.title=\u0160patn\u00e9 nebo Nerozpoznan\u00e9 \u010c\u00edslo
+MyTorrentsView.dialog.NumberError.text=\u010c\u00edslo, kter\u00e9 jste vlo\u017eili je \u0161patn\u00e9 nebo nerozpoznan\u00e9.
+MyTorrentsView.menu.manual=&Ru\u010dn\u00ed...
+MyTorrentsView.menu.manual.per_torrent=Ru\u010dn\u00ed (na torrent)
+MyTorrentsView.menu.manual.shared_torrents=Ru\u010dn\u00ed (nap\u0159\u00ed\u010d torrenty)
+MyTorrentsView.dialog.setSpeed.title=Nastavit %1 rychlost
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
-MyTorrentsView.dialog.setNumber.text=Pro vstup zadejte \u010d\u00edslo %1 ke zm\u011bn\u011b %2 to:
+MyTorrentsView.dialog.setNumber.text=Zadejte \u010d\u00edslo %1 ke zm\u011bn\u011b %2 na:
 MyTorrentsView.dialog.setNumber.upload=odes\u00edl\u00e1n\u00ed
 MyTorrentsView.dialog.setNumber.download=stahov\u00e1n\u00ed
 MyTorrentsView.dialog.setNumber.inKbps=v %1
-OpenTorrentWindow.torrentLocation=Torrent soubory:
+OpenTorrentWindow.torrentLocation=Torrent(y) ke sta\u017een\u00ed:
 OpenTorrentWindow.addFiles.URL=P\u0159idat &URL
 OpenTorrentWindow.addFiles.Folder=P\u0159idat &Adres\u00e1\u0159
-OpenTorrentWindow.addFiles.Clipboard=P\u0159idat ze Sch&r\u00e1nky
-OpenTorrentWindow.changeDestination=Zm\u011bnit um\u00edst\u011bn\u00ed
-OpenTorrentWindow.fileList=Soubory v torrents:
+OpenTorrentWindow.addFiles.Clipboard=P\u0159idat Ze Sch&r\u00e1nky
+OpenTorrentWindow.changeDestination=Zm\u011bnit C\u00edl
+OpenTorrentWindow.fileList=Soubory v torrentech:
 OpenTorrentWindow.torrentTable.name=N\u00e1zev
-OpenTorrentWindow.torrentTable.saveLocation=Ulo\u017eit um\u00edst\u011bn\u00ed
-OpenTorrentWindow.fileTable.fileName=N\u00e1zev souboru
+OpenTorrentWindow.torrentTable.saveLocation=Um\u00edst\u011bn\u00ed pro Ulo\u017een\u00ed
+OpenTorrentWindow.fileTable.fileName=N\u00e1zev Souboru
 OpenTorrentWindow.fileTable.size=Velikost
-OpenTorrentWindow.fileTable.destinationName=Jm\u00e9no c\u00edle
+OpenTorrentWindow.fileTable.destinationName=Jm\u00e9no C\u00edle
 OpenTorrentWindow.startMode.seeding=Distrubuce
-OpenTorrentWindow.fileList.changeDestination=Zm\u011bnit um\u00edst\u011bn\u00ed
-OpenTorrentWindow.mb.badSize.title=Neslu\u010diteln\u00fd soubor
+OpenTorrentWindow.fileList.changeDestination=Zm\u011bnit C\u00edl
+OpenTorrentWindow.mb.badSize.title=Nekompatibiln\u00ed soubor
 OpenTorrentWindow.mb.badSize.text='%1' nen\u00ed '%2' a nem\u016f\u017ee b\u00fdt pou\u017eit pro distribuci
 OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> ji\u017e byl p\u0159id\u00e1n jako '%2'
-OpenTorrentWindow.mb.alreadyExists.title=Torrent ji\u017e existuje
-OpenTorrentWindow.mb.openError.title=Chyba ote\u0159en\u00ed
-OpenTorrentWindow.mb.openError.text='%1' nelze otev\u0159\u00edt:
-OpenTorrentWindow.torrent.remove=Odstranit seznam torrent\u016f
-OpenTorrentWindow.torrent.options=N\u00e1sleduj\u00edc\u00ed nastaven\u00ed bude aplikov\u00e1no na vybran\u00e9 torrenty:
+OpenTorrentWindow.mb.alreadyExists.default.name=M\u00e9dia
+OpenTorrentWindow.mb.alreadyExists.title=Ji\u017e existuje
+OpenTorrentWindow.mb.openError.title=Chyba otev\u0159en\u00ed
+OpenTorrentWindow.mb.openError.text='%1' nemohl b\u00fdt otev\u0159en:\n%2
+OpenTorrentWindow.torrent.remove=Odstranit torrent ze seznamu
+OpenTorrentWindow.torrent.options=N\u00e1sleduj\u00edc\u00ed nastaven\u00ed bude pou\u017eito na torrenty vybran\u00e9 v\u00fd\u0161e:
 OpenTorrentWindow.xOfTotal=(%1 z %2)
 iconBar.open.tooltip=Otev\u0159\u00edt Torrent(y)
 LocaleUtil.column.text=Nezn\u00e1m\u00fd text
-Tracker.tooltip.MultiSupport=Tento server podporuje v\u00edcen\u00e1sobn\u00e9 hashov\u00e1n\u00ed a scrapes na po\u017e\u00e1d\u00e1n\u00ed.
-Tracker.tooltip.NoMultiSupport=Tento server nepodporuje v\u00edcen\u00e1sobn\u00e9 hashov\u00e1n\u00ed a  scrapes na po\u017e\u00e1d\u00e1n\u00ed.
-ConfigView.label.lazybitfield=Pou\u017eit\u00ed pomal\u00e9ho bitov\u00e9ho pole (pom\u00e1h\u00e1 vzniku sitov\u00fdch chyb- pou\u017e\u00edv\u00e1n\u00edm blokov\u00e1n \u00edbitov\u00fdch pol\u00ed)
-LoggerView.realtime=Update v re\u00e1ln\u00e9m \u010dase
-ConfigView.section.file.perf.cache.flushpieces=Zapisuje ihned kompletn\u00ed d\u00edly na disk. Toto zjednodu\u0161uje p\u0159\u00edstup na na disk, ale m\u016f\u017ee to m\u00edt za n\u00e1sledek vice opera\u010dn\u00edch z\u00e1pis\u016f.
-ConfigView.section.file.writemblimit=Maximum \u017e\u00e1dosti o z\u00e1pis ve front\u011b (in %1)
-ConfigView.section.file.writemblimit.explain=Kdy\u017e se zapisuje na disk rychlost\u00ed men\u0161\u00ed ne\u017e je rychlost stahov\u00e1n\u00ed ,tento parametr omez\u00ed kolik dat bude front\u011b ne\u017e se sta\u017een\u00e1 data zredukuj\u00ed.
-ConfigView.section.file.readmblimit=Maxim\u00e1ln\u00ed po\u010det \u017e\u00e1dost\u00ed ve front\u011b k na\u010dten\u00ed (in %1)
-ConfigView.section.file.readmblimit.explain=Tento parametr limituje kolik pam\u011bti bude pou\u017eito na ulo\u017een\u00ed pro nevy\u0159e\u0161en\u00e9 procesy.
-Button.moveUp=Posunout nahoru
-Button.moveDown=Posunout dol\u016f
-ConfigView.notAvailableForMode=Tato \u010d\u00e1st je ur\u010dena k %1 m\u00f3du nebo vy\u0161\u0161\u00ed.  je nedosa\u017eiteln\u00fd v %2 m\u00f3du.
-health.explain.error=Chyba torrentu.  Pod\u00edvejte se do stavov\u00e9ho sloupce, nebo na n\u00e1strojov\u00fd tip pro zji\u0161t\u011bn\u00ed chyby.
-PeersView.piece=D\u00edly
-PeersView.piece.info=\u010c\u00edslo posledn\u00edho po\u017eadovan\u00e9ho d\u00edlu
+Tracker.tooltip.MultiSupport=Tento tracker podporuje v\u00edcen\u00e1sobn\u00e9 hashov\u00e1n\u00ed a scrapes na po\u017e\u00e1d\u00e1n\u00ed.
+Tracker.tooltip.NoMultiSupport=Tento tracker nepodporuje v\u00edcen\u00e1sobn\u00e9 hashov\u00e1n\u00ed a  scrapes na po\u017e\u00e1d\u00e1n\u00ed.\nToto neovlivn\u00ed V\u00e1\u0161 v\u00fdkon, ale zp\u016fsobuje v\u011bt\u0161\u00ed z\u00e1t\u011b\u017e na tracker.
+ConfigView.label.lazybitfield=Pou\u017e\u00edt pomal\u00e9ho bitov\u00e9ho pole (pom\u00e1h\u00e1 distribuci na s\u00edt\u00edch pou\u017e\u00edvaj\u00edc\u00ed blokov\u00e1n\u00ed na z\u00e1klad\u011b bitov\u00e9ho pole)
+LoggerView.realtime=Aktualizovat v re\u00e1ln\u00e9m \u010dase
+ConfigView.section.file.perf.cache.flushpieces=Zapisovat ihned kompletn\u00ed d\u00edly na disk. Toto zjem\u0148uje p\u0159\u00edstup na disk, ale m\u016f\u017ee m\u00edt za n\u00e1sledek vice operac\u00ed z\u00e1pisu.
+ConfigView.section.file.writemblimit=Maximum \u017e\u00e1dosti o z\u00e1pis ve front\u011b (v %1)
+ConfigView.section.file.writemblimit.explain=Kdy\u017e rychlost z\u00e1pisu disku je men\u0161\u00ed ne\u017e je rychlost stahov\u00e1n\u00ed, tento parametr omez\u00ed, kolik dat bude front\u011b, ne\u017e je rychlost stahov\u00e1n\u00ed zredukov\u00e1na.
+ConfigView.section.file.readmblimit=Maximum \u017e\u00e1dost\u00ed o \u010dten\u00ed ve front\u011b (v %1)
+ConfigView.section.file.readmblimit.explain=Tento parametr limituje, kolik pam\u011bti bude pou\u017eito na ulo\u017een\u00ed pro \u010dten\u00ed z \u00faschovy, kter\u00e9 \u010dekaj\u00ed na zpracov\u00e1n\u00ed.
+Button.moveUp=Posunout &Nahoru
+Button.moveDown=Posunout &Dol\u016f
+ConfigView.notAvailableForMode=Tato \u010d\u00e1st je ur\u010dena pro re\u017eim %1 nebo vy\u0161\u0161\u00ed. Je nedostupn\u00e1 v re\u017eimu %2.
+health.explain.error=V torrentu je chyba.  Pod\u00edvejte se do sloupce stavu, nebo na popisek na ikon\u011b pro zji\u0161t\u011bn\u00ed chyby.
+GeneralView.label.trackerscrapeupdate=Scrape Trackeru
+PeersView.piece=D\u00edl
+PeersView.piece.info=\u010c\u00edslo posledn\u00edho po\u017eadovan\u00e9ho d\u00edlu od tohoto klienta
 PiecesView.priority=Priorita
-PiecesView.priority.info=Tyto d\u00edly jsou prioritou dokon\u010den\u00ed, ale nevy\u017eaduj\u00ed mnoho pozornosti
+PiecesView.priority.info=priorita dokon\u010den\u00ed tohoto d\u00edlu, ale ned\u00e1vejte tomuto moc velkou pozornost
 PiecesView.speed=Rychlost
-PiecesView.speed.info=Pomal\u00fdm klient\u016fm je \u010d\u00e1ste\u010dn\u011b blokov\u00e1n p\u0159\u00edstup k rychl\u00fdm d\u00edl\u016fm
-TableColumn.header.AvgAvail.info=Sou\u010det po\u010dtu dostupnosti d\u011blen\u00e9 # po\u010dtem p\u0159ipojen\u00ed #  connections 
+PiecesView.speed.info=Pomal\u00fdm klient\u016fm je velmi hodn\u011b zabr\u00e1n\u011bno v zasahov\u00e1n\u00ed do rychl\u00fdch d\u00edl\u016f
+TableColumn.header.AvgAvail.info=Sou\u010det po\u010dtu dostupnosti d\u00edl\u016f d\u011blen\u00fd po\u010dtem d\u00edl\u016f, d\u011blen\u00fdch po\u010dtem p\u0159ipojen\u00ed
 TableColumn.header.AvgAvail=Pr\u016fm\u011brn\u00e1 dostupnost/d\u00edl
-ConfigView.label.strictfilelocking=Zabezpe\u010dte svoje soubory, zamezen\u00edm p\u0159\u00edstupu p\u0159es torrenty
-MyTorrentsView.menu.rescanfile=Periodicky kontrolvat ne\u00fapln\u00e9 d\u00edly
-Plugin.extseed.name=Extern\u00ed klienti
+ConfigView.label.strictfilelocking=Vynutit si v\u00fdhradn\u00ed p\u0159\u00edstup k zam\u010den\u00ed soubor\u016f pro z\u00e1pis nap\u0159\u00ed\u010d torrenty
+MyTorrentsView.menu.checkfilesexist=Zkontrolovat P\u0159\u00edtomnost Soubor\u016f
+MyTorrentsView.menu.rescanfile=Periodicky Znovu Kontrolovat Nedokon\u010den\u00e9 D\u00edly
+MyTorrentsView.menu.clear_resume_data=Vy\u010distit Data Obnoven\u00ed
+Plugin.extseed.name=Extern\u00ed Distributo\u0159i
 Plugin.localtracker.name=LAN vyhled\u00e1va\u010d klient\u016f
-Plugin.localtracker.info=LAN vyhledava\u010d klient\u016f povolil v\u00edcen\u00e1sobn\u00e9 kopie z Azurea za  firewallem a na b\u011b\u017en\u00e9 sit\u00ed\nefektivn\u00ed download torrent\u016f umo\u017e\u0148uj\u00edc\u00ed p\u0159\u00edm\u00e9 p\u0159ipojen\u00ed  mezi nimi.
+Plugin.localtracker.info=LAN vyhledava\u010d klient\u016f povoluje v\u00edcen\u00e1sobn\u00e9 kopie Vuze za firewallem a na b\u011b\u017en\u00e9 sit\u00ed\nk efektivn\u00edmu stahov\u00e1n\u00ed torrent\u016f umo\u017en\u011bn\u00edm p\u0159\u00edm\u00e9ho spojen\u00ed mezi nimi.
 Plugin.localtracker.enable=Povolit LAN vyhled\u00e1n\u00ed klient\u016f
-azinstancehandler.alert.portclash=Nastaven\u00fd port v  LAN: %1 je pou\u017e\u00edvan\u00e1 jin\u00fdm u\u017eivatele (programem), vyberte nov\u00fd p\u0159\u00edchoz\u00ed port (s) pro p\u0159\u00edchoz\u00ed TCP / UDP naslouch\u00e1n\u00ed [mezi %2 and %3]. 
+azinstancehandler.alert.portclash=Zji\u0161t\u011bn st\u0159et port\u016f LAN: %1 ji\u017e je pou\u017e\u00edvan\u00fd jin\u00fdm u\u017eivatelem Vuze, vyberte nov\u00fd n\u00e1hodn\u00fd port(y) pro p\u0159\u00edchoz\u00ed TCP / UDP naslouch\u00e1n\u00ed [mezi %2 and %3].
 ConfigView.section.transfer.lan.tooltip=LAN - specifick\u00e9 nastaven\u00ed
 ConfigView.section.transfer.lan.uploadrate=KB/s LAN maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed [0: neomezeno]
-ConfigView.section.transfer.lan.uploadrate.tooltip=Klienti p\u0159ipojen\u00ed ve stejn\u00e9 vnit\u0159n\u00ed s\u00edti LAN maj\u00ed odd\u011blen\u00fd limit odes\u00edlan\u00fdch dat.
-ConfigView.section.transfer.lan.downloadrate=KB/s LAN maxim\u00e1ln\u00ed stahovac\u00ed rychlost [0: neomezn\u011b]
-ConfigView.section.transfer.lan.downloadrate.tooltip=Klienti p\u0159ipojen\u00ed ve stejn\u00e9 vnit\u0159n\u00ed s\u00edti LAN maj\u00ed odd\u011blen\u00fd limit stahovan\u00fdch dat.
+ConfigView.section.transfer.lan.uploadrate.tooltip=P\u0159ipojen\u00ed klient\u016f ve stejn\u00e9 vnit\u0159n\u00ed LAN maj\u00ed odd\u011blen\u00fd limit rychlosti odes\u00edl\u00e1n\u00ed.
+ConfigView.section.transfer.lan.downloadrate=KB/s LAN Maxim\u00e1ln\u00ed rychlost stahov\u00e1n\u00ed [0: neomezen\u011b]
+ConfigView.section.transfer.lan.downloadrate.tooltip=P\u0159ipojen\u00ed klient\u016f ve stejn\u00e9 vnit\u0159n\u00ed LAN maj\u00ed odd\u011blen\u00fd limit rychlosti stahov\u00e1n\u00ed.
 TorrentOptionsView.title.short=Mo\u017enosti
 TorrentOptionsView.title.full=Mo\u017enosti
-TorrentOptionsView.param.max.peers=Max. po\u010det p\u0159ipojen\u00ed [0: neomezen\u011b]
-ConfigView.section.connection.encryption.require_encrypted_transport=Po\u017eadujte \u0161ifrovan\u00fd p\u0159enos
-ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=Vynucen\u00e9 pou\u017eit\u00ed \u0161ifrov\u00e1n\u00e9ho p\u0159ipojen\u00ed s dal\u0161\u00edmi klienty.
-ConfigView.section.connection.encryption.min_encryption_level=Minim\u00e1ln\u00ed \u0161ifrovac\u00ed \u00farove\u0148
-ConfigView.section.connection.encryption.min_encryption_level.tooltip=P\u0159\u00edm\u00e9 propojen\u00ed jen v\nRC4 - pln\u00fd proud\n\u0160ifrov\u00e1n\u00ed v\u00edce zat\u011b\u017euje procesor.
+TorrentOptionsView.param.max.peers=Maxim\u00e1ln\u00ed po\u010det p\u0159ipojen\u00ed [0: neomezen\u011b]
+ConfigView.section.connection.encryption.require_encrypted_transport=Po\u017eadovat \u0161ifrovan\u00fd p\u0159enos
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=Vynutit pou\u017eit\u00ed \u0161ifrovan\u00e9ho p\u0159ipojen\u00ed s dal\u0161\u00edmi klienty.
+ConfigView.section.connection.encryption.min_encryption_level=Minim\u00e1ln\u00ed \u00farove\u0148 \u0161ifrov\u00e1n\u00ed
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=Prost\u00e9 - pouze zah\u00e1jen\u00ed\nRC4 - pln\u00fd proud\nVy\u0161\u0161\u00ed \u0161ifrov\u00e1n\u00ed pot\u0159ebuje v\u00edce procesoru.
 Peers.column.Encryption=\u0160ifrov\u00e1n\u00ed
 Peers.column.Encryption.info=\u00darove\u0148 pou\u017eit\u00e9ho \u0161ifrov\u00e1n\u00ed
-ConfigView.section.connection.encryption.encrypt.info=M\u00e1te-li povolen \u0161ifrovan\u00fd p\u0159enos. nebudete se moci p\u0159ipojit k nekompabilitn\u00edm klient\u016fm, pokud v nastaven\u00ed nepovol\u00edte nouzovou mo\u017enost p\u0159ipojen\u00ed
-ConfigView.section.connection.encryption.encrypt.info.link=Pros\u00edm prohl\u00e9dn\u011bte si zobrazen\u00e9 detaily
+ConfigView.section.connection.encryption.encrypt.info=M\u00e1te-li povoleno \u0161ifrov\u00e1n\u00ed, nebudete se moci p\u0159ipojit k nekompatibiln\u00edm klient\u016fm, pokud nenastav\u00edte n\u00e1vratov\u00e9 mo\u017enosti
+ConfigView.section.connection.encryption.encrypt.info.link=Pros\u00edm koukn\u011bte se sem pro podrobnosti
 MainWindow.sr.status.tooltip.ok=Pom\u011br sd\u00edlen\u00ed %1 v po\u0159\u00e1dku
 MainWindow.sr.status.tooltip.poor=Pom\u011br sd\u00edlen\u00ed %1 n\u00edzk\u00fd: < 0.9
-MainWindow.sr.status.tooltip.bad=Pom\u011br sd\u00edlen\u00ed %1 p\u0159\u00ed\u0161ern\u00fd: < 0.5
-ConfigView.section.style.status=Stav oblasti:
-ConfigView.section.style.status.show_sr=Koeficient sd\u00edlen\u00ed
+MainWindow.sr.status.tooltip.bad=Pom\u011br sd\u00edlen\u00ed %1 \u0161patn\u00fd: < 0.5
+ConfigView.section.style.status=Stav Oblasti:
+ConfigView.section.style.status.show_sr=Pom\u011br Sd\u00edlen\u00ed
 ConfigView.section.style.status.show_nat=Stav NAT 
 ConfigView.section.style.status.show_ddb=Stav DDB 
-ConfigView.section.connection.encryption.encrypt.group=\u0160ifrovan\u00fd p\u0159enos dat
-ConfigView.section.connection.encryption.encrypt.fallback_info=Povolit nouzovou mo\u017enost, kter\u00e1 dovol\u00ed spojen\u00ed s nekompatibiln\u00edmi klienty, ALE jen v ne\u0161ifrovan\u00e9m spojen\u00ed
-ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Povolit neza\u0161ifrovan\u00e9 odchoz\u00ed p\u0159ipojen\u00ed p\u0159i selh\u00e1n\u00ed \u0161ifrovan\u00e9ho odchoz\u00edho p\u0159ipojen\u00ed
-ConfigView.section.connection.encryption.encrypt.fallback_incoming=Povolit neza\u0161ifrvan\u00e1 p\u0159\u00edchoz\u00ed p\u0159ipojen\u00ed
-ConfigView.section.connection.encryption=Zaslat \u0161ifrovan\u011b
-upnp.selectedinterfaces=Vyberte rozhran\u00ed (';' odd\u011blova\u010d, e.g. eth0;eth1) [blank: all]
-ConfigView.section.style.defaultSortOrder=Standartn\u00ed po\u0159ad\u00ed
+ConfigView.section.style.status.show_ipf=Stav IPFiltru
+ConfigView.section.connection.encryption.encrypt.group=\u0160ifrov\u00e1n\u00ed/Maskov\u00e1n\u00ed P\u0159enosu
+ConfigView.section.connection.encryption.encrypt.fallback_info=Povolen\u00edm kter\u00e9koli mo\u017enosti vr\u00e1cen\u00ed umo\u017en\u00ed spojen\u00ed s nekompatibiln\u00edmi klienty ALE m\u00e1 za n\u00e1sledek neza\u0161ifrovan\u00e1 spojen\u00ed
+ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Povolit neza\u0161ifrovan\u00e1 odchoz\u00ed spojen\u00ed pokud sel\u017ee pokus o \u0161ifrovan\u00e9 odchoz\u00ed spojen\u00ed
+ConfigView.section.connection.encryption.encrypt.fallback_incoming=Povolit neza\u0161ifrovan\u00e1 p\u0159\u00edchoz\u00ed p\u0159ipojen\u00ed
+ConfigView.section.connection.encryption=\u0160ifrov\u00e1n\u00ed P\u0159enosu
+upnp.selectedinterfaces=Vyberte rozhran\u00ed (odd\u011blen\u00e9 ';', nap\u0159. eth0;eth1) [pr\u00e1zdn\u00e9: v\u0161echna]
+ConfigView.section.style.defaultSortOrder=Standardn\u00ed Po\u0159ad\u00ed \u0158azen\u00ed
 ConfigView.section.style.defaultSortOrder.desc=Sestupn\u011b
 ConfigView.section.style.defaultSortOrder.asc=Vzestupn\u011b
-ConfigView.section.style.defaultSortOrder.flip=Opa\u010dn\u00e9 p\u0159edchoz\u00ed po\u0159ad\u00ed
-LoggerView.autoscroll=Auto-rolov\u00e1n\u00ed
+ConfigView.section.style.defaultSortOrder.flip=Opa\u010dn\u00e9 k p\u0159edchoz\u00edmu po\u0159ad\u00ed
+LoggerView.autoscroll=Auto-posunov\u00e1n\u00ed
 Button.selectAll=Vybrat v\u0161e
 Button.markSelected=Ozna\u010dit vybran\u00e9
 Button.unmarkSelected=Zru\u0161it vybran\u00e9
-plugins.basicview.config=Configurace
-TorrentOptionsView.param.max.uploads=Max. po\u010det upload slotu [minimum: 2]
-MyTorrentsView.dialog.setPosition.title=Nastaven\u00ed polohy
-MyTorrentsView.dialog.setPosition.text=Enter potvrd\u00edte vybran\u00e9 torrents:
+plugins.basicview.config=Nastaven\u00ed
+TorrentOptionsView.param.max.uploads=Max. po\u010det pozic odes\u00edl\u00e1n\u00ed [minimum: 2]
+MyTorrentsView.dialog.setPosition.title=Nastaven\u00ed Polohy
+MyTorrentsView.dialog.setPosition.text=Zadejte pozici k nastaven\u00ed vybran\u00fdch torent\u016f na:
 MyTorrentsView.menu.reposition.manual=P\u0159em\u00edstit...
-ConfigView.section.connection.advanced.info.link=Pros\u00edm pod\u00edvej se na zobrazen\u00e9 detaily
+ConfigView.section.connection.advanced.info.link=Pros\u00edm pod\u00edvejte se sem pro podrobnosti
 ConfigView.section.connection.advanced.socket.group=Mo\u017enosti socketu
-ConfigView.section.connection.advanced.bind_port=P\u0159ipojit m\u00edstn\u00ed port [0: neomezen\u011b]
-ConfigView.section.connection.advanced.bind_port.tooltip=Odchoz\u00ed socket p\u0159ipojen\u00ed je sv\u00e1z\u00e1no s m\u00edstn\u00edm dan\u00fdm portem.\nPovolen\u00ed V\u00e1m m\u016f\u017ee pomoci s nestabilnosti NAT routeru.
-ConfigView.section.proxy.group.tracker=Komunikace se serverem
+ConfigView.section.connection.advanced.bind_port=Sv\u00e1zat s m\u00edstn\u00edm portem [0: vypnuto
+ConfigView.section.connection.advanced.bind_port.tooltip=Odchoz\u00ed p\u0159ipojen\u00ed socketu bude m\u00edstn\u011b sv\u00e1z\u00e1no s dan\u00fdm portem.\nZapnut\u00edm tohoto V\u00e1m m\u016f\u017ee pomoci s nestabilitou NAT routeru.
+ConfigView.section.proxy.group.tracker=Komunikace s Trackerem
 ConfigView.section.proxy.group.peer=Komunikace s klienty
 Pieces.column.Requested=Po\u017eadovan\u00fd
-Pieces.column.Requested.info=Ukazuje,zda m\u016f\u017ee b\u00fdt na d\u00edl posl\u00e1no v\u00edce \u017e\u00e1dost\u00ed (*)
-ConfigView.label.maxuploadsseeding=Alternativn\u00ed standart pro stahuj\u00edc\u00ed u\u017eivatele
+Pieces.column.Requested.info=Zobrazuje, zda m\u016f\u017ee b\u00fdt na d\u00edl pod\u00e1no v\u00edce \u017e\u00e1dost\u00ed nebo ne (*)
+ConfigView.label.maxuploadsseeding=Alternativn\u011b v\u00fdchoz\u00ed p\u0159i distribuci
 MyTorrentsView.filter=Filtr: [%1]
 popup.error.hideall=Skr\u00fdt v\u0161e
-ConfigView.section.style.dataStatsOnly=Ukazovat pouze statistiky dat (skr\u00fdt statistiky protokol\u016f)
-ConfigView.section.style.separateProtDataStats=Zobrazit odd\u011blen\u011b data a protokol jako 'data (protocol)'
-MyTorrentsView.dialog.setFilter.title=Upravit filtr
-MyTorrentsView.dialog.setFilter.text=Sekce %1 bude filtrovat text, kter\u00fd zde dol\u016f nap\u00ed\u0161ete. Pou\u017eijte symbol | (svisl\u00e1 \u010d\u00e1ra) pro filtrov\u00e1n\u00ed souslov\u00ed.
-MyTorrentsView.filter.tooltip=Pou\u017eijte Ctrl+X pro p\u0159ep\u00edn\u00e1n\u00ed mezi RexEx a norm\u00e1ln\u00edm vyhled\u00e1vac\u00edm m\u00f3dem.\n Pou\u017eijte symbol | (svisl\u00e1 \u010d\u00e1ra) pro filtrov\u00e1n\u00ed souslov\u00ed.
+ConfigView.section.style.dataStatsOnly=Zobrazit pouze statistiky dat (skr\u00fdt statistiky protokol\u016f)
+ConfigView.section.style.separateProtDataStats=Zobrazit statistiky dat a protokolu odd\u011blen\u011b jako 'data (protokol)'
+MyTorrentsView.dialog.setFilter.title=Zm\u011bnit Filtr
+MyTorrentsView.dialog.setFilter.text=Sekce %1 bude filtrov\u00e1na textem, kter\u00fd nap\u00ed\u0161ete n\u00ed\u017ee. Pou\u017eijte | (svisl\u00e1 \u010d\u00e1ra) pro filtrov\u00e1n\u00ed v\u00edce fr\u00e1z\u00ed.
+MyTorrentsView.filter.tooltip=Ctrl+X pro p\u0159ep\u00edn\u00e1n\u00ed mezi norm\u00e1ln\u00edm re\u017eimem vyhled\u00e1v\u00e1n\u00ed a vyhled\u00e1v\u00e1n\u00edm pomoc\u00ed Regul\u00e1rn\u00edho v\u00fdrazu.\n Pou\u017eijte | (svisl\u00e1 \u010d\u00e1ra) pro filtrov\u00e1n\u00ed v\u00edce fr\u00e1z\u00ed.
 MyTorrentsView.clearFilter.tooltip=Vy\u010distit filtr
-MyTorrentsView.menu.filter=Filtr list...
-ConfigureWizard.language.choose=Choose a language from the list below (Vyberte si jazyk z n\u00e1sleduj\u00edc\u00edch):
+MyTorrentsView.menu.filter=Seznam Filtr\u016f...
+ConfigView.section.file.resume.recheck.all=Kontrola cel\u00e9ho souboru pro dokon\u010den\u00e9 d\u00edly p\u0159i restartu po p\u00e1du(|Jinak jsou zkontrolov\u00e1ny pouze aktivn\u00ed d\u00edly p\u0159i posledn\u00edm ulo\u017een\u00ed)
+ConfigureWizard.language.choose=Vyberte jazyk ze seznamu n\u00ed\u017ee:
 popup.closing.in=Okno se samo zav\u0159e za %1 sekund.
-popup.more.waiting=%1 zb\u00fdvaj\u00edc\u00ed zpr\u00e1vy.
+popup.more.waiting=%1 dal\u0161\u00edch zpr\u00e1v...
 # > 2402
-popup.download.finished="%1" dokon\u010dil stahov\u00e1n\u00ed.
-popup.file.finished="%1" dokon\u010dil stahov\u00e1n\u00ed.
-Plugin.localtracker.autoadd.info=Automaticky p\u0159id\u00e1vat tyto klienty (adresy odd\u011blte st\u0159edn\u00edkem ";"):
-Plugin.localtracker.autoadd=Explicitn\u00ed klienti
-Plugin.localtracker.networks.info=Pova\u017eovat n\u00e1sleduj\u00edc\u00ed s\u00edt\u011b za m\u00edstn\u00ed (adresy odd\u011blte st\u0159edn\u00edkem ";"):
+popup.download.finished=Stahov\u00e1n\u00ed "%1" dokon\u010deno.
+popup.file.finished=Stahov\u00e1n\u00ed "%1" dokon\u010deno.
+ConfigView.auto=Automaticky
+Plugin.localtracker.autoadd.info=Automaticky p\u0159idat tyto m\u00edstn\u00ed klienty [adresy odd\u011blte ';', nap\u0159. 1.2.3.4]
+Plugin.localtracker.autoadd=Jednozna\u010dn\u00ed klienti
+Plugin.localtracker.networks.info=Pova\u017eovat n\u00e1sleduj\u00edc\u00ed s\u00edt\u011b za m\u00edstn\u00ed [s\u00edt\u011b odd\u011blte ';', nap\u0159. 145.227.*.*]
 Plugin.localtracker.networks=M\u00edstn\u00ed s\u00edt\u011b
-SpeedView.stats.autospeed=Automatick\u00e1 rychlost odes\u00edl\u00e1n\u00ed
-SpeedView.stats.autospeed.disabled=tato mo\u017enoat je bu\u010f zak\u00e1z\u00e1na (pot\u0159ebujete DHT) nebo se nepou\u017e\u00edv\u00e1 (je vybr\u00e1no manu\u00e1ln\u00ed nastaven\u00ed odchoz\u00ed rychlosti).
-SpeedView.stats.idlePing=Pomal\u00e1 odezva (ping):
+MainWindow.menu.view.plugins.logViews=Zobrazen\u00ed Z\u00e1znam\u016f
+SpeedView.stats.autospeed=Automatick\u00e1 Rychlost Odes\u00edl\u00e1n\u00ed (zobrazen\u00ed omezeno na %1 ms)
+SpeedView.stats.autospeed.disabled=Tato Funkce je bu\u010f zak\u00e1z\u00e1na (pot\u0159ebujete DHT) nebo se nepou\u017e\u00edv\u00e1 (vybr\u00e1no ru\u010dn\u00ed rychlost odes\u00edl\u00e1n\u00ed).
+SpeedView.stats.idlePing=Pomal\u00e1 Odezva:
 SpeedView.stats.maxPing=Maxim\u00e1ln\u00ed odezva (ping):
-SpeedView.stats.currentPing=Sou\u010dasn\u00e1 odezva (ping):
+SpeedView.stats.currentPing=Sou\u010dasn\u00e1 Odezva:
 SpeedView.stats.maxUp=Maxim\u00e1ln\u00ed odchoz\u00ed rychlost
-ConfigView.section.transfer.autospeed=Automatick\u00e1 rychlost
+ConfigView.pluginlist.unloadSelected=Uvolnit Vybran\u00e9
+ConfigView.pluginlist.scan=Hledat nov\u00e9 Z\u00e1suvn\u00e9 Moduly
+ConfigView.section.transfer.autospeed=Automatick\u00e1 rychlost (klasick\u00e1)
 ConfigView.section.transfer.autospeed.tooltip=Specifick\u00e9 nastaven\u00ed automatick\u00e9 rychlosti
-ConfigView.section.transfer.autospeed.info=Automatick\u00e1 rychlost automaticky nastavuje rychlost odes\u00edl\u00e1n\u00ed dat, aby nedoch\u00e1zelo k p\u0159et\u00ed\u017een\u00ed s\u00edt\u011b.\n\u005cTyto limity budou pou\u017eity pouze pokud je povoleno automatick\u00e9 nastaven\u00ed odchoz\u00ed rychlosti a pokud je povolena distrubuovan\u00e1 datab\u00e1ze\n
-ConfigView.section.transfer.autospeed.minupload=%1 minim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed dat
-ConfigView.section.transfer.autospeed.minupload.tooltip=Rychlost odes\u00edl\u00e1n\u00ed dat nebude automaticky sni\u017eov\u00e1na pod tuto hranici
-ConfigView.section.transfer.autospeed.maxupload=%1 maxim\u00e1ln\u00ed odchoz\u00ed rychlost [0: neomezen\u011b]
-ConfigView.section.transfer.autospeed.maxupload.tooltip=Rychlost odes\u00edl\u00e1n\u00ed dat nebude automaticky zvy\u0161ov\u00e1na nad tuto hranici
-ConfigView.section.transfer.autospeed.chokeping=Choking ping time [ms]
-ConfigView.section.transfer.autospeed.chokeping.tooltip=\u010casy odezvy (ping) nad tuto hodnotu budou pova\u017eov\u00e1ny za indik\u00e1tor saturace s\u00edt\u011b
-ConfigView.section.transfer.autospeed.enableauto=Povolit p\u0159i stahov\u00e1n\u00ed a distrubuci
-ConfigView.section.transfer.autospeed.enableautoseeding=Povolit pouze p\u0159i distrubuci
-ConfigView.section.transfer.lan.enable=Povolit odd\u011blen\u00ed rychlostn\u00edch limit\u016f pro LAN s\u00edt\u011b
-Plugin.localtracker.wellknownlocals=Automaticky p\u0159idat zkracov\u00e1n\u00ed/odkaz/str\u00e1nka m\u00edstn\u00ed s\u00edt\u011b (192.168. atd.)
-TableColumn.header.filesdone=Pln\u011b dokon\u010deno soubor\u016f:
-TableColumn.header.filesdone.info=Dokon\u010den\u00e9 soubory/kompletn\u00ed soubory *nebo* Dokon\u010den\u00e9 nep\u0159esko\u010den\u00e9 soubory (Dokon\u010den\u00e9 soubory)/V\u0161echny nep\u0159esko\u010den\u00e9 soubory (V\u0161echny soubory)
+ConfigView.section.transfer.autospeed.info=Automatick\u00e1 rychlost automaticky nastavuje limit rychlosti odes\u00edl\u00e1n\u00ed dat tak, aby nedoch\u00e1zelo k p\u0159et\u00ed\u017een\u00ed s\u00edt\u011b.\n\nTyto limity budou pou\u017eity, pouze pokud je povoleno automatick\u00e9 nastaven\u00ed rychlosti odes\u00edl\u00e1n\u00ed a tak\u00e9 vy\u017eaduje zapnutou distribuovan\u00e1 datab\u00e1zi.\n
+ConfigView.section.transfer.autospeed.minupload=%1 minim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed
+ConfigView.section.transfer.autospeed.minupload.tooltip=Rychlost odes\u00edl\u00e1n\u00ed nebude b\u011b\u017en\u011b automaticky sni\u017eov\u00e1na pod tuto hranici
+ConfigView.section.transfer.autospeed.maxupload=%1 maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed [0: neomezen\u011b]
+ConfigView.section.transfer.autospeed.maxupload.tooltip=Rychlost odes\u00edl\u00e1n\u00ed nebude automaticky zvy\u0161ov\u00e1na nad tuto hranici
+ConfigView.section.transfer.autospeed.chokeping=D\u00e9lka \u0161krcen\u00ed odezvy [ms]
+ConfigView.section.transfer.autospeed.chokeping.tooltip=\u010casy odezvy nad tuto hodnotu budou pova\u017eov\u00e1ny za indik\u00e1tor nasycen\u00ed s\u00edt\u011b
+ConfigView.section.transfer.autospeed.enableauto=Povolit p\u0159i stahov\u00e1n\u00ed a distribuci
+ConfigView.section.transfer.autospeed.enableautoseeding=Povolit pouze p\u0159i distribuci
+ConfigView.pluginlist.column.unloadable=Nena\u010diteln\u00fd
+ConfigView.section.transfer.lan.enable=Povolit odd\u011blen\u00ed rychlostn\u00edch limit\u016f pro LAN p\u0159ipojen\u00ed
+Plugin.localtracker.wellknownlocals=Automaticky zahrnout zp\u011btnou smy\u010dku/odkaz/str\u00e1nku m\u00edstn\u00edch s\u00edt\u00ed (192.168 atd.)
+TableColumn.header.filesdone=Soubor\u016f Dokon\u010deno
+TableColumn.header.filesdone.info=Dokon\u010den\u00e9 soubory/Soubor\u016f celkem *nebo* Dokon\u010den\u00e9 nep\u0159esko\u010den\u00e9 soubory (Dokon\u010den\u00e9 soubory)/Celkem nep\u0159esko\u010den\u00fdch soubor\u016f (Celkem soubor\u016f)
 MagnetPlugin.private_torrent=<soukrom\u00fd torrent>
-MagnetPlugin.decentral_disabled=<decentralizovan\u00fd tracking zak\u00e1z\u00e1n>
+MagnetPlugin.decentral_disabled=<decentralizovan\u00e9 sledov\u00e1n\u00ed zak\u00e1z\u00e1no>
 MagnetPlugin.decentral_backup_disabled=<decentralizovan\u00e1 z\u00e1loha zak\u00e1z\u00e1na>
 MagnetPlugin.report.waiting_ddb=\u010dek\u00e1m na inicializaci DDB...
 MagnetPlugin.report.searching=vyhled\u00e1v\u00e1m...
 MagnetPlugin.report.found=nalezeno %1
 MagnetPlugin.report.alive=%1 je na \u017eivu
 MagnetPlugin.report.dead=%1 je mrtv\u00fd
-MagnetPlugin.report.tunnel=dost\u00e1v\u00e1m se do %1
+MagnetPlugin.report.tunnel=tuneluji do %1
 MagnetPlugin.report.downloading=stahuji z %1
 MagnetPlugin.report.error=chyba %1
 MagnetURLHandler.report.no_sources=pro torrent nebyly nalezeny \u017e\u00e1dn\u00e9 zdroje
 MagnetURLHandler.report.torrent_size=velikost torrentu: %1
 MagnetURLHandler.report.percent=hotovo: %1%
 MagnetURLHandler.report.error=chyba %1
-DHTTransport.report.request_all=po\u017eadov\u00e1n cel\u00fd p\u0159enos od  %1
-DHTTransport.report.received_bit=p\u0159ijmuto %1 k %2 od %3
+DHTTransport.report.request_all=\u017e\u00e1dost cel\u00fd p\u0159enos od %1
+DHTTransport.report.received_bit=p\u0159ijmuto %1 do %2 z %3
 DHTTransport.report.complete=hotovo
 DHTTransport.report.timeout=vypr\u0161el \u010dasov\u00fd limit, od %1 nep\u0159i\u0161la \u017e\u00e1dn\u00e1 odpov\u011b\u010f
-DHTTransport.report.rerequest_all=znovu po\u017eadov\u00e1n cel\u00fd p\u0159enos od %1
-DHTTransport.report.rerequest_bit=znovu po\u017eadov\u00e1no %1 k %2 od %3
-DHTTransport.report.timeout_some=vypr\u0161el \u010dasov\u00fd limit, %1 pakety obdr\u017eeny od %2, ale nekompletn\u00ed
+DHTTransport.report.rerequest_all=znovu \u017e\u00e1d\u00e1m cel\u00fd p\u0159enos od %1
+DHTTransport.report.rerequest_bit=znovu \u017e\u00e1d\u00e1m %1 do %2 z %3
+DHTTransport.report.timeout_some=vypr\u0161el \u010dasov\u00fd limit, %1 paket\u016f obdr\u017eeno od %2, ale nen\u00ed kompletn\u00ed
 DHTTransport.report.sending=pos\u00edl\u00e1n\u00ed dat
 DHTTransport.report.resending=znovupos\u00edl\u00e1n\u00ed dat
 DHTTransport.report.send_complete=odes\u00edl\u00e1n\u00ed hotovo
-DHTTransport.report.send_timeout=poslat \u010dasov\u00fd limit
-ConfigView.section.transfer.autospeed.enabledebug=Zaznamen\u00e1vat informace o odstra\u0148ov\u00e1n\u00ed chyb
+DHTTransport.report.send_timeout=pos\u00edl\u00e1n\u00ed vypr\u0161elo
+ConfigView.section.transfer.autospeed.enabledebug=Zaznamen\u00e1vat informace o lad\u011bn\u00ed
 TableColumn.header.date_added=Datum p\u0159id\u00e1n\u00ed
-TableColumn.header.date_added.info=datum, kdy byl torrent p\u0159id\u00e1n
-platform.win32.baddll.info=Vuze detekoval obsah '%1'. Toto je sou\u010d\u00e1st\u00ed '%2' a je zn\u00e1mo t\u00edm, \u017ee n\u011bkdy zp\u016fsobuje probl\u00e9my jako je nap\u0159\u00edklad selh\u00e1v\u00e1n\u00ed program\u016f \u010di vysok\u00e9 vyu\u017e\u00edv\u00e1n\u00ed procesoru. Pokud se s t\u00edmto setk\u00e1v\u00e1te, pros\u00edm odinstalujte tento software nebo ho nastavte tak, aby neru\u0161il Azurea.
-upnp.ignorebaddevices=Ignorovat za\u0159\u00edzen\u00ed, kter\u00e9 nedok\u00e1\u017e\u00ed spr\u00e1vn\u011b odpov\u00eddat
+TableColumn.header.date_added.info=Datum, kdy byl torrent p\u0159id\u00e1n
+ConfigView.section.file.hashchecking.smallestfirst=Znovu zkontrolovat nejmen\u0161\u00ed stahov\u00e1n\u00ed jako prvn\u00ed
+platform.win32.baddll.info=Vuze detekoval p\u0159\u00edtomnost '%1'. To je sou\u010d\u00e1st\u00ed '%2' a je zn\u00e1m t\u00edm, \u017ee zp\u016fsobuje v\u00e1\u017en\u00e9 probl\u00e9my jako p\u00e1dy aplikac\u00ed a vysok\u00e9 vyu\u017eit\u00ed procesoru. Pokud na takov\u00e9 probl\u00e9my naraz\u00edte, tak pros\u00edm software odinstalujte nebo nastavte ho tak, aby neovliv\u0148oval Vuze.
+upnp.ignorebaddevices=Ignorovat za\u0159\u00edzen\u00ed, kter\u00e1 nedok\u00e1\u017e\u00ed spr\u00e1vn\u011b odpov\u011bd\u011bt
 upnp.ignorebaddevices.info=Sou\u010dasn\u011b ignorovan\u00e9 za\u0159\u00edzen\u00ed: %1
-upnp.ignorebaddevices.reset=Resetovat ignorovan\u00e9 za\u0159\u00edzen\u00ed
-upnp.ignorebaddevices.alert=UPnP za\u0159\u00edzen\u00ed v %1 je ignorov\u00e1no vzhledem k opakovan\u00fdm chb\u00e1m. Pod\u00edvejte se na UPnP plugin na nastaven\u00ed, kter\u00e9 se t\u00e9to akce t\u00fdkaj\u00ed.
-TorrentOptionsView.param.max.uploads.when.busy=Maxim\u00e1ln\u00ed odchoz\u00ed rychlost (KB/s) p\u0159i dosa\u017een\u00ed glob\u00e1ln\u00edho limitu odchoz\u00edch dat (0:zak\u00e1z\u00e1no)
-UpdateMonitor.messagebox.verification.failed.title=Ov\u011b\u0159en\u00ed instalace selhalo
+upnp.ignorebaddevices.reset=Resetovat seznam ignorovan\u00fdch za\u0159\u00edzen\u00ed
+upnp.ignorebaddevices.reset.action=Resetovat
+upnp.ignorebaddevices.alert=UPnP za\u0159\u00edzen\u00ed v um\u00edst\u011bn\u00ed %1 je ignorov\u00e1no vzhledem k opakovan\u00fdm chyb\u00e1m. Pod\u00edvejte se na nastaven\u00ed z\u00e1suvn\u00e9ho modulu UPnP pro mo\u017enosti t\u00fdkaj\u00edc\u00ed se t\u00e9to \u010dinnosti.
+TorrentOptionsView.param.max.uploads.when.busy=Maxim\u00e1ln\u00ed rychlost odes\u00edl\u00e1n\u00ed v KB/s p\u0159i dosa\u017een\u00ed glob\u00e1ln\u00edho limitu odes\u00edl\u00e1n\u00ed [0: zak\u00e1z\u00e1no]
+UpdateMonitor.messagebox.verification.failed.title=Ov\u011b\u0159en\u00ed Instalace Selhalo
 UpdateMonitor.messagebox.verification.failed.text=Ov\u011b\u0159en\u00ed '%1' selhalo: %2
-UpdateMonitor.messagebox.accept.unverified.title=P\u0159ijata neov\u011b\u0159en\u00e1 instalace
-UpdateMonitor.messagebox.accept.unverified.text='%1' nemohl b\u00fdt ov\u011b\u0159en jako ofici\u00e1ln\u00ed Vuze plugin.\nPokud to takov\u00fd plugin nen\u00ed, NEM\u011aLI byste d\u00e1le pokra\u010dovat.\nPokra\u010dovat v instalaci\u00a8?
+UpdateMonitor.messagebox.accept.unverified.title=P\u0159ijmout Neov\u011b\u0159enou Instalaci
+UpdateMonitor.messagebox.accept.unverified.text='%1' nemohl b\u00fdt ov\u011b\u0159en jako ofici\u00e1ln\u00ed z\u00e1suvn\u00fd modul Vuze.\nPokud  je to takov\u00fd z\u00e1suvn\u00fd modul, NEM\u011aLI byste d\u00e1le pokra\u010dovat.\nPokra\u010dovat v instalaci?
 FileView.BlockView.title=D\u00edly souboru
-FileView.BlockView.Done=Hotovo
-FileView.BlockView.Skipped=P\u0159esko\u010den\u00fd
+FileView.BlockView.Done=Dokon\u010den\u00e9
+FileView.BlockView.Skipped=P\u0159esko\u010den\u00e9
 FileView.BlockView.Active=Aktivn\u00ed
-FileView.BlockView.Outstanding=V\u00fdjime\u010dn\u00fd
-upnp.portchange.alert=N\u00e1sleduj\u00edc\u00ed porty byly zm\u011bn\u011bny, aby se p\u0159ede\u0161lo probl\u00e9m\u016fm UPnP: %1 [star\u00fd port=%2] %3 [star\u00fd port=%4]
-ConfigView.section.proxy.username.info=Pokud proxy server vy\u017eaduje autentifikaci, i kdy\u017e nen\u00ed \u017e\u00e1dn\u00e1 nadefinovan\u00e1, pou\u017eijte jako u\u017eivatelsk\u00e9 jm\u00e9no "<none>" (bez uvozovek)
-ConfigView.label.maxuploadswhenbusymin=Maxim\u00e1ln\u00ed odchoz\u00ed rychlost na torrent p\u0159i busy timer (s)
-MainWindow.menu.help.debug=Vygenerovat info o oprav\u011b chyb
+FileView.BlockView.Outstanding=Nedokon\u010den\u00e9
+ConfigView.label.tcplistenport=P\u0159\u00edchoz\u00ed naslouchaj\u00edc\u00ed TCP port
+ConfigView.label.udplistenport=Naslouchaj\u00edc\u00ed UDP port
+upnp.portchange.alert=N\u00e1sleduj\u00edc\u00ed porty byly zm\u011bn\u011bny, aby se p\u0159ede\u0161lo probl\u00e9m\u016fm se za\u0159\u00edzen\u00edm UPnP: %1 [star\u00fd port=%2] %3 [star\u00fd port=%4]
+ConfigView.section.proxy.username.info=Pokud proxy server vy\u017eaduje ov\u011b\u0159en\u00ed, i kdy\u017e nen\u00ed \u017e\u00e1dn\u00e9 nastaveno, pou\u017eijte \u0159et\u011bzec "<none>" jako u\u017eivatelsk\u00e9 jm\u00e9no(a)
+ConfigView.label.maxuploadswhenbusymin=Max rychlost stahov\u00e1n\u00ed na torrent, kdy\u017e je \u010dasova\u010d zanepr\u00e1zdn\u011bn [sek]
+MainWindow.menu.help.debug=Vytvo\u0159it Informace o Lad\u011bn\u00ed (Z\u00e1znam o P\u00e1du)
 DownloadManager.error.badsize=Nespr\u00e1vn\u00e1 velikost
-natpmp.info=NAT-PMP je alternativa Apple k UPnP a je podporov\u00e1na nov\u00fdmi leti\u0161tmi.\n\nPamatujte, \u017ee sou\u010dasn\u00e9 UPnP mus\u00ed b\u00fdt povoleno, aby mohlo b\u00fdt povoleno i NAT-PMP, proto\u017ee NAT-PMP je speci\u00e1ln\u00ed typ za\u0159\u00edzen\u00ed UPnP.
-natpmp.enable=Povolit (pamatujte, \u017ee toto tak\u00e9 mus\u00edte povolit v Leti\u0161tn\u00ed konfiguraci)
-ConfigView.section.tracker.host.addurls=Zabezpe\u010dit, \u017ee URL trackeru je obsa\u017eena v hostovan\u00fdch torrentech
-Tracker.announce.ignorePeerSeed=ignorovat klienti/distrubuto\u0159i count. %1
-TorrentOptionsView.param.reset.to.default=Vr\u00e1tit nastaven\u00ed na jejich p\u016fvodn\u00ed hodnoty
-natpmp.routeraddress=N\u00e1zev stanice (pokud ponech\u00e1te pr\u00e1zdn\u00e9, vypln\u00ed se samo)
-ConfigView.section.style.disableAlertSliding=Zak\u00e1zat zobrazen\u00ed posunuj\u00edc\u00ed se animace varovn\u00fdch zpr\u00e1v navrchu 
+natpmp.info=NAT-PMP je alternativa Apple k UPnP a je podporov\u00e1na nov\u00fdmi stanicemi na Leti\u0161ti.\n\nPamatujte, \u017ee v sou\u010dasnosti mus\u00ed b\u00fdt UPnP povoleno, aby mohlo b\u00fdt povoleno i NAT-PMP, proto\u017ee za\u0159\u00edzen\u00ed NAT-PMP se pova\u017euje za speci\u00e1ln\u00ed typ za\u0159\u00edzen\u00ed UPnP.
+natpmp.enable=Povolit (pamatujte, \u017ee toto tak\u00e9 mus\u00edte povolit v Leti\u0161tn\u00ed konfiguraci, aby to fungovalo)
+ConfigView.section.tracker.host.addurls=Ujistit se. \u017ee URL tohoto trackeru jsou p\u0159\u00edtomny v hostovan\u00fdch torrentech
+ConfigView.filter=zadejte text k filtrov\u00e1n\u00ed
+ConfigView.section.files.move=P\u0159esun po Dokon\u010den\u00ed
+ConfigView.section.file.defaultdir.section=Mo\u017enosti V\u00fdchoz\u00edho Adres\u00e1\u0159e
+ConfigView.section.file.defaultdir.auto=Automaticky stahovat do v\u00fdchoz\u00edho adres\u00e1\u0159e (Neptat se)
+ConfigView.section.file.defaultdir.bestguess=Pou\u017e\u00edt nejlep\u0161\u00ed odhady, p\u0159i v\u00fdb\u011bru v\u00fdchoz\u00edho adres\u00e1\u0159e ulo\u017een\u00ed
+ConfigView.section.file.defaultdir.ask=V\u00fdchoz\u00ed adres\u00e1\u0159:
+ConfigView.section.file.defaultdir.lastused=Aktualizovat v\u00fdchoz\u00ed adres\u00e1\u0159 na um\u00edst\u011bn\u00ed, kam bylo naposledy ulo\u017eeno
+ConfigView.section.file.config.section=Nastaven\u00ed Konfigurace
+ConfigView.section.file.config.currentdir=Sou\u010dasn\u00fd adres\u00e1\u0159 nastaven\u00ed:
+ConfigView.section.torrent.decoding=Dek\u00f3dov\u00e1n\u00ed Sad Znak\u016f
+ConfigView.section.logging.udptransport=Povolit u\u017evan\u011bn\u00e9 stopov\u00e1n\u00ed UDP p\u0159enosu
+Tracker.announce.ignorePeerSeed=Ignoruji po\u010det Klient\u016f/Distrubutor\u016f. %1
+ConfigView.section.connection.encryption.use_crypto_port=Pou\u017e\u00edt roz\u0161\u00ed\u0159en\u00ed trackeru '\u0161ifroport' pro zabr\u00e1nen\u00ed prost\u00fdch p\u0159\u00edchoz\u00edch pokus\u016f o p\u0159pojen\u00ed. N\u011bkter\u00e9 trackery toto nep\u0159ij\u00edmaj\u00ed a sel\u017eou s chybami jako "Neplatn\u00fd Port" nebo "Nepovolen\u00fd Argument"
+TorrentOptionsView.param.reset.to.default=Vr\u00e1tit nastaven\u00ed zp\u011bt na jejich v\u00fdchoz\u00ed hodnoty
+TorrentOptionsView.param.reset.button=Resetovat
+natpmp.routeraddress=N\u00e1zev stanice [pr\u00e1zdn\u00e9: auto]
+ConfigView.section.style.disableAlertSliding=Zak\u00e1zat posuvnou animaci/styl naho\u0159e pro varovn\u00e9 zpr\u00e1vy
 ConfigView.section.transfer.autospeed.maxinc=%1 maxim\u00e1ln\u00ed zv\u00fd\u0161en\u00ed za cyklus
 ConfigView.section.transfer.autospeed.maxdec=%1 maxim\u00e1ln\u00ed sn\u00ed\u017een\u00ed za cyklus
 ConfigView.section.transfer.autospeed.enabledownadj=Dovolit \u00fapravu rychlosti stahov\u00e1n\u00ed
-ConfigView.section.transfer.autospeed.downadjratio=Pom\u011br rychlost stahov\u00e1n\u00ed/rychlost odes\u00edl\u00e1n\u00ed (nap\u0159. 2.0 -> limit stahov\u00e1n\u00ed je dvakr\u00e1t v\u011bt\u0161\u00ed ne\u017e limit odes\u00edl\u00e1n\u00ed dat)
-ConfigView.section.transfer.autospeed.latencyfactor=Faktor pou\u017eit\u00fd ke spojen\u00ed skryt\u00fdch sm\u011bn k rychlostn\u00edm zm\u011bn\u00e1m (vy\u0161\u0161\u00ed \u010d\u00edsla sni\u017euj\u00ed citlivost)
+ConfigView.section.transfer.autospeed.downadjratio=Pom\u011br rychlosti Stahov\u00e1n\u00ed : Odes\u00edl\u00e1n\u00ed (nap\u0159. 2.0 -> limit rychlosti stahov\u00e1n\u00ed je dvojn\u00e1sobek rychlosti odes\u00edl\u00e1n\u00ed)
+ConfigView.section.transfer.autospeed.latencyfactor=Faktor pou\u017eit\u00fd ke spojen\u00ed zm\u011bn zpo\u017ed\u011bn\u00ed ke zm\u011bn\u00e1m rychlosti (vy\u0161\u0161\u00ed \u010d\u00edsla sni\u017euj\u00ed citlivost)
 ConfigView.section.transfer.autospeed.reset=Resetovat pokro\u010dil\u00e9 hodnoty
 ConfigView.section.transfer.autospeed.reset.button=Resetovat
-PeerColumn.activationCount=Klienti se sna\u017e\u00ed p\u0159ipojit: %1
-TableColumn.header.timesincedownload.info=\u010cas, kter\u00fd uplynul od doby, kdy byly sta\u017eena pro torrent posledn\u00ed data
-TableColumn.header.timesincedownload=\u010cas od stahov\u00e1n\u00ed
-TableColumn.header.timesinceupload.info=\u010cas, kter\u00fd uplynul od doby, kdy byly odesl\u00e1na torrent posledn\u00ed data torrentu
-TableColumn.header.timesinceupload=\u010cas od odes\u00edl\u00e1n\u00ed
+PeerColumn.activationCount=Klienti sna\u017e\u00edc\u00ed se p\u0159ipojit: %1
+TableColumn.header.timesincedownload.info=\u010cas, kter\u00fd uplynul od doby, kdy byla data pro tento torrent sta\u017eena
+TableColumn.header.timesincedownload=Ne\u010dinn\u00e9 Stahov\u00e1n\u00ed
+TableColumn.header.timesinceupload.info=\u010cas, kter\u00fd uplynul od doby, kdy byla data pro tento torrent odesl\u00e1na
+TableColumn.header.timesinceupload=Ne\u010dinn\u00e9 Odes\u00edl\u00e1n\u00ed
+PeersView.incomingreqcount=P\u0159\u00edchoz\u00ed Po\u017eadavky
 PeersView.incomingreqcount.info=Po\u010det p\u0159\u00edchoz\u00edch po\u017eadavk\u016f od klienta
+PeersView.outgoingreqcount=Odchoz\u00ed Po\u017eadavky
 PeersView.outgoingreqcount.info=Po\u010det odchoz\u00edch po\u017eadavk\u016f ke klientovi
+upnp.mapping.trackerclientudp=UDP Port Klient\u016f Trackeru
 upnp.mapping.dhtudp=Distribuovan\u00e1 datab\u00e1ze
-ConfigView.section.style.showiconbar=Zobrazit n\u00e1strojovou li\u0161tu
+ConfigView.section.connection.nondata.udp.same=Pou\u017e\u00edt stejn\u00fd UDP port pro Distribuovanou Datab\u00e1zi a UDP Tracker
+ConfigView.section.connection.tcp.enable=Povolit TCP
+ConfigView.section.connection.udp.enable=Povolit UDP
+ConfigView.section.style.showiconbar=Zobrazit Panel N\u00e1stroj\u016f
+MainWindow.menu.view.iconbar=Panel N\u00e1stroj\u016f
 MyTorrentsView.menu.rename=P\u0159ejmenovat
-MyTorrentsView.menu.rename.displayed=P\u0159ejmenovat zobrazen\u00e9 jm\u00e9no
-MyTorrentsView.menu.rename.save_path=P\u0159ejmenovat slo\u017eku, do kter\u00e9 se stahovan\u00e9 soubory ukl\u00e1daj\u00ed
-MyTorrentsView.menu.rename.displayed.enter.title=P\u0159ejmenovat zobrazen\u00e9 jm\u00e9no
-MyTorrentsView.menu.rename.displayed.enter.message=Vpi\u0161te nov\u00e9 jm\u00e9no, kter\u00e9 se bude zobrazovat p\u0159i tomto stahov\u00e1n\u00ed.\nPokud nebude veps\u00e1t \u017e\u00e1dn\u00fd text, Vuze pou\u017eije p\u016fvodn\u00ed jm\u00e9no.
+MyTorrentsView.menu.rename.displayed=P\u0159ejmenovat Zobrazen\u00e9 Jm\u00e9no
+MyTorrentsView.menu.rename.save_path=P\u0159ejmenovat Cestu Pro Ulo\u017een\u00ed
+AdvRenameWindow.title=P\u0159ejmenovat Stahov\u00e1n\u00ed
+AdvRenameWindow.message=Zadejte nov\u00e9 jm\u00e9no pro toto stahov\u00e1n\u00ed
+AdvRenameWindow.rename.torrent=P\u0159ejmenovat Torrent
+MyTorrentsView.menu.rename.displayed.enter.title=P\u0159ejmenovat Zobrazen\u00e9 Jm\u00e9no
+MyTorrentsView.menu.rename.displayed.enter.message=Zadejte nov\u00e9 jm\u00e9no k zobrazen\u00ed pro toto stahov\u00e1n\u00ed.
+MyTorrentsView.menu.edit_comment=Upravit Koment\u00e1\u0159
+MyTorrentsView.menu.edit_comment.enter.title=Upravit Koment\u00e1\u0159
+MyTorrentsView.menu.edit_comment.enter.message=Zadejte koment\u00e1\u0159 pro toto stahov\u00e1n\u00ed
+UIDebugGenerator.messageask.title=Gener\u00e1tor Lad\u011bn\u00ed
 UIDebugGenerator.messageask.text=Pros\u00edm zadejte popis chyby, kterou nahla\u0161ujete
-UIDebugGenerator.complete.title=Generace odstran\u011bn\u00ed chyb hotova
-UIDebugGenerator.complete.text=Pros\u00edm po\u0161lete soubor '%1'.\n\nKlikn\u011bte na OK pro otev\u0159en\u00ed okna k tomuto souboru.
-ConfigView.section.style.showProgramIcon=Zobrazit ikonu programu v seznamu soubor\u016f
+UIDebugGenerator.complete.title=Vytvo\u0159en\u00ed Lad\u011bn\u00ed Hotovo
+UIDebugGenerator.complete.text=Soubor lad\u011bn\u00ed m\u016f\u017ee b\u00fdt nalezen v '%1'.\n\nKlikn\u011bte na OK k otev\u0159en\u00ed okna souborov\u00e9ho syst\u00e9mu na tento soubor.
+ConfigView.section.style.showProgramIcon=Zobrazit ikonu programu ve sloupci n\u00e1zv\u016f
 ConfigView.section.style.showProgramIcon.tooltip=Zobrazen\u00ed mo\u017en\u00e1 bude vy\u017eadovat znovuotev\u0159en\u00ed, aby m\u011bly zm\u011bny \u00fa\u010dinek
-swt.alert.cant.update=Knihovna SWT na\u010dten\u00e1 z "%3" nem\u016f\u017ee b\u00fdt automaticky updatovan\u00e1 z  %1 na %2 (mmus\u00ed b\u00fdt na\u010dtena z  "%4"). Pros\u00edm pod\u00edvejte se na <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">the wiki</A> pro detaily.
+swt.alert.cant.update=Knihovna SWT na\u010dten\u00e1 z "%3" nem\u016f\u017ee b\u00fdt automaticky aktualizov\u00e1na z verze %1 na %2 (mus\u00ed b\u00fdt na\u010dtena z "%4"). Pros\u00edm pod\u00edvejte se na <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update"> wiki</A> pro podrobnosti.
 authenticator.savepassword=Pamatovat si moje heslo
-ConfigView.section.security.clearpasswords=Resetovat ulo\u017een\u00e9 hesla
+ConfigView.section.security.clearpasswords=Resetovat zapamatovan\u00e1 hesla
 ConfigView.section.security.clearpasswords.button=Resetovat
-Content.alert.notuploaded.title=Odeslan\u00e1 data nejsou kompletn\u00ed
-Content.alert.notuploaded.text=Odesl\u00e1n\u00ed '%1'nen\u00ed dokon\u010deno. Pokud te\u010f %2, klienti nebudou schopni kompletn\u011b st\u00e1hnout V\u00e1mi publikovan\u00e9 soubory.\n\nJste si jsit\u00fd, \u017ee chcete %2?
-Content.alert.notuploaded.multi.title=Odeslan\u00e1 data nejsou kompletn\u00ed
-Content.alert.notuploaded.multi.text=%1 V\u00e1mi publikovan\u00e9ho obsahu nen\u00ed kompletn\u011b distribuov\u00e1no. Pokud te\u010f %2, klienti nebudou schopni kompletn\u011b st\u00e1hnout V\u00e1mi publikovan\u00e9 soubory. Skute\u010dn\u011b chcete %2?\n\nTorrent nen\u00ed dostate\u010dn\u011b distrubuov\u00e1n:\n%3
-Content.alert.notuploaded.stop=ukon\u010d\u00edte torrent
-Content.alert.notuploaded.quit=opustit Azurea
 TorrentInfoView.torrent.encoding=K\u00f3dov\u00e1n\u00ed torrentu
-TorrentInfoView.columns=Sloupce z 'Moje Torrenty'
-progress.window.title=Operace pr\u00e1v\u011b prob\u00edh\u00e1
-progress.window.msg.filemove=Pros\u00edm \u010dekejte, dokud se soubor nep\u0159esune/nep\u0159ejmenuje
-ConfigView.label.popup.timestamp=P\u0159idat \u010dasom\u00edru k vyskakovac\u00edm varov\u00e1n\u00edm
-ConfigView.label.popup.autohide=Automaticky skr\u00fdvat vyskakuj\u00edc\u00ed (nechybov\u00e9) hl\u00e1\u0161en\u00ed po x sekund\u00e1ch (vpi\u0161te 0 pro zak\u00e1z\u00e1n\u00ed automatick\u00e9ho skr\u00fdv\u00e1n\u00ed)
-ConfigView.label.please.visit.here=Pros\u00edm pod\u00edvejte se sem na detaily
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
-#
+TorrentInfoView.columns=Sloupce ze zobrazen\u00ed '{library.name}'
+progress.window.title=Prob\u00edhaj\u00edc\u00ed Operace
+progress.window.msg.filemove=Pros\u00edm \u010dekejte, dokud p\u0159esun/p\u0159ejmenov\u00e1n\u00ed souboru nen\u00ed dokon\u010deno
+ConfigView.label.popup.timestamp=P\u0159idat \u010dasov\u00e1 raz\u00edtka k vyskakuj\u00edc\u00edm hl\u00e1\u0161en\u00edm
+ConfigView.label.popup.autohide=Automaticky skr\u00fdt vyskakuj\u00edc\u00ed nechybov\u00e1 hl\u00e1\u0161en\u00ed po x sekund\u00e1ch (nastavte na 0 pro zak\u00e1z\u00e1n\u00ed automatick\u00e9ho skr\u00fdv\u00e1n\u00ed)
+ConfigView.label.please.visit.here=Pros\u00edm nav\u0161tivte toto pro podrobnosti
+ConfigView.section.ipfilter.enable.descriptionCache=Ukl\u00e1dat popisy IP v do\u010dasn\u00e9m souboru
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Pokud je toto vypnuto, popisy nebudou zapamatov\u00e1ny
+OpenTorrentWindow.filesInfo=%1 z %2 bude st\u00e1hnuta.
+OpenTorrentWindow.diskUsage=%1 z %2
+ConfigView.label.openmytorrents=Otev\u0159\u00edt '{library.name}' p\u0159i spu\u0161t\u011bn\u00ed
+ConfigView.label.open_transfer_bar_on_start=Otev\u0159\u00edt Li\u0161tu P\u0159enosu p\u0159i spu\u0161t\u011bn\u00ed
+ConfigView.section.style.DNDalwaysInIncomplete=V\u017edy zobrazit torrenty se soubory "Nestahovat" v sekci Nedokon\u010den\u00e9 v {library.name}
+OpenTorrentWindow.mb.noGlobalDestDir.title=C\u00edlov\u00fd Adres\u00e1\u0159 nenalezen
+OpenTorrentWindow.mb.noGlobalDestDir.text=C\u00edlov\u00fd adres\u00e1\u0159 '%1' je neplatn\u00fd.
+OpenTorrentWindow.mb.noDestDir.title=C\u00edlov\u00fd Adres\u00e1\u0159 nenalezen
+OpenTorrentWindow.mb.noDestDir.text=C\u00edlov\u00fd adres\u00e1\u0159 '%1' pro torrent '%2' neexistuje nebo je neplatn\u00fd.
+OpenTorrentWindow.mb.notValid.title=Otev\u0159en\u00ed Torrentu Selhalo
+OpenTorrentWindow.mb.notValid.text=Nelze otev\u0159\u00edt torrent '%1'. Pokud ho otev\u00edr\u00e1te v re\u017eimu distribuce, ujist\u011bte se pros\u00edm, \u017ee datov\u00e9 soubory torrentu existuj\u00ed.
+OpenTorrentWindow.mb.notTorrent.title=Otev\u0159en\u00ed Torrentu Selhalo
+OpenTorrentWindow.mb.notTorrent.text=Nelze otev\u0159\u00edt '%1'. Nevypad\u00e1 to, \u017ee je to .torrent soubor.\n\nN\u011bkter\u00e1 z p\u0159ijat\u00fdch dat:\n%2
+ConfigView.label.pause.downloads.on.exit=Pozastavit stahov\u00e1n\u00ed p\u0159i ukon\u010den\u00ed
+ConfigView.label.resume.downloads.on.start=Pokra\u010dovat v pozastaven\u00fdch stahov\u00e1n\u00edch p\u0159i spu\u0161t\u011bn\u00ed po dokon\u010den\u00ed inicializace
+UIDebugGenerator.message.cancel.title=Vytvo\u0159en\u00ed Informac\u00ed o Lad\u011bn\u00ed Zru\u0161eno
+UIDebugGenerator.message.cancel.text=Nezadali jste popis chyby, kterou se sna\u017e\u00edte nahl\u00e1sit. Va\u0161e chyba V\u00e1m m\u016f\u017ee b\u00fdt jasn\u00e1, ale bez popisu, bychom pouze h\u00e1dali, jak\u00fd probl\u00e9m m\u00e1te.\n\nVytvo\u0159en\u00ed Informac\u00ed o Lad\u011bn\u00ed bylo zru\u0161eno.
+ConfigView.section.connection.group.http.info=Podpora HTTP distribuce
+ConfigView.section.connection.http.enable=Zapnout
+ConfigView.section.connection.http.port=\u010c\u00edslo p\u0159\u00edchoz\u00edho portu
+ConfigView.section.connection.http.portoverride=Potla\u010den\u00ed portu Trackeru HTTP [0: none]
+window.update.noupdates.title=Zkontrolovat V\u00fdsledky Aktualizace
+window.update.noupdates.text=Nejsou pro V\u00e1s dostupn\u00e9 \u017e\u00e1dn\u00e9 aktualizace.\n\nBlahop\u0159ejeme!
+ConfigView.label.bindip.details=P\u0159\u00edklad: 192.168.1.5;eth0;eth1[2] sv\u00e1\u017ee zadanou IP, se v\u0161emi IP 1. rozhran\u00ed a 3. IP 2. rozhran\u00ed.\n1. IP bude pou\u017eita pro v\u0161echny slu\u017eby, v\u0161echny ostatn\u00ed pro vyrovn\u00e1n\u00ed z\u00e1t\u011b\u017ee.\nJsou dostupn\u00e1 n\u00e1sleduj\u00edc\u00ed rozhran\u00ed:\n%1
+ConfigView.label.mindownloads=Min stahov\u00e1n\u00ed najednou
+UI.cannot_submit_blank_text=Mus\u00edte zadat hodnotu
+crypto.alert.as.warning=S\u00edt '%1' je zn\u00e1m\u00e1 pro zav\u00e1d\u011bn\u00ed formov\u00e1n\u00ed p\u0159enosu ke sn\u00ed\u017een\u00ed v\u00fdkonnosti stahov\u00e1n\u00ed. \u0160ifrov\u00e1n\u00ed p\u0159enosu bylo automaticky zapnuto - m\u016f\u017ee b\u00fdt vypnuto/zm\u011bn\u011bno p\u0159es parametry nastaven\u00ed.
+ConfigView.section.interface.alerts=Upozorn\u011bn\u00ed
+ConfigView.label.popupdownloadadded=Hl\u00e1\u0161en\u00ed vysko\u010d\u00ed, kdy\u017e je p\u0159id\u00e1no stahov\u00e1n\u00ed
+popup.download.added="%1" byl p\u0159id\u00e1n do Va\u0161eho seznamu stahov\u00e1n\u00ed.
+MessageBoxWindow.nomoreprompting=U\u017e se m\u011b neptat
+TorrentOptionsView.param.max.seeds=Maxim\u00e1ln\u00ed po\u010det p\u0159ipojen\u00ed zdroj\u016f [0: limit p\u0159ipojen\u00ed]
+TorrentOptionsView.param.alternative.value.enable=Alternativn\u00ed hodnota p\u0159i distribuci
+ConfigView.section.proxy.check.on.start=Zkontrolovat stav proxy p\u0159i spu\u0161t\u011bn\u00ed
+TransferStatsView.legend.pingaverage=Pr\u016fm\u011br
+TransferStatsView.legend.ping1=C\u00edl 1
+TransferStatsView.legend.ping2=C\u00edl 2
+TransferStatsView.legend.ping3=C\u00edl 3
+ConfigView.section.interface.enabletray._mac=Povolit Ikonu Li\u0161ty Stavu [vy\u017eadov\u00e1n restart]
+ConfigView.label.closetotray._mac=Zav\u0159en\u00ed minimalizuje do Ikony Syst\u00e9mov\u00e9 Li\u0161ty
+ConfigView.label.minimizetotray._mac=Minimalizace minimalizuje do Ikony Syst\u00e9mov\u00e9 Li\u0161ty
+OpenTorrentWindow.mb.existingFiles.title=Soubory ji\u017e existuj\u00ed!
+OpenTorrentWindow.mb.existingFiles.text=N\u011bkter\u00e9 ze soubor\u016f v c\u00edlov\u00fdch adres\u00e1\u0159\u00edch, kter\u00e9 jste zadali ji\u017e existuj\u00ed:\n\n%1\nPokud budete pokra\u010dovat, Vuze zkontroluje soubory v\u00fd\u0161e pro spr\u00e1vn\u00e1 data a p\u0159ep\u00ed\u0161e, pokud je pot\u0159eba.
+splash.unloadingTorrents=Uvol\u0148uji Torrenty
+splash.unloadingTorrent=Uvol\u0148uji Torrent
+ConfigView.section.file.defaultdir.autorename=Automaticky p\u0159ejmenovat data torrentu, pokud soubory v cest\u011b vypadaj\u00ed jinak
+ConfigView.section.file.defaultdir.autorename.tooltip=Toto zabran\u00ed, aby jeden torrent p\u0159epsal soubory jin\u00e9ho torrentu, kdy\u017e jsou jm\u00e9na souboru stejn\u00e1
+alert.raised.at.close=(Zpr\u00e1va z p\u0159edchoz\u00edho ukon\u010den\u00ed Vuze)
+Plugin.trackerpeerauth.name=Ov\u011b\u0159en\u00ed Klient\u016f Trackerem
+Plugin.trackerpeerauth.info=Tento z\u00e1suvn\u00fd modul pracuje s trackery pro ov\u011b\u0159en\u00ed, zda jsou klienti platn\u00fdmi \u010dleny \u00fa\u010dastn\u00edk\u016f
+Peers.column.maxupspeed=Max Rychlost Odes\u00edl\u00e1n\u00ed
+Peers.column.maxdownspeed=Max Rychlost Stahov\u00e1n\u00ed
+MyTorrents.items.DownSpeedLimit.disabled=\u017d\u00e1dn\u00e9 stahov\u00e1n\u00ed
+upnp.selectedaddresses=Adresy (odd\u011blen\u00e9 ';', s p\u0159edponou '-' =zam\u00edtnuty, '+' =povoleny) [pr\u00e1zdn\u00e9: v\u0161echny]
+upnp.alert.multipledevice.warning=Bylo zji\u0161t\u011bno mnoho UPnP za\u0159\u00edzen\u00ed - zkontrolujte, jestli v\u0161echna vy\u017eaduj\u00ed mapov\u00e1n\u00ed port\u016f (prohl\u00e9dn\u011bte si z\u00e1znam a nastaven\u00ed UPnP)
+UpdateMonitor.messagebox.restart.title=Aktualizace Software
+UpdateMonitor.messagebox.restart.text=Vuze pr\u00e1v\u011b dokon\u010dil stahov\u00e1n\u00ed d\u016fle\u017eit\u00e9 aktualizace a mus\u00ed b\u00fdt nyn\u00ed restartov\u00e1n, aby mohla b\u00fdt aktualizace nainstalov\u00e1na.
+PiecesView.BlockView.Have=M\u00e1m
+PiecesView.BlockView.NoHave=Nem\u00e1m
+PiecesView.BlockView.Header=%1 sloupc\u016f, %2 \u0159\u00e1dk\u016f, %3 d\u00edl\u016f
+ConfigView.section.update.autodownload=Automaticky stahovat aktualizace a dot\u00e1zat se, kdy\u017e je instalace p\u0159ipravena
+Peers.column.peer_id=ID Klienta
+Peers.column.peer_id.info=ID Klienta v \u010diteln\u00e9 form\u011b
+Peers.column.peer_byte_id=ID Klienta
+Peers.column.peer_byte_id.info=ID Klienta ve form\u011b bajt\u016f
+Peers.column.handshake_reserved=Bajty Vyhrazen\u00e9 Pro Zah\u00e1jen\u00ed Komunikace
+Peers.column.handshake_reserved.info=Ukazuje, kter\u00e9 vyhrazen\u00e9 bity byly nastaveny v zah\u00e1jen\u00ed komunikace BT
+Peers.column.client_identification=Identifikace Klienta
+Peers.column.client_identification.info=Ukazuje prost\u00e9 jm\u00e9na klient\u016f, kter\u00e9 Vuze obdr\u017eel - u\u017eite\u010dn\u00e9 pro lad\u011bn\u00ed
+dht.warn.user=Varovat o potenci\u00e1ln\u00edm probl\u00e9mu mapov\u00e1n\u00ed NAT/port
+ConfigView.label.openbar.incomplete=Li\u0161ty Stahov\u00e1n\u00ed: automaticky otev\u0159\u00edt stahov\u00e1n\u00ed
+ConfigView.label.openbar.complete=automaticky otev\u0159\u00edt zdroje
+ConfigView.label.transferbar.remember_location=Zapamatovat si posledn\u00ed pozici li\u0161ty p\u0159enosu
+ConfigView.section.transfer.autospeed.forcemin=%1 vynucen\u00e9 rychlosti odes\u00edl\u00e1n\u00ed p\u0159i anal\u00fdze p\u0159ipojen\u00ed
+MainWindow.menu.tools.speedtest=Zkou\u0161ka Rychlosti...
+speedtest.wizard.title=Zkou\u0161ka Rychlosti
+speedtest.wizard.run=Spustit zkou\u0161ku rychlosti
+speedtest.wizard.test.mode.updown=odes\u00edl\u00e1n\u00ed a stahov\u00e1n\u00ed
+speedtest.wizard.test.mode.up=odes\u00edl\u00e1n\u00ed
+speedtest.wizard.test.mode.down=stahov\u00e1n\u00ed
+SpeedTestWizard.test.panel.currinfo=Zkou\u0161ka \u0161\u00ed\u0159ky p\u00e1sma BitTorrent.
+SpeedTestWizard.test.panel.label=Zkou\u0161ka rychlosti Vuze:
+SpeedTestWizard.test.panel.already.running=Zkou\u0161ka ji\u017e b\u011b\u017e\u00ed!
+SpeedTestWizard.test.panel.not.accepted=\u017d\u00e1dost o zkou\u0161ku nebyla p\u0159ijata:
+SpeedTestWizard.test.panel.abort=P\u0159eru\u0161it
+SpeedTestWizard.test.panel.abort.countdown=p\u0159eru\u0161it zkou\u0161ku za:
+SpeedTestWizard.test.panel.test.countdown=dokon\u010den\u00ed zkou\u0161ky za:
+SpeedTestWizard.test.panel.testfailed=Zkou\u0161ka selhala
+SpeedTestWizard.test.panel.aborted=Zkou\u0161ka ru\u010dn\u011b p\u0159eru\u0161ena.
+SpeedTestWizard.test.panel.enc.label=Stiskn\u011bte pro zkou\u0161ku se \u0161ifrov\u00e1n\u00edm:
+SpeedTestWizard.test.panel.standard=standardn\u00ed
+SpeedTestWizard.test.panel.encrypted=za\u0161ifrov\u00e1no
+SpeedTestWizard.set.upload.button.apply=Pou\u017e\u00edt
+SpeedTestWizard.set.upload.result=Posledn\u00ed V\u00fdsledek Testu
+SpeedTestWizard.set.upload.bytes.per.sec=kBajt\u016f/sek
+SpeedTestWizard.set.upload.bits.per.sec=bity/sek
+SpeedTestWizard.finish.panel.title=Zkou\u0161ka Rychlosti Dokon\u010dena!
+SpeedTestWizard.finish.panel.click.close=Dokon\u010dili jste pr\u016fvodce zkou\u0161kou rychlosti. Klikn\u011bte na zav\u0159it pro dokon\u010den\u00ed.
+SpeedTestWizard.finish.panel.max.upload=Max odes\u00edl\u00e1n\u00ed :
+SpeedTestWizard.finish.panel.max.seeding.upload=Max odes\u00edl\u00e1n\u00ed p\u0159i distribuci :
+SpeedTestWizard.finish.panel.max.download=Max stahov\u00e1n\u00ed :
+SpeedTestWizard.finish.panel.enabled=zapnuto
+SpeedTestWizard.finish.panel.disabled=vypnuto
+SpeedTestWizard.abort.message.scheduled.in=zkou\u0161ka napl\u00e1nov\u00e1na za ... %1 sekund
+SpeedTestWizard.abort.message.unsupported.type=Nepodporovan\u00fd typ testu!!!!
+SpeedTestWizard.abort.message.manual.abort=Ru\u010dn\u011b p\u0159eru\u0161eno
+SpeedTestWizard.abort.message.scheduling.failed=Napl\u00e1nov\u00e1n\u00ed testu selhalo
+SpeedTestWizard.abort.message.download.added=Stahov\u00e1n\u00ed %1 bylo b\u011bhem zkou\u0161ky p\u0159id\u00e1no
+SpeedTestWizard.abort.message.entered.error=Zkou\u0161ka stahov\u00e1n\u00ed vstoupila do chybov\u00e9ho stavu '%1'
+SpeedTestWizard.abort.message.entered.queued=St\u00e1hnut\u00e1 zkou\u0161ka vstoupila do stavu ve front\u011b/zastaveno
+SpeedTestWizard.abort.message.interrupted=TorrentSpeedTestMonitorThread byl p\u0159eru\u0161en p\u0159ed dokon\u010den\u00edm zkou\u0161ky
+SpeedTestWizard.abort.message.execution.failed=Spu\u0161t\u011bn\u00ed zkou\u0161ky selhalo
+SpeedTestWizard.abort.message.failed.peers=Nelze se p\u0159ipojit k \u017e\u00e1dn\u00fdm klient\u016fm
+SpeedTestWizard.abort.message.insufficient.slots=Nelze odes\u00edlat k \u017e\u00e1dn\u00fdm klient\u016fm - nedostate\u010dn\u00e9 pozice odes\u00edl\u00e1n\u00ed?
+SpeedTestWizard.abort.message.not.unchoked=Nelze stahovat od \u017e\u00e1dn\u00fdch klient\u016f jako kdybyste nidky nep\u0159estali b\u00fdt jimi \u0161krceni
+SpeedTestWizard.stage.message.requesting=\u017e\u00e1d\u00e1m o zkou\u0161ku...
+SpeedTestWizard.stage.message.preparing=p\u0159ipravuji zkou\u0161ku...
+SpeedTestWizard.stage.message.starting=spou\u0161t\u00edm zkou\u0161ku...
+SpeedTestWizard.stage.message.connect.stats=Statistiky p\u0159ipojen\u00ed: klienti=%1, stah_ok=%2, odes_ok=%3
+window.uiswitcher.title=Zvolen\u00ed Rozhran\u00ed Vuze
+window.uiswitcher.text=Pros\u00edm vyberte u\u017eivatelsk\u00e9 rozhran\u00ed n\u00ed\u017ee, kter\u00e9 nejl\u00e9pe vyhovuje Va\u0161im pot\u0159eb\u00e1m.
+window.uiswitcher.NewUI.text=* Doporu\u010deno pro za\u010d\u00e1te\u010dn\u00edky a nov\u00e9 u\u017eivatele.\n\n Jednoduch\u00e9, intuitivn\u00ed grafick\u00e9 rozhran\u00ed
+window.uiswitcher.ClassicUI.title=Klasick\u00e9 Rozhran\u00ed
+window.uiswitcher.ClassicUI.text=* Zachov\u00e1v\u00e1 funk\u010dnost klienta \u0159ady 2.x\n\n* Klasick\u00e9 tabulkov\u00e9 zobrazen\u00ed
+iconBar.switch.tooltip=V\u00fdb\u011br Rozhran\u00ed Vuze
+VivaldiView.notAvailable=Zobrazen\u00ed Vivaldi nen\u00ed dostupn\u00e9
+restart.error=Restart selhal:\n%1\nPod\u00edvejte se na <A HREF="{restart.error.url}">probl\u00e9my s restartov\u00e1n\u00edm</a>.
+restart.error.oom=Do\u0161la Pam\u011b\u0165
+restart.error.fnf='%1' nebyl nalezen v '%2'
+restart.error.pnf=Cesta '%1' nenalezena
+restart.error.bad=\u0160patn\u00fd form\u00e1t dat pro '%1'
+restart.error.denied=P\u0159\u00edstup byl zam\u00edtnut p\u0159i pokusu o spu\u0161t\u011bn\u00ed '%1'. Ujist\u011bte se, \u017ee m\u00e1te pr\u00e1va ke spu\u0161t\u011bn\u00ed tohoto programu.
+TableColumn.header.date_completed=Kdy Dokon\u010deno
+TableColumn.menu.date_added.reset=Resetovat Datum
+ConfigView.section.ipfilter.discardbanning=Zablokovat klienty, jejich\u017e pom\u011br zahozen\u00fdch/dobr\u00fdch dat p\u0159es\u00e1hl [0: vypnuto]
+ConfigView.section.ipfilter.discardminkb=Minim\u00e1ln\u011b %1 zahozeno ne\u017e se pou\u017eije pom\u011br
+ConfigView.interface.start.advanced=Spustit v Pokro\u010dil\u00e9m Zobrazen\u00ed (AZ 2.x)
+MyTorrents.column.ColumnQuality=Kvalita
+MyTorrents.column.ColumnSpeed=Rychlost
+MyTorrents.column.ColumnProgressETA.2ndLine=P\u0159edpokl\u00e1dan\u00fd \u010das dokon\u010den\u00ed: %1
+MyTorrents.column.ColumnProgressETA.StreamReady=Streamov\u00e1n\u00ed P\u0159ipraveno
+MyTorrents.column.ColumnProgressETA.PlayableIn=P\u0159ehrateln\u00e9 za %1
+TableColumn.header.Quality=Kvalita
+TableColumn.header.Speed=Rychlost
+TableColumn.header.RateIt=Hodnotit
+TableColumn.header.Rating=Hodnocen\u00ed
+TableColumn.header.SpeedGraphic=Rychlost
+TableColumn.header.AzProduct=Od
+TableColumn.header.MediaThumb=M\u00e9dia
+TableColumn.header.ProgressETA=Postup
+TableColumn.header.name.ext=Typ Souboru: %1
+v3.MainWindow.tab.home=N\u00e1st\u011bnka
+v3.MainWindow.tab.browse=Na Vuze
+v3.MainWindow.tab.library=Knihovna
+v3.MainWindow.tab.publish=Publikovat
+v3.MainWindow.tab.advanced=Pokro\u010dil\u00e9
+v3.MainWindow.menu.home=&N\u00e1st\u011bnka
+v3.MainWindow.menu.browse=&Na Vuze
+v3.MainWindow.menu.library=&Knihovna
+v3.MainWindow.menu.publish=&Publikovat
+v3.MainWindow.menu.advanced=&Pokro\u010dil\u00e9
+v3.MainWindow.menu.view.searchbar=Li\u0161ta Hled\u00e1n\u00ed
+v3.MainWindow.menu.view.tabbar=Li\u0161ta Karty
+v3.MainWindow.currentDL=Nyn\u00ed Stahov\u00e1no
+v3.MainWindow.button.stream=Streamovat
+v3.MainWindow.button.stop=Zastavit
+v3.MainWindow.button.start=Za\u010d\u00edt
+v3.MainWindow.button.pause=Pozastavit
+v3.MainWindow.button.resume=Pokra\u010dovat
+v3.MainWindow.button.delete=Smazat
+v3.MainWindow.button.comment=Koment\u00e1\u0159
+v3.MainWindow.button.viewdetails=Zobrazit Podrobnosti
+v3.MainWindow.button.play=P\u0159ehr\u00e1t
+v3.MainWindow.button.cancel=Storno
+v3.MainWindow.button.preview=N\u00e1hled
+v3.MainWindow.view.wait=Spou\u0161t\u00edm zobrazen\u00ed, \u010dekejte pros\u00edm.
+v3.MainWindow.xofx=%1 z %2
+v3.MainWindow.Loading=Na\u010d\u00edt\u00e1m... \u010cekejte Pros\u00edm
+v3.filter-bar=Filtr N\u00e1zv\u016f:
+v3.MainWindow.search.defaultText=naj\u00edt...
+v3.mb.delPublished.title=Zastavit Distribuci Obsahu
+v3.mb.delPublished.text=Varov\u00e1n\u00ed: Tato \u010dinnost NEODSTRAN\u00cd V\u00e1\u0161 publikovan\u00fd obsah '%1' z A HREF="%2">%3</A> .\n\nKlikn\u011bte na "Smazat" pouze pokud chcete, aby V\u00e1\u0161 obsah z\u016fstal publikov\u00e1n a ke sta\u017een\u00ed, ale chcete uvolnit Va\u0161e p\u00e1smo propustnosti. Ujist\u011bte se, \u017ee proces odes\u00edl\u00e1n\u00ed byl dokon\u010den p\u0159edt\u00edm, ne\u017e tak ud\u011bl\u00e1te (<A HREF="%4">Jak</A>?).\n\nKlikn\u011bte na [...]
+v3.mb.delPublished.delete=S&mazat
+v3.mb.delPublished.cancel=&Storno
+v3.mb.PlayFileNotFound.title=Soubor Nenalezen
+v3.mb.PlayFileNotFound.text=Soubory pro '%' jsou bu\u010f smaz\u00e1ny, nebo chyb\u00ed.
+v3.mb.PlayFileNotFound.button.remove=Odstranit z Vuze
+v3.mb.PlayFileNotFound.button.redownload=Znovu St\u00e1hnout Data
+v3.mb.PlayFileNotFound.button.find=Ru\u010dn\u011b Naj\u00edt...
+v3.topbar.menu.show.plugin=Oblast z\u00e1suvn\u00fdch Modul\u016f
+v3.topbar.menu.show.search=Vyhled\u00e1v\u00e1n\u00ed
+v3.topbar.menu.show.frog=Ta Modr\u00e1 \u017d\u00e1ba
+splash.initializeCore=Zav\u00e1d\u00edm J\u00e1dro
+splash.initializeUIElements=Zav\u00e1d\u00edm Prvky Rozhran\u00ed
+ConfigView.section.transfer.autospeedbeta=Automatick\u00e1 Rychlost Beta
+ConfigView.section.ipfilter.peerblocking.group=Blokov\u00e1n\u00ed Klient\u016f
+ConfigView.section.ipfilter.autoload.group=Automatick\u00e9 Na\u010dten\u00ed
+ConfigView.section.ipfilter.autoload.file=Soubor IP filtru k automatick\u00e9mu na\u010dten\u00ed
+ConfigView.section.ipfilter.autoload.info=Podporuje form\u00e1ty DAT (eMule), P2P (PeerGuardian, splist), a P2B v1,2,3 (PeerGuardian 2). Soubor m\u016f\u017ee b\u00fdt m\u00edstn\u00ed nebo URL, zazipovan\u00fd, gzipovan\u00fd nebo prost\u00fd text. URL budou automaticky znovu sta\u017eeny po 7 dnech, zat\u00edmco soubory budou znovu na\u010dteny b\u011bhem minuty od nahrazen\u00ed/upraven\u00ed.
+ConfigView.section.ipfilter.autoload.loadnow=Na\u010d\u00edst hned
+splash.loadIpFilters=Na\u010d\u00edt\u00e1m IP Filtry...
+SpeedTestWizard.set.upload.title=Nastavit Limity Odes\u00edl\u00e1n\u00ed a Stahov\u00e1n\u00ed
+SpeedTestWizard.set.download.label=Limit Rychlosti Stahov\u00e1n\u00ed:
+SpeedTestWizard.set.upload.label=Limit Rychlosti Odes\u00edl\u00e1n\u00ed:
+SpeedTestWizard.name.conf.level.absolute=Absolutn\u00ed
+SpeedTestWizard.name.conf.level.high=Vysok\u00e1
+SpeedTestWizard.name.conf.level.med=St\u0159edn\u00ed
+SpeedTestWizard.name.conf.level.low=N\u00edzk\u00e1
+SpeedTestWizard.name.conf.level.none=\u017d\u00e1dn\u00e1
+ConfigView.section.transfer.select=Automatick\u00e1 Rychlost
+ConfigView.section.transfer.select.v2=Automatick\u00e1 Rychlost (beta)
+mb.azmustclose.title=Chyba P\u0159i Spu\u0161t\u011bn\u00ed
+mb.azmustclose.text=Vuze mus\u00ed b\u00fdt ukon\u010den kv\u016fli probl\u00e9mu (re)startov\u00e1n\u00ed Vuze, kter\u00e9 nejpravd\u011bpodobn\u011bji zap\u0159\u00ed\u010dinilo, \u017ee program byl spu\u0161t\u011bn jako Administr\u00e1tor.\n\nA\u017e bude Vuze uzav\u0159en, otev\u0159ete ho znovu ru\u010dn\u011b.
+network.ipv6.prefer.addresses=Up\u0159ednost\u0148ovat IPv6 adresy, kdy\u017e jsou ob\u011b IPv6 a IPv4 dostupn\u00e9.
+network.bindError=Sv\u00e1z\u00e1n\u00ed socketu serveru selhalo, proto\u017ee nejsou dostupn\u00e9 \u017e\u00e1dn\u00e9 kompatibiln\u00ed adresy, zkontrolujte pros\u00edm Va\u0161e nastaven\u00ed "sv\u00e1zat s IP".
+network.enforce.ipbinding=Vynutit sv\u00e1z\u00e1n\u00ed IP i kdy\u017e nejsou rozhran\u00ed dostupn\u00e1, zabra\u0148uje v\u0161em p\u0159ipojen\u00edm, pokud \u017e\u00e1dn\u00e1 z ur\u010den\u00fdch rozhran\u00ed nejsou dostupn\u00e1
+DHTView.title.full_v6=Distribuovan\u00e1 Datab\u00e1ze IPv6
+ConfigView.pluginlist.loadSelected=Na\u010d\u00edst Vybran\u00e9
+SpeedView.stats.asn=S\u00ed\u0165:
+SpeedView.stats.estupcap=Limit Odes\u00edl\u00e1n\u00ed:
+SpeedView.stats.estdowncap=Limit Stahov\u00e1n\u00ed:
+SpeedView.stats.unknown=Nezn\u00e1m\u00e1
+SpeedView.stats.estimate=Odhad
+SpeedView.stats.measured=Zm\u011b\u0159en\u00e1
+SpeedView.stats.measuredmin=Min Zm\u011b\u0159en\u00e1
+SpeedView.stats.manual=Pevn\u00e1
+ConfigView.section.transfer.autospeed.networks=Podrobnosti S\u00edt\u011b
+ConfigView.section.transfer.autospeed.resetnetwork=Resetovat podrobnosti s\u00edt\u011b
+ConfigView.section.transfer.autospeed.network.info=Limity v\u00fd\u0161e jsou b\u011b\u017en\u011b vypo\u010d\u00edt\u00e1v\u00e1ny automaticky b\u011bhem stahov\u00e1n\u00ed nebo jsou v\u00fdsledkem zkou\u0161ky rychlosti. Pokud je chcete nastavit ru\u010dn\u011b, pou\u017eijte volby n\u00ed\u017ee.\nV\u0161echny limity jin\u00e9 ne\u017e "pevn\u00e9" budou n\u00e1sledn\u011b automaticky upraveny podle pot\u0159eby.\nZadejte hodnotu a pak zvolte jej\u00ed typ. Nezapome\u0148te, \u017ee  [...]
+dialog.uiswitcher.restart.title=P\u0159ep\u00edna\u010d Rozhran\u00ed: Vy\u017eadov\u00e1n Restart Vuze
+dialog.uiswitcher.restart.text=Vuze pot\u0159ebuje b\u00fdt restartov\u00e1n, aby mohl b\u00fdt p\u0159epnut do nov\u00e9ho re\u017eimu rozhran\u00ed.
+TrayWindow.menu.close=Zav\u0159\u00edt Ko\u0161\u00edk pro Stahov\u00e1n\u00ed
 # Used for peers which we can't determine.
-PeerSocket.unknown=Nezn\u00e1m\u00fd 
-ConfigView.label.announceport=P\u0159epsat oznamovac\u00ed port trackeru
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
-iconBar.queue.tooltip=Fronta
-MainWindow.menu.help.faq=&Wiki \u010cast\u00e9 dotazy
-#what you've watched? Discover more with a single click...
-MainWindow.menu.help.donate=&Podpo\u0159it dotac\u00ed !!!
+PeerSocket.unknown=Nezn\u00e1m\u00fd
+PeerSocket.fake_client=FALE\u0160N\u00dd
+PeerSocket.bad_peer_id=\u0161patn\u00e1 ID Klienta
+PeerSocket.mismatch_id=neshoda
+PeerSocket.unknown_az_style=Nezn\u00e1m\u00fd %1 %2
+PeerSocket.unknown_shadow_style=Nezn\u00e1m\u00fd %1 %2
+OpenTorrentWindow.mb.askCreateDir.title=C\u00edlov\u00fd Adres\u00e1\u0159 neexistuje
+OpenTorrentWindow.mb.askCreateDir.text=C\u00edlov\u00fd adres\u00e1\u0159 '%1' neexistuje.\n\nVytvo\u0159it ho te\u010f?
+SpeedView.stats.estimatechoke=Odhad (p\u0159i\u0161krceno)
+ConfigTransferAutoSpeed.upload.capacity.usage=Vyu\u017eit\u00ed Kapacity Odes\u00edl\u00e1n\u00ed
+ConfigTransferAutoSpeed.mode=Re\u017eim:
+ConfigTransferAutoSpeed.capacity.used=% Pou\u017eit\u00e9 Kapacity
+ConfigTransferAutoSpeed.while.downloading=Stahov\u00e1n\u00ed:
+ConfigTransferAutoSpeed.set.dht.ping=Nastaven\u00ed Odezvy DHT:
+ConfigTransferAutoSpeed.set.point=nastaven\u00fd bod (ms)
+ConfigTransferAutoSpeed.ping.time.good=Dobr\u00e1:
+ConfigTransferAutoSpeed.ping.time.bad=\u0160patn\u00e1:
+ConfigTransferAutoSpeed.adjustment.interval=Interval \u00fapravy:
+ConfigTransferAutoSpeed.skip.after.adjust=P\u0159esko\u010dit po \u00faprav\u011b:
+GeneralView.label.distributedCopies=Distribuovan\u00e9 Kopie:
+PiecesView.DistributionView.title=Distribuce D\u00edl\u016f
+PiecesView.DistributionView.NoAvl=Nedostupn\u00e9 D\u00edly
+PiecesView.DistributionView.SeedAvl=Dostupn\u00fd P\u0159\u00edsp\u011bvek Distributora
+PiecesView.DistributionView.PeerAvl=Dostupn\u00fd P\u0159\u00edsp\u011bvek Klienta
+PiecesView.DistributionView.RarestAvl=Nejvz\u00e1cn\u011bj\u0161\u00ed D\u00edly: %1 (Dost:%2)
+PiecesView.DistributionView.weHave=D\u00edly, kter\u00e9 m\u00e1te
+PiecesView.DistributionView.theyHave=D\u00edly, kter\u00e9 m\u00e1 klient
+PiecesView.DistributionView.weDownload=D\u00edly, kter\u00e9 stahujete
+PeersView.gain=Zisk
+PeersView.gain.info=Mno\u017estv\u00ed sta\u017een\u00fdch - odeslan\u00fdch dat
+unix.script.new.title=Je dostupn\u00fd Nov\u00fd Spou\u0161t\u011bc\u00ed Skript Vuze
+unix.script.new.text=Je dostupn\u00fd nov\u00fd spou\u0161t\u011bc\u00ed skript Vuze, a byl ulo\u017een do '%1'.\n\nJe velmi doporu\u010deno, abyste Vuze ukon\u010dili a p\u0159e\u0161li na tento skript ('%2').\n\nPokud jste hodn\u011b zm\u011bnili V\u00e1\u0161 spou\u0161t\u011bc\u00ed skript Vuze pod\u00edvejte se pros\u00edm na <A HREF="{unix.script.new.manual.url}">VuzeWiki: Unix Skript</A>.\n\nPokud jste instalovali Vuze z distribuce (yum, apt-get, atd), doporu\u010dujeme p\u0159ein [...]
+unix.script.new.button.quit=Ukon\u010dit Hned
+unix.script.new.button.continue=Ud\u011bl\u00e1m To Pozd\u011bji
+unix.script.new.button.asknomore=U\u017e Mi Toto Neoznamovat
+unix.script.new.auto.title=Nov\u00fd Spou\u0161t\u011bc\u00ed Skript Vuze
+unix.script.new.auto.text=Je dostupn\u00fd nov\u00fd Spou\u0161t\u011bc\u00ed Skript Vuze.\n\nJe velmi doporu\u010deno, abyste Vuze hned restartovali.
+Content.alert.notuploaded.button.abort=&Nekon\u010dit
+ConfigView.label.checkOnSeeding=Prov\u00e9st zdrojov\u011b nen\u00e1ro\u010dn\u00e9 znovu zkontrolov\u00e1n\u00ed d\u00edl\u016f p\u0159i distribuci
+ConfigView.label.ui_switcher=Zobrazit V\u00fdb\u011br Rozhran\u00ed Vuze
+ConfigView.label.ui_switcher_button=Zobrazit
+SpeedTestWizard.test.panel.explain=Zm\u011b\u0159te Va\u0161i rychlost protokolu Vuze. Vyberte typ zkou\u0161ky rychlosti a re\u017eim \u0161ifrov\u00e1n\u00ed. Nav\u0161tivte str\u00e1nku Vuze wiki pro podrobnosti o t\u00e9to zkou\u0161ce. Zkou\u0161ka bude automaticky zastavena, pokud trv\u00e1 d\u00e9le ne\u017e dv\u011b minuty. Norm\u00e1ln\u00ed testy jsou dokon\u010deny za m\u00e9n\u011b ne\u017e minutu.
+SpeedTestWizard.set.upload.hint=Nastavte limity odes\u00edl\u00e1n\u00ed a stahov\u00e1n\u00ed pou\u017e\u00edvan\u00e9 algoritmem Automatick\u00e9 Rychlosti Vuze.
+SpeedTestWizard.set.upload.panel.explain=Limity zde jsou pou\u017eity algoritmem Automatick\u00e9 Rychlosti Vuze. Nastavte limity p\u0159enosu a limity jistoty.\n\nNezapome\u0148te, \u017ee rychlosti linky jsou \u010dasto vyj\u00e1\u0159eny v "bitech za sekundu" zat\u00edmco hodnoty n\u00ed\u017ee jsou vyj\u00e1d\u0159eny v "kilobajtech za sekundu".
+SpeedTestWizard.set.limit.conf.level=Jistota
+SpeedTestWizard.finish.panel.auto.speed=Automatick\u00e1 Rychlost je :
+SpeedTestWizard.finish.panel.auto.speed.seeding=Automatick\u00e1 Rychlost p\u0159i distribuci je :
+ConfigTransferAutoSpeed.add.comment.to.log.group=P\u0159idat koment\u00e1\u0159 do z\u00e1znamu lad\u011bn\u00ed
+ConfigTransferAutoSpeed.add.comment.to.log=P\u0159idat koment\u00e1\u0159:
+ConfigTransferAutoSpeed.log.button=Z\u00e1znam
+ConfigTransferAutoSpeed.algorithm.selector=V\u00fdb\u011br Automatick\u00e9 Rychlosti
+ConfigTransferAutoSpeed.algorithm=Algoritmus:
+ConfigTransferAutoSpeed.auto.speed.classic=Automatick\u00e1 Rychlost(klasick\u00e1)
+ConfigTransferAutoSpeed.auto.speed.beta=Automatick\u00e1 Rychlost(beta)
+ConfigTransferAutoSpeed.data.update.frequency=Frekvence Aktualizace
+Alert.failed.update=Instalace alespo\u0148 jedn\u00e9 komponenty selhala. Pod\u00edvejte se na <A HREF="{Alert.failed.update.url}">AzureusWiki: Aktualizace Selhala</A> [%1]
+OpenTorrentWindow.mb.existingFiles.partialList=(\u010c\u00e1ste\u010dn\u00fd seznam. V\u00edce soubor\u016f ji\u017e existuje)
+TableColumn.header.bad_avail_time.info=Kdy naposledy byla dostupn\u00e1 \u00fapln\u00e1 kopie stahov\u00e1n\u00ed
+TableColumn.header.bad_avail_time=\u00dapln\u00e1 Kopie Vid\u011bna
+MyTorrentsView.menu.exporthttpseeds=Exportovat HTTP URL zdroj\u016f do schr\u00e1nky
+SWT.alert.erroringuithread=Objevila se nezvl\u00e1dnuteln\u00e1 chyba v rozhran\u00ed, dal\u0161\u00ed chyby mohu b\u00fdt nahl\u00e1\u0161eny.
+ConfigView.label.minannounce=Minim\u00e1ln\u00ed interval mezi ozn\u00e1men\u00edm trackeru v sekund\u00e1ch
+ConfigView.label.maxnumwant=Omezit po\u010det klient\u016f, kter\u00e9 tracker m\u016f\u017ee vr\u00e1tit
+ConfigView.label.announceport=Potla\u010dit ozn\u00e1men\u00fd TCP port pro ozn\u00e1men\u00ed trackeru, pex a dht\n[nechte pr\u00e1zdn\u00e9: bez  potla\u010den\u00ed, 0: \u017e\u00e1dn\u00e1 p\u0159\u00edchoz\u00ed p\u0159ipojen\u00ed]
+ConfigView.label.noportannounce=Neoznamovat naslouchaj\u00edc\u00ed port trackeru (toto neovliv\u0148uje pex, dht)
+ConfigView.label.maxseedspertorrent=Max v\u00fdchoz\u00edch distributor\u016f na torrent [0: neomezen\u011b] 
+wizard.webseed=P\u0159idat HTTP Zdroje do torrentu
+wizard.webseed.title=HTTP Zdroje
+wizard.webseed.configuration=Nastaven\u00ed HTTP Zdroje
+wizard.webseed.adding=P\u0159id\u00e1v\u00e1m HTTP Zdroje
+GeneralView.label.private=Soukrom\u00fd Torrent:
+GeneralView.yes=Ano
+GeneralView.no=Ne
+ConfigView.label.userequestlimiting=Pou\u017e\u00edt p\u0159i\u0161krcov\u00e1n\u00ed po\u017eadavk\u016f m\u00edsto opo\u017ed\u011bn\u00fdch \u010dten\u00ed pro omezen\u00ed rychlost stahov\u00e1n\u00ed [nem\u00e1 \u017e\u00e1dn\u00fd efekt, kdy\u017e je rychlost stahov\u00e1n\u00ed limitov\u00e1na]
+ConfigView.label.userequestlimiting.tooltip=Omezen\u00ed po\u017eadavk\u016f nen\u00ed tak jemn\u00e9, jako opo\u017ed\u011bn\u00e9 \u010dten\u00ed, ale umo\u017e\u0148uje up\u0159ednost\u0148ov\u00e1n\u00ed stahov\u00e1n\u00ed na z\u00e1klad\u011b pozice ve front\u011b stahov\u00e1n\u00ed a m\u016f\u017ee zlep\u0161it v\u00fdkon s\u00edt\u011b
+ConfigView.label.userequestlimitingpriorities=P\u0159i dosa\u017een\u00ed limitu stahov\u00e1n\u00ed soust\u0159edit rychlost stahov\u00e1n\u00ed na \u010delo fronty stahov\u00e1n\u00ed
+ConfigView.section.logging.timestamp=Form\u00e1tovat soubory z\u00e1znamu \u010dasov\u00fdmi raz\u00edtky
+Peers.column.timetocomplete=Zb\u00fdvaj\u00edc\u00ed \u010cas
+Peers.column.timetocomplete.info=Zb\u00fdvaj\u00edc\u00ed \u010cas, ne\u017e klient bude dokon\u010den
+ConfigView.section.interface.display.suppress.file.download.dialog=Potla\u010dit vyskakuj\u00edc\u00ed dialogov\u00e9 okno St\u00e1hnut\u00ed Souboru
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Zobrazit pr\u016fb\u011bh v\u0161ech stahov\u00e1n\u00ed soubor\u016f v li\u0161t\u011b stavu m\u00edsto vyskakuj\u00edc\u00edho dialogov\u00e9ho okna
+FileDownload.canceled=Stahov\u00e1n\u00ed torrent souboru bylo \u00fasp\u011b\u0161n\u011b zru\u0161eno \u010dinnost\u00ed u\u017eivatele: %1
+Progress.reporting.status.canceled=Zru\u0161eno
+Progress.reporting.status.finished=Dokon\u010deno
+Progress.reporting.status.retrying=Zkou\u0161\u00edm Znovu...
+Progress.reporting.action.label.retry.tooltip=Zkusit znovu operaci
+Progress.reporting.action.label.remove.tooltip=Odstranit toto Hl\u00e1\u0161en\u00ed O Postupu z historie
+Progress.reporting.action.label.cancel.tooltip=Zru\u0161it operaci
+Progress.reporting.action.label.detail=Podrobnosti
+Progress.reporting.default.error=Selhalo
+Progress.reporting.no.reports.to.display=\u017d\u00e1dn\u00e1 hl\u00e1\u0161en\u00ed o postupu nejsou nyn\u00ed k dispozici.
+Progress.reporting.no.history.to.display=Neexistuj\u00ed \u017e\u00e1dn\u00e9 zpr\u00e1vy podrobnost\u00ed k zobrazen\u00ed.
+Progress.reporting.detail.history.limit=Denn\u00ed limit zpr\u00e1v (%1) pro tohoto OznamovatelePostupu byl p\u0159ekro\u010den; n\u00e1sledn\u00e9 zpr\u00e1vy nebudou p\u0159id\u00e1ny do historie
+Progress.reporting.statusbar.button.tooltip=Zobrazit okno Hl\u00e1\u0161en\u00ed o Postupu
+webui.bindip=Sv\u00e1zat IP - nen\u00ed norm\u00e1ln\u011b vy\u017eadov\u00e1no
+v3.MainWindow.text.log.in=P\u0159ihl\u00e1sit se
+v3.MainWindow.text.log.out=Odhl\u00e1sit Se
+v3.MainWindow.text.get.started=Registrovat Se
+v3.MainWindow.text.my.account=Informace o \u00da\u010dtu
+v3.MainWindow.text.my.profile=Profil
+OpenTorrentWindow.simple.open=Um\u00edst\u011bn\u00ed Torrentu (Soubor, URL, Hash)
+Progress.reporting.window.remove.auto=Automaticky odstranit neaktivn\u00ed polo\u017eky
+Progress.reporting.window.remove.auto.tooltip=Automaticky odstranit v\u0161echny dokon\u010den\u00e9, ne\u00fasp\u011b\u0161n\u00e9, nebo zru\u0161en\u00e9 procesy ze zobrazen\u00ed
+Progress.reporting.window.remove.now=Odstranit neaktivn\u00ed polo\u017eky
+Progress.reporting.window.remove.now.tooltip=Odstranit v\u0161echny dokon\u010den\u00e9, ne\u00fasp\u011b\u0161n\u00e9, nebo zru\u0161en\u00e9 procesy ze zobrazen\u00ed
+dhttracker.tracklimitedwhenonline=Nicm\u00e9n\u011b, prov\u00e1d\u011bt n\u00edzko zdrojov\u00e9 sledov\u00e1n\u00ed, kdy\u017e jste online pro populci k\u0159\u00ed\u017eem ppo\u010dtu \u00fa\u010dtn\u00edk\u016f
+TorrentOptionsView.multi.title.short=Mo\u017enosti Torrentu
+TorrentOptionsView.multi.title.full=Mo\u017enosti Torrentu
+MyTorrentsView.menu.open_parent_folder=Otev\u0159\u00edt Obsahuj\u00edc\u00ed Adres\u00e1\u0159
+ConfigView.section.style.use_show_parent_folder=Pou\u017e\u00edt "%1" m\u00edsto %2" v menu torrentu
+ConfigView.section.style.use_show_parent_folder.tooltip=Zapnut\u00edm t\u00e9to volby V\u00e1m umo\u017en\u00ed otev\u0159\u00edt obsahuj\u00edc\u00ed adres\u00e1\u0159 ve spr\u00e1vn\u00e9m programu pro spr\u00e1vu soubor\u016f.\nNicm\u00e9n\u011b, to tak\u00e9 m\u016f\u017ee znamenat, \u017ee m\u00edsto pro ulo\u017een\u00ed nen\u00ed automaticky vybr\u00e1no.
+PeerManager.status.ps_disabled=Zdroj klient\u016f Trackeru je vypnut
+ConfigView.section.stats.exportfiles=Exportovat podrobnosti souboru
+updater.cant.write.to.app.title=Nelze Zapisovat Do Adres\u00e1\u0159e Aplikace
+updater.cant.write.to.app.details=Do adres\u00e1\u0159e "%1" nelze zapsat.\n\nToto zabr\u00e1n\u00ed pou\u017eit\u00ed budouc\u00edch aktualizac\u00ed software\n\nPros\u00edm <a href="http://wiki.vuze.com/w/Failed_Update">pod\u00edvejte se na wiki pro podrobnosti</a>.
+plugin.install.class_version_error=Tento z\u00e1suvn\u00fd modul vy\u017eaduje ke spu\u0161t\u011bn\u00ed nov\u011bj\u0161\u00ed verzi Java.
+v3.MainWindow.tab.minilibrary=Stahov\u00e1n\u00ed
+v3.MainWindow.tab.events=Upozorn\u011bn\u00ed
+button.columnsetup.tooltip=Nastaven\u00ed Sloupc\u016f
+v3.activity.remove.title=Smazat Upozorn\u011bn\u00ed
+v3.activity.remove.text=Jste si jisti, \u017ee chcete smazat toto Upozorn\u011bn\u00ed?\n%1
+v3.MainWindow.menu.file.closewindow=Zav\u0159\u00edt
+Menu.show.torrent.menu=Zobrazit menu Torrenty
+Menu.show.torrent.menu.tooltip=Zobraz\u00ed menu Torrenty navrchu li\u0161ty menu aplikace
+Views.plugins.aznetstatus.title=Stav S\u00edt\u011b
+plugin.aznetstatus.pingtarget=Zjistit odezvu/cestu c\u00edle
+ConfigView.section.style.usePathFinder=Pou\u017e\u00edt 'Vyhled\u00e1va\u010d Cesty' m\u00edsto 'Vyhled\u00e1va\u010d'
+menu.sortByColumn=Se\u0159adit Podle %1
+MyTorrentsView.menu.manual.per_peer=Ru\u010dn\u00ed (na klienta)
+MyTorrentsView.menu.manual.shared_peers=Ru\u010dn\u00ed (nap\u0159\u00ed\u010d klienty)
+v3.button.removeActivityEntry=Odstranit Upozorn\u011bn\u00ed
+v3.splash.initSkin=Spou\u0161t\u00edm Vzhled Rozhran\u00ed
+v3.splash.hookPluginUI=P\u0159id\u00e1v\u00e1m Rozhran\u00ed Z\u00e1suvn\u00e9ho Modulu
+OpenTorrentWindow.mb.notTorrent.cannot.display=Data nelze spr\u00e1vn\u011b zobrazit
+MainWindow.menu.window.zoom.maximize=Maximalizovat
+MainWindow.menu.window.zoom.restore=Obnovit
+security.crypto.title=P\u0159\u00edstup K \u0160ifrovac\u00edmu Kl\u00ed\u010di
+security.crypto.encrypt=Zadejte pros\u00edm heslo k ochran\u011b Va\u0161eho nov\u011b vytvo\u0159en\u00e9ho \u0161ifrovac\u00edho kl\u00ed\u010de. Pros\u00edm toto heslo nezapome\u0148te, neexistuje \u017e\u00e1dn\u00fd zp\u016fsob jak ho obnovit, kdy\u017e se tak stane!
+security.crypto.decrypt=Pros\u00edm zadejte heslo k odem\u010den\u00ed Va\u0161eho \u0161ifrovac\u00edho kl\u00ed\u010de.
+security.crypto.reason=D\u016fvod pro operaci
+security.crypto.password=Heslo
+security.crypto.password2=Znovu zadejte heslo
+security.crypto.persist_for=Doba trv\u00e1n\u00ed hesla
+security.crypto.persist_for.dont_save=Neukl\u00e1dat
+security.crypto.persist_for.session=Tuto relaci
+security.crypto.persist_for.day=1 den
+security.crypto.persist_for.week=1 t\u00fdden
+security.crypto.persist_for.30days=30 dn\u00ed
+security.crypto.persist_for.forever=Nav\u017edy
+security.crypto.password.mismatch.title=Chyba Hesla
+security.crypto.password.mismatch=Zadan\u00e9 hodnoty hesel se neshoduj\u00ed, pros\u00edm zadejte znovu.
+ConfigView.section.security.group.crypto=Ve\u0159ejn\u00e9/Soukrom\u00e9 Kl\u00ed\u010de
+ConfigView.section.security.resetkey=Resetovat kl\u00ed\u010de
+ConfigView.section.security.resetkey.warning.title=Varov\u00e1n\u00ed o Ztr\u00e1t\u011b Dat
+ConfigView.section.security.resetkey.warning=Jste si jisti, \u017ee chcete resetovat Va\u0161e \u0161ifrovac\u00ed kl\u00ed\u010de? Pokud toto ud\u011bl\u00e1te, v\u0161echny informace za\u0161ifrovan\u00e9 pomoc\u00ed nich budou NAV\u017dDY ZTRACENY. Tak\u00e9 v\u0161ichni ostatn\u00ed klienti, kte\u0159\u00ed vlastn\u00ed V\u00e1\u0161 ve\u0159ejn\u00fd kl\u00ed\u010d, u\u017e nebudou moci s V\u00e1mi komunikovat, ani\u017e by neobdr\u017eeli V\u00e1\u0161 nov\u00fd kl\u00ed\u010d. Tak [...]
+ConfigView.section.security.unlockkey=V\u00fdslovn\u011b odemknout kl\u00ed\u010de
+ConfigView.section.security.unlockkey.button=Odemknout
+ConfigView.section.security.publickey=Ve\u0159ejn\u00fd kl\u00ed\u010d
+ConfigView.section.security.publickey.undef=Nen\u00ed nastaven
+ConfigView.section.security.resetkey.error.title=Operace Selhala
+ConfigView.section.security.resetkey.error=Nelze resetovat kl\u00ed\u010de
+ConfigView.section.security.unlockkey.error=Nelze odemknout kl\u00ed\u010d - nespr\u00e1vn\u00e9 heslo
+ConfigView.copy.to.clipboard.tooltip=Kop\u00edrovat do schr\u00e1nky
+Views.plugins.azbuddy.title=P\u0159\u00e1tel\u00e9
+Browser.popup.error.no.access=P\u0159i pokusu o p\u0159\u00edstup ke vzd\u00e1len\u00e9mu zdroji nastala chyba.\n Zkuste to, pros\u00edm, znovu pozd\u011bji.\n
+ConfigView.label.queue.stoponcebandwidthmet=Nespou\u0161t\u011bt \u017e\u00e1dn\u00e9 dal\u0161\u00ed torrenty, kdy\u017e je dosa\u017een limit odes\u00edl\u00e1n\u00ed/stahov\u00e1n\u00ed
+ConfigView.section.style.forceMozilla=Donutit Vuze pou\u017e\u00edvat Mozillu pro grafick\u00e9 komponenty Prohl\u00ed\u017ee\u010de [nutn\u00e9 m\u00edt xulrunner nebo firefox 3;vy\u017eadov\u00e1n restart]
+ConfigView.section.style.xulRunnerPath=Ru\u010dn\u011b ur\u010dit cestu XulRunner / Firefox [vy\u017eadov\u00e1no pro FF3; vy\u017eadov\u00e1n restart]
+azbuddy.name=P\u0159\u00e1tel\u00e9
+azbuddy.enabled=Zapnuto
+azbuddy.disabled=Z\u00e1suvn\u00fd modul je zak\u00e1z\u00e1n, pod\u00edvejte se na jeho konfiguraci pro zm\u011bnu.
+azbuddy.nickname=Va\u0161e P\u0159ezd\u00edvka
+azbuddy.msglog.title=Podrobnosti o P\u0159\u00edteli
+azbuddy.addtorrent.title=P\u0159ijmout Stahov\u00e1n\u00ed?
+azbuddy.addtorrent.msg=P\u0159\u00edtel '%1' V\u00e1m poslal '%2'.\nChcete p\u0159idat toto stahov\u00e1n\u00ed?
+azbuddy.contextmenu=Poslat P\u0159\u00edteli
+azbuddy.ui.mykey=M\u016fj kl\u00ed\u010d:
+azbuddy.ui.add=P\u0159idat
+azbuddy.ui.new_buddy=Kl\u00ed\u010d nov\u00e9ho p\u0159\u00edtele:
+azbuddy.ui.table.name=Jm\u00e9no
+azbuddy.ui.table.last_ygm=M\u00e1te Zpr\u00e1vu
+azbuddy.ui.table.last_msg=Posledn\u00ed Zpr\u00e1va
+azbuddy.ui.menu.remove=Odstranit
+azbuddy.ui.menu.copypk=Zkop\u00edrovat Ve\u0159ejn\u00fd Kl\u00ed\u010d
+azbuddy.ui.menu.send=Poslat Zpr\u00e1vu
+azbuddy.ui.menu.send_msg=Zadejte text, kter\u00fd p\u0159\u00e1tel\u016fm po\u0161lete
+azbuddy.ui.menu.ping=Odezva
+azbuddy.ui.menu.ygm=Poslat YGM
+azbuddy.ui.menu.enc=Za\u0161ifrovat Schr\u00e1nku
+azbuddy.ui.menu.dec=Roz\u0161ifrovat Schr\u00e1nku
+azbuddy.ui.menu.sign=Podepsat Schr\u00e1nku
+azbuddy.ui.menu.verify=Ov\u011b\u0159it Schr\u00e1nku
+azbuddy.ui.table.lastseen=Naposledy vid\u011bn
+Button.retry=Zkusit znovu
+Button.ignore=&Ignorovat
+DHTView.general.skew=Nesoum\u011brnost:
+azbuddy.ui.table.msg_in=Doru\u010den\u00e9 Zpr\u00e1vy
+azbuddy.ui.table.msg_out=Odeslan\u00e9 Zpr\u00e1vy
+v3.MainWindow.menu.view.footer=Z\u00e1pat\u00ed
+azbuddy.downspeed=KB/s max rychlost stahov\u00e1n\u00ed p\u0159\u00edtele [0: neomezen\u00e1]
+azbuddy.ui.table.con=Setk\u00e1n\u00ed
+security.crypto.badpw=Zadan\u00e9 heslo je nespr\u00e1vn\u00e9
+ConfigView.section.security.backupkeys=Z\u00e1lohovat kl\u00ed\u010de do souboru
+ConfigView.section.security.backupkeys.button=Z\u00e1loha
+ConfigView.section.security.restorekeys=Obnovit kl\u00ed\u010de ze souboru
+ConfigView.section.security.restorekeys.button=Obnovit
+ConfigView.section.security.op.error.title=Operace Selhala
+ConfigView.section.security.op.error=Nelze dokon\u010dit operaci:\n    %1
+ConfigView.section.security.restart.title=Vy\u017eadov\u00e1n Restart
+ConfigView.section.security.restart.msg=Vuze te\u010f bude restartov\u00e1n pro dokon\u010den\u00ed operace.
+ConfigView.section.security.system.managed=Chr\u00e1n\u011bn\u00ed kl\u00ed\u010d\u016f spravovan\u00fdch syst\u00e9mem
+azbuddy.ui.table.msg_queued=Ve front\u011b
+azbuddy.chat.says=%1 \u0159\u00edk\u00e1:
+Button.bar.show=Zobrazit
+Button.bar.hide=Skr\u00fdt
+Button.bar.share=Sd\u00edlet
+Button.bar.add=P\u0159idat
+Button.bar.edit=Upravit
+Button.bar.edit.cancel=\u00dapravy Dokon\u010deny
+v3.MainWindow.menu.view.pluginbar=Li\u0161ta Z\u00e1suvn\u00fdch Modul\u016f
+MainWindow.dialog.select.vuze.file=Vyberte Soubor Vuze
+MainWindow.menu.file.open.vuze=Soubor Vuze...
+metasearch.addtemplate.title=Instalovat \u0160ablonu Hled\u00e1n\u00ed?
+metasearch.addtemplate.desc=Jste si jisti, \u017ee chcete nainstalovat \u0161ablonu hled\u00e1n\u00ed s n\u00e1zvem '%1'?
+v3.share.private.title=Sd\u00edlen\u00ed Torrentu
+v3.share.private.text=Vybran\u00fd torrent je ozna\u010den jako Soukrom\u00fd Torrent.\n\nNem\u016f\u017eete sd\u00edlet soukrom\u00e9 torrenty.
+metasearch.addtemplate.dup.title=Duplik\u00e1tn\u00ed \u0160ablona
+metasearch.addtemplate.dup.desc=\u0160ablona hled\u00e1n\u00ed %1 je ji\u017e nainstalov\u00e1na
+metasearch.export.select.template.file=Ulo\u017eit \u0160ablonu
+metasearch.import.select.template.file=Otev\u0159\u00edt \u0160ablonu
+azbuddy.tracker.enabled=Zapn\u011bte 'Podpora P\u0159\u00e1tel' pro up\u0159ednost\u0148ov\u00e1n\u00ed stahov\u00e1n\u00ed s Va\u0161imi p\u0159\u00e1teli
+azbuddy.protocolspeed=max KB/s zpracov\u00e1n\u00ed protokolu p\u0159\u00edtele
+v3.MainWindow.button.download=St\u00e1hnout
+v3.MainWindow.button.run=Spustit St\u00e1hnut\u00fd Soubor
+v3.activity.header.downloads=Stahov\u00e1n\u00ed
+v3.activity.header.vuze.news=Novinky Vuze
+message.taking.too.long=Zd\u00e1 se, \u017ee to trv\u00e1 d\u00e9le, ne\u017e o\u010dek\u00e1v\u00e1no\nZm\u00e1\u010dkn\u011bte 'ESC', pokud si p\u0159ejete zru\u010dit tuto operaci
+message.status.success=\u00dasp\u011bch
+azbuddy.tracker.bbb.status.title=Podpora P\u0159\u00edtele
+azbuddy.tracker.bbb.status.title.tooltip=Klikn\u011bte dvakr\u00e1t pro podrobnosti
+azbuddy.tracker.bbb.status.idle=\u017d\u00e1dn\u00e1 Podpora
+azbuddy.tracker.bbb.status.nli=Vy\u017eadov\u00e1no P\u0159ihl\u00e1\u0161en\u00ed
+azbuddy.tracker.bbb.status.in=J\u00e1 Jsem Podporov\u00e1n
+azbuddy.tracker.bbb.status.out=Aktu\u00e1ln\u011b Podporuji P\u0159\u00e1tele
+v3.MainWindow.search.go.tooltip=Spustit Hled\u00e1n\u00ed
+v3.MainWindow.search.last.tooltip=Vr\u00e1tit se k v\u00fdsledk\u016fm hled\u00e1n\u00ed
+metasearch.addtemplate.done.title=\u0160ablona P\u0159id\u00e1na
+metasearch.addtemplate.done.desc=\u0160ablona '%1' byla \u00fasp\u011b\u0161n\u011b p\u0159id\u00e1na.\nBude pou\u017eita p\u0159i p\u0159\u00ed\u0161t\u00edm hled\u00e1n\u00ed!
+ConfigView.section.security.nopw=Nebylo poskytnuto \u017e\u00e1dn\u00e9 heslo
+ConfigView.section.security.nopw_v=\u017d\u00e1dn\u00e1 hesla nejsou dostupn\u00e1, p\u0159ihla\u0161te se, pros\u00edm, do Vuze
+fileplugininstall.install.title=Instalovat Z\u00e1suvn\u00fd Modul?
+fileplugininstall.install.desc=Jste si jisti, \u017ee chcete instalovat z\u00e1suvn\u00fd modul '%1', verze %2?
+fileplugininstall.duplicate.title=Duplik\u00e1tn\u00ed Z\u00e1suvn\u00fd Modul
+fileplugininstall.duplicate.desc=Z\u00e1suvn\u00fd modul '%1', verze %2 je ji\u017e nainstalov\u00e1n
+azbuddy.online_status=Stav Online
+azbuddy.os_away=Pry\u010d
+azbuddy.os_not_avail=Nedostupn\u00fd
+azbuddy.os_busy=Zanepr\u00e1zdn\u011bn
+azbuddy.ui.menu.disconnect=Odpojit
+azbuddy.enable_chat_notif=Zapnout upozorn\u011bn\u00ed chatu
+progress.window.msg.progress=Pros\u00edm \u010dekejte na dokon\u010den\u00ed operace
+ConfigView.section.connection.advanced.read_select=Vyp\u0159\u0161en\u00ed vybr\u00e1n\u00ed \u010dten\u00ed (ms, v\u00fdchoz\u00ed %1)
+ConfigView.section.connection.advanced.read_select_min=Minim\u00e1ln\u00ed \u010dek\u00e1n\u00ed na vybr\u00e1n\u00ed \u010dten\u00ed (ms, v\u00fdchoz\u00ed %1)
+ConfigView.section.connection.advanced.write_select=Vypr\u0161en\u00ed vybr\u00e1n\u00ed z\u00e1pisu (ms, v\u00fdchoz\u00ed %1)
+ConfigView.section.connection.advanced.write_select_min=Minim\u00e1ln\u00ed \u010dek\u00e1n\u00ed na vybr\u00e1n\u00ed \u010dten\u00ed (ms, v\u00fdchoz\u00ed %1)
+DetailedListView.title=Podrobn\u00fd Seznam
+ConfigView.section.connection.network.max.outstanding.connect.attempts=Max nevy\u0159\u00edzen\u00fdch odchoz\u00edch spojen\u00ed
+plugins.init.force_enabled=Vuze zjistil, \u017ee z\u00e1suvn\u00fd modul "%1" byl zak\u00e1z\u00e1n - byl znovu povolen, aby Vuze mohl spr\u00e1vn\u011b fungovat.
+ConfigView.section.connection.prefer.udp=Up\u0159ednost\u0148ovat UDP p\u0159ipojen\u00ed
+subscript.add.title=Instalovat Odb\u011br?
+subscript.add.desc=Jste si jisti, \u017ee chcete instalovat odb\u011br '%1'?
+subscript.add.dup.title=Duplik\u00e1tn\u00ed Odb\u011br
+subscript.add.dup.desc=Odb\u011br '%1' je ji\u017e nainstalov\u00e1n.
+subscript.add.upgrade.title=Aktualizovat Odb\u011br?
+subscript.add.upgrade.desc=Jste si jisti, \u017ee chcete aktualizovat odb\u011br '%1'?
+subscript.add.upgradeto.desc=Verze %1 odb\u011bru %2 je dostupn\u00e1.\nChcete aktualizovat?
+azsubs.contextmenu.addassoc=P\u0159idat sdru\u017een\u00ed odb\u011br\u016f
+azsubs.contextmenu.lookupassoc=Vyhledat sdru\u017een\u00ed odb\u011br\u016f
+iconBar.start=Spustit
+iconBar.stop=Zastavit
+iconBar.remove=Smazat
+iconBar.up=Nahoru
+iconBar.down=Dol\u016f
+iconBar.run=Otev\u0159\u00edt
+iconBar.editcolumns=Nastaven\u00ed Sloupc\u016f
+iconBar.top=Na za\u010d\u00e1tek
+iconBar.bottom=Na konec
+iconBar.queue=Spustit
+iconBar.open=P\u0159idat Torrent
+iconBar.share=Sd\u00edlet
+iconBar.share.tooltip=Sd\u00edlet Obsah
+iconBar.details=Podrobnosti
+iconBar.comment=Koment\u00e1\u0159
+iconBar.play=P\u0159ehr\u00e1t
+iconBar.queue.tooltip=Spustit (do fronty) vybran\u00e9 torrenty
+v3.MainWindow.menu.view.sidebar=Postrann\u00ed Li\u0161ta
+v3.MainWindow.menu.view.actionbar=Li\u0161ta \u010cinnost\u00ed
+v3.MainWindow.menu.view.toolbars=Panely N\u00e1stroj\u016f
+ump.install=Prob\u00edh\u00e1 Rychl\u00e1 Aktualizace:\nInstalov\u00e1n\u00ed mal\u00e9ho dodatku k p\u0159ehr\u00e1v\u00e1n\u00ed je vy\u017eadov\u00e1no pro toto video.
+subscriptions.listwindow.title=Vyhled\u00e1va\u010d Odb\u011br\u016f
+subscriptions.listwindow.autochecktext=Vuze m\u016f\u017ee naj\u00edt odb\u011bry souvisej\u00edc\u00ed s obsahem ve Va\u0161i knihovn\u011b. Chcete tuto funkci zapnout?
+subscriptions.listwindow.loadingtext=Hled\u00e1m odb\u011bry souvisej\u00edc\u00ed s %1
+subscriptions.listwindow.failed=Nebyly nalezeny \u017e\u00e1dn\u00e9 odb\u011bry
+subscriptions.listwindow.popularity=Popularita
+subscriptions.listwindow.popularity.unknown=Nezn\u00e1m\u00e1
+subscriptions.listwindow.name=N\u00e1zev
+subscriptions.listwindow.subscribe=Odeb\u00edrat
+TableColumn.header.azsubs.ui.column.subs=Odeb\u00edrat
+subscriptions.listwindow.popularity.reading=\u010ctu...
+PluginDeprecation.log.start=Toto okno obsahuje informace o z\u00e1suvn\u00fdch modulech, kter\u00e9 pou\u017e\u00edvaj\u00ed funkce, kter\u00e9 budou odstran\u011bny v budouc\u00edch verz\u00edch Vuze.\nNemus\u00edte tyto z\u00e1suvn\u00e9 moduly odinstalovat, m\u011bli byste z\u00e1suvn\u00e9 moduly aktualizovat na nejnov\u011bj\u0161\u00ed verzi.\nPokud pou\u017e\u00edv\u00e1te posledn\u00ed verzi, pak pros\u00edm zkop\u00edrujte obsah tohoto okna a po\u0161lete ho do f\u00f3ra um\u00e [...]
+PluginDeprecation.log.details=---------\nIDENTIFIK\u00c1TOR: %1\nKONTEXT: %2\n\n*** ZA\u010c\u00c1TEK SLEDOV\u00c1N\u00cd ***\n%3*** KONEC SLEDOV\u00c1N\u00cd ***\n\n
+PluginDeprecation.view=Lad\u011bn\u00ed Z\u00e1suvn\u00e9ho Modulu
+PluginDeprecation.alert=Zas\u00e1vn\u00fd modul se pokusil pou\u017eit funkci, kter\u00e1 bude v budoucnu odstran\u011bna - otev\u0159ete pros\u00edm Z\u00e1znam lad\u011bn\u00ed Z\u00e1suvn\u00e9ho Modulu pro v\u00edce informac\u00ed.
+TableColumn.header.Thumbnail=Ikona
+TableColumn.header.Thumbnail.info=Obr\u00e1zek miniatury pro obsah Vuze; pro jin\u00fd obsah jsou tyto ikony poskytnuty opera\u010dn\u00edm syst\u00e9mem.
+v3.MainWindow.menu.getting_started=&Za\u010d\u00edn\u00e1me
+MainWindow.menu.community=&Komunita
+MainWindow.menu.community.wiki=&Wiki a \u010cast\u00e9 Dotazy od Komunity
+MainWindow.menu.community.forums=F\u00f3&ra Komunity
+MainWindow.menu.help.support=&N\u00e1pov\u011bda a Podpora
+externalLogin.title=Vy\u017eadov\u00e1no P\u0159ihl\u00e1\u0161en\u00ed
+externalLogin.explanation=\u0160ablona "%1" vy\u017eaduje, abyste se p\u0159ihl\u00e1sili. Jakmile jste p\u0159ihl\u00e1\u0161en\u00ed, toto okno se utomaticky zav\u0159e. Pokud ne, klikn\u011bte na "hotovo".
+externalLogin.explanation.capture=Pro vytvo\u0159en\u00ed t\u00e9to \u0161ablony se mus\u00edte p\u0159ihl\u00e1sit. Jakmile jste p\u0159ihl\u00e1\u0161eni, pros\u00edm klikn\u011bte na "Hotovo".
+Button.done=Hotovo
+GeneralView.torrent_created_on_and_by=%1 od %2
+Button.continue=Pokra\u010dovat
+Button.preview=N\u00e1hled
+Subscription.menu.forcecheck=Aktualizovat Te\u010f
+Subscription.menu.clearall=Ozna\u010dit V\u0161echny V\u00fdsledky Jako P\u0159e\u010dten\u00e9
+Subscription.menu.remove=Smazat
+sidebar.LibraryDL=Stahuji...
+sidebar.LibraryCD=Dokon\u010den\u00e9
+authenticator.location=Um\u00edst\u011bn\u00ed
+authenticator.details=Podrobnosti
+v3.MainWindow.menu.showActionBarText=Zobrazit Text
+subscript.import.fail.title=Import Selhal
+subscript.import.fail.desc=Podrobnosti: %1
+Subscription.menu.export=Exportovat...
+subscript.export.select.template.file=Ulo\u017eit Odb\u011br
+Button.remove=Odstranit
+Button.send=Poslat
+Button.back=Zp\u011bt
+sidebar.LibraryUnopened=Nov\u00e9
+TableColumn.header.unopened=Nov\u00fd
+Unopened.bigView.header=Nov\u00e9
+Subscription.menu.deleteall=Smazat V\u0161echny V\u00fdsledky
+Subscription.menu.reset=Resetovat do Po\u010d\u00e1te\u010dn\u00edho Stavu
+ConfigView.section.Subscriptions=Odb\u011bry
+subscriptions.config.maxresults=Maxim\u00e1ln\u00ed po\u010det v\u00fdsledk\u016f uchovan\u00fdch na odb\u011br [0: neomezen\u011b]
+v3.activity.button.readall=Ozna\u010dit V\u0161e P\u0159e\u010dten\u00e9
+TableColumn.header.activityNew=Nov\u00e1
+TableColumn.header.activityType=Typ
+TableColumn.header.activityText=Zpr\u00e1va
+TableColumn.header.activityDate=Datum P\u0159id\u00e1n\u00ed
+TableColumn.header.activityActions=\u010cinnost
+Subscription.menu.resetauth=Resetovat Podrobnosti Ov\u011b\u0159en\u00ed
+Search.menu.engines=\u0160ablony
+Wizard.Subscription.title=Odb\u011br
+Wizard.Subscription.optin.title=Zapnout Odb\u011bry
+Wizard.Subscription.subscribe.title=Dostupn\u00e9 Odb\u011bry
+Wizard.Subscription.create.title=Vytvo\u0159it Nov\u00fd Odb\u011br
+Button.search=Hledat
+Button.save=Ulo\u017eit
+Button.add=P\u0159idat
+Button.createNewSubscription=Vytvo\u0159it Nov\u00fd Odb\u011br
+Button.availableSubscriptions=Dostupn\u00e9 Odb\u011bry
+Wizard.Subscription.optin.description=Se zapnut\u00fdmi odb\u011bry V\u00e1m bude Vuze zobrazovat odb\u011bry souvisej\u00edc\u00ed s obsahem ve Va\u0161i Knihovn\u011b, a d\u00e1 V\u00e1m v\u011bd\u011bt, kdy\u017e V\u00e1\u0161 odeb\u00edran\u00fd obsah je p\u0159ipraven ke sta\u017een\u00ed.\n\nCht\u011bli byste Odb\u011bry zapnout?
+Wizard.Subscription.create.search=Hledat
+Wizard.Subscription.search.subtitle1=Zadejte hled\u00e1n\u00ed pro zah\u00e1jen\u00ed vytv\u00e1\u0159en\u00ed Va\u0161eho odb\u011bru:
+Wizard.Subscription.search.subtitle2=Co m\u016f\u017eu hledat?
+Wizard.Subscription.search.subtitle2.sub1=HD Filmy, TV Seri\u00e1ly, Filmy, Filmov\u00e9 uk\u00e1zky na S\u00edti Vuze
+Wizard.Subscription.search.subtitle2.sub2=Torrenty z cel\u00e9ho Internetu
+Wizard.Subscription.search.subtitle3=Jakmile je V\u00e1\u0161 odb\u011br dokon\u010den, budete dost\u00e1vat aktualizace ve Va\u0161\u00ed postrann\u00ed li\u0161t\u011b, kdykoliv jsou dostupn\u00e9 nov\u00e9 v\u00fdsledky ve Va\u0161em hled\u00e1n\u00ed.
+Wizard.Subscription.rss.subtitle1=Zadejte nebo vlo\u017ete URL n\u00ed\u017ee:
+Wizard.Subscription.rss.subtitle2=Mnoho vydavatel\u016f poskytuje kan\u00e1ly RSS s jejich obsahem. Nalezn\u011bte URL na str\u00e1nce vydavatele, zkop\u00edrujte a vlo\u017ete ji do pole URL v\u00fd\u0161e, pak klikn\u011bte Ulo\u017eit.
+Wizard.Subscription.rss.subtitle3=Jakmile ulo\u017eeno, budete dost\u00e1vat aktualizace ve Va\u0161\u00ed postrann\u00ed li\u0161t\u011b, kdykoliv jsou dostupn\u00e9 nov\u00e9 v\u00fdsledky p\u0159es V\u00e1\u0161 kan\u00e1l RSS.
+Wizard.Subscription.subscribe.library=Obsah ve Va\u0161\u00ed Knihovn\u011b
+Wizard.Subscription.subscribe.subscriptions=Souvisej\u00edc\u00ed Odb\u011bry
+Wizard.Subscription.subscribe.library.empty=Nen\u00ed dostupn\u00fd \u017e\u00e1dn\u00fd odb\u011br?\n \nHledejte sv\u011btle oran\u017eov\u00e9 tla\u010d\u00edtko odb\u011bru v S\u00edti Vuze HD.\n \n <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Dov\u011bzte se v\u00edce</A>
+message.confirm.delete.title=Potvrdit Smaz\u00e1n\u00ed
+message.confirm.delete.text=Jste si jisti, \u017ee chcete smazat '%1'?
+Subscription.menu.properties=Vlastnosti...
+props.window.title=Vlastnosti pro '%1'
+subs.prop.is_auto=Automatick\u00e9 stahov\u00e1n\u00ed nov\u00fdch v\u00fdsledk\u016f
+subs.prop.last_scan=Posledn\u00ed \u00fasp\u011b\u0161n\u00e1 aktualizace
+subs.prop.last_result=Posledn\u00ed nalezen\u00fd nov\u00fd v\u00fdsledek
+subs.prop.last_error=Posledn\u00ed chyba
+subs.prop.num_read=Po\u010det p\u0159e\u010dten\u00fdch v\u00fdsledk\u016f
+subs.prop.num_unread=Po\u010det nep\u0159e\u010dten\u00fdch v\u00fdsledk\u016f
+subs.prop.template=\u0160ablona
+subs.prop.auth=Ov\u011b\u0159en\u00ed vy\u017eadov\u00e1no
+externalLogin.auth_method_proxy=Pou\u017e\u00edt roz\u0161\u00ed\u0159enou metodu zachyt\u00e1v\u00e1n\u00ed cookie. Pokud toto nefunguje, zru\u0161te tuto mo\u017enost a zkuste znovu
+externalLogin.wait=Str\u00e1nka se na\u010d\u00edt\u00e1, \u010dekejte pros\u00edm...
+TableColumn.menu.date_added.time=Zobrazit/Skr\u00fdt \u010cas
+sidebar.VuzeHDNetwork=S\u00ed\u0165 Vuze HD
+subs.prop.next_scan=Term\u00edn dal\u0161\u00edho prohled\u00e1n\u00ed
+subs.prop.assoc=Asociace
+subs.prop.version=Verze
+subscriptions.column.new.info=Ukazuje, jestli existuje jeden nebo v\u00edce nov\u00fdch v\u00fdsledk\u016f
+subscriptions.column.name=Odb\u011br
+subscriptions.column.nb-results=Celkov\u011b V\u00fdsledk\u016f
+subscriptions.column.nb-new-results=Nov\u00e9 V\u00fdsledky
+subscriptions.column.last-checked=Naposledy Kontrolov\u00e1no 
+subscriptions.view.title=Odb\u011bry
+subs.prop.is_public=Ve\u0159ejn\u00e9
+subs.prop.high_version=Nejvy\u0161\u0161\u00ed potkan\u00e1 verze
+Subscription.menu.upgrade=Povolit Aktualizaci Na Vy\u0161\u0161\u00ed Verzi
+metasearch.template.version.bad=\u0160ablona hled\u00e1n\u00ed '%1' nem\u016f\u017ee b\u00fdt nainstalov\u00e1na, dokud neaktualizujete Vuze
+metasearch.addtemplate.failed.title=Instalace Selhala
+metasearch.addtemplate.failed.desc=Nelze nainstalovat \u0161ablonu hled\u00e1n\u00ed: %1
+subscription.version.bad=Odb\u011br '%1' nem\u016f\u017ee b\u00fdt nainstalov\u00e1n, dokud neaktualizujete Vuze
+statusbar.feedback=Poslat Zp\u011btnou Vazbu
+statusbar.feedback.tooltip=Klikn\u011bte zde pro posl\u00e1n\u00ed zp\u011btn\u00e9 vazby
+sidebar.Activity=Upozorn\u011bn\u00ed
+v3.activity.button.watchall=Ozna\u010dit V\u0161e Sledovan\u00e9
+subscriptions.view.help.1=P\u0159idat Odb\u011bry kdekoliv je vid\u00edte
+subscriptions.view.help.2=Z\u00edskat zdarma aktualizace kdykoliv je nov\u00fd obsah dostupn\u00fd ke sta\u017een\u00ed. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Dov\u011bzte se v\u00edce</A>.
+sidebar.sash.tooltip=F7 pro rychl\u00e9 skryt\u00ed/zobrazen\u00ed postrann\u00ed li\u0161ty
+sidebar.expand.tooltip=Roz\u0161\u00ed\u0159it Postrann\u00ed Li\u0161tu
+sidebar.dropdown.tooltip=Zobrazit postrann\u00ed li\u0161tu ve form\u00e1tu menu
+subscript.all.subscribed=Odeb\u00edrate tento obsah
+subscript.some.subscribed=Odeb\u00edr\u00e1te n\u011bkter\u00e9 z odb\u011br\u016f tohoto obsahu.\nKlikn\u011bte pro zobrazen\u00ed dal\u0161\u00edch dostupn\u00fdch
+subscript.none.subscribed=Klikn\u011bte pro zobrazen\u00ed dostupn\u00fdch odb\u011br\u016f pro tento obsah
+v3.iconBar.up.tooltip=P\u0159esunout Nahoru\nDr\u017ete tla\u010d\u00edtko my\u0161i pro p\u0159esun na za\u010d\u00e1tek
+v3.iconBar.down.tooltip=P\u0159esunout Dol\u016f\nDr\u017ete tla\u010d\u00edtko my\u0161i pro p\u0159esun na konec
+TableColumn.header.azsubs.ui.column.subs_link=Spojen\u00ed
+TableColumn.header.azsubs.ui.column.subs_link.info=Spojen\u00e9 s odb\u011bry
+Button.deleteContent.fromLibrary=Odstranit z Knihovny
+Button.deleteContent.fromComputer=Vymazat z Po\u010d\u00edta\u010de
+v3.deleteContent.message=\nChcete smazat '%1' z Va\u0161eho po\u010d\u00edta\u010de, nebo ho jen odstranit z Va\u0161\u00ed Knihovny Vuze?
+v3.MainWindow.menu.view.toolbartext=Text Panelu N\u00e1stroj\u016f
+v3.MainWindow.menu.view.asSimpleList=Jednoduch\u00fd Seznam
+v3.MainWindow.menu.view.asAdvancedList=Pokro\u010dil\u00fd Seznam
+v3.MainWindow.menu.view.statusbar=Li\u0161ta Stavu
+Subscription.menu.dirtyall=Ozna\u010dit V\u0161echny V\u00fdsledky Jako Nep\u0159e\u010dten\u00e9
+configureWizard.file.message3=Vuze bude stahovat soubory do ur\u010den\u00e9ho adres\u00e1\u0159e, ten m\u016f\u017eete zadat zde:
+v3.deleteContent.applyToAll=Pou\u017e\u00edt \u010dinnost u v\u0161ech %1 zvolen\u00fdch polo\u017eek
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=Torrenty, kter\u00e9 nic neodes\u00edlaj\u00ed
+v3.MainWindow.menu.contentnetworks=HD &S\u00edt\u011b
+v3.MainWindow.menu.contentnetworks.about=O HD S\u00edt\u00edch
+Peers.column.as.info=Podrobnosti AS (Autonomn\u00ed Syst\u00e9m) Klienta
+ConfigTransferAutoSpeed.auto.speed.neural=Neur\u00e1ln\u00ed (Gudy Alfa)
+ConfigView.label.autoopen.downloadbars=Automaticky otev\u0159\u00edt Li\u0161ty Stahov\u00e1n\u00ed kdy\u017e
+ConfigView.label.autoopen=Auto Otev\u0159\u00edt
+ConfigView.label.autoopen.detailstab=Automaticky otev\u0159\u00edt Kartu Podrobnost\u00ed kdy\u017e
+ConfigView.label.systray=Syst\u00e9mov\u00e1 Li\u0161ta
+ConfigView.label.systray._mac=Ikona Li\u0161ty Stavu
+ConfigView.section.interface.legacy=Zastaral\u00e9
+v3.MainWindow.menu.contentnetworks.manage=Spravovat &HD S\u00edt\u011b
+azbuddy.ui.table.loc_cat=Odeslan\u00e9 Kat
+azbuddy.ui.table.rem_cat=Doru\u010den\u00e9 Kat
+azbuddy.ui.menu.cat=Kategorie
+azbuddy.ui.menu.cat.share=Povolit odb\u011bry s p\u0159\u00e1teli
+azbuddy.ui.menu.cat.set=Zadejte kategorie
+azbuddy.ui.menu.cat.set_msg=Seznam kategori\u00ed odd\u011blen\u00fdch \u010d\u00e1rkou, nebo 'V\u0161e'
+azbuddy.ui.menu.cat_subs=Po\u017e\u00e1dat o odb\u011br
+subs.prop.update_period=Interval aktualizace
+azbuddy.enable_cat_pub=Ve\u0159ejn\u00e9 kategorie, kter\u00e9 V\u0160ICHNI Va\u0161i p\u0159\u00e1tel\u00e9 mohou odeb\u00edrat (odd\u011blen\u00e9 '.')
+azbuddy.ui.table.read_cat=P\u0159e\u010dten\u00e1 Kat
+TableColumn.header.#=\u010c.
+TableColumn.header.#.info=\u010c\u00edslo Pozice/Po\u0159ad\u00ed
+TableColumn.header.category.info=Jm\u00e9no kategorie, do kter\u00e9 torrent pat\u0159\u00ed
+TableColumn.header.DateCompleted.info=Datum, kdy stahov\u00e1n\u00ed torrentu bylo dokon\u010deno
+TableColumn.header.AzProduct.info=S\u00ed\u0165 obsahu, \u017e kter\u00e9ho torrent poch\u00e1z\u00ed
+TableColumn.header.health.info=Jak zdrav\u00e9 je Va\u0161e p\u0159ipojen\u00ed k \u00fa\u010dastn\u00edk\u016fm torrentu
+TableColumn.header.maxuploads.info=Maxim\u00e1ln\u00ed po\u010det klient\u016f, kter\u00fdm soub\u011b\u017en\u011b odes\u00edlat
+TableColumn.header.name.info=N\u00e1zev Torrentu
+TableColumn.header.unopened.info=P\u0159\u00edznak ozna\u010duj\u00edc\u00ed, zda-li torrent byl p\u0159ehr\u00e1v\u00e1n (otev\u0159en)
+TableColumn.header.savepath.info=C\u00edlov\u00fd adres\u00e1\u0159 nebo soubor pro data torrentu
+TableColumn.header.SeedingRank.info=Hodnocen\u00ed, jak moc torrent pot\u0159ebuje distribuci. Vy\u0161\u0161\u00ed hodnota znamen\u00e1 vy\u0161\u0161\u00ed pot\u0159ebu.
+TableColumn.header.shareRatio.info=Jak moc jste odeslali (sd\u00edleli) v porovn\u00e1n\u00ed, jak moc jste st\u00e1hli.
+TableColumn.header.size.info=Velikost obsahu torrentu na disku
+TableColumn.header.azsubs.ui.column.subs.info=Tla\u010d\u00edtko, kter\u00e9 V\u00e1m umo\u017en\u00ed odeb\u00edrat kan\u00e1l obsahuj\u00edc\u00ed souvisej\u00edc\u00ed torrenty
+TableColumn.header.upspeed.info=Sou\u010dasn\u00e1 rychlost odes\u00edl\u00e1n\u00ed
+TableColumn.header.downspeed.info=Sou\u010dasn\u00e1 rychlost stahov\u00e1n\u00ed
+TableColumn.header.up.info=Sou\u010dasn\u00e9 mno\u017estv\u00ed dat odeslan\u00e1 ostatn\u00edm klient\u016fm
+TableColumn.header.down.info=Sou\u010dasn\u00e9 mno\u017estv\u00ed dat, p\u0159ijat\u00e9 od ostatn\u00edch u\u017eivatel\u016f
+TableColumn.header.ProgressETA.info=Kombinuje sloupce Stav, Dokon\u010den\u00ed, \u010cas dokon\u010den\u00ed, a Rychlost Stahov\u00e1n\u00ed do jednoho mnoho\u0159\u00e1dkov\u00e9ho sloupce.
+TableColumn.header.eta.info=Odhadnut\u00fd \u010das, ne\u017e stahov\u00e1n\u00ed torrentu je dokon\u010deno
+Pieces.column.#=\u010c.
+Pieces.column.#.info=\u010c\u00edslo D\u00edlu
+Peers.column.%.info=Procento torrentu, kter\u00e9 klient doposud st\u00e1hl
+TableColumn.header.download.info=Mno\u017estv\u00ed dat, p\u0159ijat\u00e9 od klienta
+TableColumn.header.upload.info=Mno\u017estv\u00ed dat, kter\u00e1 jsme odeslali klientovi
+TableColumn.header.downloadspeed.info=Rychlost, kterou od klienta dost\u00e1v\u00e1me
+TableColumn.header.uploadspeed.info=Rychlost, p\u0159i kter\u00e9 odes\u00edl\u00e1me data klientovi
+TableColumn.header.lan.info=P\u0159\u00edznak ozna\u010duj\u00edc\u00ed, jestli je klient na Va\u0161\u00ed LAN
+TableColumn.header.downloadspeedoverall.info=Odhadnut\u00e1 rychlost stahov\u00e1n\u00ed od klienta
+Peers.column.pieces.info=Grafick\u00e1 li\u0161ta, reprezentuj\u00edc\u00ed, kter\u00e9 d\u00edly si klient st\u00e1hnul
+TableColumn.header.TableColumnNameInfo=Jm\u00e9no Sloupce a Popis
+TableColumn.header.TableColumnSample=P\u0159\u00edklad
+TableColumn.header.TableColumnInfo=Popis Sloupce
+TableColumn.header.TableColumnChosenColumn=Zvolen\u00fd Sloupec
+subs.prop.is_auto_ok=Automatick\u00e9 stahov\u00e1n\u00ed dovoleno
+label.learnmore=Dozv\u011bd\u011bt se v\u00edce
+ColumnSetup.title=Nastaven\u00ed Sloupce pro '%1'
+ColumnSetup.explain=Prohl\u00e9dn\u011bte si dostupn\u00e9 sloupce vlevo, a p\u0159idejte je do seznamu zobrazen\u00fdch sloupc\u016f vpravo. Roz\u0161i\u0159te nebo zu\u017ete seznam dostupn\u00fdch sloupc\u016f pou\u017eit\u00edm sekce Filtr vlevo dole. Kl\u00e1vesov\u00e9 zkratky T\u00e1hnut\u00ed a Pu\u0161t\u011bn\u00ed jsou tak\u00e9 podporov\u00e1ny.
+ColumnSetup.chosencolumns=Zvolen\u00e9 Sloupce
+ColumnSetup.proficiency=Odbornost:
+ColumnSetup.categories=Kategorie:
+ColumnSetup.filters=Filtry
+ColumnSetup.availcolumns=Dostupn\u00e9 %1 sloupce
+ColumnSetup.availcolumns.filteredby=Dostupn\u00e9 %1 sloupce filtrovan\u00e9 podle %2
+devices.view.title=Za\u0159\u00edzen\u00ed
+device.renderer.view.title=Vykreslova\u010de
+device.mediaserver.view.title=M\u00e9dia Servery
+device.router.view.title=Routery
+device.model.desc=Popis modelu
+device.model.name=N\u00e1zev modelu
+device.model.num=\u010c\u00edslo modelu
+device.manu.desc=V\u00fdrobce
+device.router.is_mapping=Automatick\u00e9 mapov\u00e1ni port\u016f
+device.router.req_map=Po\u017eadovan\u00e9 mapov\u00e1n\u00ed
+device.router.configure=Nastavit UPnP
+device.mediaserver.configure=Nastavit Server Moje M\u00e9dium
+device.hide=Skr\u00fdt Za\u0159\u00edzen\u00ed
+device.show=Zobrazit Skryt\u00e1 Za\u0159\u00edzen\u00ed
+device.search=Hledat Za\u0159\u00edzen\u00ed
+device.router.con_type=P\u0159ipojen\u00ed: %1
+device.browse=Proch\u00e1zet
+device.upnp.desc_url=Popis Za\u0159\u00edzen\u00ed
+device.upnp.present_url=Spr\u00e1va Za\u0159\u00edzen\u00ed
+ConfigView.label.maxStalledSeeding=Maximum 'pozdr\u017een\u00fdch' [0:neomezen\u011b]
+device.search.auto=Automaticky hledat za\u0159\u00edzen\u00ed
+devices.sidebar.simple=Jednoduch\u00e9 Zobrazen\u00ed
+devices.xcode.working_dir=Oblast P\u0159evodu K\u00f3du
+devices.xcode.prof_def=V\u00fdchoz\u00ed profil p\u0159evodu k\u00f3du
+devices.xcode.profs=Dostupn\u00e9 profily p\u0159evodu k\u00f3du
+device.lastseen=Naposledy vid\u011bno
+devices.contextmenu.xcode=P\u0159ev\u00e9st K\u00f3d Pro Za\u0159\u00edzen\u00ed
+devices.device=Za\u0159\u00edzen\u00ed
+devices.profile=Profil
+General.percent=Procent
+devices.installed=Instalov\u00e1n
+devices.comp.missing=Podpora Vuze nen\u00ed nainstalov\u00e1na
+devices.state=Stav
+MainWindow.menu.help.donate=&Podpo\u0159it Dotac\u00ed
+DonationWindow.noload.title=D\u00e1rcovstv\u00ed
+DonationWindow.noload.text=Okno darov\u00e1n\u00ed nelze na\u010d\u00edst. Zkuste to, pros\u00edm, pozd\u011bji.
+devices.xcode.only.show=Na Za\u0159\u00edzen\u00ed Zobrazovat Pouze P\u0159eveden\u00e9 Soubory
+device.quit.transcoding.title=Prob\u00edh\u00e1 p\u0159ev\u00e1d\u011bn\u00ed k\u00f3du
+device.quit.transcoding.text='%1' je nyn\u00ed p\u0159ev\u00e1d\u011bn do '%2' a je %3% dokon\u010deno.\nPokud te\u010f odejdete, toto bude muset b\u00fdt restartov\u00e1no ze za\u010d\u00e1tku p\u0159i p\u0159\u00ed\u0161t\u00edm spu\u0161t\u011bn\u00ed.
+download.removerules.unauthorised.data=\tOdstranit data
+device.config.xcode.maxbps=Max rychlost p\u0159ev\u00e1d\u011bn\u00ed k\u00f3du v KB/sec [0: neomezen\u011b]
+device.xcode=P\u0159evod k\u00f3du
+device.xcode.always=V\u017edy
+device.xcode.whenreq=Kdy\u017e je pot\u0159eba
+device.xcode.never=Nikdy
+devices.copy.pending=Nevy\u0159\u00edzen\u00e9 kopie soubor\u016f
+devices.sidebar.hide.rend.generic=Skr\u00fdt obecn\u00e1 za\u0159\u00edzen\u00ed
+v3.devicesview.infobar.text2=Pro p\u0159evod k\u00f3du obsahu do za\u0159\u00edzen\u00ed, jednodu\u0161e p\u0159et\u00e1hn\u011bte obsah z Va\u0161\u00ed knihovny do za\u0159\u00edzen\u00ed na postrann\u00ed li\u0161t\u011b. Pro zobrazen\u00ed dokon\u010den\u00fdch p\u0159evod\u016f, klikn\u011bte na jednotliv\u00e1 za\u0159\u00edzen\u00ed napravo.
+iconBar.transcode=Za\u0159\u00edzen\u00ed
+iconBar.transcode.tooltip=Zp\u0159\u00edstupnit m\u00e9dia za\u0159\u00edzen\u00ed
+device.retry.copy=Zkusit Znovu Kop\u00edrovat
+devices.copy.fail=Nelze kop\u00edrovat na za\u0159\u00edzen\u00ed
+devices.on.demand=Na po\u017e\u00e1d\u00e1n\u00ed
+devices.ready=P\u0159ipraveno
+TableColumn.header.trancode_qpos=\u010c.
+TableColumn.header.trancode_qpos.info=Pozice ve Front\u011b P\u0159evodu K\u00f3du
+TableColumn.header.profile=Za\u0159\u00edzen\u00ed
+TableColumn.header.profile.info=Profil pou\u017eit\u00fd p\u0159i p\u0159evodu k\u00f3du
+TableColumn.header.copied=Kop\u00edrov\u00e1no
+TableColumn.header.device=Za\u0159\u00edzen\u00ed
+TableColumn.header.device.info=C\u00edlov\u00e9 Za\u0159\u00edzen\u00ed
+TableColumn.header.trancode_completion=Postup P\u0159evodu
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=Zobr
+v3.iconBar.view.big.tooltip=Zobrazit jako Jednoduch\u00fd Seznam
+# This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=azen\u00ed
+v3.iconBar.view.small.tooltip=Zobrazit jako Pokro\u010dil\u00fd Seznam
+general.dont.ask.again=U\u017e se znovu neptat
+v3.menu.device.exploreTranscodes=Zobrazit Soubory
+v3.menu.device.exploreTranscodes._windows=Zobrazit Soubory v Pr\u016fzkumn\u00edku
+v3.menu.device.exploreTranscodes._mac=Zobrazit Soubory ve Vyhled\u00e1va\u010di
+v3.menu.device.defaultprofile=V\u00fdchoz\u00ed Profil
+devices.button.installitunes=Nainstalovat integraci iTunes
+device.itunes.install=Pot\u0159ebujete nainstalovat iTunes
+device.itunes.start=Pot\u0159ebujete spustit iTunes nebo povolit automatick\u00e9 spu\u0161t\u011bn\u00ed
+device.itunes.install_problem=Zd\u00e1 se, \u017ee je probl\u00e9m s integrac\u00ed iTunes
+devices.downloading=Stahuji
+TableColumn.header.duration=Trv\u00e1n\u00ed
+TableColumn.header.resolution=Rozhodnut\u00ed
+devices.xcode.autoStart=Automaticky Spou\u0161t\u011bt Kdy Je Pot\u0159eba
+option.askeverytime=Zeptat Se Poka\u017ed\u00e9
+option.rememberthis=Zapamatovat si toto nastaven\u00ed
+devices.associate=Asociovat S
+devices.associate.already=U\u017e je asociov\u00e1no
+devices.always.cache=Uchov\u00e1vat nep\u0159eveden\u00e9 soubory ve vyrovn\u00e1vac\u00ed pam\u011bti
+devices.turnon.prepageload=K zapnut\u00ed t\u00e9to funkce je vy\u017eadov\u00e1na instalace extra sou\u010d\u00e1st\u00ed.
+devices.turnon.itunes=Zahrnout podporu iTunes (vy\u017eadov\u00e1no pro za\u0159\u00edzen\u00ed Apple)
+devices.turnon.qos=Sd\u00edlet anoymn\u00ed statistiky za\u0159\u00edzen\u00ed s Vuze
+devices.turnon.title=Zapnout Podporu Za\u0159\u00edzen\u00ed
+devices.choose.device.title=Vybrat za\u0159\u00edzen\u00ed pro p\u0159ehr\u00e1v\u00e1n\u00ed tohoto videa:
+devices.choose.profile.info.title=N\u00e1zev
+devices.choose.profile.info.text=Po Va\u0161em V\u00fdb\u011bru, Vuze zjist\u00ed, jestli form\u00e1t videa lze p\u0159ehr\u00e1t na Va\u0161em vybran\u00e9m za\u0159\u00edzen\u00ed, a vytvo\u0159\u00ed kopii kompatibiln\u00ed se za\u0159\u00edzen\u00edm, pokud je to nutn\u00e9.\n\nNaje\u010fte nad zvolen\u00e9 za\u0159\u00edzen\u00ed pro v\u00edce podrobnost\u00ed.
+devices.choose.profile.info.title.selected=%1 podrobnosti:
+devices.view.heading=P\u0159evod m\u00e9dia pro p\u0159ehr\u00e1v\u00e1n\u00ed na za\u0159\u00edzen\u00ed
+device.view.heading=M\u00e9dia pro %1
+devices.choose.device.info.title=Tip Za\u0159\u00edzen\u00ed
+devices.choose.device.info.text=P\u0159\u00ed\u0161t\u011b, jednodu\u0161e t\u00e1hnout a pou\u0161t\u011bt soubory do za\u0159\u00edzen\u00ed Va\u0161eho v\u00fdb\u011bru v postrann\u00ed li\u0161t\u011b.
+label.clickone=Kliknout na jeden
+Button.turnon=Zapnout
+ConfigView.label.dm.dblclick=Dvojit\u00e9 kliknut\u00ed v zobrazen\u00ed torrentu:
+ConfigView.option.dm.dblclick.play=P\u0159ehr\u00e1t Obsah
+ConfigView.option.dm.dblclick.details=Otev\u0159\u00edt Zobrazen\u00ed Podrobnost\u00ed Torrentu
+ConfigView.option.dm.dblclick.show=Zobrazit Soubor
+ConfigView.option.dm.dblclick.show._mac=Zobrazit Soubor(y) Ve Finderu
+ConfigView.option.dm.dblclick.show._windows=Zobrazit Soubor(y) V Pr\u016fzkumn\u00edku
+subscriptions.column.auto-download=Automaticky Stahovat
+xcode.deletedata.title=Smazat P\u0159eveden\u00fd Obsah
+xcode.deletedata.message=Jste si jisti, \u017ee chcete natrvalo smazat kopii '%1' p\u0159evedenou pro '%2'%3?
+xcode.deletedata.message.2=\n(kopie m\u016f\u017ee st\u00e1le existovat ve '%1')
+v3.deviceview.infobar.line1=T\u00e1hn\u011bte-a-pus\u0165te videa z Va\u0161\u00ed knihovny do za\u0159\u00edzen\u00ed Va\u0161eho v\u00fdb\u011bru.
+v3.deviceview.infobar.line2=P\u0159ehr\u00e1vat videa na v\u0161ech Va\u0161ich obrazovk\u00e1ch - iPad, iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=T\u00e1hn\u011bte-a-pus\u0165te videa z Va\u0161\u00ed knihovny do %1 ve Va\u0161i Postrann\u00ed Li\u0161t\u011b.
+v3.deviceview.infobar.line2.itunes=Videa se zobraz\u00ed ve Va\u0161em adres\u00e1\u0159i iTunes Filmy, kdy\u017e jsou p\u0159ipraveny ke spu\u0161t\u011bn\u00ed.
+v3.deviceview.infobar.line2.xbox=Streamujte videa t\u00edm, \u017ee p\u0159ejdete k Va\u0161emu Xbox 360 a vyberete M\u016fj Xbox -> Video Knihovna -> Vuze.
+v3.deviceview.infobar.line2.ps3=Streamovat videa tak, \u017ee p\u0159ejdete  k Va\u0161emu PS3 a vyberete Videa -> Vuze.
+devices.copy_url=Kop\u00edrovat URL Streamu do Schr\u00e1nky
+devices.converting=P\u0159ev\u00e1d\u00edm
+Button.reload=Znovu na\u010d\u00edst
+devices.auto.start=Automaticky spustit
+Subscription.menu.setcookies=Nastavit Cookies
+general.enter.cookies=Cookies P\u0159\u00edstupu
+device.config.xcode.workdir=V\u00fdchoz\u00ed pracovn\u00ed adres\u00e1\u0159 pro p\u0159eveden\u00e9 soubory
+MyTorrentsView.menu.clear_alloc_data=Vy\u010distit Stav P\u0159id\u011blov\u00e1n\u00ed
+DiskManager.error.nospace=Nedostatek m\u00edsta na disku
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - zkontrolujte {wiki.fat32}
+ConfigView.section.file.rename.incomplete=P\u0159idat p\u0159\u00edponu k nedokon\u010den\u00fdm soubor\u016fm
+subscriptions.config.auto=Automaticky stahovat
+subscriptions.config.autostartdls=Automaticky spou\u0161t\u011bt stahov\u00e1n\u00ed, kdy\u017e jsou p\u0159id\u00e1na (oproti p\u0159id\u00e1n\u00edm v zastaven\u00e9m stavu)
+subscriptions.config.autostart.min=Spou\u0161t\u011bt pouze kdy\u017e >= MB [0: neomezen\u011b]
+subscriptions.config.autostart.max=Spou\u0161t\u011bt pouze kdy\u017e <= MB [0: neomezen\u011b]
+dlg.corewait.title=Spou\u0161t\u00edm J\u00e1dro
+dlg.corewait.text=Moment Pros\u00edm...\n\nV\u00e1\u0161 po\u017eadavek bude zpracov\u00e1n a\u017e Vuze dokon\u010d\u00ed spu\u0161t\u011bn\u00ed
+library.core.wait=Po\u010dkejte Pros\u00edm...\nKlient Vuze je Spou\u0161t\u011bn
+ConfigView.label.StartUIBeforeCore=Spustit Rozhran\u00ed p\u0159ed inicializac\u00ed J\u00e1dra
+general.add.friends=P\u0159idat n\u011bjak\u00e9 p\u0159\u00e1tele!
+general.all.friends=V\u0161ichni P\u0159\u00e1tel\u00e9
+friend.mod.subs=Klikn\u011bte prav\u00fdm tla\u010d\u00edtkem k pozm\u011bn\u011bn\u00ed odb\u011br\u016f
+TableColumn.header.class=T\u0159\u00edda
+device.rss.group=M\u00edstn\u00ed RSS Kan\u00e1l
+devices.xcode.rsspub=Publikovat kan\u00e1l RSS
+device.rss.enable=Vytvo\u0159it kan\u00e1l RSS z p\u0159eveden\u00e9ho obsahu - to obsah zp\u0159\u00edstupn\u00ed \u010dte\u010dk\u00e1m kan\u00e1l\u016f RSS
+device.rss.port=Port RSS kan\u00e1lu
+device.rss.view=Klikn\u011bte pro zobrazen\u00ed kan\u00e1lu RSS
+device.rss.localonly=Omezit p\u0159\u00edstup na pouze tento po\u010d\u00edta\u010d
+devices.xcode.autoCopy=Automaticky Kop\u00edrovat do Adres\u00e1\u0159e
+devices.xcode.setcopyto=Nastavit Kop\u00edrovan\u00ed do Adres\u00e1\u0159e...
+devices.xcode.setcopyto.title=Zvolit um\u00edst\u011bn\u00ed kopie
+devices.copy.folder.auto=Automaticky kop\u00edrovat soubory do adres\u00e1\u0159e
+devices.copy.folder.dest=Kop\u00edrovat do adres\u00e1\u0159e
+TableColumn.menu.maxuploads=Po\u010det Max Odes\u00edl\u00e1n\u00ed
+devices.xcode.mancopy=Ru\u010dn\u011b Kop\u00edrovat Soubory
+devices.xcode.show.cat=Odd\u011blit Podle Kategorie
+ConfigView.label.alwaysShowLibraryHeader=V\u017edy zobrazit li\u0161tu hlavi\u010dky/filtru v {library.name}
+devices.cat.show=Zobrazit kategorie
+devices.tivo.machine=N\u00e1zev stroje TiVo
+devices.info.copypending=%1 Soubor(\u016f) \u010cekaj\u00ed Na Kop\u00edrov\u00e1n\u00ed
+device.error.xcodefail=P\u0159evod K\u00f3du Selhal
+device.error.copyfail=Jeden Nebo V\u00edce Soubor\u016f Nelze Kop\u00edrovat Do Adres\u00e1\u0159e
+device.error.copytonotset='Kop\u00edrovat do Adres\u00e1\u0159e' Nenastaveno
+device.error.copytomissing='Kop\u00edrovat do Adres\u00e1\u0159e' "%1" Nenalezeno
+device.error.copytonowrite='Kop\u00edrovat do Adres\u00e1\u0159e' "%1" Nen\u00ed zapisovateln\u00e9
+device.error.copyfail2=Jeden Nebo V\u00edce Soubor\u016f Nelze Kop\u00edrovat Do Za\u0159\u00edzen\u00ed
+v3.deviceview.infobar.line2.tivo=Streamujte videa t\u00edm, \u017ee p\u0159ejdete k Va\u0161emu TiVo a vyberte Vuze z Va\u0161eho Seznamu P\u0159ehr\u00e1v\u00e1n\u00ed.
+v3.deviceview.infobar.line2.psp=Videa budou zkop\u00edrov\u00e1na do Va\u0161eho PSP, a\u017e bude p\u0159ipojeno.
+devices.info.copypending2=%1 Soubor(\u016f) \u010cekaj\u00ed Na Kop\u00edrov\u00e1n\u00ed, P\u0159ipojte Va\u0161e Za\u0159\u00edzen\u00ed
+subscriptions.column.nb-subscribers=Odb\u011bratel\u00e9
+device.offlinedownloader.view.title=Offline Stahova\u010de
+device.od.enable=Povolit stahov\u00e1n\u00ed za\u0159\u00edzen\u00ed offline
+device.odauto.enable=Automaticky spravovat stahov\u00e1n\u00ed
+device.odpt.enable=Zahrnout soukrom\u00e9 torrenty
+devices.contextmenu.od=Stahov\u00e1n\u00ed Offline
+devices.contextmenu.od.auto=<Automatick\u00e9>
+devices.contextmenu.od.enable=Zapnout
+devices.contextmenu.od.enabled=Zapnuto
+devices.od.view.heading=Stahov\u00e1n\u00ed ur\u010den\u00e9 k offline sta\u017een\u00ed
+DevicesOD.column.od_completion=Pr\u016fb\u011bh P\u0159enosu
+devices.od.idle=ne\u010dinn\u00fd
+device.od.turnon.title=Zapnout podporu Offline Stahova\u010d\u016f
+device.is.disabled=Za\u0159\u00edzen\u00ed je zak\u00e1zan\u00e9
+device.configure=Nastavit...
+device.od.error.notfound=Za\u0159\u00edzen\u00ed se zd\u00e1 b\u00fdt offline
+device.od.error.opfailstatus=Za\u0159\u00edzen\u00ed selhalo zpracovat p\u0159\u00edkaz %1: stav %2
+device.od.error.opfailexcep=Za\u0159\u00edzen\u00ed selhalo zpracovat p\u0159\u00edkaz %1: v\u00fdjimka %2
+device.od.error.nospace=U\u017e nen\u00ed \u017e\u00e1dn\u00e9 m\u00edsto na za\u0159\u00edzen\u00ed nebo nen\u00ed p\u0159ipojen \u017e\u00e1dn\u00fd extern\u00ed disk
+device.od.space=Dostupn\u00e9 M\u00edsto
+ConfigView.section.style.forceSIValues=Donutit, aby hodnoty byly zobrazeny jako hodnoty IEC bez ohledu na zobrazenou jednotku pro \u00fa\u010dely d\u011bdictv\u00ed (nap\u0159. 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=Zobraz\u00ed statistiky stahov\u00e1n\u00ed p\u0159i najet\u00ed
+devices.activation=Aktivace Za\u0159\u00edzen\u00ed
+button.nothanks=Ne D\u011bkuji
+devices.od.turnon.text1=V\u0161imli jsme si, \u017ee jste p\u0159ipojeni k %1.
+devices.od.turnon.text2=Cht\u011bli byste, aby %1 pokra\u010doval ve stahov\u00e1n\u00ed Va\u0161ich soubor\u016f, kdy\u017e je po\u010d\u00edta\u010d offline?
+devices.od.turnon.text3=Pros\u00edm p\u0159ipojte Pevn\u00fd Disk do %1, k zapnut\u00ed t\u00e9to funkce.
+devices.od.turnon.learn=Dozv\u011bd\u011bt se v\u00edce >
+devices.od=offline stahova\u010d
+webui.pairingenable=Povolit sp\u00e1rov\u00e1n\u00ed pro tento z\u00e1suvn\u00fd modul (mo\u017enosti zkou\u0161ky budou povoleny, jakmile sou\u010dasn\u00e9 podrobnosti sp\u00e1rov\u00e1n\u00ed jsou \u00fasp\u011b\u0161n\u011b publikov\u00e1ny)
+webui.group.access=Kontrola P\u0159\u00edstupu
+ConfigView.section.Pairing=Sp\u00e1rov\u00e1n\u00ed
+pairing.accesscode=P\u0159\u00edstupov\u00fd k\u00f3d
+pairing.ac.getnew=P\u0159id\u011blit nov\u00fd p\u0159\u00edstupov\u00fd k\u00f3d
+pairing.ac.getnew.create=Vytvo\u0159it
+pairing.ipv4=Ve\u0159ejn\u00e1 adresa IPv4
+pairing.ipv6=Ve\u0159ejn\u00e1 adresa IPv6
+pairing.local.ipv4=M\u00edstn\u00ed adresa IPv4
+pairing.local.ipv6=M\u00edstn\u00ed adresa IPv6
+pairing.host=Adresa hostitele (jm\u00e9no DNS)
+pairing.group.explicit=Jednozna\u010dn\u00e9 Atributy
+pairing.explicit.enable=Povolit
+pairing.explicit.info=V\u011bt\u0161inou jednozna\u010dn\u00e9 atributy IP nepot\u0159ebuj\u00ed b\u00fdt zad\u00e1v\u00e1ny, proto\u017ee jsou automaticky odvozeny.\nAtribut 'host' m\u016f\u017ee b\u00fdt pou\u017eito, nap\u0159\u00edklad, pokud m\u00e1te \u00fa\u010det DynDNS a vhodn\u00fd software klienta, aby Va\u0161e dynamick\u00e1 IP byla spr\u00e1vn\u011b registrov\u00e1na
+pairing.op.fail=Operace Sp\u00e1rov\u00e1n\u00ed Selhala
+pairing.alloc.fail=Nelze p\u0159id\u011blit nov\u00fd p\u0159\u00edstupov\u00fd k\u00f3d\n%1
+pairing.enable=Povolit sp\u00e1rov\u00e1n\u00ed Vuze a vzd\u00e1len\u00e9 aplikace/rozhran\u00ed
+pairing.status.info=Stav
+pairing.status.registered=Aktualizace \u00fasp\u011b\u0161n\u00e1 (%1)
+pairing.status.pending=Aktualizace bude provedena %1
+pairing.status.initialising=Spou\u0161t\u00edm
+pairing.status.disabled=Vypnuto
+pairing.view.registered=Klikn\u011bte pro zobrazen\u00ed podrobnost\u00ed sou\u010dasn\u00e9 registrace
+webui.pairing.info.n=Sp\u00e1rov\u00e1n\u00ed je zak\u00e1z\u00e1no, pod\u00edvejte se na volby P\u0159ipojen\u00ed->Sp\u00e1rov\u00e1n\u00ed pro informace o t\u00e9to funkci
+webui.pairing.info.y=Sp\u00e1rov\u00e1n\u00ed je povoleno, pod\u00edvejte se na volby P\u0159ipojen\u00ed->Sp\u00e1rov\u00e1n\u00ed pro v\u00edce podrobnost\u00ed.
+webui.enable=Povolit
+ConfigView.section.rss=M\u00edstn\u00ed RSS atd.
+subscriptions.rss.enable=Vytvo\u0159it kan\u00e1ly RSS z odb\u011br\u016f
+device.tivo.enable=Zapnout podporu TiVo
+Button.removeAll=Odstranit V\u0161e
+label.rename=P\u0159ejmenovat %1
+pairing.server.warning.title=Zpr\u00e1va Sp\u00e1rovac\u00edho Serveru
+wizard.webseedseditor.edit.title=Editor HTTP Zdroj\u016f
+wizard.webseedseditor.edit.newseed=Nov\u00fd Zdroj
+MyTorrentsView.menu.editWebSeeds=Upravit HTTP Zdroje
+ClientStats.title.full=Statistiky Klienta
+ClientStats.column.count=Po\u010det
+Scrape.status.cached=Scrape ve vyrovn\u00e1vac\u00ed pam\u011bti
+network.ipv6.enable.support=Zapnout podporu IPv6 (Ve Windows je vy\u017eadov\u00e1na Java7)
+ConfigView.section.plugins.magnetplugin=Obslu\u017en\u00e1 Rutina Magnet URI
+MagnetPlugin.use.lookup.service=Pou\u017eit druhotnou slu\u017ebu vyhled\u00e1v\u00e1n\u00ed Vuze, pokud vyhled\u00e1v\u00e1n\u00ed magnet p\u0159es DHT sel\u017ee
+MagnetPlugin.report.secondarylookup=Zkou\u0161\u00edm druhotnou slu\u017ebu vyhled\u00e1v\u00e1n\u00ed
+MagnetPlugin.report.secondarylookup.ok=Druhotn\u00e9 vyhled\u00e1v\u00e1n\u00ed bylo \u00fasp\u011b\u0161n\u00e9
+MagnetPlugin.report.secondarylookup.fail=Druhotn\u00e9 vyhled\u00e1v\u00e1n\u00ed selhalo: \u017e\u00e1dn\u00e9 zdroje nebyly nalezeny
+TrackerView.title.short=Zdroje
+TrackerView.title.full=Zdroje
+Trackers.column.type=Typ
+Trackers.column.name=Podrobnosti
+Trackers.column.status=Stav
+Trackers.column.seeds=Distributo\u0159i
+Trackers.column.seeds.info=Distributo\u0159i v po\u010dtu \u00fa\u010dastn\u00edk\u016f
+Trackers.column.leechers=Stahuj\u00edc\u00ed
+Trackers.column.leechers.info=Stahuj\u00edc\u00ed v po\u010dtu \u00fa\u010dastn\u00edk\u016f
+Trackers.column.peers=Klienti
+Trackers.column.peers.info=Klienti vr\u00e1cen\u00ed trackerem
+Trackers.column.interval.info=Interval mezi dotazy v sek: interval (min interval)
+Trackers.column.updatein=Dal\u0161\u00ed
+Trackers.column.updatein.info=\u010cas do dal\u0161\u00ed aktualizace
+tps.status.available=Dostupn\u00e9
+tps.status.unavailable=Nedostupn\u00e9
+tps.lan.details=%1 m\u00edstn\u00edch klient\u016f objeveno
+tps.pex.details=P\u0159ipojeno k %1 klient\u016fm (nevy\u0159\u00edzeno: pex=%2, ostatn\u00ed=%3)
+tps.tracker.cache=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 klient\u016f
+tps.tracker.cache1=Vyrovn\u00e1vac\u00ed pam\u011b\u0165 klient\u016f: pou\u017eito=%1
+dht.status.disabled=Zak\u00e1z\u00e1no, distribuovan\u00e1 datab\u00e1ze nen\u00ed dostupn\u00e1
+tps.type.incoming=P\u0159\u00edchoz\u00ed
+tps.incoming.details=Nyn\u00ed: TCP=%1, UDP=%2; Celkov\u011b v\u016fbec=%3
+tps.type.plugin=Z\u00e1suvn\u00fd modul
+ConfigView.label.autoadjust=Automaticky upravovat tyto nastaven\u00ed na z\u00e1klad\u011b rychlosti p\u0159ipojen\u00ed
+ConfigView.label.start=Spu\u0161t\u011bn\u00ed
+ConfigView.label.stop=Ukon\u010den\u00ed
+ConfigView.label.start.onlogin=Spustit Vuze p\u0159i p\u0159ihl\u00e1\u0161en\u00ed
+ConfigView.label.stop.seedcomp=Kdy\u017e je distribuce dokon\u010dena
+ConfigView.label.stop.downcomp=Kdy\u017e je stahov\u00e1n\u00ed dokon\u010deno
+ConfigView.label.stop.Nothing=Ned\u011blat Nic
+ConfigView.label.stop.QuitVuze=Ukon\u010dit Vuze
+ConfigView.label.stop.Sleep=Uv\u00e9st Po\u010d\u00edta\u010d Do Re\u017eimu Sp\u00e1nku
+ConfigView.label.stop.Hibernate=Uv\u00e9st Po\u010d\u00edta\u010d Do Hibernace
+ConfigView.label.stop.Shutdown=Vypnout Po\u010d\u00edta\u010d
+core.shutdown.alert=\u010cinnost '%1' spu\u0161t\u011bn\u00e1 jako %2
+core.shutdown.dl=stahov\u00e1n\u00ed dokon\u010deno
+core.shutdown.se=distribuce dokon\u010dena
+pairing.last.error=Posledn\u00ed chyba
+MainWindow.menu.pairing=Vzd\u00e1len\u00e9 Sp\u00e1rov\u00e1n\u00ed
+ConfigView.section.startstop={ConfigView.label.start} a {ConfigView.label.stop}
+ConfigView.label.pauseresume=Automaticky pozastavit/pokra\u010dovat
+update.now.title=Aktualizace Vy\u017eadov\u00e1na
+update.now.desc=Vuze pot\u0159ebuje pou\u017e\u00edt aktualizace pro dokon\u010den\u00ed p\u0159esunu.\n\nPo uzav\u0159en\u00ed tohoto dialogov\u00e9ho okna m\u016f\u017eete b\u00fdt po\u017e\u00e1d\u00e1ni Windows, pro dokon\u010den\u00ed procesu aktualizace.\n\nRestart Vuze NEBUDE vy\u017eadov\u00e1n.
+ConfigView.label.jvm=Mo\u017enosti Java
+platform.jvmopt.sunonly=Pouze JVM od Sun jsou podporov\u00e1ny (sou\u010dasn\u00fd v\u00fdrobce=%1)
+platform.jvmopt.configerror=Nelze spravovat volby JVM kv\u016fli chyb\u011b v nastaven\u00ed
+platform.jvmopt.nolinkfile=Nelze spravovat volby JVM proto\u017ee migrace nen\u00ed dokon\u010den\u00e1
+platform.jvmopt.nolink=Nelze spravovat volby JVM proto\u017ee je to zak\u00e1z\u00e1no existuj\u00edc\u00edm nastaven\u00edm
+platform.jvmopt.accesserror=P\u0159\u00edstup k souboru voleb JVm selhal: %1
+pairing.status.noservices=\u017d\u00e1dn\u00e9 vzd\u00e1len\u00e9 slu\u017eby povoleny
+webui.pairingtest=\tKlikn\u011bte pro zkou\u0161ku sp\u00e1rov\u00e1n\u00ed
+webui.connectiontest=\tklikn\u011bte pro zkou\u0161ku spojen\u00ed
+jvm.info=Pokud tyto mo\u017enosti zm\u011bn\u00edte, bude vy\u017eadov\u00e1n restart Vuze. ***Varov\u00e1n\u00ed - nespr\u00e1vnou zm\u011bnou mo\u017enost\u00ed JVM m\u016f\u017eete zp\u016fsobit, \u017ee Vuze sel\u017ee p\u0159i startu, nebo bude \u0161patn\u011b pracovat ***\n
+jvm.show.file=M\u00edstn\u00ed soubor mo\u017enost\u00ed JVM je '%1'  - Upravujte pouze pro \u00fa\u010dely obnoven\u00ed
+jvm.reset=Resetovat mo\u017enosti JVM na v\u00fdchoz\u00ed z instalace
+jvm.error=Vyskytla se chyb p\u0159i p\u0159\u00edstupu k volb\u00e1m JVM: %1
+jvm.max.mem=Max velikost Hromadn\u00e9 pam\u011bti [pr\u00e1zdn\u00e9=v\u00fdchoz\u00ed,min=%1]
+jvm.min.mem=Min velikost Hromadn\u00e9 pam\u011bti [pr\u00e1zdn\u00e9=v\u00fdchoz\u00ed,min=%1]
+ConfigView.section.invalid.value.title=Neplatn\u00e1 Hodnota
+ConfigView.section.invalid.value=Zad\u00e1na neplatn\u00e1 hodnota '%1' pro '%2': %3
+Button.dismiss=Pominout
+webui.pairing.autoauth=Zapnout v\u00fdchoz\u00ed ochranu heslem: u\u017eivatelsk\u00e9 jm\u00e9no=vuze, heslo=<p\u0159\u00edstupov\u00fd k\u00f3d sp\u00e1rov\u00e1n\u00ed>
+ConfigView.label.stop.autoreset=Jakmile spu\u0161t\u011bno, automaticky resetovat \u010dinnosti na '%1'
+remote.pairing.title=Vzd\u00e1len\u00e9 Sp\u00e1rov\u00e1n\u00ed
+remote.pairing.subtitle=Ovlada\u010d Vuze V\u00e1m d\u00e1v\u00e1 mo\u017enost ovl\u00e1dat Vuze z jak\u00e9hokoli po\u010d\u00edta\u010de nebo mobiln\u00e1\u00edho prohl\u00ed\u017ee\u010de - kdykoliv, kdekoliv.
+remote.pairing.instruction=Jednodu\u0161e zadejte k\u00f3d do n\u00ed\u017ee poskytnut\u00fdch m\u00edst v jak\u00e9koli vzd\u00e1len\u00e9 aplikaci.
+remote.pairing.functions=<A HREF="clip">kop\u00edrovat k\u00f3d do schr\u00e1nky</A>   |   <A HREF="new">Z\u00edskat nov\u00fd k\u00f3d</A>
+remote.pairing.tip.title=N\u00e1pov\u011bda: Dva snadn\u00e9 zp\u016fsoby, jak pou\u017e\u00edt Ovlada\u010d Vuze:
+remote.pairing.tip.text=Panel N\u00e1stroj\u016f Ovlada\u010de Vuze: Jd\u011bte na <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nVuze Mobiln\u00ed Ovlada\u010d: Jd\u011bte na <A HREF="http://remote.vuze.com/">remote.vuze.com</A> ve Va\u0161em mobiln\u00edm prohl\u00ed\u017ee\u010di.
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">\u010cast\u00e9 Ot\u00e1zky Sp\u00e1rov\u00e1n\u00ed</A>
+remote.pairing.accesscode=P\u0159\u00edstupov\u00fd K\u00f3d:
+remote.pairing.test.running=Zkou\u0161\u00edm vzd\u00e1len\u00e9 p\u0159ipojen\u00ed...
+remote.pairing.test.success=Vuze je dostupn\u00fd p\u0159es ovlada\u010d
+remote.pairing.test.unavailable=Jejda, nelze zjistit Va\u0161i vzd\u00e1lenou propojitelnost. <A HREF="retry">Zkuste to znovu</A>
+remote.pairing.test.fail=Vuze nen\u00ed dostupn\u00fd mimo Va\u0161i m\u00edstn\u00ed s\u00ed\u0165. <A HREF="/pairing_error_faq.start">Dov\u011bzte se v\u00edce</A>
+update.fail.app.changed.title=Aktualizace Selhala
+update.fail.app.changed=Vuze mus\u00ed b\u00fdt aktualizov\u00e1n, ale proces nem\u016f\u017ee b\u00fdt vykon\u00e1n automaticky, proto\u017ee jm\u00e9no aplikace se zm\u011bnilo na '%1'.\n\nPros\u00edm jd\u011bte na http://www.vuze.com/ a st\u00e1hn\u011bte si nejnov\u011bj\u0161\u00ed instal\u00e1tor.
+webui.port.override=Potla\u010den\u00ed portu: vy\u017eadov\u00e1no pouze kdy\u017e se ve\u0159ejn\u00fd port li\u0161\u00ed od vnit\u0159n\u00edho kv\u016fli nastaven\u00ed NAT
+MainWindow.status.warning.tooltip=Klikn\u011bte zde pro podrobnosti
+search.dialog.text=Zadejte text pro hled\u00e1n\u00ed nov\u00fdch torrent\u016f:
+core.not.available=Vuze se st\u00e1le spou\u0161t\u00ed, zkuste to znovu, pros\u00edm, a\u017e bude spu\u0161t\u011bn\u00ed dokon\u010deno
+dlg.auth.title=Aktivace
+dlg.auth.enter.subtitle.try.1=U\u017e jsme skoro tam.
+dlg.auth.enter.line.try.1=Zadejte n\u00ed\u017ee V\u00e1\u0161 aktiva\u010dn\u00ed k\u00f3d pro dokon\u010den\u00ed Va\u0161eho vylep\u0161en\u00ed na Vuze Plus.
+dlg.auth.enter.line.try.2=Je n\u00e1m l\u00edto, nemohli jsme ov\u011b\u0159it V\u00e1\u0161 aktiva\u010dn\u00ed k\u00f3d. Pros\u00edm zkontrolujte \u010d\u00edslo a zkuste ho znovu zadat.
+dlg.auth.enter.prompt=Aktiva\u010dn\u00ed K\u00f3d Vuze Plus:
+Button.validate=Ov\u011b\u0159it
+Button.getstarted=Za\u010d\u00edt
+Button.goLibrary=J\u00edt do {library.name}
+dlg.auth.success.subtitle=Blahop\u0159ejeme!
+dlg.auth.success.line1=D\u011bkujeme V\u00e1m za Va\u0161e vylep\u0161en\u00ed na Vuze Plus
+dlg.auth.success.line2=Nyn\u00ed m\u00e1te mo\u017enost vypalovat neomezen\u00e9 p\u0159ehrateln\u00e9 DVD, skenovat Va\u0161e soubory pro viry, a streamovat videa, kter\u00e1 si stahujete - to v\u0161e bez reklam!
+dlg.auth.trial.success.line1=Vuze je p\u0159ipraven vytv\u00e1\u0159et DVD.
+dlg.auth.trial.success.subtitle=Vypalovan\u00ed DVD je P\u0159ipraveno
+dlg.auth.trial.success.info=T\u00e1hn\u011bte video soubory z Va\u0161\u00ed knihovny do "Vytvo\u0159it Nov\u00e9 DVD." Pokud jste ji\u017e video p\u0159idali p\u0159ed nainstalov\u00e1n\u00edm sou\u010d\u00e1st\u00ed, p\u0159idejte je znovu, pros\u00edm.
+dlg.auth.revoked=Aktiva\u010dn\u00ed K\u00f3d Odvol\u00e1n
+dlg.auth.revoked.line1=V\u00e1\u0161 Aktiva\u010dn\u00ed K\u00f3d Vuze Plus byl odvol\u00e1n. Pros\u00edm klikn\u011bte n\u00ed\u017ee pro v\u00edce informac\u00ed.
+dlg.auth.revoked.link=<A HREF="info">Informace o Odvolan\u00fdch Aktiva\u010dn\u00edch k\u00f3dech</A>
+dlg.auth.denied=Aktiva\u010dn\u00ed K\u00f3d Zam\u00edtnut
+dlg.auth.denied.line1=V\u00e1\u0161 Aktiva\u010dn\u00ed K\u00f3d Vuze Plus byl zam\u00edtnut. Pros\u00edm klikn\u011bte n\u00ed\u017ee pro v\u00edce informac\u00ed.
+dlg.auth.denied.link=<A HREF="info">Informace o zam\u00edtnut\u00fdch aktiva\u010dn\u00edch k\u00f3dech</A>
+dlg.auth.cancelled=Aktiva\u010dn\u00ed K\u00f3d Zru\u0161en
+dlg.auth.cancelled.line1=Va\u0161e Aktivace Vuze Plus byla zru\u0161ena.
+dlg.auth.cancelled.line2=Pokud si mysl\u00edte, \u017ee je toto chyba, pros\u00edm kontaktute podporu pomoc\u00ed instrukc\u00ed ve Va\u0161em e-mailu s \u00fa\u010dtenkou
+dlg.auth.enter.subtitle.try.2=Ov\u011b\u0159en\u00ed selhalo
+dlg.auth.enter.link.try.2=<A HREF="link">Klikn\u011bte zde</A>, pokud jste si je\u0161t\u011b nezakoupili Va\u0161i kopii Vuze Plus.
+dlg.auth.enter.link.try.1=Nem\u00e1te aktiva\u010dn\u00ed k\u00f3d? <A HREF="upgrade">Vylep\u0161ete Vuze te\u010f</A>.
+dlg.auth.enter.expiry=Sou\u010dasn\u00fd aktiva\u010dn\u00ed k\u00f3d vypr\u0161\u00ed %1
+dlg.auth.enter.revoked=Sou\u010dasn\u00fd aktiva\u010dn\u00ed k\u00f3d byl odvol\u00e1n.
+dlg.auth.enter.cancelled=Sou\u010dasn\u00fd aktiva\u010dn\u00ed k\u00f3d byl zru\u0161en.
+dlg.auth.enter.denied=Sou\u010dasn\u00fd aktiva\u010dn\u00ed k\u00f3d byl zam\u00edtnut.
+dlg.auth.validating.subtitle=Ov\u011b\u0159uji...
+dlg.try.trial.title=Vyzkou\u0161et si Vypalov\u00e1n\u00ed DVD
+dlg.try.trial.text=Vuze pot\u0159ebuje nainstalovat z\u00e1suvn\u00fd modul pot\u0159ebn\u00fd k vyp\u00e1len\u00ed p\u0159ehrateln\u00fdch DVD z Va\u0161ich vide\u00ed. Klikn\u011bte na zapnout pro pokra\u010dov\u00e1n\u00ed.
+dlg.auth.tos=P\u0159e\u010detl(a) jsem a souhlas\u00edm s <A HREF="tos">Podm\u00ednkami Slu\u017eby.</A>
+dlg.auth.install.subtitle.plus=Instaluji Vuze Plus...
+dlg.auth.install.subtitle.trial=Instaluji Vypalov\u00e1n\u00ed DVD
+dlg.auth.install.progress=Instaluji sou\u010d\u00e1sti %1...
+dlg.auth.install.pct=%1% dokon\u010deno
+mdi.entry.dvdburn=Vypalov\u00e1n\u00ed DVD
+mdi.entry.dvdburn.new=Vytvo\u0159it Nov\u00e9 DVD
+menu.register=Aktivace Vuze Plus
+dlg.auth.trial.title=Vyzkou\u0161en\u00ed Vypalov\u00e1n\u00ed DVD
+dlg.player.install.subtitle=Instalace
+dlg.player.install.description=Instlauji dodate\u010dn\u00e9 sou\u010d\u00e1sti p\u0159ehr\u00e1v\u00e1n\u00ed...
+devices.xcode.remove.vetoed=Prob\u00edh\u00e1 p\u0159evod k\u00f3du '%1', stahov\u00e1n\u00ed nem\u016f\u017ee b\u00fdt odstran\u011bno, dokud nen\u00ed toto dokon\u010deno nebo je p\u0159evod zru\u0161en ze str\u00e1nky 'Za\u0159\u00edzen\u00ed'.
+Button.agree=Souhlas\u00edm
+dlg.auth.install.failed.title=Aktivace Selhala
+dlg.auth.install.failed.text=Aktivace k\u00f3du '%1' selhala kv\u016fli chyb\u011b serveru.\n\nPros\u00edm zkuste aktivaci znovu pozd\u011bji (nahl\u00e1\u0161en\u00e1 chyba byla '%2')
+device.status.online=Za\u0159\u00edzen\u00ed je online
+device.itunes.status.running=iTunes b\u011b\u017e\u00ed
+device.itunes.status.notrunning=iTunes neb\u011b\u017e\u00ed
+device.itunes.status.notinstalled=iTunes nen\u00ed nainstalov\u00e1no
+OpenTorrentWindow.mb.notTorrent.retry=Hled\u00e1n\u00ed Magnet
+ConfigView.section.ipfilter.clear.on.reload=Vy\u010distit filtry p\u0159i znovuna\u010dten\u00ed. B\u011bhem procesu znovuna\u010dten\u00ed IP nebudou blokov\u00e1ny. Pokud nen\u00ed za\u0161krtnuto, ned\u00e1vn\u00e9 odblokov\u00e1n\u00ed nebude \u00fa\u010dinn\u00e9 dokud neprovedete restart.
+view.waiting.core=Zobrazen\u00ed bude dostupn\u00e9, a\u017e J\u00e1dro Vuze dokon\u010d\u00ed nahr\u00e1v\u00e1n\u00ed...
+devices.profile.direct=P\u0159\u00edmo
+cat.autoxcode=Auto-Za\u0159\u00edzen\u00ed
+ConfigView.section.tables=Tabulky
+ConfigView.section.style.useTree=Zobrazit Soubory v zobrazen\u00ed {library.name} (Vy\u017eaduje Restart)
+ConfigView.section.mode.resetdefaults=Resetovat nastaven\u00ed na v\u00fdchoz\u00ed hodnoty (restart je doporu\u010den)
+resetconfig.warn.title=Potvrdit \u010cinnost
+resetconfig.warn=Toto bude m\u00edt za n\u00e1sledek, \u017ee v\u0161echny zm\u011bny, kter\u00e9 jste provedli ve Va\u0161em nastaven\u00ed Vuze, budou ztraceny.\nPokra\u010dovat s resetov\u00e1n\u00edm nastaven\u00ed?
+ConfigView.label.xfer.bias_up=Zv\u00fd\u0161it rychlosti stahov\u00e1n\u00ed ovlivn\u011bn\u00edm kapacity odesl\u00e1n\u00ed pro nedokon\u010den\u00e1 stahov\u00e1n\u00ed
+ConfigView.label.xfer.bias_slack=minium KB/S rezervovan\u00fdch pro dokon\u010den\u00e1 stahov\u00e1n\u00ed
+ConfigView.label.xfer.bias_no_limit=Pokusit se ovlivnit, kdy\u017e neexistuje \u00fa\u010dinn\u00fd glob\u00e1ln\u00ed limit odes\u00edl\u00e1n\u00ed
+SpeedView.stats.upload=Data k odes\u00edl\u00e1n\u00ed ve front\u011b:
+SpeedView.stats.con=Podrobnosti p\u0159ipojen\u00ed:
+SpeedView.stats.con_details=celkem=%1, nep\u0159i\u0161krceno=%2, ve front\u011b=%3, blokov\u00e1no=%4
+SpeedView.stats.upbias=Odchylka odes\u00edl\u00e1n\u00ed:
+dlg.install.mlab.subtitle=Instaluji
+dlg.install.mlab.description=Po\u010dkejte pros\u00edm, a\u017e bude sou\u010d\u00e1st zkou\u0161ky rychlosti nainstalov\u00e1na
+dial.up=Vybudovat Spojen\u00ed
+auto.mode=Auto (doporu\u010den\u00e9)
+manual.mode=Ru\u010dn\u00ed
+configureWizard.transfer2.hint=Nastaven\u00edm Va\u0161eho limitu odes\u00edl\u00e1n\u00ed p\u0159\u00edli\u0161 vysoko nebo p\u0159\u00edli\u0161 n\u00edzko ovlivn\u00ed v\u00fdkon stahov\u00e1n\u00ed!
+configureWizard.transfer2.message=Bittorrent je zalo\u017een na protokolu n\u011bco za n\u011bco - obvykle \u010d\u00edm rychleji odes\u00edl\u00e1te, t\u00edm rychleji stahujete - tak\u017ee abyste rychle stahovali, a rychle dostali dobr\u00fd pom\u011br sd\u00edlen\u00ed, pot\u0159ebujete dobrou rychlost odes\u00edl\u00e1n\u00ed.\n\nNicm\u00e9n\u011b, pokud odes\u00edl\u00e1te p\u0159\u00edli\u0161 rychle na Va\u0161e p\u0159ipojen\u00ed, m\u016f\u017eete ho p\u0159et\u00ed\u017eit, co [...]
+configureWizard.transfer2.group=Re\u017eim
+configureWizard.transfer2.test.info=Vyberte pro spu\u0161t\u011bn\u00ed obs\u00e1hl\u00e9 zkou\u0161ky rychlosti
+configureWizard.transfer2.test=Spustit Zkou\u0161ku
+configureWizard.transfer2.mselect=Vyberte limit rychlosti ODES\u00cdL\u00c1N\u00cd Va\u0161eho p\u0159ipojen\u00ed
+configureWizard.transfer2.mselect.info=Z\u00e1znamy xxx/<hodnota> ozna\u010duj\u00ed rychlost odes\u00edl\u00e1n\u00ed p\u0159ipojen\u00ed v <hodnota> bit\u016f za sekundu.\nNap\u0159\u00edklad, pokud m\u00e1te p\u0159ipojen\u00ed ADSL s rychlost\u00ed 768 Kbps stahov\u00e1n\u00ed a 384 Kbps odes\u00edl\u00e1n\u00ed, vyberte 'xxx/384 kbit/sek'.\nZaokrouhlete dol\u016f na nejbli\u017e\u0161\u00ed hodnotu, pokud nen\u00ed Va\u0161e p\u0159esn\u00e1 rychlost zobrazena.
+configureWizard.transfer2.rate.unchanged=Bude pou\u017eito sou\u010dasn\u00e9 nastaven\u00ed
+configureWizard.transfer2.rate.changed=Limit p\u0159ipojen\u00ed=%1\nPou\u017eit\u00fd limit bude %2 (max aktivn\u00edch torrent\u016f=%3, max stahovan\u00fdch=%4)
+speedtest.wizard.select.title=Vyberte typ testu ke spu\u0161t\u011bn\u00ed
+speedtest.wizard.select.group=Typ Testu
+speedtest.wizard.select.general=Obecn\u00e1 zkou\u0161ka rychlosti (doporu\u010deno)
+speedtest.wizard.select.bt=Specifick\u00e1 zkou\u0161ka rychlosti bittorrent
+FileItem.storage.reorder=Znovu se\u0159adit
+ConfigView.label.piecereorder=P\u0159ipojit data k soubor\u016fm jak jsou stahov\u00e1na a p\u0159eskupit d\u00edly jak stahov\u00e1n\u00ed pokra\u010duje.
+ConfigView.label.piecereorderminmb=P\u0159eskupit pouze soubory v\u011bt\u0161\u00ed ne\u017e (v MB)
+configureWizard.transfer2.current=<Sou\u010dasn\u00e9 Nastaven\u00ed>
+ConfigView.section.style.extendedErase=Vykreslit rastrov\u00e9 \u010d\u00e1ry a vyplnit pr\u00e1zdn\u00e1 m\u00edsta
+iconBar.stream=P\u0159ehr\u00e1t Te\u010f
+FilesView.menu.setpriority.numeric=\u010c\u00edseln\u00e1...
+FilesView.dialog.priority.title=Zadejte \u010c\u00edselnou Prioritu
+FilesView.dialog.priority.text=0=Norm\u00e1ln\u00ed, 1=Vysok\u00e1, 2=Vy\u0161\u0161\u00ed...
+beta.wizard.title=Nastaven\u00ed Beta Verze
+beta.wizard.intro.title=V\u00fdb\u011br z\u00e1pisu
+beta.wizard.info=Z\u00e1pisem do beta programu Vuze z\u00edsk\u00e1te v\u010dasn\u00fd p\u0159\u00edstup k chystan\u00fdm funkc\u00edm klienta.\n\nTo V\u00e1m d\u00e1v\u00e1 \u0161anci si tyto funkce vyzkou\u0161et a pomoci tvo\u0159it zp\u016fsob, jak jsou zav\u00e1d\u011bny - Va\u0161e zp\u011btn\u00e1 vazba je pro n\u00e1s velmi d\u016fle\u017eit\u00e1!\n\nP\u0159irozen\u011b beta verze m\u016f\u017eou b\u00fdt nestabiln\u00ed, nicm\u00e9n\u011b v\u00fdb\u011br t\u00e9to volby V\u00e1 [...]
+beta.wizard.link=Klikn\u011bte zde pro vstup na str\u00e1nku s beta verzemi
+beta.wizard.off=Jsem spokojen\u00fd s vyd\u00e1van\u00fdmi verzemi, d\u011bkuji nechci!
+beta.wizard.on=Aktualizovat na nejnov\u011bj\u0161\u00ed stabiln\u00ed beta verzi, pros\u00edm.
+beta.wizard.version=Pr\u00e1v\u011b pou\u017e\u00edv\u00e1te verzi %1
+beta.wizard.disable.title=Vy\u017eadov\u00e1na Reinstalace
+beta.wizard.disable.text=D\u011bkujeme V\u00e1m za vyzkou\u0161en\u00ed beta berzi!\n\nSt\u00e1hn\u011bte si a instalujte, pros\u00edm, posledn\u00ed vydanou verzi k opu\u0161t\u011bn\u00ed beta programu
+beta.wizard.forum=Pou\u017eijte f\u00f3ra Vuze pro p\u0159ed\u00e1n\u00ed zp\u011btn\u00e9 vazby a ohl\u00e1\u0161en\u00ed chyb
+dlg.install.vuzexcode.subtitle=Instaluji sou\u010d\u00e1st Analyz\u00e1tor M\u00e9di\u00ed
+dlg.install.vuzexcode.description=Po\u010dkejte pros\u00edm, a\u017e bude sou\u010d\u00e1st Analyz\u00e1tor M\u00e9di\u00ed nainstalov\u00e1n
+TableColumn.header.filecount=Soubory
+TableColumn.header.torrentspeed=Rychlost
+FileProgress.deleted=Smaz\u00e1no
+priority.high=Vysok\u00e1 Priorita
+priority.normal=Norm\u00e1ln\u00ed Priorita
+label.wrap.text=Zalamovat Text
+ScrapeInfoView.title=Hlavn\u00ed Tracker
+Column.seedspeers.started=%1 z %2
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 polo\u017eek: %2 aktivn\u00edch
+library.incomplete.header.p=%1 polo\u017eek stahov\u00e1no, %2 \u010dekaj\u00ed na stahov\u00e1n\u00ed
+library.unopened.header.p=%1 polo\u017eek
+library.all.header=%1 polo\u017eka: %2 aktivn\u00ed
+library.incomplete.header=%1 polo\u017eka stahov\u00e1na, %2 \u010dekaj\u00ed na stahov\u00e1n\u00ed
+library.unopened.header=%1 polo\u017eka
+ConfigView.section.style.status.show_rategraphs=Zobrazit grafy historie hodnocen\u00ed pod textem stahov\u00e1n\u00ed/odes\u00edl\u00e1n\u00ed
+device.error.mountrequired="%1" Pot\u0159ebuje P\u0159ipojit do Va\u0161eho Za\u0159\u00edzen\u00ed
+v3.deviceview.infobar.line2.android=Povolte p\u0159ipojen\u00ed USB na Va\u0161em telefonu ke spr\u00e1vn\u00e9mu p\u0159enosu vide\u00ed
+MyTorrents.column.ColumnProgressETA.compon=Dokon\u010deno %1
+MainWindow.menu.beta.on=P\u0159ipojit se k Beta Programu...
+MainWindow.menu.beta.off=Odej\u00edt z Beta Programu...
+Button.sendNow=Poslat Te\u010f
+Button.sendManual=Ru\u010dn\u00ed Odesl\u00e1n\u00ed (vytvo\u0159it .zip)
+deletecontent.also.deletetorrent=Smazat tak\u00e9 .torrent soubor
+ConfigView.section.file.deletion.section=Smaz\u00e1n\u00ed Souboru
+ConfigView.section.file.delete.torrent=Standardn\u011b, smazat soubor .torrent, p\u0159i maz\u00e1n\u00ed obsahu
+ConfigView.section.file.delete.confirm=Potvrdit smaz\u00e1n\u00ed obsahu p\u0159es Panel n\u00e1stroj\u016f a Kl\u00ed\u010d maz\u00e1n\u00ed
+ConfigView.section.server.enableudpprobe=Povolit zji\u0161\u0165ovan\u00ed UDP trackeru pro HTTP trackery
+memmon.low.warning=Pam\u011b\u0165 je n\u00edzk\u00e1, m\u00e1te %1 zb\u00fdvaj\u00edc\u00ed z %2.\n V\u00fdkon bude sn\u00ed\u017een a nakonec Vuze p\u0159estane fungovat \u00fapln\u011b\nPod\u00edvejte se na <a href="http://wiki.vuze.com/w/Java_VM_memory_usage">Wiki</a> pro podrobnosti, jak zv\u00fd\u0161it dostupnou pam\u011b\u0165.
+jvm.max.mem.current=Sou\u010dasn\u00e9 maximum Hromadn\u00e9 je %1
+jvm.max.direct.mem=Max velikost P\u0159\u00edm\u00e9 pam\u011bti [pr\u00e1zdn\u00e9=v\u00fdchoz\u00ed,min=%1]
+jvm.max.direct.mem.info=Pozn\u00e1mka: toto nastavuje *P\u0159\u00edmou* pam\u011b\u0165, je b\u011b\u017en\u011bj\u0161\u00ed, \u017ee je pot\u0159eba aktualizovat *Hromadnou* pam\u011b\u0165 v\u00fd\u0161e
+jvm.options.summary=Souhrn sou\u010dasn\u00fdch jednozna\u010dn\u00fdch mo\u017enost\u00ed:
+memmon.heap.auto.increase.warning=Hromadn\u00e1 pam\u011b\u0165 byla zv\u00fd\u0161ena na %1. To bude m\u00edt \u00fa\u010dinek, a\u017e bude Vuze restartov\u00e1n.
+device.showGeneric=Zobrazit Obecn\u00e1 Za\u0159\u00edzen\u00ed
+mdi.entry.games=Hry
+Peers.column.Protocol=Protokol
+devices.copying=Kop\u00edruji do Za\u0159\u00edzen\u00ed
+devices.cancel_xcode=Zru\u0161it P\u0159evod
+sidebar.header.transfers=Soubory
+sidebar.header.devices=P\u0159ehr\u00e1v\u00e1n\u00ed Za\u0159\u00edzen\u00ed
+sidebar.header.subscriptions=Odb\u011bry
+sidebar.header.plugins=Z\u00e1suvn\u00e9 moduly & Dopl\u0148ky
+mdi.entry.about.devices=Prob\u00edh\u00e1
+mdi.entry.about.plugins=O Z\u00e1suvn\u00fdch Modulech
+mdi.entry.about.dvdburn=Za\u010d\u00edt
+ConfigView.section.file.tb.delete=P\u0159i maz\u00e1n\u00ed p\u0159es Kli\u010d maz\u00e1n\u00ed nebo Panel N\u00e1stroj\u016f:
+ConfigView.tb.delete.ask=Zeptat se
+ConfigView.tb.delete.content=Smazat bez ptan\u00ed
+ConfigView.tb.delete.torrent=Pouze odstranit z knihovny
+search.export.all=Exportovat V\u0161echny \u0160ablony Hled\u00e1n\u00ed...
+subscriptions.search.enable=Povolit hled\u00e1n\u00ed v\u00fdsledk\u016f odb\u011br\u016f (vy\u017eadov\u00e1n restart)
+devices.cancel_xcode_del=Zru\u0161it P\u0159evod/Odstran\u011bn\u00ed
+subscriptions.add.tooltip=P\u0159idat Odb\u011br
+subscriptions.overview=P\u0159ehled Odb\u011br\u016f
+configureWizard.nat.title=Zkou\u0161ka portu NAT / Server
+configureWizard.nat.message=Abyste dostali z Vuze to nejlep\u0161\u00ed, je vysoce doporu\u010deno, aby byl pln\u011b z internetu p\u0159\u00edstupn\u00fd. Tento n\u00e1stroj V\u00e1m umo\u017en\u00ed vyzkou\u0161et a / nebo zm\u011bnit porty, kter\u00e9 jsou pou\u017eity pro p\u0159ijet\u00ed p\u0159\u00edchoz\u00edch p\u0159ipojen\u00ed.\n\n POZN\u00c1MKA: TCP port 6880 je vnit\u0159n\u011b rezervov\u00e1n, tak\u017ee nem\u016f\u017ee b\u00fdt pou\u017eit.
+configureWizard.nat.server.udp_listen_port=P\u0159\u00edchoz\u00ed naslouchan\u00fd UDP port
+v3.menu.device.defaultprofile.never=Nikdy Nep\u0159ev\u00e1d\u011bt K\u00f3d
+subscriptions.info.avail=Je\u0161t\u011b jste nep\u0159idali \u017e\u00e1dn\u00e9 odb\u011bry. %1 jsou dostupn\u00e9 z Va\u0161\u00ed knihovny.
+subscriptions.dl_subs.enable=Stahovat odb\u011bry od ostatn\u00edch klient\u016f, kdy\u017e je pot\u0159eba
+# Will be used for {library.name} in classic view
+library.name._classic=Moje Torrenty
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Knihovna
+ConfigView.section.style.units=Zobrazen\u00ed Jednotek
+ConfigView.section.style.CatInSidebar=Zobrazit Kategorie v Postrann\u00ed Li\u0161t\u011b
+library.category.header=Kategorie '%1'
+device.import.title=Importovat Za\u0159\u00edzen\u00ed?
+device.import.desc=Jste si jisti, \u017ee chcete importovat za\u0159\u00edzen\u00ed '%1'?
+device.import.dup.title=Duplik\u00e1t Za\u0159\u00edzen\u00ed
+device.import.dup.desc=Za\u0159\u00edzen\u00ed '%1' je ji\u017e p\u0159\u00edtomno.
+stream.analysing.media=Analyzuji M\u00e9dium
+device.export.select.template.file=Exportovat Za\u0159\u00edzen\u00ed
+dlg.stream.plus.subtext=U\u017e jste unaveni \u010dek\u00e1n\u00edm na dokon\u010den\u00ed Va\u0161eho stahov\u00e1n\u00ed? D\u00edvejte se d\u0159\u00edve s P\u0159ehr\u00e1t Te\u010f, funkc\u00ed Vuze Plus, kter\u00e1 V\u00e1m umo\u017en\u00ed d\u00edvat se na video, zat\u00edmco se st\u00e1le stahuje.
+dlg.stream.plus.text=Vylep\u0161ete Vuze na Vuze Plus a p\u0159ehr\u00e1vejte videa, zat\u00edmco se stahuj\u00ed.
+dlg.stream.plus.renew.text=Prodlu\u017ete si Va\u0161e p\u0159edplatn\u00e9 Vuze Plus, abyste mohli d\u00e1le p\u0159ehr\u00e1vat videa p\u0159i stahov\u00e1n\u00ed.
+dlg.stream.plus.renew.title=Prodlou\u017een\u00ed Vuze Plus
+dlg.stream.plus.renew.subtitle=Prodlou\u017een\u00ed Vuze Plus
+Button.upgrade=Aktualizovat
+Button.renew=Obnovit
+stream.analysing.media.preview=Analyzuji M\u00e9dium (Re\u017eim N\u00e1hledu)
+devices.restrict_access=Omezit P\u0159\u00edstup...
+devices.restrict_access.prompt=Omezit P\u0159\u00edstup do '%1'
+devices.restrict_access.msg=Seznam IP odd\u011blen\u00fdch \u010d\u00e1rkou k povolen\u00ed [nebo zam\u00edtnut\u00ed pokud m\u00e1 p\u0159edponu -]
+TableColumn.TorrentStream.tooltip.disabled=P\u0159ehr\u00e1t Te\u010f tento typ soubor\u016f nepodporuje
+TableColumn.TorrentStream.tooltip.expand=Roz\u0161\u00ed\u0159it \u0159\u00e1dek pro zobrazen\u00ed P\u0159ehr\u00e1t Te\u010f pro jednotliv\u00e9 soubory
+table.columns.reset=Resetovat Sloupce
+plus.notificaiton.ExpiringEntry.s=V\u00e1\u0161 odb\u011br Vuze Plus vypr\u0161\u00ed za %1 den: <A %2>Obnovit Ho Hned</A>
+plus.notificaiton.ExpiringEntry.p=V\u00e1\u0161 odb\u011br Vuze Plus vypr\u0161\u00ed za %1 dn\u016f: <A %2>Obnovit Ho Hned</A>
+plus.notificaiton.ExpiredEntry.s=V\u00e1\u0161 odb\u011br Vuze Plus vypr\u0161el: <A %2>Obnovit Ho Hned</A>
+plus.notificaiton.OfflineExpiredEntry=Byli jste offline p\u0159\u00edli\u0161 dlouho. Vuze Plus byl deaktivov\u00e1n
+rss.internal.test.url=Klikn\u011bte pro zobrazen\u00ed m\u00edstn\u00ed domovsk\u00e9 str\u00e1nky
+cat.rss.gen=Vytvo\u0159it m\u00edstn\u00ed RSS kan\u00e1l
+dht.backup.only=Pouze z\u00e1loha DHT
+MyTorrentsView.menu.ipf_enable=Povolit filtr IP
+devices.sidebar.mainheader.tooltip=%1 za\u0159\u00edzen\u00ed je skryto jako obecn\u00e9 nebo neozna\u010den\u00e9.\nPou\u017eijte mo\u017enosti prav\u00e9ho kliknut\u00ed pro zobrazen\u00ed.
+device.mediaserver.remove_all=Odstranit v\u0161echny M\u00e9dia servery
+device.mediaserver.remove_all.title=Potvrdit odstran\u011bn\u00ed
+device.mediaserver.remove_all.desc=Jste si jisti, \u017ee chcete odstranit v\u0161echny M\u00e9dia servery?
+device.renderer.remove_all=Odstranit v\u0161echny vykreslova\u010de
+device.renderer.remove_all.desc=Jste si jisti, \u017ee chcete odstranit v\u0161echny Vykreslova\u010de A jejich p\u0159evody?
+MyTorrentsView.menu.create_personal_share=Vytvo\u0159it osobn\u00ed sd\u00edlen\u00ed
+device.tag=Ozna\u010dit za\u0159\u00edzen\u00ed
+device.onlyShowTagged=Zobrazovat pouze ozna\u010den\u00e9 p\u0159\u00edstroje
+devices.sidebar.show.only.tagged=Zobrazit pouze ozna\u010den\u00e1 za\u0159\u00edzen\u00ed
diff --git a/org/gudy/azureus2/internat/MessagesBundle_da_DK.properties b/org/gudy/azureus2/internat/MessagesBundle_da_DK.properties
index 767ce6b..9e724fd 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_da_DK.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_da_DK.properties
@@ -1,11 +1,11 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=Torrent Fil...
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=Torrent-fil...
 MainWindow.menu.file.open.torrent.keybinding=Meta+o
 Main.parameter.usage=Brug : java org.gudy.azureus2.cl.Main (parametre) "fil.torrent" "lagringssti"
 Main.parameter.maxUploads=Maksimum antal samtidige uploads
 Main.parameter.maxSpeed=Maksimum upload hastighed i bytes/sek
 MainWindow.menu.file=&Filer
-MainWindow.menu.file.open=&\u00c5ben
+MainWindow.menu.file.open=&\u00c5bn
 MainWindow.menu.file.create=&Opret ny torrent...
 MainWindow.menu.file.create.keybinding=Meta+n
 MainWindow.menu.file.create.fromfile=Fra en &Fil
@@ -30,11 +30,13 @@ MainWindow.menu.view=&Vis
 MainWindow.menu.view.show=Vis faner
 MainWindow.menu.view.mytorrents=&Mine Torrents
 MainWindow.menu.view.mytorrents.keybinding=Meta+1 
+MainWindow.menu.view.open_global_transfer_bar=V\u00e6rkt\u00f8jslinjen Overf\u00f8rsler
 MainWindow.menu.view.configuration=&Konfiguration
 MainWindow.menu.view.configuration.keybinding=Meta+, 
 MainWindow.menu.view.console=K&onsol
 MainWindow.menu.view.console.keybinding=Meta+4 
 MainWindow.menu.view.irc=&IRc
+MainWindow.menu.view.allpeers=Alle peers
 MainWindow.menu.closealldetails=Luk &Alle Faneblade
 MainWindow.menu.closealldownloadbars=Luk alle Download &Bj\u00e6lker
 MainWindow.menu.language=&Sprog
@@ -43,17 +45,14 @@ MainWindow.menu.window=&Vindue
 MainWindow.menu.window.minimize=&Minimer
 MainWindow.menu.window.minimize.keybinding=Meta+m
 MainWindow.menu.window.zoom=&Zoom 
-MainWindow.menu.window.alltofront=F\u00f8r alle frem i &Front
+MainWindow.menu.window.alltofront=Vis alle i &forgrunden
 MainWindow.menu.help=&Hj\u00e6lp
 MainWindow.menu.help.about=Om Vuze
 MainWindow.about.title=Om Vuze
-MainWindow.about.section.developers=Udviklere
-MainWindow.about.section.translators=Overs\u00e6ttere
 MainWindow.about.section.system=System 
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.homepage=Vuze hjemmeside
 MainWindow.about.internet.sourceforge=Sourceforge projektside
-MainWindow.about.internet.sourceforgedownloads=Downloads p\u00e5 Sourceforge
 MainWindow.about.internet.bugreports=Fejl rapporter
 MainWindow.about.internet.forumdiscussion=Diskussionsforum
 MainWindow.about.internet.wiki=Vuze Wiki FAQ\n(ofte stillede sp\u00f8rgsm\u00e5l)
@@ -86,7 +85,7 @@ TableColumn.header.priority.info=Bestemmer hvor meget upload b\u00e5ndbredde en
 TableColumn.header.seeds.fullcopycalc=%2 hele kopier formodes for hver %1 peers
 MyTorrentsView.menu.showdetails=Vis &Detaljer
 MyTorrentsView.menu.showdownloadbar=Vis Download &Bj\u00e6lke
-MyTorrentsView.menu.open=&\u00c5ben
+MyTorrentsView.menu.open=&\u00c5bn fil
 MyTorrentsView.menu.setpriority=S\u00e6t &Prioritet
 MyTorrentsView.menu.setpriority.high=&H\u00f8j
 MyTorrentsView.menu.setpriority.low=&Lav
@@ -98,6 +97,7 @@ TrayWindow.menu.exit=&Afslut
 TrayWindow.menu.show=&Vis Vuze
 SystemTray.menu.exit=&Afslut
 SystemTray.menu.closealldownloadbars=Luk &alle Download Bj\u00e6lker
+SystemTray.menu.open_global_transfer_bar=Vis v\u00e6rkt\u00f8jslinjen Overf\u00f8rsler
 SystemTray.menu.show=&Vis Vuze
 PeersView.ip=IP adresse :
 PeersView.ip.info=Peers IP
@@ -133,6 +133,7 @@ PeersView.client=Klient
 PeersView.client.info=Type af BT klient som peer bruger
 PeersView.title.short=Detaljer :
 PeersView.title.full=Detaljer
+AllPeersView.title.full=Alle peers
 ConfigView.section.files=Filer
 ConfigView.label.usefastresume=Aktiver hurtig fors\u00e6ttelse
 ConfigView.label.incrementalfile=Aktiver gradvis oprettelse af fil(er) (FAT32 p\u00e5 Linux kr\u00e6ver dette)
@@ -153,16 +154,16 @@ ConfigView.label.maxuploadspeed=KB/s total maksimum upload hastighed (0 = ubegr\
 ConfigView.label.saveresumeinterval=Opdater data for hurtig forts\u00e6ttelse hver
 ConfigView.unlimited=Ubegr\u00e6nset
 ConfigView.section.display=Udseende
-ConfigView.label.opendetails=\u00c5ben Detalje-Faneblade Automatisk
-ConfigView.label.openbar=\u00c5ben Downloadbj\u00e6lken Automatisk
+ConfigView.label.opendetails=\u00c5bn fanen Detaljer automatisk
+ConfigView.label.openbar=\u00c5bn downloadbj\u00e6lken automatisk
 ConfigView.label.closetotray=Luk minimerer til meddelelsesomr\u00e5det
 ConfigView.label.minimizetotray=Minimer "Minimerer" til meddelelsesomr\u00e5det
 ConfigView.section.general=Generelt
 ConfigView.section.start=Start      
 ConfigView.label.showsplash=Vis opstartsbillede
 ConfigView.label.autoupdate=Automatisk \u00e5bning af Opdateringsvinduet n\u00e5r en nyere version er tilg\u00e6ngelig
-ConfigView.label.openconsole=\u00c5ben Fanen "Konsol" n\u00e5r Vuze startes
-ConfigView.label.openconfig=\u00c5ben Fanen "Konfiguration" n\u00e5r Vuze startes
+ConfigView.label.openconsole=\u00c5bn fanen "Kommandovindue" n\u00e5r Vuze startes
+ConfigView.label.openconfig=\u00c5bn fanen "Konfiguration" n\u00e5r Vuze startes
 ConfigView.label.startminimized=Start minimeret
 ConfigView.section.irc=IRc
 ConfigView.label.ircwiki=L\u00e6s f\u00f8lgende http://www.azureuswiki.com/index.php/Rules_for_IRC
@@ -182,11 +183,10 @@ ConfigView.label.passwordmatchyes=Ja
 ConfigView.button.save=Gem
 ConfigView.title.short=Konfiguration
 ConfigView.title.full=Konfiguration
-ConsoleView.title.short=Konsol
-ConsoleView.title.full=Konsol
+ConsoleView.title.short=Kommandovindue
+ConsoleView.title.full=Kommandovindue
 FileItem.write=Skrivning
 FileItem.read=L\u00e6sning
-FileItem.normal=Normal
 FileItem.high=H\u00f8j
 FileItem.donotdownload=Download ikke
 FilesView.name=Navn :
@@ -198,7 +198,7 @@ FilesView.numberofpieces=Antallet af stykker :
 FilesView.pieces=Stykker :
 FilesView.mode=Tilstand :
 FilesView.priority=Prioritet :
-FilesView.menu.open=&\u00c5ben
+FilesView.menu.open=&\u00c5bn
 FilesView.menu.setpriority=&S\u00e6t prioritet
 FilesView.menu.setpriority.high=&H\u00f8j
 FilesView.menu.setpriority.normal=&Normal 
@@ -289,7 +289,7 @@ MainWindow.upgrade.section.automatic=Automatisk opdatering
 MainWindow.upgrade.tooltip.progressbar=Downloadforl\u00f8bet bliver vist her
 Button.next=N\u00e6ste
 Button.finish=Udf\u00f8r
-Button.cancel=Annuler
+Button.cancel=&Annuler
 LocaleUtil.title=V\u00e6lg kryptering
 LocaleUtil.section.chooseencoding=V\u00e6lg kryptering af filnavn
 LocaleUtil.label.chooseencoding=V\u00e6lg den best passende kryptering
@@ -321,8 +321,6 @@ IrcView.help=Gyldige kommandoer er :\n . /help : Viser denne besked\n . /nick |
 PasswordWindow.title=Vuze er l\u00e5st
 PasswordWindow.passwordprotected=Vuze er beskyttet med adgangskode.\nSkriv din adgangskode her for at f\u00e5 vist Vuze vinduet :
 Button.ok=Ok
-TrackerChangerWindow.title=Tilf\u00f8j tracker
-TrackerChangerWindow.newtracker=Tilf\u00f8j en ny tracker URL
 PeersView.discarded=Kasseret
 PeersView.discarded.info=Data som er blevet modtaget uden, at der var brug for det, og som derfor er blevet slettet.
 discarded=kasseret
@@ -355,7 +353,7 @@ wizard.browse=Gennemse...
 wizard.choosedirectory=V\u00e6lg en mappe
 wizard.invalidfile=Ugyldig fil!
 wizard.invaliddirectory=Ugyldig mappe!
-wizard.torrentFile=Torrent fil
+wizard.torrentFile=Torrent-fil
 wizard.choosetorrent=V\u00e6lg Torrent filen som du vil oprette
 wizard.information=Info
 wizard.notimplemented=Ikke implementeret endnu
@@ -370,8 +368,8 @@ Torrent.create.progress.totalfilecount=Samlet antal filer :
 Torrent.create.progress.parsingfiles=Analyserer filer
 Torrent.create.progress.hashing=Genererer hash-v\u00e6rdier
 MainWindow.upgrade.downloadingfrom=Downloader fra :
-MainWindow.menu.view.ipFilter=&IP Filtre
-ConfigView.section.ipfilter=IP filtre
+MainWindow.menu.view.ipFilter=&IP-filtre
+ConfigView.section.ipfilter=IP-filtre
 ConfigView.section.ipfilter.description=Beskrivelse
 ConfigView.section.ipfilter.start=Start fra IP
 ConfigView.section.ipfilter.end=Slut med IP
@@ -389,12 +387,14 @@ ConfigView.label.showpopuponclose=Bekr\u00e6ft n\u00e5r en Torrent, med et delin
 ConfigView.label.startNumSeeds=Begynd at seede hvis der er f\u00e6rre end :\n - Tilsides\u00e6tter alle andre regler
 ConfigView.label.seeds=Seeder
 ConfigView.section.seeding=Seeder
-MyTorrentsView.menu.removeand=F&jern og
-MyTorrentsView.menu.removeand.deletetorrent=Slet &Torrent
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletetorrent=Slet &torrent-fil
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletedata=Slet &Dataen
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deleteboth=Slet &Begge Dele
 deletedata.title=!!! Advarsel !!!
-deletedata.message1=Du er ved at slette data fra :\n
+# used for more than just "delete data"
 MainWindow.menu.file.configure=Guiden &Konfiguration
 configureWizard.title=Guiden til konfiguration
 configureWizard.welcome.title=Velkommen til Guiden Vuze Konfiguration
@@ -415,8 +415,6 @@ configureWizard.transfer.maxUpSpeed=Maksimal Upload hastighed (KB/s)
 configureWizard.transfer.maxActiveTorrents=Max antal aktive
 configureWizard.transfer.maxDownloads=Max antal downloads
 configureWizard.transfer.maxUploadsPerTorrent=Max Uploads Pr. Torrent
-configureWizard.nat.title=NAT / Server port
-configureWizard.nat.message=For at f\u00e5 det bedste ud af Vuze m\u00e5 det st\u00e6rkt anbefales at der er fuldt tilg\u00e6ngelighed til og fra Internettet. Dette v\u00e6rkt\u00f8j lader dig teste og/eller \u00e6ndre porten til indg\u00e5ende peer forbindelser.\n\nBEM\u00c6RK : V\u00e6rkt\u00f8jet tester KUN din TCP forbindelse. En "Distribueret DB" kr\u00e6ver ogs\u00e5 en indg\u00e5ende UDP forbindelse men vil automatisk give besked hvis der opdages, at en firewall blokerer for adgan [...]
 configureWizard.nat.test=Test port
 configureWizard.nat.testing=Porten testes
 configureWizard.nat.ok=Ok !
@@ -479,15 +477,15 @@ ConfigView.label.xfs.allocation.tooltip=Tjek om /usr/sbin/xfs_io er korrekt inst
 xfs.allocation.xfs_io.not.found=Placeringen af XFS filen mislykkedes fordi /usr/sbin/xfs_io ikke kan k\u00f8res. Kontroller at den er korrekt installeret p\u00e5 dit system. Original fejlmelding var "%1".
 ConfigView.label.zeronewfiles=Alloker diskplads og nulstil nye filer ved oprettelsen
 ConfigView.label.zeronewfiles.tooltip=Minimerer fragmentering
-ConfigView.section.stats=Statistikker
+ConfigView.section.stats=Statistik
 ConfigView.section.stats.enable=Aktiver
-ConfigView.section.stats.defaultsavepath=Gem statistikker i denne mappe
-ConfigView.section.stats.choosedefaultsavepath=V\u00e6lg mappen som statistikker skal gemme i
+ConfigView.section.stats.defaultsavepath=Gem statistik i denne mappe
+ConfigView.section.stats.choosedefaultsavepath=V\u00e6lg mappen som statistik skal gemmes i
 ConfigView.section.stats.savefreq=Gem hvert :
 ConfigView.section.stats.minutes=minutter
 ConfigView.section.stats.hours=timer
 ConfigView.section.stats.seconds=sekunder
-ConfigView.section.stats.savefile=Filnavn for statistikker :
+ConfigView.section.stats.savefile=Filnavn for statistik
 MyTorrentsView.menu.export=&XML Torrent..
 MyTorrentsView.menu.host=&Udgiv...
 ManagerItem.finishing=Afslutter
@@ -495,7 +493,7 @@ ConfigView.dialog.choosedefaulttorrentpath=V\u00e6lg din standard Torrent mappe
 ConfigView.dialog.choosemovepath=V\u00e6lg den mappe der skal flyttes til
 ConfigView.label.movecompleted=Flyt f\u00e6rdige filer (efter download)
 ConfigView.label.moveremoved=Flyt f\u00e6rdige filer (n\u00e5r de fjernes fra Vuze
-ConfigView.label.savetorrents=Gem Torrent filer
+ConfigView.label.savetorrents=Gem .torrent-filer
 MainWindow.menu.view.mytracker=Min &Tracker
 MainWindow.menu.view.mytracker.keybinding=Meta+2 
 MyTrackerView.title.full=Min tracker
@@ -512,7 +510,7 @@ MyTrackerView.downloaded=Downloadet :
 MyTrackerView.left=Tilbage
 ConfigView.section.style=Brugergr\u00e6nseflade
 ConfigView.label.set_ui_transfer_speeds=Overskriv valgfri overf\u00f8rsels hastighed
-ConfigView.label.set_ui_transfer_speeds.description=Du kan v\u00e6lge at definere din download og upload hastighed manuelt i statusbaren som du har til r\u00e5dighed i systembakken.\nV\u00e6rdierne skal v\u00e6re delt med komma (,).
+ConfigView.label.set_ui_transfer_speeds.description=Du kan v\u00e6lge at angive din download- og upload-hastighed manuelt via statuslinjeikonet, som du finder i systembakken.\nV\u00e6rdierne skal v\u00e6re adskilt af kommaer (,).
 ConfigView.label.set_ui_transfer_speeds.description.download=Juster download hastigheden (i KB/s)
 ConfigView.label.set_ui_transfer_speeds.description.upload=Juster upload hastigheden (i KB/s)
 ConfigView.section.style.useCustomTabs=Aktiver lukning af faneblade (kr\u00e6ver genstart)
@@ -526,7 +524,7 @@ fileDownloadWindow.state_downloading=Downloader
 fileDownloadWindow.state_error=Fejl :
 MainWindow.menu.file.open.url=&Placering...
 MainWindow.menu.file.open.url.keybinding=Meta+l
-openUrl.title=\u00c5ben placering
+openUrl.title=\u00c5bn URL
 openUrl.url=URL : 
 MyTorrentsView.menu.host.error.title=Hosting af Torrent fejlede
 MyTorrentsView.menu.host.error.message=F\u00f8lgende fejl opstod under fors\u00f8g p\u00e5 at hoste Torrenten
@@ -575,7 +573,7 @@ ConfigView.section.color=Farvevalg
 MyTorrentsView.menu.publish=&Udgiv...
 MyTrackerView.status.published=Udgivet
 MyTrackerView.completed=Fuldf\u00f8rte
-MainWindow.menu.file.open.torrentnodefault=Torrent Fil... (ingen standard lagring)
+MainWindow.menu.file.open.torrentnodefault=Torrent-fil... (ikke standarddestination)
 MainWindow.menu.file.open.torrentnodefault.keybinding.mac=Meta+Opt+o
 wizard.comment=Kommentar :
 ConfigView.label.movetorrent=Flyt torrent
@@ -588,7 +586,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com
 IPChecker.external.service.no-ip.description=Dynamisk og statisk DNS service udbyder\n(er der ingen til r\u00e5dighed s\u00e5 "tjek adresse" service)
 ConfigView.section.tracker.publicenable=Tillad eksterne Torrents
 ConfigView.label.playdownloadspeech="Tal" n\u00e5r en dowmload er f\u00e6rdig
-ConfigView.label.playdownloadspeech.info=Tale servisen virker i \u00f8jeblikket bedst med engelsk
 #
 # Tooltips
 #
@@ -621,16 +618,15 @@ columnChooser.columndescription=Beskrivelse
 TableColumn.header.shareRatio=Delingsforhold 
 MyTorrentsView.menu.editTableColumns=&V\u00e6lg dine kolonner
 wizard.operationfailed=Operationen mislykkedes
-authenticator.title=Bekr\u00e6ftigelse P\u00e5kr\u00e6vet
+authenticator.title=Godkendelse p\u00e5kr\u00e6vet
 authenticator.realm=Omr\u00e5de
-authenticator.tracker=Tracker :
 authenticator.user=Brugernavn
 authenticator.password=Adgangskode
 ConfigView.label.allowSendVersion=Tillad Vuze at sende versions nummer og tilf\u00e6ldig id anonymt, n\u00e5r der s\u00f8ges efter nye versioner
 wizard.hint.mode=Tip :\tDu kan v\u00e6lge en enkelt fil eller en mappe ved at\n\ttr\u00e6kke og slippe den p\u00e5 denne guide.
 wizard.hint.file=Tip :\tDu kan v\u00e6lge en enkelt fil ved brug af tr\u00e6k og slip.
 wizard.hint.directory=Tip :\tDu kan v\u00e6lge en enkelt mappe ved brug af tr\u00e6k og slip.
-MainWindow.menu.help.checkupdate=&S\u00f8g efter nye Opdateringer...
+MainWindow.menu.help.checkupdate=&S\u00f8g efter opdateringer...
 TableColumn.header.down=Downloadet 
 TableColumn.header.up=Uploadet 
 ConfigView.section.tracker.passwordenabletorrent.info=Kr\u00e6ver kompatibel BitTorrent klient (f.eks. Vuze
@@ -672,13 +668,13 @@ iconBar.showDownloadBar.tooltip=Vis Download Bj\u00e6lke
 iconBar.start.tooltip=Start 
 iconBar.stop.tooltip=stop
 iconBar.remove.tooltip=Fjern
-iconBar.openNoDefault.tooltip=\u00c5ben en Torrent fil (ingen standard lagring)
-iconBar.openURL.tooltip=\u00c5ben en URL
-iconBar.openFolder.tooltip=\u00c5ben en mappe
+iconBar.openNoDefault.tooltip=\u00c5bn en torrent-fil (ikke standarddestination)
+iconBar.openURL.tooltip=\u00c5bn en URL
+iconBar.openFolder.tooltip=\u00c5bn en mappe
 iconBar.new.tooltip=Opret en torrent
 iconBar.up.tooltip=Flyt op
 iconBar.down.tooltip=Flyt Ned
-iconBar.run.tooltip=\u00c5ben
+iconBar.run.tooltip=\u00c5bn vha. standardprogram
 iconBar.host.tooltip=V\u00e6rt
 iconBar.publish.tooltip=Udgiv
 MyTorrentsView.menu.editTracker=&Rediger en tracker URL
@@ -698,7 +694,7 @@ ConfigView.label.userSuperSeeding=Aktiver Super-Seeding
 PeersView.uniquepiece=Stykke (Super-Seed tilstand)
 PeersView.uniquepiece.none=Ingen
 PeersView.timetosend=Tid til at sende stykke igen (Super Seed tilstand)
-ConfigView.section.style.addurlsilently=\u00c5ben URL i baggrunden
+ConfigView.section.style.addurlsilently=\u00c5bn URL i baggrunden
 ConfigView.section.style.addurlsilently.tooltip=Advarsel : Ved aktivering af denne indstilling vil programvinduet ikke blive gjort synligt igen!\nHvis ikonet i meddelelsesomr\u00e5det forsvinder, b\u00f8r du deaktivere denne indstilling.
 ConfigView.section.file.decoder.prompt=Sp\u00f8rg altid n\u00e5r valg af kryptering er tilg\u00e6ngeligt
 ConfigView.section.file.decoder.prompt.tooltip=Vis altid valgmulighederne n\u00e5r kryptering er tilg\u00e6ngeligt
@@ -718,7 +714,7 @@ wizard.maketorrent.filesize=Filst\u00f8rrelse :
 wizard.maketorrent.piececount=Antal stykker :
 wizard.maketorrent.piecesize=Styk-st\u00f8rrelse :
 wizard.maketorrent.auto=Automatisk
-MainWindow.menu.view.stats=&Statistikker
+MainWindow.menu.view.stats=&Statistik
 MainWindow.menu.view.stats.keybinding=Meta+5 
 SpeedView.title.full=Aktivitet
 SpeedView.downloadSpeed.title=Download hastighed :
@@ -727,7 +723,7 @@ ConfigView.section.style.useSIUnits=Brug IEC enheder (Kb -> Kib osv.)
 iconBar.top.tooltip=Flyt til toppen
 iconBar.bottom.tooltip=Flyt til bunden
 TableColumn.header.health=Tilstand 
-MyTorrentsView.menu.health=Forklaring af tilstand
+MyTorrentsView.menu.health=Ikonforklaring
 health.explain.grey=Betyder at din Torrent ikke k\u00f8rer (downloader eller uploader).
 health.explain.red=Betyder at du ikke er forbundet til nogen peers mens du downloader.
 health.explain.blue=N\u00e5r du seeder betyder det, at du endnu ikke er forbundet til nogen peers.\nN\u00e5r du downloader, betyder det, at du er forbundet til nogle peers, men at trackeren er nede.
@@ -750,8 +746,8 @@ ConfigView.section.tracker.torrentsperpage=Hvor mange Torrents Pr. side ?  (0 =
 MainWindow.menu.file.share=&Del
 MainWindow.menu.file.share.file=&Fil...
 MainWindow.menu.file.share.dir=&Mappe...
-MainWindow.menu.file.share.dircontents=Mappe &Indhold...
-MainWindow.menu.file.share.dircontentsrecursive=Mappe Indhold... (&og undermapper)...
+MainWindow.menu.file.share.dircontents=&Mappeindhold...
+MainWindow.menu.file.share.dircontentsrecursive=Mappeindhold... (&inkl. undermapper)...
 MainWindow.dialog.share.sharefile=V\u00e6lg filen der skal deles
 MainWindow.dialog.share.sharedir=V\u00e6lg mappen der skal deles
 MainWindow.dialog.share.sharedircontents=V\u00e6lg mappeindhold der skal deles
@@ -762,10 +758,8 @@ ConfigView.section.tracker.main=Hoved
 ConfigView.section.tracker.web=web
 ConfigView.label.prioritizefirstpiece=Prioriter f\u00f8rste del af fil(er)
 ConfigView.label.prioritizefirstpiece.tooltip=Fors\u00f8ger at downloade starten af en fil f\u00f8rst.\nFor at opn\u00e5 mulighed for tidlig previewing.
-ConfigView.section.file.confirm_data_delete=Bekr\u00e6ft inden data slettes
-ConfigView.section.file.confirm_data_delete.tooltip=Bekr\u00e6ft sletning af data ved brug af "Fjern og slet..."
 TrayWindow.menu.startalldownloads=Start alle downloads
-SystemTray.menu.startalltransfers=Start Alle Overf\u00f8relser
+SystemTray.menu.startalltransfers=Start alle overf\u00f8relser
 sharing.progress.title=Delingsforl\u00f8b
 sharing.progress.hide=Skjul
 MainWindow.menu.view.myshares=Mine delte filer
@@ -792,7 +786,7 @@ configureWizard.nat.server.tcp_listen_port=Indg\u00e5ende TCP port der "lyttes"
 ConfigView.section.sharing=Deling
 ConfigView.section.sharing.usessl=Brug SSL til delte ressourcer (kr\u00e6ver konfiguration af tracker)
 ConfigView.section.style.dropdiraction=Tr\u00e6k og slip handling for mapper
-ConfigView.section.style.dropdiraction.opentorrents=\u00c5ben Torrents
+ConfigView.section.style.dropdiraction.opentorrents=\u00c5bn torrents
 ConfigView.section.style.dropdiraction.sharefolder=Dele mappe
 ConfigView.section.style.dropdiraction.sharefoldercontents=Del indholdet
 #
@@ -802,7 +796,7 @@ Categories.all=Alle
 Categories.uncategorized=Ingen kategori
 CategoryAddWindow.message=Navnet p\u00e5 den nye kategori :
 CategoryAddWindow.title=Tilf\u00f8j ny kategori
-ConfigView.label.autoSeedingIgnoreInfo=Ignorerede Torrents flyttes til bunden af seeder-k\u00f8en. De bliver ikke startet automatisk.\nReglerne for ignorering af Torrents g\u00e6lder ikke for Torrents, der opfylder kriteriet for at f\u00e5 f\u00f8rste prioritet.\nHvis ikke andet er angivet, bruges v\u00e6rdien 0 til at deaktivere en regel.
+ConfigView.label.autoSeedingIgnoreInfo=Ignorerede torrents flyttes til bunden af delingsk\u00f8en. De bliver ikke startet automatisk.\nReglerne for ignorering af torrents g\u00e6lder ikke for Torrents, der opfylder kriterierne for f\u00f8rsteprioritet.\nHvis ikke andet er angivet, bruges v\u00e6rdien 0 til at deaktivere en regel.
 ConfigView.label.directory=Til mappen
 ConfigView.label.disconnetseed.tooltip=N\u00e5r der seedes p\u00e5 en torrent, afbrydes forbindelsen til andre klienter som ogs\u00e5 seeder.\nForbindelsen til dem er ikke n\u00f8dvendig.
 ConfigView.label.ignoreCase=Der skelnes ikke mellem STORE og eller sm\u00e5 bogstaver.
@@ -815,8 +809,8 @@ ConfigView.label.minSeedingTime=Minimum seeding tid i sekunder
 ConfigView.label.minSpeedForActiveDL.tooltip=Der bliver altid brugt en download plads de f\u00f8rste 30 sekunder\nefter en ufuldst\u00e6ndig Torrent starter.
 ConfigView.label.minSpeedForActiveDL=Undlad at t\u00e6lle en torrent med hvis download hastigheden er under
 ConfigView.label.peers=Peers
-ConfigView.label.queue.debuglog=Log "debug" informationen
-ConfigView.label.queue.debuglog.info=Tilf\u00f8jer "debug" information om k\u00f8en til konsol/log-filen.\n"Debug" informationerne fort\u00e6ller, omend en smule kryptisk,\nstatus for Torrents samt hvorfor de /ikke er startetet/er i k\u00f8.
+ConfigView.label.queue.debuglog=Gem fejlrapport
+ConfigView.label.queue.debuglog.info=Tilf\u00f8jer fejlrapportdata for k\u00f8en til kommandovinduet/log-filen.\nFejlrapporten kan v\u00e6re lidt sv\u00e6r at tyde, men den indeholder statusinformation\nom dine torrents og fort\u00e6ller, hvorfor de ikke er er startet/er i k\u00f8.
 ConfigView.label.queue.minQueueingShareRatio=Stop eller s\u00e6t ikke en Torrent i k\u00f8 f\u00f8r delingsforholdet n\u00e5r
 ConfigView.label.ratio=forhold
 ConfigView.label.removeOnStop=Fjern en Torrent fra listen efter at den automatisk er stoppet
@@ -829,7 +823,7 @@ ConfigView.label.seeding.ignore=Ignorer Regler
 ConfigView.label.seeding.ignore0Peers=Ignorer Torrents med 0 peers
 ConfigView.label.seeding.ignoreRatioPeers=Ignorer Torrents som har mindst 1 seeder for hver
 ConfigView.label.seeding.ignoreShareRatio=Ignorer Torrents som har et delingsforhold p\u00e5
-ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignorer torrent selv hvis en\nf\u00f8rsteprioritets-regel er opfyldt
+ConfigView.label.seeding.ignore.header.evenFirstPriority=Ignorer torrent, selvom en\nf\u00f8rsteprioritetsregel er opfyldt
 ConfigView.label.seeding.ignore.header.rule=Regel
 ConfigView.label.seeding.ignore.header.value=V\u00e6rdi
 ConfigView.label.seeding.firstPriority.info=Torrents med f\u00f8rsteprioritet vil altid blive placeret i toppen af k\u00f8en.  Enhver Torrent der matcher kriterierne for f\u00f8rsteprioritet vil ikke automatisk blive stoppet og sat i k\u00f8.  En Torrent der matcher kriterierne for f\u00f8rsteprioritet vil tage en sidel\u00f8bende download plads hvis n\u00f8dvendigt.
@@ -876,7 +870,7 @@ ConfigView.text.minutes=minutter
 ConfigView.text.neverIgnore=Ignorer aldrig
 ConfigView.text.any=hvilken som helst
 DownloadManager.error.datamissing=Data mangler
-MainWindow.menu.file.open.torrentforseeding=Torrent Fil... (Til seeding)
+MainWindow.menu.file.open.torrentforseeding=Torrent-fil... (til seeding)
 MainWindow.menu.language.refresh=&Opdater
 ManagerItem.forced=Tvunget
 ManagerItem.queued=Sat i k\u00f8
@@ -893,7 +887,7 @@ MyTorrentsView.menu.setCategory.add=&Tilf\u00f8j en kategori...
 MyTorrentsView.menu.setCategory=Tildel/Tilf\u00f8j en kategori
 TableColumn.header.savepath=Lagringsmappe 
 TableColumn.header.SeedingRank=Seed rang
-TableColumn.header.totalspeed.info=Den totale hastighed for alle Torrents du er forbundet til
+TableColumn.header.totalspeed.info=Den totale hastighed for alle peers, du er forbundet til
 TableColumn.header.totalspeed=Den totale hastighed 
 splash.initializePlugins=Initialiserer plugins
 StartStopRules.SPratioMet=S/P Forholdet er OK
@@ -934,16 +928,15 @@ GeneralView.label.in_swarm=i sv\u00e6rmen
 ManagerItem.initializing=Initialiserer
 AlertMessageBox.error=Fejl
 AlertMessageBox.warning=Advarsel
-AlertMessageBox.comment=Info
-AlertMessageBox.information=Info
-AlertMessageBox.unread=Du har ul\u00e6ste advarsels beskeder - klik her for at l\u00e6se den/dem.
+AlertMessageBox.comment=Kommentar
+AlertMessageBox.unread=Du har ul\u00e6ste advarselsbeskeder - klik her for at \u00e5bne dem.
 SharedPortServer.alert.selectorfailed=Der kunne ikke \u00e5bnes en port for indg\u00e5ende data.\nKontroller om firewall indstillinger tillader at java(w).exe fungerer som server.
 Tracker.alert.listenfail=Kunne ikke etablere en lytte port %1.\nKontroller at porten ikke bruges af andre programmer\nog tjek samtidig om der k\u00f8rer en anden kopi af Azureus.
 DiskManager.alert.movefileexists=Kunne ikke flytte f\u00e6rdige filer.\nFilen %1 eksisterer allerede i destinationsmappen.
 DiskManager.alert.movefilefails=Kunne ikke flytte f\u00e6rdige filer.\nFlytning af filen %1 mislykkedes, %2
 DiskManager.alert.movefilerecoveryfails=Kunne ikke genoprette efter mislykket flytning.\nGenopretning af filen %1 mislykkedes, %2
-ConfigView.section.tracker.logenable=Log periodisk statistikker til "tracker.log"
-SpeedView.stats.title=Statistikker
+ConfigView.section.tracker.logenable=Gem regelm\u00e6ssigt statistik i "tracker.log"
+SpeedView.stats.title=Statistik
 SpeedView.stats.total=I alt :
 SpeedView.stats.session=Denne session :
 SpeedView.stats.session.tooltip=Total (Protokol)
@@ -957,7 +950,7 @@ AutoMigration.useralert=Resultatet efter Automatisk migrering af Vuze brugers co
 #
 # > 2.0.8.0
 #
-OpenTorrentWindow.title=\u00c5ben Torrent(s)
+OpenTorrentWindow.title=\u00c5bn torrent(s)
 OpenTorrentWindow.message=Eksperimentel
 OpenTorrentWindow.addFiles=&Tilf\u00f8j filer
 OpenTorrentWindow.dataLocation=Stien hvor data skal lagres :
@@ -1046,8 +1039,8 @@ ConfigView.section.interface.resetassoc=Nulstil explorer fil-associeringer (Torr
 ConfigView.section.interface.resetassocbutton=Genskab
 ConfigView.section.interface.checkassoc=Kontroller fil-associeringer ved opstarten
 dialog.associations.title=Kontrol af fil-associeringer
-Button.yes=Ja
-Button.no=Nej
+Button.yes=&Ja
+Button.no=&Nej
 ConfigView.label.seeding.autoStart0Peers=Start alle f\u00e6rdige Torrents uden peers automatisk
 ConfigView.label.seeding.autoStart0Peers.tooltip=Aktiver hvis du \u00f8nsker at trackeren altid skal vise antal seeds
 dialog.associations.prompt=Vuze er ikke standard program for BitTorrent filer.\n\u00d8nsker du at associere Torrent filer med Vuze
@@ -1083,20 +1076,19 @@ ConfigView.pluginlist.whereToPutOr=Placer delte tilf\u00f8jelser under :
 MainWindow.statusText.checking=Der s\u00f8ges efter nye opdateringer
 TableColumn.header.OnlyCDing4=Kun seedet 
 TableColumn.header.OnlyCDing4.info=Tidsrum hvor en Torrent kun har v\u00e6re seeding. Tidsrummet for download (og seeding) t\u00e6ller ikke med.
-ConfigView.section.style.alternateTablePainting=Brug alternativ metode til at tegne grafiske tabelkolonner (kr\u00e6ver muligvis genstart)
 UpdateWindow.status.restartMaybeNeeded=Det kan v\u00e6re n\u00f8dvendigt genstarte
 ConfigView.pluginlist.shared=Delte
 PeersView.host=Udbyders Navn
 PeersView.host.info=Peers udbyder navn, hvis det er tilg\u00e6ngeligt (kan p\u00e5virke ydeevnen)
 MainWindow.menu.help.whatsnew=&Hvad er nyt?
-ConfigView.label.checkonstart=S\u00f8g efter nye Opdateringer n\u00e5r Vuze startes
+ConfigView.label.checkonstart=S\u00f8g efter opdateringer n\u00e5r Vuze startes
 ConfigView.label.periodiccheck=Kontroller periodisk om en ny version af programmet er tilg\u00e6ngeligt
 ConfigView.label.opendialog=Automatisk \u00e5bning af OpdateringsAssistenten n\u00e5r en ny opdatering er tilg\u00e6ngelig
 MainWindow.updateavail=Klik her for at hente opdateringer
 MainWindow.status.unofficialversion=Vuze - Beta
 MainWindow.status.latestversionunchecked=Kontrol for ny version er deaktiveret
 GeneralView.label.updatein.stopped=Stoppet
-StartStopRules.menu.viewDebug=Vis debug information
+StartStopRules.menu.viewDebug=Vis fejlrapport
 ConfigView.section.style.doNotUseGB=Brug ikke enheden Gb (gigabyte)
 ConfigView.section.style.doNotUseGB.tooltip=Bruger enheden Mb (megabyte) selv for v\u00e6rdier over 1024 Mb (=1 Gb)
 MainWindow.menu.help.plugins=&Hent tilf\u00f8jelser
@@ -1136,7 +1128,6 @@ webui.access.info=Adgang kan v\u00e6re\n\t"lokal"\t = Kun den lokale computer ka
 GeneralView.label.maxdownloadspeed=Maksimum Ned
 Security.keystore.corrupt=N\u00f8glefilen "%1" kunne ikke indl\u00e6ses. Slet n\u00f8glefilen og opret/importer certifikatet igen
 Security.keystore.empty=N\u00f8glefilen er tom. Opret et selvudstedt certifikat (se V\u00e6rkt\u00f8jer-> Konfiguration->Sikkerhed) eller importer et eksisterende certifikat til "%1"
-webui.restart.info=\u00c6ndring af parametre markeret med (*) tr\u00e6der f\u00f8rst i kraft efter en genstart.
 GeneralView.label.maxdownloadspeed.tooltip=Maksimum download hastighed (0 = ubegr\u00e6nset)
 ConfigView.section.UPnP=UPnP 
 upnp.enable=Aktiver UPnP
@@ -1168,12 +1159,12 @@ webui.upnpenable=Aktiver UPnP for denne port (*)
 ConfigView.section.file.friendly.hashchecking=Brug mindre belastende metode til kontrol af hash-v\u00e6rdier
 ConfigView.section.file.friendly.hashchecking.tooltip=En anelse langsommere, men med v\u00e6sentlig mindre belastning af CPU/systemet, n\u00e5r hashfilen og filstykkerne skal tjekkes.
 ConfigView.section.tracker.seedretention=Det maksimale antal seedere opn\u00e5et Pr. Torrent (0 = ubegr\u00e6nset)
-ConfigView.section.tracker.seedretention.info=Bem\u00e6rk : Upload statistikkerne til Seeds som ikke opretholdes mistes
+ConfigView.section.tracker.seedretention.info=Bem\u00e6rk: Overf\u00f8rt statistik for ikke-gemte seeds mistes
 ConfigView.section.tracker.port=Aktiver tracker p\u00e5 HTTP porten
 ConfigView.section.tracker.sslport=Aktiver trackeren p\u00e5 HTTPS porte
 ConfigView.section.tracker.publicenable.info=Dette tillader andre at oprette Torrents som bruger din tracker\nuden at du er v\u00e6rt eller udgiver dem
 Button.clear=Ryd
-MainWindow.IPs.tooltip=Seneste opdatering af IP filter listen : %1\nAntal IP filtre i listen - Antal blokerede IP adresser i denne session.\nDobbeltklik for detaljerede oplysninger.
+MainWindow.IPs.tooltip=Seneste opdatering af IP-filterlisten: %1\nAntal IP-filtre i listen - Antal blokerede IP-adresser i denne session.\nDobbeltklik for detaljerede oplysninger.
 ConfigView.section.ipfilter.list.banned=er blevet bandlyst
 ConfigView.section.ipfilter.list.baddata=har sendt d\u00e5rlig data : hyppigheden =
 Button.reset=Nulstil
@@ -1190,7 +1181,7 @@ ConfigView.section.server.enableudp=Aktiver UDP trackerens klient protokol.
 upnp.mapping.dataportudp=UDP trackerens klient Port
 ConfigView.section.file.decoder.showlax=Vis mindst sansynlige krypteringsvalg
 ConfigView.section.file.decoder.showall=Betragt alle krypterings muligheder
-MainWindow.status.updowndetails.tooltip=Detaljer for Download/Upload hastigheden\nH\u00f8jre klik for at \u00e6ndre, Dobbelt-klik for at \u00e5bne statistikker
+MainWindow.status.updowndetails.tooltip=Detaljer om download/upload-hastighed\nH\u00f8jreklik for at \u00e6ndre, dobbeltklik for at \u00e5bne statistik
 TrackerClient.announce.warningmessage=Tracker til "%1" returneret advarsel "%2"
 ConfigView.section.tracker.natcheckenable=Tjek forbindelsesevnen p\u00e5 "indg\u00e5ende dataporte" og reporter om fejl til peers
 ConfigView.section.tracker.publishenabledetails=Udgiv alle Torrent detaljer
@@ -1200,8 +1191,6 @@ MyTrackerView.badnat.info=Seedere/Peers som ikke bestod en NAT kontrol
 ConfigView.section.tracker.natchecktimeout=Tjek "timeout" (sekunder)
 ConfigView.section.file.perf.cache.enable=Aktiver disk cache
 ConfigView.section.file.perf.cache.size=St\u00f8rrelse af cache i %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=O&verf\u00f8rsler
 MainWindow.menu.transfers.startalltransfers=St&art Alle
 MainWindow.menu.transfers.stopalltransfers=St&op Alle
@@ -1214,7 +1203,7 @@ SystemTray.menu.resumetransfers=Genoptag Overf\u00f8relser
 ConfigView.section.file.perf.cache.trace=Spor cashe operationer til diagnose form\u00e5l
 ConfigView.section.interface.enabletray=Aktiver System Bakken (kr\u00e6ver genstart af Vuze
 PeerManager.status.error=Fejl
-Stats.title.full=Statistikker
+Stats.title.full=Statistik
 TransferStatsView.title.full=Overf\u00f8relser
 CacheView.title.full=Cache fil
 CacheView.general.size=Total st\u00f8rrelse :
@@ -1254,7 +1243,6 @@ Security.jar.signfail=JAR signering mislykkedes - %1
 ConfigView.section.security.toolsinfo=Signerede JAR filer bruges til at underst\u00f8tte visse tilf\u00f8jelser, F.eks "Swing web Interface" (n\u00e5r det er indstillet til det).\nFor at kunne signere en JAR fil er det n\u00f8dvendigt at have adgang til "tools.jar" filen som kommer med Sun JDK og ikke JRE installationen.\nHvis du kun har JRE skal du installere JDK.\nAzurerus kan normalt finde filen til dig men hvis dette mislykkedes kan du tilf\u00f8je mappen der indeholder filen her.
 ConfigView.section.security.toolsdir=Mappen som indeholder "tools.jar"
 ConfigView.section.security.choosetoolssavedir=V\u00e6lg mappen som indeholder "tools.jar"
-authenticator.torrent=Torrents
 ConfigView.section.proxy.peer.same=Brug de samme proxy instillinger til "tracker og peer kommunikations proxy
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=Maksimum samtidige udg\u00e5ende forbindelses fors\u00f8g
 ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Maksmum antal af nye udg\u00e5ende forbindelses-etableringer som Vuze skal fors\u00f8ge ad gangen.\nOBS : WindowsXP Service Pack 2 (SP2) p\u00e5byder en system-begr\u00e6nsning p\u00e5 10 samtidige forbindelses-fors\u00f8g.\nStandart v\u00e6rdi er 8.
@@ -1306,7 +1294,7 @@ ConfigView.section.tracker.maxthreads=Maksimum vedvarende foresp\u00f8rgelser
 DownloadManager.error.operationcancancelled=Handling annuleret
 Torrent.create.progress.cancelled=Handling annuleret
 sharing.progress.cancel=Annuller
-wizard.maketorrents.autoopen=\u00c5ben Torrenten til Seeding N\u00e5r downloaden er f\u00e6rdig
+wizard.maketorrents.autoopen=\u00c5bn torrent-filen til seeding, n\u00e5r download er afsluttet
 ConfigView.section.sharing.rescanenable=Aktiver periodisk scanning af delte filer/mapper og tjek om der er \u00e6ndringer
 ConfigView.section.connection.advanced=Avanceret Netv\u00e6rks instillinger
 ConfigView.section.connection.advanced.url=http://www.azureuswiki.com/index.php/AdvancedNetworkSettings/
@@ -1316,15 +1304,10 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Socket SO_RCVBUF st\u00f8rrelse
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=S\u00e6tter standart socket SO_RCVBUF v\u00e6rdien (i bytes), i.e. TCP modtager vindus st\u00f8rrelse og skala.\nSom Vuze standart er feltet tomt, hvilket betyder at det er standarten for det underliggende operativsystem (OS) som bruges.\nOBS Linux fordobler den angivne v\u00e6rdi.
 ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF st\u00f8rrelse (0 = brug operativsystemets (OS) standart)
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=S\u00e6tter standart socket SO_SNDBUF v\u00e6rdien (i bytes), i.e. TCP sendte vindues st\u00f8rrelse.\nSom Vuze standart er feltet tomt, hvilket betyder at det er standarten for det underliggende operativsystem (OS) som bruges.\nOBS Linux fordobler den angivne v\u00e6rdi.
-ConfigView.section.interface.confirm_torrent_removal=Vis bekr\u00e6ftigelses dialogen inden en Torrent fjernes
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Bekr\u00e6ft handlingen n\u00e5r der fjernes en Torrent fra Mine Torrents.
-MyTorrentsView.confirm_torrent_removal=Er du sikker p\u00e5 du vil fjerne?\n
 TableColumn.header.seed_to_peer_ratio=Seed2Peer Forhold 
 TableColumn.header.seed_to_peer_ratio.info=Sv\u00e6rmens totale Seed2Peer Forhold
 PeersView.connected_time=Tilsluttet tid
 PeersView.connected_time.info=Den totale tid forbundet med peer
-ConfigView.section.interface.display.add_torrents_silently=Tilf\u00f8j Torrent uden lyd
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Tilf\u00f8j en Torrent uden at aktivere Vuze hoved vindue.
 TableColumn.header.maxdownspeed=Maksimum Download Hastighed 
 TableColumn.header.maxdownspeed.info=Maksimum Download Hastighed Pr. Torrent
 PeersGraphicView.title=Sv\u00e6rm
@@ -1333,7 +1316,7 @@ TableColumn.header.torrentpath=Torrentens placering
 TableColumn.header.torrentpath.info=Torrentens placering p\u00e5 disken
 ConfigView.section.sharing.torrentcomment=Kommentar til oprettet Torrent
 ConfigView.label.copyanddeleteratherthanmove=Kopier og derefter slet den originale data, fremfor at flytte dataen i en operation - det kan afhj\u00e6lpe data tab p\u00e5 nogle fil systemer
-ConfigView.label.openstatsonstart=\u00c5ben Fanen "Statistikker" n\u00e5r Vuze startes
+ConfigView.label.openstatsonstart=\u00c5bn fanen "Statistik" n\u00e5r Vuze startes
 swt.install.window.title=Vuze Tilf\u00f8jelses Installering
 swt.install.window.ok=Installere
 swt.install.window.header=De f\u00f8lgene komponenter er blevet valgt til  installation :
@@ -1341,7 +1324,7 @@ swt.uninstall.window.title=Afinstallering af Vuze Tilf\u00f8jelse
 swt.uninstall.window.ok=Fjern
 swt.uninstall.window.header=F\u00f8lgende komponenter er markeret til fjernelse :
 installPluginsWizard.title=Installer tilf\u00f8jelser
-installPluginsWizard.mode.title=V\u00e6lg en installations metode
+installPluginsWizard.mode.title=V\u00e6lg en installationsmetode
 installPluginsWizard.mode.list=Fra liste p\u00e5 sourceforge.net
 installPluginsWizard.list.title=Liste over installerbare tilf\u00f8jelser
 installPluginsWizard.list.loading=Vent mens tilf\u00f8jelsen indl\u00e6ses.
@@ -1350,10 +1333,10 @@ installPluginsWizard.list.name=Navn :
 installPluginsWizard.list.version=Version :
 installPluginsWizard.list.description=Beskrivelse af tilf\u00f8jelse
 installPluginsWizard.finish.title=Installationen k\u00f8rer
-installPluginsWizard.finish.explanation=Den valgte tilf\u00f8jelse bliver installeret med opdaterings assistenten.\n\nV\u00e6r t\u00e5lmodig, da kan tage et stykke tid f\u00f8r assistenten vises.\n\nDobbelt klik til venstre p\u00e5 statusbj\u00e6lken for at se en detaljeret raport.
+installPluginsWizard.finish.explanation=Den valgte tilf\u00f8jelse bliver installeret vha. opdateringsassistenten.\n\nV\u00e6r t\u00e5lmodig, da kan tage et stykke tid f\u00f8r assistenten vises.\n\nDobbeltklik til venstre p\u00e5 statuslinjen for at f\u00e5 vist en detaljeret statusrapport.
 installPluginsWizard.details.loading=Indl\u00e6ser detaljer, vent...
 installPluginsWizard.mode.file=Fra Fil :
-installPluginsWizard.installMode.title=V\u00e6lg installations typen
+installPluginsWizard.installMode.title=V\u00e6lg installationstype
 installPluginsWizard.installMode.user=Installer denne tilf\u00f8jelse kun til dig
 installPluginsWizard.installMode.shared=Installer denne tilf\u00f8jelse til alle brugere
 installPluginsWizard.file.title=S\u00f8g efter den tilf\u00f8jelse du vil installere
@@ -1366,14 +1349,14 @@ uninstallPluginsWizard.list.loaded=V\u00e6lg den tilf\u00f8jelse du \u00f8nsker
 installPluginsWizard.list.nullversion=Ingen Version
 uninstallPluginsWizard.finish.title=Forl\u00f8b af afinstallationen
 uninstallPluginsWizard.finish.explanation=Den udvalgte tilf\u00f8jelse vil blive afinstalleret med opdaterings Assistenten
-MainWindow.menu.plugins.installPlugins=Installations Guiden...
-MainWindow.menu.plugins.uninstallPlugins=Afinstallations Guiden...
+MainWindow.menu.plugins.installPlugins=Installationsguide...
+MainWindow.menu.plugins.uninstallPlugins=Afinstallationsguide...
 ConfigView.section.ipfilter.totalIPs=%1 IP'er blokeret ialt, hvilket er %2 af internettet.
 update.instance.install=Kontrolerer installationen
 update.instance.uninstall=Kontrolerer afinstallationen
 update.instance.update=S\u00f8ger efter opdateringer
 MainWindow.status.update.tooltip=Dobbelt klik for at se status information
-updater.progress.window.title=Aktuelle installations opgaver
+updater.progress.window.title=Aktuelle installationsopgaver
 updater.progress.window.info=Klik p\u00e5 "Afbryd" for at afbryde alle udest\u00e5ende opgaver
 Button.abort=Afbryd
 ConfigView.section.ipfilter.enablebanning=Bloker peers som gentagende gange sender d\u00e5rlig data
@@ -1383,8 +1366,6 @@ UpdateWindow.restartLater=Genstart Vuze senere
 MainWindow.menu.file.restart=Genstart Vuze
 MainWindow.dialog.restartconfirmation.title=Genstart Vuze
 MainWindow.dialog.restartconfirmation.text=Vil du virkelig genstarte Vuze
-deletetorrent.message1=Du er ved at sl\u00e6tte TORRENTEN til :\n
-deletetorrent.message2=\nEr du sikker p\u00e5 du vil det?
 ConfigView.label.prioritizemostcompletedfiles=Prioritere mest f\u00e6rdige filer
 splash.plugin.init=Initialiserer tilf\u00f8jelse : 
 ConfigView.section.style.osx_small_fonts=Brug sm\u00e5 skrifttyper (Genstart kr\u00e6vet)
@@ -1459,12 +1440,12 @@ ConfigView.section.file.nativedelete._windows=Flyt slettede filer til papirkurve
 ConfigView.section.logging.generatediagnostics=Opret
 ConfigView.section.logging.generatediagnostics.info=Opret diagnose informationer og kopier til udklipsholderen og log filen, hvis dette er konfigureret
 ConfigView.section.sharing.privatetorrent=Privat torrent - accepter kun peers fra trackeren
-MainWindow.menu.tools.nattest=&NAT / Firewall Tester
-Button.apply=Tilf\u00f8j
+MainWindow.menu.tools.nattest=&NAT / Firewall-test...
+Button.apply=Anvend
 Button.close=Luk
 window.welcome.title=Velkommen til Vuze %1
 #file can be a URL or a path in the jar
-MainWindow.menu.help.releasenotes=Udgivelsesnotater
+MainWindow.menu.help.releasenotes=Udgivelsesnoter
 dht.reseed.group=Seed igen
 dht.reseed.ip=IP adrasse
 dht.reseed.port=Port :
@@ -1541,25 +1522,25 @@ TableColumn.header.comment.info=En brugerdefineret kommentar til downloaden
 TableColumn.header.commenticon=Kommentar Ikon 
 TableColumn.header.commenticon.info=Vis ikonet hvis downloaden har en brugerdefineret kommentar
 MyTrackerView.category=Katagori
-MainWindow.menu.file.open.torrentfortracking=Torrent Fil...(Kun til tracking)
+MainWindow.menu.file.open.torrentfortracking=Torrent-fil...(kun til tracking)
 VivaldiView.title.full=Picasso
 MyTrackerView.date_added=Tilf\u00f8jet
 ConfigView.section.tracker.portbackup=Reserve porte (';' separerede)
 ConfigView.label.playfilespeech="Tal" n\u00e5r en fil er f\u00e6rdig
-ConfigView.label.playfilespeech.info=Tale servisen virker i \u00f8jeblikket bedst med engelsk
 ConfigView.label.playfilefinished=Afspil en lyd n\u00e5r en fil er f\u00e6rdig
 ConfigView.label.backupconfigfiles=Lav backup af konfigurations filerne til evt gendannelses form\u00e5l
 ConfigView.section.tracker.client.scrapesingleonly=Deaktiver Pr. tracker opdateringer (Dette kan afhj\u00e6lpe trackere som reporterer om "URL too long" (414) fejl)
 dht.ipfilter.log=Log brud p\u00e5 IP Filter
 ConfigView.label.seeding.addForSeedingDLCopyCount="tilf\u00f8j til seeding" downloads betragtes som at have downloaded dette antal kopier
-ActivityView.legend.limit=Begr\u00e6nsning af Hastighed
-ActivityView.legend.achieved=Opn\u00e5et Hastighed
+ActivityView.legend.limit=Hastighedsgr\u00e6nse
+ActivityView.legend.achieved=Hastighed opn\u00e5et
+ActivityView.legend.overhead=Hastighedsloft
 ActivityView.legend.peeraverage=Gennemsnit
-ActivityView.legend.swarmaverage=Sv\u00e6rmens Gennemsnit
+ActivityView.legend.swarmaverage=Sv\u00e6rmgennemsnit
 ActivityView.legend.trimmed=Trimmet
 MyTorrentsView.menu.movemenu=Flyt Filer
 MyTorrentsView.menu.movedata=Flyt Data Filer...
-MyTorrentsView.menu.movetorrent=Flyt Torrent fil...
+MyTorrentsView.menu.movetorrent=Flyt torrent-fil...
 MyTorrentsView.menu.movedata.dialog=V\u00e6lg ny placering
 DHTView.operations.data=Data :
 DHTView.general.reachable=Tilg\u00e6ngelig :
@@ -1704,9 +1685,9 @@ OpenTorrentWindow.mb.alreadyExists.title=Torrenten eksisterer allerede
 OpenTorrentWindow.mb.openError.title=Fejl ved \u00e5bning
 OpenTorrentWindow.mb.openError.text="%1" kunne ikke \u00e5bnes :\t\n%2
 OpenTorrentWindow.torrent.remove=Fjern Torrenten fra listen
-OpenTorrentWindow.torrent.options=F\u00f8lgende instillinger vil v\u00e6re g\u00e6ldende for ovenst\u00e5ende valgte Torrents :
+OpenTorrentWindow.torrent.options=F\u00f8lgende indstillinger omfatter ovenst\u00e5ende valgte torrents:
 OpenTorrentWindow.xOfTotal=(%1 af %2)
-iconBar.open.tooltip=\u00c5ben Torrent(s)
+iconBar.open.tooltip=\u00c5bn Torrent(s)
 LocaleUtil.column.text=Ukendt tekst
 Tracker.tooltip.MultiSupport=Denne tracker underst\u00f8tter flere hash opdateringer Pr. anmodning.
 Tracker.tooltip.NoMultiSupport=Denne tracker underst\u00f8tter IKKE flere hash opdateringer Pr. anmodning.\nDette vil ikke p\u00e5virke din ydeevne men l\u00e6gger en ekstra belastning p\u00e5 trackeren.
@@ -1718,7 +1699,7 @@ ConfigView.section.file.writemblimit.explain=N\u00e5r diskens skrive hastighed e
 ConfigView.section.file.readmblimit=Maksimum l\u00e6se-anmodninger i k\u00f8 (i %1)
 ConfigView.section.file.readmblimit.explain=Denne instilling begr\u00e6nser hvor meget hukommelse som bliver brugt til at lagre l\u00e6sninger som venter p\u00e5 beabejdelse.
 Button.moveUp=Flyt &op
-Button.moveDown=Flyt &Ned
+Button.moveDown=Flyt &ned
 ConfigView.notAvailableForMode=Denne sektion er beregnet til %1 tilstand eller h\u00f8jere.  Den er ikke til r\u00e5dighed i %2 tilstand.
 health.explain.error=Der er opst\u00e5et en fejl med denne torrent. Se i statuskolonnen, eller i v\u00e6rkt\u00f8jstippet p\u00e5 fejlikonet.
 GeneralView.label.trackerscrapeupdate=Opdater tracker
@@ -1756,9 +1737,9 @@ MainWindow.sr.status.tooltip.poor=Delingsforhold %1 mangelfuldt : < 0.9
 MainWindow.sr.status.tooltip.bad=Delingsforhold %1 elendigt : < 0.5
 ConfigView.section.style.status=Status Omr\u00e5de :
 ConfigView.section.style.status.show_sr=Delingsforhold
-ConfigView.section.style.status.show_nat=NAT status
-ConfigView.section.style.status.show_ddb=DDb Status
-ConfigView.section.style.status.show_ipf=IP-Filter Status
+ConfigView.section.style.status.show_nat=NAT-status
+ConfigView.section.style.status.show_ddb=DDb-status
+ConfigView.section.style.status.show_ipf=IP-filterstatus
 ConfigView.section.connection.encryption.encrypt.group=Overf\u00f8rsels kryptering
 ConfigView.section.connection.encryption.encrypt.fallback_info=Aktivering af begge "fallback" muligheder vil tillade forbindelser med ikke-kompatible klienter MEN dette vil resultere i ikke-krypterede forbindelser
 ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Tillad ikke-krypterede udg\u00e5ende forbindelser hvis fors\u00f8g p\u00e5 at oprette en krypteret forbindelse mislykkedes
@@ -1772,7 +1753,7 @@ ConfigView.section.style.defaultSortOrder.flip=Modsat den forrige ordre
 LoggerView.autoscroll=Auto rul i logfilen
 Button.selectAll=V\u00e6lg alt
 Button.markSelected=Marker valgte
-Button.unmarkSelected=Fjern markeringen af valgte
+Button.unmarkSelected=Fjern markering af valgte
 plugins.basicview.config=Konfig
 TorrentOptionsView.param.max.uploads=Det maximale antal upload porte (Dog mindst 2)
 MyTorrentsView.dialog.setPosition.title=Angiv Position
@@ -1788,8 +1769,8 @@ Pieces.column.Requested=Anmodet :
 Pieces.column.Requested.info=Hvis der kan eller ikke kan foretages flere foresp\u00f8rgelser p\u00e5 stykket s\u00e5 vis det (*)
 ConfigView.label.maxuploadsseeding=Alternativ standart n\u00e5r der seedes
 popup.error.hideall=Skjul Alle
-ConfigView.section.style.dataStatsOnly=Vis kun data statistikker (skjul protokol statistikker)
-ConfigView.section.style.separateProtDataStats=Vis adskilte data og protokol statistikker som "data (protokol)"
+ConfigView.section.style.dataStatsOnly=Vis kun datastatistik (skjul protokolstatistik)
+ConfigView.section.style.separateProtDataStats=Vis data- og protokolstatistik separat som "data (protokol)"
 MyTorrentsView.dialog.setFilter.title=Modificer filter
 MyTorrentsView.dialog.setFilter.text=%1 sektionen bliver filtreret if\u00f8lge teksten du speciferer herunder. Brug | (pipe) symbolet til at filtrere ord med flere mulige stavelser p\u00e5. 
 MyTorrentsView.filter.tooltip=Brug Ctrl+X for at skifte mellem RegEx og normal s\u00f8gemetode.\nBrug | (pipe) symbolet til at filtrere ord med flere mulige stavelser p\u00e5.
@@ -1808,7 +1789,7 @@ ConfigView.auto=Automatisk
 Plugin.localtracker.autoadd.info=Tilf\u00f8j automatisk disse lokale peers (";" sepererede adresser, f.eks. 1.2.3.4)
 Plugin.localtracker.networks.info=Betragt f\u00f8lgende netv\u00e6rk som lokale (";" separerede netv\u00e6rk, f.eks. 145.227.*.*)
 Plugin.localtracker.networks=Lokal netv\u00e6rk
-MainWindow.menu.view.plugins.logViews=Vis Loggen
+MainWindow.menu.view.plugins.logViews=Vis log
 SpeedView.stats.autospeed=Automatisk Upload Hastighed
 SpeedView.stats.autospeed.disabled=Denne mulighed er enten deaktiveret (du skal bruge DHT) eller ikke i brug (Brugerdefineret upload hastighed er valgt)
 SpeedView.stats.maxPing=Maksimal Ping :
@@ -1855,7 +1836,7 @@ DHTTransport.report.sending=sender data
 DHTTransport.report.resending=sender data igen
 DHTTransport.report.send_complete=send hele
 DHTTransport.report.send_timeout=send Timeout
-ConfigView.section.transfer.autospeed.enabledebug=Log "debug" informationen
+ConfigView.section.transfer.autospeed.enabledebug=Gem fejlrapport
 TableColumn.header.date_added=Tilf\u00f8jelses dato 
 TableColumn.header.date_added.info=Datoen for Torrentens tilf\u00f8jelse
 ConfigView.section.file.hashchecking.smallestfirst=Tjek de mindste downloads f\u00f8rst
@@ -1893,7 +1874,7 @@ ConfigView.label.udplistenport=UDP aflytnings port
 upnp.portchange.alert=F\u00f8lgende porte er blevet \u00e6ndret for at afv\u00e6rge problemer med UPnP enheden : %1 (old port = %2) %3 (old port = %4)
 ConfigView.section.proxy.username.info=Hvis proxy serveren kr\u00e6ver bekr\u00e6ftigelse af identitet, selvom ingen er defineret, s\u00e5 brug strengen <none> som brugernavn(e)
 ConfigView.label.maxuploadswhenbusymin=Maksimum upload hastighed, Pr. Torrent n\u00e5r timeren er optaget (sekunder)
-MainWindow.menu.help.debug=Opret "debug" information
+MainWindow.menu.help.debug=Generer fejlrapport (crash log)
 DownloadManager.error.badsize=Ukorrekt st\u00f8rrelse
 ConfigView.section.NATPMP=NAT - PMP
 natpmp.info=NAT-PMP er Apple's alternativ til UPnP som underst\u00f8ttes i alle nyere lufthavns      terminaler\n\nBEM\u00c6RK at p\u00e5 nuv\u00e6rende tidspunkt skal UPnP'en v\u00e6re aktiveret for at du kan aktivere NAT-PMP da NAT-PMP enhedder bliver anset som en special type UPnP enhed
@@ -1942,48 +1923,38 @@ MyTorrentsView.menu.rename.displayed.enter.message=Skriv et nyt navn som skal vi
 MyTorrentsView.menu.edit_comment=Rediger/Tilf\u00f8j en kommentar
 MyTorrentsView.menu.edit_comment.enter.title=Rediger/Tilf\u00f8j en kommentar
 MyTorrentsView.menu.edit_comment.enter.message=Skriv en kommentar til denne download.
-UIDebugGenerator.messageask.title="Debug" Opretter
-UIDebugGenerator.complete.title="Debug" oprettelse f\u00e6rdig
-UIDebugGenerator.complete.text=Send filen "%1".\n\nklik Ok for at \u00e5bne et vindue til denne fil.
+UIDebugGenerator.messageask.title=Fejlrapportgenerator
+UIDebugGenerator.complete.title=Oprettelse af fejlrapport udf\u00f8rt
+UIDebugGenerator.complete.text=Fejlrapportfilen findes under "%1".\n\nKlik p\u00e5 OK for at \u00e5bne et filsystemvindue til denne fil.
 ConfigView.section.style.showProgramIcon=Vis program ikonet i navne kolonnen
 ConfigView.section.style.showProgramIcon.tooltip=Det kan v\u00e6re n\u00f8dvendigt at skulle gen\u00e5bne for at \u00e6ndringerne vil tr\u00e6de i kraft
 swt.alert.cant.update=SWT biblioteket som er inl\u00e6st fra "%3" kan ikke opdateres automatisk fra version %1 til %2 (Skal indl\u00e6ses fra "%4"). For flere detaljer se\n<A HREF = "http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">the wiki</A>
 authenticator.savepassword=Husk mit kodeord
 ConfigView.section.security.clearpasswords=Nulstil huskede kodeord
 ConfigView.section.security.clearpasswords.button=Nulstil
-Content.alert.notuploaded.title=Uploaden er ikke fuldendt
-Content.alert.notuploaded.text=Upload af "%1" er ikke komplet. Hvis du %2 nu, vil folk ikke v\u00e6re i stand til at downloade din upload.\n\nEr du sikker p\u00e5 du vil %2?
-Content.alert.notuploaded.multi.title=Uploaden er ikke komplet
-Content.alert.notuploaded.multi.text=%1 af dit uploadet indhold er ikke seedet f\u00e6rdigt. Hvis du %2 nu, vil folk ikke kunne f\u00e5 en komplet download af det du har uploadet. Er du helt sikker p\u00e5 at du vil %2???\n\nIndholdet i uploaden er ikke f\u00e6rdig seedet :\n%3
-Content.alert.notuploaded.stop=Stop
-Content.alert.notuploaded.quit=Afslut Vuze
 TorrentInfoView.torrent.encoding=Torrent kryptering 
 TorrentInfoView.columns=Kolonner fra "Mine Torrents"
 progress.window.title=Aktuelle handling
 progress.window.msg.filemove=Vent mens flytningen/omd\u00f8bningen af filen f\u00e6rdigg\u00f8res
 ConfigView.label.popup.timestamp=Tilf\u00f8j tidsstempler p\u00e5 popup alarmer
 ConfigView.label.popup.autohide=Skjul automatisk "ingen-fejl" popup alarmer efter x sekunder (0 deaktiverer auto skjul)
-ConfigView.label.popup.suppress_alerts=Undertryk alarmer
-ConfigView.label.popup.use_message_boxes=Brug popup besked bokse istedet for standart popup alarm boksen.
-ConfigView.label.popup.show=Vis alle loggede popup alarmer indtil nu (hvis der er nogen)
-ConfigView.label.popup.show.button=Vis
 ConfigView.label.please.visit.here=Bes\u00f8g her for flere detaljer
 ConfigView.section.ipfilter.enable.descriptionCache=Gem IP beskrivelser i "scratch" filen
 ConfigView.section.ipfilter.enable.descriptionCache.tooltip=N\u00e5r funktionen er deaktiveret, vil beskrivelser ikke blive husket
 OpenTorrentWindow.filesInfo=%1 af %2 vil blive downloadet.
-ConfigView.label.openmytorrents=\u00c5ben Fanen "Mine Torrents" n\u00e5r Vuze startes
+ConfigView.label.openmytorrents=\u00c5bn fanen "Mine Torrents" n\u00e5r Vuze startes
 ConfigView.section.style.DNDalwaysInIncomplete=Vis altid Torrents med "Download ikke" i Mine Torrents under sektionen Uf\u00e6rdige
 OpenTorrentWindow.mb.noGlobalDestDir.title=Destinations mappen blev ikke fundet
 OpenTorrentWindow.mb.noGlobalDestDir.text=Destinations mappen "%1" eksisterer ikke eller er ugyldig.
 OpenTorrentWindow.mb.noDestDir.title=Destinations mappen blev ikke fundet
 OpenTorrentWindow.mb.noDestDir.text=Destinations mappen "%1" til Torrenten "%2" eksisterer ikke eller er ugyldig.
-OpenTorrentWindow.mb.notValid.title=\u00c5ben Torrent
+OpenTorrentWindow.mb.notValid.title=\u00c5bn torrent fejlet
 OpenTorrentWindow.mb.notValid.text=Kunne ikke \u00e5bne Torrenten "%1". Hvis du \u00e5bner i seeding tilstand skal du sikre dig at Torrentens datafiler findes.
-OpenTorrentWindow.mb.notTorrent.title=\u00c5ben Torrent
+OpenTorrentWindow.mb.notTorrent.title=\u00c5bn torrent fejlet
 OpenTorrentWindow.mb.notTorrent.text="%1" kunne ikke \u00e5bnes. Tilsyneladende er det ikke en Torrent fil.\n\nNoget af dataen blev modtaget :\n%2
 ConfigView.label.pause.downloads.on.exit=S\u00e6t downloads p\u00e5 pause n\u00e5r der afsluttes 
 ConfigView.label.resume.downloads.on.start=Genoptag pausede downloads efter initialitionen er f\u00e6rdig
-UIDebugGenerator.message.cancel.title=Oprettelse af "debug" informationen blev afbrudt
+UIDebugGenerator.message.cancel.title=Oprettelse af fejlrapport afbrudt
 ConfigView.section.connection.group.http=HTTP.
 ConfigView.section.connection.group.http.info=Support til HTTP seeding.
 ConfigView.section.connection.http.enable=Aktiver
@@ -2005,9 +1976,9 @@ TransferStatsView.legend.pingaverage=Gennemsnit
 TransferStatsView.legend.ping1=Ping m\u00e5l 1
 TransferStatsView.legend.ping2=Ping m\u00e5l 2
 TransferStatsView.legend.ping3=Ping m\u00e5l 3
-ConfigView.section.interface.enabletray._mac=Aktiver Status Linie Ikonet (kr\u00e6ver genstart)
-ConfigView.label.closetotray._mac=Luk minimerer til Statuslinie Icon
-ConfigView.label.minimizetotray._mac=Minimer "Minimerer" til Status menu Ikonet
+ConfigView.section.interface.enabletray._mac=Aktiver statuslinjeikonet [kr\u00e6ver genstart]
+ConfigView.label.closetotray._mac=Luk minimerer til statuslinjeikon
+ConfigView.label.minimizetotray._mac="Minimer" minimerer til statuslinjeikon
 OpenTorrentWindow.mb.existingFiles.title=Filen eller filerne findes allerede!
 OpenTorrentWindow.mb.existingFiles.text=Nogle af filerne findes allerede i den valgte destinations mappe :\n\n%1\nHvis du forts\u00e6tter vil Vuze tjekke ovenst\u00e5ende fil(er) for korrekt data og om n\u00f8dvendigt overskrive filen/filerne.
 splash.unloadingTorrents=Standser Torrents
@@ -2035,10 +2006,78 @@ Peers.column.peer_byte_id=Peers ID
 Peers.column.peer_byte_id.info=Peers ID in byte form
 ConfigView.label.openbar.incomplete=Download bj\u00e6lke: auto \u00e5ben downloads
 ConfigView.label.openbar.complete=auto \u00e5ben seeds
+MainWindow.menu.tools.speedtest=Hastighedstest...
+speedtest.wizard.title=Hastighedstest
 # Used for peers which we can't determine.
 PeerSocket.unknown=Ukendt
+ConfigTransferAutoSpeed.add.comment.to.log.group=Tilf\u00f8j kommentar til fejlrapport
 ConfigView.label.announceport=Underkend tracker annoncerings port
+button.columnsetup.tooltip=Kolonneops\u00e6tning
+MainWindow.menu.window.zoom.maximize=Maksimer
+Button.retry=&Fors\u00f8g igen
+Button.ignore=&Ignorer
+Button.bar.show=Vis
+Button.bar.hide=Skjul
+Button.bar.share=Del
+Button.bar.add=Tilf\u00f8j
+Button.bar.edit=Rediger
+Button.bar.edit.cancel=Afslut redigering
+MainWindow.menu.file.open.vuze=Vuze-fil...
 iconBar.queue.tooltip=S\u00e6t i k\u00f8
-MainWindow.menu.help.faq=&Ofte stillede sp\u00f8rgsm\u00e5l (FAQ)
+v3.MainWindow.menu.view.sidebar=Sidepanel
+v3.MainWindow.menu.view.toolbars=V\u00e6rkt\u00f8jslinjer
+MainWindow.menu.help.support=&Hj\u00e6lp og support
+Button.done=F\u00e6rdig
+Button.continue=Forts\u00e6t
+Button.preview=Forh\u00e5ndsvisning
+Button.remove=Fjern
+Button.send=Afsend
+Button.back=Tilbage
+Button.search=S\u00f8g
+Button.save=Gem
+Button.add=Tilf\u00f8j
+Button.createNewSubscription=Opret nyt abonnement
+Button.availableSubscriptions=Tilg\u00e6ngelige abonnementer
+Button.deleteContent.fromLibrary=Fjern fra bibliotek
+Button.deleteContent.fromComputer=Slet fra computer
+v3.MainWindow.menu.view.toolbartext=Tekst p\u00e5 v\u00e6rkt\u00f8jslinjen
+v3.MainWindow.menu.view.statusbar=Statuslinje
+ConfigView.label.systray._mac=Statuslinjeikon
+MainWindow.menu.help.donate=&Giv et bidrag
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+# This is the end of the word "View".  It's left aligned under the icon bar item
+Button.turnon=Aktiver
+Button.reload=Genindl\u00e6s
+button.nothanks=Nej tak
+Button.removeAll=Fjern alle
+ClientStats.title.full=Klientstatistik
+Button.dismiss=Afvis
+Button.validate=Valider
+Button.getstarted=Kom godt i gang
+Button.goLibrary=Skift til {library.name}
+menu.register=Vuze Plus-aktivering
+Button.agree=Accepter
+auto.mode=Auto (anbefales)
+#connected to more seeds/peers than tracker reports
+Button.sendNow=Afsend nu
+Button.sendManual=Manuel afsend (opret .zip)
+configureWizard.nat.title=NAT / Server port
+# Will be used for {library.name} in classic view
+# Will be used for {library.name} in VuzeUI view
+Button.upgrade=Opgrader
+Button.renew=Forny
+# The remaining keys were not in MessagesBundle.properties
+Content.alert.notuploaded.text=Upload af "%1" er ikke komplet. Hvis du %2 nu, vil folk ikke v\u00e6re i stand til at downloade din upload.\n\nEr du sikker p\u00e5 du vil %2?
 MainWindow.menu.help.faq.keybinding.mac=Meta+? 
-MainWindow.menu.help.donate=&Giv et bidrag!!!
+ConfigView.label.popup.suppress_alerts=Undertryk alarmer
+ConfigView.label.popup.use_message_boxes=Brug popup besked bokse istedet for standart popup alarm boksen.
+MyTorrentsView.menu.removeand=F&jern og
+Content.alert.notuploaded.multi.text=%1 af dit uploadet indhold er ikke seedet f\u00e6rdigt. Hvis du %2 nu, vil folk ikke kunne f\u00e5 en komplet download af det du har uploadet. Er du helt sikker p\u00e5 at du vil %2???\n\nIndholdet i uploaden er ikke f\u00e6rdig seedet :\n%3
+Content.alert.notuploaded.title=Uploaden er ikke fuldendt
+webui.restart.info=\u00c6ndring af parametre markeret med (*) tr\u00e6der f\u00f8rst i kraft efter en genstart.
+Content.alert.notuploaded.quit=Afslut Vuze
+Content.alert.notuploaded.stop=Stop
+ConfigView.label.popup.show.button=Vis
+MainWindow.menu.help.faq=&Ofte stillede sp\u00f8rgsm\u00e5l (FAQ)
+ConfigView.label.popup.show=Vis alle loggede popup alarmer indtil nu (hvis der er nogen)
+Content.alert.notuploaded.multi.title=Uploaden er ikke komplet
diff --git a/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties b/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
index dd577a0..744966a 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_de_DE.properties
@@ -35,11 +35,8 @@ MainWindow.menu.window.alltofront=Alle in den &Vordergrund bringen
 MainWindow.menu.help=&Hilfe
 MainWindow.menu.help.about=\u00dcber Vu&ze
 MainWindow.about.title=\u00dcber 
-MainWindow.about.section.developers=Entwickler
-MainWindow.about.section.translators=\u00dcbersetzer
 MainWindow.about.internet.homepage=Vuze-Homepage
 MainWindow.about.internet.sourceforge=Sourceforge-Projekt-Homepage
-MainWindow.about.internet.sourceforgedownloads=Sourceforge-Downloads
 MainWindow.about.internet.bugreports=Bug-Reporte
 MainWindow.about.internet.forumdiscussion=Foren
 MainWindow.about.internet.wiki=
@@ -99,6 +96,7 @@ PeersView.C1.info=Zeigt an, ob die Quelle den Download unterbindet
 PeersView.pieces=Teile
 PeersView.downloadspeed=DL-Geschw.
 PeersView.download=Herunter
+PeersView.download.info=Der gesamte Download von diesem Peer.
 PeersView.I2=I (Quelle ist interessiert)
 PeersView.I2.info=Zeigt an, ob die Quelle Interesse an den bereitgestellten Daten hat
 PeersView.C2=C (Quelle unterdr\u00fccken)
@@ -302,8 +300,6 @@ IrcView.errormsg=Falsche Syntax von /msg: /msg <Benutzer> <Text>
 IrcView.help=Erlaubte Befehle sind:\n . /help : zeigt diese Nachricht\n . /nick | /name : \u00e4ndert den Nick \n . /me action : sendet eine Aktion \n . /msg Benutzer Nachricht : sendet eine private Nachricht an <Benutzer>\n . /r <Nachricht>: antworten auf letzte private Nachricht\n . /join #kanal : Kanal betreten 
 PasswordWindow.title=Vuze ist gesperrt
 PasswordWindow.passwordprotected=Vuze ist passwortgesch\u00fctzt.\nF\u00fcr die Anzeige des Fensters bitte hier das Passwort eingeben:
-TrackerChangerWindow.title=Tracker hinzuf\u00fcgen
-TrackerChangerWindow.newtracker=Neue Tracker-URL eingeben
 PeersView.discarded=Verworfen
 PeersView.discarded.info=Daten, die empfangen wurden, ohne ben\u00f6tigt zu werden und daher gel\u00f6scht wurden. 
 discarded=verworfen
@@ -369,12 +365,8 @@ ConfigView.label.showpopuponclose=Zeige Best\u00e4tigungsfenster, wenn das Verte
 ConfigView.label.startNumSeeds=\nStarte Verteilen, falls es weniger vollst\u00e4ndige Quellen gibt als\n - \u00fcberschreibt alle anderen Regeln 
 ConfigView.label.seeds=vollst\u00e4ndigen Quellen
 ConfigView.section.seeding=Verteilen
-MyTorrentsView.menu.removeand=Entferne und
-MyTorrentsView.menu.removeand.deletetorrent=L\u00f6sche Torrent
-MyTorrentsView.menu.removeand.deletedata=L\u00f6sche Daten
-MyTorrentsView.menu.removeand.deleteboth=L\u00f6sche beides
 deletedata.title=L\u00f6sche Inhalt
-deletedata.message1=Sicher, dass '%1' gel\u00f6scht werden soll?
+# used for more than just "delete data"
 deletedata.noprompt=Nicht nochmal nachfragen
 MainWindow.menu.file.configure=Konfigurations&assistent...
 configureWizard.title=Konfigurationsassistent
@@ -397,7 +389,6 @@ configureWizard.transfer.maxActiveTorrents=max. aktive Torrents
 configureWizard.transfer.maxDownloads=max. Downloads
 configureWizard.transfer.maxUploadsPerTorrent=max. Uploads pro Torrent
 configureWizard.nat.title=NAT- / Server-Port
-configureWizard.nat.message=Um das Beste aus Vuze herauszuholen, wird empfohlen, vollst\u00e4ndig aus dem Internet erreichbar zu sein. Dieses Tool testet und/oder \u00e4ndert den Port f\u00fcr eingehende Verbindungen. \nHinweise:\n1) Es werden nur TCP-Verbindungen getestet. Die verteilte Datenbank erfordert zus\u00e4tzlich einen UDP-Port, ist er geschlossen, wird dies separat angezeigt.\n2) Der TCP-Port 6880 ist f\u00fcr interne Vorg\u00e4nge reserviert und kann nicht benutzt werden.
 configureWizard.nat.test=Testen
 configureWizard.nat.testing=Teste Port
 configureWizard.nat.ok=OK!
@@ -553,7 +544,6 @@ ConfigView.section.file.decoder.nodecoder=Keine
 IPChecker.external.service.no-ip.description=Dynamischer und statischer DNS Dienst Anbieter\n(kein kostenloser Adresspr\u00fcfdienst)
 ConfigView.section.tracker.publicenable=Erlaube externe Torrents
 ConfigView.label.playdownloadspeech=Sprachausgabe, wenn ein Torrent fertig ist
-ConfigView.label.playdownloadspeech.info=Die Sprachausgabe funktioniert im Moment am besten auf Englisch
 #
 # Tooltips
 #
@@ -724,8 +714,6 @@ plugin.sharing.download.remove.veto=Dieser Download ist dadurch entstanden, da e
 ConfigView.section.tracker.main=Haupt
 ConfigView.label.prioritizefirstpiece=Priorisiere erstes und letztes Teil von Datei(en)
 ConfigView.label.prioritizefirstpiece.tooltip=Versucht den Anfang und das Ende von Dateien zuerst herunterzuladen, um eine fr\u00fchzeitige Vorschau der Daten zu erlauben.
-ConfigView.section.file.confirm_data_delete=L\u00f6schen von Daten best\u00e4tigen
-ConfigView.section.file.confirm_data_delete.tooltip=L\u00f6schen von Daten bei Benutzung von 'Entfernen und L\u00f6schen...' best\u00e4tigen 
 ConfigView.section.file.delete.include_files_outside_save_dir=Beim L\u00f6schen von Daten, erlaube auch das L\u00f6schen von Dateien, die ausserhalb des Speicherverzeichnisses verlinkt sind
 TrayWindow.menu.startalldownloads=Starte alle Downloads
 SystemTray.menu.startalltransfers=Starte alle \u00dcbertragungen
@@ -1031,7 +1019,6 @@ ConfigView.pluginlist.whereToPutOr=Plugins f\u00fcr alle Benutzer werden install
 MainWindow.statusText.checking=\u00dcberpr\u00fcfe auf Updates
 TableColumn.header.OnlyCDing4=Nur verteilen seit
 TableColumn.header.OnlyCDing4.info=Zeit, seit der Daten nur noch verteilt werden (ohne Dauer des Downloads)
-ConfigView.section.style.alternateTablePainting=Benutze alternative Methode zum Zeichnen von Tabellenspalten (m\u00f6glicherweise Neustart ben\u00f6tigt)
 UpdateWindow.status.restartMaybeNeeded=Neustart k\u00f6nnte ben\u00f6tigt werden
 ConfigView.pluginlist.shared=F\u00fcr alle Benutzer
 PeersView.host=Hostname
@@ -1081,7 +1068,6 @@ webui.access.info=Zugriff kann folgender sein\n\t"local"\t= nur der lokale Rechn
 GeneralView.label.maxdownloadspeed=Down-Limit
 Security.keystore.corrupt=Laden des Schl\u00fcsselspeichers '%1' fehlgeschlagen. Bitte l\u00f6sche ihn und erstellen/importieren die Zertifikate neu 
 Security.keystore.empty=Schl\u00fcsselspeicher ist leer. Erzeuge bitte ein selbstsigniertes Zertifikat (Konfiguration->Sicherheit) oder importiere ein bereits vorhandenes nach '%1'
-webui.restart.info=\u00c4nderungen von Parametern die mit (*) markiert sind, ben\u00f6tigen einen Neustart, um sie zu aktivieren.
 GeneralView.label.maxdownloadspeed.tooltip=max. Download-Geschwindigkeit [0: unbegrenzt]
 upnp.enable=UPnP aktivieren
 upnp.info=Universelles Plug and Play (UPnP) erlaubt die automatische Zuweisung von Ports, wenn der Router UPnP unterst\u00fctzt.
@@ -1147,8 +1133,6 @@ MyTrackerView.badnat.info=Quellen, bei denen ein NAT-Check fehlgeschlagen ist, w
 ConfigView.section.tracker.natchecktimeout=Zeit\u00fcberschreitung der \u00dcberpr\u00fcfung (in s)
 ConfigView.section.file.perf.cache.enable=Disk-Cache aktivieren
 ConfigView.section.file.perf.cache.size=Cachegr\u00f6\u00dfe in %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=\u00dcbe&rtragungen
 MainWindow.menu.transfers.startalltransfers=Alle st&arten
 MainWindow.menu.transfers.stopalltransfers=Alle st&oppen
@@ -1263,18 +1247,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF Gr\u00f6\u00df
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Sets the standard socket SO_SNDBUF value (in bytes), i.e. the TCP send window size.\nVuze leaves this unset by default, meaning the defaults for the underlying OS are used.\nNOTE: Linux doubles the given value. 
 ConfigView.section.connection.advanced.IPDiffServ=DiffServ-Wert ausgehender Pakete (TOS-Feld)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Setzt den DiffServ-Teil des Type-Of-Service (TOS) Feldes im IP-Header f\u00fcr ausgehende Pakete.\nHexadezimale Werte k\u00f6nnen mit dem Pr\u00e4fix '0x' eingegeben werden.\nVuze nutzt standardm\u00e4ssig die Einstellungen des Betriebssystems.\nACHTUNG: Die unterliegende Netzwerkimplementation kann diese Werte ignorieren, die Einstellung ist sehr stark abh\u00e4ngig vom benutzten Betriebssystem und der JAVA-Version.
-ConfigView.section.interface.confirm_torrent_removal=Zeige Best\u00e4tigungsdialog beim Entfernen eines Torrents
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Verlangt eine Best\u00e4tigung beim Entfernen von Torrents aus 'Meine Torrents'.
-MyTorrentsView.confirm_torrent_removal=Soll der Torrent wirklich entfernt werden?\n
 TableColumn.header.seed_to_peer_ratio=Verh\u00e4ltnis vQ/uvQ
 TableColumn.header.seed_to_peer_ratio.info=Verh\u00e4ltnis der vollst\u00e4ndigen zu unvollst\u00e4ndigen Quellen des gesamten Schwarmes
 PeersView.connected_time=Verbunden seit
 PeersView.connected_time.info=Gesamtzeit verbunden mit unvollst\u00e4ndiger Quelle
-ConfigView.section.interface.display.add_torrents_silently=F\u00fcge Torrents unbemerkt hinzu
-ConfigView.section.interface.display.add_torrents_silently.tooltip=F\u00fcgt neue Downloads ohne Aktivierung des Vuze-Hauptfensters hinzu.
 TableColumn.header.maxdownspeed=max. DL-Geschw.
 TableColumn.header.maxdownspeed.info=Maximale Download-Geschwindigkeit pro Torrent
-PeersGraphicView.title=Schwarm
+PeersGraphicView.title.full=Schwarm
 ConfigView.section.tracker.passwordwebhttpsonly=Erlaube Zugriff nur \u00fcber HTTPS
 TableColumn.header.torrentpath=Torrentdatei
 TableColumn.header.torrentpath.info=Speicherort der Torrentdatei
@@ -1330,8 +1309,6 @@ UpdateWindow.restartLater=Sp\u00e4ter neustarten
 MainWindow.menu.file.restart=Neustart
 MainWindow.dialog.restartconfirmation.title=Vuze neu starten?
 MainWindow.dialog.restartconfirmation.text=Soll Vuze wirklich neugestartet werden?
-deletetorrent.message1=Es wird der TORRENT gel\u00f6scht von:\n
-deletetorrent.message2=\nSoll wirklich fortgefahren werden?
 ConfigView.label.prioritizemostcompletedfiles=Weitere Priorisierung von Dateien hoher Priorit\u00e4t, in Abh\u00e4ngigkeit ihres Vollst\u00e4ndigkeitsgrades und der Dateigr\u00f6\u00dfe
 splash.plugin.init=Initialisiere Plugin:
 splash.plugin.UIinit=Initialisiere Plugin GUI: %1  
@@ -1449,7 +1426,7 @@ DHTView.operations.findValue=Finde Wert
 DHTView.operations.store=Speichern
 DHTView.activity.title=Aktivit\u00e4ten
 DHTView.activity.status.true=Wartend
-DHTView.activity.status.false=Wird ausgef\u00fchrt
+DHTView.activity.status.false=Aktiv
 DHTView.activity.type=Typ
 DHTView.activity.type.1=Internes Lesen
 DHTView.activity.type.2=Externes Lesen
@@ -1490,7 +1467,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent-Datei... (nur T&racken)
 MyTrackerView.date_added=Hinzugef\u00fcgt
 ConfigView.section.tracker.portbackup=Backup-Ports (getrennt durch Semikolon)
 ConfigView.label.playfilespeech=Sprachausgabe, wenn eine Datei eines Torrents fertig ist
-ConfigView.label.playfilespeech.info=Die Sprachausgabe funktioniert im Moment am besten auf Englisch
 ConfigView.label.playfilefinished=Sound spielen, wenn eine Datei eines Torrents fertig ist
 ConfigView.label.backupconfigfiles=Sicherheitskopien der Konfigurationsdateien erstellen
 ConfigView.section.tracker.client.scrapesingleonly=Deaktiviere die Ansammlung von Scrape-Informationen pro Tracker (kann bei\nTrackern helfen, die 'URL too long' (414) Fehler melden)
@@ -1886,10 +1862,6 @@ progress.window.title=Aufgabe wird durchgef\u00fchrt
 progress.window.msg.filemove=Bitte warten, bis das Verschieben/Umbenennen  abgeschlossen ist
 ConfigView.label.popup.timestamp=F\u00fcge Zeitpunkt der Meldungen hinzu
 ConfigView.label.popup.autohide=Sekunden, nach denen eine Meldung automatisch ausgeblendet\nwerden soll (0: deaktiviert automatisches Ausblenden)
-ConfigView.label.popup.suppress_alerts=Unterdr\u00fccke Warnungen
-ConfigView.label.popup.use_message_boxes=Nutze Popups anstatt der Standardwarnmeldungen
-ConfigView.label.popup.show=Zeige alle protokollierten Popup-Warnmeldungen (falls vorhanden)
-ConfigView.label.popup.show.button=Anzeigen
 ConfigView.label.please.visit.here=F\u00fcr Details bitte hier schauen
 ConfigView.section.ipfilter.enable.descriptionCache=Speichere IP-Beschreibungen in einer Scratch-Datei
 ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Wenn deaktiviert, werden Beschreibungen nicht erinnert
@@ -1913,6 +1885,7 @@ UIDebugGenerator.message.cancel.text=Es wurde keine Beschreibung (Englisch) f\u0
 ConfigView.section.connection.group.http.info=Unterst\u00fctzung f\u00fcr die Verteilung per HTTP.
 ConfigView.section.connection.http.enable=Aktiviere
 ConfigView.section.connection.http.port=Eingehender TCP-Port
+ConfigView.section.connection.http.portoverride=\u00dcberschreibe Tracker-HTTP-Port [0: keine]
 window.update.noupdates.title=Suche nach Aktualisierungen
 window.update.noupdates.text=Es sind keine neuen Aktualisierungen verf\u00fcgbar.
 ConfigView.label.bindip.details=Beispiel: 192.168.1.5;eth0;eth1[2] wird die angegebene IP an alle IPs des ersten Interface und die dritte IP des zweiten Interface binden.\n Die erste IP wird f\u00fcr alle Services benutzt, alle anderen nur f\u00fcr Load Balancing.\nDie folgenden Interfaces sind verf\u00fcgbar:\n%1
@@ -2015,7 +1988,6 @@ window.uiswitcher.text=Bitte eine passende Benutzeroberfl\u00e4che ausw\u00e4hle
 window.uiswitcher.NewUI.text=* Empfohlen f\u00fcr Anf\u00e4nger und neue Nutzer.\n\n* Einfache, intuitive grafische Oberfl\u00e4che\n\n * Ben\u00f6tigt, um Inhalte auf der Vuze-Plattform zu ver\u00f6ffentlichen
 window.uiswitcher.ClassicUI.title=Klassische Oberfl\u00e4che
 window.uiswitcher.ClassicUI.text=* Bewahrt die Funktionalit\u00e4t der 2.x Serie von Azureus\n\n* Vuze-Inhaltsebene wird nicht geladen
-window.uiswitcher.bottom.text=Die Einstellung kann durch Nutzung der Vuze-Oberfl\u00e4chenauswahl einfach wieder ge\u00e4ndert werden.
 iconBar.switch.tooltip=Vuze-Oberfl\u00e4chenauswahl
 VivaldiView.notAvailable=Vivaldi-Ansicht nicht verf\u00fcgbar
 restart.error=Neustart fehlgeschlagen:\n%1\nSiehe <A HREF="{restart.error.url}">restarting issues</a>.
@@ -2042,12 +2014,7 @@ TableColumn.header.SpeedGraphic=Geschwindigkeit
 TableColumn.header.AzProduct=Von
 TableColumn.header.MediaThumb=Medien
 TableColumn.header.ProgressETA=Fortschritt
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
 TableColumn.header.name.ext=Dateityp: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
 v3.MainWindow.tab.home=Anzeigetafel
 v3.MainWindow.tab.browse=Auf Vuze
 v3.MainWindow.tab.library=Meine Bibliothek
@@ -2078,28 +2045,16 @@ v3.mb.delPublished.title=Stoppe Verteilen des Inhaltes
 v3.mb.delPublished.text=WARNUNG: Diese Aktion wird NICHT den ver\u00f6ffentlichten Inhalt '%1' von <A HREF="%2">%3</A> entfernen.\n\nNur auf 'L\u00f6schen' klicken, wenn der Inhalt ver\u00f6ffentlicht und herunterladbar bleiben, jedoch Bandbreite freigemacht werden soll. Sicherstellen, dass zuvor der Upload-Prozess abgeschlossen wurde. (<A HREF="%4">Wie</A>?).\n\nAuf 'Abbrechen' klicken, wenn der ver\u00f6ffentlichte Inhalt vollst\u00e4ndig von  %3 entfernt werden soll und den (X)-Knopf  [...]
 v3.mb.delPublished.delete=&L\u00f6schen
 v3.mb.delPublished.cancel=&Abbrechen
-v3.mb.openFile.title=\u00d6ffne Datei
-v3.mb.openFile.text.known=Dieser Inhalt wird zur Zeit nicht von Vuze unterst\u00fctzt. F\u00fcr weiter Informationen kann in die <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Wiedergabeanleitung</a> (engl.) geschaut werden.\n\nDateityp: %2 (%3)\n
-v3.mb.openFile.text.unknown=Dieser Inhalt wird zur Zeit nicht von Vuze unterst\u00fctzt. F\u00fcr weiter Informationen kann in die <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Wiedergabeanleitung</a> (engl.) geschaut werden.\n\nDateityp: %2\n
-v3.mb.openFile.button.play=Abspielen
-v3.mb.openFile.button.cancel=Abbrechen
-v3.mb.openFile.button.guide=Wiedergabeanleitung lesen
-v3.mb.openFile.remember=Dateien immer \u00f6ffnen, ohne zu fragen
 v3.mb.PlayFileNotFound.title=Datei nicht gefunden
 v3.mb.PlayFileNotFound.text=Die Dateien von '%1' sind gel\u00f6scht oder fehlen.
 v3.mb.PlayFileNotFound.button.remove=Entferne aus Vuze
 v3.mb.PlayFileNotFound.button.redownload=Erneut heruntergeladenene Daten
 v3.mb.PlayFileNotFound.button.find=Manuelle Suche..
-v3.mb.deletePurchased.title=Entferne gekauften Inhalt
-v3.mb.deletePurchased.text=Sicher, dass der Inhalt '%1' gel\u00f6scht werden soll?\n\nDieser Inhalt wurde entweder gekauft, oder es war eine Anmeldung erforderlich, um ihn herunterzuladen.
-v3.mb.deletePurchased.button.delete=&L\u00f6schen
-v3.mb.deletePurchased.button.cancel=&Abbrechen
 v3.topbar.menu.show.plugin=Plugin-Bereich
 v3.topbar.menu.show.search=Suchen
 v3.topbar.menu.show.frog=Der blaue Frosch
 splash.initializeCore=Initialisiere Kern
 splash.initializeUIElements=Initialisiere Benutzerschnittstellenelemente
-#
 ConfigView.section.ipfilter.peerblocking.group=Quellen-Blockierung
 ConfigView.section.ipfilter.autoload.group=Automatisches Laden
 ConfigView.section.ipfilter.autoload.file=IP-Filter-Datei, die automatisch geladen werden soll
@@ -2253,15 +2208,9 @@ v3.MainWindow.tab.events=Benachrichtigungen
 button.columnsetup.tooltip=Spalteneinstellung
 v3.activity.remove.title=L\u00f6sche Benachrichtigung
 v3.activity.remove.text=Sicher, dass die Benachrichtigung gel\u00f6scht werden soll?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
 v3.MainWindow.menu.file.closewindow=Schlie\u00dfen
 Menu.show.torrent.menu=Zeige Torrent-Men\u00fc
 Menu.show.torrent.menu.tooltip=Zeigt das Torrent-Men\u00fc im oberen Men\u00fcbalken
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
 Views.plugins.aznetstatus.title=Netzwerkstatus
 plugin.aznetstatus.pingtarget=Ziel f\u00fcr Ping/trace route
 ConfigView.section.style.usePathFinder=Nutze 'Path Finder' anstatt 'Finder'
@@ -2274,10 +2223,6 @@ v3.splash.hookPluginUI=Hinzuf\u00fcgen der Plugin-Oberfl\u00e4che
 OpenTorrentWindow.mb.notTorrent.cannot.display=Unf\u00e4hig Daten korrekt anzuzeigen
 MainWindow.menu.window.zoom.maximize=Maximieren
 MainWindow.menu.window.zoom.restore=Wiederherstellen
-ImageResizer.image.too.small=Das benutzte Bild ist zu klein, bitte ein anderes w\u00e4hlen (mind. %1 x %2 )
-ImageResizer.title=Dieses Tool bietet eine Vorschau, wie das Bild auf der Vuze -Plattform aussehen wird.
-ImageResizer.move.image=Bewege Bild durch ziehen
-ImageResizer.move.image.with.slider=Bewege Bild durch ziehen, ver\u00e4ndere die Gr\u00f6\u00dfe mit dem Schieberegler unten
 security.crypto.title=Zugriff auf Schl\u00fcssel
 security.crypto.encrypt=Bitte Passwort eingeben, um neu generierten Schl\u00fcssel zu sch\u00fctzen. Bitte das Passwort nicht vergessen, es gibt keine M\u00f6glichkeit es wiederherzustellen!
 security.crypto.decrypt=Bitte Passwort eingeben, um eigenen Schl\u00fcssel zu entsperren.
@@ -2369,9 +2314,6 @@ 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
-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
 azbuddy.tracker.enabled=Aktiviere 'Freund-Beschleunigung', um das Herunterladen mit Freunden zu priorisieren.
 azbuddy.protocolspeed=max. kB/s Freund-Protokolldaten
 v3.MainWindow.button.download=Herunterladen
@@ -2491,7 +2433,6 @@ Subscription.menu.resetauth=Authentifikationsdetails zur\u00fccksetzen
 Search.menu.engines=Masken
 Wizard.Subscription.title=Abonnieren
 Wizard.Subscription.optin.title=Aktiviere Abonnements
-#what you've watched? Discover more with a single click...
 Wizard.Subscription.subscribe.title=Verf\u00fcgbare Abonnements
 Wizard.Subscription.create.title=Erstelle neues Abonnement
 Button.search=Suchen
@@ -2511,7 +2452,7 @@ Wizard.Subscription.rss.subtitle2=Viele Anbieter geben f\u00fcr ihre Ver\u00f6ff
 Wizard.Subscription.rss.subtitle3=Sobald neue Ergebnisse durch den RSS-Feed verf\u00fcgbar sind, werden diese in der Seitenleiste angezeigt.
 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>
+Wizard.Subscription.subscribe.library.empty=Keine Abonnements verf\u00fcgbar?\n \nSuche das orangene Abonnementsymbol im Vuze-Netzwerk.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Weitere Informationen</A>
 message.confirm.delete.title=L\u00f6schen best\u00e4tigen
 message.confirm.delete.text=Sicher, dass '%1' gel\u00f6scht werden soll?
 Subscription.menu.properties=Eigenschaften
@@ -2547,7 +2488,7 @@ statusbar.feedback.tooltip=Hier klicken, um Feedback zu senden
 sidebar.Activity=Benachrichtigungen
 v3.activity.button.watchall=Alle als gesehen markieren
 subscriptions.view.help.1=Abonnements hinzuf\u00fcgen mit
-subscriptions.view.help.2=Erhalte Mitteilungen, wenn es neue Inhalte zum Herunterladen gibt. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Weitere Informationen</A>.
+subscriptions.view.help.2=Erhalte Mitteilungen, wenn es neue Inhalte zum Herunterladen gibt. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Weitere Informationen</A>.
 sidebar.sash.tooltip=F7 zeigt/versteckt Seitenleiste
 sidebar.expand.tooltip=Seitenleiste ausfahren
 sidebar.dropdown.tooltip=Zeige Seitenleiste in Men\u00fcformat
@@ -2587,13 +2528,6 @@ azbuddy.ui.menu.cat.set_msg=Mit Komma getrennte Liste von Kategorien, oder alle
 azbuddy.ui.menu.cat_subs=Abonniere
 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
-v3.dialog.cnclose.subtitle=Benachrichtigung
-v3.dialog.cnclose.info1=Ein HD-Netzwerk wurde geschlossen.
-v3.dialog.cnclose.info2=Es wurde ein HD-Netzwerk in der Seitenleiste geschlossen.\n\nFalls es wieder ge\u00f6ffnet werden soll, kann dies \u00fcber das Men\u00fc "HD Networks" auf der rechten Seite geschehen.
-v3.dialog.cnclose.noshow=Nicht noch einmal zeigen
-v3.dialog.cnmanage.title=Verwalte Netzwerke f\u00fcr HD Inhalte
-v3.dialog.cnmanage.intro=Die untere Liste zeigt eine Auswahl von Netzwerken, die im Men\u00fc "HD-Netzwerke" angezeigt werden k\u00f6nnen.
 azbuddy.ui.table.read_cat=Kat. gelesen
 TableColumn.header.#.info=Position/Ordnungsnummer
 TableColumn.header.category.info=Name der Kategorie des Torrents
@@ -2743,7 +2677,7 @@ xcode.deletedata.title=L\u00f6sche umgewandelten Inhalt
 xcode.deletedata.message=Sicher, dass die Kopie von '%1', umgewandelt f\u00fcr '%2'%3 gel\u00f6scht werden soll?
 xcode.deletedata.message.2=\n(Eine Kopie k\u00f6nnte noch in '%1' existieren.)
 v3.deviceview.infobar.line1=Ziehe Videos aus der Bibliothek zum Ger\u00e4t der Wahl.
-v3.deviceview.infobar.line2=Spiele Videos auf allem m\u00f6glichen Ger\u00e4ten ab - iPhone, iPod, TV
+v3.deviceview.infobar.line2=Spiele Videos auf allem m\u00f6glichen Ger\u00e4ten ab - iPad, iPhone, iPod, TV
 v3.deviceview.infobar.line1.generic=Ziehe Videos von der Bibliothek nach %1 im Seitenmen\u00fc.
 v3.deviceview.infobar.line2.itunes=Videos werden im iTunes-Film-Verzeichnis erscheinen, wenn sie zum Abspielen bereit sind.
 v3.deviceview.infobar.line2.xbox=Abspielen der Videos durch Auswahl von My XBox -> Video Library -> Vuze auf der Xbox 360.
@@ -2774,9 +2708,6 @@ device.rss.enable=Erzeuge RSS-Feed von umgewandeltem Inhalt - macht den Inhalt f
 device.rss.port=RSS-Feed-Port
 device.rss.view=Klicken, um RSS-Feed anzusehen
 device.rss.localonly=Beschr\u00e4nke Zugriff auf nur diesen Computer
-rcm.rc_tracker.tt=Klicken, um Tracker zu durchsuchen
-rcm.rc_hash.tt=Klicken, um diesen Inhalt herunterzuladen
-rcm.rc_title.tt=Klicken, um nach diesen Inhalt zu suchen
 devices.xcode.autoCopy=Automatisch in das Zielverzeichnis kopieren
 devices.xcode.setcopyto=Setze Zielverzeichnis...
 devices.xcode.setcopyto.title=W\u00e4hle Zielverzeichnis
@@ -2831,6 +2762,10 @@ ConfigView.section.Pairing=Paarung
 pairing.accesscode=Zugangscode
 pairing.ac.getnew=Teile neuen Zugangscode zu
 pairing.ac.getnew.create=Erstellen
+pairing.ipv4=\u00d6ffentliche IPv4-Adresse
+pairing.ipv6=\u00d6ffentliche IPv6-Adresse
+pairing.local.ipv4=Lokale IPv4-Adresse
+pairing.local.ipv6=Lokale IPv6-Adresse
 pairing.host=Hostadresse (DNS-Name)
 pairing.group.explicit=Ausf\u00fchrliche Attribute
 pairing.explicit.enable=Aktivieren
@@ -2851,12 +2786,166 @@ 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
+pairing.server.warning.title=Paarungsserver-Meldung
+wizard.webseedseditor.edit.title=HTTP-Seed-Editor
+wizard.webseedseditor.edit.newseed=Neuer Seed
+MyTorrentsView.menu.editWebSeeds=Editiere HTTP-Seeds
+ClientStats.title.full=Client-Statistik
+ClientStats.column.count=Anzahl
+network.ipv6.enable.support=Aktiviere IPv6-Unterst\u00fctzung (Ben\u00f6tigt unter Windows Java7)
+MagnetPlugin.use.lookup.service=Nutze alternativen Suchservice von Vuze, falls Magnetsuche via DHT fehlschl\u00e4gt
+MagnetPlugin.report.secondarylookup=Probiere alternativen Suchservice
+MagnetPlugin.report.secondarylookup.ok=Alternative Suche erfolgreich
+MagnetPlugin.report.secondarylookup.fail=Alternative Suche fehlgeschlagen: keine Quellen gefunden
+TrackerView.title.short=Quellen
+TrackerView.title.full=Quellen
+Trackers.column.type=Typ
+Trackers.column.seeds.info=Vollst\u00e4ndige Quellen gemeldet vom Tracker
+Trackers.column.leechers.info=Unvollst\u00e4ndige Quellen im Schwarm
+Trackers.column.peers.info=Quellen gemeldet vom Tracker
+Trackers.column.interval=Intervall
+Trackers.column.interval.info=Anfrageintervall in Sekunden: Intervall (min. Intervall)
+Trackers.column.updatein=Anfrage
+Trackers.column.updatein.info=Zeit bis zur n\u00e4chsten Aktualisierung
+tps.status.available=Verf\u00fcgbar
+tps.status.unavailable=Nicht verf\u00fcgbar
+tps.lan.details=%1 lokale Clients entdeckt
+tps.pex.details=Verbunden zu %1 Peers (ausstehend: pex=%2, andere=%3)
+tps.tracker.cache1=Peer cache: Eintr\u00e4ge=%1
+dht.status.disabled=Deaktiviert, DHT nicht verf\u00fcgbar
+tps.type.incoming=Eingehend
+tps.incoming.details=Gerade: TCP=%1, UDP=%2; Total=%3
+ConfigView.label.autoadjust=Automatisches Anpassen der Einstellungen basierend auf der Verbindungsgeschwindigkeit
+ConfigView.label.start=Start
+ConfigView.label.stop=Herunterfahren
+ConfigView.label.start.onlogin=Starte Vuze beim Einloggen
+ConfigView.label.stop.seedcomp=Wenn Hochladen beendet
+ConfigView.label.stop.downcomp=Wenn Herunterladen beendet
+ConfigView.label.stop.Nothing=Tue nichts
+ConfigView.label.stop.QuitVuze=Beende Vuze
+ConfigView.label.stop.Sleep=Computer in Standby
+ConfigView.label.stop.Hibernate=Computer in Ruhezustand
+ConfigView.label.stop.Shutdown=Computer herunterfahren
+core.shutdown.alert=Aktion '%1' ausgel\u00f6st als %2
+core.shutdown.dl=Herunterladen beendet
+core.shutdown.se=Hochladen beendet
+pairing.last.error=Letzter Fehler
+MainWindow.menu.pairing=Paarung f\u00fcr Fernbedienung
+ConfigView.label.pauseresume=Autom. Pausieren/Fortsetzen
+update.now.title=Aktualisierung ben\u00f6tigt
+update.now.desc=Vuze ben\u00f6tigt Aktualisierungen, um die Migrations abzuschlie\u00dfen.\n\nNach dem Schlie\u00dfen dieses Dialoges erfolgt eventuell eine Anfrage von Windows.\nEin Neustart von Vuze ist NICHT notwendig.
+ConfigView.label.jvm=Java-Optionen
+platform.jvmopt.sunonly=Nur Sun JVMs werden unterst\u00fctzt (aktueller Bereitsteller=%1)
+platform.jvmopt.configerror=Kann JVM-Optionen wegen Konfigurationsfehlers nicht nutzen
+platform.jvmopt.nolinkfile=Kann JVM-Optionen nicht nutzen, Migration nicht vollst\u00e4ndig
+platform.jvmopt.nolink=Kann JVM-Optionen nicht nutzen, existierende Konfiguration verbietet es
+platform.jvmopt.accesserror=Zugriff auf Datei der JVM-Optionen fehlgeschlagen: %1
+pairing.status.noservices=Kein Fernbedienungsservice aktiviert
+webui.pairingtest=\tKlicken, um Paarung zu testen
+webui.connectiontest=\tKlicken, um Verbindung zu testen
+jvm.info=Ein Neustart von Vuze is notwendig, falls Optionen ge\u00e4ndert werden. *** Warnung - Falsche JVM-Optionen k\u00f6nnen Vuze daran hindern zu starten oder dessen Performance verschlechtern. ***\n
+jvm.show.file=Die lokale Datei f\u00fcr JVM-Optionen ist '%1' - Nur im Notfall direkt editieren
+jvm.reset=Setze JVM-Optionen zur\u00fcck auf Installationsstandard
+jvm.error=Fehler beim Zugriff auf die JVM-Optionen: %1
+jvm.max.mem=Max. Speichergr\u00f6\u00dfe [leer=Standard,min=%1]
+jvm.min.mem=Min. Speichergr\u00f6\u00dfe [leer=Standard,min=%1]
+ConfigView.section.invalid.value.title=Ung\u00fcltiger Wert
+ConfigView.section.invalid.value=Ung\u00fcltiger Wert '%1' eingegeben f\u00fcr '%2': %3
+Button.dismiss=Gesehen
+webui.pairing.autoauth=Aktiviere Standardpasswortschutz: Nutzername=vuze, Passwort=<Paarungszugangscode>
+ConfigView.label.stop.autoreset=Setze Aktionen automatisch zu '%1' zur\u00fcck, sobald ausgel\u00f6st
+remote.pairing.title=Paarung f\u00fcr Fernbedienung
+remote.pairing.subtitle=Vuze-Fernbedienung bietet die M\u00f6glichkeit der Kontrolle \u00fcber Vuze von jedem Computer oder mobilem Browser - jederzeit, \u00fcberall.
+remote.pairing.instruction=Einfach den Code in eine beliebige Fernbedienungsanwendung eingeben.
+remote.pairing.functions=<A HREF="clip">Kopiere Code in Zwischenablage</A>   |   <A HREF="new">Erhalte neuen Code</A>
+remote.pairing.tip.title=Tipp: Zwei einfache Wege, die Fernbedienung zu nutzen:
+remote.pairing.tip.text=Toolbar f\u00fcr Vuze-Fernbedienung: Gehe zu <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>.\nVuze-Fernbedienung f\u00fcr Mobiltelefone: Gehe zu <A HREF="http://remote.vuze.com/">remote.vuze.com</A> im Browser des Mobiltelefons.
+remote.pairing.accesscode=Zugangscode:
+remote.pairing.test.running=Teste Verbindung f\u00fcr Fernbedienung...
+remote.pairing.test.success=Vuze l\u00e4sst sich fernbedienen.
+remote.pairing.test.unavailable=Konnte Fernbedienbarkeit nicht feststellen. <A HREF="retry">Erneut probieren</A>
+remote.pairing.test.fail=Zugriff auf Vuze von ausserhalb des LANs nicht m\u00f6glich.  <A HREF="http://www.vuze.com/pairing_error_faq.start">Mehr erfahren</A>
+update.fail.app.changed.title=Aktualisierung fehlgeschlagen
+update.fail.app.changed=Vuze muss aktualisiert werden, dies kann jedoch nicht automatisch durchgef\u00fchrt werden, da sich der Anwendungsname zu '%1' ge\u00e4ndert hat.\n\nBitte den aktuellen Installer von http://www.vuze.com/ herunterladen.
+webui.port.override=Port override: Nur ben\u00f6tigt, falls der \u00f6ffentliche vom internen Port auf Grund von NAT-Einstellungen abweicht
+MainWindow.status.warning.tooltip=F\u00fcr Details hier klicken
+search.dialog.text=Text zur Suche neuer Torrents eingeben:
+core.not.available=Vuze initialisiert noch, bitte erneut probieren, wenn der Vorgang abgeschlossen ist.
+Button.validate=\u00dcberpr\u00fcfe
+Button.getstarted=Beginnen
+Button.goLibrary=Gehe zu Meiner Bibliothek
+devices.xcode.remove.vetoed=Umwandlung von '%1' wird durchgef\u00fchrt, der Download kann nicht entfernt werden bis diese fertig, oder abgebrochen worden ist.
+Button.agree=Ich stimme zu
+device.status.online=Ger\u00e4t ist online
+device.itunes.status.running=iTunes l\u00e4uft
+device.itunes.status.notrunning=iTunes l\u00e4uft nicht
+device.itunes.status.notinstalled=iTunes ist nicht installiert
+view.waiting.core=Ansicht wird verf\u00fcgbar sein, sobald der Vuze-Kern geladen ist.
+devices.profile.direct=Direkt
+ConfigView.section.tables=Tabelle
+ConfigView.section.style.useTree=Zeige Dateien in Bibliothek/Meine Torrents-Ansichten (Neustart ben\u00f6tigt)
+ConfigView.section.mode.resetdefaults=Setze Konfiguration zur\u00fcck auf Standardwerte (Neustart empfohlen)
+resetconfig.warn.title=Aktion best\u00e4tigen
+resetconfig.warn=Alle Modifikationen in der Vuze-Konfiguration werden r\u00fcckg\u00e4ngig gemacht.\nMit dem Reset fortfahren?
+ConfigView.label.xfer.bias_up=Erh\u00f6he Download-Geschwindigkeit durch Verlagerung von Upload-Kapazit\u00e4t hin zu unvollst\u00e4ndigen Downloads
+ConfigView.label.xfer.bias_slack=KB/s Minimum reserviert f\u00fcr vollst\u00e4ndige Downloads
+SpeedView.stats.con=Verbindungsdetails:
+SpeedView.stats.con_details=gesamt=%1, unbegrenzt=%2, wartend=%3, geblockt=%4
+manual.mode=Manuell
+configureWizard.transfer2.hint=Setzen einer zu hohen oder zu niedrigend Upload-Geschwindigkeit hat Auswirkungen auf den Download!
+configureWizard.transfer2.message=Bittorrent basiert auf einem Tit-for-tat-Protokol - je schneller man hochl\u00e4dt, um so schneller kann man herunterladen. Um also schnell herunterzuladen und rasch ein gutes Verh\u00e4ltnis (share ratio) zu erzielen, ben\u00f6tigt man eine hohe Upload-Geschwindigkeit.\n\nIst diese jedoch f\u00fcr die Verbindung zu hoch eingestellt, kann es zur \u00dcberlastung kommen, den gesamten Netzwerkverkehr verlangsamen und Auswirkungen auf andere Programme haben [...]
+configureWizard.transfer2.group=Modus
+configureWizard.transfer2.test.info=W\u00e4hlen, um Geschwindigkeitstest auszuf\u00fchren
+configureWizard.transfer2.test=Starte Test
+configureWizard.transfer2.mselect=W\u00e4hle die Upload-Geschwindigkeit der Verbindung
+configureWizard.transfer2.mselect.info=xxx/<Wert> steht f\u00fcr eine Upload-Geschwindigkeit von <Wert> Kilobit-pro-Sekunde.\nBeispielsweise ist bei einer ADSL-Verbindung mit 768 Kb/s Download- und 384 Kb/s Upload-Geschwindigkeit, 'xxx/384 kbit/sec' zu w\u00e4hlen.\nIst der exakte Wert nicht in der Liste gegeben, so rundet man ab. (Achtung!: 1Byte = 8Bit)
+configureWizard.transfer2.rate.unchanged=Aktuelle Einstellungen werden benutzt
+configureWizard.transfer2.rate.changed=Verbindungslimit=%1\nAngewandtes Limit %2 (max. aktive Torrents=%3, max. Downloads=%4)
+speedtest.wizard.select.title=Typ des Test ausw\u00e4hlen
+speedtest.wizard.select.group=Testtyp
+speedtest.wizard.select.general=Allgemeiner Geschwindigkeitstest (empfohlen)
+speedtest.wizard.select.bt=Bittorrent-spezifischer Geschwindigkeitstest
+FileItem.storage.reorder=Neuordnen
+ConfigView.label.piecereorder=F\u00fcge Daten beim Herunterladen an das Ende von Dateien an und ordne die Teile neu w\u00e4hrend der Download fortschreitet.
+ConfigView.label.piecereorderminmb=Nur Dateien neuordnen, die gr\u00f6\u00dfer sind als (in MB)
+ConfigView.section.style.extendedErase=Zeichne Gitterlinien und f\u00fclle leere Fl\u00e4chen
+FilesView.menu.setpriority.numeric=Numerisch...
+FilesView.dialog.priority.title=Numerische Priorit\u00e4t eingeben
+FilesView.dialog.priority.text=0=Normal, 1=Hoch, 2=H\u00f6her...
+beta.wizard.title=Beta-Versions-Setup
+beta.wizard.intro.title=Teilnahme-Auswahl
+beta.wizard.info=Die Teilnahme am Vuze-Beta-Programm erlaubt fr\u00fchen Zugriff auf kommende Neuerungen.\n\nEs erm\u00f6glicht das Experimentieren mit diesen und hilft sie zu formen und zu verbessern - Meinungen und Anmerkungen sind sehr hilfreich f\u00fcr uns!\n\nBeta-Versionen k\u00f6nnen instabil sein, jedoch gibt diese Option Zugriff auf relativ stabile Ver\u00f6ffentlichungen. F\u00fcr noch aktuellere Versionen kann das 'Beta Updater'-Plugin verwendet werden.
+beta.wizard.link=Hier klicken f\u00fcr die Webseite der Beta-Versionen
+beta.wizard.off=Ich bin gl\u00fccklich mit den stabilen Versionen, danke!
+beta.wizard.on=Bitte auf die neuste stabile Beta-Version aktualisieren.
+beta.wizard.version=Zur Zeit Benutzung von Version %1
+beta.wizard.disable.title=Neuinstallation ben\u00f6tigt
+beta.wizard.disable.text=Danke f\u00fcr das Testen der Beta-Versionen!\n\nZum Verlassen des Beta-Programms bitte die aktuelle stabile Version installieren.
+beta.wizard.forum=Nutze die Foren von Vuze, um die Meinung zu \u00e4u\u00dfern oder Fehlerberichte zu schreiben.
+FileProgress.deleted=Gel\u00f6scht
+priority.high=Hohe Priorit\u00e4t
+priority.normal=Normale Priorit\u00e4t
+Column.seedspeers.started=%1/%2
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 Objekte: %2 aktiv
+library.incomplete.header.p=%1 Objekte herunterladend, %2 wartend auf Download
+library.unopened.header.p=%1 Objekte
+library.all.header=%1 Objekt: %2 aktiv
+library.incomplete.header=%1 Objekt herunterladend, %2 wartend auf Download
+library.unopened.header=%1 Objekt
+ConfigView.section.style.status.show_rategraphs=Zeige Geschwindigkeitverlaufsgrafik unter Upload-/Download-Text in Statusleite
+device.error.mountrequired="%1" ben\u00f6tigt Einbindung in Ger\u00e4t
+v3.deviceview.infobar.line2.android=Aktiviere USB am Telefon, um die Videos korrekt zu \u00fcbertragen.
+MyTorrents.column.ColumnProgressETA.compon=Beendet %1
+Sidebar.beta.title=Beta-Programm
+MainWindow.menu.beta.on=Nehmen am Beta-Programm teil...
+MainWindow.menu.beta.off=Verlasse Beta-Programm...
+Button.sendNow=Sende jetzt
+Button.sendManual=Sende manuell (create .zip)
+deletecontent.also.deletetorrent=L\u00f6sche auch .torrent-Datei
+ConfigView.section.file.deletion.section=L\u00f6schen von Dateien
+ConfigView.section.file.delete.torrent=L\u00f6sche .torrent-Datei beim L\u00f6schen von Inhalt
+ConfigView.section.file.delete.confirm=Best\u00e4tige L\u00f6schen von Inhalten via Werkzeugleiste und Entfernen-Taste
+MainWindow.menu.view.beta=Beta-Programm
+Peers.column.Protocol=Protokol
+devices.copying=Kopiere auf Ger\u00e4t
diff --git a/org/gudy/azureus2/internat/MessagesBundle_el_GR.properties b/org/gudy/azureus2/internat/MessagesBundle_el_GR.properties
index 06ae13f..ba6c62e 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_el_GR.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_el_GR.properties
@@ -25,12 +25,9 @@ ConfigView.section.language=\u0393\u03bb\u03ce\u03c3\u03c3\u03b1
 MainWindow.menu.help=&\u0392\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1 
 MainWindow.menu.help.about=&\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf Vuze
 MainWindow.about.title=\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf Vuze
-MainWindow.about.section.developers=\u03a0\u03c1\u03bf\u03b3\u03c1\u03b1\u03bc\u03bc\u03b1\u03c4\u03b9\u03c3\u03c4\u03ad\u03c2 
-MainWindow.about.section.translators=\u039c\u03b5\u03c4\u03b1\u03c6\u03c1\u03b1\u03c3\u03c4\u03ad\u03c2 
 MainWindow.about.section.internet=\u0394\u03b9\u03b1\u03b4\u03af\u03ba\u03c4\u03c5\u03bf 
 MainWindow.about.internet.homepage=\u0394\u03b9\u03ba\u03c4\u03c5\u03b1\u03ba\u03cc\u03c2 \u03c4\u03cc\u03c0\u03bf\u03c2 Vuze
 MainWindow.about.internet.sourceforge=\u03a3\u03b5\u03bb\u03af\u03b4\u03b1 \u03c4\u03bf\u03c5 \u03c0\u03c1\u03bf\u03b3\u03c1\u03ac\u03bc\u03bc\u03b1\u03c4\u03bf\u03c2 \u03c3\u03c4\u03bf Sourceforge
-MainWindow.about.internet.sourceforgedownloads=\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03b3\u03b9\u03b1 \u03ba\u03b1\u03c4\u03ad\u03b2\u03b1\u03c3\u03bc\u03b1 \u03c3\u03c4\u03bf Sourceforge
 MainWindow.about.internet.bugreports=\u0391\u03bd\u03b1\u03c6\u03bf\u03c1\u03ad\u03c2 \u03a3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd 
 MainWindow.about.internet.forumdiscussion=\u039f\u03bc\u03ac\u03b4\u03b1 \u03c3\u03c5\u03b6\u03b7\u03c4\u03ae\u03c3\u03b5\u03c9\u03bd \u03b3\u03b5\u03bd\u03b9\u03ba\u03bf\u03cd \u03b5\u03bd\u03b4\u03b9\u03b1\u03c6\u03ad\u03c1\u03bf\u03bd\u03c4\u03bf\u03c2 
 MainWindow.about.internet.wiki=\u03a3\u03c5\u03c7\u03bd\u03ad\u03c2 \u03b5\u03c1\u03c9\u03c4\u03ae\u03c3\u03b5\u03b9\u03c2 \u03b3\u03b9\u03b1 \u03c4\u03bf Vuze
@@ -270,8 +267,6 @@ IrcView.help=\u039f\u03b9 \u03b5\u03c0\u03b9\u03c4\u03c1\u03b5\u03c0\u03cc\u03bc
 PasswordWindow.title=\u03a4\u03bf Vuze \u03b5\u03af\u03bd\u03b1\u03b9 \u03ba\u03bb\u03b5\u03b9\u03b4\u03c9\u03bc\u03ad\u03bd\u03bf 
 PasswordWindow.passwordprotected=\u03a4\u03bf Vuze \u03c0\u03c1\u03bf\u03c3\u03c4\u03b1\u03c4\u03b5\u03cd\u03b5\u03c4\u03b1\u03b9 \u03bc\u03b5 \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc.\n\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b5\u03bc\u03c6\u03b1\u03bd\u03b9\u03c3\u03c4\u03b5\u03af \u03c4\u03bf \u03c0\u03b1\u03c1\u03ac\u03b8\u03c5\u03c1\u03bf \u03c4\u03bf\u03c5 Vuze \u03c0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03c0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03 [...]
 Button.ok=\u039f\u039a
-TrackerChangerWindow.title=\u03a0\u03c1\u03bf\u03c3\u03b8\u03b7\u03ba\u03b7 \u0399\u03c7\u03bd\u03b7\u03bb\u03b1\u03c4\u03b7
-TrackerChangerWindow.newtracker=\u03a0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03b5\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7 \u03b4\u03b9\u03b5\u03c5\u03b8\u03c5\u03bd\u03c3\u03b7 \u03c4\u03bf\u03c5 \u03bd\u03b5\u03bf\u03c5  \u0399\u03c7\u03bd\u03b7\u03bb\u03b1\u03c4\u03b7
 PeersView.discarded=\u0391\u03b3\u03bd\u03bf\u03ae\u03b8\u03b7\u03ba\u03b5 
 discarded=\u03b1\u03b3\u03bd\u03bf\u03ae\u03b8\u03b7\u03ba\u03b1\u03bd
 MyTorrentsView.#=# 
@@ -342,7 +337,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u0394\u03b9\u03b1\u03b3\u03c1\u03b1
 MyTorrentsView.menu.removeand.deletedata=\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u0394&\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd 
 MyTorrentsView.menu.removeand.deleteboth=\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae &\u03ba\u03b1\u03b9 \u03c4\u03c9\u03bd \u03b4\u03cd\u03bf 
 deletedata.title=!!! \u03a0\u03c1\u03bf\u03c3\u03bf\u03c7\u03ae !!! 
-deletedata.message1=\u03a0\u03c1\u03cc\u03ba\u03b5\u03b9\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03c4\u03b1 \u0394\u0395\u0394\u039f\u039c\u0395\u039d\u0391 \u03b1\u03c0\u03cc \u03c4\u03bf :\n 
 MainWindow.menu.file.configure=&\u039f\u03b4\u03b7\u03b3\u03cc\u03c2 \u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd 
 configureWizard.title=\u039f\u03b4\u03b7\u03b3\u03cc\u03c2 \u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd 
 configureWizard.welcome.title=\u039a\u03b1\u03bb\u03c9\u03c3\u03ae\u03c1\u03b8\u03b1\u03c4\u03b5 \u03c3\u03c4\u03bf\u03bd \u039f\u03b4\u03b7\u03b3\u03cc \u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd \u03c4\u03bf\u03c5 Vuze
@@ -364,7 +358,6 @@ configureWizard.transfer.maxActiveTorrents=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\
 configureWizard.transfer.maxDownloads=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u039b\u03ae\u03c8\u03b5\u03c9\u03bd 
 configureWizard.transfer.maxUploadsPerTorrent=\u039c\u03ad\u03b3\u03b9\u03c3\u03c4\u03bf\u03c2 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc\u03c2 \u03b1\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ce\u03bd \u03b1\u03bd\u03ac Torrent 
 configureWizard.nat.title=NAT / \u0398\u03cd\u03c1\u03b1 \u0394\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae 
-configureWizard.nat.message=\u0393\u03b9\u03b1 \u03bd\u03b1 \u03ad\u03c7\u03b5\u03c4\u03b5 \u03c4\u03b1 \u03ba\u03b1\u03bb\u03cd\u03c4\u03b5\u03c1\u03b1 \u03b1\u03c0\u03bf\u03c4\u03b5\u03bb\u03ad\u03c3\u03bc\u03b1\u03c4\u03b1 \u03bc\u03b5 \u03c4\u03bf BitTorrent, \u03c0\u03c1\u03bf\u03c4\u03b5\u03af\u03bd\u03b5\u03c4\u03b1\u03b9 \u03bd\u03b1 \u03b5\u03af\u03c3\u03c4\u03b5 \u03c0\u03bb\u03ae\u03c1\u03c9\u03c2 \u03c0\u03c1\u03bf\u03c3\u03b2\u03ac\u03c3\u03b9\u03bc\u03bf\u03c2 \u03bc\u03ad\ [...]
 configureWizard.nat.test=\u0394\u03bf\u03ba\u03b9\u03bc\u03ae 
 configureWizard.nat.testing=\u0393\u03af\u03bd\u03b5\u03c4\u03b1\u03b9 \u03b4\u03bf\u03ba\u03b9\u03bc\u03ae \u03c4\u03b7\u03c2 \u03b8\u03cd\u03c1\u03b1\u03c2 
 configureWizard.nat.ok=OK ! 
@@ -690,8 +683,6 @@ ConfigView.section.tracker.main=\u039a\u03cd\u03c1\u03b9\u03bf
 ConfigView.section.tracker.web=\u0394\u03b9\u03b1\u03b4\u03af\u03ba\u03c4\u03c5\u03bf 
 ConfigView.label.prioritizefirstpiece=\u03a0\u03c1\u03bf\u03c4\u03b5\u03c1\u03b1\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 \u03c3\u03c4\u03bf \u03c0\u03c1\u03ce\u03c4\u03bf \u03ba\u03bf\u03bc\u03bc\u03ac\u03c4\u03b9 \u03c4\u03c9\u03bd \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd 
 ConfigView.label.prioritizefirstpiece.tooltip=\u039d\u03b1 \u03b3\u03af\u03bd\u03b5\u03b9 \u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b5\u03b9\u03b1 \u03bd\u03b1 \u03ba\u03b1\u03c4\u03b5\u03b2\u03b5\u03af \u03c4\u03bf \u03b1\u03c1\u03c7\u03b9\u03ba\u03cc \u03bc\u03ad\u03c1\u03bf\u03c2 \u03c4\u03bf\u03c5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03c3\u03c4\u03b7\u03bd \u03b1\u03c1\u03c7\u03ae.\n\u0393\u03b9\u03b1 \u03c5\u03c0\u03bf\u03c3\u03c4\u03ae\u03c1\u03b9\u03be\u03b7 \u03c0\u03 [...]
-ConfigView.section.file.confirm_data_delete=\u0395\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03b9\u03c9\u03c3\u03b7 \u03ba\u03b1\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd 
-ConfigView.section.file.confirm_data_delete.tooltip=\u0395\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03b9\u03c9\u03c3\u03b7  \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2 \u03b4\u03b5\u03b4\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd \u03cc\u03c4\u03b1\u03bd \u03b3\u03af\u03bd\u03b5\u03c4\u03b1\u03b9 \u03c7\u03c1\u03ae\u03c3\u03b7 \u03c4\u03bf\u03c5 '\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 \u03ba\u03b1\u03b9 \u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae...' 
 TrayWindow.menu.startalldownloads=\u0395\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u038c\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u039b\u03ae\u03c8\u03b5\u03c9\u03bd 
 SystemTray.menu.startalltransfers=\u0395&\u03ba\u03ba\u03af\u03bd\u03b7\u03c3\u03b7 \u038c\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u039b\u03ae\u03c8\u03b5\u03c9\u03bd 
 sharing.progress.title=\u03a0\u03c1\u03cc\u03bf\u03b4\u03bf\u03c2 \u0394\u03b9\u03b1\u03bc\u03bf\u03b9\u03c1\u03b1\u03c3\u03bc\u03bf\u03c5
diff --git a/org/gudy/azureus2/internat/MessagesBundle_en_US_classic.properties b/org/gudy/azureus2/internat/MessagesBundle_en_US_classic.properties
new file mode 100644
index 0000000..d382bc9
--- /dev/null
+++ b/org/gudy/azureus2/internat/MessagesBundle_en_US_classic.properties
@@ -0,0 +1,6 @@
+Column.seedspeers.started=%1(%2)
+Column.seedspeers.notstarted=0(%2)
+Column.seedspeers.started.noscrape=%1
+Column.seedspeers.notstarted.noscrape=
+#connected to more seedspeers than tracker reports
+Column.seedspeers.started.over=%1(%2)
diff --git a/org/gudy/azureus2/internat/MessagesBundle_es_ES.properties b/org/gudy/azureus2/internat/MessagesBundle_es_ES.properties
index c3b981c..b2d4a9f 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_es_ES.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_es_ES.properties
@@ -36,12 +36,9 @@ MainWindow.menu.window.alltofront=Poner todo en &1er. plano
 MainWindow.menu.help=A&yuda
 MainWindow.menu.help.about=Acerca de Vuze
 MainWindow.about.title=Acerca
-MainWindow.about.section.developers=Desarrolladores
-MainWindow.about.section.translators=Traductores
 MainWindow.about.section.system=Sistema
 MainWindow.about.internet.homepage=P\u00e1gina de Vuze
 MainWindow.about.internet.sourceforge=P\u00e1gina del proyecto en Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Descargas desde Sourceforge
 MainWindow.about.internet.bugreports=Informe de fallos
 MainWindow.about.internet.forumdiscussion=Foros
 MainWindow.dialog.choose.savepath=Seleccione la carpeta donde guardar la descarga
@@ -308,8 +305,6 @@ IrcView.help=Los comandos v\u00e1lidos son :\n . /help : muestra este mensaje\n
 PasswordWindow.title=Vuze est\u00e1 protegido por contrase\u00f1a
 PasswordWindow.passwordprotected=Vuze est\u00e1 protegido por contrase\u00f1a.\nPara restaurar Vuze teclee aqu\u00ed por favor su contrase\u00f1a :
 Button.ok=&Aceptar
-TrackerChangerWindow.title=A\u00f1adir Rastreador (Tracker)
-TrackerChangerWindow.newtracker=Escriba la nueva url del Rastreador
 PeersView.discarded=Descartado
 PeersView.discarded.info=Datos que de alguna forma has recibido, pero no los necesitas, as\u00ed que los descartas.
 discarded=descartados
@@ -381,7 +376,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Borrar archivo .&torrent
 MyTorrentsView.menu.removeand.deletedata=Borrar &datos
 MyTorrentsView.menu.removeand.deleteboth=Borrar &ambos
 deletedata.title=Cuidado
-deletedata.message1=Va usted a eliminar LOS DATOS guardados en :\n
 deletedata.noprompt=No preguntarme de nuevo
 MainWindow.menu.file.configure=Asistente de con&figuraci\u00f3n...
 configureWizard.title=Asistente de configuraci\u00f3n
@@ -397,7 +391,6 @@ configureWizard.transfer.maxActiveTorrents=M\u00e1x. Activos
 configureWizard.transfer.maxDownloads=M\u00e1x. Descargas
 configureWizard.transfer.maxUploadsPerTorrent=M\u00e1x. env\u00edos por torrent
 configureWizard.nat.title=NAT / Puertos del servidor
-configureWizard.nat.message=Para obtener lo mejor de BitTorrent, se recomienda encarecidamente que sea totalmente accesible desde Internet. Esta herramienta te permite probar y/o cambiar los puertos que se usan para aceptar conexiones entrantes de los clientes.\n\nNOTA: Esta herramienta s\u00f3lo prueba las conexiones TCP. La BD Distribuida tambi\u00e9n necesita conexiones UDP entrantes, pero te avisar\u00e1 autom\u00e1ticamente si descubre un cortafuegos bloque\u00e1ndolas.\n\nNOTA: el  [...]
 configureWizard.nat.test=Probar
 configureWizard.nat.testing=Probando puertos
 configureWizard.nat.ok=OK
@@ -558,7 +551,6 @@ ConfigView.section.file.decoder.nodecoder=Ninguno
 IPChecker.external.service.no-ip.description=Proveedor del servicio DNS Din\u00e1mico y Est\u00e1tico\n(servicio 'check address' no disponible gratuitamente)
 ConfigView.section.tracker.publicenable=Activar .torrents externos
 ConfigView.label.playdownloadspeech=Aviso hablado al terminar una descarga
-ConfigView.label.playdownloadspeech.info=Los Servicios de Habla por el momento funcionan mejor en Ingl\u00e9s
 #
 # Tooltips
 #
@@ -730,8 +722,6 @@ plugin.sharing.download.remove.veto=Esta descarga es resultado de un recurso que
 ConfigView.section.tracker.main=Principal
 ConfigView.label.prioritizefirstpiece=Dar prioridad a la 1\u00aa parte del archivo(s)
 ConfigView.label.prioritizefirstpiece.tooltip=Intenta descargar primero el principio y el final del archivo.\nPara ayudar a la 'vista previa' temprana.
-ConfigView.section.file.confirm_data_delete=Confirmar la eliminaci\u00f3n de datos
-ConfigView.section.file.confirm_data_delete.tooltip=Confirmar el borrado de datos al usar 'Quitar y Borrar...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Al eliminar los datos, tambi\u00e9n permitir la eliminaci\u00f3n de los archivos enlazados en el exterior de la carpeta donde se guarda el torrent
 TrayWindow.menu.startalldownloads=&Iniciar Todas las Descargas
 SystemTray.menu.startalltransfers=&Iniciar Todas las Transferencias
@@ -1043,7 +1033,6 @@ ConfigView.pluginlist.whereToPutOr=Para los complementos compartidos usar esta c
 MainWindow.statusText.checking=Buscando Actualizaciones
 TableColumn.header.OnlyCDing4=Sirviendo
 TableColumn.header.OnlyCDing4.info=Tiempo sirviendo el torrent. No contabiliza lo compartido durante la descarga.
-ConfigView.section.style.alternateTablePainting=Usar el m\u00e9todo alternativo para dibujar las columnas gr\u00e1ficas (puede necesitarse reiniciar)
 UpdateWindow.status.restartMaybeNeeded=Podr\u00eda necesitarse un reinicio
 ConfigView.pluginlist.shared=compartido
 PeersView.host=Nombre del Servidor
@@ -1277,18 +1266,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Tama\u00f1o del Socket SO_SNDBU
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Establece el valor est\u00e1ndar de socket SO_SNDBUF value (en bytes), p.ej. tama\u00f1o de la ventana de env\u00edo TCP.\nVuze deja este valor sin ajustar por defecto, lo que significa que se usan los valores del SO en que corre.\nNOTA: Linux dobla el valor dado.
 ConfigView.section.connection.advanced.IPDiffServ=Valor DiffServ del paquete saliente (campo TOS)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Establece la parte DiffServ del campo tipo-de-servicio (TOS) en la cabecera IP de los paquetes salientes.\nSe pueden especificar valores hexadecimales precendiendoles con '0x', p.ej. 0x10.\nVuze deja este valor sin ajustar por defecto, lo que significa que se usan los valores del SO en que corre.\nNOTA: Las implementaciones de red subyacentes pueden ignorar este valor, as\u00ed que esta opci\u00f3n depende en gran medida de las ve [...]
-ConfigView.section.interface.confirm_torrent_removal=Mostrar un di\u00e1logo de confirmaci\u00f3n al eliminar un torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmar al eliminar un torrent desde la vista Mis Torrents.
-MyTorrentsView.confirm_torrent_removal=\u00bfSeguro que quieres eliminarlo?\n
 TableColumn.header.seed_to_peer_ratio=Proporci\u00f3n Sem/Cli
 TableColumn.header.seed_to_peer_ratio.info=Proporci\u00f3n semillas por cliente del enjambre
 PeersView.connected_time=Tiempo conectado
 PeersView.connected_time.info=Tiempo en total conectado con el cliente
-ConfigView.section.interface.display.add_torrents_silently=A\u00f1adir silenciosamente los torrents
-ConfigView.section.interface.display.add_torrents_silently.tooltip=A\u00f1ade las descargas torrent sin activar la ventana principal de Vuze
 TableColumn.header.maxdownspeed=Veloc. m\u00e1x. descarga
 TableColumn.header.maxdownspeed.info=La velocidad m\u00e1x. de descarga por torrent
-PeersGraphicView.title=Enjambre
+PeersGraphicView.title.full=Enjambre
 ConfigView.section.tracker.passwordwebhttpsonly=Permitir el acceso s\u00f3lo mediante HTTPS
 TableColumn.header.torrentpath=Ubicaci\u00f3n del Torrent
 TableColumn.header.torrentpath.info=Lugar del disco donde est\u00e1 el Torrent
@@ -1345,8 +1329,6 @@ UpdateWindow.restartLater=Reiniciar despu\u00e9s
 MainWindow.menu.file.restart=Reiniciar Vuze
 MainWindow.dialog.restartconfirmation.title=\u00bfReiniciar Vuze
 MainWindow.dialog.restartconfirmation.text=\u00bfSeguro que quieres reiniciar Vuze
-deletetorrent.message1=Est\u00e1 a punto de borrar el descriptor .TORRENT de :\n
-deletetorrent.message2=\n\u00bfQuiere seguir?
 ConfigView.label.prioritizemostcompletedfiles=Priorizar los archivos de m\u00e1s alta prioridad atendiendo a su % completado y el tama\u00f1o del archivo
 splash.plugin.init=Inicializando complemento:
 splash.plugin.UIinit=Inicializando complemento GUI: %1
@@ -1507,7 +1489,6 @@ MainWindow.menu.file.open.torrentfortracking=Archivo .torrent... (S\u00f3lo Rast
 MyTrackerView.date_added=A\u00f1adido
 ConfigView.section.tracker.portbackup=Puertos de respaldo (separados por ';')
 ConfigView.label.playfilespeech=Mensaje hablado al terminar un archivo
-ConfigView.label.playfilespeech.info=Por el momento, los servicios de habla funcionan mejor con el Ingl\u00e9s
 ConfigView.label.playfilefinished=Reproducir un sonido al terminar un archivo
 ConfigView.label.backupconfigfiles=Mantener una copia de seguridad de los archivos de configuraci\u00f3n.
 ConfigView.section.tracker.client.scrapesingleonly=Desactiva la suma de raspados por-rastreador (para casos en que los rastreadores dan el error 'URL too long' (414) (URL demasiado larga))
@@ -2105,21 +2086,11 @@ v3.mb.delPublished.title=Dejar de Compartir Contenido
 v3.mb.delPublished.text=CUIDADO: Esta acci\u00f3n NO eliminar\u00e1 su contenido publicado '%1' desde <A HREF="%2">%3</A> .\u005cn\nClic "Eliminar" solo si quieres que tu contenido siga publicado y descargable, pero quieres liberar tu ancho de banda. Aseg\u00farate de que el proceso de env\u00edo se ha completaqdo antes de hacerlo (<A HREF="%4">how</A>?).\u005cn\nClic "Cancelar" si quieres eliminar completamente tu contenido publicado desde %3, y usa el boton (X) del panel Contenido Publ [...]
 v3.mb.delPublished.delete=&Eliminar
 v3.mb.delPublished.cancel=&Cancelar
-v3.mb.openFile.text.known=Este contenido no est\u00e1 soportado a\u00fan por el Reproductor Vuze. Busque ayuda en la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Gu\u00eda de Reproducci\u00f3n</a> creada por la comunidad.\n\nEl archivo parece ser: %2 (%3)\n
-v3.mb.openFile.text.unknown=Este contenido no est\u00e1 soportado a\u00fan por el Reproductor Vuze. Busque ayuda en la <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Gu\u00eda de Reproducci\u00f3n</a> creada por la comunidad.\n\nExtensi\u00f3n del archivo : %2\n
-v3.mb.openFile.button.play=Reproducr
-v3.mb.openFile.button.cancel=Cancelar
-v3.mb.openFile.button.guide=Leer Gu\u00eda de Reproducci\u00f3n
-v3.mb.openFile.remember=Abrir siempre los archivos sin preguntarme
 v3.mb.PlayFileNotFound.title=Archivo No Encontrado
 v3.mb.PlayFileNotFound.text=Los archivos de '%1' est\u00e1n borrados o perdidos.
 v3.mb.PlayFileNotFound.button.remove=Eliminar de Vuze
 v3.mb.PlayFileNotFound.button.redownload=Volver a descargar Datos
 v3.mb.PlayFileNotFound.button.find=Buscar Manualmente..
-v3.mb.deletePurchased.title=Eliminar Contenido Comprado
-v3.mb.deletePurchased.text=Seguro que quieres eliminar el contenido  '%1'?\u005cn\nEs uno que compraste, o que se te exigi\u00f3 identificarte para poder descargarlo.
-v3.mb.deletePurchased.button.delete=&Eliminar
-v3.mb.deletePurchased.button.cancel=&Cancelar
 v3.topbar.menu.show.plugin=\u00c1rea de Complementos
 v3.topbar.menu.show.search=Buscar
 splash.initializeCore=Inicializando N\u00facleo
@@ -2307,10 +2278,6 @@ v3.splash.hookPluginUI=Enganchando el complemento GUI
 OpenTorrentWindow.mb.notTorrent.cannot.display=Los datos no se pueden mostrar correctamente
 MainWindow.menu.window.zoom.maximize=Maximizar
 MainWindow.menu.window.zoom.restore=Restaurar
-ImageResizer.image.too.small=La imagen proporcionada es demasiado peque\u00f1a, escoja por favor otra (que ha de ser al menos de %1 x %2)
-ImageResizer.title=Esta herramienta le permite ver el aspecto que va a tener su miniatura en la Plataforma Vuze
-ImageResizer.move.image=Mueva la imagen arrastr\u00e1ndola
-ImageResizer.move.image.with.slider=Mueva la imagen arrastr\u00e1ndola, redimensi\u00f3nela mediante la barra de desplazamiento inferior
 security.crypto.title=Acceso a la Clave de cifrado
 security.crypto.encrypt=Por favor, introduzca una contrase\u00f1a que proteja su clave de cifrado reci\u00e9n creada. No la olvide, ya que \u00a1no hay manera de recuperarla!
 security.crypto.decrypt=Introduzca por favor la contrase\u00f1a para desbloquear su clave de cifrado
@@ -2404,9 +2371,6 @@ metasearch.addtemplate.dup.title=Duplicar Plantilla
 metasearch.addtemplate.dup.desc=La plantilla de b\u00fasqueda %1 ya estaba instalada
 metasearch.export.select.template.file=Guardar Plantilla
 metasearch.import.select.template.file=Abrir Plantilla
-dialog.uiswitch.title=Pasar al GUI de Vuze
-dialog.uiswitch.text=Para poder usar esto, necesitas estar usando el GUI de Vuze.\n\nVuze necesitar\u00e1 reiniciarse.
-dialog.uiswitch.button=Pasar al GUI de Vuze
 azbuddy.tracker.enabled=Active 'Impulsar Amigos' para priorizar la descarga con sus amigos
 azbuddy.protocolspeed=Carga m\u00e1x del protocolo de amigo en KB/s
 v3.MainWindow.button.download=Descarga
@@ -2519,7 +2483,7 @@ Wizard.Subscription.optin.description=Con Suscripciones activadas, Vuze le mostr
 Wizard.Subscription.create.search=Buscar
 Wizard.Subscription.subscribe.library=Contenido en su Biblioteca
 Wizard.Subscription.subscribe.subscriptions=Subscripciones Relacionadas
-Wizard.Subscription.subscribe.library.empty=\u00bfNo hay subscripciones disponibles?\n \nBusca el bot\u00f3n de suscripci\u00f3n naranja brillante en Vuze HD Network.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Leer m\u00e1s</A>
+Wizard.Subscription.subscribe.library.empty=\u00bfNo hay subscripciones disponibles?\n \nBusca el bot\u00f3n de suscripci\u00f3n naranja brillante en Vuze HD Network.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Leer m\u00e1s</A>
 message.confirm.delete.title=Confirmar Eliminaci\u00f3n
 message.confirm.delete.text=\u00bfEst\u00e1 seguro de querer eliminar '%1'?
 externalLogin.wait=Cargando p\u00e1gina, por favor, espere...
diff --git a/org/gudy/azureus2/internat/MessagesBundle_eu.properties b/org/gudy/azureus2/internat/MessagesBundle_eu.properties
index 6859e5d..a7fb2bc 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_eu.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_eu.properties
@@ -1,173 +1,175 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=Torrent fitxategia...
-Main.parameter.usage=Erabilera: java org.gudy.azureus2.cl.Main [parameters] "file.torrent" "save path"
-Main.parameter.maxUploads=Aldibereko karga-kopuru maximoa
-Main.parameter.maxSpeed=Karga-abiadura maximoa byte/seg-tan
-MainWindow.menu.file=&Fitxategia
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=Torrent Agiria...
+Main.parameter.usage=Erabilera: java org.gudy.azureus2.cl.Nagusia [neurriak] "agiria.torrent" "gorde helburua"
+Main.parameter.maxUploads=Aldibereko igoera zenbateko gehiena
+Main.parameter.maxSpeed=Igera abiadura gehiena byte/seg-ko
+MainWindow.menu.file=&Agiria
 MainWindow.menu.file.open=&Ireki
-MainWindow.menu.file.create=&Torrent berria...
-MainWindow.menu.file.create.fromfile=&Fitxategi batetik
-MainWindow.menu.file.create.fromdir=&Direktorio batetik
-MainWindow.menu.file.export=&Esportatu XML torrent-a...
+MainWindow.menu.file.create=&Torrent Berria...
+MainWindow.menu.file.create.fromfile=&Agiri &batetik
+MainWindow.menu.file.create.fromdir=Zuzenbide &batetik
+MainWindow.menu.file.export=&Esportatu XML torrenta...
 MainWindow.menu.file.export.keybinding.mac=Meta+Shit+E
-MainWindow.menu.file.import=&Inportatu XML torrent-a...
-MainWindow.menu.file.closetab=Itxi &fitxa
-MainWindow.menu.file.closewindow=Itxi &leihoa
+MainWindow.menu.file.import=Inportatu &XML torrenta...
+MainWindow.menu.file.closetab=Itxi &Fitxa
+MainWindow.menu.file.closewindow=Itxi &Leihoa
 MainWindow.menu.file.exit=I&rten
-MainWindow.dialog.choose.file=Hautatu torrent fitxategia
-MainWindow.menu.file.folder=&Karpeta...
-MainWindow.dialog.choose.folder=Hautatu torrent fitxategien direktorioa
+MainWindow.dialog.choose.file=Hautatu torrent agiria
+MainWindow.menu.file.folder=&Agiritegia...
+MainWindow.menu.file.folder.keybinding=Meta+Shift+0
+MainWindow.dialog.choose.folder=Hautatu torrent agiriaren zuzenbidea
 MainWindow.menu.view=&Ikusi
 MainWindow.menu.view.show=Erakutsi
-MainWindow.menu.view.mytorrents=&Nire torrent-ak
-MainWindow.menu.view.open_global_transfer_bar=Transferentzien barra
+MainWindow.menu.view.mytorrents=&Liburutegia
+MainWindow.menu.view.open_global_transfer_bar=Eskualdaketa Barra
 MainWindow.menu.view.configuration=&Aukerak...
 MainWindow.menu.view.console=K&ontsola
-MainWindow.menu.view.allpeers=Pare guztiak
-MainWindow.menu.view.detailedlist=Zerrenda &xehea
-MainWindow.menu.closealldetails=Itxi xehetasun &guztiak
-MainWindow.menu.closealldownloadbars=Itxi deskarga-&barra guztiak
+MainWindow.menu.view.allpeers=Hartzaile Denak
+MainWindow.menu.view.detailedlist=&Zerrenda Zehatza
+MainWindow.menu.closealldetails=Itxi Xehetasun &guztiak
+MainWindow.menu.closealldownloadbars=Itxi Jeisketa-&Barra guztiak
 MainWindow.menu.language=&Hizkuntza
 ConfigView.section.language=Hizkuntza
 MainWindow.menu.window=&Leihoa
 MainWindow.menu.window.minimize=&Ikonotu
+MainWindow.menu.window.zoom=&Zooma
 MainWindow.menu.window.alltofront=Mugitu denak &aurrera
-MainWindow.menu.help=La&guntza
-MainWindow.menu.help.about=Vuze-ri buruz
-MainWindow.menu.torrent=T&orrent-a
+MainWindow.menu.help=&Laguntza
+MainWindow.menu.help.about=Vuzeri buruz
+MainWindow.menu.torrent=T&orrenta
 MainWindow.about.title=Honi buruz
-MainWindow.about.section.developers=Garatzaileak
-MainWindow.about.section.translators=Itzultzaileak
 MainWindow.about.section.system=Sistema
-MainWindow.about.internet.homepage=Vuze-ren webgunea
-MainWindow.about.internet.sourceforge=Proiektuaren webgunea Sourceforge-n
-MainWindow.about.internet.sourceforgedownloads=Sourceforge-ko deskargak
-MainWindow.about.internet.bugreports=Akatsen jakinarazpena
-MainWindow.about.internet.forumdiscussion=Foroak
-MainWindow.about.internet.wiki=Vuze-ren wikiko MEG-ak
-MainWindow.dialog.choose.savepath=Hautatu gordetze-bidea
-MainWindow.dialog.choose.savepath_forallfiles=Hautatu fitxategi GUZTIEN gordetze-bidea
+MainWindow.about.section.internet=Interneta
+MainWindow.about.internet.homepage=Vuzeren Webgunea
+MainWindow.about.internet.sourceforge=Sourceforge Egitasmoaren Webgunea
+MainWindow.about.internet.bugreports=Akatsen Jakinarazpena
+MainWindow.about.internet.forumdiscussion=Eztabaidaguneak
+MainWindow.about.internet.wiki=Vuzeren Wiki FAQ
+MainWindow.dialog.choose.savepath=Hautatu gordetze helburua
+MainWindow.dialog.choose.savepath_forallfiles=Hautatu agiri GUZTIEN gordetze helburua
 MainWindow.status.latestversion=Azkena
 MainWindow.status.latestversion.clickupdate=Egin klik eguneratzeko
 MainWindow.status.unknown=ezezaguna
 MainWindow.status.checking=egiaztatzen
-MyTorrentsView.mytorrents=Nire torrent-ak
+MyTorrentsView.mytorrents=Liburutegia
 TableColumn.header.name=Izena
-TableColumn.header.size=Tamaina
+TableColumn.header.size=Neurria
 TableColumn.header.done=Egina
-TableColumn.header.done.info=Uneko atazatik egindako ehunekoa
+TableColumn.header.done.info=Uneko eginkizunetik buruturiko ehunekoa
 TableColumn.header.status=Egoera
-TableColumn.header.status.info=Torrent-a egiten ari dena
-TableColumn.header.seeds=Aleak
-TableColumn.header.seeds.info=Konektatutako # ale (# ale guztira)
-TableColumn.header.peers=Pareak
-TableColumn.header.peers.info=# pare konektaturik (# pare guztira)
-TableColumn.header.completed=Osatua
-TableColumn.header.completed.info=Torrent-aren deskarga amaitu duten pareen #, aztarnariaren arabera
-TableColumn.header.downspeed=Deskarga-abiadura
-TableColumn.header.upspeed=Karga-abiadura
-TableColumn.header.eta=GDD
-TableColumn.header.tracker=Aztarnariaren egoera
-TableColumn.header.tracker.info=Aztarnariaren egoera
-TableColumn.header.trackernextaccess=Hurrengo aztarnariaren atzipena
+TableColumn.header.status.info=Torrenta egiten ari dena
+TableColumn.header.seeds=Emaleak
+TableColumn.header.seeds.info=Elkarketatutako emale Zenbatekoa (Zenbat emale guztira)
+TableColumn.header.peers=Hartzaileak
+TableColumn.header.peers.info=Zenbat hartzaile elkarketaturik (Zenbat hartzaile guztira)
+TableColumn.header.completed=Osatuta
+TableColumn.header.completed.info=Torrentaren jeisketa amaitu duten hartzaileak  #, aztarnariaren arabera
+TableColumn.header.downspeed=Jeisketa Abiadura
+TableColumn.header.upspeed=Igoera abiadura
+TableColumn.header.eta=UED
+TableColumn.header.tracker=Aztarnari Egoera
+TableColumn.header.tracker.info=Aztarnariaren Egoera
+TableColumn.header.trackernextaccess=Hurrengo Aztarnariaren Atzipena
 TableColumn.header.trackernextaccess.info=Hurrengo aztarnariaren atzipena noiz gertatuko den
 TableColumn.header.priority=Lehentasuna
-TableColumn.header.priority.info=Torrent-ari ematen zaion banda-zabalera finkatzen du
-TableColumn.header.seeds.fullcopycalc= %1 parek onartutako %2 kopia oso
-MyTorrentsView.menu.showdetails=Erakutsi &xehetasunak
-MyTorrentsView.menu.showdownloadbar=Erakutsi deskarga-&barra
-MyTorrentsView.menu.open=&Ireki fitxategia
-MyTorrentsView.menu.setpriority=Ezarri &lehentasuna
-MyTorrentsView.menu.setpriority.high=&Altua
-MyTorrentsView.menu.setpriority.low=&Baxua
+TableColumn.header.priority.info=Torrentari ematen zaion banda zabalera finkatzen du
+TableColumn.header.seeds.fullcopycalc=%1 hartzailek onartutako %2 kopia oso
+MyTorrentsView.menu.showdetails=Erakutsi &Xehetasunak
+MyTorrentsView.menu.showdownloadbar=Erakutsi Jeisketa &Barra
+MyTorrentsView.menu.open=&Ireki Agiria
+MyTorrentsView.menu.setpriority=Ezarri &Lehentasuna
+MyTorrentsView.menu.setpriority.high=&Handia
+MyTorrentsView.menu.setpriority.low=&Txikia
 MyTorrentsView.menu.start=&Hasi
-MyTorrentsView.menu.stop=&Gelditu
+MyTorrentsView.menu.stop=Geld&itu
 MyTorrentsView.menu.remove=&Ezabatu
-MyTorrentsView.menu.changeTracker=Gehitu aztarnariaren &URLa
+MyTorrentsView.menu.changeTracker=Gehitu aztarnariaren &URL-a
 TrayWindow.menu.exit=I&rten
-TrayWindow.menu.show=Erakutsi &Vuze
+TrayWindow.menu.show=&Erakutsi Vuze
 SystemTray.menu.exit=I&rten
-SystemTray.menu.closealldownloadbars=Itxi deskarga-&barra guztiak
-SystemTray.menu.open_global_transfer_bar=Erakutsi transferentzien barra
-SystemTray.menu.show=Erakutsi &Vuze
-PeersView.ip=IPa
-PeersView.ip.info=Parearen IPa
+SystemTray.menu.closealldownloadbars=Itxi  &Jeisketa Barra Guztiak
+SystemTray.menu.open_global_transfer_bar=Erakutsi Eskualdaketa Barra
+SystemTray.menu.show=&Erakutsi Vuze
+PeersView.ip=IP-a
+PeersView.ip.info=Hartzailearen IP-a
 PeersView.port=Ataka
 PeersView.port.info=Erabiltzen ari den ataka
-PeersView.T.info=L (lokala): zuk ezarri duzu konexioa, R (urrunekoa): pareak ezarri du konexioa.
-PeersView.T.L.tooltip=Zuk ezarri duzu konexioa
-PeersView.T.R.tooltip=Pareak ezarri du konexioa
-PeersView.I1=I (parearen interesekoa)
-PeersView.I1.info=Beste pareak duena interesatzen zaizu?
-PeersView.C1=C (Pareak buxatua)
-PeersView.C1.info=Pareak deskarga galarazten badizu
+PeersView.T=ELK
+PeersView.T.info=L (tokikoa): zuk ezarri duzu elkarketa, R (hurrunekoa): hartzaileak ezarri du elkarketa.
+PeersView.T.L.tooltip=Zuk ezarri duzu elkarketa
+PeersView.T.R.tooltip=Hartzaileak ezarri du elkarketa
+PeersView.I1=I (Interesgarria hartzailearentzat)
+PeersView.I1.info=Interesaturik zaude beste hartzaile batek duen agirian?
+PeersView.C1=IT (Hartzaileak itota)
+PeersView.C1.info=Hartzaileak jeisketa galarazten badizu
 PeersView.pieces=Atalak
-PeersView.downloadspeed=Deskarga-abiadura
-PeersView.download=Deskarga
-PeersView.I2=I (parearentzat interesgarria)
-PeersView.I2.info=Parea zure fitxategiren batean interesaturik dago?
-PeersView.C2=C (parea buxatzen)
-PeersView.C2.info=Pareari deskarga galarazten badiozu
-PeersView.uploadspeed=Karga-abiadura
-PeersView.uploadspeed.info=Zure karga-abiadura parearekiko
-PeersView.upload=Kargatu
-PeersView.upload.info=Zure karga-abiadura osoa parearekiko
-PeersView.statup=Batez besteko karga
-PeersView.statup.info=Parearen karga-abiaduraren balio estimatua
-PeersView.S.info=Errefusatua: Pare bat eskuz "errefusa" daiteke, edo automatikoki (datuak abiadura motelegian bidaltzeagatik)
-PeersView.downloadspeedoverall=Deskarga-abiadura guztira
-PeersView.optunchoke=Auk. Ezabatu buxadura
+PeersView.downloadspeed=Jeisketa Abiadura
+PeersView.download=Behera
+PeersView.download.info=Hartzailearengandik jeitsitakoa guztia
+PeersView.I2=I (Interesgarria hartzailearentzat)
+PeersView.I2.info=Hartzailea zure agiriren batean interesaturik dago?
+PeersView.C2=IT (Hartzailea itotzen)
+PeersView.C2.info=Hartzaileari jeisketa galarazten badiozu
+PeersView.uploadspeed=Igoera Abiadura
+PeersView.uploadspeed.info=Zure igoera abiadura hartzailearekiko
+PeersView.upload=Igo
+PeersView.upload.info=Zure igoera osoa hartzailearekiko
+PeersView.statup=Bataz-besteko Igoera
+PeersView.statup.info=Hartzailearen igoera abiaduraren ustezko balioa
+PeersView.S.info=Errefusatua: Hartzaile bat eskuz "errefusa" daiteke, edo berezgaitasunez (datuak abiadura geldoegian bidaltzeagatik)
+PeersView.downloadspeedoverall=Jeisketa Abiadura Guztira
+PeersView.optunchoke=Auk. Itogabe
 PeersView.client=Bezeroa
-PeersView.client.info=Parea erabiltzen ari den BT bezero-mota
-PeersView.menu.snubbed=&Errefusatua
-PeersView.title.short=Pareak
-PeersView.title.full=Pareak
-AllPeersView.title.full=Pare guztiak
-ConfigView.section.files=Fitxategiak
-ConfigView.label.usefastresume=Erabili berrabiaratze azkarreko aukera
-ConfigView.label.incrementalfile=Gaitu fitxategien sorrera inkrementala [beharrezkoa Linux-en FAT32 erabiliz gero]
-ConfigView.label.defaultsavepath=Direktorio lehenetsian gorde
-ConfigView.button.browse=&Arakatu...
-ConfigView.dialog.choosedefaultsavepath=Adierazi lehenetsitako gordetze-direktorioa
-ConfigView.section.server=Konexioa
+PeersView.client.info=Hartzaileak erabiltzen duen BT bezero mota 
+PeersView.menu.snubbed=&Errefusatuta
+PeersView.title.short=Hartzaileak
+PeersView.title.full=Hartzaileak
+AllPeersView.title.full=Hartzaile Guztiak
+ConfigView.section.files=Agiriak
+ConfigView.label.usefastresume=Erabili Berrekite Azkarreko aukera
+ConfigView.label.incrementalfile=Gaitu agirien sorrera inkrementala  [beharrezkoa Linux-en FAT32 erabiliz gero]
+ConfigView.label.defaultsavepath=Datu zuzenbide lehenetsian gorde
+ConfigView.button.browse=&Bilatu...
+ConfigView.dialog.choosedefaultsavepath=Mesedez adierazi lehenetsitako gordetze zuzenbidea
+ConfigView.section.server=Elkarketa
 ConfigView.section.global=Orokorra
-ConfigView.label.disconnetseed=Deskonektatu aleak aletzean
-ConfigView.label.switchpriority=Aletzean lehentasun baxura aldatu automatikoki
-ConfigView.label.maxdownloads=Aldibereko deskarga-kopuru maximoa [0: mugagabea]\n - Ezin da izan torrent aktiboen kopuru maximoa baino altuagoa
-ConfigView.label.maxdownloads.tooltip=Hemen erabaki duzun kopurua aktiboki deskargatu ahal izango duzu beti, salbuespen batekin.\nLehentasun handiena duen torrent osatu batek deskarga aktibo baten lekua har dezake guztiz beharrezkoa bada.
-ConfigView.label.maxactivetorrents=Torrent aktiboen kopuru maximoa [0: mugagabea]\n - Torrent berriak ez dira abian jarriko gehiago deskargatzen/aletzen ari bazara
-ConfigView.label.priorityExtensions=Eman lehentasuna automatikoki fitxategi hauei: \n - adib: .txt;.nfo;.jpg
-ConfigView.section.transfer=Transferentzia
-ConfigView.label.maxuploads=Karga-zirrikituen kopuru maximo lehenetsia torrent bakoitzeko
-ConfigView.label.maxuploadspeed=Karga-abiadura maximoa guztira KB/s-tan [0: mugagabea]
-ConfigView.label.saveresumeinterval=Eguneratu berrekite-datuak
+ConfigView.label.disconnetseed=Eten emaletzak emaletzean
+ConfigView.label.switchpriority=Berez-aldatu lehentasun apalera emaletzean
+ConfigView.label.maxdownloads=Gehienezko jeisketa aldiberean [0: mugagabea]\n - Ezin da izan torrent eraginduena baino handiagoa
+ConfigView.label.maxdownloads.tooltip=Hemen erabaki duzun kopurua eraginkortasunez jeitsi ahal izango duzu beti, salbuespen batekin.\nLehentasun handiena duen torrent osatu batek jeisketa eraginkor baten lekua har dezake guztiz beharrezkoa bada.
+ConfigView.label.maxactivetorrents=Gehienezko Torrent lanean [0: mugagabea]\n - Torrent berriak ez dira abian jarriko gehiago jeisten/emaletzen ari bazara
+ConfigView.label.priorityExtensions=Berez-lehenetsi agiri mota hauek: \n - adib: .txt;.nfo;.jpg
+ConfigView.section.transfer=Eskualdaketa
+ConfigView.label.maxuploads=Gehienezko igoera ahoak lehenetsitako torrent bakoitzeko
+ConfigView.label.maxuploadspeed=KB/s gehienezko abiadura igoera globalentzat [0: mugagabea]
+ConfigView.label.saveresumeinterval=Eguneratu berrekite datuak betik
 ConfigView.unlimited=Mugagabea
-ConfigView.section.display=Bistaratzea
-ConfigView.label.opendetails=Ireki automatikoki xehetasunen fitxa
-ConfigView.label.openbar=Ireki automatikoki deskarga-barra
-ConfigView.label.use_old_speed_menus=Erabili estilo zaharreko abiadura-menuak [aplikazioa berrabiarazi behar da]
-ConfigView.label.closetotray='Itxi' aukerak sistemaren erretilura ikonotzen du
-ConfigView.label.minimizetotray='Ikonotu' aukerak sistemaren erretilura ikonotzen du
+ConfigView.section.display=Ikusi
+ConfigView.label.opendetails=Berez ireki xehetasunen fitxa
+ConfigView.label.openbar=Berez irekitze jeisketa barra
+ConfigView.label.use_old_speed_menus=Erabili estilo zaharreko abiadura menuak [birrabiaraztea beharrezkoa]
+ConfigView.label.closetotray=Itxik Sistemaren Erretilura ikurtzen du
+ConfigView.label.minimizetotray='Ikurtu' aukerak Sistemaren Erretilura ikurtzen du
 ConfigView.section.general=Orokorra
 ConfigView.section.start=Hasi
-ConfigView.label.showsplash=Erakutsi splash pantaila
-ConfigView.label.autoupdate=Ireki berritze-leihoa bertsio berri bat eskuragarri dagoenean
-ConfigView.label.openconsole=Ireki kontsola abioan
-ConfigView.label.openconfig=Ireki aukeren leihoa abioan
-ConfigView.label.startminimized=Abiatu ikonotuta
-ConfigView.label.ircwiki=Irakurri http://azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.label.showsplash=Erakutsi zipriztin ikusleihoa
+ConfigView.label.autoupdate=Ireki berritze leihoa bertsio berri bat eskuragarri dagoenean
+ConfigView.label.openconsole=Ireki kontsola abiatzean
+ConfigView.label.openconfig=Ireki aukeren leihoa abiatzean
+ConfigView.label.startminimized=Hasi ikonotuta
+ConfigView.label.ircwiki=Mesedez irakurri http://azureuswiki.com/index.php/Rules_for_IRC
 ConfigView.label.ircserver=Zerbitzaria
 ConfigView.label.ircchannel=Kanala
-ConfigView.label.irclogin=Ezizena
-ConfigView.group.irctitle=IRC konfigurazioa
-ConfigView.boolean.ircsendinfo=Baimendu zure ezarpenak bidaltzea (modu anonimoan)\n kanal-eragileei, laguntza eman ahal diezazuten
-ConfigView.boolean.irclog=Gaitu kanal-jardueraren datuen erregistratzea (IRC_log.htm barnean)
+ConfigView.label.irclogin=Izenordea
+ConfigView.group.irctitle=IRC Ezarpenak
+ConfigView.boolean.ircsendinfo=Baimendu zure ezarpenak bidaltzea (modu izengabean)\n kanal eragileei, laguntza eman ahal diezazuten
+ConfigView.boolean.irclog=Gaitu kanal jardueraren datuen erregistratzea (IRC_log.htm)
 ConfigView.section.security=Segurtasuna
-ConfigView.label.password=Babestu Vuze pasahitza erabiliz\n - Abioan eta ikonotutako leihoa leheneratzean eskatuko da.
-ConfigView.label.passwordconfirm=Pasahitza (baieztapena)
-ConfigView.label.passwordmatch=Pasahitza aktibatua:
+ConfigView.label.password=Babestu Vuze sar-hitza erabiliz\n - Ikonotutakoan eta hasterakoan galdetuko du.
+ConfigView.label.passwordconfirm=Sar-hitza (baieztatu)
+ConfigView.label.passwordmatch=Sar-hitza eraginda:
 ConfigView.label.passwordmatchnone=Ez
-ConfigView.label.passwordmatchno=Ez / Pasahitza ez da zuzena
+ConfigView.label.passwordmatchno=Ez / Sar-hitza ez da zuzena
 ConfigView.label.passwordmatchyes=Bai
 ConfigView.button.save=Gorde
 ConfigView.title.short=Aukerak
@@ -175,556 +177,3104 @@ ConfigView.title.full=Aukerak
 ConfigView.title.full._mac=Hobespenak
 ConsoleView.title.short=Kontsola
 ConsoleView.title.full=Kontsola
-FileItem.write=idatzi
-FileItem.read=irakurri
-FileItem.normal=normala
-FileItem.high=altua
-FileItem.donotdownload=Ez deskargatu
+FileItem.write=Idatzi
+FileItem.read=Irakurri
+FileItem.normal=Arrunta
+FileItem.high=Handia
+FileItem.donotdownload=Ez jeitsi
 FileItem.delete=Ezabatu
 FilesView.name=Izena
 FilesView.name.fastRename=Berrizendatze azkarra
-FilesView.size=Tamaina
-FilesView.done=Egina
-FilesView.firstpiece=Lehen atala #
-FilesView.numberofpieces=# atal
+FilesView.size=Neurria
+FilesView.done=Eginda
+FilesView.%=% 
+FilesView.firstpiece=Lehen atala 
+FilesView.numberofpieces=Zenbat atal
 FilesView.pieces=Atalak
 FilesView.mode=Modua
 FilesView.priority=Lehentasuna
 FilesView.menu.open=&Ireki
-FilesView.menu.setpriority=Ezarri &lehentasuna
-FilesView.menu.setpriority.high=&Altua
-FilesView.menu.setpriority.normal=&Normala
-FilesView.menu.setpriority.skipped=&Ez deskargatu
-FilesView.title.short=Fitxategiak
-FilesView.title.full=Fitxategiak
-GeneralView.section.downloaded=Deskargatua
-GeneralView.label.status.file=Fitxategiaren egoera
-GeneralView.label.status.pieces=Atalen egoera
+FilesView.menu.setpriority=&Ezarri Lehentasuna
+FilesView.menu.setpriority.high=&Handia
+FilesView.menu.setpriority.normal=&Arrunta
+FilesView.menu.setpriority.skipped=&Ez jeitsi
+FilesView.title.short=Agiriak
+FilesView.title.full=Agiriak
+GeneralView.section.downloaded=Jeitsita
+GeneralView.label.status.file=Agiriaren Egoera
+GeneralView.label.status.pieces=Atalen Egoera
 GeneralView.section.availability=Eskuragarritasuna
-GeneralView.label.status.pieces_available=Atalen egoera
-GeneralView.section.transfer=Transferentzia
-GeneralView.section.info=Informazioa
+GeneralView.label.status.pieces_available=Atalen Egoera
+GeneralView.section.transfer=Eskualdaketa
+GeneralView.section.info=Argibideak
 GeneralView.title.short=Orokorra
 GeneralView.title.full=Orokorra
 GeneralView.label.timeelapsed=Igarotako denbora: 
-GeneralView.label.remaining=Falta dena: 
-GeneralView.label.downloaded=Deskargatua: 
-GeneralView.label.downloadspeed=Deskarga-abiadura: 
-GeneralView.label.maxuploads=Karga-zirrikituak: 
-GeneralView.label.maxuploads.tooltip=Une jakin batean buxadura ezabatuko zaien pare-kopuru maximoa
-GeneralView.label.uploaded=Kargatua: 
-GeneralView.label.uploadspeed=Karga-abiadura: 
-GeneralView.label.seeds=Aleak: 
-GeneralView.label.peers=Pareak:
+GeneralView.label.remaining=Gelditzen dena: 
+GeneralView.label.downloaded=Jeitsita:
+GeneralView.label.downloadspeed=Jeisketa Abiadura:
+GeneralView.label.maxuploads=Igoera Ahoak:
+GeneralView.label.maxuploads.tooltip=Une jakin batean itogabe izango diren gehienezko hartzaile zenbatekoa.
+GeneralView.label.uploaded=Igota:
+GeneralView.label.uploadspeed=Igoera Abiadura:
+GeneralView.label.seeds=Emaleak: 
+GeneralView.label.peers=Hartzaileak:
 GeneralView.label.completed=Osatua: 
-GeneralView.label.totalspeed=Erlekumearen abiadura:
-GeneralView.label.totalspeed.tooltip=Zurekin konektatuta dauden bezero guztien abiadura osoa (eta batez bestekoa).
-GeneralView.label.averagespeed=batez bestekoa
+GeneralView.label.totalspeed=Erletaldearen Abiadura:
+GeneralView.label.totalspeed.tooltip=Zurekin elkarketatuta dauden bezero guztien abiadura osoa (eta bataz-bestekoa).
+GeneralView.label.averagespeed=bataz-bestekoa
 GeneralView.label.filename=Izena: 
-GeneralView.label.totalsize=Tamaina osoa: 
+GeneralView.label.totalsize=Neurria Guztira:
 GeneralView.label.savein=Gorde hemen: 
-GeneralView.label.hash=Hash-a: 
-GeneralView.label.numberofpieces=# atal 
-GeneralView.label.size=Tamaina: 
-GeneralView.label.tracker=Aztarnariaren egoera: 
+GeneralView.label.hash=Hasha: 
+GeneralView.label.numberofpieces=Zenbat atal :
+GeneralView.label.size=Neurria:
+GeneralView.label.tracker=Aztarnariaren Egoera: 
 GeneralView.label.updatein=Eguneratu hemen: 
-GeneralView.label.trackerurl=Aztarnariaren URLa:
+GeneralView.label.trackerurl=Aztarnariaren URL-a:
 GeneralView.label.trackerurlupdate=Eguneratu aztarnaria
-GeneralView.label.comment=Torrent-aren iruzkina:
+GeneralView.label.comment=Torrentaren iruzkina:
 GeneralView.label.user_comment=Erabiltzailearen iruzkina: 
 GeneralView.label.status=Egoera:
 ManagerItem.waiting=Itxaroten
 ManagerItem.allocating=Esleitzen
 ManagerItem.checking=Egiaztatzen
-ManagerItem.ready=Torrent-ak ilaran jar daitezen itxaroten
-ManagerItem.downloading=Deskargatzen
-ManagerItem.seeding=Aletzen
+ManagerItem.ready=Torrenta(k) lerroan jar daitezen itxaroten
+ManagerItem.downloading=Jeisten
+ManagerItem.seeding=Emaletzen
 ManagerItem.stopped=Geldituta
-ManagerItem.error=Errorea
-ManagerItem.high=altua
-ManagerItem.low=baxua
+ManagerItem.error=Akatsa
+ManagerItem.high=Handia
+ManagerItem.low=Txikia
 MinimizedWindow.name=Izena:
-MinimizedWindow.all_transfers=Vuze-ren transferentziak
-PiecesView.size=Tamaina
-PiecesView.numberofblocks=Blokeen #
+MinimizedWindow.all_transfers=Vuze Eskualdaketak
+PiecesView.#=Zenb.
+PiecesView.size=Neurria
+PiecesView.numberofblocks=Bloke Zenbatekoa
 PiecesView.blocks=Blokeak
 PiecesView.completed=Osatua
 PiecesView.availability=Eskuragarritasuna
-PiecesView.reservedby=Erreserbatua
-PiecesView.writers=Blokearen emaileak
+PiecesView.reservedby=Gordeta
+PiecesView.writers=Blokearen Emaileak
 PiecesView.title.short=Atalak
 PiecesView.title.full=Atalak
-SystemTray.tooltip.seeding=%1 aletzen,
-SystemTray.tooltip.downloading=%1 deskargatzen,
-DownloadManager.error.filenotfound=Ez da aurkitu fitxategia
-DownloadManager.error.fileempty=Torrent fitxategia hutsik dago
-DownloadManager.error.filetoobig=Torrent fitxategia handiegia da
-DownloadManager.error.filewithouttorrentinfo=Ez da torrent informaziorik aurkitu fitxategian
-DownloadManager.error.unsupportedencoding=Onartzen ez den kodeketa
-DownloadManager.error.ioerror=IO errorea
-DownloadManager.error.sha1=(SHA1) errorea, ez dago algoritmo hori
-PeerManager.status.offline=Konexio-errorea
+SystemTray.tooltip.seeding=%1 emaletzen,
+SystemTray.tooltip.downloading=%1 jeisten,
+DownloadManager.error.filenotfound=Agiria Ez da Aurkitu
+DownloadManager.error.fileempty=Torrent agiria hutsik dago
+DownloadManager.error.filetoobig=Torrent agiria handiegia da
+DownloadManager.error.filewithouttorrentinfo=Ez da torrent argibiderik aurkitu agirian
+DownloadManager.error.unsupportedencoding=Kodeaketa Okerra
+DownloadManager.error.ioerror=IO Akatsa
+DownloadManager.error.sha1=(SHA1) akatsa , ez dago Algoritmoa
+PeerManager.status.offline=Elkarketa Akatsa
+PeerManager.status.ok=Ongi
 PeerManager.status.checking=Egiaztatzen
 PeerManager.status.finished=Amaitua
-PeerManager.status.finishedin=Amaitze-denbora
-MainWindow.upgrade.assistant=Berritze-laguntzailea
-MainWindow.upgrade.newerversion=Vuze-ren bertsio berri bat dago eskuragarri
-MainWindow.upgrade.explanation=Laguntzaile honek bertsio berria deskargatuko du zure ordenagailuko Vuze karpetara eta Vuze berrabiaraziko du
-MainWindow.upgrade.explanation.manual=Eskuz eguneratu dezakezu aplikazioa Vuze itxiz, bertsio berria deskargatuz eta Vuze berrabiaraziz
-MainWindow.upgrade.step1=1. urratsa: Deskargatu bertsio berria
-MainWindow.upgrade.step2=2. urratsa: Bertsio hau itxi eta Vuze-ren bertsio berria berrabiarazi
-MainWindow.upgrade.hint1=Aholkua:\t Amaitu botoia sakatuz dena automatikoki egingo da
-MainWindow.upgrade.hint2=Aholkua:\tGero Vuze itxi nahi baduzu, sakatu Utzi eta\n\titxi ondoren berrizendatu Azureus2-new.jar eta deitu Azureus2.jar
-MainWindow.upgrade.error.downloading.hint=Errorea:\tEzin izan da bertsio berria deskargatu, mesedez eguneratu eskuz
-MainWindow.upgrade.section.info=Bertsio berria eskuragarri
-MainWindow.upgrade.section.manual=Eskuzko eguneraketa 
-MainWindow.upgrade.section.automatic=Eguneraketa automatikoa
-MainWindow.upgrade.tooltip.progressbar=Deskargaren aurrerapena hemen erakusten da
+PeerManager.status.finishedin=Amaitzeko denbora
+MainWindow.upgrade.assistant=Berritze Laguntzailea
+MainWindow.upgrade.newerversion=Vuzeren bertsio berri bat dago eskuragarri
+MainWindow.upgrade.explanation=Laguntzaile honek bertsio berria jeitsiko du zure ordenagailuko Vuze agiritegira eta Vuze berrabiaraziko du
+MainWindow.upgrade.explanation.manual=Eskuz eguneratu dezakezu Vuze itxiz, bertsio berria jeitsiz eta Vuze berrabiaraziz
+MainWindow.upgrade.step1=1. urratsa: Jeitsi bertsio berria
+MainWindow.upgrade.step2=2. urratsa: Bertsio hau itxi eta Vuzeren bertsio berria berrabiarazi
+MainWindow.upgrade.hint1=Aholkua:\t Amaitu botoia sakatuz dena berezgaitasunez egingo da
+MainWindow.upgrade.hint2=Aholkua:\u005cGero Vuze itxi nahi baduzu, sakatu Ezeztatu eta\n\u005ci\txi ondoren Azureus2-new.jar birrizendatu Azureus2.jar 
+MainWindow.upgrade.error.downloading.hint=Akatsa:\tEzin izan da bertsio berria jeitsi, mesedez eguneratu eskuz
+MainWindow.upgrade.section.info=Bertsio Berria Eskuragarri
+MainWindow.upgrade.section.manual=Eskuzko Eguneraketa 
+MainWindow.upgrade.section.automatic=Berezgaitasunezko Eguneraketa
+MainWindow.upgrade.tooltip.progressbar=Jeisketaren garapena hemen erakusten da
 Button.next=Hurrengoa
 Button.finish=Amaitu
-Button.cancel=&Utzi
+Button.cancel=&Ezeztatu
 LocaleUtil.title=Hautatu kodeketa
-LocaleUtil.section.chooseencoding=Hautatu kodeketa fitxategi-izenerako
-LocaleUtil.label.chooseencoding=Hautatu kodeketarik egokiena
-LocaleUtil.label.hint.doubleclick=Aholkua: lerro batean bi aldiz klik eginez kodeketa hautatzen da eta leihoa ixten da
-LocaleUtil.label.checkbox.rememberdecision=Gogoratu erabakia gainerako fitxategi-izenetarako
-LocaleUtil.column.encoding=Kodeketa
-IrcClient.defaultChannel=#Azureus-erabiltzaileak
-IrcClient.copyright=PircBot Java IRC APIa erabiltzen - http://www.jibble.org/pircbot.php
-IrcClient.connecting=Konektatzen hona:
-IrcClient.connected=Konektatua hona:
-IrcClient.joining=Sartzen
+LocaleUtil.section.chooseencoding=Hautatu kodeketa agiri izenerako
+LocaleUtil.label.chooseencoding=Hautatu kodeaketarik egokiena
+LocaleUtil.label.hint.doubleclick=Aholkua: lerro batean bi aldiz klik eginez kodeketa hautatzen da eta leihoa isten da
+LocaleUtil.label.checkbox.rememberdecision=Gogoratu erabakia gainerako agiri izenetarako
+LocaleUtil.column.encoding=Kodeaketa
+IrcClient.defaultChannel=#Azureus-Erabiltzaileak
+IrcClient.copyright=PircBot Java IRC API erabiltzen - http://www.jibble.org/pircbot.php
+IrcClient.connecting=Elkarketatzen hona:
+IrcClient.connected=Elkarketaturik hona:
+IrcClient.joining=Bategiten
 IrcClient.channel=Kanala
-IrcClient.joined=sartuta
-IrcClient.error=Errorea
-IrcClient.hasjoined=sartu da
-IrcClient.haskicked=kanporatu dute
-IrcClient.hasleft=utzi du
-IrcClient.nowknown=orain honela ezagutzen dute:
+IrcClient.joined=bat eginda
+IrcClient.error=Akatsa
+IrcClient.hasjoined=bat egin du
+IrcClient.haskicked=kanporatua izan da
+IrcClient.hasleft=utzi egin du
+IrcClient.nowknown=orain honela ezagutua da:
 IrcClient.topicforchannel=Gaia kanalerako
-IrcClient.disconnected=Deskonektatua hemendik:
-IrcClient.noNick=Ez da goitizenik adieraz. Mesedez joan 'Aukerak' atalera
-IrcView.actionnotsupported=Ekintza hau ez dago onartua
+IrcClient.disconnected=Etenda hemendik:
+IrcClient.noNick=Ez da Goitizenik Adierazi. Mesedez joan 'Aukerak' Ikusi
+IrcView.actionnotsupported=Ekintza hau ez dago onartuta
 IrcView.clientsconnected=erabiltzaileak
 IrcView.privateto=Hona:
 IrcView.privatefrom=Hemendik
 IrcView.noticefrom=Oharra:
-IrcView.errormsg=Sintaxi akastuna /msg : /msg erabiltzaile-testuan
-IrcView.help=Baliozko aginduak hauek dira:\n . /help: mezu hau erakusten du\n . /nick | /name: zure izena aldatzen du \n . /me action: ekintza bat bidaltzen du \n . /msg nick message: mezu pribatua bidaltzen dio <nick>-(e)ri\n . /r message: azken mezu pribatuari erantzuten dio\n . /join #channelB (ez egin klik hemen, adibide bat da): uneko kanaletik channelB-ra aldatzen du
-PasswordWindow.title=Vuze blokeatuta dago
-PasswordWindow.passwordprotected=Vuze pasahitzez babestuta dago.\nVuze-ren leihoa erakusteko, mesedez sartu zure pasahitza hemen:
-TrackerChangerWindow.title=Gehitu aztarnaria
-TrackerChangerWindow.newtracker=Sartu aztarnari berriaren URLa
+IrcView.errormsg=Hitzjoskera Okerra /msg : /msg erabiltzaile idatzian
+IrcView.help=Baliozko aginduak hauek dira:\n . /help: mezu hau erakusten du\n . /nickname | /name: zure izena aldatzen du \n . /me action: ekintza bat bidaltzen du \n . /msg nick message: mezu pribatua bidaltzen dio <nick>-(e)ri\n . /r message: azken mezu pribatuari erantzuten dio\n . /join #channelB (ez egin klik hemen, adibide bat da): uneko kanaletik BKanalera aldatzen du
+PasswordWindow.title=Vuze itxita dago
+PasswordWindow.passwordprotected=Vuze sar-hitzez babestuta dago.\nVuzeren leihoa erakusteko, mesedez sartu zure sar-hitza hemen:
+Button.ok=&Ongi
 PeersView.discarded=Baztertua
 PeersView.discarded.info=Nola edo hala jaso duzun datua, nahiz eta beharrezkoa ez izan, eta baztertu duzuna.
 discarded=baztertua
+MyTorrentsView.#=Zenb.
 MyTorrentsView.menu.move=&Mugitu
 MyTorrentsView.menu.moveUp=&Gora
 MyTorrentsView.menu.moveDown=&Behera
-GeneralView.label.hashfails=Hash-ak huts egin du: 
-GeneralView.label.shareRatio=Partekatze-tasa: 
-ConfigView.section.downloadManagement=Deskargen kudeaketa
-ConfigView.label.startRatioPeers=Hasi aletzen ale bat baino gutxiago dagoenean honentzat: 
-ConfigView.text.neverStop=Ez gelditu inoiz
-ConfigView.text.neverStart=Ez hasi inoiz
-ConfigView.text.peers=Pareak
-ConfigView.label.checkOncompletion=Egiaztatu berriro atalak deskarga egin ondoren
-wizard.title=Sortu torrent-a
+GeneralView.label.hashfails=Hasha Hutsegitea: 
+GeneralView.label.shareRatio=Elkarbanatze Neurria: 
+ConfigView.section.downloadManagement=Jeisketa Kudeaketa
+ConfigView.label.startRatioPeers=Hasi emaletzen emale bat baino gutxiago dagoenean
+ConfigView.text.neverStop=Ez Gelditu Inoiz
+ConfigView.text.neverStart=Ez Hasi Inoiz
+ConfigView.text.peers=Hartzaileak
+ConfigView.label.checkOncompletion=Egiaztatu berriro atalak jeisketa egin ondoren
+wizard.title=Sortu torrent bat
 wizard.previous=< Atzera
-wizard.next=Aurrera >
+wizard.next=Hurrena>
 wizard.finish=Amaitu
 wizard.mode=Aztarnaria / Modua
 wizard.tracker=Aztarnaria:
 wizard.invalidurl=URL hau baliogabea da
-wizard.singlefile=Fitxategi bakarra
-wizard.singlefile.help=Sortu torrent-a fitxategi bakarretik
-wizard.directory=Direktorioa
-wizard.directory.help=Sortu torrent-a direktorio batetik
-wizard.choosefile=Hautatu fitxategia
-wizard.file=Fitxategia:
-wizard.browse=Arakatu...
-wizard.choosedirectory=Hautatu direktorioa
-wizard.invalidfile=Baliogabeko fitxategia!
-wizard.invaliddirectory=Baliogabeko direktorioa!
-wizard.torrentFile=Torrent fitxategia
-wizard.choosetorrent=Hautatu sortuko den torrent fitxategia
-wizard.information=Informazioa
+wizard.singlefile=Agiri bakarra
+wizard.singlefile.help=Sortu torrenta agiri bakarretik
+wizard.directory=Zuzenbidea
+wizard.directory.help=Sortu torrenta zuzenbide batetik
+wizard.choosefile=Hautatu agiria
+wizard.file=Agiria:
+wizard.browse=Bilatu
+wizard.choosedirectory=Hautatu zuzenbidea
+wizard.invalidfile=Baliogabeko Agiria!
+wizard.invaliddirectory=Baliogabeko Zuzenbidea!
+wizard.torrentFile=Torrent Agiria
+wizard.choosetorrent=Mesedez hautatu sortzeko torrent agiria
+wizard.information=Argibideak
 wizard.notimplemented=Garatu gabea
-wizard.progresstitle=Torrent fitxategia sortzen
-wizard.savingfile=Fitxategia gordetzen...
-wizard.filesaved=Fitxategia gordeta.
+wizard.progresstitle=Torrent agiria sortzen
+wizard.savingfile=Agiria gordetzen...
+wizard.filesaved=Agiria gordeta.
 wizard.close=Itxi
 Torrent.create.progress.piecelength=Atalen luzera: 
-Torrent.create.progress.piececount=Atal-kopurua: 
-Torrent.create.progress.totalfilesize=Fitxategiaren tamaina osoa: 
-Torrent.create.progress.totalfilecount=Fitxategi-kopuru osoa: 
-Torrent.create.progress.parsingfiles=Fitxategiak prozesatzen
-Torrent.create.progress.hashing=Fitxategien hash-a sortzen
-MainWindow.upgrade.downloadingfrom=Deskargatzen hemendik: 
-MainWindow.menu.view.ipFilter=&IP iragazkiak
+Torrent.create.progress.piececount=Atal zenbatekoa:
+Torrent.create.progress.totalfilesize=Agiriaren neurri osoa:
+Torrent.create.progress.totalfilecount=Agiri zenbateko osoa: 
+Torrent.create.progress.parsingfiles=Agiriak aztertzen
+Torrent.create.progress.hashing=Agirien hasha sortzen
+MainWindow.upgrade.downloadingfrom=Jeisten hemendik: 
+MainWindow.menu.view.ipFilter=&IP Iragazkiak
 ConfigView.section.ipfilter=IP iragazkiak
-ConfigView.section.ipfilter.description=Deskribapena
-ConfigView.section.ipfilter.start=Hasierako IPa
-ConfigView.section.ipfilter.end=Amaierako IPa
+ConfigView.section.ipfilter.description=Azalpena
+ConfigView.section.ipfilter.start=Hasierako IP-a
+ConfigView.section.ipfilter.end=Amaierako IP-a
 ConfigView.section.ipfilter.add=Gehitu
 ConfigView.section.ipfilter.remove=Ezabatu
 ConfigView.section.ipfilter.edit=Editatu
 ConfigView.section.ipfilter.save=Gorde
-ConfigView.section.ipfilter.editFilter=Editatu iragazkia
+ConfigView.section.ipfilter.editFilter=Iragazkia Editatu 
 ConfigView.section.ipfilter.enable=Gaitu
 PeersView.menu.close=&Itxi
-seedmore.title=Torrent-ak ez dauka aski alerik
-seedmore.shareratio=Torrent honentzako, zure partekatze-tasa hau da: 
-seedmore.uploadmore=Ehuneko 100eko partekatze-tasa baino txikiagoa edukitzea ez da ona torrent sarearentzat.\nTorrent honi pixka bat gehiago aletzen utzi behar zenioke.\nSeguru jarraitu nahi duzula?
-ConfigView.label.showpopuponclose=Erakutsi berrespen-leihoa 1 azpitik dagoen partekatze-tasa duen aletzea gelditzean
-ConfigView.label.startNumSeeds=\nHasi aletzen hauek baino gutxiago daudenean:\n - Gainerako arauak gainidazten ditu
-ConfigView.label.seeds=ale
-ConfigView.section.seeding=Aletzen
-MyTorrentsView.menu.removeand=Ken&du eta
-MyTorrentsView.menu.removeand.deletetorrent=Ezabatu &torrent fitxategia
-MyTorrentsView.menu.removeand.deletedata=Ezabatu &datuak
-MyTorrentsView.menu.removeand.deleteboth=Ezabatu &biak
+seedmore.title=Torrenta ez dago nahikoa emaletuta
+seedmore.shareratio=Torrent honentzako, zure elkarbanatze neurria hau da: 
+seedmore.uploadmore=Ehuneko 100 elkarbanatze neurria baino txikiagoa edukitzea ez da ona torrent sarearentzat.\nTorrent honi apur bat gehiago emaletzen utzi beharko zenioke.\nZihur jarraitu nahi duzula?
+ConfigView.label.showpopuponclose=Erakutsi berrespen leihoa 1 azpitik dagoen elkarbanatze maila duen emaletzea gelditzean
+ConfigView.label.startNumSeeds=\nHasi emaletzen hauek baino gutxiago daudenean:\n - Gainerako arauak gainidazten ditu
+ConfigView.label.seeds=emaleak
+ConfigView.section.seeding=Emaletzen
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletetorrent=Ezabatu &Torrent Agiria
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletedata=Ezabatu &Datuak
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=Ezabatu &Biak
 deletedata.title=Ezabatu edukia
-deletedata.message1=Seguru '%1' behin-betiko ezabatu nahi duzula?
+# used for more than just "delete data"
 deletedata.noprompt=Ez galdetu berriro
-MainWindow.menu.file.configure=Konfigurazio-&morroia...
-configureWizard.title=Konfigurazio-morroia
-configureWizard.welcome.title=Ongi etorri Vuze-ren konfigurazio-morroira
-configureWizard.welcome.message=Morroi honek zure Vuze modu egokian erabiltzen lagunduko dizu. Konfigurazioa sakonago aldatu nahi baduzu, erabili Tresnak->Aukerak menua.
-configureWizard.transfer.title=Transferentziaren eta konexioaren konfigurazioa
-configureWizard.transfer.hint=Aholkua: hautatu zure linearen abiadura baino pixka bat txikiagoa.
-configureWizard.transfer.message=Hautatu azpian adierazitako konexioetako bat. Kontuan izan karga-abiadura aski altua onartzen ez bada, deskarga-abiadura motela izango dela. Karga-abiadura torrent BAKOITZEKO soilik zenbatzen denez, torrent gehiegi aldi berean deskargatzeak ere abiadura motel dezake. Gutxieneko HERTSI gisa, torrent bakoitzeko 5KB/s erabiltzea aholkatzen dugu. Azkarrago kargatzen baduzu, azkarrago deskargatuko duzu (torrent-aren abiadurarekin konparatuz gero).
+MainWindow.menu.file.configure=Itxurapen &Laguntzailea...
+configureWizard.title=Itxurapen Laguntzailea
+configureWizard.welcome.title=Ongi etorri Vuzeren Itxurapen Laguntzailera
+configureWizard.welcome.message=Laguntzaile honek zure Vuze modu egokian erabiltzen lagunduko dizu. Itxurapena sakonago aldatu nahi baduzu, erabili Tresnak->Aukerak menua.
+configureWizard.transfer.title=Eskualdaketa eta Elkarketa ezarpenak
+configureWizard.transfer.hint=Aholkua: hautatu zure linearen abiadura baino apur bat txikiagoa.
+configureWizard.transfer.message=Hautatu azpian adierazitako elkarketetako bat. Kontuan izan igoera abiadura aski handia onartzen ez bada, jeisketa abiadura motela izango dela. Igoera abiadura torrent BAKOITZEKO bakarrik zenbatzen denez, torrent gehiegi aldi berean jeisteak ere abiadura moteldu dezake. Gutxieneko HERTSI gisa, torrent bakoitzeko 5KB/s erabiltzea aholkatzen dugu. Azkarrago igotzen baduzu, azkarrago jeitsiko duzu (torrentaren abiadurarekin alderatuz gero).
 configureWizard.transfer.connection=Linea
-configureWizard.transfer.connection.0=pertsonalizatua
-configureWizard.transfer.connection.1=modem-a
+configureWizard.transfer.connection.0=Norbererara
+configureWizard.transfer.connection.1=modema
 configureWizard.transfer.connection.2=adsl/xxx kablea/128 kbps
 configureWizard.transfer.connection.3=adsl/xxx kablea/256 kbps
 configureWizard.transfer.connection.4=adsl/xxx kablea/384 kbps
 configureWizard.transfer.connection.5=adsl/xxx kablea/512 kbps
 configureWizard.transfer.connection.6=adsl/xxx kablea/768 kbps
 configureWizard.transfer.connection.7=adsl/xxx kablea/1024 kbps
-configureWizard.transfer.maxUpSpeed=Karga-abiadura maximoa (KB/s)
-configureWizard.transfer.maxActiveTorrents=Torrent aktiboen maximoa
-configureWizard.transfer.maxDownloads=Deskarga-kopuru maximoa
-configureWizard.transfer.maxUploadsPerTorrent=Karga-kopuru maximoa torrent bakoitzeko
-configureWizard.nat.title=NAT / Zerbitzari-ataka
-configureWizard.nat.message=Vuze-k eman dezakeen onena eskuratzeko, biziki aholkatzen da Internetetik erabat atzigarria izatea. Tresna honek sarrerako pare-konexioak onartzeko erabilitako ataka probatzen eta/edo aldatzen laguntzen du.\n\nOHARRA: Tresna honek TCP konexioak probatzen ditu soilik. DB banatuak sarrerako UDP konexioak ere behar ditu, baina automatikoki jakinaraziko dizu suebaki blokeatzailea aurkitzen badu.\n\nOHARRA: 6880 TCP ataka barne-funtzioetarako erreserbatuta dago eta [...]
-configureWizard.nat.test=Probatu
-configureWizard.nat.testing=Ataka probatzen:
-configureWizard.nat.ko=NAT errorea
-configureWizard.nat.unable=Ezin izan da proba egin: Okerreko ataka eman da, edo probarako zerbitzuak huts egin du.\nAgian beste aplikazio bat ataka hau erabiltzen ari da.
-configureWizard.file.title=Torrent-ak / Fitxategiak
-configureWizard.file.message1=Vuze-k irekitako torrent-ak karpeta batean gordeko dira, karpeta hori hemen adierazi dezakezu:
-configureWizard.file.path=Bidea
-configureWizard.file.browse=Arakatu
-configureWizard.file.message2=Vuze-k berehala berrabiarazi ditzake zure fitxategiak, zure torrent-ei berrabiaratze-datuak eransten badizkiozu. Ezaugarri hau erabiliz, partzialki deskargatutako atalak ere berrabiaraziko dituzu.
-configureWizard.file.fastResume=Gaitu berrabiaratze azkarra
-configureWizard.file.invalidPath=Direktorio baliogabea
-configureWizard.finish.title=Osatua
-configureWizard.finish.message=Orain Vuze konfiguratuta dago, ondo pasa !
+configureWizard.transfer.maxUpSpeed=Gehienezko Igotze Abiadura (KB/s)
+configureWizard.transfer.maxActiveTorrents=Gehienez Eraginda
+configureWizard.transfer.maxDownloads=Gehienezko Jeisketak
+configureWizard.transfer.maxUploadsPerTorrent=Gehienezko Igoera Torrnet bakoitzeko
+configureWizard.nat.test=Aztertu
+configureWizard.nat.testing=Ataka aztertzen
+configureWizard.nat.ok=Ongi!
+configureWizard.nat.ko=NAT Akatsa
+configureWizard.nat.unable=Ezin izan da azterketa egin: Okerreko ataka eman da, edo azterketarako zerbitzuak huts egin du.\nAgian beste egokitzapen bat ataka hau erabiltzen ari da.
+configureWizard.file.title=Torrentak / Agiriak
+configureWizard.file.message1=Vuzek irekitako torrentak agiritegi batean gordeko dira, agiritegi hori hemen adierazi dezakezu:
+configureWizard.file.path=Helburua
+configureWizard.file.browse=Bilatu
+configureWizard.file.message2=Vuzek berehala birrabiarazi ditzake zure agiriak, zure torrentei birrabiarazte datuak eransten badizkiozu. Ezaugarri hau erabiliz, zati bat jeitsitako atalak ere birrabiaraziko dituzu.
+configureWizard.file.fastResume=Gaitu Jarraitu azkarra
+configureWizard.file.invalidPath=Zuzenbide okerra
+configureWizard.finish.title=Osatuta
+configureWizard.finish.message=Orain Vuze itxuratuta dago, ondo izan !
 wizard.close.confirmation=Baieztapena
-wizard.close.message=Nahi al duzu morroi hau karga dadin Vuze abiatzen den hurrengoan?
-exportTorrentWizard.title=Esportatu XML torrent-a
-exportTorrentWizard.torrentfile.title=Sarrerako torrent-aren hautapena
-exportTorrentWizard.torrentfile.message=Hautatu esportatuko den torrent fitxategia
-exportTorrentWizard.torrentfile.path=Bidea
-exportTorrentWizard.torrentfile.browse=Arakatu
-exportTorrentWizard.torrentfile.invalidPath=Torrent fitxategi baliogabea
-exportTorrentWizard.exportfile.title=Hautatu esportatuko den fitxategia
-exportTorrentWizard.exportfile.message=Sartu esportazioko xml fitxategia
-exportTorrentWizard.exportfile.path=Bidea
-exportTorrentWizard.exportfile.browse=Arakatu
-exportTorrentWizard.exportfile.invalidPath=Esportazio-fitxategi baliogabea
+wizard.close.message=Nahi al duzu laguntzaile hau gerta dadin Vuze abiatzen den hurrengoan?
+exportTorrentWizard.title=Esportatu XML torrenta
+exportTorrentWizard.torrentfile.title=Sarrerako Torrentaren Hautapena
+exportTorrentWizard.torrentfile.message=Hautatu esportatuko den torrent agiria
+exportTorrentWizard.torrentfile.path=Helburua
+exportTorrentWizard.torrentfile.browse=Bilatu
+exportTorrentWizard.torrentfile.invalidPath=Torrent agiri baliogabea
+exportTorrentWizard.exportfile.title=Hautatu Esportatzeko Agiria
+exportTorrentWizard.exportfile.message=Sartu esportatzeko xml agiria
+exportTorrentWizard.exportfile.path=Helburua
+exportTorrentWizard.exportfile.browse=Bilatu
+exportTorrentWizard.exportfile.invalidPath=Esportazio agiri baliogabea
 exportTorrentWizard.finish.title=Osatua
-exportTorrentWizard.finish.message=Esportazioa arrakastaz burutu da
-exportTorrentWizard.process.inputfilebad.title=Torrent fitxategi baliogabea
-exportTorrentWizard.process.inputfilebad.message=Hutsegitea gertatu da hurrengo sarrera-fitxategia atzitzean:
-exportTorrentWizard.process.outputfileexists.title=Fitxategia existitzen da
-exportTorrentWizard.process.outputfileexists.message=Irteerako fitxategia existitzen da - gainidatzi?
-exportTorrentWizard.process.torrentfail.title=Torrent-aren irakurketak huts egin du
-exportTorrentWizard.process.exportfail.title=Torrent-aren esportazioak huts egin du
+exportTorrentWizard.finish.message=Esportazioa ongi burutu da
+exportTorrentWizard.process.inputfilebad.title=Torrent Agiri Baliogabea
+exportTorrentWizard.process.inputfilebad.message=Hutsegitea gertatu da hurrengo sarrera agiria atzitzean:
+exportTorrentWizard.process.outputfileexists.title=Agiria Badago
+exportTorrentWizard.process.outputfileexists.message=Irteerako agiria badago - gainidatzi?
+exportTorrentWizard.process.torrentfail.title=Torrentaren Irakurketan Hutsegitea
+exportTorrentWizard.process.exportfail.title=Torrentaren Esportazioan Hutsegitea
 exportTorrentWizard.process.unknownfail.title=Ustekabeko hutsegitea
-importTorrentWizard.title=Inportatu XML torrent-a
-importTorrentWizard.torrentfile.title=Sarrerako torrent-aren hautapena
-importTorrentWizard.torrentfile.message=Adierazi inportatu nahi den torrent fitxategia
-importTorrentWizard.torrentfile.path=Bidea
-importTorrentWizard.torrentfile.browse=Arakatu
-importTorrentWizard.torrentfile.invalidPath=Torrent fitxategi baliogabea
-importTorrentWizard.importfile.title=Inportatuko den fitxategiaren hautapena
-importTorrentWizard.importfile.message=Hautatu inportatuko den xml fitxategia
-importTorrentWizard.importfile.path=Bidea
-importTorrentWizard.importfile.browse=Arakatu
-importTorrentWizard.importfile.invalidPath=Inportazio fitxategi baliogabea
-importTorrentWizard.finish.title=Osatua
-importTorrentWizard.finish.message=Inportazioa arrakastaz burutu da
-importTorrentWizard.process.inputfilebad.title=Inportazio fitxategi baliogabea
-importTorrentWizard.process.inputfilebad.message=Hutsegitea gertatu da hurrengo sarrera-fitxategia atzitzean:
-importTorrentWizard.process.outputfileexists.title=Fitxategia existitzen da
-importTorrentWizard.process.outputfileexists.message=Irteerako fitxategia existitzen da - gainidatzi?
-importTorrentWizard.process.torrentfail.title=Torrent-aren idazketak huts egin du
-importTorrentWizard.process.importfail.title=Torrent-aren inportazioak huts egin du
-importTorrentWizard.process.unknownfail.title=Ustekabeko hutsegitea
-ConfigView.label.bindip=Lotu IP helbide edo interfaze lokalera
-ConfigView.label.xfs.allocation=Esleitu fitxategi berriak XFS fitxategi-sisteman espezifikoa den metodo bat erabiliz
-ConfigView.label.xfs.allocation.tooltip=Segurtatu /usr/sbin/xfs_io zure sisteman ongi instalatuta dagoela. Linux banaketa gehienetan "xfsprogs" paketean dago.
-xfs.allocation.xfs_io.not.found=XFS fitxategiaren esleipenak huts egin du ezin izan delako /usr/sbin/xfs_io exekutatu. Segurtatu zure sisteman ongi instalatuta dagoela. Jatorrizko errorea hau izan da: "%1".
-ConfigView.label.zeronewfiles=Esleitu eta hasieratu fitxategi berriak, haiek sortzen direnean
-ConfigView.label.zeronewfiles.tooltip=Zatikatzea txikitzen du
+importTorrentWizard.title=Inportatu XML torrenta
+importTorrentWizard.torrentfile.title=Sarrerako Torrentaren Hautapena
+importTorrentWizard.torrentfile.message=Adierazi inportatu nahi duzun torrent agiria
+importTorrentWizard.torrentfile.path=Helburua
+importTorrentWizard.torrentfile.browse=Bilatu
+importTorrentWizard.torrentfile.invalidPath=Torrent agiri baliogabea
+importTorrentWizard.importfile.title=Inportazio Agiri Hautapena
+importTorrentWizard.importfile.message=Hautatu inportatuko den xml agiria
+importTorrentWizard.importfile.path=Helburua
+importTorrentWizard.importfile.browse=Bilatu
+importTorrentWizard.importfile.invalidPath=Inportazio agiri baliogabea
+importTorrentWizard.finish.title=Osatuta
+importTorrentWizard.finish.message=Inportazioa ongi burutu da
+importTorrentWizard.process.inputfilebad.title=Inportazio Agiri Baliogabea
+importTorrentWizard.process.inputfilebad.message=Hutsegitea gertatu da hurrengo sarrera agiria atzitzean:
+importTorrentWizard.process.outputfileexists.title=Agiria Badago
+importTorrentWizard.process.outputfileexists.message=Irteerako agiria badago - gainidatzi?
+importTorrentWizard.process.torrentfail.title=Torrentaren Idazketa Hutsegitea
+importTorrentWizard.process.importfail.title=Torrentaren inportazioak huts egin du
+importTorrentWizard.process.unknownfail.title=Ustekabeko Hutsegitea
+ConfigView.label.bindip=Lotu tokiko IP helbidera edo interfazera
+ConfigView.label.xfs.allocation=Esleitu agiri berriak XFS agiri-erabide bereizia den bide bat erabiliz
+ConfigView.label.xfs.allocation.tooltip=Segurtatu /usr/sbin/xfs_io zure sisteman ongi ezarrita dagoela. Linux banaketa gehienetan "xfsprogs" paketean dago.
+xfs.allocation.xfs_io.not.found=XFS agiriaren esleipenak huts egin du ezin izan delako /usr/sbin/xfs_io exekutatu. Segurtatu zure sisteman ongi ezarrita dagoela. Jatorrizko akatsa hau izan da: "%1".
+ConfigView.label.zeronewfiles=Esleitu eta hasieratu agiri berriak, haiek sortzen direnean
+ConfigView.label.zeronewfiles.tooltip=Zatikatzea gutxiagotzen du
 ConfigView.section.stats=Estatistikak
 ConfigView.section.stats.enable=Gaitu
-ConfigView.section.stats.defaultsavepath=Estatistikak gordetzeko direktorioa
-ConfigView.section.stats.choosedefaultsavepath=Hautatu estatistikak gordetzeko direktorioa 
-ConfigView.section.stats.savefreq=Gordetze-maiztasuna
-ConfigView.section.stats.minutes= minutu
-ConfigView.section.stats.hours= ordu
-ConfigView.section.stats.seconds= segundo
-ConfigView.section.stats.savefile=Estatistiken fitxategi-izena
-ConfigView.section.stats.graph_update_dividers=Erakutsi linea bertikala 60 eguneraketen multzoetarako
-MyTorrentsView.menu.export=&XML torrent-a...
+ConfigView.section.stats.defaultsavepath=Estatistikak gordetzeko zuzenbidea
+ConfigView.section.stats.choosedefaultsavepath=Hautatu estatistikak gordetzeko zuzenbidea
+ConfigView.section.stats.savefreq=Gordetze maiztasuna
+ConfigView.section.stats.minutes=min.
+ConfigView.section.stats.hours=ordu
+ConfigView.section.stats.seconds=seg.
+ConfigView.section.stats.savefile=Estatistiken agiri izena
+ConfigView.section.stats.graph_update_dividers=Erakutsi lerro zutia 60 eguneraketa bakoitzetik
+MyTorrentsView.menu.export=&XML torrenta...
 MyTorrentsView.menu.host=&Ostalaria...
 ManagerItem.finishing=Amaitzen
-ConfigView.dialog.choosedefaulttorrentpath=Hautatu torrent direktorio lehenetsia
-ConfigView.dialog.choosemovepath=Hautatu zein direktoriora mugituko den
-ConfigView.label.movecompleted=Mugitu osatutako fitxategiak (deskargatu ondoren)
-ConfigView.label.moveremoved=Mugitu osatutako fitxategiak (ezabatzerakoan)
-ConfigView.label.savetorrents=Gorde .torrent fitxategiak
+ConfigView.dialog.choosedefaulttorrentpath=Mesedez hautatu torrent zuzenbide lehenetsia
+ConfigView.dialog.choosemovepath=Mesedez hautatu zein zuzenbidera mugituko den
+ConfigView.label.movecompleted=Mugitu osatutako agiriak (jeitsi ondoren)
+ConfigView.label.moveremoved=Mugitu osatutako agiriak (ezabatzerakoan)
+ConfigView.label.savetorrents=Gorde .torrent agiriak
 MainWindow.menu.view.mytracker=Nire a&ztarnaria
 MyTrackerView.title.full=Nire aztarnaria
 MyTrackerView.name=Izena
 MyTrackerView.tracker=Aztarnaria
 MyTrackerView.status=Egoera
-MyTrackerView.status.started=Abian
+MyTrackerView.status.started=Lanean
 MyTrackerView.status.stopped=Geldituta
-MyTrackerView.peers=Pareak
-MyTrackerView.seeds=Aleak
-MyTrackerView.announces=Iragarkiak
-MyTrackerView.uploaded=Kargatua
-MyTrackerView.downloaded=Deskargatua
-MyTrackerView.left=Ezkerra
+MyTrackerView.peers=Hartzaileak
+MyTrackerView.seeds=Emaleak
+MyTrackerView.announces=Iragarleak
+MyTrackerView.uploaded=Igota
+MyTrackerView.downloaded=Jeitsita
+MyTrackerView.left=Egiteke
 ConfigView.section.style=Interfazea
-ConfigView.label.set_ui_transfer_speeds=Gainidatzi transferentzia-abiadura hautagarriak
-ConfigView.label.set_ui_transfer_speeds.description=Eskuz defini ditzakezu sistemaren erretiluko egoera-barran eskuragarri egongo diren karga- eta deskarga-abiadura lehenetsiak.\nBalioak komaz bananduak idatzi behar dira.
-ConfigView.label.set_ui_transfer_speeds.description.download=Ezarri deskarga-abiadurak (KB/s-tan)
-ConfigView.label.set_ui_transfer_speeds.description.upload=Ezarri karga-abiadurak (KB/s-tan)
-ConfigView.section.style.useCustomTabs=Erabili itxi daitezkeen etiketak (beharrezkoa da berrabiaraztea)
-MainWindow.menu.view.plugins=&Plugin-ak
-fileDownloadWindow.saveTorrentIn=Gorde torrent fitxategia hemen:
-fileDownloadWindow.title=Vuze - Torrent deskargatzailea
-fileDownloadWindow.downloading=Deskargatzen hemendik:
+ConfigView.label.set_ui_transfer_speeds=Gainidatzi eskualdaketa abiadura hautagarriak
+ConfigView.label.set_ui_transfer_speeds.description=Eskuz zehaztu ditzakezu erabidearen erretiluko egoera barran eskuragarri egongo diren igoera eta jeisketa abiadura lehenetsiak.\nBalioak kakotxaz bananduta idatzi behar dira.
+ConfigView.label.set_ui_transfer_speeds.description.download=Ezarri jeisketa abiadurak (KB/s)
+ConfigView.label.set_ui_transfer_speeds.description.upload=Ezarri igoera abiadurak (KB/s)
+ConfigView.section.style.useCustomTabs=Erabili itxi daitezkeen hegatsak (beharrezkoa da berrabiaraztea)
+MainWindow.menu.view.plugins=&Pluginak
+fileDownloadWindow.saveTorrentIn=Gorde torrent agiria hemen:
+fileDownloadWindow.title=Vuze - Torrent jeistzailea
+fileDownloadWindow.downloading=Hemendik Jeisten:
 fileDownloadWindow.status=Egoera:
-fileDownloadWindow.state_initializing=Hasieratzen
-fileDownloadWindow.state_downloading=Deskargatzen
-fileDownloadWindow.state_error=Errorea: 
+fileDownloadWindow.state_initializing=Abiatzen
+fileDownloadWindow.state_downloading=Jeisten
+fileDownloadWindow.state_error=Akatsa:
 MainWindow.menu.file.open.url=&Kokalekua...
-openUrl.title=Ireki kokalekua
-openUrl.url=URLa:
-MyTorrentsView.menu.host.error.title=Torrent-aren ostatatzeak huts egin du
-MyTorrentsView.menu.host.error.message=Torrent-a ostatatzean hurrengo akatsa gertatu da
+openUrl.title=Ireki Helbidea
+openUrl.url=URL-a:
+MyTorrentsView.menu.host.error.title=Torrentaren Ostatatzeak Huts egin du
+MyTorrentsView.menu.host.error.message=Torrenta ostatatzean hurrengo akatsa gertatu da
 ConfigView.section.tracker=Aztarnaria
 ConfigView.section.tracker.pollinterval=Aztarnariaren bezeroa zenbatero zundatuko den (segundoak)
 ConfigView.section.tracker.publishenable=Argitaratu torrent-aren xehetasunak "<tracker_url>"-era
 ConfigView.section.tracker.ip=Aztarnariaren kanpoko IP helbidea
 ConfigView.section.style.enableXPStyle=Gaitu XP estiloa (beharrezkoa da berrabiaraztea)
 IPChecker.external.service.dyndns.description=DNS Dinamikoko Sare Zerbitzuak, LLC
-ConfigView.section.tracker.checkip=Automatikoki aurkitu kanpoko IP helbidea...
-ipCheckerWizard.title=IPa egiaztatzeko morroia
+ConfigView.section.tracker.checkip=Berez-aurkitu kanpoko IP helbidea...
+ipCheckerWizard.title=IP Egiaztapen Laguntzailea
 ipCheckerWizard.service=Zerbitzua
-ipCheckerWizard.chooseService=Hautatu IPa egiaztatzeko zerbitzu bat zerrendatutako zerbitzuetatik
-ipCheckerWizard.explanations=Zure kanpoko IP helbidea zein den aurkitzeko erabil dezakezu morroi hau. Zure IP helbidea dinamikoa bada, DNS Zerbitzu Dinamiko batekin kontua irekitzea aholkatzen dizugu. Beheko zerrendan zerbitzu horietako zenbait ematen ditugu, erabili estekak kontu bat sortzeko (onartuta dagoen lekuetan). Ondoren, bete IP helbidearen eremua zure ostatatze-izen dinamikoarekin (adib. nireizena.dyndns.org). Aplikazio bat beharko duzu zure DNS Zerbitzu Dinamikoa automatikoki  [...]
-ipCheckerWizard.service.description=Deskribapena:
-ipCheckerWizard.service.url=Esteka:
-ipCheckerWizard.progresstitle=IPa egiaztatzen
+ipCheckerWizard.chooseService=Hautatu IP Egiaztapen Zerbitzu bat zerrendatutako zerbitzuetatik
+ipCheckerWizard.explanations=Zure kanpoko IP helbidea zein den aurkitzeko erabil dezakezu laguntzaile hau. Zure IP helbidea dinamikoa bada, DNS Zerbitzu Dinamiko batekin kontua irekitzea aholkatzen dizugu. Beheko zerrendan zerbitzu horietako zenbait ematen ditugu, erabili loturak kontu bat sortzeko (onartuta dagoen lekuetan). Ondoren, bete IP helbidearen eremua zure ostatatze-izen dinamikoarekin (adib. nireizena.dyndns.org). Aplikazio bat beharko duzu zure DNS Zerbitzu Dinamikoa berezgai [...]
+ipCheckerWizard.service.description=Azalpena:
+ipCheckerWizard.service.url=Lotura:
+ipCheckerWizard.progresstitle=IP-a Egiaztatzen
 ipCheckerWizard.checkComplete=IP osatua:
-ipCheckerWizard.checkFailed=Huts egin du, arrazoia:
-wizard.tracker.local=Erabili Vuze-k kapsulatuta daraman aztarnaria
+ipCheckerWizard.checkFailed=Huts egin du, zergaitia:
+wizard.tracker.local=Erabili Vuze Barneko Aztarnaria
 wizard.tracker.external=Erabili kanpoko aztarnaria
-wizard.tracker.howToLocal=Joan 'Tresnak->Aukerak->Aztarnaria' aukerara aztarnaria gaitzeko
-wizard.announceUrl=Iragarpen URLa:
-IPChecker.external.service.discoveryvip.description=Discoveryvip - IP helbidearen egiaztatzea soilik
+wizard.tracker.howToLocal=Joan 'Tresnak->Aukerak->Aztarnaria' hura gaitzeko
+wizard.announceUrl=Iragarpen URL-a:
+IPChecker.external.service.discoveryvip.description=Discoveryvip - IP helbidearen egiaztatzea bakarrik
 IPChecker.external.httpinvalidresponse=HTTP erantzun baliogabea
-IPChecker.external.loadingwebpage=Web orria kargatzen
+IPChecker.external.loadingwebpage=Web orrialdea gertatzen
 IPChecker.external.analysingresponse=Erantzuna aztertzen
 IPChecker.external.addressextracted=Erauzitako IP helbidea
-IPChecker.external.httploadfail=Orria kargatzeak huts egin du
+IPChecker.external.httploadfail=Orrialdea gertatzeak huts egin du
 IPChecker.external.timeout=Denboraz kanpo geratu da
 IPChecker.external.ipnotfound=IP helbidea ez da aurkitu
-ConfigView.section.tracker.pollintervalmin=Minimoa
-ConfigView.section.tracker.pollintervalmax=Maximoa
+ConfigView.section.tracker.pollintervalmin=Gutxienez
+ConfigView.section.tracker.pollintervalmax=Gehienez
 ConfigView.section.tracker.pollintervalincby=Handitu honenbeste:
-ConfigView.section.tracker.pollintervalincper='n' bezeroko
-splash.loadingImages=Irudiak kargatzen
-splash.initializeGui=Leiho nagusia hasieratzen
-splash.openViews=Bistak irekitzen
-splash.plugin=Plugin-a kargatzen: 
-configureWizard.nat.tooManyPorts=Aztertzeko portu gehiegi (9 gehienez)
-ConfigView.section.color=Kolore-eskema
+ConfigView.section.tracker.pollintervalincper=Betik 'z' bezero
+splash.loadingImages=Irudiak Gertatzen
+splash.initializeGui=Leiho Nagusia Abiatzen
+splash.openViews=Ikuspegiak Irekitzen
+splash.plugin=Plugina Gertatzen:
+configureWizard.nat.tooManyPorts=Aztertzeko ataka gehiegi (9 gehienez)
+ConfigView.section.color=Margo Itxurapena
 MyTorrentsView.menu.publish=Ar&gitaratu...
-MyTrackerView.status.published=Argitaratua
-MyTrackerView.completed=Osatua
-MainWindow.menu.file.open.torrentnodefault=Torrent fitxategia... (ez gorde lehenetsi gisa)
+MyTrackerView.status.published=Argitaratuta
+MyTrackerView.completed=Osatuta
+MainWindow.menu.file.open.torrentnodefault=Torrent agiria... (Ez Gorde Lehenespenez)
+MainWindow.menu.file.open.torrentnodefault.keybinding.mac=Meta+Auk+O
 wizard.comment=Iruzkina
-ConfigView.label.movetorrent=Mugitu .torrent-a
-ConfigView.label.movepartialdownloads=Mugitu fitxategi batzuk "Ez deskargatu" bandera eduki arren
-ConfigView.label.subdir_is_in_default=Deskargak direktorio lehenetsi batean existitzen ote diren aztertzean, aztertu azpidirektorioak ere. 
-ConfigView.section.file.decoder.label=Torrent kodifikazio lehenetsia hautaketak hala eskatzen duenean
+ConfigView.label.movetorrent=Mugitu .torrenta
+ConfigView.label.movepartialdownloads=Mugitu agiri batzuk "Ez jeitsi" ikurra eduki arren
+ConfigView.label.subdir_is_in_default=Jeisketak zuzenbide lehenetsi batean ba ote diren aztertzean, aztertu azpizuzenbideak ere. 
+ConfigView.section.file.decoder.label=Torrent kodeatze lehenetsia hautaketak horrela eskatzen duenean
 ConfigView.section.file.decoder.nodecoder=Bat ere ez
-IPChecker.external.service.no-ip.description=DNS zerbitzu dinamiko eta estatikoen hornitzailea (ez dauka 'egiaztatu helbidea' zerbitzu librerik)
+IPChecker.external.service.no-ip.description=DNS zerbitzu dinamiko eta estatikoen hornitzailea (ez dauka 'egiaztatu helbidea' zerbitzu askerik)
 ConfigView.section.tracker.publicenable=Gaitu kanpoko torrent-ak
-ConfigView.label.playdownloadspeech=Hitz egin deskarga amaitutakoan
-ConfigView.label.playdownloadspeech.info=Hizketa-zerbitzuak hobeto dabiltza ingelesez
+ConfigView.label.playdownloadspeech=Hitz egin jeisketa amaitutakoan
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=Bistaratu atal bakoitzaren kopia eskuragarrien kopurua.\nEskuineko zenbakia 1 baino txikiagoa bada, ez zaude ikusten fitxategiaren kopia oso bat (eta arazoak egon daitezke deskarga burutzeko).
-GeneralView.label.trackerurl.tooltip=Egin klik iragarpen URLa arbelera kopiatzeko
+GeneralView.label.status.pieces_available.tooltip=Erakutsi atal bakoitzaren kopia eskuragarrien zenbatekoa.\nEskuineko zenbakia 1 baino txikiagoa bada, ez zaude ikusten agiriaren kopia oso bat (eta arazoak egon daitezke jeisketa burutzeko).
+GeneralView.label.trackerurl.tooltip=Egin klik iragarpen URL-a gakora kopiatzeko
 GeneralView.label.trackerurlopen.tooltip=Egin klik aztarnariaren orri nagusia irekitzeko
 #
 # 2.0.4.4
 #
-ConfigView.section.style.guiUpdate=Eguneratu EIa honenbestero:
-ConfigView.section.style.inactiveUpdate=Eguneratu leiho nagusia EIaren N eguneratzetik behin, leiho aktiboa ez denean 
-ConfigView.section.style.graphicsUpdate=Eguneratu barra grafikoak EIaren N eguneratzetik behin
-ConfigView.section.style.reOrderDelay=Berrantolatu taulak EIaren N eguneratzetik behin [0: inoiz ez]
-ConfigView.section.style.reOrderDelay.never=Inoiz
-ConfigView.section.logging=Egunkaria
-ConfigView.section.logging.enable=Gaitu egunkaria fitxategira idaztea
-ConfigView.section.logging.logdir=Egunkari-fitxategiaren direktorioa
-ConfigView.section.logging.choosedefaultsavepath=Hautatu gordetze-direktorioa
-GeneralView.label.updatein.querying=Kontsultatzen...
+ConfigView.section.style.guiUpdate=Eguneratu EIG betik
+ConfigView.section.style.inactiveUpdate=Eguneratu leiho nagusia EIG-aren Z eguneratzetik behin, leiho eragilea ez denean 
+ConfigView.section.style.graphicsUpdate=Eguneratu Grafiko barrak EIG-aren Z eguneratzetik behin
+ConfigView.section.style.reOrderDelay=Berrantolatu taulak EIG-aren Z eguneratzetik behin [0: inoiz ez]
+ConfigView.section.style.reOrderDelay.never=Inoiz Ez
+ConfigView.section.logging=Saioa hasi
+ConfigView.section.logging.enable=Gaitu agirira ohartzea
+ConfigView.section.logging.logdir=Saio agiri zuzenbidea
+ConfigView.section.logging.choosedefaultsavepath=Hautatu gordetze zuzenbidea
+GeneralView.label.updatein.querying=Eskabidetzen...
 configureWizard.nat.sharePort=Erabili sarrerako ataka partekatu bakarra torrent guztientzako
-ConfigView.section.logging.maxsize=Egunkari-fitxategiaren tamaina maximoa
+ConfigView.section.logging.maxsize=Gehienezko ohar agiriaren neurria
 ConfigView.section.tracker.passwordenableweb=Gaitu pasahitza aztarnariaren webean
 ConfigView.section.tracker.passwordenabletorrent=Gaitu pasahitza torrent-etan
-ConfigView.section.tracker.username=Erabiltzaile-izena
-ConfigView.section.tracker.password=Pasahitza
-columnChooser.title=Hautatu bistaratuko diren zutabeak
-columnChooser.move=Arrastatu errenkadak haiek berrantolatzeko
-columnChooser.apply=Aplikatu
-columnChooser.columnname=Zutabe-izena
-columnChooser.columndescription=Deskribapena
-TableColumn.header.shareRatio=Partekatze-tasa
-MyTorrentsView.menu.editTableColumns=&Zutabearen konfigurazioa
+ConfigView.section.tracker.username=Erabiltzaile izena
+ConfigView.section.tracker.password=Sar-hitza
+columnChooser.title=Hautatu ikusiko diren zutabeak
+columnChooser.move=Arrastatu lerroak birrantolatzeko
+columnChooser.apply=Ezarri
+columnChooser.columnname=Zutabe Izena
+columnChooser.columndescription=Azalpena
+TableColumn.header.shareRatio=Elkarbanatze Neurria
+MyTorrentsView.menu.editTableColumns=&Zutabearen Ezarpenak
 wizard.operationfailed=Eragiketak huts egin du
-authenticator.title=Autentifikazioa beharrekoa da
-authenticator.realm=Erreinua
+authenticator.title=Egiaztapena beharrezkoa da
+authenticator.realm=Erresuma
 authenticator.tracker=Aztarnaria
-authenticator.user=Erabiltzaile-izena
-authenticator.password=Pasahitza
-ConfigView.label.allowSendVersion=Utzi Vuze-ri bertsio-zenbakia eta ausazko id anonimoak bidaltzen bertsio berriaren bila ari denean 
-ConfigView.label.version.info.link=Bisitatu hau bertsioak egiaztatzen dituen zerbitzarira bidaltzen diren datuen xehetasunak ezagutzeko
-wizard.hint.mode=Aholkua:\tFitxategi bat edo direktorio bat arrastatu eta jaregin dezakezu\nmorroi honetan fitxategia edo direktorioa hautatzeko
-wizard.hint.file=Aholkua:\tArrastatu eta jareginez hauta dezakezu fitxategia
-wizard.hint.directory=Aholkua:\tArrastatu eta jareginez hauta dezakezu direktorioa
-MainWindow.menu.help.checkupdate=&Bilatu eguneraketak...
-TableColumn.header.down=Deskargatua
-TableColumn.header.up=Kargatua
+authenticator.user=Erabiltzaile izena
+authenticator.password=Sar-hitza
+ConfigView.label.allowSendVersion=Utzi Vuzeri bertsio zenbakia eta zorizko id izengabeak bidaltzen bertsio berriaren bila ari denean 
+ConfigView.label.version.info.link=Ikusi hau bertsioak egiaztatzen dituen zerbitzarira bidaltzen diren datuen xehetasunak ezagutzeko
+wizard.hint.mode=Aholkua: Agiri bat edo zuzenbide bat Arrastatu eta Askatu dezakezu\n\t  morroi honetan agiria edo zuzenbidea hautatzeko
+wizard.hint.file=Aholkua:\tArrastatu eta Askatuz hauta dezakezu agiria
+wizard.hint.directory=Aholkua:\tArrastatu eta askatuz hauta dezakezu zuzenbidea
+MainWindow.menu.help.checkupdate=&Bilatu Eguneraketak...
+TableColumn.header.down=Jeitsita
+TableColumn.header.up=Igota
 ConfigView.section.tracker.passwordenabletorrent.info=BitTorrent bezero egokia (esaterako Vuze) behar da
-ConfigView.section.style.confirmationOnExit=Erakutsi berrespen-leihoa irtetean
-MainWindow.dialog.exitconfirmation.title=Irten Vuze-tik
-MainWindow.dialog.exitconfirmation.text=Benetan irten nahi duzu Vuze-tik?
-SystemTray.menu.stopalltransfers=Gelditu transferentzia &guztiak
-TrayWindow.menu.stopalldownloads=Gelditu deskarga &guztiak
-ConfigView.section.tracker.sslport.info=Begiratu MEGak informazio gehiago jasotzeko
+ConfigView.section.style.confirmationOnExit=Erakutsi berrespen leihoa irtetean
+MainWindow.dialog.exitconfirmation.title=Irten Vuzetik
+MainWindow.dialog.exitconfirmation.text=Egitan nahi duzu Vuzetik irtetea?
+SystemTray.menu.stopalltransfers=Gelditu &Eskualdaketa Guztiak
+TrayWindow.menu.stopalldownloads=Gelditu &Jeisketa Denak
+ConfigView.section.tracker.sslport.info=Begiratu SEG-ak argibide gehiagorako
 wizard.tracker.ssl=Erabili SSL
-ConfigView.label.playdownloadfinished=Erreproduzitu soinu bat deskarga burutzen denean
-ConfigView.label.popupdownloadfinished=Erakutsi alerta-leihoa deskarga burutzen denean
-ConfigView.label.popupfilefinished=Erakutsi alerta-leihoa fitxategia amaituta dagoenean
+ConfigView.label.playdownloadfinished=Jo soinu bat jeisketa burutzen denean
+ConfigView.label.popupdownloadfinished=Erakutsi alerta-leihoa jeisketa burutzen denean
+ConfigView.label.popupfilefinished=Erakutsi alerta leihoa agiria amaituta dagoenean
 TableColumn.header.pieces=Atalak
-TableColumn.header.pieces.info=Deskargatu dituzun atalak ordezkatzen dituen barra grafikoa
+TableColumn.header.pieces.info=Jeitsi dituzun atalak adierazten ditu barra grafikoak
 TableColumn.header.completion=Osaketa
-TableColumn.header.completion.info=Deskargatutako ehunekoa ordezkatzen duen grafikoa
-ConfigView.section.style.showdownloadbasket=Erakutsi deskarga-saskia (arrastatu eta jaregin .torrent-ak)
-ConfigView.section.style.alwaysShowTorrentFiles=Erakutsi beti torrent fitxategiak Xehetasunk/Fitxategiak atalean
-wizard.multitracker=Gehitu multi-aztarnari informazioa torrent-ari
-wizard.multitracker.title=Multi-aztarnaria
-wizard.multitracker.configuration=Multi-aztarnariaren konfigurazioa
+TableColumn.header.completion.info=Jeitsitako ehunekoa adierazten duen grafikoa
+ConfigView.section.style.showdownloadbasket=Erakutsi Jeisketa Saskia (Arrastatu eta Askatu .torrentak)
+ConfigView.section.style.alwaysShowTorrentFiles=Erakutsi betik torrent agiriak Xehetasunak/Agiriak atalean
+wizard.multitracker=Gehitu aztarnari-Anitzaren argibideak torrentari
+wizard.multitracker.title=Aztarnari-Anitz
+wizard.multitracker.configuration=Aztarnari-Anitzaren Ezarpenak
 wizard.multitracker.new=Berria...
 wizard.multitracker.edit=Editatu...
 wizard.multitracker.delete=Ezabatu
-wizard.multitracker.group=Aztarnari-taldea
-wizard.multitracker.edit.title=Multi-aztarnariaren editorea
+wizard.multitracker.group=Aztarnari Taldea
+wizard.multitracker.edit.title=Aztarnari-Anitz Editatzailea
 wizard.multitracker.edit.name=Izena
 wizard.multitracker.edit.save=Gorde
-wizard.multitracker.edit.newgroup=Talde berria
+wizard.multitracker.edit.newgroup=Talde Berria
 wizard.multitracker.edit.deletegroup=Ezabatu
-wizard.multitracker.edit.newtracker=Aztarnari berria
+wizard.multitracker.edit.newtracker=Aztarnari Berria
 wizard.multitracker.edit.deletetracker=Ezabatu
 wizard.multitracker.edit.edit=Editatu
-wizard.addingmt=Multi-aztarnariaren informazioa gehitzen
-wizard.multitracker.noannounce=Zure aztarnarien zerrendan ez dago iragarpen URLrik
-MyTorrentsView.menu.recheck=&Behartu berregiaztapena
-iconBar.showDownloadBar.tooltip=Erakutsi deskarga-barra
-iconBar.start.tooltip=Hasi hautatutako torrent-ak
-iconBar.stop.tooltip=Gelditu hautatutako torrent-ak
-iconBar.remove.tooltip=Kendu hautatutako torrent-ak
-iconBar.openNoDefault.tooltip=Ireki .torrent fitxategia (ez gorde lehenetsi gisa)
-iconBar.openURL.tooltip=Ireki URLa
-iconBar.openFolder.tooltip=Ireki karpeta
-iconBar.new.tooltip=Sortu torrent-a
+wizard.addingmt=Aztarnari-Anitzaren argibideak gehitzen
+wizard.multitracker.noannounce=Zure aztarnarien zerrendan ez dago iragarpen URL-rik
+MyTorrentsView.menu.recheck=&Behartu Birregiaztapena
+iconBar.showDownloadBar.tooltip=Erakutsi Jeisketa Barra
+iconBar.start.tooltip=Hasi hautatutako torrenta(k)
+iconBar.stop.tooltip=Gelditu hautatutako torrenta(k)
+iconBar.remove.tooltip=Ezabatu hautatutako torrentak
+iconBar.openNoDefault.tooltip=Ireki .torrent agiria (ez gorde lehenetsi bezala)
+iconBar.openURL.tooltip=Ireki URL-a
+iconBar.openFolder.tooltip=Ireki Agiritegi bat
+iconBar.new.tooltip=Sortu torrent bat
 iconBar.up.tooltip=Mugitu gora
 iconBar.down.tooltip=Mugitu behera
-iconBar.run.tooltip=Ireki aplikazio lehenetsia erabiliz
+iconBar.run.tooltip=Ireki programa lehenetsia erabiliz
 iconBar.host.tooltip=Ostalaria
 iconBar.publish.tooltip=Argitaratu
-iconBar.editcolumns.tooltip=Zutabearen konfigurazioa
-MyTorrentsView.menu.editTracker=&Editatu aztarnarien URLak
+iconBar.editcolumns.tooltip=Zutabe Ezarpena
+MyTorrentsView.menu.editTracker=&Editatu aztarnarien URL-ak
 GeneralView.menu.selectTracker=Hautatu
-ConfigView.section.stats.xslfile=XSL fitxategiaren izena
-ConfigView.section.stats.xslfiledetails=Hau estatistiken fitxategiaren goiburuan sartuko da <?xml-stylesheet> etiketa erabiliz
+ConfigView.section.stats.xslfile=XSL agiri izena
+ConfigView.section.stats.xslfiledetails=Hau estatistiken agiriaren goiburuan sartuko da <?xml-stylesheet> etiketa erabiliz
 ConfigView.label.savetorrentbackup=Gorde babeskopia
-ConfigView.section.tracker.forceport=Behartu kanpoan ostatatutako torrent-ek lehenetsitako ataka erabil dezaten
+ConfigView.section.tracker.forceport=Behartu ostatatutako kanpoko torrentak lehenetsitako ataka erabil dezaten
 ConfigView.section.ipfilter.allow=ONARTU barruti hauek (balio lehenetsia UKATZEA da)
 ConfigView.section.ipfilter.list.inrange=barrutian zegoen 
 ConfigView.section.ipfilter.list.notinrange=ez zegoen inolako barrutitan
-ConfigView.section.ipfilter.list.title=Blokeatutako IPak
-ConfigView.label.allowsameip=Onartu konexio anitz IP beretik
-ConfigView.label.allowsameip.tooltip=Markatu BEHAR baduzu soilik.\nHau izainen aurkako babesa da (desgaituta dagoenean).
-ManagerItem.superseeding=Super-aletzen
-ConfigView.label.userSuperSeeding=Erabili super-aletzea
-PeersView.uniquepiece=Atala (super-aletze modua)
+ConfigView.section.ipfilter.list.title=Eragotzitako IP-ak
+ConfigView.label.allowsameip=Onartu elkarketa anitz IP beretik
+ConfigView.label.allowsameip.tooltip=Egiaztatu BEHAR baduzu bakarrik.\nHau izainen aurkako babesa da (ezgaituta dagoenean).
+ManagerItem.superseeding=Gain-Emaletzen
+ConfigView.label.userSuperSeeding=Erabili Gain Emaletza
+PeersView.uniquepiece=Atala (Gain-Emaletze modua)
 PeersView.uniquepiece.none=Bat ere ez
-PeersView.timetosend=Atala birbidaltzeko denbora (super-aletze modua)
-ConfigView.section.style.addurlsilently=Ireki pasatutako URLak modu isilean
-ConfigView.section.style.addurlsilently.tooltip=Deskargatu automatikoki pasatutako/jaregindako .torrent-en URLak galdetze-koadroa ireki gabe.
-ConfigView.section.file.decoder.prompt=Galdetu beti kodeketa-aukera eskuragarri dagoenean
-ConfigView.section.file.decoder.prompt.tooltip=Erakutsi beti elkarrizketa-koadroa kodeketa-aukera eskuragarri dagoenean
-MyTorrentsView.menu.moveTop=&Goia
-MyTorrentsView.menu.moveEnd=&Behea
-ConfigView.label.moveonlyusingdefaultsave=soilik datuen direktorio lehenetsian
-ConfigView.label.moveonlyusingdefaultsave.tooltip=Mugitu soilik datu deskargatuak datuen direktorio lehenetsian daudenean
-ConfigView.label.watchtorrentfolder=Inportatu .torrent berriak automatikoki
+PeersView.timetosend=Atala birbidaltzeko denbora (Gain-Emaletze Modua)
+ConfigView.section.style.addurlsilently=Ireki pasatutako URL-ak modu isilean
+ConfigView.section.style.addurlsilently.tooltip=Berezgaitasunez jeitsi pasatutako/askatutako .torrenten URL-ak elkarrizketa kutxa ireki gabe.
+ConfigView.section.file.decoder.prompt=Galdetu beti kodeketa aukera eskuragarri dagoenean
+ConfigView.section.file.decoder.prompt.tooltip=Erakutsi betik elkarrizketa kodeketa aukera eskuragarri dagoenean
+MyTorrentsView.menu.moveTop=&Goren
+MyTorrentsView.menu.moveEnd=&Beheren
+ConfigView.label.moveonlyusingdefaultsave=bakarrik datuen zuzenbide lehenetsian
+ConfigView.label.moveonlyusingdefaultsave.tooltip=Mugitu jeitsitako datuak datuen zuzenbide lehenetsian badaude bakarrik
+ConfigView.label.watchtorrentfolder=Inportatu .torrent berriak berezgaitasunez 
 ConfigView.label.watchtorrentfolder.tooltip=Bilatu .torrent berriak aldizka
 ConfigView.label.watchtorrentfolderinterval=Tartea
-ConfigView.label.watchtorrentfolderinterval.tooltip=Karpeta berriro eskaneatu arteko pausaldia
-ConfigView.dialog.choosewatchtorrentfolderpath=Hautatu .torrent-en inportazio-direktorioa
+ConfigView.label.watchtorrentfolderinterval.tooltip=Agiritegia berriro mihatu arteko pausaldia
+ConfigView.dialog.choosewatchtorrentfolderpath=Mesedez hautatu .torrenten inportazio-zuzenbidea
 ConfigView.label.startwatchedtorrentsstopped=Abiatu geldituta
 ConfigView.label.startwatchedtorrentsstopped.tooltip=Gehitu .torrent berria GELDITUTA egoeran
-ConfigView.section.plugins=Plugin-ak
-wizard.maketorrent.filesize=Fitxategien tamaina
-wizard.maketorrent.piececount=Atal-kopurua
-wizard.maketorrent.piecesize=Atalen tamaina
+ConfigView.section.plugins=Pluginak
+wizard.maketorrent.filesize=Agiri(en) Neurria
+wizard.maketorrent.piececount=Atal Zenbatekoa
+wizard.maketorrent.piecesize=Atalen neurria
+wizard.maketorrent.auto=Berez
 MainWindow.menu.view.stats=&Estatistikak
 SpeedView.title.full=Jarduera
-SpeedView.downloadSpeed.title=Deskarga-abiadura
-SpeedView.uploadSpeed.title=Karga-abiadura
-ConfigView.section.style.useSIUnits=Erabili IEC unitateak (KB -> KiB, etab.)
-iconBar.top.tooltip=Mugitu lehen postura
-iconBar.bottom.tooltip=Mugitu azken postura
+SpeedView.downloadSpeed.title=Jeisketa Abiadura
+SpeedView.uploadSpeed.title=Igoera Abiadura
+ConfigView.section.style.useSIUnits=Erabili IEC Batasunak (KB -> KiB, etab.)
+iconBar.top.tooltip=Mugitu lehen tokira
+iconBar.bottom.tooltip=Mugitu beheren
 TableColumn.header.health=Osasuna
 MyTorrentsView.menu.health=Osasunari buruz
-health.explain.grey=esan nahi du zure torrent-a ez dabilela (ez deskargatzen ez kargatzen)
-health.explain.red=esan nahi du ez zaudela inolako paretara konektaturik deskargan zehar
-health.explain.blue=aletzean, esan nahi du ez zaudela inolako paretara konektaturik\ndeskargatzean, esan nahi du zenbait paretara konektaturik zaudela, baina aztarnaria bertan behera dagoela
-health.explain.yellow=esan nahi du aztarnaria ongi dagoela, pareetara konektaturik zaudela, baina ez daukazula inolako urruneko konexiorik\nZure torrent-ak egoera horian badaude etengabe, agian NAT arazoa daukazu
-health.explain.green=esan nahi du dena ongi doala.
-ConfigView.section.style.alwaysRefreshMyTorrents=Freskatu 'Nire torrent-ak' beti
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aukera honek 'Nire torrent-ak' bista freskatzen du nahiz eta begien bistan ez egon (erabilgarria zenbait mirc plugin-entzako)
+health.explain.grey=Esan nahi du zure torrenta ez dagoela (ez jeisten ez igotzen)
+health.explain.red=Esan nahi du ez zaudela inolako hartzailera elkarketaturik jeisketan zehar
+health.explain.blue=Emaletzean, esan nahi du ez zaudela inolako hartzailera elkarketaturik\njeistean, esan nahi du zenbait hartzaieetara elkarketaturik zaudela, baina aztarnaria bertan behera dagoela
+health.explain.yellow=Esan nahi du aztarnaria ongi dagoela, hartzeileetara elkarketaturik zaudela, baina ez daukazula inolako hurruneko elkarketarik\nZure torrentak egoera horian badaude etengabe, agian NAT arazo bat duzu
+health.explain.green=Esan nahi du dena ongi doala.
+ConfigView.section.style.alwaysRefreshMyTorrents=Berritu betik Liburutegia
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aukera honek Liburutegi ikuspegia berritzen du nahiz eta begien aurrean ez egon (erabilgarria zenbait mirc pluginentzako)
 #
 #2.0.7.0
 #
-security.certtruster.title=Segurtasun-ziurtagirien abisua
-security.certtruster.intro=Segurtasun-ziurtagiria fidagarritasunik onartu ez diozun konpainia batek jaulki du
+security.certtruster.title=Segurtasun Egiaztagiri Oharra
+security.certtruster.intro=Segurtasun Egiaztagiria fidagarritasunik onartu ez diozun baltzu batek jaulki du
 security.certtruster.resource=Baliabidea:
-security.certtruster.issuedto=Nori jaulkia:
-security.certtruster.issuedby=Nork jaulkia:
-security.certtruster.prompt=Fidagarritasuna onartu nah
+security.certtruster.issuedto=Nori Jaulkia:
+security.certtruster.issuedby=Nork Jaulkia:
+security.certtruster.prompt=Fidagarritasuna onartu nahi diozu?
+security.certtruster.yes=Bai
+security.certtruster.no=Ez
+ConfigView.section.tracker.torrentsperpage=Zenbat torrent orrialdeko?  [0: mugagabea]
+MainWindow.menu.file.share=Elkarbanatze-&Klasikoa
+MainWindow.menu.file.share.file=&Agiria...
+MainWindow.menu.file.share.dir=A&giritegia...
+MainWindow.menu.file.share.dircontents=Agiritegi &Edukiak...
+MainWindow.menu.file.share.dircontentsrecursive=Agiritegiko Edukiak... (&Baliabideak)
+MainWindow.dialog.share.sharefile=Hautatu Elkarbanatzeko Agiria
+MainWindow.dialog.share.sharedir=Hautatu Elkarbanatzeko Agiritegia
+MainWindow.dialog.share.sharedircontents=Hautatu Elkarbanatzeko Agiritegiko Edukia 
+MainWindow.dialog.share.sharedircontents.recursive=Balibidegarria
+globalmanager.download.remove.veto=Kenketa Ekintza Eragitza
+plugin.sharing.download.remove.veto=Jeisketa hau elkarbanatze-klasikoko baliabide baten emaitza da.\nJeisketa kentzeko elkartutako elkarbanatze-klasikoak kendu: joan Tresnak->Nire Elkarbanatze-Klasikoak.
+ConfigView.section.tracker.main=Nagusia
+ConfigView.section.tracker.web=Webgunea
+ConfigView.label.prioritizefirstpiece=Lehentasuna eman agiriko lehen eta azken atalari
+ConfigView.label.prioritizefirstpiece.tooltip=Lehen agiri baten hasiera eta amaiera jeisteko saiakerak.\nAurreikuspen hasierak sostengatzeko.
+ConfigView.section.file.delete.include_files_outside_save_dir=Datuak ezabatzerakoan, ahalbidetu torrentetik kanpo lotura duten agiriak zuzenbidea gordetzea hauek ere ezabatuak izateko 
+TrayWindow.menu.startalldownloads=Hasi Jeisketa Denak
+SystemTray.menu.startalltransfers=Hasi Eskualdaketa Denak
+sharing.progress.title=Klasikoen-Elkarbanatze Garapena
+sharing.progress.hide=Ezkutatu
+MainWindow.menu.view.myshares=Nire Elkarbanatze-Klasikoak
+MySharesView.title.full=Nire Elkarbanatze Klasikoak
+MySharesView.name=Izena
+MySharesView.type=Mota
+MySharesView.type.file=Agiria
+MySharesView.type.dir=Zuzenbidea
+MySharesView.type.dircontents=Zuzenbide edukiak
+MySharesView.type.dircontentsrecursive=Zuzenbide edukiak (baliabidea)
+MySharesView.menu.remove=Ezabatu
+ConfigView.section.tracker.extensions=Hedapenak
+ConfigView.section.tracker.sendpeerids=Bidali hartzailearen nortasuna jeistzaileetara
+ConfigView.section.tracker.enableudp=Gaitu UDP aztarnari protokoloa
+plugin.sharing.torrent.remove.veto=Aztarnari  erregistro hau elkarbanatze-klasikoako baliabide baten emaitza da.\nJeisketa kentzeko elkartutako elkarbanatze-klasikoak kendu: joan Tresnak->Nire Elkarbanatze-Klasikoak.
+plugin.download.remove.veto.notstopped=Jeisketa ezin da kendu ez delako gelditzen
+plugin.sharing.remove.veto=Elkarbanatze-klasiko hau partekatze 'zuzenbide edukiak' azpi-partekatze bat da eta ezin da ezabatua izan.\n Ezabatu elkarbanatze-klasikoak erroa
+GeneralView.label.hash.tooltip=Egin klik hasha gakoan kopiatzeko
+ConfigView.section.tracker.maxpeersreturned=Gehienezko hartzaile itzulita [0: mugagabe]
+ConfigView.label.serverport=Sarrerako TCP / UDP aditze ataka
+ConfigView.label.serverport.tooltip=Ataka barruan behar da 1-65535 lerroa, eta ez 6880 Vuzeren barne erabilpenerako gordea dagoena.
+configureWizard.nat.server.tcp_listen_port=Sarrerako TCP Aditze Ataka
+ConfigView.section.sharing=Elkarbanatze-Klasikoa
+ConfigView.section.sharing.usessl=Erabili SSL elkarbanatze -klasikoen iturburuentzat (beharrezkoa Aztarnari itxurapena)
+ConfigView.section.style.dropdiraction=Arrastatu eta Askatu ekintza zuzenbideentzat
+ConfigView.section.style.dropdiraction.opentorrents=Ireki Torrentak
+ConfigView.section.style.dropdiraction.sharefolder=Elkarbanatze-klasikoaren Zuzenbidea
+ConfigView.section.style.dropdiraction.sharefoldercontents=Elkarbanatze-klasikoaren Edukiak
+#
+# 2.0.7.x
+#
+Categories.all=Denak
+Categories.uncategorized=Kategoriatu gabeak
+CategoryAddWindow.message=Sartu kategoria izen berri bat
+CategoryAddWindow.title=Gehitu Kategori Berria
+ConfigView.label.autoSeedingIgnoreInfo=Baztertutako torrentak emaletzen lerroko beherenera doaz. Ez dira berezgaitasunez hasiko.\nBaztertu arauak ez dira Lehentasun Nagusia irizpidea duten torrentei ezartzen.\nAlderantzizkoa adierazten ez bada, erabili 0 balio bat araua ezgaitzeko.
+ConfigView.label.directory=Zuzenbidea
+ConfigView.label.disconnetseed.tooltip=Torrent bat emaletzerakoan, eten emaletzen ari diren bezeroak.\nBeraiek ez dute behar zurekin hitzegiten egotea.
+ConfigView.label.ignoreCase=Ez egin Kasurik
+ConfigView.label.ignoreSeeds=Ez egin kasu gutxienean dauden torrentei
+ConfigView.label.importdirectory=Inportatu Zuzenbidea
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=Emaletzen ez dagoen edozein torrent eta zuk adierazitakoa baino hartzaile gutxiagorekin\nlerroaren beherenera mugituak izango dira.
+ConfigView.label.minPeersToBoostNoSeeds=Emaletzen Lerrun Txikiena emaletzen ez diren torrententzat eta baino gutxiago
+ConfigView.label.minSeedingTime.tooltip=Emaletzen Lerruna sarri aldatu daiteke denbora epe labur batean, batzuetan eraginez torrenta berezgaitasunez abiaraztea, ondoren berehala geldituta eta lerrokatuta izateko..\nHonek arazoa arintzen du torrenta behartuz emaletzan egotera denbora batez.  Oraindikan eskuz gelditu dezakezu nahi baduzu.
+ConfigView.label.minSeedingTime=Gutxieneko emaletza denbora segundutan
+ConfigView.label.minSpeedForActiveDL.tooltip=Jeisketa aho bat betik da erabilia lehen 30 segundutan\nosatugabeko torrenta hasi ondoren.
+ConfigView.label.minSpeedForActiveDL=Ez zenbatu jeisketa ahoa erabiltzen ari den torrenta abiadura hau baino txikiagoa bada
+ConfigView.label.peers=hartzaileak
+ConfigView.label.queue.debuglog=Gorde garbiketa argibideak
+ConfigView.label.queue.debuglog.info=Gehitu lerro garbiketa argibideak kontsola/ohar agirira.\nEnkriptatuta izanda ere, garbiketa argibideak esaten dizu torrentaren egoera eta zergaitik dauden/ez dauden abiatzen/lerrokatzen.
+ConfigView.label.queue.minQueueingShareRatio=Ez lerrokatu edo gelditu torrenta  bere elkarbanatze maila lortu arte
+ConfigView.label.ratio=maila
+ConfigView.label.removeOnStop=Kendu torrenta zerrendatik berezgaitasunez gelditu ondoren
+ConfigView.label.savedirectory=Gorde Zuzenbidea
+ConfigView.label.seeding.autoReposition.tooltip=Gaituta badago, torrenteen ordena (Z zutabea) aldatu egingo da Emaletzen Lerrunarekin bat egin dezan.\nHau erabilgarria da zuk ez badituzu nahi ikusi Emaletzan Lerrunaren zenbakiak, baina jakin nahi duzu osatutako torrentak abiaraziko diren ordena.
+ConfigView.label.seeding.autoReposition=Berezgaitasunez birjarri Emaletza Lerrunean ohinarrituriko torrentak
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=Sarri, emaletza zenbateko apala eta hartzaile zenbeteko handia duten torrentak zihurrenik esan nahi du ez dela hartzaile arteko kopia oso bat.\nHortaz, badaiteke zuk ez nahi izatea emaletzen arauak kopia oso bat izatea (eta hortaz okerra bere lerrunaren murrizketa)
+ConfigView.label.seeding.fakeFullCopySeedStart=baina gutxienez duten torrententzat bakarrik 
+ConfigView.label.seeding.ignore=Baztertu Arauak
+ConfigView.label.seeding.ignore0Peers=Baztertu 0 hartzaileko torrentak
+ConfigView.label.seeding.ignoreRatioPeers=Baztertu bakoitzeko emale 1 duten torrentak
+ConfigView.label.seeding.ignoreShareRatio=Baztetu elkarbanatze maila hau duten torrentak
+ConfigView.label.seeding.ignore.header.evenFirstPriority=Baztertu  baita ere \nLehentasun Nagusia arauak ezarrita dituzten torrentak
+ConfigView.label.seeding.ignore.header.rule=Araua
+ConfigView.label.seeding.ignore.header.value=Balioa
+ConfigView.label.seeding.firstPriority.info=Lehentasun nagusiko torrentak betik egongo dira lerroaren gorenaldean\nLehentasun Nagusia irizpidea betetzen duen edozein torrent ez da berezgaitasunez gelditua eta lerrokatua izango.\nLehentasun Nagusia irizpidea duen torrentak Aldibereko Jeisketa ahoa hartu dezake behar izanez gero.
+ConfigView.label.seeding.firstPriority.FP=Lehentasun Nagusia
+ConfigView.label.seeding.firstPriority=Lehentasun nagusia doa hau duten torrentetara
+ConfigView.label.seeding.firstPriority.following=hurrengoetara:
+ConfigView.label.seeding.firstPriority.shareRatio=Elkarbanatze maila honen azpitik
+ConfigView.label.seeding.firstPriority.seedingMinutes=Igarotako denbora jeisten emaletzara aldatu denetik
+ConfigView.label.seeding.firstPriority.DLMinutes=Igarotako denbora jeisten hastetik
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Kopia oso 1 X hartzaileko dela saiatuz, hartzaile zenbateko handia duten torrenteen lerruna murrizten duzu.\nZihurrena da, hartzaile zenbateko handiena duten torrentak dutela ere joan-etorri handiena.\nHonek ez du aldatzen erakutsitako 'emaletzeen Z' bat ere.
+ConfigView.label.seeding.numPeersAsFullCopy=Saiatu kopia oso Bat izaten denentzat\n(0 : Ez Saiatu)
+ConfigView.label.seeding.preferLargerSwarms.tooltip=Nagusiki 'buxatuta' dauden hartzaileekin emaletzen ari bazara torrentak, nahiago izatea erletalde handiagoak zentzua du\nNagusiki eskuragarritasun handiko torrentak emaletzen ari zarenean, nahiago izatea erletalde txikiak zentzua du.
+ConfigView.label.seeding.preferLargerSwarms=Torrentak lerrun bera dutenean, nahiago izan erletalde handiak
+ConfigView.label.seeding.rankType.none.tooltip=Antolakuntza ohinarrituta Z zutabean
+ConfigView.label.seeding.rankType.none=Bat ere ez
+ConfigView.label.seeding.rankType.peer.tooltip=hartzaile gehiago eta emale gutxiago = lerrun handiagoa\nLerrun honek gutxiagotu egiten du eraginda eduki behar diren torrent zenbatekoa igoera gehieneratzeko.
+ConfigView.label.seeding.rankType.peer=Berdingarritutako Hartzaile Zenbaketa
+ConfigView.label.seeding.rankType.peerSeed.options=Hartzaile:Emaletza Maila Aukerak
+ConfigView.label.seeding.rankType.peerSeed.tooltip=Maila Handiena = Lerrun Handiena
+ConfigView.label.seeding.rankType.peerSeed=Hartzaile:Emaletza Maila
+ConfigView.label.seeding.rankType.seed.fallback=Hartzaileentzako Gordeta: Emaletza Maila ondoren  \n(0 : Inoiz Ez Gordeta)
+ConfigView.label.seeding.rankType.seed.options=Emale Zenbaketa Bakarrik Aukerak
+ConfigView.label.seeding.rankType.seed.tooltip=Emale Gutxiago = Lerrun Handiagoa
+ConfigView.label.seeding.rankType.seed=Emale Zenbaketa Bakarrik
+ConfigView.label.seeding.rankType.timedRotation.tooltip=Lerrokatutako torrent osatu guzitiak itzulikatuko dira emaletzen moduan.\nEmaletze denbora ezartzen da 'Gutxiengo Emaletza Denbora' bidez
+ConfigView.label.seeding.rankType.timedRotation=Denboratutako Itzulikapena
+ConfigView.label.seeding.rankType.tooltip=Lerrun handiena duten torrentak berezgaitasunez hasten dira.\nBeste torrent batek lerrun handiagoa lortzen duenean, lerrun txikienekoa gelditu eta lerrora itzultzen da.\n\nLerrokatuta egoeran dauden torrentak bakarrik daude baliagarri berezgaitasunez hasteko.\nGelditutako torrentak ez dira inoiz berezgaitasunez hasten.
+ConfigView.label.seeding.rankType=Lerrun osatutako torrentak berez-hasteko ohinarriturik:
+ConfigView.label.stopAfterMinutes=Behin emaletzari elkarketaturik, gelditu aldibatez
+ConfigView.label.switchpriority.tooltip=Lehentasun txikiak torrentari izendaturiko igoera bandazabalera zenbatekoa murrizten du
+ConfigView.pluginlist.info=Hurrengo pluginak ezagutuak izan dira. Plugin batzuek badaiteke ez izatea itxurapen fitxarik.
+ConfigView.pluginlist.noplugins=Ez pluginik aurkitu
+ConfigView.section.pluginslist=Zerrenda
+ConfigView.section.queue.seeding=Emaletzan
+ConfigView.section.queue.seeding.autoStarting=Berez Abiatzea
+ConfigView.section.queue.seeding.ignore=Baztertu Arauak 
+ConfigView.section.queue.seeding.firstPriority=Lehentasun Nagusia
+ConfigView.section.queue.main=Nagusia
+ConfigView.section.queue=Lerroa
+ConfigView.section.torrents=Torrentak
+ConfigView.text.all=denak
+ConfigView.text.hours=ordu
+ConfigView.text.ignoreRule=Baztertu Arauak
+ConfigView.text.ignore=Baztertu
+ConfigView.text.minutes=minutu
+ConfigView.text.neverIgnore=Ez Baztertu Inoiz
+ConfigView.text.any=edozein
+DownloadManager.error.datamissing=Gainerako Datuak
+MainWindow.menu.file.open.torrentforseeding=Torrent Agiria... (Emaletzarako)
+MainWindow.menu.language.refresh=&Berritu
+ManagerItem.forced=Behartuta
+ManagerItem.queued=Lerrokaturik
+MySeedersView.header=Osatutako Torrentak
+TableColumn.header.availability.info=Zenbat kopia oso izan diren ikusiak
+TableColumn.header.availability=Eskuragarritasuna
+TableColumn.header.category=Kategoria
+MyTorrentsView.header=Torrent Osatugabeak
+TableColumn.header.maxuploads=Geh Zenb. Igoera
+MyTorrentsView.menu.category.delete=&Ezabatu Kategoria
+MyTorrentsView.menu.forceStart=&Behartu Hastera
+MyTorrentsView.menu.queue=&Lerroan
+MyTorrentsView.menu.setCategory.add=&Gehitu Kategoria...
+MyTorrentsView.menu.setCategory=Ezarri Kategoria
+TableColumn.header.savepath=Gorde Helburua
+TableColumn.header.SeedingRank=Emaletza Maila
+TableColumn.header.totalspeed.info=Hona elkarketaturik dauden hartzaile guztien Abiarura Guztira
+TableColumn.header.totalspeed=Abiadura Guztira
+splash.initializePlugins=Pluginak Abiatzen
+StartStopRules.SPratioMet=S:P Maila Ongi
+StartStopRules.FP0Peers=FP / 0 Hartzaile
+StartStopRules.0Peers=0 Hartzaile
+StartStopRules.numSeedsMet=Emaleak Ongi
+StartStopRules.ratioMet=Hartzaileak:Emaleak Ongi
+StartStopRules.shareRatioMet=Elkarbanatze Maila Ongi
+StartStopRules.waiting=Itxaroten
+StartStopRules.firstPriority=1.Lehentasuna
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Elkarbanatze-klasikoaren Edukiak (Baliabidegarria)
+DownloadManager.error.unabletostartserver=Ezgaitu Hasi Zerbitzaria - egiaztatu sarrera atakaren ezarpenak / suhesi baimenak aplikazioa zerbitzari bezala jarduteko
+GeneralView.label.creationdate=Sortua:
+ConfigView.section.tracker.announcescrapepercentage=Zuritu tartea  % iragarpen epea\nadib. 200 = 2:1. 0 = zer erabaki hartzaile artean
+ManagerItem.stopping=Gelditzen
+ConfigView.section.tracker.announcecacheperiod=Iragarle katxea (milaen)
+ConfigView.section.tracker.scrapecacheperiod=Zuripen katxea (milis)
+ConfigView.section.tracker.scrapeandcache=Zuripena eta katxea
+ConfigView.section.tracker.announcecacheminpeers=Iragarle katxeak hartzaile muga gaitzen du
+MyTrackerView.scrapes=Zurituak
+fileDownloadWindow.retry=Saiatu berriz
+MyTrackerView.bytesin=Sar. Byte
+MyTrackerView.bytesinave=Sar. Bat.best.
+MyTrackerView.bytesout=Irt. Byte
+MyTrackerView.bytesoutave=Irt. Bat.best.
+ConfigView.section.file.max_open_files=Gehienezko agiri ireki irakurtzeko/idazteko\n[0: mugagabea]
+ConfigView.section.file.max_open_files.tooltip=Erabili ehundaka/milaka agiriko torrentak jeisketen badituzu, eta SE-ren agiri eskuragarri mugara heltzen ari bazara.
+ConfigView.section.proxy=Proxy Aukerak
+ConfigView.section.proxy.enable_proxy=Gaitu proxya aztarnariarekiko harremanetarako [birrabiaraztea beharrezkoa]
+ConfigView.section.proxy.host=Hostalaria
+ConfigView.section.proxy.port=Ataka
+ConfigView.section.proxy.username=Erabiltzaile izena
+ConfigView.section.proxy.password=Sar-hitza
+ConfigView.section.proxy.enable_socks=Nik SOCKS proxy bat dut
+wizard.createtorrent.extrahashes=Gehitu hashak beste sare batzuetatik (adib.Gnutella2, eDonkey2000)
+GeneralView.label.connected=elkarketaturik
+GeneralView.label.in_swarm=erletaldean
+ManagerItem.initializing=Abiatzen
+AlertMessageBox.error=Akatsa
+AlertMessageBox.warning=Kontuz
+AlertMessageBox.comment=Aipamena
+AlertMessageBox.information=Argibideak
+AlertMessageBox.unread=Irakurri gabeko mezu alertak dituzu. Egin klik hemen ikusteko.
+SharedPortServer.alert.selectorfailed=Huts egin du sarrerako datuen aditze ezartzeak.\nEgiaztatu suhesi ezarpenak java(w).exe baimentzen duen 'zerbitzari' bezala ekiteko
+Tracker.alert.listenfail=Huts egindu aditzea ezartzerakoan ataka honetan %1.\nEgiaztatu beste egokitzapenak ez direla ari ataka hau erabiltzen.\nEgiaztatu ere lanean diharduten Vuzeren beste kopiak.
+DiskManager.alert.movefileexists=Akatsa osatutako agiria mugitzerakoan\nAgiria %1 jadanik badago Mugitu Hona helbide zuz
+DiskManager.alert.movefilefails=Akatsa osatutako agiria mugitzerakoan\nAgiri mugitua %1 huts eginda\u005c, %2
+DiskManager.alert.movefilerecoveryfails=Berreskurapen akatsa mugitzeak hutsegin ondoren\nAgiri berreskurapena %1 huts eginda, %2
+ConfigView.section.tracker.logenable=Ohar-agiritu aldizkako estatistikak 'aztarnari.oharrak'-erako
+SpeedView.stats.title=Estatistikak
+SpeedView.stats.total=Guztia
+SpeedView.stats.session=Saio Honetan
+SpeedView.stats.session.tooltip=Guztira (Protokoloa)
+SpeedView.stats.downloaded=Jeisketa (Protokoloa)
+SpeedView.stats.uploaded=Igota (Protokoloa)
+SpeedView.stats.ratio=Maila
+SpeedView.stats.uptime=Denbora
+SpeedView.stats.now=Orain
+SpeedView.stats.now.tooltip=Guztira (Protokoloa)
+AutoMigration.useralert=Vuzek agiri/helbide itxurapen berez-migraketa erabiltzen du, emaitzak:\n\n%1\nHutsegite batzuk eskuz migratzea beharrezkoa da.\nEZ AHAZTU EGUNERATZEAZ GORDETAKO ZURE HELBURUAK ITXURAPENEAN  MIGRATU EGIN BADUTE!
+#
+# > 2.0.8.0
+#
+OpenTorrentWindow.title=Ireki Torrenta(k)
+OpenTorrentWindow.message=Esperimentala
+OpenTorrentWindow.addFiles=&Gehitu Agiriak
+OpenTorrentWindow.dataLocation=Datuak gordetzeko helbidea:
+OpenTorrentWindow.startMode=Gehitu Modua
+OpenTorrentWindow.startMode.queued=Lerrokaturik
+OpenTorrentWindow.startMode.stopped=Geldituta
+OpenTorrentWindow.startMode.forceStarted=Behartu Hastea
+OpenTorrentWindow.addPosition=Lerroko Kokapena
+OpenTorrentWindow.addPosition.first=Lehena
+OpenTorrentWindow.addPosition.last=Azkena
+TableColumn.header.remaining.info=Jeisteke dagoenaren zenbatekoa
+TableColumn.header.remaining=Egiteke
+ConfigView.section.tracker.enablecompact=Gaitu iragarpen harreman trinkoa
+ConfigView.section.tracker.enablekey=Gaitu giltza sartzea aztarnariarentzat segurtasuna hobetzeko
+ConfigView.section.file.perf=Eginaldi Aukerak
+ConfigView.section.file.perf.explain=Kontuz - Neurri hauen aldaketek kalterako eragin dezakete jeisketan. Birrabiarazpena beharrezkoa da.\n'oraimen gabe' arazoak badituzu torrent elkarketak mugatzea kontuan hartu beharko duzu. (Ikusi Eskualdaketa itxurapena)
+ConfigView.section.file.max_open_files.explain=Agiri asko irekitzeak arazoak eragiten ditzeke sistema eragilean, baliabide mugapena agiri eskuratzean bezalakoak. Honek aldiberean irekita egon daitezkeen agiriak mugatzen du.
+popup.error.hide=Ezkutatu
+popup.error.details=Xehetasunak
+ConfigView.section.style.colorOverrides=Margo Ezabatuak
+ConfigView.section.style.colorOverride.progressBar=Garapen Barra
+ConfigView.section.style.colorOverride.error=Akatsa
+MainWindow.status.tooOld=zaharra da, mesedez eguneratu ezazu
+ConfigView.section.style.colorOverride.warning=Kontuz
+ConfigView.section.style.colorOverride.altRow=Aldizkako lerroak
+ConfigView.section.file.save.peers.enable=Gorde hartzaile elkarketak birrelkarketa azkarretarako
+ConfigView.section.file.save.peers.max=Gehienezko hartzaile gordetzeko [0:mugagabe]
+ConfigView.section.file.save.peers.pertorrent=torrent bakoitzeko
+ConfigView.label.max_peers_per_torrent=Geh elkarketa torrent bakoitzeko [0: mugagabea]
+ConfigView.label.max_peers_total=Geh.elkarketa globalean [0: mugagabea]
+ConfigView.section.style.colorOverrides.reset=Birrezarri Margoa
+ConfigView.section.language.info=Gaituta dagoenean,  eguneratze egiaztapena Vuze abiarazten den bakoitzean egingo da.
+ConfigView.section.language.enableUpdate=Gaitu Web Eguneraketa
+ConfigView.section.language.UpdateURL=Eguneratu URL-a
+ConfigView.section.language.UpdateNow=Eguneratu Orain!
+Button.revert=Jauzi atzera
+MyTorrentsView.menu.changeDirectory=Aldatu Datu Zuzenbidea
+GenericText.column=zutabea
+MyTorrentsView.menu.thisColumn.remove=Ezabatu Zutabea
+MyTorrentsView.menu.thisColumn.toClipboard=Kopiatu Idatzia Gakoan
+MyTorrentsView.menu.thisColumn.autoTooltip=Betik erakutsi tresnen argibideak
+MyTorrentsView.menu.tracker=Aztarnaria/Torrenta
+TableColumn.header.secondsseeding=Emaletzen
+TableColumn.header.secondsseeding.info=Emaletzen egon zaren denboraren zenbatekoa guztira
+TableColumn.header.secondsdownloading=DLing-a 
+TableColumn.header.secondsdownloading.info=Jeisten egon zaren denboraren zenbatekoa guztira.
+ConfigView.section.tracker.udpversion=UDP Protokolo Bertsioa (1 edo 2)
+window.updateswt.title=Zure SWT Bertsio zaharregia da!
+window.updateswt.text=Zure SWT Bertsioa zaharregia da!\nSWT Vuzek erabiltzen duen grafiko liburutegia da eta zuk duzun bertsioa zaharregia da Vuzeren azken bertsioarekin lan egiteko. Klikatu 'Ongi' botoia zure SWT-a eguneratzeko.
+window.updateswt.status=Egoera
+window.updateswt.failed=Eguneratzeak huts egin du, sakatu Ongi berriro birrabiarazteko.
+window.updateswt.status.downloading.updater=Eguneratze Modulo Jeisten
+window.updateswt.status.finding=SWT Betsio berriena bilatzen
+window.updateswt.status.downloading=SWT Bertsio Berriena Jeisten
+window.updateswt.status.done=Birrabiarazten
+window.updateswt.ok=Ongi
+window.updateswt.cancel=Ezeztatu
+swt.updater.downloader.downloading=SWT hemendik jeisten
+swt.updater.urlsgetter.downloading=Izpilu zerrenda bat lortu hemendik
+swt.updater.urlsgetter.platform=SWT plataformarako
+window.updateswt.ignore=Ez ikusi
+ConfigView.section.style.useFancyTabs=Erabili Apain Fitxak
+splash.initializeGM=Torrent Kudeatzaile Globala Abiatzen
+splash.loadingTorrents=Torrentak Gertatzen
+splash.firstMessageNoI18N=(: Vuze 4.6.0.2 :)
+MyTorrentsView.menu.thisColumn.sort=&Antolatu
+Scrape.status.ok=Zuritzea Ongi
+Scrape.status.error=Zuritze Akatsa:
+Scrape.status.error.badURL=Iragarle URL-ak ez ditu zuritze zehaztapenak jarraitzen.
+Scrape.status.error.nohash=Hasha erantzun gabe.
+Scrape.status.error.invalid=Erantzun okerra.
+Scrape.status.nextScrapeAt=Hurrengo zuritzea %1
+Scrape.status.scraping=Zuritzen...
+Scrape.status.initializing=Zuritzeko itxaroten...
+Scrape.status.scraping.queued=Lerrokatuak zuritzen...
+ConfigView.label.minSpeedForActiveSeeding=Ez zenbatu osatutako torrentik aho bat erabiltzen ari bada abiadura honen azpitik badago
+ConfigView.section.stats.exportpeers=Esportatu hartzaile xehetasunak
+MainWindow.menu.view.irc.moved=Irc orain eskuragarri dago plugin bezala, ikusi http://plugins.vuze.com/plugin_list.php. Ezarritakoan erabili ikuspegi hau ->pluginak->IRC sarbide menua.
+MyTrackerView.webui.contextmenu.copyurl=Kopiatu torrentaren URL-a gakoan
+ConfigView.section.file.torrent.ignorefiles=Baztertzeko agiriak torrentak sortzen/ezabaten ari direnean\n - adib. .DS_Store;Thumbs.db
+Torrent.create.progress.ignoringfile=Agiria baztertzen
+ConfigView.section.style.useUnitsRateBits=Erabili bit-ak byte-n ordez byte-ohin maila balioetan  (KiB/s->Kibit/s etab.)
+ConfigView.section.interface.resetassoc=Leheneratu explorer agiri elkartzea (.torrent) eta erakarpen agintea (magnet:?xt=...)
+ConfigView.section.interface.resetassocbutton=Birrezarri
+ConfigView.section.interface.checkassoc=Egiaztatu elkartzeak hasitakoan
+dialog.associations.title=Elkartze Egiaztapena
+Button.yes=&Bai
+Button.no=&Ez
+ConfigView.label.seeding.autoStart0Peers=Berez Hasi 0 hartzaile duten osaturiko torrent denak
+ConfigView.label.seeding.autoStart0Peers.tooltip=Piztu nahi baduzu aztarnariak betik zerrendatzea emaletzak 0 hartzaile torrenteko.
+dialog.associations.prompt=Vuze ez da BitTorrent agirientzako egitarau lehenetsia.\nNahi duzu .torrent agiriak Vuzereikin elkartzea
+dialog.associations.askagain=Egiaztatu hasitakoan
+ConfigView.section.plugins.update=Plugin Eguneratzea
+Plugin.pluginupdate.enablecheck=Gaitu plugin eguneratze egiaztapena
+plugins.basicview.status=Egoera:
+plugins.basicview.activity=Jarduera:
+plugins.basicview.progress=Garapena:
+plugins.basicview.log=Saioa:
+ConfigView.label.maxdownloadspeed=KB/s geh. jeisketa abiadura globala [0: mugagabea]
+splash.loadingTorrent=Torrenta Gertatzen
+splash.of=.
+UpdateWindow.title=Vuze Eguneratzailea
+UpdateWindow.header=Hurrengo osagaiek eguneraketa behar dute:
+UpdateWindow.columns.install=Ezarri
+UpdateWindow.columns.name=Izena
+UpdateWindow.columns.version=Bertsioa
+UpdateWindow.columns.size=Neurria
+UpdateWindow.cancel=Ezeztatu
+UpdateWindow.quit=Irten
+UpdateWindow.close=Itxi
+UpdateWindow.ok=Eguneratu
+UpdateWindow.restart=Birrabiarazi Vuze Orain
+UpdateWindow.status.downloading=Jeisten
+UpdateWindow.status.done=Egina
+UpdateWindow.status.failed=Huts egin du
+UpdateWindow.status.restartNeeded=Birrabiaraztea beharrezkoa da!
+ConfigView.pluginlist.broken=Hautsita
+ConfigView.pluginlist.whereToPut=Ezarri erabiltzaile osagarri bereiziak zeure zuzenbidean: 
+ConfigView.pluginlist.whereToPutOr=Partekatutako pluginentzat erabili:
+MainWindow.statusText.checking=Bilatu Eguneraketak
+TableColumn.header.OnlyCDing4=CDing4 Bakarrik
+TableColumn.header.OnlyCDing4.info=Torrenta emaletzan bakarrik egon den denbora. Kenduta torrenta jeisten (eta emaletzan) egon den denbora.
+ConfigView.section.style.alternateTablePainting=Erabili aldizkako bidea aurkibide grafikoen zutabea margotzeko (birrabiaraztea beharrezkoa izan daiteke)
+UpdateWindow.status.restartMaybeNeeded=Birrabiaraztea beharrezkoa izan daiteke
+ConfigView.pluginlist.shared=partekaturik
+PeersView.host=Ostatu Izena
+PeersView.host.info=Hartzailearen ostatu izena, eskuragarria denean (egintzari eragin diezaioke)
+MainWindow.menu.help.whatsnew=Zer Berri
+ConfigView.label.checkonstart=Egiaztatu azken bertsioa dudala Vuze abiaturikoan
+ConfigView.label.periodiccheck=Egiaztatu aldizka azken bertisioa ezarrita dagoela
+ConfigView.label.opendialog=Berezgaitasunez ireki Eguneratze Laguntzailea eguneraketa eskuragarri dagoenean
+MainWindow.updateavail=Egin klik hemen eguneraketak bilatzeko
+MainWindow.status.latestversionunchecked=Bertsio egiaztapena ezgaiturik
+GeneralView.label.updatein.stopped=Geldituta
+StartStopRules.menu.viewDebug=Ikusi Garbiketa Argibideak
+ConfigView.section.style.doNotUseGB=Ez erabili GB batasunik
+ConfigView.section.style.doNotUseGB.tooltip=Egiaztaturik badago, Vuzek jarraitu dezake erabiltzen MB baita 1024 MB baino handiagoak diren neurriekin
+MainWindow.menu.help.plugins=Lortu Pluginak
+ConfigView.section.plugins.TrackerWeb=Aztarnari Webgunea
+ConfigView.section.tracker.enablecategories=Banandu torrentak kategoriatan
+health.explain.share=Esan nahi du torrenta ongi ostatuta edo argitaratuta
+ConfigView.section.tracker.createcert=Sortu bere-izenpetze egiaztagiria
+ConfigView.section.tracker.createbutton=Sortu
+security.certcreate.title=Sortu Bere-Sinatze Egiaztagiria
+security.certcreate.intro=Elkarrizketa honek bere-sinatze egiaztagiri bat sortzea ahalbidetzen ditzu
+security.certcreate.alias=Ezizena
+security.certcreate.strength=Indarra
+security.certcreate.firstlastname=Lehen eta bigarren  izena
+security.certcreate.orgunit=Erakunde Batasuna
+security.certcreate.org=Erakundea
+security.certcreate.city=Hiria edo Herria
+security.certcreate.state=Estatua edo Herrialdea
+security.certcreate.country=Bi hizkiko estatu kodea
+security.certcreate.ok=Sortu
+security.certcreate.cancel=Ezeztatu
+security.certcreate.createok=Egiaztagiria ongi sortu da
+security.certcreate.createfail=Egiaztaturiko sortzeak huts egin du
+ConfigView.section.plugins.webui=Swing Web Interfazea
+ConfigView.section.plugins.xml_http_if=XML/HTTP Interfazea
+webui.passwordenable=Gaitu sar-hitza
+webui.user=Erabiltzaile izena
+webui.password=Sar-hitza
+webui.port=Ataka
+webui.protocol=Protokoloa
+webui.homepage=Etxeko orrialdea
+webui.rootdir=Erro zuzenbidea
+webui.rootres=Baliabide erroa
+webui.mode=Modua
+webui.mode.info=Modua izan daiteke\n\t"full"\t= eragiketa guztiak egingarri (berezkoat)\n\t"ikusi"\t= ikusi bakarrik (baina berritze maiztasuna eguneratu dezake)
+webui.access=Sarbidea
+webui.access.info=Sarbidea izan daiteke\n\t"tokikoa"\t= tokiko gailua bakarrik elkarketatu daitekela\n\t"denak"\t= eragozpen gabeko sarbidea (berezkoa)\n\tIP-a\t= e.g. 192.168.0.2\t\t\u005c IP-a bakarrik\n\tIP1-IP2\t= adib. 192.168.0.1-192.168.0.255\u005cIP eremuak barne
+GeneralView.label.maxdownloadspeed=Jeisketa Muga
+Security.keystore.corrupt='%1' giltzabiltegiak huts egin du, mesedez ezabatu hura eta birsortu/bir-inportatu egiaztagiriak
+Security.keystore.empty=Giltzabiltegia hutsik dago. Mesedez sortu bere-izenemate egiaztagiri bat (ikusi Tresnak->Aukerak->Segurtasuna) edo inportatu jadanik '%1' baduzun egiaztagiri bat 
+GeneralView.label.maxdownloadspeed.tooltip=geh. jeisketa abiadura [0: mugagabea]
+upnp.enable=Gaitu UPnP
+upnp.info=Plug and Play Unibertsalak (UPnP) ahalbidetzen du berezgaitasunezko ataka izendatzea gaituriko UPnP routerretan.
+upnp.mapping.dataport=Sarrerako Hartzaile Datu Ataka
+upnp.mapping.tcptrackerport=TCP Aztarnari Ataka
+upnp.mapping.udptrackerport=UDP Aztarnari Ataka
+upnp.alert.differenthost=UPnP: Izendapena '%1' hartuta dago '%2' - mesedez aukeratu ataka ezberdin bat
+upnp.alert.mappingok=UPnP: Izendapena '%1' ezarrita
+upnp.alert.mappingfailed=UPnP: Izendapenak '%1' huts egin du
+upnp.alertsuccess=Jakinarazi zuzen egindako izendapenak
+upnp.alert.lostdevice=UPnP: Zerbitzuarekin elkarketa etenda '%1' UPnP gailuan '%2'
+upnp.grabports=Ataken mapaketa egin beste ordenagailu batekoak izanda ere
+upnp.refresh.label=Berritu mapaketak
+upnp.refresh.button=Berritu
+upnp.alert.mappinggrabbed=UPnP: Izendapena '%1' ezarrita - helduta '%2'
+upnp.mapping.tcpssltrackerport=TCP SSL Aztarnari Ataka
+upnp.alertothermappings=Beste ordenagailuetako ataken berri eman
+upnp.alertdeviceproblems=Jakinarazi UPnP gailuarekin izandako arazoak
+upnp.trace_to_log=Irteerako garbiketa argibide osoa saioa hasteko
+upnp.wiki_link=Vuze Wiki orrialdea UPnP-n
+upnp.refresh_mappings_on_bad_nat=Berezgaitasunez berritu izendapenak  NAT egoera "suhesiturik" denean
+blank.resource=baliabidea
+ConfigView.pluginlist.coreplugins=Hurrengo baterapen pluginak gertatu dira:
+Peers.column.DLedFromOthers=Beste Batzuetatik
+Peers.column.DLedFromOthers.info=Zurekin elkarketatutakoan beste batzuengandik jeitsitako datu zenbatekoa
+Peers.column.UpDownRatio=Igo:Jeitsi
+Peers.column.UpDownRatio.info=Hartzailearen "Igota:Jeitsita" Maila
+Peers.column.UpRatio=Igoera Maila
+Peers.column.UpRatio.info=Hartzailearen "Zuretik Igota : Besteetatik Igota" Maila
+upnp.releasemappings=Izendapen askapena itxieran
+webui.upnpenable=Gaitu UPnP ataka honentzat
+ConfigView.section.file.friendly.hashchecking=Lagunarteko hash egiaztapena
+ConfigView.section.file.friendly.hashchecking.tooltip=Atal hashegiaztepen modu astiroagoa baina estutasun gutxiagokoa cpu/sistemarentzat.
+ConfigView.section.tracker.seedretention=Geh. emaletza atxikia torrent bakoitzeko [0:mugagabea]
+ConfigView.section.tracker.seedretention.info=Oharra: Igoera estatistikak galdu egin daitezke emaletza ez-atxikietan
+ConfigView.section.tracker.port=Gaitu aztarnaria HTTP atakan
+ConfigView.section.tracker.sslport=Gaitu aztarnaria HTTPS atakan
+ConfigView.section.tracker.publicenable.info=Honek besteei ahalbidetzen die zure aztarnaria erabiltzen duten torrentak sortzea\nzuk haiek ostaturatu/argitaratu gabe
+Button.clear=Garbitu
+MainWindow.IPs.tooltip=Iragazki zerrendaren azken eguneratzea: %1\nGuztira IP Iragazkiak zerrendan - Itxitako/eragotzitako/gaitz IP-ak saio honetan.\nKlik bikoitza xehetasunak ikusteko.
+ConfigView.section.ipfilter.list.banned=Eragotzia izan da
+ConfigView.section.ipfilter.list.baddata=datu gaitzak bidali ditu.: gertaerak =
+Button.reset=Birrezarri
+ConfigView.section.ipfilter.bannedinfo=Datu gaitzek bidaltzen duten IP-ak - eragotzi muga gainditzen badute
+ConfigView.section.ipfilter.blockedinfo=IP iragazkiengaitik itxiak izan diren IP-ak
+download.removerules.name=Kenketa Arauak
+download.removerules.unauthorised.info=Baimengabeko torrentak dira iragarri erantzunean "ez baimendua" edo "baimengabea" dutenak "hutsegite erantzunean" 
+download.removerules.unauthorised=Berezgaitasunez kendu baimengabeko torrentak
+download.removerules.unauthorised.seedingonly=\tEmaletzan bakarrik
+download.removerules.removed.ok=Ongi buruturiko torrenteen '%1' berezgaitasunezko kenketa . Hau torrenteen kenketa arauengaitik zen.
+download.removerules.updatetorrents=Kendu Vuze eguneratze torrentak erletaldeak eskatzen badu
+ConfigView.label.defaultstarttorrentsstopped=Lehenespenez gehitu torrent berriak geldituta egoera batean
+ConfigView.section.server.enableudp=Gaitu UDP aztarnari bezero protokoloa
+upnp.mapping.dataportudp=UDP aztarnari bezero ataka
+ConfigView.section.file.decoder.showlax=Erakutsi aukera gutxieneko kodeaketak
+ConfigView.section.file.decoder.showall=Kontuan izan ahalezko kodeaketa denak
+MainWindow.status.updowndetails.tooltip=Jeisketa/Igoera abiadura xehatasunak\nEskuin-klikaketa aldatzeko, Klik Bikoitza estatistikak irekitzeko
+TrackerClient.announce.warningmessage=Aztarnaria '%1' larri itzuli da '%2'
+ConfigView.section.tracker.natcheckenable=Egiaztatu 'sarrera datu ataka' elkarketagarritasuna eta jakinarazi akatsak hartzaileei
+ConfigView.section.tracker.publishenabledetails=Argitaratu torrent guztien xehetasunak
+ConfigView.section.tracker.publishenablepeerdetails=Argitaratu hartzaile xehetasunak
+MyTrackerView.badnat=NAT Gaitzak
+MyTrackerView.badnat.info=NAT egiaztapen bat huts eginda duten Emale/Hartzaileak, gaituta badago
+ConfigView.section.tracker.natchecktimeout=Egiaztatu itxaronaldia (seg)
+ConfigView.section.file.perf.cache.enable=Gaitu diska katxea
+ConfigView.section.file.perf.cache.size=Katxe neurria %1
+MainWindow.menu.transfers=&Eskualdaketak
+MainWindow.menu.transfers.startalltransfers=Ha&si Denak
+MainWindow.menu.transfers.stopalltransfers=Ge&lditu Denak
+MainWindow.menu.transfers.pausetransfers=&Pausatu
+MainWindow.menu.transfers.resumetransfers=&Jarraitu
+ConfigView.label.experimental.osx.kernel.panic.fix=Finkapen esperimentala kernel panics dual-cpu OSX sistemarentzat [birrabiaraztea beharrezkoa]
+SystemTray.menu.pausetransfers=Pausarazi Eskualdaketak
+SystemTray.menu.resumetransfers=Jarraitu Eskualdaketekin
+ConfigView.section.file.truncate.too.large=Moztu handiegiak diren agiriak
+ConfigView.section.file.perf.cache.trace=Marraztu katxe eragiketak igarpen asmoetarako
+ConfigView.section.interface.enabletray=Gaitu Erabide Erretilua [birrabiaraztea beharrezkoa]
+PeerManager.status.error=Akatsa
+Stats.title.full=Estatistikak
+TransferStatsView.title.full=Eskualdaketak
+CacheView.title.full=Katxea
+CacheView.general.size=Neurria Guztira
+CacheView.general.inUse=Erabiltzen
+CacheView.general.title=Katxe Argibideak
+CacheView.reads.title=S/I Irakurriak
+CacheView.reads.fromFile=Agiritik
+CacheView.reads.fromCache=Katxetik
+CacheView.reads.hits=Kolpeak
+CacheView.writes.title=S/I Idatziak
+CacheView.writes.toCache=Katxera
+CacheView.writes.toFile=Agirira
+CacheView.writes.hits=Gordeta
+CacheView.speeds.title=Datu Neurriak
+CacheView.speeds.reads=Irakurriak
+CacheView.speeds.writes=Idatzirik
+CacheView.speeds.fromCache=Katxetik/Katxera
+CacheView.speeds.fromFile=Agiritik/Agirira
+CacheView.reads.#=Zenb.
+CacheView.reads.amount=Zenbatekoa
+CacheView.reads.avgsize=Neurri Bataz-bestekoa
+openUrl.referrer=Orrialde URL-ari dagozkionak:
+openUrl.referrer.info=Beharrezkoa bakarrik eskatzen duten webguneetan
+ConfigView.label.maxuploadspeedseeding=Ordezpen maila emaletzan bakarrik dagoenean
+ConfigView.label.transfer.ignorepeerports=Baztertu datu ataka hauek dituzten hartzaileak (';' bananduta, adib. 0;25)
+ConfigView.section.proxy.enable_socks.peer=Gaitu proxya hartzaileekiko harremanetarako (kanporako elkarketak bakarrik) [birrabiaraztea beharrezkoa]
+ConfigView.section.proxy.peer.informtracker=Jakinarazi aztarnariari mugapena
+ConfigView.section.proxy.socks.version=SOCKS bertsioa
+PiecesView.legend.written=Idatzia
+PiecesView.legend.requested=Eskabidetuta
+PiecesView.legend.downloaded=Jeitsita, idazketa itxaroten
+PiecesView.legend.incache=Datua Katxean dago
+PiecesView.typeItem.0=Astiroa
+PiecesView.typeItem.1=Azkarra
+PiecesView.type=Mota
+Security.jar.tools_not_found=JAR sinadura okerra - 'tools.jar' ez da aurkitu hemen %1. Ikusi Tresnak->Aukerak->Segurtasuna xehetasunetarako.
+Security.jar.signfail=JAR sinadura okerra - %1
+ConfigView.section.security.toolsinfo=JAR agiri izenpetuak plugin batzuk laguntzeko erabiltzen dira, adibidez Swing Web Interfazea (hori egiteko itxuratzen denean).\nJAR agiriak izenpetzeko asmoarekin beharrezkoa da Sun JDK (ez JRE) ezarpenarekin datorren 'tools.jar' agirira sarbidea izatea.\nJRE bakarrik baduzu ezarrita mesedez ezarri ezazu JDK.\nVuzek agiria zure ordez bilatu dezake. Horrela ere, honek huts egiten badu zeuk agerian ezarri dezakezu hemen edukiaren zuzenbidea.
+ConfigView.section.security.toolsdir='tresnak.jar' dituen zuzenbidea
+ConfigView.section.security.choosetoolssavedir=Hautatu 'tools.jar' duen agiritegia
+authenticator.torrent=Torrenta
+ConfigView.section.proxy.peer.same=Erabili proxy ezarpen berberak aztarnari eta hartzaileekiko harreman proxyan
+ConfigView.section.connection.network.max.simultaneous.connect.attempts=Gehienezko aldibereko irteera elkarketa ahalegin
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Gehienezko irteera elkarketa berri ezartzen saiatu behar den Vuze une jakin batean.\nOHARRA: WindowsXP Service Pack 2 (SP2)-k ezartzen du erabide guztiarentzako aldibereko 10 elkarketa ahalegineko muga..\nBerezko balioa 8 da.
+ConfigView.section.file.perf.cache.size.explain=Katxea diska gogorrean egiten diren irakurketa/idazketa kopurua gutxiagotzeko erabiltzen da. Javaren '-XX:MaxDirectMemorySize' aukera erabili ezean katxearentzako eskuragarri dagoen oroimena eta sarearen S/I erabilpena agerian ezartzeko, balio hau zure VM-aren gehienezko neurriaren %1 azpitik eduki behar duzu. Oraingo VM-aren gehienezko neurria %2 da. Hau nola aldatu jarraipideak lortzeko, ikusi MemoryUsage wikian %3. Ezarpen sentikorretan  [...]
+MyTorrentsView.menu.setSpeed.unlimit=Mugagabea
+MyTorrentsView.menu.setSpeed.unlimited=Mugagabea
+MyTorrentsView.menu.setSpeed.disable=Ezgaitu Igoera
+MyTorrentsView.menu.setSpeed.disabled=Ezgaiturik
+MyTorrentsView.menu.setSpeed.in=*
+MyTorrentsView.menu.setSpeed.slots=ahoak
+GeneralView.label.maxuploadspeed=Igoera Muga
+GeneralView.label.maxuploadspeed.tooltip=geh. igoera abiadura [0 : mugagabea]
+MyTorrents.items.UpSpeedLimit.disabled=Ez igo
+MyTorrents.items.UpSpeedLimit.unlimited=Mugagabe
+TableColumn.header.maxupspeed=Geh. Igoera Abiadura
+TableColumn.header.maxupspeed.info=Hartzailean ezarritako igoera abiadura muga
+ConfigView.section.file.perf.cache.enable.write=Katxeak datuak jeisten ditu diskaren idazketak gutxitzeko eta baita ere gutxitzen du diskak atal egiaztapenerako egin behar dituen irakurketak
+ConfigView.section.file.perf.cache.enable.read=Egin irakurri-aurrera diskaren irakurketak gutxitzeko igotzen ari zarenean
+ConfigView.section.tracker.separatepeerids=Erabili hartzaile nortasun ezberdinak aztarnariarentzat eta datu harremanerako
+ConfigView.section.tracker.separatepeerids.info=Izengabeko jarduera handituz jeisketa/emaletza izengabean\nez-izengabeko aztarnari elkarketa erabiltzen den bitartean
+ConfigView.section.interface.wavlocation=Helbidea .wav agiriarentzat
+ConfigView.section.interface.wavlocation.info=Hautatu .wav agiria edo utzi hutsik berezko soinuarentzat
+ConfigView.section.tracker.server=Zerbitzaria
+ConfigView.section.tracker.client=Bezeroa
+ConfigView.section.tracker.client.connecttimeout=Elkarketa itxaronaldia (seg)
+ConfigView.section.tracker.client.readtimeout=Irakurri itxaronaldia (seg)
+MainWindow.menu.tools=&Tresnak
+FilesView.path=Helburua
+FilesView.fullpath=Erakusi Helburu Osoa
+FilesView.remaining=Gainerako atalak
+TableColumn.header.trackername=Aztarnariaren Izena
+TableColumn.header.trackername.info=URL iragarpenean ohinarrituriko aztarnariaren izena
+ConfigView.group.override=Gain Aukerak
+ConfigView.section.file.perf.cache.notsmallerthan=Ez hau baino katxe agiri txikiagoak (%1)
+PeersView.menu.blockupload=Bloke Igoera
+PeersView.menu.kickandban=Ostikada eta Eragotzi
+PeersView.menu.kickandban.reason=Hartzailea eskuz eragotzia
+PeersView.state=Egoera
+PeersView.state.info=Hartzaile elkarketaren egoera
+PeersView.state.pending=Zain
+PeersView.state.connecting=Elkarketatzen
+PeersView.state.handshake=Eskukadaren zain
+PeersView.state.established=Osoki ezarrita
+ConfigView.section.tracker.processinglimits=Mugak prozesatzen
+ConfigView.section.tracker.maxgettime=Geh. denbora GET jardunerako (seg) [0: mugagabea]
+ConfigView.section.tracker.maxgettime.info=Iragarle eta zuritzetarako erabilia
+ConfigView.section.tracker.maxposttimemultiplier=GET denbora biderkatzailea POST jardunerako [0: mugagabea]
+ConfigView.section.tracker.maxposttimemultiplier.info=Erabilia azpieginkizunetarako eta igoeretarako
+ConfigView.section.tracker.maxthreads=Geh. eskabide aldiberean
+DownloadManager.error.operationcancancelled=Eragiketa ezeztatuta
+Torrent.create.progress.cancelled=Eragiketa ezeztatua
+sharing.progress.cancel=Ezeztatu
+wizard.maketorrents.autoopen=Ireki torrenta emaritzarako egindakoan
+ConfigView.section.sharing.rescanenable=Gaitu aldizkako birmihaketak elkarbanatze-klasikoetan aldaketentzat
+ConfigView.section.sharing.rescanperiod=Birmihaketa aldia (seg)
+ConfigView.section.connection.advanced=Sare Ezarpen Aurreratua
+ConfigView.section.connection.advanced.mtu=Gehienzko Eskualdaketa Batasuna (GEB) Bidea
+ConfigView.section.connection.advanced.mtu.tooltip=Sare bateko mugarri batean eskualdatu daitekeen pakete baten gehienezko neurria.\nVuzek MTU-40 (MSS) erabiltzen du paketeen-zamaerabilgarri igoera hoberenduenak egiteko.\nBalio gomendatuak:\n  576 - Urritizkin elkarketatarako\n1492 - PPPoE bandazabaleko elkarketetarako\n1500 - Ethernet, DSL eta Kable bandazabaleko elkarketetarako.
+ConfigView.section.connection.advanced.SO_RCVBUF=Hartunea SE_RCVBUF neurria [0: erabili SE berez]
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=SO_RCVBUF indar hartune estandarra ezartzen du, balioa (byte-tan), esanahi da, TCP leihoaren harrera eta eskala neurria.\nVuzek ezarri gabe uzten du berez, esanahi da azpiko SE-arentzako balio aurrezarriak erabili egiten dira.\nOHARRA; Linux bikoiztu egiten du emaniko balioa.
+ConfigView.section.connection.advanced.SO_SNDBUF=Hartune SO_SNDBUF neurria [0: erabili SE berez]
+ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=SO_SNDBUF indar hartune estandarra ezartzen du, balioa (byte-tan), esanahi da, TCP leihoaren harrera eta eskala neurria.\nVuzek ezarri gabe uzten du berez, esanahi da azpiko SE-arentzako balio aurrezarriak erabili egiten dira.\nOHARRA; Linux bikoiztu egiten du emaniko balioa.
+ConfigView.section.connection.advanced.IPDiffServ=Irteera pakete DiffServ balioa (TOS eremua)
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=Zerbitzu Mota (TOS) eremuaren DiffServ atala ezartzen du IP buruan irteerako paketeentzat.\nBalio Hexadezimalak aurrezenbaki batez adierazi daitezke '0x', adib. 0x10.\nVuzek hau berez ezarrigabe uzten du, esanahi da azpiko SE-rentzako balio aurrezarriak erabili egiten dira\nOHARRA: Azpiko sarebideak balio hauek baztertu ditzeke, hortaz aukera hau SE eta JavaRuntimeEnvironmet (JRE) bertsioaren oso araberakoa da.
+TableColumn.header.seed_to_peer_ratio=Emale-Hartzaile harremana
+TableColumn.header.seed_to_peer_ratio.info=Erletaldeko emale eta hartzeile arteko harremana guztira
+PeersView.connected_time=Elkarketaturiko Denbora
+PeersView.connected_time.info=Hartzailearekin elkarketaturik emaniko denbora guztia
+TableColumn.header.maxdownspeed=Geh. Jeisketa Abiadura
+TableColumn.header.maxdownspeed.info=Hartzailean ezarritako jeisketa abiadura muga
+PeersGraphicView.title=Erlataldea
+ConfigView.section.tracker.passwordwebhttpsonly=HTTPS bidez bakarrik eskuratzea ahalbidetuta
+TableColumn.header.torrentpath=Torrent Helbidea
+TableColumn.header.torrentpath.info=Torrentak diskan duen helbidea
+ConfigView.section.sharing.torrentcomment=Sortutako torrententzako aipamenak
+ConfigView.label.copyanddeleteratherthanmove=Kopiatu eta orduan ezabatu jatorrizko datuak eragiketa bakar batean mugitu beharrean - lagundu dezake datuen galera eragozten agiri erabide batzuetan
+ConfigView.label.openstatsonstart=Ireki Estatistikak hasitakoan
+swt.install.window.title=Vuze Osagai/Plugin Ezartzailea
+swt.install.window.ok=Ezarri
+swt.install.window.header=Hurrengo osagaiak ezarriak izateko hautatuak izan dira:
+swt.uninstall.window.title=Vuze Osagai/Plugin Kentzailea
+swt.uninstall.window.ok=Kendu
+swt.uninstall.window.header=Hurrengo osagaiak kenduak izaeko hautatuak izan dira:
+installPluginsWizard.title=Ezarri Pluginak
+installPluginsWizard.mode.title=Mesedez hautatu ezarpen bide bat
+installPluginsWizard.mode.list=Sourceforge.net-eko zerrendatik
+installPluginsWizard.list.title=Plugin Ezarrigarrien Zerrenda
+installPluginsWizard.list.loading=Mesedez itxaron Plugin zerrenda gertatzen den bitartean.
+installPluginsWizard.list.loaded=Mesedez hautatu ezarri nahi dituzun pluginak.
+installPluginsWizard.list.name=Izena
+installPluginsWizard.list.version=Bertsioa
+installPluginsWizard.list.description=Pluginaren azalpena
+installPluginsWizard.finish.title=Ezarpena Garatzen
+installPluginsWizard.finish.explanation=Hautatutako Pluginak Eguneratze Laguntzailea erabiliz ezarri daitezke.\n\nMesedez lasai hartu, denbora apur bat behar izan dezake agertzeko.\n\nGarapenaren berri izateko, egin klik bikoitza egoera barraren ezkerraldean.
+installPluginsWizard.details.loading=Xehetasunak gertatzen, mesedez itxaron...
+installPluginsWizard.mode.file=Agiritik
+installPluginsWizard.installMode.title=Mesedez hautatu ezarpen mota
+installPluginsWizard.installMode.user=Ezarri plugina(k) zuretzat bakarrik
+installPluginsWizard.installMode.shared=Ezarri plugina(k) erabiltzaile guztientzat
+installPluginsWizard.file.title=Mesedez bilatu ezarri nahi duzun plugina
+installPluginsWizard.file.file=Agiria:
+installPluginsWizard.file.invalidfile=Agiria ez da baliozko Vuze plugina.
+installPluginsWizard.file.no_such_file=Ez dago emandako izenik duen agiririk
+installPluginsWizard.file.browse=Bilatu...
+uninstallPluginsWizard.title=Kendu Pluginak
+uninstallPluginsWizard.list.title=Ezarritako Plugin Zerrenda
+uninstallPluginsWizard.list.loaded=Mesedez hautatu kendu nahi dituzun pluginak
+installPluginsWizard.list.nullversion=Bertsiorik ez
+uninstallPluginsWizard.finish.title=Kentzearen Garapena
+uninstallPluginsWizard.finish.explanation=Hautaturiko Pluginak Eguneratze Laguntzailea erabiliz kendu daitezke
+MainWindow.menu.plugins.installPlugins=Ezarpen Laguntzailea...
+MainWindow.menu.plugins.uninstallPlugins=Ezarpena Kentzeko Laguntzailea...
+ConfigView.section.ipfilter.totalIPs=%1 IP itxita guztira,  interneteko %2 
+update.instance.install=Ezarpena Egiaztatzen
+update.instance.uninstall=Kentzea Egiaztatzen
+update.instance.update=Eguneraketak Egiaztatzen
+MainWindow.status.update.tooltip=Klik bikoitza garapen argibideak ikusteko
+updater.progress.window.title=Oraingo Ezarpen Eginkizunak
+updater.progress.window.info=Sakatu 'Utzi' egiteke dauden eginkizun guztiak amaitzeko
+Button.abort=Utzi
+ConfigView.section.ipfilter.enablebanning=Itxi datu gaitzak etengabe bildaltzen dituzten hartzaileak
+Network.alert.acceptfail=Huts egite zenbait izan da %1, %2 atakatan - aurrerabidea utzita dago. Mesedez egiaztatu ataka honentzako suhesi ezarpenak zihurtatzeko gaituta dagoela elkarketak jasotzeko.
+MyShares.column.category=Kategoria
+UpdateWindow.restartLater=Birrabiarazi Vuze Geroago
+MainWindow.menu.file.restart=Birrabiarazi Vuze
+MainWindow.dialog.restartconfirmation.title=Birrabiarazi Vuze
+MainWindow.dialog.restartconfirmation.text=Egitan nahi duzu Vuze birrabiaraztea
+ConfigView.label.prioritizemostcompletedfiles=Gainontzeko agiriei lehentasun Handia eman osatutako % -aren eta agiri neurriaren arabera
+splash.plugin.init=Plugina Abiarazten:
+splash.plugin.UIinit=GUI Plugina Abiarazten: %1  
+ConfigView.section.style.osx_small_fonts=Erabili iturri txikiak [birrabiaraztea beharrezkoa]
+ConfigView.section.tracker.tcpnonblocking=Erabili S/I ez-itxipena TCP aztarnari jardunerako. Aukera hau hautatzeak web aztarnaia ataka altenatibo batean lanean izatea eskatzen du Esperimentala!
+ConfigView.section.tracker.nonblocking=Ez-isten aukerak
+ConfigView.section.tracker.nonblockingconcmax=Geh. aldibereko elkarketa [0: mugagabea]
+MyTorrentsView.menu.exportmenu=Esportatu
+MyTorrentsView.menu.exporttorrent=Torrenta...
+ConfigView.group.scrape=Zuritzea
+ConfigView.section.tracker.client.scrapeinfo=Zuritzea ezgaituz sahiestu daiteke torrent askoren lerrokatzea lanerako ohinarritzen baitira erletaldeko argibideak berreskuratzean aztarnariak zurituz.
+ConfigView.section.tracker.client.scrapeenable=Gaitu zuriketa
+ConfigView.section.tracker.client.scrapestoppedenable=Zuritu torrentak lanean ez daudenean
+Scrape.status.disabled=Zuritzea Ezgaituta
+MyTorrentsView.menu.explore=Erakutsi Agiria
+MyTorrentsView.menu.explore._mac=Erakutsi Finderren
+MyTorrentsView.menu.explore._windows=Erakutsi Explorerrean
+wizard.maketorrents.autohost=Ostaturatu torrenta aztarnariaren barne
+ConfigView.label.overrideip=Ezeztatu aztarnari iragarpen IP-a(k) - punttu eta kakotxaz banaduta sare ezberdinetarako bada
+ConfigView.label.overrideip.tooltip=Jakinarazi aztarnariari irteera paketeetatik datozen IP helbide ezberdinak. Utzi hutsik aukera hau ez erabiltzeko.
+ConfigView.section.connection.group.networks=Sareak
+ConfigView.section.connection.group.networks.info=Hautatu berez baimendutako sareak hartzaile-hartzaile datu igorpenerako
+ConfigView.section.connection.networks.prompt=Galdetu hautatzeko jeisterakoan izengabeko aztarnari bat gehitzen denean
+ConfigView.section.connection.networks.Public=IP sare publikoa (ez izengabea)
+ConfigView.section.connection.networks.I2P=I2P sarea
+ConfigView.section.connection.networks.Tor=The Onion Routerra (Tor) sarea
+TableColumn.header.networks=Sareak
+TableColumn.header.networks.info=Hartzaile-hartzaile harremanerako baimenduriko sareak
+Scrape.status.networkdisabled=Gaitu gabeko sarea
+ConfigView.section.tracker.server.group.networks=Sareak
+ConfigView.section.tracker.server.group.networks.info=Hautatu aztarnariak hartzaileak onartuko dituen sarebidea
+window.networkselection.title=Sare Hautapena
+window.networkselection.info=Behean zerrendaturiko torrentak ondorengo sareak sostengatzen dituzten aztarnariak dira.\nHautatu itzazu gaitzeko aztarnari eta hartzaile harremanerako.\nBezero publikoak sostengatzen dituen aztarnari izengabe bat bada gaitu biak eta izengabea eta sare publikoak.\nSare publikoa gaitzeak jakina izengabetasuna kentzea du ondorio!
+window.networkselection.description=Torrenta :
+plugins.basicview.clear=Garbitu
+ConfigView.section.connection.group.peersources=Hartzaile Iturriak
+ConfigView.section.connection.group.peersources.info=Hautatu berez baimedutako iturburuak hartzaileen elkarketetatik
+ConfigView.section.connection.peersource.Tracker=Aztarnaritik
+ConfigView.section.connection.peersource.DHT=Zentralizatu gabeko aztarnaritza
+ConfigView.section.connection.peersource.PeerExchange=Beste hartzaile batez lortua
+ConfigView.section.connection.peersource.Plugin=Pluginari gehitua
+ConfigView.section.connection.peersource.Incoming=Sarrera elkarketak
+PeersView.source=Iturburua
+PeersView.source.info=Hartzaile honen iturburua
+TableColumn.header.peersources=Hartzaile Iturburuak
+TableColumn.header.peersources.info=Hartzaile iturburu baimenduak hartzaileekiko elkarketak ezartzeko
+wizard.tracker.dht=Zentralizatugabea (Vuzeko bezeroak bakarrik)
+MyTorrentsView.menu.advancedmenu=Aurreratua
+MyTorrentsView.menu.networks=Sareak
+MyTorrentsView.menu.peersource=Hartzaile Iturburuak
+ConfigView.section.sharing.permitdht=Baimendu zentralizatu gabeko jarraipena aztarnaria eskuraezina denean
+ConfigView.section.sharing.protocol=Elkarbanatze-klasikoetarako iturburu protokoloa
+PeersView.Messaging=Neurriratzen
+PeersView.Messaging.info=Adierazten du zein mezularitza erabide erabiltzen ari zaren
+ConfigView.label.queue.newseedsmovetop=Mugitu osatutako torrent berrienak emaletzen zerrendaren aurrealdera
+ConfigView.label.seeding.firstPriority.ignore.info=Kontuan izan arau hauek erabiliz torrenta gelditzea gertatu daitekela\njeisketa amaitu bezain laister.
+ConfigView.label.seeding.firstPriority.ignore=Baztertu Lehentasun Nagusia arauen gainekoa hauentzat:
+ConfigView.label.seeding.firstPriority.ignoreSPRatio=Emale-Hartzaile maila gehiago duten torrentak
+ConfigView.label.seeding.firstPriority.ignore0Peer=0 Hartzaileko Torrentak
+ConfigView.section.tracker.sendjavaversionandos=Bidali Java bertsioa eta Sistema Eragile (SE) izena
+MagnetPlugin.contextmenu.exporturi=Kopiatu Magnet URI-a Gakora
+ConfigView.section.plugins.dht=Banaturiko DB
+dht.info=Plugin honek zentralizatu gabeko aztarnapena onartzen du, beste gauza batzuen artean, - ezgaituz gero zure jeisteko gaitasuna murriztuko da
+dht.enabled=Gaitu banaturiko datubasea
+dht.portdefault=Erabili berezko ataka
+dht.port=Datubasearen UDP ataka
+dht.execute.command=Igarpen komandoa
+dht.execute.info=Sakatu komandoa exekutatzeko
+dht.execute=Ekin
+dht.logging=Gaitu jarduera gardentasuna
+ConfigView.section.plugins.dhttracker=Banaturiko Aztarnaria
+dhttracker.tracknormalwhenoffline=Torrent arruntak beren aztarnaria eskuragarria ez dagoenean bakarrik bideratu
+ConfigView.section.file.nativedelete._mac=Erabili Haustea agirak ezabatzerakoan
+ConfigView.section.file.nativedelete._windows=Mugitu ezabatutako agiriak Birziklapen Gunera
+ConfigView.section.logging.generatediagnostics=Sortu
+ConfigView.section.logging.netinfo=Sortu sare argibideak
+ConfigView.section.logging.statsinfo=Sortu egoera argibideak
+ConfigView.section.logging.generatediagnostics.info=Sortu igarpen argibideak eta kopiatu gakora eta ohar agira, ezarrita badago
+ConfigView.section.sharing.privatetorrent=Torrent pribatua - aztarnariaren hartzaileak besterik ez ditu onartzen
+MainWindow.menu.tools.nattest=&NAT/Firewall Azterketa...
+Button.apply=Ezarri
+Button.close=Itxi
+window.welcome.title=Ongi etorri Vuzera %1
+#file can be a URL or a path in the jar
+MainWindow.menu.help.releasenotes=Argitaratu Oharrak
+dht.reseed.label=Arrunt birremaletzen Banaturiko Datubasea ez da beharrezkoa. Horrela ere, elkarketen zenbatekoa apala bada izan daiteke erabilia bir-baterapenerako.\nOrri zuria bereznahiko elkartutako hartzaileentzako edo sartu IP-a eta ataka hartzaile ezagun batetik bereznahikotzeko.
+dht.reseed.group=Birremale
+dht.reseed.ip=IP helbidea
+dht.reseed.port=Ataka
+dht.reseed=Birremale
+dht.reseed.info=Birremaletu datubasea
+dht.diagnostics.group=Igarpenak
+DHTView.title.full=Banaturiko Datubasea
+DHTView.title.fullcvs=Banaturiko Datubasea CVS
+DHTView.general.title=Orokorra
+DHTView.general.uptime=Jardun denbora:
+DHTView.general.users=Erabiltzaileak:
+DHTView.general.nodes=Elkarguneak:
+DHTView.general.leaves=Orriak:
+DHTView.general.contacts=Harremanak:
+DHTView.general.replacements=Ordezkapenak:
+DHTView.general.live=Bizirik:
+DHTView.general.unknown=Ezezaguna
+DHTView.general.dying=Azkenetan:
+DHTView.transport.title=Garraio Xehetasunak
+DHTView.transport.packets=Paketeak
+DHTView.transport.bytes=Byte
+DHTView.transport.received=Jasota
+DHTView.transport.sent=Bidalita
+DHTView.transport.in=Sarrera:
+DHTView.transport.out=Irteera:
+DHTView.operations.title=Eragiketa Xehetasunak
+DHTView.operations.sent=Bidalia
+DHTView.operations.ok=Ongi
+DHTView.operations.failed=Huts egin du
+DHTView.operations.received=Jasoa
+DHTView.operations.ping=Ping (Int. Pak. Eskuzt.)
+DHTView.operations.findNode=Bilatu Elkargunea
+DHTView.operations.findValue=Bilaketa Balioa
+DHTView.operations.store=Biltegia
+DHTView.activity.title=Jarduera
+DHTView.activity.status=Egoera
+DHTView.activity.status.true=Lerrokatuta
+DHTView.activity.status.false=Lanean
+DHTView.activity.type=Mota
+DHTView.activity.type.1=Barne Lorpena
+DHTView.activity.type.2=Kanpo Lorpena
+DHTView.activity.type.3=Barne Ezarpena
+DHTView.activity.type.4=Kanpo Ezarpena
+DHTView.activity.target=Xedea
+DHTView.activity.details=Xehetasunak
+DHTView.db.title=Datubasea
+DHTView.db.keys=Giltzak
+DHTView.db.values=Balioak
+DHTView.db.local=Tokikoa
+DHTView.db.direct=Zuzen
+DHTView.db.indirect=Zeharka
+DHTView.db.divfreq=Maizt. Dib.
+DHTView.db.divsize=Neurri Dib.
+MainWindow.dht.status.tooltip=Banaturiko Datubasea lanean dagoenean honek uneko online erabiltzaile zenbatekoa erakusten du
+MainWindow.dht.status.disabled=DHT-a Ezgaiturik
+MainWindow.dht.status.failed=DHT-ak Huts egin du
+MainWindow.dht.status.initializing=DHT-a Abiatzen
+MainWindow.dht.status.users=%1 erabiltzaile
+MainWindow.dht.status.unreachable=DHT-a Suhesiturik
+MainWindow.dht.status.unreachabletooltip=Badirudi arazo bat dagoela Banaturiko Datubasearen UDP ataka izendapenarekin (NAT/suhesia)
+MyTorrentsView.menu.setUpSpeed=Ezarri Igoera Abiadura
+MyTorrentsView.menu.setDownSpeed=Ezarri Jeisketa Abiadura
+ConfigView.section.tracker.client.showwarnings=Erakutsi aztarnariek bidalitako kontuz! mezuak
+dht.advanced=Gaitu ezarpen aurreratuak
+dht.advanced.group=Ezarpen aurreratuak
+dht.advanced.label=Aldatu bakarrik balio hauek egitan zer egiten ari zaren badakizu
+dht.override.ip=Ezabatu kanpoko IP helbideak
+ConfigView.section.logging.loggerenable=Gaitu saioa hastea
+ConfigView.section.ipfilter.blockbanning=256 helbideko bloke baten eragozpena gutxienez zenbateko hau blokean eragotzia izan denean 
+MyTrackerView.passive=Pasiboa
+TableColumn.header.swarm_average_speed=Erlataldearen Bataz-besteko Abiadura
+TableColumn.header.swarm_average_speed.info=Erletaldeko hartzaileen bataz-besteko abiadura
+TableColumn.header.comment=Aipamena
+TableColumn.header.comment.info=Jeisketarako erabiltzaileak zehazturiko aipamena
+TableColumn.header.commenticon=Aipamen Ikurra
+TableColumn.header.commenticon.info=Erakutsi ikurra jeisketak erabiltzaile-zehaztu baten aipamena badu
+MyTrackerView.category=Kategoria
+MainWindow.menu.file.open.torrentfortracking=Torrent Agiria... (Aztanaritza Bakarrik)
+VivaldiView.title.full=Vivaldia
+VivaldiView.title.fullcvs=Vivaldi CVS-a
+VivaldiView.title.full_v6=Vivaldi IPv6-a
+MyTrackerView.date_added=Gehituta
+ConfigView.section.tracker.portbackup=Babeskopia atakak (';' bananduta)
+ConfigView.label.playfilespeech=Hitzegin agiri batek amaitu duenean
+ConfigView.label.playfilefinished=Jo soinu bat agiri batek amaitu duenean
+ConfigView.label.backupconfigfiles=Babeskopia itxurapen agiriak berreskurapen asmoekin
+ConfigView.section.tracker.client.scrapesingleonly=Ezgaitu aztarnari-bakoitzeko zuritze gehiketa (lagundu dezake 'URL oso luzea' duten aztarnariekin' (414) akatsak) 
+dht.ipfilter.log=Ohartu  IP Iragazki bortxaketez
+ConfigView.label.seeding.addForSeedingDLCopyCount=Hartu 'emaletzarako gehitutako' jeisketatzat kopia zenbateko hau duten jeitsierak
+ActivityView.legend.limit=Neurri muga
+ActivityView.legend.achieved=Erdietsitako neurria
+ActivityView.legend.overhead=Burugain neurria
+ActivityView.legend.peeraverage=Bataz-bestekoa
+ActivityView.legend.swarmaverage=Erletalde bataz-bestekoa
+ActivityView.legend.trimmed=Murrizpena (izpilduta)
+MyTorrentsView.menu.movemenu=Mugitu Agiriak
+MyTorrentsView.menu.movedata=Mugitu Datu Agiriak...
+MyTorrentsView.menu.movetorrent=Mugitu Torrent Agiria...
+MyTorrentsView.menu.movedata.dialog=Hautatu helbide berria
+DHTView.operations.data=Datua
+DHTView.general.reachable=Eskuragarri:
+DHTView.general.rendezvous=Hitzordua:
+ConfigView.label.queue.maxactivetorrentswhenseeding=Geh. emaletzen bakarrik [0:mugagabea]
+Views.plugins.IRC.title=IRC - Onlineko Laguntza Teknikoa
+Formats.units.alot=Pilo bat!!!
+ConfigView.section.ipfilter.persistblocking=Gorde itxitako IP xehetasunak birrabiarazpenetan
+FilesView.menu.rename=Birrizendatu edo Birxedetu
+FilesView.menu.rename_only=Birrizendapen Azkarra
+FilesView.menu.retarget=Mugitu Agiriak
+FilesView.rename.choose.path=Hautatu dagoen agiria edo berri bat
+FilesView.rename.choose.path.dir=Hautatu zuzenbide berri bat edo lehendik dagoen bat
+FilesView.rename.confirm.delete.title=Baieztatu Ezabaketa
+FilesView.rename.confirm.delete.text=Baieztatu jatorrizko agiriaren ezabapena '%1'
+FilesView.rename.filename.title=Birrizendatu agiria
+FilesView.rename.filename.text=Hautatu izen berri bat agiriarentzat
+ConfigView.higher.mode.available=Aukera asko erabiltzaile modu askotan dira eskuragarriak
+ConfigView.section.mode=Modua
+ConfigView.section.mode.title=Erabiltzaile Gaitasuna
+ConfigView.section.mode.beginner=Hasiberria
+ConfigView.section.mode.beginner.wiki.definitions=BitTorrent hiztegia
+ConfigView.section.mode.intermediate=Tartekoa
+ConfigView.section.mode.intermediate.wiki.host=Agiriak Ostatutzen
+ConfigView.section.mode.intermediate.wiki.publish=Agiriak Argitaratzen
+ConfigView.section.mode.advanced=Aurreratua
+ConfigView.section.mode.advanced.wiki.main=Wiki Orrialde Nagusia
+ConfigView.section.mode.beginner.text=Torrentak jeisteko behar duzun guztia.\nErabili modu hau nahi duzun guztia zure torrentak kudeatzea bada.
+ConfigView.section.mode.intermediate.text=Sartu aztarnari eginkizunetan.\nErabili modu hau zeure aztarnaria sortzea eta zure agiriak ostatutzea/argitaratzea nahi baduzu.
+ConfigView.section.mode.advanced.text=Sartu sare ezarpenetara.\nErabili modu hau jakitea nahi baduzu zein GEB edo S/I ez itxiak dauden
+Files.column.storagetype=Biltegiratze Mota
+Files.column.fileext=Mota
+FileItem.storage.linear=Lerrotua
+FileItem.storage.compact=Trinkotua
+MessageBoxWindow.rememberdecision=Gogoratu nire erabakia
+ConfigView.section.interface.cleardecisions=Garbitu gogoraturiko elkarrizketa erabakiak
+ConfigView.section.interface.cleardecisionsbutton=Garbitu
+ConfigView.section.interface.cleartrackers=Garbitu gogoraturiko aztarnariak
+ConfigView.section.interface.cleartrackersbutton=Garbitu
+ConfigView.section.interface.clearsavepaths=Garbitu gogoraturiko helburu gordeak
+ConfigView.section.interface.clearsavepathsbutton=Garbitu
+configureWizard.welcome.usermodes=Erabiltzaile Eskumen ezarpen honek zehaztuko du ondoren agertzen diren aukeren maila Tresnak > Aukerak.Zure interes hoberenean da zuzen ezartzeko.
+FilesView.skip.confirm.delete.text=Moztu '%1' agiria tokia gordetzeko?
+FilesView.rename.failed.title=Birrizendatze/Birxedetzeak huts egin du
+FilesView.rename.failed.text=Eragiketak huts egin du, zihurrenik xede hautaketa okerragaitik
+diagnostics.log_found=Vuze ezin da zuzen itzali. Egiaztau <A HREF="%1">igarpen ohar agiriak</A>. Irakurri ere wikiko idazlana <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Ezagertzea</A> argibide gehiagorako.
+ManagerItem.paused=Pausaturik
+Utils.link.visit=Mesedez ikusi
+ConfigView.section.connection.serverport.wiki=Hautatutako ataka onak
+ConfigView.section.transfer.speeds.wiki=Abiadura oneko ezarpenak
+installPluginsWizard.installMode.info.title=Argibideak
+installPluginsWizard.installMode.info.text=Ez duzu pluginik behar Vuzerekin egoki lan egiteko, astialdi, berezgaitasuntze edo hurruneko aginte ezaugarri osagarriak eskaintzen dutenak.\nMesedez irakurri plugin bakoitzaren azalpenak ezartzea erabaki aurretik.\nPlugin gehienak zihurrak dira probatzeko, baina ez gainzamatu zure itxurapena erabiliko ez duzun pluginekin.
+Views.plugins.Distributed.DB.title=Banaturiko DB-a
+Views.plugins.Distributed.Tracker.title=Banaturiko Aztarnaria
+Views.plugins.Plugin.Update.title=Plugin Eguneratzea
+Views.plugins.UPnP.title=UPnP-a
+Views.plugins.UPnP.title.tooltip=Plug and Play Unibertsala
+openUrl.url.info=Sostengaturik http, https, magnet eta raw hex infohash kateak
+TableColumn.header.swarm_average_completion=Hartzaileen Bataz-besteko Osatua
+TableColumn.header.swarm_average_completion.info=Erlataldeko hartzeileen osaketa ehunekoaren bataz-bestekoa
+GeneralView.label.swarm_average_completion=Bataz-besteko Osaketa:
+GeneralView.label.swarm_average_completion.tooltip=Erletaldeko hartzaileen osaketa bataz-besteko ehunekoa
+MainWindow.nat.status.tooltip.unknown=Suhezi/NAT eskuragarritasun egoera ezezaguna (TCP)
+MainWindow.nat.status.ok=NAT Ongi
+MainWindow.nat.status.tooltip.ok=Eskuragarritasuna Ongi (TCP)
+MainWindow.nat.status.probok=NAT Ongi?
+MainWindow.nat.status.tooltip.probok=Eskuragarritasuna Ona zen, horrela ere ez dago TCP elkarketa sarrera berririk
+MainWindow.nat.status.bad=Suhesiturik
+MainWindow.nat.status.tooltip.bad=Suhesi/NAT (TCP) eskuragarritasun arazoa. Joan Wikira laguntza lortzeko
+plugin.installer.recommended.plugin=Plugina gomendatuta - mesedez birrikusi eta ezarri beharrezkoa bada
+LoggerView.pause=Pausatu Saio hastea
+LoggerView.clear=&Garbitu
+LoggerView.filter=Iragazkia
+LoggerView.filter.uncheckAll=Ez Egiaztatu Kategoria Guztiak
+LoggerView.filter.checkAll=Egiaztatu Kategoria Guztiak
+LoggerView.loggingDisabled=Saio hastea ez dago gaituta.
+LoggerView.includeOnly=Erakutsi bakarrik adierazpide honekin bat datozen lerroak:
+LoggerView.excludeAll=Ez erakutsi adierazpide honekin bat datozen lerroak:
+ConfigView.section.logging.log0type=Argibide
+ConfigView.section.logging.log1type=Kontuz
+ConfigView.section.logging.log2type=Akats
+ConfigView.section.logging.filter=Iragazi agirira ohartzerakoan
+ConfigView.section.logging.level=Ohar Maila
+ConfigView.section.logging.showLogsFor=Erakutsi  %1 oharrak hurrengo kategorientzat:
+ConfigView.pluginlist.column.loadAtStartup=Gertatu Abiatzerakoan
+ConfigView.pluginlist.column.type=Mota
+ConfigView.pluginlist.column.type.perUser=Erabiltzaileko
+ConfigView.pluginlist.column.type.shared=Partekaturik
+ConfigView.pluginlist.column.type.builtIn=Hemen Egina
+ConfigView.pluginlist.column.name=Izena
+ConfigView.pluginlist.column.version=Bertsioa
+ConfigView.pluginlist.column.directory=Zuzenbidea
+ConfigView.pluginlist.column.isOperational=Eragiketakor?
+PeersView.BlockView.Avail.Have=Biok duzue
+PeersView.BlockView.Avail.NoHave=Hartzaileak du; Zuk ez
+PeersView.BlockView.NoAvail.Have=Zuk duzu; Hartzaileak ez
+PeersView.BlockView.NoAvail.NoHave=Inork ez du
+PeersView.BlockView.Transfer=Eskualdatzen
+PeersView.BlockView.NextRequest=Hurrrengo Eskabidea
+PeersView.BlockView.title=Atal Mapa
+PeersView.BlockView.AvailCount=Eskuragarritasun Zenbatekoa
+MyTorrentsView.dialog.NumberError.title=Zenbaki Baliogabea edo Ezezaguna
+MyTorrentsView.dialog.NumberError.text=Sartu duzun zenbakia baliogabea edo ezezaguna da.
+MyTorrentsView.menu.manual=&Eskuz...
+MyTorrentsView.menu.manual.per_torrent=Eskuz (torrenteko)
+MyTorrentsView.menu.manual.shared_torrents=Eskuz (torrentetatik)
+MyTorrentsView.dialog.setSpeed.title=Ezarri %1 abiadura
+# %1 = "in kbps" or ""; %2 = "upload" or "download"
+MyTorrentsView.dialog.setNumber.text=Sartu %1 zenbaki bat aldatzeko %2 -ra:
+MyTorrentsView.dialog.setNumber.upload=igo
+MyTorrentsView.dialog.setNumber.download=jeitsi
+MyTorrentsView.dialog.setNumber.inKbps=%1
+OpenTorrentWindow.torrentLocation=Jeitsitako torrenta(k):
+OpenTorrentWindow.addFiles.URL=Gehitu &URL-a
+OpenTorrentWindow.addFiles.Folder=Gehitu &Agiritegia
+OpenTorrentWindow.addFiles.Clipboard=Gehitu Ga&kotik
+OpenTorrentWindow.changeDestination=Aldatu Helmuga
+OpenTorrentWindow.fileList=Agiri torrentetan:
+OpenTorrentWindow.torrentTable.name=Izena
+OpenTorrentWindow.torrentTable.saveLocation=Gorde Helbidea
+OpenTorrentWindow.fileTable.fileName=Agiri Izena
+OpenTorrentWindow.fileTable.size=Neurria
+OpenTorrentWindow.fileTable.destinationName=Helm. Izena
+OpenTorrentWindow.startMode.seeding=Emaletzen
+OpenTorrentWindow.fileList.changeDestination=Aldatu Helmuga
+OpenTorrentWindow.mb.badSize.title=Agiri Bateraezina
+OpenTorrentWindow.mb.badSize.text='%1' ez da '%2' eta ezin da emaletzarako erabili
+OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> jadanik gahituta dago '%2' bezala
+OpenTorrentWindow.mb.alreadyExists.default.name=Hedabidea
+OpenTorrentWindow.mb.alreadyExists.title=Jadanik badago
+OpenTorrentWindow.mb.openError.title=Irekiera Akatsa
+OpenTorrentWindow.mb.openError.text='%1' ezin izan du ireki:
+OpenTorrentWindow.torrent.remove=Kendu torrenta zerrendatik
+OpenTorrentWindow.torrent.options=Hurrengo ezarpenak gainean hautaturiko torrentei ezarriko zaie:
+OpenTorrentWindow.xOfTotal=(%1 %2-tik)
+iconBar.open.tooltip=Ireki Torrenta(k)
+LocaleUtil.column.text=Idatzi Ezezaguna
+Tracker.tooltip.MultiSupport=Aztarnari honek hash zuriketa anitz onartzen ditu eskabide bakoitzeko
+Tracker.tooltip.NoMultiSupport=Aztarnari honek ez ditu hash zuriketa anitz onartzen eskabide bakoitzeko./nHonek ez du eragiten zure egintzan baina gainzama bat ezartzen du aztarnarian.
+ConfigView.label.lazybitfield=Erabili biteremu alperra (laguntzen du emaletzan biteremu-itxipenean ohinarritzen diren sareetan)
+LoggerView.realtime=Eguneratu egizko denboran
+ConfigView.section.file.perf.cache.flushpieces=Idatzi atal osatuak berehala diskan. Honek diska sarbidea lehuntzen du baina idaz eragiketa gehiago egin daitezke 
+ConfigView.section.file.writemblimit=Gehienezko idaz eskabide lerrokatuta (%1)
+ConfigView.section.file.writemblimit.explain=Diskaren idazketa abiadura jeisketa abiadura bezain motela denean neurri honek mugatzen du zenbat datu lerrokatu daitekeen jeisketa abiadura murriztua izan aurretik
+ConfigView.section.file.readmblimit=Gehienezko irakurketa eskabide lerrokatuta ( %1)
+ConfigView.section.file.readmblimit.explain=Neurri honek prozesatzeke dauden irakurketak biltegiratzeko zenbat oroimen erabiliko den mugatzen du 
+Button.moveUp=Mugitu &Gora
+Button.moveDown=Mugitu &Behera
+ConfigView.notAvailableForMode=Atal hau %1 moduarentzat edo handiagoarentzat da. Ez da eskuragarria %2 moduan.
+health.explain.error=Arazo bat dago torrent honekin. Ikusi Egoera zutabea, edo ikurreko akats argibidea.
+GeneralView.label.trackerscrapeupdate=Zuritu Aztarnaria
+PeersView.piece=Atal
+PeersView.piece.info=Hartzaile honetatik eskabideturiko # azken atala
+PiecesView.priority=Lehentasuna
+PiecesView.priority.info=atal honen osaketa lehentasuna, baina ez dute harreta askorik horretan
+PiecesView.speed=Abiadura
+PiecesView.speed.info=Hartzaile geldoenekk eragotzita dute atal askoz azkarragoekin nahastea
+TableColumn.header.AvgAvail.info=Atal eskuragarritasuna bananduta # ataletan, bananduta # elkarketatan
+TableColumn.header.AvgAvail=Batez-besteko Eskurg/atal
+ConfigView.label.strictfilelocking=Betearazi bazterketa agiri idazketa sarbide itxipena torrenteetan
+MyTorrentsView.menu.checkfilesexist=Egiaztatu Dauden Agiriak
+MyTorrentsView.menu.rescanfile=Aldizka Birregiaztatu Osatugabeko Atalak
+MyTorrentsView.menu.clear_resume_data=Garbitu Datuak Jarraitzeko
+Plugin.extseed.name=Kanpoko Emaleak
+Plugin.localtracker.name=LAN Hartzaile Bilatzailea
+Plugin.localtracker.info=LAN hartzaile bilatzaileak Vuzeren kopia anitz ahalbidetzen ditu suhesi baten atzean eta sare arrunt batean\ntorrentak modu eraginkorrean jeisteko beraien arteko elkarketa zuzenak gaituz.
+Plugin.localtracker.enable=Gaitu LAN hartzaile bilatzailea
+azinstancehandler.alert.portclash=Ataka gatazka atzeman da LAN-ean: %1 jadanik erabilpenean du beste Vuze erabiltzaile batek, hautatu zorizko beste ataka eragozteko TCP / UDP aditzea [%2 eta %3 artean]. 
+ConfigView.section.transfer.lan.tooltip=LAN-bereiziko Ezarpenak
+ConfigView.section.transfer.lan.uploadrate=KB/s LAN geh. igoera abiadura [0: mugagabea]
+ConfigView.section.transfer.lan.uploadrate.tooltip=Barneko LAN bera ez duten hartzaile elkarketek igoera muga maila banandua dute
+ConfigView.section.transfer.lan.downloadrate=KB/s LAN geh. jeisketa abiadura [0: mugagabea]
+ConfigView.section.transfer.lan.downloadrate.tooltip=Barneko LAN bera ez duten hartzaile elkarketek jeisketa muga maila banandua dute
+TorrentOptionsView.title.short=Aukerak
+TorrentOptionsView.title.full=Aukerak
+TorrentOptionsView.param.max.peers=Geh. elkarketa zenbatekoa [0: mugagabea]
+ConfigView.section.connection.encryption.require_encrypted_transport=Garraio enkriptatua beharrezkoa
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=Behartu enkriptatutako elkarketak erabiltzera beste hartzaile batzuekin
+ConfigView.section.connection.encryption.min_encryption_level=Gutxieneko enkriptaketa maila
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=Laua- eskukada bakarrik\nRC4 - jario osoa\nEnkriptaketa handiagoak CPU gehiago behar du .
+Peers.column.Encryption=Enkriptaketa
+Peers.column.Encryption.info=Erabilitako enkriptaketa maila
+ConfigView.section.connection.encryption.encrypt.info=Enkriptaketa gaituta badago ezingo duzu bezero bateraezinekin elkarketarik egin ordezko aukerak gaituz ezean
+ConfigView.section.connection.encryption.encrypt.info.link=Mesedez ikusi hemen xehetasunak
+MainWindow.sr.status.tooltip.ok=Elkarbanatze Maila %1 Ongi
+MainWindow.sr.status.tooltip.poor=Elkarbanatze Maila %1 gutxi: < 0.9
+MainWindow.sr.status.tooltip.bad=Elkarbanatze Maila %1 gaizki: < 0.5
+ConfigView.section.style.status=Egoera Eremua:
+ConfigView.section.style.status.show_sr=Elkarbanatze Neurria
+ConfigView.section.style.status.show_nat=NAT Egoera
+ConfigView.section.style.status.show_ddb=DDB Egoera
+ConfigView.section.style.status.show_ipf=IP Iragazki Egoera
+ConfigView.section.connection.encryption.encrypt.group=Garraio Enkriptazioa/Itsutzea
+ConfigView.section.connection.encryption.encrypt.fallback_info=Ordezko aukera gaitzeak bezero bateraezinekin elkarketak ahalbidetuko ditu BAINA elkarketa enkriptatu-gabeak izango dira
+ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Ahalbidetu enkriptatu-gabeko irteera elkarketak enkripatutako elkarketa saiakerak huts egiten badu
+ConfigView.section.connection.encryption.encrypt.fallback_incoming=Baimendu enkriptatu-gabeko sarrera elkarketak
+ConfigView.section.connection.encryption=Garraio Enkriptaketa
+upnp.selectedinterfaces=Hautaturiko interfazeak (';' banandurik, adib. eth0;eth1) [blank: all]
+ConfigView.section.style.defaultSortOrder=Berezko Antolakuntza
+ConfigView.section.style.defaultSortOrder.desc=Beherantz
+ConfigView.section.style.defaultSortOrder.asc=Gorantz
+ConfigView.section.style.defaultSortOrder.flip=Aurreko antolakuntzaren alderantziz
+LoggerView.autoscroll=Berez-irriskatu
+Button.selectAll=Hautatu Denak
+Button.markSelected=Hautatuta Markatu
+Button.unmarkSelected=Hautatutakoa ezmarkatu
+plugins.basicview.config=Itxuratu
+TorrentOptionsView.param.max.uploads=Geh. igoera aho zenbatekoa [gutxienez: 2]
+MyTorrentsView.dialog.setPosition.title=Ezarri Kokapena
+MyTorrentsView.dialog.setPosition.text=Sartu kokapena hautatutako torrentak ezartzeko:
+MyTorrentsView.menu.reposition.manual=Birjarpena...
+ConfigView.section.connection.advanced.info.link=Mesedez ikusi hemen xehetasunak
+ConfigView.section.connection.advanced.socket.group=Hartune Aukerak
+ConfigView.section.connection.advanced.bind_port=Lotu tokiko atakara [0: ezgaituta]
+ConfigView.section.connection.advanced.bind_port.tooltip=Irteera hartune elkarketak tokiko mailan behartuta egongo dira emaniko atakan.\nHau gaitzeak NAT routerraren ezarpenarekin lagundu dezake 
+ConfigView.section.proxy.group.tracker=Aztarnari Harremanak
+ConfigView.section.proxy.group.peer=Hartzaile Harremanak
+Pieces.column.Requested=Eskabidetuta
+Pieces.column.Requested.info=Erakusten du atalean eskabide gehiago egin daitezkeen edo ez (*)
+ConfigView.label.maxuploadsseeding=Ordezpen berezkoa emaletzan dagoenean
+MyTorrentsView.filter=Iragazkia
+popup.error.hideall=Ezkutatu Denak
+ConfigView.section.style.dataStatsOnly=Erakutsi datu estatistikak bakarrik (ezkutatu protokolo estatistikak)
+ConfigView.section.style.separateProtDataStats=Erakutsi banandurik datu eta protokolo estatistikak 'datuak (protokoloa)' bezala
+MyTorrentsView.dialog.setFilter.title=Aldatu Iragazkia
+MyTorrentsView.dialog.setFilter.text=%1 atala iragazia izan daiteke adierazi duzun idatzirako. Erabili  | (tutua) ikurra iragazteko esaldi askoren artean.
+MyTorrentsView.filter.tooltip=Ctrl+X aldatzeko RegEx eta bilaketa arrunt moduaren artean.\nErabili | (tutua) ikurra iragazteko esaldi askotan.
+MyTorrentsView.clearFilter.tooltip=Garbitu Iragazkia
+MyTorrentsView.menu.filter=Iragazki Zerrenda...
+ConfigView.section.file.resume.recheck.all=Birrabiarazte-hutsegitean egiztatu agiri guztia atal osatuak bilatzeko (Bestela azken gordeketan eraginda zeuden atalak bakarrik egiaztatuko dira)
+ConfigureWizard.language.choose=Hautatu hizkuntza beheko zerrendatik:
+popup.closing.in=Berez-iste leihoa %1 segundutan
+popup.more.waiting=%1 mezu gehiago...
+# > 2402
+popup.download.finished="%1" jeisketa amaituta.
+popup.file.finished="%1" jeisketa amaituta
+ConfigView.auto=Berez
+Plugin.localtracker.autoadd.info=Berezgaitasunez gehitu tokiko hartzaile hauek [helbideak ';' bananduta, adib. 1.2.3.4]
+Plugin.localtracker.autoadd=Ageriko hartzaileak
+Plugin.localtracker.networks.info=Hartu honako sare hauek tokikotzat [sareak ';' bananduta, adib. 145.227.*.*]
+Plugin.localtracker.networks=Tokiko sareak
+MainWindow.menu.view.plugins.logViews=Saio Ikuspegiak
+SpeedView.stats.autospeed=Berezgaitasunezko Igoera Abiadura
+SpeedView.stats.autospeed.disabled=Aukera hau ez dago gaiturik (DHT-a behar duzu) edo ez zaude erabilitzen (eskuzko igoera abiadura hautatuta)
+SpeedView.stats.idlePing=Idle Ping-a:
+SpeedView.stats.maxPing=Geh. Ping-a:
+SpeedView.stats.currentPing=Oraingo Ping-a:
+SpeedView.stats.maxUp=Geh. Igoera Abiadura:
+ConfigView.pluginlist.unloadSelected=Ezgertaketa Hautatua
+ConfigView.pluginlist.scan=Mihatu Plugin berrien bila
+ConfigView.section.transfer.autospeed=Berez-Abiadura (klasikoa)
+ConfigView.section.transfer.autospeed.tooltip=Berez-abiadura ezarpen bereziak
+ConfigView.section.transfer.autospeed.info=Berez-abiadurak berezgaitasunez zehazten du igoera muga sare elkarketaren gainzamatzea sahiesteko\n\nMuga hauek berezgaitasunezko igoera abiadura gaituta dagoenean bakarrik ezarri daitezke eta behar du baita ere banaturiko datubasea gaituta egotea.\n
+ConfigView.section.transfer.autospeed.minupload=%1 gutxieneko igoera abidadura
+ConfigView.section.transfer.autospeed.minupload.tooltip=Igoera abiadura ez da arrunt berez beheratuko muga honen azpitik
+ConfigView.section.transfer.autospeed.maxupload=%1 gehienezko igoera abiadura [0: mugagabea]
+ConfigView.section.transfer.autospeed.maxupload.tooltip=Igoera abiadura ez da berez goratzen muga honen gainetik
+ConfigView.section.transfer.autospeed.chokeping=Itopen ping aldiak [sugundu milaenetan] 
+ConfigView.section.transfer.autospeed.chokeping.tooltip=Ping aldiak balio honen gainetik sare betekada adierazletzat hartuko dira
+ConfigView.section.transfer.autospeed.enableauto=Gaitu jeisten eta emaletzen 
+ConfigView.section.transfer.autospeed.enableautoseeding=Gaitu emaletzan bakarrik dagoenean
+ConfigView.pluginlist.column.unloadable=Gertaezina
+ConfigView.section.transfer.lan.enable=Gaitu abiadura muga bananduak LAN elkarketentzat
+Plugin.localtracker.wellknownlocals=Berezgaitasunez barneratzen du bigiztapena/lotura/tokiko sareak gunea (192.168 e.a)
+TableColumn.header.filesdone=Agiri Eginak
+TableColumn.header.filesdone.info=Agiri eginda/Agiriak guztira *edo*  Ez-ahazturiko agiri eginda (Agiri eginda)/Ez-ahazturiko agiriak guztira (Agiriak guztira)
+MagnetPlugin.private_torrent=<torrent pribatua>
+MagnetPlugin.decentral_disabled=<zentralizatu gabeko aztarnaritza ezgaituta>
+MagnetPlugin.decentral_backup_disabled=<zentralizatu gabeko babeskopia ezgaituta>
+MagnetPlugin.report.waiting_ddb=DDB abiarazpena itxaroten...
+MagnetPlugin.report.searching=bilatzen...
+MagnetPlugin.report.found=aurkituta %1
+MagnetPlugin.report.alive=%1 bizirik
+MagnetPlugin.report.dead=%1 hilda
+MagnetPlugin.report.tunnel=azpibideratzen %1 
+MagnetPlugin.report.downloading=Hemendik jeisten %1
+MagnetPlugin.report.error=akatsa %1
+MagnetURLHandler.report.no_sources=ez da baliabiderik aurkitu torrentarentzat
+MagnetURLHandler.report.torrent_size=torrent neurria: %1
+MagnetURLHandler.report.percent=osaturik: %1%
+MagnetURLHandler.report.error=akatsa %1
+DHTTransport.report.request_all=eskabidetzen eskualdaketa osoa %1
+DHTTransport.report.received_bit=jasota %1  %2  %3
+DHTTransport.report.complete=osatuta
+DHTTransport.report.timeout=denborazkanpo, erantzunik ez %1
+DHTTransport.report.rerequest_all=bir-eskabidetzen eskualdaketa osoa  %1
+DHTTransport.report.rerequest_bit=bir-eskabidetzen %1  %2  %3 
+DHTTransport.report.timeout_some=denborazkanpo, %1 pakete jasota %2 baina osatugabe
+DHTTransport.report.sending=datuak bidaltzen
+DHTTransport.report.resending=datuak birbidaltzen
+DHTTransport.report.send_complete=bidali osorik
+DHTTransport.report.send_timeout=bidalketa itxaronaldia
+ConfigView.section.transfer.autospeed.enabledebug=Ohar garbiketa argibideak
+TableColumn.header.date_added=Gehitze eguna
+TableColumn.header.date_added.info=Torrenta gehitu zen eguna
+ConfigView.section.file.hashchecking.smallestfirst=Birregiaztatu jeisketa txikiegiak lehenik
+platform.win32.baddll.info=Vuzek '%1' egona atzeman du. Hau '%2'  zati da eta ezaguna da programaren blokeoa eta CPU erabilpen handia bezalako arazo larriak eragiteagaitik. Aurkitzen baduzu mesedez softwarea kendu edo ezarri Vuzeri eragiten ez dion moduan.
+platform.win32.baddll.niphk=Norman Birus-aurkakoa
+platform.win32.baddll.nvappfilter=NVidia Suhesia
+platform.win32.baddll.netdog=Armor2net Suhesi Pertsonala
+platform.win32.baddll.vlsp=Venturi Suhesia
+platform.win32.baddll.imon=NOD32 Birus-aurkakoa
+platform.win32.baddll.sarah=ONDATUTA! Aplikazio Geruza Suhesia
+platform.win32.baddll.MxAVLsp=VCom Fix-It Erabilgarriak
+platform.win32.baddll.mclsp=McAfee Pribatutasun Zerbitzua
+platform.win32.baddll.radhslib=Naomi Internet Iragazkia (Dizdiratsua)
+platform.win32.baddll.nl_lsp=NetMugatzailea
+platform.win32.baddll.winsflt=Interneteko Eduki Garbi Iragazkia
+platform.win32.baddll.AxShlex=Alkohola %120
+platform.win32.baddll.iFW_Xfilter=iolo Suhesi Pertsonala
+platform.win32.baddll.WSOCKHK=Sare Babeslea
+platform.win32.baddll.InjHook12=Torrenten Maila Zaintzailea
+platform.win32.baddll.FPServiceProvider=FoxyProxy Bideo Erabilgarria
+upnp.ignorebaddevices=Baztertu zuzen erantzuten ez duten gailuak
+upnp.ignorebaddevices.info=Orain baztertutako gailuak: %1
+upnp.ignorebaddevices.reset=Birrezarri bazterturiko gailu zerrenda
+upnp.ignorebaddevices.reset.action=Birrezarri
+upnp.ignorebaddevices.alert=UPnP gailu helbidea %1 bazterturik dago etengabeko akatsengaitik. Ikusi UPnP plugin ezarpenak eragiketa honi buruzko aukerentzako.
+TorrentOptionsView.param.max.uploads.when.busy=KB/s geh. igoera abiadura igoera muga globala lortu denean [0: ezgaituta]
+UpdateMonitor.messagebox.verification.failed.title=Ezarpen Egiaztapenak Huts egin du
+UpdateMonitor.messagebox.verification.failed.text=Egiaztapena '%1' hutseginda: %2
+UpdateMonitor.messagebox.accept.unverified.title=Onartu Egiaztatugabeko Ezarpena
+UpdateMonitor.messagebox.accept.unverified.text='%1' ez da Vuzeren plugin ofizial bezala egiaztu ahal izan.\nJarraitu behar EZ duen plugina bada.\nEzarpena egin?
+FileView.BlockView.title=Agiri Atalak
+FileView.BlockView.Done=Eginda
+FileView.BlockView.Skipped=Ahaztuta
+FileView.BlockView.Active=Jardunean
+FileView.BlockView.Outstanding=Egikete
+ConfigView.label.tcplistenport=Sarrera TCP aditze ataka
+ConfigView.label.udplistenport=UDP aditze ataka
+upnp.portchange.alert=Hurrengo atakek aldatu egin dira UPnP gailuetan arazoak sahiesteko: %1 [ataka zaharra=%2] %3 [ataka zaharra=%4]
+ConfigView.section.proxy.username.info=Proxy zerbitzariak egiaztapena eskatzen badu baita zehaztua ez denean, erabili kate hau "<none>" erabiltzaile izen(ak) bezala
+ConfigView.label.maxuploadswhenbusymin=Torrent bakoitzeko geh. igoera abiadura hartuta denboragailuan dagoenean [seg]
+MainWindow.menu.help.debug=Sortu Garbiketa Argibideak (Istripu oharra)
+DownloadManager.error.badsize=Neurri Okerra
+natpmp.info=NAT-PMP Apple-n UPnP aukera da eta berriki Hegazkaietan ere sostengatua da\n\nJakin ezazu orain duzun UPnP gaituta dagoela NAT-PMP gaitzeko NAT-PMP gailu bezala UPnP gailu mota berezitzat hartzen da 
+natpmp.enable=Gaitu (jakin ezazu  lan egiteko hegazkaiko itxurapenean ere gaituta egon behar dela )
+ConfigView.section.tracker.host.addurls=Zihurtatu aztarnari hauen URL-ak ostatutako torrenteetan daudela
+ConfigView.filter=idatzi iragazteko hitza(k)
+ConfigView.section.files.move=Osaketa Mugitzen
+ConfigView.section.file.defaultdir.section=Berezko Zuzenbide Aukerak
+ConfigView.section.file.defaultdir.auto=Berezgaitasunez jeitsi berezko zuzenbidera (Ez Garaionekoa)
+ConfigView.section.file.defaultdir.bestguess=Erabili ustezko hoberena gordetzeko zuzenbide berezkoa hautatzerakoan
+ConfigView.section.file.defaultdir.ask=Berezko zuzenbidea:
+ConfigView.section.file.defaultdir.lastused=Eguneratu berezko zuzenbidea gordetako azken helbidera
+ConfigView.section.file.config.section=Itxurapen Ezarpenak:
+ConfigView.section.file.config.currentdir=Oraingo itxurapen zuzenbidea:
+ConfigView.section.torrent.decoding=Dekodeaketa Ezaugarri Ezarpenak
+ConfigView.section.logging.udptransport=Gaitu UDP garraio aztarna aditzea 
+Tracker.announce.ignorePeerSeed=Baztertzen Hartzaile/Emale zenbaketa. %1
+ConfigView.section.connection.encryption.use_crypto_port=Erabili 'kriptoataka' aztarnari hedapena sahiesteko sarrera lauko elkarketa saiakerak. Aztaranari batzuek ez dute onartzen hau eta  honelako akatsak dituzte "Atata Okerra' edo 'Legezkanpoko gatazka'
+TorrentOptionsView.param.reset.to.default=Ezarri aukerak berezko balioetan
+TorrentOptionsView.param.reset.button=Birrezarri
+natpmp.routeraddress=Geltoki helbidea [blank: auto]
+ConfigView.section.style.disableAlertSliding=Ezgaitu labantze biziduna/goren eran alerta mezuentzat
+ConfigView.section.transfer.autospeed.maxinc=%1 gehienezko gorapena aldi bakoitzeko
+ConfigView.section.transfer.autospeed.maxdec=%1 gehienezko beherapena aldi bakoitzeko
+ConfigView.section.transfer.autospeed.enabledownadj=Gaitu jeisketa abiadura neurriratzea
+ConfigView.section.transfer.autospeed.downadjratio=Jeisketa: Igoera abiadura maila (adib. 2.0 -> jeisketa abiadura muga igoera mugaren bikoitza da)
+ConfigView.section.transfer.autospeed.latencyfactor=Ezkutuko aldaketak abiadura aldaketekin lotzeko erabiltzen den ezaugarria (zenbaki luzeek sentikortasuna murrizten dute)
+ConfigView.section.transfer.autospeed.reset=Berrezarri balio aurreratuak
+ConfigView.section.transfer.autospeed.reset.button=Birrezarri
+PeerColumn.activationCount=Elkarketa egiten saiatzen diren hartzaileak: %1
+TableColumn.header.timesincedownload.info=Datua torrenterako jeitsi zenetik igarotako denbora
+TableColumn.header.timesincedownload=Jeitsi Idle-a
+TableColumn.header.timesinceupload.info=Datua torrenterako igo zenetik igarotako denbora
+TableColumn.header.timesinceupload=Igo Idle-a
+PeersView.incomingreqcount=Sarrera Eskab.
+PeersView.incomingreqcount.info=Hartzaileek eginiko sarrera eskabide zenbatekoa
+PeersView.outgoingreqcount=Irteera Eskab.
+PeersView.outgoingreqcount.info=Hartzaileari egindako irteera eskabideen zenbatekoa
+upnp.mapping.trackerclientudp=UDP Aztarnari Bezero Ataka
+upnp.mapping.dhtudp=Banaturiko Datubasea
+ConfigView.section.connection.nondata.udp.same=Erabili UDP ataka bera Banaturiko Datubaserako eta UDP Aztarnarirako
+ConfigView.section.connection.tcp.enable=Gaitu TCP-a
+ConfigView.section.connection.udp.enable=Gaitu UDP-a
+ConfigView.section.style.showiconbar=Erakutsi Tresnabarra
+MainWindow.menu.view.iconbar=Tresnabarra
+MyTorrentsView.menu.rename=Birrizendatu...
+MyTorrentsView.menu.rename.displayed=Birrizendatu Erakutsitako Izena
+MyTorrentsView.menu.rename.save_path=Birrizendatu Gordetzeko Helburua
+AdvRenameWindow.title=Birrizendatu Jeisketa
+AdvRenameWindow.message=Idatzi izen berri bat jeisketa honi.
+AdvRenameWindow.rename.torrent=Birrizendatu Torrenta
+MyTorrentsView.menu.rename.displayed.enter.title=Birrizendatu Erakutsitako Izena
+MyTorrentsView.menu.rename.displayed.enter.message=Sartu jeisketa honentzako erakusteko izen berri bat.
+MyTorrentsView.menu.edit_comment=Aipamena Editatu
+MyTorrentsView.menu.edit_comment.enter.title=Aipamena Argitaratu
+MyTorrentsView.menu.edit_comment.enter.message=Sartu aipamen bat jeisketa honentzat.
+UIDebugGenerator.messageask.title=Garbiketa Sorgailua
+UIDebugGenerator.messageask.text=Mesedez sartuzazu jakinarazten ari zaren akatsaren azalpen bat
+UIDebugGenerator.complete.title=Garbiketa Sortzea Ezeztaturik
+UIDebugGenerator.complete.text=Garbiketa agiria ezin da aurkitu '%1'.\n\nKlikatu Ongi agiri honentzat erabide-agiri leiho bat irekitzeko. 
+ConfigView.section.style.showProgramIcon=Erakutsi programaren ikurra izen zutabean
+ConfigView.section.style.showProgramIcon.tooltip=Ikusik bir-irekitzea behar izan dezake aldaketak eragina izan dezaten
+swt.alert.cant.update="%3" -tik hartutako SWT liburutegia ezin da berezgaitasunez egunaratua izan %1 to %2 bertsiotik  ("%4"-tik egon behar du hartuta). Mesedez ikusi <A HREF="http://wiki.vuze.com/w/SWT_Cant_Auto_Update">the wiki</A> xehetasunetarako.
+authenticator.savepassword=Gogoratu nire sar-hitza
+ConfigView.section.security.clearpasswords=Birrezarri gogoraturiko sar-hitzak
+ConfigView.section.security.clearpasswords.button=Birrezarri
+TorrentInfoView.torrent.encoding=Torrentak kodeatzen
+TorrentInfoView.columns=Zutabeak '{library.name}' ikusi
+progress.window.title=Eragiketa Garatzen
+progress.window.msg.filemove=Mesedez itxaron agiri mugitze/birrizendatzea burutzen den bitartean
+ConfigView.label.popup.timestamp=Gehitu ordu-irarketa alerta oharrei
+ConfigView.label.popup.autohide=Berezgaitasunez ezkutatu akatsenak ez diren ohar alertak x segundu ondoren (ezarri 0 berez ezkutatzea ezgaitzeko)
+ConfigView.label.please.visit.here=Mesedez ikusi hemen xehetasunak
+ConfigView.section.ipfilter.enable.descriptionCache=Bildu IP azalpenak urratu agirian
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Ezgaituta dagoenean, azalpenak ez dira gogoratuko
+OpenTorrentWindow.filesInfo=%1 %2-tik izango dira jeitsiak.
+OpenTorrentWindow.diskUsage=%1 %2-tik
+ConfigView.label.openmytorrents=Ireki Liburutegia hasitakoan
+ConfigView.label.open_transfer_bar_on_start=Ireki Eskualdaketa Barra hasieran
+ConfigView.section.style.DNDalwaysInIncomplete=Erakutsi betik Liburutegiko Osatugabe sailean  'Ez Jeitsi' duten agiriak
+OpenTorrentWindow.mb.noGlobalDestDir.title=Helmuga Zuzenbidea ez da aurkitu
+OpenTorrentWindow.mb.noGlobalDestDir.text=%1' helmuga zuzenbidea baliogabea da.
+OpenTorrentWindow.mb.noDestDir.title=Helmuga Zuzenbidea ez da aurkitu
+OpenTorrentWindow.mb.noDestDir.text='%2' torrentarentzako '%1' helmuga zuzenbidea ez dago edo baliogabea da.
+OpenTorrentWindow.mb.notValid.title=Ireki Torrent Akatsduna
+OpenTorrentWindow.mb.notValid.text=Ezin da '%1' torrenta ireki. Emaletzan moduan irekitzen ari bazara, mesedez zihurtatu zaitez torrentaren datu agiria badagoela.
+OpenTorrentWindow.mb.notTorrent.title=Ireki Huts egin duen Torrenta 
+OpenTorrentWindow.mb.notTorrent.text=Ezin da '%1' ireki. Ez dirudi .torrent agiri bat denik.\n\nJasotako datu batzuk:\n%2
+ConfigView.label.pause.downloads.on.exit=Gelditu jeisketak irteterakoan
+ConfigView.label.resume.downloads.on.start=Jarraitu pausaturiko jeisketekin hasterakoan abiatzea osoatuta dagoenean
+UIDebugGenerator.message.cancel.title=Garbiketa Argibidea Sortzea Ezeztatuta
+UIDebugGenerator.message.cancel.text=Ez duzu jakinarazten saiatzen ari zaren akatsaren azalpenik. Zure akatsa argia izan daiteke zuretzat, baina azalpen bat izan gabe, zure arazoaz guk egin dezakeguna asmatzea besterik ez litzake.\n\nGarbiketa Argibide Sortzea ezeztatua izan da.
+ConfigView.section.connection.group.http.info=Sostengua HTTP emaletzarako
+ConfigView.section.connection.http.enable=Gaitu
+ConfigView.section.connection.http.port=Sarrera ataka zenbakia
+ConfigView.section.connection.http.portoverride=Aztarnariaren HTTP ataka ezabatu [0: bat ere ez]
+window.update.noupdates.title=Egiaztatu Eguneraketa Emaitzak
+window.update.noupdates.text=Ez dago eguneraketa berririk eskuragarri.\n\nZorionak!
+ConfigView.label.bindip.details=Adibidea: 192.168.1.5;eth0;eth1[2]  behartu dezake IP bereizi bat, 1. interfazearen IP guztietara eta 2. interfazearen 3. IP-ra .\n1. IP-a zerbitzu guztietarako erabilitzen da, beste guztiak zama orekatzeko erabiltzen dira\nHurrengo interfazeak daude baliagarri:\n%1
+ConfigView.label.mindownloads=Gutx. aldibereko jeisketa
+UI.cannot_submit_blank_text=Balio bat sartu behar duzu.
+crypto.alert.as.warning='%1' sarea ezaguna ezartzeagaitik joan-etorri eraketak jeisketa egitea murriztuz.. Garraio enkriptaketa berezgaitasunez gaitzen da - Hau ezgaitu/aldatu daiteke itxurapenaren bidez.
+ConfigView.section.interface.alerts=Alertak
+ConfigView.label.popupdownloadadded=Ohar alerta jeisketa gehitzen denean
+popup.download.added="%1" zure jeisketa zerrendara gehitu da.
+MessageBoxWindow.nomoreprompting=Ez galdetu berriro
+TorrentOptionsView.param.max.seeds=Geh. emale elkarketak [0: elkarketa muga]
+TorrentOptionsView.param.alternative.value.enable=Txandakatu balioa emaletzan
+ConfigView.section.proxy.check.on.start=Egiaztatu proxyaren egoera hasterakoan
+TransferStatsView.legend.pingaverage=Bataz-bestekoa
+TransferStatsView.legend.ping1=1 Xedea
+TransferStatsView.legend.ping2=2 Xedea
+TransferStatsView.legend.ping3=3 Xedea
+ConfigView.section.interface.enabletray._mac=Gaitu Egoera Barra Ikurra [birrabiaraztea beharrezkoa]
+ConfigView.label.closetotray._mac=Itxi txikiagotuak Egoera Barra Ikurrera
+ConfigView.label.minimizetotray._mac=Egoera Barrako Ikurreratzen du
+OpenTorrentWindow.mb.existingFiles.title=Agiria badago!
+OpenTorrentWindow.mb.existingFiles.text=Agirietako batzuk jadanik badaude adierazitako agiritegian:\n\n%1\nJarraitzen baduzu, Vuzek datu zuzenak lortzeko agirien gaineko egiaztapena egin dezake eta gainidatzi beharrezkoa bada.
+splash.unloadingTorrents=Torrentak Ezgertatzen
+splash.unloadingTorrent=Torrenta Ezgertatzen
+ConfigView.section.file.defaultdir.autorename=Berez birrizendatu torrent datuak agiriak helburuan ezberdinak ikusten badira
+ConfigView.section.file.defaultdir.autorename.tooltip=Honek sahiesten du torrent batek beste torrent baten agiriak gainidaztea izenak berdinak direnean 
+alert.raised.at.close=(Mezua aurretik itxitako Vuzetik)
+Plugin.trackerpeerauth.name=Aztarnari Hartzaile Baimena
+Plugin.trackerpeerauth.info=Plugin honek lan egiten du aztarnariekin hartzaileak erletaldeko kide baliagarriak direla egiaztatzeko 
+Peers.column.maxupspeed=Geh. Igoera Abiadura
+Peers.column.maxdownspeed=Geh. Jeisketa Abiadura
+MyTorrents.items.DownSpeedLimit.disabled=Ez jeitsi
+upnp.selectedaddresses=Helbideak (';' banandurik, '-' prefix=deny, '+' =allow) [blank: any]
+upnp.alert.multipledevice.warning=UPnP gailu anitz atzeman dira - egiaztatu denak behar duten ataka izendapena (ikusi UPnP sarrera eta itxurapena)
+UpdateMonitor.messagebox.restart.title=Software Eguneraketa
+UpdateMonitor.messagebox.restart.text=Vuzek eguneraketa garrantzitsu baten jeisketa burutu du eta orain birrabiarazia izan behar da eguneraketa ezarria ahal izateko
+PiecesView.BlockView.Have=Du
+PiecesView.BlockView.NoHave=Ez Du
+PiecesView.BlockView.Header=%1 zutabe, %2 lerro, %3 atal
+ConfigView.section.update.autodownload=Berez jeitsi eguneraketak eta galdetu ezarpena gertu dagoenean 
+Peers.column.peer_id=Hartzaile ID-a
+Peers.column.peer_id.info=Hartzailearen ID-a era irakurgarrian
+Peers.column.peer_byte_id=Hartzaile ID-a
+Peers.column.peer_byte_id.info=Hartzailearen ID-a byte eran
+Peers.column.handshake_reserved=Eskukadak Gordetako Byte-ak
+Peers.column.handshake_reserved.info=Adierazten du zein bit izan ziren ezarriak BT eskukadan
+Peers.column.client_identification=Bezero Nortasuna
+Peers.column.client_identification.info=Adierazten du Vuzetik jasoriko bezero izenak - erabilgarria garbiketarako
+dht.warn.user=Jakinarazi balizko NAT/ ataka mapaketa arazoak
+ConfigView.label.openbar.incomplete=Jeisketa barrak: berez ireki jeisketak
+ConfigView.label.openbar.complete=berez ireki emaleak
+ConfigView.label.transferbar.remember_location=Gogoratu eskualdaketa barraren azken kokapena
+ConfigView.section.transfer.autospeed.forcemin=%1 igoera abiadura behartuta ohinbideratze elkarketan
+MainWindow.menu.tools.speedtest=Abiadura Azterketa...
+speedtest.wizard.title=Abiadura Azterketa
+speedtest.wizard.run=Egin abiadura azterketa bat
+speedtest.wizard.test.mode.updown=igoera eta jeisketa
+speedtest.wizard.test.mode.up=igo
+speedtest.wizard.test.mode.down=jeitsi
+SpeedTestWizard.test.panel.currinfo=BitTorrent bandazabalera aztertzen.
+SpeedTestWizard.test.panel.label=Vuze abiadura azterketa:
+SpeedTestWizard.test.panel.already.running=Azteketa jadanik lanean!
+SpeedTestWizard.test.panel.not.accepted=Azterketa eskabidea ez da onartu:
+SpeedTestWizard.test.panel.abort=Utzi
+SpeedTestWizard.test.panel.abort.countdown=Azterketa hemen utzita:
+SpeedTestWizard.test.panel.test.countdown=azterketa amaituko da:
+SpeedTestWizard.test.panel.testfailed=Azterketak huts egin du
+SpeedTestWizard.test.panel.aborted=Azterketa eskuz utzita
+SpeedTestWizard.test.panel.enc.label=Sakatu enkriptaketarekin aztertzeko: 
+SpeedTestWizard.test.panel.standard=irizpidea
+SpeedTestWizard.test.panel.encrypted=enkriptatuta
+SpeedTestWizard.set.upload.button.apply=Ezarri
+SpeedTestWizard.set.upload.result=Azken Azterketaren Emaitza
+SpeedTestWizard.set.upload.bytes.per.sec=kByte/seg
+SpeedTestWizard.set.upload.bits.per.sec=bit/seg
+SpeedTestWizard.finish.panel.title=Abiadura Azterketa Amaiturik!
+SpeedTestWizard.finish.panel.click.close=Amaitu duzu abiadura azterketa laguntzailea. Egin Klik hemen irteteko
+SpeedTestWizard.finish.panel.max.upload=Geh. igoera:
+SpeedTestWizard.finish.panel.max.seeding.upload=Geh. igoera emaletzen:
+SpeedTestWizard.finish.panel.max.download=Geh. jeisketa:
+SpeedTestWizard.finish.panel.enabled=gaiturik
+SpeedTestWizard.finish.panel.disabled=ezgaiturik
+SpeedTestWizard.abort.message.scheduled.in=azteketa egitarauturik ... %1 segundutan
+SpeedTestWizard.abort.message.unsupported.type=Azterketa mota ez sostengatua!!!!
+SpeedTestWizard.abort.message.manual.abort=Eskuz utzita
+SpeedTestWizard.abort.message.scheduling.failed=Azterketaren egitaraupenak huts egin du
+SpeedTestWizard.abort.message.download.added=Azterketan gehitutako %1 jeitsi
+SpeedTestWizard.abort.message.entered.error=Aztertu osoki jeitsitako akats egoera '%1'
+SpeedTestWizard.abort.message.entered.queued=Aztertu osoki jeitsitako lerrokaturik/geldituta egoera
+SpeedTestWizard.abort.message.interrupted=TorrentAbiaduraAzterketaLeihoMezua eten egin da azterketa amaitu aurretik
+SpeedTestWizard.abort.message.execution.failed=Azterketa egiteak huts egin du
+SpeedTestWizard.abort.message.failed.peers=Huts egin du hartzaileetara elkarketatzean
+SpeedTestWizard.abort.message.insufficient.slots=Ezin da igo edozein hartzailetara - ez dago nahikoa igoera aho?
+SpeedTestWizard.abort.message.not.unchoked=Ezin da inoiz itogabetu ez diren hartzaieetatik jeitsi
+SpeedTestWizard.stage.message.requesting=azterketa eskabidean...
+SpeedTestWizard.stage.message.preparing=azterketa gertatzen...
+SpeedTestWizard.stage.message.starting=azterketa hasten...
+SpeedTestWizard.stage.message.connect.stats=Elkarketa estatistikak: hartzaileak=%1, behera_ongi=%2, gora_ongi=%3
+window.uiswitcher.title=Vuze EI Hautatzailea
+window.uiswitcher.text=Mesedez hautatu zure beharretara hobekien egokitzen den erabiltzaile interfaze bat.
+window.uiswitcher.NewUI.text=* Gomendatua hasiberrientzat eta erabilltzaile berrientzat.\n\n* Erraza, ikusizko grafiko interfazea 
+window.uiswitcher.ClassicUI.title=Interfaze Klasikoa
+window.uiswitcher.ClassicUI.text=*Bezeroaren eginkortasun 2.x serieak gordetzen ditu\n\n* Hegats erakuste klasikoa
+iconBar.switch.tooltip=Vuze UI Hautatzailea
+VivaldiView.notAvailable=Vivaldi Ikuspena ez dago eskuragarri
+restart.error=Birrabiarazteak huts egin du\n%1\nIkusi <A HREF="{restart.error.url}">birrabiarazte gaiak</a>.
+restart.error.oom=Oroimenetik kanpo
+restart.error.fnf='%1' ez da aurkitu '%2'
+restart.error.pnf='%1' Helburua ez da aurkitu
+restart.error.bad=Agiri heuskarri okerra '%1'
+restart.error.denied=Sarbidea ukatua izan da '%1' abiarazten saiatzean. Zihur zaude programa hau abiarazteko eskubidea duzula.
+TableColumn.header.date_completed=Osaturik
+TableColumn.menu.date_added.reset=Birrezarri Eguna
+ConfigView.section.ipfilter.discardbanning=Itxi hartzaileak baztertutako datuak/datu onak bataz-bestekoa gainditzen badu  [0: ezgaituta]
+ConfigView.section.ipfilter.discardminkb=Gutxienez %1 baztertuta bataz-bestekoa ezarri aurretik
+ConfigView.interface.start.advanced=Hasi Ikuspegi Aurreratuan (AZ 2.x)
+MyTorrents.column.ColumnQuality=Ontasuna
+MyTorrents.column.ColumnSpeed=Abiadura
+MyTorrents.column.ColumnProgressETA.2ndLine=UED: %1
+MyTorrents.column.ColumnProgressETA.StreamReady=Jarioa Gertu
+MyTorrents.column.ColumnProgressETA.PlayableIn=Irakurgarri %1
+TableColumn.header.Quality=Ontasuna
+TableColumn.header.Speed=Abiadura
+TableColumn.header.RateIt=Maila
+TableColumn.header.Rating=Mailatzen
+TableColumn.header.SpeedGraphic=Abiadura
+TableColumn.header.AzProduct=Hemendik
+TableColumn.header.MediaThumb=Hedabidea
+TableColumn.header.ProgressETA=Garapena
+TableColumn.header.name.ext=Agiri Mota: %1
+TableColumn.header.DateCompleted=Eguna
+v3.MainWindow.tab.home=Tresnaohola
+v3.MainWindow.tab.browse=Vuzen
+v3.MainWindow.tab.library=Liburutegia
+v3.MainWindow.tab.publish=Argitaratu
+v3.MainWindow.tab.advanced=Aurreratua
+v3.MainWindow.menu.home=&Tresnaohola
+v3.MainWindow.menu.browse=&Vuzen
+v3.MainWindow.menu.library=&Liburutegia
+v3.MainWindow.menu.publish=&Argitaratu
+v3.MainWindow.menu.advanced=&Aurreratua
+v3.MainWindow.menu.view.searchbar=Bilaketa Barra
+v3.MainWindow.menu.view.tabbar=Hegats Barra
+v3.MainWindow.currentDL=Orain Jeisten
+v3.MainWindow.button.stream=Jarioa
+v3.MainWindow.button.stop=Gelditu
+v3.MainWindow.button.start=Hasi
+v3.MainWindow.button.pause=Pausatu
+v3.MainWindow.button.resume=Jarraitu
+v3.MainWindow.button.delete=Ezabatu
+v3.MainWindow.button.comment=Aipamena
+v3.MainWindow.button.viewdetails=Ikusi Xehetasunak
+v3.MainWindow.button.play=Irakurri
+v3.MainWindow.button.cancel=Ezeztatu
+v3.MainWindow.button.preview=Aurreikuspena
+v3.MainWindow.view.wait=Ikuspena abiatzen, mesedez itxaron
+v3.MainWindow.xofx=%1 %2 -tik
+v3.MainWindow.Loading=Gertatzen... Mesedez Itxaron
+v3.filter-bar=Izenburu Iragazkia:
+v3.MainWindow.search.defaultText=aurkitu...
+v3.mb.delPublished.title=Gelditu Eduki Emaletza
+v3.mb.delPublished.text=KONTUZ: Ekintza honek EZ du argitaraturiko zure edukia kenduko '%1' hemendik <A HREF="%2">%3</A> .\n\nKlikatu "Ezabatu" zure edukiak argitaraturik eta jeisgarri nahi badituzu bakarrik, baina zure bandazabalera askatzea nahi baduzu. Egin aurretik zihurtatu zaitez igoera aurrerabidea burutu dela (<A HREF="%4">nola</A>?).\n\nKlikatu "Ezeztatu" argitaraturiko zure edukiak erabat kentzea nahi badituzu %3, eta erabili (X) botoia Argitaraturiko Edukia leihoan Argitalpen  [...]
+v3.mb.delPublished.delete=&Ezabatu
+v3.mb.delPublished.cancel=&Ezeztatu
+v3.mb.openFile.title=Ireki Agiria
+v3.mb.openFile.text.known=Eduki hau ez da Vuzeren Irakurgailuaz sostengatua. Bilatu sortzaile-herkidegoan<a href="http://wiki.vuze.com/w/Playback_Guide">Playback Guide</a> laguntza lortzeko.\n\nAgiri Mota Dirudi: %2 (%3)\n
+v3.mb.openFile.text.unknown=Eduki hau ez da Vuzeren Irakurgailuaz sostengatua. Bilatu sortzaile-herkidegoan<a href="http://wiki.vuze.com/w/Playback_Guide">Playback Guide</a> laguntza lortzeko.\n\nAgiri Hedapena : %2\n
+v3.mb.openFile.button.play=Irakurri
+v3.mb.openFile.button.cancel=Ezeztatu
+v3.mb.openFile.button.guide=Irakurri Playback Gida
+v3.mb.openFile.remember=Betik ireki agiriak niri galdetu gabe
+v3.mb.PlayFileNotFound.title=Agira Ez da Aurkitu
+v3.mb.PlayFileNotFound.text=Hemengo agiriak '%1' ezabaturik edo galduta daude.
+v3.mb.PlayFileNotFound.button.remove=Kendu Vuzetik
+v3.mb.PlayFileNotFound.button.redownload=Birjeitsi Datuak
+v3.mb.PlayFileNotFound.button.find=Eskuzko Bilaketa.
+v3.mb.deletePurchased.title=Kendu Erositako Edukiak
+v3.mb.deletePurchased.text=Zihur zaude edukia ezabatzea nahi duzula '%1'?\n\nHau da erosi duzun edukia, edo beharrezkoa dena jeisketa egiteko.
+v3.mb.deletePurchased.button.delete=&Ezabatu
+v3.mb.deletePurchased.button.cancel=&Ezeztatu
+v3.topbar.menu.show.logo=Logoa
+v3.topbar.menu.show.plugin=Plugin Gunea
+v3.topbar.menu.show.search=Bilatu
+v3.topbar.menu.show.frog=Da Igel Urdina
+splash.initializeCore=Core abiatzen
+splash.initializeUIElements=EI Osagaiak Abiatzen
+ConfigView.section.transfer.autospeedbeta=Berez-Abiadura-Beta
+ConfigView.section.ipfilter.peerblocking.group=Hartzaile Itxipena
+ConfigView.section.ipfilter.autoload.group=Berez Gertatzen
+ConfigView.section.ipfilter.autoload.file=IP iragazki agiria berezgertatzeko
+ConfigView.section.ipfilter.autoload.info=DAT (eMule), P2P (PeerGuardian, splist), eta P2B v1,2,3 (PeerGuardian 2) heuskarriak sostengatuta. Agiria tokikoa izan daiteke edo URL, zip'd, gzip'd edo idazki laua. URL-ak berezgaitasunez birjeitsiko dira 7 egun ondoren, aldiz agiriak birgertatzen dira ordeztua/ikutua izan eta minutu batera.
+ConfigView.section.ipfilter.autoload.loadnow=Gertatu Orain
+splash.loadIpFilters=IP Iragazkiak Gertatzen...
+SpeedTestWizard.set.upload.title=Ezarri Igoera eta Jeisketa Mugak
+SpeedTestWizard.set.download.label=Jeisketa Abiadura Muga:
+SpeedTestWizard.set.upload.label=Igoera Abiadura Muga:
+SpeedTestWizard.name.conf.level.absolute=Osoa
+SpeedTestWizard.name.conf.level.high=Handia
+SpeedTestWizard.name.conf.level.med=Ertaina
+SpeedTestWizard.name.conf.level.low=Txikia
+SpeedTestWizard.name.conf.level.none=Ez
+ConfigView.section.transfer.select=Berez-Abiadura
+ConfigView.section.transfer.select.v2=Berez-Abiadura (beta)
+mb.azmustclose.title=Abiatze Akatsa
+mb.azmustclose.text=Vuzek amaitu beharra du arazo bat dagoelako Vuzeren (bir)abiaraztean zihurrenik eragin duena programa erabiltzaile administrari bezala exekutatu izana.\n\nVuze itxi ondoren, mesedez bir-ireki eskuz.
+network.ipv6.prefer.addresses=Lehenetsitako IPv6 helbideak biak IPv6 eta IPv4 eskuragarri daudenean
+network.bindError=Lotura zerbitzariaren argiburuak huts egin du helbide eskuragarririk ez dagoelako, mesedez egiaztatu zure IP loturen ezarpenak.
+network.enforce.ipbinding=Betearazi IP loturak baita interfazeak eskuragarri ez direnean, sahiestu edozein elkarketa adierazitako interfazeetako bat ere eskuragarria ez denean
+DHTView.title.full_v6=Banaturiko Datubasea IPv6
+ConfigView.pluginlist.loadSelected=Gertatu Hautatutakoa
+SpeedView.stats.asn=Sarea:
+SpeedView.stats.estupcap=Igoera muga:
+SpeedView.stats.estdowncap=Jeisketa muga:
+SpeedView.stats.unknown=Ezezaguna
+SpeedView.stats.estimate=Irizpena
+SpeedView.stats.measured=Neurtuta
+SpeedView.stats.measuredmin=Neurtuta Gutx.
+SpeedView.stats.manual=Finkatuta
+ConfigView.section.transfer.autospeed.networks=Sare Xehetasunak
+ConfigView.section.transfer.autospeed.resetnetwork=Birrezarri sare xehetasunak
+ConfigView.section.transfer.autospeed.network.info=Gaineko mugak arrunt berezgaitasunez kalkulatzen dira jeisketan zehar edo abiadura azterketa baten emaitza dira.. Eskuz adireraztea nahi badituzu erabili beheko aukerak.\nBeste muga guztiak 'finkoak' ondoren ezarriko dira berezgaitasunez beharrezkoa bada \nSartu balioa eta hautatu mota. Kontuan izan abiadurak direla %1.
+dialog.uiswitcher.restart.title=EI Aldagailua: Vuze Birrabiaraztea Beharrezkoa
+dialog.uiswitcher.restart.text=Vuzek birrabiaraztea behar du UI modu berrira aldatzeko.
+TrayWindow.menu.close=Itxi Jeisketa Saskia
+# Used for peers which we can't determine.
+PeerSocket.unknown=Ezezaguna
+PeerSocket.fake_client=USTELA
+PeerSocket.bad_peer_id=hartzaile txar ID-a
+PeerSocket.mismatch_id=ez dator bat
+PeerSocket.unknown_az_style=Ezezaguna %1 %2
+PeerSocket.unknown_shadow_style=Ezezaguna  %1 %2
+OpenTorrentWindow.mb.askCreateDir.title=Helmuga Zuzenbidea ez dago
+OpenTorrentWindow.mb.askCreateDir.text='%1' helmuga zuzenbidea ez dago.\n\nOrain sortu?
+SpeedView.stats.estimatechoke=Irizpena (itopena)
+ConfigTransferAutoSpeed.upload.capacity.usage=Igoera Gaitasun Erabilia
+ConfigTransferAutoSpeed.mode=Era:
+ConfigTransferAutoSpeed.capacity.used=% Gaitasun Erabilia
+ConfigTransferAutoSpeed.while.downloading=Jeisten:
+ConfigTransferAutoSpeed.set.dht.ping=DHT Ping Ezarpenak:
+ConfigTransferAutoSpeed.set.point=zehazte puntua (ms)
+ConfigTransferAutoSpeed.set.tolerance=jasangarritasuna (ms)
+ConfigTransferAutoSpeed.ping.time.good=Ona:
+ConfigTransferAutoSpeed.ping.time.bad=Gaitza:
+ConfigTransferAutoSpeed.adjustment.interval=Zehaztu tarteak:
+ConfigTransferAutoSpeed.skip.after.adjust=Egin jauzi zehaztu ondoren:
+GeneralView.label.distributedCopies=Banatutako Kopiak:
+PiecesView.DistributionView.title=Atalen Banaketa
+PiecesView.DistributionView.NoAvl=Atal Eskuraezinak
+PiecesView.DistributionView.SeedAvl=Emale Eskur.Ekarpena
+PiecesView.DistributionView.PeerAvl=Hartzaile Eskur.Ekarpena
+PiecesView.DistributionView.RarestAvl=Atal Arraroak: %1 (Eskur:%2)
+PiecesView.DistributionView.weHave=Dituzun atalak
+PiecesView.DistributionView.theyHave=Hartzaileak dituen atalak
+PiecesView.DistributionView.weDownload=Jeisten ari zaren atalak
+PeersView.gain=Irabazia
+PeersView.gain.info=Jeitsitako-igotako datu zenbatekoa
+unix.script.new.title=Vuzeren Abiarazpen Script Berria eskuragarri
+unix.script.new.text=Vuzeren abiarazte script berri bat eskuragarri dago, eta hemen gordea izan da '%1'.\n\nOso gomendagarria da Vuzetik irtetea eta script honetara aldatzea ('%2').\n\nOso eraldatua baduzu zure Vuze abiarazte scripta, mesedez ikusi <A HREF="{unix.script.new.manual.url}">VuzeWiki: Unix Script</A>.\n\nVuze distro batetik ezarri bazenuen (yum, apt-get, e.a), Gomendatzen da Vuze birrabiaraztea erabiliz  hemen dagoen pakete hau <AHREF="http://www.vuze.com/download/">Vuze Down [...]
+unix.script.new.button.quit=Irten Orain
+unix.script.new.button.continue=Geroago Egin Dezaket
+unix.script.new.button.asknomore=Ez Esan Berriro
+unix.script.new.auto.title=Vuzeren Abiarazpen Script Berria
+unix.script.new.auto.text=Vuzeren Abiarazpen Script berria eskuragarri.\n\nOso gomendagarria da zure Vuze birrabiarazia izatea orain.
+Content.alert.notuploaded.button.abort=&Ez Irten
+ConfigView.label.checkOnSeeding=Egin baliabide gutxiko atalen egiaztapena emaletzan 
+ConfigView.label.ui_switcher=Erakutsi Vuze EI Hautatzailea
+ConfigView.label.ui_switcher_button=Erakutsi
+SpeedTestWizard.test.panel.explain=Neurtu zure Vuze protokoloaren abiadura. Hautatu abiadura azterketa mota eta enkriptaketa modua. Ikusi Vuzeren wiki orrialdea azterketa honi buruzko xehetasunetarako. Azterketa berezgaitasunez gelditu daiteke bi minutu baino gehiago luzatzen bada. Ohiko azterketak minutu bat baino gutxiagoan amaitzen dira.
+SpeedTestWizard.set.upload.hint=Ezarri Vuzeren BerezAbiadura algoritmoan erabiliko dire igoera eta jeisketa mugak.
+SpeedTestWizard.set.upload.panel.explain=Hemen ezarritako mugak Vuzeren BerezAbiadura algoritmorako erabiltzen dira. Ezarri eskualdaketa mugak eta segurtasun mugak.\n\nKontuan izan bide abiadurak maiz "bit segunduko" neurrian ematen direla - horrela ere behean erakusten diren balioak "kilobyte segunduko" neurrian ematen dira.
+SpeedTestWizard.set.limit.conf.level=Segurtasuna
+SpeedTestWizard.finish.panel.auto.speed=BerezAbidura da:
+SpeedTestWizard.finish.panel.auto.speed.seeding=BerezAbiadura emaletza denean:
+ConfigTransferAutoSpeed.add.comment.to.log.group=Gehitu aipamena garbiketa saioan
+ConfigTransferAutoSpeed.add.comment.to.log=Gehitu aipamena:
+ConfigTransferAutoSpeed.log.button=Laburpena
+ConfigTransferAutoSpeed.algorithm.selector=Berez-Abiadura hautagailua
+ConfigTransferAutoSpeed.algorithm=Algoritmoa:
+ConfigTransferAutoSpeed.auto.speed.classic=Berez-Abiadura(klasikoa)
+ConfigTransferAutoSpeed.auto.speed.beta=Berez-Abiadura(beta)
+ConfigTransferAutoSpeed.data.update.frequency=Eguneratze Maiztasuna
+Alert.failed.update=Huts egin du gutxienez osagai baten ezarpenak. Ikusi  <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
+Alert.failed.update.url=http://wiki.vuze.com/w/Failed_Update\u005c
+OpenTorrentWindow.mb.existingFiles.partialList=(Zerrenda osatugabea  Agiri gehieago jadanik badaude)
+TableColumn.header.bad_avail_time.info=Jeisketaren kopia oso bat eskuragarria izan zen azken aldia
+TableColumn.header.bad_avail_time=Kopia Osoa Ikusita
+MyTorrentsView.menu.exporthttpseeds=Esportatu HTTP emale URL-ak gakora
+SWT.alert.erroringuithread=Maneiaezinezko akats bat gertatu da GUI-an, akats gehiago egon daiteke.
+ConfigView.label.minannounce=Gutxienezko denbora aztarnariaren iragarpenen artean segundutan
+ConfigView.label.maxnumwant=Mugatu itzul daitezkeen aztarnari hartzaile zenbatekoa 
+ConfigView.label.announceport=Ordeztu iragarritako TCP ataka aztarnari iragarletzatarako, pex eta dht\n[utzi hutsik: ez ezeztatu, 0: sarrera elkarketarik ez]
+ConfigView.label.noportannounce=Ez iragarri aztarnariari aditze ataka (honek ez dio eragiten hauei: pex, dht )
+ConfigView.label.maxseedspertorrent=Geh. emale torrent bakoitzeko [0: mugagabea] 
+wizard.webseed=Gehitu HTTP Emaleak torrentetik
+wizard.webseed.title=HTTP Emaleak
+wizard.webseed.configuration=HTTP Emale Itxurapena
+wizard.webseed.adding=HTTP Emaleak Gehitzen
+GeneralView.label.private=Torrent Pribatua
+GeneralView.yes=Bai
+GeneralView.no=Ez
+ConfigView.label.userequestlimiting=Erabili eskabide mugapena irakur atzerapenaren ordez jeisketa abiadura mugatzeko [ez du eraginik jeisketa abiadura mugagabea denean]
+ConfigView.label.userequestlimiting.tooltip=Eskabidea mugatzea ez da irakurketa atzerapena bezain lehuna, baina ahalbidetzen du jeisketa lehetasunerako ohinarrituz jeisketako lerro kokapean eta sarearen errendimendua hobetu dezake
+ConfigView.label.userequestlimitingpriorities=Finkatu jeisketa abiadura jeisketa lerroburuan jeisketa abiadura muga erdiesten denean
+ConfigView.section.logging.timestamp=Denbora irarketa heuskarria ohar agirientzat
+Peers.column.timetocomplete=Gelditzen den Denbora
+Peers.column.timetocomplete.info=Hartzailea osatuta dagoen arte gelditzen den denbora
+ConfigView.section.interface.display.suppress.file.download.dialog=Ezabatu Agiri Jeisketa jaulkohar elkarrizketa
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Erakutsi agiri guztien jeisketa garapena elkarrizketa leihoko egoera barran 
+FileDownload.canceled=Torrent agiriaren jeisketa ongi ezeztatu da erabiltzailearen ekintzaz: %1
+Progress.reporting.status.canceled=Ezeztaturik
+Progress.reporting.status.finished=Amaiturik
+Progress.reporting.status.retrying=Birsaiatzen...
+Progress.reporting.action.label.retry.tooltip=Birsaiatu eragiketa
+Progress.reporting.action.label.remove.tooltip=Ezabatu Garapen Ohar hau historiatik
+Progress.reporting.action.label.cancel.tooltip=Ezeztatu eragiketa
+Progress.reporting.action.label.detail=Xehetasunak
+Progress.reporting.default.error=Huts egin du
+Progress.reporting.no.reports.to.display=Une honetan ez dago garapen oharrik erakusteko
+Progress.reporting.no.history.to.display=Ez dago xehetasun mezurik erakusteko.
+Progress.reporting.detail.history.limit=Xehetasun mezu muga (%1) GarapenOhar honentzat gehiegizkoa da; ondorioz mezuak ez dira historiara gehituak izango
+Progress.reporting.statusbar.button.tooltip=Erakutsi Garapen Jakinarazpen Leihoa
+webui.bindip=Lotura IP-a - arrunt ez da beharrezkoa
+v3.MainWindow.text.log.in=Sartu
+v3.MainWindow.text.log.out=Irten
+v3.MainWindow.text.get.started=Izena Eman
+v3.MainWindow.text.my.account=Kontu Argibideak
+v3.MainWindow.text.my.profile=Profila
+OpenTorrentWindow.simple.open=Torren Helbidea (Agiria, URL-a, Hasha)
+Progress.reporting.window.remove.auto=Berez ezabatu jarduera gabeko gaiak 
+Progress.reporting.window.remove.auto.tooltip=Berez ezabatu osaturiko, huts eginiko, edo ezeztaturiko aurrerabideak ikuspenetik
+Progress.reporting.window.remove.now=Ezabatu jarduera gabeko gaiak
+Progress.reporting.window.remove.now.tooltip=Ezabatu osaturiko, huts eginiko, edo ezeztaturiko aurrerabide guztiak ikuspenetik
+dhttracker.tracklimitedwhenonline=Horrela ere, egin baliabide apalen aztarnapena online daudenean erletaldeko kidegurutzapenerako
+TorrentOptionsView.multi.title.short=Torrent Aukerak
+TorrentOptionsView.multi.title.full=Torrent Aukerak
+MyTorrentsView.menu.open_parent_folder=Ireki Edukiaren Agiritegia
+ConfigView.section.style.use_show_parent_folder=Erabili "%1" ordez "%2" torrent menuetan
+ConfigView.section.style.use_show_parent_folder.tooltip=Aukera hau gaitzeak ahalbidetzen dizu irekitzea eduki agiritegia agiri kudeatzaile egokian.\nHorrela ere, honek esanahi dezake jeisketaren gordetze helbidea ez dela berezgaitasunez hautatua.
+PeerManager.status.ps_disabled=Aztarnari hartzaile iturburua ezgaituta dago
+ConfigView.section.stats.exportfiles=Esportatu agiri xehetasuanak
+updater.cant.write.to.app.title=Ezin Da Idatzi Egokitzapen Agiritegira
+updater.cant.write.to.app.details=Agiritegia "%1" idaztezina da.\n\nHonek etorkizuneko software eguneratzeak ezartzea sahiestuko du.\n\nMesedez <a href="http://wiki.vuze.com/w/Failed_Update">ikusi wikia xehetasunetarako</a>.
+plugin.install.class_version_error=Plugin honek Javaren bertsio berriena behar du lan egiteko.
+v3.MainWindow.tab.minilibrary=Jeisketak
+v3.MainWindow.tab.events=Oharrak
+button.columnsetup.tooltip=Zutabe Ezarpena
+v3.activity.remove.title=Ezabatu Jakinarazpena
+v3.activity.remove.text=Zihur zaude Jakinarazpen hau ezabatzea nahi duzula?\n%1
+v3.MainWindow.menu.file.closewindow=Itxi
+Menu.show.torrent.menu=Erakutsi Torrenten menua
+Menu.show.torrent.menu.tooltip=Erakutsi Torrenten menua menubarraren gorenaldean
+Views.plugins.aznetstatus.title=Sare Egoera
+plugin.aznetstatus.pingtarget=Ping/zantzu bide xedea (Packet INternet Groper=INternetako Pakete Eskuztatzailea)
+ConfigView.section.style.usePathFinder=Erabili 'Helburu Bilatzailea' 'Bilatzailea'-ren ordez
+menu.sortByColumn=Antolatu %1 arabera
+MyTorrentsView.menu.manual.per_peer=Eskuz (hartzaileko)
+MyTorrentsView.menu.manual.shared_peers=Eskuz (hartzaileetatik)
+v3.button.removeActivityEntry=Kendu Jakinarazpena
+v3.splash.initSkin=UI Azala abiatzen
+v3.splash.hookPluginUI=Elkarketatzen IU Pluginean
+OpenTorrentWindow.mb.notTorrent.cannot.display=Ezgaitu datuak egoki erakusteko
+MainWindow.menu.window.zoom.maximize=Handitu
+MainWindow.menu.window.zoom.restore=Txikiagotu
+ImageResizer.image.too.small=Irudia txikiegia da, mesedez hautatu beste bat (gutxienez izan behar du %1 x %2)
+ImageResizer.title=Tresna honek zure iruditxikia Vuzeren Plataforman nola ikusiko den aurreikuspegi bat ematen dizu
+ImageResizer.move.image=Mugitu irudi arrastatuz
+ImageResizer.move.image.with.slider=Mugitu irudia arrastatuz, birneurriratu azpiko irristaria erabiliz
+security.crypto.title=Enkriptazio Giltza Sarbidea
+security.crypto.encrypt=Mesedez idatzi sar-hitz bat sortu berri duzun enkriptaketa giltza babesteko. Mesedez ez ahaztu sar-hitz hau, ez dago berreskuratzeko biderik egiten baduzu!
+security.crypto.decrypt=Mesedez idatzi sar-hitza zure enkriptaketa giltza irekitzeko.
+security.crypto.reason=Eragiketa arrazoia
+security.crypto.password=Sar-hitza
+security.crypto.password2=Sartu berriro sar-hitza
+security.crypto.persist_for=Sar-hitzaren iraupen epea
+security.crypto.persist_for.dont_save=Ez gorde
+security.crypto.persist_for.session=Saio hau
+security.crypto.persist_for.day=1 egun
+security.crypto.persist_for.week=1 aste
+security.crypto.persist_for.30days=30 egun
+security.crypto.persist_for.forever=Betirako
+security.crypto.password.mismatch.title=Sar-hitz Akatsa
+security.crypto.password.mismatch=Idatzitako sar-hitz balioak ezberdinak dira, mesedez sartu berriro.
+ConfigView.section.security.group.crypto=Publikoa/Pribatua Giltzak
+ConfigView.section.security.resetkey=Birrezarri giltzak
+ConfigView.section.security.resetkey.warning.title=Datu Galera Kontuz
+ConfigView.section.security.resetkey.warning=Zihur zaude zure enkriptaketa giltzak leheneratzea nahi dituzula? Egiten baduzu enkriptatutako argibide guztiak BETIRAKO GALDU daitezke. Baita ere, zure giltza publikoa duen edonor hartzaileek ezingo du jadanik zurekin harremandu zure giltza berria lortu arte. Hortaz, egitan zer egiten ari zaren jakin ezean, ezazu hori egin.
+ConfigView.section.security.unlockkey=Irekitze giltza bereziak
+ConfigView.section.security.unlockkey.button=Ireki
+ConfigView.section.security.publickey=Giltza Publikoa
+ConfigView.section.security.publickey.undef=Oraindikan zehaztu gabe
+ConfigView.section.security.resetkey.error.title=Eragiketak Huts egin du
+ConfigView.section.security.resetkey.error=Huts egin du giltzak birrezartzean
+ConfigView.section.security.unlockkey.error=Huts egin du giltza irekitzean - sar-hitz okerra
+ConfigView.copy.to.clipboard.tooltip=Kopiatu gakoan
+Views.plugins.azbuddy.title=Lagunak
+Browser.popup.error.no.access=Akats bat gertatu da hurruneko baliabide bat atzitzerakoan.\nMesedez saiatu zaitez geroago
+ConfigView.label.queue.stoponcebandwidthmet=Ez hasi beste torrentik igoera/jeisketa abiadura muga lortua dagoenen
+ConfigView.section.style.forceMozilla=Behartu Vuze Mozilla erabiltzera tresnak Bilatzeko [xulrunner edo firefox 3 beharrezkoa; birrabiaraztea beharrezkoa]
+ConfigView.section.style.xulRunnerPath=Adierazi  XulRunner / Firefox helburua eskuz [beharrezkoa FF3-rentzat; birrabiaraztea beharrezkoa]
+azbuddy.name=Lagunak
+azbuddy.enabled=Gaituta
+azbuddy.disabled=Plugina ezgaiturik dago, ikusi plugin itxurapenak aldatzeko.
+azbuddy.nickname=Zure Izenordekoa
+azbuddy.msglog.title=Lagun argibideak
+azbuddy.addtorrent.title=Jeisketa Onartu?
+azbuddy.addtorrent.msg=Laguna '%1' bidali dizu '%2'.\nJeisketa hau gehitzea nahi duzu?
+azbuddy.contextmenu=Bidali Lagun Bati
+azbuddy.ui.mykey=Nire giltza:
+azbuddy.ui.add=Gehitu
+azbuddy.ui.new_buddy=Lagun berriaren giltza:
+azbuddy.ui.table.name=Izena
+azbuddy.ui.table.last_msg=Azken Mezua
+azbuddy.ui.menu.remove=Ezabatu
+azbuddy.ui.menu.copypk=Kopiatu Giltza Publikoa
+azbuddy.ui.menu.send=Bidali Mezua
+azbuddy.ui.menu.send_msg=Sartu zure lagunari bidaltzeko idazkia
+azbuddy.ui.menu.ping=Ping (INT. Pak. Eskuzt.)
+azbuddy.ui.menu.ygm=Bidali YGM
+azbuddy.ui.menu.enc=Enkriptautu Gakoa
+azbuddy.ui.menu.dec=Dekriptatu Gakoa
+azbuddy.ui.menu.sign=Izenpetu Gakoa
+azbuddy.ui.menu.verify=Egiaztatu Gakoa
+azbuddy.ui.table.lastseen=Azkenaldiz Ikusia
+Button.retry=&Birsaiatu
+Button.ignore=&Ezikusi
+DHTView.general.skew=Bihurria:
+azbuddy.ui.table.msg_in=Msg Sarrera
+azbuddy.ui.table.msg_out=Msg Irteera
+v3.MainWindow.menu.view.footer=Orrialde ohina
+azbuddy.downspeed=KB/s geh. lagunen jeisketa abiadura [0: mugagabea]
+azbuddy.ui.table.con=CON
+security.crypto.badpw=Emandako sar-hitza ez da zuzena
+ConfigView.section.security.backupkeys=Babeskopia giltza agiri bati
+ConfigView.section.security.backupkeys.button=Babeskopia
+ConfigView.section.security.restorekeys=Leheneratu giltzak agiri batetik
+ConfigView.section.security.restorekeys.button=Leheneratu
+ConfigView.section.security.op.error.title=Eragiketak Huts egin du
+ConfigView.section.security.op.error=Huts egin du eragiketa osatzean:\n    %1
+ConfigView.section.security.restart.title=Birrabiarazpena Beharrezkoa
+ConfigView.section.security.restart.msg=Vuze orain birrabiarazi daiteke eragiketa osatzeko
+ConfigView.section.security.system.managed=Erabide kudeaketa giltza babesa
+azbuddy.ui.table.msg_queued=Lerrokaturik
+azbuddy.ui.menu.chat=Eztabaidagunea
+azbuddy.chat.title=Vuze Eztabaidagunea
+azbuddy.chat.says=%1-ek dio:
+Button.bar.show=Erakutsi
+Button.bar.hide=Ezkutatu
+Button.bar.share=Partekatu
+Button.bar.add=Gehitu
+Button.bar.edit=Editatu
+Button.bar.edit.cancel=Editatzen
+v3.MainWindow.menu.view.pluginbar=Plugin Barra
+MainWindow.dialog.select.vuze.file=Hautatu Vuze Agiria
+MainWindow.menu.file.open.vuze=Vuze Agiria...
+metasearch.addtemplate.title=Ezarri Eredua Bilatu?
+metasearch.addtemplate.desc=Zihur zaude '%1' izena duen bilaketa eredua ezartzea nahi duzula?
+v3.share.private.title=Torrenta Elkarbanatzen
+v3.share.private.text=Hautatutako torrenta Torrent Pribatu bezala markaturik dago\n\nEzin duzu torrent pribaturik partekatu.
+metasearch.addtemplate.dup.title=Bikoiztu Eredua
+metasearch.addtemplate.dup.desc=%1 Bilatu eredua jadanik ezarrita dago
+metasearch.export.select.template.file=Gorde Eredua
+metasearch.import.select.template.file=Ireki Eredua
+dialog.uiswitch.title=Vuze EI-ra aldatu
+dialog.uiswitch.text=Vuze EI abiaturik egon behar da eginkizun hau erabiltzeko.\n\nVuzek birrabiarazpena behar izango du.
+dialog.uiswitch.button=Vuze Erabiltzaile Interfazera aldatu
+azbuddy.tracker.enabled=Gaitu 'Lagun Kitzikapena' zure lagunekin jeisketak lehenesteko
+azbuddy.protocolspeed=KB/s geh. lagun harremanaren burugain
+v3.MainWindow.button.download=Jeitsi
+v3.MainWindow.button.run=Jaulki Jeitsitako Agiria
+v3.activity.header.downloads=Jeisketak
+v3.activity.header.vuze.news=Vuze Berriak
+message.taking.too.long=Badirudi uste baino denbora gehiago hartzen ari dela\nSakatu 'ESC' eragiketa hau ezeztatzea nahi baduzu
+message.status.success=Gertaerak
+azbuddy.tracker.bbb.status.title=Lagun Kitzikapena
+azbuddy.tracker.bbb.status.title.tooltip=Klik bikoitza xehetasunak ikusteko
+azbuddy.tracker.bbb.status.idle=Kitzikapen gabe
+azbuddy.tracker.bbb.status.nli=Saioa Hastea Beharrezkoa da.
+azbuddy.tracker.bbb.status.in=Kitzikatua Izan naiz
+azbuddy.tracker.bbb.status.out=Oraingo Lagun Kitzikapena
+v3.MainWindow.search.go.tooltip=Exekutatu Bilaketa
+v3.MainWindow.search.last.tooltip=Itzuli bilaketa emaitzetara
+metasearch.addtemplate.done.title=Eredua Gehituta
+metasearch.addtemplate.done.desc='%1' eredua ongi gehitu da.\nHurrengo bilaketan erabili dezakezu!
+ConfigView.section.security.nopw=Sar-hitzik gabe jarrita
+ConfigView.section.security.nopw_v=Sar-hitzik gabe eskuragarri, mesedez izena eman Vuzen
+fileplugininstall.install.title=Plugina Ezarri?
+fileplugininstall.install.desc=Zihur zaude '%1' pluginaren, %2 bertsioa ezarri nahi duzula?
+fileplugininstall.duplicate.title=Bikoiztu Plugina
+fileplugininstall.duplicate.desc='%1' Pluginaren, %2 bertsioa ezarrita dago
+azbuddy.online_status=Online Egoera
+azbuddy.os_away=Batbatekoa
+azbuddy.os_not_avail=Eskuraezina
+azbuddy.os_busy=Lanpetuta
+azbuddy.os_offline=Lineaz-kanpo
+azbuddy.ui.menu.disconnect=Etenda
+azbuddy.enable_chat_notif=Gaitu eztabaidagune oharrak
+progress.window.msg.progress=Mesedez itxaron eragiketa burutzen den bitartean
+ConfigView.section.connection.advanced.read_select=Irakurri hautatutako itxaronaldia (milaen, berez %1)
+ConfigView.section.connection.advanced.read_select_min=Irakurri hautatutako gutxieneko itxaronaldia (milaen, berez %1)
+ConfigView.section.connection.advanced.write_select=Idatzi hautatutako itxaron denbora (milaenak, berez %1)
+ConfigView.section.connection.advanced.write_select_min=Idatzi hautatutako gutxieneko itxaronaldia (milaenak, berez %1)
+DetailedListView.title=Zerrenda Zehatza
+ConfigView.section.connection.network.max.outstanding.connect.attempts=Geh. egitekeko irteera elkarketa
+plugins.init.force_enabled=Vuzek "%1" plugina ezgaiturik dagoela atzeman du - birgaitua izan da Vuzeri zuzen lan egitea ahalbidetzeko.
+ConfigView.section.connection.prefer.udp=UDP elkarkata lehenetsiak
+subscript.add.title=Ezarri Harpidetza?
+subscript.add.desc=Zihur zaude '%1' harpidetza ezartzea nahi duzula?
+subscript.add.dup.title=Bikoiztu Harpidetza
+subscript.add.dup.desc='%1' Harpidetza jadanik ezarrita dago.
+subscript.add.upgrade.title=Harpidetza Berritu?
+subscript.add.upgrade.desc=Zihur zaude '%1' harpidetza berritu nahi duzula?
+subscript.add.upgradeto.desc='%2' harpidetzaren %1 Bertsioa eskuragarri dago.\nEguneratzea nahi duzu?
+azsubs.contextmenu.addassoc=Gehitu harpidetza elkarketa
+azsubs.contextmenu.lookupassoc=Bilatu harpidetza elkarketak
+iconBar.start=Hasi
+iconBar.stop=Gelditu
+iconBar.remove=Ezabatu
+iconBar.up=Igo
+iconBar.down=Behera
+iconBar.run=Zabaldu
+iconBar.editcolumns=Zutabe Ezarpena
+iconBar.top=Goren
+iconBar.bottom=Beheren
+iconBar.queue=Hasi
+iconBar.open=Gehitu Torrenta
+iconBar.share=Partekatu
+iconBar.share.tooltip=Elkarbanatze Edukia
+iconBar.details=Xehetasunak
+iconBar.comment=Aipamena
+iconBar.play=Irakurri
+iconBar.queue.tooltip=Hasi (lerroan) hautaturiko torrentak
+v3.MainWindow.menu.view.sidebar=Alboko Barra
+v3.MainWindow.menu.view.actionbar=Eragiketa Barra
+v3.MainWindow.menu.view.toolbars=Tresna Barrak
+ump.install=Eguneratze Azkarra Egiten:\nBideo honentzat beharrezkoa den irakur gehigarri txiki bat ezartzen.
+subscriptions.listwindow.title=Harpidetza Bilatzailea
+subscriptions.listwindow.autochecktext=Vuzek zure liburutegiko edukiekin lotura duten harpidetzak bilatu ditzake. Nahi duzu eginkizun hau gaitzea?
+subscriptions.listwindow.loadingtext=Antzeko harpidetzak bilatzen  %1
+subscriptions.listwindow.failed=Ez da harpidetzarik Aurkitu
+subscriptions.listwindow.popularity=Ezaguntasuna
+subscriptions.listwindow.popularity.unknown=Ezezaguna
+subscriptions.listwindow.name=Izena
+subscriptions.listwindow.subscribe=Harpidetu
+TableColumn.header.azsubs.ui.column.subs=Harpidetu
+subscriptions.listwindow.popularity.reading=Irakurtzen
+PluginDeprecation.log.start=Leiho honek Vuzeren hurrengo bertsioetan ezabatuak izan daitezkeen pluginei buruzko argibideak ditu.\nEz duzu pluginak kendu beharrik, azken bertsiora eguneratu ditzakezu.\nAzken bertsioarekin ari bazara lanean, mesedez kopiatu leiho honetako edukiak eta argitara itzazu eztabaidagune honetan:\n \t%1\n\n
+PluginDeprecation.view=Plugin Garbiketa
+PluginDeprecation.alert=Plugin bat saitutu da etorkizunean kenduko den egokitzapen bat erabilitzen. - mesedez ireki Plugin Garbiketa argibide gehieago ikusteko.
+TableColumn.header.Thumbnail=Ikonoa
+TableColumn.header.Thumbnail.info=Vuzeren edukientzako iruditxikia; beste eduki guztientzakoak sistema eragileak ematen ditu ikonoak hauek.
+v3.MainWindow.menu.getting_started=&Lehen Urratsak
+MainWindow.menu.community=&Herkidegoa
+MainWindow.menu.community.wiki=Herkidegoa &Wikia && FAQ
+MainWindow.menu.community.forums=Herkidego Ezta&baidaguneak
+MainWindow.menu.community.blog=Vuze &Bloga
+MainWindow.menu.help.support=&Laguntza eta Sostengua
+externalLogin.title=Izenematea Beharrezkoa
+externalLogin.explanation="%1" ereduak izenemanda egotea eskatzen du>. Egindakoan leiho hau berezgaitasunez itxiko da. Egiten ez badu mesedez klikatu "eginda".
+externalLogin.explanation.capture=Izena eman behar duzu eredu hau sortzeko. Egindakoan, mesedez klikatu "Eginda".
+Button.done=Eginda
+GeneralView.torrent_created_on_and_by=%1 %2-tik
+Button.continue=Jarraitu
+Button.preview=Aurreikuspena
+Subscription.menu.forcecheck=Eguneratu Orain
+Subscription.menu.clearall=Markatu Emaitza Guztiak Irakurrita Bezala
+Subscription.menu.remove=Ezabatu
+sidebar.Library=Liburutegia
+sidebar.LibraryDL=Jeisten...
+sidebar.LibraryCD=Osatuta
+MySeeders.bigView.header=CDLiburtegia
+MyTorrents.bigView.header=Liburutegia
+authenticator.location=Helbidea
+authenticator.details=Xehetasunak
+v3.MainWindow.menu.showActionBarText=Erakutsi Izena
+subscript.import.fail.title=Inportatzeak Huts egin du
+subscript.import.fail.desc=Xehetasunak: %1
+Subscription.menu.export=Esportatu...
+subscript.export.select.template.file=Gorde Harpidetza
+Button.remove=Ezabatu
+Button.send=Bidali
+Button.back=Atzera
+sidebar.LibraryUnopened=Berria
+TableColumn.header.unopened=Berria
+Unopened.bigView.header=Berria
+Subscription.menu.deleteall=Ezabatu Emaitza Denak
+Subscription.menu.reset=Birrezarri Hasierako Egoera
+ConfigView.section.Subscriptions=Harpidetzak
+subscriptions.config.maxresults=Harpidetza bakoitzeko atxirikiriko emaitz zenbateko gehiena [0: mugagabea]
+v3.activity.button.readall=Markatu Irakurritako Denak 
+TableColumn.header.activityNew=Berria
+TableColumn.header.activityType=Mota
+TableColumn.header.activityText=Mezua
+TableColumn.header.activityDate=Gehitze Eguna
+TableColumn.header.activityActions=Eragiketak
+Subscription.menu.resetauth=Birrezarri Egiaztapen Xehetasunak
+Search.menu.engines=Ereduak
+Wizard.Subscription.title=Harpidetu
+Wizard.Subscription.optin.title=Gaitu Harpidetzak
+Wizard.Subscription.subscribe.title=Harpidetza Eskuragarriak
+Wizard.Subscription.create.title=Sortu Harpidetza Berria
+Button.search=Bilatu
+Button.save=Gorde
+Button.add=Gehitu
+Button.createNewSubscription=Sortu Harpidetza Berri Bat
+Button.availableSubscriptions=Harpidetza Eskuragarria
+Wizard.Subscription.optin.description=Harpidetzak gaitutakoan, Vuzek zure liburutegiko edukien antzeko harpidetzak erakutsiko ditu, eta  jakinaraziko dizu harpideturiko edukiak jeisteko gertu daudenean..\n\nZure harpidetzak gaitzea nahi duzu?
+Wizard.Subscription.create.search=Bilatu
+Wizard.Subscription.search.subtitle1=Idatzi bilaketa bat zure harpidetza sortzen hasteko:
+Wizard.Subscription.search.subtitle2=Zer bilatu dezaket?
+Wizard.Subscription.search.subtitle2.sub1=HD Filmak, TB Ikuskizunak, Filmak, Vuze Sareko Trailerrak
+Wizard.Subscription.search.subtitle2.sub2=Webguneetako torrentak
+Wizard.Subscription.search.subtitle3=Zure harpidetza behin buruturik dagoenean, zuzeneko eguneratzeak jaso ditzakezu zure albobarran emaitza berriak zure bilaketarako eskuragarri dauden bakoitzean.
+Wizard.Subscription.rss.subtitle1=Idatzi edo itsasi URL-a ondoren:
+Wizard.Subscription.rss.subtitle2=Argitaratzaile zenbaitzuk RSS jarioak eskaintzen dituzte beren edukientzat.  Helbiditu  URL-a argitaratzailearen webgunean, kopiatu eta itsati URL-a gaineko eremuan, orduan klikatu Gorde.
+Wizard.Subscription.rss.subtitle3=Behin gordeta, zuzeneko harpidetzak jasoko dituzu zure albobarran zure RSS jarioen bidez emaitza berriak eskuragarri dauden bakoitzean
+Wizard.Subscription.subscribe.library=Zure Liburutegian dago
+Wizard.Subscription.subscribe.subscriptions=Antzeko Harpidetzak
+Wizard.Subscription.subscribe.library.empty=Ez dago harpidetza eskuragarririk?\n \nBilatu margo laranja dizdiratsuko harpidetza botoia Vuze HD Sarean.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Harpidetzak">Irakurri gehieago</A>
+message.confirm.delete.title=Baieztatu Ezabaketa
+message.confirm.delete.text=Zihur zaude '%1' ezabatzea nahi duzula?
+Subscription.menu.properties=Ezaugarriak...
+props.window.title='%1' -en Ezaugarriak
+subs.prop.enabled=Gaituta
+subs.prop.is_auto=Berez-jeistsi emaitza berriak
+subs.prop.last_scan=Eginiko azken eguneraketa
+subs.prop.last_result=Aurkituriko azken emaitz berriak
+subs.prop.last_error=Azken akatsa
+subs.prop.num_read=Irakurritako emaitz zenbatekoa
+subs.prop.num_unread=Irakurrigabeko emaitz zenbatekoa
+subs.prop.template=Eredua
+subs.prop.auth=Egiaztapena beharrezkoa
+externalLogin.auth_method_proxy=Erabili cookie atzipenbide hedatua. Hutsegiten badu, ezgaitu aukera eta saiatu berriro.
+externalLogin.wait=Orrialdea gertatzen, mesedez itxaron...
+TableColumn.menu.date_added.time=Erakutsi/Ezkutatu Denbora
+MyLibrary.bigView.header=Liburutegia
+sidebar.VuzeHDNetwork=Vuze HD Sarea
+subs.prop.next_scan=Hurrengo mihaketaren epemuga
+subs.prop.assoc=Elkartasunak
+subs.prop.version=Bertsioa
+subscriptions.column.new.info=Adierazi emaitza berri bat edo gehiago badaude
+subscriptions.column.name=Harpidetza
+subscriptions.column.nb-results=Emaitza Denak
+subscriptions.column.nb-new-results=Emaitza Berriak
+subscriptions.column.last-checked=Azken Egiaztapena
+subscriptions.view.title=Harpidetzak
+subs.prop.is_public=Publikoa
+subs.prop.high_version=Aurkitutako bertsio handiena
+Subscription.menu.upgrade=Gaitu Bertsio Handienera Eguneratzea
+metasearch.template.version.bad='%1' Bilaketa eredua ezin da ezarri Vuze eguneratu arte 
+metasearch.addtemplate.failed.title=Ezarpenak Huts egin du
+metasearch.addtemplate.failed.desc=Huts egin du eredua ezartzerakoan: %1
+subscription.version.bad='%1' Harpidetza ezin da ezarri Vuze eguneratu arte
+statusbar.feedback=Bidali Iruzkina
+statusbar.feedback.tooltip=Klikatu hemen iruzkinak bidaltzeko
+sidebar.Activity=Oharrak
+v3.activity.button.watchall=Markatu Ikusitako Denak
+subscriptions.view.help.1=Gehitu Harpidetzak ikusten dituzun bakoitzean
+subscriptions.view.help.2=Eskuratu dohainik zuzeneko eguneraketak jeisteko eduki berriak eskuragarri dauden bakoitzean.  <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Learn More</A>.
+sidebar.sash.tooltip=F7 albobarra ezkutatu/erakutsi azkarrerako
+sidebar.expand.tooltip=Handitu Albokobarra
+sidebar.dropdown.tooltip=Erakutsi albokobarra menu heuskarrian
+subscript.all.subscribed=Eduki honetara harpideturik zaude
+subscript.some.subscribed=Eduki hau duten harpidetza batzuk dituzu\nKlikatu eskuragarri dauden beste batzuk ikusteko
+subscript.none.subscribed=Egin klik torrenta honentzata eskuragarri dauden harpidetzak ikusteko
+v3.iconBar.up=Gora
+v3.iconBar.up.tooltip=Mugitu gora\nEduki saguaren botoia sakatuta gorainok mugitzeko
+v3.iconBar.down=Behera
+v3.iconBar.down.tooltip=Mugitu Behera\nEduki saguaren botoia sakatuta beherainok mugitzeko
+TableColumn.header.azsubs.ui.column.subs_link=Elkartasuna
+TableColumn.header.azsubs.ui.column.subs_link.info=Harpideekin elkartuta
+Button.deleteContent.fromLibrary=Ezabatu Liburutegitik
+Button.deleteContent.fromComputer=Ezabatu Ordenagailutik
+v3.deleteContent.message=\nEzabatzea nahi duzu '%1' zure ordenagailutik, edo zure Vuze Liburutegitik kentzea besterik ez?
+v3.MainWindow.menu.view.toolbartext=Tresnabarra Izena
+v3.MainWindow.menu.view.asSimpleList=Zerrenda Arrunta
+v3.MainWindow.menu.view.asAdvancedList=Zerrenda Aurreratua
+v3.MainWindow.menu.view.statusbar=Egoera Barra
+Subscription.menu.dirtyall=Markatu Emaitza Denak Ez Irakurrita Bezala
+configureWizard.file.message3=Vuze agiriak adieraziriko agiritegira jeitsi ditzake, agiritegi hori hemen hautatu dezakezu:
+v3.deleteContent.applyToAll=Ezarri eragiketa %1 hautaturiko sarrera guztiei.
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=Ezer igo ez duten torrentak
+v3.MainWindow.menu.contentnetworks=HD &Sareak
+v3.MainWindow.menu.contentnetworks.about=HD Sareei Buruz
+Peers.column.as.info=Hartzailearen AS (Sistema Autonomoa) xehetasunak
+ConfigView.label.autoopen.downloadbars=Berez ireki Jeisketa Barrak
+ConfigView.label.autoopen=Berez Irekitzea
+ConfigView.label.autoopen.detailstab=Berez ireki Xehetasun Fitxa
+ConfigView.label.autoopen.dl=Jeisten
+ConfigView.label.autoopen.cd=Emaletzan
+ConfigView.label.systray=Erabide Erretilua
+ConfigView.label.systray._mac=Egoera Barra Ikonoa
+ConfigView.section.interface.legacy=Ondasuna
+v3.MainWindow.menu.contentnetworks.manage=&Kudeatu HD Sareak
+azbuddy.ui.table.loc_cat=Cats irteera
+azbuddy.ui.table.rem_cat=Cats sarrera
+azbuddy.ui.menu.cat=Kategoriak
+azbuddy.ui.menu.cat.share=Gaitu lagunekiko harpidetza
+azbuddy.ui.menu.cat.set=Sartu kategoria
+azbuddy.ui.menu.cat.set_msg=Kategoria zerrenda kakotxaz banandurik, edo 'Denak'
+azbuddy.ui.menu.cat_subs=Harpidetu
+subs.prop.update_period=Eguneratze epea
+azbuddy.enable_cat_pub=Kategoria publikoak dira zure lagunak izeneman daitezkeen GUZTIAK  (',' banandurik) 
+azbuddy.ui.table.read_cat=Cat irakurria
+TableColumn.header.#=Zenb.
+TableColumn.header.#.info=Kokapena/Antolaketa Zenbakia
+TableColumn.header.category.info=Torrentari dagokion kategoria izena
+TableColumn.header.DateCompleted.info=Torrentaren jeisketa burutu zen eguna
+TableColumn.header.AzProduct.info=Torrentaren Sare edukia hemendik sortua
+TableColumn.header.health.info=Zure elkarketak torrenteen erlataldeko elkarketan duen osasuna
+TableColumn.header.maxuploads.info=Gehienez # hartzaile aldibereko igoeran
+TableColumn.header.name.info=Torrentaren izena
+TableColumn.header.unopened.info=Torrenta joa izan den adierazteko ikurra (irekita)
+TableColumn.header.savepath.info=Torrenteen datuentzako helbide agiritegia edo agiria
+TableColumn.header.SeedingRank.info=Torrentak zein gaizkiro behar duen emaletzea adierazten duen balio maila. Balio handiagoak behar handiagoa esan nahi du.
+TableColumn.header.shareRatio.info=Zenbat igo duzun (elkarbanatu) jeitsi duzunarekin alderaturik.
+TableColumn.header.size.info=Diskako torrenteen edukien neurria
+TableColumn.header.azsubs.ui.column.subs.info=Antzeko torrentak dituzten jarioetara harpidetzea ahalbidetzen dizun botoia
+TableColumn.header.upspeed.info=Oraingo igoera abiadura
+TableColumn.header.downspeed.info=Oraingo jeisketa abiadura
+TableColumn.header.up.info=Orain beste erabiltzaileei bidalitako datu zenbatekoa
+TableColumn.header.down.info=Beste erabiltzaieengandik orain jasotzen ari zaren datu zenbatekoa
+TableColumn.header.ProgressETA.info=Egoera, Osaketa, ETA, eta Jeisketa Abiadura zutabeak lerro-anitzeko zutabe batean batzen ditu.
+TableColumn.header.eta.info=Torrenta jeitsi arteko ustezko denbora
+Pieces.column.#=Zenb.
+Pieces.column.#.info=Atal  Zenbakia
+Peers.column.%.info=Orain arte jeitsi duzu hartzaile torrentaren ehunekoa
+TableColumn.header.download.info=Hartzailearengandik jasotzen ari zaren datuen zenbatekoa
+TableColumn.header.upload.info=Hartzaileei bidali diegun datu zenbatekoa
+TableColumn.header.downloadspeed.info=Hartzailearengandik jasotzen ari zaren abiaduraren neurria
+TableColumn.header.uploadspeed.info=Hartzaieei datuak bidaltzeko erabiltzen ari garen abiadura
+TableColumn.header.lan.info=Hartzailea zure LAN-ean dagoen adierazten duen ikurra
+TableColumn.header.downloadspeedoverall.info=Hartzailearen ustezko jeisketa neurria
+Peers.column.pieces.info=Hartzailearengandik jeitsi dituzun atalak adierazten dituen grafika barra
+TableColumn.header.TableColumnNameInfo=Zutabe Izena eta Azalpena
+TableColumn.header.TableColumnSample=Lagina
+TableColumn.header.TableColumnInfo=Zutabe Azalpena
+TableColumn.header.TableColumnChosenColumn=Hautatu Zutabea
+subs.prop.is_auto_ok=Berez-jeisketa baimenduta
+label.learnmore=Jakin Gehiago
+ColumnSetup.title=Zutabe Ezarpena '%1'
+ColumnSetup.explain=Esploratu ezkerreko zutabeak, eta gehitu eskuinko zutabe zerrenda ikusgarrira. Handiagotu edo txikiagotu zutabe eskuragarriak ezkerreko botoiko Iragazkia erabiliz. Arrastatu eta Askatu eta teklatu lasterbideak ere onartzen dira.
+ColumnSetup.chosencolumns=Zutabe Hautatuak
+ColumnSetup.proficiency=Ontasuna:
+ColumnSetup.categories=Kategoriak:
+ColumnSetup.filters=Iragazkiak
+ColumnSetup.availcolumns=Eskuragarri  %1 zutabe
+ColumnSetup.availcolumns.filteredby=Eskuragarri %1 zutabe iragazita %2
+devices.view.title=Gailuak
+device.renderer.view.title=Egileak
+device.mediaserver.view.title=Media Zerbitzariak
+device.router.view.title=Routerrak
+device.model.desc=Eredu azalpena
+device.model.name=Eredu izena
+device.model.num=Eredu zenbakia
+device.manu.desc=Egilea
+device.router.is_mapping=Berezgaitasunezko ataka mapaketa
+device.router.req_map=Mapaketa beharrezkoa
+device.router.configure=Itxuratu UPnP-a
+device.mediaserver.configure=Itxuratu Nire Media Zerbitzaria
+device.hide=Ezkutatu Gailua
+device.show=Erakutsi Ezkutatu Gailuak
+device.search=Bilatu Gailuak
+device.router.con_type=Elkarketa: %1
+device.browse=Bilatu
+device.upnp.desc_url=Gailuaren Azalpena
+device.upnp.present_url=Gailu Administrazioa
+ConfigView.label.maxStalledSeeding=Gehienez 'hesituta' [0:mugagabea]
+ConfigView.section.Devices=Izenburua
+device.search.auto=Berezgaitasunez bilatu gailuak
+devices.sidebar.simple=Ikuspegi Arrunta
+devices.xcode.working_dir=Transkodeaketa eremua
+devices.xcode.prof_def=Berezko transkodeaketa profila
+devices.xcode.profs=Transkodeaketa profilak eskuragarri
+device.lastseen=Azken ikusialdia
+devices.contextmenu.xcode=Gailuarentzako Transkodeaketa
+devices.device=Gailua
+devices.profile=Profila
+General.percent=Ehuneko
+devices.installed=Ezarrita
+devices.comp.missing=Vuze sostengua ezarri gabe dago
+devices.state=Egoera
+MainWindow.menu.help.donate=&Eman Dirulaguntza bat
+DonationWindow.noload.title=Egin Diru ekarpen bat
+DonationWindow.noload.text=Dirulaguntza leihoak huts egin du. Mesedez saiatu zaitez geroago.
+devices.xcode.only.show=Erakutsi Bakarrik Transkodeatutako Agiriak Gailuan
+device.quit.transcoding.title=Transkodeaketa garatzen
+device.quit.transcoding.text='%1' da uneko transkodeatzeilea '%2' eta da  %3% osatuta.\nOrain kentzen baduzu beharrezkoa izango da birrabiaraztea hurrengo saio hasieraren abiaratzean.
+download.removerules.unauthorised.data=\tEzabatu datuak
+device.config.xcode.maxbps=Geh KB/seg transkodeaketa neurria [0: mugagabea]
+device.xcode=Transkodeaketa
+device.xcode.always=Betik
+device.xcode.whenreq=Beharrezkoa denean
+device.xcode.never=Inoiz
+devices.copy.pending=Agiri kopia egiteke
+devices.sidebar.hide.rend.generic=Ezkutatu gailu generikoak
+v3.devicesview.infobar.text2=Eduki bat gailu batera transkodeatzeko, arrastatu edukia zure liburutegitik albobarrako gailura. Transkodeaketa osatuak ikusteko, klikatu banako gailuan eskuinean.
+iconBar.transcode=Gailua
+iconBar.transcode.tooltip=Egin gailurako baliagarri
+device.retry.copy=Birsaiatu Kopiatzen
+devices.copy.fail=Gailura kopiatzeak huts egin du
+devices.on.demand=Eskabidean
+devices.ready=Hasi
+TableColumn.header.trancode_qpos=Zenb.
+TableColumn.header.trancode_qpos.info=Kokapena Transkodeaketa Lerroan
+TableColumn.header.profile=Gailua
+TableColumn.header.profile.info=Erabilitako transkodeaketa profila
+TableColumn.header.copied=Kopiaturik
+TableColumn.header.device=Gailua
+TableColumn.header.device.info=Xede Gailua
+TableColumn.header.trancode_completion=Bihurketaren Garapena
+TableColumn.header.transcode_name=Izena
+TableColumn.header.transcode_status=Egoera
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=Iku
+v3.iconBar.view.big.tooltip=Ikusi Zerrenda Arrunt bezala
+# This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=si
+v3.iconBar.view.small.tooltip=Ikusi Zerrenda Aurreratu bezala
+general.dont.ask.again=Ez galdetu berriro
+general.na.short=E/G
+v3.menu.device.exploreTranscodes=Erakutsi Agiriak
+v3.menu.device.exploreTranscodes._windows=Erakutsi Agiriak Explorer-ean
+v3.menu.device.exploreTranscodes._mac=Erakutsi Agiriak Finder-ean
+v3.menu.device.defaultprofile=Berezko Profila
+devices.button.installitunes=Ezarri iTunes Baterapena
+device.itunes.install=iTunes ezartzeko behar duzu
+device.itunes.start=iTunes abiatzea edo berez-abiatzea behar duzu
+device.itunes.install_problem=Badirudi arazo bat dagoela iTunes bateragarritasunarekin
+devices.downloading=Jeisten
+TableColumn.header.duration=Iraupena
+TableColumn.header.resolution=Bereizmena
+devices.xcode.autoStart=Berezgaitasunez Hazi Beharrezkoa Denean
+option.askeverytime=Galdetu Betik
+option.rememberthis=Gogoratu ezarpen hau
+devices.associate=Honekin elkartuta
+devices.associate.already=Jadanik elkartuta
+devices.always.cache=Transkodeatugabeko Agirientzako Katxea
+devices.turnon.prepageload=Eginkizun hau abiatzeko, osagai gehigarri baten ezarpena beharrezkoa da.
+devices.turnon.itunes=iTunes-entzako sostegua barne (beharrezkoa Apple gailuentzat)
+devices.turnon.qos=Partekatu izengabeko gailu estatistikak Vuzekin
+devices.turnon.title=Piztu Gailu Sostengua
+devices.choose.device.title=Hautatu irakurgailu bat bideo honentzat:
+devices.choose.profile.title=Izenburua
+devices.choose.profile.info.text=Zure hautaketaren ondoren, Vuzek atzemango du bideo heuskarria hautaturiko irakurgailuan ikusi ahal den, eta gailu-bateragarri kopia bat sortu beharrezkoa bada.\n\nJarri hautatutako gailuaren gainean xehetasun gehiago ikusteko.
+devices.choose.profile.info.title.selected=%1 xehetasunak:
+devices.view.heading=Media bihurgailua irakurgailuarentzat
+device.view.heading=Media   %1
+devices.choose.device.info.title=Gailu Mota
+devices.choose.device.info.text=Hurrengoan, agiriak arrastatu eta askatu arrunt bat gailura edo hautatu itzazu Albobarran.
+label.clickone=Klikatu bat
+Button.turnon=Piztu
+ConfigView.section.interface.password=Sar-hitza
+ConfigView.label.dm.dblclick=Klik bikoitza torrenten ikuspegietan:
+ConfigView.option.dm.dblclick.play=Irakurri Edukia
+ConfigView.option.dm.dblclick.details=Ireki Torrent Xehetasun Ikuspegia
+ConfigView.option.dm.dblclick.show=Erakutsi Agiria
+ConfigView.option.dm.dblclick.show._mac=Erakutsi Agiria(k) Finder-en
+ConfigView.option.dm.dblclick.show._windows=Erakutsi Agiria(k) Explorerren
+subscriptions.column.auto-download=Berez Jeisketa
+xcode.deletedata.title=Ezabatu Transkodeaketa Edukia
+xcode.deletedata.message=Zihur zaude behinbetirako ezabatu nahi duzula '%1' transkodeaketa kopia '%2'%3?
+xcode.deletedata.message.2=\n(hemen kopia bat egon daiteke oraindik '%1')
+v3.deviceview.infobar.line1=Arrastatu eta askatu bideoak zure Liburtegitik hautatzen duzun gailura.
+v3.deviceview.infobar.line2=Ikusi zure bideoak zure pantailetako edozeinetan - iPad, iPhone, iPod, TB
+v3.deviceview.infobar.line1.generic=Arrastatu eta askatu bideoak zure Liburutegitik %1 zure Albobarrara.
+v3.deviceview.infobar.line2.itunes=Bideoak zure iTunes Filmak agiritegian agertuko dira ikusteko gertu daudenean.
+v3.deviceview.infobar.line2.xbox=Bideo jarioak zure  Xbox 360-ra joanez eta hautatuz Nire XBox -> Bideo Liburutegia -> Vuze.
+v3.deviceview.infobar.line2.ps3=Bideo jarioak zure PS3-ra joanez eta hautatuz Bideoak -> Vuze.
+devices.copy_url=Kopiatu Jario URL-a Gakora
+devices.converting=Bihurtzen
+Button.reload=Birgertatu
+devices.auto.start=Berez-abiatzea
+Subscription.menu.setcookies=Ezarri Cookiak
+general.enter.cookies=Sartu Cookiak
+device.config.xcode.workdir=Berezko lan zuzenbidea transkodeatutako agirientzat
+MyTorrentsView.menu.clear_alloc_data=Garbitu Izendapen Egoera
+DiskManager.error.nospace=Diskako tokia ez da nahikoa
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - egiaztatu {wiki.fat32}
+wiki.fat32=http://wiki.vuze.com/w/FAT32_agir_neurri_muga
+ConfigView.section.file.rename.incomplete=Gehitu aurrehizkia osatugabeko agiriei
+subscriptions.config.auto=Berez-jeisketa
+subscriptions.config.autostartdls=Berezgaitasunez hasi jeisketak gehitutakoan (geldituta egoeran jartzearen alderantzizkoa da)
+subscriptions.config.autostart.min=Hasi bakarrik bada >= MB [0: mugagabea]
+subscriptions.config.autostart.max=Hasi bakarrik bada <= MB [0: mugagabea]
+dlg.corewait.title=Core-a Abiatzen
+dlg.corewait.text=Une Bat Mesedez...\n\nZure eskaera Vuzek abiarazpena burutu ondoren bideratuko da.
+library.core.wait=Une Bat Mesedez...\nVuze Bezeroa Abiatzen ari da
+ConfigView.label.StartUIBeforeCore=Hasi EI Core-a abiarazpenaren aurretik
+general.add.friends=Gehitu lagun batzuk!
+general.all.friends=Lagun Guztiak
+friend.mod.subs=Eskuin-klikatzea harpidetzak aldatzeko
+TableColumn.header.class=Saila
+device.rss.group=Tokiko RSS Jarioa
+devices.xcode.rsspub=Argitaratu RSS jarioa
+device.rss.enable=Sortu RSS jarioa transkodeaketa edukitik -  honek edukia eskuragarri egiten du RSS jario irakurleentzat
+device.rss.port=RSS jario ataka
+device.rss.view=Egin klik RSS jarioa ikusteko
+device.rss.localonly=Sarbide ukatua ordenagailu honetara bakarrik
+devices.xcode.autoCopy=Berezgaitasunez Kopiatu Agiritegira
+devices.xcode.setcopyto=Ezarri Kopiaketa Agiritegia
+devices.xcode.setcopyto.title=Hautatu kopiaketa helbidea
+devices.copy.folder.auto=Berezgaitasunez kopiatu agiriak agiritegian
+devices.copy.folder.dest=Agiritegira kopiatu
+TableColumn.menu.maxuploads=Geh. Igoera Zenb.
+devices.xcode.mancopy=Eskuz Kopiatu Agiriak
+devices.xcode.show.cat=Kategoriatan Banandurik
+ConfigView.label.alwaysShowLibraryHeader=Betik erakutsi buru/iragazki barra liburutegian
+devices.cat.show=Erakutsi kategoriak
+devices.tivo.machine=TiVo gailu izena
+devices.info.copypending=%1 Agiri Itxaroten Kopiatuak Izateko
+device.error.xcodefail=Transkodeaketa Hutsegitea
+device.error.copyfail=Agiri Batek Edo Gehiagok Huts Egin Du Agiritegira Kopiatzean
+device.error.copytonotset='Kopiatu Agiritegira' Ezarri Gabe
+device.error.copytomissing='Kopiatu Agiritegira' "%1" Ez da Aurkitu
+device.error.copytonowrite='Kopiatu Agiritegira' "%1" Ez Idazgarria
+device.error.copyfail2=Agiri Batek Edo Gehiagok Huts Egin Du Gailura Kopiatzean
+v3.deviceview.infobar.line2.tivo=Bideo jarioak zure TiVo-ra joanez eta Vuze hautatuz zure Uneko Irakur Zerrendan.
+v3.deviceview.infobar.line2.psp=Bideoak zure PSP-ra kopiatu daitezke hau elkarketaturik dagoenean.
+devices.info.copypending2=%1 Agiri Itxaroten Kopiatuak Izateko, Elkarketatu Zure Gailua
+subscriptions.column.nb-subscribers=Harpidetuak
+subscriptions.column.category=Kategoria
+device.offlinedownloader.view.title=Lineaz-kanpoko Jeistzaileak
+device.xcode.group=Kodea
+device.od.group=Izenburua
+device.od.enable=Gaitu lineaz-kanpoko jeisketa gailuak
+device.odauto.enable=Berezgaitasunez kudeatu jeisketak
+device.odpt.enable=Torrent pribatuak barne
+devices.contextmenu.od=Lineaz-kanpo Jeisten
+devices.contextmenu.od.auto=<Berezgaitasunez>
+devices.contextmenu.od.enable=Gaitu
+devices.contextmenu.od.enabled=Gaiturik
+devices.od.view.heading=Lineaz-kanpoko jeisketarako jeisketa egitarautuak
+DevicesOD.column.od_name=Izena
+DevicesOD.column.od_status=Nire Aztarnaria
+DevicesOD.column.od_completion=Eskualdaketa Garapena
+DevicesOD.column.od_remaining=Gainerakoa
+devices.od.xfering=Eskualdaketa
+device.od.turnon.title=Piztu Lineaz-kanpoko Jeisketa Sostengua
+device.is.disabled=Gailua ezgaiturik dago
+device.configure=Itxuratu...
+device.od.error.notfound=Gailua lineaz-kanpo dagoela dirudi
+device.od.error.opfailstatus=Gailuak huts egin du komando hau prozesatzerakoan %1: egoera %2
+device.od.error.opfailexcep=Gailuak huts egin du komando hau prozesatzerakoan %1: salbuespena %2
+device.od.error.nospace=Ez da tokirik gelditzen gailuan edo ez dago kanpo batasunik elkarketaturik 
+device.od.space=Toki Eskuragarria
+ConfigView.section.style.forceSIValues=Behartu balioak erakutsiak izateko IEK balio bezala ondorengo helburuekin erabilitako erakusleihoa edozein izanda ere. (adib. 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=Erakutsi jeisketa estatistikak azalean
+devices.activation=Gailu Eragitketa
+button.nothanks=Ez Mila esker
+devices.od.turnon.text1=Nabaritu dugu hona elkaketaturik zaudela %1.
+devices.od.turnon.text2=Nahi duzu %1 jarraitzea zure agiriak jeisten ordenagailua linez-kanpo dagoenean?
+devices.od.turnon.text3=Mesedez elkarketatu Diska Gogor bat %1 eginkizun hau abiatzeko.
+devices.od.turnon.learn=Jakin gehiago >
+devices.router=routerra
+devices.od=Lineaz-kanpoko jeistzailea
+webui.pairingenable=Gaitu parekatzea plugin honentzat (azterketa aukerak gaituak izan daitezke uneko parekatze xehetasunak ongi argitaratu direnean)
+webui.group.access=Sarbide Agintea
+ConfigView.section.Pairing=Uztarpena
+pairing.accesscode=Sarrera kodea
+pairing.ac.getnew=Izendatu sarbide kode berri bat
+pairing.ac.getnew.create=Sortu
+pairing.ipv4=IPv4 Helbide publikoa
+pairing.ipv6=IPv6 Helbide publikoa
+pairing.local.ipv4=Tokiko IPv4 helbidea
+pairing.local.ipv6=Tokiko IPv6 helbidea
+pairing.host=Ostalari izena (DNS izena)
+pairing.group.explicit=Ezaugarri Bereiziak
+pairing.explicit.enable=Gaitu
+pairing.explicit.info=Arrunt IP ezaugarriak ez dira adierazi beharrezkoak berezgaitasunez eratorriak izan daitezkelako.\n'Ostalari' ezaugarria erabilia izan daiteke, adibidez, DynDNS kontu bat baduzu eta software bezero egoki bat zure IP dinamikoa zuzen izenemanda gordetzeko.
+pairing.op.fail=Parekatze Eragiketa Huts egin du
+pairing.alloc.fail=Huts egin du sarbide kode berri bat izendatzerakoan\n%1
+pairing.enable=Gaitu parekatzea Vuzerentzako eta hurrutiko egokitzapen/interfazeak
+pairing.status.info=Egoera
+pairing.status.registered=Eguneraketa eginda (%1)
+pairing.status.pending=Eguneraketa burutuko da %1
+pairing.status.initialising=Abiatzen
+pairing.status.disabled=Ezgaiturik
+pairing.view.registered=Klikatu ikusteko uneko izenemate xehetasunak
+webui.pairing.info.n=Parekatzea ezgaiturik dago, ikusi Elkarketa->Parekatze aukerak ezaugarri honen argibide gehiagorako
+webui.pairing.info.y=Parekatzea gaituta dago, ikusi Elkarketa ->Parekatze aukerak xehetasun gehiagorako.
+webui.enable=Gaitu
+ConfigView.section.rss=Tokiko RSS etab.
+subscriptions.rss.enable=Sortu RSS Jarioak harpidetzetatik
+device.tivo.enable=Gaitu TiVo sostengua
+Button.removeAll=Denak Ezabatu
+label.rename=Birrizendatu  %1
+pairing.server.warning.title=Parekatze Zerbitzuaren Mezua
+wizard.webseedseditor.edit.title=HTTP Emale Editorea
+wizard.webseedseditor.edit.newseed=Emale Berria
+MyTorrentsView.menu.editWebSeeds=Editatu HTTP Emaleak
+ClientStats.title.full=Bezero Estatistika
+ClientStats.column.count=Zenbaketa
+ClientStats.column.discarded=Baztertuta
+ClientStats.column.received=Jasoa
+ClientStats.column.sent=Bidalia
+ClientStats.column.name=Izena
+MainWindow.menu.view.clientstats=Izen osoa
+Scrape.status.cached=Katxe zuritua
+network.ipv6.enable.support=Gaitu IPv6 sostengua (Java7-k beharrezkoa du Windowsekin)
+ConfigView.section.plugins.magnetplugin=Magnet URI Agintea
+MagnetPlugin.use.lookup.service=Erabili Vuzeren bigarren bilaketa zerbitzua DHT bidezko erakarpen bilaketak huts egiten badu
+MagnetPlugin.report.secondarylookup=Bigarren bilaketa zerbitzuarekin saiatzen
+MagnetPlugin.report.secondarylookup.ok=Bigarren bilaketa bat egin da
+MagnetPlugin.report.secondarylookup.fail=Bigarren bilaketak huts egin du: ez da iturbururik aurkitu
+TrackerView.title.short=Iturriak
+TrackerView.title.full=Iturriak
+Trackers.column.type=Mota
+Trackers.column.name=Xehetasunak
+Trackers.column.status=Egoera
+Trackers.column.seeds=Emaleak
+Trackers.column.seeds.info=Emaleak erletaldean
+Trackers.column.leechers=Izainak
+Trackers.column.leechers.info=Izainak erletaldean
+Trackers.column.peers=Hartzaileak
+Trackers.column.peers.info=Hartzaileak aztarnarira itzulita
+Trackers.column.interval=Tartea
+Trackers.column.interval.info=Galdetze tartea segundutan: tartea (gutx. tartea)
+Trackers.column.updatein=Hurrena
+Trackers.column.updatein.info=Hurrengo eguneraketa arteko denbora
+tps.status.available=Eskuragarria
+tps.status.unavailable=Eskuraezina
+tps.lan.details=%1 tokiko bezero aurkituta
+tps.pex.details=Elkarketaturik %1 hartzailera (egiteke: pex=%2, beste=%3)
+tps.tracker.cache=Hartzaile katxea
+tps.tracker.cache1=Hartzaile katxea: erabilita=%1
+dht.status.disabled=Ezgaitu, eskuraezina den banaturiko datubasea
+tps.type.incoming=Sartzen
+tps.incoming.details=Orain: TCP=%1, UDP=%2; Guztira inoiz=%3
+tps.type.plugin=Plugina
+group.auto=Berez
+ConfigView.label.autoadjust=Berezgaitasunez zehaztu elkarketa abiaduran ohinarrituriko ezarpen hau
+ConfigView.label.start=Abiarazi
+ConfigView.label.stop=Itzali
+ConfigView.label.start.onlogin=Hasi Vuze izena emanda
+ConfigView.label.stop.seedcomp=Emaletza burutu denean
+ConfigView.label.stop.downcomp=Jeisketa burutu denean
+ConfigView.label.stop.Nothing=Ez egin ezer
+ConfigView.label.stop.QuitVuze=Itzali Vuze
+ConfigView.label.stop.Sleep=Ordenagailua Egonean
+ConfigView.label.stop.Hibernate=Negutu Ordenagailua
+ConfigView.label.stop.Shutdown=Itzali Ordenagailua
+core.shutdown.alert=Ekintza '%1' sugiltzatua %2
+core.shutdown.dl=jeisketak burututa
+core.shutdown.se=emaletza burututa
+pairing.last.error=Azken akatsa
+MainWindow.menu.pairing=Hurruneko Parekatzea
+ConfigView.section.startstop=Hasi eta Gelditu
+ConfigView.label.pauseresume=Berez-pausatu/jarraitu
+update.now.title=Eguneraketa Beharrezkoa
+update.now.desc=Vuzek eguneraketak egitea behar du migrazioa osatzeko.\n\nElkarrizketa hau itxi ondoren Windowsi eskatu ahal diozu eguneraketa aurrerabidea osatzeko.\n\nVuzeren birrabiaraztea EZ da beharrezkoa.
+ConfigView.label.jvm=Java Aukerak
+platform.jvmopt.sunonly=Sun JVM-ak bakarrik dira sostengatuta (oraingo hornitzailea=%1)
+platform.jvmopt.configerror=Ezin dira  JVM aukerak kudeatu itxurapen akats bat dagoelako
+platform.jvmopt.nolinkfile=Ezin dira JVM aukerak kudeatu migrazioa burutu gabe dagoelako
+platform.jvmopt.nolink=Ezin dira JVM aukerak kudeatu dagoen itxurapenak eragaotzi egiten duelakoconfiguration
+platform.jvmopt.accesserror=Huts egin du JVM aukeratara sartzean: %1
+pairing.status.noservices=Ez dago hurrutiko zerbitzurik gaituta
+webui.pairingtest=\tEgin klik parekatze azterketarako
+webui.connectiontest=\tEgin klik elkarketa azterketarako
+ConfigView.section.connection.pairing.url=http://wiki.vuze.com/w/UG_Aukerak#Parekatzen
+jvm.info=Vuzeren birrabiarazte bat beharrezkoa da aukerak aldatuak badira. *** Kontuz - JVM aukeren aldaketa okerrak Vuze ez abiatzea edo gaizki jardutea eragin dezake ***\n
+jvm.show.file=Tokiko JVM aukera agiria da '%1' - Berreskurapenerako bakarrik editatu
+jvm.reset=Birrezarri JVM aukerak ezarpenaren berezkoetan
+jvm.error=Akats bat egon da JVM aukeretara sartzean: %1
+jvm.max.mem=Geh Piloaren oroimen neurria [zuri=berez,gutx=%1]
+jvm.min.mem=Gutx Piloaren oroimen neurria [zuri=berez,gutx=%1]
+ConfigView.section.invalid.value.title=Balio Okerra
+ConfigView.section.invalid.value=Balio okerra '%1' sartua '%2': %3
+Button.dismiss=Baztertu
+webui.pairing.autoauth=Gaitu berezko sar-hitz babesa: erabiltzaile izena=vuze, sar-hitza=<sarbide kode parekatzea>
+ConfigView.label.stop.autoreset=Berezgaitasunez birrezarri ekintzak '%1' behin eraginduta
+remote.pairing.title=Hurruneko Parekatzea
+remote.pairing.subtitle=Hurruneko Vuzek edozin ordenagailu edo mobiletik Vuzeren agintea hartzeko aukera ematen dizu - edonoiz, edonondik.
+remote.pairing.instruction=Besterik gabe sartu kodea edozein hurruneko gailuk duen beheko tartean. 
+remote.pairing.functions=<A HREF="clip">Kopiatu kodea gakora</A>   |   <A HREF="new">Eskuratu kode berri bat</A>
+remote.pairing.tip.title=Oharra: Hurruneko Vuze erabiltzeko bi bide erraz:
+remote.pairing.tip.text=Hurruneko Vuze Tresnabarra : Zoaz <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nVuze Remote Mobile: Zoaz <A HREF="http://remote.vuze.com/">remote.vuze.com</A> zure mobileko bilatzailean.
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">Parekatzea FAQs</A>
+remote.pairing.accesscode=Sarbide Kodea:
+remote.pairing.test.running=Hurruneko elkarketagarritasuna aztertzen...
+remote.pairing.test.success=Vuze hurrunetik eskuragarria da.
+remote.pairing.test.unavailable=Ene, ezin izan da zure hurruneko elkarketa zehaztu. <A HREF="retry"> Saiatu berriro</A>
+remote.pairing.test.fail=Vuze eskuraezina da zure tokiko saretik kanpo.  <A HREF="/pairing_error_faq.start">Jakin gehiago</A>
+update.fail.app.changed.title=Eguneratzeak Huts egin du
+update.fail.app.changed=Vuzek eguneratzea behar du baina aurrerabidea ezin daiteke berezgaitasunez osatu egokitzapenaren izena aldatua izan delako '%1'.\n\nMesedez joan http://www.vuze.com/-era eta jeitsi azken ezarpena.
+webui.port.override=Ataka ezeztatua: beharrezkoa da bakarrik NAT-aren itxurapenagaitik ataka publikoa eta barneko egoitza ezberdinak direnean.
+MainWindow.status.warning.tooltip=Egin klik xehetasunak ikusteko
+search.dialog.text=Sartu torrent berriak bilatzeko idazkia:
+core.not.available=Vuze oraindik abiatzen dago, mesedez saiatu berriro eginda dagoenean
+dlg.auth.title=Eragintza
+dlg.auth.enter.subtitle.try.1=Ia han.
+dlg.auth.enter.line.try.1=Sartu zure eragintza kodea behean eta osatu zure Vuze Pluserako berritzea.
+dlg.auth.enter.line.try.2=Barkatu, ezin izan dugu zure eragintza kodea balioztatu. Mesedez egiaztatu zenbakia eta saiatu zaitez berriro sartuz.
+dlg.auth.enter.prompt=Vuze Plus Eragiketa Kodea:
+Button.validate=Balioztatuta
+Button.getstarted=Abiaturik
+Button.install=Ongi
+Button.goLibrary=Joan Liburutegira
+dlg.auth.success.subtitle=Zorionak!
+dlg.auth.success.line1=Mila esker Vuze Plus eguneratzeagaitik.
+dlg.auth.success.line2=Orain gai zara DVD grabaketa mugagabe bat egiteko, mihatu zure agiriak birusen aurka, eta jariotu jeisten ari zaren bideoak - dena iragarkirik gabe!
+dlg.auth.trial.success.line1=Vuze gertu dago DVD-ak sortzeko.
+dlg.auth.trial.success.subtitle=DVD Grabaketa Gertu
+dlg.auth.trial.success.info=Arrastatu bideo agiriak zure liburtegitik "Sortu DVD Berria"-ra. Jadanik bideo bat gehituta bazenuen osagaiak ezarri aurretik, mesedez gehitu ezazu berriro.
+dlg.auth.revoked=Eragintza Kodea Indargabetuta
+dlg.auth.revoked.line1=Zure Vuze Plus Eragintza Kodea indargabetua izan da. Mesedez klikatu behean argibide gehiago izateko.
+dlg.auth.revoked.link=<A HREF="info">Eragintza kodeen Indargabetzeari buruzko Argibideak</A>
+dlg.auth.denied=Eragintza Kodea Ukatuta
+dlg.auth.denied.line1=Zure Vuze Plus Eragintza Kodea ukatua izan da. Mesedez klikatu behean argibide gehiago izateko.
+dlg.auth.denied.link=<A HREF="info">Kode Eragintza Ukapenaren Argibideak</A>
+dlg.auth.cancelled=Eragiketa Kodea Ezeztaturik
+dlg.auth.cancelled.line1=Zure Vuze Plus Eragintza ezeztatua izan da.
+dlg.auth.cancelled.line2=Akats bat dela uste baduzu, mesedez jarri zaitez harremanetan sostenguarekin jasotako e-mail helbideen bidez.
+dlg.auth.enter.subtitle.try.2=Balioztapenak huts egin du
+dlg.auth.enter.link.try.2=<A HREF="link">Klikatu hemen</A> oraindik ez baduzu Vuze Plusen kopia bat erosita.
+dlg.auth.enter.link.try.1=Ez duzu eragintza kode bat? <A HREF="upgrade">Berritu orain</A>.
+dlg.auth.enter.expiry=Oraingo eragintza kodea iraungitzen da %1.
+dlg.auth.enter.revoked=Oraingo eragintza kodea indargabetua izan da.
+dlg.auth.enter.cancelled=Oraingo eragintza kodea ezeztatua izan da.
+dlg.auth.enter.denied=Oraingo eragintza kodea ukatua izan da.
+dlg.auth.validating.subtitle=Balioztatzen
+dlg.try.trial.title=Probatu DVD Grabaketa
+dlg.try.trial.text=Vuzek zure bideoetatik DVD grabaketak egin ahal izateko beharrezkoa den plugina ezartzea behar du.  Klikatu Piztu jarraitzeko.
+dlg.auth.tos=Irakurri ditut eta onartzen ditut <A HREF="tos">Zerbitzuaren Baldintzak.</A>
+dlg.auth.install.subtitle.plus=Vuze Plus ezartzen...
+dlg.auth.install.subtitle.trial=DVD Grabaketa ezartzen
+dlg.auth.install.progress=Ezartzen %1 osagai...
+dlg.auth.install.pct=%1% eginda
+mdi.entry.dvdburn=DVD Grabaketa
+mdi.entry.dvdburn.new=Sortu DVD Berria
+menu.register=Vuze Plus Eragiketa
+dlg.auth.trial.title=DVD Grabaketa Proba
+dlg.player.install.subtitle=Ezarpena
+dlg.player.install.description=Irakurketa osagai gehiagarria ezartzen...
+devices.xcode.remove.vetoed='%1' Transkodeaketa garatzen, jeisketa ezin da kendu osatu arte edo transkodeaketa 'Gailuak' orrialdetik ezeztatuta egon arte.
+Button.agree=Onartzen Dut
+dlg.auth.install.failed.title=Eragintza Hutsegitea
+dlg.auth.install.failed.text=Kodearen eragintza '%1' hutsegitea zerbitzari akats bategaitik.\n\nMesedez saitu zaitez eragintzarekin geroago (jakinarazitako akatsa zen '%2')
+device.status.online=Gailua online dago
+device.itunes.status.running=iTunes lanean dago
+device.itunes.status.notrunning=iTunes ez dago lanean
+device.itunes.status.notinstalled=iTunes ez dago ezarrita
+OpenTorrentWindow.mb.notTorrent.retry=Magnet Itxiera
+ConfigView.section.ipfilter.clear.on.reload=Garbitu iragazkiak birgertatzerakoan. Birgertatze aurrerabidean zehar IP-ak ez dira itxiko. Egiaztatugabe badago, itxigabeko berriak ez dute eraginik izango birrabiarazi arte.
+view.waiting.core=Ikustea eskuragarri egon daiteke Vuze Core gertatzen denean
+devices.profile.direct=Zuzen
+cat.autoxcode=Berez-Baliabidea
+ConfigView.section.tables=Aurkibideak
+ConfigView.section.style.useTree=Erakutsi Agiriak Liburutegian ikusita  (Beharrezkoa Birrabiaraztea)
+ConfigView.section.mode.resetdefaults=Birrezarri ezarpenak berezko balioetan (birrabiaraztea gomendatzen da)
+resetconfig.warn.title=Baieztatu Eragiketa
+resetconfig.warn=Honek Vuzeren itxurapenean egin dituzun aldaketa guztiak galtzea eragingo du./nJarraitu itxurapen birrezarpenarekin?
+ConfigView.label.xfer.bias_up=Handitu jeisketa abiadurak igoera gaitasunera osatugabeko jeisketetan
+ConfigView.label.xfer.bias_slack=KB/s gutxienez gordeta jeisketa osatuentzat
+ConfigView.label.xfer.bias_no_limit=Bidea ezartzeko saiakera igoera muga global eraginkor bat ez dagoenean
+SpeedView.stats.upload=Igo lerrokaturiko datuak:
+SpeedView.stats.con=Elkarketa xehetasunak:
+SpeedView.stats.con_details=guztira=%1, itogabe=%2, lerrokaturik=%3, eragotzita=%4
+SpeedView.stats.upbias=Igoera bideak:
+dlg.install.mlab.subtitle=Ezartzen
+dlg.install.mlab.description=Mesedez itxaron abiadura azterketa osagia ezartzen den bitartean
+dial.up=Urrutizkin bidezko Internet elkarketa
+auto.mode=Berez (gomendatua)
+manual.mode=Eskuz
+configureWizard.transfer2.hint=Zure igoera muga hain goian edo hain behean ezartzeak jeisketan eragin dezake!
+configureWizard.transfer2.message=Bittorrent tit-for-tat protokoloan ohinarrituta dago - orokorrean zure igoera azkarrena, zure jeisketa azkarrena - zein jeisketa azkarra, eta elkarbanatze maila on bat azkar lortzeko, behar duzu igoera abiadura on bat.\n\nHorrela ere, zure elkarketarako azkarregi igotzen baduzu, gainzamatu egin dezakezu errendimendu globala motelagoa izanez eta eraginez sarearen baliabideengaitik lehiatzen diren beste egokitzapenei.\n\nHortaz garrantzitsua da zama muga o [...]
+configureWizard.transfer2.group=Modua
+configureWizard.transfer2.test.info=Hautatu azterketa oso bat egiteko abiadura
+configureWizard.transfer2.test=Abiatu Azterketa
+configureWizard.transfer2.mselect=Hautatu zure elkarketaren IGOTZE abiadura muga
+configureWizard.transfer2.mselect.info=xxx/<value> sarrerek nabaritzen dute igoera elkarketa abidura <value> bit segunduko.\nAdibidez, zuk ADSL elkarketa bat baduzu 768 Kbps-ko jeistejario abiadurarekin eta 384 Kbps-ko igoerajarioarekin, hautatu 'xxx/384 kbit/seg'.\nBorobiludu txikira hurbileneko baliora abiadura zehatza erakusten ez bada.
+configureWizard.transfer2.rate.unchanged=Oraingo ezarpenak erabiliak izan daitezke
+configureWizard.transfer2.rate.changed=Elkarketa muga=%1\nEzarritako muga izan daiteke %2 (geh. torrent eraginda =%3, geh. jeisten=%4)
+speedtest.wizard.select.title=Hautatu egin behar den abidura azteketa mota
+speedtest.wizard.select.group=Azterketa Mota
+speedtest.wizard.select.general=Abiadura azterketa Orokorra (gomendatua)
+speedtest.wizard.select.bt=Bittorrent abiadura azterketa bereizia
+FileItem.storage.reorder=Birrantolatu
+ConfigView.label.piecereorder=Erantsi datuak jeitsitako agiriei eta birrantolatu atalak jeisketa garapen bezala
+ConfigView.label.piecereorderminmb=Birrantolatu bakarrik handiagoak diren agiriak (MB-tan)
+configureWizard.transfer2.current=<Oraingo Ezarpenak>
+ConfigView.section.style.extendedErase=Marraztu saretxo erroak eta bete eremu hutsak
+iconBar.stream=Irakurri Orain
+FilesView.menu.setpriority.numeric=Zenbakizko...
+FilesView.dialog.priority.title=Sartu Zenbaki Lehentasuna
+FilesView.dialog.priority.text=0=Arrunta, 1=Handia, 2=Oso Handia...
+beta.wizard.title=Beta Bertsioaren Ezarpena
+beta.wizard.intro.title=Bazkidetasun hautapena
+beta.wizard.info=Vuze beta programan bazkidetuz bezeroan aurrentasuna duzu argitalpenetan.\n\nHonek aukera ematen dizu argitalpen hauek probatzeko eta beren egokitzapenean laguntzeko - zure laguntza oso erabilgarria da guretzat!\n\nBaina beta bertsioak berez ezegonkorrak izan daitezke, horrela ere aukera hau hautatuz argitalpen nahiko egonkorretarako sarrera izango duzu. Nahi baduzu gehitu 'Beta Eguneratze' plugina erabili dezakezu.
+beta.wizard.link=Egin klik hemen beta argitalpenen webgunera joateko
+beta.wizard.off=Pozik nago argitaraturiko bertsioekin, ez eskerrik asko!
+beta.wizard.on=Eguneratu azken beta bertsio egonkorrarekin mesedez.
+beta.wizard.version=Orain duzun bertsioa %1
+beta.wizard.disable.title=Birrezarpena Beharrezkoa
+beta.wizard.disable.text=Mila esker beta bertsioak probatzeagaitik!\n\nMesedez jeitsi eta ezarri argitaraturiko azken bertsioa beta programa baimentzeko
+beta.wizard.forum=Erabili Vuze eztabaidaguneak jarioak hartzeko akatsen berri izateko
+dlg.install.vuzexcode.subtitle=Media Aztergailu osagaia ezartzen
+dlg.install.vuzexcode.description=Mesedez itxaron Media Aztergailuaren osagaia ezartzen den bitartean
+dlg.install.azemp.subtitle=Azpidatziak
+dlg.install.azemp.description=Azalpena
+TableColumn.header.filecount=Agiriak
+TableColumn.header.torrentspeed=Abiadura
+FileProgress.deleted=Ezabatuta
+FileProgress.stopped=Geldituta
+priority.high=Lehentasun Handia
+priority.normal=Lehentasun Arrunta
+label.wrap.text=Idatzia Erdiratu
+ScrapeInfoView.title=Lehen Aztarnaria
+Column.seedspeers.started=%1 %2-tik
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 Gai: %2 Eraginda
+library.incomplete.header.p=%1 gai jeisten, %2 itxaroten jeisteko
+library.unopened.header.p=%1 gai
+library.all.header=%1 Gai: %2 Eraginda
+library.incomplete.header=%1 gai jeisten, %2 itxaroten jeisteko
+library.unopened.header=%1 gai
+ConfigView.section.style.status.show_rategraphs=Erakutsi bataz-besteko historia grafikoak jeisketa/igoera idatzien azpian
+device.error.mountrequired="%1" Zure Gailua Tresnatzeko Beharrezkoa
+v3.deviceview.infobar.line2.android=Gaitu USB heuskarria zure urrutizkenean bideoak zuzen eskualdatzeo
+MyTorrents.column.ColumnProgressETA.compon=Osatuta %1
+Sidebar.beta.title=Beta Programa
+MainWindow.menu.beta.on=Gozatu Beta Programa...
+MainWindow.menu.beta.off=Eskuratu Beta Programa...
+Button.sendNow=Bidali Orain
+Button.sendManual=Eskuzko Bidalketa (sortu .zip)
+deletecontent.also.deletetorrent=Ezabatu .torrent agiria honela
+ConfigView.section.file.deletion.section=Agiri Ezabapena
+ConfigView.section.file.delete.torrent=Berez ezabatu .torrent agiriak edukia ezabatzerakoan
+ConfigView.section.file.delete.confirm=Baieztatu eduki ezabapena Tresnabarraren eta Ezabatu giltzaren bidez
+menu.delete.options=Kendu...
+MainWindow.menu.view.beta=Beta Programa
+ConfigView.section.server.enableudpprobe=Gaitu UDP aztarnari zunda HTTP aztarnarientzat
+memmon.low.warning=Oroimena geldoki ari da lanean, duzu %1 gelditzen da %2.\nEgintza kaltetua izan daiteke eta azkenean Vuzek lan egiteari utzi diezaioke\nIkusi <a href="http://wiki.vuze.com/w/Java_VM_memory_usage">the Wiki</a> oroimen eskuragarria nola handitzeko xehetasunak.
+jvm.max.mem.current=Oraingo Pilo gehiena da  %1
+jvm.max.direct.mem=Geh Zuzeneko oroimen neurria [zuri=berez,gutx=%1]
+jvm.max.direct.mem.info=Oharra: hau *Zuzen* oroimen ezarpena da, ohikoagoa da eguneratu behar izatea *Pilo* oroimena gainean
+jvm.options.summary=Oraingo aukeren laburpena:
+memmon.heap.auto.increase.warning=Piloaren oroimena handitu da %1. Vuze birrabiarazitakoan izango du eragina.
+device.showGeneric=Erakutsi Gailu Generikoak
+mdi.entry.games=Jokoak
+v3.MainWindow.menu.games=Jolasak
+Peers.column.Protocol=Protokoloa
+devices.copying=Gailura kopiatzen
+devices.cancel_xcode=Ezeztatu Bihurketa
+sidebar.header.transfers=Agiriak
+sidebar.header.devices=Irakurketa Gailua
+sidebar.header.subscriptions=Harpidetzak
+sidebar.header.plugins=Pluginak & Gehigarriak
+sidebar.header.dvd=DVD Grabaketa
+mdi.entry.about.devices=Garatzen
+mdi.entry.about.plugins=Pluginei Buruz
+mdi.entry.about.dvdburn=Hasteko
+ConfigView.section.file.tb.delete=Ezabatzerakoan Ezabatu edo Tresnabarraren bidez:
+ConfigView.tb.delete.ask=Galdetu
+ConfigView.tb.delete.content=Ezabatu galdetu gabe
+ConfigView.tb.delete.torrent=Liburutegitik bakarrik kendu
+search.export.all=Esportatu Bilaketa Eredu Guztiak...
+subscriptions.search.enable=Gaitu harpidetza emaitzetarako bilaketa (birrabiaraztea beharrezkoa)
+devices.cancel_xcode_del=Ezeztatu Bihurketa/Kentzea
+subscriptions.add.tooltip=Gehitu Harpidetza
+subscriptions.overview=Harpidetzen Gainikuspena
+configureWizard.nat.title=NAT / Zerbitzari Ataka Azterketa
+configureWizard.nat.message=Vuzerentzako irteera hoberena izateko osoki gomendatua da internetetik erabat eskuragarri egotea.. Tresna honek aztertzea eta / edo sarrerako elkarketen onartzeko ataka aldatzea ahalbidetzen dizu.\n\n OHARRA: TCP 6880 ataka barnean gordea da eta ezin da erabili.
+configureWizard.nat.server.udp_listen_port=Sarrerako UDP Aditze Ataka
+v3.menu.device.defaultprofile.never=Inoiz ez Transkodeatu
+subscriptions.info.avail=Ez duzu harpidetzarik gehitu oraindik. %1 daude eskuragarri zure liburutegirako.
+subscriptions.dl_subs.enable=Jeitsi harpidetzak beste bezeroetatik beharrezkoa denean
+# Will be used for {library.name} in classic view
+library.name._classic=Nire Torrentak
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Liburutegia
+ConfigView.section.style.units=Erakutsi Batasunak
+ConfigView.section.style.library=Izena
+ConfigView.section.style.CatInSidebar=Erakutsi Kategoriak Albobarran
+library.category.header=Kategoria '%1'
+device.import.title=Gailua inportatu?
+device.import.desc=Zihur zaude '%1' gailua inportatu nahi duzula?
+device.import.dup.title=Bikoiztu Gailua
+device.import.dup.desc='%1' Gailua jadanik badago.
+stream.analysing.media=Hedabidea Aztertzen
+device.export.select.template.file=Esportatu Gailua
+dlg.stream.plus.subtext=Asperturik zure jeisketak osatu arte itxaroteaz? Ikusi itzazu lehenago Play Now-rekin, Vuze Plusen ezaugarri bat ahalbidetzen dizuna bideoa ikustea jeisketak jarraitzen duen bitartean.
+dlg.stream.plus.text=Berritu Vuze Plusera eta ikusi zure bideoak jeisten daudela.
+dlg.stream.plus.title=Berritu
+dlg.stream.plus.subtitle=Berritu
+Button.upgrade=Eguneratu
+iconBar.pstream=Jarioa
+stream.analysing.media.preview=Hedabideak Aztertzen (Aurreikuspen Modua)
+devices.restrict_access=Sarbidea Ukatu...
+devices.restrict_access.prompt=Sarbidea Ukatu '%1'
+devices.restrict_access.msg=IP zerrenda kakotxaz banandurik baimentzeko [edo ukatzeko aurrezenbakia bada -]
+TableColumn.header.TorrentStream=Jarioa
+TableColumn.TorrentStream.tooltip.disabled=Jo Orain ez da agiri mota honentzat baliagarria
+TableColumn.TorrentStream.tooltip.expand=Handitu lerroa Jo Orain ikusteko banakako agirientzat
+table.columns.reset=Birrezarri Zutabeak
diff --git a/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties b/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
index af75d57..45bd0fe 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_fi_FI.properties
@@ -1,2705 +1,2982 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=Torrent-tiedosto...
-Main.parameter.usage=K\u00e4ytt\u00f6: java org.gudy.azureus2.cl.Main [parametrit] "tiedosto.torrent" "tallennushakemisto" 
-Main.parameter.maxUploads=Yht\u00e4aikaisten l\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4 
-Main.parameter.maxSpeed=Enimm\u00e4isl\u00e4hetysnopeus (kB/s) 
-MainWindow.menu.file=&Tiedosto 
-MainWindow.menu.file.open=&Avaa 
-MainWindow.menu.file.create=L&uo torrent-tiedosto...
-MainWindow.menu.file.create.fromfile=&Tiedostosta 
-MainWindow.menu.file.create.fromdir=&Hakemistosta 
-MainWindow.menu.file.export=&Vie torrent-tiedosto XML-muotoon...
-MainWindow.menu.file.import=&Tuo torrent-tiedosto XML-muodosta...
-MainWindow.menu.file.closetab=Sulje v&\u00e4lilehti
-MainWindow.menu.file.closewindow=Sulje &ikkuna
-MainWindow.menu.file.exit=&Lopeta 
-MainWindow.dialog.choose.file=Valitse torrent-tiedosto 
-MainWindow.menu.file.folder=Torrent-tiedostot &hakemistosta
-MainWindow.dialog.choose.folder=Valitse torrent-tiedostot sis\u00e4lt\u00e4v\u00e4 hakemisto 
-MainWindow.menu.view=&N\u00e4yt\u00e4 
-MainWindow.menu.view.show=N\u00e4yt\u00e4
-MainWindow.menu.view.mytorrents=&Siirrot
-MainWindow.menu.view.open_global_transfer_bar=Siirrot-palkki
-MainWindow.menu.view.configuration=&Asetukset...
-MainWindow.menu.view.console=&Konsoli 
-MainWindow.menu.view.irc=IRC
-MainWindow.menu.view.allpeers=Kaikki yhteydet
-MainWindow.menu.view.detailedlist=&Yksityiskohtainen luettelo
-MainWindow.menu.closealldetails=Sulje kaikki tarkat ti&edot 
-MainWindow.menu.closealldownloadbars=Sulje kaikki &seurantapalkit 
-MainWindow.menu.language=&Kieli 
-ConfigView.section.language=Kieli
-MainWindow.menu.window=&Ikkuna
-MainWindow.menu.window.minimize=&Pienenn\u00e4
-MainWindow.menu.window.zoom=&L\u00e4henn\u00e4
-MainWindow.menu.window.alltofront=Tuo kaikki &eteen
-MainWindow.menu.help=&Ohje 
-MainWindow.menu.help.about=Tietoja Vuzesta
-MainWindow.menu.torrent=To&rrent-tiedosto
-MainWindow.about.title=Tietoja Vuzesta- versio
-MainWindow.about.section.developers=Kehitt\u00e4j\u00e4t 
-MainWindow.about.section.translators=K\u00e4\u00e4nt\u00e4j\u00e4t 
-MainWindow.about.section.system=J\u00e4rjestelm\u00e4tiedot
-MainWindow.about.section.internet=Vuze Internetiss\u00e4
-MainWindow.about.internet.homepage=Kotisivu
-MainWindow.about.internet.sourceforge=SourceForge.netin projektisivu 
-MainWindow.about.internet.sourceforgedownloads=SourceForge.netin lataussivu 
-MainWindow.about.internet.bugreports=Ohjelmavirheilmoitukset
-MainWindow.about.internet.forumdiscussion=Keskustelualueet
-MainWindow.about.internet.wiki=Vuze Wiki (UKK)
-MainWindow.dialog.choose.savepath=Valitse tallennushakemisto 
-MainWindow.dialog.choose.savepath_forallfiles=Valitse tallennushakemisto kaikille tiedostoille 
-MainWindow.status.latestversion=Uusin virallinen versio:
-MainWindow.status.latestversion.clickupdate=P\u00e4ivit\u00e4 t\u00e4st\u00e4 
-MainWindow.status.unknown=Tuntematon 
-MainWindow.status.checking=Tarkastetaan 
-MyTorrentsView.mytorrents=Siirrot 
-TableColumn.header.name=Nimi
-TableColumn.header.size=Koko
-TableColumn.header.done=Valmiina
-TableColumn.header.done.info=Latauksen valmistuminen prosenteissa.
-TableColumn.header.status=Tila
-TableColumn.header.status.info=Torrent-tiedoston tila
-TableColumn.header.seeds=L\u00e4hteet
-TableColumn.header.seeds.info=Yhdistettyjen l\u00e4hteiden lukum\u00e4\u00e4r\u00e4 (suluissa lukum\u00e4\u00e4r\u00e4 kaikkiaan).
-TableColumn.header.peers=Lataajat
-TableColumn.header.peers.info=Yhdistettyjen lataajien lukum\u00e4\u00e4r\u00e4 (suluissa lukum\u00e4\u00e4r\u00e4 kaikkiaan).
-TableColumn.header.completed=Valmiit
-TableColumn.header.completed.info=K\u00e4ytt\u00e4jien lukum\u00e4\u00e4r\u00e4, jotka ovat seurantapalvelimen mukaan saaneet latauksen valmiiksi.
-TableColumn.header.downspeed=Latausnopeus
-TableColumn.header.upspeed=L\u00e4hetysnopeus
-TableColumn.header.eta=Valm.aika
-TableColumn.header.tracker=Seurantapalvelimen tila 
-TableColumn.header.tracker.info=Seurantapalvelimen tila.
-TableColumn.header.trackernextaccess=Seuraava p\u00e4ivitys
-TableColumn.header.trackernextaccess.info=J\u00e4ljell\u00e4 oleva aika seurantapalvelimen seuraavaan p\u00e4ivitykseen.
-TableColumn.header.priority=Prioriteetti
-TableColumn.header.priority.info=M\u00e4\u00e4rittelee torrent-tiedostolle varattavan l\u00e4hetysnopeuden.
-TableColumn.header.seeds.fullcopycalc=%2 oletettua t\u00e4ytt\u00e4 kopiota %1 lataajaa kohti
-MyTorrentsView.menu.showdetails=&N\u00e4yt\u00e4 tarkemmat tiedot 
-MyTorrentsView.menu.showdownloadbar=N&\u00e4yt\u00e4 seurantapalkki 
-MyTorrentsView.menu.open=Avaa 
-MyTorrentsView.menu.setpriority=Aseta p&rioriteetti 
-MyTorrentsView.menu.setpriority.high=&Korkea 
-MyTorrentsView.menu.setpriority.low=&Alhainen 
-MyTorrentsView.menu.start=K\u00e4ynnist\u00e4
-MyTorrentsView.menu.stop=P&ys\u00e4yt\u00e4 
-MyTorrentsView.menu.remove=&Poista 
-MyTorrentsView.menu.changeTracker=&Lis\u00e4\u00e4 uusi seurantapalvelin
-TrayWindow.menu.exit=&Lopeta 
-TrayWindow.menu.show=&N\u00e4yt\u00e4 Vuze
-SystemTray.menu.exit=&Lopeta 
-SystemTray.menu.closealldownloadbars=&Sulje kaikki seurantapalkit 
-SystemTray.menu.open_global_transfer_bar=N\u00e4yt\u00e4 Siirrot-palkki
-SystemTray.menu.show=&N\u00e4yt\u00e4 Vuze
-PeersView.ip=IP-osoite
-PeersView.ip.info=K\u00e4ytt\u00e4j\u00e4n IP-osoite.
-PeersView.port=Portti
-PeersView.port.info=K\u00e4ytetty portti.
-PeersView.T=Tyyppi
-PeersView.T.info=Yhteyden muodostuminen: L (sin\u00e4 muodostit) tai R (k\u00e4ytt\u00e4j\u00e4 muodosti).
-PeersView.T.L.tooltip=Sin\u00e4 muodostit yhteyden.
-PeersView.T.R.tooltip=K\u00e4ytt\u00e4j\u00e4 muodosti yhteyden.
-PeersView.I1=Kiinnostus (sin\u00e4 kiinnostunut)
-PeersView.I1.info=Sin\u00e4 olet kiinnostunut toisen k\u00e4ytt\u00e4j\u00e4n osista.
-PeersView.C1=Estetty
-PeersView.C1.info=K\u00e4ytt\u00e4j\u00e4 est\u00e4\u00e4 sinua lataamasta h\u00e4nelt\u00e4.
-PeersView.pieces=Osat
-PeersView.downloadspeed=Latausnopeus
-PeersView.download=Ladattu
-PeersView.I2=Kiinnostus (K\u00e4ytt\u00e4j\u00e4 kiinnostunut)
-PeersView.I2.info=Toinen k\u00e4ytt\u00e4j\u00e4 on kiinnostunut sinun osistasi.
-PeersView.C2=Estet\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4\u00e4
-PeersView.C2.info=Sin\u00e4 est\u00e4t k\u00e4ytt\u00e4j\u00e4\u00e4 lataamasta sinulta.
-PeersView.uploadspeed=L\u00e4hetysnopeus
-PeersView.uploadspeed.info=L\u00e4hetysnopeus k\u00e4ytt\u00e4j\u00e4lle.
-PeersView.upload=L\u00e4hetetty
-PeersView.upload.info=L\u00e4hetetty m\u00e4\u00e4r\u00e4.
-PeersView.statup=Arvio
-PeersView.statup.info=Arvioitu l\u00e4hetysnopeus, jolla k\u00e4ytt\u00e4j\u00e4 pystyy l\u00e4hett\u00e4m\u00e4\u00e4n tietoa.
-PeersView.S=Siirtoeste
-PeersView.S.info=Manuaalisesti tai autom. estetty, jos ei l\u00e4hetet\u00e4 riitt\u00e4v\u00e4n nopeasti.
-PeersView.downloadspeedoverall=K\u00e4ytt\u00e4j\u00e4nopeus
-PeersView.optunchoke=Optimistinen vapautus
-PeersView.client=Asiakasohjelma
-PeersView.client.info=K\u00e4ytt\u00e4j\u00e4n BitTorrent-asiakasohjelma.
-PeersView.menu.snubbed=&Estetty 
-PeersView.title.short=Yhteydet 
-PeersView.title.full=Yhteydet 
-AllPeersView.title.full=Kaikki yhteydet
-ConfigView.section.files=Tiedostot 
-ConfigView.label.usefastresume=K\u00e4yt\u00e4 nopeaa latauksen jatkamista 
-ConfigView.label.incrementalfile=Varaa levytilaa viimeiseen ladattuun osaan asti (vaaditaan Linux-k\u00e4yt\u00f6ss\u00e4, jos tallennetaan FAT32-osiolle)
-ConfigView.label.defaultsavepath=Tallenna tiedostot oletushakemistoon
-ConfigView.button.browse=&Selaa... 
-ConfigView.dialog.choosedefaultsavepath=Valitse oletustallennushakemisto 
-ConfigView.section.server=Yhteys
-ConfigView.section.global=Yleiset 
-ConfigView.label.disconnetseed=Katkaise yhteys l\u00e4hett\u00e4jiin latauksen valmistuttua 
-ConfigView.label.switchpriority=Vaihda alhaiselle prioriteetille latauksen valmistuttua
-ConfigView.label.maxdownloads=Yht\u00e4aikaisten latausten enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)\n - ei voi olla suurempi kuin aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4
-ConfigView.label.maxdownloads.tooltip=Enimm\u00e4ism\u00e4\u00e4r\u00e4 t\u00e4yttyy yleens\u00e4 normaalisti. S\u00e4\u00e4nt\u00f6\u00f6n on kuitenkin yksi poikkeus:\njos v\u00e4ltt\u00e4m\u00e4tt\u00e4 niin vaaditaan, voi ensisijainen, valmistunut torrent-tiedosto ottaa haltuunsa yhden latauspaikan.\nT\u00e4ll\u00f6in aktiivisten latausten m\u00e4\u00e4r\u00e4 siis v\u00e4henee yhdell\u00e4.
-ConfigView.label.maxactivetorrents=Aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)\n - uudet siirrot eiv\u00e4t k\u00e4ynnisty, jos enimm\u00e4ism\u00e4\u00e4r\u00e4 on t\u00e4ynn\u00e4
-ConfigView.label.priorityExtensions=Lataa ensisijaisesti\ntiedostotyypin ollessa\n(esim: .txt;.nfo;.jpg)
-ConfigView.section.transfer=Siirrot 
-ConfigView.label.maxuploads=L\u00e4hetyspaikkojen oletusenimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto
-ConfigView.label.maxuploadspeed=kB/s, enimm\u00e4isl\u00e4hetysnopeus (kaikki torrent-tiedostot, 0 = rajoittamaton)
-ConfigView.label.saveresumeinterval=P\u00e4ivit\u00e4 tiedot joka 
-ConfigView.unlimited=Rajoittamaton 
-ConfigView.section.display=Ulkoasu 
-ConfigView.label.opendetails=N\u00e4yt\u00e4 torrent-tiedoston tarkemmat tiedot automaattisesti
-ConfigView.label.openbar=N\u00e4yt\u00e4 seurantapalkki automaattisesti
-ConfigView.label.use_old_speed_menus=K\u00e4yt\u00e4 perinteist\u00e4 valikkotyyli\u00e4 lataus- ja l\u00e4hetysnopeuksien asettamiseen (vaatii uudelleenk\u00e4ynnistyksen)
-ConfigView.label.closetotray=Sulkeminen piilottaa ilmoitusalueelle
-ConfigView.label.minimizetotray=Pienent\u00e4minen piilottaa ilmoitusalueelle
-ConfigView.section.general=Yleiset 
-ConfigView.section.start=K\u00e4ynnistys 
-ConfigView.label.showsplash=N\u00e4yt\u00e4 aloitusruutu
-ConfigView.label.autoupdate=Avaa P\u00e4ivitysavustaja, kun uusi versio on saatavilla 
-ConfigView.label.openconsole=Avaa konsoli k\u00e4ynnistett\u00e4ess\u00e4 
-ConfigView.label.openconfig=Avaa asetukset k\u00e4ynnistett\u00e4ess\u00e4 
-ConfigView.label.startminimized=K\u00e4ynnist\u00e4 piilotettuna ilmoitusalueelle
-ConfigView.section.irc=IRC-yhteys
-ConfigView.label.ircwiki=Muista lukea s\u00e4\u00e4nn\u00f6t osoitteesta http://www.azureuswiki.com/index.php/Rules_for_IRC
-ConfigView.label.ircserver=Palvelin
-ConfigView.label.ircchannel=Kanava 
-ConfigView.label.irclogin=Nimimerkki 
-ConfigView.group.irctitle=IRC (reaaliaikainen tekninen tuki)
-ConfigView.boolean.ircsendinfo=Salli ongelmatilanteissa asetusten l\u00e4hett\u00e4minen (anonyymisti) kanavien yll\u00e4pit\u00e4jille
-ConfigView.boolean.irclog=Kirjaa kanavien tapahtumat lokitiedostoon (IRC_log.htm Vuzen asennushakemistossa)
-ConfigView.section.security=Suojaus
-ConfigView.label.password=Suojaa Vuzen k\u00e4ytt\u00f6\u00e4 salasanalla\n - kysyt\u00e4\u00e4n k\u00e4ynnistett\u00e4ess\u00e4 ja ilmoitusalueelta palautettaessa
-ConfigView.label.passwordconfirm=Salasana uudelleen
-ConfigView.label.passwordmatch=Salasanasuojaus k\u00e4yt\u00f6ss\u00e4: 
-ConfigView.label.passwordmatchnone=Ei 
-ConfigView.label.passwordmatchno=Ei - salasanat eiv\u00e4t t\u00e4sm\u00e4\u00e4 
-ConfigView.label.passwordmatchyes=Kyll\u00e4 
-ConfigView.button.save=Tallenna 
-ConfigView.title.short=Asetukset 
-ConfigView.title.full=Asetukset 
-ConfigView.title.full._mac=Asetukset
-ConsoleView.title.short=Konsoli 
-ConsoleView.title.full=Konsoli 
-FileItem.write=Kirjoitus
-FileItem.read=Luku
-FileItem.normal=Normaali 
-FileItem.high=Korkea 
-FileItem.donotdownload=Ei ladata 
-FileItem.delete=Poista
-FilesView.name=Nimi
-FilesView.name.fastRename=Nopea uudelleennime\u00e4minen
-FilesView.size=Koko
-FilesView.done=Ladattu
-FilesView.%=Valmiina
-FilesView.firstpiece=Ensimm\u00e4inen osa
-FilesView.numberofpieces=Osien lkm
-FilesView.pieces=Osat
-FilesView.mode=Tila
-FilesView.priority=Prioriteetti
-FilesView.menu.open=&Avaa 
-FilesView.menu.setpriority=Aseta &prioriteetti 
-FilesView.menu.setpriority.high=&Korkea 
-FilesView.menu.setpriority.normal=&Normaali 
-FilesView.menu.setpriority.skipped=&\u00c4l\u00e4 lataa 
-FilesView.title.short=Tiedostot 
-FilesView.title.full=Tiedostot 
-GeneralView.section.downloaded=Ladattu
-GeneralView.label.status.file=Tiedoston tila 
-GeneralView.label.status.pieces=Osien tila 
-GeneralView.section.availability=Saatavuus 
-GeneralView.label.status.pieces_available=Osien tila 
-GeneralView.section.transfer=Siirrot 
-GeneralView.section.info=Torrent-tiedosto
-GeneralView.title.short=Yleiset 
-GeneralView.title.full=Yleiset 
-GeneralView.label.timeelapsed=Aikaa kulunut: 
-GeneralView.label.remaining=J\u00e4ljell\u00e4: 
-GeneralView.label.downloaded=Ladattu: 
-GeneralView.label.downloadspeed=Latausnopeus: 
-GeneralView.label.maxuploads=L\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4: 
-GeneralView.label.maxuploads.tooltip=Lataajien enimm\u00e4ism\u00e4\u00e4r\u00e4, joille l\u00e4hetet\u00e4\u00e4n tietoa yht\u00e4aikaisesti.
-GeneralView.label.uploaded=L\u00e4hetetty: 
-GeneralView.label.uploadspeed=L\u00e4hetysnopeus: 
-GeneralView.label.seeds=L\u00e4hteit\u00e4: 
-GeneralView.label.peers=Lataajia: 
-GeneralView.label.completed=Valmiit:
-GeneralView.label.totalspeed=Nopeus yhteens\u00e4: 
-GeneralView.label.totalspeed.tooltip=Kaikkien yhdistettyjen k\u00e4ytt\u00e4jien nopeus yhteens\u00e4 ja keskim\u00e4\u00e4rin.
-GeneralView.label.averagespeed=keskim\u00e4\u00e4rin
-GeneralView.label.filename=Nimi: 
-GeneralView.label.totalsize=Koko yhteens\u00e4: 
-GeneralView.label.savein=Tallennushakemisto: 
-GeneralView.label.hash=Tiiviste: 
-GeneralView.label.numberofpieces=Osien m\u00e4\u00e4r\u00e4: 
-GeneralView.label.size=Osan koko: 
-GeneralView.label.tracker=Seurantapalvelimen tila: 
-GeneralView.label.updatein=Aikaa p\u00e4ivitykseen: 
-GeneralView.label.trackerurl=Seurantapalvelimen osoite: 
-GeneralView.label.trackerurlupdate=Tee p\u00e4ivitys 
-GeneralView.label.comment=Kommentti: 
-GeneralView.label.user_comment=Oma kommentti:
-GeneralView.label.status=Tila:
-ManagerItem.waiting=Odotetaan 
-ManagerItem.allocating=Varataan tilaa
-ManagerItem.checking=Tarkastetaan 
-ManagerItem.ready=Odotetaan muita torrent-tiedostoja
-ManagerItem.downloading=Ladataan 
-ManagerItem.seeding=L\u00e4hetet\u00e4\u00e4n 
-ManagerItem.stopped=Pys\u00e4ytetty 
-ManagerItem.error=Virhe 
-ManagerItem.high=Korkea 
-ManagerItem.low=Alhainen 
-MinimizedWindow.name=Nimi: 
-MinimizedWindow.all_transfers=Kaikki siirrot
-PiecesView.size=Koko
-PiecesView.numberofblocks=Lohkojen lkm
-PiecesView.blocks=Lohkot
-PiecesView.completed=Valmiina
-PiecesView.availability=Saatavuus
-PiecesView.reservedby=Varattu
-PiecesView.writers=Lohkojen l\u00e4hett\u00e4j\u00e4t
-PiecesView.title.short=Osat 
-PiecesView.title.full=Osat 
-SystemTray.tooltip.seeding=%1 l\u00e4hetet\u00e4\u00e4n, 
-SystemTray.tooltip.downloading=%1 ladataan, 
-DownloadManager.error.filenotfound=Tiedostoa ei l\u00f6ytynyt 
-DownloadManager.error.fileempty=Torrent-tiedosto tyhj\u00e4 
-DownloadManager.error.filetoobig=Torrent-tiedosto liian suuri
-DownloadManager.error.filewithouttorrentinfo=Torrent-tietoja ei l\u00f6ydy tiedostosta 
-DownloadManager.error.unsupportedencoding=Koodausta ei tueta
-DownloadManager.error.ioerror=Siirr\u00e4nt\u00e4virhe 
-DownloadManager.error.sha1=Algoritmi ei k\u00e4ytett\u00e4viss\u00e4 (SHA1)
-PeerManager.status.offline=Yhteysvirhe
-PeerManager.status.ok=OK 
-PeerManager.status.checking=Tarkastetaan 
-PeerManager.status.finished=Valmis 
-PeerManager.status.finishedin=Valmis, aikaa kului 
-MainWindow.upgrade.assistant=P\u00e4ivitysavustaja 
-MainWindow.upgrade.newerversion=Uudempi versio Vuzesta on ladattavissa 
-MainWindow.upgrade.explanation=T\u00e4m\u00e4 avustaja lataa ohjelman uuden version Vuzen asennushakemistoon ja k\u00e4ynnist\u00e4\u00e4 Vuzen uudelleen 
-MainWindow.upgrade.explanation.manual=Voit suorittaa p\u00e4ivityksen my\u00f6s manuaalisesti sulkemalla Vuzen, lataamalla uudemman .jar-version, \nkopioimalla sen Vuzen asennushakemistoosi ja k\u00e4ynnist\u00e4m\u00e4ll\u00e4 Vuzen uudestaan 
-MainWindow.upgrade.step1=Vaihe 1: Uusi versio ladataan 
-MainWindow.upgrade.step2=Vaihe 2: Vuze k\u00e4ynnistet\u00e4\u00e4n uudelleen, p\u00e4ivitys on suoritettu 
-MainWindow.upgrade.hint1=Vihje:\tPainamalla Valmis kaikki tapahtuu automaattisesti 
-MainWindow.upgrade.hint2=Vihje:\tJos haluat sulkea Vuzen my\u00f6hemmin, paina nyt Peruuta ja\n\tuudelleennime\u00e4 Azureus2-new.jar Azureus2.jar:ksi my\u00f6hemmin sulkemisen j\u00e4lkeen 
-MainWindow.upgrade.error.downloading.hint=Virhe:\tUutta versiota ei pystytty lataamaan, p\u00e4ivit\u00e4 manuaalisesti 
-MainWindow.upgrade.section.info=Uusi versio saatavilla 
-MainWindow.upgrade.section.manual=Manuaalinen p\u00e4ivitys 
-MainWindow.upgrade.section.automatic=Automaattinen p\u00e4ivitys 
-MainWindow.upgrade.tooltip.progressbar=T\u00e4st\u00e4 n\u00e4et latauksen edistymisen 
-Button.next=Seuraava 
-Button.finish=Valmis 
-Button.cancel=&Peruuta 
-LocaleUtil.title=Valitse tiedoston koodaus 
-LocaleUtil.section.chooseencoding=Valitse koodaus tiedostonimelle
-LocaleUtil.label.chooseencoding=Valitse parhaiten sopiva koodaus:
-LocaleUtil.label.hint.doubleclick=Vihje: tuplaklikkaus rivill\u00e4 valitsee koodauksen ja sulkee ikkunan.
-LocaleUtil.label.checkbox.rememberdecision=K\u00e4yt\u00e4 samaa koodausta kaikille tiedostoille
-LocaleUtil.column.encoding=Koodaus 
-IrcClient.copyright=K\u00e4yt\u00f6ss\u00e4 PircBot Java IRC API - http://www.jibble.org/pircbot.php 
-IrcClient.connecting=Yhdistet\u00e4\u00e4n palvelimeen
-IrcClient.connected=Yhdistetty palvelimeen
-IrcClient.joining=Liityt\u00e4\u00e4n kanavalle 
-IrcClient.channel=Liitytty 
-IrcClient.joined=-kanavalle 
-IrcClient.error=Virhe 
-IrcClient.hasjoined=liittyi kanavalle 
-IrcClient.haskicked=poisti kanavalta k\u00e4ytt\u00e4j\u00e4n 
-IrcClient.hasleft=poistui kanavalta 
-IrcClient.nowknown=on nyt nimelt\u00e4\u00e4n 
-IrcClient.topicforchannel=Kanavan otsikko on: 
-IrcClient.disconnected=Yhteys katkesi palvelimeen
-IrcClient.noNick=Nimimerkki\u00e4 ei ole m\u00e4\u00e4ritelty. Aseta nimimerkkisi Asetuksissa kohdassa Lis\u00e4osat | IRC-yhteys. 
-IrcView.actionnotsupported=T\u00e4m\u00e4 komento ei ole k\u00e4ytett\u00e4viss\u00e4
-IrcView.clientsconnected=k\u00e4ytt\u00e4j\u00e4\u00e4 
-IrcView.privateto=K\u00e4ytt\u00e4j\u00e4lle 
-IrcView.privatefrom=K\u00e4ytt\u00e4j\u00e4lt\u00e4 
-IrcView.noticefrom=Tiedotus: 
-IrcView.errormsg=Virheellinen komento /msg : /msg k\u00e4ytt\u00e4j\u00e4 viesti
-IrcView.help=Toimivia komentoja ovat:\n . /help : n\u00e4ytt\u00e4\u00e4 t\u00e4m\u00e4n ohjeen\n . /nick | /name uusi_nimi : vaihtaa nimimerkkisi\n . /me toiminto : l\u00e4hett\u00e4\u00e4 toiminnon (mit\u00e4 olet tekem\u00e4ss\u00e4)\n . /msg k\u00e4ytt\u00e4j\u00e4 viesti : l\u00e4hett\u00e4\u00e4 yksityisviestin m\u00e4\u00e4ritetylle k\u00e4ytt\u00e4j\u00e4lle\n . /r viesti : vastaa viimeisimp\u00e4\u00e4n yksityisviestiin\n . /join #kanava : vaihtaa m\u00e4\u00e4ritetylle kanavalle 
-PasswordWindow.title=Vuze lukittu 
-PasswordWindow.passwordprotected=Vuze on salasanasuojatussa tilassa.\nJotta voisit k\u00e4ytt\u00e4\u00e4 Vuzea, anna salasana:
-TrackerChangerWindow.title=Lis\u00e4\u00e4 seurantapalvelin
-TrackerChangerWindow.newtracker=Anna uuden seurantapalvelimen osoite 
-PeersView.discarded=Hyl\u00e4tty
-PeersView.discarded.info=Ladattu tietom\u00e4\u00e4r\u00e4, jota ei tarvita.
-discarded=hyl\u00e4tty 
-MyTorrentsView.menu.move=Sii&rr\u00e4 
-MyTorrentsView.menu.moveUp=&Yl\u00f6s 
-MyTorrentsView.menu.moveDown=&Alas 
-GeneralView.label.hashfails=Korruptoituneet osat: 
-GeneralView.label.shareRatio=Jakosuhde: 
-ConfigView.section.downloadManagement=Latausten hallinta 
-ConfigView.label.startRatioPeers=Aloita l\u00e4hett\u00e4minen, kun on v\u00e4hemm\u00e4n kuin yksi l\u00e4hde kohti
-ConfigView.text.neverStop=Ei koskaan 
-ConfigView.text.neverStart=Ei koskaan 
-ConfigView.text.peers=lataajaa
-ConfigView.label.checkOncompletion=Tarkasta osat uudelleen, kun lataus on valmistunut
-wizard.title=Luo torrent-tiedosto 
-wizard.previous=Edellinen
-wizard.next=Seuraava
-wizard.finish=Valmis 
-wizard.mode=Seurantapalvelin/kohteen muoto 
-wizard.tracker=Seurantapalvelin: 
-wizard.invalidurl=Antamasi osoite ei ole kelvollinen.
-wizard.singlefile=Yksitt\u00e4inen tiedosto 
-wizard.singlefile.help=Luo torrent-tiedosto yksitt\u00e4isest\u00e4 tiedostosta 
-wizard.directory=Hakemisto 
-wizard.directory.help=Luo torrent-tiedosto hakemistosta 
-wizard.choosefile=Valitse tiedosto 
-wizard.file=Tiedosto 
-wizard.browse=Selaa... 
-wizard.choosedirectory=Valitse hakemisto 
-wizard.invalidfile=Kelpaamaton tiedosto! 
-wizard.invaliddirectory=Kelpaamaton hakemisto! 
-wizard.torrentFile=Torrent-tiedosto 
-wizard.choosetorrent=Valitse luotavan torrent-tiedoston asetukset
-wizard.information=Info 
-wizard.notimplemented=Ei viel\u00e4 toteutettu 
-wizard.progresstitle=Luodaan torrent-tiedostoa 
-wizard.savingfile=Tallennetaan torrent-tiedostoa... 
-wizard.filesaved=Torrent-tiedosto tallennettu. 
-wizard.close=Sulje 
-Torrent.create.progress.piecelength=Osan koko: 
-Torrent.create.progress.piececount=Osien lukum\u00e4\u00e4r\u00e4: 
-Torrent.create.progress.totalfilesize=Koko yhteens\u00e4: 
-Torrent.create.progress.totalfilecount=Tiedostojen m\u00e4\u00e4r\u00e4 yhteens\u00e4: 
-Torrent.create.progress.parsingfiles=J\u00e4sennell\u00e4\u00e4n tiedostoja
-Torrent.create.progress.hashing=Lasketaan tiedostoille tiivisteet
-MainWindow.upgrade.downloadingfrom=Ladataan kohteesta: 
-MainWindow.menu.view.ipFilter=&IP-suotimet
-ConfigView.section.ipfilter=IP-suotimet
-ConfigView.section.ipfilter.description=Kuvaus
-ConfigView.section.ipfilter.start=Ensimm\u00e4inen IP-osoite
-ConfigView.section.ipfilter.end=Viimeinen IP-osoite
-ConfigView.section.ipfilter.add=Lis\u00e4\u00e4
-ConfigView.section.ipfilter.remove=Poista
-ConfigView.section.ipfilter.edit=Muokkaa
-ConfigView.section.ipfilter.save=Tallenna
-ConfigView.section.ipfilter.editFilter=Muokkaa suodinta
-ConfigView.section.ipfilter.enable=IP-suotimet k\u00e4yt\u00f6ss\u00e4
-PeersView.menu.close=&Sulje 
-seedmore.title=Jakosuhde alhainen
-seedmore.shareratio=T\u00e4m\u00e4n torrent-tiedoston jakosuhde on 
-seedmore.uploadmore=Alle 100 %:n jakosuhde ei ole hyv\u00e4ksi BitTorrent-verkolle.\nOn suositeltavaa, ett\u00e4 l\u00e4hett\u00e4mist\u00e4 jatkettaisiin pidemp\u00e4\u00e4n.\nHaluatko varmasti jatkaa? 
-ConfigView.label.showpopuponclose=Pyyd\u00e4 l\u00e4hett\u00e4mist\u00e4 lopetettaessa vahvistus, jos jakosuhde on pienempi kuin 1.0
-ConfigView.label.startNumSeeds=Aloita l\u00e4hett\u00e4minen, jos on v\u00e4hemm\u00e4n kuin\n - ohittaa kaikki muut s\u00e4\u00e4nn\u00f6t
-ConfigView.label.seeds=l\u00e4hett\u00e4j\u00e4\u00e4 
-ConfigView.section.seeding=Tiedostojen l\u00e4hett\u00e4minen 
-MyTorrentsView.menu.removeand=Po&ista ja 
-MyTorrentsView.menu.removeand.deletetorrent=tuhoa &torrent-tiedosto 
-MyTorrentsView.menu.removeand.deletedata=tuhoa &kohdetiedostot
-MyTorrentsView.menu.removeand.deleteboth=tuhoa &molemmat 
-deletedata.title=Varoitus! 
-deletedata.message1=Haluatko varmasti poistaa pysyv\u00e4sti '%1'?\n
-deletedata.noprompt=\u00c4l\u00e4 kysy t\u00e4t\u00e4 uudelleen
-MainWindow.menu.file.configure=&Ohjattu asetusten m\u00e4\u00e4rittely...
-configureWizard.title=Ohjattu asetusten m\u00e4\u00e4rittely 
-configureWizard.welcome.title=Tervetuloa ohjattuun asetusten m\u00e4\u00e4rittelyyn
-configureWizard.welcome.message=T\u00e4m\u00e4 ohjattu toiminto auttaa sinua asettamaan Vuzen t\u00e4rkeimm\u00e4t asetukset k\u00e4ytt\u00f6kuntoon. Voit muokata asetuksia my\u00f6hemmin tarkemmin valitsemalla Ty\u00f6kalut-valikosta Asetukset. 
-configureWizard.transfer.title=Yhteysasetukset 
-configureWizard.transfer.hint=Vihje: \u00c4l\u00e4 k\u00e4yt\u00e4 t\u00e4ytt\u00e4 l\u00e4hetyskapasiteettia (hidastaa latauksia).
-configureWizard.transfer.message=Valitse alta yhteysasetuksesi. Muista, ett\u00e4 pieni l\u00e4hetysnopeus johtaa samalla pieniin latausnopeuksiin. Samoin voi k\u00e4yd\u00e4, jos lataat liian montaa torrent-tiedostoa yht\u00e4aikaisesti (jolloin torrent-kohtainen l\u00e4hetysnopeus j\u00e4\u00e4 pieneksi). Suositus ehdottomaksi l\u00e4hetysnopeuden alarajaksi on 5 KB/s (yht\u00e4 torrent-tiedostoa kohti). Eli yleisesti: mit\u00e4 nopeammin l\u00e4het\u00e4t, sit\u00e4 nopeammin lataat ( [...]
-configureWizard.transfer.connection=Yhteystyyppi 
-configureWizard.transfer.connection.0=Mukautettu
-configureWizard.transfer.connection.1=Modeemi
-configureWizard.transfer.connection.2=Laajakaista x/128 kbps
-configureWizard.transfer.connection.3=Laajakaista x/256 kbps
-configureWizard.transfer.connection.4=Laajakaista x/384 kbps
-configureWizard.transfer.connection.5=Laajakaista x/512 kbps
-configureWizard.transfer.connection.6=Laajakaista x/768 kbps
-configureWizard.transfer.connection.7=Laajakaista x/1024 kbps
-configureWizard.transfer.maxUpSpeed=Enimm\u00e4isl\u00e4hetysnopeus 
-configureWizard.transfer.maxActiveTorrents=Aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4 
-configureWizard.transfer.maxDownloads=Yht\u00e4aikaisten latausten enimm\u00e4ism\u00e4\u00e4r\u00e4
-configureWizard.transfer.maxUploadsPerTorrent=L\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4/torrent
-configureWizard.nat.title=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
-configureWizard.nat.message=Jotta Vuze saavuttaisi parhaat nopeudet, tulisi siihen voida muodostaa yhteys ulkoap\u00e4in esteitt\u00e4. Alla voit testata ja/tai vaihtaa sis\u00e4\u00e4ntulevan liikenteen porttia.\n\nHuom.! T\u00e4m\u00e4 ty\u00f6kalu testaa vain TCP-yhteyksien toimivuutta. Hajautetun tietokannan (DHT) k\u00e4ytt\u00e4minen vaatii my\u00f6s avoimen UDP-portin sis\u00e4\u00e4ntulevalle liikenteelle. Jos palomuuri est\u00e4\u00e4 t\u00e4m\u00e4n liikenteen, siit\u00e4 ilmoi [...]
-configureWizard.nat.test=Testaa 
-configureWizard.nat.testing=Testataan porttia
-configureWizard.nat.ok=OK 
-configureWizard.nat.ko=NAT-ongelma havaittu
-configureWizard.nat.unable=Testausta ei voitu suorittaa: joko...\n - porttinumero on virheellinen\n - tai porttia ei voitu k\u00e4ytt\u00e4\u00e4 (toinen sovellus ehk\u00e4 jo k\u00e4ytt\u00e4\u00e4 ko. porttia)
-configureWizard.file.title=Torrent-tiedostot ja nopea latauksen jatkaminen
-configureWizard.file.message1=Vuze tallentaa avatut torrent-tiedostot (luo kopiot) seuraavaan hakemistoon: 
-configureWizard.file.path=Tallennushakemisto
-configureWizard.file.browse=Selaa... 
-configureWizard.file.message2=Vuze voi jatkaa tiedostojen lataamista v\u00e4litt\u00f6m\u00e4sti lis\u00e4\u00e4m\u00e4ll\u00e4 t\u00e4h\u00e4n toimintoon liittyvi\u00e4 tietoja torrent-tiedostoihin (huomattavasti nopeampaa, kuin jos ladatut osat k\u00e4yt\u00e4isiin yksitellen l\u00e4pi jatkettaessa lataamista). T\u00e4ll\u00e4 menetelm\u00e4ll\u00e4 Vuze osaa my\u00f6s jatkaa yksitt\u00e4isten osien lataamista, jotka ovat j\u00e4\u00e4neet kesken. 
-configureWizard.file.fastResume=K\u00e4yt\u00e4 nopeaa latauksen jatkamista 
-configureWizard.file.invalidPath=Kelpaamaton hakemisto!
-configureWizard.finish.title=Ohjattu asetusten m\u00e4\u00e4rittely suoritettu loppuun 
-configureWizard.finish.message=Vuzen v\u00e4ltt\u00e4m\u00e4tt\u00f6mimm\u00e4t perusasetukset ovat nyt asetettu ja Vuze on k\u00e4ytt\u00f6kunnossa.\n\nMuista, ett\u00e4 voit palata Ohjattuun asetusten m\u00e4\u00e4rittelyyn milloin tahansa k\u00e4ynnist\u00e4m\u00e4ll\u00e4 sen Ty\u00f6kalut-valikosta. Yksityiskohtaisempia asetuksia voit tarkastella valitsemalla Asetukset samaisesta valikosta.
-wizard.close.confirmation=Vahvistus 
-wizard.close.message=Haluatko, ett\u00e4 t\u00e4m\u00e4 asetustenm\u00e4\u00e4rittelytoiminto n\u00e4ytet\u00e4\u00e4n ensi kerralla, kun Vuze k\u00e4ynnistet\u00e4\u00e4n? 
-exportTorrentWizard.title=Vie torrent-tiedosto XML-muotoon
-exportTorrentWizard.torrentfile.title=K\u00e4sitelt\u00e4v\u00e4n torrent-tiedoston valitseminen 
-exportTorrentWizard.torrentfile.message=Valitse viet\u00e4v\u00e4 torrent-tiedosto 
-exportTorrentWizard.torrentfile.path=Kohde
-exportTorrentWizard.torrentfile.browse=Selaa... 
-exportTorrentWizard.torrentfile.invalidPath=Kelpaamaton torrent-tiedosto 
-exportTorrentWizard.exportfile.title=Kohdetiedoston valitseminen 
-exportTorrentWizard.exportfile.message=Anna luotavalle XML-tiedostolle nimi ja sijainti 
-exportTorrentWizard.exportfile.path=Kohde
-exportTorrentWizard.exportfile.browse=Selaa... 
-exportTorrentWizard.exportfile.invalidPath=Kelpaamaton kohdetiedosto 
-exportTorrentWizard.finish.title=Torrent-tiedoston vienti suoritettu loppuun 
-exportTorrentWizard.finish.message=XML-tiedosto luotiin onnistuneesti.
-exportTorrentWizard.process.inputfilebad.title=Torrent-tiedosto on virheellinen 
-exportTorrentWizard.process.inputfilebad.message=L\u00e4hdetiedostoa k\u00e4sitelt\u00e4ess\u00e4 tapahtui virhe: 
-exportTorrentWizard.process.outputfileexists.title=Tiedosto jo olemassa 
-exportTorrentWizard.process.outputfileexists.message=Kohdetiedosto on jo olemassa, korvataanko?
-exportTorrentWizard.process.torrentfail.title=Torrent-tiedostosta ei voida lukea tietoja 
-exportTorrentWizard.process.exportfail.title=Torrent-tiedoston vieminen ei onnistu 
-exportTorrentWizard.process.unknownfail.title=Tuntematon virhe 
-importTorrentWizard.title=Tuo torrent-tiedosto XML-muodosta
-importTorrentWizard.torrentfile.title=Kohdetiedoston valitseminen 
-importTorrentWizard.torrentfile.message=Anna luotavalle torrent-tiedostolle nimi ja sijainti 
-importTorrentWizard.torrentfile.path=Kohde
-importTorrentWizard.torrentfile.browse=Selaa... 
-importTorrentWizard.torrentfile.invalidPath=Kelpaamaton torrent-tiedosto 
-importTorrentWizard.importfile.title=K\u00e4sitelt\u00e4v\u00e4n XML-tiedoston valitseminen 
-importTorrentWizard.importfile.message=Valitse tuotava XML-tiedosto 
-importTorrentWizard.importfile.path=Kohde
-importTorrentWizard.importfile.browse=Selaa... 
-importTorrentWizard.importfile.invalidPath=Kelpaamaton l\u00e4hdetiedosto 
-importTorrentWizard.finish.title=Torrent-tiedoston tuonti suoritettu loppuun 
-importTorrentWizard.finish.message=Torrent-tiedosto luotiin onnistuneesti 
-importTorrentWizard.process.inputfilebad.title=XML-tiedosto on virheellinen 
-importTorrentWizard.process.inputfilebad.message=L\u00e4hdetiedostoa k\u00e4sitelt\u00e4ess\u00e4 tapahtui virhe: 
-importTorrentWizard.process.outputfileexists.title=Tiedosto jo olemassa 
-importTorrentWizard.process.outputfileexists.message=Kohdetiedosto on jo olemassa, korvataanko? 
-importTorrentWizard.process.torrentfail.title=Torrent-tiedoston luominen ei onnistu 
-importTorrentWizard.process.importfail.title=Torrent-tiedoston tuominen ei onnistu 
-importTorrentWizard.process.unknownfail.title=Tuntematon virhe 
-ConfigView.label.bindip=Sido paikalliseen IP-osoitteeseen tai liit\u00e4nt\u00e4\u00e4n
-ConfigView.label.xfs.allocation=Varaa levytilaa k\u00e4ytt\u00e4m\u00e4ll\u00e4 XFS-tiedostoj\u00e4rjestelm\u00e4n varaustapaa
-ConfigView.label.xfs.allocation.tooltip=Varmista, ett\u00e4 tiedosto /usr/sbin/xfs_io l\u00f6ytyy j\u00e4rjestelm\u00e4st\u00e4. Useimmissa Linux-jakeluversioissa ko. tiedosto asentuu xfsprogs-paketin mukana.
-xfs.allocation.xfs_io.not.found=XFS-levytilanvaraus ep\u00e4onnistui, sill\u00e4 tiedostoa /usr/sbin/xfs_io ei voitu suorittaa. Varmista, ett\u00e4 se l\u00f6ytyy j\u00e4rjestelm\u00e4st\u00e4si. Alkuper\u00e4inen virhe oli: "%1".
-ConfigView.label.zeronewfiles=Varaa levytilaa tiedostojen valmiin koon verran t\u00e4ytt\u00e4m\u00e4ll\u00e4 tila nollilla
-ConfigView.label.zeronewfiles.tooltip=V\u00e4hent\u00e4\u00e4 kiintolevyn sis\u00e4ll\u00f6n pirstoutumista.
-ConfigView.section.stats=Tilastot 
-ConfigView.section.stats.enable=Tilastointitoiminto k\u00e4yt\u00f6ss\u00e4 
-ConfigView.section.stats.defaultsavepath=Tallennushakemisto 
-ConfigView.section.stats.choosedefaultsavepath=Valitse tallennushakemisto tilastoille 
-ConfigView.section.stats.savefreq=Tallennuksen aikav\u00e4li 
-ConfigView.section.stats.hours=h 
-ConfigView.section.stats.seconds=s
-ConfigView.section.stats.savefile=Tiedostonimi 
-ConfigView.section.stats.graph_update_dividers=N\u00e4yt\u00e4 pystysuuntainen ositusviiva aina 60 p\u00e4ivityksen v\u00e4lein
-MyTorrentsView.menu.export=&XML-muotoon...
-MyTorrentsView.menu.host=Aseta &seurantaan
-ManagerItem.finishing=Viimeistell\u00e4\u00e4n 
-ConfigView.dialog.choosedefaulttorrentpath=Valitse tallennushakemisto torrent-tiedostoille 
-ConfigView.dialog.choosemovepath=Valitse hakemisto, johon siirret\u00e4\u00e4n 
-ConfigView.label.movecompleted=Siirr\u00e4 valmistuneet tiedostot (latauksen j\u00e4lkeen)
-ConfigView.label.moveremoved=Siirr\u00e4 valmistuneet tiedostot (poistettaessa)
-ConfigView.label.savetorrents=Tallenna torrent-tiedostot 
-MainWindow.menu.view.mytracker=Seuranta&palvelin
-MyTrackerView.title.full=Seurantapalvelin
-MyTrackerView.name=Nimi
-MyTrackerView.tracker=Seurantapalvelin
-MyTrackerView.status=Tila
-MyTrackerView.status.started=Seurataan
-MyTrackerView.status.stopped=Pys\u00e4ytetty 
-MyTrackerView.peers=Lataajat
-MyTrackerView.seeds=L\u00e4hteet
-MyTrackerView.announces=P\u00e4ivitykset
-MyTrackerView.uploaded=L\u00e4hetetty
-MyTrackerView.downloaded=Ladattu
-MyTrackerView.left=J\u00e4ljell\u00e4
-ConfigView.section.style=K\u00e4ytt\u00f6liittym\u00e4
-ConfigView.label.set_ui_transfer_speeds=Ohita valittavat siirtonopeusrajoitukset
-ConfigView.label.set_ui_transfer_speeds.description=Voit asettaa manuaalisesti tilarivin ja ilmoitusalueen valikoista valittavissa olevat lataus- ja l\u00e4hetysnopeusrajoitusarvot.\nErota arvot toisistaan pilkulla.
-ConfigView.label.set_ui_transfer_speeds.description.download=Aseta arvot latausnopeudelle (KB/s)
-ConfigView.label.set_ui_transfer_speeds.description.upload=Aseta arvot l\u00e4hetysnopeudelle (KB/s)
-ConfigView.section.style.useCustomTabs=K\u00e4yt\u00e4 suljettavia v\u00e4lilehti\u00e4 (vaatii uudelleenk\u00e4ynnistyksen)
-MainWindow.menu.view.plugins=&Lis\u00e4osat
-fileDownloadWindow.saveTorrentIn=Tallenna torrent-tiedosto hakemistoon
-fileDownloadWindow.title=Torrent-tiedoston lataaminen
-fileDownloadWindow.downloading=Ladataan kohdetta:
-fileDownloadWindow.status=Tila:
-fileDownloadWindow.state_initializing=Aloitetaan
-fileDownloadWindow.state_downloading=Ladataan
-fileDownloadWindow.state_error=Virhe:
-MainWindow.menu.file.open.url=Torrent-tiedosto &URL-osoitteesta...
-MainWindow.menu.file.open.url.keybinding=Meta+U
-openUrl.title=Avaa torrent-tiedosto osoitteesta
-openUrl.url=URL-osoite:
-MyTorrentsView.menu.host.error.title=Seurantaan asettaminen ep\u00e4onnistui
-MyTorrentsView.menu.host.error.message=Seuraava virhe esiintyi asetettaessa torrent-tiedostoa seurantaan
-ConfigView.section.tracker=Seuranta
-ConfigView.section.tracker.pollinterval=Tietojen kysymisen aikav\u00e4li sekunneissa
-ConfigView.section.tracker.publishenable=N\u00e4yt\u00e4 seurattavat/julkistetut torrent-tiedostot www-sivulla seurantapalvelimen URL-osoitteessa
-ConfigView.section.tracker.ip=Seurantapalvelimen ulkoinen IP-osoite
-ConfigView.section.style.enableXPStyle=K\u00e4yt\u00e4 Windows XP -tyyli\u00e4 (vaatii uudelleenk\u00e4ynnistyksen)
-IPChecker.external.service.dyndns.url=http://www.dyndns.org
-IPChecker.external.service.dyndns.description=Dynamic DNS Network Services, LLC.
-ConfigView.section.tracker.checkip=Hae osoite automaattisesti...
-ipCheckerWizard.title=IP-osoitteen tarkastaminen
-ipCheckerWizard.service=Palvelu
-ipCheckerWizard.chooseService=Valitse palvelu, jonka avulla IP-osoite tarkastetaan.
-ipCheckerWizard.explanations=T\u00e4m\u00e4n toiminnon avulla voit selvitt\u00e4\u00e4 ulkoisen IP-osoitteesi, jota tarvitaan oman seurantapalvelimen k\u00e4ytt\u00e4misess\u00e4.\n\nJos IP-osoitteesi on dynaaminen (vaihtuva), on suositeltavaa k\u00e4ytt\u00e4\u00e4 dynaamisen tuen tarjoavaa verkkotunnusj\u00e4rjestelm\u00e4palvelua. Muutamia t\u00e4llaisia palveluja on listattu alla, k\u00e4y rekister\u00f6itym\u00e4ss\u00e4 johonkin niist\u00e4 (jos kyseinen palvelu mahdollistaa t\u00e [...]
-ipCheckerWizard.service.description=Kuvaus:
-ipCheckerWizard.service.url=Sivusto:
-ipCheckerWizard.progresstitle=Tarkastetaan IP-osoitetta
-ipCheckerWizard.checkComplete=K\u00e4ytett\u00e4v\u00e4 IP-osoite: 
-ipCheckerWizard.checkFailed=Tarkastus ep\u00e4onnistui, syy:
-wizard.tracker.local=Vuzen oma sis\u00e4inen seurantapalvelin
-wizard.tracker.external=Ulkoinen seurantapalvelin
-wizard.tracker.howToLocal=\tVaatii k\u00e4ytt\u00f6\u00f6noton asetuksista!
-wizard.announceUrl=P\u00e4ivitysosoite:
-IPChecker.external.service.discoveryvip.url=http://ip.discoveryvip.com
-IPChecker.external.service.discoveryvip.description=Ainoastaan IP-osoitteen tarkastus.
-IPChecker.external.httpinvalidresponse=Virheellinen HTTP-vastaus
-IPChecker.external.loadingwebpage=Ladataan sivua
-IPChecker.external.analysingresponse=Analysoidaan vastausta
-IPChecker.external.addressextracted=Selvitetty IP-osoite
-IPChecker.external.httploadfail=Sivua ei voitu ladata
-IPChecker.external.timeout=Pyynt\u00f6 aikakatkaistiin
-IPChecker.external.ipnotfound=IP-osoitetta ei l\u00f6ytynyt
-ConfigView.section.tracker.pollintervalmin=V\u00e4himm\u00e4isaika
-ConfigView.section.tracker.pollintervalmax=Enimm\u00e4isaika
-ConfigView.section.tracker.pollintervalincby=Kasvata aikaa
-ConfigView.section.tracker.pollintervalincper=sekunnilla n\u00e4in monen k\u00e4ytt\u00e4j\u00e4n j\u00e4lkeen
-splash.loadingImages=Ladataan kuvia
-splash.initializeGui=Alustetaan graafista k\u00e4ytt\u00f6liittym\u00e4\u00e4
-splash.openViews=Avataan v\u00e4lilehti\u00e4
-splash.plugin=Ladataan lis\u00e4osaa -
-configureWizard.nat.tooManyPorts=Liian monta testattavaa porttia (enint\u00e4\u00e4n 9)
-ConfigView.section.color=V\u00e4riteema
-MyTorrentsView.menu.publish=&Julkaise
-MyTrackerView.status.published=Julkistettu
-MyTrackerView.completed=Valmiina
-MainWindow.menu.file.open.torrentnodefault=Torrent-tiedosto... (m\u00e4\u00e4rit\u00e4 lataushakemisto)
-wizard.comment=Kommentti
-ConfigView.label.movetorrent=Siirr\u00e4 torrent-tiedosto
-ConfigView.label.movepartialdownloads=Siirr\u00e4, vaikka tiedoston tila olisikin "Ei ladata"
-ConfigView.label.subdir_is_in_default=Siirrett\u00e4ess\u00e4 tiedostoja oletustallennushakemistosta siirr\u00e4 my\u00f6s sen alihakemistojen tiedostot
-ConfigView.section.file.decoder.label=Kysytt\u00e4ess\u00e4 torrent-tiedoston koodausta k\u00e4yt\u00e4 oletuksena
-ConfigView.section.file.decoder.nodecoder=Ei mit\u00e4\u00e4n
-IPChecker.external.service.no-ip.url=http://www.no-ip.com
-IPChecker.external.service.no-ip.description=Dynaamisen ja staattisen tuen tarjoava DNS-palvelu\n(ei IP-osoitteen tarkastusta ilmaiseksi).
-ConfigView.section.tracker.publicenable=Salli ulkoiset torrent-tiedostot
-ConfigView.label.playdownloadspeech=Ilmoita puhuen latauksen valmistumisesta
-ConfigView.label.playdownloadspeech.info=Puhepalvelu toimii t\u00e4ll\u00e4 hetkell\u00e4 parhaiten englanniksi.
-#
-# Tooltips
-#
-GeneralView.label.status.pieces_available.tooltip=Kuvastaa osien saatavilla olevien kopioiden m\u00e4\u00e4r\u00e4\u00e4 k\u00e4ytt\u00e4jien keskuudessa.\nJos oikealla oleva luku on alle yhden, kaikkia osia eli tiedosto(j)a kokonaisena ei ole saatavilla.
-GeneralView.label.trackerurl.tooltip=Klikkaa kopioidaksesi seurantapalvelimen p\u00e4ivitysosoite leikep\u00f6yd\u00e4lle.
-GeneralView.label.trackerurlopen.tooltip=Klikkaa avataksesi seurantapalvelimen etusivu.
-#
-# 2.0.4.4
-#
-ConfigView.section.style.guiUpdate=P\u00e4ivit\u00e4 graafinen k\u00e4ytt\u00f6liittym\u00e4 (GUI) joka
-ConfigView.section.style.inactiveUpdate=P\u00e4ivit\u00e4 toimeton p\u00e4\u00e4ikkuna n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen
-ConfigView.section.style.graphicsUpdate=P\u00e4ivit\u00e4 graafiset palkit n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen
-ConfigView.section.style.reOrderDelay=J\u00e4rjest\u00e4 taulukot uudelleen n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen (0 = ei koskaan)
-ConfigView.section.style.reOrderDelay.never=Ei koskaan
-ConfigView.section.logging=Loki
-ConfigView.section.logging.enable=Kirjaa tapahtumat lokitiedostoon
-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
-ConfigView.section.tracker.passwordenableweb=K\u00e4yt\u00e4 salasanasuojausta seurantapalvelimen sivulla
-ConfigView.section.tracker.passwordenabletorrent=K\u00e4yt\u00e4 salasanasuojausta torrent-tiedostoissa
-ConfigView.section.tracker.username=K\u00e4ytt\u00e4j\u00e4tunnus
-ConfigView.section.tracker.password=Salasana
-columnChooser.title=N\u00e4ytett\u00e4v\u00e4t sarakkeet
-columnChooser.move=Voit vaihtaa sarakkeiden j\u00e4rjestyst\u00e4 raahaamalla ne haluamiisi kohtiin.
-columnChooser.apply=K\u00e4yt\u00e4
-columnChooser.columnname=Sarake
-columnChooser.columndescription=Kuvaus
-TableColumn.header.shareRatio=Jakosuhde
-MyTorrentsView.menu.editTableColumns=&Valitse n\u00e4ytett\u00e4v\u00e4t sarakkeet
-wizard.operationfailed=Toiminto ep\u00e4onnistui
-authenticator.title=Vahvista toiminto
-authenticator.realm=Asiakasohjelma
-authenticator.tracker=Seurantapalvelin
-authenticator.user=K\u00e4ytt\u00e4j\u00e4tunnus
-authenticator.password=Salasana
-ConfigView.label.allowSendVersion=L\u00e4het\u00e4 anonyymisti Vuzen versionumero ja satunnainen tunniste uutta versiota tarkastettaessa
-ConfigView.label.version.info.link=Katso t\u00e4st\u00e4 lis\u00e4tietoja l\u00e4hetett\u00e4vist\u00e4 tiedoista
-wizard.hint.mode=Vihje:\tVoit raahata ja pudottaa yksitt\u00e4isen tiedoston tai hakemiston\n\tt\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle valitaksesi kohteen.
-wizard.hint.file=Vihje:\tVoit valita yksitt\u00e4isen tiedoston my\u00f6s raahaamalla ja\n\tpudottamalla sen t\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle.
-wizard.hint.directory=Vihje:\tVoit valita yksitt\u00e4isen hakemiston my\u00f6s raahaamalla ja\n\tpudottamalla sen t\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle.
-MainWindow.menu.help.checkupdate=Tarkasta &p\u00e4ivitykset...
-TableColumn.header.down=Ladattu
-TableColumn.header.up=L\u00e4hetetty
-ConfigView.section.tracker.passwordenabletorrent.info=Vaatii yhteensopivan asiakasohjelman (kuten Vuzen)
-ConfigView.section.style.confirmationOnExit=Pyyd\u00e4 vahvistus lopetettaessa
-MainWindow.dialog.exitconfirmation.title=Lopeta Vuze
-MainWindow.dialog.exitconfirmation.text=Haluatko varmasti sulkea Vuzen?
-SystemTray.menu.stopalltransfers=&Pys\u00e4yt\u00e4 kaikki siirrot
-TrayWindow.menu.stopalldownloads=&Pys\u00e4yt\u00e4 kaikki lataukset
-ConfigView.section.tracker.sslport.info=Lis\u00e4tietoja UKK:ssa
-wizard.tracker.ssl=K\u00e4yt\u00e4 SSL:\u00e4\u00e4
-ConfigView.label.playdownloadfinished=Anna \u00e4\u00e4nimerkki latauksen valmistuttua
-ConfigView.label.popupdownloadfinished=Ilmoita latauksen valmistumisesta ponnahdusikkunalla
-ConfigView.label.popupfilefinished=Ilmoita tiedoston valmistumisesta ponnahdusikkunalla
-TableColumn.header.pieces=Osat
-TableColumn.header.pieces.info=Valmistuneet osat graafisena palkkiesityksen\u00e4.
-TableColumn.header.completion=Valmistumisaste
-TableColumn.header.completion.info=Latauksen prosenttim\u00e4\u00e4r\u00e4inen valmistuminen graafisesti.
-ConfigView.section.style.showdownloadbasket=N\u00e4yt\u00e4 pikalatauskuvake - lis\u00e4\u00e4 ty\u00f6p\u00f6yd\u00e4lle kuvakkeen, johon voit raahata ja pudottaa torrent-tiedostoja
-ConfigView.section.style.alwaysShowTorrentFiles=N\u00e4yt\u00e4 aina torrent-tiedoston k\u00e4sitt\u00e4m\u00e4t tiedostot
-wizard.multitracker=M\u00e4\u00e4rit\u00e4 useita seurantapalvelimia
-wizard.multitracker.title=Seurantapalvelimien valitseminen
-wizard.multitracker.configuration=Valmiit p\u00e4\u00e4ryhm\u00e4t:
-wizard.multitracker.new=Uusi...
-wizard.multitracker.edit=Muokkaa...
-wizard.multitracker.delete=Poista
-wizard.multitracker.group=Seurantapalvelinryhm\u00e4
-wizard.multitracker.edit.title=Seurantapalvelimien muokkaus
-wizard.multitracker.edit.name=Nimi
-wizard.multitracker.edit.save=Tallenna
-wizard.multitracker.edit.newgroup=Uusi ryhm\u00e4
-wizard.multitracker.edit.deletegroup=Poista
-wizard.multitracker.edit.newtracker=Uusi seurantapalvelin
-wizard.multitracker.edit.deletetracker=Poista
-wizard.multitracker.edit.edit=Muokkaa
-wizard.addingmt=Lis\u00e4t\u00e4\u00e4n tietoja seurantapalvelimista
-wizard.multitracker.noannounce=P\u00e4ivitysosoitetta ei l\u00f6ydy seurantapalvelinlistalta.
-MyTorrentsView.menu.recheck=&Tarkasta ladatut osat uudelleen
-iconBar.showDownloadBar.tooltip=N\u00e4yt\u00e4 seurantapalkki
-iconBar.start.tooltip=K\u00e4ynnist\u00e4 (aseta jonoon) valitut torrentit
-iconBar.stop.tooltip=Pys\u00e4yt\u00e4 valitut torrentit
-iconBar.remove.tooltip=Poista torrent-tiedosto
-iconBar.openNoDefault.tooltip=Avaa torrent-tiedosto (m\u00e4\u00e4rit\u00e4 lataushakemisto)
-iconBar.openURL.tooltip=Avaa torrent-tiedosto URL-osoitteesta
-iconBar.openFolder.tooltip=Avaa hakemisto (lis\u00e4\u00e4 kaikki hakemiston torrent-tiedostot)
-iconBar.new.tooltip=Luo torrent-tiedosto
-iconBar.up.tooltip=Siirr\u00e4 yl\u00f6s
-iconBar.down.tooltip=Siirr\u00e4 alas
-iconBar.run.tooltip=Avaa oletussovelluksessa
-iconBar.host.tooltip=Aseta seurantaan
-iconBar.publish.tooltip=Julkaise
-iconBar.editcolumns.tooltip=Sarakeasetukset
-MyTorrentsView.menu.editTracker=&Muokkaa seurantapalvelimia
-GeneralView.menu.selectTracker=Valitse seurantapalvelin
-ConfigView.section.stats.xslfile=XSL-tyylitiedoston nimi
-ConfigView.section.stats.xslfiledetails=Lis\u00e4t\u00e4\u00e4n XML-tiedostoon <?xml-stylesheet>-tunnisteeksi
-ConfigView.label.savetorrentbackup=Tallenna my\u00f6s varmuuskopio
-ConfigView.section.tracker.forceport=Pakota ulkoiset torrent-tiedostot oletusporttiin
-ConfigView.section.ipfilter.allow=Salli yhteydet vain n\u00e4ilt\u00e4 osoitealueilta (k\u00e4\u00e4nt\u00e4\u00e4 suotimien tarkoituksen)
-ConfigView.section.ipfilter.list.inrange=oli osoitealueella 
-ConfigView.section.ipfilter.list.notinrange=ei ollut osoitealueilla
-ConfigView.section.ipfilter.list.title=Estetyt k\u00e4ytt\u00e4j\u00e4t
-ConfigView.label.allowsameip=Salli useat yhteydet samasta IP-osoitteesta
-ConfigView.label.allowsameip.tooltip=K\u00e4yt\u00e4 vain, jos todella tarvitset.\nKun asetus ei ole k\u00e4yt\u00f6ss\u00e4, se est\u00e4\u00e4 sellaisten k\u00e4ytt\u00e4jien yhteydenotot,\njotka lataavat tiedostoja, mutta eiv\u00e4t juurikaan (tai ollenkaan) l\u00e4het\u00e4 (mik\u00e4 ei ole hyv\u00e4 asia).
-ManagerItem.superseeding=L\u00e4hetet\u00e4\u00e4n (tehostetusti)
-ConfigView.label.userSuperSeeding=K\u00e4yt\u00e4 tehostettua l\u00e4hetystapaa
-PeersView.uniquepiece=Osa (tehostettu)
-PeersView.uniquepiece.none=Ei k\u00e4yt\u00f6ss\u00e4
-PeersView.timetosend=Uudelleenl\u00e4hetys (tehostettu)
-ConfigView.section.style.addurlsilently=Avaa torrent-tiedostot URL-osoitteista ilman erillisi\u00e4 ilmoituksia
-ConfigView.section.style.addurlsilently.tooltip=URL-osoitteista ladattavat torrent-tiedostot avataan ilman erillisi\u00e4 ilmoituksia.
-ConfigView.section.file.decoder.prompt=Kysy aina, kun eri koodausvaihtoehtoja k\u00e4ytett\u00e4viss\u00e4
-ConfigView.section.file.decoder.prompt.tooltip=N\u00e4ytt\u00e4\u00e4 aina valintaikkunan, jos on tarjolla eri koodausvaihtoehtoja.
-MyTorrentsView.menu.moveTop=Ylimm&\u00e4ksi
-MyTorrentsView.menu.moveEnd=A&limmaksi
-ConfigView.label.moveonlyusingdefaultsave=Siirr\u00e4, jos oletustallennushakemistossa
-ConfigView.label.moveonlyusingdefaultsave.tooltip=Siirt\u00e4\u00e4 tiedostot vain, jos ne ovat tallennettu oletustallennushakemistoon.
-ConfigView.label.watchtorrentfolder=Avaa torrent-tiedostot automaattisesti
-ConfigView.label.watchtorrentfolder.tooltip=Etsii uusia torrent-tiedostoja ladattavaksi s\u00e4\u00e4nn\u00f6llisin v\u00e4liajoin.
-ConfigView.label.watchtorrentfolderinterval=Tarkastusaikav\u00e4li
-ConfigView.label.watchtorrentfolderinterval.tooltip=Aikav\u00e4li, jonka kuluttua hakemisto tarkastetaan uudelleen.
-ConfigView.dialog.choosewatchtorrentfolderpath=Valitse torrent-tiedostojen avaushakemisto
-ConfigView.label.startwatchedtorrentsstopped=Aseta pys\u00e4ytetty-tilaan
-ConfigView.label.startwatchedtorrentsstopped.tooltip=Latausta ei aloiteta, vaan torrent-tiedosto asetetaan heti pys\u00e4ytetty-tilaan.
-ConfigView.section.plugins=Lis\u00e4osat
-wizard.maketorrent.filesize=Tiedosto(je)n koko:
-wizard.maketorrent.piececount=Osien lukum\u00e4\u00e4r\u00e4:
-wizard.maketorrent.piecesize=Osan koko:
-wizard.maketorrent.auto=Autom.
-MainWindow.menu.view.stats=T&ilastot
-SpeedView.title.full=Siirtonopeudet
-SpeedView.downloadSpeed.title=Latausnopeus
-SpeedView.uploadSpeed.title=L\u00e4hetysnopeus
-ConfigView.section.style.useSIUnits=K\u00e4yt\u00e4 IEC-mittayksikk\u00f6j\u00e4rjestelm\u00e4\u00e4 (esim. kB -> KiB)
-iconBar.top.tooltip=Siirr\u00e4 ylimm\u00e4ksi
-iconBar.bottom.tooltip=Siirr\u00e4 alimmaksi
-TableColumn.header.health=Yhteys
-MyTorrentsView.menu.health=Tietoja sarakkeesta "Yhteys"
-health.explain.grey=Torrent-tiedosto on t\u00e4ysin pys\u00e4ytetty (sit\u00e4 ei ladata eik\u00e4 l\u00e4hetet\u00e4).
-health.explain.red=Et ole yhteydess\u00e4 yhteenk\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4\u00e4n (ladattaessa).
-health.explain.blue=L\u00e4hetett\u00e4ess\u00e4: et ole viel\u00e4 yhteydess\u00e4 yhteenk\u00e4\u00e4n lataajaan.\nLadattaessa: olet yhteydess\u00e4 k\u00e4ytt\u00e4jiin, mutta seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4.
-health.explain.yellow=Seurantapalvelin on kunnossa ja olet yhdist\u00e4nyt k\u00e4ytt\u00e4jiin, mutta sinuun ei saada yhteytt\u00e4 ulkoa k\u00e4sin.\nT\u00e4m\u00e4 voi olla merkki NAT-ongelmasta, jos n\u00e4et keltaisia ilmaisimia jatkuvasti.
-health.explain.green=Kaikki kunnossa.
-ConfigView.section.style.alwaysRefreshMyTorrents=P\u00e4ivit\u00e4 aina Siirrot-ikkuna
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Siirrot-ikkunan sis\u00e4lt\u00f6 p\u00e4ivitet\u00e4\u00e4n, vaikka ikkuna ei olisikaan avattuna (tietyt lis\u00e4osat hy\u00f6dynt\u00e4v\u00e4t t\u00e4t\u00e4).
-#
-#2.0.7.0
-#
-security.certtruster.title=Turvallisuusvarmennevaroitus
-security.certtruster.intro=Turvallisuusvarmenteen my\u00f6nsi osapuoli, johon et luota.
-security.certtruster.resource=L\u00e4hde:
-security.certtruster.issuedto=Kenelle:
-security.certtruster.issuedby=My\u00f6nt\u00e4j\u00e4:
-security.certtruster.prompt=Hyv\u00e4ksytk\u00f6 t\u00e4m\u00e4n varmenteen?
-security.certtruster.yes=Kyll\u00e4
-security.certtruster.no=En
-ConfigView.section.tracker.torrentsperpage=Torrent-tiedostojen lukum\u00e4\u00e4r\u00e4/sivu (0 = rajoittamaton)
-MainWindow.menu.file.share=&Jaa
-MainWindow.menu.file.share.file=&Tiedosto...
-MainWindow.menu.file.share.dir=&Hakemisto...
-MainWindow.menu.file.share.dircontents=Hakemiston &sis\u00e4lt\u00f6...
-MainWindow.menu.file.share.dircontentsrecursive=Hakemiston sis\u00e4lt\u00f6... (&rekursiivisesti)
-MainWindow.dialog.share.sharefile=Valitse jaettava tiedosto
-MainWindow.dialog.share.sharedir=Valitse jaettava hakemisto
-MainWindow.dialog.share.sharedircontents=Valitse p\u00e4\u00e4hakemisto 
-MainWindow.dialog.share.sharedircontents.recursive=jaetaan rekursiivisesti
-globalmanager.download.remove.veto=Poistaminen estetty
-plugin.sharing.download.remove.veto=T\u00e4m\u00e4 siirto on jaossa oleva kohde.\nJotta voisit poistaa siirron, sinun t\u00e4ytyy ensin poistaa kyseinen jako (Classic-Share): Ty\u00f6kalut->Jaot (Tools->My Classic-Shares).
-ConfigView.section.tracker.main=Perusasetukset
-ConfigView.label.prioritizefirstpiece=Pyri lataamaan ensisijaisesti tiedostojen ensimm\u00e4iset ja viimeiset osat
-ConfigView.label.prioritizefirstpiece.tooltip=Pyrkii lataamaan aluksi tiedoston ensimm\u00e4isen ja viimeisen osan mahdollista esikatselua varten.
-ConfigView.section.file.confirm_data_delete=Vahvista tiedostojen poisto
-ConfigView.section.file.confirm_data_delete.tooltip=Pyyt\u00e4\u00e4 vahvistusta, kun torrent-tiedostolle k\u00e4ytet\u00e4\u00e4n toimintoa "Poista ja tuhoa...".
-ConfigView.section.file.delete.include_files_outside_save_dir=Kun tiedostoja poistetaan, salli linkitettyjen tiedostojen poistaminen my\u00f6s muualta kuin torrenttien tallennushakemistosta
-TrayWindow.menu.startalldownloads=K\u00e4ynnist\u00e4 kaikki lataukset
-SystemTray.menu.startalltransfers=K\u00e4ynnist\u00e4 kaikki siirrot
-sharing.progress.title=Jakamisen edistyminen
-sharing.progress.hide=Piilota
-MainWindow.menu.view.myshares=&Jaot
-MySharesView.title.full=Jaot
-MySharesView.name=Nimi
-MySharesView.type=Tyyppi
-MySharesView.type.file=Tiedosto
-MySharesView.type.dir=Hakemisto
-MySharesView.type.dircontents=Hakemiston sis\u00e4lt\u00f6
-MySharesView.type.dircontentsrecursive=Hakemiston sis\u00e4lt\u00f6 (rekursiivisesti)
-MySharesView.menu.remove=Poista
-ConfigView.section.tracker.extensions=Lis\u00e4asetukset
-ConfigView.section.tracker.sendpeerids=L\u00e4het\u00e4 tunnisteet k\u00e4ytt\u00e4jist\u00e4 lataajille
-ConfigView.section.tracker.enableudp=K\u00e4yt\u00e4 seurantapalvelimen UDP-protokollaa
-plugin.sharing.torrent.remove.veto=T\u00e4m\u00e4 on jaettu kohde.\nPoistaaksesi kohteen poista ensin kyseinen jako (Classic-Share): Ty\u00f6kalut->Jaot (Tools->My Classic-Shares).
-plugin.download.remove.veto.notstopped=Kohdetta ei voida poistaa, koska sit\u00e4 ei ole pys\u00e4ytetty.
-plugin.sharing.remove.veto=T\u00e4m\u00e4 kohde on Hakemiston sis\u00e4lt\u00f6 -jaon alainen, joten et voi poistaa sit\u00e4 suoraan.\nPoistaaksesi kohteen poista p\u00e4\u00e4jako (p\u00e4\u00e4hakemisto).
-GeneralView.label.hash.tooltip=Klikkaa kopioidaksesi tiiviste leikep\u00f6yd\u00e4lle.
-ConfigView.section.tracker.maxpeersreturned=Palautettavien yhteystietojen enimm\u00e4ism\u00e4\u00e4r\u00e4\n(0 = rajoittamaton)
-ConfigView.label.serverport=Sis\u00e4\u00e4ntulevan TCP- ja UDP-liikenteen portti
-ConfigView.label.serverport.tooltip=Portin t\u00e4ytyy olla v\u00e4lilt\u00e4 1-65535, eik\u00e4 se saa olla 6880, koska\nkyseinen portti on varattu Vuzen sis\u00e4iseen k\u00e4ytt\u00f6\u00f6n.
-configureWizard.nat.server.tcp_listen_port=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
-ConfigView.section.sharing=Jakaminen
-ConfigView.section.sharing.usessl=K\u00e4yt\u00e4 SSL:\u00e4\u00e4 jaetuille resursseille (seurantapalvelimen asetusten oltava vastaavat)
-ConfigView.section.style.dropdiraction=Toiminto raahatessa ja pudotettaessa kansioita Vuzeen
-ConfigView.section.style.dropdiraction.opentorrents=Avaa torrent-tiedostot
-ConfigView.section.style.dropdiraction.sharefolder=Jaa hakemisto
-ConfigView.section.style.dropdiraction.sharefoldercontents=Jaa hakemiston sis\u00e4lt\u00f6
-#
-# 2.0.7.x
-#
-Categories.all=Kaikki
-Categories.uncategorized=Luokittelemattomat
-CategoryAddWindow.message=Anna uuden luokan nimi:
-CategoryAddWindow.title=Uusi luokka
-ConfigView.label.autoSeedingIgnoreInfo=Ohitetut torrent-tiedostot menev\u00e4t l\u00e4hetysjonon loppup\u00e4\u00e4h\u00e4n ja niit\u00e4 ei aloiteta l\u00e4hett\u00e4m\u00e4\u00e4n automaattisesti.\nN\u00e4m\u00e4 ohituss\u00e4\u00e4nn\u00f6t eiv\u00e4t p\u00e4de niihin torrent-tiedostoihin, jotka ovat saavuttaneet ensisijaisuuden.\nNolla-arvo (0) tarkoittaa asetuksissa s\u00e4\u00e4nn\u00f6n poistamista k\u00e4yt\u00f6st\u00e4, ellei toisin mainita.
-ConfigView.label.directory=Hakemisto
-ConfigView.label.disconnetseed.tooltip=Yhteys l\u00e4hett\u00e4jiin voidaan katkaista, koska niit\u00e4 ei en\u00e4\u00e4 tarvita latauksen valmistuttua.
-ConfigView.label.ignoreCase=Kirjainten koolla ei v\u00e4li\u00e4
-ConfigView.label.ignoreSeeds=Ohita torrent-tiedostot, joilla on v\u00e4hint\u00e4\u00e4n
-ConfigView.label.importdirectory=Avaushakemisto
-ConfigView.label.minPeersToBoostNoSeeds.tooltip=Ehdot t\u00e4ytt\u00e4v\u00e4t torrent-tiedostot siirret\u00e4\u00e4n l\u00e4hetysjonon loppup\u00e4\u00e4h\u00e4n.
-ConfigView.label.minPeersToBoostNoSeeds=Alenna torrent-tiedostojen l\u00e4hetystarvetta, joilla ei ole l\u00e4hteit\u00e4 ja v\u00e4hemm\u00e4n kuin
-ConfigView.label.minSeedingTime.tooltip=Torrent-tiedostojen l\u00e4hetystarpeet voivat vaihdella niin nopeasti, ett\u00e4 kun torrent-tiedosto on asetettu l\u00e4hetett\u00e4v\u00e4ksi,\nse pys\u00e4ytet\u00e4\u00e4nkin samantien ja palautetaan jonoon. T\u00e4ll\u00e4 asetuksella v\u00e4himm\u00e4isl\u00e4hetysaika voidaan pakottaa tietyn pituiseksi.\nL\u00e4hetyksen voi toki t\u00e4llaisessa tilanteessa pys\u00e4ytt\u00e4\u00e4 manuaalisesti.
-ConfigView.label.minSeedingTime=V\u00e4himm\u00e4isl\u00e4hetysaika sekunneissa
-ConfigView.label.minSpeedForActiveDL.tooltip=Normaalisti torrent-tiedosto lasketaan kuuluvaksi t\u00e4h\u00e4n\njoukkoon v\u00e4hint\u00e4\u00e4n 30 sekunnin ajaksi latauksen k\u00e4ynnistymisest\u00e4 l\u00e4htien.
-ConfigView.label.minSpeedForActiveDL=\u00c4l\u00e4 laske torrent-tiedostoa ladattavien joukkoon, jos latausnopeus on alle
-ConfigView.label.peers=lataajaa
-ConfigView.label.queue.debuglog=Kirjaa virheenm\u00e4\u00e4ritystiedot lokiin
-ConfigView.label.queue.debuglog.info=Lis\u00e4\u00e4 siirtojonotoimintojen virheenm\u00e4\u00e4ritystiedot konsoliin/lokitiedostoon.\nVaikka tiedot ovatkin vaikeaselkoisia, saa niist\u00e4 selville torrent-tiedostojen tilan ja miksi ne ovat k\u00e4ynnistyneet tai pys\u00e4htyneet.
-ConfigView.label.queue.minQueueingShareRatio=\u00c4l\u00e4 aseta jonoon/pys\u00e4yt\u00e4 torrent-tiedostoa ennen kuin jakosuhde on
-ConfigView.label.ratio=jakosuhde
-ConfigView.label.removeOnStop=Poista torrent-tiedosto, kun se on automaattisesti pys\u00e4htynyt
-ConfigView.label.savedirectory=Tallennushakemisto
-ConfigView.label.seeding.autoReposition.tooltip=Jos k\u00e4yt\u00f6ss\u00e4, torrent-tiedostojen j\u00e4rjestys (#-sarake Siirrot-ikkunassa)\nm\u00e4\u00e4r\u00e4ytyy niiden l\u00e4hetystarpeen mukaan.\nHy\u00f6dyllinen toiminto, jos et halua n\u00e4hd\u00e4 l\u00e4hetystarvearvoja, mutta haluat silti\nolla selvill\u00e4 siit\u00e4, mit\u00e4 valmistunutta torrent-tiedostoa aloitetaan l\u00e4hett\u00e4\u00e4 seuraavaksi.
-ConfigView.label.seeding.autoReposition=J\u00e4rjest\u00e4 torrent-tiedostot perustuen l\u00e4hetystarpeeseen
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=Jos torrent-tiedostolla on v\u00e4h\u00e4n l\u00e4hteit\u00e4 ja kuitenkin paljon lataajia, tarkoittaa se usein sit\u00e4,\nett\u00e4 lataajien joukossa on tuskin yht\u00e4\u00e4n t\u00e4ytt\u00e4 kopiota.\nNiinp\u00e4 haluat ehk\u00e4 rajoittaa edellist\u00e4 s\u00e4\u00e4nt\u00f6\u00e4, jotta Vuze ei turhaan alenna torrent-tiedoston sijoitusta l\u00e4hetysjonossa.
-ConfigView.label.seeding.fakeFullCopySeedStart=mutta vain torrent-tiedostoille, joilla on v\u00e4hint\u00e4\u00e4n
-ConfigView.label.seeding.ignore=Ohituss\u00e4\u00e4nn\u00f6t
-ConfigView.label.seeding.ignore0Peers=Ohita torrent-tiedostot, joilla ei ole yht\u00e4\u00e4n lataajaa
-ConfigView.label.seeding.ignoreRatioPeers=Ohita torrent-tiedostot, joilla on v\u00e4hint\u00e4\u00e4n yksi l\u00e4hde kohti
-ConfigView.label.seeding.ignoreShareRatio=Ohita torrent-tiedostot, joiden jakosuhde on
-ConfigView.label.seeding.ignore.header.evenFirstPriority=Ohita torrent-tiedosto,\nvaikka olisi ensisijainen
-ConfigView.label.seeding.ignore.header.rule=S\u00e4\u00e4nt\u00f6
-ConfigView.label.seeding.ignore.header.value=Arvo
-ConfigView.label.seeding.firstPriority.info=Ensisijaiset torrent-tiedostot ovat aina l\u00e4hetysjonon k\u00e4rkip\u00e4\u00e4ss\u00e4. Jos torrent-tiedosto on ensisijainen, sit\u00e4 ei automaattisesti pys\u00e4ytet\u00e4 eik\u00e4 aseteta takaisin jonoon. Ensisijainen torrent-tiedosto voi my\u00f6s varata itselleen yht\u00e4aikaisen latauspaikan, jos se tarvitsee sellaista.
-ConfigView.label.seeding.firstPriority.FP=Ensisijaisuus
-ConfigView.label.seeding.firstPriority=Ensisijaisuus my\u00f6nnet\u00e4\u00e4n torrent-tiedostoille, jotka t\u00e4ytt\u00e4v\u00e4t
-ConfigView.label.seeding.firstPriority.following=seuraavista s\u00e4\u00e4nn\u00f6ist\u00e4:
-ConfigView.label.seeding.firstPriority.shareRatio=Jakosuhde on alle
-ConfigView.label.seeding.firstPriority.seedingMinutes=Aikaa kulunut siit\u00e4, kun lataus valmistui ja l\u00e4hett\u00e4minen alkoi
-ConfigView.label.seeding.firstPriority.DLMinutes=Aikaa kulunut latauksen aloittamisesta
-ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Lis\u00e4\u00e4m\u00e4ll\u00e4 teoreettisesti yhden t\u00e4yden kopion siirrosta tietty\u00e4 lataajam\u00e4\u00e4r\u00e4\u00e4 kohti\nv\u00e4henn\u00e4t niiden torrent-tiedostojen l\u00e4hetystarvetta, joilla on paljon lataajia.\nT\u00e4llaisten torrent-tiedostojen kohdalla tietoa liikkuu todenn\u00e4k\u00f6isesti jo aivan tarpeeksi.\nT\u00e4m\u00e4 asetus ei lis\u00e4\u00e4 miss\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytett\u00 [...]
-ConfigView.label.seeding.numPeersAsFullCopy=Lis\u00e4\u00e4 teoreettisesti yksi t\u00e4ysi kopio kohti (0 = ei teoreettista lis\u00e4yst\u00e4)
-ConfigView.label.seeding.preferLargerSwarms.tooltip=T\u00e4st\u00e4 asetuksesta on hy\u00f6ty\u00e4 silloin, kun l\u00e4hetet\u00e4\u00e4n torrent-tiedostoja, joiden tiedon siirt\u00e4minen\nlataajille/lataajien kesken on hyvin hidasta. Jos puolestaan l\u00e4het\u00e4t torrent-tiedostoja, joilla on hyv\u00e4 saatavuus,\non parempi suosia niit\u00e4, joilla on v\u00e4hemm\u00e4n lataajia.
-ConfigView.label.seeding.preferLargerSwarms=Jos torrent-tiedostoilla on sama l\u00e4hetystarve, suosi sit\u00e4, jolla on enemm\u00e4n lataajia
-ConfigView.label.seeding.rankType.none.tooltip=J\u00e4rjestys pohjautuu torrent-tiedoston j\u00e4rjestysnumeroon (#-sarake Siirrot-ikkunassa).
-ConfigView.label.seeding.rankType.none=Ei mihink\u00e4\u00e4n
-ConfigView.label.seeding.rankType.peer.tooltip=Enemm\u00e4n lataajia, v\u00e4hemm\u00e4n l\u00e4hteit\u00e4 --> korkeampi prioriteetti\nT\u00e4m\u00e4 asetus pienent\u00e4\u00e4 tarvittavien aktiivisten torrenttien m\u00e4\u00e4r\u00e4\u00e4 l\u00e4hetysnopeuden maksimoimiseksi
-ConfigView.label.seeding.rankType.peer=Painotettu lataajien m\u00e4\u00e4r\u00e4
-ConfigView.label.seeding.rankType.peerSeed.options=Ohitusasetukset
-ConfigView.label.seeding.rankType.peerSeed.tooltip=Korkeampi suhdeluku vastaa korkeampaa l\u00e4hetystarvetta.
-ConfigView.label.seeding.rankType.peerSeed=Lataajia/l\u00e4hde-suhdelukuun
-ConfigView.label.seeding.rankType.seed.fallback=Vaihda edelliseen s\u00e4\u00e4nt\u00f6\u00f6n, kun on\n(0 = \u00e4l\u00e4 vaihda koskaan)
-ConfigView.label.seeding.rankType.seed.options=Ohitusasetukset
-ConfigView.label.seeding.rankType.seed.tooltip=V\u00e4hemm\u00e4n l\u00e4hteit\u00e4 vastaa korkeampaa l\u00e4hetystarvetta.
-ConfigView.label.seeding.rankType.seed=L\u00e4hteiden lukum\u00e4\u00e4r\u00e4\u00e4n
-ConfigView.label.seeding.rankType.timedRotation.tooltip=Kaikkia jonossa olevia torrent-tiedostoja l\u00e4hetet\u00e4\u00e4n vuorotellen.\nL\u00e4hetysajan pituus m\u00e4\u00e4ritell\u00e4\u00e4n L\u00e4hett\u00e4minen-asetusryhm\u00e4n kohdassa V\u00e4himm\u00e4isl\u00e4hetysaika sekunneissa.
-ConfigView.label.seeding.rankType.timedRotation=Aikaan
-ConfigView.label.seeding.rankType.tooltip=Korkeimman l\u00e4hetystarpeen torrent-tiedostoja aloitetaan l\u00e4hett\u00e4\u00e4 automaattisesti.\nKun toinen torrent-tiedosto saavuttaa korkeamman l\u00e4hetystarpeen, edellisen l\u00e4hett\u00e4minen keskeytet\u00e4\u00e4n ja se asetetaan takaisin jonoon.\n\nAutomaattista l\u00e4hetyksen aloittamista voidaan soveltaa vain niihin torrent-tiedostohin, jotka ovat Jonossa-tilassa.\nT\u00e4ysin pys\u00e4ytettyj\u00e4 torrent-tiedostoja ei koskaa [...]
-ConfigView.label.seeding.rankType=Priorisoi valmistuneiden torrent-tiedostojen l\u00e4hett\u00e4minen perustuen:
-ConfigView.label.stopAfterMinutes=Pys\u00e4yt\u00e4 l\u00e4hett\u00e4minen, kun on kulunut valmistumisen j\u00e4lkeen
-ConfigView.label.switchpriority.tooltip=Alhainen prioriteetti v\u00e4hent\u00e4\u00e4 torrent-tiedostolle jaettua l\u00e4hetysnopeutta.
-ConfigView.pluginlist.info=Vuze tunnisti seuraavat lis\u00e4osat.\nHuomaa, ett\u00e4 kaikilla ei v\u00e4ltt\u00e4m\u00e4tt\u00e4 ole asetusmahdollisuuksia.
-ConfigView.pluginlist.noplugins=Lis\u00e4osia ei l\u00f6ytynyt.
-ConfigView.section.pluginslist=Listaa
-ConfigView.section.queue.seeding=L\u00e4hett\u00e4minen
-ConfigView.section.queue.seeding.autoStarting=Automaattinen aloitus
-ConfigView.section.queue.seeding.ignore=Ohituss\u00e4\u00e4nn\u00f6t
-ConfigView.section.queue.seeding.firstPriority=Ensisijaisuus
-ConfigView.section.queue.main=Perusasetukset
-ConfigView.section.queue=Siirtojonot
-ConfigView.section.torrents=Torrent-tiedostot
-ConfigView.text.all=kaikki
-ConfigView.text.hours=tuntia
-ConfigView.text.ignoreRule=Ohita s\u00e4\u00e4nt\u00f6
-ConfigView.text.ignore=Ei k\u00e4yt\u00f6ss\u00e4
-ConfigView.text.minutes=min
-ConfigView.text.neverIgnore=\u00c4l\u00e4 koskaan ohita
-ConfigView.text.any=jonkun
-DownloadManager.error.datamissing=Tiedostoja ei saatavilla
-MainWindow.menu.file.open.torrentforseeding=Torrent-tiedosto... (l\u00e4hett\u00e4mist\u00e4 varten)
-MainWindow.menu.language.refresh=&P\u00e4ivit\u00e4
-ManagerItem.forced=Ohita s\u00e4\u00e4nn\u00f6t, 
-ManagerItem.queued=Jonossa
-MySeedersView.header=Valmistuneet torrent-tiedostot
-TableColumn.header.availability.info=T\u00e4ysien kopioiden lukum\u00e4\u00e4r\u00e4.
-TableColumn.header.availability=Saatavuus
-TableColumn.header.category=Luokka
-MyTorrentsView.header=Keskener\u00e4iset torrent-tiedostot
-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=Tallennushakemisto
-TableColumn.header.SeedingRank=L\u00e4hetystarve
-TableColumn.header.totalspeed.info=Yhdistettyin\u00e4 olevien k\u00e4ytt\u00e4jien siirtonopeus yhteens\u00e4.
-TableColumn.header.totalspeed=Nopeus yht.
-splash.initializePlugins=Alustetaan lis\u00e4osia
-StartStopRules.SPratioMet=L\u00e4h:Lat-suhdeluku OK
-StartStopRules.FP0Peers=Ensisijaisuus/0 lataajaa
-StartStopRules.0Peers=0 lataajaa
-StartStopRules.numSeedsMet=L\u00e4hteiden lkm OK
-StartStopRules.ratioMet=Lataajia/l\u00e4hde-suhde OK
-StartStopRules.shareRatioMet=Jakosuhde OK
-StartStopRules.waiting=Odotetaan
-StartStopRules.firstPriority=Ensisijainen
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Jaa hakemiston sis\u00e4lt\u00f6 (rekursiivisesti)
-DownloadManager.error.unabletostartserver=Yhteyden muodostaminen ei onnistu - tarkasta sis\u00e4\u00e4ntulevan TCP-liikenteen portti/palomuurin asetukset koskien Vuzea
-GeneralView.label.creationdate=Luontiaika:
-ConfigView.section.tracker.announcescrapepercentage=Pikap\u00e4ivitysten suhde %:ina p\u00e4ivityksist\u00e4,\nesim. 200 = 2:1 (0 = k\u00e4ytt\u00e4j\u00e4 p\u00e4\u00e4tt\u00e4\u00e4)
-ManagerItem.stopping=Pys\u00e4ytet\u00e4\u00e4n
-ConfigView.section.tracker.announcecacheperiod=P\u00e4ivitysten v\u00e4limuistiaika (ms)
-ConfigView.section.tracker.scrapecacheperiod=Pikap\u00e4ivitysten v\u00e4limuistiaika (ms)
-ConfigView.section.tracker.scrapeandcache=Pikap\u00e4ivitykset ja v\u00e4limuisti
-ConfigView.section.tracker.announcecacheminpeers=K\u00e4ytt\u00e4jien m\u00e4\u00e4r\u00e4, jonka j\u00e4lkeen\np\u00e4ivitysten v\u00e4limuisti k\u00e4yt\u00f6ss\u00e4
-MyTrackerView.scrapes=Pikap\u00e4ivitykset
-fileDownloadWindow.retry=Uudestaan
-MyTrackerView.bytesin=Sis\u00e4\u00e4n
-MyTrackerView.bytesinave=Keskim. sis\u00e4\u00e4n
-MyTrackerView.bytesout=Ulos
-MyTrackerView.bytesoutave=Keskim. ulos
-ConfigView.section.file.max_open_files=Lukua/kirjoitusta varten avattavien tiedostojen\nenimm\u00e4islukum\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
-ConfigView.section.file.max_open_files.tooltip=Tiedostojen lukum\u00e4\u00e4r\u00e4\u00e4 kannattaa rajoittaa siin\u00e4 tapauksessa, jos torrent-tiedosto k\u00e4sitt\u00e4\u00e4\nsatoja tai jopa tuhansia tiedostoja ja k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n tiedostonk\u00e4sittelyrajat tulevat t\u00e4ll\u00f6in vastaan.
-ConfigView.section.proxy=V\u00e4lityspalvelin
-ConfigView.section.proxy.enable_proxy=K\u00e4yt\u00e4 v\u00e4lityspalvelinta (vaatii uudelleenk\u00e4ynnistyksen)
-ConfigView.section.proxy.host=Osoite
-ConfigView.section.proxy.port=Portti
-ConfigView.section.proxy.username=K\u00e4ytt\u00e4j\u00e4tunnus
-ConfigView.section.proxy.password=Salasana
-ConfigView.section.proxy.enable_socks=V\u00e4lityspalvelin on SOCKS-yhteensopiva
-wizard.createtorrent.extrahashes=Lis\u00e4\u00e4 tiivisteet muille verkoille (esim. Gnutella2 ja ed2k)
-GeneralView.label.connected=yhdistetty
-GeneralView.label.in_swarm=kaikkiaan
-ManagerItem.initializing=Aloitetaan
-AlertMessageBox.error=Virhe
-AlertMessageBox.warning=Varoitus
-AlertMessageBox.comment=Info
-AlertMessageBox.information=Info
-AlertMessageBox.unread=Lukemattomia viestej\u00e4 - klikkaa t\u00e4st\u00e4
-SharedPortServer.alert.selectorfailed=Sis\u00e4\u00e4ntulevan tiedon vastaanottamisessa ongelmia.\nTarkasta palomuurin asetukset Vuzen osalta.
-Tracker.alert.listenfail=Portti %1 ei ole k\u00e4ytett\u00e4viss\u00e4.\nTarkasta, ett\u00e4 muut sovellukset eiv\u00e4t k\u00e4yt\u00e4 ko. porttia ja varmista my\u00f6s, ettei sinulla ole useampaa Vuzea k\u00e4ynniss\u00e4.
-DiskManager.alert.movefileexists=Ongelma tiedostojen siirt\u00e4misess\u00e4.\nTiedosto %1 on jo olemassa kohdehakemistossa.
-DiskManager.alert.movefilefails=Ongelma tiedostojen siirt\u00e4misess\u00e4.\nTiedoston %1 siirto ep\u00e4onnistui, %2
-DiskManager.alert.movefilerecoveryfails=Ongelma tietojen palauttamisessa.\nTiedoston %1 palautus ep\u00e4onnistui, %2
-ConfigView.section.tracker.logenable=Tallenna tilastotiedot (tracker.log-tiedosto)
-SpeedView.stats.title=Tilastot
-SpeedView.stats.total=Yhteens\u00e4
-SpeedView.stats.session=T\u00e4m\u00e4 sessio
-SpeedView.stats.session.tooltip=Yhteens\u00e4 (yhteysk\u00e4yt\u00e4nt\u00f6)
-SpeedView.stats.downloaded=Ladattu (yhteysk\u00e4yt\u00e4nt\u00f6)
-SpeedView.stats.uploaded=L\u00e4hetetty (yhteysk\u00e4yt\u00e4nt\u00f6)
-SpeedView.stats.ratio=Jakosuhde
-SpeedView.stats.uptime=K\u00e4ytt\u00f6aika
-SpeedView.stats.now=Parhaillaan
-SpeedView.stats.now.tooltip=Yhteens\u00e4 (yhteysk\u00e4yt\u00e4nt\u00f6)
-AutoMigration.useralert=Vuzen asetustiedostojen ja hakemistojen\nautomaattisen kopioinnin tulokset:\n\n%1\nEp\u00e4onnistuneet ('FAILED') kopioinnit t\u00e4ytyy tehd\u00e4 manuaalisesti.\nMuista my\u00f6s p\u00e4ivitt\u00e4\u00e4 tallennuspolut asetuksiin!
-#
-# > 2.0.8.0
-#
-OpenTorrentWindow.title=Avaa torrent-tiedosto
-OpenTorrentWindow.message=Kokeellinen
-OpenTorrentWindow.addFiles=Lis\u00e4\u00e4 &tiedostoja
-OpenTorrentWindow.dataLocation=Tallennushakemisto:
-OpenTorrentWindow.startMode=Aloitustila
-OpenTorrentWindow.startMode.queued=K\u00e4ynnist\u00e4 (aseta jonoon)
-OpenTorrentWindow.startMode.stopped=Pys\u00e4ytetty
-OpenTorrentWindow.startMode.forceStarted=K\u00e4ynnist\u00e4 (ohita s\u00e4\u00e4nn\u00f6t)
-OpenTorrentWindow.addPosition=Sijoitus jonossa
-OpenTorrentWindow.addPosition.first=Ensimm\u00e4inen
-OpenTorrentWindow.addPosition.last=Viimeinen
-TableColumn.header.remaining.info=J\u00e4ljell\u00e4 oleva ladattava m\u00e4\u00e4r\u00e4.
-TableColumn.header.remaining=J\u00e4ljell\u00e4
-ConfigView.section.tracker.enablecompact=K\u00e4yt\u00e4 tiivistetty\u00e4 p\u00e4ivitysprotokollaa (IP- ja porttitiedot l\u00e4hetet\u00e4\u00e4n 6 bitin sarjoina string-arvon sijaan)
-ConfigView.section.tracker.enablekey=K\u00e4yt\u00e4 turva-avaimen siirtoa seurantapalvelimelle (parantaa turvallisuutta)
-ConfigView.section.file.perf=Suorituskyky
-ConfigView.section.file.perf.explain=Varoitus - n\u00e4iden asetusten harkitsematon muuttaminen voi vaikuttaa alentavasti latausnopeuksiin.\nJotta muutokset tulisivat voimaan, Vuze t\u00e4ytyy k\u00e4ynnist\u00e4\u00e4 uudelleen.\nJos muistin k\u00e4ytt\u00f6 nousee huomattavasti, voit kokeilla torrent-kohtaisten yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4n pienent\u00e4mist\u00e4 Siirrot-asetuksissa.
-ConfigView.section.file.max_open_files.explain=Liian suuren tiedostom\u00e4\u00e4r\u00e4n k\u00e4sittely voi johtaa k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4ongelmiin. T\u00e4m\u00e4 asetus rajoittaa yht\u00e4aikaisesti k\u00e4sitelt\u00e4vien tiedostojen m\u00e4\u00e4r\u00e4\u00e4.
-popup.error.hide=Piilota
-popup.error.details=Lis\u00e4\u00e4...
-ConfigView.section.style.colorOverrides=Tarkemmat v\u00e4riasetukset
-ConfigView.section.style.colorOverride.progressBar=Edistymispalkit
-ConfigView.section.style.colorOverride.error=Virheet
-MainWindow.status.tooOld=on vanha. P\u00e4ivit\u00e4.
-ConfigView.section.style.colorOverride.warning=Varoitukset
-ConfigView.section.style.colorOverride.altRow=Taulukoiden rivit (joka toinen)
-ConfigView.section.file.save.peers.enable=Tallenna tiedot k\u00e4ytt\u00e4jist\u00e4
-ConfigView.section.file.save.peers.max=K\u00e4ytt\u00e4jien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
-ConfigView.section.file.save.peers.pertorrent=/torrent-tiedosto
-ConfigView.label.max_peers_per_torrent=Yhteyksien oletusenimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto (0 = rajoittamaton)
-ConfigView.label.max_peers_total=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 kaikkiaan (0 = rajoittamaton)
-ConfigView.section.style.colorOverrides.reset=Oletusv\u00e4ri
-ConfigView.section.language.info=Jos k\u00e4yt\u00f6ss\u00e4, Vuze tarkastaa k\u00e4ynnistyksen yhteydess\u00e4 saatavilla olevat p\u00e4ivitykset.
-ConfigView.section.language.enableUpdate=K\u00e4yt\u00e4 Web-p\u00e4ivityst\u00e4
-ConfigView.section.language.UpdateURL=Tarkastusosoite
-ConfigView.section.language.UpdateNow=P\u00e4ivit\u00e4 nyt
-Button.revert=Palaa
-MyTorrentsView.menu.changeDirectory=Vaihda tallennushakemistoa
-GenericText.column=-sarake
-MyTorrentsView.menu.thisColumn.remove=Poista sarake n\u00e4kyvist\u00e4
-MyTorrentsView.menu.thisColumn.toClipboard=Kopioi teksti leikep\u00f6yd\u00e4lle
-MyTorrentsView.menu.thisColumn.autoTooltip=N\u00e4yt\u00e4 aina ty\u00f6kaluvihje
-MyTorrentsView.menu.tracker=Seurantapalvelin/Torrent
-ConfigView.download.abbreviated=Lad:
-ConfigView.upload.abbreviated=L\u00e4h:
-ConfigView.complete.abbreviated=Valm:
-TableColumn.header.secondsseeding=L\u00e4h.aika
-TableColumn.header.secondsseeding.info=Torrent-tiedoston l\u00e4hetysaika sen lataukseen asettamisesta l\u00e4htien.
-TableColumn.header.secondsdownloading=Lat.aika
-TableColumn.header.secondsdownloading.info=Torrent-tiedoston latausaika sen lataukseen asettamisesta l\u00e4htien.
-ConfigView.section.tracker.udpversion=UDP-protokollan k\u00e4ytett\u00e4v\u00e4 versio (1 tai 2)
-window.updateswt.title=SWT-ohjelmakirjasto vanhentunut!
-window.updateswt.text=SWT-versiosi on vanhentunut!\nSWT on vuzen k\u00e4ytt\u00e4m\u00e4 graafinen ohjelmakirjasto, ja t\u00e4m\u00e4nhetkinen SWT-versiosi on liian vanha Vuzen k\u00e4ynnist\u00e4miseen. Valitse OK p\u00e4ivitt\u00e4\u00e4ksesi SWT-ohjelmakirjasto uusimpaan versioon.
-window.updateswt.status=Tila
-window.updateswt.failed=P\u00e4ivitys ep\u00e4onnistui, valitse OK k\u00e4ynnist\u00e4\u00e4ksesi uudelleen.
-window.updateswt.status.downloading.updater=Ladataan p\u00e4ivitysmoduulia
-window.updateswt.status.finding=Etsit\u00e4\u00e4n viimeisint\u00e4 SWT-versiota
-window.updateswt.status.downloading=Ladataan viimeisint\u00e4 SWT-versiota
-window.updateswt.status.done=K\u00e4ynnistet\u00e4\u00e4n uudelleen
-window.updateswt.cancel=Peruuta
-swt.updater.downloader.downloading=Ladataan SWT:t\u00e4 kohteesta
-swt.updater.urlsgetter.downloading=Ladataan peilaavien palvelimien listaa kohteesta
-swt.updater.urlsgetter.platform=SWT k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4alustalle: 
-window.updateswt.ignore=Ohita
-ConfigView.section.style.useFancyTabs=K\u00e4yt\u00e4 ulkoasultaan tyyliteltyj\u00e4 v\u00e4lilehti\u00e4
-splash.initializeGM=Alustetaan torrent-tiedostojen k\u00e4sittely\u00e4
-splash.loadingTorrents=Ladataan torrent-tiedostoja
-MyTorrentsView.menu.thisColumn.sort=&Lajittele torrent-tiedostot
-Scrape.status.ok=Pikap\u00e4ivitys OK.
-Scrape.status.error=Pikap\u00e4ivitysvirhe: 
-Scrape.status.error.badURL=P\u00e4ivitysosoite ei tue pikap\u00e4ivitysm\u00e4\u00e4rittelyj\u00e4.
-Scrape.status.error.nohash=Vastaus ei sis\u00e4lt\u00e4nyt tiivistett\u00e4.
-Scrape.status.error.invalid=Virheellinen vastaus.
-Scrape.status.nextScrapeAt=Seuraava pikap\u00e4ivitys %1
-Scrape.status.scraping=Suoritetaan pikap\u00e4ivityst\u00e4...
-Scrape.status.initializing=Odotetaan pikap\u00e4ivityst\u00e4
-Scrape.status.scraping.queued=Pikap\u00e4ivitys jonossa...
-ConfigView.label.minSpeedForActiveSeeding=\u00c4l\u00e4 laske valmistunutta torrent-tiedostoa aktiiviseksi, jos l\u00e4hetysnopeus on alle
-ConfigView.section.stats.exportpeers=Tallenna tarkat tiedot k\u00e4ytt\u00e4jist\u00e4
-MainWindow.menu.view.irc.moved=IRC-laajennus on nyt saatavilla lis\u00e4osana, katso lis\u00e4tietoja osoitteesta http://azureus.sourceforge.net/plugin_list.php.
-MyTrackerView.webui.contextmenu.copyurl=Kopioi torrent-tiedoston URL-osoite leikep\u00f6yd\u00e4lle
-ConfigView.section.file.torrent.ignorefiles=Tiedostot, jotka ohitetaan luotaessa/poistettaessa tiedostoja\nesim. .DS_Store;Thumbs.db
-Torrent.create.progress.ignoringfile=Ohitetaan tiedosto
-ConfigView.section.style.useUnitsRateBits=K\u00e4yt\u00e4 bittej\u00e4 tavujen sijasta tavupohjaisissa nopeusarvoissa (esim. KiB/s -> Kibit/s)
-ConfigView.section.interface.resetassoc=Palauta tiedostoassosiaatio (.torrent) Vuzelle
-ConfigView.section.interface.resetassocbutton=Palauta
-ConfigView.section.interface.checkassoc=Tarkasta assosiaatio k\u00e4ynnistett\u00e4ess\u00e4
-dialog.associations.title=Tiedostoassosiaation tarkastus
-Button.yes=&Kyll\u00e4
-Button.no=&Ei
-ConfigView.label.seeding.autoStart0Peers=K\u00e4ynnist\u00e4 valmistuneet torrent-tiedostot, joilla ei ole yht\u00e4\u00e4n lataajaa
-ConfigView.label.seeding.autoStart0Peers.tooltip=K\u00e4yt\u00e4 t\u00e4t\u00e4, jos haluat, ett\u00e4 seurantapalvelin tallentaa aina tiedot l\u00e4hteist\u00e4.
-dialog.associations.prompt=Vuzea ei ole asetettu oletussovellukseksi BitTorrent-tiedostoille.\nHaluatko assosioida .torrent-tiedostot Vuzelle?
-dialog.associations.askagain=Tarkasta k\u00e4ynnistett\u00e4ess\u00e4
-ConfigView.section.plugins.update=Lis\u00e4osien p\u00e4ivitys
-Plugin.pluginupdate.enablecheck=Tarkasta, onko k\u00e4yt\u00f6ss\u00e4 oleviin lis\u00e4osiin saatavilla p\u00e4ivityksi\u00e4
-plugins.basicview.status=Tila: 
-plugins.basicview.activity=Toiminta: 
-plugins.basicview.progress=Edistyminen: 
-plugins.basicview.log=Loki: 
-ConfigView.label.maxdownloadspeed=kB/s, enimm\u00e4islatausnopeus (kaikki torrent-tiedostot, 0 = rajoittamaton)
-splash.loadingTorrent=Ladataan torrent-tiedostoa
-splash.of=/
-ConfigView.section.plugins.irc=IRC-yhteys
-UpdateWindow.title=Vuzen p\u00e4ivitystoimenpiteet
-UpdateWindow.header=Seuraavat osat vaativat p\u00e4ivitt\u00e4mist\u00e4:
-UpdateWindow.columns.install=Asenna
-UpdateWindow.columns.name=Nimi
-UpdateWindow.columns.version=Versio
-UpdateWindow.columns.size=Koko
-UpdateWindow.cancel=Peruuta
-UpdateWindow.quit=Lopeta
-UpdateWindow.close=Sulje
-UpdateWindow.ok=P\u00e4ivit\u00e4
-UpdateWindow.restart=K\u00e4ynnist\u00e4 Vuze uudelleen
-UpdateWindow.status.downloading=Ladataan
-UpdateWindow.status.done=Valmis
-UpdateWindow.status.failed=P\u00e4ivitys ep\u00e4onnistui
-UpdateWindow.status.restartNeeded=P\u00e4ivitt\u00e4minen vaatii Vuzen uudelleenk\u00e4ynnistyksen!
-ConfigView.pluginlist.broken=Ei kunnossa
-ConfigView.pluginlist.whereToPut=Aseta k\u00e4ytt\u00e4j\u00e4kohtaiset lis\u00e4osat omiin hakemistoihinsa seuraavan p\u00e4\u00e4hakemiston alle:
-ConfigView.pluginlist.whereToPutOr=Aseta kaikkien tietokoneen k\u00e4ytt\u00e4jien kesken jaetut lis\u00e4osat omiin hakemistoihinsa seuraavan p\u00e4\u00e4hakemiston alle:
-MainWindow.statusText.checking=Tarkastetaan p\u00e4ivitykset...
-TableColumn.header.OnlyCDing4=Tod. l\u00e4h.aika
-TableColumn.header.OnlyCDing4.info=Torrent-tiedoston l\u00e4hetysaika sen latauksen valmistumisesta l\u00e4htien.
-ConfigView.section.style.alternateTablePainting=S\u00e4vyt\u00e4 graafiset taulukoiden sarakkeet vaihtoehtoisella tavalla (saattaa vaatia uudelleenk\u00e4ynnistyksen)
-UpdateWindow.status.restartMaybeNeeded=P\u00e4ivitys vaatii ehk\u00e4 uud.k\u00e4ynnistyksen.
-ConfigView.pluginlist.shared=jaettu
-PeersView.host=Verkko-osoite
-PeersView.host.info=K\u00e4ytt\u00e4j\u00e4n symbolinen verkko-osoite, jos saatavilla.
-MainWindow.menu.help.whatsnew=Mit\u00e4 uutta t\u00e4ss\u00e4 versiossa?
-ConfigView.label.checkonstart=Tarkasta saatavilla olevat p\u00e4ivitykset k\u00e4ynnistett\u00e4ess\u00e4
-ConfigView.label.periodiccheck=Tarkasta saatavilla olevat p\u00e4ivitykset s\u00e4\u00e4nn\u00f6llisesti uudestaan
-ConfigView.label.opendialog=K\u00e4ynnist\u00e4 P\u00e4ivitysavustaja automaattisesti, jos p\u00e4ivitys on saatavilla
-MainWindow.updateavail=(P\u00e4ivitys saatavilla)
-MainWindow.status.unofficialversion=Vuze beetaversio
-MainWindow.status.latestversionunchecked=Uusimman version tarkastus ei k\u00e4yt\u00f6ss\u00e4
-GeneralView.label.updatein.stopped=Pys\u00e4ytetty
-StartStopRules.menu.viewDebug=Katso virheenm\u00e4\u00e4ritystiedot
-ConfigView.section.style.doNotUseGB=\u00c4l\u00e4 k\u00e4yt\u00e4 yksik\u00f6iss\u00e4 gigatavuja
-ConfigView.section.style.doNotUseGB.tooltip=Vuze jatkaa megatavujen k\u00e4ytt\u00e4mist\u00e4 yksikk\u00f6n\u00e4,\nkun luku ylitt\u00e4\u00e4 1024 Mt:a (yhden gigatavun).
-MainWindow.menu.help.plugins=Lis\u00e4osat
-ConfigView.section.plugins.TrackerWeb=Seurantapalvelimen sivu
-ConfigView.section.tracker.enablecategories=N\u00e4yt\u00e4 torrent-tiedostot omissa luokissaan
-health.explain.share=Torrent-tiedosto on joko asetettu seurantaan omalle seurantapalvelimelle tai julkistettu.
-ConfigView.section.tracker.createcert=Luo itseallekirjoitettu varmenne
-ConfigView.section.tracker.createbutton=Luo...
-security.certcreate.title=Itseallekirjoitettu varmenne
-security.certcreate.intro=T\u00e4ll\u00e4 toiminnolla voit luoda itseallekirjoitetun varmenteen.
-security.certcreate.alias=Nimi
-security.certcreate.strength=Vahvuus
-security.certcreate.firstlastname=Etu- ja sukunimi
-security.certcreate.orgunit=Organisaatioyksikk\u00f6
-security.certcreate.org=Organisaatio
-security.certcreate.city=Kaupunki
-security.certcreate.state=Maakunta
-security.certcreate.country=Kaksikirjaiminen maakoodi
-security.certcreate.ok=Luo
-security.certcreate.cancel=Peruuta
-security.certcreate.createok=Varmenne luotiin onnistuneesti.
-security.certcreate.createfail=Varmenteen luonti ep\u00e4onnistui.
-ConfigView.section.plugins.webui=Swing-et\u00e4k\u00e4ytt\u00f6liittym\u00e4
-ConfigView.section.plugins.xml_http_if=XML/HTTP-et\u00e4k\u00e4ytt\u00f6liittym\u00e4
-webui.passwordenable=K\u00e4yt\u00e4 salasanasuojausta
-webui.user=K\u00e4ytt\u00e4j\u00e4tunnus
-webui.password=Salasana
-webui.port=Portti (*)
-webui.protocol=Protokolla (*)
-webui.homepage=Kotisivu (*)
-webui.rootdir=P\u00e4\u00e4hakemisto (*)
-webui.rootres=P\u00e4\u00e4resurssi (*)
-webui.mode=Hallintatila (*)
-webui.mode.info=Hallintatila voi olla\n\t"full"\t= k\u00e4ytt\u00e4j\u00e4 pystyy hallitsemaan kaikkia et\u00e4k\u00e4ytt\u00f6liittym\u00e4n toimintoja (oletusasetus)\n\t"view"\t= k\u00e4ytt\u00e4j\u00e4 pystyy vaihtamaan vain et\u00e4k\u00e4ytt\u00f6liittym\u00e4n p\u00e4ivitysnopeutta, muilta osin pelkk\u00e4 katseluoikeus
-webui.access=P\u00e4\u00e4syoikeus (*)
-webui.access.info=P\u00e4\u00e4syoikeus voi olla\n\t"local"\t= yhteys sallitaan vain paikalliselta koneelta, eli silt\u00e4 koneelta, jolla Vuze on k\u00e4ynniss\u00e4\n\t"all"\t= rajoittamaton p\u00e4\u00e4syoikeus, kaikki yhteydet sallitaan (oletusasetus)\n\tIP\t= esim. 192.168.0.2 (yhteys sallitaan yksitt\u00e4isest\u00e4 IP-osoitteesta)\n\tIP1-IP2\t= esim. 192.168.0.1-192.168.0.255 (yhteydet sallitaan tietylt\u00e4 IP-osoitev\u00e4lilt\u00e4)
-GeneralView.label.maxdownloadspeed=Enimm\u00e4islatausnopeus
-Security.keystore.corrupt=Keystore-tiedostoa '%1' ei voitu ladata; poista se ja luo/hae varmenteet uudelleen.
-Security.keystore.empty=Keystore-tiedosto on tyhj\u00e4; luo joko itseallekirjoitettu varmenne (katso Ty\u00f6kalut | Asetukset | Suojaus) tai hae olemassa oleva varmenne tiedostolle '%1'.
-webui.restart.info=Jos asetus on merkitty t\u00e4hdell\u00e4 (*), t\u00e4ytyy Vuze k\u00e4ynnist\u00e4\u00e4 uudelleen, jotta muutokset kyseiseen asetukseen tulisivat voimaan.
-GeneralView.label.maxdownloadspeed.tooltip=- enimm\u00e4islatausnopeus (0 = rajoittamaton)
-ConfigView.section.UPnP=UPnP-m\u00e4\u00e4ritys
-upnp.enable=K\u00e4yt\u00e4 UPnP:t\u00e4
-upnp.info=Universal Plug and Play (UPnP) mahdollistaa automaattisen porttien m\u00e4\u00e4ritt\u00e4misen niihin verkkolaitteisiin, joissa UPnP on k\u00e4ytett\u00e4viss\u00e4.
-upnp.mapping.dataport=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
-upnp.mapping.tcptrackerport=Seurantapalvelimen TCP-portti
-upnp.mapping.udptrackerport=Seurantapalvelimen UDP-portti
-upnp.alert.differenthost=UPnP: M\u00e4\u00e4rityksen '%1' on varannut '%2' - valitse jokin toinen portti
-upnp.alert.mappingok=UPnP: M\u00e4\u00e4ritys '%1' muodostettu
-upnp.alert.mappingfailed=UPnP: M\u00e4\u00e4ritys '%1' ep\u00e4onnistui
-upnp.alertsuccess=Ilmoita onnistuneista m\u00e4\u00e4rityksist\u00e4
-upnp.alert.lostdevice=UPnP: Yhteys palveluun '%1' UPnP-laitteessa '%2' menetettiin
-upnp.grabports=M\u00e4\u00e4rit\u00e4 portit, vaikka ne olisivat toisen tietokoneen k\u00e4yt\u00f6ss\u00e4
-upnp.refresh.label=P\u00e4ivit\u00e4 m\u00e4\u00e4ritykset
-upnp.refresh.button=P\u00e4ivit\u00e4
-upnp.alert.mappinggrabbed=UPnP: M\u00e4\u00e4ritys '%1' muodostettu - haettu kohteelta '%2'
-upnp.mapping.tcpssltrackerport=Seurantapalvelimen TCP-portti (SSL)
-upnp.alertothermappings=Ilmoita porteista, jotka ovat toisen tietokoneen k\u00e4yt\u00f6ss\u00e4
-upnp.alertdeviceproblems=Ilmoita UPnP-laitteen ongelmatilanteista
-upnp.trace_to_log=Tulosta kaikki virheenm\u00e4\u00e4ritystiedot lokiin
-upnp.wiki_link=Katso lis\u00e4tietoja t\u00e4st\u00e4
-upnp.refresh_mappings_on_bad_nat=P\u00e4ivit\u00e4 porttim\u00e4\u00e4ritykset automaattisesti, jos NAT status on "firewalled"
-ConfigView.pluginlist.coreplugins=Seuraavat sis\u00e4\u00e4nrakennetut lis\u00e4osat ovat k\u00e4yt\u00f6ss\u00e4:
-Peers.column.DLedFromOthers=Muilta
-Peers.column.DLedFromOthers.info=K\u00e4ytt\u00e4j\u00e4n muilta lataama tietom\u00e4\u00e4r\u00e4 t\u00e4m\u00e4n yhteyden ollessa voimassa.
-Peers.column.UpDownRatio=L\u00e4h:Lad
-Peers.column.UpDownRatio.info=K\u00e4ytt\u00e4j\u00e4n l\u00e4hetys-lataussuhde.
-Peers.column.UpRatio=L\u00e4h.suhteet
-Peers.column.UpRatio.info=Oma l\u00e4hetysm\u00e4\u00e4r\u00e4 suhteessa muiden l\u00e4hetysm\u00e4\u00e4r\u00e4\u00e4n ko. k\u00e4ytt\u00e4j\u00e4lle.
-upnp.releasemappings=Vapauta porttim\u00e4\u00e4ritykset lopetettaessa
-webui.upnpenable=K\u00e4yt\u00e4 UPnP:t\u00e4 t\u00e4lle portille (*)
-ConfigView.section.file.friendly.hashchecking=K\u00e4yt\u00e4 resurssiyst\u00e4v\u00e4llist\u00e4 tapaa osien tarkastamiseen
-ConfigView.section.file.friendly.hashchecking.tooltip=Osien tiivisteet lasketaan ja tarkastetaan hieman hitaammin kuin normaalissa tilassa,\nmutta v\u00e4hemmill\u00e4 resursseilla (suoritink\u00e4ytt\u00f6/muistin k\u00e4ytt\u00f6).
-ConfigView.section.tracker.seedretention=S\u00e4ilytett\u00e4vien l\u00e4hteiden enimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto\n(0 = rajoittamaton)
-ConfigView.section.tracker.seedretention.info=Huom.: Muista l\u00e4hteist\u00e4 ei saada l\u00e4hetystilastoja.
-ConfigView.section.tracker.port=K\u00e4yt\u00e4 HTTP-porttia
-ConfigView.section.tracker.sslport=K\u00e4yt\u00e4 HTTPS-porttia
-ConfigView.section.tracker.publicenable.info=Sallii muiden k\u00e4ytt\u00e4\u00e4 seurantapalvelintasi ilman,\nett\u00e4 sin\u00e4 itse asetat torrent-tiedostoja seurantaan/julkaiset niit\u00e4.
-Button.clear=Tyhjenn\u00e4
-MainWindow.IPs.tooltip=IP-suotimien viimeisin p\u00e4ivitys: %1\nIP-suodinosoitealueiden m\u00e4\u00e4r\u00e4\n-> k\u00e4ytt\u00e4j\u00e4t t\u00e4m\u00e4n session aikana, jotka on\n- estetty IP-suotimien toimesta\n- estetty muutoin\n- ovat l\u00e4hett\u00e4neet korruptoitunutta tietoa.\nTuplaklikkaa n\u00e4hd\u00e4ksesi tarkemmat tiedot.
-ConfigView.section.ipfilter.list.banned=- yhteydenotto estetty
-ConfigView.section.ipfilter.list.baddata=l\u00e4hetti korruptoitunutta tietoa, esiintym\u00e4t:
-Button.reset=Tyhjenn\u00e4
-ConfigView.section.ipfilter.bannedinfo=Korruptoitunutta tietoa l\u00e4hett\u00e4neet - estetty tietyn rajan ylitytty\u00e4.
-ConfigView.section.ipfilter.blockedinfo=IP-suotimien toimesta estetyt yhteydet.
-download.removerules.name=Poistamiss\u00e4\u00e4nn\u00f6t
-download.removerules.unauthorised.info=Luvattomat torrent-tiedostot ovat sellaisia, jotka palauttavat virheilmoituksena joko tekstin "not authoris(z)ed" tai "unauthoris(z)ed" seurantapalvelimen tilaa tiedusteltaessa.
-download.removerules.unauthorised=Poista automaattisesti luvattomat torrent-tiedostot
-download.removerules.unauthorised.seedingonly=\tVain jos torrent-tiedostoa l\u00e4hetet\u00e4\u00e4n (lataus jo valmistunut)
-download.removerules.removed.ok=Torrent-tiedoston '%1' poistaminen onnistui. T\u00e4m\u00e4 tapahtui poistamiss\u00e4\u00e4nt\u00f6jen johdosta.
-download.removerules.updatetorrents=Poista automaattisesti p\u00e4ivitt\u00e4miseen k\u00e4ytetyt torrent-tiedostot, jos l\u00e4hett\u00e4miselle ei en\u00e4\u00e4 ole tarvetta
-ConfigView.label.defaultstarttorrentsstopped=Aseta avatut torrent-tiedostot oletuksena pys\u00e4ytetty-tilaan
-ConfigView.section.server.enableudp=K\u00e4yt\u00e4 UDP-protokollaa seurantapalvelinyhteyksiin
-upnp.mapping.dataportudp=Sis\u00e4\u00e4ntulevan UDP-liikenteen portti
-ConfigView.section.file.decoder.showlax=N\u00e4yt\u00e4 ep\u00e4todenn\u00e4k\u00f6iset koodausvaihtoehdot
-ConfigView.section.file.decoder.showall=Luettele kaikki mahdolliset koodausvaihtoehdot
-MainWindow.status.updowndetails.tooltip=Lataus- ja l\u00e4hetysnopeudet\n - Vaihda rajoituksia klikkaamalla hiiren kakkospainikkeella ja valitsemalla haluamasi arvot\n - Tuplaklikkaus avaa tilastot
-TrackerClient.announce.warningmessage=Torrent-tiedoston '%1' seurantapalvelin palautti varoituksen '%2'.
-ConfigView.section.tracker.natcheckenable=Tarkasta k\u00e4ytt\u00e4j\u00e4n sis\u00e4\u00e4ntulevan TCP-liikenteen portin toimivuus ja ilmoita ongelmista
-ConfigView.section.tracker.publishenabledetails=Julkaise kaikki tarkat tiedot torrent-tiedostoista
-ConfigView.section.tracker.publishenablepeerdetails=Julkaise tarkat tiedot k\u00e4ytt\u00e4jist\u00e4
-MyTrackerView.badnat=NAT-ongelmat
-MyTrackerView.badnat.info=K\u00e4ytt\u00e4j\u00e4t, jotka eiv\u00e4t l\u00e4p\u00e4isseet NAT-testi\u00e4 (jos testaus k\u00e4yt\u00f6ss\u00e4).
-ConfigView.section.tracker.natchecktimeout=Tarkastuksen aikakatkaisu (s)
-ConfigView.section.file.perf.cache.enable=K\u00e4yt\u00e4 v\u00e4limuistia
-ConfigView.section.file.perf.cache.size=V\u00e4limuistin koko (%1)
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
-MainWindow.menu.transfers=&Siirrot
-MainWindow.menu.transfers.startalltransfers=&K\u00e4ynnist\u00e4 kaikki
-MainWindow.menu.transfers.stopalltransfers=&Pys\u00e4yt\u00e4 kaikki
-MainWindow.menu.transfers.pausetransfers=K&eskeyt\u00e4
-MainWindow.menu.transfers.resumetransfers=&Jatka keskeytettyj\u00e4
-ConfigView.label.experimental.osx.kernel.panic.fix=Korjaa kaksiytimisten OSX-koneiden kernel panic -ongelmat (vaatii uud.k\u00e4yn.)
-SystemTray.menu.pausetransfers=K&eskeyt\u00e4 siirrot
-SystemTray.menu.resumetransfers=Jatka keskeytettyj\u00e4 siirtoja
-ConfigView.section.file.truncate.too.large=Pienenn\u00e4 olemassa olevat liian isot tiedostot oikeaan kokoonsa
-ConfigView.section.file.perf.cache.trace=J\u00e4ljit\u00e4 v\u00e4limuistioperaatiot virheenm\u00e4\u00e4rityst\u00e4 varten
-ConfigView.section.interface.enabletray=N\u00e4yt\u00e4 Vuzen kuvake ilmoitusalueella (vaatii uudelleenk\u00e4ynnistyksen)
-PeerManager.status.error=Virhe
-Stats.title.full=Tilastot
-TransferStatsView.title.full=Siirrot ja k\u00e4ytt\u00f6aika
-CacheView.title.full=V\u00e4limuisti
-CacheView.general.size=Koko yhteens\u00e4
-CacheView.general.inUse=K\u00e4yt\u00f6ss\u00e4
-CacheView.general.title=Tila
-CacheView.reads.title=Siirr\u00e4nt\u00e4luvut
-CacheView.reads.fromFile=Tiedostosta
-CacheView.reads.fromCache=V\u00e4limuistista
-CacheView.reads.hits=k\u00e4ytt\u00f6
-CacheView.writes.title=Siirr\u00e4nt\u00e4kirjoitukset
-CacheView.writes.toCache=V\u00e4limuistiin
-CacheView.writes.toFile=Tiedostoon
-CacheView.writes.hits=s\u00e4\u00e4stetty
-CacheView.speeds.title=Luku- ja kirjoitusnopeudet
-CacheView.speeds.reads=Luvut
-CacheView.speeds.writes=Kirjoitukset
-CacheView.speeds.fromCache=V\u00e4limuistista/\nv\u00e4limuistiin
-CacheView.speeds.fromFile=Tiedostosta/\ntiedostoon
-CacheView.reads.#=Kertaa
-CacheView.reads.amount=M\u00e4\u00e4r\u00e4
-CacheView.reads.avgsize=Keskim\u00e4\u00e4r\u00e4inen koko
-openUrl.referrer=Viittaavan sivun osoite:
-openUrl.referrer.info=Tarvitaan vain, jos sivusto vaatii t\u00e4t\u00e4.
-ConfigView.label.maxuploadspeedseeding=Vaihtoehtoinen nopeus ainoastaan l\u00e4hetett\u00e4ess\u00e4
-ConfigView.label.transfer.ignorepeerports=Est\u00e4 k\u00e4ytt\u00e4j\u00e4, jos sis\u00e4\u00e4ntulevan TCP-liikenteen porttina on (erota ;-merkill\u00e4, esim. 0;25)
-ConfigView.section.proxy.enable_socks.peer=K\u00e4yt\u00e4 v\u00e4lityspalvelinta (yhteydet ulosp\u00e4in, vaatii uudelleenk\u00e4ynnistyksen)
-ConfigView.section.proxy.peer.informtracker=Ilmoita seurantapalvelimelle, ett\u00e4 sis\u00e4\u00e4ntulevia yhteyksi\u00e4 ei voida ottaa vastaan
-ConfigView.section.proxy.socks.version=SOCKS-versio
-PiecesView.legend.written=Kirjoitettu levylle
-PiecesView.legend.requested=Pyydetty
-PiecesView.legend.downloaded=Ladattu, odottaa kirjoittamista
-PiecesView.legend.incache=Tieto on v\u00e4limuistissa
-PiecesView.typeItem.0=Hidas
-PiecesView.typeItem.1=Nopea
-PiecesView.type=Tyyppi
-Security.jar.tools_not_found=JAR-allekirjoitus ep\u00e4onnistui - tools.jar-tiedostoa ei l\u00f6ytynyt kohteesta %1. Katso lis\u00e4tietoja kohdasta Ty\u00f6kalut | Asetukset | Suojaus.
-Security.jar.signfail=JAR-allekirjoitus ep\u00e4onnistui - %1
-ConfigView.section.security.toolsinfo=Er\u00e4\u00e4t Vuzen lis\u00e4osat, kuten Swing-et\u00e4k\u00e4ytt\u00f6liittym\u00e4, k\u00e4ytt\u00e4v\u00e4t tarvittaessa ns. varmennettuja JAR-tiedostoja.\n\nJAR-tiedostojen varmentamiseen tarvitset tools.jar-tiedoston, joka tulee Sunin JDK:n (Java Development Kit) mukana.\nJos olet asentanut vain JRE:n (Java Runtime Environment), tarvitsee sinun siis asentaa JDK.\n\nYleens\u00e4 Vuze l\u00f6yt\u00e4\u00e4 tools.jar-tiedoston sijainnin automaatt [...]
-ConfigView.section.security.toolsdir=Tools.jar-tiedoston sijainti
-ConfigView.section.security.choosetoolssavedir=Valitse tools.jar-tiedoston sis\u00e4lt\u00e4v\u00e4 hakemisto
-authenticator.torrent=Torrent-tiedosto
-ConfigView.section.proxy.peer.same=K\u00e4yt\u00e4 samaa v\u00e4lityspalvelinta kuin yhteyksiss\u00e4 seurantapalvelimiin
-ConfigView.section.connection.network.max.simultaneous.connect.attempts=Yht\u00e4aikaisesti ulosp\u00e4in luotavien yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Huom.: Windows XP -tuoteperheen SP2-p\u00e4ivityspaketti rajoittaa automaattisesti ulosp\u00e4in luotavat yhteydet kymmeneen.\nAsetuksen oletusarvo on 8.
-ConfigView.section.file.perf.cache.size.explain=V\u00e4limuistia k\u00e4ytet\u00e4\u00e4n v\u00e4hent\u00e4m\u00e4\u00e4n tiedon lukua kiintolevylt\u00e4/kirjoittamista kiintolevylle. Jos et k\u00e4yt\u00e4 Javan -XX:MaxDirectMemorySize -asetusta muistim\u00e4\u00e4r\u00e4n asettamiseen v\u00e4limuisti- ja verkkosiirr\u00e4nt\u00e4k\u00e4ytt\u00f6\u00e4 varten, sinun tulisi pit\u00e4\u00e4 t\u00e4m\u00e4 arvo v\u00e4hint\u00e4\u00e4n %1:\u00e4 alle virtuaalimuistisi enimm\u00e4ism\u00e4\ [...]
-MyTorrentsView.menu.setSpeed.unlimit=Rajoittamaton
-MyTorrentsView.menu.setSpeed.unlimited=Rajoittamaton
-MyTorrentsView.menu.setSpeed.disable=\u00c4l\u00e4 l\u00e4het\u00e4
-MyTorrentsView.menu.setSpeed.disabled=Ei l\u00e4hetet\u00e4
-MyTorrentsView.menu.setSpeed.in=jaettuna
-MyTorrentsView.menu.setSpeed.slots=paikkaan, kullekin
-GeneralView.label.maxuploadspeed=Enimm\u00e4isl\u00e4hetysnopeus
-GeneralView.label.maxuploadspeed.tooltip=- enimm\u00e4isl\u00e4hetysnopeus (0 = rajoittamaton)
-MyTorrents.items.UpSpeedLimit.disabled=Ei l\u00e4hetet\u00e4
-MyTorrents.items.UpSpeedLimit.unlimited=Rajoittamaton
-TableColumn.header.maxupspeed=Enim.l\u00e4h.nopeus
-TableColumn.header.maxupspeed.info=Torrent-tiedoston enimm\u00e4isl\u00e4hetysnopeus.
-ConfigView.section.file.perf.cache.enable.write=Siirr\u00e4 ladattu tieto v\u00e4limuistiin levylle kirjoituksen v\u00e4hent\u00e4miseksi ja levylt\u00e4 lukemisen v\u00e4hent\u00e4miseksi osia tarkastettaessa
-ConfigView.section.file.perf.cache.enable.read=Lue tiedostoja ennakoidusti v\u00e4limuistiin levylt\u00e4 lukemisen v\u00e4hent\u00e4miseksi tiedostoja l\u00e4hetett\u00e4ess\u00e4
-ConfigView.section.tracker.separatepeerids=K\u00e4yt\u00e4 eri k\u00e4ytt\u00e4j\u00e4tunnisteita seurantapalvelin- ja tiedonsiirtoyhteyksiss\u00e4
-ConfigView.section.tracker.separatepeerids.info=Lis\u00e4\u00e4 anonymiteettia, jos siirret\u00e4\u00e4n tietoa anonyymisti\nk\u00e4ytett\u00e4ess\u00e4 ei-anonyymista yhteytt\u00e4 seurantapalvelimeen.
-ConfigView.section.interface.wavlocation=Valitse .wav-tiedosto
-ConfigView.section.interface.wavlocation.info=.wav tai j\u00e4t\u00e4 tyhj\u00e4ksi (oletus\u00e4\u00e4ni)
-ConfigView.section.tracker.server=Oma seurantapalvelin
-ConfigView.section.tracker.client=Asiakasyhteys
-ConfigView.section.tracker.client.connecttimeout=Yhteydenoton aikakatkaisu (sekunneissa)
-ConfigView.section.tracker.client.readtimeout=Tietojen vastaanottamisen aikakatkaisu (sekunneissa)
-MainWindow.menu.tools=Ty&\u00f6kalut
-FilesView.path=Hakemisto
-FilesView.fullpath=N\u00e4yt\u00e4 koko polku
-FilesView.remaining=Osia j\u00e4ljell\u00e4
-TableColumn.header.trackername=Seurantapalvelin
-TableColumn.header.trackername.info=Seurantapalvelimen nimi perustuen sen p\u00e4ivitysosoitteeseen.
-ConfigView.group.override=Ohitusasetukset
-ConfigView.section.file.perf.cache.notsmallerthan=\u00c4l\u00e4 siirr\u00e4 t\u00e4st\u00e4 pienempi\u00e4 tiedostoja v\u00e4limuistiin (%1)
-PeersView.menu.blockupload=Est\u00e4 l\u00e4hett\u00e4minen
-PeersView.menu.kickandban=Sulje yhteys ja est\u00e4 yhteydenotot
-PeersView.menu.kickandban.reason=Manuaalisesti estetty
-PeersView.state=Tila
-PeersView.state.info=Yhteyden tila k\u00e4ytt\u00e4j\u00e4\u00e4n.
-PeersView.state.pending=Odottava
-PeersView.state.connecting=Yhdistet\u00e4\u00e4n
-PeersView.state.handshake=Odotetaan k\u00e4ttely\u00e4
-PeersView.state.established=Muodostettu
-ConfigView.section.tracker.processinglimits=K\u00e4sittelyrajoitukset
-ConfigView.section.tracker.maxgettime=GET-k\u00e4sittelyn enimm\u00e4isaika sekunneissa (0 = rajoittamaton)
-ConfigView.section.tracker.maxgettime.info=K\u00e4ytet\u00e4\u00e4n p\u00e4ivityksiss\u00e4 ja pikap\u00e4ivityksiss\u00e4.
-ConfigView.section.tracker.maxposttimemultiplier=GET-ajan kerroin POST-k\u00e4sittelylle (0 = rajoittamaton)
-ConfigView.section.tracker.maxposttimemultiplier.info=K\u00e4ytet\u00e4\u00e4n lomaketietojen l\u00e4hett\u00e4misess\u00e4 ja siirroissa.
-ConfigView.section.tracker.maxthreads=Yht\u00e4aikaisten pyynt\u00f6jen enimm\u00e4ism\u00e4\u00e4r\u00e4
-DownloadManager.error.operationcancancelled=Toiminto peruutettu
-Torrent.create.progress.cancelled=Toiminto peruutettu
-sharing.progress.cancel=Peruuta
-wizard.maketorrents.autoopen=Kun torrent-tiedosto on luotu, avaa se suoraan l\u00e4hetett\u00e4v\u00e4ksi
-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 - E [...]
-ConfigView.section.connection.advanced.SO_RCVBUF=Pistokkeen SO_RCVBUF-koko (0 = k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n oletusarvo)
-ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=SO_RCVBUF-arvolla m\u00e4\u00e4ritell\u00e4\u00e4n pistokkeen vastaanottopuskurin koko tavuissa.\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nHuom.: Linux-k\u00e4yt\u00f6ss\u00e4 arvo kaksinkertaistuu automaattisesti.
-ConfigView.section.connection.advanced.SO_SNDBUF=Pistokkeen SO_SNDBUF-koko (0 = k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n oletusarvo)
-ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=SO_SNDBUF-arvolla m\u00e4\u00e4ritell\u00e4\u00e4n pistokkeen l\u00e4hetyspuskurin koko tavuissa.\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nHuom.: Linux-k\u00e4yt\u00f6ss\u00e4 arvo kaksinkertaistuu automaattisesti.
-ConfigView.section.connection.advanced.IPDiffServ=Ulosmenevien pakettien liikenteen luokka/palvelu (TOS / type-of-service)
-ConfigView.section.connection.advanced.IPDiffServ.tooltip=Voit m\u00e4\u00e4ritt\u00e4\u00e4 ulosmenevien pakettien IP-otsakkeisiin liikenteen luokan/palvelun (type-of-service).\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nEsimerkkej\u00e4 mahdollisista arvoista:\n0x02 = IPTOS_LOWCOST\n0x04 = IPTOS_RELIABILITY\n0x08 = IPTOS_THROUGHPUT\n0x10 = IPTOS_LOWDELAY\nHuom.: [...]
-ConfigView.section.interface.confirm_torrent_removal=Pyyd\u00e4 vahvistus torrent-tiedostoa poistettaessa
-ConfigView.section.interface.confirm_torrent_removal.tooltip=K\u00e4ytt\u00e4j\u00e4lt\u00e4 pyydet\u00e4\u00e4n vahvistus torrent-tiedostoa poistettaessa Siirrot-n\u00e4kym\u00e4st\u00e4.
-MyTorrentsView.confirm_torrent_removal=Haluatko varmasti poistaa t\u00e4m\u00e4n torrent-tiedoston?\n
-TableColumn.header.seed_to_peer_ratio=K\u00e4ytt\u00e4j\u00e4suhde
-TableColumn.header.seed_to_peer_ratio.info=Kaikkien l\u00e4hteiden lukum\u00e4\u00e4r\u00e4n suhde kaikkien lataajien lukum\u00e4\u00e4r\u00e4\u00e4n.
-PeersView.connected_time=Aika
-PeersView.connected_time.info=Yhteysaika k\u00e4ytt\u00e4j\u00e4\u00e4n.
-ConfigView.section.interface.display.add_torrents_silently=Avaa torrent-tiedostot aktivoimatta Vuzea
-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=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
-ConfigView.section.sharing.torrentcomment=Kommentti, joka lis\u00e4t\u00e4\u00e4n luotaviin torrent-tiedostoihin
-ConfigView.label.copyanddeleteratherthanmove=Kopioi ja poista alkuper\u00e4iset tiedostot siirt\u00e4misen sijaan - ehk\u00e4isee tietojen menett\u00e4mist\u00e4 ongelmatilanteissa
-ConfigView.label.openstatsonstart=Avaa tilastot k\u00e4ynnistett\u00e4ess\u00e4
-swt.install.window.title=Vuzen lis\u00e4osien asennus
-swt.install.window.ok=Asenna
-swt.install.window.header=Seuraavat osat on valittu asennettavaksi:
-swt.uninstall.window.title=Vuzen lis\u00e4osien poistaminen
-swt.uninstall.window.ok=Poista
-swt.uninstall.window.header=Seuraavat osat on valittu poistettavaksi:
-installPluginsWizard.title=Asenna lis\u00e4osia
-installPluginsWizard.mode.title=Valitse lis\u00e4osien l\u00e4hde
-installPluginsWizard.mode.list=Valitsemalla listasta (ladataan SourceForge.netist\u00e4)
-installPluginsWizard.list.title=Asennettavat lis\u00e4osat
-installPluginsWizard.list.loading=Odota hetki, kunnes lis\u00e4osien lista on ladattu.
-installPluginsWizard.list.loaded=Valitse lis\u00e4osat, jotka haluat asentaa:
-installPluginsWizard.list.name=Nimi
-installPluginsWizard.list.version=Versio
-installPluginsWizard.list.description=Lis\u00e4osan kuvaus:
-installPluginsWizard.finish.title=Asennus k\u00e4ynniss\u00e4
-installPluginsWizard.finish.explanation=Valitut lis\u00e4osat asennetaan k\u00e4ytt\u00e4en Vuzen P\u00e4ivitysavustajaa.\n\nOle k\u00e4rsiv\u00e4llinen, sill\u00e4 P\u00e4ivitysavustajan ilmestyminen ruudulle\nsaattaa kest\u00e4\u00e4 hetkisen.
-installPluginsWizard.details.loading=Ladataan tietoja, odota hetki...
-installPluginsWizard.mode.file=Suoraan tiedostosta
-installPluginsWizard.installMode.title=Valitse asennustapa
-installPluginsWizard.installMode.user=Asenna lis\u00e4osa(t) vain sinun k\u00e4ytt\u00f6\u00f6si
-installPluginsWizard.installMode.shared=Asenna lis\u00e4osa(t) kaikille tietokoneen k\u00e4ytt\u00e4jille
-installPluginsWizard.file.title=Etsi lis\u00e4osa, jonka haluat asentaa.
-installPluginsWizard.file.file=Tiedosto:
-installPluginsWizard.file.invalidfile=Tiedosto ei ole kelvollinen Vuzen lis\u00e4osa.
-installPluginsWizard.file.no_such_file=Tiedostoa ei l\u00f6ydy.
-installPluginsWizard.file.browse=Selaa...
-uninstallPluginsWizard.title=Poista lis\u00e4osia
-uninstallPluginsWizard.list.title=Asennetut lis\u00e4osat
-uninstallPluginsWizard.list.loaded=Valitse lis\u00e4osat, jotka haluat poistaa:
-installPluginsWizard.list.nullversion=Ei versionumeroa
-uninstallPluginsWizard.finish.title=Poistaminen k\u00e4ynniss\u00e4
-uninstallPluginsWizard.finish.explanation=Valitut lis\u00e4osat poistetaan k\u00e4ytt\u00e4en P\u00e4ivitysavustajaa.
-MainWindow.menu.plugins.installPlugins=Ohjattu asennustoiminto...
-MainWindow.menu.plugins.uninstallPlugins=Ohjattu poistotoiminto...
-ConfigView.section.ipfilter.totalIPs=%1 IP-osoitetta estetty yhteens\u00e4, joka on %2 kaikista osoitteista Internetiss\u00e4.
-update.instance.install=Tarkastetaan asennusteht\u00e4v\u00e4t
-update.instance.uninstall=Tarkastetaan poistoteht\u00e4v\u00e4t
-update.instance.update=Tarkastetaan p\u00e4ivitykset
-MainWindow.status.update.tooltip=Tuplaklikkaa n\u00e4hd\u00e4ksesi tarkemmat tiedot edistymisest\u00e4.
-updater.progress.window.title=Asennusteht\u00e4v\u00e4t
-updater.progress.window.info=Valitse Keskeyt\u00e4 peruuttaaksesi kaikki suorittamattomat teht\u00e4v\u00e4t.
-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\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
-deletetorrent.message2=\nHaluatko varmasti jatkaa?
-ConfigView.label.prioritizemostcompletedfiles=Pyri lataamaan ensisijaisesti l\u00e4himp\u00e4n\u00e4 valmistumista olevia korkean prioriteetin tiedostoja
-splash.plugin.init=Alustetaan lis\u00e4osaa - 
-splash.plugin.UIinit=Alustetaan lis\u00e4osan graafista k\u00e4ytt\u00f6liittym\u00e4\u00e4: %1
-ConfigView.section.style.osx_small_fonts=K\u00e4yt\u00e4 pieni\u00e4 kirjasinkokoja (vaatii uudelleenk\u00e4ynnistyksen)
-ConfigView.section.tracker.tcpnonblocking=K\u00e4yt\u00e4 ei-rajoittavaa siirr\u00e4nt\u00e4\u00e4 TCP-k\u00e4sittelyss\u00e4. Jos k\u00e4yt\u00f6ss\u00e4, seurantapalvelimen sivun t\u00e4ytyy k\u00e4ytt\u00e4\u00e4 toista porttia. Kokeellinen!
-ConfigView.section.tracker.nonblocking=Siirr\u00e4nn\u00e4n rajoittaminen
-ConfigView.section.tracker.nonblockingconcmax=Yht\u00e4aikaisten yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
-MyTorrentsView.menu.exportmenu=Vie
-MyTorrentsView.menu.exporttorrent=torrent-tiedostoksi...
-ConfigView.group.scrape=Pikap\u00e4ivitykset
-ConfigView.section.tracker.client.scrapeinfo=Pikap\u00e4ivitysten ohittaminen est\u00e4\u00e4 monien siirtojonos\u00e4\u00e4nt\u00f6jen toimimisen, sill\u00e4 ne ovat riippuvaisia seurantapalvelimien pikap\u00e4ivitystiedoista.
-ConfigView.section.tracker.client.scrapeenable=K\u00e4yt\u00e4 pikap\u00e4ivityksi\u00e4
-ConfigView.section.tracker.client.scrapestoppedenable=Tee pikap\u00e4ivitykset pys\u00e4ytetyille torrent-tiedostoille
-Scrape.status.disabled=Pikap\u00e4ivitys ei k\u00e4yt\u00f6ss\u00e4
-MyTorrentsView.menu.explore=N\u00e4yt\u00e4
-MyTorrentsView.menu.explore._mac=N\u00e4yt\u00e4 Finderissa
-MyTorrentsView.menu.explore._windows=N\u00e4yt\u00e4 Windows Explorerissa
-wizard.maketorrents.autohost=Aseta torrent-tiedosto seurantaan omalle seurantapalvelimelle
-ConfigView.label.overrideip=Ohita seurantapalvelimelle n\u00e4kyv\u00e4 IP-osoite - erota puolipisteill\u00e4, jos useita osoitteita eri verkoille
-ConfigView.label.overrideip.tooltip=Ilmoittaa seurantapalvelimelle m\u00e4\u00e4ritetyn IP-osoitteen (tai osoitteet) sen sijaan, mist\u00e4 tietoa oikeasti l\u00e4hetet\u00e4\u00e4n.\nJ\u00e4t\u00e4 tyhj\u00e4ksi, jos et halua k\u00e4ytt\u00e4\u00e4 t\u00e4t\u00e4 asetusta.
-ConfigView.section.connection.group.networks=Verkot
-ConfigView.section.connection.group.networks.info=Valitse oletusverkot, joissa sallitaan varsinaisen siirrett\u00e4v\u00e4n tiedon liikkuminen
-ConfigView.section.connection.networks.prompt=Kysy valintaa, jos torrent-tiedosto k\u00e4ytt\u00e4\u00e4 anonyymista seurantapalvelinta (verkkoa)
-ConfigView.section.connection.networks.Public=Julkinen IP-verkko (ei anonyyminen)
-ConfigView.section.connection.networks.I2P=I2P-verkko
-ConfigView.section.connection.networks.Tor=The Onion Router (Tor) -verkko
-TableColumn.header.networks=Verkot
-TableColumn.header.networks.info=Verkot, joissa sallitaan varsinaisen siirrett\u00e4v\u00e4n tiedon liikkuminen.
-Scrape.status.networkdisabled=Verkko ei k\u00e4ytett\u00e4viss\u00e4
-ConfigView.section.tracker.server.group.networks=Verkot
-ConfigView.section.tracker.server.group.networks.info=Valitse verkot, joihin hyv\u00e4ksyt\u00e4\u00e4n k\u00e4ytt\u00e4ji\u00e4:
-window.networkselection.title=Verkkojen valitseminen
-window.networkselection.info=Alla olevan torrent-tiedoston seurantapalvelimet tukevat seuraavia verkkoja.\nValitse ne, joita haluat k\u00e4ytt\u00e4\u00e4 yhteyksiss\u00e4 seurantapalvelimiin ja k\u00e4ytt\u00e4jiin.\nJos kyseess\u00e4 on anonyyminen seurantapalvelin, joka tukee julkisia yhteyksi\u00e4, k\u00e4yt\u00e4 sek\u00e4\nanonyymista ett\u00e4 julkista verkkoa.\nJulkisen verkon k\u00e4ytt\u00e4misest\u00e4 seuraa luonnollisesti se, ett\u00e4 anonymiteetti h\u00e4vi\u00e4\u00e4.
-window.networkselection.description=Torrent-tiedosto:
-plugins.basicview.clear=Tyhjenn\u00e4
-ConfigView.section.connection.group.peersources=K\u00e4ytt\u00e4j\u00e4t
-ConfigView.section.connection.group.peersources.info=Valitse oletustietol\u00e4hteet, joista saadut k\u00e4ytt\u00e4j\u00e4t voivat muodostaa yhteyden
-ConfigView.section.connection.peersource.Tracker=Seurantapalvelimen palauttamat tiedot
-ConfigView.section.connection.peersource.DHT=Hajautettu k\u00e4ytt\u00e4jien seuranta (DHT)
-ConfigView.section.connection.peersource.PeerExchange=K\u00e4ytt\u00e4jien luovuttamat tiedot
-ConfigView.section.connection.peersource.Plugin=Lis\u00e4osan lis\u00e4\u00e4m\u00e4 yhteystieto
-ConfigView.section.connection.peersource.Incoming=Sis\u00e4\u00e4ntulevat yhteydet
-PeersView.source=L\u00e4hde
-PeersView.source.info=L\u00e4hde, josta kyseisen k\u00e4ytt\u00e4j\u00e4n tiedot on saatu selville.
-TableColumn.header.peersources=Tietol\u00e4hteet
-TableColumn.header.peersources.info=Tietol\u00e4hteet, joista saadut k\u00e4ytt\u00e4j\u00e4t voivat muodostaa yhteyden.
-wizard.tracker.dht=Hajautettu k\u00e4ytt\u00e4jien seuranta (vain Vuze-asiakasohjelmat)
-MyTorrentsView.menu.advancedmenu=Lis\u00e4asetukset
-MyTorrentsView.menu.networks=K\u00e4ytett\u00e4v\u00e4t verkot
-MyTorrentsView.menu.peersource=K\u00e4ytt\u00e4jien etsiminen
-ConfigView.section.sharing.permitdht=Hajautettu k\u00e4ytt\u00e4jien seuranta, kun seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4
-ConfigView.section.sharing.protocol=Protokolla jaetuille resursseille
-PeersView.Messaging=Viestint\u00e4
-PeersView.Messaging.info=K\u00e4ytett\u00e4v\u00e4 viestint\u00e4j\u00e4rjestelm\u00e4.
-ConfigView.label.queue.newseedsmovetop=Siirr\u00e4 viimeksi valmistuneet torrent-tiedostot l\u00e4hetysjonon k\u00e4rkeen
-ConfigView.label.seeding.firstPriority.ignore.info=Huomaa, ett\u00e4 n\u00e4iden ohituss\u00e4\u00e4nt\u00f6jen k\u00e4ytt\u00e4minen saattaa johtaa siihen, ett\u00e4\ntorrent-tiedosto pys\u00e4ytet\u00e4\u00e4n heti kun lataus on valmistunut.
-ConfigView.label.seeding.firstPriority.ignore=Ohita yll\u00e4 olevat s\u00e4\u00e4nn\u00f6t torrent-tiedostojen kohdalla
-ConfigView.label.seeding.firstPriority.ignoreSPRatio=joiden l\u00e4hteit\u00e4/lataajia-suhdeluku on yli
-ConfigView.label.seeding.firstPriority.ignore0Peer=joilla ei ole yht\u00e4\u00e4n lataajaa
-ConfigView.section.tracker.sendjavaversionandos=L\u00e4het\u00e4 tiedot Javan versiosta ja k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4st\u00e4
-MagnetPlugin.contextmenu.exporturi=Kopioi Magnet URI -linkki leikep\u00f6yd\u00e4lle
-ConfigView.section.plugins.dht=Hajautettu tietokanta
-dht.info=T\u00e4m\u00e4 lis\u00e4osa mahdollistaa mm. hajautetun k\u00e4ytt\u00e4jien seurannan - k\u00e4ytt\u00e4m\u00e4tt\u00e4 j\u00e4tt\u00e4minen vaikuttaa alentavasti latausnopeuksiin.
-dht.enabled=K\u00e4yt\u00e4 hajautettua tietokantaa
-dht.portdefault=K\u00e4yt\u00e4 oletusporttia
-dht.port=Hajautetun tietokannan UDP-portti
-dht.execute.command=Virheenm\u00e4\u00e4rityskomento
-dht.execute.info=Suorita komento
-dht.execute=Suorita
-dht.logging=Seuraa toimintaa
-ConfigView.section.plugins.dhttracker=Hajautettu seurantapalvelin
-dhttracker.tracknormalwhenoffline=Seuraa normaaleja torrent-tiedostoja vain, kun niiden seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4
-ConfigView.section.file.nativedelete._mac=K\u00e4yt\u00e4 Roskakoria tiedostoja tuhottaessa
-ConfigView.section.file.nativedelete._windows=Siirr\u00e4 tuhotut tiedostot Roskakoriin
-ConfigView.section.logging.generatediagnostics=Luo
-ConfigView.section.logging.netinfo=Luo verkon tiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
-ConfigView.section.logging.statsinfo=Luo tilastotiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
-ConfigView.section.logging.generatediagnostics.info=Luo virheenm\u00e4\u00e4ritystiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
-ConfigView.section.sharing.privatetorrent=Yksityinen jako - vain oman seurantapalvelimen k\u00e4ytt\u00e4j\u00e4t hyv\u00e4ksyt\u00e4\u00e4n
-MainWindow.menu.tools.nattest=&NAT- ja palomuuritesti
-Button.apply=K\u00e4yt\u00e4
-Button.close=Sulje
-window.welcome.title=Tervetuloa k\u00e4ytt\u00e4m\u00e4\u00e4n Vuzen versiota %1!
-#file can be a URL or a path in the jar
-MainWindow.menu.help.releasenotes=Julkaisutiedot
-dht.reseed.label=Normaalisti hajautetun tietokannan uudelleenjakoon ei ole tarvetta. Jos yhteystietojen m\u00e4\u00e4r\u00e4 on kuitenkin pieni, voidaan t\u00e4ll\u00e4 kasvattaa tietojen m\u00e4\u00e4r\u00e4\u00e4.\nJ\u00e4t\u00e4 kent\u00e4t tyhj\u00e4ksi yhdist\u00e4\u00e4ksesi tietoja kaikilta yhdistetyilt\u00e4 k\u00e4ytt\u00e4jilt\u00e4 tai m\u00e4\u00e4rit\u00e4 IP-osoite ja portti tehd\u00e4ksesi saman vain tietyn k\u00e4ytt\u00e4j\u00e4n kanssa.
-dht.reseed.group=Uudelleenjako
-dht.reseed.ip=IP-osoite
-dht.reseed.port=Portti
-dht.reseed=Jaa
-dht.reseed.info=Jaa tietokanta uudelleen
-dht.diagnostics.group=Virheenm\u00e4\u00e4ritys
-DHTView.title.full=Hajautettu tietokanta
-DHTView.title.fullcvs=Hajautettu tietokanta (CVS)
-DHTView.general.title=Yleiset
-DHTView.general.uptime=K\u00e4ytt\u00f6aika:
-DHTView.general.users=K\u00e4ytt\u00e4j\u00e4t:
-DHTView.general.nodes=Solmut:
-DHTView.general.leaves=Lehti\u00e4:
-DHTView.general.contacts=Yhteydet:
-DHTView.general.replacements=Varalla:
-DHTView.general.live=El\u00e4v\u00e4t:
-DHTView.general.unknown=Vieraat:
-DHTView.general.dying=Kuolevat:
-DHTView.transport.title=Siirrot
-DHTView.transport.packets=Paketit
-DHTView.transport.bytes=Tavut
-DHTView.transport.received=Vastaanotetut
-DHTView.transport.sent=L\u00e4hetetyt
-DHTView.transport.in=Sis\u00e4\u00e4n:
-DHTView.transport.out=Ulos:
-DHTView.operations.title=Toiminnan tarkemmat tiedot
-DHTView.operations.sent=L\u00e4hetetyt
-DHTView.operations.ok=Onnistuneet
-DHTView.operations.failed=Ep\u00e4onnistuneet
-DHTView.operations.received=Vastaanotetut
-DHTView.operations.ping=Vasteaikojen haut
-DHTView.operations.findNode=Solmujen etsint\u00e4
-DHTView.operations.findValue=Arvojen etsint\u00e4
-DHTView.operations.store=Tallennukset
-DHTView.activity.title=Toiminta
-DHTView.activity.status=Tila
-DHTView.activity.status.true=Jonossa
-DHTView.activity.status.false=K\u00e4yt\u00f6ss\u00e4
-DHTView.activity.type=Tyyppi
-DHTView.activity.type.1=Sis\u00e4inen haku
-DHTView.activity.type.2=Ulkoinen haku
-DHTView.activity.type.3=Sis\u00e4inen asetus
-DHTView.activity.type.4=Ulkoinen asetus
-DHTView.activity.target=Kohde
-DHTView.activity.details=Tarkemmat tiedot
-DHTView.db.title=Tietokanta
-DHTView.db.keys=Avaimet
-DHTView.db.values=Arvot
-DHTView.db.local=Paikalliset
-DHTView.db.direct=Suorat
-DHTView.db.indirect=Ep\u00e4suorat
-DHTView.db.divfreq=Taajuuden jakaja
-DHTView.db.divsize=Koon jakaja
-MainWindow.dht.status.tooltip=Kun hajautettu tietokanta on k\u00e4yt\u00f6ss\u00e4, n\u00e4et t\u00e4st\u00e4 kytkettyin\u00e4 olevien k\u00e4ytt\u00e4jien arvioidun m\u00e4\u00e4r\u00e4n.
-MainWindow.dht.status.disabled=DHT ei k\u00e4yt\u00f6ss\u00e4
-MainWindow.dht.status.failed=DHT:n k\u00e4ytt\u00f6\u00f6notto ep\u00e4onnistui
-MainWindow.dht.status.initializing=Alustetaan DHT:t\u00e4
-MainWindow.dht.status.users=%1 k\u00e4ytt\u00e4j\u00e4\u00e4
-MainWindow.dht.status.unreachable=DHT:n k\u00e4ytt\u00f6 estetty
-MainWindow.dht.status.unreachabletooltip=Hajautetun tietokannan (DHT:n) UDP-portin k\u00e4yt\u00f6ss\u00e4 on havaittu ongelmia\n - palomuuri est\u00e4\u00e4 liikenteen/NAT-ongelma
-MyTorrentsView.menu.setUpSpeed=L\u00e4hetysnopeus
-MyTorrentsView.menu.setDownSpeed=Latausnopeus
-ConfigView.section.tracker.client.showwarnings=N\u00e4yt\u00e4 seurantapalvelimien palauttamat varoitusviestit
-dht.advanced=K\u00e4yt\u00e4 lis\u00e4asetuksia
-dht.advanced.group=Lis\u00e4asetukset
-dht.advanced.label=Vaihda n\u00e4it\u00e4 asetuksia vain, jos todella tied\u00e4t mit\u00e4 olet tekem\u00e4ss\u00e4.
-dht.override.ip=Ohita ulkoinen IP-osoite
-ConfigView.section.logging.loggerenable=Kirjaa tapahtumat lokiin (n\u00e4ht\u00e4vill\u00e4 konsolissa)
-ConfigView.section.ipfilter.blockbanning=Est\u00e4 koko 256 osoitteen osoiteryhm\u00e4, kun v\u00e4hint\u00e4\u00e4n n\u00e4in monta osoitetta ryhm\u00e4n sis\u00e4lt\u00e4 on jo estetty
-MyTrackerView.passive=Passiivinen
-TableColumn.header.swarm_average_speed=Keskim. nopeus
-TableColumn.header.swarm_average_speed.info=K\u00e4ytt\u00e4jien keskim\u00e4\u00e4r\u00e4inen siirtonopeus
-TableColumn.header.comment=Kommentti
-TableColumn.header.comment.info=Oma kommentti siirrolle.
-TableColumn.header.commenticon=Kommentoitu
-TableColumn.header.commenticon.info=N\u00e4ytt\u00e4\u00e4 ikonin, jos siirrolle on asetettu oma kommentti.
-MyTrackerView.category=Luokka
-MainWindow.menu.file.open.torrentfortracking=Torrent-tiedosto... (seurantaa varten)
-VivaldiView.title.full=Vivaldi-n\u00e4kym\u00e4
-MyTrackerView.date_added=Lis\u00e4tty
-ConfigView.section.tracker.portbackup=Varaportit (erota ;-merkill\u00e4)
-ConfigView.label.playfilespeech=Kerro tiedoston valmistumisesta puheella
-ConfigView.label.playfilespeech.info=Puhepalvelu toimii toistaiseksi parhaiten englanniksi.
-ConfigView.label.playfilefinished=Anna \u00e4\u00e4nimerkki yksitt\u00e4isen tiedoston valmistuttua
-ConfigView.label.backupconfigfiles=Varmuuskopioi asetustiedostot tietojen palauttamisen varalta
-ConfigView.section.tracker.client.scrapesingleonly=Est\u00e4 seurantapalvelinkohtaiset pikap\u00e4ivitysker\u00e4ym\u00e4t (k\u00e4yt\u00e4, jos seurantapalvelin antaa 'URL too long' (414) -virhesanomia)
-dht.ipfilter.log=N\u00e4yt\u00e4 lokissa IP-suotimien est\u00e4m\u00e4t k\u00e4ytt\u00e4j\u00e4t
-ConfigView.label.seeding.addForSeedingDLCopyCount=Avattaessa torrent-tiedosto pelkk\u00e4\u00e4 l\u00e4hett\u00e4mist\u00e4 varten, aseta latauskertoimeksi
-ActivityView.legend.limit=Nopeusrajoitus
-ActivityView.legend.achieved=Saavutettu nopeus
-ActivityView.legend.overhead=Yleisrasite
-ActivityView.legend.peeraverage=Keskim\u00e4\u00e4r\u00e4inen nopeus
-ActivityView.legend.swarmaverage=K\u00e4ytt\u00e4jien keskinopeus
-ActivityView.legend.trimmed=Tasattu (sovitettu) nopeus
-MyTorrentsView.menu.movemenu=Siirr\u00e4 tiedostot
-MyTorrentsView.menu.movedata=Vaihda tallennushakemistoa...
-MyTorrentsView.menu.movetorrent=Siirr\u00e4 torrent-tiedosto...
-MyTorrentsView.menu.movedata.dialog=Valitse uusi sijainti
-DHTView.operations.data=Tieto
-DHTView.general.reachable=Saavutettavissa
-DHTView.general.rendezvous=Tavattavissa
-ConfigView.label.queue.maxactivetorrentswhenseeding=Ainoastaan l\u00e4hetett\u00e4ess\u00e4 (0 = rajoittamaton)
-Views.plugins.IRC.title=IRC - reaaliaikainen tekninen tuki
-Formats.units.alot=Paljon!
-ConfigView.section.ipfilter.persistblocking=Muista estettyjen k\u00e4ytt\u00e4jien tiedot uudelleenk\u00e4ynnistyksen j\u00e4lkeen
-FilesView.menu.rename=Nime\u00e4 uudelleen ja/tai siirr\u00e4
-FilesView.menu.rename_only=Nime\u00e4 uudelleen
-FilesView.menu.retarget=Siirr\u00e4
-FilesView.rename.choose.path=Valitse uusi tai olemassa oleva tiedosto
-FilesView.rename.choose.path.dir=Valitse uusi tai olemassa oleva hakemisto
-FilesView.rename.confirm.delete.title=Vahvista poisto
-FilesView.rename.confirm.delete.text=Haluatko varmasti poistaa seuraavan tiedoston?\n%1
-FilesView.rename.filename.title=Nime\u00e4 uudelleen
-FilesView.rename.filename.text=Anna uusi nimi tiedostolle:
-ConfigView.higher.mode.available=Korkeammissa k\u00e4ytt\u00e4j\u00e4tiloissa on valittavissa lis\u00e4\u00e4 asetuksia
-ConfigView.section.mode=K\u00e4ytt\u00e4j\u00e4tila
-ConfigView.section.mode.title=K\u00e4ytt\u00e4j\u00e4n taidot
-ConfigView.section.mode.beginner=Aloittelija
-ConfigView.section.mode.beginner.wiki.definitions=BitTorrent-sanasto
-ConfigView.section.mode.intermediate=Keskiverto
-ConfigView.section.mode.intermediate.wiki.host=Torrent-tiedostojen seuranta
-ConfigView.section.mode.intermediate.wiki.publish=Torrent-tiedostojen julkaiseminen
-ConfigView.section.mode.advanced=Edistynyt
-ConfigView.section.mode.advanced.wiki.main=Wikin etusivu
-ConfigView.section.mode.beginner.text=Kaikki mit\u00e4 tarvitset torrent-tiedostojen lataamiseen.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa, jos haluat vain hallita torrent-tiedostojasi.
-ConfigView.section.mode.intermediate.text=Vaikutusmahdollisuus oman seurantapalvelimen asetuksiin.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa, jos haluat asettaa seurantaan tai julkaista torrent-tiedostoja.
-ConfigView.section.mode.advanced.text=Vaikutusmahdollisuus tarkempiin yhteysasetuksiin.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa vain, jos todella tied\u00e4t mit\u00e4 olet tekem\u00e4ss\u00e4.
-Files.column.storagetype=Varaustapa
-Files.column.fileext=Tyyppi
-FileItem.storage.linear=Lineaarinen
-FileItem.storage.compact=Kompakti
-MessageBoxWindow.rememberdecision=Muista valinta jatkossa
-ConfigView.section.interface.cleardecisions=Tyhjenn\u00e4 tallennetut asetusvalinnat
-ConfigView.section.interface.cleardecisionsbutton=Tyhjenn\u00e4
-ConfigView.section.interface.cleartrackers=Tyhjenn\u00e4 tallennetut seurantapalvelintiedot
-ConfigView.section.interface.cleartrackersbutton=Tyhjenn\u00e4
-ConfigView.section.interface.clearsavepaths=Tyhjenn\u00e4 tallennetut tallennushakemistovalinnat
-ConfigView.section.interface.clearsavepathsbutton=Tyhjenn\u00e4
-configureWizard.welcome.usermodes=K\u00e4ytt\u00e4j\u00e4tilan m\u00e4\u00e4ritt\u00e4minen vaikuttaa k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytett\u00e4vien asetusmahdollisuuksien m\u00e4\u00e4r\u00e4\u00e4n. Oikean tason valinta varmistaa sen, ett\u00e4 k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytet\u00e4\u00e4n vain h\u00e4nen osaamistasolleen sopivat toiminnot, ja perusk\u00e4ytt\u00f6 onnistuu vaivattomasti. Voit halutessasi vaihtaa k\u00e4ytt\u00e4j\u00e4tilaa my\u00f6hemmin asetuksista.
-FilesView.skip.confirm.delete.text=Haluatko varmasti poistaa seuraavan tiedoston k\u00e4ytt\u00e4m\u00e4n tilanvarauksen?\n%1
-FilesView.rename.failed.title=Uudelleennime\u00e4minen/siirt\u00e4minen ep\u00e4onnistui
-FilesView.rename.failed.text=Toiminto ep\u00e4onnistui - todenn\u00e4k\u00f6isesti virheellinen kohdevalinta.
-diagnostics.log_found=Vuze ei sulkeutunut viimeksi kunnollisesti. Tarkasta <A HREF="%1">virheenm\u00e4\u00e4rityslokitiedostot</A> ja ilmoita mahdollisista ohjelmavirheist\u00e4 Azureuksen kehitt\u00e4jille. Tarkasta my\u00f6s wikist\u00e4 (katso Ohje-valikko) artikkeli "Vuze Disappears".
-ManagerItem.paused=Keskeytetty
-Utils.link.visit=Katso my\u00f6s
-ConfigView.section.connection.serverport.wiki=Hyv\u00e4 porttivalinta
-ConfigView.section.transfer.speeds.wiki=Hyv\u00e4t nopeusrajoitusasetukset
-installPluginsWizard.installMode.info.title=Tietoa lis\u00e4osista
-installPluginsWizard.installMode.info.text=Vuze toimii vallan mainosti ilman lis\u00e4osiakin, mutta niiden avulla voit esimerkiksi hy\u00f6dynt\u00e4\u00e4 automaattisia toimenpiteit\u00e4 ja et\u00e4hallita Vuzea.\n\nLue jokaisen lis\u00e4osan kuvaus tarkasti ennen kuin asennat sen.\nN\u00e4in pid\u00e4t huolen siit\u00e4, ettet turhaan pid\u00e4 asennettuina sellaisia lis\u00e4osia, joita et kuitenkaan k\u00e4ytt\u00e4isi.\n\nLis\u00e4osia voit poistaa ohjatulla poistotoiminnolla, jon [...]
-Views.plugins.Distributed.DB.title=Hajautettu tietokanta
-Views.plugins.Distributed.Tracker.title=Hajautettu seurantapalvelin
-Views.plugins.Plugin.Update.title=Lis\u00e4osien p\u00e4ivitys
-Views.plugins.UPnP.title=UPnP-m\u00e4\u00e4ritys
-Views.plugins.UPnP.title.tooltip=Universal Plug and Play -tuki
-openUrl.url.info=Tukee http- ja https-protokollia, magnet-linkkej\u00e4 sek\u00e4 heksadesimaalisia tiivistearvoja
-TableColumn.header.swarm_average_completion=Keskim. valmiina
-TableColumn.header.swarm_average_completion.info=Keskim\u00e4\u00e4r\u00e4inen valmistumisprosentti kaikkien lataajien keskuudessa.
-GeneralView.label.swarm_average_completion=Keskim\u00e4\u00e4rin valmistunut:
-GeneralView.label.swarm_average_completion.tooltip=Keskim\u00e4\u00e4r\u00e4inen valmistumisprosentti kaikkien k\u00e4ytt\u00e4jien keskuudessa.
-MainWindow.nat.status.unknown=NAT-tila
-MainWindow.nat.status.tooltip.unknown=Yhteyden toimivuus palomuurin/NATin suhteen tuntematon (TCP-portin osalta).
-MainWindow.nat.status.ok=NAT-tila OK
-MainWindow.nat.status.tooltip.ok=Yhteyden toimivuus kunnossa (TCP-portin osalta).
-MainWindow.nat.status.probok=NAT-tila OK?
-MainWindow.nat.status.tooltip.probok=Yhteyden toimivuuden pit\u00e4isi olla kunnossa, mutta Vuze ei ole saanut l\u00e4hiaikoina sis\u00e4\u00e4ntulevia TCP-yhteyksi\u00e4.
-MainWindow.nat.status.bad=Yhteysongelma
-MainWindow.nat.status.tooltip.bad=Palomuuri est\u00e4\u00e4 liikenteen/NAT-ongelma havaittu (TCP-portin osalta)\n - ohjeita ongelman ratkaisemiseksi wikiss\u00e4 (katso Ohje | Wiki (UKK))
-plugin.installer.recommended.plugin=Suositeltu lis\u00e4osa - tarkasta tiedot ja asenna, jos tarvitset.
-LoggerView.pause=Keskeyt\u00e4 lokin luominen
-LoggerView.clear=&Tyhjenn\u00e4
-LoggerView.filter=Suodata n\u00e4ytett\u00e4vi\u00e4 tietoja
-LoggerView.filter.uncheckAll=Poista kaikki
-LoggerView.filter.checkAll=Valitse kaikki
-LoggerView.loggingDisabled=Lokin tekeminen on asetettu pois p\u00e4\u00e4lt\u00e4.
-LoggerView.includeOnly=N\u00e4yt\u00e4 vain t\u00e4t\u00e4 s\u00e4\u00e4nn\u00f6llist\u00e4 lauseketta vastaavat rivit:
-LoggerView.excludeAll=\u00c4l\u00e4 n\u00e4yt\u00e4 t\u00e4t\u00e4 s\u00e4\u00e4nn\u00f6llist\u00e4 lauseketta vastaavia rivej\u00e4:
-ConfigView.section.logging.log0type=Tiedot
-ConfigView.section.logging.log1type=Varoitukset
-ConfigView.section.logging.log2type=Virheet
-ConfigView.section.logging.filter=Kirjattavien tietojen suodatus
-ConfigView.section.logging.level=P\u00e4\u00e4taso
-ConfigView.section.logging.showLogsFor=N\u00e4yt\u00e4 %1-tason lokimerkinn\u00e4t luokista:
-ConfigView.pluginlist.column.loadAtStartup=Lataa k\u00e4ynnistett\u00e4ess\u00e4
-ConfigView.pluginlist.column.type=Tyyppi
-ConfigView.pluginlist.column.type.perUser=K\u00e4ytt\u00e4j\u00e4kohtainen
-ConfigView.pluginlist.column.type.shared=Jaettu
-ConfigView.pluginlist.column.type.builtIn=Sis\u00e4\u00e4nrakennettu
-ConfigView.pluginlist.column.name=Nimi
-ConfigView.pluginlist.column.version=Versio
-ConfigView.pluginlist.column.directory=Hakemisto
-ConfigView.pluginlist.column.isOperational=K\u00e4ytett\u00e4viss\u00e4
-PeersView.BlockView.Avail.Have=On molemmilla
-PeersView.BlockView.Avail.NoHave=On toisella; ei itsell\u00e4
-PeersView.BlockView.NoAvail.Have=On itsell\u00e4; ei toisella
-PeersView.BlockView.NoAvail.NoHave=Ei ole kummallakaan
-PeersView.BlockView.Transfer=Siirret\u00e4\u00e4n
-PeersView.BlockView.NextRequest=Pyydet\u00e4\u00e4n seuraavaksi
-PeersView.BlockView.title=Kuvaus osista
-PeersView.BlockView.AvailCount=Saatavuusluku
-MyTorrentsView.dialog.NumberError.title=Virheellinen arvo
-MyTorrentsView.dialog.NumberError.text=Sy\u00f6tt\u00e4m\u00e4si arvo ei ole kelvollinen.
-MyTorrentsView.menu.manual=&Manuaalinen...
-MyTorrentsView.menu.manual.per_torrent=Manuaalinen (torrent-tiedostokohtainen)...
-MyTorrentsView.menu.manual.shared_torrents=Manuaalinen (jaettuna valittujen kesken)...
-MyTorrentsView.dialog.setSpeed.title=Aseta %1
-# %1 = "in kbps" or ""; %2 = "upload" or "download"
-MyTorrentsView.dialog.setNumber.text=Rajoita %2 arvoon (%1):
-MyTorrentsView.dialog.setNumber.upload=l\u00e4hetysnopeus
-MyTorrentsView.dialog.setNumber.download=latausnopeus
-MyTorrentsView.dialog.setNumber.inKbps=%1
-OpenTorrentWindow.torrentLocation=Ladattavat torrent-tiedostot:
-OpenTorrentWindow.addFiles.URL=Lis\u00e4\u00e4 &URL
-OpenTorrentWindow.addFiles.Folder=Lis\u00e4\u00e4 &hakemisto
-OpenTorrentWindow.addFiles.Clipboard=Lis\u00e4\u00e4 &leikep\u00f6yd\u00e4lt\u00e4
-OpenTorrentWindow.changeDestination=Vaihda tallennushakemistoa
-OpenTorrentWindow.fileList=Ladattavat tiedostot:
-OpenTorrentWindow.torrentTable.name=Nimi
-OpenTorrentWindow.torrentTable.saveLocation=Tallennushakemisto
-OpenTorrentWindow.fileTable.fileName=Tiedostonimi
-OpenTorrentWindow.fileTable.size=Koko
-OpenTorrentWindow.fileTable.destinationName=Kohdesijainti ja -nimi
-OpenTorrentWindow.startMode.seeding=Aseta l\u00e4hetett\u00e4v\u00e4ksi
-OpenTorrentWindow.fileList.changeDestination=Vaihda tallennushakemistoa (kohdetta)
-OpenTorrentWindow.mb.badSize.title=Yhteensopimaton tiedosto
-OpenTorrentWindow.mb.badSize.text='%1' ei ole sama kuin '%2', joten sit\u00e4 ei voida asettaa l\u00e4hetett\u00e4v\u00e4ksi.
-OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> on jo lis\u00e4tty nimell\u00e4 '%2'.
-OpenTorrentWindow.mb.alreadyExists.default.name=Kohde
-OpenTorrentWindow.mb.alreadyExists.title=Kohde jo lis\u00e4tty
-OpenTorrentWindow.mb.openError.title=Virhe tiedoston avauksessa
-OpenTorrentWindow.mb.openError.text=Kohdetta '%1' ei voitu avata:\n%2
-OpenTorrentWindow.torrent.remove=Poista torrent-tiedosto listalta
-OpenTorrentWindow.torrent.options=Seuraavat asetukset koskevat yll\u00e4 valittuina olevia torrent-tiedostoja:
-OpenTorrentWindow.xOfTotal=(%1/%2)
-iconBar.open.tooltip=Avaa torrent-tiedosto
-LocaleUtil.column.text=Tuntematon tekstiosa
-Tracker.tooltip.MultiSupport=Seurantapalvelin tukee useita pikap\u00e4ivityksi\u00e4 yhdell\u00e4 yhteydenottokerralla.
-Tracker.tooltip.NoMultiSupport=Seurantapalvelin ei tue useita pikap\u00e4ivityksi\u00e4 yhdell\u00e4 yhteydenottokerralla.\nT\u00e4m\u00e4 ei vaikuta Vuzen suorituskykyyn, mutta asettaa seurantapalvelimelle lis\u00e4\u00e4 kuormaa.
-ConfigView.label.lazybitfield=L\u00e4het\u00e4 tiedot saatavilla olevista osista hajautetusti (auttaa tilanteessa, jossa ISP est\u00e4\u00e4 tietojen l\u00e4hett\u00e4misen kerralla)
-LoggerView.realtime=P\u00e4ivit\u00e4 reaaliajassa
-ConfigView.section.file.perf.cache.flushpieces=Kirjoita valmistuneet osat v\u00e4litt\u00f6m\u00e4sti kiintolevylle. Tasaa levyhakuja, mutta voi johtaa useampiin kirjoitusoperaatioihin
-ConfigView.section.file.writemblimit=Jonoon asetettavan kirjoitettavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4 (%1)
-ConfigView.section.file.writemblimit.explain=Kun kirjoitusnopeus kiintolevylle on pienempi kuin latausnopeus, t\u00e4m\u00e4 asetus rajoittaa jonoon asetettavan, kirjoitusta odottavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4\u00e4. Jos enimm\u00e4ism\u00e4\u00e4r\u00e4 tulee t\u00e4yteen, alennetaan latausnopeutta automaattisesti.
-ConfigView.section.file.readmblimit=Jonoon asetettavan luettavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4 (%1)
-ConfigView.section.file.readmblimit.explain=T\u00e4m\u00e4 asetus rajoittaa keskusmuistiin asetettavan, k\u00e4sittely\u00e4 odottavan luettavan tiedon m\u00e4\u00e4r\u00e4\u00e4.
-Button.moveUp=Siirr\u00e4 &yl\u00f6s
-Button.moveDown=Siirr\u00e4 &alas
-ConfigView.notAvailableForMode=N\u00e4m\u00e4 asetukset ovat suunnattu edistyneemmille k\u00e4ytt\u00e4jille (%1-tila tai korkeampi).\nNe eiv\u00e4t siis ole k\u00e4ytett\u00e4viss\u00e4 %2-k\u00e4ytt\u00e4j\u00e4tilassa.
-health.explain.error=Torrent-tiedoston kanssa on ongelma - katso lis\u00e4tietoja Tila-sarakkeesta tai Yhteys-sarakkeen ilmaisimen ty\u00f6kaluvihjeest\u00e4.
-GeneralView.label.trackerscrapeupdate=Tee pikap\u00e4ivitys
-PeersView.piece=Viimeisin osa
-PeersView.piece.info=Viimeisimm\u00e4n k\u00e4ytt\u00e4j\u00e4lt\u00e4 pyydetyn osan numero
-PiecesView.priority=Prioriteetti
-PiecesView.priority.info=Osan valmistumisprioriteetti.
-PiecesView.speed=Nopeus
-PiecesView.speed.info=Hitaiden k\u00e4ytt\u00e4jien ei anneta h\u00e4irit\u00e4 nopeasti tulevien osien lataamista.
-TableColumn.header.AvgAvail.info=Osien saatavuuslukujen summa / osien m\u00e4\u00e4r\u00e4ll\u00e4 / yhteyksien m\u00e4\u00e4r\u00e4ll\u00e4.
-TableColumn.header.AvgAvail=Keskim. saatavuus/osa
-ConfigView.label.strictfilelocking=Lukitse tiedostot kirjoittamisen varalta torrent-tiedostojen kesken
-MyTorrentsView.menu.checkfilesexist=Tarkasta tiedostojen olemassaolo
-MyTorrentsView.menu.rescanfile=Tarkasta keskener\u00e4iset osat uudelleen s\u00e4\u00e4nn\u00f6llisesti
-MyTorrentsView.menu.clear_resume_data=Tyhjenn\u00e4 nopean latauksen jatkamisen tiedot
-Plugin.extseed.name=Ulkoiset l\u00e4hteet
-Plugin.localtracker.name=L\u00e4hiverkkok\u00e4ytt\u00f6
-Plugin.localtracker.info=Vuze-asiakasohjelmien yhteisk\u00e4ytt\u00f6\u00e4 voidaan tehostaa l\u00e4hiverkossa ja palomuurisuojatussa ymp\u00e4rist\u00f6ss\u00e4. T\u00e4m\u00e4 lis\u00e4osa muodostaa suorat tiedonsiirtoyhteydet asiakasohjelmien v\u00e4lille ja parantaa n\u00e4in siirtonopeuksia.
-Plugin.localtracker.enable=Tarkkaile l\u00e4hiverkkoa Vuze-k\u00e4ytt\u00e4jien varalta
-azinstancehandler.alert.portclash=Porttivastaavuus havaittu LAN:ssa: %1 toisen Vuze-k\u00e4ytt\u00e4j\u00e4n k\u00e4yt\u00f6ss\u00e4, valitse toinen portti sis\u00e4\u00e4ntulevalle TCP- ja UDP-liikenteelle (v\u00e4lilt\u00e4 %2 ja %3).
-ConfigView.section.transfer.lan=L\u00e4hiverkko
-ConfigView.section.transfer.lan.tooltip=L\u00e4hiverkkokohtaiset asetukset
-ConfigView.section.transfer.lan.uploadrate=kB/s, enimm\u00e4isl\u00e4hetysnopeus l\u00e4hiverkossa (0 = rajoittamaton)
-ConfigView.section.transfer.lan.uploadrate.tooltip=Erillinen enimm\u00e4isl\u00e4hetysnopeusrajoitus, jota k\u00e4ytet\u00e4\u00e4n l\u00e4hiverkon sis\u00e4isess\u00e4 liikenteess\u00e4.
-ConfigView.section.transfer.lan.downloadrate=kB/s, enimm\u00e4islatausnopeus l\u00e4hiverkossa (0 = rajoittamaton)
-ConfigView.section.transfer.lan.downloadrate.tooltip=Erillinen enimm\u00e4islatausnopeusrajoitus, jota k\u00e4ytet\u00e4\u00e4n l\u00e4hiverkon sis\u00e4isess\u00e4 liikenteess\u00e4.
-TorrentOptionsView.title.short=Asetukset
-TorrentOptionsView.title.full=Asetukset
-TorrentOptionsView.param.max.peers=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
-ConfigView.section.connection.encryption.require_encrypted_transport=Vaadi salattu liikenne
-ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=Pakottaa k\u00e4ytt\u00e4m\u00e4\u00e4n salattua liikennett\u00e4 yhteyksiss\u00e4 k\u00e4ytt\u00e4jiin.
-ConfigView.section.connection.encryption.min_encryption_level=Salauksen v\u00e4himm\u00e4istaso
-ConfigView.section.connection.encryption.min_encryption_level.tooltip=Plain - pelkk\u00e4 k\u00e4ttelyvaihe\nRC4 - t\u00e4ysi salaus\nKorkeampi salaustaso vaatii enemm\u00e4n suoritinaikaa.
-Peers.column.Encryption=Salaus
-Peers.column.Encryption.info=K\u00e4ytett\u00e4v\u00e4n salauksen taso.
-ConfigView.section.connection.encryption.encrypt.info=Jos salaus on k\u00e4yt\u00f6ss\u00e4, et voi yhdist\u00e4\u00e4 k\u00e4ytt\u00e4jiin, joiden asiakasohjelmat\neiv\u00e4t tue salausta (ellet m\u00e4\u00e4rittele salauksenohitusasetuksia k\u00e4ytt\u00f6\u00f6n alempana).
-ConfigView.section.connection.encryption.encrypt.info.link=Katso lis\u00e4tietoja t\u00e4st\u00e4
-MainWindow.sr.status.tooltip.ok=Jakosuhde riitt\u00e4v\u00e4 (%1)
-MainWindow.sr.status.tooltip.poor=Jakosuhde alhainen: %1 < 0.9
-MainWindow.sr.status.tooltip.bad=Jakosuhde eritt\u00e4in alhainen: %1 < 0.5
-ConfigView.section.style.status=Tilarivi:
-ConfigView.section.style.status.show_sr=Jakosuhde
-ConfigView.section.style.status.show_nat=NAT-tila
-ConfigView.section.style.status.show_ddb=Hajautetun tietokannan tila
-ConfigView.section.style.status.show_ipf=IP-suotimien toiminta
-ConfigView.section.connection.encryption.encrypt.group=Liikenteen salaaminen/peitt\u00e4minen
-ConfigView.section.connection.encryption.encrypt.fallback_info=Kumpi tahansa alla olevista asetuksista sallii yhteydet ep\u00e4yhteensopiviin asiakasohjelmiin, mutta poistaa liikenteen salauksen.
-ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Salli salaamattomat ulosp\u00e4in luotavat yhteydet, jos salattu liikenne ei ole k\u00e4ytett\u00e4viss\u00e4
-ConfigView.section.connection.encryption.encrypt.fallback_incoming=Salli salaamattomat sis\u00e4\u00e4ntulevat yhteydet
-ConfigView.section.connection.encryption=Salaus
-upnp.selectedinterfaces=Valitut liit\u00e4nn\u00e4t (erota ;-merkill\u00e4, esim. eth0;eth1, tyhj\u00e4 ruutu = kaikki)
-ConfigView.section.style.defaultSortOrder=Tietojen oletuslajittelu
-ConfigView.section.style.defaultSortOrder.desc=Laskeva
-ConfigView.section.style.defaultSortOrder.asc=Nouseva
-ConfigView.section.style.defaultSortOrder.flip=Viimeisimm\u00e4n vastakohta
-LoggerView.autoscroll=Automaattinen vieritys
-Button.selectAll=Valitse kaikki
-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=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)
-ConfigView.section.connection.advanced.bind_port.tooltip=Ulosp\u00e4in luotavat yhteydet sidotaan paikallisesti m\u00e4\u00e4riteltyyn porttiin.\nSaattaa auttaa tilanteissa, joissa NAT-liikennett\u00e4 ohjaavan laitteen kanssa esiintyy ep\u00e4vakautta.
-ConfigView.section.proxy.group.tracker=Yhteydet seurantapalvelimiin
-ConfigView.section.proxy.group.peer=Yhteydet k\u00e4ytt\u00e4jiin
-Pieces.column.Requested=Pyydetty
-Pieces.column.Requested.info=Voidaanko osaa pyyt\u00e4\u00e4 ladattavaksi edelleen.
-ConfigView.label.maxuploadsseeding=Vaihtoehtoinen oletusm\u00e4\u00e4r\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4
-MyTorrentsView.filter=Suodin
-popup.error.hideall=Piilota kaikki
-ConfigView.section.style.dataStatsOnly=N\u00e4yt\u00e4 tilastot vain varsinaisesta siirrett\u00e4v\u00e4st\u00e4 tiedosta (ei yhteysk\u00e4yt\u00e4nn\u00f6n tietoja)
-ConfigView.section.style.separateProtDataStats=N\u00e4yt\u00e4 tilastot eriteltyn\u00e4 siirrett\u00e4v\u00e4st\u00e4 tiedosta ja yhteysk\u00e4yt\u00e4nn\u00f6st\u00e4 (muodossa "tieto (yhteysk\u00e4yt\u00e4nt\u00f6)")
-MyTorrentsView.dialog.setFilter.title=Muokkaa suodinta
-MyTorrentsView.dialog.setFilter.text=%1 suodatetaan sy\u00f6tetyn tekstin perusteella. K\u00e4yt\u00e4 |-merkki\u00e4 (putkimerkki) suodattaaksesi useilla termeill\u00e4.
-MyTorrentsView.filter.tooltip=Ctrl+X vaihtaa RegEx-haun ja normaalin haun v\u00e4lill\u00e4.\nK\u00e4yt\u00e4 |-merkki\u00e4 (putkimerkki) suodattaaksesi useilla termeill\u00e4.
-MyTorrentsView.clearFilter.tooltip=Tyhjenn\u00e4 suodin
-MyTorrentsView.menu.filter=Suodata torrent-tiedostoja...
-ConfigView.section.file.resume.recheck.all=Tarkasta kaatumisen j\u00e4lkeen tiedostot kokonaisuudessaan (muutoin vain viimeisen tallennuksen aktiiviset osat tarkastetaan)
-ConfigureWizard.language.choose=Valitse kieli:
-popup.closing.in=Suljetaan autom. %1 sekunnissa
-popup.more.waiting=%1 viesti(\u00e4) j\u00e4ljell\u00e4...
-# > 2402
-popup.download.finished=Lataus valmistunut: "%1".
-popup.file.finished=Lataus valmistunut: "%1".
-ConfigView.auto=Automaattinen
-Plugin.localtracker.autoadd.info=Lis\u00e4\u00e4 automaattisesti seuraavat l\u00e4hiverkon k\u00e4ytt\u00e4j\u00e4t (esim. 1.2.3.4, erota osoitteet ;-merkill\u00e4)
-Plugin.localtracker.autoadd=K\u00e4ytt\u00e4j\u00e4t
-Plugin.localtracker.networks.info=K\u00e4sittele seuraavia verkkoalueita l\u00e4hiverkkoina (esim. 145.227.*.*, erota verkot ;-merkill\u00e4)
-Plugin.localtracker.networks=L\u00e4hiverkot
-MainWindow.menu.view.plugins.logViews=Lokiseurannat
-SpeedView.stats.autospeed=Automaattinen l\u00e4hetysnopeuden asettaminen
-SpeedView.stats.autospeed.disabled=T\u00e4m\u00e4 ominaisuus joko ei ole k\u00e4ytett\u00e4viss\u00e4 (hajautetun tietokannan tulee olla toiminnassa) tai l\u00e4hetysnopeus on asetettu manuaalisesti.
-SpeedView.stats.idlePing=Joutovasteaika:
-SpeedView.stats.maxPing=Enimm\u00e4isvasteaika:
-SpeedView.stats.currentPing=T\u00e4m\u00e4nhetkinen vasteaika:
-SpeedView.stats.maxUp=Enimm\u00e4isl\u00e4hetysnopeus:
-ConfigView.pluginlist.unloadSelected=Poista valitut k\u00e4yt\u00f6st\u00e4
-ConfigView.pluginlist.scan=Hae uudet
-ConfigView.section.transfer.autospeed=Auto-Speed (perinteinen)
-ConfigView.section.transfer.autospeed.tooltip=Automaattisen l\u00e4hetysnopeuden asetukset
-ConfigView.section.transfer.autospeed.info=Automaattisella enimm\u00e4isl\u00e4hetysnopeusrajoituksen asettamisella v\u00e4ltet\u00e4\u00e4n verkon liian suuri kuormittuminen.\n\nAlla olevat raja-arvot ovat k\u00e4yt\u00f6ss\u00e4, kun automaattinen l\u00e4hetysnopeuden asettaminen ja hajautettu tietokanta ovat k\u00e4yt\u00f6ss\u00e4.
-ConfigView.section.transfer.autospeed.minupload=%1, v\u00e4himm\u00e4isl\u00e4hetysnopeus
-ConfigView.section.transfer.autospeed.minupload.tooltip=L\u00e4hetysnopeutta ei normaalisti lasketa automaattisesti t\u00e4m\u00e4n rajan alle.
-ConfigView.section.transfer.autospeed.maxupload=%1, enimm\u00e4isl\u00e4hetysnopeus (0 = rajoittamaton)
-ConfigView.section.transfer.autospeed.maxupload.tooltip=L\u00e4hetysnopeutta ei automaattisesti nosteta t\u00e4m\u00e4n rajan yli.
-ConfigView.section.transfer.autospeed.chokeping=Vasteaika, jonka ylitytty\u00e4 enimm\u00e4isl\u00e4hetysnopeusrajoitusta alennetaan (millisekunteja)
-ConfigView.section.transfer.autospeed.chokeping.tooltip=Vasteajan ylittyminen on merkki liian suuresta verkon kuormituksesta.
-ConfigView.section.transfer.autospeed.enableauto=K\u00e4yt\u00e4 automaattista asetusta sek\u00e4 ladattaessa ett\u00e4 l\u00e4hetett\u00e4ess\u00e4
-ConfigView.section.transfer.autospeed.enableautoseeding=K\u00e4yt\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4 (kun ei ladata mit\u00e4\u00e4n)
-ConfigView.pluginlist.column.unloadable=Poistettavissa k\u00e4yt\u00f6st\u00e4
-ConfigView.section.transfer.lan.enable=K\u00e4yt\u00e4 erillisi\u00e4 nopeusrajoituksia l\u00e4hiverkossa
-Plugin.localtracker.wellknownlocals=Ota automaattisesti huomioon paikalliset verkot (esim. 192.168...)
-TableColumn.header.filesdone=Tiedostot
-TableColumn.header.filesdone.info=Valm. tiedostot/kaikki TAI valm. ladattavat tiedostot (valm. tiedostot)/kaikki lad. tiedostot (kaikki)
-MagnetPlugin.private_torrent=<yksityinen torrent-tiedosto>
-MagnetPlugin.decentral_disabled=<hajautettu seuranta ei k\u00e4ytett\u00e4viss\u00e4>
-MagnetPlugin.decentral_backup_disabled=<yksityinen torrent-tiedosto - hajautettu seuranta ei k\u00e4ytett\u00e4viss\u00e4>
-MagnetPlugin.report.waiting_ddb=alustetaan hajautettua tietokantaa...
-MagnetPlugin.report.searching=etsit\u00e4\u00e4n...
-MagnetPlugin.report.found=l\u00f6ydettiin %1
-MagnetPlugin.report.alive=%1 on tavoitettavissa
-MagnetPlugin.report.dead=%1 ei ole tavoitettavissa
-MagnetPlugin.report.tunnel=tunneloidaan kohteeseen %1
-MagnetPlugin.report.downloading=ladataan kohteesta %1
-MagnetPlugin.report.error=virhe %1
-MagnetURLHandler.report.no_sources=torrent-tiedostolle ei l\u00f6ytynyt l\u00e4hteit\u00e4
-MagnetURLHandler.report.torrent_size=torrent-tiedoston koko: %1
-MagnetURLHandler.report.percent=valmiiina: %1%
-MagnetURLHandler.report.error=virhe %1
-DHTTransport.report.request_all=pyydet\u00e4\u00e4n tietoa siirrett\u00e4v\u00e4ksi kohteelta %1
-DHTTransport.report.received_bit=vastaanotettiin %1 - %2 kohteelta %3
-DHTTransport.report.complete=valmis
-DHTTransport.report.timeout=aikakatkaisu, ei vastausta kohteelta %1
-DHTTransport.report.rerequest_all=pyydet\u00e4\u00e4n uudestaan tietoa siirrett\u00e4v\u00e4ksi kohteelta %1
-DHTTransport.report.rerequest_bit=pyydet\u00e4\u00e4n tietoja %1 - %2 uudestaan kohteelta %3
-DHTTransport.report.timeout_some=aikakatkaisu, %1 pakettia vastaanotettu kohteelta %2, mutta siirto ei valmis
-DHTTransport.report.sending=l\u00e4hetet\u00e4\u00e4n tietoa
-DHTTransport.report.resending=l\u00e4hetet\u00e4\u00e4n tietoja uudelleen
-DHTTransport.report.send_complete=l\u00e4hetys valmistunut
-DHTTransport.report.send_timeout=l\u00e4hetyksen aikakatkaisu
-ConfigView.section.transfer.autospeed.enabledebug=Kirjaa virheenm\u00e4\u00e4ritystiedot lokiin
-TableColumn.header.date_added=Lis\u00e4tty
-TableColumn.header.date_added.info=Ajankohta, jolloin torrent-tiedosto on avattu Vuzeen
-ConfigView.section.file.hashchecking.smallestfirst=Aloita osien tarkastaminen uudelleen pienimmist\u00e4 latauksista
-platform.win32.baddll.info=Vuze on havainnut kohteen %1 (%2) olemassaolon. T\u00e4m\u00e4n tiedet\u00e4\u00e4n aiheuttavan ongelmia Vuzen kanssa, esimerkiksi ohjelman kaatuilua ja korkeaa suoritink\u00e4ytt\u00f6\u00e4. Jos havaitset ongelmia, poista ohjelmisto tai aseta se niin, ettei se vaikuta Vuzeen.
-upnp.ignorebaddevices=Ohita laitteet, jotka eiv\u00e4t vastaa oikein
-upnp.ignorebaddevices.info=T\u00e4ll\u00e4 hetkell\u00e4 ohitetut laitteet: %1
-upnp.ignorebaddevices.reset=Tyhjenn\u00e4 ohitettavien laitteiden lista
-upnp.ignorebaddevices.reset.action=Tyhjenn\u00e4
-upnp.ignorebaddevices.alert=UPnP-laite kohteessa %1 on ohitettu toistuvien yhteysongelmien takia. Katso asetusvaihtoehdot UPnP-m\u00e4\u00e4rityksen asetuksista.
-TorrentOptionsView.param.max.uploads.when.busy=KB/s - enimm\u00e4isl\u00e4hetysnopeus, kun yleinen raja saavutettu (0 = ei k\u00e4yt\u00f6ss\u00e4)
-UpdateMonitor.messagebox.verification.failed.title=Asennuksen vahvistus ep\u00e4onnistui
-UpdateMonitor.messagebox.verification.failed.text=Kohteen '%1' vahvistus ep\u00e4onnistui: %2
-UpdateMonitor.messagebox.accept.unverified.title=Vahvistamaton asennus
-UpdateMonitor.messagebox.accept.unverified.text=Kohdetta '%1' ei voitu vahvistaa Vuzen viralliseksi lis\u00e4osaksi.\nT\u00e4llaisessa tilanteessa asennusta ei kannata jatkaa.\nJatketaanko asennusta?
-FileView.BlockView.title=Tiedoston osat
-FileView.BlockView.Done=Valmis
-FileView.BlockView.Skipped=Ohitettu
-FileView.BlockView.Active=Aktiivinen
-FileView.BlockView.Outstanding=Keskener\u00e4inen
-ConfigView.label.tcplistenport=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
-ConfigView.label.udplistenport=UDP-liikenteen portti
-upnp.portchange.alert=Seuraavat portit on vaihdettu UPnP-laitteen ongelmien v\u00e4ltt\u00e4miseksi: %1 (vanha portti = %2) %3 (vanha portti = %4)
-ConfigView.section.proxy.username.info=Jos v\u00e4lityspalvelin vaatii k\u00e4ytt\u00e4j\u00e4n todentamisen, vaikka todentamistietoja ei ole m\u00e4\u00e4ritelty, k\u00e4yt\u00e4 k\u00e4ytt\u00e4j\u00e4tunnusta "<none>"
-ConfigView.label.maxuploadswhenbusymin=Torrent-kohtainen l\u00e4hetysrajoitus k\u00e4ytt\u00f6\u00f6n, kun yleinen raja ollut saavutettuna (sekunteja)
-MainWindow.menu.help.debug=Luo virheenm\u00e4\u00e4ritystiedot
-DownloadManager.error.badsize=Virheellinen koko
-ConfigView.section.NATPMP=NAT-PMP-m\u00e4\u00e4ritys
-natpmp.info=NAT-PMP on Applen kehitt\u00e4m\u00e4 vaihtoehto UPnP:lle ja sit\u00e4 tukevat uusimmat AirPort-tukiasemat.\n\nHuomaa, ett\u00e4 t\u00e4ll\u00e4 hetkell\u00e4 UPnP-m\u00e4\u00e4rityksen t\u00e4ytyy olla k\u00e4yt\u00f6ss\u00e4, jotta voisit k\u00e4ytt\u00e4\u00e4 NAT-PMP:t\u00e4, sill\u00e4 NAT-PMP-laitetta k\u00e4sitell\u00e4\u00e4n erityistyyppisen\u00e4 UPnP-laitteena.
-natpmp.enable=K\u00e4yt\u00e4 NAT-PMP:t\u00e4 (huomaa, ett\u00e4 ominaisuus t\u00e4ytyy ottaa k\u00e4ytt\u00f6\u00f6n my\u00f6s AirPort-tukiaseman asetuksista)
-ConfigView.section.tracker.host.addurls=Lis\u00e4\u00e4 oman seurantapalvelimen p\u00e4ivitysosoite seurattaviin torrent-tiedostoihin
-ConfigView.filter=hae asetuksia
-ConfigView.section.files.move=Valmistuneiden siirt\u00e4minen
-ConfigView.section.file.defaultdir.section=Oletustallennushakemisto
-ConfigView.section.file.defaultdir.auto=Tallenna automaattisesti oletushakemistoon (ei kysyt\u00e4 erikseen)
-ConfigView.section.file.defaultdir.bestguess=K\u00e4yt\u00e4 parasta arvausta valittaessa oletustallennushakemistoa
-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=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
-ConfigView.section.connection.encryption.use_crypto_port=K\u00e4yt\u00e4 cryptoport-seurantapalvelinlaajennusta est\u00e4m\u00e4\u00e4n Plain-salatut yhteyden sis\u00e4\u00e4np\u00e4in
-TorrentOptionsView.param.reset.to.default=Palauta asetukset oletusarvoihin
-TorrentOptionsView.param.reset.button=Palauta
-natpmp.routeraddress=Tukiaseman osoite (tyhj\u00e4 ruutu = automaattinen haku)
-ConfigView.section.style.disableAlertSliding=Poista k\u00e4yt\u00f6st\u00e4 ponnahdusikkunoiden liukuva esiintulo ja aina p\u00e4\u00e4llimm\u00e4isen\u00e4 -tyyli
-ConfigView.section.transfer.autospeed.maxinc=%1, enimm\u00e4iskasvu yhden kierron aikana
-ConfigView.section.transfer.autospeed.maxdec=%1, enimm\u00e4isv\u00e4hennys yhden kierron aikana
-ConfigView.section.transfer.autospeed.enabledownadj=Salli latausnopeuden s\u00e4\u00e4tely
-ConfigView.section.transfer.autospeed.downadjratio=Lataus- ja l\u00e4hetysnopeuksien suhde (esim. 2.0 -> latausrajoitus on kaksi kertaa l\u00e4hetysrajoitus)
-ConfigView.section.transfer.autospeed.latencyfactor=Vasteajan ja nopeuden muutokset yhdist\u00e4v\u00e4 tekij\u00e4 (suuri luku v\u00e4hent\u00e4\u00e4 herkkyytt\u00e4)
-ConfigView.section.transfer.autospeed.reset=Palauta lis\u00e4asetukset oletusarvoihin
-ConfigView.section.transfer.autospeed.reset.button=Palauta
-PeerColumn.activationCount=K\u00e4ytt\u00e4j\u00e4t, jotka yritt\u00e4v\u00e4t yhdist\u00e4\u00e4: %1
-TableColumn.header.timesincedownload.info=Aikaa kulunut siit\u00e4, kun torrent-tiedostoa viimeksi ladattiin.
-TableColumn.header.timesincedownload=Lat. joutilasaika
-TableColumn.header.timesinceupload.info=Aikaa kulunut siit\u00e4, kun torrent-tiedostoa viimeksi l\u00e4hetettiin.
-TableColumn.header.timesinceupload=L\u00e4h. joutilasaika
-PeersView.incomingreqcount=Pyynn\u00f6t sis\u00e4\u00e4n
-PeersView.incomingreqcount.info=K\u00e4ytt\u00e4j\u00e4n tekemien sis\u00e4\u00e4np\u00e4in tulevien pyynt\u00f6jen m\u00e4\u00e4r\u00e4.
-PeersView.outgoingreqcount=Pyynn\u00f6t ulos
-PeersView.outgoingreqcount.info=K\u00e4ytt\u00e4j\u00e4lle tehtyjen ulosp\u00e4in menevien pyynt\u00f6jen m\u00e4\u00e4r\u00e4.
-upnp.mapping.trackerclientudp=Seurantapalvelinyhteyksien UDP-portti
-upnp.mapping.dhtudp=Hajautettu tietokanta
-ConfigView.section.connection.nondata.udp.same=K\u00e4yt\u00e4 samaa UDP-porttia hajautetulle tietokannalle ja UDP-seurantapalvelimelle
-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=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:
-UIDebugGenerator.messageask.title=Virheenm\u00e4\u00e4ritystietojen luominen
-UIDebugGenerator.messageask.text=Kirjoita kuvaus havaitusta ohjelmavirheest\u00e4.
-UIDebugGenerator.complete.title=Virheenm\u00e4\u00e4ritystiedot luotu onnistuneesti
-UIDebugGenerator.complete.text=L\u00e4het\u00e4 tiedosto '%1'.\n\nValitse OK tarkastellaksesi tiedostoa.
-ConfigView.section.style.showProgramIcon=N\u00e4yt\u00e4 avaavan ohjelman ikoni Nimi-sarakkeessa
-ConfigView.section.style.showProgramIcon.tooltip=Siirrot-ikkuna t\u00e4ytyy ehk\u00e4 sulkea ja avata uudelleen,\njotta muutos astuu voimaan.
-swt.alert.cant.update=SWT-ohjelmakirjastoa (ladattu kohteesta "%3") ei voida automaattisesti p\u00e4ivitt\u00e4\u00e4 versiosta %1 versioon %2 (t\u00e4ytyy ladata kohteesta "%4"). Katso lis\u00e4tietoja <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">wikist\u00e4</A>.
-authenticator.savepassword=Muista salasana
-ConfigView.section.security.clearpasswords=Tyhjenn\u00e4 muistetut salasanat
-ConfigView.section.security.clearpasswords.button=Tyhjenn\u00e4
-Content.alert.notuploaded.title=Siirto ei valmis
-Content.alert.notuploaded.text=Julkaisemasi kohteen '%1' siirto ei ole kokonaan valmis. Jos aiot %2 nyt, lataajilla ei ole mahdollisuutta saada latausta valmiiksi.\n\nHaluatko varmasti %2?
-Content.alert.notuploaded.multi.title=Siirrot ei valmiita
-Content.alert.notuploaded.multi.text=%1 julkaisemasi kohteen siirto ei ole kokonaan valmis. Jos aiot %2 nyt, lataajilla ei ole mahdollisuutta saada latauksia valmiiksi. Haluatko varmasti %2?\n\nKohteet, joita ei ole l\u00e4hetetty tarpeeksi:\n%3
-Content.alert.notuploaded.stop=pys\u00e4ytt\u00e4\u00e4
-Content.alert.notuploaded.quit=sulkea Vuzen
-TorrentInfoView.torrent.encoding=Torrent-tiedoston koodaus
-TorrentInfoView.columns=Siirrot-ikkunan sarakkeet
-progress.window.title=Toiminto meneill\u00e4\u00e4n
-progress.window.msg.filemove=Odota, ett\u00e4 tiedoston siirto/uudelleennime\u00e4minen valmistuu.
-ConfigView.label.popup.timestamp=N\u00e4yt\u00e4 aikaleimat ponnahdusikkunoissa
-ConfigView.label.popup.autohide=Ponnahdusikkunoiden piilotusaika (sekunteja, ei koske virheviestej\u00e4, 0 = ei automaattista piilotusta)
-ConfigView.label.popup.suppress_alerts=Piilota ilmoitukset (uusista tiedotetaan tilarivill\u00e4)
-ConfigView.label.popup.use_message_boxes=K\u00e4yt\u00e4 sanomaikkunoita ponnahdusikkunoiden sijaan
-ConfigView.label.popup.show=N\u00e4yt\u00e4 kaikki menneet ilmoitukset
-ConfigView.label.popup.show.button=N\u00e4yt\u00e4
-ConfigView.label.please.visit.here=Katso lis\u00e4tietoja t\u00e4st\u00e4
-ConfigView.section.ipfilter.enable.descriptionCache=Tallenna kuvaukset osoitealueista v\u00e4liaikaistiedostoon
-ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Jos tietoja ei tallenneta, kuvauksia ei muisteta.
-OpenTorrentWindow.filesInfo=Ladataan %1/%2
-OpenTorrentWindow.diskUsage=%1/%2
-ConfigView.label.openmytorrents=Avaa siirrot k\u00e4ynnistett\u00e4ess\u00e4
-ConfigView.label.open_transfer_bar_on_start=Avaa Siirrot-palkki k\u00e4ynnistett\u00e4ess\u00e4
-ConfigView.section.style.DNDalwaysInIncomplete=N\u00e4yt\u00e4 ei-ladattavia tiedostoja sis\u00e4lt\u00e4v\u00e4t torrent-tiedostot aina keskener\u00e4isiss\u00e4 siirroissa
-OpenTorrentWindow.mb.noGlobalDestDir.title=Tallennushakemistoa ei kelpaa
-OpenTorrentWindow.mb.noGlobalDestDir.text=Tallennushakemisto '%1' on virheellinen.
-OpenTorrentWindow.mb.noDestDir.title=Tallennushakemistoa ei l\u00f6ytynyt
-OpenTorrentWindow.mb.noDestDir.text=Tallennushakemistoa '%1' torrent-tiedostolle '%2' ei ole olemassa tai se on virheellinen.
-OpenTorrentWindow.mb.notValid.title=Torrent-tiedoston avaaminen
-OpenTorrentWindow.mb.notValid.text=Torrent-tiedostoa '%1' ei voitu avata. Jos olet avaamassa l\u00e4hett\u00e4mist\u00e4 varten, varmista ett\u00e4 itse l\u00e4hetett\u00e4v\u00e4t tiedostot ovat olemassa.
-OpenTorrentWindow.mb.notTorrent.title=Virhe tiedoston avauksessa
-OpenTorrentWindow.mb.notTorrent.text=Tiedostoa '%1' ei voitu avata. Se ei vaikuta olevan torrent-tiedosto.\n\nTiedostosta saatuja tietoja:\n%2
-ConfigView.label.pause.downloads.on.exit=Aseta siirrot keskeytettyyn tilaan lopetettaessa
-ConfigView.label.resume.downloads.on.start=Jatka keskeytettyj\u00e4 siirtoja k\u00e4ynnistett\u00e4ess\u00e4 kun alustus on valmistunut
-UIDebugGenerator.message.cancel.title=Virheenm\u00e4\u00e4ritystietojen luonti peruutettu
-UIDebugGenerator.message.cancel.text=Et kirjoittanut mink\u00e4\u00e4nlaista kuvausta havaitsemastasi ohjelmavirheest\u00e4. Ongelman esiintyminen saattaa olla itsest\u00e4\u00e4n selv\u00e4\u00e4 sinulle, mutta kehitt\u00e4j\u00e4t joutuisivat n\u00e4in vain arvailemaan ongelman taustoja ja ilmenemistilannetta.\n\nVirheenm\u00e4\u00e4ritystietojen luominen ja l\u00e4hett\u00e4minen on peruutettu.
-ConfigView.section.connection.group.http.info=HTTP-pohjaisen l\u00e4hett\u00e4misen tuki
-ConfigView.section.connection.http.enable=Ota k\u00e4ytt\u00f6\u00f6n
-ConfigView.section.connection.http.port=Sis\u00e4\u00e4ntulevien pyynt\u00f6jen portti
-ConfigView.section.connection.http.portoverride=Oman seurantapalvelimen HTTP-portin ohitus (0 = ei k\u00e4yt\u00f6ss\u00e4)
-window.update.noupdates.title=Ei p\u00e4ivityksi\u00e4 saatavilla
-window.update.noupdates.text=T\u00e4ll\u00e4 hetkell\u00e4 ei ole uusia p\u00e4ivityksi\u00e4 saatavilla.
-ConfigView.label.bindip.details=Esimerkki: "192.168.1.5;eth0;eth1[2]" sitoo m\u00e4\u00e4ritetyn IP-osoitteen kaikkiin ensimm\u00e4isen liit\u00e4nn\u00e4n IP-osoitteisiin ja toisen liit\u00e4nn\u00e4n kolmanteen IP-osoitteeseen.\nEnsimm\u00e4ist\u00e4 IP-osoitetta k\u00e4ytet\u00e4\u00e4n kaikille palveluille, muut on tarkoitettu kuorman tasaamista varten.\nK\u00e4ytett\u00e4viss\u00e4 ovat seuraavat liit\u00e4nn\u00e4t:\n%1
-ConfigView.label.mindownloads=Yht\u00e4aikaisten latausten v\u00e4himm\u00e4ism\u00e4\u00e4r\u00e4
-UI.cannot_submit_blank_text=Sy\u00f6t\u00e4 arvo.
-crypto.alert.as.warning='%1' -verkossa tiedet\u00e4\u00e4n tapahtuvan BitTorrent-liikenteen suodatusta. Vuzen liikenteen salaaminen on otettu automaattisesti k\u00e4ytt\u00f6\u00f6n - voit halutessasi muokata salausasetuksia asetuksista.
-ConfigView.section.interface.alerts=Ilmoitukset
-ConfigView.label.popupdownloadadded=Ilmoita siirron lis\u00e4\u00e4misest\u00e4 ponnahdusikkunalla
-popup.download.added="%1" lis\u00e4tty Siirtoihin.
-MessageBoxWindow.nomoreprompting=\u00c4l\u00e4 huomauta jatkossa
-TorrentOptionsView.param.max.seeds=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 l\u00e4hett\u00e4jiin (0 = k\u00e4yt\u00e4 yleist\u00e4 yhteysrajoitusta)
-TorrentOptionsView.param.alternative.value.enable=Vaihtoehtoinen m\u00e4\u00e4r\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4
-ConfigView.section.proxy.check.on.start=Tarkasta v\u00e4lityspalvelimen tila k\u00e4ynnistett\u00e4ess\u00e4
-TransferStatsView.legend.pingaverage=Keskim\u00e4\u00e4r\u00e4inen
-TransferStatsView.legend.ping1=Kohde 1
-TransferStatsView.legend.ping2=Kohde 2
-TransferStatsView.legend.ping3=Kohde 3
-ConfigView.section.interface.enabletray._mac=N\u00e4yt\u00e4 Vuzen kuvake tilapalkissa (vaatii uudelleenk\u00e4ynnistyksen)
-ConfigView.label.closetotray._mac=Sulkeminen piilottaa tilapalkkiin
-ConfigView.label.minimizetotray._mac=Pienent\u00e4minen piilottaa tilapalkkiin
-OpenTorrentWindow.mb.existingFiles.title=Tiedostot jo olemassa
-OpenTorrentWindow.mb.existingFiles.text=Seuraavat tiedostot ovat jo olemassa kohdehakemistoissa:\n\n%1\nJos jatkat, Vuze tarkastaa yll\u00e4olevien tiedostojen sis\u00e4ll\u00f6n vastaavuuden ja ylikirjoittaa ne tarvittaessa.
-splash.unloadingTorrents=Poistetaan torrent-tiedostoja muistista
-splash.unloadingTorrent=Poistetaan torrent-tiedostoa muistista
-ConfigView.section.file.defaultdir.autorename=Nime\u00e4 samannimiset, mutta sis\u00e4ll\u00f6lt\u00e4\u00e4n erilaiset tiedostot automaattisesti uudelleen
-ConfigView.section.file.defaultdir.autorename.tooltip=T\u00e4m\u00e4 est\u00e4\u00e4 torrent-tiedoston k\u00e4sitt\u00e4mien tiedostojen ylikirjoittamisen toisen torrent-tiedoston samannimisill\u00e4 tiedostoilla.
-alert.raised.at.close=(Viesti Vuzen edelliselt\u00e4 sulkemiskerralta)
-Plugin.trackerpeerauth.name=K\u00e4ytt\u00e4j\u00e4valtuutus
-Plugin.trackerpeerauth.info=T\u00e4t\u00e4 lis\u00e4osaa k\u00e4ytet\u00e4\u00e4n yhdess\u00e4 seurantapalvelimien toimintojen kanssa varmistamaan k\u00e4ytt\u00e4jien oikeudet torrent-tiedostoihin.
-Peers.column.maxupspeed=Enim.l\u00e4h.nopeus
-Peers.column.maxdownspeed=Enim.lat.nopeus
-MyTorrents.items.DownSpeedLimit.disabled=Ei ladata
-Peers.column.lan=L\u00e4hiverkko
-upnp.selectedaddresses=Osoitteet (erota ;-merkill\u00e4, etumerkit: - est\u00e4\u00e4, + sallii, tyhj\u00e4 ruutu = mik\u00e4 tahansa)
-upnp.alert.multipledevice.warning=Useita UPnP-laitteita havaittu - tarkasta vaativatko kaikki porttim\u00e4\u00e4ritykset (katso UPnP-loki ja -asetukset)
-UpdateMonitor.messagebox.restart.title=Ohjelmap\u00e4ivitys
-UpdateMonitor.messagebox.restart.text=Uusi t\u00e4rke\u00e4 ohjelmap\u00e4ivitys ladattu - Vuze t\u00e4ytyy k\u00e4ynnist\u00e4\u00e4 nyt uudelleen, jotta p\u00e4ivitys voidaan asentaa.
-PiecesView.BlockView.Have=Valmis
-PiecesView.BlockView.NoHave=Puuttuu
-PiecesView.BlockView.Header=%1 sarake(tta), %2 rivi(\u00e4), %3 osa(a)
-ConfigView.section.update.autodownload=Lataa p\u00e4ivitykset automaattisesti ja ilmoita kun ollaan valmiita asentamaan
-Peers.column.peer_id=Tunniste
-Peers.column.peer_id.info=K\u00e4ytt\u00e4j\u00e4n tunniste luettavassa muodossa.
-Peers.column.peer_byte_id=Tunniste
-Peers.column.peer_byte_id.info=K\u00e4ytt\u00e4j\u00e4n tunniste tavumuodossa.
-Peers.column.handshake_reserved=K\u00e4ttelybitit
-Peers.column.handshake_reserved.info=K\u00e4ttelyvaiheessa asetetut varatut bitit.
-Peers.column.client_identification=Asiakasohjelma (raaka)
-Peers.column.client_identification.info=Asiakasohjelman nimi raakamuodossa - hy\u00f6dyllinen virheenm\u00e4\u00e4rityksess\u00e4.
-dht.warn.user=Varoita mahdollisista NAT-/porttiohjausongelmista
-ConfigView.label.openbar.incomplete=Avaa seurantapalkki automaattisesti ladattaville
-ConfigView.label.openbar.complete=l\u00e4hetett\u00e4ville torrent-tiedostoille
-ConfigView.label.transferbar.remember_location=Muista Siirrot-palkin viimeisin sijainti
-ConfigView.section.transfer.autospeed.forcemin=%1, pakotettu l\u00e4hetysnopeus m\u00e4\u00e4ritett\u00e4ess\u00e4 vasteajan pohjavertailuarvoa
-MainWindow.menu.tools.speedtest=Nopeustesti
-speedtest.wizard.title=Nopeustesti
-speedtest.wizard.run=Suorita nopeustesti
-speedtest.wizard.test.mode.updown=l\u00e4hetys ja lataus
-speedtest.wizard.test.mode.up=l\u00e4hetys
-speedtest.wizard.test.mode.down=lataus
-SpeedTestWizard.test.panel.currinfo=BitTorrent-pohjainen yhteysnopeustesti.
-SpeedTestWizard.test.panel.label=Testin tyyppi:
-SpeedTestWizard.test.panel.already.running=Testi on jo k\u00e4ynniss\u00e4!
-SpeedTestWizard.test.panel.not.accepted=Testipyynt\u00f6\u00e4 ei hyv\u00e4ksytty:
-SpeedTestWizard.test.panel.abort=Keskeyt\u00e4
-SpeedTestWizard.test.panel.abort.countdown=Aikaa keskeytt\u00e4miseen:
-SpeedTestWizard.test.panel.test.countdown=Aikaa valmistumiseen:
-SpeedTestWizard.test.panel.testfailed=Testi ep\u00e4onnistui
-SpeedTestWizard.test.panel.aborted=Testi keskeytetty manuaalisesti.
-SpeedTestWizard.test.panel.enc.label=Liikenteen salaus:
-SpeedTestWizard.test.panel.standard=normaali
-SpeedTestWizard.test.panel.encrypted=salattu
-SpeedTestWizard.set.upload.button.apply=K\u00e4yt\u00e4
-SpeedTestWizard.set.upload.result=Testin tulokset
-SpeedTestWizard.set.upload.bytes.per.sec=kilotavua/s
-SpeedTestWizard.set.upload.bits.per.sec=bitti\u00e4/s
-SpeedTestWizard.finish.panel.title=Nopeustesti suoritettu!
-SpeedTestWizard.finish.panel.click.close=Nopeustesti suoritettu onnistuneesti, voit sulkea t\u00e4m\u00e4n ikkunan Sulje-painikkeella.
-SpeedTestWizard.finish.panel.max.upload=Enimm\u00e4isl\u00e4hetysnopeus:
-SpeedTestWizard.finish.panel.max.seeding.upload=- ainoastaan l\u00e4hetett\u00e4ess\u00e4:
-SpeedTestWizard.finish.panel.max.download=Enimm\u00e4islatausnopeus:
-SpeedTestWizard.finish.panel.enabled=k\u00e4yt\u00f6ss\u00e4
-SpeedTestWizard.finish.panel.disabled=ei k\u00e4yt\u00f6ss\u00e4
-SpeedTestWizard.abort.message.scheduled.in=Testi ajastettu alkamaan %1 sekunnin kuluttua
-SpeedTestWizard.abort.message.unsupported.type=Testin tyyppi\u00e4 ei tueta!
-SpeedTestWizard.abort.message.manual.abort=Keskeytetty manuaalisesti
-SpeedTestWizard.abort.message.scheduling.failed=Testin ajastus ep\u00e4onnistui
-SpeedTestWizard.abort.message.download.added=Lataus %1 lis\u00e4tty testin aikana
-SpeedTestWizard.abort.message.entered.error=Testilataus aiheutti virhetilanteen '%1'
-SpeedTestWizard.abort.message.entered.queued=Testilataus jonossa/pys\u00e4ytetyss\u00e4 tilassa
-SpeedTestWizard.abort.message.interrupted=TorrentSpeedTestMonitorThread-toiminto keskeytyi ennen testin valmistumista
-SpeedTestWizard.abort.message.execution.failed=Testin suoritus ep\u00e4onnistui
-SpeedTestWizard.abort.message.failed.peers=Yhteydenmuodostus k\u00e4ytt\u00e4jiin ei onnistunut
-SpeedTestWizard.abort.message.insufficient.slots=L\u00e4hett\u00e4minen k\u00e4ytt\u00e4jille ei onnistunut - ei vapaita l\u00e4hetyspaikkoja?
-SpeedTestWizard.abort.message.not.unchoked=Lataaminen k\u00e4ytt\u00e4jilt\u00e4 ei onnistunut, sill\u00e4 kaikki est\u00e4v\u00e4t tiedonsiirron
-SpeedTestWizard.stage.message.requesting=Pyydet\u00e4\u00e4n testi\u00e4 palvelimelta...
-SpeedTestWizard.stage.message.preparing=Valmistellaan testi\u00e4...
-SpeedTestWizard.stage.message.starting=Aloitetaan testi...
-SpeedTestWizard.stage.message.connect.stats=Yhteystilastot: k\u00e4ytt\u00e4ji\u00e4=%1, lataus ok=%2, l\u00e4hetys ok=%3
-window.uiswitcher.title=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
-window.uiswitcher.text=Valitse k\u00e4ytt\u00f6liittym\u00e4, joka vastaa parhaiten tarpeitasi.
-window.uiswitcher.NewUI.text=* Suositellaan aloitteleville, uusille k\u00e4ytt\u00e4jille\n\n* Helppo, intuitiivinen k\u00e4ytt\u00f6liittym\u00e4\n\n* Vaaditaan julkaisemiseen Vuze -alustalla
-window.uiswitcher.ClassicUI.title=Perinteinen
-window.uiswitcher.ClassicUI.text=* Vastaa t\u00e4ysin Azureuksen 2.x-sarjan toimintoja ja ulkoasua\n\n* Vuze -sis\u00e4lt\u00f6\u00e4 ei ladata n\u00e4kyville
-window.uiswitcher.bottom.text=Valintaa voi vaihtaa helposti j\u00e4lkik\u00e4teen valitsemalla ty\u00f6kalupalkin UI-painikkeen.
-iconBar.switch.tooltip=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
-VivaldiView.notAvailable=Vivaldi-n\u00e4kym\u00e4 ei k\u00e4ytett\u00e4viss\u00e4.
-restart.error=Uudelleenk\u00e4ynnistys ep\u00e4onnistui:\n%1\nKatso <A HREF="{restart.error.url}">lis\u00e4tietoja uudelleenk\u00e4ynnistysongelmista</a>.
-restart.error.oom=Ei vapaata muistia k\u00e4ytett\u00e4viss\u00e4.
-restart.error.fnf=Tiedostoa '%1' ei l\u00f6ytynyt hakemistosta '%2'.
-restart.error.pnf=Polkua '%1' ei l\u00f6ytynyt.
-restart.error.bad=Kelpaamaton tiedostomuoto (%1).
-restart.error.denied=Kohteen '%1' suorittaminen ei onnistunut. Varmista, ett\u00e4 sinulla on oikeudet suorittaa t\u00e4m\u00e4 ohjelma.
-TableColumn.header.date_completed=Valmistunut
-TableColumn.menu.date_added.reset=Nollaa ajankohta
-ConfigView.section.ipfilter.discardbanning=Vastaanotetun hyl\u00e4tyn/hyv\u00e4n tiedon suhde, jonka j\u00e4lkeen k\u00e4ytt\u00e4j\u00e4 estet\u00e4\u00e4n (0 = ei k\u00e4yt\u00f6ss\u00e4)
-ConfigView.section.ipfilter.discardminkb=Vaadittu hyl\u00e4tyn tiedon v\u00e4himm\u00e4ism\u00e4\u00e4r\u00e4 (%1) ennen suhdes\u00e4\u00e4nn\u00f6n k\u00e4ytt\u00f6\u00f6nottoa
-ConfigView.interface.start.advanced=K\u00e4ynnist\u00e4 lis\u00e4n\u00e4kym\u00e4ss\u00e4 (Vuze 2.x -tyyli)
-MyTorrents.column.ColumnQuality=Laatu
-MyTorrents.column.ColumnSpeed=Nopeus
-MyTorrents.column.ColumnProgressETA.2ndLine=J\u00e4ljell\u00e4: %1
-MyTorrents.column.ColumnProgressETA.StreamReady=Suoratoisto valmis
-MyTorrents.column.ColumnProgressETA.PlayableIn=Aikaa toistoon %1
-TableColumn.header.Quality=Laatu
-TableColumn.header.Speed=Nopeus
-TableColumn.header.RateIt=Arvostele
-TableColumn.header.Rating=Arvostelu
-TableColumn.header.SpeedGraphic=Nopeus
-TableColumn.header.AzProduct=L\u00e4hde
-TableColumn.header.ProgressETA=Valmistuminen
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-TableColumn.header.name.ext=Tyyppi: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
-v3.MainWindow.tab.home=Kojelauta
-v3.MainWindow.tab.browse=Vuze
-v3.MainWindow.tab.library=Kirjasto
-v3.MainWindow.tab.publish=Julkaise
-v3.MainWindow.tab.advanced=Lis\u00e4n\u00e4kym\u00e4
-v3.MainWindow.menu.home=&Kojelauta
-v3.MainWindow.menu.browse=&Vuze
-v3.MainWindow.menu.library=K&irjasto
-v3.MainWindow.menu.publish=&Julkaise
-v3.MainWindow.menu.advanced=&Lis\u00e4n\u00e4kym\u00e4
-v3.MainWindow.menu.view.searchbar=Hakupalkki
-v3.MainWindow.menu.view.tabbar=V\u00e4lilehtipalkki
-v3.MainWindow.currentDL=Ladataan parhaillaan
-v3.MainWindow.button.stream=Suoratoista
-v3.MainWindow.button.stop=Pys\u00e4yt\u00e4
-v3.MainWindow.button.start=K\u00e4ynnist\u00e4
-v3.MainWindow.button.pause=Keskeyt\u00e4
-v3.MainWindow.button.resume=Jatka
-v3.MainWindow.button.delete=Tuhoa
-v3.MainWindow.button.comment=Kommentoi
-v3.MainWindow.button.viewdetails=Lis\u00e4tiedot
-v3.MainWindow.button.play=Toista
-v3.MainWindow.button.cancel=Peruuta
-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=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 kok [...]
-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
-v3.mb.PlayFileNotFound.button.redownload=Lataa uudelleen
-v3.mb.PlayFileNotFound.button.find=Etsi manuaalisesti...
-v3.mb.deletePurchased.title=Ostetun sis\u00e4ll\u00f6n tuhoaminen
-v3.mb.deletePurchased.text=Haluatko varmasti tuhota kohteen '%1'?\n\nT\u00e4m\u00e4 sis\u00e4lt\u00f6 on joko ostettu tai sen lataamiseen vaadittiin sis\u00e4\u00e4nkirjautuminen palveluun.
-v3.mb.deletePurchased.button.delete=&Tuhoa
-v3.mb.deletePurchased.button.cancel=&Peruuta
-v3.topbar.menu.show.logo=Vuze -logo
-v3.topbar.menu.show.plugin=Lis\u00e4osaalue
-v3.topbar.menu.show.search=Haku
-v3.topbar.menu.show.frog=Azureus-logo
-splash.initializeCore=Alustetaan ydint\u00e4
-splash.initializeUIElements=Alustetaan k\u00e4ytt\u00f6liittym\u00e4elementtej\u00e4
-ConfigView.section.transfer.autospeedbeta=Autom. l\u00e4h.nopeus (beeta)
-#
-ConfigView.section.ipfilter.peerblocking.group=K\u00e4ytt\u00e4jien est\u00e4minen
-ConfigView.section.ipfilter.autoload.group=Automaattinen suodatinlistan lataaminen
-ConfigView.section.ipfilter.autoload.file=IP-suodintiedosto
-ConfigView.section.ipfilter.autoload.info=Tuetut tiedostomuodot ovat DAT (eMule), P2P (PeerGuardian, splist) ja P2B:n versiot 1, 2 ja 3 (PeerGuardian 2). Tiedosto voi olla paikallinen tai se voidaan noutaa URL-osoitteen perusteella, ja se voi olla zip- tai gzip-pakattu tai puhdas tekstitiedosto. URL-osoitteesta tiedosto ladataan automaattisesti uudelleen seitsem\u00e4n p\u00e4iv\u00e4n v\u00e4lein, paikallinen tiedosto minuutin sis\u00e4ll\u00e4 sen korvautumisesta tai muokkaamisesta.
-ConfigView.section.ipfilter.autoload.loadnow=Lataa
-splash.loadIpFilters=Ladataan IP-suotimia...
-SpeedTestWizard.set.upload.title=Aseta l\u00e4hetys- ja latausnopeusrajoitukset
-SpeedTestWizard.set.download.label=Enimm\u00e4islatausnopeus:
-SpeedTestWizard.set.upload.label=Enimm\u00e4isl\u00e4hetysnopeus:
-SpeedTestWizard.name.conf.level.absolute=Absoluuttinen
-SpeedTestWizard.name.conf.level.high=Korkea
-SpeedTestWizard.name.conf.level.med=Keskiverto
-SpeedTestWizard.name.conf.level.low=Matala
-SpeedTestWizard.name.conf.level.none=Ei mik\u00e4\u00e4n
-ConfigView.section.transfer.select=Autom. nopeus
-ConfigView.section.transfer.select.v2=Auto-Speed (beeta)
-mb.azmustclose.title=K\u00e4ynnistysvirhe
-mb.azmustclose.text=Vuze t\u00e4ytyy sulkea k\u00e4ynnistysvirheen takia - t\u00e4m\u00e4 todenn\u00e4k\u00f6isesti aiheutti ohjelman suorittamisen j\u00e4rjestelm\u00e4nvalvojan oikeuksilla.\n\nKun Vuze on suljettu, k\u00e4ynnist\u00e4 se uudelleen manuaalisesti.
-network.ipv6.prefer.addresses=K\u00e4yt\u00e4 IPv6-osoitteita, kun sek\u00e4 IPv6- ett\u00e4 IPv4-osoitteet ovat k\u00e4ytett\u00e4viss\u00e4
-network.bindError=Palvelinpistokkeen (server socket) kiinnitys ep\u00e4onnistui, koska yhteensopivia osoitteita ei l\u00f6ytynyt, tarkista sidosasetukset (bind-to-IP).
-network.enforce.ipbinding=Pakota IP-sidokset k\u00e4ytt\u00f6\u00f6n, vaikka liit\u00e4nt\u00f6j\u00e4 ei olisi saatavilla (est\u00e4\u00e4 yhteydet, jos yksik\u00e4\u00e4n m\u00e4\u00e4ritetyist\u00e4 liit\u00e4nn\u00f6ist\u00e4 ei ole saatavilla)
-DHTView.title.full_v6=Hajautettu tietokanta (IPv6)
-ConfigView.pluginlist.loadSelected=Lataa valitut
-SpeedView.stats.asn=Verkko:
-SpeedView.stats.estupcap=Enimm\u00e4isl\u00e4hetysnopeus:
-SpeedView.stats.estdowncap=Enimm\u00e4islatausnopeus:
-SpeedView.stats.unknown=tuntematon
-SpeedView.stats.estimate=arvio
-SpeedView.stats.measured=mitattu
-SpeedView.stats.measuredmin=mitattu v\u00e4h.
-SpeedView.stats.manual=kiinte\u00e4
-ConfigView.section.transfer.autospeed.networks=Verkon tarkemmat tiedot
-ConfigView.section.transfer.autospeed.resetnetwork=Palauta oletusarvot
-ConfigView.section.transfer.autospeed.network.info=Yll\u00e4olevat nopeusrajoitukset lasketaan automaattisesti normaalien siirtojen aikana tai ne saadaan nopeustestin tuloksena. Jos haluat m\u00e4\u00e4ritt\u00e4\u00e4 arvot manuaalisesti, k\u00e4yt\u00e4 alla olevia asetuksia.\nKaikkia muita paitsi tyypilt\u00e4\u00e4n kiinteit\u00e4 arvoja s\u00e4\u00e4det\u00e4\u00e4n tarvittaessa jatkossa automaattisesti.\nSy\u00f6t\u00e4 arvo ja valitse t\u00e4m\u00e4n j\u00e4lkeen sen varmuusrajaty [...]
-dialog.uiswitcher.restart.title=Uudelleenk\u00e4ynnistys vaaditaan
-dialog.uiswitcher.restart.text=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen vaatii Vuzen uudelleenk\u00e4ynnist\u00e4misen.
-TrayWindow.menu.close=Sulje pikalatauskuvake
-# Used for peers which we can't determine.
-PeerSocket.unknown=Tuntematon
-PeerSocket.fake_client=V\u00e4\u00e4renne
-PeerSocket.bad_peer_id=Kelpaamaton tunniste
-PeerSocket.mismatch_id=Poikkeama
-PeerSocket.unknown_az_style=Tuntematon %1 %2
-PeerSocket.unknown_shadow_style=Tuntematon %1 %2
-OpenTorrentWindow.mb.askCreateDir.title=Tallennushakemistoa ei ole olemassa
-OpenTorrentWindow.mb.askCreateDir.text=Tallennushakemistoa '%1' ei ole olemassa.\n\nLuodaanko se nyt?
-SpeedView.stats.estimatechoke=arvio, esto
-ConfigTransferAutoSpeed.upload.capacity.usage=L\u00e4hetyskapasiteetin k\u00e4ytt\u00f6
-ConfigTransferAutoSpeed.mode=Tila:
-ConfigTransferAutoSpeed.capacity.used=% kapasiteetista k\u00e4ytetty
-ConfigTransferAutoSpeed.while.downloading=Ladattaessa:
-ConfigTransferAutoSpeed.set.dht.ping=Vasteaika-asetus:
-ConfigTransferAutoSpeed.set.point=asetuskohta (ms)
-ConfigTransferAutoSpeed.set.tolerance=toleranssi (ms)
-ConfigTransferAutoSpeed.ping.time.good=Hyv\u00e4:
-ConfigTransferAutoSpeed.ping.time.bad=Huono:
-ConfigTransferAutoSpeed.adjustment.interval=Asetusv\u00e4li:
-ConfigTransferAutoSpeed.skip.after.adjust=Ohita asettamisen j\u00e4lkeen:
-GeneralView.label.distributedCopies=Jaetut kopiot:
-PiecesView.DistributionView.title=Osien jakauma
-PiecesView.DistributionView.NoAvl=Eiv\u00e4t saatavilla
-PiecesView.DistributionView.SeedAvl=Saatavuusosuus - l\u00e4hteet
-PiecesView.DistributionView.PeerAvl=Saatavuusosuus - lataajat
-PiecesView.DistributionView.RarestAvl=Harvinaisimmat: %1 (saat.: %2)
-PiecesView.DistributionView.weHave=On itsell\u00e4
-PiecesView.DistributionView.theyHave=On toisella
-PiecesView.DistributionView.weDownload=Parhaillaan ladattavat
-PeersView.gain=Saavutettu
-PeersView.gain.info=Ladattu m\u00e4\u00e4r\u00e4 v\u00e4hennettyn\u00e4 l\u00e4hetetyll\u00e4 m\u00e4\u00e4r\u00e4ll\u00e4.
-unix.script.new.title=Uusi k\u00e4ynnistyskomentosarja
-unix.script.new.text=Uusi Vuzen k\u00e4ynnistyskomentosarja on saatavilla ja se on tallennettu kohteeseen '%1'.\n\nOn suositeltavaa, ett\u00e4 suljet nyt Vuzen ja vaihdat uuteen komentosarjaan ('%2').\n\nJos olet muokannut kattavasti alkuper\u00e4ist\u00e4 komentosarjaa, katso lis\u00e4tietoja seuraavasta artikkelista: <A HREF="{unix.script.new.manual.url}">AzureusWiki: Unix Script</A>.\n\nJos k\u00e4yt\u00e4t jakeluversion omaa versiota Vuzesta (asennettu esimerkiksi yum:n tai apt-get:n [...]
-unix.script.new.button.quit=Lopeta nyt
-unix.script.new.button.continue=My\u00f6hemmin
-unix.script.new.button.asknomore=\u00c4l\u00e4 huomauta jatkossa
-unix.script.new.auto.title=Uusi k\u00e4ynnistyskomentosarja
-unix.script.new.auto.text=Uusi Vuzen k\u00e4ynnistyskomentosarja on saatavilla.\n\nOn suositeltavaa, ett\u00e4 k\u00e4ynnist\u00e4t Vuzen nyt uudelleen.
-Content.alert.notuploaded.button.stop=&Pys\u00e4yt\u00e4
-Content.alert.notuploaded.button.continue=&Jatka l\u00e4hett\u00e4mist\u00e4
-Content.alert.notuploaded.button.abort=&\u00c4l\u00e4 lopeta
-ConfigView.label.checkOnSeeding=Tee resurssiyst\u00e4v\u00e4llinen osien uudelleentarkastus l\u00e4hetett\u00e4ess\u00e4
-ConfigView.label.ui_switcher=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
-ConfigView.label.ui_switcher_button=N\u00e4yt\u00e4
-SpeedTestWizard.test.panel.explain=L\u00e4hetys- ja latausnopeuksien m\u00e4\u00e4ritt\u00e4minen BitTorrent-protokollan avulla. Valitse testin tyyppi, salaustaso ja Suorita. Testi keskeytyy automaattisesti viimeist\u00e4\u00e4n kahden minuutin kuluttua, normaalisti testi vie kuitenkin vain alle minuutin. Lis\u00e4tietoja on luettavissa wikist\u00e4.
-SpeedTestWizard.set.upload.hint=Aseta nopeusrajoitukset Vuzen Auto-Speed-algoritmille
-SpeedTestWizard.set.upload.panel.explain=Alla olevia asetuksia k\u00e4ytt\u00e4\u00e4 Vuzen Auto-Speed-algoritmi, joka on tarkoitettu l\u00e4hetys- ja latausnopeuksien automaattiseen asettamiseen - anna nopeusrajoitukset ja varmuusrajat.\n\nHuom.: Yhteysnopeudet ilmoitetaan yleens\u00e4 kilobittein\u00e4 sekunnissa, mutta alla olevat arvot ovat kilotavuja sekunnissa.
-SpeedTestWizard.set.limit.conf.level=Varmuusraja
-SpeedTestWizard.finish.panel.auto.speed=Autom. nopeuden asettaminen:
-SpeedTestWizard.finish.panel.auto.speed.seeding=- ainoastaan l\u00e4hetett\u00e4ess\u00e4:
-ConfigTransferAutoSpeed.add.comment.to.log.group=Lis\u00e4\u00e4 kommentti virheenm\u00e4\u00e4rityslokiin
-ConfigTransferAutoSpeed.add.comment.to.log=Kommentti:
-ConfigTransferAutoSpeed.log.button=Lis\u00e4\u00e4
-ConfigTransferAutoSpeed.algorithm.selector=Automaattinen l\u00e4hetys- ja latausnopeuksien asettaminen
-ConfigTransferAutoSpeed.algorithm=Algoritmi:
-ConfigTransferAutoSpeed.auto.speed.classic=Auto-Speed (perinteinen)
-ConfigTransferAutoSpeed.auto.speed.beta=Auto-Speed (beeta)
-ConfigTransferAutoSpeed.data.update.frequency=P\u00e4ivitystiheys
-Alert.failed.update=Ainakin yhden p\u00e4ivityksen asentaminen ep\u00e4onnistui. Katso lis\u00e4tietoja: <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
-OpenTorrentWindow.mb.existingFiles.partialList=(Vain osittainen listaus - lis\u00e4\u00e4 p\u00e4\u00e4llekk\u00e4isyyksi\u00e4 olemassa.)
-TableColumn.header.bad_avail_time.info=Aika, jolloin siirrosta on viimeksi ollut saatavilla t\u00e4ysi kopio.
-TableColumn.header.bad_avail_time=T\u00e4ysi kopio n\u00e4hty
-MyTorrentsView.menu.exporthttpseeds=HTTP-l\u00e4hteiden URL-osoitteet leikep\u00f6yd\u00e4lle
-SWT.alert.erroringuithread=Graafisessa k\u00e4ytt\u00f6liittym\u00e4ss\u00e4 ilmeni k\u00e4sittelem\u00e4t\u00f6n virhe. Seurauksena voi ilmet\u00e4 muita virheit\u00e4.
-ConfigView.label.minannounce=Seurantapalvelimen p\u00e4ivitysten v\u00e4linen v\u00e4himm\u00e4isaika (sekunneissa)
-ConfigView.label.maxnumwant=Seurantapalvelimen palauttamien yhteystietojen enimm\u00e4ism\u00e4\u00e4r\u00e4
-ConfigView.label.announceport=Ohita ilmoitettava TCP-portti (seurantapalvelimet, PEX ja DHT)\n(tyhj\u00e4 ruutu = ei ohitusta, 0 = ei sis\u00e4\u00e4ntulevia yhteyksi\u00e4)
-ConfigView.label.noportannounce=\u00c4l\u00e4 ilmoita kuuntelevaa porttia seurantapalvelimelle (ei vaikuta PEX- ja DHT-toimintoihin)
-ConfigView.label.maxseedspertorrent=Yhteyksien oletusenimm\u00e4ism\u00e4\u00e4r\u00e4 l\u00e4hett\u00e4jiin/torrent-tiedosto (0 = rajoittamaton)
-wizard.webseed=Lis\u00e4\u00e4 HTTP-l\u00e4hteet
-wizard.webseed.title=HTTP-l\u00e4hteet
-wizard.webseed.configuration=Lis\u00e4\u00e4 HTTP-l\u00e4hteet:
-wizard.webseed.adding=Lis\u00e4t\u00e4\u00e4n HTTP-l\u00e4hteit\u00e4
-GeneralView.label.private=Yksityinen:
-GeneralView.yes=Kyll\u00e4
-GeneralView.no=Ei
-ConfigView.label.userequestlimiting=K\u00e4yt\u00e4 latausnopeuden rajoittamiseen pyynt\u00f6jen hidastamista viiv\u00e4stettyjen lukujen sijaan (ei vaikutusta, jos rajoittamaton)
-ConfigView.label.userequestlimiting.tooltip=Pyynt\u00f6jen rajoittaminen ei ole yht\u00e4 sulava tapa kuin lukujen viiv\u00e4stytt\u00e4minen, mutta se mahdollistaa latausten priorisoinnin perustuen sijoitukseen latausjonossa ja saattaa parantaa verkkotoimintojen suorituskyky\u00e4.
-ConfigView.label.userequestlimitingpriorities=Keskit\u00e4 latausnopeus latausjonon alkuun, kun enimm\u00e4islatausnopeusrajoitus saavutettu
-ConfigView.section.logging.timestamp=Aikaleiman muoto
-Peers.column.timetocomplete=Aikaa j\u00e4ljell\u00e4
-Peers.column.timetocomplete.info=Aika, jonka kuluttua k\u00e4ytt\u00e4j\u00e4 on saanut latauksen valmiiksi.
-ConfigView.section.interface.display.suppress.file.download.dialog=Piilota torrent-tiedostojen lataamisen edistymisest\u00e4 kertovat tiedot
-ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Kaikki torrent-tiedostojen lataamisesta kertovat tiedot esitet\u00e4\u00e4n tilarivin edistymisraportteina ponnahdusikkunoiden sijaan.
-FileDownload.canceled=Torrent-tiedoston lataaminen on peruutettu k\u00e4ytt\u00e4j\u00e4n toimesta: %1
-Progress.reporting.status.canceled=Peruutettu
-Progress.reporting.status.finished=Valmis
-Progress.reporting.status.retrying=Yritet\u00e4\u00e4n uudelleen...
-Progress.reporting.action.label.retry.tooltip=Yrit\u00e4 operaation suorittamista uudelleen
-Progress.reporting.action.label.remove.tooltip=Poista t\u00e4m\u00e4 edistymisraportti historiasta
-Progress.reporting.action.label.cancel.tooltip=Peruuta operaatio
-Progress.reporting.action.label.detail=Tarkemmat tiedot
-Progress.reporting.default.error=Toiminto ep\u00e4onnistui
-Progress.reporting.no.reports.to.display=T\u00e4ll\u00e4 hetkell\u00e4 ei ole edistymisraportteja n\u00e4ytett\u00e4v\u00e4ksi.
-Progress.reporting.no.history.to.display=Ei tarkempia tietoja n\u00e4ytett\u00e4v\u00e4ksi.
-Progress.reporting.detail.history.limit=Edistymisraporttien historiaan ei mahdu enemp\u00e4\u00e4 raporttien tarkempia tietoja (raja: %1) - tulevia tietoja ei lis\u00e4t\u00e4 historiaan.
-Progress.reporting.statusbar.button.tooltip=N\u00e4yt\u00e4 edistymisraportit
-webui.bindip=Sido IP-osoitteeseen - ei normaalisti tarpeen (*)
-v3.MainWindow.text.log.in=Kirjaudu sis\u00e4\u00e4n
-v3.MainWindow.text.log.out=Kirjaudu ulos
-v3.MainWindow.text.get.started=Rekister\u00f6idy
-v3.MainWindow.text.my.account=Oma tunnus
-v3.MainWindow.text.my.profile=Profiili
-OpenTorrentWindow.simple.open=Sijainti (tiedosto, URL-osoite, tiiviste)
-Progress.reporting.window.remove.auto=Poista toimettomat raportit automaattisesti
-Progress.reporting.window.remove.auto.tooltip=Poistaa automaattisesti kaikkien valmiiden, ep\u00e4onnistuneiden ja peruutettujen toimintojen raportit listasta.
-Progress.reporting.window.remove.now=Poista toimettomat
-Progress.reporting.window.remove.now.tooltip=Poistaa kaikkien valmiiden, ep\u00e4onnistuneiden ja peruutettujen toimintojen raportit listasta.
-dhttracker.tracklimitedwhenonline=Kun seurantapalvelin on k\u00e4ytett\u00e4viss\u00e4, k\u00e4yt\u00e4 resurssiyst\u00e4v\u00e4llist\u00e4 seurantaa k\u00e4ytt\u00e4j\u00e4vaihdon varalta
-TorrentOptionsView.multi.title.short=Torrent-tiedoston asetukset
-TorrentOptionsView.multi.title.full=Torrent-tiedoston asetukset
-MyTorrentsView.menu.open_parent_folder=Avaa tallennushakemisto
-ConfigView.section.style.use_show_parent_folder=N\u00e4yt\u00e4 "%1" oletuksen "%2" sijaan torrent-tiedostovalikoissa
-ConfigView.section.style.use_show_parent_folder.tooltip=T\u00e4m\u00e4 mahdollistaa torrent-tiedoston kohteet sis\u00e4lt\u00e4v\u00e4n hakemiston avaamisen oikeassa tiedostonhallintaohjelmassa.\nAsetus voi kuitenkin aiheuttaa sen, ett\u00e4 latauksille ei pystyt\u00e4 valitsemaan automaattisesti tallennushakemistoa.
-PeerManager.status.ps_disabled=Seurantapalvelimen palauttamat tiedot eiv\u00e4t k\u00e4yt\u00f6ss\u00e4
-ConfigView.section.stats.exportfiles=Tallenna tarkat tiedot tiedostoista
-updater.cant.write.to.app.title=Asennushakemisto ei kirjoitettavissa
-updater.cant.write.to.app.details=Hakemistoon "%1" ei voida kirjoittaa.\n\nT\u00e4m\u00e4 est\u00e4\u00e4 tulevien ohjelmap\u00e4ivitysten asentamisen.\n\nKatso lis\u00e4tietoja <a href="http://www.azureuswiki.com/index.php/Failed_Update">wikist\u00e4</a>.
-plugin.install.class_version_error=T\u00e4m\u00e4 lis\u00e4osa vaatii toimiakseen uudemman version Javasta.
-v3.MainWindow.tab.minilibrary=Lataukset
-v3.MainWindow.tab.events=Tapahtumat
-button.columnsetup.tooltip=Valitse n\u00e4ytett\u00e4v\u00e4t sarakkeet
-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
-Menu.show.torrent.menu=N\u00e4yt\u00e4 torrent-tiedostovalikko
-Menu.show.torrent.menu.tooltip=N\u00e4ytt\u00e4\u00e4 torrent-tiedostovalikon p\u00e4\u00e4valikkopalkissa.
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
-Views.plugins.aznetstatus.title=Verkon tila
-plugin.aznetstatus.pingtarget=Tiedustelupakettien/reittihaun kohde
-ConfigView.section.style.usePathFinder=K\u00e4yt\u00e4 Path Finderia Finderin sijaan
-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 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
-MainWindow.menu.window.zoom.maximize=Suurenna
-MainWindow.menu.window.zoom.restore=Palauta
-ImageResizer.image.too.small=Annettu kuva on liian pieni - valitse uusi, jonka koko on v\u00e4hint\u00e4\u00e4n %1 x %2
-ImageResizer.title=T\u00e4m\u00e4n ty\u00f6kalun avulla n\u00e4et, milt\u00e4 pikkukuva tulee n\u00e4ytt\u00e4m\u00e4\u00e4n Vuze ssa
-ImageResizer.move.image=Siirr\u00e4 kuvaa raahaamalla sit\u00e4
-ImageResizer.move.image.with.slider=Siirr\u00e4 kuvaa raahaamalla sit\u00e4, muuta kokoa alla olevalla liukus\u00e4\u00e4timell\u00e4
-security.crypto.title=Salausavaimen suojaus
-security.crypto.encrypt=Anna salasana uuden salausavaimesi suojaamiseksi. T\u00e4t\u00e4 salasanaa ei ole mahdollista palauttaa, joten valitse se huolella.
-security.crypto.decrypt=Anna salasana salausavaimen avaamiseen.
-security.crypto.reason=Toiminnon syy
-security.crypto.password=Salasana
-security.crypto.password2=Salasana uudelleen
-security.crypto.persist_for=Salasanan s\u00e4ilyvyysaika
-security.crypto.persist_for.dont_save=\u00c4l\u00e4 tallenna
-security.crypto.persist_for.session=T\u00e4m\u00e4 istunto
-security.crypto.persist_for.day=1 p\u00e4iv\u00e4
-security.crypto.persist_for.week=1 viikko
-security.crypto.persist_for.30days=30 p\u00e4iv\u00e4\u00e4
-security.crypto.persist_for.forever=Ikuisesti
-security.crypto.password.mismatch.title=Salasanavirhe
-security.crypto.password.mismatch=Annetut salasanat eiv\u00e4t ole yhtenevi\u00e4, anna salasana uudelleen.
-ConfigView.section.security.group.crypto=Julkiset/yksityiset avaimet
-ConfigView.section.security.resetkey=Tyhjenn\u00e4 avaimet
-ConfigView.section.security.resetkey.warning.title=Varoitus tietojen menett\u00e4misest\u00e4
-ConfigView.section.security.resetkey.warning=Haluatko varmasti tyhjent\u00e4\u00e4 salausavaimesi? Jos tyhjenn\u00e4t avaimet, kaikki niiden avulla salatut tiedot menetet\u00e4\u00e4n pysyv\u00e4sti, eiv\u00e4tk\u00e4 julkisen avaimesi k\u00e4ytt\u00e4j\u00e4t pysty en\u00e4\u00e4 kommunikoimaan kanssasi ilman uutta avainta.
-ConfigView.section.security.unlockkey=Avaa avaimet
-ConfigView.section.security.unlockkey.button=Avaa
-ConfigView.section.security.publickey=Julkinen avain
-ConfigView.section.security.publickey.undef=Ei viel\u00e4 m\u00e4\u00e4ritelty
-ConfigView.section.security.resetkey.error.title=Toiminto ep\u00e4onnistui
-ConfigView.section.security.resetkey.error=Avainten tyhjent\u00e4minen ep\u00e4onnistui
-ConfigView.section.security.unlockkey.error=Avainten avaaminen ep\u00e4onnistui - salasana ei kelpaa
-ConfigView.copy.to.clipboard.tooltip=Kopioi leikep\u00f6yd\u00e4lle
-Views.plugins.azbuddy.title=Yst\u00e4v\u00e4t
-Browser.popup.error.no.access=Virhe et\u00e4resurssin k\u00e4yt\u00f6ss\u00e4.\nYrit\u00e4 my\u00f6hemmin uudelleen.
-ConfigView.label.queue.stoponcebandwidthmet=\u00c4l\u00e4 k\u00e4ynnist\u00e4 uusia torrentteja, kun l\u00e4hetys/lataus nopeusraja on saavutettu
-ConfigView.section.style.forceMozilla=Pakota Vuze k\u00e4ytt\u00e4m\u00e4\u00e4n Mozillaa selain-widgetteihin [vaaditaan xulrunner tai firefox 3; uudelleenk\u00e4ynnistys]
-ConfigView.section.style.xulRunnerPath=Aseta XulRunner / Firefox -hakemisto k\u00e4sin [Vaaditaan FF3:a varten; uudelleenk\u00e4ynnistys]
-Button.retry=Yrit\u00e4 uudelleen
-Button.ignore=Ohita
-DHTView.general.skew=Vinous:
-security.crypto.badpw=Salasana oli v\u00e4\u00e4rin
-ConfigView.section.security.backupkeys=Varmuuskopioi avaimet tiedostoon
-ConfigView.section.security.backupkeys.button=Varmuuskopio
-ConfigView.section.security.restorekeys=Palauta avaimet tiedostosta
-ConfigView.section.security.restorekeys.button=Palauta
-ConfigView.section.security.op.error.title=Toiminto ep\u00e4onnistui
-ConfigView.section.security.op.error=Toiminto ep\u00e4onnistui:\n    %1
-ConfigView.section.security.restart.title=Uudelleenk\u00e4ynnistys tarvitaan
-ConfigView.section.security.restart.msg=Vuze k\u00e4ynnistyy uudelleen toiminnon viimeistelemiseksi.
-ConfigView.section.security.system.managed=Avainten suojaus j\u00e4rjestelm\u00e4ss\u00e4
-Button.bar.show=N\u00e4yt\u00e4
-Button.bar.hide=Piilota
-Button.bar.share=Jaa
-Button.bar.add=Lis\u00e4\u00e4
-Button.bar.edit=Muokkaa
-Button.bar.edit.cancel=Muokkaus valmis
-v3.MainWindow.menu.view.pluginbar=Lis\u00e4osat-palkki
-MainWindow.dialog.select.vuze.file=Valitse Vuze-tiedosto
-MainWindow.menu.file.open.vuze=Vuze-tiedosto...
-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
-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
-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.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?
-fileplugininstall.install.desc=Oletko varma, ett\u00e4 haluat asentaan lis\u00e4osan '%1' version %2?
-fileplugininstall.duplicate.title=Lis\u00e4osan tuplakopio
-fileplugininstall.duplicate.desc=Lis\u00e4osan '%1' versio %2 on jo asennettuna
-progress.window.msg.progress=Odota toimenpiteen valmistumista
-DetailedListView.title=Yksityiskohtainen luettelo
-ConfigView.section.connection.network.max.outstanding.connect.attempts=Suurin sallittu l\u00e4htevien yhteyksien m\u00e4\u00e4r\u00e4
-plugins.init.force_enabled=Vuze havaitsi lis\u00e4osan "%1" olevan estettyn\u00e4 toimimasta - se on sallittu uudelleen Vuzen toiminnan varmistamiseksi.
-ConfigView.section.connection.prefer.udp=Suosi UDP-yhteyksi\u00e4
-iconBar.start=K\u00e4ynnist\u00e4
-iconBar.stop=Pys\u00e4yt\u00e4
-iconBar.remove=Poista
-iconBar.up=Yl\u00f6s
-iconBar.down=Alas
-iconBar.run=K\u00e4ynnist\u00e4
-iconBar.editcolumns=Sarakeasetukset
-iconBar.top=Ylimm\u00e4ksi
-iconBar.bottom=Alimmaksi
-iconBar.queue=K\u00e4ynnist\u00e4
-iconBar.open=Lis\u00e4\u00e4 torrent
-iconBar.share=Jaa
-iconBar.share.tooltip=Jaa sis\u00e4lt\u00f6\u00e4
-iconBar.details=Yksityiskohdat
-iconBar.comment=Kommentti
-iconBar.play=Soita
-iconBar.queue.tooltip=K\u00e4ynnist\u00e4 (aseta jonoon)
-v3.MainWindow.menu.view.sidebar=Sivupalkki
-v3.MainWindow.menu.view.toolbars=Ty\u00f6kalupalkit
-ump.install=Pikap\u00e4ivitys k\u00e4ynniss\u00e4:\nAsennetaan video soittamiseen tarvittava pieni lis\u00e4osa.
-PluginDeprecation.log.start=T\u00e4m\u00e4 ikkuna sis\u00e4lt\u00e4\u00e4 tietoa lis\u00e4osista, jotak k\u00e4ytt\u00e4v\u00e4t tulevaisuudessa poistettavia Vuzen toiminnallisuuksia.\nSinun ei tarvitse poistaa kyseisten lis\u00e4osien asennusta, mutta sinun pit\u00e4isi p\u00e4ivitt\u00e4\u00e4 lis\u00e4osat uusimpaan versioon.\nJos k\u00e4yt\u00e4t jo lis\u00e4osan uusinta versiota, voisit kopioida t\u00e4m\u00e4n ikkunan sis\u00e4ll\u00f6n Vuzen foorumille:\n \t%1\n\n
-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.
-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.help.support=Apua ja tukea
-Button.done=Valmis
-GeneralView.torrent_created_on_and_by=%1 / %2
-Button.continue=Jatka
-Button.preview=Esikatsele
-sidebar.Library=Kirjasto
-sidebar.LibraryDL=Lataukset
-sidebar.LibraryCD=Valmiit
-authenticator.location=Sijainti
-authenticator.details=Detaljit
-v3.MainWindow.menu.showActionBarText=N\u00e4yt\u00e4 teksti
-Button.remove=Poista
-Button.send=L\u00e4het\u00e4
-Button.back=Takaisin
-sidebar.LibraryUnopened=Ei-katsotut
-TableColumn.header.unopened=Uusi
-Unopened.bigView.header=Uusi
-ConfigView.section.Subscriptions=Tilaukset
-v3.activity.button.readall=Merkitse kaikki luetuiksi
-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
-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
-v3.iconBar.up.tooltip=Siirr\u00e4 yl\u00f6s\nPid\u00e4 hiirt\u00e4 painettuna siirt\u00e4\u00e4ksesi ylimm\u00e4ksi
-v3.iconBar.down.tooltip=Siirr\u00e4 alas\nPid\u00e4 hiirt\u00e4 painettuna siirt\u00e4\u00e4ksesi alimmaksi
-Button.deleteContent.fromLibrary=Poista Vuzen kirjastosta
-Button.deleteContent.fromComputer=Poista tietokoneelta
-v3.deleteContent.message=\nHaluatko poistaa '%1' my\u00f6s tietokoneeltasi, vai poistaa sen vain Vuzen kirjastosta?
-v3.MainWindow.menu.view.toolbartext=Ty\u00f6kalupalkin tekstit
-v3.MainWindow.menu.view.asSimpleList=Yksinkertainen luettelo
-v3.MainWindow.menu.view.asAdvancedList=Kehittynyt luettelo
-v3.MainWindow.menu.view.statusbar=Tilarivi
-configureWizard.file.message3=Vuze tallentaa lataamasi tiedostot hakemistoon. Valitse kyseinen hakemisto nyt:
-v3.deleteContent.applyToAll=Tee toiminto %1 kaikille valituille kohteille
-ConfigView.label.seeding.firstPriority.ignoreIdleHours=jotka eiv\u00e4t l\u00e4het\u00e4 mit\u00e4\u00e4n
-v3.MainWindow.menu.contentnetworks=&HD Network
-v3.MainWindow.menu.contentnetworks.about=HD Networks -tietoa
-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.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.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.
-TableColumn.header.size.info=Torrent-tiedoston kohteen koko.
-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.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
-Peers.column.%.info=K\u00e4ytt\u00e4j\u00e4n t\u00e4h\u00e4n menness\u00e4 lataama osuus torrentista
-TableColumn.header.download.info=Kohteelt\u00e4 ladattu tietom\u00e4\u00e4r\u00e4
-TableColumn.header.upload.info=L\u00e4hetetyn tiedon m\u00e4\u00e4r\u00e4
-TableColumn.header.downloadspeed.info=Meid\u00e4n lataamisnopeutemme t\u00e4lt\u00e4 kohteelta
-TableColumn.header.uploadspeed.info=Tiedon l\u00e4hetysnopeus
-TableColumn.header.lan.info=Samassa LAN-verkossa olevan lataajan indikaattori
-TableColumn.header.downloadspeedoverall.info=Lataajan arvioitu lataamisnopeus
-Peers.column.pieces.info=Graafinen esitys k\u00e4ytt\u00e4j\u00e4n lataamista osista
-TableColumn.header.TableColumnNameInfo=Sarakkeen nimi ja kuvaus
-TableColumn.header.TableColumnSample=Esimerkki
-TableColumn.header.TableColumnInfo=Sarakkeen kuvaus
-TableColumn.header.TableColumnChosenColumn=Valittu sarake
-label.learnmore=Lis\u00e4tietoja
-ColumnSetup.title=Sarakeasetukset: '%1'
-ColumnSetup.explain=Katso valittavissa olevia sarakkeiden listaa vasemmalla, ja lis\u00e4\u00e4 haluamasi oikealla olevaan valittujen sarakkeiden listaan. Voit suodattaa tarjolla olevien listaa alavasemmalla olevilla suodattimilla. Sarakenimien vet\u00e4minen hiirell\u00e4 on mahdollista.
-ColumnSetup.chosencolumns=Valitut sarakkeet
-ColumnSetup.proficiency=K\u00e4ytt\u00e4j\u00e4n taidot:
-ColumnSetup.categories=Luokat:
-ColumnSetup.filters=Suodatus
-ColumnSetup.availcolumns=Mahdolliset %1 sarakkeet
-ColumnSetup.availcolumns.filteredby=Mahdolliset %1 sarakkeet, suodatus %2
-devices.view.title=Oheislaitteet
-ConfigView.label.maxStalledSeeding=Max. 'pys\u00e4htynyt' [0:rajoittamaton]
-General.percent=Prosenttia
-MainWindow.menu.help.donate=Tee &lahjoitus
-DonationWindow.noload.title=Lahjoitukset
-DonationWindow.noload.text=Lahjoitusikkunan lataaminen ep\u00e4onnistui. Yrit\u00e4 my\u00f6hemmin uudelleen.
-download.removerules.unauthorised.data=\tPoista my\u00f6s datatiedostot
-iconBar.transcode=Oheislaite
-iconBar.transcode.tooltip=Muunna media oheislaitetta varten
-TableColumn.header.profile=Oheislaite
-TableColumn.header.device=Oheislaite
-TableColumn.header.device.info=Kohde-oheislaite
-# This is the beginning of the word "View".  It's right aligned under the icon bar item
-v3.iconBar.view.big=N\u00e4k
-v3.iconBar.view.big.tooltip=Yksinkertainen
-# This is the end of the word "View".  It's left aligned under the icon bar item
-v3.iconBar.view.small=ym\u00e4
-v3.iconBar.view.small.tooltip=Kehittynyt luettelo
-general.dont.ask.again=\u00c4l\u00e4 kysy uudelleen
-TableColumn.header.duration=Kesto
-TableColumn.header.resolution=Resoluutio
-option.askeverytime=Kysy joka kerta
-option.rememberthis=Muista t\u00e4m\u00e4 asetus
-label.clickone=Valitse yksi
-Button.turnon=K\u00e4ynnist\u00e4
-ConfigView.label.dm.dblclick=Tuplaklikkaus torrent-n\u00e4kym\u00e4ss\u00e4:
-ConfigView.option.dm.dblclick.play=Soita/k\u00e4ynnist\u00e4 sis\u00e4lt\u00f6
-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
-dlg.corewait.text=Odota hetki...\n\nPyynt\u00f6si k\u00e4sitell\u00e4\u00e4n Vuzen k\u00e4ynnistymisen p\u00e4\u00e4tytty\u00e4
-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
-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
-label.rename=Uudelleennime\u00e4 %1
-RCM.column.rc_rank=Sija
-RCM.column.rc_created=Luotu
-RCM.column.rc_hash=Tiiviste
-RCM.column.rc_lastseen=Viimeksi n\u00e4hty
-RCM.column.rc_level=Taso
-RCM.column.rc_tracker=Seurantapalvelin
-rcm.view.heading=Naapuritorrentit
-rcm.config.enabled=K\u00e4yt\u00f6ss\u00e4
-rcm.config.max_results=Tuloksia enint\u00e4\u00e4n
-rcm.config.max_level=Maksimitaso
-rcm.search.provider=Parvi
-wizard.webseedseditor.edit.title=HTTP-l\u00e4hteiden muokkaus
-wizard.webseedseditor.edit.newseed=Uusi l\u00e4hde
-MyTorrentsView.menu.editWebSeeds=Muokkaa HTTP-l\u00e4hteit\u00e4
-ClientStats.title.full=Asiakasohjelma-tilastot
-ClientStats.column.count=M\u00e4\u00e4r\u00e4
-Scrape.status.cached=Pikap\u00e4ivitys v\u00e4limuistista
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=Torrent-tiedosto...
+Main.parameter.usage=K\u00e4ytt\u00f6: java org.gudy.azureus2.cl.Main [parametrit] "tiedosto.torrent" "tallennushakemisto" 
+Main.parameter.maxUploads=Yht\u00e4aikaisten l\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4 
+Main.parameter.maxSpeed=Enimm\u00e4isl\u00e4hetysnopeus (kB/s) 
+MainWindow.menu.file=&Tiedosto 
+MainWindow.menu.file.open=&Avaa 
+MainWindow.menu.file.create=L&uo torrent-tiedosto...
+MainWindow.menu.file.create.fromfile=&Tiedostosta 
+MainWindow.menu.file.create.fromdir=&Hakemistosta 
+MainWindow.menu.file.export=&Vie torrent-tiedosto XML-muotoon...
+MainWindow.menu.file.import=&Tuo torrent-tiedosto XML-muodosta...
+MainWindow.menu.file.closetab=Sulje v&\u00e4lilehti
+MainWindow.menu.file.closewindow=Sulje &ikkuna
+MainWindow.menu.file.exit=&Lopeta 
+MainWindow.dialog.choose.file=Valitse torrent-tiedosto 
+MainWindow.menu.file.folder=Torrent-tiedostot &hakemistosta
+MainWindow.dialog.choose.folder=Valitse torrent-tiedostot sis\u00e4lt\u00e4v\u00e4 hakemisto 
+MainWindow.menu.view=&N\u00e4yt\u00e4 
+MainWindow.menu.view.show=N\u00e4yt\u00e4
+MainWindow.menu.view.open_global_transfer_bar=Siirrot-palkki
+MainWindow.menu.view.configuration=&Asetukset...
+MainWindow.menu.view.console=&Konsoli 
+MainWindow.menu.view.irc=IRC
+MainWindow.menu.view.allpeers=Kaikki yhteydet
+MainWindow.menu.view.detailedlist=&Yksityiskohtainen luettelo
+MainWindow.menu.closealldetails=Sulje kaikki tarkat ti&edot 
+MainWindow.menu.closealldownloadbars=Sulje kaikki &seurantapalkit 
+MainWindow.menu.language=&Kieli 
+ConfigView.section.language=Kieli
+MainWindow.menu.window=&Ikkuna
+MainWindow.menu.window.minimize=&Pienenn\u00e4
+MainWindow.menu.window.zoom=&L\u00e4henn\u00e4
+MainWindow.menu.window.alltofront=Tuo kaikki &eteen
+MainWindow.menu.help=&Ohje 
+MainWindow.menu.help.about=Tietoja Vuzesta
+MainWindow.menu.torrent=To&rrent-tiedosto
+MainWindow.about.title=Tietoja Vuzesta- versio
+MainWindow.about.section.system=J\u00e4rjestelm\u00e4tiedot
+MainWindow.about.section.internet=Vuze Internetiss\u00e4
+MainWindow.about.internet.homepage=Kotisivu
+MainWindow.about.internet.sourceforge=SourceForge.netin projektisivu 
+MainWindow.about.internet.bugreports=Ohjelmavirheilmoitukset
+MainWindow.about.internet.forumdiscussion=Keskustelualueet
+MainWindow.about.internet.wiki=Vuze Wiki (UKK)
+MainWindow.dialog.choose.savepath=Valitse tallennushakemisto 
+MainWindow.dialog.choose.savepath_forallfiles=Valitse tallennushakemisto kaikille tiedostoille 
+MainWindow.status.latestversion=Uusin virallinen versio:
+MainWindow.status.latestversion.clickupdate=P\u00e4ivit\u00e4 t\u00e4st\u00e4 
+MainWindow.status.unknown=Tuntematon 
+MainWindow.status.checking=Tarkastetaan 
+TableColumn.header.name=Nimi
+TableColumn.header.size=Koko
+TableColumn.header.done=Valmiina
+TableColumn.header.done.info=Latauksen valmistuminen prosenteissa.
+TableColumn.header.status=Tila
+TableColumn.header.status.info=Torrent-tiedoston tila
+TableColumn.header.seeds=L\u00e4hteet
+TableColumn.header.seeds.info=Yhdistettyjen l\u00e4hteiden lukum\u00e4\u00e4r\u00e4 (suluissa lukum\u00e4\u00e4r\u00e4 kaikkiaan).
+TableColumn.header.peers=Lataajat
+TableColumn.header.peers.info=Yhdistettyjen lataajien lukum\u00e4\u00e4r\u00e4 (suluissa lukum\u00e4\u00e4r\u00e4 kaikkiaan).
+TableColumn.header.completed=Valmiit
+TableColumn.header.completed.info=K\u00e4ytt\u00e4jien lukum\u00e4\u00e4r\u00e4, jotka ovat seurantapalvelimen mukaan saaneet latauksen valmiiksi.
+TableColumn.header.downspeed=Latausnopeus
+TableColumn.header.upspeed=L\u00e4hetysnopeus
+TableColumn.header.eta=Valm.aika
+TableColumn.header.tracker=Seurantapalvelimen tila 
+TableColumn.header.tracker.info=Seurantapalvelimen tila.
+TableColumn.header.trackernextaccess=Seuraava p\u00e4ivitys
+TableColumn.header.trackernextaccess.info=J\u00e4ljell\u00e4 oleva aika seurantapalvelimen seuraavaan p\u00e4ivitykseen.
+TableColumn.header.priority=Prioriteetti
+TableColumn.header.priority.info=M\u00e4\u00e4rittelee torrent-tiedostolle varattavan l\u00e4hetysnopeuden.
+TableColumn.header.seeds.fullcopycalc=%2 oletettua t\u00e4ytt\u00e4 kopiota %1 lataajaa kohti
+MyTorrentsView.menu.showdetails=&N\u00e4yt\u00e4 tarkemmat tiedot 
+MyTorrentsView.menu.showdownloadbar=N&\u00e4yt\u00e4 seurantapalkki 
+MyTorrentsView.menu.open=Avaa 
+MyTorrentsView.menu.setpriority=Aseta p&rioriteetti 
+MyTorrentsView.menu.setpriority.high=&Korkea 
+MyTorrentsView.menu.setpriority.low=&Alhainen 
+MyTorrentsView.menu.start=K\u00e4ynnist\u00e4
+MyTorrentsView.menu.stop=P&ys\u00e4yt\u00e4 
+MyTorrentsView.menu.remove=&Poista 
+MyTorrentsView.menu.changeTracker=&Lis\u00e4\u00e4 uusi seurantapalvelin
+TrayWindow.menu.exit=&Lopeta 
+TrayWindow.menu.show=&N\u00e4yt\u00e4 Vuze
+SystemTray.menu.exit=&Lopeta 
+SystemTray.menu.closealldownloadbars=&Sulje kaikki seurantapalkit 
+SystemTray.menu.open_global_transfer_bar=N\u00e4yt\u00e4 Siirrot-palkki
+SystemTray.menu.show=&N\u00e4yt\u00e4 Vuze
+PeersView.ip=IP-osoite
+PeersView.ip.info=K\u00e4ytt\u00e4j\u00e4n IP-osoite.
+PeersView.port=Portti
+PeersView.port.info=K\u00e4ytetty portti.
+PeersView.T=Tyyppi
+PeersView.T.info=Yhteyden muodostuminen: L (sin\u00e4 muodostit) tai R (k\u00e4ytt\u00e4j\u00e4 muodosti).
+PeersView.T.L.tooltip=Sin\u00e4 muodostit yhteyden.
+PeersView.T.R.tooltip=K\u00e4ytt\u00e4j\u00e4 muodosti yhteyden.
+PeersView.I1=Kiinnostus (sin\u00e4 kiinnostunut)
+PeersView.I1.info=Sin\u00e4 olet kiinnostunut toisen k\u00e4ytt\u00e4j\u00e4n osista.
+PeersView.C1=Estetty
+PeersView.C1.info=K\u00e4ytt\u00e4j\u00e4 est\u00e4\u00e4 sinua lataamasta h\u00e4nelt\u00e4.
+PeersView.pieces=Osat
+PeersView.downloadspeed=Latausnopeus
+PeersView.download=Ladattu
+PeersView.download.info=Kokonaislatausm\u00e4\u00e4r\u00e4si t\u00e4lt\u00e4 taholta.
+PeersView.I2=Kiinnostus (K\u00e4ytt\u00e4j\u00e4 kiinnostunut)
+PeersView.I2.info=Toinen k\u00e4ytt\u00e4j\u00e4 on kiinnostunut sinun osistasi.
+PeersView.C2=Estet\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4\u00e4
+PeersView.C2.info=Sin\u00e4 est\u00e4t k\u00e4ytt\u00e4j\u00e4\u00e4 lataamasta sinulta.
+PeersView.uploadspeed=L\u00e4hetysnopeus
+PeersView.uploadspeed.info=L\u00e4hetysnopeus k\u00e4ytt\u00e4j\u00e4lle.
+PeersView.upload=L\u00e4hetetty
+PeersView.upload.info=L\u00e4hetetty m\u00e4\u00e4r\u00e4.
+PeersView.statup=Arvio
+PeersView.statup.info=Arvioitu l\u00e4hetysnopeus, jolla k\u00e4ytt\u00e4j\u00e4 pystyy l\u00e4hett\u00e4m\u00e4\u00e4n tietoa.
+PeersView.S=Siirtoeste
+PeersView.S.info=Manuaalisesti tai autom. estetty, jos ei l\u00e4hetet\u00e4 riitt\u00e4v\u00e4n nopeasti.
+PeersView.downloadspeedoverall=K\u00e4ytt\u00e4j\u00e4nopeus
+PeersView.optunchoke=Optimistinen vapautus
+PeersView.client=Asiakasohjelma
+PeersView.client.info=K\u00e4ytt\u00e4j\u00e4n BitTorrent-asiakasohjelma.
+PeersView.menu.snubbed=&Estetty 
+PeersView.title.short=Yhteydet 
+PeersView.title.full=Yhteydet 
+AllPeersView.title.full=Kaikki yhteydet
+ConfigView.section.files=Tiedostot 
+ConfigView.label.usefastresume=K\u00e4yt\u00e4 nopeaa latauksen jatkamista 
+ConfigView.label.incrementalfile=Varaa levytilaa viimeiseen ladattuun osaan asti (vaaditaan Linux-k\u00e4yt\u00f6ss\u00e4, jos tallennetaan FAT32-osiolle)
+ConfigView.label.defaultsavepath=Tallenna tiedostot oletushakemistoon
+ConfigView.button.browse=&Selaa... 
+ConfigView.dialog.choosedefaultsavepath=Valitse oletustallennushakemisto 
+ConfigView.section.server=Yhteys
+ConfigView.section.global=Yleiset 
+ConfigView.label.disconnetseed=Katkaise yhteys l\u00e4hett\u00e4jiin latauksen valmistuttua 
+ConfigView.label.switchpriority=Vaihda alhaiselle prioriteetille latauksen valmistuttua
+ConfigView.label.maxdownloads=Yht\u00e4aikaisten latausten enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)\n - ei voi olla suurempi kuin aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4
+ConfigView.label.maxdownloads.tooltip=Enimm\u00e4ism\u00e4\u00e4r\u00e4 t\u00e4yttyy yleens\u00e4 normaalisti. S\u00e4\u00e4nt\u00f6\u00f6n on kuitenkin yksi poikkeus:\njos v\u00e4ltt\u00e4m\u00e4tt\u00e4 niin vaaditaan, voi ensisijainen, valmistunut torrent-tiedosto ottaa haltuunsa yhden latauspaikan.\nT\u00e4ll\u00f6in aktiivisten latausten m\u00e4\u00e4r\u00e4 siis v\u00e4henee yhdell\u00e4.
+ConfigView.label.maxactivetorrents=Aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)\n - uudet siirrot eiv\u00e4t k\u00e4ynnisty, jos enimm\u00e4ism\u00e4\u00e4r\u00e4 on t\u00e4ynn\u00e4
+ConfigView.label.priorityExtensions=Lataa ensisijaisesti\ntiedostotyypin ollessa\n(esim: .txt;.nfo;.jpg)
+ConfigView.section.transfer=Siirrot 
+ConfigView.label.maxuploads=L\u00e4hetyspaikkojen oletusenimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto
+ConfigView.label.maxuploadspeed=kB/s, enimm\u00e4isl\u00e4hetysnopeus (kaikki torrent-tiedostot, 0 = rajoittamaton)
+ConfigView.label.saveresumeinterval=P\u00e4ivit\u00e4 tiedot joka 
+ConfigView.unlimited=Rajoittamaton 
+ConfigView.section.display=Ulkoasu 
+ConfigView.label.opendetails=N\u00e4yt\u00e4 torrent-tiedoston tarkemmat tiedot automaattisesti
+ConfigView.label.openbar=N\u00e4yt\u00e4 seurantapalkki automaattisesti
+ConfigView.label.use_old_speed_menus=K\u00e4yt\u00e4 perinteist\u00e4 valikkotyyli\u00e4 lataus- ja l\u00e4hetysnopeuksien asettamiseen (vaatii uudelleenk\u00e4ynnistyksen)
+ConfigView.label.closetotray=Sulkeminen piilottaa ilmoitusalueelle
+ConfigView.label.minimizetotray=Pienent\u00e4minen piilottaa ilmoitusalueelle
+ConfigView.section.general=Yleiset 
+ConfigView.section.start=K\u00e4ynnistys 
+ConfigView.label.showsplash=N\u00e4yt\u00e4 aloitusruutu
+ConfigView.label.autoupdate=Avaa P\u00e4ivitysavustaja, kun uusi versio on saatavilla 
+ConfigView.label.openconsole=Avaa konsoli k\u00e4ynnistett\u00e4ess\u00e4 
+ConfigView.label.openconfig=Avaa asetukset k\u00e4ynnistett\u00e4ess\u00e4 
+ConfigView.label.startminimized=K\u00e4ynnist\u00e4 piilotettuna ilmoitusalueelle
+ConfigView.section.irc=IRC-yhteys
+ConfigView.label.ircwiki=Muista lukea s\u00e4\u00e4nn\u00f6t osoitteesta http://wiki.vuze.com/w/Rules_for_IRC
+ConfigView.label.ircserver=Palvelin
+ConfigView.label.ircchannel=Kanava 
+ConfigView.label.irclogin=Nimimerkki 
+ConfigView.group.irctitle=IRC (reaaliaikainen tekninen tuki)
+ConfigView.boolean.ircsendinfo=Salli ongelmatilanteissa asetusten l\u00e4hett\u00e4minen (anonyymisti) kanavien yll\u00e4pit\u00e4jille
+ConfigView.boolean.irclog=Kirjaa kanavien tapahtumat lokitiedostoon (IRC_log.htm Vuzen asennushakemistossa)
+ConfigView.section.security=Suojaus
+ConfigView.label.password=Suojaa Vuzen k\u00e4ytt\u00f6\u00e4 salasanalla\n - kysyt\u00e4\u00e4n k\u00e4ynnistett\u00e4ess\u00e4 ja ilmoitusalueelta palautettaessa
+ConfigView.label.passwordconfirm=Salasana uudelleen
+ConfigView.label.passwordmatch=Salasanasuojaus k\u00e4yt\u00f6ss\u00e4: 
+ConfigView.label.passwordmatchnone=Ei 
+ConfigView.label.passwordmatchno=Ei - salasanat eiv\u00e4t t\u00e4sm\u00e4\u00e4 
+ConfigView.label.passwordmatchyes=Kyll\u00e4 
+ConfigView.button.save=Tallenna 
+ConfigView.title.short=Asetukset 
+ConfigView.title.full=Asetukset 
+ConfigView.title.full._mac=Asetukset
+ConsoleView.title.short=Konsoli 
+ConsoleView.title.full=Konsoli 
+FileItem.write=Kirjoitus
+FileItem.read=Luku
+FileItem.normal=Normaali 
+FileItem.high=Korkea 
+FileItem.donotdownload=Ei ladata 
+FileItem.delete=Poista
+FilesView.name=Nimi
+FilesView.name.fastRename=Nopea uudelleennime\u00e4minen
+FilesView.size=Koko
+FilesView.done=Ladattu
+FilesView.%=Valmiina
+FilesView.firstpiece=Ensimm\u00e4inen osa
+FilesView.numberofpieces=Osien lkm
+FilesView.pieces=Osat
+FilesView.mode=Tila
+FilesView.priority=Prioriteetti
+FilesView.menu.open=&Avaa 
+FilesView.menu.setpriority=Aseta &prioriteetti 
+FilesView.menu.setpriority.high=&Korkea 
+FilesView.menu.setpriority.normal=&Normaali 
+FilesView.menu.setpriority.skipped=&\u00c4l\u00e4 lataa 
+FilesView.title.short=Tiedostot 
+FilesView.title.full=Tiedostot 
+GeneralView.section.downloaded=Ladattu
+GeneralView.label.status.file=Tiedoston tila 
+GeneralView.label.status.pieces=Osien tila 
+GeneralView.section.availability=Saatavuus 
+GeneralView.label.status.pieces_available=Osien tila 
+GeneralView.section.transfer=Siirrot 
+GeneralView.section.info=Torrent-tiedosto
+GeneralView.title.short=Yleiset 
+GeneralView.title.full=Yleiset 
+GeneralView.label.timeelapsed=Aikaa kulunut: 
+GeneralView.label.remaining=J\u00e4ljell\u00e4: 
+GeneralView.label.downloaded=Ladattu: 
+GeneralView.label.downloadspeed=Latausnopeus: 
+GeneralView.label.maxuploads=L\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4: 
+GeneralView.label.maxuploads.tooltip=Lataajien enimm\u00e4ism\u00e4\u00e4r\u00e4, joille l\u00e4hetet\u00e4\u00e4n tietoa yht\u00e4aikaisesti.
+GeneralView.label.uploaded=L\u00e4hetetty: 
+GeneralView.label.uploadspeed=L\u00e4hetysnopeus: 
+GeneralView.label.seeds=L\u00e4hteit\u00e4: 
+GeneralView.label.peers=Lataajia: 
+GeneralView.label.completed=Valmiit:
+GeneralView.label.totalspeed=Nopeus yhteens\u00e4: 
+GeneralView.label.totalspeed.tooltip=Kaikkien yhdistettyjen k\u00e4ytt\u00e4jien nopeus yhteens\u00e4 ja keskim\u00e4\u00e4rin.
+GeneralView.label.averagespeed=keskim\u00e4\u00e4rin
+GeneralView.label.filename=Nimi: 
+GeneralView.label.totalsize=Koko yhteens\u00e4: 
+GeneralView.label.savein=Tallennushakemisto: 
+GeneralView.label.hash=Tiiviste: 
+GeneralView.label.numberofpieces=Osien m\u00e4\u00e4r\u00e4: 
+GeneralView.label.size=Osan koko: 
+GeneralView.label.tracker=Seurantapalvelimen tila: 
+GeneralView.label.updatein=Aikaa p\u00e4ivitykseen: 
+GeneralView.label.trackerurl=Seurantapalvelimen osoite: 
+GeneralView.label.trackerurlupdate=Tee p\u00e4ivitys 
+GeneralView.label.comment=Kommentti: 
+GeneralView.label.user_comment=Oma kommentti:
+GeneralView.label.status=Tila:
+ManagerItem.waiting=Odotetaan 
+ManagerItem.allocating=Varataan tilaa
+ManagerItem.checking=Tarkastetaan 
+ManagerItem.ready=Odotetaan muita torrent-tiedostoja
+ManagerItem.downloading=Ladataan 
+ManagerItem.seeding=L\u00e4hetet\u00e4\u00e4n 
+ManagerItem.stopped=Pys\u00e4ytetty 
+ManagerItem.error=Virhe 
+ManagerItem.high=Korkea 
+ManagerItem.low=Alhainen 
+MinimizedWindow.name=Nimi: 
+MinimizedWindow.all_transfers=Kaikki siirrot
+PiecesView.size=Koko
+PiecesView.numberofblocks=Lohkojen lkm
+PiecesView.blocks=Lohkot
+PiecesView.completed=Valmiina
+PiecesView.availability=Saatavuus
+PiecesView.reservedby=Varattu
+PiecesView.writers=Lohkojen l\u00e4hett\u00e4j\u00e4t
+PiecesView.title.short=Osat 
+PiecesView.title.full=Osat 
+SystemTray.tooltip.seeding=%1 l\u00e4hetet\u00e4\u00e4n, 
+SystemTray.tooltip.downloading=%1 ladataan, 
+DownloadManager.error.filenotfound=Tiedostoa ei l\u00f6ytynyt 
+DownloadManager.error.fileempty=Torrent-tiedosto tyhj\u00e4 
+DownloadManager.error.filetoobig=Torrent-tiedosto liian suuri
+DownloadManager.error.filewithouttorrentinfo=Torrent-tietoja ei l\u00f6ydy tiedostosta 
+DownloadManager.error.unsupportedencoding=Koodausta ei tueta
+DownloadManager.error.ioerror=Siirr\u00e4nt\u00e4virhe 
+DownloadManager.error.sha1=Algoritmi ei k\u00e4ytett\u00e4viss\u00e4 (SHA1)
+PeerManager.status.offline=Yhteysvirhe
+PeerManager.status.ok=OK 
+PeerManager.status.checking=Tarkastetaan 
+PeerManager.status.finished=Valmis 
+PeerManager.status.finishedin=Valmis, aikaa kului 
+MainWindow.upgrade.assistant=P\u00e4ivitysavustaja 
+MainWindow.upgrade.newerversion=Uudempi versio Vuzesta on ladattavissa 
+MainWindow.upgrade.explanation=T\u00e4m\u00e4 avustaja lataa ohjelman uuden version Vuzen asennushakemistoon ja k\u00e4ynnist\u00e4\u00e4 Vuzen uudelleen 
+MainWindow.upgrade.explanation.manual=Voit suorittaa p\u00e4ivityksen my\u00f6s manuaalisesti sulkemalla Vuzen, lataamalla uudemman .jar-version, \nkopioimalla sen Vuzen asennushakemistoosi ja k\u00e4ynnist\u00e4m\u00e4ll\u00e4 Vuzen uudestaan 
+MainWindow.upgrade.step1=Vaihe 1: Uusi versio ladataan 
+MainWindow.upgrade.step2=Vaihe 2: Vuze k\u00e4ynnistet\u00e4\u00e4n uudelleen, p\u00e4ivitys on suoritettu 
+MainWindow.upgrade.hint1=Vihje:\tPainamalla Valmis kaikki tapahtuu automaattisesti 
+MainWindow.upgrade.hint2=Vihje:\tJos haluat sulkea Vuzen my\u00f6hemmin, paina nyt Peruuta ja\n\tuudelleennime\u00e4 Azureus2-new.jar Azureus2.jar:ksi my\u00f6hemmin sulkemisen j\u00e4lkeen 
+MainWindow.upgrade.error.downloading.hint=Virhe:\tUutta versiota ei pystytty lataamaan, p\u00e4ivit\u00e4 manuaalisesti 
+MainWindow.upgrade.section.info=Uusi versio saatavilla 
+MainWindow.upgrade.section.manual=Manuaalinen p\u00e4ivitys 
+MainWindow.upgrade.section.automatic=Automaattinen p\u00e4ivitys 
+MainWindow.upgrade.tooltip.progressbar=T\u00e4st\u00e4 n\u00e4et latauksen edistymisen 
+Button.next=Seuraava 
+Button.finish=Valmis 
+Button.cancel=&Peruuta 
+LocaleUtil.title=Valitse tiedoston koodaus 
+LocaleUtil.section.chooseencoding=Valitse koodaus tiedostonimelle
+LocaleUtil.label.chooseencoding=Valitse parhaiten sopiva koodaus:
+LocaleUtil.label.hint.doubleclick=Vihje: tuplaklikkaus rivill\u00e4 valitsee koodauksen ja sulkee ikkunan.
+LocaleUtil.label.checkbox.rememberdecision=K\u00e4yt\u00e4 samaa koodausta kaikille tiedostoille
+LocaleUtil.column.encoding=Koodaus 
+IrcClient.copyright=K\u00e4yt\u00f6ss\u00e4 PircBot Java IRC API - http://www.jibble.org/pircbot.php 
+IrcClient.connecting=Yhdistet\u00e4\u00e4n palvelimeen
+IrcClient.connected=Yhdistetty palvelimeen
+IrcClient.joining=Liityt\u00e4\u00e4n kanavalle 
+IrcClient.channel=Liitytty 
+IrcClient.joined=-kanavalle 
+IrcClient.error=Virhe 
+IrcClient.hasjoined=liittyi kanavalle 
+IrcClient.haskicked=poisti kanavalta k\u00e4ytt\u00e4j\u00e4n 
+IrcClient.hasleft=poistui kanavalta 
+IrcClient.nowknown=on nyt nimelt\u00e4\u00e4n 
+IrcClient.topicforchannel=Kanavan otsikko on: 
+IrcClient.disconnected=Yhteys katkesi palvelimeen
+IrcClient.noNick=Nimimerkki\u00e4 ei ole m\u00e4\u00e4ritelty. Aseta nimimerkkisi Asetuksissa kohdassa Lis\u00e4osat | IRC-yhteys. 
+IrcView.actionnotsupported=T\u00e4m\u00e4 komento ei ole k\u00e4ytett\u00e4viss\u00e4
+IrcView.clientsconnected=k\u00e4ytt\u00e4j\u00e4\u00e4 
+IrcView.privateto=K\u00e4ytt\u00e4j\u00e4lle 
+IrcView.privatefrom=K\u00e4ytt\u00e4j\u00e4lt\u00e4 
+IrcView.noticefrom=Tiedotus: 
+IrcView.errormsg=Virheellinen komento /msg : /msg k\u00e4ytt\u00e4j\u00e4 viesti
+IrcView.help=Toimivia komentoja ovat:\n . /help : n\u00e4ytt\u00e4\u00e4 t\u00e4m\u00e4n ohjeen\n . /nick | /name uusi_nimi : vaihtaa nimimerkkisi\n . /me toiminto : l\u00e4hett\u00e4\u00e4 toiminnon (mit\u00e4 olet tekem\u00e4ss\u00e4)\n . /msg k\u00e4ytt\u00e4j\u00e4 viesti : l\u00e4hett\u00e4\u00e4 yksityisviestin m\u00e4\u00e4ritetylle k\u00e4ytt\u00e4j\u00e4lle\n . /r viesti : vastaa viimeisimp\u00e4\u00e4n yksityisviestiin\n . /join #kanava : vaihtaa m\u00e4\u00e4ritetylle kanavalle 
+PasswordWindow.title=Vuze lukittu 
+PasswordWindow.passwordprotected=Vuze on salasanasuojatussa tilassa.\nJotta voisit k\u00e4ytt\u00e4\u00e4 Vuzea, anna salasana:
+PeersView.discarded=Hyl\u00e4tty
+PeersView.discarded.info=Ladattu tietom\u00e4\u00e4r\u00e4, jota ei tarvita.
+discarded=hyl\u00e4tty 
+MyTorrentsView.menu.move=Sii&rr\u00e4 
+MyTorrentsView.menu.moveUp=&Yl\u00f6s 
+MyTorrentsView.menu.moveDown=&Alas 
+GeneralView.label.hashfails=Korruptoituneet osat: 
+GeneralView.label.shareRatio=Jakosuhde: 
+ConfigView.section.downloadManagement=Latausten hallinta 
+ConfigView.label.startRatioPeers=Aloita l\u00e4hett\u00e4minen, kun on v\u00e4hemm\u00e4n kuin yksi l\u00e4hde kohti
+ConfigView.text.neverStop=Ei koskaan 
+ConfigView.text.neverStart=Ei koskaan 
+ConfigView.text.peers=lataajaa
+ConfigView.label.checkOncompletion=Tarkasta osat uudelleen, kun lataus on valmistunut
+wizard.title=Luo torrent-tiedosto 
+wizard.previous=Edellinen
+wizard.next=Seuraava
+wizard.finish=Valmis 
+wizard.mode=Seurantapalvelin/kohteen muoto 
+wizard.tracker=Seurantapalvelin: 
+wizard.invalidurl=Antamasi osoite ei ole kelvollinen.
+wizard.singlefile=Yksitt\u00e4inen tiedosto 
+wizard.singlefile.help=Luo torrent-tiedosto yksitt\u00e4isest\u00e4 tiedostosta 
+wizard.directory=Hakemisto 
+wizard.directory.help=Luo torrent-tiedosto hakemistosta 
+wizard.choosefile=Valitse tiedosto 
+wizard.file=Tiedosto 
+wizard.browse=Selaa... 
+wizard.choosedirectory=Valitse hakemisto 
+wizard.invalidfile=Kelpaamaton tiedosto! 
+wizard.invaliddirectory=Kelpaamaton hakemisto! 
+wizard.torrentFile=Torrent-tiedosto 
+wizard.choosetorrent=Valitse luotavan torrent-tiedoston asetukset
+wizard.information=Info 
+wizard.notimplemented=Ei viel\u00e4 toteutettu 
+wizard.progresstitle=Luodaan torrent-tiedostoa 
+wizard.savingfile=Tallennetaan torrent-tiedostoa... 
+wizard.filesaved=Torrent-tiedosto tallennettu. 
+wizard.close=Sulje 
+Torrent.create.progress.piecelength=Osan koko: 
+Torrent.create.progress.piececount=Osien lukum\u00e4\u00e4r\u00e4: 
+Torrent.create.progress.totalfilesize=Koko yhteens\u00e4: 
+Torrent.create.progress.totalfilecount=Tiedostojen m\u00e4\u00e4r\u00e4 yhteens\u00e4: 
+Torrent.create.progress.parsingfiles=J\u00e4sennell\u00e4\u00e4n tiedostoja
+Torrent.create.progress.hashing=Lasketaan tiedostoille tiivisteet
+MainWindow.upgrade.downloadingfrom=Ladataan kohteesta: 
+MainWindow.menu.view.ipFilter=&IP-suotimet
+ConfigView.section.ipfilter=IP-suotimet
+ConfigView.section.ipfilter.description=Kuvaus
+ConfigView.section.ipfilter.start=Ensimm\u00e4inen IP-osoite
+ConfigView.section.ipfilter.end=Viimeinen IP-osoite
+ConfigView.section.ipfilter.add=Lis\u00e4\u00e4
+ConfigView.section.ipfilter.remove=Poista
+ConfigView.section.ipfilter.edit=Muokkaa
+ConfigView.section.ipfilter.save=Tallenna
+ConfigView.section.ipfilter.editFilter=Muokkaa suodinta
+ConfigView.section.ipfilter.enable=IP-suotimet k\u00e4yt\u00f6ss\u00e4
+PeersView.menu.close=&Sulje 
+seedmore.title=Jakosuhde alhainen
+seedmore.shareratio=T\u00e4m\u00e4n torrent-tiedoston jakosuhde on 
+seedmore.uploadmore=Alle 100 %:n jakosuhde ei ole hyv\u00e4ksi BitTorrent-verkolle.\nOn suositeltavaa, ett\u00e4 l\u00e4hett\u00e4mist\u00e4 jatkettaisiin pidemp\u00e4\u00e4n.\nHaluatko varmasti jatkaa? 
+ConfigView.label.showpopuponclose=Pyyd\u00e4 l\u00e4hett\u00e4mist\u00e4 lopetettaessa vahvistus, jos jakosuhde on pienempi kuin 1.0
+ConfigView.label.startNumSeeds=Aloita l\u00e4hett\u00e4minen, jos on v\u00e4hemm\u00e4n kuin\n - ohittaa kaikki muut s\u00e4\u00e4nn\u00f6t
+ConfigView.label.seeds=l\u00e4hett\u00e4j\u00e4\u00e4 
+ConfigView.section.seeding=Tiedostojen l\u00e4hett\u00e4minen 
+#Used by the webui plugin
+#Used by the webui plugin
+#Used by the webui plugin
+deletedata.title=Varoitus! 
+# used for more than just "delete data"
+deletedata.noprompt=\u00c4l\u00e4 kysy t\u00e4t\u00e4 uudelleen
+MainWindow.menu.file.configure=&Ohjattu asetusten m\u00e4\u00e4rittely...
+configureWizard.title=Ohjattu asetusten m\u00e4\u00e4rittely 
+configureWizard.welcome.title=Tervetuloa ohjattuun asetusten m\u00e4\u00e4rittelyyn
+configureWizard.welcome.message=T\u00e4m\u00e4 ohjattu toiminto auttaa sinua asettamaan Vuzen t\u00e4rkeimm\u00e4t asetukset k\u00e4ytt\u00f6kuntoon. Voit muokata asetuksia my\u00f6hemmin tarkemmin valitsemalla Ty\u00f6kalut-valikosta Asetukset. 
+configureWizard.transfer.title=Yhteysasetukset 
+configureWizard.transfer.hint=Vihje: \u00c4l\u00e4 k\u00e4yt\u00e4 t\u00e4ytt\u00e4 l\u00e4hetyskapasiteettia (hidastaa latauksia).
+configureWizard.transfer.message=Valitse alta yhteysasetuksesi. Muista, ett\u00e4 pieni l\u00e4hetysnopeus johtaa samalla pieniin latausnopeuksiin. Samoin voi k\u00e4yd\u00e4, jos lataat liian montaa torrent-tiedostoa yht\u00e4aikaisesti (jolloin torrent-kohtainen l\u00e4hetysnopeus j\u00e4\u00e4 pieneksi). Suositus ehdottomaksi l\u00e4hetysnopeuden alarajaksi on 5 KB/s (yht\u00e4 torrent-tiedostoa kohti). Eli yleisesti: mit\u00e4 nopeammin l\u00e4het\u00e4t, sit\u00e4 nopeammin lataat ( [...]
+configureWizard.transfer.connection=Yhteystyyppi 
+configureWizard.transfer.connection.0=Mukautettu
+configureWizard.transfer.connection.1=Modeemi
+configureWizard.transfer.connection.2=Laajakaista x/128 kbps
+configureWizard.transfer.connection.3=Laajakaista x/256 kbps
+configureWizard.transfer.connection.4=Laajakaista x/384 kbps
+configureWizard.transfer.connection.5=Laajakaista x/512 kbps
+configureWizard.transfer.connection.6=Laajakaista x/768 kbps
+configureWizard.transfer.connection.7=Laajakaista x/1024 kbps
+configureWizard.transfer.maxUpSpeed=Enimm\u00e4isl\u00e4hetysnopeus 
+configureWizard.transfer.maxActiveTorrents=Aktiivisten torrent-tiedostojen enimm\u00e4ism\u00e4\u00e4r\u00e4 
+configureWizard.transfer.maxDownloads=Yht\u00e4aikaisten latausten enimm\u00e4ism\u00e4\u00e4r\u00e4
+configureWizard.transfer.maxUploadsPerTorrent=L\u00e4hetyspaikkojen enimm\u00e4ism\u00e4\u00e4r\u00e4/torrent
+configureWizard.nat.test=Testaa 
+configureWizard.nat.testing=Testataan porttia
+configureWizard.nat.ok=OK 
+configureWizard.nat.ko=NAT-ongelma havaittu
+configureWizard.nat.unable=Testausta ei voitu suorittaa: joko...\n - porttinumero on virheellinen\n - tai porttia ei voitu k\u00e4ytt\u00e4\u00e4 (toinen sovellus ehk\u00e4 jo k\u00e4ytt\u00e4\u00e4 ko. porttia)
+configureWizard.file.title=Torrent-tiedostot ja nopea latauksen jatkaminen
+configureWizard.file.message1=Vuze tallentaa avatut torrent-tiedostot (luo kopiot) seuraavaan hakemistoon: 
+configureWizard.file.path=Tallennushakemisto
+configureWizard.file.browse=Selaa... 
+configureWizard.file.message2=Vuze voi jatkaa tiedostojen lataamista v\u00e4litt\u00f6m\u00e4sti lis\u00e4\u00e4m\u00e4ll\u00e4 t\u00e4h\u00e4n toimintoon liittyvi\u00e4 tietoja torrent-tiedostoihin (huomattavasti nopeampaa, kuin jos ladatut osat k\u00e4yt\u00e4isiin yksitellen l\u00e4pi jatkettaessa lataamista). T\u00e4ll\u00e4 menetelm\u00e4ll\u00e4 Vuze osaa my\u00f6s jatkaa yksitt\u00e4isten osien lataamista, jotka ovat j\u00e4\u00e4neet kesken. 
+configureWizard.file.fastResume=K\u00e4yt\u00e4 nopeaa latauksen jatkamista 
+configureWizard.file.invalidPath=Kelpaamaton hakemisto!
+configureWizard.finish.title=Ohjattu asetusten m\u00e4\u00e4rittely suoritettu loppuun 
+configureWizard.finish.message=Vuzen v\u00e4ltt\u00e4m\u00e4tt\u00f6mimm\u00e4t perusasetukset ovat nyt asetettu ja Vuze on k\u00e4ytt\u00f6kunnossa.\n\nMuista, ett\u00e4 voit palata Ohjattuun asetusten m\u00e4\u00e4rittelyyn milloin tahansa k\u00e4ynnist\u00e4m\u00e4ll\u00e4 sen Ty\u00f6kalut-valikosta. Yksityiskohtaisempia asetuksia voit tarkastella valitsemalla Asetukset samaisesta valikosta.
+wizard.close.confirmation=Vahvistus 
+wizard.close.message=Haluatko, ett\u00e4 t\u00e4m\u00e4 asetustenm\u00e4\u00e4rittelytoiminto n\u00e4ytet\u00e4\u00e4n ensi kerralla, kun Vuze k\u00e4ynnistet\u00e4\u00e4n? 
+exportTorrentWizard.title=Vie torrent-tiedosto XML-muotoon
+exportTorrentWizard.torrentfile.title=K\u00e4sitelt\u00e4v\u00e4n torrent-tiedoston valitseminen 
+exportTorrentWizard.torrentfile.message=Valitse viet\u00e4v\u00e4 torrent-tiedosto 
+exportTorrentWizard.torrentfile.path=Kohde
+exportTorrentWizard.torrentfile.browse=Selaa... 
+exportTorrentWizard.torrentfile.invalidPath=Kelpaamaton torrent-tiedosto 
+exportTorrentWizard.exportfile.title=Kohdetiedoston valitseminen 
+exportTorrentWizard.exportfile.message=Anna luotavalle XML-tiedostolle nimi ja sijainti 
+exportTorrentWizard.exportfile.path=Kohde
+exportTorrentWizard.exportfile.browse=Selaa... 
+exportTorrentWizard.exportfile.invalidPath=Kelpaamaton kohdetiedosto 
+exportTorrentWizard.finish.title=Torrent-tiedoston vienti suoritettu loppuun 
+exportTorrentWizard.finish.message=XML-tiedosto luotiin onnistuneesti.
+exportTorrentWizard.process.inputfilebad.title=Torrent-tiedosto on virheellinen 
+exportTorrentWizard.process.inputfilebad.message=L\u00e4hdetiedostoa k\u00e4sitelt\u00e4ess\u00e4 tapahtui virhe: 
+exportTorrentWizard.process.outputfileexists.title=Tiedosto jo olemassa 
+exportTorrentWizard.process.outputfileexists.message=Kohdetiedosto on jo olemassa, korvataanko?
+exportTorrentWizard.process.torrentfail.title=Torrent-tiedostosta ei voida lukea tietoja 
+exportTorrentWizard.process.exportfail.title=Torrent-tiedoston vieminen ei onnistu 
+exportTorrentWizard.process.unknownfail.title=Tuntematon virhe 
+importTorrentWizard.title=Tuo torrent-tiedosto XML-muodosta
+importTorrentWizard.torrentfile.title=Kohdetiedoston valitseminen 
+importTorrentWizard.torrentfile.message=Anna luotavalle torrent-tiedostolle nimi ja sijainti 
+importTorrentWizard.torrentfile.path=Kohde
+importTorrentWizard.torrentfile.browse=Selaa... 
+importTorrentWizard.torrentfile.invalidPath=Kelpaamaton torrent-tiedosto 
+importTorrentWizard.importfile.title=K\u00e4sitelt\u00e4v\u00e4n XML-tiedoston valitseminen 
+importTorrentWizard.importfile.message=Valitse tuotava XML-tiedosto 
+importTorrentWizard.importfile.path=Kohde
+importTorrentWizard.importfile.browse=Selaa... 
+importTorrentWizard.importfile.invalidPath=Kelpaamaton l\u00e4hdetiedosto 
+importTorrentWizard.finish.title=Torrent-tiedoston tuonti suoritettu loppuun 
+importTorrentWizard.finish.message=Torrent-tiedosto luotiin onnistuneesti 
+importTorrentWizard.process.inputfilebad.title=XML-tiedosto on virheellinen 
+importTorrentWizard.process.inputfilebad.message=L\u00e4hdetiedostoa k\u00e4sitelt\u00e4ess\u00e4 tapahtui virhe: 
+importTorrentWizard.process.outputfileexists.title=Tiedosto jo olemassa 
+importTorrentWizard.process.outputfileexists.message=Kohdetiedosto on jo olemassa, korvataanko? 
+importTorrentWizard.process.torrentfail.title=Torrent-tiedoston luominen ei onnistu 
+importTorrentWizard.process.importfail.title=Torrent-tiedoston tuominen ei onnistu 
+importTorrentWizard.process.unknownfail.title=Tuntematon virhe 
+ConfigView.label.bindip=Sido paikalliseen IP-osoitteeseen tai liit\u00e4nt\u00e4\u00e4n
+ConfigView.label.xfs.allocation=Varaa levytilaa k\u00e4ytt\u00e4m\u00e4ll\u00e4 XFS-tiedostoj\u00e4rjestelm\u00e4n varaustapaa
+ConfigView.label.xfs.allocation.tooltip=Varmista, ett\u00e4 tiedosto /usr/sbin/xfs_io l\u00f6ytyy j\u00e4rjestelm\u00e4st\u00e4. Useimmissa Linux-jakeluversioissa ko. tiedosto asentuu xfsprogs-paketin mukana.
+xfs.allocation.xfs_io.not.found=XFS-levytilanvaraus ep\u00e4onnistui, sill\u00e4 tiedostoa /usr/sbin/xfs_io ei voitu suorittaa. Varmista, ett\u00e4 se l\u00f6ytyy j\u00e4rjestelm\u00e4st\u00e4si. Alkuper\u00e4inen virhe oli: "%1".
+ConfigView.label.zeronewfiles=Varaa levytilaa tiedostojen valmiin koon verran t\u00e4ytt\u00e4m\u00e4ll\u00e4 tila nollilla
+ConfigView.label.zeronewfiles.tooltip=V\u00e4hent\u00e4\u00e4 kiintolevyn sis\u00e4ll\u00f6n pirstoutumista.
+ConfigView.section.stats=Tilastot 
+ConfigView.section.stats.enable=Tilastointitoiminto k\u00e4yt\u00f6ss\u00e4 
+ConfigView.section.stats.defaultsavepath=Tallennushakemisto 
+ConfigView.section.stats.choosedefaultsavepath=Valitse tallennushakemisto tilastoille 
+ConfigView.section.stats.savefreq=Tallennuksen aikav\u00e4li 
+ConfigView.section.stats.hours=h 
+ConfigView.section.stats.seconds=s
+ConfigView.section.stats.savefile=Tiedostonimi 
+ConfigView.section.stats.graph_update_dividers=N\u00e4yt\u00e4 pystysuuntainen ositusviiva aina 60 p\u00e4ivityksen v\u00e4lein
+MyTorrentsView.menu.export=&XML-muotoon...
+MyTorrentsView.menu.host=Aseta &seurantaan
+ManagerItem.finishing=Viimeistell\u00e4\u00e4n 
+ConfigView.dialog.choosedefaulttorrentpath=Valitse tallennushakemisto torrent-tiedostoille 
+ConfigView.dialog.choosemovepath=Valitse hakemisto, johon siirret\u00e4\u00e4n 
+ConfigView.label.movecompleted=Siirr\u00e4 valmistuneet tiedostot (latauksen j\u00e4lkeen)
+ConfigView.label.moveremoved=Siirr\u00e4 valmistuneet tiedostot (poistettaessa)
+ConfigView.label.savetorrents=Tallenna torrent-tiedostot 
+MainWindow.menu.view.mytracker=Seuranta&palvelin
+MyTrackerView.title.full=Seurantapalvelin
+MyTrackerView.name=Nimi
+MyTrackerView.tracker=Seurantapalvelin
+MyTrackerView.status=Tila
+MyTrackerView.status.started=Seurataan
+MyTrackerView.status.stopped=Pys\u00e4ytetty 
+MyTrackerView.peers=Lataajat
+MyTrackerView.seeds=L\u00e4hteet
+MyTrackerView.announces=P\u00e4ivitykset
+MyTrackerView.uploaded=L\u00e4hetetty
+MyTrackerView.downloaded=Ladattu
+MyTrackerView.left=J\u00e4ljell\u00e4
+ConfigView.section.style=K\u00e4ytt\u00f6liittym\u00e4
+ConfigView.label.set_ui_transfer_speeds=Ohita valittavat siirtonopeusrajoitukset
+ConfigView.label.set_ui_transfer_speeds.description=Voit asettaa manuaalisesti tilarivin ja ilmoitusalueen valikoista valittavissa olevat lataus- ja l\u00e4hetysnopeusrajoitusarvot.\nErota arvot toisistaan pilkulla.
+ConfigView.label.set_ui_transfer_speeds.description.download=Aseta arvot latausnopeudelle (KB/s)
+ConfigView.label.set_ui_transfer_speeds.description.upload=Aseta arvot l\u00e4hetysnopeudelle (KB/s)
+ConfigView.section.style.useCustomTabs=K\u00e4yt\u00e4 suljettavia v\u00e4lilehti\u00e4 (vaatii uudelleenk\u00e4ynnistyksen)
+MainWindow.menu.view.plugins=&Lis\u00e4osat
+fileDownloadWindow.saveTorrentIn=Tallenna torrent-tiedosto hakemistoon
+fileDownloadWindow.title=Torrent-tiedoston lataaminen
+fileDownloadWindow.downloading=Ladataan kohdetta:
+fileDownloadWindow.status=Tila:
+fileDownloadWindow.state_initializing=Aloitetaan
+fileDownloadWindow.state_downloading=Ladataan
+fileDownloadWindow.state_error=Virhe:
+MainWindow.menu.file.open.url=Torrent-tiedosto &URL-osoitteesta...
+MainWindow.menu.file.open.url.keybinding=Meta+U
+openUrl.title=Avaa torrent-tiedosto osoitteesta
+openUrl.url=URL-osoite:
+MyTorrentsView.menu.host.error.title=Seurantaan asettaminen ep\u00e4onnistui
+MyTorrentsView.menu.host.error.message=Seuraava virhe esiintyi asetettaessa torrent-tiedostoa seurantaan
+ConfigView.section.tracker=Seuranta
+ConfigView.section.tracker.pollinterval=Tietojen kysymisen aikav\u00e4li sekunneissa
+ConfigView.section.tracker.publishenable=N\u00e4yt\u00e4 seurattavat/julkistetut torrent-tiedostot www-sivulla seurantapalvelimen URL-osoitteessa
+ConfigView.section.tracker.ip=Seurantapalvelimen ulkoinen IP-osoite
+ConfigView.section.style.enableXPStyle=K\u00e4yt\u00e4 Windows XP -tyyli\u00e4 (vaatii uudelleenk\u00e4ynnistyksen)
+IPChecker.external.service.dyndns.url=http://www.dyndns.org
+IPChecker.external.service.dyndns.description=Dynamic DNS Network Services, LLC.
+ConfigView.section.tracker.checkip=Hae osoite automaattisesti...
+ipCheckerWizard.title=IP-osoitteen tarkastaminen
+ipCheckerWizard.service=Palvelu
+ipCheckerWizard.chooseService=Valitse palvelu, jonka avulla IP-osoite tarkastetaan.
+ipCheckerWizard.explanations=T\u00e4m\u00e4n toiminnon avulla voit selvitt\u00e4\u00e4 ulkoisen IP-osoitteesi, jota tarvitaan oman seurantapalvelimen k\u00e4ytt\u00e4misess\u00e4.\n\nJos IP-osoitteesi on dynaaminen (vaihtuva), on suositeltavaa k\u00e4ytt\u00e4\u00e4 dynaamisen tuen tarjoavaa verkkotunnusj\u00e4rjestelm\u00e4palvelua. Muutamia t\u00e4llaisia palveluja on listattu alla, k\u00e4y rekister\u00f6itym\u00e4ss\u00e4 johonkin niist\u00e4 (jos kyseinen palvelu mahdollistaa t\u00e [...]
+ipCheckerWizard.service.description=Kuvaus:
+ipCheckerWizard.service.url=Sivusto:
+ipCheckerWizard.progresstitle=Tarkastetaan IP-osoitetta
+ipCheckerWizard.checkComplete=K\u00e4ytett\u00e4v\u00e4 IP-osoite: 
+ipCheckerWizard.checkFailed=Tarkastus ep\u00e4onnistui, syy:
+wizard.tracker.local=Vuzen oma sis\u00e4inen seurantapalvelin
+wizard.tracker.external=Ulkoinen seurantapalvelin
+wizard.tracker.howToLocal=\tVaatii k\u00e4ytt\u00f6\u00f6noton asetuksista!
+wizard.announceUrl=P\u00e4ivitysosoite:
+IPChecker.external.service.discoveryvip.url=http://ip.discoveryvip.com
+IPChecker.external.service.discoveryvip.description=Ainoastaan IP-osoitteen tarkastus.
+IPChecker.external.httpinvalidresponse=Virheellinen HTTP-vastaus
+IPChecker.external.loadingwebpage=Ladataan sivua
+IPChecker.external.analysingresponse=Analysoidaan vastausta
+IPChecker.external.addressextracted=Selvitetty IP-osoite
+IPChecker.external.httploadfail=Sivua ei voitu ladata
+IPChecker.external.timeout=Pyynt\u00f6 aikakatkaistiin
+IPChecker.external.ipnotfound=IP-osoitetta ei l\u00f6ytynyt
+ConfigView.section.tracker.pollintervalmin=V\u00e4himm\u00e4isaika
+ConfigView.section.tracker.pollintervalmax=Enimm\u00e4isaika
+ConfigView.section.tracker.pollintervalincby=Kasvata aikaa
+ConfigView.section.tracker.pollintervalincper=sekunnilla n\u00e4in monen k\u00e4ytt\u00e4j\u00e4n j\u00e4lkeen
+splash.loadingImages=Ladataan kuvia
+splash.initializeGui=Alustetaan graafista k\u00e4ytt\u00f6liittym\u00e4\u00e4
+splash.openViews=Avataan v\u00e4lilehti\u00e4
+splash.plugin=Ladataan lis\u00e4osaa -
+configureWizard.nat.tooManyPorts=Liian monta testattavaa porttia (enint\u00e4\u00e4n 9)
+ConfigView.section.color=V\u00e4riteema
+MyTorrentsView.menu.publish=&Julkaise
+MyTrackerView.status.published=Julkistettu
+MyTrackerView.completed=Valmiina
+MainWindow.menu.file.open.torrentnodefault=Torrent-tiedosto... (m\u00e4\u00e4rit\u00e4 lataushakemisto)
+wizard.comment=Kommentti
+ConfigView.label.movetorrent=Siirr\u00e4 torrent-tiedosto
+ConfigView.label.movepartialdownloads=Siirr\u00e4, vaikka tiedoston tila olisikin "Ei ladata"
+ConfigView.label.subdir_is_in_default=Siirrett\u00e4ess\u00e4 tiedostoja oletustallennushakemistosta siirr\u00e4 my\u00f6s sen alihakemistojen tiedostot
+ConfigView.section.file.decoder.label=Kysytt\u00e4ess\u00e4 torrent-tiedoston koodausta k\u00e4yt\u00e4 oletuksena
+ConfigView.section.file.decoder.nodecoder=Ei mit\u00e4\u00e4n
+IPChecker.external.service.no-ip.url=http://www.no-ip.com
+IPChecker.external.service.no-ip.description=Dynaamisen ja staattisen tuen tarjoava DNS-palvelu\n(ei IP-osoitteen tarkastusta ilmaiseksi).
+ConfigView.section.tracker.publicenable=Salli ulkoiset torrent-tiedostot
+ConfigView.label.playdownloadspeech=Ilmoita puhuen latauksen valmistumisesta
+#
+# Tooltips
+#
+GeneralView.label.status.pieces_available.tooltip=Kuvastaa osien saatavilla olevien kopioiden m\u00e4\u00e4r\u00e4\u00e4 k\u00e4ytt\u00e4jien keskuudessa.\nJos oikealla oleva luku on alle yhden, kaikkia osia eli tiedosto(j)a kokonaisena ei ole saatavilla.
+GeneralView.label.trackerurl.tooltip=Klikkaa kopioidaksesi seurantapalvelimen p\u00e4ivitysosoite leikep\u00f6yd\u00e4lle.
+GeneralView.label.trackerurlopen.tooltip=Klikkaa avataksesi seurantapalvelimen etusivu.
+#
+# 2.0.4.4
+#
+ConfigView.section.style.guiUpdate=P\u00e4ivit\u00e4 graafinen k\u00e4ytt\u00f6liittym\u00e4 (GUI) joka
+ConfigView.section.style.inactiveUpdate=P\u00e4ivit\u00e4 toimeton p\u00e4\u00e4ikkuna n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen
+ConfigView.section.style.graphicsUpdate=P\u00e4ivit\u00e4 graafiset palkit n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen
+ConfigView.section.style.reOrderDelay=J\u00e4rjest\u00e4 taulukot uudelleen n\u00e4in monen GUI-p\u00e4ivityksen j\u00e4lkeen (0 = ei koskaan)
+ConfigView.section.style.reOrderDelay.never=Ei koskaan
+ConfigView.section.logging=Loki
+ConfigView.section.logging.enable=Kirjaa tapahtumat lokitiedostoon
+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
+ConfigView.section.tracker.passwordenableweb=K\u00e4yt\u00e4 salasanasuojausta seurantapalvelimen sivulla
+ConfigView.section.tracker.passwordenabletorrent=K\u00e4yt\u00e4 salasanasuojausta torrent-tiedostoissa
+ConfigView.section.tracker.username=K\u00e4ytt\u00e4j\u00e4tunnus
+ConfigView.section.tracker.password=Salasana
+columnChooser.title=N\u00e4ytett\u00e4v\u00e4t sarakkeet
+columnChooser.move=Voit vaihtaa sarakkeiden j\u00e4rjestyst\u00e4 raahaamalla ne haluamiisi kohtiin.
+columnChooser.apply=K\u00e4yt\u00e4
+columnChooser.columnname=Sarake
+columnChooser.columndescription=Kuvaus
+TableColumn.header.shareRatio=Jakosuhde
+MyTorrentsView.menu.editTableColumns=&Valitse n\u00e4ytett\u00e4v\u00e4t sarakkeet
+wizard.operationfailed=Toiminto ep\u00e4onnistui
+authenticator.title=Vahvista toiminto
+authenticator.realm=Asiakasohjelma
+authenticator.tracker=Seurantapalvelin
+authenticator.user=K\u00e4ytt\u00e4j\u00e4tunnus
+authenticator.password=Salasana
+ConfigView.label.allowSendVersion=L\u00e4het\u00e4 anonyymisti Vuzen versionumero ja satunnainen tunniste uutta versiota tarkastettaessa
+ConfigView.label.version.info.link=Katso t\u00e4st\u00e4 lis\u00e4tietoja l\u00e4hetett\u00e4vist\u00e4 tiedoista
+wizard.hint.mode=Vihje:\tVoit raahata ja pudottaa yksitt\u00e4isen tiedoston tai hakemiston\n\tt\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle valitaksesi kohteen.
+wizard.hint.file=Vihje:\tVoit valita yksitt\u00e4isen tiedoston my\u00f6s raahaamalla ja\n\tpudottamalla sen t\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle.
+wizard.hint.directory=Vihje:\tVoit valita yksitt\u00e4isen hakemiston my\u00f6s raahaamalla ja\n\tpudottamalla sen t\u00e4m\u00e4n ikkunan p\u00e4\u00e4lle.
+MainWindow.menu.help.checkupdate=Tarkasta &p\u00e4ivitykset...
+TableColumn.header.down=Ladattu
+TableColumn.header.up=L\u00e4hetetty
+ConfigView.section.tracker.passwordenabletorrent.info=Vaatii yhteensopivan asiakasohjelman (kuten Vuzen)
+ConfigView.section.style.confirmationOnExit=Pyyd\u00e4 vahvistus lopetettaessa
+MainWindow.dialog.exitconfirmation.title=Lopeta Vuze
+MainWindow.dialog.exitconfirmation.text=Haluatko varmasti sulkea Vuzen?
+SystemTray.menu.stopalltransfers=&Pys\u00e4yt\u00e4 kaikki siirrot
+TrayWindow.menu.stopalldownloads=&Pys\u00e4yt\u00e4 kaikki lataukset
+ConfigView.section.tracker.sslport.info=Lis\u00e4tietoja UKK:ssa
+wizard.tracker.ssl=K\u00e4yt\u00e4 SSL:\u00e4\u00e4
+ConfigView.label.playdownloadfinished=Anna \u00e4\u00e4nimerkki latauksen valmistuttua
+ConfigView.label.popupdownloadfinished=Ilmoita latauksen valmistumisesta ponnahdusikkunalla
+ConfigView.label.popupfilefinished=Ilmoita tiedoston valmistumisesta ponnahdusikkunalla
+TableColumn.header.pieces=Osat
+TableColumn.header.pieces.info=Valmistuneet osat graafisena palkkiesityksen\u00e4.
+TableColumn.header.completion=Valmistumisaste
+TableColumn.header.completion.info=Latauksen prosenttim\u00e4\u00e4r\u00e4inen valmistuminen graafisesti.
+ConfigView.section.style.showdownloadbasket=N\u00e4yt\u00e4 pikalatauskuvake - lis\u00e4\u00e4 ty\u00f6p\u00f6yd\u00e4lle kuvakkeen, johon voit raahata ja pudottaa torrent-tiedostoja
+ConfigView.section.style.alwaysShowTorrentFiles=N\u00e4yt\u00e4 aina torrent-tiedoston k\u00e4sitt\u00e4m\u00e4t tiedostot
+wizard.multitracker=M\u00e4\u00e4rit\u00e4 useita seurantapalvelimia
+wizard.multitracker.title=Seurantapalvelimien valitseminen
+wizard.multitracker.configuration=Valmiit p\u00e4\u00e4ryhm\u00e4t:
+wizard.multitracker.new=Uusi...
+wizard.multitracker.edit=Muokkaa...
+wizard.multitracker.delete=Poista
+wizard.multitracker.group=Seurantapalvelinryhm\u00e4
+wizard.multitracker.edit.title=Seurantapalvelimien muokkaus
+wizard.multitracker.edit.name=Nimi
+wizard.multitracker.edit.save=Tallenna
+wizard.multitracker.edit.newgroup=Uusi ryhm\u00e4
+wizard.multitracker.edit.deletegroup=Poista
+wizard.multitracker.edit.newtracker=Uusi seurantapalvelin
+wizard.multitracker.edit.deletetracker=Poista
+wizard.multitracker.edit.edit=Muokkaa
+wizard.addingmt=Lis\u00e4t\u00e4\u00e4n tietoja seurantapalvelimista
+wizard.multitracker.noannounce=P\u00e4ivitysosoitetta ei l\u00f6ydy seurantapalvelinlistalta.
+MyTorrentsView.menu.recheck=&Tarkasta ladatut osat uudelleen
+iconBar.showDownloadBar.tooltip=N\u00e4yt\u00e4 seurantapalkki
+iconBar.start.tooltip=K\u00e4ynnist\u00e4 (aseta jonoon) valitut torrentit
+iconBar.stop.tooltip=Pys\u00e4yt\u00e4 valitut torrentit
+iconBar.remove.tooltip=Poista torrent-tiedosto
+iconBar.openNoDefault.tooltip=Avaa torrent-tiedosto (m\u00e4\u00e4rit\u00e4 lataushakemisto)
+iconBar.openURL.tooltip=Avaa torrent-tiedosto URL-osoitteesta
+iconBar.openFolder.tooltip=Avaa hakemisto (lis\u00e4\u00e4 kaikki hakemiston torrent-tiedostot)
+iconBar.new.tooltip=Luo torrent-tiedosto
+iconBar.up.tooltip=Siirr\u00e4 yl\u00f6s
+iconBar.down.tooltip=Siirr\u00e4 alas
+iconBar.run.tooltip=Avaa oletussovelluksessa
+iconBar.host.tooltip=Aseta seurantaan
+iconBar.publish.tooltip=Julkaise
+iconBar.editcolumns.tooltip=Sarakeasetukset
+MyTorrentsView.menu.editTracker=&Muokkaa seurantapalvelimia
+GeneralView.menu.selectTracker=Valitse seurantapalvelin
+ConfigView.section.stats.xslfile=XSL-tyylitiedoston nimi
+ConfigView.section.stats.xslfiledetails=Lis\u00e4t\u00e4\u00e4n XML-tiedostoon <?xml-stylesheet>-tunnisteeksi
+ConfigView.label.savetorrentbackup=Tallenna my\u00f6s varmuuskopio
+ConfigView.section.tracker.forceport=Pakota ulkoiset torrent-tiedostot oletusporttiin
+ConfigView.section.ipfilter.allow=Salli yhteydet vain n\u00e4ilt\u00e4 osoitealueilta (k\u00e4\u00e4nt\u00e4\u00e4 suotimien tarkoituksen)
+ConfigView.section.ipfilter.list.inrange=oli osoitealueella 
+ConfigView.section.ipfilter.list.notinrange=ei ollut osoitealueilla
+ConfigView.section.ipfilter.list.title=Estetyt k\u00e4ytt\u00e4j\u00e4t
+ConfigView.label.allowsameip=Salli useat yhteydet samasta IP-osoitteesta
+ConfigView.label.allowsameip.tooltip=K\u00e4yt\u00e4 vain, jos todella tarvitset.\nKun asetus ei ole k\u00e4yt\u00f6ss\u00e4, se est\u00e4\u00e4 sellaisten k\u00e4ytt\u00e4jien yhteydenotot,\njotka lataavat tiedostoja, mutta eiv\u00e4t juurikaan (tai ollenkaan) l\u00e4het\u00e4 (mik\u00e4 ei ole hyv\u00e4 asia).
+ManagerItem.superseeding=L\u00e4hetet\u00e4\u00e4n (tehostetusti)
+ConfigView.label.userSuperSeeding=K\u00e4yt\u00e4 tehostettua l\u00e4hetystapaa
+PeersView.uniquepiece=Osa (tehostettu)
+PeersView.uniquepiece.none=Ei k\u00e4yt\u00f6ss\u00e4
+PeersView.timetosend=Uudelleenl\u00e4hetys (tehostettu)
+ConfigView.section.style.addurlsilently=Avaa torrent-tiedostot URL-osoitteista ilman erillisi\u00e4 ilmoituksia
+ConfigView.section.style.addurlsilently.tooltip=URL-osoitteista ladattavat torrent-tiedostot avataan ilman erillisi\u00e4 ilmoituksia.
+ConfigView.section.file.decoder.prompt=Kysy aina, kun eri koodausvaihtoehtoja k\u00e4ytett\u00e4viss\u00e4
+ConfigView.section.file.decoder.prompt.tooltip=N\u00e4ytt\u00e4\u00e4 aina valintaikkunan, jos on tarjolla eri koodausvaihtoehtoja.
+MyTorrentsView.menu.moveTop=Ylimm&\u00e4ksi
+MyTorrentsView.menu.moveEnd=A&limmaksi
+ConfigView.label.moveonlyusingdefaultsave=Siirr\u00e4, jos oletustallennushakemistossa
+ConfigView.label.moveonlyusingdefaultsave.tooltip=Siirt\u00e4\u00e4 tiedostot vain, jos ne ovat tallennettu oletustallennushakemistoon.
+ConfigView.label.watchtorrentfolder=Avaa torrent-tiedostot automaattisesti
+ConfigView.label.watchtorrentfolder.tooltip=Etsii uusia torrent-tiedostoja ladattavaksi s\u00e4\u00e4nn\u00f6llisin v\u00e4liajoin.
+ConfigView.label.watchtorrentfolderinterval=Tarkastusaikav\u00e4li
+ConfigView.label.watchtorrentfolderinterval.tooltip=Aikav\u00e4li, jonka kuluttua hakemisto tarkastetaan uudelleen.
+ConfigView.dialog.choosewatchtorrentfolderpath=Valitse torrent-tiedostojen avaushakemisto
+ConfigView.label.startwatchedtorrentsstopped=Aseta pys\u00e4ytetty-tilaan
+ConfigView.label.startwatchedtorrentsstopped.tooltip=Latausta ei aloiteta, vaan torrent-tiedosto asetetaan heti pys\u00e4ytetty-tilaan.
+ConfigView.section.plugins=Lis\u00e4osat
+wizard.maketorrent.filesize=Tiedosto(je)n koko:
+wizard.maketorrent.piececount=Osien lukum\u00e4\u00e4r\u00e4:
+wizard.maketorrent.piecesize=Osan koko:
+wizard.maketorrent.auto=Autom.
+MainWindow.menu.view.stats=T&ilastot
+SpeedView.title.full=Siirtonopeudet
+SpeedView.downloadSpeed.title=Latausnopeus
+SpeedView.uploadSpeed.title=L\u00e4hetysnopeus
+ConfigView.section.style.useSIUnits=K\u00e4yt\u00e4 IEC-mittayksikk\u00f6j\u00e4rjestelm\u00e4\u00e4 (esim. kB -> KiB)
+iconBar.top.tooltip=Siirr\u00e4 ylimm\u00e4ksi
+iconBar.bottom.tooltip=Siirr\u00e4 alimmaksi
+TableColumn.header.health=Yhteys
+MyTorrentsView.menu.health=Tietoja sarakkeesta "Yhteys"
+health.explain.grey=Torrent-tiedosto on t\u00e4ysin pys\u00e4ytetty (sit\u00e4 ei ladata eik\u00e4 l\u00e4hetet\u00e4).
+health.explain.red=Et ole yhteydess\u00e4 yhteenk\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4\u00e4n (ladattaessa).
+health.explain.blue=L\u00e4hetett\u00e4ess\u00e4: et ole viel\u00e4 yhteydess\u00e4 yhteenk\u00e4\u00e4n lataajaan.\nLadattaessa: olet yhteydess\u00e4 k\u00e4ytt\u00e4jiin, mutta seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4.
+health.explain.yellow=Seurantapalvelin on kunnossa ja olet yhdist\u00e4nyt k\u00e4ytt\u00e4jiin, mutta sinuun ei saada yhteytt\u00e4 ulkoa k\u00e4sin.\nT\u00e4m\u00e4 voi olla merkki NAT-ongelmasta, jos n\u00e4et keltaisia ilmaisimia jatkuvasti.
+health.explain.green=Kaikki kunnossa.
+ConfigView.section.style.alwaysRefreshMyTorrents=P\u00e4ivit\u00e4 aina {library.name}-ikkuna
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip={library.name}-ikkunan sis\u00e4lt\u00f6 p\u00e4ivitet\u00e4\u00e4n, vaikka ikkuna ei olisikaan avattuna (tietyt lis\u00e4osat hy\u00f6dynt\u00e4v\u00e4t t\u00e4t\u00e4).
+#
+#2.0.7.0
+#
+security.certtruster.title=Turvallisuusvarmennevaroitus
+security.certtruster.intro=Turvallisuusvarmenteen my\u00f6nsi osapuoli, johon et luota.
+security.certtruster.resource=L\u00e4hde:
+security.certtruster.issuedto=Kenelle:
+security.certtruster.issuedby=My\u00f6nt\u00e4j\u00e4:
+security.certtruster.prompt=Hyv\u00e4ksytk\u00f6 t\u00e4m\u00e4n varmenteen?
+security.certtruster.yes=Kyll\u00e4
+security.certtruster.no=En
+ConfigView.section.tracker.torrentsperpage=Torrent-tiedostojen lukum\u00e4\u00e4r\u00e4/sivu (0 = rajoittamaton)
+MainWindow.menu.file.share=&Jaa
+MainWindow.menu.file.share.file=&Tiedosto...
+MainWindow.menu.file.share.dir=&Hakemisto...
+MainWindow.menu.file.share.dircontents=Hakemiston &sis\u00e4lt\u00f6...
+MainWindow.menu.file.share.dircontentsrecursive=Hakemiston sis\u00e4lt\u00f6... (&rekursiivisesti)
+MainWindow.dialog.share.sharefile=Valitse jaettava tiedosto
+MainWindow.dialog.share.sharedir=Valitse jaettava hakemisto
+MainWindow.dialog.share.sharedircontents=Valitse p\u00e4\u00e4hakemisto 
+MainWindow.dialog.share.sharedircontents.recursive=jaetaan rekursiivisesti
+globalmanager.download.remove.veto=Poistaminen estetty
+plugin.sharing.download.remove.veto=T\u00e4m\u00e4 siirto on jaossa oleva kohde.\nJotta voisit poistaa siirron, sinun t\u00e4ytyy ensin poistaa kyseinen jako (Classic-Share): Ty\u00f6kalut->Jaot (Tools->My Classic-Shares).
+ConfigView.section.tracker.main=Perusasetukset
+ConfigView.label.prioritizefirstpiece=Pyri lataamaan ensisijaisesti tiedostojen ensimm\u00e4iset ja viimeiset osat
+ConfigView.label.prioritizefirstpiece.tooltip=Pyrkii lataamaan aluksi tiedoston ensimm\u00e4isen ja viimeisen osan mahdollista esikatselua varten.
+ConfigView.section.file.delete.include_files_outside_save_dir=Kun tiedostoja poistetaan, salli linkitettyjen tiedostojen poistaminen my\u00f6s muualta kuin torrenttien tallennushakemistosta
+TrayWindow.menu.startalldownloads=K\u00e4ynnist\u00e4 kaikki lataukset
+SystemTray.menu.startalltransfers=K\u00e4ynnist\u00e4 kaikki siirrot
+sharing.progress.title=Jakamisen edistyminen
+sharing.progress.hide=Piilota
+MainWindow.menu.view.myshares=&Jaot
+MySharesView.title.full=Jaot
+MySharesView.name=Nimi
+MySharesView.type=Tyyppi
+MySharesView.type.file=Tiedosto
+MySharesView.type.dir=Hakemisto
+MySharesView.type.dircontents=Hakemiston sis\u00e4lt\u00f6
+MySharesView.type.dircontentsrecursive=Hakemiston sis\u00e4lt\u00f6 (rekursiivisesti)
+MySharesView.menu.remove=Poista
+ConfigView.section.tracker.extensions=Lis\u00e4asetukset
+ConfigView.section.tracker.sendpeerids=L\u00e4het\u00e4 tunnisteet k\u00e4ytt\u00e4jist\u00e4 lataajille
+ConfigView.section.tracker.enableudp=K\u00e4yt\u00e4 seurantapalvelimen UDP-protokollaa
+plugin.sharing.torrent.remove.veto=T\u00e4m\u00e4 on jaettu kohde.\nPoistaaksesi kohteen poista ensin kyseinen jako (Classic-Share): Ty\u00f6kalut->Jaot (Tools->My Classic-Shares).
+plugin.download.remove.veto.notstopped=Kohdetta ei voida poistaa, koska sit\u00e4 ei ole pys\u00e4ytetty.
+plugin.sharing.remove.veto=T\u00e4m\u00e4 kohde on Hakemiston sis\u00e4lt\u00f6 -jaon alainen, joten et voi poistaa sit\u00e4 suoraan.\nPoistaaksesi kohteen poista p\u00e4\u00e4jako (p\u00e4\u00e4hakemisto).
+GeneralView.label.hash.tooltip=Klikkaa kopioidaksesi tiiviste leikep\u00f6yd\u00e4lle.
+ConfigView.section.tracker.maxpeersreturned=Palautettavien yhteystietojen enimm\u00e4ism\u00e4\u00e4r\u00e4\n(0 = rajoittamaton)
+ConfigView.label.serverport=Sis\u00e4\u00e4ntulevan TCP- ja UDP-liikenteen portti
+ConfigView.label.serverport.tooltip=Portin t\u00e4ytyy olla v\u00e4lilt\u00e4 1-65535, eik\u00e4 se saa olla 6880, koska\nkyseinen portti on varattu Vuzen sis\u00e4iseen k\u00e4ytt\u00f6\u00f6n.
+configureWizard.nat.server.tcp_listen_port=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
+ConfigView.section.sharing=Jakaminen
+ConfigView.section.sharing.usessl=K\u00e4yt\u00e4 SSL:\u00e4\u00e4 jaetuille resursseille (seurantapalvelimen asetusten oltava vastaavat)
+ConfigView.section.style.dropdiraction=Toiminto raahatessa ja pudotettaessa kansioita Vuzeen
+ConfigView.section.style.dropdiraction.opentorrents=Avaa torrent-tiedostot
+ConfigView.section.style.dropdiraction.sharefolder=Jaa hakemisto
+ConfigView.section.style.dropdiraction.sharefoldercontents=Jaa hakemiston sis\u00e4lt\u00f6
+#
+# 2.0.7.x
+#
+Categories.all=Kaikki
+Categories.uncategorized=Luokittelemattomat
+CategoryAddWindow.message=Anna uuden luokan nimi:
+CategoryAddWindow.title=Uusi luokka
+ConfigView.label.autoSeedingIgnoreInfo=Ohitetut torrent-tiedostot menev\u00e4t l\u00e4hetysjonon loppup\u00e4\u00e4h\u00e4n ja niit\u00e4 ei aloiteta l\u00e4hett\u00e4m\u00e4\u00e4n automaattisesti.\nN\u00e4m\u00e4 ohituss\u00e4\u00e4nn\u00f6t eiv\u00e4t p\u00e4de niihin torrent-tiedostoihin, jotka ovat saavuttaneet ensisijaisuuden.\nNolla-arvo (0) tarkoittaa asetuksissa s\u00e4\u00e4nn\u00f6n poistamista k\u00e4yt\u00f6st\u00e4, ellei toisin mainita.
+ConfigView.label.directory=Hakemisto
+ConfigView.label.disconnetseed.tooltip=Yhteys l\u00e4hett\u00e4jiin voidaan katkaista, koska niit\u00e4 ei en\u00e4\u00e4 tarvita latauksen valmistuttua.
+ConfigView.label.ignoreCase=Kirjainten koolla ei v\u00e4li\u00e4
+ConfigView.label.ignoreSeeds=Ohita torrent-tiedostot, joilla on v\u00e4hint\u00e4\u00e4n
+ConfigView.label.importdirectory=Avaushakemisto
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=Ehdot t\u00e4ytt\u00e4v\u00e4t torrent-tiedostot siirret\u00e4\u00e4n l\u00e4hetysjonon loppup\u00e4\u00e4h\u00e4n.
+ConfigView.label.minPeersToBoostNoSeeds=Alenna torrent-tiedostojen l\u00e4hetystarvetta, joilla ei ole l\u00e4hteit\u00e4 ja v\u00e4hemm\u00e4n kuin
+ConfigView.label.minSeedingTime.tooltip=Torrent-tiedostojen l\u00e4hetystarpeet voivat vaihdella niin nopeasti, ett\u00e4 kun torrent-tiedosto on asetettu l\u00e4hetett\u00e4v\u00e4ksi,\nse pys\u00e4ytet\u00e4\u00e4nkin samantien ja palautetaan jonoon. T\u00e4ll\u00e4 asetuksella v\u00e4himm\u00e4isl\u00e4hetysaika voidaan pakottaa tietyn pituiseksi.\nL\u00e4hetyksen voi toki t\u00e4llaisessa tilanteessa pys\u00e4ytt\u00e4\u00e4 manuaalisesti.
+ConfigView.label.minSeedingTime=V\u00e4himm\u00e4isl\u00e4hetysaika sekunneissa
+ConfigView.label.minSpeedForActiveDL.tooltip=Normaalisti torrent-tiedosto lasketaan kuuluvaksi t\u00e4h\u00e4n\njoukkoon v\u00e4hint\u00e4\u00e4n 30 sekunnin ajaksi latauksen k\u00e4ynnistymisest\u00e4 l\u00e4htien.
+ConfigView.label.minSpeedForActiveDL=\u00c4l\u00e4 laske torrent-tiedostoa ladattavien joukkoon, jos latausnopeus on alle
+ConfigView.label.peers=lataajaa
+ConfigView.label.queue.debuglog=Kirjaa virheenm\u00e4\u00e4ritystiedot lokiin
+ConfigView.label.queue.debuglog.info=Lis\u00e4\u00e4 siirtojonotoimintojen virheenm\u00e4\u00e4ritystiedot konsoliin/lokitiedostoon.\nVaikka tiedot ovatkin vaikeaselkoisia, saa niist\u00e4 selville torrent-tiedostojen tilan ja miksi ne ovat k\u00e4ynnistyneet tai pys\u00e4htyneet.
+ConfigView.label.queue.minQueueingShareRatio=\u00c4l\u00e4 aseta jonoon/pys\u00e4yt\u00e4 torrent-tiedostoa ennen kuin jakosuhde on
+ConfigView.label.ratio=jakosuhde
+ConfigView.label.removeOnStop=Poista torrent-tiedosto, kun se on automaattisesti pys\u00e4htynyt
+ConfigView.label.savedirectory=Tallennushakemisto
+ConfigView.label.seeding.autoReposition.tooltip=Jos k\u00e4yt\u00f6ss\u00e4, torrent-tiedostojen j\u00e4rjestys (#-sarake Siirrot-ikkunassa)\nm\u00e4\u00e4r\u00e4ytyy niiden l\u00e4hetystarpeen mukaan.\nHy\u00f6dyllinen toiminto, jos et halua n\u00e4hd\u00e4 l\u00e4hetystarvearvoja, mutta haluat silti\nolla selvill\u00e4 siit\u00e4, mit\u00e4 valmistunutta torrent-tiedostoa aloitetaan l\u00e4hett\u00e4\u00e4 seuraavaksi.
+ConfigView.label.seeding.autoReposition=J\u00e4rjest\u00e4 torrent-tiedostot perustuen l\u00e4hetystarpeeseen
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=Jos torrent-tiedostolla on v\u00e4h\u00e4n l\u00e4hteit\u00e4 ja kuitenkin paljon lataajia, tarkoittaa se usein sit\u00e4,\nett\u00e4 lataajien joukossa on tuskin yht\u00e4\u00e4n t\u00e4ytt\u00e4 kopiota.\nNiinp\u00e4 haluat ehk\u00e4 rajoittaa edellist\u00e4 s\u00e4\u00e4nt\u00f6\u00e4, jotta Vuze ei turhaan alenna torrent-tiedoston sijoitusta l\u00e4hetysjonossa.
+ConfigView.label.seeding.fakeFullCopySeedStart=mutta vain torrent-tiedostoille, joilla on v\u00e4hint\u00e4\u00e4n
+ConfigView.label.seeding.ignore=Ohituss\u00e4\u00e4nn\u00f6t
+ConfigView.label.seeding.ignore0Peers=Ohita torrent-tiedostot, joilla ei ole yht\u00e4\u00e4n lataajaa
+ConfigView.label.seeding.ignoreRatioPeers=Ohita torrent-tiedostot, joilla on v\u00e4hint\u00e4\u00e4n yksi l\u00e4hde kohti
+ConfigView.label.seeding.ignoreShareRatio=Ohita torrent-tiedostot, joiden jakosuhde on
+ConfigView.label.seeding.ignore.header.evenFirstPriority=Ohita torrent-tiedosto,\nvaikka olisi ensisijainen
+ConfigView.label.seeding.ignore.header.rule=S\u00e4\u00e4nt\u00f6
+ConfigView.label.seeding.ignore.header.value=Arvo
+ConfigView.label.seeding.firstPriority.info=Ensisijaiset torrent-tiedostot ovat aina l\u00e4hetysjonon k\u00e4rkip\u00e4\u00e4ss\u00e4. Jos torrent-tiedosto on ensisijainen, sit\u00e4 ei automaattisesti pys\u00e4ytet\u00e4 eik\u00e4 aseteta takaisin jonoon. Ensisijainen torrent-tiedosto voi my\u00f6s varata itselleen yht\u00e4aikaisen latauspaikan, jos se tarvitsee sellaista.
+ConfigView.label.seeding.firstPriority.FP=Ensisijaisuus
+ConfigView.label.seeding.firstPriority=Ensisijaisuus my\u00f6nnet\u00e4\u00e4n torrent-tiedostoille, jotka t\u00e4ytt\u00e4v\u00e4t
+ConfigView.label.seeding.firstPriority.following=seuraavista s\u00e4\u00e4nn\u00f6ist\u00e4:
+ConfigView.label.seeding.firstPriority.shareRatio=Jakosuhde on alle
+ConfigView.label.seeding.firstPriority.seedingMinutes=Aikaa kulunut siit\u00e4, kun lataus valmistui ja l\u00e4hett\u00e4minen alkoi
+ConfigView.label.seeding.firstPriority.DLMinutes=Aikaa kulunut latauksen aloittamisesta
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Lis\u00e4\u00e4m\u00e4ll\u00e4 teoreettisesti yhden t\u00e4yden kopion siirrosta tietty\u00e4 lataajam\u00e4\u00e4r\u00e4\u00e4 kohti\nv\u00e4henn\u00e4t niiden torrent-tiedostojen l\u00e4hetystarvetta, joilla on paljon lataajia.\nT\u00e4llaisten torrent-tiedostojen kohdalla tietoa liikkuu todenn\u00e4k\u00f6isesti jo aivan tarpeeksi.\nT\u00e4m\u00e4 asetus ei lis\u00e4\u00e4 miss\u00e4\u00e4n k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytett\u00 [...]
+ConfigView.label.seeding.numPeersAsFullCopy=Lis\u00e4\u00e4 teoreettisesti yksi t\u00e4ysi kopio kohti (0 = ei teoreettista lis\u00e4yst\u00e4)
+ConfigView.label.seeding.preferLargerSwarms.tooltip=T\u00e4st\u00e4 asetuksesta on hy\u00f6ty\u00e4 silloin, kun l\u00e4hetet\u00e4\u00e4n torrent-tiedostoja, joiden tiedon siirt\u00e4minen\nlataajille/lataajien kesken on hyvin hidasta. Jos puolestaan l\u00e4het\u00e4t torrent-tiedostoja, joilla on hyv\u00e4 saatavuus,\non parempi suosia niit\u00e4, joilla on v\u00e4hemm\u00e4n lataajia.
+ConfigView.label.seeding.preferLargerSwarms=Jos torrent-tiedostoilla on sama l\u00e4hetystarve, suosi sit\u00e4, jolla on enemm\u00e4n lataajia
+ConfigView.label.seeding.rankType.none.tooltip=J\u00e4rjestys pohjautuu torrent-tiedoston j\u00e4rjestysnumeroon (#-sarake Siirrot-ikkunassa).
+ConfigView.label.seeding.rankType.none=Ei mihink\u00e4\u00e4n
+ConfigView.label.seeding.rankType.peer.tooltip=Enemm\u00e4n lataajia, v\u00e4hemm\u00e4n l\u00e4hteit\u00e4 --> korkeampi prioriteetti\nT\u00e4m\u00e4 asetus pienent\u00e4\u00e4 tarvittavien aktiivisten torrenttien m\u00e4\u00e4r\u00e4\u00e4 l\u00e4hetysnopeuden maksimoimiseksi
+ConfigView.label.seeding.rankType.peer=Painotettu lataajien m\u00e4\u00e4r\u00e4
+ConfigView.label.seeding.rankType.peerSeed.options=Ohitusasetukset
+ConfigView.label.seeding.rankType.peerSeed.tooltip=Korkeampi suhdeluku vastaa korkeampaa l\u00e4hetystarvetta.
+ConfigView.label.seeding.rankType.peerSeed=Lataajia/l\u00e4hde-suhdelukuun
+ConfigView.label.seeding.rankType.seed.fallback=Vaihda edelliseen s\u00e4\u00e4nt\u00f6\u00f6n, kun on\n(0 = \u00e4l\u00e4 vaihda koskaan)
+ConfigView.label.seeding.rankType.seed.options=Ohitusasetukset
+ConfigView.label.seeding.rankType.seed.tooltip=V\u00e4hemm\u00e4n l\u00e4hteit\u00e4 vastaa korkeampaa l\u00e4hetystarvetta.
+ConfigView.label.seeding.rankType.seed=L\u00e4hteiden lukum\u00e4\u00e4r\u00e4\u00e4n
+ConfigView.label.seeding.rankType.timedRotation.tooltip=Kaikkia jonossa olevia torrent-tiedostoja l\u00e4hetet\u00e4\u00e4n vuorotellen.\nL\u00e4hetysajan pituus m\u00e4\u00e4ritell\u00e4\u00e4n L\u00e4hett\u00e4minen-asetusryhm\u00e4n kohdassa V\u00e4himm\u00e4isl\u00e4hetysaika sekunneissa.
+ConfigView.label.seeding.rankType.timedRotation=Aikaan
+ConfigView.label.seeding.rankType.tooltip=Korkeimman l\u00e4hetystarpeen torrent-tiedostoja aloitetaan l\u00e4hett\u00e4\u00e4 automaattisesti.\nKun toinen torrent-tiedosto saavuttaa korkeamman l\u00e4hetystarpeen, edellisen l\u00e4hett\u00e4minen keskeytet\u00e4\u00e4n ja se asetetaan takaisin jonoon.\n\nAutomaattista l\u00e4hetyksen aloittamista voidaan soveltaa vain niihin torrent-tiedostohin, jotka ovat Jonossa-tilassa.\nT\u00e4ysin pys\u00e4ytettyj\u00e4 torrent-tiedostoja ei koskaa [...]
+ConfigView.label.seeding.rankType=Priorisoi valmistuneiden torrent-tiedostojen l\u00e4hett\u00e4minen perustuen:
+ConfigView.label.stopAfterMinutes=Pys\u00e4yt\u00e4 l\u00e4hett\u00e4minen, kun on kulunut valmistumisen j\u00e4lkeen
+ConfigView.label.switchpriority.tooltip=Alhainen prioriteetti v\u00e4hent\u00e4\u00e4 torrent-tiedostolle jaettua l\u00e4hetysnopeutta.
+ConfigView.pluginlist.info=Vuze tunnisti seuraavat lis\u00e4osat.\nHuomaa, ett\u00e4 kaikilla ei v\u00e4ltt\u00e4m\u00e4tt\u00e4 ole asetusmahdollisuuksia.
+ConfigView.pluginlist.noplugins=Lis\u00e4osia ei l\u00f6ytynyt.
+ConfigView.section.pluginslist=Listaa
+ConfigView.section.queue.seeding=L\u00e4hett\u00e4minen
+ConfigView.section.queue.seeding.autoStarting=Automaattinen aloitus
+ConfigView.section.queue.seeding.ignore=Ohituss\u00e4\u00e4nn\u00f6t
+ConfigView.section.queue.seeding.firstPriority=Ensisijaisuus
+ConfigView.section.queue.main=Perusasetukset
+ConfigView.section.queue=Siirtojonot
+ConfigView.section.torrents=Torrent-tiedostot
+ConfigView.text.all=kaikki
+ConfigView.text.hours=tuntia
+ConfigView.text.ignoreRule=Ohita s\u00e4\u00e4nt\u00f6
+ConfigView.text.ignore=Ei k\u00e4yt\u00f6ss\u00e4
+ConfigView.text.minutes=min
+ConfigView.text.neverIgnore=\u00c4l\u00e4 koskaan ohita
+ConfigView.text.any=jonkun
+DownloadManager.error.datamissing=Tiedostoja ei saatavilla
+MainWindow.menu.file.open.torrentforseeding=Torrent-tiedosto... (l\u00e4hett\u00e4mist\u00e4 varten)
+MainWindow.menu.language.refresh=&P\u00e4ivit\u00e4
+ManagerItem.forced=Ohita s\u00e4\u00e4nn\u00f6t, 
+ManagerItem.queued=Jonossa
+MySeedersView.header=Valmistuneet torrent-tiedostot
+TableColumn.header.availability.info=T\u00e4ysien kopioiden lukum\u00e4\u00e4r\u00e4.
+TableColumn.header.availability=Saatavuus
+TableColumn.header.category=Luokka
+MyTorrentsView.header=Keskener\u00e4iset torrent-tiedostot
+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=Tallennushakemisto
+TableColumn.header.SeedingRank=L\u00e4hetystarve
+TableColumn.header.totalspeed.info=Yhdistettyin\u00e4 olevien k\u00e4ytt\u00e4jien siirtonopeus yhteens\u00e4.
+TableColumn.header.totalspeed=Nopeus yht.
+splash.initializePlugins=Alustetaan lis\u00e4osia
+StartStopRules.SPratioMet=L\u00e4h:Lat-suhdeluku OK
+StartStopRules.FP0Peers=Ensisijaisuus/0 lataajaa
+StartStopRules.0Peers=0 lataajaa
+StartStopRules.numSeedsMet=L\u00e4hteiden lkm OK
+StartStopRules.ratioMet=Lataajia/l\u00e4hde-suhde OK
+StartStopRules.shareRatioMet=Jakosuhde OK
+StartStopRules.waiting=Odotetaan
+StartStopRules.firstPriority=Ensisijainen
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Jaa hakemiston sis\u00e4lt\u00f6 (rekursiivisesti)
+DownloadManager.error.unabletostartserver=Yhteyden muodostaminen ei onnistu - tarkasta sis\u00e4\u00e4ntulevan TCP-liikenteen portti/palomuurin asetukset koskien Vuzea
+GeneralView.label.creationdate=Luontiaika:
+ConfigView.section.tracker.announcescrapepercentage=Pikap\u00e4ivitysten suhde %:ina p\u00e4ivityksist\u00e4,\nesim. 200 = 2:1 (0 = k\u00e4ytt\u00e4j\u00e4 p\u00e4\u00e4tt\u00e4\u00e4)
+ManagerItem.stopping=Pys\u00e4ytet\u00e4\u00e4n
+ConfigView.section.tracker.announcecacheperiod=P\u00e4ivitysten v\u00e4limuistiaika (ms)
+ConfigView.section.tracker.scrapecacheperiod=Pikap\u00e4ivitysten v\u00e4limuistiaika (ms)
+ConfigView.section.tracker.scrapeandcache=Pikap\u00e4ivitykset ja v\u00e4limuisti
+ConfigView.section.tracker.announcecacheminpeers=K\u00e4ytt\u00e4jien m\u00e4\u00e4r\u00e4, jonka j\u00e4lkeen\np\u00e4ivitysten v\u00e4limuisti k\u00e4yt\u00f6ss\u00e4
+MyTrackerView.scrapes=Pikap\u00e4ivitykset
+fileDownloadWindow.retry=Uudestaan
+MyTrackerView.bytesin=Sis\u00e4\u00e4n
+MyTrackerView.bytesinave=Keskim. sis\u00e4\u00e4n
+MyTrackerView.bytesout=Ulos
+MyTrackerView.bytesoutave=Keskim. ulos
+ConfigView.section.file.max_open_files=Lukua/kirjoitusta varten avattavien tiedostojen\nenimm\u00e4islukum\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
+ConfigView.section.file.max_open_files.tooltip=Tiedostojen lukum\u00e4\u00e4r\u00e4\u00e4 kannattaa rajoittaa siin\u00e4 tapauksessa, jos torrent-tiedosto k\u00e4sitt\u00e4\u00e4\nsatoja tai jopa tuhansia tiedostoja ja k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n tiedostonk\u00e4sittelyrajat tulevat t\u00e4ll\u00f6in vastaan.
+ConfigView.section.proxy=V\u00e4lityspalvelin
+ConfigView.section.proxy.enable_proxy=K\u00e4yt\u00e4 v\u00e4lityspalvelinta (vaatii uudelleenk\u00e4ynnistyksen)
+ConfigView.section.proxy.host=Osoite
+ConfigView.section.proxy.port=Portti
+ConfigView.section.proxy.username=K\u00e4ytt\u00e4j\u00e4tunnus
+ConfigView.section.proxy.password=Salasana
+ConfigView.section.proxy.enable_socks=V\u00e4lityspalvelin on SOCKS-yhteensopiva
+wizard.createtorrent.extrahashes=Lis\u00e4\u00e4 tiivisteet muille verkoille (esim. Gnutella2 ja ed2k)
+GeneralView.label.connected=yhdistetty
+GeneralView.label.in_swarm=kaikkiaan
+ManagerItem.initializing=Aloitetaan
+AlertMessageBox.error=Virhe
+AlertMessageBox.warning=Varoitus
+AlertMessageBox.comment=Kommentti
+AlertMessageBox.information=Info
+AlertMessageBox.unread=Lukemattomia viestej\u00e4 - klikkaa t\u00e4st\u00e4
+SharedPortServer.alert.selectorfailed=Sis\u00e4\u00e4ntulevan tiedon vastaanottamisessa ongelmia.\nTarkasta palomuurin asetukset Vuzen osalta.
+Tracker.alert.listenfail=Portti %1 ei ole k\u00e4ytett\u00e4viss\u00e4.\nTarkasta, ett\u00e4 muut sovellukset eiv\u00e4t k\u00e4yt\u00e4 ko. porttia ja varmista my\u00f6s, ettei sinulla ole useampaa Vuzea k\u00e4ynniss\u00e4.
+DiskManager.alert.movefileexists=Ongelma tiedostojen siirt\u00e4misess\u00e4.\nTiedosto %1 on jo olemassa kohdehakemistossa.
+DiskManager.alert.movefilefails=Ongelma tiedostojen siirt\u00e4misess\u00e4.\nTiedoston %1 siirto ep\u00e4onnistui, %2
+DiskManager.alert.movefilerecoveryfails=Ongelma tietojen palauttamisessa.\nTiedoston %1 palautus ep\u00e4onnistui, %2
+ConfigView.section.tracker.logenable=Tallenna tilastotiedot (tracker.log-tiedosto)
+SpeedView.stats.title=Tilastot
+SpeedView.stats.total=Yhteens\u00e4
+SpeedView.stats.session=T\u00e4m\u00e4 sessio
+SpeedView.stats.session.tooltip=Yhteens\u00e4 (yhteysk\u00e4yt\u00e4nt\u00f6)
+SpeedView.stats.downloaded=Ladattu (yhteysk\u00e4yt\u00e4nt\u00f6)
+SpeedView.stats.uploaded=L\u00e4hetetty (yhteysk\u00e4yt\u00e4nt\u00f6)
+SpeedView.stats.ratio=Jakosuhde
+SpeedView.stats.uptime=K\u00e4ytt\u00f6aika
+SpeedView.stats.now=Parhaillaan
+SpeedView.stats.now.tooltip=Yhteens\u00e4 (yhteysk\u00e4yt\u00e4nt\u00f6)
+AutoMigration.useralert=Vuzen asetustiedostojen ja hakemistojen\nautomaattisen kopioinnin tulokset:\n\n%1\nEp\u00e4onnistuneet ('FAILED') kopioinnit t\u00e4ytyy tehd\u00e4 manuaalisesti.\nMuista my\u00f6s p\u00e4ivitt\u00e4\u00e4 tallennuspolut asetuksiin!
+#
+# > 2.0.8.0
+#
+OpenTorrentWindow.title=Avaa torrent-tiedosto
+OpenTorrentWindow.message=Kokeellinen
+OpenTorrentWindow.addFiles=Lis\u00e4\u00e4 &tiedostoja
+OpenTorrentWindow.dataLocation=Tallennushakemisto:
+OpenTorrentWindow.startMode=Aloitustila
+OpenTorrentWindow.startMode.queued=K\u00e4ynnist\u00e4 (aseta jonoon)
+OpenTorrentWindow.startMode.stopped=Pys\u00e4ytetty
+OpenTorrentWindow.startMode.forceStarted=K\u00e4ynnist\u00e4 (ohita s\u00e4\u00e4nn\u00f6t)
+OpenTorrentWindow.addPosition=Sijoitus jonossa
+OpenTorrentWindow.addPosition.first=Ensimm\u00e4inen
+OpenTorrentWindow.addPosition.last=Viimeinen
+TableColumn.header.remaining.info=J\u00e4ljell\u00e4 oleva ladattava m\u00e4\u00e4r\u00e4.
+TableColumn.header.remaining=J\u00e4ljell\u00e4
+ConfigView.section.tracker.enablecompact=K\u00e4yt\u00e4 tiivistetty\u00e4 p\u00e4ivitysprotokollaa (IP- ja porttitiedot l\u00e4hetet\u00e4\u00e4n 6 bitin sarjoina string-arvon sijaan)
+ConfigView.section.tracker.enablekey=K\u00e4yt\u00e4 turva-avaimen siirtoa seurantapalvelimelle (parantaa turvallisuutta)
+ConfigView.section.file.perf=Suorituskyky
+ConfigView.section.file.perf.explain=Varoitus - n\u00e4iden asetusten harkitsematon muuttaminen voi vaikuttaa alentavasti latausnopeuksiin.\nJotta muutokset tulisivat voimaan, Vuze t\u00e4ytyy k\u00e4ynnist\u00e4\u00e4 uudelleen.\nJos muistin k\u00e4ytt\u00f6 nousee huomattavasti, voit kokeilla torrent-kohtaisten yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4n pienent\u00e4mist\u00e4 Siirrot-asetuksissa.
+ConfigView.section.file.max_open_files.explain=Liian suuren tiedostom\u00e4\u00e4r\u00e4n k\u00e4sittely voi johtaa k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4ongelmiin. T\u00e4m\u00e4 asetus rajoittaa yht\u00e4aikaisesti k\u00e4sitelt\u00e4vien tiedostojen m\u00e4\u00e4r\u00e4\u00e4.
+popup.error.hide=Piilota
+popup.error.details=Lis\u00e4\u00e4...
+ConfigView.section.style.colorOverrides=Tarkemmat v\u00e4riasetukset
+ConfigView.section.style.colorOverride.progressBar=Edistymispalkit
+ConfigView.section.style.colorOverride.error=Virheet
+MainWindow.status.tooOld=on vanha. P\u00e4ivit\u00e4.
+ConfigView.section.style.colorOverride.warning=Varoitukset
+ConfigView.section.style.colorOverride.altRow=Taulukoiden rivit (joka toinen)
+ConfigView.section.file.save.peers.enable=Tallenna tiedot k\u00e4ytt\u00e4jist\u00e4
+ConfigView.section.file.save.peers.max=K\u00e4ytt\u00e4jien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
+ConfigView.section.file.save.peers.pertorrent=/torrent-tiedosto
+ConfigView.label.max_peers_per_torrent=Yhteyksien oletusenimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto (0 = rajoittamaton)
+ConfigView.label.max_peers_total=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 kaikkiaan (0 = rajoittamaton)
+ConfigView.section.style.colorOverrides.reset=Oletusv\u00e4ri
+ConfigView.section.language.info=Jos k\u00e4yt\u00f6ss\u00e4, Vuze tarkastaa k\u00e4ynnistyksen yhteydess\u00e4 saatavilla olevat p\u00e4ivitykset.
+ConfigView.section.language.enableUpdate=K\u00e4yt\u00e4 Web-p\u00e4ivityst\u00e4
+ConfigView.section.language.UpdateURL=Tarkastusosoite
+ConfigView.section.language.UpdateNow=P\u00e4ivit\u00e4 nyt
+Button.revert=Palaa
+MyTorrentsView.menu.changeDirectory=Vaihda tallennushakemistoa
+GenericText.column=-sarake
+MyTorrentsView.menu.thisColumn.remove=Poista sarake n\u00e4kyvist\u00e4
+MyTorrentsView.menu.thisColumn.toClipboard=Kopioi teksti leikep\u00f6yd\u00e4lle
+MyTorrentsView.menu.thisColumn.autoTooltip=N\u00e4yt\u00e4 aina ty\u00f6kaluvihje
+MyTorrentsView.menu.tracker=Seurantapalvelin/Torrent
+ConfigView.download.abbreviated=Lad:
+ConfigView.upload.abbreviated=L\u00e4h:
+ConfigView.complete.abbreviated=Valm:
+TableColumn.header.secondsseeding=L\u00e4h.aika
+TableColumn.header.secondsseeding.info=Torrent-tiedoston l\u00e4hetysaika sen lataukseen asettamisesta l\u00e4htien.
+TableColumn.header.secondsdownloading=Lat.aika
+TableColumn.header.secondsdownloading.info=Torrent-tiedoston latausaika sen lataukseen asettamisesta l\u00e4htien.
+ConfigView.section.tracker.udpversion=UDP-protokollan k\u00e4ytett\u00e4v\u00e4 versio (1 tai 2)
+window.updateswt.title=SWT-ohjelmakirjasto vanhentunut!
+window.updateswt.text=SWT-versiosi on vanhentunut!\nSWT on vuzen k\u00e4ytt\u00e4m\u00e4 graafinen ohjelmakirjasto, ja t\u00e4m\u00e4nhetkinen SWT-versiosi on liian vanha Vuzen k\u00e4ynnist\u00e4miseen. Valitse OK p\u00e4ivitt\u00e4\u00e4ksesi SWT-ohjelmakirjasto uusimpaan versioon.
+window.updateswt.status=Tila
+window.updateswt.failed=P\u00e4ivitys ep\u00e4onnistui, valitse OK k\u00e4ynnist\u00e4\u00e4ksesi uudelleen.
+window.updateswt.status.downloading.updater=Ladataan p\u00e4ivitysmoduulia
+window.updateswt.status.finding=Etsit\u00e4\u00e4n viimeisint\u00e4 SWT-versiota
+window.updateswt.status.downloading=Ladataan viimeisint\u00e4 SWT-versiota
+window.updateswt.status.done=K\u00e4ynnistet\u00e4\u00e4n uudelleen
+window.updateswt.cancel=Peruuta
+swt.updater.downloader.downloading=Ladataan SWT:t\u00e4 kohteesta
+swt.updater.urlsgetter.downloading=Ladataan peilaavien palvelimien listaa kohteesta
+swt.updater.urlsgetter.platform=SWT k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4alustalle: 
+window.updateswt.ignore=Ohita
+ConfigView.section.style.useFancyTabs=K\u00e4yt\u00e4 ulkoasultaan tyyliteltyj\u00e4 v\u00e4lilehti\u00e4
+splash.initializeGM=Alustetaan torrent-tiedostojen k\u00e4sittely\u00e4
+splash.loadingTorrents=Ladataan torrent-tiedostoja
+MyTorrentsView.menu.thisColumn.sort=&Lajittele torrent-tiedostot
+Scrape.status.ok=Pikap\u00e4ivitys OK.
+Scrape.status.error=Pikap\u00e4ivitysvirhe: 
+Scrape.status.error.badURL=P\u00e4ivitysosoite ei tue pikap\u00e4ivitysm\u00e4\u00e4rittelyj\u00e4.
+Scrape.status.error.nohash=Vastaus ei sis\u00e4lt\u00e4nyt tiivistett\u00e4.
+Scrape.status.error.invalid=Virheellinen vastaus.
+Scrape.status.nextScrapeAt=Seuraava pikap\u00e4ivitys %1
+Scrape.status.scraping=Suoritetaan pikap\u00e4ivityst\u00e4...
+Scrape.status.initializing=Odotetaan pikap\u00e4ivityst\u00e4
+Scrape.status.scraping.queued=Pikap\u00e4ivitys jonossa...
+ConfigView.label.minSpeedForActiveSeeding=\u00c4l\u00e4 laske valmistunutta torrent-tiedostoa aktiiviseksi, jos l\u00e4hetysnopeus on alle
+ConfigView.section.stats.exportpeers=Tallenna tarkat tiedot k\u00e4ytt\u00e4jist\u00e4
+MainWindow.menu.view.irc.moved=IRC-laajennus on nyt saatavilla lis\u00e4osana, katso lis\u00e4tietoja osoitteesta http://plugins.vuze.com/plugin_list.php . Asennuksen j\u00e4lkeen lis\u00e4osa l\u00f6ytyy valikosta N\u00e4yt\u00e4 -> Lis\u00e4osat -> IRC.
+MyTrackerView.webui.contextmenu.copyurl=Kopioi torrent-tiedoston URL-osoite leikep\u00f6yd\u00e4lle
+ConfigView.section.file.torrent.ignorefiles=Tiedostot, jotka ohitetaan luotaessa/poistettaessa tiedostoja\nesim. .DS_Store;Thumbs.db
+Torrent.create.progress.ignoringfile=Ohitetaan tiedosto
+ConfigView.section.style.useUnitsRateBits=K\u00e4yt\u00e4 bittej\u00e4 tavujen sijasta tavupohjaisissa nopeusarvoissa (esim. KiB/s -> Kibit/s)
+ConfigView.section.interface.resetassoc=Palauta .torrent-tiedostojen ja magnet-protokollan assosiaatio Vuzelle
+ConfigView.section.interface.resetassocbutton=Palauta
+ConfigView.section.interface.checkassoc=Tarkasta assosiaatio k\u00e4ynnistett\u00e4ess\u00e4
+dialog.associations.title=Tiedostoassosiaation tarkastus
+Button.yes=&Kyll\u00e4
+Button.no=&Ei
+ConfigView.label.seeding.autoStart0Peers=K\u00e4ynnist\u00e4 valmistuneet torrent-tiedostot, joilla ei ole yht\u00e4\u00e4n lataajaa
+ConfigView.label.seeding.autoStart0Peers.tooltip=K\u00e4yt\u00e4 t\u00e4t\u00e4, jos haluat, ett\u00e4 seurantapalvelin tallentaa aina tiedot l\u00e4hteist\u00e4.
+dialog.associations.prompt=Vuzea ei ole asetettu oletussovellukseksi BitTorrent-tiedostoille.\nHaluatko assosioida .torrent-tiedostot Vuzelle?
+dialog.associations.askagain=Tarkasta k\u00e4ynnistett\u00e4ess\u00e4
+ConfigView.section.plugins.update=Lis\u00e4osien p\u00e4ivitys
+Plugin.pluginupdate.enablecheck=Tarkasta, onko k\u00e4yt\u00f6ss\u00e4 oleviin lis\u00e4osiin saatavilla p\u00e4ivityksi\u00e4
+plugins.basicview.status=Tila: 
+plugins.basicview.activity=Toiminta: 
+plugins.basicview.progress=Edistyminen: 
+plugins.basicview.log=Loki: 
+ConfigView.label.maxdownloadspeed=kB/s, enimm\u00e4islatausnopeus (kaikki torrent-tiedostot, 0 = rajoittamaton)
+splash.loadingTorrent=Ladataan torrent-tiedostoa
+splash.of=/
+ConfigView.section.plugins.irc=IRC-yhteys
+UpdateWindow.title=Vuzen p\u00e4ivitystoimenpiteet
+UpdateWindow.header=Seuraavat osat vaativat p\u00e4ivitt\u00e4mist\u00e4:
+UpdateWindow.columns.install=Asenna
+UpdateWindow.columns.name=Nimi
+UpdateWindow.columns.version=Versio
+UpdateWindow.columns.size=Koko
+UpdateWindow.cancel=Peruuta
+UpdateWindow.quit=Lopeta
+UpdateWindow.close=Sulje
+UpdateWindow.ok=P\u00e4ivit\u00e4
+UpdateWindow.restart=K\u00e4ynnist\u00e4 Vuze uudelleen
+UpdateWindow.status.downloading=Ladataan
+UpdateWindow.status.done=Valmis
+UpdateWindow.status.failed=P\u00e4ivitys ep\u00e4onnistui
+UpdateWindow.status.restartNeeded=P\u00e4ivitt\u00e4minen vaatii Vuzen uudelleenk\u00e4ynnistyksen!
+ConfigView.pluginlist.broken=Ei kunnossa
+ConfigView.pluginlist.whereToPut=Aseta k\u00e4ytt\u00e4j\u00e4kohtaiset lis\u00e4osat omiin hakemistoihinsa seuraavan p\u00e4\u00e4hakemiston alle:
+ConfigView.pluginlist.whereToPutOr=Aseta kaikkien tietokoneen k\u00e4ytt\u00e4jien kesken jaetut lis\u00e4osat omiin hakemistoihinsa seuraavan p\u00e4\u00e4hakemiston alle:
+MainWindow.statusText.checking=Tarkastetaan p\u00e4ivitykset...
+TableColumn.header.OnlyCDing4=Tod. l\u00e4h.aika
+TableColumn.header.OnlyCDing4.info=Torrent-tiedoston l\u00e4hetysaika sen latauksen valmistumisesta l\u00e4htien.
+UpdateWindow.status.restartMaybeNeeded=P\u00e4ivitys vaatii ehk\u00e4 uud.k\u00e4ynnistyksen.
+ConfigView.pluginlist.shared=jaettu
+PeersView.host=Verkko-osoite
+PeersView.host.info=K\u00e4ytt\u00e4j\u00e4n symbolinen verkko-osoite, jos saatavilla.
+MainWindow.menu.help.whatsnew=Mit\u00e4 uutta t\u00e4ss\u00e4 versiossa?
+ConfigView.label.checkonstart=Tarkasta saatavilla olevat p\u00e4ivitykset k\u00e4ynnistett\u00e4ess\u00e4
+ConfigView.label.periodiccheck=Tarkasta saatavilla olevat p\u00e4ivitykset s\u00e4\u00e4nn\u00f6llisesti uudestaan
+ConfigView.label.opendialog=K\u00e4ynnist\u00e4 P\u00e4ivitysavustaja automaattisesti, jos p\u00e4ivitys on saatavilla
+MainWindow.updateavail=(P\u00e4ivitys saatavilla)
+MainWindow.status.unofficialversion=Vuze beetaversio
+MainWindow.status.latestversionunchecked=Uusimman version tarkastus ei k\u00e4yt\u00f6ss\u00e4
+GeneralView.label.updatein.stopped=Pys\u00e4ytetty
+StartStopRules.menu.viewDebug=Katso virheenm\u00e4\u00e4ritystiedot
+ConfigView.section.style.doNotUseGB=\u00c4l\u00e4 k\u00e4yt\u00e4 yksik\u00f6iss\u00e4 gigatavuja
+ConfigView.section.style.doNotUseGB.tooltip=Vuze jatkaa megatavujen k\u00e4ytt\u00e4mist\u00e4 yksikk\u00f6n\u00e4,\nkun luku ylitt\u00e4\u00e4 1024 Mt:a (yhden gigatavun).
+MainWindow.menu.help.plugins=Lis\u00e4osat
+ConfigView.section.plugins.TrackerWeb=Seurantapalvelimen sivu
+ConfigView.section.tracker.enablecategories=N\u00e4yt\u00e4 torrent-tiedostot omissa luokissaan
+health.explain.share=Torrent-tiedosto on joko asetettu seurantaan omalle seurantapalvelimelle tai julkistettu.
+ConfigView.section.tracker.createcert=Luo itseallekirjoitettu varmenne
+ConfigView.section.tracker.createbutton=Luo...
+security.certcreate.title=Itseallekirjoitettu varmenne
+security.certcreate.intro=T\u00e4ll\u00e4 toiminnolla voit luoda itseallekirjoitetun varmenteen.
+security.certcreate.alias=Nimi
+security.certcreate.strength=Vahvuus
+security.certcreate.firstlastname=Etu- ja sukunimi
+security.certcreate.orgunit=Organisaatioyksikk\u00f6
+security.certcreate.org=Organisaatio
+security.certcreate.city=Kaupunki
+security.certcreate.state=Maakunta
+security.certcreate.country=Kaksikirjaiminen maakoodi
+security.certcreate.ok=Luo
+security.certcreate.cancel=Peruuta
+security.certcreate.createok=Varmenne luotiin onnistuneesti.
+security.certcreate.createfail=Varmenteen luonti ep\u00e4onnistui.
+ConfigView.section.plugins.webui=Swing-et\u00e4k\u00e4ytt\u00f6liittym\u00e4
+ConfigView.section.plugins.xml_http_if=XML/HTTP-et\u00e4k\u00e4ytt\u00f6liittym\u00e4
+webui.passwordenable=K\u00e4yt\u00e4 salasanasuojausta
+webui.user=K\u00e4ytt\u00e4j\u00e4tunnus
+webui.password=Salasana
+webui.port=Portti
+webui.protocol=Protokolla
+webui.homepage=Kotisivu
+webui.rootdir=P\u00e4\u00e4hakemisto
+webui.rootres=P\u00e4\u00e4resurssi
+webui.mode=Hallintatila
+webui.mode.info=Hallintatila voi olla\n\t"full"\t= k\u00e4ytt\u00e4j\u00e4 pystyy hallitsemaan kaikkia et\u00e4k\u00e4ytt\u00f6liittym\u00e4n toimintoja (oletusasetus)\n\t"view"\t= k\u00e4ytt\u00e4j\u00e4 pystyy vaihtamaan vain et\u00e4k\u00e4ytt\u00f6liittym\u00e4n p\u00e4ivitysnopeutta, muilta osin pelkk\u00e4 katseluoikeus
+webui.access=P\u00e4\u00e4syoikeus
+webui.access.info=P\u00e4\u00e4syoikeus voi olla\n\t"local"\t= yhteys sallitaan vain paikalliselta koneelta, eli silt\u00e4 koneelta, jolla Vuze on k\u00e4ynniss\u00e4\n\t"all"\t= rajoittamaton p\u00e4\u00e4syoikeus, kaikki yhteydet sallitaan (oletusasetus)\n\tIP\t= esim. 192.168.0.2 (yhteys sallitaan yksitt\u00e4isest\u00e4 IP-osoitteesta)\n\tIP1-IP2\t= esim. 192.168.0.1-192.168.0.255 (yhteydet sallitaan tietylt\u00e4 IP-osoitev\u00e4lilt\u00e4)
+GeneralView.label.maxdownloadspeed=Enimm\u00e4islatausnopeus
+Security.keystore.corrupt=Keystore-tiedostoa '%1' ei voitu ladata; poista se ja luo/hae varmenteet uudelleen.
+Security.keystore.empty=Keystore-tiedosto on tyhj\u00e4; luo joko itseallekirjoitettu varmenne (katso Ty\u00f6kalut | Asetukset | Suojaus) tai hae olemassa oleva varmenne tiedostolle '%1'.
+GeneralView.label.maxdownloadspeed.tooltip=- enimm\u00e4islatausnopeus (0 = rajoittamaton)
+ConfigView.section.UPnP=UPnP-m\u00e4\u00e4ritys
+upnp.enable=K\u00e4yt\u00e4 UPnP:t\u00e4
+upnp.info=Universal Plug and Play (UPnP) mahdollistaa automaattisen porttien m\u00e4\u00e4ritt\u00e4misen niihin verkkolaitteisiin, joissa UPnP on k\u00e4ytett\u00e4viss\u00e4.
+upnp.mapping.dataport=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
+upnp.mapping.tcptrackerport=Seurantapalvelimen TCP-portti
+upnp.mapping.udptrackerport=Seurantapalvelimen UDP-portti
+upnp.alert.differenthost=UPnP: M\u00e4\u00e4rityksen '%1' on varannut '%2' - valitse jokin toinen portti
+upnp.alert.mappingok=UPnP: M\u00e4\u00e4ritys '%1' muodostettu
+upnp.alert.mappingfailed=UPnP: M\u00e4\u00e4ritys '%1' ep\u00e4onnistui
+upnp.alertsuccess=Ilmoita onnistuneista m\u00e4\u00e4rityksist\u00e4
+upnp.alert.lostdevice=UPnP: Yhteys palveluun '%1' UPnP-laitteessa '%2' menetettiin
+upnp.grabports=M\u00e4\u00e4rit\u00e4 portit, vaikka ne olisivat toisen tietokoneen k\u00e4yt\u00f6ss\u00e4
+upnp.refresh.label=P\u00e4ivit\u00e4 m\u00e4\u00e4ritykset
+upnp.refresh.button=P\u00e4ivit\u00e4
+upnp.alert.mappinggrabbed=UPnP: M\u00e4\u00e4ritys '%1' muodostettu - haettu kohteelta '%2'
+upnp.mapping.tcpssltrackerport=Seurantapalvelimen TCP-portti (SSL)
+upnp.alertothermappings=Ilmoita porteista, jotka ovat toisen tietokoneen k\u00e4yt\u00f6ss\u00e4
+upnp.alertdeviceproblems=Ilmoita UPnP-laitteen ongelmatilanteista
+upnp.trace_to_log=Tulosta kaikki virheenm\u00e4\u00e4ritystiedot lokiin
+upnp.wiki_link=Katso lis\u00e4tietoja t\u00e4st\u00e4
+upnp.refresh_mappings_on_bad_nat=P\u00e4ivit\u00e4 porttim\u00e4\u00e4ritykset automaattisesti, jos NAT status on "firewalled"
+ConfigView.pluginlist.coreplugins=Seuraavat sis\u00e4\u00e4nrakennetut lis\u00e4osat ovat k\u00e4yt\u00f6ss\u00e4:
+Peers.column.DLedFromOthers=Muilta
+Peers.column.DLedFromOthers.info=K\u00e4ytt\u00e4j\u00e4n muilta lataama tietom\u00e4\u00e4r\u00e4 t\u00e4m\u00e4n yhteyden ollessa voimassa.
+Peers.column.UpDownRatio=L\u00e4h:Lad
+Peers.column.UpDownRatio.info=K\u00e4ytt\u00e4j\u00e4n l\u00e4hetys-lataussuhde.
+Peers.column.UpRatio=L\u00e4h.suhteet
+Peers.column.UpRatio.info=Oma l\u00e4hetysm\u00e4\u00e4r\u00e4 suhteessa muiden l\u00e4hetysm\u00e4\u00e4r\u00e4\u00e4n ko. k\u00e4ytt\u00e4j\u00e4lle.
+upnp.releasemappings=Vapauta porttim\u00e4\u00e4ritykset lopetettaessa
+webui.upnpenable=K\u00e4yt\u00e4 UPnP:t\u00e4 t\u00e4lle portille
+ConfigView.section.file.friendly.hashchecking=K\u00e4yt\u00e4 resurssiyst\u00e4v\u00e4llist\u00e4 tapaa osien tarkastamiseen
+ConfigView.section.file.friendly.hashchecking.tooltip=Osien tiivisteet lasketaan ja tarkastetaan hieman hitaammin kuin normaalissa tilassa,\nmutta v\u00e4hemmill\u00e4 resursseilla (suoritink\u00e4ytt\u00f6/muistin k\u00e4ytt\u00f6).
+ConfigView.section.tracker.seedretention=S\u00e4ilytett\u00e4vien l\u00e4hteiden enimm\u00e4ism\u00e4\u00e4r\u00e4/torrent-tiedosto\n(0 = rajoittamaton)
+ConfigView.section.tracker.seedretention.info=Huom.: Muista l\u00e4hteist\u00e4 ei saada l\u00e4hetystilastoja.
+ConfigView.section.tracker.port=K\u00e4yt\u00e4 HTTP-porttia
+ConfigView.section.tracker.sslport=K\u00e4yt\u00e4 HTTPS-porttia
+ConfigView.section.tracker.publicenable.info=Sallii muiden k\u00e4ytt\u00e4\u00e4 seurantapalvelintasi ilman,\nett\u00e4 sin\u00e4 itse asetat torrent-tiedostoja seurantaan/julkaiset niit\u00e4.
+Button.clear=Tyhjenn\u00e4
+MainWindow.IPs.tooltip=IP-suotimien viimeisin p\u00e4ivitys: %1\nIP-suodinosoitealueiden m\u00e4\u00e4r\u00e4\n-> k\u00e4ytt\u00e4j\u00e4t t\u00e4m\u00e4n session aikana, jotka on\n- estetty IP-suotimien toimesta\n- estetty muutoin\n- ovat l\u00e4hett\u00e4neet korruptoitunutta tietoa.\nTuplaklikkaa n\u00e4hd\u00e4ksesi tarkemmat tiedot.
+ConfigView.section.ipfilter.list.banned=- yhteydenotto estetty
+ConfigView.section.ipfilter.list.baddata=l\u00e4hetti korruptoitunutta tietoa, esiintym\u00e4t:
+Button.reset=Tyhjenn\u00e4
+ConfigView.section.ipfilter.bannedinfo=Korruptoitunutta tietoa l\u00e4hett\u00e4neet - estetty tietyn rajan ylitytty\u00e4.
+ConfigView.section.ipfilter.blockedinfo=IP-suotimien toimesta estetyt yhteydet.
+download.removerules.name=Poistamiss\u00e4\u00e4nn\u00f6t
+download.removerules.unauthorised.info=Luvattomat torrent-tiedostot ovat sellaisia, jotka palauttavat virheilmoituksena joko tekstin "not authoris(z)ed" tai "unauthoris(z)ed" seurantapalvelimen tilaa tiedusteltaessa.
+download.removerules.unauthorised=Poista automaattisesti luvattomat torrent-tiedostot
+download.removerules.unauthorised.seedingonly=\tVain jos torrent-tiedostoa l\u00e4hetet\u00e4\u00e4n (lataus jo valmistunut)
+download.removerules.removed.ok=Torrent-tiedoston '%1' poistaminen onnistui. T\u00e4m\u00e4 tapahtui poistamiss\u00e4\u00e4nt\u00f6jen johdosta.
+download.removerules.updatetorrents=Poista automaattisesti p\u00e4ivitt\u00e4miseen k\u00e4ytetyt torrent-tiedostot, jos l\u00e4hett\u00e4miselle ei en\u00e4\u00e4 ole tarvetta
+ConfigView.label.defaultstarttorrentsstopped=Aseta avatut torrent-tiedostot oletuksena pys\u00e4ytetty-tilaan
+ConfigView.section.server.enableudp=K\u00e4yt\u00e4 UDP-protokollaa seurantapalvelinyhteyksiin
+upnp.mapping.dataportudp=Sis\u00e4\u00e4ntulevan UDP-liikenteen portti
+ConfigView.section.file.decoder.showlax=N\u00e4yt\u00e4 ep\u00e4todenn\u00e4k\u00f6iset koodausvaihtoehdot
+ConfigView.section.file.decoder.showall=Luettele kaikki mahdolliset koodausvaihtoehdot
+MainWindow.status.updowndetails.tooltip=Lataus- ja l\u00e4hetysnopeudet\n - Vaihda rajoituksia klikkaamalla hiiren kakkospainikkeella ja valitsemalla haluamasi arvot\n - Tuplaklikkaus avaa tilastot
+TrackerClient.announce.warningmessage=Torrent-tiedoston '%1' seurantapalvelin palautti varoituksen '%2'.
+ConfigView.section.tracker.natcheckenable=Tarkasta k\u00e4ytt\u00e4j\u00e4n sis\u00e4\u00e4ntulevan TCP-liikenteen portin toimivuus ja ilmoita ongelmista
+ConfigView.section.tracker.publishenabledetails=Julkaise kaikki tarkat tiedot torrent-tiedostoista
+ConfigView.section.tracker.publishenablepeerdetails=Julkaise tarkat tiedot k\u00e4ytt\u00e4jist\u00e4
+MyTrackerView.badnat=NAT-ongelmat
+MyTrackerView.badnat.info=K\u00e4ytt\u00e4j\u00e4t, jotka eiv\u00e4t l\u00e4p\u00e4isseet NAT-testi\u00e4 (jos testaus k\u00e4yt\u00f6ss\u00e4).
+ConfigView.section.tracker.natchecktimeout=Tarkastuksen aikakatkaisu (s)
+ConfigView.section.file.perf.cache.enable=K\u00e4yt\u00e4 v\u00e4limuistia
+ConfigView.section.file.perf.cache.size=V\u00e4limuistin koko (%1)
+MainWindow.menu.transfers=&Siirrot
+MainWindow.menu.transfers.startalltransfers=&K\u00e4ynnist\u00e4 kaikki
+MainWindow.menu.transfers.stopalltransfers=&Pys\u00e4yt\u00e4 kaikki
+MainWindow.menu.transfers.pausetransfers=K&eskeyt\u00e4
+MainWindow.menu.transfers.resumetransfers=&Jatka keskeytettyj\u00e4
+ConfigView.label.experimental.osx.kernel.panic.fix=Korjaa kaksiytimisten OSX-koneiden kernel panic -ongelmat (vaatii uud.k\u00e4yn.)
+SystemTray.menu.pausetransfers=K&eskeyt\u00e4 siirrot
+SystemTray.menu.resumetransfers=Jatka keskeytettyj\u00e4 siirtoja
+ConfigView.section.file.truncate.too.large=Pienenn\u00e4 olemassa olevat liian isot tiedostot oikeaan kokoonsa
+ConfigView.section.file.perf.cache.trace=J\u00e4ljit\u00e4 v\u00e4limuistioperaatiot virheenm\u00e4\u00e4rityst\u00e4 varten
+ConfigView.section.interface.enabletray=N\u00e4yt\u00e4 Vuzen kuvake ilmoitusalueella (vaatii uudelleenk\u00e4ynnistyksen)
+PeerManager.status.error=Virhe
+Stats.title.full=Tilastot
+TransferStatsView.title.full=Siirrot ja k\u00e4ytt\u00f6aika
+CacheView.title.full=V\u00e4limuisti
+CacheView.general.size=Koko yhteens\u00e4
+CacheView.general.inUse=K\u00e4yt\u00f6ss\u00e4
+CacheView.general.title=Tila
+CacheView.reads.title=Siirr\u00e4nt\u00e4luvut
+CacheView.reads.fromFile=Tiedostosta
+CacheView.reads.fromCache=V\u00e4limuistista
+CacheView.reads.hits=k\u00e4ytt\u00f6
+CacheView.writes.title=Siirr\u00e4nt\u00e4kirjoitukset
+CacheView.writes.toCache=V\u00e4limuistiin
+CacheView.writes.toFile=Tiedostoon
+CacheView.writes.hits=s\u00e4\u00e4stetty
+CacheView.speeds.title=Luku- ja kirjoitusnopeudet
+CacheView.speeds.reads=Luvut
+CacheView.speeds.writes=Kirjoitukset
+CacheView.speeds.fromCache=V\u00e4limuistista/\nv\u00e4limuistiin
+CacheView.speeds.fromFile=Tiedostosta/\ntiedostoon
+CacheView.reads.#=Kertaa
+CacheView.reads.amount=M\u00e4\u00e4r\u00e4
+CacheView.reads.avgsize=Keskim\u00e4\u00e4r\u00e4inen koko
+openUrl.referrer=Viittaavan sivun osoite:
+openUrl.referrer.info=Tarvitaan vain, jos sivusto vaatii t\u00e4t\u00e4.
+ConfigView.label.maxuploadspeedseeding=Vaihtoehtoinen nopeus ainoastaan l\u00e4hetett\u00e4ess\u00e4
+ConfigView.label.transfer.ignorepeerports=Est\u00e4 k\u00e4ytt\u00e4j\u00e4, jos sis\u00e4\u00e4ntulevan TCP-liikenteen porttina on (erota ;-merkill\u00e4, esim. 0;25)
+ConfigView.section.proxy.enable_socks.peer=K\u00e4yt\u00e4 v\u00e4lityspalvelinta (yhteydet ulosp\u00e4in, vaatii uudelleenk\u00e4ynnistyksen)
+ConfigView.section.proxy.peer.informtracker=Ilmoita seurantapalvelimelle, ett\u00e4 sis\u00e4\u00e4ntulevia yhteyksi\u00e4 ei voida ottaa vastaan
+ConfigView.section.proxy.socks.version=SOCKS-versio
+PiecesView.legend.written=Kirjoitettu levylle
+PiecesView.legend.requested=Pyydetty
+PiecesView.legend.downloaded=Ladattu, odottaa kirjoittamista
+PiecesView.legend.incache=Tieto on v\u00e4limuistissa
+PiecesView.typeItem.0=Hidas
+PiecesView.typeItem.1=Nopea
+PiecesView.type=Tyyppi
+Security.jar.tools_not_found=JAR-allekirjoitus ep\u00e4onnistui - tools.jar-tiedostoa ei l\u00f6ytynyt kohteesta %1. Katso lis\u00e4tietoja kohdasta Ty\u00f6kalut | Asetukset | Suojaus.
+Security.jar.signfail=JAR-allekirjoitus ep\u00e4onnistui - %1
+ConfigView.section.security.toolsinfo=Er\u00e4\u00e4t Vuzen lis\u00e4osat, kuten Swing-et\u00e4k\u00e4ytt\u00f6liittym\u00e4, k\u00e4ytt\u00e4v\u00e4t tarvittaessa ns. varmennettuja JAR-tiedostoja.\n\nJAR-tiedostojen varmentamiseen tarvitset tools.jar-tiedoston, joka tulee Sunin JDK:n (Java Development Kit) mukana.\nJos olet asentanut vain JRE:n (Java Runtime Environment), tarvitsee sinun siis asentaa JDK.\n\nYleens\u00e4 Vuze l\u00f6yt\u00e4\u00e4 tools.jar-tiedoston sijainnin automaatt [...]
+ConfigView.section.security.toolsdir=Tools.jar-tiedoston sijainti
+ConfigView.section.security.choosetoolssavedir=Valitse tools.jar-tiedoston sis\u00e4lt\u00e4v\u00e4 hakemisto
+authenticator.torrent=Torrent-tiedosto
+ConfigView.section.proxy.peer.same=K\u00e4yt\u00e4 samaa v\u00e4lityspalvelinta kuin yhteyksiss\u00e4 seurantapalvelimiin
+ConfigView.section.connection.network.max.simultaneous.connect.attempts=Yht\u00e4aikaisesti ulosp\u00e4in luotavien yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Huom.: Windows XP -tuoteperheen SP2-p\u00e4ivityspaketti rajoittaa automaattisesti ulosp\u00e4in luotavat yhteydet kymmeneen.\nAsetuksen oletusarvo on 8.
+ConfigView.section.file.perf.cache.size.explain=V\u00e4limuistia k\u00e4ytet\u00e4\u00e4n v\u00e4hent\u00e4m\u00e4\u00e4n tiedon lukua kiintolevylt\u00e4/kirjoittamista kiintolevylle. Jos et k\u00e4yt\u00e4 Javan -XX:MaxDirectMemorySize -asetusta muistim\u00e4\u00e4r\u00e4n asettamiseen v\u00e4limuisti- ja verkkosiirr\u00e4nt\u00e4k\u00e4ytt\u00f6\u00e4 varten, sinun tulisi pit\u00e4\u00e4 t\u00e4m\u00e4 arvo v\u00e4hint\u00e4\u00e4n %1:\u00e4 alle virtuaalimuistisi enimm\u00e4ism\u00e4\ [...]
+MyTorrentsView.menu.setSpeed.unlimit=Rajoittamaton
+MyTorrentsView.menu.setSpeed.unlimited=Rajoittamaton
+MyTorrentsView.menu.setSpeed.disable=\u00c4l\u00e4 l\u00e4het\u00e4
+MyTorrentsView.menu.setSpeed.disabled=Ei l\u00e4hetet\u00e4
+MyTorrentsView.menu.setSpeed.in=jaettuna
+MyTorrentsView.menu.setSpeed.slots=paikkaan, kullekin
+GeneralView.label.maxuploadspeed=Enimm\u00e4isl\u00e4hetysnopeus
+GeneralView.label.maxuploadspeed.tooltip=- enimm\u00e4isl\u00e4hetysnopeus (0 = rajoittamaton)
+MyTorrents.items.UpSpeedLimit.disabled=Ei l\u00e4hetet\u00e4
+MyTorrents.items.UpSpeedLimit.unlimited=Rajoittamaton
+TableColumn.header.maxupspeed=Enim.l\u00e4h.nopeus
+TableColumn.header.maxupspeed.info=Torrent-tiedoston enimm\u00e4isl\u00e4hetysnopeus.
+ConfigView.section.file.perf.cache.enable.write=Siirr\u00e4 ladattu tieto v\u00e4limuistiin levylle kirjoituksen v\u00e4hent\u00e4miseksi ja levylt\u00e4 lukemisen v\u00e4hent\u00e4miseksi osia tarkastettaessa
+ConfigView.section.file.perf.cache.enable.read=Lue tiedostoja ennakoidusti v\u00e4limuistiin levylt\u00e4 lukemisen v\u00e4hent\u00e4miseksi tiedostoja l\u00e4hetett\u00e4ess\u00e4
+ConfigView.section.tracker.separatepeerids=K\u00e4yt\u00e4 eri k\u00e4ytt\u00e4j\u00e4tunnisteita seurantapalvelin- ja tiedonsiirtoyhteyksiss\u00e4
+ConfigView.section.tracker.separatepeerids.info=Lis\u00e4\u00e4 anonymiteettia, jos siirret\u00e4\u00e4n tietoa anonyymisti\nk\u00e4ytett\u00e4ess\u00e4 ei-anonyymista yhteytt\u00e4 seurantapalvelimeen.
+ConfigView.section.interface.wavlocation=Valitse .wav-tiedosto
+ConfigView.section.interface.wavlocation.info=.wav tai j\u00e4t\u00e4 tyhj\u00e4ksi (oletus\u00e4\u00e4ni)
+ConfigView.section.tracker.server=Oma seurantapalvelin
+ConfigView.section.tracker.client=Asiakasyhteys
+ConfigView.section.tracker.client.connecttimeout=Yhteydenoton aikakatkaisu (sekunneissa)
+ConfigView.section.tracker.client.readtimeout=Tietojen vastaanottamisen aikakatkaisu (sekunneissa)
+MainWindow.menu.tools=Ty&\u00f6kalut
+FilesView.path=Hakemisto
+FilesView.fullpath=N\u00e4yt\u00e4 koko polku
+FilesView.remaining=Osia j\u00e4ljell\u00e4
+TableColumn.header.trackername=Seurantapalvelin
+TableColumn.header.trackername.info=Seurantapalvelimen nimi perustuen sen p\u00e4ivitysosoitteeseen.
+ConfigView.group.override=Ohitusasetukset
+ConfigView.section.file.perf.cache.notsmallerthan=\u00c4l\u00e4 siirr\u00e4 t\u00e4st\u00e4 pienempi\u00e4 tiedostoja v\u00e4limuistiin (%1)
+PeersView.menu.blockupload=Est\u00e4 l\u00e4hett\u00e4minen
+PeersView.menu.kickandban=Sulje yhteys ja est\u00e4 yhteydenotot
+PeersView.menu.kickandban.reason=Manuaalisesti estetty
+PeersView.state=Tila
+PeersView.state.info=Yhteyden tila k\u00e4ytt\u00e4j\u00e4\u00e4n.
+PeersView.state.pending=Odottava
+PeersView.state.connecting=Yhdistet\u00e4\u00e4n
+PeersView.state.handshake=Odotetaan k\u00e4ttely\u00e4
+PeersView.state.established=Muodostettu
+ConfigView.section.tracker.processinglimits=K\u00e4sittelyrajoitukset
+ConfigView.section.tracker.maxgettime=GET-k\u00e4sittelyn enimm\u00e4isaika sekunneissa (0 = rajoittamaton)
+ConfigView.section.tracker.maxgettime.info=K\u00e4ytet\u00e4\u00e4n p\u00e4ivityksiss\u00e4 ja pikap\u00e4ivityksiss\u00e4.
+ConfigView.section.tracker.maxposttimemultiplier=GET-ajan kerroin POST-k\u00e4sittelylle (0 = rajoittamaton)
+ConfigView.section.tracker.maxposttimemultiplier.info=K\u00e4ytet\u00e4\u00e4n lomaketietojen l\u00e4hett\u00e4misess\u00e4 ja siirroissa.
+ConfigView.section.tracker.maxthreads=Yht\u00e4aikaisten pyynt\u00f6jen enimm\u00e4ism\u00e4\u00e4r\u00e4
+DownloadManager.error.operationcancancelled=Toiminto peruutettu
+Torrent.create.progress.cancelled=Toiminto peruutettu
+sharing.progress.cancel=Peruuta
+wizard.maketorrents.autoopen=Kun torrent-tiedosto on luotu, avaa se suoraan l\u00e4hetett\u00e4v\u00e4ksi
+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.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 - E [...]
+ConfigView.section.connection.advanced.SO_RCVBUF=Pistokkeen SO_RCVBUF-koko (0 = k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n oletusarvo)
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=SO_RCVBUF-arvolla m\u00e4\u00e4ritell\u00e4\u00e4n pistokkeen vastaanottopuskurin koko tavuissa.\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nHuom.: Linux-k\u00e4yt\u00f6ss\u00e4 arvo kaksinkertaistuu automaattisesti.
+ConfigView.section.connection.advanced.SO_SNDBUF=Pistokkeen SO_SNDBUF-koko (0 = k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n oletusarvo)
+ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=SO_SNDBUF-arvolla m\u00e4\u00e4ritell\u00e4\u00e4n pistokkeen l\u00e4hetyspuskurin koko tavuissa.\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nHuom.: Linux-k\u00e4yt\u00f6ss\u00e4 arvo kaksinkertaistuu automaattisesti.
+ConfigView.section.connection.advanced.IPDiffServ=Ulosmenevien pakettien liikenteen luokka/palvelu (TOS / type-of-service)
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=Voit m\u00e4\u00e4ritt\u00e4\u00e4 ulosmenevien pakettien IP-otsakkeisiin liikenteen luokan/palvelun (type-of-service).\nVuze ei itse m\u00e4\u00e4rittele t\u00e4t\u00e4 oletusarvoisesti ollenkaan, joten k\u00e4yt\u00f6ss\u00e4 ovat k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4n asettamat arvot.\nEsimerkkej\u00e4 mahdollisista arvoista:\n0x02 = IPTOS_LOWCOST\n0x04 = IPTOS_RELIABILITY\n0x08 = IPTOS_THROUGHPUT\n0x10 = IPTOS_LOWDELAY\nHuom.: [...]
+TableColumn.header.seed_to_peer_ratio=K\u00e4ytt\u00e4j\u00e4suhde
+TableColumn.header.seed_to_peer_ratio.info=Kaikkien l\u00e4hteiden lukum\u00e4\u00e4r\u00e4n suhde kaikkien lataajien lukum\u00e4\u00e4r\u00e4\u00e4n.
+PeersView.connected_time=Aika
+PeersView.connected_time.info=Yhteysaika k\u00e4ytt\u00e4j\u00e4\u00e4n.
+TableColumn.header.maxdownspeed=Enim.lat.nopeus
+TableColumn.header.maxdownspeed.info=Torrent-tiedoston enimm\u00e4islatausnopeus.
+PeersGraphicView.title.full=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
+ConfigView.section.sharing.torrentcomment=Kommentti, joka lis\u00e4t\u00e4\u00e4n luotaviin torrent-tiedostoihin
+ConfigView.label.copyanddeleteratherthanmove=Kopioi ja poista alkuper\u00e4iset tiedostot siirt\u00e4misen sijaan - ehk\u00e4isee tietojen menett\u00e4mist\u00e4 ongelmatilanteissa
+ConfigView.label.openstatsonstart=Avaa tilastot k\u00e4ynnistett\u00e4ess\u00e4
+swt.install.window.title=Vuzen lis\u00e4osien asennus
+swt.install.window.ok=Asenna
+swt.install.window.header=Seuraavat osat on valittu asennettavaksi:
+swt.uninstall.window.title=Vuzen lis\u00e4osien poistaminen
+swt.uninstall.window.ok=Poista
+swt.uninstall.window.header=Seuraavat osat on valittu poistettavaksi:
+installPluginsWizard.title=Asenna lis\u00e4osia
+installPluginsWizard.mode.title=Valitse lis\u00e4osien l\u00e4hde
+installPluginsWizard.mode.list=Valitsemalla listasta (ladataan SourceForge.netist\u00e4)
+installPluginsWizard.list.title=Asennettavat lis\u00e4osat
+installPluginsWizard.list.loading=Odota hetki, kunnes lis\u00e4osien lista on ladattu.
+installPluginsWizard.list.loaded=Valitse lis\u00e4osat, jotka haluat asentaa:
+installPluginsWizard.list.name=Nimi
+installPluginsWizard.list.version=Versio
+installPluginsWizard.list.description=Lis\u00e4osan kuvaus:
+installPluginsWizard.finish.title=Asennus k\u00e4ynniss\u00e4
+installPluginsWizard.finish.explanation=Valitut lis\u00e4osat asennetaan k\u00e4ytt\u00e4en Vuzen P\u00e4ivitysavustajaa.\n\nOle k\u00e4rsiv\u00e4llinen, sill\u00e4 P\u00e4ivitysavustajan ilmestyminen ruudulle\nsaattaa kest\u00e4\u00e4 hetkisen.
+installPluginsWizard.details.loading=Ladataan tietoja, odota hetki...
+installPluginsWizard.mode.file=Suoraan tiedostosta
+installPluginsWizard.installMode.title=Valitse asennustapa
+installPluginsWizard.installMode.user=Asenna lis\u00e4osa(t) vain sinun k\u00e4ytt\u00f6\u00f6si
+installPluginsWizard.installMode.shared=Asenna lis\u00e4osa(t) kaikille tietokoneen k\u00e4ytt\u00e4jille
+installPluginsWizard.file.title=Etsi lis\u00e4osa, jonka haluat asentaa.
+installPluginsWizard.file.file=Tiedosto:
+installPluginsWizard.file.invalidfile=Tiedosto ei ole kelvollinen Vuzen lis\u00e4osa.
+installPluginsWizard.file.no_such_file=Tiedostoa ei l\u00f6ydy.
+installPluginsWizard.file.browse=Selaa...
+uninstallPluginsWizard.title=Poista lis\u00e4osia
+uninstallPluginsWizard.list.title=Asennetut lis\u00e4osat
+uninstallPluginsWizard.list.loaded=Valitse lis\u00e4osat, jotka haluat poistaa:
+installPluginsWizard.list.nullversion=Ei versionumeroa
+uninstallPluginsWizard.finish.title=Poistaminen k\u00e4ynniss\u00e4
+uninstallPluginsWizard.finish.explanation=Valitut lis\u00e4osat poistetaan k\u00e4ytt\u00e4en P\u00e4ivitysavustajaa.
+MainWindow.menu.plugins.installPlugins=Ohjattu asennustoiminto...
+MainWindow.menu.plugins.uninstallPlugins=Ohjattu poistotoiminto...
+ConfigView.section.ipfilter.totalIPs=%1 IP-osoitetta estetty yhteens\u00e4, joka on %2 kaikista osoitteista Internetiss\u00e4.
+update.instance.install=Tarkastetaan asennusteht\u00e4v\u00e4t
+update.instance.uninstall=Tarkastetaan poistoteht\u00e4v\u00e4t
+update.instance.update=Tarkastetaan p\u00e4ivitykset
+MainWindow.status.update.tooltip=Tuplaklikkaa n\u00e4hd\u00e4ksesi tarkemmat tiedot edistymisest\u00e4.
+updater.progress.window.title=Asennusteht\u00e4v\u00e4t
+updater.progress.window.info=Valitse Keskeyt\u00e4 peruuttaaksesi kaikki suorittamattomat teht\u00e4v\u00e4t.
+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\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?
+ConfigView.label.prioritizemostcompletedfiles=Pyri lataamaan ensisijaisesti l\u00e4himp\u00e4n\u00e4 valmistumista olevia korkean prioriteetin tiedostoja
+splash.plugin.init=Alustetaan lis\u00e4osaa - 
+splash.plugin.UIinit=Alustetaan lis\u00e4osan graafista k\u00e4ytt\u00f6liittym\u00e4\u00e4: %1
+ConfigView.section.style.osx_small_fonts=K\u00e4yt\u00e4 pieni\u00e4 kirjasinkokoja (vaatii uudelleenk\u00e4ynnistyksen)
+ConfigView.section.tracker.tcpnonblocking=K\u00e4yt\u00e4 ei-rajoittavaa siirr\u00e4nt\u00e4\u00e4 TCP-k\u00e4sittelyss\u00e4. Jos k\u00e4yt\u00f6ss\u00e4, seurantapalvelimen sivun t\u00e4ytyy k\u00e4ytt\u00e4\u00e4 toista porttia. Kokeellinen!
+ConfigView.section.tracker.nonblocking=Siirr\u00e4nn\u00e4n rajoittaminen
+ConfigView.section.tracker.nonblockingconcmax=Yht\u00e4aikaisten yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
+MyTorrentsView.menu.exportmenu=Vie
+MyTorrentsView.menu.exporttorrent=torrent-tiedostoksi...
+ConfigView.group.scrape=Pikap\u00e4ivitykset
+ConfigView.section.tracker.client.scrapeinfo=Pikap\u00e4ivitysten ohittaminen est\u00e4\u00e4 monien siirtojonos\u00e4\u00e4nt\u00f6jen toimimisen, sill\u00e4 ne ovat riippuvaisia seurantapalvelimien pikap\u00e4ivitystiedoista.
+ConfigView.section.tracker.client.scrapeenable=K\u00e4yt\u00e4 pikap\u00e4ivityksi\u00e4
+ConfigView.section.tracker.client.scrapestoppedenable=Tee pikap\u00e4ivitykset pys\u00e4ytetyille torrent-tiedostoille
+Scrape.status.disabled=Pikap\u00e4ivitys ei k\u00e4yt\u00f6ss\u00e4
+MyTorrentsView.menu.explore=N\u00e4yt\u00e4
+MyTorrentsView.menu.explore._mac=N\u00e4yt\u00e4 Finderissa
+MyTorrentsView.menu.explore._windows=N\u00e4yt\u00e4 Windows Explorerissa
+wizard.maketorrents.autohost=Aseta torrent-tiedosto seurantaan omalle seurantapalvelimelle
+ConfigView.label.overrideip=Ohita seurantapalvelimelle n\u00e4kyv\u00e4 IP-osoite - erota puolipisteill\u00e4, jos useita osoitteita eri verkoille
+ConfigView.label.overrideip.tooltip=Ilmoittaa seurantapalvelimelle m\u00e4\u00e4ritetyn IP-osoitteen (tai osoitteet) sen sijaan, mist\u00e4 tietoa oikeasti l\u00e4hetet\u00e4\u00e4n.\nJ\u00e4t\u00e4 tyhj\u00e4ksi, jos et halua k\u00e4ytt\u00e4\u00e4 t\u00e4t\u00e4 asetusta.
+ConfigView.section.connection.group.networks=Verkot
+ConfigView.section.connection.group.networks.info=Valitse oletusverkot, joissa sallitaan varsinaisen siirrett\u00e4v\u00e4n tiedon liikkuminen
+ConfigView.section.connection.networks.prompt=Kysy valintaa, jos torrent-tiedosto k\u00e4ytt\u00e4\u00e4 anonyymista seurantapalvelinta (verkkoa)
+ConfigView.section.connection.networks.Public=Julkinen IP-verkko (ei anonyyminen)
+ConfigView.section.connection.networks.I2P=I2P-verkko
+ConfigView.section.connection.networks.Tor=The Onion Router (Tor) -verkko
+TableColumn.header.networks=Verkot
+TableColumn.header.networks.info=Verkot, joissa sallitaan varsinaisen siirrett\u00e4v\u00e4n tiedon liikkuminen.
+Scrape.status.networkdisabled=Verkko ei k\u00e4ytett\u00e4viss\u00e4
+ConfigView.section.tracker.server.group.networks=Verkot
+ConfigView.section.tracker.server.group.networks.info=Valitse verkot, joihin hyv\u00e4ksyt\u00e4\u00e4n k\u00e4ytt\u00e4ji\u00e4:
+window.networkselection.title=Verkkojen valitseminen
+window.networkselection.info=Alla olevan torrent-tiedoston seurantapalvelimet tukevat seuraavia verkkoja.\nValitse ne, joita haluat k\u00e4ytt\u00e4\u00e4 yhteyksiss\u00e4 seurantapalvelimiin ja k\u00e4ytt\u00e4jiin.\nJos kyseess\u00e4 on anonyyminen seurantapalvelin, joka tukee julkisia yhteyksi\u00e4, k\u00e4yt\u00e4 sek\u00e4\nanonyymista ett\u00e4 julkista verkkoa.\nJulkisen verkon k\u00e4ytt\u00e4misest\u00e4 seuraa luonnollisesti se, ett\u00e4 anonymiteetti h\u00e4vi\u00e4\u00e4.
+window.networkselection.description=Torrent-tiedosto:
+plugins.basicview.clear=Tyhjenn\u00e4
+ConfigView.section.connection.group.peersources=K\u00e4ytt\u00e4j\u00e4t
+ConfigView.section.connection.group.peersources.info=Valitse oletustietol\u00e4hteet, joista saadut k\u00e4ytt\u00e4j\u00e4t voivat muodostaa yhteyden
+ConfigView.section.connection.peersource.Tracker=Seurantapalvelimen palauttamat tiedot
+ConfigView.section.connection.peersource.DHT=Hajautettu k\u00e4ytt\u00e4jien seuranta (DHT)
+ConfigView.section.connection.peersource.PeerExchange=K\u00e4ytt\u00e4jien luovuttamat tiedot
+ConfigView.section.connection.peersource.Plugin=Lis\u00e4osan lis\u00e4\u00e4m\u00e4 yhteystieto
+ConfigView.section.connection.peersource.Incoming=Sis\u00e4\u00e4ntulevat yhteydet
+PeersView.source=L\u00e4hde
+PeersView.source.info=L\u00e4hde, josta kyseisen k\u00e4ytt\u00e4j\u00e4n tiedot on saatu selville.
+TableColumn.header.peersources=Tietol\u00e4hteet
+TableColumn.header.peersources.info=Tietol\u00e4hteet, joista saadut k\u00e4ytt\u00e4j\u00e4t voivat muodostaa yhteyden.
+wizard.tracker.dht=Hajautettu k\u00e4ytt\u00e4jien seuranta (vain Vuze-asiakasohjelmat)
+MyTorrentsView.menu.advancedmenu=Lis\u00e4asetukset
+MyTorrentsView.menu.networks=K\u00e4ytett\u00e4v\u00e4t verkot
+MyTorrentsView.menu.peersource=K\u00e4ytt\u00e4jien etsiminen
+ConfigView.section.sharing.permitdht=Hajautettu k\u00e4ytt\u00e4jien seuranta, kun seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4
+ConfigView.section.sharing.protocol=Protokolla jaetuille resursseille
+PeersView.Messaging=Viestint\u00e4
+PeersView.Messaging.info=K\u00e4ytett\u00e4v\u00e4 viestint\u00e4j\u00e4rjestelm\u00e4.
+ConfigView.label.queue.newseedsmovetop=Siirr\u00e4 viimeksi valmistuneet torrent-tiedostot l\u00e4hetysjonon k\u00e4rkeen
+ConfigView.label.seeding.firstPriority.ignore.info=Huomaa, ett\u00e4 n\u00e4iden ohituss\u00e4\u00e4nt\u00f6jen k\u00e4ytt\u00e4minen saattaa johtaa siihen, ett\u00e4\ntorrent-tiedosto pys\u00e4ytet\u00e4\u00e4n heti kun lataus on valmistunut.
+ConfigView.label.seeding.firstPriority.ignore=Ohita yll\u00e4 olevat s\u00e4\u00e4nn\u00f6t torrent-tiedostojen kohdalla
+ConfigView.label.seeding.firstPriority.ignoreSPRatio=joiden l\u00e4hteit\u00e4/lataajia-suhdeluku on yli
+ConfigView.label.seeding.firstPriority.ignore0Peer=joilla ei ole yht\u00e4\u00e4n lataajaa
+ConfigView.section.tracker.sendjavaversionandos=L\u00e4het\u00e4 tiedot Javan versiosta ja k\u00e4ytt\u00f6j\u00e4rjestelm\u00e4st\u00e4
+MagnetPlugin.contextmenu.exporturi=Kopioi Magnet URI -linkki leikep\u00f6yd\u00e4lle
+ConfigView.section.plugins.dht=Hajautettu tietokanta
+dht.info=T\u00e4m\u00e4 lis\u00e4osa mahdollistaa mm. hajautetun k\u00e4ytt\u00e4jien seurannan - k\u00e4ytt\u00e4m\u00e4tt\u00e4 j\u00e4tt\u00e4minen vaikuttaa alentavasti latausnopeuksiin.
+dht.enabled=K\u00e4yt\u00e4 hajautettua tietokantaa
+dht.portdefault=K\u00e4yt\u00e4 oletusporttia
+dht.port=Hajautetun tietokannan UDP-portti
+dht.execute.command=Virheenm\u00e4\u00e4rityskomento
+dht.execute.info=Suorita komento
+dht.execute=Suorita
+dht.logging=Seuraa toimintaa
+ConfigView.section.plugins.dhttracker=Hajautettu seurantapalvelin
+dhttracker.tracknormalwhenoffline=Seuraa normaaleja torrent-tiedostoja vain, kun niiden seurantapalvelin ei ole k\u00e4ytett\u00e4viss\u00e4
+ConfigView.section.file.nativedelete._mac=K\u00e4yt\u00e4 Roskakoria tiedostoja tuhottaessa
+ConfigView.section.file.nativedelete._windows=Siirr\u00e4 tuhotut tiedostot Roskakoriin
+ConfigView.section.logging.generatediagnostics=Luo
+ConfigView.section.logging.netinfo=Luo verkon tiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
+ConfigView.section.logging.statsinfo=Luo tilastotiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
+ConfigView.section.logging.generatediagnostics.info=Luo virheenm\u00e4\u00e4ritystiedot ja kopioi ne leikep\u00f6yd\u00e4lle (sek\u00e4 lokiin ja lokitiedostoon, jos asetettu)
+ConfigView.section.sharing.privatetorrent=Yksityinen jako - vain oman seurantapalvelimen k\u00e4ytt\u00e4j\u00e4t hyv\u00e4ksyt\u00e4\u00e4n
+MainWindow.menu.tools.nattest=&NAT- ja palomuuritesti
+Button.apply=K\u00e4yt\u00e4
+Button.close=Sulje
+window.welcome.title=Tervetuloa k\u00e4ytt\u00e4m\u00e4\u00e4n Vuzen versiota %1!
+#file can be a URL or a path in the jar
+MainWindow.menu.help.releasenotes=Julkaisutiedot
+dht.reseed.label=Normaalisti hajautetun tietokannan uudelleenjakoon ei ole tarvetta. Jos yhteystietojen m\u00e4\u00e4r\u00e4 on kuitenkin pieni, voidaan t\u00e4ll\u00e4 kasvattaa tietojen m\u00e4\u00e4r\u00e4\u00e4.\nJ\u00e4t\u00e4 kent\u00e4t tyhj\u00e4ksi yhdist\u00e4\u00e4ksesi tietoja kaikilta yhdistetyilt\u00e4 k\u00e4ytt\u00e4jilt\u00e4 tai m\u00e4\u00e4rit\u00e4 IP-osoite ja portti tehd\u00e4ksesi saman vain tietyn k\u00e4ytt\u00e4j\u00e4n kanssa.
+dht.reseed.group=Uudelleenjako
+dht.reseed.ip=IP-osoite
+dht.reseed.port=Portti
+dht.reseed=Jaa
+dht.reseed.info=Jaa tietokanta uudelleen
+dht.diagnostics.group=Virheenm\u00e4\u00e4ritys
+DHTView.title.full=Hajautettu tietokanta
+DHTView.title.fullcvs=Hajautettu tietokanta (CVS)
+DHTView.general.title=Yleiset
+DHTView.general.uptime=K\u00e4ytt\u00f6aika:
+DHTView.general.users=K\u00e4ytt\u00e4j\u00e4t:
+DHTView.general.nodes=Solmut:
+DHTView.general.leaves=Lehti\u00e4:
+DHTView.general.contacts=Yhteydet:
+DHTView.general.replacements=Varalla:
+DHTView.general.live=El\u00e4v\u00e4t:
+DHTView.general.unknown=Vieraat:
+DHTView.general.dying=Kuolevat:
+DHTView.transport.title=Siirrot
+DHTView.transport.packets=Paketit
+DHTView.transport.bytes=Tavut
+DHTView.transport.received=Vastaanotetut
+DHTView.transport.sent=L\u00e4hetetyt
+DHTView.transport.in=Sis\u00e4\u00e4n:
+DHTView.transport.out=Ulos:
+DHTView.operations.title=Toiminnan tarkemmat tiedot
+DHTView.operations.sent=L\u00e4hetetyt
+DHTView.operations.ok=Onnistuneet
+DHTView.operations.failed=Ep\u00e4onnistuneet
+DHTView.operations.received=Vastaanotetut
+DHTView.operations.ping=Vasteaikojen haut
+DHTView.operations.findNode=Solmujen etsint\u00e4
+DHTView.operations.findValue=Arvojen etsint\u00e4
+DHTView.operations.store=Tallennukset
+DHTView.activity.title=Toiminta
+DHTView.activity.status=Tila
+DHTView.activity.status.true=Jonossa
+DHTView.activity.status.false=K\u00e4yt\u00f6ss\u00e4
+DHTView.activity.type=Tyyppi
+DHTView.activity.type.1=Sis\u00e4inen haku
+DHTView.activity.type.2=Ulkoinen haku
+DHTView.activity.type.3=Sis\u00e4inen asetus
+DHTView.activity.type.4=Ulkoinen asetus
+DHTView.activity.target=Kohde
+DHTView.activity.details=Tarkemmat tiedot
+DHTView.db.title=Tietokanta
+DHTView.db.keys=Avaimet
+DHTView.db.values=Arvot
+DHTView.db.local=Paikalliset
+DHTView.db.direct=Suorat
+DHTView.db.indirect=Ep\u00e4suorat
+DHTView.db.divfreq=Taajuuden jakaja
+DHTView.db.divsize=Koon jakaja
+MainWindow.dht.status.tooltip=Kun hajautettu tietokanta on k\u00e4yt\u00f6ss\u00e4, n\u00e4et t\u00e4st\u00e4 kytkettyin\u00e4 olevien k\u00e4ytt\u00e4jien arvioidun m\u00e4\u00e4r\u00e4n.
+MainWindow.dht.status.disabled=DHT ei k\u00e4yt\u00f6ss\u00e4
+MainWindow.dht.status.failed=DHT:n k\u00e4ytt\u00f6\u00f6notto ep\u00e4onnistui
+MainWindow.dht.status.initializing=Alustetaan DHT:t\u00e4
+MainWindow.dht.status.users=%1 k\u00e4ytt\u00e4j\u00e4\u00e4
+MainWindow.dht.status.unreachable=DHT:n k\u00e4ytt\u00f6 estetty
+MainWindow.dht.status.unreachabletooltip=Hajautetun tietokannan (DHT:n) UDP-portin k\u00e4yt\u00f6ss\u00e4 on havaittu ongelmia\n - palomuuri est\u00e4\u00e4 liikenteen/NAT-ongelma
+MyTorrentsView.menu.setUpSpeed=L\u00e4hetysnopeus
+MyTorrentsView.menu.setDownSpeed=Latausnopeus
+ConfigView.section.tracker.client.showwarnings=N\u00e4yt\u00e4 seurantapalvelimien palauttamat varoitusviestit
+dht.advanced=K\u00e4yt\u00e4 lis\u00e4asetuksia
+dht.advanced.group=Lis\u00e4asetukset
+dht.advanced.label=Vaihda n\u00e4it\u00e4 asetuksia vain, jos todella tied\u00e4t mit\u00e4 olet tekem\u00e4ss\u00e4.
+dht.override.ip=Ohita ulkoinen IP-osoite
+ConfigView.section.logging.loggerenable=Kirjaa tapahtumat lokiin (n\u00e4ht\u00e4vill\u00e4 konsolissa)
+ConfigView.section.ipfilter.blockbanning=Est\u00e4 koko 256 osoitteen osoiteryhm\u00e4, kun v\u00e4hint\u00e4\u00e4n n\u00e4in monta osoitetta ryhm\u00e4n sis\u00e4lt\u00e4 on jo estetty
+MyTrackerView.passive=Passiivinen
+TableColumn.header.swarm_average_speed=Keskim. nopeus
+TableColumn.header.swarm_average_speed.info=K\u00e4ytt\u00e4jien keskim\u00e4\u00e4r\u00e4inen siirtonopeus
+TableColumn.header.comment=Kommentti
+TableColumn.header.comment.info=Oma kommentti siirrolle.
+TableColumn.header.commenticon=Kommentoitu
+TableColumn.header.commenticon.info=N\u00e4ytt\u00e4\u00e4 ikonin, jos siirrolle on asetettu oma kommentti.
+MyTrackerView.category=Luokka
+MainWindow.menu.file.open.torrentfortracking=Torrent-tiedosto... (seurantaa varten)
+VivaldiView.title.full=Vivaldi-n\u00e4kym\u00e4
+MyTrackerView.date_added=Lis\u00e4tty
+ConfigView.section.tracker.portbackup=Varaportit (erota ;-merkill\u00e4)
+ConfigView.label.playfilespeech=Kerro tiedoston valmistumisesta puheella
+ConfigView.label.playfilefinished=Anna \u00e4\u00e4nimerkki yksitt\u00e4isen tiedoston valmistuttua
+ConfigView.label.backupconfigfiles=Varmuuskopioi asetustiedostot tietojen palauttamisen varalta
+ConfigView.section.tracker.client.scrapesingleonly=Est\u00e4 seurantapalvelinkohtaiset pikap\u00e4ivitysker\u00e4ym\u00e4t (k\u00e4yt\u00e4, jos seurantapalvelin antaa 'URL too long' (414) -virhesanomia)
+dht.ipfilter.log=N\u00e4yt\u00e4 lokissa IP-suotimien est\u00e4m\u00e4t k\u00e4ytt\u00e4j\u00e4t
+ConfigView.label.seeding.addForSeedingDLCopyCount=Avattaessa torrent-tiedosto pelkk\u00e4\u00e4 l\u00e4hett\u00e4mist\u00e4 varten, aseta latauskertoimeksi
+ActivityView.legend.limit=Nopeusrajoitus
+ActivityView.legend.achieved=Saavutettu nopeus
+ActivityView.legend.overhead=Yleisrasite
+ActivityView.legend.peeraverage=Keskim\u00e4\u00e4r\u00e4inen nopeus
+ActivityView.legend.swarmaverage=K\u00e4ytt\u00e4jien keskinopeus
+ActivityView.legend.trimmed=Tasattu (sovitettu) nopeus
+MyTorrentsView.menu.movemenu=Siirr\u00e4 tiedostot
+MyTorrentsView.menu.movedata=Vaihda tallennushakemistoa...
+MyTorrentsView.menu.movetorrent=Siirr\u00e4 torrent-tiedosto...
+MyTorrentsView.menu.movedata.dialog=Valitse uusi sijainti
+DHTView.operations.data=Tieto
+DHTView.general.reachable=Saavutettavissa
+DHTView.general.rendezvous=Tavattavissa
+ConfigView.label.queue.maxactivetorrentswhenseeding=Ainoastaan l\u00e4hetett\u00e4ess\u00e4 (0 = rajoittamaton)
+Views.plugins.IRC.title=IRC - reaaliaikainen tekninen tuki
+Formats.units.alot=Paljon!
+ConfigView.section.ipfilter.persistblocking=Muista estettyjen k\u00e4ytt\u00e4jien tiedot uudelleenk\u00e4ynnistyksen j\u00e4lkeen
+FilesView.menu.rename=Nime\u00e4 uudelleen ja/tai siirr\u00e4
+FilesView.menu.rename_only=Nime\u00e4 uudelleen
+FilesView.menu.retarget=Siirr\u00e4
+FilesView.rename.choose.path=Valitse uusi tai olemassa oleva tiedosto
+FilesView.rename.choose.path.dir=Valitse uusi tai olemassa oleva hakemisto
+FilesView.rename.confirm.delete.title=Vahvista poisto
+FilesView.rename.confirm.delete.text=Haluatko varmasti poistaa seuraavan tiedoston?\n%1
+FilesView.rename.filename.title=Nime\u00e4 uudelleen
+FilesView.rename.filename.text=Anna uusi nimi tiedostolle:
+ConfigView.higher.mode.available=Korkeammissa k\u00e4ytt\u00e4j\u00e4tiloissa on valittavissa lis\u00e4\u00e4 asetuksia
+ConfigView.section.mode=K\u00e4ytt\u00e4j\u00e4tila
+ConfigView.section.mode.title=K\u00e4ytt\u00e4j\u00e4n taidot
+ConfigView.section.mode.beginner=Aloittelija
+ConfigView.section.mode.beginner.wiki.definitions=BitTorrent-sanasto
+ConfigView.section.mode.intermediate=Keskiverto
+ConfigView.section.mode.intermediate.wiki.host=Torrent-tiedostojen seuranta
+ConfigView.section.mode.intermediate.wiki.publish=Torrent-tiedostojen julkaiseminen
+ConfigView.section.mode.advanced=Edistynyt
+ConfigView.section.mode.advanced.wiki.main=Wikin etusivu
+ConfigView.section.mode.beginner.text=Kaikki mit\u00e4 tarvitset torrent-tiedostojen lataamiseen.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa, jos haluat vain hallita torrent-tiedostojasi.
+ConfigView.section.mode.intermediate.text=Vaikutusmahdollisuus oman seurantapalvelimen asetuksiin.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa, jos haluat asettaa seurantaan tai julkaista torrent-tiedostoja.
+ConfigView.section.mode.advanced.text=Vaikutusmahdollisuus tarkempiin yhteysasetuksiin.\nK\u00e4yt\u00e4 t\u00e4t\u00e4 tilaa vain, jos todella tied\u00e4t mit\u00e4 olet tekem\u00e4ss\u00e4.
+Files.column.storagetype=Varaustapa
+Files.column.fileext=Tyyppi
+FileItem.storage.linear=Lineaarinen
+FileItem.storage.compact=Kompakti
+MessageBoxWindow.rememberdecision=Muista valinta jatkossa
+ConfigView.section.interface.cleardecisions=Tyhjenn\u00e4 tallennetut asetusvalinnat
+ConfigView.section.interface.cleardecisionsbutton=Tyhjenn\u00e4
+ConfigView.section.interface.cleartrackers=Tyhjenn\u00e4 tallennetut seurantapalvelintiedot
+ConfigView.section.interface.cleartrackersbutton=Tyhjenn\u00e4
+ConfigView.section.interface.clearsavepaths=Tyhjenn\u00e4 tallennetut tallennushakemistovalinnat
+ConfigView.section.interface.clearsavepathsbutton=Tyhjenn\u00e4
+configureWizard.welcome.usermodes=K\u00e4ytt\u00e4j\u00e4tilan m\u00e4\u00e4ritt\u00e4minen vaikuttaa k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytett\u00e4vien asetusmahdollisuuksien m\u00e4\u00e4r\u00e4\u00e4n. Oikean tason valinta varmistaa sen, ett\u00e4 k\u00e4ytt\u00e4j\u00e4lle n\u00e4ytet\u00e4\u00e4n vain h\u00e4nen osaamistasolleen sopivat toiminnot, ja perusk\u00e4ytt\u00f6 onnistuu vaivattomasti. Voit halutessasi vaihtaa k\u00e4ytt\u00e4j\u00e4tilaa my\u00f6hemmin asetuksista.
+FilesView.skip.confirm.delete.text=Haluatko varmasti poistaa seuraavan tiedoston k\u00e4ytt\u00e4m\u00e4n tilanvarauksen?\n%1
+FilesView.rename.failed.title=Uudelleennime\u00e4minen/siirt\u00e4minen ep\u00e4onnistui
+FilesView.rename.failed.text=Toiminto ep\u00e4onnistui - todenn\u00e4k\u00f6isesti virheellinen kohdevalinta.
+diagnostics.log_found=Vuze ei sulkeutunut viimeksi kunnollisesti. Tarkasta <A HREF="%1">virheenm\u00e4\u00e4rityslokitiedostot</A>. Lue lis\u00e4tietoja my\u00f6s wikist\u00e4 (katso Ohje-valikko) artikkelista <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Disappears</A>.
+ManagerItem.paused=Keskeytetty
+Utils.link.visit=Katso my\u00f6s
+ConfigView.section.connection.serverport.wiki=Hyv\u00e4 porttivalinta
+ConfigView.section.transfer.speeds.wiki=Hyv\u00e4t nopeusrajoitusasetukset
+installPluginsWizard.installMode.info.title=Tietoa lis\u00e4osista
+installPluginsWizard.installMode.info.text=Vuze toimii vallan mainosti ilman lis\u00e4osiakin, mutta niiden avulla voit esimerkiksi hy\u00f6dynt\u00e4\u00e4 automaattisia toimenpiteit\u00e4 ja et\u00e4hallita Vuzea.\n\nLue jokaisen lis\u00e4osan kuvaus tarkasti ennen kuin asennat sen.\nN\u00e4in pid\u00e4t huolen siit\u00e4, ettet turhaan pid\u00e4 asennettuina sellaisia lis\u00e4osia, joita et kuitenkaan k\u00e4ytt\u00e4isi.\n\nLis\u00e4osia voit poistaa ohjatulla poistotoiminnolla, jon [...]
+Views.plugins.Distributed.DB.title=Hajautettu tietokanta
+Views.plugins.Distributed.Tracker.title=Hajautettu seurantapalvelin
+Views.plugins.Plugin.Update.title=Lis\u00e4osien p\u00e4ivitys
+Views.plugins.UPnP.title=UPnP-m\u00e4\u00e4ritys
+Views.plugins.UPnP.title.tooltip=Universal Plug and Play -tuki
+openUrl.url.info=Tukee http- ja https-protokollia, magnet-linkkej\u00e4 sek\u00e4 heksadesimaalisia tiivistearvoja
+TableColumn.header.swarm_average_completion=Keskim. valmiina
+TableColumn.header.swarm_average_completion.info=Keskim\u00e4\u00e4r\u00e4inen valmistumisprosentti kaikkien lataajien keskuudessa.
+GeneralView.label.swarm_average_completion=Keskim\u00e4\u00e4rin valmistunut:
+GeneralView.label.swarm_average_completion.tooltip=Keskim\u00e4\u00e4r\u00e4inen valmistumisprosentti kaikkien k\u00e4ytt\u00e4jien keskuudessa.
+MainWindow.nat.status.unknown=NAT-tila
+MainWindow.nat.status.tooltip.unknown=Yhteyden toimivuus palomuurin/NATin suhteen tuntematon (TCP-portin osalta).
+MainWindow.nat.status.ok=NAT-tila OK
+MainWindow.nat.status.tooltip.ok=Yhteyden toimivuus kunnossa (TCP-portin osalta).
+MainWindow.nat.status.probok=NAT-tila OK?
+MainWindow.nat.status.tooltip.probok=Yhteyden toimivuuden pit\u00e4isi olla kunnossa, mutta Vuze ei ole saanut l\u00e4hiaikoina sis\u00e4\u00e4ntulevia TCP-yhteyksi\u00e4.
+MainWindow.nat.status.bad=Yhteysongelma
+MainWindow.nat.status.tooltip.bad=Palomuuri est\u00e4\u00e4 liikenteen/NAT-ongelma havaittu (TCP-portin osalta)\n - ohjeita ongelman ratkaisemiseksi wikiss\u00e4 (katso Ohje | Wiki (UKK))
+plugin.installer.recommended.plugin=Suositeltu lis\u00e4osa - tarkasta tiedot ja asenna, jos tarvitset.
+LoggerView.pause=Keskeyt\u00e4 lokin luominen
+LoggerView.clear=&Tyhjenn\u00e4
+LoggerView.filter=Suodata n\u00e4ytett\u00e4vi\u00e4 tietoja
+LoggerView.filter.uncheckAll=Poista kaikki
+LoggerView.filter.checkAll=Valitse kaikki
+LoggerView.loggingDisabled=Lokin tekeminen on asetettu pois p\u00e4\u00e4lt\u00e4.
+LoggerView.includeOnly=N\u00e4yt\u00e4 vain t\u00e4t\u00e4 s\u00e4\u00e4nn\u00f6llist\u00e4 lauseketta vastaavat rivit:
+LoggerView.excludeAll=\u00c4l\u00e4 n\u00e4yt\u00e4 t\u00e4t\u00e4 s\u00e4\u00e4nn\u00f6llist\u00e4 lauseketta vastaavia rivej\u00e4:
+ConfigView.section.logging.log0type=Tiedot
+ConfigView.section.logging.log1type=Varoitukset
+ConfigView.section.logging.log2type=Virheet
+ConfigView.section.logging.filter=Kirjattavien tietojen suodatus
+ConfigView.section.logging.level=P\u00e4\u00e4taso
+ConfigView.section.logging.showLogsFor=N\u00e4yt\u00e4 %1-tason lokimerkinn\u00e4t luokista:
+ConfigView.pluginlist.column.loadAtStartup=Lataa k\u00e4ynnistett\u00e4ess\u00e4
+ConfigView.pluginlist.column.type=Tyyppi
+ConfigView.pluginlist.column.type.perUser=K\u00e4ytt\u00e4j\u00e4kohtainen
+ConfigView.pluginlist.column.type.shared=Jaettu
+ConfigView.pluginlist.column.type.builtIn=Sis\u00e4\u00e4nrakennettu
+ConfigView.pluginlist.column.name=Nimi
+ConfigView.pluginlist.column.version=Versio
+ConfigView.pluginlist.column.directory=Hakemisto
+ConfigView.pluginlist.column.isOperational=K\u00e4ytett\u00e4viss\u00e4
+PeersView.BlockView.Avail.Have=On molemmilla
+PeersView.BlockView.Avail.NoHave=On toisella; ei itsell\u00e4
+PeersView.BlockView.NoAvail.Have=On itsell\u00e4; ei toisella
+PeersView.BlockView.NoAvail.NoHave=Ei ole kummallakaan
+PeersView.BlockView.Transfer=Siirret\u00e4\u00e4n
+PeersView.BlockView.NextRequest=Pyydet\u00e4\u00e4n seuraavaksi
+PeersView.BlockView.title=Kuvaus osista
+PeersView.BlockView.AvailCount=Saatavuusluku
+MyTorrentsView.dialog.NumberError.title=Virheellinen arvo
+MyTorrentsView.dialog.NumberError.text=Sy\u00f6tt\u00e4m\u00e4si arvo ei ole kelvollinen.
+MyTorrentsView.menu.manual=&Manuaalinen...
+MyTorrentsView.menu.manual.per_torrent=Manuaalinen (torrent-tiedostokohtainen)...
+MyTorrentsView.menu.manual.shared_torrents=Manuaalinen (jaettuna valittujen kesken)...
+MyTorrentsView.dialog.setSpeed.title=Aseta %1
+# %1 = "in kbps" or ""; %2 = "upload" or "download"
+MyTorrentsView.dialog.setNumber.text=Rajoita %2 arvoon (%1):
+MyTorrentsView.dialog.setNumber.upload=l\u00e4hetysnopeus
+MyTorrentsView.dialog.setNumber.download=latausnopeus
+MyTorrentsView.dialog.setNumber.inKbps=%1
+OpenTorrentWindow.torrentLocation=Ladattavat torrent-tiedostot:
+OpenTorrentWindow.addFiles.URL=Lis\u00e4\u00e4 &URL
+OpenTorrentWindow.addFiles.Folder=Lis\u00e4\u00e4 &hakemisto
+OpenTorrentWindow.addFiles.Clipboard=Lis\u00e4\u00e4 &leikep\u00f6yd\u00e4lt\u00e4
+OpenTorrentWindow.changeDestination=Vaihda tallennushakemistoa
+OpenTorrentWindow.fileList=Ladattavat tiedostot:
+OpenTorrentWindow.torrentTable.name=Nimi
+OpenTorrentWindow.torrentTable.saveLocation=Tallennushakemisto
+OpenTorrentWindow.fileTable.fileName=Tiedostonimi
+OpenTorrentWindow.fileTable.size=Koko
+OpenTorrentWindow.fileTable.destinationName=Kohdesijainti ja -nimi
+OpenTorrentWindow.startMode.seeding=Aseta l\u00e4hetett\u00e4v\u00e4ksi
+OpenTorrentWindow.fileList.changeDestination=Vaihda tallennushakemistoa (kohdetta)
+OpenTorrentWindow.mb.badSize.title=Yhteensopimaton tiedosto
+OpenTorrentWindow.mb.badSize.text='%1' ei ole sama kuin '%2', joten sit\u00e4 ei voida asettaa l\u00e4hetett\u00e4v\u00e4ksi.
+OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> on jo lis\u00e4tty nimell\u00e4 '%2'.
+OpenTorrentWindow.mb.alreadyExists.default.name=Kohde
+OpenTorrentWindow.mb.alreadyExists.title=Kohde jo lis\u00e4tty
+OpenTorrentWindow.mb.openError.title=Virhe tiedoston avauksessa
+OpenTorrentWindow.mb.openError.text=Kohdetta '%1' ei voitu avata:\n%2
+OpenTorrentWindow.torrent.remove=Poista torrent-tiedosto listalta
+OpenTorrentWindow.torrent.options=Seuraavat asetukset koskevat yll\u00e4 valittuina olevia torrent-tiedostoja:
+OpenTorrentWindow.xOfTotal=(%1/%2)
+iconBar.open.tooltip=Avaa torrent-tiedosto
+LocaleUtil.column.text=Tuntematon tekstiosa
+Tracker.tooltip.MultiSupport=Seurantapalvelin tukee useita pikap\u00e4ivityksi\u00e4 yhdell\u00e4 yhteydenottokerralla.
+Tracker.tooltip.NoMultiSupport=Seurantapalvelin ei tue useita pikap\u00e4ivityksi\u00e4 yhdell\u00e4 yhteydenottokerralla.\nT\u00e4m\u00e4 ei vaikuta Vuzen suorituskykyyn, mutta asettaa seurantapalvelimelle lis\u00e4\u00e4 kuormaa.
+ConfigView.label.lazybitfield=L\u00e4het\u00e4 tiedot saatavilla olevista osista hajautetusti (auttaa tilanteessa, jossa ISP est\u00e4\u00e4 tietojen l\u00e4hett\u00e4misen kerralla)
+LoggerView.realtime=P\u00e4ivit\u00e4 reaaliajassa
+ConfigView.section.file.perf.cache.flushpieces=Kirjoita valmistuneet osat v\u00e4litt\u00f6m\u00e4sti kiintolevylle. Tasaa levyhakuja, mutta voi johtaa useampiin kirjoitusoperaatioihin
+ConfigView.section.file.writemblimit=Jonoon asetettavan kirjoitettavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4 (%1)
+ConfigView.section.file.writemblimit.explain=Kun kirjoitusnopeus kiintolevylle on pienempi kuin latausnopeus, t\u00e4m\u00e4 asetus rajoittaa jonoon asetettavan, kirjoitusta odottavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4\u00e4. Jos enimm\u00e4ism\u00e4\u00e4r\u00e4 tulee t\u00e4yteen, alennetaan latausnopeutta automaattisesti.
+ConfigView.section.file.readmblimit=Jonoon asetettavan luettavan tiedon enimm\u00e4ism\u00e4\u00e4r\u00e4 (%1)
+ConfigView.section.file.readmblimit.explain=T\u00e4m\u00e4 asetus rajoittaa keskusmuistiin asetettavan, k\u00e4sittely\u00e4 odottavan luettavan tiedon m\u00e4\u00e4r\u00e4\u00e4.
+Button.moveUp=Siirr\u00e4 &yl\u00f6s
+Button.moveDown=Siirr\u00e4 &alas
+ConfigView.notAvailableForMode=N\u00e4m\u00e4 asetukset ovat suunnattu edistyneemmille k\u00e4ytt\u00e4jille (%1-tila tai korkeampi).\nNe eiv\u00e4t siis ole k\u00e4ytett\u00e4viss\u00e4 %2-k\u00e4ytt\u00e4j\u00e4tilassa.
+health.explain.error=Torrent-tiedoston kanssa on ongelma - katso lis\u00e4tietoja Tila-sarakkeesta tai Yhteys-sarakkeen ilmaisimen ty\u00f6kaluvihjeest\u00e4.
+GeneralView.label.trackerscrapeupdate=Tee pikap\u00e4ivitys
+PeersView.piece=Viimeisin osa
+PeersView.piece.info=Viimeisimm\u00e4n k\u00e4ytt\u00e4j\u00e4lt\u00e4 pyydetyn osan numero
+PiecesView.priority=Prioriteetti
+PiecesView.priority.info=Osan valmistumisprioriteetti.
+PiecesView.speed=Nopeus
+PiecesView.speed.info=Hitaiden k\u00e4ytt\u00e4jien ei anneta h\u00e4irit\u00e4 nopeasti tulevien osien lataamista.
+TableColumn.header.AvgAvail.info=Osien saatavuuslukujen summa / osien m\u00e4\u00e4r\u00e4ll\u00e4 / yhteyksien m\u00e4\u00e4r\u00e4ll\u00e4.
+TableColumn.header.AvgAvail=Keskim. saatavuus/osa
+ConfigView.label.strictfilelocking=Lukitse tiedostot kirjoittamisen varalta torrent-tiedostojen kesken
+MyTorrentsView.menu.checkfilesexist=Tarkasta tiedostojen olemassaolo
+MyTorrentsView.menu.rescanfile=Tarkasta keskener\u00e4iset osat uudelleen s\u00e4\u00e4nn\u00f6llisesti
+MyTorrentsView.menu.clear_resume_data=Tyhjenn\u00e4 nopean latauksen jatkamisen tiedot
+Plugin.extseed.name=Ulkoiset l\u00e4hteet
+Plugin.localtracker.name=L\u00e4hiverkkok\u00e4ytt\u00f6
+Plugin.localtracker.info=Vuze-asiakasohjelmien yhteisk\u00e4ytt\u00f6\u00e4 voidaan tehostaa l\u00e4hiverkossa ja palomuurisuojatussa ymp\u00e4rist\u00f6ss\u00e4. T\u00e4m\u00e4 lis\u00e4osa muodostaa suorat tiedonsiirtoyhteydet asiakasohjelmien v\u00e4lille ja parantaa n\u00e4in siirtonopeuksia.
+Plugin.localtracker.enable=Tarkkaile l\u00e4hiverkkoa Vuze-k\u00e4ytt\u00e4jien varalta
+azinstancehandler.alert.portclash=Porttivastaavuus havaittu LAN:ssa: %1 toisen Vuze-k\u00e4ytt\u00e4j\u00e4n k\u00e4yt\u00f6ss\u00e4, valitse toinen portti sis\u00e4\u00e4ntulevalle TCP- ja UDP-liikenteelle (v\u00e4lilt\u00e4 %2 ja %3).
+ConfigView.section.transfer.lan=L\u00e4hiverkko
+ConfigView.section.transfer.lan.tooltip=L\u00e4hiverkkokohtaiset asetukset
+ConfigView.section.transfer.lan.uploadrate=kB/s, enimm\u00e4isl\u00e4hetysnopeus l\u00e4hiverkossa (0 = rajoittamaton)
+ConfigView.section.transfer.lan.uploadrate.tooltip=Erillinen enimm\u00e4isl\u00e4hetysnopeusrajoitus, jota k\u00e4ytet\u00e4\u00e4n l\u00e4hiverkon sis\u00e4isess\u00e4 liikenteess\u00e4.
+ConfigView.section.transfer.lan.downloadrate=kB/s, enimm\u00e4islatausnopeus l\u00e4hiverkossa (0 = rajoittamaton)
+ConfigView.section.transfer.lan.downloadrate.tooltip=Erillinen enimm\u00e4islatausnopeusrajoitus, jota k\u00e4ytet\u00e4\u00e4n l\u00e4hiverkon sis\u00e4isess\u00e4 liikenteess\u00e4.
+TorrentOptionsView.title.short=Asetukset
+TorrentOptionsView.title.full=Asetukset
+TorrentOptionsView.param.max.peers=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 (0 = rajoittamaton)
+ConfigView.section.connection.encryption.require_encrypted_transport=Vaadi salattu liikenne
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=Pakottaa k\u00e4ytt\u00e4m\u00e4\u00e4n salattua liikennett\u00e4 yhteyksiss\u00e4 k\u00e4ytt\u00e4jiin.
+ConfigView.section.connection.encryption.min_encryption_level=Salauksen v\u00e4himm\u00e4istaso
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=Plain - pelkk\u00e4 k\u00e4ttelyvaihe\nRC4 - t\u00e4ysi salaus\nKorkeampi salaustaso vaatii enemm\u00e4n suoritinaikaa.
+Peers.column.Encryption=Salaus
+Peers.column.Encryption.info=K\u00e4ytett\u00e4v\u00e4n salauksen taso.
+ConfigView.section.connection.encryption.encrypt.info=Jos salaus on k\u00e4yt\u00f6ss\u00e4, et voi yhdist\u00e4\u00e4 k\u00e4ytt\u00e4jiin, joiden asiakasohjelmat\neiv\u00e4t tue salausta (ellet m\u00e4\u00e4rittele salauksenohitusasetuksia k\u00e4ytt\u00f6\u00f6n alempana).
+ConfigView.section.connection.encryption.encrypt.info.link=Katso lis\u00e4tietoja t\u00e4st\u00e4
+MainWindow.sr.status.tooltip.ok=Jakosuhde riitt\u00e4v\u00e4 (%1)
+MainWindow.sr.status.tooltip.poor=Jakosuhde alhainen: %1 < 0.9
+MainWindow.sr.status.tooltip.bad=Jakosuhde eritt\u00e4in alhainen: %1 < 0.5
+ConfigView.section.style.status=Tilarivi:
+ConfigView.section.style.status.show_sr=Jakosuhde
+ConfigView.section.style.status.show_nat=NAT-tila
+ConfigView.section.style.status.show_ddb=Hajautetun tietokannan tila
+ConfigView.section.style.status.show_ipf=IP-suotimien toiminta
+ConfigView.section.connection.encryption.encrypt.group=Liikenteen salaaminen/peitt\u00e4minen
+ConfigView.section.connection.encryption.encrypt.fallback_info=Kumpi tahansa alla olevista asetuksista sallii yhteydet ep\u00e4yhteensopiviin asiakasohjelmiin, mutta poistaa liikenteen salauksen.
+ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Salli salaamattomat ulosp\u00e4in luotavat yhteydet, jos salattu liikenne ei ole k\u00e4ytett\u00e4viss\u00e4
+ConfigView.section.connection.encryption.encrypt.fallback_incoming=Salli salaamattomat sis\u00e4\u00e4ntulevat yhteydet
+ConfigView.section.connection.encryption=Salaus
+upnp.selectedinterfaces=Valitut liit\u00e4nn\u00e4t (erota ;-merkill\u00e4, esim. eth0;eth1, tyhj\u00e4 ruutu = kaikki)
+ConfigView.section.style.defaultSortOrder=Tietojen oletuslajittelu
+ConfigView.section.style.defaultSortOrder.desc=Laskeva
+ConfigView.section.style.defaultSortOrder.asc=Nouseva
+ConfigView.section.style.defaultSortOrder.flip=Viimeisimm\u00e4n vastakohta
+LoggerView.autoscroll=Automaattinen vieritys
+Button.selectAll=Valitse kaikki
+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=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)
+ConfigView.section.connection.advanced.bind_port.tooltip=Ulosp\u00e4in luotavat yhteydet sidotaan paikallisesti m\u00e4\u00e4riteltyyn porttiin.\nSaattaa auttaa tilanteissa, joissa NAT-liikennett\u00e4 ohjaavan laitteen kanssa esiintyy ep\u00e4vakautta.
+ConfigView.section.proxy.group.tracker=Yhteydet seurantapalvelimiin
+ConfigView.section.proxy.group.peer=Yhteydet k\u00e4ytt\u00e4jiin
+Pieces.column.Requested=Pyydetty
+Pieces.column.Requested.info=Voidaanko osaa pyyt\u00e4\u00e4 ladattavaksi edelleen.
+ConfigView.label.maxuploadsseeding=Vaihtoehtoinen oletusm\u00e4\u00e4r\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4
+MyTorrentsView.filter=Suodin
+popup.error.hideall=Piilota kaikki
+ConfigView.section.style.dataStatsOnly=N\u00e4yt\u00e4 tilastot vain varsinaisesta siirrett\u00e4v\u00e4st\u00e4 tiedosta (ei yhteysk\u00e4yt\u00e4nn\u00f6n tietoja)
+ConfigView.section.style.separateProtDataStats=N\u00e4yt\u00e4 tilastot eriteltyn\u00e4 siirrett\u00e4v\u00e4st\u00e4 tiedosta ja yhteysk\u00e4yt\u00e4nn\u00f6st\u00e4 (muodossa "tieto (yhteysk\u00e4yt\u00e4nt\u00f6)")
+MyTorrentsView.dialog.setFilter.title=Muokkaa suodinta
+MyTorrentsView.dialog.setFilter.text=%1 suodatetaan sy\u00f6tetyn tekstin perusteella. K\u00e4yt\u00e4 |-merkki\u00e4 (putkimerkki) suodattaaksesi useilla termeill\u00e4.
+MyTorrentsView.filter.tooltip=Ctrl+X vaihtaa RegEx-haun ja normaalin haun v\u00e4lill\u00e4.\nK\u00e4yt\u00e4 |-merkki\u00e4 (putkimerkki) suodattaaksesi useilla termeill\u00e4.
+MyTorrentsView.clearFilter.tooltip=Tyhjenn\u00e4 suodin
+MyTorrentsView.menu.filter=Suodata torrent-tiedostoja...
+ConfigView.section.file.resume.recheck.all=Tarkasta kaatumisen j\u00e4lkeen tiedostot kokonaisuudessaan (muutoin vain viimeisen tallennuksen aktiiviset osat tarkastetaan)
+ConfigureWizard.language.choose=Valitse kieli:
+popup.closing.in=Suljetaan autom. %1 sekunnissa
+popup.more.waiting=%1 viesti(\u00e4) j\u00e4ljell\u00e4...
+# > 2402
+popup.download.finished=Lataus valmistunut: "%1".
+popup.file.finished=Lataus valmistunut: "%1".
+ConfigView.auto=Automaattinen
+Plugin.localtracker.autoadd.info=Lis\u00e4\u00e4 automaattisesti seuraavat l\u00e4hiverkon k\u00e4ytt\u00e4j\u00e4t (esim. 1.2.3.4, erota osoitteet ;-merkill\u00e4)
+Plugin.localtracker.autoadd=K\u00e4ytt\u00e4j\u00e4t
+Plugin.localtracker.networks.info=K\u00e4sittele seuraavia verkkoalueita l\u00e4hiverkkoina (esim. 145.227.*.*, erota verkot ;-merkill\u00e4)
+Plugin.localtracker.networks=L\u00e4hiverkot
+MainWindow.menu.view.plugins.logViews=Lokiseurannat
+SpeedView.stats.autospeed=Automaattinen l\u00e4hetysnopeuden asettaminen (N\u00e4ytt\u00f6 rajoitettu %1 ms)
+SpeedView.stats.autospeed.disabled=T\u00e4m\u00e4 ominaisuus joko ei ole k\u00e4ytett\u00e4viss\u00e4 (hajautetun tietokannan tulee olla toiminnassa) tai l\u00e4hetysnopeus on asetettu manuaalisesti.
+SpeedView.stats.idlePing=Joutovasteaika:
+SpeedView.stats.maxPing=Enimm\u00e4isvasteaika:
+SpeedView.stats.currentPing=T\u00e4m\u00e4nhetkinen vasteaika:
+SpeedView.stats.maxUp=Enimm\u00e4isl\u00e4hetysnopeus:
+ConfigView.pluginlist.unloadSelected=Poista valitut k\u00e4yt\u00f6st\u00e4
+ConfigView.pluginlist.scan=Hae uudet
+ConfigView.section.transfer.autospeed=Auto-Speed (perinteinen)
+ConfigView.section.transfer.autospeed.tooltip=Automaattisen l\u00e4hetysnopeuden asetukset
+ConfigView.section.transfer.autospeed.info=Automaattisella enimm\u00e4isl\u00e4hetysnopeusrajoituksen asettamisella v\u00e4ltet\u00e4\u00e4n verkon liian suuri kuormittuminen.\n\nAlla olevat raja-arvot ovat k\u00e4yt\u00f6ss\u00e4, kun automaattinen l\u00e4hetysnopeuden asettaminen ja hajautettu tietokanta ovat k\u00e4yt\u00f6ss\u00e4.
+ConfigView.section.transfer.autospeed.minupload=%1, v\u00e4himm\u00e4isl\u00e4hetysnopeus
+ConfigView.section.transfer.autospeed.minupload.tooltip=L\u00e4hetysnopeutta ei normaalisti lasketa automaattisesti t\u00e4m\u00e4n rajan alle.
+ConfigView.section.transfer.autospeed.maxupload=%1, enimm\u00e4isl\u00e4hetysnopeus (0 = rajoittamaton)
+ConfigView.section.transfer.autospeed.maxupload.tooltip=L\u00e4hetysnopeutta ei automaattisesti nosteta t\u00e4m\u00e4n rajan yli.
+ConfigView.section.transfer.autospeed.chokeping=Vasteaika, jonka ylitytty\u00e4 enimm\u00e4isl\u00e4hetysnopeusrajoitusta alennetaan (millisekunteja)
+ConfigView.section.transfer.autospeed.chokeping.tooltip=Vasteajan ylittyminen on merkki liian suuresta verkon kuormituksesta.
+ConfigView.section.transfer.autospeed.enableauto=K\u00e4yt\u00e4 automaattista asetusta sek\u00e4 ladattaessa ett\u00e4 l\u00e4hetett\u00e4ess\u00e4
+ConfigView.section.transfer.autospeed.enableautoseeding=K\u00e4yt\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4 (kun ei ladata mit\u00e4\u00e4n)
+ConfigView.pluginlist.column.unloadable=Poistettavissa k\u00e4yt\u00f6st\u00e4
+ConfigView.section.transfer.lan.enable=K\u00e4yt\u00e4 erillisi\u00e4 nopeusrajoituksia l\u00e4hiverkossa
+Plugin.localtracker.wellknownlocals=Ota automaattisesti huomioon paikalliset verkot (esim. 192.168...)
+TableColumn.header.filesdone=Tiedostot
+TableColumn.header.filesdone.info=Valm. tiedostot/kaikki TAI valm. ladattavat tiedostot (valm. tiedostot)/kaikki lad. tiedostot (kaikki)
+MagnetPlugin.private_torrent=<yksityinen torrent-tiedosto>
+MagnetPlugin.decentral_disabled=<hajautettu seuranta ei k\u00e4ytett\u00e4viss\u00e4>
+MagnetPlugin.decentral_backup_disabled=<yksityinen torrent-tiedosto - hajautettu seuranta ei k\u00e4ytett\u00e4viss\u00e4>
+MagnetPlugin.report.waiting_ddb=alustetaan hajautettua tietokantaa...
+MagnetPlugin.report.searching=etsit\u00e4\u00e4n...
+MagnetPlugin.report.found=l\u00f6ydettiin %1
+MagnetPlugin.report.alive=%1 on tavoitettavissa
+MagnetPlugin.report.dead=%1 ei ole tavoitettavissa
+MagnetPlugin.report.tunnel=tunneloidaan kohteeseen %1
+MagnetPlugin.report.downloading=ladataan kohteesta %1
+MagnetPlugin.report.error=virhe %1
+MagnetURLHandler.report.no_sources=torrent-tiedostolle ei l\u00f6ytynyt l\u00e4hteit\u00e4
+MagnetURLHandler.report.torrent_size=torrent-tiedoston koko: %1
+MagnetURLHandler.report.percent=valmiiina: %1%
+MagnetURLHandler.report.error=virhe %1
+DHTTransport.report.request_all=pyydet\u00e4\u00e4n tietoa siirrett\u00e4v\u00e4ksi kohteelta %1
+DHTTransport.report.received_bit=vastaanotettiin %1 - %2 kohteelta %3
+DHTTransport.report.complete=valmis
+DHTTransport.report.timeout=aikakatkaisu, ei vastausta kohteelta %1
+DHTTransport.report.rerequest_all=pyydet\u00e4\u00e4n uudestaan tietoa siirrett\u00e4v\u00e4ksi kohteelta %1
+DHTTransport.report.rerequest_bit=pyydet\u00e4\u00e4n tietoja %1 - %2 uudestaan kohteelta %3
+DHTTransport.report.timeout_some=aikakatkaisu, %1 pakettia vastaanotettu kohteelta %2, mutta siirto ei valmis
+DHTTransport.report.sending=l\u00e4hetet\u00e4\u00e4n tietoa
+DHTTransport.report.resending=l\u00e4hetet\u00e4\u00e4n tietoja uudelleen
+DHTTransport.report.send_complete=l\u00e4hetys valmistunut
+DHTTransport.report.send_timeout=l\u00e4hetyksen aikakatkaisu
+ConfigView.section.transfer.autospeed.enabledebug=Kirjaa virheenm\u00e4\u00e4ritystiedot lokiin
+TableColumn.header.date_added=Lis\u00e4tty
+TableColumn.header.date_added.info=Ajankohta, jolloin torrent-tiedosto on avattu Vuzeen
+ConfigView.section.file.hashchecking.smallestfirst=Aloita osien tarkastaminen uudelleen pienimmist\u00e4 latauksista
+platform.win32.baddll.info=Vuze on havainnut kohteen %1 (%2) olemassaolon. T\u00e4m\u00e4n tiedet\u00e4\u00e4n aiheuttavan ongelmia Vuzen kanssa, esimerkiksi ohjelman kaatuilua ja korkeaa suoritink\u00e4ytt\u00f6\u00e4. Jos havaitset ongelmia, poista ohjelmisto tai aseta se niin, ettei se vaikuta Vuzeen.
+upnp.ignorebaddevices=Ohita laitteet, jotka eiv\u00e4t vastaa oikein
+upnp.ignorebaddevices.info=T\u00e4ll\u00e4 hetkell\u00e4 ohitetut laitteet: %1
+upnp.ignorebaddevices.reset=Tyhjenn\u00e4 ohitettavien laitteiden lista
+upnp.ignorebaddevices.reset.action=Tyhjenn\u00e4
+upnp.ignorebaddevices.alert=UPnP-laite kohteessa %1 on ohitettu toistuvien yhteysongelmien takia. Katso asetusvaihtoehdot UPnP-m\u00e4\u00e4rityksen asetuksista.
+TorrentOptionsView.param.max.uploads.when.busy=KB/s - enimm\u00e4isl\u00e4hetysnopeus, kun yleinen raja saavutettu (0 = ei k\u00e4yt\u00f6ss\u00e4)
+UpdateMonitor.messagebox.verification.failed.title=Asennuksen vahvistus ep\u00e4onnistui
+UpdateMonitor.messagebox.verification.failed.text=Kohteen '%1' vahvistus ep\u00e4onnistui: %2
+UpdateMonitor.messagebox.accept.unverified.title=Vahvistamaton asennus
+UpdateMonitor.messagebox.accept.unverified.text=Kohdetta '%1' ei voitu vahvistaa Vuzen viralliseksi lis\u00e4osaksi.\nT\u00e4llaisessa tilanteessa asennusta ei kannata jatkaa.\nJatketaanko asennusta?
+FileView.BlockView.title=Tiedoston osat
+FileView.BlockView.Done=Valmis
+FileView.BlockView.Skipped=Ohitettu
+FileView.BlockView.Active=Aktiivinen
+FileView.BlockView.Outstanding=Keskener\u00e4inen
+ConfigView.label.tcplistenport=Sis\u00e4\u00e4ntulevan TCP-liikenteen portti
+ConfigView.label.udplistenport=UDP-liikenteen portti
+upnp.portchange.alert=Seuraavat portit on vaihdettu UPnP-laitteen ongelmien v\u00e4ltt\u00e4miseksi: %1 (vanha portti = %2) %3 (vanha portti = %4)
+ConfigView.section.proxy.username.info=Jos v\u00e4lityspalvelin vaatii k\u00e4ytt\u00e4j\u00e4n todentamisen, vaikka todentamistietoja ei ole m\u00e4\u00e4ritelty, k\u00e4yt\u00e4 k\u00e4ytt\u00e4j\u00e4tunnusta "<none>"
+ConfigView.label.maxuploadswhenbusymin=Torrent-kohtainen l\u00e4hetysrajoitus k\u00e4ytt\u00f6\u00f6n, kun yleinen raja ollut saavutettuna (sekunteja)
+MainWindow.menu.help.debug=Luo virheenm\u00e4\u00e4ritystiedot
+DownloadManager.error.badsize=Virheellinen koko
+ConfigView.section.NATPMP=NAT-PMP-m\u00e4\u00e4ritys
+natpmp.info=NAT-PMP on Applen kehitt\u00e4m\u00e4 vaihtoehto UPnP:lle ja sit\u00e4 tukevat uusimmat AirPort-tukiasemat.\n\nHuomaa, ett\u00e4 t\u00e4ll\u00e4 hetkell\u00e4 UPnP-m\u00e4\u00e4rityksen t\u00e4ytyy olla k\u00e4yt\u00f6ss\u00e4, jotta voisit k\u00e4ytt\u00e4\u00e4 NAT-PMP:t\u00e4, sill\u00e4 NAT-PMP-laitetta k\u00e4sitell\u00e4\u00e4n erityistyyppisen\u00e4 UPnP-laitteena.
+natpmp.enable=K\u00e4yt\u00e4 NAT-PMP:t\u00e4 (huomaa, ett\u00e4 ominaisuus t\u00e4ytyy ottaa k\u00e4ytt\u00f6\u00f6n my\u00f6s AirPort-tukiaseman asetuksista)
+ConfigView.section.tracker.host.addurls=Lis\u00e4\u00e4 oman seurantapalvelimen p\u00e4ivitysosoite seurattaviin torrent-tiedostoihin
+ConfigView.filter=hae asetuksia
+ConfigView.section.files.move=Valmistuneiden siirt\u00e4minen
+ConfigView.section.file.defaultdir.section=Oletustallennushakemisto
+ConfigView.section.file.defaultdir.auto=Tallenna automaattisesti oletushakemistoon (ei kysyt\u00e4 erikseen)
+ConfigView.section.file.defaultdir.bestguess=K\u00e4yt\u00e4 parasta arvausta valittaessa oletustallennushakemistoa
+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=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
+ConfigView.section.connection.encryption.use_crypto_port=K\u00e4yt\u00e4 cryptoport-seurantapalvelinlaajennusta est\u00e4m\u00e4\u00e4n Plain-salatut yhteyden sis\u00e4\u00e4np\u00e4in
+TorrentOptionsView.param.reset.to.default=Palauta asetukset oletusarvoihin
+TorrentOptionsView.param.reset.button=Palauta
+natpmp.routeraddress=Tukiaseman osoite (tyhj\u00e4 ruutu = automaattinen haku)
+ConfigView.section.style.disableAlertSliding=Poista k\u00e4yt\u00f6st\u00e4 ponnahdusikkunoiden liukuva esiintulo ja aina p\u00e4\u00e4llimm\u00e4isen\u00e4 -tyyli
+ConfigView.section.transfer.autospeed.maxinc=%1, enimm\u00e4iskasvu yhden kierron aikana
+ConfigView.section.transfer.autospeed.maxdec=%1, enimm\u00e4isv\u00e4hennys yhden kierron aikana
+ConfigView.section.transfer.autospeed.enabledownadj=Salli latausnopeuden s\u00e4\u00e4tely
+ConfigView.section.transfer.autospeed.downadjratio=Lataus- ja l\u00e4hetysnopeuksien suhde (esim. 2.0 -> latausrajoitus on kaksi kertaa l\u00e4hetysrajoitus)
+ConfigView.section.transfer.autospeed.latencyfactor=Vasteajan ja nopeuden muutokset yhdist\u00e4v\u00e4 tekij\u00e4 (suuri luku v\u00e4hent\u00e4\u00e4 herkkyytt\u00e4)
+ConfigView.section.transfer.autospeed.reset=Palauta lis\u00e4asetukset oletusarvoihin
+ConfigView.section.transfer.autospeed.reset.button=Palauta
+PeerColumn.activationCount=K\u00e4ytt\u00e4j\u00e4t, jotka yritt\u00e4v\u00e4t yhdist\u00e4\u00e4: %1
+TableColumn.header.timesincedownload.info=Aikaa kulunut siit\u00e4, kun torrent-tiedostoa viimeksi ladattiin.
+TableColumn.header.timesincedownload=Lat. joutilasaika
+TableColumn.header.timesinceupload.info=Aikaa kulunut siit\u00e4, kun torrent-tiedostoa viimeksi l\u00e4hetettiin.
+TableColumn.header.timesinceupload=L\u00e4h. joutilasaika
+PeersView.incomingreqcount=Pyynn\u00f6t sis\u00e4\u00e4n
+PeersView.incomingreqcount.info=K\u00e4ytt\u00e4j\u00e4n tekemien sis\u00e4\u00e4np\u00e4in tulevien pyynt\u00f6jen m\u00e4\u00e4r\u00e4.
+PeersView.outgoingreqcount=Pyynn\u00f6t ulos
+PeersView.outgoingreqcount.info=K\u00e4ytt\u00e4j\u00e4lle tehtyjen ulosp\u00e4in menevien pyynt\u00f6jen m\u00e4\u00e4r\u00e4.
+upnp.mapping.trackerclientudp=Seurantapalvelinyhteyksien UDP-portti
+upnp.mapping.dhtudp=Hajautettu tietokanta
+ConfigView.section.connection.nondata.udp.same=K\u00e4yt\u00e4 samaa UDP-porttia hajautetulle tietokannalle ja UDP-seurantapalvelimelle
+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=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:
+UIDebugGenerator.messageask.title=Virheenm\u00e4\u00e4ritystietojen luominen
+UIDebugGenerator.messageask.text=Kirjoita kuvaus havaitusta ohjelmavirheest\u00e4.
+UIDebugGenerator.complete.title=Virheenm\u00e4\u00e4ritystiedot luotu onnistuneesti
+UIDebugGenerator.complete.text=L\u00e4het\u00e4 tiedosto '%1'.\n\nValitse OK tarkastellaksesi tiedostoa.
+ConfigView.section.style.showProgramIcon=N\u00e4yt\u00e4 avaavan ohjelman ikoni Nimi-sarakkeessa
+ConfigView.section.style.showProgramIcon.tooltip=Siirrot-ikkuna t\u00e4ytyy ehk\u00e4 sulkea ja avata uudelleen,\njotta muutos astuu voimaan.
+swt.alert.cant.update=SWT-ohjelmakirjastoa (ladattu kohteesta "%3") ei voida automaattisesti p\u00e4ivitt\u00e4\u00e4 versiosta %1 versioon %2 (t\u00e4ytyy ladata kohteesta "%4"). Katso lis\u00e4tietoja <A HREF="http://wiki.vuze.com/w/SWT_Cant_Auto_Update">wikist\u00e4</A>.
+authenticator.savepassword=Muista salasana
+ConfigView.section.security.clearpasswords=Tyhjenn\u00e4 muistetut salasanat
+ConfigView.section.security.clearpasswords.button=Tyhjenn\u00e4
+TorrentInfoView.torrent.encoding=Torrent-tiedoston koodaus
+TorrentInfoView.columns='{library.name}'-ikkunan sarakkeet
+progress.window.title=Toiminto meneill\u00e4\u00e4n
+progress.window.msg.filemove=Odota, ett\u00e4 tiedoston siirto/uudelleennime\u00e4minen valmistuu.
+ConfigView.label.popup.timestamp=N\u00e4yt\u00e4 aikaleimat ponnahdusikkunoissa
+ConfigView.label.popup.autohide=Ponnahdusikkunoiden piilotusaika (sekunteja, ei koske virheviestej\u00e4, 0 = ei automaattista piilotusta)
+ConfigView.label.please.visit.here=Katso lis\u00e4tietoja t\u00e4st\u00e4
+ConfigView.section.ipfilter.enable.descriptionCache=Tallenna kuvaukset osoitealueista v\u00e4liaikaistiedostoon
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=Jos tietoja ei tallenneta, kuvauksia ei muisteta.
+OpenTorrentWindow.filesInfo=Ladataan %1/%2
+OpenTorrentWindow.diskUsage=%1/%2
+ConfigView.label.openmytorrents=Avaa '{library.name}' k\u00e4ynnistett\u00e4ess\u00e4
+ConfigView.label.open_transfer_bar_on_start=Avaa Siirrot-palkki k\u00e4ynnistett\u00e4ess\u00e4
+ConfigView.section.style.DNDalwaysInIncomplete=N\u00e4yt\u00e4 ei-ladattavia tiedostoja sis\u00e4lt\u00e4v\u00e4t torrent-tiedostot aina keskener\u00e4isiss\u00e4 siirroissa
+OpenTorrentWindow.mb.noGlobalDestDir.title=Tallennushakemistoa ei kelpaa
+OpenTorrentWindow.mb.noGlobalDestDir.text=Tallennushakemisto '%1' on virheellinen.
+OpenTorrentWindow.mb.noDestDir.title=Tallennushakemistoa ei l\u00f6ytynyt
+OpenTorrentWindow.mb.noDestDir.text=Tallennushakemistoa '%1' torrent-tiedostolle '%2' ei ole olemassa tai se on virheellinen.
+OpenTorrentWindow.mb.notValid.title=Torrent-tiedoston avaaminen ep\u00e4onnistui
+OpenTorrentWindow.mb.notValid.text=Torrent-tiedostoa '%1' ei voitu avata. Jos olet avaamassa l\u00e4hett\u00e4mist\u00e4 varten, varmista ett\u00e4 itse l\u00e4hetett\u00e4v\u00e4t tiedostot ovat olemassa.
+OpenTorrentWindow.mb.notTorrent.title=Virhe tiedoston avauksessa
+OpenTorrentWindow.mb.notTorrent.text=Tiedostoa '%1' ei voitu avata. Se ei vaikuta olevan torrent-tiedosto.\n\nTiedostosta saatuja tietoja:\n%2
+ConfigView.label.pause.downloads.on.exit=Aseta siirrot keskeytettyyn tilaan lopetettaessa
+ConfigView.label.resume.downloads.on.start=Jatka keskeytettyj\u00e4 siirtoja k\u00e4ynnistett\u00e4ess\u00e4 kun alustus on valmistunut
+UIDebugGenerator.message.cancel.title=Virheenm\u00e4\u00e4ritystietojen luonti peruutettu
+UIDebugGenerator.message.cancel.text=Et kirjoittanut mink\u00e4\u00e4nlaista kuvausta havaitsemastasi ohjelmavirheest\u00e4. Ongelman esiintyminen saattaa olla itsest\u00e4\u00e4n selv\u00e4\u00e4 sinulle, mutta kehitt\u00e4j\u00e4t joutuisivat n\u00e4in vain arvailemaan ongelman taustoja ja ilmenemistilannetta.\n\nVirheenm\u00e4\u00e4ritystietojen luominen ja l\u00e4hett\u00e4minen on peruutettu.
+ConfigView.section.connection.group.http.info=HTTP-pohjaisen l\u00e4hett\u00e4misen tuki
+ConfigView.section.connection.http.enable=Ota k\u00e4ytt\u00f6\u00f6n
+ConfigView.section.connection.http.port=Sis\u00e4\u00e4ntulevien pyynt\u00f6jen portti
+ConfigView.section.connection.http.portoverride=Oman seurantapalvelimen HTTP-portin ohitus (0 = ei k\u00e4yt\u00f6ss\u00e4)
+window.update.noupdates.title=Ei p\u00e4ivityksi\u00e4 saatavilla
+window.update.noupdates.text=T\u00e4ll\u00e4 hetkell\u00e4 ei ole uusia p\u00e4ivityksi\u00e4 saatavilla.
+ConfigView.label.bindip.details=Esimerkki: "192.168.1.5;eth0;eth1[2]" sitoo m\u00e4\u00e4ritetyn IP-osoitteen kaikkiin ensimm\u00e4isen liit\u00e4nn\u00e4n IP-osoitteisiin ja toisen liit\u00e4nn\u00e4n kolmanteen IP-osoitteeseen.\nEnsimm\u00e4ist\u00e4 IP-osoitetta k\u00e4ytet\u00e4\u00e4n kaikille palveluille, muut on tarkoitettu kuorman tasaamista varten.\nK\u00e4ytett\u00e4viss\u00e4 ovat seuraavat liit\u00e4nn\u00e4t:\n%1
+ConfigView.label.mindownloads=Yht\u00e4aikaisten latausten v\u00e4himm\u00e4ism\u00e4\u00e4r\u00e4
+UI.cannot_submit_blank_text=Sy\u00f6t\u00e4 arvo.
+crypto.alert.as.warning='%1' -verkossa tiedet\u00e4\u00e4n tapahtuvan BitTorrent-liikenteen suodatusta. Vuzen liikenteen salaaminen on otettu automaattisesti k\u00e4ytt\u00f6\u00f6n - voit halutessasi muokata salausasetuksia asetuksista.
+ConfigView.section.interface.alerts=Ilmoitukset
+ConfigView.label.popupdownloadadded=Ilmoita siirron lis\u00e4\u00e4misest\u00e4 ponnahdusikkunalla
+popup.download.added="%1" lis\u00e4tty Siirtoihin.
+MessageBoxWindow.nomoreprompting=\u00c4l\u00e4 huomauta jatkossa
+TorrentOptionsView.param.max.seeds=Yhteyksien enimm\u00e4ism\u00e4\u00e4r\u00e4 l\u00e4hett\u00e4jiin (0 = k\u00e4yt\u00e4 yleist\u00e4 yhteysrajoitusta)
+TorrentOptionsView.param.alternative.value.enable=Vaihtoehtoinen m\u00e4\u00e4r\u00e4 ainoastaan l\u00e4hetett\u00e4ess\u00e4
+ConfigView.section.proxy.check.on.start=Tarkasta v\u00e4lityspalvelimen tila k\u00e4ynnistett\u00e4ess\u00e4
+TransferStatsView.legend.pingaverage=Keskim\u00e4\u00e4r\u00e4inen
+TransferStatsView.legend.ping1=Kohde 1
+TransferStatsView.legend.ping2=Kohde 2
+TransferStatsView.legend.ping3=Kohde 3
+ConfigView.section.interface.enabletray._mac=N\u00e4yt\u00e4 Vuzen kuvake tilapalkissa (vaatii uudelleenk\u00e4ynnistyksen)
+ConfigView.label.closetotray._mac=Sulkeminen piilottaa tilapalkkiin
+ConfigView.label.minimizetotray._mac=Pienent\u00e4minen piilottaa tilapalkkiin
+OpenTorrentWindow.mb.existingFiles.title=Tiedostot jo olemassa
+OpenTorrentWindow.mb.existingFiles.text=Seuraavat tiedostot ovat jo olemassa kohdehakemistoissa:\n\n%1\nJos jatkat, Vuze tarkastaa yll\u00e4olevien tiedostojen sis\u00e4ll\u00f6n vastaavuuden ja ylikirjoittaa ne tarvittaessa.
+splash.unloadingTorrents=Poistetaan torrent-tiedostoja muistista
+splash.unloadingTorrent=Poistetaan torrent-tiedostoa muistista
+ConfigView.section.file.defaultdir.autorename=Nime\u00e4 samannimiset, mutta sis\u00e4ll\u00f6lt\u00e4\u00e4n erilaiset tiedostot automaattisesti uudelleen
+ConfigView.section.file.defaultdir.autorename.tooltip=T\u00e4m\u00e4 est\u00e4\u00e4 torrent-tiedoston k\u00e4sitt\u00e4mien tiedostojen ylikirjoittamisen toisen torrent-tiedoston samannimisill\u00e4 tiedostoilla.
+alert.raised.at.close=(Viesti Vuzen edelliselt\u00e4 sulkemiskerralta)
+Plugin.trackerpeerauth.name=K\u00e4ytt\u00e4j\u00e4valtuutus
+Plugin.trackerpeerauth.info=T\u00e4t\u00e4 lis\u00e4osaa k\u00e4ytet\u00e4\u00e4n yhdess\u00e4 seurantapalvelimien toimintojen kanssa varmistamaan k\u00e4ytt\u00e4jien oikeudet torrent-tiedostoihin.
+Peers.column.maxupspeed=Enim.l\u00e4h.nopeus
+Peers.column.maxdownspeed=Enim.lat.nopeus
+MyTorrents.items.DownSpeedLimit.disabled=Ei ladata
+Peers.column.lan=L\u00e4hiverkko
+upnp.selectedaddresses=Osoitteet (erota ;-merkill\u00e4, etumerkit: - est\u00e4\u00e4, + sallii, tyhj\u00e4 ruutu = mik\u00e4 tahansa)
+upnp.alert.multipledevice.warning=Useita UPnP-laitteita havaittu - tarkasta vaativatko kaikki porttim\u00e4\u00e4rityksi\u00e4 (katso UPnP-loki ja -asetukset)
+UpdateMonitor.messagebox.restart.title=Ohjelmap\u00e4ivitys
+UpdateMonitor.messagebox.restart.text=Uusi t\u00e4rke\u00e4 ohjelmap\u00e4ivitys ladattu - Vuze t\u00e4ytyy k\u00e4ynnist\u00e4\u00e4 nyt uudelleen, jotta p\u00e4ivitys voidaan asentaa.
+PiecesView.BlockView.Have=Valmis
+PiecesView.BlockView.NoHave=Puuttuu
+PiecesView.BlockView.Header=%1 sarake(tta), %2 rivi(\u00e4), %3 osa(a)
+ConfigView.section.update.autodownload=Lataa p\u00e4ivitykset automaattisesti ja ilmoita kun ollaan valmiita asentamaan
+Peers.column.peer_id=Tunniste
+Peers.column.peer_id.info=K\u00e4ytt\u00e4j\u00e4n tunniste luettavassa muodossa.
+Peers.column.peer_byte_id=Tunniste
+Peers.column.peer_byte_id.info=K\u00e4ytt\u00e4j\u00e4n tunniste tavumuodossa.
+Peers.column.handshake_reserved=K\u00e4ttelybitit
+Peers.column.handshake_reserved.info=K\u00e4ttelyvaiheessa asetetut varatut bitit.
+Peers.column.client_identification=Asiakasohjelma (raaka)
+Peers.column.client_identification.info=Asiakasohjelman nimi raakamuodossa - hy\u00f6dyllinen virheenm\u00e4\u00e4rityksess\u00e4.
+dht.warn.user=Varoita mahdollisista NAT-/porttiohjausongelmista
+ConfigView.label.openbar.incomplete=Avaa seurantapalkki automaattisesti ladattaville
+ConfigView.label.openbar.complete=l\u00e4hetett\u00e4ville torrent-tiedostoille
+ConfigView.label.transferbar.remember_location=Muista Siirrot-palkin viimeisin sijainti
+ConfigView.section.transfer.autospeed.forcemin=%1, pakotettu l\u00e4hetysnopeus m\u00e4\u00e4ritett\u00e4ess\u00e4 vasteajan pohjavertailuarvoa
+MainWindow.menu.tools.speedtest=Nopeustesti
+speedtest.wizard.title=Nopeustesti
+speedtest.wizard.run=Suorita nopeustesti
+speedtest.wizard.test.mode.updown=l\u00e4hetys ja lataus
+speedtest.wizard.test.mode.up=l\u00e4hetys
+speedtest.wizard.test.mode.down=lataus
+SpeedTestWizard.test.panel.currinfo=BitTorrent-pohjainen yhteysnopeustesti.
+SpeedTestWizard.test.panel.label=Testin tyyppi:
+SpeedTestWizard.test.panel.already.running=Testi on jo k\u00e4ynniss\u00e4!
+SpeedTestWizard.test.panel.not.accepted=Testipyynt\u00f6\u00e4 ei hyv\u00e4ksytty:
+SpeedTestWizard.test.panel.abort=Keskeyt\u00e4
+SpeedTestWizard.test.panel.abort.countdown=Aikaa keskeytt\u00e4miseen:
+SpeedTestWizard.test.panel.test.countdown=Aikaa valmistumiseen:
+SpeedTestWizard.test.panel.testfailed=Testi ep\u00e4onnistui
+SpeedTestWizard.test.panel.aborted=Testi keskeytetty manuaalisesti.
+SpeedTestWizard.test.panel.enc.label=Liikenteen salaus:
+SpeedTestWizard.test.panel.standard=normaali
+SpeedTestWizard.test.panel.encrypted=salattu
+SpeedTestWizard.set.upload.button.apply=K\u00e4yt\u00e4
+SpeedTestWizard.set.upload.result=Testin tulokset
+SpeedTestWizard.set.upload.bytes.per.sec=kilotavua/s
+SpeedTestWizard.set.upload.bits.per.sec=bitti\u00e4/s
+SpeedTestWizard.finish.panel.title=Nopeustesti suoritettu!
+SpeedTestWizard.finish.panel.click.close=Nopeustesti suoritettu onnistuneesti, voit sulkea t\u00e4m\u00e4n ikkunan Sulje-painikkeella.
+SpeedTestWizard.finish.panel.max.upload=Enimm\u00e4isl\u00e4hetysnopeus:
+SpeedTestWizard.finish.panel.max.seeding.upload=- ainoastaan l\u00e4hetett\u00e4ess\u00e4:
+SpeedTestWizard.finish.panel.max.download=Enimm\u00e4islatausnopeus:
+SpeedTestWizard.finish.panel.enabled=k\u00e4yt\u00f6ss\u00e4
+SpeedTestWizard.finish.panel.disabled=ei k\u00e4yt\u00f6ss\u00e4
+SpeedTestWizard.abort.message.scheduled.in=Testi ajastettu alkamaan %1 sekunnin kuluttua
+SpeedTestWizard.abort.message.unsupported.type=Testin tyyppi\u00e4 ei tueta!
+SpeedTestWizard.abort.message.manual.abort=Keskeytetty manuaalisesti
+SpeedTestWizard.abort.message.scheduling.failed=Testin ajastus ep\u00e4onnistui
+SpeedTestWizard.abort.message.download.added=Lataus %1 lis\u00e4tty testin aikana
+SpeedTestWizard.abort.message.entered.error=Testilataus aiheutti virhetilanteen '%1'
+SpeedTestWizard.abort.message.entered.queued=Testilataus jonossa/pys\u00e4ytetyss\u00e4 tilassa
+SpeedTestWizard.abort.message.interrupted=TorrentSpeedTestMonitorThread-toiminto keskeytyi ennen testin valmistumista
+SpeedTestWizard.abort.message.execution.failed=Testin suoritus ep\u00e4onnistui
+SpeedTestWizard.abort.message.failed.peers=Yhteydenmuodostus k\u00e4ytt\u00e4jiin ei onnistunut
+SpeedTestWizard.abort.message.insufficient.slots=L\u00e4hett\u00e4minen k\u00e4ytt\u00e4jille ei onnistunut - ei vapaita l\u00e4hetyspaikkoja?
+SpeedTestWizard.abort.message.not.unchoked=Lataaminen k\u00e4ytt\u00e4jilt\u00e4 ei onnistunut, sill\u00e4 kaikki est\u00e4v\u00e4t tiedonsiirron
+SpeedTestWizard.stage.message.requesting=Pyydet\u00e4\u00e4n testi\u00e4 palvelimelta...
+SpeedTestWizard.stage.message.preparing=Valmistellaan testi\u00e4...
+SpeedTestWizard.stage.message.starting=Aloitetaan testi...
+SpeedTestWizard.stage.message.connect.stats=Yhteystilastot: k\u00e4ytt\u00e4ji\u00e4=%1, lataus ok=%2, l\u00e4hetys ok=%3
+window.uiswitcher.title=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
+window.uiswitcher.text=Valitse k\u00e4ytt\u00f6liittym\u00e4, joka vastaa parhaiten tarpeitasi.
+window.uiswitcher.NewUI.text=* Suositellaan aloittelijoille ja uusille k\u00e4ytt\u00e4jille\n\n* Helppo, intuitiivinen k\u00e4ytt\u00f6liittym\u00e4
+window.uiswitcher.ClassicUI.title=Perinteinen
+window.uiswitcher.ClassicUI.text=* Tarjoaa Azureus 2.x -versioiden toiminnot\n\n* Klassinen v\u00e4lilehti-ulkoasu
+iconBar.switch.tooltip=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
+VivaldiView.notAvailable=Vivaldi-n\u00e4kym\u00e4 ei k\u00e4ytett\u00e4viss\u00e4.
+restart.error=Uudelleenk\u00e4ynnistys ep\u00e4onnistui:\n%1\nKatso <A HREF="{restart.error.url}">lis\u00e4tietoja uudelleenk\u00e4ynnistysongelmista</a>.
+restart.error.oom=Ei vapaata muistia k\u00e4ytett\u00e4viss\u00e4.
+restart.error.fnf=Tiedostoa '%1' ei l\u00f6ytynyt hakemistosta '%2'.
+restart.error.pnf=Polkua '%1' ei l\u00f6ytynyt.
+restart.error.bad=Kelpaamaton tiedostomuoto (%1).
+restart.error.denied=Kohteen '%1' suorittaminen ei onnistunut. Varmista, ett\u00e4 sinulla on oikeudet suorittaa t\u00e4m\u00e4 ohjelma.
+TableColumn.header.date_completed=Valmistunut
+TableColumn.menu.date_added.reset=Nollaa ajankohta
+ConfigView.section.ipfilter.discardbanning=Vastaanotetun hyl\u00e4tyn/hyv\u00e4n tiedon suhde, jonka j\u00e4lkeen k\u00e4ytt\u00e4j\u00e4 estet\u00e4\u00e4n (0 = ei k\u00e4yt\u00f6ss\u00e4)
+ConfigView.section.ipfilter.discardminkb=Vaadittu hyl\u00e4tyn tiedon v\u00e4himm\u00e4ism\u00e4\u00e4r\u00e4 (%1) ennen suhdes\u00e4\u00e4nn\u00f6n k\u00e4ytt\u00f6\u00f6nottoa
+ConfigView.interface.start.advanced=K\u00e4ynnist\u00e4 lis\u00e4n\u00e4kym\u00e4ss\u00e4 (Vuze 2.x -tyyli)
+MyTorrents.column.ColumnQuality=Laatu
+MyTorrents.column.ColumnSpeed=Nopeus
+MyTorrents.column.ColumnProgressETA.2ndLine=J\u00e4ljell\u00e4: %1
+MyTorrents.column.ColumnProgressETA.StreamReady=Suoratoisto valmis
+MyTorrents.column.ColumnProgressETA.PlayableIn=Aikaa toistoon %1
+TableColumn.header.Quality=Laatu
+TableColumn.header.Speed=Nopeus
+TableColumn.header.RateIt=Arvostele
+TableColumn.header.Rating=Arvostelu
+TableColumn.header.SpeedGraphic=Nopeus
+TableColumn.header.AzProduct=L\u00e4hde
+TableColumn.header.ProgressETA=Valmistuminen
+TableColumn.header.name.ext=Tyyppi: %1
+v3.MainWindow.tab.home=Kojelauta
+v3.MainWindow.tab.browse=Vuze
+v3.MainWindow.tab.library=Kirjasto
+v3.MainWindow.tab.publish=Julkaise
+v3.MainWindow.tab.advanced=Lis\u00e4n\u00e4kym\u00e4
+v3.MainWindow.menu.home=&Kojelauta
+v3.MainWindow.menu.browse=&Vuze
+v3.MainWindow.menu.library=K&irjasto
+v3.MainWindow.menu.publish=&Julkaise
+v3.MainWindow.menu.advanced=&Lis\u00e4n\u00e4kym\u00e4
+v3.MainWindow.menu.view.searchbar=Hakupalkki
+v3.MainWindow.menu.view.tabbar=V\u00e4lilehtipalkki
+v3.MainWindow.currentDL=Ladataan parhaillaan
+v3.MainWindow.button.stream=Suoratoista
+v3.MainWindow.button.stop=Pys\u00e4yt\u00e4
+v3.MainWindow.button.start=K\u00e4ynnist\u00e4
+v3.MainWindow.button.pause=Keskeyt\u00e4
+v3.MainWindow.button.resume=Jatka
+v3.MainWindow.button.delete=Tuhoa
+v3.MainWindow.button.comment=Kommentoi
+v3.MainWindow.button.viewdetails=Lis\u00e4tiedot
+v3.MainWindow.button.play=Toista
+v3.MainWindow.button.cancel=Peruuta
+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=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 kok [...]
+v3.mb.delPublished.delete=&Tuhoa
+v3.mb.delPublished.cancel=&Peruuta
+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
+v3.mb.PlayFileNotFound.button.redownload=Lataa uudelleen
+v3.mb.PlayFileNotFound.button.find=Etsi manuaalisesti...
+v3.topbar.menu.show.logo=Vuze -logo
+v3.topbar.menu.show.plugin=Lis\u00e4osaalue
+v3.topbar.menu.show.search=Haku
+v3.topbar.menu.show.frog=Azureus-logo
+splash.initializeCore=Alustetaan ydint\u00e4
+splash.initializeUIElements=Alustetaan k\u00e4ytt\u00f6liittym\u00e4elementtej\u00e4
+ConfigView.section.transfer.autospeedbeta=Autom. l\u00e4h.nopeus (beeta)
+ConfigView.section.ipfilter.peerblocking.group=K\u00e4ytt\u00e4jien est\u00e4minen
+ConfigView.section.ipfilter.autoload.group=Automaattinen suodatinlistan lataaminen
+ConfigView.section.ipfilter.autoload.file=IP-suodintiedosto
+ConfigView.section.ipfilter.autoload.info=Tuetut tiedostomuodot ovat DAT (eMule), P2P (PeerGuardian, splist) ja P2B:n versiot 1, 2 ja 3 (PeerGuardian 2). Tiedosto voi olla paikallinen tai se voidaan noutaa URL-osoitteen perusteella, ja se voi olla zip- tai gzip-pakattu tai puhdas tekstitiedosto. URL-osoitteesta tiedosto ladataan automaattisesti uudelleen seitsem\u00e4n p\u00e4iv\u00e4n v\u00e4lein, paikallinen tiedosto minuutin sis\u00e4ll\u00e4 sen korvautumisesta tai muokkaamisesta.
+ConfigView.section.ipfilter.autoload.loadnow=Lataa
+splash.loadIpFilters=Ladataan IP-suotimia...
+SpeedTestWizard.set.upload.title=Aseta l\u00e4hetys- ja latausnopeusrajoitukset
+SpeedTestWizard.set.download.label=Enimm\u00e4islatausnopeus:
+SpeedTestWizard.set.upload.label=Enimm\u00e4isl\u00e4hetysnopeus:
+SpeedTestWizard.name.conf.level.absolute=Absoluuttinen
+SpeedTestWizard.name.conf.level.high=Korkea
+SpeedTestWizard.name.conf.level.med=Keskiverto
+SpeedTestWizard.name.conf.level.low=Matala
+SpeedTestWizard.name.conf.level.none=Ei mik\u00e4\u00e4n
+ConfigView.section.transfer.select=Autom. nopeus
+ConfigView.section.transfer.select.v2=Auto-Speed (beeta)
+mb.azmustclose.title=K\u00e4ynnistysvirhe
+mb.azmustclose.text=Vuze t\u00e4ytyy sulkea k\u00e4ynnistysvirheen takia - t\u00e4m\u00e4 todenn\u00e4k\u00f6isesti aiheutti ohjelman suorittamisen j\u00e4rjestelm\u00e4nvalvojan oikeuksilla.\n\nKun Vuze on suljettu, k\u00e4ynnist\u00e4 se uudelleen manuaalisesti.
+network.ipv6.prefer.addresses=K\u00e4yt\u00e4 ensisijaisesti IPv6-osoitteita, kun sek\u00e4 IPv6- ett\u00e4 IPv4-osoitteet ovat k\u00e4yt\u00f6ss\u00e4
+network.bindError=Palvelinpistokkeen (server socket) kiinnitys ep\u00e4onnistui, koska yhteensopivia osoitteita ei l\u00f6ytynyt, tarkista sidosasetukset (bind-to-IP).
+network.enforce.ipbinding=Pakota IP-sidokset k\u00e4ytt\u00f6\u00f6n, vaikka liit\u00e4nt\u00f6j\u00e4 ei olisi saatavilla (est\u00e4\u00e4 yhteydet, jos yksik\u00e4\u00e4n m\u00e4\u00e4ritetyist\u00e4 liit\u00e4nn\u00f6ist\u00e4 ei ole saatavilla)
+DHTView.title.full_v6=Hajautettu tietokanta (IPv6)
+ConfigView.pluginlist.loadSelected=Lataa valitut
+SpeedView.stats.asn=Verkko:
+SpeedView.stats.estupcap=Enimm\u00e4isl\u00e4hetysnopeus:
+SpeedView.stats.estdowncap=Enimm\u00e4islatausnopeus:
+SpeedView.stats.unknown=tuntematon
+SpeedView.stats.estimate=arvio
+SpeedView.stats.measured=mitattu
+SpeedView.stats.measuredmin=mitattu v\u00e4h.
+SpeedView.stats.manual=kiinte\u00e4
+ConfigView.section.transfer.autospeed.networks=Verkon tarkemmat tiedot
+ConfigView.section.transfer.autospeed.resetnetwork=Palauta oletusarvot
+ConfigView.section.transfer.autospeed.network.info=Yll\u00e4olevat nopeusrajoitukset lasketaan automaattisesti normaalien siirtojen aikana tai ne saadaan nopeustestin tuloksena. Jos haluat m\u00e4\u00e4ritt\u00e4\u00e4 arvot manuaalisesti, k\u00e4yt\u00e4 alla olevia asetuksia.\nKaikkia muita paitsi tyypilt\u00e4\u00e4n kiinteit\u00e4 arvoja s\u00e4\u00e4det\u00e4\u00e4n tarvittaessa jatkossa automaattisesti.\nSy\u00f6t\u00e4 arvo ja valitse t\u00e4m\u00e4n j\u00e4lkeen sen varmuusrajaty [...]
+dialog.uiswitcher.restart.title=Uudelleenk\u00e4ynnistys vaaditaan
+dialog.uiswitcher.restart.text=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen vaatii Vuzen uudelleenk\u00e4ynnist\u00e4misen.
+TrayWindow.menu.close=Sulje pikalatauskuvake
+# Used for peers which we can't determine.
+PeerSocket.unknown=Tuntematon
+PeerSocket.fake_client=V\u00e4\u00e4renne
+PeerSocket.bad_peer_id=Kelpaamaton tunniste
+PeerSocket.mismatch_id=Poikkeama
+PeerSocket.unknown_az_style=Tuntematon %1 %2
+PeerSocket.unknown_shadow_style=Tuntematon %1 %2
+OpenTorrentWindow.mb.askCreateDir.title=Tallennushakemistoa ei ole olemassa
+OpenTorrentWindow.mb.askCreateDir.text=Tallennushakemistoa '%1' ei ole olemassa.\n\nLuodaanko se nyt?
+SpeedView.stats.estimatechoke=arvio, esto
+ConfigTransferAutoSpeed.upload.capacity.usage=L\u00e4hetyskapasiteetin k\u00e4ytt\u00f6
+ConfigTransferAutoSpeed.mode=Tila:
+ConfigTransferAutoSpeed.capacity.used=% kapasiteetista k\u00e4ytetty
+ConfigTransferAutoSpeed.while.downloading=Ladattaessa:
+ConfigTransferAutoSpeed.set.dht.ping=Vasteaika-asetus:
+ConfigTransferAutoSpeed.set.point=asetuskohta (ms)
+ConfigTransferAutoSpeed.set.tolerance=toleranssi (ms)
+ConfigTransferAutoSpeed.ping.time.good=Hyv\u00e4:
+ConfigTransferAutoSpeed.ping.time.bad=Huono:
+ConfigTransferAutoSpeed.adjustment.interval=Asetusv\u00e4li:
+ConfigTransferAutoSpeed.skip.after.adjust=Ohita asettamisen j\u00e4lkeen:
+GeneralView.label.distributedCopies=Jaetut kopiot:
+PiecesView.DistributionView.title=Osien jakauma
+PiecesView.DistributionView.NoAvl=Eiv\u00e4t saatavilla
+PiecesView.DistributionView.SeedAvl=Saatavuusosuus - l\u00e4hteet
+PiecesView.DistributionView.PeerAvl=Saatavuusosuus - lataajat
+PiecesView.DistributionView.RarestAvl=Harvinaisimmat: %1 (saat.: %2)
+PiecesView.DistributionView.weHave=On itsell\u00e4
+PiecesView.DistributionView.theyHave=On toisella
+PiecesView.DistributionView.weDownload=Parhaillaan ladattavat
+PeersView.gain=Saavutettu
+PeersView.gain.info=Ladattu m\u00e4\u00e4r\u00e4 v\u00e4hennettyn\u00e4 l\u00e4hetetyll\u00e4 m\u00e4\u00e4r\u00e4ll\u00e4.
+unix.script.new.title=Uusi k\u00e4ynnistyskomentosarja
+unix.script.new.text=Uusi Vuzen k\u00e4ynnistyskomentosarja on saatavilla ja se on tallennettu kohteeseen '%1'.\n\nOn suositeltavaa, ett\u00e4 suljet nyt Vuzen ja vaihdat uuteen komentosarjaan ('%2').\n\nJos olet muokannut kattavasti alkuper\u00e4ist\u00e4 komentosarjaa, katso lis\u00e4tietoja seuraavasta artikkelista: <A HREF="{unix.script.new.manual.url}">VuzeWiki: Unix Script</A>.\n\nJos k\u00e4yt\u00e4t Linux-jakelun omaa repository-versiota Vuzesta (asennettu esimerkiksi yum:n tai a [...]
+unix.script.new.button.quit=Lopeta nyt
+unix.script.new.button.continue=My\u00f6hemmin
+unix.script.new.button.asknomore=\u00c4l\u00e4 huomauta jatkossa
+unix.script.new.auto.title=Uusi k\u00e4ynnistyskomentosarja
+unix.script.new.auto.text=Uusi Vuzen k\u00e4ynnistyskomentosarja on saatavilla.\n\nOn suositeltavaa, ett\u00e4 k\u00e4ynnist\u00e4t Vuzen nyt uudelleen.
+Content.alert.notuploaded.button.abort=&\u00c4l\u00e4 lopeta
+ConfigView.label.checkOnSeeding=Tee resurssiyst\u00e4v\u00e4llinen osien uudelleentarkastus l\u00e4hetett\u00e4ess\u00e4
+ConfigView.label.ui_switcher=K\u00e4ytt\u00f6liittym\u00e4n vaihtaminen
+ConfigView.label.ui_switcher_button=N\u00e4yt\u00e4
+SpeedTestWizard.test.panel.explain=L\u00e4hetys- ja latausnopeuksien m\u00e4\u00e4ritt\u00e4minen BitTorrent-protokollan avulla. Valitse testin tyyppi, salaustaso ja Suorita. Testi keskeytyy automaattisesti viimeist\u00e4\u00e4n kahden minuutin kuluttua, normaalisti testi vie kuitenkin vain alle minuutin. Lis\u00e4tietoja on luettavissa wikist\u00e4.
+SpeedTestWizard.set.upload.hint=Aseta nopeusrajoitukset Vuzen Auto-Speed-algoritmille
+SpeedTestWizard.set.upload.panel.explain=Alla olevia asetuksia k\u00e4ytt\u00e4\u00e4 Vuzen Auto-Speed-algoritmi, joka on tarkoitettu l\u00e4hetys- ja latausnopeuksien automaattiseen asettamiseen - anna nopeusrajoitukset ja varmuusrajat.\n\nHuom.: Yhteysnopeudet ilmoitetaan yleens\u00e4 kilobittein\u00e4 sekunnissa, mutta alla olevat arvot ovat kilotavuja sekunnissa.
+SpeedTestWizard.set.limit.conf.level=Varmuusraja
+SpeedTestWizard.finish.panel.auto.speed=Autom. nopeuden asettaminen:
+SpeedTestWizard.finish.panel.auto.speed.seeding=- ainoastaan l\u00e4hetett\u00e4ess\u00e4:
+ConfigTransferAutoSpeed.add.comment.to.log.group=Lis\u00e4\u00e4 kommentti virheenm\u00e4\u00e4rityslokiin
+ConfigTransferAutoSpeed.add.comment.to.log=Kommentti:
+ConfigTransferAutoSpeed.log.button=Lis\u00e4\u00e4
+ConfigTransferAutoSpeed.algorithm.selector=Automaattinen l\u00e4hetys- ja latausnopeuksien asettaminen
+ConfigTransferAutoSpeed.algorithm=Algoritmi:
+ConfigTransferAutoSpeed.auto.speed.classic=Auto-Speed (perinteinen)
+ConfigTransferAutoSpeed.auto.speed.beta=Auto-Speed (beeta)
+ConfigTransferAutoSpeed.data.update.frequency=P\u00e4ivitystiheys
+Alert.failed.update=Ainakin yhden p\u00e4ivityksen asentaminen ep\u00e4onnistui. Katso lis\u00e4tietoja: <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
+OpenTorrentWindow.mb.existingFiles.partialList=(Vain osittainen listaus - lis\u00e4\u00e4 p\u00e4\u00e4llekk\u00e4isyyksi\u00e4 olemassa.)
+TableColumn.header.bad_avail_time.info=Aika, jolloin siirrosta on viimeksi ollut saatavilla t\u00e4ysi kopio.
+TableColumn.header.bad_avail_time=T\u00e4ysi kopio n\u00e4hty
+MyTorrentsView.menu.exporthttpseeds=HTTP-l\u00e4hteiden URL-osoitteet leikep\u00f6yd\u00e4lle
+SWT.alert.erroringuithread=Graafisessa k\u00e4ytt\u00f6liittym\u00e4ss\u00e4 ilmeni k\u00e4sittelem\u00e4t\u00f6n virhe. Seurauksena voi ilmet\u00e4 muita virheit\u00e4.
+ConfigView.label.minannounce=Seurantapalvelimen p\u00e4ivitysten v\u00e4linen v\u00e4himm\u00e4isaika (sekunneissa)
+ConfigView.label.maxnumwant=Seurantapalvelimen palauttamien yhteystietojen enimm\u00e4ism\u00e4\u00e4r\u00e4
+ConfigView.label.announceport=Ohita ilmoitettava TCP-portti (seurantapalvelimet, PEX ja DHT)\n(tyhj\u00e4 ruutu = ei ohitusta, 0 = ei sis\u00e4\u00e4ntulevia yhteyksi\u00e4)
+ConfigView.label.noportannounce=\u00c4l\u00e4 ilmoita kuuntelevaa porttia seurantapalvelimelle (ei vaikuta PEX- ja DHT-toimintoihin)
+ConfigView.label.maxseedspertorrent=Yhteyksien oletusenimm\u00e4ism\u00e4\u00e4r\u00e4 l\u00e4hett\u00e4jiin/torrent-tiedosto (0 = rajoittamaton)
+wizard.webseed=Lis\u00e4\u00e4 HTTP-l\u00e4hteet
+wizard.webseed.title=HTTP-l\u00e4hteet
+wizard.webseed.configuration=Lis\u00e4\u00e4 HTTP-l\u00e4hteet:
+wizard.webseed.adding=Lis\u00e4t\u00e4\u00e4n HTTP-l\u00e4hteit\u00e4
+GeneralView.label.private=Yksityinen:
+GeneralView.yes=Kyll\u00e4
+GeneralView.no=Ei
+ConfigView.label.userequestlimiting=K\u00e4yt\u00e4 latausnopeuden rajoittamiseen pyynt\u00f6jen hidastamista viiv\u00e4stettyjen lukujen sijaan (ei vaikutusta, jos rajoittamaton)
+ConfigView.label.userequestlimiting.tooltip=Pyynt\u00f6jen rajoittaminen ei ole yht\u00e4 sulava tapa kuin lukujen viiv\u00e4stytt\u00e4minen, mutta se mahdollistaa latausten priorisoinnin perustuen sijoitukseen latausjonossa ja saattaa parantaa verkkotoimintojen suorituskyky\u00e4.
+ConfigView.label.userequestlimitingpriorities=Keskit\u00e4 latausnopeus latausjonon alkuun, kun enimm\u00e4islatausnopeusrajoitus saavutettu
+ConfigView.section.logging.timestamp=Aikaleiman muoto
+Peers.column.timetocomplete=Aikaa j\u00e4ljell\u00e4
+Peers.column.timetocomplete.info=Aika, jonka kuluttua k\u00e4ytt\u00e4j\u00e4 on saanut latauksen valmiiksi.
+ConfigView.section.interface.display.suppress.file.download.dialog=Piilota torrent-tiedostojen lataamisen edistymisest\u00e4 kertovat tiedot
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Kaikki torrent-tiedostojen lataamisesta kertovat tiedot esitet\u00e4\u00e4n tilarivin edistymisraportteina ponnahdusikkunoiden sijaan.
+FileDownload.canceled=Torrent-tiedoston lataaminen on peruutettu k\u00e4ytt\u00e4j\u00e4n toimesta: %1
+Progress.reporting.status.canceled=Peruutettu
+Progress.reporting.status.finished=Valmis
+Progress.reporting.status.retrying=Yritet\u00e4\u00e4n uudelleen...
+Progress.reporting.action.label.retry.tooltip=Yrit\u00e4 operaation suorittamista uudelleen
+Progress.reporting.action.label.remove.tooltip=Poista t\u00e4m\u00e4 edistymisraportti historiasta
+Progress.reporting.action.label.cancel.tooltip=Peruuta operaatio
+Progress.reporting.action.label.detail=Tarkemmat tiedot
+Progress.reporting.default.error=Toiminto ep\u00e4onnistui
+Progress.reporting.no.reports.to.display=T\u00e4ll\u00e4 hetkell\u00e4 ei ole edistymisraportteja n\u00e4ytett\u00e4v\u00e4ksi.
+Progress.reporting.no.history.to.display=Ei tarkempia tietoja n\u00e4ytett\u00e4v\u00e4ksi.
+Progress.reporting.detail.history.limit=Edistymisraporttien historiaan ei mahdu enemp\u00e4\u00e4 raporttien tarkempia tietoja (raja: %1) - tulevia tietoja ei lis\u00e4t\u00e4 historiaan.
+Progress.reporting.statusbar.button.tooltip=N\u00e4yt\u00e4 edistymisraportit
+webui.bindip=Sido IP-osoitteeseen - ei normaalisti tarpeen
+v3.MainWindow.text.log.in=Kirjaudu sis\u00e4\u00e4n
+v3.MainWindow.text.log.out=Kirjaudu ulos
+v3.MainWindow.text.get.started=Rekister\u00f6idy
+v3.MainWindow.text.my.account=Oma tunnus
+v3.MainWindow.text.my.profile=Profiili
+OpenTorrentWindow.simple.open=Sijainti (tiedosto, URL-osoite, tiiviste)
+Progress.reporting.window.remove.auto=Poista toimettomat raportit automaattisesti
+Progress.reporting.window.remove.auto.tooltip=Poistaa automaattisesti kaikkien valmiiden, ep\u00e4onnistuneiden ja peruutettujen toimintojen raportit listasta.
+Progress.reporting.window.remove.now=Poista toimettomat
+Progress.reporting.window.remove.now.tooltip=Poistaa kaikkien valmiiden, ep\u00e4onnistuneiden ja peruutettujen toimintojen raportit listasta.
+dhttracker.tracklimitedwhenonline=Kun seurantapalvelin on k\u00e4ytett\u00e4viss\u00e4, k\u00e4yt\u00e4 resurssiyst\u00e4v\u00e4llist\u00e4 seurantaa k\u00e4ytt\u00e4j\u00e4vaihdon varalta
+TorrentOptionsView.multi.title.short=Torrent-tiedoston asetukset
+TorrentOptionsView.multi.title.full=Torrent-tiedoston asetukset
+MyTorrentsView.menu.open_parent_folder=Avaa tallennushakemisto
+ConfigView.section.style.use_show_parent_folder=N\u00e4yt\u00e4 "%1" oletuksen "%2" sijaan torrent-tiedostovalikoissa
+ConfigView.section.style.use_show_parent_folder.tooltip=T\u00e4m\u00e4 mahdollistaa torrent-tiedoston kohteet sis\u00e4lt\u00e4v\u00e4n hakemiston avaamisen oikeassa tiedostonhallintaohjelmassa.\nAsetus voi kuitenkin aiheuttaa sen, ett\u00e4 latauksille ei pystyt\u00e4 valitsemaan automaattisesti tallennushakemistoa.
+PeerManager.status.ps_disabled=Seurantapalvelimen palauttamat tiedot eiv\u00e4t k\u00e4yt\u00f6ss\u00e4
+ConfigView.section.stats.exportfiles=Tallenna tarkat tiedot tiedostoista
+updater.cant.write.to.app.title=Asennushakemisto ei kirjoitettavissa
+updater.cant.write.to.app.details=Hakemistoon "%1" ei voida kirjoittaa.\n\nT\u00e4m\u00e4 est\u00e4\u00e4 tulevien ohjelmap\u00e4ivitysten asentamisen.\n\nKatso lis\u00e4tietoja <a href="http://wiki.vuze.com/w/Failed_Update">wikist\u00e4</a>.
+plugin.install.class_version_error=T\u00e4m\u00e4 lis\u00e4osa vaatii toimiakseen uudemman version Javasta.
+v3.MainWindow.tab.minilibrary=Lataukset
+v3.MainWindow.tab.events=Tapahtumat
+button.columnsetup.tooltip=Valitse n\u00e4ytett\u00e4v\u00e4t sarakkeet
+v3.activity.remove.title=Poista viesti
+v3.activity.remove.text=Haluatko varmasti poistaa t\u00e4m\u00e4n viestin?\n%1
+v3.MainWindow.menu.file.closewindow=Sulje
+Menu.show.torrent.menu=N\u00e4yt\u00e4 torrent-tiedostovalikko
+Menu.show.torrent.menu.tooltip=N\u00e4ytt\u00e4\u00e4 torrent-tiedostovalikon p\u00e4\u00e4valikkopalkissa.
+Views.plugins.aznetstatus.title=Verkon tila
+plugin.aznetstatus.pingtarget=Tiedustelupakettien/reittihaun kohde
+ConfigView.section.style.usePathFinder=K\u00e4yt\u00e4 Path Finderia Finderin sijaan
+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 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
+MainWindow.menu.window.zoom.maximize=Suurenna
+MainWindow.menu.window.zoom.restore=Palauta
+security.crypto.title=Salausavaimen suojaus
+security.crypto.encrypt=Anna salasana uuden salausavaimesi suojaamiseksi. T\u00e4t\u00e4 salasanaa ei ole mahdollista palauttaa, joten valitse se huolella.
+security.crypto.decrypt=Anna salasana salausavaimen avaamiseen.
+security.crypto.reason=Toiminnon syy
+security.crypto.password=Salasana
+security.crypto.password2=Salasana uudelleen
+security.crypto.persist_for=Salasanan s\u00e4ilyvyysaika
+security.crypto.persist_for.dont_save=\u00c4l\u00e4 tallenna
+security.crypto.persist_for.session=T\u00e4m\u00e4 istunto
+security.crypto.persist_for.day=1 p\u00e4iv\u00e4
+security.crypto.persist_for.week=1 viikko
+security.crypto.persist_for.30days=30 p\u00e4iv\u00e4\u00e4
+security.crypto.persist_for.forever=Ikuisesti
+security.crypto.password.mismatch.title=Salasanavirhe
+security.crypto.password.mismatch=Annetut salasanat eiv\u00e4t ole yhtenevi\u00e4, anna salasana uudelleen.
+ConfigView.section.security.group.crypto=Julkiset/yksityiset avaimet
+ConfigView.section.security.resetkey=Tyhjenn\u00e4 avaimet
+ConfigView.section.security.resetkey.warning.title=Varoitus tietojen menett\u00e4misest\u00e4
+ConfigView.section.security.resetkey.warning=Haluatko varmasti tyhjent\u00e4\u00e4 salausavaimesi? Jos tyhjenn\u00e4t avaimet, kaikki niiden avulla salatut tiedot menetet\u00e4\u00e4n pysyv\u00e4sti, eiv\u00e4tk\u00e4 julkisen avaimesi k\u00e4ytt\u00e4j\u00e4t pysty en\u00e4\u00e4 kommunikoimaan kanssasi ilman uutta avainta.
+ConfigView.section.security.unlockkey=Avaa avaimet
+ConfigView.section.security.unlockkey.button=Avaa
+ConfigView.section.security.publickey=Julkinen avain
+ConfigView.section.security.publickey.undef=Ei viel\u00e4 m\u00e4\u00e4ritelty
+ConfigView.section.security.resetkey.error.title=Toiminto ep\u00e4onnistui
+ConfigView.section.security.resetkey.error=Avainten tyhjent\u00e4minen ep\u00e4onnistui
+ConfigView.section.security.unlockkey.error=Avainten avaaminen ep\u00e4onnistui - salasana ei kelpaa
+ConfigView.copy.to.clipboard.tooltip=Kopioi leikep\u00f6yd\u00e4lle
+Views.plugins.azbuddy.title=Yst\u00e4v\u00e4t
+Browser.popup.error.no.access=Virhe et\u00e4resurssin k\u00e4yt\u00f6ss\u00e4.\nYrit\u00e4 my\u00f6hemmin uudelleen.
+ConfigView.label.queue.stoponcebandwidthmet=\u00c4l\u00e4 k\u00e4ynnist\u00e4 uusia torrentteja, kun l\u00e4hetys/lataus nopeusraja on saavutettu
+ConfigView.section.style.forceMozilla=Pakota Vuze k\u00e4ytt\u00e4m\u00e4\u00e4n Mozillaa selain-widgetteihin [vaaditaan xulrunner tai firefox 3; uudelleenk\u00e4ynnistys]
+ConfigView.section.style.xulRunnerPath=Aseta XulRunner / Firefox -hakemisto k\u00e4sin [Vaaditaan FF3:a varten; uudelleenk\u00e4ynnistys]
+Button.retry=Yrit\u00e4 uudelleen
+Button.ignore=Ohita
+DHTView.general.skew=Vinous:
+v3.MainWindow.menu.view.footer=Alapalkki
+security.crypto.badpw=Salasana oli v\u00e4\u00e4rin
+ConfigView.section.security.backupkeys=Varmuuskopioi avaimet tiedostoon
+ConfigView.section.security.backupkeys.button=Varmuuskopio
+ConfigView.section.security.restorekeys=Palauta avaimet tiedostosta
+ConfigView.section.security.restorekeys.button=Palauta
+ConfigView.section.security.op.error.title=Toiminto ep\u00e4onnistui
+ConfigView.section.security.op.error=Toiminto ep\u00e4onnistui:\n    %1
+ConfigView.section.security.restart.title=Uudelleenk\u00e4ynnistys tarvitaan
+ConfigView.section.security.restart.msg=Vuze k\u00e4ynnistyy uudelleen toiminnon viimeistelemiseksi.
+ConfigView.section.security.system.managed=Avainten suojaus j\u00e4rjestelm\u00e4ss\u00e4
+Button.bar.show=N\u00e4yt\u00e4
+Button.bar.hide=Piilota
+Button.bar.share=Jaa
+Button.bar.add=Lis\u00e4\u00e4
+Button.bar.edit=Muokkaa
+Button.bar.edit.cancel=Muokkaus valmis
+v3.MainWindow.menu.view.pluginbar=Lis\u00e4osat-palkki
+MainWindow.dialog.select.vuze.file=Valitse Vuze-tiedosto
+MainWindow.menu.file.open.vuze=Vuze-tiedosto...
+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
+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
+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.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?
+fileplugininstall.install.desc=Oletko varma, ett\u00e4 haluat asentaan lis\u00e4osan '%1' version %2?
+fileplugininstall.duplicate.title=Lis\u00e4osan tuplakopio
+fileplugininstall.duplicate.desc=Lis\u00e4osan '%1' versio %2 on jo asennettuna
+progress.window.msg.progress=Odota toimenpiteen valmistumista
+DetailedListView.title=Yksityiskohtainen luettelo
+ConfigView.section.connection.network.max.outstanding.connect.attempts=Suurin sallittu l\u00e4htevien yhteyksien m\u00e4\u00e4r\u00e4
+plugins.init.force_enabled=Vuze havaitsi lis\u00e4osan "%1" olevan estettyn\u00e4 toimimasta - se on sallittu uudelleen Vuzen toiminnan varmistamiseksi.
+ConfigView.section.connection.prefer.udp=Suosi UDP-yhteyksi\u00e4
+iconBar.start=K\u00e4ynnist\u00e4
+iconBar.stop=Pys\u00e4yt\u00e4
+iconBar.remove=Poista
+iconBar.up=Yl\u00f6s
+iconBar.down=Alas
+iconBar.run=Avaa
+iconBar.editcolumns=Sarakeasetukset
+iconBar.top=Ylimm\u00e4ksi
+iconBar.bottom=Alimmaksi
+iconBar.queue=K\u00e4ynnist\u00e4
+iconBar.open=Lis\u00e4\u00e4 torrent
+iconBar.share=Jaa
+iconBar.share.tooltip=Jaa sis\u00e4lt\u00f6\u00e4
+iconBar.details=Yksityiskohdat
+iconBar.comment=Kommentti
+iconBar.play=Soita
+iconBar.queue.tooltip=K\u00e4ynnist\u00e4 (aseta jonoon)
+v3.MainWindow.menu.view.sidebar=Sivupalkki
+v3.MainWindow.menu.view.actionbar=Toimintapalkki
+v3.MainWindow.menu.view.toolbars=Ty\u00f6kalupalkit
+ump.install=Pikap\u00e4ivitys k\u00e4ynniss\u00e4:\nAsennetaan video soittamiseen tarvittava pieni lis\u00e4osa.
+PluginDeprecation.log.start=T\u00e4m\u00e4 ikkuna sis\u00e4lt\u00e4\u00e4 tietoa lis\u00e4osista, jotak k\u00e4ytt\u00e4v\u00e4t tulevaisuudessa poistettavia Vuzen toiminnallisuuksia.\nSinun ei tarvitse poistaa kyseisten lis\u00e4osien asennusta, mutta sinun pit\u00e4isi p\u00e4ivitt\u00e4\u00e4 lis\u00e4osat uusimpaan versioon.\nJos k\u00e4yt\u00e4t jo lis\u00e4osan uusinta versiota, voisit kopioida t\u00e4m\u00e4n ikkunan sis\u00e4ll\u00f6n Vuzen foorumille:\n \t%1\n\n
+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.
+v3.MainWindow.menu.getting_started=Aloitussivu
+MainWindow.menu.community=&K\u00e4ytt\u00e4j\u00e4yhteis\u00f6
+MainWindow.menu.community.wiki=K\u00e4ytt\u00e4jien Wiki-artikkelit
+MainWindow.menu.community.forums=K\u00e4ytt\u00e4jien keskustelufoorumi
+MainWindow.menu.help.support=Apua ja tukea
+externalLogin.title=Login vaaditaan
+externalLogin.explanation=Hakupohja "%1" vaatii kirjautumista. Kun olet kirjautunut, t\u00e4m\u00e4 ikkuna sulkeutuu automaattisesti. Jos se kuitenkin j\u00e4\u00e4 auki, paina "Valmis".
+externalLogin.explanation.capture=Sinun pit\u00e4\u00e4 kirjautua luodaksesi hakupohjan. Kun olet sis\u00e4ll\u00e4, paina "Valmis".
+Button.done=Valmis
+GeneralView.torrent_created_on_and_by=%1 / %2
+Button.continue=Jatka
+Button.preview=Esikatsele
+sidebar.LibraryDL=Lataukset...
+sidebar.LibraryCD=Valmiit
+authenticator.location=Sijainti
+authenticator.details=Detaljit
+v3.MainWindow.menu.showActionBarText=N\u00e4yt\u00e4 teksti
+Button.remove=Poista
+Button.send=L\u00e4het\u00e4
+Button.back=Takaisin
+sidebar.LibraryUnopened=Uudet
+TableColumn.header.unopened=Uusi
+Unopened.bigView.header=Uusi
+ConfigView.section.Subscriptions=Tilaukset
+v3.activity.button.readall=Merkitse kaikki luetuiksi
+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
+Button.search=Etsi
+Button.save=Tallenna
+Button.add=Lis\u00e4\u00e4
+message.confirm.delete.title=Vahvista poistaminen
+message.confirm.delete.text=Haluatko varmasti poistaa '%1'?
+props.window.title='%1':n ominaisuudet
+subs.prop.template=Hakupohja
+externalLogin.auth_method_proxy=K\u00e4yt\u00e4 laajennettua keksin (cookie) poimintaa. Jos se ei toimi, poista optio ja kokeile uudelleen.
+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
+v3.iconBar.up.tooltip=Siirr\u00e4 yl\u00f6s\nPid\u00e4 hiirt\u00e4 painettuna siirt\u00e4\u00e4ksesi ylimm\u00e4ksi
+v3.iconBar.down.tooltip=Siirr\u00e4 alas\nPid\u00e4 hiirt\u00e4 painettuna siirt\u00e4\u00e4ksesi alimmaksi
+Button.deleteContent.fromLibrary=Poista Vuzen kirjastosta
+Button.deleteContent.fromComputer=Poista tietokoneelta
+v3.deleteContent.message=\nHaluatko poistaa '%1' my\u00f6s tietokoneeltasi, vai poistaa sen vain Vuzen kirjastosta?
+v3.MainWindow.menu.view.toolbartext=Ty\u00f6kalupalkin tekstit
+v3.MainWindow.menu.view.asSimpleList=Yksinkertainen luettelo
+v3.MainWindow.menu.view.asAdvancedList=Kehittynyt luettelo
+v3.MainWindow.menu.view.statusbar=Tilarivi
+configureWizard.file.message3=Vuze tallentaa lataamasi tiedostot hakemistoon. Valitse kyseinen hakemisto nyt:
+v3.deleteContent.applyToAll=Tee toiminto %1 kaikille valituille kohteille
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=jotka eiv\u00e4t l\u00e4het\u00e4 mit\u00e4\u00e4n
+v3.MainWindow.menu.contentnetworks=&HD Network
+v3.MainWindow.menu.contentnetworks.about=HD Networks -tietoa
+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
+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.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.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.
+TableColumn.header.size.info=Torrent-tiedoston kohteen koko.
+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.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
+Peers.column.%.info=K\u00e4ytt\u00e4j\u00e4n t\u00e4h\u00e4n menness\u00e4 lataama osuus torrentista
+TableColumn.header.download.info=Kohteelt\u00e4 ladattu tietom\u00e4\u00e4r\u00e4
+TableColumn.header.upload.info=L\u00e4hetetyn tiedon m\u00e4\u00e4r\u00e4
+TableColumn.header.downloadspeed.info=Meid\u00e4n lataamisnopeutemme t\u00e4lt\u00e4 kohteelta
+TableColumn.header.uploadspeed.info=Tiedon l\u00e4hetysnopeus
+TableColumn.header.lan.info=Samassa LAN-verkossa olevan lataajan indikaattori
+TableColumn.header.downloadspeedoverall.info=Lataajan arvioitu lataamisnopeus
+Peers.column.pieces.info=Graafinen esitys k\u00e4ytt\u00e4j\u00e4n lataamista osista
+TableColumn.header.TableColumnNameInfo=Sarakkeen nimi ja kuvaus
+TableColumn.header.TableColumnSample=Esimerkki
+TableColumn.header.TableColumnInfo=Sarakkeen kuvaus
+TableColumn.header.TableColumnChosenColumn=Valittu sarake
+label.learnmore=Lis\u00e4tietoja
+ColumnSetup.title=Sarakeasetukset: '%1'
+ColumnSetup.explain=Katso valittavissa olevia sarakkeiden listaa vasemmalla, ja lis\u00e4\u00e4 haluamasi oikealla olevaan valittujen sarakkeiden listaan. Voit suodattaa tarjolla olevien listaa alavasemmalla olevilla suodattimilla. Sarakenimien vet\u00e4minen hiirell\u00e4 on mahdollista.
+ColumnSetup.chosencolumns=Valitut sarakkeet
+ColumnSetup.proficiency=K\u00e4ytt\u00e4j\u00e4n taidot:
+ColumnSetup.categories=Luokat:
+ColumnSetup.filters=Suodatus
+ColumnSetup.availcolumns=Mahdolliset %1 sarakkeet
+ColumnSetup.availcolumns.filteredby=Mahdolliset %1 sarakkeet, suodatus %2
+devices.view.title=Oheislaitteet
+device.renderer.view.title=N\u00e4ytt\u00f6laitteet
+device.mediaserver.view.title=Mediapalvelimet
+device.router.view.title=Reitittimet
+device.model.desc=Mallin kuvaus
+device.model.name=Mallin nimi
+device.model.num=Mallinumero
+device.manu.desc=Valmistaja
+device.router.is_mapping=Automaattinen porttien asetus (port mapping)
+device.router.req_map=Vaaditut porttiasetukset
+device.router.configure=Konfiguroi UPnP
+device.mediaserver.configure=Mediapalvelimen asetukset
+device.hide=Piilota oheislaite
+device.show=N\u00e4yt\u00e4 k\u00e4tketyt oheislaitteet
+device.search=Etsi oheislaitteita
+device.router.con_type=Yhteys: %1
+device.browse=Selaa
+device.upnp.desc_url=Oheislaitteen kuvaus
+device.upnp.present_url=Oheislaitteen hallinnointi
+ConfigView.label.maxStalledSeeding=Max. 'pys\u00e4htynyt' [0:rajoittamaton]
+device.search.auto=Etsi oheislaitteita automaattisesti
+devices.sidebar.simple=Yksinkertainen n\u00e4kym\u00e4
+devices.xcode.working_dir=Konvertointi-alue
+devices.xcode.prof_def=Oletus konvertointiprofiili
+devices.xcode.profs=K\u00e4ytett\u00e4viss\u00e4 olevat konvertointiprofiilit
+device.lastseen=Viimeksi n\u00e4hty
+devices.contextmenu.xcode=Konvertoi oheislaitteelle
+devices.device=Oheislaite
+devices.profile=Profiili
+General.percent=Prosenttia
+devices.installed=Asennettu
+devices.comp.missing=Vuze-tukea ei asennettu
+devices.state=Tila
+MainWindow.menu.help.donate=Tee &lahjoitus
+DonationWindow.noload.title=Lahjoitukset
+DonationWindow.noload.text=Lahjoitusikkunan lataaminen ep\u00e4onnistui. Yrit\u00e4 my\u00f6hemmin uudelleen.
+devices.xcode.only.show=N\u00e4yt\u00e4 vain konvertoidut tiedostot laitteessa
+device.quit.transcoding.title=Konvertointi k\u00e4ynniss\u00e4
+device.quit.transcoding.text='%1' konvertoidaan parhaillaan '%2' varten ja on %3% valmis.\nJos poistut nyt, konvertointi pit\u00e4\u00e4 k\u00e4ynnist\u00e4\u00e4 uudelleen alusta ensi kerralla.
+download.removerules.unauthorised.data=\tPoista my\u00f6s datatiedostot
+device.config.xcode.maxbps=Max KB/s konvertointinopeus [0: rajoittamaton]
+device.xcode=Konvertoi
+device.xcode.always=Aina
+device.xcode.whenreq=Tarvittaessa
+device.xcode.never=Ei koskaan
+devices.copy.pending=Tiedoston kopiointia odotetaan
+devices.sidebar.hide.rend.generic=Piilota geneeriset oheislaitteet
+v3.devicesview.infobar.text2=Konvertoidaksesi sis\u00e4lt\u00f6\u00e4 oheislaitteelle, yksinrtaisesti ved\u00e4 sis\u00e4lt\u00f6\u00e4 kirjastosta laitteen p\u00e4\u00e4lle sivupalkissa. N\u00e4hd\u00e4ksesi valmiit konvertoinnit, valitse oheislaite oikealla.
+iconBar.transcode=Oheislaite
+iconBar.transcode.tooltip=Muunna media oheislaitetta varten
+device.retry.copy=Yrit\u00e4 kopioida
+devices.copy.fail=Kopiointi oheislaitteelle ep\u00e4onnistui
+devices.on.demand=Tarvittaessa
+devices.ready=Valmis
+TableColumn.header.trancode_qpos.info=Paikka konvertointijonossa
+TableColumn.header.profile=Oheislaite
+TableColumn.header.profile.info=K\u00e4ytetty konvertointiprofiili
+TableColumn.header.copied=Kopioitu
+TableColumn.header.device=Oheislaite
+TableColumn.header.device.info=Kohde-oheislaite
+TableColumn.header.trancode_completion=Konvertointi k\u00e4ynniss\u00e4
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=N\u00e4k
+v3.iconBar.view.big.tooltip=Yksinkertainen
+# This is the end of the word "View".  It's left aligned under the icon bar item
+v3.iconBar.view.small=ym\u00e4
+v3.iconBar.view.small.tooltip=Kehittynyt luettelo
+general.dont.ask.again=\u00c4l\u00e4 kysy uudelleen
+v3.menu.device.exploreTranscodes=N\u00e4yt\u00e4 tiedostot
+v3.menu.device.exploreTranscodes._windows=N\u00e4yt\u00e4 tiedostot Explorerissa
+v3.menu.device.exploreTranscodes._mac=N\u00e4yt\u00e4 tiedostot Finderissa
+v3.menu.device.defaultprofile=Oletusprofiili
+devices.button.installitunes=Asenna iTunes-integraatio
+device.itunes.install=Sinun pit\u00e4\u00e4 asentaa iTunes
+device.itunes.start=Sinun pit\u00e4\u00e4 k\u00e4ynnist\u00e4\u00e4 iTunes tai mahdollistaa automaattinen k\u00e4ynnistys
+device.itunes.install_problem=Havaittu ongelma iTunes-integraatiossa
+devices.downloading=Ladataan
+TableColumn.header.duration=Kesto
+TableColumn.header.resolution=Resoluutio
+devices.xcode.autoStart=K\u00e4ynnist\u00e4 tarvittaessa automaattisesti
+option.askeverytime=Kysy joka kerta
+option.rememberthis=Muista t\u00e4m\u00e4 asetus
+devices.associate=Liit\u00e4 yhteyteen 
+devices.associate.already=On jo liitetty
+devices.always.cache=Laita ei-konvertoidut tiedostot v\u00e4limuistiin
+devices.turnon.prepageload=T\u00e4m\u00e4n ominaisuuden k\u00e4ytt\u00f6 vaatii ylim\u00e4\u00e4r\u00e4isten lis\u00e4osien asennusta.
+devices.turnon.itunes=Mahdollista iTunes-tuki (vaaditaan Apple-oheislaitteille)
+devices.turnon.qos=L\u00e4het\u00e4 nimett\u00f6mi\u00e4 oheislaitetilastoja Vuzelle
+devices.turnon.title=Mahdollista tuki oheislaitteille
+devices.choose.device.title=Valitse soittolaite t\u00e4lle videolle:
+devices.choose.profile.info.text=Valintasi j\u00e4lkeen Vuze tunnistaa, toimiiko videoformaatti valitemassasi laitteessa ja luo tarvittaessa yhteensopivan kopion.\n\nPid\u00e4 hiirt\u00e4 laitteen p\u00e4\u00e4ll\u00e4 saadaksesi lis\u00e4tietoja.
+devices.choose.profile.info.title.selected=%1 yksityiskohdat:
+devices.view.heading=Median konvertointi oheislaitetta varten
+device.view.heading=Median kohde: %1
+devices.choose.device.info.title=Oheislaite-vihje
+devices.choose.device.info.text=Ensi kerralla, yksinkertaisesti ved\u00e4 tiedostot valitsemasi laitteen p\u00e4\u00e4lle sivupalkissa.
+label.clickone=Valitse yksi
+Button.turnon=K\u00e4ynnist\u00e4
+ConfigView.label.dm.dblclick=Tuplaklikkaus torrent-n\u00e4kym\u00e4ss\u00e4:
+ConfigView.option.dm.dblclick.play=Soita/k\u00e4ynnist\u00e4 sis\u00e4lt\u00f6
+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
+xcode.deletedata.title=Poista konvertoitu sis\u00e4lt\u00f6
+xcode.deletedata.message=Haluatko varmasti poistaa pysyv\u00e4sti konvertoidun kopion '%1' laitteelle '%2'%3?
+xcode.deletedata.message.2=\n(kopio voi viel\u00e4 sijaita: '%1')
+v3.deviceview.infobar.line1=Ved\u00e4 videoita kirjastosta valitsemallesi oheislaitteelle.
+v3.deviceview.infobar.line2=Soita videoitasi kaikilla oheislaitteillasi - iPad, iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=Ved\u00e4 videoita kirjastosta laitteelle %1 sivupalkissa.
+v3.deviceview.infobar.line2.itunes=Videot n\u00e4kyv\u00e4t iTunes Movies-kansiossa, kun ne ovat valmiita soitettavaksi.
+v3.deviceview.infobar.line2.xbox=Suoratoista videot: mene Xbox360:een ja valitse My XBox -> Video Library -> Vuze.
+v3.deviceview.infobar.line2.ps3=Suoratoista videot: mene PS3:een ja valitse Videos -> Vuze.
+devices.copy_url=Kopioi suoratoisto-URL leikep\u00e4yd\u00e4lle
+devices.converting=Konvertoi
+Button.reload=Lataa uudelleen
+devices.auto.start=Autom. k\u00e4ynnistys
+general.enter.cookies=Ev\u00e4steet (cookies)
+device.config.xcode.workdir=Oletushakemisto konvertoiduille tiedostoille
+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
+dlg.corewait.text=Odota hetki...\n\nPyynt\u00f6si k\u00e4sitell\u00e4\u00e4n Vuzen k\u00e4ynnistymisen p\u00e4\u00e4tytty\u00e4
+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
+TableColumn.header.class=Luokka
+device.rss.group=Paikallinen RSS-sy\u00f6te
+devices.xcode.rsspub=Julkaise RSS-sy\u00f6te
+device.rss.enable=Luo RSS-sy\u00f6te konvertoidusta sis\u00e4ll\u00f6st\u00e4 - t\u00e4m\u00e4 tekee sis\u00e4ll\u00f6st\u00e4 lukukelpoisen RSS-ohjelmilla
+device.rss.port=RSS-sy\u00f6tteen portti
+device.rss.view=Paina katsoaksesi RSS-sy\u00f6tett\u00e4
+device.rss.localonly=Rajoita yhteydet vain t\u00e4h\u00e4n tietokoneeseen
+devices.xcode.autoCopy=Kopioi automaattisesti kansioon
+devices.xcode.setcopyto=Aseta Kopioi kansioon...
+devices.xcode.setcopyto.title=Valitse, mihin kopioidaan
+devices.copy.folder.auto=Kopioi tiedostot automaattisesti kansioon
+devices.copy.folder.dest=Kopioi kansioon
+TableColumn.menu.maxuploads=# Max l\u00e4hetyspaikkoja
+devices.xcode.mancopy=Kopioi tiedostot k\u00e4sin
+devices.xcode.show.cat=Erottele kategorioittain
+ConfigView.label.alwaysShowLibraryHeader=N\u00e4yt\u00e4 otsikko/suodatinrivi aina {library.name}-ikkunassa
+devices.cat.show=N\u00e4yt\u00e4 luokat
+devices.tivo.machine=TiVo-laitteen nimi
+devices.info.copypending=%1 tiedosto(a) odottaa kopiointia
+device.error.xcodefail=Konvertointi ep\u00e4onnistui
+device.error.copyfail=Yksi tai useampi tiedosto ei kopioitunut kansioon
+device.error.copytonotset='Kopioi kansioon' ei ole asetettu
+device.error.copytomissing='Kopioi kansioon' "%1" ei l\u00f6ydetty
+device.error.copytonowrite='Kopioi kansioon' "%1" ei voi kirjoittaa
+device.error.copyfail2=Yksi tai useampi tiedosto ei kopioitunut oheislaitteeseen
+v3.deviceview.infobar.line2.tivo=Suoratoista videot: mene Tivoon ja valitse 'Now Playing List' -> Vuze.
+v3.deviceview.infobar.line2.psp=Videot kopioidaan PSP:hen, kun se on yhdistetty.
+devices.info.copypending2=%1 tiedosto(a) odottaa kopiointia, yhdist\u00e4 oheislaite
+device.offlinedownloader.view.title=Offline Download -oheislaitteet
+device.od.enable=Mahdollista Offline Download -oheislaitteet
+device.odauto.enable=Hallitse latauksia automaattisesti
+device.odpt.enable=Sis\u00e4llyt\u00e4 yksityiset torrentit
+devices.contextmenu.od.enable=P\u00e4\u00e4lle
+devices.contextmenu.od.enabled=P\u00e4\u00e4ll\u00e4
+devices.od.view.heading=Lataukset jonossa Offline Downloading -oheislaitteeseen
+DevicesOD.column.od_completion=Siirron tila
+devices.od.idle=Vapaa
+device.od.turnon.title=Aseta Offline download -oheislaitteiden tuki p\u00e4\u00e4lle
+device.is.disabled=Oheislaite ei k\u00e4yt\u00f6ss\u00e4
+device.configure=Asetukset...
+device.od.error.notfound=Oheislaite on ilmeisesti pois p\u00e4\u00e4lt\u00e4
+device.od.error.opfailstatus=Oheislaite ei k\u00e4sitellyt komentoa %1: status %2
+device.od.error.opfailexcep=Oheislaite ei k\u00e4sitellyt komentoa %1: exception %2
+device.od.error.nospace=Ei tilaa oheislaitteessa tai ulkoista levy\u00e4 ei ole yhdistetty
+device.od.space=Tilaa k\u00e4ytett\u00e4viss\u00e4
+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
+devices.activation=Oheislaitteen aktivointi
+button.nothanks=Ei kiitos
+devices.od.turnon.text1=Huomasimme, ett\u00e4 olet yhdistetty oheislaitteeseen %1.
+devices.od.turnon.text2=Haluaisitko %1 jatkavan tiedostojen lataamista, kun tietokoneesi ei ole p\u00e4\u00e4ll\u00e4?
+devices.od.turnon.text3=Yhdist\u00e4 kovalevy laitteeseen %1 k\u00e4ytt\u00e4\u00e4ksesi t\u00e4t\u00e4 ominaisuutta.
+devices.od.turnon.learn=Lis\u00e4tietoja >
+devices.router=reititin
+webui.pairingenable=Mahdollista paritus (testaustoimintojen k\u00e4ytt\u00f6 on mahdollista, kun paritustiedot on julkaistu onnistuneesti)
+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=Julkinen IPv4-osoite
+pairing.ipv6=Julkinen IPv6-osoite
+pairing.local.ipv4=Paikallinen IPv4-osoite
+pairing.local.ipv6=Paikallinen 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.
+device.tivo.enable=Mahdollista TiVo-tuki
+Button.removeAll=Poista kaikki
+label.rename=Uudelleennime\u00e4 %1
+pairing.server.warning.title=Parituspalvelimen viesti
+wizard.webseedseditor.edit.title=HTTP-l\u00e4hteiden muokkaus
+wizard.webseedseditor.edit.newseed=Uusi l\u00e4hde
+MyTorrentsView.menu.editWebSeeds=Muokkaa HTTP-l\u00e4hteit\u00e4
+ClientStats.title.full=Asiakasohjelma-tilastot
+ClientStats.column.count=M\u00e4\u00e4r\u00e4
+Scrape.status.cached=Pikap\u00e4ivitys v\u00e4limuistista
+network.ipv6.enable.support=IPv6-protokollan tuki (Windows-ymp\u00e4rist\u00f6ss\u00e4 vaaditaan Java7 beta-versio: http://download.java.net/jdk7/binaries/ )
+ConfigView.section.plugins.magnetplugin=Magnet URI-palvelut
+MagnetPlugin.use.lookup.service=K\u00e4yt\u00e4 Vuzen toissijaista hakupalvelua, jos magnet-haku DHT:n kautta ep\u00e4onnistuu
+MagnetPlugin.report.secondarylookup=Kokeillaan toissijaista hakupalvelua
+MagnetPlugin.report.secondarylookup.ok=Toissijainen hakupalvelu onnistui
+MagnetPlugin.report.secondarylookup.fail=Toissijainen hakupalvelu ep\u00e4onnistui: ei l\u00e4hteit\u00e4
+TrackerView.title.short=L\u00e4hteet
+TrackerView.title.full=L\u00e4hteet
+Trackers.column.type=Tyyppi
+Trackers.column.name=Tiedot
+Trackers.column.status=Tila
+Trackers.column.seeds=L\u00e4hteet
+Trackers.column.seeds.info=L\u00e4hteit\u00e4 parvessa
+Trackers.column.leechers=Pelkki\u00e4 lataajia
+Trackers.column.leechers.info=Pelkki\u00e4 lataajia parvessa
+Trackers.column.peers=Lataajia
+Trackers.column.peers.info=Lataajat seurantapalvelimelta
+Trackers.column.interval=V\u00e4li
+Trackers.column.interval.info=Kyselyiden v\u00e4liaika sekunteina: v\u00e4li (v\u00e4himm\u00e4isv\u00e4li)
+Trackers.column.updatein=Seuraava
+Trackers.column.updatein.info=Aika p\u00e4ivitykseen
+tps.status.available=K\u00e4ytett\u00e4viss\u00e4
+tps.status.unavailable=Ei k\u00e4ytett\u00e4viss\u00e4
+tps.lan.details=%1 paikallista kohdetta l\u00f6ydetty
+tps.pex.details=Yhteydess\u00e4 %1 kohteeseen (odottaa: pex=%2, muu=%3)
+tps.tracker.cache=V\u00e4limuisti
+tps.tracker.cache1=V\u00e4limuisti: kohteita=%1
+dht.status.disabled=Ei k\u00e4yt\u00f6ss\u00e4, DHT - hajautettu tietokanta ei ole k\u00e4ytett\u00e4viss\u00e4
+tps.type.incoming=Sis\u00e4\u00e4ntuleva
+tps.incoming.details=Nyt: TCP=%1, UDP=%2; Yhteens\u00e4 aina=%3
+tps.type.plugin=Lis\u00e4osa
+ConfigView.label.autoadjust=S\u00e4\u00e4d\u00e4 n\u00e4it\u00e4 asetuksia automaattisesti yhteysnopeuden perusteella
+ConfigView.label.start=K\u00e4ynnistys
+ConfigView.label.stop=Sammutus
+ConfigView.label.start.onlogin=K\u00e4ynnist\u00e4 Vuze koneeseen loggautumisen yhteydess\u00e4
+ConfigView.label.stop.seedcomp=Kun l\u00e4hetykset ovat valmiit:
+ConfigView.label.stop.downcomp=Kun lataukset ovat valmiit:
+ConfigView.label.stop.Nothing=\u00c4l\u00e4 tee mit\u00e4\u00e4n
+ConfigView.label.stop.QuitVuze=Sulje Vuze
+ConfigView.label.stop.Sleep=Tietokone valmiustilaan (standby)
+ConfigView.label.stop.Hibernate=Tietokone virransaa\u00e4st\u00f6tilaan (hibernate)
+ConfigView.label.stop.Shutdown=Sammuta tietokone
+core.shutdown.alert=Toiminto '%1' lauennut %2
+core.shutdown.dl=Lataukset ovat valmistuneet
+core.shutdown.se=L\u00e4hetykset ovat valmistuneet
+pairing.last.error=Viimeisin virhe
+MainWindow.menu.pairing=Et\u00e4-paritus
+ConfigView.label.pauseresume=Automaattinen tauko/jatkaminen
+update.now.title=P\u00e4ivitys tarvitaan
+update.now.desc=Vuzen pit\u00e4\u00e4 asentaa p\u00e4ivityksi\u00e4 toiminnon loppuunsaattamiseksi.\n\nT\u00e4m\u00e4n ikkunan sulkemisen j\u00e4lkeen Windows saattaa pyyt\u00e4\u00e4 luvan p\u00e4ivityksen tekemiseen.\n\nVuzen uudelleenk\u00e4ynnistyst\u00e4 ei tarvita.
+ConfigView.label.jvm=Java-asetukset
+platform.jvmopt.sunonly=Vain Sunin Java/JVM on tuettu (nyt k\u00e4yt\u00f6ss\u00e4 = %1)
+platform.jvmopt.configerror=Java/JVM-optioita ei voi asettaa konfigurointivirheen takia
+platform.jvmopt.nolinkfile=Java/JVM-optioiden k\u00e4sittely ei onnistu, koska migraatio ei ole valmis
+platform.jvmopt.nolink=Java/JVM-optioiden k\u00e4sittely ei onnistu aikaisemman konfiguroinnin takia
+platform.jvmopt.accesserror=Java/JVM-optiotiedoston k\u00e4sittely ei onnistu: %1
+pairing.status.noservices=Et\u00e4palveluita ei ole p\u00e4\u00e4ll\u00e4
+webui.pairingtest=\tPaina testataaksesi paritusta
+webui.connectiontest=\tPaina testataaksesi yhteytt\u00e4
+jvm.info=Vuzen pit\u00e4\u00e4 uudelleenk\u00e4ynnist\u00e4\u00e4, jos optioita muutetaan. *** Varoitus - Java JVM-optioiden virheellinen muuttaminen voi kaataa Vuzen tai est\u00e4\u00e4 sen normaalin toiminnan ***\n
+jvm.show.file=Paikallinen JVM-optioiden tiedosto on '%1' - Editoi sit\u00e4 suoraan vain palautumistarkoituksessa
+jvm.reset=Palauta JVM-optiot oletusarvoihin
+jvm.error=Virhe JVM-optioiden k\u00e4sittelyss\u00e4: %1
+ConfigView.section.invalid.value.title=Viallinen arvo
+ConfigView.section.invalid.value=Viallinen arvo '%1' sy\u00f6tetty '%2': %3
+Button.dismiss=Hylk\u00e4\u00e4
+webui.pairing.autoauth=K\u00e4yt\u00e4 oletussalasanoja: username=vuze, password=<pairing access code>
+ConfigView.label.stop.autoreset=Nollaa asetukset asentoon '%1', kun ne ovat lauenneet kerran
+remote.pairing.title=Et\u00e4-paritus
+remote.pairing.subtitle=Et\u00e4-Vuze mahdollistaa Vuzen et\u00e4hallinnan mist\u00e4 tahansa tietokoneen tai \u00e4lypuhelimen selaimesta
+remote.pairing.instruction=Sy\u00f6t\u00e4 oheinen tunnuskoodi et\u00e4sovelluksen tunnuskoodi-kentt\u00e4\u00e4n
+remote.pairing.functions=<A HREF="clip">Kopioi koodi leikep\u00f6yd\u00e4lle</A>   |   <A HREF="new">Hae uusi koodi</A>
+remote.pairing.tip.title=Vihje: Kaksi helppoa tapaa k\u00e4ytt\u00e4\u00e4 Vuzen et\u00e4yhteytt\u00e4:
+remote.pairing.tip.text=Vuze Et\u00e4yhteys-palkki: Mene <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nVuze Et\u00e4yhteys-mobiili: Mene <A HREF="http://remote.vuze.com/">remote.vuze.com</A>mobiiliselaimessasi.
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">Paritus-FAQs</A>
+remote.pairing.accesscode=Tunnuskoodi:
+remote.pairing.test.running=Kokeillaan et\u00e4yhteytt\u00e4...
+remote.pairing.test.success=Et\u00e4yhteys Vuzeen onnistui.
+remote.pairing.test.unavailable=Oi voi, et\u00e4yhteyden onnistumisesta ei saatu selkoa. <A HREF="retry">Kokeile uudelleen</A>
+remote.pairing.test.fail=Vuzeen ei saada yhteytt\u00e4 paikallisverkkosi ulkopuolelta.  <A HREF="/pairing_error_faq.start">Lue lis\u00e4\u00e4</A>
+update.fail.app.changed.title=P\u00e4ivitys ep\u00e4onnistui
+update.fail.app.changed=Vuzen pit\u00e4\u00e4 p\u00e4ivitt\u00e4\u00e4 itsens\u00e4, mutta se ei onnistu automaattisesti, koska sovelluksen nimi on vaihdettu muotoon '%1'.\n\nOle hyv\u00e4 ja lataa uusin asennusohjelma osoitteesta http://www.vuze.com/
+webui.port.override=Portin asetus: tarvitaan vain, jos julkinen portti eroaa NAT-asetusten takia sis\u00e4isest\u00e4 portista
+MainWindow.status.warning.tooltip=Paina t\u00e4st\u00e4, saat lis\u00e4tietoa
+search.dialog.text=Sy\u00f6t\u00e4 hakuteksti uusien torrentin l\u00f6yt\u00e4miseksi:
+core.not.available=Vuze on viel\u00e4 k\u00e4ynnistym\u00e4ss\u00e4. Yrit\u00e4 uudelleen hetken kuluttua
+Button.validate=Tarkista
+Button.getstarted=Aloita
+Button.goLibrary=Mene {library.name}
+dlg.player.install.subtitle=Asennus
+dlg.player.install.description=Asennetaan lis\u00e4osa soittosovellukseen...
+devices.xcode.remove.vetoed=Konvertointi '%1' on k\u00e4ynniss\u00e4, latausta/torrenttia ei voi poistaa ennen kuin konvertointi on valmis tai se on keskeytetty 'Oheislaitteet'-sivulta.
+Button.agree=Hyv\u00e4ksyn
+device.status.online=Oheislaite on p\u00e4\u00e4ll\u00e4
+device.itunes.status.running=iTunes on k\u00e4ynniss\u00e4
+device.itunes.status.notrunning=iTunes ei ole k\u00e4ynniss\u00e4
+device.itunes.status.notinstalled=iTunes ei ole asennettu
+OpenTorrentWindow.mb.notTorrent.retry=Magnet-haku
+ConfigView.section.ipfilter.clear.on.reload=Nollaa suodatintiedot p\u00e4ivitt\u00e4misen aluksi. Tietojen p\u00e4ivitt\u00e4misen aikana IP-suodatus ei ole k\u00e4yt\u00f6ss\u00e4. Jos optio ei ole p\u00e4\u00e4ll\u00e4, p\u00e4ivityksess\u00e4 poistuneet suodatintietueet poistuvat k\u00e4yt\u00f6st\u00e4 vasta Vuzen uudelleenk\u00e4ynnistyksen j\u00e4lkeen.
+view.waiting.core=N\u00e4kym\u00e4 tulee k\u00e4ytt\u00f6\u00f6n, kun Vuze on k\u00e4ynnistynyt kokonaan.
+devices.profile.direct=Suora
+cat.autoxcode=Auto-oheislaite
+ConfigView.section.tables=Taulukot
+ConfigView.section.style.useTree=N\u00e4yt\u00e4 my\u00f6s tiedostot {library.name}-n\u00e4kym\u00e4ss\u00e4 (vaatii uud.k\u00e4ynnistyksen)
+ConfigView.section.mode.resetdefaults=Palauta Vuzen asetukset oletusarvoiksi (uud.k\u00e4ynnistys suositellaan)
+resetconfig.warn.title=Vahvista toimenpide
+resetconfig.warn=Palautuksen seurauksena menet\u00e4t kaikki Vuzen asetuksiin tekem\u00e4si muutokset.\nTehd\u00e4\u00e4nk\u00f6 palautus?
+ConfigView.label.xfer.bias_up=Kasvata latausnopeutta painottamalla l\u00e4hetyskaistaa keskener\u00e4isten latausten eduksi
+ConfigView.label.xfer.bias_slack=KB/s minimi varattu l\u00e4hetett\u00e4ville torrenteille
+ConfigView.label.xfer.bias_no_limit=Yrit\u00e4 k\u00e4ytt\u00e4\u00e4 painotusta kun k\u00e4yt\u00f6ss\u00e4 ei ole globaalia l\u00e4hetysnopeuden rajoitusta
+SpeedView.stats.upload=L\u00e4hetett\u00e4v\u00e4n datan jono:
+SpeedView.stats.con=Yhteyksien tiedot:
+SpeedView.stats.con_details=Yhteens\u00e4=%1, sallittu=%2, jonossa=%3, estetty=%4
+SpeedView.stats.upbias=L\u00e4hetyksen suosiminen:
+dlg.install.mlab.subtitle=Asennetaan
+dlg.install.mlab.description=Odota kunnes nopeustestin komponentit on asennettu
+auto.mode=Auto (suositeltu)
+manual.mode=Manuaalinen
+configureWizard.transfer2.hint=L\u00e4hetysnopeuden yl\u00e4rajan asettaminen liian korkeaksi tai liian matalaksi heikent\u00e4\u00e4 suorituskyky\u00e4!
+configureWizard.transfer2.message=Bittorrent perustuu vastavuoroisuuteen - yleisesti ottaen mit\u00e4 nopeammin sin\u00e4 l\u00e4het\u00e4t dataa, sit\u00e4 nopeammin sin\u00e4 lataat muilta - hyv\u00e4 l\u00e4hetysnopeus parantaa siis latausnopeuttasi.\n\nJos kuitenkin yrit\u00e4t l\u00e4hett\u00e4\u00e4 nopeammin kuin mit\u00e4 internet-yhteytesi sallii, ylikuormitus voi hidastaa liikennett\u00e4 my\u00f6s muiden verkkoa k\u00e4ytt\u00e4vien sovellusten osalta.\n\nSiksi on t\u00e4rke\u [...]
+configureWizard.transfer2.group=Tapa
+configureWizard.transfer2.test.info=Valitse suorittaaksesi perusteellinen nopeustesti
+configureWizard.transfer2.test=Suorita testi
+configureWizard.transfer2.mselect=Valitse internet-yhteytesi suurin l\u00e4hetysnopeus
+configureWizard.transfer2.mselect.info=xxx/<arvo> kertoo internet-yhteyden l\u00e4hetysnopeuden bitti\u00e4 sekunnissa. Esim. ADSL 768 Kbps latausnopeus ja 384 Kbps l\u00e4hetysnopeus --> valitse 'xxx/384 kbit/sec'.\nPy\u00f6rist\u00e4 nopeutesi l\u00e4himp\u00e4\u00e4n arvoon, jos tarkkaa nopeuttasi ei ole tarjolla.
+configureWizard.transfer2.rate.unchanged=K\u00e4ytet\u00e4\u00e4n nykyisi\u00e4 asetuksia
+configureWizard.transfer2.rate.changed=Yhteyksien raja=%1\nK\u00e4ytett\u00e4v\u00e4 raja on %2 (max aktiivista torrettia=%3, max latauksia=%4)
+speedtest.wizard.select.title=Valitse ajettava nopeustesti
+speedtest.wizard.select.group=Testin tyyppi
+speedtest.wizard.select.general=Yleinen nopeustesti (suositeltu)
+speedtest.wizard.select.bt=Bittorrent-nopeustesti
+FileItem.storage.reorder=J\u00e4rjest\u00e4
+ConfigView.label.piecereorder=Kirjoita data ladattaessa tiedoston loppuun, ja j\u00e4rjest\u00e4 palat my\u00f6hemmin.
+ConfigView.label.piecereorderminmb=J\u00e4rjest\u00e4 vain yli x MB kokoiset tiedostot
+configureWizard.transfer2.current=<nykyiset asetukset>
+ConfigView.section.style.extendedErase=Piirr\u00e4 ruudukon viivat ja t\u00e4yt\u00e4 tyhj\u00e4t alueet
+iconBar.stream=Toista heti
+FilesView.menu.setpriority.numeric=Numeerinen...
+FilesView.dialog.priority.title=Sy\u00f6t\u00e4 numeerinen prioriteetti
+FilesView.dialog.priority.text=0=Normaali, 1=Korkea, 2=Korkeampi...
+beta.wizard.title=Beta-version asetukset
+beta.wizard.intro.title=Liittymisvalinta
+beta.wizard.info=Vuzen beta-ohjelmaan liittyminen mahdollistaa sinulle aikaisen tutustumisen uusiin tuleviin ominaisuuksiin.\n\nT\u00e4m\u00e4 mahdollistaa n\u00e4iden toiminnallisuuksien kokeilun ja vaikuttamisen niiden lopulliseen toteukseen - palautteesi on t\u00e4rke\u00e4\u00e4!\n\nBeta-versiot voivat olla ep\u00e4vakaita, mutta t\u00e4m\u00e4n asetuksen valinnalla saat k\u00e4ytt\u00f6\u00f6si melko vakaita beta-versioita. Jos haluat kaikkein uusimpia beta-versioita, k\u00e4yt\u00e [...]
+beta.wizard.link=Paina t\u00e4st\u00e4 beta-version sivulle p\u00e4\u00e4semiseksi
+beta.wizard.off=Ei kiitos, tyydyn virallisiin julkaisuversioihin!
+beta.wizard.on=P\u00e4ivit\u00e4 minut uusimpaan beta-versioon.
+beta.wizard.version=K\u00e4yt\u00e4t parhaillaan versiota %1
+beta.wizard.disable.title=Uudelleenk\u00e4ynnistys tarvitaan
+beta.wizard.disable.text=Kiitos beta versioiden kokeilemisesta!\n\nLataa ja asenna uusin virallinen versio lopettaaksesi beta-versioiden k\u00e4yt\u00f6n
+beta.wizard.forum=K\u00e4yt\u00e4 Vuze forumia palautteen antamiseen ja virheiden raportointiin
+dlg.install.vuzexcode.subtitle=Asennetaan media-analysointikomponenttia
+dlg.install.vuzexcode.description=Odota kunnes media-analysointikomponentin asennus valmistuu
+TableColumn.header.filecount=Tiedostot
+TableColumn.header.torrentspeed=Nopeus
+FileProgress.deleted=Poistettu
+priority.high=Korkea prioriteetti
+priority.normal=Normaali prioriteetti
+label.wrap.text=Jaa teksti riveille
+ScrapeInfoView.title=Ensisijainen seurantapalvelin
+Column.seedspeers.started=%1(%2)
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 kohdetta: %2 aktiivista
+library.incomplete.header.p=%1kohdetta latauksessa, %2 odottaa latausta
+library.unopened.header.p=%1 kohdetta
+library.all.header=%1 kohde: %2 aktiivista
+library.incomplete.header=%1 kohde latauksessa, %2 odottaa latausta
+library.unopened.header=%1 kohde
+ConfigView.section.style.status.show_rategraphs=N\u00e4yt\u00e4 nopeusgraafit alakulman lataus/l\u00e4hetysnopeuskenttien taustalla
+device.error.mountrequired="%1" tarvitsee k\u00e4ytt\u00f6\u00f6noton oheislaitteessasi
+v3.deviceview.infobar.line2.android=Mahdollista USB-tuki puhelimessasi siirt\u00e4\u00e4ksesi videot oikein.
+MyTorrents.column.ColumnProgressETA.compon=Valmistunut %1
+Sidebar.beta.title=Beta-ohjelma
+MainWindow.menu.beta.on=Osallistu Beta-ohjelmaan
+MainWindow.menu.beta.off=Poistu Beta-ohjelmasta
+Button.sendNow=L\u00e4het\u00e4 nyt
+Button.sendManual=L\u00e4het\u00e4 manuaalisesti (luo .zip-tiedosto)
+deletecontent.also.deletetorrent=Poista my\u00f6s .torrent-tiedosto
+ConfigView.section.file.deletion.section=Tiedoston poisto
+ConfigView.section.file.delete.torrent=Oletuksena poista my\u00f6s .torrent-tiedosto, kun poistetaan sis\u00e4lt\u00f6\u00e4
+ConfigView.section.file.delete.confirm=Kysy vahvistus, kun sis\u00e4lt\u00f6\u00e4 poistetaan Ty\u00f6kalupalkin painikkeella tai Delete-n\u00e4pp\u00e4imell\u00e4
+MainWindow.menu.view.beta=Beta-ohjelma
+ConfigView.section.server.enableudpprobe=Mahdollista UDP-palvelimen tarkistus HTTP-seurantapalvelimille
+jvm.options.summary=Yhteenveto nykyisist\u00e4 erityisasetuksista:
+device.showGeneric=N\u00e4yt\u00e4 geneeriset oheislaitteet
+Peers.column.Protocol=Protokolla
+devices.copying=Kopioidaan oheislaitteelle
+devices.cancel_xcode=Keskeyt\u00e4 konvertointi
+sidebar.header.transfers=Tiedostot
+sidebar.header.devices=Oheislaitteet
+sidebar.header.plugins=Lis\u00e4osat ja Extrat
+mdi.entry.about.devices=K\u00e4ynniss\u00e4
+mdi.entry.about.plugins=Tietoja lis\u00e4osista
+ConfigView.section.file.tb.delete=Kun poistetaan k\u00e4ytt\u00e4m\u00e4ll\u00e4 Delete-n\u00e4pp\u00e4int\u00e4 tai Poista-painiketta:
+ConfigView.tb.delete.ask=Kysy
+ConfigView.tb.delete.content=Poista tiedosto kysym\u00e4tt\u00e4
+ConfigView.tb.delete.torrent=Poista vain torrent kirjastosta
+search.export.all=Tallenna (export) kaikki hakupohjat...
+devices.cancel_xcode_del=Keskeyt\u00e4 konvertointi / Poista
+configureWizard.nat.title=Sis\u00e4\u00e4ntulevan TCP-liikenteen NAT-testi
+configureWizard.nat.message=Jotta Vuze saavuttaisi t\u00e4yden nopeuden, tulisi siihen voida muodostaa yhteys ulkoa p\u00e4in esteitt\u00e4. T\u00e4m\u00e4n ty\u00f6kalun avulla voit testata ja/tai vaihtaa "porttia", jota k\u00e4ytet\u00e4\u00e4n sis\u00e4\u00e4ntuleviin yhteyksiin.\n\nHuom.: TCP-portti 6880 on varattu Vuzen sis\u00e4iseen k\u00e4ytt\u00f6\u00f6n, joten se ei ole k\u00e4ytett\u00e4viss\u00e4.
+configureWizard.nat.server.udp_listen_port=Sis\u00e4\u00e4ntuleva UDP-portti
+v3.menu.device.defaultprofile.never=Ei konvertoida koskaan
+# Will be used for {library.name} in classic view
+library.name._classic=Siirrot
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Kirjasto
+ConfigView.section.style.units=K\u00e4ytetyt mittayksik\u00f6t
+ConfigView.section.style.CatInSidebar=N\u00e4yt\u00e4 luokat sivupalkissa
+library.category.header=Luokka '%1'
+device.import.title=Tuo oheislaitteen tiedot
+device.import.desc=Oletko varma, ett\u00e4 haluat tuoda oheislaitteen '%1'?
+device.import.dup.title=Tee kopio oheislaitteesta
+device.import.dup.desc=Oheislaite '%1' on jo olemassa.
+stream.analysing.media=Analysoidaan media
+device.export.select.template.file=Tallenna oheislaitteen tiedot
+stream.analysing.media.preview=Analysoidaan media (esikatselu)
+devices.restrict_access=Rajoita k\u00e4ytt\u00f6\u00e4...
+devices.restrict_access.prompt=K\u00e4ytt\u00f6 rajoitettu: '%1'
+devices.restrict_access.msg=Pilkuilla erotettu luettelo sallituista IP-osoitteista [tai kielletyist\u00e4 jos alkaa '-'-merkill\u00e4]
+TableColumn.TorrentStream.tooltip.disabled="Toista heti" ei tue t\u00e4t\u00e4 tiedostotyyppi\u00e4
+TableColumn.TorrentStream.tooltip.expand=Laajenna rivi n\u00e4hd\u00e4ksesi "Toista heti" yksitt\u00e4isille tiedostoille
+table.columns.reset=Palauta sarake-oletusasetukset
+rss.internal.test.url=Katso n\u00e4hd\u00e4ksesi paikallisen kotisivun
+cat.rss.gen=Luo paikallinen RSS-sy\u00f6te
diff --git a/org/gudy/azureus2/internat/MessagesBundle_fr_FR.properties b/org/gudy/azureus2/internat/MessagesBundle_fr_FR.properties
index c49efbd..a18ed48 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_fr_FR.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_fr_FR.properties
@@ -30,13 +30,10 @@ MainWindow.menu.window.alltofront=A&fficher tout devant
 MainWindow.menu.help=Aid&e
 MainWindow.menu.help.about=\u00c0 &propos...
 MainWindow.about.title=\u00c0 propos de Vuze
-MainWindow.about.section.developers=D\u00e9veloppeurs
-MainWindow.about.section.translators=Traducteurs
 MainWindow.about.section.system=Syst\u00e8me
 MainWindow.about.section.internet=Sur Internet
 MainWindow.about.internet.homepage=Page d'accueil de Vuze
 MainWindow.about.internet.sourceforge=Page Sourceforge
-MainWindow.about.internet.sourceforgedownloads=T\u00e9l\u00e9chargements sur Sourceforge
 MainWindow.about.internet.bugreports=Rapporter un bogue
 MainWindow.about.internet.forumdiscussion=Forum g\u00e9n\u00e9ral
 MainWindow.about.internet.wiki=Wiki FAQ Vuze
@@ -292,8 +289,6 @@ IrcView.errormsg=Erreur de syntaxe /msg : /msg [utilisateur] texte
 IrcView.help=Commandes valides :\n . /help : affiche ce message\n . /nick | /name : change votre alias\n . /me action : envoie une action \n . /msg [utilisateur] message : envoie un message priv\u00e9 \u00e0 <alias>\n . /r message : r\u00e9pond au dernier message priv\u00e9\n . /join #canal : change le canal actuel
 PasswordWindow.title=Vuze est barr\u00e9
 PasswordWindow.passwordprotected=Vuze est prot\u00e9g\u00e9 par un mot de passe.\nPour r\u00e9tablir Vuze veuillez entrer votre mot de passe :
-TrackerChangerWindow.title=Ajouter/changer le tracker
-TrackerChangerWindow.newtracker=Entrer la nouvelle URL du tracker
 PeersView.discarded=Rejet\u00e9
 PeersView.discarded.info=Pi\u00e8ces re\u00e7ues alors que vous les aviez d\u00e9j\u00e0. Elimin\u00e9es.
 discarded=rejet\u00e9s
@@ -360,7 +355,6 @@ MyTorrentsView.menu.removeand.deletetorrent=effacer le fichier &torrent
 MyTorrentsView.menu.removeand.deletedata=effacer les &donn\u00e9es
 MyTorrentsView.menu.removeand.deleteboth=e&ffacer tout
 deletedata.title=!!! Attention !!!
-deletedata.message1=Vous vous appr\u00eatez \u00e0 effacer les DONN\u00c9ES de\u00a0:\n
 MainWindow.menu.file.configure=&Assistant de configuration
 configureWizard.title=Assistant de Configuration
 configureWizard.welcome.title=Bienvenue dans l'Assistant de Configuration de Vuze
@@ -382,7 +376,6 @@ configureWizard.transfer.maxActiveTorrents=Maximum Actifs
 configureWizard.transfer.maxDownloads=T\u00e9l\u00e9chargements Max
 configureWizard.transfer.maxUploadsPerTorrent=Max Envois par Torrent
 configureWizard.nat.title=NAT / Port du Serveur
-configureWizard.nat.message=Pour une utilisation optimale de BitTorrent, il est conseill\u00e9 d'\u00eatre pleinement accessible depuis internet. BitTorrent utilise seulement le port 6881 par d\u00e9faut. Cet assistant vous permet de tester et / ou de changer ce port. Si vous avez des t\u00e9l\u00e9chargements en cours, certains ports ne pourront pas \u00eatre test\u00e9s.
 configureWizard.nat.test=Test en cours
 configureWizard.nat.testing=Test du port
 configureWizard.nat.ko=Erreur NAT
@@ -532,7 +525,6 @@ IPChecker.external.service.no-ip.url=www.no-ip.com
 IPChecker.external.service.no-ip.description=Fournisseur de services DNS dynamique et statique\n(aucun service de v\u00e9rification d'IP gratuit)
 ConfigView.section.tracker.publicenable=Autoriser les torrents externes
 ConfigView.label.playdownloadspeech=Jouer \u00e0 la fin d'un t\u00e9l\u00e9chargement
-ConfigView.label.playdownloadspeech.info=Les services de parole fonctionnent actuellement mieux en anglais
 #
 # Tooltips
 #
@@ -702,8 +694,6 @@ plugin.sharing.download.remove.veto=Ce t\u00e9l\u00e9chargement provient d'une r
 ConfigView.section.tracker.main=Principal
 ConfigView.label.prioritizefirstpiece=Donner la priorit\u00e9 aux premi\u00e8res pi\u00e8ces de fichiers
 ConfigView.label.prioritizefirstpiece.tooltip=Tente de t\u00e9l\u00e9charger le d\u00e9but d'un fichier en premier.\nPeut permettre la pr\u00e9visualisation.
-ConfigView.section.file.confirm_data_delete=Demander une confirmation avant d'effacer les donn\u00e9es
-ConfigView.section.file.confirm_data_delete.tooltip=Demande une confirmation quand "Enlever et effacer..." est utilis\u00e9.
 TrayWindow.menu.startalldownloads=&D\u00e9marrer tous les t\u00e9l\u00e9chargements
 SystemTray.menu.startalltransfers=&D\u00e9marrer tous les transferts
 sharing.progress.title=\u00c9tat du partage
@@ -1005,7 +995,6 @@ ConfigView.pluginlist.whereToPutOr=Pour un plugin partag\u00e9, utiliser:
 MainWindow.statusText.checking=V\u00e9rification des mises \u00e0 jour
 TableColumn.header.OnlyCDing4=EnSourceDepuis
 TableColumn.header.OnlyCDing4.info=Dur\u00e9e pendant laquelle le torrent n'a fait qu'\u00eatre en source. Ne prend pas en compte le temps de t\u00e9l\u00e9chargement.
-ConfigView.section.style.alternateTablePainting=Utiliser une m\u00e9thode alternative pour tracer les colonnes des tables graphiques (peut necessiter un red\u00e9marrage)
 UpdateWindow.status.restartMaybeNeeded=Un red\u00e9marrage sera peut-\u00eatre necessaire
 ConfigView.pluginlist.shared=partag\u00e9
 PeersView.host=Nom d'h\u00f4te
@@ -1115,8 +1104,6 @@ MyTrackerView.badnat.info=Sources/Clients ayant echou\u00e9s au test NAT, si act
 ConfigView.section.tracker.natchecktimeout=Expiration de la v\u00e9rification (secs)
 ConfigView.section.file.perf.cache.enable=Activer le cache disque
 ConfigView.section.file.perf.cache.size=Taille du cache en %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=&Transferts
 MainWindow.menu.transfers.startalltransfers=&D\u00e9marrer tout
 MainWindow.menu.transfers.stopalltransfers=&Arr\u00eater tout
@@ -1226,18 +1213,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Taille de la socket SO_RCVBUF [
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=R\u00e8gle la taille du socket standard SO_RCVBUF (en octets), soit l'\u00e9chelle et la taille de la fen\u00eatre de reception TCP.\nVuze laisse ce champ vide par d\u00e9faut, donc les valeurs par d\u00e9fault du syst\u00e8me d'exploitation sont utilis\u00e9es.\nNOTE: Linux double la valeur indiqu\u00e9e.
 ConfigView.section.connection.advanced.SO_SNDBUF=Taille de la socket SO_SNDBUF [0: utilise la valeur par d\u00e9faut du syst\u00e8me d'exploitation]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=R\u00e8gle la taille du socket standard SO_SNDBUF (en octets), soit la taille de la fen\u00eatre d'envoi TCP.\nVuze laisse ce champ vide par d\u00e9faut, donc les valeurs par d\u00e9fault du syst\u00e8me d'exploitation sont utilis\u00e9es.\nNOTE: Linux double la valeur indiqu\u00e9e.
-ConfigView.section.interface.confirm_torrent_removal=Afficher une fen\u00eatre de confirmation pour supprimer un torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Demande confirmation lors de la suppression d'un torrent de la vue Mes Torrents.
-MyTorrentsView.confirm_torrent_removal=Confirmation de la suppression\u00a0?\n
 TableColumn.header.seed_to_peer_ratio=TauxSources/Clients
 TableColumn.header.seed_to_peer_ratio.info=Taux global sources/clients du groupe
 PeersView.connected_time=Temps connect\u00e9
 PeersView.connected_time.info=Temps total de connexion avec le client
-ConfigView.section.interface.display.add_torrents_silently=Ajouter les torrents silencieusement
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Ajouter les torrents sans activer la fen\u00eatre principale d'Azureus.
 TableColumn.header.maxdownspeed=Vit. T\u00e9l. max
 TableColumn.header.maxdownspeed.info=Vitesse maximale de t\u00e9l\u00e9chargement par torrent
-PeersGraphicView.title=Essaim
+PeersGraphicView.title.full=Essaim
 ConfigView.section.tracker.passwordwebhttpsonly=Ne permet que l'acc\u00e8s par HTTPS
 TableColumn.header.torrentpath=Chemin d'acc\u00e8s du torrent
 TableColumn.header.torrentpath.info=Chemin d'acc\u00e8s du torrent sur le disque
@@ -1292,8 +1274,6 @@ UpdateWindow.restartLater=Red\u00e9marrer plus tard
 MainWindow.menu.file.restart=Red\u00e9marrer
 MainWindow.dialog.restartconfirmation.title=Red\u00e9marrer Vuze u00a0?
 MainWindow.dialog.restartconfirmation.text=Voulez-vous vraiment red\u00e9marrer Vuze u00a0?
-deletetorrent.message1=Vous vous appr\u00eatez \u00e0 supprimer le TORRENT pour\u00a0:\n
-deletetorrent.message2=\nEtes-vous s\u00fbrs de vouloir continuer\u00a0?
 ConfigView.label.prioritizemostcompletedfiles=Donner priorit\u00e9 aux fichiers les plus avanc\u00e9s
 splash.plugin.init=Initialisation du Plugin: 
 ConfigView.section.style.osx_small_fonts=Utiliser une petite police [red\u00e9marrage n\u00e9cessaire]
@@ -1443,7 +1423,6 @@ MainWindow.menu.file.open.torrentfortracking=Fichier Torrent... (Tracking Unique
 MyTrackerView.date_added=Ajout\u00e9
 ConfigView.section.tracker.portbackup=Ports de r\u00e9serve (s\u00e9par\u00e9s par ';')
 ConfigView.label.playfilespeech=Parler \u00e0 la fin du t\u00e9l\u00e9chargement d'un fichier
-ConfigView.label.playfilespeech.info=Les services "parl\u00e9s" fonctionne le mieux en anglais
 ConfigView.label.playfilefinished=Jouer un son \u00e0 la fin du t\u00e9l\u00e9chargement d'un fichier
 ConfigView.label.backupconfigfiles=Sauvegarder les fichiers de configuration (pour r\u00e9cup\u00e9ration \u00e9ventuelle)
 ConfigView.section.tracker.client.scrapesingleonly=D\u00e9sactiver l'agr\u00e9gation de scrape par tracker (peut \u00e9viter les erreurs du type 'URL too long' (414))
@@ -1686,11 +1665,6 @@ TableColumn.header.Rating=Note
 TableColumn.header.SpeedGraphic=Vitesse
 TableColumn.header.AzProduct=De
 TableColumn.header.ProgressETA=Avancement
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
 v3.MainWindow.tab.home=Accueil
 v3.MainWindow.tab.browse=Sur Vuze
 v3.MainWindow.tab.library=Biblioth\u00e8que
@@ -1723,7 +1697,6 @@ v3.mb.delPublished.delete=&Supprimer
 v3.mb.delPublished.cancel=&Annuler
 v3.mb.deletePurchased.button.delete=&Supprimer
 v3.mb.deletePurchased.button.cancel=&Annuler
-#
 # Used for peers which we can't determine.
 PeerSocket.unknown=Inconnu
 Content.alert.notuploaded.button.stop=&Arr\u00eater
@@ -1750,13 +1723,7 @@ v3.MainWindow.tab.minilibrary=T\u00e9l\u00e9chargements
 v3.MainWindow.tab.events=Activit\u00e9s
 v3.activity.remove.title=Supprimer l'entr\u00e9e d'activit\u00e9
 v3.activity.remove.text=Etes vous s\u00fbr de vouloir supprimer l'entr\u00e9e d'activit\u00e9 '%1' ?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
 v3.MainWindow.menu.file.closewindow=Fermer
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
 v3.button.removeActivityEntry=Supprimer l'entr\u00e9e d'activit\u00e9
 ConfigView.copy.to.clipboard.tooltip=Copier dans le presse-papier
 Browser.popup.error.no.access=Une erreur s'est produite lors de la tentative d'acc\u00e9der \u00e0 une ressource \u00e9loign\u00e9e. \nR\u00e9essayez ult\u00e9rieurement. \n 
@@ -1808,27 +1775,86 @@ azbuddy.os_offline=D\u00e9connect\u00e9
 azbuddy.ui.menu.disconnect=D\u00e9connect\u00e9
 azbuddy.enable_chat_notif=Activer les notifications du chat
 DetailedListView.title=Liste d\u00e9taill\u00e9e
+subscript.add.title=Installer l'abonnement?
+subscript.add.desc=Voulez vous installer l'abonnement '%1'?
+subscript.add.dup.title=Abonnement en double
+subscript.add.dup.desc=L'abonnement '%1' est d\u00e9ja install\u00e9.
+subscript.add.upgrade.title=Mettre \u00e0 jour l'abonnement?
+subscript.add.upgrade.desc=Voulez vous mettre \u00e0 jour l'abonnement '%1'?
+subscript.add.upgradeto.desc=La version %1 de l'abonnement '%2' est disponible.\nVoulez vous mettre a jour?
 iconBar.queue.tooltip=File d'attente
+subscriptions.listwindow.title=Abonnements
+subscriptions.listwindow.autochecktext=Vuze peut trouver des abonnements li\u00e9s au contenu de votre bibliotheque. Voulez vous activer cette option?
+subscriptions.listwindow.loadingtext=Recherche d'abonnements li\u00e9s \u00e0 '%1'
+subscriptions.listwindow.failed=Pas d'abonnements trouv\u00e9s
+subscriptions.listwindow.popularity=Popularit\u00e9
+subscriptions.listwindow.popularity.unknown=Inconnu
+subscriptions.listwindow.name=Nom
+subscriptions.listwindow.subscribe=Abonnement
+subscriptions.listwindow.popularity.reading=Lecture...
 MainWindow.menu.help.faq=&FAQ
-sidebar.Library=Ma biblioth\u00e8que
+Subscription.menu.forcecheck=Mettre \u00e0 jour
+Subscription.menu.clearall=Marquer tous les r\u00e9sultats lus
+Subscription.menu.remove=Effacer
+sidebar.Library=Biblioth\u00e8que
 sidebar.LibraryDL=T\u00e9l\u00e9chargement
 sidebar.LibraryCD=Termin\u00e9
 authenticator.location=Lieu
 authenticator.details=D\u00e9tails
+Subscription.menu.export=Exporter
+subscript.export.select.template.file=Sauver
 Button.back=Retour
 sidebar.LibraryUnopened=Non visionn\u00e9s
-#what you've watched? Discover more with a single click...
+Subscription.menu.deleteall=Effacer tous les r\u00e9sultats
+Subscription.menu.reset=R\u00e9initialiser
+ConfigView.section.Subscriptions=Abonnements
+subscriptions.config.maxresults=Nombre maximum de r\u00e9sultats memoris\u00e9s par abonnement [0: illimit\u00e9]
+Subscription.menu.resetauth=R\u00e9initialiser les details d'authentification
+Wizard.Subscription.title=Abonnement
+Wizard.Subscription.optin.title=Activer les abonnements
+Wizard.Subscription.subscribe.title=Abonnements disponibles
+Wizard.Subscription.create.title=Cr\u00e9er un nouvel abonnement
 Button.add=Ajouter
+Button.createNewSubscription=Nouvel Abonnement
+Button.availableSubscriptions=Abonnements disponibles
+Wizard.Subscription.optin.description=En activant les abonnements, Vuze vous montrera les abonnements li\u00e9s au contenu de votre biblioth\u00e8que, et vous permettra de savoir quand le contenu de votre abonnement est disponible au t\u00e9l\u00e9chargement.\n\nSouhaitez-vous activer les abonnements?
+Wizard.Subscription.search.subtitle1=Tapez une recherche afin de commencer \u00e0 cr\u00e9er votre abonnement:
+Wizard.Subscription.search.subtitle2=Que puis-je rechercher?
+Wizard.Subscription.search.subtitle2.sub1=HD Movies, TV Shows, Films, Bandes-annonces sur le r\u00e9seau Vuze
+Wizard.Subscription.search.subtitle2.sub2=Torrents \u00e0 travers tout le Web
+Wizard.Subscription.search.subtitle3=Une fois votre abonnement compl\u00e9t\u00e9, vous recevrez des mises \u00e0 jour dans votre barre lat\u00e9rale lorsque de nouveaux r\u00e9sultats sont disponibles pour votre recherche.
+Wizard.Subscription.rss.subtitle1=Tapez ou collez l'URL ci-dessous:
+Wizard.Subscription.rss.subtitle2=De nombreux \u00e9diteurs fournissent des flux RSS de leur contenu. Localiser l'URL sur le site de l'\u00e9diteur, copiez et collez l'URL dans le champ ci-dessus, puis cliquez sur Enregistrer.
+Wizard.Subscription.rss.subtitle3=Une fois enregistr\u00e9, vous recevrez des mises \u00e0 jour dans votre barre lat\u00e9rale lorsque de nouveaux r\u00e9sultats sont disponibles via votre flux RSS.
+Wizard.Subscription.subscribe.library=Contenu dans votre biblioth\u00e8que
+Wizard.Subscription.subscribe.subscriptions=Abonnements connexes
+Wizard.Subscription.subscribe.library.empty=Pas d'abonnement disponible?\n \nCherchez le bouton d'abonnement orange vif sur le r\u00e9seau HD Vuze.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions"> En savoir plus </A>
 message.confirm.delete.title=Confirmer la suppression
 message.confirm.delete.text=\u00cates-vous certain de vouloir supprimer '%1'?
+Subscription.menu.properties=Propri\u00e9t\u00e9s
 props.window.title=Propri\u00e9t\u00e9s pour '%1'
+subscriptions.column.new.info=Indique si plus d'un nouveau r\u00e9sultat
+subscriptions.column.name=Abonnement
+subscriptions.column.nb-results=R\u00e9sultats
+subscriptions.column.nb-new-results=Nouveaux r\u00e9sultats
+subscriptions.column.last-checked=Derniere v\u00e9rification
+subscriptions.view.title=Abonnements
+Subscription.menu.upgrade=Activer la mise \u00e0 jour a une version sup\u00e9rieure
+subscription.version.bad=L'abonnement '%1' ne peut \u00eatre install\u00e9 qu'apres avoir mis Vuze \u00e0 jour
+subscriptions.view.help.1=Ajoutez des abonnement partout o\u00f9 vous voyez
+subscriptions.view.help.2=Obtenez gratuitement des mises \u00e0 jour chaque fois qu'un nouveau contenu est disponible en t\u00e9l\u00e9chargement. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">En savoir plus</A>.
+subscript.some.subscribed=Vous \u00eates abonn\u00e9s \u00e0 un ou plusieurs abonnements pour ce contenu.\nCliquez pour voir tous les abonnements displonibles.
+subscript.none.subscribed=Cliquer pour voir les abonnement disponibles pour ce contenu
+TableColumn.header.azsubs.ui.column.subs_link.info=Associ\u00e9s \u00e0 des abonnements
 Button.deleteContent.fromComputer=Supprimer de votre ordinateur
+Subscription.menu.dirtyall=Marquer tous les r\u00e9sultats non lus
 configureWizard.file.message3=Vuze placera les fichiers t\u00e9l\u00e9charg\u00e9s dans un dossier sp\u00e9cifique, vous pouvez choisir ce dossier ici:
 azbuddy.ui.menu.cat=Cat\u00e9gories
 azbuddy.ui.menu.cat.set=Entrez des cat\u00e9gories
 azbuddy.ui.menu.cat.set_msg=S\u00e9parez la liste des cat\u00e9gories par des virgules, ou marquez "Tous"
 azbuddy.ui.menu.cat_subs=S'abonner
 azbuddy.enable_cat_pub=Cat\u00e9gories publiques auxquelles TOUS vos amis peuvent s'abonner (s\u00e9par\u00e9 par des ',')
+devices.view.title=P\u00e9riph\u00e9riques
 device.browse=Parcourir
 ConfigView.label.maxStalledSeeding=Maximum 'stalled' [0: illimit\u00e9]
 General.percent=Pourcent
@@ -1841,3 +1867,23 @@ device.itunes.start=Vous devez d\u00e9marrer iTunes ou activer le d\u00e9marrage
 device.itunes.install_problem=Il semble y avoir un probl\u00e8me avec l'int\u00e9gration d'iTunes 
 option.askeverytime=Demander \u00e0 chaque fois
 option.rememberthis=Se souvenir de ce r\u00e9glage
+Subscription.menu.setcookies=Configurer les cookies
+subscriptions.config.autostartdls=D\u00e9marrer les t\u00e9l\u00e9chargements automatiquement (sinon ils s'ajoutent arr\u00eat\u00e9s)
+subscriptions.config.autostart.min=Ne d\u00e9marre que si >= Mo [0: illimit\u00e9]
+subscriptions.config.autostart.max=Ne d\u00e9marre que si <= Mo [0: illimit\u00e9]
+subscriptions.column.nb-subscribers=Abonn\u00e9s
+subscriptions.rss.enable=Cr\u00e9er un flux RSS \u00e0 partir d'un abonnement
+
+v3.MainWindow.menu.getting_started=&Premiers Pas
+MainWindow.menu.community=&Communaut\u00e9
+MainWindow.menu.help.faq=Questions &Fr\u00e9quentes (FAQ)
+MainWindow.menu.help.faq.keybinding.mac=Meta+?
+MainWindow.menu.community.wiki=&Wiki Communautaire
+MainWindow.menu.community.forums=Fo&rum Communautaire
+MainWindow.menu.community.blog=&Blog
+MainWindow.menu.help.support=&Aide
+
+mdi.entry.plus.full=Vuze Plus
+mdi.entry.plus.free=Vuze Plus
+mdi.entry.dvdburn=Gravure de DVD
+mdi.entry.dvdburn.new=Nouveau DVD
diff --git a/org/gudy/azureus2/internat/MessagesBundle_fy_NL.properties b/org/gudy/azureus2/internat/MessagesBundle_fy_NL.properties
index 8812f75..9f7747a 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_fy_NL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_fy_NL.properties
@@ -31,12 +31,9 @@ MainWindow.menu.window.alltofront=Alle naar voren brengen
 MainWindow.menu.help=&Help 
 MainWindow.menu.help.about=Oer &Vuze
 MainWindow.about.title=Ynfo oer Vuze
-MainWindow.about.section.developers=Ontwikkelaars 
-MainWindow.about.section.translators=Fertellers
 MainWindow.about.section.internet=Ynternet 
 MainWindow.about.internet.homepage=Thuispagina Vuze
 MainWindow.about.internet.sourceforge=Sourceforge-projectpagina 
-MainWindow.about.internet.sourceforgedownloads=Sourceforge-Downloads 
 MainWindow.about.internet.bugreports=Foutrapportages 
 MainWindow.about.internet.wiki=Veelgestelde vragen over Vuze Wiki
 MainWindow.dialog.choose.savepath=Kies het pad voor opslag
@@ -284,8 +281,6 @@ IrcView.help=Geldige commando's zijn :\n . /help : geeft dit bericht weer\n . /n
 PasswordWindow.title=Vuze is geblokkeerd 
 PasswordWindow.passwordprotected=Vuze is beschermd met een wachtwoord.\nVul hier je wachtwoord in, om het venster te tonen :
 Button.ok=Ok
-TrackerChangerWindow.title=Voeg Tracker toe
-TrackerChangerWindow.newtracker=Vul een nieuw trackeradres in
 PeersView.discarded=Negearje
 PeersView.discarded.info=Gegevens die je ontvangen hebt maar niet nodig hebt en daarom verwijderd zijn.
 discarded=\u00f4ftankje
@@ -356,7 +351,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Verwijder .&torrent
 MyTorrentsView.menu.removeand.deletedata=Verwijder &gegevens
 MyTorrentsView.menu.removeand.deleteboth=Verwijder &beide
 deletedata.title=Warsk\u00f4ging!
-deletedata.message1=Je staat op het punt de GEGEVENS te verwijderen van:\n
 MainWindow.menu.file.configure=Konfiguraasjewizard...
 configureWizard.title=Configuratiewizard 
 configureWizard.welcome.title=Wolkom by de konfiguraasjewizard fan Vuze
@@ -377,7 +371,6 @@ configureWizard.transfer.maxActiveTorrents=Max Actief
 configureWizard.transfer.maxDownloads=Maks Downloads
 configureWizard.transfer.maxUploadsPerTorrent=Maks Uploads per Torrent
 configureWizard.nat.title=NAT / Server Poorten 
-configureWizard.nat.message=Om het beste uit Bittorrent te behalen is het raadzaam om goed bereikbaar te zijn vanaf het internet. De standaard poort is 6881. Dit programma helpt met het testen / veranderen van de poort.
 configureWizard.nat.testing=Testen van poort 
 configureWizard.nat.ok=Ok !
 configureWizard.nat.ko=NAT-Fout 
@@ -523,7 +516,6 @@ ConfigView.section.file.decoder.label=Standaard torrentcodering wanneer selectie
 ConfigView.section.file.decoder.nodecoder=Gjin
 ConfigView.section.tracker.publicenable=Externe torrents toestaan 
 ConfigView.label.playdownloadspeech=Geef met spraak aan wanneer een download voltooid is
-ConfigView.label.playdownloadspeech.info=De spraakservice werkt momenteel het beste met Engels
 #
 # Tooltips
 #
@@ -690,8 +682,6 @@ ConfigView.section.tracker.main=Hoofd
 ConfigView.section.tracker.web=Web 
 ConfigView.label.prioritizefirstpiece=Geef het eerste deel van bestand(en) voorrang
 ConfigView.label.prioritizefirstpiece.tooltip=Probeert het eerste deel van een bestand eerst te downloaden.\nOm previews te ondersteunen.
-ConfigView.section.file.confirm_data_delete=Bevestig het verwijderen van gegevens
-ConfigView.section.file.confirm_data_delete.tooltip=Bevestig het verwijderen van gegevens bij het gebruik van 'Verplaats en Verwijder...'
 TrayWindow.menu.startalldownloads=Alle oerhellings starten
 SystemTray.menu.startalltransfers=Start Alle Overdrachten
 sharing.progress.title=Voortgang van het Delen
@@ -983,7 +973,6 @@ ConfigView.pluginlist.whereToPutOr=Gebruik voor gedeelde plugins:
 MainWindow.statusText.checking=Controleren op Updates
 TableColumn.header.OnlyCDing4=AlleenUploaden
 TableColumn.header.OnlyCDing4.info=Hoeveelheid tijd waarin de torrent alleen aan het uploaden was.  Exclusief de tijd dat de torrent aan het downloaden was (en uploaden)
-ConfigView.section.style.alternateTablePainting=Gebruik alternatieve methode om grafische tabel colommen te tekenen (kan herstart nodig hebben)
 UpdateWindow.status.restartMaybeNeeded=Herstart kan nodig zijn
 ConfigView.pluginlist.shared=gedeeld
 PeersView.host=Hostnaam
@@ -1197,15 +1186,10 @@ wizard.maketorrents.autoopen=De torrent voor uploaden gebruiken indien voltooid
 ConfigView.section.connection.advanced.mtu=Maximale overdrachtseenheid van de lijn (MTU)
 ConfigView.section.connection.advanced.SO_RCVBUF=Grootte van Socket SO_RCVBUF[0: gebruik standaard besturingssysteem]
 ConfigView.section.connection.advanced.SO_SNDBUF=Grotte Socket SO_SNDBUF [0: gebruik standaard besturingssysteem]
-ConfigView.section.interface.confirm_torrent_removal=Om befestiching freegje as in torrent fuortsmite wurdt
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Om befestiching freegje as in torrent fuortsmite wurdt \u00fat it skerm MyTorrents
-MyTorrentsView.confirm_torrent_removal=Weet je zeker dat je deze torrent wilt verplaatsen?\n
 TableColumn.header.seed_to_peer_ratio=Naar uploader overgebracht
 TableColumn.header.seed_to_peer_ratio.info=Verhouding van totaal downloads naar uploaders in zwerm
 PeersView.connected_time=Verbindingsduur
 PeersView.connected_time.info=De totale tijd van de verbinding met de cli\u00ebnt
-ConfigView.section.interface.display.add_torrents_silently=Torrents op de achtergrond toevoegen
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Torrents toevoegen zonder het hoofdscherm vna Vuze te openen.
 TableColumn.header.maxdownspeed=Max downloadsnelheid
 TableColumn.header.maxdownspeed.info=Max Downloadsnelheid per torrent
 ConfigView.section.tracker.passwordwebhttpsonly=Alleen toegang via HTTPS toestaan
@@ -1233,8 +1217,6 @@ MyShares.column.category=Kategory
 MainWindow.menu.file.restart=Vuze opnieuw opstarten
 MainWindow.dialog.restartconfirmation.title=Vuze opnij opstarte?
 MainWindow.dialog.restartconfirmation.text=Vuze opnij opstarte?
-deletetorrent.message1=Je staat op het punt de TORRENT te verwijderen van:\n
-deletetorrent.message2=\nWolst trochgean?
 ConfigView.label.prioritizemostcompletedfiles=Prioriteer meest-voltooide bestanden
 ConfigView.section.tracker.nonblocking=Opties voor het niet blokkeren
 ConfigView.section.tracker.nonblockingconcmax=Maximum aantal aanvragen tegelijkertijd [0: ongelimiteerd]
diff --git a/org/gudy/azureus2/internat/MessagesBundle_gl_ES.properties b/org/gudy/azureus2/internat/MessagesBundle_gl_ES.properties
index 32ba8b9..f82dcf6 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_gl_ES.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_gl_ES.properties
@@ -26,12 +26,9 @@ ConfigView.section.language=Lingua
 MainWindow.menu.help=Axuda 
 MainWindow.menu.help.about=Cr\u00e9ditos do Vuze
 MainWindow.about.title=Cr\u00e9ditos 
-MainWindow.about.section.developers=Desenvolvedores 
-MainWindow.about.section.translators=Traductores 
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.homepage=P\u00e1xina do Vuze
 MainWindow.about.internet.sourceforge=P\u00e1xina do proxecto en Sourceforge 
-MainWindow.about.internet.sourceforgedownloads=Descargas dende Sourceforge 
 MainWindow.about.internet.bugreports=Informe de erros 
 MainWindow.about.internet.forumdiscussion=Foro xeral 
 MainWindow.dialog.choose.savepath=Escolla a carpeta para a descarga 
@@ -262,8 +259,6 @@ IrcView.help=Os comandos v\u00e1lidos son :\n . /help : amosa esta mensaxe\n . /
 PasswordWindow.title=Vuze est\u00e1 protexido con contrasinal 
 PasswordWindow.passwordprotected=Vuze est\u00e1 protexido con contrasinal.\nPara restaurar Vuze pr\u00e9gase escriba o seu contrasinal aqu\u00ed : 
 Button.ok=Ok 
-TrackerChangerWindow.title=Cambiar Tracker 
-TrackerChangerWindow.newtracker=Introduza a nova url do Tracker 
 PeersView.discarded=Descartado 
 discarded=descartado 
 MyTorrentsView.#=# 
@@ -334,7 +329,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Borrar .torrent
 MyTorrentsView.menu.removeand.deletedata=Borrar datos 
 MyTorrentsView.menu.removeand.deleteboth=Borrar ambos 
 deletedata.title=Precauci\u00f3n!!! 
-deletedata.message1=Vostede est\u00e1 a piques de borra-los datos contidos en :\n 
 MainWindow.menu.file.configure=Asistente de configuraci\u00f3n 
 configureWizard.title=Asistente de configuraci\u00f3n 
 configureWizard.welcome.title=Benvido ao asistente de configuraci\u00f3n do Vuze
@@ -353,7 +347,6 @@ configureWizard.transfer.maxActiveTorrents=M\u00e1x. Activos
 configureWizard.transfer.maxDownloads=M\u00e1x. Descargas 
 configureWizard.transfer.maxUploadsPerTorrent=M\u00e1x. envios por Torrent 
 configureWizard.nat.title=NAT / Portos do servidor 
-configureWizard.nat.message=Se desexas obter o mellor de BitTorrent, \u00e9 moi recomend\u00e1bel que poidas conectar directamente dende Internet. O rango de portos por defecto de BitTorrent vai dende 6881 ata 6889. Esta ferramenta perm\u00edteche probar e/ou mudar de portos. Se tes algunha descarga activa, \u00e9 pos\u00edbel que alg\u00fans portos non sexan acces\u00edbeis. 
 configureWizard.nat.test=Probar 
 configureWizard.nat.testing=Probando portos 
 configureWizard.nat.ok=Ok 
diff --git a/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties b/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
index 8424e66..cd05eca 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_hu_HU.properties
@@ -35,12 +35,9 @@ MainWindow.menu.window.alltofront=Mindent el\u0151t\u00e9rben
 MainWindow.menu.help=&S\u00fag\u00f3
 MainWindow.menu.help.about=Vuze N\u00e9vjegye
 MainWindow.about.title=N\u00e9vjegy
-MainWindow.about.section.developers=Fejleszt\u0151k
-MainWindow.about.section.translators=Ford\u00edt\u00f3k
 MainWindow.about.section.system=Rendszer
 MainWindow.about.internet.homepage=Vuze Honlapja
 MainWindow.about.internet.sourceforge=Sourceforge Project honlapja
-MainWindow.about.internet.sourceforgedownloads=Sourceforge Let\u00f6lt\u00e9sek
 MainWindow.about.internet.bugreports=Hibajelent\u00e9s
 MainWindow.about.internet.forumdiscussion=F\u00f3rumok
 MainWindow.about.internet.wiki=Vuze Wiki GYIK
@@ -307,8 +304,6 @@ IrcView.errormsg=Hib\u00e1s szintaxis: helyes /msg \u00fczenet
 IrcView.help=\u00c9rv\u00e9nyes parancsok: \n . /help : megjelen\u00edti ert az \u00fczenetet\n . /nick | /name : becenevet v\u00e1ltoztat \n . /me sz\u00f6veg : cselekv\u00e9st imit\u00e1l \n . /msg becen\u00e9v \u00fczenet : szem\u00e9lyes \u00fczenetet k\u00fcld <becen\u00e9v>-nek\n . /r \u00fczenet : v\u00e1laszol az utols\u00f3 mag\u00e1n \u00fczenetre\n . /join #csatorna : \u00e1tv\u00e1lt egy m\u00e1sik szob\u00e1ba
 PasswordWindow.title=Vuze lez\u00e1rva
 PasswordWindow.passwordprotected=AZ Azureust jelsz\u00f3 v\u00e9di.\nHa l\u00e1tni k\u00edv\u00e1nja a kezel\u0151ablakot, k\u00e9rem adja meg a jelsz\u00f3t :
-TrackerChangerWindow.title=Tracker Hozz\u00e1ad\u00e1sa
-TrackerChangerWindow.newtracker=\u00cdrja be az \u00faj tracker c\u00edmet
 PeersView.discarded=Elvetve
 PeersView.discarded.info=Felesleges adatok, amire nincs sz\u00fcks\u00e9ges, ez\u00e9rt ezek el lettek t\u00e1vol\u00edtva
 discarded=elvetve
@@ -378,7 +373,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Torrent F\u00e1jl T\u00f6rl\u00e9se
 MyTorrentsView.menu.removeand.deletedata=A&dat t\u00f6rl\u00e9se
 MyTorrentsView.menu.removeand.deleteboth=Mind t\u00f6rl\u00e9se
 deletedata.title=Figyelem
-deletedata.message1=Az al\u00e1bbi helyen l\u00e9v\u0151 ADATOT t\u00f6rl\u00e9se :\n
 MainWindow.menu.file.configure=Be\u00e1ll\u00edt\u00e1s &Var\u00e1zsl\u00f3...
 configureWizard.title=Be\u00e1ll\u00edt\u00e1s Var\u00e1zsl\u00f3
 configureWizard.welcome.title=\u00dcdv\u00f6zli az Vuze Be\u00e1ll\u00edt\u00e1s Var\u00e1zsl\u00f3ja
@@ -400,7 +394,6 @@ configureWizard.transfer.maxActiveTorrents=Max Akt\u00edv
 configureWizard.transfer.maxDownloads=Max Let\u00f6lt\u00e9s
 configureWizard.transfer.maxUploadsPerTorrent=Max Felt\u00f6lt\u00e9s Torrentenk\u00e9nt
 configureWizard.nat.title=NAT / Szerver Port
-configureWizard.nat.message=Ahhoz hogy az Vuze a legjobban m\u0171k\u00f6dj\u00f6n, aj\u00e1nlott a teljes el\u00e9r\u00e9s az internetr\u0151l. Itt letesztelheted \u00e9s/vagy megv\u00e1ltoztathatod a bej\u00f6v\u0151 kapcsolathoz haszn\u00e1lt portot.\n\nMegjegyz\u00e9s: Csak a TCP kapcsolatot teszteli. Az Elosztott Adatv\u00e1zishoz bej\u00f6v\u0151 UDP kapcsolat sz\u00fcks\u00e9ges, de hiba eset\u00e9n visszajelz\u00e9st fogsz kapni.\n\nMegjegyz\u00e9s: 6880 TCP port m\u00e1r le van  [...]
 configureWizard.nat.test=Teszt
 configureWizard.nat.testing=Port tesztel\u00e9se
 configureWizard.nat.ok=OK!
@@ -556,7 +549,6 @@ ConfigView.section.file.decoder.nodecoder=Nincs
 IPChecker.external.service.no-ip.description=Dinamikus \u00e9s Statikus DNS szolg\u00e1ltat\u00f3\n(nem ingyenes)
 ConfigView.section.tracker.publicenable=K\u00fcls\u0151 torrentek enged\u00e9lyez\u00e9se
 ConfigView.label.playdownloadspeech=Sz\u00f3beli \u00e9rtes\u00edt\u00e9s let\u00f6lt\u00e9s befejez\u0151d\u00e9s\u00e9r\u0151l
-ConfigView.label.playdownloadspeech.info=A Besz\u00e9dszolg\u00e1ltat\u00e1s legjobban angolul m\u0171k\u00f6dik
 #
 # Tooltips
 #
@@ -728,8 +720,6 @@ plugin.sharing.download.remove.veto=Ez a let\u00f6lt\u00e9s megosztott forr\u00e
 ConfigView.section.tracker.main=F\u0151oldal
 ConfigView.label.prioritizefirstpiece=A f\u00e1jl(ok) els\u0151 \u00e9s utols\u00f3 darabjait t\u00f6ltse le el\u0151sz\u00f6r
 ConfigView.label.prioritizefirstpiece.tooltip=El\u0151sz\u00f6r minden \u00e1llom\u00e1ny elej\u00e9t \u00e9s v\u00e9g\u00e9t pr\u00f3b\u00e1lja let\u00f6lteni.\nEl\u0151bb belen\u00e9zhetsz a f\u00e1jlba.
-ConfigView.section.file.confirm_data_delete=Meger\u0151s\u00edt\u00e9s k\u00e9r\u00e9se adatok t\u00f6rl\u00e9n\u00e9l
-ConfigView.section.file.confirm_data_delete.tooltip=Meger\u0151s\u00edt\u00e9s k\u00e9r\u00e9se, adatok v\u00e9gleges t\u00f6rl\u00e9se el\u0151tt (Remove&Delete)...
 ConfigView.section.file.delete.include_files_outside_save_dir=Adatok t\u00f6rl\u00e9sekor a torrent mapp\u00e1n k\u00edv\u00fcl es\u0151 f\u00e1jlok \u00e9s t\u00f6rl\u0151dnek
 TrayWindow.menu.startalldownloads=\u00d6sszes Let\u00f6lt\u00e9s Ind\u00edt\u00e1sa
 SystemTray.menu.startalltransfers=\u00d6sszes \u00e1tvitel ind\u00edt\u00e1sa
@@ -1047,7 +1037,6 @@ ConfigView.pluginlist.whereToPutOr=A megosztott b\u0151v\u00edtm\u00e9nyeket ide
 MainWindow.statusText.checking=Friss\u00edt\u00e9sek Keres\u00e9se
 TableColumn.header.OnlyCDing4=Csak Seed
 TableColumn.header.OnlyCDing4.info=Csak a seedel\u00e9s ideje. Nem sz\u00e1molja belea let\u00f6lt\u00e9s idej\u00e9t (akkori felt\u00f6lt\u00e9st).
-ConfigView.section.style.alternateTablePainting=Alternat\u00edv t\u00e1bl\u00e1zat-rajzol\u00e1si m\u00f3dszer az oszlopokhoz (\u00fajraind\u00edt\u00e1s sz\u00fcks\u00e9ges)
 UpdateWindow.status.restartMaybeNeeded=\u00dajraind\u00edt\u00e1s aj\u00e1nlott
 ConfigView.pluginlist.shared=megosztott
 PeersView.host=Kiszolg\u00e1l\u00f3 Neve
@@ -1280,18 +1269,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=SO_SNDBUF socket m\u00e9rete [0
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Az alap SO_SNDBUF socket m\u00e9ret\u00e9nek be\u00e1ll\u00edt\u00e1sa (b\u00e1jtban), pl.: TCP k\u00fcld\u00e9si keret m\u00e9rete.\nVuze alapesetben nem haszn\u00e1lja, ekkor az oper\u00e1ci\u00f3s rendszer \u00e1l\u00edtja be.\nMEGJEGYZ\u00c9S: a Linux megdupl\u00e1zza a megadott \u00e9rt\u00e9ket.
 ConfigView.section.connection.advanced.IPDiffServ=Kimen\u0151 csomagok DiffServ \u00e9rt\u00e9ke (TOS mez\u0151)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Be\u00e1ll\u00edtja a DiffServ r\u00e9szt a type-of-service (TOS) mez\u0151ben az IP csomagok fejl\u00e9c\u00e9ben.\nHexadecim\u00e1lis sz\u00e1mot lehet haszn\u00e1lni '0x kezdve', pl. 0x10.\nA Vuze nem haszn\u00e1lja ezt az \u00e9rt\u00e9ket alapbe\u00e1ll\u00edt\u00e1sban, vagyis az OS \u00e1ll\u00edtja be.\nNOTE: A h\u00e1l\u00f3zat figyelmen k\u00edv\u00fcl hagyhatja ezt az \u00e9rt\u00e9ket, teh\u00e1t nagyban f\u00fcgg az O [...]
-ConfigView.section.interface.confirm_torrent_removal=Meger\u0151s\u00edt\u00e9s k\u00e9r\u00e9se torrent elt\u00e1vol\u00edt\u00e1sakor
-ConfigView.section.interface.confirm_torrent_removal.tooltip=A program meger\u0151s\u00edt\u00e9st k\u00e9r, ha a Torrentjeim list\u00e1b\u00f3l el akarsz t\u00e1vol\u00edtanie egy torrentet
-MyTorrentsView.confirm_torrent_removal=Val\u00f3ban el akarja t\u00e1vol\u00edtani?\n
 TableColumn.header.seed_to_peer_ratio=Seed/Peer Ar\u00e1ny
 TableColumn.header.seed_to_peer_ratio.info=A boly teljes felt\u00f6lt\u0151k/let\u00f6lt\u0151k ar\u00e1nya
 PeersView.connected_time=Kapcsolat Ideje
 PeersView.connected_time.info=Ennyi ideje kapcsol\u00f3dik az \u00fcgyf\u00e9lhez
-ConfigView.section.interface.display.add_torrents_silently=Torrentek hozz\u00e1ad\u00e1sa a h\u00e1tt\u00e9rben
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Torrentek hozz\u00e1ad\u00e1sa Vuze f\u0151ablak\u00e1nak megnyit\u00e1sa n\u00e9lk\u00fcl.
 TableColumn.header.maxdownspeed=Max Let\u00f6lt\u00e9si Sebess\u00e9g
 TableColumn.header.maxdownspeed.info=Max Let\u00f6lt\u00e9si Sebess\u00e9g torrentenk\u00e9nt
-PeersGraphicView.title=Boly
+PeersGraphicView.title.full=Boly
 ConfigView.section.tracker.passwordwebhttpsonly=Csak HTTPS-en kereszt\u00fcl \u00e9rkez\u0151 kapcsolatok enged\u00e9lyez\u00e9se
 TableColumn.header.torrentpath=Torrent Helye
 TableColumn.header.torrentpath.info=A torrent helye a lemezen
@@ -1348,8 +1332,6 @@ UpdateWindow.restartLater=\u00dajraind\u00edt\u00e1s k\u00e9s\u0151bb
 MainWindow.menu.file.restart=Vuze \u00dajraind\u00edt\u00e1sa
 MainWindow.dialog.restartconfirmation.title=Vuze \u00fajraind\u00edt\u00e1sa?
 MainWindow.dialog.restartconfirmation.text=\u00dajra akarja ind\u00edtani az Azureust?
-deletetorrent.message1=TORRENT t\u00f6rl\u00e9se :\n
-deletetorrent.message2=\nBiztos t\u00f6rl\u00f6d?
 ConfigView.label.prioritizemostcompletedfiles=Magas priorit\u00e1s\u00fa f\u00e1jlok rangsorol\u00e1sa a f\u00e1jl m\u00e9rete \u00e9s a let\u00f6lt\u00e9s \u00e1llapota szerint
 splash.plugin.init=B\u0151v\u00edtm\u00e9ny el\u0151k\u00e9sz\u00edt\u00e9se:
 splash.plugin.UIinit=B\u0151v\u00edtm\u00e9ny GUI ind\u00edt\u00e1sa: %1  
@@ -1513,7 +1495,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent F\u00e1jl... (Csak K\u00f6v
 MyTrackerView.date_added=Hozz\u00e1adva
 ConfigView.section.tracker.portbackup=Tartal\u00e9k portok (';'-val elv\u00e1lasztva)
 ConfigView.label.playfilespeech=Besz\u00e9d ha egy f\u00e1jl elk\u00e9sz\u00fclt
-ConfigView.label.playfilespeech.info=A besz\u00e9dszolg\u00e1ltat\u00e1s legjobban angolul m\u0171k\u00f6dik
 ConfigView.label.playfilefinished=Hangjelz\u00e9s, ha egy feladat elk\u00e9sz\u00fclt
 ConfigView.label.backupconfigfiles=Be\u00e1ll\u00edt\u00e1si f\u00e1jl ment\u00e9se vissza\u00e1ll\u00edthat\u00f3s c\u00e9lj\u00e1b\u00f3l
 ConfigView.section.tracker.client.scrapesingleonly=Trackerenk\u00e9nti s\u00e9rt\u00e9s felhazmoz\u00e1s tilt\u00e1sa (seg\u00edt ha a tracker 'Az URL t\u00fal hossz\u00fa' (414) \u00fczentet k\u00fcld)
@@ -2106,22 +2087,11 @@ v3.mb.delPublished.title=Seedel\u00e9s le\u00e1ll\u00edt\u00e1sa
 v3.mb.delPublished.text=FIGYELEM: Ezzel nem t\u00f6rl\u0151dik a let\u00f6lt\u00f6tt tartalom '%1', <A HREF="%2">%3</A> .\n\nV\u00e1laszd a "T\u00f6rl\u00e9s"-t ha azt szeretn\u00e9d, hogy a tartalom m\u00e9g el\u00e9rhet\u0151, let\u00f6lthet\u0151 maradjon, de fel akarod szabad\u00edtani a felt\u00f6t\u00e9si s\u00e1vodat. Ellen\u0151rizd, hogy a let\u00f6lt\u00e9s befejez\u0151d\u00f6tt (<A HREF="%4">how</A>?).\n\nKattints a M\u00e9gsem-re, ha teljesen el akarod t\u00e1vol\u00edtani a [...]
 v3.mb.delPublished.delete=&T\u00f6r\u00f6l
 v3.mb.delPublished.cancel=&M\u00e9gsem
-v3.mb.openFile.title=F\u00e1jl megnyit\u00e1sa
-v3.mb.openFile.text.known=A Vuze Lej\u00e1tsz\u00f3 nem t\u00e1mogatja ezt a form\u00e1tumot. B\u0151vebb inf\u00f3-created <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Lej\u00e1tsz\u00e1s \u00datmutat\u00f3</a>\n\nF\u00e1jlt\u00edpus: %2 (%3)\n
-v3.mb.openFile.text.unknown=A Vuze Lej\u00e1tsz\u00f3 nem t\u00e1mogatja ezt a form\u00e1tumot.  B\u0151vebb inf\u00f3 <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a>\n\nKiterjeszt\u00e9s : %2\n
-v3.mb.openFile.button.play=Lej\u00e1tsz\u00e1s
-v3.mb.openFile.button.cancel=M\u00e9gsem
-v3.mb.openFile.button.guide=\u00datmutat\u00f3 olvas\u00e1sa
-v3.mb.openFile.remember=Mindig nyissa meg k\u00e9rd\u00e9s n\u00e9lk\u00fcl a f\u00e1jlokat
 v3.mb.PlayFileNotFound.title=A f\u00e1jl nemtal\u00e1lhat\u00f3
 v3.mb.PlayFileNotFound.text=A '%1' f\u00e1jl hi\u00e1nyzik vagy t\u00f6r\u00f6lve lett.
 v3.mb.PlayFileNotFound.button.remove=T\u00f6rl\u00e9s az Azureusb\u00f3l
 v3.mb.PlayFileNotFound.button.redownload=Adatok \u00dajrat\u00f6lt\u00e9se
 v3.mb.PlayFileNotFound.button.find=K\u00e9zi keres\u00e9s..
-v3.mb.deletePurchased.title=Let\u00f6lt\u00f6tt Elem T\u00f6rl\u00e9se
-v3.mb.deletePurchased.text=Biztosan t\u00f6r\u00f6lni akarod a k\u00f6vetkez\u0151 elemet? '%1'?\n\n Az elem megosztott, vagy bel\u00e9p\u00e9s sz\u00fcks\u00e9ges a let\u00f6lt\u00e9s\u00e9hez.
-v3.mb.deletePurchased.button.delete=&T\u00f6r\u00f6l
-v3.mb.deletePurchased.button.cancel=&M\u00e9gsem
 v3.topbar.menu.show.plugin=B\u0151v\u00edtm\u00e9nyek
 v3.topbar.menu.show.search=Keres
 splash.initializeCore=Mag Ind\u00edt\u00e1sa
@@ -2310,10 +2280,6 @@ v3.splash.hookPluginUI=Hurok a Plugin UI-ban
 OpenTorrentWindow.mb.notTorrent.cannot.display=Az adatokat nem lehet helyesen megjelen\u00edteni
 MainWindow.menu.window.zoom.maximize=Teljes m\u00e9ret
 MainWindow.menu.window.zoom.restore=Vissza\u00e1ll\u00edt
-ImageResizer.image.too.small=A kiv\u00e1lasztott k\u00e9p t\u00fal kicsil, adj meg egy m\u00e1sikat (legal\u00e1bb %1 x %2)
-ImageResizer.title=Az eszk\u00f6z megmutatja, hogy hogyan fog kin\u00e9zni a mozaikod a Vuze Platformon
-ImageResizer.move.image=K\u00e9p mozgat\u00e1sa h\u00faz\u00e1ssal
-ImageResizer.move.image.with.slider=K\u00e9p mozgat\u00e1sa h\u00faz\u00e1ssal, \u00e1tm\u00e9retez\u00e9s a lentebb l\u00e9v\u0151 cs\u00faszk\u00e1val
 security.crypto.title=Titkos\u00edt\u00f3 Kulcs
 security.crypto.encrypt=\u00cdrj be egy jelsz\u00f3t, ami v\u00e9di a gener\u00e1lt titkos\u00edt\u00e1si kulcsot. Ne felejtsd el a jelsz\u00f3t, nem lehet vissza\u00e1ll\u00edtani!
 security.crypto.decrypt=\u00cdrd be a jelsz\u00f3t a titkos\u00edt\u00f3 kulcs kinyit\u00e1s\u00e1hoz.
@@ -2404,9 +2370,6 @@ metasearch.addtemplate.dup.title=Sablon m\u00e1sol\u00e1sa
 metasearch.addtemplate.dup.desc=A %1 keres\u00e9si sablon m\u00e1r telep\u00edtve van
 metasearch.export.select.template.file=Sablon Ment\u00e9se
 metasearch.import.select.template.file=Sablon Megnyit\u00e1sa
-dialog.uiswitch.title=V\u00e1lt\u00e1s Vuze UI-ra
-dialog.uiswitch.text=A funkci\u00f3hoz Vuze fel\u00fclet sz\u00fcks\u00e9ge.\n\n\u00dajraind\u00edt\u00e1s sz\u00fcks\u00e9ges.
-dialog.uiswitch.button=V\u00e1lt\u00e1s Vuze UI-ra
 azbuddy.tracker.enabled='Bar\u00e1t gyors\u00edt\u00e1sa' nagyobb priorit\u00e1sban r\u00e9szes\u00edti a bar\u00e1taidat 
 azbuddy.protocolspeed=KB/s a bar\u00e1tod max protokoll fejr\u00e9sz
 v3.MainWindow.button.download=Let\u00f6lt\u00e9s
diff --git a/org/gudy/azureus2/internat/MessagesBundle_in_ID.properties b/org/gudy/azureus2/internat/MessagesBundle_in_ID.properties
index 82f70a0..f7c2f6a 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_in_ID.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_in_ID.properties
@@ -19,10 +19,7 @@ MainWindow.menu.window=Jendela
 MainWindow.menu.help=Bantuan
 MainWindow.menu.help.about=Tentang Vuze
 MainWindow.about.title=Tentang
-MainWindow.about.section.developers=Pengembang
-MainWindow.about.section.translators=Penerjemah
 MainWindow.about.section.system=Sistem
-MainWindow.about.internet.sourceforgedownloads=Mengunduh dari Sourceforge
 MainWindow.about.internet.bugreports=Laporan Bug
 MainWindow.about.internet.forumdiscussion=Forum Diskusi
 MainWindow.dialog.choose.savepath=Pilih tempat untuk menyimpan data
@@ -188,8 +185,6 @@ Button.cancel=Batal
 IrcClient.copyright=Menggunakan PircBot Java IRC API - http://www.jibble.org/pircbot.php
 PasswordWindow.title=Vuze terkunci
 PasswordWindow.passwordprotected=Vuze dilindungi dengan kata sandi.\nUntuk menampilkan jendela Vuze, silahkan masukkan kata sandi Anda disini :
-TrackerChangerWindow.title=Tambah Tracker
-TrackerChangerWindow.newtracker=Masukkan url tracker yang baru
 discarded=dibuang
 MyTorrentsView.menu.move=Pindah
 MyTorrentsView.menu.moveUp=Ke Atas
@@ -282,7 +277,6 @@ splash.plugin=Memuat Plugin:
 ConfigView.label.movetorrent=Pindahkan .torrent
 ConfigView.label.movepartialdownloads=Pindahkan sekalipun ada berkas yang ditandai "jangan diunduh"
 ConfigView.label.playdownloadspeech=Bicara jika mengunduh selesai
-ConfigView.label.playdownloadspeech.info=Servis Kata-kata saat ini bekerja dengan baik dengan Bahasa Inggris
 #
 # Tooltips
 #
@@ -359,8 +353,6 @@ MainWindow.dialog.share.sharefile=Pilih berkas untuk berbagi
 MainWindow.dialog.share.sharedir=Pilih direktori untuk berbagi
 MainWindow.dialog.share.sharedircontents=Pilih isi direktori untuk berbagi
 MainWindow.dialog.share.sharedircontents.recursive=Rekursif
-ConfigView.section.file.confirm_data_delete=Konfirmasi ketika menghapus data
-ConfigView.section.file.confirm_data_delete.tooltip=Konfirmasi penghapusan menggunakan 'Singkirkan dan Hapus...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Ketika menghapus data, ijinkan berkas yang di-link diluar direktori penyimpanan torrent untuk dihapus juga
 MySharesView.type.file=Berkas
 plugin.download.remove.veto.notstopped=Unduh tidak bisa disingkirkan karena tidak dalam keadaan berhenti
@@ -596,7 +588,6 @@ PeersView.state.established=Terhubung
 DownloadManager.error.operationcancancelled=Operasi dibatalkan
 Torrent.create.progress.cancelled=Operasi Dibatalkan
 ConfigView.section.connection.advanced=Jaringan Tingkat Lanjut
-MyTorrentsView.confirm_torrent_removal=Anda yakin akan menghilangkan torrent ini?
 TableColumn.header.maxdownspeed=Maks. Kec. Unduh
 TableColumn.header.maxdownspeed.info=Maksimal kecepatan unduh yang ditentukan pada peer
 ConfigView.label.copyanddeleteratherthanmove=Salin dulu baru kemudian hapus data, daripada memindahkan dalam satu operasi - dapat membantu menghindari kehilangan data pada beberapa sistem
@@ -689,7 +680,6 @@ TableColumn.header.comment=Komentar
 TableColumn.header.comment.info=Komentar pengguna
 TableColumn.header.commenticon=Icon Komentar
 ConfigView.label.playfilespeech=Bicara jika sebuah berkas selesai
-ConfigView.label.playfilespeech.info=Servis Kata-kata saat ini bekerja dengan baik dengan Bahasa Inggris
 ConfigView.label.playfilefinished=Mainkan suara jika sebuah berkas selesai
 ConfigView.label.backupconfigfiles=Buat salinan konfigurasi untuk tujuan pemulihan
 ActivityView.legend.limit=Batas kecepatan
@@ -954,10 +944,6 @@ v3.MainWindow.button.play=Mainkan
 v3.MainWindow.view.wait=Inisialisasi tampilan, tunggu sejenak.
 v3.MainWindow.xofx=%1 dari %2
 v3.MainWindow.search.defaultText=cari...
-v3.mb.openFile.title=Buka Berkas
-v3.mb.openFile.button.play=Mainkan
-v3.mb.openFile.button.cancel=Batal
-v3.mb.openFile.button.guide=Baca Playback Guide
 splash.initializeCore=Inisialisasi Inti
 splash.initializeUIElements=Inisialisasi Elemen Tampilan
 #
@@ -1156,7 +1142,6 @@ ConfigView.label.autoopen.downloadbars=Buka Download Bar secara otomatis jika
 ConfigView.label.autoopen=Buka Otomatis
 ConfigView.label.autoopen.detailstab=Buka Tab Detil secara otomatis jika 
 v3.MainWindow.menu.contentnetworks.manage=&Atur Jaringan HD
-v3.dialog.cnclose.subtitle=Pemberitahuan
 TableColumn.header.#.info=Posisi/Nomor Urut
 TableColumn.header.category.info=Nama kategori dari torrent
 TableColumn.header.health.info=Seberapa sehat koneksi Anda ke swarm
diff --git a/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties b/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
index d6f85f4..2585ee0 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_it_IT.properties
@@ -32,12 +32,9 @@ MainWindow.menu.window.alltofront=Porta tutto in primo &piano
 MainWindow.menu.help=&Aiuto
 MainWindow.menu.help.about=Informazioni su Vuze
 MainWindow.about.title=Informazioni su Vuze
-MainWindow.about.section.developers=Sviluppatori
-MainWindow.about.section.translators=Traduttori
 MainWindow.about.section.system=Sistema
 MainWindow.about.internet.homepage=Sito di Vuze
 MainWindow.about.internet.sourceforge=Sito del progetto su Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Scarica da Sourceforge
 MainWindow.about.internet.bugreports=Segnalazioni errori
 MainWindow.about.internet.forumdiscussion=Forum
 MainWindow.about.internet.wiki=FAQ della wiki di Vuze
@@ -99,6 +96,7 @@ PeersView.C1.info=Se il peer sta bloccando il tuo download
 PeersView.pieces=Parti
 PeersView.downloadspeed=Velocit\u00e0 DL
 PeersView.download=Ricevuti
+PeersView.download.info=Il totale dei download dal peer
 PeersView.I2=I (Peer interessato)
 PeersView.I2.info=Il peer \u00e8 interessato a quello che hai?
 PeersView.C2=C (Peer respinto)
@@ -305,8 +303,6 @@ IrcView.errormsg=Sintassi sbagliata su /msg : /msg utente messaggio
 IrcView.help=Comandi validi sono :\n . /help : visualizza questo messaggio\n . /nick | /name : cambia il tuo nome \n . /me azione : invia un'azione \n . /msg nome messaggio : invia un messaggio a \u00abnome\u00bb\n . /r messaggio : risponde all'ultimo messaggio privato\n . /join #channelB (non fare clic qui, \u00e8 solo un esempio): modifica il canale attuale a \u00abcanaleB\u00bb
 PasswordWindow.title=Vuze \u00e8 bloccato
 PasswordWindow.passwordprotected=Vuze \u00e8 protetto da password.\nPer visualizzare la finestra di Vuze, inserire la password :
-TrackerChangerWindow.title=Aggiungi tracker
-TrackerChangerWindow.newtracker=Inserire il nuovo URL per il tracker
 PeersView.discarded=Scartato
 PeersView.discarded.info=A volte si ricevono dati non necessari, quindi si possono scartare.
 discarded=scartato
@@ -377,7 +373,6 @@ 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 multimediali
-deletedata.message1=Si vuole eliminare definitivamente \u00ab%1\u00bb?
 deletedata.noprompt=Non chiedere ancora
 MainWindow.menu.file.configure=Assistente di configura&zione...
 configureWizard.title=Assistente di configurazione
@@ -399,7 +394,6 @@ 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 all'uso in [...]
 configureWizard.nat.test=Prova
 configureWizard.nat.testing=Test delle porte
 configureWizard.nat.ok=Ok
@@ -559,7 +553,6 @@ ConfigView.section.file.decoder.nodecoder=Nessuna
 IPChecker.external.service.no-ip.description=Fornisce servizi di DNS statico e dinamico\n(il servizio per il controllo dell'indirizzo non \u00e8 disponibile gratuitamente)
 ConfigView.section.tracker.publicenable=Abilita torrent esterni
 ConfigView.label.playdownloadspeech=Parla al completamento di un download
-ConfigView.label.playdownloadspeech.info=Il servizio di sintesi vocale funziona meglio con la lingua inglese.
 #
 # Tooltips
 #
@@ -728,8 +721,6 @@ plugin.sharing.download.remove.veto=Questo download \u00e8 il risultato di una r
 ConfigView.section.tracker.main=Principale
 ConfigView.label.prioritizefirstpiece=Dai priorit\u00e0 alla prima ed ultima parte dei file
 ConfigView.label.prioritizefirstpiece.tooltip=Tenta di scaricare innanzi tutto l'inizio e la fine del file.\nPer permettere un veloce controllo.
-ConfigView.section.file.confirm_data_delete=Chiedi conferma quando elimini dati
-ConfigView.section.file.confirm_data_delete.tooltip=Chiedi conferma della cancellazione quando si usa \u00abRimuovi e elimina...\u00bb
 ConfigView.section.file.delete.include_files_outside_save_dir=Quando si eliminano i dati, rimuovi anche i file collegati fuori dalla cartella di salvataggio
 TrayWindow.menu.startalldownloads=&Avvia tutti i download
 SystemTray.menu.startalltransfers=&Avvia tutti i trasferimenti
@@ -1041,7 +1032,6 @@ ConfigView.pluginlist.whereToPutOr=Per i plugin condivisi usa:
 MainWindow.statusText.checking=Verifico la presenza di aggiornamenti
 TableColumn.header.OnlyCDing4=Solo in seed
 TableColumn.header.OnlyCDing4.info=Periodo di tempo durante il quale il torrent \u00e8 stato solamente in seed. Esclude il tempo durante il quale il torrent veniva scaricato (e condiviso).
-ConfigView.section.style.alternateTablePainting=Usa un metodo alternativo per disegnare le colonne delle tabelle grafiche (pu\u00f2 richiedere un riavvio)
 UpdateWindow.status.restartMaybeNeeded=Potrebbe essere necessario riavviare
 ConfigView.pluginlist.shared=condiviso
 PeersView.host=Nome host
@@ -1092,7 +1082,6 @@ webui.access.info=L'accesso puo essere \n\t\u00ablocal\u00bb\t= solo il computer
 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 la mappatura automatica delle porte sui router abilitati all'UPnP.
@@ -1271,15 +1260,10 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Dimensioni del SO_SNDBUF del so
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Imposta il valore standard del socket SO_SNDBUF (in byte), i.e.dimensioni e scala della finestra di ricezione dei TCP.\nVuze lascia questi valori disattivati di default, intendendo le impostazioni predefinite per il SO che si sta usando.\nNOTE: Linux duplica i valori dati.
 ConfigView.section.connection.advanced.IPDiffServ=Valore DiffServ dei pacchetti In Uscita (campo TOS)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Imposta la sezione DiffServ del campo type-of-service (TOS) nell'intestazione IP per i pacchetti in uscita.\nSi possono specificare valori esadecimali usando il prefisso \u00ab0x\u00bb, ad esempio \u00ab0x10\u00bb.\nVuze per scelta non imposta questo valore, lasciando che venga usato il valore predefinito del sistema operativo.\nNOTA: Le implementazioni di rete sottostanti potrebbero ignorare questo valore, quindi questa opzione \ [...]
-ConfigView.section.interface.confirm_torrent_removal=Mostra messaggi di conferma alla rimozione di un torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Chiedi conferma quando viene rimosso un torrent dalla scheda \u00abI miei torrent\u00bb.
-MyTorrentsView.confirm_torrent_removal=Si \u00e8 sicuri di volerlo rimuovere?\n
 TableColumn.header.seed_to_peer_ratio=Seed alla media dei peer
 TableColumn.header.seed_to_peer_ratio.info=Seed totali nello swarm rispetto la media dei peer
 PeersView.connected_time=Tempo di connessione
 PeersView.connected_time.info=Tempo totale di connessione con il peer
-ConfigView.section.interface.display.add_torrents_silently=Aggiungi torrent in modo silenzioso
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Metti i torrent in download senza aprire la finestra principale di Vuze.
 TableColumn.header.maxdownspeed=Massima velocit\u00e0 di download
 TableColumn.header.maxdownspeed.info=Massima velocit\u00e0 di download per il peer
 ConfigView.section.tracker.passwordwebhttpsonly=Abilita accesso solo via HTTPS
@@ -1338,8 +1322,6 @@ UpdateWindow.restartLater=Riavvia in seguito
 MainWindow.menu.file.restart=Riavvia Vuze
 MainWindow.dialog.restartconfirmation.title=Conferma del riavvio di Vuze
 MainWindow.dialog.restartconfirmation.text=Riavviare Vuze?
-deletetorrent.message1=Si sta per eliminare il TORRENT di:\n
-deletetorrent.message2=\nSi \u00e8 sicuri di procedere?
 ConfigView.label.prioritizemostcompletedfiles=Dai ulteriore priorit\u00e0 ai file con Prima priorit\u00e0 in base alla percentuale di completamento e alla dimensione del file
 splash.plugin.init=Inizializzazione del plugin:
 splash.plugin.UIinit=Inizializzazione del plugin dell'interfaccia: %1
@@ -1502,7 +1484,6 @@ MainWindow.menu.file.open.torrentfortracking=File torrent... (solo tracking)
 MyTrackerView.date_added=Aggiunto
 ConfigView.section.tracker.portbackup=Porte di backup (separate da \u00ab;\u00bb)
 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 per tracker degli scrape (pu\u00f2 aiutare con i tracker che riportano errori \u00abURL too long\u00bb (414))
@@ -1907,10 +1888,6 @@ 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 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=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
@@ -2094,22 +2071,11 @@ 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 i [...]
 v3.mb.delPublished.delete=&Elimina
 v3.mb.delPublished.cancel=&Rimuovi
-v3.mb.openFile.title=Apri file
-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
-v3.mb.openFile.remember=Apri sempre i file senza chiedere
 v3.mb.PlayFileNotFound.title=File non trovato
 v3.mb.PlayFileNotFound.text=I file per \u00ab%1\u00bb sono stati cancellati o sono mancanti.
 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 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
 v3.topbar.menu.show.search=Cerca
 splash.initializeCore=Inizializzazione del core
@@ -2289,10 +2255,6 @@ v3.splash.hookPluginUI=Aggancio nell'interfaccia del plugin
 OpenTorrentWindow.mb.notTorrent.cannot.display=Impossibile visualizzare correttamente i dati.
 MainWindow.menu.window.zoom.maximize=Ingrandisci
 MainWindow.menu.window.zoom.restore=Ripristina
-ImageResizer.image.too.small=L'immagine fornita \u00e8 troppo piccola, sceglierne una diversa (dev'essere almeno %1 x %2)
-ImageResizer.title=Questo strumento consente di regolare l'aspetto delle anteprime sulla piattaforma Vuze
-ImageResizer.move.image=Muovere l'immagine trascinandola col mouse
-ImageResizer.move.image.with.slider=Muovere l'immagine trascinandola, ridimensionarla usando il cursore in basso
 security.crypto.title=Accesso alla chiave di cifratura
 security.crypto.encrypt=Inserire una password per proteggere la chiave di cifratura appena creata. Non dimenticare questa password, altrimenti non ci sar\u00e0 modo di recuperarla!
 security.crypto.decrypt=Inserire la password per sbloccare la chiave di cifratura.
@@ -2383,9 +2345,6 @@ 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
-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 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
@@ -2538,7 +2497,7 @@ Wizard.Subscription.rss.subtitle2=Molti produttori di contenuti multimediali met
 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=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>
+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://wiki.vuze.com/w/FAQ_Subscriptions">Maggiori informazioni</A>
 message.confirm.delete.title=Conferma dell'eliminazione
 message.confirm.delete.text=Eliminare \u00ab%1\u00bb?
 Subscription.menu.properties=Propriet\u00e0
@@ -2575,7 +2534,7 @@ 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 multimediali. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Maggiori informazioni</A> (in inglese).
+subscriptions.view.help.2=Ottieni aggiornamenti in tempo reale quando sono disponibili per il download nuovi contenuti multimediali. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">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
@@ -2618,13 +2577,6 @@ azbuddy.ui.menu.cat.set_msg=Lista di categorie separata da spazio, o \u00abAll\u
 azbuddy.ui.menu.cat_subs=Iscriviti
 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.
-v3.dialog.cnclose.info2=Se si vuole aprire di nuovo questa rete in HD, lo si pu\u00f2 fare dal menu \u00abReti in HD\u00bb nella parte alta dello schermo.
-v3.dialog.cnclose.noshow=Non mostrare ancora
-v3.dialog.cnmanage.title=Menu di gestione delle reti HD
-v3.dialog.cnmanage.intro=Si possono selezionare nella lista sotto i network da visualizzare nel menu \u00abReti HD\u00bb.
 TableColumn.header.#=N\u00b0
 TableColumn.header.#.info=Posizione/Numero d'ordine
 TableColumn.header.category.info=Nome della categoria a cui il torrent appartiene
@@ -2779,7 +2731,7 @@ xcode.deletedata.title=Eliminazione dei file convertiti
 xcode.deletedata.message=Eliminare permanentemente la copia di \u00ab%1\u00bb convertita per \u00ab%2\u00bb%3?
 xcode.deletedata.message.2=\n(una copia potrebbe ancora esistere in \u00ab%1\u00bb)
 v3.deviceview.infobar.line1=Trascina i video dalla libreria al dispositivo scelto.
-v3.deviceview.infobar.line2=Riproduci i video su tutti i tuoi dispositivi: iPhone, iPod e TV.
+v3.deviceview.infobar.line2=Riproduci i video su tutti i tuoi dispositivi: iPad, iPhone, iPod e TV.
 v3.deviceview.infobar.line1.generic=Trascina i video dalla libreria a %1 nella barra laterale.
 v3.deviceview.infobar.line2.itunes=I video appariranno nella cartella Video di iTunes quando saranno pronti ad essere riprodotti.
 v3.deviceview.infobar.line2.xbox=Fare lo streaming di video andando in \u00abLa mia XBox -> Libreria video -> Vuze\u00bb
@@ -2813,9 +2765,6 @@ device.rss.enable=Crea un feed RSS dai contenuti multimediali convertiti - li re
 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
@@ -2874,6 +2823,8 @@ pairing.ac.getnew=Assegna un nuovo codice di accesso
 pairing.ac.getnew.create=Crea
 pairing.ipv4=Indirizzo IPv4
 pairing.ipv6=Indirizzo IPv6
+pairing.local.ipv4=Indirizzo IPv4 locale
+pairing.local.ipv6=Indirizzo IPv6 locale
 pairing.host=Indirizzo dell'host (nome DNS)
 pairing.group.explicit=Dati espliciti
 pairing.explicit.enable=Abilita
@@ -2895,14 +2846,6 @@ subscriptions.rss.enable=Crea feed RSS dalle sottoscrizioni
 device.tivo.enable=Abilita il supporto a TiVo
 Button.removeAll=Rimuovi tutto
 label.rename=Rinomina %1
-RCM.column.rc_rank=Punteggio
-RCM.column.rc_created=Creato
-RCM.column.rc_lastseen=Visto per l'ultima volta
-RCM.column.rc_level=Livello
-rcm.view.heading=Discovery nello swarm
-rcm.config.enabled=Abilita
-rcm.config.max_results=Risultati massimi
-rcm.config.max_level=Livello massimo
 pairing.server.warning.title=Messaggio del server sull'accoppiamento
 wizard.webseedseditor.edit.title=Editor dei seed HTTP
 wizard.webseedseditor.edit.newseed=Nuovo seed
@@ -2916,3 +2859,88 @@ MagnetPlugin.use.lookup.service=Usa il servizio di lookup secondario di Vuze se
 MagnetPlugin.report.secondarylookup=Provo il servizio di lookup secondario
 MagnetPlugin.report.secondarylookup.ok=Lookup secondario riuscito
 MagnetPlugin.report.secondarylookup.fail=Lookup secondario non riuscito: nessuna sorgente trovata
+TrackerView.title.short=Sorgenti
+TrackerView.title.full=Sorgenti
+Trackers.column.type=Tipo
+Trackers.column.name=Dettagli
+Trackers.column.status=Stato
+Trackers.column.seeds=Seed
+Trackers.column.seeds.info=Seed nello swarm
+Trackers.column.leechers=Leecher
+Trackers.column.leechers.info=Leecher nello swarm
+Trackers.column.peers=Peer
+Trackers.column.peers.info=Peer restituiti dal tracker
+Trackers.column.interval=Intervallo
+Trackers.column.interval.info=Intervallo di aggiornamento in secondi: intervallo (intervallo minimo)
+Trackers.column.updatein=Prossimo
+Trackers.column.updatein.info=Tempo prima del prossimo aggiornamento
+tps.status.available=Disponibile
+tps.status.unavailable=Non disponibile
+tps.lan.details=Rilevati %1 client locali
+tps.pex.details=Connesso a %1 peer (in attesa: pex=%2, altri=%3)
+tps.tracker.cache=Cache dei peer
+tps.tracker.cache1=Cache dei peer: %1 elementi
+dht.status.disabled=Disabilitato, il database distribuito non \u00e8 disponibile
+tps.type.incoming=In entrata
+tps.incoming.details=Attuale: TCP=%1, UDP=%2; Totale: %3
+ConfigView.label.autoadjust=Configura automaticamente queste impostazioni in base alla velocit\u00e0 di connessione
+ConfigView.label.start=Avvio
+ConfigView.label.stop=Uscita
+ConfigView.label.start.onlogin=Avvia Vuze all'accesso
+ConfigView.label.stop.seedcomp=Al completamento del seed
+ConfigView.label.stop.downcomp=Al completamento del download
+ConfigView.label.stop.Nothing=Non fare nulla
+ConfigView.label.stop.QuitVuze=Esci da Vuze
+ConfigView.label.stop.Sleep=Metti il computer in standby
+ConfigView.label.stop.Hibernate=Iberna il computer
+ConfigView.label.stop.Shutdown=Spegni il computer
+core.shutdown.alert=Azione \u00ab%1\u00bb eseguita come %2
+core.shutdown.dl=download completato
+core.shutdown.se=seed completato
+pairing.last.error=Ultimo errore
+MainWindow.menu.pairing=Abbinamento remoto
+ConfigView.label.pauseresume=Pausa/Riprendi in automatico
+update.now.title=Aggiornamento necessario
+update.now.desc=Vuze ha bisogno di aggiornarsi per completare la migrazione.\n\nDopo aver chiuso questa finestra, Windows potrebbe chiedere di completare il processo di aggiornamento.\n\nNON sar\u00e0 necessario un riavvio Vuze.
+ConfigView.label.jvm=Opzioni di Java
+platform.jvmopt.sunonly=Sono supportate solo le JVM di Sun (il produttore della JVM in uso \u00e8 \u00ab%1\u00bb).
+platform.jvmopt.configerror=Impossibile gestire le opzioni della JVM a causa di un errore di configurazione.
+platform.jvmopt.nolinkfile=Impossibile gestire le opzioni della JVM perch\u00e9 la migrazione non \u00e8 completa.
+platform.jvmopt.nolink=Impossibile gestire le opzioni della JVM perch\u00e9 \u00e8 proibito dalla configurazione esistente.
+platform.jvmopt.accesserror=Impossibile accedere al file delle opzioni della JVM: %1
+pairing.status.noservices=Nessun servizio remoto abilitato
+webui.pairingtest=\tFare clic per testare l'abbinamento
+webui.connectiontest=\tFare clic per provare la connessione
+jvm.info=\u00c8 necessario un riavvio di Vuze per applicare le impostazioni. *** Attenzione: se si modificano le opzioni della JVM in modo errato, Vuze potrebbe non avviarsi pi\u00f9 o avere basse prestazioni. ***\n
+jvm.show.file=Il file corrente per le opzioni della JVM \u00e8 \u00ab%1\u00bb - Modificarlo direttamente solo a scopo di recupero
+jvm.reset=Reimposta ai valori predefiniti le opzioni della JVM
+jvm.error=Errore nell'accesso alle opzioni della JVM: %1
+jvm.max.mem=Dimensione massima della memoria [vuoto=predefinita,min=%1]
+jvm.min.mem=Dimensione minima della memoria [vuoto=predefinita,min=%1]
+ConfigView.section.invalid.value.title=Valore non valido
+ConfigView.section.invalid.value=Valore non valido \u00ab%1\u00bb inserito per \u00ab%2\u00bb: %3
+Button.dismiss=Nascondi
+webui.pairing.autoauth=Abilita la protezione predefinita con password: username=vuze, password=<codice di accesso per l'abbinamento>
+ConfigView.label.stop.autoreset=Reimposta automaticamente le azioni a \u00ab%1\u00bb dopo averle eseguite
+remote.pairing.title=Abbinamento remoto
+remote.pairing.subtitle=Vuze Remote permette di controllare Vuze da qualsiasi computer o browser - dovunque e in qualsiasi momento.
+remote.pairing.instruction=Inserire il codice qui sotto negli spazi forniti dalle applicazioni remote.
+remote.pairing.functions=<A HREF="clip">Copia codice negli appunti</A>   |   <A HREF="new">Ottieni un nuovo codice</A>
+remote.pairing.tip.title=Suggerimento: due modi facili di usare Vuze Remote:
+remote.pairing.tip.text=Barra degli strumenti di Vuze Remote: visita il sito <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A> (in inglese)\nVuze Remote Mobile: Vai al sito <A HREF="http://remote.vuze.com/">remote.vuze.com</A> (in inglese) nel browser del dispositivo mobile.
+remote.pairing.learnmore=<A HREF="http://www.vuze.com/pairing_learnmore.start">FAQ sull'abbinamento</A> (in inglese)
+remote.pairing.accesscode=Codice di accesso:
+remote.pairing.test.running=Controllo della connettivit\u00e0 remota in corso...
+remote.pairing.test.success=Vuze \u00e8 accessibile in remoto.
+remote.pairing.test.unavailable=Oops, impossible determinare la connettivit\u00e0 remota. <A HREF="retry">Riprova</A>
+remote.pairing.test.fail=Vuze non \u00e8 accessibile fuori dalla rete locale. <A HREF="http://www.vuze.com/pairing_error_faq.start">Maggiori informazioni</A> (in inglese)
+update.fail.app.changed.title=Aggiornamento non riuscito
+update.fail.app.changed=\u00c8 necessario aggiornare Vuze ma non \u00e8 possibile farlo in automatico perch\u00e9 il nome dell'applicazione \u00e8 cambiato in \u00ab%1\u00bb.\n\nVisitare il sito http://www.vuze.com/ e scaricare l'ultima versione di Vuze.
+webui.port.override=Forza porta: richiesto solo se la porta pubblica \u00e8 diversa da quella interna a causa della configurazione NAT.
+MainWindow.status.warning.tooltip=Fare clic qui per i dettagli
+# The remaining keys were not in MessagesBundle.properties
+ConfigView.label.popup.suppress_alerts=
+ConfigView.label.popup.use_message_boxes=
+webui.restart.info=
+ConfigView.label.popup.show.button=
+ConfigView.label.popup.show=
diff --git a/org/gudy/azureus2/internat/MessagesBundle_iw_IL.properties b/org/gudy/azureus2/internat/MessagesBundle_iw_IL.properties
index 06eb5eb..4c5ebe7 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_iw_IL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_iw_IL.properties
@@ -25,12 +25,9 @@ ConfigView.section.language=\u05e9\u05e4\u05d4
 MainWindow.menu.help=\u05e2\u05d6\u05e8\u05d4
 MainWindow.menu.help.about=\u05d0\u05d5\u05d3\u05d5\u05ea \u05d0\u05d6\u05d5\u05e8\u05d0\u05d5\u05e1
 MainWindow.about.title=\u05ea\u05e8\u05d2\u05d5\u05dd \u05dc\u05e2\u05d1\u05e8\u05d9\u05ea, \u05d2\u05d9\u05e8\u05e1\u05d4
-MainWindow.about.section.developers=\u05de\u05e4\u05ea\u05d7\u05d9\u05dd
-MainWindow.about.section.translators=\u05de\u05ea\u05e8\u05d2\u05de\u05d9\u05dd
 MainWindow.about.section.internet=\u05d0\u05d9\u05e0\u05d8\u05e8\u05e0\u05d8
 MainWindow.about.internet.homepage=\u05d3\u05e3 \u05d4\u05d1\u05d9\u05ea \u05e9\u05dc \u05d0\u05d6\u05d5\u05e8\u05d0\u05d5\u05e1
 MainWindow.about.internet.sourceforge=\u05d3\u05e3 \u05d4\u05e4\u05e8\u05d5\u05d9\u05e7\u05d8\u05d9\u05dd \u05e9\u05dc Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Sourceforge-\u05d4\u05d5\u05e8\u05d3\u05d5\u05ea \u05de
 MainWindow.about.internet.bugreports=\u05d3\u05d5\u05d5\u05d7 \u05e2\u05dc \u05d1\u05d0\u05d2\u05d9\u05dd
 MainWindow.about.internet.forumdiscussion=\u05e4\u05d5\u05e8\u05d5\u05dd \u05db\u05dc\u05dc\u05d9
 MainWindow.dialog.choose.savepath=\u05d1\u05d7\u05e8 \u05d0\u05ea \u05e0\u05ea\u05d9\u05d1 \u05d4\u05e9\u05de\u05d9\u05e8\u05d4
@@ -281,8 +278,6 @@ IrcView.help=Valid commands are :\n . /help : displays this message\n . /nick |
 PasswordWindow.title=\u05d0\u05d6\u05d5\u05e8\u05d0\u05d5\u05e1 \u05e0\u05e2\u05d5\u05dc\u05d4
 PasswordWindow.passwordprotected=\u05d0\u05d6\u05d5\u05e8\u05d0\u05d5\u05e1 \u05de\u05d5\u05d2\u05e0\u05ea \u05e2"\u05d9 \u05e1\u05d9\u05e1\u05de\u05d4\n\u05e2\u05dc \u05de\u05e0\u05ea \u05dc\u05d4\u05e6\u05d9\u05d2 \u05d0\u05ea \u05d7\u05dc\u05d5\u05df \u05d4\u05ea\u05d5\u05db\u05e0\u05d4 \u05d4\u05db\u05e0\u05e1 \u05db\u05d0\u05df \u05d0\u05ea \u05d4\u05e1\u05d9\u05e1\u05de\u05d4 :
 Button.ok=\u05d0\u05d9\u05e9\u05d5\u05e8
-TrackerChangerWindow.title=\u05d4\u05d5\u05e1\u05e3 \u05d8\u05e8\u05e7\u05e8
-TrackerChangerWindow.newtracker=\u05d4\u05db\u05e0\u05e1 \u05db\u05ea\u05d5\u05d1\u05ea \u05d8\u05e8\u05e7\u05e8 \u05d7\u05d3\u05e9\u05d4
 PeersView.discarded=\u05de\u05ea\u05e2\u05dc\u05dd
 PeersView.discarded.info=\u05de\u05d9\u05d3\u05e2 \u05e9\u05e7\u05d9\u05d1\u05dc\u05ea \u05d0\u05e3 \u05e2\u05dc \u05e4\u05d9 \u05e9\u05d0\u05d9\u05df \u05dc\u05da \u05e6\u05d5\u05e8\u05da \u05d1\u05d5, \u05d4\u05de\u05d9\u05d3\u05e2 \u05e0\u05de\u05d7\u05e7
 discarded=\u05d4\u05ea\u05e2\u05dc\u05dd
@@ -354,7 +349,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u05de\u05d7\u05e7 \u05d8\u05d5\u05e
 MyTorrentsView.menu.removeand.deletedata=\u05de\u05d7\u05e7 \u05de\u05d9\u05d3\u05e2
 MyTorrentsView.menu.removeand.deleteboth=\u05de\u05d7\u05e7 \u05d4\u05db\u05dc
 deletedata.title=!!! \u05d6\u05d4\u05d9\u05e8\u05d5\u05ea !!!
-deletedata.message1=:\u05d0\u05ea\u05d4 \u05e2\u05d5\u05de\u05d3 \u05dc\u05de\u05d7\u05d5\u05e7 \u05d0\u05ea \u05d4\u05de\u05d9\u05d3\u05e2 \u05de
 MainWindow.menu.file.configure=\u05d0\u05e9\u05e3 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea
 configureWizard.title=\u05d0\u05e9\u05e3 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea
 configureWizard.welcome.title=\u05d1\u05e8\u05d5\u05db\u05d9\u05dd \u05d4\u05d1\u05d0\u05d9\u05dd \u05dc\u05d0\u05e9\u05e3 \u05d4\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea \u05e9\u05dc \u05d0\u05d6\u05d5\u05e8\u05d0\u05d5\u05e1
@@ -375,7 +369,6 @@ configureWizard.transfer.maxUpSpeed=(\u05de\u05d4\u05d9\u05e8\u05d5\u05ea \u05de
 configureWizard.transfer.maxActiveTorrents=\u05de\u05e7\u05e1\u05d9\u05de\u05d5\u05dd \u05e4\u05e2\u05d9\u05dc\u05d9\u05dd
 configureWizard.transfer.maxDownloads=\u05de\u05e1\u05e4\u05e8 \u05d4\u05d5\u05e8\u05d3\u05d5\u05ea \u05de\u05e7\u05e1\u05d9\u05de\u05dc\u05d9
 configureWizard.transfer.maxUploadsPerTorrent=\u05de\u05e1\u05e4\u05e8 \u05d4\u05e2\u05dc\u05d0\u05d5\u05ea \u05dc\u05d8\u05d5\u05e8\u05e0\u05d8
-configureWizard.nat.message=\u05e2\u05dc \u05de\u05e0\u05ea \u05dc\u05d4\u05e4\u05d9\u05e7 \u05d0\u05ea \u05d4\u05de\u05d9\u05e8\u05d1 \u05de\u05d1\u05d9\u05d8\u05d5\u05e8\u05e0\u05d8, \u05de\u05d5\u05de\u05dc\u05e5 \u05d1\u05d9\u05d5\u05ea\u05e8 \u05e9\u05dc\u05ea\u05d5\u05db\u05e0\u05d4 \u05ea\u05d4\u05d9\u05d4 \u05d2\u05d9\u05e9\u05d4 \u05de\u05dc\u05d0\u05d4 \u05dc\u05d0\u05d9\u05e0\u05d8\u05e8\u05e0\u05d8. .\u05e4\u05d5\u05e8\u05d8 \u05d1\u05e8\u05d9\u05e8\u05ea \u05d4\u05de\u05d7\u [...]
 configureWizard.nat.test=\u05d1\u05d3\u05d9\u05e7\u05d4
 configureWizard.nat.testing=\u05e4\u05d5\u05e8\u05d8 \u05dc\u05d1\u05d3\u05d9\u05e7\u05d4
 configureWizard.nat.ok=\u05d1\u05e1\u05d3\u05e8
@@ -688,8 +681,6 @@ ConfigView.section.tracker.main=\u05e8\u05d0\u05e9\u05d9
 ConfigView.section.tracker.web=\u05d0\u05d9\u05e0\u05d8\u05e8\u05e0\u05d8
 ConfigView.label.prioritizefirstpiece=(\u05e9\u05d9\u05dd \u05d1\u05e2\u05d3\u05d9\u05e4\u05d5\u05ea \u05d0\u05ea \u05d4\u05d7\u05dc\u05e7 \u05d4\u05e8\u05d0\u05e9\u05d5\u05df \u05e9\u05dc \u05d4\u05e7\u05d5\u05d1\u05e5(\u05d9\u05dd
 ConfigView.label.prioritizefirstpiece.tooltip=\u05e0\u05e1\u05d4 \u05dc\u05d4\u05d5\u05e8\u05d9\u05d3 \u05d0\u05ea \u05ea\u05d7\u05d9\u05dc\u05ea \u05d4\u05e7\u05d5\u05d1\u05e5 \u05e7\u05d5\u05d3\u05dd.\n\u05dc\u05ea\u05de\u05d9\u05db\u05d4 \u05d1\u05ea\u05e6\u05d5\u05d2\u05d4 \u05de\u05d5\u05e7\u05d3\u05de\u05ea
-ConfigView.section.file.confirm_data_delete=\u05d0\u05e9\u05e8 \u05de\u05d7\u05d9\u05e7\u05ea \u05de\u05d9\u05d3\u05e2
-ConfigView.section.file.confirm_data_delete.tooltip='..\u05d1\u05e7\u05e9 \u05d0\u05d9\u05e9\u05d5\u05e8 \u05de\u05d7\u05d9\u05e7\u05d4 \u05db\u05d0\u05e9\u05e8 \u05de\u05e9\u05ea\u05de\u05e9\u05d9\u05dd \u05d1'\u05de\u05d7\u05e7 \u05d5
 TrayWindow.menu.startalldownloads=\u05d4\u05ea\u05d7\u05dc \u05d0\u05ea \u05db\u05dc \u05d4\u05d4\u05d5\u05e8\u05d3\u05d5\u05ea
 SystemTray.menu.startalltransfers=\u05d4\u05ea\u05d7\u05dc \u05d0\u05ea \u05db\u05dc \u05d4\u05d4\u05e2\u05d1\u05e8\u05d5\u05ea
 sharing.progress.title=\u05d4\u05ea\u05e7\u05d3\u05de\u05d5\u05ea \u05d4\u05e9\u05d9\u05ea\u05d5\u05e3
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties b/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
index a8ce490..778b4bd 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ja_JP.properties
@@ -35,13 +35,10 @@ MainWindow.menu.help=\u30d8\u30eb\u30d7
 MainWindow.menu.help.about=Vuze \u306b\u3064\u3044\u3066
 MainWindow.menu.torrent=Torrent
 MainWindow.about.title=Vuze \u306b\u3064\u3044\u3066
-MainWindow.about.section.developers=\u958b\u767a\u8005
-MainWindow.about.section.translators=\u7ffb\u8a33\u8005
 MainWindow.about.section.system=\u30b7\u30b9\u30c6\u30e0
 MainWindow.about.section.internet=\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8
 MainWindow.about.internet.homepage=Vuze \u30db\u30fc\u30e0\u30da\u30fc\u30b8
 MainWindow.about.internet.sourceforge=Sourceforge \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30da\u30fc\u30b8
-MainWindow.about.internet.sourceforgedownloads=Sourceforge \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u30da\u30fc\u30b8
 MainWindow.about.internet.bugreports=\u30d0\u30b0\u30ec\u30dd\u30fc\u30c8
 MainWindow.about.internet.forumdiscussion=\u30d5\u30a9\u30fc\u30e9\u30e0
 MainWindow.dialog.choose.savepath=\u4fdd\u5b58\u5148\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044
@@ -306,8 +303,6 @@ IrcView.errormsg=Wrong Syntax on /msg\uff1a/msg user text
 PasswordWindow.title=Vuze \u306f\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059
 PasswordWindow.passwordprotected=Vuze \u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u3088\u3063\u3066\u4fdd\u8b77\u3055\u308c\u3066\u3044\u307e\u3059\u3002\nVuze \u306e\u30a6\u30a4\u30f3\u30c9\u30a6\u3092\u8868\u793a\u3059\u308b\u306b\u306f\u3001\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\uff1a
 Button.ok=OK
-TrackerChangerWindow.title=\u30c8\u30e9\u30c3\u30ab\u30fc\u3092\u8ffd\u52a0
-TrackerChangerWindow.newtracker=\u65b0\u3057\u3044\u30c8\u30e9\u30c3\u30ab\u30fc\u306e URL \u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044
 PeersView.discarded=\u7834\u68c4
 PeersView.discarded.info=\uff08\u4f55\u3089\u304b\u306e\u7406\u7531\u3067\uff09\u5fc5\u8981\u3068\u3057\u306a\u3044\u306e\u306b\u53d7\u4fe1\u3057\u3001\u7834\u68c4\u3055\u308c\u305f\u30c7\u30fc\u30bf
 discarded=\u3092\u7834\u68c4
@@ -378,7 +373,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Torrent \u30d5\u30a1\u30a4\u30eb\u30
 MyTorrentsView.menu.removeand.deletedata=\u30c7\u30fc\u30bf\u30d5\u30a1\u30a4\u30eb
 MyTorrentsView.menu.removeand.deleteboth=\u4e21\u65b9\u3068\u3082
 deletedata.title=\u8b66\u544a
-deletedata.message1=\u6b21\u306e\u30c7\u30fc\u30bf\u3092\u524a\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059:\n
 MainWindow.menu.file.configure=\u8a2d\u5b9a\u30a6\u30a3\u30b6\u30fc\u30c9...
 configureWizard.title=\u8a2d\u5b9a\u30a6\u30a3\u30b6\u30fc\u30c9
 configureWizard.welcome.title=Vuze \u8a2d\u5b9a\u30a6\u30a3\u30b6\u30fc\u30c9\u3078\u3088\u3046\u3053\u305d
@@ -400,7 +394,6 @@ configureWizard.transfer.maxActiveTorrents=\u6700\u5927\u30a2\u30af\u30c6\u30a3\
 configureWizard.transfer.maxDownloads=\u6700\u5927\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u6570
 configureWizard.transfer.maxUploadsPerTorrent=Torrent \u3054\u3068\u306e\u6700\u5927\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u6570
 configureWizard.nat.title=NAT / \u30b5\u30fc\u30d0\u30dd\u30fc\u30c8
-configureWizard.nat.message=Vuze \u3092\u6700\u9ad8\u306e\u72b6\u614b\u3067\u4f7f\u7528\u3059\u308b\u305f\u3081\u306b\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u5074\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\u3053\u3068\u3092\u5f37\u304f\u304a\u5968\u3081\u3057\u307e\u3059\u3002\u3053\u306e\u30c4\u30fc\u30eb\u306f\u30d4\u30a2\u304b\u3089\u306e\u63a5\u7d9a\u3092\u5f85\u3061\u53d7\u3051\u308b\u30dd\u30fc\u30c8\u3092\u30c6\u30b9\u30c8\u307e\u305f\u306f\u5 [...]
 configureWizard.nat.test=\u30c6\u30b9\u30c8
 configureWizard.nat.testing=\u30dd\u30fc\u30c8\u3092\u30c6\u30b9\u30c8\u4e2d
 configureWizard.nat.ok=OK
@@ -563,7 +556,6 @@ ConfigView.section.file.decoder.nodecoder=\u306a\u3057
 IPChecker.external.service.no-ip.description=\u30c0\u30a4\u30ca\u30df\u30c3\u30af\uff0f\u30b9\u30bf\u30c6\u30a3\u30c3\u30af DNS \u30b5\u30fc\u30d3\u30b9\u30d7\u30ed\u30d0\u30a4\u30c0\n\uff08\u5229\u7528\u53ef\u80fd\u306a\u7121\u6599\u306e '\u30c1\u30a7\u30c3\u30af\u30a2\u30c9\u30ec\u30b9' \u30b5\u30fc\u30d3\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\uff09
 ConfigView.section.tracker.publicenable=\u5916\u90e8 Torrent \u3092\u6709\u52b9\u306b\u3059\u308b
 ConfigView.label.playdownloadspeech=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5b8c\u4e86\u6642\u306b\u97f3\u58f0\u3067\u77e5\u3089\u305b\u308b
-ConfigView.label.playdownloadspeech.info=\u73fe\u5728\u3053\u306e\u6a5f\u80fd\u306f\u82f1\u8a9e\u3067\u306e\u307f\u52d5\u4f5c\u3057\u307e\u3059
 #
 # Tooltips
 #
@@ -737,8 +729,6 @@ plugin.sharing.download.remove.veto=\u3053\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u
 ConfigView.section.tracker.main=\u30e1\u30a4\u30f3
 ConfigView.label.prioritizefirstpiece=\u30d5\u30a1\u30a4\u30eb\u306e\u5148\u982d\u3068\u672b\u5c3e\u306e\u30d4\u30fc\u30b9\u3092\u512a\u5148
 ConfigView.label.prioritizefirstpiece.tooltip=\u3067\u304d\u308b\u3060\u3051\u65e9\u304f\u30d7\u30ec\u30d3\u30e5\u30fc\u304c\u51fa\u6765\u308b\u3088\u3046\u3001\n\u30d5\u30a1\u30a4\u30eb\u306e\u5148\u982d\u3068\u672b\u5c3e\u306b\u3042\u305f\u308b\u30d4\u30fc\u30b9\u3092\u512a\u5148\u3057\u3066\u53d6\u5f97\u3057\u307e\u3059
-ConfigView.section.file.confirm_data_delete=\u30c7\u30fc\u30bf\u3092\u524a\u9664\u3059\u308b\u524d\u306b\u78ba\u8a8d
-ConfigView.section.file.confirm_data_delete.tooltip=\u30c7\u30fc\u30bf\u3092\u524a\u9664\u3059\u308b\u969b\u306b\u78ba\u8a8d\u30c0\u30a4\u30a2\u30ed\u30b0\u3092\u8868\u793a\u3057\u307e\u3059
 ConfigView.section.file.delete.include_files_outside_save_dir=\u30c7\u30fc\u30bf\u3092\u524a\u9664\u3059\u308b\u969b\u3001 Torrent \u5916\u306b\u30ea\u30f3\u30af\u3055\u308c\u3066\u3044\u308b\u30d5\u30a1\u30a4\u30eb\u3082\u524a\u9664
 TrayWindow.menu.startalldownloads=\u3059\u3079\u3066\u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3092\u958b\u59cb
 SystemTray.menu.startalltransfers=\u3059\u3079\u3066\u306e\u8ee2\u9001\u3092\u958b\u59cb
@@ -1048,7 +1038,6 @@ ConfigView.pluginlist.whereToPut=\u3053\u306e\u30e6\u30fc\u30b6\u306e\u307f\u304
 ConfigView.pluginlist.whereToPutOr=\u5171\u6709\u30d7\u30e9\u30b0\u30a4\u30f3\u306f\u6b21\u306e\u30d5\u30a9\u30eb\u30c0\u306e\u4e0b\u3078\u7f6e\u3044\u3066\u304f\u3060\u3055\u3044\uff1a
 MainWindow.statusText.checking=\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u78ba\u8a8d\u4e2d
 TableColumn.header.OnlyCDing4.info=\u30b7\u30fc\u30c9\u6642\u9593\u306e\u5408\u8a08\u3002\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u4e2d\u306e\u6642\u9593\u306f\u542b\u307f\u307e\u305b\u3093\u3002
-ConfigView.section.style.alternateTablePainting=\u30c6\u30fc\u30d6\u30eb\u306e\u80cc\u666f\u8272\u3092\u884c\u3054\u3068\u306b\u5207\u308a\u66ff\u3048\u308b\uff08\u518d\u8d77\u52d5\u304c\u5fc5\u8981\uff09
 UpdateWindow.status.restartMaybeNeeded=\u518d\u8d77\u52d5\u304c\u5fc5\u8981
 ConfigView.pluginlist.shared=\u5171\u6709
 PeersView.host=\u30db\u30b9\u30c8\u540d
@@ -1271,13 +1260,9 @@ ConfigView.section.connection.advanced.mtu=MTU
 ConfigView.section.connection.advanced.SO_RCVBUF=SO_RCVBUF \u30b5\u30a4\u30ba [0: OS \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u5024]
 ConfigView.section.connection.advanced.SO_SNDBUF=SO_SNDBUF \u30b5\u30a4\u30ba [0: OS \u306e\u30c7\u30d5\u30a9\u30eb\u30c8\u5024]
 ConfigView.section.connection.advanced.IPDiffServ=\u9001\u4fe1\u30d1\u30b1\u30c3\u30c8 DiffServ\uff08TOS \u30d5\u30a3\u30fc\u30eb\u30c9\uff09
-ConfigView.section.interface.confirm_torrent_removal=Torrent \u3092\u524a\u9664\u3059\u308b\u3068\u304d\u3001\u78ba\u8a8d\u30c0\u30a4\u30a2\u30ed\u30b0\u3092\u8868\u793a
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Torrent \u30ea\u30b9\u30c8\u304b\u3089 Torrent \u3092\u524a\u9664\u3059\u308b\u969b\u306b\u78ba\u8a8d\u3057\u307e\u3059
 TableColumn.header.seed_to_peer_ratio.info=\u30b7\u30fc\u30c0\u30fc\u306b\u5bfe\u3059\u308b\u30d4\u30a2\u306e\u6bd4\u7387
 PeersView.connected_time=\u63a5\u7d9a\u6642\u9593
 PeersView.connected_time.info=\u30d4\u30a2\u3068\u306e\u5408\u8a08\u63a5\u7d9a\u6642\u9593
-ConfigView.section.interface.display.add_torrents_silently=\u30b5\u30a4\u30ec\u30f3\u30c8\u30e2\u30fc\u30c9\u3067 Torrent \u3092\u8ffd\u52a0
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Torrent \u3092\u30ea\u30b9\u30c8\u306b\u8ffd\u52a0\u3059\u308b\u969b\u3001\u30e1\u30a4\u30f3\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u30a2\u30af\u30c6\u30a3\u30d6\u306b\u3057\u306a\u3044
 TableColumn.header.maxdownspeed=\u6700\u5927\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u901f\u5ea6
 TableColumn.header.maxdownspeed.info=Torrent \u3054\u3068\u306e\u6700\u5927\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u901f\u5ea6
 ConfigView.section.tracker.passwordwebhttpsonly=HTTPS \u306b\u3088\u308b\u30a2\u30af\u30bb\u30b9\u306e\u307f\u8a31\u53ef
@@ -1336,8 +1321,6 @@ UpdateWindow.restartLater=\u5f8c\u3067
 MainWindow.menu.file.restart=Vuze \u3092\u518d\u8d77\u52d5
 MainWindow.dialog.restartconfirmation.title=Vuze \u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u304b\uff1f
 MainWindow.dialog.restartconfirmation.text=Vuze \u3092\u518d\u8d77\u52d5\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f
-deletetorrent.message1=\u6b21\u306e Torrent \u3092\u524a\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059:\n
-deletetorrent.message2=\n\u524a\u9664\u3057\u3066\u3082\u3088\u308d\u3057\u3044\u3067\u3059\u304b\uff1f
 ConfigView.label.prioritizemostcompletedfiles=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u5b8c\u4e86\u7387\u304c\u6307\u5b9a\u5024\u3088\u308a\u3082\u9ad8\u3044\u30d5\u30a1\u30a4\u30eb\u3092\u512a\u5148
 splash.plugin.init=\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u521d\u671f\u5316: 
 splash.plugin.UIinit=\u30d7\u30e9\u30b0\u30a4\u30f3 GUI \u3092\u521d\u671f\u5316\u4e2d: %1  
@@ -1499,7 +1482,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent \u30d5\u30a1\u30a4\u30eb...
 MyTrackerView.date_added=\u8ffd\u52a0\u6e08
 ConfigView.section.tracker.portbackup=\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u30dd\u30fc\u30c8\uff08':' \u533a\u5207\u308a\uff09
 ConfigView.label.playfilespeech=\u30d5\u30a1\u30a4\u30eb\u5b8c\u6210\u6642\u306b\u97f3\u58f0\u3067\u77e5\u3089\u305b\u308b
-ConfigView.label.playfilespeech.info=\u73fe\u5728\u3053\u306e\u6a5f\u80fd\u306f\u82f1\u8a9e\u3067\u306e\u307f\u52d5\u4f5c\u3057\u307e\u3059
 ConfigView.label.playfilefinished=\u30d5\u30a1\u30a4\u30eb\u5b8c\u6210\u6642\u306b\u30b5\u30a6\u30f3\u30c9\u3092\u9cf4\u3089\u3059
 ConfigView.label.backupconfigfiles=\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u30d0\u30c3\u30af\u30a2\u30c3\u30d7
 ConfigView.section.tracker.client.scrapesingleonly=\u30c8\u30e9\u30c3\u30ab\u30fc\u3054\u3068\u306e\u30b9\u30af\u30ec\u30a4\u30d7\u3092\u7121\u52b9\u306b\u3059\u308b\uff08'URL too long' (414) \u30a8\u30e9\u30fc\u3092\u8fd4\u3059\u5834\u5408\u306b\u6709\u52b9\u3067\u3059\uff09
@@ -2013,22 +1995,11 @@ v3.mb.delPublished.title=\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u30b7\u30fc\u30c9\
 v3.mb.delPublished.text=\u8b66\u544a\uff1a\u3053\u306e\u64cd\u4f5c\u3067\u306f <A HREF="%2">%3</A> \u304b\u3089\u516c\u958b\u3055\u308c\u3066\u3044\u308b\u30b3\u30f3\u30c6\u30f3\u30c4 '%1' \u306f\u524a\u9664\u3055\u308c\u307e\u305b\u3093\u3002\n\n\u524a\u9664\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u516c\u958b\u3092\u53d6\u308a\u6d88\u3059\u3060\u3051\u3067\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u53ef\u80fd\u306a\u307e\u307e\u306b\u306a\u308a\u307e\u3059\u3002\u30a2\u30c3\u30d7\u30e [...]
 v3.mb.delPublished.delete=\u524a\u9664
 v3.mb.delPublished.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
-v3.mb.openFile.title=\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f
-v3.mb.openFile.text.known=\u3053\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306f Vuze Player \u3067\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u3088\u3063\u3066\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002\n\n\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f: %2 (%3)\n
-v3.mb.openFile.text.unknown=\u3053\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306f Vuze Player \u3067\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u3088\u3063\u3066\u4f5c\u6210\u3055\u308c\u3066\u3044\u308b <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Playback Guide</a> \u3092\u3054\u89a7\u304f\u3060\u3055\u3044\u3002\n\n\u30d5\u30a1\u30a4\u30eb\u62e1\u5f35\u5b50: %2\n
-v3.mb.openFile.button.play=\u518d\u751f
-v3.mb.openFile.button.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
-v3.mb.openFile.button.guide=Playback Guide \u3092\u8aad\u3080
-v3.mb.openFile.remember=\u78ba\u8a8d\u306a\u3057\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f
 v3.mb.PlayFileNotFound.title=\u30d5\u30a1\u30a4\u30eb\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
 v3.mb.PlayFileNotFound.text=\u6307\u5b9a\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb '%1' \u306f\u524a\u9664\u3055\u308c\u305f\u304b\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3002
 v3.mb.PlayFileNotFound.button.remove=Vuze \u304b\u3089\u524a\u9664
 v3.mb.PlayFileNotFound.button.redownload=\u30c7\u30fc\u30bf\u3092\u518d\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
 v3.mb.PlayFileNotFound.button.find=\u624b\u52d5\u3067\u691c\u7d22...
-v3.mb.deletePurchased.title=\u8cfc\u5165\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u524a\u9664
-v3.mb.deletePurchased.text='%1' \u3092\u524a\u9664\u3057\u307e\u3059\u304b\uff1f\n\n\u3053\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u306f\u8cfc\u5165\u3057\u305f\u3082\u306e\u304b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306e\u306b\u30ed\u30b0\u30a4\u30f3\u304c\u5fc5\u8981\u306a\u3082\u306e\u3067\u3059\u3002
-v3.mb.deletePurchased.button.delete=\u524a\u9664
-v3.mb.deletePurchased.button.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
 v3.topbar.menu.show.logo=\u30ed\u30b4
 v3.topbar.menu.show.plugin=\u30d7\u30e9\u30b0\u30a4\u30f3
 v3.topbar.menu.show.search=\u691c\u7d22
@@ -2162,10 +2133,6 @@ v3.splash.hookPluginUI=\u30d7\u30e9\u30b0\u30a4\u30f3 UI \u3092\u30d5\u30c3\u30a
 OpenTorrentWindow.mb.notTorrent.cannot.display=\u30c7\u30fc\u30bf\u3092\u8868\u793a\u3067\u304d\u307e\u305b\u3093\u3002
 MainWindow.menu.window.zoom.maximize=\u6700\u5927\u5316
 MainWindow.menu.window.zoom.restore=\u30ea\u30b9\u30c8\u30a2
-ImageResizer.image.too.small=\u753b\u50cf\u304c\u5c0f\u3055\u3059\u304e\u307e\u3059\u3002\u5225\u306e\u753b\u50cf\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\uff08%1 x %2 \u4ee5\u4e0a\uff09
-ImageResizer.title=Vuze \u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u306b\u8868\u793a\u3055\u308c\u308b\u30b5\u30e0\u30cd\u30fc\u30eb\u3092\u30d7\u30ec\u30d3\u30e5\u30fc\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059
-ImageResizer.move.image=\u30c9\u30e9\u30c3\u30b0\u3057\u3066\u753b\u50cf\u3092\u79fb\u52d5\u3057\u307e\u3059
-ImageResizer.move.image.with.slider=\u30c9\u30e9\u30c3\u30b0\u3057\u3066\u753b\u50cf\u3092\u79fb\u52d5\u3057\u3001\u4e0b\u306e\u30b9\u30e9\u30a4\u30c0\u30fc\u3067\u30b5\u30a4\u30ba\u3092\u5909\u66f4\u3057\u307e\u3059
 security.crypto.title=\u6697\u53f7\u9375\u3078\u306e\u30a2\u30af\u30bb\u30b9
 security.crypto.encrypt=\u65b0\u3057\u304f\u4f5c\u6210\u3057\u305f\u6697\u53f7\u9375\u3092\u4fdd\u8b77\u3059\u308b\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5fd8\u308c\u308b\u3068\u89e3\u9664\u3067\u304d\u306a\u3044\u305f\u3081\u3001\u5fd8\u308c\u306a\u3044\u3088\u3046\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002
 security.crypto.decrypt=\u6697\u53f7\u9375\u3092\u89e3\u9664\u3059\u308b\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
@@ -2249,9 +2216,6 @@ metasearch.addtemplate.dup.title=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u91c
 metasearch.addtemplate.dup.desc=\u691c\u7d22\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8 %1 \u306f\u65e2\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u307e\u3059\u3002
 metasearch.export.select.template.file=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u4fdd\u5b58
 metasearch.import.select.template.file=\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u3092\u958b\u304f
-dialog.uiswitch.title=Vuze UI \u306e\u5207\u308a\u66ff\u3048
-dialog.uiswitch.text=\u3053\u306e\u6a5f\u80fd\u3092\u5229\u7528\u3059\u308b\u306b\u306f Vuze UI \u306b\u5207\u308a\u66ff\u3048\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\n\nVuze \u3092\u518d\u8d77\u52d5\u3057\u3066\u304f\u3060\u3055\u3044\u3002
-dialog.uiswitch.button=Vuze UI \u306b\u5207\u308a\u66ff\u3048\u308b
 azbuddy.tracker.enabled=Friend \u3068\u306e\u30d5\u30a1\u30a4\u30eb\u8ee2\u9001\u3092\u9ad8\u901f\u306b\u3059\u308b 'Friends Boost' \u3092\u4f7f\u7528
 v3.MainWindow.button.download=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9
 v3.MainWindow.button.run=\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u305f\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ka_GE.properties b/org/gudy/azureus2/internat/MessagesBundle_ka_GE.properties
index 602009c..194e654 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ka_GE.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ka_GE.properties
@@ -31,12 +31,9 @@ MainWindow.menu.window.zoom=\u10d2\u10d0\u10d3\u10d8\u10d3\u10d4\u10d1\u10d0
 MainWindow.menu.help=\u10d3\u10dd\u10d9\u10e3\u10db\u10d4\u10dc\u10e2\u10d0\u10ea\u10d8\u10d0
 MainWindow.menu.help.about=Vuze u2013\u10d8\u10e1 \u10e8\u10d4\u10e1\u10d0\u10ee\u10d4\u10d1
 MainWindow.about.title=\u10e9\u10d5\u10d4\u10dc\u10e1 \u10e8\u10d4\u10e1\u10d0\u10ee\u10d4\u10d1
-MainWindow.about.section.developers=\u10de\u10e0\u10dd\u10d2\u10e0\u10d0\u10db\u10d8\u10e1\u10e2\u10d4\u10d1\u10d8
-MainWindow.about.section.translators=\u10db\u10d7\u10d0\u10e0\u10d2\u10db\u10dc\u10d4\u10da\u10d4\u10d1\u10d8
 MainWindow.about.section.internet=\u10d8\u10dc\u10e2\u10d4\u10e0\u10dc\u10d4\u10e2\u10d8
 MainWindow.about.internet.homepage=\u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8\u10e1 \u10e1\u10d0\u10e8\u10d8\u10dc\u10d0\u10dd \u10d2\u10d5\u10d4\u10e0\u10d3\u10d8
 MainWindow.about.internet.sourceforge=\u10de\u10e0\u10dd\u10d4\u10e5\u10e2\u10d8\u10e1 \u10d2\u10d5\u10d4\u10e0\u10d3\u10d8 Sourceforge\u2013\u10d6\u10d4
-MainWindow.about.internet.sourceforgedownloads=Sourceforge\u2013\u10e1 \u10e9\u10d0\u10db\u10dd\u10e2\u10d5\u10d8\u10e0\u10d7\u10d5\u10d4\u10d1\u10d8
 MainWindow.about.internet.bugreports=Bug \u10e0\u10d4\u10de\u10dd\u10e0\u10e2\u10d4\u10d1\u10d8
 MainWindow.about.internet.forumdiscussion=\u10e4\u10dd\u10e0\u10e3\u10db\u10d4\u10d1\u10d8
 MainWindow.about.internet.wiki=\u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8\u10e1 \u10d5\u10d8\u10d9\u10d8 \u10ee.\u10d3.\u10d9.
@@ -270,8 +267,6 @@ IrcView.help=Valid commands are :\n . /help : displays this message\n . /nick |
 PasswordWindow.title=\u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8 \u10d3\u10d0\u10d1\u10da\u10dd\u10d9\u10d8\u10da\u10d8\u10d0
 PasswordWindow.passwordprotected=\u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8 \u10d3\u10d0\u10ea\u10e3\u10da\u10d8\u10d0 \u10de\u10d0\u10e0\u10dd\u10da\u10d8\u10d7.\n\u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8\u10e1 \u10e4\u10d0\u10dc\u10ef\u10e0\u10d8\u10e1 \u10d2\u10d0\u10e1\u10d0\u10ee\u10e1\u10dc\u10d4\u10da\u10d0\u10d3 \u10e8\u10d4\u10d8\u10e7\u10d5\u10d4\u10dc\u10d4\u10d7 \u10d7\u10e5\u10d5\u10d4\u10dc\u10d8 \u10de\u10d0\u10e0\u10dd\u10da\u10d8 :
 Button.ok=\u10d3\u10d8\u10d0\u10ee
-TrackerChangerWindow.title=\u10d3\u10d0\u10d0\u10db\u10d0\u10e2\u10d4 \u10db\u10d4\u10d7\u10d5\u10d0\u10da\u10e7\u10e3\u10e0\u10d4
-TrackerChangerWindow.newtracker=\u10e8\u10d4\u10d8\u10e7\u10d5\u10d0\u10dc\u10d4 \u10d0\u10ee\u10d0\u10da\u10d8 \u10db\u10d4\u10d7\u10d5\u10d0\u10da\u10e7\u10e3\u10e0\u10d8\u10e1 url
 PeersView.discarded=\u10e3\u10d0\u10e0\u10e7\u10dd\u10e4\u10d8\u10da\u10d8\u10d0
 PeersView.discarded.info=\u10d8\u10dc\u10e4\u10dd\u10e0\u10db\u10d0\u10ea\u10d8\u10d0 \u10e0\u10dd\u10db\u10d4\u10da\u10d8\u10ea \u10d7\u10e5\u10d5\u10d4\u10dc\u10d7\u10d0\u10dc \u10e0\u10d0\u10e6\u10d0\u10ea\u10dc\u10d0\u10d8\u10e0\u10d0\u10d3 \u10db\u10dd\u10ee\u10d5\u10d3\u10d0, \u10d0\u10db\u10d8\u10e2\u10dd\u10db\u10d0\u10ea \u10d5\u10d8\u10e8\u10dd\u10e0\u10d4\u10d1\u10d7 \u10d7\u10d0\u10d5\u10d8\u10d3\u10d0.
 discarded=\u10e3\u10d0\u10e0\u10e7\u10dd\u10e4\u10d8\u10da\u10d8\u10d0
@@ -359,7 +354,6 @@ configureWizard.transfer.maxActiveTorrents=\u10d0\u10e5\u10e2\u10d8\u10e3\u10e0\
 configureWizard.transfer.maxDownloads=\u10d2\u10d0\u10d3\u10db\u10dd\u10e2\u10d5\u10d8\u10e0\u10d7\u10d5\u10d4\u10d1\u10d8\u10e1 \u10db\u10d0\u10e5\u10e1. \u10e0\u10d0\u10dd\u10d3\u10d4\u10dc\u10dd\u10d1\u10d0
 configureWizard.transfer.maxUploadsPerTorrent=\u10db\u10d0\u10e5\u10e1. \u10d0\u10d7\u10d5\u10d8\u10e0\u10d7\u10d5\u10d4\u10d1\u10d8 \u10d4\u10e0\u10d7 \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d6\u10d4
 configureWizard.nat.title=NAT / \u10e1\u10d4\u10e0\u10d5\u10d4\u10e0\u10d8\u10e1 \u10de\u10dd\u10e0\u10e2\u10d8
-configureWizard.nat.message=\u10d1\u10d8\u10e2\u2013\u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d8\u10e1 \u10db\u10d0\u10e5\u10e1\u10d8\u10d0\u10db\u10d0\u10da\u10e3\u10e0\u10d0\u10d3 \u10e1\u10d0\u10e1\u10d0\u10e0\u10d2\u10d4\u10d1\u10da\u10dd \u10db\u10dd\u10ee\u10db\u10d0\u10e0\u10d4\u10d1\u10d8\u10e1\u10d0\u10d7\u10d5\u10d8\u10e1, \u10e0\u10d4\u10d9\u10dd\u10db\u10d4\u10dc\u10d3\u10d4\u10d1\u10e3\u10da\u10d8\u10d0 \u10e0\u10dd\u10db \u10d8\u10e7\u10dd\u10d7 \u10e1\u10e0\u10e3\u10da\u10d0 [...]
 configureWizard.nat.test=\u10e2\u10d4\u10e1\u10e2\u10d8
 configureWizard.nat.testing=\u10de\u10dd\u10e0\u10e2\u10d8\u10e1 \u10e2\u10d4\u10e1\u10e2\u10d8\u10e0\u10d4\u10d1\u10d0
 configureWizard.nat.ok=\u10d0\u10e0\u10d8\u10e1 !
@@ -492,7 +486,6 @@ ConfigView.label.movetorrent=\u10d2\u10d0\u10d3\u10d0\u10d8\u10e2\u10d0\u10dc\u1
 ConfigView.section.file.decoder.nodecoder=\u10d0\u10e0\u10ea\u10d4\u10e0\u10d7\u10d8
 ConfigView.section.tracker.publicenable=\u10e9\u10d0\u10e0\u10d7\u10d4 \u10d2\u10d0\u10e0\u10d4\u10e8\u10d4 \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d4\u10d1\u10d8
 ConfigView.label.playdownloadspeech=\u10e9\u10d0\u10db\u10dd\u10e2\u10d5\u10d8\u10e0\u10d7\u10d5\u10d8\u10e1 \u10d3\u10d0\u10e1\u10e0\u10e3\u10da\u10d4\u10d1\u10d8\u10e1\u10d0\u10e1 \u10e8\u10d4\u10db\u10d0\u10e2\u10e7\u10dd\u10d1\u10d8\u10dc\u10d4 \u10e1\u10d8\u10e2\u10e7\u10d5\u10d8\u10d4\u10e0\u10d0\u10d3
-ConfigView.label.playdownloadspeech.info=\u10db\u10d4\u10e2\u10e7\u10d5\u10d4\u10da\u10d4\u10d1\u10d8\u10e1 \u10e1\u10d4\u10e0\u10d5\u10d8\u10e1\u10d4\u10d1\u10d8 \u10e1\u10d0\u10e3\u10d9\u10d4\u10d7\u10d4\u10e1\u10dd\u10d3 \u10db\u10ee\u10dd\u10da\u10dd\u10d3 \u10d8\u10dc\u10d2\u10da\u10d8\u10e1\u10e3\u10e0\u10d0\u10d3 \u10db\u10e3\u10e8\u10d0\u10dd\u10d1\u10e1
 #
 # Tooltips
 #
@@ -1056,16 +1049,11 @@ ConfigView.section.connection.advanced=\u10e5\u10e1\u10d4\u10da\u10d8\u10e1 \u10
 ConfigView.section.connection.advanced.mtu=\u10db\u10d0\u10e5\u10e1\u10d8\u10d0\u10db\u10da\u10e3\u10e0\u10d8 \u10d2\u10d0\u10d3\u10d0\u10e1\u10d0\u10ea\u10d4\u10db\u10d8 \u10d4\u10e0\u10d7\u10d4\u10e3\u10da\u10d8 (MTU)
 ConfigView.section.connection.advanced.SO_RCVBUF=\u10e1\u10dd\u10d9\u10d4\u10e2\u10d8\u10e1 SO_RCVBUF \u10d6\u10dd\u10db\u10d0 [0: use OS default]
 ConfigView.section.connection.advanced.SO_SNDBUF=\u10e1\u10dd\u10d9\u10d4\u10e2\u10d8\u10e1 SO_SNDBUF \u10d6\u10dd\u10db\u10d0 [0: use OS default]
-ConfigView.section.interface.confirm_torrent_removal=\u10d0\u10e9\u10d5\u10d4\u10dc\u10d4 \u10d3\u10d0\u10d3\u10d0\u10e1\u10e2\u10e3\u10e0\u10d4\u10d1\u10d8\u10e1 \u10d3\u10d8\u10d0\u10da\u10dd\u10d2\u10d8 torrent\u2013\u10d8\u10e1 \u10ec\u10d0\u10e8\u10da\u10d8\u10e1\u10d0\u10e1
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u10d3\u10d0\u10d0\u10d3\u10d0\u10e1\u10e2\u10e3\u10e0\u10d4 \u10e0\u10dd\u10ea\u10d0 \u10e8\u10da\u10d8  \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10e1 \u10e9\u10d4\u10db\u10d8 \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d4\u10d1\u10d8\u10e1 \u10e4\u10d0\u10dc\u10ef\u10e0\u10d8\u10d3\u10d0\u10dc.
-MyTorrentsView.confirm_torrent_removal=\u10d3\u10d0\u10ec\u10e0\u10db\u10e3\u10dc\u10d4\u10d1\u10e3\u10da\u10d8 \u10ee\u10d0\u10e0 \u10ec\u10d0\u10e8\u10d0\u10da\u10dd?\n
 PeersView.connected_time=\u10e8\u10d4\u10d4\u10e0\u10d7\u10d4\u10d1\u10d8\u10e1 \u10d3\u10e0\u10dd
 PeersView.connected_time.info=\u10de\u10d8\u10e0\u10d7\u10d0\u10dc \u10e8\u10d4\u10d4\u10e0\u10d7\u10d4\u10d1\u10d8\u10e1 \u10e1\u10e0\u10e3\u10da\u10d8 \u10d3\u10e0\u10dd
-ConfigView.section.interface.display.add_torrents_silently=\u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d4\u10d1\u10d8\u10e1 \u10e3\u10ee\u10db\u10d0\u10e3\u10e0\u10dd\u10d3 \u10e9\u10d0\u10db\u10d0\u10e2\u10d4\u10d1\u10d0
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u10d3\u10d0\u10d0\u10db\u10d0\u10e2\u10d4\u10d1\u10e1 \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d4\u10d1\u10e1 \u10d0\u10d6\u10e3\u10e0\u10d4\u10e3\u10e1\u10d8\u10e1 \u10db\u10d7\u10d0\u10d5\u10d0\u10e0\u10d8 \u10e4\u10d0\u10dc\u10ef\u10e0\u10d8\u10e1 \u10d2\u10d0\u10db\u10dd\u10e9\u10d4\u10dc\u10d8\u10e1 \u10d2\u10d0\u10e0\u10d4\u10e8\u10d4
 TableColumn.header.maxdownspeed=\u10db\u10d0\u10e5\u10e1. \u10e9\u10d0\u10db\u10dd\u10e2\u10d5\u10d8\u10e0\u10d7\u10d5\u10d8\u10e1 \u10e1\u10d8\u10e9\u10e5\u10d0\u10e0\u10d4
 TableColumn.header.maxdownspeed.info=\u10db\u10d0\u10e5\u10e1. \u10e9\u10d0\u10db\u10dd\u10e2\u10d5\u10d8\u10e0\u10d7\u10d5\u10d8\u10e1 \u10e1\u10d8\u10e9\u10e5\u10d0\u10e0\u10d4 \u10d7\u10d8\u10d7\u10dd\u10d4\u10e3\u10da \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d6\u10d4
-PeersGraphicView.title=\u10e1\u10e5\u10d4\u10db\u10d0
+PeersGraphicView.title.full=\u10e1\u10e5\u10d4\u10db\u10d0
 TableColumn.header.torrentpath=\u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d8\u10e1 \u10db\u10d3\u10d4\u10d1\u10d0\u10e0\u10d4\u10dd\u10d1\u10d0
 TableColumn.header.torrentpath.info=\u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d8\u10e1 \u10db\u10d3\u10d4\u10d1\u10d0\u10e0\u10d4\u10dd\u10d1\u10d0 \u10d3\u10d8\u10e1\u10d9\u10d6\u10d4
 ConfigView.section.sharing.torrentcomment=\u10d9\u10dd\u10db\u10d4\u10dc\u10e2\u10d0\u10e0\u10d8 \u10d2\u10d4\u10dc\u10d4\u10e0\u10d8\u10e0\u10d4\u10d1\u10e3\u10da\u10d8 \u10e2\u10dd\u10e0\u10d4\u10dc\u10e2\u10d4\u10d1\u10d8\u10e1\u10d0\u10d7\u10d5\u10d8\u10e1
@@ -1191,7 +1179,6 @@ MyTrackerView.category=\u10d9\u10d0\u10e2\u10d4\u10d2\u10dd\u10e0\u10d8\u10d0
 VivaldiView.title.full=\u10d5\u10d8\u10d5\u10d0\u10da\u10d3\u10d8
 MyTrackerView.date_added=\u10d3\u10d0\u10db\u10d0\u10e2\u10d4\u10d1\u10e3\u10da\u10d8\u10d0
 ConfigView.label.playfilespeech=\u10d8\u10e1\u10d0\u10e3\u10d1\u10e0\u10d4 \u10e0\u10dd\u10ea\u10d0 \u10d3\u10d0\u10e1\u10e0\u10e3\u10da\u10d3\u10d4\u10d1\u10d0 \u10e4\u10d0\u10d8\u10da\u10d8
-ConfigView.label.playfilespeech.info=\u10e1\u10d0\u10e3\u10d1\u10e0\u10d8\u10e1 \u10e1\u10d4\u10e0\u10d5\u10d8\u10e1\u10d4\u10d1\u10d8 \u10db\u10e3\u10e8\u10d0\u10dd\u10d1\u10e1 \u10d9\u10d0\u10e0\u10d2\u10d0\u10d3 \u10db\u10ee\u10dd\u10da\u10dd\u10d3 \u10d8\u10dc\u10d2\u10da\u10d8\u10e1\u10e3\u10e0\u10d7\u10d0\u10dc
 ConfigView.label.playfilefinished=\u10d3\u10d0\u10e3\u10d9\u10d0\u10e0\u10d8 \u10ee\u10db\u10dd\u10d5\u10d0\u10dc\u10d8 \u10e8\u10d4\u10e2\u10e7\u10dd\u10d1\u10d8\u10dc\u10d4\u10d1\u10d0 \u10e0\u10dd\u10ea\u10d0 \u10d3\u10d0\u10e1\u10e0\u10e3\u10da\u10d3\u10d4\u10d1\u10d0
 ConfigView.label.backupconfigfiles=\u10d9\u10dd\u10dc\u10e4\u10d8\u10d2\u10e3\u10e0\u10d0\u10ea\u10d8\u10d8\u10e1 \u10e8\u10d4\u10db\u10ea\u10d5\u10d4\u10da\u10d8 \u10e4\u10d0\u10d8\u10da\u10d4\u10d1\u10d8\u10e1 \u10e0\u10d4\u10d6\u10d4\u10e0\u10d5\u10d8\u10e0\u10d4\u10d1\u10d0 \u10d0\u10e6\u10d2\u10d4\u10dc\u10d8\u10e1 \u10e8\u10d4\u10db\u10d3\u10d2\u10dd\u10db\u10d8 \u10d0\u10e6\u10d3\u10d2\u10d4\u10dc\u10d8\u10e1\u10d0\u10d7\u10d5\u10d8\u10e1
 ActivityView.legend.limit=\u10e0\u10d4\u10d8\u10e2\u10d8\u10dc\u10d2\u10d8\u10e1 \u10da\u10d8\u10db\u10d8\u10e2\u10d8
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ko_KR.properties b/org/gudy/azureus2/internat/MessagesBundle_ko_KR.properties
index 4116b44..bd25fc2 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ko_KR.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ko_KR.properties
@@ -1,298 +1,297 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c...
-Main.parameter.usage=\uc0ac\uc6a9\ubc95: java org.gudy.azureus2.cl.Main [parameters] "file.torrent" "save path"
-Main.parameter.maxUploads=\ub3d9\uc2dc \uc62c\ub9ac\uae30\ud560 \ucd5c\ub300 \uc218
-Main.parameter.maxSpeed=\ucd5c\uace0 \uc62c\ub9ac\uae30 \uc18d\ub3c4 (\ubc14\uc774\ud2b8/\ucd08)
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=\ud1a0\ub80c\ud2b8 \ud30c\uc77c...
+Main.parameter.usage=\uc0ac\uc6a9\ubc95: java org.gudy.azureus2.cl.Main [\ud30c\ub77c\ubbf8\ud130] "file.torrent" "\uc800\uc7a5 \uacbd\ub85c"
+Main.parameter.maxUploads=\ucd5c\ub300 \ub3d9\uc2dc \uc5c5\ub85c\ub4dc \uc218
+Main.parameter.maxSpeed=\ucd5c\uace0 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 (bytes/\ucd08)
 MainWindow.menu.file=\ud30c\uc77c(&F)
 MainWindow.menu.file.open=\uc5f4\uae30(&O)
-MainWindow.menu.file.create=\ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4\uae30...(&C)
+MainWindow.menu.file.create=\uc0c8 \ud1a0\ub80c\ud2b8(&N)...
 MainWindow.menu.file.create.fromfile=\ud30c\uc77c\uc5d0\uc11c(&F)
 MainWindow.menu.file.create.fromdir=\ud3f4\ub354\uc5d0\uc11c(&D)
-MainWindow.menu.file.export=XML \ud1a0\ub7f0\ud2b8\ub97c \ub0b4\ubcf4\ub0b4\uae30...(&E)
-MainWindow.menu.file.import=XML \ud1a0\ub7f0\ud2b8\ub97c \ub4e4\uc5ec\uc624\uae30...(&I)
+MainWindow.menu.file.export=XML \ud1a0\ub80c\ud2b8 \ub0b4\ubcf4\ub0b4\uae30(&E)...
+MainWindow.menu.file.import=XML \ud1a0\ub80c\ud2b8 \uac00\uc838\uc624\uae30(&I)...
 MainWindow.menu.file.closetab=\ud0ed \ub2eb\uae30(&T)
 MainWindow.menu.file.closewindow=\ucc3d \ub2eb\uae30(&W)
-MainWindow.menu.file.exit=\ub05d\ub0b4\uae30(&X)
-MainWindow.dialog.choose.file=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uace0\ub974\uae30
-MainWindow.menu.file.folder=\ud3f4\ub354...(&F)
-MainWindow.dialog.choose.folder=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc774 \uc788\ub294 \ud3f4\ub354 \uace0\ub974\uae30
+MainWindow.menu.file.exit=\ub098\uac00\uae30(&X)
+MainWindow.dialog.choose.file=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc120\ud0dd
+MainWindow.menu.file.folder=\ud3f4\ub354(&F)...
+MainWindow.dialog.choose.folder=\ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc774 \ub4e4\uc5b4\uc788\ub294 \ub514\ub809\ud130\ub9ac \uc120\ud0dd
 MainWindow.menu.view=\ubcf4\uae30(&V)
-MainWindow.menu.view.show=\ubcf4\uc774\uae30
-MainWindow.menu.view.mytorrents=\ub0b4 \ud1a0\ub7f0\ud2b8(&M)
-MainWindow.menu.view.mytorrents.keybinding=\uba54\ud0c0+1
-MainWindow.menu.view.open_global_transfer_bar=\uad50\ud658 \ud45c\uc2dc\uc904
-MainWindow.menu.view.configuration=\uc120\ud0dd\uc0ac\ud56d...(&O)
-MainWindow.menu.view.configuration.keybinding=\uba54\ud0c0+,
+MainWindow.menu.view.show=\ubcf4\uc5ec\uc8fc\uae30
+MainWindow.menu.view.mytorrents=\ub0b4 \ud1a0\ub80c\ud2b8(&M)
+MainWindow.menu.view.open_global_transfer_bar=\uc804\uc1a1 \ub9c9\ub300
+MainWindow.menu.view.configuration=\uc635\uc158(&O)...
 MainWindow.menu.view.console=\ucf58\uc194(&O)
-MainWindow.menu.view.console.keybinding=\uba54\ud0c0+4
 MainWindow.menu.view.irc=IRC(&I)
-MainWindow.menu.view.allpeers=\ubaa8\ub4e0 \ub3d9\ub8cc
-MainWindow.menu.view.detailedlist=&\uc138\ubd80 \ubaa9\ub85d
-MainWindow.menu.closealldetails=\ubaa8\ub4e0 \uc0c1\uc138 \uc815\ubcf4 \ub2eb\uae30(&A)
-MainWindow.menu.closealldownloadbars=\ubaa8\ub4e0 \ub0b4\ub824\ubc1b\uae30 \ub9c9\ub300 \ub2eb\uae30(&B)
-MainWindow.menu.language=\ub9d0(&L)
+MainWindow.menu.view.allpeers=\ubaa8\ub4e0 \ud53c\uc5b4
+MainWindow.menu.view.detailedlist=\uc138\ubd80 \ubaa9\ub85d(&D)
+MainWindow.menu.closealldetails=\ubaa8\ub4e0 \uc138\ubd80\uc0ac\ud56d \ub2eb\uae30(&A)
+MainWindow.menu.closealldownloadbars=\ubaa8\ub4e0 \ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \ub2eb\uae30(&B)
+MainWindow.menu.language=\uc5b8\uc5b4(&L)
 ConfigView.section.language=\uc5b8\uc5b4
 MainWindow.menu.window=\ucc3d(&W)
 MainWindow.menu.window.minimize=\ucd5c\uc18c\ud654(&M)
-MainWindow.menu.window.minimize.keybinding=\uba54\ud0c0+M
 MainWindow.menu.window.zoom=\ud655\ub300(&Z)
 MainWindow.menu.window.alltofront=\ubaa8\ub450 \uc55e\uc73c\ub85c \uac00\uc838\uc624\uae30(&F)
 MainWindow.menu.help=\ub3c4\uc6c0\ub9d0(&H)
 MainWindow.menu.help.about=Vuze \uc815\ubcf4
-MainWindow.menu.torrent=\ud1a0\ub7f0\ud2b8 (T&)
+MainWindow.menu.torrent=\ud1a0\ub80c\ud2b8(&O)
 MainWindow.about.title=\uc815\ubcf4
 MainWindow.about.section.developers=\uac1c\ubc1c\uc790
-MainWindow.about.section.translators=\uc5ed\uc790
+MainWindow.about.section.translators=\ubc88\uc5ed\uc790
 MainWindow.about.section.system=\uc2dc\uc2a4\ud15c
 MainWindow.about.section.internet=\uc778\ud130\ub137
 MainWindow.about.internet.homepage=Vuze \ud648\ud398\uc774\uc9c0
 MainWindow.about.internet.sourceforge=Sourceforge \ud504\ub85c\uc81d\ud2b8 \ud398\uc774\uc9c0
-MainWindow.about.internet.sourceforgedownloads=Sourceforge \ub0b4\ub824\ubc1b\uae30
+MainWindow.about.internet.sourceforgedownloads=Sourceforge \ub2e4\uc6b4\ub85c\ub4dc
 MainWindow.about.internet.bugreports=\ubc84\uadf8 \ub9ac\ud3ec\ud2b8
 MainWindow.about.internet.forumdiscussion=\ud3ec\ub7fc
-MainWindow.about.internet.wiki=Vuze \uc704\ud0a4\uc704\ud0a4 \uc790\uc8fc \ubb3b\ub294 \ubb3c\uc74c
-MainWindow.dialog.choose.savepath=\uc800\uc7a5 \uc704\uce58 \uace0\ub974\uae30
-MainWindow.dialog.choose.savepath_forallfiles=\ubaa8\ub4e0 \ud30c\uc77c\uc758 \uc800\uc7a5 \uc704\uce58 \uace0\ub974\uae30
-MainWindow.status.latestversion=\ucd5c\uc2e0 \ubc84\uc804
+MainWindow.dialog.choose.savepath=\uc800\uc7a5 \uacbd\ub85c \uc120\ud0dd
+MainWindow.dialog.choose.savepath_forallfiles=*\ubaa8\ub4e0* \ud30c\uc77c\uc5d0 \ub300\ud55c \uc800\uc7a5 \uacbd\ub85c \uc120\ud0dd
+MainWindow.status.latestversion=\ucd5c\uc2e0
 MainWindow.status.latestversion.clickupdate=\uc5c5\ub370\uc774\ud2b8\ud558\ub824\uba74 \ud074\ub9ad
-MainWindow.status.unknown=\uc54c\uc218\uc5c6\uc74c
-MainWindow.status.checking=\uac80\uc0ac\ud558\uace0 \uc788\uc74c
-MyTorrentsView.mytorrents=\ub0b4 \ud1a0\ub7f0\ud2b8
+MainWindow.status.unknown=\uc54c \uc218 \uc5c6\uc74c
+MainWindow.status.checking=\uac80\uc0ac\uc911
+MyTorrentsView.mytorrents=\ub0b4 \ud1a0\ub80c\ud2b8
 TableColumn.header.name=\uc774\ub984
 TableColumn.header.size=\ud06c\uae30
-TableColumn.header.done=\ub9c8\uce68
-TableColumn.header.done.info=\uc9c0\uae08\uc758 \uc791\uc5c5\uc5d0\uc11c \ub9c8\uce5c \ubc31\ubd84\uc728
+TableColumn.header.done=\uc644\ub8cc
+TableColumn.header.done.info=\ud604\uc7ac \uc791\uc5c5\uc774 \uc644\ub8cc\ub41c \ud37c\uc13c\ud14c\uc774\uc9c0\uc785\ub2c8\ub2e4.
 TableColumn.header.status=\uc0c1\ud0dc
-TableColumn.header.status.info=\ud1a0\ub7f0\ud2b8\uac00 \ud558\uace0 \uc788\ub294 \uac83
-TableColumn.header.seeds=\uc528\uc557
-TableColumn.header.seeds.info=\uc528\uc557 \uc218 \uc5f0\uacb0\ub428 (\ucd1d \uc528\uc557 \uc218)
-TableColumn.header.peers=\ub3d9\ub8cc
-TableColumn.header.peers.info=\uc5f0\uacb0\ub41c \ub3d9\ub8cc\uc218 (\ucd1d \ub3d9\ub8cc \uc218)
-TableColumn.header.downspeed=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4
-TableColumn.header.upspeed=\uc62c\ub9ac\uae30 \uc18d\ub3c4
-TableColumn.header.eta=\ub9c8\uce68 \uc608\uc815 \uc2dc\uac01
-TableColumn.header.tracker=\ub354\ub4ec\uc774 \uc0c1\ud0dc
-TableColumn.header.tracker.info=\ub354\ub4ec\uc774\uc758 \uc0c1\ud0dc
-TableColumn.header.trackernextaccess=\ub2e4\uc74c \ub354\ub4ec\uc774 \uc811\uadfc
-TableColumn.header.trackernextaccess.info=\ub2e4\uc74c \ub354\ub4ec\uc774 \uc811\uadfc\uc774 \uc77c\uc5b4\ub0a0 \ub54c
+TableColumn.header.status.info=\ud1a0\ub80c\ud2b8\uac00 \ud558\uace0 \uc788\ub294 \uac83\uc774 \ubb34\uc5c7\uc778\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.seeds=\uc2dc\ub4dc
+TableColumn.header.seeds.info=\uc5f0\uacb0\ub41c \uc2dc\ub4dc \uc218 (\uc804\uccb4 \uc2dc\ub4dc \uc218)\uc785\ub2c8\ub2e4.
+TableColumn.header.peers=\ud53c\uc5b4
+TableColumn.header.peers.info=\uc5f0\uacb0\ub41c \ud53c\uc5b4\uc758 \uc218 (\uc804\uccb4 \ud53c\uc5b4 \uc218)\uc785\ub2c8\ub2e4.
+TableColumn.header.completed=\uc644\ub8cc\ub428
+TableColumn.header.completed.info=\ud2b8\ub798\ucee4\uc5d0 \uc758\ud574 \ubcf4\uace0\ub41c \ud1a0\ub80c\ud2b8 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \uc644\ub8cc\ud55c \ud53c\uc5b4\uc758 \uc218\uc785\ub2c8\ub2e4.
+TableColumn.header.downspeed=\ub2e4\uc6b4 \uc18d\ub3c4
+TableColumn.header.upspeed=\uc5c5 \uc18d\ub3c4
+TableColumn.header.tracker=\ud2b8\ub798\ucee4 \uc0c1\ud0dc
+TableColumn.header.tracker.info=\ud2b8\ub798\ucee4\uc758 \uc0c1\ud0dc\uc785\ub2c8\ub2e4.
+TableColumn.header.trackernextaccess=\ub2e4\uc74c \ud2b8\ub798\ucee4 \uc811\uadfc
+TableColumn.header.trackernextaccess.info=\ub2e4\uc74c \ud2b8\ub798\ucee4 \uc811\uadfc\uc774 \uc77c\uc5b4\ub098\ub294 \uc2dc\uac04\uc774 \uc5b8\uc81c\uc778\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
 TableColumn.header.priority=\uc6b0\uc120\uad8c
-TableColumn.header.priority.info=\uc62c\ub9ac\uae30 \ub300\uc5ed\ud3ed\uc774 \uc5bc\ub9c8\ub9cc\ud07c \ud1a0\ub7f0\ud2b8\uc5d0 \uc8fc\uc5b4\uc9c0\ub294\uc9c0 \uc815\ud569\ub2c8\ub2e4.
-MyTorrentsView.menu.showdetails=\uc0c1\uc138 \uc815\ubcf4 \ubcf4\uc774\uae30(&D)
-MyTorrentsView.menu.showdownloadbar=\ub0b4\ub824\ubc1b\uae30 \ub9c9\ub300 \ubcf4\uc774\uae30(&B)
+TableColumn.header.priority.info=\ud1a0\ub80c\ud2b8\uc5d0 \uc8fc\uc5b4\uc9c4 \uc5c5\ub85c\ub4dc \ub300\uc5ed\ud3ed\uc774 \uc5bc\ub9c8\uc778\uc9c0\ub97c \uacb0\uc815\ud569\ub2c8\ub2e4.
+TableColumn.header.seeds.fullcopycalc=%1 \ud53c\uc5b4\uc5d0 \ub300\ud574 %2 \uc644\uc804\ud55c \uc0ac\ubcf8\uc774 \uc788\uc74c\uc744 \uac00\uc815\ud569\ub2c8\ub2e4.
+MyTorrentsView.menu.showdetails=\uc138\ubd80\uc0ac\ud56d \ubcf4\uc5ec\uc8fc\uae30(&D)
+MyTorrentsView.menu.showdownloadbar=\ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \ubcf4\uc5ec\uc8fc\uae30(&B)
 MyTorrentsView.menu.open=\ud30c\uc77c \uc5f4\uae30(&O)
 MyTorrentsView.menu.setpriority=\uc6b0\uc120\uad8c \uc9c0\uc815(&P)
 MyTorrentsView.menu.setpriority.high=\ub192\uc74c(&H)
 MyTorrentsView.menu.setpriority.low=\ub0ae\uc74c(&L)
 MyTorrentsView.menu.start=\uc2dc\uc791(&S)
-MyTorrentsView.menu.stop=\uba48\ucda4(&P)
-MyTorrentsView.menu.remove=\uc9c0\uc6b0\uae30(&R)
-MyTorrentsView.menu.changeTracker=\ub354\ub4ec\uc774 \uc8fc\uc18c \ub354\ud558\uae30(&A)
-TrayWindow.menu.exit=\ub05d\ub0b4\uae30(&X)
-TrayWindow.menu.show=Vuze \ubcf4\uc774\uae30(&S)
+MyTorrentsView.menu.stop=\uc815\uc9c0(&P)
+MyTorrentsView.menu.remove=\uc81c\uac70(&R)
+MyTorrentsView.menu.changeTracker=\ud2b8\ub798\ucee4 URL \ucd94\uac00(&A)
+TrayWindow.menu.exit=\ub098\uac00\uae30(&X)
+TrayWindow.menu.show=Vuze \ubcf4\uc5ec\uc8fc\uae30(&S)
 SystemTray.menu.exit=\ub05d\ub0b4\uae30(&X)
-SystemTray.menu.closealldownloadbars=\ubaa8\ub4e0 \ub0b4\ub824\ubc1b\uae30 \ub9c9\ub300 \ub2eb\uae30(&A)
-SystemTray.menu.show=Vuze \ubcf4\uc774\uae30(&S)
-PeersView.ip.info=\ub3d9\ub8cc\uc758 IP
+SystemTray.menu.closealldownloadbars=\ubaa8\ub4e0 \ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \ub2eb\uae30(&A)
+SystemTray.menu.open_global_transfer_bar=\uc804\uc1a1 \ub9c9\ub300 \ubcf4\uc5ec\uc8fc\uae30
+SystemTray.menu.show=Vuze \ubcf4\uc5ec\uc8fc\uae30(&S)
+PeersView.ip.info=\ud53c\uc5b4\uc758 IP
 PeersView.port=\ud3ec\ud2b8
-PeersView.port.info=\uc4f0\uc774\ub294 \ud3ec\ud2b8
-PeersView.T=\uac78\uae30
-PeersView.T.info=L(\uc5ec\uae30): \ub2f9\uc2e0\uc774 \uc5f0\uacb0\ud558\uc600\uc2b5\ub2c8\ub2e4. R(\uc800\uae30): \ub3d9\ub8cc\uac00 \uc5f0\uacb0\ud558\uc600\uc2b5\ub2c8\ub2e4.
-PeersView.I1=\ub04c (\ub3d9\ub8cc\uc5d0\uac8c \ub04c\ub9bc)
-PeersView.I1.info=\ub2f9\uc2e0\uc740 \ub2e4\ub978 \ub3d9\ub8cc\uc5d0\uac8c \uc788\ub294 \uac83\uc5d0 \ub04c\ub9bd\ub2c8\uae4c?
-PeersView.C1=\ub9c9 (\ub3d9\ub8cc\uc5d0\uac8c \ub9c9\ud798)
-PeersView.C1.info=\ub3d9\ub8cc\uac00 \ub098\uc758 \ub0b4\ub824\ubc1b\uae30\ub97c \ub9c9\uc558\ub294\uc9c0 \ubcf4\uc5ec\uc90c
+PeersView.port.info=\uc0ac\uc6a9 \uc911\uc778 \ud3ec\ud2b8
+PeersView.T.info=L (\ub85c\uceec): \uc0ac\uc6a9\uc790 \uce21\uc5d0\uc11c \uc5f0\uacb0 \ud655\ub9bd, R (\uc6d0\uaca9): \ud53c\uc5b4 \uce21\uc5d0\uc11c \uc5f0\uacb0 \ud655\ub9bd.
+PeersView.T.L.tooltip=\uc0ac\uc6a9\uc790 \uce21\uc5d0\uc11c \uc5f0\uacb0 \ud655\ub9bd
+PeersView.T.R.tooltip=\ud53c\uc5b4 \uce21\uc5d0\uc11c \uc5f0\uacb0 \ud655\ub9bd
+PeersView.I1=I (\ud53c\uc5b4\uc758 \uad00\uc2ec)
+PeersView.I1.info=\ub2e4\ub978 \ud53c\uc5b4\uac00 \uac00\uc9c4 \uc5b4\ub5a4 \uac83\uc5d0 \uad00\uc2ec\uc774 \uc788\uc2b5\ub2c8\uae4c?
+PeersView.C1=C (\ud53c\uc5b4\uc5d0 \uc758\ud574 \ud3ec\ud654)
+PeersView.C1.info=\uc0ac\uc6a9\uc790\uac00 \ub2e4\uc6b4\ub85c\ub4dc \ud558\ub824\ub294 \uac83\uc744 \ud53c\uc5b4\uac00 \uc815\uc9c0\uc2dc\ucf30\ub294\uc9c0\ub97c \ubcf4\uc5ec\uc90d\ub2c8\ub2e4.
 PeersView.pieces=\uc870\uac01
-PeersView.downloadspeed=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4
-PeersView.download=\ub0b4\ub824\ubc1b\uae30
-PeersView.I2=\ub04c (\ub3d9\ub8cc\ub97c \ub04e)
-PeersView.I2.info=\ub3d9\ub8cc\ub294 \ub2f9\uc2e0\uc5d0\uac8c \uc788\ub294 \uac83\uc5d0 \ub04c\ub9bd\ub2c8\uae4c?
-PeersView.C2=\ub9c9 (\ub3d9\ub8cc\ub97c \ub9c9\uc74c)
-PeersView.C2.info=\ub0b4\uac00 \ub3d9\ub8cc\uc758 \ub0b4\ub824\ubc1b\uae30\ub97c \ub9c9\uc558\ub294\uc9c0 \ubcf4\uc5ec\uc90c
-PeersView.uploadspeed=\uc62c\ub9ac\uae30 \uc18d\ub3c4
-PeersView.uploadspeed.info=\ub2f9\uc2e0\uc774 \ub3d9\ub8cc\uc5d0\uac8c \uc62c\ub9b0 \uc18d\ub3c4
-PeersView.upload=\uc62c\ub9ac\uae30
-PeersView.upload.info=\ub2f9\uc2e0\uc774 \ub3d9\ub8cc\uc5d0\uac8c \uc62c\ub9ac\uae30 \ubaa8\ub450
-PeersView.statup=\uc62c\ub9ac\uae30 \ud1b5\uacc4\ub7c9
-PeersView.statup.info=\ub3d9\ub8cc\uc758 \uc62c\ub9ac\uae30 \uc18d\ub3c4\ub97c \uc5b4\ub9bc\uc7a1\uc740 \uac12
-PeersView.S=\uba48\uce6b
-PeersView.S.info=\uba48\ucdb0\uc9d0: \ub3d9\ub8cc\uac00 \uc190\uc218 \ub610\ub294 (\uadf8\ub2e4\uc9c0 \ub109\ub109\ud55c \uc18d\ub3c4\ub85c \ub370\uc774\ud130\ub97c \ub118\uae30\uc9c0 \ubabb\ud558\uc5ec\uc11c) \uc800\uc808\ub85c \uba48\ucdb0\uc9c8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-PeersView.downloadspeedoverall=\ubaa8\ub4e0 \ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4
-PeersView.optunchoke=\uace8\ub77c\uc11c \ub9c9\uc9c0 \uc54a\uc74c
-PeersView.client=\uc811\uc18d \ud504\ub85c\uadf8\ub7a8
-PeersView.client.info=\ub3d9\ub8cc\uac00 \uc4f0\uace0 \uc788\ub294 BitTorrent \uc811\uc18d \ud504\ub85c\uadf8\ub7a8
-PeersView.menu.snubbed=\uba48\ucdb0\uc9d0(&S)
-PeersView.title.short=\ub3d9\ub8cc
-PeersView.title.full=\ub3d9\ub8cc
-AllPeersView.title.full=\ubaa8\ub4e0 \ub3d9\ub8cc
+PeersView.downloadspeed=\ub2e4\uc6b4 \uc18d\ub3c4
+PeersView.download=\ub2e4\uc6b4
+PeersView.download.info=\ud53c\uc5b4\ub85c\ubd80\ud130\uc758 \uc804\uccb4 \ub2e4\uc6b4\ub85c\ub4dc
+PeersView.I2=I (\ud53c\uc5b4\uc5d0 \ub300\ud55c \uad00\uc2ec)
+PeersView.I2.info=\uc0ac\uc6a9\uc790\uac00 \uac00\uc9c4 \uac83\uc5d0 \ud53c\uc5b4\uac00 \uad00\uc2ec\uc774 \uc788\uc2b5\ub2c8\uae4c?
+PeersView.C2=C (\ud53c\uc5b4\ub97c \ud3ec\ud654)
+PeersView.C2.info=\ud53c\uc5b4\uac00 \ub2e4\uc6b4\ub85c\ub4dc \ud558\ub824\ub294 \uac83\uc744 \uc0ac\uc6a9\uc790\uac00 \uc815\uc9c0\uc2dc\ucf30\ub294\uc9c0\ub97c \ubcf4\uc5ec\uc90d\ub2c8\ub2e4.
+PeersView.uploadspeed=\uc5c5 \uc18d\ub3c4
+PeersView.uploadspeed.info=\ud53c\uc5b4\uc5d0\uac8c \uc0ac\uc6a9\uc790\uac00 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc18d\ub3c4
+PeersView.upload=\uc5c5
+PeersView.upload.info=\uc0ac\uc6a9\uc790\uac00 \ud53c\uc5b4\uc5d0\uac8c \uc5c5\ub85c\ub4dc\ud55c \uc804\uccb4\uc785\ub2c8\ub2e4.
+PeersView.statup=\uc5c5 \ud1b5\uacc4
+PeersView.statup.info=\ud53c\uc5b4 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \ucd94\uc815\uce58
+PeersView.S.info=\ucad3\uc544\ub0c4: \ub370\uc774\ud130 \uc804\ub2ec \uc18d\ub3c4\uac00 \ucda9\ubd84\ud788 \ub192\uc9c0 \uc54a\uc740 \uacbd\uc6b0, \ud53c\uc5b4\ub97c \uc790\ub3d9 \ub610\ub294 \uc218\ub3d9\uc73c\ub85c "\ucad3\uc544\ub0bc" \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+PeersView.downloadspeedoverall=\uc804\uccb4 \ub2e4\uc6b4 \uc18d\ub3c4
+PeersView.optunchoke=\uc635\uc158 \ud3ec\ud654\uc0c1\ud0dc \ud480\uae30
+PeersView.client=\ud074\ub77c\uc774\uc5b8\ud2b8
+PeersView.client.info=\ud53c\uc5b4\uac00 \uc0ac\uc6a9 \uc911\uc778 BT \ud074\ub77c\uc774\uc5b8\ud2b8 \uc720\ud615
+PeersView.menu.snubbed=\ucad3\uc544\ub0b4\uae30(&S)
+PeersView.title.short=\ud53c\uc5b4
+PeersView.title.full=\ud53c\uc5b4
+AllPeersView.title.full=\ubaa8\ub4e0 \ud53c\uc5b4
 ConfigView.section.files=\ud30c\uc77c
-ConfigView.label.usefastresume=\ube60\ub978 \ub2e4\uc2dc \uc2dc\uc791 \ubc29\uc2dd \uc4f0\uae30
-ConfigView.label.incrementalfile=\ub298\uc5b4\ub098\ub294 \ud30c\uc77c \ub9cc\ub4e4\uae30 \uc791\ub3d9 [Linux\uc5d0\uc11c FAT32\uc5d0 \ud544\uc694\ud568]
-ConfigView.label.defaultsavepath=\uae30\ubcf8 \ub370\uc774\ud130 \ud3f4\ub354\ub85c \uc800\uc7a5
-ConfigView.button.browse=\ucc3e\uc544\ubcf4\uae30...
-ConfigView.dialog.choosedefaultsavepath=\uae30\ubcf8 \uc800\uc7a5 \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
+ConfigView.label.usefastresume=\ube60\ub978 \ub2e4\uc2dc \uc2dc\uc791 \ubaa8\ub4dc \uc4f0\uae30
+ConfigView.label.incrementalfile=\uc99d\ubd84\ud615 \ud30c\uc77c \uc0dd\uc131 \ud65c\uc131\ud654 [Linux\uc5d0\uc11c FAT32 \uc0ac\uc6a9\uc744 \uc704\ud574 \ud544\uc694\ud568]
+ConfigView.label.defaultsavepath=\uae30\ubcf8 \ub370\uc774\ud130 \ud3f4\ub354\uc5d0 \uc800\uc7a5
+ConfigView.button.browse=\ucc3e\uc544\ubcf4\uae30(&B)...
+ConfigView.dialog.choosedefaultsavepath=\uae30\ubcf8 \uc800\uc7a5 \ud3f4\ub354 \uc120\ud0dd
 ConfigView.section.server=\uc5f0\uacb0
-ConfigView.section.global=\uc77c\ubc18
-ConfigView.label.disconnetseed=\ubfcc\ub9ac\ub294 \uc911 \uc528\uc557\uacfc \ub04a\uae30
-ConfigView.label.switchpriority=\ubfcc\ub9b4 \ub54c \ub0ae\uc740 \uc6b0\uc120\uad8c\uc73c\ub85c \uc800\uc808\ub85c \ubc14\uafc8
-ConfigView.label.maxdownloads=\ucd5c\ub300 \ub3d9\uc2dc \ub0b4\ub824\ubc1b\uae30 [0: \ubb34\uc81c\ud55c]
-ConfigView.label.maxdownloads.tooltip=\uc5ec\uae30\uc5d0 \uc815\ud55c \uc218\ub9cc\ud07c \ub0b4\ub824\ubc1b\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uc608\uc678\ub85c\ub294 \uc644\ub8cc\ub41c \ud1a0\ub7f0\ud2b8\uac00 \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c\uc5d0 \uc801\ud569\ud558\ub2e4\uba74 \ud65c\uc131\ud654\ub41c \ub0b4\ub824\ubc1b\uae30 \uc790\ub9ac\ub97c \ucc28\uc9c0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ConfigView.label.maxactivetorrents=\ucd5c\ub300 \ud65c\uc131 \ud1a0\ub7f0\ud2b8 [0: \ubb34\uc81c\ud55c]\n - \uc0c8\ub85c \ub0b4\ub824\ubc1b\uac70\ub098 \ubfcc\ub9b4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
-ConfigView.label.priorityExtensions=\ub2e4\uc74c \ud655\uc7a5\uc790\uc778 \ud30c\uc77c\uc744 \uc800\uc808\ub85c \uc6b0\uc120\uc2dc\ud0b4\n - \uc608: .txt;.nfo;.jpg
+ConfigView.section.global=\uc804\uc5ed
+ConfigView.label.disconnetseed=\ubc30\ud3ec \uc911\uc5d0\ub294 \ub2e4\ub978 \uc2dc\ub4dc\uc640 \uc5f0\uacb0 \ub04a\uae30
+ConfigView.label.switchpriority=\ubc30\ud3ec\ud560 \ub54c \ub0ae\uc740 \uc6b0\uc120\uad8c\uc73c\ub85c \uc790\ub3d9\uc804\ud658
+ConfigView.label.maxdownloads=\ucd5c\ub300 \ub3d9\uc2dc \ub2e4\uc6b4\ub85c\ub4dc [0: \ubb34\uc81c\ud55c]\n - \ucd5c\ub300 \ud65c\uc131 \ud1a0\ub80c\ud2b8 \uc218 \ubcf4\ub2e4 \ub192\uc744 \uc218 \uc5c6\uc74c
+ConfigView.label.maxdownloads.tooltip=\ud55c\uac00\uc9c0 \uc608\uc678 \uc0c1\ud669\ub9cc \uc81c\uc678\ud558\uace0, \ud56d\uc0c1 \uc5ec\uae30\uc5d0 \uc9c0\uc815\ud55c \uc218\uc758 \ub2e4\uc6b4\ub85c\ub4dc\ub9cc \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uc608\uc678: \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c\uacfc \uc77c\uce58\ud558\ub294 \uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8\uc5d0 \uc758\ud574 \uc808\ub300\uc801\uc73c\ub85c \ud544\uc694\ud55c \uacbd\uc6b0 \ud65c\uc131 \ub2e4\uc6b4\ub85c\ub4dc  [...]
+ConfigView.label.maxactivetorrents=\ucd5c\ub300 \ud65c\uc131 \ud1a0\ub80c\ud2b8 [0: \ubb34\uc81c\ud55c]\n - \uc124\uc815 \uac12 \uc774\uc0c1\uc73c\ub85c \uc0c8 \ud1a0\ub80c\ud2b8\ub97c \ub2e4\uc6b4\ub85c\ub4dc\ud558\uac70\ub098 \ubc30\ud3ec\ud560 \uc218 \uc5c6\uc74c
+ConfigView.label.priorityExtensions=\ub2e4\uc74c\uc758 \ud655\uc7a5\uc790\ub85c \ub41c \ud30c\uc77c\uc5d0 \ub300\ud574 \uc790\ub3d9\uc6b0\uc120\uc21c\uc704 \ubd80\uc5ec\n - \uc608: .txt,.nfo;.jpg
 ConfigView.section.transfer=\uc804\uc1a1
-ConfigView.label.maxuploads=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \ucd5c\ub300 \uae30\ubcf8 \uc62c\ub9ac\uae30 \uc790\ub9ac
-ConfigView.label.maxuploadspeed=KB/s \ucd5c\uace0 \ucd1d \uc62c\ub9ac\uae30 \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
-ConfigView.label.saveresumeinterval=\ub2e4\uc74c\ub9c8\ub2e4 \ub2e4\uc2dc \uc2dc\uc791 \ub370\uc774\ud130 \uc5c5\ub370\uc774\ud2b8
+ConfigView.label.maxuploads=\ud1a0\ub80c\ud2b8 \ubcc4 \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc2ac\ub86f \uae30\ubcf8\uac12
+ConfigView.label.maxuploadspeed=KB/s \uc804\uc5ed \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+ConfigView.label.saveresumeinterval=\ub2e4\uc2dc \uc2dc\uc791 \ub370\uc774\ud130 \uc5c5\ub370\uc774\ud2b8\ud558\uae30: \ub9e4
 ConfigView.unlimited=\ubb34\uc81c\ud55c
 ConfigView.section.display=\ub514\uc2a4\ud50c\ub808\uc774
-ConfigView.label.opendetails=\uc0c1\uc138 \uc815\ubcf4 \ud0ed \uc800\uc808\ub85c \uc5f4\ub9ac\uae30
-ConfigView.label.openbar=\ub0b4\ub824\ubc1b\uae30 \ub9c9\ub300 \uc800\uc808\ub85c \uc5f4\ub9ac\uae30
-ConfigView.label.closetotray=\uc54c\ub9bc \uc601\uc5ed\uc73c\ub85c \ucd5c\uc18c\ud654
-ConfigView.label.minimizetotray=\ucd5c\uc18c\ud654\ub97c \uc54c\ub9bc \uc601\uc5ed\uc73c\ub85c \ud569\ub2c8\ub2e4.
+ConfigView.label.opendetails=\uc138\ubd80\uc0ac\ud56d \ud0ed \uc790\ub3d9 \uc5f4\uae30
+ConfigView.label.openbar=\ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \uc790\ub3d9 \uc5f4\uae30
+ConfigView.label.use_old_speed_menus=\uc774\uc804 \uc2a4\ud0c0\uc77c\uc758 \ube60\ub978 \uba54\ub274 \uc0ac\uc6a9 [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
+ConfigView.label.closetotray=\ub2eb\uc73c\uba74 \uc2dc\uc2a4\ud15c \ud2b8\ub798\uc774\ub85c \ucd5c\uc18c\ud654
+ConfigView.label.minimizetotray=\ucd5c\uc18c\ud654 \uc2dc \uc54c\ub9bc \uc601\uc5ed\uc73c\ub85c \ucd5c\uc18c\ud654
 ConfigView.section.general=\uc77c\ubc18
 ConfigView.section.start=\uc2dc\uc791
-ConfigView.label.showsplash=\ud654\ub824\ud55c \ud654\uba74\uc744 \ubcf4\uc5ec\uc90c
-ConfigView.label.autoupdate=\uc0c8 \ubc84\uc804\uc774 \uc788\uc744 \ub54c \uc5c5\uadf8\ub808\uc774\ub4dc \ub300\ud654 \ucc3d \uc5f4\uae30
-ConfigView.label.openconsole=\uc2dc\uc791\ud560 \ub54c \ucf58\uc194 \uc5f4\uae30
-ConfigView.label.openconfig=\uc2dc\uc791\ud560 \ub54c \uc120\ud0dd\uc0ac\ud56d \uc5f4\uae30
-ConfigView.label.startminimized=\ucd5c\uc18c\ud654\ub85c \uc2dc\uc791
-ConfigView.label.ircwiki=\ub2e4\uc74c\uc744 \uc77d\uc5b4\uc8fc\uc138\uc694 http://www.azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.label.showsplash=\uc2dc\uc791 \ub85c\uace0 \ud654\uba74\uc744 \ubcf4\uc5ec\uc8fc\uae30
+ConfigView.label.autoupdate=\uc0c8 \ubc84\uc804\uc774 \uc788\uc73c\uba74 \uc5c5\uadf8\ub808\uc774\ub4dc \ub300\ud654\uc0c1\uc790 \uc5f4\uae30
+ConfigView.label.openconsole=\uc2dc\uc791 \uc2dc \ucf58\uc194 \uc5f4\uae30
+ConfigView.label.openconfig=\uc2dc\uc791 \uc2dc \uc635\uc158 \uc5f4\uae30
+ConfigView.label.startminimized=\ucd5c\uc18c\ud654 \ub41c \uc0c1\ud0dc\ub85c \uc2dc\uc791
+ConfigView.label.ircwiki=http://www.azureuswiki.com/index.php/Rules_for_IRC \ub97c \uc77d\uc5b4\ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4
 ConfigView.label.ircserver=\uc11c\ubc84
 ConfigView.label.ircchannel=\ucc44\ub110
-ConfigView.label.irclogin=\ub300\ud654\uba85
+ConfigView.label.irclogin=\ubcc4\uba85
 ConfigView.group.irctitle=IRC \uc124\uc815
-ConfigView.boolean.ircsendinfo=\uc775\uba85\uc73c\ub85c \ucc44\ub110 \uad00\ub9ac\uc790\uac00 \ub2f9\uc2e0\uc744 \ub3c4\uc6b8 \uc218 \uc788\ub3c4\ub85d \n\uc124\uc815\uc815\ubcf4\ub97c \ubcf4\ub0c5\ub2c8\ub2e4
-ConfigView.boolean.irclog=\ucc44\ub110\uc5d0\uc11c \ud65c\ub3d9\uc744 \uae30\ub85d\ud558\ub3c4\ub85d \uc791\ub3d9\ud569\ub2c8\ub2e4. (IRC_log.htm\uc5d0 \uae30\ub85d)
+ConfigView.boolean.ircsendinfo=\ucc44\ub110 \uad00\ub9ac\uc790\uac00 \ub2f9\uc2e0\uc744 \ub3c4\uc6b8 \uc218 \uc788\ub3c4\ub85d \n(\uc775\uba85\uc73c\ub85c) \uc124\uc815\uc815\ubcf4\ub97c \ubcf4\ub0bc \uc218 \uc788\uac8c \ud5c8\uc6a9
+ConfigView.boolean.irclog=\ucc44\ub110 \ud65c\ub3d9 \ub85c\uae45\uc744 \ud65c\uc131\ud654 (IRC_log.htm\uc5d0 \uae30\ub85d)
 ConfigView.section.security=\ubcf4\uc548
-ConfigView.label.password=\uc554\ud638\ub97c \uc368\uc11c Vuze ub97c \uc9c0\ud0b4\n - \uc2dc\uc791\ud560 \ub54c\uc640 \uc774\uc804 \ud06c\uae30\ub85c \ub420 \ub54c \ubb3c\uc5b4\ubcfc \uac83\uc785\ub2c8\ub2e4.
+ConfigView.label.password=\uc554\ud638\ub97c \uc368\uc11c Vuze\ub97c \ubcf4\ud638\n - \uc2dc\uc791\ud560 \ub54c\uc640 \uc6d0\ub798 \uc0c1\ud0dc\ub85c \ubcf5\uc6d0\ub420 \ub54c \ubb3c\uc5b4\ubcf4\uac8c \ub429\ub2c8\ub2e4.
 ConfigView.label.passwordconfirm=\uc554\ud638 (\ud655\uc778)
-ConfigView.label.passwordmatch=\ud65c\uc131\ud654\ub41c \uc554\ud638:
-ConfigView.label.passwordmatchnone=\uc544\ub2c8\uc624
-ConfigView.label.passwordmatchno=\uc544\ub2c8\uc624 / \uc554\ud638\uac00 \ub9de\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4
-ConfigView.label.passwordmatchyes=\uc608
+ConfigView.label.passwordmatch=\ud65c\uc131\ud654\ub41c \uc554\ud638 :
+ConfigView.label.passwordmatchnone=\uc5c6\uc74c
+ConfigView.label.passwordmatchno=\uc5c6\uc74c / \uc554\ud638\uac00 \ub9de\uc9c0 \uc54a\uc74c
+ConfigView.label.passwordmatchyes=\uc788\uc74c
 ConfigView.button.save=\uc800\uc7a5
-ConfigView.title.short=\uc120\ud0dd\uc0ac\ud56d
-ConfigView.title.full=\uc120\ud0dd\uc0ac\ud56d
-ConfigView.title.full._mac=\uc120\ud0dd\uc0ac\ud56d
+ConfigView.title.short=\uc635\uc158
+ConfigView.title.full=\uc635\uc158
+ConfigView.title.full._mac=\uc124\uc815
 ConsoleView.title.short=\ucf58\uc194
 ConsoleView.title.full=\ucf58\uc194
 FileItem.write=\uc4f0\uae30
 FileItem.read=\uc77d\uae30
 FileItem.normal=\ubcf4\ud1b5
 FileItem.high=\ub192\uc74c
-FileItem.donotdownload=\ub0b4\ub824\ubc1b\uae30\ud558\uc9c0 \uc54a\uc74c
+FileItem.donotdownload=\ub2e4\uc6b4\ub85c\ub4dc \ud558\uc9c0 \uc54a\uc74c
 FileItem.delete=\uc0ad\uc81c
 FilesView.name=\uc774\ub984
-FilesView.name.fastRename=\ube60\ub978 \uc774\ub984\ubc14\uafb8\uae30
+FilesView.name.fastRename=\ube60\ub978 \uc774\ub984 \ubc14\uafb8\uae30
 FilesView.size=\ud06c\uae30
-FilesView.done=\ub9c8\uce68
-FilesView.firstpiece=\uccab \uc870\uac01 \ubc88\ud638
+FilesView.done=\uc644\ub8cc
+FilesView.firstpiece=\uccab \uc870\uac01
 FilesView.numberofpieces=\uc870\uac01 \uc218
 FilesView.pieces=\uc870\uac01
-FilesView.mode=\ubc29\uc2dd
+FilesView.mode=\ubaa8\ub4dc
 FilesView.priority=\uc6b0\uc120\uad8c
 FilesView.menu.open=\uc5f4\uae30(&O)
 FilesView.menu.setpriority=\uc6b0\uc120\uad8c \uc9c0\uc815(&P)
 FilesView.menu.setpriority.high=\ub192\uc74c(&H)
 FilesView.menu.setpriority.normal=\ubcf4\ud1b5(&N)
-FilesView.menu.setpriority.skipped=\ub0b4\ub824\ubc1b\uae30\ud558\uc9c0 \uc54a\uc74c(&D)
+FilesView.menu.setpriority.skipped=\ub2e4\uc6b4\ub85c\ub4dc \ud558\uc9c0 \uc54a\uc74c(&D)
 FilesView.title.short=\ud30c\uc77c
 FilesView.title.full=\ud30c\uc77c
-GeneralView.section.downloaded=\ub0b4\ub824\ubc1b\uae30\ub428
+GeneralView.section.downloaded=\ub2e4\uc6b4\ub85c\ub4dc\ub428
 GeneralView.label.status.file=\ud30c\uc77c \uc0c1\ud0dc
 GeneralView.label.status.pieces=\uc870\uac01 \uc0c1\ud0dc
-GeneralView.section.availability=\uc4f8 \uc218 \uc788\uc74c
+GeneralView.section.availability=\uc720\ud6a8\uc131
 GeneralView.label.status.pieces_available=\uc870\uac01 \uc0c1\ud0dc
 GeneralView.section.transfer=\uc804\uc1a1
 GeneralView.section.info=\uc815\ubcf4
 GeneralView.title.short=\uc77c\ubc18
 GeneralView.title.full=\uc77c\ubc18
-GeneralView.label.timeelapsed=\uc9c0\ub09c \uc2dc\uac04: 
-GeneralView.label.remaining=\ub0a8\uc74c: 
-GeneralView.label.downloaded=\ub0b4\ub824\ubc1b\uae30: 
-GeneralView.label.downloadspeed=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4: 
-GeneralView.label.maxuploads=\uc62c\ub9ac\uae30 \uc790\ub9ac: 
-GeneralView.label.maxuploads.tooltip=\uc8fc\uc5b4\uc9c4 \uc2dc\uac04\uc5d0 \ub9c9\uc9c0 \uc54a\uc744 \ucd5c\ub300 \ub3d9\ub8cc \uc218
-GeneralView.label.uploaded=\uc62c\ub9ac\uae30: 
-GeneralView.label.uploadspeed=\uc62c\ub9ac\uae30 \uc18d\ub3c4: 
-GeneralView.label.seeds=\uc528\uc557: 
-GeneralView.label.peers=\ub3d9\ub8cc: 
-GeneralView.label.completed=\uc644\ub8cc : 
-GeneralView.label.totalspeed=\ub5bc \uc18d\ub3c4: 
-GeneralView.label.totalspeed.tooltip=\ub2f9\uc2e0\uacfc \uc5f0\uacb0\ub41c \ubaa8\ub4e0 \uc811\uc18d \ucef4\ud4e8\ud130\uc758 \ucd1d (\uadf8\ub9ac\uace0 \ud3c9\uade0) \uc18d\ub3c4
+GeneralView.label.timeelapsed=\uacbd\uacfc \uc2dc\uac04 :
+GeneralView.label.remaining=\ub0a8\uc74c:
+GeneralView.label.downloaded=\ub2e4\uc6b4\ub85c\ub4dc\ub428 :
+GeneralView.label.downloadspeed=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 :
+GeneralView.label.maxuploads=\uc5c5\ub85c\ub4dc \uc2ac\ub86f :
+GeneralView.label.maxuploads.tooltip=\ud3ec\ud654\ub418\uc9c0 \uc54a\uc740 \uac83\uc73c\ub85c \uac04\uc8fc\ud560 \ucd5c\ub300 \ud53c\uc5b4 \uc218 \uc785\ub2c8\ub2e4.
+GeneralView.label.uploaded=\uc5c5\ub85c\ub4dc\ub428 :
+GeneralView.label.uploadspeed=\uc5c5\ub85c\ub4dc \uc18d\ub3c4 :
+GeneralView.label.seeds=\uc2dc\ub4dc :
+GeneralView.label.peers=\ud53c\uc5b4 :
+GeneralView.label.completed=\uc644\ub8cc\ub428 :
+GeneralView.label.totalspeed=\uc2a4\uc6dc \uc18d\ub3c4 :
+GeneralView.label.totalspeed.tooltip=\uc5f0\uacb0\ub41c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc804\uccb4 (\uadf8\ub9ac\uace0 \ud3c9\uade0) \uc18d\ub3c4\uc785\ub2c8\ub2e4.
 GeneralView.label.averagespeed=\ud3c9\uade0
-GeneralView.label.filename=\uc774\ub984: 
-GeneralView.label.totalsize=\ucd1d \ud06c\uae30: 
-GeneralView.label.savein=\uc800\uc7a5 \uc704\uce58: 
-GeneralView.label.hash=\ud574\uc2dc: 
-GeneralView.label.numberofpieces=\uc870\uac01 \uc218: 
-GeneralView.label.size=\ud06c\uae30: 
-GeneralView.label.tracker=\ub354\ub4ec\uc774 \uc0c1\ud0dc: 
-GeneralView.label.updatein=\uc5c5\ub370\uc774\ud2b8 \ub0a8\uc740 \uc2dc\uac04: 
-GeneralView.label.trackerurl=\ub354\ub4ec\uc774 \uc8fc\uc18c: 
-GeneralView.label.trackerurlupdate=\ub354\ub4ec\uc774 \uc5c5\ub370\uc774\ud2b8
-GeneralView.label.comment=\ud1a0\ub7f0\ud2b8 \ub367\ub9d0: 
-GeneralView.label.user_comment=\uc0ac\uc6a9\uc790 \ub367\ub9d0:
+GeneralView.label.filename=\uc774\ub984:
+GeneralView.label.totalsize=\uc804\uccb4 \ud06c\uae30 :
+GeneralView.label.savein=\uc800\uc7a5 \uc704\uce58:
+GeneralView.label.hash=\ud574\uc2dc:
+GeneralView.label.numberofpieces=\uc870\uac01 \uc218 :
+GeneralView.label.size=\ud06c\uae30 :
+GeneralView.label.tracker=\ud2b8\ub798\ucee4 \uc0c1\ud0dc :
+GeneralView.label.updatein=\ub2e4\uc74c \uc5c5\ub370\uc774\ud2b8 :
+GeneralView.label.trackerurl=\ud2b8\ub798\ucee4 URL :
+GeneralView.label.trackerurlupdate=\ud2b8\ub798\ucee4 \uc5c5\ub370\uc774\ud2b8
+GeneralView.label.comment=\ud1a0\ub80c\ud2b8 \uc8fc\uc11d :
+GeneralView.label.user_comment=\uc0ac\uc6a9\uc790 \uc8fc\uc11d :
 GeneralView.label.status=\uc0c1\ud0dc :
-ManagerItem.waiting=\uae30\ub2e4\ub9ac\uace0 \uc788\uc74c
-ManagerItem.allocating=\ud560\ub2f9\ud558\uace0 \uc788\uc74c
-ManagerItem.checking=\uac80\uc0ac\ud558\uace0 \uc788\uc74c
-ManagerItem.ready=\uc900\ube44
-ManagerItem.downloading=\ub0b4\ub824\ubc1b\uae30 \uc911
-ManagerItem.seeding=\ubfcc\ub9ac\uace0 \uc788\uc74c
-ManagerItem.stopped=\uba48\ucda4
+ManagerItem.waiting=\uae30\ub2e4\ub9ac\ub294 \uc911
+ManagerItem.allocating=\ud560\ub2f9 \uc911
+ManagerItem.checking=\uac80\uc0ac \uc911
+ManagerItem.ready=\ub2e4\ub978 \ud1a0\ub80c\ud2b8\uac00 \ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac00\uae30\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911
+ManagerItem.downloading=\ub2e4\uc6b4\ub85c\ub4dc \uc911
+ManagerItem.seeding=\ubc30\ud3ec \uc911
+ManagerItem.stopped=\uc815\uc9c0\ub428
 ManagerItem.error=\uc624\ub958
 ManagerItem.high=\ub192\uc74c
 ManagerItem.low=\ub0ae\uc74c
-MinimizedWindow.name=\ud30c\uc77c \uc774\ub984:
-MinimizedWindow.all_transfers=Vuze \uad50\ud658
-PiecesView.#=\ubc88\ud638
+MinimizedWindow.name=\uc774\ub984:
+MinimizedWindow.all_transfers=Vuze \uc804\uc1a1
 PiecesView.size=\ud06c\uae30
-PiecesView.numberofblocks=\ud1a0\ub9c9 \uc218
-PiecesView.blocks=\ud1a0\ub9c9
-PiecesView.completed=\ub9c8\uce68
-PiecesView.availability=\uc4f8 \uc218 \uc788\uc74c
-PiecesView.reservedby=\ub9c8\ub828
-PiecesView.writers=\ud1a0\ub9c9 \ubcf4\ub0b4\ub294 \uc0ac\ub78c
+PiecesView.numberofblocks=\ube14\ub85d\uc758 \uc218
+PiecesView.blocks=\ube14\ub85d
+PiecesView.completed=\uc644\ub8cc
+PiecesView.availability=\uc720\ud6a8\uc131
+PiecesView.reservedby=\uc608\uc57d\ub428
+PiecesView.writers=\ube14\ub85d \uae30\uc5ec\uc790
 PiecesView.title.short=\uc870\uac01
 PiecesView.title.full=\uc870\uac01
-SystemTray.tooltip.seeding=%1 \uac1c \ubfcc\ub9ac\uace0 \uc788\uc74c, 
-SystemTray.tooltip.downloading=%1 \uac1c \ub0b4\ub824\ubc1b\uace0 \uc788\uc74c, 
+SystemTray.tooltip.seeding=%1 \ubc30\ud3ec \uc911,
+SystemTray.tooltip.downloading=%1 \ub2e4\uc6b4\ub85c\ub4dc \uc911,
 DownloadManager.error.filenotfound=\ud30c\uc77c\uc744 \ucc3e\uc9c0 \ubabb\ud568
-DownloadManager.error.fileempty=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc774 \ube44\uc5b4\uc788\uc74c
-DownloadManager.error.filetoobig=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc774 \ub108\ubb34 \ud07c
-DownloadManager.error.filewithouttorrentinfo=\ud30c\uc77c\uc5d0\uc11c \uc544\ubb34 \ud1a0\ub7f0\ud2b8 \uc815\ubcf4\ub3c4 \ucc3e\uc9c0 \ubabb\ud568
+DownloadManager.error.fileempty=\ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc774 \ube44\uc5b4\uc788\uc74c
+DownloadManager.error.filetoobig=\ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc774 \ub108\ubb34 \ud07c
+DownloadManager.error.filewithouttorrentinfo=\ud30c\uc77c\uc5d0 \ud1a0\ub80c\ud2b8 \uc815\ubcf4 \uc5c6\uc74c
 DownloadManager.error.unsupportedencoding=\uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uc778\ucf54\ub529
 DownloadManager.error.ioerror=\uc785\ucd9c\ub825 \uc624\ub958
-DownloadManager.error.sha1=\uadf8\ub7f0 \uc5f0\uc0b0 \uc5c6\uc74c(SHA1) \uc624\ub958
+DownloadManager.error.sha1=\uc54c\uace0\ub9ac\uc998 (SHA1) \uc5c6\uc74c \uc624\ub958
 PeerManager.status.offline=\uc5f0\uacb0 \uc624\ub958
-PeerManager.status.ok=\ud655\uc778
-PeerManager.status.checking=\uac80\uc0ac\ud558\uace0 \uc788\uc74c
+PeerManager.status.ok=\uc815\uc0c1
+PeerManager.status.checking=\uac80\uc0ac \uc911
 PeerManager.status.finished=\ub9c8\uce68
-PeerManager.status.finishedin=\ub9c8\uce68
+PeerManager.status.finishedin=\ub9c8\uce68:
 MainWindow.upgrade.assistant=\uc5c5\uadf8\ub808\uc774\ub4dc \ub3c4\uc6b0\ubbf8
-MainWindow.upgrade.newerversion=\ub0b4\ub824\ubc1b\uc744 \uc218 \uc788\ub294 \uc0c8 Vuze \ubc84\uc804\uc774 \uc788\uc2b5\ub2c8\ub2e4.
-MainWindow.upgrade.explanation=\uc774 \ub3c4\uc6b0\ubbf8\ub294 \ub2f9\uc2e0\uc758 Vuze \ud3f4\ub354\uc5d0 \uc0c8 \ubc84\uc804\uc744 \ub0b4\ub824\ubc1b\uace0 \ub098\uc11c Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud560 \uac83\uc785\ub2c8\ub2e4.
-MainWindow.upgrade.explanation.manual=Vuze\uc744 \ub2eb\uace0 \uc0c8 \ubc84\uc804\uc744 \ub0b4\ub824\ubc1b\uace0\uc11c Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud558\uc5ec \uc190\uc218 \uc5c5\ub370\uc774\ud2b8\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-MainWindow.upgrade.step1=1 \ub2e8\uacc4: \uc0c8 \ubc84\uc804\uc744 \ub0b4\ub824\ubc1b\uc73c\uc138\uc694.
-MainWindow.upgrade.step2=2 \ub2e8\uacc4: \uc774 \ubc84\uc804\uc744 \ub2eb\uace0 \uc0c8 \ubc84\uc804\uc758 Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791 \ud558\uc2ed\uc2dc\uc694.
-MainWindow.upgrade.hint1=\uadc0\ub754:\t\ub9c8\uce68\uc744 \ub20c\ub7ec \ubaa8\ub4e0 \uac83\uc774 \uc800\uc808\ub85c \ub418\uac8c \ud568
-MainWindow.upgrade.hint2=\uadc0\ub754:\tVuze\ub97c \ub098\uc911\uc5d0 \ub2eb\uc73c\ub824\uba74, \ucde8\uc18c\ub97c \ub204\ub974\uace0 \ub098\uc11c\n\t\ub2eb\ud78c \ub2e4\uc74c\uc5d0 Azureus2-new.jar\uc5d0\uc11c Azureus2.jar\ub85c \uc774\ub984\uc744 \ubc14\uafb8\uc2ed\uc2dc\uc694.
-MainWindow.upgrade.error.downloading.hint=\uc624\ub958:\t\uc0c8 \ubc84\uc804\uc744 \ub0b4\ub824\ubc1b\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.  \uc190\uc218 \uc5c5\ub370\uc774\ud2b8\ud558\uc2ed\uc2dc\uc694.
-MainWindow.upgrade.section.info=\uc0c8 \ubc84\uc804 \uc4f8 \uc218 \uc788\uc74c
-MainWindow.upgrade.section.manual=\uc190\uc218 \uc5c5\ub370\uc774\ud2b8
+MainWindow.upgrade.newerversion=\ub2e4\uc6b4\ub85c\ub4dc \ud560 \uc218 \uc788\ub294 Vuze\uc758 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc774 \uc788\uc74c
+MainWindow.upgrade.explanation=\uc774 \ub3c4\uc6b0\ubbf8\ub294 Vuze \ud3f4\ub354\uc5d0 \uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ub85c\ub4dc \ud558\uace0 Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791 \ud569\ub2c8\ub2e4.
+MainWindow.upgrade.explanation.manual=Vuze\ub97c \ub2eb\uace0 \uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ub85c\ub4dc \ubc1b\uc740 \ub2e4\uc74c Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud558\ub294 \uac83\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ub97c \uc218\ub3d9\uc73c\ub85c \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+MainWindow.upgrade.step1=\ub2e8\uacc4 1: \uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ub85c\ub4dc
+MainWindow.upgrade.step2=\ub2e8\uacc4 2: \uc774 \ubc84\uc804\uc744 \ub2eb\uace0 \uc0c8 \ubc84\uc804\uc758 Vuze\ub85c \ub2e4\uc2dc \uc2dc\uc791
+MainWindow.upgrade.hint1=\ud78c\ud2b8:\t\ub9c8\uce68\uc744 \ub204\ub974\uba74 \ubaa8\ub450 \uc790\ub3d9\uc73c\ub85c \uc9c4\ud589
+MainWindow.upgrade.hint2=\ud78c\ud2b8:\tVuze\ub97c \ub098\uc911\uc5d0 \ub2eb\uc73c\ub824\uba74, \ucde8\uc18c\ub97c \ub204\ub974\uace0 \ub098\uc11c\n\t\ub2eb\ud78c \ub2e4\uc74c\uc5d0 Azureus2-new.jar\uc5d0\uc11c Azureus2.jar\ub85c \uc774\ub984 \ubc14\uafb8\uae30
+MainWindow.upgrade.error.downloading.hint=\uc624\ub958:\t\t\uc0c8 \ubc84\uc804\uc744 \ub2e4\uc6b4\ub85c\ub4dc \ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc218\ub3d9\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ubc14\ub78d\ub2c8\ub2e4.
+MainWindow.upgrade.section.info=\uc0c8 \ubc84\uc804\uc774 \uc0ac\uc6a9 \uac00\ub2a5\ud568
+MainWindow.upgrade.section.manual=\uc218\ub3d9 \uc5c5\ub370\uc774\ud2b8
 MainWindow.upgrade.section.automatic=\uc790\ub3d9 \uc5c5\ub370\uc774\ud2b8
-MainWindow.upgrade.tooltip.progressbar=\ub0b4\ub824\ubc1b\uae30 \uc9c4\ud589\uc744 \uc5ec\uae30 \ubcf4\uc785\ub2c8\ub2e4.
+MainWindow.upgrade.tooltip.progressbar=\ub2e4\uc6b4\ub85c\ub4dc \uc9c4\ud589\uc774 \uc5ec\uae30\uc5d0 \ud45c\uc2dc \ub429\ub2c8\ub2e4
 Button.next=\ub2e4\uc74c
 Button.finish=\ub9c8\uce68
-Button.cancel=\ucde8\uc18c &C
-LocaleUtil.title=\uc778\ucf54\ub529 \uace0\ub974\uae30
-LocaleUtil.section.chooseencoding=\ud30c\uc77c \uc774\ub984\uc5d0 \ub9de\ub294 \uc778\ucf54\ub529\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-LocaleUtil.label.chooseencoding=\uac00\uc7a5 \uc798 \uc5b4\uc6b8\ub9ac\ub294 \uc778\ucf54\ub529\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-LocaleUtil.label.hint.doubleclick=\uadc0\ub754: \uc904\uc5d0 \ub354\ube14 \ud074\ub9ad\ud558\uc5ec\uc11c \uc778\ucf54\ub529\uc744 \uace0\ub974\uace0 \uba54\uc138\uc9c0 \uc0c1\uc790\ub97c \ub2eb\uc2b5\ub2c8\ub2e4.
-LocaleUtil.label.checkbox.rememberdecision=\ub0a8\uc740 \ud30c\uc77c \uc774\ub984\uc744 \uc78a\uc9c0 \uc54a\uae30\ub85c \uacb0\uc815
+Button.cancel=\ucde8\uc18c(&C)
+LocaleUtil.title=\uc778\ucf54\ub529 \uc120\ud0dd
+LocaleUtil.section.chooseencoding=\ud30c\uc77c \uc774\ub984\uc5d0 \ub300\ud55c \uc778\ucf54\ub529\uc744 \uc120\ud0dd
+LocaleUtil.label.chooseencoding=\uac00\uc7a5 \uc798 \uc77c\uce58\ud558\ub294 \uc778\ucf54\ub529\uc744 \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
+LocaleUtil.label.hint.doubleclick=\ud78c\ud2b8: \ud589\uc744 \ub354\ube14\ud074\ub9ad\ud558\uba74 \uc778\ucf54\ub529\uc774 \uc120\ud0dd\ub418\uace0 \ub300\ud654\uc0c1\uc790\uac00 \ub2eb\ud799\ub2c8\ub2e4
+LocaleUtil.label.checkbox.rememberdecision=\ub098\uba38\uc9c0 \ud30c\uc77c \uc774\ub984\uc5d0 \ub300\ud574 \uacb0\uc815 \uc0ac\ud56d \uae30\uc5b5
 LocaleUtil.column.encoding=\uc778\ucf54\ub529
-IrcClient.copyright=PircBot Java IRC API\ub97c \uc4f0\uace0 \uc788\uc74c - http://www.jibble.org/pircbot.php
-IrcClient.connecting=\ub2e4\uc74c\uc73c\ub85c \uc5f0\uacb0\ud558\uace0 \uc788\uc74c
+IrcClient.copyright=PircBot Java IRC API \uc0ac\uc6a9 \uc911 - http://www.jibble.org/pircbot.php
+IrcClient.connecting=\ub2e4\uc74c\uc73c\ub85c \uc5f0\uacb0 \uc911
 IrcClient.connected=\ub2e4\uc74c\uc73c\ub85c \uc5f0\uacb0\ub428
 IrcClient.joining=\ucc38\uac00\ud558\uace0 \uc788\uc74c
 IrcClient.channel=\ucc44\ub110
@@ -301,419 +300,424 @@ IrcClient.error=\uc624\ub958
 IrcClient.hasjoined=\ucc38\uac00\ud568
 IrcClient.haskicked=\ucad3\uaca8\ub0a8
 IrcClient.hasleft=\ub098\uac10
-IrcClient.nowknown=\ub2e4\uc74c\ucc98\ub7fc \uc9c0\uae08 \uc54c\ub824\uc9d0
-IrcClient.topicforchannel=\ucc44\ub110\uc758 \uc774\uc57c\uae43\uac70\ub9ac
-IrcClient.disconnected=\ub2e4\uc74c\uc5d0\uc11c \uc5f0\uacb0\uc774 \ub04a\uae40
-IrcClient.noNick=\uc544\ubb34 \ub300\ud654\uba85\ub3c4 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc74c. \uba54\ub274 \ubaa8\uc74c\uc5d0\uc11c '\uc120\ud0dd\uc0ac\ud56d' \uba54\ub274\ub85c \uac00\uc2ed\uc2dc\uc694.
-IrcView.actionnotsupported=\uc774 \ub3d9\uc791\uc740 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+IrcClient.nowknown=\ub294 \uc774\uc81c\ubd80\ud130
+IrcClient.topicforchannel=\ucc44\ub110\uc758 \uc8fc\uc81c
+IrcClient.disconnected=\ub2e4\uc74c\uc73c\ub85c\ubd80\ud130 \uc5f0\uacb0 \ub04a\uae40
+IrcClient.noNick=\ub300\ud654\uba85\uc774 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. '\uc635\uc158' \ubcf4\uae30\ub85c \uac00\uc2ed\uc2dc\uc624
+IrcView.actionnotsupported=\uc774 \ub3d9\uc791\uc740 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc74c
 IrcView.clientsconnected=\uc0ac\uc6a9\uc790
 IrcView.privateto=\ubc1b\ub294 \uc774
 IrcView.privatefrom=\ubcf4\ub0b8 \uc774
 IrcView.noticefrom=\uc54c\ub9bc:
-IrcView.errormsg=/msg\uc5d0\uc11c \uc798\ubabb\ub41c \ubb38\ubc95: /msg \uc0ac\uc6a9\uc790 \uae00
-IrcView.help=\uc815\ud655\ud55c \uba85\ub839\uc5b4\ub4e4\uc740:\n . /help: \uc774 \uba54\uc138\uc9c0\ub97c \ubcf4\uc784\n . /nick | /name: \ub300\ud654\uba85\uc744 \ubc14\uafc8\n . /me action: \ub3d9\uc791\uc744 \ubcf4\ub0c4\n . /msg nick message: <nick>\uc5d0\uac8c \uadd3\uc18d\ub9d0\uc744 \ubcf4\ub0c4\n . /r message: \ub9c8\uc9c0\ub9c9 \uadd3\uc18d\ub9d0\uc5d0 \ub2f5\ud568\n . /join #channel: \uc9c0\uae08\uc758 \ucc44\ub110\uc744 \ubc14\uafc8
+IrcView.errormsg=\uc798\ubabb\ub41c /msg \uba85\ub839: /msg <\uc0ac\uc6a9\uc790> <\ud14d\uc2a4\ud2b8>
+IrcView.help=\uc720\ud6a8\ud55c \uba85\ub839\uc740 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4:\n . /help : \uc774 \uba54\uc2dc\uc9c0 \ud45c\uc2dc\n . /nick | /name : \uc0ac\uc6a9\uc790 \uc774\ub984 \ubcc0\uacbd \n . /me action : \ub3d9\uc791 \ubcf4\ub0b4\uae30 \n . /msg <nick> message : \ube44\uacf5\uac1c \uba54\uc2dc\uc9c0\ub97c <nick>\uc5d0\uac8c \ubcf4\ub0b4\uae30 \n . /r message : \ucd5c\uadfc \ube44\uacf5\uac1c \uba54\uc2dc\uc9c0\uc5d0 \ub2f5\uc7a5\n . /join #channelB (\ud074\ub9ad [...]
 PasswordWindow.title=Vuze\uac00 \uc7a0\uacbc\uc74c
-PasswordWindow.passwordprotected=Vuze\uac00 \uc554\ud638\ub85c \ub9c9\ud614\uc2b5\ub2c8\ub2e4.\nVuze \ucc3d\uc744 \ubcf4\ub824\uba74 \uc5ec\uae30\uc5d0 \uc554\ud638\ub97c \uc368\ub123\uc73c\uc2ed\uc2dc\uc694.:
-Button.ok=\ud655\uc778 &O
-TrackerChangerWindow.title=\ub354\ub4ec\uc774 \ub354\ud558\uae30
-TrackerChangerWindow.newtracker=\uc0c8 \ub354\ub4ec\uc774 \uc8fc\uc18c\ub97c \uc368\ub123\uc73c\uc2ed\uc2dc\uc694.
+PasswordWindow.passwordprotected=Vuze\uac00 \uc554\ud638\ub85c \ubcf4\ud638\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.\nVuze \ucc3d\uc744 \ubcf4\ub824\uba74 \uc554\ud638\ub97c \uc785\ub825\ud558\uc2ed\uc2dc\uc624 :
+Button.ok=\ud655\uc778(&O)
 PeersView.discarded=\ubc84\ub824\uc9d0
-PeersView.discarded.info=\ub2f9\uc2e0\uc5d0\uac8c \ud544\uc694\ud558\uc9c0 \uc54a\uc558\ub354\ub77c\ub3c4 \uc5b4\ub5bb\uac8c \ud558\ub4e0\uc9c0 \ud574\uc11c \ubc1b\uc740 \ub370\uc774\ud130\uc785\ub2c8\ub2e4. \uadf8\ub798\uc11c \uadf8 \ub370\uc774\ud130\ub97c \uc9c0\uc6e0\uc2b5\ub2c8\ub2e4.
+PeersView.discarded.info=\ud544\uc694\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uc5b4\ub5bb\uac8c\ub4e0 \uc218\uc2e0\ub41c \ub370\uc774\ud130 \uc774\ubbc0\ub85c \uc81c\uac70\ud588\uc2b5\ub2c8\ub2e4.
 discarded=\ubc84\ub824\uc9d0
-MyTorrentsView.#=\ubc88\ud638
-MyTorrentsView.menu.move=\uc62e\uae30\uae30(&M)
+MyTorrentsView.menu.move=\uc774\ub3d9(&M)
 MyTorrentsView.menu.moveUp=\uc704\ub85c(&U)
 MyTorrentsView.menu.moveDown=\uc544\ub798\ub85c(&D)
-GeneralView.label.hashfails=\ud574\uc2dc\ud558\uc9c0 \ubabb\ud568: 
-GeneralView.label.shareRatio=\uacf5\uc720 \ube44: 
-ConfigView.section.downloadManagement=\ub0b4\ub824\ubc1b\uae30 \uad00\ub9ac
-ConfigView.label.startRatioPeers=\ub2e4\uc74c \ub3d9\ub8cc\uc5d0 1 \uc528\uc557\ubcf4\ub2e4 \uc801\uc73c\uba74 \ubfcc\ub9ac\uae30 \uc2dc\uc791
-ConfigView.text.neverStop=\uacb0\ucf54 \uba48\ucd94\uc9c0 \uc54a\uc74c
-ConfigView.text.neverStart=\uacb0\ucf54 \uc2dc\uc791\ud558\uc9c0 \uc54a\uc74c
-ConfigView.text.peers=\ub3d9\ub8cc
-ConfigView.label.checkOncompletion=\ub0b4\ub824\ubc1b\uae30 \uc644\ub8cc\ub418\uba74 \uc870\uac01\ub4e4\uc744 \ub2e4\uc2dc \uac80\uc0ac
-wizard.title=\ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4\uae30
+GeneralView.label.hashfails=\ud574\uc2dc \uc2e4\ud328 :
+GeneralView.label.shareRatio=\uacf5\uc720 \ube44\uc728 :
+ConfigView.section.downloadManagement=\ub2e4\uc6b4\ub85c\ub4dc \uad00\ub9ac
+ConfigView.label.startRatioPeers=\ub2e4\uc74c \uac12\uc5d0 \ub300\ud574 1\ubcf4\ub2e4 \uc801\uc740 \uc2dc\ub4dc\uac00 \uc788\uc744 \ub54c \ubc30\ud3ec \uc2dc\uc791
+ConfigView.text.neverStop=\uc815\uc9c0\ud558\uc9c0 \uc54a\uc74c
+ConfigView.text.neverStart=\uc2dc\uc791\ud558\uc9c0 \uc54a\uc74c
+ConfigView.text.peers=\ud53c\uc5b4
+ConfigView.label.checkOncompletion=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub418\uba74 \uc870\uac01 \ub2e4\uc2dc \uac80\uc0ac
+wizard.title=\ud1a0\ub80c\ud2b8 \ub9cc\ub4e4\uae30
 wizard.previous=< \ub4a4\ub85c
 wizard.next=\ub2e4\uc74c >
 wizard.finish=\ub9c8\uce68
-wizard.mode=\ub354\ub4ec\uc774 / \ubc29\uc2dd
-wizard.tracker=\ub354\ub4ec\uc774:
-wizard.invalidurl=\uc774 \uc8fc\uc18c\ub294 \ub9de\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
-wizard.singlefile=\ud55c \uac1c \ud30c\uc77c
-wizard.singlefile.help=\ud55c \uac1c \ud30c\uc77c\ub85c \ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4\uae30
-wizard.directory=\ud3f4\ub354
-wizard.directory.help=\ud3f4\ub354\ub85c \ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4\uae30
-wizard.choosefile=\ud30c\uc77c \uace0\ub974\uae30
-wizard.file=\ud30c\uc77c:
+wizard.mode=\ud2b8\ub798\ucee4 / \ubaa8\ub4dc
+wizard.tracker=\ud2b8\ub798\ucee4:
+wizard.invalidurl=\uc774 URL\uc740 \uc62c\ubc14\ub974\uc9c0 \uc54a\uc74c
+wizard.singlefile=\ub2e8\uc77c \ud30c\uc77c
+wizard.singlefile.help=\ub2e8\uc77c \ud30c\uc77c\ub85c\ubd80\ud130 \ud1a0\ub80c\ud2b8 \uc0dd\uc131
+wizard.directory=\ub514\ub809\ud130\ub9ac
+wizard.directory.help=\ub514\ub809\ud130\ub9ac\ub85c\ubd80\ud130 \ud1a0\ub80c\ud2b8 \uc0dd\uc131
+wizard.choosefile=\ud30c\uc77c \uc120\ud0dd
+wizard.file=\ud30c\uc77c :
 wizard.browse=\ucc3e\uc544\ubcf4\uae30...
-wizard.choosedirectory=\ud3f4\ub354 \uace0\ub974\uae30
-wizard.invalidfile=\uc798\ubabb\ub41c \ud30c\uc77c
-wizard.invaliddirectory=\uc798\ubabb\ub41c \ud3f4\ub354
-wizard.torrentFile=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c
-wizard.choosetorrent=\ub9cc\ub4e4 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
+wizard.choosedirectory=\ub514\ub809\ud1a0\ub9ac \uc120\ud0dd
+wizard.invalidfile=\uc798\ubabb\ub41c \ud30c\uc77c!
+wizard.invaliddirectory=\uc798\ubabb\ub41c \ub514\ub809\ud130\ub9ac!
+wizard.torrentFile=\ud1a0\ub80c\ud2b8 \ud30c\uc77c
+wizard.choosetorrent=\uc0dd\uc131\ud560 \ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc744 \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
 wizard.information=\uc815\ubcf4
-wizard.notimplemented=\uc791\uc5c5 \uc9c4\ud589\uc911
-wizard.progresstitle=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \ub9cc\ub4e4\uace0 \uc788\uc74c
-wizard.savingfile=\ud30c\uc77c \uc800\uc7a5...
-wizard.filesaved=\ud30c\uc77c \uc800\uc7a5\ud588\uc2b5\ub2c8\ub2e4.
+wizard.notimplemented=\uc544\uc9c1 \uad6c\ud604\ub418\uc9c0 \uc54a\uc74c
+wizard.progresstitle=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc0dd\uc131 \uc911
+wizard.savingfile=\ud30c\uc77c \uc800\uc7a5 \uc911...
+wizard.filesaved=\ud30c\uc77c\uc774 \uc800\uc7a5\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
 wizard.close=\ub2eb\uae30
-Torrent.create.progress.piecelength=\uc870\uac01 \uae38\uc774: 
-Torrent.create.progress.piececount=\uc870\uac01 \uc218: 
-Torrent.create.progress.totalfilesize=\ucd1d \ud30c\uc77c \ud06c\uae30: 
-Torrent.create.progress.totalfilecount=\ucd1d \ud30c\uc77c \uc218: 
+Torrent.create.progress.piecelength=\uc870\uac01 \uae38\uc774:
+Torrent.create.progress.piececount=\uc870\uac01 \uc218:
+Torrent.create.progress.totalfilesize=\ucd1d \ud30c\uc77c \ud06c\uae30:
+Torrent.create.progress.totalfilecount=\ucd1d \ud30c\uc77c \uc218:
 Torrent.create.progress.parsingfiles=\ud30c\uc77c \ubd84\uc11d\ud558\uace0 \uc788\uc74c
 Torrent.create.progress.hashing=\ud30c\uc77c \ud574\uc2dc\ud558\uace0 \uc788\uc74c
-MainWindow.upgrade.downloadingfrom=\ub2e4\uc74c\uc5d0\uc11c \ub0b4\ub824\ubc1b\uace0 \uc788\uc74c:
+MainWindow.upgrade.downloadingfrom=\ub2e4\uc6b4\ub85c\ub4dc \uc704\uce58 :
 MainWindow.menu.view.ipFilter=IP \ud544\ud130(&I)
 ConfigView.section.ipfilter=IP \ud544\ud130
 ConfigView.section.ipfilter.description=\uc124\uba85
-ConfigView.section.ipfilter.start=\ucc98\uc74c IP
-ConfigView.section.ipfilter.end=\ub9c8\uc9c0\ub9c9 IP
-ConfigView.section.ipfilter.add=\ub354\ud558\uae30
-ConfigView.section.ipfilter.remove=\uc9c0\uc6b0\uae30
+ConfigView.section.ipfilter.start=\uc2dc\uc791 IP
+ConfigView.section.ipfilter.end=\ub05d IP
+ConfigView.section.ipfilter.add=\ucd94\uac00
+ConfigView.section.ipfilter.remove=\uc81c\uac70
 ConfigView.section.ipfilter.edit=\ud3b8\uc9d1
 ConfigView.section.ipfilter.save=\uc800\uc7a5
 ConfigView.section.ipfilter.editFilter=\ud544\ud130 \ud3b8\uc9d1
-ConfigView.section.ipfilter.enable=\uc791\ub3d9
+ConfigView.section.ipfilter.enable=\ud65c\uc131\ud654
 PeersView.menu.close=\ub2eb\uae30(&C)
-seedmore.title=\ud1a0\ub7f0\ud2b8\uac00 \uadf8\ub2e4\uc9c0 \ucda9\ubd84\ud558\uc9c0 \uc54a\uac8c \ubfcc\ub824\uc84c\uc2b5\ub2c8\ub2e4.
-seedmore.shareratio=\uc774 \ud1a0\ub7f0\ud2b8\uc5d0 \ub300\ud55c \ub2f9\uc2e0\uc758 \uacf5\uc720 \ube44\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4. - 
-seedmore.uploadmore=100%\ubcf4\ub2e4 \ub0ae\uc740 \uacf5\uc720 \ube44\ub85c \ub9c8\uce58\ub294 \uac83\uc740 bittorrent \ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \uadf8\ub2e4\uc9c0 \uc88b\uc740 \uc0dd\uac01\uc774 \uc544\ub2d9\ub2c8\ub2e4.\n\uc774 \ud1a0\ub7f0\ud2b8\ub97c \uc870\uae08 \ub354 \ubfcc\ub824\uc57c \ud569\ub2c8\ub2e4.\n\uc815\ub9d0 \uacc4\uc18d\ud558\uaca0\uc2b5\ub2c8\uae4c?
-ConfigView.label.showpopuponclose=1\ubcf4\ub2e4 \ub0ae\uc740 \uacf5\uc720 \ube44\uc778 \ucc44\ub85c \ubfcc\ub9ac\uae30\ub97c \uba48\ucd9c \ub54c \ud655\uc778 \uba54\uc138\uc9c0 \uc0c1\uc790\ub97c \ubcf4\uc5ec\uc90c
-ConfigView.label.startNumSeeds=\n\ub2e4\uc74c\ubcf4\ub2e4 \uc801\uc73c\uba74 \ubfcc\ub9ac\uae30 \uc2dc\uc791\n - \ub2e4\ub978 \ubaa8\ub4e0 \uaddc\uce59\ub4e4\uc744 \ubb34\uc2dc
-ConfigView.label.seeds=\uc528\uc557
-ConfigView.section.seeding=\ubfcc\ub9ac\uae30
-MyTorrentsView.menu.removeand=\uc9c0\uc6b0\uace0 \ub098\uc11c(&V)
-MyTorrentsView.menu.removeand.deletetorrent=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc9c0\uc6b0\uae30(&T)
-MyTorrentsView.menu.removeand.deletedata=\ub370\uc774\ud130 \uc9c0\uc6b0\uae30(&D)
-MyTorrentsView.menu.removeand.deleteboth=\ub458 \ub2e4 \uc9c0\uc6b0\uae30(&B)
-deletedata.title=!!! \uacbd\uace0 !!!
-deletedata.message1=\ub2e4\uc74c\uc5d0\uc11c \ub370\uc774\ud130\ub97c \uc9c0\uae08 \uc9c0\uc6b0\ub824\uace0 \ud569\ub2c8\ub2e4:\n
-deletedata.noprompt=\ub2e4\uc2dc \ud45c\uc2dc\ud558\uc9c0 \uc54a\uc74c
-MainWindow.menu.file.configure=\uad6c\uc131 \ub9c8\ubc95\uc0ac...(&W)
+seedmore.title=\ud1a0\ub80c\ud2b8\uac00 \ucda9\ubd84\ud788 \ubc30\ud3ec\ub418\uc9c0 \uc54a\uc558\uc74c
+seedmore.shareratio=\uc774 \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud55c \ub2f9\uc2e0\uc758 \uacf5\uc720 \ube44\uc728\uc740
+seedmore.uploadmore=100 \ud37c\uc13c\ud2b8\ubcf4\ub2e4 \ub0ae\uc740 \uacf5\uc720 \ube44\uc728\uc744 \uc720\uc9c0\ud558\ub294 \uac83\uc740 BitTorrent \ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c\ub294 \uc88b\uc740 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4.\n\ud1a0\ub80c\ud2b8 \uc2dc\ub4dc\ub97c \uc880 \ub354 \ub9ce\uc774 \ubc30\ud3ec\ud574\uc57c\ub9cc \ud569\ub2c8\ub2e4.\n\uc815\ub9d0\ub85c \uacc4\uc18d \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+ConfigView.label.showpopuponclose=1\ubcf4\ub2e4 \ub0ae\uc740 \uacf5\uc720 \ube44\uc728\ub85c \ubc30\ud3ec\ub418\ub294 \uc2dc\ub4dc\ub97c \uc815\uc9c0\ud560 \ub54c \uc2b9\uc778 \ud31d\uc5c5\uc744 \ubcf4\uc5ec\uc8fc\uae30
+ConfigView.label.startNumSeeds=\n\ub2e4\uc74c\ubcf4\ub2e4 \uc801\uc73c\uba74 \ubc30\ud3ec \uc2dc\uc791\n - \ub2e4\ub978 \ubaa8\ub4e0 \uaddc\uce59\uc744 \ubb34\uc2dc
+ConfigView.label.seeds=\uc2dc\ub4dc
+ConfigView.section.seeding=\ubc30\ud3ec
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletetorrent=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc0ad\uc81c(&T)
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletedata=\ub370\uc774\ud130 \uc0ad\uc81c(&D)
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=\ub458 \ub2e4 \uc0ad\uc81c(&B)
+deletedata.title=\ucf58\ud150\uce20 \uc0ad\uc81c
+# used for more than just "delete data"
+deletedata.noprompt=\ub2e4\uc2dc \ubb3b\uc9c0 \uc54a\uc74c
+MainWindow.menu.file.configure=\uad6c\uc131 \ub9c8\ubc95\uc0ac(&W)...
 configureWizard.title=\uad6c\uc131 \ub9c8\ubc95\uc0ac
-configureWizard.welcome.title=Vuze \uad6c\uc131 \ub9c8\ubc95\uc0ac\uc5d0 \uc5b4\uc11c \uc624\uc2ed\uc2dc\uc694
-configureWizard.welcome.message=\uc774 \ub9c8\ubc95\uc0ac\ub294 \uac00\uc7a5 \uc77c\ubc18\uc801\uc778 \uc6a9\ub3c4\ub85c Vuze\ub97c \uad6c\uc131\ud558\ub3c4\ub85d \ud574\uc904 \uac83\uc785\ub2c8\ub2e4. \ub3c4\uad6c->\uc120\ud0dd\uc0ac\ud56d \uba54\ub274\ub97c \uc368\uc11c \ubcf4\ub2e4 \uc790\uc138\ud55c \uad6c\uc131\uc744 \ubc14\uafc0 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-configureWizard.transfer.title=\uc804\uc1a1\uacfc \uc5f0\uacb0 \uad6c\uc131
-configureWizard.transfer.hint=\uadc0\ub754: \ub2f9\uc2e0\uc758 \ud1b5\uc2e0 \uc18d\ub3c4\ubcf4\ub2e4 \uc870\uae08 \ub0ae\uac8c \uc4f0\ub294 \uac83\uc774 \uac00\uc7a5 \uc88b\uc2b5\ub2c8\ub2e4.
-configureWizard.transfer.message=\uc544\ub798\uc5d0\uc11c \uc5f0\uacb0\uc744 \uace0\ub974\uc2ed\uc2dc\uc694. \uc62c\ub9ac\uae30 \uc18d\ub3c4\ub97c \ucda9\ubd84\ud788 \ub450\uc9c0 \uc54a\uc73c\uba74 \ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4\uac00 \ub290\ub824\uc9c8 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ub0b4\ub824\ubc1b\ub294 \ud1a0\ub7f0\ud2b8\ub85c\ub9cc \uc62c\ub9ac\uae30 \uc18d\ub3c4\uac00 \uacc4\uc0b0\ub418\ubbc0\ub85c, \ud55c\ubc88\uc5d0 \ub108\ubb34 \ub9ce\uc740 \ud1a0\ub7f0\ud2b8\ub [...]
-configureWizard.transfer.connection=\ud1b5\uc2e0\uc120
+configureWizard.welcome.title=Vuze \uad6c\uc131 \ub9c8\ubc95\uc0ac\uc5d0 \uc624\uc2e0 \uac83\uc744 \ud658\uc601\ud569\ub2c8\ub2e4
+configureWizard.welcome.message=\uc774 \ub9c8\ubc95\uc0ac\ub294 \uac00\uc7a5 \uc77c\ubc18\uc801\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 Vuze \uc124\uc815\uc744 \ub3c4\uc640 \uc90d\ub2c8\ub2e4. \ub3c4\uad6c\u2192\uc635\uc158 \uba54\ub274\uc5d0\uc11c \uc124\uc815\uc744 \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+configureWizard.transfer.title=\uc804\uc1a1\uacfc \uc5f0\uacb0 \uc124\uc815
+configureWizard.transfer.hint=\ud78c\ud2b8 : \uc120\ub85c \uc18d\ub3c4\ubcf4\ub2e4 \uc57d\uac04 \ub0ae\uac8c \uc124\uc815\ud558\ub294 \uac83\uc774 \uac00\uc7a5 \uc88b\uc2b5\ub2c8\ub2e4.
+configureWizard.transfer.message=\uc5f0\uacb0\uc744 \uc544\ub798\uc5d0\uc11c \uc120\ud0dd\ud574\uc8fc\uc2ed\uc2dc\uc624. \ucda9\ubd84\ud55c \uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub97c \uc8fc\uc9c0 \uc54a\uc73c\uba74 \uacb0\uacfc\uc801\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\uac00 \ub5a8\uc5b4\uc9c0\uac8c \ub428\uc744 \uc720\ub150\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4. \uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub294 \ub2e4\uc6b4\ub85c\ub4dc \uc911\uc778 \ud1a0\ub80c\ud2b8 \ubcc4\ub85c\ub9c [...]
+configureWizard.transfer.connection=\uc120\ub85c
 configureWizard.transfer.connection.0=\uc0ac\uc6a9\uc790 \uc9c0\uc815
 configureWizard.transfer.connection.1=\ubaa8\ub380
-configureWizard.transfer.connection.2=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 128 kbps
-configureWizard.transfer.connection.3=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 256 kbps
-configureWizard.transfer.connection.4=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 384 kbps
-configureWizard.transfer.connection.5=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 512 kbps
-configureWizard.transfer.connection.6=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 768 kbps
-configureWizard.transfer.connection.7=DSL/\ucf00\uc774\ube14 \ucd5c\ub300 1024 kbps
-configureWizard.transfer.maxUpSpeed=\ucd5c\uace0 \uc62c\ub9ac\uae30 \uc18d\ub3c4 (KB/s)
-configureWizard.transfer.maxActiveTorrents=\ucd5c\ub300 \ud65c\ub3d9 \uc911
-configureWizard.transfer.maxDownloads=\ucd5c\ub300 \ub0b4\ub824\ubc1b\uae30
-configureWizard.transfer.maxUploadsPerTorrent=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4 \ucd5c\ub300 \uc62c\ub9ac\uae30
-configureWizard.nat.title=\uacf5\uc720\uae30 / \uc11c\ubc84 \ud3ec\ud2b8
-configureWizard.nat.message=Vuze\uc5d0\uc11c \uc7ac\uc131\ub2a5\uc744 \ub0bc\ub824\uba74 \uc778\ud130\ub137\uc811\uc18d\uc774 \uc6d0\ud560\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4. \uc774 \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\ub8cc\ub4e4\uc774 \ub0b4 \ucef4\ud4e8\ud130\ub85c \uc811\uc18d\ud558\ub294 \ud3ec\ud2b8\ub97c \ubcc0\uacbd\ud558\uac70\ub098 \uc811\uc18d\uc774 \uc6d0\ud560\ud55c\uc9c0 \uac80\uc0ac\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \n\n\uadc0\ub754 : \uc774 \ub3c4\uad [...]
-configureWizard.nat.test=\uac80\uc0ac
-configureWizard.nat.testing=\ud3ec\ud2b8 \uac80\uc0ac \uc911
-configureWizard.nat.ok=\ud655\uc778
-configureWizard.nat.ko=\uacf5\uc720\uae30 \uc624\ub958
-configureWizard.nat.unable=\uac80\uc0ac\uac00 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc74c
-configureWizard.file.title=\ud1a0\ub7f0\ud2b8 / \ud30c\uc77c
-configureWizard.file.message1=Vuze\uac00 \ud2b9\uc815\ud55c \ud3f4\ub354\uc5d0 \uc5f4\ub9b0 \ud1a0\ub7f0\ud2b8\ub97c \uc800\uc7a5\ud560 \uac83\uc785\ub2c8\ub2e4. \uc774 \ud3f4\ub354\ub97c \uc5ec\uae30\uc5d0\uc11c \uace0\ub97c \uc218 \uc788\uc2b5\ub2c8\ub2e4:
-configureWizard.file.path=\uc704\uce58
+configureWizard.transfer.connection.2=DSL/\ucf00\uc774\ube14/128 kbps
+configureWizard.transfer.connection.3=DSL/\ucf00\uc774\ube14/256 kbps
+configureWizard.transfer.connection.4=DSL/\ucf00\uc774\ube14/384 kbps
+configureWizard.transfer.connection.5=DSL/\ucf00\uc774\ube14/512 kbps
+configureWizard.transfer.connection.6=DSL/\ucf00\uc774\ube14/768 kbps
+configureWizard.transfer.connection.7=DSL/\ucf00\uc774\ube14/1024 kbps
+configureWizard.transfer.maxUpSpeed=\ucd5c\uace0 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 (KB/s)
+configureWizard.transfer.maxActiveTorrents=\ucd5c\ub300 \ud65c\uc131 \ud1a0\ub80c\ud2b8
+configureWizard.transfer.maxDownloads=\ucd5c\ub300 \ub2e4\uc6b4\ub85c\ub4dc \uc218
+configureWizard.transfer.maxUploadsPerTorrent=\ud1a0\ub80c\ud2b8 \ubcc4 \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc218
+configureWizard.nat.test=\ud14c\uc2a4\ud2b8
+configureWizard.nat.testing=\ud3ec\ud2b8 \ud14c\uc2a4\ud2b8 \uc911
+configureWizard.nat.ok=\uc815\uc0c1 !
+configureWizard.nat.ko=NAT \uc624\ub958
+configureWizard.nat.unable=\ud14c\uc2a4\ud2b8\ud560 \uc218 \uc5c6\uc74c: \uc798\ubabb\ub41c \ud3ec\ud2b8\uac00 \uc8fc\uc5b4\uc84c\uac70\ub098 \ud14c\uc2a4\ud2b8 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\ub2e4\ub978 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\uc774 \uc774\ubbf8 \ud574\ub2f9 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+configureWizard.file.title=\ud1a0\ub80c\ud2b8 / \ud30c\uc77c
+configureWizard.file.message1=Vuze\ub294 \uc5f4\ub9b0 \ud1a0\ub80c\ud2b8\ub97c \ud2b9\uc815 \ud3f4\ub354\uc5d0 \uc800\uc7a5\ud558\uac8c \ub429\ub2c8\ub2e4. \uadf8 \ud3f4\ub354\ub97c \uc5ec\uae30\uc5d0 \uc9c0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4:
+configureWizard.file.path=\uacbd\ub85c
 configureWizard.file.browse=\ucc3e\uc544\ubcf4\uae30
-configureWizard.file.message2=Vuze\uac00 \ub2f9\uc2e0\uc758 \ud1a0\ub7f0\ud2b8\ub4e4\uc5d0 \ub2e4\uc2dc \uc2dc\uc791 \ub370\uc774\ud130\ub97c \ub354\ud574\uc11c \ud30c\uc77c\ub4e4\uc744 \ubc14\ub85c \ub2e4\uc2dc \uc2dc\uc791\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uba74, \ubd80\ubd84\uc801\uc73c\ub85c \ub0b4\ub824\ubc1b\uc740 \uc870\uac01\ub4e4\ub3c4 \ub2e4\uc2dc \uc2dc\uc791\ud560 \uac83\uc785\ub2c8\ub2e4.
-configureWizard.file.fastResume=\ube60\ub978 \ub2e4\uc2dc \uc2dc\uc791\ud558\uae30 \uc791\ub3d9
+configureWizard.file.message2=Vuze\ub294 \uc0ac\uc6a9\uc790\uac00 \ud1a0\ub80c\ud2b8\uc5d0 \uc57d\uac04\uc758 \uc774\uc5b4\ubc1b\uae30 \ub370\uc774\ud130\ub97c \ucd94\uac00\ud558\uba74 \ud30c\uc77c\uc744 \uc989\uc2dc \uc774\uc5b4\ubc1b\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uba74 \ubd80\ubd84\uc801\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc\ud55c \uc870\uac01 \uc5ed\uc2dc \uc774\uc5b4\ubc1b\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+configureWizard.file.fastResume=\ube60\ub978 \ub2e4\uc2dc \uc2dc\uc791 \ud65c\uc131\ud654
 configureWizard.file.invalidPath=\uc798\ubabb\ub41c \ud3f4\ub354
-configureWizard.finish.title=\ub9c8\uce68
-configureWizard.finish.message=Vuze\uac00 \uc774\uc81c \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uc990\uae30\uc138\uc694!
-wizard.close.confirmation=\ud655\uc778
-wizard.close.message=\ub2e4\uc74c\uc5d0 Vuze\ub97c \uc2dc\uc791\ud560 \ub54c \uc774 \ub9c8\ubc95\uc0ac\ub97c \ubd80\ub974\uaca0\uc2b5\ub2c8\uae4c?
-exportTorrentWizard.title=\ud1a0\ub7f0\ud2b8\ub97c XML\ub85c \ub0b4\ubcf4\ub0b4\uae30
-exportTorrentWizard.torrentfile.title=\uc785\ub825 \ud1a0\ub7f0\ud2b8 \uace0\ub974\uae30
-exportTorrentWizard.torrentfile.message=\ub0b4\ubcf4\ub0bc \ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-exportTorrentWizard.torrentfile.path=\uc704\uce58
+configureWizard.finish.title=\uc644\ub8cc\ub428
+configureWizard.finish.message=Vuze \uc124\uc815\uc774 \uc644\ub8cc \ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uc990\uac70\uc6b4 \uc2dc\uac04 \ub418\uc2ed\uc2dc\uc624!
+wizard.close.confirmation=\uc2b9\uc778
+wizard.close.message=\ub2e4\uc74c\uc5d0 Vuze\ub97c \uc2dc\uc791\ud560 \ub54c \uc774 \ub9c8\ubc95\uc0ac\ub97c \ubcf4\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+exportTorrentWizard.title=XML \ud1a0\ub80c\ud2b8 \ub0b4\ubcf4\ub0b4\uae30
+exportTorrentWizard.torrentfile.title=\uc785\ub825 \ud1a0\ub80c\ud2b8 \uc120\ud0dd
+exportTorrentWizard.torrentfile.message=\ub0b4\ubcf4\ub0bc \ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc744 \uc120\ud0dd
+exportTorrentWizard.torrentfile.path=\uacbd\ub85c
 exportTorrentWizard.torrentfile.browse=\ucc3e\uc544\ubcf4\uae30
-exportTorrentWizard.torrentfile.invalidPath=\uc798\ubabb\ub41c \ud1a0\ub7f0\ud2b8 \ud30c\uc77c
-exportTorrentWizard.exportfile.title=\ub0b4\ubcf4\ub0b4\uae30 \ud30c\uc77c \uace0\ub974\uae30
-exportTorrentWizard.exportfile.message=\ub0b4\ubcf4\ub0bc xml \ud30c\uc77c \uc774\ub984\uc744 \uc368\ub123\uc73c\uc2ed\uc2dc\uc694.
-exportTorrentWizard.exportfile.path=\uc704\uce58
+exportTorrentWizard.torrentfile.invalidPath=\uc798\ubabb\ub41c \ud1a0\ub80c\ud2b8 \ud30c\uc77c
+exportTorrentWizard.exportfile.title=\ub0b4\ubcf4\ub0b4\uae30 \ud30c\uc77c \uc120\ud0dd
+exportTorrentWizard.exportfile.message=\ub0b4\ubcf4\ub0bc XML \ud30c\uc77c \uc774\ub984 \uc785\ub825
+exportTorrentWizard.exportfile.path=\uacbd\ub85c
 exportTorrentWizard.exportfile.browse=\ucc3e\uc544\ubcf4\uae30
 exportTorrentWizard.exportfile.invalidPath=\uc798\ubabb\ub41c \ub0b4\ubcf4\ub0b4\uae30 \ud30c\uc77c
-exportTorrentWizard.finish.title=\ub05d\ub9c8\uce68
-exportTorrentWizard.finish.message=\ub0b4\ubcf4\ub0b4\uae30\ub97c \uc81c\ub300\ub85c \ub05d\ub9c8\uce68
-exportTorrentWizard.process.inputfilebad.title=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc774 \ub9de\uc9c0 \uc54a\uc74c
-exportTorrentWizard.process.inputfilebad.message=\uc785\ub825 \ud30c\uc77c\uc5d0 \uc811\uadfc\ud558\uc9c0 \ubabb\ud568:
-exportTorrentWizard.process.outputfileexists.title=\ud30c\uc77c\uc774 \uc788\uc74c
-exportTorrentWizard.process.outputfileexists.message=\ucd9c\ub825 \ud30c\uc77c\uc774 \uc788\uc74c - \ub36e\uc5b4 \uc4f0\uaca0\uc2b5\ub2c8\uae4c?
-exportTorrentWizard.process.torrentfail.title=\ud1a0\ub7f0\ud2b8\ub97c \uc77d\uc9c0 \ubabb\ud568
-exportTorrentWizard.process.exportfail.title=\ud1a0\ub7f0\ud2b8\ub97c \ub0b4\ubcf4\ub0b4\uc9c0 \ubabb\ud568
-exportTorrentWizard.process.unknownfail.title=\ub73b\ubc16\uc758 \uc624\ub958
-importTorrentWizard.title=XML \ud1a0\ub7f0\ud2b8\ub97c \ub4e4\uc5ec\uc624\uae30
-importTorrentWizard.torrentfile.title=\uc785\ub825 \ud1a0\ub7f0\ud2b8 \uace0\ub974\uae30
-importTorrentWizard.torrentfile.message=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc5d0 \ub4e4\uc5ec\uc62c \ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc774\ub984\uc744 \uc368\ub123\uc73c\uc2ed\uc2dc\uc694.
-importTorrentWizard.torrentfile.path=\uc704\uce58
+exportTorrentWizard.finish.title=\uc644\ub8cc
+exportTorrentWizard.finish.message=\uc131\uacf5\uc801\uc73c\ub85c \ub0b4\ubcf4\ub0b4\uae30 \uc644\ub8cc
+exportTorrentWizard.process.inputfilebad.title=\uc798\ubabb\ub41c \ud1a0\ub80c\ud2b8 \ud30c\uc77c
+exportTorrentWizard.process.inputfilebad.message=\uc785\ub825 \ud30c\uc77c \uc811\uadfc \uc911 \uc2e4\ud328:
+exportTorrentWizard.process.outputfileexists.title=\ud30c\uc77c\uc774 \uc774\ubbf8 \uc874\uc7ac
+exportTorrentWizard.process.outputfileexists.message=\ucd9c\ub825 \ud30c\uc77c\uc774 \uc774\ubbf8 \uc874\uc7ac - \ub36e\uc5b4 \uc4f0\uaca0\uc2b5\ub2c8\uae4c?
+exportTorrentWizard.process.torrentfail.title=\ud1a0\ub80c\ud2b8 \uc77d\uae30 \uc2e4\ud328
+exportTorrentWizard.process.exportfail.title=\ud1a0\ub80c\ud2b8 \ub0b4\ubcf4\ub0b4\uae30 \uc2e4\ud328
+exportTorrentWizard.process.unknownfail.title=\uc608\uc0c1\ub418\uc9c0 \uc54a\uc740 \uc624\ub958
+importTorrentWizard.title=XML \ud1a0\ub80c\ud2b8 \uac00\uc838\uc624\uae30
+importTorrentWizard.torrentfile.title=\uc785\ub825 \ud1a0\ub80c\ud2b8 \uc120\ud0dd
+importTorrentWizard.torrentfile.message=\uac00\uc838\uc62c \ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc785\ub825
+importTorrentWizard.torrentfile.path=\uacbd\ub85c
 importTorrentWizard.torrentfile.browse=\ucc3e\uc544\ubcf4\uae30
-importTorrentWizard.torrentfile.invalidPath=\uc798\ubabb\ub41c \ud1a0\ub7f0\ud2b8 \ud30c\uc77c
-importTorrentWizard.importfile.title=\ub4e4\uc5ec\uc624\uae30 \ud30c\uc77c \uace0\ub974\uae30
-importTorrentWizard.importfile.message=\ub4e4\uc5ec\uc62c xml \ud30c\uc77c\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-importTorrentWizard.importfile.path=\uc704\uce58
+importTorrentWizard.torrentfile.invalidPath=\uc798\ubabb\ub41c \ud1a0\ub80c\ud2b8 \ud30c\uc77c
+importTorrentWizard.importfile.title=\uac00\uc838\uc624\uae30 \ud30c\uc77c \uc120\ud0dd
+importTorrentWizard.importfile.message=\uac00\uc838\uc62c XML \ud30c\uc77c \uc120\ud0dd
+importTorrentWizard.importfile.path=\uacbd\ub85c
 importTorrentWizard.importfile.browse=\ucc3e\uc544\ubcf4\uae30
-importTorrentWizard.importfile.invalidPath=\uc798\ubabb\ub41c \ub4e4\uc5ec\uc624\uae30 \ud30c\uc77c
-importTorrentWizard.finish.title=\ub05d\ub9c8\uce68
-importTorrentWizard.finish.message=\ub4e4\uc5ec\uc624\uae30\ub97c \uc81c\ub300\ub85c \ub05d\ub9c8\uce68
-importTorrentWizard.process.inputfilebad.title=\uc798\ubabb\ub41c \ub4e4\uc5ec\uc624\uae30 \ud30c\uc77c
-importTorrentWizard.process.inputfilebad.message=\uc785\ub825 \ud30c\uc77c\uc5d0 \uc811\uadfc\ud558\uc9c0 \ubabb\ud568:
-importTorrentWizard.process.outputfileexists.title=\ud30c\uc77c\uc774 \uc788\uc74c
-importTorrentWizard.process.outputfileexists.message=\ucd9c\ub825 \ud30c\uc77c\uc774 \uc788\uc74c - \ub36e\uc5b4 \uc4f0\uaca0\uc2b5\ub2c8\uae4c?
-importTorrentWizard.process.torrentfail.title=\ud1a0\ub7f0\ud2b8\ub97c \uc4f0\uc9c0 \ubabb\ud568
-importTorrentWizard.process.importfail.title=\ud1a0\ub7f0\ud2b8\ub97c \ub4e4\uc5ec\uc624\uc9c0 \ubabb\ud568
-importTorrentWizard.process.unknownfail.title=\ub73b\ubc16\uc758 \uc624\ub958
-ConfigView.label.bindip=\ub85c\uceec IP \uc8fc\uc18c\ub85c \uc5f0\uacb0 or interface
-xfs.allocation.xfs_io.not.found=/usr/sbin/xfs_io\uac00 \uc791\ub3d9\ud558\uc9c0 \uc54a\uc544 XFS\ud30c\uc77c \ud560\ub2f9\uc774 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc2dc\uc2a4\ud15c\uc5d0 \uc124\uce58\uac00 \uc548\ub418\uc5b4 \uc788\uc744 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc624\ub958 \uba54\uc138\uc9c0 : "%1".
-ConfigView.label.zeronewfiles=\ub9cc\ub4e4 \ub54c \uc0c8 \ud30c\uc77c\uc744 \ud560\ub2f9\ud558\uace0 0\uc5d0 \ub9de\ucda4
-ConfigView.label.zeronewfiles.tooltip=\uc870\uac01 \ucd5c\uc18c\ub85c \ud568
+importTorrentWizard.importfile.invalidPath=\uc798\ubabb\ub41c \uac00\uc838\uc624\uae30 \ud30c\uc77c
+importTorrentWizard.finish.title=\uc644\ub8cc\ub428
+importTorrentWizard.finish.message=\uac00\uc838\uc624\uae30\uac00 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub428
+importTorrentWizard.process.inputfilebad.title=\uc798\ubabb\ub41c \uac00\uc838\uc624\uae30 \ud30c\uc77c
+importTorrentWizard.process.inputfilebad.message=\uc785\ub825 \ud30c\uc77c \uc811\uadfc \uc911 \uc2e4\ud328:
+importTorrentWizard.process.outputfileexists.title=\ud30c\uc77c \uc874\uc7ac
+importTorrentWizard.process.outputfileexists.message=\ucd9c\ub825 \ud30c\uc77c\uc774 \uc774\ubbf8 \uc874\uc7ac - \ub36e\uc5b4 \uc4f0\uaca0\uc2b5\ub2c8\uae4c?
+importTorrentWizard.process.torrentfail.title=\ud1a0\ub80c\ud2b8 \uc4f0\uae30 \uc2e4\ud328
+importTorrentWizard.process.importfail.title=\ud1a0\ub80c\ud2b8 \uac00\uc838\uc624\uae30 \uc2e4\ud328
+importTorrentWizard.process.unknownfail.title=\uc608\uc0c1\ud558\uc9c0 \ubabb\ud55c \uc624\ub958
+ConfigView.label.bindip=\ub85c\uceec IP \uc8fc\uc18c \ub610\ub294 \uc778\ud130\ud398\uc774\uc2a4\uc5d0 \ubc14\uc778\ub4dc
+ConfigView.label.xfs.allocation=XFS \ud30c\uc77c \uc2dc\uc2a4\ud15c\uc5d0 \ud55c\uc815\ub41c \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0c8 \ud30c\uc77c \ud560\ub2f9
+ConfigView.label.xfs.allocation.tooltip=/usr/sbin/xfs_io\uac00 \uc2dc\uc2a4\ud15c\uc5d0 \uc62c\ubc14\ub85c \uc124\uce58\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud574\uc8fc\uc2ed\uc2dc\uc624. \ub300\ubd80\ubd84\uc758 Linux \ubc30\ud3ec\ud310\uc5d0\ub294 \ud574\ub2f9 \ubc30\ud3ec\ubcf8\uc774 "xfsprogs" \ud328\ud0a4\uc9c0\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.
+xfs.allocation.xfs_io.not.found=/usr/sbin/xfs_io \uc774 \uc2e4\ud589\ub418\uc9c0 \uc54a\uc544\uc11c XFS\ud30c\uc77c \ud560\ub2f9\uc744 \uc2e4\ud328 \ud588\uc2b5\ub2c8\ub2e4. \uc2dc\uc2a4\ud15c\uc5d0 \uc62c\ubc14\ub974\uac8c \uc124\uce58\ub418\uc5c8\ub294\uc9c0 \ud655\uc778 \ubc14\ub78d\ub2c8\ub2e4. \uc6d0\ub798\uc758 \uc624\ub958 \uba54\uc2dc\uc9c0: "%1".
+ConfigView.label.zeronewfiles=\uc0c8 \ud30c\uc77c\uc744 \uc0dd\uc131\ud560 \ub54c \ud30c\uc77c \ud560\ub2f9 \ud6c4 0\uc73c\ub85c \uccb4\uc6b0\uae30
+ConfigView.label.zeronewfiles.tooltip=\ub514\uc2a4\ud06c \ub2e8\ud3b8\ud654\ub97c \ucd5c\uc18c\ud654
 ConfigView.section.stats=\ud1b5\uacc4
-ConfigView.section.stats.enable=\uc791\ub3d9
-ConfigView.section.stats.defaultsavepath=\ud1b5\uacc4 \uc800\uc7a5 \ud3f4\ub354
-ConfigView.section.stats.choosedefaultsavepath=\ud1b5\uacc4 \uc800\uc7a5 \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-ConfigView.section.stats.savefreq=\ube48\ub3c4 \uc800\uc7a5
+ConfigView.section.stats.enable=\ud65c\uc131\ud654
+ConfigView.section.stats.defaultsavepath=\ud1b5\uacc4 \uc800\uc7a5 \ub514\ub809\ud130\ub9ac
+ConfigView.section.stats.choosedefaultsavepath=\ud1b5\uacc4 \uc800\uc7a5 \ub514\ub809\ud130\ub9ac\ub97c \uc120\ud0dd
+ConfigView.section.stats.savefreq=\uc800\uc7a5 \ube48\ub3c4
 ConfigView.section.stats.minutes=\ubd84
 ConfigView.section.stats.hours=\uc2dc\uac04
 ConfigView.section.stats.seconds=\ucd08
 ConfigView.section.stats.savefile=\ud1b5\uacc4 \ud30c\uc77c \uc774\ub984
-MyTorrentsView.menu.export=XML \ud1a0\ub7f0\ud2b8...(&X)
-MyTorrentsView.menu.host=\ud638\uc2a4\ud2b8...(&H)
-ManagerItem.finishing=\ub9c8\uce58\uace0 \uc788\uc74c
-ConfigView.dialog.choosedefaulttorrentpath=\uae30\ubcf8 \ud1a0\ub7f0\ud2b8 \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-ConfigView.dialog.choosemovepath=\uc62e\uae38 \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-ConfigView.label.movecompleted=\ub05d\ub9c8\uce5c \ud30c\uc77c \uc62e\uae40
-ConfigView.label.moveremoved=\uc644\ub8cc\ub41c \ud30c\uc77c \uc62e\uae30\uae30 (\uc62e\uae30\uae30 \uc2dc\uc791\ud560\ub54c)
-ConfigView.label.savetorrents=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc800\uc7a5
-MainWindow.menu.view.mytracker=\ub0b4 \ub354\ub4ec\uc774(&T)
-MainWindow.menu.view.mytracker.keybinding=\uba54\ud0c0+2
-MyTrackerView.title.full=\ub0b4 \ub354\ub4ec\uc774
+ConfigView.section.stats.graph_update_dividers=60 \uc5c5\ub370\uc774\ud2b8\ub9c8\ub2e4 \uc138\ub85c\uc904 \ud45c\uc2dc
+MyTorrentsView.menu.export=XML \ud1a0\ub80c\ud2b8(&X)...
+MyTorrentsView.menu.host=\ud638\uc2a4\ud2b8(&H)...
+ManagerItem.finishing=\ub9c8\uce58\ub294 \uc911
+ConfigView.dialog.choosedefaulttorrentpath=\uae30\ubcf8 \ud1a0\ub80c\ud2b8 \ud3f4\ub354 \uc120\ud0dd
+ConfigView.dialog.choosemovepath=\uc774\ub3d9\ud560 \ub514\ub809\ud130\ub9ac \uc120\ud0dd
+ConfigView.label.movecompleted=\uc644\ub8cc\ub41c \ud30c\uc77c \uc774\ub3d9 (\ub2e4\uc6b4\ub85c\ub4dc \ud6c4)
+ConfigView.label.moveremoved=\uc644\ub8cc\ub41c \ud30c\uc77c \uc774\ub3d9 (\uc81c\uac70\ub420 \ub54c)
+ConfigView.label.savetorrents=.torrent \ud30c\uc77c \uc800\uc7a5
+MainWindow.menu.view.mytracker=\ub0b4 \ud2b8\ub798\ucee4(&T)
+MyTrackerView.title.full=\ub0b4 \ud2b8\ub798\ucee4
 MyTrackerView.name=\uc774\ub984
-MyTrackerView.tracker=\ub354\ub4ec\uc774
+MyTrackerView.tracker=\ud2b8\ub798\ucee4
 MyTrackerView.status=\uc0c1\ud0dc
-MyTrackerView.status.started=\uc2dc\uc791
-MyTrackerView.status.stopped=\uba48\ucda4
-MyTrackerView.peers=\ub3d9\ub8cc
-MyTrackerView.seeds=\uc528\uc557
-MyTrackerView.announces=\ub354\ub4ec\uc774 \uc54c\ub9ac\uae30
-MyTrackerView.uploaded=\uc62c\ub824\uc9d0
-MyTrackerView.downloaded=\ub0b4\ub824\ubc1b\uc74c
+MyTrackerView.status.started=\uc2e4\ud589 \uc911
+MyTrackerView.status.stopped=\uc815\uc9c0\ub428
+MyTrackerView.peers=\ud53c\uc5b4
+MyTrackerView.seeds=\uc2dc\ub4dc
+MyTrackerView.announces=\uc54c\ub9bc
+MyTrackerView.uploaded=\uc5c5\ub85c\ub4dc\ub428
+MyTrackerView.downloaded=\ub2e4\uc6b4\ub85c\ub4dc\ub428
 MyTrackerView.left=\ub0a8\uc74c
 ConfigView.section.style=\uc778\ud130\ud398\uc774\uc2a4
-ConfigView.section.style.useCustomTabs=\ub2eb\uc744 \uc218 \uc788\ub294 \ud0ed \uc4f0\uae30 (\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568)
-MainWindow.menu.view.plugins=\ucd94\uac00\uae30\ub2a5(&P)
-fileDownloadWindow.saveTorrentIn=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc800\uc7a5 \uc704\uce58
-fileDownloadWindow.title=Vuze - \ud1a0\ub7f0\ud2b8 \ub0b4\ub824\ubc1b\uae30 \ud504\ub85c\uadf8\ub7a8
-fileDownloadWindow.downloading=\ub0b4\ub824\ubc1b\uae30\ud558\uace0 \uc788\ub294 \uacf3:
-fileDownloadWindow.status=\uc0c1\ud0dc: 
-fileDownloadWindow.state_initializing=\ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
-fileDownloadWindow.state_downloading=\ub0b4\ub824\ubc1b\uae30\ud558\uace0 \uc788\uc74c
-fileDownloadWindow.state_error=\uc624\ub958: 
-MainWindow.menu.file.open.url=\uc8fc\uc18c(&U)
-openUrl.title=\uc8fc\uc18c \uc5f4\uae30
-openUrl.url=\uc8fc\uc18c:
-MyTorrentsView.menu.host.error.title=\ud1a0\ub7f0\ud2b8 \ud638\uc2a4\ud2b8\ud558\uc9c0 \ubabb\ud568
-MyTorrentsView.menu.host.error.message=\ud1a0\ub7f0\ud2b8\ub97c \ud638\uc2a4\ud2b8\ud558\ub2e4\uac00 \ub2e4\uc74c \uc624\ub958\uac00 \uc0dd\uacbc\uc2b5\ub2c8\ub2e4.
-ConfigView.section.tracker=\ub354\ub4ec\uc774
-ConfigView.section.tracker.pollinterval=\ub354\ub4ec\uc774 \uc811\uc18d \ucef4\ud4e8\ud130 \ud3f4\ub9c1 \uac04\uaca9 (\ucd08)
-ConfigView.section.tracker.publishenable="<tracker_url>"\ub85c \ud1a0\ub7f0\ud2b8 \uc0c1\uc138 \uc815\ubcf4 \uc54c\ub9bc
-ConfigView.section.tracker.ip=\uc678\ubd80 IP \uc8fc\uc18c \ud2b8\ub798\ucee4
-ConfigView.section.style.enableXPStyle=XP \uc2a4\ud0c0\uc77c \uc791\ub3d9 (\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568)
-IPChecker.external.service.dyndns.description=\uc720\ub3d9 DNS \ub124\ud2b8\uc6cc\ud06c \uc11c\ube44\uc2a4, \uc720\ud55c \ucc45\uc784 \ud68c\uc0ac
-ConfigView.section.tracker.checkip=\uc678\ubd80 IP \uc8fc\uc18c\ub97c \uc800\uc808\ub85c \uc54c\uc544\ucc54...
-ipCheckerWizard.title=IP \uac80\uc0ac \ub9c8\ubc95\uc0ac
+ConfigView.label.set_ui_transfer_speeds=\uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc804\uc1a1 \uc18d\ub3c4 \uc6b0\uc120\uc801\uc6a9
+ConfigView.label.set_ui_transfer_speeds.description=\uc2dc\uc2a4\ud15c \ud2b8\ub798\uc774\uc758 \uc0c1\ud0dc \ub9c9\ub300\uc5d0\uc11c \uac00\ub2a5\ud55c \uae30\ubcf8 \ub2e4\uc6b4\ub85c\ub4dc\uc640 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uae30\ubcf8\uac12\uc744 \uc218\ub3d9\uc73c\ub85c \uc120\ud0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\ud574\ub2f9 \uac12\uc740 \ubc18\ub4dc\uc2dc \ucf64\ub9c8(,)\ub85c \uad6c\ubd84\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4..
+ConfigView.label.set_ui_transfer_speeds.description.download=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc124\uc815 [KB/s]
+ConfigView.label.set_ui_transfer_speeds.description.upload=\uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc124\uc815 [KB/s]
+ConfigView.section.style.useCustomTabs=\ub2eb\uc744 \uc218 \uc788\ub294 \ud0ed \uc0ac\uc6a9 (\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694)
+MainWindow.menu.view.plugins=\ud50c\ub7ec\uadf8\uc778(&P)
+fileDownloadWindow.saveTorrentIn=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc800\uc7a5 \uc704\uce58:
+fileDownloadWindow.title=Vuze - \ud1a0\ub80c\ud2b8 \ub2e4\uc6b4\ub85c\ub354
+fileDownloadWindow.downloading=\ub2e4\uc74c\uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc \uc911 :
+fileDownloadWindow.status=\uc0c1\ud0dc :
+fileDownloadWindow.state_initializing=\ucd08\uae30\ud654 \uc911
+fileDownloadWindow.state_downloading=\ub2e4\uc6b4\ub85c\ub4dc \uc911
+fileDownloadWindow.state_error=\uc624\ub958:
+MainWindow.menu.file.open.url=\uc704\uce58(&L)...
+openUrl.title=\uc704\uce58 \uc5f4\uae30
+MyTorrentsView.menu.host.error.title=\ud1a0\ub80c\ud2b8 \ud638\uc2a4\ud305 \uc2e4\ud328
+MyTorrentsView.menu.host.error.message=\ud1a0\ub80c\ud2b8 \ud638\uc2a4\ud305 \uc911 \ub2e4\uc74c \uc624\ub958\uac00 \ubc1c\uc0dd\ud568
+ConfigView.section.tracker=\ud2b8\ub798\ucee4
+ConfigView.section.tracker.pollinterval=\ud2b8\ub798\ucee4 \ud074\ub77c\uc774\uc5b8\ud2b8 \ud3f4 \uac04\uacac (\ucd08)
+ConfigView.section.tracker.publishenable=<tracker_url>\uc5d0 \ud1a0\ub80c\ud2b8 \uc0c1\uc138 \uc815\ubcf4\ub97c \uac8c\uc2dc
+ConfigView.section.tracker.ip=\ud2b8\ub798\ucee4 \uc678\ubd80 IP \uc8fc\uc18c
+ConfigView.section.style.enableXPStyle=XP \uc2a4\ud0c0\uc77c \ud65c\uc131\ud654 (\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694)
+ConfigView.section.tracker.checkip=\uc678\ubd80 IP \uc8fc\uc18c \uc790\ub3d9 \uac10\uc9c0...
+ipCheckerWizard.title=IP \uac80\uc0ac\uae30 \ub9c8\ubc95\uc0ac
 ipCheckerWizard.service=\uc11c\ube44\uc2a4
-ipCheckerWizard.chooseService=\ub4e4\uace0 \uc788\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c IP \uac80\uc0ac \uc11c\ube44\uc2a4\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-ipCheckerWizard.explanations=\uc774 \ub9c8\ubc95\uc0ac\ub97c \uc368\uc11c \uc774 \ucef4\ud4e8\ud130\uc758 \uc678\ubd80 IP \uc8fc\uc18c\uac00 \ubb34\uc5c7\uc778\uc9c0 \uc54c\uc544\ub0bc \uc218 \uc788\uc2b5\ub2c8\ub2e4. IP \uc8fc\uc18c\uac00 \uc720\ub3d9 IP\uc774\uba74 DDNS \uc11c\ube44\uc2a4\ub85c IP\uc8fc\uc18c\ub97c \uc5f0\uacb0 \uc2dc\ucf1c \ud638\uc2a4\ud2b8 \uc774\ub984\uc744 \ub9cc\ub4e4 \uac83\uc744 \uad8c\ud569\ub2c8\ub2e4. \uc544\ub798\uc758 \ubb34\ub8cc \uc11c\ube44\uc2a4 \uc81c [...]
-ipCheckerWizard.service.description=\uc124\uba85:
-ipCheckerWizard.service.url=\uc8fc\uc18c:
-ipCheckerWizard.progresstitle=IP \uac80\uc0ac\ud558\uace0 \uc788\uc74c
-ipCheckerWizard.checkComplete=\ub05d\ub9c8\uce5c IP:
-ipCheckerWizard.checkFailed=\uc791\ub3d9\ud558\uc9c0 \uc54a\ub294 IP, \uae4c\ub2ed:
-wizard.tracker.local=Vuze\uc5d0 \ub0b4\uc7a5\ub41c \ub354\ub4ec\uc774\ub97c \uc500
-wizard.tracker.external=\uc678\ubd80 \ub354\ub4ec\uc774\ub97c \uc500
-wizard.tracker.howToLocal=\t\uc791\ub3d9\uc2dc\ud0a4\ub824\uba74 '\ub3c4\uad6c->\uc120\ud0dd\uc0ac\ud56d->\ub354\ub4ec\uc774'\ub85c \uac00\uc2ed\uc2dc\uc694.
-wizard.announceUrl=\ub354\ub4ec\uc774 \uc54c\ub9bc \uc8fc\uc18c(Announce URL):
+ipCheckerWizard.chooseService=\ub098\uc5f4\ub41c \uc11c\ube44\uc2a4 \ubaa9\ub85d\uc5d0\uc11c IP \uac80\uc0ac \uc11c\ube44\uc2a4\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
+ipCheckerWizard.explanations=\uc774 \ub9c8\ubc95\uc0ac\ub97c \ud1b5\ud574\uc11c \uc678\ubd80 IP \uc8fc\uc18c\uac00 \ubb34\uc5c7\uc778\uc9c0\ub97c \uc54c \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub9cc\uc57d \ub2f9\uc2e0\uc758 IP \uc8fc\uc18c\uac00 \uc720\ub3d9\uc801\uc774\ub77c\uba74 \uc720\ub3d9 DNS \uc11c\ube44\uc2a4 \uacc4\uc815\uc744 \uc5f4\uae30\ub97c \uad8c\uc7a5\ud569\ub2c8\ub2e4. \ud574\ub2f9 \uc11c\ube44\uc2a4 \ubaa9\ub85d\uc774 \uc544\ub798\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. \uacc4\uc815\ [...]
+ipCheckerWizard.service.description=\uc124\uba85 :
+ipCheckerWizard.service.url=\ub9c1\ud06c :
+ipCheckerWizard.progresstitle=IP \uac80\uc0ac \uc911
+ipCheckerWizard.checkComplete=\uc644\ub8cc\ub41c IP :
+ipCheckerWizard.checkFailed=\uc2e4\ud328, \uc774\uc720 :
+wizard.tracker.local=Vuze \ub0b4\uc7a5 \ud2b8\ub798\ucee4 \uc0ac\uc6a9
+wizard.tracker.external=\uc678\ubd80 \ud2b8\ub798\ucee4 \uc0ac\uc6a9
+wizard.tracker.howToLocal=\t\ud65c\uc131\ud654 \ud558\ub824\uba74 '\ub3c4\uad6c\u2192\uc635\uc158\u2192\ud2b8\ub798\ucee4'\ub85c \uac00\uc2ed\uc2dc\uc624.
+wizard.announceUrl=\uc54c\ub9bc URL :
 IPChecker.external.service.discoveryvip.description=Discoveryvip - IP \uc8fc\uc18c \uac80\uc0ac\ub9cc
-IPChecker.external.httpinvalidresponse=\uc798\ubabb\ub41c HTTP \ubc18\uc751
-IPChecker.external.loadingwebpage=\uc6f9 \ud398\uc774\uc9c0\ub97c \uc5f4\uace0 \uc788\uc74c
-IPChecker.external.analysingresponse=\ubc18\uc751\uc744 \ubd84\uc11d\ud558\uace0 \uc788\uc74c
-IPChecker.external.addressextracted=\ubf51\uc544\ub0b8 IP \uc8fc\uc18c
-IPChecker.external.httploadfail=\ud398\uc774\uc9c0\ub97c \uc5f4\uc9c0 \ubabb\ud568
-IPChecker.external.timeout=\uc2dc\uac04\uc744 \ub118\uacbc\uc2b5\ub2c8\ub2e4.
+IPChecker.external.httpinvalidresponse=\uc798\ubabb\ub41c HTTP \uc751\ub2f5
+IPChecker.external.loadingwebpage=\uc6f9 \ud398\uc774\uc9c0 \uc5ec\ub294 \uc911
+IPChecker.external.analysingresponse=\uc751\ub2f5 \ubd84\uc11d \uc911
+IPChecker.external.addressextracted=\ucd94\ucd9c\ud55c IP \uc8fc\uc18c
+IPChecker.external.httploadfail=\ud398\uc774\uc9c0 \ubd88\ub7ec\uc624\uae30 \uc2e4\ud328
+IPChecker.external.timeout=\uc2dc\uac04 \uc81c\ud55c\uc5d0 \ub3c4\ub2ec
 IPChecker.external.ipnotfound=IP \uc8fc\uc18c\ub97c \ucc3e\uc9c0 \ubabb\ud568
 ConfigView.section.tracker.pollintervalmin=\ucd5c\uc18c
 ConfigView.section.tracker.pollintervalmax=\ucd5c\ub300
-ConfigView.section.tracker.pollintervalincby=\ub2e4\uc74c \uc218\ub9cc\ud07c\uc529 \ub29a
-ConfigView.section.tracker.pollintervalincper=\ub2e4\uc74c \uc218\uc758 \uc811\uc18d \ucef4\ud4e8\ud130\ub9c8\ub2e4
+ConfigView.section.tracker.pollintervalincby=\ub2e4\uc74c\ub9cc\ud07c \uc99d\uac00:
+ConfigView.section.tracker.pollintervalincper='n' \ud074\ub77c\uc774\uc5b8\ud2b8\ub9c8\ub2e4
 splash.loadingImages=\uc774\ubbf8\uc9c0\ub97c \ubd88\ub7ec\uc624\uace0 \uc788\uc74c
 splash.initializeGui=\uc8fc \ucc3d\uc744 \ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
 splash.openViews=\ubcf4\uc784\uc0c8\ub97c \uc5f4\uace0 \uc788\uc74c
-splash.plugin=\ucd94\uac00\uae30\ub2a5\uc744 \uc2dc\uc791\ud558\uace0 \uc788\uc74c: 
-configureWizard.nat.tooManyPorts=\uac80\uc0ac\ud560 \ud3ec\ud2b8\uac00 \ub108\ubb34 \ub9ce\uc74c (\ucd5c\ub300 9)
-ConfigView.section.color=\ube5b\uae54 \uad6c\uc131\ud45c
-MyTorrentsView.menu.publish=\ubc1c\ud589..(&P)
-MyTrackerView.status.published=\ubc1c\ud589
-MyTrackerView.completed=\ub9c8\uce68
-MainWindow.menu.file.open.torrentnodefault=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c... (\uae30\ubcf8 \uc800\uc7a5 \uc5c6\uc74c)
-wizard.comment=\ub367\ub9d0
-ConfigView.label.movetorrent=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc62e\uae40
-ConfigView.label.movepartialdownloads=\uba87\uba87 \ud30c\uc77c\uc774 "\ub2e4\uc6b4\ub85c\ub4dc \ud558\uc9c0 \ub9c8\uc138\uc694"\ub85c \ub418\uc5b4\uc788\uc5b4\ub3c4 \uc62e\uae40
-ConfigView.section.file.decoder.label=\uace0\ub978 \uac83\uc5d0 \ud544\uc694\ud560 \ub54c\uc758 \uae30\ubcf8 \ud1a0\ub7f0\ud2b8 \uc778\ucf54\ub529
-ConfigView.section.file.decoder.nodecoder=\uace0\ub974\uc9c0 \uc54a\uc74c
-IPChecker.external.service.no-ip.description=\uc720\ub3d9 \ubc0f \uace0\uc815 DNS \uc11c\ube44\uc2a4 \uacf5\uae09\uc790\n(\uc790\uc720\ub85c\uc774 \uc4f8 \uc218 \uc5c6\ub294 '\uc8fc\uc18c \uac80\uc0ac' \uc11c\ube44\uc2a4)
-ConfigView.section.tracker.publicenable=\uc678\ubd80 \ud1a0\ub7f0\ud2b8 \uc791\ub3d9
-ConfigView.label.playdownloadspeech=\ub0b4\ub824\ubc1b\uae30\uac00 \ub05d\ub0a0 \ub54c \uc6b8\ub9bc
-ConfigView.label.playdownloadspeech.info=\uc6b8\ub9bc \uc11c\ube44\uc2a4\ub294 \uc9c0\uae08 \uc601\uc5b4\ub85c \uac00\uc7a5 \uc798 \uc791\ub3d9\ud569\ub2c8\ub2e4
+splash.plugin=\ucd94\uac00\uae30\ub2a5\uc744 \uc2dc\uc791\ud558\uace0 \uc788\uc74c:
+configureWizard.nat.tooManyPorts=\ud14c\uc2a4\ud2b8\ud560 \ud3ec\ud2b8\uac00 \ub108\ubb34 \ub9ce\uc74c (\ucd5c\ub300 9)
+ConfigView.section.color=\uc0c9\uc0c1\ud45c
+MyTorrentsView.menu.publish=\ubc1c\ud589(&L)...
+MyTrackerView.status.published=\uac8c\uc2dc\ub428
+MyTrackerView.completed=\uc644\ub8cc\ub428
+MainWindow.menu.file.open.torrentnodefault=\ud1a0\ub80c\ud2b8 \ud30c\uc77c... (\uc800\uc7a5 \uc548\ud568)
+wizard.comment=\uc8fc\uc11d
+ConfigView.label.movetorrent=.torrent \uc774\ub3d9
+ConfigView.label.movepartialdownloads=\uc77c\ubd80 "\ub2e4\uc6b4\ub85c\ub4dc \ud558\uc9c0 \ub9d0 \uac83"\uc73c\ub85c \ud45c\uc2dc\ub41c \ud30c\uc77c\uc774 \uc788\uc5b4\ub3c4 \uc774\ub3d9
+ConfigView.label.subdir_is_in_default=\uae30\ubcf8 \ub514\ub809\ud130\ub9ac\uc5d0 \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294\uc9c0\ub97c \uace0\ub824\ud560 \ub54c, \ud30c\uc77c\uc744 \ud3ec\ud568\ud55c \ud558\uc704 \ub514\ub809\ud130\ub9ac\ub3c4 \uace0\ub824
+ConfigView.section.file.decoder.label=\uc120\ud0dd\uc774 \ud544\uc694\ud560 \ub54c \uae30\ubcf8 \ud1a0\ub80c\ud2b8 \uc778\ucf54\ub529
+ConfigView.section.file.decoder.nodecoder=\uc5c6\uc74c
+IPChecker.external.service.no-ip.description=\uc720\ub3d9 \ubc0f \uace0\uc815 DNS \uc11c\ube44\uc2a4 \uacf5\uae09\uc790\n(\uc790\uc720\ub86d\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 '\uc8fc\uc18c \uac80\uc0ac' \uc11c\ube44\uc2a4\ub294 \uc5c6\uc74c)
+ConfigView.section.tracker.publicenable=\uc678\ubd80 \ud1a0\ub80c\ud2b8 \ud65c\uc131\ud654
+ConfigView.label.playdownloadspeech=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \ub05d\ub098\uba74 \ub9d0\ud558\uae30
+ConfigView.label.playdownloadspeech.info=\ub9d0\ud558\uae30 \uc11c\ube44\uc2a4\ub294 \ud604\uc7ac \uc601\uc5b4\ub85c \uac00\uc7a5 \uc798 \ub3d9\uc791\ud568
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=\uc4f8 \uc218 \uc788\ub294 \ub0b1\ub0b1\uc758 \uc870\uac01 \uc218\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.\n\uc624\ub978\ucabd\uc758 \uc218\uac00 1\ubcf4\ub2e4 \uc791\uc73c\uba74 \uc644\uc804\ud55c \ud30c\uc77c\uc744 \ubcfc \uc218 \uc5c6\uace0 (\ub0b4\ub824\ubc1b\uae30\ub97c \ub9c8\uce60 \uc218) \uc5c6\uc744 \uac83\uc785\ub2c8\ub2e4.
-GeneralView.label.trackerurl.tooltip=\ub354\ub4ec\uc774 \uc54c\ub9bc \uc8fc\uc18c(Announce URL)\ub97c \ud074\ub9bd\ubcf4\ub4dc\ub85c \ubcf5\uc0ac\ud558\ub824\uba74 \ud074\ub9ad
-GeneralView.label.trackerurlopen.tooltip=\ub354\ub4ec\uc774 \uba54\uc778 \ud398\uc774\uc9c0\ub97c \uc5f4\ub824\uba74 \ud074\ub9ad
+GeneralView.label.status.pieces_available.tooltip=\uac01 \uc870\uac01 \ubcc4\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ubcf5\uc0ac\ubcf8\uc758 \uc218\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4.\n\uc6b0\uce21\uc758 \uc218\uac00 1\ubcf4\ub2e4 \uc791\uc73c\uba74 \uc0ac\uc6a9\uc790\uac00 \ud574\ub2f9 \ud30c\uc77c\uc758 \uc628\uc804\ud55c \ubcf5\uc0ac\ubcf8\uc744 \ubcf4\uace0 \uc788\ub294 \uac83\uc774 \uc544\ub2d8\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4 (\uc774 \uacbd\uc6b0 \ub2e4\uc6b4\ub85c\ub4d [...]
+GeneralView.label.trackerurl.tooltip=\uc54c\ub9bc URL\uc744 \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac\ud558\ub824\uba74 \ud074\ub9ad
+GeneralView.label.trackerurlopen.tooltip=\ud2b8\ub798\ucee4 \uba54\uc778 \ud398\uc774\uc9c0\ub97c \uc5f4\ub824\uba74 \ud074\ub9ad
 #
 # 2.0.4.4
 #
 ConfigView.section.style.guiUpdate=\ub2e4\uc74c \uc2dc\uac04\ub9c8\ub2e4 GUI \uc5c5\ub370\uc774\ud2b8
-ConfigView.section.style.graphicsUpdate=\ub2e4\uc74c \uc218\uc758 GUI \uc5c5\ub370\uc774\ud2b8\ub9c8\ub2e4 \uadf8\ub798\ud53d \ub9c9\ub300 \uc5c5\ub370\uc774\ud2b8
-ConfigView.section.style.reOrderDelay=\ub2e4\uc74c \uc218\uc758 GUI \uc5c5\ub370\uc774\ud2b8\ub9c8\ub2e4 \ubaa9\ub85d \ub2e4\uc2dc \uc815\ub82c [0: \uacb0\ucf54 \ud558\uc9c0 \uc54a\uc74c]
-ConfigView.section.style.reOrderDelay.never=\uacb0\ucf54 \ud558\uc9c0 \uc54a\uc74c
-ConfigView.section.logging=\uae30\ub85d \ub0a8\uae30\uae30
-ConfigView.section.logging.enable=\ud30c\uc77c\ub85c \uae30\ub85d \ub0a8\uae30\uae30 \uc791\ub3d9
-ConfigView.section.logging.logdir=\ud30c\uc77c \ud3f4\ub354 \uae30\ub85d
-ConfigView.section.logging.choosedefaultsavepath=\uc800\uc7a5 \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-GeneralView.label.updatein.querying=\uc54c\uc544 \ubcf4\uace0 \uc788\uc74c...
-configureWizard.nat.sharePort=\ubaa8\ub4e0 \ud1a0\ub7f0\ud2b8\uc5d0 \ub2e8 \ud558\ub098\uc758 \uacf5\uc720\ub41c \ub4e4\uc5b4\uc624\ub294 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9
-ConfigView.section.logging.maxsize=\uae30\ub85d \ud30c\uc77c \ucd5c\ub300 \ud06c\uae30
-ConfigView.section.tracker.passwordenableweb=\ub354\ub4ec\uc774 \uc6f9\uc5d0 \uc554\ud638 \uc791\ub3d9
-ConfigView.section.tracker.passwordenabletorrent=\ud1a0\ub7f0\ud2b8\uc5d0 \uc554\ud638 \uc791\ub3d9
+ConfigView.section.style.inactiveUpdate=GUI\ub97c 'N'\ubc88 \uc5c5\ub370\uc774\ud2b8\ud560 \ub54c\ub9c8\ub2e4 \ud65c\uc131\ub418\uc9c0 \uc54a\uc740 \uba54\uc778 \ucc3d\uc744 \uc5c5\ub370\uc774\ud2b8
+ConfigView.section.style.graphicsUpdate=GUI\ub97c 'N'\ubc88 \uc5c5\ub370\uc774\ud2b8\ud560 \ub54c\ub9c8\ub2e4 \uadf8\ub798\ud53d \ub9c9\ub300 \uc5c5\ub370\uc774\ud2b8
+ConfigView.section.style.reOrderDelay=GUI\ub97c 'N'\ubc88 \uc5c5\ub370\uc774\ud2b8\ud560 \ub54c\ub9c8\ub2e4 \ud14c\uc774\ube14 \uc7ac\uc815\ub82c [0: \ud558\uc9c0\uc54a\uc74c]
+ConfigView.section.style.reOrderDelay.never=\ud558\uc9c0 \uc54a\uc74c
+ConfigView.section.logging=\ub85c\uae45
+ConfigView.section.logging.enable=\ud30c\uc77c\uc5d0 \ub85c\uadf8 \uc800\uc7a5 \ud65c\uc131\ud654
+ConfigView.section.logging.logdir=\ub85c\uadf8 \ud30c\uc77c \ub514\ub809\ud130\ub9ac
+ConfigView.section.logging.choosedefaultsavepath=\uc800\uc7a5 \ub514\ub809\ud130\ub9ac\ub97c \uc120\ud0dd\ud574\uc8fc\uc2ed\uc2dc\uc624
+GeneralView.label.updatein.querying=\uc870\ud68c \uc911...
+configureWizard.nat.sharePort=\ubaa8\ub4e0 \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud558\uc5ec \ub2e8\uc77c \uacf5\uc720 \ub4e4\uc5b4\uc624\ub294 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9
+ConfigView.section.logging.maxsize=\ucd5c\ub300 \ub85c\uadf8 \ud30c\uc77c \ud06c\uae30
+ConfigView.section.tracker.passwordenableweb=\ud2b8\ub798\ucee4 \uc6f9\uc5d0 \uc554\ud638 \ud65c\uc131\ud654
+ConfigView.section.tracker.passwordenabletorrent=\ud1a0\ub80c\ud2b8\uc5d0 \uc554\ud638 \ud65c\uc131\ud654
 ConfigView.section.tracker.username=\uc0ac\uc6a9\uc790 \uc774\ub984
 ConfigView.section.tracker.password=\uc554\ud638
-columnChooser.title=\ud45c\uc2dc\ud560 \uc138\ub85c\uc904\uc744 \uace0\ub974\uc2ed\uc2dc\uc624
-columnChooser.move=\ub2e4\uc2dc \uc815\ub9ac\ud558\ub824\uba74 \uc904\uc744 \ub044\uc2ed\uc2dc\uc624
+columnChooser.title=\ud45c\uc2dc\ud560 \uc5f4\uc744 \uc120\ud0dd
+columnChooser.move=\uc7ac\uc815\ub82c\ud558\ub824\uba74 \ud589\uc744 \ub4dc\ub798\uadf8
 columnChooser.apply=\uc801\uc6a9
-columnChooser.columnname=\uc138\ub85c\uc904 \uc774\ub984
+columnChooser.columnname=\uc5f4 \uc774\ub984
 columnChooser.columndescription=\uc124\uba85
-TableColumn.header.shareRatio=\uacf5\uc720 \ube44
-MyTorrentsView.menu.editTableColumns=\uc138\ub85c\uc904 \uad6c\uc131(&C)
+TableColumn.header.shareRatio=\uacf5\uc720 \ube44\uc728
+MyTorrentsView.menu.editTableColumns=\uc5f4 \uc124\uc815(&C)
 wizard.operationfailed=\uc791\uc5c5 \uc2e4\ud328
 authenticator.title=\uc778\uc99d \ud544\uc694
 authenticator.realm=\uc601\uc5ed
-authenticator.tracker=\ub354\ub4ec\uc774
+authenticator.tracker=\ud2b8\ub798\ucee4
 authenticator.user=\uc0ac\uc6a9\uc790 \uc774\ub984
 authenticator.password=\uc554\ud638
-ConfigView.label.allowSendVersion=\uc0c8 \ubc84\uc804\uc744 \uac80\uc0ac\ud558\ub294 \ub3d9\uc548 Vuze\uac00 \uc775\uba85\uc758 \ubc84\uc804 \ubc88\ud638\uc640 \uc784\uc758\uc758 \uc544\uc774\ub514\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud5c8\uc6a9
-wizard.hint.mode=\uadc0\ub754:\t\ud30c\uc77c\uc774\ub098 \ud3f4\ub354\ub97c \uace0\ub974\ub824\uba74 \uc774 \ub9c8\ubc95\uc0ac\uc5d0 \ud55c \uac1c \ud30c\uc77c\uc774\ub098 \ud3f4\ub354\ub97c\n\t\ub04c\uc5b4\ub2e4\uac00 \ub193\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-wizard.hint.file=\uadc0\ub754:\t\ub04c\uc5b4\ub2e4\uac00 \ub193\uae30\ub85c \ud55c \uac1c \ud30c\uc77c\uc744 \uace0\ub97c \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-wizard.hint.directory=\uadc0\ub754:\t\ub04c\uc5b4\ub2e4\uac00 \ub193\uae30\ub85c \ud55c \uac1c \ud3f4\ub354\ub97c \uace0\ub97c \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-MainWindow.menu.help.checkupdate=\uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac...(&C)
-TableColumn.header.down=\ub0b4\ub824\ubc1b\uc74c
-TableColumn.header.up=\uc62c\ub824\uc9d0
-ConfigView.section.tracker.passwordenabletorrent.info=\uc54c\ub9de\uc740 BitTorrent \uc811\uc18d \ud504\ub85c\uadf8\ub7a8\uc774 \uc788\uc5b4\uc57c \ud568 (\uc608 Vuze
-ConfigView.section.style.confirmationOnExit=\ub05d\ub0bc \ub54c \ud655\uc778 \uba54\uc138\uc9c0 \uc0c1\uc790 \ubcf4\uc774\uae30
-MainWindow.dialog.exitconfirmation.title=Vuze\ub97c \ub05d\ub0b4\uaca0\uc2b5\ub2c8\uae4c?
-MainWindow.dialog.exitconfirmation.text=Vuze\ub97c \uc815\ub9d0 \ub05d\ub0b4\uaca0\uc2b5\ub2c8\uae4c?
+ConfigView.label.allowSendVersion=\uc0c8 \ubc84\uc804\uc744 \uac80\uc0ac\ud558\ub294 \ub3d9\uc548 Vuze\uac00 \uc775\uba85\uc73c\ub85c \ubc84\uc804 \ubc88\ud638\uc640 \uc784\uc758 ID\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud5c8\uc6a9
+ConfigView.label.version.info.link=\ubc84\uc804 \uac80\uc0ac \uc11c\ubc84\uc5d0 \uc5b4\ub5a4 \ub370\uc774\ud130\uac00 \ubcf4\ub0b4\uc9c0\ub294\uc9c0\uc5d0 \ub300\ud55c \uc138\ubd80\uc0ac\ud56d\uc740 \uc5ec\uae30\ub97c \ubc29\ubb38
+wizard.hint.mode=\ud78c\ud2b8:\t\ud30c\uc77c\uc774\ub098 \ub514\ub809\ud130\ub9ac\ub97c \uc120\ud0dd\ud558\uae30\uc704\ud574 \uc774 \ub9c8\ubc95\uc0ac\uc5d0 \n\t\ub2e8\uc77c \ud30c\uc77c\uc774\ub098 \ub514\ub809\ud130\ub9ac\ub97c \ub04c\uc5b4\ub193\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+wizard.hint.file=\ud78c\ud2b8:\t\ub04c\uc5b4\ub193\uae30\ub85c \ub2e8\uc77c \ud30c\uc77c\uc744 \uc120\ud0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+wizard.hint.directory=\ud78c\ud2b8:\t\ub04c\uc5b4\ub193\uae30\ub85c \ub2e8\uc77c \ub514\ub809\ud130\ub9ac\ub97c \uc120\ud0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+MainWindow.menu.help.checkupdate=\uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac(&C)...
+TableColumn.header.down=\ub2e4\uc6b4\ub85c\ub4dc\ub428
+TableColumn.header.up=\uc5c5\ub85c\ub4dc\ub428
+ConfigView.section.tracker.passwordenabletorrent.info=\uc801\uc808\ud55c BitTorrent \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \ud544\uc694 (\uc608: Vuze)
+ConfigView.section.style.confirmationOnExit=\ub098\uac08 \ub54c \uc2b9\uc778 \ub300\ud654\uc0c1\uc790 \ubcf4\uc5ec\uc8fc\uae30
+MainWindow.dialog.exitconfirmation.title=Vuze \ub098\uac00\uae30
+MainWindow.dialog.exitconfirmation.text=\uc815\ub9d0\ub85c Vuze\uc5d0\uc11c \ub098\uac00\uc2dc\uaca0\uc2b5\ub2c8\uae4c
 SystemTray.menu.stopalltransfers=\ubaa8\ub4e0 \uc804\uc1a1 \uba48\ucda4(&A)
-TrayWindow.menu.stopalldownloads=\ubaa8\ub4e0 \ub0b4\ub824\ubc1b\uae30 \uba48\ucda4(&A)
-ConfigView.section.tracker.sslport.info=\ud55c\uacb0 \ub354\ud55c \uc815\ubcf4\ub294 \uc790\uc8fc \ubb3b\ub294 \ubb3c\uc74c\uc744 \ubcf4\uc2ed\uc2dc\uc694.
-wizard.tracker.ssl=SSL\uc744 \uc500
-ConfigView.label.playdownloadfinished=\ub0b4\ub824\ubc1b\uae30\uac00 \ub05d\ub0a0 \ub54c \uc18c\ub9ac\ub0b4\uae30
+TrayWindow.menu.stopalldownloads=\ubaa8\ub4e0 \ub2e4\uc6b4\ub85c\ub4dc \uc815\uc9c0(&A)
+ConfigView.section.tracker.sslport.info=\ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub294 FAQ\ub97c \ucc38\uace0
+wizard.tracker.ssl=SSL \uc0ac\uc6a9
+ConfigView.label.playdownloadfinished=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \ub05d\ub098\uba74 \uc0ac\uc6b4\ub4dc \uc7ac\uc0dd
+ConfigView.label.popupdownloadfinished=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \ub05d\ub098\uba74 \uacbd\ubcf4\ub97c \ud31d\uc5c5
+ConfigView.label.popupfilefinished=\ud30c\uc77c\uc774 \ub05d\ub098\uba74 \uacbd\ubcf4\ub97c \ud31d\uc5c5
 TableColumn.header.pieces=\uc870\uac01
-TableColumn.header.pieces.info=\uadf8\ub798\ud53d \ub9c9\ub300\ub294 \uc5b4\ub290 \uc870\uac01\uc744 \ub0b4\ub824\ubc1b\uc558\ub294\uc9c0 \ubcf4\uc5ec\uc90d\ub2c8\ub2e4.
-TableColumn.header.completion=\ub05d\ub9c8\uce68
-TableColumn.header.completion.info=\ub0b4\ub824\ubc1b\uc740 %\uc758 \uadf8\ub798\ud53d \ud45c\uc2dc
-ConfigView.section.style.showdownloadbasket=\ub0b4\ub824\ubc1b\uae30 \ubc14\uad6c\ub2c8 \ubcf4\uc774\uae30 (\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \ub04c\uc5b4\ub2e4\uac00 \ub193\uae30)
-ConfigView.section.style.alwaysShowTorrentFiles=\uc0c1\uc138 \uc815\ubcf4/\ud30c\uc77c\uc5d0 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c \ub298 \ubcf4\uc774\uae30
-wizard.multitracker=\ud1a0\ub7f0\ud2b8\uc5d0 \uc5ec\ub7ec \ub354\ub4ec\uc774 \uc815\ubcf4\ub97c \ub354\ud558\uae30
-wizard.multitracker.title=\uc5ec\ub7ec \ub354\ub4ec\uc774
-wizard.multitracker.configuration=\uc5ec\ub7ec \ub354\ub4ec\uc774 \uc124\uc815
-wizard.multitracker.new=\uc0c8\ub85c\uc6b4...
+TableColumn.header.pieces.info=\uadf8\ub798\ud53d \ub9c9\ub300\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5b4\ub290 \uc870\uac01\uc744 \ub2e4\uc6b4\ub85c\ub4dc \ud588\ub294\uc9c0 \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.completion=\uc644\uc131\ub3c4
+TableColumn.header.completion.info=\ub2e4\uc6b4\ub85c\ub4dc\ub41c %\ub97c \uadf8\ub798\ud53d\uc73c\ub85c \ud45c\uc2dc\ud569\ub2c8\ub2e4.
+ConfigView.section.style.showdownloadbasket=\ub2e4\uc6b4\ub85c\ub4dc \ubc14\uad6c\ub2c8 \ubcf4\uc5ec\uc8fc\uae30 (.torrent \ub04c\uc5b4 \ub193\uae30)
+ConfigView.section.style.alwaysShowTorrentFiles=\uc138\ubd80\uc0ac\ud56d/\ud30c\uc77c\uc5d0 \ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc744 \ud56d\uc0c1 \ubcf4\uc5ec\uc8fc\uae30
+wizard.multitracker=\ud1a0\ub80c\ud2b8\uc5d0 \ub2e4\uc911 \ud2b8\ub798\ucee4 \uc815\ubcf4 \ucd94\uac00
+wizard.multitracker.title=\ub2e4\uc911 \ud2b8\ub798\ucee4
+wizard.multitracker.configuration=\ub2e4\uc911 \ud2b8\ub808\ucee4 \uc124\uc815
+wizard.multitracker.new=\uc0c8\ub85c \ub9cc\ub4e4\uae30...
 wizard.multitracker.edit=\ud3b8\uc9d1...
-wizard.multitracker.delete=\uc9c0\uc6b0\uae30
-wizard.multitracker.group=\ub354\ub4ec\uc774 \ubb36\uc74c
-wizard.multitracker.edit.title=\uc5ec\ub7ec \ub354\ub4ec\uc774 \ud3b8\uc9d1\uae30
+wizard.multitracker.delete=\uc0ad\uc81c
+wizard.multitracker.group=\ud2b8\ub798\ucee4 \uadf8\ub8f9
+wizard.multitracker.edit.title=\ub2e4\uc911 \ud2b8\ub798\ucee4 \ud3b8\uc9d1\uae30
 wizard.multitracker.edit.name=\uc774\ub984
 wizard.multitracker.edit.save=\uc800\uc7a5
-wizard.multitracker.edit.newgroup=\uc0c8 \ubb36\uc74c
-wizard.multitracker.edit.deletegroup=\uc9c0\uc6b0\uae30
-wizard.multitracker.edit.newtracker=\uc0c8 \ub354\ub4ec\uc774
-wizard.multitracker.edit.deletetracker=\uc9c0\uc6b0\uae30
+wizard.multitracker.edit.newgroup=\uc0c8 \uadf8\ub8f9
+wizard.multitracker.edit.deletegroup=\uc0ad\uc81c
+wizard.multitracker.edit.newtracker=\uc0c8 \ud2b8\ub798\ucee4
+wizard.multitracker.edit.deletetracker=\uc0ad\uc81c
 wizard.multitracker.edit.edit=\ud3b8\uc9d1
-wizard.addingmt=\uc5ec\ub7ec \ub354\ub4ec\uc774 \uc815\ubcf4 \ub354\ud558\uace0 \uc788\uc74c
-wizard.multitracker.noannounce=\ub354\ub4ec\uc774 \uc54c\ub9bc \uc8fc\uc18c(Announce URL)\uac00 \ub354\ub4ec\uc774 \ubaa9\ub85d\uc5d0 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
-MyTorrentsView.menu.recheck=\uc5b5\uc9c0\ub85c \ub2e4\uc2dc \uac80\uc0ac(&K)
-iconBar.showDownloadBar.tooltip=\ub0b4\ub824\ubc1b\uae30 \ub9c9\ub300 \ubcf4\uc774\uae30
-iconBar.start.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub7f0\ud2b8 \uc2dc\uc791
-iconBar.stop.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub7f0\ud2b8 \uba48\ucda4
-iconBar.remove.tooltip=\uc9c0\uc6b0\uae30
-iconBar.openNoDefault.tooltip=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc5f4\uae30 (\uae30\ubcf8 \uc800\uc7a5 \uc5c6\uc74c)
-iconBar.openURL.tooltip=\uc8fc\uc18c \uc5f4\uae30
+wizard.addingmt=\ub2e4\uc911 \ud2b8\ub798\ucee4 \uc815\ubcf4 \ucd94\uac00 \uc911
+wizard.multitracker.noannounce=\uc54c\ub9bc URL\uc774 \ud2b8\ub798\ucee4 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc74c
+MyTorrentsView.menu.recheck=\uac15\uc81c \ub2e4\uc2dc \uac80\uc0ac(&K)
+iconBar.showDownloadBar.tooltip=\ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \ubcf4\uc5ec\uc8fc\uae30
+iconBar.start.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8 \uc2dc\uc791
+iconBar.stop.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8 \uc815\uc9c0
+iconBar.remove.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8 \uc81c\uac70
+iconBar.openNoDefault.tooltip=.torrent \ud30c\uc77c \uc5f4\uae30 (\uc800\uc7a5 \uc548\ud568)
+iconBar.openURL.tooltip=URL \uc5f4\uae30
 iconBar.openFolder.tooltip=\ud3f4\ub354 \uc5f4\uae30
-iconBar.new.tooltip=\ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4\uae30
-iconBar.up.tooltip=\uc704\ub85c \uc62e\uae40
-iconBar.down.tooltip=\uc544\ub798\ub85c \uc62e\uae40
-iconBar.run.tooltip=\uc5f4\uae30
+iconBar.new.tooltip=\ud1a0\ub80c\ud2b8 \uc0dd\uc131
+iconBar.up.tooltip=\uc704\ub85c \uc774\ub3d9
+iconBar.down.tooltip=\uc544\ub798\ub85c \uc774\ub3d9
+iconBar.run.tooltip=\uae30\ubcf8 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\uc744 \uc774\uc6a9\ud558\uc5ec \uc5f4\uae30
 iconBar.host.tooltip=\ud638\uc2a4\ud2b8
 iconBar.publish.tooltip=\ubc1c\ud589
-iconBar.editcolumns.tooltip=\uc138\ub85c\uc904 \uc124\uc815
-MyTorrentsView.menu.editTracker=\ub354\ub4ec\uc774 \uc8fc\uc18c \ud3b8\uc9d1(&E)
-GeneralView.menu.selectTracker=\uace0\ub974\uae30
+iconBar.editcolumns.tooltip=\uc5f4 \uc124\uc815
+MyTorrentsView.menu.editTracker=\ud2b8\ub798\ucee4 URL \ud3b8\uc9d1(&E)
+GeneralView.menu.selectTracker=\uc120\ud0dd
 ConfigView.section.stats.xslfile=XSL \ud30c\uc77c \uc774\ub984
-ConfigView.section.stats.xslfiledetails=\uc774\uac83\uc740 <?xml-stylesheet> \ud0dc\uadf8\ub97c \ud1b5\ud558\uc5ec\uc11c \ud1b5\uacc4 \ud30c\uc77c \ud5e4\ub354\uc5d0 \ub07c\uc6cc\uc9c8 \uac83\uc785\ub2c8\ub2e4.
+ConfigView.section.stats.xslfiledetails=\u2192 <?xml-stylesheet> \ud0dc\uadf8\ub97c \ud1b5\ud574 \ud1b5\uacc4 \ud30c\uc77c \ud574\ub354\uc5d0 \ud3ec\ud568\ub428
 ConfigView.label.savetorrentbackup=\ubc31\uc5c5 \uc800\uc7a5
-ConfigView.section.tracker.forceport=\uae30\ubcf8 \ud3ec\ud2b8\ub85c \uc678\ubd80 \ud1a0\ub7f0\ud2b8\ub97c \uc5b5\uc9c0\ub85c \ud638\uc2a4\ud2b8
-ConfigView.section.ipfilter.allow=\uc774 \ubc94\uc704 \ud5c8\uc6a9 (\uae30\ubcf8\uac12\uc740 \uac70\ubd80)
+ConfigView.section.tracker.forceport=\uae30\ubcf8 \ud3ec\ud2b8\ub85c \uc678\ubd80 \ud1a0\ub80c\ud2b8\uac00 \ud638\uc2a4\ud2b8 \ub418\ub3c4\ub85d \uac15\uc81c
+ConfigView.section.ipfilter.allow=\uc774 \ubc94\uc704\uc5d0 \ub300\ud574\uc11c *\ud5c8\uc6a9* (\uae30\ubcf8\uac12\uc740 *\uac70\ubd80*)
 ConfigView.section.ipfilter.list.inrange=\ubc94\uc704 \uc548\uc5d0 \uc788\uc74c
-ConfigView.section.ipfilter.list.notinrange=\uc544\ubb34 \ubc94\uc704\uc5d0\ub3c4 \uc788\uc9c0 \uc54a\uc74c
-ConfigView.section.ipfilter.list.title=\ub9c9\uc740 IP \ubaa9\ub85d
-ConfigView.label.allowsameip=\uac19\uc740 IP\ub85c\ubd80\ud130\uc758 \ub2e4\uc218 \uc5f0\uacb0 \ud5c8\uc6a9
-ConfigView.label.allowsameip.tooltip=\uc815\ub9d0 \ud544\uc694\ud560 \ub54c\ub9cc \uace0\ub974\uc2ed\uc2dc\uc694.\n(\uace0\ub974\uc9c0 \uc54a\uc558\uc744 \ub54c\ub294) \uc774\uac83\uc740 \uac70\uba38\ub9ac \ubc29\uc9c0\uc6a9 \uc785\ub2c8\ub2e4.
-ManagerItem.superseeding=\ub9ce\uc774 \ubfcc\ub9ac\uace0 \uc788\uc74c
-ConfigView.label.userSuperSeeding=\ub300\ub2e8\ud55c \ubfcc\ub9ac\uae30 \uc4f0\uae30
-PeersView.uniquepiece=\uc870\uac01 (\ub9ce\uc774 \ubfcc\ub9ac\uae30 \ubc29\uc2dd)
+ConfigView.section.ipfilter.list.notinrange=\uc5b4\ub5a4 \ubc94\uc704\uc5d0\ub3c4 \uc5c6\uc74c
+ConfigView.section.ipfilter.list.title=\ucc28\ub2e8\ub41c IP
+ConfigView.label.allowsameip=\ub3d9\uc77c\ud55c IP\uc5d0\uc11c \ub2e4\uc911 \uc5f0\uacb0 \ud5c8\uc6a9
+ConfigView.label.allowsameip.tooltip=*\ud544\uc694\ud55c* \uacbd\uc6b0\uc5d0\ub9cc \ud45c\uc2dc \ud558\uc2ed\uc2dc\uc624.\n\uc774 \uc635\uc158\uc740 (\uaebc\uc838\uc788\uc744 \uacbd\uc6b0) \ubc30\ud3ec\ud558\uc9c0\ub294 \uc54a\uace0 \ub2e4\uc6b4\ub85c\ub4dc\ub9cc \ud558\ub294 \ub9ac\uccd0\ub97c \ubc29\uc9c0\ud569\ub2c8\ub2e4.
+ManagerItem.superseeding=\uac15\ub825 \ubc30\ud3ec \uc911
+ConfigView.label.userSuperSeeding=\uac15\ub825 \ubc30\ud3ec \uc0ac\uc6a9
+PeersView.uniquepiece=\uc870\uac01 (\uac15\ub825 \ubc30\ud3ec \ubaa8\ub4dc)
 PeersView.uniquepiece.none=\uc5c6\uc74c
-PeersView.timetosend=\uc870\uac01\uc744 \ub2e4\uc2dc \ubcf4\ub0b4\ub294 \uc2dc\uac04 (\ub9ce\uc774 \ubfcc\ub9ac\uae30 \ubc29\uc2dd)
-ConfigView.section.style.addurlsilently=\uc7a0\uc790\ucf54 \uc9c0\ub098\uac04 \uc8fc\uc18c \uc5f4\uae30
-ConfigView.section.style.addurlsilently.tooltip=\uba54\uc138\uc9c0 \uc0c1\uc790\ub97c \ubc14\ub85c \uc5f4\uc9c0 \uc54a\uace0\uc11c \uc9c0\ub098\uac00\uac70\ub098 \ub5a8\uc5b4\ub728\ub9b0 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc8fc\uc18c\ub4e4\uc744 \uc800\uc808\ub85c \ub0b4\ub824\ubc1b\uae30\ud569\ub2c8\ub2e4.
-ConfigView.section.file.decoder.prompt=\uc778\ucf54\ub529 \uace0\ub97c \uc77c\uc774 \uc0dd\uae30\uba74 \ub298 \uc0dd\uac01\ub098\uac8c \ud568
-ConfigView.section.file.decoder.prompt.tooltip=\uc778\ucf54\ub529 \uace0\ub974\uae30\ub97c \uc4f8 \uc218 \uc788\uc744 \ub54c \uba54\uc138\uc9c0 \uc0c1\uc790\ub97c \ub298 \ubcf4\uc774\uae30
+PeersView.timetosend=\uc870\uac01\uc744 \ub2e4\uc2dc \ubcf4\ub0b4\ub294 \uc2dc\uac04 (\uac15\ub825 \ubc30\ud3ec \ubaa8\ub4dc)
+ConfigView.section.style.addurlsilently=\ub118\uaca8\uc9c4 URL\uc744 \uc870\uc6a9\ud788 \uc5f4\uae30
+ConfigView.section.style.addurlsilently.tooltip=\ub118\uaca8\uc9c0\uac70\ub098 \ub5a8\uc5b4\ub728\ub9b0 .torrent URL\uc744 \uc5f4\uae30 \ub300\ud654\uc0c1\uc790\ub97c \ubcf4\uc5ec\uc8fc\uc9c0 \uc54a\uace0 \uc790\ub3d9\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc \ud569\ub2c8\ub2e4.
+ConfigView.section.file.decoder.prompt=\uc778\ucf54\ub529 \uc120\ud0dd\uc774 \uac00\ub2a5\ud560 \uacbd\uc6b0 \ud56d\uc0c1 \ubb3c\uc5b4\ubcf4\uae30
+ConfigView.section.file.decoder.prompt.tooltip=\uc778\ucf54\ub529 \uc120\ud0dd\uc774 \uac00\ub2a5\ud560 \uacbd\uc6b0 \ud56d\uc0c1 \ub300\ud654\uc0c1\uc790 \ubcf4\uc5ec\uc8fc\uae30
 MyTorrentsView.menu.moveTop=\ub9e8 \uc704(&T)
 MyTorrentsView.menu.moveEnd=\ub9e8 \uc544\ub798(&B)
-ConfigView.label.moveonlyusingdefaultsave=\uae30\ubcf8 \ub370\uc774\ud130 \ud3f4\ub354\uc5d0 \uc788\uc744 \ub54c\ub9cc
-ConfigView.label.moveonlyusingdefaultsave.tooltip=\ub0b4\ub824\ubc1b\uae30 \uc790\ub8cc\uac00 \uae30\ubcf8 \ub370\uc774\ud130 \ud3f4\ub354\uc5d0 \uc788\uc744 \ub54c\ub9cc \uc62e\uae40
-ConfigView.label.watchtorrentfolder=\uc0c8 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \uc800\uc808\ub85c \ub4e4\uc5ec\uc624\uae30
-ConfigView.label.watchtorrentfolder.tooltip=\uc0c8 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \uc815\uae30\uc801\uc73c\ub85c \ucc3e\uc74c
-ConfigView.label.watchtorrentfolderinterval=\ud2c8
-ConfigView.label.watchtorrentfolderinterval.tooltip=\ud3f4\ub354\ub97c \ub2e4\uc2dc \ud6d1\uc744 \ub54c\uae4c\uc9c0 \uc7a0\uc2dc \uba48\ucda4
-ConfigView.dialog.choosewatchtorrentfolderpath=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \ub4e4\uc5ec\uc62c \ud3f4\ub354\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-ConfigView.label.startwatchedtorrentsstopped=\uba48\ucd98 \ucc44\ub85c \uc2dc\uc791
-ConfigView.label.startwatchedtorrentsstopped.tooltip=\uba48\ucd98 \uc0c1\ud0dc\ub85c \uc0c8 \ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 \ub354\ud558\uae30
-ConfigView.section.plugins=\ucd94\uac00\uae30\ub2a5
+ConfigView.label.moveonlyusingdefaultsave=\uae30\ubcf8 \ub370\uc774\ud130 \ub514\ub809\ud130\ub9ac\uc5d0 \uc788\uc744 \ub54c\ub9cc
+ConfigView.label.moveonlyusingdefaultsave.tooltip=\ub2e4\uc6b4\ub85c\ub4dc\ud55c \ub370\uc774\ud130\uac00 \uae30\ubcf8 \ub370\uc774\ud130 \ub514\ub809\ud130\ub9ac\uc5d0 \uc788\uc744 \ub54c\ub9cc \uc774\ub3d9
+ConfigView.label.watchtorrentfolder=\uc790\ub3d9\uc73c\ub85c \uc0c8 .torrent \uac00\uc838\uc624\uae30
+ConfigView.label.watchtorrentfolder.tooltip=\uc815\uae30\uc801\uc73c\ub85c \uc0c8 .torrent\ub97c \ucc3e\uc2b5\ub2c8\ub2e4.
+ConfigView.label.watchtorrentfolderinterval=\uac04\uaca9
+ConfigView.label.watchtorrentfolderinterval.tooltip=\ud3f4\ub354\uac00 \ub2e4\uc2dc \uac80\uc0c9\ub420 \ub54c\uae4c\uc9c0 \uc77c\uc2dc\uc815\uc9c0
+ConfigView.dialog.choosewatchtorrentfolderpath=.torrent \uac00\uc838\uc624\uae30 \ub514\ub809\ud130\ub9ac \uc120\ud0dd
+ConfigView.label.startwatchedtorrentsstopped=\uc815\uc9c0\ub41c \uc0c1\ud0dc\ub85c \uc2dc\uc791
+ConfigView.label.startwatchedtorrentsstopped.tooltip=*\uc911\uc9c0\ub428* \uc0c1\ud0dc\uc5d0\uc11c \uc0c8 .torrent \ucd94\uac00
+ConfigView.section.plugins=\ud50c\ub7ec\uadf8\uc778
 wizard.maketorrent.filesize=\ud30c\uc77c \ud06c\uae30
 wizard.maketorrent.piececount=\uc870\uac01 \uc218
 wizard.maketorrent.piecesize=\uc870\uac01 \ud06c\uae30
 wizard.maketorrent.auto=\uc790\ub3d9
 MainWindow.menu.view.stats=\ud1b5\uacc4(&S)
-MainWindow.menu.view.stats.keybinding=\uba54\ud0c0+5
 SpeedView.title.full=\ud65c\ub3d9
-SpeedView.downloadSpeed.title=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4
-SpeedView.uploadSpeed.title=\uc62c\ub9ac\uae30 \uc18d\ub3c4
-ConfigView.section.style.useSIUnits=\uad6d\uc81c \ud1b5\uc77c \ub2e8\uc704\uacc4 \ub2e8\uc704\ub97c \uc500 (KB -> KiB \ub4e4)
-iconBar.top.tooltip=\ub9e8 \uc704\ub85c \uc62e\uae40
-iconBar.bottom.tooltip=\ub9e8 \uc544\ub798\ub85c \uc62e\uae40
-TableColumn.header.health=\ud1a0\ub7f0\ud2b8 \uc0c1\ud0dc
-MyTorrentsView.menu.health=\ud1a0\ub7f0\ud2b8 \uc0c1\ud0dc \uc815\ubcf4
-health.explain.grey=\ud1a0\ub7f0\ud2b8\uac00 \ub3cc\uc544\uac00\uace0 \uc788\uc9c0 \uc54a\ub294 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.(\ub0b4\ub824\ubc1b\uae30 \ub610\ub294 \uc62c\ub9ac\uae30)
-health.explain.red=\ub0b4\ub824\ubc1b\uae30\ud558\uace0 \uc788\uc73c\uba74\uc11c \uc544\ubb34 \ub3d9\ub8cc\uc5d0\ub3c4 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc740 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.
-health.explain.blue=\ubfcc\ub9ac\uace0 \uc788\uc73c\uba74 \uc544\uc9c1 \ud55c \ub3d9\ub8cc\uc5d0\ub3c4 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc740 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.\n\ub0b4\ub824\ubc1b\uae30\ud558\uace0 \uc788\uc73c\uba74 \uba87\uba87 \ub3d9\ub8cc\ub4e4\uc5d0 \uc5f0\uacb0\ub418\uc5c8\uc9c0\ub9cc \ub354\ub4ec\uc774\uac00 \uace0\uc7a5\uc774 \ub09c \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.
-health.explain.yellow=\ub354\ub4ec\uc774\ub294 \uad1c\ucc2e\uace0 \ub3d9\ub8cc\ub4e4\uc5d0 \uc5f0\uacb0\ub418\uc5c8\uc9c0\ub9cc \uc544\ubb34 \uc6d0\uaca9 \uc5f0\uacb0\ub3c4 \uc5c6\ub294 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.\n\ud1a0\ub7f0\ud2b8\uac00 \uc904\uace7 \ub178\ub780 \uc0c1\ud0dc\uc5d0 \uba38\ubb34\ub974\uace0 \uc788\uc73c\uba74 NAT \ubb38\uc81c\uc77c \uac83\uc785\ub2c8\ub2e4.
-health.explain.green=\ubaa8\ub450 \ud6cc\ub96d\ud558\uac8c \ub418\uace0 \uc788\ub294 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.
-ConfigView.section.style.alwaysRefreshMyTorrents=\ub0b4 \ud1a0\ub7f0\ud2b8 \ub298 \uc0c8\ub85c \uace0\uce68
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=\uc774 \uc120\ud0dd\uc0ac\ud56d\uc740 \ub098\ud0c0\ub098\uc9c0 \uc54a\ub354\ub77c\ub3c4 \ub0b4 \ud1a0\ub7f0\ud2b8 \ubcf4\uae30\ub97c \uc0c8\ub85c \uace0\uce60 \uac83\uc785\ub2c8\ub2e4. (mIRC \ucd94\uac00\uae30\ub2a5\uc5d0 \uc4f8\ubaa8 \uc788\uc74c)
+SpeedView.downloadSpeed.title=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4
+SpeedView.uploadSpeed.title=\uc5c5\ub85c\ub4dc \uc18d\ub3c4
+ConfigView.section.style.useSIUnits=IEC \ub2e8\uc704\ub97c \uc0ac\uc6a9 (KB \u2192 KiB, \ub4f1)
+iconBar.top.tooltip=\ub9e8 \uc704\ub85c \uc774\ub3d9
+iconBar.bottom.tooltip=\ub9e8 \uc544\ub798\ub85c \uc774\ub3d9
+TableColumn.header.health=\ud1a0\ub80c\ud2b8 \uc0c1\ud0dc
+MyTorrentsView.menu.health=\ud1a0\ub80c\ud2b8 \uc0c1\ud0dc \uc815\ubcf4
+health.explain.grey=\ud1a0\ub80c\ud2b8\uac00 (\ub2e4\uc6b4\ub85c\ub4dc \ub610\ub294 \uc5c5\ub85c\ub4dc\ub97c) \uc2e4\ud589 \uc911\uc774 \uc544\ub2d8\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+health.explain.red=\ub2e4\uc6b4\ub85c\ub4dc \uc911 \uc5b4\ub5a4 \ud53c\uc5b4\uc640\ub3c4 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc558\uc74c\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+health.explain.blue=\ubc30\ud3ec \uc911\uc77c \ub54c, \uc5b4\ub5a4 \ud53c\uc5b4\uc640\ub3c4 \uc544\uc9c1 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc558\uc74c\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.\n\ub2e4\uc6b4\ub85c\ub4dc \uc911\uc77c \ub54c, \uc77c\ubd80 \ud53c\uc5b4\uc640 \uc5f0\uacb0\uc740 \ub418\uc5c8\uc73c\ub098 \ud2b8\ub798\ucee4\uac00 \ub2e4\uc6b4\ub418\uc5c8\uc74c\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+health.explain.yellow=\ud2b8\ub798\ucee4\uac00 \uc815\uc0c1\uc774\uace0 \ud53c\uc5b4\uc640 \uc5f0\uacb0\uc774 \ub418\uc5c8\uc9c0\ub9cc \uc6d0\uaca9\uc5d0\uc11c\uc758 \uc5f0\uacb0\uc774 \ud558\ub098\ub3c4 \uc5c6\uc74c\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.\n\uc774 \uc0c1\ud0dc\uac00 \ud56d\uc0c1 \uc9c0\uc18d\ub41c\ub2e4\uba74 NAT \ubb38\uc81c\uac00 \uc788\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+health.explain.green=\ubaa8\ub4e0 \uac83\uc774 \uc815\uc0c1\uc784\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+ConfigView.section.style.alwaysRefreshMyTorrents=\ud56d\uc0c1 \ub0b4 \ud1a0\ub80c\ud2b8 \uc0c8\ub85c\uace0\uce68
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=\uc774 \uc635\uc158\uc740 \ud45c\uc2dc\ub418\uc9c0 \uc54a\uace0 \uc788\ub294 \uc0c1\ud669\uc5d0\uc11c\ub3c4 \ub0b4 \ud1a0\ub80c\ud2b8 \ubcf4\uae30\ub97c \uacc4\uc18d \uc0c8\ub85c \uace0\uce68\ud569\ub2c8\ub2e4. (\uc77c\ubd80 mirc \ud50c\ub7ec\uadf8\uc778\uc5d0 \ub300\ud574 \uc720\uc6a9\ud568)
 #
 #2.0.7.0
 #
@@ -725,485 +729,478 @@ security.certtruster.issuedby=\ubc1c\uae09\uc790:
 security.certtruster.prompt=\uc2e0\ub8b0\ud558\uaca0\uc2b5\ub2c8\uae4c?
 security.certtruster.yes=\uc608
 security.certtruster.no=\uc544\ub2c8\uc624
-ConfigView.section.tracker.torrentsperpage=\ud398\uc774\uc9c0\ub9c8\ub2e4 \ud1a0\ub7f0\ud2b8\uac00 \uc5bc\ub9c8\ub098 \uc788\uc2b5\ub2c8\uae4c? [0: \ubb34\uc81c\ud55c]
-MainWindow.menu.file.share=\uacf5\uc720(&S)
-MainWindow.menu.file.share.file=\ud30c\uc77c...(&F)
-MainWindow.menu.file.share.dir=\ud3f4\ub354...(&O)
-MainWindow.menu.file.share.dircontents=\ud3f4\ub354 \ub0b4\uc6a9...(&C)
-MainWindow.menu.file.share.dircontentsrecursive=\ud3f4\ub354 \ub0b4\uc6a9... (\ub418\ud480\uc774)(&R)
-MainWindow.dialog.share.sharefile=\uacf5\uc720\ud560 \ud30c\uc77c \uace0\ub974\uae30
-MainWindow.dialog.share.sharedir=\uacf5\uc720\ud560 \ud3f4\ub354 \uace0\ub974\uae30
-MainWindow.dialog.share.sharedircontents=\uacf5\uc720\ud560 \ud3f4\ub354 \ub0b4\uc6a9 \uace0\ub974\uae30
-MainWindow.dialog.share.sharedircontents.recursive=\ub418\ud480\uc774
-globalmanager.download.remove.veto=\uc9c0\uc6b0\uae30\uac00 \uac70\ubd80\ub428
-plugin.sharing.download.remove.veto=\uc774 \ub0b4\ub824\ubc1b\uae30\ub294 \uacf5\uc720\ub418\uace0 \uc788\ub294 \uc790\uc6d0\uc758 \uacb0\uacfc\uc785\ub2c8\ub2e4.\n\ub0b4\ub824\ubc1b\uae30\ub97c \uc9c0\uc6b0\ub824\uba74 \uad00\uacc4\ub41c \uacf5\uc720\ub97c \uc9c0\uc6b0\uc2ed\uc2dc\uc694.
-ConfigView.section.tracker.main=\uc8fc\uc694 \ubd80\ubd84
+ConfigView.section.tracker.torrentsperpage=\ud398\uc774\uc9c0 \ubcc4\ub85c \uba87 \uac1c\uc758 \ud1a0\ub80c\ud2b8 ? [0: \ubb34\uc81c\ud55c]
+MainWindow.menu.file.share=\uace0\uc804\uc2dd \uacf5\uc720(&S)
+MainWindow.menu.file.share.file=\ud30c\uc77c(&F)...
+MainWindow.menu.file.share.dir=\ud3f4\ub354(&O)...
+MainWindow.menu.file.share.dircontents=\ud3f4\ub354 \ub0b4\uc6a9(&C)...
+MainWindow.menu.file.share.dircontentsrecursive=\ud3f4\ub354 \ub0b4\uc6a9(&R)... (\ud558\uc704 \ub514\ub809\ud130\ub9ac \ud3ec\ud568)
+MainWindow.dialog.share.sharefile=\uacf5\uc720\ud560 \ud30c\uc77c \uc120\ud0dd
+MainWindow.dialog.share.sharedir=\uacf5\uc720\ud560 \ud3f4\ub354 \uc120\ud0dd
+MainWindow.dialog.share.sharedircontents=\uacf5\uc720\ud560 \ud3f4\ub354 \ub0b4\uc6a9 \uc120\ud0dd
+MainWindow.dialog.share.sharedircontents.recursive=\ud558\uc704 \ub514\ub809\ud130\ub9ac \ud3ec\ud568
+globalmanager.download.remove.veto=\uc81c\uac70 \ub3d9\uc791\uc774 \uac70\ubd80\ub428
+plugin.sharing.download.remove.veto=\uc774 \ub2e4\uc6b4\ub85c\ub4dc\ub294 \uace0\uc804\uc2dd\uc73c\ub85c \uacf5\uc720\ub41c \uc790\uc6d0\uc5d0\uc11c \uae30\uc778\ub41c \uac83\uc785\ub2c8\ub2e4.\n\ub2e4\uc6b4\ub85c\ub4dc\ub97c \uc81c\uac70\ud558\ub824\uba74 \uace0\uc804\uc2dd \uacf5\uc720 \uc5f0\ub3d9\uc744 \uc81c\uac70\ud558\uc2ed\uc2dc\uc624: \ub3c4\uad6c\u2192\ub0b4 \uace0\uc804\uc2dd \uacf5\uc720.
+ConfigView.section.tracker.main=\uc8fc
 ConfigView.section.tracker.web=\uc6f9
-ConfigView.label.prioritizefirstpiece=\ud30c\uc77c \uccab \uc870\uac01\uc744 \uc6b0\uc120\uc2dc\ud0b4
-ConfigView.label.prioritizefirstpiece.tooltip=\uc2dc\uc791\ud560 \ub54c \ud30c\uc77c\uc758 \ub9e8 \ucc98\uc74c\ubd80\ud130 \ub0b4\ub824\ubc1b\uae30\ud558\ub3c4\ub85d \ud569\ub2c8\ub2e4.\n\uc77c\ucc0c\uac10\uce58 \ubbf8\ub9ac\ubcf4\uae30\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ConfigView.section.file.confirm_data_delete=\ub370\uc774\ud130\ub97c \uc9c0\uc6b8 \ub54c \ud655\uc778
-ConfigView.section.file.confirm_data_delete.tooltip='\uc9c0\uc6b0\uace0 \ub098\uc11c \u2026\u2026 \uc9c0\uc6b0\uae30'\ud560 \ub54c \ub370\uc774\ud130 \uc9c0\uc6b0\uae30 \ud655\uc778
-TrayWindow.menu.startalldownloads=\ubaa8\ub4e0\ub0b4\ub824\ubc1b\uae30 \uc2dc\uc791
+ConfigView.label.prioritizefirstpiece=\ud30c\uc77c\uc758 \uccab \uc870\uac01\uacfc \ub05d \uc870\uac01\uc5d0 \uc6b0\uc120\uc21c\uc704 \ubd80\uc5ec
+ConfigView.label.prioritizefirstpiece.tooltip=\ud30c\uc77c\uc758 \ub9e8 \ucc98\uc74c\uacfc \ub9e8 \ub05d\uc744 \uba3c\uc800 \ub2e4\uc6b4\ub85c\ub4dc\ud558\ub3c4\ub85d \ud569\ub2c8\ub2e4.\n\uc774\ub978 \ubbf8\ub9ac\ubcf4\uae30 \uc9c0\uc6d0\uc744 \uc704\ud55c \uac83\uc785\ub2c8\ub2e4.
+ConfigView.section.file.delete.include_files_outside_save_dir=\ub370\uc774\ud130\ub97c \uc0ad\uc81c\ud560 \ub54c \ud1a0\ub80c\ud2b8 \uc800\uc7a5 \ub514\ub809\ud130\ub9ac \uc678\ubd80\uc5d0 \uc5f0\uacb0\ub41c \ud30c\uc77c\ub3c4 \uac19\uc774 \uc81c\uac70\ub418\ub3c4\ub85d \ud5c8\uc6a9
+TrayWindow.menu.startalldownloads=\ubaa8\ub4e0 \ub2e4\uc6b4\ub85c\ub4dc \uc2dc\uc791
 SystemTray.menu.startalltransfers=\ubaa8\ub4e0 \uc804\uc1a1 \uc2dc\uc791
-sharing.progress.title=\uacf5\uc720 \uc9c4\ud589
+sharing.progress.title=\uace0\uc804\uc2dd \uacf5\uc720 \uc9c4\ud589
 sharing.progress.hide=\uc228\uae40
-MainWindow.menu.view.myshares=\ub0b4 \uacf5\uc720
-MainWindow.menu.view.myshares.keybinding=\uba54\ud0c0+3
-MySharesView.title.full=\ub0b4 \uacf5\uc720
-MySharesView.name=\ud30c\uc77c \uc774\ub984
-MySharesView.type=\uc591\uc2dd
+MainWindow.menu.view.myshares=\ub0b4 \uace0\uc804\uc2dd \uacf5\uc720
+MySharesView.title.full=\ub0b4 \uace0\uc804\uc2dd \uacf5\uc720
+MySharesView.name=\uc774\ub984
+MySharesView.type=\uc720\ud615
 MySharesView.type.file=\ud30c\uc77c
-MySharesView.type.dir=\ud3f4\ub354
-MySharesView.type.dircontents=\ud3f4\ub354 \ub0b4\uc6a9
-MySharesView.type.dircontentsrecursive=\ud3f4\ub354 \ub0b4\uc6a9 (\ub418\ud480\uc774)
-MySharesView.menu.remove=\uc9c0\uc6b0\uae30
+MySharesView.type.dir=\ub514\ub809\ud130\ub9ac
+MySharesView.type.dircontents=\ub514\ub809\ud130\ub9ac \ub0b4\uc6a9
+MySharesView.type.dircontentsrecursive=\ub514\ub809\ud130\ub9ac \ub0b4\uc6a9 (\ud558\uc704 \ub514\ub809\ud130\ub9ac \ud3ec\ud568)
+MySharesView.menu.remove=\uc81c\uac70
 ConfigView.section.tracker.extensions=\ud655\uc7a5\uc790
-ConfigView.section.tracker.sendpeerids=\ub3d9\ub8cc \uc2e0\uc6d0\uc744 \ub0b4\ub824\ubc1b\uae30 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c \ubcf4\ub0c4
-ConfigView.section.tracker.enableudp=UDP \ub354\ub4ec\uc774 \ud504\ub85c\ud1a0\ucf5c \uc791\ub3d9
-plugin.sharing.torrent.remove.veto=\uc774 \ub354\ub4ec\uc774 \ub4f1\ub85d\uc740 \uacf5\uc720\ub418\uace0 \uc788\ub294 \uc790\uc6d0\uc758 \uacb0\uacfc\uc785\ub2c8\ub2e4.\n\ub0b4\ub824\ubc1b\uae30\ub97c \uc9c0\uc6b0\ub824\uba74 \uad00\uacc4\ub41c \uacf5\uc720\ub97c \uc9c0\uc6b0\uc2ed\uc2dc\uc694.
-plugin.download.remove.veto.notstopped=\ub0b4\ub824\ubc1b\uae30\uac00 \uba48\ucd94\uc9c0 \uc54a\uc558\uc73c\ubbc0\ub85c \uc9c0\uc6b8 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
-plugin.sharing.remove.veto=\uc774 \uacf5\uc720\ub294 '\ud3f4\ub354 \ub0b4\uc6a9' \uacf5\uc720\uc5d0 \ubc84\uae08\uac00\ub294 \uacf5\uc720\ub85c\uc11c \ub4dc\ub7ec\ub0b8 \ucc44\ub85c \uc9c0\uc6cc\uc9c8 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n \ubfcc\ub9ac\uac00 \ub418\ub294 \uacf5\uc720\ub97c \uc9c0\uc6b0\uc2ed\uc2dc\uc694.
-GeneralView.label.hash.tooltip=\ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ud574\uc2dc\ub97c \ubcf5\uc0ac\ud558\ub824\uba74 \ud074\ub9ad
-ConfigView.section.tracker.maxpeersreturned=\ub3cc\ub824 \ubcf4\ub0b4\uc9c4 \ucd5c\ub300 \ub3d9\ub8cc \uc218 [0: \ubb34\uc81c\ud55c]
-ConfigView.label.serverport=\ub4e4\uc5b4\uc624\ub294 TCP \ub4e3\uae30 \ud3ec\ud2b8
-ConfigView.label.serverport.tooltip=\ud3ec\ud2b8\ub294 \ubc18\ub4dc\uc2dc 1-65535\uc758 \ubc94\uc704 \uc548\uc5d0 \uc788\uc5b4\uc57c \ud558\uace0, 6880 \ud3ec\ud2b8\ub294 Vuze \uc548\uc5d0\uc11c \uc4f0\ub824\uace0 \ub0a8\uaca8 \ub461\ub2c8\ub2e4.
-configureWizard.nat.server.tcp_listen_port=\ub4e4\uc5b4\uc624\ub294 TCP \ub4e3\uae30 \ud3ec\ud2b8
-ConfigView.section.sharing=\uacf5\uc720
-ConfigView.section.sharing.usessl=\uacf5\uc720\ub41c \uc790\uc6d0\uc5d0 SSL \uc0ac\uc6a9 (\ub354\ub4ec\uc774 \uad6c\uc131\uc774 \ud544\uc694\ud568)
-ConfigView.section.style.dropdiraction=\ud3f4\ub354\uc5d0 \ub04c\uc5b4\ub2e4\uac00 \ub193\uae30
-ConfigView.section.style.dropdiraction.opentorrents=\ud1a0\ub7f0\ud2b8 \uc5f4\uae30
-ConfigView.section.style.dropdiraction.sharefolder=\ud3f4\ub354 \uacf5\uc720
-ConfigView.section.style.dropdiraction.sharefoldercontents=\ub0b4\uc6a9 \uacf5\uc720
+ConfigView.section.tracker.sendpeerids=\ud53c\uc5b4 \uc2e0\uc6d0\uc744 \ub2e4\uc6b4\ub85c\ub354\uc5d0\uac8c \ubcf4\ub0c4
+ConfigView.section.tracker.enableudp=UDP \ud2b8\ub798\ucee4 \ud504\ub85c\ud1a0\ucf5c \ud65c\uc131\ud654
+plugin.sharing.torrent.remove.veto=\uc774 \ud2b8\ub798\ucee4 \ub4f1\ub85d\uc740 \uace0\uc804\uc2dd\uc73c\ub85c \uacf5\uc720\ub41c \uc790\uc6d0\uc5d0\uc11c \uae30\uc778\ub41c \uac83\uc785\ub2c8\ub2e4.\n\ub2e4\uc6b4\ub85c\ub4dc\ub97c \uc81c\uac70\ud558\ub824\uba74 \uace0\uc804\uc2dd \uacf5\uc720 \uc5f0\ub3d9\uc744 \uc81c\uac70\ud558\uc2ed\uc2dc\uc624: \ub3c4\uad6c\u2192\ub0b4 \uace0\uc804\uc2dd \uacf5\uc720.
+plugin.download.remove.veto.notstopped=\uc815\uc9c0\ub418\uc9c0 \uc54a\uc558\uc73c\ubbc0\ub85c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc81c\uac70\ub420 \uc218 \uc5c6\uc74c
+plugin.sharing.remove.veto=\uc774 \uace0\uc804\uc2dd \uacf5\uc720\ub294 '\ub514\ub809\ud130\ub9ac \ub0b4\uc6a9' \uacf5\uc720\uc758 \ud558\uc704 \uacf5\uc720\ub85c\uc11c \uba85\uc2dc\uc801\uc73c\ub85c \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uace0\uc804\uc2dd \uacf5\uc720 \ub8e8\ud2b8\ub97c \uc0ad\uc81c\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+GeneralView.label.hash.tooltip=\ud574\uc2dc\ub97c \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac\ud558\ub824\uba74 \ud074\ub9ad
+ConfigView.section.tracker.maxpeersreturned=\ubc18\ud658\ub418\ub294 \ucd5c\ub300 \ud53c\uc5b4 [0: \ubb34\uc81c\ud55c]
+ConfigView.label.serverport=\ub4e4\uc5b4\uc624\ub294 TCP / UDP \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8
+ConfigView.label.serverport.tooltip=Vuze \ub0b4\ubd80 \uc0ac\uc6a9\uc744 \uc704\ud574 \uc608\uc57d\ub41c 6880 \ud3ec\ud2b8\ub97c \uc81c\uc678\ud558\uace0 \ubc18\ub4dc\uc2dc 1-65535\uc758 \ubc94\uc704 \uc548\uc758 \ud3ec\ud2b8\uc774\uc5b4\uc57c \ud569\ub2c8\ub2e4.
+configureWizard.nat.server.tcp_listen_port=\ub4e4\uc5b4\uc624\ub294 TCP \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8
+ConfigView.section.sharing=\uace0\uc804\uc2dd \uacf5\uc720
+ConfigView.section.sharing.usessl=\uace0\uc804\uc2dd \uacf5\uc720 \uc790\uc6d0\uc5d0 \ub300\ud574 SSL \uc0ac\uc6a9 (\ud2b8\ub798\ucee4 \uc124\uc815 \ud544\uc694)
+ConfigView.section.style.dropdiraction=\ub514\ub809\ud1a0\ub9ac\uc5d0 \ub300\ud55c \ub04c\uc5b4 \ub193\uae30 \ub3d9\uc791
+ConfigView.section.style.dropdiraction.opentorrents=\ud1a0\ub80c\ud2b8 \uc5f4\uae30
+ConfigView.section.style.dropdiraction.sharefolder=\uace0\uc804\uc2dd \uacf5\uc720 \ub514\ub809\ud130\ub9ac
+ConfigView.section.style.dropdiraction.sharefoldercontents=\uace0\uc804\uc2dd \uacf5\uc720 \ub0b4\uc6a9
 #
 # 2.0.7.x
 #
 Categories.all=\ubaa8\ub450
 Categories.uncategorized=\ubd84\ub958\ub418\uc9c0 \uc54a\uc74c
-CategoryAddWindow.message=\uc0c8 \ubd84\ub958 \uc774\ub984\uc744 \uc368\ub123\uc73c\uc2ed\uc2dc\uc694
-CategoryAddWindow.title=\uc0c8 \ubd84\ub958 \ucd94\uac00\ud558\uae30
-ConfigView.label.autoSeedingIgnoreInfo=\ubb34\uc2dc\ub41c \ud1a0\ub7f0\ud2b8\ub4e4\uc740 \ubfcc\ub9ac\ub294 \ucc28\ub840\uc758 \ubc11\uc73c\ub85c \uac11\ub2c8\ub2e4. \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791\ub418\uc9c0\ub294 \uc54a\uc2b5\ub2c8\ub2e4.\n\ubb34\uc2dc \uaddc\uce59\ub4e4\uc740 \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uae30\uc900\uc5d0 \ub9de\ub294 \ud1a0\ub7f0\ud2b8\ub4e4\uc5d0 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n\ub2ec\ub9ac \uc815\ud574\uc9c0\uc9c0 \uc54a\uc558\u [...]
-ConfigView.label.directory=\ud3f4\ub354
-ConfigView.label.disconnetseed.tooltip=\ud1a0\ub7f0\ud2b8\ub97c \ubfcc\ub9b4 \ub54c, \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubfcc\ub9ac\uace0 \uc788\ub294 \uc811\uc18d \ucef4\ud4e8\ud130\ub97c \ub04a\uc2b5\ub2c8\ub2e4.\n\uadf8\ub4e4\uc774 \ub2f9\uc2e0\uacfc \ud1b5\uc2e0\ud560 \ud544\uc694\ub3c4 \uc5c6\uc2b5\ub2c8\ub2e4.
+CategoryAddWindow.message=\uc0c8 \ubd84\ub958 \uc774\ub984 \uc785\ub825
+CategoryAddWindow.title=\uc0c8 \ubd84\ub958 \ucd94\uac00
+ConfigView.label.autoSeedingIgnoreInfo=\ubb34\uc2dc\ub41c \ud1a0\ub80c\ud2b8\ub294 \ubc30\ud3ec \ub300\uae30\uc5f4\uc758 \uac00\uc7a5 \uc544\ub798\ub85c \uac11\ub2c8\ub2e4. \uc774 \ud1a0\ub80c\ud2b8\ub4e4\uc740 \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n\ubb34\uc2dc \uaddc\uce59\uc740 \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uc870\uac74\uacfc \uc77c\uce58\ud558\ub294 \ud1a0\ub80c\ud2b8\uc5d0\ub294 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n\ubcc4\ [...]
+ConfigView.label.directory=\ub514\ub809\ud130\ub9ac
+ConfigView.label.disconnetseed.tooltip=\ud1a0\ub80c\ud2b8\ub97c \ubc30\ud3ec\ud560 \ub54c, \ubc30\ud3ec\ud558\uace0\uc788\ub294 \ub2e4\ub978 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc5f0\uacb0\uc744 \ub04a\uc2b5\ub2c8\ub2e4.\n\ud574\ub2f9 \ud074\ub77c\uc774\uc5b8\ud2b8\ub4e4\uc774 \uc0ac\uc6a9\uc790\uc5d0\uac8c \ub9d0\uc744 \uac78 \uc774\uc720\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
 ConfigView.label.ignoreCase=\ub300\uc18c\ubb38\uc790 \ubb34\uc2dc
-ConfigView.label.ignoreSeeds=\uc801\uc5b4\ub3c4 \ub2e4\uc74c\ub9cc\ud07c \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub97c \ubb34\uc2dc
-ConfigView.label.importdirectory=\ud3f4\ub354 \ub4e4\uc5ec\uc624\uae30
-ConfigView.label.minPeersToBoostNoSeeds.tooltip=\ubfcc\ub9ac\uae30\uac00 \uc5c6\uac70\ub098 \ud544\uc694\ud55c \uc778\uc6d0\ubcf4\ub2e4 \uc801\uc740 \ud1a0\ub7f0\ud2b8\ub294 \ucc28\ub840\uc758 \ub05d\uc5d0 \ub193\uc785\ub2c8\ub2e4.
-ConfigView.label.minPeersToBoostNoSeeds=\ubfcc\ub9ac\uae30\uac00 \uc5c6\uac70\ub098 \uadf8\uc640 \ube44\uc2b7\ud55c \ud1a0\ub7f0\ud2b8\uc758 \ubfcc\ub9ac\uae30 \uc21c\uc704 \ub0ae\ucda4
-ConfigView.label.minSeedingTime.tooltip=\ubfcc\ub9ac\uae30 \uc21c\uc704\ub294 \uc9e7\uc740 \uc2dc\uac04\uc5d0 \uc790\uc8fc \uc624\ub974\ub0b4\ub9b4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ub85c \uc778\ud574 \uc774\ub530\uae08 \ud1a0\ub7f0\ud2b8\uac00 \uc800\uc808\ub85c \uc2dc\uc791\ud558\uace0\uc11c \ubc14\ub85c \ub2e4\uc74c\uc5d0 \uba48\ucd94\uace0 \ub300\uae30\ud558\uae30\ub3c4 \ud569\ub2c8\ub2e4.\n\uc774 \ubb38\uc81c\ub294 \ud1a0\ub7f0\ud2b8\uac00 \uc8fc\uc5b4\uc9c4 \uc2dc\uac04 \ub3d [...]
-ConfigView.label.minSeedingTime=\ucd5c\uc18c \ubfcc\ub9ac\uae30 \uc2dc\uac04 (\ucd08)
-ConfigView.label.minSpeedForActiveDL.tooltip=\ub05d\ub9c8\uce58\uc9c0 \ubabb\ud55c \ud1a0\ub7f0\ud2b8\uac00 \uc2dc\uc791\ud558\uace0\uc11c \ucc98\uc74c 30\ucd08 \ub3d9\uc548\n\ub0b4\ub824\ubc1b\uae30 \uc790\ub9ac\uac00 \ub298 \uc4f0\uc785\ub2c8\ub2e4.
-ConfigView.label.minSpeedForActiveDL=\uc18d\ub3c4\uac00 \uc774\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c0\uba74 \ub0b4\ub824\ubc1b\uae30 \uc790\ub9ac\ub97c \uc4f0\uace0 \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub97c \uc138\uc9c0 \uc54a\uc74c
-ConfigView.label.peers=\ub3d9\ub8cc
+ConfigView.label.ignoreSeeds=\uc801\uc5b4\ub3c4 \ub2e4\uc74c\uc758 \ud1a0\ub80c\ud2b8\ub97c \ubb34\uc2dc
+ConfigView.label.importdirectory=\uac00\uc838\uc62c \ub514\ub809\ud130\ub9ac
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=\uc2dc\ub4dc\uac00 \uc5c6\uac70\ub098 \uc0ac\uc6a9\uc790\uac00 \uc9c0\uc815\ud55c \uac83\ubcf4\ub2e4 \uc801\uc740 \ud53c\uc5b4\ub97c \uac00\uc9c4 \ud1a0\ub80c\ud2b8\ub294 \ub300\uae30\uc5f4\uc758 \ub4a4\ub85c \uc774\ub3d9 \ub429\ub2c8\ub2e4.
+ConfigView.label.minPeersToBoostNoSeeds=\uc2dc\ub4dc\uac00 \uc5c6\uac70\ub098 \ub2e4\uc74c\ubcf4\ub2e4 \uc801\uc740 \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud574 \ub0ae\uc740 \ubc30\ud3ec \ub4f1\uae09 \ubd80\uc5ec
+ConfigView.label.minSeedingTime.tooltip=\ubc30\ud3ec \ub4f1\uae09\uc740 \uc9e7\uc740 \uc2dc\uac04 \ub3d9\uc548 \uae09\uaca9\ud55c \ubcc0\ub3d9\uc774 \uc788\uc744 \uc218 \uc788\ub294\ub370, \uc774\uac83\uc740 \uac00\ub054 \ud1a0\ub80c\ud2b8\uac00 \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791 \ub418\ub3c4\ub85d \ub9cc\ub4e4\uba70, \uc774\ud6c4 \uc989\uc2dc \uc911\uc9c0\ub418\uac70\ub098 \ub300\uae30\uc5f4\ub85c \ub4e4\uc5b4\uac11\ub2c8\ub2e4.\n\uc774 \uc635\uc158\uc740 \uc8fc\uc5b4\uc9c4 \uc2dc\ua [...]
+ConfigView.label.minSeedingTime=\ucd5c\uc18c \ubc30\ud3ec \uc2dc\uac04 [\ucd08]
+ConfigView.label.minSpeedForActiveDL.tooltip=\ub2e4\uc6b4\ub85c\ub4dc \uc2ac\ub86f\uc740 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc740 \ud1a0\ub80c\ud2b8\uac00 \uc2dc\uc791\ub41c \ud6c4 \n\ucd5c\ucd08 30\ucd08 \ub3d9\uc548\uc740 \ud56d\uc0c1 \uc0ac\uc6a9 \ub429\ub2c8\ub2e4.
+ConfigView.label.minSpeedForActiveDL=\uc9c0\uc815\ud55c \uc18d\ub3c4 \uc774\ud558\ub85c \ub5a8\uc5b4\uc9c0\ub294 \uacbd\uc6b0 \ub2e4\uc6b4\ub85c\ub4dc \uc2ac\ub86f\uc744 \uc0ac\uc6a9\ud558\ub294 \ud1a0\ub80c\ud2b8\ub85c \uce74\uc6b4\ud2b8\ud558\uc9c0 \uc54a\uc74c
+ConfigView.label.peers=\ud53c\uc5b4
 ConfigView.label.queue.debuglog=\ub514\ubc84\uadf8 \uc815\ubcf4 \ub85c\uadf8
-ConfigView.label.queue.debuglog.info=\ucf58\uc194/\ub85c\uadf8 \ud30c\uc77c\uc5d0 \ub300\uae30 \ub514\ubc84\uadf8 \uc815\ubcf4\ub97c \ub354\ud569\ub2c8\ub2e4.\n\uc554\ud638\ubb38\uc774\uc9c0\ub9cc, \ub514\ubc84\uadf8 \uc815\ubcf4\ub294 \ud1a0\ub7f0\ud2b8\uc758 \uc0c1\ud0dc\uc640 \uadf8\uac83\ub4e4\uc774 \uc2dc\uc791/\ub300\uae30\ud558\uac70\ub098 \ud558\uc9c0 \uc54a\ub294 \uc774\uc720\ub97c \uc54c\ub824 \uc90d\ub2c8\ub2e4.
-ConfigView.label.queue.minQueueingShareRatio=\ud1a0\ub7f0\ud2b8\uc758 \uacf5\uc720 \ube44\uac00 \ub2e4\uc74c\uc5d0 \uc774\ub97c \ub54c\uae4c\uc9c0 \ud1a0\ub7f0\ud2b8\ub97c \ub300\uae30\ud558\uac70\ub098 \uba48\ucd94\uc9c0 \uc54a\uc74c
-ConfigView.label.ratio=\ube44
-ConfigView.label.removeOnStop=\ud1a0\ub7f0\ud2b8\uac00 \uc800\uc808\ub85c \uba48\ucd94\uace0 \ub098\uc11c \ubaa9\ub85d\uc5d0\uc11c \ud1a0\ub7f0\ud2b8 \uc9c0\uc6b0\uae30
-ConfigView.label.savedirectory=\ud3f4\ub354 \uc800\uc7a5
-ConfigView.label.seeding.autoReposition.tooltip=\uc791\ub3d9\uc2dc\ud0a4\uba74 \ud1a0\ub7f0\ud2b8\uc758 \uc21c\uc11c('\ubc88\ud638' \uc138\ub85c\uc904)\uac00 \ubfcc\ub9ac\uae30 \uc21c\uc704\uc5d0 \ub9de\ucd94\uc5b4\uc11c \ubc14\ub014 \uac83\uc785\ub2c8\ub2e4.\n\ub2f9\uc2e0\uc774 \ubfcc\ub9ac\uae30 \uc21c\uc704 \uc22b\uc790\ub97c \ubcf4\uace0 \uc2f6\uc9c0 \uc54a\uc73c\ub098, \uadf8\ub798\ub3c4 \ub05d\ub9c8\uce5c \ud1a0\ub7f0\ud2b8\uac00 \uc2dc\uc791\ud560 \uc21c\uc11c\ub97c \uc54c\uace0 \ [...]
-ConfigView.label.seeding.autoReposition=\ubfcc\ub9ac\uae30 \uc21c\uc704\uc5d0 \ub530\ub77c \ud1a0\ub7f0\ud2b8\uc758 \uc790\ub9ac\ub97c \uc800\uc808\ub85c \ubc14\uafc8
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\uac00\ub054 \ub0ae\uc740 \uc528\uc557 \uc218\uc640 \ub192\uc740 \ub3d9\ub8cc \uc218\uc778 \ud1a0\ub7f0\ud2b8\ub294 \uc544\ub9c8 \ub3d9\ub8cc\ub4e4 \uc911\uc5d0\uc11c \uc644\uc804\ubcf8\uc774 \uc5c6\ub2e4\ub294 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.\n\uadf8\ub7ec\ubbc0\ub85c \uc544\ub9c8 \uc644\uc804\ubcf8\uc774 \uc788\ub294 \uac83\ucc98\ub7fc \uad74\uc5b4\uc11c (\uadf8 \uc21c\uc704\ub97c \ubc14\ub974\uc9c0 \uc54a\uac8c \ub0b4\ub9ac\ [...]
-ConfigView.label.seeding.fakeFullCopySeedStart=\uadf8\ub807\uc9c0\ub9cc \uc801\uc5b4\ub3c4 \ub2e4\uc74c\ub9cc\ud07c \uc788\ub294 \ud1a0\ub7f0\ud2b8\uc5d0\ub9cc
+ConfigView.label.queue.debuglog.info=\ub300\uae30\uc5f4 \ub514\ubc84\uadf8 \uc815\ubcf4\ub97c \ucf58\uc194/\ub85c\uadf8 \ud30c\uc77c\uc5d0 \ucd94\uac00\ud569\ub2c8\ub2e4.\n\uc554\ud638\ud654\uac00 \ub418\uc5b4\uc788\ub354\ub77c\ub3c4, \ub514\ubc84\uadf8 \uc815\ubcf4\ub294 \ud1a0\ub80c\ud2b8\uc758 \uc0c1\ud0dc\uc640 \uc65c \ud574\ub2f9 \ud1a0\ub80c\ud2b8\ub4e4\uc774 \uc2dc\uc791/\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac00\uae30\uac00 \ub418\uc5c8\ub294\uc9c0/\uc548 \ub418\uc5c8\ub294\uc9c [...]
+ConfigView.label.queue.minQueueingShareRatio=\ud1a0\ub80c\ud2b8\uac00 \uacf5\uc720 \ube44\uc728\uc5d0 \uc774\ub974\uae30 \uc804\uae4c\uc9c0\ub294 \ud574\ub2f9 \ud1a0\ub80c\ud2b8\ub97c \ub300\uae30\uc5f4\uc5d0 \ub123\uac70\ub098 \uc911\uc9c0\ud558\uc9c0 \uc54a\uc74c
+ConfigView.label.ratio=\ube44\uc728
+ConfigView.label.removeOnStop=\ud1a0\ub80c\ud2b8\uac00 \uc790\ub3d9\uc73c\ub85c \uba48\ucd98 \ud6c4 \ubaa9\ub85d\uc5d0\uc11c \ud574\ub2f9 \ud1a0\ub80c\ud2b8 \uc81c\uac70
+ConfigView.label.savedirectory=\ub514\ub809\ud130\ub9ac \uc800\uc7a5
+ConfigView.label.seeding.autoReposition.tooltip=\ud65c\uc131\ud654\ub418\uba74 \ud1a0\ub80c\ud2b8\uc758 \uc21c\uc11c ('#' \uc5f4)\uac00 \ubc30\ud3ec \ub4f1\uae09\uc5d0 \ub9de\ucdb0\uc11c \ubc14\ub00c\uac8c \ub429\ub2c8\ub2e4.\n\ubc30\ud3ec \ub4f1\uae09 \uc22b\uc790\ub97c \ubcf4\uace0 \uc2f6\uc9c0\ub294 \uc54a\uc9c0\ub9cc \ub4f1\uae09\uc5d0 \ub530\ub77c \uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8\uac00 \uc2dc\uc791\ub418\ub294 \uc21c\uc11c\ub97c \ubcf4\uace0\uc790\ud560 \ub54c \uc720\uc6a9\ud56 [...]
+ConfigView.label.seeding.autoReposition=\uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec \ub4f1\uae09\uc5d0 \ub530\ub77c \ud1a0\ub80c\ud2b8 \uc704\uce58 \ubc14\uafc8
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\uc885\uc885 \uc2dc\ub4dc \uc218\uac00 \uc801\uace0 \ud53c\uc5b4 \uc218\ub294 \ub192\uc740 \ud1a0\ub80c\ud2b8\ub294 \ud53c\uc5b4 \uc0ac\uc774\uc5d0 \uc644\uc804\ud55c \ubcf5\uc0ac\ubcf8\uc774 \uc5c6\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uadf8\ub7ec\ubbc0\ub85c \uc644\uc804\ud55c \ubcf5\uc0ac\ubcf8\uc774 \uc874\uc7ac\ud558\ub294 \uac83\ucc98\ub7fc \ubcf4\uc774\ub294 (\uadf8\ub798\uc11c \ud574\u [...]
+ConfigView.label.seeding.fakeFullCopySeedStart=\ud558\uc9c0\ub9cc \ucd5c\uc18c \ub2e4\uc74c\uc758 \uc218\ub7c9\uc774 \ub9cc\uc871\ub41c \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud574\uc11c\ub9cc
 ConfigView.label.seeding.ignore=\uaddc\uce59 \ubb34\uc2dc
-ConfigView.label.seeding.ignore0Peers=0 \ub3d9\ub8cc\uc778 \ud1a0\ub7f0\ud2b8 \ubb34\uc2dc
-ConfigView.label.seeding.ignoreRatioPeers=\uc801\uc5b4\ub3c4 \ub2e4\uc74c\ub9c8\ub2e4 1 \uc528\uc557\uc774 \uc788\ub294 \ud1a0\ub7f0\ud2b8 \ubb34\uc2dc
-ConfigView.label.seeding.ignoreShareRatio=\ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc720 \ube44\uc778 \ud1a0\ub7f0\ud2b8 \ubb34\uc2dc
-ConfigView.label.seeding.ignore.header.evenFirstPriority=\uccab\ubc88\uc9f8 \uc6b0\uad8c\uc120 \uaddc\uce59\uc5d0 \ub9de\ub354\ub77c\ub3c4\n\ud1a0\ub7f0\ud2b8\ub97c \ubb34\uc2dc\ud569\ub2c8\ub2e4.
+ConfigView.label.seeding.ignore0Peers=0 \ud53c\uc5b4 \ud1a0\ub80c\ud2b8 \ubb34\uc2dc
+ConfigView.label.seeding.ignoreRatioPeers=\ub2e4\uc74c\ub9c8\ub2e4 \uc801\uc5b4\ub3c4 1 \uc2dc\ub4dc\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud1a0\ub80c\ud2b8 \ubb34\uc2dc
+ConfigView.label.seeding.ignoreShareRatio=\ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc720 \ube44\uc728\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \ud1a0\ub80c\ud2b8 \ubb34\uc2dc
+ConfigView.label.seeding.ignore.header.evenFirstPriority=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uaddc\uce59\uc774 \n\uc801\uc6a9\ub418\uc5b4\ub3c4 \ud1a0\ub80c\ud2b8 \ubb34\uc2dc
 ConfigView.label.seeding.ignore.header.rule=\uaddc\uce59
 ConfigView.label.seeding.ignore.header.value=\uac12
-ConfigView.label.seeding.firstPriority.info=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \ud1a0\ub7f0\ud2b8\ub294 \ub298 \ub300\uae30\uc21c\uc11c\uc758 \ub9e8 \uc704\uc5d0 \uc788\uc744 \uac83\uc785\ub2c8\ub2e4. \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uae30\uc900\uc5d0 \ub9de\ub294 \ud1a0\ub7f0\ud2b8\ub294 \uc5b4\ub5a4 \uac83\uc774\ub77c\ub3c4 \uc800\uc808\ub85c \uba48\ucd94\uac70\ub098 \ub300\uae30\ud558\uc9c0 \uc54a\uc744 \uac83\uc785\ub2c8\ub2e4. \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uae30\uc [...]
+ConfigView.label.seeding.firstPriority.info=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \ud1a0\ub80c\ud2b8\ub294 \ud56d\uc0c1 \ub300\uae30\uc5f4\uc758 \ub9e8 \uc704\uc5d0 \uc788\uac8c \ub429\ub2c8\ub2e4.\n\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uaddc\uc900\uacfc \uc77c\uce58\ud558\ub294 \ud1a0\ub80c\ud2b8\ub77c\uba74 \uc790\ub3d9\uc73c\ub85c \uc911\uc9c0\ub418\uac70\ub098 \ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac00\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\n\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uaddc\uc [...]
 ConfigView.label.seeding.firstPriority.FP=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c
-ConfigView.label.seeding.firstPriority=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c\uc774 \ub2e4\uc74c \uac00\uc6b4\ub370
-ConfigView.label.seeding.firstPriority.following=\u3000\uc788\ub294 \ud1a0\ub7f0\ud2b8\uc5d0 \ubbf8\uce5c\ub2e4:
-ConfigView.label.seeding.firstPriority.shareRatio=\ub2e4\uc74c\ubcf4\ub2e4 \ubabb\ud55c \uacf5\uc720 \ube44
-ConfigView.label.seeding.firstPriority.seedingMinutes=\ub0b4\ub824\ubc1b\uae30\uc5d0\uc11c \ubfcc\ub9ac\uae30\ub85c \ubc14\ub00c\uace0\ub098\uc11c \uc9c0\ub09c \uc2dc\uac04
-ConfigView.label.seeding.firstPriority.DLMinutes=\ub0b4\ub824\ubc1b\uae30\ub97c \uc2dc\uc791\ud558\uace0\uc11c \uc9c0\ub09c \uc2dc\uac04
-ConfigView.label.seeding.numPeersAsFullCopy.tooltip=X \ub3d9\ub8cc\ub9c8\ub2e4 1 \uc644\uc804\ubcf8\uc774 \uc788\ub294 \uccb4\ud558\uc5ec\uc11c, \ub2f9\uc2e0\uc740 \ub192\uc740 \ub3d9\ub8cc \uc218\uac00 \uc788\ub294 \ud1a0\ub7f0\ud2b8\uc758 \uc21c\uc704\ub97c \ub0ae\ucda5\ub2c8\ub2e4.\n\uc544\ub9c8 \ub192\uc740 \ub3d9\ub8cc \uc218\uac00 \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub294 \ub192\uc740 \uc804\uc1a1\ub7c9\ub3c4 \uc788\uc744 \uac83\uc785\ub2c8\ub2e4.\n\uc774\uac83\uc740 \uc5b4\ub5a4 '\uc5 [...]
-ConfigView.label.seeding.numPeersAsFullCopy=\ub2e4\uc74c\ub9c8\ub2e4 1 \uc644\uc804\ubcf8\uc774 \uc788\ub294 \uccb4\ud568\n(0: \uc18d\uc774\uc9c0 \uc54a\uc74c)
-ConfigView.label.seeding.preferLargerSwarms.tooltip=\ub3d9\ub8cc\ub4e4\uc774 \ubd99\uc5b4 \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub97c \uc8fc\ub85c \ubfcc\ub9b4 \ub54c\ub294 \ub354 \ud070 \ub5bc\ub97c \uace0\ub974\ub294 \uac83\uc774 \ub2f9\uc5f0\ud569\ub2c8\ub2e4.\n\ucda9\ubd84\ud788 \uc5bb\uc744 \uc218 \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub97c \uc8fc\ub85c \ubfcc\ub9b4 \ub54c\ub294 \ub354 \uc791\uc740 \ub5bc\ub97c \uace0\ub974\ub294 \uac83\uc774 \ub2f9\uc5f0\ud569\ub2c8\ub2e4.
-ConfigView.label.seeding.preferLargerSwarms=\ud1a0\ub7f0\ud2b8\ub4e4\uc774 \uac19\uc740 \uc21c\uc704\uc774\uba74 \ub354 \ub9ce\uc740 \ub5bc\ub97c \uace0\ub985\ub2c8\ub2e4.
-ConfigView.label.seeding.rankType.none.tooltip=\ubc88\ud638 \uc138\ub85c\uc904\uc5d0 \ub530\ub77c\uc11c \uc7a1\uc74c
-ConfigView.label.seeding.rankType.none=\uc544\ubb34 \uac83\ub3c4 \uc5c6\uc74c
-ConfigView.label.seeding.rankType.peerSeed.options=\uc528\uc557:\ub3d9\ub8cc \ube44\uc758 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.label.seeding.rankType.peerSeed.tooltip=\ub192\uc740 \ube44 = \ub192\uc740 \uc21c\uc704
-ConfigView.label.seeding.rankType.peerSeed=\ub3d9\ub8cc:\uc528\uc557 \ube44
-ConfigView.label.seeding.rankType.seed.fallback=\ub2e4\uc74c\ubcf4\ub2e4 \uc801\uc73c\uba74 \ub3d9\ub8cc:\uc528\uc557 \ube44\ub85c \ub300\ube44\n(0: \ub300\ube44\ud558\uc9c0 \uc54a\uc74c)
-ConfigView.label.seeding.rankType.seed.options=\uc528\uc557 \uc218\ub9cc\uc758 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.label.seeding.rankType.seed.tooltip=\uc801\uc740 \uc528\uc557 = \ub192\uc740 \uc21c\uc704
-ConfigView.label.seeding.rankType.seed=\uc528\uc557 \uc218\ub9cc
-ConfigView.label.seeding.rankType.timedRotation.tooltip=\ub300\uae30\ud558\ub294 \ubaa8\ub4e0 \ub05d\ub9c8\uce5c \ud1a0\ub7f0\ud2b8\ub294 \ubfcc\ub9ac\uae30 \ubc29\uc2dd\uc5d0\uc11c \ubc88\uac08\uc544 \ubc14\ub014 \uac83\uc785\ub2c8\ub2e4.\n\uc774\uc5b4\uc9c0\ub294 \ubfcc\ub9ac\uae30 \uc2dc\uac04\uc740 '\ucd5c\uc18c \ubfcc\ub9ac\uae30 \uc2dc\uac04'\uc73c\ub85c \uc7a1\uc2b5\ub2c8\ub2e4.
-ConfigView.label.seeding.rankType.timedRotation=\uc815\uae30\uc801\uc778 \ubc88\uac08\uc544 \ubc14\uafc8
-ConfigView.label.seeding.rankType.tooltip=\uac00\uc7a5 \ub192\uac8c \ub9e4\uaca8\uc9c4 \ud1a0\ub7f0\ud2b8\ub294 \uc800\uc808\ub85c \uc2dc\uc791\ud569\ub2c8\ub2e4.\n\ub2e4\ub978 \ud1a0\ub7f0\ud2b8\uac00 \ub354 \ub192\uac8c \ub9e4\uaca8\uc9c0\uba74, \ub0ae\uac8c \ub9e4\uaca8\uc9c4 \uac83\uc740 \uba48\ucd94\uace0 \ub300\uae30\ub85c \ub3cc\uc544\uac11\ub2c8\ub2e4.\n\n\ub300\uae30 \uc0c1\ud0dc\uc758 \ud1a0\ub7f0\ud2b8\ub9cc \uc800\uc808\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4 [...]
-ConfigView.label.seeding.rankType=\ub2e4\uc74c\uc5d0 \ub530\ub77c\uc11c \uc800\uc808\ub85c \uc2dc\uc791\ud560 \ub05d\ub9c8\uce5c \ud1a0\ub7f0\ud2b8\uc758 \ucc28\ub840\ub97c \ub9e4\uae41\ub2c8\ub2e4:
-ConfigView.label.stopAfterMinutes=\ud55c\ubc88 \ubfcc\ub9ac\uae30\ub85c \ubc14\ub00c\uba74, \uc774\uc5b4\uc9c4 \uc2dc\uac04 \ud6c4\uc5d0 \uba48\ucda4
-ConfigView.label.switchpriority.tooltip=\ub0ae\uc740 \uc6b0\uc120\uad8c\uc740 \ud1a0\ub7f0\ud2b8\uc5d0 \ud560\ub2f9\ud558\ub294 \uc62c\ub9ac\uae30 \ub300\uc5ed\ud3ed\uc758 \uc591\uc744 \uc904\uc785\ub2c8\ub2e4.
-ConfigView.pluginlist.info=\ub2e4\uc74c \ucd94\uac00\uae30\ub2a5\uc774 \ud655\uc778\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uba87\uba87 \ucd94\uac00\uae30\ub2a5\uc740 \uad6c\uc131 \ud0ed\uc774 \uc5c6\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ConfigView.pluginlist.noplugins=\uc544\ubb34 \ucd94\uac00\uae30\ub2a5\ub3c4 \ucc3e\uc9c0 \ubabb\ud558\uc600\uc2b5\ub2c8\ub2e4.
+ConfigView.label.seeding.firstPriority=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c\uc740 \ub2e4\uc74c \uc870\uac74\uc744
+ConfigView.label.seeding.firstPriority.following=\ub9cc\uc871\ud558\ub294 \ud1a0\ub80c\ud2b8\uc5d0\uac8c \ubd80\uc5ec\ud569\ub2c8\ub2e4:
+ConfigView.label.seeding.firstPriority.shareRatio=\uacf5\uc720 \ube44\uc728\uc774 \ub2e4\uc74c\uc758 \uac12 \uc774\ud558
+ConfigView.label.seeding.firstPriority.seedingMinutes=\ub2e4\uc6b4\ub85c\ub4dc\uc5d0\uc11c \ubc30\ud3ec\ub85c \uc804\ud658 \ub418\uace0\ub098\uc11c \uacbd\uacfc\uc2dc\uac04
+ConfigView.label.seeding.firstPriority.DLMinutes=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc2dc\uc791\ub418\uace0\ub098\uc11c \uacbd\uacfc\ub41c \uc2dc\uac04
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=X \ud53c\uc5b4\ub9c8\ub2e4 1\uac1c\uc758 \uc644\uc804\ud55c \ubcf5\uc0ac\ubcf8\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uac00\uc815\ud574\uc11c, \ub192\uc740 \ud53c\uc5b4 \uce74\uc6b4\ud2b8\uc758 \ud1a0\ub80c\ud2b8\uc758 \ub4f1\uae09\uc744 \ub0ae\ucd9c \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\ub300\uac1c\uc758 \uacbd\uc6b0, \ub192\uc740 \ud53c\uc5b4 \uce74\uc6b4\ud2b8\ub97c \uac00\uc9c4 \ud1a0\ub80c\ud2b8\ub294 \ub192\uc740 \ub124\ud2b8\uc6cc\u [...]
+ConfigView.label.seeding.numPeersAsFullCopy=\ub2e4\uc74c\ub9c8\ub2e4 1\uac1c\uc758 \uc644\uc804\ud55c \ubcf5\uc0ac\ubcf8\uc774 \uc788\ub2e4\uace0 \uac00\uc815\n(0: \uac00\uc7a5\ud558\uc9c0 \uc54a\uc74c)
+ConfigView.label.seeding.preferLargerSwarms.tooltip=\uc8fc\ub85c "\ub2e4\ub2e5\ub2e4\ub2e5 \ubd99\uc5b4\uc788\uc744 \uc815\ub3c4\ub85c \ub9ce\uc740" \ud53c\uc5b4\ub97c \uac00\uc9c4 \ud1a0\ub80c\ud2b8\ub97c \ubc30\ud3ec\ud558\ub824 \ud55c\ub2e4\uba74, \ud070 \uc2a4\uc6dc\uc744 \uc120\ud638\ud558\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc785\ub2c8\ub2e4.\n\ub192\uc740 \uac00\uc6a9\uc131\uc744 \uac00\uc9c4 \ud1a0\ub80c\ud2b8\ub97c \uc8fc\ub85c \ubc30\ud3ec\ud560 \ub54c\ub294 \uc791\uc740 \uc2 [...]
+ConfigView.label.seeding.preferLargerSwarms=\ud1a0\ub80c\ud2b8\uac00 \uac19\uc740 \ub4f1\uae09\uc744 \uac00\uc9c8 \ub54c, \ud070 \uc2a4\uc6dc\uc744 \uc120\ud638
+ConfigView.label.seeding.rankType.none.tooltip=# \uc5f4\uc744 \uae30\uc900\uc73c\ub85c \uc815\ub82c
+ConfigView.label.seeding.rankType.none=\uc5c6\uc74c
+ConfigView.label.seeding.rankType.peer.tooltip=\ub9ce\uc740 \ud53c\uc5b4\uc5d0 \uc801\uc740 \uc2dc\ub4dc = \ub192\uc740 \ub4f1\uae09\n\uc774 \ub4f1\uae09\uc740 \uc5c5\ub85c\ub4dc \ucd5c\ub300\ud654\ub97c \uc704\ud55c \ud65c\uc131 \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud558\uae30 \uc704\ud55c \ud1a0\ub80c\ud2b8 \uc218\ub97c \ucd5c\uc18c\ud654 \ud569\ub2c8\ub2e4.
+ConfigView.label.seeding.rankType.peer=\uac00\uc911\uce58\uac00 \ubd80\uc5ec\ub41c \ud53c\uc5b4 \uc218
+ConfigView.label.seeding.rankType.peerSeed.options=\ud53c\uc5b4:\uc2dc\ub4dc \ube44\uc728 \uc635\uc158
+ConfigView.label.seeding.rankType.peerSeed.tooltip=\ub354 \ub192\uc740 \ube44\uc728 = \ub354 \ub192\uc740 \ub4f1\uae09
+ConfigView.label.seeding.rankType.peerSeed=\ud53c\uc5b4:\uc2dc\ub4dc \ube44\uc728
+ConfigView.label.seeding.rankType.seed.fallback=\ub2e4\uc74c \uc774\ud6c4 \ud53c\uc5b4:\uc2dc\ub4dc \ube44\uc728\ub85c \ub300\uccb4\n(0 : \ub300\uccb4\ud558\uc9c0 \uc54a\uc74c)
+ConfigView.label.seeding.rankType.seed.options='\uc2dc\ub4dc \uac2f\uc218\ub9cc \uace0\ub824' \uc635\uc158
+ConfigView.label.seeding.rankType.seed.tooltip=\uc801\uc740 \uc2dc\ub4dc = \ub192\uc740 \ub4f1\uae09
+ConfigView.label.seeding.rankType.seed=\uc2dc\ub4dc \uac2f\uc218\ub9cc \uace0\ub824
+ConfigView.label.seeding.rankType.timedRotation.tooltip=\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uc788\ub294 \ubaa8\ub4e0 \uc644\ub8cc \ud1a0\ub80c\ud2b8\ub294 \ub3cc\uc544\uac00\uba74\uc11c \ubc30\ud3ec \ubaa8\ub4dc\uc5d0 \ub4e4\uc5b4\uac11\ub2c8\ub2e4.\n\ubc30\ud3ec\uac00 \uc720\uc9c0\ub418\ub294 \uc2dc\uac04\uc740 '\ucd5c\uc18c \ubc30\ud3ec \uc2dc\uac04'\uc73c\ub85c \uc124\uc815\ub429\ub2c8\ub2e4.
+ConfigView.label.seeding.rankType.timedRotation=\uc2dc\uac04\uc5d0 \ub530\ub77c \uad50\ub300\ub85c
+ConfigView.label.seeding.rankType.tooltip=\uac00\uc7a5 \ub192\uc740 \ub4f1\uae09\uc758 \ud1a0\ub80c\ud2b8\ub294 \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791\ub429\ub2c8\ub2e4.\n\ub610 \ub2e4\ub978 \ud1a0\ub80c\ud2b8\uac00 \ub354 \ub192\uc740 \ub4f1\uae09\uc744 \uc5bb\uc744 \ub54c, \ub0ae\uc740 \ub4f1\uae09\uc758 \ud1a0\ub80c\ud2b8\ub294 \uc911\uc9c0\ub418\uba70 \ub300\uae30\uc5f4\ub85c \ub3cc\uc544\uac11\ub2c8\ub2e4.
+ConfigView.label.seeding.rankType=\uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8\uc758 \uc790\ub3d9 \uc2dc\uc791\uc744 \uc704\ud574 \ub2e4\uc74c\uc5d0 \uc870\uac74\uc5d0 \uae30\ubc18\ud558\uc5ec \uc21c\uc704\ub97c \ub9e4\uae41\ub2c8\ub2e4:
+ConfigView.label.stopAfterMinutes=\ubc30\ud3ec\ub85c \uc77c\ub2e8 \uc804\ud658\ub418\uba74, \uc720\uc9c0 \uc2dc\uac04 \ud6c4 \uc911\uc9c0
+ConfigView.label.switchpriority.tooltip=\ub0ae\uc740 \uc6b0\uc120\uad8c\uc740 \ud1a0\ub80c\ud2b8\uc5d0 \ud560\ub2f9\ud558\ub294 \uc5c5\ub85c\ub4dc \ub300\uc5ed\ud3ed \uc591\uc744 \uc904\uc785\ub2c8\ub2e4.
+ConfigView.pluginlist.info=\ub2e4\uc74c\uc758 \ud50c\ub7ec\uadf8\uc778\uc774 \uc778\uc2dd\ub418\uc5c8\uc2b5\ub2c8\ub2e4.  \uc77c\ubd80 \ud50c\ub7ec\uadf8\uc778\uc740 \uc124\uc815 \ud0ed\uc774 \uc5c6\uc744 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.
+ConfigView.pluginlist.noplugins=\ud50c\ub7ec\uadf8\uc778\uc744 \ucc3e\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4.
 ConfigView.section.pluginslist=\ubaa9\ub85d
-ConfigView.section.queue.seeding=\ubfcc\ub9ac\uae30
-ConfigView.section.queue.seeding.autoStarting=\uc800\uc808\ub85c \uc2dc\uc791
+ConfigView.section.queue.seeding=\ubc30\ud3ec
+ConfigView.section.queue.seeding.autoStarting=\uc790\ub3d9 \uc2dc\uc791
 ConfigView.section.queue.seeding.ignore=\uaddc\uce59 \ubb34\uc2dc
 ConfigView.section.queue.seeding.firstPriority=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c
-ConfigView.section.queue.main=\uc8fc\uc694 \ubd80\ubd84
-ConfigView.section.queue=\ub300\uae30
-ConfigView.section.torrents=\ud1a0\ub7f0\ud2b8
+ConfigView.section.queue.main=\uba54\uc778
+ConfigView.section.queue=\ub300\uae30\uc5f4\uc5d0 \ub123\uae30
+ConfigView.section.torrents=\ud1a0\ub80c\ud2b8
 ConfigView.text.all=\ubaa8\ub450
 ConfigView.text.hours=\uc2dc\uac04
 ConfigView.text.ignoreRule=\ubb34\uc2dc \uaddc\uce59
 ConfigView.text.ignore=\ubb34\uc2dc
 ConfigView.text.minutes=\ubd84
-ConfigView.text.neverIgnore=\uacb0\ucf54 \ubb34\uc2dc\ud558\uc9c0 \uc54a\uc74c
-ConfigView.text.any=\ubb34\uc5c7\uc774\ub4e0\uc9c0
-DownloadManager.error.datamissing=\ub370\uc774\ud130\uac00 \uc5c6\uc5b4\uc9d0
-MainWindow.menu.file.open.torrentforseeding=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c... (\ubfcc\ub9ac\uae30\uc5d0 \uc500)
-MainWindow.menu.language.refresh=\uc0c8\ub85c \uace0\uce68(&R)
-ManagerItem.forced=\uc5b5\uc9c0\ub85c
-ManagerItem.queued=\ub300\uae30
-MySeedersView.header=\ub05d\ub9c8\uce5c \ud1a0\ub7f0\ud2b8
-TableColumn.header.availability.info=\uc644\uc804\ubcf8 \uba87 \uac1c\uac00 \ubcf4\uc784
-TableColumn.header.availability=\uc4f8 \uc218 \uc788\uc74c
+ConfigView.text.neverIgnore=\ubb34\uc2dc\ud558\uc9c0 \uc54a\uc74c
+ConfigView.text.any=\ud558\ub098\ub77c\ub3c4
+DownloadManager.error.datamissing=\ub370\uc774\ud130 \uc783\uc5b4\ubc84\ub9bc
+MainWindow.menu.file.open.torrentforseeding=\ud1a0\ub80c\ud2b8 \ud30c\uc77c... (\ubc30\ud3ec\uc6a9)
+MainWindow.menu.language.refresh=\uc0c8\ub85c\uace0\uce68(&R)
+ManagerItem.forced=\uac15\uc81c
+ManagerItem.queued=\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac10
+MySeedersView.header=\uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8
+TableColumn.header.availability.info=\uc9c0\uae08\uae4c\uc9c0 \ubaa9\uaca9\ub41c \uc644\uc804\ud55c \uc0ac\ubcf8 \uc218\uc785\ub2c8\ub2e4.
+TableColumn.header.availability=\uc720\ud6a8\uc131
 TableColumn.header.category=\ubd84\ub958
-MyTorrentsView.header=\ub05d\ub9c8\uce58\uc9c0 \ubabb\ud55c \ud1a0\ub7f0\ud2b8
-TableColumn.header.maxuploads=\ucd5c\uace0 \uc62c\ub9ac\uae30 \uc218
-MyTorrentsView.menu.category.delete=\ubd84\ub958 \uc9c0\uc6b0\uae30(&D)
-MyTorrentsView.menu.forceStart=\uc5b5\uc9c0\ub85c \uc2dc\uc791(&F)
-MyTorrentsView.menu.queue=\ub300\uae30(&Q)
-MyTorrentsView.menu.setCategory.add=\ubd84\ub958 \ub354\ud558\uae30...(&A)
-MyTorrentsView.menu.setCategory=\ubd84\ub958 \uc815\ud558\uae30
-TableColumn.header.savepath=\uc800\uc7a5 \uc704\uce58
-TableColumn.header.SeedingRank=\ubfcc\ub9ac\uae30 \uc21c\uc704
-TableColumn.header.totalspeed.info=\ub2f9\uc2e0\uacfc \uc5f0\uacb0\ub41c \ubaa8\ub4e0 \ub3d9\ub8cc\ub4e4\uc758 \ucd1d \uc18d\ub3c4 
-TableColumn.header.totalspeed=\ucd1d \uc18d\ub3c4
+MyTorrentsView.header=\uc644\ub8cc\ub418\uc9c0 \uc54a\uc740 \ud1a0\ub80c\ud2b8
+TableColumn.header.maxuploads=\ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc218
+MyTorrentsView.menu.category.delete=\ubd84\ub958 \uc0ad\uc81c(&D)
+MyTorrentsView.menu.forceStart=\uac15\uc81c \uc2dc\uc791(&F)
+MyTorrentsView.menu.queue=\uc2dc\uc791 (\ub300\uae30\uc5f4\uc5d0 \ub123\uae30)(&Q)
+MyTorrentsView.menu.setCategory.add=\ubd84\ub958 \ucd94\uac00(&A)...
+MyTorrentsView.menu.setCategory=\ubd84\ub958 \uc9c0\uc815
+TableColumn.header.savepath=\uc800\uc7a5 \uacbd\ub85c
+TableColumn.header.SeedingRank=\ubc30\ud3ec \ub4f1\uae09
+TableColumn.header.totalspeed.info=\uc0ac\uc6a9\uc790\uc640 \uc5f0\uacb0\ub41c \ubaa8\ub4e0 \ud53c\uc5b4\uc758 \uc804\uccb4 \uc18d\ub3c4\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.totalspeed=\uc804\uccb4 \uc18d\ub3c4
 splash.initializePlugins=\ucd94\uac00\uae30\ub2a5\uc744 \ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
-StartStopRules.SPratioMet=\uc528\uc557:\ub3d9\ub8cc \ube44 \uc88b\uc74c
-StartStopRules.FP0Peers=FP / 0 \ub3d9\ub8cc
-StartStopRules.0Peers=0 \ub3d9\ub8cc
-StartStopRules.numSeedsMet=\uc528\uc557 \uc218 \uc88b\uc2b5\ub2c8\ub2e4
-StartStopRules.ratioMet=\ub3d9\ub8cc:\uc528\uc557 \uc88b\uc2b5\ub2c8\ub2e4
-StartStopRules.shareRatioMet=\uacf5\uc720 \ube44 \uc88b\uc2b5\ub2c8\ub2e4
-StartStopRules.waiting=\uae30\ub2e4\ub9ac\uace0 \uc788\uc74c
+StartStopRules.SPratioMet=S:P \ube44\uc728 \uc815\uc0c1
+StartStopRules.FP0Peers=FP / 0 \ud53c\uc5b4
+StartStopRules.0Peers=0 \ud53c\uc5b4
+StartStopRules.numSeedsMet=\uc2dc\ub4dc \uc218 \uc815\uc0c1
+StartStopRules.ratioMet=\ud53c\uc5b4:\uc2dc\ub4dc \uc815\uc0c1
+StartStopRules.shareRatioMet=\uacf5\uc720 \ube44\uc728 \uc815\uc0c1
+StartStopRules.waiting=\uae30\ub2e4\ub9ac\ub294 \uc911
 StartStopRules.firstPriority=\uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\ub0b4\uc6a9 \uacf5\uc720 (\ub418\ud480\uc774)
-DownloadManager.error.unabletostartserver=\uc11c\ubc84\ub97c \uc2dc\uc791\ud560 \uc218 \uc5c6\uc74c - \ub4e4\uc5b4\uc624\ub294 \ud3ec\ud2b8 \uad6c\uc131\uacfc \uc11c\ubc84\ub85c \uc791\ub3d9\ud558\ub294 \ud504\ub85c\uadf8\ub7a8\uc5d0 \ubc29\ud654\ubcbd \ud5c8\uc6a9 \uac80\uc0ac
-GeneralView.label.creationdate=\ub9cc\ub4e4\uc5b4\uc9c4 \uc2dc\uac01: 
-ConfigView.section.tracker.announcescrapepercentage=\uc54c\ub9ac\uae30\uc758 %age\uc5d0 \ub530\ub978 \ubaa8\uc73c\uae30 \uac04\uaca9\n\uc608 200 = 2:1. 0 = \ub3d9\ub8cc\uac00 \uc815\ud558\ub3c4\ub85d \ud568
-ManagerItem.stopping=\uba48\ucd94\uace0 \uc788\uc74c
-ConfigView.section.tracker.announcecacheperiod=\uc54c\ub9bc \uce90\uc2dc (\ubc00\ub9ac\ucd08)
-ConfigView.section.tracker.scrapecacheperiod=\ubaa8\uc73c\uae30 \uce90\uc2dc (\ubc00\ub9ac\ucd08)
-ConfigView.section.tracker.scrapeandcache=\ubaa8\uc73c\uae30\uc640 \uce90\uc2dc
-ConfigView.section.tracker.announcecacheminpeers=\uc54c\ub9bc \uce90\uc2dc\uac00 \uc791\ub3d9\ud558\ub294 \ub3d9\ub8cc \uacbd\uacc4
-MyTrackerView.scrapes=\ubaa8\uc740 \uac83
-fileDownloadWindow.retry=\ub2e4\uc2dc \ud574 \ubd04
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\uace0\uc804\uc2dd \uacf5\uc720 \ub0b4\uc6a9 (\ud558\uc704 \ub514\ub809\ud130\ub9ac \ud3ec\ud568)
+DownloadManager.error.unabletostartserver=\uc11c\ubc84\ub97c \uc2dc\uc791\ud560 \uc218 \uc5c6\uc74c - \ub4e4\uc5b4\uc624\ub294 \ud3ec\ud2b8 \uad6c\uc131\uacfc \uc11c\ubc84\ub85c \ub3d9\uc791\ud558\uae30 \uc704\ud55c \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \ubc29\ud654\ubcbd \ud1b5\uacfc \uc2b9\uc778 \uc124\uc815\uc744 \uac80\uc0ac\ud560 \uac83
+GeneralView.label.creationdate=\uc0dd\uc131 \uc2dc\uac01 :
+ConfigView.section.tracker.announcescrapepercentage=\uc54c\ub9bc\uc758 % \ube44\uc728\uc5d0 \ub530\ub978 \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \uac04\uaca9\n\uc608: 200 = 2:1. 0 = \ud53c\uc5b4\uac00 \uacb0\uc815 \ud558\ub3c4\ub85d \ud568
+ManagerItem.stopping=\uc815\uc9c0\ud558\ub294 \uc911
+ConfigView.section.tracker.announcecacheperiod=\uc54c\ub9bc \uce90\uc2dc (millis)
+ConfigView.section.tracker.scrapecacheperiod=\uc2a4\uc6dc \uc815\ubcf4 \uce90\uc2dc (millis)
+ConfigView.section.tracker.scrapeandcache=\uc2a4\uc6dc \uc815\ubcf4\ub97c \uc218\uc9d1\ud558\uace0 \uce90\uc2dc\ud558\uae30
+ConfigView.section.tracker.announcecacheminpeers=\uc54c\ub9bc \uce90\uc2dc\uac00 \ud53c\uc5b4 \uc784\uacc4\uac12\uc744 \ud65c\uc131\ud654
+MyTrackerView.scrapes=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1
+fileDownloadWindow.retry=\ub2e4\uc2dc \uc2dc\ub3c4
 MyTrackerView.bytesin=\ub4e4\uc5b4\uc628 \ubc14\uc774\ud2b8
 MyTrackerView.bytesinave=\ub4e4\uc5b4\uc628 \ud3c9\uade0
 MyTrackerView.bytesout=\ub098\uac04 \ubc14\uc774\ud2b8
 MyTrackerView.bytesoutave=\ub098\uac04 \ud3c9\uade0
-ConfigView.section.file.max_open_files=\uc77d\uae30/\uc4f0\uae30\ub97c \ud558\ub824\uace0 \uc5ec\ub294 \ucd5c\ub300 \ud30c\uc77c \uc218\n[0: \ubb34\uc81c\ud55c]
-ConfigView.section.file.max_open_files.tooltip=\ub2f9\uc2e0\uc774 \uc218\ubc31 \uc218\ucc9c \uac1c\uc758 \ud30c\uc77c\ub85c \ub41c \ud1a0\ub7f0\ud2b8\ub97c \ub0b4\ub824\ubc1b\uac70\ub098, OS\uc758 \ud30c\uc77c \ub2e4\ub8e8\uae30 \ud55c\uacc4(FAT\uc758 2\uae30\uac00 \ud55c\uacc4\ub4f1)\uc5d0 \ub2e4\ub2e4\ub974\uba74 \uc4f8\ubaa8 \uc788\uc2b5\ub2c8\ub2e4.
-ConfigView.section.proxy=\ud504\ub85d\uc2dc \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.proxy.enable_proxy=\ub354\ub4ec\uc774 \ud1b5\uc2e0 \ud504\ub85d\uc2dc \uc791\ub3d9 [\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568]
+ConfigView.section.file.max_open_files=\uc77d\uae30/\uc4f0\uae30\ub97c \uc704\ud574 \uc5f4\ub9b0 \ucd5c\ub300 \ud30c\uc77c \uc218\n[0: \ubb34\uc81c\ud55c]
+ConfigView.section.file.max_open_files.tooltip=\uc218\ubc31/\uc218\ucc9c\uc758 \ud30c\uc77c\uc774 \ub4e4\uc5b4\uc788\ub294 \ud1a0\ub80c\ud2b8\ub97c \ub2e4\uc6b4\ub85c\ub4dc\ud558\uace0\uc790 \ud560 \ub54c, OS\uac00 \uc218\uc6a9\ud560 \uc218 \uc788\ub294 \ud30c\uc77c\uc758 \uac2f\uc218\uac00 \ud55c\uc815\ub418\uc5b4 \uc788\ub294 \uacbd\uc6b0 \uc720\uc6a9\ud569\ub2c8\ub2e4.
+ConfigView.section.proxy=\ud504\ub85d\uc2dc \uc635\uc158
+ConfigView.section.proxy.enable_proxy=\ud2b8\ub798\ucee4 \ud1b5\uc2e0\uc5d0 \ud504\ub85d\uc2dc \ud65c\uc131\ud654 [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
 ConfigView.section.proxy.host=\ud638\uc2a4\ud2b8
 ConfigView.section.proxy.port=\ud3ec\ud2b8
 ConfigView.section.proxy.username=\uc0ac\uc6a9\uc790 \uc774\ub984
 ConfigView.section.proxy.password=\uc554\ud638
-ConfigView.section.proxy.enable_socks=SOCKS \ud504\ub85d\uc2dc\uac00 \uc788\uc2b5\ub2c8\ub2e4.
-wizard.createtorrent.extrahashes=\ub2e4\ub978 \ub124\ud2b8\uc6cc\ud06c\uc5d0 \ub9de\ub294 \ud574\uc2dc\ub97c \ub354\ud558\uae30(\uc608: Gnutella2, eDonkey2000)
+ConfigView.section.proxy.enable_socks=SOCKS \ud504\ub85d\uc2dc\uac00 \uc788\uc74c
+wizard.createtorrent.extrahashes=\ub2e4\ub978 \ub124\ud2b8\uc6cc\ud06c\ub97c \uc704\ud55c \ud574\uc2dc \ucd94\uac00 (\uc608: Gnutella2, eDonkey2000)
 GeneralView.label.connected=\uc5f0\uacb0\ub428
-GeneralView.label.in_swarm=\uac1c\uac00 \uc9d3\ub294 \ub5bc
-ManagerItem.initializing=\ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
+GeneralView.label.in_swarm=\uc2a4\uc6dc\uc5d0 \uc788\uc74c
+ManagerItem.initializing=\ucd08\uae30\ud654 \uc911
 AlertMessageBox.error=\uc624\ub958
 AlertMessageBox.warning=\uacbd\uace0
-AlertMessageBox.comment=\uc54c\ub9bc
-AlertMessageBox.information=\uc54c\ub9bc
-AlertMessageBox.unread=\uc77d\uc9c0 \uc54a\uc740 \uacbd\uace0 \uc54c\ub9bc\uc774 \uc788\uc2b5\ub2c8\ub2e4 - \ub20c\ub7ec\uc11c \ud655\uc778\ud558\uc138\uc694.
-SharedPortServer.alert.selectorfailed=\ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130 \ub4e3\uae30\ub97c \ub9c8\ub828\ud558\uc9c0 \ubabb\ud568.\n\ubc29\ud654\ubcbd \uc124\uc815\uc5d0\uc11c java(w).exe\uc774 '\uc11c\ubc84'\ub85c \ub3cc\uc544\uac00\uac8c \ub450\uace0 \uc788\ub294\uc9c0 \uac80\uc0ac.
-Tracker.alert.listenfail=%1 \ud3ec\ud2b8\uc5d0 \ub4e3\uae30 \ud3ec\ud2b8 \ub9c8\ub828\ud558\uc9c0 \ubabb\ud568.\n\ub2e4\ub978 \ud504\ub85c\uadf8\ub7a8\uc774 \uc774 \ud3ec\ud2b8\ub97c \uc774\ubbf8 \uc4f0\uace0 \uc788\ub294\uc9c0 \uac80\uc0ac.\n\ub610\ud55c Vuze uc758 \ub2e4\ub978 \ubcf8\uc774 \uc2e4\ud589\ub418\uace0 \uc788\ub294\uc9c0\ub3c4 \uac80\uc0ac.
-DiskManager.alert.movefileexists=\ub05d\ub9c8\uce5c \ud30c\uc77c \uc62e\uae30\uae30 \uc624\ub958\n%1 \ud30c\uc77c\uc740 \uc62e\uae38 \ub300\uc0c1 \ud3f4\ub354\uc5d0 \uc774\ubbf8 \uc788\uc2b5\ub2c8\ub2e4.
-DiskManager.alert.movefilefails=\ub05d\ub9c8\uce5c \ud30c\uc77c \uc62e\uae30\uae30 \uc624\ub958\n%1 \ud30c\uc77c\uc744 \uc62e\uae30\uc9c0 \ubabb\ud568, %2
-DiskManager.alert.movefilerecoveryfails=\uc62e\uae30\uc9c0 \ubabb\ud558\uace0 \ub098\uc11c \ub418\ucc3e\uae30 \uc624\ub958\n%1 \ud30c\uc77c\uc744 \ub418\ub3cc\ub9ac\uc9c0 \ubabb\ud568, %2
-ConfigView.section.tracker.logenable='tracker.log'\ub85c \uc8fc\uae30\uc801\uc778 \ud1b5\uacc4 \ub85c\uadf8 \uc801\uae30
+AlertMessageBox.comment=\uc8fc\uc11d
+AlertMessageBox.information=\uc815\ubcf4
+AlertMessageBox.unread=\uc77d\uc9c0 \uc54a\uc740 \uacbd\uace0 \uba54\uc2dc\uc9c0\uac00 \uc788\uc2b5\ub2c8\ub2e4 - \uc5ec\uae30\ub97c \ub204\ub974\uba74 \ud45c\uc2dc\ub429\ub2c8\ub2e4.
+SharedPortServer.alert.selectorfailed=\ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130\uc5d0 \ub300\ud574 \ub9ac\uc2a4\ub108 \ud655\ub9bd\uc744 \uc2e4\ud328 \ud588\uc2b5\ub2c8\ub2e4.\n\ubc29\ud654\ubcbd \uc124\uc815\uc5d0\uc11c java(w).exe\uc774 '\uc11c\ubc84'\ub85c \ub3d9\uc791\ud560 \uc218 \uc788\uac8c \uc124\uc815\ub418\uc5c8\ub294\uc9c0\ub97c \ud655\uc778\ubc14\ub78d\ub2c8\ub2e4.
+Tracker.alert.listenfail=%1 \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8\ub97c \ud655\ub9bd\ud558\uc9c0 \ubabb\ud588\uc2b5\ub2c8\ub2e4.\n\ub2e4\ub978 \ud504\ub85c\uadf8\ub7a8\uc774 \uc774 \ud3ec\ud2b8\ub97c \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc774 \uc544\ub2cc\uc9c0 \ud655\uc778\ud574\ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.\n\ub610\ud55c \ub2e4\ub978 Vuze\uac00 \uc2e4\ud589\ub418\uace0 \uc788\uc9c0\ub294 \uc54a\uc740\uc9c0\ub3c4 \ud655\uc778 \ud574\ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+DiskManager.alert.movefileexists=\uc644\ub8cc\ub41c \ud30c\uc77c \uc774\ub3d9 \uc624\ub958\n%1 \ud30c\uc77c\uc774 \uc774\ub3d9 \ub300\uc0c1 \ub514\ub809\ud1a0\ub9ac\uc5d0 \uc774\ubbf8 \uc874\uc7ac\ud568
+DiskManager.alert.movefilefails=\uc644\ub8cc\ub41c \ud30c\uc77c \uc774\ub3d9 \uc624\ub958\n%1 \ud30c\uc77c \uc774\ub3d9 \uc2e4\ud328, %2
+DiskManager.alert.movefilerecoveryfails=\uc774\ub3d9 \ud6c4 \ubcf5\uad6c \uc2e4\ud328 \uc624\ub958\n%1 \ud30c\uc77c \ubcf5\uad6c \uc2e4\ud328, %2
+ConfigView.section.tracker.logenable='tracker.log'\ub85c \uc8fc\uae30\uc801\uc778 \ud1b5\uacc4 \ub85c\uadf8
 SpeedView.stats.title=\ud1b5\uacc4
-SpeedView.stats.total=\ucd1d
-SpeedView.stats.session=\uc774 \uc138\uc158
-SpeedView.stats.session.tooltip=\ucd1d (\ud504\ub85c\ud1a0\ucf5c)
-SpeedView.stats.downloaded=\ub0b4\ub824\ubc1b\uc74c (\ud504\ub85c\ud1a0\ucf5c)
-SpeedView.stats.uploaded=\uc62c\ub824\uc9d0 (\ud504\ub85c\ud1a0\ucf5c)
-SpeedView.stats.ratio=\ube44
-SpeedView.stats.uptime=\uc62c\ub9ac\uae30 \uc2dc\uac04
+SpeedView.stats.total=\uc804\uccb4
+SpeedView.stats.session=\ud604\uc7ac \uc138\uc158
+SpeedView.stats.session.tooltip=\uc804\uccb4 (\ud504\ub85c\ud1a0\ucf5c)
+SpeedView.stats.downloaded=\ub2e4\uc6b4\ub85c\ub4dc\ub428 (\ud504\ub85c\ud1a0\ucf5c)
+SpeedView.stats.uploaded=\uc5c5\ub85c\ub4dc\ub428 (\ud504\ub85c\ud1a0\ucf5c)
+SpeedView.stats.ratio=\ube44\uc728
+SpeedView.stats.uptime=\uc5c5\ub85c\ub4dc \uc2dc\uac04
 SpeedView.stats.now=\uc9c0\uae08
-SpeedView.stats.now.tooltip=\ucd1d (\ud504\ub85c\ud1a0\ucf5c)
-AutoMigration.useralert=Vuze \uc0ac\uc6a9\uc790 \uad6c\uc131 \ud30c\uc77c/\ud3f4\ub354\uc758 \uc790\ub3d9 \uc774\ub3d9 \uacb0\uacfc:\n\n%1\n\uba87 \uac00\uc9c0 \uc798\ubabb\ub41c \uac83\ub4e4\uc740 \uc190\uc218 \uc62e\uaca8\uc57c \ud569\ub2c8\ub2e4.\n\uc62e\uae34 \ub2e4\uc74c\uc5d0\ub294 \ubc18\ub4dc\uc2dc \uc120\ud0dd\uc0ac\ud56d\uc5d0\uc11c \ub2f9\uc2e0\uc758 \uc800\uc7a5 \uc704\uce58\ub97c \uc0c8\ub85c \uc124\uc815\ud558\uc138\uc694!
+SpeedView.stats.now.tooltip=\uc804\uccb4 (\ud504\ub85c\ud1a0\ucf5c)
+AutoMigration.useralert=Vuze \uc0ac\uc6a9\uc790 \uc124\uc815 \ud30c\uc77c/\ud3f4\ub354 \uc790\ub3d9\ub9c8\uc774\uadf8\ub808\uc774\uc158 \uacb0\uacfc:\n\n%1\n\uc2e4\ud328\ud55c \uac83\ub4e4\uc740 \ubc18\ub4dc\uc2dc \uc218\ub3d9\uc73c\ub85c \ub9c8\uc774\uadf8\ub808\uc774\uc158 \ud574\uc57c\ud569\ub2c8\ub2e4.\n***\uc124\uc815\uc0c1 \uc800\uc7a5 \uacbd\ub85c\uac00 \ubc14\ub010 \uacbd\uc6b0 \ud574\ub2f9 \uacbd\ub85c\ub97c \uc0c8 \uacbd\ub85c\ub85c \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \uac83\u [...]
 #
 # > 2.0.8.0
 #
-OpenTorrentWindow.title=\ud1a0\ub7f0\ud2b8 \uc5f4\uae30
-OpenTorrentWindow.message=\uc2dc\ud5d8
-OpenTorrentWindow.addFiles=\ud30c\uc77c \ucd94\uac00
-OpenTorrentWindow.dataLocation=\uc790\ub8cc\ub97c \uc800\uc7a5\ud560 \uc704\uce58:
-OpenTorrentWindow.startMode=\ubc29\uc2dd \ub354\ud558\uae30
-OpenTorrentWindow.startMode.queued=\ub300\uae30
-OpenTorrentWindow.startMode.stopped=\uba48\ucda4
-OpenTorrentWindow.startMode.forceStarted=\uc5b5\uc9c0\ub85c \uc2dc\uc791\ud568
+OpenTorrentWindow.title=\ud1a0\ub80c\ud2b8 \uc5f4\uae30
+OpenTorrentWindow.message=\uc2dc\ud5d8\uc801
+OpenTorrentWindow.addFiles=\ud30c\uc77c \ucd94\uac00(&A)
+OpenTorrentWindow.dataLocation=\ub370\uc774\ud130 \uc800\uc7a5 \uc704\uce58:
+OpenTorrentWindow.startMode=\ucd94\uac00 \ubaa8\ub4dc
+OpenTorrentWindow.startMode.queued=\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac10
+OpenTorrentWindow.startMode.stopped=\uc815\uc9c0\ub428
+OpenTorrentWindow.startMode.forceStarted=\uac15\uc81c\ub85c \uc2dc\uc791\ub428
 OpenTorrentWindow.addPosition=\ub300\uae30\uc5f4 \uc704\uce58
 OpenTorrentWindow.addPosition.first=\ucc98\uc74c
 OpenTorrentWindow.addPosition.last=\ub9c8\uc9c0\ub9c9
-TableColumn.header.remaining.info=\ub0b4\ub824\ubc1b\uc544\uc57c \ud560 \uc591
+TableColumn.header.remaining.info=\ub0a8\uc740 \ub2e4\uc6b4\ub85c\ub4dc \ucd1d\uacc4\uc785\ub2c8\ub2e4.
 TableColumn.header.remaining=\ub0a8\uc74c
-ConfigView.section.tracker.enablecompact=\uc870\uadf8\ub9c8\ud55c \uc54c\ub9ac\uae30 \ud504\ub85c\ud1a0\ucf5c \uc791\ub3d9
-ConfigView.section.tracker.enablekey=\ub192\uc740 \ubcf4\uc548\uc744 \uc704\ud574\uc11c \uc5f4\uc1e0\ub85c \ub354\ub4ec\uc774 \uc9c0\ub098\uae30 \uc791\ub3d9
-ConfigView.section.file.perf=\uc2e4\ud589 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.file.perf.explain=\uacbd\uace0 - \uc774 \ub9e4\uac1c \ubcc0\uc218\ub4e4\uc744 \uc54c\ub9de\uc9c0 \uc54a\uac8c \ubc14\uafb8\uba74 \ub0b4\ub824\ubc1b\uae30 \uc131\ub2a5\uc5d0 \uac70\uc2a4\ub974\ub294 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4.\n\ud639\uc2dc "out of memory(\uba54\ubaa8\ub9ac \ubc16\uc73c\ub85c)" \ubb38\uc81c\uac00 \uc0dd\uae30\uba74, \ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \uc5f0\ [...]
-ConfigView.section.file.max_open_files.explain=\ub108\ubb34 \ub9ce\uc740 \ud30c\uc77c\uc744 \uc5ec\ub294 \uac83\uc740 \ud30c\uc77c \ub2e4\ub8e8\uae30\uc640 \uac19\uc740 \ud55c\uc815\ub41c \uc790\uc6d0 \ub54c\ubb38\uc5d0 \uc6b4\uc601 \uccb4\uacc4 \ubb38\uc81c\ub97c \uc77c\uc73c\ud0ac \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774\uac83\uc740 \ud568\uaed8 \uc5ec\ub294 \ud30c\uc77c\uc758 \uc218\ub97c \uc81c\ud55c\ud569\ub2c8\ub2e4.
+ConfigView.section.tracker.enablecompact=\uc791\uc740 \uc54c\ub9bc \ud504\ub85c\ud1a0\ucf5c \ud65c\uc131\ud654
+ConfigView.section.tracker.enablekey=\uac15\ud654\ub41c \ubcf4\uc548\uc744 \uc704\ud574 \ud2b8\ub798\ucee4\ub85c \ud0a4 \uc804\ub2ec \ud65c\uc131\ud654
+ConfigView.section.file.perf=\uc131\ub2a5 \uc635\uc158
+ConfigView.section.file.perf.explain=\uacbd\uace0 - \uc774 \ud30c\ub77c\ubbf8\ud130 \uac12\ub4e4\uc5d0 \ub300\ud55c \ubb34\uc870\uac74\uc801\uc778 \ubcc0\uacbd\uc740 \ub2e4\uc6b4\ub85c\ub4dc \uc131\ub2a5\uc5d0 \uc801\ub300\uc801\uc778 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uac12\uc744 \ubcc0\uacbd\ud55c \ud6c4\uc5d0\ub294 \ub2e4\uc2dc \uc2dc\uc791 \ud574\uc57c \ud569\ub2c8\ub2e4.\n"\uba54\ubaa8\ub9ac \ucd08\uacfc" \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc744 \ua [...]
+ConfigView.section.file.max_open_files.explain=\ub108\ubb34 \ub9ce\uc740 \ud30c\uc77c\uc744 \uc5ec\ub294 \uac83\uc740 \ud55c\uc815\ub41c \uc790\uc6d0 \ubb38\uc81c\ub85c \uc778\ud574 \uc6b4\uc601\uccb4\uc81c\uac00 \ubb38\uc81c\ub97c \uc77c\uc73c\ud0a4\ub3c4\ub85d \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uc635\uc158\uc740 \ub3d9\uc2dc\uc5d0 \uc5f4\ub9ac\ub294 \ud30c\uc77c \uc218\ub97c \uc81c\ud55c\ud569\ub2c8\ub2e4.
 popup.error.hide=\uc228\uae30\uae30
-popup.error.details=\uc0c1\uc138 \uc815\ubcf4
-ConfigView.section.style.colorOverrides=\ube5b\uae54 \ubb34\uc2dc
+popup.error.details=\uc138\ubd80\uc0ac\ud56d
+ConfigView.section.style.colorOverrides=\uc0c9 \uc6b0\uc120\uc801\uc6a9
 ConfigView.section.style.colorOverride.progressBar=\uc9c4\ud589 \ub9c9\ub300
 ConfigView.section.style.colorOverride.error=\uc624\ub958
-MainWindow.status.tooOld=\uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uc5c5\ub370\uc774\ud2b8\ud558\uc2ed\uc2dc\uc694.
+MainWindow.status.tooOld=\uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \uc5c5\ub370\uc774\ud2b8 \ubc14\ub78d\ub2c8\ub2e4.
 ConfigView.section.style.colorOverride.warning=\uacbd\uace0
-ConfigView.section.style.colorOverride.altRow=\ubc88\uac08\uc544 \uc788\ub294 \uc904
-ConfigView.section.file.save.peers.enable=\ube60\ub978 \ub2e4\uc2dc \uc787\uae30\ub97c \ud558\ub824\uace0 \ub3d9\ub8cc \uc5f0\uacb0\uc744 \uc800\uc7a5
-ConfigView.section.file.save.peers.max=\uc800\uc7a5\ud560 \ucd5c\ub300 \ub3d9\ub8cc \uc218 [0: \ubb34\uc81c\ud55c]
-ConfigView.section.file.save.peers.pertorrent=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \ub3d9\ub8cc \uc218
-ConfigView.label.max_peers_per_torrent=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \ucd5c\ub300 \uc5f0\uacb0 \uc218 [0: \ubb34\uc81c\ud55c]
-ConfigView.label.max_peers_total=\ucd5c\ub300 \ucd1d \uc5f0\uacb0 \uc218 [0: \ubb34\uc81c\ud55c]
-ConfigView.section.style.colorOverrides.reset=\ube5b\uae54 \ucc98\uc74c \uac12\uc73c\ub85c
-ConfigView.section.language.info=\uc791\ub3d9\ud558\uba74 Vuze uac00 \uc2dc\uc791\ud560 \ub54c\ub9c8\ub2e4 \uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac\ub97c \ud569\ub2c8\ub2e4.
-ConfigView.section.language.enableUpdate=\uc6f9 \uc5c5\ub370\uc774\ud2b8 \uc791\ub3d9
-ConfigView.section.language.UpdateURL=\uc5c5\ub370\uc774\ud2b8 \uc8fc\uc18c
-ConfigView.section.language.UpdateNow=\uc9c0\uae08 \uc5c5\ub370\uc774\ud2b8
-Button.revert=\ubcf5\uad6c
-MyTorrentsView.menu.changeDirectory=\ub370\uc774\ud130 \ud3f4\ub354 \ubc14\uafb8\uae30
-GenericText.column=\uc138\ub85c\uc904
-MyTorrentsView.menu.thisColumn.remove=\uc138\ub85c\uc904 \uc9c0\uc6b0\uae30
-MyTorrentsView.menu.thisColumn.toClipboard=\ud14d\uc2a4\ud2b8\ub97c \ud074\ub9bd\ubcf4\ub4dc\ub85c \ubcf5\uc0ac
-MyTorrentsView.menu.thisColumn.autoTooltip=\ud56d\uc0c1 \uadc0\ub754 \ubcf4\uc5ec\uc8fc\uae30
-MyTorrentsView.menu.tracker=\ub354\ub4ec\uc774
-ConfigView.download.abbreviated=\ub0b4\ub9bc:
-ConfigView.upload.abbreviated=\uc62c\ub9bc:
-ConfigView.complete.abbreviated=\ub05d:
-TableColumn.header.secondsseeding=\ub2e4\uc74c\uc5d0 \ubfcc\ub9ac\uae30
-TableColumn.header.secondsseeding.info=\uc774\uc81c\uae4c\uc9c0 \ubfcc\ub9b0 \uc804\uccb4 \uc2dc\uac04
-TableColumn.header.secondsdownloading=\ub2e4\uc74c\uc5d0 \ub0b4\ub824\ubc1b\uae30
-TableColumn.header.secondsdownloading.info=\uc774\uc81c\uae4c\uc9c0 \ub0b4\ub824\ubc1b\uc740 \uc2dc\uac04
+ConfigView.section.style.colorOverride.altRow=\uc904\ubb34\ub2ac \ud589
+ConfigView.section.file.save.peers.enable=\ube60\ub978 \ub2e4\uc2dc \uc5f0\uacb0\uc744 \uc704\ud574 \ud53c\uc5b4 \uc5f0\uacb0\uc744 \uc800\uc7a5
+ConfigView.section.file.save.peers.max=\uc800\uc7a5\ud560 \ucd5c\ub300 \ud53c\uc5b4 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.file.save.peers.pertorrent=\ud1a0\ub80c\ud2b8\ub9c8\ub2e4
+ConfigView.label.max_peers_per_torrent=\ud1a0\ub80c\ud2b8 \ubcc4 \ucd5c\ub300 \uc5f0\uacb0 \uae30\ubcf8\uac12 [0: \ubb34\uc81c\ud55c]
+ConfigView.label.max_peers_total=\uc804\uc5ed \ucd5c\ub300 \uc5f0\uacb0 \uc218 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.style.colorOverrides.reset=\uc0c9 \ucd08\uae30\ud654
+ConfigView.section.language.info=\ud65c\uc131\ud654 \uc2dc Vuze\uac00 \uc2dc\uc791\ud560 \ub54c\ub9c8\ub2e4 \uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac\ub97c \uc218\ud589\ud569\ub2c8\ub2e4.
+ConfigView.section.language.enableUpdate=\uc6f9 \uc5c5\ub370\uc774\ud2b8 \ud65c\uc131\ud654
+ConfigView.section.language.UpdateURL=\uc5c5\ub370\uc774\ud2b8 URL
+ConfigView.section.language.UpdateNow=\uc9c0\uae08 \uc5c5\ub370\uc774\ud2b8!
+Button.revert=\ub418\ub3cc\ub9ac\uae30
+MyTorrentsView.menu.changeDirectory=\ub370\uc774\ud130 \ub514\ub809\ud130\ub9ac \ubcc0\uacbd
+GenericText.column=\uc5f4
+MyTorrentsView.menu.thisColumn.remove=\uc5f4 \uc81c\uac70
+MyTorrentsView.menu.thisColumn.toClipboard=\ud14d\uc2a4\ud2b8\ub97c \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac
+MyTorrentsView.menu.thisColumn.autoTooltip=\ud56d\uc0c1 \ud234\ud301 \ud45c\uc2dc
+MyTorrentsView.menu.tracker=\ud2b8\ub798\ucee4/\ud1a0\ub80c\ud2b8
+TableColumn.header.secondsseeding=\ubc30\ud3ec \uc2dc\uac04
+TableColumn.header.secondsseeding.info=\ubc30\ud3ec\ud55c \uc2dc\uac04\uc758 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
+TableColumn.header.secondsdownloading=\ub2e4\uc6b4 \uc2dc\uac04
+TableColumn.header.secondsdownloading.info=\ub2e4\uc6b4\ub85c\ub4dc\ud55c \uc2dc\uac04\uc758 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
 ConfigView.section.tracker.udpversion=UDP \ud504\ub85c\ud1a0\ucf5c \ubc84\uc804 (1 \ub610\ub294 2)
-window.updateswt.title=SWT \ubc84\uc804\uc774 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
-window.updateswt.text=SWT \ubc84\uc804\uc774 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\nSWT\ub294 Vuze \uc5d0\uc11c \uc4f0\uc774\ub294 \uadf8\ub798\ud53d \ub77c\uc774\ube0c\ub7ec\ub9ac\ub85c, \uac00\uc9c0\uace0 \uc788\ub294 \ubc84\uc804\uc774 \ucd5c\uc2e0 Vuze \ubc84\uc804\uc744 \uc2e4\ud589\ud558\uae30\uc5d0\ub294 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4. SWT\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\ub824\uba74 \ud655\uc778 \ub2e8\ucd94\ub97c \ub204\ub974\uc2ed [...]
+window.updateswt.title=SWT \ubc84\uc804\uc774 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4!
+window.updateswt.text=SWT \ubc84\uc804\uc774 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\nSWT\ub294 Vuze \uc5d0\uc11c \uc4f0\uc774\ub294 \uadf8\ub798\ud53d \ub77c\uc774\ube0c\ub7ec\ub9ac\ub85c, \uac00\uc9c0\uace0 \uc788\ub294 \ubc84\uc804\uc774 \ucd5c\uc2e0 Vuze \ubc84\uc804\uc744 \uc2e4\ud589\ud558\uae30\uc5d0\ub294 \ub108\ubb34 \uc624\ub798\ub418\uc5c8\uc2b5\ub2c8\ub2e4. SWT\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\ub824\uba74 \ud655\uc778\uc744 \ub204\ub974\uc2ed\uc2dc\uc624.
 window.updateswt.status=\uc0c1\ud0dc
 window.updateswt.failed=\uc5c5\ub370\uc774\ud2b8\ud558\uc9c0 \ubabb\ud558\uc600\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc2dc\uc791\ud558\ub824\uba74 \ud655\uc778\uc744 \ub204\ub974\uc2ed\uc2dc\uc694.
-window.updateswt.status.downloading.updater=\uc5c5\ub370\uc774\ud2b8 \ubaa8\ub4c8\uc744 \ub0b4\ub824\ubc1b\uace0 \uc788\uc74c
-window.updateswt.status.finding=\ucd5c\uc2e0 SWT \ubc84\uc804\uc744 \ucc3e\uace0 \uc788\uc74c
-window.updateswt.status.downloading=\ucd5c\uc2e0 SWT \ubc84\uc804\uc744 \ub0b4\ub824\ubc1b\uace0 \uc788\uc74c
-window.updateswt.status.done=\ub2e4\uc2dc \uc2dc\uc791\ud558\uace0 \uc788\uc74c
-window.updateswt.ok=\ud655\uc778
+window.updateswt.status.downloading.updater=\uc5c5\ub370\uc774\ud130 \ubaa8\ub4c8 \ub2e4\uc6b4\ub85c\ub4dc \uc911
+window.updateswt.status.finding=\ucd5c\uc2e0 SWT \ubc84\uc804 \uac80\uc0c9 \uc911
+window.updateswt.status.downloading=\ucd5c\uc2e0 SWT \ubc84\uc804 \ub2e4\uc6b4\ub85c\ub4dc \uc911
+window.updateswt.status.done=\ub2e4\uc2dc \uc2dc\uc791 \uc911
+window.updateswt.ok=\uc815\uc0c1
 window.updateswt.cancel=\ucde8\uc18c
-swt.updater.downloader.downloading=\ub2e4\uc74c\uc5d0\uc11c SWT \ub0b4\ub824\ubc1b\uae30
-swt.updater.urlsgetter.downloading=\ub2e4\uc74c\uc5d0\uc11c \ubbf8\ub7ec \ub9ac\uc2a4\ud2b8 \uc5bb\uc74c
-swt.updater.urlsgetter.platform=\uc6b4\uc601 \uccb4\uacc4\uc5d0 \ub9de\ub294 SWT: 
+swt.updater.downloader.downloading=\ub2e4\uc74c\uc5d0\uc11c SWT \ub2e4\uc6b4\ub85c\ub4dc \uc911
+swt.updater.urlsgetter.downloading=\ub2e4\uc74c\uc5d0\uc11c \ubbf8\ub7ec \ub9ac\uc2a4\ud2b8 \uc5bb\ub294 \uc911
+swt.updater.urlsgetter.platform=\ud50c\ub7ab\ud3fc\uc744 \uc704\ud55c SWT :
 window.updateswt.ignore=\ubb34\uc2dc
-ConfigView.section.style.useFancyTabs=\ud654\ub824\ud55c \ud0ed\uc744 \uc500
-splash.initializeGM=\uc804\uccb4 \ud1a0\ub7f0\ud2b8 \uad00\ub9ac\uc790\ub97c \ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
-splash.loadingTorrents=\ud1a0\ub7f0\ud2b8\ub4e4\uc744 \ubd88\ub7ec\uc624\uace0 \uc788\uc74c
+ConfigView.section.style.useFancyTabs=\ubbf8\ub824\ud55c \ubaa8\uc591\uc758 \ud0ed \uc0ac\uc6a9
+splash.initializeGM=\uc804\uc5ed \ud1a0\ub80c\ud2b8 \uad00\ub9ac\uc790\ub97c \ucd08\uae30\ud654 \ud558\ub294 \uc911
+splash.loadingTorrents=\ud1a0\ub80c\ud2b8 \uc801\uc7ac \uc911
 MyTorrentsView.menu.thisColumn.sort=\uc815\ub82c(&S)
-Scrape.status.ok=\ubaa8\uc73c\uae30 \uc88b\uc74c
-Scrape.status.error=\ubaa8\uc73c\uae30 \uc624\ub958: 
-Scrape.status.error.badURL=\ub354\ub4ec\uc774 \uc54c\ub9bc \uc8fc\uc18c(Announce URL)\uac00 \ubaa8\uc73c\uae30 \uc591\uc2dd\uc744 \ub530\ub974\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
-Scrape.status.error.nohash=\ud574\uc2dc\uac00 \ub2f5\uc5d0\uc11c \ube60\uc9d0
-Scrape.status.error.invalid=\uc798\ubabb\ub41c \ub2f5
-Scrape.status.nextScrapeAt=%1\uc5d0\uc11c \ub2e4\uc74c \ubaa8\uc73c\uae30
-Scrape.status.scraping=\ubaa8\uc73c\uace0 \uc788\uc74c..
-Scrape.status.initializing=\ubaa8\uc73c\ub824\uace0 \ud558\uace0 \uc788\uc74c
-Scrape.status.scraping.queued=\ubaa8\uc73c\uae30 \ub300\uae30 \uc21c\uc11c..
-ConfigView.label.minSpeedForActiveSeeding=\uc18d\ub3c4\uac00 \uc774\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c0\uba74 \uc790\ub9ac\ub97c \uc4f0\uace0 \uc788\ub294 \ub05d\ub9c8\uce5c \ud1a0\ub7f0\ud2b8\ub97c \uc138\uc9c0 \uc54a\uc74c
-ConfigView.section.stats.exportpeers=\ub3d9\ub8cc \uc0c1\uc138 \uc815\ubcf4 \ub0b4\ubcf4\ub0b4\uae30
-MainWindow.menu.view.irc.moved=IRC\ub294 \ucd94\uac00\uae30\ub2a5\uc73c\ub85c \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4. http://azureus.sourceforge.net/plugin_list.php\ub97c \ucc38\uace0\ud558\uc138\uc694. \ucd94\uac00\uae30\ub2a5\uc774 \uc124\uce58\ub418\uc5c8\uc73c\uba74 \uba54\ub274 \ubaa8\uc74c\uc5d0\uc11c \ucd94\uac00\uae30\ub2a5->IRC \uba54\ub274\ub97c \uc4f0\uc2ed\uc2dc\uc694.
-MyTrackerView.webui.contextmenu.copyurl=\ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ud1a0\ub7f0\ud2b8 \uc8fc\uc18c\ub97c \ubcf5\uc0ac
-ConfigView.section.file.torrent.ignorefiles=\ud1a0\ub7f0\ud2b8 \ub9cc\ub4e4 \ub54c \ubb34\uc2dc\ud560 \ud30c\uc77c\ub4e4\n\uc608 .DS_Store;Thumbs.db
+Scrape.status.ok=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \uc815\uc0c1
+Scrape.status.error=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \uc624\ub958:
+Scrape.status.error.badURL=\uc54c\ub9bc URL\uc774 \uc2a4\uc6dc \uc815\ubcf4 \uad50\ud658 \uba85\uc138\ub97c \ub530\ub974\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+Scrape.status.error.nohash=\uc751\ub2f5\uc5d0 \ud574\uc26c\uac00 \ube60\uc84c\uc2b5\ub2c8\ub2e4.
+Scrape.status.error.invalid=\uc798\ubabb\ub41c \uc751\ub2f5\uc785\ub2c8\ub2e4.
+Scrape.status.nextScrapeAt=\ub2e4\uc74c \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1: %1
+Scrape.status.scraping=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \uc911...
+Scrape.status.initializing=\uc2a4\uc6dc \uc815\ubcf4 \uac00\uc838\uc624\uae30\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911...
+Scrape.status.scraping.queued=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \uc791\uc5c5\uc774 \ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac10...
+ConfigView.label.minSpeedForActiveSeeding=\uc9c0\uc815\ud55c \uc18d\ub3c4 \uc774\ud558\ub85c \ub5a8\uc5b4\uc9c0\ub294 \uacbd\uc6b0 \uc2ac\ub86f\uc744 \uc0ac\uc6a9\ud558\ub294 \uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8\ub85c \uce74\uc6b4\ud2b8\ud558\uc9c0 \uc54a\uc74c
+ConfigView.section.stats.exportpeers=\ud53c\uc5b4 \uc138\ubd80\uc0ac\ud56d \ub0b4\ubcf4\ub0b4\uae30
+MainWindow.menu.view.irc.moved=IRC\ub294 \uc774\uc81c \ud50c\ub7ec\uadf8\uc778\uc73c\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. http://azureus.sourceforge.net/plugin_list.php \ucc38\uace0.\n\uc124\uce58\ud55c \ud6c4 \ubcf4\uae30\u2192\ud50c\ub7ec\uadf8\uc778\u2192IRC \uba54\ub274\ub97c \ud1b5\ud574 \uc811\uadfc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+MyTrackerView.webui.contextmenu.copyurl=\ud1a0\ub80c\ud2b8 URL\uc744 \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac
+ConfigView.section.file.torrent.ignorefiles=\ud1a0\ub80c\ud2b8\ub97c \uc0dd\uc131\ud558\uac70\ub098 \uc0ad\uc81c\ud560 \ub54c \ubb34\uc2dc\ud560 \ud30c\uc77c\n - \uc608: .DS_Store;Thumbs.db
 Torrent.create.progress.ignoringfile=\ud30c\uc77c \ubb34\uc2dc\ud558\uace0 \uc788\uc74c
-ConfigView.section.style.useUnitsRateBits=\ubc14\uc774\ud2b8\uc5d0 \ubc14\ud0d5\uc744 \ub454 \uc18d\ub3c4 \uac12\uc5d0 \ubc14\uc774\ud2b8 \ub300\uc2e0\uc5d0 \ube44\ud2b8\ub97c \uc500 (KiB/s -> Kibit/s \ub4e4)
-ConfigView.section.interface.resetassoc=\ud30c\uc77c(.torrent) \uc5f0\uacb0 \ud504\ub85c\uadf8\ub7a8 \ucc98\uc74c \uac12\uc73c\ub85c
-ConfigView.section.interface.resetassocbutton=\ucc98\uc74c \uac12\uc73c\ub85c
-ConfigView.section.interface.checkassoc=\uc2dc\uc791\ud560 \ub54c \uc5f0\uacb0 \ud504\ub85c\uadf8\ub7a8 \uac80\uc0ac
+ConfigView.section.style.useUnitsRateBits=\uc18d\ub3c4\ub97c \ubcf4\uc5ec\uc904 \ub54c \ubc14\uc774\ud2b8 \ub300\uc2e0 \ube44\ud2b8\ub97c \uc0ac\uc6a9 (KiB/s\u2192Kibit/s, \ub4f1)
+ConfigView.section.interface.resetassoc=\ud0d0\uc0c9\uae30 \ud30c\uc77c \uc5f0\uacb0 (.torrent) \ucd08\uae30\ud654
+ConfigView.section.interface.resetassocbutton=\ucd08\uae30\ud654
+ConfigView.section.interface.checkassoc=\uc2dc\uc791 \uc2dc \uc5f0\uacb0 \uac80\uc0ac
 dialog.associations.title=\uc5f0\uacb0 \uac80\uc0ac
-Button.yes=\uc608 &Y
-Button.no=\uc544\ub2c8\uc624 &N
-ConfigView.label.seeding.autoStart0Peers=0 \ub3d9\ub8cc\uc778 \ub05d\ub9c8\uce5c \ubaa8\ub4e0 \ud1a0\ub7f0\ud2b8\ub97c \uc800\uc808\ub85c \uc2dc\uc791
-ConfigView.label.seeding.autoStart0Peers.tooltip=0 \ub3d9\ub8cc\uc778 \ud1a0\ub7f0\ud2b8\uc5d0 \ub354\ub4ec\uc774\uac00 \ub298 \uc528\uc557\uc744 \uc62c\ub9ac\ub824\uba74 \ucf1c\uc2ed\uc2dc\uc694.
-dialog.associations.prompt=Vuze\uac00 BitTorrent \ud30c\uc77c\uc758 \uae30\ubcf8 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\uc774 \uc544\ub2d9\ub2c8\ub2e4.\n\ud1a0\ub7f0\ud2b8 \ud30c\uc77c\uc744 Vuze\uc5d0 \uc5f0\uacb0\ud558\uaca0\uc2b5\ub2c8\uae4c?
-dialog.associations.askagain=\uc2dc\uc791\ud560 \ub54c \uac80\uc0ac
-ConfigView.section.plugins.update=\ucd94\uac00\uae30\ub2a5 \uc5c5\ub370\uc774\ud2b8
-Plugin.pluginupdate.enablecheck=\ucd94\uac00\uae30\ub2a5 \uc5c5\ub370\uc774\ud2b8 \ud655\uc778 \ud65c\uc131\ud654
+Button.yes=\uc608(&Y)
+Button.no=\uc544\ub2c8\uc624(&N)
+ConfigView.label.seeding.autoStart0Peers=0 \ud53c\uc5b4\uc778 \ubaa8\ub4e0 \uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8 \uc790\ub3d9 \uc2dc\uc791
+ConfigView.label.seeding.autoStart0Peers.tooltip=0 \ud53c\uc5b4 \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud574 \ud2b8\ub798\ucee4\uac00 \ud56d\uc0c1 \uc2dc\ub4dc\ub97c \uc5f4\uac70 \ud558\ub3c4\ub85d \ud558\ub824\uba74 \ucf2d\ub2c8\ub2e4.
+dialog.associations.prompt=Vuze\uac00 BitTorrent \ud30c\uc77c\uc758 \uae30\ubcf8 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8\uc774 \uc544\ub2d9\ub2c8\ub2e4.\n.torrent \ud30c\uc77c\uc744 Vuze\uc5d0 \uc5f0\uacb0\ud558\uaca0\uc2b5\ub2c8\uae4c?
+dialog.associations.askagain=\uc2dc\uc791 \uc2dc \uac80\uc0ac
+ConfigView.section.plugins.update=\ud50c\ub7ec\uadf8\uc778 \uc5c5\ub370\uc774\ud2b8
+Plugin.pluginupdate.enablecheck=\ud50c\ub7ec\uadf8\uc778 \uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac \ud65c\uc131\ud654
 plugins.basicview.status=\uc0c1\ud0dc:
 plugins.basicview.activity=\ud65c\ub3d9:
-plugins.basicview.progress=\uc9c4\ud589
+plugins.basicview.progress=\uc9c4\ud589:
 plugins.basicview.log=\ub85c\uadf8:
-ConfigView.label.maxdownloadspeed=KB/s \ucd5c\uace0 \ucd1d \ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
-splash.loadingTorrent=\ud1a0\ub7f0\ud2b8\ub97c \ubd88\ub7ec\uc624\uace0 \uc788\uc74c
+ConfigView.label.maxdownloadspeed=KB/s \uc804\uc5ed \ucd5c\uace0 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+splash.loadingTorrent=\ud1a0\ub80c\ud2b8 \uc801\uc7ac \uc911
 splash.of=:
-UpdateWindow.title=Vuze \uc5c5\ub370\uc774\ud2b8
+UpdateWindow.title=Vuze \uc5c5\ub370\uc774\ud130
 UpdateWindow.header=\ub2e4\uc74c \uad6c\uc131 \uc694\uc18c\ub4e4\uc744 \uc5c5\ub370\uc774\ud2b8\ud574\uc57c \ud569\ub2c8\ub2e4.:
 UpdateWindow.columns.install=\uc124\uce58
 UpdateWindow.columns.name=\uc774\ub984
 UpdateWindow.columns.version=\ubc84\uc804
 UpdateWindow.columns.size=\ud06c\uae30
 UpdateWindow.cancel=\ucde8\uc18c
-UpdateWindow.quit=\ub098\uac00\uae30
+UpdateWindow.quit=\uc885\ub8cc
 UpdateWindow.close=\ub2eb\uae30
 UpdateWindow.ok=\uc5c5\ub370\uc774\ud2b8
-UpdateWindow.restart=\ub2e4\uc2dc \uc2dc\uc791
-UpdateWindow.status.downloading=\ub0b4\ub824\ubc1b\uae30\ud558\uace0 \uc788\uc74c
-UpdateWindow.status.done=\ub9c8\uce68
-UpdateWindow.status.failed=\ud558\uc9c0 \ubabb\ud568
-UpdateWindow.status.restartNeeded=\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4.
+UpdateWindow.restart=\uc9c0\uae08 Vuze \ub2e4\uc2dc \uc2dc\uc791
+UpdateWindow.status.downloading=\ub2e4\uc6b4\ub85c\ub4dc \uc911
+UpdateWindow.status.done=\uc644\ub8cc
+UpdateWindow.status.failed=\uc2e4\ud328\ud568
+UpdateWindow.status.restartNeeded=\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4!
 ConfigView.pluginlist.broken=\uae68\uc9d0
-ConfigView.pluginlist.whereToPut=\uc0ac\uc6a9\uc790 \ucd94\uac00\uae30\ub2a5\uc744 \uc544\ub798\uc640 \uac19\uc740 \uc0ac\uc6a9\uc790 \ud3f4\ub354\uc5d0 \ub123\uc73c\uc2ed\uc2dc\uc694:
-ConfigView.pluginlist.whereToPutOr=\uacf5\uc720 \ucd94\uac00\uae30\ub2a5\uc744 \uc4f0\ub824\uba74 \uc544\ub798\uc640 \uac19\uc740 \ud3f4\ub354\uc5d0 \ub123\uc73c\uc2ed\uc2dc\uc694:
-MainWindow.statusText.checking=\uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac\ud558\uace0 \uc788\uc74c
-TableColumn.header.OnlyCDing4=\ub2e4\uc74c\uc5d0 \ubfcc\ub9ac\uae30\ub9cc
-TableColumn.header.OnlyCDing4.info=\uc774\uc81c\uae4c\uc9c0 \ubfcc\ub9ac\uae30\ub9cc \ud55c \uc2dc\uac04.  \ub0b4\ub824\ubc1b\uae30\ud558\uace0 \ub098\uc11c (\ubfcc\ub9b0) \uc2dc\uac04\uc740 \ube8c.
-ConfigView.section.style.alternateTablePainting=\uadf8\ub798\ud53d \ubaa9\ub85d \uc138\ub85c\uc904\uc744 \uafb8\ubbf8\ub824\uace0 \ubc88\uac08\uc544 \ud558\ub294 \ubc29\ubc95\uc744 \uc500 (\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud560 \uc218 \uc788\uc74c)
-UpdateWindow.status.restartMaybeNeeded=\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+ConfigView.pluginlist.whereToPut=\ub2e4\uc74c \ub514\ub809\ud1a0\ub9ac\uc5d0 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \ud50c\ub7ec\uadf8\uc778\uc744 \uc704\uce58\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4:
+ConfigView.pluginlist.whereToPutOr=\uacf5\uc720 \ud50c\ub7ec\uadf8\uc778\uc774 \uc0ac\uc6a9\ud558\ub294 \ub514\ub809\ud130\ub9ac\ub294:
+MainWindow.statusText.checking=\uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac\uc911
+TableColumn.header.OnlyCDing4=\ubc30\ud3ec\ub9cc \ud55c \uc2dc\uac04
+TableColumn.header.OnlyCDing4.info=\ud1a0\ub80c\ud2b8 \ubc30\ud3ec\ub9cc \uc774\ub8e8\uc5b4\uc9c4 \uc2dc\uac04\uc758 \ucd1d\uacc4\uc785\ub2c8\ub2e4.  \ud1a0\ub80c\ud2b8\uac00 \ub2e4\uc6b4\ub85c\ub4dc\ud55c (\ub2e4\uc6b4\ub85c\ub4dc\uc640 \ubc30\ud3ec\uac00 \ub3d9\uc2dc\uc5d0 \uc774\ub8e8\uc5b4\uc9c4) \uc2dc\uac04\uc740 \uc81c\uc678\ud569\ub2c8\ub2e4.
+UpdateWindow.status.restartMaybeNeeded=\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud560 \uc218 \uc788\uc74c
 ConfigView.pluginlist.shared=\uacf5\uc720\ub428
 PeersView.host=\ud638\uc2a4\ud2b8 \uc774\ub984
-PeersView.host.info=\ub3d9\ub8cc\uc758 \uc4f8 \uc218 \uc788\ub294 \ud638\uc2a4\ud2b8 \uc774\ub984 (\uc2e4\ud589\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60\uc9c0\ub3c4 \ubaa8\ub984)
-MainWindow.menu.help.whatsnew=\uc0c8 \uc18c\uc2dd
+PeersView.host.info=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \ud53c\uc5b4\uc758 \ud638\uc2a4\ud2b8 \uc774\ub984 (\uc131\ub2a5\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\uc74c)
+MainWindow.menu.help.whatsnew=\uc0c8\ub85c\uc6cc\uc9c4 \uc810
 ConfigView.label.checkonstart=Vuze\ub97c \uc2dc\uc791\ud560 \ub54c \ucd5c\uc2e0 \ubc84\uc804 \uac80\uc0ac
-ConfigView.label.periodiccheck=\uc815\uae30\uc801\uc73c\ub85c \ucd5c\uc2e0 \ubc84\uc804 \uac80\uc0ac
-ConfigView.label.opendialog=\uc5c5\ub370\uc774\ud2b8\uac00 \uac00\ub2a5\ud560 \ub54c \uc5c5\ub370\uc774\ud2b8 \uc800\uc808\ub85c \uc5f4\ub9ac\uae30
+ConfigView.label.periodiccheck=\uc8fc\uae30\uc801\uc73c\ub85c \ucd5c\uc2e0 \ubc84\uc804 \uac80\uc0ac
+ConfigView.label.opendialog=\uc5c5\ub370\uc774\ud2b8\uac00 \uc0ac\uc6a9 \uac00\ub2a5\ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ub3c4\uc6b0\ubbf8 \uc5f4\uae30
 MainWindow.updateavail=\uc5c5\ub370\uc774\ud2b8\ud558\ub824\uba74 \uc5ec\uae30\ub97c \ud074\ub9ad
 MainWindow.status.unofficialversion=Vuze \ubca0\ud0c0
-MainWindow.status.latestversionunchecked=\ubc84\uc804 \uac80\uc0ac\uac00 \uc791\ub3d9\ud558\uc9c0 \uc54a\uc74c
-GeneralView.label.updatein.stopped=\uba48\ucda4
+MainWindow.status.latestversionunchecked=\ubc84\uc804 \uac80\uc0ac \ube44\ud65c\uc131 \ub428
+GeneralView.label.updatein.stopped=\uc815\uc9c0\ub428
 StartStopRules.menu.viewDebug=\ub514\ubc84\uadf8 \uc815\ubcf4 \ubcf4\uae30
-ConfigView.section.style.doNotUseGB=GB \ub2e8\uc704 \uc4f0\uc9c0 \uc54a\uc74c
-ConfigView.section.style.doNotUseGB.tooltip=\uace0\ub974\uba74 Vuze ub294 1024MB\ubcf4\ub2e4 \ud070 \ud06c\uae30\uc5d0\ub3c4 MB\ub97c \uacc4\uc18d \uc4f8 \uac83\uc785\ub2c8\ub2e4.
-MainWindow.menu.help.plugins=\ucd94\uac00\uae30\ub2a5 \uc5bb\uae30
-ConfigView.section.plugins.TrackerWeb=\ub354\ub4ec\uc774 \uc6f9
-ConfigView.section.tracker.enablecategories=\ubd84\ub958\ub85c \ud1a0\ub7f0\ud2b8 \ub098\ub204\uae30
-health.explain.share=\ud1a0\ub7f0\ud2b8\uac00 \ud638\uc2a4\ud2b8\ub098 \ubc1c\ud589 \uc911 \ud558\ub098\uac00 \ub418\ub294 \uac83\uc744 \ub73b\ud569\ub2c8\ub2e4.
-ConfigView.section.tracker.createcert=\uc2a4\uc2a4\ub85c \uc11c\uba85\ud55c \uc778\uc99d\uc11c \ub9cc\ub4e4\uae30
-ConfigView.section.tracker.createbutton=\ub9cc\ub4e4\uae30
-security.certcreate.title=\uc2a4\uc2a4\ub85c \uc11c\uba85\ud55c \uc778\uc99d\uc11c \ub9cc\ub4e4\uae30
-security.certcreate.intro=\uc774 \uba54\uc138\uc9c0 \uc0c1\uc790\ub294 \uc2a4\uc2a4\ub85c \uc11c\uba85\ud55c \uc778\uc99d\uc11c\ub97c \ub9cc\ub4e4\ub3c4\ub85d \ub3c4\uc640\uc90d\ub2c8\ub2e4.
+ConfigView.section.style.doNotUseGB=GB \ub2e8\uc704 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc74c
+ConfigView.section.style.doNotUseGB.tooltip=\uc120\ud0dd\ud558\uba74, Vuze\ub294 1024MB\ubcf4\ub2e4 \ud070 \ud06c\uae30\uc5d0 \ub300\ud574\uc11c\ub3c4 \uacc4\uc18d MB \ub2e8\uc704\ub97c \uc0ac\uc6a9\ud558\uac8c \ub429\ub2c8\ub2e4.
+MainWindow.menu.help.plugins=\ud50c\ub7ec\uadf8\uc778 \uc5bb\uae30
+ConfigView.section.plugins.TrackerWeb=\ud2b8\ub798\ucee4 \uc6f9
+ConfigView.section.tracker.enablecategories=\ubd84\ub958\ub85c \ud1a0\ub80c\ud2b8 \ubd84\ub9ac
+health.explain.share=\ud638\uc2a4\ud305 \ub418\uac70\ub098 \ub610\ub294 \uac8c\uc2dc\ub41c \ud1a0\ub80c\ud2b8\uc784\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+ConfigView.section.tracker.createcert=\uc790\uac00 \uc11c\uba85 \uc778\uc99d\uc11c \uc0dd\uc131
+ConfigView.section.tracker.createbutton=\uc0dd\uc131\ud558\uae30
+security.certcreate.title=\uc790\uac00 \uc11c\uba85 \uc778\uc99d\uc11c \uc0dd\uc131
+security.certcreate.intro=\uc774 \ub300\ud654\uc0c1\uc790\ub294 \uc790\uac00 \uc11c\uba85 \uc778\uc99d\uc11c\ub97c \uc0dd\uc131\ud558\ub3c4\ub85d \ud569\ub2c8\ub2e4.
 security.certcreate.alias=\ubcc4\uba85
-security.certcreate.strength=\uc778\uc6d0
-security.certcreate.firstlastname=\uc131\uacfc \uc774\ub984
+security.certcreate.strength=\uac15\ub3c4
+security.certcreate.firstlastname=\uc774\ub984\uacfc \uc131
 security.certcreate.orgunit=\uc9c1\ud568
 security.certcreate.org=\uc870\uc9c1
-security.certcreate.city=\uc2dc\uad70\uad6c \ub610\ub294 \uc74d\uba74\ub9ac\ub3d9
-security.certcreate.state=\ub098\ub77c \ub610\ub294 \uc2dc\ub3c4
+security.certcreate.city=\ub3c4\uc2dc \ub610\ub294 \uc18c\uc7ac\uc9c0
+security.certcreate.state=\uc8fc \ub610\ub294 \ub3c4
 security.certcreate.country=\ub450 \uae00\uc790\uc758 \ub098\ub77c \ubd80\ud638
-security.certcreate.ok=\ub9cc\ub4e4\uae30
+security.certcreate.ok=\uc0dd\uc131
 security.certcreate.cancel=\ucde8\uc18c
-security.certcreate.createok=\uc778\uc99d\uc11c\ub97c \uc81c\ub300\ub85c \ub9cc\ub4e6
-security.certcreate.createfail=\uc778\uc99d\uc11c\ub97c \ub9cc\ub4e4\uc9c0 \ubabb\ud568
-ConfigView.section.plugins.webui=\ucca8\ub2e8 \uc6f9 \uc778\ud130\ud398\uc774\uc2a4
+security.certcreate.createok=\uc131\uacf5\uc801\uc73c\ub85c \uc778\uc99d\uc11c\uac00 \uc0dd\uc131\ub428
+security.certcreate.createfail=\uc778\uc99d\uc11c \uc0dd\uc131 \uc2e4\ud328
+ConfigView.section.plugins.webui=Swing \uc6f9 \uc778\ud130\ud398\uc774\uc2a4
 ConfigView.section.plugins.xml_http_if=XML/HTTP \uc778\ud130\ud398\uc774\uc2a4
-webui.passwordenable=\uc554\ud638 \uc791\ub3d9
+webui.passwordenable=\uc554\ud638 \ud65c\uc131\ud654
 webui.user=\uc0ac\uc6a9\uc790 \uc774\ub984
 webui.password=\uc554\ud638
-webui.port=\ud3ec\ud2b8 (*)
-webui.protocol=\ud504\ub85c\ud1a0\ucf5c (*)
-webui.homepage=\ud648\ud398\uc774\uc9c0 (*)
-webui.rootdir=\ub8e8\ud2b8 \ud3f4\ub354 (*)
-webui.rootres=\ub8e8\ud2b8 \uc790\uc6d0 (*)
-webui.mode=\ubc29\uc2dd (*)
-webui.mode.info=\ubc29\uc2dd\uc740\n\t"full"\t= \ubaa8\ub4e0 \uc791\uc5c5\uc744 \uc4f8 \uc218 \uc788\uc74c(\uae30\ubcf8\uac12)\n\t"view"\t= \ubcf4\uae30\ub9cc \ud560 \uc218 \uc788\uc74c(\uadf8\ub7ec\ub098 \uc0c8\ub85c \uace0\uce68 \ube48\ub3c4\ub97c \uc5c5\ub370\uc774\ud2b8\ud560 \uc218 \uc788\uc74c)
-webui.access=\uc811\uadfc (*)
+webui.port=\ud3ec\ud2b8
+webui.protocol=\ud504\ub85c\ud1a0\ucf5c
+webui.homepage=\ud648\ud398\uc774\uc9c0
+webui.rootdir=\ub8e8\ud2b8 \ub514\ub809\ud130\ub9ac
+webui.rootres=\ub8e8\ud2b8 \uc790\uc6d0
+webui.mode=\ubaa8\ub4dc
+webui.mode.info=\ubaa8\ub4dc\ub294\n\t"full"\t= \ubaa8\ub4e0 \uc791\uc5c5 \uac00\ub2a5 (\uae30\ubcf8\uac12)\n\t"view"\t= \ubcf4\uae30 \uc804\uc6a9 (\uadf8\ub7ec\ub098 \uc0c8\ub85c \uace0\uce68 \ube48\ub3c4\ub97c \uc5c5\ub370\uc774\ud2b8\ud560 \uc218 \uc788\uc74c)
+webui.access=\uc811\uadfc
 webui.access.info=\uc811\uadfc\uc740\n\t"local"\t= \ub85c\uceec \ucef4\ud4e8\ud130\ub9cc \uc5f0\uacb0\ud560 \uc218 \uc788\uc74c\n\t"all"\t= \uc790\uc720\ub85c\uc6b4 \uc811\uadfc (\uae30\ubcf8\uac12)\n\tIP\t= \uc608 192.168.0.2\t\t\t\ud55c IP\ub9cc\n\tIP1-IP2\t= \uc608 192.168.0.1-192.168.0.255\tIP\uc758 \ubaa8\ub4e0 \ubc94\uc704
-GeneralView.label.maxdownloadspeed=\ucd5c\uace0 \ub0b4\ub824\ubc1b\uae30
-Security.keystore.corrupt='%1' \uac08\ubb34\ub9ac \uc554\ud638\ub97c \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud568. \uadf8\uac83\uc744 \uc9c0\uc6b0\uace0 \uc778\uc99d\uc11c\ub97c \ub2e4\uc2dc \ub9cc\ub4e4\uac70\ub098 \ub2e4\uc2dc \ub4e4\uc5ec\uc624\uc2ed\uc2dc\uc694.
-Security.keystore.empty=\uac08\ubb34\ub9ac \uc554\ud638\uac00 \ube44\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. \uc2a4\uc2a4\ub85c \uc11c\uba85\ud55c \uc778\uc99d\uc11c\ub97c \ub9cc\ub4e4\uac70\ub098(\ub3c4\uad6c->\uc120\ud0dd\uc0ac\ud56d->\ubcf4\uc548\uc744 \ubcf4\uc2ed\uc2dc\uc694.) '%1'\ub85c \uc774\ubbf8 \uc788\ub358 \uc778\uc99d\uc11c\ub97c \ub4e4\uc5ec \uc624\uc2ed\uc2dc\uc694.
-webui.restart.info=(*)\ub77c\uace0 \ud45c\uc2dc\ub41c \ub9e4\uac1c \ubcc0\uc218\ub97c \ubc14\uafbc \uac83\uc740 \ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud6a8\ub825\uc774 \ub098\ud0c0\ub0a9\ub2c8\ub2e4.
-GeneralView.label.maxdownloadspeed.tooltip=\ucd5c\uace0 \ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
-upnp.enable=UPnP \uc791\ub3d9
-upnp.info=\uc77c\ubc18\uc801\uc778 \ud50c\ub7ec\uadf8 \uc564 \ud50c\ub808\uc774(UPnP)\ub294 UPnP\uc774 \uc791\ub3d9\ud558\ub294 \ub77c\uc6b0\ud130\uc5d0\uc11c \ud3ec\ud2b8\ub97c \uc800\uc808\ub85c \uc0ac\uc0c1(\u5beb\u50cf)\ud558\ub3c4\ub85d \ud569\ub2c8\ub2e4.
-upnp.mapping.dataport=\ub4e4\uc5b4\uc624\ub294 \ub3d9\ub8cc \ub370\uc774\ud130 \ud3ec\ud2b8
-upnp.mapping.tcptrackerport=TCP \ub354\ub4ec\uc774 \ud3ec\ud2b8
-upnp.mapping.udptrackerport=UDP \ub354\ub4ec\uc774 \ud3ec\ud2b8
-upnp.alert.differenthost=UPnP: '%1'\uc758 \uc0ac\uc0c1(\u5beb\u50cf)\uc774 '%2'\uc5d0\uc11c \ubbf8\ub8e8\uc5b4\uc84c\uc2b5\ub2c8\ub2e4. - \ub2e4\ub978 \ud3ec\ud2b8\ub97c \uace0\ub974\uc2ed\uc2dc\uc694.
-upnp.alert.mappingok=UPnP: '%1'\uc758 \uc0ac\uc0c1(\u5beb\u50cf)\uc744 \ub9c8\ub828\ud568
-upnp.alert.mappingfailed=UPnP: '%1'\uc758 \uc0ac\uc0c1(\u5beb\u50cf)\uc744 \ubabb\ud568
-upnp.alertsuccess=\uc798\ub41c \uc0ac\uc0c1(\u5beb\u50cf)\ub4e4\uc744 \uae30\ub85d\ud568
-upnp.alert.lostdevice=UPnP: UPnP '%2' \uc7a5\uce58\uc5d0\uc11c '%1' \uc11c\ube44\uc2a4\uc758 \uc5f0\uacb0\uc744 \uc783\uc74c
-upnp.grabports=\ub2e4\ub978 \ucef4\ud4e8\ud130\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud3ec\ud2b8\ub77c\ub3c4 \uc0ac\uc0c1(\u5beb\u50cf)
-upnp.refresh.label=\uc0ac\uc0c1(\u5beb\u50cf) \uc0c8\ub85c \uace0\uce68
+GeneralView.label.maxdownloadspeed=\ub2e4\uc6b4 \uc81c\ud55c
+Security.keystore.corrupt=\ud0a4\uc800\uc7a5\uc18c '%1' \uc801\uc7ac \uc2e4\ud328. \uc0ad\uc81c \ud6c4 \uc778\uc99d\uc11c\ub97c \ub2e4\uc2dc \uc0dd\uc131\ud558\uac70\ub098/\uac00\uc838\uc624\uae30 \ubc14\ub78d\ub2c8\ub2e4
+Security.keystore.empty=\ud0a4\uc800\uc7a5\uc18c\uac00 \ube44\uc5b4\uc788\uc2b5\ub2c8\ub2e4. \uc790\uac00 \uc11c\uba85 \uc778\uc99d\uc11c\ub97c \uc0dd\uc131 \ud558\uac70\ub098 (\ub3c4\uad6c\u2192\uc635\uc158\u2192\ubcf4\uc548 \ucc38\uace0) \uc874\uc7ac\ud558\ub294 \uc778\uc99d\uc11c\ub97c '%1'\ub85c \uac00\uc838\uc624\uae30 \ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+GeneralView.label.maxdownloadspeed.tooltip=\ucd5c\ub300 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+upnp.enable=UPnP \ud65c\uc131\ud654
+upnp.info=Universal Plug and Play (UPnP)\ub294 UPnP\uac00 \ud65c\uc131\ud654\ub41c \ub77c\uc6b0\ud130\uc5d0\uc11c \uc790\ub3d9 \ud3ec\ud2b8 \ub9f5\ud551\uc744 \ud560 \uc218 \uc788\uac8c\ud569\ub2c8\ub2e4.
+upnp.mapping.dataport=\ub4e4\uc5b4\uc624\ub294 \ud53c\uc5b4 \ub370\uc774\ud130 \ud3ec\ud2b8
+upnp.mapping.tcptrackerport=TCP \ud2b8\ub798\ucee4 \ud3ec\ud2b8
+upnp.mapping.udptrackerport=UDP \ud2b8\ub798\ucee4 \ud3ec\ud2b8
+upnp.alert.differenthost=UPnP: '%1' \ub9f5\ud551\uc774 '%2'\uc5d0 \uc758\ud574 \uc608\uc57d\ub418\uc5c8\uc2b5\ub2c8\ub2e4 - \ub2e4\ub978 \ud3ec\ud2b8\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
+upnp.alert.mappingok=UPnP: '%1' \ub9f5\ud551 \ud655\ub9bd\ub428
+upnp.alert.mappingfailed=UPnP: '%1' \ub9f5\ud551 \uc2e4\ud328
+upnp.alertsuccess=\uc131\uacf5\uc801\uc778 \ub9f5\ud551\uc744 \ubcf4\uace0
+upnp.alert.lostdevice=UPnP: UPnP \uc7a5\uce58 '%2'\uc5d0\uc11c \uc11c\ube44\uc2a4 '%1'\ub85c\uc758 \uc5f0\uacb0\uc744 \uc783\uc5b4\ubc84\ub9bc
+upnp.grabports=\ub2e4\ub978 \ucef4\ud4e8\ud130\uac00 \uc18c\uc720\ud55c \ud3ec\ud2b8\ub77c\ub3c4 \ub9f5\ud551
+upnp.refresh.label=\ub9f5\ud551 \uc0c8\ub85c \uace0\uce68
 upnp.refresh.button=\uc0c8\ub85c \uace0\uce68
-upnp.alert.mappinggrabbed=UPnP: '%1'\uc758 \uc0ac\uc0c1(\u5beb\u50cf)\uc744 '%2'\uc5d0\uc11c \ub9c8\ub828\ud558\uace0 \uac00\ub85c\ucc54
-upnp.mapping.tcpssltrackerport=TCP SSL \ub354\ub4ec\uc774 \ud3ec\ud2b8
-upnp.alertothermappings=\ub2e4\ub978 \ucef4\ud4e8\ud130\uac00 \uac00\uc9c0\uac8c \ub41c \ud3ec\ud2b8\ub97c \uae30\ub85d\ud568
-upnp.alertdeviceproblems=UPnP \uc7a5\uce58\uc758 \ubb38\uc81c\ub4e4\uc744 \uae30\ub85d\ud568
-upnp.trace_to_log=\uc804\uccb4 \uc624\ub958\ubc0f \uc138\ubd80\ub0b4\uc6a9 \uae30\ub85d
-upnp.wiki_link=UPnP\uc5d0\uc11c Vuze \uc704\ud0a4 \ud398\uc774\uc9c0
-ConfigView.pluginlist.coreplugins=\ub2e4\uc74c \ubcf8\ub798 \uac16\ucdb0\uc9c4 \ucd94\uac00\uae30\ub2a5\uc774 \uc2dc\uc791\ub428:
-Peers.column.DLedFromOthers=\ub2e4\ub978 \ub3d9\ub8cc\uc5d0\uac8c\uc11c
-Peers.column.DLedFromOthers.info=\uc5f0\uacb0\ub41c \ub3d9\uc548 \ub2e4\ub978 \ub3d9\ub8cc\ub4e4\uc5d0\uac8c\uc11c \ub0b4\ub824\ubc1b\uc740 \ub370\uc774\ud130 \uc591
-Peers.column.UpDownRatio=\uc62c\ub9ac\uae30:\ub0b4\ub824\ubc1b\uae30
-Peers.column.UpDownRatio.info=\ub3d9\ub8cc\uc758 "\uc62c\ub9ac\uae30 : \ub0b4\ub824\ubc1b\uae30" \ube44
-Peers.column.UpRatio=\uc62c\ub9ac\uae30 \ube44
-Peers.column.UpRatio.info=\ub3d9\ub8cc\uc758 "\ub2f9\uc2e0\uc5d0\uac8c\uc11c \uc62c\ub9ac\uae30 : \ub2e4\ub978 \ub3d9\ub8cc\uc5d0\uac8c\uc11c \uc62c\ub9ac\uae30" \ube44
-upnp.releasemappings=\ub2eb\uae30\uc5d0\uc11c \uc0ac\uc0c1(\u5beb\u50cf) \ud480\uc5b4 \ub193\uc74c
-webui.upnpenable=\uc774 \ud3ec\ud2b8\uc5d0 UPnP \uc791\ub3d9 (*)
-ConfigView.section.file.friendly.hashchecking=\uc4f8\ubaa8 \uc788\ub294 \ud574\uc2dc \uac80\uc0ac
-ConfigView.section.file.friendly.hashchecking.tooltip=CPU/\uc2dc\uc2a4\ud15c\uc5d0\uc11c \uc870\uae08 \ub354 \ub290\ub9ac\ub098 \ud6e8\uc52c \ub354 \uc801\uac8c \uc790\uadf9 \ubc1b\ub294 \uc870\uac01 \ud574\uc2dc \uac80\uc0ac \ubc29\uc2dd
-ConfigView.section.tracker.seedretention=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4 \uc787\ub2ec\uc544 \uac00\uc9c0\uace0 \uc788\ub294 \ucd5c\ub300 \uc528\uc557 \uc218 [0: \ubb34\uc81c\ud55c] 
-ConfigView.section.tracker.seedretention.info=\uadc0\ub754: \uc787\ub2ec\uc544 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\uc740 \uc528\uc557\uc5d0\uc11c\ub294 \uc62c\ub9ac\uae30 \ud1b5\uacc4\ub97c \uc783\uc744 \uac83\uc785\ub2c8\ub2e4.
-ConfigView.section.tracker.port=\ub2e4\uc74c HTTP \ud3ec\ud2b8\uc5d0\uc11c \ub354\ub4ec\uc774 \uc791\ub3d9
-ConfigView.section.tracker.sslport=\ub2e4\uc74c HTTPS \ud3ec\ud2b8\uc5d0\uc11c \ub354\ub4ec\uc774 \uc791\ub3d9
-ConfigView.section.tracker.publicenable.info=\uc774\uac83\uc740 \ub0a8\ub4e4\uc774 \ud638\uc2a4\ud2b8/\ubc1c\ud589 \uc5c6\uc774 \ub2f9\uc2e0\uc758 \ub354\ub4ec\uc774\ub97c \uc4f0\ub294 \ud1a0\ub7f0\ud2b8\ub97c\n\ub9cc\ub4e4\uac8c \ub0b4\ubc84\ub824 \ub461\ub2c8\ub2e4.
+upnp.alert.mappinggrabbed=UPnP: '%1' \ub9f5\ud551 \ud655\ub9bd\ub428 - '%2'\uc5d0\uc11c \uac00\uc838\uc634
+upnp.mapping.tcpssltrackerport=TCP SSL \ud2b8\ub798\ucee4 \ud3ec\ud2b8
+upnp.alertothermappings=\ub2e4\ub978 \ucef4\ud4e8\ud130\uac00 \uc18c\uc720\ud55c \ud3ec\ud2b8\ub97c \ubcf4\uace0
+upnp.alertdeviceproblems=UPnP \uc7a5\uce58\uc758 \ubb38\uc81c\uc5d0 \ub300\ud574 \ubcf4\uace0
+upnp.trace_to_log=\ub85c\uadf8\uc5d0 \uc804\uccb4 \ub514\ubc84\uadf8 \uc815\ubcf4 \ucd9c\ub825
+upnp.wiki_link=UPnP\uc5d0 \ub300\ud55c Vuze Wiki \ud398\uc774\uc9c0
+upnp.refresh_mappings_on_bad_nat=NAT \uc0c1\ud0dc\uac00 "\ubc29\ud654\ubcbd\uc73c\ub85c \ub9c9\ud798"\uc77c \ub54c \uc790\ub3d9\uc73c\ub85c \ub9f5\ud551 \uc0c8\ub85c \uace0\uce68
+ConfigView.pluginlist.coreplugins=\ub2e4\uc74c\uacfc \uac19\uc740 \ub0b4\uc7a5 \ud50c\ub7ec\uadf8\uc778\uc774 \ub85c\ub4dc\ub418\uc5c8\uc2b5\ub2c8\ub2e4:
+Peers.column.DLedFromOthers=\ub2e4\ub978 \uacf3\uc5d0\uc11c
+Peers.column.DLedFromOthers.info=\uc5f0\uacb0\ub418\uc5b4 \uc788\ub294 \ub3d9\uc548 \ub2e4\ub978 \uacf3\uc73c\ub85c\ubd80\ud130 \ub2e4\uc6b4\ub85c\ub4dc \ubc1b\uc740 \uc804\uccb4 \ub370\uc774\ud130 \uc591
+Peers.column.UpDownRatio=\uc5c5:\ub2e4\uc6b4
+Peers.column.UpDownRatio.info=\ud53c\uc5b4\uc758 "\uc5c5 : \ub2e4\uc6b4" \ube44\uc728
+Peers.column.UpRatio=\uc5c5 \ube44\uc728
+Peers.column.UpRatio.info=\ud53c\uc5b4\uc758 "\ub098\uc758 \uc5c5\ub85c\ub4dc : \ub2e4\ub978 \uc5c5\ub85c\ub4dc" \ube44\uc728
+upnp.releasemappings=\ub2eb\uc744 \ub54c \ub9f5\ud551\ub41c \ud3ec\ud2b8\ub97c \ud480\uc5b4\uc8fc\uae30
+webui.upnpenable=\uc774 \ud3ec\ud2b8\uc5d0 UPnP \ud65c\uc131\ud654
+ConfigView.section.file.friendly.hashchecking=\ud638\uc758\uc801\uc778 \ud574\uc26c \uac80\uc0ac
+ConfigView.section.file.friendly.hashchecking.tooltip=\uc77c\ubc18\uc801\uc778 \uc870\uac01 \ud574\uc26c \uac80\uc0ac \ubaa8\ub4dc\ub97c \ub300\uccb4\ud558\ub294 \ubaa8\ub4dc\ub85c\uc11c \uc57d\uac04 \ub290\ub9ac\uc9c0\ub9cc CPU/\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ub2f4\uc744 \ub35c \uc90d\ub2c8\ub2e4.
+ConfigView.section.tracker.seedretention=\ud1a0\ub80c\ud2b8 \ubcc4 \ubcf4\uc720 \uac00\ub2a5 \ucd5c\ub300 \uc2dc\ub4dc [0: \ubb34\uc81c\ud55c]
+ConfigView.section.tracker.seedretention.info=\uc8fc\uc758: \ubcf4\uc720\ud558\uc9c0 \uc54a\uc740 \uc2dc\ub4dc\uc5d0 \ub300\ud55c \uc5c5\ub85c\ub4dc \ud1b5\uacc4\ub294 \uc0ac\ub77c\uc9d1\ub2c8\ub2e4
+ConfigView.section.tracker.port=HTTP \ud3ec\ud2b8\uc5d0\uc11c \ud2b8\ub798\ucee4 \ud65c\uc131\ud654
+ConfigView.section.tracker.sslport=HTTPS \ud3ec\ud2b8\uc5d0\uc11c \ud2b8\ub798\ucee4 \ud65c\uc131\ud654
+ConfigView.section.tracker.publicenable.info=\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc0ac\uc6a9\uc790\uac00 \ud638\uc2a4\ud305/\ubc1c\ud589\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc\n\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ucee4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud1a0\ub80c\ud2b8\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4.
 Button.clear=\uc9c0\uc6b0\uae30
-MainWindow.IPs.tooltip=\uace8\ub77c\ubcf4\uae30 \ubaa9\ub85d \ucd5c\uc2e0 \uc5c5\ub370\uc774\ud2b8: %1\n\ubaa9\ub85d\uc758 \ubaa8\ub4e0 IP \ud544\ud130 - \uc774 \uc138\uc158\uc5d0\uc11c \ucc28\ub2e8/\ucd94\ubc29/\uc545\uc131 IP\uc758 \uc218\n\uc0c1\uc138\ud55c \uc124\uba85\uc744 \ubcf4\ub824\uba74 \ub354\ube14 \ud074\ub9ad
-ConfigView.section.ipfilter.list.banned=\uc545\uc131 \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\uc11c \ubab0\uc544\ub0c4
-ConfigView.section.ipfilter.list.baddata=\uc545\uc131 \ub370\uc774\ud130\ub97c \ubcf4\ub0c4: \uc77c\uc5b4\ub09c \uc77c =
-Button.reset=\ucc98\uc74c \uac12\uc73c\ub85c
-ConfigView.section.ipfilter.bannedinfo=\uc545\uc131 \ub370\uc774\ud130\ub97c \ubcf4\ub0b8 IP\ub4e4 - \ud55c\ub3c4\ub97c \ub118\uc73c\uba74 \ubab0\uc544\ub0c4
-ConfigView.section.ipfilter.blockedinfo=IP \ud544\ud130\ub85c \ubab0\uc544\ub0b8 IP\ub4e4
-download.removerules.name=\uc9c0\uc6b0\uae30 \uaddc\uce59
-download.removerules.unauthorised.info=\uad8c\ud55c\uc774 \uc5c6\ub294 \ud1a0\ub7f0\ud2b8\ub294 "\uc2e4\ud328 \ubc18\uc751"\uc5d0\uc11c" "\uad8c\ud55c\uc744 \ubc1b\uc9c0 \ubabb\ud55c"\uc774\ub098 "\uad8c\ud55c\uc774 \uc5c6\ub294" \uc911 \ud558\ub098\ub97c \ub2f4\uace0 \uc788\ub294 \uc54c\ub9ac\uae30 \ubc18\uc751\uc5d0 \uc788\ub294 \uac83\uc774\ub2e4.
-download.removerules.unauthorised=\uad8c\ud55c\uc774 \uc5c6\ub294 \ud1a0\ub7f0\ud2b8 \uc800\uc808\ub85c \uc9c0\uc6b0\uae30
-download.removerules.unauthorised.seedingonly=\t\ubfcc\ub9ac\uace0 \uc788\uae30\ub9cc \ud558\uba74
-download.removerules.removed.ok=\ud1a0\ub7f0\ud2b8 \uc9c0\uc6b0\uae30 \uaddc\uce59\uc5d0 \ub530\ub77c \ud1a0\ub7f0\ud2b8 '%1'\ub97c \uc800\uc808\ub85c \uc9c0\uc6e0\uc2b5\ub2c8\ub2e4.
-download.removerules.updatetorrents=\ub5bc\uc5d0 \ud544\uc694\ud558\uc5ec\uc11c Vuze \uc5c5\ub370\uc774\ud2b8 \ud1a0\ub7f0\ud2b8 \uc9c0\uc6b0\uae30
-ConfigView.label.defaultstarttorrentsstopped=\uae30\ubcf8\uac12\uc73c\ub85c \uba48\ucd98 \ucc44\ub85c \uc0c8 \ud1a0\ub7f0\ud2b8\ub97c \ub354\ud558\uae30
-ConfigView.section.server.enableudp=UDP \ub354\ub4ec\uc774 \uc811\uc18d \ucef4\ud4e8\ud130 \ud504\ub85c\ud1a0\ucf5c \uc791\ub3d9.
-upnp.mapping.dataportudp=UDP \ub354\ub4ec\uc774 \uc811\uc18d \ucef4\ud4e8\ud130 \ud3ec\ud2b8
-ConfigView.section.file.decoder.showlax=\ubcc4\ub85c \uc54c\ub9de\uc9c0 \uc54a\uc740 \uc778\ucf54\ub529\uae4c\uc9c0 \ubcf4\uc774\uae30
-ConfigView.section.file.decoder.showall=\ubaa8\ub4e0 \uc5b4\uc6b8\ub9ac\ub294 \uc778\ucf54\ub529\uc744 \uc54c\ub9de\uac8c \ud5e4\uc544\ub9bc
-MainWindow.status.updowndetails.tooltip=\uc62c\ub9ac\uae30/\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 \uc0c1\uc138 \uc815\ubcf4 - \ubc14\uafb8\ub824\uba74 \uc624\ub978\ucabd \ub2e8\ucd94\ub97c \ub204\ub974\uc2ed\uc2dc\uc694.
-TrackerClient.announce.warningmessage='%1'\uc758 \ub354\ub4ec\uc774\uc5d0\uc11c '%2'\uc640 \uac19\uc740 \uacbd\uace0\uac00 \ub3cc\uc544\uc634
-ConfigView.section.tracker.natcheckenable='\ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130 \ud3ec\ud2b8'\ub97c \uc5f0\uacb0\ud560 \uc218 \uc788\ub294\uc9c0 \uac80\uc0ac\ud558\uace0 \ub3d9\ub8cc\uc5d0\uac8c \uc2e4\ud328\ub97c \uc804\ud568
-ConfigView.section.tracker.publishenabledetails=\ubaa8\ub4e0 \ud1a0\ub7f0\ud2b8 \uc0c1\uc138 \uc815\ubcf4 \uc54c\ub9bc
-ConfigView.section.tracker.publishenablepeerdetails=\ub3d9\ub8cc \uc0c1\uc138 \uc815\ubcf4 \uc54c\ub9bc
-MyTrackerView.badnat=\uc545\uc131 NAT
-MyTrackerView.badnat.info=\uc791\ub3d9\ud558\uc5ec\uc11c \uc528\uc557/NAT \uac80\uc0ac\uc5d0\uc11c \ub5a8\uc5b4\uc9c4 \ub3d9\ub8cc
+MainWindow.IPs.tooltip=\ud544\ud130 \ubaa9\ub85d \ub9c8\uc9c0\ub9c9 \uc5c5\ub370\uc774\ud2b8: %1\n\ubaa9\ub85d\uc0c1 \uc804\uccb4 IP\ud544\ud130 - \uc774 \uc138\uc158\uc5d0\uc11c \ucc28\ub2e8\ud55c/\uae08\uc9c0\ub41c/\uc190\uc0c1\ub41c IP\uc758 \uac2f\uc218 \uc785\ub2c8\ub2e4.\n\uc138\ubd80\uc0ac\ud56d\uc744 \ubcf4\ub824\uba74 \ub354\ube14\ud074\ub9ad \ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.ipfilter.list.banned=\uae08\uc9c0 \ub418\uc5c8\uc74c
+ConfigView.section.ipfilter.list.baddata=\ubcf4\ub0b4\uc9c4 \uc190\uc0c1\ub41c \ub370\uc774\ud130: \ubc1c\uc0dd\uc218
+Button.reset=\ucd08\uae30\ud654
+ConfigView.section.ipfilter.bannedinfo=\uc190\uc0c1\ub41c \ub370\uc774\ud130\ub97c \ubcf4\ub0b8 IP - \ud55c\uacc4\ub97c \ucd08\uacfc\ud55c \uacbd\uc6b0 \uae08\uc9c0\ub428
+ConfigView.section.ipfilter.blockedinfo=IP \ud544\ud130\ub85c \ucc28\ub2e8\ub41c IP
+download.removerules.name=\uc81c\uac70 \uaddc\uce59
+download.removerules.unauthorised.info=\uc778\uc99d\ub418\uc9c0 \uc54a\uc740 \ud1a0\ub80c\ud2b8\ub294 "\uc2e4\ud328 \uc751\ub2f5"\uc5d0 "\uc778\uc99d\ub418\uc9c0 \uc54a\uc74c" \uc54c\ub9bc \uc751\ub2f5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4:
+download.removerules.unauthorised=\uc790\ub3d9\uc73c\ub85c \uc778\uc99d\ub418\uc9c0 \uc54a\uc740 \ud1a0\ub80c\ud2b8 \uc81c\uac70
+download.removerules.unauthorised.seedingonly=\t\ubc30\ud3ec \uc911\uc778 \uacbd\uc6b0\uc5d0\ub9cc
+download.removerules.removed.ok=\uc790\ub3d9 \ud1a0\ub80c\ud2b8 \uc81c\uac70 '%1' \uc131\uacf5\ud588\uc2b5\ub2c8\ub2e4. \uc774 \uc791\uc5c5\uc740 \ud1a0\ub80c\ud2b8 \uc81c\uac70 \uaddc\uce59\uc5d0 \uc758\uac70\ud55c \uac83\uc785\ub2c8\ub2e4.
+download.removerules.updatetorrents=\uc2a4\uc6dc \uc694\uad6c\uc5d0\ub530\ub77c Vuze \uc5c5\ub370\uc774\ud2b8 \ud1a0\ub80c\ud2b8 \uc81c\uac70
+ConfigView.label.defaultstarttorrentsstopped=\uae30\ubcf8\uc73c\ub85c \uc0c8 \ud1a0\ub80c\ud2b8\ub294 \uc911\uc9c0\ub41c \uc0c1\ud0dc\ub85c \ucd94\uac00
+ConfigView.section.server.enableudp=UDP \ud2b8\ub798\ucee4 \ud074\ub77c\uc774\uc5b8\ud2b8 \ud504\ub85c\ud1a0\ucf5c \ud65c\uc131\ud654
+upnp.mapping.dataportudp=UDP \ud2b8\ub798\ucee4 \ud074\ub77c\uc774\uc5b8\ud2b8 \ud3ec\ud2b8
+ConfigView.section.file.decoder.showlax=\uc57d\uac04 \ubd80\uc801\uc808\ud55c \uc778\ucf54\ub529\ub3c4 \ubcf4\uc5ec\uc8fc\uae30
+ConfigView.section.file.decoder.showall=\uac00\ub2a5\ud55c \uc778\ucf54\ub529\uc744 \ubaa8\ub450 \uace0\ub824
+MainWindow.status.updowndetails.tooltip=\ub2e4\uc6b4\ub85c\ub4dc/\uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc138\ubd80\uc0ac\ud56d\n\ubcc0\uacbd\ud558\ub824\uba74 \uc624\ub978\ucabd \ud074\ub9ad, \ud1b5\uacc4\ub97c \uc5f4\ub824\uba74 \ub354\ube14\ud074\ub9ad
+TrackerClient.announce.warningmessage='%2' \uacbd\uace0\uac00 \ubc18\ud658\ub41c '%1'\uc5d0 \ub300\ud55c \ud2b8\ub798\ucee4
+ConfigView.section.tracker.natcheckenable='\ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130 \ud3ec\ud2b8' \uc5f0\uacb0 \uac00\ub2a5\uc131\uc744 \uac80\uc0ac\ud558\uace0 \ud53c\uc5b4\uc5d0\uac8c \uc2e4\ud328\ub97c \ubcf4\uace0
+ConfigView.section.tracker.publishenabledetails=\ubaa8\ub4e0 \ud1a0\ub80c\ud2b8 \uc138\ubd80\uc0ac\ud56d \uac8c\uc2dc
+ConfigView.section.tracker.publishenablepeerdetails=\ud53c\uc5b4 \uc138\ubd80\uc0ac\ud56d \uac8c\uc2dc
+MyTrackerView.badnat=\uc190\uc0c1\ub41c NAT
+MyTrackerView.badnat.info=\ud65c\uc131\ud654\ud55c \uacbd\uc6b0, NAT \uac80\uc0ac \uc2e4\ud328\ud55c \uc2dc\ub4dc/\ud53c\uc5b4
 ConfigView.section.tracker.natchecktimeout=\uac80\uc0ac \uc2dc\uac04 \uc81c\ud55c (\ucd08)
-ConfigView.section.file.perf.cache.enable=\ub514\uc2a4\ud06c \uce90\uc2dc \uc791\ub3d9
-ConfigView.section.file.perf.cache.size=%1\ub85c \uce90\uc2dc \ud06c\uae30
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
+ConfigView.section.file.perf.cache.enable=\ub514\uc2a4\ud06c \uce90\uc2dc \ud65c\uc131\ud654
+ConfigView.section.file.perf.cache.size=\uce90\uc2dc \ud06c\uae30 (%1)
 MainWindow.menu.transfers=\uc804\uc1a1(&R)
 MainWindow.menu.transfers.startalltransfers=\ubaa8\ub450 \uc2dc\uc791(&A)
-MainWindow.menu.transfers.stopalltransfers=\ubaa8\ub450 \uba48\ucda4(&O)
-MainWindow.menu.transfers.pausetransfers=\uc7a0\uc2dc \uba48\ucda4(&P)
-MainWindow.menu.transfers.pausetransfers.keybinding.mac=\uba54\ud0c0+.
+MainWindow.menu.transfers.stopalltransfers=\ubaa8\ub450 \uc815\uc9c0(&O)
+MainWindow.menu.transfers.pausetransfers=\uc77c\uc2dc\uc815\uc9c0(&P)
 MainWindow.menu.transfers.resumetransfers=\ub2e4\uc2dc \uc2dc\uc791(&R)
 ConfigView.label.experimental.osx.kernel.panic.fix=\ub4c0\uc5bc CPU OSX \uc2dc\uc2a4\ud15c\uc5d0\uc11c \ucee4\ub110 \ud328\ub2c9\uc758 \uc2dc\ud5d8\uc801\uc778 \ud574\uacb0 [\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568]
 SystemTray.menu.pausetransfers=\uc804\uc1a1 \uc7a0\uc2dc \uba48\ucda4
 SystemTray.menu.resumetransfers=\uc804\uc1a1 \ub2e4\uc2dc \uc2dc\uc791
-ConfigView.section.file.truncate.too.large=\uc9c0\uae08 \uc788\ub294 \ub108\ubb34 \ud070 \ud30c\uc77c\uc744 \uc790\ub984
-ConfigView.section.file.perf.cache.trace=\uc9c4\ub2e8\uc5d0 \ub3c4\uc6c0\uc774 \ub418\ub294 \ubaa9\uc801\uc73c\ub85c \uce90\uc2dc \uc791\uc5c5\uc744 \uae30\ub85d
-ConfigView.section.interface.enabletray=\uc54c\ub9bc \uc601\uc5ed \uc791\ub3d9 [\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568]
+ConfigView.section.file.truncate.too.large=\ub108\ubb34 \ud070 \ud30c\uc77c\uc740 \ud544\uc694\uc5c6\ub294 \ubd80\ubd84\uc744 \uc904\uc774\uae30
+ConfigView.section.file.perf.cache.trace=\uc9c4\ub2e8 \ubaa9\uc801\uc73c\ub85c \uce90\uc2dc \uc791\uc5c5 \ucd94\uc801
+ConfigView.section.interface.enabletray=\uc2dc\uc2a4\ud15c \ud2b8\ub798\uc774 \ud65c\uc131\ud654 [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
 PeerManager.status.error=\uc624\ub958
 Stats.title.full=\ud1b5\uacc4
 TransferStatsView.title.full=\uc804\uc1a1
 CacheView.title.full=\uce90\uc2dc
-CacheView.general.size=\ucd1d \ud06c\uae30
-CacheView.general.inUse=\uc4f0\uace0 \uc788\uc74c
+CacheView.general.size=\uc804\uccb4 \ud06c\uae30
+CacheView.general.inUse=\uc0ac\uc6a9 \uc911
 CacheView.general.title=\uce90\uc2dc \uc815\ubcf4
 CacheView.reads.title=\uc785\ucd9c\ub825 \uc77d\uae30
 CacheView.reads.fromFile=\ud30c\uc77c\ub85c\ubd80\ud130
 CacheView.reads.fromCache=\uce90\uc2dc\ub85c\ubd80\ud130
-CacheView.reads.hits=\ub9de\ud798
+CacheView.reads.hits=\uc801\uc911
 CacheView.writes.title=\uc785\ucd9c\ub825 \uc4f0\uae30
 CacheView.writes.toCache=\uce90\uc2dc\ub85c
 CacheView.writes.toFile=\ud30c\uc77c\ub85c
@@ -1213,134 +1210,131 @@ CacheView.speeds.reads=\uc77d\uae30
 CacheView.speeds.writes=\uc4f0\uae30
 CacheView.speeds.fromCache=\uce90\uc2dc\ub85c\ubd80\ud130/\uce90\uc2dc\ub85c
 CacheView.speeds.fromFile=\ud30c\uc77c\ub85c\ubd80\ud130/\ud30c\uc77c\ub85c
-CacheView.reads.#=\ubc88\ud638
-CacheView.reads.amount=\uc591
+CacheView.reads.amount=\ucd1d\uacc4
 CacheView.reads.avgsize=\ud3c9\uade0 \ud06c\uae30
-openUrl.referrer=\ub9e1\uae38 \ud398\uc774\uc9c0 \uc8fc\uc18c:
-openUrl.referrer.info=\ub9e1\uae38 \uc6f9 \uc0ac\uc774\ud2b8\uac00 \ud544\uc694\ud560 \ub54c\ub9cc
-ConfigView.label.maxuploadspeedseeding=KB/s \ubfcc\ub9ac\uae30\ub9cc \ud560 \ub54c\uc758 \ucd5c\uace0 \ucd1d \uc62c\ub9ac\uae30 \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
-ConfigView.label.transfer.ignorepeerports=\uc774 \ub370\uc774\ud130 \ud3ec\ud2b8\uc744 \uc4f4 \ub3d9\ub8cc \ubb34\uc2dc (';'\uc73c\ub85c \ub098\ub214, \uc608 0;25)
-ConfigView.section.proxy.enable_socks.peer=\ub3d9\ub8cc \ud1b5\uc2e0 \ud504\ub85d\uc2dc \uc791\ub3d9 (\ub098\uac00\ub294 \uc5f0\uacb0\ub9cc) [\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568]
-ConfigView.section.proxy.peer.informtracker=\uc81c\ud55c\uc774 \uc788\ub294 \ub354\ub4ec\uc774\ub97c \uc54c\ub9bc
+openUrl.referrer=\ucc38\uc870\ud560 \ud398\uc774\uc9c0 URL :
+openUrl.referrer.info=\ud574\ub2f9 URL\uc5d0 \uad8c\ud55c\uc774 \uc788\ub294 \uc6f9\uc0ac\uc774\ud2b8\uc5d0\ub9cc \ud544\uc694
+ConfigView.label.maxuploadspeedseeding=\ubc30\ud3ec\ub9cc \ud560 \ub54c \ub300\uccb4 \uc18d\ub3c4
+ConfigView.label.transfer.ignorepeerports=\uc774 \ub370\uc774\ud130 \ud3ec\ud2b8\uc744 \uc4f4 \ud53c\uc5b4 \ubb34\uc2dc (';'\uc73c\ub85c \ubd84\ub9ac, \uc608: 0;25)
+ConfigView.section.proxy.enable_socks.peer=\ud53c\uc5b4 \ud1b5\uc2e0\uc5d0 \ud504\ub85d\uc2dc \ud65c\uc131\ud654 (\ub098\uac00\ub294 \uc5f0\uacb0 \uc804\uc6a9) [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
+ConfigView.section.proxy.peer.informtracker=\uc81c\ud55c\uc774 \uc788\ub294 \ud2b8\ub798\ucee4 \uc54c\ub824\uc8fc\uae30
 ConfigView.section.proxy.socks.version=SOCKS \ubc84\uc804
-PiecesView.legend.written=\uc4f0\uc784
-PiecesView.legend.requested=\uc694\uad6c\ub428
-PiecesView.legend.downloaded=\ub0b4\ub824\ubc1b\uae30\ub418\uace0 \uace7 \uc500
+PiecesView.legend.written=\uae30\ub85d\ub428
+PiecesView.legend.requested=\uc694\uccad\ub428
+PiecesView.legend.downloaded=\ub2e4\uc6b4\ub85c\ub4dc\ub428, \uc4f0\uae30 \ubcf4\ub958
 PiecesView.legend.incache=\ub370\uc774\ud130\uac00 \uce90\uc2dc\uc5d0 \uc788\uc74c
 PiecesView.typeItem.0=\ub290\ub9bc
 PiecesView.typeItem.1=\ube60\ub984
-PiecesView.type=\uc885\ub958
-Security.jar.tools_not_found=JAR \ud30c\uc77c\uc5d0 \uc11c\uba85\ud558\uc9c0 \ubabb\ud568 - %1\uc5d0\uc11c 'tools.jar'\ub97c \ucc3e\uc9c0 \ubabb\ud568. \uc0c1\uc138\ud55c \uc124\uba85\uc740 \ub3c4\uad6c->\uc120\ud0dd\uc0ac\ud56d->\ubcf4\uc548\uc744 \ubcf4\uc2ed\uc2dc\uc694.
-Security.jar.signfail=JAR \ud30c\uc77c\uc5d0 \uc11c\uba85\ud558\uc9c0 \ubabb\ud568 - %1
-ConfigView.section.security.toolsinfo=\uc11c\uba85\ub41c JAR \ud30c\uc77c\ub4e4\uc740, \uc608\ub97c \ub4e4\uc5b4 (\uadf8\ub807\uac8c \ud558\ub3c4\ub85d \uad6c\uc131\ud588\uc744 \ub54c) Swing Web Interface\uc640 \uac19\uc740 \ucd94\uac00\uae30\ub2a5\ub4e4\uc744 \ub4b7\ubc1b\uce68\ud558\ub294\ub370 \uc4f0\uc785\ub2c8\ub2e4.\nJAR \ud30c\uc77c\ub4e4\uc5d0 \uc11c\uba85\ud558\ub824\uba74 Sun JDK(JRE \uc544\ub2d8)\ub97c \uc124\uce58\ud558\uc5ec\uc11c \uc788\ub294 'tools.jar' \ud30c\uc77c\uc5d0  [...]
-ConfigView.section.security.toolsdir='tools.jar'\uac00 \uc788\ub294 \ud3f4\ub354
-ConfigView.section.security.choosetoolssavedir='tools.jar'\uac00 \uc788\ub294 \ud3f4\ub354\ub97c \uace0\ub974\uae30
-authenticator.torrent=\ud1a0\ub7f0\ud2b8
-ConfigView.section.proxy.peer.same=\ub354\ub4ec\uc774\uc640 \ub3d9\ub8cc \ud1b5\uc2e0 \ud504\ub85d\uc2dc\uc5d0 \uac19\uc740 \ud504\ub85d\uc2dc \uc124\uc815\uc744 \uc500
-ConfigView.section.connection.network.max.simultaneous.connect.attempts=\ucd5c\ub300 \ub3d9\uc2dc \ub098\uac00\ub294 \uc5f0\uacb0 \uc2dc\ub3c4 [0: \ub098\uac00\ub294 \uc5f0\uacb0\uc774 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc74c]
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Vuze uac00 \uc8fc\uc5b4\uc9c4 \uc2dc\uac04\uc5d0 \uc2dc\ub3c4\ud574\uc57c \ud558\ub294 \uc0c8 \ub098\uac00\ub294 \uc5f0\uacb0 \uc124\uc815\uc758 \ucd5c\ub300 \uc218.\n\uc8fc\uc758: Windows XP Service Pack 2 (SP2)\ub294 \uc2dc\uc2a4\ud15c \uc804\uccb4\uc5d0 \uac78\uccd0 10 \uac1c\uc758 \ub3d9\uc2dc \uc5f0\uacb0 \uc2dc\ub3c4\ub85c \uc81c\ud55c\ud569\ub2c8\ub2e4.\n\uae30\ubcf8\uac12\uc740 8\uc785\ub2c8\ub2e4. \u [...]
-ConfigView.section.file.perf.cache.size.explain=\uce90\uc2dc\ub294 \ub514\uc2a4\ud06c\uc5d0\uc11c \uc77d\uace0 \uc4f0\uae30\ub97c \uc904\uc774\ub824\uace0 \uc4f0\uc785\ub2c8\ub2e4. \ub2f9\uc2e0\uc774 \uc790\ubc14 \uc635\uc158 '-XX:MaxDirectMemorySize'\ub97c \uc368\uc11c \uce90\uc2dc\uc640 \ub124\ud2b8\uc6cc\ud06c \uc785\ucd9c\ub825\uc5d0 \uc4f8 \uba54\ubaa8\ub9ac\ub97c \ub69c\ub837\ud558\uac8c \uad6c\uc131\ud558\uace0 \uc788\uc9c0 \uc54a\ub2e4\uba74, \uc774 \uac12\uc744 \uc801\uc5b4\ub3c [...]
-MyTorrentsView.menu.setSpeed.unlimit=\ubb34\uc81c\ud55c
+PiecesView.type=\uc720\ud615
+Security.jar.tools_not_found=JAR \uc11c\uba85 \uc2e4\ud328 - %1\uc5d0\uc11c 'tools.jar'\ub97c \ucc3e\uc9c0 \ubabb\ud568. \uc138\ubd80\uc0ac\ud56d\uc740 \ub3c4\uad6c\u2192\uc635\uc158\u2192\ubcf4\uc548\uc744 \ucc38\uace0\ud558\uc2ed\uc2dc\uc624.
+Security.jar.signfail=JAR \uc11c\uba85 \uc2e4\ud328 - %1
+ConfigView.section.security.toolsinfo=\uc11c\uba85\ub41c JAR \ud30c\uc77c\uc740 (\uc124\uc815\uc744 \uadf8\ub807\uac8c \ud558\ub294 \uacbd\uc6b0) \uba87\uba87 \ud50c\ub7ec\uadf8\uc778(\uc608\ub97c \ub4e4\uc5b4, Swing \uc6f9 \uc778\ud130\ud398\uc774\uc2a4)\uc744 \uc9c0\uc6d0\ud558\uae30 \uc704\ud574 \uc0ac\uc6a9\ub429\ub2c8\ub2e4.\nJAR \ud30c\uc77c\uc5d0 \uc11c\uba85\ud558\uae30 \uc704\ud574\uc11c\ub294 Sun JDK (JRE\uac00 \uc544\ub2d8)\uc5d0 \ub4e4\uc5b4\uc788\ub294 'tools.jar' \ud30c\uc7 [...]
+ConfigView.section.security.toolsdir='tools.jar'\uac00 \uc788\ub294 \ub514\ub809\ud130\ub9ac
+ConfigView.section.security.choosetoolssavedir='tools.jar'\uac00 \uc788\ub294 \ud3f4\ub354\ub97c \uc120\ud0dd
+authenticator.torrent=\ud1a0\ub80c\ud2b8
+ConfigView.section.proxy.peer.same=\ud2b8\ub798\ucee4\uc640 \ud53c\uc5b4 \ud1b5\uc2e0 \ud504\ub85d\uc2dc\ub97c \uc704\ud574 \uac19\uc740 \ud504\ub85d\uc2dc \uc124\uc815 \uc0ac\uc6a9
+ConfigView.section.connection.network.max.simultaneous.connect.attempts=\ucd5c\ub300 \ub3d9\uc2dc \ub098\uac00\ub294 \uc5f0\uacb0 \uc2dc\ub3c4
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Vuze\uac00 \uc8fc\uc5b4\uc9c4 \uc2dc\uac04 \ub3d9\uc548 \uacc4\uc18d \uc0c8\ub85c \ub098\uac00\ub294 \uc5f0\uacb0 \ud655\ub9bd\uc744 \uc2dc\ub3c4\ud558\ub294 \ucd5c\ub300 \uc218\uc785\ub2c8\ub2e4.\n*\uc8fc\uc758*: Windows XP \uc11c\ube44\uc2a4 \ud329 2 (SP2)\ub294 \uc2dc\uc2a4\ud15c \uc804\ubc18\uc5d0 \uac78\uccd0 10\uac1c\uc758 \ub3d9\uc2dc \uc5f0\uacb0 \uc2dc\ub3c4\ub97c \uac15\uc81c\ud569\ub2c8\ub2e4.\n\ua [...]
+ConfigView.section.file.perf.cache.size.explain=\uce90\uc2dc\ub294 \ub514\uc2a4\ud06c\uc5d0\uc11c \uc77d\uac70\ub098 \ub514\uc2a4\ud06c\uc5d0 \uc4f0\ub294 \ud69f\uc218\ub97c \uac10\uc18c\uc2dc\ud0b5\ub2c8\ub2e4. \uce90\uc26c\uc640 \ub124\ud2b8\uc6cc\ud06c IO\uac00 \uc0ac\uc6a9\ud560 \uba54\ubaa8\ub9ac \ud06c\uae30\ub97c '-XX:MaxDirectMemorySize' Java \uc635\uc158\uc744 \ud1b5\ud574 \uba85\uc2dc\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc740 \uc774\uc0c1, \uc774 \uac12\uc744 \uc8 [...]
+MyTorrentsView.menu.setSpeed.unlimit=\uc81c\ud55c \uc5c6\uc74c
 MyTorrentsView.menu.setSpeed.unlimited=\ubb34\uc81c\ud55c
-MyTorrentsView.menu.setSpeed.disable=\uc62c\ub9ac\uae30\ub97c \ud560 \uc218 \uc5c6\uc74c
-MyTorrentsView.menu.setSpeed.disabled=\uac00\ub2a5\ud558\uc9c0 \uc54a\uc74c
-MyTorrentsView.menu.setSpeed.in=\ucd1d \uc18d\ub3c4\uc774\uace0
-MyTorrentsView.menu.setSpeed.slots=\uc790\ub9ac\ub85c \ud558\ub098\ub9c8\ub2e4
-GeneralView.label.maxuploadspeed=\ucd5c\uace0 \uc62c\ub9ac\uae30
-GeneralView.label.maxuploadspeed.tooltip=\ucd5c\uace0 \uc62c\ub9ac\uae30 \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
-MyTorrents.items.UpSpeedLimit.disabled=\uc62c\ub9ac\uae30\ud560 \uc218 \uc5c6\uc74c
+MyTorrentsView.menu.setSpeed.disable=\uc5c5\ub85c\ub4dc \ube44\ud65c\uc131
+MyTorrentsView.menu.setSpeed.disabled=\ube44\ud65c\uc131\ub428
+MyTorrentsView.menu.setSpeed.in=\ub2e4\uc74c\uc5d0\uc11c
+MyTorrentsView.menu.setSpeed.slots=\uc2ac\ub86f, \ub2e4\uc74c\ub9c8\ub2e4
+GeneralView.label.maxuploadspeed=\uc5c5 \uc81c\ud55c
+GeneralView.label.maxuploadspeed.tooltip=\ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+MyTorrents.items.UpSpeedLimit.disabled=\uc5c5\ub85c\ub4dc \uc5c6\uc74c
 MyTorrents.items.UpSpeedLimit.unlimited=\ubb34\uc81c\ud55c
-TableColumn.header.maxupspeed=\uc62c\ub9ac\uae30 \ucd5c\uace0 \uc18d\ub3c4
-TableColumn.header.maxupspeed.info=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \uc62c\ub9ac\uae30 \ucd5c\uace0 \uc18d\ub3c4
-ConfigView.section.file.perf.cache.enable.write=\ub514\uc2a4\ud06c \uc4f0\uae30\ub97c \uc904\uc774\uace0 \uc870\uac01 \uac80\uc0ac\uc5d0 \ud544\uc694\ud55c \ub514\uc2a4\ud06c \uc77d\uae30\ub3c4 \uc904\uc774\ub824\uace0 \ub0b4\ub824\ubc1b\uae30 \ub370\uc774\ud130\ub97c \uce90\uc2dc
-ConfigView.section.file.perf.cache.enable.read=\uc62c\ub9ac\uae30\ud560 \ub54c \ub514\uc2a4\ud06c \uc77d\uae30\ub97c \uc904\uc774\ub824\uace0 \uc55e\ubd80\ud130 \uc77d\uae30\ub97c \uc2e4\ud589
-ConfigView.section.tracker.separatepeerids=\ub354\ub4ec\uc774\uc640 \ub370\uc774\ud130 \ud1b5\uc2e0\uc5d0\uc11c \ub2e4\ub978 \ub3d9\ub8cc \uc2e0\uc6d0\uc744 \uc4f0\uae30 
-ConfigView.section.tracker.separatepeerids.info=\uc775\uba85\uc774 \uc544\ub2cc \ub354\ub4ec\uc774 \uc5f0\uacb0\uc744 \uc4f0\uba74\uc11c \uc775\uba85\uc73c\ub85c \ub0b4\ub824\ubc1b\uae30/\ubfcc\ub9ac\uae30\ub97c \ud558\uba74\n\uc815\uccb4 \ubd88\uba85\uc758 \uc0ac\uc6a9\uc790\ub97c \ub298\ub9bd\ub2c8\ub2e4.
-ConfigView.section.interface.wavlocation=\uc18c\ub9ac \ucc3e\uc544\ubcf4\uae30
-ConfigView.section.interface.wavlocation.info=\uc18c\ub9ac \ud30c\uc77c\uc744 \uace0\ub974\uac70\ub098 \uae30\ubcf8 \uc18c\ub9ac\ub85c \ube44\uc6cc \ub460
+TableColumn.header.maxupspeed=\ucd5c\ub300 \uc5c5 \uc18d\ub3c4
+TableColumn.header.maxupspeed.info=\ud53c\uc5b4\uc5d0 \uc124\uc815\ub41c \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc785\ub2c8\ub2e4.
+ConfigView.section.file.perf.cache.enable.write=\ub514\uc2a4\ud06c \uc4f0\uae30 \uc791\uc5c5\uc744 \uac10\uc18c\uc2dc\ud0a4\uace0 \uc870\uac01 \uac80\uc0ac\ub97c \uc704\ud55c \ub514\uc2a4\ud06c \uc77d\uae30\ub3c4 \uac10\uc18c \uc2dc\ud0a4\uae30 \uc704\ud574 \ub2e4\uc6b4\ub85c\ub4dc \ub370\uc774\ud130\ub97c \uce90\uc2dc
+ConfigView.section.file.perf.cache.enable.read=\uc5c5\ub85c\ub4dc \uc2dc \ub514\uc2a4\ud06c \uc77d\uae30\ub97c \uac10\uc18c\uc2dc\ud0a4\uae30 \uc704\ud574 \ubbf8\ub9ac \uc77d\uae30 \uc218\ud589
+ConfigView.section.tracker.separatepeerids=\ud2b8\ub798\ucee4\uc640 \ub370\uc774\ud130 \ud1b5\uc2e0 \ubcc4\ub85c \ub2e4\ub978 \ud53c\uc5b4 \uc2e0\uc6d0 \uc0ac\uc6a9
+ConfigView.section.tracker.separatepeerids.info=\uc775\uba85\uc774 \uc544\ub2cc \ud2b8\ub798\ucee4 \uc5f0\uacb0\uc744 \uc0ac\uc6a9\ud558\ub294 \ub3d9\uc548 \uc775\uba85\uc73c\ub85c\n\ub2e4\uc6b4\ub85c\ub4dc/\ubc30\ud3ec\ub97c \ud558\uba74 \uc775\uba85\uc131\uc774 \uac15\ud654\ub429\ub2c8\ub2e4.
+ConfigView.section.interface.wavlocation=.wav \ud30c\uc77c \uc704\uce58
+ConfigView.section.interface.wavlocation.info=\ube48\uce78\uc73c\ub85c \uae30\ubcf8 \uc0ac\uc6b4\ub4dc \ub610\ub294 .wav \ud30c\uc77c\uc744 \uc120\ud0dd
 ConfigView.section.tracker.server=\uc11c\ubc84
-ConfigView.section.tracker.client=\uc811\uc18d \ucef4\ud4e8\ud130
+ConfigView.section.tracker.client=\ud074\ub77c\uc774\uc5b8\ud2b8
 ConfigView.section.tracker.client.connecttimeout=\uc5f0\uacb0 \uc2dc\uac04 \uc81c\ud55c (\ucd08)
 ConfigView.section.tracker.client.readtimeout=\uc77d\uae30 \uc2dc\uac04 \uc81c\ud55c (\ucd08)
 MainWindow.menu.tools=\ub3c4\uad6c(&T)
-FilesView.path=\uc704\uce58
-FilesView.fullpath=\uc804\uccb4 \uc704\uce58 \ubcf4\uae30
+FilesView.path=\uacbd\ub85c
+FilesView.fullpath=\uc804\uccb4 \uacbd\ub85c \ubcf4\uc5ec\uc8fc\uae30
 FilesView.remaining=\ub0a8\uc740 \uc870\uac01
-TableColumn.header.trackername=\ub354\ub4ec\uc774 \uc774\ub984
-TableColumn.header.trackername.info=\ub354\ub4ec\uc774 \uc54c\ub9bc \uc8fc\uc18c(Announce URL)\uc5d0 \ub530\ub978 \ub354\ub4ec\uc774\uc758 \uc774\ub984
-ConfigView.group.override=\ubb34\uc2dc \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.file.perf.cache.notsmallerthan=(%1\ub85c \ubcf4\uc774\ub294) \uc774\ubcf4\ub2e4 \ub354 \uc791\uc740 \ud30c\uc77c\ub4e4\uc744 \uce90\uc2dc\ud558\uc9c0 \uc54a\uc74c
-PeersView.menu.blockupload=\uc62c\ub9ac\uae30 \ub9c9\uc74c
-PeersView.menu.kickandban=\ubab0\uc544\ub0c4
-PeersView.menu.kickandban.reason=\uc190\uc218 \ubab0\uc544\ub0b8 \ub3d9\ub8cc
+TableColumn.header.trackername=\ud2b8\ub798\ucee4 \uc774\ub984
+TableColumn.header.trackername.info=\uc54c\ub9bc URL\uc5d0 \uae30\ubc18\ud55c \ud2b8\ub798\ucee4\uc758 \uc774\ub984\uc785\ub2c8\ub2e4.
+ConfigView.group.override=\uc6b0\uc120\uc801\uc6a9 \uc635\uc158
+ConfigView.section.file.perf.cache.notsmallerthan=\ub2e4\uc74c\ubcf4\ub2e4 \uc791\uc740 \ud30c\uc77c\uc740 \uce90\uc2dc\ud558\uc9c0 \uc54a\uc74c (%1)
+PeersView.menu.blockupload=\uc5c5\ub85c\ub4dc \ucc28\ub2e8
+PeersView.menu.kickandban=\ucad3\uc544\ub0b4\uace0 \uae08\uc9c0
+PeersView.menu.kickandban.reason=\uc218\ub3d9\uc73c\ub85c \uae08\uc9c0\ub41c \ud53c\uc5b4
 PeersView.state=\uc0c1\ud0dc
-PeersView.state.info=\ub3d9\ub8cc \uc5f0\uacb0\uc758 \uc0c1\ud0dc
-PeersView.state.pending=\uac78\ub824 \uc788\uc74c
-PeersView.state.connecting=\uc5f0\uacb0\ud558\uace0 \uc788\uc74c
-PeersView.state.handshake=\uc5f0\uacb0 \uc815\ubcf4 \uc804\uc1a1\uc744 \uae30\ub2e4\ub9ac\uace0 \uc788\uc74c
-PeersView.state.established=\ub109\ub109\ud788 \ub9c8\ub828\ub428
+PeersView.state.info=\ud53c\uc5b4 \uc5f0\uacb0 \uc0c1\ud0dc
+PeersView.state.pending=\ubcf4\ub958 \uc911
+PeersView.state.connecting=\uc5f0\uacb0 \uc911
+PeersView.state.handshake=\ud578\ub4dc\uc250\uc774\ud06c\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911
+PeersView.state.established=\uc644\uc804\ud788 \ud655\ub9bd\ub428
 ConfigView.section.tracker.processinglimits=\ucc98\ub9ac \uc81c\ud55c
-ConfigView.section.tracker.maxgettime=GET \ucc98\ub9ac\uc5d0 \ub4dc\ub294 \ucd5c\ub300 \uc2dc\uac04 (\ucd08) [0: \ubb34\uc81c\ud55c]
-ConfigView.section.tracker.maxgettime.info=\uc54c\ub9ac\uae30\uc640 \ubaa8\uc73c\uae30\uc5d0 \uc4f0\uc784
-ConfigView.section.tracker.maxposttimemultiplier=POST \ucc98\ub9ac\uc5d0 \ub4dc\ub294 GET \uc2dc\uac04 \uacf1\uc218 [0: \ubb34\uc81c\ud55c]
-ConfigView.section.tracker.maxposttimemultiplier.info=\uc591\uc2dd \uc758\ub8b0\uc640 \uc62c\ub9ac\uae30\uc5d0 \uc4f0\uc784
-ConfigView.section.tracker.maxthreads=\ud55c\uaebc\ubc88\uc5d0 \uc0dd\uae30\ub294 \ucd5c\ub300 \uc694\uad6c
-DownloadManager.error.operationcancancelled=\uc791\uc5c5\uc774 \ucde8\uc18c\ub428
+ConfigView.section.tracker.maxgettime=GET \ucc98\ub9ac \ucd5c\ub300 \uc2dc\uac04 (\ucd08) [0: \ubb34\uc81c\ud55c]
+ConfigView.section.tracker.maxgettime.info=\uc54c\ub9bc\uacfc \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1\uc744 \uc704\ud574 \uc0ac\uc6a9\ub428
+ConfigView.section.tracker.maxposttimemultiplier=POST \ucc98\ub9ac\ub97c \uc704\ud55c GET \uc2dc\uac04 \ubc30\uc218 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.tracker.maxposttimemultiplier.info=\uc591\uc2dd \ubcf4\ub0b4\uae30\uc640 \uc5c5\ub85c\ub4dc\ub97c \uc704\ud574 \uc0ac\uc6a9\ub428
+ConfigView.section.tracker.maxthreads=\ub3d9\uc2dc \uc694\uccad \ucd5c\ub300\uac12
+DownloadManager.error.operationcancancelled=\uc791\uc5c5 \ucde8\uc18c\ub428
 Torrent.create.progress.cancelled=\uc791\uc5c5\uc774 \ucde8\uc18c\ub428
 sharing.progress.cancel=\ucde8\uc18c
-wizard.maketorrents.autoopen=\ub9c8\uce58\uba74 \ubfcc\ub9b4 \ud1a0\ub7f0\ud2b8\ub97c \uc5f4\uae30
-ConfigView.section.sharing.rescanenable=\ubc14\ub010 \uac83\ub4e4\uc744 \uacf5\uc720\ud558\ub824\ub294 \uc8fc\uae30\uc801\uc778 \ub2e4\uc2dc \ud6d1\uae30 \uc791\ub3d9
-ConfigView.section.sharing.rescanperiod=\ub2e4\uc2dc \ud6d1\ub294 \uc8fc\uae30(secs)
+wizard.maketorrents.autoopen=\uc644\ub8cc\ub418\uba74 \ubc30\ud3ec\ub97c \uc704\ud574 \ud1a0\ub80c\ud2b8 \uc5f4\uae30
+ConfigView.section.sharing.rescanenable=\ubcc0\uacbd \uc0ac\ud56d\uc5d0 \ub300\ud55c \uace0\uc801\uc2dd \uacf5\uc720\uc758 \ub2e4\uc2dc \uac80\uc0c9 \uc8fc\uae30 \ud65c\uc131\ud654
+ConfigView.section.sharing.rescanperiod=\uc7ac\uac80\uc0c9 \uc8fc\uae30 (\ucd08)
 ConfigView.section.connection.advanced=\uace0\uae09 \ub124\ud2b8\uc6cc\ud06c \uc124\uc815
-ConfigView.section.connection.advanced.mtu=\ud68c\uc120 \ucd5c\ub300 \uc804\uc1a1 \ub2e8\uc704(MTU)
-ConfigView.section.connection.advanced.mtu.tooltip=\ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \ud55c \ud504\ub808\uc784\uc5d0 \uc804\uc1a1\ud560 \uc218 \uc788\ub294 \ud328\ud0b7\uc758 \ucd5c\ub300 \ud06c\uae30\nVuze \uc62c\ub9ac\uae30 \ud328\ud0b7 \ud0d1\uc7ac\ub7c9\uc744 \ucd5c\uc801\ud654\ud558\ub824\uace0 MTU-40(MSS)\uc744 \uc501\ub2c8\ub2e4.\n\uad8c\ud558\ub294 \uac12:\n  576 - \uc804\ud654 \uc811\uc18d \ubaa8\ub380\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc5f0\uacb0\n1492 - \uc0ac\uc6a9\uc790 \uc [...]
-ConfigView.section.connection.advanced.SO_RCVBUF=\uc18c\ucf13 SO_RCVBUF \ud06c\uae30 [0: \uc6b4\uc601 \uccb4\uacc4 \uae30\ubcf8\uac12\uc744 \uc500]
-ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=(\ubc14\uc774\ud2b8\ub85c \ubcf4\uc774\ub294) \ud45c\uc900 \uc18c\ucf13 SO_RCVBUF \uac12\uc744 \uc124\uc815\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 TCP \uc218\uc2e0 \uc708\ub3c4\uc6b0 \ud06c\uae30\uc640 \ud06c\uae30 \uc870\uc815\uc774 \uc788\uc2b5\ub2c8\ub2e4.\nVuze ub294 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc740 \ucc44 \ub461\ub2c8\ub2e4. \uae30\ubcf8\uac12\uc740 \ubc11\uc744 \uc774\ub8e8\ub294 \uc6 [...]
-ConfigView.section.connection.advanced.SO_SNDBUF=\uc18c\ucf13 SO_SNDBUF \ud06c\uae30 [0: \uc6b4\uc601 \uccb4\uacc4 \uae30\ubcf8\uac12\uc744 \uc500]
-ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=(\ubc14\uc774\ud2b8\ub85c \ubcf4\uc774\ub294) \ud45c\uc900 \uc18c\ucf13 SO_SNDBUF \uac12\uc744 \uc124\uc815\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 TCP \uc1a1\uc2e0 \uc708\ub3c4\uc6b0 \ud06c\uae30\uac00 \uc788\uc2b5\ub2c8\ub2e4.\nVuze ub294 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc740 \ucc44 \ub461\ub2c8\ub2e4. \uae30\ubcf8\uac12\uc740 \ubc11\uc744 \uc774\ub8e8\ub294 \uc6b4\uc601 \uccb4\uacc4\uc5d0\uc11 [...]
-ConfigView.section.interface.confirm_torrent_removal=\ud1a0\ub7f0\ud2b8\ub97c \uc9c0\uc6b8 \ub54c \ud655\uc778 \uba54\uc138\uc9c0 \uc0c1\uc790\ub97c \ubcf4\uc774\uae30
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\ub0b4 \ud1a0\ub7f0\ud2b8 \ubcf4\uc784\uc0c8\uc5d0\uc11c \ud1a0\ub7f0\ud2b8\ub97c \uc9c0\uc6b8 \ub54c \ud655\uc778\ud569\ub2c8\ub2e4.
-MyTorrentsView.confirm_torrent_removal=\uc815\ub9d0 \uc9c0\uc6b0\uaca0\uc2b5\ub2c8\uae4c?\n
-TableColumn.header.seed_to_peer_ratio=\uc528\uc557\uacfc \ub3d9\ub8cc\uc758 \ube44
-TableColumn.header.seed_to_peer_ratio.info=\ucd1d \ub5bc\uc758 \uc528\uc557\uacfc \ub3d9\ub8cc\ub4e4\uc758 \ube44
+ConfigView.section.connection.advanced.mtu=\ud68c\uc120 \ucd5c\ub300 \uc804\uc1a1 \ub2e8\uc704 (MTU)
+ConfigView.section.connection.advanced.mtu.tooltip=\ub124\ud2b8\uc6cc\ud06c\ub97c \ud1b5\ud574 \ud55c \ud504\ub808\uc784\uc5d0 \uc804\uc1a1\ud560 \uc218 \uc788\ub294 \ud328\ud0b7\uc758 \ucd5c\ub300 \ud06c\uae30\uc785\ub2c8\ub2e4.\nVuze\ub294 \uc5c5\ub85c\ub4dc \ud328\ud0b7 \ud328\uc774\ub85c\ub4dc \ucd5c\uc801\ud654\ub97c \uc704\ud574 MTU-40 (MSS)\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.\n\uad8c\uc7a5 \uac12:\n  576 - \uc804\ud654 \uc5f0\uacb0\n1492 - PPPoE \uad11\ub300\uc5ed \uc5f0\uacb0\n [...]
+ConfigView.section.connection.advanced.SO_RCVBUF=\uc18c\ucf13 SO_RCVBUF \ud06c\uae30 [0: OS \uae30\ubcf8\uac12 \uc0ac\uc6a9]
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\ubc14\uc774\ud2b8 \ub2e8\uc704\uc758 \ud45c\uc900 \uc18c\ucf13 SO_RCVBUF \uac12\uc744 \uc124\uc815\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, TCP \uc218\uc2e0 \uc708\ub3c4\uc6b0 \ud06c\uae30\uc640 \uc2a4\ucf00\uc77c.\nVuze\ub294 \uae30\ubcf8\uc73c\ub85c \uc774 \uac12\uc744 \uc124\uc815\ud558\uc9c0 \uc54a\uc740\uccb4\ub85c \ub46c\uc11c \uae30\ubc18 OS\uac00 \uc0ac\uc6a9\ud558\ub294 \uac12\uc744 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc [...]
+ConfigView.section.connection.advanced.SO_SNDBUF=\uc18c\ucf13 SO_SNDBUF \ud06c\uae30 [0: OS \uae30\ubcf8\uac12 \uc0ac\uc6a9]
+ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\ubc14\uc774\ud2b8 \ub2e8\uc704\uc758 \ud45c\uc900 \uc18c\ucf13 SO_SNDBUF \uac12\uc744 \uc124\uc815\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, TCP \uc1a1\uc2e0 \uc708\ub3c4\uc6b0 \ud06c\uae30.\nVuze\ub294 \uae30\ubcf8\uc73c\ub85c \uc774 \uac12\uc744 \uc124\uc815\ud558\uc9c0 \uc54a\uc740\uccb4\ub85c \ub46c\uc11c \uae30\ubc18 OS\uac00 \uc0ac\uc6a9\ud558\ub294 \uac12\uc744 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.\n* [...]
+ConfigView.section.connection.advanced.IPDiffServ=\ub098\uac00\ub294 \ud328\ud0b7 SiffServ \uac12 (TOS \ud544\ub4dc)
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=\ub098\uac00\ub294 \ud328\ud0b7\uc758 IP \ud574\ub354\uc5d0 \uc11c\ube44\uc2a4 \uc720\ud615 (TOS) \ud544\ub4dc\uc758 DiffServ \ubd80\ubb38\uc744 \uc124\uc815\ud569\ub2c8\ub2e4.\n'0x'\ub97c \uc55e\uc5d0 \ubd99\uc5ec\uc11c 16\uc9c4\uc218 \uac12\uc73c\ub85c \uc9c0\uc815\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, 0x10.\nVuze\ub294 \uae30\ubcf8\uc73c\ub85c \uc774 \uac12\uc744 \uc124\uc815\ud558\uc9c0 \uc54a [...]
+TableColumn.header.seed_to_peer_ratio=\uc2dc\ub4dc:\ud53c\uc5b4 \ube44\uc728
+TableColumn.header.seed_to_peer_ratio.info=\uc804\uccb4 \uc2a4\uc6dc\uc758 \uc2dc\ub4dc \ub300 \ud53c\uc5b4 \ube44\uc728\uc785\ub2c8\ub2e4.
 PeersView.connected_time=\uc5f0\uacb0\ub41c \uc2dc\uac04
-PeersView.connected_time.info=\ub3d9\ub8cc\uc640 \uc5f0\uacb0\ub41c \ucd1d \uc2dc\uac04
-ConfigView.section.interface.display.add_torrents_silently=\uc7a0\uc790\ucf54 \ud1a0\ub7f0\ud2b8 \ub354\ud558\uae30
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Vuze \uc8fc \ucc3d\uc744 \ud65c\uc131\ud654\ud558\uc9c0 \uc54a\uace0 \ud1a0\ub7f0\ud2b8 \ub0b4\ub824\ubc1b\uae30\ub97c \ub354\ud569\ub2c8\ub2e4.
-TableColumn.header.maxdownspeed=\ub0b4\ub824\ubc1b\uae30 \ucd5c\uace0 \uc18d\ub3c4
-TableColumn.header.maxdownspeed.info=\ud1a0\ub7f0\ud2b8\ub9c8\ub2e4\uc758 \ub0b4\ub824\ubc1b\uae30 \ucd5c\uace0 \uc18d\ub3c4
-PeersGraphicView.title=\ub5bc
-ConfigView.section.tracker.passwordwebhttpsonly=HTTPS\ub85c\ub9cc \uc811\uadfc \ud5c8\uc6a9
-TableColumn.header.torrentpath=\ud1a0\ub7f0\ud2b8 \uc704\uce58
-TableColumn.header.torrentpath.info=\ub514\uc2a4\ud06c\uc5d0 \uc788\ub294 \ud1a0\ub7f0\ud2b8\uc758 \uc704\uce58
-ConfigView.section.sharing.torrentcomment=\ub9cc\ub4e0 \ud1a0\ub7f0\ud2b8\uc5d0 \ub367\ub9d0 \uc791\uc131
-ConfigView.label.copyanddeleteratherthanmove=\ud55c \uc791\uc5c5\uc5d0\uc11c \ubcf8\ub514 \ub370\uc774\ud130\ub97c \uc62e\uae30\uae30\ubcf4\ub2e4 \uc624\ud788\ub824 \ubcf5\uc0ac\ud558\uace0\uc11c \ubcf8\ub514 \ub370\uc774\ud130\ub97c \uc9c0\uc6b0\uae30 - \uba87\uba87 \ud30c\uc77c \uc2dc\uc2a4\ud15c\uc5d0\uc11c \ub370\uc774\ud130 \ubd84\uc2e4\uc744 \ud53c\ud558\ub3c4\ub85d \ub3c4\uc640\uc904 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-ConfigView.label.openstatsonstart=\uc2dc\uc791\ud560 \ub54c \ud1b5\uacc4 \uc5f4\uae30
-swt.install.window.title=Vuze \ucd94\uac00\uae30\ub2a5 \uc124\uce58 \ud504\ub85c\uadf8\ub7a8
+PeersView.connected_time.info=\ud53c\uc5b4\uc640 \uc5f0\uacb0\ub41c \ucd1d \uc2dc\uac04
+TableColumn.header.maxdownspeed=\ucd5c\ub300 \ub2e4\uc6b4 \uc18d\ub3c4
+TableColumn.header.maxdownspeed.info=\ud53c\uc5b4\uc5d0 \uc124\uc815\ub41c \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc785\ub2c8\ub2e4.
+PeersGraphicView.title.full=\uc2a4\uc6dc
+ConfigView.section.tracker.passwordwebhttpsonly=HTTPS\ub97c \ud1b5\ud574\uc11c\ub9cc \uc811\uadfc \ud5c8\uc6a9
+TableColumn.header.torrentpath=\ud1a0\ub80c\ud2b8 \uc704\uce58
+TableColumn.header.torrentpath.info=\ub514\uc2a4\ud06c \uc0c1\uc5d0\uc11c \ud1a0\ub80c\ud2b8 \uc704\uce58(\uacbd\ub85c)\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+ConfigView.section.sharing.torrentcomment=\uc0dd\uc131\ub41c \ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud55c \uc8fc\uc11d
+ConfigView.label.copyanddeleteratherthanmove=\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uc791\uc5c5 \ud55c \ubc88\uc73c\ub85c \uc774\ub3d9\ud558\uae30 \ubcf4\ub2e4 \ubcf5\uc0ac\ud6c4 \uc0ad\uc81c\ud558\ub294 \ubc29\uc2dd\uc73c\ub85c \uc774\ub3d9 (\uc77c\ubd80 \ud30c\uc77c \uc2dc\uc2a4\ud15c\uc5d0\uc11c \ub370\uc774\ud130 \uc190\uc2e4 \ubc29\uc9c0\uc5d0 \ub3c4\uc6c0\ub420 \uc218 \uc788\uc74c)
+ConfigView.label.openstatsonstart=\uc2dc\uc791 \uc2dc \ud1b5\uacc4 \uc5f4\uae30
+swt.install.window.title=Vuze \uad6c\uc131 \uc694\uc18c/\ud50c\ub7ec\uadf8\uc778 \uc124\uce58 \ub9c8\ubc95\uc0ac
 swt.install.window.ok=\uc124\uce58
-swt.install.window.header=\ub2e4\uc74c \uad6c\uc131 \uc694\uc18c\ub4e4\uc744 \uc124\uce58\ud558\ub824\uace0 \uace8\ub790\uc2b5\ub2c8\ub2e4.:
-swt.uninstall.window.title=Vuze \ucd94\uac00\uae30\ub2a5 \uc9c0\uc6b0\uae30 \ud504\ub85c\uadf8\ub7a8
-swt.uninstall.window.ok=\uc9c0\uc6b0\uae30
-swt.uninstall.window.header=\ub2e4\uc74c \uad6c\uc131 \uc694\uc18c\ub4e4\uc744 \uc9c0\uc6b0\ub824\uace0 \uace8\ub790\uc2b5\ub2c8\ub2e4.:
-installPluginsWizard.title=\ucd94\uac00\uae30\ub2a5 \uc124\uce58
-installPluginsWizard.mode.title=\uc124\uce58 \ubc29\ubc95\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-installPluginsWizard.mode.list=sourceforge.net\uc758 \ubaa9\ub85d\uc73c\ub85c
-installPluginsWizard.list.title=\uc124\uce58\ud560 \uc218 \uc788\ub294 \ucd94\uac00\uae30\ub2a5 \ubaa9\ub85d
-installPluginsWizard.list.loading=\ucd94\uac00\uae30\ub2a5 \ubaa9\ub85d\uc744 \ubd88\ub7ec\uc624\ub294 \ub3d9\uc548 \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc694.
-installPluginsWizard.list.loaded=\uc124\uce58\ud558\ub824\ub294 \ucd94\uac00\uae30\ub2a5\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
+swt.install.window.header=\ub2e4\uc74c \uad6c\uc131 \uc694\uc18c\ub294 \uc124\uce58\ub97c \uc704\ud574 \uc120\ud0dd\ub418\uc5c8\uc2b5\ub2c8\ub2e4:
+swt.uninstall.window.title=Vuze \uad6c\uc131 \uc694\uc18c/\ud50c\ub7ec\uadf8\uc778 \uc81c\uac70\uae30
+swt.uninstall.window.ok=\uc81c\uac70
+swt.uninstall.window.header=\ub2e4\uc74c \uad6c\uc131 \uc694\uc18c\ub294 \uc81c\uac70\ub97c \uc704\ud574 \uc120\ud0dd\ub418\uc5c8\uc2b5\ub2c8\ub2e4 :
+installPluginsWizard.title=\ud50c\ub7ec\uadf8\uc778 \uc124\uce58
+installPluginsWizard.mode.title=\uc124\uce58 \ubc29\uc2dd\uc744 \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
+installPluginsWizard.mode.list=sourceforge.net\uc5d0\uc11c \uac00\uc838\uc628 \ubaa9\ub85d\uc73c\ub85c
+installPluginsWizard.list.title=\uc124\uce58\ud560 \uc218 \uc788\ub294 \ud50c\ub7ec\uadf8\uc778 \ubaa9\ub85d
+installPluginsWizard.list.loading=\ud50c\ub7ec\uadf8\uc778 \ubaa9\ub85d\uc744 \ubd88\ub7ec\uc624\ub294 \ub3d9\uc548 \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc624.
+installPluginsWizard.list.loaded=\uc124\uce58\ud558\ub824\ub294 \ud50c\ub7ec\uadf8\uc778\uc744 \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.
 installPluginsWizard.list.name=\uc774\ub984
 installPluginsWizard.list.version=\ubc84\uc804
-installPluginsWizard.list.description=\ucd94\uac00\uae30\ub2a5\uc758 \uc124\uba85
-installPluginsWizard.finish.title=\uc9c4\ud589\ud558\uace0 \uc788\ub294 \uc124\uce58
-installPluginsWizard.finish.explanation=\uc120\ud0dd\ud55c \ucd94\uac00\uae30\ub2a5\ub4e4\uc740 \uc5c5\ub370\uc774\ud2b8 \ub3c4\uc6b0\ubbf8\ub97c \uc368\uc11c \uc124\uce58\ub420 \uac83\uc785\ub2c8\ub2e4.\n\n\ub290\uae0b\ud558\uac8c \uae30\ub2e4\ub9ac\uba74 \uae08\ubc29 \ub098\ud0c0\ub0a0 \uac83\uc785\ub2c8\ub2e4.\n\n\uc9c4\ud589 \uae30\ub85d\uc744 \ubcf4\ub824\uba74 \uc0c1\ud0dc \ud45c\uc2dc\uc904\uc758 \uc67c\ucabd\uc744 \ub354\ube14 \ud074\ub9ad\ud558\uc2ed\uc2dc\uc694.
-installPluginsWizard.details.loading=\uc0c1\uc138 \uc815\ubcf4\ub97c \ubd88\ub7ec\uc624\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc694...
+installPluginsWizard.list.description=\ud50c\ub7ec\uadf8\uc778 \uc124\uba85
+installPluginsWizard.finish.title=\uc9c4\ud589 \uc911\uc778 \uc124\uce58
+installPluginsWizard.finish.explanation=\uc120\ud0dd\ud55c \ucd94\uac00\uae30\ub2a5\ub4e4\uc740 \uc5c5\ub370\uc774\ud2b8 \ub3c4\uc6b0\ubbf8\ub97c \uc0ac\uc6a9\ud574\uc11c \uc124\uce58\ub420 \uac83\uc785\ub2c8\ub2e4.\n\n\uc7a0\uc2dc \uae30\ub2e4\ub824\uc8fc\uc2ed\uc2dc\uc624. \ub3c4\uc6b0\ubbf8\uac00 \ub098\ud0c0\ub098\ub824\uba74 \uc57d\uac04 \uc2dc\uac04\uc774 \uac78\ub9bd\ub2c8\ub2e4.\n\n\uc9c4\ud589 \ub9ac\ud3ec\ud2b8\ub97c \ubcf4\ub824\uba74, \uc0c1\ud0dc \ud45c\uc2dc\uc904\uc758 \uc [...]
+installPluginsWizard.details.loading=\uc138\ubd80\uc0ac\ud56d\uc744 \uc5ec\ub294 \uc911, \uae30\ub2e4\ub824 \uc8fc\uc2ed\uc2dc\uc624...
 installPluginsWizard.mode.file=\ud30c\uc77c\ub85c
-installPluginsWizard.installMode.title=\uc124\uce58 \uc591\uc2dd\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-installPluginsWizard.installMode.user=\ub2f9\uc2e0\ub9cc \uc4f0\uac8c\ub054 \ucd94\uac00\uae30\ub2a5\uc744 \uc124\uce58
-installPluginsWizard.installMode.shared=\ubaa8\ub4e0 \uc0ac\uc6a9\uc790\ub4e4\uc774 \uc4f0\uac8c\ub054 \ucd94\uac00\uae30\ub2a5\uc744 \uc124\uce58
-installPluginsWizard.file.title=\uc124\uce58\ud560 \ucd94\uac00\uae30\ub2a5\uc744 \ucc3e\uc544\ubcf4\uc2ed\uc2dc\uc694.
-installPluginsWizard.file.file=\ud30c\uc77c:
-installPluginsWizard.file.invalidfile=\uc774 \ud30c\uc77c\uc740 Vuze \ucd94\uac00\uae30\ub2a5\uc774 \uc544\ub2d9\ub2c8\ub2e4.
+installPluginsWizard.installMode.title=\uc124\uce58 \uc720\ud615\uc744 \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624
+installPluginsWizard.installMode.user=\ubcf8\uc778\uc744 \uc704\ud574\uc11c\ub9cc \ud50c\ub7ec\uadf8\uc778 \uc124\uce58
+installPluginsWizard.installMode.shared=\ubaa8\ub4e0 \uc0ac\uc6a9\uc790\uac00 \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud50c\ub7ec\uadf8\uc778 \uc124\uce58
+installPluginsWizard.file.title=\uc124\uce58\ud560 \ucd94\uac00\uae30\ub2a5\uc744 \ucc3e\uc544\ubcf4\uc2ed\uc2dc\uc624
+installPluginsWizard.file.file=\ud30c\uc77c :
+installPluginsWizard.file.invalidfile=\ud574\ub2f9 \ud30c\uc77c\uc740 \uc62c\ubc14\ub978 Vuze \ud50c\ub7ec\uadf8\uc778\uc774 \uc544\ub2d9\ub2c8\ub2e4.
+installPluginsWizard.file.no_such_file=\uc8fc\uc5b4\uc9c4 \uc774\ub984\uc758 \ud30c\uc77c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
 installPluginsWizard.file.browse=\ucc3e\uc544\ubcf4\uae30...
 uninstallPluginsWizard.title=\ucd94\uac00\uae30\ub2a5 \uc81c\uac70
 uninstallPluginsWizard.list.title=\uc124\uce58\ub41c \ucd94\uac00\uae30\ub2a5 \ubaa9\ub85d
@@ -1350,1075 +1344,1885 @@ uninstallPluginsWizard.finish.title=\uc9c4\ud589\ud558\uace0 \uc788\ub294 \uc81c
 uninstallPluginsWizard.finish.explanation=\uc0ac\uc6a9\ud558\uace0 \uc788\ub294 \ucd94\uac00\uae30\ub2a5\ub4e4\uc740 \uc5c5\ub370\uc774\ud2b8 \ub3c4\uc6b0\ubbf8\ub97c \uc368\uc11c \uc81c\uac70\ub420 \uac83\uc785\ub2c8\ub2e4.
 MainWindow.menu.plugins.installPlugins=\uc124\uce58 \ub9c8\ubc95\uc0ac...
 MainWindow.menu.plugins.uninstallPlugins=\uc81c\uac70 \ub9c8\ubc95\uc0ac...
-ConfigView.section.ipfilter.totalIPs=\uc804\uccb4\uc5d0\uc11c %1 IP\ub4e4\uc744 \ub9c9\uc558\uc2b5\ub2c8\ub2e4. \uc804\uccb4\ub294 \uc778\ud130\ub137\uc758 %2\uc785\ub2c8\ub2e4.
-update.instance.install=\uc124\uce58\ub97c \uac80\uc0ac\ud558\uace0 \uc788\uc74c
-update.instance.uninstall=\uc81c\uac70\ub97c \uac80\uc0ac\ud558\uace0 \uc788\uc74c
-update.instance.update=\uc5c5\ub370\uc774\ud2b8\ub97c \uac80\uc0ac\ud558\uace0 \uc788\uc74c
+ConfigView.section.ipfilter.totalIPs=\ucd1d %1 IP\uac00 \ucc28\ub2e8\ub428, \uc774\ub294 \uc778\ud130\ub137 \uc0c1\uc758 %2\uc5d0 \ud574\ub2f9\ud569\ub2c8\ub2e4.
+update.instance.install=\uc124\uce58 \uac80\uc0ac \uc911
+update.instance.uninstall=\uc81c\uac70 \uac80\uc0ac \uc911
+update.instance.update=\uc5c5\ub370\uc774\ud2b8 \uac80\uc0ac \uc911
 MainWindow.status.update.tooltip=\uc9c4\ud589 \uc815\ubcf4\ub97c \ubcf4\ub824\uba74 \ub354\ube14 \ud074\ub9ad
-updater.progress.window.title=\uc9c0\uae08\uc758 \uc124\uce58 \uc791\uc5c5
-updater.progress.window.info=\uc544\uc9c1 \ud574\uacb0\ud558\uc9c0 \ubabb\ud55c \ubaa8\ub4e0 \uc791\uc5c5\uc744 \ub05d\ub0b4\ub824\uba74 '\uadf8\ub9cc\ub460'\uc744 \ub204\ub974\uc2ed\uc2dc\uc694.
-Button.abort=\uadf8\ub9cc\ub460
-ConfigView.section.ipfilter.enablebanning=\ud55c\uacb0\uac19\uc774 \uc545\uc131 \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ub3d9\ub8cc \ub9c9\uc74c
-Network.alert.acceptfail=%1, %2 \ud3ec\ud2b8\uc5d0\uc11c \ub108\ubb34 \ub9ce\uc774 \uc787\ub530\ub978 \uc798\ubabb\ub41c \uac83\ub4e4\uc774 \uc77c\uc5b4\ub0ac\uc2b5\ub2c8\ub2e4. - \ucc98\ub9ac\uac00 \ubc84\ub824\uc9d0. \uc774 \ud3ec\ud2b8\uc758 \ubc29\ud654\ubcbd \uc124\uc815\uc744 \uc0b4\ud3b4\ubcf4\uace0 \ub098\uc11c \uc218\uc2e0 \uc5f0\uacb0\uc5d0\uc11c \uc774 \ud3ec\ud2b8\uac00 \uc791\ub3d9\ud558\ub3c4\ub85d \ud558\uc2ed\uc2dc\uc694.
+updater.progress.window.title=\ud604\uc7ac \uc124\uce58 \uc791\uc5c5
+updater.progress.window.info=\ubaa8\ub4e0 \ubbf8\uc644\uc131 \uc791\uc5c5\uc744 \uc911\ub2e8\ud558\ub824\uba74 '\uc911\ub2e8'\uc744 \ub204\ub974\uae30
+Button.abort=\uc911\ub2e8
+ConfigView.section.ipfilter.enablebanning=\uc9c0\uc18d\uc801\uc73c\ub85c \uc190\uc0c1\ub41c \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ud53c\uc5b4 \ucc28\ub2e8
+Network.alert.acceptfail=%1 \ud3ec\ud2b8\uc5d0\uc11c \ub108\ubb34 \ub9ce\uc740 \uc5f0\uc18d\uc801 \uc2e4\ud328\uac00 \uc77c\uc5b4\ub098\uc11c, %2 \ucc98\ub9ac\uac00 \ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \ud574\ub2f9 \ud3ec\ud2b8\uc5d0 \ub300\ud55c \ubc29\ud654\ubcbd \uc124\uc815\uc744 \uc0b4\ud3b4\ubcf4\uace0 \uc5f0\uacb0\uc744 \ubc1b\uc744 \uc218 \uc788\ub3c4\ub85d \ud65c\uc131\ud654 \ub418\uc5b4 \uc788\uc74c\uc744 \ud655\uc778\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
 MyShares.column.category=\ubd84\ub958
-UpdateWindow.restartLater=\ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\uc791
+UpdateWindow.restartLater=\ub098\uc911\uc5d0 Vuze \ub2e4\uc2dc \uc2dc\uc791
 MainWindow.menu.file.restart=Vuze \ub2e4\uc2dc \uc2dc\uc791
-MainWindow.dialog.restartconfirmation.title=Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud558\uaca0\uc2b5\ub2c8\uae4c?
-MainWindow.dialog.restartconfirmation.text=Vuze\ub97c \uc815\ub9d0 \ub2e4\uc2dc \uc2dc\uc791\ud558\uaca0\uc2b5\ub2c8\uae4c?
-deletetorrent.message1=\ub2e4\uc74c\uc758 \ud1a0\ub7f0\ud2b8\ub97c \uc9c0\uae08 \uc9c0\uc6b0\ub824\uace0 \ud569\ub2c8\ub2e4:\n
-deletetorrent.message2=\n\uc815\ub9d0 \uacc4\uc18d\ud558\uaca0\uc2b5\ub2c8\uae4c?
-ConfigView.label.prioritizemostcompletedfiles=\uac00\uc7a5 \ub9ce\uc774 \ub05d\ub9c8\uce5c \ud30c\uc77c\uc744 \uc6b0\uc120\uc2dc\ud0b4
-splash.plugin.init=\ucd94\uac00\uae30\ub2a5\uc744 \uc900\ube44\ud558\uace0 \uc788\uc74c: 
-splash.plugin.UIinit=GUI \ucd94\uac00\uae30\ub2a5\uc744 \uc900\ube44\ud558\uace0 \uc788\uc74c: %1  
-ConfigView.section.style.osx_small_fonts=\uc791\uc740 \uae00\uaf34\uc744 \uc500 [\ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud568]
-ConfigView.section.tracker.tcpnonblocking=TCP \ub354\ub4ec\uc774 \ucc98\ub9ac\uc5d0 \ub9c9\uc9c0 \uc54a\uc744 \uc785\ucd9c\ub825\uc744 \uc501\ub2c8\ub2e4. \uc774 \uc120\ud0dd\uc0ac\ud56d\uc744 \uace0\ub974\ub824\uba74 \ub2e4\ub978 \ud3ec\ud2b8\uc5d0\uc11c \ub3cc\uc544\uac08 \ub354\ub4ec\uc774 \uc6f9\uc774 \ud544\uc694\ud569\ub2c8\ub2e4. \uc2dc\ud5d8\uc801\uc784
-ConfigView.section.tracker.nonblocking=\ub9c9\uc9c0 \uc54a\uae30 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.tracker.nonblockingconcmax=\ud55c\uaebc\ubc88\uc5d0 \uc0dd\uae30\ub294 \ucd5c\ub300 \uc5f0\uacb0 [0: \ubb34\uc81c\ud55c]
+MainWindow.dialog.restartconfirmation.title=Vuze \ub2e4\uc2dc \uc2dc\uc791
+MainWindow.dialog.restartconfirmation.text=\uc815\ub9d0\ub85c Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c
+ConfigView.label.prioritizemostcompletedfiles=\uc774\ud6c4\uc5d0\ub294 \ud30c\uc77c\uc758 \uc644\ub8cc\ub41c %\uc640 \ud06c\uae30\uc5d0 \ub530\ub77c \ub192\uc740 \uc6b0\uc120\uc21c\uc704 \ud30c\uc77c\uc744 \uacb0\uc815
+splash.plugin.init=\ucd94\uac00\uae30\ub2a5\uc744 \uc900\ube44\ud558\uace0 \uc788\uc74c:
+splash.plugin.UIinit=GUI \ucd94\uac00\uae30\ub2a5\uc744 \uc900\ube44\ud558\uace0 \uc788\uc74c: %1
+ConfigView.section.style.osx_small_fonts=\uc791\uc740 \uae00\uaf34 \uc0ac\uc6a9 [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
+ConfigView.section.tracker.tcpnonblocking=TCP \ud2b8\ub798\ucee4 \ucc98\ub9ac\uc5d0 \ube44\ucc28\ub2e8 I/O\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4. \uc774 \uc635\uc158\uc744 \uc120\ud0dd\ud558\ub824\uba74 \ub2e4\ub978 \ud3ec\ud2b8\uc5d0\uc11c \ud2b8\ub798\ucee4 \uc6f9\uc774 \uc2e4\ud589\ub418\uace0 \uc788\uc5b4\uc57c \ud569\ub2c8\ub2e4. \uc2e4\ud5d8\uc801\uc778 \uae30\ub2a5!
+ConfigView.section.tracker.nonblocking=\ube44\ucc28\ub2e8 \uc635\uc158
+ConfigView.section.tracker.nonblockingconcmax=\ucd5c\ub300 \ub3d9\uc2dc \uc5f0\uacb0 [0: \ubb34\uc81c\ud55c]
 MyTorrentsView.menu.exportmenu=\ub0b4\ubcf4\ub0b4\uae30
-MyTorrentsView.menu.exporttorrent=\ud1a0\ub7f0\ud2b8...
-ConfigView.group.scrape=\ubaa8\uc73c\uae30
-ConfigView.section.tracker.client.scrapeinfo=\ubaa8\uc73c\uae30\ub97c \ud558\uc9c0 \uc54a\uc73c\uba74 \ub9ce\uc740 \ud1a0\ub7f0\ud2b8 \ub300\uae30 \uaddc\uce59\ub4e4\uc774 \ubaa8\uc73c\uae30 \ub354\ub4ec\uc774\ub4e4\ub85c \ub418\ucc3e\ub294 \ub5bc \uc815\ubcf4\uc5d0 \uc758\uc9c0\ud558\ub294 \ub9cc\ud07c \uc791\ub3d9\ud558\uc9c0 \ubabb\ud558\uac8c \ud560 \uac83\uc785\ub2c8\ub2e4.
-ConfigView.section.tracker.client.scrapeenable=\ubaa8\uc73c\uae30 \uc791\ub3d9
-ConfigView.section.tracker.client.scrapestoppedenable=\uc6c0\uc9c1\uc774\uace0 \uc788\uc9c0 \uc54a\uc740 \ud1a0\ub7f0\ud2b8\ub4e4 \ubaa8\uc73c\uae30
-Scrape.status.disabled=\ubaa8\uc744 \uc218 \uc5c6\uc74c
-MyTorrentsView.menu.explore=\ud30c\uc77c \ubcf4\uc774\uae30
-MyTorrentsView.menu.explore._mac=\uac80\uc0c9\uc73c\ub85c \ubcf4\uc774\uae30
-MyTorrentsView.menu.explore._windows=\ud0d0\uc0c9\uae30\ub85c \ubcf4\uc774\uae30
-wizard.maketorrents.autohost=\ubcf8\ub798 \uac16\ucdb0\uc9c4 \ub354\ub4ec\uc774\uc5d0 \ud1a0\ub7f0\ud2b8\ub97c \ud638\uc2a4\ud2b8\ud558\uae30
-ConfigView.label.overrideip=\ub354\ub4ec\uc774 \uc54c\ub9bc IP \uc8fc\uc18c \ubb34\uc2dc
-ConfigView.label.overrideip.tooltip=\uc5b4\ub5a4 IP \uc8fc\uc18c\uc5d0\uc11c \ub098\uac00\ub294 \ud328\ud0b7\uacfc \ub2e4\ub978 IP \uc8fc\uc18c\uc758 \ub354\ub4ec\uc774\ub97c \uc54c\ub824 \uc90d\ub2c8\ub2e4. \uc120\ud0dd\uc0ac\ud56d\uc744 \uc4f0\uc9c0 \uc54a\uc73c\ub824\uba74 \ube44\uc6cc \ub450\uc2ed\uc2dc\uc694.
+MyTorrentsView.menu.exporttorrent=\ud1a0\ub80c\ud2b8...
+ConfigView.group.scrape=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1
+ConfigView.section.tracker.client.scrapeinfo=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1\uc744 \ud558\uc9c0 \uc54a\uc73c\uba74 \ud2b8\ub798\ucee4\uc5d0\uc11c \uac00\uc838\uc628 \uc2a4\uc6dc \uc815\ubcf4\uc5d0 \uc758\uc874\ud558\ub294 \n\ub300\ubd80\ubd84\uc758 \ud1a0\ub80c\ud2b8 \ub300\uae30\uc5f4 \uaddc\uce59\uc774 \ub3d9\uc791\ud558\ub294 \uac83\uc744 \ub9c9\uac8c \ub429\ub2c8\ub2e4.
+ConfigView.section.tracker.client.scrapeenable=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \ud65c\uc131\ud654
+ConfigView.section.tracker.client.scrapestoppedenable=\uc2e4\ud589\uc911\uc774 \uc544\ub2cc \ud1a0\ub80c\ud2b8\uc758 \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1\ud558\uae30
+Scrape.status.disabled=\uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1 \ube44\ud65c\uc131\ub428
+MyTorrentsView.menu.explore=\ud30c\uc77c \ubcf4\uc5ec\uc8fc\uae30
+MyTorrentsView.menu.explore._mac=Finder\uc5d0\uc11c \ubcf4\uc5ec\uc8fc\uae30
+MyTorrentsView.menu.explore._windows=\ud0d0\uc0c9\uae30\uc5d0\uc11c \ubcf4\uc5ec\uc8fc\uae30
+wizard.maketorrents.autohost=\ub0b4\uc7a5 \ud2b8\ub798\ucee4\uc5d0\uc11c \ud574\ub2f9 \ud1a0\ub80c\ud2b8 \ud638\uc2a4\ud305
+ConfigView.label.overrideip=\uc6b0\uc120\uc801\uc6a9 \ud2b8\ub798\ucee4 \uc54c\ub9bc IP - \ub2e4\ub978 \ub124\ud2b8\uc6cc\ud06c\ub97c \uc704\ud55c \ud558\ub098 \uc774\uc0c1\uc758 IP\uac00 \uc788\uc73c\uba74 \uc138\ubbf8\ucf5c\ub860(;)\uc73c\ub85c \uad6c\ubd84
+ConfigView.label.overrideip.tooltip=\ud558\ub098 \uc774\uc0c1\uc758 \ub098\uac00\ub294 \ud328\ud0b7\uc774 \uc628 \ub2e4\ub978 IP \uc8fc\uc18c\ub97c \ud2b8\ub798\ucee4\uc5d0\uac8c \uc54c\ub824\uc90d\ub2c8\ub2e4. \uc635\uc158\uc744 \uc4f0\uc9c0 \uc54a\uc73c\ub824\uba74 \ube48 \uce78\uc73c\ub85c \ub450\uc2ed\uc2dc\uc624.
 ConfigView.section.connection.group.networks=\ub124\ud2b8\uc6cc\ud06c
-ConfigView.section.connection.group.networks.info=\ub3d9\ub8cc-\ub3d9\ub8cc \ub370\uc774\ud130 \uc804\uc1a1\uc5d0 \uae30\ubcf8\uc73c\ub85c \ud5c8\uc6a9\ub41c \ub124\ud2b8\uc6cc\ud06c\ub4e4\uc744 \uace0\ub974\uc2ed\uc2dc\uc694
-ConfigView.section.connection.networks.prompt=\uc775\uba85\uc758 \ub354\ub4ec\uc774\ub85c \ub0b4\ub824\ubc1b\uae30\uac00 \ub354\ud574\uc9c8 \ub54c \uace0\ub974\uae30\ub97c \ub744\uc6c0
-ConfigView.section.connection.networks.Public=\uacf5\uacf5\uc758 IP \ub124\ud2b8\uc6cc\ud06c (\uc775\uba85 \uc544\ub2d8)
+ConfigView.section.connection.group.networks.info=\ud53c\uc5b4-\ud53c\uc5b4 \ub370\uc774\ud130 \uc804\uc1a1\uc5d0 \ub300\ud574 \ud5c8\uc6a9\ub41c \ub124\ud2b8\uc6cc\ud06c \uae30\ubcf8\uac12\uc744 \uc120\ud0dd
+ConfigView.section.connection.networks.prompt=\uc775\uba85 \ud2b8\ub798\ucee4\uac00 \ucd94\uac00\ub41c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc788\uc73c\uba74 \uc120\ud0dd\ud560 \uc218 \uc788\ub3c4\ub85d \uc0ac\uc6a9\uc790\uc5d0\uac8c \ubb3c\uc5b4\ubcf4\uae30
+ConfigView.section.connection.networks.Public=\uacf5\uac1c IP \ub124\ud2b8\uc6cc\ud06c (\uc775\uba85 \uc544\ub2d8)
 ConfigView.section.connection.networks.I2P=I2P \ub124\ud2b8\uc6cc\ud06c
 ConfigView.section.connection.networks.Tor=The Onion Router (Tor) \ub124\ud2b8\uc6cc\ud06c
 TableColumn.header.networks=\ub124\ud2b8\uc6cc\ud06c
-TableColumn.header.networks.info=\ub3d9\ub8cc-\ub3d9\ub8cc \ub370\uc774\ud130 \ud1b5\uc2e0\uc774 \ud5c8\uc6a9\ub41c \ub124\ud2b8\uc6cc\ud06c
-Scrape.status.networkdisabled=\ub124\ud2b8\uc6cc\ud06c\uac00 \uc791\ub3d9\ud558\uc9c0 \uc54a\uc74c
+TableColumn.header.networks.info=\ud53c\uc5b4-\ud53c\uc5b4 \ub370\uc774\ud130 \ud1b5\uc2e0\uc774 \ud5c8\uc6a9\ub41c \ub124\ud2b8\uc6cc\ud06c\uc785\ub2c8\ub2e4.
+Scrape.status.networkdisabled=\ub124\ud2b8\uc6cc\ud06c\uac00 \ud65c\uc131\ud654\ub418\uc9c0 \uc54a\uc74c
 ConfigView.section.tracker.server.group.networks=\ub124\ud2b8\uc6cc\ud06c
-ConfigView.section.tracker.server.group.networks.info=\ub354\ub4ec\uc774\uac00 \ub3d9\ub8cc\ub4e4\uc744 \ud5c8\uc6a9\ud560 \ub124\ud2b8\uc6cc\ud06c\ub4e4\uc744 \uace0\ub974\uc2ed\uc2dc\uc694
-window.networkselection.title=\ub124\ud2b8\uc6cc\ud06c \uace0\ub974\uae30
-window.networkselection.info=\uc544\ub798 \uc2e4\ub9b0 \ud1a0\ub7f0\ud2b8\ub4e4\uc740 \ub2e4\uc74c \ub124\ud2b8\uc6cc\ud06c\ub4e4\uc744 \uc9c0\uc6d0\ud558\ub294 \ub354\ub4ec\uc774\ub4e4\uc774 \uc788\uc2b5\ub2c8\ub2e4.\n\ub354\ub4ec\uc774\uc640 \ub3d9\ub8cc \ud1b5\uc2e0\uc5d0 \uc4f8 \uac83\ub4e4\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.\n\uacf5\uacf5\uc758 \ucef4\ud4e8\ud130\ub4e4\uc744 \uc9c0\uc6d0\ud558\ub294 \uc775\uba85\uc758 \ub354\ub4ec\uc774\ub77c\uba74 \uc775\uba85\uacfc \uacf5\uacf5\ [...]
-window.networkselection.description=\ud1a0\ub7f0\ud2b8:
+ConfigView.section.tracker.server.group.networks.info=\ud2b8\ub798\ucee4\uac00 \ubc1b\uc544\ub4e4\uc77c \ud53c\uc5b4 \ub124\ud2b8\uc6cc\ud06c\ub97c \uc120\ud0dd
+window.networkselection.title=\ub124\ud2b8\uc6cc\ud06c \uc120\ud0dd
+window.networkselection.info=\uc544\ub798\uc5d0 \ub098\uc5f4\ub41c \ud1a0\ub80c\ud2b8\ub294 \ub2e4\uc74c \ub124\ud2b8\uc6cc\ud06c\ub85c\ubd80\ud130 \uc9c0\uc6d0\ub418\ub294 \ud2b8\ub798\ucee4\ub97c \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n\ud2b8\ub798\ucee4\uc640 \ud53c\uc5b4 \ud1b5\uc2e0\uc744 \uc704\ud574 \ud65c\uc131\ud654\ud560 \ub124\ud2b8\uc6cc\ud06c\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.\n\uacf5\uac1c \ud074\ub77c\uc774\uc5b8\ud2b8\ub97c \uc9c0\uc6d0\ud558\ub294 \uc775\u [...]
+window.networkselection.description=\ud1a0\ub80c\ud2b8 :
 plugins.basicview.clear=\uc9c0\uc6b0\uae30
-ConfigView.section.connection.group.peersources=\ub3d9\ub8cc \uc18c\uc2a4
-ConfigView.section.connection.group.peersources.info=\ub3d9\ub8cc \uc5f0\uacb0\ub4e4\uc5d0 \uae30\ubcf8\uc73c\ub85c \ud5c8\uc6a9\ub41c \uc18c\uc2a4\ub4e4\uc744 \uace0\ub974\uc2ed\uc2dc\uc694.
-ConfigView.section.connection.peersource.Tracker=\ub354\ub4ec\uc774\uc5d0\uc11c
-ConfigView.section.connection.peersource.DHT=\ubd84\uc0b0\ub41c \ub354\ub4ec\uae30
-ConfigView.section.connection.peersource.PeerExchange=\ub2e4\ub978 \ub3d9\ub8cc\uc5d0\uac8c \ubc1b\uc74c
-ConfigView.section.connection.peersource.Plugin=\ucd94\uac00\uae30\ub2a5\uc73c\ub85c \ub354\ud574\uc9d0
-ConfigView.section.connection.peersource.Incoming=\ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0
-PeersView.source=\uc18c\uc2a4
-PeersView.source.info=\uc774 \ub3d9\ub8cc\uc758 \uc18c\uc2a4
-TableColumn.header.peersources=\ub3d9\ub8cc \uc18c\uc2a4
-TableColumn.header.peersources.info=\ub3d9\ub8cc \uc5f0\uacb0\uc758 \uc218\ub9bd\uc774 \ud5c8\uc6a9\ub41c \ub3d9\ub8cc \uc18c\uc2a4
-wizard.tracker.dht=\ubd84\uc0b0\ub428 (Vuze \ud074\ub77c\uc774\uc5b8\ud2b8 \ud504\ub85c\uadf8\ub7a8\ub9cc)
+ConfigView.section.connection.group.peersources=\ud53c\uc5b4 \ucd9c\ucc98
+ConfigView.section.connection.group.peersources.info=\ud53c\uc5b4 \uc5f0\uacb0\uc5d0 \ub300\ud574 \uae30\ubcf8\uc73c\ub85c \ud5c8\uc6a9\ud560 \ucd9c\ucc98 \uc120\ud0dd
+ConfigView.section.connection.peersource.Tracker=Tracker: \ud2b8\ub798\ucee4\ub85c\ubd80\ud130 \ubc1b\uc740 \ud53c\uc5b4
+ConfigView.section.connection.peersource.DHT=DHT: \ubd84\uc0b0 \ud2b8\ub798\ud0b9\uc744 \ud1b5\ud574 \ubc1c\uacac\ud55c \ud53c\uc5b4
+ConfigView.section.connection.peersource.PeerExchange=PeerExchange: \ub2e4\ub978 \ud53c\uc5b4\uc5d0 \uc758\ud574 \uacf5\uae09\ub41c \ud53c\uc5b4
+ConfigView.section.connection.peersource.Plugin=Plugin: \ud50c\ub7ec\uadf8\uc778\uc5d0 \uc758\ud574 \ucd94\uac00\ub41c \ud53c\uc5b4
+ConfigView.section.connection.peersource.Incoming=Incoming: \ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0\uc5d0\uc11c \ubc1c\uacac\ud55c \ud53c\uc5b4
+PeersView.source=\ucd9c\ucc98
+PeersView.source.info=\uc774 \ud53c\uc5b4\uc758 \ucd9c\ucc98
+TableColumn.header.peersources=\ud53c\uc5b4 \ucd9c\ucc98
+TableColumn.header.peersources.info=\ud574\ub2f9 \ud53c\uc5b4 \ucd9c\ucc98\uc5d0 \ub4e4\uc5b4\uc788\ub294 \ud53c\uc5b4\ub9cc \uc5f0\uacb0 \ud655\ub9bd\uc774 \ud5c8\uc6a9\ub429\ub2c8\ub2e4.
+wizard.tracker.dht=\ubd84\uc0b0\ub428 (Vuze \ud074\ub77c\uc774\uc5b8\ud2b8 \uc804\uc6a9)
 MyTorrentsView.menu.advancedmenu=\uace0\uae09
 MyTorrentsView.menu.networks=\ub124\ud2b8\uc6cc\ud06c
-MyTorrentsView.menu.peersource=\ub3d9\ub8cc \uc18c\uc2a4
-ConfigView.section.sharing.permitdht=\ub354\ub4ec\uc774\ub97c \uc4f8 \uc218 \uc5c6\uc744 \ub54c \ubd84\uc0b0\ub41c \ub354\ub4ec\uae30\ub97c \ud5c8\uc6a9
-ConfigView.section.sharing.protocol=\uacf5\uc720\ub41c \uc790\uc6d0\ub4e4\uc758 \ud504\ub85c\ud1a0\ucf5c
-PeersView.Messaging=\ud1b5\uc2e0
-PeersView.Messaging.info=\uace0\uae09 \ud1b5\uc2e0 API\ub97c \uc9c0\uc6d0
-ConfigView.label.queue.newseedsmovetop=\uc0c8\ub85c \ub9c8\uce5c \ud1a0\ub7f0\ud2b8\ub4e4\uc744 \ubfcc\ub9ac\uae30 \ubaa9\ub85d\uc758 \uc55e\uc73c\ub85c \uc62e\uae40
-ConfigView.label.seeding.firstPriority.ignore.info=\uc774 \uaddc\uce59\ub4e4\uc744 \uc4f0\ub294 \uac83\uc774 \ub0b4\ub824\ubc1b\uae30\uac00 \ub05d\ub098\uc790\ub9c8\uc790 \ud1a0\ub7f0\ud2b8\ub97c\n\uba48\ucd94\uac8c \ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc8fc\uc758\ud558\uc138\uc694.
-ConfigView.label.seeding.firstPriority.ignore=\ub2e4\uc74c\uc758 \ud1a0\ub7f0\ud2b8\uc5d0 \uc704\uc758 \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uaddc\uce59\ub4e4\uc744 \ubb34\uc2dc:
-ConfigView.label.seeding.firstPriority.ignoreSPRatio=\uc528\uc557\uacfc \ub3d9\ub8cc \ube44\uac00 \ub2e4\uc74c\uc744 \ub118\uc740 \ud1a0\ub7f0\ud2b8\ub4e4
-ConfigView.label.seeding.firstPriority.ignore0Peer=0 \ub3d9\ub8cc\uc778 \ud1a0\ub7f0\ud2b8\ub4e4
+MyTorrentsView.menu.peersource=\ud53c\uc5b4 \ucd9c\ucc98
+ConfigView.section.sharing.permitdht=\ud2b8\ub798\ucee4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744 \uacbd\uc6b0 \ubd84\uc0b0 \ud2b8\ub798\ud0b9\uc744 \ud5c8\uc6a9
+ConfigView.section.sharing.protocol=\uace0\uc804\uc2dd \uacf5\uc720 \uc790\uc6d0\uc5d0 \ub300\ud55c \ud504\ub85c\ud1a0\ucf5c
+PeersView.Messaging=\uba54\uc2dc\uc9c0
+PeersView.Messaging.info=\uc5b4\ub5a4 \uba54\uc2dc\uc9c0 \uc2dc\uc2a4\ud15c\uc774 \uc0ac\uc6a9\ub418\uace0 \uc788\ub294\uc9c0\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4.
+ConfigView.label.queue.newseedsmovetop=\uc0c8\ub85c \uc644\ub8cc\ub41c \ud1a0\ub80c\ud2b8\ub294 \ubc30\ud3ec \ubaa9\ub85d\uc758 \uc55e\uc73c\ub85c \uc774\ub3d9
+ConfigView.label.seeding.firstPriority.ignore.info=\uc774 \uaddc\uce59\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c\uc11c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \ub05d\ub098\uc790\ub9c8\uc790 \ud1a0\ub80c\ud2b8\uac00\n\uc911\uc9c0\ub418\ub294 \uacb0\uacfc\ub97c \ucd08\ub798\ud560 \uc218 \uc788\uc74c\uc744 \uc8fc\uc758\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+ConfigView.label.seeding.firstPriority.ignore=\ub2e4\uc74c\uc5d0 \ub300\ud574\uc11c\ub294 \uc704\uc758 \uccab\ubc88\uc9f8 \uc6b0\uc120\uad8c \uaddc\uce59\uc744 \ubb34\uc2dc:
+ConfigView.label.seeding.firstPriority.ignoreSPRatio=\uc2dc\ub4dc \ub300 \ud53c\uc5b4 \ube44\uc728\uc774 \ub2e4\uc74c\uc744 \ub118\uc5b4\uc120 \ud1a0\ub80c\ud2b8
+ConfigView.label.seeding.firstPriority.ignore0Peer=0 \ud53c\uc5b4 \ud1a0\ub80c\ud2b8
 ConfigView.section.tracker.sendjavaversionandos=Java \ubc84\uc804\uacfc OS \uc774\ub984 \ubcf4\ub0b4\uae30
-MagnetPlugin.contextmenu.exporturi=Magnet URI\ub97c \ud074\ub9bd\ubcf4\ub4dc\ub85c \ubcf5\uc0ac
-ConfigView.section.plugins.dht=\ubd84\ud3ec\ub41c \ub370\uc774\ud130\ubca0\uc774\uc2a4
-dht.info=\uc774 \ucd94\uac00\uae30\ub2a5\uc740 \ub2e4\ub978 \uac83\ub4e4 \uc911\uc5d0\uc11c \ubd84\uc0b0\ub41c \ub354\ub4ec\uae30\ub97c \uc9c0\uc6d0\ud569\ub2c8\ub2e4. - \uc774\uac83\uc744 \uba48\ucd94\uba74 \ub0b4\ub824\ubc1b\uae30\ud558\ub294 \ub2a5\ub825\uc774 \uc904\uc5b4\ub4e4 \uac83\uc785\ub2c8\ub2e4.
-dht.enabled=\ubd84\ud3ec\ub41c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc791\ub3d9
-dht.portdefault=\uae30\ubcf8 \ud3ec\ud2b8 \uc500
-dht.port=\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 UDP \ud3ec\ud2b8
+MagnetPlugin.contextmenu.exporturi=\ub9c8\uadf8\ub137 URI\ub97c \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac
+ConfigView.section.plugins.dht=\ubd84\uc0b0 DB
+dht.info=\uc774 \ud50c\ub7ec\uadf8\uc778\uc740 \ubd84\uc0b0 \ud2b8\ub798\ud0b9\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4. \ube44\ud65c\uc131\ud654 \uc2dc \ub2e4\uc6b4\ub85c\ub4dc \uac00\ub2a5\uc131\uc744 \ub5a8\uc5b4\ub728\ub9bd\ub2c8\ub2e4.
+dht.enabled=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \ud65c\uc131\ud654
+dht.portdefault=\uae30\ubcf8 \ud3ec\ud2b8 \uc0ac\uc6a9
+dht.port=\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc6a9 UDP \ud3ec\ud2b8
 dht.execute.command=\uc9c4\ub2e8 \uba85\ub839
-dht.execute.info=\uba85\ub839\uc744 \uc2e4\ud589\ud558\ub824\uba74 \ub204\ub974\uc2ed\uc2dc\uc694
+dht.execute.info=\uba85\ub839\uc744 \uc2e4\ud589\ud558\ub824\uba74 \ub204\ub974\uae30
 dht.execute=\uc2e4\ud589
-dht.logging=\ud65c\ub3d9\uc758 \uae30\ub85d \uc791\ub3d9
-ConfigView.section.plugins.dhttracker=\ubd84\ud3ec\ub41c \ub354\ub4ec\uc774
-dhttracker.tracknormalwhenoffline=\ub354\ub4ec\uc774\ub97c \uc4f8 \uc218 \uc5c6\uc744 \ub54c \ubcf4\ud1b5 \ud1a0\ub7f0\ud2b8\ub4e4\uc744 \ub354\ub4ec\uae30\ub9cc \ud568
-ConfigView.section.file.nativedelete._mac=\ud30c\uc77c\ub4e4\uc744 \uc9c0\uc6b8 \ub54c \ud734\uc9c0\ud1b5 \uc4f0\uae30
-ConfigView.section.file.nativedelete._windows=\uc9c0\uc6b4 \ud30c\uc77c\ub4e4\uc744 \ud734\uc9c0\ud1b5\uc73c\ub85c \uc62e\uae30\uae30
+dht.logging=\ud65c\ub3d9 \ucd94\uc801 \ud65c\uc131\ud654
+ConfigView.section.plugins.dhttracker=\ubd84\uc0b0 \ud2b8\ub798\ucee4
+dhttracker.tracknormalwhenoffline=\ud2b8\ub798\ucee4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744 \ub54c \uc77c\ubc18 \ud1a0\ub80c\ud2b8 \ucd94\uc801\ub9cc \uc218\ud589
+ConfigView.section.file.nativedelete._mac=\ud30c\uc77c\uc744 \uc0ad\uc81c\ud560 \ub54c \ud734\uc9c0\ud1b5 \uc0ac\uc6a9
+ConfigView.section.file.nativedelete._windows=\ud30c\uc77c\uc744 \uc0ad\uc81c\ud560 \ub54c \ud734\uc9c0\ud1b5 \uc0ac\uc6a9
 ConfigView.section.logging.generatediagnostics=\uc0dd\uc131
-ConfigView.section.logging.statsinfo=\uc0c1\ud0dc \uc815\ubcf4 \ub9cc\ub4e4\uae30
-ConfigView.section.logging.generatediagnostics.info=\uc124\uc815\ub418\uc5c8\uc73c\uba74, \uc9c4\ub2e8 \uc815\ubcf4\ub97c \uc0dd\uc131\ud558\uace0 \ud074\ub9bd\ubcf4\ub4dc\uc640 \uae30\ub85d \ud30c\uc77c\ub85c \ubcf5\uc0ac\ud569\ub2c8\ub2e4
-ConfigView.section.sharing.privatetorrent=\uac1c\uc778\uc758 \ud1a0\ub7f0\ud2b8 - \ub354\ub4ec\uc774\uc5d0\uc11c \ubc1b\uc544\ub4e4\uc778 \ub3d9\ub8cc\ub4e4\ub9cc
-MainWindow.menu.tools.nattest=NAT / \ubc29\ud654\ubcbd \uac80\uc0ac(&N)
+ConfigView.section.logging.netinfo=\ub124\ud2b8\uc6cc\ud06c \uc815\ubcf4 \uc0dd\uc131
+ConfigView.section.logging.statsinfo=\ud1b5\uacc4 \uc815\ubcf4 \uc0dd\uc131
+ConfigView.section.logging.generatediagnostics.info=\uc124\uc815\ud55c \uacbd\uc6b0, \uc9c4\ub2e8 \uc815\ubcf4\ub97c \uc0dd\uc131\ud574\uc11c \ud074\ub9bd\ubcf4\ub4dc\uc640 \ub85c\uadf8 \ud30c\uc77c\uc5d0 \ubcf5\uc0ac\ud569\ub2c8\ub2e4.
+ConfigView.section.sharing.privatetorrent=\ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8 - \ud2b8\ub798\ucee4\ub97c \ud1b5\ud574 \uc628 \ud53c\uc5b4\ub9cc
+MainWindow.menu.tools.nattest=NAT / \ubc29\ud654\ubcbd \ud14c\uc2a4\ud2b8(&N)
 Button.apply=\uc801\uc6a9
 Button.close=\ub2eb\uae30
-window.welcome.title=Vuze %1\uc5d0 \uc5b4\uc11c \uc624\uc2ed\uc2dc\uc694.
+window.welcome.title=Vuze %1 \uc5d0 \uc624\uc2e0 \uac83\uc744 \ud658\uc601\ud569\ub2c8\ub2e4
 #file can be a URL or a path in the jar
-MainWindow.menu.help.releasenotes=\ubc1c\ud45c \uae30\ub85d
-dht.reseed.label=\ubcf4\ud1b5 \ubd84\ud3ec\ub41c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ub2e4\uc2dc \ubfcc\ub9ac\uae30\ub294 \ud544\uc694\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uadf8\ub7ec\ub098 \uc811\ucd09\uc758 \uc218\uac00 \ub0ae\uc73c\uba74 \ub2e4\uc2dc \uc644\uc804\ud558\uac8c \ud558\ub294 \ub370\uc5d0 \uc774\uac83\uc744 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uc5f0\uacb0\ub41c \ub3d9\ub8cc\ub4e4\uc744 \uc2a4\uc2a4\ub85c \ub04a\uc73c\ub824\uba74 \ube44\uc6cc \ub450\uac70\ub0 [...]
-dht.reseed.group=\ub2e4\uc2dc \ubfcc\ub9ac\uae30
+MainWindow.menu.help.releasenotes=\ub9b4\ub9ac\uc988 \ub178\ud2b8
+dht.reseed.label=\uc77c\ubc18\uc801\uc73c\ub85c \ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \ub2e4\uc2dc \ubc30\ud3ec\ud558\ub294 \uac83\uc740 \ud544\uc694\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uadf8\ub7ec\ub098 \uc811\ucd09 \uc218\uac00 \uc801\uc740 \uacbd\uc6b0, \ubb34\uacb0\uc131\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \uc774 \uc124\uc815\uc774 \uc0ac\uc6a9\ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\ube48\uce78\uc73c\ub85c \ub450\uba74 \uc5f0\uacb0\ub41c \ud53c\uc5b4\ub [...]
+dht.reseed.group=\ub2e4\uc2dc \ubc30\ud3ec
 dht.reseed.ip=IP \uc8fc\uc18c
 dht.reseed.port=\ud3ec\ud2b8
-dht.reseed=\ub2e4\uc2dc \ubfcc\ub9ac\uae30
-dht.reseed.info=\ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \ub2e4\uc2dc \ubfcc\ub9ac\uae30
+dht.reseed=\ub2e4\uc2dc \ubc30\ud3ec
+dht.reseed.info=\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub2e4\uc2dc \ubc30\ud3ec
 dht.diagnostics.group=\uc9c4\ub2e8
-DHTView.title.full=\ubd84\ud3ec\ub41c \ub370\uc774\ud130\ubca0\uc774\uc2a4
-DHTView.title.fullcvs=\ubd84\ud3ec\ub41c CVS \ub370\uc774\ud130\ubca0\uc774\uc2a4
+DHTView.title.full=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4
+DHTView.title.fullcvs=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4 CVS
 DHTView.general.title=\uc77c\ubc18
-DHTView.general.uptime=\uc62c\ub9ac\uae30 \uc2dc\uac04:
+DHTView.general.uptime=\uc5c5\uc2dc\uac04:
 DHTView.general.users=\uc0ac\uc6a9\uc790:
 DHTView.general.nodes=\ub178\ub4dc:
-DHTView.general.leaves=\ud5c8\uac00:
+DHTView.general.leaves=\ub5a0\ub0a8:
 DHTView.general.contacts=\uc811\ucd09:
-DHTView.general.replacements=\ubc18\ud658:
-DHTView.general.live=\uc720\ud6a8:
+DHTView.general.replacements=\ub300\uccb4:
+DHTView.general.live=\uc0b6:
 DHTView.general.unknown=\uc54c \uc218 \uc5c6\uc74c:
 DHTView.general.dying=\uc8fd\uc74c:
-DHTView.transport.title=\uc138\ubd80 \uc804\uc1a1
+DHTView.transport.title=\uc804\uc1a1 \uc138\ubd80\uc0ac\ud56d
 DHTView.transport.packets=\ud328\ud0b7
-DHTView.transport.bytes=\ubc14\uc774\ud2b8
 DHTView.transport.received=\ubc1b\uc74c
 DHTView.transport.sent=\ubcf4\ub0c4
-DHTView.transport.in=\ub4e4\uc5b4\uc624\uae30:
-DHTView.transport.out=\ub098\uac00\uae30:
-DHTView.operations.title=\uc138\ubd80 \uc791\ub3d9
+DHTView.transport.in=\uc778 :
+DHTView.transport.out=\uc544\uc6c3 :
+DHTView.operations.title=\uc791\uc5c5 \uc138\ubd80\uc0ac\ud56d
 DHTView.operations.sent=\ubcf4\ub0c4
-DHTView.operations.ok=\uc88b\uc74c
+DHTView.operations.ok=\uc815\uc0c1
 DHTView.operations.failed=\uc2e4\ud328
 DHTView.operations.received=\ubc1b\uc74c
 DHTView.operations.ping=\ud551
 DHTView.operations.findNode=\ub178\ub4dc \ucc3e\uae30
-DHTView.operations.findValue=\uc720\uc6a9\uc131 \ucc3e\uae30
+DHTView.operations.findValue=\uac12 \ucc3e\uae30
 DHTView.operations.store=\uc800\uc7a5
 DHTView.activity.title=\ud65c\ub3d9
 DHTView.activity.status=\uc0c1\ud0dc
-DHTView.activity.status.true=\ub300\uae30
-DHTView.activity.status.false=\ub3cc\uace0 \uc788\uc74c
-DHTView.activity.type=\uc885\ub958
-DHTView.activity.type.1=\ub0b4\ubd80 \uc5bb\uae30
-DHTView.activity.type.2=\uc678\ubd80 \uc5bb\uae30
-DHTView.activity.type.3=\ub0b4\ubd80 \uc8fc\uae30
-DHTView.activity.type.4=\uc678\ubd80 \uc8fc\uae30
-DHTView.activity.target=\ubaa9\ud45c
-DHTView.activity.details=\uc124\uba85
+DHTView.activity.status.true=\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac10
+DHTView.activity.status.false=\uc2e4\ud589 \uc911
+DHTView.activity.type=\uc720\ud615
+DHTView.activity.type.1=\ub0b4\ubd80 GET
+DHTView.activity.type.2=\uc678\ubd80 GET
+DHTView.activity.type.3=\ub0b4\ubd80 PUT
+DHTView.activity.type.4=\uc678\ubd80 PUT
+DHTView.activity.target=\ud45c\uc801
+DHTView.activity.details=\uc138\ubd80\uc0ac\ud56d
 DHTView.db.title=\ub370\uc774\ud130\ubca0\uc774\uc2a4
-DHTView.db.keys=\uc694\uc18c
-DHTView.db.values=\uc720\uc6a9\uc131
+DHTView.db.keys=\ud0a4
+DHTView.db.values=\uac12
 DHTView.db.local=\ub85c\uceec
 DHTView.db.direct=\uc9c1\uc811
 DHTView.db.indirect=\uac04\uc811
-DHTView.db.divfreq=\ub3c4\uc218 \ubd84\ud560
-DHTView.db.divsize=\ud06c\uae30 \ubd84\ud560
-MainWindow.dht.status.tooltip=\ubd84\ud3ec\ub41c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ub3cc\uc544\uac00\uba74 \uc774\uac83\uc740 \uc9c0\uae08 \uc628\ub77c\uc778 \uc0ac\uc6a9\uc790\uc758 \uc608\uc0c1 \uc218\ub97c \ubcf4\uc785\ub2c8\ub2e4.
-MainWindow.dht.status.disabled=\uc791\ub3d9\ud558\uc9c0 \uc54a\uc74c
-MainWindow.dht.status.failed=\uc2e4\ud328\ud568
-MainWindow.dht.status.initializing=\uc900\ube44\ud558\uace0 \uc788\uc74c
+DHTView.db.divfreq=\ube48\ub3c4 \uad6c\ud68d
+DHTView.db.divsize=\ud06c\uae30 \uad6c\ud68d
+MainWindow.dht.status.tooltip=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ub3d9\uc791\ud558\ub294 \uacbd\uc6b0, \uc774 \uc218\uce58\ub294 \ud604\uc7ac \uc5f0\uacb0\ub41c \uc0ac\uc6a9\uc790 \uc218\ub97c \ucd94\uc815\ud574\uc11c \ubcf4\uc5ec \uc8fc\ub294 \uac83\uc785\ub2c8\ub2e4.
+MainWindow.dht.status.disabled=DHT \ube44\ud65c\uc131
+MainWindow.dht.status.failed=DHT \uc2e4\ud328
+MainWindow.dht.status.initializing=DHT \ucd08\uae30\ud654 \uc911
 MainWindow.dht.status.users=%1 \uc0ac\uc6a9\uc790
-MainWindow.dht.status.unreachable=DHT \ubc29\ud654\ubcbd
-MyTorrentsView.menu.setUpSpeed=\uc62c\ub9ac\uae30 \uc18d\ub3c4 \uc815\ud558\uae30
-MyTorrentsView.menu.setDownSpeed=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 \uc815\ud558\uae30
-ConfigView.section.tracker.client.showwarnings=\ub354\ub4ec\uc774\ub4e4\uc5d0\uac8c\uc11c \ubcf4\uace0\ub41c \uacbd\uace0 \uba54\uc2dc\uc9c0\ub4e4 \ubcf4\uc774\uae30
-dht.advanced=\uace0\uae09 \uc124\uc815 \uc791\ub3d9
+MainWindow.dht.status.unreachable=DHT \ubc29\ud654\ubcbd\uc73c\ub85c \ub9c9\ud798
+MainWindow.dht.status.unreachabletooltip=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 UDP \ud3ec\ud2b8 \ub9f5\ud551 (NAT/\ubc29\ud654\ubcbd)\uc5d0 \ubb38\uc81c\uac00 \uc788\ub294 \uac83\uc73c\ub85c \ubcf4\uc785\ub2c8\ub2e4.
+MyTorrentsView.menu.setUpSpeed=\uc5c5 \uc18d\ub3c4 \uc124\uc815
+MyTorrentsView.menu.setDownSpeed=\ub2e4\uc6b4 \uc18d\ub3c4 \uc124\uc815
+ConfigView.section.tracker.client.showwarnings=\ud2b8\ub798\ucee4\uc5d0 \uc758\ud574 \ubcf4\uace0\ub41c \uacbd\uace0 \uba54\uc2dc\uc9c0\ub97c \ubcf4\uc5ec\uc8fc\uae30
+dht.advanced=\uace0\uae09 \uc124\uc815 \ud65c\uc131\ud654
 dht.advanced.group=\uace0\uae09 \uc124\uc815
-dht.advanced.label=\ubc29\ubc95\uc744 \ub611\ubc14\ub85c \uc54c \ub54c\ub9cc \uc774 \uac12\ub4e4\uc744 \uace0\uce58\uc2ed\uc2dc\uc694
-dht.override.ip=\uc678\ubd80 IP \uc8fc\uc18c \ubb34\uc2dc
-ConfigView.section.logging.loggerenable=\uae30\ub85d \ub0a8\uae30\uae30 \uc791\ub3d9
-ConfigView.section.ipfilter.blockbanning=\ud55c \ud1a0\ub9c9\uc5d0\uc11c \uc801\uc5b4\ub3c4 \uba87 \uac1c \uc815\ub3c4\ub97c \ubab0\uc544\ub0b4\uba74 256 \uac1c \uc8fc\uc18c\uc758 \ud55c \ud1a0\ub9c9\uc744 \ubab0\uc544\ub0c5\ub2c8\ub2e4
+dht.advanced.label=\uc0ac\uc6a9\uc790\uac00 \uc815\ud655\ud788 \ubb34\uc5c7\uc744 \ud558\uace0 \uc788\ub294\uc9c0 \uc54c\uace0\uc788\ub294 \uacbd\uc6b0\uc5d0\ub9cc \uc774 \uac12\uc744 \ubcc0\uacbd\ud558\uc2ed\uc2dc\uc624
+dht.override.ip=\uc678\ubd80 IP \uc8fc\uc18c \uc6b0\uc120\uc801\uc6a9
+ConfigView.section.logging.loggerenable=\ub85c\uae45 \ud65c\uc131\ud654
+ConfigView.section.ipfilter.blockbanning=\ub2e4\uc74c\uc5d0 \uc815\uc758\ub41c \uc774\uc0c1 \uae08\uc9c0\ub418\uba74 256\uac1c\uc758 \uc8fc\uc18c \ube14\ub85d \uc790\uccb4\ub97c \uae08\uc9c0
 MyTrackerView.passive=\uc218\ub3d9
-TableColumn.header.swarm_average_speed=\ub5bc \ud3c9\uade0 \uc18d\ub3c4
-TableColumn.header.swarm_average_speed.info=\ub5bc\uc5d0 \uc788\ub294 \ub3d9\ub8cc\ub4e4\uc758 \ud3c9\uade0 \uc18d\ub3c4
-TableColumn.header.comment=\ub367\ub9d0
-TableColumn.header.comment.info=\ub0b4\ub824\ubc1b\uc740 \uc790\ub8cc\uc758 \uc0ac\uc6a9\uc790 \ub367\ub9d0
-TableColumn.header.commenticon=\ub367\ub9d0
-TableColumn.header.commenticon.info=\uc790\ub8cc\uc5d0 \uc0ac\uc6a9\uc790 \uc785\ub825 \ub367\ub9d0\uc774 \uc788\uc744\uc2dc \uc544\uc774\ucf58 \ud45c\uc2dc
+TableColumn.header.swarm_average_speed=\uc2a4\uc6dc \ud3c9\uade0 \uc18d\ub3c4
+TableColumn.header.swarm_average_speed.info=\uc2a4\uc6dc \uc548\uc5d0 \ub4e4\uc5b4\uc788\ub294 \ud53c\uc5b4\uc758 \ud3c9\uade0 \uc18d\ub3c4\uc785\ub2c8\ub2e4.
+TableColumn.header.comment=\uc8fc\uc11d
+TableColumn.header.comment.info=\ub2e4\uc6b4\ub85c\ub4dc\uc5d0 \ub300\ud55c \uc0ac\uc6a9\uc790 \uc815\uc758 \uc8fc\uc11d\uc785\ub2c8\ub2e4.
+TableColumn.header.commenticon=\uc8fc\uc11d \uc544\uc774\ucf58
+TableColumn.header.commenticon.info=\uc790\ub8cc\uc5d0 \uc0ac\uc6a9\uc790 \uc815\uc758 \uc8fc\uc11d\uc774 \uc788\uc73c\uba74 \uc544\uc774\ucf58\uc744 \ud45c\uc2dc\ud569\ub2c8\ub2e4.
 MyTrackerView.category=\ubd84\ub958
-MainWindow.menu.file.open.torrentfortracking=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c... (\ub354\ub4ec\uae30\ub9cc)
-VivaldiView.title.full=\ube44\ubc1c\ub514 \ubcf4\uae30
-VivaldiView.title.fullcvs=\ube44\ubc1c\ub514 CVS
-VivaldiView.title.full_v6=\ube44\ubc1c\ub514 IPv6
-MyTrackerView.date_added=\ucd94\uac00
-ConfigView.label.playfilespeech=\ud30c\uc77c\uc774 \ub05d\ub9c8\uccd0 \uc84c\uc73c\uba74 \ub9d0\ud574\uc8fc\uae30
-ConfigView.label.playfilespeech.info=\ub9d0\ud574\uc8fc\uae30 \uae30\ub2a5\uc740 \uc601\uc5b4\uc0b0\ud0dc\uc5d0\uc11c \uc798 \uc791\ub3d9\ud569\ub2c8\ub2e4.
-ConfigView.label.backupconfigfiles=\ubcf5\uad6c\ub97c \uc704\ud574 \uc124\uc815\ud30c\uc77c \ubc31\uc5c5 
+MainWindow.menu.file.open.torrentfortracking=\ud1a0\ub80c\ud2b8 \ud30c\uc77c... (\ud2b8\ub798\ucee4 \uc804\uc6a9)
+MyTrackerView.date_added=\ucd94\uac00\ub428
+ConfigView.section.tracker.portbackup=\ubc31\uc5c5 \ud3ec\ud2b8 (';'\ub85c \ubd84\ub9ac)
+ConfigView.label.playfilespeech=\ud30c\uc77c\uc774 \ub05d\ub098\uba74 \ub9d0\ud558\uae30
+ConfigView.label.playfilespeech.info=\ub9d0\ud558\uae30 \uc11c\ube44\uc2a4\ub294 \ud604\uc7ac \uc601\uc5b4\ub85c \uac00\uc7a5 \uc798 \ub3d9\uc791\ud568
+ConfigView.label.playfilefinished=\ud30c\uc77c\uc774 \ub05d\ub098\uba74 \uc0ac\uc6b4\ub4dc \uc7ac\uc0dd
+ConfigView.label.backupconfigfiles=\ubcf5\uad6c\uc6a9 \uc124\uc815 \ud30c\uc77c \ubc31\uc5c5
+ConfigView.section.tracker.client.scrapesingleonly=\ud2b8\ub798\ucee4 \ub2e8\uc704 \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1\uc744 \ube44\ud65c\uc131 (\uc774\ub807\uac8c \ud558\uba74 \ud2b8\ub798\ucee4\uac00 'URL\uc774 \ub108\ubb34 \uae40' (414) \uc624\ub958\ub97c \ubcf4\uace0\ud558\ub294 \uac83\uc744 \ubc29\uc9c0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4)
+dht.ipfilter.log=IP \ud544\ud130 \uc704\ubc18 \ub85c\uadf8
+ConfigView.label.seeding.addForSeedingDLCopyCount='\ubc30\ud3ec\ub97c \uc704\ud574 \ucd94\uac00'\ud55c \ub2e4\uc6b4\ub85c\ub4dc\ub294 \ub2e4\uc74c \uc218\ub7c9\uc758 \ubcf5\uc0ac\ubcf8\uc744 \ub2e4\uc6b4\ub85c\ub4dc\ud55c \uac83\uc73c\ub85c \uac04\uc8fc\ud560 \uac83
 ActivityView.legend.limit=\ud55c\uacc4 \ube44\uc728
 ActivityView.legend.achieved=\ub2ec\uc131 \ube44\uc728
 ActivityView.legend.overhead=\uc624\ubc84\ud5e4\ub4dc \ube44\uc728
 ActivityView.legend.peeraverage=\ud3c9\uade0
-ActivityView.legend.swarmaverage=\ub5bc \ud3c9\uade0
-ActivityView.legend.trimmed=\uc18c\uc218\uc810\uc774\ud558 \uc0dd\ub7b5
-MyTorrentsView.menu.movemenu=\ud30c\uc77c \uc62e\uae30\uae30
-MyTorrentsView.menu.movetorrent=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c \uc62e\uae30\uae30...
+ActivityView.legend.swarmaverage=\uc2a4\uc6dc \ud3c9\uade0
+ActivityView.legend.trimmed=\uc0dd\ub7b5\ub428 (\uc18c\uc218\uc810)
+MyTorrentsView.menu.movemenu=\ud30c\uc77c \uc774\ub3d9
+MyTorrentsView.menu.movedata=\ub370\uc774\ud130 \ud30c\uc77c \uc774\ub3d9...
+MyTorrentsView.menu.movetorrent=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \uc774\ub3d9...
+MyTorrentsView.menu.movedata.dialog=\uc0c8 \uc704\uce58 \uc120\ud0dd
 DHTView.operations.data=\ub370\uc774\ud130
-DHTView.general.reachable=\ub3c4\ub2ec\uc728:
-DHTView.general.rendezvous=\ub791\ub370\ubdf0:
+DHTView.general.reachable=\ub3c4\ub2ec\uc131:
+DHTView.general.rendezvous=\ub9cc\ub0a8:
+ConfigView.label.queue.maxactivetorrentswhenseeding=\ubc30\ud3ec\ub9cc \ud560 \ub54c \ucd5c\ub300\uac12 [0: \ubb34\uc81c\ud55c]
 Views.plugins.IRC.title=IRC - \uc628\ub77c\uc778 \uae30\uc220\uc9c0\uc6d0
-Formats.units.persec=/\ucd08
-Formats.units.TiB=\ud14c\ub77c\ubc14\uc774\ud2b8
-Formats.units.Tibit=\ud14c\ub77c\ube44\ud2b8
-Formats.units.TB=\ud14c\ub77c\ubc14\uc774\ud2b8
-Formats.units.Tbit=\ud14c\ub77c\ube44\ud2b8
-Formats.units.GiB=\uae30\uac00\ubc14\uc774\ud2b8
-Formats.units.Gibit=\uae30\uac00\ube44\ud2b8
-Formats.units.GB=\uae30\uac00\ubc14\uc774\ud2b8
-Formats.units.Gbit=\uae30\uac00\ube44\ud2b8
-Formats.units.MiB=\uba54\uac00\ubc14\uc774\ud2b8
-Formats.units.Mibit=\uba54\uac00\ube44\ud2b8
-Formats.units.MB=\uba54\uac00\ubc14\uc774\ud2b8
-Formats.units.Mbit=\uba54\uac00\ube44\ud2b8
-Formats.units.KiB=\ud0ac\ub85c\ube44\ud2b8
-Formats.units.Kibit=\ud0ac\ub85c\ube44\ud2b8
-Formats.units.kB=\ud0ac\ub85c\ubc14\uc774\ud2b8
-Formats.units.KB=\ud0ac\ub85c\ubc14\uc774\ud2b8
-Formats.units.kbit=\ud0ac\ub85c\ube44\ud2b8
-Formats.units.B=\ubc14\uc774\ud2b8
-Formats.units.bit=\ube44\ud2b8
-Formats.units.alot=\ub9e4\uc6b0 \ub9ce\uc2b5\ub2c8\ub2e4 !!!
-FilesView.menu.rename=\uc774\ub984\ubc14\uafb8\uae30 \ud639\uc740 \ubaa9\ud45c\uc7ac\uc124\uc815
-FilesView.menu.rename_only=\ube60\ub978 \uc774\ub984\ubc14\uafb8\uae30
-FilesView.menu.retarget=\ud30c\uc77c \uc62e\uae30\uae30
-FilesView.rename.choose.path=\uc0c8 \ud30c\uc77c\uc774\ub098 \uae30\uc874 \ud30c\uc77c \uc120\ud0dd
-FilesView.rename.choose.path.dir=\uc0c8 \ud3f4\ub354\ub098 \uae30\uc874 \ud3f4\ub354 \uc120\ud0dd
-FilesView.rename.confirm.delete.title=\uc0ad\uc81c \ud655\uc778
-FilesView.rename.confirm.delete.text='%1'\uc758 \uc6d0\ubcf8\ud30c\uc77c\uc744 \uc0ad\uc81c\ud558\ub294\uac83\uc744 \ud655\uc778\ud574 \uc8fc\uc2ed\uc2dc\uc624.
-FilesView.rename.filename.title=\uc774\ub984 \ubc14\uafb8\uae30
-FilesView.rename.filename.text=\ud30c\uc77c\uc758 \uc0c8\uc774\ub984 \uc120\ud0dd
-ConfigView.higher.mode.available=\uace0\uae09 \uc0ac\uc6a9\uc790\ub97c \uc704\ud55c \uc120\ud0dd\uc0ac\ud56d \ud45c\uc2dc
+Formats.units.alot=\ub9ce\uc544\uc694 !!!
+ConfigView.section.ipfilter.persistblocking=\ub2e4\uc2dc \uc2dc\uc791 \uc2dc \ucc28\ub2e8\ub41c IP \uc138\ubd80\uc0ac\ud56d \uc800\uc7a5
+FilesView.menu.rename=\uc774\ub984 \ubc14\uafb8\uae30 \ub610\ub294 \ud45c\uc801 \ub2e4\uc2dc \uc124\uc815
+FilesView.menu.rename_only=\ube60\ub978 \uc774\ub984 \ubc14\uafb8\uae30
+FilesView.menu.retarget=\ud30c\uc77c \uc774\ub3d9
+FilesView.rename.choose.path=\uc0c8 \ud30c\uc77c \ub610\ub294 \uc874\uc7ac\ud558\ub294 \ud30c\uc77c \uc120\ud0dd
+FilesView.rename.choose.path.dir=\uc0c8 \ud30c\uc77c \ub610\ub294 \uc874\uc7ac\ud558\ub294 \ub514\ub809\ud130\ub9ac \uc120\ud0dd
+FilesView.rename.confirm.delete.title=\uc0ad\uc81c \uc2b9\uc778
+FilesView.rename.confirm.delete.text='%1' \uc6d0\ubcf8 \ud30c\uc77c\uc744 \uc0ad\uc81c \uc2b9\uc778
+FilesView.rename.filename.title=\ud30c\uc77c \uc774\ub984 \ubc14\uafb8\uae30
+FilesView.rename.filename.text=\uc0c8 \ud30c\uc77c \uc774\ub984 \uc120\ud0dd
+ConfigView.higher.mode.available=\ub098\uba38\uc9c0 \uc635\uc158\uc740 \ub354 \ub192\uc740 \uc218\uc900\uc758 \uc0ac\uc6a9\uc790 \ubaa8\ub4dc\uc5d0\uc11c \uc0ac\uc6a9 \uac00\ub2a5
 ConfigView.section.mode=\ubaa8\ub4dc
-ConfigView.section.mode.beginner=\ucd08\uc2ec\uc790
-ConfigView.section.mode.beginner.wiki.definitions=\ube44\ud2b8 \ud1a0\ub7f0\ud2b8 \uc0ac\uc6a9 \ub2e8\uc5b4
-ConfigView.section.mode.intermediate=\uc911\uae09\uc790
+ConfigView.section.mode.title=\uc0ac\uc6a9\uc790 \ub2a5\uc219\ub3c4
+ConfigView.section.mode.beginner=\ucd08\ubcf4
+ConfigView.section.mode.beginner.wiki.definitions=BitTorrent \uc5b4\ud718
+ConfigView.section.mode.intermediate=\uc911\uae09
 ConfigView.section.mode.intermediate.wiki.host=\ud30c\uc77c \ud638\uc2a4\ud305
 ConfigView.section.mode.intermediate.wiki.publish=\ud30c\uc77c \ubc30\ud3ec
 ConfigView.section.mode.advanced=\uace0\uae09
-ConfigView.section.mode.advanced.wiki.main=\uc704\ud0a4 \ub300\ubb38
+ConfigView.section.mode.advanced.wiki.main=Wiki \uba54\uc778 \ud398\uc774\uc9c0
+ConfigView.section.mode.beginner.text=\ud1a0\ub80c\ud2b8\ub97c \ub2e4\uc6b4\ub85c\ub4dc \ud558\ub294\ub370 \ud544\uc694\ud55c \ubaa8\ub4e0 \uac83.\n\ud1a0\ub80c\ud2b8 \uad00\ub9ac\uac00 \ub2f9\uc2e0\uc774 \ud544\uc694\ud55c \ubaa8\ub4e0 \uac83\uc774\ub77c\uba74 \uc774 \ubaa8\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.mode.intermediate.text=\ud2b8\ub798\ucee4 \uae30\ub2a5\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uc790\uc2e0\uc758 \ud2b8\ub798\ucee4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4 \ud30c\uc77c\uc744 \ud638\uc2a4\ud305/\ubc30\ud3ec\ud558\uace0\uc790 \ud55c\ub2e4\uba74 \uc774 \ubaa8\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.mode.advanced.text=\ub124\ud2b8\uc6cc\ud06c \uc124\uc815\uc5d0 \uc811\uadfc\ud569\ub2c8\ub2e4.\nMTU \ub610\ub294 \ube44\ucc28\ub2e8 I/O \ub4f1\uc774 \ubb34\uc5c7\uc778\uc9c0 \uc544\ub294 \uacbd\uc6b0 \uc774 \ubaa8\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.
 Files.column.storagetype=\uc800\uc7a5\uc18c \uc720\ud615
 Files.column.fileext=\uc720\ud615
-MessageBoxWindow.rememberdecision=\uc120\ud0dd\ub0b4\uc6a9\uc744 \uae30\uc5b5\ud574 \ub461\ub2c8\ub2e4.
-configureWizard.welcome.usermodes=\ub3c4\uad6c > \uc120\ud0dd\uc0ac\ud56d\uc5d0\uc11c \uc0ac\uc6a9\uc790\uc758 \uc218\uc900\uc5d0 \uc801\ub2f9\ud55c \ub2e8\uacc4\ub85c \uc124\uc815\ud558\uba74 \ud45c\uc2dc\ub418\ub294 \uc815\ubcf4\uc758 \uc591\uc744 \uc870\uc808 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-diagnostics.log_found=Vuze\uac00 \uae54\ub054\ud558\uac8c \ub05d\ub098\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uc9c4\ub2e8\uc5d0 \ub3c4\uc6c0\uc774 \ub418\ub294 \ub85c\uadf8 \ud30c\uc77c\ub4e4\uc5d0\uc11c %1\uc744 \uac80\uc0ac\ud558\uace0 \ud504\ub85c\uadf8\ub7a8 \uc624\ub958 \ub54c\ubb38\uc774\uba74 Vuze \ud300\uc5d0\uac8c \uc804\ud560 \uac83\uc744 \uc0dd\uac01\ud558\uc2ed\uc2dc\uc694.
-ManagerItem.paused=\uc7a0\uc2dc \uba48\ucda4
-Utils.link.visit=\ubc29\ubb38\ud574 \uc8fc\uc138\uc694
+FileItem.storage.linear=\uc120\ud615
+FileItem.storage.compact=\ucf64\ud329\ud2b8
+MessageBoxWindow.rememberdecision=\uacb0\uc815 \uc0ac\ud56d\uc744 \uae30\uc5b5
+ConfigView.section.interface.cleardecisions=\uae30\uc5b5\ub41c \ub300\ud654\uc0c1\uc790 \uacb0\uc815 \uc9c0\uc6b0\uae30
+ConfigView.section.interface.cleardecisionsbutton=\uc9c0\uc6b0\uae30
+ConfigView.section.interface.cleartrackers=\uae30\uc5b5\ub41c \ud2b8\ub798\ucee4 \uc9c0\uc6b0\uae30
+ConfigView.section.interface.cleartrackersbutton=\uc9c0\uc6b0\uae30
+ConfigView.section.interface.clearsavepaths=\uae30\uc5b5\ub41c \uc800\uc7a5 \uacbd\ub85c \uc9c0\uc6b0\uae30
+ConfigView.section.interface.clearsavepathsbutton=\uc9c0\uc6b0\uae30
+configureWizard.welcome.usermodes=\uc774 \uc0ac\uc6a9\uc790 \ub2a5\uc219\ub3c4 \uc124\uc815\uc740 \ub3c4\uad6c\u2192\uc635\uc158\uc5d0 \ud45c\uc2dc\ub418\ub294 \uc635\uc158\uc758 \uc218\uc900\uc744 \uacb0\uc815\ud569\ub2c8\ub2e4. \uc801\uc808\ud788 \uc124\uc815\ud558\uba74 \uc0ac\uc6a9\uc790\uac00 \uc6d0\ud558\ub294 \uba54\ub274\ub9cc \ud45c\uc2dc \ub418\ub3c4\ub85d \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+FilesView.skip.confirm.delete.text='%1' \ud30c\uc77c\uc758 \ubd88\ud544\uc694\ud55c \ubd80\ubd84\uc744 \uc81c\uac70\ud574\uc11c \uacf5\uac04\uc744 \ud655\ubcf4\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+FilesView.rename.failed.title=\uc774\ub984 \ubc14\uafb8\uae30/\ud45c\uc801 \ub2e4\uc2dc \uc124\uc815 \uc2e4\ud328
+FilesView.rename.failed.text=\uc791\uc5c5 \uc2e4\ud328, \uc798\ubabb\ub41c \ud45c\uc801\uc744 \uc120\ud0dd\ud588\uae30 \ub54c\ubb38\uc77c \uc218 \uc788\uc74c
+diagnostics.log_found=Vuze\uac00 \uc81c\ub300\ub85c \uc885\ub8cc\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. <A HREF="%1">\uc9c4\ub2e8 \ub85c\uadf8 \ud30c\uc77c</A>\uc744 \uc0b4\ud3b4\ubcf4\uc2dc\uae38 \ubc14\ub78d\ub2c8\ub2e4. \uadf8\ub9ac\uace0 \ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub294 Wiki <A HREF="http://wiki.vuze.com/w/Vuze_disappears">Vuze Disappears</A> \ud56d\ubaa9\uc744 \ucc38\uace0\ubc14\ub78d\ub2c8\ub2e4.
+ManagerItem.paused=\uc77c\uc2dc\uc815\uc9c0
+Utils.link.visit=\ubc29\ubb38\ud574\uc8fc\uc2ed\uc2dc\uc624
+ConfigView.section.connection.serverport.wiki=\uc120\ud638 \ud3ec\ud2b8 \uc120\ud0dd
 ConfigView.section.transfer.speeds.wiki=\uad8c\uc7a5\ud558\ub294 \uc18d\ub3c4 \uc124\uc815
 installPluginsWizard.installMode.info.title=\uc815\ubcf4
-Views.plugins.Distributed.DB.title=\ubc30\ud3ec DB
-Views.plugins.Distributed.Tracker.title=\ubc30\ud3ec \ub354\ub4ec\uc774
-Views.plugins.Plugin.Update.title=\ucd94\uac00\uae30\ub2a5 \uc5c5\ub370\uc774\ud2b8
-Views.plugins.UPnP.title.tooltip=\uc720\ub2c8\ubc84\uc15c \ud504\ub7ec\uadf8 \uc564 \ud50c\ub808\uc774
-MainWindow.nat.status.unknown=\uacf5\uc720\uae30
-MainWindow.nat.status.tooltip.unknown=\ubc29\ud654\ubcbd/\uacf5\uc720\uae30 \uc811\uadfc\uc5ec\ubd80 \uc0c1\ud0dc\ub97c \uc54c\uc218 \uc5c6\uc74c (TCP)
-MainWindow.nat.status.ok=\uacf5\uc720\uae30 OK
-MainWindow.nat.status.tooltip.ok=\uc811\uadfc\uc5ec\ubd80 OK (TCP)
-MainWindow.nat.status.probok=\uacf5\uc720\uae30 OK?
-MainWindow.nat.status.tooltip.probok=\uc811\uadfc\uc740 \uac00\ub2a5\ud558\ub098 \uc0c8\ub86d\uac8c \ub4e4\uc5b4\uc624\ub294 TCP\uc5f0\uacb0\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.
-MainWindow.nat.status.bad=\ubc29\ud654\ubcbd
-MainWindow.nat.status.tooltip.bad=\ubc29\ud654\ubcbd/\uacf5\uc720\uae30 (TCP)\uc5d0 \uc811\uadfc\ud560\uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc704\ud0a4\uc758 \ub3c4\uc6c0\ub9d0\uc744 \uc0b4\ud3b4\ubcf4\uc138\uc694.
-LoggerView.pause=\uae30\ub85d \uc7a0\uc2dc\uc911\uc9c0
+installPluginsWizard.installMode.info.text=Vuze\uac00 \uc62c\ubc14\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud558\ub294\ub370\ub294 \ud50c\ub7ec\uadf8\uc778\uc774 \ud544\uc694\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Vuze\ub294 \ud50c\ub7ec\uadf8\uc778\uc744 \ud1b5\ud574 \uc7ac\ubbf8, \uc790\ub3d9\ud654, \uc6d0\uaca9 \uc870\uc885\uc744 \uc704\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.\n\ub530\ub77c\uc11c \uc124\uce58\ud558\uae30 \uc804\uc5d0 \ud50c\ub7ec\uadf8\uc778 \uc124\uba85\ [...]
+Views.plugins.Distributed.DB.title=\ubd84\uc0b0 DB
+Views.plugins.Distributed.Tracker.title=\ubd84\uc0b0 \ud2b8\ub798\ucee4
+Views.plugins.Plugin.Update.title=\ud50c\ub7ec\uadf8\uc778 \uc5c5\ub370\uc774\ud2b8
+openUrl.url.info=http, https, \ub9c8\uadf8\ub137, \uac00\uacf5\ub418\uc9c0 \uc54a\uc740 16\uc9c4 infohash \ubb38\uc790\uc5f4 \uc9c0\uc6d0
+TableColumn.header.swarm_average_completion=\ud53c\uc5b4 \ud3c9\uade0 \uc644\uc131\ub3c4
+TableColumn.header.swarm_average_completion.info=\uc2a4\uc6dc \uc548 \ud53c\uc5b4\uc758 \ud3c9\uade0 \uc644\uc131 \ud37c\uc13c\ud14c\uc774\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+GeneralView.label.swarm_average_completion=\ud3c9\uade0 \uc644\ub8cc\uc728:
+GeneralView.label.swarm_average_completion.tooltip=\uc2a4\uc6dc \uc0c1 \ud3c9\uade0 \uc644\ub8cc \ud53c\uc5b4 \ud37c\uc13c\ud14c\uc774\uc9c0
+MainWindow.nat.status.tooltip.unknown=\ubc29\ud654\ubcbd/NAT \uc811\uadfc\uc131 \uc0c1\ud0dc\ub97c \uc54c \uc218 \uc5c6\uc74c (TCP)
+MainWindow.nat.status.ok=NAT \uc815\uc0c1
+MainWindow.nat.status.tooltip.ok=\uc811\uadfc\uc131 \uc815\uc0c1 (TCP)
+MainWindow.nat.status.probok=NAT \uc815\uc0c1?
+MainWindow.nat.status.tooltip.probok=\uc811\uadfc\uc131\uc740 \uc815\uc0c1\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ucd5c\uadfc \ub4e4\uc5b4\uc624\ub294 TCP \uc5f0\uacb0\uc774 \uc5c6\uc5c8\uc74c
+MainWindow.nat.status.bad=\ubc29\ud654\ubcbd\uc73c\ub85c \ub9c9\ud798
+MainWindow.nat.status.tooltip.bad=\ubc29\ud654\ubcbd/NAT (TCP) \uc811\uadfc\uc131 \ubb38\uc81c \ubc1c\uc0dd. \uc704\ud0a4\uc758 \ub3c4\uc6c0\ub9d0\uc744 \uc0b4\ud3b4\ubcfc \uac83
+plugin.installer.recommended.plugin=\ucd94\ucc9c \ud50c\ub7ec\uadf8\uc778 - \uac80\ud1a0\ud574\ubcf4\uc2dc\uace0 \ud544\uc694\ud55c \uacbd\uc6b0 \uc124\uce58\ud558\uc2ed\uc2dc\uc624
+LoggerView.pause=\ub85c\uadf8 \uc77c\uc2dc\uc815\uc9c0
+LoggerView.clear=\uc9c0\uc6b0\uae30(&C)
 LoggerView.filter=\ud544\ud130
-LoggerView.filter.uncheckAll=\ubaa8\ub4e0 \uad6c\ubd84 \ud655\uc778\ud558\uc9c0 \uc54a\uc74c
-LoggerView.filter.checkAll=\ubaa8\ub4e0 \uad6c\ubd84 \ud655\uc778
-LoggerView.loggingDisabled=\uae30\ub85d\uc774 \uc791\ub3d9\uc911\uc774\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+LoggerView.filter.uncheckAll=\ubaa8\ub4e0 \ubd84\ub958 \uc120\ud0dd\ud558\uc9c0 \uc54a\uc74c
+LoggerView.filter.checkAll=\ubaa8\ub4e0 \ubd84\ub958 \uc120\ud0dd
+LoggerView.loggingDisabled=\ub85c\uadf8 \uae30\ub85d\uc774 \ud65c\uc131\ud654\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.
+LoggerView.includeOnly=\uc774 \uc815\uaddc\uc2dd\uacfc \uc77c\uce58\ud558\ub294 \ud589\ub9cc \ud45c\uc2dc:
+LoggerView.excludeAll=\uc774 \uc815\uaddc\uc2dd\uacfc \uc77c\uce58\ud558\ub294 \ud589\uc740 \ud45c\uc2dc\ud558\uc9c0 \uc54a\uae30:
 ConfigView.section.logging.log0type=\uc815\ubcf4
 ConfigView.section.logging.log1type=\uacbd\uace0
 ConfigView.section.logging.log2type=\uc624\ub958
-ConfigView.section.logging.filter=\ud30c\uc77c\uc5d0 \uae30\ub85d\ud560\ub54c \ud544\ud130
-ConfigView.pluginlist.column.loadAtStartup=\uc2dc\uc791\uc2dc \ubd88\ub7ec\uc62e
-ConfigView.pluginlist.column.type=\uc885\ub958
-ConfigView.pluginlist.column.type.perUser=\uc0ac\uc6a9\uc790\ub2f9 \ube44\uc728
-ConfigView.pluginlist.column.type.shared=\uacf5\uc720
+ConfigView.section.logging.filter=\ud30c\uc77c\uc5d0 \ub85c\uadf8 \uc800\uc7a5\uc2dc \ud544\ud130
+ConfigView.section.logging.level=\ub85c\uadf8 \uc218\uc900
+ConfigView.section.logging.showLogsFor=\ub2e4\uc74c \ubd84\ub958\uc5d0 \ub300\ud574 %1 \ub85c\uadf8\ub97c \ubcf4\uc5ec\uc90c:
+ConfigView.pluginlist.column.loadAtStartup=\uc2dc\uc791 \uc2dc \uc801\uc7ac
+ConfigView.pluginlist.column.type=\uc720\ud615
+ConfigView.pluginlist.column.type.perUser=\uc0ac\uc6a9\uc790 \ub2e8\uc704
+ConfigView.pluginlist.column.type.shared=\uacf5\uc720\ub428
+ConfigView.pluginlist.column.type.builtIn=\ub0b4\uc7a5
 ConfigView.pluginlist.column.name=\uc774\ub984
 ConfigView.pluginlist.column.version=\ubc84\uc804
-ConfigView.pluginlist.column.directory=\ud3f4\ub354
-ConfigView.pluginlist.column.isOperational=\uc0ac\uc6a9\ud560\uc218 \uc788\uc2b5\ub2c8\uae4c?
-PeersView.BlockView.Avail.Have=\ub458\ub2e4 \uc788\uc74c
-PeersView.BlockView.Avail.NoHave=\ub3d9\ub8cc \uc788\uc74c; \ub098\ub294 \uc5c6\uc74c
-PeersView.BlockView.NoAvail.Have=\ub098\ub294 \uc788\uc74c; \ub3d9\ub8cc \uc5c6\uc74c
-PeersView.BlockView.Transfer=\uc804\uc1a1
+ConfigView.pluginlist.column.directory=\ub514\ub809\ud130\ub9ac
+ConfigView.pluginlist.column.isOperational=\uc6b4\uc601 \uac00\ub2a5?
+PeersView.BlockView.Avail.Have=\ub458 \ub2e4 \uc788\uc74c
+PeersView.BlockView.Avail.NoHave=\ud53c\uc5b4\ub294 \uc788\uc74c; \uc0ac\uc6a9\uc790\ub294 \uc5c6\uc74c
+PeersView.BlockView.NoAvail.Have=\uc0ac\uc6a9\uc790\ub294 \uc788\uc74c; \ud53c\uc5b4\ub294 \uc5c6\uc74c
+PeersView.BlockView.NoAvail.NoHave=\ub458 \ub2e4 \uc5c6\uc74c
+PeersView.BlockView.Transfer=\uc804\uc1a1 \uc911
 PeersView.BlockView.NextRequest=\ub2e4\uc74c \uc694\uccad
 PeersView.BlockView.title=\uc870\uac01 \uc9c0\ub3c4
+PeersView.BlockView.AvailCount=\uc720\ud6a8\uc131 \uce74\uc6b4\ud2b8
+MyTorrentsView.dialog.NumberError.title=\uc798\ubabb\ub418\uac70\ub098 \uc778\uc2dd\ub420 \uc218 \uc5c6\ub294 \uc218
+MyTorrentsView.dialog.NumberError.text=\uc785\ub825\ud55c \uc218\ub294 \uc798\ubabb\ub418\uc5c8\uac70\ub098 \uc778\uc2dd\ud560 \uc218 \uc5c6\ub294 \uc218 \uc785\ub2c8\ub2e4.
+MyTorrentsView.menu.manual=\uc218\ub3d9(&M)...
+MyTorrentsView.menu.manual.per_torrent=\uc218\ub3d9 (\ud1a0\ub80c\ud2b8 \ub2e8\uc704)
+MyTorrentsView.menu.manual.shared_torrents=\uc218\ub3d9 (\ud1a0\ub80c\ud2b8 \uc804\uccb4)
+MyTorrentsView.dialog.setSpeed.title=%1 \uc18d\ub3c4 \uc124\uc815
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
-MyTorrentsView.dialog.setNumber.upload=\uc62c\ub9ac\uae30
-MyTorrentsView.dialog.setNumber.download=\ub0b4\ub824\ubc1b\uae30
-OpenTorrentWindow.torrentLocation=\ud1a0\ub7f0\ud2b8 \ud30c\uc77c:
-OpenTorrentWindow.addFiles.URL=\ucd94\uac00 &URL
-OpenTorrentWindow.addFiles.Folder=\ucd94\uac00 &Folder
-OpenTorrentWindow.addFiles.Clipboard=\ucd94\uac00 Clip&board
-OpenTorrentWindow.fileList=\ud1a0\ub7f0\ud2b8 \ub0b4 \ud30c\uc77c:
+MyTorrentsView.dialog.setNumber.text=%2\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc218 \uc785\ub825 %1:
+MyTorrentsView.dialog.setNumber.upload=\uc5c5\ub85c\ub4dc
+MyTorrentsView.dialog.setNumber.download=\ub2e4\uc6b4\ub85c\ub4dc
+MyTorrentsView.dialog.setNumber.inKbps=[%1]
+OpenTorrentWindow.torrentLocation=\ub2e4\uc6b4\ub85c\ub4dc\ud560 \ud1a0\ub80c\ud2b8:
+OpenTorrentWindow.addFiles.URL=URL \ucd94\uac00(&U)
+OpenTorrentWindow.addFiles.Folder=\ud3f4\ub354 \ucd94\uac00(&F)
+OpenTorrentWindow.addFiles.Clipboard=\ud074\ub9bd\ubcf4\ub4dc\ub85c\ubd80\ud130 \ucd94\uac00(&B)
+OpenTorrentWindow.changeDestination=\ub300\uc0c1 \ubcc0\uacbd
+OpenTorrentWindow.fileList=\ud1a0\ub80c\ud2b8 \uc548 \ud30c\uc77c:
 OpenTorrentWindow.torrentTable.name=\uc774\ub984
-OpenTorrentWindow.torrentTable.saveLocation=\uc704\uce58 \uc800\uc7a5
+OpenTorrentWindow.torrentTable.saveLocation=\uc800\uc7a5 \uc704\uce58
 OpenTorrentWindow.fileTable.fileName=\ud30c\uc77c \uc774\ub984
 OpenTorrentWindow.fileTable.size=\ud06c\uae30
-OpenTorrentWindow.startMode.seeding=\ubfcc\ub9ac\uae30
+OpenTorrentWindow.fileTable.destinationName=\ub300\uc0c1 \uc774\ub984
+OpenTorrentWindow.startMode.seeding=\ubc30\ud3ec \uc911
+OpenTorrentWindow.fileList.changeDestination=\ub300\uc0c1 \ubcc0\uacbd
+OpenTorrentWindow.mb.badSize.title=\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ud30c\uc77c
+OpenTorrentWindow.mb.badSize.text='%1'\ub294 '%2'\uac00 \uc544\ub2c8\ubbc0\ub85c \ubc30\ud3ec\ub97c \uc704\ud574 \uc0ac\uc6a9\ub420 \uc218 \uc5c6\uc74c
+OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A>\ub294 \uc774\ubbf8 '%2'\ub85c \ucd94\uac00 \ub418\uc5b4\uc788\uc2b5\ub2c8\ub2e4.
 OpenTorrentWindow.mb.alreadyExists.default.name=\ubbf8\ub514\uc5b4
-OpenTorrentWindow.mb.openError.title=\uc624\ub958 \uc5f4\uae30
-OpenTorrentWindow.torrent.remove=\ubaa9\ub85d\uc5d0\uc11c \ud1a0\ub7f0\ud2b8 \uc0ad\uc81c
-iconBar.open.tooltip=\ud1a0\ub7f0\ud2b8 \uc5f4\uae30
-LocaleUtil.column.text=\uc54c\uc218\uc5c6\ub294 \ubb38\uc790
-ConfigView.label.lazybitfield=\ube44\ud6a8\uc728\uc801\uc778 \ube44\ud2b8\ud544\ub4dc \uc0ac\uc6a9 (\ub124\ud2b8\uc6cd\uc5d0\uc11c \ube44\ud2b8\ud544\ub4dc\uae30\ubc18\uc758 \ucc28\ub2e8\uc744 \uc0ac\uc6a9\ud558\uc5ec \ubfcc\ub9b4\ub54c \ub3c4\uc6c0\uc774 \ub428)
+OpenTorrentWindow.mb.alreadyExists.title=\uc774\ubbf8 \uc874\uc7ac\ud568
+OpenTorrentWindow.mb.openError.title=\uc5f4\uae30 \uc624\ub958
+OpenTorrentWindow.mb.openError.text='%1'\ub294 \uc5f4\ub9b4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4:\n%2
+OpenTorrentWindow.torrent.remove=\ubaa9\ub85d\uc5d0\uc11c \ud1a0\ub80c\ud2b8 \uc81c\uac70
+OpenTorrentWindow.torrent.options=\ub2e4\uc74c\uc758 \uc124\uc815\uc740 \uc704\uc5d0\uc11c \uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8\uc5d0 \uc801\uc6a9\ub429\ub2c8\ub2e4:
+OpenTorrentWindow.xOfTotal=(%2 \uc911 %1)
+iconBar.open.tooltip=\ud1a0\ub80c\ud2b8 \uc5f4\uae30
+LocaleUtil.column.text=\uc54c \uc218 \uc5c6\ub294 \ud14d\uc2a4\ud2b8
+Tracker.tooltip.MultiSupport=\uc774 \ud2b8\ub798\ucee4\ub294 \uc694\uccad \ud55c\ubc88\uc5d0 \uc5ec\ub7ec \ud574\uc26c \uc2a4\uc6dc \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub294 \ud2b8\ub798\ucee4\uc785\ub2c8\ub2e4.
+Tracker.tooltip.NoMultiSupport=\uc774 \ud2b8\ub798\ucee4\ub294 \uc694\uccad \ud55c\ubc88\uc5d0 \uc5ec\ub7ec \ud574\uc26c \uc2a4\uc6dc \uc815\ubcf4\ub97c \ubc18\ud658\ud558\uc9c0 \uc54a\ub294 \ud2b8\ub798\ucee4\uc785\ub2c8\ub2e4.\n\uc774\ub294 \uc131\ub2a5\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0\ub294 \uc54a\uc9c0\ub9cc \ud2b8\ub798\ucee4\uc5d0 \ucd94\uac00 \ubd80\ud558\ub97c \uc77c\uc73c\ud0b5\ub2c8\ub2e4.
+ConfigView.label.lazybitfield=\uad7c\ub72c \ube44\ud2b8\ud544\ub4dc \uc0ac\uc6a9 (\ube44\ud2b8\ud544\ub4dc\uae30\ubc18\uc758 \ucc28\ub2e8\uc744 \ucc44\ud0dd\ud558\uace0 \uc788\ub294 \ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \ubc30\ud3ec \uc2dc \ub3c4\uc6c0\uc774 \ub428)
 LoggerView.realtime=\uc2e4\uc2dc\uac04 \uc5c5\ub370\uc774\ud2b8
-Button.moveUp=\uc704\ub85c \uc62e\uae40 &U
-Button.moveDown=\uc544\ub798\ub85c \uc62e\uae40 &D
+ConfigView.section.file.perf.cache.flushpieces=\uc644\ub8cc\ub41c \uc870\uac01\uc744 \ub514\uc2a4\ud06c\uc5d0 \uace7\ubc14\ub85c \uc4f0\uae30. \ub514\uc2a4\ud06c \uc811\uadfc\uc744 \uc6d0\ud65c\ud558\uac8c \ud558\uc9c0\ub9cc \ub354 \ub9ce\uc740 \uc4f0\uae30\uc791\uc5c5\uc744 \uc720\ubc1c\ud568
+ConfigView.section.file.writemblimit=\ub300\uae30\ud558\ub294 \ucd5c\ub300 \uc4f0\uae30 \uc694\uccad (%1)
+ConfigView.section.file.writemblimit.explain=\ub514\uc2a4\ud06c \uc4f0\uae30 \uc18d\ub3c4\uac00 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\ubcf4\ub2e4 \ub290\ub9b4 \uacbd\uc6b0 \uc774 \ud30c\ub77c\ubbf8\ud130\ub294 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\uac00 \ub5a8\uc5b4\uc9c0\uae30 \uc804\uae4c\uc9c0 \uc5bc\ub9c8\ub098 \ub9ce\uc740 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud574\ub193\uc744 \uac83\uc778\uac00\ub97c \uacb0\uc815\ud569\ub2c8\ub2e4.
+ConfigView.section.file.readmblimit=\ub300\uae30\ud558\ub294 \ucd5c\ub300 \uc77d\uae30 \uc694\uccad (%1)
+ConfigView.section.file.readmblimit.explain=\uc774 \ud30c\ub77c\ubbf8\ud130\ub294 \ucc98\ub9ac\ub97c \uae30\ub2e4\ub9ac\ub294 \uc77d\uae30 \uc694\uccad\uc744 \uc800\uc7a5\ud558\ub294\ub370 \uc0ac\uc6a9\ud560 \uba54\ubaa8\ub9ac \uc591\uc744 \uc81c\ud55c \ud569\ub2c8\ub2e4.
+Button.moveUp=\uc704\ub85c \uc774\ub3d9(&U)
+Button.moveDown=\uc544\ub798\ub85c \uc774\ub3d9(&D)
+ConfigView.notAvailableForMode=\uc774 \uc139\uc158\uc740 %1 \ubaa8\ub4dc \uc774\uc0c1\uc744 \uc704\ud55c \uac83\uc785\ub2c8\ub2e4. %2 \ubaa8\ub4dc\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+health.explain.error=\ud574\ub2f9 \ud1a0\ub80c\ud2b8\uc5d0 \uc624\ub958\uac00 \uc788\uc2b5\ub2c8\ub2e4.\n\uc624\ub958\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 \uc0c1\ud0dc \uc5f4\uc774\ub098 \uc544\uc774\ucf58\uc758 \ud234\ud301\uc744 \ucc38\uace0\ud558\uc2ed\uc2dc\uc624.
+GeneralView.label.trackerscrapeupdate=\ud2b8\ub798\ucee4 \uc2a4\uc6dc \uc815\ubcf4 \uc218\uc9d1
 PeersView.piece=\uc870\uac01
-PiecesView.priority=\uc21c\uc704
-PiecesView.speed=\ud06c\uae30
-MyTorrentsView.menu.checkfilesexist=\ud30c\uc77c \uc704\uce58 \ud655\uc778
-MyTorrentsView.menu.clear_resume_data=\ub2e4\uc2dc\uc2dc\ub3c4\ud55c \ub370\uc774\ud130 \uc9c0\uc6b0\uae30
-azinstancehandler.alert.portclash=\uc0ac\uc6a9\uc911\uc778 \ub124\ud2b8\uc6cd\uc758 \ud3ec\ud2b8\uc5d0\uc11c \ucda9\ub3cc\uc774 \ubc1c\uacac\ub418\uc5c8\uc2b5\ub2c8\ub2e4: %1 \uc774\ubbf8 \ub2e4\ub978 Vuze \uc0ac\uc6a9\uc790\uac00 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 \uac83 \uac19\uc2b5\ub2c8\ub2e4. TCP / UDP \ub4e3\uae30\uc6a9 \ub2e4\ub978 \ud3ec\ud2b8\ub97c \uc120\ud0dd\ud574 \uc8fc\uc138\uc694. [%2 \uc5d0\uc11c %3 \uc0ac\uc774]. 
-TorrentOptionsView.title.short=\ud1a0\ub7f0\ud2b8 \uc120\ud0dd\uc0ac\ud56d
-TorrentOptionsView.title.full=\ud1a0\ub7f0\ud2b8 \uc120\ud0dd\uc0ac\ud56d
-MainWindow.sr.status.tooltip.ok=\uacf5\uc720\ube44\uc728 %1 OK
-MainWindow.sr.status.tooltip.poor=\uacf5\uc720\ube44\uc728 %1 \uc5f4\uc545: < 0.9
-MainWindow.sr.status.tooltip.bad=\uacf5\uc720\ube44\uc728 %1 \ub098\uc068: < 0.5
-ConfigView.section.style.status.show_ipf=IP \ud544\ud130 \uc0c1\ud0dc
-ConfigView.section.connection.encryption=\uc554\ud638\ud654
+PeersView.piece.info=\uc774 \ud53c\uc5b4\uc5d0 \uc758\ud574 \uc694\uccad\ub41c \ucd5c\uadfc \uc870\uac01 \uc218 \uc785\ub2c8\ub2e4.
+PiecesView.priority=\uc6b0\uc120\uad8c
+PiecesView.priority.info=\uc774 \uc870\uac01\uc758 \uc644\ub8cc \uc6b0\uc120\uad8c, \ud558\uc9c0\ub9cc \ub108\ubb34 \uc2e0\uacbd\uc4f0\uc9c0\ub294 \ub9c8\uc138\uc694
+PiecesView.speed=\uc18d\ub3c4
+PiecesView.speed.info=\ub290\ub9b0 \ud53c\uc5b4\ub294 \ube60\ub978 \uc870\uac01\uc73c\ub85c \uc778\ud574 \ud06c\uac8c \ubc29\ud574 \ubc1b\uac8c\ub429\ub2c8\ub2e4.
+TableColumn.header.AvgAvail.info=\uc720\ud6a8\ud55c \uc870\uac01 \ud569\uacc4\ub97c \uc870\uac01 \uc218\ub85c \ub098\ub208 \uac83\uc744 \uc5f0\uacb0 \uc218\ub85c \ub2e4\uc2dc \ub098\ub220\uc11c \ubcf4\uc5ec\uc8fc\ub294 \ud3c9\uade0\uc785\ub2c8\ub2e4.
+TableColumn.header.AvgAvail=\ud3c9\uade0 \uc720\ud6a8/\uc870\uac01
+ConfigView.label.strictfilelocking=\ud1a0\ub80c\ud2b8\ub97c \uc7a0\uad88\uc11c \ubc30\ud0c0\uc801 \ud30c\uc77c \uc4f0\uae30 \uc811\uadfc \uad8c\ud55c \ud68d\ub4dd \uac15\uc81c
+MyTorrentsView.menu.checkfilesexist=\ud30c\uc77c \uc874\uc7ac\uc5ec\ubd80 \uac80\uc0ac
+MyTorrentsView.menu.rescanfile=\uc8fc\uae30\uc801\uc73c\ub85c \uc644\ub8cc\ub418\uc9c0 \uc54a\uc740 \uc870\uac01 \ub2e4\uc2dc \uac80\uc0ac
+MyTorrentsView.menu.clear_resume_data=\ub2e4\uc2dc \uc2dc\uc791 \ub370\uc774\ud130 \uc9c0\uc6b0\uae30
+Plugin.extseed.name=\uc678\ubd80 \uc2dc\ub4dc
+Plugin.localtracker.name=LAN \ud53c\uc5b4 \uac80\uc0c9\uae30
+Plugin.localtracker.info=LAN \ud53c\uc5b4 \uac80\uc0c9\uae30\ub294 \ubc29\ud654\ubcbd \ub4a4\uc5d0 \uc5ec\ub7ec Vuze \uc0ac\ubcf8\uc774 \uc2e4\ud589\ub418\ub3c4\ub85d \uad6c\uc131\ud55c \ud6c4 \uc11c\ub85c \uc9c1\uc811 \uc811\uc18d\ud558\uc5ec\n\ud6a8\uc728\uc801\uc778 \ud1a0\ub80c\ud2b8 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \ud560 \uc218 \uc788\ub294 \uacf5\ub3d9 \ub124\ud2b8\uc6cc\ud06c\ub97c \uc774\ub8e8\ub3c4\ub85d \ud569\ub2c8\ub2e4.
+Plugin.localtracker.enable=LAN \ud53c\uc5b4 \uac80\uc0c9\uae30 \ud65c\uc131\ud654
+azinstancehandler.alert.portclash=LAN \uc0c1 \ud3ec\ud2b8 \ucda9\ub3cc\uc774 \uac10\uc9c0\ub428: %1\ub294 \uc774\ubbf8 \ub2e4\ub978 Vuze \uc0ac\uc6a9\uc790\uc5d0 \uc758\ud574\uc11c \uc0ac\uc6a9\ub418\uace0 \uc788\uc73c\ubbc0\ub85c, \ub4e4\uc5b4\uc624\ub294 TCP / UDP \ub9ac\uc2a4\ub2dd\uc744 \uc704\ud574 [%2\uc640 %3 \uc0ac\uc774\uc758] \uc0c8 \uc784\uc758 \ud3ec\ud2b8\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.transfer.lan.tooltip=LAN \ud55c\uc815 \uc124\uc815
+ConfigView.section.transfer.lan.uploadrate=KB/s LAN \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.transfer.lan.uploadrate.tooltip=\uac19\uc740 \ub0b4\ubd80 LAN\uc548\uc5d0 \uc18d\ud574\uc788\ub294 \ud53c\uc5b4 \uc5f0\uacb0\uc740 \ubcc4\ub3c4\uc758 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc744 \uac00\uc9d1\ub2c8\ub2e4.
+ConfigView.section.transfer.lan.downloadrate=KB/s LAN \ucd5c\ub300 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.transfer.lan.downloadrate.tooltip=\uac19\uc740 \ub0b4\ubd80 LAN\uc548\uc5d0 \uc18d\ud574\uc788\ub294 \ud53c\uc5b4 \uc5f0\uacb0\uc740 \ubcc4\ub3c4\uc758 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc744 \uac00\uc9d1\ub2c8\ub2e4.
+TorrentOptionsView.title.short=\uc635\uc158
+TorrentOptionsView.title.full=\uc635\uc158
+TorrentOptionsView.param.max.peers=\uc5f0\uacb0\uc758 \ucd5c\ub300 \uac2f\uc218 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.connection.encryption.require_encrypted_transport=\uc554\ud638\ud654\ub41c \uc804\uc1a1 \ud544\uc694
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=\ub2e4\ub978 \ud53c\uc5b4\uc640 \uc554\ud638\ud654\ub41c \uc5f0\uacb0\uc744 \uc0ac\uc6a9\ud558\ub3c4\ub85d \uac15\uc81c\ud569\ub2c8\ub2e4.
+ConfigView.section.connection.encryption.min_encryption_level=\ucd5c\uc18c \uc554\ud638\ud654 \uc218\uc900
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=\ub2e8\uc21c - \ud578\ub4dc\uc250\uc774\ud06c \uc804\uc6a9\nRC4 - \uc804\uccb4 \uc2a4\ud2b8\ub9bc\n\ub192\uc740 \uc554\ud638\ud654 \uc218\uc900\uc740 \ub354 \ub9ce\uc740 CPU \uc790\uc6d0\uc744 \uc694\uad6c\ud569\ub2c8\ub2e4.
+Peers.column.Encryption=\uc554\ud638\ud654
+Peers.column.Encryption.info=\uc0ac\uc6a9\ud560 \uc554\ud638\ud654 \uc218\uc900
+ConfigView.section.connection.encryption.encrypt.info=\uc554\ud638\ud654\uac00 \ud65c\uc131\ud654\ub418\uba74, \ub300\uccb4 \uc635\uc158\uc744 \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uc774\uc0c1, \ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uac8c \ub429\ub2c8\ub2e4.
+ConfigView.section.connection.encryption.encrypt.info.link=\uc138\ubd80\uc0ac\ud56d\uc5d0 \ub300\ud574\uc11c\ub294 \uc5ec\uae30\ub97c \ubc29\ubb38\ud574\uc8fc\uc2ed\uc2dc\uc624
+MainWindow.sr.status.tooltip.ok=\uacf5\uc720 \ube44\uc728 %1 \uc815\uc0c1
+MainWindow.sr.status.tooltip.poor=\uacf5\uc720 \ube44\uc728 %1 \ubd80\uc871: < 0.9
+MainWindow.sr.status.tooltip.bad=\uacf5\uc720 \ube44\uc728 %1 \ub098\uc068: < 0.5
+ConfigView.section.style.status=\uc0c1\ud0dc \uc601\uc5ed:
+ConfigView.section.style.status.show_sr=\uacf5\uc720 \ube44\uc728
+ConfigView.section.style.status.show_nat=NAT \uc0c1\ud0dc
+ConfigView.section.style.status.show_ddb=DDB \uc0c1\ud0dc
+ConfigView.section.style.status.show_ipf=IP\ud544\ud130 \uc0c1\ud0dc
+ConfigView.section.connection.encryption.encrypt.group=\uc804\uc1a1 \uc554\ud638\ud654/\uad50\ub780
+ConfigView.section.connection.encryption.encrypt.fallback_info=\uc5b4\ub5a4 \ub300\uccb4 \uc635\uc158\uc744 \ud65c\uc131\ud654 \ud558\ub4e0\uc9c0 \ud638\ud658\uc131 \uc5c6\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc5f0\uacb0\uc744 \ud5c8\uc6a9\ud569\ub2c8\ub2e4.\n*\uadf8\ub7ec\ub098* \uc554\ud638\ud654\ub418\uc9c0 \uc54a\uc740 \uc5f0\uacb0\uc744 \ud5c8\uc6a9\ud558\uac8c \ub429\ub2c8\ub2e4.
+ConfigView.section.connection.encryption.encrypt.fallback_outgoing=\uc554\ud638\ud654\ub41c \uc5f0\uacb0 \uc2dc\ub3c4\uac00 \uc2e4\ud328\ud560 \uacbd\uc6b0 \uc554\ud638\ud654\ub418\uc9c0 \uc54a\uc740 \ub098\uac00\ub294 \uc5f0\uacb0 \ud5c8\uc6a9
+ConfigView.section.connection.encryption.encrypt.fallback_incoming=\uc554\ud638\ud654 \ub418\uc9c0 \uc54a\uc740 \ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0 \ud5c8\uc6a9
+ConfigView.section.connection.encryption=\uc804\uc1a1 \uc554\ud638\ud654
+upnp.selectedinterfaces=\uc120\ud0dd\ub41c \uc778\ud130\ud398\uc774\uc2a4 (';'\ub85c \ubd84\ub9ac\ub428, \uc608: eth0;eth1) [\ube48\uce78: \ubaa8\ub450]
+ConfigView.section.style.defaultSortOrder=\uae30\ubcf8 \uc815\ub82c \uc21c\uc11c
+ConfigView.section.style.defaultSortOrder.desc=\ub0b4\ub9bc\ucc28\uc21c
+ConfigView.section.style.defaultSortOrder.asc=\uc62c\ub9bc\ucc28\uc21c
+ConfigView.section.style.defaultSortOrder.flip=\uc774\uc804 \uc21c\uc11c\uc640 \ubc18\ub300\ub85c
 LoggerView.autoscroll=\uc790\ub3d9 \uc2a4\ud06c\ub864
 Button.selectAll=\ubaa8\ub450 \uc120\ud0dd
-Button.markSelected=\uc120\ud0dd
-Button.unmarkSelected=\uc120\ud0dd\uc548\ud568
+Button.markSelected=\uc120\ud0dd\uc744 \ud45c\uc2dc
+Button.unmarkSelected=\uc120\ud0dd\uc744 \ud45c\uc2dc \ud574\uc81c
 plugins.basicview.config=\uc124\uc815
-ConfigView.section.connection.advanced.info.link=\uc138\ubd80\ud56d\ubaa9\uc744 \ubcf4\uc2dc\ub824\uba74 \ubc29\ubb38\ud574 \uc8fc\uc138\uc694
-ConfigView.section.connection.advanced.socket.group=\uc18c\ucf13 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.connection.advanced.bind_port=\ub85c\uceec\ud3ec\ud2b8\ub85c \uc9c0\uc815 [0: \uc791\ub3d9 \uc911\uc9c0]
-ConfigView.section.proxy.group.tracker=\ub354\ub4ec\uc774 \ud1b5\uc2e0
-ConfigView.section.proxy.group.peer=\ub3d9\ub8cc \ud1b5\uc2e0
+TorrentOptionsView.param.max.uploads=\uc5c5\ub85c\ub4dc \uc2ac\ub86f\uc758 \ucd5c\ub300 \uac2f\uc218 [\ucd5c\uc18c: 2]
+MyTorrentsView.dialog.setPosition.title=\uc704\uce58 \uc124\uc815
+MyTorrentsView.dialog.setPosition.text=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8\ub97c \ub2e4\uc74c\uc73c\ub85c \uc124\uc815\ud558\uae30 \uc704\ud55c \uc704\uce58\ub97c \uc785\ub825:
+MyTorrentsView.menu.reposition.manual=\uc704\uce58 \ubc14\uafb8\uae30...
+ConfigView.section.connection.advanced.info.link=\uc138\ubd80\ud56d\ubaa9\uc744 \ubcf4\uc2dc\ub824\uba74 \ubc29\ubb38\ud574 \uc8fc\uc2ed\uc2dc\uc624
+ConfigView.section.connection.advanced.socket.group=\uc18c\ucf13 \uc635\uc158
+ConfigView.section.connection.advanced.bind_port=\ub85c\uceec \ud3ec\ud2b8\uc5d0 \ubc14\uc778\ub4dc [0: \ud574\uc81c]
+ConfigView.section.connection.advanced.bind_port.tooltip=\ub098\uac00\ub294 \uc18c\ucf13 \uc5f0\uacb0\uc740 \uc8fc\uc5b4\uc9c4 \ud3ec\ud2b8\uc5d0 \ub85c\uceec\ub85c \ubc14\uc6b4\ub4dc \ub429\ub2c8\ub2e4.\n\uc774 \uc635\uc158\uc744 \ud65c\uc131\ud654\ud558\ub294 \uac83\uc740 NAT \ub77c\uc6b0\ud130 \ubd88\uc548\uc815\uc5d0 \ub3c4\uc6c0\uc774 \ub429\ub2c8\ub2e4.
+ConfigView.section.proxy.group.tracker=\ud2b8\ub798\ucee4 \ud1b5\uc2e0
+ConfigView.section.proxy.group.peer=\ud53c\uc5b4 \ud1b5\uc2e0
 Pieces.column.Requested=\uc694\uccad\ub428
-ConfigView.label.maxuploadsseeding=\ubfcc\ub9b4\ub54c \ub300\uccb4\ud560 \uae30\ubcf8\uac12
-MyTorrentsView.filter=\uace8\ub77c\ubcf4\uae30:
+Pieces.column.Requested.info=\ud574\ub2f9 \uc870\uac01\uc5d0 \ub300\ud574 \ub354 \ub9ce\uc740 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc788\ub294\uc9c0 \uc5c6\ub294\uc9c0\ub97c \ubcf4\uc5ec\uc8fc\uae30 (*)
+ConfigView.label.maxuploadsseeding=\ubc30\ud3ec\ud560 \ub54c \ub300\uccb4 \uae30\ubcf8\uac12
+MyTorrentsView.filter=\ud544\ud130
 popup.error.hideall=\ubaa8\ub450 \uc228\uae30\uae30
-MyTorrentsView.dialog.setFilter.title=\uace8\ub77c\ubcf4\uae30 \ud3b8\uc9d1
-MyTorrentsView.menu.filter=\uace8\ub77c\ubcf4\uae30 \ubaa9\ub85d...
-ConfigureWizard.language.choose=\uc544\ub798\uc5d0\uc11c \uc5b8\uc5b4\ub97c \uc120\ud0dd\ud558\uc138\uc694:
+ConfigView.section.style.dataStatsOnly=\ub370\uc774\ud130 \ud1b5\uacc4\ub9cc \ubcf4\uc5ec\uc8fc\uae30 (\ud504\ub85c\ud1a0\ucf5c \ud1b5\uacc4\ub294 \uc228\uae30\uae30)
+ConfigView.section.style.separateProtDataStats=\ub370\uc774\ud130\uc640 \ud504\ub85c\ud1a0\ucf5c \ud1b5\uacc4\ub97c '\ub370\uc774\ud130 (\ud504\ub85c\ud1a0\ucf5c)' \uc2dd\uc73c\ub85c \ubd84\ub9ac\ud574\uc11c \ubcf4\uc5ec\uc90c
+MyTorrentsView.dialog.setFilter.title=\ud544\ud130 \ubcc0\uacbd
+MyTorrentsView.dialog.setFilter.text=%1 \uc139\uc158\uc740 \uc544\ub798\uc5d0 \uc815\uc758\ud55c \ud14d\uc2a4\ud2b8\ub85c \ud544\ud130\ub9c1\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub2e4\uc911  \uad6c\ubb38\uc5d0 \ub300\ud574\uc11c\ub294 | (\ud30c\uc774\ud504) \uc2ec\ubcfc\uc744 \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.
+MyTorrentsView.filter.tooltip=Ctrl+X\ub85c \uc815\uaddc\uc2dd\uacfc \uc77c\ubc18 \uac80\uc0c9 \ubaa8\ub4dc \uac04 \uc804\ud658\uc744 \ud558\uc2ed\uc2dc\uc624.\n\uc5ec\ub7ec \uad6c\ub85c \ud544\ud130\ub97c \ud558\ub824\uba74 | (\ud30c\uc774\ud504) \uc2ec\ubcfc\uc744 \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.
+MyTorrentsView.clearFilter.tooltip=\ud544\ud130 \uc9c0\uc6b0\uae30
+MyTorrentsView.menu.filter=\ud544\ud130 \ubaa9\ub85d...
+ConfigView.section.file.resume.recheck.all=\ucda9\ub3cc \ud6c4 \ub2e4\uc2dc \uc2dc\uc791 \uc2dc \uc644\ub8cc\ub41c \uc870\uac01\uc744 \ud3ec\ud568\ud55c \uc804\uccb4 \ud30c\uc77c \uac80\uc0ac (\uc124\uc815\ud558\uc9c0 \uc54a\uc73c\uba74 \uac00\uc7a5 \ub9c8\uc9c0\ub9c9\uc5d0 \uc800\uc7a5\ub41c \uc870\uac01\ub4e4\ub9cc \uac80\uc0ac\ub428)
+ConfigureWizard.language.choose=\uc544\ub798 \ubaa9\ub85d\uc5d0\uc11c \uc5b8\uc5b4\ub97c \uc120\ud0dd \ud558\uc2ed\uc2dc\uc624:
+popup.closing.in=%1 \ucd08 \uc548\uc5d0 \ucc3d\uc774 \uc790\ub3d9\uc73c\ub85c \ub2eb\ud798
+popup.more.waiting=%1 \uba54\uc2dc\uc9c0\uac00 \ub354 \uc788\uc74c..
 # > 2402
+popup.download.finished=%1 \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+popup.file.finished=%1 \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
 ConfigView.auto=\uc790\ub3d9
-MainWindow.menu.view.plugins.logViews=\uae30\ub85d \ubcf4\uae30
-SpeedView.stats.autospeed=\uc790\ub3d9 \uc62c\ub9ac\uae30 \uc18d\ub3c4
-SpeedView.stats.idlePing=\ud734\uc9c0\uae30 \ud551:
+Plugin.localtracker.autoadd.info=\uc790\ub3d9\uc73c\ub85c \uc774 \ub85c\uceec \ud53c\uc5b4\ub97c \ucd94\uac00 [';'\ub85c \ubd84\ub9ac\ub41c \uc8fc\uc18c, \uc608: 1.2.3.4]
+Plugin.localtracker.autoadd=\uba85\uc2dc \ud53c\uc5b4
+Plugin.localtracker.networks.info=\ub2e4\uc74c \ub124\ud2b8\uc6cc\ud06c\ub294 \uc9c0\uc5ed \ub124\ud2b8\uc6cc\ud06c\ub85c \uac04\uc8fc [';'\ub85c \ubd84\ub9ac\ub41c \ub124\ud2b8\uc6cc\ud06c, \uc608: 145.227.*.*]
+Plugin.localtracker.networks=\uc9c0\uc5ed \ub124\ud2b8\uc6cc\ud06c
+MainWindow.menu.view.plugins.logViews=\ub85c\uadf8 \ubcf4\uae30
+SpeedView.stats.autospeed=\uc790\ub3d9 \uc5c5\ub85c\ub4dc \uc18d\ub3c4
+SpeedView.stats.autospeed.disabled=\uc774 \uae30\ub2a5\uc740 \ube44\ud65c\uc131\ud654 (\uc774 \uacbd\uc6b0 DHT \ud544\uc694) \ub418\uac70\ub098 \uc0ac\uc6a9\ub418\uace0 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4 (\uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uac00 \uc218\ub3d9\uc73c\ub85c \uc120\ud0dd\ub428).
+SpeedView.stats.idlePing=\uc720\ud734 \ud551:
 SpeedView.stats.maxPing=\ud551 \ucd5c\ub300\uac12:
-SpeedView.stats.currentPing=\ud604\uc7ac\uae4c\uc9c0 \ud551:
-SpeedView.stats.maxUp=\uc62c\ub9ac\uae30 \uc18d\ub3c4 \ucd5c\ub300\uac12:
-ConfigView.pluginlist.unloadSelected=\uc120\ud0dd\ud55c\uac83 \ubd88\ub7ec\uc624\uae30 \ucde8\uc18c
-ConfigView.pluginlist.scan=\uc0c8\ub85c\uc6b4 \ucd94\uac00\uae30\ub2a5 \ucc3e\uc544\ubcf4\uae30
-ConfigView.section.transfer.autospeed=\uc790\ub3d9 \uc18d\ub3c4 (\uae30\ubcf8)
-ConfigView.pluginlist.column.unloadable=\ubd88\ub7ec\uc62c\uc218 \uc5c6\uc74c
+SpeedView.stats.currentPing=\ud604\uc7ac \ud551:
+SpeedView.stats.maxUp=\ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4:
+ConfigView.pluginlist.unloadSelected=\uc120\ud0dd\ud55c \uac83 \uc5b8\ub85c\ub4dc
+ConfigView.pluginlist.scan=\uc0c8 \ud50c\ub7ec\uadf8\uc778 \uac80\uc0c9
+ConfigView.section.transfer.autospeed=\uc790\ub3d9\uc18d\ub3c4 (\ud074\ub798\uc2dd)
+ConfigView.section.transfer.autospeed.tooltip=\uc790\ub3d9\uc18d\ub3c4\uc5d0 \ud55c\uc815\ub41c \uc124\uc815
+ConfigView.section.transfer.autospeed.info=\uc790\ub3d9\uc18d\ub3c4\ub294 \ub124\ud2b8\uc6cc\ud06c \uc5f0\uacb0\uc758 \uacfc\ubd80\ud558\ub97c \ud53c\ud558\uae30 \uc704\ud574 \uc790\ub3d9\uc73c\ub85c \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc744 \uc870\uc815\ud569\ub2c8\ub2e4.
+ConfigView.section.transfer.autospeed.minupload=%1 \ucd5c\uc18c \uc5c5\ub85c\ub4dc \uc18d\ub3c4
+ConfigView.section.transfer.autospeed.minupload.tooltip=\uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub294 \uc774 \uc81c\ud55c \uc544\ub798\ub85c\ub294 \uc790\ub3d9 \uac10\uc18c\ub418\uc9c0 \uc54a\uc74c
+ConfigView.section.transfer.autospeed.maxupload=%1 \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+ConfigView.section.transfer.autospeed.maxupload.tooltip=\uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub294 \uc774 \uc81c\ud55c \uc704\ub85c\ub294 \uc790\ub3d9 \uc99d\uac00\ub418\uc9c0 \uc54a\uc74c
+ConfigView.section.transfer.autospeed.chokeping=\ud3ec\ud654 \ud551 \uc2dc\uac04 [millis]
+ConfigView.section.transfer.autospeed.chokeping.tooltip=\uc774 \uac12\uc744 \ucd08\uacfc\ud558\ub294 \ud551 \uc2dc\uac04\uc740 \ub124\ud2b8\uc6cc\ud06c \ud3ec\ud654 \uc0c1\ud0dc\ub97c \ud45c\uc2dc\ud558\ub294 \uac83\uc73c\ub85c \uac04\uc8fc \ub429\ub2c8\ub2e4.
+ConfigView.section.transfer.autospeed.enableauto=\ub2e4\uc6b4\ub85c\ub4dc\uc640 \ubc30\ud3ec \uc2dc \ud65c\uc131\ud654
+ConfigView.section.transfer.autospeed.enableautoseeding=\ubc30\ud3ec \uc2dc\uc5d0\ub9cc \ud65c\uc131\ud654
+ConfigView.pluginlist.column.unloadable=\uc5b8\ub85c\ub4dc \uac00\ub2a5
+ConfigView.section.transfer.lan.enable=LAN \uc5f0\uacb0\uc5d0 \ub300\ud55c \ubcc4\ub3c4 \uc18d\ub3c4 \uc81c\ud55c \ud65c\uc131\ud654
+Plugin.localtracker.wellknownlocals=\uc790\ub3d9\uc73c\ub85c \ub8e8\ud504\ubc31/\ub9c1\ud06c/\uc0ac\uc774\ud2b8 \ub85c\uceec \ub124\ud2b8\uc6cc\ud06c \ud3ec\ud568 (192.168.*.* \ub4f1)
 TableColumn.header.filesdone=\ud30c\uc77c \uc644\ub8cc
-MagnetPlugin.report.searching=\uac80\uc0c9...
+TableColumn.header.filesdone.info=\uc644\ub8cc\ub41c \ud30c\uc77c/\uc804\uccb4 \ud30c\uc77c *\ub610\ub294* \uc644\ub8cc\ub41c \uac74\ub108\ub6f0\uc9c0 \uc54a\uc740 \ud30c\uc77c (\uc644\ub8cc\ub41c \ud30c\uc77c)/\uc804\uccb4 \uac74\ub108\ub6f0\uc9c0 \uc54a\uc740 \ud30c\uc77c(\uc804\uccb4 \ud30c\uc77c)\uc744 \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+MagnetPlugin.private_torrent=<\ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8>
+MagnetPlugin.decentral_disabled=<\ubd84\uc0b0 \ucd94\uc801 \ube44\ud65c\uc131\ud654\ub428>
+MagnetPlugin.decentral_backup_disabled=<\ubd84\uc0b0 \ubc31\uc5c5 \ube44\ud65c\uc131\ud654\ub428>
+MagnetPlugin.report.waiting_ddb=DDB \ucd08\uae30\ud654\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911...
+MagnetPlugin.report.searching=\uac80\uc0c9 \uc911...
+MagnetPlugin.report.found=\ucc3e\uc74c %1
 MagnetPlugin.report.alive=%1 \uc0b4\uc544\uc788\uc74c
-MagnetPlugin.report.dead=%1 \uc8fd\uc5b4\uc788\uc74c
-MagnetPlugin.report.downloading=%1\uc5d0\uc11c \ub0b4\ub824\ubc1b\uae30 \uc911
+MagnetPlugin.report.dead=%1 \uc8fd\uc5c8\uc74c
+MagnetPlugin.report.tunnel=%1\uc73c\ub85c \ud130\ub110\ub9c1
+MagnetPlugin.report.downloading=%1\uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc \uc911
 MagnetPlugin.report.error=\uc624\ub958 %1
-MagnetURLHandler.report.no_sources=\ud1a0\ub7f0\ud2b8\uc5d0\uc11c \uc18c\uc2a4\ub97c \ucc3e\uc9c0 \ubabb\ud568
-MagnetURLHandler.report.torrent_size=\ud1a0\ub7f0\ud2b8 \ud06c\uae30: %1
+MagnetURLHandler.report.no_sources=\ud1a0\ub80c\ud2b8\uc5d0\uc11c \ubc1c\uacac\ub41c \ucd9c\ucc98 \uc5c6\uc74c
+MagnetURLHandler.report.torrent_size=\ud1a0\ub80c\ud2b8 \ud06c\uae30: %1
 MagnetURLHandler.report.percent=\uc644\ub8cc: %1%
+MagnetURLHandler.report.error=\uc624\ub958 %1
+DHTTransport.report.request_all=%1\uc5d0\uc11c \uc804\uccb4 \uc804\uc1a1 \uc694\uccad
+DHTTransport.report.received_bit=%3\uc73c\ub85c\ubd80\ud130 %1\uc5d0\uc11c %2\uae4c\uc9c0 \uc218\uc2e0
 DHTTransport.report.complete=\uc644\ub8cc
+DHTTransport.report.timeout=\uc2dc\uac04\ucd08\uacfc, %1\uc73c\ub85c\ubd80\ud130 \uc751\ub2f5\uc5c6\uc74c
+DHTTransport.report.rerequest_all=%1\uc5d0\uc11c \uc804\uccb4 \uc804\uc1a1 \ub2e4\uc2dc \uc694\uccad
+DHTTransport.report.rerequest_bit=%3\uc73c\ub85c\ubd80\ud130 %1\uc5d0\uc11c %2\uae4c\uc9c0 \ub2e4\uc2dc \uc694\uccad
+DHTTransport.report.timeout_some=\uc2dc\uac04\ucd08\uacfc, %2\uc73c\ub85c\ubd80\ud130 %1 \ud328\ud0b7\uc744 \uc218\uc2e0\ud588\uc9c0\ub9cc \uc644\ub8cc\ub418\uc9c0\uc54a\uc74c
 DHTTransport.report.sending=\ub370\uc774\ud130 \ubcf4\ub0b4\uae30
-DHTTransport.report.resending=\ub370\uc774\ud130 \ub2e4\uc2dc\ubcf4\ub0b4\uae30
+DHTTransport.report.resending=\ub370\uc774\ud130 \ub2e4\uc2dc \ubcf4\ub0b4\uae30
 DHTTransport.report.send_complete=\uc644\ub8cc \ubcf4\ub0b4\uae30
 DHTTransport.report.send_timeout=\uc2dc\uac04\ucd08\uacfc \ubcf4\ub0b4\uae30
-TableColumn.header.date_added=\ucd94\uac00 \ub0a0\uc9dc
-TableColumn.header.date_added.info=\ud1a0\ub7f0\ud2b8\uac00 \ucd94\uac00\ub41c \ub0a0\uc9dc
-platform.win32.baddll.nvappfilter=NVidia \ubc29\ud654\ubcbd
-platform.win32.baddll.vlsp=Venturi \ubc29\ud654\ubcbd
-platform.win32.baddll.radhslib=Naomi \uc778\ud130\ub137 \ud544\ud130 (Radiant)
-platform.win32.baddll.winsflt=PureSight \uc778\ud130\ub137 \ud544\ud130
-platform.win32.baddll.iFW_Xfilter=iolo \uac1c\uc778\uc6a9 \ubc29\ud654\ubcbd
+ConfigView.section.transfer.autospeed.enabledebug=\ub514\ubc84\uadf8 \uc815\ubcf4 \ub85c\uadf8
+TableColumn.header.date_added=\ucd94\uac00\ub41c \ub0a0\uc9dc
+TableColumn.header.date_added.info=\ud1a0\ub80c\ud2b8\uac00 \ucd94\uac00\ub41c \ub0a0\uc9dc\uc785\ub2c8\ub2e4.
+ConfigView.section.file.hashchecking.smallestfirst=\uac00\uc7a5 \uc791\uc740 \ub2e4\uc6b4\ub85c\ub4dc\ubd80\ud130 \uba3c\uc800 \ub2e4\uc2dc \uac80\uc0ac
+platform.win32.baddll.info=Vuze\uac00 '%1'\ub97c \uac10\uc9c0\ud588\uc2b5\ub2c8\ub2e4. \uc774\uac83\uc740 '%2'\uc758 \ubd80\ubd84\uc73c\ub85c\uc11c \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \ucda9\ub3cc\uacfc \ub192\uc740 CPU \uc0ac\uc6a9\ub960\uacfc \uac19\uc740 \uc2ec\uac01\ud55c \ubb38\uc81c\ub97c \uc77c\uc73c\ud0a4\ub294 \uac83\uc73c\ub85c \uc54c\ub824\uc838\uc788\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \ubb38\uc81c\uc5d0 \uc9c1\uba74\ud588\uc744 \uacbd\uc6b0 \ud574\ub2f9 \uc18c\ud504\ud2b8 [...]
+upnp.ignorebaddevices=\uc62c\ubc14\ub85c \uc751\ub2f5\ud558\uc9c0 \uc54a\ub294 \uc7a5\uce58 \ubb34\uc2dc
+upnp.ignorebaddevices.info=\ud604\uc7ac \ubb34\uc2dc\ub41c \uc7a5\uce58: %1
+upnp.ignorebaddevices.reset=\ubb34\uc2dc\ub41c \uc7a5\uce58 \ubaa9\ub85d \ucd08\uae30\ud654
 upnp.ignorebaddevices.reset.action=\ucd08\uae30\ud654
+upnp.ignorebaddevices.alert=%1 \uc704\uce58\uc5d0 \uc788\ub294 UPnP \uc7a5\uce58\uac00 \ubc18\ubcf5\uc801\uc778 \uc2e4\ud328\ub97c \ubcf4\uace0\ud574\uc11c \ud574\ub2f9 \uc7a5\uce58\uac00 \ubb34\uc2dc\ub418\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \ub3d9\uc791\uc5d0 \ub300\ud55c UPnP \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \uc635\uc158\uc744 \ucc38\uace0 \ubc14\ub78d\ub2c8\ub2e4.
+TorrentOptionsView.param.max.uploads.when.busy=KB/s \uc804\uc5ed \uc5c5\ub85c\ub4dc \uc81c\ud55c\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 [0: \ube44\ud65c\uc131]
+UpdateMonitor.messagebox.verification.failed.title=\uc124\uce58 \uac80\uc99d \uc2e4\ud328
+UpdateMonitor.messagebox.verification.failed.text='%1' \uac80\uc99d \uc2e4\ud328: %2
+UpdateMonitor.messagebox.accept.unverified.title=\uac80\uc99d\ub418\uc9c0 \uc54a\uc740 \uc124\uce58 \ud5c8\ub77d
+UpdateMonitor.messagebox.accept.unverified.text='%1'\uac00 \uacf5\uc2dd Vuze \ud50c\ub7ec\uadf8\uc778\uc778\uc9c0 \uac80\uc99d\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uc774\ub7f0 \ud50c\ub7ec\uadf8\uc778\uc5d0 \ub300\ud574\uc11c\ub294 \uacc4\uc18d \ud558\uc2dc\uba74 *\uc548 \ub429\ub2c8\ub2e4*.\n\uc124\uce58\ub97c \uacc4\uc18d \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
 FileView.BlockView.title=\ud30c\uc77c \uc870\uac01
 FileView.BlockView.Done=\uc644\ub8cc
 FileView.BlockView.Skipped=\ubb34\uc2dc\ub428
 FileView.BlockView.Active=\ud65c\uc131
-ConfigView.label.maxuploadswhenbusymin=\ubc14\uc05c \uc0c1\ud669\uc5d0 \ud1a0\ub7f0\ud2b8\ubcc4 \ucd5c\ub300 \uc62c\ub9ac\uae30 \uc18d\ub3c4 [\ucd08]
-DownloadManager.error.badsize=\ubd80\uc815\ud655\ud55c \ud06c\uae30
-ConfigView.filter=\uac80\uc0c9 \uc120\ud0dd\uc0ac\ud56d \uc124\uc815
-ConfigView.section.file.defaultdir.section=\uae30\ubcf8 \ud3f4\ub354 \uc120\ud0dd\uc0ac\ud56d
-ConfigView.section.file.config.currentdir=\uae30\uc874 \uc120\ud0dd\uc0ac\ud56d \ud3f4\ub354:
-Tracker.announce.ignorePeerSeed=\ub3d9\ub8cc/\uc528\uc557 \ud69f\uc218 \ubb34\uc2dc. %1
+FileView.BlockView.Outstanding=\ubbf8\uc644\uc131
+ConfigView.label.tcplistenport=\ub4e4\uc5b4\uc624\ub294 TCP \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8
+ConfigView.label.udplistenport=UDP \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8
+upnp.portchange.alert=\ub2e4\uc74c \ud3ec\ud2b8\ub294 UPnP \uc7a5\uce58 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ubcc0\uacbd\ub418\uc5c8\uc2b5\ub2c8\ub2e4: %1 [\uc774\uc804 \ud3ec\ud2b8=%2] %3 [\uc774\uc804 \ud3ec\ud2b8=%4]
+ConfigView.section.proxy.username.info=\uc778\uc99d\uc744 \uc694\uad6c\ud558\uc9c0 \uc54a\uc74c\uc73c\ub85c \uc124\uc815\ud588\uc5b4\ub3c4 \ud504\ub85d\uc2dc \uc11c\ubc84\uac00 \uc778\uc99d\uc744 \uc694\uad6c\ud558\ub294 \uacbd\uc6b0,\n"<none>" \ubb38\uc790\uc5f4\uc744 \uc0ac\uc6a9\uc790 \uc774\ub984\uc73c\ub85c \uc0ac\uc6a9
+ConfigView.label.maxuploadswhenbusymin=\ud1a0\ub80c\ud2b8 \ubcc4\ub85c \uc124\uc815\ud55c \ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub294 \ub2e4\uc74c \uc2dc\uac04 \uc774\uc0c1\n\ucd5c\ub300 \uc18d\ub3c4\uac00 \uc9c0\uc18d\ub418\uba74 \uc801\uc6a9 [\ucd08]
+MainWindow.menu.help.debug=\ub514\ubc84\uadf8 \uc815\ubcf4 \uc0dd\uc131 (\ucda9\ub3cc \ub85c\uadf8)
+DownloadManager.error.badsize=\uc798\ubabb\ub41c \ud06c\uae30
+natpmp.info=NAT-PMP\ub294 Apple \uc0ac\uc758 UPnP \ub300\uccb4 \uae30\uc220\uc774\uba70 \ucd5c\uc2e0 Airport \uc2a4\ud14c\uc774\uc158\uc5d0\uc11c \uc9c0\uc6d0\ub429\ub2c8\ub2e4.\n\nNAT-PMP \uc7a5\uce58\ub97c \ud2b9\uc218\ud55c \uc885\ub958\uc758 UPnP \uc7a5\uce58\ub85c \uc778\uc2dd\ud558\ub3c4\ub85d NAT-PMP\ub97c \ud65c\uc131\ud654\ud558\ub3c4\ub85d \ud604\uc7ac UPnP\ub97c \ud65c\uc131\ud654 \ud574\uc57c\ud55c\ub2e4\ub294 \uc810\uc744 \uc8fc\uc758\ud574\uc57c \ud569\ub2c8\ub2e4.
+natpmp.enable=\ud65c\uc131\ud654 (\ud6a8\ub825\uc744 \uac00\uc9c0\ub3c4\ub85d \ud558\ub824\uba74 Airport \uc124\uc815\uc5d0\uc11c\ub3c4 \uac19\uc774 \ud65c\uc131\ud654 \ud574\uc57c\ud569\ub2c8\ub2e4)
+ConfigView.section.tracker.host.addurls=\ud574\ub2f9 \ud2b8\ub798\ucee4\uc758 URL\uc774 \ud638\uc2a4\ud2b8 \ud558\uace0 \uc788\ub294 \ud1a0\ub79c\ud2b8\uc5d0 \ub4e4\uc5b4\uc788\ub294 \uac83\uc774 \ub9de\ub294\uc9c0 \ud655\uc778
+ConfigView.filter=\uac80\uc0c9 \uc635\uc158
+ConfigView.section.files.move=\uc644\ub8cc \uc774\ub3d9
+ConfigView.section.file.defaultdir.section=\uae30\ubcf8 \ub514\ub809\ud130\ub9ac \uc635\uc158
+ConfigView.section.file.defaultdir.auto=\uc790\ub3d9\uc73c\ub85c \uae30\ubcf8 \ub514\ub809\ud130\ub9ac\uc5d0 \ub2e4\uc6b4\ub85c\ub4dc (\ubb3c\uc5b4\ubcf4\uc9c0 \uc54a\uc74c)
+ConfigView.section.file.defaultdir.bestguess=\uae30\ubcf8 \uc800\uc7a5 \ub514\ub809\ud130\ub9ac\ub97c \uc120\ud0dd\ud560 \ub54c \uac00\uc7a5 \uc801\uc808\ud55c \ucd94\uc815\uac12\uc744 \uc0ac\uc6a9
+ConfigView.section.file.defaultdir.ask=\uae30\ubcf8 \ub514\ub809\ud130\ub9ac:
+ConfigView.section.file.defaultdir.lastused=\uae30\ubcf8 \ub514\ub809\ud130\ub9ac\ub97c \ub9c8\uc9c0\ub9c9\uc5d0 \uc800\uc7a5\ud55c \uc704\uce58\ub85c \uc5c5\ub370\uc774\ud2b8
+ConfigView.section.file.config.section=\uc124\uc815
+ConfigView.section.file.config.currentdir=\ud604\uc7ac \uc124\uc815 \ub514\ub809\ud130\ub9ac:
+ConfigView.section.torrent.decoding=\ub514\ucf54\ub529 \ubb38\uc790 \uc138\ud2b8
+ConfigView.section.logging.udptransport=\uc790\uc138\ud55c UDP \uc804\uc1a1 \ucd94\uc801 \ud65c\uc131\ud654
+Tracker.announce.ignorePeerSeed=\ud53c\uc5b4/\uc2dc\ub4dc \uc218 \ubb34\uc2dc. %1
+ConfigView.section.connection.encryption.use_crypto_port=\ub4e4\uc5b4\uc624\ub294 \ub2e8\uc21c \uc5f0\uacb0 \uc2dc\ub3c4\ub97c \ub9c9\uc73c\ub824\uba74 '\uc554\ud638\ud654 \ud3ec\ud2b8' \ud2b8\ub798\ucee4 \ud655\uc7a5\uc744 \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624. \n\uc5b4\ub5a4 \ud2b8\ub798\ucee4\ub294 \uc774 \ud655\uc7a5\uc744 \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc73c\uba70 "\uc798\ubabb\ub41c \ud3ec\ud2b8" \ub610\ub294 "\ubd80\uc801\uc808\ud55c \uc778\uc218"\uc640 \uac19\uc740 \n\uc624\ub958 [...]
+TorrentOptionsView.param.reset.to.default=\uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815 \uc635\uc158\uc744 \ub418\ub3cc\ub9bc
 TorrentOptionsView.param.reset.button=\ucd08\uae30\ud654
-ConfigView.section.connection.tcp.enable=TCP \uc791\ub3d9
-ConfigView.section.connection.udp.enable=UDP \uc791\ub3d9
-ConfigView.section.style.showiconbar=\ub3c4\uad6c \ud45c\uc2dc\uc904 \ubcf4\uae30
-MainWindow.menu.view.iconbar=\ub3c4\uad6c \ud45c\uc2dc\uc904
-MyTorrentsView.menu.rename=\uc774\ub984\ubc14\uafb8\uae30
-MyTorrentsView.menu.rename.displayed=\ubcf4\uc774\ub294 \uc774\ub984\ubc14\uafb8\uae30
-MyTorrentsView.menu.rename.displayed.enter.title=\ubcf4\uc774\ub294 \uc774\ub984\ubc14\uafb8\uae30
-MyTorrentsView.menu.edit_comment=\ub367\ub9d0 \uc218\uc815
-MyTorrentsView.menu.edit_comment.enter.title=\ub367\ub9d0 \uc218\uc815
-MyTorrentsView.menu.edit_comment.enter.message=\ub0b4\ub824\ubc1b\uae30 \uc790\ub8cc\uc5d0 \ub367\ub9d0\uc744 \uc785\ub825 \ud569\ub2c8\ub2e4.
-UIDebugGenerator.messageask.title=\uc624\ub958\uc7a1\uc774 \ucd94\uc801\uae30
-UIDebugGenerator.complete.title=\uc624\ub958\uc7a1\uc774 \ucd94\uc801 \uc644\ub8cc
-authenticator.savepassword=\uc554\ud638 \uc800\uc7a5
-ConfigView.section.security.clearpasswords=\uae30\uc5b5\ud558\uace0 \uc788\ub294 \uc554\ud638 \ucd08\uae30\ud654
+natpmp.routeraddress=\uc2a4\ud14c\uc774\uc158 \uc8fc\uc18c [\ube48\uce78: \uc790\ub3d9]
+ConfigView.section.style.disableAlertSliding=\uc2ac\ub77c\uc774\ub529 \uc560\ub2c8\uba54\uc774\uc158/\uacbd\ubcf4 \uba54\uc2dc\uc9c0\uc758 \ub9e8 \uc704\ucabd \uc2a4\ud0c0\uc77c\uc744 \ube44\ud65c\uc131\ud654
+ConfigView.section.transfer.autospeed.maxinc=\uc0ac\uc774\ud074 \ub9c8\ub2e4 %1 \ucd5c\ub300 \uc99d\uac00
+ConfigView.section.transfer.autospeed.maxdec=\uc0ac\uc774\ud074 \ub9c8\ub2e4 %1 \ucd5c\ub300 \uac10\uc18c
+ConfigView.section.transfer.autospeed.enabledownadj=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc870\uc815 \ud65c\uc131\ud654
+ConfigView.section.transfer.autospeed.downadjratio=\ub2e4\uc6b4\ub85c\ub4dc : \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \ube44\uc728\n(\uc608: 2.0 \uc774\uba74 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc774 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc758 \ub450 \ubc30\uc785\ub2c8\ub2e4.)
+ConfigView.section.transfer.autospeed.latencyfactor=\uc18d\ub3c4 \ubcc0\uacbd\uc744 \uc704\ud55c \uc5f0\uacb0 \uc9c0\uc5f0 \ubcc0\uacbd\uc5d0 \uc0ac\uc6a9\ub418\ub294 \ubc30\uc218\n(\ud070 \uc218\uac00 \uc785\ub825 \ub420\uc218\ub85d \uac10\ub3c4\uac00 \ub5a8\uc5b4\uc9d0)
+ConfigView.section.transfer.autospeed.reset=\uace0\uae09 \uac12 \ucd08\uae30\ud654
+ConfigView.section.transfer.autospeed.reset.button=\ucd08\uae30\ud654
+PeerColumn.activationCount=\ud53c\uc5b4\uac00 \uc5f0\uacb0\uc744 \uc2dc\ub3c4 \uc911: %1
+TableColumn.header.timesincedownload.info=\ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud55c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc774\ub904\uc9c0\uace0 \ub098\uc11c\ubd80\ud130 \uacbd\uacfc\ub41c \uc2dc\uac04\uc785\ub2c8\ub2e4.
+TableColumn.header.timesincedownload=\ub2e4\uc6b4 \uc720\ud734
+TableColumn.header.timesinceupload.info=\ud1a0\ub80c\ud2b8\uc5d0 \ub300\ud55c \uc5c5\ub85c\ub4dc\uac00 \uc774\ub904\uc9c0\uace0 \ub098\uc11c\ubd80\ud130 \uacbd\uacfc\ub41c \uc2dc\uac04\uc785\ub2c8\ub2e4.
+TableColumn.header.timesinceupload=\uc5c5 \uc720\ud734
+PeersView.incomingreqcount=\ub4e4\uc5b4\uc624\ub294 \uc694\uccad
+PeersView.incomingreqcount.info=\ud53c\uc5b4\uc5d0 \uc758\ud55c \ub4e4\uc5b4\uc624\ub294 \uc694\uccad \uc218
+PeersView.outgoingreqcount=\ub098\uac00\ub294 \uc694\uccad
+PeersView.outgoingreqcount.info=\ud53c\uc5b4\uc5d0 \ub300\ud55c \ub098\uac00\ub294 \uc694\uccad \uc218
+upnp.mapping.trackerclientudp=UDP \ud2b8\ub798\ucee4 \ud074\ub77c\uc774\uc5b8\ud2b8 \ud3ec\ud2b8
+upnp.mapping.dhtudp=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4
+ConfigView.section.connection.nondata.udp.same=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 UDP \ud2b8\ub798\ucee4\uc5d0 \uac19\uc740 UDP \ud3ec\ud2b8\ub97c \uc0ac\uc6a9
+ConfigView.section.connection.tcp.enable=TCP \ud65c\uc131\ud654
+ConfigView.section.connection.udp.enable=UDP \ud65c\uc131\ud654
+ConfigView.section.style.showiconbar=\ub3c4\uad6c\ubaa8\uc74c \ubcf4\uc5ec\uc8fc\uae30
+MainWindow.menu.view.iconbar=\ub3c4\uad6c\ubaa8\uc74c
+MyTorrentsView.menu.rename=\uc774\ub984 \ubc14\uafb8\uae30...
+MyTorrentsView.menu.rename.displayed=\ud45c\uc2dc\ub41c \uc774\ub984 \ubc14\uafb8\uae30
+MyTorrentsView.menu.rename.save_path=\uc800\uc7a5 \uacbd\ub85c \ubc14\uafb8\uae30
+AdvRenameWindow.title=\ub2e4\uc6b4\ub85c\ub4dc \uc774\ub984 \ubc14\uafb8\uae30
+AdvRenameWindow.message=\uc774 \ub2e4\uc6b4\ub85c\ub4dc\uc5d0 \ub300\ud55c \uc0c8 \uc774\ub984\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624.
+AdvRenameWindow.rename.torrent=\ud1a0\ub80c\ud2b8 \uc774\ub984 \ubc14\uafb8\uae30
+MyTorrentsView.menu.rename.displayed.enter.title=\ud45c\uc2dc\ub418\ub294 \uc774\ub984 \ubc14\uafb8\uae30
+MyTorrentsView.menu.rename.displayed.enter.message=\uc774 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \ud45c\uc2dc\ud560 \uc0c8 \uc774\ub984 \uc785\ub825
+MyTorrentsView.menu.edit_comment=\uc8fc\uc11d \uc218\uc815
+MyTorrentsView.menu.edit_comment.enter.title=\uc8fc\uc11d \ud3b8\uc9d1
+MyTorrentsView.menu.edit_comment.enter.message=\uc774 \ub2e4\uc6b4\ub85c\ub4dc\uc5d0 \ub300\ud55c \uc8fc\uc11d \uc785\ub825
+UIDebugGenerator.messageask.title=\ub514\ubc84\uadf8 \uc0dd\uc131\uae30
+UIDebugGenerator.messageask.text=\ubcf4\uace0\ud558\ub824\ud558\ub294 \ubc84\uadf8\uc5d0 \ub300\ud55c \uc124\uba85\uc744 \uc785\ub825\ud558\uc2ed\uc2dc\uc624
+UIDebugGenerator.complete.title=\ub514\ubc84\uadf8 \uc0dd\uc131 \uc644\ub8cc
+UIDebugGenerator.complete.text=\ub514\ubc84\uadf8 \ud30c\uc77c\uc740 '%1'\uc5d0\uc11c \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\n\uc774 \ud30c\uc77c\uc744 \ud30c\uc77c \uc2dc\uc2a4\ud15c \ucc3d\uc5d0 \uc5f4\ub824\uba74 \ud655\uc778\uc744 \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.style.showProgramIcon=\uc774\ub984 \uc5f4\uc5d0 \ud504\ub85c\uadf8\ub7a8 \uc544\uc774\ucf58 \ubcf4\uc5ec\uc8fc\uae30
+ConfigView.section.style.showProgramIcon.tooltip=\ubcc0\uacbd \uc0ac\ud56d\uc774 \ud6a8\ub825\uc744 \uac00\uc9c0\ub3c4\ub85d \ud558\uae30\uc704\ud574 \ubcf4\uae30\ub97c \ub2e4\uc2dc \uc5f4 \ud544\uc694\uac00 \uc788\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+swt.alert.cant.update=SWT \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 "%3"\uc5d0\uc11c \uc801\uc7ac\ub418\uc5c8\uc73c\uba70 %1\uc5d0\uc11c %2\uc73c\ub85c \uc790\ub3d9 \ubc84\uc804 \uc5c5\ub370\uc774\ud2b8\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. ("%4"\uc5d0\uc11c \uc801\uc7ac\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4) \uc790\uc138\ud55c \uc0ac\ud56d\uc5d0 \ub300\ud574\uc11c\ub294 <A HREF="http://wiki.vuze.com/w/SWT_Cant_Auto_Update">Wiki</A>\ub97c \ucc38\uace0 \ubc14\ub78d\ub2c8\ub2e4.
+authenticator.savepassword=\ub0b4 \uc554\ud638 \uae30\uc5b5
+ConfigView.section.security.clearpasswords=\uae30\uc5b5\ub41c \uc554\ud638 \ucd08\uae30\ud654
 ConfigView.section.security.clearpasswords.button=\ucd08\uae30\ud654
-Content.alert.notuploaded.title=\uc62c\ub9ac\uae30\uac00 \ub05d\ub098\uc9c0 \uc54a\uc558\uc74c
-Content.alert.notuploaded.text='%1'\ub294 \uc62c\ub9ac\uae30\uac00 \ub05d\ub098\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. %2\ub97c \uc9c0\uae08 \ud558\uba74\uc740 \uc0ac\ub78c\ub4e4\uc774 \ub0b4\uac00 \ucd9c\ud310\ud55c \ub0b4\uc6a9\uc744 \uc644\uc804\ud788 \ub0b4\ub824\ubc1b\uc9c0 \ubabb \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \n\n\uadf8\ub798\ub3c4 %2\ub97c \ud560\uae4c\uc694?
-Content.alert.notuploaded.multi.title=\uc62c\ub9ac\uae30\uac00 \ub05d\ub098\uc9c0 \uc54a\uc558\uc74c
-Content.alert.notuploaded.stop=\uba48\ucda4
-Content.alert.notuploaded.quit=Vuze \uc885\ub8cc
-ConfigView.label.popup.autohide=\uc624\ub958 \uc54c\ub9bc\uc774 \uc544\ub2cc\uacbd\uc6b0 x\ucd08\ud6c4 \uc790\ub3d9\uc73c\ub85c \ud31d\uc5c5\ucc3d \uc228\uae30\uae30 (0\uc73c\ub85c \uc124\uc815\uc2dc \uc790\ub3d9 \uc228\uae30\uae30 \uc791\ub3d9\uc548\ud568)
-ConfigView.label.popup.show=\uae30\ub85d\ub418\ub294 \uc54c\ub9bc \ubcf4\uc5ec\uc8fc\uae30
-ConfigView.label.popup.show.button=\ubcf4\uae30
-ConfigView.label.please.visit.here=\uc790\uc138\ud55c \ub0b4\uc6a9\uc744 \uc54c\uace0\uc2f6\uc73c\uba74 \uc774\uacf3\uc744 \ubc29\ubb38\ud574 \uc8fc\uc138\uc694
-ConfigView.label.openmytorrents=\uc2dc\uc791\uc2dc '\ub0b4 \ud1a0\ub7f0\ud2b8' \uc5f4\uae30
-ConfigView.label.open_transfer_bar_on_start=\uc2dc\uc791\uc2dc \uc804\uc1a1 \ud45c\uc2dc\uc904 \uc5f4\uae30
-OpenTorrentWindow.mb.notValid.title=\ud1a0\ub7f0\ud2b8 \uc5f4\uae30
-OpenTorrentWindow.mb.notTorrent.title=\ud1a0\ub7f0\ud2b8 \uc5f4\uae30
-ConfigView.label.pause.downloads.on.exit=Vauz\ub97c \ub098\uac08\ub54c \ub0b4\ub824\ubc1b\uae30 \uc911\uc9c0
-UIDebugGenerator.message.cancel.title=\uc624\ub958\uc7a1\uc774 \uc815\ubcf4 \ucd94\uc801 \ucde8\uc18c
-ConfigView.section.connection.http.enable=\uc791\ub3d9
+TorrentInfoView.torrent.encoding=\ud1a0\ub80c\ud2b8 \uc778\ucf54\ub529
+TorrentInfoView.columns='\ub0b4 \ud1a0\ub80c\ud2b8' \ubcf4\uae30\uc758 \uc5f4
+progress.window.title=\uc791\uc5c5 \uc9c4\ud589 \uc911
+progress.window.msg.filemove=\ud30c\uc77c \uc774\ub3d9/\uc774\ub984 \ubc14\uafb8\uae30\uac00 \uc644\ub8cc\ub418\ub294 \ub3d9\uc548 \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc624
+ConfigView.label.popup.timestamp=\ud31d\uc5c5 \uacbd\ubcf4\uc5d0 \ud0c0\uc784\uc2a4\ud0ec\ud504 \ucd94\uac00
+ConfigView.label.popup.autohide=\uc624\ub958\uc544\ub2cc \ud31d\uc5c5 \uacbd\ubcf4\ub294 x\ucd08 \ud6c4 \uc790\ub3d9\uc73c\ub85c \uc228\uae40 (0\uc73c\ub85c \uc124\uc815\ud558\uba74 \uc790\ub3d9 \uc228\uae40 \ube44\ud65c\uc131\ud654)
+ConfigView.label.please.visit.here=\uc138\ubd80\uc0ac\ud56d\uc5d0 \ub300\ud574\uc11c\ub294 \uc5ec\uae30\ub97c \ubc29\ubb38\ud574\uc8fc\uc2ed\uc2dc\uc624
+ConfigView.section.ipfilter.enable.descriptionCache=\uc2a4\ud06c\ub798\uce58 \ud30c\uc77c \uc548\uc5d0 IP \uc124\uba85 \uc800\uc7a5
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\ube44\ud65c\uc131\ud654 \ub418\uba74 \uc124\uba85\uc740 \uc9c0\uc6cc\uc9d0
+OpenTorrentWindow.filesInfo=%2 \uc911 %1 \ub2e4\uc6b4\ub85c\ub4dc \ub429\ub2c8\ub2e4.
+OpenTorrentWindow.diskUsage=%2 \uc911 %1
+ConfigView.label.openmytorrents=\uc2dc\uc791 \uc2dc '\ub0b4 \ud1a0\ub80c\ud2b8' \uc5f4\uae30
+ConfigView.label.open_transfer_bar_on_start=\uc2dc\uc791 \uc2dc \uc804\uc1a1 \ub9c9\ub300 \uc5f4\uae30
+ConfigView.section.style.DNDalwaysInIncomplete='\ub2e4\uc6b4\ub85c\ub4dc \ud558\uc9c0 \uc54a\uc74c' \ud30c\uc77c\uc774 \uc788\ub294 \ud1a0\ub80c\ud2b8\ub294 \ud56d\uc0c1 \ub0b4 \ud1a0\ub80c\ud2b8\uc758 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc74c \uc139\uc158\uc5d0 \ubcf4\uc5ec\uc8fc\uae30
+OpenTorrentWindow.mb.noGlobalDestDir.title=\ub300\uc0c1 \ub514\ub809\ud130\ub9ac\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc74c
+OpenTorrentWindow.mb.noGlobalDestDir.text=\ub300\uc0c1 \ub514\ub809\ud130\ub9ac '%1'\ub294 \uc798\ubabb\ub428
+OpenTorrentWindow.mb.noDestDir.title=\ub300\uc0c1 \ub514\ub809\ud130\ub9ac\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc74c
+OpenTorrentWindow.mb.noDestDir.text=\ud1a0\ub80c\ud2b8 '%2'\uc5d0 \ub300\ud55c \ub300\uc0c1 \ub514\ub809\ud130\ub9ac '%1'\ub294 \uc874\uc7ac\ud558\uc9c0 \uc54a\uac70\ub098 \uc62c\ubc14\ub974\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+OpenTorrentWindow.mb.notValid.title=\ud1a0\ub80c\ud2b8 \uc5f4\uae30 \uc2e4\ud328
+OpenTorrentWindow.mb.notValid.text='%1' \ud1a0\ub80c\ud2b8\ub97c \uc5f4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ubc30\ud3ec \ubaa8\ub4dc\ub97c \ud574\ub2f9 \ud30c\uc77c\uc744 \uc5f4\uc5c8\ub2e4\uba74, \ud1a0\ub80c\ud2b8 \ub370\uc774\ud130 \ud30c\uc77c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0\ub97c \ud655\uc778\ud558\uc2ed\uc2dc\uc624.
+OpenTorrentWindow.mb.notTorrent.title=\ud1a0\ub80c\ud2b8 \uc5f4\uae30 \uc2e4\ud328
+OpenTorrentWindow.mb.notTorrent.text='%1' \uc5f4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ud574\ub2f9 \ud30c\uc77c\uc740 .torrent \ud30c\uc77c\uc774 \uc544\ub2cc \uac83\uc73c\ub85c \ubcf4\uc785\ub2c8\ub2e4.\n\n\uc218\uc2e0\ud55c \ub370\uc774\ud130\uc758 \uc77c\ubd80:\n%2
+ConfigView.label.pause.downloads.on.exit=\ub098\uac08 \ub54c \ub2e4\uc6b4\ub85c\ub4dc \uc77c\uc2dc\uc815\uc9c0
+ConfigView.label.resume.downloads.on.start=\ucd08\uae30\ud654\uac00 \uc644\ub8cc\ub418\uba74 \uc2dc\uc791 \uc2dc \uc77c\uc2dc\uc815\uc9c0 \ub41c \ub2e4\uc6b4\ub85c\ub4dc \ub2e4\uc2dc \uc2dc\uc791
+UIDebugGenerator.message.cancel.title=\ub514\ubc84\uadf8 \uc815\ubcf4 \uc0dd\uc131 \ucde8\uc18c
+UIDebugGenerator.message.cancel.text=\ubcf4\uace0\ud558\ub824\ub294 \ubc84\uadf8\uc5d0 \ub300\ud55c \uc124\uba85\uc744 \uc785\ub825\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.  \uc0ac\uc6a9\uc790 \ubcf8\uc778\uc5d0\uac8c\ub294 \ubc84\uadf8\uac00 \uba85\ubc31\ud560\uc9c0 \ubab0\ub77c\ub3c4 \uc124\uba85\uc774 \uc5c6\uc73c\uba74 \uc6b0\ub9ac\ub294 \ubb38\uc81c\ub97c \uc720\ucd94\ud560 \uc218\ubc16\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.\n\n\ub514\ubc84\uadf8 \uc815\ubcf4 \uc0dd\uc131\uc774 \ucde8\u [...]
+ConfigView.section.connection.group.http.info=HTTP \ubc30\ud3ec\uc5d0 \ub300\ud55c \uc9c0\uc6d0\uc785\ub2c8\ub2e4.
+ConfigView.section.connection.http.enable=\ud65c\uc131\ud654
 ConfigView.section.connection.http.port=\ub4e4\uc5b4\uc624\ub294 \ud3ec\ud2b8 \ubc88\ud638
-window.update.noupdates.title=\uc5c5\ub370\uc774\ud2b8 \uacb0\uacfc\ud655\uc778
-window.update.noupdates.text=\uc0c8\ub85c\uc6b4 \uc5c5\ub370\uc774\ud2b8\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
-ConfigView.label.mindownloads=\ucd5c\uc18c \ub3d9\uc2dc \ub0b4\ub824\ubc1b\uae30
+ConfigView.section.connection.http.portoverride=\ud2b8\ub798\ucee4 HTTP \ud3ec\ud2b8 \uc6b0\uc120\uc801\uc6a9 [0: \uc5c6\uc74c]
+window.update.noupdates.title=\uc5c5\ub370\uc774\ud2b8 \uacb0\uacfc \uac80\uc0ac
+window.update.noupdates.text=\uc0c8\ub85c\uc6b4 \uc5c5\ub370\uc774\ud2b8\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.\n\n\ucd95\ud558\ud569\ub2c8\ub2e4!
+ConfigView.label.bindip.details=\uc608: 192.168.1.5;eth0;eth1[2]\uc744 \uc785\ub825\ud558\uba74 \ud2b9\uc815 IP, \uccab\ubc88\uc9f8 \uc778\ud130\ud398\uc774\uc2a4\uc758 \ubaa8\ub4e0 IP \uadf8\ub9ac\uace0 2\ubc88\uc9f8 \uc778\ud130\ud398\uc774\uc2a4\uc758 3\ubc88\uc9f8 IP\uc5d0 \ubc14\uc778\ub4dc\ud558\uac8c \ub429\ub2c8\ub2e4.\n\uccab\ubc88\uc9f8 IP\ub294 \ubaa8\ub4e0 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uac8c \ub418\uba70, \uadf8 \uc774\uc678\uc758 \ubaa8\ub4e0 IP\ub294 \ubd80\ud [...]
+ConfigView.label.mindownloads=\ucd5c\uc18c \ub3d9\uc2dc \ub2e4\uc6b4\ub85c\ub4dc
 UI.cannot_submit_blank_text=\uac12\uc744 \uc785\ub825\ud558\uc154\uc57c \ud569\ub2c8\ub2e4.
+crypto.alert.as.warning=\ub124\ud2b8\uc6cc\ud06c '%1'\uc740 \ub2e4\uc6b4\ub85c\ub4dc \uc131\uc99d\uc744 \uac10\uc18c \uc2dc\ud0a4\uae30 \uc704\ud574 \ud2b8\ub798\ud53d\uc744 \uc81c\ud55c\ud558\ub294 \uac83\uc73c\ub85c \uc54c\ub824\uc838 \uc788\uc2b5\ub2c8\ub2e4.\n\uc804\uc1a1 \uc554\ud638\ud654\uac00 \uc790\ub3d9\uc73c\ub85c \ucf1c\uc84c\uc2b5\ub2c8\ub2e4 - \uc774 \uc635\uc158\uc740 \uc124\uc815 \ub9e4\uac1c\ubcc0\uc218\ub97c \ud1b5\ud574 \ub044\uac70\ub098/\uc218\uc815\ud560 \uc218 \uc7 [...]
 ConfigView.section.interface.alerts=\uacbd\uace0
+ConfigView.label.popupdownloadadded=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \ucd94\uac00\ub418\uba74 \uacbd\ubcf4\ub97c \ud31d\uc5c5
+popup.download.added=\ub2e4\uc6b4\ub85c\ub4dc \ubaa9\ub85d\uc5d0 "%1"\uc774 \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
 MessageBoxWindow.nomoreprompting=\ub2e4\uc2dc \ubcf4\uc5ec\uc8fc\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+TorrentOptionsView.param.max.seeds=\uc2dc\ub4dc \uc5f0\uacb0\uc758 \ucd5c\ub300 \uac2f\uc218 [0: \uc5f0\uacb0 \uc81c\ud55c]
+TorrentOptionsView.param.alternative.value.enable=\ubc30\ud3ec \uc2dc \ub300\uccb4 \uac12
+ConfigView.section.proxy.check.on.start=\uc2dc\uc791 \uc2dc \ud504\ub85d\uc2dc \uc0c1\ud0dc \uac80\uc0ac
 TransferStatsView.legend.pingaverage=\ud3c9\uade0
-TransferStatsView.legend.ping1=\ubaa9\ud45c 1
-TransferStatsView.legend.ping2=\ubaa9\ud45c 2
-TransferStatsView.legend.ping3=\ubaa9\ud45c 3
-ConfigView.label.closetotray._mac=\ucd5c\uc18c\ud654 \ud560\ub54c \uc0c1\ud0dc \ud45c\uc2dc\uc904 \uc544\uc774\ucf58\uc73c\ub85c
-splash.unloadingTorrents=\ud1a0\ub7f0\ud2b8 \uc62c\ub9ac\uae30 \uc911
-splash.unloadingTorrent=\ud1a0\ub7f0\ud2b8 \uc62c\ub9ac\uae30 \uc911
-alert.raised.at.close=(Vuze\uac00 \ub9c8\uc9c0\ub9c9 \uc2e4\ud589 \ub418\uc5c8\uc744\ub54c \uc54c\ub9bc)
-Peers.column.maxupspeed=\uc5c5\uc18d\ub3c4 \ucd5c\ub300\uac12
-Peers.column.maxdownspeed=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 \ucd5c\ub300\uac12
-MyTorrents.items.DownSpeedLimit.disabled=\ub0b4\ub824\ubc1b\uae30 \uc5c6\uc74c
+TransferStatsView.legend.ping1=\ud45c\uc801 1
+TransferStatsView.legend.ping2=\ud45c\uc801 2
+TransferStatsView.legend.ping3=\ud45c\uc801 3
+ConfigView.section.interface.enabletray._mac=\uc0c1\ud0dc \ub9c9\ub300 \uc544\uc774\ucf58 \ud65c\uc131\ud654 [\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
+ConfigView.label.closetotray._mac=\ub2eb\uc73c\uba74 \uc0c1\ud0dc \ud45c\uc2dc\uc904 \uc544\uc774\ucf58\uc73c\ub85c \ucd5c\uc18c\ud654
+ConfigView.label.minimizetotray._mac=\ucd5c\uc18c\ud654 \uc2dc \uc0c1\ud0dc \ud45c\uc2dc\uc904 \uc544\uc774\ucf58\uc73c\ub85c \ucd5c\uc18c\ud654
+OpenTorrentWindow.mb.existingFiles.title=\ud30c\uc77c\uc774 \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4!
+OpenTorrentWindow.mb.existingFiles.text=\uc9c0\uc815\ud55c \ub300\uc0c1 \ud3f4\ub354\uc5d0 \uc77c\ubd80 \ud30c\uc77c\uc740 \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4:\n\n%1\n\uacc4\uc18d\ud558\uba74 Vuze\ub294 \uc0c1\uae30\uc758 \ud30c\uc77c\uc774 \uc62c\ubc14\ub978\uc9c0 \uac80\uc0ac\ud558\uac8c \ub418\uba70 \ud544\uc694\ud55c \uacbd\uc6b0 \ub36e\uc5b4\uc4f0\uac8c \ub429\ub2c8\ub2e4.
+splash.unloadingTorrents=\ud1a0\ub80c\ud2b8 \ub0b4\ub9ac\ub294 \uc911
+splash.unloadingTorrent=\ud1a0\ub80c\ud2b8 \ub0b4\ub9ac\ub294 \uc911
+ConfigView.section.file.defaultdir.autorename=\uacbd\ub85c\uc0c1 \ud30c\uc77c \uc774\ub984\uc774 \ub2ec\ub77c\uc57c \ud560 \uacbd\uc6b0 \ud1a0\ub80c\ud2b8 \ub370\uc774\ud130 \uc774\ub984\uc744 \uc790\ub3d9\uc73c\ub85c \ubc14\uafb8\uae30
+ConfigView.section.file.defaultdir.autorename.tooltip=\ud30c\uc77c \uc774\ub984\uc774 \uac19\uc740 \uacbd\uc6b0 \ub2e4\ub978 \ud1a0\ub80c\ud2b8 \ud30c\uc77c\uc744 \ub36e\uc5b4 \uc4f0\ub294 \uac83\uc744 \ub9c9\uc2b5\ub2c8\ub2e4.
+alert.raised.at.close=(\uc774\uc804\uc5d0 \ub2eb\ud78c Vuze\uc758 \uba54\uc2dc\uc9c0)
+Plugin.trackerpeerauth.name=\ud2b8\ub798\ucee4 \ud53c\uc5b4 \uc778\uc99d
+Plugin.trackerpeerauth.info=\uc774 \ud50c\ub7ec\uadf8\uc778\uc740 \ud2b8\ub798\ucee4\uc640 \uac19\uc774 \ub3d9\uc791\ud574\uc11c \ud53c\uc5b4\uac00 \uc2a4\uc6dc\uc5d0\uc11c \uc720\ud6a8\ud55c\uc9c0\ub97c \uac80\uc99d\ud569\ub2c8\ub2e4.
+Peers.column.maxupspeed=\ucd5c\ub300 \uc5c5 \uc18d\ub3c4
+Peers.column.maxdownspeed=\ucd5c\ub300 \ub2e4\uc6b4 \uc18d\ub3c4
+MyTorrents.items.DownSpeedLimit.disabled=\ub2e4\uc6b4\ub85c\ub4dc \uc5c6\uc74c
+upnp.selectedaddresses=\uc8fc\uc18c (';'\ub85c \ubd84\ub9ac\ub428, '-' \uc811\ub450\ubb38\uc790=\uac70\ubd80, '+' \uc811\ub450\ubb38\uc790=\ud5c8\uc6a9) [\ube48\uce78: \uc544\ubb34\uac70\ub098]
+upnp.alert.multipledevice.warning=\uc5ec\ub7ec \uac1c\uc758 UPnP \uc7a5\uce58\uac00 \uac10\uc9c0\ub418\uc5c8\uc2b5\ub2c8\ub2e4 - \ubaa8\ub4e0 \ud544\uc694 \ud3ec\ud2b8 \ub9f5\ud551\uc744 \uac80\uc0ac\ud558\uc2ed\uc2dc\uc624 (UPnP \ub85c\uadf8\uc640 \uc124\uc815\uc744 \ucc38\uace0)
 UpdateMonitor.messagebox.restart.title=\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5c5\ub370\uc774\ud2b8
-PiecesView.BlockView.Have=\uc788\uc74c
+UpdateMonitor.messagebox.restart.text=Vuze\uac00 \ubc29\uae08 \uc911\uc694\ud55c \uc5c5\ub370\uc774\ud2b8\ub97c \ub2e4\uc6b4\ub85c\ub4dc \ud588\uc73c\uba70 \ud574\ub2f9 \uc5c5\ub370\uc774\ud2b8\uac00 \uc124\uce58\ub420 \uc218 \uc788\ub3c4\ub85d \ubc18\ub4dc\uc2dc \ub2e4\uc2dc \uc2dc\uc791\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4.
+PiecesView.BlockView.Have=\ubcf4\uc720
 PiecesView.BlockView.NoHave=\uc5c6\uc74c
-ConfigView.section.update.autodownload=\uc5c5\ub370\uc774\ud2b8\ub97c \uc790\ub3d9\uc73c\ub85c \ub0b4\ub824\ubc1b\uace0 \uc124\uce58\uc900\ube44\uac00 \ub418\uba74 \uc54c\ub9ac\uae30
-Peers.column.peer_id=\ub3d9\ub8cc ID
-Peers.column.peer_id.info=\ub3d9\ub8cc ID in readable form
-Peers.column.peer_byte_id=\ub3d9\ub8cc ID
-Peers.column.peer_byte_id.info=\ub3d9\ub8ccr ID in byte form
-ConfigView.label.openbar.incomplete=\ub0b4\ub824\ubc1b\uae30 \ud45c\uc2dc\uc904: \ub0b4\ub824\ubc1b\uae30 \uc790\ub3d9 \uc5f4\uae30
-ConfigView.label.openbar.complete=\uc528\uc557 \uc790\ub3d9\uc73c\ub85c \uc5f4\uae30
-MainWindow.menu.tools.speedtest=\uc18d\ub3c4 \uac80\uc0ac..
-speedtest.wizard.title=\uc18d\ub3c4 \uac80\uc0ac
+PiecesView.BlockView.Header=%1 \uc5f4, %2 \ud589, %3 \uc870\uac01
+ConfigView.section.update.autodownload=\uc5c5\ub370\uc774\ud2b8\ub97c \uc790\ub3d9 \ub2e4\uc6b4\ub85c\ub4dc\ud558\uace0 \uc124\uce58\uac00 \uc900\ube44\ub418\uba74 \ubb3b\uae30
+Peers.column.peer_id=\ud53c\uc5b4 ID
+Peers.column.peer_id.info=\uc77d\uc744 \uc218 \uc788\ub294 \ud615\uc2dd\uc758 \ud53c\uc5b4 ID
+Peers.column.peer_byte_id=\ud53c\uc5b4 ID
+Peers.column.peer_byte_id.info=\ubc14\uc774\ud2b8 \ud615\uc2dd\uc758 \ud53c\uc5b4 ID
+Peers.column.handshake_reserved=\uc608\uc57d\ub41c \ud578\ub4dc\uc250\uc774\ud06c \ubc14\uc774\ud2b8
+Peers.column.handshake_reserved.info=\uc608\uc57d\ub41c \ube44\ud2b8\ub294 BT \ud578\ub4dc\uc250\uc774\ud06c\uc5d0 \uc124\uc815\ub41c \uac83\uc744 \ud45c\uc2dc
+Peers.column.client_identification=\ud074\ub77c\uc774\uc5b8\ud2b8 \uc2e0\uc6d0
+Peers.column.client_identification.info=Vuze\uac00 \ubc1b\uc740 \uac00\uacf5\ub418\uc9c0 \uc54a\uc740 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc774\ub984\uc744 \ud45c\uc2dc - \ub514\ubc84\uae45\uc2dc \uc720\uc6a9
+dht.warn.user=\uc7a0\uc7ac\uc801\uc778 NAT/\ud3ec\ud2b8 \ub9f5\ud551 \ubb38\uc81c \uacbd\uace0
+ConfigView.label.openbar.incomplete=\ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300: \ub2e4\uc6b4\ub85c\ub4dc \uc790\ub3d9 \uc5f4\uae30
+ConfigView.label.openbar.complete=\uc2dc\ub4dc \uc790\ub3d9 \uc5f4\uae30
+ConfigView.label.transferbar.remember_location=\uc804\uc1a1 \ub9c9\ub300\uc758 \ub9c8\uc9c0\ub9c9 \uc704\uce58 \uae30\uc5b5
+ConfigView.section.transfer.autospeed.forcemin=%1 \uc5c5\ub85c\ub4dc \uc18d\ub3c4 \uac15\uc81c (\uae30\uc800 \uc5f0\uacb0 \uc2dc)
+MainWindow.menu.tools.speedtest=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8...
+speedtest.wizard.title=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8
 speedtest.wizard.run=\uc18d\ub3c4 \uac80\uc0ac \uc2e4\ud589
-speedtest.wizard.test.mode.updown=\uc62c\ub9ac\uae30/\ub0b4\ub824\ubc1b\uae30
-speedtest.wizard.test.mode.up=\uc62c\ub9ac\uae30
-speedtest.wizard.test.mode.down=\ub0b4\ub824\ubc1b\uae30
-SpeedTestWizard.test.panel.currinfo=\ud1a0\ub7f0\ud2b8 \ub300\uc5ed\ud3ed \uac80\uc0ac.
+speedtest.wizard.test.mode.updown=\uc5c5\ub85c\ub4dc\uc640 \ub2e4\uc6b4\ub85c\ub4dc
+speedtest.wizard.test.mode.up=\uc5c5\ub85c\ub4dc
+speedtest.wizard.test.mode.down=\ub2e4\uc6b4\ub85c\ub4dc
+SpeedTestWizard.test.panel.currinfo=BitTorrent \ub300\uc5ed\ud3ed \ud14c\uc2a4\ud2b8 \uc911\uc785\ub2c8\ub2e4.
 SpeedTestWizard.test.panel.label=Vuze \uc18d\ub3c4 \uac80\uc0ac:
-SpeedTestWizard.test.panel.already.running=\uac80\uc0ac\uac00 \uc774\ubbf8 \uc9c4\ud589\uc911\uc785\ub2c8\ub2e4.
-SpeedTestWizard.test.panel.not.accepted=\uac80\uc0ac \uc694\uccad\uc774 \uc218\ub77d\ub428: 
-SpeedTestWizard.test.panel.abort=\ucde8\uc18c
-SpeedTestWizard.test.panel.abort.countdown=\uac80\uc0ac \ucde8\uc18c:
+SpeedTestWizard.test.panel.already.running=\ud14c\uc2a4\ud2b8\uac00 \uc774\ubbf8 \uc2e4\ud589 \uc911\uc785\ub2c8\ub2e4!
+SpeedTestWizard.test.panel.not.accepted=\uac80\uc0ac \uc694\uccad\uc774 \uc218\ub77d\ub428:
+SpeedTestWizard.test.panel.abort=\uc911\ub2e8
+SpeedTestWizard.test.panel.abort.countdown=\ud14c\uc2a4\ud2b8 \uc911\ub2e8:
 SpeedTestWizard.test.panel.test.countdown=\uac80\uc0ac \uc885\ub8cc:
 SpeedTestWizard.test.panel.testfailed=\uac80\uc0ac \uc2e4\ud328
+SpeedTestWizard.test.panel.aborted=\ud14c\uc2a4\ud2b8\uac00 \uc218\ub3d9\uc73c\ub85c \uc911\ub2e8\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+SpeedTestWizard.test.panel.enc.label=\uc554\ud638\ud654 \ud14c\uc2a4\ud2b8 (\ud074\ub9ad):
 SpeedTestWizard.test.panel.standard=\uae30\ubcf8
+SpeedTestWizard.test.panel.encrypted=\uc554\ud638\ud654\ub428
 SpeedTestWizard.set.upload.button.apply=\uc801\uc6a9
 SpeedTestWizard.set.upload.result=\ub9c8\uc9c0\ub9c9 \uac80\uc0ac \uacb0\uacfc
-SpeedTestWizard.finish.panel.title=\uc18d\ub3c4 \uac80\uc0ac\uac00 \ub05d\ub0ac\uc2b5\ub2c8\ub2e4
-SpeedTestWizard.finish.panel.max.upload=\ucd5c\ub300 \uc62c\ub9ac\uae30 :
-SpeedTestWizard.finish.panel.max.seeding.upload=\ubfcc\ub9ac\ub294 \ub3d9\uc548 \ucd5c\ub300 \uc62c\ub9ac\uae30 :
-SpeedTestWizard.finish.panel.max.download=\ucd5c\ub300 \ub0b4\ub824\ubc1b\uae30 :
-SpeedTestWizard.finish.panel.enabled=\uc791\ub3d9
-SpeedTestWizard.finish.panel.disabled=\uc791\ub3d9\uba48\ucda4
+SpeedTestWizard.finish.panel.title=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8\uac00 \ub05d\ub0ac\uc2b5\ub2c8\ub2e4!
+SpeedTestWizard.finish.panel.click.close=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8 \ub9c8\ubc95\uc0ac\uac00 \ub05d\ub0ac\uc2b5\ub2c8\ub2e4. \ub098\uac00\ub824\uba74 \ub2eb\uae30\ub97c \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624.
+SpeedTestWizard.finish.panel.max.upload=\ucd5c\ub300 \uc5c5\ub85c\ub4dc :
+SpeedTestWizard.finish.panel.max.seeding.upload=\ubc30\ud3ec\ud558\ub294 \ub3d9\uc548 \ucd5c\ub300 \uc5c5\ub85c\ub4dc :
+SpeedTestWizard.finish.panel.max.download=\ucd5c\ub300 \ub2e4\uc6b4\ub85c\ub4dc :
+SpeedTestWizard.finish.panel.enabled=\ud65c\uc131\ud654\ub428
+SpeedTestWizard.finish.panel.disabled=\ube44\ud65c\uc131\ud654\ub428
+SpeedTestWizard.abort.message.scheduled.in=\ud14c\uc2a4\ud2b8\uac00 \uc608\uc57d \ub418\uc5c8\uc74c ... %1 \ucd08
+SpeedTestWizard.abort.message.unsupported.type=\uc9c0\uc6d0\ub418\uc9c0 \uc54a\ub294 \ud14c\uc2a4\ud2b8 \uc720\ud615!!!!
 SpeedTestWizard.abort.message.manual.abort=\uc218\ub3d9\uc73c\ub85c \ucde8\uc18c
-SpeedTestWizard.abort.message.failed.peers=\ubaa8\ub4e0 \ub3d9\ub8cc\uc640 \uc5f0\uacb0 \uc2e4\ud328
-SpeedTestWizard.stage.message.requesting=\uac80\uc0ac \uc694\uccad..
-SpeedTestWizard.stage.message.preparing=\uac80\uc0ac \uc900\ube44..
-SpeedTestWizard.stage.message.starting=\uac80\uc0ac \uc2dc\uc791..
-SpeedTestWizard.stage.message.connect.stats=\uc5f0\uacb0 \uc0c1\ud669 : \ub3d9\ub8cc=%1, \ub0b4\ub824\ubc1b\uae30 \uc591\ud638=%2, \uc62c\ub9ac\uae30 \uc591\ud638=%3
-window.uiswitcher.title=Vuze UI \uc120\ud0dd\ud558\uae30
+SpeedTestWizard.abort.message.scheduling.failed=\ud14c\uc2a4\ud2b8 \uc608\uc57d \uc2e4\ud328
+SpeedTestWizard.abort.message.download.added=\ud14c\uc2a4\ud2b8 \ub3c4\uc911 \ucd94\uac00\ub41c \ub2e4\uc6b4\ub85c\ub4dc %1
+SpeedTestWizard.abort.message.entered.error='%1' \uc624\ub958 \uc0c1\ud0dc\ub97c \uc785\ub825\ud55c \ub2e4\uc6b4\ub85c\ub4dc \ud14c\uc2a4\ud2b8
+SpeedTestWizard.abort.message.entered.queued=\ub300\uae30\uc5f4\ub85c \ub4e4\uc5b4\uac00\uac70\ub098/\uc815\uc9c0\ub41c \uc0c1\ud0dc\uac00 \uc785\ub825\ub41c \ub2e4\uc6b4\ub85c\ub4dc \ud14c\uc2a4\ud2b8
+SpeedTestWizard.abort.message.interrupted=TorrentSpeedTestMonitorThread\ub294 \ud14c\uc2a4\ud2b8\uac00 \uc644\ub8cc\ub418\uae30 \uc804\uae4c\uc9c0 \uc911\uc9c0
+SpeedTestWizard.abort.message.execution.failed=\ud14c\uc2a4\ud2b8 \uc2e4\ud589 \uc2e4\ud328
+SpeedTestWizard.abort.message.failed.peers=\ubaa8\ub4e0 \ud53c\uc5b4\uc640 \uc5f0\uacb0 \uc2e4\ud328
+SpeedTestWizard.abort.message.insufficient.slots=\uc5b4\ub5a4 \ud53c\uc5b4\uc5d0\uac8c\ub3c4 \uc5c5\ub85c\ub4dc \ud560 \uc218 \uc5c6\uc74c - \uc5c5\ub85c\ub4dc \uc2ac\ub86f\uc774 \ubd80\uc871\ud569\ub2c8\uae4c?
+SpeedTestWizard.abort.message.not.unchoked=\ud3ec\ud654\uac00 \ud480\ub9ac\uc9c0 \uc54a\ub294 \ud53c\uc5b4\ub85c\ubd80\ud130\ub294 \ub2e4\uc6b4\ub85c\ub4dc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+SpeedTestWizard.stage.message.requesting=\ud14c\uc2a4\ud2b8 \uc694\uccad \uc911...
+SpeedTestWizard.stage.message.preparing=\ud14c\uc2a4\ud2b8 \uc900\ube44 \uc911...
+SpeedTestWizard.stage.message.starting=\ud14c\uc2a4\ud2b8 \uc2dc\uc791 \uc911...
+SpeedTestWizard.stage.message.connect.stats=\uc5f0\uacb0 \ud1b5\uacc4: \ud53c\uc5b4=%1, \ub2e4\uc6b4_\uc815\uc0c1=%2, \uc5c5_\uc815\uc0c1=%3
+window.uiswitcher.title=Vuze UI \uc120\ud0dd\uae30
 window.uiswitcher.text=\uc544\ub798\uc5d0\uc11c \uac00\uc7a5 \uc801\ud569\ud55c \uc720\uc800 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uace0\ub974\uc138\uc694.
-window.uiswitcher.NewUI.title=Vuze \uc778\ud130\ud398\uc774\uc2a4
-window.uiswitcher.NewUI.text=* \ucc98\uc74c\uc0ac\uc6a9\uc790\uc640 \ucd08\ubcf4\uc790\uc5d0\uac8c \uad8c\uc7a5\ud569\ub2c8\ub2e4.\n\n* \uc27d\uace0 \uc9c1\uad00\uc801\uc778 \uadf8\ub798\ud53d \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.\n\n* Vuze\uac00 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\uae30\uc5d0 \uc88b\uc2b5\ub2c8\ub2e4.
-window.uiswitcher.ClassicUI.title=\ud074\ub808\uc2dd \uc778\ud130\ud398\uc774\uc2a4
-window.uiswitcher.ClassicUI.text=* 2.x \ubc84\uc804\uc758 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc720\uc9c0\ud569\ub2c8\ub2e4.\n\n* Vuze\uc758 HD \ub124\ud2b8\uc6cc\ud06c\ub4f1 \ucee8\ud150\ud2b8 \uad00\ub828 \uae30\ub2a5\uc740 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
-window.uiswitcher.bottom.text=Vuze UI \uc120\ud0dd\ud558\uae30 \ub2e8\ucd94\ub97c \ud1b5\ud574 \uc5b8\uc81c\ub4e0\uc9c0 UI\ub97c \ubc14\uafc0 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+window.uiswitcher.NewUI.text=* \ucc98\uc74c\uc0ac\uc6a9\uc790\uc640 \ucd08\ubcf4\uc790\uc5d0\uac8c \uad8c\uc7a5\ud569\ub2c8\ub2e4.\n\n* \uc27d\uace0 \uc9c1\uad00\uc801\uc778 \uadf8\ub798\ud53d \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.\n\n* Vuze \ud50c\ub7ab\ud3fc\uc5d0 \uac8c\uc2dc\ud558\ub824\ud560 \ub54c \ud544\uc694\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc785\ub2c8\ub2e4.
+window.uiswitcher.ClassicUI.title=\ud074\ub798\uc2dd \uc778\ud130\ud398\uc774\uc2a4
+window.uiswitcher.ClassicUI.text=* 2.x \ubc84\uc804\uc758 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc720\uc9c0\ud569\ub2c8\ub2e4.\n\n* Vuze\uc758 \ucf58\ud150\uce20 \uacc4\uce35\uc740 \ubd88\ub7ec\uc624\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
 iconBar.switch.tooltip=Vuze UI \uc120\ud0dd\uae30
-VivaldiView.notAvailable=\ube44\ubc1c\ub514 \ubcf4\uae30\uac00 \ud65c\uc131\ud654 \ub418 \uc788\uc9c0 \uc54a\uc74c
-restart.error.oom=\uc608\uc0b0 \ucd08\uacfc
+VivaldiView.notAvailable=Vivaldi \ubcf4\uae30\ub97c \ud560 \uc218 \uc5c6\uc74c
+restart.error=\ub2e4\uc2dc \uc2dc\uc791 \uc2e4\ud328:\n%1\n<A HREF="{restart.error.url}">\ub2e4\uc2dc \uc2dc\uc791 \ubb38\uc81c</a>\ub97c \ucc38\uace0\ud558\uc138\uc694.
+restart.error.oom=\uba54\ubaa8\ub9ac \ucd08\uacfc
+restart.error.fnf='%2'\uc5d0\uc11c '%1'\uc774 \ubc1c\uacac\ub418\uc9c0 \uc54a\uc74c
+restart.error.pnf='%1' \uacbd\ub85c\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc74c
+restart.error.bad='%1'\uc5d0 \ub300\ud55c \uc190\uc0c1\ub41c \ud30c\uc77c \ud615\uc2dd
+restart.error.denied='%1'\ub97c \uc2e4\ud589\ud558\ub824\uace0 \ud560 \ub54c \uc811\uadfc \uac70\ubd80\ub418\uc5c8\uc2b5\ub2c8\ub2e4.  \uc774 \ud504\ub85c\uadf8\ub7a8\uc744 \uc2e4\ud589\ud560 \uad8c\ud55c\uc774 \uc788\ub294\uc9c0 \ud655\uc778\ubc14\ub78d\ub2c8\ub2e4.
+TableColumn.header.date_completed=\uc644\ub8cc \uc2dc\uac04
 TableColumn.menu.date_added.reset=\ub0a0\uc9dc \ucd08\uae30\ud654
-ConfigView.interface.start.advanced=\uace0\uae09 \uc120\ud0dd\uc0ac\ud56d \ud45c\uc2dc (AZ 2.x)
+ConfigView.section.ipfilter.discardbanning=\ubc84\ub7ec\uc9c4 \ub370\uc774\ud130/\uc62c\ubc14\ub978 \ub370\uc774\ud130 \ube44\uc728\uc744 \ucd08\uacfc\ud55c \ud53c\uc5b4 \ucc28\ub2e8 [0: \ube44\ud65c\uc131]
+ConfigView.section.ipfilter.discardminkb=\ube44\uc728\uc744 \uc801\uc6a9\ud558\uae30 \uc804\uc5d0 \ubc84\ub9b4 \ucd5c\uc18c %1
+ConfigView.interface.start.advanced=\uace0\uae09 \ubcf4\uae30\ub85c \uc2dc\uc791 (AZ 2.x)
 MyTorrents.column.ColumnQuality=\ud488\uc9c8
+MyTorrents.column.ColumnSpeed=\uc18d\ub3c4
+MyTorrents.column.ColumnProgressETA.StreamReady=\uc2a4\ud2b8\ub9ac\ubc0d \uc900\ube44
+MyTorrents.column.ColumnProgressETA.PlayableIn=%1 \uc548\uc5d0 \uc7ac\uc0dd\uac00\ub2a5
 TableColumn.header.Quality=\ud488\uc9c8
 TableColumn.header.Speed=\uc18d\ub3c4
-TableColumn.header.RateIt=\uc21c\uc704
-TableColumn.header.Rating=\uc21c\uc704
+TableColumn.header.RateIt=\ub4f1\uae09
+TableColumn.header.Rating=\ub4f1\uae09\ub9e4\uae40
 TableColumn.header.SpeedGraphic=\uc18d\ub3c4
-TableColumn.header.AzProduct=\ubcf4\ub0b8 \uc774
+TableColumn.header.AzProduct=\ucd9c\ucc98
 TableColumn.header.MediaThumb=\ubbf8\ub514\uc5b4
-TableColumn.header.ProgressETA=\uc9c4\ud589\uc0c1\ud669
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-TableColumn.header.name.ext=\ud30c\uc77c \uc885\ub958: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
+TableColumn.header.ProgressETA=\uc9c4\ud589
+TableColumn.header.name.ext=\ud30c\uc77c \uc720\ud615: %1
 v3.MainWindow.tab.home=\ub300\uc26c\ubcf4\ub4dc
-v3.MainWindow.tab.browse=Vuze\uc5d0\uc11c
+v3.MainWindow.tab.browse=Vuze\uc5d0\uc11c...
 v3.MainWindow.tab.library=\ub77c\uc774\ube0c\ub7ec\ub9ac
-v3.MainWindow.tab.publish=\ubc30\ud3ec
+v3.MainWindow.tab.publish=\uac8c\uc2dc
 v3.MainWindow.tab.advanced=\uace0\uae09
-v3.MainWindow.menu.home=&\ub300\uc26c\ubcf4\ub4dc
-v3.MainWindow.menu.browse=&Vuze\uc5d0\uc11c
-v3.MainWindow.menu.library=&\ub77c\uc774\ube0c\ub7ec\ub9ac
-v3.MainWindow.menu.publish=&\ubc30\ud3ec
-v3.MainWindow.menu.advanced=&\uace0\uae09
-v3.MainWindow.menu.view.searchbar=\uac80\uc0c9 \ud45c\uc2dc\uc904
-v3.MainWindow.menu.view.tabbar=\ud0ed \ud45c\uc2dc\uc904
-v3.MainWindow.currentDL=\ud604\uc7ac \ub0b4\ub824\ubc1b\uae30 \uc911\uc778 \uc790\ub8cc
+v3.MainWindow.menu.home=\ub300\uc26c\ubcf4\ub4dc(&D)
+v3.MainWindow.menu.browse=Vuze\uc5d0\uc11c(&O)...
+v3.MainWindow.menu.library=\ub77c\uc774\ube0c\ub7ec\ub9ac(&L)
+v3.MainWindow.menu.publish=\uac8c\uc2dc(&P)
+v3.MainWindow.menu.advanced=\uace0\uae09(&A)
+v3.MainWindow.menu.view.searchbar=\uac80\uc0c9 \ub9c9\ub300
+v3.MainWindow.menu.view.tabbar=\ud0ed \ub9c9\ub300
+v3.MainWindow.currentDL=\ud604\uc7ac \ub2e4\uc6b4\ub85c\ub4dc \uc911
 v3.MainWindow.button.stream=\uc2a4\ud2b8\ub9bc
-v3.MainWindow.button.stop=\uc911\uc9c0
+v3.MainWindow.button.stop=\uc815\uc9c0
 v3.MainWindow.button.start=\uc2dc\uc791
-v3.MainWindow.button.pause=\uba48\ucda4
-v3.MainWindow.button.resume=\uacc4\uc18d
+v3.MainWindow.button.pause=\uc77c\uc2dc\uc815\uc9c0
+v3.MainWindow.button.resume=\ub2e4\uc2dc \uc2dc\uc791
 v3.MainWindow.button.delete=\uc0ad\uc81c
-v3.MainWindow.button.comment=\ub367\ub9d0
-v3.MainWindow.button.viewdetails=\uc18d\uc131
+v3.MainWindow.button.comment=\uc8fc\uc11d
+v3.MainWindow.button.viewdetails=\uc138\ubd80\uc0ac\ud56d \ubcf4\uae30
 v3.MainWindow.button.play=\uc7ac\uc0dd
 v3.MainWindow.button.cancel=\ucde8\uc18c
-v3.MainWindow.button.preview=\ud504\ub9ac\ubdf0
-v3.MainWindow.view.wait=\uc678\ud615\uc744 \ucd08\uae30\ud654\uc911\uc785\ub2c8\ub2e4. \uc7a0\uc2dc\ub9cc \uae30\ub2e4\ub824 \uc8fc\uc138\uc694.
-v3.MainWindow.xofx=%1 \uc758 %2
-v3.MainWindow.Loading=\ubd88\ub7ec\uc624\ub294\uc911.. \uc7a0\uc2dc \uae30\ub2e4\ub824\uc8fc\uc138\uc694.
-v3.filter-bar=\uc81c\ubaa9 \uace8\ub77c\ubcf4\uae30:
-v3.MainWindow.search.defaultText=\ucc3e\uae30...
-v3.mb.delPublished.title=\uc528\uc557 \ubfcc\ub9ac\uae30 \uc911\ub2e8
-v3.mb.delPublished.text=\uacbd\uace0: \uc774\uc791\uc5c5\uc774 <A HREF="%2">%3</A>\ub85c\ubd80\ud130 \uacf5\uc720\ud55c \ucee8\ud150\uce20  '%1'\ub97c \uc81c\uac70\ud558\ub294\uac83\uc740 \uc544\ub2d9\ub2c8\ub2e4.\n\n\ub0a8\ub294 \ub300\uc5ed\ud3ed\uc744 \ud65c\uc6a9\ud574 \uc790\ub8cc\ub97c \ubc30\ud3ec\ud558\uac70\ub098 \ub0b4\ub824\ubc1b\uae30 \uac00\ub2a5\ud558\uac8c \ud558\ub824\uba74 "\uc0ad\uc81c"\ub97c \ub204\ub974\uc138\uc694. (<A HREF="%4">\uc5b4\ub5bb\uac8c</A>?)\ub97c \ucc38\ [...]
-v3.mb.delPublished.delete=&\uc0ad\uc81c
-v3.mb.delPublished.cancel=&\ucde8\uc18c
-v3.mb.openFile.title=\ud30c\uc77c \uc5f4\uae30
-v3.mb.openFile.text.known=\uc774\uc790\ub8cc\ub294 Vuze \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c \uc7ac\uc0dd\ud560 \uc218 \uc5c6\ub294 \uc790\ub8cc\uc785\ub2c8\ub2e4. \ucee4\ubba4\ub2c8\ud2f0\uc5d0\uc11c <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\ud30c\uc77c\uc7ac\uc0dd \uac00\uc774\ub4dc</a> \ub97c \ucc38\uace0\ud558\uc138\uc694.\n\n\ud30c\uc77c\ud0c0\uc785: %2 (%3)\n
-v3.mb.openFile.text.unknown=\uc774\uc790\ub8cc\ub294 Vuze \ud50c\ub808\uc774\uc5b4\uc5d0\uc11c \uc9c0\uc6d0\ud558\uc9c0 \uc54a\ub294 \uc790\ub8cc\uc785\ub2c8\ub2e4. \ucee4\ubba4\ub2c8\ud2f0\uc5d0\uc11c <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\ud30c\uc77c\uc7ac\uc0dd \uac00\uc774\ub4dc</a> \ub97c \ud655\uc778\ud558\uc138\uc694.\n\n\ud30c\uc77c \ud615\uc2dd : %2\n
-v3.mb.openFile.button.play=\uc7ac\uc0dd
-v3.mb.openFile.button.cancel=\ucde8\uc18c
-v3.mb.openFile.button.guide=\ud30c\uc77c\uc7ac\uc0dd \uac00\uc774\ub4dc \uc77d\uae30
-v3.mb.openFile.remember=\ubb3c\uc5b4\ubcf4\uc9c0 \uc54a\uace0 \ud56d\uc0c1 \ud30c\uc77c \uc5f4\uae30
+v3.MainWindow.button.preview=\ubbf8\ub9ac\ubcf4\uae30
+v3.MainWindow.view.wait=\ubcf4\uae30\ub97c \ucd08\uae30\ud654\ud558\ub294 \uc911, \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc624.
+v3.MainWindow.xofx=%2 \uc911 %1
+v3.MainWindow.Loading=\ubd88\ub7ec\uc624\ub294 \uc911.. \uae30\ub2e4\ub824 \uc8fc\uc2ed\uc2dc\uc624
+v3.filter-bar=\uc81c\ubaa9 \ud544\ud130:
+v3.MainWindow.search.defaultText=\uac80\uc0c9\u2026
+v3.mb.delPublished.title=\ucf58\ud150\uce20 \ubc30\ud3ec \uc911\uc9c0
+v3.mb.delPublished.text=*\uacbd\uace0*: \uc774 \ub3d9\uc791\uc740 <A HREF="%2">%3</A>\uc5d0 \uac8c\uc2dc\ub41c \uc0ac\uc6a9\uc790 \ucf58\ud150\uce20 '%1'\ub97c \uc81c\uac70\ud558\uc9c0 *\uc54a\uc2b5\ub2c8\ub2e4*.\n\n\ucf58\ud150\uce20\ub97c \uacc4\uc18d \uac8c\uc2dc\ud574\uc11c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \uc720\uc9c0\ud558\uc9c0\ub9cc \ub300\uc5ed\ud3ed\uc744 \ud655\ubcf4\ud558\ub824\uba74 "\uc0ad\uc81c"\ub97c \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624. \uc77 [...]
+v3.mb.delPublished.delete=\uc0ad\uc81c(&D)
+v3.mb.delPublished.cancel=\ucde8\uc18c(&C)
 v3.mb.PlayFileNotFound.title=\ud30c\uc77c\uc774 \uc5c6\uc74c
 v3.mb.PlayFileNotFound.text='%1'\uc758 \ud30c\uc77c\uc774 \uc9c0\uc6cc\uc84c\uac70\ub098 \uc704\uce58\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.
 v3.mb.PlayFileNotFound.button.remove=Vuze\uc5d0\uc11c \uc81c\uac70
-v3.mb.PlayFileNotFound.button.redownload=\ub2e4\uc2dc \ub0b4\ub824\ubc1b\uae30
+v3.mb.PlayFileNotFound.button.redownload=\ub370\uc774\ud130 \ub2e4\uc2dc \ub2e4\uc6b4\ub85c\ub4dc
 v3.mb.PlayFileNotFound.button.find=\uc9c1\uc811 \ucc3e\uae30..
-v3.mb.deletePurchased.title=\uad6c\uc785\ud55c \ucee8\ud150\uce20 \uc81c\uac70
-v3.mb.deletePurchased.text='%1' \uc790\ub8cc\ub97c \uc0ad\uc81c\ud558\uae30\ub97c \uc6d0\ud558\uc138\uc694?\n\n\uc774 \uc790\ub8cc\ub294 \uad6c\ub9e4\ud558\uc600\uac70\ub098, \ub0b4\ub824\ubc1b\uae30\uc704\ud574 \ub85c\uadf8\uc778\uc774 \ud544\uc694\ud55c \uc790\ub8cc \uc785\ub2c8\ub2e4.
-v3.mb.deletePurchased.button.delete=&\uc0ad\uc81c
-v3.mb.deletePurchased.button.cancel=&\ucde8\uc18c
 v3.topbar.menu.show.logo=\ub85c\uace0
-v3.topbar.menu.show.plugin=\ucd94\uac00\uae30\ub2a5 \uc601\uc5ed
+v3.topbar.menu.show.plugin=\ud50c\ub7ec\uadf8\uc778 \uc601\uc5ed
 v3.topbar.menu.show.search=\uac80\uc0c9
-v3.topbar.menu.show.frog=\ud30c\ub780 \uac1c\uad6c\ub9ac
 splash.initializeCore=\ud575\uc2ec\ubd80\ubd84\uc744 \ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
 splash.initializeUIElements=UI \uc694\uc18c\ub97c \ucd08\uae30\uac12\uc5d0 \ub9de\ucd94\uace0 \uc788\uc74c
-ConfigView.section.transfer.autospeedbeta=\uc790\ub3d9 \uc18d\ub3c4 (\ubca0\ud0c0)
-#
-ConfigView.section.ipfilter.peerblocking.group=\ub3d9\ub8cc \ub9c9\uae30
-ConfigView.section.ipfilter.autoload.group=\uc790\ub3d9 \ubd88\ub7ec\ub4e4\uc774\uae30
-ConfigView.section.ipfilter.autoload.file=IP \ud544\ud130 \ud30c\uc77c \uc790\ub3d9 \ubd88\ub7ec\uc624\uae30
-ConfigView.section.ipfilter.autoload.loadnow=\uc9c0\uae08 \ubd88\ub7ec\ub4e4\uc774\uae30
+ConfigView.section.ipfilter.peerblocking.group=\ud53c\uc5b4 \ucc28\ub2e8
+ConfigView.section.ipfilter.autoload.group=\uc790\ub3d9 \uc801\uc7ac
+ConfigView.section.ipfilter.autoload.file=\uc790\ub3d9\uc73c\ub85c \ub85c\ub4dc\ud560 IP \ud544\ud130 \ud30c\uc77c
+ConfigView.section.ipfilter.autoload.info=DAT (eMule), P2P (PeerGuardian, splist), P2B v1,2,3 (PeerGuardian 2) \ud615\uc2dd\uc744 \uc9c0\uc6d0\ud569\ub2c8\ub2e4.  \ud30c\uc77c\uc740 \ub85c\uceec \ub610\ub294 URL, zip'd, gzip'd, \uc77c\ubc18 \ud14d\uc2a4\ud2b8\ub85c \uc8fc\uc5b4\uc9c8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.  \ud30c\uc77c\uc740 \uad50\uccb4\ub418\uac70\ub098 \ubcc0\uacbd\ub41c \ud6c4 \uba87 \ubd84 \uc548\uc5d0 \uc0c8\ub85c\uace0\uce68 \ub418\ub294 \ubc18\uba74, URL\uc740 7\uc77c  [...]
+ConfigView.section.ipfilter.autoload.loadnow=\uc9c0\uae08 \ub85c\ub4dc
 splash.loadIpFilters=IP \ud544\ud130 \ubd88\ub7ec\uc624\uae30..
-SpeedTestWizard.set.upload.title=\ub0b4\ub824\ubc1b\uae30 \uc62c\ub9ac\uae30 \uc81c\ud55c \uc124\uc815
-SpeedTestWizard.set.download.label=\ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 \uc81c\ud55c:
+SpeedTestWizard.set.upload.title=\uc5c5\ub85c\ub4dc\uc640 \ub2e4\uc6b4\ub85c\ub4dc \uc81c\ud55c \uc124\uc815
+SpeedTestWizard.set.download.label=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c:
 SpeedTestWizard.set.upload.label=\uc62c\ub9ac\uae30 \uc18d\ub3c4 \uc81c\ud55c:
-SpeedTestWizard.name.conf.level.absolute=\uc808\ub300\uc801
+SpeedTestWizard.name.conf.level.absolute=\uc808\ub300
 SpeedTestWizard.name.conf.level.high=\ub192\uc74c
 SpeedTestWizard.name.conf.level.med=\uc911\uac04
 SpeedTestWizard.name.conf.level.low=\ub0ae\uc74c
-SpeedTestWizard.name.conf.level.none=\uc544\ub2d8
-ConfigView.section.transfer.select=\uc790\ub3d9 \uc18d\ub3c4
-ConfigView.section.transfer.select.v2=\uc790\ub3d9 \uc18d\ub3c4 (\ubca0\ud0c0)
-mb.azmustclose.title=\uc2dc\uc791\uc2dc \uc624\ub958
-DHTView.title.full_v6=\ubd84\ud3ec\ub41c IPv6 \ub370\uc774\ud130\ubca0\uc774\uc2a4
-ConfigView.pluginlist.loadSelected=\uc120\ud0dd\ud55c\uac83 \ubd88\ub7ec\uc624\uae30
+SpeedTestWizard.name.conf.level.none=\uc5c6\uc74c
+ConfigView.section.transfer.select=\uc790\ub3d9\uc18d\ub3c4
+ConfigView.section.transfer.select.v2=\uc790\ub3d9\uc18d\ub3c4 (\ubca0\ud0c0)
+mb.azmustclose.title=\uc2dc\uc791 \uc2dc \uc624\ub958
+mb.azmustclose.text=Vuze\uac00 (\ub2e4\uc2dc) \uc2dc\uc791\ud560 \ub54c \ubc1c\uc0dd\ud55c \ubb38\uc81c\ub85c \uc778\ud574 Vuze\ub294 \ubc18\ub4dc\uc2dc \uc885\ub8cc\ub418\uc5b4\uc57c \ud569\ub2c8\ub2e4. \uc774 \ubb38\uc81c\ub294 \ud504\ub85c\uadf8\ub7a8\uc774 \uad00\ub9ac\uc790 \uad8c\ud55c\uc73c\ub85c \uc2e4\ud589\ub418\uc5c8\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud558\ub294 \uac83\uc73c\ub85c \ubcf4\uc785\ub2c8\ub2e4.\n\nVuze\uac00 \ub2eb\ud788\uba74 \uc218\ub3d9\uc73c\ub85c \ub2e4\uc [...]
+network.ipv6.prefer.addresses=IPv6\uc640 IPv4 \ub458 \ub2e4 \uc0ac\uc6a9 \uac00\ub2a5\ud560 \uacbd\uc6b0 IPv6 \uc8fc\uc18c\ub97c \uc120\ud638
+network.bindError=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \ud638\ud658 \uc8fc\uc18c\uac00 \uc5c6\uc5b4\uc11c \uc11c\ubc84 \uc18c\ucf13 \ubc14\uc778\ub529\uc744 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. bind-to-IP \uc124\uc815\uc744 \ud655\uc778\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+network.enforce.ipbinding=\uc778\ud130\ud398\uc774\uc2a4\uac00 \uc0ac\uc6a9 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc744 \ub54c\ub3c4 IP \ubc14\uc778\ub529\uc744 \ud558\ub3c4\ub85d \uac15\uc81c\ud569\ub2c8\ub2e4. \n\uc9c0\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub294 \uacbd\uc6b0 \ubaa8\ub4e0 \uc5f0\uacb0\uc744 \ub9c9\uc2b5\ub2c8\ub2e4.
+DHTView.title.full_v6=\ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4 IPv6
+ConfigView.pluginlist.loadSelected=\uc120\ud0dd\ud55c \uac83 \ub85c\ub4dc
 SpeedView.stats.asn=\ub124\ud2b8\uc6cc\ud06c:
-SpeedView.stats.estupcap=\uc62c\ub9ac\uae30 \uc81c\ud55c:
-SpeedView.stats.estdowncap=\ub0b4\ub824\ubc1b\uae30 \uc81c\ud55c:
-SpeedView.stats.unknown=\uc54c\uc218 \uc5c6\uc74c
-SpeedView.stats.manual=\uace0\uce68
-dialog.uiswitcher.restart.title=UI \uc120\ud0dd\uae30: Vuze \uc7ac\uc2dc\uc791 \ud544\uc694
+SpeedView.stats.estupcap=\uc5c5\ub85c\ub4dc \uc81c\ud55c:
+SpeedView.stats.estdowncap=\ub2e4\uc6b4\ub85c\ub4dc \uc81c\ud55c:
+SpeedView.stats.unknown=\uc54c \uc218 \uc5c6\uc74c
+SpeedView.stats.estimate=\ucd94\uc815\uce58
+SpeedView.stats.measured=\uce21\uc815\uce58
+SpeedView.stats.measuredmin=\uce21\uc815\uce58 \ucd5c\uc18c\uac12
+SpeedView.stats.manual=\uace0\uc815
+ConfigView.section.transfer.autospeed.networks=\ub124\ud2b8\uc6cc\ud06c \uc138\ubd80\uc0ac\ud56d
+ConfigView.section.transfer.autospeed.resetnetwork=\ub124\ud2b8\uc6cc\ud06c \uc138\ubd80\uc0ac\ud56d \ucd08\uae30\ud654
+ConfigView.section.transfer.autospeed.network.info=\uc0c1\uae30\uc758 \uc81c\ud55c\uc740 \uc77c\ubc18\uc801\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc \ud558\ub294 \ub3d9\uc548 \uc790\ub3d9\uc73c\ub85c \uacc4\uc0b0\ub418\uac70\ub098 \uc18d\ub3c4 \ud14c\uc2a4\ud2b8\ub85c \uacb0\uc815\ub429\ub2c8\ub2e4. \ub9cc\uc57d \uc218\ub3d9\uc73c\ub85c \uc81c\ud55c\uac12\uc744 \uc9c0\uc815\ud558\ub824\uba74 \uc544\ub798\uc758 \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624.\n'\uace0\uc815\ub428'\uc7 [...]
+dialog.uiswitcher.restart.title=UI \uc804\ud658\uae30: Vuze \ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694
+dialog.uiswitcher.restart.text=\uc0c8 UI \ubaa8\ub4dc\ub85c \uc804\ud658\uc744 \uc704\ud574 Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4.
+TrayWindow.menu.close=\ub2e4\uc6b4\ub85c\ub4dc \ubc14\uad6c\ub2c8 \ub2eb\uae30
 # Used for peers which we can't determine.
-PeerSocket.unknown=\uc54c\uc218\uc5c6\uc74c
-PeerSocket.unknown_az_style=\uc54c\uc218\uc5c6\uc74c %1/%2
-PeerSocket.unknown_shadow_style=\uc54c\uc218\uc5c6\uc74c %1/%2
-ConfigTransferAutoSpeed.upload.capacity.usage=\uc62c\ub9ac\uae30 \uc0ac\uc6a9\ub7c9
+PeerSocket.unknown=\uc54c \uc218 \uc5c6\uc74c
+PeerSocket.fake_client=*\uac00\uc9dc*
+PeerSocket.bad_peer_id=\uc798\ubabb\ub41c \ud53c\uc5b4 ID
+PeerSocket.mismatch_id=\uc77c\uce58\ud558\uc9c0 \uc54a\uc74c
+PeerSocket.unknown_az_style=\uc54c \uc218 \uc5c6\uc74c %1 %2
+PeerSocket.unknown_shadow_style=\uc54c \uc218 \uc5c6\uc74c %1 %2
+OpenTorrentWindow.mb.askCreateDir.title=\ub300\uc0c1 \ub514\ub809\ud130\ub9ac\uac00 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc74c
+OpenTorrentWindow.mb.askCreateDir.text=\ub300\uc0c1 \ub514\ub809\ud1a0\ub9ac
+SpeedView.stats.estimatechoke=\ucd94\uc815\uce58 (\ud3ec\ud654\uc0c1\ud0dc)
+ConfigTransferAutoSpeed.upload.capacity.usage=\uc5c5\ub85c\ub4dc \uc6a9\ub7c9 \uc0ac\uc6a9\uacc4
 ConfigTransferAutoSpeed.mode=\ubaa8\ub4dc:
-ConfigTransferAutoSpeed.capacity.used=% \uc0ac\uc6a9 \uc6a9\ub7c9
-ConfigTransferAutoSpeed.while.downloading=\ub0b4\ub9ac\uae30:
+ConfigTransferAutoSpeed.capacity.used=% \uc6a9\ub7c9 \uc0ac\uc6a9\ub428
+ConfigTransferAutoSpeed.while.downloading=\ub2e4\uc6b4\ub85c\ub4dc \uc911:
 ConfigTransferAutoSpeed.set.dht.ping=DHT \ud551 \uc124\uc815:
-ConfigTransferAutoSpeed.set.point=\uc124\uc815 \uc9c0\uc810 (ms)
-ConfigTransferAutoSpeed.set.tolerance=\uad00\uc6a9\uc131 (ms)
-ConfigTransferAutoSpeed.ping.time.good=\uc88b\uc740:
-ConfigTransferAutoSpeed.ping.time.bad=\ub098\uc05c:
-ConfigTransferAutoSpeed.adjustment.interval=\uc870\uc815 \uac04\uaca9:
-ConfigTransferAutoSpeed.skip.after.adjust=\uc870\uc815 \ud6c4 \uc0dd\ub7b5:
-PiecesView.DistributionView.NoAvl=\ud65c\uc131\ud654 \uc870\uac01
-PiecesView.DistributionView.weHave=\ub0b4\uac00 \uac00\uc9c4 \uc870\uac01
-PiecesView.DistributionView.theyHave=\ub3d9\ub8cc\uac00 \uac00\uc9c4 \uc870\uac01
-PiecesView.DistributionView.weDownload=\ub0b4\uac00 \ub0b4\ub824\ubc1b\uace0\uc788\ub294 \uc870\uac01
+ConfigTransferAutoSpeed.set.point=\uc9c0\uc810 \uc124\uc815 (ms)
+ConfigTransferAutoSpeed.set.tolerance=\ud5c8\uc6a9 \ud55c\uacc4 (ms)
+ConfigTransferAutoSpeed.ping.time.good=\uc88b\uc74c:
+ConfigTransferAutoSpeed.ping.time.bad=\uc190\uc0c1:
+ConfigTransferAutoSpeed.adjustment.interval=\uac04\uaca9 \uc870\uc815:
+ConfigTransferAutoSpeed.skip.after.adjust=\uc870\uc815 \ud6c4 \uac74\ub108\ub700:
+GeneralView.label.distributedCopies=\ubc30\ubd84\ub41c \ubcf5\uc0ac\ubcf8:
+PiecesView.DistributionView.title=\uc870\uac01 \ubd84\ud3ec
+PiecesView.DistributionView.NoAvl=\uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub294 \uc870\uac01
+PiecesView.DistributionView.SeedAvl=\uc2dc\ub4dc \uc720\ud6a8\uc131 \uae30\uc5ec\ub3c4
+PiecesView.DistributionView.PeerAvl=\ud53c\uc5b4 \uc720\ud6a8\uc131 \uae30\uc5ec\ub3c4
+PiecesView.DistributionView.RarestAvl=\uac00\uc7a5 \ud76c\uadc0\ud55c \uc870\uac01: %1 (\uc720\ud6a8\uc131: %2)
+PiecesView.DistributionView.weHave=\ubcf4\uc720\ud55c \uc870\uac01
+PiecesView.DistributionView.theyHave=\ud53c\uc5b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \uc870\uac01
+PiecesView.DistributionView.weDownload=\ub2e4\uc6b4\ub85c\ub4dc \uc911\uc778 \uc870\uac01
+PeersView.gain=\uc774\ub4dd
+PeersView.gain.info=\uc804\uccb4 \ub2e4\uc6b4\ub85c\ub4dc - \uc5c5\ub85c\ub4dc\ud55c \ub370\uc774\ud130
 unix.script.new.title=\uc0c8\ub85c\uc6b4 Vuze \uc2dc\uc791 \uc2a4\ud06c\ub9bd\uc774 \uc788\uc2b5\ub2c8\ub2e4.
-unix.script.new.button.quit=\uc9c0\uae08 \ub05d\ub124\uae30
+unix.script.new.text=\uc0c8 Vuze \uc2dc\uc791 \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc73c\uba70 '%1'\uc5d0 \uc800\uc7a5\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\nVuze\ub97c \uc9c0\uae08 \uc885\ub8cc\ud558\uace0 \ud574\ub2f9 \uc2a4\ud06c\ub9bd\ud2b8 ('%2')\ub85c \uc804\ud658\ud558\uae30\ub97c \uac15\ub825\ud558\uac8c \uad8c\uc7a5\ud569\ub2c8\ub2e4.\n\nVuze \uc2a4\ud06c\ub9bd\ud2b8\ub97c \ud06c\uac8c \uc218\uc815\ud55c \uc0c1\ud0dc\ub77c\uba74 <A HREF="{unix.script.new.ma [...]
+unix.script.new.button.quit=\uc9c0\uae08 \uc885\ub8cc
 unix.script.new.button.continue=\ub2e4\uc74c\uc5d0 \ud558\uaca0\uc2b5\ub2c8\ub2e4
-unix.script.new.button.asknomore=\ub2e4\uc2dc \uc54c\ub9ac\uc9c0 \ub9d0\uc544\uc8fc\uc138\uc694
-unix.script.new.auto.title=\uc0c8\ub85c\uc6b4 Vuze \uc2dc\uc791 \uc2a4\ud06c\ub9bd
-Content.alert.notuploaded.button.stop=&\uba48\ucda4
-Content.alert.notuploaded.button.continue=&\ubfcc\ub9ac\uae30 \uacc4\uc18d
-Content.alert.notuploaded.button.abort=&\ub05d\ub0b4\uc9c0 \uc54a\uc74c
-ConfigView.label.checkOnSeeding=\ubfcc\ub9b4\ub54c \ub0ae\uc740 \uc6d0\ubcf8\uc758 \uc870\uac01\uc744 \ub2e4\uc2dc\ud655\uc778 \ud55c\ub2e4\ub294 \uac83\uc744 \uc54c\ub9bc
-SpeedTestWizard.finish.panel.auto.speed=\uc790\ub3d9 \uc18d\ub3c4 :
-SpeedTestWizard.finish.panel.auto.speed.seeding=\ubfcc\ub9ac\ub294 \ub3d9\uc548 \uc790\ub3d9 \uc18d\ub3c4 : 
-ConfigTransferAutoSpeed.add.comment.to.log.group=\ub514\ubc84\uadf8 \ub85c\uadf8\uc5d0 \ub367\ub9d0 \uc791\uc131
-ConfigTransferAutoSpeed.add.comment.to.log=\ub367\ub9d0 \uc791\uc131:
-ConfigTransferAutoSpeed.log.button=\uae30\ub85d
-ConfigTransferAutoSpeed.algorithm.selector=\uc790\ub3d9 \uc18d\ub3c4 \uc870\uc808\uae30
-ConfigTransferAutoSpeed.algorithm=\uc5f0\uc0b0 \ubc29\ubc95:
-ConfigTransferAutoSpeed.auto.speed.classic=\uc790\ub3d9 \uc18d\ub3c4 \uc870\uc808(\uc774\uc804\ubc84\uc804)
-ConfigTransferAutoSpeed.auto.speed.beta=\uc790\ub3d9 \uc18d\ub3c4 \uc870\uc808(\ubca0\ud0c0)
-ConfigTransferAutoSpeed.data.update.frequency=\uc5c5\ub370\uc774\ud2b8 \uac04\uaca9
-Alert.failed.update=\ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 \ucef4\ud3ec\ub10c\ud2b8 \uc124\uce58\uac00 \uc2e4\ud328\ud558\uc600\uc2b5\ub2c8\ub2e4. <A HREF="{Alert.failed.update.url}">Azureus\uc704\ud0a4: \uc5c5\ub370\uc774\ud2b8 \uc2e4\ud328</A> [%1]\ub97c \ucc38\uace0 \ud558\uc138\uc694.
-MyTorrentsView.menu.exporthttpseeds=HTTP \uc528\uc557 \uc8fc\uc18c\ub97c \ud06c\ub9ac\ub9bd\ubcf4\ub4dc\ub85c \ub0b4\ubcf4\ub0b4\uae30
-ConfigView.label.minannounce=\ub354\ub4ec\uc774 \uc54c\ub9ac\uae30 \uc0ac\uc774\uc758 \ucd5c\uc18c\uc2dc\uac04 (\ucd08)
-ConfigView.label.maxnumwant=\ub354\ub4ec\uc774\uac00 \ub2e4\uc2dc \ub3cc\uc544\uc62c\ub54c \uc81c\ud55c\ub41c \uc218\uc758 \ub3d9\ub8cc
-ConfigView.label.announceport=\ub354\ub4ec\uc774 \uc54c\ub9ac\uae30\ub97c \uc704\ud574\uc11c \uc54c\ub9ac\uae30 TCP\ud3ec\ud2b8\ub97c \uc624\ubc84\ub77c\uc774\ub4dc \ud568(PEX\uc640 DHT)\n[\ube48\uce78\uc73c\ub85c \ub0a8\uaca8\ub460: \uc624\ubc84\ub77c\uc774\ub4dc \uc5c6\uc74c, 0: \ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0 \uc5c6\uc74c]
-ConfigView.label.noportannounce=\ub354\ub4ec\uc774\uc5d0\uac8c \ub4e3\uae30\ud3ec\ud2b8 \uc54c\ub9ac\uc9c0 \uc54a\uc74c (PEX, DHT\uc5d0 \uc601\ud5a5\uc5c6\uc74c)
-ConfigView.label.maxseedspertorrent=\ud1a0\ub7f0\ud2b8\ubcc4 \uae30\ubcf8 \ucd5c\uace0 \uc528\uc557\uc218 [0: \ubb34\uc81c\ud55c] 
-wizard.webseed=HTTP \uc528\uc557\uc744 \ud1a0\ub7f0\ud2b8\uc5d0 \ucd94\uac00
-wizard.webseed.title=HTTP \uc528\uc557
-wizard.webseed.configuration=HTTP \uc528\uc557 \uc124\uc815
-wizard.webseed.adding=HTTP \uc528\uc557 \ucd94\uac00
-GeneralView.label.private=\ube44\uacf5\uac1c \ud1a0\ub7f0\ud2b8 :
-GeneralView.yes=\ub124
+unix.script.new.button.asknomore=\ub2e4\uc2dc \ub098\uc5d0\uac8c \ub9d0\ud558\uc9c0 \ub9c8\uc138\uc694
+unix.script.new.auto.title=\uc0c8 Vuze \uc2dc\uc791 \uc2a4\ud06c\ub9bd\ud2b8
+unix.script.new.auto.text=\uc0c8 Vuze \uc2dc\uc791 \uc2a4\ud06c\ub9bd\ud2b8\uac00 \uc0ac\uc6a9 \uac00\ub2a5\ud569\ub2c8\ub2e4.\n\n\uc9c0\uae08 Vuze \ub2e4\uc2dc \uc2dc\uc791\uc744 \uac15\ub825\ud788 \uad8c\uc7a5\ub429\ub2c8\ub2e4.
+Content.alert.notuploaded.button.abort=\uc885\ub8cc\ud558\uc9c0 \uc54a\uc74c(&D)
+ConfigView.label.checkOnSeeding=\ubc30\ud3ec\ud560 \ub54c \uc801\uc740 \ub9ac\uc18c\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc870\uac01 \ub2e4\uc2dc \uac80\uc0ac \uc218\ud589
+ConfigView.label.ui_switcher=Vuze UI \uc120\ud0dd \ud654\uba74 \ud45c\uc2dc
+ConfigView.label.ui_switcher_button=\ubcf4\uc5ec\uc8fc\uae30
+SpeedTestWizard.test.panel.explain=Vuze \ud504\ub85c\ud1a0\ucf5c \uc18d\ub3c4\ub97c \uce21\uc815\ud569\ub2c8\ub2e4. \uc18d\ub3c4 \ud14c\uc2a4\ud2b8 \uc720\ud615\uacfc \uc554\ud638\ud654 \ubaa8\ub4dc\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624. \uc774 \ud14c\uc2a4\ud2b8\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc0ac\ud56d\uc740 Vuze Wiki \ud398\uc774\uc9c0\ub97c \ubc29\ubb38\ud574\uc8fc\uc2ed\uc2dc\uc624. \ud14c\uc2a4\ud2b8\ub294 2\ubd84 \uc774\uc0c1 \uac78\ub9ac\uba74 \uc790\ub3d9\uc73c\ub8 [...]
+SpeedTestWizard.set.upload.hint=Vuze \uc790\ub3d9\uc18d\ub3c4 \uc54c\uace0\ub9ac\uc998\uc774 \uc0ac\uc6a9\ud560 \uc5c5\ub85c\ub4dc\uc640 \ub2e4\uc6b4\ub85c\ub4dc \uc81c\ud55c\uc744 \uc124\uc815\ud558\uc2ed\uc2dc\uc624.
+SpeedTestWizard.set.upload.panel.explain=\uc5ec\uae30\uc11c \uc124\uc815\ud55c \uc81c\ud55c\uc740 Vuze \uc790\ub3d9\uc18d\ub3c4 \uc54c\uace0\ub9ac\uc998\uc774 \uc0ac\uc6a9\ud558\uac8c \ub429\ub2c8\ub2e4. \uc804\uc1a1 \ud55c\uacc4\uc640 \uc2e4\uc81c \ud55c\uacc4\ub97c \uc124\uc815\ud558\uc2ed\uc2dc\uc624.\n\n\ud68c\uc120 \uc18d\ub3c4\ub294 \uc77c\ubc18\uc801\uc73c\ub85c "\ucd08\ub2f9 \ube44\ud2b8"\ub85c \uc5b8\uae09\ub418\uc9c0\ub9cc \uc544\ub798\uc758 \uac12\uc740 "\ucd08\ub2f9 \ud0ac\ub [...]
+SpeedTestWizard.set.limit.conf.level=\uc2e0\ub8b0
+SpeedTestWizard.finish.panel.auto.speed=\uc790\ub3d9\uc18d\ub3c4 :
+SpeedTestWizard.finish.panel.auto.speed.seeding=\ubc30\ud3ec\ud558\ub294 \ub3d9\uc548 \uc790\ub3d9\uc18d\ub3c4 :
+ConfigTransferAutoSpeed.add.comment.to.log.group=\ub514\ubc84\uadf8 \ub85c\uadf8\uc5d0 \uc8fc\uc11d \ucd94\uac00
+ConfigTransferAutoSpeed.add.comment.to.log=\uc8fc\uc11d \ucd94\uac00:
+ConfigTransferAutoSpeed.log.button=\ub85c\uadf8
+ConfigTransferAutoSpeed.algorithm.selector=\uc790\ub3d9\uc18d\ub3c4 \uc120\ud0dd\uae30
+ConfigTransferAutoSpeed.algorithm=\uc54c\uace0\ub9ac\uc998:
+ConfigTransferAutoSpeed.auto.speed.classic=\uc790\ub3d9\uc18d\ub3c4(\ud074\ub798\uc2dd)
+ConfigTransferAutoSpeed.auto.speed.beta=\uc790\ub3d9\uc18d\ub3c4(\ubca0\ud0c0)
+ConfigTransferAutoSpeed.data.update.frequency=\uc5c5\ub370\uc774\ud2b8 \uc8fc\uae30
+Alert.failed.update=\uc801\uc5b4\ub3c4 \ud558\ub098 \uc774\uc0c1\uc758 \ucef4\ud3ec\ub10c\ud2b8 \uc124\uce58\uac00 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. <A HREF="{Alert.failed.update.url}">AzureusWiki: \uc5c5\ub370\uc774\ud2b8 \uc2e4\ud328</A> [%1] \ucc38\uace0
+OpenTorrentWindow.mb.existingFiles.partialList=(\ubaa9\ub85d\uc758 \uc77c\ubd80. \ub354 \ub9ce\uc740 \ud30c\uc77c\uc774 \uc774\ubbf8 \uc874\uc7ac\ud568)
+TableColumn.header.bad_avail_time.info=\uc644\uc804\ud55c \uc0ac\ubcf8\uc774 \ub2e4\uc6b4\ub85c\ub4dc \uac00\ub2a5\ud588\ub358 \ub9c8\uc9c0\ub9c9 \uc2dc\uac01\uc785\ub2c8\ub2e4.
+TableColumn.header.bad_avail_time=\uc644\uc804\ud55c \uc0ac\ubcf8\uc774 \ubaa9\uaca9\ub428
+MyTorrentsView.menu.exporthttpseeds=HTTP \uc2dc\ub4dc URL\uc744 \ud074\ub9bd\ubcf4\ub4dc\ub85c \ub0b4\ubcf4\ub0b4\uae30
+SWT.alert.erroringuithread=GUI\uc5d0\uc11c \ucc98\ub9ac\ub418\uc9c0 \ubabb\ud55c \uc624\ub958\uac00 \ubc1c\uc0dd\ud588\uc2b5\ub2c8\ub2e4. \uc774\ud6c4\uc758 \uc624\ub958\ub294 \ubcf4\uace0\ub420 \uac83\uc785\ub2c8\ub2e4.
+ConfigView.label.minannounce=\ud2b8\ub798\ucee4 \uc54c\ub9bc \ucd5c\uc18c \uc2dc\uac04 \uac04\uaca9 [\ucd08]
+ConfigView.label.maxnumwant=\ud2b8\ub798\ucee4\uac00 \ubc18\ud658\ud560 \uc218 \uc788\ub294 \ud53c\uc5b4\uc758 \uc218 \uc81c\ud55c
+ConfigView.label.announceport=\ud2b8\ub798\ucee4 \uc54c\ub9bc, pex, dht\ub97c \uc704\ud574 \uc54c\ub824\uc9c4 TCP \ud3ec\ud2b8\ub97c \uc6b0\uc120\uc801\uc6a9\n[\ube48 \uce78: \uc6b0\uc120\uc801\uc6a9 \uc548\ud568, 0: \ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0 \uc5c6\uc74c]
+ConfigView.label.noportannounce=\ud2b8\ub798\ucee4\uc5d0\uac8c \ub9ac\uc2a4\ub2dd \ud3ec\ud2b8\ub97c \uc54c\ub9ac\uc9c0 \uc54a\uae30 (pex, dht\uc5d0\ub294 \uc601\ud5a5 \uc5c6\uc74c)
+ConfigView.label.maxseedspertorrent=\ud1a0\ub80c\ud2b8 \ubcc4 \ucd5c\uace0 \uc2dc\ub4dc \uae30\ubcf8\uac12 [0: \ubb34\uc81c\ud55c]
+wizard.webseed=HTTP \uc2dc\ub4dc\ub97c \ud1a0\ub80c\ud2b8\uc5d0 \ucd94\uac00
+wizard.webseed.title=HTTP \uc2dc\ub4dc
+wizard.webseed.configuration=HTTP \uc2dc\ub4dc \uc124\uc815
+wizard.webseed.adding=HTTP \uc2dc\ub4dc \ucd94\uac00
+GeneralView.label.private=\ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8:
+GeneralView.yes=\uc608
 GeneralView.no=\uc544\ub2c8\uc624
-Peers.column.timetocomplete=\ub0a8\uc740\uc2dc\uac04
-Peers.column.timetocomplete.info=\ub3d9\ub8cc\uac00 \ub2e4\ubc1b\uae30 \uc804\uae4c\uc9c0 \ub0a8\uc740\uc2dc\uac04
+ConfigView.label.userequestlimiting=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\ub97c \uc81c\ud55c\ud558\uae30 \uc704\ud574 \uc9c0\uc5f0\ub41c \uc77d\uae30 \ub300\uc2e0 \uac10\uc18d \uc694\uccad\uc744 \uc0ac\uc6a9\n[\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\uac00 \ubb34\uc81c\ud55c\uc778 \uacbd\uc6b0 \ud6a8\uacfc \uc5c6\uc74c]
+ConfigView.label.userequestlimiting.tooltip=\uc81c\ud55c \uc694\uccad\uc740 \uc9c0\uc5f0\ub41c \uc77d\uae30 \ub9cc\ud07c \ubd80\ub4dc\ub7ec\uc6b4 \ubc29\uc2dd\uc774 \uc544\ub2c8\uc9c0\ub9cc \ub2e4\uc6b4\ub85c\ub4dc \ub300\uae30\uc5f4 \uc704\uce58\uc5d0 \uae30\ubc18\ud55c \ub2e4\uc6b4\ub85c\ub4dc \uc6b0\uc120 \uc21c\uc704 \ub9e4\uae30\uae30\uac00 \uac00\ub2a5\ud558\uae30 \ub54c\ubb38\uc5d0 \ub124\ud2b8\uc6cc\ud06c \uc131\ub2a5\uc774 \ud5a5\uc0c1\ub420 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.
+ConfigView.label.userequestlimitingpriorities=\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \ub2e4\uc6b4\ub85c\ub4dc \ub300\uae30\uc5f4\uc758 \uba38\ub9ac \ucabd\uc5d0 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\ub97c \uc9d1\uc911
+ConfigView.section.logging.timestamp=\ub85c\uadf8 \ud30c\uc77c\uc6a9 \ud0c0\uc784\uc2a4\ud0ec\ud504 \ud615\uc2dd
+Peers.column.timetocomplete=\ub0a8\uc740 \uc2dc\uac04
+Peers.column.timetocomplete.info=\ud53c\uc5b4\uac00 \uc644\ub8cc\ub418\uae30\uae4c\uc9c0 \ub0a8\uc740 \uc2dc\uac04
+ConfigView.section.interface.display.suppress.file.download.dialog=\ud30c\uc77c \ub2e4\uc6b4\ub85c\ub4dc \ud31d\uc5c5 \ub300\ud654\uc0c1\uc790 \ucd9c\ub825 \ub9c9\uae30
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=\ubaa8\ub4e0 \ud30c\uc77c \ub2e4\uc6b4\ub85c\ub4dc \uc9c4\ud589\uc744 \ud31d\uc5c5 \ub300\ud654\uc0c1\uc81c \ub300\uc2e0 \uc0c1\ud0dc \ud45c\uc2dc\uc904\uc5d0 \ubcf4\uc5ec\uc8fc\uae30
+FileDownload.canceled=\ud1a0\ub80c\ud2b8 \ud30c\uc77c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc0ac\uc6a9\uc790 \ub3d9\uc791\uc5d0 \uc758\ud574 \uc131\uacf5\uc801\uc73c\ub85c \ucde8\uc18c\ub418\uc5c8\uc2b5\ub2c8\ub2e4: %1
 Progress.reporting.status.canceled=\ucde8\uc18c\ub428
-Progress.reporting.status.retrying=\uc7ac\uc2dc\ub3c4..
-Progress.reporting.action.label.retry.tooltip=\uc791\uc5c5 \uc7ac\uc2dc\ub3c4
+Progress.reporting.status.finished=\ub05d\ub0a8
+Progress.reporting.status.retrying=\ub2e4\uc2dc \uc2dc\ub3c4...
+Progress.reporting.action.label.retry.tooltip=\uc791\uc5c5 \ub2e4\uc2dc \uc2dc\ub3c4
+Progress.reporting.action.label.remove.tooltip=\uacfc\uac70\uae30\ub85d\uc5d0\uc11c \uc774 \uc9c4\ud589 \ub9ac\ud3ec\ud2b8 \uc81c\uac70
 Progress.reporting.action.label.cancel.tooltip=\uc791\uc5c5 \ucde8\uc18c
-Progress.reporting.action.label.detail=\uc138\ubd80\ub0b4\uc6a9
+Progress.reporting.action.label.detail=\uc138\ubd80\uc0ac\ud56d
 Progress.reporting.default.error=\uc2e4\ud328
-webui.bindip=IP \uc228\uae30\uae30 - \uc77c\ubc18\uc801\uc73c\ub85c \uad8c\uc7a5\ub418\uc9c0 \uc54a\uc74c (*)
+Progress.reporting.no.reports.to.display=\ud604\uc7ac\ub294 \ud45c\uc2dc\ud560 \uc9c4\ud589 \ubcf4\uace0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+Progress.reporting.no.history.to.display=\ud45c\uc2dc\ud560 \uc790\uc138\ud55c \uba54\uc2dc\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.
+Progress.reporting.detail.history.limit=\uc774 ProgressReporter\uc5d0 \ud560\ub2f9\ub41c \uc790\uc138\ud55c \uba54\uc2dc\uc9c0 \uc81c\ud55c (%1)\uc5d0 \ub3c4\ub2ec\ud588\uc2b5\ub2c8\ub2e4; \uc774\ud6c4 \uba54\uc2dc\uc9c0\ub294 \uacfc\uac70 \uae30\ub85d\uc5d0 \ucd94\uac00\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+Progress.reporting.statusbar.button.tooltip=\uc9c4\ud589 \ubcf4\uace0 \ucc3d \ubcf4\uc5ec\uc8fc\uae30
+webui.bindip=IP \ubc14\uc778\ub4dc - \uc77c\ubc18\uc801\uc73c\ub85c \uad8c\uc7a5\ub418\uc9c0 \uc54a\uc74c
 v3.MainWindow.text.log.in=\ub85c\uadf8\uc778
 v3.MainWindow.text.log.out=\ub85c\uadf8\uc544\uc6c3
 v3.MainWindow.text.get.started=\uac00\uc785
 v3.MainWindow.text.my.account=\uacc4\uc815 \uc815\ubcf4
 v3.MainWindow.text.my.profile=\ud504\ub85c\ud544
-OpenTorrentWindow.simple.open=\ud1a0\ub7f0\ud2b8 \uc704\uce58 (\ud30c\uc77c, URL, \ud574\uc26c)
-Progress.reporting.window.remove.auto=\ud65c\uc131\ud654 \ub418\uc9c0 \uc54a\uc740 \uc544\uc774\ud15c \uc790\ub3d9 \uc0ad\uc81c
-Progress.reporting.window.remove.now=\ud65c\uc131\ud654 \ub418\uc9c0 \uc54a\uc740 \uc544\uc774\ud15c \uc0ad\uc81c
-TorrentOptionsView.multi.title.short=\ud1a0\ub7f0\ud2b8 \uc120\ud0dd\uc0ac\ud56d
-TorrentOptionsView.multi.title.full=\ud1a0\ub7f0\ud2b8 \uc120\ud0dd\uc0ac\ud56d
-MyTorrentsView.menu.open_parent_folder=\uc800\uc7a5 \ud3f4\ub354 \uc5f4\uae30
-ConfigView.section.stats.exportfiles=\ud30c\uc77c \uc138\ubd80\uc815\ubcf4 \ub0b4\ubcf4\ub0b4\uae30
-v3.MainWindow.tab.minilibrary=\ub0b4\ub824\ubc1b\uae30
+OpenTorrentWindow.simple.open=\ud1a0\ub80c\ud2b8 \uc704\uce58 (\ud30c\uc77c, URL, \ud574\uc26c)
+Progress.reporting.window.remove.auto=\uc790\ub3d9\uc73c\ub85c \ud65c\uc131\ud654 \ub418\uc9c0 \uc54a\uc740 \ud56d\ubaa9 \uc81c\uac70
+Progress.reporting.window.remove.auto.tooltip=\uc790\ub3d9\uc73c\ub85c \uc774 \ubcf4\uae30\uc5d0\uc11c \ubaa8\ub4e0 \uc644\ub8cc\ub41c, \uc2e4\ud328\ud55c, \ucde8\uc18c\ub41c \uc9c4\ud589 \uc81c\uac70
+Progress.reporting.window.remove.now=\ud65c\uc131\ud654\ub418\uc9c0 \uc54a\uc740 \ud56d\ubaa9 \uc81c\uac70
+Progress.reporting.window.remove.now.tooltip=\uc774 \ubcf4\uae30\uc5d0\uc11c \ubaa8\ub4e0 \uc644\ub8cc\ub41c, \uc2e4\ud328\ud55c, \ucde8\uc18c\ub41c \uc9c4\ud589 \uc81c\uac70
+dhttracker.tracklimitedwhenonline=\uadf8\ub7ec\ub098 \uc628\ub77c\uc778 \uc2dc \uc2a4\uc6dc \uc804\ubc18\uc5d0 \ub300\ud574 \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ucd94\uc801\uc744 \uc218\ud589
+TorrentOptionsView.multi.title.short=\ud1a0\ub80c\ud2b8 \uc635\uc158
+TorrentOptionsView.multi.title.full=\ud1a0\ub80c\ud2b8 \uc635\uc158
+MyTorrentsView.menu.open_parent_folder=\ub4e4\uc5b4\uc788\ub294 \ud3f4\ub354 \uc5f4\uae30
+ConfigView.section.style.use_show_parent_folder=\ud1a0\ub80c\ud2b8 \uba54\ub274\uc5d0\uc11c "%2" \ub300\uc2e0 "%1" \uc0ac\uc6a9\ud558\uae30
+ConfigView.section.style.use_show_parent_folder.tooltip=\uc774 \uc635\uc158\uc744 \ud65c\uc131\ud654\ud558\uba74 \ud30c\uc77c \uad00\ub9ac \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ud574\ub2f9 \ud30c\uc77c\uc774 \ub4e4\uc5b4\uc788\ub294 \ud3f4\ub354\ub97c \uc5f4\ub3c4\ub85d \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\n\uadf8\ub7ec\ub098 \uc774\ub807\uac8c \ud558\uba74 \ub2e4\uc6b4\ub85c\ub4dc \uc800\uc7a5 \uc704\uce58\uac00 \uc790\ub3d9\uc73c\ub85c \uc120\ud0dd\ub418\uc9c0\ub294 \uc54a\uc2b5\ub2 [...]
+PeerManager.status.ps_disabled=\ud2b8\ub798\ucee4\uc5d0\uc11c \ud53c\uc5b4\ub97c \uac00\uc838\uc624\uc9c0 \uc54a\ub3c4\ub85d \uc124\uc815\ub428
+ConfigView.section.stats.exportfiles=\ud30c\uc77c \uc138\ubd80\uc0ac\ud56d \ub0b4\ubcf4\ub0b4\uae30
+updater.cant.write.to.app.title=\uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \ud3f4\ub354\uc5d0 \uae30\ub85d\ud560 \uc218 \uc5c6\uc74c
+updater.cant.write.to.app.details=%1 \ud3f4\ub354\uc5d0 \uae30\ub85d\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\n\uc774 \ubb38\uc81c\ub294 \uc774\ud6c4\uc5d0 \uc801\uc6a9\ub418\ub294 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5c5\ub370\uc774\ud2b8\ub97c \ud560 \uc218 \uc5c6\uac8c\ud569\ub2c8\ub2e4.\n\n<a href="http://wiki.vuze.com/w/Failed_Update">\uc790\uc138\ud55c \uc0ac\ud56d\uc5d0 \ub300\ud574\uc11c\ub294 Wiki</a>\ub97c \ucc38\uc870 \ubc14\ub78d\ub2c8\ub2e4.
+plugin.install.class_version_error=\uc774 \ud50c\ub7ec\uadf8\uc778\uc744 \uc2e4\ud589\ud558\ub824\uba74 \ub354 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc758 Java\uac00 \ud544\uc694\ud569\ub2c8\ub2e4.
+v3.MainWindow.tab.minilibrary=\ub2e4\uc6b4\ub85c\ub4dc
 v3.MainWindow.tab.events=\uc54c\ub9bc
-button.columnsetup.tooltip=\uc138\ub85c\uc904 \uc124\uc815
+button.columnsetup.tooltip=\uc5f4 \uc124\uc815
 v3.activity.remove.title=\uc54c\ub9bc \uc0ad\uc81c
-v3.activity.remove.text=\uc774 \ub0b4\uc6a9\uc744 \uc54c\ub9bc\uc5d0\uc11c \uc0ad\uc81c\ud560\uae4c\uc694?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
+v3.activity.remove.text=\uc815\ub9d0\ub85c \uc774 \uc54c\ub9bc\uc744 \uc0ad\uc81c\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?\n%1
 v3.MainWindow.menu.file.closewindow=\ub2eb\uae30
-Menu.show.torrent.menu=\ud1a0\ub7f0\ud2b8 \uba54\ub274 \ubcf4\uae30
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
-Views.plugins.aznetstatus.title=\ub124\ud2b8\uc6cc\ud06c \uc0c1\ud0dc 
+Menu.show.torrent.menu=\ud1a0\ub80c\ud2b8 \uba54\ub274 \ubcf4\uc5ec\uc8fc\uae30
+Menu.show.torrent.menu.tooltip=\uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \uc0c1\ub2e8 \uba54\ub274 \ub9c9\ub300\uc5d0 \ud1a0\ub80c\ud2b8 \uba54\ub274\ub97c \ubcf4\uc5ec\uc8fc\uae30
+Views.plugins.aznetstatus.title=\ub124\ud2b8\uc6cc\ud06c \uc0c1\ud0dc
+plugin.aznetstatus.pingtarget=\ud551/\ucd94\uc801 \ub77c\uc6b0\ud130 \ud45c\uc801
+ConfigView.section.style.usePathFinder='Finder' \ub300\uc2e0 'Path Finder' \uc0ac\uc6a9
 menu.sortByColumn=%1\ub85c \uc815\ub82c
-v3.button.removeActivityEntry=\uc54c\ub9bc\uc5d0\uc11c \uc81c\uac70
-v3.splash.initSkin=UI \uc2a4\ud0a8 \ucd08\uae30\ud654
-v3.splash.hookPluginUI=\ucd94\uac00\uae30\ub2a5 UI \uace0\uc815
+MyTorrentsView.menu.manual.per_peer=\uc218\ub3d9 (\ud53c\uc5b4 \ub2e8\uc704)
+MyTorrentsView.menu.manual.shared_peers=\uc218\ub3d9 (\ud53c\uc5b4 \uc804\uccb4)
+v3.button.removeActivityEntry=\uc54c\ub9bc \uc81c\uac70
+v3.splash.initSkin=UI \uc2a4\ud0a8 \ucd08\uae30\ud654 \uc911
+v3.splash.hookPluginUI=\ud50c\ub7ec\uadf8\uc778 UI \ub04c\uc5b4\uc624\ub294 \uc911
+OpenTorrentWindow.mb.notTorrent.cannot.display=\ub370\uc774\ud130\ub97c \uc62c\ubc14\ub85c \ud45c\uc2dc\ud560 \uc218 \uc5c6\uc74c
 MainWindow.menu.window.zoom.maximize=\ucd5c\ub300\ud654
-MainWindow.menu.window.zoom.restore=\ub418\ub3cc\ub9ac\uae30
+MainWindow.menu.window.zoom.restore=\uc774\uc804 \ud06c\uae30\ub85c
+security.crypto.title=\uc554\ud638\ud0a4 \uc811\uadfc
+security.crypto.encrypt=\uc0c8\ub85c \uc0dd\uc131\ub41c \uc554\ud638\ud0a4\ub97c \ubcf4\ud638\ud558\uae30\uc704\ud55c \uc554\ud638\ub97c \uc785\ub825\ud558\uc2ed\uc2dc\uc624. \uc774 \uc554\ud638\ub97c \uc783\uc5b4\ubc84\ub9ac\uc9c0 \ub9c8\uc2ed\uc2dc\uc624. \uc783\uc5b4\ubc84\ub9ac\uba74 \ubcf5\uad6c\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \uc5c6\uc2b5\ub2c8\ub2e4!
+security.crypto.decrypt=\uc554\ud638\ud0a4\ub97c \ud480\uae30\uc704\ud55c \uc554\ud638\ub97c \uc785\ub825\ud558\uc2ed\uc2dc\uc624.
+security.crypto.reason=\uc791\uc5c5\uc5d0 \ub300\ud55c \uc774\uc720
 security.crypto.password=\uc554\ud638
-security.crypto.password2=\uc554\ud638 \uc7ac\uc785\ub825
+security.crypto.password2=\uc554\ud638 \ub2e4\uc2dc \uc785\ub825
+security.crypto.persist_for=\uc554\ud638 \uc9c0\uc18d \uae30\uac04
+security.crypto.persist_for.dont_save=\uc800\uc7a5\ud558\uc9c0 \uc54a\uc74c
 security.crypto.persist_for.session=\uc774\ubc88 \uc138\uc158
-security.crypto.persist_for.day=\ud558\ub8e8
-security.crypto.persist_for.week=\ud55c\uc8fc
-security.crypto.persist_for.30days=\ud55c\ub2ec
-security.crypto.persist_for.forever=\uc885\ud569
+security.crypto.persist_for.day=1\uc77c
+security.crypto.persist_for.week=1\uc8fc
+security.crypto.persist_for.30days=30\uc77c
+security.crypto.persist_for.forever=\uc601\uad6c
 security.crypto.password.mismatch.title=\uc554\ud638 \uc624\ub958
-ConfigView.section.security.group.crypto=\uacf5\uac1c/\ube44\uacf5\uac1c \ud0a4
+security.crypto.password.mismatch=\uc554\ud638\uac00 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \uc785\ub825\ud558\uc2ed\uc2dc\uc624.
+ConfigView.section.security.group.crypto=\uacf5\uac1c\ud0a4/\uac1c\uc778\ud0a4
 ConfigView.section.security.resetkey=\ud0a4 \ucd08\uae30\ud654
-ConfigView.section.security.resetkey.warning.title=\ub370\uc774\ud0c0 \uc720\uc2e4 \uacbd\uace0
+ConfigView.section.security.resetkey.warning.title=\ub370\uc774\ud130 \uc190\uc2e4 \uacbd\uace0
+ConfigView.section.security.resetkey.warning=\uc815\ub9d0\ub85c \uc554\ud638\ud654 \ud0a4\uc758 \ucd08\uae30\ud654 \ud558\uae30\ub97c \uc6d0\ud558\uc2ed\ub2c8\uae4c? \ud574\ub2f9 \ud0a4\ub85c \uc554\ud638\ud654\ud55c \ubaa8\ub4e0 \uc815\ubcf4\ub294 *\uc601\uad6c\uc801\uc73c\ub85c \uc190\uc2e4*\ub429\ub2c8\ub2e4. \ub610\ud55c \ud574\ub2f9 \uacf5\uac1c\ud0a4\ub97c \uc18c\uc720\ud558\uace0 \uc788\ub294 \ub2e4\ub978 \ud53c\uc5b4 \uc5ed\uc2dc \uc0c8\ub85c\uc6b4 \ud0a4\ub97c \ubc1b\uae30 \uc80 [...]
+ConfigView.section.security.unlockkey=\uba85\uc2dc\uc801\uc778 \ud0a4 \uc7a0\uae08\ud574\uc81c
 ConfigView.section.security.unlockkey.button=\uc7a0\uae08\ud574\uc81c
-ConfigView.section.security.publickey=\uacf5\uac1c \ud0a4
+ConfigView.section.security.publickey=\uacf5\uac1c\ud0a4
 ConfigView.section.security.publickey.undef=\uc815\uc758 \ub418\uc9c0 \uc54a\uc74c
-ConfigView.section.security.resetkey.error.title=\uc791\ub3d9 \uc2e4\ud328
+ConfigView.section.security.resetkey.error.title=\uc791\uc5c5 \uc2e4\ud328
 ConfigView.section.security.resetkey.error=\ud0a4 \ucd08\uae30\ud654 \uc2e4\ud328
+ConfigView.section.security.unlockkey.error=\ud0a4 \uc7a0\uae08\ud574\uc81c \uc2e4\ud328 - \uc798\ubabb\ub41c \uc554\ud638
 ConfigView.copy.to.clipboard.tooltip=\ud074\ub9bd\ubcf4\ub4dc\ub85c \ubcf5\uc0ac
 Views.plugins.azbuddy.title=\uce5c\uad6c
-Browser.popup.error.no.access=\uc6d0\uaca9 \uc811\uc18d\uc744 \ud558\ub294\ub3d9\uc548 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4.\n\uc7a0\uc2dc \ud6c4 \ub2e4\uc2dc \ud55c\ubc88 \uc2dc\ub3c4\ud574 \uc8fc\uc138\uc694.
+Browser.popup.error.no.access=\uc6d0\uaca9 \ub9ac\uc18c\uc2a4\uc5d0 \uc811\uadfc \ud558\ub294 \ub3c4\uc911\uc5d0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4.\n\ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+ConfigView.label.queue.stoponcebandwidthmet=\uc5c5\ub85c\ub4dc/\ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \uc81c\ud55c\uc5d0 \ub3c4\ub2ec\ud558\uba74 \ub354\uc774\uc0c1 \ud1a0\ub80c\ud2b8\ub97c \uc2dc\uc791\ud558\uc9c0 \uc54a\uc74c
+ConfigView.section.style.forceMozilla=\ube0c\ub77c\uc6b0\uc800 \uc704\uc82f\uc744 \uc704\ud574 Vuze\uac00 Mozilla\ub97c \uc0ac\uc6a9\ud558\ub3c4\ub85d \uac15\uc81c [XULRunner\ub098 Firefox 3 \ud544\uc694; \ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
+ConfigView.section.style.xulRunnerPath=XulRunner / Firefox \uacbd\ub85c \uc218\ub3d9 \uc9c0\uc815 [Firefox 3 \ud544\uc694; \ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694]
 azbuddy.name=\uce5c\uad6c
-azbuddy.enabled=\uc791\ub3d9
-azbuddy.disabled=\ucd94\uac00\uae30\ub2a5\uc774 \uc791\ub3d9\uc911\uc9c0\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ucd94\uac00\uae30\ub2a5 \uc120\ud0dd\uc0ac\ud56d\uc744 \ucc38\uace0\ud558\uc138\uc694.
-azbuddy.nickname=\ubcc4\uba85
+azbuddy.enabled=\ud65c\uc131\ud654
+azbuddy.disabled=\ud50c\ub7ec\uadf8\uc778\uc774 \ube44\ud65c\uc131 \ub428, \ubcc0\uacbd\ud558\ub824\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815\uc744 \ucc38\uace0\ud558\uc138\uc694.
+azbuddy.nickname=\uc0ac\uc6a9\uc790 \ubcc4\uba85
 azbuddy.msglog.title=\uce5c\uad6c \uc815\ubcf4
-azbuddy.addtorrent.title=\uc790\ub8cc\ub97c \ub0b4\ub824\ubc1b\uc73c\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
-azbuddy.addtorrent.msg='%1' \uac00 '%2'\ub97c \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.\n\uc790\ub8cc\ub97c \ub0b4\ub824\ubc1b\uc73c\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+azbuddy.addtorrent.title=\ub2e4\uc6b4\ub85c\ub4dc\ub97c \uc218\ub77d\ud569\ub2c8\uae4c?
+azbuddy.addtorrent.msg=\uce5c\uad6c '%1'\uac00 '%2'\ub97c \ubcf4\ub0c8\uc2b5\ub2c8\ub2e4.\n\uc774 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \ucd94\uac00\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
 azbuddy.contextmenu=\uce5c\uad6c\uc5d0\uac8c \ubcf4\ub0b4\uae30
-azbuddy.ui.mykey=\ud0a4:
-azbuddy.ui.add=\ub354\ud558\uae30
-azbuddy.ui.new_buddy=\uc0c8 \uce5c\uad6c\uc758 \ud0a4:
+azbuddy.ui.mykey=\ub0b4 \ud0a4:
+azbuddy.ui.add=\ucd94\uac00
+azbuddy.ui.new_buddy=\uc0c8 \uce5c\uad6c \ud0a4:
 azbuddy.ui.table.name=\uc774\ub984
 azbuddy.ui.table.online=\uc628\ub77c\uc778
-azbuddy.ui.table.last_msg=\ub9c8\uc9c0\ub9c9 \ucabd\uc9c0
+azbuddy.ui.table.last_msg=\ub9c8\uc9c0\ub9c9 \uba54\uc2dc\uc9c0
 azbuddy.ui.menu.remove=\uc81c\uac70
 azbuddy.ui.menu.copypk=\uacf5\uac1c\ud0a4 \ubcf5\uc0ac
-azbuddy.ui.menu.send=\ucabd\uc9c0 \ubcf4\ub0b4\uae30
-azbuddy.ui.menu.send_msg=\uce5c\uad6c\uc5d0\uac8c \ubcf4\ub0bc \ucabd\uc9c0\ub0b4\uc6a9\uc744 \uc785\ub825\ud558\uc138\uc694
+azbuddy.ui.menu.send=\uba54\uc2dc\uc9c0 \ubcf4\ub0b4\uae30
+azbuddy.ui.menu.send_msg=\uce5c\uad6c\uc5d0\uac8c \ubcf4\ub0bc \ud14d\uc2a4\ud2b8\ub97c \uc785\ub825
 azbuddy.ui.menu.ping=\ud551
-azbuddy.ui.menu.ygm=YGM\ubcf4\ub0b4\uae30
-azbuddy.ui.menu.enc=\uac8c\uc2dc\ud310 \uc554\ud638\ud654
-azbuddy.ui.menu.dec=\uac8c\uc2dc\ud310 \uc554\ud638\ud574\uc81c
-azbuddy.ui.menu.sign=\uac8c\uc2dc\ud310\uc5d0 \uc4f0\uae30
-azbuddy.ui.menu.verify=\uac8c\uc2dc\ud310 \ud655\uc778
-azbuddy.ui.table.lastseen=\ub9c8\uc9c0\ub9c9 \uc811\uc18d
-Button.retry=\ub2e4\uc2dc\uc2dc\ub3c4 &R
-Button.ignore=\ubb34\uc2dc &I
-azbuddy.ui.table.msg_in=\ubc1b\uc740 \ucabd\uc9c0
-azbuddy.ui.table.msg_out=\ubcf4\ub0b8 \ucabd\uc9c0 
+azbuddy.ui.menu.ygm=YGM \ubcf4\ub0b4\uae30
+azbuddy.ui.menu.enc=\ud074\ub9bd\ubcf4\ub4dc \uc554\ud638\ud654
+azbuddy.ui.menu.dec=\ud074\ub9bd\ubcf4\ub4dc \ubcf5\ud638\ud654
+azbuddy.ui.menu.sign=\ud074\ub9bd\ubcf4\ub4dc \uc11c\uba85
+azbuddy.ui.menu.verify=\ud074\ub9bd\ubcf4\ub4dc \uac80\uc99d
+azbuddy.ui.table.lastseen=\ub9c8\uc9c0\ub9c9 \ub9cc\ub0a8
+Button.retry=\ub2e4\uc2dc\uc2dc\ub3c4(&R)
+Button.ignore=\ubb34\uc2dc(&I)
+DHTView.general.skew=\ube57\ub098\uac10:
+azbuddy.ui.table.msg_in=Msg \uc778
+azbuddy.ui.table.msg_out=Msg \uc544\uc6c3
 v3.MainWindow.menu.view.footer=\uaf2c\ub9ac\ub9d0
-azbuddy.downspeed=\uce5c\uad6c\ub85c\ubd80\ud130 \ub0b4\ub824\ubc1b\uae30 \uc18d\ub3c4 \ucd5c\ub300\uac12 KB/s [0: \ubb34\uc81c\ud55c]
+azbuddy.downspeed=KB/s \ucd5c\ub300 \uce5c\uad6c \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 [0: unlimited]
+security.crypto.badpw=\uc81c\uacf5\ub41c \uc554\ud638\uac00 \uc62c\ubc14\ub974\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
 ConfigView.section.security.backupkeys=\ud0a4\ub97c \ud30c\uc77c\ub85c \ubc31\uc5c5
 ConfigView.section.security.backupkeys.button=\ubc31\uc5c5
-ConfigView.section.security.restorekeys=\ud30c\uc77c\ub85c \ubd80\ud130 \ud0a4 \ubcf5\uad6c
+ConfigView.section.security.restorekeys=\ud30c\uc77c\ub85c\ubd80\ud130 \ud0a4 \ubcf5\uad6c
 ConfigView.section.security.restorekeys.button=\ubcf5\uad6c
-ConfigView.section.security.op.error.title=\uc791\ub3d9 \uc2e4\ud328
-ConfigView.section.security.restart.title=\uc7ac\uc2dc\uc791\uc774 \ud544\uc694\ud568
-azbuddy.ui.table.msg_queued=\ub300\uae30
+ConfigView.section.security.op.error.title=\uc791\uc5c5 \uc2e4\ud328
+ConfigView.section.security.op.error=\uc791\uc5c5 \uc644\ub8cc \uc2e4\ud328:\n    %1
+ConfigView.section.security.restart.title=\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694
+ConfigView.section.security.restart.msg=Vuze\ub294 \uc791\uc5c5\uc744 \uc644\ub8cc\ud558\uae30 \uc704\ud574 \ub2e4\uc2dc \uc2dc\uc791\ud569\ub2c8\ub2e4.
+ConfigView.section.security.system.managed=\uc2dc\uc2a4\ud15c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 \ud0a4 \ubcf4\ud638
+azbuddy.ui.table.msg_queued=\ub300\uae30\uc5f4\uc5d0 \ub4e4\uc5b4\uac10
 azbuddy.ui.menu.chat=\ub300\ud654
-azbuddy.chat.title=Vuze \ub300\ud654\uc2e4
-azbuddy.chat.says=%1 :
-Button.bar.show=\ubcf4\uc774\uae30
+azbuddy.chat.title=Vuze \ub300\ud654
+azbuddy.chat.says=%1 \ub9d0:
+Button.bar.show=\ubcf4\uc5ec\uc8fc\uae30
 Button.bar.hide=\uc228\uae30\uae30
 Button.bar.share=\uacf5\uc720
 Button.bar.add=\ucd94\uac00
 Button.bar.edit=\ud3b8\uc9d1
 Button.bar.edit.cancel=\ud3b8\uc9d1 \uc644\ub8cc
-v3.MainWindow.menu.view.pluginbar=\ucd94\uac00\uae30\ub2a5 \ud45c\uc2dc\uc904
+v3.MainWindow.menu.view.pluginbar=\ud50c\ub7ec\uadf8\uc778 \ub9c9\ub300
 MainWindow.dialog.select.vuze.file=Vuze \ud30c\uc77c \uc120\ud0dd
 MainWindow.menu.file.open.vuze=Vuze \ud30c\uc77c...
-metasearch.addtemplate.title=\uac80\uc0c9\ud55c \uc591\uc2dd\uc744 \uc124\uce58\ud560\uae4c\uc694?
-v3.share.private.title=\ud1a0\ub7f0\ud2b8 \uacf5\uc720
-v3.share.private.text=\uc120\ud0dd\ub41c \ud1a0\ub7f0\ud2b8\ub294 \ube44\uacf5\uac1c \ud1a0\ub7f0\ud2b8 \uc785\ub2c8\ub2e4.\n\n\ube44\uacf5\uac1c \ud1a0\ub7f0\ud2b8\ub294 \uacf5\uc720\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
-metasearch.addtemplate.dup.title=\uc591\uc2dd \ubcf5\uc0ac
-metasearch.addtemplate.dup.desc=\uac80\uc0c9\ud55c \uc591\uc2dd %1\uc740 \uc774\ubbf8 \uc124\uce58\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.
-metasearch.export.select.template.file=\uc591\uc2dd \uc800\uc7a5
-metasearch.import.select.template.file=\uc591\uc2dd \uc5f4\uae30
-dialog.uiswitch.title=Vuze UI \ubcc0\uacbd
-dialog.uiswitch.text=\uc774 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\ub824\uba74 Vuze UI\ub97c \uc791\ub3d9\uc2dc\ucf1c\uc57c \ud569\ub2c8\ub2e4.\n\nVuze\ub97c \ub2e4\uc2dc\uc2dc\uc791 \ud569\ub2c8\ub2e4.
-dialog.uiswitch.button=Vuze UI\ub85c \ubcc0\uacbd
-azbuddy.tracker.enabled=\uce5c\uad6c\uc640 \ub0b4\ub824\ubc1b\uae30\uc2dc '\uce5c\uad6c \uac00\uc18d' \uae30\ub2a5\uc744 \uc791\ub3d9\ud569\ub2c8\ub2e4
-azbuddy.protocolspeed=\uce5c\uad6c\ub85c\ubd80\ud130 \uc624\ubc84\ud5e4\ub4dc \ud504\ub85c\ud1a0\ucf5c \ucd5c\ub300\uac12 KB/s 
-v3.MainWindow.button.download=\ub0b4\ub824\ubc1b\uae30
-v3.MainWindow.button.run=\ub0b4\ub824\ubc1b\uc740 \ud30c\uc77c \uc2e4\ud589
-v3.activity.header.downloads=\ub0b4\ub824\ubc1b\uae30
+metasearch.addtemplate.title=\uac80\uc0c9 \ud15c\ud50c\ub9bf\uc744 \uc124\uce58\ud569\ub2c8\uae4c?
+metasearch.addtemplate.desc=\uc815\ub9d0\ub85c '%1' \uac80\uc0c9 \ud15c\ud50c\ub9bf\uc744 \uc124\uce58\ud569\ub2c8\uae4c?
+v3.share.private.title=\ud1a0\ub80c\ud2b8 \uacf5\uc720
+v3.share.private.text=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8\ub294 \ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8\ub85c \ud45c\uc2dc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\n\ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8\ub294 \uacf5\uc720\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+metasearch.addtemplate.dup.title=\ud15c\ud50c\ub9bf \ubcf5\uc81c
+metasearch.addtemplate.dup.desc=%1 \uac80\uc0c9 \ud15c\ud50c\ub9bf\uc740 \uc774\ubbf8 \uc124\uce58\ub418\uc5b4 \uc788\uc74c
+metasearch.export.select.template.file=\ud15c\ud50c\ub9bf \uc800\uc7a5
+metasearch.import.select.template.file=\ud15c\ud50c\ub9bf \uc5f4\uae30
+azbuddy.tracker.enabled=\uce5c\uad6c\uc5d0\uac8c \uc6b0\uc120 \uc21c\uc704\ub97c \ubd80\uc5ec\ud574\uc11c \ub2e4\uc6b4\ub85c\ub4dc\ud558\ub294 '\uce5c\uad6c \ubc00\uc5b4\uc8fc\uae30'\ub97c \ud65c\uc131\ud654
+azbuddy.protocolspeed=KB/s \ucd5c\ub300 \uce5c\uad6c \ud504\ub85c\ud1a0\ucf5c \uc624\ubc84\ud5e4\ub4dc
+v3.MainWindow.button.download=\ub2e4\uc6b4\ub85c\ub4dc
+v3.MainWindow.button.run=\ub2e4\uc6b4\ub85c\ub4dc\ub41c \ud30c\uc77c \uc2e4\ud589
+v3.activity.header.downloads=\ub2e4\uc6b4\ub85c\ub4dc
 v3.activity.header.vuze.news=Vuze \uc0c8\uc18c\uc2dd
+message.taking.too.long=\uc608\uc0c1\ud55c \uac83\ubcf4\ub2e4 \uc791\uc5c5\uc774 \uc624\ub798\uac78\ub9ac\ub294 \uac83\uc73c\ub85c \ubcf4\uc785\ub2c8\ub2e4.\n\uc774 \uc791\uc5c5\uc744 \ucde8\uc18c\ud558\ub824\uba74 'ESC'\ub97c \ub204\ub974\uc138\uc694.
 message.status.success=\uc131\uacf5
-azbuddy.tracker.bbb.status.title=\uce5c\uad6c \uac00\uc18d
-azbuddy.tracker.bbb.status.title.tooltip=\uc138\ubd80\ub0b4\uc6a9\uc744 \ubcf4\uc2dc\ub824\uba74 \ub354\ube14\ud074\ub9ad \ud558\uc138\uc694
-azbuddy.tracker.bbb.status.idle=\uac00\uc18d \uc5c6\uc74c
+azbuddy.tracker.bbb.status.title=\uce5c\uad6c \ubc00\uc5b4\uc8fc\uae30
+azbuddy.tracker.bbb.status.title.tooltip=\uc138\ubd80\uc0ac\ud56d\uc740 \ub354\ube14\ud074\ub9ad
+azbuddy.tracker.bbb.status.idle=\ubc00\uc5b4\uc8fc\uae30 \uc5c6\uc74c
 azbuddy.tracker.bbb.status.nli=\ub85c\uadf8\uc778\uc774 \ud544\uc694\ud568
-azbuddy.tracker.bbb.status.in=\uac00\uc18d \uc2dc\uc791
-azbuddy.tracker.bbb.status.out=\uc774\ubbf8 \uac00\uc18d\ub41c \uce5c\uad6c
+azbuddy.tracker.bbb.status.in=\uc9c0\uc9c0\ubc1b\uace0 \uc788\ub294 \uc911
+azbuddy.tracker.bbb.status.out=\ud604\uc7ac \ubc00\uc5b4\uc8fc\ub294 \uce5c\uad6c
 v3.MainWindow.search.go.tooltip=\uac80\uc0c9 \uc2e4\ud589
-v3.MainWindow.search.last.tooltip=\uac80\uc0c9\uacb0\uacfc\ub85c \uc774\ub3d9
+v3.MainWindow.search.last.tooltip=\uac80\uc0c9\uacb0\uacfc\ub85c \ub3cc\uc544\uac00\uae30
 metasearch.addtemplate.done.title=\ud15c\ud50c\ub9bf \ucd94\uac00
-fileplugininstall.install.title=\ucd94\uac00\uae30\ub2a5\uc744 \uc124\uce58 \ud560\uae4c\uc694?
-fileplugininstall.duplicate.title=\ucd94\uac00\uae30\ub2a5 \ubcf5\uc0ac
-azbuddy.online_status=\uc811\uc18d \uc0c1\ud0dc
+metasearch.addtemplate.done.desc='%1' \ud15c\ud50c\ub9bf\uc774 \uc131\uacf5\uc801\uc73c\ub85c \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\ub2e4\uc74c \uac80\uc0c9 \uc2dc \uc0ac\uc6a9\ub429\ub2c8\ub2e4!
+ConfigView.section.security.nopw=\uc81c\uacf5\ub41c \uc554\ud638 \uc5c6\uc74c
+ConfigView.section.security.nopw_v=\uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc554\ud638 \uc5c6\uc74c, Vuze\uc5d0 \ub85c\uadf8\uc778 \ud574\uc8fc\uc138\uc694
+fileplugininstall.install.title=\ud50c\ub7ec\uadf8\uc778 \uc124\uce58?
+fileplugininstall.install.desc=\uc815\ub9d0\ub85c \ud50c\ub7ec\uadf8\uc778 '%1', \ubc84\uc804 %2\ub97c \uc124\uce58\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+fileplugininstall.duplicate.title=\ud50c\ub7ec\uadf8\uc778 \ubcf5\uc0ac
+fileplugininstall.duplicate.desc=\ud50c\ub7ec\uadf8\uc778 '%1', \ubc84\uc804 %2\ub294 \uc774\ubbf8 \uc124\uce58\ub418\uc5b4 \uc788\uc74c
+azbuddy.online_status=\uc628\ub77c\uc778 \uc0c1\ud0dc
 azbuddy.os_online=\uc628\ub77c\uc778
 azbuddy.os_away=\uc790\ub9ac\ube44\uc6c0
-azbuddy.os_not_avail=\ube44\ud65c\uc131
+azbuddy.os_not_avail=\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c
 azbuddy.os_busy=\ubc14\uc068
 azbuddy.os_offline=\uc624\ud504\ub77c\uc778
 azbuddy.ui.menu.disconnect=\uc5f0\uacb0\ub04a\uae30
-azbuddy.enable_chat_notif=\ub300\ud654 \uc54c\ub9bc \uc791\ub3d9
+azbuddy.enable_chat_notif=\ub300\ud654 \uc54c\ub9bc \ud65c\uc131\ud654
+progress.window.msg.progress=\uc791\uc5c5\uc774 \uc644\ub8cc\ub418\ub294 \ub3d9\uc548 \uae30\ub2e4\ub9ac\uc2ed\uc2dc\uc624
+ConfigView.section.connection.advanced.read_select=\uc120\ud0dd \uc77d\uae30 \uc2dc\uac04\uc81c\ud55c (millis, \uae30\ubcf8\uac12 %1)
+ConfigView.section.connection.advanced.read_select_min=\uc120\ud0dd \uc77d\uae30 \ucd5c\uc18c \ub300\uae30 (millis, \uae30\ubcf8\uac12 %1)
+ConfigView.section.connection.advanced.write_select=\uc120\ud0dd \uc4f0\uae30 \uc2dc\uac04\uc81c\ud55c (millis, \uae30\ubcf8\uac12 %1)
+ConfigView.section.connection.advanced.write_select_min=\uc120\ud0dd \uc4f0\uae30 \ucd5c\uc18c \ub300\uae30 (millis, \uae30\ubcf8\uac12 %1)
 DetailedListView.title=\uc138\ubd80 \ubaa9\ub85d
+ConfigView.section.connection.network.max.outstanding.connect.attempts=\ucd5c\ub300 \ubbf8\uc644\uc758 \ub098\uac00\ub294 \uc5f0\uacb0
+plugins.init.force_enabled=Vuze\ub294 \ud50c\ub7ec\uadf8\uc778 "%1"\uc774 \ube44\ud65c\uc131 \ub418\uc5c8\uc74c\uc744 \uac10\uc9c0\ud588\uc2b5\ub2c8\ub2e4 - Vuze\uac00 \uc62c\ubc14\ub85c \ub3d9\uc791\ud558\uac8c \ud558\ub824\uba74 \ub2e4\uc2dc \ud560\uc1bd\ud654\ud574\uc57c \ud569\ub2c8\ub2e4.
+ConfigView.section.connection.prefer.udp=UDP \uc5f0\uacb0 \uc120\ud638
 subscript.add.title=\uad6c\ub3c5\uc744 \uc124\uce58\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
-subscript.add.desc='%1'\ub97c \uad6c\ub3c5\ud558\uc5ec \uc124\uce58\ud558\uc2dc\uae38 \uc6d0\ud558\uc2ed\ub2c8\uae4c?
-subscript.add.dup.title=\ubcf5\uc0ac\ud558\uae30
-subscript.add.dup.desc='%1'\ub294 \uc774\ubbf8 \uad6c\ub3c5\ud558\uc5ec \uc124\uce58\ud558\uc600\uc2b5\ub2c8\ub2e4.
-subscript.add.upgrade.title=\uad6c\ub3c5\uc744 \uc5c5\ub370\uc774\ud2b8 \ud560\uae4c\uc694?
-subscript.add.upgrade.desc='%1'\uc744 \uc5c5\ub370\uc774\ud2b8 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
-subscript.add.upgradeto.desc=\uad6c\ub3c5\uc911\uc778 %1 \ubc84\uc804\uc758 \uc0c8 \ubc84\uc804\uc778 '%2'\uc744 \uc5c5\ub370\uc774\ud2b8 \uac00\ub2a5\ud569\ub2c8\ub2e4.\n\uc5c5\ub370\uc774\ud2b8 \ud560\uae4c\uc694?
-azsubs.contextmenu.addassoc=\uc0c8 \uad6c\ub3c5 \uc5f0\ub3d9 \ucd94\uac00\ud558\uae30
-azsubs.contextmenu.lookupassoc=\uad6c\ub3c5 \uc5f0\ub3d9 \ubcf4\uae30
+subscript.add.desc=\uc815\ub9d0\ub85c '%1' \uad6c\ub3c5\uc744 \uc124\uce58\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+subscript.add.dup.title=\uad6c\ub3c5 \ubcf5\uc81c
+subscript.add.dup.desc='%1' \uad6c\ub3c5\uc740 \uc774\ubbf8 \uc124\uce58\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+subscript.add.upgrade.title=\uad6c\ub3c5\uc744 \uc5c5\uadf8\ub808\uc774\ub4dc \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+subscript.add.upgrade.desc=\uc815\ub9d0\ub85c '%1' \uad6c\ub3c5\uc744 \uc5c5\uadf8\ub808\uc774\ub4dc \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+subscript.add.upgradeto.desc='%2' \uad6c\ub3c5\uc758 %1 \ubc84\uc804\uc774 \uc0ac\uc6a9 \uac00\ub2a5\ud569\ub2c8\ub2e4.\n\uc5c5\ub370\uc774\ud2b8 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+azsubs.contextmenu.addassoc=\uad6c\ub3c5 \uc5f0\ub3d9 \ucd94\uac00
+azsubs.contextmenu.lookupassoc=\uad6c\ub3c5 \uc5f0\ub3d9 \ucc3e\uc544\ubcf4\uae30
 iconBar.start=\uc2dc\uc791
-iconBar.stop=\uba48\ucda4
+iconBar.stop=\uc815\uc9c0
 iconBar.remove=\uc0ad\uc81c
 iconBar.up=\uc704\ub85c
 iconBar.down=\uc544\ub798\ub85c
 iconBar.run=\uc2e4\ud589
-iconBar.editcolumns=\uc138\ub85c\uc904 \uc124\uc815
-iconBar.top=\uc704\ub85c \uc62e\uae40
-iconBar.bottom=\uc544\ub798\ub85c \uc62e\uae40
+iconBar.editcolumns=\uc5f4 \uc124\uc815
+iconBar.top=\ub9e8 \uc704\ub85c \uc774\ub3d9
+iconBar.bottom=\ub9e8 \uc544\ub798\ub85c \uc774\ub3d9
 iconBar.queue=\uc2dc\uc791
-iconBar.open=\ud1a0\ub7f0\ud2b8 \ucd94\uac00
+iconBar.open=\ud1a0\ub80c\ud2b8 \ucd94\uac00
 iconBar.share=\uacf5\uc720
-iconBar.share.tooltip=\uacf5\uc720 \uc790\ub8cc
-iconBar.details=\uc138\ubd80\ub0b4\uc6a9
-iconBar.comment=\ub367\ub9d0
+iconBar.share.tooltip=\ucf58\ud150\uce20 \uacf5\uc720
+iconBar.details=\uc138\ubd80\uc0ac\ud56d
+iconBar.comment=\uc8fc\uc11d
 iconBar.play=\uc7ac\uc0dd
-iconBar.queue.tooltip=\ub300\uae30
-v3.MainWindow.menu.view.sidebar=\uce21\uba74 \ud45c\uc2dc\uc904 
-v3.MainWindow.menu.view.actionbar=\uc2e4\ud589 \ud45c\uc2dc\uc904
-v3.MainWindow.menu.view.toolbars=\ub3c4\uad6c \ud45c\uc2dc\uc904
-subscriptions.listwindow.title=\uad6c\ub3c5\uac00\ub2a5\ud55c \uc790\ub8cc \ucc3e\uae30
-subscriptions.listwindow.autochecktext=Vuze\ub294 \uc790\ub3d9\uc73c\ub85c \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 \uc788\ub294 \uc790\ub8cc\uc640 \uc720\uc0ac\ud55c \uad6c\ub3c5\uc744 \ucc3e\uc544 \uc81c\uc2dc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774\uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+iconBar.queue.tooltip=\uc120\ud0dd\ud55c \ud1a0\ub80c\ud2b8\ub97c \uc2dc\uc791 (\ub300\uae30\uc5f4\uc5d0 \ub123\uae30)
+v3.MainWindow.menu.view.sidebar=\uc0ac\uc774\ub4dc \ubc14
+v3.MainWindow.menu.view.actionbar=\ud65c\ub3d9 \ub9c9\ub300
+v3.MainWindow.menu.view.toolbars=\ub3c4\uad6c\ubaa8\uc74c
+ump.install=\ube60\ub978 \uc5c5\ub370\uc774\ud2b8\uac00 \uc9c4\ud589 \uc911\uc785\ub2c8\ub2e4:\n\uc774 \ube44\ub514\uc624\uc5d0 \ub300\ud574 \ud544\uc694\ud55c \uc791\uc740 \uc7ac\uc0dd \ucd94\uac00 \uae30\ub2a5\uc774 \uc124\uce58\ub418\uace0 \uc788\uc2b5\ub2c8\ub2e4.
+subscriptions.listwindow.title=\uad6c\ub3c5 \uac80\uc0c9\uae30
+subscriptions.listwindow.autochecktext=Vuze\ub294 \uc0ac\uc6a9\uc790 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 \uc788\ub294 \ucf58\ud150\uce20\uc640 \uc5f0\uad00\uc774 \uc788\ub294 \uad6c\ub3c5\uc744 \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uae30\ub2a5\uc744 \ud65c\uc131\ud654 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
 subscriptions.listwindow.loadingtext=%1\uacfc \uc5f0\uad00\ub41c \uad6c\ub3c5\uc744 \ucc3e\uc544\ubcf4\uae30
-subscriptions.listwindow.failed=\uad6c\ub3c5\uac00\ub2a5\ud55c \uc790\ub8cc\uac00 \uc5c6\uc74c
+subscriptions.listwindow.failed=\ucc3e\uc740 \uad6c\ub3c5 \uc5c6\uc74c
 subscriptions.listwindow.popularity=\uc778\uae30\ub3c4
-subscriptions.listwindow.popularity.unknown=\uc54c\uc218\uc5c6\uc74c
+subscriptions.listwindow.popularity.unknown=\uc54c \uc218 \uc5c6\uc74c
 subscriptions.listwindow.name=\uc774\ub984
 subscriptions.listwindow.subscribe=\uad6c\ub3c5
 TableColumn.header.azsubs.ui.column.subs=\uad6c\ub3c5
-subscriptions.listwindow.popularity.reading=\uc77d\ub294\uc911...
-PluginDeprecation.view=\uc624\ub958\ucd94\uc801 \ucd94\uac00\uae30\ub2a5
+subscriptions.listwindow.popularity.reading=\uc77d\ub294 \uc911...
+PluginDeprecation.log.start=\uc774 \ucc3d\uc740 \uc55e\uc73c\ub85c\uc758 Vuze \ubc84\uc804\uc5d0\uc11c \uc81c\uac70\ub420 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\ub294 \ud50c\ub7ec\uadf8\uc778\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ud3ec\ud568\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n\ud50c\ub7ec\uadf8\uc778\uc744 \uc81c\uac70\ud560 \ud544\uc694\ub294 \uc5c6\uc2b5\ub2c8\ub2e4\ub9cc \ucd5c\uc2e0\ubc84\uc804\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ub294 \ud574\uc8fc\uc154\uc57c\ud569\ub2c8\ub2e4. [...]
+PluginDeprecation.view=\ud50c\ub7ec\uadf8\uc778 \ub514\ubc84\uadf8
+PluginDeprecation.alert=\ud50c\ub7ec\uadf8\uc778\uc740 \uc55e\uc73c\ub85c \uc81c\uac70\ub420 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc2b5\ub2c8\ub2e4 - \uc790\uc138\ud55c \uc0ac\ud56d\uc740 \ud50c\ub7ec\uadf8\uc778 \ub514\ubc84\uadf8 \ub85c\uadf8 \ubcf4\uae30\ub97c \uc5f4\uc5b4\ubcf4\uc2ed\uc2dc\uc624.
 TableColumn.header.Thumbnail=\uc544\uc774\ucf58
-v3.MainWindow.menu.getting_started=&\uc2dc\uc791\ud558\uae30
-MainWindow.menu.community=&\ucee4\ubba4\ub2c8\ud2f0
-MainWindow.menu.help.faq=\uc790\uc8fc \ubb3b\ub294 \ubb3c\uc74c(&F)
-MainWindow.menu.community.wiki=\ucee4\ubba4\ub2c8\ud2f0 &\uc704\ud0a4
-MainWindow.menu.community.forums=\ucee4\ubba4\ub2c8\ud2f0 Fo&rums
-MainWindow.menu.community.blog=Vuze &\ube14\ub85c\uadf8
+TableColumn.header.Thumbnail.info=Vuze \ucf58\ud150\uce20\uc5d0 \ub300\ud55c \ubbf8\ub9ac\ubcf4\uae30 \uc774\ubbf8\uc9c0 \uc785\ub2c8\ub2e4. \ub2e4\ub978 \ubaa8\ub4e0 \ucf58\ud150\uce20\uc5d0 \ub300\ud574\uc11c \uc6b4\uc601\uccb4\uc81c\ub294 \uc774\ub7ec\ud55c \uc544\uc774\ucf58\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.
+v3.MainWindow.menu.getting_started=\uc2dc\uc791\ud558\uae30(&G)
+MainWindow.menu.community=\ucee4\ubba4\ub2c8\ud2f0(&C)
+MainWindow.menu.community.wiki=\ucee4\ubba4\ub2c8\ud2f0 Wiki(&W)
+MainWindow.menu.community.forums=\ucee4\ubba4\ub2c8\ud2f0 \ud3ec\ub7fc(&R)
+MainWindow.menu.community.blog=Vuze \ube14\ub85c\uadf8(&B)
+MainWindow.menu.help.support=\ub3c4\uc6c0\ub9d0\uacfc \uc9c0\uc6d0(&H)
 externalLogin.title=\ub85c\uadf8\uc778 \ud544\uc694
+externalLogin.explanation=%1 \ud0ec\ud50c\ub9bf\uc740 \ub85c\uadf8\uc778\uc774 \ud544\uc694\ud569\ub2c8\ub2e4. \uc77c\ub2e8 \ub85c\uadf8\uc778\ub418\uba74 \uc774 \ucc3d\uc740 \uc790\ub3d9\uc73c\ub85c \ub2eb\ud799\ub2c8\ub2e4. \ub9cc\uc57d \uadf8\ub807\uac8c \ub418\uc9c0 \uc54a\uc73c\uba74 "\uc644\ub8cc"\ub97c \ud074\ub9ad\ud558\uc154\uc11c \ub2eb\uc544\uc8fc\uc138\uc694.
+externalLogin.explanation.capture=\uc774 \ud15c\ud50c\ub9bf\uc744 \uc0dd\uc131\ud558\uae30 \uc704\ud574 \ub85c\uadf8\uc778\ud574\uc57c \ud569\ub2c8\ub2e4. \uc791\uc5c5\uc744 \ub9c8\uce5c \ud6c4, "\uc644\ub8cc"\ub97c \ud074\ub9ad\ud574\uc8fc\uc2ed\uc2dc\uc624.
 Button.done=\uc644\ub8cc
+GeneralView.torrent_created_on_and_by=%1 / %2
 Button.continue=\uacc4\uc18d
 Button.preview=\ubbf8\ub9ac\ubcf4\uae30
 Subscription.menu.forcecheck=\uc9c0\uae08 \uc5c5\ub370\uc774\ud2b8
-Subscription.menu.clearall=\ubaa8\ub4e0 \uc790\ub8cc\ub97c "\uc77d\uc74c" \uc0c1\ud0dc\ub85c \ud45c\uc2dc
+Subscription.menu.clearall=\ubaa8\ub4e0 \uacb0\uacfc\ub97c "\uc77d\uc74c" \uc0c1\ud0dc\ub85c \ud45c\uc2dc
 Subscription.menu.remove=\uc0ad\uc81c
 sidebar.Library=\ub77c\uc774\ube0c\ub7ec\ub9ac
-sidebar.LibraryDL=\ub0b4\ub824\ubc1b\ub294 \uc911
-sidebar.LibraryCD=\uc644\ub8cc
+sidebar.LibraryDL=\ub2e4\uc6b4\ub85c\ub4dc \uc911
+sidebar.LibraryCD=\uc644\ub8cc\ub428
 authenticator.location=\uc704\uce58
-authenticator.details=\uc138\ubd80\uc815\ubcf4
-v3.MainWindow.menu.showActionBarText=\ubb38\uc790\ubcf4\uae30
+authenticator.details=\uc138\ubd80\uc0ac\ud56d
+v3.MainWindow.menu.showActionBarText=\ud14d\uc2a4\ud2b8 \ubcf4\uc5ec\uc8fc\uae30
+subscript.import.fail.title=\uac00\uc838\uc624\uae30 \uc2e4\ud328
+subscript.import.fail.desc=\uc138\ubd80\uc0ac\ud56d: %1
 Subscription.menu.export=\ub0b4\ubcf4\ub0b4\uae30
 subscript.export.select.template.file=\uad6c\ub3c5 \uc800\uc7a5
 Button.remove=\uc81c\uac70
 Button.send=\ubcf4\ub0b4\uae30
 Button.back=\ub4a4\ub85c
-sidebar.LibraryUnopened=\ub0b4\ub824\ubc1b\uae30 \uc644\ub8cc
+sidebar.LibraryUnopened=\ubcf4\uc9c0 \uc54a\uc558\uc74c
 TableColumn.header.unopened=\uc2e0\uaddc
 Unopened.bigView.header=\uc2e0\uaddc
-Subscription.menu.deleteall=\ubaa8\ub4e0 \uc790\ub8cc \uc0ad\uc81c
-Subscription.menu.reset=\ucc98\uc74c \uc0c1\ud0dc\ub85c \ucd08\uae30\ud654
+Subscription.menu.deleteall=\ubaa8\ub4e0 \uacb0\uacfc \uc0ad\uc81c
+Subscription.menu.reset=\ucd08\uae30 \uc0c1\ud0dc\ub85c \ucd08\uae30\ud654
 ConfigView.section.Subscriptions=\uad6c\ub3c5
-subscriptions.config.maxresults=\uad6c\ub3c5\ubcc4 \uc720\uc9c0\ud558\uace0 \uc788\ub294 \uc790\ub8cc\uc758 \ucd5c\ub300\uac12 [0: \ubb34\uc81c\ud55c]
+subscriptions.config.maxresults=\uad6c\ub3c5\ub9c8\ub2e4 \ud3ec\ud568\ud558\uac8c \ub420 \ucd5c\ub300 \uacb0\uacfc \uc218 [0: \ubb34\uc81c\ud55c]
 v3.activity.button.readall=\ubaa8\ub450 \uc77d\uc5c8\uc74c\uc73c\ub85c \ud45c\uc2dc
 TableColumn.header.activityNew=\uc2e0\uaddc
-TableColumn.header.activityType=\uc885\ub958
-TableColumn.header.activityText=\ub0b4\uc6a9
-TableColumn.header.activityDate=\ucd94\uac00 \ub0a0\uc9dc
-TableColumn.header.activityActions=\ud3c9\uac00
-Subscription.menu.resetauth=\uc778\uc99d \uc815\ubcf4 \ucd08\uae30\ud654
-Search.menu.engines=\uc591\uc2dd
+TableColumn.header.activityType=\uc720\ud615
+TableColumn.header.activityText=\uba54\uc2dc\uc9c0
+TableColumn.header.activityDate=\ucd94\uac00\ub41c \ub0a0\uc9dc
+TableColumn.header.activityActions=\ub3d9\uc791
+Subscription.menu.resetauth=\uc778\uc99d \uc138\ubd80\uc0ac\ud56d \ucd08\uae30\ud654
+Search.menu.engines=\ud15c\ud50c\ub9bf
 Wizard.Subscription.title=\uad6c\ub3c5
-Wizard.Subscription.optin.title=\uad6c\ub3c5\uc791\ub3d9
-#what you've watched? Discover more with a single click...
+Wizard.Subscription.optin.title=\uad6c\ub3c5 \ud65c\uc131\ud654
 Wizard.Subscription.subscribe.title=\ud65c\uc131\ud654 \uad6c\ub3c5
 Wizard.Subscription.create.title=\uc0c8 \uad6c\ub3c5 \ub9cc\ub4e4\uae30
 Button.search=\uac80\uc0c9
 Button.save=\uc800\uc7a5
 Button.add=\ucd94\uac00
-Button.createNewSubscription=\uc0c8\ub85c\uc6b4 \uc790\ub8cc \uad6c\ub3c5 \ud558\uae30
-Button.availableSubscriptions=\uc0ac\uc6a9\uac00\ub2a5\ud55c \uad6c\ub3c5
-Wizard.Subscription.optin.description=\uad6c\ub3c5\uae30\ub2a5\uc744 \uc791\ub3d9\uc2dc\ud0a4\uba74, Vuze\ub294 \uc790\ub3d9\uc73c\ub85c \uad6c\ub3c5\ud55c \uc790\ub8cc\ub97c \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 \ud45c\uc2dc\ud558\uc5ec \uc190\uc27d\uac8c \ub0b4\ub824\ubc1b\uc744 \ud560 \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4.\n\n\uad6c\ub3c5\uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+Button.createNewSubscription=\uc0c8 \uad6c\ub3c5 \uc0dd\uc131
+Button.availableSubscriptions=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uad6c\ub3c5
+Wizard.Subscription.optin.description=\uad6c\ub3c5\uae30\ub2a5\uc744 \ud65c\uc131\ud654 \ud558\uba74, Vuze\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 \uc788\ub294 \ucf58\ud150\uce20\uc640 \uc5f0\uad00\ub41c \uad6c\ub3c5\uc744 \ubcf4\uc5ec\uc8fc\uba70 \uad6c\ub3c5\ud55c \ucf58\ud150\uce20\uac00 \ub2e4\uc6b4\ub85c\ub4dc \ud560 \uc218 \uc788\uc744 \ub54c \uc54c\ub824\uc90d\ub2c8\ub2e4.\n\n\uad6c\ub3c5 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
 Wizard.Subscription.create.search=\uac80\uc0c9
 Wizard.Subscription.search.subtitle1=\uac80\uc0c9\uc744 \ud1b5\ud574 \uc790\ub8cc\ub97c \uad6c\ub3c5\ud558\uc138\uc694 :
 Wizard.Subscription.search.subtitle2=\uc5b4\ub5a4\uc790\ub8cc\ub97c \uad6c\ub3c5\ud560 \uc218 \uc788\uc744\uae4c\uc694?
 Wizard.Subscription.search.subtitle2.sub1=Vuze \ub124\ud2b8\uc6cc\ud06c\uc758 \ub2e4\uc591\ud55c HD \uc601\ud654, TV \uc1fc, \ub4dc\ub77c\ub9c8 \uc608\uace0\ud3b8\ub97c \uad6c\ub3c5\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-Wizard.Subscription.search.subtitle2.sub2=\uc778\ud130\ub137\uc5d0 \uc788\ub294 \ud1a0\ub7f0\ud2b8\ub97c \uad6c\ub3c5\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+Wizard.Subscription.search.subtitle2.sub2=\uc6f9\uc744 \ud1b5\ud574 \uc5bb\uc740 \ud1a0\ub80c\ud2b8
 Wizard.Subscription.search.subtitle3=\uad6c\ub3c5\uc744 \uc2dc\uc791\ud558\uba74, \uc0c8\ub85c\uc6b4 \uc790\ub8cc\uac00 \uc62c\ub77c\uc62c\ub54c \ub9c8\ub2e4 \uce21\uba74 \ud45c\uc2dc\uc904\uc5d0\uc11c \uace7\ubc14\ub85c \ud655\uc778\ud558\uc2e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
 Wizard.Subscription.rss.subtitle1=\uad6c\ub3c5\ud560 URL\uc744 \uc544\ub798\uc5d0 \uc801\uc73c\uc138\uc694 :
 Wizard.Subscription.rss.subtitle2=\ub9ce\uc740 \uc790\ub8cc\uac00 RSS\ud53c\ub4dc\ub85c \ubc30\ud3ec\ub418\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uc6f9\uc0ac\uc774\ud2b8\uc5d0\uc11c URL\uc8fc\uc18c\ub97c \ucc3e\uc544 \uc717\uce78\uc5d0 \ub123\uace0, \uc800\uc7a5\uc744 \ub20c\ub7ec\uc8fc\uc138\uc694.
-Wizard.Subscription.rss.subtitle3=\uc790\ub8cc \ubc30\ud3ec\uc790\uac00 RSS \ud53c\ub4dc\ub97c \ud1b5\ud574 \uc0c8\ub85c\uc6b4 \uc790\ub8cc\ub97c \uacf5\uc9c0\ud558\uba74, \uce21\uba74 \ud45c\uc2dc\uc904\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ub0b4\ub824\ubc1b\uae30 \uac00\ub2a5\ud55c \uc790\ub8cc\uac00 \uc5c5\ub370\uc774\ud2b8\ub429\ub2c8\ub2e4.
+Wizard.Subscription.rss.subtitle3=\uc77c\ub2e8 \uc800\uc7a5\ub418\uba74, RSS \ud53c\ub4dc\ub97c \ud1b5\ud574 \uc0c8 \uacb0\uacfc\uac00 \uc0ac\uc6a9 \uac00\ub2a5\ud574\uc9c0\uba74 \ud56d\uc0c1 \uc0ac\uc774\ub4dc \ubc14\uc5d0\uc11c \uc2e4\uc2dc\uac04 \uc5c5\ub370\uc774\ud2b8\ub97c \ubc1b\uac8c \ub429\ub2c8\ub2e4.
 Wizard.Subscription.subscribe.library=\ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \uc790\ub8cc
 Wizard.Subscription.subscribe.subscriptions=\uc5f0\uad00\ub41c \uad6c\ub3c5
 Wizard.Subscription.subscribe.library.empty=\uc544\uc9c1 \uad6c\ub3c5\ud558\ub294 \uc790\ub8cc\uac00 \uc5c6\uc73c\uc138\uc694?\n \nVuze HD \ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \ub178\ub780\uc0c9\uc73c\ub85c \ub41c RSS \uad6c\ub3c5 \ub2e8\ucd94\ub97c \ub20c\ub7ec\ubcf4\uc138\uc694.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\uad00\ub828\ub0b4\uc6a9</A>
-message.confirm.delete.title=\uc0ad\uc81c \ud655\uc778
-message.confirm.delete.text='%1'\ub97c \uc815\ub9d0\ub85c \uc9c0\uc6b0\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
-Subscription.menu.properties=\uc6b0\uc120\uc21c\uc704
-subs.prop.is_auto=\uc0c8 \uacb0\uacfc\uc5d0 \ub300\ud574 \uc790\ub3d9 \ub0b4\ub824\ubc1b\uae30
-subs.prop.last_scan=\ub9c8\uc9c0\ub9c9 \uc131\uacf5 \uc5c5\ub370\uc774\ud2b8
+message.confirm.delete.title=\uc0ad\uc81c \uc2b9\uc778
+message.confirm.delete.text=\uc815\ub9d0\ub85c '%1'\ub97c \uc0ad\uc81c\ud569\ub2c8\uae4c?
+Subscription.menu.properties=\uc18d\uc131
+props.window.title='%1' \uc18d\uc131
+subs.prop.is_auto=\uc0c8 \uacb0\uacfc \uc790\ub3d9 \ub2e4\uc6b4\ub85c\ub4dc
+subs.prop.last_scan=\ub9c8\uc9c0\ub9c9 \uc5c5\ub370\uc774\ud2b8 \uc131\uacf5
 subs.prop.last_result=\ub9c8\uc9c0\ub9c9 \uc0c8 \uacb0\uacfc \ucc3e\uae30
 subs.prop.last_error=\ub9c8\uc9c0\ub9c9 \uc624\ub958
-subs.prop.num_read=\uc77d\uc740 \uc790\ub8cc\uc218
-subs.prop.num_unread=\uc54a\uc77d\uc740 \uc790\ub8cc\uc218
-subs.prop.template=\uc591\uc2dd
-externalLogin.wait=\ud654\uba74 \ubd88\ub7ec\uc624\ub294\uc911, \uc7a0\uc2dc\ub9cc \uae30\ub2e4\ub824 \uc8fc\uc138\uc694.
-TableColumn.menu.date_added.time=\uc2dc\uac04 \ubcf4\uc774\uae30/\uc228\uae30\uae30
+subs.prop.num_read=\uc77d\uc740 \uacb0\uacfc \uc218
+subs.prop.num_unread=\uc77d\uc9c0\uc54a\uc740 \uacb0\uacfc \uc218
+subs.prop.template=\ud15c\ud50c\ub9bf
+subs.prop.auth=\uc778\uc99d \ud544\uc694
+externalLogin.auth_method_proxy=\ud655\uc7a5\ub41c \ucfe0\ud0a4 \ucea1\uccd0 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4. \uc791\ub3d9\uc774 \uc548\ub418\uba74 \uc635\uc158\uc744 \ube44\ud65c\uc131\ud654\ud558\uace0 \ub2e4\uc2dc \uc2dc\ub3c4
+externalLogin.wait=\ud398\uc774\uc9c0\ub97c \ubd88\ub7ec\uc624\ub294 \uc911, \uae30\ub2e4\ub824\uc8fc\uc2ed\uc2dc\uc624...
+TableColumn.menu.date_added.time=\uc2dc\uac04 \ubcf4\uc5ec\uc8fc\uae30/\uc228\uae30\uae30
 sidebar.VuzeHDNetwork=Vuze HD \ub124\ud2b8\uc6cc\ud06c
+subs.prop.next_scan=\ub2e4\uc74c \uac80\uc0c9:
+subs.prop.assoc=\uc5f0\uacb0
 subs.prop.version=\ubc84\uc804
-subscriptions.column.new.info=\uc0c8\ub85c\uc6b4 \uacb0\uacfc\uac00 \uc788\uc73c\uba74 \ud45c\uc2dc\ud568
-subscriptions.column.name=\uc774\ub984
-subscriptions.column.nb-results=\ubaa8\ub4e0 \uc790\ub8cc
-subscriptions.column.nb-new-results=\uc0c8 \uc790\ub8cc
-subscriptions.column.last-checked=\ub9c8\uc9c0\ub9c9 \ud655\uc778
+subscriptions.column.new.info=\ud558\ub098 \uc774\uc0c1\uc758 \uc0c8 \uacb0\uacfc\uac00 \uc788\uc73c\uba74 \ud45c\uc2dc
+subscriptions.column.name=\uad6c\ub3c5
+subscriptions.column.nb-results=\uc804\uccb4 \uacb0\uacfc
+subscriptions.column.nb-new-results=\uc0c8 \uacb0\uacfc
+subscriptions.column.last-checked=\ucd5c\uadfc \uac80\uc0ac
 subscriptions.view.title=\uad6c\ub3c5
 subs.prop.is_public=\uacf5\uac1c\ub428
-Subscription.menu.upgrade=\ucd5c\uc2e0 \ubc84\uc804\uc73c\ub85c \uc790\ub3d9 \uc5c5\ub370\uc774\ud2b8 \uae30\ub2a5 \uc0ac\uc6a9
+subs.prop.high_version=\ucd5c\uace0 \ubc84\uc804 \ubc1c\uacac
+Subscription.menu.upgrade=\ub192\uc740 \ubc84\uc804\uc73c\ub85c \uc5c5\uadf8\ub808\uc774\ub4dc \ud65c\uc131\ud654
+metasearch.template.version.bad='%1' \uac80\uc0c9 \ud15c\ud50c\ub9bf\uc740 Vuze\ub97c \uc5c5\uadf8\ub808\uc774\ub4dc\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc124\uce58\ud560 \uc218 \uc5c6\uc74c
 metasearch.addtemplate.failed.title=\uc124\uce58 \uc2e4\ud328
-metasearch.addtemplate.failed.desc=\uac80\uc0c9\ud55c \uc591\uc2dd\uc744 \uc124\uce58\ud558\ub294\ub370 \uc2e4\ud328\ud568: %1
-subscription.version.bad=Vuze\ub97c \uc5c5\ub370\uc774\ud2b8 \ud558\uae30\uc804\uae4c\uc9c0 '%1'\uac00 \uc124\uce58 \ub420 \uc218 \uc5c6\uc74c 
-statusbar.feedback=\uc758\uacac \ubcf4\ub124\uae30
-statusbar.feedback.tooltip=\uc5ec\uae30\ub97c \ub20c\ub7ec\uc11c \uc81c\uc791\uc9c4\uc5d0\uac8c \uc870\uc5b8/\uc758\uacac\uc744 \ubcf4\ub0c5\ub2c8\ub2e4.
+metasearch.addtemplate.failed.desc=\uac80\uc0c9 \ud15c\ud50c\ub9bf \uc124\uce58 \uc2e4\ud328: %1
+subscription.version.bad=Vuze\ub97c \uc5c5\ub370\uc774\ud2b8 \ud558\uae30\uc804\uae4c\uc9c0 '%1'\uac00 \uc124\uce58 \ub420 \uc218 \uc5c6\uc74c
+statusbar.feedback=\ud53c\ub4dc\ubc31 \ubcf4\ub0b4\uae30
+statusbar.feedback.tooltip=\ud53c\ub4dc\ubc31\uc744 \ubcf4\ub0b4\ub824\uba74 \uc5ec\uae30\ub97c \ud074\ub9ad
 sidebar.Activity=\uc54c\ub9bc
-v3.activity.button.watchall=\ubaa8\ub4dc \ubcf4\uc558\uc74c\uc73c\ub85c \ud45c\uc2dc
-subscriptions.view.help.1=\ubcf4\uace0\uc2f6\uc740 \uc790\ub8cc\ub97c \uad6c\ub3c5\ud558\uc138\uc694
-subscriptions.view.help.2=\ub0b4\ub824\ubc1b\uae30 \uac00\ub2a5\ud55c \uc0c8\uc790\ub8cc\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ud558\ub294 \ubc29\ubc95\uc744 \ud65c\uc6a9\ud558\uc138\uc694. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\ub354 \uc54c\uc544\ubcf4\uae30</A>.
-sidebar.sash.tooltip=F7\ub85c \uce21\uba74 \ud45c\uc2dc\uc904 \ubcf4\uc774\uae30/\uc228\uae30\uae30
-sidebar.expand.tooltip=\uce21\uba74 \ud45c\uc2dc\uc904 \ud3bc\uce58\uae30
-sidebar.dropdown.tooltip=\uba54\ub274\uc5d0\uc11c \uce21\uba74 \ud45c\uc2dc\uc904 \ud45c\uc2dc
-subscript.all.subscribed=\uc774 \uc790\ub8cc\ub97c \uad6c\ub3c5\ud588\uc2b5\ub2c8\ub2e4
-subscript.some.subscribed=\uc774 \uc790\ub8cc\ub97c \uc704\ud574\uc11c \uc774\ubbf8 \uad6c\ub3c5\ud558\uace0 \uc788\ub294\uac83\uc774 \uc788\uc2b5\ub2c8\ub2e4.\n\ub0b4\uc6a9\uc744 \ubcf4\uc2dc\ub824\uba74 \ud074\ub9ac\ud558\uc138\uc694
-subscript.none.subscribed=\uc774 \uc790\ub8cc\uc640 \uc5f0\uad00\ub41c \uad6c\ub3c5\uc744 \ubcf4\uc2dc\ub824\uba74 \ud074\ub9ad\ud558\uc138\uc694
-v3.iconBar.up.tooltip=\uc704\ub85c \uc62c\ub9ac\uc138\uc694.\n\ub9c8\uc6b0\uc2a4 \ub2e8\ucd94\ub97c \ub204\ub978\ucc44\ub85c \uc704\ub85c \uc62c\ub9ac\uc138\uc694.
-v3.iconBar.down.tooltip=\uc544\ub798\ub85c \ub0b4\ub9ac\uc138\uc694.\n\ub9c8\uc6b0\uc2a4 \ub2e8\ucd94\ub97c \ub204\ub978\ucc44\ub85c \uc544\ub798\ub85c \ub0b4\ub9ac\uc138\uc694.
-TableColumn.header.azsubs.ui.column.subs_link.info=\uad6c\ub3c5\uacfc \ud568\uaed8 \uc5f0\ub3d9
+v3.activity.button.watchall=\ubaa8\ub450 \ubcf4\uc558\uc74c\uc73c\ub85c \ud45c\uc2dc
+subscriptions.view.help.1=\uc5b4\ub514\uc11c\ub4e0\uc9c0 \uad6c\ub3c5\uc744 \ucd94\uac00
+subscriptions.view.help.2=\uc5b8\uc81c\ub4e0\uc9c0 \uc0c8 \ucf58\ud150\uce20\ub97c \ub2e4\uc6b4\ub85c\ub4dc \ud560 \uc218 \uc788\ub294 \uc2e4\uc2dc\uac04 \uc5c5\ub370\uc774\ud2b8\ub97c \ubb34\ub8cc\ub85c \uc5bb\uc73c\uc138\uc694. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\uc790\uc138\ud788 \ubcf4\uae30</A>.
+sidebar.sash.tooltip=F7\ub85c \uc0ac\uc774\ub4dc\ubc14 \ube60\ub978 \ubcf4\uc5ec\uc8fc\uae30/\uc228\uae30\uae30
+sidebar.expand.tooltip=\uc0ac\uc774\ub4dc\ubc14 \ud655\uc7a5
+sidebar.dropdown.tooltip=\uba54\ub274\uc5d0 \uc0ac\uc774\ub4dc\ubc14 \ubcf4\uc5ec\uc8fc\uae30
+subscript.all.subscribed=\uc774 \ucf58\ud150\uce20\ub97c \uad6c\ub3c5\ud588\uc2b5\ub2c8\ub2e4
+subscript.some.subscribed=\uc774 \ucf58\ud150\uce20\ub97c \uc77c\ubd80 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \uad6c\ub3c5\uc744 \uc774\ubbf8 \uad6c\ub3c5\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4.\n\ub2e4\ub978 \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uad6c\ub3c5\uc744 \ubcf4\ub824\uba74 \ud074\ub9ad
+subscript.none.subscribed=\uc774 \ucf58\ud150\uce20\uc5d0 \ub300\ud55c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uad6c\ub3c5\uc744 \ubcf4\ub824\uba74 \ud074\ub9ad
+v3.iconBar.up.tooltip=\uc704\ub85c \uc774\ub3d9\n\ub9e8 \uc704\ub85c \uc774\ub3d9\ud558\ub824\uba74 \ub9c8\uc6b0\uc2a4 \ubc84\ud2bc\uc744 \uacc4\uc18d \ub204\ub974\uace0 \uacc4\uc2ed\uc2dc\uc624.
+v3.iconBar.down.tooltip=\uc544\ub798\ub85c \uc774\ub3d9\n\ub9e8 \uc544\ub798\ub85c \uc774\ub3d9\ud558\ub824\uba74 \ub9c8\uc6b0\uc2a4 \ubc84\ud2bc\uc744 \uacc4\uc18d \ub204\ub974\uace0 \uacc4\uc2ed\uc2dc\uc624.
+TableColumn.header.azsubs.ui.column.subs_link=\uc5f0\uacb0
+TableColumn.header.azsubs.ui.column.subs_link.info=\uad6c\ub3c5\uacfc\uc758 \uc5f0\uacb0\uc785\ub2c8\ub2e4.
 Button.deleteContent.fromLibrary=\ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc81c\uac70
-Button.deleteContent.fromComputer=\ub514\uc2a4\ud06c\uc5d0\uc11c \uc9c0\uc6b0\uae30
-v3.deleteContent.message=\n'%1'\ub97c \ub514\uc2a4\ud06c\uc5d0\uc11c \uc9c0\uc6b0\uc2dc\uaca0\uc2b5\ub2c8\uae4c? \uc544\ub2c8\uba74 Vuze \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \ud45c\uc2dc\uac00 \uc548\ub418\uac8c \uc81c\uac70\ub9cc \ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.
-v3.MainWindow.menu.view.toolbartext=\ub3c4\uad6c \ud45c\uc2dc\uc904 \ubb38\uc790
-v3.MainWindow.menu.view.asSimpleList=\uac04\ub2e8\ubaa9\ub85d
-v3.MainWindow.menu.view.asAdvancedList=\uace0\uae09\ubaa9\ub85d
+Button.deleteContent.fromComputer=\ucef4\ud4e8\ud130\uc5d0\uc11c \uc0ad\uc81c
+v3.deleteContent.message=\n\ucef4\ud4e8\ud130\uc5d0\uc11c '%1'\ub97c \uc0ad\uc81c\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c? \uc544\ub2c8\uba74 Vuze \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c\ub9cc \uc81c\uac70\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+v3.MainWindow.menu.view.toolbartext=\ub3c4\uad6c\ubaa8\uc74c \ud14d\uc2a4\ud2b8
+v3.MainWindow.menu.view.asSimpleList=\uac04\ub2e8 \ubaa9\ub85d
+v3.MainWindow.menu.view.asAdvancedList=\uace0\uae09 \ubaa9\ub85d
 v3.MainWindow.menu.view.statusbar=\uc0c1\ud0dc \ud45c\uc2dc\uc904
-Subscription.menu.dirtyall=\ubaa8\ub4e0 \uc790\ub8cc\ub97c "\uc77d\uc9c0 \uc54a\uc74c" \uc0c1\ud0dc\ub85c \ud45c\uc2dc
-configureWizard.file.message3=Vuze\uc5d0\uc11c \ub0b4\ub824\ubc1b\uc740 \ud30c\uc77c\uc744 \ubcf4\uad00\ud560 \ud3f4\ub354\ub97c \uc9c0\uc815\ud558\uc138\uc694:
-v3.deleteContent.applyToAll=\uc120\ud0dd\ub41c \ubaa8\ub4e0 %1\uc5d0 \uc801\uc6a9\ud569\ub2c8\ub2e4.
-v3.MainWindow.menu.contentnetworks=HD &\ub124\ud2b8\uc6cc\ud06c
-v3.MainWindow.menu.contentnetworks.about=HD \ub124\ud2b8\uc6cc\ud06c\uc5d0 \uad00\ud558\uc5ec
-ConfigTransferAutoSpeed.auto.speed.neural=\uc77c\ubc18 \uc790\ub3d9 \uc18d\ub3c4 \uc870\uc808(\uad6c\ub514 \uc54c\ud30c)
-ConfigView.label.autoopen.downloadbars=\ub0b4\ub824\ubc1b\uae30 \ud45c\uc2dc\uc904 \uc790\ub3d9\uc5f4\uae30
+Subscription.menu.dirtyall=\ubaa8\ub4e0 \uacb0\uacfc\ub97c "\uc77d\uc9c0 \uc54a\uc74c" \uc0c1\ud0dc\ub85c \ud45c\uc2dc
+configureWizard.file.message3=Vuze\ub294 \ud2b9\uc815 \ud3f4\ub354\uc5d0 \ud30c\uc77c\uc744 \ub2e4\uc6b4\ub85c\ub4dc\ud558\uac8c \ub429\ub2c8\ub2e4. \uadf8 \ud3f4\ub354\ub97c \uc5ec\uae30\uc5d0 \uc9c0\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4:
+v3.deleteContent.applyToAll=\ubaa8\ub4e0 \uc120\ud0dd\ud55c \ud56d\ubaa9 %1\uc5d0 \ub3d9\uc791\uc744 \uc801\uc6a9
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=\ub2e4\uc74c \uc2dc\uac04 \ub3d9\uc548 \uc5b4\ub5a4 \uc5c5\ub85c\ub4dc\ub3c4 \ud558\uc9c0 \uc54a\ub294 \ud1a0\ub80c\ud2b8
+v3.MainWindow.menu.contentnetworks=HD \ub124\ud2b8\uc6cc\ud06c(&N)
+v3.MainWindow.menu.contentnetworks.about=HD \ub124\ud2b8\uc6cc\ud06c \uc815\ubcf4
+Peers.column.as.info=\ud53c\uc5b4\uc758 AS (\uc790\uc728 \uc2dc\uc2a4\ud15c) \uc138\ubd80\uc0ac\ud56d
+ConfigTransferAutoSpeed.auto.speed.neural=\uc2e0\uacbd\ub9dd(Gudy \uc54c\ud30c)
+ConfigView.label.autoopen.downloadbars=\ub2e4\uc74c \uc870\uac74\uc744 \ub9cc\uc871\ud560 \ub54c, \ub2e4\uc6b4\ub85c\ub4dc \ub9c9\ub300 \uc790\ub3d9 \uc5f4\uae30
 ConfigView.label.autoopen=\uc790\ub3d9 \uc5f4\uae30
-ConfigView.label.autoopen.detailstab=\uc138\ubd80\ub0b4\uc6a9 \ud45c\uc2dc\uc904 \uc790\ub3d9\uc5f4\uae30 
-v3.MainWindow.menu.contentnetworks.manage=&HD \ub124\ud2b8\uc6cc\ud06c \uad00\ub9ac
-azbuddy.ui.menu.cat=\ubaa9\ub85d
-azbuddy.ui.menu.cat.share=\uce5c\uad6c\uc640 \ud568\uaed8 \uad6c\ub3c5 \uc791\ub3d9
-azbuddy.ui.menu.cat.set=\ubaa9\ub85d \uc785\ub825
-azbuddy.ui.menu.cat.set_msg=\uc27c\ud45c\ub85c \ubaa9\ub85d\uc744 \ub098\ub20c \uc218 \uc788\uc73c\uba70 '\uc804\ubd80' \uc0ac\uc6a9\ud560 \uc218 \ub3c4 \uc788\uc2b5\ub2c8\ub2e4
+ConfigView.label.autoopen.detailstab=\ub2e4\uc74c \uc870\uac74\uc744 \ub9cc\uc871\ud560 \ub54c, \uc138\ubd80 \uc0ac\ud56d \ud0ed \uc790\ub3d9 \uc5f4\uae30
+ConfigView.label.systray=\uc2dc\uc2a4\ud15c \ud2b8\ub798\uc774
+ConfigView.label.systray._mac=\uc0c1\ud0dc \ub9c9\ub300 \uc544\uc774\ucf58
+ConfigView.section.interface.legacy=\ub9ac\uac70\uc2dc
+v3.MainWindow.menu.contentnetworks.manage=HD \ub124\ud2b8\uc6cc\ud06c \uad00\ub9ac(&M)
+azbuddy.ui.table.loc_cat=Cats \uc544\uc6c3
+azbuddy.ui.table.rem_cat=Cats \uc778
+azbuddy.ui.menu.cat=\ubd84\ub958
+azbuddy.ui.menu.cat.share=\uce5c\uad6c\uc640 \ud568\uaed8 \uad6c\ub3c5 \ud65c\uc131\ud654
+azbuddy.ui.menu.cat.set=\ubd84\ub958 \uc785\ub825
+azbuddy.ui.menu.cat.set_msg=\ucf64\ub9c8\ub85c \ubd84\ub958 \ubaa9\ub85d\uc744 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc73c\uba74 '\ubaa8\ub450'
 azbuddy.ui.menu.cat_subs=\uad6c\ub3c5
 subs.prop.update_period=\uc5c5\ub370\uc774\ud2b8 \uac04\uaca9
-azbuddy.enable_cat_pub=\ubaa8\ub4e0 \uce5c\uad6c\uac00 \uacf5\uac1c\ub41c \ubd84\ub958\ub97c \uad6c\ub3c5\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4 (','\ub85c \uad6c\ubd84\ud568)
-v3.dialog.cnclose.title=%1 \ub2eb\ud798
-v3.dialog.cnclose.subtitle=\uc54c\ub9bc
-v3.dialog.cnclose.info1=HD \ub124\ud2b8\uc6cd\uc73c\ub85c\uc758 \uc811\uc18d\uc744 \ub2eb\uc73c\uc168\uc2b5\ub2c8\ub2e4.
-v3.dialog.cnclose.info2=HD \ub124\ud2b8\uc6cd\uc5d0 \ub2e4\uc2dc \uc811\uadfc\ud558\uc2dc\ub824\uba74, \ud654\uba74 \uc717\ubd80\ubd84\uc5d0 "HD \ub124\ud2b8\uc6cd" \uba54\ub274\uc5d0\uc11c "HD \ub124\ud2b8\uc6cd"\uc744 \ub204\ub974\uc2dc\uba74 \ub429\ub2c8\ub2e4.
-v3.dialog.cnclose.noshow=\ub2e4\uc2dc \ubcf4\uc5ec\uc8fc\uc9c0 \uc54a\uc74c
-v3.dialog.cnmanage.title=HD \ub124\ud2b8\uc6cc\ud06c \uad00\ub9ac \uba54\ub274
-v3.dialog.cnmanage.intro="HD \ub124\ud2b8\uc6cc\ud06c" \uba54\ub274\uc5d0\uc11c \ubcf4\uc774\uace0 \uc2f6\uc740 \uc790\ub8cc\ub97c \uc544\ub798\uc5d0\uc11c \uc120\ud0dd\ud558\uc138\uc694
-TableColumn.header.name.info=\ud1a0\ub7f0\ud2b8 \uc774\ub984
-TableColumn.header.size.info=\ub514\uc2a4\ud06c\uc5d0\uc11c \ud1a0\ub7f0\ud2b8 \uc790\ub8cc\uc758 \ud06c\uae30
-TableColumn.header.azsubs.ui.column.subs.info=\uc774 \ub2e8\ucd94\ub85c \uc5f0\uad00\ub41c \ud1a0\ub7f0\ud2b8\ub97c \uad6c\ub3c5\ubc1b\uc744 \uc218 \uc788\uc74c
-TableColumn.header.upspeed.info=\ud604\uc7ac\uae4c\uc9c0 \uc62c\ub9ac\uae30 \uc18d\ub3c4
-TableColumn.header.downspeed.info=\ud604\uc7ac\uae4c\uc9c0 \ub0b4\ub824\ubc1b\uc740 \uc18d\ub3c4
-TableColumn.header.up.info=\ud604\uc7ac\uae4c\uc9c0\ub2e4\ub978 \uc0ac\uc6a9\uc790\uc5d0\uac8c \ubcf4\ub0b8 \ub370\uc774\ud130\uc591
-TableColumn.header.down.info=\ud604\uc7ac\uae4c\uc9c0 \ub2e4\ub978 \uc0ac\uc6a9\uc790\ub85c\ubd80\ud130 \ubc1b\uc740 \ub370\uc774\ud130 \uc591
+azbuddy.enable_cat_pub=*\ubaa8\ub4e0* \uce5c\uad6c\uac00 \uad6c\ub3c5\ud560 \uc218 \uc788\ub294 \uacf5\uac1c \ubd84\ub958 (','\ub85c \uad6c\ubd84)
+azbuddy.ui.table.read_cat=Cat \uc77d\uae30
+TableColumn.header.#.info=TableColumn.header.#.info=\uc704\uce58/\uc815\ub82c \ubc88\ud638\uc785\ub2c8\ub2e4.
+TableColumn.header.category.info=\ud1a0\ub80c\ud2b8\uac00 \uc18d\ud574\uc788\ub294 \ubd84\ub958\uc758 \uc774\ub984\uc785\ub2c8\ub2e4.
+TableColumn.header.DateCompleted.info=\ud1a0\ub80c\ud2b8 \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub41c \ub0a0\uc9dc\uc785\ub2c8\ub2e4.
+TableColumn.header.AzProduct.info=\ud1a0\ub80c\ud2b8\ub97c \ubc1b\uc544\uc628 \ucf58\ud150\uce20 \ub124\ud2b8\uc6cc\ud06c\uc785\ub2c8\ub2e4.
+TableColumn.header.health.info=\ud1a0\ub80c\ud2b8 \uc2a4\uc6dc\uc5d0\uc11c \uc0ac\uc6a9\uc790 \uc5f0\uacb0\uc774 \uc5bc\ub9c8\ub098 \uac74\uc2e4\ud55c\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.maxuploads.info=\ub3d9\uc2dc\uc5d0 \uc5c5\ub85c\ub4dc\ud560 \uc218 \uc788\ub294 \ud53c\uc5b4\uc758 \ucd5c\ub300 \uc218\uc785\ub2c8\ub2e4.
+TableColumn.header.name.info=\ud1a0\ub80c\ud2b8 \uc774\ub984\uc785\ub2c8\ub2e4.
+TableColumn.header.unopened.info=\ud1a0\ub80c\ud2b8\uac00 \uc7ac\uc0dd\ub418\uc5c8\ub294\uc9c0 (\uc5f4\ub838\ub294\uc9c0) \uc5ec\ubd80\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.savepath.info=\ud1a0\ub80c\ud2b8 \ub370\uc774\ud130\ub97c \uc704\ud55c \ub300\uc0c1 \ud3f4\ub354 \ub610\ub294 \ud30c\uc77c\uc785\ub2c8\ub2e4.
+TableColumn.header.SeedingRank.info=\ub4f1\uae09 \uac12\uc740 \ud1a0\ub80c\ud2b8\uac00 \uc5bc\ub9c8\ub098 \ubc30\ud3ec\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.  \uc989 \ub192\uc740 \uac12\uc740 \ub192\uc740 \ud544\uc694\uc131\uc744 \uc758\ubbf8\ud569\ub2c8\ub2e4.
+TableColumn.header.shareRatio.info=\uc5bc\ub9c8\ub098 \ub2e4\uc6b4\ub85c\ub4dc \ud588\ub294\uc9c0\uc640 \ube44\uad50\ud574\uc11c \uc5bc\ub9c8\ub098 \uc5c5\ub85c\ub4dc (\uacf5\uc720) \ud588\ub294\uc9c0\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.size.info=\ub514\uc2a4\ud06c \uc0c1\uc5d0\uc11c \ud1a0\ub80c\ud2b8 \ub0b4\uc6a9\uc774 \ucc28\uc9c0\ud558\ub294 \ud06c\uae30\uc785\ub2c8\ub2e4.
+TableColumn.header.azsubs.ui.column.subs.info=\uc5f0\uad00\ub41c \ud1a0\ub80c\ud2b8\uac00 \ub4e4\uc5b4\uc788\ub294 \ud53c\ub4dc\ub97c \uad6c\ub3c5\ud560 \uc218 \uc788\ub294 \ubc84\ud2bc\uc785\ub2c8\ub2e4.
+TableColumn.header.upspeed.info=\ud604\uc7ac \uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
+TableColumn.header.downspeed.info=\ud604\uc7ac \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\uc785\ub2c8\ub2e4.
+TableColumn.header.up.info=\ud604\uc7ac \ub2e4\ub978 \uc0ac\uc6a9\uc790\uc5d0\uac8c \ubcf4\ub0b8 \ub370\uc774\ud130 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
+TableColumn.header.down.info=\ud604\uc7ac \ub2e4\ub978 \uc0ac\uc6a9\uc790\ub85c\ubd80\ud130 \ubc1b\uc740 \ub370\uc774\ud130\uc758 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
+TableColumn.header.ProgressETA.info=\uc0c1\ud0dc, \uc644\uc131\ub3c4, ETA, \ub2e4\uc6b4 \uc18d\ub3c4 \uc5f4\uc774 \uc5ec\ub7ec \uc904\ub85c\ub41c \ud558\ub098\uc758 \uc5f4\ub85c \ud569\uccd0\uc9d1\ub2c8\ub2e4.
+TableColumn.header.eta.info=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub418\uae30\uae4c\uc9c0 \ucd94\uc815 \uc2dc\uac04\uc785\ub2c8\ub2e4.
 Pieces.column.#.info=\uc870\uac01 \ubc88\ud638
-TableColumn.header.TableColumnNameInfo=\uc138\ub85c\uc904 \uc774\ub984\uacfc \uc124\uba85
+Peers.column.%.info=\uc9c0\uae08\uae4c\uc9c0 \ud53c\uc5b4\uac00 \ub2e4\uc6b4\ub85c\ub4dc\ud55c \ud1a0\ub80c\ud2b8\uc758 \ud37c\uc13c\ud14c\uc774\uc9c0
+TableColumn.header.download.info=\ud53c\uc5b4\ub85c\ubd80\ud130 \ubc1b\uc740 \ub370\uc774\ud130 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
+TableColumn.header.upload.info=\ud53c\uc5b4\uc5d0\uac8c \ubcf4\ub0b8 \ub370\uc774\ud130\uc758 \ucd1d\uacc4\uc785\ub2c8\ub2e4.
+TableColumn.header.downloadspeed.info=\ud53c\uc5b4\ub85c\ubd80\ud130 \ubc1b\uc544\uc624\ub294 \uc18d\ub3c4\uc785\ub2c8\ub2e4.
+TableColumn.header.uploadspeed.info=\ud53c\uc5b4\uc5d0\uac8c \ubcf4\ub0b4\uace0 \uc788\ub294 \ub370\uc774\ud130 \uc18d\ub3c4\uc785\ub2c8\ub2e4.
+TableColumn.header.lan.info=\ud53c\uc5b4\uac00 LAN \uc0c1\uc5d0 \uac19\uc774 \uc788\uc74c\uc744 \ud45c\uc2dc\ud569\ub2c8\ub2e4.
+TableColumn.header.downloadspeedoverall.info=\ud53c\uc5b4\uc758 \ucd94\uc815\ub41c \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\uc785\ub2c8\ub2e4.
+Peers.column.pieces.info=\uadf8\ub798\ud53d \ud45c\uc2dc \ub9c9\ub300\ub294 \uc5b4\ub5a4 \uc870\uac01\uc744 \ud53c\uc5b4\uac00 \ub2e4\uc6b4\ub85c\ub4dc \ud588\ub294\uc9c0\ub97c \ub098\ud0c0\ub0c4
+TableColumn.header.TableColumnNameInfo=\uc5f4 \uc774\ub984\uacfc \uc124\uba85
 TableColumn.header.TableColumnSample=\uacac\ubcf8
-TableColumn.header.TableColumnInfo=\uc138\ub85c\uc904 \uc124\uba85
-TableColumn.header.TableColumnChosenColumn=\uc138\ub85c\uc904 \uc120\ud0dd
+TableColumn.header.TableColumnInfo=\uc5f4 \uc124\uba85
+TableColumn.header.TableColumnChosenColumn=\uc5f4 \uc120\ud0dd
+subs.prop.is_auto_ok=\uc790\ub3d9 \ub2e4\uc6b4\ub85c\ub4dc \ud5c8\uc6a9\ub428
 label.learnmore=\ub354 \uc54c\uc544\ubcf4\uae30
-ColumnSetup.title='%1' \uc138\ub85c\uc904 \uc124\uc815
-ColumnSetup.explain=\uc67c\ucabd\uc5d0 \ud65c\uc6a9\uac00\ub2a5\ud55c \uc138\ub85c\uc904 \ubaa9\ub85d\uc744 \uc624\ub978\ucabd\uc5d0 \ucd94\uac00\ud558\uc5ec \ubaa9\ub85d\uc5d0\uc11c \ud45c\uc2dc\ud558\uc138\uc694. \uc67c\ucabd \uc704\uc5d0 \uc5ed\uc0bc\uac01\ud615\uc744 \ud3bc\uce58\uba74 \uace8\ub77c\ubcfc\uc218 \uc788\ub294 \uc138\ub85c\uc904 \ubaa9\ub85d\uc774 \ud3bc\uccd0\uc9d1\ub2c8\ub2e4. \ub9c8\uc6b0\uc2a4 \ub04c\uc5b4\uc624\uae30\uc640 \ub2e8\ucd95\ud0a4\ub3c4 \uc9c0\uc6d0\ud569 [...]
-ColumnSetup.chosencolumns=\uc138\ub85c\uc904 \uc120\ud0dd
+ColumnSetup.title='%1'\uc5d0 \ub300\ud55c \uc5f4 \uc124\uc815
+ColumnSetup.explain=\uc67c\ucabd\uc5d0 \ub098\uc5f4\ub41c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5f4\uc744 \ud0d0\uc0c9\ud574\uc11c \uc624\ub978\ucabd\uc758 \ubcfc \uc218 \uc788\ub294 \uc5f4\uc5d0 \ucd94\uac00\ud558\uc2ed\uc2dc\uc624. \uc67c\ucabd \uc544\ub798\uc5d0 \uc788\ub294 \ud544\ud130 \uc601\uc5ed\uc744 \uc0ac\uc6a9\ud574\uc11c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5f4 \ubaa9\ub85d\uc744 \uc27d\uac8c \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub04c\uc5b4\uc11c \ub5a8\uc5b4\ub728\ub9a [...]
+ColumnSetup.chosencolumns=\uc120\ud0dd\ud55c \uc5f4
 ColumnSetup.proficiency=\uc219\ub828\ub3c4:
 ColumnSetup.categories=\ubd84\ub958:
-ColumnSetup.filters=\uace8\ub77c\ubcf4\uae30
-ColumnSetup.availcolumns=%1 \uc138\ub85c\uc904 \ud65c\uc131\ud654
-ColumnSetup.availcolumns.filteredby=%2\ub97c \uace8\ub77c\uc11c %1 \uc138\ub85c\uc904 \ud65c\uc131\ud654
+ColumnSetup.filters=\ud544\ud130
+ColumnSetup.availcolumns=%1 \uc5f4 \uc0ac\uc6a9 \uac00\ub2a5
+ColumnSetup.availcolumns.filteredby=%2\ub85c \ud544\ud130\ub9c1 \ub41c %1 \uc5f4 \uc0ac\uc6a9 \uac00\ub2a5
 devices.view.title=\uc7a5\uce58
 device.renderer.view.title=\ub80c\ub354\ub7ec
 device.mediaserver.view.title=\ubbf8\ub514\uc5b4 \uc11c\ubc84
 device.router.view.title=\ub77c\uc6b0\ud130
 device.model.desc=\ubaa8\ub378 \uc124\uba85
-device.model.name=\ubaa8\ub378 \uba85
+device.model.name=\ubaa8\ub378 \uc774\ub984
 device.model.num=\ubaa8\ub378 \ubc88\ud638
 device.manu.desc=\uc81c\uc870\uc0ac
-device.router.is_mapping=\uc790\ub3d9\uc73c\ub85c \ud3ec\ud2b8 \ub9e4\ud551
-device.router.req_map=\uc694\uad6c\ub418\ub294 \ud3ec\ud2b8 \ub9e4\ud551
+device.router.is_mapping=\uc790\ub3d9 \ud3ec\ud2b8 \ub9f5\ud551
+device.router.req_map=\ud544\uc694\ud55c \ub9f5\ud551
 device.router.configure=UPnP \uc124\uc815
-device.mediaserver.configure=\ubbf8\ub514\uc5b4 \uc11c\ubc84 \uc124\uc815
+device.mediaserver.configure=\ub0b4 \ubbf8\ub514\uc5b4 \uc11c\ubc84 \uc124\uc815
 device.hide=\uc7a5\uce58 \uac10\ucd94\uae30
-device.show=\uc228\uaca8\uc9c4 \uc7a5\uce58 \ud45c\uc2dc
+device.show=\uc228\uaca8\uc9c4 \uc7a5\uce58 \ubcf4\uc5ec\uc8fc\uae30
 device.search=\uc7a5\uce58 \uac80\uc0c9
 device.router.con_type=\uc5f0\uacb0: %1
-device.browse=\ud0d0\uc0c9
+device.browse=\ucc3e\uc544\ubcf4\uae30
 device.upnp.desc_url=\uc7a5\uce58 \uc124\uba85
-device.upnp.present_url=\uc7a5\uce58 \uad00\ub9ac\uc790
-ConfigView.label.maxStalledSeeding='\ubc1c\ube8c\ud558\uae30(stalled)' \ucd5c\ub300\uac12 [0:\ubb34\uc81c\ud55c]
+device.upnp.present_url=\uc7a5\uce58 \uad00\ub9ac
+ConfigView.label.maxStalledSeeding=\ucd5c\ub300 '\uc18d\ub3c4 \ub0ae\uc740 \ud1a0\ub80c\ud2b8' \uc218 [0:\ubb34\uc81c\ud55c]
 device.search.auto=\uc790\ub3d9\uc73c\ub85c \uc7a5\uce58 \uac80\uc0c9
 devices.sidebar.simple=\uac04\ub2e8\ud788 \ubcf4\uae30
-devices.xcode.working_dir=\uc790\ub3d9\ubcc0\ud658 \uc601\uc5ed
-devices.xcode.prof_def=\uc790\ub3d9\ubcc0\ud658 \uae30\ubcf8 \ud504\ub85c\ud544
-devices.xcode.profs=\uc790\ub3d9\ubcc0\ud658 \ud504\ub85c\ud544 \ud65c\uc131\ud654
-device.lastseen=\ub9c8\uc9c0\ub9c9 \uc52c
-devices.contextmenu.xcode=\uc678\ubd80\uc7a5\uce58\uc6a9\uc73c\ub85c \uc790\ub8cc \uc790\ub3d9\ubcc0\ud658
+devices.xcode.working_dir=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc601\uc5ed
+devices.xcode.prof_def=\uae30\ubcf8 \ud2b8\ub79c\uc2a4 \ucf54\ub4dc \ud504\ub85c\ud544
+devices.xcode.profs=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \ud2b8\ub79c\uc2a4 \ucf54\ub4dc \ud504\ub85c\ud544
+device.lastseen=\ucd5c\uadfc \uc5f0\uacb0
+devices.contextmenu.xcode=\uc7a5\uce58\uc6a9 \ud2b8\ub79c\uc2a4 \ucf54\ub4dc
 devices.device=\uc7a5\uce58
 devices.profile=\ud504\ub85c\ud544
 General.percent=\ud37c\uc13c\ud2b8
 devices.installed=\uc124\uce58\ub428
+devices.comp.missing=Vuze \uc9c0\uc6d0 \uc124\uce58\ub418\uc9c0 \uc54a\uc74c
 devices.state=\uc0c1\ud0dc
-MainWindow.menu.help.donate=\uae30\ubd80\uae08 \ub0b4\uae30
-devices.xcode.only.show=\uc7a5\uce58\ub0b4 \uc790\ub3d9\ubcc0\ud658\ub41c \ud30c\uc77c\ub9cc \ud45c\uc2dc
-device.quit.transcoding.title=\uc790\ub3d9\ubcc0\ud658 \uc9c4\ud589
-device.quit.transcoding.text='%1'\uac00 '%2'\uc6a9\uc73c\ub85c \uc790\ub3d9\ubcc0\ud658 \ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub3d9\uc2dc\uc5d0 %3% \ub85c \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\ub2e4\uc74c \uc2dc\uc791\uc804\uae4c\uc9c0 \uc774 \uc791\uc5c5\uc73c\ub85c \ubd80\ud130 \ubc97\uc5b4\ub0a0 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
-download.removerules.unauthorised.data=\t\uc81c\uac70\ub41c \ub370\uc774\ud130
-device.config.xcode.maxbps=\uc790\ub3d9\ubcc0\ud658 \ube44\uc728 \ucd5c\ub300\uac12 KB/sec [0: \ubb34\uc81c\ud55c]
-device.xcode=\uc678\ubd80\uc7a5\uce58\uc6a9 \uc790\ub8cc \uc790\ub3d9\ubcc0\ud658
+MainWindow.menu.help.donate=\uae30\ubd80\ud558\uae30(&M)
+DonationWindow.noload.title=\uae30\ubd80
+DonationWindow.noload.text=\uae30\ubd80 \ucc3d\uc744 \uc5ec\ub294\ub370 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc2ed\uc2dc\uc624.
+devices.xcode.only.show=\uc7a5\uce58 \uc548 \ud2b8\ub79c\uc2a4 \ucf54\ub4dc\ub41c \ud30c\uc77c\ub9cc \ubcf4\uc5ec\uc8fc\uae30
+device.quit.transcoding.title=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc9c4\ud589 \uc911
+device.quit.transcoding.text='%1'\uac00 '%2'\uc6a9\uc73c\ub85c \ud604\uc7ac \ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc911\uc774\uba70 %3% \uc644\ub8cc\ub418\uc5c8\uc2b5\ub2c8\ub2e4.\n\uc9c0\uae08 \uc885\ub8cc\ud558\uba74 \uc774 \uc791\uc5c5\uc740 \ub2e4\uc74c \uc2dc\uc791\uc2dc \ucc98\uc74c\ubd80\ud130 \ub2e4\uc2dc \ud574\uc57c \ud569\ub2c8\ub2e4.
+download.removerules.unauthorised.data=\t\ub370\uc774\ud130 \uc81c\uac70
+device.config.xcode.maxbps=KB/sec \ucd5c\ub300 \ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc18d\ub3c4 [0: \ubb34\uc81c\ud55c]
+device.xcode=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc
 device.xcode.always=\ud56d\uc0c1 \uc608
-device.xcode.whenreq=\ud5c8\uc6a9\uc2dc\uc5d0\ub9cc
+device.xcode.whenreq=\ud544\uc694\uc2dc\uc5d0\ub9cc
 device.xcode.never=\ud56d\uc0c1 \uc544\ub2c8\uc694
-devices.sidebar.hide.rend.generic=\uc77c\ubc18\uc7a5\uce58 \uc228\uae30\uae30
-v3.devicesview.infobar.text2=\uc678\ubd80\uc7a5\uce58\uc5d0 \uc0ac\uc6a9\ud560 \uc790\ub8cc\ub97c \uc790\ub3d9\ubcc0\ud658\ud558\ub824\uba74, \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc790\ub8cc\ub97c \ub4dc\ub808\uadf8\ud574\uc11c \uce21\uba74 \ud45c\uc2dc\uc904\uc758 \uc678\ubd80\uc7a5\uce58\uc5d0 \ub5a8\uad6c\uba74 \ub429\ub2c8\ub2e4. \uc790\ub3d9\ubcc0\ud658\uc758 \uc0c1\ud0dc\ub97c \uc54c\uace0\uc2f6\uc73c\uba74 \ud574\ub2f9 \uc678\ubd80\uc7a5\uce58\uc5d0\uc11c \uc624\ub978\ucabd [...]
+devices.copy.pending=\ud30c\uc77c \ubcf5\uc0ac \ubcf4\ub958 \uc911
+devices.sidebar.hide.rend.generic=\uc77c\ubc18 \uc7a5\uce58 \uc228\uae30\uae30
+v3.devicesview.infobar.text2=\uc7a5\uce58\ub85c \ucf58\ud150\uce20\ub97c \ud2b8\ub79c\uc2a4 \ucf54\ub4dc\ud558\ub824\uba74, \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc0ac\uc774\ub4dc \ubc14\uc758 \uc7a5\uce58\ub85c \ucf58\ud150\uce20\ub97c \ub04c\uc5b4 \ub193\uc73c\uc2ed\uc2dc\uc624.  \uc644\ub8cc\ub41c \ud2b8\ub79c\uc2a4 \ucf54\ub4dc\ub97c \ubcf4\ub824\uba74, \uc6b0\uce21\uc758 \uac01 \uc7a5\uce58\ub97c \ud074\ub9ad\ud558\uc2ed\uc2dc\uc624.
 iconBar.transcode=\uc7a5\uce58
-iconBar.transcode.tooltip=\ub0b4\ub824\ubc1b\uc740 \uc790\ub8cc\ub97c \uc678\ubd80\uc7a5\uce58\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ubcc0\ud658\uc2dc\ud0a4\uc138\uc694.
-device.retry.copy=\ubcf5\uc0ac \ub2e4\uc2dc\uc2dc\ub3c4
-devices.copy.fail=\uc7a5\uce58\ub85c \ubcf5\uc0ac\uac00 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4
+iconBar.transcode.tooltip=\uc7a5\uce58\uc5d0\uc11c \uc0ac\uc6a9\uac00\ub2a5\ud55c \ubbf8\ub514\uc5b4 \ub9cc\ub4e4\uae30
+device.retry.copy=\ubcf5\uc0ac \ub2e4\uc2dc \uc2dc\ub3c4
+devices.copy.fail=\uc7a5\uce58\ub85c \ubcf5\uc0ac\ud558\uae30 \uc2e4\ud328
+devices.on.demand=\uc694\uccad\uc989\uc2dc
 devices.ready=\uc900\ube44
-TableColumn.header.trancode_qpos.info=\uc790\ub3d9\ubcc0\ud658 \ub300\uae30\uc21c\uc11c
+TableColumn.header.trancode_qpos.info=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \ub300\uae30\uc5f4 \uc0c1\uc758 \uc704\uce58\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.
 TableColumn.header.profile=\uc7a5\uce58
-TableColumn.header.profile.info=\uc790\ub3d9\ubcc0\ud658 \ud504\ub85c\ud544 \uc0ac\uc6a9
+TableColumn.header.profile.info=\uc0ac\uc6a9\ub41c \ud2b8\ub79c\uc2a4 \ucf54\ub4dc \ud504\ub85c\ud544\uc785\ub2c8\ub2e4.
+TableColumn.header.copied=\ubcf5\uc0ac\ub428
 TableColumn.header.device=\uc7a5\uce58
-TableColumn.header.device.info=\ubaa9\ud45c \uc7a5\uce58
+TableColumn.header.device.info=\ud45c\uc801 \uc7a5\uce58\uc785\ub2c8\ub2e4.
+TableColumn.header.trancode_completion=\ubcc0\ud658 \uc9c4\ud589
 # This is the beginning of the word "View".  It's right aligned under the icon bar item
-v3.iconBar.view.big.tooltip=\uac04\ub2e8\ubaa9\ub85d\uc73c\ub85c \ubcf4\uae30
+v3.iconBar.view.big=\ubcf4
+v3.iconBar.view.big.tooltip=\uac04\ub2e8 \ubaa9\ub85d\uc73c\ub85c \ubcf4\uae30
 # This is the end of the word "View".  It's left aligned under the icon bar item
-v3.iconBar.view.small.tooltip=\uace0\uae09\ubaa9\ub85d\uc73c\ub85c \ubcf4\uae30
+v3.iconBar.view.small=\uae30
+v3.iconBar.view.small.tooltip=\uace0\uae09 \ubaa9\ub85d\uc73c\ub85c \ubcf4\uae30
 general.dont.ask.again=\ub2e4\uc2dc \ubb3b\uc9c0 \uc54a\uae30
-general.na.short=\uc6a9\ub3c4\uc5c6\uc74c
-v3.menu.device.exploreTranscodes=\ud30c\uc77c \ubcf4\uae30
-v3.menu.device.exploreTranscodes._windows=\ud0d0\uc0c9\uae30\uc5d0\uc11c \ud30c\uc77c\uc704\uce58 \ubcf4\uae30
+v3.menu.device.exploreTranscodes=\ud30c\uc77c \ubcf4\uc5ec\uc8fc\uae30
+v3.menu.device.exploreTranscodes._windows=\ud0d0\uc0c9\uae30\uc5d0\uc11c \ud30c\uc77c\uc704\uce58 \ubcf4\uc5ec\uc8fc\uae30
 v3.menu.device.exploreTranscodes._mac=\ud30c\uc778\ub354\uc5d0\uc11c \ud30c\uc77c\uc704\uce58 \ubcf4\uae30
 v3.menu.device.defaultprofile=\uae30\ubcf8 \ud504\ub85c\ud544
-devices.button.installitunes=iTunes \ud1b5\ud569 \ucd94\uac00\uae30\ub2a5 \uc124\uce58
-device.itunes.install=iTunes\ub97c \uc124\uce58 \ud558\uc154\uc57c \ud569\ub2c8\ub2e4.
-device.itunes.start=iTunes\ub97c \uc2dc\uc791\ud558\uac70\ub098 \uc790\ub3d9 \uc2dc\uc791\uc744 \uc791\ub3d9\uc2dc\ucf1c\uc57c \ud569\ub2c8\ub2e4
-device.itunes.install_problem=iTunes\uc640 \ud1b5\ud569\uc774 \ubb38\uc81c\ub97c \uc77c\uc73c\ud0ac \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.
-devices.downloading=\ub0b4\ub824\ubc1b\uae30 \uc911
+devices.button.installitunes=iTunes \uc5f0\uacb0 \uae30\ub2a5 \uc124\uce58
+device.itunes.install=iTunes \uc124\uce58 \ud544\uc694
+device.itunes.start=iTunes \uc2dc\uc791 \ub610\ub294 \uc790\ub3d9 \uc2dc\uc791 \ud65c\uc131\ud654 \ud544\uc694
+device.itunes.install_problem=iTunes \ud1b5\ud569\uc5d0 \ubb38\uc81c\uac00 \ubc1c\uc0dd
+devices.downloading=\ub2e4\uc6b4\ub85c\ub4dc \uc911
 TableColumn.header.duration=\uc9c0\uc18d\uc2dc\uac04
-devices.xcode.autoStart=\ud544\uc694\ud558\uba74 \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791
-option.askeverytime=\ub9e4\ubc88 \ubb3b\uae30
-option.rememberthis=\uc774\uc124\uc815 \uae30\uc5b5
-devices.associate=\uc5f0\ub3d9\ud558\uae30
-devices.associate.already=\uc774\ubbf8 \uc5f0\ub3d9\ub428
-devices.always.cache=\uc790\ub3d9\ubcc0\ud658\ub418\uc9c0 \uc54a\uc740 \ud30c\uc77c\uc744 \uce90\uc26c
-devices.turnon.title=\uc7a5\uce58 \uc9c0\uc6d0\uc744 \uc791\ub3d9
-devices.choose.profile.info.title.selected=%1 \uc138\ubd80\ub0b4\uc6a9:
-devices.view.heading=\uc7a5\uce58\uc758 \uc7ac\uc0dd\ubc29\uc2dd\uc5d0 \uc54c\ub9de\uac8c \uc790\ub8cc \ubcc0\ud658
-device.view.heading=%1\uc6a9 \uc790\ub8cc
-devices.choose.device.info.title=\uc7a5\uce58 \uadc0\ub754
-Button.turnon=\uc791\ub3d9
-ConfigView.label.dm.dblclick=\ub354\ube14\ud074\ub9ad\ud560 \ub54c \ud1a0\ub7f0\ud2b8 \ubcf4\uae30:
-ConfigView.option.dm.dblclick.play=\uc790\ub8cc \uc7ac\uc0dd
-ConfigView.option.dm.dblclick.details=\ud1a0\ub7f0\ud2b8 \uc138\ubd80\uc0ac\ud56d \ubcf4\uae30 \uc5f4\uae30
-ConfigView.option.dm.dblclick.show=\ud30c\uc77c \ubcf4\uae30
-ConfigView.option.dm.dblclick.show._mac=\ud30c\uc778\ub354\uc5d0\uc11c \ud30c\uc77c \uc704\uce58 \ubcf4\uae30
-ConfigView.option.dm.dblclick.show._windows=\ud0d0\uc0c9\uae30\uc5d0\uc11c \ud30c\uc77c \uc704\uce58 \ubcf4\uae30
-subscriptions.column.auto-download=\uc790\ub3d9 \ub0b4\ub824\ubc1b\uae30
+TableColumn.header.resolution=\ud574\uc0c1\ub3c4
+devices.xcode.autoStart=\ud544\uc694\ud55c \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \uc2dc\uc791
+option.askeverytime=\ud56d\uc0c1 \ubb3b\uae30
+option.rememberthis=\uc124\uc815 \uae30\uc5b5
+devices.associate=\ub2e4\uc74c\uacfc \uc5f0\uacb0:
+devices.associate.already=\uc774\ubbf8 \uc5f0\uacb0\ub428
+devices.always.cache=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc548 \ub41c \ud30c\uc77c\uc744 \uce90\uc2dc
+devices.turnon.prepageload=\uc774 \uae30\ub2a5\uc744 \ucf1c\uba74, \ucd94\uac00 \ucef4\ud3ec\ub10c\ud2b8 \uc124\uce58\uac00 \ud544\uc694\ud569\ub2c8\ub2e4.
+devices.turnon.itunes=iTunes \uc9c0\uc6d0 \ud3ec\ud568 (Apple \uc7a5\uce58\ub97c \uc704\ud574 \ud544\uc694)
+devices.turnon.qos=\uc775\uba85\uc758 \uc7a5\uce58 \ud1b5\uacc4\ub97c Vuze\uc640 \uacf5\uc720
+devices.turnon.title=\uc7a5\uce58 \uc9c0\uc6d0 \ucf1c\uae30
+devices.choose.device.title=\uc774 \ube44\ub514\uc624\ub97c \uc7ac\uc0dd\ud560 \uc7a5\uce58\ub97c \uc120\ud0dd \ud558\uc2ed\uc2dc\uc624:
+devices.choose.profile.info.text=\uc120\ud0dd\ud55c \ud6c4, Vuze\ub294 \ube44\ub514\uc624 \ud615\uc2dd\uc774 \uc120\ud0dd\ud55c \uc7a5\uce58\uc5d0\uc11c \uc7ac\uc0dd \uac00\ub2a5\ud55c\uc9c0 \uadf8\ub807\uc9c0 \uc54a\uc740\uc9c0 \uac10\uc9c0\ud558\uace0, \ud544\uc694\ud55c \uacbd\uc6b0 \uc7a5\uce58\uc640 \ud638\ud658\ub418\ub294 \uc0ac\ubcf8\uc744 \uc0dd\uc131\ud569\ub2c8\ub2e4.\n\n\uc120\ud0dd\ud55c \uc7a5\uce58\uc5d0 \ub300\ud574\uc11c \ub354 \uc790\uc138\ud55c \uc0ac\ud56d\uc744 \ubcf [...]
+devices.choose.profile.info.title.selected=%1 \uc138\ubd80\uc0ac\ud56d:
+devices.view.heading=\uc7a5\uce58 \uc7ac\uc0dd\uc744 \uc704\ud574 \ubbf8\ub514\uc5b4 \ubcc0\ud658
+device.view.heading=%1\uc5d0 \ub300\ud55c \ubbf8\ub514\uc5b4
+devices.choose.device.info.title=\uc7a5\uce58 \ud301
+devices.choose.device.info.text=\ub2e4\uc74c\ubd80\ud130\ub294 \uac04\ub2e8\ud558\uac8c \uc0ac\uc774\ub4dc\ubc14\uc5d0 \uc0ac\uc6a9\uc790\uac00 \uc120\ud0dd\ud55c \uc7a5\uce58\ub85c \ud30c\uc77c\uc744 \ub04c\uc5b4\ub193\uae30
+label.clickone=\ud558\ub098\ub97c \ud074\ub9ad
+Button.turnon=\ucf1c\uae30
+ConfigView.label.dm.dblclick=\ud1a0\ub80c\ud2b8 \ubcf4\uae30\uc5d0\uc11c \ub354\ube14\ud074\ub9ad\ud558\uba74:
+ConfigView.option.dm.dblclick.play=\ucf58\ud150\uce20 \uc7ac\uc0dd
+ConfigView.option.dm.dblclick.details=\ud1a0\ub80c\ud2b8 \uc138\ubd80\uc0ac\ud56d \ubcf4\uae30 \uc5f4\uae30
+ConfigView.option.dm.dblclick.show=\ud30c\uc77c \ubcf4\uc5ec\uc8fc\uae30
+ConfigView.option.dm.dblclick.show._mac=\ud30c\uc778\ub354\uc5d0\uc11c \ud30c\uc77c \ubcf4\uae30
+ConfigView.option.dm.dblclick.show._windows=\ud0d0\uc0c9\uae30\uc5d0\uc11c \ud30c\uc77c \ubcf4\uc5ec\uc8fc\uae30
+subscriptions.column.auto-download=\uc790\ub3d9 \ub2e4\uc6b4\ub85c\ub4dc
 xcode.deletedata.title=\uc790\ub3d9\ubcc0\ud658 \uc790\ub8cc \uc0ad\uc81c
 xcode.deletedata.message='%2'%3\uc6a9 \uc790\ub3d9\ubcc0\ud658 \uc790\ub8cc '%1'\uc758 \ubcf5\uc0ac\ubcf8\uc744 \uc644\uc804\ud788 \uc0ad\uc81c\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
 xcode.deletedata.message.2=\n('%1'\uc758 \ubcf5\uc0ac\ubcf8\uc774 \ub0a8\uc544\uc788\uc744 \uc218 \uc788\uc74c)
-v3.deviceview.infobar.line1=\ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc7a5\uce58\ub85c \uc62e\uae38 \uc790\ub8cc\ub97c \ub4dc\ub85c\uadf8 \uc564 \ub4dc\ub86d \ud558\uc138\uc694.
-v3.deviceview.infobar.line2=\ub0b4\ub824\ubc1b\uc740 \uc790\ub8cc\ub97c \uc5b4\ub5a4\uae30\uae30\uc758 \uc5b4\ub5a4\uc2a4\ud06c\ub9b0\uc5d0\uc11c\ub3c4 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4 - iPhone, iPod, TV
-v3.deviceview.infobar.line1.generic=\uce21\uba74 \ud45c\uc2dc\uc904\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c %1\ub85c  \uc790\ub8cc\ub97c \ub04c\uc5b4 \uc624\uc138\uc694.
-v3.deviceview.infobar.line2.itunes=\uc790\ub8cc \uc7ac\uc0dd\uc900\ube44\uac00 \ub2e4 \ub418\uba74 iTunes Movies\uc5d0\uc11c \uc790\ub8cc\uac00 \ubcf4\uc77c\uac83\uc785\ub2c8\ub2e4.
-v3.deviceview.infobar.line2.xbox=Xbox 360\uc73c\ub85c \uc2a4\ud2b8\ub9ac\ubc0d \uc790\ub8cc\ub97c \ubcf4\ub0b4\uc2dc\ub824\uba74 Xbox360\uc5d0\uc11c My XBox -> Video Library -> Vuze\ub97c \uc120\ud0dd\ud558\uc138\uc694.
-v3.deviceview.infobar.line2.ps3=\uc2a4\ud2b8\ub9ac\ubc0d \uc790\ub8cc\ub97c PS3\uc5d0\uc11c \ubcf4\uc2dc\ub824\uba74 PS3\uc5d0\uc11c Videos -> Vuze\ub97c \uc120\ud0dd\ud558\uc138\uc694.
+v3.deviceview.infobar.line1=\uc120\ud0dd\ud55c \ube44\ub514\uc624\ub97c \uc0ac\uc6a9\uc790 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc7a5\uce58\ub85c \ub04c\uc5b4\ub193\uc73c\uc2ed\uc2dc\uc624.
+v3.deviceview.infobar.line2=\uc5b4\ub5a4 \uacf3\uc5d0\uc11c\ub4e0 \ube44\ub514\uc624\ub97c \uc7ac\uc0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4 - iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=\ube44\ub514\uc624\ub97c \uc0ac\uc6a9\uc790 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c \uc0ac\uc774\ub4dc \ubc14\uc758 %1\ub85c \ub04c\uc5b4\ub193\uc73c\uc2ed\uc2dc\uc624.
+v3.deviceview.infobar.line2.itunes=\uc7ac\uc0dd\ud560 \uc900\ube44\uac00 \ub418\uba74 iTunes Movies \ud3f4\ub354\uc5d0 \ube44\ub514\uc624\uac00 \ub098\ud0c0\ub0a9\ub2c8\ub2e4.
+v3.deviceview.infobar.line2.xbox=\ube44\ub514\uc624 \uc2a4\ud2b8\ub9bc\uc740 Xbox 360\uc73c\ub85c \uac00\uc154\uc11c \ub0b4 XBox \u2192 \ube44\ub514\uc624 \ub77c\uc774\ube0c\ub7ec\ub9ac \u2192 Vuze\ub97c \uc120\ud0dd\ud558\uba74 \ub429\ub2c8\ub2e4.
+v3.deviceview.infobar.line2.ps3=\ube44\ub514\uc624\ub97c \uc2a4\ud2b8\ub9bc\uc740 PS3\ub85c \uac00\uc154\uc11c \ube44\ub514\uc624 \u2192 Vuze\ub97c \uc120\ud0dd\ud558\uc2ed\uc2dc\uc624.
+devices.copy_url=\uc2a4\ud2b8\ub9bc URL\uc744 \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac
 devices.converting=\ubcc0\ud658 \uc911
 Button.reload=\uc0c8\ub85c\uace0\uce68
-devices.auto.start=\uc790\ub3d9\uc2dc\uc791
-general.enter.cookies=\ucfe0\ud0a4\uc5d0 \uae30\ub85d
+devices.auto.start=\uc790\ub3d9 \uc2dc\uc791
+Subscription.menu.setcookies=\ucfe0\ud0a4 \uc124\uc815
+general.enter.cookies=\uc5d4\ud2b8\ub9ac \ucfe0\ud0a4
+device.config.xcode.workdir=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \ud30c\uc77c\uc744 \uc704\ud55c \uae30\ubcf8 \uc791\uc5c5 \ub514\ub809\ud130\ub9ac
 MyTorrentsView.menu.clear_alloc_data=\ud560\ub2f9 \uc0c1\ud0dc \uc9c0\uc6b0\uae30
-subscriptions.config.auto=\uc790\ub3d9 \ub0b4\ub824\ubc1b\uae30
+DiskManager.error.nospace=\ubd88\ucda9\ubd84\ud55c \ub514\uc2a4\ud06c \uacf5\uac04
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - {wiki.fat32} \uac80\uc0ac
+ConfigView.section.file.rename.incomplete=\uc644\ub8cc\ub418\uc9c0 \uc54a\uc740 \ud30c\uc77c\uc5d0 \ubd99\uc77c \uc811\ubbf8 \ubb38\uc790\uc5f4
+subscriptions.config.auto=\uc790\ub3d9 \ub2e4\uc6b4\ub85c\ub4dc
+subscriptions.config.autostartdls=\ucd94\uac00\ub418\uba74 \uc790\ub3d9\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc \uc2dc\uc791 (\uc815\uc9c0 \uc0c1\ud0dc\ub85c \ucd94\uac00\ub418\ub294 \uac83\uacfc \ubc18\ub300)
+subscriptions.config.autostart.min=\ub2e4\uc74c\ubcf4\ub2e4 \ud06c\uac70\ub098 \uac19\uc73c\uba74 \uc2dc\uc791 (MB) [0: \ubb34\uc81c\ud55c]
+subscriptions.config.autostart.max=\ub2e4\uc74c\ubcf4\ub2e4 \uc791\uac70\ub098 \uac19\uc73c\uba74 \uc2dc\uc791 (MB) [0: \ubb34\uc81c\ud55c]
+dlg.corewait.title=\ucf54\uc5b4 \ucd08\uae30\ud654 \uc911
+dlg.corewait.text=\uc7a0\uc2dc\ub9cc \uae30\ub2e4\ub824 \uc8fc\uc2ed\uc2dc\uc624...\n\nVuze \ucd08\uae30\ud654\uac00 \uc644\ub8cc\ub41c \ud6c4 \uc0ac\uc6a9\uc790 \uc694\uccad\uc774 \ucc98\ub9ac\ub429\ub2c8\ub2e4.
+library.core.wait=\uc7a0\uc2dc \uae30\ub2e4\ub824 \uc8fc\uc2ed\uc2dc\uc624...\nVuze \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \ucd08\uae30\ud654 \uc911 \uc785\ub2c8\ub2e4.
+ConfigView.label.StartUIBeforeCore=\ucf54\uc5b4 \ucd08\uae30\ud654 \uc804\uc5d0 UI \uc2dc\uc791
+general.add.friends=\uce5c\uad6c\ub97c \ucd94\uac00\ud558\uc138\uc694!
+general.all.friends=\ubaa8\ub4e0 \uce5c\uad6c
+friend.mod.subs=\uc624\ub978\ucabd \ud074\ub9ad\uc73c\ub85c \uad6c\ub3c5 \ubcc0\uacbd
+TableColumn.header.class=\ud074\ub798\uc2a4
+device.rss.group=\ub85c\uceec RSS \ud53c\ub4dc
+devices.xcode.rsspub=RSS \ud53c\ub4dc \uac8c\uc2dc
+device.rss.enable=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc\ub41c \ucf58\ud150\uce20\ub85c RSS \ud53c\ub4dc \uc0dd\uc131 - \uc774 \uc791\uc5c5\uc740 \ud574\ub2f9 \ucf58\ud150\uce20\uac00 RSS \ud53c\ub4dc \ub9ac\ub354\uc5d0\uc11c \uc0ac\uc6a9 \uac00\ub2a5\ud558\uac8c \ud569\ub2c8\ub2e4
+device.rss.port=RSS \ud53c\ub4dc \ud3ec\ud2b8
+device.rss.view=RSS \ud53c\ub4dc\ub97c \ubcf4\ub824\uba74 \ud074\ub9ad
+device.rss.localonly=\uc774 \ucef4\ud4e8\ud130\uc5d0\uc11c\ub9cc \uc811\uadfc\ud560 \uc218 \uc788\ub3c4\ub85d \uc81c\ud55c
+devices.xcode.autoCopy=\uc790\ub3d9\uc73c\ub85c \ud3f4\ub354\uc5d0 \ubcf5\uc0ac
+devices.xcode.setcopyto=\ubcf5\uc0ac\ud560 \ud3f4\ub354 \uc124\uc815...
+devices.xcode.setcopyto.title=\ubcf5\uc0ac\ud560 \uc704\uce58 \uc120\ud0dd
+devices.copy.folder.auto=\uc790\ub3d9\uc73c\ub85c \ud3f4\ub354\uc5d0 \ud30c\uc77c \ubcf5\uc0ac
+devices.copy.folder.dest=\ud3f4\ub354\uc5d0 \ubcf5\uc0ac
+TableColumn.menu.maxuploads=\ucd5c\ub300 \uc5c5\ub85c\ub4dc \uc218
+devices.xcode.mancopy=\uc218\ub3d9\uc73c\ub85c \ud30c\uc77c \ubcf5\uc0ac
+devices.xcode.show.cat=\ubd84\ub958\ub85c \ub098\ub204\uae30
+ConfigView.label.alwaysShowLibraryHeader=\ub77c\uc774\ube0c\ub7ec\ub9ac(\ub0b4 \ud1a0\ub80c\ud2b8)\uc5d0 \ud5e4\ub354/\ud544\ud130 \ub9c9\ub300\ub97c \ud56d\uc0c1 \ubcf4\uc5ec\uc8fc\uae30
+devices.cat.show=\ubd84\ub958 \ubcf4\uc5ec\uc8fc\uae30
+devices.tivo.machine=TiVo \uae30\uacc4 \uc774\ub984
+devices.info.copypending=%1 \ud30c\uc77c\uc774 \ubcf5\uc0ac\ub418\uae30\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911
+device.error.xcodefail=\ud2b8\ub79c\uc2a4 \ucf54\ub4dc \uc2e4\ud328
+device.error.copyfail=\ud3f4\ub354\ub85c \ubcf5\uc0ac \uc911 \ud55c \uac1c \uc774\uc0c1\uc758 \ud30c\uc77c \uc2e4\ud328
+device.error.copytonotset='\ud3f4\ub354\ub85c \ubcf5\uc0ac' \uc124\uc815\ub418\uc9c0 \uc54a\uc74c
+device.error.copytomissing='\ud3f4\ub354\ub85c \ubcf5\uc0ac' "%1" \ucc3e\uc744 \uc218 \uc5c6\uc74c
+device.error.copytonowrite='\ud3f4\ub354\ub85c \ubcf5\uc0ac' "%1" \uc4f8 \uc218 \uc5c6\uc74c
+device.error.copyfail2=\uc7a5\uce58\ub85c \ubcf5\uc0ac \uc911 \ud55c \uac1c \uc774\uc0c1\uc758 \ud30c\uc77c \uc2e4\ud328
+v3.deviceview.infobar.line2.tivo=\ube44\ub514\uc624 \uc2a4\ud2b8\ub9bc\uc740 TiVo\ub85c \uac00\uc154\uc11c \uc9c0\uae08 \uc7ac\uc0dd \uc911\uc778 \ubaa9\ub85d\uc5d0\uc11c Vuze\ub97c \uc120\ud0dd\ud558\uba74 \ub429\ub2c8\ub2e4.
+v3.deviceview.infobar.line2.psp=PSP\uac00 \uc5f0\uacb0\ub418\uba74 \ube44\ub514\uc624\uac00 \ubcf5\uc0ac\ub429\ub2c8\ub2e4.
+devices.info.copypending2=%1 \ud30c\uc77c\uc774 \ubcf5\uc0ac\ub418\uae30\ub97c \uae30\ub2e4\ub9ac\ub294 \uc911, \uc7a5\uce58\ub97c \uc5f0\uacb0\ud560 \uac83
+subscriptions.column.nb-subscribers=\uad6c\ub3c5\uc790
+device.offlinedownloader.view.title=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub354
+device.od.group=
+device.od.enable=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub4dc \uc7a5\uce58 \ud65c\uc131\ud654
+device.odauto.enable=\uc790\ub3d9\uc73c\ub85c \ub2e4\uc6b4\ub85c\ub4dc \uad00\ub9ac
+device.odpt.enable=\ube44\uacf5\uac1c \ud1a0\ub80c\ud2b8 \ud3ec\ud568
+devices.contextmenu.od=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub4dc
+devices.contextmenu.od.auto=<\uc790\ub3d9>
+devices.contextmenu.od.enable=\ud65c\uc131\ud654
+devices.contextmenu.od.enabled=\ud65c\uc131\ud654\ub428
+devices.od.view.heading=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \uc704\ud574 \ub2e4\uc6b4\ub85c\ub4dc \uc608\uc57d\ub428
+DevicesOD.column.od_completion=\uc804\uc1a1 \uc9c4\ud589
+devices.od.idle=\uc720\ud734
+device.od.turnon.title=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub354 \uc9c0\uc6d0 \ucf1c\uae30
+device.is.disabled=\uc7a5\uce58\uac00 \ud574\uc81c\ub428
+device.configure=\uc124\uc815...
+device.od.error.notfound=\uc7a5\uce58\uac00 \uc624\ud504\ub77c\uc778\uc778 \uac83\uc73c\ub85c \ub098\ud0c0\ub0a8
+device.od.error.opfailstatus=\uc7a5\uce58\uac00 \uba85\ub839 %1 \uc9c4\ud589 \uc2e4\ud328: \uc0c1\ud0dc %2
+device.od.error.opfailexcep=\uc7a5\uce58\uac00 \uba85\ub839 %1 \uc9c4\ud589 \uc2e4\ud328: \uc608\uc678 %2
+device.od.error.nospace=\uc7a5\uce58\uc5d0 \ub0a8\uc740 \uacf5\uac04\uc774 \uc5c6\uac70\ub098 \uc678\ubd80 \ub4dc\ub77c\uc774\ube0c\uac00 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc74c
+device.od.space=\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uacf5\uac04
+ConfigView.section.style.forceSIValues=\ud45c\uc2dc \ub2e8\uc704\ub97c \ub9ac\uac70\uc2dc \ud638\ud658 \ubaa9\uc801\uacfc\ub294 \uc0c1\uad00\uc5c6\uc774 IEC \uac12\uc73c\ub85c \ubcf4\uc5ec\uc8fc\uae30 \uac15\uc81c (\uc608: 1MB = 1MiB = 1048576B)
+ConfigView.label.enableSystrayToolTip=\ub5a0\ub2e4\ub2c8\ub294 \ub2e4\uc6b4\ub85c\ub4dc \uc0c1\ud0dc \ubcf4\uc5ec\uc8fc\uae30
+devices.activation=\uc7a5\uce58 \ud65c\uc131
+button.nothanks=\uc0ac\uc591\ud569\ub2c8\ub2e4
+devices.od.turnon.text1=\ucef4\ud4e8\ud130\uac00 %1\uc5d0 \uc5f0\uacb0 \ub418\uc5b4\uc788\ub294 \uac83\uc73c\ub85c \uc778\uc2dd\ub429\ub2c8\ub2e4.
+devices.od.turnon.text2=\ucef4\ud4e8\ud130\uac00 \uc624\ud504\ub77c\uc778\uc77c \ub54c \uacc4\uc18d\ud574\uc11c %1\uac00 \ud30c\uc77c\uc744 \ub2e4\uc6b4\ub85c\ub4dc\ub97c \ud558\ub3c4\ub85d \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+devices.od.turnon.text3=\uc774 \uae30\ub2a5\uc744 \ucf1c\ub824\uba74 \ud558\ub4dc \ub514\uc2a4\ud06c \ub4dc\ub77c\uc774\ube0c\ub97c %1\uc5d0 \uc5f0\uacb0\ubc14\ub78d\ub2c8\ub2e4.
+devices.od.turnon.learn=\ub354 \uc54c\uc544\ubcf4\uae30 >
+devices.router=\ub77c\uc6b0\ud130
+devices.od=\uc624\ud504\ub77c\uc778 \ub2e4\uc6b4\ub85c\ub354
+webui.pairingenable=\uc774 \ud50c\ub7ec\uadf8\uc778\uc5d0 \ub300\ud574 \ud328\uc5b4\ub9c1\uc774 \ud65c\uc131\ud654\ub428\n(\ud14c\uc2a4\ud2b8 \uc635\uc158\uc740 \ud604\uc7ac \ud328\uc5b4\ub9c1 \uc138\ubd80\uc0ac\ud56d\uc774 \uc77c\ub2e8 \uc131\uacf5\uc801\uc73c\ub85c \uac8c\uc2dc\ub418\uba74 \ud65c\uc131\ud654 \ub429\ub2c8\ub2e4)
+webui.group.access=\uc811\uadfc \uc81c\uc5b4
+ConfigView.section.Pairing=\ud328\uc5b4\ub9c1
+pairing.accesscode=\uc811\uadfc \ucf54\ub4dc
+pairing.ac.getnew=\uc0c8 \uc811\uadfc \ucf54\ub4dc \ud560\ub2f9
+pairing.ac.getnew.create=\uc0dd\uc131
+pairing.ipv4=\uacf5\uac1c IPv4 \uc8fc\uc18c
+pairing.ipv6=\uacf5\uac1c IPv6 \uc8fc\uc18c
+pairing.local.ipv4=\ub85c\uceec IPv4 \uc8fc\uc18c
+pairing.local.ipv6=\ub85c\uceec IPv6 \uc8fc\uc18c
+pairing.host=\ud638\uc2a4\ud2b8 \uc8fc\uc18c (DNS \uc774\ub984)
+pairing.group.explicit=\uba85\ubc31\ud55c \uc18d\uc131
+pairing.explicit.enable=\ud65c\uc131\ud654
+pairing.explicit.info=\uc77c\ubc18\uc801\uc73c\ub85c \uba85\ubc31\ud55c IP \uc18d\uc131\uc740 \uc790\ub3d9\uc73c\ub85c \ubd80\uc5ec\ub418\ubbc0\ub85c \uba85\uc2dc\ud560 \ud544\uc694\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.\n\uc608\ub97c \ub4e4\uc5b4, \ub9cc\uc57d DynDNS \uacc4\uc815\uc774 \uc788\uace0 \ub3d9\uc801 IP\ub97c \uc62c\ubc14\ub85c \ub4f1\ub85d\ud574\uc8fc\ub294 \uc801\uc808\ud55c \ud074\ub77c\uc774\uc5b8\ud2b8 \uc18c\ud504\ud2b8\uc6e8\uc5b4\uac00 \uc788\uc73c\uba74 '\ud638\uc2a4\ud2b8' [...]
+pairing.op.fail=\ud328\uc5b4\ub9c1 \uc791\uc5c5 \uc2e4\ud328
+pairing.alloc.fail=\uc0c8 \uc811\uadfc \ucf54\ub4dc \ud560\ub2f9 \uc2e4\ud328\n%1
+pairing.enable=\uc6d0\uaca9 \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8/\uc778\ud130\ud398\uc774\uc2a4\uc640 Vuze \ud328\uc5b4\ub9c1 \ud65c\uc131\ud654
+pairing.status.info=\uc0c1\ud0dc
+pairing.status.registered=\uc5c5\ub370\uc774\ud2b8 \uc131\uacf5 (%1)
+pairing.status.pending=\uc5c5\ub370\uc774\ud2b8\ub294 %1\uc5d0\uc11c \uc218\ud589\ub420 \uac83\uc785\ub2c8\ub2e4
+pairing.status.initialising=\ucd08\uae30\ud654 \uc911
+pairing.status.disabled=\ube44\ud65c\uc131\ub428
+pairing.view.registered=\ud604\uc7ac \ub4f1\ub85d \uc138\ubd80\uc0ac\ud56d\uc744 \ubcf4\ub824\uba74 \ud074\ub9ad
+webui.pairing.info.n=\ud328\uc5b4\ub9c1\uc774 \ube44\ud65c\uc131\ub428, \uc774 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ubcf4\ub824\uba74 \uc5f0\uacb0\u2192\ud328\uc5b4\ub9c1 \uc635\uc158 \ucc38\uace0
+webui.pairing.info.y=\ud328\uc5b4\ub9c1\uc774 \ud65c\uc131\ud654\ub428, \uc774 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ubcf4\ub824\uba74 \uc5f0\uacb0\u2192\ud328\uc5b4\ub9c1 \uc635\uc158 \ucc38\uace0
+webui.enable=\ud65c\uc131\ud654
+ConfigView.section.rss=\uc9c0\uc5ed RSS \ub4f1
+subscriptions.rss.enable=\uad6c\ub3c5\uc73c\ub85c\ubd80\ud130 RSS \ud53c\ub4dc \uc0dd\uc131
+device.tivo.enable=TiVo \uc9c0\uc6d0 \ud65c\uc131\ud654
+Button.removeAll=\ubaa8\ub450 \uc81c\uac70
+label.rename=\uc774\ub984 \ubc14\uafb8\uae30 %1
+pairing.server.warning.title=\ud328\uc5b4\ub9c1 \uc11c\ubc84 \uba54\uc2dc\uc9c0
+wizard.webseedseditor.edit.title=HTTP \uc2dc\ub4dc \ud3b8\uc9d1\uae30
+wizard.webseedseditor.edit.newseed=\uc0c8 \uc2dc\ub4dc
+MyTorrentsView.menu.editWebSeeds=HTTP \uc2dc\ub4dc \ud3b8\uc9d1
+ClientStats.title.full=\ud074\ub77c\uc774\uc5b8\ud2b8 \ud1b5\uacc4
+ClientStats.column.count=\uc218
+Scrape.status.cached=\uce90\uc2dc\ub41c \uc2a4\uc6dc \uc815\ubcf4
+network.ipv6.enable.support=IPv6 \uc9c0\uc6d0 \ud65c\uc131\ud654 (Windows\uc5d0\uc11c\ub294 Java7 \ud544\uc694)
+ConfigView.section.plugins.magnetplugin=\ub9c8\uadf8\ub137 URI \ucc98\ub9ac\uae30
+MagnetPlugin.use.lookup.service=DHT\ub97c \ud1b5\ud55c \ub9c8\uadf8\ub137 \ucc3e\uc544\ubcf4\uae30 \uc2e4\ud328 \uc2dc \ubcf4\uc870 Vuze \ucc3e\uc544\ubcf4\uae30 \uc11c\ube44\uc2a4 \uc0ac\uc6a9
+MagnetPlugin.report.secondarylookup=\ucc3e\uc544\ubcf4\uae30 \ubcf4\uc870 \uc11c\ube44\uc2a4 \uc2dc\ub3c4
+MagnetPlugin.report.secondarylookup.ok=\ucc3e\uc544\ubcf4\uae30 \ubcf4\uc870 \uc11c\ube44\uc2a4 \uc131\uacf5
+MagnetPlugin.report.secondarylookup.fail=\ucc3e\uc544\ubcf4\uae30 \ubcf4\uc870 \uc11c\ube44\uc2a4 \uc2e4\ud328: \ubc1c\uacac\ub41c \ucd9c\ucc98 \uc5c6\uc74c
+TrackerView.title.short=\ucd9c\ucc98
+TrackerView.title.full=\ucd9c\ucc98
+Trackers.column.type=\uc720\ud615
+Trackers.column.name=\uc138\ubd80\uc0ac\ud56d
+Trackers.column.status=\uc0c1\ud0dc
+Trackers.column.seeds=\uc2dc\ub4dc
+Trackers.column.seeds.info=\uc2a4\uc6dc \uc548\uc5d0 \uc788\ub294 \uc2dc\ub4dc \uc785\ub2c8\ub2e4.
+Trackers.column.leechers=\ub9ac\uccd0
+Trackers.column.leechers.info=\uc2a4\uc6dc \uc548\uc5d0 \uc788\ub294 (\ubc30\ud3ec\ud558\uc9c0\ub294 \uc54a\uace0 \ub2e4\uc6b4\ub85c\ub4dc\ub9cc \ud558\ub294) \ub9ac\uccd0 \uc785\ub2c8\ub2e4.
+Trackers.column.peers=\ud53c\uc5b4
+Trackers.column.peers.info=\ud2b8\ub798\ucee4\uc5d0 \uc758\ud574 \ubc18\ud658\ub41c \ud53c\uc5b4
+Trackers.column.interval=\uac04\uaca9
+Trackers.column.interval.info=\ub2e4\uc2dc \uc870\ud68c\ud558\ub294 \ucd08 \ub2e8\uc704 \uac04\uaca9: \uac04\uaca9 (\ucd5c\uc18c \uac04\uaca9)
+Trackers.column.updatein=\ub2e4\uc74c
+Trackers.column.updatein.info=\ub2e4\uc74c \uc5c5\ub370\uc774\ud2b8 \uc2dc\uac04 \uc785\ub2c8\ub2e4.
+tps.status.available=\uc0ac\uc6a9\uac00\ub2a5
+tps.status.unavailable=\uc0ac\uc6a9\ubd88\uac00\ub2a5
+tps.lan.details=%1 \ub85c\uceec \ud074\ub77c\uc774\uc5b8\ud2b8 \ubc1c\uacac\ub428
+tps.pex.details=%1 \ud53c\uc5b4\uc5d0 \uc5f0\uacb0\ub428 (\ubcf4\ub958 \uc911: pex=%2, \uae30\ud0c0=%3)
+tps.tracker.cache=\ud53c\uc5b4 \uce90\uc2dc
+tps.tracker.cache1=\ud53c\uc5b4 \uce90\uc2dc: \uc5d4\ud2b8\ub9ac=%1
+dht.status.disabled=\ube44\ud65c\uc131\ub428. \ubd84\uc0b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc74c
+tps.type.incoming=\ub4e4\uc5b4\uc624\ub294 \uc5f0\uacb0
+tps.incoming.details=\ud604\uc7ac: TCP=%1, UDP=%2; \uc9c0\uae08\uae4c\uc9c0 \ucd1d\uacc4=%3
+tps.type.plugin=\ud50c\ub7ec\uadf8\uc778
+group.auto=\uc790\ub3d9
+ConfigView.label.autoadjust=\uc5f0\uacb0 \uc18d\ub3c4\ub97c \uae30\uc900\uc73c\ub85c \uc774 \uc124\uc815\uc744 \uc790\ub3d9\uc73c\ub85c \uc870\uc815
+ConfigView.label.start=\uc2dc\ub3d9
+ConfigView.label.stop=\uc2dc\uc2a4\ud15c \uc885\ub8cc
+ConfigView.label.start.onlogin=\ub85c\uadf8\uc778 \uc2dc Vuze \uc2dc\uc791
+ConfigView.label.stop.seedcomp=\ubc30\ud3ec\uac00 \uc644\ub8cc\ub418\uba74
+ConfigView.label.stop.downcomp=\ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc644\ub8cc\ub418\uba74
+ConfigView.label.stop.Nothing=\uc544\ubb34 \uac83\ub3c4 \ud558\uc9c0 \uc54a\uc74c
+ConfigView.label.stop.QuitVuze=Vuze \uc885\ub8cc
+ConfigView.label.stop.Sleep=\ucef4\ud4e8\ud130 \uc808\uc804
+ConfigView.label.stop.Hibernate=\ucef4\ud4e8\ud130 \ucd5c\ub300 \uc808\uc804
+ConfigView.label.stop.Shutdown=\ucef4\ud4e8\ud130 \uc885\ub8cc
+core.shutdown.alert=%2\ub85c \ucd09\ubc1c\ub41c '%1' \ub3d9\uc791
+core.shutdown.dl=\ub2e4\uc6b4\ub85c\ub4dc \uc644\ub8cc
+core.shutdown.se=\ubc30\ud3ec \uc644\ub8cc
+pairing.last.error=\ucd5c\uadfc \uc624\ub958
+MainWindow.menu.pairing=\uc6d0\uaca9 \ud328\uc5b4\ub9c1
+ConfigView.label.pauseresume=\uc790\ub3d9\uc77c\uc2dc\uc815\uc9c0/\ub2e4\uc2dc \uc2dc\uc791
+update.now.title=\uc5c5\ub370\uc774\ud2b8 \ud544\uc694
+update.now.desc=Vuze\ub294 \ub9c8\uc774\uadf8\ub808\uc774\uc158\uc744 \uc644\ub8cc\ud558\uae30\uc704\ud574 \uc5c5\ub370\uc774\ud2b8\ub97c \uc801\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.\n\n\uc774 \ub300\ud654\uc0c1\uc790\ub97c \ub2eb\uc73c\uba74 Windows\uac00 \uc5c5\ub370\uc774\ud2b8 \uacfc\uc815\uc744 \uc644\ub8cc\ud560 \uac83\uc778\uc9c0 \uc9c8\ubb38\ud560 \uac83\uc785\ub2c8\ub2e4.\n\nVuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud560 \ud544\uc694\ub294 \uc5c6\uc2b5\ub2c8\ub2e4.
+ConfigView.label.jvm=Java \uc635\uc158
+platform.jvmopt.sunonly=Sun JVM\ub9cc \uc9c0\uc6d0\ud568 (\ud604\uc7ac \uc81c\uc870\uc790=%1)
+platform.jvmopt.configerror=\uc124\uc815 \uc624\ub958\ub85c \uc778\ud574 JVM \uc635\uc158\uc744 \uad00\ub9ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+platform.jvmopt.nolinkfile=\ub9c8\uc774\uadf8\ub808\uc774\uc158\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc544\uc11c JVM \uc635\uc158\uc744 \uad00\ub9ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+platform.jvmopt.nolink=\uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uc124\uc815\uc73c\ub85c \uae08\uc9c0\ub41c JVM \uc635\uc158\uc744 \uad00\ub9ac\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.
+platform.jvmopt.accesserror=JVM \uc635\uc158 \ud30c\uc77c \uc811\uadfc \uc2e4\ud328: %1
+pairing.status.noservices=\ud65c\uc131\ud654\ub41c \uc6d0\uaca9 \uc11c\ube44\uc2a4 \uc5c6\uc74c
+webui.pairingtest=\t\ud328\uc5b4\ub9c1\uc744 \ud14c\uc2a4\ud2b8\ud558\ub824\uba74 \ud074\ub9ad
+webui.connectiontest=\t\uc5f0\uacb0 \ud14c\uc2a4\ud2b8\ud558\ub824\uba74 \ud074\ub9ad
+jvm.info=\uc635\uc158\uc774 \ubcc0\uacbd\ub41c \uacbd\uc6b0 Vuze\ub97c \ub2e4\uc2dc \uc2dc\uc791\ud574\uc57c \ud569\ub2c8\ub2e4.\n*** \uacbd\uace0 - JVM \uc635\uc158\uc744 \uc798\ubabb \ubcc0\uacbd\ud558\uba74 Vuze \uc2dc\uc791\uc744 \uc2e4\ud328\ud558\uac70\ub098 \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c8 \uc218 \uc788\uc2b5\ub2c8\ub2e4! ***\n
+jvm.show.file=\ub85c\uceec JVM \uc635\uc158 \ud30c\uc77c - \ubcf5\uad6c \ubaa9\uc801\uc73c\ub85c\ub9cc \uc9c1\uc811 \ud3b8\uc9d1 \ubc14\ub78d\ub2c8\ub2e4:\n%1
+jvm.reset=JVM \uc635\uc158\uc744 \uc124\uce58 \uc2dc \uae30\ubcf8\uac12\uc73c\ub85c \ucd08\uae30\ud654
+jvm.error=JVM \uc635\uc158 \uc811\uadfc \uc624\ub958: %1
+jvm.max.mem=\ucd5c\ub300 \uba54\ubaa8\ub9ac \ud06c\uae30 [\ube48\uce78=\uae30\ubcf8\uac12,\ucd5c\ub300=%1]
+jvm.min.mem=\ucd5c\uc18c \uba54\ubaa8\ub9ac \ud06c\uae30 [\ube48\uce78=\uae30\ubcf8\uac12,\ucd5c\uc18c=%1]
+ConfigView.section.invalid.value.title=\uc798\ubabb\ub41c \uac12
+ConfigView.section.invalid.value=%2\uc5d0 \ub300\ud574 \uc798\ubabb \uc785\ub825\ub41c \uac12 '%1': %3
+Button.dismiss=\ubc84\ub9ac\uae30
+webui.pairing.autoauth=\uae30\ubcf8 \uc554\ud638 \ubcf4\ud638 \ud65c\uc131\ud654: \uc0ac\uc6a9\uc790\uc774\ub984=vuze, \uc554\ud638=<\ud328\uc5b4\ub9c1 \uc811\uadfc \ucf54\ub4dc>
+ConfigView.label.stop.autoreset=\ud55c\ubc88 \ud2b8\ub9ac\uac70 \ub418\uba74 \uc790\ub3d9\uc73c\ub85c '%1'\ub85c \ucd08\uae30\ud654
+remote.pairing.title=\uc6d0\uaca9 \ud328\uc5b4\ub9c1
+remote.pairing.subtitle=Vuze Remote\ub294 Vuze\ub97c \uc5b4\ub5a4 \ucef4\ud4e8\ud130\ub098 \ubaa8\ubc14\uc77c \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c\ub3c4 Vuze\ub97c \uc81c\uc5b4\ud560 \uc218 \uc788\uac8c \ud569\ub2c8\ub2e4 - \uc5b8\uc81c \uc5b4\ub514\uc11c\ub098.
+remote.pairing.instruction=\uc6d0\uaca9 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c\ubd80\ud130 \uc81c\uacf5\ub41c \ube48\uce78\uc5d0 \ucf54\ub4dc\ub97c \uc785\ub825\ud558\uc2ed\uc2dc\uc624.
+remote.pairing.functions=<A HREF="clip">\ucf54\ub4dc\ub97c \ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ubcf5\uc0ac</A>   |   <A HREF="new">\uc0c8 \ucf54\ub4dc \uc5bb\uae30</A>
+remote.pairing.tip.title=\ud301: Vuze Remote\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub450\uac00\uc9c0 \uc26c\uc6b4 \ubc29\ubc95:
+remote.pairing.tip.text=Vuze Remote Toolbar: <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A> \ubc29\ubb38\nVuze Remote Mobile: \ubaa8\ubc14\uc77c \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c <A HREF="http://remote.vuze.com/">remote.vuze.com</A> \ubc29\ubb38
+remote.pairing.learnmore=<A HREF="http://www.vuze.com/pairing_learnmore.start">\ud328\uc5b4\ub9c1 FAQ</A>
+remote.pairing.accesscode=\uc811\uadfc \ucf54\ub4dc:
+remote.pairing.test.running=\uc6d0\uaca9 \uc811\uc18d \ud14c\uc2a4\ud2b8 \uc911...
+remote.pairing.test.success=\uc6d0\uaca9\uc5d0\uc11c Vuze\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.
+remote.pairing.test.unavailable=\uc6d0\uaca9 \uc811\uc18d\uc774 \uac00\ub2a5\ud55c\uc9c0\ub97c \uc54c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. <A HREF="retry">\ub2e4\uc2dc \uc2dc\ub3c4</A>
+remote.pairing.test.fail=\ub85c\uceec \ub124\ud2b8\uc6cc\ud06c \ubc16\uc5d0\uc11c Vuze\uc5d0 \uc811\uadfc\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.  <A HREF="http://www.vuze.com/pairing_error_faq.start">\ub354\ubcf4\uae30</A>
+update.fail.app.changed.title=\uc5c5\ub370\uc774\ud2b8 \uc2e4\ud328
+update.fail.app.changed=Vuze\ub294 \uc5c5\uadf8\ub808\uc774\ub4dc \ub418\uc5b4\uc57c \ud558\uc9c0\ub9cc \uc751\uc6a9\ud504\ub85c\uadf8\ub7a8 \uc774\ub984\uc774 '%1'\uc73c\ub85c \ubcc0\uacbd\ub418\uc5b4 \uc791\uc5c5 \uc9c4\ud589\uc744 \uc790\ub3d9\uc73c\ub85c \uc218\ud589\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\n\nhttp://www.vuze.com/ \uc5d0\uc11c \ucd5c\uc2e0 \uc124\uce58 \ud328\ud0a4\uc9c0\ub97c \ub2e4\uc6b4\ub85c\ub4dc \ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+webui.port.override=\ud3ec\ud2b8 \uc6b0\uc120\uc801\uc6a9: \uacf5\uac1c \ud3ec\ud2b8\uac00 NAT \uc124\uc815\uc73c\ub85c \uc778\ud55c \ub0b4\ubd80 \ud3ec\ud2b8\uc640 \ub2e4\ub97c \uacbd\uc6b0\uc5d0\ub9cc \ud544\uc694\ud568
+MainWindow.status.warning.tooltip=\uc138\ubd80\uc0ac\ud56d\uc744 \ubcf4\ub824\uba74 \uc5ec\uae30\ub97c \ud074\ub9ad
+search.dialog.text=\uc0c8 \ud1a0\ub80c\ud2b8\ub97c \uac80\uc0c9\ud558\uae30 \uc704\ud55c \ud14d\uc2a4\ud2b8 \uc785\ub825:
+core.not.available=Vuze\uac00 \uc544\uc9c1 \ucd08\uae30\ud654 \uc911\uc785\ub2c8\ub2e4. \uc644\ub8cc \ub418\uc5c8\uc744 \ub54c \ub2e4\uc2dc \uc2dc\ub3c4\ud574 \uc8fc\uc2ed\uc2dc\uc624
+dlg.auth.title=\ud65c\uc131\ud654
+dlg.auth.enter.subtitle.try.1=\uac70\uc758 \ub2e4 \uc654\uc2b5\ub2c8\ub2e4.
+dlg.auth.enter.line.try.1=\uc544\ub798\uc5d0 \uc0ac\uc6a9\uc790 \ud65c\uc131\ud654 \ucf54\ub4dc\ub97c \uc785\ub825\ud558\uc5ec Vuze Plus\ub85c \uc5c5\uadf8\ub808\uc774\ub4dc\ub97c \uc644\ub8cc\ud558\uc2ed\uc2dc\uc624.
+dlg.auth.enter.line.try.2=\uc8c4\uc1a1\ud569\ub2c8\ub2e4. \uc800\ud76c\uac00 \uc0ac\uc6a9\uc790\uaed8\uc11c \uc81c\uacf5\ud558\uc2e0 \ud65c\uc131\ud654 \ucf54\ub4dc\uc758 \uc720\ud6a8\uc131\uc744 \ud655\uc778\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ubc88\ud638\ub97c \ud655\uc778\ud558\uc2dc\uace0 \ub2e4\uc2dc \uc785\ub825\ud574\ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+dlg.auth.enter.prompt=Vuze Plus \ud65c\uc131\ud654 \ucf54\ub4dc:
+Button.validate=\uc720\ud6a8\uc131 \ud655\uc778
+Button.getstarted=\uc2dc\uc791\ud558\uae30
+Button.goLibrary=\ub0b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub85c \uac00\uae30
+dlg.auth.success.subtitle=\ucd95\ud558\ud569\ub2c8\ub2e4!
+dlg.auth.success.line1=Vuze Plus\ub85c \uc5c5\uadf8\ub808\uc774\ub4dc \ud574\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4.
+dlg.auth.success.line2=\uc774\uc81c \uc7ac\uc0dd \ud69f\uc218 \uc81c\ud55c \uc5c6\ub294 DVD\ub85c \uad6c\uc6b8 \uc218 \uc788\uace0, \ud30c\uc77c\uc5d0 \uc228\uc5b4\uc788\ub294 \ubc14\uc774\ub7ec\uc2a4\ub97c \uac80\uc0ac\ud560 \uc218 \uc788\uc73c\uba70, \uad11\uace0 \uc5c6\uc774 \ud655\uc7a5\ub41c \uac80\uc0c9\uc744 \uc218\ud589\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4!
+dlg.auth.trial.success.line1=Vuze\ub294 DVD\ub97c \uc0dd\uc131\ud560 \uc900\ube44\uac00 \ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+dlg.auth.trial.success.subtitle=DVD \uad7d\uae30 \uc900\ube44\uc644\ub8cc
+dlg.auth.trial.success.info=\uc0ac\uc6a9\uc790 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c "\uc0c8 DVD \uc0dd\uc131"\uc73c\ub85c \ube44\ub514\uc624 \ud30c\uc77c\uc744 \ub04c\uc5b4 \ub193\uae30 \ubc14\ub78d\ub2c8\ub2e4. \uad6c\uc131 \uc694\uc18c\ub97c \uc124\uce58\ud558\uae30 \uc804\uc5d0 \uc774\ubbf8 \ube44\ub514\uc624\ub97c \ucd94\uac00\ud588\uc73c\uba74 \ub2e4\uc2dc \ucd94\uac00\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+dlg.auth.revoked=\ud3d0\uae30\ub41c \ud65c\uc131\ud654 \ucf54\ub4dc
+dlg.auth.revoked.line1=\uc0ac\uc6a9\uc790 Vuze Plus \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 \ud3d0\uae30\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub294 \uc544\ub798\ub97c \ud074\ub9ad\ud558\uc138\uc694.
+dlg.auth.revoked.link=<A HREF="info">\ud3d0\uae30\ub41c \ud65c\uc131\ud654 \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc815\ubcf4</A>
+dlg.auth.denied=\uac70\ubd80\ub41c \ud65c\uc131\ud654 \ucf54\ub4dc
+dlg.auth.denied.line1=\uc0ac\uc6a9\uc790\uc758 Vuze Plus \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 \uac70\ubd80\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ub354 \uc790\uc138\ud55c \uc815\ubcf4\ub294 \uc544\ub798\ub97c \ud074\ub9ad\ud558\uc138\uc694.
+dlg.auth.denied.link=<A HREF="info">\uac70\ubd80\ub41c \ud65c\uc131\ud654 \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc815\ubcf4</A>
+dlg.auth.cancelled=\ucde8\uc18c\ub41c \ud65c\uc131\ud654 \ucf54\ub4dc
+dlg.auth.cancelled.line1=\uc0ac\uc6a9\uc790 Vuze Plus \ud65c\uc131\ud654\uac00 \ucde8\uc18c\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+dlg.auth.cancelled.line2=\uc774\uac83\uc774 \uc624\ub958\ub77c\uace0 \ub290\ub07c\uc2e0\ub2e4\uba74 \uc601\uc218\uc99d \uc774\uba54\uc77c\uc5d0 \ub4e4\uc5b4\uc788\ub294 \uc548\ub0b4\uc5d0 \ub530\ub77c \uc9c0\uc6d0 \ubc1b\uc73c\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+dlg.auth.enter.subtitle.try.2=\uc720\ud6a8\uc131 \ud655\uc778 \uc2e4\ud328
+dlg.auth.enter.link.try.2=\uc544\uc9c1 Vuze Plus\ub97c \uad6c\uc785\ud558\uc9c0 \uc54a\uc73c\uc168\ub2e4\uba74 <A HREF="link">\uc5ec\uae30\ub97c \ud074\ub9ad</A>\ud558\uc138\uc694.
+dlg.auth.enter.link.try.1=\ud65c\uc131\ud654 \ucf54\ub4dc\uac00 \uc5c6\ub098\uc694? <A HREF="upgrade">\uc9c0\uae08 \uc5c5\uadf8\ub808\uc774\ub4dc \ud558\uc138\uc694</A>.
+dlg.auth.enter.expiry=\ud604\uc7ac \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 %1\uc5d0 \ub9cc\ub8cc\ub429\ub2c8\ub2e4.
+dlg.auth.enter.revoked=\ud604\uc7ac \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 \ud3d0\uae30\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+dlg.auth.enter.cancelled=\ud604\uc7ac \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 \ucde8\uc18c\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+dlg.auth.enter.denied=\ud604\uc7ac \ud65c\uc131\ud654 \ucf54\ub4dc\ub294 \uac70\ubd80\ub418\uc5c8\uc2b5\ub2c8\ub2e4.
+dlg.auth.validating.subtitle=\uc720\ud6a8\uc131 \ud655\uc778 \uc911...
+dlg.try.trial.title=DVD \uad7d\uae30 \uc0ac\uc6a9\ud574\ubcf4\uae30
+dlg.try.trial.text=Vuze\ub294 \uc0ac\uc6a9\uc790 \ube44\ub514\uc624\ub97c DVD\ub85c \uad7d\uae30 \uc704\ud574 \ud50c\ub7ec\uadf8\uc778\uc744 \uaf2d \uc124\uce58\ud574\uc57c\ud569\ub2c8\ub2e4. \ucf1c\uae30\ub97c \ud074\ub9ad\ud558\uc5ec \uacc4\uc18d \ud558\uc2ed\uc2dc\uc624.
+dlg.auth.tos=\ub098\ub294 <A HREF="tos">\uc11c\ube44\uc2a4 \uc57d\uad00</A>\uc744 \uc77d\uc5c8\uace0 \ub3d9\uc758\ud569\ub2c8\ub2e4.
+dlg.auth.install.subtitle.plus=Vuze Plus \uc124\uce58 \uc911...
+dlg.auth.install.subtitle.trial=DVD \uad7d\uae30 \uc124\uce58 \uc911
+dlg.auth.install.progress=%1 \uad6c\uc131 \uc694\uc18c \uc124\uce58 \uc911...
+dlg.auth.install.pct=%1% \uc644\ub8cc
+mdi.entry.dvdburn=DVD \uad7d\uae30
+mdi.entry.dvdburn.new=\uc0c8 DVD \uc0dd\uc131
+menu.register=Vuze Plus \ud65c\uc131\ud654
+dlg.auth.trial.title=DVD \uad7d\uae30 \ud3c9\uac00\ud310
+dlg.player.install.subtitle=\uc124\uce58
+dlg.player.install.description=\ucd94\uac00 \uc7ac\uc0dd \uad6c\uc131 \uc694\uc18c \uc124\uce58 \uc911...
+devices.xcode.remove.vetoed='%1'\uc758 \ud2b8\ub79c\uc2a4 \ucf54\ub529\uc774 \uc9c4\ud589 \uc911 \uc785\ub2c8\ub2e4. \ud574\ub2f9 \ub2e4\uc6b4\ub85c\ub4dc\ub294 \uc774 \uc791\uc5c5\uc774 \uc644\ub8cc\ub420 \ub54c\uae4c\uc9c0 \uc81c\uac70\ub420 \uc218 \uc5c6\uc73c\uba70, \uc81c\uac70\ud560 \uacbd\uc6b0 \ud2b8\ub79c\uc2a4 \ucf54\ub4dc\uac00 \ucde8\uc18c \ub429\ub2c8\ub2e4.
+Button.agree=\ub3d9\uc758\ud569\ub2c8\ub2e4
+dlg.auth.install.failed.title=\ud65c\uc131\ud654 \uc2e4\ud328
+dlg.auth.install.failed.text=\uc11c\ubc84 \uc624\ub958 \ub54c\ubb38\uc5d0 '%1' \ucf54\ub4dc\uc758 \ud65c\uc131\ud654\uac00 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4.\n\n\ub098\uc911\uc5d0 \ud65c\uc131\ud654\ub97c \ub2e4\uc2dc \uc2dc\ub3c4\ud574\ubcf4\uc138\uc694 (\ubcf4\uace0\ub41c \uc624\ub958: '%2')
+device.status.online=\uc7a5\uce58 \uc628\ub77c\uc778
+device.itunes.status.running=iTunes \uc2e4\ud589 \uc911
+device.itunes.status.notrunning=iTunes\uc774 \uc2e4\ud589\ub418\uace0 \uc788\uc9c0 \uc54a\uc74c
+device.itunes.status.notinstalled=iTunes\uc774 \uc124\uce58\ub418\uc9c0 \uc54a\uc74c
+OpenTorrentWindow.mb.notTorrent.retry=\ub9c8\uadf8\ub137 \ucc3e\uc544\uac00\uae30
+ConfigView.section.ipfilter.clear.on.reload=\uc0c8\ub85c \uace0\uce60 \ub54c \ud544\ud130\ub97c \uc9c0\uc6c1\ub2c8\ub2e4. \uc0c8\ub85c \uace0\uce58\ub294 \ub3c4\uc911\uc5d0\ub294 IP\uac00 \ucc28\ub2e8\ub420 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uccb4\ud06c \ud45c\uc2dc\ub97c \uc9c0\uc6b0\uba74 \ucd5c\uadfc \ucc28\ub2e8\uc744 \ud574\uc81c\ud55c \uac83\uc5d0 \ub300\ud574\uc11c\ub294 \ub2e4\uc2dc \uc2dc\uc791\ud560 \ub54c\uae4c\uc9c0 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
+view.waiting.core=Vuze \ucf54\uc5b4\uac00 \uc77c\ub2e8 \uba54\ubaa8\ub9ac\uc5d0 \uc801\uc7ac\uac00 \uc644\ub8cc\ub418\uba74 \ubcf4\uae30\uac00 \ub098\ud0c0\ub0a9\ub2c8\ub2e4..
+devices.profile.direct=\uc9c1\uc811
+cat.autoxcode=\uc790\ub3d9\uc7a5\uce58
+ConfigView.section.tables=\ud45c
+ConfigView.section.style.useTree=\ub77c\uc774\ube0c\ub7ec\ub9ac/\ub0b4 \ud1a0\ub80c\ud2b8 \ubcf4\uae30\uc5d0 \ud30c\uc77c \ubcf4\uc5ec\uc8fc\uae30 (\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694)
+ConfigView.section.mode.resetdefaults=\uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815 \ucd08\uae30\ud654 (\ub2e4\uc2dc \uc2dc\uc791\uc744 \uad8c\uc7a5\ud568)
+resetconfig.warn.title=\ub3d9\uc791 \uc2b9\uc778
+resetconfig.warn=\uc9c0\uae08\uae4c\uc9c0\uc758 \ubaa8\ub4e0 Vuze \uc124\uc815\uc744 \uc783\uc5b4\ubc84\ub9ac\uac8c \ub429\ub2c8\ub2e4.\n\uc124\uc815 \ucd08\uae30\ud654\ub97c \uacc4\uc18d\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+ConfigView.label.xfer.bias_up=\ubbf8\uc644\ub8cc \ub2e4\uc6b4\ub85c\ub4dc\uc5d0 \ub300\ud574 \ubab0\uc544\uc8fc\uae30 \uc5c5\ub85c\ub4dc \uc6a9\ub7c9\uc744 \uc801\uc6a9\ud574\uc11c \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4\ub97c \ub192\uc774\uae30
+ConfigView.label.xfer.bias_slack=KB/s \uc644\ub8cc\ub41c \ub2e4\uc6b4\ub85c\ub4dc\uc5d0 \ub300\ud55c \ucd5c\uc18c \uc608\uc57d \uc18d\ub3c4
+ConfigView.label.xfer.bias_no_limit=\uc720\ud6a8\ud55c \uc804\uc5ed \uc5c5\ub85c\ub4dc \uc81c\ud55c \uc5c6\uc744 \ub54c \ubab0\uc544\uc8fc\uae30 \uc801\uc6a9 \uc2dc\ub3c4
+SpeedView.stats.upload=\ub300\uae30\uc911\uc778 \uc5c5\ub85c\ub4dc \ub370\uc774\ud130:
+SpeedView.stats.con=\uc5f0\uacb0 \uc138\ubd80\uc0ac\ud56d:
+SpeedView.stats.con_details=\uc804\uccb4=%1, \ud3ec\ud654\ub428=%2, \ub300\uae30=%3, \ucc28\ub2e8\ub428=%4
+SpeedView.stats.upbias=\uc5c5\ub85c\ub4dc \ubab0\uc544\uc8fc\uae30:
+dlg.install.mlab.subtitle=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8 \uad6c\uc131 \uc694\uc18c \uc124\uce58 \uc911
+dlg.install.mlab.description=\uc18d\ub3c4 \ud14c\uc2a4\ud2b8 \uad6c\uc131 \uc694\uc18c\uac00 \uc124\uce58\ub418\ub294 \ub3d9\uc548 \uae30\ub2e4\ub824\uc8fc\uc2ed\uc2dc\uc624
+dial.up=\uc804\ud654\uc811\uc18d
+auto.mode=\uc790\ub3d9 (\uad8c\uc7a5)
+manual.mode=\uc218\ub3d9
+configureWizard.transfer2.hint=\uc5c5\ub85c\ub4dc \uc81c\ud55c\uc744 \ub108\ubb34 \ub192\uac8c \uc7a1\uac70\ub098 \ub0ae\uac8c \uc7a1\uc73c\uba74 \ub2e4\uc6b4\ub85c\ub4dc \uc131\ub2a5\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce69\ub2c8\ub2e4!
+configureWizard.transfer2.message=Bittorrent\ub294 tit-for-tat \ud504\ub85c\ud1a0\ucf5c\uc744 \uae30\ubc18\uc73c\ub85c \ud569\ub2c8\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc5c5\ub85c\ub4dc \uc18d\ub3c4\uac00 \ube60\ub974\uba74 \ube60\ub97c \uc218\ub85d \ub2e4\uc6b4\ub85c\ub4dc\uac00 \ube68\ub77c\uc9d1\ub2c8\ub2e4. \uadf8\ub7ec\ubbc0\ub85c \ube60\ub978 \ub2e4\uc6b4\ub85c\ub4dc \uc18d\ub3c4 \ub610\ub294 \uc88b\uc740 \uacf5\uc720\ube44\ub97c \ube68\ub9ac \uc5bb\uc73c\ub824\uba74, \uc88b\uc7 [...]
+configureWizard.transfer2.group=\ubaa8\ub4dc
+configureWizard.transfer2.test.info=\uc804\uccb4 \uc18d\ub3c4 \ud14c\uc2a4\ud2b8\ub97c \uc218\ud589\ud558\ub3c4\ub85d \uc120\ud0dd
+configureWizard.transfer2.test=\uc2e4\ud589 \ud14c\uc2a4\ud2b8
+configureWizard.transfer2.mselect=\uc5f0\uacb0 *\uc5c5\ub85c\ub4dc* \uc18d\ub3c4 \uc81c\ud55c \uc120\ud0dd
+configureWizard.transfer2.mselect.info=\uac01 xxx/<\uac12> \ud56d\ubaa9\uc740 \uc5f0\uacb0\uc758 <\uac12> \ucd08\ub2f9 \ube44\ud2b8 \ub2e8\uc704 \uc5c5\ub85c\ub4dc \uc18d\ub3c4\ub97c \ub098\ud0c0\ub0c5\ub2c8\ub2e4.\n\uc608\ub97c \ub4e4\uc5b4, \uc0ac\uc6a9\uc790\uac00 768 Kbps \ub2e4\uc6b4\uc2a4\ud2b8\ub9bc \uc18d\ub3c4\uc640 384 Kbps \uc5c5\uc2a4\ud2b8\ub9bc \uc18d\ub3c4\ub85c \uad6c\uc131\ub41c ADSL \uc5f0\uacb0\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uba74, 'xxx/384 kbit/sec'\ub97c \uc12 [...]
+configureWizard.transfer2.rate.unchanged=\ud604\uc7ac \uc124\uc815\uc774 \uc0ac\uc6a9\ub420 \uac83\uc784
+configureWizard.transfer2.rate.changed=\uc5f0\uacb0 \uc81c\ud55c=%1\n\uc801\uc6a9 \uc81c\ud55c\uc740 %2 (\ucd5c\ub300 \ud65c\uc131 \ud1a0\ub80c\ud2b8=%3, \ucd5c\ub300 \uc9c4\ud589 \ub2e4\uc6b4\ub85c\ub4dc=%4)\uc774 \ub429\ub2c8\ub2e4
+speedtest.wizard.select.title=\uc2e4\ud589\ud560 \uc18d\ub3c4 \ud14c\uc2a4\ud2b8 \uc720\ud615 \uc120\ud0dd
+speedtest.wizard.select.group=\ud14c\uc2a4\ud2b8 \uc720\ud615
+speedtest.wizard.select.general=\uc77c\ubc18 \uc18d\ub3c4 \ud14c\uc2a4\ud2b8 (\uad8c\uc7a5)
+speedtest.wizard.select.bt=Bittorrent\uc5d0 \ud55c\uc815\ub41c \uc18d\ub3c4 \ud14c\uc2a4\ud2b8
+FileItem.storage.reorder=\ub2e4\uc2dc \uc815\ub82c
+ConfigView.label.piecereorder=\ub2e4\uc6b4\ub85c\ub4dc \ub41c \uac83\uc5d0 \ub530\ub77c \ud30c\uc77c\uc5d0 \ub370\uc774\ud130\ub97c \ub367\ubd99\uc774\uace0 \ub2e4\uc6b4\ub85c\ub4dc \uc9c4\ud589 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc870\uac01\uc744 \ub2e4\uc2dc \uc815\ub82c
+ConfigView.label.piecereorderminmb=\ub2e4\uc74c\ubcf4\ub2e4 \ud070 \ud30c\uc77c\ub9cc \ub2e4\uc2dc \uc815\ub82c (MB \ub2e8\uc704)
+configureWizard.transfer2.current=<\ud604\uc7ac \uc124\uc815>
+ConfigView.section.style.extendedErase=\uaca9\uc790\uc120\uc744 \uadf8\ub824\uc11c \ube48 \uacf5\uac04\uc744 \uccb4\uc6b0\uae30
+iconBar.stream=\uc2a4\ud2b8\ub9bc
+FilesView.menu.setpriority.numeric=\uc22b\uc790...
+FilesView.dialog.priority.title=\uc6b0\uc120\uc21c\uc704 \uc22b\uc790 \uc785\ub825
+FilesView.dialog.priority.text=0=\ubcf4\ud1b5, 1=\ub192\uc74c, 2=\ub354 \ub192\uc74c...
+beta.wizard.title=\ubca0\ud0c0 \ubc84\uc804 \uc124\uce58
+beta.wizard.intro.title=\ucc38\uc5ec \uc120\ud0dd
+beta.wizard.info=Vuze \ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8\uc5d0 \ucc38\uc5ec\ud558\uba74 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc0c1\uc758 \ucd5c\uc2e0 \ub610\ub294 \uc55e\uc73c\ub85c \ucd94\uac00\ub420 \uae30\ub2a5\uc5d0 \ubbf8\ub9ac \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \uc5bb\uac8c \ub429\ub2c8\ub2e4.\n\n\uc0ac\uc6a9\uc790\ub294 \uc774\ub7ec\ud55c \uae30\ub2a5\uc744 \ubbf8\ub9ac \uc0ac\uc6a9\ud574\ubcfc \uc218 \uc788\ub294 \uae30\ud68c\ub97c \uc5bb\uc74c\uacfc \ub3d9\u [...]
+beta.wizard.link=\uc5ec\uae30\ub97c \ud074\ub9ad\ud574\uc11c \ubca0\ud0c0 \ub9b4\ub9ac\uc988 \uc6f9 \ud398\uc774\uc9c0 \uc5f4\uae30
+beta.wizard.off=\uc815\uc2dd \ubc84\uc804\uc73c\ub85c \ub9cc\uc871\ud569\ub2c8\ub2e4, \uad1c\ucc2e\uc544\uc694!
+beta.wizard.on=\ucd5c\uc2e0 \uc548\uc815 \ubca0\ud0c0 \ubc84\uc804\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ub97c \uc6d0\ud569\ub2c8\ub2e4.
+beta.wizard.version=\uc0ac\uc6a9\uc790\uac00 \uc2e4\ud589 \uc911\uc778 \ubc84\uc804: %1
+beta.wizard.disable.title=\ub2e4\uc2dc \uc124\uce58 \ud544\uc694
+beta.wizard.disable.text=\ubca0\ud0c0 \ubc84\uc804\uc744 \uc2dc\ud5d8\ud574\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!\n\n\ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8 \ucc38\uc5ec\ub97c \uadf8\ub9cc\ub450\uc2dc\ub824\uba74 \ucd5c\uc2e0 \uc815\uc2dd \ubc84\uc804\uc744 \ub2e4\uc6b4\ub85c\ub4dc\ud574\uc11c \uc124\uce58\ud574\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4
+beta.wizard.forum=\ud53c\ub4dc\ubc31\uc774\ub098 \ubc84\uadf8 \ub9ac\ud3ec\ud305\uc744 \uc704\ud574 Vuze \ud3ec\ub7fc \uc774\uc6a9
+dlg.install.vuzexcode.subtitle=\ubbf8\ub514\uc5b4 \ubd84\uc11d\uae30 \uad6c\uc131 \uc694\uc18c \uc124\uce58 \uc911
+dlg.install.vuzexcode.description=\ubbf8\ub514\uc5b4 \ubd84\uc11d\uae30 \uad6c\uc131 \uc694\uc18c\uac00 \uc124\uce58\ub418\ub294 \ub3d9\uc548 \uae30\ub2e4\ub824\uc8fc\uc2ed\uc2dc\uc624
+TableColumn.header.filecount=\ud30c\uc77c
+TableColumn.header.torrentspeed=\uc18d\ub3c4
+FileProgress.deleted=\uc0ad\uc81c\ub428
+priority.high=\ub192\uc740 \uc6b0\uc120\uc21c\uc704
+priority.normal=\ubcf4\ud1b5 \uc6b0\uc120\uc21c\uc704
+label.wrap.text=\ud14d\uc2a4\ud2b8 \uc904 \ubc14\uafc8
+ScrapeInfoView.title=\uc8fc \ud2b8\ub798\ucee4
+Column.seedspeers.started=%2 \uc911 %1
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 \ud56d\ubaa9: %2 \ud65c\uc131
+library.incomplete.header.p=%1 \ud56d\ubaa9 \ub2e4\uc6b4\ub85c\ub4dc \uc911, %2 \ub2e4\uc6b4\ub85c\ub4dc \ub300\uae30 \uc911
+library.unopened.header.p=%1 \ud56d\ubaa9
+library.all.header=%1 \ud56d\ubaa9: %2 \ud65c\uc131
+library.incomplete.header=%1 \ud56d\ubaa9 \ub2e4\uc6b4\ub85c\ub4dc \uc911, %2 \ub2e4\uc6b4\ub85c\ub4dc \ub300\uae30 \uc911
+library.unopened.header=%1 \ud56d\ubaa9
+ConfigView.section.style.status.show_rategraphs=\ub2e4\uc6b4\ub85c\ub4dc/\uc5c5\ub85c\ub4dc \ud45c\uc2dc \uc544\ub798 \uc18d\ub3c4 \ud788\uc2a4\ud1a0\ub9ac \uadf8\ub798\ud504 \ubcf4\uc5ec\uc8fc\uae30
+device.error.mountrequired="%1": \uc0ac\uc6a9\uc790 \uc7a5\uce58\uc640 \ub9c8\uc6b4\ud2b8\uac00 \ud544\uc694
+v3.deviceview.infobar.line2.android=\ube44\ub514\uc624\ub97c \ud3f0\uc5d0 \uc804\uc1a1\ud558\ub824\uba74 USB \ub9c8\uc6b4\ud2b8\ub97c \ud65c\uc131\ud654 \ud574\uc8fc\uc2ed\uc2dc\uc624.
+MyTorrents.column.ColumnProgressETA.compon=%1\uc5d0 \uc644\ub8cc\ub428
+Sidebar.beta.title=\ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8
+MainWindow.menu.beta.on=\ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8 \ucc38\uc5ec...
+MainWindow.menu.beta.off=\ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8 \ud0c8\ud1f4...
+Button.sendNow=\uc9c0\uae08 \ubcf4\ub0b4\uae30
+Button.sendManual=\uc218\ub3d9 \ubcf4\ub0b4\uae30 (.zip \uc0dd\uc131\ud558\uae30)
+deletecontent.also.deletetorrent=.torrent  \ud30c\uc77c\ub3c4 \uc0ad\uc81c
+ConfigView.section.file.deletion.section=\ud30c\uc77c \uc0ad\uc81c
+ConfigView.section.file.delete.torrent=\uae30\ubcf8\uac12\uc73c\ub85c, \ucee8\ud150\ud2b8\ub97c \uc0ad\uc81c\ud560 \ub54c .torrent \ud30c\uc77c\uc744 \uc0ad\uc81c
+ConfigView.section.file.delete.confirm=\ub3c4\uad6c \ubaa8\uc74c\uc774\ub098 \uc0ad\uc81c \ud0a4\ub97c \ud1b5\ud574 \uc0ad\uc81c\ub418\ub294 \ucee8\ud150\uce20 \uc2b9\uc778
+MainWindow.menu.view.beta=\ubca0\ud0c0 \ud504\ub85c\uadf8\ub7a8
+ConfigView.section.server.enableudpprobe=HTTP \ud2b8\ub798\ucee4\uc5d0 \ub300\ud574 UDP \ud2b8\ub798\ucee4\uac00 \uc788\ub294\uc9c0 \uac80\uc0ac \ud65c\uc131\ud654
+memmon.low.warning=\uba54\ubaa8\ub9ac\uac00 \uc904\uc5b4\ub4e4\uace0 \uc788\uc2b5\ub2c8\ub2e4. %2 \uc911 %1\uac00 \ub0a8\uc544\uc788\uc2b5\ub2c8\ub2e4.\n\uc131\ub2a5\uc774 \uc800\ud558\ub420 \uac83\uc774\uba70 \uad81\uadf9\uc801\uc73c\ub85c Vuze\uac00 \ub3d9\uc791\uc744 \uba48\ucd9c \uac83\uc785\ub2c8\ub2e4.\n\uc0ac\uc6a9 \uac00\ub2a5\ud55c \uba54\ubaa8\ub9ac\ub97c \uc5b4\ub5bb\uac8c \ub298\ub9b4 \uc218 \uc788\ub294\uc9c0\uc5d0 \ub300\ud574\uc11c\ub294 <a href="http://wiki.vuze.com/w/Jav [...]
+jvm.max.mem.current=\ud604\uc7ac Heap \ucd5c\ub300\uac12\uc740 %1
+jvm.max.direct.mem=\ucd5c\ub300 \uc9c1\uc811 \uba54\ubaa8\ub9ac \ud06c\uae30 [\ube48\uce78=\uae30\ubcf8\uac12,\ucd5c\uc18c=%1]
+jvm.max.direct.mem.info=\uc8fc\uc758: \uc774\uac83\uc740 *\uc9c1\uc811* \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud569\ub2c8\ub2e4. *Heap* \uba54\ubaa8\ub9ac \uc0c1\uc704\uc5d0\uc11c \uc77c\ubc18\uc801\uc73c\ub85c \ub354 \ub9ce\uc740 \uc5c5\ub370\uc774\ud2b8 \ud544\uc694\ud569\ub2c8\ub2e4.
+jvm.options.summary=\ud604\uc7ac \uba85\uc2dc\ub41c \uc635\uc158 \uc694\uc57d:
+memmon.heap.auto.increase.warning=Heap \uba54\ubaa8\ub9ac\uac00 %1\ub85c \uc99d\uac00\ub410\uc2b5\ub2c8\ub2e4. Vuze\uac00 \ub2e4\uc2dc \uc2dc\uc791 \ub420 \ub54c \ud6a8\ub825\uc774 \ubc1c\uc0dd\ud569\ub2c8\ub2e4.
+device.showGeneric=\uc77c\ubc18 \uc7a5\uce58 \ubcf4\uc5ec\uc8fc\uae30
+mdi.entry.games=\uac8c\uc784
+Peers.column.Protocol=\ud504\ub85c\ud1a0\ucf5c
+devices.copying=\uc7a5\uce58\uc5d0 \ubcf5\uc0ac \uc911
+devices.cancel_xcode=\ubcc0\ud658 \ucde8\uc18c
+sidebar.header.transfers=\uc804\uc1a1
+sidebar.header.devices=\uc7a5\uce58
+sidebar.header.subscriptions=\uad6c\ub3c5
+sidebar.header.plugins=\ud50c\ub7ec\uadf8 \uc778 & \ucd94\uac00 \uae30\ub2a5
+mdi.entry.about.devices=\uc9c4\ud589 \uc911
+mdi.entry.about.plugins=\ud50c\ub7ec\uadf8 \uc778 \uc815\ubcf4
+mdi.entry.about.dvdburn=\uc2dc\uc791
+ConfigView.section.file.tb.delete=\uc0ad\uc81c \ud0a4\ub098 \ub3c4\uad6c \ubaa8\uc74c\uc744 \ud1b5\ud574 \uc0ad\uc81c\ud560 \ub54c:
+ConfigView.tb.delete.ask=\ubb3c\uc5b4\ubcf4\uae30
+ConfigView.tb.delete.content=\ubb3c\uc5b4\ubcf4\uc9c0 \uc54a\uace0 \uc0ad\uc81c
+ConfigView.tb.delete.torrent=\ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0\uc11c\ub9cc \uc81c\uac70
+search.export.all=\ubaa8\ub4e0 \uac80\uc0c9 \ud0ec\ud50c\ub9bf \ub0b4\ubcf4\ub0b4\uae30...
+subscriptions.search.enable=\uad6c\ub3c5 \uacb0\uacfc \uac80\uc0c9 \ud65c\uc131\ud654 (\ub2e4\uc2dc \uc2dc\uc791 \ud544\uc694)
+devices.cancel_xcode_del=\ubcc0\ud658 \ucde8\uc18c/\uc81c\uac70
+subscriptions.add.tooltip=\uad6c\ub3c5 \ucd94\uac00
+subscriptions.overview=\uad6c\ub3c5 \uac1c\uc694
+configureWizard.nat.title=NAT / \uc11c\ubc84 \ud3ec\ud2b8
+configureWizard.nat.message=Vuze\uac00 \uc7ac\uc131\ub2a5\uc744 \ub0b4\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ub137\uc5d0 \uc790\uc720\ub85c\uc6b4 \uc811\uadfc\uc774 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uac83\uc774 \uac00\uc7a5 \uc911\uc694\ud569\ub2c8\ub2e4. \uc774 \ub3c4\uad6c\ub294 \uc0ac\uc6a9\uc790\uac00 \ub4e4\uc5b4\uc624\ub294 \ud53c\uc5b4 \uc5f0\uacb0\uc744 \ubc1b\uc544\ub4e4\uc77c \uc218 \uc788\ub294 \ud3ec\ud2b8\ub97c \ud14c\uc2a4\ud2b8\ud558\uace0 \ub610\ub294 \ub [...]
+configureWizard.nat.server.udp_listen_port=\ub4e4\uc5b4\uc624\ub294 UDP \ub300\uae30 \ud3ec\ud2b8
+v3.menu.device.defaultprofile.never=\ud2b8\ub79c\uc2a4\ucf54\ub4dc \ud558\uc9c0\uc54a\uc74c
+subscriptions.info.avail=\uc544\uc9c1 \uc5b4\ub5a4 \uad6c\ub3c5\ub3c4 \ucd94\uac00\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 %1 \uc0ac\uc6a9 \uac00\ub2a5\ud569\ub2c8\ub2e4.
+subscriptions.dl_subs.enable=\ud544\uc694\ud55c \uacbd\uc6b0 \uad6c\ub3c5\uc744 \ub2e4\ub978 \ud074\ub77c\uc774\uc5b8\ud2b8\ub85c\ubd80\ud130 \ub2e4\uc6b4\ub85c\ub4dc
+# Will be used for {library.name} in classic view
+library.name._classic=\ub0b4 \ud1a0\ub80c\ud2b8
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=\ub77c\uc774\ube0c\ub7ec\ub9ac
+ConfigView.section.style.units=\ub2e8\uc704 \ud45c\uc2dc
+ConfigView.section.style.CatInSidebar=\uc0ac\uc774\ub4dc \ubc14\uc5d0 \ubd84\ub958 \ubcf4\uc5ec\uc8fc\uae30
+library.category.header=\ubd84\ub958 '%1'
+device.import.title=\uc7a5\uce58 \uac00\uc838\uc624\uae30
+device.import.desc=\uc815\ub9d0 '%1' \uc7a5\uce58\ub97c \uac00\uc838\uc624\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+device.import.dup.title=\uc911\ubcf5\ub41c \uc7a5\uce58
+device.import.dup.desc='%1' \uc7a5\uce58\uac00 \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4.
+stream.analysing.media=\ubbf8\ub514\uc5b4 \ubd84\uc11d \uc911
+device.export.select.template.file=\uc7a5\uce58 \ub0b4\ubcf4\ub0b4\uae30
+dlg.stream.plus.subtext=\ub2e4\uc6b4\ub85c\ub4dc \uc644\ub8cc\ub97c \uae30\ub2e4\ub9ac\ub294 \uac83\uc774 \uc9c0\ub8e8\ud558\uc2ed\ub2c8\uae4c? Vuze Plus\uc5d0\uc11c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc9c4\ud589\ub418\ub294 \ub3d9\uc548 \ubcfc \uc218 \uc788\ub3c4\ub85d \uc81c\uacf5\ub418\ub294 \uae30\ub2a5\uc778 [\uc9c0\uae08 \uc7ac\uc0dd]\uc73c\ub85c \uc880 \ub354 \uc77c\ucc0d \ubcf4\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.
+dlg.stream.plus.text=Vuze Plus\ub85c \uc5c5\uadf8\ub808\uc774\ub4dc\ud574\uc11c \ub2e4\uc6b4\ub85c\ub4dc\uac00 \uc9c4\ud589\ub418\ub294 \ub3d9\uc548 \ube44\ub514\uc624\ub97c \uc7ac\uc0dd\ud569\ub2c8\ub2e4.
+dlg.stream.plus.title=\uc5c5\uadf8\ub808\uc774\ub4dc
+dlg.stream.plus.subtitle=\uc5c5\uadf8\ub808\uc774\ub4dc
+dlg.stream.plus.renew.text=\ub2e4\uc6b4\ub85c\ub4dc \ub418\ub294\ub300\ub85c \ube44\ub514\uc624 \uc7ac\uc0dd\uc744 \ud558\ub824\uba74 Vuze Plus \uad6c\ub3c5\uc744 \uac31\uc2e0\ud558\uc2ed\uc2dc\uc624.
+dlg.stream.plus.renew.title=Vuze Plus \uac31\uc2e0
+dlg.stream.plus.renew.subtitle=Vuze Plus \uac31\uc2e0\ud558\uae30
+Button.upgrade=\uc5c5\uadf8\ub808\uc774\ub4dc
+Button.renew=\uac31\uc2e0
+stream.analysing.media.preview=\ubbf8\ub514\uc5b4 \ubd84\uc11d \uc911 (\ubbf8\ub9ac\ubcf4\uae30 \ubaa8\ub4dc)
+devices.restrict_access=\uc811\uadfc \uc81c\ud55c...
+devices.restrict_access.prompt='%1'\uc5d0 \uc811\uadfc \uc81c\ud55c
+devices.restrict_access.msg=\uc27c\ud45c(,)\ub85c \uad6c\ubd84\ub41c IP \ubaa9\ub85d\uc744 \ud5c8\uc6a9 [-\ub97c \uc55e\uc5d0 \ubd99\uc774\uba74 \uac70\ubd80]
+TableColumn.TorrentStream.tooltip.disabled=\ud574\ub2f9 \uc720\ud615\uc758 \ud30c\uc77c\uc740 [\uc9c0\uae08 \uc7ac\uc0dd]\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc74c
+TableColumn.TorrentStream.tooltip.expand=\uac01 \ud30c\uc77c \ubcc4\ub85c [\uc9c0\uae08 \uc7ac\uc0dd]\uc744 \ubcf4\uae30 \uc704\ud574 \ud589 \ud655\uc7a5
+table.columns.reset=\uc5f4 \ucd08\uae30\ud654
+plus.notificaiton.ExpiringEntry.s=\uc0ac\uc6a9\uc790\uc758 Vuze Plus \uad6c\ub3c5\uc774 %1\uc77c \uc548\uc5d0 \ub9cc\ub8cc\ub429\ub2c8\ub2e4: <A %2>\uc9c0\uae08 \uac31\uc2e0</A>
+plus.notificaiton.ExpiringEntry.p=\uc0ac\uc6a9\uc790\uc758 Vuze Plus \uad6c\ub3c5\uc774 %1\uc77c \uc548\uc5d0 \ub9cc\ub8cc\ub429\ub2c8\ub2e4: <A %2>\uc9c0\uae08 \uac31\uc2e0</A>
+plus.notificaiton.ExpiredEntry.s=\uc0ac\uc6a9\uc790\uc758 Vuze Plus \uad6c\ub3c5\uc774 \ub9cc\ub8cc\ub410\uc2b5\ub2c8\ub2e4: <A %2>\uc9c0\uae08 \uac31\uc2e0</A>
+plus.notificaiton.OfflineExpiredEntry=\ub108\ubb34 \uc624\ub7ab\ub3d9\uc548 \uc624\ud504\ub77c\uc778 \uc0c1\ud0dc\ub85c \uc788\uc5c8\uc2b5\ub2c8\ub2e4. Vuze Plus\ub294 \ube44\ud65c\uc131\ud654 \ub410\uc2b5\ub2c8\ub2e4.
+rss.internal.test.url=\ub85c\uceec \ud648\ud398\uc774\uc9c0\ub97c \ubcf4\ub824\uba74 \ud074\ub9ad
+cat.rss.gen=\ub85c\uceec RSS \ud53c\ub4dc \uc0dd\uc131
+dht.backup.only=DHT \ubc31\uc5c5\ub9cc
+TableColumn.header.ipfilter=IP \ud544\ud130 \ud65c\uc131\ub428
+MyTorrentsView.menu.ipf_enable=IP \ud544\ud130 \ud65c\uc131\ud654
+devices.sidebar.mainheader.tooltip=%1 \uc7a5\uce58\ub4e4\uc774 \uc77c\ubc18 \ub610\ub294 \ud14c\uae45\ub418\uc9c0 \uc54a\uc740 \uac83\uc73c\ub85c \uc228\uaca8\uc838 \uc788\uc2b5\ub2c8\ub2e4.\n\ud45c\uc2dc\ud558\ub824\uba74 \uc624\ub978\ucabd \ud074\ub9ad \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uc2ed\uc2dc\uc624
+device.mediaserver.remove_all=\ubaa8\ub4e0 \ubbf8\ub514\uc5b4 \uc11c\ubc84 \uc81c\uac70
+device.mediaserver.remove_all.title=\uc81c\uac70 \uc2b9\uc778
+device.mediaserver.remove_all.desc=\uc815\ub9d0\ub85c \ubaa8\ub4e0 \ubbf8\ub514\uc5b4 \uc11c\ubc84\ub97c \uc81c\uac70\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+device.renderer.remove_all=\ubaa8\ub4e0 \ub80c\ub354\ub7ec \uc81c\uac70
+device.renderer.remove_all.desc=\uc815\ub9d0\ub85c \ubaa8\ub4e0 \ub80c\ub354\ub7ec\uc640 \ud2b8\ub80c\uc2a4 \ucf54\ub529\ub41c \ub370\uc774\ud130\ub97c \uc81c\uac70\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?
+MyTorrentsView.menu.create_personal_share=\uac1c\uc778 \uacf5\uc720 \uc0dd\uc131
+device.tag=\uc7a5\uce58 \ud14c\uadf8
+device.onlyShowTagged=\ud14c\uae45\ub41c \uc7a5\uce58\ub9cc \ubcf4\uc5ec\uc8fc\uae30
+devices.sidebar.show.only.tagged=\ud14c\uadf8\ud55c \uc7a5\uce58\ub9cc \ubcf4\uc5ec\uc8fc\uae30
+ipfilter.disabled=IP \ud544\ud130 \uaebc\uc9d0
+ipfilter.options=IP \ud544\ud130 \uc635\uc158...
+TableColumn.header.eta_next=\ub2e4\uc74c ETA
+torrentdownload.error.dl_fail='%1'\uc5d0\uc11c '%2'\uae4c\uc9c0 \ub2e4\uc6b4\ub85c\ub4dc \uc2e4\ud328: %3
+MainWindow.menu.speed_limits=\uc18d\ub3c4 \uc81c\ud55c
+MainWindow.menu.speed_limits.profile=\ud504\ub85c\ud544 \uc774\ub984 \uc785\ub825
+MainWindow.menu.speed_limits.profiles=\ud504\ub85c\ud544
+MainWindow.menu.speed_limits.load=\uc801\uc6a9...
+MainWindow.menu.speed_limits.view=\ubcf4\uae30...
+MainWindow.menu.speed_limits.delete=\uc0ad\uc81c
+MainWindow.menu.speed_limits.view_current=\ud604\uc7ac \uc124\uc815 \ubcf4\uae30...
+MainWindow.menu.speed_limits.save_current=\ud604\uc7ac \uc124\uc815\uc744 \ub2e4\ub978 \uc774\ub984\uc73c\ub85c \uc800\uc7a5...
+MainWindow.menu.speed_limits.reset=\ud604\uc7ac \uc81c\ud55c \uc0ac\ud56d \uc9c0\uc6b0\uae30
+MainWindow.menu.speed_limits.info.title=\uc18d\ub3c4 \uc81c\ud55c \ub0b4\uc5ed
+MainWindow.menu.speed_limits.info.prof=\ud504\ub85c\ud544 '%1'\uc5d0 \ub300\ud55c \uc124\uc815
+MainWindow.menu.speed_limits.info.curr=\ud604\uc7ac \uc124\uc815
+MainWindow.menu.speed_limits.schedule=\uc77c\uc815...
+MainWindow.menu.speed_limits.schedule.title=\uc18d\ub3c4 \uc81c\ud55c \uc77c\uc815
+MainWindow.menu.speed_limits.schedule.msg=\uc18d\ub3c4 \uc81c\ud55c \ud504\ub85c\ud30c\uc77c \uc790\ub3d9\ud654 \uc751\uc6a9 \ud504\ub85c\uadf8\ub7a8\uc744 \uc81c\uc5b4\ud558\ub294 \ud604\uc7ac \uaddc\uce59
+MainWindow.menu.speed_limits.schedule.err=\ub2e4\uc74c\uacfc \uac19\uc740 \uc624\ub958\uac00 \uc788\uc2b5\ub2c8\ub2e4. \ub2e4\uc2dc \ud3b8\uc9d1\uc744 \ubd80\ud0c1\ub4dc\ub9bd\ub2c8\ub2e4!
diff --git a/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties b/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
index 8fdc769..ed58426 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_li_NL.properties
@@ -34,12 +34,9 @@ MainWindow.menu.help=&Help
 MainWindow.menu.help.about=Euver Vuze
 MainWindow.menu.torrent=T&orrentbesjturing
 MainWindow.about.title=Euver Vuze
-MainWindow.about.section.developers=\u00d3ntwikkeliers 
-MainWindow.about.section.translators=Vertalers 
 MainWindow.about.section.system=Systeem
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.sourceforge=Sourceforge Projectpagina
-MainWindow.about.internet.sourceforgedownloads=Sourceforge Downloads.
 MainWindow.about.internet.bugreports=Foutreporte
 MainWindow.about.internet.wiki=Vuze Wiki FAQ.
 MainWindow.dialog.choose.savepath=Kees 't paad veur opsjlaag
@@ -304,8 +301,6 @@ IrcView.errormsg=Verkierde syntaxis bie /msg : /msg gebroekersteks
 IrcView.help=Geljige commando's zeen :\n . /help : geuf dit berich weer\n . /Nick | /naam : verangert diene naam \n . /me actie : sjik 'n actie \n . /msg naam berich : sjik 'n priv\u00e9berich nao <naam>\n . /r berich : antwaordt op l\u00e8ste priv\u00e9berich\n . /join #kenaal : verangert 't hujige kenaal
 PasswordWindow.title=Vuze is vergrendeld
 PasswordWindow.passwordprotected=Vuze is besjirmp mit e wachwaord.\nV\u00f6l hie dien wachwaord in, \u00f3m 't v\u00e8nster te laote zeen:
-TrackerChangerWindow.title=Voeg Tracker toe
-TrackerChangerWindow.newtracker=V\u00f6l 'n nuuj trackeradres in
 PeersView.discarded=Verworpe
 PeersView.discarded.info=Data die se waal h\u00f6bs \u00f3ntvange, meh neet nudig hads, dus h\u00f6bs weggedaon.
 discarded=aafgedank
@@ -374,7 +369,6 @@ MyTorrentsView.menu.removeand.deletetorrent=&Torrentbesjtandj weghaole
 MyTorrentsView.menu.removeand.deletedata=&Data weghaole
 MyTorrentsView.menu.removeand.deleteboth=Alle&bei weghaole
 deletedata.title=Waarsjuwing
-deletedata.message1=Doe sjteis op 't puntj de DATA weg te haole van :\n
 MainWindow.menu.file.configure=K\u00f3ngfiggerasie-&wizard...
 configureWizard.title=K\u00f3ngfiggerasiewizard 
 configureWizard.welcome.title=Welk\u00f3m biej de Vuze-k\u00f3ngfiggerasiewizard
@@ -395,7 +389,6 @@ configureWizard.transfer.maxActiveTorrents=Max. actief
 configureWizard.transfer.maxDownloads=Max. downloads
 configureWizard.transfer.maxUploadsPerTorrent=Max. uploads per torrent
 configureWizard.nat.title=NAT- / serverpaort
-configureWizard.nat.message=Om het b\u00e8ste oet Vuze te haole is 't raodzaam \u00f3m good bereikbaar te zeen vanaaf 't internet. De standaardpaort is 6881. Dit program help mit 't teste / verangere van de paort.\n\nOpmirking: Dit program test allein TCP-verb\u00e8njinge. De versjpreide database vereis ouch ink\u00f3mmende UDP-verb\u00e8njinge, meh z\u00f3l dich automatisch notificere es 't 'ne firewall \u00f3ntd\u00e8k.\n\nOpmirking: TCP-paort 6880 is intern gereserveerd, dus kan neet  [...]
 configureWizard.nat.testing=Paort weurt getes
 configureWizard.nat.ok=OK!
 configureWizard.nat.ko=NAT-fout
@@ -551,7 +544,6 @@ ConfigView.section.file.decoder.nodecoder=Gein
 IPChecker.external.service.no-ip.description=Dynamic en Static DNS-serviceprovider\n(neet vrie besjikbare 'adresk\u00f3ntrol'-service)
 ConfigView.section.tracker.publicenable=Externe torrents toesjtaon
 ConfigView.label.playdownloadspeech=Kal wen 'ne download vaerdig is
-ConfigView.label.playdownloadspeech.info=De Sjpraokservice wirk 't b\u00e8ste mit Ingels
 #
 # Tooltips
 #
@@ -725,8 +717,6 @@ ConfigView.section.tracker.main=Hoof
 ConfigView.section.tracker.web=Web 
 ConfigView.label.prioritizefirstpiece=Gaef 't ierste deil van besjtenj veurrang
 ConfigView.label.prioritizefirstpiece.tooltip=Perbeert 't ierste deil van 'n besjtandj iers te downloade.\n\u00d3m previews te \u00f3ngersteune.
-ConfigView.section.file.confirm_data_delete=Weghaole van data bevestige
-ConfigView.section.file.confirm_data_delete.tooltip=Bevestig 't wusje van data bie 't gebroek van 'Verplaatsen en weghaole...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Wen data d'r vanaaf waere gehaold, torrents die gelink zeen in 'n opsjlaagmap ouch d'r vanaaf haole
 TrayWindow.menu.startalldownloads=Alle downloads sjtarte
 SystemTray.menu.startalltransfers=Alle euverdrachte sjtarte
@@ -1035,7 +1025,6 @@ ConfigView.pluginlist.whereToPutOr=Gebroek veur gedeilde plugins:
 MainWindow.statusText.checking=Controleren op updates
 TableColumn.header.OnlyCDing4=Allein uploade
 TableColumn.header.OnlyCDing4.info=Tiedsdoer wo-in de torrent allein aan 't uploade waas.\nExclusief d'n tied det de torrent aan 't downloade waas (en uploade).
-ConfigView.section.style.alternateTablePainting=Gebroek 'n alternatieve methode \u00f3m grafische tabelkel\u00f3mme te teikene (kan hersjtart vereise)
 UpdateWindow.status.restartMaybeNeeded=Hersjtart kan vereis zeen
 ConfigView.pluginlist.shared=gedeild
 PeersView.host=Hostnaam
@@ -1266,17 +1255,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF-gruutde [0: ge
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Sjtelt de sjtanderdsocket SO_SNDBUF waerde (in bytes) in, wie TCP \u00f3ntvangv\u00e8nstergruutde en sjaol.\nVuze leut dit sjtanderd \u00f3ning\u00e8steld, dit beteikent det de sjtanderd OS-inst\u00e8llinge waere gebroek.\nOpmirking: Linux verdubbelt de gegaeve waerd.
 ConfigView.section.connection.advanced.IPDiffServ=Oetg\u00e4\u00f6ndj pakket DiffServ waerd (TOS veldj)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Sjt\u00e8lt 't DiffServ-deil in van 't type-of-service(TOS)-veldj in de IP header veur oetgaonde pakkette.\nHexadecimaal waerdes kinne gespecificeerd waere door deze te veuraaf te laote gaon mit '0x', bv. 0x10.\nVuze leut dit sjtanderd ongebroek, dit beteikent det de sjtanderd van 't \u00f3ngerlikgend OS weurt gebroek.\nOpmirking: \u00d3ngerligkende netwerkimplmentaties kinne dees waerdes negere, dus dees optie is afhankelik van ' [...]
-ConfigView.section.interface.confirm_torrent_removal=Bevestigingsv\u00e8nster laote zeen es torrent d'r vanaaf weurt gehaold
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Bevestig wen 'n torrent oet Mien Torrents weurt weggehaold.
 TableColumn.header.seed_to_peer_ratio=Seed2Peer-verh.
 TableColumn.header.seed_to_peer_ratio.info=Totale zjwerm-seeders-nao-leechers-verhaajing
 PeersView.connected_time=Verb\u00f3nje tied
 PeersView.connected_time.info=Totale tied verb\u00f3nje mit de peer
-ConfigView.section.interface.display.add_torrents_silently=Voeg torrents sjtil toe
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Voeg torrent downloads toe, z\u00f3nger 't hoofv\u00e8nster te activere.
 TableColumn.header.maxdownspeed=Max. downloadsjnelheid
 TableColumn.header.maxdownspeed.info=Max. downloadsjnelheid per torrent
-PeersGraphicView.title=Zjwerm
+PeersGraphicView.title.full=Zjwerm
 ConfigView.section.tracker.passwordwebhttpsonly=Sjtaon toegank allein toe via HTTPS
 TableColumn.header.torrentpath=Torrentlocatie
 TableColumn.header.torrentpath.info=Locatie van de torrent op de sjief
@@ -1333,8 +1318,6 @@ UpdateWindow.restartLater=Later hersjtarte
 MainWindow.menu.file.restart=Vuze hersjtarte
 MainWindow.dialog.restartconfirmation.title=Vuze opnuuj opsjtarte
 MainWindow.dialog.restartconfirmation.text=W\u00e8ts je zeker des se Vuze opnuuj wils opsjtarte?
-deletetorrent.message1=Doe sjteis op 't puntj de TORRENT weg te haole veur :\n
-deletetorrent.message2=\nW\u00e8ts se zeker des se wiejer wils gaon?
 ConfigView.label.prioritizemostcompletedfiles=Gaef veurrang mit hoeg prioriteit aan besjtenj volges % compleet en de gruutde van 't besjtandj
 splash.plugin.init=Plugin initialisere:
 splash.plugin.UIinit=Plug-in GUI aan 't laje: %1  
@@ -1494,7 +1477,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent-besjtandj... (allein tracki
 MyTrackerView.date_added=Toegevoeg
 ConfigView.section.tracker.portbackup=Backuppaorte ( gesjeije door ; )
 ConfigView.label.playfilespeech=Kal es 'n besjtandj vaerdig is
-ConfigView.label.playfilespeech.info=De Sjpraokservice wirk 't b\u00e8ste mit Ingels
 ConfigView.label.playfilefinished=Sjpeel 'n geluid/meziekske es 'n sjt\u00f6kske van 't besjtandj vaerdig is
 ConfigView.label.backupconfigfiles=Backupk\u00f3ngfiggerasiebesjtenj veur hersjt\u00e8lopties
 ConfigView.section.tracker.client.scrapesingleonly=Per-tracker scrape-aggregatie oetz\u00e8tte (kan helpe bie trackers die rapportere det de  'URL te lank is ' (414) foute) 
@@ -2069,19 +2051,11 @@ v3.mb.delPublished.title=Inhaud uploade sjtoppe
 v3.mb.delPublished.text=WAARSJUWING: Dees actie z\u00f3l neet de gepubliceerde inhaud '%1' weghaole van <A HREF="%2">%3</A>  \n\nKlik allein op "Weghaole" es te de gepubliceerde inhaud besjikbaar wils hauwe \u00f3m te downloade, meh waal bandjbreide vrie wils make. Z\u00f6rg waal det de uploads good aafgesjlaote zeen veurdet-s te det duis.(<A HREF="%4">wie</A>?).\n\nKlik op "Aafbraeke" es te de ganse gepubliceerde inhaud weg wils haole van %3, en gebroek de (X)-kn\u00f3p op 't Gepublicee [...]
 v3.mb.delPublished.delete=&Weghaole
 v3.mb.delPublished.cancel=&Aafbraeke
-v3.mb.openFile.title=Besjtandj \u00e4\u00f6pene
-v3.mb.openFile.button.play=Aafsjpele
-v3.mb.openFile.button.cancel=Aafbraeke
-v3.mb.openFile.remember=Besjtenj ummer \u00e4\u00f6pene z\u00f3nger te vraoge
 v3.mb.PlayFileNotFound.title=Besjtandj neet gev\u00f3nje
 v3.mb.PlayFileNotFound.text=De besjtenj veur '%1' zeen weggehaold of \u00f3ntbraeke.
 v3.mb.PlayFileNotFound.button.remove=Oet Vuze weghaole
 v3.mb.PlayFileNotFound.button.redownload=Data opnuuj downloade
 v3.mb.PlayFileNotFound.button.find=Handjmaotig zeuke...
-v3.mb.deletePurchased.title=De gekochde inhaud weghaole
-v3.mb.deletePurchased.text=W\u00e8ts te zeker det-s te deze inhaud  '%1' weg wils haole?\n\nDit is inhaud dae se \u00f2f gekoch h\u00f6bs, \u00f2f woveur-s te h\u00f6bs mote inlogge \u00f3m 't te downloade.
-v3.mb.deletePurchased.button.delete=&Weghaole
-v3.mb.deletePurchased.button.cancel=&Aafbraeke
 v3.topbar.menu.show.plugin=Plug-in-gebied
 v3.topbar.menu.show.search=Zeuke
 splash.initializeCore=Kern aan 't laje
@@ -2264,10 +2238,6 @@ v3.splash.hookPluginUI=Plug-in-UI in aan 't h\u00e4\u00f6ke
 OpenTorrentWindow.mb.notTorrent.cannot.display=Kan de data neet fetsoendelik laote zeen
 MainWindow.menu.window.zoom.maximize=Maximalisere
 MainWindow.menu.window.zoom.restore=Hersjt\u00e8lle
-ImageResizer.image.too.small='t Aangegaeve plaetje is te klein, kees estebleef 'n anger ('t m\u00f3t tenminste %1 x %2 zeen)
-ImageResizer.title=Dit sjt\u00f6kske gereidsjap leut de miniatuur zeen wie dae op 't Vuze Platform geplaats weurt
-ImageResizer.move.image=Verplaats 't plaetje door 't te sjleipe
-ImageResizer.move.image.with.slider=Verplaats 't plaetje door 't te sjleipe, veur versjaole gebroek de sjaof hie-\u00f3nger
 security.crypto.title=Encryptiesjleuteltoegank
 security.crypto.encrypt=Gaef 't wachwaord veur 't besjrime van de nuuj gemaakde encryptiesjleutel. Vergaet dit wachwaord neet, 't geuf gein maneer \u00f3m dit tr\u00f6k te haole es det gebeurt!
 security.crypto.decrypt=Gaef 't wachwaord veur 't \u00f3ntgrendel van de encryptiesjleutel.
@@ -2354,9 +2324,6 @@ v3.share.private.text=De geselecteerde torrent is gemarkeerd es 'ne priv\u00e9to
 metasearch.addtemplate.dup.desc=Zeuktemplate %1 is al ge\u00efnstalleerd
 metasearch.export.select.template.file=Template beware
 metasearch.import.select.template.file=Template \u00e4\u00f6pene
-dialog.uiswitch.title=Nao de Vuze-interface \u00f3msjakele
-dialog.uiswitch.text=Doe m\u00f3s de Vuze-interface gebroeke \u00f3m gebroek te kinne make van dees meugelikheid.
-dialog.uiswitch.button=Nao de Vuze-interface \u00f3msjakele
 azbuddy.tracker.enabled=Gaef prioriteit aan vrunj mit 't downloade van dezelfde inhawd
 azbuddy.protocolspeed=KB/s max vrundj protocol overhead
 v3.MainWindow.button.download=Downloade
diff --git a/org/gudy/azureus2/internat/MessagesBundle_lt_LT.properties b/org/gudy/azureus2/internat/MessagesBundle_lt_LT.properties
index 36194ef..cef4129 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_lt_LT.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_lt_LT.properties
@@ -36,13 +36,10 @@ MainWindow.menu.help=&Pagalba
 MainWindow.menu.help.about=Apie Vuze
 MainWindow.menu.torrent=Torrentas
 MainWindow.about.title=Apie
-MainWindow.about.section.developers=K\u016br\u0117jai
-MainWindow.about.section.translators=Vert\u0117jai
 MainWindow.about.section.system=Sistema
 MainWindow.about.section.internet=Internete
 MainWindow.about.internet.homepage=Vuze pagrindinis tinklalapis
 MainWindow.about.internet.sourceforge=Sourceforge projekto tinklalapis
-MainWindow.about.internet.sourceforgedownloads=Sourceforge atsiuntimai
 MainWindow.about.internet.bugreports=Rikt\u0173 raportavimas
 MainWindow.about.internet.forumdiscussion=Forumai
 MainWindow.about.internet.wiki=Vuze Wiki DUK
@@ -308,8 +305,6 @@ IrcView.help=Galimos komandos yra:\n . /help - parodo \u0161i\u0105 \u017einut\u
 PasswordWindow.title=Vuze u\u017erakintas
 PasswordWindow.passwordprotected=Vuze yra apsaugotas slapta\u017eod\u017eiu.\nKad pamatytum\u0117te Vuze lang\u0105, \u012fveskite slapta\u017eod\u012f \u010dia:
 Button.ok=Gerai
-TrackerChangerWindow.title=Prid\u0117ti Tracker\u012f
-TrackerChangerWindow.newtracker=\u012eveskite naujo Trackerio url
 PeersView.discarded=Atmesta
 PeersView.discarded.info=Duomenys, kurie kaip nors buvo gauti, bet nereikalingi, tod\u0117l atmesti.
 discarded=atmesta
@@ -381,7 +376,6 @@ MyTorrentsView.menu.removeand.deletetorrent=I\u0161trinti &Torrent fail\u0105
 MyTorrentsView.menu.removeand.deletedata=I\u0161trinti &duomenis
 MyTorrentsView.menu.removeand.deleteboth=I\u0161trinti &visk\u0105
 deletedata.title=\u012esp\u0117jimas
-deletedata.message1=J\u016bs tuoj i\u0161trinsite DUOMENIS i\u0161:\n
 MainWindow.menu.file.configure=Nustatym\u0173 &vedlys...
 configureWizard.title=Nustatym\u0173 vedlys
 configureWizard.welcome.title=Sveiki \u012fsijung\u0119 Vuze Nustatym\u0173 vedl\u012f
@@ -403,7 +397,6 @@ configureWizard.transfer.maxActiveTorrents=Daugiausia aktyvi\u0173
 configureWizard.transfer.maxDownloads=Daugiausia atsiuntim\u0173
 configureWizard.transfer.maxUploadsPerTorrent=Daugiausia i\u0161siuntim\u0173 Torrentui
 configureWizard.nat.title=NAT / Serverio prievadai
-configureWizard.nat.message=Norint naudotis visais Vuze privalumais rekomenduojama b\u016bti visi\u0161kai prieinamu i\u0161 Interneto. \u0160is \u012frankis leid\u017eia testuoti ir / arba keisti prievad\u0105, naudojam\u0105 \u012feinantiems Siunt\u0117j\u0173 susijungimams.\n\nPASTABA: \u0160is \u012frankis testuoja tik TCP susijungimus. Paskirstytai DB reikia UDP susijungim\u0173, J\u016bs b\u016bsite automati\u0161kai persp\u0117ti, jei bus pasteb\u0117ti ugniasien\u0117s blokavimai [...]
 configureWizard.nat.test=Testuoti
 configureWizard.nat.testing=Testuojamas prievadas
 configureWizard.nat.ok=Gerai!
@@ -566,7 +559,6 @@ ConfigView.section.file.decoder.nodecoder=joks
 IPChecker.external.service.no-ip.description=Dinaminio ir statinio DNS serviso tiek\u0117jas\n(n\u0117ra laisvai prieinamos adreso tikrinimo paslaugos)
 ConfigView.section.tracker.publicenable=\u012ejungti i\u0161orinius Torrentus
 ConfigView.label.playdownloadspeech=Kalb\u0117ti, kai atsiuntimas baigtas
-ConfigView.label.playdownloadspeech.info=Kalbos servisas dabar geriausiai veikia angl\u0173 kalba
 #
 # Tooltips
 #
@@ -740,8 +732,6 @@ ConfigView.section.tracker.main=Pagrindinis
 ConfigView.section.tracker.web=Tinklalapis
 ConfigView.label.prioritizefirstpiece=Suteikti prioritet\u0105 pirmoms ir paskutin\u0117ms fail\u0173 dalims
 ConfigView.label.prioritizefirstpiece.tooltip=Pirmiausia bando parsi\u0173sti pa\u010di\u0105 failo prad\u017ei\u0105 ir pabaig\u0105.\nAnkstyvai per\u017ei\u016brai palaikyti.
-ConfigView.section.file.confirm_data_delete=Patvirtinti duomen\u0173 trynim\u0105
-ConfigView.section.file.confirm_data_delete.tooltip=Patvirtinti duomen\u0173 trynim\u0105, kai naudojama '\u0160alinti ir trinti...'
 TrayWindow.menu.startalldownloads=Prad\u0117ti visus atsiuntimus
 SystemTray.menu.startalltransfers=Prad\u0117ti visus siuntimus
 sharing.progress.title=Dalinimosi progresas
@@ -1059,7 +1049,6 @@ ConfigView.pluginlist.whereToPutOr=Vie\u0161iesiems intarpams naudokite:
 MainWindow.statusText.checking=Ie\u0161koma atnaujinim\u0173
 TableColumn.header.OnlyCDing4=Tik skleid\u017eiama
 TableColumn.header.OnlyCDing4.info=Torrento skleidimo laikas. Neskai\u010diuojamas laikas, kai Torrentas buvo atsiun\u010diamas (ir skleid\u017eiamas).
-ConfigView.section.style.alternateTablePainting=Naudoti kit\u0105 grafini\u0173 lentel\u0117s stulpeli\u0173 pie\u0161imo metod\u0105 (gali reik\u0117ti perkrauti)
 UpdateWindow.status.restartMaybeNeeded=Gali reik\u0117ti perkrauti
 ConfigView.pluginlist.shared=vie\u0161asis
 PeersView.host=Kompiuterio vardas
@@ -1296,18 +1285,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Jungties SO_RCVBUF dydis [0: na
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Nustato standartin\u0119 jungties SO_RCVBUF reik\u0161m\u0119 (baitais), tai yra TCP pri\u0117mino lango dyd\u012f ir mast\u0105.\nVuze pagal numatym\u0105 jos nenustato, tai rei\u0161kia, kad yra panaudojami OS numatymai.\nPASTABA: Linux dvigubina duot\u0105 reik\u0161m\u0119.
 ConfigView.section.connection.advanced.SO_SNDBUF=Jungties SO_SNDBUF dydis [0: naudoti OS numatyt\u0105]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Nustato standartin\u0119 jungties SO_SNDBUF reik\u0161m\u0119 (baitais), tai yra TCP siuntimo lango dyd\u012f.\nVuze pagal numatym\u0105 jos nenustato, tai rei\u0161kia, kad yra panaudojami OS numatymai.\nPASTABA: Linux dvigubina duot\u0105 reik\u0161m\u0119.
-ConfigView.section.interface.confirm_torrent_removal=Rodyti patvirtinimo dialog\u0105 \u0161alinant Torrent\u0105
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Patvirtinti, kai \u0161alinamas Torrentas i\u0161 Mano Torrent\u0173 lango.
-MyTorrentsView.confirm_torrent_removal=Ar tikrai norite \u0161alinti?\n
 TableColumn.header.seed_to_peer_ratio=Skleid\u0117jai:Siunt\u0117jai
 TableColumn.header.seed_to_peer_ratio.info=Visos grup\u0117s Skleid\u0117j\u0173:Siunt\u0117j\u0173 santykis
 PeersView.connected_time=Susijungta laiko
 PeersView.connected_time.info=Visas susijungimo su Siunt\u0117ju laikas
-ConfigView.section.interface.display.add_torrents_silently=Prid\u0117ti Torrentus tyliai
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Prid\u0117ti Torrent\u0173 atsiuntimus neaktyvuojant pagrindinio Vuze lango.
 TableColumn.header.maxdownspeed=Did\u017e. ats. greitis
 TableColumn.header.maxdownspeed.info=Did\u017eiausias atsiuntimo greitis Torrentui
-PeersGraphicView.title=Grup\u0117
+PeersGraphicView.title.full=Grup\u0117
 ConfigView.section.tracker.passwordwebhttpsonly=Leisti prisijungti tik per HTTPS
 TableColumn.header.torrentpath=Torrento vieta
 TableColumn.header.torrentpath.info=Torrento buvimo vieta diske
@@ -1363,8 +1347,6 @@ UpdateWindow.restartLater=Perkrauti v\u0117liau
 MainWindow.menu.file.restart=Perkrauti Vuze
 MainWindow.dialog.restartconfirmation.title=Perkrauti Vuze
 MainWindow.dialog.restartconfirmation.text=Ar tikrai norite perkrauti Vuze
-deletetorrent.message1=J\u016bs norite i\u0161trinti TORRENT\u0104 susiet\u0105 su:\n
-deletetorrent.message2=\nAr tikrai norite t\u0119sti?
 ConfigView.label.prioritizemostcompletedfiles=Dar labiau didinti auk\u0161to prioriteto fail\u0173 prioritet\u0105 atsi\u017evelgiant \u012f u\u017ebaigtum\u0105 ir failo dyd\u012f
 splash.plugin.init=Ruo\u0161iamas intarpas
 ConfigView.section.style.osx_small_fonts=Naudoti smulkius \u0161riftus [reikia perkrauti]
@@ -1526,7 +1508,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent fail\u0105... (tik sekimui)
 MyTrackerView.date_added=Prid\u0117ta
 ConfigView.section.tracker.portbackup=Atsarginiai prievadai (atskirti ';')
 ConfigView.label.playfilespeech=Kalb\u0117ti, kai failas baigtas
-ConfigView.label.playfilespeech.info=Kalbos servisas dabar geriausiai veikia angl\u0173 kalba
 ConfigView.label.playfilefinished=Sugroti gars\u0105, kai failas baigtas
 ConfigView.label.backupconfigfiles=I\u0161saugoti nustatym\u0173 failus atstatymo tikslais
 ConfigView.section.tracker.client.scrapesingleonly=I\u0161jungti s\u0105rankos apjungim\u0105 Trackeriui (gali pad\u0117ti su Trackeriais, kurie gr\u0105\u017eina klaidas 'URL per ilgas' (414))
@@ -2084,10 +2065,6 @@ v3.mb.delPublished.delete=&Trinti
 v3.mb.delPublished.cancel=&Atsisakyti
 v3.mb.PlayFileNotFound.title=Failas nerastas
 v3.mb.PlayFileNotFound.button.remove=\u0160alinti i\u0161 Vuze
-v3.mb.deletePurchased.title=\u0160alinti nupirkt\u0105 turin\u012f
-v3.mb.deletePurchased.text=Ar tikrai norite trinti \u0161\u012f turin\u012f '%1'?\n\n\u0160\u012f turin\u012f J\u016bs arba nupirkote, arba Jums reik\u0117jo prisijungti, norint j\u012f atsisi\u0173sti.
-v3.mb.deletePurchased.button.delete=&Trinti
-v3.mb.deletePurchased.button.cancel=&Atsisakyti
 #
 splash.loadIpFilters=\u012ekeliami IP filtrai..
 SpeedTestWizard.set.upload.title=Nustatyti i\u0161siuntimo ir atsiuntimo limitus
diff --git a/org/gudy/azureus2/internat/MessagesBundle_mk_MK.properties b/org/gudy/azureus2/internat/MessagesBundle_mk_MK.properties
index b40cb42..a7f16a6 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_mk_MK.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_mk_MK.properties
@@ -22,12 +22,9 @@ MainWindow.menu.window.alltofront=\u041f\u043e\u0432\u043b\u0435\u0447\u0438 \u0
 MainWindow.menu.help=\u041f\u043e\u043c\u043e\u0448
 MainWindow.menu.help.about=\u0417\u0430 \u0410\u0437\u0443\u0440\u0435\u0443\u0441
 MainWindow.about.title=\u0417\u0430
-MainWindow.about.section.developers=\u0420\u0430\u0437\u0432\u0438\u0432\u0430\u0447\u0438
-MainWindow.about.section.translators=\u041f\u0440\u0435\u0432\u0435\u0434\u0443\u0432\u0430\u0447\u0438
 MainWindow.about.section.internet=\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442
 MainWindow.about.internet.homepage=\u0414\u043e\u043c\u0430\u0448\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0430 \u043d\u0430 \u0410\u0437\u0443\u0440\u0435\u0443\u0441
 MainWindow.about.internet.sourceforge=\u0421\u0442\u0440\u0430\u043d\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0442 \u043d\u0430 Sourceforge
-MainWindow.about.internet.sourceforgedownloads=\u041f\u0440\u0435\u0437\u0435\u043c\u0430\u045a\u0430 \u043e\u0434 Sourceforge
 MainWindow.about.internet.forumdiscussion=\u0424\u043e\u0440\u0443\u043c\u0438
 MainWindow.status.latestversion=\u041d\u0430\u0458\u043d\u043e\u0432\u0430
 MainWindow.status.latestversion.clickupdate=\u041a\u043b\u0438\u043a\u043d\u0438 \u0437\u0430 \u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0430
@@ -128,7 +125,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u0438\u0437\u0431\u0440\u0438\u0448
 MyTorrentsView.menu.removeand.deletedata=\u0438\u0437\u0431\u0440\u0438\u0448\u0438 \u0433\u0438 \u043f\u043e\u0434\u0430\u0442\u043e\u0446\u0438\u0442\u0435
 MyTorrentsView.menu.removeand.deleteboth=\u0438\u0437\u0431\u0440\u0438\u0448\u0438 \u0441\u0450
 deletedata.title=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0434\u0443\u0432\u0430\u045a\u0435
-deletedata.message1=\u040c\u0435 \u0433\u0438 \u0438\u0437\u0431\u0440\u0438\u0448\u0435\u0442\u0435 \u043f\u043e\u0434\u0430\u0442\u043e\u0446\u0438\u0442\u0435 \u0437\u0430 :\n
 configureWizard.title=\u0412\u043e\u043b\u0448\u0435\u0431\u043d\u0438\u043a \u0437\u0430 \u043f\u043e\u0434\u0435\u0441\u0443\u0432\u0430\u045a\u0430
 configureWizard.transfer.hint=\u0421\u043e\u0432\u0435\u0442: \u041d\u0430\u043c\u0435\u0441\u0442\u0435\u0442\u0435 \u043d\u0435\u0448\u0442\u043e \u043f\u043e\u043c\u0430\u043b\u043a\u0443 \u043e\u0434 \u043d\u0430\u0458\u0433\u043e\u043b\u0435\u043c\u0430\u0442\u0430 \u0432\u0440\u0435\u0434\u043d\u043e\u0441\u0442
 configureWizard.transfer.connection=\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0432\u0440\u0441\u043a\u0430
@@ -138,7 +134,6 @@ configureWizard.transfer.maxUpSpeed=\u041d\u0430\u0458\u0432\u0438\u0441\u043e\u
 configureWizard.transfer.maxActiveTorrents=\u041d\u0430\u0458\u043c\u043d\u043e\u0433\u0443 \u0430\u043a\u0442\u0438\u0432\u043d\u0438
 configureWizard.transfer.maxDownloads=\u041d\u0430\u0458\u043c\u043d\u043e\u0433\u0443 \u043f\u0440\u0435\u0437\u0435\u043c\u0430\u045a\u0430
 configureWizard.transfer.maxUploadsPerTorrent=\u041d\u0430\u0458\u043c\u043d\u043e\u0433\u0443 \u0438\u0441\u043f\u0440\u0430\u045c\u0430\u045a\u0430 \u043f\u043e \u0442\u043e\u0440\u0435\u043d\u0442
-configureWizard.nat.message=\u041f\u0440\u0435\u043f\u043e\u0440\u0430\u0447\u043b\u0438\u0432\u043e \u0435 \u0431\u0430\u0440\u0435\u043c \u0435\u0434\u043d\u0430 \u043f\u043e\u0440\u0442\u0430 \u0434\u0430 \u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u043f\u043b\u0438\u0432\u0430 \u043e\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0437\u0430 \u043d\u0430\u0458\u0434\u043e\u0431\u0440\u043e \u0438\u0441\u043a\u0443\u0441\u0442\u0432\u043e \u0441\u043e \u0411\u0438\u0442\u0422 [...]
 configureWizard.nat.test=\u0422\u0435\u0441\u0442\u0438\u0440\u0430\u0458
 configureWizard.nat.testing=\u0422\u0435\u0441\u0442\u0438\u0440\u0430\u043c \u0437\u0430 \u043f\u043e\u0440\u0442\u0430\u0442\u0430 
 configureWizard.nat.ok=\u0412\u043e \u0440\u0435\u0434 \u0435!
@@ -313,15 +308,12 @@ FilesView.path=\u041f\u0430\u0442
 FilesView.fullpath=\u041f\u043e\u043a\u0430\u0436\u0438 \u0433\u043e \u0446\u0435\u043b\u0438\u043e\u0442 \u043f\u0430\u0442
 FilesView.remaining=\u041f\u0440\u0435\u043e\u0441\u0442\u0430\u043d\u0430\u0442\u0438 \u043f\u0430\u0440\u0447\u0438\u045a\u0430
 TableColumn.header.trackername=\u0418\u043c\u0435 \u043d\u0430 \u0442\u0440\u0430\u043a\u0435\u0440\u043e\u0442
-MyTorrentsView.confirm_torrent_removal=\u0421\u0438\u0433\u0443\u0440\u043d\u043e \u043b\u0438 \u0441\u043a\u0430\u0442\u0430 \u0434\u0430 \u0433\u043e \u0442\u0440\u0433\u043d\u0435\u0442\u0435?\n
 TableColumn.header.maxdownspeed=\u041d\u0430\u0458\u0433\u043e\u043b\u0435\u043c\u0430 \u0431\u0440\u0437\u0438\u043d\u0430 \u043d\u0430\u0434\u043e\u043b\u0443
 TableColumn.header.maxdownspeed.info=\u041d\u0430\u0458\u0433\u043e\u043b\u0435\u043c\u0430 \u0431\u0440\u0437\u0438\u043d\u0430 \u043d\u0430\u0434\u043e\u043b\u0443 \u043f\u043e \u0442\u043e\u0440\u0435\u043d\u0442
 TableColumn.header.torrentpath=\u041c\u0435\u0441\u0442\u043e \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u0442
 TableColumn.header.torrentpath.info=\u041c\u0435\u0441\u0442\u043e \u043d\u0430 \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u0442 \u043d\u0430 \u0434\u0438\u0441\u043a
 Button.abort=\u041e\u0442\u043a\u0430\u0436\u0438
 MainWindow.menu.file.restart=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0458 \u0433\u043e \u0410\u0437\u0443\u0440\u0435\u0443\u0441
-deletetorrent.message1=\u040c\u0435 \u0433\u043e \u0438\u0437\u0431\u0440\u0438\u0448\u0435\u0442\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u043e\u0442 \u0437\u0430 :\n
-deletetorrent.message2=\n\u0414\u0430\u043b\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043d\u0438?
 ConfigView.label.prioritizemostcompletedfiles=Prioritize most completed files
 splash.plugin.init=\u0413\u043e \u0438\u043d\u0438\u0446\u0438\u0458\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0442 
 MyTorrentsView.menu.explore=\u041f\u043e\u043a\u0430\u0436\u0438 \u0458\u0430 \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0430\u0442\u0430
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ms_SG.properties b/org/gudy/azureus2/internat/MessagesBundle_ms_SG.properties
index e43243a..65ae814 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ms_SG.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ms_SG.properties
@@ -21,11 +21,8 @@ MainWindow.menu.language=&Bahasa
 MainWindow.menu.help=&Pertolongan
 MainWindow.menu.help.about=&Tentang Vuze
 MainWindow.about.title=Tentang
-MainWindow.about.section.developers=Pengarang
-MainWindow.about.section.translators=Penterjemah
 MainWindow.about.internet.homepage=Lelaman Vuze
 MainWindow.about.internet.sourceforge=Lelaman Projek Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Muat turunan Sourceforge
 MainWindow.about.internet.bugreports=Report Masalah
 MainWindow.about.internet.forumdiscussion=Forum Umum
 MainWindow.dialog.choose.savepath=Pilih tempat simpan
@@ -222,8 +219,6 @@ IrcClient.noNick=Tiada Nama Timangan Ditetapkan. Sila ke pandangan 'Konfigurasi'
 IrcView.help=Valid commands are :\n . /help : displays this message\n . /nick | /name : changes your name \n . /me action : sends an action \n . /msg nick message : sends a private message to <nick>\n . /r message : reply to last private message\n . /join #channel : changes current channel
 PasswordWindow.title=Vuze telah dikunci
 PasswordWindow.passwordprotected=Vuze telah dikunci.\nUntuk menggunakannya, sila taip passwordnya disini :
-TrackerChangerWindow.title=Tambah Pengesan
-TrackerChangerWindow.newtracker=Masukkan url pengesan baru
 PeersView.discarded=Dibuang
 PeersView.discarded.info=Data yang anda terima walaupun tidak diperlukan, lalu dibuang.
 discarded=dibuang
@@ -284,10 +279,8 @@ MyTorrentsView.menu.removeand.deletetorrent=Padam .&torrent
 MyTorrentsView.menu.removeand.deletedata=Padam &Data
 MyTorrentsView.menu.removeand.deleteboth=Padam Kedua-duanya
 deletedata.title=!!! Awas !!!
-deletedata.message1=Kamu akan memadam DATA dari :\n
 MainWindow.menu.file.configure=Configuration &Wizard
 configureWizard.welcome.message=This wizard will help you configure Vuze for most common use. You can modify in depth the configuration using the View>Configuration menu.
-configureWizard.nat.message=In order to get the best out of BitTorrent, it's highly recommended to be fully accessible from the internet. Default bittorrent port is 6881. This tool lets you test and / or change the port.
 configureWizard.nat.unable=Unable to test
 configureWizard.file.title=Torrent / Fail
 configureWizard.file.message1=Vuze akan menyimpan Torrent terbuka di satu direktori, kamu boleh memilih direktori tersebut di sini:
diff --git a/org/gudy/azureus2/internat/MessagesBundle_nl_NL.properties b/org/gudy/azureus2/internat/MessagesBundle_nl_NL.properties
index e82d118..a8a9fbb 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_nl_NL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_nl_NL.properties
@@ -33,12 +33,9 @@ MainWindow.menu.help=&Help
 MainWindow.menu.help.about=Over Vuze
 MainWindow.menu.torrent=Torrent Besturing
 MainWindow.about.title=Over Vuze
-MainWindow.about.section.developers=Ontwikkelaars 
-MainWindow.about.section.translators=Vertalers 
 MainWindow.about.section.system=Systeem
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.sourceforge=Sourceforge Projectpagina
-MainWindow.about.internet.sourceforgedownloads=Sourceforge Downloads.
 MainWindow.about.internet.bugreports=Fout rapportages 
 MainWindow.about.internet.forumdiscussion=Forums.
 MainWindow.about.internet.wiki=Vuze Wiki FAQ.
@@ -304,8 +301,6 @@ IrcView.help=Geldige commando's zijn :\n . /help : geeft dit bericht weer\n . /N
 PasswordWindow.title=Vuze is vergrendeld
 PasswordWindow.passwordprotected=Vuze is beschermd met een wachtwoord.\nVul hier je wachtwoord in, om het venster te tonen :
 Button.ok=&Ok
-TrackerChangerWindow.title=Voeg Tracker toe
-TrackerChangerWindow.newtracker=Vul een nieuw tracker adres in
 PeersView.discarded=Verworpen 
 PeersView.discarded.info=Data die je wel hebt ontvangen, maar niet nodig hebt, dus je hebt het verwijderd.
 discarded=verworpen
@@ -375,7 +370,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Verwijder &Torrent bestand
 MyTorrentsView.menu.removeand.deletedata=Verwijder &Data
 MyTorrentsView.menu.removeand.deleteboth=Verwijder &Beide
 deletedata.title=!!! Waarschuwing !!!
-deletedata.message1=Je staat op het punt de DATA te verwijderen van :
 MainWindow.menu.file.configure=Configuratie &Wizard...
 configureWizard.title=Configuratie wizard 
 configureWizard.welcome.title=Welkom bij de Vuze Configuratie wizard
@@ -396,7 +390,6 @@ configureWizard.transfer.maxActiveTorrents=Max Actief
 configureWizard.transfer.maxDownloads=Max. Downloads
 configureWizard.transfer.maxUploadsPerTorrent=Max. Uploads per Torrent
 configureWizard.nat.title=NAT / Server Poort
-configureWizard.nat.message=Om het beste uit Bittorrent te behalen is het raadzaam om goed bereikbaar te zijn vanaf het internet. De standaard poort is 6881. Dit programma helpt met het testen / veranderen van de poort.
 configureWizard.nat.testing=Testen van poort 
 configureWizard.nat.ok=NAT OK !
 configureWizard.nat.ko=NAT-Fout 
@@ -553,7 +546,6 @@ ConfigView.section.file.decoder.nodecoder=Geen
 IPChecker.external.service.no-ip.description=Dynamic en Static DNS service provider\n(niet vrij beschikbaar 'check adres' service)
 ConfigView.section.tracker.publicenable=Externe torrents toestaan 
 ConfigView.label.playdownloadspeech=Spreek wanneer een download voltooid is
-ConfigView.label.playdownloadspeech.info=De Spraak Service werkt het beste met Engels
 #
 # Tooltips
 #
@@ -725,8 +717,6 @@ ConfigView.section.tracker.main=Hoofd
 ConfigView.section.tracker.web=Web 
 ConfigView.label.prioritizefirstpiece=Geef het eerste deel van bestand(en) voorrang
 ConfigView.label.prioritizefirstpiece.tooltip=Probeert het eerste deel van een bestand eerst te downloaden.\nOm previews te ondersteunen.
-ConfigView.section.file.confirm_data_delete=Bevestig het verwijderen van data
-ConfigView.section.file.confirm_data_delete.tooltip=Bevestig het verwijderen van data bij het gebruik van 'Verplaats en Verwijder...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Bij verwijderen van data, torrents die gelinkt zijn in een opslag directorie ook verwijderen.
 TrayWindow.menu.startalldownloads=Start Alle Downloads
 SystemTray.menu.startalltransfers=Start Alle Overdrachten
@@ -1034,7 +1024,6 @@ ConfigView.pluginlist.whereToPutOr=Gebruik voor gedeelde plugins:
 MainWindow.statusText.checking=Controleren op Updates
 TableColumn.header.OnlyCDing4=Alleen Uploaden
 TableColumn.header.OnlyCDing4.info=Hoeveelheid tijd waarin de torrent alleen aan het uploaden was.\nExclusief de tijd dat de torrent aan het downloaden was (en uploaden).
-ConfigView.section.style.alternateTablePainting=Gebruik alternatieve methode om grafische tabel kolommen te tekenen (kan herstart nodig hebben)
 UpdateWindow.status.restartMaybeNeeded=Herstart kan nodig zijn
 ConfigView.pluginlist.shared=gedeelt
 PeersView.host=Host Naam
@@ -1268,18 +1257,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF grootte [0: ge
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Stel de standaard socket SO_SNDBUF waarde (in bytes) in, zoals TCP zend venster grootte.\nVuze laat dit  standaard oningesteld, dit betekend dat de standaard OS instellingen worden gebruikt.\nOpmerking: Linux verdubbeld de gegeven waarde.
 ConfigView.section.connection.advanced.IPDiffServ=Uitgaande packet DiffServ waarde (TOS field)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Zet de DiffServ deel van het type-of-service (TOS) veldt in de IP header voor uitgaande packets.\nHexadecimal waardes kunnen gespecificeerd worden door deze te prefixing met '0x', e.g. 0x10.\nVuze laat dit standaard ongebruikt, dit betekent dat de standaard ven de underlying OS word gebruikt.\nNOTE: Underlying network implementaties kunnen deze waardes negeeren, zo is deze optie afhankelijk van de  OS en JRE versie.
-ConfigView.section.interface.confirm_torrent_removal=Laat bevestigingsvenster zien bij het verwijderen van een torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Bevestig wanneer er een torrent uit Mijn Torrents wordt verwijderd.
-MyTorrentsView.confirm_torrent_removal=Weet je zeker dat je wil verwijderen?\n
 TableColumn.header.seed_to_peer_ratio=Seed2PeerVerhouding
 TableColumn.header.seed_to_peer_ratio.info=Totalen zwerm seeders naar leechers verhouding
 PeersView.connected_time=Verbonden Tijd
 PeersView.connected_time.info=Totalen tijd verbonden met de peer
-ConfigView.section.interface.display.add_torrents_silently=Voeg torrents stil toe
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Voeg torrent downloads toe, zonder het hoofd venster te activeren.
 TableColumn.header.maxdownspeed=Max Down Snelheid
 TableColumn.header.maxdownspeed.info=Max Download Snelheid per torrent
-PeersGraphicView.title=Zwerm
+PeersGraphicView.title.full=Zwerm
 ConfigView.section.tracker.passwordwebhttpsonly=Sta toegang alleen toe via HTTPS
 TableColumn.header.torrentpath=Torrent Locatie
 TableColumn.header.torrentpath.info=Locatie van de Torrent op de schijf
@@ -1336,8 +1320,6 @@ UpdateWindow.restartLater=Herstart Later
 MainWindow.menu.file.restart=Herstart Vuze
 MainWindow.dialog.restartconfirmation.title=Vuze opnieuw opstarten?
 MainWindow.dialog.restartconfirmation.text=Weet je zeker dat je Vuze opnieuw wil opstarten?
-deletetorrent.message1=U staat op het punt de TORRENT te verwijderen voor :\n
-deletetorrent.message2=\nWeet u zeker dat u verder wil gaan?
 ConfigView.label.prioritizemostcompletedfiles=Geef voorrang met hoge prioriteit aan bestanden volgens % compleet en de grootte van de file 
 splash.plugin.init=Initialiseren Plugin:
 splash.plugin.UIinit=Initialiceren Plugin GUI: %1  
@@ -1496,7 +1478,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent Bestand... (Alleen Tracking
 MyTrackerView.date_added=Toegevoegd
 ConfigView.section.tracker.portbackup="Backup poorten ( gescheiden door ; )"
 ConfigView.label.playfilespeech=Spreek als een file gereed is
-ConfigView.label.playfilespeech.info=Spraak Service werkt momenteel het beste met Engels
 ConfigView.label.playfilefinished=Speel een geluid/muziekje als een stukje van de file gereed is
 ConfigView.label.backupconfigfiles=Backup configuratie files voor herstel opties
 ConfigView.section.tracker.client.scrapesingleonly=Uitzetten per-tracker scrape aggregation (kan helpen bij trackers die rapporteren dat de  'URL te lang is ' (414) errors) 
@@ -2074,10 +2055,6 @@ v3.mb.PlayFileNotFound.text=De files voor '%1' zijn verwijder of vermist.
 v3.mb.PlayFileNotFound.button.remove=Verwijder uit Vuze
 v3.mb.PlayFileNotFound.button.redownload=Herdownload de data.
 v3.mb.PlayFileNotFound.button.find=Handmatig zoeken
-v3.mb.deletePurchased.title=Verwijder de verkregen inhoud
-v3.mb.deletePurchased.text=Ben je zeker dat je deze inhoud  '%1'  wilt verwijderen?\n\nDeze heb je nog niet verkregen, je moet misschien inloggen om te kunnen downloaden.
-v3.mb.deletePurchased.button.delete=&Verwijder
-v3.mb.deletePurchased.button.cancel=&Annuleer
 v3.topbar.menu.show.plugin=Plugin Gebied
 v3.topbar.menu.show.search=Zoek
 splash.initializeCore=Initialiseren Core
@@ -2208,7 +2185,7 @@ Progress.reporting.status.retrying=Opnieuw proberen...
 Progress.reporting.action.label.retry.tooltip=Bewerking opnieuw proberen.
 Progress.reporting.action.label.remove.tooltip=Verwijder dit Voortgangs Raport van de historie.
 Progress.reporting.action.label.cancel.tooltip=Annuleer de bewerking.
-Progress.reporting.default.error=Gevaald
+Progress.reporting.default.error=Gefaald
 Progress.reporting.no.reports.to.display=Er zijn geen Voortgangs Raportages om te laten zien op het moment.
 Progress.reporting.no.history.to.display=Er zijn geen detail berichten om te laten zien.
 Progress.reporting.detail.history.limit=Het detail bericht limit (%1) voor de Voortgangs Raporteerder is overschreden; volgende detail berichten zullen niet in de historie lijst geplaatst worden.
@@ -2259,10 +2236,6 @@ v3.splash.hookPluginUI=Inhaken op de Plugin UI
 OpenTorrentWindow.mb.notTorrent.cannot.display=Onmogelijk om de date te tonen.
 MainWindow.menu.window.zoom.maximize=Maximaliseer
 MainWindow.menu.window.zoom.restore=Herstellen
-ImageResizer.image.too.small=De aangegeven image is teklein, a.u.b. kies een anderen (het minimalen formaat moet zijn %1 x %2
-ImageResizer.title=Dit stukje gereedschap laat de thumbnail zien zoals deze op het Vuze Platform geplaats worden.
-ImageResizer.move.image=Verplaats de image door deze te slepen
-ImageResizer.move.image.with.slider=Verplaats de image door deze te slepen, voor verschalen gebruik de schuifregelaar hier onder
 security.crypto.title=Encryptie Key Toegang
 security.crypto.encrypt=Plaats het wachtwoord voor het beschermen van de nieuw gemaakte encryption key. Vergeet dit wachtwoord niet, er is geen mannier om dit terug te halen wanneer dit wel gebeurt!
 security.crypto.decrypt=Geef het wachtwoord voor het unlocken van de encryption key.
@@ -2342,9 +2315,6 @@ v3.share.private.title=Delen Torrent
 v3.share.private.text=De geselecteerde torrent is gemarkeerd als een prive torrent.\n\nJe kunt geen prive torrents delen.
 metasearch.addtemplate.dup.desc=Zoek template %1 is al geinstalleerd
 metasearch.export.select.template.file=Opslaan Template
-dialog.uiswitch.title=Schakel naar de Vuze UI
-dialog.uiswitch.text=Je moet de Vuze UI gebruiker om gebruik te kunnen maken van deze mogelijkheid.
-dialog.uiswitch.button=Schakel naar de Vuze UI
 azbuddy.tracker.enabled=Geef prioriteit aan vrienden met het downloaden van de zelfde inhoud
 azbuddy.protocolspeed=KB/s max vriend protocol overhead
 v3.MainWindow.button.run=Start gedownloaden file
diff --git a/org/gudy/azureus2/internat/MessagesBundle_no_NO.properties b/org/gudy/azureus2/internat/MessagesBundle_no_NO.properties
index 26ac5f7..35ac7d8 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_no_NO.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_no_NO.properties
@@ -50,13 +50,10 @@ MainWindow.menu.help=&Hjelp
 MainWindow.menu.help.about=&Om Vuze
 #MainWindow.menu.torrent=T&orrent
 MainWindow.about.title=Om
-MainWindow.about.section.developers=Utviklere
-MainWindow.about.section.translators=Oversettere
 MainWindow.about.section.system=Ditt system
 MainWindow.about.section.internet=Internett
 MainWindow.about.internet.homepage=Hjemmeside for Vuze
 MainWindow.about.internet.sourceforge=SourceForge-prosjektside
-MainWindow.about.internet.sourceforgedownloads=SourceForge-nedlasting
 MainWindow.about.internet.bugreports=Feilrapporter
 MainWindow.about.internet.forumdiscussion=Generelt fora
 MainWindow.dialog.choose.savepath=Velg sti for lagring
@@ -316,8 +313,6 @@ IrcView.help=Gyldige kommandoer er:\n . /help : viser denne meldingen\n . /nick
 PasswordWindow.title=Vuze er l�st
 PasswordWindow.passwordprotected=Vuze er l�st med passord.\nSkriv inn passordet her for � gjen�pne hovedvinduet:
 Button.ok=&OK
-TrackerChangerWindow.title=Skift Tracker
-TrackerChangerWindow.newtracker=Skriv ny Tracker-URL
 PeersView.discarded=Forkastet
 PeersView.discarded.info=Overfl�dig mottatt data ble fjernet.
 discarded=forkastet
@@ -387,7 +382,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Slett .torrent
 MyTorrentsView.menu.removeand.deletedata=Slett data
 MyTorrentsView.menu.removeand.deleteboth=Slett begge
 deletedata.title=!!! Advarsel !!!
-deletedata.message1=Du skal til � slette DATAENE fra:
 deletedata.message2=\nVil du virkelig dette?
 MainWindow.menu.file.configure=Konfigurasjonsveiviser
 configureWizard.title=Konfigurasjonsveiviser
@@ -410,7 +404,6 @@ configureWizard.transfer.maxActiveTorrents=Maks aktive torrenter
 configureWizard.transfer.maxDownloads=Maks nedlastinger
 configureWizard.transfer.maxUploadsPerTorrent=Maks # opplastinger per torrent
 configureWizard.nat.title=NAT / tjener-porter
-configureWizard.nat.message=For � f� det beste ut av BitTorrent, er det sterkt anbefalt � v�re fullt tilgengelig p� Internett. Standard BitTorrent-port er 6881. Med dette verkt�yet kan du teste og/eller forandre portnummer. OBS: Port 6880 er reservert til internt bruk, og kan derfor ikke benyttes.
 configureWizard.nat.testing=Tester port
 configureWizard.nat.ok=OK!
 configureWizard.nat.ko=NAT-feil
@@ -570,7 +563,6 @@ ConfigView.section.file.decoder.nodecoder=Ingen
 IPChecker.external.service.no-ip.description=Dynamisk og statisk DNS-tjenestetilbyder\n(ikke gratis IP-sjekk-tjeneste)
 ConfigView.section.tracker.publicenable=Aktiver eksterne torrenter
 ConfigView.label.playdownloadspeech=Talelyd n�r en nedlasting ferdigstilles
-ConfigView.label.playdownloadspeech.info="Speech Services" virker for tiden best for engelsk
 GeneralView.label.status.pieces_available.tooltip=Viser for �yeblikket antall tilgjengelige kopier av hvert bruddstykke. \nEr verdien til h�yre mindre enn 1, finnes det ingen n�v�rende komplett kopi av torrenten. (Dette vanskeliggj�r nedlastingen).
 GeneralView.label.trackerurl.tooltip=Klikk for � kopiere annonserings-URL til utklippstavle
 GeneralView.label.trackerurlopen.tooltip=Klikk for � �pne trackerens hovedside
@@ -733,8 +725,6 @@ ConfigView.section.tracker.main=Hoved
 ConfigView.section.tracker.web=Vev
 ConfigView.label.prioritizefirstpiece=Prioriter f�rste delen av filer.
 ConfigView.label.prioritizefirstpiece.tooltip=Fors�ker � laste ned begynnelsen av filene f�rst.
-ConfigView.section.file.confirm_data_delete=Bekreft sletting av data
-ConfigView.section.file.confirm_data_delete.tooltip=Bekreft sletting av data ved 'Fjern og slett...'
 TrayWindow.menu.startalldownloads=Start alle nedlastinger
 SystemTray.menu.startalltransfers=Start alle overf�ringer
 sharing.progress.title=Delings-prosess
@@ -1034,7 +1024,6 @@ ConfigView.pluginlist.whereToPut=Plasser alle brukerspesifike programtillegg i e
 ConfigView.pluginlist.whereToPutOr=For felles programtillegg, bruk:
 MainWindow.statusText.checking=S�ker etter oppdateringer
 TableColumn.header.OnlyCDing4.info=Forg�tt tid siden torrenten ble komplett. Utelater tiden torrenten var under nedlasting (seeding).
-ConfigView.section.style.alternateTablePainting=Bruk alternativ metode for opptegning av tabellkolonner. (krever muligens omstart)
 UpdateWindow.status.restartMaybeNeeded=Omstart kan trenges
 ConfigView.pluginlist.shared=delt
 PeersView.host=Vertsnavn
@@ -1261,17 +1250,12 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF st
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Angir standard SO_SNDBUF socket verdi (i byte), dvs. TCP vindust�rrelse og vekt (sending).\nStandardinnstillinger i Vuze setter denne tom, noe som vil si at underliggende standardverdier i OS benyttes.\nNB: Linux dobbler angitt verdi.
 ConfigView.section.connection.advanced.IPTOS=Utg�ende pakke 'type-of-service' (TOS)
 ConfigView.section.connection.advanced.IPTOS.tooltip=Angir type trafikk / "type-of-service" (TOS) felt i IP header for utg�ende pakker.\nStandardinnstillinger i Vuze setter denne tom, noe som vil si at underliggende standardverdier i OS benyttes.\nEksempelverdier:\n0x02 for IPTOS_LOWCOST\n0x04 for IPTOS_RELIABILITY\n0x08 for IPTOS_THROUGHPUT\n0x10 for IPTOS_LOWDELAY\nNB: Unerliggende netverksimplementasjoner kan ignorere disse verdiene, s� dette valget er avhengig av OS og JRE versjon.
-ConfigView.section.interface.confirm_torrent_removal=Vis bekreftelsesdialog ved fjerning av torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Forlanger bekreftelse ved fjerning av en torrent ifra visning i 'Mine torrenter'.
-MyTorrentsView.confirm_torrent_removal=Vil du virkelig fjerne torrenten?
 TableColumn.header.seed_to_peer_ratio.info=Forhold mellom komplette kilder og ufullstendige kilder i sverm
 PeersView.connected_time=Tilkoblingstid
 PeersView.connected_time.info=Total tid tilkoblet kilde
-ConfigView.section.interface.display.add_torrents_silently=Legg til torrenter automatisk (uten brukerinteraksjon)
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Legger til nye nedlastinger uten aktivering av hovedvinduet til Azureus.
 TableColumn.header.maxdownspeed=Maks nedlastingshastighet
 TableColumn.header.maxdownspeed.info=Maks nedlastingshastighet per torrent
-PeersGraphicView.title=Sverm
+PeersGraphicView.title.full=Sverm
 ConfigView.section.tracker.passwordwebhttpsonly=Tillat tilgang kun via HTTPS
 TableColumn.header.torrentpath=Torrent-sti
 TableColumn.header.torrentpath.info=Lokal lagringssti til torrent
@@ -1328,8 +1312,6 @@ UpdateWindow.restartLater=Omstart av Vuze senere
 MainWindow.menu.file.restart=Omstart
 MainWindow.dialog.restartconfirmation.title=Starte om Vuze
 MainWindow.dialog.restartconfirmation.text=Vil du virkelig starte om Vuze
-deletetorrent.message1=Torrenten blir slettet:
-deletetorrent.message2=\n\u00d8nsker de � fortsette?
 ConfigView.label.prioritizemostcompletedfiles=Prioriter ytterlige h�y-prioritets filer i forhold til % ferdigstillelse og filst�rrelse
 splash.plugin.init=Initialiserer programtillegg:
 ConfigView.section.style.osx_small_fonts=Bruk sm� fonter [krever omstart]
@@ -1483,7 +1465,6 @@ MainWindow.menu.file.open.torrentfortracking=.torrent fil (kun tracking)
 MyTrackerView.date_added=Lagt til
 ConfigView.section.tracker.portbackup=Reserveporter (adskilt med ';')
 ConfigView.label.playfilespeech=Talelyd idet en fil ferdigstilles
-ConfigView.label.playfilespeech.info="Speec Services" st�ttes best for engelsk
 ConfigView.label.playfilefinished=Spill en lyd n�r en fil er ferdig
 ConfigView.label.backupconfigfiles=Backup konfigurasjonsfiler for bergingshensikter
 ConfigView.section.tracker.client.scrapesingleonly=Deaktiver per-tracker scrape aggregasjon (kan hjelpe trackere som gir 'URL too long' 414 feilmeldinger)
@@ -2253,11 +2234,6 @@ v3.mb.PlayFileNotFound.button.remove=Fjern fra Vuze
 v3.mb.PlayFileNotFound.button.redownload=Last ned data p� nytt
 v3.mb.PlayFileNotFound.button.find=Finn data manuelt..
 
-v3.mb.deletePurchased.title=Fjern kj�pt innhold
-v3.mb.deletePurchased.text=Er du sikker p� at du vil slette innholdet '%1'?\n\nDette innholdet har du enten har kj�pt, eller betalt for p�logging og nedlasting.
-v3.mb.deletePurchased.button.delete=&Slett
-v3.mb.deletePurchased.button.cancel=&Avbryt
-
 v3.topbar.menu.show.logo=Logo
 v3.topbar.menu.show.plugin=Plugin-omr�de
 v3.topbar.menu.show.search=S�k
diff --git a/org/gudy/azureus2/internat/MessagesBundle_pl_PL.properties b/org/gudy/azureus2/internat/MessagesBundle_pl_PL.properties
index a6a0826..c89f443 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_pl_PL.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_pl_PL.properties
@@ -35,11 +35,8 @@ MainWindow.menu.window.alltofront=Sprowad\u017a wszystko na &pocz\u0105tek
 MainWindow.menu.help=&Pomoc
 MainWindow.menu.help.about=O programie Vuze
 MainWindow.about.title=O programie
-MainWindow.about.section.developers=Programi\u015bci
-MainWindow.about.section.translators=T\u0142umacze
 MainWindow.about.internet.homepage=Strona g\u0142\u00f3wna Vuze
 MainWindow.about.internet.sourceforge=Strona Sourceforge Project
-MainWindow.about.internet.sourceforgedownloads=Pobierania Sourceforge
 MainWindow.about.internet.bugreports=Raportowanie b\u0142\u0119d\u00f3w
 MainWindow.about.internet.forumdiscussion=Forum
 MainWindow.dialog.choose.savepath=Wybierz \u015bcie\u017ck\u0119 zapisu
@@ -306,8 +303,6 @@ IrcView.help=Poprawne komendy to :\n . /help : wy\u015bwietla ten komunikat\n .
 PasswordWindow.title=Vuze jest zablokowany
 PasswordWindow.passwordprotected=Vuze jest chroniony has\u0142em.\nAby zobaczy\u0107 okno Vuze, nale\u017cy poda\u0107 has\u0142o tutaj:
 Button.ok=OK
-TrackerChangerWindow.title=Zmie\u0144 tracker
-TrackerChangerWindow.newtracker=Wpisz url nowego trackera
 PeersView.discarded=Odrzucone
 PeersView.discarded.info=Dane, kt\u00f3re zosta\u0142y pobrane niepotrzebnie i odrzucone.
 discarded=odrzucone
@@ -377,7 +372,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Wykasuj &plik torrent
 MyTorrentsView.menu.removeand.deletedata=Wykasuj &dane
 MyTorrentsView.menu.removeand.deleteboth=Wykasuj &oba
 deletedata.title=Usu\u0144 zawarto\u015b\u0107
-deletedata.message1=Czy jeste\u015b pewien, \u017ce chcesz usun\u0105\u0107 trwale '%1'?\n
 deletedata.noprompt=Nie pokazuj tego ponownie
 MainWindow.menu.file.configure=Kreator &konfiguracji...
 configureWizard.title=Kreator konfiguracji
@@ -400,7 +394,6 @@ configureWizard.transfer.maxActiveTorrents=Maksymalna liczba aktywnych
 configureWizard.transfer.maxDownloads=Maksymalna liczba pobieranych
 configureWizard.transfer.maxUploadsPerTorrent=Maksymalna liczba po\u0142\u0105cze\u0144 wychodz\u0105cych na torrent
 configureWizard.nat.title=NAT / Porty serwera
-configureWizard.nat.message=Aby jak najlepiej wykorzysta\u0107 mo\u017cliwo\u015bci aplikacji Vuze, nale\u017cy mie\u0107 pe\u0142ny dost\u0119p do Internetu. To narz\u0119dzie pozwoli na przetestowanie i / lub zmian\u0119 portu przyjmuj\u0105cego nadchodz\u0105ce  po\u0142\u0105czenia (peer).\n\nUWAGA: To narz\u0119dzie sprawdza tylko po\u0142\u0105czenia TCP. Po\u0142\u0105czenie UDP jest r\u00f3wnie\u017c wymagane, ale zostaniesz powiadomiony je\u015bli firewall b\u0119dzie je blokowa [...]
 configureWizard.nat.testing=Testuj\u0119 port
 configureWizard.nat.ok=OK!
 configureWizard.nat.ko=B\u0142\u0105d NAT
@@ -556,7 +549,6 @@ ConfigView.section.file.decoder.nodecoder=Brak
 IPChecker.external.service.no-ip.description=Provider dynamicznych i statycznych adres\u00f3w IP\n(swobodne sprawdzanie adresu jest niedost\u0119pne)
 ConfigView.section.tracker.publicenable=W\u0142\u0105cz zewn\u0119trzne torrenty
 ConfigView.label.playdownloadspeech=Przem\u00f3w gdy pobieranie zostanie zako\u0144czone
-ConfigView.label.playdownloadspeech.info=Obecnie Us\u0142ugi g\u0142osowe najlepiej dzia\u0142aj\u0105 w j\u0119zyku angielskim
 #
 # Tooltips
 #
@@ -729,8 +721,6 @@ plugin.sharing.download.remove.veto=To pobieranie jest wynikiem udost\u0119pnian
 ConfigView.section.tracker.main=G\u0142\u00f3wne
 ConfigView.label.prioritizefirstpiece=Zwi\u0119ksz priorytet dla pierwszej i ostatniej cz\u0119\u015bci pliku
 ConfigView.label.prioritizefirstpiece.tooltip=Zaczyna najpierw od pobrania pocz\u0105tku i ko\u0144ca pliku.\nPrzydatne przy podgl\u0105dzie plik\u00f3w.
-ConfigView.section.file.confirm_data_delete=Potwierdzaj przy usuwaniu danych
-ConfigView.section.file.confirm_data_delete.tooltip=Potwierdzaj usuni\u0119cie danych przy u\u017cyciu 'Usu\u0144 i Wykasuj...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Gdy usuwasz dane, pozw\u00f3l r\u00f3wnie\u017c na usuwanie plik\u00f3w po\u0142\u0105czonych z torrentami poza zapisanym katalogiem 
 TrayWindow.menu.startalldownloads=Uruchom wszystkie pobierania
 SystemTray.menu.startalltransfers=Uruchom wszystkie transfery
@@ -1038,7 +1028,6 @@ ConfigView.pluginlist.whereToPutOr=Dla wtyczek wsp\u00f3\u0142dzielonych u\u017c
 MainWindow.statusText.checking=Sprawdzanie aktualizacji
 TableColumn.header.OnlyCDing4=Tylko seedowanie
 TableColumn.header.OnlyCDing4.info=Pokazuje czas, w kt\u00f3rym torrent by\u0142 tylko seedowany. Nie uwzgl\u0119dnia czasu, w kt\u00f3rym torrent by\u0142 pobierany ( i seedowany).
-ConfigView.section.style.alternateTablePainting=U\u017cyj alternatywnej metody wype\u0142niania graficznie kolumn tabeli (mo\u017ce wymaga\u0107 ponownego uruchomienia)
 UpdateWindow.status.restartMaybeNeeded=Mo\u017ce by\u0107 potrzebne ponowne uruchomienie
 ConfigView.pluginlist.shared=udost\u0119pnione
 PeersView.host=Nazwa hosta
@@ -1272,18 +1261,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Rozmiar socketu SO_SNDBUF [0: u
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Ustawia standardow\u0105 warto\u015b\u0107 socketu SO_SNDBUF (w bajtach) np. TCP wysy\u0142a rozmiar okna.\nVuze pozostawi te nieustawione jako domy\u015blne, w rozumieniu domy\u015blnych warto\u015bci u\u017cywanych w systemie operacyjnym.\nUWAGA: Linuks podwaja wprowadzon\u0105 warto\u015b\u0107.
 ConfigView.section.connection.advanced.IPDiffServ=Warto\u015b\u0107 pakietu wychodz\u0105czego DiffServ (pole TOS)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Ustawia DiffServ jako cz\u0119\u015b\u0107 w polu typu serwisu (TOS) w nag\u0142\u00f3wku adresu IP dla nadchodz\u0105cych pakiet\u00f3w. Warto\u015bci szesnastkowe mog\u0105 by\u0107 ustawione przez dostawienie na ich pocz\u0105tku '0x', np. 0x10.\nVuze pozostawi te nieustawione jako domy\u015blne, w rozumieniu domy\u015blnych warto\u015bci u\u017cywanych w systemie operacyjnym.\nUWAGA: Ukryte implementacje sieci mog\u0105 ignoro [...]
-ConfigView.section.interface.confirm_torrent_removal=Poka\u017c okno potwierdzenia przy usuwaniu torrent\u00f3w
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Wy\u015bwietla okno potwierdzenia, gdy usuwasz torrenta z widoku Moje Torrenty
-MyTorrentsView.confirm_torrent_removal=Czy jeste\u015b pewien, \u017ce chcesz usun\u0105\u0107?\n
 TableColumn.header.seed_to_peer_ratio=Ratio seed:peer
 TableColumn.header.seed_to_peer_ratio.info=Ca\u0142kowite ratio seed\u00f3w do peer\u00f3w
 PeersView.connected_time=Czas pod\u0142\u0105czenia
 PeersView.connected_time.info=Ca\u0142kowity czas po\u0142\u0105czenia z peerem
-ConfigView.section.interface.display.add_torrents_silently=Dodawaj torrenty w tle
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Dodaje torrenty do pobierania bez aktywacji g\u0142\u00f3wnego okna Vuze.
 TableColumn.header.maxdownspeed=Maksymalna pr\u0119dko\u015b\u0107 pobierania
 TableColumn.header.maxdownspeed.info=Limit pr\u0119dko\u015b\u0107i pobierania ustawiony na torrent
-PeersGraphicView.title=Ruch
+PeersGraphicView.title.full=Ruch
 ConfigView.section.tracker.passwordwebhttpsonly=Dopuszczaj tylko po\u0142\u0105czenia przez HTTPS
 TableColumn.header.torrentpath=Lokalizacja torrenta
 TableColumn.header.torrentpath.info=Lokalizacja torrenta na dysku
@@ -1340,8 +1324,6 @@ UpdateWindow.restartLater=Uruchom ponownie p\u00f3\u017aniej
 MainWindow.menu.file.restart=Uruchom Vuze ponownie
 MainWindow.dialog.restartconfirmation.title=Ponowne uruchomienie Vuze
 MainWindow.dialog.restartconfirmation.text=Czy na pewno chcesz uruchomi\u0107 ponownie Vuze
-deletetorrent.message1=Chcesz usun\u0105\u0107 torrent dla :\n
-deletetorrent.message2=\nCzy chcesz kontynuowa\u0107?
 ConfigView.label.prioritizemostcompletedfiles=Ustaw najwy\u017cszy priorytet na pliki, w zale\u017cno\u015bci od ich % uko\u0144czenia i rozmiaru
 splash.plugin.init=Uruchamianie wtyczki:
 splash.plugin.UIinit=Uruchamianie wtyczki interfejsu u\u017cytkownika: %1
@@ -1504,7 +1486,6 @@ MainWindow.menu.file.open.torrentfortracking=Plik torrent... (tylko \u015bledzen
 MyTrackerView.date_added=Dodane
 ConfigView.section.tracker.portbackup=Porty kopii (';' oddzielenie)
 ConfigView.label.playfilespeech=Przem\u00f3w gdy plik zostanie uko\u0144czony
-ConfigView.label.playfilespeech.info=Obecnie Us\u0142ugi g\u0142osowe najlepiej dzia\u0142aj\u0105 w j\u0119zyku angielskim
 ConfigView.label.playfilefinished=Odtw\u00f3rz d\u017awi\u0119k gdy plik zostanie uko\u0144czony
 ConfigView.label.backupconfigfiles=Kopia zapasowa plik\u00f3w konfiguracyjnych w celu odzyskania po awarii
 ConfigView.section.tracker.client.scrapesingleonly=Wy\u0142\u0105cz sumowanie \u017c\u0105da\u0144 dla trackera (mo\u017ce pom\u00f3c, gdy tracker raportuje b\u0142\u0105d 414 "URL too long") 
@@ -2096,22 +2077,11 @@ v3.mb.delPublished.title=Zatrzymaj seedowanie zawarto\u015bci
 v3.mb.delPublished.text=OSTRZE\u017bENIE: Ta akcja NIE usunie Twojej publikowanej zawarto\u015bci '%1' z <A HREF="%2">%3</A> .\n\nKliknij "Usu\u0144" tylko, je\u015bli chcesz, aby publikowana i pobierana zawarto\u015b\u0107 zosta\u0142a zachowana, ale chcesz zwolni\u0107 \u0142\u0105cze. Upewnij si\u0119, \u017ce  proces wysy\u0142ania zosta\u0142 uko\u0144czony przed wykonaniem (<A HREF="%4">how</A>?).\n\nKliknij "Anuluj", je\u015bli chcesz ca\u0142kowicie usun\u0105\u0107 publikowan\u0 [...]
 v3.mb.delPublished.delete=&Usu\u0144
 v3.mb.delPublished.cancel=&Anuluj
-v3.mb.openFile.title=Otw\u00f3rz plik
-v3.mb.openFile.text.known=Ta zawarto\u015b\u0107 nie jest obecnie obs\u0142ugiwana przez odtwarzacz Vuze. Sprawd\u017a utworzony przez spo\u0142eczno\u015b\u0107 <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Poradnik odtwarzania</a>.\n\nTypy plik\u00f3w: %2 (%3)\n
-v3.mb.openFile.text.unknown=Ta zawarto\u015b\u0107 nie jest obecnie obs\u0142ugiwana przez odtwarzacz Vuze. Sprawd\u017a utworzony przez spo\u0142eczno\u015b\u0107 <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Poradnik odtwarzania</a>.\n\nRozszerzenie pliku : %2\n
-v3.mb.openFile.button.play=Odtw\u00f3rz
-v3.mb.openFile.button.cancel=Anuluj
-v3.mb.openFile.button.guide=Przeczytaj poradnik odtwarzania
-v3.mb.openFile.remember=Zawsze otwieraj pliki bez pytania
 v3.mb.PlayFileNotFound.title=Nie znaleziono pliku
 v3.mb.PlayFileNotFound.text=Brak plik\u00f3w "%1" lub s\u0105 one usuni\u0119te.
 v3.mb.PlayFileNotFound.button.remove=Usu\u0144 z Vuze
 v3.mb.PlayFileNotFound.button.redownload=Powt\u00f3rz pobieranie danych
 v3.mb.PlayFileNotFound.button.find=Wyszukiwanie r\u0119czne..
-v3.mb.deletePurchased.title=Usu\u0144 kupion\u0105 zawarto\u015b\u0107
-v3.mb.deletePurchased.text=Czy jeste\u015b pewien, \u017ce chcesz usun\u0105\u0107 zawarto\u015b\u0107 '%1'?\n\nJest to zawarto\u015b\u0107 kupi\u0142e\u015b lub musia\u0142e\u015b by\u0107 zalogowanym, aby pobra\u0107.
-v3.mb.deletePurchased.button.delete=&Usu\u0144
-v3.mb.deletePurchased.button.cancel=&Anuluj
 v3.topbar.menu.show.plugin=Strefa wtyczki
 v3.topbar.menu.show.search=Szukaj
 v3.topbar.menu.show.frog=Niebieska \u017caba
@@ -2287,10 +2257,6 @@ v3.splash.hookPluginUI=Przyczepione do wtyczki interfejsu u\u017cytkownika
 OpenTorrentWindow.mb.notTorrent.cannot.display=Nie mo\u017cna poprawnie wy\u015bwietli\u0107 danych
 MainWindow.menu.window.zoom.maximize=Maksymalizuj
 MainWindow.menu.window.zoom.restore=Przywr\u00f3\u0107
-ImageResizer.image.too.small=Wprowadzony obrazek jest za ma\u0142y, wybierz inny (musi by\u0107 przynajmniej %1 x %2)
-ImageResizer.title=Te narz\u0119dzie pozwala na podgl\u0105d jak b\u0119dzie wygl\u0105da\u0142 Tw\u00f3j paznokie\u0107 kciuka na platformie Vuze
-ImageResizer.move.image=Przenie\u015b obrazek przez przeci\u0105gni\u0119cie
-ImageResizer.move.image.with.slider=Przenie\u015b obrazek przez przeci\u0105gni\u0119cie, dostosuj go u\u017cywaj\u0105c poni\u017cszego suwaka
 security.crypto.title=Kontrola klucza szyfruj\u0105cego
 security.crypto.encrypt=Wprowad\u017a has\u0142o, \u017ceby zabezpieczy\u0107 nowo wygenerowany klucz szyfruj\u0105cy. Nie zapomnij has\u0142a, nie ma mo\u017cliwo\u015bci na jego odzyskanie!
 security.crypto.decrypt=Wprowad\u017a has\u0142o, \u017ceby odblokowa\u0107 klucz szyfruj\u0105cy.
@@ -2380,9 +2346,6 @@ metasearch.addtemplate.dup.title=Duplikat szablonu
 metasearch.addtemplate.dup.desc=Szablon wyszukiwania %1 jest ju\u017c zainstalowany
 metasearch.export.select.template.file=Zapisz szablon
 metasearch.import.select.template.file=Otw\u00f3rz szablon
-dialog.uiswitch.title=Prze\u0142\u0105cz do interfejsu u\u017cytkownika Vuze
-dialog.uiswitch.text=Musisz mie\u0107 uruchomiony interfejs u\u017cytkownika Vuze, aby u\u017cy\u0107 tej opcji.\n\nVuze musi by\u0107 ponownie uruchomiony.
-dialog.uiswitch.button=Prze\u0142\u0105cz do interfejsu u\u017cytkownika Vuze
 azbuddy.tracker.enabled=W\u0142\u0105cz 'Friends Boost', aby uszeregowa\u0107 pobieranie ze znajomymi
 v3.MainWindow.button.download=Pobierz
 v3.MainWindow.button.run=Uruchom pobrany plik
@@ -2526,7 +2489,7 @@ Wizard.Subscription.rss.subtitle2=Wielu publikuj\u0105cych wprowadza kana\u0142
 Wizard.Subscription.rss.subtitle3=Po zapisaniu, b\u0119dziesz otrzymywa\u0142 aktualizacje w pasku bocznym, je\u015bli tylko b\u0119d\u0105 dost\u0119pne nowe wyniki przez kana\u0142 RSS.
 Wizard.Subscription.subscribe.library=Zawarto\u015b\u0107 Twojej biblioteki
 Wizard.Subscription.subscribe.subscriptions=Powi\u0105zane subskrypcje
-Wizard.Subscription.subscribe.library.empty=Brak dost\u0119pnych subskrypcji?\n \nSp\u00f3jrz na jasno pomara\u0144czony przycisk subskrypcji w Sie\u0107 Vuze HD.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Wi\u0119cej</A>
+Wizard.Subscription.subscribe.library.empty=Brak dost\u0119pnych subskrypcji?\n \nSp\u00f3jrz na jasno pomara\u0144czony przycisk subskrypcji w Sie\u0107 Vuze HD.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Wi\u0119cej</A>
 message.confirm.delete.title=Potwierd\u017a usuni\u0119cie
 message.confirm.delete.text=Czy na pewno chcesz usun\u0105\u0107 '%1'?
 Subscription.menu.properties=W\u0142a\u015bciwo\u015bci
@@ -2563,7 +2526,7 @@ statusbar.feedback.tooltip=Kliknij tutaj, aby wys\u0142a\u0107 opini\u0119
 sidebar.Activity=Powiadomienia
 v3.activity.button.watchall=Zaznacz wszystkie zobaczone
 subscriptions.view.help.1=Dodaj subskrypcje, kt\u00f3re widzisz
-subscriptions.view.help.2=Zdob\u0105d\u017a bezp\u0142atnie nowe aktualizacje, je\u015bli b\u0119d\u0105 dost\u0119pne do pobrania. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Wi\u0119cej</A>.
+subscriptions.view.help.2=Zdob\u0105d\u017a bezp\u0142atnie nowe aktualizacje, je\u015bli b\u0119d\u0105 dost\u0119pne do pobrania. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Wi\u0119cej</A>.
 sidebar.sash.tooltip=F7 do szybkiego ukrycia/pokazania paska bocznego
 sidebar.expand.tooltip=Rozwi\u0144 pasek boczny
 sidebar.dropdown.tooltip=Poka\u017c pasek boczny w menu formatu
@@ -2600,14 +2563,6 @@ azbuddy.ui.menu.cat.share=W\u0142\u0105cz subskrypcje ze znajomym(i)
 azbuddy.ui.menu.cat.set_msg=Lista kategorii oddzielona przecinkami lub 'Wszyscy'
 azbuddy.ui.menu.cat_subs=Subskrybuj
 subs.prop.update_period=Cykl aktualizacji
-azbuddy.enable_cat_pub=Publiczne kategorie, kt\u00f3re WSZYSCY Twoi znajomi mog\u0105 subskrybowa\u0107 (',' separated) 
-v3.dialog.cnclose.title=%1 zamkni\u0119tych
-v3.dialog.cnclose.subtitle=Powiadomienie
-v3.dialog.cnclose.info1=Zamkn\u0105\u0142e\u015b sie\u0107 HD
-v3.dialog.cnclose.info2=Je\u015bli chcia\u0142by\u015b ponownie otworzy\u0107 sie\u0107 HD, mo\u017cesz to zrobi\u0107 w menu "Sieci HD" na g\u00f3rze ekranu.
-v3.dialog.cnclose.noshow=Nie pokazuj wi\u0119cej
-v3.dialog.cnmanage.title=Menu zarz\u0105dzania sieciami HD
-v3.dialog.cnmanage.intro=Mo\u017cesz wybra\u0107 z poni\u017cszej listy, zawarto\u015bci sieci kt\u00f3re chcesz wy\u015bwietli\u0107 w menu "Sieci HD"
 TableColumn.header.#.info=Pozycja/numer porz\u0105dkowy
 TableColumn.header.category.info=Nazwa kategorii, do kt\u00f3rej nale\u017cy torrent
 TableColumn.header.DateCompleted.info=Data, kiedy pobranie torrenta zosta\u0142a uko\u0144czona
@@ -2758,7 +2713,7 @@ xcode.deletedata.title=Usu\u0144 zawarto\u015b\u0107 transkodowan\u0105
 xcode.deletedata.message=Czy jeste\u015b pewien, \u017ce chcesz nieodwracalnie usun\u0105\u0107 kopi\u0119 '%1' transkodowan\u0105 dla '%2'%3?
 xcode.deletedata.message.2=\n(kopia mo\u017ce ci\u0105gle istnie\u0107 w '%1')
 v3.deviceview.infobar.line1=Przeci\u0105gnij i upu\u015b\u0107 wideo z biblioteki na wybrane urz\u0105dzenie.
-v3.deviceview.infobar.line2=Odtw\u00f3rz wideo na kt\u00f3rym\u015b z ekran\u00f3w - iPhone, iPod, TV
+v3.deviceview.infobar.line2=Odtw\u00f3rz wideo na kt\u00f3rym\u015b z ekran\u00f3w - iPad, iPhone, iPod, TV
 v3.deviceview.infobar.line1.generic=Przeci\u0105gnij i upu\u015b\u0107 wideo z biblioteki do %1 na pasku bocznym.
 v3.deviceview.infobar.line2.itunes=Wideo poka\u017ce si\u0119 w folderze iTunes Movies, gdy b\u0119d\u0105 dost\u0119pne do odtworzenia.
 v3.deviceview.infobar.line2.xbox=Wideo strumieniowe na Xbox 360 po wybraniu M\u00f3j Xbox->Bilbioteka Wideo -> Vuze.
diff --git a/org/gudy/azureus2/internat/MessagesBundle_pt_BR.properties b/org/gudy/azureus2/internat/MessagesBundle_pt_BR.properties
index 60c59a8..8a71e5f 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_pt_BR.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_pt_BR.properties
@@ -34,13 +34,10 @@ MainWindow.menu.window.alltofront=Trazer Todos para a &Frente
 MainWindow.menu.help=&Ajuda
 MainWindow.menu.help.about=Sobre o Vuze
 MainWindow.about.title=Sobre
-MainWindow.about.section.developers=Desenvolvedores
-MainWindow.about.section.translators=Tradutores
 MainWindow.about.section.system=Sistema
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.homepage=Home page do Vuze
 MainWindow.about.internet.sourceforge=P\u00e1gina do Projeto no Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Downloads do Sourceforge
 MainWindow.about.internet.bugreports=Relatar Bugs
 MainWindow.about.internet.forumdiscussion=F\u00f3runs
 MainWindow.about.internet.wiki=FAQ e Wiki do Vuze
@@ -311,8 +308,6 @@ IrcView.help=Os comandos v\u00e1lidos s\u00e3o :\n . /help : exibe esta mensagem
 PasswordWindow.title=O Vuze est\u00e1 trancado
 PasswordWindow.passwordprotected=O Vuze est\u00e1 protegido por senha.\nPara mostrar a janela do Vuze, por favor insira a sua senha aqui :
 Button.ok=OK
-TrackerChangerWindow.title=Adicionar Tracker
-TrackerChangerWindow.newtracker=Insira a nova URL do tracker
 PeersView.discarded=Descartado
 PeersView.discarded.info=Dados que voc\u00ea de alguma forma recebeu embora voc\u00ea n\u00e3o precisasse deles, ent\u00e3o voc\u00ea se livrou deles.
 discarded=descartado
@@ -382,7 +377,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Apagar &Arquivo Torrent
 MyTorrentsView.menu.removeand.deletedata=Apagar &Dados
 MyTorrentsView.menu.removeand.deleteboth=Apagar &Ambos
 deletedata.title=Aten\u00e7\u00e3o 
-deletedata.message1=Voc\u00ea est\u00e1 para apagar os DADOS de :\n 
 deletedata.noprompt=N\u00e3o me alertar de novo
 MainWindow.menu.file.configure=Assistente de &Configura\u00e7\u00e3o...
 configureWizard.title=Assistente de Configura\u00e7\u00e3o
@@ -404,7 +398,6 @@ configureWizard.transfer.maxActiveTorrents=M\u00e1ximo de Ativos
 configureWizard.transfer.maxDownloads=M\u00e1ximo de Downloads 
 configureWizard.transfer.maxUploadsPerTorrent=M\u00e1ximo de Uploads por Torrent 
 configureWizard.nat.title=Porta do NAT / Servidor 
-configureWizard.nat.message=De modo a obter o melhor do Vuze, \u00e9 altamente recomendado estar completamente acess\u00edvel a internet. Esta ferramenta deixa voc\u00ea testar e / ou mudar a porta usada para aceitar as conex\u00f5es de entrada dos peers.\n\nNOTA: Esta ferramenta apenas testa conex\u00f5es TCP. A Base de Dados Distribu\u00edda requer conex\u00f5es de entrada UDP tamb\u00e9m, mas automaticamente notificar\u00e1 voc\u00ea se descobrir um firewall bloqueando.\n\nNOTA: Porta [...]
 configureWizard.nat.test=Teste
 configureWizard.nat.testing=Testando porta
 configureWizard.nat.ok=OK! 
@@ -568,7 +561,6 @@ ConfigView.section.file.decoder.nodecoder=Nenhum
 IPChecker.external.service.no-ip.description=Provedor de servi\u00e7o DNS din\u00e2mico e est\u00e1tico\n(nenhum servi\u00e7o de 'verificar o endre\u00e7o' dispon\u00edvel gratuitamente)
 ConfigView.section.tracker.publicenable=Ativar torrents externos
 ConfigView.label.playdownloadspeech=Falar quando um download est\u00e1 terminado
-ConfigView.label.playdownloadspeech.info=Os servi\u00e7os de discurso atualmente funcionam melhor com o ingl\u00eas
 #
 # Tooltips
 #
@@ -741,8 +733,6 @@ ConfigView.section.tracker.main=Principal
 ConfigView.section.tracker.web=Web 
 ConfigView.label.prioritizefirstpiece=Priorizar o primeiro e o \u00faltimo peda\u00e7o do(s) arquivo(s)
 ConfigView.label.prioritizefirstpiece.tooltip=Tenta baixar o come\u00e7o e o fim de um arquivo primeiro.\nPara o suporte de pr\u00e9-visualiza\u00e7\u00e3o.
-ConfigView.section.file.confirm_data_delete=Confirmar antes de apagar os dados
-ConfigView.section.file.confirm_data_delete.tooltip=Confirmar a exclus\u00e3o dos dados quando usar 'Remover e Apagar...'
 ConfigView.section.file.delete.include_files_outside_save_dir=Quando apagando os dados, permitir aos arquivos ligados fora do diret\u00f3rio para salvar torrents serem removidos tamb\u00e9m
 TrayWindow.menu.startalldownloads=Iniciar Todos os Downloads
 SystemTray.menu.startalltransfers=Iniciar Todas as Transfer\u00eancias
@@ -1047,7 +1037,6 @@ ConfigView.pluginlist.whereToPutOr=Para plugins compartilhados usar:
 MainWindow.statusText.checking=Procurando por Atualiza\u00e7\u00f5es
 TableColumn.header.OnlyCDing4=S\u00f3FazendoSeed4
 TableColumn.header.OnlyCDing4.info=Quantia de tempo que o torrent esteve fazendo seed. Exclui o tempo que o torrent estava baixando (e fazendo seed).
-ConfigView.section.style.alternateTablePainting=Usar m\u00e9todo alternativo para desenhar os gr\u00e1ficos de tabela das colunas (pode ser necess\u00e1rio reiniciar)
 UpdateWindow.status.restartMaybeNeeded=Pode ser necess\u00e1rio reiniciar
 ConfigView.pluginlist.shared=compartilhado
 PeersView.host=Nome do Servidor
@@ -1283,18 +1272,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Tamanho do Socket SO_SNDBUF [0:
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Define o valor do socket padr\u00e3o SO_SNDBUF (em bytes), i.e. o tamanho da janela de envio TCP.\nO Vuze deixa isto n\u00e3o definido por padr\u00e3o, siginificando que os padr\u00f5es para o SO b\u00e1sico s\u00e3o usados.\nNOTA: O linux dobra o valor dado.
 ConfigView.section.connection.advanced.IPDiffServ=Valor do DiffServ do pacote de sa\u00edda (campo do TOS)
 ConfigView.section.connection.advanced.IPDiffServ.tooltip=Define a parte do DiffServ do campo do tipo-de-servi\u00e7o (TOS) no cabe\u00e7alho do IP para os pacotes de sa\u00edda.\nValores hexadecimais podem ser especificados prefixando eles com '0x', ex: 0x10.\nO Vuze deixa isto n\u00e3o definido por padr\u00e3o, significando que os padr\u00f5es para o SO b\u00e1sico s\u00e3o usados.\nNOTA: As implementa\u00e7\u00e3o da rede b\u00e1sica pode ignorar este valor, ent\u00e3o esta op\u00e7\u [...]
-ConfigView.section.interface.confirm_torrent_removal=Mostrar dialogo de comfirma\u00e7\u00e3o sobre a remo\u00e7\u00e3o de torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmar quando estiver removendo um torrent de MeusTorrents.
-MyTorrentsView.confirm_torrent_removal=Voc\u00ea tem certeza que voc\u00ea quer remover?\n
 TableColumn.header.seed_to_peer_ratio=Propor\u00e7\u00e3oSeed2Peer
 TableColumn.header.seed_to_peer_ratio.info=Total da propor\u00e7a\u00f5 de seeds para peers na multid\u00e3o 
 PeersView.connected_time=Tempo Conectado
 PeersView.connected_time.info=Tempo total que est\u00e1 conectado com o peer
-ConfigView.section.interface.display.add_torrents_silently=Adicionar torrents silenciosamente
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Adicionar downloads de torrent sem ativar a janela principal do Vuze.
 TableColumn.header.maxdownspeed=M\u00e1x de Velocidade de Down
 TableColumn.header.maxdownspeed.info=M\u00e1x de Velocidade de Download por torrent
-PeersGraphicView.title=Multid\u00e3o
+PeersGraphicView.title.full=Multid\u00e3o
 ConfigView.section.tracker.passwordwebhttpsonly=S\u00f3 permitir o acesso via HTTPS
 TableColumn.header.torrentpath=Local do Torrent
 TableColumn.header.torrentpath.info=Local do Torrent no disco
@@ -1351,8 +1335,6 @@ UpdateWindow.restartLater=Reiniciar Mais Tarde
 MainWindow.menu.file.restart=Reiniciar o Vuze
 MainWindow.dialog.restartconfirmation.title=Reiniciar o Vuze?
 MainWindow.dialog.restartconfirmation.text=Voc\u00ea realmente quer reiniciar o Vuze?
-deletetorrent.message1=Voc\u00ea est\u00e1 pra exclu\u00edr o TORRENT para :\n
-deletetorrent.message2=\nVoc\u00ea tem certeza que voc\u00ea quer prosseguir?
 ConfigView.label.prioritizemostcompletedfiles=Priorizar mais os arquivos de alta prioridade de acordo com a % completada e o tamanho do arquivo
 splash.plugin.init=Inicializando o Plugin: 
 splash.plugin.UIinit=Inicializando a GUI do Plugin:  %1
@@ -1509,7 +1491,6 @@ MainWindow.menu.file.open.torrentfortracking=Arquivo Torrent... (Apenas Tracking
 MyTrackerView.date_added=Adicionado
 ConfigView.section.tracker.portbackup=Fazer backup das portas (';' separadas)
 ConfigView.label.playfilespeech=Falar quando um arquivo est\u00e1 terminado
-ConfigView.label.playfilespeech.info=Os servi\u00e7os de discurso atualmente funcionam melhor com o ingl\u00eas
 ConfigView.label.playfilefinished=Tocar um som quando um arquivo est\u00e1 terminado
 ConfigView.label.backupconfigfiles=Fazer backup dos arquivos de configura\u00e7\u00e3o para prop\u00f3sitos de recupera\u00e7\u00e3o
 ConfigView.section.tracker.client.scrapesingleonly=Desativar agrega\u00e7\u00e3o de scrape por tracker (pode ajudar com os trackers que reportam os erros de 'URL muito longa' (414) ) 
@@ -2097,22 +2078,11 @@ v3.mb.delPublished.title=Parar de Ficar de Seed com este Conte\u00fado
 v3.mb.delPublished.text=AVISO: Esta a\u00e7\u00e3o N\u00c3O remover\u00e1 seu conte\u00fado publicado '%1' de <A HREF="%2">%3</A> .\n\nClique em "Apagar" apenas se voc\u00ea quer que o seu conte\u00fado permane\u00e7a publicado e baix\u00e1vel, mas quer liberar a sua banda. Tenha certeza de que o processo de upload foi completado antes de faz\u00ea-lo (<A HREF="%4">how</A>?).\n\nClique em "Cancelar" se voc\u00ea quer remover completamente seu conte\u00fado publicado de %3, e usar o bot\u [...]
 v3.mb.delPublished.delete=&Apagar
 v3.mb.delPublished.cancel=&Cancelar
-v3.mb.openFile.title=Abrir o Arquivo
-v3.mb.openFile.text.known=Este conte\u00fado n\u00e3o \u00e9 atualmente suportado pelo player do Vuze.  Verifique a comunidade criada  <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Guia do Playback</a> por ajuda.\n\nO Tipo do Arquivo Aparenta ser: %2 (%3)\n
-v3.mb.openFile.text.unknown=Este conte\u00fado n\u00e3o \u00e9 atualmente suportado pelo player do Vuze.  Verifique a comunidade criada <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Guia do Playback</a> por ajuda.\n\nExtens\u00e3o do Arquivo : %2\n
-v3.mb.openFile.button.play=Reproduzir
-v3.mb.openFile.button.cancel=Cancelar
-v3.mb.openFile.button.guide=Leia o Guia do Playback
-v3.mb.openFile.remember=Sempre abrir os arquivos sem me perguntar
 v3.mb.PlayFileNotFound.title=Arquivo N\u00e3o Encontrado
 v3.mb.PlayFileNotFound.text=Os arquivos para '%1' est\u00e3o ou apagados ou desaparecidos.
 v3.mb.PlayFileNotFound.button.remove=Remover do Vuze
 v3.mb.PlayFileNotFound.button.redownload=Baixar Dados de Novo
 v3.mb.PlayFileNotFound.button.find=Achar Manualmente..
-v3.mb.deletePurchased.title=Remover o Conte\u00fado Comprado
-v3.mb.deletePurchased.text=Voc\u00ea tem certeza de que voc\u00ea quer apagar o conte\u00fado '%1'?\n\nIsto \u00e9 conte\u00fado que voc\u00ea ou comprou, ou voc\u00e9 \u00e9 requerido logar para baixar.
-v3.mb.deletePurchased.button.delete=&Apagar
-v3.mb.deletePurchased.button.cancel=&Cancelar
 v3.topbar.menu.show.plugin=\u00c1rea dos Plugins
 v3.topbar.menu.show.search=Busca
 v3.topbar.menu.show.frog=O Sapo Azul
@@ -2301,10 +2271,6 @@ v3.splash.hookPluginUI=Enganchando na UI do Plugin
 OpenTorrentWindow.mb.notTorrent.cannot.display=Incapaz de exibir os dados apropriadamente
 MainWindow.menu.window.zoom.maximize=Maximizar
 MainWindow.menu.window.zoom.restore=Restaurar
-ImageResizer.image.too.small=A imagem fornecida \u00e9 muito pequena, por favor escolha uma imagem diferene (tem que ser pelo menos %1 x %2)
-ImageResizer.title=Esta ferramenta deixa voc\u00ea pr\u00e9-visualizar como o seu thumbnail vai parecer na Plataforma Vuze
-ImageResizer.move.image=Mova a imagem arrastando-a
-ImageResizer.move.image.with.slider=Mova a imagem arrastando-a, redimensione-a usando o slider abaixo
 security.crypto.title=Acesso a Chave de Encripta\u00e7\u00e3o
 security.crypto.encrypt=Por favor insira uma senha para proteger sua chave de encripta\u00e7\u00e3o gerada recentemente. Por favor n\u00e3o esque\u00e7a esta senha, n\u00e3o h\u00e1 meio de recuper\u00e1-loa se voc\u00ea esquecer!
 security.crypto.decrypt=Por favor insira sua senha para destrancar sua chave de encripta\u00e7\u00e3o.
@@ -2396,9 +2362,6 @@ metasearch.addtemplate.dup.title=Modelo Duplicado
 metasearch.addtemplate.dup.desc=O modelo de busca %1 j\u00e1 est\u00e1 instalado
 metasearch.export.select.template.file=Salvar o Modelo
 metasearch.import.select.template.file=Abrir o Modelo
-dialog.uiswitch.title=Trocar para a IU do Vuze
-dialog.uiswitch.text=Voc\u00ea precisa estar executando a IU do Vuze para usar esta fun\u00e7\u00e3o.\n\nO Vuze precisar\u00e1 reiniciar.
-dialog.uiswitch.button=Trocar para a IU do Vuze
 azbuddy.tracker.enabled=Ativar a 'Acelera\u00e7\u00e3o do Amigo' para priorizar o download com seus amigos
 azbuddy.protocolspeed=Eleva\u00e7\u00e3o m\u00e1xima do protocolo em KB/s do amigo
 v3.MainWindow.button.run=Executar o Arquivo Baixado
@@ -2549,7 +2512,7 @@ Wizard.Subscription.rss.subtitle2=Muitos editores fornecem feeds RSS do conte\u0
 Wizard.Subscription.rss.subtitle3=Uma vez salvo, voc\u00ea receber\u00e1 atualiza\u00e7\u00f5es ao vivo na sua barra lateral sempre que novos resultados est\u00e3o dispon\u00edveis via seu feed RSS.
 Wizard.Subscription.subscribe.library=Conte\u00fado na sua Biblioteca
 Wizard.Subscription.subscribe.subscriptions=Subscri\u00e7\u00f5es Relacionadas
-Wizard.Subscription.subscribe.library.empty=Sem subscri\u00e7\u00f5es dispon\u00edveis?\n \nProcure pelo bot\u00e3o para subscrever laranja brilhante na Rede HD do Vuze.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Leia mais</A>
+Wizard.Subscription.subscribe.library.empty=Sem subscri\u00e7\u00f5es dispon\u00edveis?\n \nProcure pelo bot\u00e3o para subscrever laranja brilhante na Rede HD do Vuze.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Leia mais</A>
 message.confirm.delete.title=Confirmar a Exclus\u00e3o
 message.confirm.delete.text=Voc\u00ea tem certeza que voc\u00ea quer apagar o '%1'?
 Subscription.menu.properties=Propriedades
@@ -2587,7 +2550,7 @@ statusbar.feedback.tooltip=Clique aqui para enviar feedback
 sidebar.Activity=Notifica\u00e7\u00f5es
 v3.activity.button.watchall=Marcar Todos os Observados
 subscriptions.view.help.1=Adicionar Subscri\u00e7\u00f5es onde quer que voc\u00ea veja
-subscriptions.view.help.2=Obtenha atualiza\u00e7\u00f5es ao vivo gr\u00e1tis sempre que novo conte\u00fado est\u00e1 dispon\u00edvel para baixar. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Leia mais</A>.
+subscriptions.view.help.2=Obtenha atualiza\u00e7\u00f5es ao vivo gr\u00e1tis sempre que novo conte\u00fado est\u00e1 dispon\u00edvel para baixar. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">Leia mais</A>.
 sidebar.sash.tooltip=F7 para rapidamente esconder/mostrar a barra lateral
 sidebar.expand.tooltip=Expandir a Barra Lateral
 sidebar.dropdown.tooltip=Mostrar a barra lateral no formato do menu
@@ -2626,13 +2589,6 @@ azbuddy.ui.menu.cat.set_msg=Lista das categorias separadas por v\u00edrgula, ou
 azbuddy.ui.menu.cat_subs=Subscrever
 subs.prop.update_period=Per\u00eddo de atualiza\u00e7\u00f5es
 azbuddy.enable_cat_pub=Categorias p\u00fablicas nas quais todos os seus amigos podem subscrever (separadas por ',' ) 
-v3.dialog.cnclose.title=%1 Fechado
-v3.dialog.cnclose.subtitle=Notifica\u00e7\u00e3o
-v3.dialog.cnclose.info1=Voc\u00ea fechou um Rede HD
-v3.dialog.cnclose.info2=Se voc\u00ea quiser reabrir esta Rede HD, voc\u00ea pode faz\u00ea-lo no menu "Redes HD" no topo da sua tela.
-v3.dialog.cnclose.noshow=N\u00e3o mostrar de novo
-v3.dialog.cnmanage.title=Gerenciar o Menu das Redes HD
-v3.dialog.cnmanage.intro=Voc\u00ea pode escolher da lista abaixo quais redes com conte\u00fado voc\u00ea deseja exibir no menu "Redes HD"
 azbuddy.ui.table.read_cat=Leitura do gato
 TableColumn.header.#.info=N\u00famero da Posi\u00e7\u00e3o/Ordenamento
 TableColumn.header.category.info=Nome da categoria a qual o torrent pertence
diff --git a/org/gudy/azureus2/internat/MessagesBundle_pt_PT.properties b/org/gudy/azureus2/internat/MessagesBundle_pt_PT.properties
index d4e0938..a7c11b8 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_pt_PT.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_pt_PT.properties
@@ -31,12 +31,9 @@ MainWindow.menu.window.alltofront=Trazer tudo para a &Frente
 MainWindow.menu.help=&Ajuda
 MainWindow.menu.help.about=&Sobre o Vuze
 MainWindow.about.title=Sobre
-MainWindow.about.section.developers=Colaboradores
-MainWindow.about.section.translators=Tradutores
 MainWindow.about.section.system=Sistema
 MainWindow.about.internet.homepage=P\u00e1gina do Vuze
 MainWindow.about.internet.sourceforge=P\u00e1gina do Projecto na Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Transfer\u00eancias da Sourceforge
 MainWindow.about.internet.bugreports=Reportar Erros
 MainWindow.about.internet.forumdiscussion=Forum Geral
 MainWindow.about.internet.wiki=Wiki FAQ do Vuze
@@ -296,8 +293,6 @@ IrcView.help=Os comandos v\u00e1lidos s\u00e3o :\n . /help : mostra esta mensage
 PasswordWindow.title=Vuze est\u00e1 bloqueado
 PasswordWindow.passwordprotected=O Vuze est\u00e1 protegido com senha.\nPara mostrar a janela principal, por favor introduza aqui a senha :
 Button.ok=Ok
-TrackerChangerWindow.title=Adicionar Tracker
-TrackerChangerWindow.newtracker=Indique o novo endere\u00e7o do tracker
 PeersView.discarded=Descartado
 PeersView.discarded.info=Dados que voc\u00ea recebeu apesar de j\u00e1 n\u00e3o precisar, por isso viu-se livre deles.
 discarded=descartado
@@ -368,7 +363,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Apaga o &Torrent
 MyTorrentsView.menu.removeand.deletedata=Apaga os &Dados
 MyTorrentsView.menu.removeand.deleteboth=Apaga &Ambos
 deletedata.title=!!! Aviso !!!
-deletedata.message1=Est\u00e1 prestes a apagar os DADOS de :\n
 MainWindow.menu.file.configure=A&ssistente de Configura\u00e7\u00e3o
 configureWizard.title=Assistente de Configura\u00e7\u00e3o
 configureWizard.welcome.title=Bem-vindo ao Assistente de Configura\u00e7\u00e3o
@@ -390,7 +384,6 @@ configureWizard.transfer.maxActiveTorrents=N\u00famero m\u00e1ximo de torrents a
 configureWizard.transfer.maxDownloads=N\u00famero m\u00e1ximo de transfer\u00eancias
 configureWizard.transfer.maxUploadsPerTorrent=N\u00famero m\u00e1ximo de envios por torrent
 configureWizard.nat.title=NAT / Portas do Servidor
-configureWizard.nat.message=De forma a ter o melhor uso do protocolo BitTorrent, \u00e9 altamente recomendado que d\u00ea acessos completos ao Vuze na sua Firewall/Router.\nO porto de escuta usado para o protocolo bittorrent por omiss\u00e3o \u00e9 6881.\nEsta ferramenta permite testar e/ou efectuar a sua altera\u00e7\u00e3o.
 configureWizard.nat.test=Testar
 configureWizard.nat.testing=A testar porta
 configureWizard.nat.ok=Ok
@@ -549,7 +542,6 @@ ConfigView.section.file.decoder.nodecoder=Nenhum
 IPChecker.external.service.no-ip.description=provedor de servi\u00e7os de DNS Est\u00e1ticos e Din\u00e2micos\n(n\u00e3o tem servi\u00e7o gr\u00e1tis de verificar endere\u00e7o)
 ConfigView.section.tracker.publicenable=Permitir torrents externos
 ConfigView.label.playdownloadspeech=Fala quando a transfer\u00eancia termina.
-ConfigView.label.playdownloadspeech.info=Os Servi\u00e7os de Fala actualmente funcionam melhor em Ingl\u00eas
 #
 # Tooltips
 #
@@ -720,8 +712,6 @@ ConfigView.section.tracker.main=Principal
 ConfigView.section.tracker.web=P\u00e1gina
 ConfigView.label.prioritizefirstpiece=Dar prioridade ao primeiro bloco de cada ficheiro
 ConfigView.label.prioritizefirstpiece.tooltip=Tenta sacar primeiro o in\u00edcio de cada ficheiro.\nPara suportar a pr\u00e9-visualiza\u00e7\u00e3o de ficheiros incompletos.
-ConfigView.section.file.confirm_data_delete=Confirmar quando apagar ficheiros
-ConfigView.section.file.confirm_data_delete.tooltip=Confirma apagar ficheiros quando usar 'Remover e Apagar...'
 TrayWindow.menu.startalldownloads=Iniciar Todos as Transfer\u00eancias
 SystemTray.menu.startalltransfers=Iniciar todas as Transfer\u00eancias
 sharing.progress.title=Progresso da Partilha
@@ -1013,7 +1003,6 @@ ConfigView.pluginlist.whereToPut=Coloque qualquer extens\u00e3o especifica de ut
 ConfigView.pluginlist.whereToPutOr=Para extens\u00f5es partilhadas entre utilizadores, use:
 MainWindow.statusText.checking=Verificando por Actualiza\u00e7\u00f5es
 TableColumn.header.OnlyCDing4.info=Quantidade de tempo que o torrent esteve apenas a semear. Exclui o tempo que o torrent esteve a receber (e a semear)
-ConfigView.section.style.alternateTablePainting=Usar m\u00e9todo alternativo para pintar colunas das tabelas com gr\u00e1ficos (pode requerer reinicio)
 ConfigView.pluginlist.shared=partilhado
 PeersView.host=Nome do PC
 PeersView.host.info=O nome da m\u00e1quina em que se encontra o par, quando disponivel (pode afectar a performance)
@@ -1241,15 +1230,10 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Tamanho do buffer de entrada -
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Define o valor (em bytes) do socket SO_RCVBUF, isto \u00e9 o tamanho e escala da janela de recep\u00e7\u00e3o TCP.\nO Vuze n\u00e3o define isto por omiss\u00e3o, isto significa que as defini\u00e7\u00f5es do Sistema Operativo s\u00e3o usadas.\nNOTE: Em Linux os valores dados s\u00e3o duplicados.
 ConfigView.section.connection.advanced.SO_SNDBUF=Tamanho do buffer de sa\u00edda - SO_SNDBUF [0: definido pelo SO]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Define o valor (em bytes) do socket SO_SNDBUF, isto \u00e9 o tamanho e escala da janela de envio TCP.\nO Vuze n\u00e3o define isto por omiss\u00e3o, isto significa que as defini\u00e7\u00f5es do Sistema Operativo s\u00e3o usadas.\nNOTE: Em Linux os valores dados s\u00e3o duplicados.\n
-ConfigView.section.interface.confirm_torrent_removal=Mostrar di\u00e1logo de confirma\u00e7\u00e3o ao remover torrents
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmar quando Remover um Torrent da vista \u201cMeus Torrents\u201d
-MyTorrentsView.confirm_torrent_removal=Tem a certeza que deseja remover?\n
 TableColumn.header.seed_to_peer_ratio=R\u00e1cioSeed2Peer
 TableColumn.header.seed_to_peer_ratio.info=R\u00e1cio Total de swarm entre seeders e pares
 PeersView.connected_time=Tempo Ligado
 PeersView.connected_time.info=Tempo total ligado ao par
-ConfigView.section.interface.display.add_torrents_silently=Adicionar torrents silenciosamente
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Adicionar download de torrents sem activar a janela principal do Azureus.
 TableColumn.header.maxdownspeed=Velocidade M\u00e1x de Transf
 TableColumn.header.maxdownspeed.info=Velocidade M\u00e1x de transfer\u00eancia por torrent
 ConfigView.section.tracker.passwordwebhttpsonly=Permitir apenas acesso via HTTPS
@@ -1306,8 +1290,6 @@ MyShares.column.category=Categoria
 MainWindow.menu.file.restart=Reiniciar Vuze
 MainWindow.dialog.restartconfirmation.title=Reiniciar Vuze
 MainWindow.dialog.restartconfirmation.text=Deseja mesmo reiniciar o Vuze
-deletetorrent.message1=Est\u00e1 prestes a apagar o TORRENT para :\n
-deletetorrent.message2=\nTem a certeza que deseja continuar?
 ConfigView.label.prioritizemostcompletedfiles=Dar prioridade aos ficheiros com prioridade alta de acordo com a % e o tamanho do ficheiro
 splash.plugin.init=A inicializar extens\u00e3o: 
 ConfigView.section.style.osx_small_fonts=Usar fontes pequenas [requer reinicio]
@@ -1465,7 +1447,6 @@ MainWindow.menu.file.open.torrentfortracking=Ficheiro Torrent... (Apenas Trackin
 MyTrackerView.date_added=Adicionado
 ConfigView.section.tracker.portbackup=Portas de Backup (';' separado)
 ConfigView.label.playfilespeech=Falar quando um ficheiro \u00e9 terminado
-ConfigView.label.playfilespeech.info=Os Servi\u00e7os de Fala actualmente funcionam melhor em Ingl\u00eas
 ConfigView.label.playfilefinished=Tocar um som quando um ficheiro \u00e9 terminado
 ConfigView.label.backupconfigfiles=Guardar ficheiros de recupera\u00e7\u00e3o para prop\u00f3sitos de restauro
 ConfigView.section.tracker.client.scrapesingleonly=Desactivar a agrega\u00e7\u00e3o per-tracker scrape (pode ajudar com trackers que informam  'URL demasiado comprido' (414) erros) 
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties b/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
index ca81535..22e3b8e 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ro_RO.properties
@@ -1,21 +1,21 @@
-#There is a plugin to help with internationalizing these bundles at http://azureus.sourceforge.net/plugin_list.php
-MainWindow.menu.file.open.torrent=Fi\u0219ier Torent...
-Main.parameter.usage=Folosire: java org.gudy.azureus2.cl.Main [parametri] "fi\u0219ier.torrent" "calea de salvare"
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=Fil\u0103 Torent...
+Main.parameter.usage=Folosire: java org.gudy.azureus2.cl.Main [parametri] "fila.torrent" "calea de salvare"
 Main.parameter.maxUploads=Nr. max de \u00eenc\u0103rc\u0103ri simultane
 Main.parameter.maxSpeed=Viteza max de \u00eenc\u0103rcare \u00een bai\u021bi/sec
-MainWindow.menu.file=&Fi\u0219ier
+MainWindow.menu.file=&Fil\u0103
 MainWindow.menu.file.open=&Deschide
 MainWindow.menu.file.create=Torent &Nou...
-MainWindow.menu.file.create.fromfile=Dintr-un &Fi\u0219ier
+MainWindow.menu.file.create.fromfile=Dintr-o &Fil\u0103
 MainWindow.menu.file.create.fromdir=Dintr-un &Dosar
 MainWindow.menu.file.export=&Export\u0103 Torentul \u00een XML...
 MainWindow.menu.file.import=&Import\u0103 Torentul din XML...
 MainWindow.menu.file.closetab=\u00cenchide &Tabul
 MainWindow.menu.file.closewindow=\u00cenchide &Fereastra
 MainWindow.menu.file.exit=&Ie\u0219i
-MainWindow.dialog.choose.file=Alege\u021bi fi\u0219ierul torent
+MainWindow.dialog.choose.file=Alege fila torent
 MainWindow.menu.file.folder=D&osar...
-MainWindow.dialog.choose.folder=Alege\u021bi dosarul ce con\u021bine fi\u0219ierele torent
+MainWindow.dialog.choose.folder=Alege dosarul ce con\u021bine filele torent
 MainWindow.menu.view=&Vezi
 MainWindow.menu.view.show=Afi\u0219eaz\u0103
 MainWindow.menu.view.mytorrents=Torentele &Mele
@@ -36,20 +36,17 @@ MainWindow.menu.help=A&jutor
 MainWindow.menu.help.about=Despre Vuze
 MainWindow.menu.torrent=Torent
 MainWindow.about.title=Despre
-MainWindow.about.section.developers=Programatori
-MainWindow.about.section.translators=Traduc\u0103tori
 MainWindow.about.section.system=Sistem
 MainWindow.about.section.internet=Pe Internet
 MainWindow.about.internet.homepage=Situl Vuze
 MainWindow.about.internet.sourceforge=Pagina Proiectului de la Sourceforge
-MainWindow.about.internet.sourceforgedownloads=Desc\u0103rc\u0103ri de la Sourceforge
 MainWindow.about.internet.bugreports=Raport\u0103ri de Buguri
 MainWindow.about.internet.forumdiscussion=Forumuri
 MainWindow.about.internet.wiki=Wiki \u0219i FAQ Vuze
-MainWindow.dialog.choose.savepath=Alege\u021bi calea de salvare
-MainWindow.dialog.choose.savepath_forallfiles=Alege\u021bi calea de salvare pentru TOATE fi\u0219ierele
+MainWindow.dialog.choose.savepath=Alege calea de salvare
+MainWindow.dialog.choose.savepath_forallfiles=Alege calea de salvare pentru TOATE filele
 MainWindow.status.latestversion=Ultima
-MainWindow.status.latestversion.clickupdate=Clica\u021bi pentru actualizare
+MainWindow.status.latestversion.clickupdate=Clicheaz\u0103 pentru actualizare
 MainWindow.status.unknown=necunoscut
 MainWindow.status.checking=verific
 MyTorrentsView.mytorrents=Torentele Mele
@@ -94,20 +91,21 @@ SystemTray.menu.show=Ara&t\u0103 Vuze
 PeersView.ip=Adresa IP
 PeersView.ip.info=IP-ul partenerului
 PeersView.port.info=Portul folosit
-PeersView.T.info=L (local): conexiune realizat\u0103 de dv., D (distant): conexiune realizat\u0103 de partener
-PeersView.T.L.tooltip=Conexiune realizat\u0103 de dv.
+PeersView.T.info=L (local): conexiune realizat\u0103 de tine, D (distant): conexiune realizat\u0103 de partener
+PeersView.T.L.tooltip=Conexiune realizat\u0103 de tine
 PeersView.T.R.tooltip=Conexiune realizat\u0103 de partener
 PeersView.I1=I (Interesant la partener)
-PeersView.I1.info=S\u00eente\u021bi interesat de ceea ce are partenerul?
+PeersView.I1.info=E\u0219ti interesat de ceea ce are partenerul?
 PeersView.C1=L (Limitat de partener)
-PeersView.C1.info=Dac\u0103 partenerul v\u0103 \u00eempiedic\u0103 sau nu s\u0103 desc\u0103rca\u021bi
+PeersView.C1.info=Dac\u0103 partenerul te \u00eempiedic\u0103 sau nu s\u0103 descarci
 PeersView.pieces=P\u0103r\u021bi
 PeersView.downloadspeed=Desc\u0103rcare
 PeersView.download=Desc\u0103rcat
+PeersView.download.info=Desc\u0103rcarea total\u0103 f\u0103cut\u0103 de la partener.
 PeersView.I2=I (Partenerul e interesat)
-PeersView.I2.info=E interesat partenerul de ceea ce ave\u021bi?
+PeersView.I2.info=Este interesat partenerul de ceea ce ai?
 PeersView.C2=L (Limitez partenerul)
-PeersView.C2.info=Dac\u0103 bloca\u021bi sau nu desc\u0103rcarea de c\u0103tre partener
+PeersView.C2.info=Dac\u0103 blochezi sau nu desc\u0103rcarea de c\u0103tre partener
 PeersView.uploadspeed=\u00cenc\u0103rcare
 PeersView.uploadspeed.info=Viteza de \u00eenc\u0103rcare c\u0103tre partener.
 PeersView.upload=\u00cenc\u0103rcare
@@ -123,20 +121,20 @@ PeersView.menu.snubbed=&Ignorat
 PeersView.title.short=Parteneri
 PeersView.title.full=Parteneri
 AllPeersView.title.full=To\u021bi Partenerii
-ConfigView.section.files=Fi\u0219iere
+ConfigView.section.files=File
 ConfigView.label.usefastresume=Folose\u0219te Modul de Reluare Rapid\u0103
-ConfigView.label.incrementalfile=Activeaz\u0103 crearea gradat\u0103 a fi\u0219ierelor (necesar pentru FAT32 sub Linux)
+ConfigView.label.incrementalfile=Activeaz\u0103 crearea gradat\u0103 a filelor (necesar pentru FAT32 sub Linux)
 ConfigView.label.defaultsavepath=Salveaz\u0103 \u00een dosarul implicit
 ConfigView.button.browse=&Exploreaz\u0103...
-ConfigView.dialog.choosedefaultsavepath=Alege\u021bi dosarul implicit de salvare
+ConfigView.dialog.choosedefaultsavepath=Alege dosarul implicit de salvare
 ConfigView.section.server=Conexiune
 ConfigView.section.global=Generale
 ConfigView.label.disconnetseed=La donare, deconecteaz\u0103 ceilal\u021bi donori
 ConfigView.label.switchpriority=Comut\u0103 automat la prioritate sc\u0103zut\u0103 \u00een timpul don\u0103rii
 ConfigView.label.maxdownloads=Nr. max. de desc\u0103rc\u0103ri simultane [0:nelimitat]\n - Nu poate fi mai mare dec\u00eet num\u0103rul maxim de torente active
-ConfigView.label.maxdownloads.tooltip=Ve\u021bi putea desc\u0103rca \u00eentotdeauna num\u0103rul de torente specificat aici, cu o singur\u0103 excep\u021bie, anume: \nAtunci c\u00eend un torent terminat satisface criteriul de Prim\u0103 Prioritate, el ar putea prelua un slot de desc\u0103rcare activ\u0103 dac\u0103 este absolut necesar.
-ConfigView.label.maxactivetorrents=Nr. max. de torente active [0: nelimitat]\n - Torentele noi nu vor mai porni dac\u0103 desc\u0103rca\u021bi/dona\u021bi mai mult
-ConfigView.label.priorityExtensions=Prioritizeaz\u0103 automat fi\u0219ierele cu extensiile \n - de ex: .txt;.nfo;.jpg
+ConfigView.label.maxdownloads.tooltip=Vei putea desc\u0103rca \u00eentotdeauna num\u0103rul de torente specificat aici, cu o singur\u0103 excep\u021bie, anume: \nAtunci c\u00eend un torent terminat satisface criteriul de Prim\u0103 Prioritate, el ar putea prelua un slot de desc\u0103rcare activ\u0103 dac\u0103 este absolut necesar.
+ConfigView.label.maxactivetorrents=Nr. max. de torente active [0: nelimitat]\n - Torentele noi nu vor mai porni dac\u0103 descarci/donezi mai mult
+ConfigView.label.priorityExtensions=Prioritizeaz\u0103 automat filele cu extensiile \n - de ex: .txt;.nfo;.jpg
 ConfigView.section.transfer=Transferuri
 ConfigView.label.maxuploads=Nr. max. de sloturi de \u00eenc\u0103rcare per torent
 ConfigView.label.maxuploadspeed=KB/s viteza max. global\u0103 de \u00eenc\u0103rcare [0: nelimitat\u0103]
@@ -146,23 +144,23 @@ ConfigView.section.display=Afi\u0219aj
 ConfigView.label.opendetails=Deschide automat tabelul cu detalii
 ConfigView.label.openbar=Deschide automat Bara de Desc\u0103rcare
 ConfigView.label.use_old_speed_menus=Folose\u0219te meniurile de vitez\u0103 cu stilul vechi (repornirea e necesar\u0103)
-ConfigView.label.closetotray=\u00cenchide \u00een Sistaler [System Tray]
-ConfigView.label.minimizetotray=Minimizeaz\u0103 \u00een Sistaler
+ConfigView.label.closetotray=\u00cenchide \u00een Sertar [System Tray]
+ConfigView.label.minimizetotray=Minimizeaz\u0103 \u00een Sertar
 ConfigView.section.general=Generale
 ConfigView.section.start=Pornire
 ConfigView.label.showsplash=Arat\u0103 ecranul de prezentare
-ConfigView.label.autoupdate=Deschide dialogul de Promovare [Upgrade] c\u00eend e disponibil\u0103 o versiune nou\u0103
+ConfigView.label.autoupdate=Deschide dialogul de Supragradare [Upgrade] c\u00eend e disponibil\u0103 o versiune nou\u0103
 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://wiki.vuze.com/index.php/Rules_for_IRC
+ConfigView.label.ircwiki=Citi\u021bi http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC
 ConfigView.label.ircchannel=Canal
 ConfigView.label.irclogin=Porecl\u0103
 ConfigView.group.irctitle=Set\u0103ri IRC
 ConfigView.boolean.ircsendinfo=Permite trimiterea (anonim\u0103) a set\u0103rilor proprii c\u0103tre\n operatorii canalului pentru a-i ajuta sa-mi ofere asisten\u021b\u0103
 ConfigView.boolean.irclog=Activeaz\u0103 jurnalizarea (\u00eenregistrarea) activit\u0103\u021bii canalului (\u00een IRC_log.htm)
 ConfigView.section.security=Securitate
-ConfigView.label.password=Proteja\u021bi Vuze folosind o parol\u0103\n - Va fi cerut\u0103 la restaurare (din minimizare) \u0219i la pornire.
+ConfigView.label.password=Protejeaz\u0103 Vuze folosind o parol\u0103\n - Va fi cerut\u0103 la restaurarea din minimizare \u0219i la pornire.
 ConfigView.label.passwordconfirm=Parol\u0103 (confirmare)
 ConfigView.label.passwordmatch=Parola activat\u0103:
 ConfigView.label.passwordmatchnone=Nu
@@ -181,7 +179,7 @@ FileItem.high=\u00eenalt\u0103
 FileItem.donotdownload=Nu desc\u0103rca
 FileItem.delete=\u0218terge
 FilesView.name=Nume
-FilesView.name.fastRename=Redenumire Rapid\u0103
+FilesView.name.fastRename=Renumire Rapid\u0103
 FilesView.size=M\u0103rime
 FilesView.done=Realizat
 FilesView.firstpiece=Nr. Primei P\u0103r\u021bi
@@ -194,10 +192,10 @@ FilesView.menu.setpriority=&Seteaz\u0103 Prioritatea
 FilesView.menu.setpriority.high=&\u00cenalt\u0103
 FilesView.menu.setpriority.normal=&Normal\u0103
 FilesView.menu.setpriority.skipped=Nu &desc\u0103rca
-FilesView.title.short=Fi\u0219iere
-FilesView.title.full=Fi\u0219iere
+FilesView.title.short=File
+FilesView.title.full=File
 GeneralView.section.downloaded=Desc\u0103rcat
-GeneralView.label.status.file=Starea Fi\u0219ierului
+GeneralView.label.status.file=Starea Filei
 GeneralView.label.status.pieces=Starea P\u0103r\u021bii
 GeneralView.section.availability=Disponibilitate
 GeneralView.label.status.pieces_available=Starea P\u0103r\u021bilor
@@ -214,22 +212,22 @@ GeneralView.label.uploaded=\u00cenc\u0103rcat :
 GeneralView.label.uploadspeed=Viteza de \u00cenc\u0103rcare :
 GeneralView.label.seeds=Donatori :
 GeneralView.label.peers=Parteneri:
-GeneralView.label.completed=Terminate : 
+GeneralView.label.completed=Terminate :
 GeneralView.label.totalspeed=Viteza Roiului :
-GeneralView.label.totalspeed.tooltip=Viteza total\u0103 (\u0219i medie) a tuturor partenerilor la care s\u00eente\u021bi conectat.
+GeneralView.label.totalspeed.tooltip=Viteza total\u0103 (\u0219i medie) a tuturor partenerilor la care e\u0219ti conectat.
 GeneralView.label.averagespeed=medie
-GeneralView.label.filename=Nume : 
+GeneralView.label.filename=Nume :
 GeneralView.label.totalsize=M\u0103rime Total\u0103 :
 GeneralView.label.savein=Salveaz\u0103 \u00een:
 GeneralView.label.hash=Ha\u0219 :
-GeneralView.label.numberofpieces=Nr. de P\u0103r\u021bi : 
+GeneralView.label.numberofpieces=Nr. de P\u0103r\u021bi :
 GeneralView.label.size=M\u0103rime:
 GeneralView.label.tracker=Starea Trackerului :
 GeneralView.label.updatein=Actualizare \u00een:
 GeneralView.label.trackerurl=Adresa Trackerului :
 GeneralView.label.trackerurlupdate=Actualizeaz\u0103 Trackerul
-GeneralView.label.comment=Comentariul Produc\u0103torului: 
-GeneralView.label.user_comment=Comentariul Utilizatorului: 
+GeneralView.label.comment=Comentariul Produc\u0103torului:
+GeneralView.label.user_comment=Comentariul Utilizatorului:
 GeneralView.label.status=Stare :
 ManagerItem.waiting=A\u0219tept
 ManagerItem.allocating=Aloc
@@ -255,10 +253,10 @@ PiecesView.title.short=P\u0103r\u021bi
 PiecesView.title.full=P\u0103r\u021bi
 SystemTray.tooltip.seeding=%1 don\u0103ri,
 SystemTray.tooltip.downloading=%1 desc\u0103rc\u0103ri,
-DownloadManager.error.filenotfound=Fi\u0219ier Neg\u0103sit
-DownloadManager.error.fileempty=Fi\u0219ierul torent e gol
-DownloadManager.error.filetoobig=Fi\u0219ierul torent e prea mare
-DownloadManager.error.filewithouttorrentinfo=Din fi\u0219ier lipsesc informa\u021biile torentului!
+DownloadManager.error.filenotfound=Fil\u0103 Neg\u0103sit\u0103
+DownloadManager.error.fileempty=Fila torent e goal\u0103
+DownloadManager.error.filetoobig=Fila torent e prea mare
+DownloadManager.error.filewithouttorrentinfo=Din fil\u0103 lipsesc informa\u021biile torentului!
 DownloadManager.error.unsupportedencoding=Codare Nesuportat\u0103
 DownloadManager.error.ioerror=Eroare I/O
 DownloadManager.error.sha1=Eroare: Nu exist\u0103 un asemenea Algoritm (SHA1)
@@ -269,12 +267,12 @@ PeerManager.status.finishedin=Terminat \u00een
 MainWindow.upgrade.assistant=Asistent de Actualizare
 MainWindow.upgrade.newerversion=Exist\u0103 o versiune mai nou\u0103 de Vuze disponibil\u0103 pentru desc\u0103rcare
 MainWindow.upgrade.explanation=Asistentul va desc\u0103rca versiunea nou\u0103 \u00een dosarul de instalare Vuze \u0219i va reporni softul
-MainWindow.upgrade.explanation.manual=Pute\u021bi actualiza manual softul \u00eenchiz\u00eend Vuze, desc\u0103rc\u00eend versiunea nou\u0103 \u0219i apoi repornind softul
-MainWindow.upgrade.step1=Pasul 1: Desc\u0103rca\u021bi noua versiune
-MainWindow.upgrade.step2=Pasul 2: \u00cenchide\u021bi versiunea curent\u0103 \u0219i porni\u021bi noua versiune de Vuze
+MainWindow.upgrade.explanation.manual=Po\u021bi actualiza manual softul \u00eenchiz\u00eend Vuze, desc\u0103rc\u00eend versiunea nou\u0103 \u0219i apoi repornind softul
+MainWindow.upgrade.step1=Pasul 1: Descarc\u0103 versiunea nou\u0103
+MainWindow.upgrade.step2=Pasul 2: \u00cenchide versiunea curent\u0103 \u0219i porne\u0219te versiunea nou\u0103 de Vuze
 MainWindow.upgrade.hint1=Pont:\tAp\u0103s\u00eend pe "Finalizeaz\u0103" duce la executarea automat\u0103
-MainWindow.upgrade.hint2=Pont:\tDaca dori\u021bi s\u0103 \u00eenchide\u021bi Vuze mai t\u00eerziu, ap\u0103sa\u021bi pe "Anuleaz\u0103" \u0219i\n\t schimba\u021bi numele din Azureus2-new.jar \u00een Azureus2.jar dup\u0103 \u00eenchidere
-MainWindow.upgrade.error.downloading.hint=Eroare:\tNu am putut desc\u0103rca versiunea nou\u0103, actualiza\u021bi manual softul
+MainWindow.upgrade.hint2=Pont:\tDaca vrei s\u0103 \u00eenchizi Vuze mai t\u00eerziu, apas\u0103 pe "Anuleaz\u0103" \u0219i schimb\u0103 numele din Azureus2-new.jar \u00een Azureus2.jar dup\u0103 \u00eenchidere
+MainWindow.upgrade.error.downloading.hint=Eroare:\tNu am putut desc\u0103rca versiunea nou\u0103, actualizeaz\u0103 manual softul
 MainWindow.upgrade.section.info=Versiune Nou\u0103 Disponibil\u0103
 MainWindow.upgrade.section.manual=Actualizare Manual\u0103
 MainWindow.upgrade.section.automatic=Actualizare automata
@@ -282,11 +280,11 @@ MainWindow.upgrade.tooltip.progressbar=Progresul desc\u0103rc\u0103rii va fi pre
 Button.next=Urm\u0103torul
 Button.finish=Finalizeaz\u0103
 Button.cancel=&Anuleaz\u0103
-LocaleUtil.title=Alege\u021bi Codarea
-LocaleUtil.section.chooseencoding=Alege\u021bi codarea pentru numele fi\u0219ierului
-LocaleUtil.label.chooseencoding=Selecta\u021bi codarea cea mai potrivit\u0103
+LocaleUtil.title=Alege Codarea
+LocaleUtil.section.chooseencoding=Alege codarea pentru fil\u0103
+LocaleUtil.label.chooseencoding=Selecteaz\u0103 codarea cea mai potrivit\u0103
 LocaleUtil.label.hint.doubleclick=Pont: dublu-clic pe un r\u00eend alege codificarea \u0219i \u00eenchide dialogul
-LocaleUtil.label.checkbox.rememberdecision=Memoreaz\u0103 decizia pentru restul de nume de fi\u0219iere
+LocaleUtil.label.checkbox.rememberdecision=Memoreaz\u0103 decizia pentru restul de file
 LocaleUtil.column.encoding=Codare
 IrcClient.defaultChannel=Canalul #Azureus-Users
 IrcClient.copyright=Folosesc PircBot Java IRC API - http://www.jibble.org/pircbot.php
@@ -302,21 +300,19 @@ IrcClient.hasleft=a plecat
 IrcClient.nowknown=e acum cunoscut ca
 IrcClient.topicforchannel=Topic pentru canal
 IrcClient.disconnected=Deconectat de la
-IrcClient.noNick=Nu a\u021bi specificat o porecl\u0103. Merge\u021bi la "Op\u021biuni" pentru a o face.
+IrcClient.noNick=Nu ai specificat o porecl\u0103. Mergi la "Op\u021biuni" pentru a o face.
 IrcView.actionnotsupported=Ac\u021biunea nu e suportat\u0103
 IrcView.clientsconnected=utilizatori
 IrcView.privateto=La
 IrcView.privatefrom=De la
 IrcView.noticefrom=Noti\u021b\u0103 :
 IrcView.errormsg=Sintax\u0103 incorect\u0103 la /msg : /msg text utilizator
-IrcView.help=Comenzi valide s\u00eent: \n . /help : afi\u0219eaza acest mesaj\n . /nick | /name : schimb\u0103 porecla sau numele \n . /me action : trimite o ac\u021biune \n . /msg nick message : trimite un mesaj privat c\u0103tre <nick>\n . /r message : r\u0103spunde la ultimul mesaj privat\n . /join #channel : al\u0103turare la un nou canal
+IrcView.help=Comenzi valide s\u00eent: \n . /help : afi\u0219eaza acest mesaj\n . /nick | /name : schimb\u0103 porecla sau numele \n . /me action : trimite o ac\u021biune \n . /msg nick message : trimite un mesaj privat c\u0103tre <nick>\n . /r message : r\u0103spunde la ultimul mesaj privat\n . /join #channel : al\u0103tur\u0103-te la un canal nou
 PasswordWindow.title=Vuze e z\u0103vor\u00eet
-PasswordWindow.passwordprotected=Vuze e protejat cu parol\u0103.\nPentru a ar\u0103ta fereastra Vuze, introduce\u021bi parola aici :
-TrackerChangerWindow.title=Adaug\u0103 Tracker
-TrackerChangerWindow.newtracker=Introduce\u021bi adresa noului tracker
+PasswordWindow.passwordprotected=Vuze e protejat cu parol\u0103.\nPentru a ar\u0103ta fereastra Vuze, introdu parola aici :
 PeersView.discarded=Abandonate
 PeersView.discarded.info=Date primite, dar \u00eenl\u0103turate ca nefiind necesare.
-discarded=anula\u021bi
+discarded=anulat
 MyTorrentsView.#=Nr
 MyTorrentsView.menu.move=&Mut\u0103
 MyTorrentsView.menu.moveUp=&Sus
@@ -335,30 +331,30 @@ wizard.next=\u00cenainte >
 wizard.finish=Finalizeaz\u0103
 wizard.mode=Tracker / Mod
 wizard.invalidurl=Adresa nu este valid\u0103
-wizard.singlefile=Fi\u0219ier unic
-wizard.singlefile.help=Creeaz\u0103 un torent dintr-un singur fi\u0219ier
+wizard.singlefile=Fil\u0103 unic\u0103
+wizard.singlefile.help=Creeaz\u0103 un torent dintr-o singur\u0103 fil\u0103
 wizard.directory=Dosar
 wizard.directory.help=Creeaz\u0103 un torent dintr-un dosar
-wizard.choosefile=Alege\u021bi un Fi\u0219ier
-wizard.file=Fi\u0219ier :
+wizard.choosefile=Alege o Fil\u0103
+wizard.file=Fil\u0103 :
 wizard.browse=Exploreaz\u0103...
-wizard.choosedirectory=Alege\u021bi un Dosar
-wizard.invalidfile=Fi\u0219ier Invalid!
+wizard.choosedirectory=Alege un Dosar
+wizard.invalidfile=Fil\u0103 Nevalid\u0103!
 wizard.invaliddirectory=Dosar Invalid!
-wizard.torrentFile=Fi\u0219ier Torent
-wizard.choosetorrent=Alege\u021bi fi\u0219ierul torentul de creat
+wizard.torrentFile=Fil\u0103 Torent
+wizard.choosetorrent=Alege fila torentul de creat
 wizard.information=Informa\u021bie
 wizard.notimplemented=Neimplementat \u00eenc\u0103
-wizard.progresstitle=Creez Fi\u0219ierul Torent
-wizard.savingfile=Salvez Fi\u0219ierul...
-wizard.filesaved=Fi\u0219ier salvat.
+wizard.progresstitle=Creez Fila Torent
+wizard.savingfile=Salvez Fila...
+wizard.filesaved=Fil\u0103 salvat\u0103.
 wizard.close=\u00cenchide
-Torrent.create.progress.piecelength=Lungimea p\u0103r\u021bii: 
-Torrent.create.progress.piececount=Num\u0103rul de p\u0103r\u021bi: 
-Torrent.create.progress.totalfilesize=M\u0103rimea total\u0103 a fi\u0219ierului: 
-Torrent.create.progress.totalfilecount=Num\u0103rul total de fi\u0219iere: 
-Torrent.create.progress.parsingfiles=Parsez fi\u0219ierele
-Torrent.create.progress.hashing=Ha\u0219ez fi\u0219ierele
+Torrent.create.progress.piecelength=Lungimea p\u0103r\u021bii:
+Torrent.create.progress.piececount=Num\u0103rul de p\u0103r\u021bi:
+Torrent.create.progress.totalfilesize=M\u0103rimea total\u0103 a filei:
+Torrent.create.progress.totalfilecount=Num\u0103rul total de file:
+Torrent.create.progress.parsingfiles=Parsez filele
+Torrent.create.progress.hashing=Ha\u0219ez filele
 MainWindow.upgrade.downloadingfrom=Descarc de la :
 MainWindow.menu.view.ipFilter=Filtre &IP
 ConfigView.section.ipfilter=Filtre IP
@@ -373,26 +369,28 @@ ConfigView.section.ipfilter.editFilter=Editeaz\u0103 Filtrul
 ConfigView.section.ipfilter.enable=Activeaz\u0103
 PeersView.menu.close=\u00cenc&hide
 seedmore.title=Torentul nu este donat suficient
-seedmore.shareratio=Raportul  de partajare [share ratio] al dv. pentru acest torent este
-seedmore.uploadmore=Nu e bine pentru re\u021beaua BT s\u0103 ave\u021bi un raport de partajare sub 100%. \nAr trebui s\u0103 dona\u021bi acest torent \u00eenc\u0103 o perioad\u0103 de timp.\nSigur dori\u021bi s\u0103 continua\u021bi?
+seedmore.shareratio=Raportul de partajare [share ratio] al t\u0103u pentru acest torent este
+seedmore.uploadmore=Nu e bine pentru re\u021beaua BitTorrent s\u0103 ai un raport de partajare sub 100%. \nAr trebui s\u0103 donezi acest torent \u00eenc\u0103 o perioad\u0103 de timp.\nSigur vrei s\u0103 continui?
 ConfigView.label.showpopuponclose=Cere confirmare la oprirea don\u0103rii c\u00eend raportul de partajare e mai mic de 1
 ConfigView.label.startNumSeeds=\nDoneaz\u0103 dac\u0103 e mai mic de\n - Ignor\u0103 celelalte reguli
 ConfigView.label.seeds=donatori
 ConfigView.section.seeding=Donare
-MyTorrentsView.menu.removeand=\u0218&terge
+#Used by the webui plugin
 MyTorrentsView.menu.removeand.deletetorrent=\u0218terge &Torentul
-MyTorrentsView.menu.removeand.deletedata=\u0218terge &Fi\u0219ierele Desc\u0103rcate
-MyTorrentsView.menu.removeand.deleteboth=\u0218terge Torentul \u0219i Fi\u0219ierele &Desc\u0103rcate
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletedata=\u0218terge &Filele Desc\u0103rcate
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=\u0218terge Torentul \u0219i Filele &Desc\u0103rcate
 deletedata.title=!!! Avertisment !!!
-deletedata.message1=Sigur dori\u021bi s\u0103 \u0219terge\u021bi fi\u0219ierele desc\u0103rcate ale torentului: '%1'?
+# used for more than just "delete data"
 deletedata.noprompt=Nu m\u0103 avertiza din nou
 MainWindow.menu.file.configure=&Vr\u0103jitor de Configurare
 configureWizard.title=Vr\u0103jitor de Configurare
-configureWizard.welcome.title=Bine a\u021bi venit la Vr\u0103jitorul de Configurare Vuze
-configureWizard.welcome.message=Acest vr\u0103jitor v\u0103 va ajuta s\u0103 configura\u021bi Vuze pentru o folosire obi\u0219nuit\u0103. Pentru o configurare avansat\u0103 folosi\u021bi meniul Unelte>Op\u021biuni.
+configureWizard.welcome.title=Bine ai venit la Vr\u0103jitorul de Configurare Vuze
+configureWizard.welcome.message=Acest vr\u0103jitor te va ajuta s\u0103 configurezi Vuze pentru o folosire obi\u0219nuit\u0103. Pentru o configurare avansat\u0103 folose\u0219te meniul Unelte>Op\u021biuni.
 configureWizard.transfer.title=Configureaz\u0103 Transferurile \u0219i Conexiunea
-configureWizard.transfer.hint=Pont: Un pic sub viteza maxim\u0103 suportat\u0103 de linia dv. e setarea optim\u0103.
-configureWizard.transfer.message=Alege\u021bi o conexiune de mai jos. Lua\u021bi aminte c\u0103 o vitez\u0103 insuficient\u0103 de \u00eenc\u0103rcare va duce la viteze de desc\u0103rcare sc\u0103zute. Datorit\u0103 faptului c\u0103 viteza de \u00eenc\u0103rcare se m\u0103soara pe FIECARE torent desc\u0103rcat, \u00eencercarea de a desc\u0103rca simultan prea multe torente va face ca vitezele de desc\u0103rcare s\u0103 fie mici. Recomand\u0103m folosirea unei viteze de 5KB/s ca un minim  [...]
+configureWizard.transfer.hint=Pont: Un pic sub viteza maxim\u0103 suportat\u0103 de linia ta e setarea optim\u0103.
+configureWizard.transfer.message=Alege o conexiune de mai jos. Noteaz\u0103 c\u0103 o vitez\u0103 insuficient\u0103 de \u00eenc\u0103rcare va duce la viteze de desc\u0103rcare sc\u0103zute. Datorit\u0103 faptului c\u0103 viteza de \u00eenc\u0103rcare se m\u0103soara pe FIECARE torent desc\u0103rcat, \u00eencercarea de a desc\u0103rca simultan prea multe torente va face ca vitezele de desc\u0103rcare s\u0103 fie mici. Recomand\u0103m folosirea unei viteze de 5KB/s ca un minim NECESAR. Cu  [...]
 configureWizard.transfer.connection=Conexiune
 configureWizard.transfer.connection.0=Personalizat
 configureWizard.transfer.connection.2=adsl/cablu xxx/128 kbps
@@ -405,85 +403,83 @@ configureWizard.transfer.maxUpSpeed=Viteza Maxim\u0103 de \u00cenc\u0103rcare (K
 configureWizard.transfer.maxActiveTorrents=Nr. Max. Torente Active
 configureWizard.transfer.maxDownloads=Max Desc\u0103rc\u0103ri
 configureWizard.transfer.maxUploadsPerTorrent=Max \u00cenc\u0103rc\u0103ri per Torent
-configureWizard.nat.title=Portul NAT / Server
-configureWizard.nat.message=Pentru folosirea optim\u0103 a lui Vuze , este recomandat s\u0103 ave\u021bi calculatorul pe deplin accesibil dinspre internet. Aceast\u0103 unealt\u0103 v\u0103 permite s\u0103 testa\u021bi \u0219i/sau s\u0103 schimba\u021bi portul folosit pentru acceptarea conexiunilor intr\u00eende de la calculatoarele partenerilor.\n\nNOT\u0102: Aceast\u0103 unealt\u0103 testeaz\u0103 doar conexiunile TCP. Baza de Date Distribuit\u0103 [DHT] necesit\u0103 deasemenea conexi [...]
 configureWizard.nat.test=Testeaz\u0103
 configureWizard.nat.testing=Testez portul
 configureWizard.nat.ko=Eroare NAT
-configureWizard.nat.unable=Imposibil de testat: Portul dat e invalid sau testarea serviciului a e\u0219uat.\nE posibil ca o alt\u0103 aplica\u021bie s\u0103 foloseasc\u0103 portul.
-configureWizard.file.title=Torente / Fi\u0219iere
-configureWizard.file.message1=Vuze va salva torentele desc\u0103rcate \u00eentr-un dosar special, pe care \u00eel pute\u021bi alege aici:
+configureWizard.nat.unable=Imposibil de testat: Portul dat e nevalid sau testarea serviciului a e\u0219uat.\nE posibil ca o alt\u0103 aplica\u021bie s\u0103 foloseasc\u0103 portul.
+configureWizard.file.title=Torente / File
+configureWizard.file.message1=Vuze va salva torentele desc\u0103rcate \u00eentr-un dosar special, pe care \u00eel po\u021bi alege aici:
 configureWizard.file.path=Cale
 configureWizard.file.browse=Exploreaz\u0103
-configureWizard.file.message2=Vuze poate relua instantaneu fi\u0219ierele prin ad\u0103ugarea unor date de reluare la torente. Cu aceast\u0103 facilitate pute\u021bi relua \u0219i p\u0103r\u021bi desc\u0103rcate incomplet.
+configureWizard.file.message2=Vuze poate relua instantaneu filele prin ad\u0103ugarea unor date de reluare la torente. Cu aceast\u0103 facilitate po\u021bi relua \u0219i p\u0103r\u021bi desc\u0103rcate incomplet.
 configureWizard.file.fastResume=Activeaz\u0103 reluarea rapid\u0103
 configureWizard.file.invalidPath=Dosar invalid
 configureWizard.finish.title=Terminat
-configureWizard.finish.message=Vuze este acum configurat, bucura\u021bi-v\u0103 de el!
+configureWizard.finish.message=Vuze este acum configurat, bucur\u0103-te de el!
 wizard.close.confirmation=Confirmare
-wizard.close.message=Dori\u021bi \u00eenc\u0103rcarea acestui vr\u0103jitor la urm\u0103toarea pornire a programului?
+wizard.close.message=Vrei s\u0103 fie \u00eenc\u0103rcat acest vr\u0103jitor la urm\u0103toarea pornire a programului?
 exportTorrentWizard.title=Export\u0103 un torent XML
-exportTorrentWizard.torrentfile.title=Alege\u021bi torentul de exportat
-exportTorrentWizard.torrentfile.message=Selecta\u021bi fi\u0219ierul torent de exportat
+exportTorrentWizard.torrentfile.title=Alege torentul de exportat
+exportTorrentWizard.torrentfile.message=Selecteaz\u0103 fila torent de exportat
 exportTorrentWizard.torrentfile.path=Cale
 exportTorrentWizard.torrentfile.browse=Exploreaz\u0103
-exportTorrentWizard.torrentfile.invalidPath=Fi\u0219ier torent invalid
-exportTorrentWizard.exportfile.title=Selectarea Fi\u0219ierului de Export
-exportTorrentWizard.exportfile.message=Alege\u021bi fi\u0219ierul xml \u00een care s\u0103 se exporte
+exportTorrentWizard.torrentfile.invalidPath=Fil\u0103 torent nevalid\u0103
+exportTorrentWizard.exportfile.title=Selectarea Filei de Exportare
+exportTorrentWizard.exportfile.message=Alege fila xml \u00een care s\u0103 se exporte
 exportTorrentWizard.exportfile.path=Cale
 exportTorrentWizard.exportfile.browse=Exploreaz\u0103
-exportTorrentWizard.exportfile.invalidPath=Fi\u0219ier de export invalid
+exportTorrentWizard.exportfile.invalidPath=Fil\u0103 de exportare nevalid\u0103
 exportTorrentWizard.finish.title=Terminat
 exportTorrentWizard.finish.message=Exportare terminat\u0103 cu succes
-exportTorrentWizard.process.inputfilebad.title=Fi\u0219ier Torent Invalid
-exportTorrentWizard.process.inputfilebad.message=La accesarea fi\u0219ierului de importat a avut loc eroarea:
-exportTorrentWizard.process.outputfileexists.title=Fi\u0219ierul Exist\u0103
-exportTorrentWizard.process.outputfileexists.message=Fi\u0219ierul \u021bint\u0103 exist\u0103 deja - \u00eel suprascriu?
+exportTorrentWizard.process.inputfilebad.title=Fil\u0103 Torent Nevalid\u0103
+exportTorrentWizard.process.inputfilebad.message=La accesarea filei de importare a avut loc eroarea:
+exportTorrentWizard.process.outputfileexists.title=Fila Exist\u0103
+exportTorrentWizard.process.outputfileexists.message=Fila \u021bint\u0103 exist\u0103 deja - o suprascrii?
 exportTorrentWizard.process.torrentfail.title=E\u0219ec la citirea torentului
 exportTorrentWizard.process.exportfail.title=Exportul torentului a e\u0219uat!
 exportTorrentWizard.process.unknownfail.title=Eroare Nea\u0219teptat\u0103
 importTorrentWizard.title=Import\u0103 un torent din XML
-importTorrentWizard.torrentfile.title=Introduce\u021bi Selec\u021bia de Torente
-importTorrentWizard.torrentfile.message=Introduce\u021bi fi\u0219ierul torent \u00een care s\u0103 se importe
+importTorrentWizard.torrentfile.title=Introdu Selec\u021bia de Torente
+importTorrentWizard.torrentfile.message=Introdu fila torent \u00een care s\u0103 se importe
 importTorrentWizard.torrentfile.path=Adresa
 importTorrentWizard.torrentfile.browse=Exploreaz\u0103
-importTorrentWizard.torrentfile.invalidPath=Fi\u0219ier torent invalid
-importTorrentWizard.importfile.title=Import\u0103 Fi\u0219ierele Selectate
-importTorrentWizard.importfile.message=Alege\u021bi fi\u0219ierul xml de importat
+importTorrentWizard.torrentfile.invalidPath=Fil\u0103 torent nevalid\u0103
+importTorrentWizard.importfile.title=Import\u0103 Filele Selectate
+importTorrentWizard.importfile.message=Alege fila xml de importat
 importTorrentWizard.importfile.path=Cale
 importTorrentWizard.importfile.browse=Exploreaz\u0103
-importTorrentWizard.importfile.invalidPath=Fi\u0219ierul de importat e invalid
+importTorrentWizard.importfile.invalidPath=Fila de importat e nevalid\u0103
 importTorrentWizard.finish.title=Terminat
 importTorrentWizard.finish.message=Import realizat cu succes
-importTorrentWizard.process.inputfilebad.title=Fi\u0219ier de Importat Invalid
-importTorrentWizard.process.inputfilebad.message=A survenit un e\u0219ec la accesarea fi\u0219ierului introdus:
-importTorrentWizard.process.outputfileexists.title=Fi\u0219ierul Exist\u0103
-importTorrentWizard.process.outputfileexists.message=Fi\u0219ierul de ie\u0219ire exist\u0103 - \u00eel suprascriu?
+importTorrentWizard.process.inputfilebad.title=Fil\u0103 de Importat Nevalid\u0103
+importTorrentWizard.process.inputfilebad.message=A survenit un e\u0219ec la accesarea filei introduse:
+importTorrentWizard.process.outputfileexists.title=Fila Exist\u0103
+importTorrentWizard.process.outputfileexists.message=Fila de destina\u021bie exist\u0103 deja - o suprascriu?
 importTorrentWizard.process.torrentfail.title=E\u0219ec la scriere
 importTorrentWizard.process.importfail.title=E\u0219ec la importarea torentului
 importTorrentWizard.process.unknownfail.title=Eroare nea\u0219teptat\u0103
 ConfigView.label.bindip=Leag\u0103 la adresa IP local\u0103 sau la interfa\u021ba de conectare
-ConfigView.label.xfs.allocation=Aloc\u0103 fi\u0219ierele noi folosind o metod\u0103 specific\u0103 sistemului de fi\u0219iere XFS
-ConfigView.label.xfs.allocation.tooltip=Asigura\u021bi-v\u0103 c\u0103 /usr/sbin/xfs_io este instalat corespunz\u0103tor pe sistemul dv. \u00cen cele mai multe distribu\u021bii Linux el este inclus \u00een pachetul "xfsprogs".
-xfs.allocation.xfs_io.not.found=Alocarea fi\u0219ierului prin XFS a e\u0219uat din cauz\u0103 c\u0103 /usr/sbin/xfs_io nu poate fi rulat. Asigura\u021bi-v\u0103 c\u0103 este instalat corect pe sistemul dv. Eroarea original\u0103 era : "%1".
-ConfigView.label.zeronewfiles=Aloc\u0103 \u0219i umple cu zero fi\u0219ierele noi la creare
+ConfigView.label.xfs.allocation=Aloc\u0103 filele noi folosind o metod\u0103 specific\u0103 sistemului de file XFS
+ConfigView.label.xfs.allocation.tooltip=Asigur\u0103-te c\u0103 /usr/sbin/xfs_io este instalat corespunz\u0103tor pe sistemul t\u0103u. \u00cen cele mai multe distribu\u021bii Linux el este inclus \u00een pachetul "xfsprogs".
+xfs.allocation.xfs_io.not.found=Alocarea filei prin XFS a e\u0219uat din cauz\u0103 c\u0103 /usr/sbin/xfs_io nu poate fi rulat\u0103. Asigur\u0103-te c\u0103 este instalat\u0103 corect pe sistemul t\u0103u. Eroarea original\u0103 era : "%1".
+ConfigView.label.zeronewfiles=Aloc\u0103 \u0219i umple cu zero filele noi la creare
 ConfigView.label.zeronewfiles.tooltip=Reduce fragmentarea
 ConfigView.section.stats=Statistici
 ConfigView.section.stats.enable=Activeaz\u0103
 ConfigView.section.stats.defaultsavepath=Dosarul de salvare a statisticilor
-ConfigView.section.stats.choosedefaultsavepath=Alege\u021bi dosarul de salvare a statisticilor
+ConfigView.section.stats.choosedefaultsavepath=Alege dosarul de salvare a statisticilor
 ConfigView.section.stats.savefreq=Frecven\u021ba salv\u0103rii
 ConfigView.section.stats.hours=ore
-ConfigView.section.stats.savefile=Numele fi\u0219ierului cu statistici
+ConfigView.section.stats.savefile=Numele filei cu statistici
 ConfigView.section.stats.graph_update_dividers=Afi\u0219eaz\u0103 o linie vertical\u0103 la fiecare 60 de actualiz\u0103ri
 MyTorrentsView.menu.export=Torent &XML...
 MyTorrentsView.menu.host=&G\u0103zduie\u0219te...
 ManagerItem.finishing=Termin
-ConfigView.dialog.choosedefaulttorrentpath=Alege\u021bi dosarul implicit pentru torente
-ConfigView.dialog.choosemovepath=Alege\u021bi dosarul implicit \u00een care s\u0103 se fac\u0103 mutarea 
-ConfigView.label.movecompleted=Mut\u0103 fi\u0219ierele terminate (dup\u0103 desc\u0103rcare)
-ConfigView.label.moveremoved=Mut\u0103 fi\u0219ierele terminate (c\u00eend s\u00eent \u00eenl\u0103turate)
-ConfigView.label.savetorrents=Salveaz\u0103 fi\u0219ierele torent
+ConfigView.dialog.choosedefaulttorrentpath=Alege dosarul implicit pentru torente
+ConfigView.dialog.choosemovepath=Alege dosarul implicit \u00een care s\u0103 se fac\u0103 mutarea
+ConfigView.label.movecompleted=Mut\u0103 filele terminate (dup\u0103 desc\u0103rcare)
+ConfigView.label.moveremoved=Mut\u0103 filele terminate (c\u00eend s\u00eent \u00eenl\u0103turate)
+ConfigView.label.savetorrents=Salveaz\u0103 filele torent
 MainWindow.menu.view.mytracker=&Trackerul Meu
 MyTrackerView.title.full=Trackerul Meu
 MyTrackerView.name=Nume
@@ -498,18 +494,18 @@ MyTrackerView.downloaded=Desc\u0103rcat
 MyTrackerView.left=R\u0103mas
 ConfigView.section.style=Interfa\u021b\u0103
 ConfigView.label.set_ui_transfer_speeds=Ignor\u0103 vitezele de transfer selectabile
-ConfigView.label.set_ui_transfer_speeds.description=Pute\u021bi alege s\u0103 defini\u021bi manual vitezele de desc\u0103rcare \u0219i de \u00eenc\u0103rcare disponibile pe bara de stare din sistaler [system tray].\nValorile trebuie s\u0103 fie separate prin virgule.
+ConfigView.label.set_ui_transfer_speeds.description=Po\u021bi alege s\u0103 define\u0219ti manual vitezele de desc\u0103rcare \u0219i de \u00eenc\u0103rcare disponibile pe bara de stare din sertar [system tray].\nValorile trebuie s\u0103 fie separate prin virgule.
 ConfigView.label.set_ui_transfer_speeds.description.download=Seteaz\u0103 vitezele de desc\u0103rcare (\u00een KB/s)
 ConfigView.label.set_ui_transfer_speeds.description.upload=Seteaz\u0103 vitezele de \u00eenc\u0103rcare (\u00een KB/s)
 ConfigView.section.style.useCustomTabs=Folose\u0219te taburi ce pot fi \u00eenchise (necesit\u0103 repornire)
 MainWindow.menu.view.plugins=E&xtensii
-fileDownloadWindow.saveTorrentIn=Salveaz\u0103 fi\u0219ierul torent \u00een
+fileDownloadWindow.saveTorrentIn=Salveaz\u0103 fila torent \u00een
 fileDownloadWindow.title=Vuze - Desc\u0103rc\u0103tor de Torente
 fileDownloadWindow.downloading=Descarc de la :
 fileDownloadWindow.status=Stare :
 fileDownloadWindow.state_initializing=Ini\u021bializez
 fileDownloadWindow.state_downloading=Descarc
-fileDownloadWindow.state_error=Eroare: 
+fileDownloadWindow.state_error=Eroare:
 MainWindow.menu.file.open.url=&Loca\u021bia...
 openUrl.title=Deschide Loca\u021bia
 MyTorrentsView.menu.host.error.title=G\u0103zduirea torentului a e\u0219uat
@@ -523,8 +519,8 @@ IPChecker.external.service.dyndns.description=Dynamic DNS Network Services, SRL
 ConfigView.section.tracker.checkip=Descoper\u0103 automat adresa IP extern\u0103...
 ipCheckerWizard.title=Vr\u0103jitor de Verificare IP
 ipCheckerWizard.service=Serviciu
-ipCheckerWizard.chooseService=Alege\u021bi un serviciu de verificat IP-uri din lista afi\u0219at\u0103
-ipCheckerWizard.explanations=Folosi\u021bi acest vr\u0103jitor pentru a v\u0103 descoperi adresa IP extern\u0103. Dac\u0103 ave\u021bi o adres\u0103 IP dinamic\u0103, v\u0103 recomand\u0103m s\u0103 deschide\u021bi un cont la un Serviciu de DNS dinamic. C\u00eeteva dintre aceste servicii s\u00eent trecute mai jos. Folosi\u021bi leg\u0103turile \u0219i crea\u021bi-v\u0103 un cont (\u00een cazul \u00een care se poate). Apoi completa\u021bi c\u00eempul IP cu numele gazdei dv. dinamice (de e [...]
+ipCheckerWizard.chooseService=Alege un serviciu de verificat IP-uri din lista afi\u0219at\u0103
+ipCheckerWizard.explanations=Folose\u0219te acest vr\u0103jitor pentru a-\u021bi descoperi adresa IP extern\u0103. Dac\u0103 ai o adres\u0103 IP dinamic\u0103, \u00ee\u021bi recomand\u0103m s\u0103 deschizi un cont la un Serviciu de DNS dinamic. C\u00eeteva dintre aceste servicii s\u00eent trecute mai jos. Folose\u0219te leg\u0103turile \u0219i creeaz\u0103-\u021bi un cont (\u00een cazul \u00een care se poate). Apoi completeaz\u0103 c\u00eempul IP cu numele gazdei dinamice (de ex: gazdam [...]
 ipCheckerWizard.service.description=Descriere:
 ipCheckerWizard.service.url=Leg\u0103tur\u0103 :
 ipCheckerWizard.progresstitle=Verific IP
@@ -532,7 +528,7 @@ ipCheckerWizard.checkComplete=IP completat :
 ipCheckerWizard.checkFailed=E\u0219uat, motivul :
 wizard.tracker.local=Folose\u0219te trackerul \u00eencorporat \u00een Vuze
 wizard.tracker.external=Folose\u0219te un tracker extern
-wizard.tracker.howToLocal=\tMerge\u021bi la "Unelte">"Op\u021biuni">"Tracker" pentru activare
+wizard.tracker.howToLocal=\tMergi la "Unelte">"Op\u021biuni">"Tracker" pentru activare
 wizard.announceUrl=Adres\u0103 de Anun\u021bare :
 IPChecker.external.service.discoveryvip.url=ip.discoveryvip.com/
 IPChecker.external.service.discoveryvip.description=Discoveryvip - doar verificare a adresei IP
@@ -550,16 +546,16 @@ ConfigView.section.tracker.pollintervalincper=La fiecare "n" clien\u021bi
 splash.loadingImages=\u00cencarc Imaginile
 splash.initializeGui=Ini\u021bializez Fereastra Principal\u0103
 splash.openViews=Deschid Vederile
-splash.plugin=\u00cencarc Extensia : 
+splash.plugin=\u00cencarc Extensia :
 configureWizard.nat.tooManyPorts=Prea multe porturi de testat (max 9)
 ConfigView.section.color=Schema de Culori
 MyTorrentsView.menu.publish=Pub&lic\u0103...
 MyTrackerView.status.published=Publicat
 MyTrackerView.completed=Progres
-MainWindow.menu.file.open.torrentnodefault=Fi\u0219ier Torent... (F\u0103r\u0103 Salvare Implicit\u0103)
+MainWindow.menu.file.open.torrentnodefault=Fil\u0103 Torent... (F\u0103r\u0103 Salvare Implicit\u0103)
 wizard.comment=Comentariu
-ConfigView.label.movetorrent=Mut\u0103 Fi\u0219ierul Torent
-ConfigView.label.movepartialdownloads=Mut\u0103 chiar dac\u0103 anumite fi\u0219iere s\u00eent marcate "Nu Desc\u0103rca"
+ConfigView.label.movetorrent=Mut\u0103 Fila Torent
+ConfigView.label.movepartialdownloads=Mut\u0103 chiar dac\u0103 anumite file s\u00eent marcate "Nu Desc\u0103rca"
 ConfigView.label.subdir_is_in_default=Atunci c\u00eend se investigheaz\u0103 existen\u021ba unor desc\u0103rc\u0103ri \u00eentr-un anumit dosar, trebuie luate \u00een calcul \u0219i subdosarele acestuia
 ConfigView.section.file.decoder.label=Codarea implicit\u0103 a torentului c\u00eend selectarea e obligatorie
 ConfigView.section.file.decoder.nodecoder=Nimic
@@ -567,12 +563,11 @@ IPChecker.external.service.no-ip.url=www.no-ip.com/
 IPChecker.external.service.no-ip.description=Furnizor al serviciului DNS dinamic \u0219i static\n(serviciul 'verific\u0103 adresa' nu e disponibil gratuit)
 ConfigView.section.tracker.publicenable=Activeaz\u0103 torentele externe
 ConfigView.label.playdownloadspeech=Vorbe\u0219te c\u00eend s-a terminat o desc\u0103rcare
-ConfigView.label.playdownloadspeech.info=Serviciile de Vorbire merg momentan mai bine \u00een Englez\u0103
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=Afi\u0219eaz\u0103 num\u0103rul de copii disponibile pentru fiecare parte.\n\u00cen cazul \u00een care num\u0103rul din dreapta e mai mic de 1 \u00eenseamn\u0103 c\u0103 nu s-a g\u0103sit nici o copie \u00eentreag\u0103 (\u0219i e posibil s\u0103 ave\u021bi dificult\u0103\u021bi la terminarea desc\u0103rc\u0103rii).
-GeneralView.label.trackerurl.tooltip=Clica\u021bi pentru copierea adresei de anun\u021bare \u00een cliplan\u0219et\u0103
+GeneralView.label.status.pieces_available.tooltip=Afi\u0219eaz\u0103 num\u0103rul de copii disponibile pentru fiecare parte.\n\u00cen cazul \u00een care num\u0103rul din dreapta e mai mic de 1, \u00eenseamn\u0103 c\u0103 nu s-a g\u0103sit nici o copie \u00eentreag\u0103 (\u0219i e posibil s\u0103 ai dificult\u0103\u021bi la terminarea desc\u0103rc\u0103rii).
+GeneralView.label.trackerurl.tooltip=Clicheaz\u0103 pentru copierea adresei de anun\u021bare \u00een cliplan\u0219et\u0103
 GeneralView.label.trackerurlopen.tooltip=Clic pentru deschiderea paginii trackerului
 #
 # 2.0.4.4
@@ -583,18 +578,18 @@ ConfigView.section.style.graphicsUpdate=Actualizeaz\u0103 barele grafice la fiec
 ConfigView.section.style.reOrderDelay=Reordoneaz\u0103 tabelele la fiecare N actualiz\u0103ri ale GUI [0: niciodat\u0103]
 ConfigView.section.style.reOrderDelay.never=Niciodat\u0103
 ConfigView.section.logging=Jurnalizare
-ConfigView.section.logging.enable=Activeaz\u0103 jurnalizarea \u00eentr-un fi\u0219ier
-ConfigView.section.logging.logdir=Dosarul fi\u0219ierului jurnal
-ConfigView.section.logging.choosedefaultsavepath=Alege\u021bi dosarul de salvare
+ConfigView.section.logging.enable=Activeaz\u0103 jurnalizarea \u00eentr-o fil\u0103
+ConfigView.section.logging.logdir=Dosarul filei jurnal
+ConfigView.section.logging.choosedefaultsavepath=Alege dosarul de salvare
 GeneralView.label.updatein.querying=Interoghez...
 configureWizard.nat.sharePort=Folose\u0219te un singur port de intrare partajat de toate torentele
-ConfigView.section.logging.maxsize=M\u0103rimea maxim\u0103 a fi\u0219ierului jurnal
+ConfigView.section.logging.maxsize=M\u0103rimea maxim\u0103 a filei jurnal
 ConfigView.section.tracker.passwordenableweb=Activeaz\u0103 parol\u0103 pentru re\u021beaua trackerului
 ConfigView.section.tracker.passwordenabletorrent=Activeaz\u0103 parol\u0103 pentru torente
 ConfigView.section.tracker.username=Utilizator
 ConfigView.section.tracker.password=Parol\u0103
-columnChooser.title=Alege\u021bi coloanele de afi\u0219at
-columnChooser.move=Trage\u021bi r\u00eendurile ca s\u0103 le reordona\u021bi
+columnChooser.title=Alege coloanele afi\u0219ate
+columnChooser.move=Trage r\u00eendurile ca s\u0103 le reordonezi
 columnChooser.apply=Aplic\u0103
 columnChooser.columnname=Numele Coloanei
 columnChooser.columndescription=Descriere
@@ -605,31 +600,31 @@ authenticator.title=Necesit\u0103 Autentificare
 authenticator.realm=Domeniu
 authenticator.user=Utilizator
 authenticator.password=Parol\u0103
-ConfigView.label.allowSendVersion=Permite\u021bi ca Vuze s\u0103 trimit\u0103 \u00een mod anonim num\u0103rul versiunii \u0219i un identificator aleator la verificarea apari\u021biei versiunilor noi.
-ConfigView.label.version.info.link=Afla\u021bi detalii despre ce date s\u00eent trimise la serverul de verficare a versiunii
-wizard.hint.mode=Point:\tPute\u021bi trage \u0219i depune un singur fi\u0219ier sau dosar \u00een acest vr\u0103jitor pentru a alege un fi\u0219ier sau un dosar
-wizard.hint.file=Pont:\tPute\u021bi alege un singur fi\u0219ier prin tragere-\u0219i-depunere
-wizard.hint.directory=Pont:\tPute\u021bi alege un singur dosar prin tragere-\u0219i-depunere
+ConfigView.label.allowSendVersion=Permite ca Vuze s\u0103 trimit\u0103 \u00een mod anonim num\u0103rul versiunii \u0219i un identificator aleator la verificarea apari\u021biei versiunilor noi.
+ConfigView.label.version.info.link=Afl\u0103 detalii despre ce date s\u00eent trimise la serverul de verficare a versiunii
+wizard.hint.mode=Point:\tLa alegerea unei file sau unui dosar, po\u021bi trage \u0219i pune un singur element \u00een acest vr\u0103jitor
+wizard.hint.file=Pont:\tPo\u021bi alege o singur\u0103 fil\u0103 pentru tragere-\u0219i-punere
+wizard.hint.directory=Pont:\tPo\u021bi alege un singur dosar pentru tragere-\u0219i-punere
 MainWindow.menu.help.checkupdate=&Caut\u0103 Actualiz\u0103ri...
 TableColumn.header.down=Desc\u0103rcat
 TableColumn.header.up=\u00cenc\u0103rcat
 ConfigView.section.tracker.passwordenabletorrent.info=Necesit\u0103 un client BitTorrent potrivit (de ex. Vuze)
 ConfigView.section.style.confirmationOnExit=Arat\u0103 dialogul de confirmare la ie\u0219ire
 MainWindow.dialog.exitconfirmation.title=P\u0103r\u0103sesc Vuze?
-MainWindow.dialog.exitconfirmation.text=Sigur dori\u021bi s\u0103 p\u0103r\u0103si\u021bi Vuze?
+MainWindow.dialog.exitconfirmation.text=Sigur vrei s\u0103 \u00eenchizi Vuze?
 SystemTray.menu.stopalltransfers=&Opre\u0219te Transferurile
 TrayWindow.menu.stopalldownloads=Opre\u0219te To&ate Desc\u0103rc\u0103rile
 ConfigView.section.tracker.sslport.info=Vezi FAQ pentru alte informa\u021bii
 wizard.tracker.ssl=Folose\u0219te SSL
 ConfigView.label.playdownloadfinished=Emite un sunet c\u00eend desc\u0103rcarea s-a terminat
 ConfigView.label.popupdownloadfinished=Arat\u0103 o alert\u0103 popup la terminarea unei desc\u0103rc\u0103ri
-ConfigView.label.popupfilefinished=Arat\u0103 o alert\u0103 popup la terminarea unui fi\u0219ier
+ConfigView.label.popupfilefinished=Arat\u0103 o alert\u0103 popup la terminarea unei file
 TableColumn.header.pieces=P\u0103r\u021bi
-TableColumn.header.pieces.info=Bar\u0103 grafic\u0103 ar\u0103t\u00eend p\u0103r\u021bile pe care le-a\u021bi desc\u0103rcat
+TableColumn.header.pieces.info=Bar\u0103 grafic\u0103 ar\u0103t\u00eend p\u0103r\u021bile pe care le-ai desc\u0103rcat
 TableColumn.header.completion=Realizare
 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
+ConfigView.section.style.alwaysShowTorrentFiles=Arat\u0103 mereu filele torent \u00een Detalii/File
 wizard.multitracker=Adaug\u0103 la torent informa\u021bia despre Multi-Tracker
 wizard.multitracker.title=Tracker Multiplu
 wizard.multitracker.configuration=Configura\u021bia Multi-Trackerului
@@ -646,13 +641,13 @@ wizard.multitracker.edit.newtracker=Tracker Nou
 wizard.multitracker.edit.deletetracker=\u0218terge
 wizard.multitracker.edit.edit=Editeaz\u0103
 wizard.addingmt=Adaug Info Multi-Tracker
-wizard.multitracker.noannounce=Adresa de anun\u021bare nu apare \u00een lista dv. de trackere
+wizard.multitracker.noannounce=Adresa de anun\u021bare nu apare \u00een lista ta de trackere
 MyTorrentsView.menu.recheck=For\u021beaz\u0103 Re&verificarea
 iconBar.showDownloadBar.tooltip=Arat\u0103 Bara de Desc\u0103rcare
 iconBar.start.tooltip=Porne\u0219te
 iconBar.stop.tooltip=Opre\u0219te
 iconBar.remove.tooltip=\u0218terge
-iconBar.openNoDefault.tooltip=Deschide un fi\u0219ier torent (f\u0103r\u0103 salvare implicit\u0103)
+iconBar.openNoDefault.tooltip=Deschide o fil\u0103 torent (f\u0103r\u0103 salvare implicit\u0103)
 iconBar.openURL.tooltip=Deschide o Adres\u0103 (URL)
 iconBar.openFolder.tooltip=Deschide un Dosar
 iconBar.new.tooltip=Creeaz\u0103 Torent
@@ -661,11 +656,11 @@ iconBar.down.tooltip=Mut\u0103 \u00een Jos
 iconBar.run.tooltip=Deschide
 iconBar.host.tooltip=G\u0103zduie\u0219te
 iconBar.publish.tooltip=Public\u0103
-iconBar.editcolumns.tooltip=Alege\u021bi ce coloane s\u0103 fie afi\u0219ate
+iconBar.editcolumns.tooltip=Alege ce coloane s\u0103 fie afi\u0219ate
 MyTorrentsView.menu.editTracker=&Editeaz\u0103 Adresa Trackerului
 GeneralView.menu.selectTracker=Selecteaz\u0103
-ConfigView.section.stats.xslfile=Numele fi\u0219ierului XSL
-ConfigView.section.stats.xslfiledetails=Vor fi incluse \u00een antetul fi\u0219ierului cu statistici prin tagul <?xml-stylesheet>
+ConfigView.section.stats.xslfile=Numele filei XSL
+ConfigView.section.stats.xslfiledetails=Vor fi incluse \u00een antetul filei cu statistici prin tagul <?xml-stylesheet>
 ConfigView.label.savetorrentbackup=Salveaz\u0103 Copie de Rezerv\u0103
 ConfigView.section.tracker.forceport=For\u021beaz\u0103 torentele g\u0103zduite extern c\u0103tre portul implicit
 ConfigView.section.ipfilter.allow=PERMITE aceste intervale (implicit este INTERZICE)
@@ -673,7 +668,7 @@ ConfigView.section.ipfilter.list.inrange=era \u00een interval
 ConfigView.section.ipfilter.list.notinrange=nu era \u00een nici un interval
 ConfigView.section.ipfilter.list.title=Adrese IP blocate
 ConfigView.label.allowsameip=Permite conexiuni multiple de la aceea\u0219i adres\u0103 IP
-ConfigView.label.allowsameip.tooltip=Bifa\u021bi numai dac\u0103 e NEVOIE.\nC\u00eend e dezactivat\u0103 e o protec\u021bie anti-lipitori (utilizatori care nu \u00eencarc\u0103 date).
+ConfigView.label.allowsameip.tooltip=Bifeaz\u0103 numai dac\u0103 e NEVOIE.\nC\u00eend e dezactivat\u0103 e o protec\u021bie antiprofitori (utilizatori care nu \u00eencarc\u0103 date).
 ManagerItem.superseeding=Superdonare
 ConfigView.label.userSuperSeeding=Folose\u0219te Superdonarea
 PeersView.uniquepiece=Parte (Mod de Superdonare)
@@ -686,15 +681,15 @@ ConfigView.section.file.decoder.prompt.tooltip=Arat\u0103 mereu un dialog c\u00e
 MyTorrentsView.menu.moveTop=&V\u00eerf
 MyTorrentsView.menu.moveEnd=&Ultimul
 ConfigView.label.moveonlyusingdefaultsave=numai dac\u0103 s\u00eent \u00een dosarul implicit de date
-ConfigView.label.moveonlyusingdefaultsave.tooltip=Mut\u0103 doar dac\u0103 fi\u0219ierele desc\u0103rcate se afl\u0103 \u00een dosarul folosit implicit pt. ele
-ConfigView.label.watchtorrentfolder=Import\u0103 automat fi\u0219ierele torent noi
+ConfigView.label.moveonlyusingdefaultsave.tooltip=Mut\u0103 doar dac\u0103 filele desc\u0103rcate se afl\u0103 \u00een dosarul folosit implicit pt. ele
+ConfigView.label.watchtorrentfolder=Import\u0103 automat filele torent noi
 ConfigView.label.watchtorrentfolder.tooltip=Caut\u0103 regulat torente noi
 ConfigView.label.watchtorrentfolderinterval.tooltip=Intervalul p\u00een\u0103 la scanarea urm\u0103toare a dosarului
-ConfigView.dialog.choosewatchtorrentfolderpath=Alege\u021bi dosarul pentru importat torente
+ConfigView.dialog.choosewatchtorrentfolderpath=Alege dosarul pentru importat torente
 ConfigView.label.startwatchedtorrentsstopped=Porne\u0219te opritele
 ConfigView.label.startwatchedtorrentsstopped.tooltip=Adaug\u0103 torentele noi \u00een stare OPRIT\u0102
 ConfigView.section.plugins=Extensii
-wizard.maketorrent.filesize=M\u0103rimea Fi\u0219ierelor
+wizard.maketorrent.filesize=M\u0103rimea Filelor
 wizard.maketorrent.piececount=Num\u0103rul P\u0103r\u021bilor
 wizard.maketorrent.piecesize=M\u0103rimea P\u0103r\u021bii
 wizard.maketorrent.auto=Automat
@@ -706,44 +701,42 @@ ConfigView.section.style.useSIUnits=Folose\u0219te unit\u0103\u021bi IEC (KB ->
 iconBar.top.tooltip=Mut\u0103 \u00een v\u00eerf
 iconBar.bottom.tooltip=Mut\u0103 la Sf\u00eer\u0219it
 TableColumn.header.health=S\u0103n\u0103tate
-MyTorrentsView.menu.health=Despre S\u0103n\u0103tate
+MyTorrentsView.menu.health=Despre S\u0103n\u0103tatea Torentelor
 health.explain.grey=\u00eenseamn\u0103 c\u0103 torentul nu func\u021bioneaz\u0103 (desc\u0103rcare sau \u00eenc\u0103rcare)
-health.explain.red=\u00eenseamn\u0103 c\u0103  nu s\u00eente\u021bi conectat la nici un partener c\u00eend desc\u0103rca\u021bi
-health.explain.blue=la donare, \u00eenseamn\u0103 c\u0103 nu s\u00eente\u021bi conectat \u00eenc\u0103 la nici un partener. \nla desc\u0103rcare, \u00eenseamn\u0103 c\u0103 s\u00eente\u021bi conectat la c\u00ee\u021biva parteneri, dar trackerul este indisponibil.
-health.explain.yellow=\u00eenseamn\u0103 c\u0103 trackerul func\u021bioneaz\u0103 corect, s\u00eente\u021bi conectat la parteneri, dar nu ave\u021bi nici o leg\u0103tur\u0103 ini\u021biat\u0103 din exterior. \n\u00cen cazul \u00een care toate torentele s\u00eent colorate \u00een galben e posibil s\u0103 ave\u021bi o problem\u0103 cu NAT-ul.
+health.explain.red=\u00eenseamn\u0103 c\u0103 nu e\u0219ti conectat la nici un partener c\u00eend descarci
+health.explain.blue=la donare, \u00eenseamn\u0103 c\u0103 nu e\u0219ti conectat \u00eenc\u0103 la nici un partener. \nla desc\u0103rcare, \u00eenseamn\u0103 c\u0103 e\u0219ti conectat la c\u00ee\u021biva parteneri, dar trackerul este indisponibil.
+health.explain.yellow=\u00eenseamn\u0103 c\u0103 trackerul func\u021bioneaz\u0103 corect, e\u0219ti conectat la parteneri, dar nu ai nici o leg\u0103tur\u0103 ini\u021biat\u0103 din exterior. \n\u00cen cazul \u00een care toate torentele s\u00eent colorate \u00een galben, e posibil s\u0103 ai o problem\u0103 cu NAT-ul.
 health.explain.green=\u00eenseamn\u0103 c\u0103 totul e \u00een regul\u0103.
 ConfigView.section.style.alwaysRefreshMyTorrents=\u00cemprosp\u0103teaz\u0103 \u00eentotdeauna Torentele Mele
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aceast\u0103 op\u021biune va \u00eemprosp\u0103ta vederea Torentelor Mele chiar \u0219i c\u00eend aceasta e neafi\u0219at\u0103 (util pentru unele extensii mirc)
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=Aceast\u0103 op\u021biune va \u00eemprosp\u0103ta vederea Arhivei Torentelor chiar \u0219i c\u00eend aceasta e neafi\u0219at\u0103 (util pentru unele extensii mIRC)
 #
 #2.0.7.0
 #
 security.certtruster.title=Avertisment privitor la certificat
-security.certtruster.intro=Certificatul de securitate a fost eliberat de o companie \u00een care nu ave\u021bi \u00eencredere
+security.certtruster.intro=Certificatul de securitate a fost eliberat de o companie \u00een care nu ai \u00eencredere
 security.certtruster.resource=Resurs\u0103:
 security.certtruster.issuedto=Eliberat catre:
 security.certtruster.issuedby=Eliberat de:
-security.certtruster.prompt=\u00cei acorda\u021bi \u00eencredere?
+security.certtruster.prompt=\u00cei acorzi \u00eencredere?
 security.certtruster.yes=Da
 security.certtruster.no=Nu.
 ConfigView.section.tracker.torrentsperpage=C\u00eete torente pe fiecare pagin\u0103? [0: nelimitat]
 MainWindow.menu.file.share=&Partajeaz\u0103
-MainWindow.menu.file.share.file=&Fi\u0219ier...
+MainWindow.menu.file.share.file=&Fil\u0103...
 MainWindow.menu.file.share.dir=D&osar...
 MainWindow.menu.file.share.dircontents=&Con\u021binutul Dosarului...
 MainWindow.menu.file.share.dircontentsrecursive=Con\u021binutul Dosarului... (&Recursiv)
-MainWindow.dialog.share.sharefile=Selecta\u021bi Fi\u0219ierul de Partajat
-MainWindow.dialog.share.sharedir=Alege\u021bi Dosarul de Partajat
-MainWindow.dialog.share.sharedircontents=Alege\u021bi Con\u021binutul Partajat din Dosar
+MainWindow.dialog.share.sharefile=Selecteaz\u0103 Fila de Partajat
+MainWindow.dialog.share.sharedir=Alege Dosarul de Partajat
+MainWindow.dialog.share.sharedircontents=Alege Con\u021binutul Partajat din Dosar
 MainWindow.dialog.share.sharedircontents.recursive=Recursiv
 globalmanager.download.remove.veto=\u0218tergere refuzat\u0103
-plugin.sharing.download.remove.veto=Aceast\u0103 desc\u0103rcare e rezultatul partaj\u0103rii clasice a unei resurse comune.\nPentru a \u00eenl\u0103tura desc\u0103rcarea, \u00eenl\u0103tura\u021bi partajarea clasic\u0103 asociat\u0103.
+plugin.sharing.download.remove.veto=Aceast\u0103 desc\u0103rcare e rezultatul partaj\u0103rii clasice a unei resurse comune.\nPentru a \u00eenl\u0103tura desc\u0103rcarea, \u00eenl\u0103tur\u0103 partajarea clasic\u0103 asociat\u0103.
 ConfigView.section.tracker.main=Principal
 ConfigView.section.tracker.web=Re\u021bea
-ConfigView.label.prioritizefirstpiece=Prioritizeaz\u0103 prima \u0219i ultima parte din fi\u0219iere
-ConfigView.label.prioritizefirstpiece.tooltip=Se \u00eencearc\u0103 mai \u00eent\u00eei desc\u0103rcarea p\u0103r\u021bilor de \u00eenceput \u0219i de sf\u00eer\u0219it ale fi\u0219ierului.\nPentru previzionarea precoce (\u00een timp ce se descarc\u0103).
-ConfigView.section.file.confirm_data_delete=Cere confirmare la \u0219tergerea de fi\u0219iere
-ConfigView.section.file.confirm_data_delete.tooltip=Confirmare la \u0219tergere
-ConfigView.section.file.delete.include_files_outside_save_dir=C\u00eend se \u0219terg fi\u0219iere, permite \u0219i \u0219tergerea fi\u0219ierelor rela\u021bionate (legate) care exist\u0103 \u00een afara dosarului de salvare a torentelor
+ConfigView.label.prioritizefirstpiece=Prioritizeaz\u0103 prima \u0219i ultima parte din fil\u0103/file
+ConfigView.label.prioritizefirstpiece.tooltip=Se \u00eencearc\u0103 mai \u00eent\u00eei desc\u0103rcarea p\u0103r\u021bilor de \u00eenceput \u0219i de sf\u00eer\u0219it ale filei.\nPentru previzionarea precoce (\u00een timp ce se descarc\u0103).
+ConfigView.section.file.delete.include_files_outside_save_dir=C\u00eend se \u0219terg file, permite \u0219i \u0219tergerea filelor rela\u021bionate (legate) care exist\u0103 \u00een afara dosarului de salvare a torentelor
 TrayWindow.menu.startalldownloads=Pone\u0219te Toate Desc\u0103rc\u0103rile
 SystemTray.menu.startalltransfers=Porne\u0219te Transferurile
 sharing.progress.title=Progresul Partaj\u0103rii Clasice
@@ -752,7 +745,7 @@ MainWindow.menu.view.myshares=Partajul Meu
 MySharesView.title.full=Partajul Meu
 MySharesView.name=Nume
 MySharesView.type=Tip
-MySharesView.type.file=Fi\u0219ier
+MySharesView.type.file=Fil\u0103
 MySharesView.type.dir=Dosar
 MySharesView.type.dircontents=Con\u021binutul dosarului
 MySharesView.type.dircontentsrecursive=Con\u021binutul dosarului (recursiv)
@@ -760,17 +753,17 @@ MySharesView.menu.remove=\u0218terge
 ConfigView.section.tracker.extensions=Extensii
 ConfigView.section.tracker.sendpeerids=Trimite identitatea partenerilor la desc\u0103rc\u0103tori
 ConfigView.section.tracker.enableudp=Activeaz\u0103 protocolul pt. trackere UDP
-plugin.sharing.torrent.remove.veto=\u00cenregistrarea acestui tracker e rezultatul unei resurse partajate clasic.\nPentru a \u00eenl\u0103tura desc\u0103rcarea, \u00eenl\u0103tura\u021bi partajarea clasic\u0103 asociat\u0103.
+plugin.sharing.torrent.remove.veto=\u00cenregistrarea acestui tracker e rezultatul unei resurse partajate clasic.\nPentru a \u00eenl\u0103tura desc\u0103rcarea, \u00eenl\u0103tur\u0103 partajarea clasic\u0103 asociat\u0103.
 plugin.download.remove.veto.notstopped=Desc\u0103rcarea nu poate fi \u00eenl\u0103turat\u0103 dac\u0103 nu e oprit\u0103
-plugin.sharing.remove.veto=Aceast\u0103 partajare clasic\u0103 e o subparte a partaj\u0103rii con\u021binutului unui dosar, deci nu se poate \u0219terge direct.\n\u0218terge\u021bi partajarea clasic\u0103 a r\u0103d\u0103cinii.
-GeneralView.label.hash.tooltip=Clica\u021bi pentru a copia ha\u0219ul \u00een cliplan\u0219et\u0103
+plugin.sharing.remove.veto=Aceast\u0103 partajare clasic\u0103 e o subparte a partaj\u0103rii con\u021binutului unui dosar, deci nu se poate \u0219terge direct.\n\u0218terge partajarea clasic\u0103 a r\u0103d\u0103cinii.
+GeneralView.label.hash.tooltip=Clicheaz\u0103 pentru a copia ha\u0219ul \u00een cliplan\u0219et\u0103
 ConfigView.section.tracker.maxpeersreturned=Max parteneri raporta\u021bi [0: nelimitat]
 ConfigView.label.serverport=Port de ascultare a conexiunilor TCP / UDP intr\u00eende
 ConfigView.label.serverport.tooltip=Num\u0103rul portului trebuie s\u0103 fie \u00eentre 1 \u0219i 65535, dar nu 6880 care este rezervat pentru uzul intern al lui Vuze.
 configureWizard.nat.server.tcp_listen_port=Port TCP de ascultare
 ConfigView.section.sharing=Partajare Clasic\u0103
 ConfigView.section.sharing.usessl=Folose\u0219te SSL pt. resursele partajate clasic (necesit\u0103 configurarea trackerului)
-ConfigView.section.style.dropdiraction=Ac\u021biune de tip tragere-\u0219i-depunere pentru dosare
+ConfigView.section.style.dropdiraction=Ac\u021biune de tip tragere-\u0219i-punere pentru dosare
 ConfigView.section.style.dropdiraction.opentorrents=Deschide Torentele
 ConfigView.section.style.dropdiraction.sharefolder=Dosarul Partajului
 ConfigView.section.style.dropdiraction.sharefoldercontents=Con\u021binutul Partajului
@@ -779,30 +772,30 @@ ConfigView.section.style.dropdiraction.sharefoldercontents=Con\u021binutul Parta
 #
 Categories.all=Tot
 Categories.uncategorized=Necategorisit
-CategoryAddWindow.message=Introduce\u021bi numele categoriei
-CategoryAddWindow.title=Ad\u0103uga\u021bi o Categorie Nou\u0103
-ConfigView.label.autoSeedingIgnoreInfo=Torentele ignorate merg la coada \u0219irului de donare. Ele nu vor fi pornite automat. \nRegulile de ignorare nu se aplic\u0103 torentelor care satisfac criteriile de Prim\u0103 Prioritate. \u00cen afara cazului c\u0103 se specific\u0103 altfel, folosi\u021bi valoarea 0 pentru a dezactiva o regul\u0103.
+CategoryAddWindow.message=Scrie numele categoriei
+CategoryAddWindow.title=Adaug\u0103 o Categorie Nou\u0103
+ConfigView.label.autoSeedingIgnoreInfo=Torentele ignorate merg la coada \u0219irului de donare. Ele nu vor fi pornite automat. \nRegulile de ignorare nu se aplic\u0103 torentelor care satisfac criteriile de Prim\u0103 Prioritate. \u00cen afara cazului c\u0103 se specific\u0103 altfel, folose\u0219te valoarea 0 pentru a dezactiva o regul\u0103.
 ConfigView.label.directory=Catalog
-ConfigView.label.disconnetseed.tooltip=La donarea unui torent, deconecteaz\u0103 orice clien\u021bi care doneaz\u0103 \u0219i ei. \nNu e necesar ca ei s\u0103 fie conecta\u021bi la sistemul dv.
+ConfigView.label.disconnetseed.tooltip=La donarea unui torent, deconecteaz\u0103 orice clien\u021bi care doneaz\u0103 \u0219i ei. \nNu e necesar ca ei s\u0103 fie conecta\u021bi la calculatorul t\u0103u.
 ConfigView.label.ignoreCase=Ignor\u0103 MAJ/min
 ConfigView.label.ignoreSeeds=Ignor\u0103 torentele cu cel pu\u021bin
 ConfigView.label.importdirectory=Dosarul Importurilor
-ConfigView.label.minPeersToBoostNoSeeds.tooltip=Orice torent f\u0103r\u0103 donatori \u0219i cu mai pu\u021bini parteneri dec\u00eet a\u021bi specificat\nva fi mutat spre cap\u0103tul cozii.
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=Orice torent f\u0103r\u0103 donatori \u0219i cu mai pu\u021bini parteneri dec\u00eet ai specificat va fi mutat spre cap\u0103tul cozii.
 ConfigView.label.minPeersToBoostNoSeeds=Mic\u0219oreaz\u0103 Rangul de Donare pt. torentele f\u0103r\u0103 donatori \u0219i mai pu\u021bin de
-ConfigView.label.minSeedingTime.tooltip=Rangurile de Donare pot fluctua apreciabil pentru scurte perioade de timp, c\u00eeteodat\u0103 f\u0103c\u00eend ca torentul s\u0103 porneasc\u0103 automat, pentru ca imediat dup\u0103 aceea s\u0103 fie oprit \u0219i pus \u00een coada de a\u0219teptare.\nAceast\u0103 op\u021biune u\u0219ureaz\u0103 problema for\u021b\u00eend torentul s\u0103 r\u0103m\u00een\u0103 donat pentru o anumit\u0103 perioad\u0103 de vreme. Poate fi totu\u0219i oprit manual d [...]
+ConfigView.label.minSeedingTime.tooltip=Rangurile de Donare pot fluctua apreciabil pentru scurte perioade de timp, c\u00eeteodat\u0103 f\u0103c\u00eend ca torentul s\u0103 porneasc\u0103 automat, pentru ca imediat dup\u0103 aceea s\u0103 fie oprit \u0219i pus \u00een coada de a\u0219teptare.\nAceast\u0103 op\u021biune u\u0219ureaz\u0103 problema for\u021b\u00eend torentul s\u0103 r\u0103m\u00een\u0103 donat pentru o anumit\u0103 perioad\u0103 de vreme. Poate fi totu\u0219i oprit manual d [...]
 ConfigView.label.minSeedingTime=Durata minim\u0103 de donare \u00een secunde
 ConfigView.label.minSpeedForActiveDL.tooltip=Un slot de desc\u0103rcare e folosit mereu pt. primele 30 de secunde\ndup\u0103 pornirea torentului incomplet.
 ConfigView.label.minSpeedForActiveDL=Nu considera c\u0103 torentul folose\u0219te un slot de desc\u0103rcare dac\u0103 viteza sa e sub
 ConfigView.label.peers=parteneri
 ConfigView.label.queue.debuglog=\u00cenregistreaz\u0103 informa\u021biile despre debugare
-ConfigView.label.queue.debuglog.info=Adaug\u0103 informa\u021bii despre debugarea cozii la consol\u0103/fi\u0219ierul jurnal.\nDe\u0219i s\u00eent criptice, informa\u021biile despre debugare comunic\u0103 starea torentelor \u0219i motivul pentru care s\u00eent sau nu s\u00eent puse \u00een coada de a\u0219teptare.
+ConfigView.label.queue.debuglog.info=Adaug\u0103 informa\u021bii despre debugarea cozii la consol\u0103/fila jurnal.\nDe\u0219i s\u00eent criptice, informa\u021biile despre debugare comunic\u0103 starea torentelor \u0219i motivul pentru care s\u00eent sau nu s\u00eent puse \u00een coada de a\u0219teptare.
 ConfigView.label.queue.minQueueingShareRatio=Nu pune \u00een coad\u0103 sau opri torentul p\u00een\u0103 ce raportul de partajare nu atinge
 ConfigView.label.ratio=raport
 ConfigView.label.removeOnStop=\u0218terge torentul din list\u0103 dup\u0103 ce se opre\u0219te automat
 ConfigView.label.savedirectory=Dosar de Salvare
-ConfigView.label.seeding.autoReposition.tooltip=\u00cen cazul activ\u0103rii, ordinea torentelor (coloana "#") va fi modificat\u0103 pentru a se potrivi cu Rangul de Donare.\nEste util \u00een cazul \u00een care nu dori\u021bi s\u0103 fie afi\u0219ate Rangurile de Donare, dar dori\u021bi s\u0103 \u0219ti\u021bi \u00een ce ordine vor porni torentele terminate.
+ConfigView.label.seeding.autoReposition.tooltip=\u00cen cazul activ\u0103rii, ordinea torentelor (coloana "#") va fi modificat\u0103 pentru a se potrivi cu Rangul de Donare.\nEste util \u00een cazul \u00een care nu vrei s\u0103 fie afi\u0219ate Rangurile de Donare, dar vrei s\u0103 \u0219tii \u00een ce ordine vor porni torentele terminate.
 ConfigView.label.seeding.autoReposition=Repozi\u021bioneaz\u0103 automat torentele dup\u0103 Rangul de Donare
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u00cen cele mai multe cazuri torentele cu pu\u021bini donatori \u0219i mul\u021bi parteneri s\u00eent rezultatul faptului c\u0103 nu exist\u0103 o copie \u00eentreag\u0103 a fi\u0219ierului la vreun partener. \nA\u0219adar, e posibil s\u0103 nu dori\u021bi ca regulile de donare s\u0103 pretind\u0103 c\u0103 ar exista o copie complet\u0103 (\u0219i astfel s\u0103 fie redus rangul \u00een mod incorect)
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u00cen cele mai multe cazuri torentele cu pu\u021bini donatori \u0219i mul\u021bi parteneri s\u00eent rezultatul faptului c\u0103 nu exist\u0103 o copie \u00eentreag\u0103 a filei la vreun partener. \nA\u0219adar, e posibil s\u0103 nu vrei ca regulile de donare s\u0103 pretind\u0103 c\u0103 ar exista o copie complet\u0103 (\u0219i astfel s\u0103 fie redus rangul \u00een mod incorect)
 ConfigView.label.seeding.fakeFullCopySeedStart=dar numai pentru torente cu cel pu\u021bin
 ConfigView.label.seeding.ignore=Reguli de Ignorare
 ConfigView.label.seeding.ignore0Peers=Ignor\u0103 torentele cu 0 parteneri
@@ -818,9 +811,9 @@ ConfigView.label.seeding.firstPriority.following=din urm\u0103toarele:
 ConfigView.label.seeding.firstPriority.shareRatio=Raport de Partajare sub
 ConfigView.label.seeding.firstPriority.seedingMinutes=Timpul scurs de la schimbarea ac\u021biunii din desc\u0103rcare \u00een donare
 ConfigView.label.seeding.firstPriority.DLMinutes=Timp scurs de la \u00eenceputul desc\u0103rc\u0103rii
-ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Pretinz\u00eend c\u0103 exist\u0103 o copie complet\u0103 la fiecare X parteneri, pute\u021bi reduce rangul torentelor cu mul\u021bi parteneri.\nAproape sigur, torentele cu mul\u021bi parteneri au \u0219i trafic ridicat.\nAceasta nu schimb\u0103 \u00eens\u0103 afi\u0219area num\u0103rului de donatori.
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=Pretinz\u00eend c\u0103 exist\u0103 o copie complet\u0103 la fiecare X parteneri, po\u021bi reduce rangul torentelor cu mul\u021bi parteneri.\nAproape sigur, torentele cu mul\u021bi parteneri au \u0219i trafic ridicat.\nAceasta nu schimb\u0103 \u00eens\u0103 afi\u0219area num\u0103rului de donatori.
 ConfigView.label.seeding.numPeersAsFullCopy=Presupune c\u0103 exist\u0103 1 copie complet\u0103 la fiecare \n(0: Nu presupune)
-ConfigView.label.seeding.preferLargerSwarms.tooltip=Are rost s\u0103 prefera\u021bi roiuri mai mari dac\u0103 dona\u021bi \u00een principal torente cu parteneri "stabili"\nDac\u0103 dona\u021bi \u00een special torente cu disponibilitate ridicat\u0103, e mai bine s\u0103 prefera\u021bi roiuri mai mici.
+ConfigView.label.seeding.preferLargerSwarms.tooltip=Are rost s\u0103 preferi roiuri mai mari dac\u0103 donezi \u00een principal torente cu parteneri "stabili"\nDac\u0103 donezi \u00een special torente cu disponibilitate ridicat\u0103, e mai bine s\u0103 preferi roiuri mai mici.
 ConfigView.label.seeding.preferLargerSwarms=C\u00eend torentele au rang egal, prefer\u0103 roiurile mai mari
 ConfigView.label.seeding.rankType.none.tooltip=Ordoneaz\u0103 dup\u0103 coloana #
 ConfigView.label.seeding.rankType.none=Nimic
@@ -857,7 +850,7 @@ ConfigView.text.minutes=minute
 ConfigView.text.neverIgnore=Nu ignora niciodat\u0103
 ConfigView.text.any=oricare
 DownloadManager.error.datamissing=Date Lips\u0103
-MainWindow.menu.file.open.torrentforseeding=Fi\u0219ier Torent... (Pentru Donare)
+MainWindow.menu.file.open.torrentforseeding=Fil\u0103 Torent... (Pentru Donare)
 MainWindow.menu.language.refresh=\u00ce&mprosp\u0103teaz\u0103
 ManagerItem.forced=For\u021bat
 ManagerItem.queued=Pus \u00een Coad\u0103
@@ -874,7 +867,7 @@ MyTorrentsView.menu.setCategory.add=&Categorie Nou\u0103...
 MyTorrentsView.menu.setCategory=Pune \u00een Categoria
 TableColumn.header.savepath=Calea de Salvare
 TableColumn.header.SeedingRank=Rang de Donare
-TableColumn.header.totalspeed.info=Viteza total\u0103 a partenerilor la care s\u00eente\u021bi conectat
+TableColumn.header.totalspeed.info=Viteza total\u0103 a partenerilor la care e\u0219ti conectat
 TableColumn.header.totalspeed=Vitez\u0103 Total\u0103
 splash.initializePlugins=Ini\u021bializez Extensiile
 StartStopRules.SPratioMet=Raport S:P OK
@@ -886,7 +879,7 @@ StartStopRules.shareRatioMet=Raport de Partajare OK
 StartStopRules.waiting=A\u0219tept
 StartStopRules.firstPriority=1a Prioritate
 ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=Con\u021binutul Partajului (Recursiv)
-DownloadManager.error.unabletostartserver=Imposibil de pornit Serverul - verifica\u021bi configurarea porturilor de intrare \u0219i permisiunile paravanului [firewall] pentru ca aplica\u021bia s\u0103 func\u021bioneze ca server.
+DownloadManager.error.unabletostartserver=Imposibil de pornit Serverul - verific\u0103 configurarea porturilor de intrare \u0219i permisiunile parafocului [firewall] pentru ca aplica\u021bia s\u0103 func\u021bioneze ca server.
 GeneralView.label.creationdate=Creat pe :
 ConfigView.section.tracker.announcescrapepercentage=Interval de r\u0103zuire ca procentaj din cel de anun\u021bare\nde ex. 200 = 2:1. 0 = las\u0103 partenerul s\u0103 decid\u0103
 ManagerItem.stopping=Opresc
@@ -900,8 +893,8 @@ MyTrackerView.bytesin=Bai\u021bi Primi\u021bi
 MyTrackerView.bytesinave=Medie Primit\u0103
 MyTrackerView.bytesout=Bai\u021bi Trimi\u0219i
 MyTrackerView.bytesoutave=Medie Trimis\u0103
-ConfigView.section.file.max_open_files=Nr. maxim de fi\u0219iere deschise pt. citire/scriere\n[0: nelimitat]
-ConfigView.section.file.max_open_files.tooltip=Util dac\u0103 desc\u0103rca\u021bi torente cu sute \u0219i mii de fi\u0219iere \u00een ele, care provoac\u0103 atingerea limitei SO pt. m\u00eenerele fi\u0219ierelor.
+ConfigView.section.file.max_open_files=Nr. maxim de file deschise pt. citire/scriere\n[0: nelimitat]
+ConfigView.section.file.max_open_files.tooltip=Util dac\u0103 descarci torente cu sute \u0219i mii de file \u00een ele, care provoac\u0103 atingerea limitei SO pt. m\u00eenerele filelor.
 ConfigView.section.proxy=Op\u021biuni Proxy
 ConfigView.section.proxy.enable_proxy=Permite proxificarea comunic\u0103rilor cu trackerul (necesit\u0103 repornire)
 ConfigView.section.proxy.host=Gazda
@@ -916,12 +909,12 @@ AlertMessageBox.error=Eroare
 AlertMessageBox.warning=Avertisment
 AlertMessageBox.comment=Informa\u021bii
 AlertMessageBox.information=Informa\u021bii
-AlertMessageBox.unread=Ave\u021bi mesaje de avertizare necitite - clica\u021bi aici pentru a le afi\u0219a.
-SharedPortServer.alert.selectorfailed=Nu am reu\u0219it s\u0103 stabilim un ascult\u0103tor pentru datele intr\u00eende. \nVerifica\u021bi dac\u0103 set\u0103rile paravanului [firewall] permit ca java(w).exe s\u0103 func\u021bioneze ca "server"
-Tracker.alert.listenfail=E\u0219ec la stabilirea ascult\u0103rii pe portul  %1.\nVerifica\u021bi dac\u0103 nu exist\u0103 alte programe care \u00eel folosesc\nVerifica\u021bi dac\u0103 nu ruleaz\u0103 alt\u0103 instan\u021b\u0103 a lui Vuze.
-DiskManager.alert.movefileexists=Eroare la mutarea fi\u0219ierelor terminate\nFi\u0219ierul %1 exist\u0103 deja \u00een dosarul de destina\u021bie
-DiskManager.alert.movefilefails=Eroare la mutarea fi\u0219ierelor terminate\nMutarea fi\u0219ierului %1 a e\u0219uat, %2
-DiskManager.alert.movefilerecoveryfails=Repararea erorii dup\u0103 mutare a e\u0219uat\nRestaurarea fi\u0219ierului %1 a e\u0219uat, %2
+AlertMessageBox.unread=Ai mesaje de avertizare necitite - clicheaz\u0103 aici pentru a fi afi\u0219ate.
+SharedPortServer.alert.selectorfailed=Nu s-a reu\u0219it stabilirea unui ascult\u0103tor pentru datele intr\u00eende. \nVerific\u0103 dac\u0103 set\u0103rile parafocului [firewall] permit ca java(w).exe s\u0103 func\u021bioneze ca "server"
+Tracker.alert.listenfail=E\u0219ec la stabilirea ascult\u0103rii pe portul  %1.\nVerific\u0103 dac\u0103 nu exist\u0103 alte programe care \u00eel folosesc\nVerific\u0103 dac\u0103 nu ruleaz\u0103 alt\u0103 instan\u021b\u0103 a lui Vuze.
+DiskManager.alert.movefileexists=Eroare la mutarea filelor terminate\nFila %1 exist\u0103 deja \u00een dosarul de destina\u021bie
+DiskManager.alert.movefilefails=Eroare la mutarea filelor terminate\nMutarea filei %1 a e\u0219uat, %2
+DiskManager.alert.movefilerecoveryfails=Repararea erorii dup\u0103 mutare a e\u0219uat\nRestaurarea filei %1 a e\u0219uat, %2
 ConfigView.section.tracker.logenable=Consemneaz\u0103 periodic statisticile \u00een "tracker.log"
 SpeedView.stats.title=Statistici
 SpeedView.stats.session=Aceast\u0103 Sesiune
@@ -931,12 +924,12 @@ SpeedView.stats.ratio=Raport
 SpeedView.stats.uptime=Durata \u00cenc\u0103rc\u0103rii
 SpeedView.stats.now=Acum
 SpeedView.stats.now.tooltip=Total (pe protocol)
-AutoMigration.useralert=Rezultatele automigr\u0103rii fi\u0219./dos. de config. ale utilizatorului:\n\n%1\nE\u0219u\u0103rile trebuie migrate manual.\nNU UITA\u021aI S\u0102 ACTUALIZA\u021aI DESTINA\u021aIILE DE SALVARE \u00ceN CONFIGURA\u021aIE DAC\u0102 AU FOST MUTATE!
+AutoMigration.useralert=Rezultatele automigr\u0103rii file/dosare de config. ale utilizatorului:\n\n%1\nE\u0219u\u0103rile trebuie migrate manual.\nNU UITA S\u0102 ACTUALIZEZI DESTINA\u021aIILE DE SALVARE \u00ceN CONFIGURA\u021aIE DAC\u0102 AU FOST MUTATE!
 #
 # > 2.0.8.0
 #
 OpenTorrentWindow.title=Deschide Torentele
-OpenTorrentWindow.addFiles=&Adaug\u0103 Fi\u0219iere
+OpenTorrentWindow.addFiles=&Adaug\u0103 File
 OpenTorrentWindow.dataLocation=Locul de salvare a datelor:
 OpenTorrentWindow.startMode=Mod de Ad\u0103ugare
 OpenTorrentWindow.startMode.queued=Pus \u00een Coad\u0103
@@ -950,14 +943,14 @@ TableColumn.header.remaining=R\u0103mas
 ConfigView.section.tracker.enablecompact=Activeaz\u0103 protocolul cu anun\u021buri compacte
 ConfigView.section.tracker.enablekey=Activeaz\u0103 pasarea cheilor c\u0103tre tracker pt. cre\u0219terea siguran\u021bei
 ConfigView.section.file.perf=Op\u021biuni de Performan\u021b\u0103
-ConfigView.section.file.perf.explain=Avertisment - schimbarea \u00een necuno\u0219tin\u021b\u0103 de cauz\u0103 a acestor parametri poate afecta viteza de desc\u0103rcare. Necesit\u0103 repornirea.\nDac\u0103 ave\u021bi probleme legate de epuizarea memoriei, lua\u021bi \u00een considerare limitarea num\u0103rului de conexiuni per torent (Vezi Configura\u021bie>Transfer)
-ConfigView.section.file.max_open_files.explain=Deschiderea unui num\u0103r prea mare de fi\u0219iere poate crea probleme pentru sistemul de operare, din cauza limitelor unor resurse cum s\u00eent m\u00eenerele fi\u0219ierelor. Aceast\u0103 op\u021biune limiteaz\u0103 num\u0103rul de fi\u0219iere deschise \u00een acela\u0219i timp.
+ConfigView.section.file.perf.explain=Avertisment - schimbarea \u00een necuno\u0219tin\u021b\u0103 de cauz\u0103 a acestor parametri poate afecta viteza de desc\u0103rcare. Necesit\u0103 repornirea.\nDac\u0103 ai probleme legate de epuizarea memoriei, ia \u00een considerare limitarea num\u0103rului de conexiuni per torent (Vezi Configura\u021bie>Transfer)
+ConfigView.section.file.max_open_files.explain=Deschiderea unui num\u0103r prea mare de file poate crea probleme pentru sistemul de operare, din cauza limitelor unor resurse cum s\u00eent m\u00eenerele [handles] filelor. Aceast\u0103 op\u021biune limiteaz\u0103 num\u0103rul de file deschise \u00een acela\u0219i timp.
 popup.error.hide=Ascunde
 popup.error.details=Detalii
 ConfigView.section.style.colorOverrides=Supradefiniri de culori
 ConfigView.section.style.colorOverride.progressBar=Bara de Progres
 ConfigView.section.style.colorOverride.error=Eroare
-MainWindow.status.tooOld=e veche, v\u0103 rug\u0103m s\u0103 o actualiza\u021bi.
+MainWindow.status.tooOld=e veche, te rug\u0103m s-o actualizezi.
 ConfigView.section.style.colorOverride.warning=Avertisment
 ConfigView.section.style.colorOverride.altRow=R\u00eenduri Alternante
 ConfigView.section.file.save.peers.enable=Salveaz\u0103 conexiunile cu partenerii pentru reconect\u0103ri rapide
@@ -979,14 +972,14 @@ MyTorrentsView.menu.thisColumn.autoTooltip=Arat\u0103 Mereu Ponturile Flotante
 MyTorrentsView.menu.tracker=Tracker/Torent
 ConfigView.upload.abbreviated=\u00ce:
 TableColumn.header.secondsseeding=Donez de
-TableColumn.header.secondsseeding.info=Timpul total al don\u0103rii pe care a\u021bi f\u0103cut-o.
+TableColumn.header.secondsseeding.info=Timpul total c\u00eet ai donat.
 TableColumn.header.secondsdownloading=Desc\u0103rcat de
-TableColumn.header.secondsdownloading.info=Timpul total c\u00eet a\u021bi desc\u0103rcat.
+TableColumn.header.secondsdownloading.info=Timpul total c\u00eet ai desc\u0103rcat.
 ConfigView.section.tracker.udpversion=Versiunea Protocolului UDP(1 sau 2)
 window.updateswt.title=Versiunea existent\u0103 de SWT e prea veche!
-window.updateswt.text=Versiunea existent\u0103 de SWT e prea veche!\nSWT este biblioteca grafic\u0103 folosit\u0103 de Vuze, iar cea pe care o ave\u021bi este prea veche pentru rularea ultimei versiuni de Vuze. Ap\u0103sa\u021bi butonul OK pentru a actualiza SWT.
+window.updateswt.text=Versiunea existent\u0103 de SWT e prea veche!\nSWT este biblioteca grafic\u0103 folosit\u0103 de Vuze, iar cea existent\u0103 este prea veche pentru rularea ultimei versiuni de Vuze. Apas\u0103 butonul OK pentru a actualiza SWT.
 window.updateswt.status=Stare
-window.updateswt.failed=Actualizarea a e\u0219uat, ap\u0103sa\u021bi OK din nou pentru repornire.
+window.updateswt.failed=Actualizarea a e\u0219uat, apas\u0103 OK din nou pentru repornire.
 window.updateswt.status.downloading.updater=Descarc modulul de actualizare
 window.updateswt.status.finding=Caut ultima versiune de SWT
 window.updateswt.status.downloading=Descarc ultima versiune de SWT
@@ -994,10 +987,10 @@ window.updateswt.status.done=Repornesc
 window.updateswt.cancel=Anuleaz\u0103
 swt.updater.downloader.downloading=Descarc SWT de la
 swt.updater.urlsgetter.downloading=Iau o list\u0103 de clone de la
-swt.updater.urlsgetter.platform=SWT pt. platform\u0103 : 
+swt.updater.urlsgetter.platform=SWT pt. platform\u0103 :
 window.updateswt.ignore=Ignor\u0103
 ConfigView.section.style.useFancyTabs=Folose\u0219te taburi elegante
-splash.initializeGM=Ini\u021bializez Managerul Global de Torente
+splash.initializeGM=Ini\u021bializez Administratorul Global de Torente
 splash.loadingTorrents=\u00cencarc Torentele
 MyTorrentsView.menu.thisColumn.sort=&Sorteaz\u0103
 Scrape.status.ok=R\u0103zuire OK
@@ -1010,21 +1003,21 @@ Scrape.status.scraping=R\u0103zuiesc...
 Scrape.status.initializing=A\u0219tept s\u0103 r\u0103zuiesc...
 Scrape.status.scraping.queued=R\u0103zuire pus\u0103 \u00een coada de a\u0219teptare...
 ConfigView.label.minSpeedForActiveSeeding=Nu considera c\u0103 torentul terminat folose\u0219te un slot dac\u0103 viteza sa e sub
-ConfigView.section.stats.exportpeers=Detaliile Partenerului Exportat
-MainWindow.menu.view.irc.moved=IRC este acum disponibil ca extensie, vede\u021bi http://azureus.sourceforge.net/plugin_list.php. Dup\u0103 instalare, folosi\u021bi meniul Vezi > Extensii > IRC pentru accesare.
+ConfigView.section.stats.exportpeers=Detaliile partenerului exportat
+MainWindow.menu.view.irc.moved=IRC este acum disponibil ca extensie, vezi http://azureus.sourceforge.net/plugin_list.php. Dup\u0103 instalare, folose\u0219te meniul Vezi > Extensii > IRC pentru accesare.
 MyTrackerView.webui.contextmenu.copyurl=Copiaz\u0103 \u00een cliplan\u0219et\u0103 adresa torentului
-ConfigView.section.file.torrent.ignorefiles=Fi\u0219iere de ignorat la crearea torentelor\nde ex. .DS_Store;Thumbs.db
-Torrent.create.progress.ignoringfile=Ignor fi\u0219ierul
+ConfigView.section.file.torrent.ignorefiles=File de ignorat la crearea torentelor\nde ex. .DS_Store;Thumbs.db
+Torrent.create.progress.ignoringfile=Ignor fila
 ConfigView.section.style.useUnitsRateBits=Folose\u0219te bi\u021bi \u00een loc de bai\u021bi pentru valorile \u00een bai\u021bi ale vitezei (KiB/s->Kibit/s etc.)
-ConfigView.section.interface.resetassoc=Reseteaz\u0103 asocierile fi\u0219ierelor (.torrent) \u00een explorator
+ConfigView.section.interface.resetassoc=Reseteaz\u0103 asocierile filelor (.torrent) \u00een explorator
 ConfigView.section.interface.resetassocbutton=Reseteaz\u0103
 ConfigView.section.interface.checkassoc=Verific\u0103 asocierile la pornire
 dialog.associations.title=Verific\u0103 Asocierea
 Button.yes=&Da
 Button.no=&Nu
 ConfigView.label.seeding.autoStart0Peers=Porne\u0219te automat toate torentele terminate, chiar cu 0 parteneri
-ConfigView.label.seeding.autoStart0Peers.tooltip=Activa\u021bi dac\u0103 dori\u021bi ca trackerul s\u0103 listeze mereu donatorii pt. torentele cu 0 parteneri.
-dialog.associations.prompt=Vuze nu e aplica\u021bia implicit\u0103 pentru fi\u0219iere Bit Torrent.\nDori\u021bi s\u0103 asocia\u021bi fi\u0219ierele .torrent cu Vuze?
+ConfigView.label.seeding.autoStart0Peers.tooltip=Activeaz\u0103 dac\u0103 vrei ca trackerul s\u0103 listeze mereu donatorii pt. torentele cu 0 parteneri.
+dialog.associations.prompt=Vuze nu e aplica\u021bia implicit\u0103 pentru file Bit Torrent.\nVrei s\u0103 asociezi filele .torrent cu Vuze?
 dialog.associations.askagain=Verific\u0103 la pornire
 ConfigView.section.plugins.update=Actualizarea Extensiilor
 Plugin.pluginupdate.enablecheck=Activeaz\u0103 verificarea actualiz\u0103rilor extensiilor.
@@ -1056,7 +1049,6 @@ ConfigView.pluginlist.whereToPutOr=Pt. extensiile comune folose\u0219te:
 MainWindow.statusText.checking=Caut Actualiz\u0103ri
 TableColumn.header.OnlyCDing4=Doar Donare
 TableColumn.header.OnlyCDing4.info=Timpul c\u00eet torentul a fost doar donat. Este exclus timpul c\u00eet torentul a fost folosit pentru primirea \u0219i donarea de date \u00een acela\u0219i timp.
-ConfigView.section.style.alternateTablePainting=Folose\u0219te metoda alternativ\u0103 pentru colorarea coloanelor tabelului (e posibil s\u0103 necesite repornirea)
 UpdateWindow.status.restartMaybeNeeded=Repornirea poate fi necesar\u0103
 ConfigView.pluginlist.shared=partajat
 PeersView.host=Numele Gazdei
@@ -1065,7 +1057,7 @@ MainWindow.menu.help.whatsnew=Ce-i Nou
 ConfigView.label.checkonstart=Verific\u0103 la pornirea softului dac\u0103 a ap\u0103rut o versiune nou\u0103
 ConfigView.label.periodiccheck=Caut\u0103 periodic versiune nou\u0103 de Vuze
 ConfigView.label.opendialog=Deschide automat Actualizatorul c\u00eend e disponibil\u0103 o actualizare
-MainWindow.updateavail=Clica\u021bi aici pentru actualizare
+MainWindow.updateavail=Clicheaz\u0103 aici pentru actualizare
 MainWindow.status.latestversionunchecked=Verificarea versiunii e dezactivat\u0103
 GeneralView.label.updatein.stopped=Oprit
 StartStopRules.menu.viewDebug=Vezi Informa\u021bii de Debugare
@@ -1078,7 +1070,7 @@ health.explain.share=\u00eenseamn\u0103 c\u0103 torentul e g\u0103zduit sau publ
 ConfigView.section.tracker.createcert=Creeaz\u0103 Certificat Autosemnat
 ConfigView.section.tracker.createbutton=Creeaz\u0103
 security.certcreate.title=Creeaz\u0103 Certificat Autosemnat
-security.certcreate.intro=Acest dialog v\u0103 permite s\u0103 crea\u021bi un certificat autosemnat
+security.certcreate.intro=Acest dialog \u00ee\u021bi permite s\u0103 creezi un certificat autosemnat
 security.certcreate.strength=Putere
 security.certcreate.firstlastname=Prenume \u0219i Nume
 security.certcreate.orgunit=Unitate de Organizare
@@ -1105,16 +1097,15 @@ webui.mode.info=Modul poate fi\n\t"full"\t= toate opera\u021biunile disponibile
 webui.access=Acces (*)
 webui.access.info=Accesul poate fi \n\t"local"\t= doar calculatorul local se poate conecta \n\t"all"\t= acces nerestric\u021bionat (predefinit)\n\tIP\t= ex. 192.168.0.2\t\t\tun singur IP\n\tIP1-IP2\t= ex. 192.168.0.1-192.168.0.255\t interval de IP-uri
 GeneralView.label.maxdownloadspeed=Viteza Maxim\u0103 de Desc\u0103rcare
-Security.keystore.corrupt=E\u0219ec la \u00eenc\u0103rcarea stocului de parole '%1' , \u0219tergeti-l \u0219i recrea\u021bi sau reimporta\u021bi certificatele
-Security.keystore.empty=Stocul de parole e gol. Crea\u021bi un certificat autosemnat (vezi Unelte>Op\u021biuni>Securitate) sau importa\u021bi unul existent in %1'
-webui.restart.info=Modific\u0103rile parametrilor marca\u021bi cu (*) au nevoie de repornirea softului pentru a fi activate 
+Security.keystore.corrupt=E\u0219ec la \u00eenc\u0103rcarea stocului de parole '%1' , \u0219terge-l \u0219i recreeaz\u0103 sau reimport\u0103 certificatele
+Security.keystore.empty=Stocul de parole e gol. Creeaz\u0103 un certificat autosemnat (vezi Unelte>Op\u021biuni>Securitate) sau import\u0103 unul existent in %1'
 GeneralView.label.maxdownloadspeed.tooltip=viteza max desc\u0103rcare [0: nelimitat\u0103]
 upnp.enable=Activeaz\u0103 UPnP
 upnp.info=Universal Plug and Play (UPnP) permite maparea automat\u0103 a porturilor \u00een ruterele care folosesc acest standard.
 upnp.mapping.dataport=Port de Intrare a Datelor Partenerilor
 upnp.mapping.tcptrackerport=Port al Trackerului TCP
 upnp.mapping.udptrackerport=Port al Trackerului UDP
-upnp.alert.differenthost=UPnP: Maparea '%1' a fost deja rezervat\u0103 de '%2' - selecta\u021bi un alt port
+upnp.alert.differenthost=UPnP: Maparea '%1' a fost deja rezervat\u0103 de '%2' - selecteaz\u0103 un alt port
 upnp.alert.mappingok=UPnP: Maparea '%1' e f\u0103cut\u0103
 upnp.alert.mappingfailed=UPnP: Maparea '%1' a e\u0219uat
 upnp.alertsuccess=Raporteaz\u0103 succesul map\u0103rilor
@@ -1128,10 +1119,10 @@ upnp.alertothermappings=Raporteaz\u0103 porturile altor calculatoare
 upnp.alertdeviceproblems=Raporteaz\u0103 problemele cu dispozitivul UPnP
 upnp.trace_to_log=Trimite informa\u021bii de debugare complete \u00een jurnal
 upnp.wiki_link=Pagina din Wikiul Vuze despre UPnP
-upnp.refresh_mappings_on_bad_nat=\u00cemprosp\u0103teaz\u0103 automat map\u0103rile c\u00eend starea NAT-ului este "paravanat".
+upnp.refresh_mappings_on_bad_nat=\u00cemprosp\u0103teaz\u0103 automat map\u0103rile c\u00eend starea NAT-ului este "parafocat".
 ConfigView.pluginlist.coreplugins=Urm\u0103toarele extensii \u00eencorporate s\u00eent \u00eenc\u0103rcate:
 Peers.column.DLedFromOthers=De la Al\u021bii
-Peers.column.DLedFromOthers.info=Cantitatea de date desc\u0103rcate de la al\u021bii c\u00eet au fost conecta\u021bi la dv.
+Peers.column.DLedFromOthers.info=Cantitatea de date desc\u0103rcate de la al\u021bii c\u00eet au fost conecta\u021bi la tine
 Peers.column.UpDownRatio=Sus:Jos
 Peers.column.UpDownRatio.info=Rata "Sus:Jos" a partenerului
 Peers.column.UpRatio=Raport \u00cenc
@@ -1140,11 +1131,11 @@ upnp.releasemappings=Elibereaz\u0103 map\u0103rile la ie\u0219ire
 webui.upnpenable=Activeaz\u0103 UPnP pentru portul acesta (*)
 ConfigView.section.file.friendly.hashchecking=Verificare a ha\u0219ului mai pu\u021bin solicitant\u0103
 ConfigView.section.file.friendly.hashchecking.tooltip=Un mod ceva mai lent de verificare a ha\u0219urilor p\u0103r\u021bilor, dar mult mai pu\u021bin solicitant pentru CPU \u0219i sistem
-ConfigView.section.tracker.seedretention=Nr. max. de donatori re\u021binu\u021bi per torent [0: nelimitat] 
+ConfigView.section.tracker.seedretention=Nr. max. de donatori re\u021binu\u021bi per torent [0: nelimitat]
 ConfigView.section.tracker.seedretention.info=Not\u0103: Statisticile de \u00eenc\u0103rcare pentru donatorii nere\u021binu\u021bi vor fi pierdute
 ConfigView.section.tracker.port=Permite trackerului s\u0103 foloseasc\u0103 portul HTTP
 ConfigView.section.tracker.sslport=Permite trackerului s\u0103 foloseasc\u0103 portul HTTPS
-ConfigView.section.tracker.publicenable.info=Aceasta le permite celorlal\u021bi s\u0103 creeze torente ce folosesc trackerul dv.\nf\u0103r\u0103 ca s\u0103 le g\u0103zdui\u021bi/publica\u021bi
+ConfigView.section.tracker.publicenable.info=Aceasta le permite celorlal\u021bi s\u0103 creeze torente ce folosesc trackerul t\u0103u f\u0103r\u0103 s\u0103 le g\u0103zduie\u0219ti/publici
 Button.clear=\u0218terge
 MainWindow.IPs.tooltip=Ultima actualizare a listei de IP-uri filtrate: %1\nNum\u0103rul total de IP-uri filtrate \u00een list\u0103 - Num\u0103rul de IP-uri blocate/interzise sau gre\u0219ite \u00een sesiunea actual\u0103.\nDublu-clic pentru detalii.
 ConfigView.section.ipfilter.list.banned=a fost blocat
@@ -1173,8 +1164,6 @@ MyTrackerView.badnat.info=Donatorii/Partenerii cu verificare e\u0219uat\u0103 a
 ConfigView.section.tracker.natchecktimeout=Expirarea verific\u0103rii (sec)
 ConfigView.section.file.perf.cache.enable=Activeaz\u0103 ca\u0219ul hardiscului [disk cache]
 ConfigView.section.file.perf.cache.size=M\u0103rimea ca\u0219ului \u00een %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
 MainWindow.menu.transfers=T&ransferuri
 MainWindow.menu.transfers.startalltransfers=Po&rne\u0219te Tot
 MainWindow.menu.transfers.stopalltransfers=&Opre\u0219te Tot
@@ -1183,9 +1172,9 @@ MainWindow.menu.transfers.resumetransfers=&Reia
 ConfigView.label.experimental.osx.kernel.panic.fix=Repara\u021bie experimental\u0103 pentru panicile de kernel \u00een sistemele OSX cu dou\u0103 procesoare [necesit\u0103 repornire]
 SystemTray.menu.pausetransfers=Pauzeaz\u0103 Transferurile
 SystemTray.menu.resumetransfers=Reia Transferurile
-ConfigView.section.file.truncate.too.large=Trunchiaz\u0103 fi\u0219ierele prea mari care exist\u0103 deja
+ConfigView.section.file.truncate.too.large=Trunchiaz\u0103 filele prea mari care exist\u0103 deja
 ConfigView.section.file.perf.cache.trace=Urm\u0103re\u0219te opera\u021biunile cu ca\u0219ul \u00een scopuri de diagnosticare
-ConfigView.section.interface.enabletray=Activeaz\u0103 Sistalerul (necesit\u0103 repornire)
+ConfigView.section.interface.enabletray=Activeaz\u0103 Sertarul (necesit\u0103 repornire)
 PeerManager.status.error=Eroare
 Stats.title.full=Statistici
 TransferStatsView.title.full=Transferuri
@@ -1194,18 +1183,18 @@ CacheView.general.size=M\u0103rime Total\u0103
 CacheView.general.inUse=\u00cen Uz
 CacheView.general.title=Informa\u021bii despre Ca\u0219
 CacheView.reads.title=Citiri I/O
-CacheView.reads.fromFile=Din Fi\u0219ier
+CacheView.reads.fromFile=Din Fil\u0103
 CacheView.reads.fromCache=Din Ca\u0219
 CacheView.reads.hits=Reu\u0219ite
 CacheView.writes.title=Scrieri I/O
 CacheView.writes.toCache=Spre Ca\u0219
-CacheView.writes.toFile=Spre Fi\u0219ier
+CacheView.writes.toFile=Spre Fil\u0103
 CacheView.writes.hits=Salvat
 CacheView.speeds.title=Vitezele Datelor
 CacheView.speeds.reads=Citiri
 CacheView.speeds.writes=Scrieri
 CacheView.speeds.fromCache=Din/Spre Ca\u0219
-CacheView.speeds.fromFile=Din/Spre Fi\u0219ier
+CacheView.speeds.fromFile=Din/Spre Fil\u0103
 CacheView.reads.#=Nr.
 CacheView.reads.amount=Cantitate
 CacheView.reads.avgsize=M\u0103rime medie
@@ -1223,16 +1212,16 @@ PiecesView.legend.incache=Datele s\u00eent \u00een Ca\u0219
 PiecesView.typeItem.0=Lent
 PiecesView.typeItem.1=Rapid
 PiecesView.type=Tip
-Security.jar.tools_not_found=E\u0219ec la semnarea JAR - Nu am putut g\u0103si 'tools.jar' \u00een %1. Pentru detalii consulta\u021bi Unelte>Op\u021biuni>Securitate
+Security.jar.tools_not_found=E\u0219ec la semnarea JAR - Nu am putut g\u0103si 'tools.jar' \u00een %1. Pentru detalii consult\u0103 Unelte>Op\u021biuni>Securitate
 Security.jar.signfail=Semnarea JAR a e\u0219uat - %1
-ConfigView.section.security.toolsinfo=Fi\u0219ierele JAR identificate cu semn\u0103turi s\u00eent folosite pentru a asista unele extensii, de exemplu interfa\u021ba Swing Web (c\u00eend e configurat\u0103 \u00een acest scop). \nPentru a a putea semna un fi\u0219ier JAR e necesar accesul la fi\u0219ierul "tools.jar" care e primit \u00eempreun\u0103 cu pachetul de instalare Sun JDK (nu JRE!). \n\u00cen cazul \u00een care ave\u021bi instalat numai JRE, rug\u0103m instala\u021bi \u0219i JDK. [...]
+ConfigView.section.security.toolsinfo=Filele JAR identificate cu semn\u0103turi s\u00eent folosite pentru a asista unele extensii, de exemplu interfa\u021ba Swing Web (c\u00eend e configurat\u0103 \u00een acest scop). \nPentru a a putea semna o fil\u0103 JAR e necesar accesul la fila "tools.jar" care e primit\u0103 \u00eempreun\u0103 cu pachetul de instalare Sun JDK (nu JRE!). \n\u00cen cazul \u00een care ai instalat numai JRE, va trebui s\u0103 instalezi \u0219i JDK. \n\u00cen mod obi\u [...]
 ConfigView.section.security.toolsdir=Dosarul ce con\u021bine 'tools.jar'
-ConfigView.section.security.choosetoolssavedir=Selecta\u021bi dosarul ce con\u021bine 'tools.jar'
+ConfigView.section.security.choosetoolssavedir=Selecteaz\u0103 dosarul ce con\u021bine 'tools.jar'
 authenticator.torrent=Torent
 ConfigView.section.proxy.peer.same=Folose\u0219te acelea\u0219i set\u0103ri proxy pentru comunicarea cu trackerul \u0219i cu partenerii
 ConfigView.section.connection.network.max.simultaneous.connect.attempts=Nr. maxim de tentative simultane de conectare \u00eenspre exterior
 ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=Nr. maxim de conexiuni noi \u00eenspre exterior pe care Vuze trebuie s\u0103 le \u00eencerce la orice moment.\nNOT\u0102: WindowsXP Service Pack 2 (SP2) impune o limit\u0103 per sistem de 10 tentative simultane de conectare.\nValoarea implicit\u0103 este 8.
-ConfigView.section.file.perf.cache.size.explain=Ca\u0219ul este folosit pentru a reduce num\u0103rul de citiri \u0219i scrieri pe disc. \u00cen afar\u0103 de cazul \u00een care folosi\u021bi op\u021biunea '-XX:MaxDirectMemorySize' din Java pentru a seta \u00een mod explicit memoria disponibil\u0103 pentru ca\u0219 \u0219i pentru schimbul de informa\u021bii cu re\u021beaua, este bine s\u0103 pune\u021bi o valoare cu cel pu\u021bin %1 mai mic\u0103 dec\u00eet valoarea maxim\u0103 a memorie [...]
+ConfigView.section.file.perf.cache.size.explain=Ca\u0219ul este folosit pentru a reduce num\u0103rul de citiri \u0219i scrieri pe disc. \u00cen afar\u0103 de cazul \u00een care folose\u0219ti op\u021biunea '-XX:MaxDirectMemorySize' din Java pentru a seta \u00een mod explicit memoria disponibil\u0103 pentru ca\u0219 \u0219i pentru schimbul de informa\u021bii cu re\u021beaua, este bine s\u0103 pui o valoare cu cel pu\u021bin %1 mai mic\u0103 dec\u00eet valoarea maxim\u0103 a memoriei virtu [...]
 MyTorrentsView.menu.setSpeed.unlimit=Nelimitat\u0103
 MyTorrentsView.menu.setSpeed.unlimited=Nelimitat\u0103
 MyTorrentsView.menu.setSpeed.disable=Dezactiveaz\u0103 \u00cenc\u0103rcarea
@@ -1249,8 +1238,8 @@ ConfigView.section.file.perf.cache.enable.write=Ca\u0219eaz\u0103 datele desc\u0
 ConfigView.section.file.perf.cache.enable.read=Efectueaz\u0103 citiri \u00een avans pt. a reduce citirile de pe disc la \u00eenc\u0103rcare
 ConfigView.section.tracker.separatepeerids=Folose\u0219te identit\u0103\u021bi diferite pentru tracker \u0219i comunicarea de date
 ConfigView.section.tracker.separatepeerids.info=\u00cembun\u0103t\u0103\u021be\u0219te anonimatul \u00een cazul desc\u0103rc\u0103rii/don\u0103rii anonime,\n\u00een cazul folosirii unei conexiuni neanonime cu trackerul.
-ConfigView.section.interface.wavlocation=Adresa fi\u0219ierului .wav
-ConfigView.section.interface.wavlocation.info=Alege\u021bi un fi\u0219ier .wav sau l\u0103sa\u021bi gol pentru sunetul implicit
+ConfigView.section.interface.wavlocation=Adresa filei .wav
+ConfigView.section.interface.wavlocation.info=Alege o fil\u0103 .wav sau las\u0103 gol pentru sunetul implicit
 ConfigView.section.tracker.client.connecttimeout=Expirarea conexiunii (sec)
 ConfigView.section.tracker.client.readtimeout=Expirarea citirii (sec)
 MainWindow.menu.tools=&Unelte
@@ -1260,7 +1249,7 @@ FilesView.remaining=P\u0103r\u021bi R\u0103mase
 TableColumn.header.trackername=Numele Trackerului
 TableColumn.header.trackername.info=Numele trackerului bazat pe adresa de anun\u021bare
 ConfigView.group.override=Ignor\u0103 Op\u021biunile
-ConfigView.section.file.perf.cache.notsmallerthan=Nu ca\u0219a fi\u0219iere mai mici de (%1)
+ConfigView.section.file.perf.cache.notsmallerthan=Nu ca\u0219a file mai mici de (%1)
 PeersView.menu.blockupload=Blocheaz\u0103 \u00cenc\u0103rcarea
 PeersView.menu.kickandban=Blocheaz\u0103 \u0219i Alung\u0103
 PeersView.menu.kickandban.reason=Partener alungat manual
@@ -1290,24 +1279,19 @@ ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Seteaz\u0103 valoarea s
 ConfigView.section.connection.advanced.SO_SNDBUF=M\u0103rimea Socketului SO_SNDBUF [0: valoarea implicit\u0103 a SO]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Seteaz\u0103 valoarea standard a socketului SO_SNDBUF (\u00een bai\u021bi), de ex. dimensiunea intervalului de trimitere folosit de protocolul TCP.\nVuze nu modific\u0103 aceste valori ini\u021bial, adic\u0103 s\u00eent preluate valorile folosite de sistemul de operare.\nNot\u0103: \u00cen Linux, valoarea folosit\u0103 este dublat\u0103.
 ConfigView.section.connection.advanced.IPDiffServ=Valoarea pachetului ie\u0219ind DiffServ (c\u00eemp TOS)
-ConfigView.section.connection.advanced.IPDiffServ.tooltip=Seteaz\u0103 partea DiffServ a c\u00eempului tip-de-serviciu (TOS) \u00een antetul IP pentru pachetele ie\u0219inde.\nValorile hexazecimale pot fi specificate prin prefixarea lor cu '0x', de ex. 0x10.\nVuze las\u0103 aceast\u0103 valooarei nesetat\u0103 \u00een mod implicit, ceea ce \u00eenseamn\u0103 c\u0103 va fi folosit\u0103 valorea implicit\u0103 a SO.\nNOT\u0102: Implement\u0103rile de re\u021bea din SO pot s\u0103 ignore ac [...]
-ConfigView.section.interface.confirm_torrent_removal=Arat\u0103 un dialog de confirmare la \u00eenl\u0103turarea torentelor
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmare la \u00eenl\u0103turarea unui torent din vederea "Torentele mele"
-MyTorrentsView.confirm_torrent_removal=Sigur dori\u021bi s\u0103 \u00eenl\u0103tura\u021bi?\n
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=Seteaz\u0103 partea DiffServ a c\u00eempului tip-de-serviciu (TOS) \u00een antetul IP pentru pachetele ie\u0219inde.\nValorile hexazecimale pot fi specificate prin prefixarea lor cu '0x', de ex. 0x10.\nVuze las\u0103 aceast\u0103 valoarei nesetat\u0103 \u00een mod implicit, ceea ce \u00eenseamn\u0103 c\u0103 va fi folosit\u0103 valorea implicit\u0103 a SO.\nNOT\u0102: Implement\u0103rile de re\u021bea din SO pot s\u0103 ignore ace [...]
 TableColumn.header.seed_to_peer_ratio=RaportDonatoriLaParteneri
 TableColumn.header.seed_to_peer_ratio.info=Raportul total de donatori la parteneri din roi
 PeersView.connected_time=Timp conectat
 PeersView.connected_time.info=Timp conectat cu partenerul
-ConfigView.section.interface.display.add_torrents_silently=Adaug\u0103 torentele \u00een mod silen\u021bios
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Adaug\u0103 desc\u0103rc\u0103rile de torente f\u0103r\u0103 a activa fereastra principal\u0103 Vuze.
 TableColumn.header.maxdownspeed=Vit. Max. Desc\u0103rcare
 TableColumn.header.maxdownspeed.info=Viteza Maxim\u0103 de Desc\u0103rcare per Torent
-PeersGraphicView.title=Roi
+PeersGraphicView.title.full=Roi
 ConfigView.section.tracker.passwordwebhttpsonly=Accept\u0103 doar accesul prin HTTPS
 TableColumn.header.torrentpath=Loca\u021bia Torentului
 TableColumn.header.torrentpath.info=Locul torentului pe hardisc
 ConfigView.section.sharing.torrentcomment=Comentariu pentru torentele create
-ConfigView.label.copyanddeleteratherthanmove=Copiaz\u0103 fi\u0219ierele originale \u0219i abia apoi \u0219terge-le, \u00een loc de a le muta dintr-o singur\u0103 opera\u021bie - poate preveni pierderea datelor \u00een cazul unor sisteme de fi\u0219iere.
+ConfigView.label.copyanddeleteratherthanmove=Copiaz\u0103 filele originale \u0219i abia apoi \u0219terge-le, \u00een loc de a le muta dintr-o singur\u0103 opera\u021bie - poate preveni pierderea datelor \u00een cazul unor sisteme de file.
 ConfigView.label.openstatsonstart=Deschide Statisticile la pornire
 swt.install.window.title=Instalatorul de Extensii
 swt.install.window.ok=Instaleaz\u0103
@@ -1316,29 +1300,29 @@ swt.uninstall.window.title=Dezinstalatorul de Extensii
 swt.uninstall.window.ok=\u0218terge
 swt.uninstall.window.header=Urm\u0103toarele componente au fost selectate pentru a fi \u00eenl\u0103turate :
 installPluginsWizard.title=Instaleaz\u0103 Extensiile
-installPluginsWizard.mode.title=Alege\u021bi o metod\u0103 de instalare
+installPluginsWizard.mode.title=Alege o metod\u0103 de instalare
 installPluginsWizard.mode.list=Din lista de la sourceforge.net
 installPluginsWizard.list.title=Lista cu Extensii Instalabile
-installPluginsWizard.list.loading=A\u0219tepta\u021bi p\u00een\u0103 la afi\u0219area listei de extensii.
-installPluginsWizard.list.loaded=Alege\u021bi extensiile pe care dori\u021bi s\u0103 le instala\u021bi.
+installPluginsWizard.list.loading=A\u0219teapt\u0103 p\u00een\u0103 la afi\u0219area listei de extensii.
+installPluginsWizard.list.loaded=Alege extensiile pe care vrei s\u0103 le instalezi.
 installPluginsWizard.list.name=Nume
 installPluginsWizard.list.version=Versiune
 installPluginsWizard.list.description=Descrierea extensiei
 installPluginsWizard.finish.title=Instalare \u00een Curs
-installPluginsWizard.finish.explanation=Extensiile selectate vor fi instalate folosind asistentul de actualizare.\n\nAve\u021bi r\u0103bdare, este posibil sa dureze un timp p\u00een\u0103 la afi\u0219are.\n\nPentru afi\u0219area unui raport despre progres, dublu clic pe partea st\u00eeng\u0103 a barei de stare.
-installPluginsWizard.details.loading=\u00cencarc detaliile, a\u0219tepta\u021bi v\u0103 rog...
-installPluginsWizard.mode.file=Din fi\u0219ier
-installPluginsWizard.installMode.title=Alege\u021bi tipul de instalare
+installPluginsWizard.finish.explanation=Extensiile selectate vor fi instalate folosind asistentul de actualizare.\n\nAi r\u0103bdare, este posibil sa dureze un timp p\u00een\u0103 la afi\u0219are.\n\nPentru afi\u0219area unui raport despre progres, dublu-clicheaz\u0103 pe partea st\u00eeng\u0103 a barei de stare.
+installPluginsWizard.details.loading=\u00cencarc detaliile, a\u0219teapt\u0103 un pic...
+installPluginsWizard.mode.file=Din fil\u0103
+installPluginsWizard.installMode.title=Alege tipul de instalare
 installPluginsWizard.installMode.user=Instaleaz\u0103 extensiile doar pentru utilizatorul curent
 installPluginsWizard.installMode.shared=Instaleaz\u0103 extensiile pentru to\u021bi utilizatorii
-installPluginsWizard.file.title=C\u0103uta\u021bi extensia pe care dori\u021bi s\u0103 o instala\u021bi
-installPluginsWizard.file.file=Fi\u0219ier :
-installPluginsWizard.file.invalidfile=Fi\u0219ierul nu e o extensie valid\u0103 pentru Vuze.
-installPluginsWizard.file.no_such_file=Nu exist\u0103 nici un fi\u0219ier cu numele dat.
+installPluginsWizard.file.title=Caut\u0103 extensia pe care vrei s-o instalezi
+installPluginsWizard.file.file=Fil\u0103 :
+installPluginsWizard.file.invalidfile=Fila nu e o extensie valid\u0103 pentru Vuze.
+installPluginsWizard.file.no_such_file=Nu exist\u0103 nici o fil\u0103 cu numele dat.
 installPluginsWizard.file.browse=Exploreaz\u0103...
 uninstallPluginsWizard.title=Dezinstaleaz\u0103 Extensii
 uninstallPluginsWizard.list.title=Lista de Extensii Instalate
-uninstallPluginsWizard.list.loaded=Alege\u021bi extensiile pe care dori\u021bi s\u0103 le dezinstala\u021bi.
+uninstallPluginsWizard.list.loaded=Alege extensiile pe care vrei s\u0103 le dezinstalezi.
 installPluginsWizard.list.nullversion=Nici o versiune
 uninstallPluginsWizard.finish.title=Dezinstalare \u00een Curs
 uninstallPluginsWizard.finish.explanation=Extensiile selectate vor fi dezinstalate folosind asistentul de actualizare.
@@ -1350,20 +1334,18 @@ update.instance.uninstall=Verific Dezinstalarea
 update.instance.update=Caut Actualiz\u0103ri
 MainWindow.status.update.tooltip=Dublu clic pentru informatii despre progres
 updater.progress.window.title=Sarcini curente
-updater.progress.window.info=Ap\u0103sa\u021bi "\u00centrerupe" pentru a opri sarcinile aflate \u00een curs
+updater.progress.window.info=Apas\u0103 "\u00centrerupe" pentru a opri sarcinile aflate \u00een curs
 Button.abort=\u00centrerupe
 ConfigView.section.ipfilter.enablebanning=Blocheaz\u0103 partenerii care trimit \u00een mod repetat date nefolositoare
-Network.alert.acceptfail=Prea multe e\u0219ecuri succesive ap\u0103rute pe portul %1, %2 - am abandonat procesarea. Verifica\u021bi specifica\u021biile paravanului [firewall] pentru acest port, ca s\u0103 v\u0103 asigura\u021bi c\u0103 este autorizat pentru conexiunile intr\u00eende.
+Network.alert.acceptfail=Prea multe e\u0219ecuri succesive ap\u0103rute pe portul %1, %2 - am abandonat procesarea. Verific\u0103 specifica\u021biile parafocului [firewall] pentru acest port, ca s\u0103 te asiguri c\u0103 este autorizat pentru conexiunile intr\u00eende.
 MyShares.column.category=Categorie
 UpdateWindow.restartLater=Reporne\u0219te Vuze Mai T\u00eerziu
 MainWindow.menu.file.restart=Reporne\u0219te Vuze
 MainWindow.dialog.restartconfirmation.title=Repornesc Vuze?
-MainWindow.dialog.restartconfirmation.text=Sigur dori\u021bi sa reporni\u021bi Vuze?
-deletetorrent.message1=S\u00eente\u021bi pe punctul de a \u0219terge TORENTUL lui :\n
-deletetorrent.message2=\nSigur dori\u021bi s\u0103 continua\u021bi?
-ConfigView.label.prioritizemostcompletedfiles=Prioritizeaz\u0103 suplimentar fi\u0219ierele cu prioritate \u00cenalt\u0103 \u00een func\u021bie de procentul de realizare \u0219i de m\u0103rimea fi\u0219ierului
-splash.plugin.init=Ini\u021bializez Extensia: 
-splash.plugin.UIinit=Ini\u021bializez Extensia GUI: %1  
+MainWindow.dialog.restartconfirmation.text=Sigur vrei sa reporne\u0219ti Vuze?
+ConfigView.label.prioritizemostcompletedfiles=Prioritizeaz\u0103 suplimentar filele cu prioritate \u00cenalt\u0103 \u00een func\u021bie de procentul de realizare \u0219i de m\u0103rimea filei
+splash.plugin.init=Ini\u021bializez Extensia:
+splash.plugin.UIinit=Ini\u021bializez Extensia GUI: %1
 ConfigView.section.style.osx_small_fonts=Folose\u0219te corpuri de liter\u0103 mici (necesit\u0103 repornire)
 ConfigView.section.tracker.tcpnonblocking=Folose\u0219te intr\u0103ri/ie\u0219iri f\u0103r\u0103 blocare pentru procesarea de trackere TCP. Selectarea op\u021biunii necesit\u0103 ca re\u021beaua de trackere s\u0103 fie accesat\u0103 pe un port alternativ. Experimental!
 ConfigView.section.tracker.nonblocking=Op\u021biuni de deblocare
@@ -1375,14 +1357,14 @@ ConfigView.section.tracker.client.scrapeinfo=Dezactivarea r\u0103zuirii \u00eemp
 ConfigView.section.tracker.client.scrapeenable=Activeaz\u0103 r\u0103zuirea [scraping]
 ConfigView.section.tracker.client.scrapestoppedenable=R\u0103zuie\u0219te torentele care nu s\u00eent active
 Scrape.status.disabled=R\u0103zuire Dezactivat\u0103 [scrape]
-MyTorrentsView.menu.explore=Arat\u0103 Fi\u0219ierul
+MyTorrentsView.menu.explore=Arat\u0103 Fila
 MyTorrentsView.menu.explore._mac=Arat\u0103 \u00een G\u0103sitor
 MyTorrentsView.menu.explore._windows=Arat\u0103 \u00een Explorator
 wizard.maketorrents.autohost=G\u0103zduie\u0219te torentul \u00een trackerul \u00eencorporat
-ConfigView.label.overrideip=Ignor\u0103 anun\u021b\u0103rile de adres\u0103 IP ale trackerului - separa\u021bi cu punct-\u0219i-virgul\u0103 dac\u0103 s\u00eent mai multe adrese (pt. re\u021bele diferite).
-ConfigView.label.overrideip.tooltip=Informeaz\u0103 trackerul despre adresele IP diferite de cea de la care vin pachetele dinspre exterior. L\u0103sa\u021bi spa\u021biul gol dac\u0103 op\u021biunea nu e folosit\u0103.
+ConfigView.label.overrideip=Ignor\u0103 anun\u021b\u0103rile de adres\u0103 IP ale trackerului - separ\u0103 cu punct-\u0219i-virgul\u0103 dac\u0103 s\u00eent mai multe adrese (pt. re\u021bele diferite).
+ConfigView.label.overrideip.tooltip=Informeaz\u0103 trackerul despre adresele IP diferite de cea de la care vin pachetele dinspre exterior. Las\u0103 spa\u021biul gol dac\u0103 op\u021biunea nu e folosit\u0103.
 ConfigView.section.connection.group.networks=Re\u021bele
-ConfigView.section.connection.group.networks.info=Selecta\u021bi re\u021belele permise implicit pt. transmisia de date partener-la-partener
+ConfigView.section.connection.group.networks.info=Selecteaz\u0103 re\u021belele permise implicit pt. transmisia de date partener-la-partener
 ConfigView.section.connection.networks.prompt=Aten\u021bioneaz\u0103-m\u0103 s\u0103 selectez atunci c\u00eend e ad\u0103ugat\u0103 o desc\u0103rcare cu tracker anonim
 ConfigView.section.connection.networks.Public=Re\u021bea IP public\u0103 (nu anonim\u0103)
 ConfigView.section.connection.networks.I2P=Re\u021bea I2P
@@ -1391,13 +1373,13 @@ TableColumn.header.networks=Re\u021bele
 TableColumn.header.networks.info=Re\u021bele permise pentru transferul de date partener-la-partener
 Scrape.status.networkdisabled=Re\u021beaua nu e activat\u0103
 ConfigView.section.tracker.server.group.networks=Re\u021bele
-ConfigView.section.tracker.server.group.networks.info=Alege\u021bi re\u021belele din care trackerul va accepta parteneri
+ConfigView.section.tracker.server.group.networks.info=Alege re\u021belele din care trackerul va accepta parteneri
 window.networkselection.title=Selectarea Re\u021belei
-window.networkselection.info=Torentul de mai jos are un tracker care accept\u0103 re\u021belele urm\u0103toare.\nAlege\u021bi-le pe cele pe care dori\u021bi s\u0103 le activa\u021bi pentru comunic\u0103ri cu trackerul \u0219i cu partenerii.\nDac\u0103 e un tracker anonim care accept\u0103 clien\u021bi publici, activa\u021bi at\u00eet re\u021beaua anonim\u0103 c\u00eet \u0219i pe cea public\u0103.\nActivarea re\u021belei publice are drept consecin\u021b\u0103 pierderea anonimatului!
+window.networkselection.info=Torentul de mai jos are un tracker care accept\u0103 re\u021belele urm\u0103toare.\nAlege-le pe cele pe care vrei s\u0103 le activezi pentru comunic\u0103ri cu trackerul \u0219i cu partenerii.\nDac\u0103 e un tracker anonim care accept\u0103 clien\u021bi publici, activeaz\u0103 at\u00eet re\u021beaua anonim\u0103 c\u00eet \u0219i pe cea public\u0103.\nActivarea re\u021belei publice are drept consecin\u021b\u0103 pierderea anonimatului!
 window.networkselection.description=Torent :
 plugins.basicview.clear=Cur\u0103\u021b\u0103
 ConfigView.section.connection.group.peersources=Donatorii Partenerilor
-ConfigView.section.connection.group.peersources.info=Selecta\u021bi sursele implicite permise pentru conect\u0103rile cu partenerii
+ConfigView.section.connection.group.peersources.info=Selecteaz\u0103 sursele implicite permise pentru conect\u0103rile cu partenerii
 ConfigView.section.connection.peersource.Tracker=De la un tracker
 ConfigView.section.connection.peersource.DHT=Tracking descentralizat
 ConfigView.section.connection.peersource.PeerExchange=Oferit de un alt partener
@@ -1416,37 +1398,37 @@ ConfigView.section.sharing.protocol=Protocol pentru resurse partajate \u00een mo
 PeersView.Messaging=Mesagerie
 PeersView.Messaging.info=Indic\u0103 ce sistem de mesagerie este \u00een uz.
 ConfigView.label.queue.newseedsmovetop=Mut\u0103 torentele recent terminate \u00een v\u00eerful listei de don\u0103ri
-ConfigView.label.seeding.firstPriority.ignore.info=Tine\u021bi seama c\u0103 folosirea acestor reguli poate duce la\n oprirea torentului imediat ce se termin\u0103 desc\u0103rcarea.
+ConfigView.label.seeding.firstPriority.ignore.info=\u021aine seam\u0103 c\u0103 folosirea acestor reguli poate duce la\n oprirea torentului imediat ce se termin\u0103 desc\u0103rcarea.
 ConfigView.label.seeding.firstPriority.ignore=Ignor\u0103 regulile de Prim\u0103 Prioritate pentru:
 ConfigView.label.seeding.firstPriority.ignoreSPRatio=Torente cu un raport Donatori/Parteneri peste
 ConfigView.label.seeding.firstPriority.ignore0Peer=Torente cu 0 parteneri
 ConfigView.section.tracker.sendjavaversionandos=Trimite versiunea de JAVA \u0219i numele SO
 MagnetPlugin.contextmenu.exporturi=Copiaz\u0103 Leg\u0103tura Magnet \u00een Cliplan\u0219et\u0103
 ConfigView.section.plugins.dht=BD Distribuit\u0103
-dht.info=Aceast\u0103 extensie permite urm\u0103rirea [tracking] descentralizat\u0103, printre altele. Dac\u0103 o dezactiva\u021bi, va scade capacitatea de desc\u0103rcare.
+dht.info=Aceast\u0103 extensie permite urm\u0103rirea [tracking] descentralizat\u0103, printre altele. Dac\u0103 o dezactivezi, va scade capacitatea de desc\u0103rcare.
 dht.enabled=Activeaz\u0103 baza de date distribuit\u0103
 dht.portdefault=Folose\u0219te portul implicit
 dht.port=Port UDP pentru baza de date
 dht.execute.command=Comand\u0103 de diagnosticare
-dht.execute.info=Ap\u0103sa\u021bi pentru a executa comanda
+dht.execute.info=Apas\u0103 pentru a executa comanda
 dht.execute=Ruleaz\u0103
 dht.logging=Activeaz\u0103 \u00eenregistrarea activit\u0103\u021bii
 ConfigView.section.plugins.dhttracker=Tracker Distribuit
 dhttracker.tracknormalwhenoffline=Urm\u0103re\u0219te [track] numai torentele normale atunci c\u00eend trackerul lor este indisponibil.
-ConfigView.section.file.nativedelete._mac=Folose\u0219te Reciclatorul pentru \u0219tergerea fi\u0219ierelor
-ConfigView.section.file.nativedelete._windows=Mut\u0103 fi\u0219ierele \u0219terse \u00een Reciclator
+ConfigView.section.file.nativedelete._mac=Folose\u0219te Reciclatorul pentru \u0219tergerea filelor
+ConfigView.section.file.nativedelete._windows=Mut\u0103 filele \u0219terse \u00een Reciclator
 ConfigView.section.logging.generatediagnostics=Genereaz\u0103
 ConfigView.section.logging.netinfo=Genereaz\u0103 informa\u021bii despre re\u021bea
 ConfigView.section.logging.statsinfo=Genereaz\u0103 informa\u021bii statistice
-ConfigView.section.logging.generatediagnostics.info=Genereaz\u0103 informa\u021bii de diagnosticare \u0219i copiaz\u0103-le \u00een cliplan\u0219et\u0103 \u0219i fi\u0219ierul jurnalului, dac\u0103 e configurat.
+ConfigView.section.logging.generatediagnostics.info=Genereaz\u0103 informa\u021bii de diagnosticare \u0219i copiaz\u0103-le \u00een cliplan\u0219et\u0103 \u0219i fila jurnalului, dac\u0103 e configurat\u0103.
 ConfigView.section.sharing.privatetorrent=Torent privat - accept\u0103 parteneri numai prin tracker
-MainWindow.menu.tools.nattest=Test pentru &NAT / Paravan
+MainWindow.menu.tools.nattest=Test pentru &NAT / Parafoc
 Button.apply=Aplic\u0103
 Button.close=\u00cenchide
-window.welcome.title=Bine a\u021bi venit la Vuze %1
+window.welcome.title=Bine ai venit la Vuze %1
 #file can be a URL or a path in the jar
 MainWindow.menu.help.releasenotes=Note de Lansare
-dht.reseed.label=\u00cen mod normal nu e nevoie de repopularea bazei de date distribuite. Cu toate acestea, \u00een cazul \u00een care num\u0103rul de contacte e mic, aceasta poate fi folosit\u0103 pentru reintegrare.\nL\u0103sa\u021bi gol pentru a repopula cu date de la partenerii conecta\u021bi sau scrie\u021bi IP-ul \u0219i portul pentru a fi folosite la repopularea cu date de la un partener cunoscut.
+dht.reseed.label=\u00cen mod normal nu e nevoie de repopularea bazei de date distribuite. Cu toate acestea, \u00een cazul \u00een care num\u0103rul de contacte e mic, aceasta poate fi folosit\u0103 pentru reintegrare.\nLas\u0103 gol pentru a repopula cu date de la partenerii conecta\u021bi sau scrie IP-ul \u0219i portul pentru a fi folosite la repopularea cu date de la un partener cunoscut.
 dht.reseed.group=Redoneaz\u0103
 dht.reseed.ip=Adresa IP
 dht.reseed=Redoneaz\u0103
@@ -1501,14 +1483,14 @@ MainWindow.dht.status.disabled=DHT Dezactivat
 MainWindow.dht.status.failed=DHT E\u0219uat
 MainWindow.dht.status.initializing=Ini\u021bializez DHT
 MainWindow.dht.status.users=%1 utilizatori
-MainWindow.dht.status.unreachable=DHT Paravanat
-MainWindow.dht.status.unreachabletooltip=Se pare c\u0103 exist\u0103 o problem\u0103 cu maparea porturilor UDP ale bazei de date distribuite (NAT/paravan)
+MainWindow.dht.status.unreachable=DHT Parafocat
+MainWindow.dht.status.unreachabletooltip=Se pare c\u0103 exist\u0103 o problem\u0103 cu maparea porturilor UDP ale bazei de date distribuite (NAT/parafoc)
 MyTorrentsView.menu.setUpSpeed=Seteaz\u0103 Viteza de \u00cenc\u0103rcare
 MyTorrentsView.menu.setDownSpeed=Seteaz\u0103 Viteza de Desc\u0103rcare
 ConfigView.section.tracker.client.showwarnings=Arat\u0103 mesajele de avertizare emise de trackere
 dht.advanced=Activeaz\u0103 set\u0103rile avansate
 dht.advanced.group=Set\u0103ri Avansate
-dht.advanced.label=Modifica\u021bi aceste valori numai dac\u0103 \u0219ti\u021bi cu adev\u0103rat ce face\u021bi
+dht.advanced.label=Modific\u0103 aceste valori numai dac\u0103 \u0219tii cu adev\u0103rat ce faci
 dht.override.ip=Ignor\u0103 adresa IP extern\u0103
 ConfigView.section.logging.loggerenable=Activeaz\u0103 jurnalizarea
 ConfigView.section.ipfilter.blockbanning=Blocheaz\u0103 un interval de 256 de adrese atunci c\u00eend cel pu\u021bin at\u00eetea din interval au fost blocate.
@@ -1518,16 +1500,15 @@ TableColumn.header.swarm_average_speed.info=Viteza medie a partenerilor din roi
 TableColumn.header.comment=Comentariu
 TableColumn.header.comment.info=Comentariul utilizatorului despre desc\u0103rcare
 TableColumn.header.commenticon=Comentariu
-TableColumn.header.commenticon.info=Iconi\u021ba e afi\u0219at\u0103 c\u00eend desc\u0103rcarea are un comentariu pus de utilizator
+TableColumn.header.commenticon.info=Icoana e afi\u0219at\u0103 c\u00eend desc\u0103rcarea are un comentariu pus de utilizator
 MyTrackerView.category=Categorie
-MainWindow.menu.file.open.torrentfortracking=Fi\u0219ier Torent... (Doar Tracking)
+MainWindow.menu.file.open.torrentfortracking=Fil\u0103 Torent... (Doar Tracking)
 MyTrackerView.date_added=Ad\u0103ugat
 ConfigView.section.tracker.portbackup=Porturi de rezerv\u0103 (separate cu ';')
-ConfigView.label.playfilespeech=Vorbe\u0219te c\u00eend se termin\u0103 un fi\u0219ier
-ConfigView.label.playfilespeech.info=Serviciile de Vorbire merg momentan mai bine \u00een Englez\u0103
-ConfigView.label.playfilefinished=Emite un sunet c\u00eend un fi\u0219ier este terminat
-ConfigView.label.backupconfigfiles=Salvgardeaz\u0103 [backup] fi\u0219ierele de configurare pentru a le folosi la restaur\u0103ri.
-ConfigView.section.tracker.client.scrapesingleonly=Dezactiveaz\u0103 agregarea r\u0103zuirilor pe fiecare tracker (poate ajuta cu trackerele care \u00eentorc eroarea 'URL too long' (414)) 
+ConfigView.label.playfilespeech=Vorbe\u0219te c\u00eend se termin\u0103 o fil\u0103
+ConfigView.label.playfilefinished=Emite un sunet c\u00eend o fil\u0103 este terminat\u0103
+ConfigView.label.backupconfigfiles=Salvgardeaz\u0103 [backup] filele de configurare pentru a le folosi la restaur\u0103ri.
+ConfigView.section.tracker.client.scrapesingleonly=Dezactiveaz\u0103 agregarea r\u0103zuirilor pe fiecare tracker (poate ajuta cu trackerele care \u00eentorc eroarea 'URL too long' (414))
 dht.ipfilter.log=Logheaz\u0103 viol\u0103rile Filtrului IP
 ConfigView.label.seeding.addForSeedingDLCopyCount=Consider\u0103 c\u0103 desc\u0103rc\u0103rile "ad\u0103ugate pentru donare" au fost deja desc\u0103rcate de acest num\u0103r de ori
 ActivityView.legend.limit=Viteza Limit\u0103
@@ -1536,39 +1517,48 @@ ActivityView.legend.overhead=Dep\u0103\u0219ire a Vitezei
 ActivityView.legend.peeraverage=Medie
 ActivityView.legend.swarmaverage=Media pe roi
 ActivityView.legend.trimmed=Tuns (punctat)
-MyTorrentsView.menu.movemenu=Mut\u0103 Fi\u0219ierele
-MyTorrentsView.menu.movedata=Mut\u0103 Fi\u0219ierele cu Date...
-MyTorrentsView.menu.movetorrent=Mut\u0103 Fi\u0219ierul Torent...
-MyTorrentsView.menu.movedata.dialog=Alege\u021bi un loc nou
+MyTorrentsView.menu.movemenu=Mut\u0103 Filele
+MyTorrentsView.menu.movedata=Mut\u0103 Filele cu Date...
+MyTorrentsView.menu.movetorrent=Mut\u0103 Fila Torent...
+MyTorrentsView.menu.movedata.dialog=Alege un loc nou
 DHTView.operations.data=Date
 DHTView.general.reachable=Conectabile:
 DHTView.general.rendezvous=\u00cent\u00eelniri:
 ConfigView.label.queue.maxactivetorrentswhenseeding=Nr. max de torente atunci c\u00eend doar se doneaz\u0103 [0:nelimitat]
 Views.plugins.IRC.title=Ajutor prin IRC
+Formats.units.Tibit=Tibi\u021bi
+Formats.units.Tbit=Tbi\u021bi
+Formats.units.Gibit=Gibi\u021bi
+Formats.units.Gbit=Gbi\u021bi
+Formats.units.Mibit=Mibi\u021bi
+Formats.units.Mbit=Mbi\u021bi
+Formats.units.Kibit=Kibi\u021bi
+Formats.units.kbit=kbi\u021bi
+Formats.units.bit=bi\u021bi
 Formats.units.alot=Multe !!!
 ConfigView.section.ipfilter.persistblocking=Salveaz\u0103 adresele IP blocate \u00eentre sesiuni
-FilesView.menu.rename=Redenume\u0219te sau Re\u021binte\u0219te
-FilesView.menu.rename_only=Redenume\u0219te
+FilesView.menu.rename=Renume\u0219te sau Re\u021binte\u0219te
+FilesView.menu.rename_only=Renume\u0219te
 FilesView.menu.retarget=Re\u021binte\u0219te
-FilesView.rename.choose.path=Alege un fi\u0219ier nou sau unul existent
-FilesView.rename.choose.path.dir=Alege\u021bi un dosar nou sau pe cel existent
+FilesView.rename.choose.path=Alege o fil\u0103 nou\u0103 sau una existent\u0103
+FilesView.rename.choose.path.dir=Alege un dosar nou sau pe cel existent deja
 FilesView.rename.confirm.delete.title=Confirm\u0103 \u0218tergerea
-FilesView.rename.confirm.delete.text=Confirm\u0103 \u0219tergerea fi\u0219ierului original '%1'
-FilesView.rename.filename.title=Redenume\u0219te Fi\u0219ierul
-FilesView.rename.filename.text=Alege\u021bi un nou nume pentru fi\u0219ier
+FilesView.rename.confirm.delete.text=Confirm\u0103 \u0219tergerea filei originale '%1'
+FilesView.rename.filename.title=Renume\u0219te Fila
+FilesView.rename.filename.text=Alege un nume nou pentru fil\u0103
 ConfigView.higher.mode.available=Mai multe op\u021biuni s\u00eent prezente \u00een modurile avansate
 ConfigView.section.mode=Afi\u0219area Op\u021biunilor
 ConfigView.section.mode.title=Utilizator
 ConfigView.section.mode.beginner=\u00cencep\u0103tor
-ConfigView.section.mode.beginner.wiki.definitions=Vocabular BitTorrent
+ConfigView.section.mode.beginner.wiki.definitions=Vocabularul BitTorrent
 ConfigView.section.mode.intermediate=Intermediar
-ConfigView.section.mode.intermediate.wiki.host=G\u0103zduirea Fi\u0219ierelor
-ConfigView.section.mode.intermediate.wiki.publish=Publicarea Fi\u0219ierelor
+ConfigView.section.mode.intermediate.wiki.host=G\u0103zduirea Filelor
+ConfigView.section.mode.intermediate.wiki.publish=Publicarea Filelor
 ConfigView.section.mode.advanced=Avansat
-ConfigView.section.mode.advanced.wiki.main=Pagina Principal\u0103 Wiki
-ConfigView.section.mode.beginner.text=Tot ce v\u0103 trebuie pentru a desc\u0103rca torente.\nFolosi\u021bi acest mod dac\u0103 dori\u021bi doar s\u0103 administra\u021bi torentele.
-ConfigView.section.mode.intermediate.text=Acces la func\u021biile trackerului.\nFolosi\u021bi acest nivel dac\u0103 dori\u021bi s\u0103 v\u0103 crea\u021bi propriul tracker \u0219i s\u0103 g\u0103zdui\u021bi/publica\u021bi propriile fi\u0219iere.
-ConfigView.section.mode.advanced.text=Set\u0103rile Re\u021belei.\nFolosi\u021bi acest nivel dac\u0103 \u0219ti\u021bi ce \u00eenseamn\u0103 MTU sau intr\u0103rile/ie\u0219irile neblocate...
+ConfigView.section.mode.advanced.wiki.main=Wikiul Vuze
+ConfigView.section.mode.beginner.text=Tot ce-\u021bi trebuie pentru a desc\u0103rca torente.\nFolose\u0219te acest mod dac\u0103 vrei doar s\u0103 administrezi torentele.
+ConfigView.section.mode.intermediate.text=Acces la func\u021biile trackerului.\nFolose\u0219te acest nivel dac\u0103 vrei s\u0103-\u021bi creezi propriul tracker \u0219i s\u0103 g\u0103zduie\u0219ti/publici propriile file.
+ConfigView.section.mode.advanced.text=Set\u0103rile Re\u021belei.\nFolose\u0219te acest nivel dac\u0103 \u0219tii ce \u00eenseamn\u0103 MTU sau intr\u0103rile/ie\u0219irile neblocate...
 Files.column.storagetype=Tip de Stocare
 Files.column.fileext=Tip
 FileItem.storage.linear=Liniar
@@ -1580,17 +1570,17 @@ ConfigView.section.interface.cleartrackers=Cur\u0103\u021b\u0103 trackerele memo
 ConfigView.section.interface.cleartrackersbutton=Cur\u0103\u021b\u0103
 ConfigView.section.interface.clearsavepaths=Cur\u0103\u021b\u0103 c\u0103ile de salvare memorate
 ConfigView.section.interface.clearsavepathsbutton=Cur\u0103\u021b\u0103
-configureWizard.welcome.usermodes=Aceast\u0103 setare a Priceperii Utilizatorului va determina nivelul op\u021biunilor afi\u0219ate \u00een Unelte>Op\u021biuni. E \u00een interesul dv. s\u0103 alege\u021bi setarea potrivit\u0103.
-FilesView.skip.confirm.delete.text=Trunchiez fi\u0219ierul '%1' pentru a economisi spa\u021biu?
-FilesView.rename.failed.title=Redenumire/Redirec\u021bionare e\u0219uat\u0103
+configureWizard.welcome.usermodes=Aceast\u0103 setare a Priceperii Utilizatorului va determina nivelul op\u021biunilor afi\u0219ate \u00een Unelte>Op\u021biuni. E \u00een interesul t\u0103u s\u0103 alegi setarea potrivit\u0103.
+FilesView.skip.confirm.delete.text=Trunchiez fila '%1' pentru a economisi spa\u021biu?
+FilesView.rename.failed.title=Renumire/Redirec\u021bionare e\u0219uat\u0103
 FilesView.rename.failed.text=Opera\u021biunea a e\u0219uat, probabil din cauza select\u0103rii incorecte a \u021bintei
-diagnostics.log_found=Vuze nu s-a \u00eenchis cum trebuie. Verifica\u021bi <A HREF="%1">jurnalul de diagnosticare</A>. De asemenea citi\u021bi articolul din wiki <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">Vuze Dispare</A> pt. informa\u021bii suplimentare.
+diagnostics.log_found=Vuze nu s-a \u00eenchis cum trebuie. Verific\u0103 <A HREF="%1">jurnalul de diagnosticare</A>. De asemenea cite\u0219te articolul din wiki <A HREF="http://www.azureuswiki.com/index.php/Vuze_disappears">Vuze Dispare</A> pt. informa\u021bii suplimentare.
 ManagerItem.paused=Pauzat
-Utils.link.visit=V\u0103 rug\u0103m s\u0103 vizita\u021bi
+Utils.link.visit=Viziteaz\u0103
 ConfigView.section.connection.serverport.wiki=Op\u021biuni bune pt. porturi
 ConfigView.section.transfer.speeds.wiki=Set\u0103ri bune ale vitezei
 installPluginsWizard.installMode.info.title=Informa\u021bii
-installPluginsWizard.installMode.info.text=Nu ave\u021bi nevoie de extensii pentru a folosi Vuze, extensiile s\u00eent bune pentru facilit\u0103\u021bi suplimentare, automatizare sau control de la distan\u021b\u0103.\nA\u0219adar v\u0103 rug\u0103m s\u0103 citi\u021bi cu aten\u021bie descrierea fiec\u0103reia dintre extensii \u00eenainte de a hot\u0103r\u00ee dac\u0103 o instala\u021bi.\nMajoritatea extensiilor pot fi testate f\u0103r\u0103 probleme, dar nu supra\u00eenc\u0103rca\u021bi  [...]
+installPluginsWizard.installMode.info.text=Nu este nevoie de extensii pentru a folosi Vuze, extensiile s\u00eent bune pentru facilit\u0103\u021bi suplimentare, automatizare sau control de la distan\u021b\u0103.\nA\u0219adar te rug\u0103m s\u0103 cite\u0219ti cu aten\u021bie descrierea fiec\u0103reia dintre extensii \u00eenainte de a hot\u0103r\u00ee dac\u0103 o instalez\u021bi.\nMajoritatea extensiilor pot fi testate f\u0103r\u0103 probleme, dar nu supra\u00eenc\u0103rca configura\u021bi [...]
 Views.plugins.Distributed.DB.title=Baz\u0103 de Date Distribuit\u0103
 Views.plugins.Distributed.Tracker.title=Tracker Distribuit
 Views.plugins.Plugin.Update.title=Actualizarea Extensiilor
@@ -1599,12 +1589,12 @@ TableColumn.header.swarm_average_completion=Realizarea Medie a Partenerilor
 TableColumn.header.swarm_average_completion.info=Procentul mediu de realizare (terminare) al partenerilor din roi
 GeneralView.label.swarm_average_completion=Progres Mediu:
 GeneralView.label.swarm_average_completion.tooltip=Procentajul mediu de realizare a desc\u0103rc\u0103rii la partenerii din roi.
-MainWindow.nat.status.tooltip.unknown=Starea accesibilit\u0103\u021bii paravanului/NAT este necunoscut\u0103 (TCP)
+MainWindow.nat.status.tooltip.unknown=Starea accesibilit\u0103\u021bii parafocului/NAT este necunoscut\u0103 (TCP)
 MainWindow.nat.status.tooltip.ok=Accesibilitate OK (TCP)
 MainWindow.nat.status.tooltip.probok=Accesibilitatea este \u00een regul\u0103, totu\u0219i nu exist\u0103 conexiuni TCP intr\u00eende
-MainWindow.nat.status.bad=Paravanat
-MainWindow.nat.status.tooltip.bad=Problem\u0103 la accesibilitatea prin paravan/NAT (TCP). Consulta\u021bi Wikiul pentru ajutor.
-plugin.installer.recommended.plugin=Extensie recomandat\u0103 - verifica\u021bi \u0219i instala\u021bi dac\u0103 e nevoie
+MainWindow.nat.status.bad=Parafocat
+MainWindow.nat.status.tooltip.bad=Problem\u0103 la accesibilitatea prin parafoc/NAT (TCP). Cite\u0219te Wikiul pentru ajutor.
+plugin.installer.recommended.plugin=Extensie recomandat\u0103 - verific\u0103 \u0219i instaleaz\u0103 dac\u0103 e nevoie
 LoggerView.pause=Pauzeaz\u0103 Jurnalizarea
 LoggerView.clear=&Cur\u0103\u021b\u0103
 LoggerView.filter=Filtru
@@ -1616,7 +1606,7 @@ LoggerView.excludeAll=Nu afi\u0219a liniile care se potrivesc cu aceast\u0103 ex
 ConfigView.section.logging.log0type=Informa\u021bii
 ConfigView.section.logging.log1type=Avertisment
 ConfigView.section.logging.log2type=Eroare
-ConfigView.section.logging.filter=Filtreaz\u0103 la jurnalizarea \u00een fi\u0219ier
+ConfigView.section.logging.filter=Filtreaz\u0103 la jurnalizarea \u00een fil\u0103
 ConfigView.section.logging.level=Nivelul Jurnaliz\u0103rii
 ConfigView.section.logging.showLogsFor=Arat\u0103 %1 jurnale pentru categoriile:
 ConfigView.pluginlist.column.loadAtStartup=Porne\u0219te odat\u0103 cu SO
@@ -1629,21 +1619,21 @@ ConfigView.pluginlist.column.version=Versiune
 ConfigView.pluginlist.column.directory=Dosar
 ConfigView.pluginlist.column.isOperational=Opera\u021bional?
 PeersView.BlockView.Avail.Have=Ambii ave\u021bi
-PeersView.BlockView.Avail.NoHave=Partenerul are, Dv. nu
-PeersView.BlockView.NoAvail.Have=Dv. ave\u021bi, Partenerul nu
+PeersView.BlockView.Avail.NoHave=Partenerul are, Tu nu
+PeersView.BlockView.NoAvail.Have=Tu ai, Partenerul nu
 PeersView.BlockView.NoAvail.NoHave=Nici unul n-are
 PeersView.BlockView.Transfer=Transfer
 PeersView.BlockView.NextRequest=Urm\u0103toarea Solicitare
 PeersView.BlockView.title=Harta P\u0103r\u021bilor
 PeersView.BlockView.AvailCount=Num\u0103rul Disponibilit\u0103\u021bilor
 MyTorrentsView.dialog.NumberError.title=Num\u0103r Invalid sau Nerecunoscut
-MyTorrentsView.dialog.NumberError.text=Num\u0103rul pe care l-a\u021bi introdus e invalid sau nerecunoscut.
+MyTorrentsView.dialog.NumberError.text=Num\u0103rul pe care l-ai introdus e nevalid sau nerecunoscut.
 MyTorrentsView.menu.manual=&Manual\u0103...
 MyTorrentsView.menu.manual.per_torrent=Manual\u0103 (per torent)
 MyTorrentsView.menu.manual.shared_torrents=Manual\u0103 (pt. toate torentele)
 MyTorrentsView.dialog.setSpeed.title=Seteaz\u0103 viteza %1
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
-MyTorrentsView.dialog.setNumber.text=Introduce\u021bi un num\u0103r %1 pentru a schimba %2 \u00een:
+MyTorrentsView.dialog.setNumber.text=Introdu un num\u0103r %1 pentru a schimba %2 \u00een:
 MyTorrentsView.dialog.setNumber.upload=\u00eenc\u0103rcare
 MyTorrentsView.dialog.setNumber.download=desc\u0103rcare
 MyTorrentsView.dialog.setNumber.inKbps=\u00een %1
@@ -1652,15 +1642,15 @@ OpenTorrentWindow.addFiles.URL=Adaug\u0103 &Adres\u0103
 OpenTorrentWindow.addFiles.Folder=Adaug\u0103 &Dosar
 OpenTorrentWindow.addFiles.Clipboard=Adaug\u0103 din Clip&lan\u0219et\u0103
 OpenTorrentWindow.changeDestination=Schimb\u0103 Destina\u021bia
-OpenTorrentWindow.fileList=Fi\u0219iere \u00een torente:
+OpenTorrentWindow.fileList=File \u00een torente:
 OpenTorrentWindow.torrentTable.name=Nume
 OpenTorrentWindow.torrentTable.saveLocation=Loc de Salvare
-OpenTorrentWindow.fileTable.fileName=Numele Fi\u0219ierului
+OpenTorrentWindow.fileTable.fileName=Numele Filei
 OpenTorrentWindow.fileTable.size=M\u0103rime
 OpenTorrentWindow.fileTable.destinationName=Nume la Destina\u021bie
 OpenTorrentWindow.startMode.seeding=Donare
 OpenTorrentWindow.fileList.changeDestination=Schimb\u0103 Destina\u021bia
-OpenTorrentWindow.mb.badSize.title=Fi\u0219ier Incompatibil
+OpenTorrentWindow.mb.badSize.title=Fil\u0103 Incompatibil\u0103
 OpenTorrentWindow.mb.badSize.text='%1' nu e '%2' si nu e folosibil pentru sadit.
 OpenTorrentWindow.mb.alreadyExists.text=Torentul '%1' a fost deja ad\u0103ugat ca '%2'
 OpenTorrentWindow.mb.alreadyExists.title=Torentul exist\u0103 deja
@@ -1683,25 +1673,25 @@ ConfigView.section.file.readmblimit.explain=Acest parametru limiteaz\u0103 memor
 Button.moveUp=Mut\u0103 \u00een Sus
 Button.moveDown=Mut\u0103 \u00een Jos
 ConfigView.notAvailableForMode=Aceast\u0103 sec\u021biune e pentru modul %1 sau peste.  Nu e disponibil\u0103 \u00een modul %2.
-health.explain.error=Exist\u0103 o eroare in acest torent. Verifica\u021bi coloana de Stare sau pontul de pe iconi\u021b\u0103 pentru a o vedea.
+health.explain.error=Exist\u0103 o eroare in acest torent. Verific\u0103 coloana de Stare sau pontul de pe icoan\u0103 pentru a o vedea.
 GeneralView.label.trackerscrapeupdate=R\u0103zuie\u0219te Trackerul
 PeersView.piece=Parte
 PeersView.piece.info=Nr. ultimii p\u0103r\u021bi cerut\u0103 de acest partener
 PiecesView.priority=Prioritate
-PiecesView.priority.info=Prioritatea de realizare a p\u0103r\u021bii, nu-i acorda\u021bi prea mult\u0103 aten\u021bie
+PiecesView.priority.info=Prioritatea de realizare a p\u0103r\u021bii, nu-i acorda prea mult\u0103 aten\u021bie
 PiecesView.speed=Viteza
 PiecesView.speed.info=Partenerii len\u021bi s\u00eent \u00eempiedica\u021bi s\u0103 interfereze prea mult cu p\u0103r\u021bile rapide
 TableColumn.header.AvgAvail.info=Suma disponibilit\u0103\u021bii p\u0103r\u021bilor \u00eemp\u0103r\u021bit\u0103 la nr. de p\u0103r\u021bi \u0219i la nr. de conexiuni
 TableColumn.header.AvgAvail=Disp. Medie/parte
-ConfigView.label.strictfilelocking=Impune blocarea accesului exclusiv la scrierea fi\u0219ierelor \u00eentre torente
-MyTorrentsView.menu.checkfilesexist=Controleaz\u0103 Dac\u0103 Fi\u0219ierele Exist\u0103
+ConfigView.label.strictfilelocking=Impune blocarea accesului exclusiv la scrierea filelor \u00eentre torente
+MyTorrentsView.menu.checkfilesexist=Controleaz\u0103 Dac\u0103 Filele Exist\u0103
 MyTorrentsView.menu.rescanfile=Reverific\u0103 Periodic P\u0103r\u021bile Incomplete
 MyTorrentsView.menu.clear_resume_data=Cur\u0103\u021b\u0103 Datele de Reluare
 Plugin.extseed.name=Donatori Externi
 Plugin.localtracker.name=C\u0103ut\u0103tor de Parteneri \u00een LAN
 Plugin.localtracker.info=Cautatorul de parteneri LAN permite mai multe copii Vuze aflate dupa un zid-de-foc pe o retzea comuna\n pentru o tragere eficienta prin acceptarea de legaturi directe intre ele.
 Plugin.localtracker.enable=Activeaz\u0103 c\u0103ut\u0103torul de parteneri \u00een LAN
-azinstancehandler.alert.portclash=Conflict de porturi detectat pe LAN: %1 e deja folosit de alt utilizator Vuze. Alege\u021bi un port aleator nou (sau mai multe) pentru ascultarea intr\u0103rilor TCP/UDP [\u00eentre %2 \u0219i %3].
+azinstancehandler.alert.portclash=Conflict de porturi detectat pe LAN: %1 e deja folosit de alt utilizator Vuze. Alege un port aleator nou (sau mai multe) pentru ascultarea intr\u0103rilor TCP/UDP [\u00eentre %2 \u0219i %3].
 ConfigView.section.transfer.lan.tooltip=Set\u0103ri specifice pt. LAN
 ConfigView.section.transfer.lan.uploadrate=KB/s viteza max de \u00eenc\u0103rcare \u00een LAN [0: nelimitat]
 ConfigView.section.transfer.lan.uploadrate.tooltip=Conexiunile cu partenerii din aceea\u0219i re\u021bea local\u0103 (LAN) au o limit\u0103 separat\u0103 a vitezei de \u00eenc\u0103rcare.
@@ -1716,8 +1706,8 @@ ConfigView.section.connection.encryption.min_encryption_level=Nivelul minim de c
 ConfigView.section.connection.encryption.min_encryption_level.tooltip=Simpl\u0103 - doar str\u00eengerea de m\u00een\u0103\nRC4 - fluxul complet\nCript\u0103rile complexe folosesc mai multe resurse ale CPU.
 Peers.column.Encryption=Criptare
 Peers.column.Encryption.info=Puterea cript\u0103rii folosite
-ConfigView.section.connection.encryption.encrypt.info=Dac\u0103 este activat\u0103 criptarea nu v\u0103 ve\u021bi putea conecta la clien\u021bi (softuri) incompatibili p\u00een\u0103 ce nu configura\u021bi op\u021biunile de rezerv\u0103
-ConfigView.section.connection.encryption.encrypt.info.link=Clica\u021bi aici pentru detalii
+ConfigView.section.connection.encryption.encrypt.info=Dac\u0103 este activat\u0103 criptarea, nu te vei putea conecta la softuri client incompatibile p\u00een\u0103 ce nu configurezi op\u021biunile de rezerv\u0103
+ConfigView.section.connection.encryption.encrypt.info.link=Clicheaz\u0103 aici pentru detalii
 MainWindow.sr.status.tooltip.ok=Raport de Partajare %1 OK
 MainWindow.sr.status.tooltip.poor=Raport de Partajare %1 slab: < 0.9
 MainWindow.sr.status.tooltip.bad=Raport de Partajare %1 prost: < 0.5
@@ -1727,7 +1717,7 @@ ConfigView.section.style.status.show_nat=Starea NAT
 ConfigView.section.style.status.show_ddb=Starea BDD
 ConfigView.section.style.status.show_ipf=Starea Filtrului IP
 ConfigView.section.connection.encryption.encrypt.group=Criptarea/Mascarea Transferului
-ConfigView.section.connection.encryption.encrypt.fallback_info=Activarea oric\u0103reia din op\u021biunile de rezerv\u0103 va permite conexiuni cu clien\u021bi incompatibili, \u00ceNS\u0102 conexiunile vor fi necriptate.
+ConfigView.section.connection.encryption.encrypt.fallback_info=Activarea oric\u0103reia din op\u021biunile de rezerv\u0103 va permite conexiuni cu softuri client incompatibile, \u00ceNS\u0102 conexiunile vor fi necriptate.
 ConfigView.section.connection.encryption.encrypt.fallback_outgoing=Permite conexiunile ie\u0219inde necriptate dac\u0103 tentativa de conectare criptat\u0103 e\u0219ueaz\u0103
 ConfigView.section.connection.encryption.encrypt.fallback_incoming=Permite conexiuni intr\u00eende necriptate
 ConfigView.section.connection.encryption=Criptarea Transferului
@@ -1743,9 +1733,9 @@ Button.unmarkSelected=Deselecteaz\u0103 Itemurile
 plugins.basicview.config=Configura\u021bie
 TorrentOptionsView.param.max.uploads=Nr. maxim de sloturi de \u00eenc\u0103rcare [minimum: 2]
 MyTorrentsView.dialog.setPosition.title=Seteaz\u0103 Pozi\u021bia
-MyTorrentsView.dialog.setPosition.text=Introduce\u021bi pozi\u021bia de setat pentru torentele alese:
+MyTorrentsView.dialog.setPosition.text=Introdu pozi\u021bia de setat pentru torentele alese:
 MyTorrentsView.menu.reposition.manual=Repozi\u021bioneaz\u0103..
-ConfigView.section.connection.advanced.info.link=Clica\u021bi aici pentru detalii
+ConfigView.section.connection.advanced.info.link=Clicheaz\u0103 aici pentru detalii
 ConfigView.section.connection.advanced.socket.group=Op\u021biunile Socketului
 ConfigView.section.connection.advanced.bind_port=Leag\u0103 de portul local [0:neactivat]
 ConfigView.section.connection.advanced.bind_port.tooltip=Conexiunile la socket ie\u0219inde vor fi legate local de portul specificat.\nActivarea acestei op\u021biuni poate ajuta \u00een cazul instabilit\u0103\u021bii ruterului NAT.
@@ -1759,24 +1749,25 @@ popup.error.hideall=Ascunde Tot
 ConfigView.section.style.dataStatsOnly=Arat\u0103 doar statisticile datelor (ascunde statisticile protocolului)
 ConfigView.section.style.separateProtDataStats=Arat\u0103 statisticile de date \u0219i de protocol \u00een mod separat ca 'date (protocol)'
 MyTorrentsView.dialog.setFilter.title=Modific\u0103 Filtrul
-MyTorrentsView.dialog.setFilter.text=Sec\u021biunea %1 va fi filtrat\u0103 dup\u0103 textul specificat mai jos.  Folosi\u021bi semnul | (\u021beav\u0103) pentru a filtra dup\u0103 fraze multiple. 
+MyTorrentsView.dialog.setFilter.text=Sec\u021biunea %1 va fi filtrat\u0103 dup\u0103 textul specificat mai jos.  Folose\u0219te semnul | (\u021beav\u0103) pentru a filtra dup\u0103 fraze multiple.
 MyTorrentsView.filter.tooltip=Ctrl+X pentru comutarea \u00eentre RegEx \u0219i moduri de c\u0103utare obi\u0219nuite.\nFolose\u0219te simbolul | (\u021beav\u0103) pentru a filtra cu fraze multiple.
 MyTorrentsView.clearFilter.tooltip=Cur\u0103\u021b\u0103 Filtrul
 MyTorrentsView.menu.filter=Lista de Filtre...
-ConfigView.section.file.resume.recheck.all=La pr\u0103bu\u0219ire-repornire verific\u0103 tot fi\u0219ierul pentru p\u0103r\u021bile terminate (altfel doar p\u0103r\u021bile active la ultima salvare s\u00eent verificate)
-ConfigureWizard.language.choose=Alege\u021bi o limb\u0103 din lista de mai jos:
+ConfigView.section.file.resume.recheck.all=La pr\u0103bu\u0219ire-repornire verific\u0103 toat\u0103 fila pentru p\u0103r\u021bile terminate (altfel doar p\u0103r\u021bile active la ultima salvare s\u00eent verificate)
+ConfigureWizard.language.choose=Alege o limb\u0103 din lista de mai jos:
 popup.closing.in=Anun\u021bul se va \u00eenchide \u00een %1 sec
 popup.more.waiting=%1 mesaj(e) \u00een plus..
 # > 2402
 popup.download.finished="%1" a fost desc\u0103rcat complet.
 popup.file.finished="%1" a fost desc\u0103rcat complet.
+ConfigView.auto=Automat
 Plugin.localtracker.autoadd.info=Adaug\u0103 automat ace\u0219ti parteneri locali [';' separ\u0103 adresele, de ex. 1.2.3.4]
 Plugin.localtracker.autoadd=Parteneri Explici\u021bi
 Plugin.localtracker.networks.info=Consider\u0103 re\u021belele urm\u0103toare ca fiind locale [separ\u0103 re\u021belele cu ';' de ex. 145.227.*.*]
 Plugin.localtracker.networks=Re\u021bele Locale
 MainWindow.menu.view.plugins.logViews=Jurnale de Activitate
 SpeedView.stats.autospeed=Vitez\u0103 Automat\u0103 de \u00cenc\u0103rcare
-SpeedView.stats.autospeed.disabled=Aceast\u0103 facilitate este fie dezactivat\u0103 (ave\u021bi nevoie de DHT), fie nu e \u00een uz (viteza de \u00eenc\u0103rcare e selectat\u0103 manual)
+SpeedView.stats.autospeed.disabled=Aceast\u0103 facilitate este fie dezactivat\u0103 (ai nevoie de DHT), fie nu e \u00een uz (viteza de \u00eenc\u0103rcare e selectat\u0103 manual)
 SpeedView.stats.idlePing=Ping Inactiv:
 SpeedView.stats.maxPing=Ping Max:
 SpeedView.stats.currentPing=Pingul Curent:
@@ -1797,8 +1788,8 @@ ConfigView.section.transfer.autospeed.enableautoseeding=Activeaz\u0103 doar c\u0
 ConfigView.pluginlist.column.unloadable=Ne\u00eenc\u0103rcabil
 ConfigView.section.transfer.lan.enable=Activeaz\u0103 limite de vitez\u0103 separate pentru conexiunile LAN
 Plugin.localtracker.wellknownlocals=Include automat re\u021belele locale de tip bucl\u0103 invers\u0103/leg\u0103tur\u0103/sit (192.168 etc.)
-TableColumn.header.filesdone=Fi\u0219iere Terminate
-TableColumn.header.filesdone.info=Fi\u0219iere Terminate/Toate Fi\u0219ierele *sau* Fi\u0219iere Nes\u0103rite Terminate (Fi\u0219iere Terminate)/Toate Fi\u0219ierele Nes\u0103rite (Toate Fi\u0219ierele)
+TableColumn.header.filesdone=File Terminate
+TableColumn.header.filesdone.info=File Terminate/Toate Filele *sau* File Nes\u0103rite Terminate (File Terminate)/Toate Filele Nes\u0103rite (Toate Filele)
 MagnetPlugin.private_torrent=<torent privat>
 MagnetPlugin.decentral_disabled=<tracking descentralizat dezactivat>
 MagnetPlugin.decentral_backup_disabled=<salvgardare descentralizat\u0103 dezactivat\u0103>
@@ -1829,20 +1820,20 @@ ConfigView.section.transfer.autospeed.enabledebug=F\u0103 un jurnal cu informa\u
 TableColumn.header.date_added=Data Ad\u0103ug\u0103rii
 TableColumn.header.date_added.info=Data la care a fost ad\u0103ugat torentul
 ConfigView.section.file.hashchecking.smallestfirst=Reverific\u0103 mai \u00eent\u00eei desc\u0103rc\u0103rile mici
-platform.win32.baddll.info=Vuze a detectat prezen\u021ba lui '%1'. Acesta face parte din '%2' \u0219i este cunoscut a cauza probleme grave cum s\u00eent pr\u0103bu\u0219iri ale aplica\u021biei \u0219i utilizare crescut\u0103 a procesorului. Dac\u0103 le \u00eent\u00eelni\u021bi dezinstala\u021bi softul respectiv sau configura\u021bi-l pentru a nu afecta func\u021bionarea Vuze.
+platform.win32.baddll.info=Vuze a detectat prezen\u021ba lui '%1'. Acesta face parte din '%2' \u0219i este cunoscut a cauza probleme grave cum s\u00eent pr\u0103bu\u0219iri ale aplica\u021biei \u0219i utilizare crescut\u0103 a procesorului. Dac\u0103 le \u00eent\u00eelne\u0219ti, dezinstaleaz\u0103 softul respectiv sau configureaz\u0103-l pentru a nu afecta func\u021bionarea Vuze.
 platform.win32.baddll.radhslib=Filtru de Internet Naomi (Radiant)
 platform.win32.baddll.winsflt=Filtru PureSight pt. Con\u021binut de pe Internet
 upnp.ignorebaddevices=Ignor\u0103 dispozitivele care nu r\u0103spund corect
 upnp.ignorebaddevices.info=Dispozitive ignorate acum: %1
 upnp.ignorebaddevices.reset=Reseteaz\u0103 lista cu dispozitive ignorate
 upnp.ignorebaddevices.reset.action=Reseteaz\u0103
-upnp.ignorebaddevices.alert=Dispozitivul UPnP din loca\u021bia %1 e ignorat din cauza unor defec\u021biuni repetate. Vede\u021bi configurarea extensiei UPnP pentru op\u021biunile \u00een privin\u021ba acestei ac\u021biuni.
+upnp.ignorebaddevices.alert=Dispozitivul UPnP din loca\u021bia %1 e ignorat din cauza unor defec\u021biuni repetate. Vezi configurarea extensiei UPnP pentru op\u021biunile \u00een privin\u021ba acestei ac\u021biuni.
 TorrentOptionsView.param.max.uploads.when.busy=KB/s vitez\u0103 max de \u00eenc\u0103rcare la atingerea limitei globale de \u00eenc\u0103rcare [0: dezactivat\u0103]
 UpdateMonitor.messagebox.verification.failed.title=Verificarea Instal\u0103rii a E\u0219uat
 UpdateMonitor.messagebox.verification.failed.text=Verificarea lui '%1' a e\u0219uat: %2
 UpdateMonitor.messagebox.accept.unverified.title=Accept\u0103 Instalarea Neverificat\u0103
-UpdateMonitor.messagebox.accept.unverified.text='%1' nu poate fi verificat\u0103 ca fiind o extensie original\u0103 Vuze.\nDac\u0103 acest lucru e adev\u0103rat NU ar trebui s\u0103 continua\u021bi instalarea.\nContinui cu instalarea?
-FileView.BlockView.title=P\u0103r\u021bi de Fi\u0219iere
+UpdateMonitor.messagebox.accept.unverified.text='%1' nu poate fi verificat\u0103 ca fiind o extensie original\u0103 Vuze.\nDac\u0103 acest lucru e adev\u0103rat, NU ar trebui s\u0103 continui instalarea.\nContinui cu instalarea?
+FileView.BlockView.title=P\u0103r\u021bi de File
 FileView.BlockView.Done=Realizat
 FileView.BlockView.Skipped=S\u0103rit
 FileView.BlockView.Active=Activ
@@ -1852,28 +1843,28 @@ ConfigView.label.udplistenport=Portul de ascultare UDP
 upnp.portchange.alert=Porturile urm\u0103toare au fost schimbate pentru a evita problemele cu dispozitivele UPnP: %1 [vechiul port=%2] %3 [vechiul port=%4]
 ConfigView.section.proxy.username.info=Dac\u0103 serverul proxy solicit\u0103 autentificarea chiar \u0219i c\u00eend nici una nu e definit\u0103, folose\u0219te \u0219irul "<nimic>" ca nume de utilizator
 ConfigView.label.maxuploadswhenbusymin=Viteza max. de \u00eenc\u0103rcare per torent cu temporizator ocupat [sec]
-MainWindow.menu.help.debug=Genereaz\u0103 Info de Debugare (Jurnalul Pr\u0103bu\u0219irii)
+MainWindow.menu.help.debug=Informa\u021bii pentru Debugare (\u00een caz de pr\u0103bu\u0219ire a softului)
 DownloadManager.error.badsize=M\u0103rime Incorect\u0103
-natpmp.info=NAT-PMP este alternativa Apple la UPnP \u0219i e suportat\u0103 de dispozitivele recente de tip Airport\n\nLua\u021bi not\u0103 de faptul c\u0103 UPnPtrebuie activat pentru ca NAT-PMP s\u0103 poat\u0103 fi la r\u00eendul s\u0103u activat, deoarece dispozitivul NAT-PMP e tratat ca un tip special de dispozitiv UPnP
+natpmp.info=NAT-PMP este alternativa Apple la UPnP \u0219i e suportat\u0103 de dispozitivele recente de tip Airport\n\nNoteaz\u0103 faptul c\u0103 UPnPtrebuie activat pentru ca NAT-PMP s\u0103 poat\u0103 fi la r\u00eendul s\u0103u activat, deoarece dispozitivul NAT-PMP e tratat ca un tip special de dispozitiv UPnP
 natpmp.enable=Activeaz\u0103 (trebuie s\u0103 fie activat \u0219i \u00een configura\u021bia Airport pentru a func\u021biona)
-ConfigView.section.tracker.host.addurls=Asigura\u021bi-v\u0103 c\u0103 adresele acestui tracker s\u00eent prezente \u00een torentele g\u0103zduite
-ConfigView.filter=tasta\u021bi textul de filtrare
+ConfigView.section.tracker.host.addurls=Asigur\u0103-te c\u0103 adresele acestui tracker s\u00eent prezente \u00een torentele g\u0103zduite
+ConfigView.filter=tasteaz\u0103 textul de filtrare
 ConfigView.section.files.move=Mutarea la Terminare
 ConfigView.section.file.defaultdir.section=Op\u021biunile Implicite ale Dosarelor
 ConfigView.section.file.defaultdir.auto=Descarc\u0103 \u00eentotdeauna \u00een dosarul implicit (f\u0103r\u0103 avertizare)
 ConfigView.section.file.defaultdir.bestguess=Folose\u0219te solu\u021bia cea mai potrivit\u0103 la alegerea dosarului implicit de salvare
-ConfigView.section.file.defaultdir.ask=Dosarul implicit: 
+ConfigView.section.file.defaultdir.ask=Dosarul implicit:
 ConfigView.section.file.defaultdir.lastused=Seteaz\u0103 dosarul implicit la locul ultimei salv\u0103ri
 ConfigView.section.file.config.section=Set\u0103ri de Configurare
 ConfigView.section.file.config.currentdir=Dosarul configura\u021biei curente:
 ConfigView.section.torrent.decoding=Seturi de Decodare a Caracterelor
 ConfigView.section.logging.udptransport=Activeaz\u0103 urm\u0103rirea detaliat\u0103 a transportului UDP
 Tracker.announce.ignorePeerSeed=Ignor nr. %1 de Part./Donatori
-ConfigView.section.connection.encryption.use_crypto_port=Folosi\u021bi extensia 'cryptoport' pentru tracker \u00een scopul prevenirii tentativelor obi\u0219nuite de conect\u0103ri intr\u00eende. Anumite trackere nu accept\u0103 asta \u0219i e\u0219ueaz\u0103 cu erori ca "Port Invalid" sau "Argument Incorect"
+ConfigView.section.connection.encryption.use_crypto_port=Folose\u0219te extensia 'cryptoport' pentru tracker \u00een scopul prevenirii tentativelor obi\u0219nuite de conect\u0103ri intr\u00eende. Anumite trackere nu accept\u0103 asta \u0219i e\u0219ueaz\u0103 cu erori ca "Port Invalid" sau "Argument Incorect"
 TorrentOptionsView.param.reset.to.default=Seteaz\u0103 op\u021biunile \u00eenapoi la valorile implicite
 TorrentOptionsView.param.reset.button=Reseteaz\u0103
 natpmp.routeraddress=Adresa sta\u021biei [gol: auto]
-ConfigView.section.style.disableAlertSliding=Dezactiveaz\u0103 apari\u021bia \u00een prim-plan \u0219i anima\u021bia de glisare a mesajelor de alert\u0103
+ConfigView.section.style.disableAlertSliding=Dezactiveaz\u0103 apari\u021bia \u00een prim-plan \u0219i anima\u021bia de alunecare a mesajelor de alert\u0103
 ConfigView.section.transfer.autospeed.maxinc=%1 cre\u0219tere maxim\u0103 per ciclu
 ConfigView.section.transfer.autospeed.maxdec=%1 sc\u0103dere maxim\u0103 per ciclu
 ConfigView.section.transfer.autospeed.enabledownadj=Activeaz\u0103 ajustarea vitezei de desc\u0103rcare
@@ -1897,62 +1888,53 @@ ConfigView.section.connection.tcp.enable=Activeaz\u0103 TCP
 ConfigView.section.connection.udp.enable=Activeaz\u0103 UDP
 ConfigView.section.style.showiconbar=Arat\u0103 Bara de Unelte
 MainWindow.menu.view.iconbar=Bara de Unelte
-MyTorrentsView.menu.rename=Redenume\u0219te
+MyTorrentsView.menu.rename=Renume\u0219te
 MyTorrentsView.menu.rename.displayed=Modific\u0103 Numele Afi\u0219at
-MyTorrentsView.menu.rename.save_path=Redenume\u0219te Calea de Salvare
-AdvRenameWindow.title=Redenume\u0219te Desc\u0103rcarea
-AdvRenameWindow.message=Introduce\u021bi un nume nou pentru aceast\u0103 desc\u0103rcare.
-AdvRenameWindow.rename.torrent=Redenume\u0219te Torentul
+MyTorrentsView.menu.rename.save_path=Renume\u0219te Calea de Salvare
+AdvRenameWindow.title=Renume\u0219te Desc\u0103rcarea
+AdvRenameWindow.message=Introdu un nume nou pentru aceast\u0103 desc\u0103rcare.
+AdvRenameWindow.rename.torrent=Renume\u0219te Torentul
 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.
+MyTorrentsView.menu.rename.displayed.enter.message=Introdu un nume nou ce va fi afi\u0219at 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.
-UIDebugGenerator.messageask.title=Generator de Info pt. Debugare
-UIDebugGenerator.messageask.text=Introduce\u021bi o descriere a bugului pe care \u00eel raporta\u021bi
-UIDebugGenerator.complete.title=Generarea de info pt. debugare este complet\u0103
-UIDebugGenerator.complete.text=Trimite\u021bi fi\u0219ierul '%1' la adresa az-bugreports at azureus-inc.com\n\nClica\u021bi pe Ok pentru a deschide o fereastr\u0103 cu acest fi\u0219ier.
-ConfigView.section.style.showProgramIcon=Arat\u0103 iconi\u021ba programului \u00een coloana numelui
+MyTorrentsView.menu.edit_comment.enter.message=Adaug\u0103 un comentariu pt. aceast\u0103 desc\u0103rcare.
+UIDebugGenerator.messageask.title=Generator de Informa\u021bii pentru Debugare
+UIDebugGenerator.messageask.text=Adaug\u0103 o descriere a bugului pe care \u00eel raportezi
+UIDebugGenerator.complete.title=Generarea de informa\u021bii pentru debugare este complet\u0103
+UIDebugGenerator.complete.text=Trimite fila '%1' la adresa az-bugreports at azureus-inc.com\n\nClicheaz\u0103 pe Ok pentru a deschide o fereastr\u0103 cu aceast\u0103 fil\u0103.
+ConfigView.section.style.showProgramIcon=Arat\u0103 icoana programului \u00een coloana numelui
 ConfigView.section.style.showProgramIcon.tooltip=Vederea trebuie redeschis\u0103 pentru ca schimb\u0103rile s\u0103 devin\u0103 efective
-swt.alert.cant.update=Biblioteca SWT \u00eenc\u0103rcat\u0103 din "%3" nu poate fi actualizat\u0103 automat de la versiunea %1 la %2 (trebuie \u00eenc\u0103rcat\u0103 din "%4"). Vede\u021bi <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">wikiul</A> pentru detalii.
+swt.alert.cant.update=Biblioteca SWT \u00eenc\u0103rcat\u0103 din "%3" nu poate fi actualizat\u0103 automat de la versiunea %1 la %2 (trebuie \u00eenc\u0103rcat\u0103 din "%4"). Vezi <A HREF="http://www.azureuswiki.com/index.php/SWT_Cant_Auto_Update">wikiul</A> pentru detalii.
 authenticator.savepassword=Memoreaz\u0103-mi parola
 ConfigView.section.security.clearpasswords=Reseteaz\u0103 parolele memorate
 ConfigView.section.security.clearpasswords.button=Reseteaz\u0103
-Content.alert.notuploaded.title=\u00cenc\u0103rcarea nu e complet\u0103
-Content.alert.notuploaded.text=\u00cenc\u0103rcarea lui '%1' nu este complet\u0103. Dac\u0103 ve\u021bi %2 acum, lumea nu va putea s\u0103 descarce complet opera publicat\u0103 de dv.\n\nSigur dori\u021bi s\u0103 %2?
-Content.alert.notuploaded.multi.title=\u00cenc\u0103rc\u0103rile Nu S\u00eent Complete
-Content.alert.notuploaded.multi.text=%1 din con\u021binutul publicat de dv. nu s\u00eent donate complet. Dac\u0103 %2 acum, ceilal\u021bi nu vor putea s\u0103 descarce complet lucr\u0103rile pe care le-a\u021bi publicat. Sigur dori\u021bi s\u0103 %2?\n\nCon\u021binut care nu e donat complet:\n%3
-Content.alert.notuploaded.quit=p\u0103r\u0103se\u0219te Vuze
 TorrentInfoView.torrent.encoding=Codarea Torentelor
 TorrentInfoView.columns=Coloane pentru vederea 'Torentele Mele'
 progress.window.title=Opera\u021biune \u00een Desf\u0103\u0219urare
-progress.window.msg.filemove=A\u0219tepta\u021bi p\u00een\u0103 se termin\u0103 mutarea/redenumirea fi\u0219ierului
+progress.window.msg.filemove=A\u0219teapt\u0103 p\u00een\u0103 se termin\u0103 mutarea/renumirea filei
 ConfigView.label.popup.timestamp=Adaug\u0103 marcaje de timp la alertele popup
 ConfigView.label.popup.autohide=Ascunde automat alertele popup dup\u0103 x secunde (seteaz\u0103 la 0 pt. a dezactiva autoascunderea)
-ConfigView.label.popup.suppress_alerts=Suprim\u0103 alertele
-ConfigView.label.popup.use_message_boxes=Folose\u0219te casete cu mesaje popup mai degrab\u0103 dec\u00eet casete de alertare obi\u0219nuite.
-ConfigView.label.popup.show=Arat\u0103 toate alertele popup \u00eenregistrate p\u00een\u0103 acum (dac\u0103 exist\u0103)
-ConfigView.label.popup.show.button=Arat\u0103
-ConfigView.label.please.visit.here=Clica\u021bi aici pentru detalii suplimentare
-ConfigView.section.ipfilter.enable.descriptionCache=Stocheaz\u0103 descrierile IP \u00eentr-un fi\u0219ier ciorn\u0103
+ConfigView.label.please.visit.here=Clicheaz\u0103 aici pentru detalii suplimentare
+ConfigView.section.ipfilter.enable.descriptionCache=Stocheaz\u0103 descrierile IP \u00eentr-o fil\u0103 ciorn\u0103
 ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u00cen caz de dezactivare, descrierile nu vor fi memorate
 OpenTorrentWindow.filesInfo=%1 din %2 vor fi desc\u0103rcate.
 OpenTorrentWindow.diskUsage=%1 din %2
 ConfigView.label.openmytorrents=Deschide 'Torentele Mele' la pornire
 ConfigView.label.open_transfer_bar_on_start=Deschide Bara de Transferuri la pornire
-ConfigView.section.style.DNDalwaysInIncomplete=Arat\u0103 mereu torentele cu fi\u0219iere 'Nu Desc\u0103rca' \u00een sec\u021biunea Incomplete din Torentele Mele  
+ConfigView.section.style.DNDalwaysInIncomplete=Arat\u0103 mereu torentele cu file de tip 'Nu Desc\u0103rca' \u00een sec\u021biunea Incomplete din Torentele Mele
 OpenTorrentWindow.mb.noGlobalDestDir.title=Dosarul de Destina\u021bie
 OpenTorrentWindow.mb.noGlobalDestDir.text=Dosarul de Destina\u021bie '%1' este invalid.
 OpenTorrentWindow.mb.noDestDir.title=Dosarul de Destina\u021bie nu a fost g\u0103sit
-OpenTorrentWindow.mb.noDestDir.text=Dosarul de destina\u021bie '%1' pentru torentul '%2' nu exist\u0103 sau e invalid.
+OpenTorrentWindow.mb.noDestDir.text=Dosarul de destina\u021bie '%1' pentru torentul '%2' nu exist\u0103 sau e nevalid.
 OpenTorrentWindow.mb.notValid.title=Deschide Torentul
-OpenTorrentWindow.mb.notValid.text=Nu pot deschide torentul '%1'.  Dac\u0103 \u00eel deschide\u021bi \u00een mod de donare, asigura\u021bi-v\u0103 c\u0103 exist\u0103 fi\u0219ierele cu date.
+OpenTorrentWindow.mb.notValid.text=Nu pot deschide torentul '%1'.  Dac\u0103 \u00eel deschizi \u00een mod de donare, asigur\u0103-te c\u0103 exist\u0103 filele cu date.
 OpenTorrentWindow.mb.notTorrent.title=Deschide Torentul
-OpenTorrentWindow.mb.notTorrent.text=Nu pot deschide '%1'.  Nu pare a fi un fi\u0219ier torent.\n\nUnele din datele primite:\n%2
+OpenTorrentWindow.mb.notTorrent.text=Nu pot deschide '%1'.  Nu pare a fi o fil\u0103 torent.\n\nUnele din datele primite:\n%2
 ConfigView.label.pause.downloads.on.exit=Pauzeaz\u0103 desc\u0103rc\u0103rile la ie\u0219ire
 ConfigView.label.resume.downloads.on.start=Reia la pornire desc\u0103rc\u0103rile pauzate, dup\u0103 ce s-a terminat ini\u021bializarea
 UIDebugGenerator.message.cancel.title=Generarea de info pt. debugare a fost anulat\u0103
-UIDebugGenerator.message.cancel.text=Nu a\u021bi ad\u0103ugat o descriere a bugului pe care dori\u021bi s\u0103-l raporta\u021bi.  Bugul poate fi evident pentru dv., dar f\u0103r\u0103 o descriere detaliat\u0103 nu vom putea dec\u00eet s\u0103 ghicim care e problema care \u00eel produce.\n\nGenerarea de info pentru debugare a fost anulat\u0103.
+UIDebugGenerator.message.cancel.text=Nu ai ad\u0103ugat o descriere a bugului pe care vrei s\u0103-l raportezi.  Bugul poate fi evident pentru tine, dar f\u0103r\u0103 o descriere detaliat\u0103 nu vom putea dec\u00eet s\u0103 ghicim care e problema care \u00eel produce.\n\nGenerarea de informa\u021bii pentru debugare a fost anulat\u0103.
 ConfigView.section.connection.group.http.info=Suport pentru donare HTTP.
 ConfigView.section.connection.http.enable=Activeaz\u0103
 ConfigView.section.connection.http.port=Num\u0103rul portului de intrare
@@ -1961,8 +1943,8 @@ window.update.noupdates.title=Rezultatul C\u0103ut\u0103rii de Actualiz\u0103ri
 window.update.noupdates.text=Nu exist\u0103 actualiz\u0103ri disponibile pentru program.\n\nFelicit\u0103ri!
 ConfigView.label.bindip.details=Exemplu: 192.168.1.5;eth0;eth1[2] vor lega adresa IP specificat\u0103 la toate adresele IP de la 1-a interfa\u021b\u0103 \u0219i la a 3-a adres\u0103 IP a celei de-a 2-a interfe\u021be.\nPrima adres\u0103 IP va fi utilizat\u0103 pentru toate serviciile, iar restul vor fi utilizate doar pentru echilibrarea sarcinii.\nS\u00eent disponibile urm\u0103toarele interfe\u021be:\n%1
 ConfigView.label.mindownloads=Nr. min. de desc\u0103rc\u0103ri simultane
-UI.cannot_submit_blank_text=Trebuie s\u0103 introduce\u021bi o valoare.
-crypto.alert.as.warning=Re\u021beaua '%1' este cunoscut\u0103 ca folosind fasonarea traficului [shaping] \u00een scopul sc\u0103derii vitezei de desc\u0103rcare. Criptarea transferurilor a fost activat\u0103 automat - ea poate fi modificat\u0103/\u00eenchis\u0103 prin configurarea parametrilor. 
+UI.cannot_submit_blank_text=Trebuie s\u0103 introduci o valoare.
+crypto.alert.as.warning=Re\u021beaua '%1' este cunoscut\u0103 ca folosind fasonarea traficului [shaping] \u00een scopul sc\u0103derii vitezei de desc\u0103rcare. Criptarea transferurilor a fost activat\u0103 automat - ea poate fi modificat\u0103/\u00eenchis\u0103 prin configurarea parametrilor.
 ConfigView.section.interface.alerts=Alerte
 ConfigView.label.popupdownloadadded=Arat\u0103 o alert\u0103 popup la ad\u0103ugarea unei desc\u0103rc\u0103ri
 popup.download.added="%1" a fost ad\u0103ugat la lista de desc\u0103rcare.
@@ -1974,15 +1956,15 @@ TransferStatsView.legend.pingaverage=Medie
 TransferStatsView.legend.ping1=\u021ainta 1
 TransferStatsView.legend.ping2=\u021ainta 2
 TransferStatsView.legend.ping3=\u021ainta 3
-ConfigView.section.interface.enabletray._mac=Activeaz\u0103 Iconi\u021ba din Bara de Stare (necesit\u0103 repornire)
-ConfigView.label.closetotray._mac=\u00cenchiderea ferestrei minimizeaz\u0103 programul \u00een sistaler
-ConfigView.label.minimizetotray._mac=Minimizeaz\u0103 ca iconi\u021b\u0103 \u00een sistaler
-OpenTorrentWindow.mb.existingFiles.title=Fi\u0219ierele exist\u0103 deja!
-OpenTorrentWindow.mb.existingFiles.text=Anumite fi\u0219iere exist\u0103 deja \u00een dosarul (dosarele) de destina\u021bie pe care l-a\u021bi specificat:\n\n%1\nDac\u0103 ve\u021bi continua, Vuze va verifica fi\u0219ierele \u00een cauz\u0103 pentru a vedea dac\u0103 au date valide \u0219i le va suprascrie dac\u0103 va fi necesar.
+ConfigView.section.interface.enabletray._mac=Activeaz\u0103 Icoana din Bara de Stare (necesit\u0103 repornire)
+ConfigView.label.closetotray._mac=\u00cenchiderea ferestrei minimizeaz\u0103 programul \u00een sertar
+ConfigView.label.minimizetotray._mac=Minimizeaz\u0103 ca icoan\u0103 \u00een sertar
+OpenTorrentWindow.mb.existingFiles.title=Filele exist\u0103 deja!
+OpenTorrentWindow.mb.existingFiles.text=Anumite file exist\u0103 deja \u00een dosarul (dosarele) de destina\u021bie pe care l-ai specificat:\n\n%1\nDac\u0103 vei continua, Vuze va verifica filele \u00een cauz\u0103 pentru a vedea dac\u0103 au date valide \u0219i le va suprascrie dac\u0103 va fi necesar.
 splash.unloadingTorrents=Dez\u00eencarc Torentele
 splash.unloadingTorrent=Dez\u00eencarc Torentul
-ConfigView.section.file.defaultdir.autorename=Redenume\u0219te automat fi\u0219ierele torentului dac\u0103 fi\u0219ierele din cale par diferite
-ConfigView.section.file.defaultdir.autorename.tooltip=Aceasta previne ca un torent s\u0103 suprascrie fi\u0219ierele altui torent atunci c\u00eend numele fi\u0219ierelor s\u00eent identice
+ConfigView.section.file.defaultdir.autorename=Renume\u0219te automat filele torentului dac\u0103 filele din cale par diferite
+ConfigView.section.file.defaultdir.autorename.tooltip=Aceasta previne ca un torent s\u0103 suprascrie filele altui torent atunci c\u00eend numele filelor s\u00eent identice
 alert.raised.at.close=(Mesaj de la \u00eenchiderea precedent\u0103 a lui Vuze)
 Plugin.trackerpeerauth.name=Autorizarea Trackerului Partenerului
 Plugin.trackerpeerauth.info=Aceast\u0103 extensie lucreaz\u0103 cu trackerele pentru a verifica dac\u0103 partenerii s\u00eent membri valizi ai roiului
@@ -1990,7 +1972,7 @@ Peers.column.maxupspeed=Viteza Max \u00cenc
 Peers.column.maxdownspeed=Viteza Max Desc
 MyTorrents.items.DownSpeedLimit.disabled=Nici o desc\u0103rcare
 upnp.selectedaddresses=Adrese (separate prin ';' , prefix '-' =refuz\u0103, '+' =permite) [gol: oricare]
-upnp.alert.multipledevice.warning=Au fost detectate multiple dispozitive UPnP - verifica\u021bi dac\u0103 toate necesit\u0103 maparea porturilor (vede\u021bi jurnalul \u0219i configurarea UPnP)
+upnp.alert.multipledevice.warning=Au fost detectate multiple dispozitive UPnP - verific\u0103 dac\u0103 toate necesit\u0103 maparea porturilor (vezi jurnalul \u0219i configurarea UPnP)
 UpdateMonitor.messagebox.restart.title=Actualizarea Softului
 UpdateMonitor.messagebox.restart.text=Vuze tocmai a terminat de desc\u0103rcat o actualizare important\u0103 \u0219i trebuie repornit pentru ca aceasta s\u0103 fie instalat\u0103.
 PiecesView.BlockView.Have=Am
@@ -2002,7 +1984,7 @@ Peers.column.peer_id.info=ID-ul Partenerului \u00een format citibil
 Peers.column.peer_byte_id=ID Partener
 Peers.column.peer_byte_id.info=ID-ul Partenerului \u00een format binar
 Peers.column.handshake_reserved=Bai\u021bi Rezerva\u021bi pt. Str\u00eengerea de M\u00een\u0103
-Peers.column.handshake_reserved.info=Indic\u0103 care bi\u021bi rezerva\u021bi au fost seta\u021bi \u00een "str\u00eengerea de m\u00een\u0103" BT
+Peers.column.handshake_reserved.info=Indic\u0103 ce bi\u021bi rezerva\u021bi au fost seta\u021bi \u00een "str\u00eengerea de m\u00een\u0103" BT
 Peers.column.client_identification=Identificarea Clientului
 Peers.column.client_identification.info=Indic\u0103 numele brute de clien\u021bi primite de Vuze - util pentru debugare
 dht.warn.user=Aten\u021bioneaz\u0103 dac\u0103 pot apare probleme cu NAT/maparea porturilor
@@ -2019,20 +2001,20 @@ speedtest.wizard.test.mode.down=desc\u0103rcare
 SpeedTestWizard.test.panel.currinfo=Testarea l\u0103\u021bimii de band\u0103 pentru BitTorrent.
 SpeedTestWizard.test.panel.label=Test de vitez\u0103 Vuze:
 SpeedTestWizard.test.panel.already.running=Testul ruleaz\u0103 deja!
-SpeedTestWizard.test.panel.not.accepted=Solicitare de testare neacceptat\u0103: 
+SpeedTestWizard.test.panel.not.accepted=Solicitare de testare neacceptat\u0103:
 SpeedTestWizard.test.panel.abort=\u00centrerupe
-SpeedTestWizard.test.panel.abort.countdown=\u00eentrerupe testul \u00een:
+SpeedTestWizard.test.panel.abort.countdown=\u00eentrerupe testul dup\u0103:
 SpeedTestWizard.test.panel.test.countdown=test terminat \u00een:
 SpeedTestWizard.test.panel.testfailed=Testul a e\u0219uat
 SpeedTestWizard.test.panel.aborted=Test \u00eentrerupt manual.
-SpeedTestWizard.test.panel.enc.label=Ap\u0103sa\u021bi pentru a testa cu criptare:
+SpeedTestWizard.test.panel.enc.label=Apas\u0103 pentru a testa cu criptare:
 SpeedTestWizard.test.panel.encrypted=criptat
 SpeedTestWizard.set.upload.button.apply=Aplic\u0103
 SpeedTestWizard.set.upload.result=Ultimul Rezultat al Testului
 SpeedTestWizard.set.upload.bytes.per.sec=kBai\u021bi/sec
 SpeedTestWizard.set.upload.bits.per.sec=bi\u021bi/sec
 SpeedTestWizard.finish.panel.title=Testul de Vitez\u0103 a fost Realizat!
-SpeedTestWizard.finish.panel.click.close=A\u021bi terminat vr\u0103jitorul de testare a vitezei. Clica\u021bi pe \u00cenchide pentru a ie\u0219i.
+SpeedTestWizard.finish.panel.click.close=Ai terminat vr\u0103jitorul de testare a vitezei. Clicheaz\u0103 pe \u00cenchide pentru a ie\u0219i.
 SpeedTestWizard.finish.panel.max.upload=Max \u00eenc\u0103rcare :
 SpeedTestWizard.finish.panel.max.seeding.upload=Max \u00eenc\u0103rcare la donare :
 SpeedTestWizard.finish.panel.max.download=Max desc\u0103rcare :
@@ -2055,19 +2037,18 @@ SpeedTestWizard.stage.message.preparing=preg\u0103tesc testul...
 SpeedTestWizard.stage.message.starting=pornesc testul...
 SpeedTestWizard.stage.message.connect.stats=Statisticile conexiunii: parteneri=%1, desc_ok=%2, \u00eenc_ok=%3
 window.uiswitcher.title=Selector de Interfa\u021b\u0103 Vuze
-window.uiswitcher.text=Selecta\u021bi o interfa\u021b\u0103 de mai jos care v\u0103 satisface cel mai bine necesit\u0103\u021bile.
+window.uiswitcher.text=Selecteaz\u0103 interfa\u021ba de mai jos care \u00ee\u021bi satisface cel mai bine necesit\u0103\u021bile.
 window.uiswitcher.NewUI.text=* Recomandat pentru \u00eencep\u0103tori \u0219i utilizatori noi.\n\n* Interfa\u021b\u0103 grafic\u0103 u\u0219oar\u0103 \u0219i intuitiv\u0103\n\n* Interfa\u021b\u0103 necesar\u0103 pentru publicarea pe platforma Vuze
 window.uiswitcher.ClassicUI.title=Interfa\u021b\u0103 Clasic\u0103
 window.uiswitcher.ClassicUI.text=* P\u0103streaz\u0103 func\u021bionalitatea clientului din seria 2.x\n\n* Stratul de con\u021binut Vuze nu va fi \u00eenc\u0103rcat
-window.uiswitcher.bottom.text=Alegerea dv. poate fi modificat\u0103 din nou cu ajutorul butonului de selectare a interfe\u021bei Vuze
 iconBar.switch.tooltip=Selectorul de Interfa\u021b\u0103 Vuze
 VivaldiView.notAvailable=Vederea Vivaldi nu e disponibil\u0103
 restart.error=Repornirea a e\u0219uat:\n%1\nVezi <A HREF="{restart.error.url}">probleme la repornire</a>.
 restart.error.oom=Memorie RAM Epuizat\u0103
 restart.error.fnf='%1' nu a fost g\u0103sit \u00een '%2'
 restart.error.pnf=Calea '%1' nu a fost g\u0103sit\u0103
-restart.error.bad=Format gre\u0219it de fi\u0219ier pentru '%1'
-restart.error.denied=Accesul a fost refuzat \u00een timp ce se \u00eencerca rularea lui '%1'.  Asigura\u021bi-v\u0103 c\u0103 ave\u021bi permisiunile necesare pentru a rula programul respectiv.
+restart.error.bad=Format gre\u0219it de fil\u0103 pentru '%1'
+restart.error.denied=Accesul a fost refuzat \u00een timp ce se \u00eencerca rularea lui '%1'.  Asigur\u0103-te c\u0103 ai permisiunile necesare pentru a rula programul respectiv.
 TableColumn.header.date_completed=Data Termin\u0103rii
 TableColumn.menu.date_added.reset=Reseteaz\u0103 Data
 ConfigView.section.ipfilter.discardbanning=Blocheaz\u0103 partenerii al c\u0103ror raport "date nefolositoare/date bune" dep\u0103\u0219e\u0219te [0: dezactivat]
@@ -2085,12 +2066,7 @@ TableColumn.header.Rating=Not\u0103
 TableColumn.header.SpeedGraphic=Vitez\u0103
 TableColumn.header.AzProduct=Din
 TableColumn.header.ProgressETA=Progres
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
-TableColumn.header.name.ext=Tipul de Fi\u0219ier: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
+TableColumn.header.name.ext=Tipul de Fil\u0103: %1
 v3.MainWindow.tab.home=Tablou de Bord
 v3.MainWindow.tab.browse=Vuze
 v3.MainWindow.tab.library=Arhiva Torentelor
@@ -2115,42 +2091,30 @@ v3.MainWindow.button.viewdetails=Vezi Detaliile
 v3.MainWindow.button.play=Red\u0103
 v3.MainWindow.button.cancel=Anuleaz\u0103
 v3.MainWindow.button.preview=Previzioneaz\u0103
-v3.MainWindow.view.wait=Ini\u021bializez vederea, a\u0219tepta\u021bi.
+v3.MainWindow.view.wait=Ini\u021bializez vederea, a\u0219teapt\u0103.
 v3.MainWindow.xofx=%1 din %2
-v3.MainWindow.Loading=\u00cencarc.. A\u0219tepta\u021bi
+v3.MainWindow.Loading=\u00cencarc.. A\u0219teapt\u0103
 v3.filter-bar=Filtru de Titluri:
 v3.MainWindow.search.defaultText=Caut\u0103 \u00een Vuze
 v3.mb.delPublished.title=Opre\u0219te Donarea de Con\u021binut
-v3.mb.delPublished.text=AVERTISMENT: Aceast\u0103 ac\u021biune NU va \u00eenl\u0103tura con\u021binutul dv. publicat '%1' de la <A HREF="%2">%3</A> .\n\nClica\u021bi pe "\u0218terge" doar dac\u0103 dori\u021bi s\u0103 r\u0103m\u00een\u0103 publicat \u0219i s\u0103 poat\u0103 fi desc\u0103rcat con\u021binutul dv., dar dori\u021bi s\u0103 v\u0103 elibera\u021bi l\u0103\u021bimea de band\u0103. Asigura\u021bi-v\u0103 c\u0103 procesul de \u00eenc\u0103rcare a fost terminat \u00eenainte de a  [...]
+v3.mb.delPublished.text=AVERTISMENT: Aceast\u0103 ac\u021biune NU va \u00eenl\u0103tura con\u021binutul t\u0103u publicat '%1' de la <A HREF="%2">%3</A> .\n\nClicheaz\u0103 pe "\u0218terge" doar dac\u0103 vrei ca con\u021binutul t\u0103u s\u0103 r\u0103m\u00een\u0103 publicat \u0219i s\u0103 poat\u0103 fi desc\u0103rcat, dar \u00een acela\u0219i timp vrei s\u0103 eliberezi l\u0103\u021bimea de band\u0103 ocupat\u0103 de el. Asigur\u0103-te c\u0103 procesul de \u00eenc\u0103rcare a fost t [...]
 v3.mb.delPublished.delete=\u0218ter&ge
 v3.mb.delPublished.cancel=&Anuleaz\u0103
-v3.mb.openFile.title=Deschide Fi\u0219ierul
-v3.mb.openFile.text.known=Acest con\u021binut nu e suportat momentan de c\u0103tre Redorul Vuze [Player]. Pentru ajutor consulta\u021bi acest <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Ghid de Redare</a> alc\u0103tuit de comunitate.\n\nFi\u0219ierul pare s\u0103 fie de tipul: %2 (%3)\n
-v3.mb.openFile.text.unknown=Acest con\u021binut nu e suportat momentan de c\u0103tre Redorul Vuze [Player]. Pentru ajutor consulta\u021bi acest <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Ghid de Redare</a> alc\u0103tuit de comunitate.\n\nExtensia Fi\u0219ierului : %2\n
-v3.mb.openFile.button.play=Red\u0103
-v3.mb.openFile.button.cancel=Anuleaz\u0103
-v3.mb.openFile.button.guide=Ghidul Red\u0103rii cu Vuze
-v3.mb.openFile.remember=Deschide mereu fi\u0219ierele f\u0103r\u0103 a m\u0103 \u00eentreba
-v3.mb.PlayFileNotFound.title=Fi\u0219ier Neg\u0103sit
-v3.mb.PlayFileNotFound.text=Fi\u0219ierele pentru '%1' au fost \u0219terse sau s\u00eent absente.
+v3.mb.PlayFileNotFound.title=Fil\u0103 Neg\u0103sit\u0103
+v3.mb.PlayFileNotFound.text=Filele pentru '%1' au fost \u0219terse sau s\u00eent absente.
 v3.mb.PlayFileNotFound.button.remove=\u0218terge din Vuze
-v3.mb.PlayFileNotFound.button.redownload=Redescarc\u0103 Fi\u0219ierele
+v3.mb.PlayFileNotFound.button.redownload=Redescarc\u0103 Filele
 v3.mb.PlayFileNotFound.button.find=G\u0103se\u0219te Manual..
-v3.mb.deletePurchased.title=\u0218terge Con\u021binutul Cump\u0103rat
-v3.mb.deletePurchased.text=Sigur dori\u021bi s\u0103 \u0219terge\u021bi con\u021binutul '%1'?\n\nAcesta este un con\u021binut pe care fie l-a\u021bi cump\u0103rat, fie este nevoie s\u0103 v\u0103 autentifica\u021bi pentru a-l desc\u0103rca.
-v3.mb.deletePurchased.button.delete=\u0218ter&ge
-v3.mb.deletePurchased.button.cancel=&Anuleaz\u0103
 v3.topbar.menu.show.plugin=Zona Extensiilor
 v3.topbar.menu.show.search=Caut\u0103
 v3.topbar.menu.show.frog=Brotacul Albastru
 splash.initializeCore=Ini\u021bializez Nucleul
 splash.initializeUIElements=Ini\u021bializez Elementele Interfe\u021bei
 ConfigView.section.transfer.autospeedbeta=Autovitez\u0103-Beta
-#
 ConfigView.section.ipfilter.peerblocking.group=Blocarea Partenerilor
 ConfigView.section.ipfilter.autoload.group=Auto\u00eenc\u0103rcare
-ConfigView.section.ipfilter.autoload.file=Fi\u0219ierul cu filtre IP de auto\u00eenc\u0103rcat
-ConfigView.section.ipfilter.autoload.info=Suport\u0103 formatele DAT (eMule), P2P (PeerGuardian, splist) \u0219i P2B v1,2,3 (PeerGuardian 2).  Fi\u0219ierul poate fi stocat local sau pe internet (URL), \u00een format arhivat (zip, gzip) sau \u00een format text simplu.  Adresele (URL-urile) vor fi redesc\u0103rcate automat dup\u0103 7 zile, \u00een timp ce fi\u0219ierele locale vor fi re\u00eenc\u0103rcate la trecerea a un minut de c\u00eend au fost \u00eenlocuite/modificate.
+ConfigView.section.ipfilter.autoload.file=Fila cu filtre IP de auto\u00eenc\u0103rcat
+ConfigView.section.ipfilter.autoload.info=Suport\u0103 formatele DAT (eMule), P2P (PeerGuardian, splist) \u0219i P2B v1,2,3 (PeerGuardian 2).  Fila poate fi stocat\u0103 local sau pe internet (URL), \u00een format arhivat (zip, gzip) sau \u00een format text simplu.  Adresele (URL-urile) vor fi redesc\u0103rcate automat dup\u0103 7 zile, \u00een timp ce filele locale vor fi re\u00eenc\u0103rcate la trecerea a un minut de c\u00eend au fost \u00eenlocuite/modificate.
 ConfigView.section.ipfilter.autoload.loadnow=\u00cencarc\u0103 Acum
 splash.loadIpFilters=\u00cencarc Filtrele IP..
 SpeedTestWizard.set.upload.title=Seteaz\u0103 Limitele de \u00cenc\u0103rcare \u0219i Desc\u0103rcare
@@ -2164,9 +2128,9 @@ SpeedTestWizard.name.conf.level.none=Nimic
 ConfigView.section.transfer.select=Autovitez\u0103
 ConfigView.section.transfer.select.v2=Autovitez\u0103 (beta)
 mb.azmustclose.title=Eroare de Pornire
-mb.azmustclose.text=Azureus trebuie s\u0103 se \u00eenchid\u0103 din cauza unei probleme de (re)pornire care a f\u0103cut ca programul s\u0103 fie rulat \u00een mod Adminstrator.\n\nDup\u0103 \u00eenchiderea programului Azureus, redeschide\u021bi-l manual.
+mb.azmustclose.text=Azureus trebuie s\u0103 se \u00eenchid\u0103 din cauza unei probleme de (re)pornire care a f\u0103cut ca programul s\u0103 fie rulat \u00een mod Adminstrator.\n\nDup\u0103 \u00eenchiderea programului Azureus, redeschide-l manual.
 network.ipv6.prefer.addresses=Prefer\u0103 adresele IPv6 c\u00eend s\u00eent disponibile at\u00eet IPv6 c\u00eet \u0219i IPv4
-network.bindError=\u00cembinarea cu socketul serverului a e\u0219uat pentru c\u0103 nu s\u00eent disponibile adrese compatibile, verifica\u021bi set\u0103rile bind-to-IP.
+network.bindError=\u00cembinarea cu socketul serverului a e\u0219uat pentru c\u0103 nu s\u00eent disponibile adrese compatibile, verific\u0103 set\u0103rile bind-to-IP.
 network.enforce.ipbinding=For\u021beaz\u0103 leg\u0103rile IP chiar \u0219i c\u00eend intefe\u021bele nu s\u00eent disponibile, \u00eempiedic\u0103 orice conexiuni dac\u0103 nici una dintre interfe\u021bele specificate nu este disponibil\u0103
 DHTView.title.full_v6=Baz\u0103 de Date Distribuit\u0103 IPv6
 ConfigView.pluginlist.loadSelected=\u00cencarc\u0103 Selectatele
@@ -2180,7 +2144,7 @@ SpeedView.stats.measuredmin=Min M\u0103surat\u0103
 SpeedView.stats.manual=Fix\u0103
 ConfigView.section.transfer.autospeed.networks=Detaliile Re\u021belei
 ConfigView.section.transfer.autospeed.resetnetwork=Reseteaz\u0103 detaliile re\u021belei
-ConfigView.section.transfer.autospeed.network.info=Limitele \u00een cauz\u0103 s\u00eent de obicei calculate automat \u00een timpul desc\u0103rc\u0103rii sau s\u00eent rezultatul unui test de vitez\u0103. Dac\u0103 dori\u021bi s\u0103 le specifica\u021bi manual utiliza\u021bi op\u021biunile de mai jos.\nToate limitele \u00een afara celor 'fixate' vor fi \u00een consecin\u021b\u0103 ajustate automat dac\u0103 e nevoie. \nIntroduce\u021bi valoarea \u0219i apoi selecta\u021bi tipul ei. Lua\ [...]
+ConfigView.section.transfer.autospeed.network.info=Limitele \u00een cauz\u0103 s\u00eent de obicei calculate automat \u00een timpul desc\u0103rc\u0103rii sau s\u00eent rezultatul unui test de vitez\u0103. Dac\u0103 vrei s\u0103 le specifici manual, utilizeaz\u0103 op\u021biunile de mai jos.\nToate limitele \u00een afara celor 'fixate' vor fi \u00een consecin\u021b\u0103 ajustate automat dac\u0103 e nevoie. \nIntrodu valoarea \u0219i apoi selecteaz\u0103 tipul ei. Ia aminte c\u0103 viteze [...]
 dialog.uiswitcher.restart.title=Comutatorul de Interfa\u021b\u0103: E Necesar\u0103 Repornirea Vuze
 dialog.uiswitcher.restart.text=Vuze trebuie repornit pentru a se trece la noua interfa\u021b\u0103.
 TrayWindow.menu.close=\u00cenchide Co\u0219ul de Desc\u0103rcare
@@ -2217,24 +2181,22 @@ PiecesView.DistributionView.weDownload=P\u0103r\u021bi Desc\u0103rcate
 PeersView.gain=C\u00ee\u0219tig
 PeersView.gain.info=Cantitatea de date desc\u0103rcate - \u00eenc\u0103rcate
 unix.script.new.title=E disponibil un nou Script de Pornire Vuze
-unix.script.new.text=E disponibil un nou script de pornire pt. Vuze \u0219i a fost salvat \u00een '%1'.\n\nEste recomandat s\u0103 p\u0103r\u0103si\u021bi Vuze acum \u0219i s\u0103 comuta\u021bi la acest script ('%2').\n\nDac\u0103 a\u021bi f\u0103cut modific\u0103ri importante la scriptul de pornire, vede\u021bi <A HREF="{unix.script.new.manual.url}">AzureusWiki: Unix Script</A>.\n\nDac\u0103 a\u021bi instalat Vuze printr-o distribu\u021bie de GNU/Linux (yum, apt-get, etc), este recoman [...]
+unix.script.new.text=E disponibil un nou script de pornire pt. Vuze \u0219i a fost salvat \u00een '%1'.\n\nEste recomandat s\u0103 p\u0103r\u0103se\u0219ti Vuze acum \u0219i s\u0103 comu\u021bi la acest script ('%2').\n\nDac\u0103 ai f\u0103cut modific\u0103ri importante la scriptul de pornire, vezi <A HREF="{unix.script.new.manual.url}">AzureusWiki: Unix Script</A>.\n\nDac\u0103 ai instalat Vuze printr-o distribu\u021bie de GNU/Linux (yum, apt-get, etc), este recomandat s\u0103-l reinst [...]
 unix.script.new.button.quit=P\u0103r\u0103se\u0219te Acum
 unix.script.new.button.continue=Am s\u0103-l fac mai t\u00eerziu
 unix.script.new.button.asknomore=Nu-mi mai spune din nou
 unix.script.new.auto.title=Nou Script de Pornire Vuze
-unix.script.new.auto.text=E disponibil un nou Script de Pornire Vuze.\n\nEste recomandat s\u0103 reporni\u021bi Vuze acum.
-Content.alert.notuploaded.button.stop=&Opre\u0219te
-Content.alert.notuploaded.button.continue=&Continu\u0103 Donarea
+unix.script.new.auto.text=E disponibil un nou Script de Pornire Vuze.\n\nEste recomandat s\u0103 reporne\u0219ti Vuze acum.
 Content.alert.notuploaded.button.abort=&Nu P\u0103r\u0103si
 ConfigView.label.checkOnSeeding=Efectueaz\u0103 \u00een fundal reverificarea p\u0103r\u021bilor \u00een timpul don\u0103rii
 ConfigView.label.ui_switcher=Arat\u0103 Selectorul de Interfe\u021be Vuze
 ConfigView.label.ui_switcher_button=Arat\u0103
-SpeedTestWizard.test.panel.explain=M\u0103sura\u021bi viteza protocolului Vuze. Selecta\u021bi tipul testului de vitez\u0103 \u0219i modul de criptare. Vizita\u021bi pagina wiki Vuze pentru a afla detalii despre test. Testul se va opri automat dac\u0103 dureaz\u0103 mai mult de minute. De obicei durata unui test nu dep\u0103\u0219e\u0219te un minut.
+SpeedTestWizard.test.panel.explain=M\u0103soar\u0103 viteza protocolului Vuze. Selecteaz\u0103 tipul testului de vitez\u0103 \u0219i modul de criptare. Viziteaz\u0103 pagina wiki Vuze pentru a afla detalii despre test. Testul se va opri automat dac\u0103 dureaz\u0103 mai mult de c\u00eeteva minute. De obicei durata unui test nu dep\u0103\u0219e\u0219te un minut.
 SpeedTestWizard.set.upload.hint=Seteaz\u0103 valorile limit\u0103 pentru desc\u0103rcare \u0219i \u00eenc\u0103rcare folosite la algoritmul de Autovitez\u0103.
-SpeedTestWizard.set.upload.panel.explain=Limitele setate aici s\u00eent folosite de algoritmul de Autovitez\u0103. Seta\u021bi limitele de transfer \u0219i cele de \u00eencredere.\n\nVitezele conexiunii s\u00eent de multe ori exprimate \u00een "bi\u021bi pe secund\u0103" - totu\u0219i valoarea de mai jos e exprimat\u0103 \u00een "kilobai\u021bi pe secund\u0103".
+SpeedTestWizard.set.upload.panel.explain=Limitele setate aici s\u00eent folosite de algoritmul de Autovitez\u0103. Seteaz\u0103 limitele de transfer \u0219i cele de \u00eencredere.\n\nVitezele conexiunii s\u00eent de multe ori exprimate \u00een "bi\u021bi pe secund\u0103" - totu\u0219i valoarea de mai jos e exprimat\u0103 \u00een "kilobai\u021bi pe secund\u0103".
 SpeedTestWizard.set.limit.conf.level=\u00cencredere
 SpeedTestWizard.finish.panel.auto.speed=Autoviteza e :
-SpeedTestWizard.finish.panel.auto.speed.seeding=Autoviteza \u00een timpul don\u0103rii e : 
+SpeedTestWizard.finish.panel.auto.speed.seeding=Autoviteza \u00een timpul don\u0103rii e :
 ConfigTransferAutoSpeed.add.comment.to.log.group=Adaug\u0103 comentariu la jurnalul de debugare
 ConfigTransferAutoSpeed.add.comment.to.log=Adaug\u0103 comentariu:
 ConfigTransferAutoSpeed.log.button=Jurnal
@@ -2244,7 +2206,7 @@ ConfigTransferAutoSpeed.auto.speed.classic=Autovitez\u0103(clasic)
 ConfigTransferAutoSpeed.auto.speed.beta=Autovitez\u0103(beta)
 ConfigTransferAutoSpeed.data.update.frequency=Frecven\u021ba de Actualizare
 Alert.failed.update=Instalarea a cel pu\u021bin o component\u0103 a e\u0219uat. Vezi <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A>
-OpenTorrentWindow.mb.existingFiles.partialList=(List\u0103 par\u021bial\u0103.  Mai multe fi\u0219iere exist\u0103 deja)
+OpenTorrentWindow.mb.existingFiles.partialList=(List\u0103 par\u021bial\u0103.  Mai multe file exist\u0103 deja)
 TableColumn.header.bad_avail_time.info=Ultima oar\u0103 c\u00eend a fost disponibil\u0103 o copie complet\u0103 a desc\u0103rc\u0103rii
 TableColumn.header.bad_avail_time=Copie Complet\u0103 Descoperit\u0103
 MyTorrentsView.menu.exporthttpseeds=Export\u0103 \u00een cliplan\u0219et\u0103 adresele (URL) donatorilor prin HTTP
@@ -2253,7 +2215,7 @@ ConfigView.label.minannounce=Timpul minim \u00een secunde \u00eentre anun\u021bu
 ConfigView.label.maxnumwant=Limiteaz\u0103 num\u0103rul de parteneri pe care \u00eel poate returna trackerul
 ConfigView.label.announceport=Ignor\u0103 portul TCP implicit pentru anun\u021burile despre tracker, PEX \u0219i DHT\n[l\u0103sat gol: nu ignora, 0: f\u0103r\u0103 conexiuni intr\u00eende]
 ConfigView.label.noportannounce=Nu anun\u021ba portul de ascultare c\u0103tre tracker (aceasta nu afecteaz\u0103 PEX, DHT)
-ConfigView.label.maxseedspertorrent=Nr. max. de donatori per torent [0: nelimitat] 
+ConfigView.label.maxseedspertorrent=Nr. max. de donatori per torent [0: nelimitat]
 wizard.webseed=Adaug\u0103 la torent sursele HTTP
 wizard.webseed.title=Donatori HTTP
 wizard.webseed.configuration=Configureaz\u0103 Donatorii HTTP
@@ -2261,15 +2223,15 @@ wizard.webseed.adding=Adaug  Donatori HTTP
 GeneralView.label.private=Torent Privat:
 GeneralView.yes=da
 GeneralView.no=nu
-ConfigView.label.userequestlimiting=Folose\u0219te fasonarea [throttling] solicit\u0103rilor \u00een loc de citirile \u00eent\u00eerziate pt. a limita viteza de desc\u0103rcare (f\u0103r\u0103 efect dac\u0103 viteza de desc\u0103rcare e nelimitat\u0103) 
+ConfigView.label.userequestlimiting=Folose\u0219te fasonarea [throttling] solicit\u0103rilor \u00een loc de citirile \u00eent\u00eerziate pt. a limita viteza de desc\u0103rcare (f\u0103r\u0103 efect dac\u0103 viteza de desc\u0103rcare e nelimitat\u0103)
 ConfigView.label.userequestlimiting.tooltip=Limitarea solicit\u0103rilor nu e at\u00eet de fluent\u0103 ca \u0219i citirile \u00eent\u00eerziate, dar permite prioritizarea desc\u0103rc\u0103rilor pe baza pozi\u021biei \u00een coada de a\u0219teptare \u0219i poate cre\u0219te performan\u021ba re\u021belei
 ConfigView.label.userequestlimitingpriorities=Focalizeaz\u0103 viteza de desc\u0103rcare pe v\u00eerful cozii de desc\u0103rcare c\u00eend a fost atins\u0103 limita vitezei de desc\u0103rcare
-ConfigView.section.logging.timestamp=Formatul marcajului de timp pt. fi\u0219ierele jurnal
+ConfigView.section.logging.timestamp=Formatul marcajului de timp pt. filele jurnal
 Peers.column.timetocomplete=Timp R\u0103mas
 Peers.column.timetocomplete.info=Timp r\u0103mas p\u00een\u0103 c\u00eend termin\u0103 partenerul
-ConfigView.section.interface.display.suppress.file.download.dialog=Suprim\u0103 dialogul popup despre desc\u0103rcarea fi\u0219ierului
-ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Arat\u0103 progresul desc\u0103rc\u0103rii fi\u0219ierelor \u00een bara de stare \u00een loc de dialogul popup
-FileDownload.canceled=Desc\u0103rcarea unui fi\u0219ier torent a fost anulat\u0103 cu succes de utilizator: %1
+ConfigView.section.interface.display.suppress.file.download.dialog=Suprim\u0103 dialogul popup despre desc\u0103rcarea filei
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=Arat\u0103 progresul desc\u0103rc\u0103rii filelor \u00een bara de stare \u00een loc de dialogul popup
+FileDownload.canceled=Desc\u0103rcarea unei file torent a fost anulat\u0103 cu succes de utilizator: %1
 Progress.reporting.status.canceled=Anulat
 Progress.reporting.status.finished=Terminat
 Progress.reporting.status.retrying=Re\u00eencerc...
@@ -2288,7 +2250,7 @@ v3.MainWindow.text.log.out=Dezautentificare
 v3.MainWindow.text.get.started=\u00censcriere
 v3.MainWindow.text.my.account=Contul Meu
 v3.MainWindow.text.my.profile=Profil
-OpenTorrentWindow.simple.open=Loca\u021bia Torentului (Fi\u0219ier, Adres\u0103, Ha\u0219)
+OpenTorrentWindow.simple.open=Loca\u021bia Torentului (Fil\u0103, Adres\u0103, Ha\u0219)
 Progress.reporting.window.remove.auto=\u0218terge automat itemurile inactive
 Progress.reporting.window.remove.auto.tooltip=\u0218terge automat din vedere toate procesele terminate, e\u0219uate sau anulate
 Progress.reporting.window.remove.now=\u0218terge itemurile inactive
@@ -2298,30 +2260,24 @@ TorrentOptionsView.multi.title.short=Op\u021biunile Torentelor
 TorrentOptionsView.multi.title.full=Op\u021biunile Torentelor
 MyTorrentsView.menu.open_parent_folder=Deschide Dosarul Con\u021bin\u0103tor
 ConfigView.section.style.use_show_parent_folder=Folose\u0219te "%1" \u00een loc de "%2" \u00een meniurile torentelor
-ConfigView.section.style.use_show_parent_folder.tooltip=Activarea acesei op\u021biuni v\u0103 va permite s\u0103 deschide\u021bi dosarul con\u021bin\u0103tor \u00een aplica\u021bia corect\u0103 de administrare a fi\u0219ierelor.\nTotu\u0219i, asta ar putea \u00eensemna c\u0103 locul de salvare a desc\u0103rc\u0103rilor nu este selectat automat.
+ConfigView.section.style.use_show_parent_folder.tooltip=Activarea acesei op\u021biuni \u00ee\u021bi va permite s\u0103 deschizi dosarul con\u021bin\u0103tor \u00een aplica\u021bia corect\u0103 de administrare a filelor.\nTotu\u0219i, asta ar putea \u00eensemna c\u0103 locul de salvare a desc\u0103rc\u0103rilor nu este selectat automat.
 PeerManager.status.ps_disabled=Sursa trackerului partenerilor este dezactivat\u0103
-ConfigView.section.stats.exportfiles=Detaliile Fi\u0219ierului Exportat
+ConfigView.section.stats.exportfiles=Detaliile filei exportate
 updater.cant.write.to.app.title=Nu pot scrie \u00een dosarul aplica\u021biei
-updater.cant.write.to.app.details=\u00cen dosarul "%1" nu se poate scrie.\n\nAceasta va \u00eempiedica aplicarea actualiz\u0103rilor softului.\n\nConsulta\u021bi wikiul<a href="http://www.azureuswiki.com/index.php/Failed_Update">pentru detalii</a>.
+updater.cant.write.to.app.details=\u00cen dosarul "%1" nu se poate scrie.\n\nAceasta va \u00eempiedica aplicarea actualiz\u0103rilor softului.\n\nConsult\u0103 wikiul<a href="http://www.azureuswiki.com/index.php/Failed_Update">pentru detalii</a>.
 plugin.install.class_version_error=Aceast\u0103 extensie necesit\u0103 o versiune mai nou\u0103 de Java pentru a putea rula.
 v3.MainWindow.tab.minilibrary=Desc\u0103rc\u0103ri
 v3.MainWindow.tab.events=Activitate
 button.columnsetup.tooltip=Configureaz\u0103 Coloanele
 v3.activity.remove.title=\u0218terge Intrarea Activit\u0103\u021bii
-v3.activity.remove.text=Sigur dori\u021bi s\u0103 \u00eenl\u0103tura\u021bi eviden\u021ba activit\u0103\u021bii '%1'?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
+v3.activity.remove.text=Sigur vrei s\u0103 \u00eenl\u0103turi eviden\u021ba activit\u0103\u021bii '%1'?
 v3.MainWindow.menu.file.closewindow=\u00cenchide
 Menu.show.torrent.menu=Arat\u0103 Meniul Torentelor
 Menu.show.torrent.menu.tooltip=Arat\u0103 meniul torentelor deasupra barei de meniuri
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
 Views.plugins.aznetstatus.title=Starea Re\u021belei
 plugin.aznetstatus.pingtarget=Ping/traceroute spre \u021bint\u0103
 ConfigView.section.style.usePathFinder=Folose\u0219te "G\u0103sitorul de C\u0103i" \u00een loc de "G\u0103sitor"
-menu.sortByColumn=Sorteaz\u0103 dup\u0103 %1 
+menu.sortByColumn=Sorteaz\u0103 dup\u0103 %1
 MyTorrentsView.menu.manual.per_peer=Manual\u0103 (per partener)
 MyTorrentsView.menu.manual.shared_peers=Manual\u0103 (pt. to\u021bi partenerii)
 v3.button.removeActivityEntry=\u0218terge Intrarea Activit\u0103\u021bii
@@ -2330,16 +2286,12 @@ v3.splash.hookPluginUI=Activez Interfa\u021ba Extensiilor
 OpenTorrentWindow.mb.notTorrent.cannot.display=Nu pot afi\u0219a corect datele
 MainWindow.menu.window.zoom.maximize=Maximizeaz\u0103
 MainWindow.menu.window.zoom.restore=Restaureaz\u0103
-ImageResizer.image.too.small=Imaginea oferit\u0103 e prea mic\u0103, alege\u021bi alta (trebuie s\u0103 fie de cel pu\u021bin %1 x %2)
-ImageResizer.title=Aceast\u0103 unealt\u0103 v\u0103 permite s\u0103 previziona\u021bi modul \u00een care miniatura va ar\u0103ta pe Platforma Vuze
-ImageResizer.move.image=Muta\u021bi imaginea prin tragere
-ImageResizer.move.image.with.slider=Muta\u021bi imaginea prin tragere, redimensiona\u021bi-o folosind glisorul de mai jos
 security.crypto.title=Cheia pentru Acces Criptat
-security.crypto.encrypt=Introduce\u021bi o parol\u0103 pentru a proteja cheia de criptare generat\u0103. Nu uita\u021bi parola pentru c\u0103 nu exist\u0103 nici o cale pentru a o recupera!
-security.crypto.decrypt=Introduce\u021bi parola pentru a debloca cheia de criptare.
+security.crypto.encrypt=Introdu o parol\u0103 pentru a proteja cheia de criptare generat\u0103. Nu uita parola pentru c\u0103 nu exist\u0103 nici o cale de a o recupera!
+security.crypto.decrypt=Introdu parola pentru a debloca cheia de criptare.
 security.crypto.reason=Motivul opera\u021biunii
 security.crypto.password=Parol\u0103
-security.crypto.password2=Reintroduce\u021bi parola
+security.crypto.password2=Reintrodu parola
 security.crypto.persist_for=Perioada de persisten\u021b\u0103 a parolei
 security.crypto.persist_for.dont_save=Nu salva
 security.crypto.persist_for.session=Aceast\u0103 sesiune
@@ -2348,11 +2300,11 @@ security.crypto.persist_for.week=1 s\u0103pt\u0103m\u00een\u0103
 security.crypto.persist_for.30days=30 de zile
 security.crypto.persist_for.forever=Mereu
 security.crypto.password.mismatch.title=Eroare a parolei
-security.crypto.password.mismatch=Parolele introduse nu s\u00eent identice, reintroduce\u021bi-le.
+security.crypto.password.mismatch=Parolele introduse nu s\u00eent identice, reintrodu-le.
 ConfigView.section.security.group.crypto=Chei Publice/Private
 ConfigView.section.security.resetkey=Reseteaz\u0103 cheile
 ConfigView.section.security.resetkey.warning.title=Avertisment despre Pierderea de Date
-ConfigView.section.security.resetkey.warning=Sigur dori\u021bi s\u0103 reseta\u021bi cheile de criptare? Dac\u0103 ve\u021bi face asta toate informa\u021biile criptate cu ele vor fi PIERDUTE DEFINITIV. De asemenea to\u021bi partenerii care posed\u0103 cheia dv. public\u0103 nu vor mai putea comunica cu dv. p\u00een\u0103 la primirea cheii noi. Deci nu face\u021bi asta dac\u0103 nu s\u00eente\u021bi sigur c\u0103 proceda\u021bi bine.
+ConfigView.section.security.resetkey.warning=Sigur vrei s\u0103 resetezi cheile de criptare? Dac\u0103 vei face asta, toate informa\u021biile criptate cu ele vor fi PIERDUTE DEFINITIV. De asemenea to\u021bi partenerii care posed\u0103 cheia ta public\u0103 nu vor mai putea comunica cu tine p\u00een\u0103 la primirea cheii noi. Deci, nu face asta dac\u0103 nu e\u0219ti sigur c\u0103 procedezi bine.
 ConfigView.section.security.unlockkey=Deblocheaz\u0103 \u00een mod explicit cheile
 ConfigView.section.security.unlockkey.button=Deblocheaz\u0103
 ConfigView.section.security.publickey=Cheie Public\u0103
@@ -2362,17 +2314,17 @@ ConfigView.section.security.resetkey.error=Resetarea cheilor a e\u0219uat
 ConfigView.section.security.unlockkey.error=Deblocarea cheii a e\u0219uat - parol\u0103 incorect\u0103
 ConfigView.copy.to.clipboard.tooltip=Copiaz\u0103 \u00een Cliplan\u0219et\u0103
 Views.plugins.azbuddy.title=Prieteni
-Browser.popup.error.no.access=S-a produs o eroare la \u00eencercarea de accesare a unei resurse distante. Re\u00eencerca\u021bi mai t\u00eerziu.
+Browser.popup.error.no.access=S-a produs o eroare la \u00eencercarea de accesare a unei resurse distante. Re\u00eencearc\u0103 mai t\u00eerziu.
 ConfigView.label.queue.stoponcebandwidthmet=Nu mai porni alte torente dac\u0103 a fost atins\u0103 limita vitezei de desc\u0103rcare
 ConfigView.section.style.forceMozilla=For\u021beaz\u0103 Vuze s\u0103 foloseasc\u0103 Mozilla pentru gadgeturile Exploratorului [xulrunner sau firefox 3 s\u00eent necesare; repornirea e \u0219i ea necesar\u0103]
 ConfigView.section.style.xulRunnerPath=Specific\u0103 manual calea XulRunner / Firefox (pentru FF3; necesit\u0103 repornire)
 azbuddy.name=Prieteni
 azbuddy.enabled=Activat
-azbuddy.disabled=Extensia e dezactivat\u0103, schimba\u021bi setarea folosind configurarea extensiei.
+azbuddy.disabled=Extensia e dezactivat\u0103, activeaz-o folosind configurarea extensiei.
 azbuddy.nickname=Porecl\u0103
 azbuddy.msglog.title=Informa\u021bii despre Prieten
-azbuddy.addtorrent.title=Accepta\u021bi Desc\u0103rcarea?
-azbuddy.addtorrent.msg=Prietenul '%1' v-a trimis '%2'.\nDori\u021bi s\u0103 ad\u0103uga\u021bi aceast\u0103 desc\u0103rcare?
+azbuddy.addtorrent.title=Accep\u021bi Desc\u0103rcarea?
+azbuddy.addtorrent.msg=Prietenul '%1' \u021bi-a trimis '%2'.\nVrei s\u0103 adaugi aceast\u0103 desc\u0103rcare?
 azbuddy.contextmenu=Trimite Prietenului
 azbuddy.ui.mykey=Cheia mea:
 azbuddy.ui.add=Adaug\u0103
@@ -2383,7 +2335,7 @@ azbuddy.ui.table.last_msg=Ultimul Mesaj
 azbuddy.ui.menu.remove=\u0218terge
 azbuddy.ui.menu.copypk=Copiaz\u0103 Cheia Public\u0103
 azbuddy.ui.menu.send=Trimite Mesaj
-azbuddy.ui.menu.send_msg=Introduce\u021bi textul de trimis prietenilor
+azbuddy.ui.menu.send_msg=Scrie textul de trimis prietenilor
 azbuddy.ui.menu.ygm=Trimite YGM
 azbuddy.ui.menu.enc=Cripteaz\u0103 Cliplan\u0219eta
 azbuddy.ui.menu.dec=Decripteaz\u0103 Cliplan\u0219eta
@@ -2398,9 +2350,9 @@ azbuddy.ui.table.msg_out=Msj Trim
 v3.MainWindow.menu.view.footer=Bara de Prieteni
 azbuddy.downspeed=KB/s max viteza de desc\u0103rcare a prietenului [0: nelimitat]
 security.crypto.badpw=Parola introdus\u0103 nu e corect\u0103
-ConfigView.section.security.backupkeys=Salvgardeaz\u0103 cheile \u00eentr-un fi\u0219ier
+ConfigView.section.security.backupkeys=Salvgardeaz\u0103 cheile \u00eentr-o fil\u0103
 ConfigView.section.security.backupkeys.button=Salvgardeaz\u0103
-ConfigView.section.security.restorekeys=Restaureaz\u0103 cheile dintr-un fi\u0219ier
+ConfigView.section.security.restorekeys=Restaureaz\u0103 cheile dintr-o fil\u0103
 ConfigView.section.security.restorekeys.button=Restaureaz\u0103
 ConfigView.section.security.op.error.title=Opera\u021biune E\u0219uat\u0103
 ConfigView.section.security.op.error=Terminarea opera\u021biunii a e\u0219uat:\n    %1
@@ -2418,26 +2370,23 @@ Button.bar.add=Adaug\u0103 Prieteni
 Button.bar.edit=Editeaz\u0103
 Button.bar.edit.cancel=Editare Terminat\u0103
 v3.MainWindow.menu.view.pluginbar=Bara de Extensii
-MainWindow.dialog.select.vuze.file=Selecteaz\u0103 Fi\u0219ierul Vuze
-MainWindow.menu.file.open.vuze=Fi\u0219ier Vuze...
+MainWindow.dialog.select.vuze.file=Selecteaz\u0103 Fila Vuze
+MainWindow.menu.file.open.vuze=Fil\u0103 Vuze...
 metasearch.addtemplate.title=Instalez \u0218ablonul de C\u0103utare?
-metasearch.addtemplate.desc=S\u00eente\u021bi sigur c\u0103 dori\u021bi s\u0103 instala\u021bi \u0219ablonul de c\u0103utare numit '%1'?
+metasearch.addtemplate.desc=E\u0219ti sigur c\u0103 vrei s\u0103 instalezi \u0219ablonul de c\u0103utare numit '%1'?
 v3.share.private.title=Partajeaz\u0103 Torentul
-v3.share.private.text=Torentul selectat e marcat ca privat.\n\nNu pute\u021bi partaja torentele private.
+v3.share.private.text=Torentul selectat e marcat ca privat.\n\nNu po\u021bi partaja torentele private.
 metasearch.addtemplate.dup.title=Duplicheaz\u0103 \u0218ablonul
 metasearch.addtemplate.dup.desc=\u0218ablonul de c\u0103utare %1 e deja instalat
 metasearch.export.select.template.file=Salveaz\u0103 \u0218ablonul
 metasearch.import.select.template.file=Deschide \u0218ablonul
-dialog.uiswitch.title=Comut\u0103 la Interfa\u021ba Vuze
-dialog.uiswitch.text=Trebuie s\u0103 rula\u021bi interfa\u021ba Vuze pentru a folosi aceast\u0103 facilitate.\n\nVuze trebuie repornit.
-dialog.uiswitch.button=Comut\u0103 la Interfa\u021ba Vuze
-azbuddy.tracker.enabled=Activeaz\u0103 'Accelerarea Prietenilor' pentru a prioritiza transferul cu prietenii 
+azbuddy.tracker.enabled=Activeaz\u0103 'Accelerarea Prietenilor' pentru a prioritiza transferul cu prietenii
 azbuddy.protocolspeed=KB/s max dep\u0103\u0219irea protocolului de c\u0103tre prieten
 v3.MainWindow.button.download=Descarc\u0103
-v3.MainWindow.button.run=Deschide Fi\u0219ierul Desc\u0103rcat
+v3.MainWindow.button.run=Deschide Fila Desc\u0103rcat\u0103
 v3.activity.header.downloads=Desc\u0103rc\u0103ri
 v3.activity.header.vuze.news=\u0218tiri Vuze
-message.taking.too.long=Se pare c\u0103 opera\u021biunea dureaz\u0103 mai mult dec\u00eet era a\u0219teptat. \nAp\u0103sa\u021bi 'ESC' dac\u0103 dori\u021bi s\u0103 o anula\u021bi.
+message.taking.too.long=Se pare c\u0103 opera\u021biunea dureaz\u0103 mai mult dec\u00eet era a\u0219teptat. \nApas\u0103 'ESC' dac\u0103 vrei s\u0103 o anulezi.
 message.status.success=Succes
 azbuddy.tracker.bbb.status.title=Accelereaz\u0103 Prietenii
 azbuddy.tracker.bbb.status.title.tooltip=Dublu-clic pentru detalii
@@ -2450,9 +2399,9 @@ v3.MainWindow.search.last.tooltip=\u00centoarce-te la Rezultatele C\u0103ut\u010
 metasearch.addtemplate.done.title=\u0218ablon Ad\u0103ugat
 metasearch.addtemplate.done.desc=\u0218ablonul '%1' a fost ad\u0103ugat cu succes.\nVa fi utilizat la urm\u0103toarea c\u0103utare!
 ConfigView.section.security.nopw=Nu a fost introdus\u0103 nici o parol\u0103
-ConfigView.section.security.nopw_v=Nu este disponibil\u0103 nici o parol\u0103, autentifica\u021bi-v\u0103 la Vuze
+ConfigView.section.security.nopw_v=Nu este disponibil\u0103 nici o parol\u0103, autentific\u0103-te la Vuze
 fileplugininstall.install.title=Instalez Extensia?
-fileplugininstall.install.desc=Sigur dori\u021bi s\u0103 instala\u021bi extensia '%1', versiunea %2?
+fileplugininstall.install.desc=Sigur vrei s\u0103 instalezi extensia '%1', versiunea %2?
 fileplugininstall.duplicate.title=Extensie Duplicat\u0103
 fileplugininstall.duplicate.desc=Extensia '%1', versiunea %2 e deja instalat\u0103
 azbuddy.online_status=Stare
@@ -2463,7 +2412,7 @@ azbuddy.os_busy=Ocupat
 azbuddy.os_offline=Neconectat
 azbuddy.ui.menu.disconnect=Deconecteaz\u0103
 azbuddy.enable_chat_notif=Activeaz\u0103 notific\u0103rile \u00een taifas [chat]
-progress.window.msg.progress=A\u0219tepta\u021bi ca opera\u021biunea s\u0103 se termine
+progress.window.msg.progress=A\u0219teapt\u0103 ca opera\u021biunea s\u0103 se termine
 ConfigView.section.connection.advanced.read_select=Expirarea citirii select\u0103rii (msec, implicit %1)
 ConfigView.section.connection.advanced.read_select_min=A\u0219teptarea minim\u0103 a citirii select\u0103rii (msec, implicit %1)
 ConfigView.section.connection.advanced.write_select=Expirarea scrierii select\u0103rii (msec, implicit %1)
@@ -2473,12 +2422,12 @@ ConfigView.section.connection.network.max.outstanding.connect.attempts=Nr. max.
 plugins.init.force_enabled=Vuze a detectat c\u0103 extensia "%1" a fost dezactivat\u0103 - ea a fost reactivat\u0103 pentru a permite func\u021bionarea corect\u0103 a lui Vuze.
 ConfigView.section.connection.prefer.udp=Prefer\u0103 conexiunile UDP
 subscript.add.title=Instalez Abonamentul?
-subscript.add.desc=Sigur dori\u021bi s\u0103 instala\u021bi abonamentul '%1'?
+subscript.add.desc=Sigur vrei s\u0103 instalezi abonamentul '%1'?
 subscript.add.dup.title=Abonament Duplicat
 subscript.add.dup.desc=Abonamentul '%1' e deja instalat.
 subscript.add.upgrade.title=Supragradez Abonamentul?
-subscript.add.upgrade.desc=Sigur dori\u021bi s\u0103 supragrada\u021bi [upgrade] abonamentul '%1'?
-subscript.add.upgradeto.desc=Versiunea %1 a abonamentului '%2' e disponibil\u0103.\nDori\u021bi s\u0103 actualiza\u021bi?
+subscript.add.upgrade.desc=Sigur vrei s\u0103 supragradezi [upgrade] abonamentul '%1'?
+subscript.add.upgradeto.desc=Versiunea %1 a abonamentului '%2' e disponibil\u0103.\nVrei s\u0103-l actualizezi?
 azsubs.contextmenu.addassoc=Adaug\u0103 asociere a abonamentului
 azsubs.contextmenu.lookupassoc=Vezi asocierile abonamentului
 iconBar.start=Porne\u0219te
@@ -2503,7 +2452,7 @@ v3.MainWindow.menu.view.actionbar=Bara de Ac\u021biuni
 v3.MainWindow.menu.view.toolbars=Bare de Unelte
 ump.install=Actualizare Rapid\u0103 \u00cen Curs:\nInstalez o mic\u0103 extensie de redare necesar\u0103 acestui video.
 subscriptions.listwindow.title=G\u0103sitor de Abonamente
-subscriptions.listwindow.autochecktext=Vuze poate g\u0103si abonamente similare cu con\u021binutul din Arhiv\u0103. Dori\u021bi s\u0103 activa\u021bi aceast\u0103 facilitate?
+subscriptions.listwindow.autochecktext=Vuze poate g\u0103si abonamente similare cu con\u021binutul din Arhiv\u0103. Vrei s\u0103 activezi aceast\u0103 facilitate?
 subscriptions.listwindow.loadingtext=Caut abonamente corelate cu %1
 subscriptions.listwindow.failed=Nu au fost g\u0103site abonamente
 subscriptions.listwindow.popularity=Popularitate
@@ -2512,12 +2461,12 @@ subscriptions.listwindow.name=Nume
 subscriptions.listwindow.subscribe=Aboneaz\u0103
 TableColumn.header.azsubs.ui.column.subs=Abonare
 subscriptions.listwindow.popularity.reading=Citesc...
-PluginDeprecation.log.start=Aceast\u0103 fereastr\u0103 con\u021bine informa\u021bii despre extensii ce folosesc facilit\u0103\u021bi care vor fi fi \u00eenl\u0103turate din versiunile viitoare de Vuze.\nNu e nevoie s\u0103 dezinstala\u021bi extensiile, trebuie doar s\u0103 le actualiza\u021bi la ultima versiune.\nDac\u0103 rula\u021bi deja ultima versiune, atunci copia\u021bi con\u021binutul acestei ferestre \u0219i posta\u021bi-l pe forumul aflat aici:\n \t%1\n\n
+PluginDeprecation.log.start=Aceast\u0103 fereastr\u0103 con\u021bine informa\u021bii despre extensii ce folosesc facilit\u0103\u021bi care vor fi fi \u00eenl\u0103turate din versiunile viitoare de Vuze.\nNu e nevoie s\u0103 dezinstalezi extensiile, trebuie doar s\u0103 le actualizezi la ultima versiune.\nDac\u0103 rulezi deja ultima versiune, atunci copiaz\u0103 con\u021binutul acestei ferestre \u0219i posteaz\u0103-l pe forumul aflat aici:\n \t%1\n\n
 PluginDeprecation.log.details=---------\nIDENTIFICATOR: %1\nCONTEXT: %2\n\n*** BEGIN TRACE ***\n%3*** END TRACE ***\n\n
 PluginDeprecation.view=Debugheaz\u0103 Extensia
-PluginDeprecation.alert=O extensie a \u00eencercat s\u0103 foloseasc\u0103 o facilitate ce va fi \u00eenl\u0103turat\u0103 pe viitor - deschide\u021bi jurnalul de Debugare a Extensiilor pentru mai multe informa\u021bii.
-TableColumn.header.Thumbnail=Iconi\u021b\u0103
-TableColumn.header.Thumbnail.info=Imagine miniaturizat\u0103 pentru con\u021binut din re\u021beaua Vuze; Pentru con\u021binutul de alt\u0103 provenien\u021b\u0103 s\u00eent folosite iconi\u021bele sistemului de operare.
+PluginDeprecation.alert=O extensie a \u00eencercat s\u0103 foloseasc\u0103 o facilitate ce va fi \u00eenl\u0103turat\u0103 pe viitor - deschide jurnalul de Debugare a Extensiilor pentru mai multe informa\u021bii.
+TableColumn.header.Thumbnail=Icoan\u0103
+TableColumn.header.Thumbnail.info=Imagine miniaturizat\u0103 pentru con\u021binut din re\u021beaua Vuze; Pentru con\u021binutul de alt\u0103 provenien\u021b\u0103 s\u00eent folosite icoanele sistemului de operare.
 v3.MainWindow.menu.getting_started=&Prezentare Vuze
 MainWindow.menu.community=&Comunitate
 MainWindow.menu.help.faq=\u00centreb\u0103ri Puse &Frecvent
@@ -2526,8 +2475,8 @@ MainWindow.menu.community.forums=Fo&rumul Vuze
 MainWindow.menu.community.blog=&Blogul Vuze
 MainWindow.menu.help.support=A&jutor \u0219i Suport
 externalLogin.title=Logare Necesar\u0103
-externalLogin.explanation=\u0218ablonul "%1" necesit\u0103 logare. Dup\u0103 logare, aceast\u0103 fereastr\u0103 se va \u00eenchide automat. Dac\u0103 nu se \u00eent\u00eempl\u0103 asta ap\u0103sa\u021bi pe "gata".
-externalLogin.explanation.capture=Trebuie s\u0103 v\u0103 loga\u021bi pentru a crea acest \u0219ablon. Dup\u0103 logare, clica\u021bi pe "Gata".
+externalLogin.explanation=\u0218ablonul "%1" necesit\u0103 logare. Dup\u0103 logare, aceast\u0103 fereastr\u0103 se va \u00eenchide automat. Dac\u0103 nu se \u00eent\u00eempl\u0103 asta, apas\u0103 pe "gata".
+externalLogin.explanation.capture=Trebuie s\u0103 te loghezi pentru a crea acest \u0219ablon. Dup\u0103 logare, clicheaz\u0103 pe "Gata".
 Button.done=Gata
 GeneralView.torrent_created_on_and_by=%1 de %2
 Button.continue=Continu\u0103
@@ -2565,7 +2514,6 @@ Subscription.menu.resetauth=Reseteaz\u0103 Detaliile de Autentificare
 Search.menu.engines=\u0218abloane
 Wizard.Subscription.title=Aboneaz\u0103
 Wizard.Subscription.optin.title=Activez Abonamentele?
-#what you've watched? Discover more with a single click...
 Wizard.Subscription.subscribe.title=Abonamente Disponibile
 Wizard.Subscription.create.title=Creeaz\u0103 Abonament Nou
 Button.search=Caut\u0103
@@ -2573,21 +2521,21 @@ Button.save=Salveaz\u0103
 Button.add=Adaug\u0103
 Button.createNewSubscription=Creeaz\u0103 Abonament Nou
 Button.availableSubscriptions=Abonamente Disponibile
-Wizard.Subscription.optin.description=Dac\u0103 activa\u021bi Abonamentele, ve\u021bi putea descoperi unele similare cu con\u021binutul din arhiva dv. Clica\u021bi:
+Wizard.Subscription.optin.description=Dac\u0103 activezi Abonamentele, vei putea descoperi unele similare cu con\u021binutul din arhiva ta. Clicheaz\u0103:
 Wizard.Subscription.create.search=Caut\u0103
-Wizard.Subscription.search.subtitle1=Tasta\u021bi ni\u0219te cuvinte-cheie pentru a crea abonamentul:
+Wizard.Subscription.search.subtitle1=Scrie ni\u0219te cuvinte-cheie pentru a crea abonamentul:
 Wizard.Subscription.search.subtitle2=Ce pot c\u0103uta?
 Wizard.Subscription.search.subtitle2.sub1=Filme, Spectacole TV, Prezent\u0103ri de filme existente \u00een re\u021beaua Vuze
 Wizard.Subscription.search.subtitle2.sub2=Torente de pe internet
-Wizard.Subscription.search.subtitle3=Dup\u0103 ce abonamentul a fost realizat, ve\u021bi primi \u00een panoul lateral actualiz\u0103ri referitoare la rezultatele c\u0103ut\u0103rilor f\u0103cute.
-Wizard.Subscription.rss.subtitle1=Tasta\u021bi sau lipi\u021bi adresa mai jos:
-Wizard.Subscription.rss.subtitle2=Mul\u021bi produc\u0103tori ofer\u0103 fluxuri RSS pentru con\u021binutul publicat. G\u0103si\u021bi adresa (URL) fluxului pe situl produc\u0103torului, copia\u021bi-o \u0219i lipi\u021bi-o \u00een c\u00eempul de mai sus, apoi clica\u021bi butonul Salveaz\u0103. 
-Wizard.Subscription.rss.subtitle3=Odat\u0103 salvat, ve\u021bi primi \u00een panoul lateral actualiz\u0103ri referitoare la rezultatele c\u0103ut\u0103rilor specificate \u00een fluxurile RSS.
+Wizard.Subscription.search.subtitle3=Dup\u0103 ce abonamentul a fost realizat, vei primi \u00een panoul lateral actualiz\u0103ri referitoare la rezultatele c\u0103ut\u0103rilor f\u0103cute.
+Wizard.Subscription.rss.subtitle1=Scrie sau lipe\u0219te adresa mai jos:
+Wizard.Subscription.rss.subtitle2=Mul\u021bi produc\u0103tori ofer\u0103 fluxuri RSS pentru con\u021binutul publicat. G\u0103se\u0219te adresa (URL) fluxului pe situl produc\u0103torului, copiaz-o \u0219i lipe\u0219te-o \u00een c\u00eempul de mai sus, apoi clicheaz\u0103 pe butonul Salveaz\u0103.
+Wizard.Subscription.rss.subtitle3=Odat\u0103 salvat, vei primi \u00een panoul lateral actualiz\u0103ri referitoare la rezultatele c\u0103ut\u0103rilor specificate \u00een fluxurile RSS.
 Wizard.Subscription.subscribe.library=Con\u021binut \u00een Arhiv\u0103
 Wizard.Subscription.subscribe.subscriptions=Abonamente Similare
-Wizard.Subscription.subscribe.library.empty=Nu s\u00eent disponibile abonamente?\n \nUita\u021bi-v\u0103 \u00een Re\u021beaua Vuze HD dup\u0103 butonul portocaliu de abonare.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>
-message.confirm.delete.title=Confirma\u021bi \u0218tergerea
-message.confirm.delete.text=Sigur dori\u021bi s\u0103 \u0219terge\u021bi '%1'?
+Wizard.Subscription.subscribe.library.empty=Nu s\u00eent disponibile abonamente?\n \nUit\u0103-te \u00een Re\u021beaua Vuze HD dup\u0103 butonul portocaliu de abonare.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>
+message.confirm.delete.title=Confirm\u0103 \u0218tergerea
+message.confirm.delete.text=Sigur vrei s\u0103 \u0219tergi '%1'?
 Subscription.menu.properties=Propriet\u0103\u021bi
 props.window.title=Propriet\u0103\u021bi pentru '%1'
 subs.prop.is_auto=Autodescarc\u0103 rezultatele noi
@@ -2599,7 +2547,7 @@ subs.prop.num_unread=Num\u0103rul de rezultate necitite
 subs.prop.template=\u0218ablon
 subs.prop.auth=E necesar\u0103 autentificarea
 externalLogin.auth_method_proxy=Folose\u0219te metoda extins\u0103 de capturare a fursecurilor [cookies]. Dac\u0103 acest lucru e\u0219ueaz\u0103, trebuie dezactivat\u0103 op\u021biunea \u0219i re\u00eencercat.
-externalLogin.wait=Pagina se \u00eencarc\u0103, a\u0219tepta\u021bi...
+externalLogin.wait=Pagina se \u00eencarc\u0103, a\u0219teapt\u0103...
 TableColumn.menu.date_added.time=Arat\u0103/Ascunde Timpul
 sidebar.VuzeHDNetwork=Re\u021beaua Vuze HD
 subs.prop.next_scan=Urm\u0103toarea scanare \u00een
@@ -2613,35 +2561,35 @@ subscriptions.column.last-checked=Ultima Verificare
 subscriptions.view.title=Abonamente
 subs.prop.high_version=A fost descoperit\u0103 o versiune mai nou\u0103
 Subscription.menu.upgrade=Activeaz\u0103 supragradarea [upgrade] la o versiune superioar\u0103
-metasearch.template.version.bad=\u0218ablonul de c\u0103utare '%1' nu va putea fi instalat dec\u00eet dac\u0103 ve\u021bi supragrada [upgrade] Vuze
+metasearch.template.version.bad=\u0218ablonul de c\u0103utare '%1' nu va putea fi instalat dec\u00eet dac\u0103 vei supragrada [upgrade] Vuze
 metasearch.addtemplate.failed.title=Instalare E\u0219uat\u0103
 metasearch.addtemplate.failed.desc=Instalare e\u0219uat\u0103 a \u0219ablonului de c\u0103utare: %1
-subscription.version.bad=Abonamentul '%1' nu pote fi instalat dec\u00eet dup\u0103 ce supragrada\u021bi [upgrade] Vuze
-statusbar.feedback=Spune\u021bi-v\u0103 P\u0103rerea
-statusbar.feedback.tooltip=Clica\u021bi aici pentru a v\u0103 spune p\u0103rerea
+subscription.version.bad=Abonamentul '%1' nu pote fi instalat dec\u00eet dup\u0103 ce supragradezi [upgrade] Vuze
+statusbar.feedback=Spune-\u021bi P\u0103rerea
+statusbar.feedback.tooltip=Clicheaz\u0103 aici pentru a-\u021bi spune p\u0103rerea
 sidebar.Activity=Notific\u0103ri
 v3.activity.button.watchall=Marcheaz\u0103 Tot ca Citit
 subscriptions.view.help.1=Abonarea e disponibil\u0103 oriunde apare
-subscriptions.view.help.2=Ob\u021bine\u021bi actualiz\u0103ri instantanee ori de c\u00eete ori este disponibil con\u021binut nou pentru desc\u0103rcare. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Read more</A>.
+subscriptions.view.help.2=Ob\u021bine actualiz\u0103ri instantanee ori de c\u00eete ori este disponibil con\u021binut nou pentru desc\u0103rcare. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">Cite\u0219te mai mult</A>.
 sidebar.sash.tooltip=F7 arat\u0103/ascunde rapid panoul lateral
 sidebar.expand.tooltip=Expandeaz\u0103 Panoul Lateral
 sidebar.dropdown.tooltip=Arat\u0103 panoul lateral \u00een format de meniu
-subscript.all.subscribed=S\u00eente\u021bi abonat la acest con\u021binut
-subscript.some.subscribed=S\u00eente\u021bi abonat la unele surse pentru acest con\u021binut.\nClica\u021bi pentru a vedea \u0219i alte surse disponibile.
-subscript.none.subscribed=Clica\u021bi pentru a vedea abonamentele disponibile pentru acest con\u021binut
-v3.iconBar.up.tooltip=Mut\u0103 \u00een Sus\n\u021aine\u021bi ap\u0103sat butonul mausului pentru a muta \u00een sus
-v3.iconBar.down.tooltip=Mut\u0103 \u00een Jos\n\u021aine\u021bi ap\u0103sat butonul mausului pentru a muta \u00een jos
+subscript.all.subscribed=E\u0219ti abonat la acest con\u021binut
+subscript.some.subscribed=E\u0219ti abonat la unele surse pentru acest con\u021binut.\nClicheaz\u0103 pentru a vedea \u0219i alte surse disponibile.
+subscript.none.subscribed=Clicheaz\u0103 pentru a vedea abonamentele disponibile pentru acest con\u021binut
+v3.iconBar.up.tooltip=Mut\u0103 \u00een Sus\n\u021aine ap\u0103sat butonul mausului pentru a muta \u00een sus
+v3.iconBar.down.tooltip=Mut\u0103 \u00een Jos\n\u021aine ap\u0103sat butonul mausului pentru a muta \u00een jos
 TableColumn.header.azsubs.ui.column.subs_link=Asociere
 TableColumn.header.azsubs.ui.column.subs_link.info=Asociat cu abonamentele
 Button.deleteContent.fromLibrary=\u0218terge din Arhiva Torentelor
 Button.deleteContent.fromComputer=\u0218terge de pe Calculator
-v3.deleteContent.message=\nDori\u021bi s\u0103 \u0219terge\u021bi '%1' de pe calculator sau doar s\u0103-l \u00eenl\u0103tura\u021bi din Arhiva Vuze?
+v3.deleteContent.message=\nVrei s\u0103 \u0219tergi '%1' de pe calculator sau doar s\u0103-l \u00eenl\u0103turi din Arhiva Torentelor?
 v3.MainWindow.menu.view.toolbartext=Text pe Bara de Unelte
 v3.MainWindow.menu.view.asSimpleList=List\u0103 Simpl\u0103
 v3.MainWindow.menu.view.asAdvancedList=List\u0103 Avansat\u0103
 v3.MainWindow.menu.view.statusbar=Bara de Stare
 Subscription.menu.dirtyall=Marcheaz\u0103 Toate Rezultatele ca Citite
-configureWizard.file.message3=Vuze va desc\u0103rca fi\u0219ierele \u00eentr-un dosar special, pe care pute\u021bi s\u0103-l alege\u021bi aici:
+configureWizard.file.message3=Vuze va desc\u0103rca filele \u00eentr-un dosar special, pe care po\u021bi s\u0103-l alegi aici:
 v3.deleteContent.applyToAll=Aplic\u0103 ac\u021biunea la toate cele %1 intr\u0103ri selectate
 ConfigView.label.seeding.firstPriority.ignoreIdleHours=Torente care nu \u00eencarc\u0103 nimic timp de
 v3.MainWindow.menu.contentnetworks=&Re\u021bele HD
@@ -2650,38 +2598,31 @@ Peers.column.as.info=Detalii despre SA-ul partenerului (Sistemul Autonom)
 ConfigView.label.autoopen.downloadbars=Deschide automat Barele de Desc\u0103rcare c\u00eend
 ConfigView.label.autoopen=Autodeschide
 ConfigView.label.autoopen.detailstab=Deschide automat tabul Detalii c\u00eend
-ConfigView.label.systray=Sistaler
-ConfigView.label.systray._mac=Iconi\u021ba din Bara de Stare
+ConfigView.label.systray=Sertar
+ConfigView.label.systray._mac=Icoana din Bara de Stare
 ConfigView.section.interface.legacy=\u00cenvechit
 v3.MainWindow.menu.contentnetworks.manage=Ad&ministreaz\u0103 Re\u021belele HD
 azbuddy.ui.menu.cat=Categorii
 azbuddy.ui.menu.cat.share=Activeaz\u0103 abonamentele pentru prieteni
-azbuddy.ui.menu.cat.set=Introduce\u021bi categoriile
+azbuddy.ui.menu.cat.set=Scrie categoriile
 azbuddy.ui.menu.cat.set_msg=List\u0103 de categorii separate prin virgul\u0103, sau 'Tot'
 azbuddy.ui.menu.cat_subs=Aboneaz\u0103
 subs.prop.update_period=Perioada de actualizare
-azbuddy.enable_cat_pub=Categorii publice la care se pot abona TO\u021aI prietenii dv. (separate prin ',' ) 
-v3.dialog.cnclose.title=%1 \u00cenchis
-v3.dialog.cnclose.subtitle=Notificare
-v3.dialog.cnclose.info1=A\u021bi \u00eenchis o Re\u021bea HD
-v3.dialog.cnclose.info2=Dac\u0103 dori\u021bi s\u0103 redeschide\u021bi aceast\u0103 re\u021bea HD, o pute\u021bi face \u00een meniul "Re\u021bele HD" din partea de sus a ecranului.
-v3.dialog.cnclose.noshow=Nu ar\u0103ta din nou
-v3.dialog.cnmanage.title=Administreaz\u0103 Meniul Re\u021belelor HD
-v3.dialog.cnmanage.intro=Pute\u021bi alege din lista de mai jos re\u021belele de con\u021binut care dori\u021bi s\u0103 fie afi\u0219ate \u00een meniul "Re\u021bele HD"
+azbuddy.enable_cat_pub=Categorii publice la care se pot abona TO\u021aI prietenii t\u0103i (separate prin ',' )
 TableColumn.header.#=Nr.
 TableColumn.header.#.info=Num\u0103rul de Pozi\u021bie/Ordonare
 TableColumn.header.category.info=Numele categoriei c\u0103reia \u00eei apar\u021bine torentul
 TableColumn.header.DateCompleted.info=Data la care a fost terminat\u0103 desc\u0103rcarea torentului
 TableColumn.header.AzProduct.info=Re\u021beaua de con\u021binut de unde provine torentul
-TableColumn.header.health.info=C\u00eet de s\u0103n\u0103toas\u0103/viabil\u0103 este conexiunea dv. la roiul torentului
+TableColumn.header.health.info=C\u00eet de s\u0103n\u0103toas\u0103/viabil\u0103 este conexiunea ta la roiul torentului
 TableColumn.header.maxuploads.info=Nr. maxim de parteneri c\u0103tre care se poate \u00eenc\u0103rca simultan
 TableColumn.header.name.info=Numele Torentului
 TableColumn.header.unopened.info=Fanion care indic\u0103 dac\u0103 torentul a fost redat (deschis)
-TableColumn.header.savepath.info=Dosarul sau fi\u0219ierul de destina\u021bie pentru datele din torent
+TableColumn.header.savepath.info=Dosarul sau fila de destina\u021bie pentru datele din torent
 TableColumn.header.SeedingRank.info=Valoarea rangului sau c\u00eet de mult are nevoie un torent de donare.. O valoare mai mare \u00eenseamn\u0103 o necesitate mai mare.
-TableColumn.header.shareRatio.info=C\u00eet de mult a\u021bi \u00eenc\u0103rcat (partajat) comparativ cu c\u00eet de mult a\u021bi desc\u0103rcat.
+TableColumn.header.shareRatio.info=C\u00eet de mult ai \u00eenc\u0103rcat (partajat) comparativ cu c\u00eet de mult ai desc\u0103rcat.
 TableColumn.header.size.info=M\u0103rimea pe disc a con\u021binutului torentului
-TableColumn.header.azsubs.ui.column.subs.info=Buton care v\u0103 permite s\u0103 v\u0103 abona\u021bi la fluxul ce con\u021bine torente \u00eenrudite
+TableColumn.header.azsubs.ui.column.subs.info=Buton care-\u021bi permite s\u0103 te abonezi la fluxul ce con\u021bine torente \u00eenrudite
 TableColumn.header.upspeed.info=Viteza curent\u0103 de \u00eenc\u0103rcare
 TableColumn.header.downspeed.info=Viteza curent\u0103 de desc\u0103rcare
 TableColumn.header.up.info=Cantitatea curent\u0103 de date trimise altor utilizatori
@@ -2695,7 +2636,7 @@ TableColumn.header.download.info=Cantitatea de date primit\u0103 de la partener
 TableColumn.header.upload.info=Cantitatea de date pe care i le-am trimis partenerului
 TableColumn.header.downloadspeed.info=Viteza cu care se primesc date de la partener
 TableColumn.header.uploadspeed.info=Viteza cu care s\u00eent trimise datele c\u0103tre partener
-TableColumn.header.lan.info=Fanion care indic\u0103 dac\u0103 partenerul e \u00een re\u021beaua (LAN) dv.
+TableColumn.header.lan.info=Fanion care indic\u0103 dac\u0103 partenerul e \u00een re\u021beaua ta (LAN)
 TableColumn.header.downloadspeedoverall.info=Viteza de desc\u0103rcare estimat\u0103 a partenerului
 Peers.column.pieces.info=Bar\u0103 grafic\u0103 care prezint\u0103 p\u0103r\u021bile desc\u0103rcate de partener
 TableColumn.header.TableColumnNameInfo=Numele \u0219i Descrierea Coloanei
@@ -2703,15 +2644,15 @@ TableColumn.header.TableColumnSample=E\u0219antion
 TableColumn.header.TableColumnInfo=Descrierea Coloanei
 TableColumn.header.TableColumnChosenColumn=Coloana Aleas\u0103
 subs.prop.is_auto_ok=Autodesc\u0103rcare permis\u0103
-label.learnmore=Afla\u021bi mai multe
+label.learnmore=Afl\u0103 mai multe
 ColumnSetup.title=Configurarea Coloanelor pt. '%1'
-ColumnSetup.explain=Explora\u021bi coloanele disponibile din st\u00eenga \u0219i ad\u0103uga\u021bi-le la lista de coloane vizibile \u00een dreapta. M\u0103ri\u021bi sau diminua\u021bi lista de coloane disponibile folosind sec\u021biunea de Filtrare din partea st\u00eeng\u0103-jos. Tragerea-\u0219i-depunerea [drag-and-drop], ca \u0219i scurt\u0103turile de tastatur\u0103 pot fi de asemenea folosite.
+ColumnSetup.explain=Exploreaz\u0103 coloanele disponibile din st\u00eenga \u0219i adaug\u0103-le la lista de coloane vizibile \u00een dreapta. M\u0103re\u0219te sau mic\u0219oreaz\u0103 lista de coloane disponibile folosind sec\u021biunea de Filtrare din partea st\u00eeng\u0103-jos. Tragerea-\u0219i-punerea [drag-and-drop], ca \u0219i scurt\u0103turile de tastatur\u0103 pot fi de asemenea folosite.
 ColumnSetup.chosencolumns=Coloane Alese
 ColumnSetup.proficiency=Competen\u021b\u0103:
 ColumnSetup.categories=Categorii:
 ColumnSetup.filters=Filtre
-ColumnSetup.availcolumns=%1 coloane disponibile
-ColumnSetup.availcolumns.filteredby=%1 coloane disponibile filtrate dup\u0103 %2
+ColumnSetup.availcolumns=Coloane Disponibile %1
+ColumnSetup.availcolumns.filteredby=Coloane disponibile %1 filtrate dup\u0103 %2
 devices.view.title=Dispozitive
 device.renderer.view.title=Randatoare
 device.mediaserver.view.title=Servere Media
@@ -2745,12 +2686,12 @@ General.percent=Procent
 devices.installed=Instalat
 devices.comp.missing=Nu a fost instalat suportul pentru Vuze
 devices.state=Stare
-MainWindow.menu.help.donate=&Face\u021bi o Dona\u021bie
+MainWindow.menu.help.donate=&Doneaz\u0103 Bani pentru Soft
 DonationWindow.noload.title=Donare
-DonationWindow.noload.text=Fereastra de donare nu a putut fi \u00eenc\u0103rcat\u0103.  Re\u00eencerca\u021bi mai t\u00eerziu.
-devices.xcode.only.show=Arat\u0103 doar fi\u0219ierele transcodate de pe dispozitiv
+DonationWindow.noload.text=Fereastra de donare nu a putut fi \u00eenc\u0103rcat\u0103.  Re\u00eencearc\u0103 mai t\u00eerziu.
+devices.xcode.only.show=Arat\u0103 doar filele transcodate de pe dispozitiv
 device.quit.transcoding.title=Transcodare \u00een curs
-device.quit.transcoding.text='%1' este actualmente transcodat \u00een '%2', iar %3% e complet\u0103.\nDac\u0103 \u00eenchide\u021bi programul, opera\u021biunea va trebui reluat\u0103 de la \u00eenceput la urm\u0103toarea pornire a programului.
+device.quit.transcoding.text='%1' este actualmente transcodat \u00een '%2', iar %3% e complet\u0103.\nDac\u0103 \u00eenchizi programul, opera\u021biunea va trebui reluat\u0103 de la \u00eenceput la urm\u0103toarea pornire a programului.
 download.removerules.unauthorised.data=\t\u00cenl\u0103tur\u0103 datele
 device.config.xcode.maxbps=Rata de transcodare max. KB/sec [0: nelimitat]
 device.xcode=Transcodeaz\u0103
@@ -2759,9 +2700,9 @@ device.xcode.whenreq=C\u00eend e necesar
 device.xcode.never=Niciodat\u0103
 devices.copy.pending=Copiere \u00een a\u0219teptare
 devices.sidebar.hide.rend.generic=Ascunde dispozitivele generice
-v3.devicesview.infobar.text2=Pentru a transcoda con\u021binut c\u0103tre un dispozitiv, trage\u021bi \u0219i depune\u021bi con\u021binut din arhiv\u0103 \u00een dispozitivele din panoul lateral.  Pentru a vedea transcod\u0103rile terminate clica\u021bi dispozitivul individual din dreapta.
+v3.devicesview.infobar.text2=Pentru a transcoda con\u021binut c\u0103tre un dispozitiv, trage \u0219i pune con\u021binut din arhiv\u0103 \u00een dispozitivele din panoul lateral.  Pentru a vedea transcod\u0103rile terminate, clicheaz\u0103 dispozitivul individual din dreapta.
 iconBar.transcode=Dispozitiv
-iconBar.transcode.tooltip=Prepar\u0103 fi\u0219ierul media pentru redarea cu un dispozitiv
+iconBar.transcode.tooltip=Prepar\u0103 fila media pentru redarea cu un dispozitiv
 device.retry.copy=Re\u00eencearc\u0103 Copierea
 devices.copy.fail=Copierea pe dispozitiv a e\u0219uat
 devices.on.demand=La cerere
@@ -2781,13 +2722,13 @@ v3.iconBar.view.big.tooltip=List\u0103 Simpl\u0103
 v3.iconBar.view.small=zi
 v3.iconBar.view.small.tooltip=List\u0103 Avansat\u0103
 general.dont.ask.again=Nu \u00eentreba din nou
-v3.menu.device.exploreTranscodes=Arat\u0103 Fi\u0219ierele
-v3.menu.device.exploreTranscodes._windows=Arat\u0103 Fi\u0219ierele \u00een Explorator
-v3.menu.device.exploreTranscodes._mac=Arat\u0103 Fi\u0219ierele \u00een G\u0103sitor
+v3.menu.device.exploreTranscodes=Arat\u0103 Filele
+v3.menu.device.exploreTranscodes._windows=Arat\u0103 Filele \u00een Explorator
+v3.menu.device.exploreTranscodes._mac=Arat\u0103 Filele \u00een G\u0103sitor
 v3.menu.device.defaultprofile=Profil Implicit
 devices.button.installitunes=Instaleaz\u0103 Integrarea cu iTunes
-device.itunes.install=Trebuie s\u0103 instala\u021bi iTunes
-device.itunes.start=Trebuie s\u0103 porni\u021bi iTunes sau s\u0103 activa\u021bi autopornirea
+device.itunes.install=Trebuie s\u0103 instalezi iTunes
+device.itunes.start=Trebuie s\u0103 porne\u0219ti iTunes sau s\u0103 activezi autopornirea
 device.itunes.install_problem=Se pare c\u0103 exist\u0103 o problem\u0103 cu integrarea iTunes
 devices.downloading=Descarc
 TableColumn.header.duration=Durat\u0103
@@ -2797,33 +2738,33 @@ option.askeverytime=\u00centreab\u0103 de fiecare dat\u0103
 option.rememberthis=Memoreaz\u0103 aceast\u0103 setare
 devices.associate=Asociaz\u0103 cu
 devices.associate.already=Deja asociat
-devices.always.cache=Ca\u0219eaz\u0103 Fi\u0219ierele Netranscodate
+devices.always.cache=Ca\u0219eaz\u0103 Filele Netranscodate
 devices.turnon.prepageload=Pentru a activa aceast\u0103 facilitate, e necesar\u0103 instalarea unor componente suplimentare.
 devices.turnon.itunes=Include suportul pentru iTunes (necesar pt. dispozitivele Apple)
 devices.turnon.qos=Trimite statistici anonimizate la Vuze
 devices.turnon.title=Activeaz\u0103 Suportul pt. Dispozitiv
-devices.choose.device.title=Selecta\u021bi un dispozitiv de redare pentru acest video:
-devices.choose.profile.info.text=Dup\u0103 selectare, Vuze va detecta dac\u0103 formatul video va putea sau nu s\u0103 fie redat pe dispozitivul selectat, \u0219i va crea la nevoie o copie compatibil\u0103 cu dispozitivul.\n\nDuce\u021bi cursorul mausului deasupra dispozitivului pentru a vedea detalii suplimentare.
+devices.choose.device.title=Selecteaz\u0103 un dispozitiv de redare pentru acest video:
+devices.choose.profile.info.text=Dup\u0103 selectare, Vuze va detecta dac\u0103 formatul video va putea sau nu s\u0103 fie redat pe dispozitivul selectat, \u0219i va crea la nevoie o copie compatibil\u0103 cu dispozitivul.\n\nDu cursorul mausului deasupra dispozitivului pentru a vedea detalii suplimentare.
 devices.choose.profile.info.title.selected=Detalii %1:
 devices.view.heading=Convertire media pentru redarea cu un dispozitiv
 device.view.heading=Media pentru %1
 devices.choose.device.info.title=Pont pentru Dispozitiv
-devices.choose.device.info.text=Data viitoare, trage\u021bi \u0219i depune\u021bi fi\u0219ierele peste dispozitivul dorit din Panoul Lateral.
-label.clickone=Clica\u021bi pe unul din dispozitive
+devices.choose.device.info.text=Data viitoare, trage \u0219i pune filele peste dispozitivul dorit din Panoul Lateral.
+label.clickone=Clicheaz\u0103 pe unul din dispozitive
 Button.turnon=Activeaz\u0103
 ConfigView.label.dm.dblclick=Dublu-clicheaz\u0103 \u00een vederea torentelor:
 ConfigView.option.dm.dblclick.play=Red\u0103 Con\u021binutul
 ConfigView.option.dm.dblclick.details=Deschide Vederea Detaliat\u0103 a Torentului
-ConfigView.option.dm.dblclick.show=Arat\u0103 Fi\u0219ierul
-ConfigView.option.dm.dblclick.show._mac=Arat\u0103 Fi\u0219ierele \u00een G\u0103sitor
-ConfigView.option.dm.dblclick.show._windows=Arat\u0103 Fi\u0219ierele \u00een Explorator
+ConfigView.option.dm.dblclick.show=Arat\u0103 Fila
+ConfigView.option.dm.dblclick.show._mac=Arat\u0103 Filele \u00een G\u0103sitor
+ConfigView.option.dm.dblclick.show._windows=Arat\u0103 Filele \u00een Explorator
 subscriptions.column.auto-download=Descarc\u0103 Automat
 xcode.deletedata.title=\u0218terge Con\u021binutul Transcodat
-xcode.deletedata.message=Sigur dori\u021bi s\u0103 \u0219terge\u021bi definitiv copia lui '%1' transcodat\u0103 pentru '%2'%3?
+xcode.deletedata.message=Sigur vrei s\u0103 \u0219tergi definitiv copia lui '%1' transcodat\u0103 pentru '%2'%3?
 xcode.deletedata.message.2=\n(o copie ar putea s\u0103 mai existe \u00een '%1')
-v3.deviceview.infobar.line1=Trage\u021bi \u0219i depune\u021bi videouri din Arhiva Torentelor \u00een dispozitivul dorit.
-v3.deviceview.infobar.line2=Reda\u021bi videourile pe oricare din ecranele avute la dispozi\u021bie - iPhone, iPod, TV
-v3.deviceview.infobar.line1.generic=Trage\u021bi \u0219i depune\u021bi videouri din Arhiva Torentelor \u00een sec\u021biunea %1 din Panoul Lateral.
+v3.deviceview.infobar.line1=Trage \u0219i pune videouri din Arhiva Torentelor \u00een dispozitivul dorit.
+v3.deviceview.infobar.line2=Red\u0103 videourile pe oricare din ecranele avute la dispozi\u021bie - iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=Trage \u0219i pune videouri din Arhiva Torentelor \u00een sec\u021biunea %1 din Panoul Lateral.
 v3.deviceview.infobar.line2.itunes=Videourile vor ap\u0103rea \u00een dosarul iTunes Movies c\u00eend vor fi gata de a fi redate.
 v3.deviceview.infobar.line2.xbox=Fluxeaz\u0103 [stream] videourile acces\u00eend Xbox-ul 360 \u0219i select\u00eend My XBox -> Video Library -> Vuze.
 v3.deviceview.infobar.line2.ps3=Fluxeaz\u0103 [stream] videourile acces\u00eend PS3-ul \u0219i select\u00eend Videos -> Vuze.
@@ -2833,53 +2774,50 @@ Button.reload=Re\u00eencarc\u0103
 devices.auto.start=Autoporne\u0219te
 Subscription.menu.setcookies=Seteaz\u0103 Fursecurile [Cookies]
 general.enter.cookies=Fursecurile intr\u0103rii [cookies]
-device.config.xcode.workdir=Dosarul implicit de lucru pentru fi\u0219ierele transcodate
+device.config.xcode.workdir=Dosarul implicit de lucru pentru filele 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
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - cite\u0219te {wiki.fat32}
+ConfigView.section.file.rename.incomplete=Adaug\u0103 sufix la filele 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)
 subscriptions.config.autostart.min=Porne\u0219te doar dac\u0103 >= MB [0: nelimitat]
 subscriptions.config.autostart.max=Porne\u0219te doar dac\u0103 <= MB [0: nelimitat]
 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
+dlg.corewait.text=A\u0219teapt\u0103 un pic...\n\nSolicitarea va fi procesat\u0103 dup\u0103 ce se va termina ini\u021bializarea Vuze
+library.core.wait=A\u0219teapt\u0103 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.add.friends=Adaug\u0103 ni\u0219te prieteni!
 general.all.friends=To\u021bi Prietenii
-friend.mod.subs=Clica\u021bi-dreapta pentru a modifica abonamentele
+friend.mod.subs=Clicheaz\u0103-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.view=Clicheaz\u0103 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.auto=Copiaz\u0103 automat filele \u00een dosar
 devices.copy.folder.dest=Copiaz\u0103 \u00een Dosar
 TableColumn.menu.maxuploads=Nr. Max \u00cenc\u0103rc\u0103ri
-devices.xcode.mancopy=Copiaz\u0103 Manual Fi\u0219ierele
+devices.xcode.mancopy=Copiaz\u0103 Manual Filele
 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
+devices.info.copypending=%1 file 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.copyfail=Una sau mai multe file 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.
+device.error.copyfail2=Una sau mai multe file nu au putut fi copiate pe dispozitiv
+v3.deviceview.infobar.line2.tivo=Fluxeaz\u0103 [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
+devices.info.copypending2=%1 file a\u0219teapt\u0103 s\u0103 fie copiate, conecteaz\u0103 dispozitivul
 subscriptions.column.nb-subscribers=Abona\u021bi
 device.offlinedownloader.view.title=Desc\u0103rc\u0103toare Neconectate
 device.od.enable=Activeaz\u0103 dispozitivele cu desc\u0103rcare neconectat\u0103 [offline]
@@ -2904,10 +2842,10 @@ ConfigView.section.style.forceSIValues=For\u021beaz\u0103 ar\u0103tarea valorilo
 ConfigView.label.enableSystrayToolTip=Arat\u0103 statisticile de desc\u0103rcare la planarea cu mausul
 devices.activation=Activarea Dispozitivului
 button.nothanks=Nu, Mul\u021bumesc
-devices.od.turnon.text1=Am observat c\u0103 s\u00eente\u021bi conectat la %1.
-devices.od.turnon.text2=Dori\u021bi ca %1 s\u0103 continue desc\u0103rcarea fi\u0219ierelor atunci c\u00eend calculatorul este neconectat [offline]?
-devices.od.turnon.text3=Conecta\u021bi un Hardisc la %1 pentru a activa aceast\u0103 facilitate.
-devices.od.turnon.learn=Afla\u021bi mai multe >
+devices.od.turnon.text1=Am observat c\u0103 e\u0219ti conectat la %1.
+devices.od.turnon.text2=Vrei ca %1 s\u0103 continue desc\u0103rcarea filelor atunci c\u00eend calculatorul este neconectat [offline]?
+devices.od.turnon.text3=Conecteaz\u0103 un Hardisc la %1 pentru a activa aceast\u0103 facilitate.
+devices.od.turnon.learn=Afl\u0103 mai multe >
 devices.router=ruter
 devices.od=desc\u0103rc\u0103tor neconectat
 webui.pairingenable=Activeaz\u0103 cuplarea [pairing]
@@ -2918,37 +2856,29 @@ pairing.ac.getnew=Aloc\u0103 un cod nou de acces
 pairing.ac.getnew.create=Creeaz\u0103
 pairing.ipv4=Adres\u0103 IPv4
 pairing.ipv6=Adres\u0103 IPv6
+pairing.local.ipv4=Adres\u0103 local\u0103 IPv4
+pairing.local.ipv6=Adres\u0103 local\u0103 IPv6
 pairing.host=Adresa gazdei (Nume DNS)
 pairing.group.explicit=Atribute Explicite
 pairing.explicit.enable=Activeaz\u0103
-pairing.explicit.info=Atributele explicite IP nu trebuie specificate \u00een mod obi\u0219nuit, pentru c\u0103 pot fi deduse automat.\nAtributul 'host' poate fi utilizat de exemplu dac\u0103 ave\u021bi un cont DynDNS \u0219i soft client potrivit pentru a p\u0103stra adresa IP dinamic\u0103 \u00eenregistrat\u0103 corect.
-pairing.op.fail=Opera\u021bia de cuplare a e\u0219uat
+pairing.explicit.info=Atributele explicite IP nu trebuie specificate \u00een mod obi\u0219nuit, pentru c\u0103 pot fi deduse automat.\nAtributul 'host' poate fi utilizat de exemplu dac\u0103 ai un cont DynDNS \u0219i soft client potrivit pentru a p\u0103stra adresa IP dinamic\u0103 \u00eenregistrat\u0103 corect.
+pairing.op.fail=Opera\u021biunea de cuplare a e\u0219uat
 pairing.alloc.fail=Alocarea unui cod nou de acces a e\u0219uat\n%1
-pairing.enable=Activeaz\u0103 cuplarea [pairing] softului Vuze cu aplica\u021bii/interfe\u021be distante
+pairing.enable=Activeaz\u0103 cuplarea [pairing] softului Vuze cu o aplica\u021bie/interfa\u021b\u0103 distant\u0103
 pairing.status.info=Stare
 pairing.status.registered=Actualizare reu\u0219it\u0103 (%1)
 pairing.status.pending=Actualizarea va fi realizat\u0103 la %1
 pairing.status.initialising=Ini\u021bializare
 pairing.status.disabled=Dezactivat\u0103
-pairing.view.registered=Clica\u021bi pentru a vedea detaliile \u00eenregistr\u0103rii curente
-webui.pairing.info.n=Cuplarea este dezactivat\u0103, vede\u021bi op\u021biunile de la Conexiune->Cuplare pentru informa\u021bii despre aceast\u0103 facilitate.
-webui.pairing.info.y=Cuplarea este activat\u0103, vede\u021bi op\u021biunile de la Conexiune->Cuplare pentru detalii suplimentare.
+pairing.view.registered=Clicheaz\u0103 pentru a vedea detaliile \u00eenregistr\u0103rii curente
+webui.pairing.info.n=Cuplarea este dezactivat\u0103, vezi op\u021biunile de la Conexiune->Cuplare pentru informa\u021bii despre aceast\u0103 facilitate.
+webui.pairing.info.y=Cuplarea este activat\u0103, vezi op\u021biunile de la Conexiune->Cuplare pentru detalii suplimentare.
 webui.enable=Activeaz\u0103 (*)
 ConfigView.section.rss=RSS Local etc.
 subscriptions.rss.enable=Creeaz\u0103 Flux RSS din abonamente
 device.tivo.enable=Activeaz\u0103 suportul pentru TiVo
 Button.removeAll=\u00cenl\u0103tur\u0103 Tot
-label.rename=Redenume\u0219te %1
-RCM.column.rc_rank=Rang
-RCM.column.rc_created=Creat
-RCM.column.rc_hash=Ha\u0219
-RCM.column.rc_lastseen=Ultima Apari\u021bie
-RCM.column.rc_level=Nivel
-rcm.view.heading=Descoperiri ale Roiului
-rcm.config.enabled=Activeaz\u0103
-rcm.config.max_results=Nr. Maxim de Rezultate
-rcm.config.max_level=Nivel Maxim
-rcm.search.provider=Roi
+label.rename=Renume\u0219te %1
 pairing.server.warning.title=Mesajul Serverului de Cuplare
 wizard.webseedseditor.edit.title=Editorul Donatorilor HTTP
 wizard.webseedseditor.edit.newseed=Donator Nou
@@ -2956,3 +2886,517 @@ MyTorrentsView.menu.editWebSeeds=Editeaz\u0103 Donatorii HTTP
 ClientStats.title.full=Statisticile Softului
 ClientStats.column.count=Num\u0103r
 Scrape.status.cached=R\u0103zuire [scrape] ca\u0219at\u0103
+network.ipv6.enable.support=Activeaz\u0103 suportul IPv6
+ConfigView.section.plugins.magnetplugin=Procesator de Adrese Magnet
+MagnetPlugin.use.lookup.service=Folose\u0219te serviciul de c\u0103utare suplimentar \u00een cazul \u00een care c\u0103utarea magnet prin DHT e\u0219ueaz\u0103
+MagnetPlugin.report.secondarylookup=\u00cencerc serviciul de c\u0103utare suplimentar
+MagnetPlugin.report.secondarylookup.ok=C\u0103utarea suplimentar\u0103 a avut succes
+MagnetPlugin.report.secondarylookup.fail=C\u0103utarea suplimentar\u0103 a e\u0219uat: nu au fost g\u0103site surse
+TrackerView.title.short=Surse
+TrackerView.title.full=Surse
+Trackers.column.type=Tip
+Trackers.column.name=Detalii
+Trackers.column.status=Stare
+Trackers.column.seeds=Donatori
+Trackers.column.seeds.info=Donatori \u00een roi
+Trackers.column.leechers=Profitori
+Trackers.column.leechers.info=Profitori \u00een roi
+Trackers.column.peers=Parteneri
+Trackers.column.peers.info=Parteneri returna\u021bi (declara\u021bi) de tracker
+Trackers.column.interval.info=Interval de resolicitare \u00een sec: interval (interval min.)
+Trackers.column.updatein=Continu\u0103
+Trackers.column.updatein.info=Timp p\u00een\u0103 la urm\u0103toarea actualizare
+tps.status.available=Disponibil
+tps.status.unavailable=Nedisponibil
+tps.lan.details=%1 clien\u021bi locali descoperi\u021bi
+tps.pex.details=Conectat la %1 parteneri (\u00een a\u0219teptare: pex=%2, al\u021bii=%3)
+tps.tracker.cache=Ca\u0219ul [cache] partenrilor
+tps.tracker.cache1=Ca\u0219ul partenerilor: intr\u0103ri=%1
+dht.status.disabled=Dezactivat, baza de date distribuit\u0103 nu e disponibil\u0103
+tps.type.incoming=Intr\u00eend
+tps.incoming.details=Curent: TCP=%1, UDP=%2; Total oric\u00eend=%3
+tps.type.plugin=Extensie
+ConfigView.label.autoadjust=Ajusteaz\u0103 automat aceste set\u0103ri \u00een func\u021bie de viteza de conectare
+ConfigView.label.start=Pornire
+ConfigView.label.stop=\u00cenchidere
+ConfigView.label.start.onlogin=Porne\u0219te Vuze odat\u0103 cu sistemul de operare
+ConfigView.label.stop.seedcomp=C\u00eend donarea este terminat\u0103
+ConfigView.label.stop.downcomp=C\u00eend desc\u0103rcarea este terminat\u0103
+ConfigView.label.stop.Nothing=Nici o Ac\u021biune
+ConfigView.label.stop.QuitVuze=\u00cenchide Vuze
+ConfigView.label.stop.Sleep=Pune Calculatorul \u00een Veghe [Stand-by]
+ConfigView.label.stop.Hibernate=Pune Calculatorul \u00een Hibernare
+ConfigView.label.stop.Shutdown=\u00cenchide Calculatorul
+core.shutdown.alert=Ac\u021biunea '%1' declan\u0219at\u0103 ca %2
+core.shutdown.dl=desc\u0103rc\u0103ri terminate
+core.shutdown.se=donare terminat\u0103
+pairing.last.error=Ultima eroare
+MainWindow.menu.pairing=Cuplarea Telecomenzii
+ConfigView.label.pauseresume=Auto-pauzeaz\u0103/reia
+update.now.title=Actualizare necesar\u0103
+update.now.desc=Vuze trebuie s\u0103 aplice actualiz\u0103rile pentru a termina migrarea.\n\nDup\u0103 \u00eenchiderea acestui dialog vei fi \u00eendemnat de SO Windows s\u0103 termini procesul de actualizare.\n\nRepornirea Vuze NU este necesar\u0103.
+ConfigView.label.jvm=Op\u021biuni Java
+platform.jvmopt.sunonly=Doar MVJ [JVM] Sun s\u00eent suportate (produc\u0103torul curent=%1)
+platform.jvmopt.configerror=Nu se pot administra op\u021biunile MVJ [JVM], din cauza unei erori de configurare
+platform.jvmopt.nolinkfile=Nu se pot administra op\u021biunile MVJ [JVM], pentru c\u0103 migra\u021bia nu e terminat\u0103
+platform.jvmopt.nolink=Nu se pot administra op\u021biunile MVJ [JVM], pentru c\u0103 acest lucru e interzis de configura\u021bia curent\u0103
+platform.jvmopt.accesserror=Accesarea filei de op\u021biuni MVJ [JVM] a e\u0219uat: %1
+pairing.status.noservices=Nu este activat nici un serviciu la distan\u021b\u0103
+webui.pairingtest=\tClicheaz\u0103 pentru a testa cuplarea
+webui.connectiontest=\tClicheaz\u0103 pentru a testa conexiunea
+jvm.info=Este necesar\u0103 repornirea Vuze dac\u0103 op\u021biunile au fost modificate. *** Aten\u021bie - modificarea incorect\u0103 a op\u021biunilor MVJ [JVM] poate face ca Vuze s\u0103 nu mai porneasc\u0103 sau s\u0103 func\u021bioneze prost ***\n
+jvm.show.file=Fil\u0103 local\u0103 cu op\u021biuni MVJ [JVM] este '%1' - Editeaz\u0103 direct doar \u00een scopuri de reparare
+jvm.reset=Reseteaz\u0103 op\u021biunile MVJ [JVM] la implicitele de la instalare
+jvm.error=A ap\u0103rut o eroare la accesarea op\u021biunilor MVJ [JVM]: %1
+jvm.max.mem=M\u0103rime max. memorie [gol=implicit,min=%1]
+jvm.min.mem=M\u0103rime min. memorie [gol=implicit,min=%1]
+ConfigView.section.invalid.value.title=Valoare Nevalid\u0103
+ConfigView.section.invalid.value=Valoare nevalid\u0103 '%1' introdus\u0103 pentru '%2': %3
+Button.dismiss=Nu Accept
+webui.pairing.autoauth=Activeaz\u0103 protec\u021bia parolei implicite: utilizator=vuze, parol\u0103=<codul de acces al cupl\u0103rii>
+ConfigView.label.stop.autoreset=Reseteaz\u0103 automat op\u021biunea la '%1' dup\u0103 declan\u0219area ac\u021biunii
+remote.pairing.title=Cuplarea Telecomenzii
+remote.pairing.subtitle=Telecomanda Vuze v\u0103 d\u0103 posibilitatea de a controla Vuze de pe orice calculator sau dispozitiv mobil - oric\u00eend, oriunde.
+remote.pairing.instruction=Scrie codul de mai jos \u00een spa\u021biile oferite de aplica\u021bia de control la distan\u021b\u0103.
+remote.pairing.functions=<A HREF="clip">Copiaz\u0103 codul \u00een cliplan\u0219et\u0103</A>   |   <A HREF="new">Ob\u021bine cod nou</A>
+remote.pairing.tip.title=Pont: Dou\u0103 moduri simple de a utiliza Telecomanda Vuze:
+remote.pairing.tip.text=Bara Telecomenzii Vuze: Mergi la <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nTelecomanda Vuze Mobil: Mergi la <A HREF="http://remote.vuze.com/">remote.vuze.com</A> \u00een exploratorul [browser] mobil.
+remote.pairing.learnmore=<A HREF="/pairing_learnmore.start">\u00centreb\u0103ri Frecvente despre Cuplare</A>
+remote.pairing.accesscode=Cod de Acces:
+remote.pairing.test.running=Testez conectivitatea la distan\u021b\u0103...
+remote.pairing.test.success=Vuze este accesibil \u00een mod telecomandat.
+remote.pairing.test.unavailable=Hopa, nu am putut determina conectivitatea la distan\u021b\u0103. <A HREF="retry">Re\u00eencearc\u0103</A>
+remote.pairing.test.fail=Vuze nu este accesibil \u00een afara re\u021belei tale locale.  <A HREF="/pairing_error_faq.start">Afl\u0103 mai multe</A>
+update.fail.app.changed.title=E\u0219ec al actualiz\u0103rii
+update.fail.app.changed=Vuze trebuie s\u0103 fie actualizat, dar procesul nu poate fi realizat automat pentru c\u0103 numele aplica\u021biei a fost schimbat \u00een '%1'.\n\nMergi la http://www.vuze.com/ \u0219i descarc\u0103 ultimul instalator.
+webui.port.override=Ignorarea portului: necesar doar dac\u0103 portul public difer\u0103 de cel intern datorit\u0103 configura\u021biei NAT
+MainWindow.status.warning.tooltip=Clicheaz\u0103 aici pentru detalii
+search.dialog.text=Scrie textul pt. c\u0103utarea torentelor noi:
+core.not.available=Vuze este \u00eenc\u0103 \u00een curs de ini\u021bializare, re\u00eencearc\u0103 dup\u0103 terminarea ei
+dlg.auth.title=Activare
+dlg.auth.enter.subtitle.try.1=Aproape gata.
+dlg.auth.enter.line.try.1=Introdu mai jos codul de activare pentru a termina supragradarea [upgrade] la Vuze Plus.
+dlg.auth.enter.line.try.2=Scuze, nu am putut valida codul t\u0103u de activare. Verific\u0103 num\u0103rul \u0219i \u00eencearc\u0103 s\u0103-l scrii din nou.
+dlg.auth.enter.prompt=Cod de Activare Vuze Plus:
+Button.validate=Valideaz\u0103
+Button.getstarted=\u00cencepe
+Button.goLibrary=Arhiva Torentelor
+dlg.auth.success.subtitle=Felicit\u0103ri!
+dlg.auth.success.line1=\u00ce\u021bi mul\u021bumim c\u0103 ai supragradat [upgraded] la Vuze Plus.
+dlg.auth.success.line2=Po\u021bi de acum \u00eencolo s\u0103 inscrip\u021bionezi DVD-uri, s\u0103 scanezi filele de viru\u0219i, s\u0103 faci c\u0103ut\u0103ri mai extinse - totul f\u0103r\u0103 publicitate!
+dlg.auth.trial.success.line1=Vuze este gata s\u0103 creeze DVD-uri.
+dlg.auth.trial.success.subtitle=DVD Burn este Gata
+dlg.auth.trial.success.info=Trage file video din arhiva torentelor \u00een sec\u021biunea "Creeaz\u0103 DVD Nou." Dac\u0103 ai ad\u0103ugat deja un video \u00eenainte de instalarea componentelor, adaug\u0103-l din nou.
+dlg.auth.revoked=Activare a Codului Revocat\u0103
+dlg.auth.revoked.line1=Codul t\u0103u de Activare Vuze Plus a fost revocat. Clicheaz\u0103 mai jos pentru informa\u021bii suplimentare.
+dlg.auth.revoked.link=<A HREF="info">Informa\u021bii despre Coduri de Activare revocate</A>
+dlg.auth.denied=Cod de Activare Refuzat
+dlg.auth.denied.line1=Codul t\u0103u de Activare pentru Vuze Plus a fost refuzat. Clicheaz\u0103 mai jos pentru informa\u021bii suplimentare.
+dlg.auth.denied.link=<A HREF="info">Informa\u021bii despre Codurile de Activare refuzate</A>
+dlg.auth.cancelled=Activare a Codului Anulat\u0103
+dlg.auth.cancelled.line1=Codul t\u0103u de Activare pentru Vuze Plus  a fost anulat. Dac\u0103 crezi c\u0103 e vorba de o eroare, contacteaz\u0103 departamentul de suport folosind instruc\u021biunile din mesajul electronic primit drept chitan\u021b\u0103.
+dlg.auth.cancelled.line2=Dac\u0103 crezi c\u0103 e vorba de o eroare, contacteaz\u0103 departamentul de suport folosind instruc\u021biunile din mesajul electronic primit drept chitan\u021b\u0103.
+dlg.auth.enter.subtitle.try.2=Validare e\u0219uat\u0103
+dlg.auth.enter.link.try.2=<A HREF="link">Clicheaz\u0103 aici</A> dac\u0103 nu ai cump\u0103rat \u00eenc\u0103 softul Vuze Plus.
+dlg.auth.enter.link.try.1=Nu ai un cod de activare? <A HREF="upgrade">Supragradeaz\u0103 [upgrade] acum</A>.
+dlg.auth.enter.expiry=Codul de activare curent expir\u0103 pe %1.
+dlg.auth.enter.revoked=Codul de activare curent a fost revocat.
+dlg.auth.enter.cancelled=Codul de activare curent a fost anulat.
+dlg.auth.enter.denied=Codul de activare curent a fost refuzat.
+dlg.auth.validating.subtitle=Validez...
+dlg.try.trial.title=\u00cencearc\u0103 DVD Burn
+dlg.try.trial.text=Vuze trebuie s\u0103 instaleze extensia necesar\u0103 pentru inscrip\u021bionarea DVD-urilor cu filmele tale. Clicheaz\u0103 pe Porne\u0219te pentru a continua.
+dlg.auth.tos=Am citit \u0219i acceptat <A HREF="tos">Termenii de Utilizare.</A>
+dlg.auth.install.subtitle.plus=Instalez Vuze Plus...
+dlg.auth.install.subtitle.trial=Instalez DVD Burn
+dlg.auth.install.progress=Instalez componentele %1...
+dlg.auth.install.pct=%1% realizat
+mdi.entry.dvdburn=Inscrip\u021bionare DVD
+mdi.entry.dvdburn.new=Creeaz\u0103 DVD Nou
+menu.register=Activeaz\u0103 Vuze Plus
+dlg.auth.trial.title=Evaluare DVD Burn
+dlg.player.install.subtitle=Instalare
+dlg.player.install.description=Instalez componenta de redare suplimentar\u0103...
+devices.xcode.remove.vetoed=Transcodarea '%1' e \u00een curs, deci desc\u0103rcarea nu poate fi \u00eenl\u0103turat\u0103 p\u00een\u0103 la terminarea opera\u021biunii sau anularea transcod\u0103rii.
+Button.agree=Accept
+dlg.auth.install.failed.title=Activare e\u0219uat\u0103
+dlg.auth.install.failed.text=Activarea codului '%1' a e\u0219uat din cauza unei erori a serverului.\n\nRe\u00eencearc\u0103 activarea mai t\u00eerziu (eroarea raportat\u0103 a fost '%2')
+device.status.online=Dispozitivul e conectat
+device.itunes.status.running=iTunes ruleaz\u0103
+device.itunes.status.notrunning=iTunes nu ruleaz\u0103
+device.itunes.status.notinstalled=iTunes nu este instalat
+OpenTorrentWindow.mb.notTorrent.retry=C\u0103utare Magnet
+ConfigView.section.ipfilter.clear.on.reload=Cur\u0103\u021b\u0103 filtrele la re\u00eenc\u0103rcare. \u00cen timpul procesului de re\u00eenc\u0103rcare adresele IP nu vor fi blocate. Dac\u0103 op\u021biunea e nebifat\u0103, debloc\u0103rile recente nu vor deveni efective dec\u00eet dup\u0103 repornire.
+view.waiting.core=Vederea va fi disponibil\u0103 dup\u0103 terminarea \u00eenc\u0103rc\u0103rii Nucleului Vuze..
+cat.autoxcode=Auto-Dispozitiv
+ConfigView.section.tables=Tabele
+ConfigView.section.style.useTree=Arat\u0103 Filele \u00een Arhiva Torentelor (necesit\u0103 repornire)
+ConfigView.section.mode.resetdefaults=Reseteaz\u0103 configura\u021bia la valorile implicite (necesit\u0103 repornire)
+resetconfig.warn.title=Confirm\u0103 Ac\u021biunea
+resetconfig.warn=Aceasta va face ca toate modific\u0103rile pe care le-ai f\u0103cut la configura\u021bia Vuze s\u0103 fie pierdute.\nVrei s\u0103 continui cu resetarea configura\u021biei?
+ConfigView.label.xfer.bias_up=Cre\u0219te vitezele de desc\u0103rcare ale torentelor prin direc\u021bionarea cu predilec\u021bie a capacit\u0103\u021bii de \u00eenc\u0103rcare spre desc\u0103rc\u0103rile neterminate
+ConfigView.label.xfer.bias_slack=KB/s minimum rezerva\u021bi pentru desc\u0103rc\u0103rile complete
+ConfigView.label.xfer.bias_no_limit=\u00cencearc\u0103 s\u0103 aplici predilec\u021bia c\u00eend nu exist\u0103 o limit\u0103 efectiv\u0103 global\u0103 de \u00eenc\u0103rcare
+SpeedView.stats.upload=Date de \u00eenc\u0103rcare puse \u00een coad\u0103:
+SpeedView.stats.con=Detaliile conexiunii:
+SpeedView.stats.con_details=total=%1, neg\u00eetuit=%2, pus \u00een coad\u0103=%3, blocat=%4
+SpeedView.stats.upbias=Predilec\u021bia \u00eenc\u0103rc\u0103rii:
+dlg.install.mlab.subtitle=Instalez
+dlg.install.mlab.description=A\u0219teapt\u0103 s\u0103 se instaleze componenta de testare a vitezei conexiunii
+dial.up=Dial-Up
+auto.mode=Automat (recomandat)
+configureWizard.transfer2.hint=Setarea limitei vitezei de \u00eenc\u0103rcare prea sus sau prea jos va afecta performan\u021ba desc\u0103rc\u0103rii!
+configureWizard.transfer2.message=Torentele se bazeaz\u0103 pe un protocol care func\u021bioneaz\u0103 pe baz\u0103 de reciprocitate  - \u00een general cu c\u00eet este mai rapid\u0103 \u00eenc\u0103rcarea, cu at\u00eet va fi mai rapid\u0103 desc\u0103rcarea - deci pentru a desc\u0103rca rapid \u0219i a avea un raport [ratio] de partajare bun, ai nevoie de o vitez\u0103 de \u00eenc\u0103rcare mare.\n\nTotu\u0219i, dac\u0103 \u00eenc\u0103rcarea este prea rapid\u0103 pentru conexiunea ta, [...]
+configureWizard.transfer2.group=Mod
+configureWizard.transfer2.test.info=Selecteaz\u0103 pentru a efectua un test de vitez\u0103 am\u0103nun\u021bit
+configureWizard.transfer2.test=Ruleaz\u0103 Testul
+configureWizard.transfer2.mselect=Selecteaz\u0103 limita vitezei de \u00ceNC\u0102RCARE a conexiunii tale la internet
+configureWizard.transfer2.mselect.info=Intr\u0103rile de tipul xxx/<valoare numeric\u0103> denot\u0103 o vitez\u0103 de \u00eenc\u0103rcare de <valoare numeric\u0103> bi\u021bi-pe-secund\u0103.\nDe exemplu, dac\u0103 ai o conexiune ADSL cu viteza de desc\u0103rcare de 768 Kbps \u0219i viteza de \u00eenc\u0103rcare de 384 Kbps, selecteaz\u0103 'xxx/384 kbi\u021bi/sec'.\nRotunje\u0219te la valoarea cea mai apropiat\u0103 dac\u0103 viteza exact\u0103 a conexiunii tale nu este ar\u0103tat\u0103.
+configureWizard.transfer2.rate.unchanged=Vor fi utilizate set\u0103rile curente
+configureWizard.transfer2.rate.changed=Limit conexiunii=%1\nLimita aplicat\u0103 va fi %2 (nr. max torente active=%3, nr. max desc\u0103rc\u0103ri=%4)
+speedtest.wizard.select.title=Selecteaz\u0103 tipul testului de vitez\u0103 care s\u0103 fie rulat
+speedtest.wizard.select.group=Tipul de Test
+speedtest.wizard.select.general=Test de vitez\u0103 generic (recomandat)
+speedtest.wizard.select.bt=Test de vitez\u0103 specific Bittorrent
+FileItem.storage.reorder=Reordoneaz\u0103
+ConfigView.label.piecereorder=Ata\u0219eaz\u0103 datele la file a\u0219a cum s\u00eent desc\u0103rcate \u0219i reordoneaz\u0103 p\u0103r\u021bile \u00een timp ce desc\u0103rcarea progreseaz\u0103.
+ConfigView.label.piecereorderminmb=Reordoneaz\u0103 doar filele mai mari dec\u00eet at\u00eet (\u00een MB)
+configureWizard.transfer2.current=<Set\u0103rile Curente>
+ConfigView.section.style.extendedErase=Deseneaz\u0103 liniile grilei \u0219i umple zonele albe
+iconBar.stream=Flux
+FilesView.menu.setpriority.numeric=Numeric\u0103...
+FilesView.dialog.priority.title=Introdu Prioritatea Numeric\u0103
+FilesView.dialog.priority.text=Obi\u0219nuit\u0103, 1=\u00cenalt\u0103, 2=Mai \u00cenalt\u0103...
+beta.wizard.title=Instalarea Versiunii Beta
+beta.wizard.intro.title=Participare la Testarea Versiunilor Beta
+beta.wizard.info=Participarea la programul Vuze Beta \u00ee\u021bi ofer\u0103 posibilitatea s\u0103 ai acces la facilit\u0103\u021bile care vor ap\u0103rea \u00een versiunile viitoare ale softului.\n\nAsta \u00ee\u021bi permite s\u0103 le experimentezi \u0219i s\u0103 aju\u021bi la procesul lor de punere \u00een practic\u0103 - p\u0103rerea ta este foarte important\u0103 pentru noi!\n\nPrin \u00eens\u0103\u0219i natura lor versiunile beta pot fi instabile, dar prin selectarea acestei op\ [...]
+beta.wizard.link=Clicheaz\u0103 aici pentru a accesa pagina versiunii beta
+beta.wizard.off=S\u00eent mul\u021bumit cu versiunile obi\u0219nuite, mul\u021bumesc!
+beta.wizard.on=Actualizeaz\u0103 mereu softul la ultima versiune beta stabil\u0103.
+beta.wizard.version=\u00cen acest moment rulezi versiunea %1
+beta.wizard.disable.title=Reinstalare Necesar\u0103
+beta.wizard.disable.text=\u00ce\u021bi mul\u021bumim c\u0103 testezi versiunile beta!\n\nDescarc\u0103 \u0219i instaleaz\u0103 ultima versiune lansat\u0103 pentru a p\u0103r\u0103si programul beta
+beta.wizard.forum=Folose\u0219te forumul Vuze pentru a-\u021bi spune p\u0103rerea despre soft \u0219i a raporta buguri
+dlg.install.vuzexcode.subtitle=Instalez componenta de analiz\u0103 media
+dlg.install.vuzexcode.description=A\u0219teapt\u0103 s\u0103 se instaleze componenta de analiz\u0103 media
+TableColumn.header.filecount=File
+TableColumn.header.torrentspeed=Vitez\u0103
+FileProgress.deleted=\u0218ters
+priority.high=Prioritate \u00cenalt\u0103
+priority.normal=Prioritate Obi\u0219nuit\u0103
+label.wrap.text=\u00cencadreaz\u0103 Textul
+ScrapeInfoView.title=Tracker Principal
+Column.seedspeers.started=%1 din %2
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 itemuri: %2 active
+library.incomplete.header.p=%1 itemuri se descarc\u0103, %2 a\u0219teapt\u0103 desc\u0103rcarea
+library.unopened.header.p=%1 itemuri
+library.all.header=%1 item: %2 activ
+library.incomplete.header=%1 item se descarc\u0103, %2 a\u0219teapt\u0103 desc\u0103rcarea
+library.unopened.header=itemul %1
+ConfigView.section.style.status.show_rategraphs=Arat\u0103 graficul istoricului vitezelor sub textul desc\u0103rcare/\u00eenc\u0103rcare
+device.error.mountrequired="%1" Necesit\u0103 Montarea [Mounting] Dispozitivului T\u0103u
+v3.deviceview.infobar.line2.android=Activeaz\u0103 montarea portului USB pe telefonul t\u0103u pentru ca videourile s\u0103 fie transferate corespunz\u0103tor.
+MyTorrents.column.ColumnProgressETA.compon=Terminat pe %1
+Sidebar.beta.title=Testarea Versiunilor Beta
+MainWindow.menu.beta.on=Al\u0103tur\u0103-te Test\u0103rii Versiunilor Beta...
+MainWindow.menu.beta.off=P\u0103r\u0103se\u0219te Testarea Versiunilor Beta...
+Button.sendNow=Trimite Acum
+Button.sendManual=Trimite Manual (creeaz\u0103 .zip)
+deletecontent.also.deletetorrent=\u0218terge \u0219i fila .torrent
+ConfigView.section.file.deletion.section=\u0218tergerea Filelor
+ConfigView.section.file.delete.torrent=\u00cen mod implicit, \u0219terge \u0219i fila .torrent atunci c\u00eend se \u0219terge con\u021binutul torentului
+ConfigView.section.file.delete.confirm=Cere confirmare la \u0219tergerea con\u021binutului folosind Bara de Unelte sau tasta Delete
+MainWindow.menu.view.beta=Testarea Versiunilor Beta
+ConfigView.section.server.enableudpprobe=Activeaz\u0103 sondarea pentru trackere UDP \u00een cazul trackerelor HTTP
+memmon.low.warning=Memoria se epuizeaz\u0103, au mai r\u0103mas doar %1 din totalul de %2.\nPerforman\u021ba va sc\u0103dea, iar \u00een cele din urm\u0103 Vuze se va opri.\nVezi <a href="http://wiki.vuze.com/w/Java_VM_memory_usage">Wikiul</a> pentru detalii despre cum s\u0103 fie crescut\u0103 memoria disponibil\u0103.
+jvm.max.mem.current=Memoria Maxim\u0103 Alocat\u0103 Dinamic este %1
+jvm.max.direct.mem=M\u0103rimea Maxim\u0103 a Memoriei Directe [gol=implicit\u0103,min=%1]
+jvm.max.direct.mem.info=Not\u0103: aceasta seteaz\u0103 memoria *Direct\u0103*, dar este mai degrab\u0103 necesar s\u0103 fie actualizat\u0103 memoria *Dinamic\u0103* mai sus
+jvm.options.summary=Rezumatul op\u021biunilor explicite curente:
+memmon.heap.auto.increase.warning=Memoria Alocat\u0103 Dinamic a fost crescut\u0103 la %1. Aceast\u0103 schimbare va deveni efectiv\u0103 dup\u0103 repornirea Vuze.
+device.showGeneric=Arat\u0103 Dispozitivele Generice
+mdi.entry.games=Jocuri
+devices.copying=Copiez pe dispozitiv
+devices.cancel_xcode=Anuleaz\u0103 Convertirea
+sidebar.header.transfers=File
+sidebar.header.devices=Redare cu Dispozitive
+sidebar.header.subscriptions=Abonamente
+sidebar.header.plugins=Extensii \u0219i Adaosuri
+mdi.entry.about.devices=\u00cen Curs
+mdi.entry.about.plugins=Despre Extensii
+mdi.entry.about.dvdburn=Porne\u0219te
+ConfigView.section.file.tb.delete=C\u00eend se \u0219terge folosind Bara de Unelte sau tasta Delete:
+ConfigView.tb.delete.content=\u0218terge f\u0103r\u0103 a cere confirmare
+ConfigView.tb.delete.torrent=\u0218terge doar din Arhiva Torentelor
+search.export.all=Export\u0103 Toate \u0218abloanele de C\u0103utare...
+subscriptions.search.enable=Activeaz\u0103 c\u0103utare de rezultate \u00een abonamente (e necesar\u0103 repornirea)
+devices.cancel_xcode_del=Anuleaz\u0103 Convertirea/\u00cenl\u0103turarea
+subscriptions.add.tooltip=Adaug\u0103 Abonament
+subscriptions.overview=Panorama Abonamentelor
+configureWizard.nat.title=Portul NAT / Server
+configureWizard.nat.message=Pentru folosirea optim\u0103 a softului Vuze , este recomandat s\u0103 ai calculatorul pe deplin accesibil dinspre internet. Aceast\u0103 unealt\u0103 \u00ee\u021bi permite s\u0103 testezi \u0219i/sau s\u0103 schimbi portul folosit pentru acceptarea conexiunilor intr\u00eende de la calculatoarele partenerilor.\n\nNOT\u0102: Aceast\u0103 unealt\u0103 testeaz\u0103 doar conexiunile TCP. Baza de Date Distribuit\u0103 [DHT] necesit\u0103 deasemenea conexiuni UDP i [...]
+configureWizard.nat.server.udp_listen_port=Port de Ascultare UDP Intr\u00eend
+v3.menu.device.defaultprofile.never=Nu Transcoda Niciodat\u0103
+subscriptions.info.avail=Nu ai ad\u0103ugat \u00eenc\u0103 nici un abonament. %1 s\u00eent disponibile pentru arhiva ta.
+subscriptions.dl_subs.enable=Descarc\u0103 abonamentele de la al\u021bi clien\u021bi la nevoie
+# Will be used for {library.name} in classic view
+library.name._classic=Arhiva Torentelor
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=Arhiva Torentelor
+ConfigView.section.style.units=Afi\u0219area Unit\u0103\u021bilor
+ConfigView.section.style.CatInSidebar=Arat\u0103 Categoriile \u00een Panoul Lateral
+library.category.header=Categoria '%1'
+device.import.title=Impor\u021bi Dispozitivul?
+device.import.desc=Sigur vrei s\u0103 impor\u021bi dispozitivul '%1'?
+device.import.dup.title=Duplicheaz\u0103 Dispozitivul
+device.import.dup.desc=Dispozitivul '%1' este deja prezent.
+stream.analysing.media=Analizez Media
+device.export.select.template.file=Export\u0103 Dispozitivul
+dlg.stream.plus.subtext=Te-ai s\u0103turat s\u0103 a\u0219tep\u021bi terminarea desc\u0103rc\u0103rii pentru a vedea filmul con\u021binut \u00een ea?  Vizioneaz\u0103 filmele chiar \u00een timp ce se descarc\u0103, folosind func\u021bia Red\u0103 Acum, o facilitate prezent\u0103 \u00een Vuze Plus care-\u021bi permite s\u0103 te ui\u021bi la filme pe m\u0103sur\u0103 ce se descarc\u0103.
+dlg.stream.plus.text=Supragradeaz\u0103 la Vuze Plus \u0219i vizioneaz\u0103 filmele pe m\u0103sur\u0103 ce se descarc\u0103.
+dlg.stream.plus.title=Supragradeaz\u0103
+dlg.stream.plus.subtitle=Supragradeaz\u0103
+Button.upgrade=Supragradeaz\u0103
+stream.analysing.media.preview=Analizez Media (Mod de Previzionare)
+# The remaining keys were not in MessagesBundle.properties
+v3.Share.add.buddy.existing=Prieteni Existen\u021bi:
+v3.buddy.prop.pks=Num\u0103r de chei publice
+MyTorrentsView.availability.info=Nr. copii complete descoperite
+MyTorrentsView.upspeed=\u00cenc\u0103rcare
+window.uiswitcher.AdvancedUI.title=Vuze Avansat
+v3.buddies.faq=Informa\u021bii Suplimentare
+MyTorrentsView.torrentpath=Locul Torentului
+login.optional.message=Trebuie s\u0103 fii autentificat pentru a utiliza aceast\u0103 facilitate
+TableColumn.header.videoLength=Lungimea Videoului
+v3.Share.wizard.title=Partajare -- Vr\u0103jitor
+azbuddy.ui.dialog.disable.title=Dezactiveaz\u0103 Extensia Prieteni
+v3.dialog.cnmanage.title=Administreaz\u0103 Meniul Re\u021belelor HD
+MyTorrentsView.trackername.info=Numele trackerului bazat pe adresa de anun\u021bare
+TableColumn.header.Info.info=Buton care lanseaz\u0103 pagina detaliat\u0103 a Con\u021binutului Vuze
+v3.Share.header.message=Partajeaz\u0103 cu prietenii existen\u021bi sau adaug\u0103 prieteni noi
+MyTorrentsView.done.info=Procentajul realizat din sarcina curent\u0103
+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.
+MyTorrentsView.swarm_average_speed=Viteza Medie a Roiului
+message.confirm.invite.error=Oof! Ni\u0219te s\u00eerme s-au \u00eencurcat la cererea asta. Una sau mai multe dintre invita\u021bii au erori.
+v3.activity.header.friend.requests.fromyou=Cereri de \u00cemprietenire - De la Tine
+MyTorrentsView.tracker=Tracker
+v3.MainWindow.menu.view.buddies-viewer=Bara Prietenilor
+v3.activity.header.rating.reminders=Memento al Not\u0103rii
+v3.activity.header.xdaysago=Acum %1 Zile
+MyTorrentsView.torrentpath.info=Locul torentului pe disc
+v3.MainWindow.myMedia.noneSelected=Ai %1 p\u0103r\u021bi din con\u021binut.\n%2 din ele s\u00eent complete.\n\nClicheaz\u0103 pe un r\u00eend pentru a vedea informa\u021bii despre con\u021binut
+MyTorrentsView.commenticon=Comentarii
+ConfigView.label.popup.suppress_alerts=Suprim\u0103 alertele
+ConfigView.label.popup.use_message_boxes=Folose\u0219te casete cu mesaje popup mai degrab\u0103 dec\u00eet casete de alertare obi\u0219nuite.
+v3.chat.wrongversion=%1 folose\u0219te o versiune de Vuze care nu suport\u0103 Taifasul [Chat].
+v3.buddy.menu.chat=Discut\u0103
+MyTorrentsView.bad_avail_time.info=Ultima dat\u0103 c\u00eend a fost disponibil\u0103 o copie complet\u0103 a desc\u0103rc\u0103rii
+v3.dialog.cnclose.noshow=Nu ar\u0103ta din nou
+MyTorrentsView.completion=Progres
+v3.Share.send.now=Trimite
+v3.Share.add.buddy.all=Partajeaz\u0103 cu to\u021bi
+v3.AddFriends.wizard.title=Adaug\u0103 Prieteni -- Vr\u0103jitor
+message.confirm.share.singular=Excelent!  Cererea ta de partajare a unui torent a fost trimis\u0103.
+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
+v3.Share.invite.buddies.prompt=Invit\u0103 mai mul\u021bi prieteni pentru partajare
+TableColumn.header.RateIt.info=Capacitatea de a nota con\u021binutul Vuze
+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
+v3.buddy.prop.catin=Categoriile prietenului la care te po\u021bi abona
+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
+Content.alert.notuploaded.multi.text=%1 din con\u021binutul publicat de tine nu s\u00eent donate complet. Dac\u0103 %2 acum, ceilal\u021bi nu vor putea s\u0103 descarce complet lucr\u0103rile pe care le-ai publicat. Sigur vrei s\u0103 %2?\n\nCon\u021binut care nu e donat complet:\n%3
+v3.buddies.online=Conecta\u021bi (%1)
+MyTorrentsView.AvgAvail.info=Suma p\u0103r\u021bilor disponibile divizat\u0103 prin nr. de p\u0103r\u021bi, divizat\u0103 prin nr. de conexiuni
+v3.HomeReminder.title=Desc\u0103rcare Ad\u0103ugat\u0103
+TableColumn.header.Quality.info=Calitatea con\u021binutului Vuze, cum ar fi HD, SD
+v3.MainWindow.menu.publish.about=Despre Publicare...
+MyTorrentsView.pieces.info=Bar\u0103 grafic\u0103 reprezent\u00eend p\u0103r\u021bile pe care le-ai desc\u0103rcat
+v3.buddies.remove=\u0218terge Prietenul
+MyTorrentsView.maxupspeed=Viteza Maxim\u0103 de \u00cenc\u0103rcare
+Content.alert.notuploaded.quit=p\u0103r\u0103se\u0219te Vuze
+v3.activity.header.today=Azi
+MyTorrentsView.availability=Disponibilitate
+Content.alert.notuploaded.button.stop=&Opre\u0219te
+MyTorrentsView.tracker.info=Starea Trackerului
+v3.buddies.dnd.info.dialog.remember=Nu ar\u0103ta din nou acest mesaj
+message.confirm.invite.singular=Excelent! Cererea de \u00eemprietenire a fost trimis\u0103.  Simte-te liber s\u0103-\u021bi constr\u00eengi cu ging\u0103\u0219ie prietenii s-o accepte.
+MyTorrentsView.comment.info=Comentariu f\u0103cut de utilizator pt. desc\u0103rcare
+v3.activity.header.friend.requests.accepted=Cereri de \u00cemprietenire - Acceptate
+MyTorrentsView.bad_avail_time=Copie Complet\u0103 V\u0103zut\u0103
+MyTorrentsView.date_added.menu.reset=Reseteaz\u0103 Data
+MyTorrentsView.peersources.info=Sursele partenerilor s\u00eent permise pentru stabilirea leg\u0103turilor cu ace\u0219tia
+ConfigView.section.file.confirm_data_delete=Cere confirmare la \u0219tergerea de file
+MyTorrentsView.completion.info=Reprezentarea grafic\u0103 a procentajului desc\u0103rcat
+ConfigView.section.style.verticaloffset=Decalarea vertical\u0103 a graficelor (repara\u021bie GTK)
+MyTorrentsView.timesinceupload.info=Timpul scurs de c\u00eend au fost \u00eenc\u0103rcate date din torent
+MyTorrentsView.date_completed=Terminat \u00cen
+TableColumn.header.Rating_global.info=Aprecierea global\u0103 pentru acest con\u021binut
+MyTorrentsView.size=M\u0103rime
+v3.buddy.prop.un=Utilizator
+v3.dialog.cnmanage.intro=Po\u021bi alege din lista de mai jos re\u021belele de con\u021binut care vrei s\u0103 fie afi\u0219ate \u00een meniul "Re\u021bele HD"
+MyTorrentsView.done=Progres
+MyTorrentsView.secondsseeding=Donez de
+v3.Share.optional.message=Mesaj op\u021bional trimis prin Fluxul de Activitate (maximum 140 de caractere):
+MyTorrentsView.AvgAvail=Medie/portiune
+message.confirm.share.invite.plural=Excelent!  Solicit\u0103rile tale de conectare \u0219i partajare au fost trimise.  Simte-te liber s\u0103 \u00ee\u021bi constr\u00eengi delicat prietenul s\u0103 le accepte.
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=Introdu un nume nou pentru aceast\u0103 desc\u0103rcare.
+MyTorrentsView.trackername=Numele Trackerului
+v3.buddies.disabled.text._mac=Ai dezactivat extensia pt. prieteni, ceea ce te va \u00eempiedica s\u0103 partajezi sau s\u0103 accep\u021bi torente ori cereri de a deveni prieten. Po\u021bi schimba setarea \u00een tabul op\u021biunilor.
+MainWindow.menu.help.beta=Versiune Beta...
+MyTorrentsView.down=Desc\u0103rcat
+message.confirm.invite.plural=Excelent! Solicit\u0103rile de \u00eemprietenire au fost trimise.  Simte-te liber s\u0103-\u021bi constr\u00eengi cu ging\u0103\u0219ie prietenii s\u0103 le accepte.
+MyTorrentsView.swarm_average_completion=Realizarea medie a partenerilor
+Tab.closeHint=(apas\u0103 "Esc" pentru \u00eenchidere)
+ConfigView.label.popup.show.button=Arat\u0103
+v3.buddies.dnd.info.dialog.ok=OK
+MyTorrentsView.peers.info=nr. de parteneri la care e\u0219ti conectat (nr. total de parteneri)
+v3.Share.invitees=Invit\u0103
+deletetorrent.message2=\nSigur vrei s\u0103 continui?
+deletetorrent.message1=E\u0219ti pe punctul de a \u0219terge TORENTUL lui :\n
+MyTorrentsView.menu.rename.save_path.enter.message=Introdu o cale nou\u0103 de salvare pentru aceast\u0103 desc\u0103rcare.
+v3.activity.header.xweeksago=Acum %1 S\u0103pt\u0103m\u00eeni
+MyTorrentsView.name=Nume
+MyTorrentsView.eta=Timp Estimat
+MyTorrentsView.swarm_average_speed.info=Viteza medie a partenerilor din roi
+MyTorrentsView.completed=Terminat
+ConfigView.section.interface.confirm_torrent_removal.tooltip=Confirmare la \u00eenl\u0103turarea unui torent din vederea "Torentele mele"
+MyTorrentsView.up=\u00cenc\u0103rcat
+Wizard.Subscription.optin.description.library=\u00cen Arhiva Torentelor, sau
+MyTorrentsView.secondsseeding.info=Durata de timp total\u0103 de la \u00eenceperea don\u0103rii.
+v3.activity.header.1weekago=Acum 1 S\u0103pt\u0103m\u00een\u0103
+v3.buddies.disabled.text._windows=Ai dezactivat extensia pt. prieteni, ceea ce te va \u00eempiedica s\u0103 partajezi sau s\u0103 accep\u021bi torente ori cereri de a deveni prieten. Po\u021bi schimba setarea \u00een tabul op\u021biunilor.
+MyTorrentsView.savepath=Calea de Salvare
+v3.buddy.set.catout=Permite prietenului s\u0103 se aboneze la categorie
+v3.MainWindow.menu.publish.new=Public\u0103 Con\u021binut Nou
+v3.activity.header.friend.requests.foryou=Cereri de \u00cemprietenire - Pentru Tine
+MyTorrentsView.networks.info=Re\u021bele permise pentru comunicarea de date cu partenerii
+v3.MainWindow.recentDL.library=Arhiva Torentelor >>
+v3.buddy.menu.remove=\u0218terge Prietenul
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=Renume\u0219te Desc\u0103rcarea
+MyTorrentsView.date_added.info=Data ad\u0103ug\u0103rii torentului
+message.confirm.share.plural=Excelent!  Solicit\u0103rile tale de partajare a unui torent au fost trimise.
+v3.buddies.add.to.share=Adaug\u0103 prietenul la partaj
+MyTorrentsView.downspeed=Desc\u0103rcare
+v3.activity.buddy-request.multi=Ai o cerere de \u00eemprietenire [#%3] de la %1\n\n<A HREF="%2" TARGET="minibrowse">ACCEPT\u0102</A>
+MyTorrentsView.remaining.info=R\u0103mas de desc\u0103rcat
+deletedata.message2=\nSigur vrei s\u0103 continui?
+deletedata.message1=Sigur vrei s\u0103 \u0219tergi filele desc\u0103rcate ale torentului: '%1'?
+Content.alert.notuploaded.multi.title=\u00cenc\u0103rc\u0103rile Nu S\u00eent Complete
+v3.activity.share-content.no-msg=%1 a partajat %2 cu tine
+v3.activity.buddy-request.accept=Accept\u0103
+Content.alert.notuploaded.text=\u00cenc\u0103rcarea lui '%1' nu este complet\u0103. Dac\u0103 vei %2 acum, lumea nu va putea s\u0103 descarce complet opera publicat\u0103 de tine.\n\nSigur vrei s\u0103 %2?
+window.uiswitcher.AdvancedUI.text=* Recomandat pentru utilizatorii care vor s\u0103 p\u0103streze aspectul interfe\u021bei clasice dar \u00een acela\u0219i timp vor s\u0103 caute, s\u0103 exploreze \u0219i s\u0103 publice con\u021binut pe platforma Vuze\n\n* Interfa\u021b\u0103 grafic\u0103 u\u0219oar\u0103 \u0219i intuitiv\u0103, asociat\u0103 cu facilit\u0103\u021bi \u0219i func\u021bionalitate mai avansat\u0103
+v3.MainWindow.button.sendtofriend=Partajeaz\u0103
+v3.MainWindow.button.newtag.share=Nou! Partajeaz\u0103 Torentul
+MyTorrentsView.seeds.fullcopycalc=%2 copii complete presupuse pentru %1 parteneri
+v3.dialog.cnclose.info1=Ai \u00eenchis o Re\u021bea HD
+v3.dialog.cnclose.info2=Dac\u0103 vrei s\u0103 redeschizi aceast\u0103 re\u021bea HD, o po\u021bi face \u00een meniul "Re\u021bele HD" din partea de sus a ecranului.
+MyTorrentsView.maxuploads=Nr. Max de \u00cenc\u0103rc\u0103ri
+v3.activity.share-content=%1 a partajat %2 cu tine\n\nMesaj de la %3:\n%4
+MyTorrentsView.peersources=Sursele Partenerilor
+MyTorrentsView.totalspeed.info=Viteza total\u0103 a tuturor partenerilor cu care e\u0219ti conectat
+MyTorrentsView.OnlyCDing4=Doar CDing4
+MainWindow.menu.community.add_friends=&Adaug\u0103 Prieteni
+v3.Share.header=Partajeaz\u0103
+MyTorrentsView.SeedingRank=Rang de Donare
+ConfigView.section.interface.display.add_torrents_silently.tooltip=Adaug\u0103 desc\u0103rc\u0103rile de torente f\u0103r\u0103 a activa fereastra principal\u0103 Vuze.
+v3.MainWindow.recentDL=Ultimele %1 Desc\u0103rc\u0103ri
+v3.dialog.cnclose.subtitle=Notificare
+MyTorrentsView.confirm_torrent_removal=Sigur vrei s\u0103 \u00eenl\u0103turi?\n
+MyTorrentsView.status.info=Ce face torentul
+message.intro.friends=Adaug\u0103 Prieteni.\nPartajeaz\u0103 Torente.\nDescarc\u0103 mai Rapid.
+MyTorrentsView.peers=Parteneri
+MyTorrentsView.maxdownspeed=Viteza Maxim\u0103 de Desc\u0103rcare
+v3.AddFriends.header.message=Adaug\u0103 prieteni pentru a \u00eencepe s\u0103 partajezi torentele favorite
+v3.Share.add.edit.buddy=Adaug\u0103/Editeaz\u0103 Prieteni
+v3.buddies.disabled.title=Extensia pt. Prieteni e Dezactivat\u0103
+ConfigView.section.security.vuze.login=Trebuie s\u0103 fii autentificat la Vuze pentru a realiza aceast\u0103 opera\u021biune
+MyTorrentsView.date_added=Dat\u0103 ad\u0103ugat\u0103
+MyTorrentsView.menu.removeand=\u0218&terge
+MyTorrentsView.priority=Prioritate
+ConfigView.section.style.useNewStyleMessageBox=Folose\u0219te stilul nou de caset\u0103 cu mesaje
+v3.AddFriends.header=Adaug\u0103 Prieteni
+ConfigView.section.interface.confirm_torrent_removal=Arat\u0103 un dialog de confirmare la \u00eenl\u0103turarea torentelor
+message.prompt.add.friends=Pentru a partaja clica\u021bi iconi\u021bele prietenilor de la partea de jos a paginii
+MyTorrentsView.status=Stare
+v3.Share.buddies=Prieteni
+v3.activity.buddy-request=Ai o cerere de \u00eemprietenire de la %1\n\n<A HREF="%2" TARGET="minibrowse">ACCEPT\u0102</A>
+MyTorrentsView.shareRatio=Raport de Partajare
+MyTorrentsView.menu.rename.save_path.enter.title=Renume\u0219te Calea de Salvare
+v3.buddies.remove.buddy.dialog.title=\u0218terge Confirmarea Prietenului
+window.uiswitcher.bottom.text=Alegerea ta poate fi modificat\u0103 din nou cu ajutorul butonului de selectare a interfe\u021bei Vuze
+message.confirm.share.invite.singular=Excelent!  Cererea ta de conectare \u0219i partajare a fost trimis\u0103.  Simte-te liber s\u0103 \u00ee\u021bi constr\u00eengi delicat prietenul s\u0103 o accepte.
+MyTorrentsView.health=S\u0103n\u0103tate
+Content.alert.notuploaded.title=\u00cenc\u0103rcarea nu e complet\u0103
+v3.dialog.cnclose.title=%1 \u00cenchis
+MyTorrentsView.maxdownspeed.info=Vit Max Desc per torent
+MyTorrentsView.filesdone=File Terminate
+ConfigView.interface.start.library=Porne\u0219te \u00een Arhiva Torentelor
+MyTorrentsView.seeds.info=# donatori conecta\u021bi la (# total donatori)
+webui.restart.info=Modific\u0103rile parametrilor marca\u021bi cu (*) au nevoie de repornirea softului pentru a fi activate
+MyTorrentsView.seed_to_peer_ratio.info=Raportul donatori/parteneri pe tot roiul
+v3.Share.add.buddy.new=Prieteni Noi:
+v3.MainWindow.menu.publish.mine=Con\u021binutul Publicat Deja
+v3.Share.add.buddy=Adaug\u0103 Prieteni
+MyTorrentsView.pieces=P\u0103r\u021bi
+v3.buddies.dnd.info.dialog.title=Partajare Direct\u0103
+ConfigView.section.file.confirm_data_delete.tooltip=Confirmare la \u0219tergere
+v3.Share.disclaimer.link=Informa\u021bii Suplimentare
+MyTorrentsView.maxupspeed.info=Vit Max \u00cenc per torent
+v3.buddy.prop.catout=Categoriile la care se poate abona prietenul t\u0103u
+MyTorrentsView.totalspeed=Viteza Total\u0103
+v3.activity.buddy-linkup=Tu \u0219i %1 s\u00eente\u021bi acum prieteni
+v3.buddies.count=%1 Prieteni
+v3.MainWindow.menu.view.buttonbar=Bara cu Butoane
+MyTorrentsView.remaining=R\u0103mas
+Wizard.Subscription.optin.description.sidebar=Abonamente \u00een Bara Lateral\u0103.
+Content.alert.notuploaded.button.continue=&Continu\u0103 Donarea
+v3.buddy.menu.viewprofile=Vezi Profilul
+v3.activity.buddy-invited.multi=Ai trimis o cerere de \u00eemprietenire urm\u0103toarelor persoane:\n%1
+Content.alert.notuploaded.stop=opre\u0219te
+v3.buddy.prop.dn=Nume Afi\u0219at
+v3.HomeReminder.gohome=Comut\u0103 la Tabloul de Bord
+v3.buddies.dnd.info.dialog.text=Ai ini\u021biat o Partajare Direct\u0103 [Drop Share]. Con\u021binutul este preparat pentru partajare, \u0219i ecranul de partajare va fi afi\u0219at \u00een momentul \u00een care con\u021binutul va fi gata.\n\nTrebuie s\u0103 men\u021bii Vuze deschis pentru ca Prietenul s\u0103 primeasc\u0103 con\u021binutul.\n<A HREF="http://faq.vuze.com/?View=entry&EntryID=267">Clicheaz\u0103 aici</A> pentru informa\u021bii suplimentare despre aceast\u0103 facilitate.
+MyTorrentsView.menu.rename.displayed_and_save_path=Renume\u0219te Ambele
+v3.HomeReminder.text='%1' a fost ad\u0103ugat\u0103 la lista de desc\u0103rcare.\n\nDac\u0103 vrei s\u0103 vezi progresul desc\u0103rc\u0103rii, sau s\u0103 redai fila dup\u0103 terminarea ei, clicheaz\u0103 pe tabul Tablou de Bord.
+MyTorrentsView.networks=Re\u021bele
+v3.activity.buddy-invited=Ai trimis o cerere de \u00eemprietenire c\u0103tre %1.
+MyTorrentsView.timesincedownload.info=Timpul scurs de c\u00eend au fost desc\u0103rcate date din torent
+v3.activity.header.yesterday=Ieri
+v3.buddy.set.catin=Aboneaz\u0103 la categoria prietenului
+azbuddy.ui.dialog.disable.text=Dezactivarea extensiei Prieteni te va \u00eempiedica s\u0103 partajezi torente cu ajutorul Barei de Prieteni de la partea de jos a aplica\u021biei \u0219i te va \u00eempiedica s\u0103 modifici lista de prieteni.\n\nSigur vrei s\u0103 dezactivezi extensia Prieteni?
+TableColumn.header.date_added.menu.reset=Reseteaz\u0103 Data
+MyTorrentsView.trackernextaccess=Urm\u0103toarea Accesare a Trackerului
+v3.buddy.prop.on=Conectat
+v3.library.infobar.text2=Folose\u0219te butonul "Vezi" din bara de unelte pentru a comuta \u00eentre cele dou\u0103 tipuri de interfa\u021b\u0103.
+v3.library.infobar.text1=Cau\u021bi Vederea Avansat\u0103?
+v3.buddy.prop.pc=Mesaje de taifas [chat] \u00een a\u0219teptare
+externalLogin.alt_method=Folose\u0219te metod\u0103 alternativ\u0103 de captur\u0103 a fursecului [cookie]  => alfa! de \u00eencercat doar dac\u0103 metoda obi\u0219nuit\u0103 nu func\u021bioneaz\u0103
+MyTorrentsView.secondsdownloading=Descarc de
+MyTorrentsView.seeds=Donatori
+v3.buddies.remove.buddy.dialog.text=Sigur vrei s\u0103 \u0219tergi prietenul %1 ?
+MyTorrentsView.filesdone.info=File Terminate/File Totale *sau* File Nes\u0103rite Terminate (File Terminate)/File Nes\u0103rite Totale (File Totale)
+v3.activity.header.share.requests=Partajeaz\u0103 Solicit\u0103rile de Torente
+ConfigView.section.interface.display.add_torrents_silently=Adaug\u0103 torentele \u00een mod silen\u021bios
+TableColumn.header.videoLength.info=Durata de redare a con\u021binutului video Vuze
+MyTorrentsView.secondsdownloading.info=Durata de timp de la \u00eenceperea desc\u0103rc\u0103rii.
+v3.Share.menu=Partajeaz\u0103 Con\u021binutul
+xmlhttp.legacy.error=Aceast\u0103 versiune a extensiei XML/HTTP nu mai func\u021bioneaz\u0103 cu Vuze - trebuie s-o actualizezi la o versiune mai nou\u0103.
+v3.buddy.prop.lupd=Ultima Actualizare
+v3.chat.offline=%1 e momentan neconectat \u0219i va primi mesajul t\u0103u c\u00eend se va reconecta.
+ConfigView.label.popup.show=Arat\u0103 toate alertele popup \u00eenregistrate p\u00een\u0103 acum (dac\u0103 exist\u0103)
+MyTorrentsView.priority.info=Determin\u0103 banda ascendent\u0103 (de \u00eenc\u0103rcare) oferit\u0103 torentului
+TableColumn.header.Rating_global=Apreciere
+v3.MainWindow.button.share=Partajeaz\u0103 Con\u021binutul
+v3.buddies.friends=Prieteni
+MyTorrentsView.commenticon.info=Arat\u0103 iconi\u021ba dac\u0103 desc\u0103rcarea are comentarii f\u0103cute de utilizatori
+MyTorrentsView.timesincedownload=Desc\u0103rcare Inactiv\u0103 de
+MyTorrentsView.swarm_average_completion.info=Media progresului la partenerii din roi
+v3.Share.disclaimer=Not\u0103: At\u00eet con\u021binutul pe care \u00eel partajezi, c\u00eet \u0219i acest mesaj op\u021bional vor fi criptate.
diff --git a/org/gudy/azureus2/internat/MessagesBundle_ru_RU.properties b/org/gudy/azureus2/internat/MessagesBundle_ru_RU.properties
index aeb5fd0..7e93aee 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_ru_RU.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_ru_RU.properties
@@ -1,731 +1,732 @@
-#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\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b...
-Main.parameter.usage=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435: java org.gudy.azureus2.cl.Main [\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b] "\u0444\u0430\u0439\u043b.torrent" "\u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f"
-Main.parameter.maxUploads=\u041c\u0430\u043a\u0441. \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0430\u0447
-Main.parameter.maxSpeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u0411/\u0441
+#There is a plugin to help with internationalizing these bundles at http://plugins.vuze.com/plugin_list.php
+MainWindow.menu.file.open.torrent=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 \u0424\u0430\u0439\u043b...
+Main.parameter.usage=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 : java org.gudy.azureus2.cl.Main [\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b] "\u0444\u0430\u0439\u043b.torrent" "\u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f"
+Main.parameter.maxUploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435  \u043a\u043e\u043b-\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0430\u0447
+Main.parameter.maxSpeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447 \u0431\u0430\u0439\u0442/\u0441\u0435\u043a
 MainWindow.menu.file=&\u0424\u0430\u0439\u043b
-MainWindow.menu.file.open=&\u041e\u0442\u043a\u0440\u044b\u0442\u044c
-MainWindow.menu.file.create=&\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442...
+MainWindow.menu.file.open=\u041e\u0442\u043a\u0440\u044b\u0442\u044c
+MainWindow.menu.file.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 MainWindow.menu.file.create.fromfile=\u0438\u0437 &\u0444\u0430\u0439\u043b\u0430
-MainWindow.menu.file.create.fromdir=\u0418\u0437 &\u043f\u0430\u043f\u043a\u0438
-MainWindow.menu.file.export=&\u042d\u043a\u0441\u043f\u043e\u0440\u0442 XML \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430...
-MainWindow.menu.file.import=\u0418\u043c\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-MainWindow.menu.file.closetab=\u0417\u0430\u043a\u0440\u044b\u0442\u044c &\u0432\u043a\u043b\u0430\u0434\u043a\u0443
-MainWindow.menu.file.closewindow=\u0417\u0430\u043a\u0440\u044b\u0442\u044c &\u043e\u043a\u043d\u043e
-MainWindow.menu.file.exit=\u0412&\u044b\u0445\u043e\u0434
+MainWindow.menu.file.create.fromdir=\u0438\u0437 &\u043f\u0430\u043f\u043a\u0438
+MainWindow.menu.file.export=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 XML-\u0442\u043e\u0440\u0440\u0435\u043d\u0442 ...
+MainWindow.menu.file.import=\u0418\u043c\u043f\u043e\u0440\u0442 \u0438\u0437 XML-\u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 ...
+MainWindow.menu.file.closetab=&\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u0432\u043a\u043b\u0430\u0434\u043a\u0443
+MainWindow.menu.file.closewindow=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u043e\u043a\u043d\u043e
+MainWindow.menu.file.exit=\u0412\u044b\u0439\u0442\u0438
 MainWindow.dialog.choose.file=\u0412\u044b\u0431\u043e\u0440 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 MainWindow.menu.file.folder=\u041f\u0430\u043f\u043a\u0430
 MainWindow.dialog.choose.folder=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438
 MainWindow.menu.view=&\u0412\u0438\u0434
 MainWindow.menu.view.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
-MainWindow.menu.view.mytorrents=&\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-MainWindow.menu.view.open_global_transfer_bar=\u0421\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+MainWindow.menu.view.mytorrents=\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+MainWindow.menu.view.open_global_transfer_bar=\u041f\u0430\u043d\u0435\u043b\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430
 MainWindow.menu.view.configuration=&\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438...
-MainWindow.menu.view.console=&\u041a\u043e\u043d\u0441\u043e\u043b\u044c
-MainWindow.menu.view.allpeers=\u0412\u0441\u0435 \u0443\u0437\u043b\u044b
-MainWindow.menu.view.detailedlist=&\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
-MainWindow.menu.closealldetails=\u0417\u0430\u043a\u0440\u044b\u0442\u044c &\u0432\u0441\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-MainWindow.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u0432\u0441\u0435 \u0441&\u043a\u0440\u0438\u043d\u043b\u0435\u0442\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+MainWindow.menu.view.console=\u041a\u043e\u043d&\u0441\u043e\u043b\u044c
+MainWindow.menu.view.allpeers=\u0412\u0441\u0435 \u043f\u0438\u0440\u044b
+MainWindow.menu.view.detailedlist=&\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+MainWindow.menu.closealldetails=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+MainWindow.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u043a\u0430\u0447\u0435\u043a
 MainWindow.menu.language=&\u042f\u0437\u044b\u043a
 ConfigView.section.language=\u042f\u0437\u044b\u043a
 MainWindow.menu.window=&\u041e\u043a\u043d\u043e
 MainWindow.menu.window.minimize=&\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c
 MainWindow.menu.window.zoom=&\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c
-MainWindow.menu.window.alltofront=&\u041f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445 \u043e\u043a\u043e\u043d
-MainWindow.menu.help=&\u0421\u043f\u0440\u0430\u0432\u043a\u0430
-MainWindow.menu.help.about=\u041e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 Vuze
-MainWindow.menu.torrent=\u0422\u043e&\u0440\u0440\u0435\u043d\u0442
+MainWindow.menu.window.alltofront=\u041f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445
+MainWindow.menu.help=&\u041f\u043e\u043c\u043e\u0449\u044c
+MainWindow.menu.help.about=\u041e Vuze...  / "\u041f\u0420\u0410\u0412\u0418\u041b\u042c\u041d\u042b\u0419" \u043c\u0435\u0442\u0430-\u043f\u0435\u0440\u0435\u0432\u043e\u0434, ver.2.0.9; (\u0441)2011 GamBIT/
+MainWindow.menu.torrent=\u0422&\u043e\u0440\u0440\u0435\u043d\u0442
 MainWindow.about.title=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
-MainWindow.about.section.developers=\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438
-MainWindow.about.section.translators=\u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0438
 MainWindow.about.section.system=\u0421\u0438\u0441\u0442\u0435\u043c\u0430
 MainWindow.about.section.internet=\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442
-MainWindow.about.internet.homepage=\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 Vuze
-MainWindow.about.internet.sourceforge=\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Sourceforge
-MainWindow.about.internet.sourceforgedownloads=\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0441 Sourceforge
+MainWindow.about.internet.homepage=\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 Vuze
+MainWindow.about.internet.sourceforge=\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Sourceforge
 MainWindow.about.internet.bugreports=\u0421\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043e \u043e\u0448\u0438\u0431\u043a\u0435
-MainWindow.about.internet.forumdiscussion=\u041e\u0431\u0449\u0438\u0439 \u0444\u043e\u0440\u0443\u043c
-MainWindow.about.internet.wiki=\u0427\u0430\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0412\u0438\u043a\u0438 Vuze
+MainWindow.about.internet.forumdiscussion=\u041e\u0431\u0449\u0438\u0439 \u0424\u043e\u0440\u0443\u043c
+MainWindow.about.internet.wiki=Wiki - \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0441 \u0427\u0430\u0412\u043e \u043e Vuze
 MainWindow.dialog.choose.savepath=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
 MainWindow.dialog.choose.savepath_forallfiles=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u0431\u0449\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
 MainWindow.status.latestversion=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0432\u0435\u0440\u0441\u0438\u044f
-MainWindow.status.latestversion.clickupdate=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
+MainWindow.status.latestversion.clickupdate=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
 MainWindow.status.unknown=\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e
 MainWindow.status.checking=\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
 MyTorrentsView.mytorrents=M\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-TableColumn.header.name=\u0418\u043c\u044f
+TableColumn.header.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 TableColumn.header.size=\u0420\u0430\u0437\u043c\u0435\u0440
-TableColumn.header.done=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-TableColumn.header.done.info=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438
-TableColumn.header.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
-TableColumn.header.status.info=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442
-TableColumn.header.seeds=\u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
-TableColumn.header.seeds.info=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u043c (\u043e\u0431\u0449\u0435\u0435 \u0447\u0438\u0441\u043b\u043e \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445)
-TableColumn.header.peers=\u0423\u0437\u043b\u043e\u0432
-TableColumn.header.peers.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u0432 (\u0438\u0445 \u043e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e)
+TableColumn.header.done=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e
+TableColumn.header.done.info=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f
+TableColumn.header.status=\u0421\u0442\u0430\u0442\u0443\u0441
+TableColumn.header.status.info=\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+TableColumn.header.seeds=\u0421\u0438\u0434\u044b
+TableColumn.header.seeds.info=\u041a\u043e\u043b. \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0434\u043e\u0432 (\u041a\u043e\u043b. \u0432\u0441\u0435\u0433\u043e \u0441\u0438\u0434\u043e\u0432)
+TableColumn.header.peers=\u041b\u0438\u0447\u0435\u0440\u044b
+TableColumn.header.peers.info=\u041a\u043e\u043b. \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u043b\u0438\u0447\u0435\u0440\u043e\u0432 (\u041a\u043e\u043b. \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0447\u0435\u0440\u043e\u0432)
 TableColumn.header.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-TableColumn.header.completed.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432, \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0432\u0448\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043f\u043e \u0434\u0430\u043d\u043d\u044b\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-TableColumn.header.downspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
+TableColumn.header.completed.info=\u041a\u043e\u043b. \u043f\u0438\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u0442\u0440\u0435\u043a\u0435\u0440
+TableColumn.header.downspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 TableColumn.header.upspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 TableColumn.header.eta=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c
-TableColumn.header.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
-TableColumn.header.tracker.info=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-TableColumn.header.trackernextaccess=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
-TableColumn.header.trackernextaccess.info=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+TableColumn.header.tracker=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+TableColumn.header.tracker.info=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+TableColumn.header.trackernextaccess=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0430\u043d\u0441 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
+TableColumn.header.trackernextaccess.info=\u041a\u043e\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0430\u043d\u0441 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442
 TableColumn.header.priority=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-TableColumn.header.priority.info=\u0427\u0430\u0441\u0442\u044c \u043f\u043e\u043b\u043e\u0441\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.seeds.fullcopycalc=%2 \u043f\u043e\u043b\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0443 %1 \u0443\u0437\u043b\u043e\u0432
+TableColumn.header.priority.info=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u043e\u0441\u044b \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443
+TableColumn.header.seeds.fullcopycalc=%2 \u043f\u043e\u043b\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 %1 \u043f\u0438\u0440\u043e\u0432
 MyTorrentsView.menu.showdetails=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430
-MyTorrentsView.menu.showdownloadbar=\u0421&\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-MyTorrentsView.menu.open=&\u041e\u0442\u043a\u0440\u044b\u0442\u044c
-MyTorrentsView.menu.setpriority=\u0417\u0430\u0434\u0430\u0442\u044c &\u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+MyTorrentsView.menu.showdownloadbar=\u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+MyTorrentsView.menu.open=\u041e\u0442\u043a\u0440\u044b\u0442\u044c
+MyTorrentsView.menu.setpriority=\u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
 MyTorrentsView.menu.setpriority.high=&\u0412\u044b\u0441\u043e\u043a\u0438\u0439
-MyTorrentsView.menu.setpriority.low=&\u041d\u0438\u0437\u043a\u0438\u0439
-MyTorrentsView.menu.start=&\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-MyTorrentsView.menu.stop=\u041e&\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-MyTorrentsView.menu.remove=&\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-MyTorrentsView.menu.changeTracker=&\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+MyTorrentsView.menu.setpriority.low=&\u043d\u0438\u0437\u043a\u0438\u0439
+MyTorrentsView.menu.start=\u043d\u0430\u0447\u0430\u0442\u044c
+MyTorrentsView.menu.stop=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+MyTorrentsView.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+MyTorrentsView.menu.changeTracker=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 TrayWindow.menu.exit=\u0412\u044b\u0439\u0442\u0438
-TrayWindow.menu.show=&\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c Vuze
-SystemTray.menu.exit=\u0412&\u044b\u0445\u043e\u0434
-SystemTray.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u044b\u0442\u044c &\u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-SystemTray.menu.open_global_transfer_bar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043e\u043a\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-SystemTray.menu.show=&\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c Vuze
-PeersView.ip.info=IP \u0443\u0437\u043b\u0430
+TrayWindow.menu.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+SystemTray.menu.exit=\u0412\u044b\u0439\u0442\u0438
+SystemTray.menu.closealldownloadbars=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u043a\u0430\u0447\u0435\u043a
+SystemTray.menu.open_global_transfer_bar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 Vuze
+SystemTray.menu.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+PeersView.ip=IP-\u0430\u0434\u0440\u0435\u0441
+PeersView.ip.info=IP-\u0430\u0434\u0440\u0435\u0441 \u043f\u0438\u0440\u0430
 PeersView.port=\u041f\u043e\u0440\u0442
-PeersView.port.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u043e\u0440\u0442 
-PeersView.T=\u0422
-PeersView.T.info=L (local): \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, R (remote): \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0443\u0437\u043b\u0430.
-PeersView.T.L.tooltip=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435
-PeersView.T.R.tooltip=\u0412\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435
-PeersView.I1=\u0418 (\u044f \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d)
-PeersView.I1.info=\u042f \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0443 \u0443\u0437\u043b\u0430
-PeersView.C1=C (\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c)
-PeersView.C1.info=\u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441 \u0432\u0430\u0448\u0435\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b
+PeersView.port.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0438\u0440\u043e\u043c \u043f\u043e\u0440\u0442\n(\u043f\u043e\u0440\u0442 \u043d\u0430 \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435)
+PeersView.T=\u0418\u043d\u0438\u0446\u0438\u0430\u0442\u043e\u0440
+PeersView.T.info=\u0418\u043d\u0438\u0446\u0438\u0430\u0442\u043e\u0440 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f:\n[L]  (local):      \u0412\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\n[R]  (remote): \u041f\u0438\u0440 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435
+PeersView.T.L.tooltip=\u0412\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435
+PeersView.T.R.tooltip=\u041f\u0438\u0440 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435
+PeersView.I1=\u042f \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d
+PeersView.I1.info=[*] \u0435\u0441\u043b\u0438 \u0412\u044b \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u044b \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u0438\u0440
+PeersView.C1=\u041f\u0438\u0440 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442
+PeersView.C1.info=[*] \u0435\u0441\u043b\u0438 \u043f\u0438\u0440 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u043b \u0412\u0430\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441 \u043d\u0435\u0433\u043e
 PeersView.pieces=\u0427\u0430\u0441\u0442\u0438
-PeersView.downloadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-PeersView.download=\u041f\u0440\u0438\u043d\u044f\u0442\u043e
-PeersView.I2=\u0418 (\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u0443\u0437\u043b\u0443)
-PeersView.I2.info=\u0423\u0437\u0435\u043b \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0443 \u043c\u0435\u043d\u044f
-PeersView.C2=C (\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d)
-PeersView.C2.info=\u0423\u0437\u043b\u0443 \u0431\u044b\u043b\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435
+PeersView.downloadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+PeersView.download=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+PeersView.download.info=\u0412\u0430\u0448\u0430 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441 \u043f\u0438\u0440\u0430
+PeersView.I2=\u041f\u0438\u0440 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d
+PeersView.I2.info=[*] \u0435\u0441\u043b\u0438 \u043f\u0438\u0440 \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u043c\u0435\u0435\u0442\u0435 \u0412\u044b
+PeersView.C2=\u042f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e
+PeersView.C2.info=[*] \u0435\u0441\u043b\u0438 \u0412\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0435 \u043f\u0438\u0440\u0430 \u043e\u0442 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 PeersView.uploadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-PeersView.uploadspeed.info=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u0437\u043b\u0443
-PeersView.upload=\u0420\u043e\u0437\u0434\u0430\u043d\u043e
-PeersView.upload.info=\u0412\u0430\u043c\u0438 \u0440\u043e\u0437\u0434\u0430\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e.
+PeersView.uploadspeed.info=\u0412\u0430\u0448\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+PeersView.upload=\u041e\u0442\u0434\u0430\u043d\u043e
+PeersView.upload.info=\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435\u0433\u043e \u0412\u0430\u043c\u0438 \u0440\u043e\u0437\u0434\u0430\u043d\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u0440\u0443
 PeersView.statup=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-PeersView.statup.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u0437\u043b\u0430
-PeersView.S=\u0411
-PeersView.S.info=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0451\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 (\u0437\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043d\u0430 \u0441\u043b\u0438\u0448 [...]
-PeersView.downloadspeedoverall=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-PeersView.optunchoke=\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-PeersView.client=\u041a\u043b\u0438\u0435\u043d\u0442
-PeersView.client.info=\u0422\u0438\u043f BitTorrent-\u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0443\u0437\u043b\u043e\u043c
+PeersView.statup.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u0438\u0440\u0430
+PeersView.S=\u041f\u0440\u0438\u0442\u043e\u0440\u043c\u043e\u0436\u0435\u043d
+PeersView.S.info=[*] \u0435\u0441\u043b\u0438 \u043f\u0438\u0440 "\u043f\u0440\u0438\u0442\u043e\u0440\u043c\u043e\u0436\u0435\u043d" \u0412\u0430\u043c\u0438\n\n\u041f\u0438\u0440 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c "\u043f\u0440\u0438\u0442\u043e\u0440\u043c\u043e\u0436\u0435\u043d" \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438\n\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 (\u0437\u0430 \u043e\u0442\u0434\u0430\u0447 [...]
+PeersView.downloadspeedoverall=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+PeersView.optunchoke=\u041e\u043f\u0442\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d
+PeersView.client=\u0412\u0422-\u041a\u043b\u0438\u0435\u043d\u0442
+PeersView.client.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u043f\u0438\u0440\u043e\u043c BT-\u043a\u043b\u0438\u0435\u043d\u0442\u0430
 PeersView.menu.snubbed=\u041f\u043e\u043c\u0435\u0447\u0435\u043d 
-PeersView.title.short=\u0423\u0437\u043b\u044b
-PeersView.title.full=\u0423\u0437\u043b\u044b
-AllPeersView.title.full=\u0412\u0441\u0435 \u0443\u0437\u043b\u044b
-ConfigView.section.files=\u0424\u0430\u0439\u043b\u044b
-ConfigView.label.usefastresume=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u00ab\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f\u00bb
-ConfigView.label.incrementalfile=\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f FAT32 \u0432 Linux]
+PeersView.title.short=\u041f\u0438\u0440\u044b
+PeersView.title.full=\u041f\u0438\u0440\u044b
+AllPeersView.title.full=\u0412\u0441\u0435 \u043f\u0438\u0440\u044b
+ConfigView.section.files=\u0424\u0430\u0439\u043b\u044b (\u043f\u0443\u0442\u0438, \u0434\u0438\u0441\u043a\u0438, \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435)
+ConfigView.label.usefastresume=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c "\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f"
+ConfigView.label.incrementalfile=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 (\u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u044e\u0449\u0435\u0435 \u0432 \u0440\u0430\u0437\u043c\u0435\u0440\u0435) \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f FAT32 \u043f\u043e\u0434 Linux)
 ConfigView.label.defaultsavepath=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435
-ConfigView.button.browse=&\u041e\u0431\u0437\u043e\u0440...
+ConfigView.button.browse=\u041e\u0431\u0437\u043e\u0440...
 ConfigView.dialog.choosedefaultsavepath=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432
-ConfigView.section.server=\u0421\u0435\u0440\u0432\u0435\u0440
+ConfigView.section.server=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 (\u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0438 \u043a\u0440\u0438\u043f\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438)
 ConfigView.section.global=\u041e\u0431\u0449\u0435\u0435
-ConfigView.label.disconnetseed=\u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+ConfigView.label.disconnetseed=\u041e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0441\u0438\u0434\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 ConfigView.label.switchpriority=\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.maxdownloads=\u041c\u0430\u043a\u0441. \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n - \u041d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0430\u043a\u04 [...]
-ConfigView.label.maxdownloads.tooltip=\u0412\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c.\n\u0421\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0 [...]
-ConfigView.label.maxactivetorrents=\u041c\u0430\u043a\u0441. \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]\n - \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u043b\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u043d\u0430\u0447\u043d\u0451\u04 [...]
-ConfigView.label.priorityExtensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0432\u044b\u0441\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \n (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u00ab.jpg;.txt;.nfo\u00bb)
-ConfigView.section.transfer=\u041e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438
-ConfigView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.maxuploadspeed=\u041a\u0411/\u0441 \u043c\u0430\u043a\u0441. \u043e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.label.saveresumeinterval=\u0417\u0430\u043f\u0438\u0441\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u00ab\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f\u00bb \u043a\u0430\u0436\u0434\u044b\u0435
-ConfigView.unlimited=\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f
+ConfigView.label.maxdownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043a\u0430\u0447\u0435\u043a [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]\n  (\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u043 [...]
+ConfigView.label.maxdownloads.tooltip=\u0412\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u043d\u043e \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c.\n\u0421\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u [...]
+ConfigView.label.maxactivetorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]\n  (\u043d\u043e\u0432\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043 [...]
+ConfigView.label.priorityExtensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0432\u044b\u0441\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 (\u043d\u0430\u043f\u0440.: .jpg)
+ConfigView.section.transfer=\u041f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 (\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0441\u043b\u043e\u0442\u044b)
+ConfigView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u043b\u043e\u0442\u043e\u0432 (\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439) \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438  (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430)
+ConfigView.label.maxuploadspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 Vuze, \u0432 \u041a\u0411/\u0441 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ConfigView.label.saveresumeinterval=\u0417\u0430\u043f\u0438\u0441\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f "\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f" \u043a\u0430\u0436\u0434\u044b\u0435
+ConfigView.unlimited=\u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e
 ConfigView.section.display=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u0432\u0438\u0434
-ConfigView.label.opendetails=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u0441 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u043c\u0438
-ConfigView.label.openbar=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
-ConfigView.label.use_old_speed_menus=\u041f\u0440\u0435\u0436\u043d\u0438\u0439 \u0434\u0438\u0437\u0430\u0439\u043d \u043c\u0435\u043d\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
-ConfigView.label.closetotray=\u041f\u0440\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439
-ConfigView.label.minimizetotray=\u0421\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439
+ConfigView.label.opendetails=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443 \u0441 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0435
+ConfigView.label.openbar=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
+ConfigView.label.use_old_speed_menus=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u043d\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0432 \u0441\u0442\u0430\u0440\u043e\u043c \u0441\u0442\u0438\u043b\u0435 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+ConfigView.label.closetotray='\u0417\u0430\u043a\u0440\u044b\u0442\u044c' \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0432 \u0422\u0440\u0435\u0439
+ConfigView.label.minimizetotray='\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c' \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0432 \u0422\u0440\u0435\u0439
 ConfigView.section.general=\u041e\u0431\u0449\u0435\u0435
 ConfigView.section.start=\u0417\u0430\u043f\u0443\u0441\u043a
-ConfigView.label.showsplash=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u043a\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
+ConfigView.label.showsplash=\u041f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u0430\u0441\u0442\u0430\u0432\u043a\u0443
 ConfigView.label.autoupdate=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
-ConfigView.label.openconsole=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.label.openconfig=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.label.startminimized=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432 \u0441\u0432\u0451\u0440\u043d\u0443\u0442\u043e\u043c \u0432\u0438\u0434\u0435
-ConfigView.label.ircwiki=\u041e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043d\u0430 http://www.azureuswiki.com/index.php/Rules_for_IRC
+ConfigView.label.openconsole=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435
+ConfigView.label.openconfig=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435
+ConfigView.label.startminimized=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u043e\u043c \u043e\u043a\u043d\u0435
+ConfigView.section.irc=IRC-\u0421\u0435\u0442\u044c
+ConfigView.label.ircwiki=\u041f\u0440\u043e\u0447\u0442\u0438\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 http://azureus.aelitis.com/wiki/index.php/Rules_for_IRC
 ConfigView.label.ircserver=\u0421\u0435\u0440\u0432\u0435\u0440
 ConfigView.label.ircchannel=\u041a\u043e\u043c\u043d\u0430\u0442\u0430
-ConfigView.label.irclogin=\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c
+ConfigView.label.irclogin=\u041d\u0438\u043a
 ConfigView.group.irctitle=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 IRC
-ConfigView.boolean.ircsendinfo=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Vuze (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e),\n\u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043c\u043e\u0433\u043b\u0438 \u0432\u0430\u043c \u043f\u043e\u043c\u043e\u0447\u044c
-ConfigView.boolean.irclog=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 IRC (\u0432 \u0444\u0430\u0439\u043b IRC_log.htm)
-ConfigView.section.security=\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c
-ConfigView.label.password=\u0417\u0430\u0449\u0438\u0442\u0438\u0442\u044c Vuze \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0430\u0440\u043e\u043b\u044f\n\u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438\u043b\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u043a\u043d\u0430 \u0438\u0437 \u0437\u043d\u0430\u0447\u0 [...]
-ConfigView.label.passwordconfirm=\u041f\u0430\u0440\u043e\u043b\u044c (\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435)
-ConfigView.label.passwordmatch=\u041f\u0430\u0440\u043e\u043b\u044c \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d:
+ConfigView.boolean.ircsendinfo=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432\u0430\u0448\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \n \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u044b \u043a\u0430\u043d\u043 [...]
+ConfigView.boolean.irclog=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 IRC ( \u0432 \u0444\u0430\u0439\u043b IRC_log.htm)
+ConfigView.section.security=\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c (\u043f\u0430\u0440\u043e\u043b\u0438)
+ConfigView.label.password=\u041f\u0430\u0440\u043e\u043b\u044c\n(\u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0438 \u0438\u0437 \u0437\u043d\u0430\u0447\u043a\u0430)
+ConfigView.label.passwordconfirm=\u041f\u0430\u0440\u043e\u043b\u044c (\u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437)
+ConfigView.label.passwordmatch=\u041f\u0430\u0440\u043e\u043b\u044c \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d :
 ConfigView.label.passwordmatchnone=\u041d\u0435\u0442
-ConfigView.label.passwordmatchno=\u041d\u0435\u0442 / \u043f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442
+ConfigView.label.passwordmatchno=\u041d\u0435\u0442 / \u041f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442
 ConfigView.label.passwordmatchyes=\u0414\u0430
 ConfigView.button.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
 ConfigView.title.short=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 ConfigView.title.full=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
-ConfigView.title.full._mac=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b
+ConfigView.title.full._mac=\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u044f
 ConsoleView.title.short=\u041a\u043e\u043d\u0441\u043e\u043b\u044c
 ConsoleView.title.full=\u041a\u043e\u043d\u0441\u043e\u043b\u044c
 FileItem.write=\u0437\u0430\u043f\u0438\u0441\u044c
 FileItem.read=\u0447\u0442\u0435\u043d\u0438\u0435
-FileItem.normal=\u0421\u0440\u0435\u0434\u043d\u0438\u0439
+FileItem.normal=\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439
 FileItem.high=\u0412\u044b\u0441\u043e\u043a\u0438\u0439
-FileItem.donotdownload=\u041d\u0435 \u0433\u0440\u0443\u0437\u0438\u0442\u044c
-FileItem.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-FilesView.name=\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
+FileItem.donotdownload=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c
+FileItem.delete=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+FilesView.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 FilesView.name.fastRename=\u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435
 FilesView.size=\u0420\u0430\u0437\u043c\u0435\u0440
-FilesView.done=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-FilesView.firstpiece=\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c
-FilesView.numberofpieces=\u0427\u0430\u0441\u0442\u0435\u0439
+FilesView.done=\u0413\u043e\u0442\u043e\u0432\u043e
+FilesView.firstpiece=\u2116 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438
+FilesView.numberofpieces=\u041a\u043e\u043b. \u0447\u0430\u0441\u0442\u0435\u0439
 FilesView.pieces=\u0427\u0430\u0441\u0442\u0438
 FilesView.mode=\u0420\u0435\u0436\u0438\u043c
-FilesView.priority=\u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+FilesView.priority=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
 FilesView.menu.open=&\u041e\u0442\u043a\u0440\u044b\u0442\u044c
 FilesView.menu.setpriority=\u0417\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
 FilesView.menu.setpriority.high=&\u0412\u044b\u0441\u043e\u043a\u0438\u0439
-FilesView.menu.setpriority.normal=&\u0421\u0440\u0435\u0434\u043d\u0438\u0439
+FilesView.menu.setpriority.normal=&\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439
 FilesView.menu.setpriority.skipped=&\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c
 FilesView.title.short=\u0424\u0430\u0439\u043b\u044b
 FilesView.title.full=\u0424\u0430\u0439\u043b\u044b
 GeneralView.section.downloaded=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
-GeneralView.label.status.file=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430
-GeneralView.label.status.pieces=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0435\u0439
-GeneralView.section.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
-GeneralView.label.status.pieces_available=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0435\u0439
-GeneralView.section.transfer=\u041e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438
+GeneralView.label.status.file=\u0421\u0442\u0430\u0442\u0443\u0441 \u0444\u0430\u0439\u043b\u0430
+GeneralView.label.status.pieces=\u0421\u0442\u0430\u0442\u0443\u0441 \u0447\u0430\u0441\u0442\u0435\u0439
+GeneralView.section.availability=\u0420\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0441\u0442\u044c
+GeneralView.label.status.pieces_available=\u0421\u0442\u0430\u0442\u0443\u0441 \u0447\u0430\u0441\u0442\u0435\u0439
+GeneralView.section.transfer=\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430
 GeneralView.section.info=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
 GeneralView.title.short=\u041e\u0431\u0449\u0435\u0435
 GeneralView.title.full=\u041e\u0431\u0449\u0435\u0435
-GeneralView.label.timeelapsed=\u041f\u0440\u043e\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438: 
+GeneralView.label.timeelapsed=\u041f\u0440\u043e\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 : 
 GeneralView.label.remaining=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c: 
-GeneralView.label.downloaded=\u041f\u0440\u0438\u043d\u044f\u0442\u043e:
-GeneralView.label.downloadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430:
-GeneralView.label.maxuploads=\u0421\u043b\u043e\u0442\u044b \u0440\u0430\u0437\u0434\u0430\u0447\u0438: 
-GeneralView.label.maxuploads.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.
-GeneralView.label.uploaded=\u0420\u043e\u0437\u0434\u0430\u043d\u043e: 
-GeneralView.label.uploadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438: 
-GeneralView.label.seeds=\u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445: 
-GeneralView.label.peers=\u0423\u0437\u043b\u043e\u0432:
-GeneralView.label.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e: 
-GeneralView.label.totalspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f: 
-GeneralView.label.totalspeed.tooltip=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f (\u0438 \u0441\u0440\u0435\u0434\u043d\u044f\u044f) \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u044b\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.
-GeneralView.label.averagespeed=\u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c
-GeneralView.label.filename=\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430:
-GeneralView.label.totalsize=\u041e\u0431\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440: 
-GeneralView.label.savein=\u0421\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432: 
-GeneralView.label.hash=\u0425\u0435\u0448: 
-GeneralView.label.numberofpieces=\u0427\u0430\u0441\u0442\u0435\u0439: 
-GeneralView.label.size=\u0420\u0430\u0437\u043c\u0435\u0440: 
-GeneralView.label.tracker=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430: 
-GeneralView.label.updatein=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437: 
-GeneralView.label.trackerurl=URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430:
-GeneralView.label.trackerurlupdate=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441
-GeneralView.label.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430:
-GeneralView.label.user_comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: 
-GeneralView.label.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435:
+GeneralView.label.downloaded=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e :
+GeneralView.label.downloadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:
+GeneralView.label.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0440\u0430\u0437\u0434\u0430\u0447: 
+GeneralView.label.maxuploads.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0438\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e.
+GeneralView.label.uploaded=\u041e\u0442\u0434\u0430\u043d\u043e : 
+GeneralView.label.uploadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 : 
+GeneralView.label.seeds=\u0421\u0438\u0434\u044b: 
+GeneralView.label.peers=\u041b\u0438\u0447\u0435\u0440\u044b :
+GeneralView.label.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e :
+GeneralView.label.totalspeed=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c : 
+GeneralView.label.totalspeed.tooltip=\u041e\u0431\u0449\u0430\u044f (\u0438 \u0441\u0440\u0435\u0434\u043d\u044f\u044f) \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u043a \u0412\u0430\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432:
+GeneralView.label.averagespeed=\u0441\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
+GeneralView.label.filename=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430:
+GeneralView.label.totalsize=\u041e\u0431\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 : 
+GeneralView.label.savein=\u041c\u0435\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f:
+GeneralView.label.hash=\u0425\u044d\u0448-\u0441\u0443\u043c\u043c\u0430 : 
+GeneralView.label.numberofpieces=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439: 
+GeneralView.label.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u0441\u0442\u0438: 
+GeneralView.label.tracker=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 : 
+GeneralView.label.updatein=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 : 
+GeneralView.label.trackerurl=URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430 (\u0430\u043d\u043e\u043d\u0441\u0430):
+GeneralView.label.trackerurlupdate=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440
+GeneralView.label.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 :
+GeneralView.label.user_comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f : 
+GeneralView.label.status=\u0421\u0442\u0430\u0442\u0443\u0441 :
 ManagerItem.waiting=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435
-ManagerItem.allocating=\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0441\u0442\u0430
+ManagerItem.allocating=\u0420\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435...
 ManagerItem.checking=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
-ManagerItem.ready=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430(\u043e\u0432) \u0432 \u041e\u0447\u0435\u0440\u0435\u0434\u0438
+ManagerItem.ready=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430(\u043e\u0432) \u0432 \u041e\u0447\u0435\u0440\u0435\u0434\u044c
 ManagerItem.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
 ManagerItem.seeding=\u0420\u0430\u0437\u0434\u0430\u0447\u0430
 ManagerItem.stopped=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-ManagerItem.error=o\u0448\u0438\u0431\u043a\u0430
+ManagerItem.error=\u041e\u0448\u0438\u0431\u043a\u0430!
 ManagerItem.high=\u0432\u044b\u0441\u043e\u043a\u0438\u0439
 ManagerItem.low=\u043d\u0438\u0437\u043a\u0438\u0439
 MinimizedWindow.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435:
-MinimizedWindow.all_transfers=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438 Vuze
+MinimizedWindow.all_transfers=\u0422\u0440\u0430\u0444\u0438\u043a Vuze
+PiecesView.#=\u2116
 PiecesView.size=\u0420\u0430\u0437\u043c\u0435\u0440
-PiecesView.numberofblocks=\u0411\u043b\u043e\u043a\u043e\u0432
+PiecesView.numberofblocks=\u041a\u043e\u043b. \u0411\u043b\u043e\u043a\u043e\u0432
 PiecesView.blocks=\u0411\u043b\u043e\u043a\u0438
-PiecesView.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
+PiecesView.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
 PiecesView.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
 PiecesView.reservedby=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d
-PiecesView.writers=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438
+PiecesView.writers=\u0414\u043e\u043d\u043e\u0440\u044b \u0411\u043b\u043e\u043a\u043e\u0432
 PiecesView.title.short=\u0427\u0430\u0441\u0442\u0438
 PiecesView.title.full=\u0427\u0430\u0441\u0442\u0438
-SystemTray.tooltip.seeding=%1 \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0441\u044f,
-SystemTray.tooltip.downloading=%1 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f,
+SystemTray.tooltip.seeding=%1 \u0440\u0430\u0437\u0434\u0430\u0435\u0442\u0441\u044f, 
+SystemTray.tooltip.downloading=%1 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, 
 DownloadManager.error.filenotfound=\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
 DownloadManager.error.fileempty=\u041f\u0443\u0441\u0442\u043e\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 DownloadManager.error.filetoobig=Torrent \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0439
 DownloadManager.error.filewithouttorrentinfo=\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 \u0444\u0430\u0439\u043b\u0435
 DownloadManager.error.unsupportedencoding=\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f
-DownloadManager.error.ioerror=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430
+DownloadManager.error.ioerror=IO \u041e\u0448\u0438\u0431\u043a\u0430
 DownloadManager.error.sha1="\u0410\u043b\u0433o\u0440\u0438\u0442\u043c (SHA1) \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d"- \u041e\u0448\u0438\u0431\u043a\u0430
-PeerManager.status.offline=\u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
+PeerManager.status.offline=\u041e\u0448\u0438\u0431\u043a\u0430 \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
+PeerManager.status.ok=\u041e\u043a
 PeerManager.status.checking=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
-PeerManager.status.finished=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+PeerManager.status.finished=\u0413\u043e\u0442\u043e\u0432\u043e
 PeerManager.status.finishedin=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e \u0437\u0430
-MainWindow.upgrade.assistant=\u041c\u0430\u0441\u0442\u0435\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-MainWindow.upgrade.newerversion=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c?
-MainWindow.upgrade.explanation=Vuze \u0441\u043a\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f
-MainWindow.upgrade.explanation.manual=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e: \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0441\u043a\u0430\u0447\u0430\u0432 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u044 [...]
-MainWindow.upgrade.step1=\u0428\u0430\u0433 1: \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e
+MainWindow.upgrade.assistant=\u041f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+MainWindow.upgrade.newerversion=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Vuze
+MainWindow.upgrade.explanation=\u042d\u0442\u043e\u0442 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0441\u043a\u0430\u0447\u0430\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Vuze  \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442.
+MainWindow.upgrade.explanation.manual=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e: \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u04 [...]
+MainWindow.upgrade.step1=\u0428\u0430\u0433 1: \u0421\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e
 MainWindow.upgrade.step2=\u0428\u0430\u0433 2: \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 Vuze
 MainWindow.upgrade.hint1=\u0421\u043e\u0432\u0435\u0442:\t\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0432\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
-MainWindow.upgrade.hint2=\u0421\u043e\u0432\u0435\u0442:\t\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u044c Vuze \u043f\u043e\u0437\u0436\u0435, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c\u00bb \u0438\n\t\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0439\u0442\u0435 \u0444\u0430\u0439\u043b Azureus2-new.jar \u0432 Azureus2.jar \u043f\u043e\u0441\u043b\u0435 [...]
-MainWindow.upgrade.error.downloading.hint=\u041e\u0448\u0438\u0431\u043a\u0430:\t\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0432\u0440\u0443\u0447\u043d\u0443\u044e
-MainWindow.upgrade.section.info=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f
-MainWindow.upgrade.section.manual=\u0412\u0440\u0443\u0447\u043d\u0443\u044e
+MainWindow.upgrade.hint2=\u0421\u043e\u0432\u0435\u0442:\t\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u044c Vuze \u043f\u043e\u0437\u0436\u0435, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u041e\u0442\u043c\u0435\u043d\u0430 \u0438\n\t\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0439\u0442\u0435 \u0444\u0430\u0439\u043b Azureus2-new.jar \u0432 Azureus2.jar \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u044 [...]
+MainWindow.upgrade.error.downloading.hint=\u041e\u0448\u0438\u0431\u043a\u0430:\t\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+MainWindow.upgrade.section.info=\u041d\u043e\u0432\u0430\u044f \u0412\u0435\u0440\u0441\u0438\u044f \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+MainWindow.upgrade.section.manual=\u041e\u0431\u043d\u043e\u0432\u043b\u044e \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e
 MainWindow.upgrade.section.automatic=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
 MainWindow.upgrade.tooltip.progressbar=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0442\u0443\u0442
 Button.next=\u0414\u0430\u043b\u0435\u0435
 Button.finish=\u0413\u043e\u0442\u043e\u0432\u043e
-Button.cancel=\u041e&\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+Button.cancel=\u041e\u0442\u043c\u0435\u043d\u0430
 LocaleUtil.title=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443
 LocaleUtil.section.chooseencoding=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430
 LocaleUtil.label.chooseencoding=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0430\u043c\u0443\u044e \u043b\u0443\u0447\u0448\u0443\u044e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443
 LocaleUtil.label.hint.doubleclick=\u0441\u043e\u0432\u0435\u0442: \u0434\u0432\u043e\u0439\u043d\u043e\u0439 \u043a\u043b\u0438\u043a \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0443 \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0434\u0438\u0430\u043b\u043e\u0433
 LocaleUtil.label.checkbox.rememberdecision=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432
 LocaleUtil.column.encoding=\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430
-IrcClient.copyright=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f PircBot Java IRC API - http://www.jibble.org/pircbot.php
-IrcClient.connecting=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a
-IrcClient.connected=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d \u043a
-IrcClient.joining=\u0412\u0445\u043e\u0434 \u0432
-IrcClient.channel=\u041a\u043e\u043c\u043d\u0430\u0442\u0430
-IrcClient.joined=\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+IrcClient.copyright=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c PircBot Java IRC API - http://www.jibble.org/pircbot.php
+IrcClient.connecting=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441
+IrcClient.connected=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d \u0441
+IrcClient.joining=\u041a\u043e\u043d\u043d\u0435\u043a\u0442\u0438\u0442\u0441\u044f
+IrcClient.channel=\u041a\u0430\u043d\u0430\u043b
+IrcClient.joined=\u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043b\u0441\u044f
 IrcClient.error=\u041e\u0448\u0438\u0431\u043a\u0430
-IrcClient.hasjoined=\u0432\u043e\u0448\u0451\u043b \u0432 \u043a\u043e\u043c\u043d\u0430\u0442\u0443
-IrcClient.haskicked=\u0432\u044b\u0433\u043d\u0430\u043b
-IrcClient.hasleft=\u0432\u044b\u0448\u0435\u043b \u0438\u0437 \u043a\u043e\u043c\u043d\u0430\u0442\u044b
-IrcClient.nowknown=\u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043a\u0430\u043a
-IrcClient.topicforchannel=\u0422\u0435\u043c\u0430 \u043a\u043e\u043c\u043d\u0430\u0442\u044b
-IrcClient.disconnected=\u041e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u043e\u0442
-IrcClient.noNick=\u0412\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043e\u043a\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0435\u0433\u043e
+IrcClient.hasjoined=\u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043b\u0441\u044f
+IrcClient.haskicked=\u0432\u044b\u043a\u0438\u043d\u0443\u043b
+IrcClient.hasleft=\u0443\u0448\u0451\u043b
+IrcClient.nowknown=\u0441\u0435\u0439\u0447\u0430\u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u043a\u0430\u043a 
+IrcClient.topicforchannel=\u0422\u0435\u043c\u0430 \u043a\u0430\u043d\u0430\u043b\u0430
+IrcClient.disconnected=\u041e\u0442\u0441\u043e\u0435\u0434\u0438\u043d\u0451\u043d \u043e\u0442
+IrcClient.noNick=\u0412\u044b \u0437\u0430\u0431\u044b\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u043c\u044f. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043e\u043a\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043c\u044f
 IrcView.actionnotsupported=\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f
-IrcView.clientsconnected=\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
-IrcView.privateto=\u041a
-IrcView.privatefrom=\u041e\u0442
-IrcView.noticefrom=\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: 
-IrcView.errormsg=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432 /msg: \u00ab/msg \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442\u00bb
-IrcView.help=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:\n/help: \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442\n/nick | /name: \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c\n/me \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435: \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043c\u0435\u0447\u0430\ [...]
-PasswordWindow.title=Vuze \u0437\u0430\u0449\u0438\u0449\u0451\u043d \u043f\u0430\u0440\u043e\u043b\u0435\u043c
-PasswordWindow.passwordprotected=Vuze \u0437\u0430\u0449\u0438\u0449\u0451\u043d \u043f\u0430\u0440\u043e\u043b\u0435\u043c.\n\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u043a\u043d\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c:
-TrackerChangerWindow.title=\u0417\u0430\u043c\u0435\u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-TrackerChangerWindow.newtracker=\u0417\u0430\u0434\u0430\u0442\u044c URL \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+IrcView.clientsconnected=\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438
+IrcView.privateto=\u0441 
+IrcView.privatefrom=\u043e\u0442 
+IrcView.noticefrom=\u0417\u0430\u043c\u0435\u0442\u043a\u0430 : 
+IrcView.errormsg=\u041d\u0435 \u0432\u0435\u0440\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432 /msg : /msg \u0432\u0430\u0448 \u0442\u0435\u043a\u0441\u0442
+IrcView.help=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b: \n/help : \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442\n/nick | /name : \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u043d\u0438\u043a\n/me action : \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0437\u0430\u043c\u0435\u0442\u043a\u0443\n/msg nick message: \u043f\u043e\u0441\u043b\u043 [...]
+PasswordWindow.title=Vuze \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d
+PasswordWindow.passwordprotected=Vuze \u0437\u0430\u0449\u0438\u0449\u0435\u043d \u043f\u0430\u0440\u043e\u043b\u0435\u043c.\n\u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u043a\u043d\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c :
+Button.ok=Ok 
 PeersView.discarded=\u041e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e
-PeersView.discarded.info=\u0414\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u044b, \u043d\u043e \u0431\u044b\u043b\u0438 \u043a\u0430\u043a\u0438\u043c-\u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b, \u0438 \u0431\u044b\u043b\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u044b
-discarded=\u043e\u0442\u0431\u0440\u043e\u0448\u0435\u043d\u043e
+PeersView.discarded.info=\u0414\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438, \u0445\u043e\u0442\u044f \u0432 \u043d\u0438\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u043b\u0438\u0441\u044c - \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u0441\u0442\u0438\u0440\u0430\u044e\u0442\u0441\u044f
+discarded=\u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e
 MyTorrentsView.#=\u2116
-MyTorrentsView.menu.move=\u041f\u0435\u0440\u0435&\u043c\u0435\u0441\u0442\u0438\u0442\u044c
-MyTorrentsView.menu.moveUp=&\u0412\u0432\u0435\u0440\u0445
-MyTorrentsView.menu.moveDown=&\u0412\u043d\u0438\u0437
-GeneralView.label.hashfails=\u041d\u0435\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0445\u0435\u0448\u0430:
-GeneralView.label.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433:
-ConfigView.section.downloadManagement=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u043c\u0438
-ConfigView.label.startRatioPeers=\u041d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043f\u0440\u0438 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c 1 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0435\u043c
-ConfigView.text.neverStop=\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c
-ConfigView.text.neverStart=\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c
-ConfigView.text.peers=\u0443\u0437\u043b\u043e\u0432
-ConfigView.label.checkOncompletion=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0447\u0430\u0441\u0442\u0438 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+MyTorrentsView.menu.move=&\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c
+MyTorrentsView.menu.moveUp=\u0432\u0432\u0435\u0440\u0445
+MyTorrentsView.menu.moveDown=&\u0432\u043d\u0438\u0437
+GeneralView.label.hashfails=\u0421 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0432 hash-\u0441\u0443\u043c\u043c\u0435:
+GeneralView.label.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430:
+ConfigView.section.downloadManagement=\u041c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442 \u0437\u0430\u043a\u0430\u0447\u043a\u0438
+ConfigView.label.startRatioPeers=\u041d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043f\u0440\u0438 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c 1 \u0441\u0438\u0434\u0435 \u043d\u0430
+ConfigView.text.neverStop=\u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c
+ConfigView.text.neverStart=\u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c
+ConfigView.text.peers=\u041b\u0438\u0447\u0435\u0440\u043e\u0432
+ConfigView.label.checkOncompletion=\u041f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0447\u0430\u0441\u0442\u0435\u0439 \u043f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 wizard.title=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 wizard.previous=< \u041d\u0430\u0437\u0430\u0434
 wizard.next=\u0414\u0430\u043b\u0435\u0435 >
 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=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u0430\u044f URL
+wizard.invalidurl=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430 (URL)
 wizard.singlefile=\u041e\u0434\u0438\u043d \u0444\u0430\u0439\u043b
 wizard.singlefile.help=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430
 wizard.directory=\u041f\u0430\u043f\u043a\u0430
 wizard.directory.help=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
 wizard.choosefile=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430
-wizard.file=\u0424\u0430\u0439\u043b:
+wizard.file=\u0424\u0430\u0439\u043b : 
 wizard.browse=\u041e\u0431\u0437\u043e\u0440...
 wizard.choosedirectory=\u0412\u044b\u0431\u043e\u0440 \u043f\u0430\u043f\u043a\u0438
 wizard.invalidfile=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0444\u0430\u0439\u043b!
 wizard.invaliddirectory=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u043f\u0430\u043f\u043a\u0430!
-wizard.torrentFile=\u0424\u0430\u0439\u043b \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+wizard.torrentFile=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b
 wizard.choosetorrent=\u0412\u044b\u0431\u043e\u0440 torrent-\u0424\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f
 wizard.information=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
-wizard.notimplemented=\u0412 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435
+wizard.notimplemented=\u0415\u0449\u0451 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435
 wizard.progresstitle=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-wizard.savingfile=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430...
+wizard.savingfile=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 ...
 wizard.filesaved=\u0424\u0430\u0439\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d.
 wizard.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
 Torrent.create.progress.piecelength=\u0414\u043b\u0438\u043d\u0430 \u0447\u0430\u0441\u0442\u0438:
 Torrent.create.progress.piececount=\u041a\u043e\u043b-\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439:
 Torrent.create.progress.totalfilesize=\u041e\u0431\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430:
-Torrent.create.progress.totalfilecount=\u0412\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432:
+Torrent.create.progress.totalfilecount=\u041e\u0431\u0449\u0435\u0435 \u043a\u043e\u043b-\u0432\u043e \u0444\u0430\u0439\u043b\u043e\u0432:
 Torrent.create.progress.parsingfiles=\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430
-Torrent.create.progress.hashing=\u0425\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
-MainWindow.upgrade.downloadingfrom=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441:
-MainWindow.menu.view.ipFilter=\u0424\u0438\u043b\u044c\u0442\u0440\u044b &IP
-ConfigView.section.ipfilter=\u0424\u0438\u043b\u044c\u0442\u0440\u044b IP
+Torrent.create.progress.hashing=\u0425\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
+MainWindow.upgrade.downloadingfrom=\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441 :
+MainWindow.menu.view.ipFilter=&IP-\u0444\u0438\u043b\u044c\u0442\u0440\u044b
+ConfigView.section.ipfilter=IP-\u0444\u0438\u043b\u044c\u0442\u0440\u044b
 ConfigView.section.ipfilter.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
 ConfigView.section.ipfilter.start=\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 IP
-ConfigView.section.ipfilter.end=\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 IP
+ConfigView.section.ipfilter.end=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 IP
 ConfigView.section.ipfilter.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
 ConfigView.section.ipfilter.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-ConfigView.section.ipfilter.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
+ConfigView.section.ipfilter.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
 ConfigView.section.ipfilter.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
-ConfigView.section.ipfilter.editFilter=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u0430
+ConfigView.section.ipfilter.editFilter=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
 ConfigView.section.ipfilter.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
 PeersView.menu.close=&\u0417\u0430\u043a\u0440\u044b\u0442\u044c
 seedmore.title=\u0420\u0430\u0437\u0434\u0430\u0447\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u0430 
-seedmore.shareratio=\u0412\u0430\u0448\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-seedmore.uploadmore=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 <1 \u043f\u043b\u043e\u0445\u043e \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0442\u0438 BitTorrent.\n\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043d\u0430\u0434\u043e\u043b\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0440\u0430\u0437\u0 [...]
-ConfigView.label.showpopuponclose=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441 \u0440\u0435\u0439\u0442\u0438\u043d\u0433\u043e\u043c <1
+seedmore.shareratio=\u0412\u0430\u0448 \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+seedmore.uploadmore=\u0412\u0430\u0448 \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443 \u043c\u0435\u043d\u0435\u0435 100%, \u0447\u0442\u043e  \u043f\u043b\u043e\u0445\u043e \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 bittorrent-\u0441\u0435\u0442\u0438.\n\u0412\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0445 [...]
+ConfigView.label.showpopuponclose=\u041f\u0440\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441 \u0420\u0435\u0439\u0442\u0438\u043d\u0433\u043e\u043c \u041e\u0431\u043c\u0435\u043d\u0430 \u043d\u0438\u0436\u0435, \u0447\u0435\u043c 1, \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435
 ConfigView.label.startNumSeeds=\n\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043f\u0440\u0438 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c\n - \u0412\u0441\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f
-ConfigView.label.seeds=\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
+ConfigView.label.seeds=\u0441\u0438\u0434\u043e\u0432
 ConfigView.section.seeding=\u0420\u0430\u0437\u0434\u0430\u0447\u0430
-MyTorrentsView.menu.removeand=\u0423&\u0434\u0430\u043b\u0438\u0442\u044c \u0438
-MyTorrentsView.menu.removeand.deletetorrent=\u0423\u0434\u0430\u043b\u0438\u0442\u044c &\u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
-MyTorrentsView.menu.removeand.deletedata=\u0423\u0434\u0430\u043b\u0438\u0442\u044c &\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b
-MyTorrentsView.menu.removeand.deleteboth=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441&\u0451
-deletedata.title=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435
-deletedata.message1=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u00ab%1\u00bb \u0431\u0435\u0437\u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043d\u043e?
-deletedata.noprompt=\u041d\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletetorrent=\u0421\u0442\u0435\u0440\u0435\u0442\u044c torrent-\u0444\u0430\u0439\u043b
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deletedata=\u0421\u0442\u0435\u0440\u0435\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0434\u0430\u043d\u043d\u044b\u0445
+#Used by the webui plugin
+MyTorrentsView.menu.removeand.deleteboth=\u0421\u0442\u0435\u0440\u0435\u0442\u044c torrent-\u0444\u0430\u0439\u043b + \u0444\u0430\u0439\u043b\u044b \u0434\u0430\u043d\u043d\u044b\u0445
+deletedata.title=\u0421\u0442\u0435\u0440\u0435\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442
+# used for more than just "delete data"
+deletedata.noprompt=\u041d\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043c\u0435\u043d\u044f \u0441\u043d\u043e\u0432\u0430
 MainWindow.menu.file.configure=\u041c\u0430\u0441\u0442\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a
 configureWizard.title=\u041c\u0430\u0441\u0442\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a
-configureWizard.welcome.title=\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u0430\u0441\u0442\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a Vuze
-configureWizard.welcome.message=\u042d\u0442\u043e\u0442 \u043c\u0430\u0441\u0442\u0435\u0440 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Vuze \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u043d\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u043 [...]
-configureWizard.transfer.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
-configureWizard.transfer.hint=\u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435: \t\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044c\u0448\u0435\u0439 \u0432\u0430\u0448\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f
-configureWizard.transfer.message=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0438\u0436\u0435. \u0423\u0447\u0442\u0438\u0442\u0435, \u0447\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043d\u0438\u0437\u043a\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043c\u043e\u0436\u0435\u0 [...]
+configureWizard.welcome.title=\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u043c\u0430\u0441\u0442\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a Vuze!
+configureWizard.welcome.message=\u042d\u0442\u043e\u0442 \u043c\u0430\u0441\u0442\u0435\u0440 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043d\u0430\u043b\u0430\u0434\u0438\u0442\u044c Vuze \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0414\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u043d\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043 [...]
+configureWizard.transfer.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+configureWizard.transfer.hint=\u0421\u043e\u0432\u0435\u0442: \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044c\u0448\u0435\u0439, \u0447\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043b\u0438\u043d\u0438\u0438.
+configureWizard.transfer.message=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043d\u0438\u0436\u0435.  \u0418\u043c\u0435\u0439\u0442\u0435 \u0432\u0432\u0438\u0434\u0443, \u0447\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u0440\ [...]
 configureWizard.transfer.connection=\u0421\u0432\u044f\u0437\u044c
 configureWizard.transfer.connection.0=\u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f
 configureWizard.transfer.connection.1=\u043c\u043e\u0434\u0435\u043c
-configureWizard.transfer.connection.2=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/128 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.connection.3=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/256 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.connection.4=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/384 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.connection.5=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/512 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.connection.6=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/768 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.connection.7=ADSL/\u041a\u0430\u0431\u0435\u043b\u044c xxx/1024 \u041a\u0431\u0438\u0442/\u0441
-configureWizard.transfer.maxUpSpeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (\u041a\u0411/\u0441)
+configureWizard.transfer.connection.2=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/128 kbps
+configureWizard.transfer.connection.3=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/256 kbps
+configureWizard.transfer.connection.4=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/384 kbps
+configureWizard.transfer.connection.5=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/512 kbps
+configureWizard.transfer.connection.6=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/768 kbps
+configureWizard.transfer.connection.7=\u0410\u0414\u0421\u041b/\u041a\u0430\u0431\u0435\u043b\u044c xxx/1024 kbps
+configureWizard.transfer.maxUpSpeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (K\u0411/c)
 configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445
-configureWizard.transfer.maxDownloads=\u041c\u0430\u043a\u0441. \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-configureWizard.transfer.maxUploadsPerTorrent=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447 \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-configureWizard.nat.title=NAT / \u043f\u043e\u0440\u0442 \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 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 BitTorrent \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\ [...]
+configureWizard.transfer.maxDownloads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+configureWizard.transfer.maxUploadsPerTorrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 configureWizard.nat.test=\u0422\u0435\u0441\u0442
 configureWizard.nat.testing=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u0440\u0442\u0430
-configureWizard.nat.ok=OK!
-configureWizard.nat.ko=\u041e\u0448\u0438\u0431\u043a\u0430 NAT
-configureWizard.nat.unable=\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e: \u0443\u043a\u0430\u0437\u0430\u043d \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0438\u043b\u0438 \u0441\u043b\u0443\u0436\u0431\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u04 [...]
-configureWizard.file.title=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b / \u0444\u0430\u0439\u043b\u044b
-configureWizard.file.message1=\u0417\u0430\u043f\u0438\u0441\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435. \u0412\u044b\u0431\u043e\u0440:
-configureWizard.file.path=\u041f\u0430\u043f\u043a\u0430
+configureWizard.nat.ok=\u041e\u041a !
+configureWizard.nat.ko=NAT \u041e\u0448\u0438\u0431\u043a\u0430
+configureWizard.nat.unable=\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e: \u0423\u043a\u0430\u0437\u0430\u043d \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u043e\u0440\u0442, \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.\n\u0414\u0440\u0443\u0433\u043e\u0435 [...]
+configureWizard.file.title=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b / \u0424\u0430\u0439\u043b\u044b
+configureWizard.file.message1=Vuze \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043e\u043a\u0440\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b\u044b \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u043f\u0430\u043f\u043a\u0435:
+configureWizard.file.path=\u041f\u0443\u0442\u044c
 configureWizard.file.browse=\u041e\u0431\u0437\u043e\u0440
-configureWizard.file.message2=Vuze \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u043e\u0431\u0430\u0432\u043a\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0432\u0430\u0448\u0 [...]
-configureWizard.file.fastResume=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u00ab\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e\u00bb \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f
-configureWizard.file.invalidPath=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430
+configureWizard.file.message2=Vuze \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0434\u043e\u0431\u0430\u0432\u043a\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0432\u0430\u0448\u0 [...]
+configureWizard.file.fastResume=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e "\u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e" \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f
+configureWizard.file.invalidPath=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u043f\u0430\u043f\u043a\u0430
 configureWizard.finish.title=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
 configureWizard.finish.message=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430. \u0416\u0435\u043b\u0430\u0435\u043c \u0432\u0430\u043c \u0443\u0434\u0430\u0447\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0432\u0440\u0435\u043c\u044f!
 wizard.close.confirmation=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435
-wizard.close.message=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043c\u0430\u0441\u0442\u0435\u0440 \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b?
-exportTorrentWizard.title=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 XML \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+wizard.close.message=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b?
+exportTorrentWizard.title=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 XML-\u0442\u043e\u0440\u0440\u0435\u043d\u0442
 exportTorrentWizard.torrentfile.title=\u0412\u044b\u0431\u043e\u0440 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 exportTorrentWizard.torrentfile.message=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
-exportTorrentWizard.torrentfile.path=\u041f\u0430\u043f\u043a\u0430
+exportTorrentWizard.torrentfile.path=\u041f\u0443\u0442\u044c
 exportTorrentWizard.torrentfile.browse=\u041e\u0431\u0437\u043e\u0440
-exportTorrentWizard.torrentfile.invalidPath=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+exportTorrentWizard.torrentfile.invalidPath=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
 exportTorrentWizard.exportfile.title=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
 exportTorrentWizard.exportfile.message=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 XML-\u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
-exportTorrentWizard.exportfile.path=\u041f\u0430\u043f\u043a\u0430
+exportTorrentWizard.exportfile.path=\u041f\u0443\u0442\u044c
 exportTorrentWizard.exportfile.browse=\u041e\u0431\u0437\u043e\u0440
-exportTorrentWizard.exportfile.invalidPath=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
+exportTorrentWizard.exportfile.invalidPath=\u041d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0430
 exportTorrentWizard.finish.title=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
 exportTorrentWizard.finish.message=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u043e
-exportTorrentWizard.process.inputfilebad.title=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-exportTorrentWizard.process.inputfilebad.message=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0430\u0439\u043b\u0443:
+exportTorrentWizard.process.inputfilebad.title=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
+exportTorrentWizard.process.inputfilebad.message=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u0432\u043e\u0434\u043d\u043e\u043c\u0443 \u0444\u0430\u0439\u043b\u0443:
 exportTorrentWizard.process.outputfileexists.title=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
-exportTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u2014 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c?
+exportTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 - \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c?
 exportTorrentWizard.process.torrentfail.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 exportTorrentWizard.process.exportfail.title=\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 exportTorrentWizard.process.unknownfail.title=\u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430
-importTorrentWizard.title=XML-\u0438\u043c\u043f\u043e\u0440\u0442 \u0444\u0430\u0439\u043b\u0430
-importTorrentWizard.torrentfile.title=\u0412\u0432\u043e\u0434 \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-importTorrentWizard.torrentfile.message=\u0412\u0432\u043e\u0434 \u0438\u043c\u0435\u043d\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430
-importTorrentWizard.torrentfile.path=\u041f\u0430\u043f\u043a\u0430
+importTorrentWizard.title=\u0418\u043c\u043f\u043e\u0440\u0442 \u0438\u0437 XML-\u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+importTorrentWizard.torrentfile.title=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0438\u043c\u044f \u0438 \u043f\u0443\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u0437 \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+importTorrentWizard.torrentfile.message=\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+importTorrentWizard.torrentfile.path=\u041f\u0443\u0442\u044c
 importTorrentWizard.torrentfile.browse=\u041e\u0431\u0437\u043e\u0440
-importTorrentWizard.torrentfile.invalidPath=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-importTorrentWizard.importfile.title=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0430
-importTorrentWizard.importfile.message=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430
-importTorrentWizard.importfile.path=\u041f\u0430\u043f\u043a\u0430
+importTorrentWizard.torrentfile.invalidPath=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
+importTorrentWizard.importfile.title=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430
+importTorrentWizard.importfile.message=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 xml-\u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430
+importTorrentWizard.importfile.path=\u041f\u0443\u0442\u044c
 importTorrentWizard.importfile.browse=\u041e\u0431\u0437\u043e\u0440
-importTorrentWizard.importfile.invalidPath=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438\u043c\u043f\u043e\u0440\u0442\u0430
+importTorrentWizard.importfile.invalidPath=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b
 importTorrentWizard.finish.title=\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d
 importTorrentWizard.finish.message=\u0418\u043c\u043f\u043e\u0440\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d \u0443\u0434\u0430\u0447\u043d\u043e
-importTorrentWizard.process.inputfilebad.title=\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b \u043e\u0448\u0438\u0431\u043e\u0447\u0435\u043d
+importTorrentWizard.process.inputfilebad.title=\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c
 importTorrentWizard.process.inputfilebad.message=\u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b \u0432\u0432\u043e\u0434\u0430:
 importTorrentWizard.process.outputfileexists.title=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
-importTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u2014 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c?
-importTorrentWizard.process.torrentfail.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-importTorrentWizard.process.importfail.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+importTorrentWizard.process.outputfileexists.message=\u0424\u0430\u0439\u043b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 - \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c?
+importTorrentWizard.process.torrentfail.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+importTorrentWizard.process.importfail.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 importTorrentWizard.process.unknownfail.title=\u041d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430
-ConfigView.label.bindip=\u041f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 IP
-ConfigView.label.xfs.allocation=\u0412\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b XFS
-ConfigView.label.xfs.allocation.tooltip=\u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e /usr/sbin/xfs_io \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432\u0430\u0445 Linux \u043e\u043d \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u0432 \u043f\u0430\u043a\u0435\u0442 \u00abxfsprogs\u00bb.
-xfs.allocation.xfs_io.not.found=\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0441\u0442\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043c XFS \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u00ab/usr/sbin/xfs_io\u00bb. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c \u0432 \u043f\u0440\u0430\u0432\u043 [...]
-ConfigView.label.zeronewfiles=\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043d\u0443\u043b\u044f\u043c\u0438 \u0444\u0430\u0439\u043b
+ConfigView.label.bindip=\u041f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 IP \u0430\u0434\u0440\u0435\u0441\u0443
+ConfigView.label.xfs.allocation=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043c\u0435\u0442\u043e\u0434 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u043d\u044b\u0439 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c XFS 
+ConfigView.label.xfs.allocation.tooltip=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c \u0447\u0442\u043e  /usr/sbin/xfs_io \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u0432 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u041d\u0430 \u043c\u043d\u043e\u0433\u0438\u0445 Linux'\u0430\u0445 \u0443\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0432\u0443\u0435\u0442 \ [...]
+xfs.allocation.xfs_io.not.found=XFS \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430  \u043d\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e /usr/sbin/xfs_io \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043e\u043d\u043e \u043a\u043e\u0440\u0440\u [...]
+ConfigView.label.zeronewfiles=\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043d\u0443\u043b\u044f\u043c\u0438 \u0444\u0430\u0439\u043b
 ConfigView.label.zeronewfiles.tooltip=\u0423\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e
 ConfigView.section.stats=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
 ConfigView.section.stats.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
 ConfigView.section.stats.defaultsavepath=\u041f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438
 ConfigView.section.stats.choosedefaultsavepath=\u0412\u044b\u0431\u043e\u0440 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438
 ConfigView.section.stats.savefreq=\u0427\u0430\u0441\u0442\u043e\u0442\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
-ConfigView.section.stats.minutes=\u043c
+ConfigView.section.stats.minutes=\u043c\u0438\u043d
 ConfigView.section.stats.hours=\u0447
-ConfigView.section.stats.seconds=\u0441
-ConfigView.section.stats.savefile=\u0424\u0430\u0439\u043b \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438
-ConfigView.section.stats.graph_update_dividers=\u0412\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u043a\u0430\u0436\u0434\u044b\u0435 60 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
-MyTorrentsView.menu.export=&\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 XML...
-MyTorrentsView.menu.host=&\u0425\u043e\u0441\u0442...
+ConfigView.section.stats.seconds=\u0441\u0435\u043a
+ConfigView.section.stats.savefile=\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438
+ConfigView.section.stats.graph_update_dividers=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u043a\u0430\u0436\u0434\u044b\u0435 60 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
+MyTorrentsView.menu.export=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 XML...
+MyTorrentsView.menu.host=&\u0425\u043e\u0441\u0442\u0438\u043d\u0433 \u043d\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0435
 ManagerItem.finishing=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435
 ConfigView.dialog.choosedefaulttorrentpath=\u0412\u044b\u0431\u0435\u0440\u0435\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
 ConfigView.dialog.choosemovepath=\u0412\u044b\u0431\u0435\u0440\u0435\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430
-ConfigView.label.movecompleted=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b (\u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438)
-ConfigView.label.moveremoved=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b (\u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438)
+ConfigView.label.movecompleted=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b (\u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438)
+ConfigView.label.moveremoved=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b (\u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438)
 ConfigView.label.savetorrents=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0444\u0430\u0439\u043b\u044b
-MainWindow.menu.view.mytracker=\u041c\u043e\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u044b
-MyTrackerView.title.full=\u041c\u043e\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u044b
+MainWindow.menu.view.mytracker=\u041c\u043e\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
+MyTrackerView.title.full=\u041c\u043e\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
 MyTrackerView.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 MyTrackerView.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
-MyTrackerView.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+MyTrackerView.status=\u0421\u0442\u0430\u0442\u0443\u0441
 MyTrackerView.status.started=\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442
 MyTrackerView.status.stopped=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-MyTrackerView.peers=\u0423\u0437\u043b\u043e\u0432
-MyTrackerView.seeds=\u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
-MyTrackerView.announces=\u0410\u043d\u043e\u043d\u0441\u044b
-MyTrackerView.uploaded=\u0420\u043e\u0437\u0434\u0430\u043d\u043e
+MyTrackerView.peers=\u041b\u0438\u0447\u0435\u0440\u043e\u0432
+MyTrackerView.seeds=\u0421\u0438\u0434\u043e\u0432
+MyTrackerView.announces=\u0410\u043d\u043d\u043e\u043d\u0441\u044b
+MyTrackerView.uploaded=\u041e\u0442\u0434\u0430\u043d\u043e
 MyTrackerView.downloaded=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
 MyTrackerView.left=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c
-ConfigView.section.style=\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
-ConfigView.label.set_ui_transfer_speeds=\u041a\u043e\u0440\u0440\u0435\u043a\u0446\u0438\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0435\u0439 \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438
-ConfigView.label.set_ui_transfer_speeds.description=\u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0451\u043c\u0430 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432 \u043c\u0435\u043d\u044e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\ [...]
-ConfigView.label.set_ui_transfer_speeds.description.download=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 (\u041a\u0411/c)
-ConfigView.label.set_ui_transfer_speeds.description.upload=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (\u041a\u0411/c)
-ConfigView.section.style.useCustomTabs=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
-MainWindow.menu.view.plugins=&\u041c\u043e\u0434\u0443\u043b\u0438
+ConfigView.section.style=\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 (\u044f\u0437\u044b\u043a, \u0432\u0438\u0434, \u043e\u043a\u043d\u0430)
+ConfigView.label.set_ui_transfer_speeds=\u041a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438
+ConfigView.label.set_ui_transfer_speeds.description=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432 \u0441\u0442\u0440\u043e\u [...]
+ConfigView.label.set_ui_transfer_speeds.description.download=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f (\u0432 \u041a\u0411/c)
+ConfigView.label.set_ui_transfer_speeds.description.upload=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (\u0432 \u041a\u0411/c)
+ConfigView.section.style.useCustomTabs=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
+MainWindow.menu.view.plugins=\u041f\u043b\u0430\u0433\u0438\u043d\u044b
 fileDownloadWindow.saveTorrentIn=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0432
-fileDownloadWindow.title=Vuze \u2014 BitTorrent-\u043a\u043b\u0438\u0435\u043d\u0442
-fileDownloadWindow.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441:
-fileDownloadWindow.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435:
+fileDownloadWindow.title=Vuze - \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+fileDownloadWindow.downloading=\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0441 :
+fileDownloadWindow.status=\u0421\u0442\u0430\u0442\u0443\u0441 :
 fileDownloadWindow.state_initializing=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
 fileDownloadWindow.state_downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
-fileDownloadWindow.state_error=\u041e\u0448\u0438\u0431\u043a\u0430:
-MainWindow.menu.file.open.url=&\u0410\u0434\u0440\u0435\u0441...
-openUrl.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0430\u0434\u0440\u0435\u0441
-openUrl.url=URL:
-MyTorrentsView.menu.host.error.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+fileDownloadWindow.state_error=\u041e\u0448\u0438\u0431\u043a\u0430 :
+MainWindow.menu.file.open.url=URL
+openUrl.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c Url
+MyTorrentsView.menu.host.error.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u0425\u043e\u0441\u0442\u0438\u043d\u0433a \u0422\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 MyTorrentsView.menu.host.error.message=\u041f\u0440\u0438 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 
-ConfigView.section.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
-ConfigView.section.tracker.pollinterval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u043e\u043f\u0440\u043e\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 (\u0441)
-ConfigView.section.tracker.publishenable=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0435\u0442\u0430\u043b\u0435\u0439 \u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0430 "<tracker_url>/"
-ConfigView.section.tracker.ip=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u0430\u0434\u0440\u0435\u0441 IP \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker=\u0422\u0440\u0435\u043a\u0435\u0440 (\u043a\u043b\u0438\u0435\u043d\u0442, \u0441\u0435\u0440\u0432\u0435\u0440)
+ConfigView.section.tracker.pollinterval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u043f\u0440\u043e\u0441\u0430 \u0442\u0440\u0435\u043a\u0435\u0440-\u043a\u043b\u0438\u0435\u043d\u0442 (\u0441\u0435\u043a)
+ConfigView.section.tracker.publishenable=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0432 "<tracker_url>"
+ConfigView.section.tracker.ip=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 IP \u0412\u0430\u0448\u0435\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 ConfigView.section.style.enableXPStyle=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0442\u0438\u043b\u044c XP (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
-ConfigView.section.tracker.checkip=\u0423\u0437\u043d\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0430\u0434\u0440\u0435\u0441...
+IPChecker.external.service.dyndns.description=\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 DNS \u0421\u0435\u0440\u0432\u0438\u0441\u044b \u0441\u0435\u0442\u0438, LLC
+ConfigView.section.tracker.checkip=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441...
 ipCheckerWizard.title=\u041c\u0430\u0441\u0442\u0435\u0440 "IP Checker"
 ipCheckerWizard.service=\u0421\u0435\u0440\u0432\u0438\u0441
-ipCheckerWizard.chooseService=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 IP-Checker \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043d\u0438\u0436\u0435
-ipCheckerWizard.explanations=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 IP. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448 IP \u0434 [...]
-ipCheckerWizard.service.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435:
-ipCheckerWizard.service.url=\u0421\u0441\u044b\u043b\u043a\u0430:
+ipCheckerWizard.chooseService=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441 IP-Checker \u0438\u0437 \u043d\u0438\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445
+ipCheckerWizard.explanations=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0442\u0435\u0440 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430 IP. \u0415\u0441\u043b\u0438 \u0432\u0430\u0448 IP \u0434 [...]
+ipCheckerWizard.service.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 :
+ipCheckerWizard.service.url=\u0421\u0441\u044b\u043b\u043a\u0430 :
 ipCheckerWizard.progresstitle=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 IP
-ipCheckerWizard.checkComplete=\u041f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0435 IP:
-ipCheckerWizard.checkFailed=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u043f\u0440\u0438\u0447\u0438\u043d\u0430:
-wizard.tracker.local=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b Vuze
+ipCheckerWizard.checkComplete=\u041f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0435 IP :
+ipCheckerWizard.checkFailed=\u041e\u0448\u0438\u0431\u043a\u0430! \u041f\u0440\u0438\u0447\u0438\u043d\u0430 :
+wizard.tracker.local=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b Vuze
 wizard.tracker.external=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-wizard.tracker.howToLocal=\t\u0414\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00ab\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b/\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438/\u0422\u0440\u0435\u043a\u0435\u0440\u00bb
-wizard.announceUrl=URL \u0430\u043d\u043e\u043d\u0441\u0430:
-IPChecker.external.service.discoveryvip.description=Discoveryvip \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 IP
-IPChecker.external.httpinvalidresponse=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 HTTP
-IPChecker.external.loadingwebpage=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0430
+wizard.tracker.howToLocal=\t\u0414\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 '\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 > \u0422\u0440\u0435\u043a\u0435\u0440'
+wizard.announceUrl=URL \u0430\u043d\u043e\u043d\u0441\u0430 :
+IPChecker.external.service.discoveryvip.name=\u0421\u0435\u0440\u0432\u0438\u0441 Discoveryvip
+IPChecker.external.service.discoveryvip.description=Discoveryvip - \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 IP \u0430\u0434\u0440\u0435\u0441\u0430
+IPChecker.external.httpinvalidresponse=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 HTTP-\u043e\u0442\u0432\u0435\u0442
+IPChecker.external.loadingwebpage=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 web-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b
 IPChecker.external.analysingresponse=\u0410\u043d\u0430\u043b\u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430
 IPChecker.external.addressextracted=\u0418\u0437\u0432\u043b\u0435\u0447\u0451\u043d\u043d\u044b\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 IP 
-IPChecker.external.httploadfail=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443
-IPChecker.external.timeout=\u0412\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438\u0441\u0442\u0435\u043a\u043b\u043e
+IPChecker.external.httploadfail=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b
+IPChecker.external.timeout=\u0412\u0440\u0435\u043c\u044f \u0438\u0441\u0442\u0435\u043a\u043b\u043e
 IPChecker.external.ipnotfound=\u0410\u0434\u0440\u0435\u0441 IP \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
-ConfigView.section.tracker.pollintervalmin=\u041c\u0438\u043d\u0438\u043c\u0443\u043c
-ConfigView.section.tracker.pollintervalmax=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c
-ConfigView.section.tracker.pollintervalincby=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043d\u0430
-ConfigView.section.tracker.pollintervalincper=\u043a\u0430\u0436\u0434\u044b\u0435 N \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.tracker.pollintervalmin=\u041c\u0438\u043d.
+ConfigView.section.tracker.pollintervalmax=\u041c\u0430\u043a\u0441.
+ConfigView.section.tracker.pollintervalincby=\u041f\u043e\u0432\u044b\u0448\u0430\u0442\u044c \u043f\u043e
+ConfigView.section.tracker.pollintervalincper=\u041a\u0430\u0436\u0434\u044b\u0445 N \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432
 splash.loadingImages=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a
-splash.initializeGui=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430
+splash.initializeGui=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e
 splash.openViews=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
-splash.plugin=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u044c: 
+splash.plugin=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043f\u043b\u0430\u0433\u0438\u043d : 
 configureWizard.nat.tooManyPorts=\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (\u043c\u0430\u0445. 9)
 ConfigView.section.color=\u0426\u0432\u0435\u0442\u043e\u0432\u0430\u044f \u0441\u0445\u0435\u043c\u0430
-MyTorrentsView.menu.publish=&\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c...
+MyTorrentsView.menu.publish=&\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c (\u0431\u0435\u0437 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0430)
 MyTrackerView.status.published=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d
-MyTrackerView.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0451\u043d
-MainWindow.menu.file.open.torrentnodefault=\u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0431\u0435\u0437 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)
+MyTrackerView.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+MainWindow.menu.file.open.torrentnodefault=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 \u0424\u0430\u0439\u043b...(\u0411\u0435\u0437 \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f)
 wizard.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
-ConfigView.label.movetorrent=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
-ConfigView.label.movepartialdownloads=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0431\u044b\u043b\u0438 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u043a\u0430\u043a \u00ab\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u00bb
-ConfigView.label.subdir_is_in_default=\u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u00ab\u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\u00bb \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0438 \u0432\u0441\u0435\u0445 \u0435\u0451 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a
-ConfigView.section.file.decoder.label=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430,\n\u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u043e\u0440
-ConfigView.section.file.decoder.nodecoder=\u041d\u0435\u0442
-IPChecker.external.service.no-ip.description=\u0421\u043b\u0443\u0436\u0431\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Dynamic \u0438 Static DNS\n(\u0431\u0435\u0437 \u043e\u0442\u043a\u0440\u044b\u0442\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 'check address')
+ConfigView.label.movetorrent=\u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 .torrent-\u0444\u0430\u0439\u043b
+ConfigView.label.movepartialdownloads=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u044b \u043a\u0430\u043a "\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c" 
+ConfigView.label.subdir_is_in_default=\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0442\u043e \u044d\u0442\u043e \u043a\u0430\u0441\u0430\ [...]
+ConfigView.section.file.decoder.label=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\n(\u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u043e\u0440 )
+ConfigView.section.file.decoder.nodecoder=\u041d\u0438\u043a\u0430\u043a\u043e\u0439
+IPChecker.external.service.no-ip.description=\u0421\u043b\u0443\u0436\u0431\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 Dynamic \u0438 Static DNS\n(\u0431\u0435\u0437 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e-\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 '\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u0434\u0440\u0435\u0441\u0430')
 ConfigView.section.tracker.publicenable=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-ConfigView.label.playdownloadspeech=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0440\u0435\u0447\u0438 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-ConfigView.label.playdownloadspeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0440\u0435\u0447\u0438 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c
+ConfigView.label.playdownloadspeech=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0440\u0435\u0447\u0438 \u043f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 #
 # Tooltips
 #
-GeneralView.label.status.pieces_available.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.\n\u0415\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 1, \u0444\u0430\u0439\u043b \u043d\u0430 \u0434\u0430\u043d\u043d\u044b [...]
-GeneralView.label.trackerurl.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0430\u043d\u043e\u043d\u0441\u0430 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-GeneralView.label.trackerurlopen.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+GeneralView.label.status.pieces_available.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.\n\u0415\u0441\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0447\u0438\u0441\u043b\u043e \u043c\u0435\u043d\u044c\u0448\u0435 1, \u0442\u043e\u0433\u0434\ [...]
+GeneralView.label.trackerurl.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0430\u043d\u043e\u043d\u0441\u0430 \u0432 \u0411\u0443\u0444\u0435\u0440\u0435 \u041e\u0431\u043c\u0435\u043d\u0430
+GeneralView.label.trackerurlopen.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440 \u0438\u043b\u0438 \u0430\u043d\u043e\u043d\u0441\n********************************************\n\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435:\n\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u [...]
 #
 # 2.0.4.4
 #
-ConfigView.section.style.guiUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u0430\u0436\u0434\u044b\u0435
-ConfigView.section.style.inactiveUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u043e \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e
-ConfigView.section.style.graphicsUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043a\u0430\u0436\u0434\u044b\u0435 N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
-ConfigView.section.style.reOrderDelay=\u041f\u0435\u0440\u0435\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446 \u043a\u0430\u0436\u0434\u044b\u0435 N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 [0: \u043d\u0438\u043a\u043e\u0433\u0434\u0430]
+ConfigView.section.style.guiUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (GUI) \u043a\u0430\u0436\u0434\u044b\u0435
+ConfigView.section.style.inactiveUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043e\u043a\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0435 N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 GUI, \u043a\u043e\u0433\u0434\u0430 \u043e\u043a\u043d\u043e \u043d\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e
+ConfigView.section.style.graphicsUpdate=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0430\u043d\u0435\u043b\u0435\u0439 \u043a\u0430\u0436\u0434\u044b\u0435 N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 GUI
+ConfigView.section.style.reOrderDelay=\u041f\u0435\u0440\u0435\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u0430\u0431\u043b\u0438\u0446 \u043a\u0430\u0436\u0434\u044b\u0435 N \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 GUI [0: \u043d\u0438\u043a\u043e\u0433\u0434\u0430]
 ConfigView.section.style.reOrderDelay.never=\u041d\u0438\u043a\u043e\u0433\u0434\u0430
-ConfigView.section.logging=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+ConfigView.section.logging=\u041b\u043e\u0433 (\u0436\u0443\u0440\u043d\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u044b)
 ConfigView.section.logging.enable=\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b \u0432 \u0444\u0430\u0439\u043b
 ConfigView.section.logging.logdir=\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u043f\u0430\u043f\u043a\u0443
 ConfigView.section.logging.choosedefaultsavepath=\u0412\u044b\u0431\u043e\u0440 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
-GeneralView.label.updatein.querying=\u0417\u0430\u043f\u0440\u043e\u0441...
-configureWizard.nat.sharePort=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0438\u0439 \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+GeneralView.label.updatein.querying=\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u044e\u0441\u044c...
+configureWizard.nat.sharePort=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0442\u044c \u043e\u0434\u0438\u043d \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
 ConfigView.section.logging.maxsize=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430
-ConfigView.section.tracker.passwordenableweb=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0441\u0435\u0442\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.tracker.passwordenabletorrent=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.tracker.passwordenableweb=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0430 web-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.passwordenabletorrent=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
 ConfigView.section.tracker.username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 ConfigView.section.tracker.password=\u041f\u0430\u0440\u043e\u043b\u044c
 columnChooser.title=\u0412\u044b\u0431\u043e\u0440 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432
-columnChooser.move=\u041e\u0447\u0435\u0440\u0451\u0434\u043d\u043e\u0441\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u0438
-columnChooser.apply=\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c
+columnChooser.move=\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u044f \u0438\u0445 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
+columnChooser.apply=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
 columnChooser.columnname=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u0430
 columnChooser.columndescription=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
-TableColumn.header.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MyTorrentsView.menu.editTableColumns=&\u0421\u0442\u043e\u043b\u0431\u0446\u044b...
-wizard.operationfailed=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
-authenticator.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f
+TableColumn.header.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
+MyTorrentsView.menu.editTableColumns=&\u0412\u044b\u0431\u043e\u0440 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432
+wizard.operationfailed=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0448\u043b\u0430 \u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e
+authenticator.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0432\u043e\u0434 \u043f\u0430\u0440\u043e\u043b\u044f
 authenticator.realm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c
 authenticator.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
 authenticator.user=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 authenticator.password=\u041f\u0430\u0440\u043e\u043b\u044c
 ConfigView.label.allowSendVersion=\u041f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c Vuze \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0443\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043d\u043e\u043c\u0435\u0440\u0430 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u0432\u044b\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043 [...]
-ConfigView.label.version.info.link=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0437\u0434\u0435\u0441\u044c
-wizard.hint.mode=\u0421\u043e\u0432\u0435\u0442:\t\u041c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u0432 \u043e\u043a\u043d\u043e \u043c\u0430\u0441\u0442\u0435\u0440\u0430\n\t\u043d\u0443\u0436\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438\u043b\u0438 \u043f\u0430\u043f\u043a\u0443
-wizard.hint.file=\u0421\u043e\u0432\u0435\u0442:\t\u0412\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430
-wizard.hint.directory=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:\t\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443, \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0432 \u0435\u0451 \u0441\u044e\u0434\u0430
-MainWindow.menu.help.checkupdate=&\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f...
-TableColumn.header.down=\u041f\u0440\u0438\u043d\u044f\u0442\u043e
+ConfigView.label.version.info.link=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u044d\u0442\u043e \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0435\u0440\u0441\u0438\u0439
+wizard.hint.mode=\u0418\u041d\u0424\u041e\u0420\u041c\u0410\u0426\u0418\u042f \u0438 \u0421\u041e\u0412\u0415\u0422\u042b:\n1) \u041c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u0432 \u043e\u043a\u043d\u043e \u043c\u0430\u0441\u0442\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0438\u043b\u0438 \u043f\u0430\u043f\u043a\u0443.\n2) \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u [...]
+wizard.hint.file=\u0421\u043e\u0432\u0435\u0442:\t\t\u0412\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f
+wizard.hint.directory=C\u043e\u0442\u0432\u0435\u0442:\t\u0412\u043e\u0437\u043c\u043e\u0436\u0435\u043d \u0432\u044b\u0431\u043e\u0440 \u043f\u0430\u043f\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f
+MainWindow.menu.help.checkupdate=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+TableColumn.header.down=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
 TableColumn.header.up=\u0420\u043e\u0437\u0434\u0430\u043d\u043e
-ConfigView.section.tracker.passwordenabletorrent.info=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 BitTorrent-\u043a\u043b\u0438\u0435\u043d\u0442 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Vuze)
+ConfigView.section.tracker.passwordenabletorrent.info=\u0422\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 BitTorrent-\u043a\u043b\u0438\u0435\u043d\u0442 (\u043d\u0430\u043f\u0440. Vuze)
 ConfigView.section.style.confirmationOnExit=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435
 MainWindow.dialog.exitconfirmation.title=\u0412\u044b\u0439\u0442\u0438 \u0438\u0437 Vuze
 MainWindow.dialog.exitconfirmation.text=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443?
-SystemTray.menu.stopalltransfers=\u041e&\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-TrayWindow.menu.stopalldownloads=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+SystemTray.menu.stopalltransfers=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+TrayWindow.menu.stopalldownloads=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 ConfigView.section.tracker.sslport.info=\u0421\u043c. FAQ \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438
 wizard.tracker.ssl=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c SSL
-ConfigView.label.playdownloadfinished=\u0417\u0432\u0443\u043a \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-ConfigView.label.popupdownloadfinished=\u0412\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-ConfigView.label.popupfilefinished=\u0412\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430
+ConfigView.label.playdownloadfinished=\u041f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0443
+ConfigView.label.popupdownloadfinished=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435
+ConfigView.label.popupfilefinished=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435
 TableColumn.header.pieces=\u0427\u0430\u0441\u0442\u0438
-TableColumn.header.pieces.info=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439
-TableColumn.header.completion=\u0413\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u044c
-TableColumn.header.completion.info=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 %
-ConfigView.section.style.showdownloadbasket=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a (\u0434\u043b\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435\u043c)
+TableColumn.header.pieces.info=\u0413\u0440\u0430\u0444\u0438\u043a, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u0412\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438
+TableColumn.header.completion=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435
+TableColumn.header.completion.info=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 % \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u0433\u043e
+ConfigView.section.style.showdownloadbasket=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c "\u041a\u043e\u0440\u0437\u0438\u043d\u0443 \u0417\u0430\u0433\u0440\u0443\u0437\u043e\u043a" (\u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b\u044b)
 ConfigView.section.style.alwaysShowTorrentFiles=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e (\u0444\u0430\u0439\u043b\u043e\u0432\u0443\u044e) \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e  \u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u0445
-wizard.multitracker=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0443\u043b\u044c\u0442\u0438\u0442\u0440\u0435\u043a\u0438\u043d\u0433\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e
+wizard.multitracker=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u041c\u0443\u043b\u044c\u0442\u0438-\u0422\u0440\u0435\u043a\u0435\u0440 \u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443
 wizard.multitracker.title=\u041c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440
 wizard.multitracker.configuration=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
-wizard.multitracker.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c...
-wizard.multitracker.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c...
-wizard.multitracker.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+wizard.multitracker.new=\u041d\u043e\u0432\u044b\u0439 ...
+wizard.multitracker.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435...
+wizard.multitracker.delete=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
 wizard.multitracker.group=\u0413\u0440\u0443\u043f\u043f\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432
 wizard.multitracker.edit.title=\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043c\u0443\u043b\u044c\u0442\u0438-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
 wizard.multitracker.edit.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 wizard.multitracker.edit.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
 wizard.multitracker.edit.newgroup=\u041d\u043e\u0432\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430
-wizard.multitracker.edit.deletegroup=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+wizard.multitracker.edit.deletegroup=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
 wizard.multitracker.edit.newtracker=\u041d\u043e\u0432\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-wizard.multitracker.edit.deletetracker=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-wizard.multitracker.edit.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
-wizard.addingmt=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u0443\u043b\u044c\u0442\u0438\u0442\u0440\u0435\u043a\u0438\u043d\u0433\u0430
-wizard.multitracker.noannounce=URL \u0430\u043d\u043e\u043d\u0441\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432
-MyTorrentsView.menu.recheck=\u041f\u0440\u043e&\u0432\u0435\u0440\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b
-iconBar.showDownloadBar.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-iconBar.start.tooltip=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-iconBar.stop.tooltip=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-iconBar.remove.tooltip=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+wizard.multitracker.edit.deletetracker=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+wizard.multitracker.edit.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
+wizard.addingmt=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e \u041c\u0443\u043b\u044c\u0442\u0438-\u0422\u0440\u0435\u043a\u0435\u0440\u0443
+wizard.multitracker.noannounce=URL \u0430\u043d\u043e\u043d\u0441\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432
+MyTorrentsView.menu.recheck=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0445\u044d\u0448-\u0441\u0443\u043c\u043c\u0443
+iconBar.showDownloadBar.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u043a\u0430\u0447\u043a\u0438
+iconBar.start.tooltip=\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443/\u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+iconBar.stop.tooltip=\u041f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443/\u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+iconBar.remove.tooltip=\u0423\u0431\u0440\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430
 iconBar.openNoDefault.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b (\u0431\u0435\u0437 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f)
 iconBar.openURL.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c URL
-iconBar.openFolder.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443
+iconBar.openFolder.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u041f\u0430\u043f\u043a\u0443
 iconBar.new.tooltip=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 iconBar.up.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u0432\u0435\u0440\u0445
-iconBar.down.tooltip=\u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432\u0432\u0435\u0440\u0445
-iconBar.run.tooltip=\u043e\u0442\u043a\u0440\u044b\u0442\u044c
-iconBar.host.tooltip=\u0445\u043e\u0441\u0442
-iconBar.publish.tooltip=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c
-iconBar.editcolumns.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0446\u044b
-MyTorrentsView.menu.editTracker=&\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+iconBar.down.tooltip=\u0421\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u043d\u0438\u0436\u0435
+iconBar.run.tooltip=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443
+iconBar.host.tooltip=\u0425\u043e\u0441\u0442\u0438\u043d\u0433 \u043d\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0435
+iconBar.publish.tooltip=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u043d\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0435 (\u0431\u0435\u0437 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0430)
+iconBar.editcolumns.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u0430
+MyTorrentsView.menu.editTracker=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 GeneralView.menu.selectTracker=\u0412\u044b\u0431\u0440\u0430\u0442\u044c
-ConfigView.section.stats.xslfile=\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430 XSL
-ConfigView.section.stats.xslfiledetails=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0430\u0439\u043b\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0432 \u0442\u0435\u0433 <?xml-stylesheet>
+ConfigView.section.stats.xslfile=\u0418\u043c\u044f XSL \u0444\u0430\u0439\u043b\u0430
+ConfigView.section.stats.xslfiledetails=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0430\u0439\u043b\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0441 \u0442\u044d\u0433\u043e\u043c <?xml-stylesheet>
 ConfigView.label.savetorrentbackup=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u043a\u043e\u043f\u0438\u044e
-ConfigView.section.tracker.forceport=\u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-ConfigView.section.ipfilter.allow=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b (\u043e\u0431\u044b\u0447\u043d\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b)
+ConfigView.section.tracker.forceport=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 \u0434\u043b\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.ipfilter.allow=\u0420\u0410\u0417\u0420\u0415\u0428\u0418\u0422\u042c \u044d\u0442\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u044b (\u043e\u0431\u044b\u0447\u043d\u043e \u0417\u0410\u041f\u0420\u0415\u0429\u0415\u041d\u042b)
 ConfigView.section.ipfilter.list.inrange=\u0431\u044b\u043b \u0432 \u0441\u043f\u0438\u0441\u043a\u0435
-ConfigView.section.ipfilter.list.notinrange=\u041d\u0435 \u0431\u044b\u043b \u043d\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435
-ConfigView.section.ipfilter.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 IP
-ConfigView.label.allowsameip=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441 \u043e\u0434\u043d\u043e\u0433\u043e IP
-ConfigView.label.allowsameip.tooltip=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0422\u041e\u041b\u042c\u041a\u041e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.\n\u0412 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043f\u043e\u043 [...]
-ManagerItem.superseeding=\u0421\u0443\u043f\u0435\u0440-\u0440\u0430\u0437\u0434\u0430\u0447\u0430
-ConfigView.label.userSuperSeeding=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u043f\u0435\u0440-\u0440\u0430\u0437\u0434\u0430\u0447\u0443
-PeersView.uniquepiece=\u0427\u0430\u0441\u0442\u044c (\u0440\u0435\u0436\u0438\u043c \u0441\u0443\u043f\u0435\u0440-\u0440\u0430\u0437\u0434\u0430\u0447\u0438)
+ConfigView.section.ipfilter.list.notinrange=- \u0432\u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0445 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432
+ConfigView.section.ipfilter.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 IP
+ConfigView.label.allowsameip=\u0414\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0432\u044f\u0437\u0435\u0439 \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 IP-\u0430\u0434\u0440\u0435\u0441\u043e\u043c
+ConfigView.label.allowsameip.tooltip=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0438.\n\u0412 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 '\u0 [...]
+ManagerItem.superseeding=\u0421\u0443\u043f\u0435\u0440-\u0420\u0430\u0437\u0434\u0430\u0447\u0430
+ConfigView.label.userSuperSeeding=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0421\u0443\u043f\u0435\u0440-\u0420\u0430\u0437\u0434\u0430\u0447\u0443 (Super-Seed)
+PeersView.uniquepiece=\u0427\u0430\u0441\u0442\u044c (\u0420\u0435\u0436\u0438\u043c \u0421\u0443\u043f\u0435\u0440-\u0420\u0430\u0437\u0434\u0430\u0447\u0438)
 PeersView.uniquepiece.none=\u041d\u0435\u0442
-PeersView.timetosend=\u0412\u0440\u0435\u043c\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0447\u0430\u0441\u0442\u0438 (\u0440\u0435\u0436\u0438\u043c \u0441\u0443\u043f\u0435\u0440-\u0440\u0430\u0437\u0434\u0430\u0447\u0438)
-ConfigView.section.style.addurlsilently=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c URL \u0431\u0435\u0437 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f
-ConfigView.section.style.addurlsilently.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c URL \u0431\u0435\u0437 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.
+PeersView.timetosend=\u0412\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0427\u0430\u0441\u0442\u044c (\u0420\u0435\u0436\u0438\u043c \u0421\u0443\u043f\u0435\u0440-\u0420\u0430\u0437\u0434\u0430\u0447\u0438)
+ConfigView.section.style.addurlsilently=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0438 (URL) \u0431\u0435\u0437 \u0434\u0438\u0430\u043b\u043e\u0433\u0430
+ConfigView.section.style.addurlsilently.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0435\u043d\u043d\u044b\u0435/\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0435 URL\u044b \u0431\u0435\u0437 \u0434\u0438\u0430\u043b\u043e\u0433\u0430 \u043d\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435
 ConfigView.section.file.decoder.prompt=\u041f\u0440\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c
 ConfigView.section.file.decoder.prompt.tooltip=\u041f\u0440\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433
-MyTorrentsView.menu.moveTop=\u0412 &\u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445
-MyTorrentsView.menu.moveEnd=\u0412 \u0441\u0430\u043c\u044b\u0439 &\u043d\u0438\u0437
-ConfigView.label.moveonlyusingdefaultsave=\u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.label.moveonlyusingdefaultsave.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435
-ConfigView.label.watchtorrentfolder=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+MyTorrentsView.menu.moveTop=\u041d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445
+MyTorrentsView.menu.moveEnd=\u0412 \u0441\u0430\u043c\u044b\u0439 \u043d\u0438\u0437
+ConfigView.label.moveonlyusingdefaultsave=\u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435
+ConfigView.label.moveonlyusingdefaultsave.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435
+ConfigView.label.watchtorrentfolder=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043c\u043f\u043e\u0440\u0442 \u043d\u043e\u0432\u044b\u0445 .torrent-\u0444\u0430\u0439\u043b\u043e\u0432
 ConfigView.label.watchtorrentfolder.tooltip=\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u043e\u0432\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-ConfigView.label.watchtorrentfolderinterval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b
+ConfigView.label.watchtorrentfolderinterval=\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a
 ConfigView.label.watchtorrentfolderinterval.tooltip=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0430\u0443\u0437\u044b \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0430\u043f\u043a\u0438
-ConfigView.dialog.choosewatchtorrentfolderpath=\u0412\u044b\u0431\u0435\u0440\u0435\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-ConfigView.label.startwatchedtorrentsstopped=\u041d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+ConfigView.dialog.choosewatchtorrentfolderpath=\u0412\u044b\u0431\u0435\u0440\u0435\u0442\u0435 \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430 .torrent-\u0444\u0430\u0439\u043b\u043e\u0432
+ConfigView.label.startwatchedtorrentsstopped=\u041d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0432 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438
 ConfigView.label.startwatchedtorrentsstopped.tooltip=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0432 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435
-ConfigView.section.plugins=\u041c\u043e\u0434\u0443\u043b\u0438
+ConfigView.section.plugins=\u041f\u043b\u0430\u0433\u0438\u043d\u044b
 wizard.maketorrent.filesize=\u0420\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430(-\u043e\u0432)
-wizard.maketorrent.piececount=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439
-wizard.maketorrent.piecesize=\u0420\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u0441\u0442\u0438
+wizard.maketorrent.piececount=\u041a\u043e\u043b-\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439
+wizard.maketorrent.piecesize=\u0420\u0430\u0437\u043c\u0435\u0440 \u0447\u0430\u0441\u0442\u0435\u0439
 wizard.maketorrent.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
-MainWindow.menu.view.stats=&\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
+MainWindow.menu.view.stats=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
 SpeedView.title.full=\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c 
-SpeedView.downloadSpeed.title=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
+SpeedView.downloadSpeed.title=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 SpeedView.uploadSpeed.title=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 ConfigView.section.style.useSIUnits=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0434\u0438\u043d\u0438\u0446\u044b \u0421\u0418 (KB -> KiB \u0438.\u0442.\u0434.)
-iconBar.top.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0432\u0432\u0435\u0440\u0445
-iconBar.bottom.tooltip=\u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432\u043d\u0438\u0437
-TableColumn.header.health=\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c
-MyTorrentsView.menu.health=\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0430 \u0437\u043d\u0430\u0447\u043a\u043e\u0432
-health.explain.grey=\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 (\u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438)
-health.explain.red=\u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0443\u0437\u043b\u0430\u043c\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442
-health.explain.blue=\u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043d\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c\n\u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u2014 \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d [...]
-health.explain.yellow=\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u0440\u0435\u043a\u0435\u0440 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c\u0438 \u0435\u0441\u0442\u044c, \u043d\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043d\u0435\u044 [...]
-health.explain.green=\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435
-ConfigView.section.style.alwaysRefreshMyTorrents=\u0412\u0441\u0435\u0433\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u00ab\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb
-ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u00ab\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0441\u043a\u0440\u044b\u0442\u0430 (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u [...]
+iconBar.top.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e
+iconBar.bottom.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0446
+TableColumn.header.health=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+MyTorrentsView.menu.health=\u0427\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0442 \u0441\u043c\u0430\u0439\u043b\u0438\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+health.explain.grey=\u041e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d (\u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0438\u043b\u0438 \u043d\u0435 \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0441\u044f).
+health.explain.red=\u041e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0412\u044b \u043d\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441 \u043f\u0438\u0440\u0430\u043c\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.\n\u041b\u0438\u0431\u043e \u043f\u0438\u0440\u043e\u0432 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0442, \u043b\u0438\u0431\u043e \u043d\u0435 \u0443\u0434\u0430\u0435\u0442\u0 [...]
+health.explain.blue=\u041f\u0440\u0438 \u0420\u0410\u0417\u0414\u0410\u0427\u0415 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0412\u044b \u043d\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u043d\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043f\u0438\u0440\u043e\u043c.\n\u041f\u0440\u0438 \u0417\u0410\u0413\u0420\u0423\u0417\u041a\u0415 - \u0447\u0442\u043e \u0412\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441 \u043d\u0435 [...]
+health.explain.yellow=\u041e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u044f \u0442\u0440\u0435\u043a\u0435\u0440 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438 \u0412\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u0441 \u043f\u0438\u0440\u0430\u043c\u0438\n(\u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u04 [...]
+health.explain.green=\u041e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435.
+ConfigView.section.style.alwaysRefreshMyTorrents=\u0412\u0441\u0435\u0433\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c "\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b"
+ConfigView.section.style.alwaysRefreshMyTorrents.tooltip=\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043e\u043a\u043d\u043e "\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b", \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e (\u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u04 [...]
 #
 #2.0.7.0
 #
-security.certtruster.title=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
+security.certtruster.title=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u0421\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0435 \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
 security.certtruster.intro=\u042d\u0442\u043e\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0444\u0438\u0440\u043c\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u043d\u0435 \u0434\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0435
 security.certtruster.resource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a:
 security.certtruster.issuedto=\u0418\u0437\u0434\u0430\u043d \u0434\u043b\u044f:
@@ -733,327 +734,325 @@ security.certtruster.issuedby=\u0418\u0437\u0434\u0430\u0442\u0435\u043b\u044c:
 security.certtruster.prompt=\u0412\u044b \u0434\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0435 \u0435\u043c\u0443?
 security.certtruster.yes=\u0414\u0430
 security.certtruster.no=\u041d\u0435\u0442
-ConfigView.section.tracker.torrentsperpage=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-MainWindow.menu.file.share=&\u0420\u0430\u0437\u0434\u0430\u0442\u044c
+ConfigView.section.tracker.torrentsperpage=\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435? [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+MainWindow.menu.file.share=&\u0420\u0430\u0437\u0434\u0430\u0442\u044c (share)
 MainWindow.menu.file.share.file=&\u0424\u0430\u0439\u043b...
 MainWindow.menu.file.share.dir=&\u041f\u0430\u043f\u043a\u0443...
-MainWindow.menu.file.share.dircontents=&\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438...
-MainWindow.menu.file.share.dircontentsrecursive=\u0421&\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438 \u0432\u0441\u0435\u0445 \u0435\u0451 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a...
+MainWindow.menu.file.share.dircontents=&\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438
+MainWindow.menu.file.share.dircontentsrecursive=\u0421&\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438 \u0432\u0441\u0435\u0445 \u0435\u0435 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a...
 MainWindow.dialog.share.sharefile=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 MainWindow.dialog.share.sharedir=\u0412\u044b\u0431\u043e\u0440 \u043f\u0430\u043f\u043a\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MainWindow.dialog.share.sharedircontents=\u0412\u044b\u0431\u043e\u0440 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u043f\u043a\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+MainWindow.dialog.share.sharedircontents=\u0412\u044b\u0431\u043e\u0440 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 MainWindow.dialog.share.sharedircontents.recursive=\u0418 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0432\u0441\u0435\u0445 \u0435\u0435 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a
-globalmanager.download.remove.veto=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e
-plugin.sharing.download.remove.veto=\u042d\u0442\u043e\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c.\n\u0414\u043b\u044f \u0435\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043e\u043e\u0442 [...]
+globalmanager.download.remove.veto=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u0430
+plugin.sharing.download.remove.veto=\u0414\u0430\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430 - \u044d\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u044f.\n\u0414\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u043 [...]
 ConfigView.section.tracker.main=\u0413\u043b\u0430\u0432\u043d\u0430\u044f
-ConfigView.section.tracker.web=\u0421\u0435\u0442\u044c
-ConfigView.label.prioritizefirstpiece=\u041f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u043e\u0432
-ConfigView.label.prioritizefirstpiece.tooltip=\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430.\n\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441 [...]
-ConfigView.section.file.confirm_data_delete=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445
-ConfigView.section.file.confirm_data_delete.tooltip=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u00ab\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438 \u0441\u0442\u0435\u0440\u0435\u0442\u044c\u00bb
-ConfigView.section.file.delete.include_files_outside_save_dir=\u041f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0438 \u0432\u0441\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432\u043d\u0435 \u043f\u0430\u043f\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+ConfigView.label.prioritizefirstpiece=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u043c \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0447\u0430\u0441\u0442\u044f\u043c \u0444\u0430\u0439\u043b\u0430(\u043e\u0432)
+ConfigView.label.prioritizefirstpiece.tooltip=\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u0444\u0430\u0439\u043b\u0430.\n\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u0440\u043e [...]
+ConfigView.section.file.delete.include_files_outside_save_dir=\u041a\u043e\u0433\u0434\u0430 \u0441\u0442\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043f\u0430\u04 [...]
 TrayWindow.menu.startalldownloads=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-SystemTray.menu.startalltransfers=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-sharing.progress.title=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u0449\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430
+SystemTray.menu.startalltransfers=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+sharing.progress.title=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0440\u0430\u0441\u0448\u0430\u0440\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
 sharing.progress.hide=\u0421\u043a\u0440\u044b\u0442\u044c
-MainWindow.menu.view.myshares=\u0420\u0430\u0437\u0434\u0430\u0447\u0438
-MySharesView.title.full=M\u043e\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MySharesView.name=\u0418\u043c\u044f
+MainWindow.menu.view.myshares=\u041c\u043e\u0438 \u0440\u0430\u0441\u0448\u0430\u0440\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+MySharesView.title.full=\u041c\u043e\u0438 \u0440\u0430\u0441\u0448\u0430\u0440\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+MySharesView.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 MySharesView.type=\u0422\u0438\u043f
-MySharesView.type.file=\u0424\u0430\u0439\u043b
-MySharesView.type.dir=\u041f\u0430\u043f\u043a\u0430
-MySharesView.type.dircontents=\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438
-MySharesView.type.dircontentsrecursive=\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438 \u0432\u0441\u0435\u0445 \u0435\u0451 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a
-MySharesView.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c 
-ConfigView.section.tracker.extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f
-ConfigView.section.tracker.sendpeerids=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0443\u0437\u043b\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u043c
-ConfigView.section.tracker.enableudp=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b UDP \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-plugin.sharing.torrent.remove.veto=\u0414\u0430\u043d\u043d\u0430\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043e\u0431\u0449\u0435\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0435.\n\u0414\u043b\u044f \u0435\u0451 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u043e\u0431\u0449\u0443\u044e \u0440\u0430\u043 [...]
+MySharesView.type.file=\u0444\u0430\u0439\u043b
+MySharesView.type.dir=\u043f\u0430\u043f\u043a\u0430
+MySharesView.type.dircontents=\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043f\u0430\u043f\u043a\u0438
+MySharesView.type.dircontentsrecursive=\u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438 \u0432\u0441\u0435\u0445 \u0435\u0435 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a
+MySharesView.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+ConfigView.section.tracker.extensions=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435
+ConfigView.section.tracker.sendpeerids=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0438\u0440\u0430 \u043b\u0438\u0447\u0435\u0440\u0430\u043c
+ConfigView.section.tracker.enableudp=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c UDP-\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+plugin.sharing.torrent.remove.veto=\u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0435 - \u044d\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 share-\u0440\u0430\u0437\u0434\u0430\u0447\u0438.\n\u0414\u043b\u044f \u0435\u0433\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u0435 share-\u0440\u0430\u0437\u0434\u0430\u0447\u0443.
 plugin.download.remove.veto.notstopped=\u0414\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443.
-plugin.sharing.remove.veto=\u0414\u0430\u043d\u043d\u0430\u044f \u043e\u0431\u0449\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 "\u041f\u0430\u043f\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e" \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0430.\n\u0423\u0434\u0430\u043 [...]
-GeneralView.label.hash.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0445\u0435\u0448 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-ConfigView.section.tracker.maxpeersreturned=\u041c\u0430\u043a\u0441. \u0443\u0437\u043b\u043e\u0432 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.label.serverport=\u041f\u043e\u0440\u0442 TCP/UDP \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
+plugin.sharing.remove.veto=\u0414\u0430\u043d\u043d\u0430\u044f share-\u0440\u0430\u0437\u0434\u0430\u0447\u0430 - \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u043e\u0431\u0449\u0435\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0446\u0435\u043b\u043e\u0439 \u0432\u0435\u0442\u043a\u0438 \u043f\u0430\u043f\u043e\u043a \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u043 [...]
+GeneralView.label.hash.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0445\u044d\u0448-\u0441\u0443\u043c\u043c\u0443 \u0432 \u0411\u0443\u0444\u0435\u0440\u0435 \u041e\u0431\u043c\u0435\u043d\u0430
+ConfigView.section.tracker.maxpeersreturned=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u043d\u044b\u0445 \u043f\u0438\u0440\u043e\u0432 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ConfigView.label.serverport=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0439 TCP/UDP -\u043f\u043e\u0440\u0442 
 ConfigView.label.serverport.tooltip=\u041d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 1 \u0434\u043e 65535, \u043a\u0440\u043e\u043c\u0435 6880 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0 [...]
-configureWizard.nat.server.tcp_listen_port=\u041f\u043e\u0440\u0442 TCP \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
-ConfigView.section.sharing=\u041e\u0431\u0449\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430
+configureWizard.nat.server.tcp_listen_port=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0439 TCP-\u043f\u043e\u0440\u0442 
+ConfigView.section.sharing=Share-\u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b (\u0441\u0432\u043e\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u044b)
 ConfigView.section.sharing.usessl=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c SSL \u0434\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u0440\u0430\u0437\u0434\u0430\u0447 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
-ConfigView.section.style.dropdiraction=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u0430\u043f\u043e\u043a
-ConfigView.section.style.dropdiraction.opentorrents=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-ConfigView.section.style.dropdiraction.sharefolder=\u0420\u0430\u0437\u0434\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443
-ConfigView.section.style.dropdiraction.sharefoldercontents=\u0420\u0430\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435
+ConfigView.section.style.dropdiraction=\u041e\u043f\u0446\u0438\u044f "Drag and Drop" \u0434\u043b\u044f \u043f\u0430\u043f\u043e\u043a
+ConfigView.section.style.dropdiraction.opentorrents=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.section.style.dropdiraction.sharefolder=\u0420\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u0430\u043f\u043a\u0430
+ConfigView.section.style.dropdiraction.sharefoldercontents=\u0420\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
 #
 # 2.0.7.x
 #
 Categories.all=\u0412\u0441\u0435
 Categories.uncategorized=\u0411\u0435\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439
-CategoryAddWindow.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
+CategoryAddWindow.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
 CategoryAddWindow.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e
-ConfigView.label.autoSeedingIgnoreInfo=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0438 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u044 [...]
+ConfigView.label.autoSeedingIgnoreInfo=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0438 \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u044 [...]
 ConfigView.label.directory=\u041f\u0430\u043f\u043a\u0430
-ConfigView.label.disconnetseed.tooltip=\u041f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u043c\u0438.\n\u041a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u043d\u0438\u043c\u0438 \u043d\u [...]
-ConfigView.label.ignoreCase=\u041d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0433\u0438\u0441\u0442\u0440
-ConfigView.label.ignoreSeeds=\u041e\u0442\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0447\u0435\u043c
+ConfigView.label.disconnetseed.tooltip=\u041f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0438\u0434\u043e\u0432.\n\u041a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u043d\u0438\u043c\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u0430.
+ConfigView.label.ignoreCase=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0420\u0435\u0433\u0438\u0441\u0442\u0440
+ConfigView.label.ignoreSeeds=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0447\u0435\u043c
 ConfigView.label.importdirectory=\u041f\u0430\u043f\u043a\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0430
-ConfigView.label.minPeersToBoostNoSeeds.tooltip=\u0412\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0431\u0435\u0437 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0438\u043b\u0438 \u043a\u0430\u0447\u0430\u044e\u0449\u0438\u0445 \u043c\u0435\u043d\u0435\u0435 \n\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u0432\u0432\u0435\u0440\u0445 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-ConfigView.label.minPeersToBoostNoSeeds=\u041f\u043e\u043d\u0438\u0436\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0431\u0435\u0437 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0438
-ConfigView.label.minSeedingTime.tooltip=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043f\u0440\u0438\u0 [...]
-ConfigView.label.minSeedingTime=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445
-ConfigView.label.minSpeedForActiveDL.tooltip=\u0421\u043b\u043e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043d\u044f\u0442\u044b\u043c \u0432 \u043f\u0435\u0440\u0432\u044b\u0435 30 \u0441\u0435\u043a\u0443\u043d\u0434\n\u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043d\u0435\u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0433\u043e  [...]
-ConfigView.label.minSpeedForActiveDL=\u041d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0438\u0436\u0435, \u0447\u0435\u043c
-ConfigView.label.peers=\u0443\u0437\u043b\u043e\u0432
+ConfigView.label.minPeersToBoostNoSeeds.tooltip=\u041b\u044e\u0431\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0431\u0435\u0437 \u0441\u0438\u0434\u043e\u0432 \u0438 \u0438\u043c\u0435\u044e\u0449\u0438\u0445 \u043c\u0435\u043d\u044c\u0448\u0435 \u043b\u0438\u0447\u0435\u0440\u043e\u0432, \u0447\u0435\u043c \u0412\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438,\n\u0434\u0432\u0438\u0433\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0446 \u043e\u0447\u0435\u0440\ [...]
+ConfigView.label.minPeersToBoostNoSeeds=\u0417\u0430\u043d\u0438\u0436\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0431\u0435\u0437 \u0441\u0438\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c
+ConfigView.label.minSeedingTime.tooltip=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043c\u043e\u0433\u0443\u0442 \u0437\u0430 \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0447\u0430\u0441\u0442\u043e \u0432\u0430\u0440\u044c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f,\n\u0447\u0442\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e \ [...]
+ConfigView.label.minSeedingTime=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 [\u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445]
+ConfigView.label.minSpeedForActiveDL.tooltip=\u0421\u043b\u043e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \n\u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043d\u0435\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u043e\u0440\ [...]
+ConfigView.label.minSpeedForActiveDL=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043b\u043e\u0442 \u0437\u0430\u043a\u0430\u0447\u043a\u0438, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0438\u0436\u0435 \u0447\u0435\u043c
+ConfigView.label.peers=\u043b\u0438\u0447\u0435\u0440\u043e\u0432
 ConfigView.label.queue.debuglog=\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e
-ConfigView.label.queue.debuglog.info=\u0412\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0444\u0430\u0439\u043b \u0436\u0443\u0440\u043d\u0430\u043b\u0430.\n\u0425\u043e\u0442\u044f \u043e\u043d\u0430 \u0438 \u0442\u0440\u0443\u0434\u043d\u043e\u0447\u0438\u [...]
-ConfigView.label.queue.minQueueingShareRatio=\u041d\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0434\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0432\u044b\u0448\u0435
-ConfigView.label.ratio=\u0440\u0435\u0439\u0442\u0438\u043d\u0433
+ConfigView.label.queue.debuglog.info=\u0412\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0438 \u0444\u0430\u0439\u043b \u0436\u0443\u0440\u043d\u0430\u043b\u0430.\n\u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0 [...]
+ConfigView.label.queue.minQueueingShareRatio=\u041d\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0434\u043e \u0420\u0435\u0439\u0442\u0438\u043d\u0433\u0430 \u041e\u0431\u043c\u0435\u043d\u0430 \u0432\u044b\u0448\u0435
+ConfigView.label.ratio=\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435
 ConfigView.label.removeOnStop=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u043e\u0441\u043b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-ConfigView.label.savedirectory=\u041f\u0430\u043f\u043a\u0430
-ConfigView.label.seeding.autoReposition.tooltip=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 (\u0441\u0442\u043e\u043b\u0431\u0435\u0446 \u00ab\u2116\u00bb) \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u044 [...]
-ConfigView.label.seeding.autoReposition=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u0427\u0430\u0441\u0442\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u043c\u0430\u043b\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0443\u0437\u043b\u043e\u0432  [...]
-ConfigView.label.seeding.fakeFullCopySeedStart=\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0447\u0435\u043c
-ConfigView.label.seeding.ignore=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-ConfigView.label.seeding.ignore0Peers=\u041e\u0442\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 0 \u0443\u0437\u043b\u043e\u0432
-ConfigView.label.seeding.ignoreRatioPeers=\u041e\u0442\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 1 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0435
-ConfigView.label.seeding.ignoreShareRatio=\u041e\u0442\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.seeding.ignore.header.evenFirstPriority=\u041e\u0442\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0434\u0430\u0436\u0435\n\u0435\u0441\u043b\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u044b\u0441\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430
+ConfigView.label.savedirectory=\u041f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+ConfigView.label.seeding.autoReposition.tooltip=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u0442\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 (\u0441\u0442\u043e\u043b\u0431\u0435\u0446 '\u2116') \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0443 \u [...]
+ConfigView.label.seeding.autoReposition=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e \u0440\u0430\u043d\u0433\u0443 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+ConfigView.label.seeding.fakeFullCopySeedStart.tooltip=\u0427\u0430\u0441\u0442\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u043c\u0430\u043b\u044b\u043c \u043a\u043e\u043b-\u0432\u043e\u043c \u0441\u0438\u0434\u043e\u0432 \u0438 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043b\u0438\u0447\u0435\u0440\u043e\u0432 \u0433\u043e\u0432\u043e\u0440\u0438\u044 [...]
+ConfigView.label.seeding.fakeFullCopySeedStart=\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0447\u0435\u043c
+ConfigView.label.seeding.ignore=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+ConfigView.label.seeding.ignore0Peers=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 0 \u043b\u0438\u0447\u0435\u0440\u043e\u0432
+ConfigView.label.seeding.ignoreRatioPeers=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 1 \u0441\u0438\u0434\u0430 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0435
+ConfigView.label.seeding.ignoreShareRatio=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
+ConfigView.label.seeding.ignore.header.evenFirstPriority=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438\n\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0412\u044b\u0441\u0448\u0435\u0433\u043e \u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430
 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\u0438\u0435
-ConfigView.label.seeding.firstPriority.info=\u0412\u044b\u0441\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438. \u0422\u043e\u0440\u0440\u0435\u043d\u044 [...]
-ConfigView.label.seeding.firstPriority.FP=\u0412\u044b\u0441\u0448\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.label.seeding.firstPriority=\u041f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c \u0432\u044b\u0441\u0448\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b
-ConfigView.label.seeding.firstPriority.following=\u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439:
-ConfigView.label.seeding.firstPriority.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043c\u0435\u043d\u0435\u0435
-ConfigView.label.seeding.firstPriority.seedingMinutes=\u041f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0441\u043c\u0435\u043d\u044b \u0440\u0435\u0436\u0438\u043c\u0430 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u043d\u0430 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.seeding.firstPriority.DLMinutes=\u041f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u043a\u0430\u0447\u043a\u0438
-ConfigView.label.seeding.numPeersAsFullCopy.tooltip=\u0414\u043e\u043f\u0443\u0441\u043a\u0430\u044f, \u0447\u0442\u043e \u0441\u0440\u0435\u0434\u0438 X \u0443\u0437\u043b\u043e\u0432 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f, \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u04 [...]
-ConfigView.label.seeding.numPeersAsFullCopy=\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438 \u043a\u0430\u0436\u0434\u044b\u0435\n[0: \u043d\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c]
-ConfigView.label.seeding.preferLargerSwarms.tooltip=\u0415\u0441\u043b\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u0438\u043c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u043c \u0443\u0437\u043b\u0430\u043c, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u00ab\u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0431\u043 [...]
-ConfigView.label.seeding.preferLargerSwarms=\u0421\u0440\u0435\u0434\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0443\u0437\u043b\u043e\u0432
-ConfigView.label.seeding.rankType.none.tooltip=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u0443 \u00ab\u2116\u00bb
-ConfigView.label.seeding.rankType.none=\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e
-ConfigView.label.seeding.rankType.peer.tooltip=\u0411\u043e\u043b\u044c\u0448\u0435 \u0443\u0437\u043b\u043e\u0432 \u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 = \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\n\u041f\u043e\u0434\u043e\u0431\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u0430\u043a\u0441\u0438\u043c\u0438\u0437\u0438\u0440 [...]
-ConfigView.label.seeding.rankType.peer=\u0412\u0437\u0432\u0435\u0448\u0435\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432
-ConfigView.label.seeding.rankType.peerSeed.options=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435:\u0443\u0437\u043b\u044b
-ConfigView.label.seeding.rankType.peerSeed.tooltip=\u0412\u044b\u0448\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u2014 \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.label.seeding.rankType.peerSeed=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0443\u0437\u043b\u044b:\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435
-ConfigView.label.seeding.rankType.seed.fallback=\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u0443\u0437\u043b\u044b:\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435 \u0447\u0435\u0440\u0435\u0437\n [0: \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f]
-ConfigView.label.seeding.rankType.seed.options=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
-ConfigView.label.seeding.rankType.seed.tooltip=\u041c\u0435\u043d\u044c\u0448\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u2014 \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.label.seeding.rankType.seed=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
-ConfigView.label.seeding.rankType.timedRotation.tooltip=\u0412\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e\u043e\u0447\u0435\u0440\u0451\u0434\u043d\u043e \u0441\u0442\u0430\u0432\u044f\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438.\n\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u043a\u0430\u0437\u044b\u04 [...]
-ConfigView.label.seeding.rankType.timedRotation=\u041e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438
-ConfigView.label.seeding.rankType.tooltip=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u043d\u0430\u0438\u0432\u044b\u0441\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\n\u0415\u0441\u043b\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0431\u043e\u043b\u0435\ [...]
-ConfigView.label.seeding.rankType=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043a\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f:
+ConfigView.label.seeding.firstPriority.info=\u0412\u044b\u0441\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0435\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.\n\u0422\u043e\u0440\u0440\u0435\u043d\u04 [...]
+ConfigView.label.seeding.firstPriority.FP=\u0412\u044b\u0441\u0448\u0438\u0439 \u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+ConfigView.label.seeding.firstPriority=\u0412\u044b\u0441\u0448\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043e\u0442\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c
+ConfigView.label.seeding.firstPriority.following=\u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432:
+ConfigView.label.seeding.firstPriority.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u043e\u0431\u043c\u0435\u043d\u0430 \u043c\u0435\u043d\u0435\u0435
+ConfigView.label.seeding.firstPriority.seedingMinutes=\u041f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0441\u043c\u0435\u043d\u044b \u0440\u0435\u0436\u0438\u043c\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+ConfigView.label.seeding.firstPriority.DLMinutes=\u041f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+ConfigView.label.seeding.numPeersAsFullCopy.tooltip=\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044f 1 \u043f\u043e\u043b\u043d\u0443\u044e \u043a\u043e\u043f\u0438\u044e \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0435 \u0425 \u043b\u0438\u0447\u0435\u0440\u043e\u0432, \u0412\u044b \u0441\u043d\u0438\u0436\u0430\u0435\u0442\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0431\u043e\u043b\u044 [...]
+ConfigView.label.seeding.numPeersAsFullCopy=\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 [0 : \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0439]
+ConfigView.label.seeding.preferLargerSwarms.tooltip=\u0415\u0441\u043b\u0438 \u0412\u044b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0441\u0438\u0434\u0438\u0440\u0443\u0435\u0442\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 "\u0442\u043e\u0440\u043c\u043e\u0437\u043d\u044b\u043c\u0438" \u043f\u0438\u0440\u0430\u043c\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f "\u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435 [...]
+ConfigView.label.seeding.preferLargerSwarms=\u0421\u0440\u0435\u0434\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0430\u0442\u044c \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u0431\u041e\u043b\u044c\u0448\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u0438\u0440\u043e\u0432.
+ConfigView.label.seeding.rankType.none.tooltip=\u041f\u043e\u0440\u044f\u0434\u043e\u043a, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u2116 \u0441\u0442\u043e\u043b\u0431\u0446\u0430
+ConfigView.label.seeding.rankType.none=\u041d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c
+ConfigView.label.seeding.rankType.peer.tooltip=\u0411\u043e\u043b\u044c\u0448\u0435 \u043b\u0438\u0447\u0435\u0440\u043e\u0432 \u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0438\u0434\u043e\u0432 = \u0432\u044b\u0448\u0435 \u0440\u0430\u043d\u0433 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\n\u0422\u0430\u043a\u043e\u0439 \u0440\u0430\u043d\u0433 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043 [...]
+ConfigView.label.seeding.rankType.peer=\u0412\u0437\u0432\u0435\u0448\u0435\u043d\u043d\u043e\u0435 \u0427\u0438\u0441\u043b\u043e \u041b\u0438\u0447\u0435\u0440\u043e\u0432
+ConfigView.label.seeding.rankType.peerSeed.options=\u0414\u043e\u043d\u043e\u0440\u0430\u043c\u0438: \u041f\u043e \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+ConfigView.label.seeding.rankType.peerSeed.tooltip=\u0427\u0435\u043c \u0432\u044b\u0448\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435, \u0442\u0435\u043c \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+ConfigView.label.seeding.rankType.peerSeed=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u041b\u0438\u0447\u0435\u0440\u044b:\u0421\u0438\u0434\u044b
+ConfigView.label.seeding.rankType.seed.fallback=\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u041b\u0438\u0447\u0435\u0440\u044b:\u0421\u0438\u0434\u044b \u043f\u043e\u0441\u043b\u0435\n [0 : \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f]
+ConfigView.label.seeding.rankType.seed.options=\u041e\u043f\u0446\u0438\u0438 '\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0421\u0438\u0434\u043e\u0432'
+ConfigView.label.seeding.rankType.seed.tooltip=\u041c\u0435\u043d\u044c\u0448\u0435 \u0421\u0438\u0434\u043e\u0432 = \u0412\u044b\u0448\u0435 \u0420\u0430\u043d\u0433
+ConfigView.label.seeding.rankType.seed=\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0421\u0438\u0434\u043e\u0432
+ConfigView.label.seeding.rankType.timedRotation.tooltip=\u0412\u0441\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e\u043e\u0447\u0435\u0440\u0451\u0434\u043d\u043e \u0441\u0442\u0430\u0432\u044f\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438.\n\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0 [...]
+ConfigView.label.seeding.rankType.timedRotation=\u0420\u043e\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438
+ConfigView.label.seeding.rankType.tooltip=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u043d\u0430\u0438\u0432\u044b\u0441\u0448\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0443\u044e\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\n\u0415\u0441\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\ [...]
+ConfigView.label.seeding.rankType=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f:
 ConfigView.label.stopAfterMinutes=\u0417\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u0443\u044e \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438
-ConfigView.label.switchpriority.tooltip=\u041d\u0438\u0437\u043a\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430.
-ConfigView.pluginlist.info=\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.
-ConfigView.pluginlist.noplugins=\u041c\u043e\u0434\u0443\u043b\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b.
+ConfigView.label.switchpriority.tooltip=\u041d\u0438\u0437\u043a\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u043e\u043d\u0438\u0436\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443.
+ConfigView.pluginlist.info=\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0433\u0443\u0442 \u043d\u0435 \u0438\u043c\u0435\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.
+ConfigView.pluginlist.noplugins=\u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e
 ConfigView.section.pluginslist=\u0421\u043f\u0438\u0441\u043e\u043a
 ConfigView.section.queue.seeding=\u0420\u0430\u0437\u0434\u0430\u0447\u0430
-ConfigView.section.queue.seeding.autoStarting=\u0410\u0432\u0442\u043e\u0437\u0430\u043f\u0443\u0441\u043a
+ConfigView.section.queue.seeding.autoStarting=\u0410\u0432\u0442\u043e-\u0437\u0430\u043f\u0443\u0441\u043a
 ConfigView.section.queue.seeding.ignore=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-ConfigView.section.queue.seeding.firstPriority=\u0412\u044b\u0441\u0448\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+ConfigView.section.queue.seeding.firstPriority=\u0412\u044b\u0441\u0448\u0438\u0439 \u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
 ConfigView.section.queue.main=\u0413\u043b\u0430\u0432\u043d\u0430\u044f
-ConfigView.section.queue=\u041e\u0447\u0435\u0440\u0435\u0434\u044c
+ConfigView.section.queue=\u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
 ConfigView.section.torrents=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-ConfigView.text.all=\u0432\u0441\u0435
+ConfigView.text.all=\u0441\u043e \u0432\u0441\u0435\u043c\u0438
 ConfigView.text.hours=\u0447\u0430\u0441\u043e\u0432
-ConfigView.text.ignoreRule=\u041f\u0440\u0430\u0432\u0438\u043b\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e
-ConfigView.text.ignore=\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+ConfigView.text.ignoreRule=\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e
+ConfigView.text.ignore=\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c
 ConfigView.text.minutes=\u043c\u0438\u043d\u0443\u0442
-ConfigView.text.neverIgnore=\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-ConfigView.text.any=\u043b\u044e\u0431\u044b\u0435
-DownloadManager.error.datamissing=\u0414\u0430\u043d\u043d\u044b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442
-MainWindow.menu.file.open.torrentforseeding=\u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438)
+ConfigView.text.neverIgnore=\u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u0431\u0438\u0432\u0430\u0442\u044c
+ConfigView.text.any=\u0441 \u043b\u044e\u0431\u044b\u043c\u0438
+DownloadManager.error.datamissing=\u041d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445!
+MainWindow.menu.file.open.torrentforseeding=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 (\u0414\u043b\u044f \u0420\u0430\u0437\u0434\u0430\u0447\u0438)
 MainWindow.menu.language.refresh=&\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
-ManagerItem.forced=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e
-ManagerItem.queued=\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-MySeedersView.header=\u0417\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435/\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-TableColumn.header.availability.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439
+ManagerItem.forced=\u0424\u043e\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f
+ManagerItem.queued=\u0412 \u041e\u0447\u0435\u0440\u0435\u0434\u0438
+MySeedersView.header=\u0417\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+TableColumn.header.availability.info=\u041a\u043e\u043b. \u043f\u043e\u043b\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u0437\u0430\u043c\u0435\u0447\u0435\u043d\u043e
 TableColumn.header.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
 TableColumn.header.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f
-MyTorrentsView.header=\u041d\u0435\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435/\u0433\u0440\u0443\u0437\u044f\u0449\u0438\u0435\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
-TableColumn.header.maxuploads=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447
+MyTorrentsView.header=\u041d\u0435\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+TableColumn.header.maxuploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b. \u0440\u0430\u0437\u0434\u0430\u0447
 MyTorrentsView.menu.category.delete=&\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e
-MyTorrentsView.menu.forceStart=&\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e
-MyTorrentsView.menu.queue=&\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
+MyTorrentsView.menu.forceStart=&\u0424\u043e\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0421\u0442\u0430\u0440\u0442
+MyTorrentsView.menu.queue=&\u0412 \u041e\u0447\u0435\u0440\u0435\u0434\u044c
 MyTorrentsView.menu.setCategory.add=&\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e...
 MyTorrentsView.menu.setCategory=\u0417\u0430\u0434\u0430\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e
-TableColumn.header.savepath=\u041f\u0443\u0442\u044c
-TableColumn.header.SeedingRank=\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.totalspeed.info=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u0445 \u0441 \u0432\u0430\u043c\u0438 \u0443\u0437\u043b\u043e\u0432
+TableColumn.header.savepath=\u041c\u0435\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+TableColumn.header.SeedingRank=\u0420\u0430\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+TableColumn.header.totalspeed.info=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u0438\u0440\u043e\u0432, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0412\u044b \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0435\u043d\u0435\u043d\u044b
 TableColumn.header.totalspeed=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
-splash.initializePlugins=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-StartStopRules.SPratioMet=S:P \u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 OK
-StartStopRules.FP0Peers=FP / 0 \u0443\u0437\u043b\u043e\u0432
-StartStopRules.0Peers=0 \u0443\u0437\u043b\u043e\u0432
-StartStopRules.numSeedsMet=# \u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435 OK
-StartStopRules.ratioMet=\u0423\u0437\u043b\u044b:\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0439 OK
-StartStopRules.shareRatioMet=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 OK
+splash.initializePlugins=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+StartStopRules.SPratioMet=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0421\u0438\u0434/\u041b\u0438\u0447\u0435\u0440 - OK
+StartStopRules.FP0Peers=FP / 0 \u041b\u0438\u0447\u0435\u0440\u043e\u0432
+StartStopRules.0Peers=0 \u041b\u0438\u0447\u0435\u0440\u043e\u0432
+StartStopRules.numSeedsMet=\u041a\u043e\u043b. \u0421\u0438\u0434\u043e\u0432 - OK
+StartStopRules.ratioMet=\u041b\u0438\u0447\u0435\u0440\u044b/\u0421\u0438\u0434\u044b - OK
+StartStopRules.shareRatioMet=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 - OK
 StartStopRules.waiting=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435
-StartStopRules.firstPriority=\u0412\u044b\u0441\u0448\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\u0420\u0430\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 (\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e)
-DownloadManager.error.unabletostartserver=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430/\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\ [...]
+StartStopRules.firstPriority=\u0412\u044b\u0441\u0448\u0438\u0439 \u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+ConfigView.section.style.dropdiraction.sharefoldercontentsrecursive=\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438 \u0432\u0441\u0435\u0445 \u0435\u0435 \u043f\u043e\u0434\u043f\u0430\u043f\u043e\u043a
+DownloadManager.error.unabletostartserver=\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0441\u044f - \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430 \u0438\u043b\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u0440 [...]
 GeneralView.label.creationdate=\u0421\u043e\u0437\u0434\u0430\u043d:
-ConfigView.section.tracker.announcescrapepercentage=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 % \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0438\u0437\u043d\u0438 \u0430\u043d\u043e\u043d\u0441\u0430\n\u0442.\u0435. 200 = 2:1. [0: \u043d\u0430 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430]
-ManagerItem.stopping=\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430
-ConfigView.section.tracker.announcecacheperiod=\u041a\u044d\u0448 \u0430\u043d\u043e\u043d\u0441\u0430 (\u043c\u0441)
-ConfigView.section.tracker.scrapecacheperiod=\u041a\u044d\u0448 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 (\u043c\u0441)
-ConfigView.section.tracker.scrapeandcache=\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043a\u044d\u0448
-ConfigView.section.tracker.announcecacheminpeers=\u041a\u044d\u0448 \u0430\u043d\u043e\u043d\u0441\u043e\u0432 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u043f\u043e\u0440\u043e\u0433 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
-MyTrackerView.scrapes=\u0417\u0430\u043f\u0440\u043e\u0441\u043e\u0432
+ConfigView.section.tracker.announcescrapepercentage=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u043f\u0440\u043e\u0441\u0430 \u043a\u0430\u043a % \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430 \u0430\u043d\u043e\u043d\u0441\u0430\n\u0442.\u0435. 200 = 2:1. 0  = \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0438\u0440
+ManagerItem.stopping=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430...
+ConfigView.section.tracker.announcecacheperiod=\u041a\u044d\u0448 \u0430\u043d\u043e\u043d\u0441\u0430 [\u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b]
+ConfigView.section.tracker.scrapecacheperiod=\u041a\u044d\u0448 scrape-\u043e\u043f\u0440\u043e\u0441\u043e\u0432 [\u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b]
+ConfigView.section.tracker.scrapeandcache=Scrape-\u043e\u043f\u0440\u043e\u0441\u044b \u0438 \u043a\u044d\u0448
+ConfigView.section.tracker.announcecacheminpeers=\u041f\u043e\u0440\u043e\u0433 \u043a\u043e\u043b-\u0432\u0430 \u043f\u0438\u0440\u043e\u0432 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430 \u0430\u043d\u043e\u043d\u0441\u043e\u0432
+MyTrackerView.scrapes=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0445
 fileDownloadWindow.retry=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c
-MyTrackerView.bytesin=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e, \u0411
-MyTrackerView.bytesinave=\u0421\u0440. \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
-MyTrackerView.bytesout=\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e, \u0411
-MyTrackerView.bytesoutave=\u0421\u0440. \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
-ConfigView.section.file.max_open_files=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f/\u0437\u0430\u043f\u0438\u0441\u0438\n[0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+MyTrackerView.bytesin=\u0411\u0430\u0439\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
+MyTrackerView.bytesinave=\u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
+MyTrackerView.bytesout=\u0411\u0430\u0439\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
+MyTrackerView.bytesoutave=\u0412 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
+ConfigView.section.file.max_open_files=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f/\u0437\u0430\u043f\u0438\u0441\u0438\n[0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
 ConfigView.section.file.max_open_files.tooltip=\u041f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043e\u0442\u043d\u044f\u043c\u0438/\u0442\u044b\u0441\u044f\u0447\u0430\u043c\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u [...]
-ConfigView.section.proxy=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u043a\u0441\u0438
+ConfigView.section.proxy=\u041f\u0440\u043e\u043a\u0441\u0438
 ConfigView.section.proxy.enable_proxy=\u0414\u043e\u0441\u0442\u0443\u043f \u0447\u0435\u0440\u0435\u0437 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440
-ConfigView.section.proxy.host=\u0418\u043c\u044f \u0443\u0437\u043b\u0430
+ConfigView.section.proxy.host=\u0425\u043e\u0441\u0442
 ConfigView.section.proxy.port=\u041f\u043e\u0440\u0442
 ConfigView.section.proxy.username=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 ConfigView.section.proxy.password=\u041f\u0430\u0440\u043e\u043b\u044c
-ConfigView.section.proxy.enable_socks=SOCKS-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440
-wizard.createtorrent.extrahashes=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0445\u0435\u0448\u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0442\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Gnutella2, ed2k)
+ConfigView.section.proxy.enable_socks=\u0423 \u043c\u0435\u043d\u044f SOCKS-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440
+wizard.createtorrent.extrahashes=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0445\u044d\u0448-\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e (hash) \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0442\u0435\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Gnutella2, eDonkey2000)
 GeneralView.label.connected=\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e
-GeneralView.label.in_swarm=\u0432\u0441\u0435\u0433\u043e
-ManagerItem.initializing=\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f
+GeneralView.label.in_swarm=\u0432 \u0433\u0440\u0443\u043f\u043f\u0435 
+ManagerItem.initializing=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f...
 AlertMessageBox.error=\u041e\u0448\u0438\u0431\u043a\u0430
-AlertMessageBox.warning=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435
+AlertMessageBox.warning=\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415
 AlertMessageBox.comment=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
 AlertMessageBox.information=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
-AlertMessageBox.unread=\u0415\u0441\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f \u2014 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0437\u0434\u0435\u0441\u044c.
-SharedPortServer.alert.selectorfailed=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445.\n\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u044d\u043a\u0440\u0430\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0 [...]
-Tracker.alert.listenfail=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u0440\u0442\u0430 %1.\n\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436 [...]
-DiskManager.alert.movefileexists=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043f\u0440\u0438\u043d\u044f\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043ba.\n\u0424\u0430\u0439\u043b %1 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
-DiskManager.alert.movefilefails=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430.\n\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0444\u0430\u0439\u043b %1, %2
-DiskManager.alert.movefilerecoveryfails=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f\n\u0424\u0430\u0439\u043b %1 \u043d\u0435 \u0431\u044b\u043b \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435 [...]
-ConfigView.section.tracker.logenable=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0432 \u00abtracker.log\u00bb
+AlertMessageBox.unread=\u0423 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f - \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c.
+SharedPortServer.alert.selectorfailed=\u041d\u0435 \u0443\u0434\u0430\u0435\u0442\u0441\u044f \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.\n\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0432\u0430\u0448 \u0444\u0430\u0439\u0440\u0432\u043e\u043b\u043b, \u0447\u0442\u043e\u0431\u044b \u043f\u [...]
+Tracker.alert.listenfail=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u043e\u0440\u0442\u0430 \u0441\u0432\u044f\u0437\u0438 %1.\n\u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u0440\u0438\u043b\u043 [...]
+DiskManager.alert.movefileexists=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043ba.\n\u0424\u0430\u0439\u043b %1 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430
+DiskManager.alert.movefilefails=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430.\n\u041f\u0435\u0440\u0435\u043d\u043e\u0441 \u0444\u0430\u0439\u043b\u0430 %1 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f, %2
+DiskManager.alert.movefilerecoveryfails=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0444\u0430\u0439\u043b\u0430 %1, %2
+ConfigView.section.tracker.logenable=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \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\u0435\u0433\u043e
-SpeedView.stats.session=\u042d\u0442\u043e\u0442 \u0441\u0435\u0430\u043d\u0441
-SpeedView.stats.session.tooltip=\u0412\u0441\u0435\u0433\u043e (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
-SpeedView.stats.downloaded=\u041f\u0440\u0438\u043d\u044f\u0442\u043e (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
-SpeedView.stats.uploaded=\u0420\u043e\u0437\u0434\u0430\u043d\u043e (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
-SpeedView.stats.ratio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433
-SpeedView.stats.uptime=\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b
+SpeedView.stats.session=\u042d\u0442\u0430 \u0441\u0435\u0441\u0441\u0438\u044f
+SpeedView.stats.session.tooltip=\u0412\u0441\u0435\u0433\u043e (\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
+SpeedView.stats.downloaded=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e (\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
+SpeedView.stats.uploaded=\u041e\u0442\u0434\u0430\u043d\u043e (\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
+SpeedView.stats.ratio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
+SpeedView.stats.uptime=\u0412\u0440\u0435\u043c\u044f \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b (\u0432 \u0447\u0430\u0441\u0430\u0445)
 SpeedView.stats.now=\u0421\u0435\u0439\u0447\u0430\u0441
-SpeedView.stats.now.tooltip=\u0412\u0441\u0435\u0433\u043e (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
-AutoMigration.useralert=\u0418\u043c\u043f\u043e\u0440\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u0430\u043f\u043e\u043a:\n\n%1\n\u0412\u0441\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u044b \u0432\u0440\u044 [...]
+SpeedView.stats.now.tooltip=\u0412\u0441\u0435\u0433\u043e (\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)
+AutoMigration.useralert=\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0430\u0432\u0442\u043e-\u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u0430\u043f\u043e\u043a Vuze:\n\n%1\n\u0412\u0441\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\ [...]
 #
 # > 2.0.8.0
 #
 OpenTorrentWindow.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442(\u044b)
 OpenTorrentWindow.message=\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e
-OpenTorrentWindow.addFiles=&\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b
-OpenTorrentWindow.dataLocation=\u041c\u0435\u0441\u0442\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445:
-OpenTorrentWindow.startMode=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0436\u0438\u043c
-OpenTorrentWindow.startMode.queued=\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
+OpenTorrentWindow.addFiles=&\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+OpenTorrentWindow.dataLocation=\u041c\u0435\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445:
+OpenTorrentWindow.startMode=\u0420\u0435\u0436\u0438\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f
+OpenTorrentWindow.startMode.queued=\u0412 \u041e\u0447\u0435\u0440\u0435\u0434\u0438
 OpenTorrentWindow.startMode.stopped=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-OpenTorrentWindow.startMode.forceStarted=\u0423\u0441\u043a\u043e\u0440\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a
+OpenTorrentWindow.startMode.forceStarted=\u0424\u043e\u0440\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0417\u0430\u043f\u0443\u0441\u043a
 OpenTorrentWindow.addPosition=\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
 OpenTorrentWindow.addPosition.first=\u041f\u0435\u0440\u0432\u0430\u044f
 OpenTorrentWindow.addPosition.last=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f
-TableColumn.header.remaining.info=\u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044c
+TableColumn.header.remaining.info=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c
 TableColumn.header.remaining=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c
-ConfigView.section.tracker.enablecompact=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u043d\u043e\u043d\u0441\u043e\u0432
-ConfigView.section.tracker.enablekey=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u043d\u043e\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
+ConfigView.section.tracker.enablecompact=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0430\u043d\u043e\u043d\u0441\u0430
+ConfigView.section.tracker.enablekey=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u043d\u043e\u0439 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438
 ConfigView.section.file.perf=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438
-ConfigView.section.file.perf.explain=\u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e \u2014 \u043d\u0435\u043e\u0431\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u043e\u0440\ [...]
+ConfigView.section.file.perf.explain=\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415 - \u043d\u0435\u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u044d\u0444\u [...]
 ConfigView.section.file.max_open_files.explain=\u041f\u0440\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c \u [...]
 popup.error.hide=\u0421\u043a\u0440\u044b\u0442\u044c
-popup.error.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-ConfigView.section.style.colorOverrides=\u041e\u0442\u043c\u0435\u043d\u0430 \u0446\u0432\u0435\u0442\u043e\u0432
-ConfigView.section.style.colorOverride.progressBar=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430
+popup.error.details=\u0414\u0435\u0442\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e
+ConfigView.section.style.colorOverrides=\u041f\u043e\u0434\u043c\u0435\u043d\u0430 \u0446\u0432\u0435\u0442\u0430
+ConfigView.section.style.colorOverride.progressBar=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f
 ConfigView.section.style.colorOverride.error=\u041e\u0448\u0438\u0431\u043a\u0430
-MainWindow.status.tooOld=\u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430 \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.
+MainWindow.status.tooOld=\u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435.
 ConfigView.section.style.colorOverride.warning=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435
-ConfigView.section.style.colorOverride.altRow=\u041d\u0435\u0447\u0451\u0442\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438
-ConfigView.section.file.save.peers.enable=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0443\u0437\u043b\u0430\u043c\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-ConfigView.section.file.save.peers.max=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0443\u0437\u043b\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.file.save.peers.pertorrent=\u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-ConfigView.label.max_peers_per_torrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.label.max_peers_total=\u041c\u0430\u043a\u0441. \u0432\u0441\u0435\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.style.colorOverrides.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430 \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435
+ConfigView.section.style.colorOverride.altRow=\u0427\u0435\u0440\u0435\u0437\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435
+ConfigView.section.file.save.peers.enable=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0441\u0432\u044f\u0437\u0438 \u0441 \u043f\u0438\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f
+ConfigView.section.file.save.peers.max=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0445 \u0441\u0432\u044f\u0437\u0435\u0439  [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.file.save.peers.pertorrent=\u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.label.max_peers_per_torrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b. \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430) [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.label.max_peers_total=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0441\u0435\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 Vuze [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.style.colorOverrides.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430
 ConfigView.section.language.info=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
 ConfigView.section.language.enableUpdate=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c
-ConfigView.section.language.UpdateURL=URL \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-ConfigView.section.language.UpdateNow=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441
+ConfigView.section.language.UpdateURL=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c URL
+ConfigView.section.language.UpdateNow=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0421\u0435\u0439\u0447\u0430\u0441!
 Button.revert=\u041d\u0430\u0437\u0430\u0434
-MyTorrentsView.menu.changeDirectory=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+MyTorrentsView.menu.changeDirectory=\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438
 GenericText.column=\u0441\u0442\u043e\u043b\u0431\u0435\u0446
-MyTorrentsView.menu.thisColumn.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0435\u0446
-MyTorrentsView.menu.thisColumn.toClipboard=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-MyTorrentsView.menu.thisColumn.autoTooltip=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0443
+MyTorrentsView.menu.thisColumn.remove=\u0423\u0431\u0440\u0430\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0435\u0446
+MyTorrentsView.menu.thisColumn.toClipboard=\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+MyTorrentsView.menu.thisColumn.autoTooltip=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0438
 MyTorrentsView.menu.tracker=\u0422\u0440\u0435\u043a\u0435\u0440
-ConfigView.download.abbreviated=\u041f:
-ConfigView.upload.abbreviated=\u0420:
+ConfigView.download.abbreviated=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430:
+ConfigView.upload.abbreviated=\u0420\u0430\u0437\u0434\u0430\u0447\u0430:
 ConfigView.complete.abbreviated=\u0417:
-TableColumn.header.secondsseeding=\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.secondsseeding.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.secondsdownloading=\u0412\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-TableColumn.header.secondsdownloading.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+TableColumn.header.secondsseeding=\u0421\u0438\u0434\u0438\u0440\u0443\u0435\u043c \u0443\u0436\u0435
+TableColumn.header.secondsseeding.info=\u0412\u0441\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b \u0440\u0430\u0437\u0434\u0430\u0435\u0442\u0435.
+TableColumn.header.secondsdownloading=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0443\u0436\u0435
+TableColumn.header.secondsdownloading.info=\u0412\u0440\u0435\u043c\u044f, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0432\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0435
 ConfigView.section.tracker.udpversion=\u0412\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 UDP (1 \u0438\u043b\u0438 2)
 window.updateswt.title=\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430!
-window.updateswt.text=\u0412\u0435\u0440\u0441\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430!\nVuze \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 SWT \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u0438. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \ [...]
-window.updateswt.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+window.updateswt.text=\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0430!\nVuze \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u0438. \u041f\u043e\u0441\u043b\u0435\ [...]
+window.updateswt.status=\u0421\u0442\u0430\u0442\u0443\u0441
 window.updateswt.failed=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u041e\u041a \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430.
 window.updateswt.status.downloading.updater=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
 window.updateswt.status.finding=\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT
 window.updateswt.status.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT
 window.updateswt.status.done=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
+window.updateswt.ok=\u041e\u043a
 window.updateswt.cancel=O\u0442\u043c\u0435\u043d\u0430
-swt.updater.downloader.downloading=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 SWT \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0441 
+swt.updater.downloader.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 SWT \u0438\u0437
 swt.updater.urlsgetter.downloading=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0437\u0435\u0440\u043a\u0430\u043b 
-swt.updater.urlsgetter.platform=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 SWT \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b: 
+swt.updater.urlsgetter.platform=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 SWT \u0434\u043b\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b : 
 window.updateswt.ignore=\u041f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-ConfigView.section.style.useFancyTabs=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0432\u0435\u0442\u043d\u044b\u0435 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438
+ConfigView.section.style.useFancyTabs=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0435 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438
 splash.initializeGM=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Global Torrent Manager
 splash.loadingTorrents=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-splash.firstMessageNoI18N=
-MyTorrentsView.menu.thisColumn.sort=&\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430
-Scrape.status.ok=\u0417\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 OK
-Scrape.status.error=\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430:
-Scrape.status.error.badURL=URL \u0430\u043d\u043e\u043d\u0441\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.
-Scrape.status.error.nohash=\u0412 \u043e\u0442\u0432\u0435\u0442\u043d\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0445\u0435\u0448.
-Scrape.status.error.invalid=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.
-Scrape.status.nextScrapeAt=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0447\u0435\u0440\u0435\u0437 %1
-Scrape.status.scraping=\u0417\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438...
-Scrape.status.initializing=\u0417\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438...
-Scrape.status.scraping.queued=\u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c...
-ConfigView.label.minSpeedForActiveSeeding=\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043b\u043e\u0442, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0438\u0436\u0435, \u0447\u0435\u043c
-ConfigView.section.stats.exportpeers=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0443\u0437\u043b\u0430
-MainWindow.menu.view.irc.moved=IRC \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u043e\u0434\u0443\u043b\u044f \u043d\u0430 http://azureus.sourceforge.net/plugin_list.php. \u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u043c\u0435\u043d\u044e \u00ab\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b/\ [...]
-MyTrackerView.webui.contextmenu.copyurl=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-ConfigView.section.file.torrent.ignorefiles=\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\n(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 .DS_Store;Thumbs.db)
+splash.firstMessageNoI18N=(: Vuze :)\n\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 "\u041f\u0420\u0410\u0412\u0418\u041b\u042c\u041d\u042b\u0419" \u043f\u0435\u0440\u0435\u0432\u043e\u0434, ver.2.0.9\n(\u0441)2011 GamBIT (Nizhniy Novgorod, Russia)\n\u0440\u0443\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f Azureus, Vuze
+MyTorrentsView.menu.thisColumn.sort=&\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+Scrape.status.ok=Scrape-\u043e\u043f\u0440\u043e\u0441 OK
+Scrape.status.error=\u041e\u0448\u0438\u0431\u043a\u0430 scrape-\u043e\u043f\u0440\u043e\u0441\u0430:
+Scrape.status.error.badURL=URL \u0430\u043d\u043e\u043d\u0441\u0430 \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 scrape-\u043e\u043f\u0440\u043e\u0441\u043e\u0432..
+Scrape.status.error.nohash=\u041d\u0435\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u043e\u0439 hash-\u0441\u0443\u043c\u043c\u044b \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430.
+Scrape.status.error.invalid=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.
+Scrape.status.nextScrapeAt=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 scrape-\u043e\u043f\u0440\u043e\u0441  \u0432 %1
+Scrape.status.scraping=Scrape-\u043e\u043f\u0440\u043e\u0441...
+Scrape.status.initializing=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043e\u043f\u0440\u043e\u0441\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430...
+Scrape.status.scraping.queued=Scrape-\u043e\u043f\u0440\u043e\u0441 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438...
+ConfigView.label.minSpeedForActiveSeeding=\u0420\u0430\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043b\u043e\u0442, \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0438\u0436\u0435 \u0447\u0435\u043c
+ConfigView.section.stats.exportpeers=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u0438\u0440\u0430\u0445
+MainWindow.menu.view.irc.moved=IRC \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043d\u0430 http://azureus.sourceforge.net/plugin_list.php. \u0415\u0441\u043b\u0438 \u0438\u043d\u0441\u0442\u0430\u043b\u043b\u0438\u0440\u043e\u0432\u0430\u043d - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043c\u0435\u043d\u044e \u0412\u0438\u0434 > plugins > IRC \u0434\u043b\u0 [...]
+MyTrackerView.webui.contextmenu.copyurl=\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+ConfigView.section.file.torrent.ignorefiles=\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b\n(\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 .DS_Store;Thumbs.db)
 Torrent.create.progress.ignoringfile=\u0424\u0430\u0439\u043b \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f
-ConfigView.section.style.useUnitsRateBits=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u0430\u0439\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 (\u041a\u0438\u0411/\u0441 > \u041a\u0438\u0431\u0438\u0442/\u0441 \u0438 \u0442.\u0434)
-ConfigView.section.interface.resetassoc=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0435 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 .torrent \u0432 explorer
+ConfigView.section.style.useUnitsRateBits=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u0430\u0439\u0442\u043e\u0432 \u0434\u043b\u044f \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0431\u0430\u0439\u0442\u0430\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u0445 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 (KiB/s > Kibit/s \u0438.\u0442.\u0434)
+ConfigView.section.interface.resetassoc=\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u044c \u041f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0430 \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c (.torrent)
 ConfigView.section.interface.resetassocbutton=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
 ConfigView.section.interface.checkassoc=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0432\u044f\u0437\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435
-dialog.associations.title=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438
-Button.yes=&\u0414\u0430
-Button.no=&\u041d\u0435\u0442
-ConfigView.label.seeding.autoStart0Peers=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 0 \u0443\u0437\u043b\u043e\u0432
-ConfigView.label.seeding.autoStart0Peers.tooltip=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0431\u0435\u0437 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0445.
+dialog.associations.title=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0432\u044f\u0437\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b\u043e\u0432
+Button.yes=\u0414\u0430
+Button.no=\u041d\u0435\u0442
+ConfigView.label.seeding.autoStart0Peers=\u0410\u0432\u0442\u043e-\u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 0 \u043b\u0438\u0447\u0435\u0440\u043e\u0432
+ConfigView.label.seeding.autoStart0Peers.tooltip=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u0435, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u0442\u0440\u0435\u043a\u0435\u0440 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0441\u0438\u0434\u043e\u0432 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 0 \u043b\u0438\u [...]
 dialog.associations.prompt=Vuze \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043e\u0439 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 BitTorrent.\n\u0416\u0435\u043b\u0430\u0435\u0442\u0435 \u043b\u0438 \u0432\u044b \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c Vuze \u044d\u0442\u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441?
 dialog.associations.askagain=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.section.plugins.update=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-Plugin.pluginupdate.enablecheck=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-plugins.basicview.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435:
-plugins.basicview.activity=\u0414\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c:
+ConfigView.section.plugins.update=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+Plugin.pluginupdate.enablecheck=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+plugins.basicview.status=\u0421\u0442\u0430\u0442\u0443\u0441:
+plugins.basicview.activity=\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c:
 plugins.basicview.progress=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441:
 plugins.basicview.log=\u0416\u0443\u0440\u043d\u0430\u043b:
-ConfigView.label.maxdownloadspeed=\u041a\u0411/c \u043e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-splash.loadingTorrent=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 
+ConfigView.label.maxdownloadspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 Vuze, \u0432 \u041a\u0411/\u0441 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+splash.loadingTorrent=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442 
 splash.of=\u0438\u0437
-UpdateWindow.title=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f Vuze
-UpdateWindow.header=\u0414\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f:
+UpdateWindow.title=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u043b\u044c\u0449\u0438\u043a Vuze
+UpdateWindow.header=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438:
 UpdateWindow.columns.install=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-UpdateWindow.columns.name=\u0418\u043c\u044f
+UpdateWindow.columns.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 UpdateWindow.columns.version=\u0412\u0435\u0440\u0441\u0438\u044f
 UpdateWindow.columns.size=\u0420\u0430\u0437\u043c\u0435\u0440
 UpdateWindow.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
@@ -1061,55 +1060,54 @@ UpdateWindow.quit=\u0412\u044b\u0439\u0442\u0438
 UpdateWindow.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
 UpdateWindow.ok=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
 UpdateWindow.restart=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441
-UpdateWindow.status.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
-UpdateWindow.status.done=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+UpdateWindow.status.downloading=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044e
+UpdateWindow.status.done=\u0421\u0434\u0435\u043b\u0430\u043d\u043e
 UpdateWindow.status.failed=\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u043e
-UpdateWindow.status.restartNeeded=\u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a!
+UpdateWindow.status.restartNeeded=\u0420\u0435\u0441\u0442\u0430\u0440\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d!
 ConfigView.pluginlist.broken=\u041f\u043e\u0432\u0440\u0435\u0436\u0434\u0451\u043d
-ConfigView.pluginlist.whereToPut=\u041f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0432:
-ConfigView.pluginlist.whereToPutOr=\u0414\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:
+ConfigView.pluginlist.whereToPut=\u0420\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u0441\u0432\u043e\u0438\u0445 \u043f\u0430\u043f\u043a\u0430\u0445 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u0443\u0442\u0438:
+ConfigView.pluginlist.whereToPutOr=\u0414\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043f\u0430\u043f\u043a\u0443:
 MainWindow.statusText.checking=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438
-TableColumn.header.OnlyCDing4=\u041d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0435
-TableColumn.header.OnlyCDing4.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-ConfigView.section.style.alternateTablePainting=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u043e\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044b (\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u04 [...]
-UpdateWindow.status.restartMaybeNeeded=\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
-ConfigView.pluginlist.shared=\u0440\u043e\u0437\u0434\u0430\u043d\u043e
-PeersView.host=\u0414\u043e\u043c\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f
-PeersView.host.info=\u0414\u043e\u043c\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0443\u0437\u043b\u0430, \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e (\u043c\u043e\u0436\u0435\u0442 \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c)
-MainWindow.menu.help.whatsnew=\u0427\u0442\u043e \u043d\u043e\u0432\u043e\u0433\u043e
-ConfigView.label.checkonstart=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.label.periodiccheck=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
-ConfigView.label.opendialog=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u041c\u0430\u0441\u0442\u0435\u0440\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
+TableColumn.header.OnlyCDing4=\u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u0434\u0438\u0440\u0443\u0435\u043c \u0443\u0436\u0435
+TableColumn.header.OnlyCDing4.info=\u0412\u0440\u0435\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u0440\u0435\u043c\u044f, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0441\u044f (\u0438 \u0440\u0430\u04 [...]
+UpdateWindow.status.restartMaybeNeeded=\u0420\u0435\u0441\u0442\u0430\u0440\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+ConfigView.pluginlist.shared=\u0440\u0430\u0441\u0448\u0430\u0440\u0435\u043d
+PeersView.host=\u0418\u043c\u044f \u0445\u043e\u0441\u0442\u0430
+PeersView.host.info=\u0418\u043c\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0433\u043e \u0445\u043e\u0441\u0442\u0430 \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e (\u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c)
+MainWindow.menu.help.whatsnew=\u0427\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e?        [\u0441\u043c. \u0441\u0430\u0439\u0442:     WWW.AZUREUS.NAROD.NNOV.RU]
+ConfigView.label.checkonstart=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
+ConfigView.label.periodiccheck=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438
+ConfigView.label.opendialog=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u041c\u0430\u0441\u0442\u0435\u0440 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
 MainWindow.updateavail=\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f
 MainWindow.status.unofficialversion=Vuze \u0411\u0435\u0442\u0430
 MainWindow.status.latestversionunchecked=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0430
 GeneralView.label.updatein.stopped=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
 StartStopRules.menu.viewDebug=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e
-ConfigView.section.style.doNotUseGB=\u041d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0413\u0411 \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0438\u0446\u0443
-ConfigView.section.style.doNotUseGB.tooltip=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, Vuze \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044b (\u041c\u0411), \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 1024\u041c\u0411
-MainWindow.menu.help.plugins=\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u043d\u0430 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0435
-ConfigView.section.plugins.TrackerWeb=\u0422\u0440\u0435\u043a\u0435\u0440 \u0441\u0435\u0442\u0438
-ConfigView.section.tracker.enablecategories=\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c
-health.explain.share=\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0435 \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0438 \u043d\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442\u0441\u044f
+ConfigView.section.style.doNotUseGB=\u041d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0413\u0411  \u043a\u0430\u043a \u0435\u0434\u0438\u043d\u0438\u0446\u0443
+ConfigView.section.style.doNotUseGB.tooltip=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044b (MB), \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 1024MB
+MainWindow.menu.help.plugins=\u041f\u043b\u0430\u0433\u0438\u043d\u044b
+ConfigView.section.plugins.TrackerWeb=Web-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.enablecategories=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c
+health.explain.share=\u042d\u0442\u043e\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f (\u0445\u043e\u0441\u0442\u0438\u043d\u0433) \u0438\u043b\u0438 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d (\u0431\u0435\u0437 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0430)\n\u043d\u0430 \u0412\u0430\u0448\u0435\u043c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0442\u0440\u043 [...]
 ConfigView.section.tracker.createcert=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442
 ConfigView.section.tracker.createbutton=\u0421\u043e\u0437\u0434\u0430\u0442\u044c
 security.certcreate.title=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430
 security.certcreate.intro=\u0414\u0430\u043d\u043d\u044b\u0439 \u0434\u0438\u0430\u043b\u043e\u0433 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430
-security.certcreate.alias=\u042f\u0440\u043b\u044b\u043a
+security.certcreate.alias=\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c
 security.certcreate.strength=\u0421\u0442\u043e\u0439\u043a\u043e\u0441\u0442\u044c
-security.certcreate.firstlastname=\u0418\u043c\u044f \u0438 \u0444\u0430\u043c\u0438\u043b\u0438\u044f
+security.certcreate.firstlastname=\u0418\u043c\u044f, \u0424\u0430\u043c\u0438\u043b\u0438\u044f
 security.certcreate.orgunit=\u041e\u0442\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438
 security.certcreate.org=\u041e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f
 security.certcreate.city=\u0413\u043e\u0440\u043e\u0434 \u0438\u043b\u0438 \u043c\u0435\u0441\u0442\u043e \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f
 security.certcreate.state=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0438\u043b\u0438 \u0440\u0430\u0439\u043e\u043d
 security.certcreate.country=\u0414\u0432\u0443\u0445\u0431\u0443\u043a\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u0442\u0440\u0430\u043d\u044b
 security.certcreate.ok=\u0421\u043e\u0437\u0434\u0430\u0442\u044c
-security.certcreate.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+security.certcreate.cancel=\u041e\u0442\u043c\u0435\u043d\u0430
 security.certcreate.createok=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u043f\u0440\u043e\u0448\u043b\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e
 security.certcreate.createfail=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u043f\u0440\u043e\u0448\u043b\u043e \u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e
-ConfigView.section.plugins.webui=\u0412\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430 Swing
-ConfigView.section.plugins.xml_http_if=\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 XML/HTTP
-webui.passwordenable=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c
+ConfigView.section.plugins.webui=Web-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Swing
+ConfigView.section.plugins.xml_http_if=XML/HTTP \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
+webui.passwordenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c
 webui.user=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 webui.password=\u041f\u0430\u0440\u043e\u043b\u044c
 webui.port=\u041f\u043e\u0440\u0442 (*)
@@ -1118,458 +1116,450 @@ webui.homepage=\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u04
 webui.rootdir=\u041a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 (*)
 webui.rootres=\u041a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0440\u0435\u0441\u0443\u0440\u0441 (*)
 webui.mode=\u0420\u0435\u0436\u0438\u043c (*)
-webui.mode.info=\u0420\u0435\u0436\u0438\u043c\u044b\n\t\u00abfull\u00bb\t= \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)\n\t\u00abview\u00bb\t= \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 (\u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u [...]
+webui.mode.info=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0440\u0435\u0436\u0438\u043c\n\t"full"\t= \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c)\n\t"view"\t= \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 (\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043c\u04 [...]
 webui.access=\u0414\u043e\u0441\u0442\u0443\u043f (*)
-webui.access.info=\u0414\u043e\u0441\u0442\u0443\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\n\t\u00ablocal\u00bb\t= \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\n\t\u00aball\u00bb\t\t= \u0434\u043e\u0441\u0442\u0443\u043f \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 (\u043f\u043e [...]
-GeneralView.label.maxdownloadspeed=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0451\u043c\u0430
-Security.keystore.corrupt=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u043b\u044e\u0447\u0435\u0439 \u00ab%1\u00bb, \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0435\u0433\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435/\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u [...]
-Security.keystore.empty=\u041f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u043e\u0431\u043e\u0439 \u0437\u0430\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 (\u0441\u043c. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 > \u0411\u0435\u0437\u043e\u0 [...]
-webui.restart.info=* \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-GeneralView.label.maxdownloadspeed.tooltip=\u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+webui.access.info=\u0414\u043e\u0441\u0442\u0443\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c\n\t"local"\t= \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u0438\u043c\u0435\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\n\t"all"\t= \u0434\u043e\u0441\u0442\u0443\u043f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u04 [...]
+GeneralView.label.maxdownloadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+Security.keystore.corrupt=\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043b\u044e\u0447\u0430 '%1', \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0435\u0433\u043e \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435/\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0437\u0430\u043d\u043e\u0432\u043e
+Security.keystore.empty=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043a\u043b\u044e\u0447\u0435\u0439 \u043f\u0443\u0441\u0442\u043e. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0432\u043e\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 (\u0441\u043c. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 > \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u04 [...]
+GeneralView.label.maxdownloadspeed.tooltip=- \u0435\u0434.\u0438\u0437\u043c.; \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
 ConfigView.section.UPnP=UPnP 
 upnp.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c UPnP
-upnp.info=\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 Plug and Play (UPnP) \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430\u0445 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 UPnP.
-upnp.mapping.dataport=\u041f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445
+upnp.info=\u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f \u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e Plug and Play (UPnP) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0440\u0442\u044b \u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u04 [...]
+upnp.mapping.dataport=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e\u0440\u0442 \u0434\u0430\u043d\u043d\u044b\u0445
 upnp.mapping.tcptrackerport=TCP \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-upnp.mapping.udptrackerport=\u041f\u043e\u0440\u0442 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
-upnp.alert.differenthost=UPnP: \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u00ab%1\u00bb \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0434\u043b\u044f \u00ab%2\u00bb \u2014 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0440\u0442
-upnp.alert.mappingok=UPnP: \u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u00ab%1\u00bb \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e
-upnp.alert.mappingfailed=UPnP: \u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u00ab%1\u00bb
-upnp.alertsuccess=\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043e\u0431 \u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445
-upnp.alert.lostdevice=UPnP: \u041f\u043e\u0442\u0435\u0440\u044f\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u00ab%1\u00bb \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 UPnP \u00ab%2\u00bb
+upnp.mapping.udptrackerport=UDP \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+upnp.alert.differenthost=UPnP: \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '%1' \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043e '%2' - \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0440\u0442
+upnp.alert.mappingok=UPnP: \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '%1' \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e
+upnp.alert.mappingfailed=UPnP: \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '%1' \u043d\u0435 \u0443\u0434\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c
+upnp.alertsuccess=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e\u0431 \u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445
+upnp.alert.lostdevice=UPnP: \u041f\u043e\u0442\u0435\u0440\u044f\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c '%1' \u043d\u0430 UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 '%2'
 upnp.grabports=\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0440\u0442\u044b, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0442 \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0443
-upnp.refresh.label=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u043e\u0432
+upnp.refresh.label=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0440\u0442\u043e\u0432
 upnp.refresh.button=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
-upnp.alert.mappinggrabbed=UPnP: \u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u00ab%1\u00bb \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e \u2014 \u0432\u0437\u044f\u0442\u043e \u0438\u0437 \u00ab%2\u00bb
+upnp.alert.mappinggrabbed=UPnP: \u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '%1' \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e - \u0432\u0437\u044f\u0442\u043e \u0438\u0437 '%2'
 upnp.mapping.tcpssltrackerport=TCP SSL \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-upnp.alertothermappings=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442\u044b, \u0437\u0430\u043d\u044f\u0442\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430\u043c\u0438
-upnp.alertdeviceproblems=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u0441 UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438
-upnp.trace_to_log=\u0412\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u044e \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u043c\u0430\u0446\u0438\u044e \u0432 \u0436\u0443\u0440\u043d\u0430\u043b
-upnp.wiki_link=\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0432 \u0412\u0438\u043a\u0438 Vuze \u043f\u043e UPnP
-upnp.refresh_mappings_on_bad_nat=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0440\u0442\u044b, \u0435\u0441\u043b\u0438 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 NAT \u2014 \u00ab\u0437\u0430 \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c\u00bb
-ConfigView.pluginlist.coreplugins=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438:
+upnp.alertothermappings=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u043f\u043e\u0440\u0442\u0430\u0445, \u0437\u0430\u043d\u044f\u0442\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430\u043c\u0438
+upnp.alertdeviceproblems=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u0441 UPnP-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c
+upnp.trace_to_log=\u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u043b\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b
+upnp.wiki_link=Vuze Wiki-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u043e UPnP
+upnp.refresh_mappings_on_bad_nat=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u043e\u0432 \u043a\u043e\u0433\u0434\u0430 \u0441\u0442\u0430\u0442\u0443\u0441 NAT "\u0417\u0430\u043a\u0440\u044b\u0442\u043e \u0424\u0430\u0439\u0440\u0432\u043e\u043b\u043b\u043e\u043c"
+blank.resource=\u0420\u0435\u0441\u0443\u0440\u0441
+ConfigView.pluginlist.coreplugins=\u0421\u043a\u0430\u0447\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b:
 Peers.column.DLedFromOthers=\u041e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445
-Peers.column.DLedFromOthers.info=\u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0443\u0437\u043b\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0432\u0430\u043c\u0438
-Peers.column.UpDownRatio=\u0420\u043e\u0437\u0434\u0430\u043d\u043e:\u043f\u0440\u0438\u043d\u044f\u0442\u043e
-Peers.column.UpDownRatio.info=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 "\u0420\u0430\u0437\u0434\u0430\u043b : \u041f\u0440\u0438\u043d\u044f\u043b"
+Peers.column.DLedFromOthers.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u043f\u0438\u0440\u043e\u043c \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0438\u0440\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0412\u0430\u043c\u0438
+Peers.column.UpDownRatio=\u0420\u0430\u0437\u0434\u0430\u0447\u0430:\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+Peers.column.UpDownRatio.info=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u043f\u0438\u0440\u0430 "\u0420\u0430\u0437\u0434\u0430\u0447\u0430 : \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430"
 Peers.column.UpRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-Peers.column.UpRatio.info=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 \u0432\u0430\u0441 : \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445"
-upnp.releasemappings=\u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u044b \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f
-webui.upnpenable=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c UPnP \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 (*)
-ConfigView.section.file.friendly.hashchecking=\u0429\u0430\u0434\u044f\u0449\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0445\u0435\u0448\u0435\u0439
-ConfigView.section.file.friendly.hashchecking.tooltip=\u0427\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0433\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0439 \u0426\u041f/\u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0445\u0435\u0448\u0430 \u043f\u043e [...]
-ConfigView.section.tracker.seedretention=\u041c\u0430\u043a\u0441. \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e] 
-ConfigView.section.tracker.seedretention.info=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0445
-ConfigView.section.tracker.port=\u0422\u0440\u0435\u043a\u0435\u0440 \u043d\u0430 \u043f\u043e\u0440\u0442\u0435 HTTP
-ConfigView.section.tracker.sslport=\u0422\u0440\u0435\u043a\u0435\u0440 \u043d\u0430 \u043f\u043e\u0440\u0442\u0435 HTTPS
-ConfigView.section.tracker.publicenable.info=\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b\n\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0432\u0430\u0448\u0435\u0433\u043e \u0442\u0440\u0435\u043 [...]
+Peers.column.UpRatio.info=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u043f\u0438\u0440\u0430 "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 \u0432\u0430\u0441 : \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445"
+upnp.releasemappings=\u041e\u0441\u0432\u043e\u0431\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u0440\u0442\u044b \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+webui.upnpenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c UPnP \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0440\u0442\u0430 (*)
+ConfigView.section.file.friendly.hashchecking=\u0414\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0445\u044d\u0448-\u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438
+ConfigView.section.file.friendly.hashchecking.tooltip=\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439, \u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0433\u0440\u0443\u0436\u0430\u044e\u0449\u0438\u0439 \u0426\u041f\u0423/\u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0445\u044d\u0448 \u043f\u043e \u0447\u0430 [...]
+ConfigView.section.tracker.seedretention=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447. \u0441\u0438\u0434\u043e\u0432, \u0445\u0440\u0430\u043d\u0438\u043c\u043e\u0435 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e] 
+ConfigView.section.tracker.seedretention.info=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u0430 \u0434\u043b\u044f  \u043d\u0435\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0434\u043e\u0432
+ConfigView.section.tracker.port=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0430 HTTP-\u043f\u043e\u0440\u0442\u0435
+ConfigView.section.tracker.sslport=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0430 HTTPS(SSL)-\u043f\u043e\u0440\u0442\u0435
+ConfigView.section.tracker.publicenable.info=\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0435 \u0432\u0430\u0448 \u0442\u0440\u0435\u043a\u0435\u0440\n\u0431\u0435\u0437 \u0432\u0430\u0448\u0435\u0433\u043e \u043b\u0438\u0447\u043d\u0 [...]
 Button.clear=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-MainWindow.IPs.tooltip=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0444\u0438\u043b\u044c\u0442\u0440\u0430: %1\n\u0412\u0441\u0435\u0433\u043e \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 IPFilters - \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445/\u0437\u0430\u0431\u043 [...]
-ConfigView.section.ipfilter.list.banned=\u0431\u044b\u043b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d
-ConfigView.section.ipfilter.list.baddata=\u043f\u0440\u0438\u0441\u043b\u0430\u043b \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435: \u0441\u043b\u0443\u0447\u0430\u0435\u0432 =
-Button.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-ConfigView.section.ipfilter.bannedinfo=\u0410\u0434\u0440\u0435\u0441\u0430 IP, \u043f\u0440\u0438\u0441\u043b\u0430\u0432\u0448\u0438\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u [...]
-ConfigView.section.ipfilter.blockedinfo=\u0410\u0434\u0440\u0435\u0441\u0430 IP, \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432
+MainWindow.IPs.tooltip=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u0430: %1\n[\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u0432 IP-\u0444\u0438\u043b\u044c\u0442\u0440\u0435] - [\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u04 [...]
+ConfigView.section.ipfilter.list.banned=\u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d (\u0431\u0430\u043d)
+ConfigView.section.ipfilter.list.baddata=\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0412\u0430\u043c \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435: \u0441\u043b\u0443\u0447\u0430\u0435\u0432 =
+Button.reset=\u0421\u0431\u0440\u043e\u0441
+ConfigView.section.ipfilter.bannedinfo=IP-\u0430\u0434\u0440\u0435\u0441\u0430, \u043f\u0440\u0438\u0441\u043b\u0430\u0432\u0448\u0438\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 - \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u044b \u043b\u0438\u043c\u0438\u0442\u044b
+ConfigView.section.ipfilter.blockedinfo=IP-\u0430\u0434\u0440\u0435\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0438\u0437-\u0437\u0430 IP-\u0444\u0438\u043b\u044c\u0442\u0440\u0430
 download.removerules.name=\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f
-download.removerules.unauthorised.info=\u041d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442, \u0432 \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u044e\u0449\u0435\u043c \u043e\u0442\u0432\u0435\u0442\u0435 \u043d\u0430 \u0430\u043d\u043e\u043d\u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044 [...]
-download.removerules.unauthorised=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-download.removerules.unauthorised.seedingonly=\t\u0422\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435
+download.removerules.unauthorised.info=\u041d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043b\u0438 "n [...]
+download.removerules.unauthorised=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+download.removerules.unauthorised.seedingonly=\t\u0422\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0434\u0430\u0435\u043c
 download.removerules.removed.ok=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u044c\u044e '%1'. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0442 [...]
-download.removerules.updatetorrents=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u043b\u044f Vuze, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c
-ConfigView.label.defaultstarttorrentsstopped=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.section.server.enableudp=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b UDP
-upnp.mapping.dataportudp=\u041f\u043e\u0440\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.file.decoder.showlax=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0434\u043a\u0438\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438
+download.removerules.updatetorrents=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0438\u0435 Vuze, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0438\u0440\u043e\u0432
+ConfigView.label.defaultstarttorrentsstopped=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0431\u0435\u0437 \u0438\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u0430
+ConfigView.section.server.enableudp=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b UDP (\u043a\u043b\u0438\u0435\u043d\u0442<=>\u0442\u0440\u0435\u043a\u0435\u0440)
+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\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438
 ConfigView.section.file.decoder.showall=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438
-MainWindow.status.updowndetails.tooltip=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438/\u043f\u0440\u0438\u0451\u043c\u0430\n\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0440\u0430\u0432\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u044b\u0448\u0438, \u0434\u043e\u043f [...]
-TrackerClient.announce.warningmessage=\u0422\u0440\u0435\u043a\u0435\u0440 \u0434\u043b\u044f \u00ab%1\u00bb \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u00ab%2\u00bb
-ConfigView.section.tracker.natcheckenable=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u0440\u0442\u0430\u043c \u0443\u0437\u043b\u043e\u0432 \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u0443\u0437\u043b\u044b \u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445
-ConfigView.section.tracker.publishenabledetails=\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0435
+MainWindow.status.updowndetails.tooltip=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0420\u0430\u0437\u0434\u0430\u0447\u0438/\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438\n\u041f\u0440\u0430\u0432\u044b\u0439 \u041a\u043b\u0438\u043a \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0414\u0432\u043e\u0439\u043d\u043e\u0439 \u041a\u043b\u0438\u043a \u0447\u0442\u043e\u0431\ [...]
+TrackerClient.announce.warningmessage=\u0422\u0440\u0435\u043a\u0435\u0440 \u0434\u043b\u044f '%1' \u0432\u044b\u0434\u0430\u043b \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 '%2'
+ConfigView.section.tracker.natcheckenable=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u043e\u0441\u0442\u044c \u0441 '\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u043f\u043e\u0440\u0442\u043e\u043c' \u0438 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0438\u0440\u0430\u043c
+ConfigView.section.tracker.publishenabledetails=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0437\u0430\u043a\u0430\u0447\u043a\u0435
 ConfigView.section.tracker.publishenablepeerdetails=\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435
-MyTrackerView.badnat=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 NAT
-MyTrackerView.badnat.info=\u0420\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435/\u0443\u0437\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u0440\u043e\u0448\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 NAT (\u0435\u0441\u043b\u0438 NAT \u0432\u043a\u043b\u044e\u0447\u0451\u043d)
-ConfigView.section.tracker.natchecktimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (\u0441)
-ConfigView.section.file.perf.cache.enable=\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0438\u0441\u043a\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438
+MyTrackerView.badnat=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 NAT
+MyTrackerView.badnat.info=\u0421\u0438\u0434\u044b \u0438 \u041b\u0438\u0447\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 NAT, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+ConfigView.section.tracker.natchecktimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 NAT [\u0441\u0435\u043a]
+ConfigView.section.file.perf.cache.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u0438\u0441\u043a\u0430
 ConfigView.section.file.perf.cache.size=\u0420\u0430\u0437\u043c\u0435\u0440 \u043a\u044d\u0448\u0430 \u0432 %1
-#Removed
-#MyTorrentsView.menu.setSpeed=Set Upload Speed
-MainWindow.menu.transfers=\u0417&\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MainWindow.menu.transfers.startalltransfers=&\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435
-MainWindow.menu.transfers.stopalltransfers=\u041e&\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435
-MainWindow.menu.transfers.pausetransfers=&\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-MainWindow.menu.transfers.resumetransfers=&\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
-ConfigView.label.experimental.osx.kernel.panic.fix=\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0442\u0447 \u0434\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f kernel panic \u043d\u0430 \u0434\u0432\u0443\u0445\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0441 Mac OS X [\u0442\u0440\u0435\u0431\u0443\u0435\u [...]
-SystemTray.menu.pausetransfers=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-SystemTray.menu.resumetransfers=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.section.file.truncate.too.large=\u0420\u0430\u0437\u0440\u0435\u0437\u0430\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u043c\u0435\u043d\u044c\u0448\u0438\u0435 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443
+MainWindow.menu.transfers=\u041f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445
+MainWindow.menu.transfers.startalltransfers=&\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+MainWindow.menu.transfers.stopalltransfers=&\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+MainWindow.menu.transfers.pausetransfers=&\u041f\u0430\u0443\u0437\u0430 (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+MainWindow.menu.transfers.resumetransfers=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c (\u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0443\u0437\u044b)
+ConfigView.label.experimental.osx.kernel.panic.fix=\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0442\u0447 \u0434\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 kernel panics \u043d\u0430 \u0434\u0432\u0443\u0445\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u0441 Mac OS X (\u0442 [...]
+SystemTray.menu.pausetransfers=\u041f\u0430\u0443\u0437\u0430 (\u0432\u0441\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+SystemTray.menu.resumetransfers=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c (\u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0443\u0437\u044b)
+ConfigView.section.file.truncate.too.large=\u041e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435, \u043d\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0444\u0430\u0439\u043b\u044b
 ConfigView.section.file.perf.cache.trace=\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0446\u0435\u043b\u044f\u0445 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438
-ConfigView.section.interface.enabletray=\u0417\u043d\u0430\u0447\u043e\u043a \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
+ConfigView.section.interface.enabletray=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u0422\u0440\u0435\u0435 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
 PeerManager.status.error=\u041e\u0448\u0438\u0431\u043a\u0430
 Stats.title.full=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430
-TransferStatsView.title.full=\u041e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438
+TransferStatsView.title.full=\u041f\u0435\u0440\u0435\u0434\u0430\u043d\u043e
 CacheView.title.full=\u041a\u044d\u0448
-CacheView.general.size=\u0412\u0441\u0435\u0433\u043e
+CacheView.general.size=\u041f\u043e\u043b\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440
 CacheView.general.inUse=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f
 CacheView.general.title=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043a\u044d\u0448\u0435
-CacheView.reads.title=\u0427\u0442\u0435\u043d\u0438\u0435
+CacheView.reads.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430: \u0447\u0442\u0435\u043d\u0438\u0435
 CacheView.reads.fromFile=\u0418\u0437 \u0444\u0430\u0439\u043b\u0430
 CacheView.reads.fromCache=\u0418\u0437 \u043a\u044d\u0448\u0430
-CacheView.reads.hits=\u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u0439
-CacheView.writes.title=\u0417\u0430\u043f\u0438\u0441\u044c
+CacheView.reads.hits=\u041e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439
+CacheView.writes.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430: \u0437\u0430\u043f\u0438\u0441\u044c
 CacheView.writes.toCache=\u0412 \u043a\u044d\u0448
 CacheView.writes.toFile=\u0412 \u0444\u0430\u0439\u043b
-CacheView.writes.hits=\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e
+CacheView.writes.hits=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e
 CacheView.speeds.title=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445
 CacheView.speeds.reads=\u0427\u0442\u0435\u043d\u0438\u0435
 CacheView.speeds.writes=\u0417\u0430\u043f\u0438\u0441\u044c
-CacheView.speeds.fromCache=\u0418\u0437/\u0432 \u043a\u044d\u0448
-CacheView.speeds.fromFile=\u0418\u0437/\u0432 \u0444\u0430\u0439\u043b
+CacheView.speeds.fromCache=\u0438\u0437/\u0432 \u041a\u044d\u0448
+CacheView.speeds.fromFile=\u0438\u0437/\u0432 \u0424\u0430\u0439\u043b
+CacheView.reads.#=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e
 CacheView.reads.amount=\u0412\u0441\u0435\u0433\u043e
 CacheView.reads.avgsize=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440
-openUrl.referrer=\u0410\u0434\u0440\u0435\u0441 \u0441\u0441\u044b\u043b\u0430\u044e\u0449\u0435\u0439\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:
-openUrl.referrer.info=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0430\u0439\u0442\u043e\u0432
-ConfigView.label.maxuploadspeedseeding=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0430\u0447\u0435
-ConfigView.label.transfer.ignorepeerports=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u043b\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 0;25)
-ConfigView.section.proxy.enable_socks.peer=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0443\u0437\u043b\u0430\u043c\u0438 (\u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f) [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u04 [...]
+openUrl.referrer=\u0410\u0434\u0440\u0435\u0441 \u0441\u0441\u044b\u043b\u0430\u044e\u0449\u0435\u0439\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b :
+openUrl.referrer.info=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u044d\u0442\u043e
+ConfigView.label.maxuploadspeedseeding=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430, \u043a\u043e\u0433\u0434\u0430 \u0422\u041e\u041b\u042c\u041a\u041e \u0440\u0430\u0437\u0434\u0430\u0447\u0430, \u0432 \u041a\u0411/\u0441  [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.label.transfer.ignorepeerports=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0438\u0440\u043e\u0432 \u0441 \u044d\u0442\u0438\u043c\u0438 \u043f\u043e\u0440\u0442\u0430\u043c\u0438 (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c - ';', \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 0;25)
+ConfigView.section.proxy.enable_socks.peer=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438 (\u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043 [...]
 ConfigView.section.proxy.peer.informtracker=\u0418\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 \u043e\u0431 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0438
 ConfigView.section.proxy.socks.version=\u0412\u0435\u0440\u0441\u0438\u044f SOCKS
 PiecesView.legend.written=\u0417\u0430\u043f\u0438\u0441\u0430\u043d
 PiecesView.legend.requested=\u0417\u0430\u043f\u0440\u043e\u0448\u0435\u043d
-PiecesView.legend.downloaded=\u041f\u0440\u0438\u043d\u044f\u0442\u043e, \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f
+PiecesView.legend.downloaded=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e, \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0438
 PiecesView.legend.incache=\u0414\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u044d\u0448\u0435
 PiecesView.typeItem.0=\u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439
 PiecesView.typeItem.1=\u0411\u044b\u0441\u0442\u0440\u044b\u0439
 PiecesView.type=\u0422\u0438\u043f
 Security.jar.tools_not_found=\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 JAR \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c - \u0444\u0430\u0439\u043b 'tools.jar' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 %1. \u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b->\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438->\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0 [...]
 Security.jar.signfail=\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u0435 JAR \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c - %1
-ConfigView.section.security.toolsinfo=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b JAR \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439; \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\ [...]
+ConfigView.section.security.toolsinfo=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 JAR \u0444\u0430\u0439\u043b\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f Swing Web Interface (\u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u04 [...]
 ConfigView.section.security.toolsdir=\u041f\u0430\u043f\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f 'tools.jar'
 ConfigView.section.security.choosetoolssavedir=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0430\u043f\u043a\u0443, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e 'tools.jar'
 authenticator.torrent=\u0422\u043e\u0440\u0440\u0435\u043d\u0442
-ConfigView.section.proxy.peer.same=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0443\u0437\u043b\u0430\u043c\u0438
-ConfigView.section.connection.network.max.simultaneous.connect.attempts=\u041c\u0430\u043a\u0441. \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
-ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c\u044b\u0445 Vuze \u0432 \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u [...]
-ConfigView.section.file.perf.cache.size.explain=\u041a\u044d\u0448 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0434\u0438\u0441\u043a\u0443. \u041f\u043e\u043a\u0430 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u0430\u0440\u0430 [...]
-MyTorrentsView.menu.setSpeed.unlimit=\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f
-MyTorrentsView.menu.setSpeed.unlimited=\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f
+ConfigView.section.proxy.peer.same=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u0438 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438
+ConfigView.section.connection.network.max.simultaneous.connect.attempts=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u0443-\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+ConfigView.section.connection.network.max.simultaneous.connect.attempts.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 '\u043f\u043e\u043b\u0443-\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445' \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439,\n\u044 [...]
+ConfigView.section.file.perf.cache.size.explain=\u041a\u044d\u0448 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0434\u0438\u0441\u043a\u0443. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043f\u043 [...]
+MyTorrentsView.menu.setSpeed.unlimit=\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439
+MyTorrentsView.menu.setSpeed.unlimited=\u041d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e
 MyTorrentsView.menu.setSpeed.disable=\u0417\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443
 MyTorrentsView.menu.setSpeed.disabled=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e
 MyTorrentsView.menu.setSpeed.in=\u0432
-MyTorrentsView.menu.setSpeed.slots=\u044f\u0447\u0435\u0439\u043a\u0430\u0445
-GeneralView.label.maxuploadspeed=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-GeneralView.label.maxuploadspeed.tooltip=\u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+MyTorrentsView.menu.setSpeed.slots=\u0441\u043b\u043e\u0442\u0430\u0445 \u043f\u043e
+GeneralView.label.maxuploadspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+GeneralView.label.maxuploadspeed.tooltip=- \u0435\u0434.\u0438\u0437\u043c.; \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [0 : \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
 MyTorrents.items.UpSpeedLimit.disabled=\u041d\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MyTorrents.items.UpSpeedLimit.unlimited=\u0411\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f
-TableColumn.header.maxupspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.maxupspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.file.perf.cache.enable.write=\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u043a\u0440\u0430\u0449\u0435 [...]
-ConfigView.section.file.perf.cache.enable.read=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0435\u0436\u0430\u044e\u0449\u0435\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u0434\u0438\u0441\u043a\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.section.tracker.separatepeerids=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0443\u0437\u043b\u0430 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0438 \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438
-ConfigView.section.tracker.separatepeerids.info=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f/\u0440\u0430\u0437\u0434\u0430\u0447\u0438 \n\u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e \u0442\ [...]
-ConfigView.section.interface.wavlocation=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 .wav
+MyTorrents.items.UpSpeedLimit.unlimited=\u041d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u0430
+TableColumn.header.maxupspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+TableColumn.header.maxupspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.section.file.perf.cache.enable.write=\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a, \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u0443\u043c\u0435\u043d [...]
+ConfigView.section.file.perf.cache.enable.read=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u043f\u0435\u0440\u0435\u0436\u0430\u044e\u0449\u0435\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u0434\u0438\u0441\u043a\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u [...]
+ConfigView.section.tracker.separatepeerids=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0438\u0440\u0430 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445
+ConfigView.section.tracker.separatepeerids.info=(\u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c/\u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c\n\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f [...]
+ConfigView.section.interface.wavlocation=\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 .wav
 ConfigView.section.interface.wavlocation.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b .wav \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c \u0434\u043b\u044f \u0437\u0432\u0443\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.section.tracker.server=\u0421\u0435\u0440\u0432\u0435\u0440
-ConfigView.section.tracker.client=\u041a\u043b\u0438\u0435\u043d\u0442
-ConfigView.section.tracker.client.connecttimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (\u0441)
-ConfigView.section.tracker.client.readtimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f (\u0441)
+ConfigView.section.tracker.server=\u0421\u0435\u0440\u0432\u0435\u0440 (\u0441\u0432\u043e\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440)
+ConfigView.section.tracker.client=\u041a\u043b\u0438\u0435\u043d\u0442 (\u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438)
+ConfigView.section.tracker.client.connecttimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c [\u0441\u0435\u043a\u0443\u043d\u0434]
+ConfigView.section.tracker.client.readtimeout=\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0447\u0442\u0435\u043d\u0438\u044f \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 [\u0441\u0435\u043a\u0443\u043d\u0434]
 MainWindow.menu.tools=&\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b
 FilesView.path=\u041f\u0443\u0442\u044c
 FilesView.fullpath=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c
-FilesView.remaining=\u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0447\u0430\u0441\u0442\u0438
-TableColumn.header.trackername=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-TableColumn.header.trackername.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430, \u0432\u0437\u044f\u0442\u043e\u0435 \u0438\u0437 URL \u0430\u043d\u043e\u043d\u0441\u0430
-ConfigView.group.override=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f
-ConfigView.section.file.perf.cache.notsmallerthan=\u041d\u0435 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c (\u0432 %1)
-PeersView.menu.blockupload=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443
-PeersView.menu.kickandban=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c
-PeersView.menu.kickandban.reason=\u0423\u0437\u0435\u043b \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+FilesView.remaining=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0447\u0430\u0441\u0442\u0435\u0439
+TableColumn.header.trackername=\u0422\u0440\u0435\u043a\u0435\u0440
+TableColumn.header.trackername.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430 URL \u0430\u043d\u043e\u043d\u0441\u0430
+ConfigView.group.override=\u041f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b
+ConfigView.section.file.perf.cache.notsmallerthan=\u041d\u0435 \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c (\u0432 %1)
+PeersView.menu.blockupload=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u044d\u0442\u043e\u043c\u0443 \u043f\u0438\u0440\u0443
+PeersView.menu.kickandban=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043f\u0438\u0440\u043e\u0432 \u0438 \u0417\u0430\u0431\u0430\u043d\u0438\u0442\u044c
+PeersView.menu.kickandban.reason=\u041f\u0438\u0440 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0437\u0430\u0431\u0430\u043d\u0435\u043d \u0412\u0430\u043c\u0438
 PeersView.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
-PeersView.state.info=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430
-PeersView.state.pending=\u041e\u0436\u0438\u0434\u0430\u0435\u0442
-PeersView.state.connecting=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435
-PeersView.state.handshake=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u0438
-PeersView.state.established=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d
-ConfigView.section.tracker.processinglimits=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f
-ConfigView.section.tracker.maxgettime=\u041c\u0430\u043a\u0441. \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 GET (\u0441) [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.tracker.maxgettime.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u043e\u0432 \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432
-ConfigView.section.tracker.maxposttimemultiplier=\u041c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 GET \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 POST  [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.tracker.maxposttimemultiplier.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0444\u043e\u0440\u043c \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440
-ConfigView.section.tracker.maxthreads=\u041c\u0430\u043a\u0441. \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432
+PeersView.state.info=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u0438\u0440\u0430
+PeersView.state.pending=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435
+PeersView.state.connecting=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435
+PeersView.state.handshake=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0432\u044f\u0437\u0438
+PeersView.state.established=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d
+ConfigView.section.tracker.processinglimits=\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439
+ConfigView.section.tracker.maxgettime=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 GET (\u0441\u0435\u043a\u0443\u043d\u0434) [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.tracker.maxgettime.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u043e\u0432 \u0438 scrape-\u043e\u043f\u0440\u043e\u0441\u043e\u0432
+ConfigView.section.tracker.maxposttimemultiplier=GET \u0443\u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 POST  [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.tracker.maxposttimemultiplier.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u043e\u0440\u043c \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440
+ConfigView.section.tracker.maxthreads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432
 DownloadManager.error.operationcancancelled=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430
 Torrent.create.progress.cancelled=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430
-sharing.progress.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+sharing.progress.cancel=\u041e\u0442\u043c\u0435\u043d\u0430
 wizard.maketorrents.autoopen=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f
-ConfigView.section.sharing.rescanenable=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0449\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
-ConfigView.section.sharing.rescanperiod=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u0441)
-ConfigView.section.connection.advanced=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0435\u0442\u0438
-ConfigView.section.connection.advanced.mtu=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 (MTU) 
-ConfigView.section.connection.advanced.mtu.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0430\u0434\u0440\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c.\nVuze \u0438\u0441\u043f\ [...]
-ConfigView.section.connection.advanced.SO_RCVBUF=\u0420\u0430\u0437\u043c\u0435\u0440 SO_RCVBUF \u0434\u043b\u044f \u0441\u043e\u043a\u0435\u0442\u0430 [0: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u041e\u0421]
-ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 SO_RCVBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442.\u0435. \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431 \u043a\u0430\u0434\u0440\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\ [...]
-ConfigView.section.connection.advanced.SO_SNDBUF=\u0420\u0430\u0437\u043c\u0435\u0440 SO_SNDBUF \u0434\u043b\u044f \u0441\u043e\u043a\u0435\u0442\u0430 [0: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u041e\u0421]
-ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 SO_SNDBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442.\u0435. \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u0434\u0440\u0430 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 TCP.\nVuze \u0438\u0 [...]
-ConfigView.section.connection.advanced.IPDiffServ=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 DiffServ \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 (\u043f\u043e\u043b\u0435 TOS)
-ConfigView.section.connection.advanced.IPDiffServ.tooltip=\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 DiffServ \u043f\u043e\u043b\u044f type-of-service (TOS) \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 IP \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432.\n\u0428\u043 [...]
-ConfigView.section.interface.confirm_torrent_removal=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0438\u0437 "\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b"
-MyTorrentsView.confirm_torrent_removal=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442?\n
-TableColumn.header.seed_to_peer_ratio=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445/\u0443\u0437\u043b\u043e\u0432
-TableColumn.header.seed_to_peer_ratio.info=\u0418\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445/\u0443\u0437\u043b\u043e\u0432 \u0434\u043b\u044f \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
+ConfigView.section.sharing.rescanenable=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 share-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
+ConfigView.section.sharing.rescanperiod=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f [\u0441\u0435\u043a\u0443\u043d\u0434]
+ConfigView.section.connection.advanced=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0421\u0435\u0442\u0435\u0432\u044b\u0435 \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
+ConfigView.section.connection.advanced.mtu=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430 \u0432 \u0441\u0435\u0442\u0438 (MTU) 
+ConfigView.section.connection.advanced.mtu.tooltip=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043a\u0435\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0430\u0434\u0440\u0435 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0442\u044c.\nVuze \u0438\u0441\u043f\ [...]
+ConfigView.section.connection.advanced.SO_RCVBUF=\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u043a\u0435\u0442\u0430 SO_RCVBUF [0: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0430\u0448\u0435\u0439 \u041e\u0421]
+ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 SO_RCVBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442.\u0435.  \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043e\u043a\u043d\u0430 TCP \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431.\nVuze \ [...]
+ConfigView.section.connection.advanced.SO_SNDBUF=\u0420\u0430\u0437\u043c\u0435\u0440 \u0441\u043e\u043a\u0435\u0442\u0430 SO_SNDBUF [0: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0430\u0448\u0435\u0439 \u041e\u0421]
+ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 SO_SNDBUF (\u0432 \u0431\u0430\u0439\u0442\u0430\u0445), \u0442.\u0435. \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043e\u043a\u043d\u0430 TCP .\nVuze \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0 [...]
+ConfigView.section.connection.advanced.IPDiffServ=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u0430\u043a\u0435\u0442 DiffServ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u043f\u043e\u043b\u0435 TOS)
+ConfigView.section.connection.advanced.IPDiffServ.tooltip=\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 DiffServ-\u0447\u0430\u0441\u0442\u044c \u043f\u043e\u043b\u044f \u0442\u0438\u043f\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (TOS) \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 IP \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432. \u0428\u0435\u0441\u0442\u043d\u0 [...]
+TableColumn.header.seed_to_peer_ratio=\u0421\u0438\u0434\u044b/\u041b\u0438\u0447\u0435\u0440\u044b
+TableColumn.header.seed_to_peer_ratio.info=\u041e\u0431\u0449\u0435\u0435 \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0421\u0438\u0434\u044b/\u041b\u0438\u0447\u0435\u0440\u044b
 PeersView.connected_time=\u0412\u0440\u0435\u043c\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
-PeersView.connected_time.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0443\u0437\u043b\u043e\u043c
-ConfigView.section.interface.display.add_torrents_silently=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0431\u0435\u0437 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0431\u0435\u0437 \u043f\u043e\u043a\u0430\u0437\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 Azureus.
-TableColumn.header.maxdownspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-TableColumn.header.maxdownspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-PeersGraphicView.title=\u041e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435
-ConfigView.section.tracker.passwordwebhttpsonly=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 HTTPS
-TableColumn.header.torrentpath=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435
+PeersView.connected_time.info=\u041f\u043e\u043b\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u043e\u043c
+TableColumn.header.maxdownspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+TableColumn.header.maxdownspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+PeersGraphicView.title=\u0413\u0440\u0430\u0444\u0438\u043a \u0433\u0440\u0443\u043f\u043f\u044b
+ConfigView.section.tracker.passwordwebhttpsonly=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b HTTPS
+TableColumn.header.torrentpath=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 TableColumn.header.torrentpath.info=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435
-ConfigView.section.sharing.torrentcomment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-ConfigView.label.copyanddeleteratherthanmove=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0434\u043d\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e (\u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c  [...]
-ConfigView.label.openstatsonstart=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-swt.install.window.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 Vuze
+ConfigView.section.sharing.torrentcomment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.label.copyanddeleteratherthanmove=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0437\u0430\u0442\u0435\u043c \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0438\u0445 \u0437\u0430 \u043e\u0434\u043d\ [...]
+ConfigView.label.openstatsonstart=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+swt.install.window.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 Vuze
 swt.install.window.ok=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-swt.install.window.header=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438:
-swt.uninstall.window.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 Vuze
+swt.install.window.header=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 :
+swt.uninstall.window.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 Vuze
 swt.uninstall.window.ok=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-swt.uninstall.window.header=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f:
-installPluginsWizard.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439
+swt.uninstall.window.header=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u044b\u0431\u0440\u0430\u043d\u044b \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f :
+installPluginsWizard.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
 installPluginsWizard.mode.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u043f\u043e\u0441\u043e\u0431 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-installPluginsWizard.mode.list=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0441 sourceforge.net
-installPluginsWizard.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435
-installPluginsWizard.list.loading=\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439.
-installPluginsWizard.list.loaded=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c.
+installPluginsWizard.mode.list=\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0441 \u0441\u0430\u0439\u0442\u0430 sourceforge.net (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)
+installPluginsWizard.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432, \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435
+installPluginsWizard.list.loading=\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.
+installPluginsWizard.list.loaded=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c.
 installPluginsWizard.list.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 installPluginsWizard.list.version=\u0412\u0435\u0440\u0441\u0438\u044f
-installPluginsWizard.list.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f
-installPluginsWizard.finish.title=\u0418\u0434\u0451\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430
-installPluginsWizard.finish.explanation=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u041c\u0430\u0441\u0442\u0435\u0440\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\n\n\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e\u043d \u0437\u043 [...]
-installPluginsWizard.details.loading=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435...
-installPluginsWizard.mode.file=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u0437 \u0444\u0430\u0439\u043b\u0430
+installPluginsWizard.list.description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430
+installPluginsWizard.finish.title=\u0418\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430
+installPluginsWizard.finish.explanation=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u041f\u043e\u043c\u043e\u0449\u043d\u0438\u043a\u0430 \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\n\n\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e [...]
+installPluginsWizard.details.loading=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435...
+installPluginsWizard.mode.file=\u0423 \u0432\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b \u043f\u043b\u0430\u0433\u0438\u043d\u0430
 installPluginsWizard.installMode.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u043f\u043e\u0441\u043e\u0431 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-installPluginsWizard.installMode.user=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
-installPluginsWizard.installMode.shared=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
-installPluginsWizard.file.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-installPluginsWizard.file.file=\u0424\u0430\u0439\u043b:
-installPluginsWizard.file.invalidfile=\u0414\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c Vuze.
-installPluginsWizard.file.no_such_file=\u041d\u0435\u0442 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c.
+installPluginsWizard.installMode.user=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430
+installPluginsWizard.installMode.shared=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
+installPluginsWizard.file.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+installPluginsWizard.file.file=\u0424\u0430\u0439\u043b :
+installPluginsWizard.file.invalidfile=\u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u043e\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u0430 Azureus/Vuze.
+installPluginsWizard.file.no_such_file=\u041d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c
 installPluginsWizard.file.browse=\u041e\u0431\u0437\u043e\u0440...
-uninstallPluginsWizard.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-uninstallPluginsWizard.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-uninstallPluginsWizard.list.loaded=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c.
+uninstallPluginsWizard.title=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+uninstallPluginsWizard.list.title=\u0421\u043f\u0438\u0441\u043e\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+uninstallPluginsWizard.list.loaded=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c
 installPluginsWizard.list.nullversion=\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430
 uninstallPluginsWizard.finish.title=\u0418\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435
-uninstallPluginsWizard.finish.explanation=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u041c\u0430\u0441\u0442\u0435\u0440\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439.
+uninstallPluginsWizard.finish.explanation=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u041c\u0430\u0441\u0442\u0435\u0440\u0430 \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439.
 MainWindow.menu.plugins.installPlugins=\u041c\u0430\u0441\u0442\u0435\u0440 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438...
-MainWindow.menu.plugins.uninstallPlugins=\u041c\u0430\u0441\u0442\u0435\u0440 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f...
-ConfigView.section.ipfilter.totalIPs=%1 IP \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432\u0441\u0435\u0433\u043e, %2 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435.
+MainWindow.menu.plugins.uninstallPlugins=\u041c\u0430\u0441\u0442\u0435\u0440 \u0434\u0435\u0438\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0446\u0438\u0438...
+ConfigView.section.ipfilter.totalIPs=%1 \u0432\u0441\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e IP, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 %2 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430.
 update.instance.install=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
 update.instance.uninstall=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
 update.instance.update=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439
-MainWindow.status.update.tooltip=\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u0434\u0432\u0430\u0436\u0434\u044b \u0449\u0451\u043b\u043a\u043d\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c
+MainWindow.status.update.tooltip=\u0429\u0435\u043b\u043a\u043d\u0438\u0442\u0435 \u043c\u044b\u0448\u044c\u044e \u0434\u0432\u0430\u0436\u0434\u044b \u0434\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0445\u043e\u0434\u0435
 updater.progress.window.title=\u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-updater.progress.window.info=\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c\u00bb \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439
+updater.progress.window.info=\u041d\u0430\u0436\u043c\u0438\u0442\u0435 '\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c' \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447
 Button.abort=\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c
-ConfigView.section.ipfilter.enablebanning=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u043b\u044b, \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u0441\u044b\u043b\u0430\u044e\u0449\u0438\u0435 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435
-Network.alert.acceptfail=\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 %1, %2 \u2014 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u0430\u0441\u044 [...]
+ConfigView.section.ipfilter.enablebanning=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0438\u0440\u043e\u0432, \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u0441\u044b\u043b\u0430\u044e\u0449\u0438\u0445 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435
+Network.alert.acceptfail=\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u0441\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u043f\u043e \u043f\u043e\u0440\u0442\u0443 %1, %2 - \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u [...]
 MyShares.column.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f
-UpdateWindow.restartLater=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0437\u0436\u0435
+UpdateWindow.restartLater=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0437\u0434\u043d\u0435\u0435
 MainWindow.menu.file.restart=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Vuze
 MainWindow.dialog.restartconfirmation.title=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Vuze
-MainWindow.dialog.restartconfirmation.text=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Vuze
-deletetorrent.message1=\u0412\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0435\u0441\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0434\u043b\u044f:\n
-deletetorrent.message2=\n\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?
-ConfigView.label.prioritizemostcompletedfiles=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0434\u043b\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432
-splash.plugin.init=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f:
-splash.plugin.UIinit=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430: %1  
-ConfigView.section.style.osx_small_fonts=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0435 \u0448\u0440\u0438\u0444\u0442\u044b [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
-ConfigView.section.tracker.tcpnonblocking=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0432\u0432\u043e\u0434-\u0432\u044b\u0432\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b TCP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430. \u0412\u044b\u0431\u043e\u0440 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\n\u0442\u0440\u0435\u [...]
-ConfigView.section.tracker.nonblocking=\u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c
-ConfigView.section.tracker.nonblockingconcmax=\u041c\u0430\u043a\u0441. \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+MainWindow.dialog.restartconfirmation.text=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Vuze?
+ConfigView.label.prioritizemostcompletedfiles=\u0421\u0440\u0435\u0434\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 '\u0412\u044b\u0441\u043e\u043a\u0438\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c' \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f %  [...]
+splash.plugin.init=\u0421\u0442\u0430\u0440\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u0430: 
+splash.plugin.UIinit=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430: %1  
+ConfigView.section.style.osx_small_fonts=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u043b\u044b\u0435 \u0448\u0440\u0438\u0444\u0442\u044b (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
+ConfigView.section.tracker.tcpnonblocking=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0432\u0432\u043e\u0434-\u0432\u044b\u0432\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0441 TCP. \u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b web-\u0441\u0430\u0439\u0442 \u0442\u0440\u0 [...]
+ConfigView.section.tracker.nonblocking=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0435\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+ConfigView.section.tracker.nonblockingconcmax=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
 MyTorrentsView.menu.exportmenu=\u042d\u043a\u0441\u043f\u043e\u0440\u0442
 MyTorrentsView.menu.exporttorrent=\u0422\u043e\u0440\u0440\u0435\u043d\u0442...
-ConfigView.group.scrape=\u0417\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438
-ConfigView.section.tracker.client.scrapeinfo=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u0447\u0435\u0440\u0451\u0434\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u0441\u043c\u043e\u0 [...]
-ConfigView.section.tracker.client.scrapeenable=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438
-ConfigView.section.tracker.client.scrapestoppedenable=\u041f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-Scrape.status.disabled=\u0417\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d
+ConfigView.group.scrape=\u041e\u043f\u0440\u043e\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.tracker.client.scrapeinfo=Scrape (\u043f\u043e\u0441\u043a\u0440\u0435\u0431\u044b\u0432\u0430\u043d\u0438\u0435) - \u044d\u0442\u043e \u043e\u043f\u0440\u043e\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432, \u0434\u0430\u0436\u0435 \u043 [...]
+ConfigView.section.tracker.client.scrapeenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c scrape-\u043e\u043f\u0440\u043e\u0441\u044b
+ConfigView.section.tracker.client.scrapestoppedenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c scrape-\u043e\u043f\u0440\u043e\u0441\u044b \u0438 \u0434\u043b\u044f \u043d\u0435\u0437\u0430\u043f\u0443\u0449\u0435\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+Scrape.status.disabled=Scrape-\u043e\u043f\u0440\u043e\u0441 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d
 MyTorrentsView.menu.explore=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b
 MyTorrentsView.menu.explore._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 Finder
-MyTorrentsView.menu.explore._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435
+MyTorrentsView.menu.explore._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435 Windows
 wizard.maketorrents.autohost=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443 \u043d\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0435
-ConfigView.label.overrideip=\u041f\u043e\u0441\u044b\u043b\u0430\u0435\u043c\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0430\u0434\u0440\u0435\u0441(\u0430) IP (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb)
-ConfigView.label.overrideip.tooltip=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u0430\u0445 IP, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u [...]
+ConfigView.label.overrideip=\u041f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c IP-\u0430\u0434\u0440\u0435\u0441 \u0438\u0437 \u0430\u043d\u043e\u043d\u0441\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430  -  \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0439\u0442\u0435 ';',\n\u0435\u0441\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u0438\u043d \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0435\u0442\u0435\u0439.
+ConfigView.label.overrideip.tooltip=\u0421\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0434\u0440\u0443\u0433\u043e\u0439 IP \u0430\u0434\u0440\u0435\u0441(-\u044b), \u0430 \u043d\u0435 \u0442\u043e\u0442, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0434\u0443\u0442 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u [...]
 ConfigView.section.connection.group.networks=\u0421\u0435\u0442\u0438
-ConfigView.section.connection.group.networks.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435 \u0442\u0438\u043f\u044b \u0441\u0435\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438
-ConfigView.section.connection.networks.prompt=\u0421\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.connection.networks.Public=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u0430\u044f \u0441\u0435\u0442\u044c IP (\u043d\u0435 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f)
-ConfigView.section.connection.networks.I2P=\u0421\u0435\u0442\u044c I2P
-ConfigView.section.connection.networks.Tor=\u0421\u0435\u0442\u044c The Onion Router (Tor)
+ConfigView.section.connection.group.networks.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0435 \u0442\u0438\u043f\u044b \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u04 [...]
+ConfigView.section.connection.networks.prompt=\u0421\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
+ConfigView.section.connection.networks.Public=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u0430\u044f IP \u0441\u0435\u0442\u044c (\u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0441\u043e\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f)
+ConfigView.section.connection.networks.I2P=\u0410\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f \u0441\u0435\u0442\u044c I2P
+ConfigView.section.connection.networks.Tor=\u0410\u043d\u043e\u043d\u0438\u043c\u043d\u0430\u044f \u0441\u0435\u0442\u044c The Onion Router (Tor)
 TableColumn.header.networks=\u0421\u0435\u0442\u0438
-TableColumn.header.networks.info=\u0421\u0435\u0442\u0438, \u0440\u0430\u0437\u0440\u0435\u0448\u0451\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430 \u0443\u0437\u0435\u043b-\u0443\u0437\u0435\u043b
+TableColumn.header.networks.info=\u0421\u0435\u0442\u0438, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0438\u0440<->\u043f\u0438\u0440
 Scrape.status.networkdisabled=\u0421\u0435\u0442\u044c \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430
 ConfigView.section.tracker.server.group.networks=\u0421\u0435\u0442\u0438
-ConfigView.section.tracker.server.group.networks.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0435\u0442\u0438, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0440\u0435\u043a\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0443\u0437\u043b\u044b
+ConfigView.section.tracker.server.group.networks.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0441\u0435\u0442\u0438, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0440\u0435\u043a\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u0438\u0440\u043e\u0432
 window.networkselection.title=\u0412\u044b\u0431\u043e\u0440 \u0441\u0435\u0442\u0438
-window.networkselection.info=\u0422\u043e\u0440\u0440\u0435\u043d\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c (\u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0441\u043b\u0435 [...]
-window.networkselection.description=\u0422\u043e\u0440\u0440\u0435\u043d\u0442:
+window.networkselection.info=\u0422\u043e\u0440\u0440\u0435\u043d\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u043e\u0434\u043d\u0438\u043c \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0434\ [...]
+window.networkselection.description=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 :
 plugins.basicview.clear=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-ConfigView.section.connection.group.peersources=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0443\u0437\u043b\u043e\u0432
-ConfigView.section.connection.group.peersources.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0443\u0437\u043b\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.section.connection.peersource.Tracker=\u041e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-ConfigView.section.connection.peersource.DHT=\u0414\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433
-ConfigView.section.connection.peersource.PeerExchange=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u043c \u0443\u0437\u043b\u043e\u043c
-ConfigView.section.connection.peersource.Plugin=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0443\u043b\u044f
-ConfigView.section.connection.peersource.Incoming=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f
+ConfigView.section.connection.group.peersources=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0438\u0440\u043e\u0432
+ConfigView.section.connection.group.peersources.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438\n(\u0432 \u0441\u043a\u043e\u0431\u043a\u0430\ [...]
+ConfigView.section.connection.peersource.Tracker=\u041e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 (Tracker)
+ConfigView.section.connection.peersource.DHT=\u041e\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 (DHT)
+ConfigView.section.connection.peersource.PeerExchange=\u041e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0438\u0440\u043e\u0432 (PeerExchange)
+ConfigView.section.connection.peersource.Plugin=\u041e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 (Plugin)
+ConfigView.section.connection.peersource.Incoming=\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f (Incoming)
 PeersView.source=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a
-PeersView.source.info=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u044d\u0442\u043e\u0433\u043e \u0443\u0437\u043b\u0430
-TableColumn.header.peersources=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0443\u0437\u043b\u043e\u0432
-TableColumn.header.peersources.info=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0443\u0437\u043b\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
-wizard.tracker.dht=\u0414\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 (\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 Vuze)
+PeersView.source.info=\u041e\u0442\u043a\u0443\u0434\u0430 \u0412\u0430\u043c \u0441\u0442\u0430\u043b\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043e \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0438\u0440\u0435\n(\u0441\u043c. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 - \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435)\n\n\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f:\n\n-<\u0435\u0441\u043b\u0438 \u0412\u044b \u0441\u0430\u043c\u0438 \u0443\u0 [...]
+TableColumn.header.peersources=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0438\u0440\u043e\u0432
+TableColumn.header.peersources.info=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0438\u0440\u043e\u0432, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438
+wizard.tracker.dht=\u0414\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u0441\u0435\u0442\u0438 DHT ('\u0431\u0435\u0441\u0442\u0440\u0435\u043a\u0435\u0440\u043d\u044b\u0439' \u0442\u043e\u0440\u0440\u0435\u043d\u0442)
 MyTorrentsView.menu.advancedmenu=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e
 MyTorrentsView.menu.networks=\u0421\u0435\u0442\u0438
-MyTorrentsView.menu.peersource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0443\u0437\u043b\u043e\u0432
-ConfigView.section.sharing.permitdht=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433, \u043a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
-ConfigView.section.sharing.protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u043e\u0431\u0449\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
+MyTorrentsView.menu.peersource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0438\u0440\u043e\u0432
+ConfigView.section.sharing.permitdht=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c DHT, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d (\u0434\u043b\u044f Azureus/Vuze - \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432)
+ConfigView.section.sharing.protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f share-\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432
 PeersView.Messaging=\u041e\u0431\u043c\u0435\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438
 PeersView.Messaging.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438.
-ConfigView.label.queue.newseedsmovetop=\u041f\u043e\u043c\u0435\u0449\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.label.seeding.firstPriority.ignore.info=\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430,\n\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0437 [...]
-ConfigView.label.seeding.firstPriority.ignore=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0434\u043b\u044f:
-ConfigView.label.seeding.firstPriority.ignoreSPRatio=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435:\u0443\u0437\u043b\u044b \u0432\u044b\u0448\u0435
-ConfigView.label.seeding.firstPriority.ignore0Peer=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 0 \u0443\u0437\u043b\u043e\u0432
-ConfigView.section.tracker.sendjavaversionandos=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u0435\u0440\u0441\u0438\u0438 Java \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435
-MagnetPlugin.contextmenu.exporturi=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c Magnet URI \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-ConfigView.section.plugins.dht=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414
-dht.info=\u041a\u0440\u043e\u043c\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433. \u0415\u0433\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u0 [...]
-dht.enabled=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0443\u044e \u0411\u0414
+ConfigView.label.queue.newseedsmovetop=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043d\u0430 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445 \u0441\u043f\u0438\u0441\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447
+ConfigView.label.seeding.firstPriority.ignore.info=\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\n\u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u [...]
+ConfigView.label.seeding.firstPriority.ignore=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0412\u044b\u0441\u0448\u0438\u0439 \u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0434\u043b\u044f:
+ConfigView.label.seeding.firstPriority.ignoreSPRatio=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u043c \u0421\u0438\u0434\u044b/\u041b\u0438\u0447\u0435\u0440\u044b \u0431\u043e\u043b\u0435\u0435
+ConfigView.label.seeding.firstPriority.ignore0Peer=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u0441 0 \u041b\u0438\u0447\u0435\u0440\u043e\u0432
+ConfigView.section.tracker.sendjavaversionandos=\u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u0435\u0440\u0441\u0438\u0438 Java \u0438 \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0421\u0438\u0441\u0442\u0435\u043c\u044b
+MagnetPlugin.contextmenu.exporturi=\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c Magnet URI
+ConfigView.section.plugins.dht=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0414 (azDHT)
+dht.info=\u042d\u0442\u043e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433, \u043a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0447\u0435\u0433\u043e - \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0 [...]
+dht.enabled=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0411\u0430\u0437\u0443 (azDHT)
 dht.portdefault=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0440\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-dht.port=\u041f\u043e\u0440\u0442 UDP \u0434\u043b\u044f \u0411\u0414
+dht.port=UDP \u043f\u043e\u0440\u0442 \u0434\u043b\u044f azDHT
 dht.execute.command=\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b
 dht.execute.info=\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b
 dht.execute=\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c
-dht.logging=\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c
-ConfigView.section.plugins.dhttracker=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-dhttracker.tracknormalwhenoffline=\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
-ConfigView.section.file.nativedelete._mac=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u043e\u0440\u0437\u0438\u043d\u0443
-ConfigView.section.file.nativedelete._windows=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u043e\u0440\u0437\u0438\u043d\u0443
-ConfigView.section.logging.generatediagnostics=\u0412\u044b\u0434\u0430\u0442\u044c
-ConfigView.section.logging.netinfo=\u0412\u044b\u0434\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0435\u0442\u0438
-ConfigView.section.logging.statsinfo=\u0412\u044b\u0434\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443
-ConfigView.section.logging.generatediagnostics.info=\u0412\u044b\u0434\u0430\u0442\u044c \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0435\u0451 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430 \u0438 \u0436\u0443\u0440\u043d\u0430\u043b (\u0435\u0441\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\ [...]
-ConfigView.section.sharing.privatetorrent=\u0417\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 - \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0443\u0437\u043b\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
-MainWindow.menu.tools.nattest=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c &NAT/\u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u044d\u043a\u0440\u0430\u043d
+dht.logging=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438
+ConfigView.section.plugins.dhttracker=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u0441\u0435\u0442\u0438 azDHT
+dhttracker.tracknormalwhenoffline=\u041e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u043e DHT \u043e\u0431\u044b\u043a\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d.
+ConfigView.section.file.nativedelete._mac=\u0421\u0442\u0438\u0440\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u041a\u043e\u0440\u0437\u0438\u043d\u0443
+ConfigView.section.file.nativedelete._windows=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0442\u044c \u0441\u0442\u0435\u0440\u0442\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u041a\u043e\u0440\u0437\u0438\u043d\u0443
+ConfigView.section.logging.generatediagnostics=\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+ConfigView.section.logging.netinfo=\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0435\u0442\u0438
+ConfigView.section.logging.statsinfo=\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0435
+ConfigView.section.logging.generatediagnostics.info=\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0435 \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430 \u0438 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b, \ [...]
+ConfigView.section.sharing.privatetorrent=\u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 - \u0443\u0437\u043d\u0430\u0432\u0430\u0442\u044c \u043e \u043f\u0438\u0440\u0430\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 (PEX \u0438 DHT \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b)
+MainWindow.menu.tools.nattest=\u0422\u0435\u0441\u0442 &NAT / \u0424\u0430\u0439\u0440\u0432\u043e\u043b\u043b
 Button.apply=\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c
 Button.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
 window.welcome.title=\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 Vuze %1
 #file can be a URL or a path in the jar
-MainWindow.menu.help.releasenotes=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u044f \u043a \u0432\u044b\u043f\u0443\u0441\u043a\u0443
-dht.reseed.label=\u041e\u0431\u044b\u0447\u043d\u043e \u043e\u0447\u0438\u0449\u0435\u043d\u0438\u0435 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0411\u0414 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043d\u0435\u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u044 [...]
-dht.reseed.group=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-dht.reseed.ip=\u0410\u0434\u0440\u0435\u0441 IP
+MainWindow.menu.help.releasenotes=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e \u0440\u0435\u043b\u0438\u0437\u0435
+dht.reseed.label=\u041e\u0431\u044b\u0447\u043d\u043e, \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0435 \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0411\u0430\u0437\u044b (AzDHT) \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u043 [...]
+dht.reseed.group=\u041f\u0435\u0440\u0435\u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+dht.reseed.ip=IP \u0430\u0434\u0440\u0435\u0441
 dht.reseed.port=\u041f\u043e\u0440\u0442
-dht.reseed=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-dht.reseed.info=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0411\u0414
+dht.reseed=\u041f\u0435\u0440\u0435\u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+dht.reseed.info=\u041f\u0435\u0440\u0435\u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c azDHT
 dht.diagnostics.group=\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430
-DHTView.title.full=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414
-DHTView.title.fullcvs=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414 CVS
+DHTView.title.full=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 (azDHT)
+DHTView.title.fullcvs=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 (azDHT) CVS
 DHTView.general.title=\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435
 DHTView.general.uptime=\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b:
-DHTView.general.users=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:
-DHTView.general.nodes=\u0423\u0437\u043b\u043e\u0432:
-DHTView.general.leaves=\u041a\u043e\u043d\u0446\u0435\u0432\u044b\u0445:
-DHTView.general.contacts=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439:
-DHTView.general.replacements=\u0417\u0430\u043c\u0435\u043d:
-DHTView.general.live=\u0416\u0438\u0432\u044b\u0445:
-DHTView.general.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445:
-DHTView.general.dying=\u041c\u0435\u0440\u0442\u0432\u044b\u0445:
-DHTView.transport.title=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438
+DHTView.general.users=\u041f\u0438\u0440\u043e\u0432:
+DHTView.general.nodes=\u0412\u0435\u0442\u043a\u0438:
+DHTView.general.leaves=\u041b\u0438\u0441\u0442\u044c\u044f:
+DHTView.general.contacts=\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u044b:
+DHTView.general.replacements=\u0417\u0430\u043c\u0435\u043d\u044b:
+DHTView.general.live=\u041d\u0430 \u0441\u0432\u044f\u0437\u0438:
+DHTView.general.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e:
+DHTView.general.dying=\u041c\u043e\u043b\u0447\u0430\u0442:
+DHTView.transport.title=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445
 DHTView.transport.packets=\u041f\u0430\u043a\u0435\u0442\u043e\u0432
 DHTView.transport.bytes=\u0411\u0430\u0439\u0442
 DHTView.transport.received=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
 DHTView.transport.sent=\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
-DHTView.transport.in=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435:
-DHTView.transport.out=\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430:
+DHTView.transport.in=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 :
+DHTView.transport.out=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 :
 DHTView.operations.title=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438
 DHTView.operations.sent=\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
 DHTView.operations.ok=\u0423\u0434\u0430\u0447\u043d\u043e
 DHTView.operations.failed=\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u043e
-DHTView.operations.received=\u041f\u0440\u0438\u043d\u044f\u0442\u043e
-DHTView.operations.ping=\u041e\u043f\u0440\u043e\u0441
+DHTView.operations.received=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
+DHTView.operations.ping=\u041e\u043f\u0440\u043e\u0441 (Ping)
 DHTView.operations.findNode=\u041f\u043e\u0438\u0441\u043a \u0443\u0437\u043b\u0430
 DHTView.operations.findValue=\u041f\u043e\u0438\u0441\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f
-DHTView.operations.store=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435
+DHTView.operations.store=\u0417\u0430\u043f\u0438\u0441\u0438
 DHTView.activity.title=\u0410\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c
-DHTView.activity.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+DHTView.activity.status=\u0421\u0442\u0430\u0442\u0443\u0441
 DHTView.activity.status.true=\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-DHTView.activity.status.false=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f
+DHTView.activity.status.false=\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442
 DHTView.activity.type=\u0422\u0438\u043f
-DHTView.activity.type.1=\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
-DHTView.activity.type.2=\u0412\u043d\u0435\u0448\u043d\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
-DHTView.activity.type.3=\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435
-DHTView.activity.type.4=\u0412\u043d\u0435\u0448\u043d\u0435\u0435 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435
+DHTView.activity.type.1=\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435
+DHTView.activity.type.2=\u0412\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435
+DHTView.activity.type.3=\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435
+DHTView.activity.type.4=\u0412\u043d\u0435\u0448\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435
 DHTView.activity.target=\u0426\u0435\u043b\u044c
 DHTView.activity.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-DHTView.db.title=\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445
+DHTView.db.title=\u0411\u0430\u0437\u0430 \u0414\u0430\u043d\u043d\u044b\u0445 azDHT
 DHTView.db.keys=\u041a\u043b\u044e\u0447\u0438
 DHTView.db.values=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f
 DHTView.db.local=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u043e
-DHTView.db.direct=\u041d\u0430\u043f\u0440\u044f\u043c\u0443\u044e
+DHTView.db.direct=\u041f\u0440\u044f\u043c\u043e
 DHTView.db.indirect=\u041a\u043e\u0441\u0432\u0435\u043d\u043d\u043e
-DHTView.db.divfreq=\u0427\u0430\u0441\u0442\u043e\u0442\u0430 Div.
+DHTView.db.divfreq=\u0427\u0430\u0441\u0442\u043e\u0442\u0430. Div.
 DHTView.db.divsize=\u0420\u0430\u0437\u043c\u0435\u0440 Div.
-MainWindow.dht.status.tooltip=\u041a\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414, \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u0 [...]
-MainWindow.dht.status.disabled=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e
-MainWindow.dht.status.failed=DHT \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c
-MainWindow.dht.status.initializing=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f
-MainWindow.dht.status.users=%1 \u0443\u0437\u043b\u043e\u0432
-MainWindow.dht.status.unreachable=DHT \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c
-MainWindow.dht.status.unreachabletooltip=\u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0440\u0442\u043e\u0432 UDP \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0411\u0414 (\u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u044d\u043a\u0440\u0430\u043d \u0438\u043b\u0438 NAT)
+MainWindow.dht.status.tooltip=\u041a\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 (azDHT), \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u [...]
+MainWindow.dht.status.disabled=azDHT \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+MainWindow.dht.status.failed=\u0417\u0430\u043f\u0443\u0441\u043a azDHT \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u043d
+MainWindow.dht.status.initializing=\u0417\u0430\u043f\u0443\u0441\u043a azDHT
+MainWindow.dht.status.users=azDHT: %1 \u043f\u0438\u0440\u043e\u0432
+MainWindow.dht.status.unreachable=azDHT \u0437\u0430\u043a\u0440\u044b\u0442\u0430 \u0444\u0430\u0439\u0440\u0432\u043e\u043b\u043b\u043e\u043c
+MainWindow.dht.status.unreachabletooltip=\u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c UDP-\u043f\u043e\u0440\u0442\u043e\u0432 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0411\u0430\u0437\u044b azDHT (\u0441\u043c. \u0422\u0435\u0441\u0442 NAT/\u0424\u0430\u0439\u0440\u0432\u043e\u043b\u043b)
 MyTorrentsView.menu.setUpSpeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-MyTorrentsView.menu.setDownSpeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-ConfigView.section.tracker.client.showwarnings=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f, \u0432\u044b\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
+MyTorrentsView.menu.setDownSpeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+ConfigView.section.tracker.client.showwarnings=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f, \u0432\u044b\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438
 dht.advanced=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
-dht.advanced.group=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
+dht.advanced.group=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 dht.advanced.label=\u041c\u0435\u043d\u044f\u0439\u0442\u0435 \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0432\u044b \u0434\u0435\u043b\u0430\u0435\u0442\u0435
-dht.override.ip=\u041f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0430\u0434\u0440\u0435\u0441 IP
+dht.override.ip=\u041f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441
 ConfigView.section.logging.loggerenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b
-ConfigView.section.ipfilter.blockbanning=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0438\u0437 256 \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u0435\u0441\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0443\u0436\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u04 [...]
+ConfigView.section.ipfilter.blockbanning=\u0417\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0431\u043b\u043e\u043a \u0438\u0437 256 \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u0435\u0441\u043b\u0438 \u0438\u0437 \u0431\u043b\u043e\u043a\u0430 \u0443\u0436\u0435 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c
 MyTrackerView.passive=\u041f\u0430\u0441\u0441\u0438\u0432\u043d\u044b\u0439
-TableColumn.header.swarm_average_speed=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
-TableColumn.header.swarm_average_speed.info=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0443\u0437\u043b\u043e\u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
+TableColumn.header.swarm_average_speed=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+TableColumn.header.swarm_average_speed.info=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0443 \u043f\u0438\u0440\u043e\u0432 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
 TableColumn.header.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
-TableColumn.header.comment.info=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-TableColumn.header.commenticon=\u0417\u043d\u0430\u0447\u043e\u043a \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f
-TableColumn.header.commenticon.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u043e\u043a, \u0435\u0441\u043b\u0438 \u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 
+TableColumn.header.comment.info=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435
+TableColumn.header.commenticon=\u0418\u043a\u043e\u043d\u043a\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f
+TableColumn.header.commenticon.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0438\u043a\u043e\u043d\u043a\u0443, \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
 MyTrackerView.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f
-MainWindow.menu.file.open.torrentfortracking=\u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
-VivaldiView.title.full=\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438
-VivaldiView.title.fullcvs=\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438 CVS
-VivaldiView.title.full_v6=\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438 IPv6
+MainWindow.menu.file.open.torrentfortracking=\u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b... (\u0422\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0432\u043e\u0435\u043c \u0422\u0440\u0435\u043a\u0435\u0440\u0435)
+VivaldiView.title.full=\u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438
+VivaldiView.title.fullcvs=\u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438 CVS
+VivaldiView.title.full_v6=\u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438 IPv6
 MyTrackerView.date_added=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d
-ConfigView.section.tracker.portbackup=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u044b (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb)
+ConfigView.section.tracker.portbackup=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043f\u043e\u0440\u0442\u044b (\u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 ';')
 ConfigView.label.playfilespeech=\u041f\u0440\u043e\u0438\u0437\u043d\u043e\u0441\u0438\u0442\u044c \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440\u043e\u043c \u0433\u043e\u043b\u043e\u0441\u0430 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430
-ConfigView.label.playfilespeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u0433\u043e\u043b\u043e\u0441\u0430 \u043f\u043e\u043a\u0430 \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u043c \u044f\u0437\u044b\u043a\u043e\u043c
-ConfigView.label.playfilefinished=\u0417\u0432\u0443\u043a \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430
-ConfigView.label.backupconfigfiles=\u0414\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u044f
-ConfigView.section.tracker.client.scrapesingleonly=\u041d\u0435 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c (\u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 414: URL too long)
+ConfigView.label.playfilefinished=\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0443
+ConfigView.label.backupconfigfiles=\u0414\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0430\u0432\u0430\u0440\u0438\u0438
+ConfigView.section.tracker.client.scrapesingleonly=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 scrape-\u043e\u043f\u0440\u043e\u0441\u043e\u0432 (\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 414-'URL \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u044b\u0439')
 dht.ipfilter.log=\u0412\u0435\u0441\u0442\u0438 \u0436\u0443\u0440\u043d\u0430\u043b \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0439 IP \u0444\u0438\u043b\u044c\u0442\u0440\u0430 
-ConfigView.label.seeding.addForSeedingDLCopyCount=\u0421\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u00ab\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438\u00bb \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u043c\u0435\u044e\u0442 \u0434\u0430\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043f\u0438\u0439
-ActivityView.legend.limit=\u041f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u0430\u044f
-ActivityView.legend.achieved=\u041c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f
-ActivityView.legend.overhead=\u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430
+ConfigView.label.seeding.addForSeedingDLCopyCount=\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0443\u0436\u0435 \u0441\u043a\u0430\u0447\u0430\u043d\u044b \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043f\u04 [...]
+ActivityView.legend.limit=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+ActivityView.legend.achieved=\u0414\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
+ActivityView.legend.overhead=\u041f\u043e\u0442\u043e\u043b\u043e\u043a \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
 ActivityView.legend.peeraverage=\u0421\u0440\u0435\u0434\u043d\u044f\u044f
-ActivityView.legend.swarmaverage=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u043f\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044e
-ActivityView.legend.trimmed=\u0417\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0430 (\u043f\u0443\u043d\u043a\u0442\u0438\u0440)
+ActivityView.legend.swarmaverage=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+ActivityView.legend.trimmed=\u0421\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f (\u043f\u0443\u043d\u043a\u0442\u0438\u0440)
 MyTorrentsView.menu.movemenu=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b
 MyTorrentsView.menu.movedata=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438...
-MyTorrentsView.menu.movetorrent=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b...
+MyTorrentsView.menu.movetorrent=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c torrent-\u0444\u0430\u0439\u043b...
 MyTorrentsView.menu.movedata.dialog=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u043c\u0435\u0441\u0442\u043e
 DHTView.operations.data=\u0414\u0430\u043d\u043d\u044b\u0435
-DHTView.general.reachable=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d:
-ConfigView.label.queue.maxactivetorrentswhenseeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c, \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0430\u0447\u0430 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-Views.plugins.IRC.title=IRC \u2014 \u0441\u043b\u0443\u0436\u0431\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0432 \u0441\u0435\u0442\u0438
+DHTView.general.reachable=\u0414\u043e\u0441\u0442\u0443\u043f\u043d:
+DHTView.general.rendezvous=\u0412\u0441\u0442\u0440\u0435\u0447\u0438:
+ConfigView.label.queue.maxactivetorrentswhenseeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c, \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0430\u0447\u0430 [0:\u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+Views.plugins.IRC.title=IRC - \u041e\u043d\u043b\u0430\u0439\u043d\u043e\u0432\u0430\u044f \u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430
 Formats.units.persec=/\u0441
 Formats.units.TiB=\u0422\u0438\u0411
 Formats.units.Tibit=\u0422\u0438\u0431\u0438\u0442
@@ -1578,1183 +1568,2104 @@ Formats.units.Tbit=\u0422\u0431\u0438\u0442
 Formats.units.GiB=\u0413\u0438\u0411
 Formats.units.Gibit=\u0413\u0438\u0431\u0438\u0442
 Formats.units.GB=\u0413\u0411
-Formats.units.Gbit=\u0413\u0431\u0438\u0442
+Formats.units.Gbit=\u0413\u0411\u0438\u0442
 Formats.units.MiB=\u041c\u0438\u0411
 Formats.units.Mibit=\u041c\u0438\u0431\u0438\u0442
 Formats.units.MB=\u041c\u0411
 Formats.units.Mbit=\u041c\u0431\u0438\u0442
 Formats.units.KiB=\u041a\u0438\u0411
 Formats.units.Kibit=K\u0438\u0431\u0438\u0442
-Formats.units.kB=\u041a\u0411
+Formats.units.kB=\u043a\u0411
 Formats.units.KB=\u041a\u0411
 Formats.units.kbit=\u043a\u0431\u0438\u0442
 Formats.units.B=\u0411
 Formats.units.bit=\u0431\u0438\u0442
 Formats.units.alot=\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e !!!
 ConfigView.section.ipfilter.persistblocking=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 IP \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
-FilesView.menu.rename=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438
-FilesView.menu.rename_only=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c
-FilesView.menu.retarget=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c
+FilesView.menu.rename=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c
+FilesView.menu.rename_only=\u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435
+FilesView.menu.retarget=\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c
 FilesView.rename.choose.path=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0438\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b
 FilesView.rename.choose.path.dir=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0438\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u0430\u043f\u043a\u0443
-FilesView.rename.confirm.delete.title=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435
-FilesView.rename.confirm.delete.text=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 '%1'
+FilesView.rename.confirm.delete.title=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0441\u0442\u0438\u0440\u0430\u043d\u0438\u0435
+FilesView.rename.confirm.delete.text=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0441\u0442\u0438\u0440\u0430\u043d\u0438\u0435 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 '%1'
 FilesView.rename.filename.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b
 FilesView.rename.filename.text=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430
-ConfigView.higher.mode.available=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445
-ConfigView.section.mode=\u0420\u0435\u0436\u0438\u043c
-ConfigView.section.mode.title=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+ConfigView.higher.mode.available=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f \u0432\u044b\u0441\u0448\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f
+ConfigView.section.mode=\u0420\u0435\u0436\u0438\u043c (\u043e\u043f\u044b\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f)
+ConfigView.section.mode.title=\u0421\u0442\u0435\u043f\u0435\u043d\u044c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
 ConfigView.section.mode.beginner=\u041d\u043e\u0432\u0438\u0447\u043e\u043a
 ConfigView.section.mode.beginner.wiki.definitions=\u0421\u043b\u043e\u0432\u0430\u0440\u044c BitTorrent
 ConfigView.section.mode.intermediate=\u041e\u043f\u044b\u0442\u043d\u044b\u0439
-ConfigView.section.mode.intermediate.wiki.host=\u0420\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
-ConfigView.section.mode.intermediate.wiki.publish=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432
-ConfigView.section.mode.advanced=\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439
-ConfigView.section.mode.advanced.wiki.main=\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0412\u0438\u043a\u0438
-ConfigView.section.mode.beginner.text=\u0412\u0441\u0451, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f [...]
-ConfigView.section.mode.intermediate.text=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0430.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u04 [...]
-ConfigView.section.mode.advanced.text=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0435\u0442\u0435\u0432\u044b\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u043d\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 MTU \u0438\u043b\u0438 \u043d\u0435\u0431\u043b\u043e\ [...]
-Files.column.storagetype=\u0422\u0438\u043f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430
+ConfigView.section.mode.intermediate.wiki.host=\u0425\u043e\u0441\u0442\u0438\u043d\u0433 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.mode.intermediate.wiki.publish=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.mode.advanced=\u041f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b
+ConfigView.section.mode.advanced.wiki.main=\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 Wiki
+ConfigView.section.mode.beginner.text=\u0412\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e - \u044d\ [...]
+ConfigView.section.mode.intermediate.text=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u0442\u0440\u0435\u043a\u0435\u0440\u0430.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438  \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u [...]
+ConfigView.section.mode.advanced.text=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0435\u0442\u0435\u0432\u044b\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0440\u0435\u0436\u0438\u043c, \u0435\u0441\u043b\u0438 \u0432\u044b \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u0442\u0435 \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 MTU \u0438\u043b\u0438 \ [...]
+Files.column.storagetype=\u0422\u0438\u043f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
 Files.column.fileext=\u0422\u0438\u043f
 FileItem.storage.linear=\u041b\u0438\u043d\u0435\u0439\u043d\u044b\u0439
 FileItem.storage.compact=\u041a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439
 MessageBoxWindow.rememberdecision=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043c\u043e\u0439 \u0432\u044b\u0431\u043e\u0440
-ConfigView.section.interface.cleardecisions=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0432 \u0434\u0438\u0430\u043b\u043e\u0433\u0430\u0445
+ConfigView.section.interface.cleardecisions=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440 \u0432 \u0434\u0438\u0430\u043b\u043e\u0433\u0430\u0445
 ConfigView.section.interface.cleardecisionsbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-ConfigView.section.interface.cleartrackers=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432
+ConfigView.section.interface.cleartrackers=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u044b
 ConfigView.section.interface.cleartrackersbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
-ConfigView.section.interface.clearsavepaths=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0443\u0442\u0435\u0439 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+ConfigView.section.interface.clearsavepaths=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
 ConfigView.section.interface.clearsavepathsbutton=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
 configureWizard.welcome.usermodes=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u043e\u043f\u044b\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b > \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u041e\u043d\u0438 \u0437\u0430\u0434\u0430\u [...]
 FilesView.skip.confirm.delete.text=\u041e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b '%1' \u0434\u043b\u044f \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0438 \u043c\u0435\u0441\u0442\u0430?
-FilesView.rename.failed.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u041f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c
+FilesView.rename.failed.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435/\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c
 FilesView.rename.failed.text=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u0430, \u0432\u043e\u0437\u043e\u043c\u0436\u043d\u043e \u0438\u0437-\u0437\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0446\u0435\u043b\u0438
-diagnostics.log_found=Vuze \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 <A HREF="%1">\u0436\u0443\u0440\u043d\u0430\u043b\u0435</A>. \u0422\u0430\u043a\u0436\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0412\u0438\u043a\u0438: <A HREF [...]
-ManagerItem.paused=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
-Utils.link.visit=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435
-ConfigView.section.connection.serverport.wiki=\u041a\u0430\u043a\u0438\u0435 \u043f\u043e\u0440\u0442\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c
+diagnostics.log_found=Vuze \u043d\u0435 \u0431\u044b\u043b \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 <A HREF="%1">diagnostic log files</A>.\n\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0447\u0442\u0438\u0442\u0435 wiki-\u0441\u0442\u0430\u0442\u044c\u044e  <A HREF="http://www.azureuswiki.com/index.php/Vu [...]
+ManagerItem.paused=\u041f\u0430\u0443\u0437\u0430
+Utils.link.visit=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435:
+ConfigView.section.connection.serverport.wiki=\u0412\u044b\u0431\u043e\u0440 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u043f\u043e\u0440\u0442\u043e\u0432
 ConfigView.section.transfer.speeds.wiki=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
-installPluginsWizard.installMode.info.title=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
-installPluginsWizard.installMode.info.text=\u041c\u043e\u0434\u0443\u043b\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b Vuze. \u041e\u043d\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0 [...]
-Views.plugins.Distributed.DB.title=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414
-Views.plugins.Distributed.Tracker.title=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
-Views.plugins.Plugin.Update.title=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f
-Views.plugins.UPnP.title.tooltip=\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 Plug and Play
-openUrl.url.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f http, https, magnet \u0438 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 infohash
-TableColumn.header.swarm_average_completion=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0441\u0442\u0438
-TableColumn.header.swarm_average_completion.info=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
-GeneralView.label.swarm_average_completion=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0441\u0442\u044c:
-GeneralView.label.swarm_average_completion.tooltip=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0441\u0442\u044c \u0441\u0440\u0435\u0434\u0438 \u0443\u0437\u043b\u043e\u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
-MainWindow.nat.status.tooltip.unknown=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0435 \u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0447\u0435\u0440\u0435\u0437 NAT (TCP) \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430
-MainWindow.nat.status.tooltip.ok=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437\u0432\u043d\u0435 (TCP)
-MainWindow.nat.status.tooltip.probok=\u0411\u044b\u043b \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437\u0432\u043d\u0435, \u043d\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e TCP \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f
-MainWindow.nat.status.bad=\u0417\u0430 \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c
-MainWindow.nat.status.tooltip.bad=\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c \u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c \u0447\u0435\u0440\u0435\u0437 NAT (TCP). \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0435 \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0412\u0438\u0 [...]
-plugin.installer.recommended.plugin=\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u2014 \u043e\u0446\u0435\u043d\u0438\u0442\u0435 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e
+installPluginsWizard.installMode.info.title=\u0418\u043d\u0444\u043e
+installPluginsWizard.installMode.info.text=\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b Vuze, \u043e\u043d\u0438 \u043d\u0435\u0441\u0443\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\ [...]
+Views.plugins.Distributed.DB.title=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0414 (azDHT)
+Views.plugins.Distributed.Tracker.title=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0422\u0440\u0435\u043a\u0435\u0440
+Views.plugins.Plugin.Update.title=\u0410\u043f\u0434\u0435\u0439\u0442 \u041f\u043b\u0430\u0433\u0438\u043d\u0430
+Views.plugins.UPnP.title.tooltip=\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439  Plug and Play
+openUrl.url.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f http, https, magnet \u0438 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u0435\u0440\u0438\u0447\u043d\u044b\u0435 \u0438\u043d\u0444\u043e-\u0445\u044d\u0448 \u0441\u0442\u0440\u043e\u043a\u0438
+TableColumn.header.swarm_average_completion=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0443 \u043b\u0438\u0447\u0435\u0440\u043e\u0432
+TableColumn.header.swarm_average_completion.info=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0443 \u043b\u0438\u0447\u0435\u0440\u043e\u0432 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+GeneralView.label.swarm_average_completion=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u044c:
+GeneralView.label.swarm_average_completion.tooltip=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u043b\u0438\u0447\u0435\u0440\u043e\u0432
+MainWindow.nat.status.tooltip.unknown=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0411\u0440\u0430\u0443\u043d\u0434\u043c\u0430\u0443\u044d\u0440\u0430 \u0438\u043b\u0438 NAT \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 (TCP)
+MainWindow.nat.status.tooltip.ok=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0440\u0442\u0430 \u0432 \u043d\u043e\u0440\u043c\u0435 (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b TCP)
+MainWindow.nat.status.tooltip.probok=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0432 \u043d\u043e\u0440\u043c\u0435, \u043e\u0434\u043d\u0430\u043a\u043e \u043d\u0435\u0442 \u043d\u0435\u0434\u0430\u0432\u043d\u0438\u0445 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 TCP-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+MainWindow.nat.status.bad=\u0417\u0430\u043a\u0440\u044b\u0442\u043e \u0424\u0430\u0439\u0440\u0432\u043e\u043b\u043b\u043e\u043c
+MainWindow.nat.status.tooltip.bad=\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u0412\u0430\u0448\u0435\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c\u044e \u0438\u0437-\u0437\u0430 \u0424\u0430\u0439\u0440\u0432\u043e\u043b\u043b\u0430 \u0438\u043b\u0438 NAT. \u0417\u0430\u0433\u043b\u044f\u043d\u0438\u0442\u0435 \u0432 Wiki \u0434\u043b\u044f \u043f\u043e\u043c\u043e\u0449\u0438
+plugin.installer.recommended.plugin=\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d - \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u044c\u0442\u0435\u0441\u044c \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e.
 LoggerView.pause=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
 LoggerView.clear=&\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c
 LoggerView.filter=\u0424\u0438\u043b\u044c\u0442\u0440
-LoggerView.filter.uncheckAll=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440
-LoggerView.filter.checkAll=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0451
+LoggerView.filter.uncheckAll=\u0421\u043d\u044f\u0442\u044c \u043f\u043e\u043c\u0435\u0442\u043a\u0443 \u0443 \u0432\u0441\u0435\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439
+LoggerView.filter.checkAll=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
 LoggerView.loggingDisabled=\u0416\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e.
-LoggerView.includeOnly=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a\u0438, \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0435 \u0441 \u0440\u0435\u0433. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c:
-LoggerView.excludeAll=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438, \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0435 \u0441 \u0440\u0435\u0433. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c:
+LoggerView.includeOnly=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a\u0438, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044e:
+LoggerView.excludeAll=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044e:
 ConfigView.section.logging.log0type=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
 ConfigView.section.logging.log1type=\u041f\u0440\u0438\u043d\u044f\u0442\u043e
 ConfigView.section.logging.log2type=\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e
 ConfigView.section.logging.filter=\u0424\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0432 \u0444\u0430\u0439\u043b
-ConfigView.section.logging.level=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0437\u0430\u043f\u0438\u0441\u0438
-ConfigView.section.logging.showLogsFor=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u00ab%1\u00bb \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c:
-ConfigView.pluginlist.column.loadAtStartup=\u0410\u0432\u0442\u043e\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+ConfigView.section.logging.level=\u0421\u0442\u0435\u043f\u0435\u043d\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430
+ConfigView.section.logging.showLogsFor=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c %1 \u0436\u0443\u0440\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u043e\u0433\u043e\u0432 \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439:
+ConfigView.pluginlist.column.loadAtStartup=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435
 ConfigView.pluginlist.column.type=\u0422\u0438\u043f
-ConfigView.pluginlist.column.type.perUser=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439
-ConfigView.pluginlist.column.type.shared=\u041e\u0431\u0449\u0438\u0439
+ConfigView.pluginlist.column.type.perUser=\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+ConfigView.pluginlist.column.type.shared=\u0420\u0430\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439
 ConfigView.pluginlist.column.type.builtIn=\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439
-ConfigView.pluginlist.column.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
+ConfigView.pluginlist.column.name=\u0418\u043c\u044f
 ConfigView.pluginlist.column.version=\u0412\u0435\u0440\u0441\u0438\u044f
 ConfigView.pluginlist.column.directory=\u041f\u0430\u043f\u043a\u0430
 ConfigView.pluginlist.column.isOperational=\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442?
 PeersView.BlockView.Avail.Have=\u0415\u0441\u0442\u044c \u0443 \u043e\u0431\u043e\u0438\u0445
-PeersView.BlockView.Avail.NoHave=\u0422\u043e\u043b\u044c\u043a\u043e \u0443 \u0443\u0437\u043b\u0430
-PeersView.BlockView.NoAvail.Have=\u0422\u043e\u043b\u044c\u043a\u043e \u0443 \u043c\u0435\u043d\u044f
-PeersView.BlockView.NoAvail.NoHave=\u041d\u0435\u0442 \u0443 \u043e\u0431\u043e\u0438\u0445
-PeersView.BlockView.Transfer=\u041f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f
+PeersView.BlockView.Avail.NoHave=\u0423 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430 \u0435\u0441\u0442\u044c; \u0423 \u0412\u0430\u0441 \u043d\u0435\u0442
+PeersView.BlockView.NoAvail.Have=\u0423 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c; \u0423 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430 \u043d\u0435\u0442
+PeersView.BlockView.NoAvail.NoHave=\u0423 \u043e\u0431\u043e\u0438\u0445 \u043d\u0435\u0442
+PeersView.BlockView.Transfer=\u041f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0441\u0435\u0439\u0447\u0430\u0441
 PeersView.BlockView.NextRequest=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
 PeersView.BlockView.title=\u041a\u0430\u0440\u0442\u0430 \u0447\u0430\u0441\u0442\u0435\u0439
-PeersView.BlockView.AvailCount=\u0418\u043d\u0434\u0435\u043a\u0441 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438
-MyTorrentsView.dialog.NumberError.title=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0447\u0438\u0441\u043b\u043e
-MyTorrentsView.dialog.NumberError.text=\u0412\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0438\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043e.
-MyTorrentsView.menu.manual=&\u0417\u0430\u0434\u0430\u0442\u044c...
-MyTorrentsView.menu.manual.per_torrent=\u0417\u0430\u0434\u0430\u0442\u044c (\u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442)
-MyTorrentsView.menu.manual.shared_torrents=\u0417\u0430\u0434\u0430\u0442\u044c (\u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432)
-MyTorrentsView.dialog.setSpeed.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (%1)
+PeersView.BlockView.AvailCount=\u0421\u0447\u0451\u0442\u0447\u0438\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438
+MyTorrentsView.dialog.NumberError.title=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u043d\u0435\u0440\u0430\u0437\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e
+MyTorrentsView.dialog.NumberError.text=\u0412\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u0438\u043b\u0438 \u043d\u0435\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0435.
+MyTorrentsView.menu.manual=&\u0417\u0430\u0434\u0430\u0442\u044c..
+MyTorrentsView.menu.manual.per_torrent=\u0412\u0440\u0443\u0447\u043d\u0443\u044e (\u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442)
+MyTorrentsView.menu.manual.shared_torrents=\u0412\u0440\u0443\u0447\u043d\u0443\u044e (\u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043d\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+MyTorrentsView.dialog.setSpeed.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c %1 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
 # %1 = "in kbps" or ""; %2 = "upload" or "download"
-MyTorrentsView.dialog.setNumber.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 %1, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u0430 \u00ab%2\u00bb:
+MyTorrentsView.dialog.setNumber.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e %1 \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c %2 \u043d\u0430:
 MyTorrentsView.dialog.setNumber.upload=\u0420\u0430\u0437\u0434\u0430\u0447\u0430
 MyTorrentsView.dialog.setNumber.download=\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
-MyTorrentsView.dialog.setNumber.inKbps=\u0432 %1
+MyTorrentsView.dialog.setNumber.inKbps=\u0432 \u041a\u0411/\u0441
 OpenTorrentWindow.torrentLocation=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:
-OpenTorrentWindow.addFiles.URL=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c &\u0430\u0434\u0440\u0435\u0441
-OpenTorrentWindow.addFiles.Folder=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c &\u043f\u0430\u043f\u043a\u0443
-OpenTorrentWindow.addFiles.Clipboard=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430
+OpenTorrentWindow.addFiles.URL=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c URL
+OpenTorrentWindow.addFiles.Folder=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c &\u041f\u0430\u043f\u043a\u0443
+OpenTorrentWindow.addFiles.Clipboard=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437 \u0411\u0443\u0444\u0435\u0440\u0430 \u041e\u0431\u043c\u0435\u043d\u0430
 OpenTorrentWindow.changeDestination=\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f
-OpenTorrentWindow.fileList=\u0424\u0430\u0439\u043b\u043e\u0432 \u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u0445:
-OpenTorrentWindow.torrentTable.name=\u0418\u043c\u044f
-OpenTorrentWindow.torrentTable.saveLocation=\u041f\u0443\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+OpenTorrentWindow.fileList=\u0424\u0430\u0439\u043b\u044b \u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u0445:
+OpenTorrentWindow.torrentTable.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
+OpenTorrentWindow.torrentTable.saveLocation=\u041c\u0435\u0441\u0442\u043e \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
 OpenTorrentWindow.fileTable.fileName=\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430
 OpenTorrentWindow.fileTable.size=\u0420\u0430\u0437\u043c\u0435\u0440
 OpenTorrentWindow.fileTable.destinationName=\u041a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
-OpenTorrentWindow.startMode.seeding=\u0420\u0430\u0437\u0434\u0430\u0447\u0430
+OpenTorrentWindow.startMode.seeding=\u0422\u043e\u043b\u044c\u043a\u043e \u0420\u0430\u0437\u0434\u0430\u0447\u0430
 OpenTorrentWindow.fileList.changeDestination=\u041f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
 OpenTorrentWindow.mb.badSize.title=\u0424\u0430\u0439\u043b \u043d\u0435\u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0430
 OpenTorrentWindow.mb.badSize.text='%1' \u043d\u0435 '%2' \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f
-OpenTorrentWindow.mb.alreadyExists.text=<A HREF="%1">%3</A> \u0443\u0436\u0435 \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043a\u0430\u043a \u00ab%2\u00bb
+OpenTorrentWindow.mb.alreadyExists.text=\u0422\u043e\u0440\u0440\u0435\u043d\u0442 '%1' \u0443\u0436\u0435 \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c '%2'
 OpenTorrentWindow.mb.alreadyExists.default.name=\u041c\u0435\u0434\u0438\u0430
 OpenTorrentWindow.mb.alreadyExists.title=\u0422\u0430\u043a\u043e\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
 OpenTorrentWindow.mb.openError.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0444\u0430\u0439\u043b\u0430
-OpenTorrentWindow.mb.openError.text=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u00ab%1\u00bb:
+OpenTorrentWindow.mb.openError.text='%1' \u043d\u0435 \u0443\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u044c:
 OpenTorrentWindow.torrent.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438\u0437 \u043b\u0438\u0441\u0442\u0430
-OpenTorrentWindow.torrent.options=\u041a \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:
+OpenTorrentWindow.torrent.options=\u041a \u0432\u044b\u0448\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:
 OpenTorrentWindow.xOfTotal=(%1 \u0438\u0437 %2)
-iconBar.open.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0444\u0430\u0439\u043b \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+iconBar.open.tooltip=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u0444\u0430\u0439\u043b
 LocaleUtil.column.text=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442
-Tracker.tooltip.MultiSupport=\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0445\u0435\u0448\u0435\u0439.
-Tracker.tooltip.NoMultiSupport=\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0445\u0435\u0448\u0435\u0439.\n\u042d\u0442\u043e \u043d\u0435 \u0441\u043d\u0438\u0437\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c Vuze, \u043d\u043e \u043e\u0431\u0440\u0 [...]
-ConfigView.label.lazybitfield=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u00ab\u043b\u0435\u043d\u0438\u0432\u043e\u0435\u00bb \u043f\u043e\u043b\u0435 \u0431\u0438\u0442\u043e\u0432 (\u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0432 \u0441\u0435\u0442\u044f\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a [...]
+Tracker.tooltip.MultiSupport=\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0445\u044d\u0448-\u043e\u043f\u0440\u043e\u0441\u044b \u0437\u0430 \u0441\u0435\u0430\u043d\u0441 \u0441\u0432\u044f\u0437\u0438.
+Tracker.tooltip.NoMultiSupport=\u042d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440 \u041d\u0415 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0445\u044d\u0448-\u043e\u043f\u0440\u043e\u0441\u044b \u0437\u0430 \u0441\u0435\u0430\u043d\u0441 \u0441\u0432\u044f\u0437\u0438.\n\u042d\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0432\u0430\u0448\ [...]
+ConfigView.label.lazybitfield=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c '\u043b\u0435\u043d\u0438\u0432\u043e\u0435' \u0431\u0438\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435 (\u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u0435\u0442\u044f\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u0431\u043b\u04 [...]
 LoggerView.realtime=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438
-ConfigView.section.file.perf.cache.flushpieces=\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u0441\u0440\u0430\u0437\u0443. \u042d\u0442\u043e \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a, \u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442  [...]
-ConfigView.section.file.writemblimit=\u041c\u0430\u043a\u0441. \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 (\u0432 %1)
-ConfigView.section.file.writemblimit.explain=\u0415\u0441\u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f, \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0 [...]
-ConfigView.section.file.readmblimit=\u041c\u0430\u043a\u0441. \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 (\u0432 %1)
-ConfigView.section.file.readmblimit.explain=\u042d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u043c\u044f\u0442\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0447\u0442\u0435\u043d\u0438\u044f.
+ConfigView.section.file.perf.cache.flushpieces=\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u042d\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043a \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u043c\u0443, \u043d\u043e \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e\u043c\u [...]
+ConfigView.section.file.writemblimit=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 (\u0432 %1)
+ConfigView.section.file.writemblimit.explain=\u0415\u0441\u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0 [...]
+ConfigView.section.file.readmblimit=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 (\u0432 %1)
+ConfigView.section.file.readmblimit.explain=\u042d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043b\u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u043c\u044f\u0442\u0438, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043e\u0447\u0435\u0 [...]
 Button.moveUp=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c &\u0432\u0432\u0435\u0440\u0445
 Button.moveDown=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c &\u0432\u043d\u0438\u0437
-ConfigView.notAvailableForMode=\u042d\u0442\u0430 \u0441\u0435\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u0443\u0440\u043e\u0432\u0435\u043d\u044f %1 \u0438\u043b\u0438 \u0432\u044b\u0448\u0435. \u0412 \u0440\u0435\u0436\u0438\u043c\u0435 %2 \u043e\u043d\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430.
-health.explain.error=\u0421 \u0434\u0430\u043d\u043d\u044b\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b; \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0442\u043e\u043b\u0431\u04 [...]
-GeneralView.label.trackerscrapeupdate=\u0417\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e
+ConfigView.notAvailableForMode=\u042d\u0442\u0430 \u0441\u0435\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u0443\u0440\u043e\u0432\u0435\u043d\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043f\u044b\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u0432\u0430\u0442\u0435\u043b\u044f %1 \u0438\u043b\u0438 \u0432\u044b\u0448\u0435. \u0412 \u0440\u0435\u0436\u0438\u043c\u [...]
+health.explain.error=\u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0441 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c.\n\u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0438\u043b\u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0443 \u043d\u0430 \u0438\u043a\u043e\u043d\u043a\u0435 \u043e\u0431 \u044d\u0442\u043e\u0439 \u043e\u0448\u0438\u0431 [...]
+GeneralView.label.trackerscrapeupdate=\u041e\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 (scrape)
 PeersView.piece=\u0427\u0430\u0441\u0442\u044c
-PeersView.piece.info=\u041d\u043e\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438, \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u0443 \u044d\u0442\u043e\u0433\u043e \u0443\u0437\u043b\u0430
+PeersView.piece.info=\u041d\u043e\u043c\u0435\u0440 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438, \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0439 \u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430
 PiecesView.priority=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
-PiecesView.priority.info=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0447\u0430\u0441\u0442\u0438, \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u043c\u0443
+PiecesView.priority.info=\u042d\u0442\u043e \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0447\u0430\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u043d\u043e \u043d\u0435  \u043e\u0431\u0440\u0430\u0449\u0430\u0439\u0442\u0435 \u043d\u0430 \u044d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f
 PiecesView.speed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
-PiecesView.speed.info=\u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c \u0443\u0437\u043b\u0430\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0447\u0430\u0441\u0442\u044f\u043c
-TableColumn.header.AvgAvail.info=\u0421\u0443\u043c\u043c\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u0435\u0439, \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439, \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0 [...]
-TableColumn.header.AvgAvail=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
-ConfigView.label.strictfilelocking=\u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0444\u0430\u0439\u043b
-MyTorrentsView.menu.checkfilesexist=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
-MyTorrentsView.menu.rescanfile=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u0447\u0430\u0441\u0442\u0438
-MyTorrentsView.menu.clear_resume_data=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435
-Plugin.extseed.name=\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0435
-Plugin.localtracker.name=\u041f\u043e\u0438\u0441\u043a \u0443\u0437\u043b\u043e\u0432 \u0432 LAN
-Plugin.localtracker.info=\u041f\u043e\u0438\u0441\u043a \u0443\u0437\u043b\u043e\u0432 \u0432 LAN \u0434\u0430\u0451\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c Vuze \u0437\u0430 \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u044b\u043c \u044d\u043a\u0440\u0430\u043d\u043e\u043c \u0432 \u043e\u0431\u0449\u0435\u0439 \u0441\u0435\u0442\u0438\n\u044d [...]
-Plugin.localtracker.enable=\u0418\u0441\u043a\u0430\u0442\u044c \u0443\u0437\u043b\u044b \u0432 LAN
-azinstancehandler.alert.portclash=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 \u043f\u043e\u0440\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438: %1 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u043e [...]
+PiecesView.speed.info=\u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c \u043f\u0438\u0440\u0430\u043c \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0435\u0448\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0431\u044b\u0441\u0442\u0440\u044b\u043c\u0438  \u0447\u0430\u0441\u0442\u044f\u043c\u0438
+TableColumn.header.AvgAvail.info=\u0421\u0443\u043c\u043c\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439, \u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043d\u0430 \u043a\u043e\u043b. \u0447\u0430\u0441\u0442\u0435\u0439, \u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043d\u0430 \u0447\u0438\u0441\u043b\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+TableColumn.header.AvgAvail=\u0421\u0440\u0435\u0434\u043d\u0435\u0435 \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0447\u0430\u0441\u0442\u0435\u0439/\u0412\u0441\u0435\u0433\u043e \u0447\u0430\u0441\u0442\u0435\u0439
+ConfigView.label.strictfilelocking=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043e\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0444\u0430\u0439\u043b\u043e\u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+MyTorrentsView.menu.checkfilesexist=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
+MyTorrentsView.menu.rescanfile=\u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0435\u0434\u043e\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438
+MyTorrentsView.menu.clear_resume_data=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f
+Plugin.extseed.name=\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0421\u0438\u0434\u044b
+Plugin.localtracker.name=\u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a \u043f\u0438\u0440\u043e\u0432 \u0432 LAN
+Plugin.localtracker.info=\u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a \u043f\u0438\u0440\u043e\u0432 \u0432 LAN \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0443 \u043a\u043e\u043f\u0438\u0439 Vuze \u0437\u0430 \u043e\u0434\u043d\u0438\u043c \u0444\u0430\u0435\u0440\u0432\u043e\u043b\u043b\u043e\u043c \u0438 \u0432 \u043e\u0434\u043d\u043e\u0439 \u043e\u0431\u0449\u0435\u0439 \u0441\u0435\u0442\u0438 \u044d\u0444\u0444 [...]
+Plugin.localtracker.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a \u043f\u0438\u0440\u043e\u0432 \u0432 LAN
+azinstancehandler.alert.portclash=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 \u043f\u043e\u0440\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438: %1 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043f\u0440\u043e [...]
 ConfigView.section.transfer.lan.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 LAN
-ConfigView.section.transfer.lan.uploadrate=\u041a\u0411/\u0441 \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u043e LAN [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.transfer.lan.uploadrate.tooltip=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u043f\u043e \u0435\u0434\u0438\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 LAN \u0438\u043c\u0435\u044e\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0435\u0434\u0435\u043b \u0440\u0430\u0437\u0434\u0430\u0447\u0438.
-ConfigView.section.transfer.lan.downloadrate=\u041a\u0411/\u0441 \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u043f\u043e LAN [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.transfer.lan.downloadrate.tooltip=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u043f\u043e \u0435\u0434\u0438\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 LAN \u0438\u043c\u0435\u044e\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0435\u0434\u0435\u043b \u043f\u0440\u0438\u0451\u043c\u0430.
+ConfigView.section.transfer.lan.uploadrate=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u043e LAN, \u0432 \u041a\u0411/\u0441 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.transfer.lan.uploadrate.tooltip=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u0438\u0440\u043e\u0432 \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438 (LAN) \u0438\u043c\u0435\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443.
+ConfigView.section.transfer.lan.downloadrate=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e LAN, \u0432 \u041a\u0411/\u0441 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.transfer.lan.downloadrate.tooltip=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u0438\u0440\u043e\u0432 \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438 (LAN) \u0438\u043c\u0435\u044e\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437 [...]
 TorrentOptionsView.title.short=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
 TorrentOptionsView.title.full=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
-TorrentOptionsView.param.max.peers=\u041c\u0430\u043a\u0441. \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.connection.encryption.require_encrypted_transport=\u0422\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445
-ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0443\u0437\u043b\u0430\u043c\u0438.
-ConfigView.section.connection.encryption.min_encryption_level=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-ConfigView.section.connection.encryption.min_encryption_level.tooltip=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\nRC4 \u2014 \u0432\u0435\u0441\u044c \u043f\u043e\u0442\u043e\u043a\n\u0411\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0 [...]
+TorrentOptionsView.param.max.peers=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\n[0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+ConfigView.section.connection.encryption.require_encrypted_transport=\u0422\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0440\u0430\u0444\u0438\u043a\u0430
+ConfigView.section.connection.encryption.require_encrypted_transport.tooltip=\u041f\u0440\u0438\u043d\u0443\u0436\u0434\u0430\u0442\u044c \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u0438\u0440\u0430\u043c\u0438
+ConfigView.section.connection.encryption.min_encryption_level=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u0430\u0446\u0438\u0438
+ConfigView.section.connection.encryption.min_encryption_level.tooltip=Plain - \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\nRC4 - \u0432\u0435\u0441\u044c \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445\n\u0411\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\ [...]
 Peers.column.Encryption=\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435
-Peers.column.Encryption.info=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-ConfigView.section.connection.encryption.encrypt.info=\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0 [...]
-ConfigView.section.connection.encryption.encrypt.info.link=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0437\u0434\u0435\u0441\u044c
-MainWindow.sr.status.tooltip.ok=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 %1: \u0445\u043e\u0440\u043e\u0448\u0438\u0439
-MainWindow.sr.status.tooltip.poor=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 %1: \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 (<0.9)
-MainWindow.sr.status.tooltip.bad=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 %1: \u043f\u043b\u043e\u0445\u043e\u0439 (<0.5)
+Peers.column.Encryption.info=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0440\u0430\u0444\u0438\u043a\u0430:\nNone - \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f\nPlain - \u043f\u0440\u043e\u0441\u0442\u043e\u0435\nRC4-160 - \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435
+ConfigView.section.connection.encryption.encrypt.info=\u0415\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0432\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0438\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c,\n\u043f\u043e\u043a\u043 [...]
+ConfigView.section.connection.encryption.encrypt.info.link=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u0441\u0430\u0439\u0442 \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439
+MainWindow.sr.status.tooltip.ok=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 %1 OK!
+MainWindow.sr.status.tooltip.poor=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 %1 \u043d\u0438\u0437\u043a\u0438\u0439: < 0.9
+MainWindow.sr.status.tooltip.bad=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 %1 \u043f\u043b\u043e\u0445\u043e\u0439: < 0.5
 ConfigView.section.style.status=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441\u0430:
-ConfigView.section.style.status.show_sr=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+ConfigView.section.style.status.show_sr=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
 ConfigView.section.style.status.show_nat=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 NAT
-ConfigView.section.style.status.show_ddb=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0420\u0411\u0414
-ConfigView.section.style.status.show_ipf=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 IP
-ConfigView.section.connection.encryption.encrypt.group=\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u0443\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445
-ConfigView.section.connection.encryption.encrypt.fallback_info=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043d\u0438\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438, \u041d\u041e \u043f\u044 [...]
+ConfigView.section.style.status.show_ddb=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0411\u0430\u0437\u044b (azDHT)
+ConfigView.section.style.status.show_ipf=\u0421\u0442\u0430\u0442\u0443\u0441 IP-\u0444\u0438\u043b\u044c\u0442\u0440\u0430
+ConfigView.section.connection.encryption.encrypt.group=\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0441\u043a\u0440\u044b\u0442\u0438\u0435 \u0442\u0440\u0430\u0444\u0438\u043a\u0430
+ConfigView.section.connection.encryption.encrypt.fallback_info=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u043d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u [...]
 ConfigView.section.connection.encryption.encrypt.fallback_outgoing=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c \u043d\u0435\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u0438\u0441\u044c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435
 ConfigView.section.connection.encryption.encrypt.fallback_incoming=\u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0442\u044c \u043d\u0435\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
 ConfigView.section.connection.encryption=\u0428\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0430\u0444\u0438\u043a\u0430
-upnp.selectedinterfaces=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, eth0;eth1) [\u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435: \u0432\u0441\u0435]
+upnp.selectedinterfaces=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b (\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 ';', \u0442.\u0435. eth0;eth1) [\u043f\u0443\u0441\u0442\u043e: \u0432\u0441\u0435]
 ConfigView.section.style.defaultSortOrder=\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.section.style.defaultSortOrder.desc=\u041f\u043e \u0443\u0431\u044b\u0432\u0430\u043d\u0438\u044e
-ConfigView.section.style.defaultSortOrder.asc=\u041f\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u044e
+ConfigView.section.style.defaultSortOrder.desc=\u0423\u043c\u0435\u043d\u044c\u0448\u0430\u044e\u0449\u0438\u0439\u0441\u044f
+ConfigView.section.style.defaultSortOrder.asc=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439\u0441\u044f
 ConfigView.section.style.defaultSortOrder.flip=\u041f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443
 LoggerView.autoscroll=\u0410\u0432\u0442\u043e\u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0430
-Button.selectAll=\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0441\u0451
-Button.markSelected=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435
-Button.unmarkSelected=\u0421\u043d\u044f\u0442\u044c \u043f\u043e\u043c\u0435\u0442\u043a\u0443 \u0441 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445
-plugins.basicview.config=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430
-TorrentOptionsView.param.max.uploads=\u041c\u0430\u043a\u0441. \u0441\u043b\u043e\u0442\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [\u043c\u0438\u043d\u0438\u043c\u0443\u043c: 2]
-MyTorrentsView.dialog.setPosition.title=\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438
-MyTorrentsView.dialog.setPosition.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432:
-MyTorrentsView.menu.reposition.manual=\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438...
-ConfigView.section.connection.advanced.info.link=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0437\u0434\u0435\u0441\u044c
-ConfigView.section.connection.advanced.socket.group=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u043a\u0435\u0442\u043e\u0432
-ConfigView.section.connection.advanced.bind_port=\u041f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u043e\u0440\u0442\u0443 [0: \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e]
+Button.selectAll=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435
+Button.markSelected=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435
+Button.unmarkSelected=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u0441 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0445
+plugins.basicview.config=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f
+TorrentOptionsView.param.max.uploads=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0441\u043b\u043e\u0442\u043e\u0432 (\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439) \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443\n\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430  [\u043c\u0438\u043d\u0438\u043c\u0443\u043c: 2]
+MyTorrentsView.dialog.setPosition.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435
+MyTorrentsView.dialog.setPosition.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0434\u043b\u044f \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432:
+MyTorrentsView.menu.reposition.manual=\u041f\u0435\u0440\u0435\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432 \u0441\u043f\u0438\u0441\u043a\u0435...
+ConfigView.section.connection.advanced.info.link=\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u0441\u0430\u0439\u0442 \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439
+ConfigView.section.connection.advanced.socket.group=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u043e\u043a\u0435\u0442\u0430
+ConfigView.section.connection.advanced.bind_port=\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0440\u0442\u043e\u043c [0: \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e]
 ConfigView.section.connection.advanced.bind_port.tooltip=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u0440\u0442\u043e\u043c.\n\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0 [...]
 ConfigView.section.proxy.group.tracker=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
-ConfigView.section.proxy.group.peer=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0443\u0437\u043b\u0430\u043c\u0438
+ConfigView.section.proxy.group.peer=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438
 Pieces.column.Requested=\u0417\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043e
-Pieces.column.Requested.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043b\u0438 \u0435\u0449\u0451 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u043b\u0438 \u043d\u0435\u0442 (*)
-ConfigView.label.maxuploadsseeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043f\u0440\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0430\u0447\u0435
+Pieces.column.Requested.info=[*] \u0435\u0441\u043b\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438
+ConfigView.label.maxuploadsseeding=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430, \u043a\u043e\u0433\u0434\u0430 \u0422\u041e\u041b\u042c\u041a\u041e \u0440\u0430\u0437\u0434\u0430\u0447\u0430 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)
 MyTorrentsView.filter=\u0424\u0438\u043b\u044c\u0442\u0440:
 popup.error.hideall=\u0421\u043a\u0440\u044b\u0442\u044c \u0432\u0441\u0451
-ConfigView.section.style.dataStatsOnly=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u0434\u0430\u043d\u043d\u044b\u043c (\u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430)
-ConfigView.section.style.separateProtDataStats=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\u043c \u0438 \u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0430\u043a \u00ab\u0434\u0430\u043d\u043d\u044b\u0435 (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)\u00bb
+ConfigView.section.style.dataStatsOnly=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430)
+ConfigView.section.style.separateProtDataStats=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430\u043c \u0438 \u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0430\u043a '\u0434\u0430\u043d\u043d\u044b\u0435 (\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b)'
 MyTorrentsView.dialog.setFilter.title=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
-MyTorrentsView.dialog.setFilter.text=\u0421\u0435\u043a\u0446\u0438\u044f %1 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u043e \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443.  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0438\u043c\u0432\u043e\u043b \u00ab|\u00bb \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043f\u043e [...]
+MyTorrentsView.dialog.setFilter.text=\u0421\u0435\u043a\u0446\u0438\u044f %1 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u043d\u0438\u0436\u0435.  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0438\u043c\u0432\u043e\u043b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u [...]
 MyTorrentsView.filter.tooltip=Ctrl+X \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0440\u0435\u0436\u0438\u043c\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u043c\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438.\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437 [...]
 MyTorrentsView.clearFilter.tooltip=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440
-MyTorrentsView.menu.filter=\u0424\u0438\u043b\u044c\u0442\u0440...
-ConfigView.section.file.resume.recheck.all=\u041f\u043e\u0441\u043b\u0435 \u0430\u0432\u0430\u0440\u0438\u0439\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u0430 (\u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u044 [...]
+MyTorrentsView.menu.filter=\u0421\u043f\u0438\u0441\u043e\u043a \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432...
+ConfigView.section.file.resume.recheck.all=\u041f\u0440\u0438 \u0441\u0431\u043e\u0435 \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u0444\u0430\u0439\u043b \u043d\u0430  \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u0435\u0439 (\u0418\u043d\u0430\u0447\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0 [...]
 ConfigureWizard.language.choose=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u044f\u0437\u044b\u043a \u0438\u0437 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0438\u0436\u0435 \u0441\u043f\u0438\u0441\u043a\u0430:
-popup.closing.in=\u041e\u043a\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 %1
-popup.more.waiting=\u0415\u0449\u0451 %1 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435(\u044f)..
+popup.closing.in=\u041e\u043a\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 %1 \u0441\u0435\u043a\u0443\u043d\u0434(\u0443)
+popup.more.waiting=%1 \u0435\u0449\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435(\u044f)..
 # > 2402
-popup.download.finished=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u00ab%1\u00bb \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.
-popup.file.finished=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u00ab%1\u00bb \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.
+popup.download.finished="%1" \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443.
+popup.file.finished="%1" \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443.
 ConfigView.auto=\u0410\u0432\u0442\u043e
-Plugin.localtracker.autoadd.info=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u044d\u0442\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0437\u043b\u044b [\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 1.2.3.4]
-Plugin.localtracker.autoadd=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0443\u0437\u043b\u044b
-Plugin.localtracker.networks.info=\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0435\u0442\u0438 \u043a\u0430\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 [\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 145.227.*.*]
+Plugin.localtracker.autoadd.info=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0438\u0440\u043e\u0432 (IP-\u0430\u0434\u0440\u0435\u0441\u0430, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435  ';', \u043d\u0430\u043f\u0440. 1.2.3.4;5.6.7.8)
+Plugin.localtracker.autoadd=\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0440\u044b
+Plugin.localtracker.networks.info=\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0435\u0442\u0438 \u043a\u0430\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435  [\u0441\u0435\u0442\u0438, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 ';', \u043d\u0430\u043f\u0440. 145.227.*.*;250.151.*.*]
 Plugin.localtracker.networks=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0442\u0438
-MainWindow.menu.view.plugins.logViews=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0436\u0443\u0440\u043d\u0430\u043b\u043e\u0432
-SpeedView.stats.autospeed=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-SpeedView.stats.autospeed.disabled=\u042d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u0431\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0420\u0411\u0414), \u043b\u0438\u0431\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f (\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u04 [...]
-SpeedView.stats.idlePing=\u041f\u0438\u043d\u0433 \u043f\u0440\u0438 \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438:
-SpeedView.stats.maxPing=\u041c\u0430\u043a\u0441. \u043f\u0438\u043d\u0433:
+MainWindow.menu.view.plugins.logViews=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043b\u043e\u0433\u043e\u0432
+SpeedView.stats.autospeed=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+SpeedView.stats.autospeed.disabled=\u042d\u0442\u0430 \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u0431\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430 (\u0432\u0430\u043c \u043d\u0443\u0436\u0435\u043d DHT) \u0438\u043b\u0438 \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f (\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u0430  [...]
+SpeedView.stats.idlePing=\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u041f\u0438\u043d\u0433:
+SpeedView.stats.maxPing=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u041f\u0438\u043d\u0433:
 SpeedView.stats.currentPing=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0438\u043d\u0433:
-SpeedView.stats.maxUp=\u041f\u0440\u0435\u0434\u0435\u043b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438:
-ConfigView.pluginlist.unloadSelected=\u0412\u044b\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435
-ConfigView.pluginlist.scan=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-ConfigView.section.transfer.autospeed=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f)
-ConfigView.section.transfer.autospeed.tooltip=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
-ConfigView.section.transfer.autospeed.info=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u0435\u043b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0447\u0440\u0435\u0437\u [...]
-ConfigView.section.transfer.autospeed.minupload=%1 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.section.transfer.autospeed.minupload.tooltip=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0430 \u043d\u0438\u0436\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f
-ConfigView.section.transfer.autospeed.maxupload=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 %1 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-ConfigView.section.transfer.autospeed.maxupload.tooltip=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0430 \u0432\u044b\u0448\u0435 \u044d\u0442\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f
-ConfigView.section.transfer.autospeed.chokeping=\u0412\u0440\u0435\u043c\u044f \u043f\u0438\u043d\u0433\u0430 \u043f\u0440\u0438 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0435 [\u043c\u0441]
-ConfigView.section.transfer.autospeed.chokeping.tooltip=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0448\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u043e\u0441\u [...]
-ConfigView.section.transfer.autospeed.enableauto=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u0445 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0430\u0445
-ConfigView.section.transfer.autospeed.enableautoseeding=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0430\u0447\u0430\u0445
+SpeedView.stats.maxUp=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u041f\u0440\u0435\u0434\u0435\u043b \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u0438:
+ConfigView.pluginlist.unloadSelected=\u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445
+ConfigView.pluginlist.scan=\u0421\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+ConfigView.section.transfer.autospeed=\u0410\u0432\u0442\u043e-\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c (classic)
+ConfigView.section.transfer.autospeed.tooltip=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+ConfigView.section.transfer.autospeed.info=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u0443\u0435\u0442 \u043b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0433\u [...]
+ConfigView.section.transfer.autospeed.minupload=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [%1]
+ConfigView.section.transfer.autospeed.minupload.tooltip=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0430 \u043d\u0438\u0436\u0435 \u044d\u0442\u043e\u0433\u043e \u043b\u0438\u043c\u0438\u0442\u0430
+ConfigView.section.transfer.autospeed.maxupload=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [%1] (0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e)
+ConfigView.section.transfer.autospeed.maxupload.tooltip=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u044d\u0442\u043e\u0433\u043e \u043b\u0438\u043c\u0438\u0442\u0430
+ConfigView.section.transfer.autospeed.chokeping=\u041b\u0438\u043c\u0438\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0438\u043d\u0433\u0430 \u0434\u043b\u044f "\u043f\u0440\u0438\u0442\u043e\u0440\u043c\u0430\u0436\u0438\u0432\u0430\u043d\u0438\u044f" \u043f\u0438\u0440\u043e\u0432 [\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b]
+ConfigView.section.transfer.autospeed.chokeping.tooltip=\u0412\u0440\u0435\u043c\u044f \u043f\u0438\u043d\u0433\u0430, \u043f\u0440\u0435\u0432\u043e\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043d\u0430\u04 [...]
+ConfigView.section.transfer.autospeed.enableauto=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0430
+ConfigView.section.transfer.autospeed.enableautoseeding=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0434\u0430\u0447\u0430
 ConfigView.pluginlist.column.unloadable=\u0412\u044b\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0439
-ConfigView.section.transfer.lan.enable=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u043f\u043e LAN
-Plugin.localtracker.wellknownlocals=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u0442\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, 192.168.x.x) \u0438 \u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
+ConfigView.section.transfer.lan.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u043c\u0438\u0442\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0434\u043b\u044f LAN-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+Plugin.localtracker.wellknownlocals=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0430\u0434\u0440\u0435\u0441\u0430 \u043e\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0435\u0442\u0435\u043b\u044c (loopback) / \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b / \u043c\u0435\u0441\u0442\u043d\u044b [...]
 TableColumn.header.filesdone=\u0424\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-TableColumn.header.filesdone.info=\u0424\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e/\u0432\u0441\u0435\u0433\u043e *\u0438\u043b\u0438* \u041d\u0435 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e (\u0444\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e)/\u0432\u0441\u0435\u0433\u043e \u043d\u0435 \u04 [...]
-MagnetPlugin.private_torrent=<\u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442>
-MagnetPlugin.decentral_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433 \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d>
-MagnetPlugin.decentral_backup_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e>
-MagnetPlugin.report.waiting_ddb=\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u0420\u0414\u0411...
+TableColumn.header.filesdone.info=\u0424\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e / \u0412\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432 *\u0438\u043b\u0438* \u041d\u0435\u043f\u0440\u043e\u043f\u0443\u0448\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e (\u0424\u0430\u0439\u043b\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e) / \u0412\u [...]
+MagnetPlugin.private_torrent=<\u0447\u0430\u0441\u0442\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442>
+MagnetPlugin.decentral_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0438\u043d\u0433 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d>
+MagnetPlugin.decentral_backup_disabled=<\u0434\u0435\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e>
+MagnetPlugin.report.waiting_ddb=\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 DDB-\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438...
 MagnetPlugin.report.searching=\u043f\u043e\u0438\u0441\u043a...
 MagnetPlugin.report.found=\u043d\u0430\u0439\u0434\u0435\u043d\u043e %1
 MagnetPlugin.report.alive=%1 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439
 MagnetPlugin.report.dead=%1 \u043d\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439
 MagnetPlugin.report.tunnel=\u0442\u0443\u043d\u043d\u0435\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 %1
-MagnetPlugin.report.downloading=\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0441 %1
+MagnetPlugin.report.downloading=\u043a\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0441 %1
 MagnetPlugin.report.error=\u043e\u0448\u0438\u0431\u043a\u0430 %1
 MagnetURLHandler.report.no_sources=\u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0438\u0441\u0447\u0442\u043e\u043d\u0438\u043a\u043e\u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
 MagnetURLHandler.report.torrent_size=\u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430: %1
 MagnetURLHandler.report.percent=\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e: %1%
 MagnetURLHandler.report.error=\u043e\u0448\u0438\u0431\u043a\u0430 %1
-DHTTransport.report.request_all=\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0437 %1
+DHTTransport.report.request_all=\u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0438\u0437 %1
 DHTTransport.report.received_bit=\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e %1 \u0432 %2 \u0438\u0437 %3
 DHTTransport.report.complete=\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-DHTTransport.report.timeout=\u0442\u0430\u0439\u043c\u0430\u0443\u0442, \u043d\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 %1
-DHTTransport.report.rerequest_all=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0438\u0437 %1
+DHTTransport.report.timeout=\u0442\u0430\u0439\u043c\u0430\u0443\u0442, \u043d\u0435 \u043e\u0442\u043a\u043b\u0438\u043a\u043e\u0432 \u043e\u0442 %1
+DHTTransport.report.rerequest_all=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0438\u0437 %1
 DHTTransport.report.rerequest_bit=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 %1 \u0432 %2 \u0438\u0437 %3
-DHTTransport.report.timeout_some=\u0432\u0440\u0435\u043c\u044f \u0438\u0441\u0442\u0435\u043a\u043b\u043e, %1 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 %2, \u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e
+DHTTransport.report.timeout_some=\u0442\u0430\u0439\u043c\u0430\u0443\u0442, %1 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u043e\u0442 %2 \u043d\u043e \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
 DHTTransport.report.sending=\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445
 DHTTransport.report.resending=\u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445
 DHTTransport.report.send_complete=\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
-DHTTransport.report.send_timeout=\u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0438\u0441\u0442\u0435\u043a\u043b\u043e
-ConfigView.section.transfer.autospeed.enabledebug=\u0412\u0435\u0441\u0442\u0438 \u0436\u0443\u0440\u043d\u0430\u043b \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438
+DHTTransport.report.send_timeout=\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430
+ConfigView.section.transfer.autospeed.enabledebug=\u0412\u0435\u0441\u0442\u0438 \u043b\u043e\u0433\u0438  \u043e\u0448\u0438\u0431\u043e\u043a \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438
 TableColumn.header.date_added=\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f
-TableColumn.header.date_added.info=\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.file.hashchecking.smallestfirst=\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0430\u043c\u044b\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-platform.win32.baddll.info=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u00ab%1\u00bb. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u00ab%2\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b; \u0441\u0431\u043e\u0438 \u0432 \u0440\u0430\u0431\u043e\ [...]
-upnp.ignorebaddevices=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435  \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e
-upnp.ignorebaddevices.info=\u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430: %1
-upnp.ignorebaddevices.reset=\u0421\u0431\u0440\u043e\u0441 \u0441\u043f\u0438\u0441\u043a\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432
-upnp.ignorebaddevices.reset.action=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-upnp.ignorebaddevices.alert=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e UPnP \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 %1 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0431\u043e\u0435\u0432. \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043d [...]
-TorrentOptionsView.param.max.uploads.when.busy=\u041a\u0411/c \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u043a\u043e\u0433\u0434\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e [0: \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u [...]
-UpdateMonitor.messagebox.verification.failed.title=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
-UpdateMonitor.messagebox.verification.failed.text=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u00ab%1\u00bb \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u043e\u0439: %2
-UpdateMonitor.messagebox.accept.unverified.title=\u041f\u0440\u0438\u043d\u044f\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u0443\u044e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443
-UpdateMonitor.messagebox.accept.unverified.text=\u041c\u043e\u0434\u0443\u043b\u044c \u00ab%1\u00bb \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043c\u043e\u0434\u0443\u043b\u0435\u043c Vuze .\n\u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u04 [...]
+TableColumn.header.date_added.info=\u0414\u0430\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d
+ConfigView.section.file.hashchecking.smallestfirst=\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0430\u043c\u044b\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 
+platform.win32.baddll.info=Vuze \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b \u043d\u0430\u043b\u0438\u0447\u0438\u0435  '%1'. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u044c '%2' \u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438, \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a \u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u04 [...]
+upnp.ignorebaddevices=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435  \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e
+upnp.ignorebaddevices.info=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430: %1
+upnp.ignorebaddevices.reset=\u0421\u0431\u0440\u043e\u0441 \u0441\u043f\u0438\u0441\u043a\u0430 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432
+upnp.ignorebaddevices.reset.action=\u0421\u0431\u0440\u043e\u0441
+upnp.ignorebaddevices.alert=UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0432\u043e, \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u043e\u0435 \u043d\u0430  %1, \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u043b\u0443 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043a\u043e\u043d\u0444\u0438\u043 [...]
+TorrentOptionsView.param.max.uploads.when.busy=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430,\n\u043a\u043e\u0433\u0434\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u043e\u0441\u0442\u0438\u [...]
+UpdateMonitor.messagebox.verification.failed.title=\u0418\u043d\u0441\u0442\u0430\u043b\u044f\u0446\u0438\u044f \u041d\u0435 \u041f\u0440\u043e\u0448\u043b\u0430 \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0443
+UpdateMonitor.messagebox.verification.failed.text=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 '%1' \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430 : %2
+UpdateMonitor.messagebox.accept.unverified.title=\u041f\u0440\u0438\u043d\u044f\u0442\u044c \u041d\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u0443\u044e \u0418\u043d\u0441\u0442\u0430\u043b\u043b\u044f\u0446\u0438\u044e
+UpdateMonitor.messagebox.accept.unverified.text='%1' \u043d\u0435 \u043c\u043e\u0433 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d \u043a\u0430\u043a  \u041e\u0444\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d Vuze .\n\u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0442\u043e\u0442 \u0436\u0435 \u043f\u043b\u0430\u0433\u0438\u043d \u0442\u0435\u0431\u0435 \u041d\u0415 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \ [...]
 FileView.BlockView.title=\u0427\u0430\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u0430
-FileView.BlockView.Done=\u0417\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435
-FileView.BlockView.Skipped=\u041f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435
-FileView.BlockView.Active=\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435
-FileView.BlockView.Outstanding=\u041d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-ConfigView.label.tcplistenport=\u041f\u043e\u0440\u0442 TCP \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
-ConfigView.label.udplistenport=\u041f\u043e\u0440\u0442 UDP \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
-upnp.portchange.alert=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0440\u0442\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 UPnP: %1 [\u043f\u0440\u0435\u0436\u043d\u0438\u0439 \u043f\u043e\u0440\u0442=%2] %3 [\u043f\u0440\u0435\u0436\u043d\u0438\u0439 \u043f\u043e\u0 [...]
-ConfigView.section.proxy.username.info=\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u0434\u0430\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0442\u0440\u043e\u043a\u0443 \u00ab<n [...]
-ConfigView.label.maxuploadswhenbusymin=\u0422\u0430\u0439\u043c\u0435\u0440 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 [\u0441]
-MainWindow.menu.help.debug=\u0412\u044b\u0434\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 (\u0436\u0443\u0440\u043d\u0430\u043b \u0441\u0431\u043e\u0435\u0432)
+FileView.BlockView.Done=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+FileView.BlockView.Skipped=\u041f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e
+FileView.BlockView.Active=\u0412 \u0440\u0430\u0431\u043e\u0442\u0435
+FileView.BlockView.Outstanding=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+ConfigView.label.tcplistenport=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 TCP-\u043f\u043e\u0440\u0442
+ConfigView.label.udplistenport=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 UDP-\u043f\u043e\u0440\u0442                      
+upnp.portchange.alert=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0440\u0442\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0447\u0442\u043e\u0431\u044b  \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c UPnP \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432: %1 [\u0441\u0442\u0430\u0440\u044b\u0439 \u043f\u043e\u0440\u0442=%2] %3 [\u0441\u0442\u0430\u0440\u044b\u0439 \u043f\u043e\u0440\u0442=%4]
+ConfigView.section.proxy.username.info=\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u043a\u0441\u0438-\u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u0430\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u0442\u0440\u043e\u043a\u0443 "<none>" \u043a [...]
+ConfigView.label.maxuploadswhenbusymin=\u0422\u0430\u0439\u043c\u0435\u0440 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043d\u044f\u0442\u043e, \u0432 [\u0441\u0435\u043a]
+MainWindow.menu.help.debug=\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438
 DownloadManager.error.badsize=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440
-natpmp.info=NAT-PMP \u2014 \u044d\u0442\u043e \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 UPnP, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f Apple, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 Airport [...]
-natpmp.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c (\u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 Airport)
-ConfigView.section.tracker.host.addurls=\u041e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a\u0435\u0440 \u0432 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u0445
-ConfigView.filter=\u0444\u0438\u043b\u044c\u0442\u0440
-ConfigView.section.files.move=\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e
-ConfigView.section.file.defaultdir.section=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0443\u0442\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-ConfigView.section.file.defaultdir.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 (\u0431\u0435\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0443\u0442\u0438)
-ConfigView.section.file.defaultdir.bestguess=\u0412\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0430\u043c\u0443\u044e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-ConfigView.section.file.defaultdir.ask=\u041f\u0430\u043f\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e: 
-ConfigView.section.file.defaultdir.lastused=\u0417\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
-ConfigView.section.file.config.section=\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a
-ConfigView.section.file.config.currentdir=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u0443\u0442\u044c \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a:
+natpmp.info=NAT-PMP \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043e\u0439 \u0444\u0438\u0440\u043c\u044b Apple \u0434\u043b\u044f UPnP \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c\u0438 \u0431\u0435\u0441\u043f\u0440\u043e\u0432\u043e\u0434\u043d\u044b\u043c\u0438 \u0441\u0442\u0430\u043d\u0446\u0438\u044f\u043c\u0 [...]
+natpmp.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c (\u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0431\u0435\u0441\u043f\u0440\u043e\u0432\u043e\u0434\u0 [...]
+ConfigView.section.tracker.host.addurls=\u0423\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e URL \u043d\u0430 \u044d\u0442\u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u0437\u0430\u0445\u043e\u0441\u0442\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u0445
+ConfigView.filter=\u041a\u0430\u043a\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0438\u0449\u0438\u0442\u0435?
+ConfigView.section.files.move=\u041f\u0435\u0440\u0435\u043d\u043e\u0441 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f
+ConfigView.section.file.defaultdir.section=\u041e\u043f\u0446\u0438\u0438 \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u041f\u0430\u043f\u043a\u0438
+ConfigView.section.file.defaultdir.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 (\u0431\u0435\u0437 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f)
+ConfigView.section.file.defaultdir.bestguess=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u0431\u043e\u0440\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+ConfigView.section.file.defaultdir.ask=\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u043f\u0430\u043f\u043a\u0430: 
+ConfigView.section.file.defaultdir.lastused=\u0418\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043f\u0430\u043f\u043a\u0443 \u043d\u0430 \u043f\u0430\u043f\u043a\u0443 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+ConfigView.section.file.config.section=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+ConfigView.section.file.config.currentdir=\u041f\u0430\u043f\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438:
 ConfigView.section.torrent.decoding=\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432
-ConfigView.section.logging.udptransport=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e UDP
-Tracker.announce.ignorePeerSeed=\u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432/\u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f. %1
-ConfigView.section.connection.encryption.use_crypto_port=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u00abcryptoport\u00bb, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u043d\u0435\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u [...]
-TorrentOptionsView.param.reset.to.default=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u043c
-TorrentOptionsView.param.reset.button=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-natpmp.routeraddress=\u0410\u0434\u0440\u0435\u0441 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 [\u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435: \u0430\u0432\u0442\u043e]
-ConfigView.section.style.disableAlertSliding=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043b\u0430\u0432\u043d\u0443\u044e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e/\u043f\u043e\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0440\u0445 \u0432\u0441\u0435\u0445 \u043e\u043a\u043e\u043d \u0434\u043b\u044f \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439
-ConfigView.section.transfer.autospeed.maxinc=%1 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0432\u0435\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0446\u0438\u043a\u043b
-ConfigView.section.transfer.autospeed.maxdec=%1 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0446\u0438\u043a\u043b
-ConfigView.section.transfer.autospeed.enabledownadj=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f
-ConfigView.section.transfer.autospeed.downadjratio=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0435\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:\u0440\u0430\u0437\u0434\u0430\u0447\u0438 (\u0442.\u0435. 2.0 -> \u043f\u0440\u0435\u0434\u0435\u043b \u043f\u0440\u0438\u0451\u043c\u0430 \u0432 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 [...]
-ConfigView.section.transfer.autospeed.latencyfactor=\u041a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u0435\u0442\u0438 (\u0431\u043e\u043b\u044c\u0448\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u20 [...]
-ConfigView.section.transfer.autospeed.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
-ConfigView.section.transfer.autospeed.reset.button=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-PeerColumn.activationCount=\u0423\u0437\u043b\u044b \u043f\u044b\u0442\u0430\u044e\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f: %1
-TableColumn.header.timesincedownload.info=\u0412\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043f\u0440\u0438\u0451\u043c\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.timesincedownload=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u0451\u043c\u0430
-TableColumn.header.timesinceupload.info=\u0412\u0440\u0435\u043c\u044f \u0441 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.timesinceupload=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-PeersView.incomingreqcount=\u0412\u0445. \u0437\u0430\u043f\u0440\u043e\u0441\u044b
-PeersView.incomingreqcount.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u043e\u043c
-PeersView.outgoingreqcount=\u0418\u0441\u0445. \u0437\u0430\u043f\u0440\u043e\u0441\u044b
-PeersView.outgoingreqcount.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0443\u0437\u043b\u0443
-upnp.mapping.trackerclientudp=\u041f\u043e\u0440\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
-upnp.mapping.dhtudp=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 \u0414\u0430\u043d\u043d\u044b\u0445
-ConfigView.section.connection.nondata.udp.same=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043f\u043e\u0440\u0442 UDP \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430
+ConfigView.section.logging.udptransport=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e  UDP  \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0443 \u043f\u0435\u0440\u0443\u0434\u0430\u0447\u0438
+Tracker.announce.ignorePeerSeed=\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u041b\u0438\u0447\u0435\u0440\u044b/\u0421\u0438\u0434\u044b. %1
+ConfigView.section.connection.encryption.use_crypto_port=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 '\u043a\u0440\u0438\u043f\u0442\u043e-\u043f\u043e\u0440\u0442', \u0447\u0442\u043e\u0431\u044b \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435  \u0432\u0445\u0 [...]
+TorrentOptionsView.param.reset.to.default=\u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b
+TorrentOptionsView.param.reset.button=\u0421\u0431\u0440\u043e\u0441
+natpmp.routeraddress=\u0410\u0434\u0440\u0435\u0441 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 [<\u043f\u0443\u0441\u0442\u043e>: \u0430\u0432\u0442\u043e]
+ConfigView.section.style.disableAlertSliding=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0443\u044e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u0438 \u0441\u0442\u0438\u043b\u044c '\u043f\u043e\u0432\u0435\u0440\u0445' \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439
+ConfigView.section.transfer.autospeed.maxinc=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u0446\u0438\u043a\u043b [%1]
+ConfigView.section.transfer.autospeed.maxdec=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0446\u0438\u043a\u043b [%1]
+ConfigView.section.transfer.autospeed.enabledownadj=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+ConfigView.section.transfer.autospeed.downadjratio=\u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0435\u0439 [\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438]/[\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0420\u0430\u0437\u0434\u0430\u0447\u0438]\n(\u043d\u0430\u043f\u0440., 2.0 -> \u043b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0 [...]
+ConfigView.section.transfer.autospeed.latencyfactor=\u0418\u043d\u0434\u0435\u043a\u0441, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\n(\u0431\u041e\u043b\u044c\u0448\u0438\u0435 \u0447\u0438\u0441\u043b\ [...]
+ConfigView.section.transfer.autospeed.reset=\u0421\u0431\u0440\u043e\u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439
+ConfigView.section.transfer.autospeed.reset.button=\u0421\u0431\u0440\u043e\u0441
+PeerColumn.activationCount=\u041f\u0438\u0440\u043e\u0432, \u043f\u044b\u0442\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f: %1
+TableColumn.header.timesincedownload.info=\u0412\u0440\u0435\u043c\u044f, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.timesincedownload=\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435
+TableColumn.header.timesinceupload.info=\u0412\u0440\u0435\u043c\u044f, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.timesinceupload=\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432 \u0440\u0430\u0437\u0434\u0430\u0447\u0435
+PeersView.incomingreqcount=\u0412\u0445\u043e\u0434.\u0417\u0430\u043f\u0440\u043e\u0441\u044b
+PeersView.incomingreqcount.info=\u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u043f\u0438\u0440\u043e\u043c
+PeersView.outgoingreqcount=\u0418\u0441\u0445\u043e\u0434.\u0417\u0430\u043f\u0440\u043e\u0441\u044b
+PeersView.outgoingreqcount.info=\u041f\u043e\u0434\u0441\u0447\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0445 \u043f\u0438\u0440\u0443
+upnp.mapping.trackerclientudp=UDP-\u043f\u043e\u0440\u0442 \u0422\u0440\u0435\u043a\u0435\u0440-\u041a\u043b\u0438\u0435\u043d\u0442
+upnp.mapping.dhtudp=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 \u0414\u0430\u043d\u043d\u044b\u0445 (azDHT)
+ConfigView.section.connection.nondata.udp.same=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 UDP \u043f\u043e\u0440\u0442 \u0434\u043b\u044f  \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 UDP \u0442\u0440\u0435\u043a\u0435\u0440\u0430
 ConfigView.section.connection.tcp.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c TCP
 ConfigView.section.connection.udp.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c UDP
-ConfigView.section.style.showiconbar=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.style.showiconbar=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
 MainWindow.menu.view.iconbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0438\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
-MyTorrentsView.menu.rename=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u043c\u044f/\u043f\u0443\u0442\u044c
-MyTorrentsView.menu.rename.displayed=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f
-MyTorrentsView.menu.rename.save_path=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
-MyTorrentsView.menu.rename.displayed.enter.title=\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u0438
-MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.\n\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u0432\u0435\u0434\u0435\u043d, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u043d\u043e\u0435 \u0438 [...]
-MyTorrentsView.menu.edit_comment=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
-MyTorrentsView.menu.edit_comment.enter.title=\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f
-MyTorrentsView.menu.edit_comment.enter.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043a \u044d\u0442\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435.
+MyTorrentsView.menu.rename=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c
+MyTorrentsView.menu.rename.displayed=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f
+MyTorrentsView.menu.rename.save_path=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+AdvRenameWindow.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443
+AdvRenameWindow.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+AdvRenameWindow.rename.torrent=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+MyTorrentsView.menu.rename.displayed.enter.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f
+MyTorrentsView.menu.rename.displayed.enter.message=\u0412\u0432\u0435\u0434\u0438 \u043d\u043e\u0432\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438.
+MyTorrentsView.menu.edit_comment=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
+MyTorrentsView.menu.edit_comment.enter.title=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
+MyTorrentsView.menu.edit_comment.enter.message=\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438.
 UIDebugGenerator.messageask.title=\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u041e\u0442\u043b\u0430\u0434\u043a\u0438
-UIDebugGenerator.messageask.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438
-UIDebugGenerator.complete.title=\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u041e\u0442\u043b\u0430\u0434\u043a\u0438 \u0417\u0430\u0432\u0435\u0440\u0448\u0451\u043d
-UIDebugGenerator.complete.text=\u0424\u0430\u0439\u043b \u0441\u043e \u0441\u0432\u0435\u0434\u0435\u043d\u0438\u044f\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u00ab%1\u00bb.\n\n\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u00abOK\u00bb, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043e\u043a\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c.
-ConfigView.section.style.showProgramIcon=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u043e\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432 \u0441\u0442\u043e\u043b\u0431\u0446\u0435 \u00ab\u0418\u043c\u044f\u00bb
+UIDebugGenerator.messageask.text=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0432\u0432\u0435\u0434\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0431\u0430\u0433\u0430
+UIDebugGenerator.complete.title=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0442\u0447\u0435\u0442\u0430 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+UIDebugGenerator.complete.text=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0444\u0430\u0439\u043b  '%1' \u043d\u0430 az-bugreports at azureus-inc.com\n\n\u041a\u043b\u0438\u043a\u043d\u0438  Ok, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u043e\u043a\u043d\u043e \u0441 \u044d\u0442\u0438\u043c \u0444\u0430\u0439\u043b\u043e\u043c.
+ConfigView.section.style.showProgramIcon=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0438 \u043e\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 (\u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441)
 ConfigView.section.style.showProgramIcon.tooltip=\u0412\u0438\u0434 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439
-swt.alert.cant.update=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 SWT, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u0441 \u00ab%3\u00bb, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 %1 \u0434\u043e %2 (\u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u04 [...]
+swt.alert.cant.update=SWT \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u043a\u0430\u0447\u0435\u043d\u0430 \u0441 "%3" \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 %1 to %2 (\u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0441\u043a\u0430\u0447\u0435\ [...]
 authenticator.savepassword=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043c\u043e\u0439 \u043f\u0430\u0440\u043e\u043b\u044c
 ConfigView.section.security.clearpasswords=\u0421\u0431\u0440\u043e\u0441 \u043f\u0430\u0440\u043e\u043b\u0435\u0439
-ConfigView.section.security.clearpasswords.button=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
-Content.alert.notuploaded.title=\u0420\u0430\u0437\u0434\u0430\u0447\u0430 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
-Content.alert.notuploaded.text=\u0420\u0430\u0437\u0434\u0430\u0447\u0430 %1 \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u0415\u0441\u043b\u0438 \u0432\u044b %2 \u0441\u0435\u0439\u0447\u0430\u0441, \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u043a\u043e\u043d\u0 [...]
-Content.alert.notuploaded.multi.title=\u0420\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b
-Content.alert.notuploaded.multi.text=%1 \u0444\u0430\u0439\u043b\u043e\u0432 \u0435\u0449\u0451 \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u043e\u0437\u0434\u0430\u043d\u043e. \u0415\u0441\u043b\u0438 \u0432\u044b %2 \u0441\u0435\u0439\u0447\u0430\u0441, \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0 [...]
-Content.alert.notuploaded.stop=\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435
-Content.alert.notuploaded.quit=\u0432\u044b\u0439\u0434\u0435\u0442\u0435 \u0438\u0437 Vuze
+ConfigView.section.security.clearpasswords.button=\u0421\u0431\u0440\u043e\u0441
 TorrentInfoView.torrent.encoding=\u041a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TorrentInfoView.columns=\u0421\u0442\u043e\u043b\u0431\u0446\u044b \u0438\u0437 \u0432\u0438\u0434\u0430 \u00ab\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb
-progress.window.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f
-progress.window.msg.filemove=\u0424\u0430\u0439\u043b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f
-ConfigView.label.popup.timestamp=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0448\u0442\u0430\u043c\u043f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u043e \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f
-ConfigView.label.popup.autohide=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 X \u0441\u0435\u043a\u0443\u043d\u0434 [0: \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e]
-ConfigView.label.popup.suppress_alerts=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
-ConfigView.label.popup.use_message_boxes=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043e\u043a\u043d\u0430 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043e\u043a\u043e\u043d
-ConfigView.label.popup.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c)
-ConfigView.label.popup.show.button=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
-ConfigView.label.please.visit.here=\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0437\u0434\u0435\u0441\u044c
-ConfigView.section.ipfilter.enable.descriptionCache=\u0425\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f IP \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435
-ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c\u0441\u044f
-OpenTorrentWindow.filesInfo=%1 \u0438\u0437 %2 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b.
+TorrentInfoView.columns=\u041a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438\u0437 \u0432\u0438\u0434\u0430 '\u041c\u043e\u0438 \u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b' 
+progress.window.title=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f
+progress.window.msg.filemove=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435 \u043f\u043e\u043a\u0430 \u0444\u0430\u0439\u043b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u0441\u044f/\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0435\u0442\u0441\u044f
+ConfigView.label.popup.timestamp=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043a\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439
+ConfigView.label.popup.autohide=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f  \u043f\u043e\u0441\u043b\u0435 x \u0441\u0435\u043a\u0443\u043d\u0434 (0 \u0434\u043b\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0441\u043a\u0440\u044b\u0442\u0438\u044f) 
+ConfigView.label.please.visit.here=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0441\u0435\u0442\u0438\u0442\u0435 \u044d\u0442\u043e \u0434\u043b\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438
+ConfigView.section.ipfilter.enable.descriptionCache=\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f  IP \u0432 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435
+ConfigView.section.ipfilter.enable.descriptionCache.tooltip=\u041a\u043e\u0433\u0434\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u044b
+OpenTorrentWindow.filesInfo=%1 \u0438\u0437 %2 \u0431\u0443\u0434\u0443 \u0441\u043a\u0430\u0447\u0435\u043d\u044b.
 OpenTorrentWindow.diskUsage=%1 \u0438\u0437 %2
-ConfigView.label.openmytorrents=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u00ab\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.label.open_transfer_bar_on_start=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
-ConfigView.section.style.DNDalwaysInIncomplete=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u00ab\u041d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u00bb \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 \u00ab\u043d\u0435\u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435\u00bb
+ConfigView.label.openmytorrents=\u041e\u0442\u043a\u0440\u044b\u0442\u044c  '\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b' \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430
+ConfigView.label.open_transfer_bar_on_start=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u041f\u0430\u043d\u0435\u043b\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435
+ConfigView.section.style.DNDalwaysInIncomplete=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c '\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c' \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043d\u0435\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d [...]
 OpenTorrentWindow.mb.noGlobalDestDir.title=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430
-OpenTorrentWindow.mb.noGlobalDestDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f  '%1' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430.
+OpenTorrentWindow.mb.noGlobalDestDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f  '%1' \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430.
 OpenTorrentWindow.mb.noDestDir.title=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430
-OpenTorrentWindow.mb.noDestDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f '%1' \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 '%2' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430.
-OpenTorrentWindow.mb.notValid.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-OpenTorrentWindow.mb.notValid.text=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u00ab%1\u00bb. \u0415\u0441\u043b\u0438 \u043e\u043d \u0431\u044b\u043b \u043e\u0442\u043a\u0440\u044b\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043b\u0438\u0447\ [...]
-OpenTorrentWindow.mb.notTorrent.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-OpenTorrentWindow.mb.notTorrent.text=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u00ab%1\u00bb. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0444\u0430\u0439\u043b \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c.\n\n\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u0443\u0447\u0 [...]
-ConfigView.label.pause.downloads.on.exit=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435
-ConfigView.label.resume.downloads.on.start=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438
-UIDebugGenerator.message.cancel.title=\u0421\u0431\u043e\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u0451\u043d
-UIDebugGenerator.message.cancel.text=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c, \u043d\u0435 \u0431\u044b\u043b\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u043e. \u0414\u043b\u044f \u0432\u0430\u0441 \u044d\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044 [...]
-ConfigView.section.connection.group.http.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438.
+OpenTorrentWindow.mb.noDestDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f '%1' \u0434\u043b\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 '%2' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043b\u0438 \u043d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430.
+OpenTorrentWindow.mb.notValid.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0422\u043e\u0440\u0440\u0435\u043d\u0442
+OpenTorrentWindow.mb.notValid.text=\u041d\u0435 \u043c\u043e\u0433\u0443 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 '%1'.  \u0415\u0441\u043b\u0438 \u0412\u044b \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0420\u0430\u0437\u0434\u0430\u0447\u0438, \u0442\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u043e\u0442 \u044d\u [...]
+OpenTorrentWindow.mb.notTorrent.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0422\u043e\u0440\u0440\u0435\u043d\u0442
+OpenTorrentWindow.mb.notTorrent.text=\u041d\u0435 \u043c\u043e\u0433\u0443 \u043e\u0442\u043a\u0440\u044b\u0442\u044c '%1'.  \u041e\u043d \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u043e\u043c \u0442\u0438\u043f\u0430 ".torrent".\n\n\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b:\n%2
+ConfigView.label.pause.downloads.on.exit=\u0421\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u043d\u0430 \u043f\u0430\u0443\u0437\u0443 \u043f\u0440\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+ConfigView.label.resume.downloads.on.start=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+UIDebugGenerator.message.cancel.title=\u0421\u0431\u043e\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u0435\u043d
+UIDebugGenerator.message.cancel.text=\u0412\u044b \u043d\u0435 \u0432\u0432\u0435\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0412\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c. \u041e\u0448\u0438\u0431\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0430 \ [...]
+ConfigView.section.connection.group.http.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438
 ConfigView.section.connection.http.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
 ConfigView.section.connection.http.port=\u041d\u043e\u043c\u0435\u0440 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u043f\u043e\u0440\u0442\u0430
-ConfigView.section.connection.http.portoverride=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430 HTTP-\u0442\u0440\u0435\u043a\u0435\u0440\u0430 [0: \u043d\u0435\u0442]
-window.update.noupdates.title=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-window.update.noupdates.text=\u041d\u0435\u0442 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u043d\u043e\u043b\u0435\u043d\u0438\u0439.\n\n\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u044f\u044e!
-ConfigView.label.bindip.details=\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: 192.168.1.5;eth0;eth1[2] \u0441\u0432\u044f\u0436\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 IP \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438 1\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0441 \u0442\u0440\u0435\u0442\u044c\u0438\u043c \u0430\u0434\u0440\u0435\u0441\u043e\u043c 2\u0433\u043e \u0438\u [...]
-ConfigView.label.mindownloads=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0439
-UI.cannot_submit_blank_text=\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.
-crypto.alert.as.warning=\u041e \u0441\u0435\u0442\u0438 \u00ab%1\u00bb \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e, \u0447\u0442\u043e \u043e\u043d\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0430\u0444\u0438\u043a \u0434\u043b\u044f \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438. \u0428\u0438\u0444\u0440\u [...]
+ConfigView.section.connection.http.portoverride=HTTP-\u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 [0: \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c]
+window.update.noupdates.title=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+window.update.noupdates.text=\u041d\u0435\u0442 \u043d\u043e\u0432\u044b\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0412\u0430\u0448\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+ConfigView.label.bindip.details=\u041f\u0440\u0438\u043c\u0435\u0440: '192.168.1.5;eth0;eth1[2]'  \u0441\u0432\u044f\u0436\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c IP (192.168.1.5), \u0441\u043e \u0432\u0441\u0435\u043c\u0438 IP \u0438\u0437 1-\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (eth0) \u0438 \u0441 3-\u043c \u043f\u043e \u0441\u0447\u0435\u0442\u0443 IP \u0438\u0 [...]
+ConfigView.label.mindownloads=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043a\u0430\u0447\u0435\u043a
+UI.cannot_submit_blank_text=\u0422\u044b \u0434\u043e\u043b\u0436\u0435 \u0432\u0432\u0435\u0441\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.
+crypto.alert.as.warning=\u0421\u0435\u0442\u044c '%1' \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0442\u0435\u043c, \u0447\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0442\u0440\u0430\u0444\u0438\u043a \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0 [...]
 ConfigView.section.interface.alerts=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
-ConfigView.label.popupdownloadadded=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-popup.download.added=\u00ab%1\u00bb \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a.
+ConfigView.label.popupdownloadadded=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435
+popup.download.added="%1" \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u0412\u0430\u0448 \u0441\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.
 MessageBoxWindow.nomoreprompting=\u041d\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u043c\u043d\u0435 \u0441\u043d\u043e\u0432\u0430
-TorrentOptionsView.param.max.seeds=\u041c\u0430\u043a\u0441. \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 [0: \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\u043c\u0438]
-TorrentOptionsView.param.alternative.value.enable=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-ConfigView.section.proxy.check.on.start=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u043a\u0441\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
+TorrentOptionsView.param.max.seeds=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441 \u0441\u0438\u0434\u0430\u043c\u0438 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e]
+TorrentOptionsView.param.alternative.value.enable=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430, \u043a\u043e\u0433\u0434\u0430 \u0422\u041e\u041b\u042c\u041a\u041e \u0440\u0430\u0437\u0434\u0430\u0447\u0430
+ConfigView.section.proxy.check.on.start=\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u0440\u043e\u043a\u0441\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435
 TransferStatsView.legend.pingaverage=\u0421\u0440\u0435\u0434\u043d\u0435\u0435
-TransferStatsView.legend.ping1=\u041c\u0435\u0441\u0442\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 1
-TransferStatsView.legend.ping2=\u041c\u0435\u0441\u0442\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 2
-TransferStatsView.legend.ping3=\u041c\u0435\u0441\u0442\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 3
-ConfigView.section.interface.enabletray._mac=\u0417\u043d\u0430\u0447\u043e\u043a \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
-ConfigView.label.closetotray._mac=\u0417\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043e\u043a\u043d\u0430 \u0441\u0432\u0435\u0440\u043d\u0451\u0442 \u0435\u0433\u043e \u0432 \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f
+TransferStatsView.legend.ping1=\u0426\u0435\u043b\u044c 1
+TransferStatsView.legend.ping2=\u0426\u0435\u043b\u044c 2
+TransferStatsView.legend.ping3=\u0426\u0435\u043b\u044c 3
+ConfigView.section.interface.enabletray._mac=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0418\u043a\u043e\u043d\u043a\u0443 \u0412 \u0421\u0442\u0440\u043e\u043a\u0435 \u0421\u0442\u0430\u0442\u0443\u0441\u0430 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
+ConfigView.label.closetotray._mac=\u041f\u0440\u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u0421\u0442\u0440\u043e\u043a\u0443 \u0421\u0442\u0430\u0442\u0443\u0441\u0430
 ConfigView.label.minimizetotray._mac=\u0421\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0432 \u0442\u0440\u0435\u0439
 OpenTorrentWindow.mb.existingFiles.title=\u0424\u0430\u0439\u043b(\u044b) \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442!
-OpenTorrentWindow.mb.existingFiles.text=\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:\n\n%1\n\u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, Vuze \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \ [...]
-splash.unloadingTorrents=\u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
-splash.unloadingTorrent=\u0412\u044b\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.file.defaultdir.autorename=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f
-ConfigView.section.file.defaultdir.autorename.tooltip=\u042d\u0442\u043e \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u0438\u043c\u0435\u043d\u0430\ [...]
-alert.raised.at.close=(\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0441\u0435\u0430\u043d\u0441\u0430 Vuze)
-Plugin.trackerpeerauth.name=\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u0437\u043b\u043e\u0432 \u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0435
-Plugin.trackerpeerauth.info=\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0443\u0437\u043b\u044b \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438 \u0440\u0430\ [...]
+OpenTorrentWindow.mb.existingFiles.text=\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u0444\u0430\u0439\u043b\u044b \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435(\u0430\u0445) \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f :\n\n%1\n\u0415\u0441\u043b\u0438 \u0412\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u04 [...]
+splash.unloadingTorrents=\u041d\u0435\u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+splash.unloadingTorrent=\u041d\u0435\u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.section.file.defaultdir.autorename=\u0410\u0432\u0442\u043e\u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0444\u0430\u0439\u043b\u044b \u0432 \u043f\u0443\u0442\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0435\u043d\u0438\u044f \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f
+ConfigView.section.file.defaultdir.autorename.tooltip=\u042d\u0442\u043e \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043a\u043e\u0433\u0434\u0430 \u0438\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043e\u0434\u0438\u043d\u0430\ [...]
+alert.raised.at.close=(\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f Vuze)
+Plugin.trackerpeerauth.name=\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0438\u0440\u043e\u0432 \u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0435
+Plugin.trackerpeerauth.info=\u042d\u0442\u043e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0447\u0442\u043e \u043f\u0438\u0440\u044b - \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u0433\u0440\u0443\u043f\u043f\u044b
 Peers.column.maxupspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-Peers.column.maxdownspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-MyTorrents.items.DownSpeedLimit.disabled=\u041d\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-upnp.selectedaddresses=\u0410\u0434\u0440\u0435\u0441\u0430 (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab;\u00bb, \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u00ab-\u00bb =\u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c, \u00ab+\u00bb =\u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c) [\u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435: \u0432\u0441\u0435]
-upnp.alert.multipledevice.warning=\u0411\u044b\u043b\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 UPnP \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0432\u0441\u0435\u043c \u043b\u0438 \u0438\u0437 \u043d\u0438\u0445 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0 [...]
-UpdateMonitor.messagebox.restart.title=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
-UpdateMonitor.messagebox.restart.text=\u0411\u044b\u043b\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e \u0432\u0430\u0436\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435. \u0414\u043b\u044f \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Vuze.
-PiecesView.BlockView.Have=\u041f\u0440\u0438\u043d\u044f\u0442\u0430
-PiecesView.BlockView.NoHave=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442
-PiecesView.BlockView.Header=%1 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432, %2 \u0441\u0442\u0440\u043e\u043a, %3 \u0447\u0430\u0441\u0442\u0435\u0439
-ConfigView.section.update.autodownload=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
-Peers.column.peer_id=ID \u0443\u0437\u043b\u0430
-Peers.column.peer_id.info=ID \u0443\u0437\u043b\u0430 \u0432 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0439 \u0444\u043e\u0440\u043c\u0435
-Peers.column.peer_byte_id=ID \u0443\u0437\u043b\u0430
-Peers.column.peer_byte_id.info=ID \u0443\u0437\u043b\u0430 \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u043e\u0439 \u0444\u043e\u0440\u043c\u0435
-Peers.column.handshake_reserved=\u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0442\u044b
-Peers.column.handshake_reserved.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0442\u044b \u0431\u044b\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043f\ [...]
-Peers.column.client_identification=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430
-Peers.column.client_identification.info=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u2014 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438
-dht.warn.user=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435 NAT
-ConfigView.label.openbar.incomplete=\u0421\u043a\u0440\u0438\u043d\u043b\u0435\u0442\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a: \u0430\u0432\u0442\u043e\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-ConfigView.label.openbar.complete=\u0430\u0432\u0442\u043e\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445
-ConfigView.label.transferbar.remember_location=\u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
-ConfigView.section.transfer.autospeed.forcemin=%1 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0431\u044b\u043b\u0430 \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043f\u0440\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
-MainWindow.menu.tools.speedtest=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c...
+Peers.column.maxdownspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+MyTorrents.items.DownSpeedLimit.disabled=\u041d\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+upnp.selectedaddresses=\u0410\u0434\u0440\u0435\u0441\u044b (\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 ';', \u043f\u0440\u0435\u0444\u0438\u043a\u0441 '-'=\u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c, '+' =\u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c) [\u043f\u0443\u0441\u0442\u043e: \u043b\u044e\u0431\u043e\u0435]
+upnp.alert.multipledevice.warning=\u041c\u0443\u043b\u044c\u0442\u0438-UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043b\u0438 "\u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u043f\u043e\u0440\u0442\u043e\u0432" - port-forwarding (\u0441\u043c. UPnP-\u0436\u0443\u0440\u043d\u0430\u043b [...]
+UpdateMonitor.messagebox.restart.title=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+UpdateMonitor.messagebox.restart.text=Vuze \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0432\u0430\u0436\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\ [...]
+PiecesView.BlockView.Have=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+PiecesView.BlockView.NoHave=\u041d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+PiecesView.BlockView.Header=%1 \u0441\u0442\u043e\u043b\u0431\u0446\u044b, %2 \u0441\u0442\u0440\u043e\u043a\u0438, %3 \u0447\u0430\u0441\u0442\u0438
+ConfigView.section.update.autodownload=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c, \u0447\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430.
+Peers.column.peer_id=ID \u043f\u0438\u0440\u0430
+Peers.column.peer_id.info=ID \u043f\u0438\u0440\u0430 \u0432 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0439 \u0444\u043e\u0440\u043c\u0435
+Peers.column.peer_byte_id=ID \u043f\u0438\u0440\u0430
+Peers.column.peer_byte_id.info=ID \u043f\u0438\u0440\u0430 \u0432 \u0444\u043e\u0440\u043c\u0435 \u0431\u0430\u0439\u0442\u043e\u0432
+Peers.column.handshake_reserved=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u0431\u0430\u0439\u0442\u044b \u043d\u0430 \u0412\u0422-\u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f
+Peers.column.handshake_reserved.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 \u0431\u0438\u0442\u044b \u0431\u044b\u043b\u0438 \u043f\u043e\u0441\u043b\u0430\u043d\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043c\u0435\u043d\u0430 BT-\u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f\u043c\u0438
+Peers.column.client_identification=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0430
+Peers.column.client_identification.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 Vuze - \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438
+dht.warn.user=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u0442\u044c \u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u0441 NAT / \u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0440\u0442\u043e\u0432
+ConfigView.label.openbar.incomplete=\u041f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u043a\u0430\u0447\u043a\u0438: \u0430\u0432\u0442\u043e-\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0437\u0430\u043a\u0430\u0447\u0435\u043a
+ConfigView.label.openbar.complete=\u0430\u0432\u0442\u043e-\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447
+ConfigView.label.transferbar.remember_location=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u041f\u0430\u043d\u0435\u043b\u0438 \u0442\u0440\u0430\u0444\u0438\u043a\u0430
+ConfigView.section.transfer.autospeed.forcemin=\u0412\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u0438\u0437 \u043e\u0431\u0449\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u043a\u043e\u0433\u0434\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435, \u0432 [%1]
+MainWindow.menu.tools.speedtest=\u0422\u0435\u0441\u0442 \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u0438...
 speedtest.wizard.title=\u0422\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
-speedtest.wizard.run=\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
-speedtest.wizard.test.mode.updown=\u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0438 \u043f\u0440\u0438\u0451\u043c
+speedtest.wizard.run=\u041f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0442\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+speedtest.wizard.test.mode.updown=\u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
 speedtest.wizard.test.mode.up=\u0440\u0430\u0437\u0434\u0430\u0447\u0430
-speedtest.wizard.test.mode.down=\u043f\u0440\u0438\u0451\u043c
-SpeedTestWizard.test.panel.currinfo=\u0422\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 BitTorrent.
+speedtest.wizard.test.mode.down=\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+SpeedTestWizard.test.panel.currinfo=\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0411\u0438\u0442\u0422\u043e\u0440\u0440\u0435\u043d\u0442-\u043a\u0430\u043d\u0430\u043b\u0430
 SpeedTestWizard.test.panel.label=\u0422\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 Vuze:
 SpeedTestWizard.test.panel.already.running=\u0422\u0435\u0441\u0442 \u0443\u0436\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d!
-SpeedTestWizard.test.panel.not.accepted=\u0417\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u0441\u0442\u0430 \u043d\u0435 \u0431\u044b\u043b \u043e\u0442\u043a\u043b\u043e\u043d\u0451\u043d: 
+SpeedTestWizard.test.panel.not.accepted=\u0417\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u0441\u0442\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u044f\u0442:
 SpeedTestWizard.test.panel.abort=\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c
-SpeedTestWizard.test.panel.abort.countdown=\u041e\u0442\u043c\u0435\u043d\u0430 \u0442\u0435\u0441\u0442\u0430 \u0447\u0435\u0440\u0435\u0437:
-SpeedTestWizard.test.panel.test.countdown=\u0442\u0435\u0441\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437:
-SpeedTestWizard.test.panel.testfailed=\u0422\u0435\u0441\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439
-SpeedTestWizard.test.panel.aborted=\u0422\u0435\u0441\u0442 \u043f\u0440\u0435\u0440\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c.
-SpeedTestWizard.test.panel.enc.label=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c:
-SpeedTestWizard.test.panel.standard=\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
-SpeedTestWizard.test.panel.encrypted=\u0441 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c
+SpeedTestWizard.test.panel.abort.countdown=\u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442. \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437:
+SpeedTestWizard.test.panel.test.countdown=\u043f\u043b\u0430\u043d\u043e\u0432\u043e\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437:
+SpeedTestWizard.test.panel.testfailed=\u0422\u0435\u0441\u0442 \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u043d
+SpeedTestWizard.test.panel.aborted=\u0422\u0435\u0441\u0442 \u043f\u0440\u0435\u0440\u0432\u0430\u043d \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+SpeedTestWizard.test.panel.enc.label=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0438\u0444\u0440\u0430\u0446\u0438\u0438:
+SpeedTestWizard.test.panel.standard=\u0431\u0435\u0437 \u0448\u0438\u0444\u0440\u0430\u0446\u0438\u0438
+SpeedTestWizard.test.panel.encrypted=\u0448\u0438\u0444\u0440\u0430\u0446\u0438\u044f
 SpeedTestWizard.set.upload.button.apply=\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c
 SpeedTestWizard.set.upload.result=\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430
-SpeedTestWizard.set.upload.bytes.per.sec=\u041a\u0411/\u0441
-SpeedTestWizard.set.upload.bits.per.sec=\u0431\u0438\u0442/\u0441
-SpeedTestWizard.finish.panel.title=\u0422\u0435\u0441\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d!
-SpeedTestWizard.finish.panel.click.close=\u0422\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d.
-SpeedTestWizard.finish.panel.max.upload=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447\u0430:
-SpeedTestWizard.finish.panel.max.seeding.upload=\u041c\u0430\u043a\u0441. \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435:
+SpeedTestWizard.set.upload.bytes.per.sec=\u041a\u0431\u0430\u0439\u0442/\u0441\u0435\u043a
+SpeedTestWizard.set.upload.bits.per.sec=\u0431\u0438\u0442/\u0441\u0435\u043a
+SpeedTestWizard.finish.panel.title=\u0422\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d!
+SpeedTestWizard.finish.panel.click.close=\u041c\u0430\u0441\u0442\u0435\u0440 \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 "\u0437\u0430\u043a\u0440\u044b\u0442\u044c" \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430.
+SpeedTestWizard.finish.panel.max.upload=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447\u0430
+SpeedTestWizard.finish.panel.max.seeding.upload=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:
 SpeedTestWizard.finish.panel.max.download=\u041c\u0430\u043a\u0441. \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430:
 SpeedTestWizard.finish.panel.enabled=\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043e
 SpeedTestWizard.finish.panel.disabled=\u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e
-SpeedTestWizard.abort.message.scheduled.in=\u0442\u0435\u0441\u0442 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d \u0447\u0435\u0440\u0435\u0437 ... %1 \u0441\u0435\u043a\u0443\u043d\u0434"
-SpeedTestWizard.abort.message.unsupported.type=\u0422\u0438\u043f \u0442\u0435\u0441\u0442\u0430 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f!
-SpeedTestWizard.abort.message.manual.abort=\u041f\u0440\u0435\u0440\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c
-SpeedTestWizard.abort.message.scheduling.failed=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442
-SpeedTestWizard.abort.message.download.added=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u0445\u043e\u0434\u0435 \u0442\u0435\u0441\u0442\u0430 %1
-SpeedTestWizard.abort.message.entered.error=\u0422\u0435\u0441\u0442 \u043f\u0440\u0438\u0451\u043c\u0430 \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u00ab%1\u00bb
-SpeedTestWizard.abort.message.entered.queued=\u0422\u0435\u0441\u0442 \u043f\u0440\u0438\u0451\u043c\u0430 \u0431\u044b\u043b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c/\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-SpeedTestWizard.abort.message.interrupted=TorrentSpeedTestMonitorThread \u0431\u044b\u043b \u043f\u0440\u0435\u0440\u0432\u0430\u043d \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430
-SpeedTestWizard.abort.message.execution.failed=\u0417\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f
-SpeedTestWizard.abort.message.failed.peers=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0441 \u0443\u0437\u043b\u0430\u043c\u0438
-SpeedTestWizard.abort.message.insufficient.slots=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0434\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0437\u043b\u0430\u043c \u2014 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0442\u043e\u0432 \u0440\u0430\u0437\u0434\u0430\u0447\u0438?
-SpeedTestWizard.abort.message.not.unchoked=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0438 \u043e\u0442 \u043e\u0434\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 (\u043d\u0438 \u043e\u0434\u0438\u043d \u043d\u0435 \u043f\u0440\u0438\u043d\u044f\u043b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435)
-SpeedTestWizard.stage.message.requesting=\u0437\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u0441\u0442\u0430...
-SpeedTestWizard.stage.message.preparing=\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0442\u0435\u0441\u0442\u0430...
-SpeedTestWizard.stage.message.starting=\u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u0430...
-SpeedTestWizard.stage.message.connect.stats=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f: \u0443\u0437\u043b\u043e\u0432=%1, down_ok=%2, up_ok=%3
-window.uiswitcher.title=\u0412\u044b\u0431\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 Vuze
-window.uiswitcher.text=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.
-window.uiswitcher.NewUI.text=* \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432 \u0438 \u043d\u0435\u0438\u0441\u043a\u0443\u0448\u0451\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.\n\n* \u041f\u0440\u043e\u0441\u0442\u043e\u0439, \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u [...]
-window.uiswitcher.ClassicUI.title=\u041a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441
-window.uiswitcher.ClassicUI.text=* \u041e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c \u0441\u0435\u0440\u0438\u0438 2.x\n\n* \u041a\u043e\u043d\u0442\u0435\u043d\u0442 Vuze \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
-window.uiswitcher.bottom.text=\u0412\u044b\u0431\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441 \u043b\u0451\u0433\u043a\u043e\u0441\u0442\u044c\u044e \u0438\u0437\u043c\u0435\u043d\u0451\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043a\u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 Vuze
+SpeedTestWizard.abort.message.scheduled.in=\u0442\u0435\u0441\u0442 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 ... %1 \u0441\u0435\u043a\u0443\u043d\u0434"
+SpeedTestWizard.abort.message.unsupported.type=\u041d\u0435\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0442\u0435\u0441\u0442\u0430!!!!
+SpeedTestWizard.abort.message.manual.abort=\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+SpeedTestWizard.abort.message.scheduling.failed=\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0430 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e
+SpeedTestWizard.abort.message.download.added=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 %1, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0442\u0435\u0441\u0442\u0430
+SpeedTestWizard.abort.message.entered.error=\u0422\u0435\u0441\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0438\u043b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 '%1'
+SpeedTestWizard.abort.message.entered.queued=\u0422\u0435\u0441\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0438\u043b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0430\u0443\u0437\u044b/\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
+SpeedTestWizard.abort.message.interrupted=\u041f\u043e\u0442\u043e\u043a \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0431\u044b\u043b \u043f\u0440\u0435\u0440\u0432\u0430\u043d \u0434\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430
+SpeedTestWizard.abort.message.execution.failed=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0430 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e
+SpeedTestWizard.abort.message.failed.peers=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u0435\u043c-\u043b\u0438\u0431\u043e \u0438\u0437 \u043f\u0438\u0440\u043e\u0432
+SpeedTestWizard.abort.message.insufficient.slots=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0443-\u043b\u0438\u0431\u043e \u0438\u0437 \u043f\u0438\u0440\u043e\u0432 - \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0442\u043e\u0432 \u0440\u0430\u0437\u0434\u0430\u0447\u0438?
+SpeedTestWizard.abort.message.not.unchoked=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441 \u043a\u043e\u0433\u043e-\u043b\u0438\u0431\u043e \u0438\u0437 \u043f\u0438\u0440\u043e\u0432, \u0442.\u043a. \u043e\u043d\u0438 \u043d\u0438 \u0440\u0430\u0437\u0443 \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u043b\u0438 \u043a\u0430\u043d\u0430\u043b
+SpeedTestWizard.stage.message.requesting=\u0437\u0430\u043f\u0440\u043e\u0441 \u0442\u0435\u0441\u0442\u0430....
+SpeedTestWizard.stage.message.preparing=\u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0442\u0435\u0441\u0442\u0430....
+SpeedTestWizard.stage.message.starting=\u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u0430....
+SpeedTestWizard.stage.message.connect.stats=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439: \u043f\u0438\u0440\u044b=%1, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430_ok=%2, \u0440\u0430\u0437\u0434\u0430\u0447\u0430_ok=%3
+window.uiswitcher.title=\u0412\u044b\u0431\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
+window.uiswitcher.text=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0412\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.
+window.uiswitcher.NewUI.title=VUZE (\u043d\u043e\u0432\u044b\u0439)
+window.uiswitcher.NewUI.text=\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043e \u0422\u041e\u041b\u042c\u041a\u041e \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u0430 Vuze!\n\n\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438:\n* \u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u04 [...]
+window.uiswitcher.ClassicUI.title=AZUREUS (\u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439)
+window.uiswitcher.ClassicUI.text=\u0420\u0415\u041a\u041e\u041c\u0415\u041d\u0414\u041e\u0412\u0410\u041d\u041e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\n\u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\ [...]
 iconBar.switch.tooltip=\u0412\u044b\u0431\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 Vuze
-VivaldiView.notAvailable=\u0414\u0438\u0430\u0433\u0440\u0430\u043c\u043c\u0430 \u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-restart.error=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f:\n%1\n\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <A HREF="{restart.error.url}">restarting issues</a>.
-restart.error.oom=\u041f\u0430\u043c\u044f\u0442\u044c \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043d\u0430
-restart.error.fnf=\u00ab%1\u00bb \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u00ab%2\u00bb
-restart.error.pnf=\u041f\u0443\u0442\u044c \u00ab%1\u00bb \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
-restart.error.bad=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f \u00ab%1\u00bb
-restart.error.denied=\u041f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u00ab%1\u00bb \u0434\u043e\u0441\u0442\u0443\u043f \u0431\u044b\u043b \u0437\u0430\u043f\u0440\u0435\u0449\u0451\u043d.  \u0423\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044c\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043b\u0 [...]
-TableColumn.header.date_completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e \u0432
-TableColumn.menu.date_added.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0430\u0442\u0443
-ConfigView.section.ipfilter.discardbanning=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0437\u043b\u044b, \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u00ab\u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442\u0431\u0440\u043e\u0448\u0435\u043d\u043e/\u043f\u0440\u0438\u043d\u044f\u0442\u043e\u00bb \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 [0: \u043e\u0442\u043a\u043b\u044e\u0447\u04 [...]
-ConfigView.section.ipfilter.discardminkb=\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0435\u0441\u043b\u0438 \u0431\u044b\u043b\u043e \u043e\u0442\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 (%1)
-ConfigView.interface.start.advanced=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 (AZ 2.x)
+VivaldiView.notAvailable=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 '\u0412\u0438\u0432\u0430\u043b\u044c\u0434\u0438' \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
+restart.error=\u0420\u0435\u0441\u0442\u0430\u0440\u0442 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f:\n%1\n\u0421\u043c. <A HREF="{restart.error.url}">restarting issues</a>.
+restart.error.oom=\u041d\u0435\u0445\u0432\u0430\u0442\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438
+restart.error.fnf='%1' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0432 '%2'
+restart.error.pnf=\u041f\u0443\u0442\u044c '%1' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
+restart.error.bad=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u0444\u0430\u0439\u043b\u0430 \u0434\u043b\u044f '%1'
+restart.error.denied=\u0414\u043e\u0441\u0442\u0443\u043f \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d \u0432\u043e \u0440\u0435\u043c\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c '%1'.  \u0423\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044c\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u044 [...]
+TableColumn.header.date_completed=\u0414\u0430\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f
+TableColumn.menu.date_added.reset=\u0414\u0430\u0442\u0430 \u0441\u0431\u0440\u043e\u0441\u0430
+ConfigView.section.ipfilter.discardbanning=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0438\u0440\u043e\u0432, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043f\u043b\u043e\u0445\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 [0: \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u [...]
+ConfigView.section.ipfilter.discardminkb=\u041c\u0438\u043d\u0438\u043c\u0443\u043c %1 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f
+ConfigView.interface.start.advanced=\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0432 \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u043c \u0412\u0438\u0434\u0435 (AZ 2.x)
 MyTorrents.column.ColumnQuality=\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e
 MyTorrents.column.ColumnSpeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
 MyTorrents.column.ColumnProgressETA.2ndLine=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c: %1
-MyTorrents.column.ColumnProgressETA.StreamReady=\u041f\u043e\u0442\u043e\u043a \u0433\u043e\u0442\u043e\u0432
-MyTorrents.column.ColumnProgressETA.PlayableIn=\u0413\u043e\u0442\u043e\u0432 \u043a \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0443 \u0447\u0435\u0440\u0435\u0437 %1
+MyTorrents.column.ColumnProgressETA.StreamReady=\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0433\u043e\u0442\u043e\u0432\u0430
+MyTorrents.column.ColumnProgressETA.PlayableIn=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0432 %1
 TableColumn.header.Quality=\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e
 TableColumn.header.Speed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
-TableColumn.header.RateIt=\u041e\u0446\u0435\u043d\u0438\u0442\u044c
-TableColumn.header.Rating=\u041e\u0446\u0435\u043d\u043a\u0430
+TableColumn.header.RateIt=\u0420\u0435\u0439\u0442\u0438\u043d\u0433
+TableColumn.header.Rating=\u0420\u0435\u0439\u0442\u0438\u043d\u0433
 TableColumn.header.SpeedGraphic=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
-TableColumn.header.AzProduct=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a
+TableColumn.header.AzProduct=\u041e\u0442
 TableColumn.header.MediaThumb=\u041c\u0435\u0434\u0438\u0430
 TableColumn.header.ProgressETA=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441
-#TableColumn.header.size={MyTorrentsView.size}
-#TableColumn.header.up={MyTorrentsView.up}
-#TableColumn.header.date_added={MyTorrentsView.date_added}
-#TableColumn.header.name={MyTorrentsView.name}
 TableColumn.header.name.ext=\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u0430: %1
-#TableColumn.header.shareRatio={MyTorrentsView.shareRatio}
+v3.MainWindow.tab.home=\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u041f\u0430\u043d\u0435\u043b\u044c
 v3.MainWindow.tab.browse=\u0412 Vuze
-v3.MainWindow.tab.library=\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430
-v3.MainWindow.tab.publish=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438
+v3.MainWindow.tab.library=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+v3.MainWindow.tab.publish=\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c
 v3.MainWindow.tab.advanced=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439
+v3.MainWindow.menu.home=&\u0420\u0430\u0431\u043e\u0447\u0430\u044f \u041f\u0430\u043d\u0435\u043b\u044c
 v3.MainWindow.menu.browse=&\u0412 Vuze
-v3.MainWindow.menu.library=&\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430
-v3.MainWindow.menu.publish=&\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f
+v3.MainWindow.menu.library=&\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+v3.MainWindow.menu.publish=&\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c
 v3.MainWindow.menu.advanced=&\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439
 v3.MainWindow.menu.view.searchbar=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430
-v3.MainWindow.menu.view.tabbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0432\u043a\u043b\u0430\u0434\u043e\u043a
+v3.MainWindow.menu.view.tabbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043e\u043a
 v3.MainWindow.currentDL=\u0421\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f
 v3.MainWindow.button.stream=\u041f\u043e\u0442\u043e\u043a
 v3.MainWindow.button.stop=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-v3.MainWindow.button.start=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-v3.MainWindow.button.pause=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-v3.MainWindow.button.resume=\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
-v3.MainWindow.button.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-v3.MainWindow.button.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-v3.MainWindow.button.viewdetails=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-v3.MainWindow.button.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438
-v3.MainWindow.button.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+v3.MainWindow.button.start=\u0421\u0442\u0430\u0440\u0442
+v3.MainWindow.button.pause=\u041f\u0430\u0443\u0437\u0430
+v3.MainWindow.button.resume=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c
+v3.MainWindow.button.delete=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+v3.MainWindow.button.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
+v3.MainWindow.button.viewdetails=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+v3.MainWindow.button.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435
+v3.MainWindow.button.cancel=\u041e\u0442\u043c\u0435\u043d\u0430
 v3.MainWindow.button.preview=\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440
-v3.MainWindow.view.wait=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435.
+v3.MainWindow.view.wait=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435.
 v3.MainWindow.xofx=%1 \u0438\u0437 %2
-v3.MainWindow.Loading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430...
-v3.filter-bar=\u0424\u0438\u043b\u044c\u0442\u0440:
-v3.MainWindow.search.defaultText=\u043d\u0430\u0439\u0442\u0438...
+v3.MainWindow.Loading=\u0418\u0434\u0451\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430... \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435.
+v3.filter-bar=\u0424\u0438\u043b\u044c\u0442\u0440 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439:
+v3.MainWindow.search.defaultText=\u0438\u0441\u043a\u0430\u0442\u044c...
 v3.mb.delPublished.title=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430
-v3.mb.delPublished.text=\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415: \u042d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u041d\u0415 \u0443\u0434\u0430\u043b\u0438\u0442 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u00ab%1\u00bb \u0438\u0437 <A HREF="%2">%3</A> .\n\n\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u0423\u0434\u0430\u043b\u0438\u0442\u044c\u00bb \u0442\u043e\u043b\u0 [...]
-v3.mb.delPublished.delete=&\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-v3.mb.delPublished.cancel=\u041e&\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+v3.mb.delPublished.text=\u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u042d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u041d\u0415 \u0443\u0431\u0438\u0440\u0435\u0442 \u0412\u0430\u0448 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 '%1' \u0438\u0437 <A HREF="%2">%3</A> .\n\n\u041d\u0430\u0436\u0438\u043c\u0430\u0439\u0442\u0435 "\u0421\u0442\u0435 [...]
+v3.mb.delPublished.delete=&\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+v3.mb.delPublished.cancel=&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 v3.mb.openFile.title=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0444\u0430\u0439\u043b
-v3.mb.openFile.text.known=Vuze Player \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <a href="http://www.az [...]
-v3.mb.openFile.text.unknown=Vuze Player \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <a href="http://www. [...]
-v3.mb.openFile.button.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438
+v3.mb.openFile.text.known=\u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u043c Vuze. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e [...]
+v3.mb.openFile.text.unknown=\u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u041f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u043c Vuze. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435\u0441\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u04 [...]
+v3.mb.openFile.button.play=\u0418\u0433\u0440\u0430\u0442\u044c
 v3.mb.openFile.button.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
-v3.mb.openFile.button.guide=\u0421\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e
-v3.mb.openFile.remember=\u0412\u0441\u0435\u0433\u0434\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b
+v3.mb.openFile.button.guide=\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044e
+v3.mb.openFile.remember=\u0412\u0441\u0435\u0433\u0434\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c, \u043d\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044f \u043c\u0435\u043d\u044f
 v3.mb.PlayFileNotFound.title=\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
-v3.mb.PlayFileNotFound.text=\u0424\u0430\u0439\u043b\u044b \u00ab%1\u00bb \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438\u043b\u0438 \u0431\u044b\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u044b.
-v3.mb.PlayFileNotFound.button.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 Vuze
-v3.mb.PlayFileNotFound.button.redownload=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043d\u043e\u0432\u0430
-v3.mb.PlayFileNotFound.button.find=\u041d\u0430\u0439\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e...
-v3.mb.deletePurchased.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
-v3.mb.deletePurchased.text=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u00ab%1\u00bb?\n\n\u042d\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043b\u0438\u0431\u043e \u0431\u044b\u043b \u0432\u0430\u043c\u0438 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0451\u043d, \u043b\u0438\u0431\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437 [...]
-v3.mb.deletePurchased.button.delete=&\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-v3.mb.deletePurchased.button.cancel=\u041e&\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+v3.mb.PlayFileNotFound.text=\u0424\u0430\u0439\u043b\u044b \u043e\u0442 '%1' \u0441\u0442\u0435\u0440\u0442\u044b \u0438\u043b\u0438 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u044b.
+v3.mb.PlayFileNotFound.button.remove=\u0423\u0431\u0440\u0430\u0442\u044c \u0438\u0437 Vuze
+v3.mb.PlayFileNotFound.button.redownload=\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435
+v3.mb.PlayFileNotFound.button.find=\u041d\u0430\u0439\u0442\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e..
+v3.mb.deletePurchased.title=\u0423\u0431\u0440\u0430\u0442\u044c \u043a\u0443\u043f\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
+v3.mb.deletePurchased.text=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0442\u0435\u0440\u0435\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 '%1'?\n\n\u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0412\u044b \u0438\u043b\u0438 \u043a\u0443\u043f\u0438\u043b\u0438, \u0438\u043b\u0438 \u0431\u044b\u043b\u0438 \u0432\u044b\u043d\u0443\u0436\u0434\u0435\u043d\u044b \u0437\u0430\u0440\u [...]
+v3.mb.deletePurchased.button.delete=&\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+v3.mb.deletePurchased.button.cancel=&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
 v3.topbar.menu.show.logo=\u041b\u043e\u0433\u043e\u0442\u0438\u043f
-v3.topbar.menu.show.plugin=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-v3.topbar.menu.show.search=\u041d\u0430\u0439\u0442\u0438
-splash.initializeCore=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044f\u0434\u0440\u0430
+v3.topbar.menu.show.plugin=\u041c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+v3.topbar.menu.show.search=\u041f\u043e\u0438\u0441\u043a
+v3.topbar.menu.show.frog=\u0421\u0438\u043d\u044f\u044f \u043b\u044f\u0433\u0443\u0448\u043a\u0430
+splash.initializeCore=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u042f\u0434\u0440\u0430
 splash.initializeUIElements=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
-ConfigView.section.transfer.autospeedbeta=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u0431\u0435\u0442\u0430)
-#
-ConfigView.section.ipfilter.peerblocking.group=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0443\u0437\u043b\u043e\u0432
+ConfigView.section.transfer.autospeedbeta=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (Beta)
+ConfigView.section.ipfilter.peerblocking.group=\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u0438\u0440\u043e\u0432
 ConfigView.section.ipfilter.autoload.group=\u0410\u0432\u0442\u043e\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
-ConfigView.section.ipfilter.autoload.file=\u0424\u0430\u0439\u043b \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 IP \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-ConfigView.section.ipfilter.autoload.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u044b DAT (eMule), P2P (PeerGuardian, splist), \u0438 P2B v1,2,3 (PeerGuardian 2). \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438\u043b\u0438 \u043f\u043e URL, \u0441\u0436\u043 [...]
-ConfigView.section.ipfilter.autoload.loadnow=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c
-splash.loadIpFilters=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 IP-\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432...
-SpeedTestWizard.set.upload.title=\u041f\u0440\u0435\u0434\u0435\u043b\u044b \u043f\u0440\u0438\u0451\u043c\u0430 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-SpeedTestWizard.set.download.label=\u041f\u0440\u0435\u0434\u0435\u043b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0451\u043c\u0430:
-SpeedTestWizard.set.upload.label=\u041f\u0440\u0435\u0434\u0435\u043b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438:
-SpeedTestWizard.name.conf.level.absolute=\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u0439
+ConfigView.section.ipfilter.autoload.file=\u0444\u0430\u0439\u043b \u0441 IP \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+ConfigView.section.ipfilter.autoload.info=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0444\u043e\u0440\u043c\u0430\u0442\u044b DAT (eMule), P2P (PeerGuardian, splist) \u0438 P2B v1,2,3 (PeerGuardian 2). \u0424\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0438\u043b\u0438 URL, \u0441\u0436\u0430\u0442\u044b\u043c (zip, gzip) \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442 [...]
+ConfigView.section.ipfilter.autoload.loadnow=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441
+splash.loadIpFilters=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 IP-\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432..
+SpeedTestWizard.set.upload.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043b\u0438\u043c\u0438\u0442\u044b \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+SpeedTestWizard.set.download.label=\u041b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:
+SpeedTestWizard.set.upload.label=\u041b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438:
+SpeedTestWizard.name.conf.level.absolute=\u041f\u043e\u043b\u043d\u044b\u0439
 SpeedTestWizard.name.conf.level.high=\u0412\u044b\u0441\u043e\u043a\u0438\u0439
 SpeedTestWizard.name.conf.level.med=\u0421\u0440\u0435\u0434\u043d\u0438\u0439
 SpeedTestWizard.name.conf.level.low=\u041d\u0438\u0437\u043a\u0438\u0439
 SpeedTestWizard.name.conf.level.none=\u041d\u0435\u0442
-ConfigView.section.transfer.select=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
-ConfigView.section.transfer.select.v2=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u0431\u0435\u0442\u0430)
+ConfigView.section.transfer.select=\u0410\u0432\u0442\u043e-\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
+ConfigView.section.transfer.select.v2=\u0410\u0432\u0442\u043e-\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c (beta)
 mb.azmustclose.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430
-mb.azmustclose.text=\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 Vuze \u0434\u043e\u043b\u0436\u043d\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0438\u0437-\u0437\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u04 [...]
-network.ipv6.prefer.addresses=\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c IPv6, \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b IPv6 \u0438 IPv4
-network.bindError=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u043e\u043a\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u0437-\u0437\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439 [...]
-network.enforce.ipbinding=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 IP, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b (\u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\ [...]
-DHTView.title.full_v6=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414 IPv6
-ConfigView.pluginlist.loadSelected=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435
+mb.azmustclose.text=Vuze \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u043a\u0440\u044b\u0442\u044c\u0441\u044f \u0432\u0441\u0438\u043b\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0420\u0435\u0441\u0442\u0430\u0440\u0442 Vuze \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0437\u0432\u0430\u043d \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043a\u0430\u043a  [...]
+network.ipv6.prefer.addresses=\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c IPv6-\u0430\u0434\u0440\u0435\u0441\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0430 - \u0438 IPv4 \u0438 IPv6 - \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b
+network.bindError=\u0421\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u043a\u0435\u0442\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0442.\u043a. \u043d\u0435\u0442 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u [...]
+network.enforce.ipbinding=\u041d\u0430\u0432\u044f\u0437\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u043a IP \u0434\u0430\u0436\u0435 \u043a\u043e\u0433\u0434\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b. \u041f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043b\u044e\u0431\u044b\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f, \u0435 [...]
+DHTView.title.full_v6=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0411\u0430\u0437\u0430 \u0414\u0430\u043d\u043d\u044b\u0445 IPv6
+ConfigView.pluginlist.loadSelected=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435
 SpeedView.stats.asn=\u0421\u0435\u0442\u044c:
-SpeedView.stats.estupcap=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u0447\u0430:
-SpeedView.stats.estdowncap=\u041c\u0430\u043a\u0441. \u043f\u0440\u0438\u0451\u043c:
-SpeedView.stats.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e
-SpeedView.stats.estimate=\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e
-SpeedView.stats.measured=\u0438\u0437\u043c\u0435\u0440\u0435\u043d\u043e
-SpeedView.stats.measuredmin=\u0438\u0437\u043c\u0435\u0440\u0435\u043d\u043e \u043c\u0438\u043d.
-SpeedView.stats.manual=\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043e
-ConfigView.section.transfer.autospeed.networks=\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0435\u0442\u0438
-ConfigView.section.transfer.autospeed.resetnetwork=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0441\u0435\u0442\u0438
-ConfigView.section.transfer.autospeed.network.info=\u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0431\u043c\u0435\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u043b\u0438 \u043f\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u0442\u04 [...]
-dialog.uiswitcher.restart.title=\u0412\u044b\u0431\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 Vuze: \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
-dialog.uiswitcher.restart.text=\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Vuze.
-TrayWindow.menu.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+SpeedView.stats.estupcap=\u041b\u0438\u043c\u0438\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438:
+SpeedView.stats.estdowncap=\u041b\u0438\u043c\u0438\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:
+SpeedView.stats.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439
+SpeedView.stats.estimate=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439
+SpeedView.stats.measured=\u0418\u0437\u043c\u0435\u0440\u0435\u043d\u043d\u044b\u0439
+SpeedView.stats.measuredmin=\u0418\u0437\u043c\u0435\u0440\u0435\u043d\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e
+SpeedView.stats.manual=\u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439
+ConfigView.section.transfer.autospeed.networks=\u0414\u0435\u0442\u0430\u043b\u0438 \u0441\u0435\u0442\u0438
+ConfigView.section.transfer.autospeed.resetnetwork=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u0441\u0435\u0442\u0438
+ConfigView.section.transfer.autospeed.network.info=\u0412\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043b\u0438\u043c\u0438\u0442\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438\n\u0438\u043b\u0438 \u044f\u043 [...]
+dialog.uiswitcher.restart.title=\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u0435\u043b\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430: \u0434\u043b\u044f Vuze \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442
+dialog.uiswitcher.restart.text=\u0414\u043b\u044f Vuze \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.
+TrayWindow.menu.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c \u041a\u043e\u0440\u0437\u0438\u043d\u0443 \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 # Used for peers which we can't determine.
-PeerSocket.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e
-PeerSocket.bad_peer_id=\u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 ID \u0443\u0437\u043b\u0430
+PeerSocket.unknown=\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d
+PeerSocket.fake_client=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439
+PeerSocket.bad_peer_id=ID \u043f\u043b\u043e\u0445\u043e\u0433\u043e \u043f\u0438\u0440\u0430
 PeerSocket.mismatch_id=\u043d\u0435\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435
-PeerSocket.unknown_az_style=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e %1/%2
-PeerSocket.unknown_shadow_style=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e %1/%2
-OpenTorrentWindow.mb.askCreateDir.title=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
-OpenTorrentWindow.mb.askCreateDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u00ab%1\u00bb \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\n\u0421\u043e\u0437\u0434\u0430\u0442\u044c?
-SpeedView.stats.estimatechoke=\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e (\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e)
-ConfigTransferAutoSpeed.upload.capacity.usage=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+PeerSocket.unknown_az_style=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 %1/%2
+PeerSocket.unknown_shadow_style=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 %1/%2
+OpenTorrentWindow.mb.askCreateDir.title=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
+OpenTorrentWindow.mb.askCreateDir.text=\u041f\u0430\u043f\u043a\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f '%1' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\n\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441?
+SpeedView.stats.estimatechoke=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 (\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430)
+ConfigTransferAutoSpeed.upload.capacity.usage=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0448\u0438\u0440\u0438\u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0430 \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443
 ConfigTransferAutoSpeed.mode=\u0420\u0435\u0436\u0438\u043c:
-ConfigTransferAutoSpeed.capacity.used=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u043e\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+ConfigTransferAutoSpeed.capacity.used=% \u0448\u0438\u0440\u0438\u043d\u044b \u043a\u0430\u043d\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f
 ConfigTransferAutoSpeed.while.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430:
-ConfigTransferAutoSpeed.set.point=\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u0447\u043a\u0443 (\u043c\u0441)
-ConfigTransferAutoSpeed.set.tolerance=\u043f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u044c (\u043c\u0441)
-ConfigTransferAutoSpeed.ping.time.good=\u0425\u043e\u0440\u043e\u0448\u0438\u0439:
-ConfigTransferAutoSpeed.ping.time.bad=\u041f\u043b\u043e\u0445\u043e\u0439:
-ConfigTransferAutoSpeed.adjustment.interval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0438:
-ConfigTransferAutoSpeed.skip.after.adjust=\u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u043a\u0438:
-GeneralView.label.distributedCopies=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439:
+ConfigTransferAutoSpeed.set.dht.ping=DHT \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u0438\u043d\u0433\u0430:
+ConfigTransferAutoSpeed.set.point=\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0446\u0435\u043b\u044c (ms)
+ConfigTransferAutoSpeed.set.tolerance=\u0434\u043e\u043f\u0443\u0441\u043a (ms)
+ConfigTransferAutoSpeed.ping.time.good=\u0425\u043e\u0440\u043e\u0448\u043e:
+ConfigTransferAutoSpeed.ping.time.bad=\u041f\u043b\u043e\u0445\u043e:
+ConfigTransferAutoSpeed.adjustment.interval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:
+ConfigTransferAutoSpeed.skip.after.adjust=\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438:
+GeneralView.label.distributedCopies=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043f\u0438\u0438:
 PiecesView.DistributionView.title=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0447\u0430\u0441\u0442\u0435\u0439
-PiecesView.DistributionView.NoAvl=\u041d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438
-PiecesView.DistributionView.SeedAvl=\u0412\u0437\u043d\u043e\u0441 \u0443\u0437\u043b\u0430 \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
-PiecesView.DistributionView.PeerAvl=
-PiecesView.DistributionView.RarestAvl=\u0420\u0435\u0434\u043a\u0438\u0435: %1 (\u0414\u043e\u0441\u0442.:%2)
-PiecesView.DistributionView.weHave=\u0418\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0447\u0430\u0441\u0442\u0438
-PiecesView.DistributionView.theyHave=\u0427\u0430\u0441\u0442\u0438 \u0443\u0437\u043b\u0430
-PiecesView.DistributionView.weDownload=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0435 \u0447\u0430\u0441\u0442\u0438
-PeersView.gain=\u041f\u0440\u0438\u0431\u044b\u043b\u044c
-PeersView.gain.info=\u041e\u0431\u044a\u0451\u043c \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0438\u043d\u0443\u0441 \u043e\u0431\u044a\u0451\u043c \u0440\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445
-unix.script.new.title=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze
-unix.script.new.text=\u041d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d \u0432 \u00ab%1\u00bb.\n\n\u041d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 Vuze \u0438 \u04 [...]
+PiecesView.DistributionView.NoAvl=\u041d\u0435\u0442 \u043d\u0438 \u0443 \u043a\u043e\u0433\u043e
+PiecesView.DistributionView.SeedAvl=\u0427\u0430\u0441\u0442\u0438 \u0443 \u0421\u0438\u0434\u043e\u0432
+PiecesView.DistributionView.PeerAvl=\u0427\u0430\u0441\u0442\u0438 \u0443 \u041b\u0438\u0447\u0435\u0440\u043e\u0432
+PiecesView.DistributionView.RarestAvl=\u0420\u0435\u0434\u0447\u0430\u0439\u0448\u0438\u0445: %1 (\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0443 %2 \u043f\u0438\u0440\u043e\u0432)
+PiecesView.DistributionView.weHave=\u0427\u0430\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u0412\u0430\u0441 \u0435\u0441\u0442\u044c
+PiecesView.DistributionView.theyHave=\u0427\u0430\u0441\u0442\u0435\u0439 \u0443 \u043f\u0438\u0440\u0430
+PiecesView.DistributionView.weDownload=\u0427\u0430\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0412\u044b \u043a\u0430\u0447\u0430\u0435\u0442\u0435
+PeersView.gain=\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e
+PeersView.gain.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445-\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445
+unix.script.new.title=\u041d\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
+unix.script.new.text=\u041d\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d \u0432 '%1'.\n\n\u041a\u0440\u0430\u0439\u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 Vuze \u0438 \u043f\u0435\u0440\u0435 [...]
 unix.script.new.button.quit=\u0412\u044b\u0439\u0442\u0438 \u0441\u0435\u0439\u0447\u0430\u0441
-unix.script.new.button.continue=\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0437\u0436\u0435
-unix.script.new.button.asknomore=\u041d\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430
-unix.script.new.auto.title=\u041d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze
-unix.script.new.auto.text=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze.\n\n\u041d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Vuze.
-Content.alert.notuploaded.button.stop=\u041e&\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-Content.alert.notuploaded.button.continue=&\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0443
+unix.script.new.button.continue=\u042f \u0441\u0434\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u043f\u043e\u0437\u0436\u0435
+unix.script.new.button.asknomore=\u041d\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u043c\u043d\u0435 \u0441\u043d\u043e\u0432\u0430
+unix.script.new.auto.title=\u041d\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze
+unix.script.new.auto.text=\u041d\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d.\n\n \u041a\u0440\u0430\u0439\u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c Vuze \u0441\u0435\u0439\u0447\u0430\u0441.
 Content.alert.notuploaded.button.abort=&\u041d\u0435 \u0432\u044b\u0445\u043e\u0434\u0438\u0442\u044c
-ConfigView.label.checkOnSeeding=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0451\u043c\u043a\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435
-ConfigView.label.ui_switcher=\u041e\u043a\u043d\u043e \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 Vuze
+ConfigView.label.checkOnSeeding=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0438\u0437\u043a\u043e-\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0449\u0443\u044e \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043f\u0435\u0440\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0447\u0430\u0441\u0442\u0435\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+ConfigView.label.ui_switcher=\u0412\u044b\u0431\u043e\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
 ConfigView.label.ui_switcher_button=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
-SpeedTestWizard.test.panel.explain=\u0418\u0437\u043c\u0435\u0440\u044c\u0442\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c Vuze. \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0442\u0435\u0441\u0442\u0430 \u0438 \u0440\u0435\u0436\u0438\u043c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e \u0442\u0435\u0441\u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\ [...]
-SpeedTestWizard.set.upload.hint=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u043e\u0432 \u043f\u0440\u0438\u0451\u043c\u0430 \u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 Vuze.
-SpeedTestWizard.set.upload.panel.explain=\u041f\u0440\u0435\u0434\u0435\u043b\u044b, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u0434\u0435\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u [...]
-SpeedTestWizard.set.limit.conf.level=\u0422\u0438\u043f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f
-SpeedTestWizard.finish.panel.auto.speed=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c:
-SpeedTestWizard.finish.panel.auto.speed.seeding=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435: 
-ConfigTransferAutoSpeed.add.comment.to.log.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b
-ConfigTransferAutoSpeed.add.comment.to.log=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:
-ConfigTransferAutoSpeed.log.button=\u0416\u0443\u0440\u043d\u0430\u043b
-ConfigTransferAutoSpeed.algorithm.selector=\u0412\u044b\u0431\u043e\u0440 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0430\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
-ConfigTransferAutoSpeed.algorithm=\u0421\u0445\u0435\u043c\u0430:
-ConfigTransferAutoSpeed.auto.speed.classic=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f)
-ConfigTransferAutoSpeed.auto.speed.beta=\u0410\u0432\u0442\u043e\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (\u0431\u0435\u0442\u0430)
+SpeedTestWizard.test.panel.explain=\u0418\u0437\u043c\u0435\u0440\u044c\u0442\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 Vuze.\n\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u0440\u0435\u0436\u0438\u043c \u0448\u0438\u0444\u0440\u0430\u0446\u0438\u0438.\n\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u043 [...]
+SpeedTestWizard.set.upload.hint=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043b\u0438\u043c\u0438\u0442\u044b \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c Vuze AutoSpeed.
+SpeedTestWizard.set.upload.panel.explain=\u041b\u0438\u043c\u0438\u0442\u044b, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0437\u0434\u0435\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c AutoSpeed. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043b\u0438\u043c\u0438\u0442\u044b  \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043a\u0 [...]
+SpeedTestWizard.set.limit.conf.level=\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438
+SpeedTestWizard.finish.panel.auto.speed=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c:
+SpeedTestWizard.finish.panel.auto.speed.seeding=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:
+ConfigTransferAutoSpeed.add.comment.to.log.group=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0432 \u0436\u0443\u0440\u043d\u0430\u043b \u043e\u0448\u0438\u0431\u043e\u043a
+ConfigTransferAutoSpeed.add.comment.to.log=\u0414\u043e\u0431. \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:
+ConfigTransferAutoSpeed.log.button=\u041b\u043e\u0433
+ConfigTransferAutoSpeed.algorithm.selector=\u0412\u044b\u0431\u043e\u0440 \u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+ConfigTransferAutoSpeed.algorithm=\u0410\u043b\u0433\u043e\u0440\u0438\u0442\u043c:
+ConfigTransferAutoSpeed.auto.speed.classic=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (classic)
+ConfigTransferAutoSpeed.auto.speed.beta=\u0410\u0432\u0442\u043e-\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c (beta)
 ConfigTransferAutoSpeed.data.update.frequency=\u0427\u0430\u0441\u0442\u043e\u0442\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-Alert.failed.update=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435: <A HREF="{Alert.failed.update.url}">AzureusWiki: \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0 [...]
-OpenTorrentWindow.mb.existingFiles.partialList=(\u041d\u0435\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a.  \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0430\u0439\u043b\u043e\u0432)
-TableColumn.header.bad_avail_time.info=\u0412\u0440\u0435\u043c\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f \u0431\u044b\u043b\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-TableColumn.header.bad_avail_time=\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u043e\u043f\u0438\u0438
-MyTorrentsView.menu.exporthttpseeds=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
-SWT.alert.erroringuithread=\u0412 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438.
-ConfigView.label.minannounce=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u0435\u0436\u0434\u0443 \u0430\u043d\u043e\u043d\u0441\u0430\u043c\u0438 (\u0441)
-ConfigView.label.maxnumwant=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
-ConfigView.label.announceport=\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 TCP \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u043e\u0432, PEX \u0438 DHT.\n[\u043f\u0443\u0441\u0442\u043e\u0435 \u043f\u043e\u043b\u0435: \u043d\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c, 0: \u0437\u0430\u043f\u0440\u0435\u0442\u043 [...]
-ConfigView.label.noportannounce=\u041d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 (\u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u043d\u0430 PEX \u0438 \u0420\u0411\u0414)
-ConfigView.label.maxseedspertorrent=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e] 
-wizard.webseed=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443 HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438
-wizard.webseed.title=HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438
-wizard.webseed.configuration=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 HTTP-\u0440\u0430\u0437\u0434\u0430\u0447\u0438
-wizard.webseed.adding=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 HTTP-\u0440\u0430\u0437\u0434\u0430\u0447
-GeneralView.label.private=\u0417\u0430\u043a\u0440\u044b\u0442\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442:
+Alert.failed.update=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0435 \u0443\u0434\u0430\u0447\u043d\u0430. \u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 <A HREF="{Alert.failed.update.url}">AzureusWiki: Failed Update</A> [%1]
+OpenTorrentWindow.mb.existingFiles.partialList=(\u041d\u0435\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a. \u0411\u043e\u043b\u044c\u0448\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442)
+TableColumn.header.bad_avail_time.info=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u0431\u044b\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f
+TableColumn.header.bad_avail_time=\u041f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u044f\u043b\u0430\u0441\u044c
+MyTorrentsView.menu.exporthttpseeds=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL '\u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0447\u0435\u0440\u0435\u0437 HTTP' \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+SWT.alert.erroringuithread=\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043d\u0435\u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435, \u043c\u043e\u0433\u0443\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438.
+ConfigView.label.minannounce=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0430\u043d\u043e\u043d\u0441-\u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u0442\u0440\u0435\u043a\u0435\u0440\u0443 [\u0441\u0435\u043a]
+ConfigView.label.maxnumwant=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0438\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440
+ConfigView.label.announceport=\u041f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c \u0430\u043d\u043e\u043d\u0441\u0438\u0440\u0443\u0435\u043c\u044b\u0439 TCP-\u043f\u043e\u0440\u0442 \u0434\u043b\u044f \u0430\u043d\u043e\u043d\u0441\u043e\u0432 \u0442\u0440\u0435\u043a\u0435\u0440\u0430,\nPEX \u0438 DHT [\u043f\u0443\u0441\u0442\u043e: \u043d\u0435 \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c, 0: \u043d\u0435\u0442 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u04 [...]
+ConfigView.label.noportannounce=\u041d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e\u0440\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0443 (\u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 PEX, DHT)
+ConfigView.label.maxseedspertorrent=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u0434\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430) [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e] 
+wizard.webseed=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c HTTP Seed \u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+wizard.webseed.title=HTTP-\u0441\u0438\u0434\u044b (webseed)
+wizard.webseed.configuration=\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f HTTP Seed
+wizard.webseed.adding=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 HTTP Seed
+GeneralView.label.private=\u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442:
 GeneralView.yes=\u0414\u0430
 GeneralView.no=\u041d\u0435\u0442
-ConfigView.label.userequestlimiting=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u043d\u0435 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0447\u0442\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 [\u043 [...]
-ConfigView.label.userequestlimiting.tooltip=\u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u043b\u0430\u0432\u043d\u044b\u0439, \u043a\u0430\u043a \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0447\u0442\u0435\u043d\u0438\u044f, \u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0 [...]
-ConfigView.label.userequestlimitingpriorities=\u041f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0451\u043c\u0430 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043e\u0447\u04 [...]
-ConfigView.section.logging.timestamp=\u0424\u043e\u0440\u043c\u0430\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0436\u0443\u0440\u043d\u0430\u043b\u0430
-Peers.column.timetocomplete=\u041e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0432\u0440\u0435\u043c\u044f
-Peers.column.timetocomplete.info=\u0412\u0440\u0435\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0437\u043b\u0443 \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f
-ConfigView.section.interface.display.suppress.file.download.dialog=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0438\u0430\u043b\u043e\u0433 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430
-ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0430 \u043d\u0435 \u0432\u043e \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u043c \u043e\u043a\u043d\u0435
-FileDownload.canceled=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430 \u043f\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: %1
+ConfigView.label.userequestlimiting=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0 [...]
+ConfigView.label.userequestlimiting.tooltip=\u041b\u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0435 \u0442\u0430\u043a\u043e\u0435 \u043f\u043b\u0430\u0432\u043d\u043e\u0435, \u043a\u0430\u043a \u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435, \u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u04 [...]
+ConfigView.label.userequestlimitingpriorities=\u0421\u0444\u043e\u043a\u0443\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043a\u043e\u0433\u0434\u0430 \u043b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0 [...]
+ConfigView.section.logging.timestamp=\u0424\u043e\u0440\u043c\u0430\u0442 \u0441\u043e \u0448\u0442\u0430\u043c\u043f\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u043b\u043e\u0433-\u0444\u0430\u0439\u043b\u043e\u0432
+Peers.column.timetocomplete=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438
+Peers.column.timetocomplete.info=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u043f\u0438\u0440\u043e\u043c
+ConfigView.section.interface.display.suppress.file.download.dialog=\u041f\u043e\u0434\u0430\u0432\u0438\u0442\u044c \u043e\u043a\u043d\u043e \u0434\u0438\u0430\u043b\u043e\u0433\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430
+ConfigView.section.interface.display.suppress.file.download.dialog.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043 [...]
+FileDownload.canceled=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c: %1
 Progress.reporting.status.canceled=\u041e\u0442\u043c\u0435\u043d\u0435\u043d\u043e
-Progress.reporting.status.finished=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
-Progress.reporting.status.retrying=\u041f\u043e\u0432\u0442\u043e\u0440...
-Progress.reporting.action.label.retry.tooltip=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
-Progress.reporting.action.label.remove.tooltip=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0442\u0447\u0451\u0442 \u0438\u0437 \u0436\u0443\u0440\u043d\u0430\u043b\u0430
-Progress.reporting.action.label.cancel.tooltip=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
-Progress.reporting.action.label.detail=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-Progress.reporting.default.error=\u041e\u0448\u0438\u0431\u043a\u0430
-Progress.reporting.no.reports.to.display=\u041e\u0442\u0447\u0451\u0442\u044b \u043e\u0431 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u0445 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.
-Progress.reporting.no.history.to.display=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442.
-Progress.reporting.detail.history.limit=\u041f\u0440\u0435\u0434\u0435\u043b \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (%1) \u0431\u044b\u043b \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442; \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u043 [...]
-Progress.reporting.statusbar.button.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u043e\u0442\u0447\u0451\u0442\u0430 \u043e\u0431 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438
-webui.bindip=\u0410\u0434\u0440\u0435\u0441 IP \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u2014 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f (*)
-v3.MainWindow.text.log.in=\u0412\u043e\u0439\u0442\u0438
-v3.MainWindow.text.log.out=\u0412\u044b\u0439\u0442\u0438
-v3.MainWindow.text.get.started=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0447\u0451\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c
-v3.MainWindow.text.my.account=\u0421\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e\u0431 \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438
+Progress.reporting.status.finished=\u0417\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e
+Progress.reporting.status.retrying=\u041f\u044b\u0442\u0430\u044e\u0441\u044c \u0441\u043d\u043e\u0432\u0430...
+Progress.reporting.action.label.retry.tooltip=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e
+Progress.reporting.action.label.remove.tooltip=\u0423\u0431\u0440\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043e\u0442\u0447\u0435\u0442 \u0438\u0437 \u0438\u0441\u0442\u043e\u0440\u0438\u0438
+Progress.reporting.action.label.cancel.tooltip=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e
+Progress.reporting.action.label.detail=\u0414\u0435\u0442\u0430\u043b\u0438
+Progress.reporting.default.error=\u041d\u0435\u0443\u0434\u0430\u0447\u0430
+Progress.reporting.no.reports.to.display=\u041d\u0435\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430
+Progress.reporting.no.history.to.display=\u041d\u0435\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430
+Progress.reporting.detail.history.limit=\u041b\u0438\u043c\u0438\u0442 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (%1) \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0447\u0435\u0442\u0430 \u043e \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0435 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d; \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u04 [...]
+Progress.reporting.statusbar.button.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u043a\u043d\u043e \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0435
+webui.bindip=\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u0441  IP - \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f (*)
+v3.MainWindow.text.log.in=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+v3.MainWindow.text.log.out=\u0412\u044b\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
+v3.MainWindow.text.get.started=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
+v3.MainWindow.text.my.account=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431 \u0410\u043a\u043a\u0430\u0443\u043d\u0442\u0435
 v3.MainWindow.text.my.profile=\u041f\u0440\u043e\u0444\u0438\u043b\u044c
-OpenTorrentWindow.simple.open=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 (\u0444\u0430\u0439\u043b, URL, \u0445\u0435\u0448)
-Progress.reporting.window.remove.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438
-Progress.reporting.window.remove.auto.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435, \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438
-Progress.reporting.window.remove.now=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438
-Progress.reporting.window.remove.now.tooltip=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u044b\u0435, \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438
-dhttracker.tracklimitedwhenonline=\u041d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435\u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0451\u043c\u043a\u043e\u0435 \u0441\u043b\u0435\u0436\u0435\u043d\u0438\u0435 \u0432 \u0446\u0435\u043b\u044f\u0445 \u043f\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
-TorrentOptionsView.multi.title.short=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TorrentOptionsView.multi.title.full=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-MyTorrentsView.menu.open_parent_folder=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0444\u0430\u0439\u043b\u043e\u043c
-ConfigView.section.style.use_show_parent_folder=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u00ab%1\u00bb \u0432\u043c\u0435\u0441\u0442\u043e \u00ab%2\u00bb \u0432 \u043c\u0435\u043d\u044e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0438 \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0435.\n\u041e\u04 [...]
-PeerManager.status.ps_disabled=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0443\u0437\u043b\u043e\u0432 \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d \u043d\u0430 \u0442\u0440\u0435\u043a\u0435\u0440\u0435
-ConfigView.section.stats.exportfiles=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u0430
-updater.cant.write.to.app.title=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
-updater.cant.write.to.app.details=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043f\u0430\u043f\u043a\u0443 \u00ab%1\u00bb.\n\n\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b.\n\n<a href="http://www.azureuswiki.com/index.php/Failed_Update">\u041f\u04 [...]
-plugin.install.class_version_error=\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438 Java.
+OpenTorrentWindow.simple.open=\u041c\u0435\u0441\u0442\u043e\u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 (\u0424\u0430\u0439\u043b, URL, Hash)
+Progress.reporting.window.remove.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b
+Progress.reporting.window.remove.auto.tooltip=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435, \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438\u0437 \u043f\u0440\u043e\u0441\u043c\u043e\u04 [...]
+Progress.reporting.window.remove.now=\u0423\u0431\u0440\u0430\u0442\u044c \u043d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b
+Progress.reporting.window.remove.now.tooltip=\u0423\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u044b\u0435, \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0435 \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438\u0437 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430
+dhttracker.tracklimitedwhenonline=\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0438\u0437\u043a\u043e\u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044e\u0449\u0438\u0439 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0442\u0440\u0435\u043a\u0438\u043d\u0433, \u043a\u043e\u0433\u0434\u0430 \u0412\u044b \u0432 \u0441\u0435\u0442\u0438, \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044 [...]
+TorrentOptionsView.multi.title.short=\u041e\u043f\u0446\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TorrentOptionsView.multi.title.full=\u041e\u043f\u0446\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+MyTorrentsView.menu.open_parent_folder=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c
+ConfigView.section.style.use_show_parent_folder=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c "%1" \u0432\u043c\u0435\u0441\u0442\u043e "%2" \u0432 \u043c\u0435\u043d\u044e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+ConfigView.section.style.use_show_parent_folder.tooltip=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u043e\u043f\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c \u0432 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0435.\n\u0422\u0 [...]
+PeerManager.status.ps_disabled=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u043f\u0438\u0440\u043e\u0432 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d
+ConfigView.section.stats.exportfiles=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0444\u0430\u0439\u043b\u0435
+updater.cant.write.to.app.title=\u041d\u0435 \u043c\u043e\u0433\u0443 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f
+updater.cant.write.to.app.details=\u041f\u0430\u043f\u043a\u0430 "%1" \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0430\u044f.\n\n\u042d\u0442\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443.\n\n\u041f\u0440\u043e\u0447\u0442\u0438\u0442\u0435 <a href="http://www.azureuswiki.com/in [...]
+plugin.install.class_version_error=\u041f\u043b\u0430\u0433\u0438\u043d \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0441\u0432\u0435\u0436\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 JAVA.
 v3.MainWindow.tab.minilibrary=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-v3.MainWindow.tab.events=\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f
-button.columnsetup.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432
-v3.activity.remove.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
-v3.activity.remove.text=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435?
-#v3.MainWindow.menu.view.configuration=Preferences
-#v3.MainWindow.menu.view.configuration.keybinding=Meta+,
+v3.MainWindow.tab.events=\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f
+button.columnsetup.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043b\u043e\u043d\u043e\u043a
+v3.activity.remove.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435
+v3.activity.remove.text=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435?
 v3.MainWindow.menu.file.closewindow=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
-Menu.show.torrent.menu=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u043d\u044e \u00ab\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb
-Menu.show.torrent.menu.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u043d\u044e \u00ab\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b\u00bb \u0432 \u043c\u0435\u043d\u044e \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430
-#v3.TorrentOptionsView.title.short=Preferences
-#v3.TorrentOptionsView.title.full=Preferences
-#v3.ConfigView.title.short=Preferences
-#v3.ConfigView.title.full=Preferences
-Views.plugins.aznetstatus.title=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0435\u0442\u0438
-plugin.aznetstatus.pingtarget=\u0422\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e \u0446\u0435\u043b\u0438
-ConfigView.section.style.usePathFinder=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u00abPath Finder\u00bb \u0432\u043c\u0435\u0441\u0442\u043e \u00abFinder\u00bb
+Menu.show.torrent.menu=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043c\u0435\u043d\u044e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+Menu.show.torrent.menu.tooltip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u043d\u044e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u0434 \u043f\u0430\u043d\u0435\u043b\u044c\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+Views.plugins.aznetstatus.title=\u0421\u0442\u0430\u0442\u0443\u0441 \u0421\u0435\u0442\u0438
+plugin.aznetstatus.pingtarget=\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0438\u043d\u0433\u0430/\u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438
+ConfigView.section.style.usePathFinder=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c '\u041f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438' \u0432\u043c\u0435\u0441\u0442\u043e '\u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0430'
 menu.sortByColumn=\u0421\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e %1 
-MyTorrentsView.menu.manual.per_peer=\u0417\u0430\u0434\u0430\u0442\u044c (\u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b)
-MyTorrentsView.menu.manual.shared_peers=\u0417\u0430\u0434\u0430\u0442\u044c (\u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0443\u0437\u043b\u043e\u0432)
-v3.button.removeActivityEntry=\u0423\u0431\u0440\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
-v3.splash.initSkin=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
-v3.splash.hookPluginUI=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
-OpenTorrentWindow.mb.notTorrent.cannot.display=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435
-MainWindow.menu.window.zoom.maximize=\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c
+MyTorrentsView.menu.manual.per_peer=\u0412\u0440\u0443\u0447\u043d\u0443\u044e (\u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0438\u0440\u0430)
+MyTorrentsView.menu.manual.shared_peers=\u0412\u0440\u0443\u0447\u043d\u0443\u044e (\u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043d\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0438\u0440\u043e\u0432)
+v3.button.removeActivityEntry=\u0423\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435
+v3.splash.initSkin=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043a\u0438\u043d \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
+v3.splash.hookPluginUI=\u041f\u043e\u0434\u0446\u0435\u043f\u043b\u044f\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u043b\u0430\u0433\u0438\u043d\u0430
+OpenTorrentWindow.mb.notTorrent.cannot.display=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435
+MainWindow.menu.window.zoom.maximize=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c
 MainWindow.menu.window.zoom.restore=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-ImageResizer.image.too.small=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 (\u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c %1 \u043d\u0430 %2)
-ImageResizer.title=\u042d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u043c, \u043a\u0430\u043a\u0438\u043c \u043e\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432 Vuze
-ImageResizer.move.image=\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043c\u044b\u0448\u044c\u044e
-ImageResizer.move.image.with.slider=\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043c\u044b\u0448\u044c\u044e \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043d\u0438\u0436\u0435
-security.crypto.title=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043b\u044e\u0447\u0430\u043c \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-security.crypto.encrypt=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043a\u043b\u044e\u0447\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u043e\u043b\u044c, \u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0 [...]
-security.crypto.decrypt=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0441\u043d\u044f\u0442\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0441 \u043a\u043b\u044e\u0447\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f.
-security.crypto.reason=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0434\u043b\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f
+ImageResizer.image.too.small=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 (\u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u [...]
+ImageResizer.title=\u042d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0412\u0430\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0412\u0430\u0448\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 Vuze
+ImageResizer.move.image=\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435
+ImageResizer.move.image.with.slider=\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0435\u0433\u0443\u043d\u043e\u043a \u043d\u0438\u0436\u0435
+security.crypto.title=\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043b\u044e\u0447\u0443 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+security.crypto.encrypt=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u0432\u0430\u0448\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041f [...]
+security.crypto.decrypt=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u044e\u0447\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+security.crypto.reason=\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f
 security.crypto.password=\u041f\u0430\u0440\u043e\u043b\u044c
-security.crypto.password2=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0435\u0449\u0451 \u0440\u0430\u0437
-security.crypto.persist_for=\u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c
+security.crypto.password2=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c \u0437\u0430\u043d\u043e\u0432\u043e
+security.crypto.persist_for=\u0421\u0440\u043e\u043a \u0433\u043e\u0434\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u043e\u043b\u044f
 security.crypto.persist_for.dont_save=\u041d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c
-security.crypto.persist_for.session=\u042d\u0442\u043e\u0442 \u0441\u0435\u0430\u043d\u0441
+security.crypto.persist_for.session=\u042d\u0442\u0430 \u0441\u0435\u0441\u0441\u0438\u044f
 security.crypto.persist_for.day=1 \u0434\u0435\u043d\u044c
 security.crypto.persist_for.week=1 \u043d\u0435\u0434\u0435\u043b\u044f
 security.crypto.persist_for.30days=30 \u0434\u043d\u0435\u0439
 security.crypto.persist_for.forever=\u041d\u0430\u0432\u0441\u0435\u0433\u0434\u0430
-security.crypto.password.mismatch.title=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c
-security.crypto.password.mismatch=\u0412\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443.
-ConfigView.section.security.group.crypto=\u041e\u0442\u043a\u0440\u044b\u0442\u044b\u0435/\u0437\u0430\u043a\u0440\u044b\u0442\u044b\u0435 \u043a\u043b\u044e\u0447\u0438
-ConfigView.section.security.resetkey=
-ConfigView.section.security.resetkey.warning.title=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0439 \u043f\u043e\u0442\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445
-ConfigView.section.security.resetkey.warning=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0438 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f? \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0437\u0430\u0449\u0438\u0449\u0451\u043d\u043d\u0430\u044f \u0441 \u0438\u0445 \u043f\u043e\u043c\u043e\u0449\u044c\u [...]
-ConfigView.section.security.unlockkey=\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+security.crypto.password.mismatch.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0430\u0440\u043e\u043b\u044f
+security.crypto.password.mismatch=\u0421\u0438\u043c\u0432\u043e\u043b\u044b \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0441\u043d\u043e\u0432\u0430.
+ConfigView.section.security.group.crypto=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435/\u041b\u0438\u0447\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0438
+ConfigView.section.security.resetkey=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0438
+ConfigView.section.security.resetkey.warning.title=\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u043f\u043e\u0442\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445
+ConfigView.section.security.resetkey.warning=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0438? \u0415\u0441\u043b\u0438 \u0442\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0442\u043e \u0432\u0441\u044f \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430 [...]
+ConfigView.section.security.unlockkey=\u041e\u0442\u043a\u0440\u044b\u0442\u043e \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438
 ConfigView.section.security.unlockkey.button=\u0420\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-ConfigView.section.security.publickey=\u041e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043b\u044e\u0447
-ConfigView.section.security.publickey.undef=\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d
-ConfigView.section.security.resetkey.error.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
-ConfigView.section.security.resetkey.error=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0438
-ConfigView.section.security.unlockkey.error=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 \u2014 \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c
-ConfigView.copy.to.clipboard.tooltip=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0431\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
+ConfigView.section.security.publickey=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447
+ConfigView.section.security.publickey.undef=\u0415\u0449\u0435 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e
+ConfigView.section.security.resetkey.error.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+ConfigView.section.security.resetkey.error=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0438
+ConfigView.section.security.unlockkey.error=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 - \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439
+ConfigView.copy.to.clipboard.tooltip=\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
 Views.plugins.azbuddy.title=\u0414\u0440\u0443\u0437\u044c\u044f
-Browser.popup.error.no.access=\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.\n\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0434\u043d\u0435\u0435.\n
-ConfigView.label.queue.stoponcebandwidthmet=\u041d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u043f\u0440\u0435\u0434\u0435\u043b \u0440\u0430\u0437\u0434\u0430\u0447\u0438/\u043f\u0440\u0438\u0451\u043c\u0430
-ConfigView.section.style.forceMozilla=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0436\u0435\u0442\u044b Mozilla [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f xulrunner \u0438\u043b\u0438 firefox 3; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
-ConfigView.section.style.xulRunnerPath=\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e XulRunner / Firefox \u0432\u0440\u0443\u0447\u043d\u0443\u044e [\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f FF3; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a]
+Browser.popup.error.no.access=\u0412\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.\n\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u044b\u0442\u0430\u0439\u0442\u0435\u0441\u044c \u04 [...]
+ConfigView.label.queue.stoponcebandwidthmet=\u041d\u0435 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u0435\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b, \u0435\u0441\u043b\u0438 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447/\u0437\u0430\u043a\u0430\u0447\u0435\u043a \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442
+ConfigView.section.style.forceMozilla=\u0417\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c Vuze \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Mozilla \u0434\u043b\u044f \u0432\u0438\u0434\u0436\u0435\u0442\u043e\u0432 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f xulrunner \u0438\u043b\u0438 firefox 3; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a)
+ConfigView.section.style.xulRunnerPath=- \u0423\u043a\u0430\u0437\u0430\u0442\u044c XulRunner / Firefox \u043f\u0443\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f FireFox3; \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
 azbuddy.name=\u0414\u0440\u0443\u0437\u044c\u044f
-azbuddy.enabled=\u0412\u043a\u043b\u044e\u0447\u0451\u043d
-azbuddy.disabled=\u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u043a\u043b\u044e\u0447\u0451\u043d, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043c\u043e\u0434\u0443\u043b\u044f.
-azbuddy.nickname=\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c
+azbuddy.enabled=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+azbuddy.disabled=\u041f\u043b\u0430\u0433\u0438\u043d \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d, \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e.
+azbuddy.nickname=\u0412\u0430\u0448 \u043d\u0438\u043a
 azbuddy.msglog.title=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0434\u0440\u0443\u0433\u0435
-azbuddy.addtorrent.title=\u041f\u0440\u0438\u043d\u044f\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443?
-azbuddy.addtorrent.msg=\u0412\u0430\u0448 \u0434\u0440\u0443\u0433 \u00ab%1\u00bb \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0430\u043c \u00ab%2\u00bb.\n\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443?
-azbuddy.contextmenu=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443
+azbuddy.addtorrent.title=\u0421\u043e\u0433\u043b\u0430\u0441\u0438\u0442\u044c\u0441\u044f \u0441 \u0437\u0430\u043a\u0430\u0447\u043a\u043e\u0439?
+azbuddy.addtorrent.msg=\u0414\u0440\u0443\u0433 '%1' \u043f\u043e\u0441\u043b\u0430\u043b \u0412\u0430\u043c '%2'.\n\u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u043a\u0430\u0447\u043a\u0443?
+azbuddy.contextmenu=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443
 azbuddy.ui.mykey=\u041c\u043e\u0439 \u043a\u043b\u044e\u0447:
 azbuddy.ui.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
-azbuddy.ui.new_buddy=\u041d\u043e\u0432\u044b\u0439 \u043a\u043b\u044e\u0447 \u0434\u0440\u0443\u0433\u0430:
+azbuddy.ui.new_buddy=\u041a\u043b\u044e\u0447 \u043d\u043e\u0432\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u0430:
 azbuddy.ui.table.name=\u0418\u043c\u044f
-azbuddy.ui.table.online=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d
+azbuddy.ui.table.online=\u041e\u043d-\u043b\u0430\u0439\u043d
 azbuddy.ui.table.last_msg=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
-azbuddy.ui.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-azbuddy.ui.menu.copypk=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439 \u043a\u043b\u044e\u0447
-azbuddy.ui.menu.send=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
-azbuddy.ui.menu.send_msg=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0443 \u0438\u043b\u0438 \u0434\u0440\u0443\u0437\u044c\u044f\u043c
-azbuddy.ui.menu.ping=\u041f\u0438\u043d\u0433
-azbuddy.ui.menu.ygm=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c YGM
-azbuddy.ui.menu.enc=\u0417\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430
-azbuddy.ui.menu.dec=\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430
-azbuddy.ui.menu.sign=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430
-azbuddy.ui.menu.verify=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u0443\u0444\u0435\u0440\u0430 \u043e\u0431\u043c\u0435\u043d\u0430
-azbuddy.ui.table.lastseen=\u0411\u044b\u043b \u0432 \u0441\u0435\u0442\u0438
-Button.retry=&\u041f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u043d\u043e\u0432\u0430
+azbuddy.ui.menu.remove=\u0423\u0431\u0440\u0430\u0442\u044c
+azbuddy.ui.menu.copypk=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043a\u043b\u044e\u0447
+azbuddy.ui.menu.send=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
+azbuddy.ui.menu.send_msg=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u0440\u0443\u0437\u044c\u044f\u043c
+azbuddy.ui.menu.ping=\u041f\u0438\u043d\u0433\u043e\u0432\u0430\u0442\u044c
+azbuddy.ui.menu.ygm=\u041f\u043e\u0441\u043b\u0430\u0442\u044c YGM
+azbuddy.ui.menu.enc=\u0417\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+azbuddy.ui.menu.dec=\u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c \u0411\u0443\u0444\u0435\u0440 \u043e\u0431\u043c\u0435\u043d\u0430
+azbuddy.ui.menu.sign=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+azbuddy.ui.menu.verify=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+azbuddy.ui.table.lastseen=\u0411\u044b\u043b \u0432 \u043f\u043e\u0441\u043b. \u0440\u0430\u0437
+Button.retry=&\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c
 Button.ignore=&\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-DHTView.general.skew=\u0410\u0441\u0441\u0438\u043c\u0435\u0442\u0440\u0438\u044f:
-azbuddy.ui.table.msg_in=\u0412\u0445\u043e\u0434\u044f\u0449\u0435\u0435
-azbuddy.ui.table.msg_out=\u0418\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435
-azbuddy.downspeed=\u041a\u0411/\u0441 \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0430 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-azbuddy.ui.table.con=\u0421\u043e\u0435\u0434
-security.crypto.badpw=\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u0432\u0435\u0440\u0435\u043d
-ConfigView.section.security.backupkeys=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438 \u0432 \u0444\u0430\u0439\u043b
-ConfigView.section.security.backupkeys.button=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+DHTView.general.skew=\u041e\u0442\u0441\u0442\u0430\u0432\u0430\u043d\u0438\u0435:
+azbuddy.ui.table.msg_in=\u0412\u0445\u043e\u0434.\u0441\u043e\u043e\u0431\u0449
+azbuddy.ui.table.msg_out=\u0418\u0441\u0445\u043e\u0434.\u0441\u043e\u043e\u0431\u0449
+v3.MainWindow.menu.view.footer=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435
+azbuddy.downspeed=KB/s \u043c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0437\u0435\u0439 [0: \u0431\u0435\u0437 \u043b\u0438\u043c\u0438\u0442\u0430]
+azbuddy.ui.table.con=\u0421\u0442\u043e\u043b\u0431\u0435\u0446
+security.crypto.badpw=\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u0432\u0435\u0440\u043d\u044b\u0439
+ConfigView.section.security.backupkeys=\u0420\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438 \u0432 \u0444\u0430\u0439\u043b\u0435
+ConfigView.section.security.backupkeys.button=BackUp
 ConfigView.section.security.restorekeys=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u044e\u0447\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430
 ConfigView.section.security.restorekeys.button=\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
-ConfigView.section.security.op.error.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
-ConfigView.section.security.op.error=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e:\n    %1
-ConfigView.section.security.restart.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
-ConfigView.section.security.restart.msg=\u0414\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430.
-ConfigView.section.security.system.managed=\u0417\u0430\u0449\u0438\u0442\u0430 \u043a\u043b\u044e\u0447\u0435\u0439 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u041e\u0421
+ConfigView.section.security.op.error.title=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+ConfigView.section.security.op.error=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e:\n    %1
+ConfigView.section.security.restart.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+ConfigView.section.security.restart.msg=Vuze \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.
+ConfigView.section.security.system.managed=\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u0421\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0437\u0430\u0449\u0438\u0442\u0430 \u043a\u043b\u044e\u0447\u043e\u043c
 azbuddy.ui.table.msg_queued=\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-azbuddy.ui.menu.chat=\u0411\u0435\u0441\u0435\u0434\u0430
+azbuddy.ui.menu.chat=\u0427\u0430\u0442
 azbuddy.chat.title=\u0427\u0430\u0442 Vuze
-azbuddy.chat.says=%1 \u0441\u043a\u0430\u0437\u0430\u043b(\u0430):
+azbuddy.chat.says=%1 \u0433\u043e\u0432\u043e\u0440\u0438\u0442:
 Button.bar.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
 Button.bar.hide=\u0421\u043a\u0440\u044b\u0442\u044c
-Button.bar.share=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f
-Button.bar.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
-Button.bar.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
-Button.bar.edit.cancel=\u0413\u043e\u0442\u043e\u0432\u043e
-v3.MainWindow.menu.view.pluginbar=\u041f\u0430\u043d\u0435\u043b\u044c \u043c\u043e\u0434\u0443\u043b\u0435\u0439
-MainWindow.dialog.select.vuze.file=\u0412\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u0430 Vuze
-MainWindow.menu.file.open.vuze=\u0424\u0430\u0439\u043b Vuze...
-metasearch.addtemplate.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d?
-metasearch.addtemplate.desc=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u00ab%1\u00bb?
-v3.share.private.title=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c
-v3.share.private.text=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u043c.\n\n\u041d\u0435\u043b\u044c\u0437\u044f \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u044b\u043c\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438.
-metasearch.addtemplate.dup.title=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d
-metasearch.addtemplate.dup.desc=\u041f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u00ab%1\u00bb \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-metasearch.export.select.template.file=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d
-metasearch.import.select.template.file=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d
-dialog.uiswitch.title=\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze UI
-dialog.uiswitch.text=\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze UI.\n\n\u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a Vuze.
-dialog.uiswitch.button=\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze UI
-azbuddy.tracker.enabled=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u00ab\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443\u00bb \u0434\u0440\u0443\u0437\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043e\u0431\u043c\u0435\u043d \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441 \u043d\u0438\u043c\u0438
-azbuddy.protocolspeed=\u041a\u0411/\u0441 \u043c\u0430\u043a\u0441. \u0442\u0440\u0430\u0444\u0438\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0434\u0440\u0443\u0437\u0435\u0439
+Button.bar.share=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f (\u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0442\u044c)
+Button.bar.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0414\u0440\u0443\u0437\u0435\u0439
+Button.bar.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+Button.bar.edit.cancel=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+v3.MainWindow.menu.view.pluginbar=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+MainWindow.dialog.select.vuze.file=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b Vuze
+MainWindow.menu.file.open.vuze=Vuze \u0444\u0430\u0439\u043b...
+metasearch.addtemplate.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0438\u0441\u043a\u0430?
+metasearch.addtemplate.desc=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0443\u044e \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c %1?
+v3.share.private.title=\u0414\u0435\u043b\u0438\u043c\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c
+v3.share.private.text=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043f\u043e\u043c\u0435\u0447\u0435\u043d \u043a\u0430\u043a \u0427\u0430\u0441\u0442\u043d\u044b\u0439 \u0422\u043e\u0440\u0440\u0435\u043d\u0442.\n\n\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0447\u0430\u0441\u0442\u043d\u044b\u043c\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438.
+metasearch.addtemplate.dup.title=\u0414\u0443\u0431\u043b\u0438\u043a\u0430\u0442 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438
+metasearch.addtemplate.dup.desc=\u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0430\u044f \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0430 %1 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430
+metasearch.export.select.template.file=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443
+metasearch.import.select.template.file=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443
+dialog.uiswitch.title=\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze
+dialog.uiswitch.text=\u0412\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.\n\n\u0414\u043b\u044f Vuze \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442.
+dialog.uiswitch.button=\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Vuze
+azbuddy.tracker.enabled=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c "\u0414\u0440\u0443\u0436\u0435\u0441\u043a\u043e\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435" \u0434\u043b\u044f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0441 \u0434\u0440\u0443\u0437\u0435\u0439
+azbuddy.protocolspeed=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043f\u043b\u0430\u0433\u0438\u043d\u0430 "\u0434\u0440\u0443\u0437\u044c\u044f" [\u043a\u0411/\u0441]
 v3.MainWindow.button.download=\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c
-v3.MainWindow.button.run=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b
+v3.MainWindow.button.run=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b
 v3.activity.header.downloads=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438
 v3.activity.header.vuze.news=\u041d\u043e\u0432\u043e\u0441\u0442\u0438 Vuze
-message.taking.too.long=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0435\u043c \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c\n\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0435\u0451, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u00abESC\u00bb
-message.status.success=\u0423\u0441\u043f\u0435\u0448\u043d\u043e
-azbuddy.tracker.bbb.status.title=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0434\u0440\u0443\u0437\u0435\u0439
-azbuddy.tracker.bbb.status.title.tooltip=\u0414\u0432\u043e\u0439\u043d\u043e\u0439 \u0449\u0435\u043b\u0447\u043e\u043a \u043e\u0442\u043a\u0440\u043e\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435
-azbuddy.tracker.bbb.status.idle=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-azbuddy.tracker.bbb.status.nli=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f
-azbuddy.tracker.bbb.status.in=\u041c\u0435\u043d\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442
-azbuddy.tracker.bbb.status.out=\u0412 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0440\u0443\u0437\u044c\u044f
+message.taking.too.long=\u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u0434\u043b\u0438\u0442\u0441\u044f \u0434\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c\n\u041d\u0430\u0436\u043c\u0438\u0442\u0435 ESC \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e
+message.status.success=\u0423\u0434\u0430\u0447\u043d\u043e
+azbuddy.tracker.bbb.status.title=\u0414\u0440\u0443\u0436\u0435\u0441\u043a\u043e\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435
+azbuddy.tracker.bbb.status.title.tooltip=\u0414\u0432\u043e\u0439\u043d\u043e\u0439 \u043a\u043b\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439
+azbuddy.tracker.bbb.status.idle=\u0411\u0435\u0437 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f
+azbuddy.tracker.bbb.status.nli=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043b\u043e\u0433\u0438\u043d
+azbuddy.tracker.bbb.status.in=\u042f \u0443\u0441\u043a\u043e\u0440\u044f\u044e\u0441\u044c
+azbuddy.tracker.bbb.status.out=\u0421\u0435\u0439\u0447\u0430\u0441 \u0443\u0441\u043a\u043e\u0440\u044f\u044e \u0434\u0440\u0443\u0437\u0435\u0439
 v3.MainWindow.search.go.tooltip=\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a
-v3.MainWindow.search.last.tooltip=\u041d\u0430\u0437\u0430\u0434 \u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u043f\u043e\u0438\u0441\u043a\u0430
-metasearch.addtemplate.done.title=\u0428\u0430\u0431\u043b\u043e\u043d \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d
-metasearch.addtemplate.done.desc=\u0428\u0430\u0431\u043b\u043e\u043d \u00ab%1\u00bb \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d.\n\u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435.
-ConfigView.section.security.nopw=\u041f\u0430\u0440\u043e\u043b\u044c \u043d\u0435 \u0431\u044b\u043b \u0443\u043a\u0430\u0437\u0430\u043d
-ConfigView.section.security.nopw_v=\u041f\u0430\u0440\u043e\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d, \u0432\u043e\u0439\u0434\u0438\u0442\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 Vuze
-fileplugininstall.install.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c?
-fileplugininstall.install.desc=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c \u00ab%1\u00bb \u0432\u0435\u0440\u0441\u0438\u0438 %2?
-fileplugininstall.duplicate.title=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c
-fileplugininstall.duplicate.desc=\u041c\u043e\u0434\u0443\u043b\u044c \u00ab%1\u00bb \u0432\u0435\u0440\u0441\u0438\u0438 %2 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
-azbuddy.online_status=\u0421\u0442\u0430\u0442\u0443\u0441
-azbuddy.os_online=\u0414\u043e\u0441\u0442\u0443\u043f\u0435\u043d
-azbuddy.os_away=\u041e\u0442\u043e\u0448\u0451\u043b
-azbuddy.os_not_avail=\u041d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
+v3.MainWindow.search.last.tooltip=\u0412\u044b\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u043f\u043e\u0438\u0441\u043a\u0430
+metasearch.addtemplate.done.title=\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430
+metasearch.addtemplate.done.desc=\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0430 %1 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e.\n\u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u043e\u0438\u0441\u043a\u0435!
+ConfigView.section.security.nopw=\u041d\u0435 \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u0430\u0440\u043e\u043b\u044c
+ConfigView.section.security.nopw_v=\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u0430\u0440\u043e\u043b\u0435\u0439, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043f\u0438\u0448\u0438\u0442\u0435\u0441\u044c \u0432 Vuze
+fileplugininstall.install.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d?
+fileplugininstall.install.desc=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d '%1', \u0432\u0435\u0440\u0441\u0438\u044f %2?
+fileplugininstall.duplicate.title=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430
+fileplugininstall.duplicate.desc=\u041f\u043b\u0430\u0433\u0438\u043d '%1', \u0432\u0435\u0440\u0441\u0438\u044f %2 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
+azbuddy.online_status=\u041e\u043d\u043b\u0430\u0439\u043d-\u0441\u0442\u0430\u0442\u0443\u0441
+azbuddy.os_online=\u0412 \u0441\u0435\u0442\u0438
+azbuddy.os_away=\u041e\u0442\u043e\u0448\u0435\u043b
+azbuddy.os_not_avail=\u041d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d
 azbuddy.os_busy=\u0417\u0430\u043d\u044f\u0442
 azbuddy.os_offline=\u041d\u0435 \u0432 \u0441\u0435\u0442\u0438
-azbuddy.ui.menu.disconnect=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f
-azbuddy.enable_chat_notif=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u0432 \u0431\u0435\u0441\u0435\u0434\u0430\u0445
-progress.window.msg.progress=\u041f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f
-ConfigView.section.connection.advanced.read_select=\u041c\u0430\u043a\u0441. \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u0430 (\u043c\u0441, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
-ConfigView.section.connection.advanced.read_select_min=\u041c\u0438\u043d. \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u0430 (\u043c\u0441, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
-ConfigView.section.connection.advanced.write_select=\u041c\u0430\u043a\u0441. \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 (\u043c\u0441, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
-ConfigView.section.connection.advanced.write_select_min=\u041c\u0438\u043d. \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 (\u043c\u0441, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
-DetailedListView.title=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
-ConfigView.section.connection.network.max.outstanding.connect.attempts=\u041c\u0430\u043a\u0441. \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
-plugins.init.force_enabled=\u041c\u043e\u0434\u0443\u043b\u044c \u00ab%1\u00bb \u0431\u044b\u043b \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b Vuze.
-ConfigView.section.connection.prefer.udp=\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e UDP
-subscript.add.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443?
-subscript.add.desc=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u00ab%1\u00bb?
-subscript.add.dup.title=\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430
-subscript.add.dup.desc=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u00ab%1\u00bb \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430.
+azbuddy.ui.menu.disconnect=\u0420\u0430\u0441\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c
+azbuddy.enable_chat_notif=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u0430
+progress.window.msg.progress=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435, \u043f\u043e\u043a\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430.
+ConfigView.section.connection.advanced.read_select=\u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u0431\u043e\u0440\u0430 \u0447\u0442\u0435\u043d\u0438\u044f [\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b] (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
+ConfigView.section.connection.advanced.read_select_min=\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0447\u0442\u0435\u043d\u0438\u044f [\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b] (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
+ConfigView.section.connection.advanced.write_select=\u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u0432\u044b\u0431\u043e\u0440\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 [\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b] (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
+ConfigView.section.connection.advanced.write_select_min=\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0437\u0430\u043f\u0438\u0441\u0438 [\u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u044b] (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e %1)
+DetailedListView.title=\u0414\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+ConfigView.section.connection.network.max.outstanding.connect.attempts=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438
+plugins.init.force_enabled=Vuze \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b, \u0447\u0442\u043e \u043f\u043b\u0430\u0433\u0438\u043d "%1" \u0431\u044b\u043b \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d - \u043e\u043d \u0431\u044b\u043b \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c Vuze \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u [...]
+ConfigView.section.connection.prefer.udp=\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c UDP-\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
+subscript.add.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443?
+subscript.add.desc=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435  \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443  '%1'?
+subscript.add.dup.title=\u0421\u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
+subscript.add.dup.desc=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 '%1' \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430.
 subscript.add.upgrade.title=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443?
-subscript.add.upgrade.desc=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 \u00ab%1\u00bb?
-subscript.add.upgradeto.desc=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f %1 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u00ab%2\u00bb.\n\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c?
-azsubs.contextmenu.addassoc=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u043a \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0435
-azsubs.contextmenu.lookupassoc=\u041d\u0430\u0439\u0442\u0438 \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-iconBar.start=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-iconBar.stop=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+subscript.add.upgrade.desc=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 '%1'?
+subscript.add.upgradeto.desc=\u0412\u0435\u0440\u0441\u0438\u044f %1 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 '%2' \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430.\n\u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c?
+azsubs.contextmenu.addassoc=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044e \u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u043e\u0439
+azsubs.contextmenu.lookupassoc=\u0418\u0441\u043a\u0430\u0442\u044c \u0430\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u043e\u0439
+iconBar.start=\u0421\u0442\u0430\u0440\u0442
+iconBar.stop=\u0421\u0442\u043e\u043f
 iconBar.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-iconBar.up=\u0412\u0432\u0435\u0440\u0445
-iconBar.down=\u0412\u043d\u0438\u0437
-iconBar.run=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
-iconBar.editcolumns=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432
-iconBar.top=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u0430\u043c\u044b\u0439 \u0432\u0435\u0440\u0445
-iconBar.bottom=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u0430\u043c\u044b\u0439 \u043d\u0438\u0437
-iconBar.queue=
+iconBar.up=\u0412\u044b\u0448\u0435
+iconBar.down=\u041d\u0438\u0436\u0435
+iconBar.run=\u041e\u0442\u043a\u0440\u044b\u0442\u044c
+iconBar.editcolumns=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u0430
+iconBar.top=\u0412\u0435\u0440\u0445
+iconBar.bottom=\u041d\u0438\u0437
+iconBar.queue=\u0421\u0442\u0430\u0440\u0442
 iconBar.open=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442
 iconBar.share=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f
-iconBar.share.tooltip=\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c
-iconBar.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-iconBar.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
-iconBar.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438
+iconBar.share.tooltip=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c
+iconBar.details=\u0414\u0435\u0442\u0430\u043b\u0438
+iconBar.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
+iconBar.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435
 iconBar.queue.tooltip=B \u043e\u0447\u0435\u0440\u0435\u0434\u044c
-v3.MainWindow.menu.view.sidebar=\u0411\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c
+v3.MainWindow.menu.view.sidebar=\u0411\u043e\u043a\u043e\u0432\u0430\u044f \u041f\u0430\u043d\u0435\u043b\u044c
 v3.MainWindow.menu.view.actionbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439
-v3.MainWindow.menu.view.toolbars=\u041f\u0430\u043d\u0435\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
-ump.install=\u0418\u0434\u0451\u0442 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435:\n\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u044d\u0442\u043e\u0433\u043e \u0432\u0438\u0434\u0435\u043e.
+v3.MainWindow.menu.view.toolbars=\u041f\u0430\u043d\u0435\u043b\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
+ump.install=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435:\n\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0430\u0434\u0434-\u043e\u043d \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u044d\u0442\u043e\ [...]
 subscriptions.listwindow.title=\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a
-subscriptions.listwindow.autochecktext=Vuze \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0432 \u0432\u0430\u0448\u0435\u0439 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0435. \u0425\u043e\u0442\u0438\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u043e\u0439 \u0432\u043e\u0437\u04 [...]
-subscriptions.listwindow.loadingtext=\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a, \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u043d\u0430 \u00ab%1\u00bb
-subscriptions.listwindow.failed=\u041f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e
+subscriptions.listwindow.autochecktext=Vuze \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0443 \u0432 \u0412\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435. \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u [...]
+subscriptions.listwindow.loadingtext=\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0445\u0441\u044f \u043a %1
+subscriptions.listwindow.failed=\u041d\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a
 subscriptions.listwindow.popularity=\u041f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c
-subscriptions.listwindow.popularity.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e
+subscriptions.listwindow.popularity.unknown=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439
 subscriptions.listwindow.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
 subscriptions.listwindow.subscribe=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
-TableColumn.header.azsubs.ui.column.subs=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
+TableColumn.header.azsubs.ui.column.subs=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430
 subscriptions.listwindow.popularity.reading=\u0427\u0442\u0435\u043d\u0438\u0435...
-PluginDeprecation.log.start=\u042d\u0442\u043e \u043e\u043a\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043c\u043e\u0434\u0443\u043b\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\ [...]
-PluginDeprecation.log.details=---------\n\u0418\u0414\u0415\u041d\u0422\u0418\u0424\u0418\u041a\u0410\u0422\u041e\u0420: %1\n\u041a\u041e\u041d\u0422\u0415\u041a\u0421\u0422: %2\n\n*** \u041d\u0410\u0427\u0410\u041b\u041e \u041e\u0422\u041b\u0410\u0414\u041a\u0418 ***\n%3*** \u041a\u041e\u041d\u0415\u0426 \u041e\u0422\u041b\u0410\u0414\u041a\u0418 ***\n\n
-PluginDeprecation.view=\u041e\u0442\u043b\u0430\u0434\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u044f
-PluginDeprecation.alert=\u041c\u043e\u0434\u0443\u043b\u044c \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u0431\u0440\u0430\u043d \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u2014 \u043f\u043e\u0434\u0440 [...]
-TableColumn.header.Thumbnail=\u0417\u043d\u0430\u0447\u043e\u043a
-TableColumn.header.Thumbnail.info=\u0417\u043d\u0430\u0447\u043e\u043a \u0441 \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 (\u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 Vuze) \u0438\u043b\u0438 \u0437\u043d\u0430\u0447\u043e\u043a \u0444\u0430\u0439\u043b\u0430 (\u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e)
-v3.MainWindow.menu.getting_started=&\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442
-MainWindow.menu.community=\u0421\u043e\u043e&\u0431\u0449\u0435\u0441\u0442\u0432\u043e
-MainWindow.menu.help.faq=&\u0427\u0430\u0441\u0442\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b (FAQ)
-MainWindow.menu.community.wiki=&\u0412\u0438\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430
-MainWindow.menu.community.forums=&\u0424\u043e\u0440\u0443\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430
-MainWindow.menu.community.blog=&\u0411\u043b\u043e\u0433 Vuze
-MainWindow.menu.help.support=&\u0421\u043f\u0440\u0430\u0432\u043a\u0430 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430
-externalLogin.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f
-externalLogin.explanation=\u0428\u0430\u0431\u043b\u043e\u043d \u00ab%1\u00bb \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e \u043e\u043a\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u [...]
-externalLogin.explanation.capture=\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u00ab%1\u00bb \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u00ab\u0413\u043e\u0442\u043e\u0432\u043e\u00bb.
-Button.done=\u0413\u043e\u0442\u043e\u0432\u043e
-GeneralView.torrent_created_on_and_by=%1 ( %2 )
+PluginDeprecation.log.start=\u042d\u0442\u043e \u043e\u043a\u043d\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u0431\u0440\u0430\u043d\u044b \u0432 \u0431\u0443\u0434 [...]
+PluginDeprecation.log.details=---------\n\u0418\u0414\u0415\u041d\u0422\u0418\u0424\u0418\u041a\u0410\u0422\u041e\u0420: %1\n\u041a\u041e\u041d\u0422\u0415\u041a\u0421\u0422: %2\n\n*** \u041d\u0410\u0427\u0410\u041b\u041e \u0422\u0420\u0410\u0421\u0421\u0418\u0420\u041e\u0412\u041a\u0418 ***\n%3*** \u041a\u041e\u041d\u0415\u0426 \u0422\u0420\u0410\u0421\u0421\u0418\u0420\u041e\u0412\u041a\u0418 ***\n\n
+PluginDeprecation.view=\u041e\u0448\u0438\u0431\u043a\u0438 \u041f\u043b\u0430\u0433\u0438\u043d\u043e\u0432
+PluginDeprecation.alert=\u041f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u0431\u0440\u0430\u043d\u044b \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c - \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0442\u043a\u0440\u043e\u0439\u04 [...]
+TableColumn.header.Thumbnail=\u0418\u043a\u043e\u043d\u043a\u0430
+TableColumn.header.Thumbnail.info=\u041a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0433\u0430\u043b\u0435\u0440\u0435\u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 Vuze; \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043e\u0431\u04 [...]
+v3.MainWindow.menu.getting_started=&\u0414\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445
+MainWindow.menu.community=&\u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e
+MainWindow.menu.community.wiki=Wiki \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430
+MainWindow.menu.community.forums=\u0424\u043e\u0440\u0443\u043c\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430
+MainWindow.menu.community.blog=Vuze &\u0411\u043b\u043e\u0433
+MainWindow.menu.help.support=&\u041f\u043e\u043c\u043e\u0449\u044c \u0438 \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430
+externalLogin.title=\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+externalLogin.explanation=\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0430 "%1" \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u0430\u0448\u0435\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (login). \u0421\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u044d\u0442\u043e \u043e\u043a\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043a\u0440\u043e\u0435\u0442\u04 [...]
+externalLogin.explanation.capture=\u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f (login), \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442\u0435, \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 "\u0421\u0434\u0435\u0 [...]
+Button.done=\u0421\u0434\u0435\u043b\u0430\u043d\u043e
+GeneralView.torrent_created_on_and_by=%1 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e: %2
 Button.continue=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c
 Button.preview=\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440
-Subscription.menu.forcecheck=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
-Subscription.menu.clearall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u0440\u043e\u0447\u0442\u0451\u043d\u043d\u044b\u043c\u0438
-Subscription.menu.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-sidebar.Library=\u041c\u043e\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430
-sidebar.LibraryDL=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438
-sidebar.LibraryCD=\u0413\u043e\u0442\u043e\u0432\u043e
+Subscription.menu.forcecheck=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441
+Subscription.menu.clearall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u0430\u043a '\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e'
+Subscription.menu.remove=\u0421\u0442\u0435\u0440\u0435\u0442\u044c
+sidebar.Library=\u041c\u043e\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+sidebar.LibraryDL=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f
+sidebar.LibraryCD=\u0417\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e
 authenticator.location=\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435
-authenticator.details=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
-v3.MainWindow.menu.showActionBarText=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u0438
-subscript.import.fail.title=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+authenticator.details=\u0414\u0435\u0442\u0430\u043b\u0438
+v3.MainWindow.menu.showActionBarText=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442
+subscript.import.fail.title=\u0418\u043c\u043f\u043e\u0440\u0442 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f
 subscript.import.fail.desc=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438: %1
-Subscription.menu.export=\u042d\u0441\u043f\u043e\u0440\u0442
+Subscription.menu.export=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
 subscript.export.select.template.file=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
-Button.remove=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
-Button.send=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
+Button.remove=\u0423\u0431\u0440\u0430\u0442\u044c
+Button.send=\u041f\u043e\u0441\u043b\u0430\u0442\u044c
 Button.back=\u041d\u0430\u0437\u0430\u0434
-sidebar.LibraryUnopened=\u041d\u043e\u0432\u044b\u0435
+sidebar.LibraryUnopened=\u041d\u0435\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e
 TableColumn.header.unopened=\u041d\u043e\u0432\u044b\u0439
-Unopened.bigView.header=\u041d\u043e\u0432\u044b\u0435
-Subscription.menu.deleteall=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
-Subscription.menu.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0432 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+Unopened.bigView.header=\u041d\u043e\u0432\u044b\u0439
+Subscription.menu.deleteall=\u0421\u0442\u0435\u0440\u0435\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
+Subscription.menu.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f
 ConfigView.section.Subscriptions=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-subscriptions.config.maxresults=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
-v3.activity.button.readall=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0451 \u043f\u0440\u043e\u0447\u0442\u0451\u043d\u043d\u044b\u043c
+subscriptions.config.maxresults=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0445 \u0437\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443 [0: \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+v3.activity.button.readall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u043a\u0430\u043a \u041f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0435
 TableColumn.header.activityNew=\u041d\u043e\u0432\u044b\u0439
 TableColumn.header.activityType=\u0422\u0438\u043f
 TableColumn.header.activityText=\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435
 TableColumn.header.activityDate=\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f
 TableColumn.header.activityActions=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f
-Subscription.menu.resetauth=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438
-Search.menu.engines=\u0428\u0430\u0431\u043b\u043e\u043d\u044b
+Subscription.menu.resetauth=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438
+Search.menu.engines=\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0438
 Wizard.Subscription.title=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
-Wizard.Subscription.optin.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-#what you've watched? Discover more with a single click...
+Wizard.Subscription.optin.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
 Wizard.Subscription.subscribe.title=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
 Wizard.Subscription.create.title=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
-Button.search=\u041d\u0430\u0439\u0442\u0438
+Button.search=\u0418\u0441\u043a\u0430\u0442\u044c
 Button.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
 Button.add=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
 Button.createNewSubscription=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
 Button.availableSubscriptions=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-Wizard.Subscription.optin.description=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 Vuze \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0432 \u0432\u0430\u0448\u0435\u0439 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0435 \u0438 \u0443\u0432\u0435 [...]
-Wizard.Subscription.create.search=\u041d\u0430\u0439\u0442\u0438
-Wizard.Subscription.search.subtitle1=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438:
-Wizard.Subscription.search.subtitle2=\u0427\u0442\u043e \u043c\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c?
-Wizard.Subscription.search.subtitle2.sub1=\u0424\u0438\u043b\u044c\u043c\u044b \u0432 HD, \u0442\u0435\u043b\u0435\u0448\u043e\u0443, \u0444\u0438\u043b\u044c\u043c\u044b, \u0442\u0440\u0435\u0439\u043b\u0435\u0440\u044b \u043d\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0435 Vuze
-Wizard.Subscription.search.subtitle2.sub2=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0438\u0437 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430
-Wizard.Subscription.search.subtitle3=\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0432\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u043f\u043e\u044f\u0432\u0438\u [...]
-Wizard.Subscription.rss.subtitle1=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0438\u043b\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u044e\u0434\u0430 URL:
-Wizard.Subscription.rss.subtitle2=\u041c\u043d\u043e\u0433\u0438\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u0435\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 RSS.  \u041d\u0430\u0439\u0434\u0438\u0442\u0435 URL \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043d\u0430 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0435 \u0440\u0430 [...]
-Wizard.Subscription.rss.subtitle3=\u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0432 \u0441\u043e\u0445\u0440\u0430\u043d\u0451\u043d\u043d\u043e\u0439 \u043b\u0435\u043d\u0442\u0435 RSS \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435.
-Wizard.Subscription.subscribe.library=\u041a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0435
+Wizard.Subscription.optin.description=\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430, Vuze \u043f\u043e\u043a\u0430\u0436\u0435\u0442 \u0412\u0430\u0448\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438, \u043e\u0442\u043d\u043e\u0441\u044f\u0449\u0438\u0435\u0441\u044f \u043a \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0443 \u0438\u0437 \u0412\u0430\u0448\u0435\u0439 \u0411\u0438\u0431\u043b\u0438\u04 [...]
+Wizard.Subscription.create.rss=\u041b\u0435\u043d\u0442\u0430 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 RSS
+Wizard.Subscription.create.search=\u041f\u043e\u0438\u0441\u043a
+Wizard.Subscription.search.subtitle1=\u041d\u0430\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u0441\u043a\u043e\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0412\u0430\u0448\u0435\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438:
+Wizard.Subscription.search.subtitle2=\u0427\u0442\u043e \u044f \u043c\u043e\u0433\u0443 \u043f\u043e\u0438\u0441\u043a\u0430\u0442\u044c?
+Wizard.Subscription.search.subtitle2.sub1=HD-\u0424\u0438\u043b\u044c\u043c\u044b, \u0422\u0412-\u0428\u043e\u0443, \u0424\u0438\u043b\u044c\u043c\u044b, \u0420\u043e\u043b\u0438\u043a\u0438 \u0432 \u0421\u0435\u0442\u0438 Vuze
+Wizard.Subscription.search.subtitle2.sub2=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0441\u043e \u0432\u0441\u0435\u0433\u043e \u0412\u0435\u0431\u0430
+Wizard.Subscription.search.subtitle3=\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0412\u0430\u0448\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430, \u0412\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0441\u0432\u0435\u0436\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 , \u0435\u0441\u043b\u [...]
+Wizard.Subscription.rss.subtitle1=\u041d\u0430\u0431\u0435\u0440\u0438\u0442\u0435 \u0438\u043b\u0438 \u0432\u0441\u0442\u0430\u0432\u044c\u0442\u0435 URL \u043d\u0438\u0436\u0435:
+Wizard.Subscription.rss.subtitle2=\u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043b\u0435\u043d\u0442\u0443 RSS \u043d\u0430 \u0438\u0445 \u043a\u043e\u043d\u0442\u0435\u043d\u0442. \u041d\u0430\u0439\u0434\u0438\u0442\u0435 URL \u043d\u0430 \u0412\u0435\u0431-\u0441\u0430\u0439\u0442 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0440\u0430 [...]
+Wizard.Subscription.rss.subtitle3=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0432, \u0412\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0432\u0435\u0436\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c [...]
+Wizard.Subscription.subscribe.library=\u041a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 \u0412\u0430\u0448\u0435\u0439 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435
 Wizard.Subscription.subscribe.subscriptions=\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-Wizard.Subscription.subscribe.library.empty=\u041d\u0435 \u043d\u0430\u0448\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a?\n \n\u0418\u0449\u0438\u0442\u0435 \u044f\u0440\u043a\u043e-\u043e\u0440\u0430\u043d\u0436\u0435\u0432\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u043f\u043e\u0440\u0442\u0430\u043b\u0435 Vuze HD.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435...</A>
-message.confirm.delete.title=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435
-message.confirm.delete.text=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u00ab%1\u00bb?
+Wizard.Subscription.subscribe.library.empty=\u041d\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a?\n \n\u041f\u043e\u0438\u0449\u0438\u0442\u0435 \u0441\u0432\u0435\u0442\u043b\u043e-\u043e\u0440\u0430\u043d\u0436\u0435\u0432\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0432 Vuze HD Network.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u041f\u043e\u043 [...]
+message.confirm.delete.title=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0441\u0442\u0438\u0440\u0430\u043d\u0438\u0435
+message.confirm.delete.text=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u0442\u0435\u0440\u0435\u0442\u044c '%1'?
 Subscription.menu.properties=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430
-props.window.title=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u00ab%1\u00bb
-subs.prop.is_auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
+props.window.title=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0442 '%1'
+subs.prop.is_auto=\u0410\u0432\u0442\u043e-\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
 subs.prop.last_scan=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0443\u0434\u0430\u0447\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435
-subs.prop.last_result=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0438\u0437 \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
+subs.prop.last_result=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043d\u043e\u0432\u0430\u044f \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430
 subs.prop.last_error=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043e\u0448\u0438\u0431\u043a\u0430
-subs.prop.num_read=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
-subs.prop.num_unread=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
-subs.prop.template=\u0428\u0430\u0431\u043b\u043e\u043d
+subs.prop.num_read=\u0427\u0438\u0441\u043b\u043e \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
+subs.prop.num_unread=\u0427\u0438\u0441\u043b\u043e \u043d\u0435\u043f\u0440\u043e\u0447\u0442\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
+subs.prop.template=\u0417\u0430\u043a\u043b\u0430\u0434\u043a\u0430
 subs.prop.auth=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f
-externalLogin.auth_method_proxy=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 cookies. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0438 \ [...]
-externalLogin.wait=\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435...
-TableColumn.menu.date_added.time=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c/\u0441\u043a\u0440\u044b\u0442\u044c \u0432\u0440\u0435\u043c\u044f
-sidebar.VuzeHDNetwork=\u041f\u043e\u0440\u0442\u0430\u043b Vuze HD
-subs.prop.next_scan=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435
-subs.prop.assoc=\u0410\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u0438
+externalLogin.auth_method_proxy=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043c\u0435\u0442\u043e\u0434 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0437\u0430\u0445\u0432\u0430\u0442\u0430 cookie. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u044d\u0442\u0443 \u043e\u043f\u0446\u0438\u044e \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u [...]
+externalLogin.wait=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0436\u0434\u0438\u0442\u0435...
+TableColumn.menu.date_added.time=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c/\u0421\u043a\u0440\u044b\u0442\u044c \u0432\u0440\u0435\u043c\u044f
+sidebar.VuzeHDNetwork=\u0421\u0435\u0442\u044c Vuze HD
+subs.prop.next_scan=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
+subs.prop.assoc=\u0421\u0432\u044f\u0437\u0438
 subs.prop.version=\u0412\u0435\u0440\u0441\u0438\u044f
-subscriptions.column.new.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
-subscriptions.column.name=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430
-subscriptions.column.nb-results=\u0412\u0441\u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432
+subscriptions.column.new.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0435\u0441\u0442\u044c \u043b\u0438 \u043d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
+subscriptions.column.name=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
+subscriptions.column.nb-results=\u041e\u0431\u0449\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
 subscriptions.column.nb-new-results=\u041d\u043e\u0432\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b
-subscriptions.column.last-checked=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
+subscriptions.column.last-checked=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u043e\u0441\u044c
 subscriptions.view.title=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
-subs.prop.is_public=\u041e\u0442\u043a\u0440\u044b\u0442\u0430\u044f
-subs.prop.high_version=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f
-Subscription.menu.upgrade=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043e \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438
-metasearch.template.version.bad=\u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u00ab%1\u00bb \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Vuze
-metasearch.addtemplate.failed.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
-metasearch.addtemplate.failed.desc=\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d: %1
-subscription.version.bad=\u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u00ab%1\u00bb \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Vuze
-statusbar.feedback=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u044f\u043c\u0438   
-statusbar.feedback.tooltip=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 Vuze
-sidebar.Activity=\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f
-v3.activity.button.watchall=\u041e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u043c
-subscriptions.view.help.1=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u0432\u0441\u0451, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u043e\u043a
-subscriptions.view.help.2=\u041f\u043e\u043b\u0443\u0447\u0430\u0439\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435</A>.
-sidebar.sash.tooltip=F7 \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442/\u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c
-sidebar.expand.tooltip=\u0420\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c
-sidebar.dropdown.tooltip=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043c\u0435\u043d\u044e
+subs.prop.is_public=\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c
+subs.prop.high_version=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0432\u0435\u0440\u0441\u0438\u044f
+Subscription.menu.upgrade=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e
+metasearch.template.version.bad=\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430 '%1' \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u043f\u0440\u043e\u0430\u043f\u0433\u0440\u0435\u0439\u0434\u0438\u0442\u0435 Vuze
+metasearch.addtemplate.failed.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+metasearch.addtemplate.failed.desc=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430: %1
+subscription.version.bad=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 '%1' \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430, \u043f\u043e\u043a\u0430 \u0412\u044b \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 Vuze
+statusbar.feedback=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u043e\u0442\u0437\u044b\u0432
+statusbar.feedback.tooltip=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0430\u0442\u044c \u043e\u0442\u0437\u044b\u0432
+sidebar.Activity=\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f
+v3.activity.button.watchall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u043a\u0430\u043a \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u043e\u0435
+subscriptions.view.help.1=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b
+subscriptions.view.help.2=\u041f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u0441\u0432\u0435\u0436\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d [...]
+sidebar.sash.tooltip=F7 \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043a\u0440\u044b\u0442\u044c/\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0431\u0430\u043a\u043e\u0432\u0443\u044e \u043f\u043e\u043b\u043e\u0441\u043a\u0443
+sidebar.expand.tooltip=\u0420\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u043e\u043b\u043e\u0441\u043a\u0443
+sidebar.dropdown.tooltip=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043c\u0435\u043d\u044e
 subscript.all.subscribed=\u0412\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u044d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
-subscript.some.subscribed=\u0423 \u0432\u0430\u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442.\n\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0432\u0441\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0434 [...]
-subscript.none.subscribed=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430
-v3.iconBar.up.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u0432\u0435\u0440\u0445\n\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u0435 \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 \u0432\u0432\u0435\u0440\u0445, \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044f \u043b\u0435\u0432\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443
-v3.iconBar.down.tooltip=\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u0437\n\u041f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u0435 \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 \u0432\u043d\u0438\u0437, \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044f \u043b\u0435\u0432\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443
+subscript.some.subscribed=\u0412\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a \u043a \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0443.\n\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u043e\u0441\u0442 [...]
+subscript.none.subscribed=\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043a \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0443
+v3.iconBar.up.tooltip=\u0421\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432\u0432\u0435\u0440\u0445\n\u0423\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u044b\u0448\u0438 \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432 \u043d\u0430\u0447\u0430\u043b\u043e
+v3.iconBar.down.tooltip=\u0421\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0432\u043d\u0438\u0437\n\u0423\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u044b\u0448\u0438 \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0446
 TableColumn.header.azsubs.ui.column.subs_link=\u0410\u0441\u0441\u043e\u0446\u0438\u0430\u0446\u0438\u044f
-TableColumn.header.azsubs.ui.column.subs_link.info=\u0421\u0432\u044f\u0437\u0438 \u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430\u043c\u0438
-Button.deleteContent.fromLibrary=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438
-Button.deleteContent.fromComputer=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430
-v3.deleteContent.message=\n\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u00ab%1\u00bb \u0441 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 \u0438\u043b\u0438 \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438 Vuze?
-v3.MainWindow.menu.view.toolbartext=\u041f\u043e\u0434\u043f\u0438\u0441\u0438 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
+TableColumn.header.azsubs.ui.column.subs_link.info=\u0410\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0441 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0430\u043c\u0438
+Button.deleteContent.fromLibrary=\u0423\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438
+Button.deleteContent.fromComputer=\u0421\u0442\u0435\u0440\u0435\u0442\u044c \u0438\u0437 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430
+v3.deleteContent.message=\n\u0412\u044b \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0441\u0442\u0435\u0440\u0435\u0442\u044c '%1' \u0438\u0437 \u0412\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430, \u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0412\u0430\u0448\u0435\u0439 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Vuze?
+v3.MainWindow.menu.view.toolbartext=\u0422\u0435\u043a\u0441\u0442 \u043f\u0430\u043d\u0435\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432
 v3.MainWindow.menu.view.asSimpleList=\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
 v3.MainWindow.menu.view.asAdvancedList=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
-v3.MainWindow.menu.view.statusbar=\u0421\u0442\u0440\u043e\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f
-Subscription.menu.dirtyall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u043c\u0438
-configureWizard.file.message3=Vuze \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442 \u0444\u0430\u0439\u043b\u044b \u0432 \u043e\u0441\u043e\u0431\u0443\u044e \u043f\u0430\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c:
-v3.deleteContent.applyToAll=\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0430\u0434 \u0432\u0441\u0435\u043c\u0438 %1 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438
-ConfigView.label.seeding.firstPriority.ignoreIdleHours=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438
-v3.MainWindow.menu.contentnetworks=\u0421&\u0435\u0442\u0438 HD
+v3.MainWindow.menu.view.statusbar=\u041f\u0430\u043d\u0435\u043b\u044c \u0441\u0442\u0430\u0442\u0443\u0441\u0430
+Subscription.menu.dirtyall=\u041f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u0430\u043a '\u041d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e'
+configureWizard.file.message3=Vuze \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u043d\u0438\u0436\u0435 \u043f\u0430\u043f\u043a\u0443:
+v3.deleteContent.applyToAll=\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 %1 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439
+ConfigView.label.seeding.firstPriority.ignoreIdleHours=\u0422\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0443\u0436\u0435
+v3.MainWindow.menu.contentnetworks=\u0421\u0435\u0442\u0438 HD
 v3.MainWindow.menu.contentnetworks.about=\u041e \u0441\u0435\u0442\u044f\u0445 HD
-Peers.column.as.info=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043e\u0431 AS (\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435) \u0443\u0437\u043b\u0430
-ConfigTransferAutoSpeed.auto.speed.neural=\u041d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c (Gudy Alpha)
-ConfigView.label.autoopen.downloadbars=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043d\u043b\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438
-ConfigView.label.autoopen=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0435
-ConfigView.label.autoopen.detailstab=\u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u0440\u0438
-ConfigView.label.systray=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439
-ConfigView.label.systray._mac=\u0417\u043d\u0430\u0447\u043e\u043a \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f
-ConfigView.section.interface.legacy=\u041f\u0440\u0435\u0436\u043d\u0438\u0439 \u0434\u0438\u0437\u0430\u0439\u043d
-v3.MainWindow.menu.contentnetworks.manage=&\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u044f\u043c\u0438 HD
-azbuddy.ui.table.loc_cat=
+Peers.column.as=\u041f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440
+Peers.column.as.info=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0410\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0439 \u0421\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0438\u0440\u0430, \u0442.\u0435. \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430.
+ConfigView.label.autoopen.downloadbars=\u0410\u0432\u0442\u043e-\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u041f\u0430\u043d\u0435\u043b\u044c \u0422\u0440\u0430\u0444\u0438\u043a\u0430 \u043a\u043e\u0433\u0434\u0430 \u0438\u0434\u0435\u0442
+ConfigView.label.autoopen=\u0410\u0432\u0442\u043e-\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c
+ConfigView.label.autoopen.detailstab=\u0410\u0432\u0442\u043e-\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0443 \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043a\u043e\u0433\u0434\u0430 \u0438\u0434\u0435\u0442
+ConfigView.label.systray=\u0421\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0442\u0440\u0435\u0439
+ConfigView.label.systray._mac=\u0418\u043a\u043e\u043d\u043a\u0430 \u041f\u0430\u043d\u0435\u043b\u0438 \u0421\u0442\u0430\u0442\u0443\u0441\u0430
+ConfigView.section.interface.legacy=\u041f\u0440\u0435\u0436\u043d\u0438\u0439 \u0441\u0442\u0438\u043b\u044c
+v3.MainWindow.menu.contentnetworks.manage=&\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0421\u0435\u0442\u044f\u043c\u0438 HD
+azbuddy.ui.table.loc_cat=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0432\u043e \u0432\u043d\u0435
+azbuddy.ui.table.rem_cat=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435
 azbuddy.ui.menu.cat=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
-azbuddy.ui.menu.cat.share=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0437\u0435\u0439
+azbuddy.ui.menu.cat.share=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u0441 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438
 azbuddy.ui.menu.cat.set=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
-azbuddy.ui.menu.cat.set_msg=\u0421\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e \u0438\u043b\u0438 \u00abAll\u00bb
+azbuddy.ui.menu.cat.set_msg=\u0420\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439, \u0438\u043b\u0438 'All' (\u0432\u0441\u0435)
 azbuddy.ui.menu.cat_subs=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f
-subs.prop.update_period=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
-azbuddy.enable_cat_pub=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0412\u0421\u0415 \u0432\u0430\u0448\u0438 \u0434\u0440\u0443\u0437\u044c\u044f (\u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c: \u00ab,\u00bb) 
-v3.dialog.cnclose.title=\u0417\u0430\u043a\u0440\u044b\u0442\u043e %1
-v3.dialog.cnclose.subtitle=\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435
-v3.dialog.cnclose.info1=\u0412\u044b \u0437\u0430\u043a\u0440\u044b\u043b\u0438 \u0441\u0435\u0442\u044c HD
-v3.dialog.cnclose.info2=\u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u043f\u044f\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u044d\u0442\u0443 \u0441\u0435\u0442\u044c HD, \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u043d\u044e \u00ab\u0421\u0435\u0442\u0438 HD\u00bb
-v3.dialog.cnclose.noshow=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430
-v3.dialog.cnmanage.title=\u041c\u0435\u043d\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u044f\u043c\u0438 HD
-v3.dialog.cnmanage.intro=\u041d\u0438\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0441\u0435\u0442\u0438 HD, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432 \u043c\u0435\u043d\u044e \u00ab\u0421\u0435\u0442\u0438 HD\u00bb
+subs.prop.update_period=\u041f\u0435\u0440\u0438\u043e\u0434 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+azbuddy.enable_cat_pub=\u041f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0412\u0421\u0415 \u0412\u0430\u0448\u0438 \u0434\u0440\u0443\u0437\u044c\u044f \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f (\u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f ',')
+azbuddy.ui.table.read_cat=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0447\u0442\u0435\u043d\u0438\u044f
 TableColumn.header.#=\u2116
-TableColumn.header.#.info=\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u043b\u0438 \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432\u044b\u0439 \u043d\u043e\u043c\u0435\u0440
-TableColumn.header.category.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u0442\u043e\u0440\u0440\u0435\u043d\u0442
-TableColumn.header.DateCompleted.info=\u0414\u0430\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.AzProduct.info=\u0421\u0435\u0442\u044c-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.health.info=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0441 \u0443\u0437\u043b\u0430\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f
-TableColumn.header.maxuploads.info=\u041d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0443\u0437\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430
-TableColumn.header.name.info=\u0418\u043c\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.unopened.info=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u0431\u044b\u043b \u043b\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043e\u0442\u043a\u0440\u044b\u0442 (\u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0451\u043d)
-TableColumn.header.savepath.info=\u0426\u0435\u043b\u0435\u0432\u0430\u044f \u043f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.SeedingRank.info=\u041e\u0446\u0435\u043d\u043e\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0432 \u043f\u043b\u0430\u043d\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438. \u0427\u0435\u043c \u0432\u044b\u0448\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0440\u0440\u04 [...]
-TableColumn.header.shareRatio.info=\u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c.
-TableColumn.header.size.info=\u0420\u0430\u0437\u043c\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435
-TableColumn.header.azsubs.ui.column.subs.info=\u041a\u043d\u043e\u043f\u043a\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043b\u0435\u043d\u0442\u0443 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+TableColumn.header.#.info=\u041d\u043e\u043c\u0435\u0440 \u041f\u043e\u0437\u0438\u0446\u0438\u0438/\u041f\u043e\u0440\u044f\u0434\u043a\u0430
+TableColumn.header.category.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+TableColumn.header.DateCompleted.info=\u0414\u0430\u0442\u0430, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0431\u044b\u043b\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
+TableColumn.header.AzProduct.info=\u0421\u0435\u0442\u044c \u041a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+TableColumn.header.health.info=\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e \u0412\u0430\u0448\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0433\u0440\u0443\u043f\u043f\u043e\u0439 \u043f\u0438\u0440\u043e\u0432 \u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0435
+TableColumn.header.maxuploads.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 # \u043f\u0438\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c
+TableColumn.header.name.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.unopened.info=\u0424\u043b\u0430\u0436\u043e\u043a, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u0435\u0441\u043b\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0431\u044b\u043b \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d (\u0438\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442)
+TableColumn.header.savepath.info=\u041f\u0430\u043f\u043a\u0430 \u0438\u043b\u0438 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.SeedingRank.info=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0430\u043d\u0433\u0430 - \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u0412\u044b\u0448\u0435 \u0440\u0430\u043d\u0433 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0431\u04 [...]
+TableColumn.header.shareRatio.info=\u041a\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0412\u044b \u0440\u0430\u0437\u0434\u0430\u043b\u0438 \u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0412\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438.
+TableColumn.header.size.info=\u0420\u0430\u0437\u043c\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435
+TableColumn.header.azsubs.ui.column.subs.info=\u041a\u043d\u043e\u043f\u043a\u0430, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0412\u0430\u043c \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0443, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e \u0440\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
 TableColumn.header.upspeed.info=\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
-TableColumn.header.downspeed.info=\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430
-TableColumn.header.up.info=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u0440\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u0430\u043c
-TableColumn.header.down.info=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0443\u0437\u043b\u043e\u0432
-TableColumn.header.ProgressETA.info=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u044c, \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u0432\u0440\u0435\u043c\u044f \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u0435.
-TableColumn.header.eta.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+TableColumn.header.downspeed.info=\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+TableColumn.header.up.info=\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043b\u0430\u043d\u043d\u043e\u0435 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c
+TableColumn.header.down.info=\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439
+TableColumn.header.ProgressETA.info=\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 "\u0421\u0442\u0430\u0442\u0443\u0441", "\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435", "ETA" \u0438 "\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438" \u0432 \u043e\u0434\u043d\u0443 \u043c\u043d\u043e\u0433\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u0443\u044e \u043a\u043e\u043b\u043e [...]
+TableColumn.header.eta.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0431\u044b\u043b \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d
+Pieces.column.#=\u2116
 Pieces.column.#.info=\u041d\u043e\u043c\u0435\u0440 \u0447\u0430\u0441\u0442\u0438
-Peers.column.%.info=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0443\u0437\u043b\u0430
-TableColumn.header.download.info=\u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u044f\u0442\u044b\u0445 \u043e\u0442 \u0443\u0437\u043b\u0430
-TableColumn.header.upload.info=\u041e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u0443
-TableColumn.header.downloadspeed.info=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u0443\u0437\u043b\u0430
-TableColumn.header.uploadspeed.info=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u0437\u043b\u0443
-TableColumn.header.lan.info=\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0437\u043b\u0430 \u0432 LAN
-TableColumn.header.downloadspeedoverall.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0451\u043c\u0430 \u0443\u0437\u043b\u0430
-Peers.column.pieces.info=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u0447\u0430\u0441\u0442\u0435\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
-TableColumn.header.TableColumnNameInfo=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
+Peers.column.%.info=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u043e\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0438\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f
+TableColumn.header.download.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0438\u043d\u044f\u0442\u044b\u0445 \u043e\u0442 \u043f\u0438\u0440\u0430
+TableColumn.header.upload.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u043e\u0441\u043b\u0430\u043b\u0438 \u043f\u0438\u0440\u0443
+TableColumn.header.downloadspeed.info=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043a\u0430\u0447\u0430\u0435\u043c \u0441 \u043f\u0438\u0440\u0430
+TableColumn.header.uploadspeed.info=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u0441\u044b\u043b\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0438\u0440\u0443
+TableColumn.header.lan.info=\u0424\u043b\u0430\u0436\u043e\u043a, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0448\u0438\u0439, \u0447\u0442\u043e \u043f\u0438\u0440 \u0438\u0437 \u0412\u0430\u0448\u0435\u0439 \u0441\u0435\u0442\u0438 LAN
+TableColumn.header.downloadspeedoverall.info=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0438\u0440\u0430
+Peers.column.pieces.info=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0442\u043e\u043b\u0431\u0438\u043a, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u043f\u0438\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b
+TableColumn.header.TableColumnNameInfo=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435
 TableColumn.header.TableColumnSample=\u041f\u0440\u0438\u043c\u0435\u0440
-TableColumn.header.TableColumnInfo=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u0430
-TableColumn.header.TableColumnChosenColumn=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446
-subs.prop.is_auto_ok=\u0410\u0432\u0442\u043e\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0430
-label.learnmore=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435...
-ColumnSetup.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0434\u043b\u044f \u00ab%1\u00bb
-ColumnSetup.explain=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0441\u043b\u0435\u0432\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0438\u0434\u0438\u043c\u044b\u0445 \u0441\u043f\u0440\u0430\u0432\u0430. \u0424\ [...]
-ColumnSetup.chosencolumns=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b
-ColumnSetup.proficiency=\u0423\u0440\u043e\u0432\u0435\u043d\u044c:
+TableColumn.header.TableColumnInfo=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438
+TableColumn.header.TableColumnChosenColumn=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u0430\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0430
+subs.prop.is_auto_ok=\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u0430\u044f \u0410\u0432\u0442\u043e-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+label.learnmore=\u0423\u0437\u043d\u0430\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435
+ColumnSetup.title=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0434\u043b\u044f '%1'
+ColumnSetup.explain=\u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0439\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0441\u043b\u0435\u0432\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0438\u0445 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0445 \u043a\u043e\u043b\u043e\u043d\u043e\u043a \u0441\u043f\u0440\u0430\u0432\u0430. \u0420\u0430\u0 [...]
+ColumnSetup.chosencolumns=\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438
+ColumnSetup.proficiency=\u041a\u0432\u0430\u043b\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f:
 ColumnSetup.categories=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438:
 ColumnSetup.filters=\u0424\u0438\u043b\u044c\u0442\u0440\u044b
-ColumnSetup.availcolumns=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b (%1)
-ColumnSetup.availcolumns.filteredby=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0441\u0442\u043e\u043b\u0431\u0446\u044b (%1, \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u043e %2)
-ConfigView.label.maxStalledSeeding=\u041c\u0430\u043a\u0441. \u00ab\u0437\u0430\u0433\u043b\u043e\u0445\u0448\u0438\u0445\u00bb [0: \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043e]
+ColumnSetup.availcolumns=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 %1 \u043a\u043e\u043b\u043e\u043d\u043a\u0438
+ColumnSetup.availcolumns.filteredby=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 %1 \u043a\u043e\u043b\u043e\u043d\u043a\u0438, \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 %2
+devices.view.title=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+device.renderer.view.title=\u0420\u0435\u043d\u0434\u0435\u0440\u044b
+device.mediaserver.view.title=\u041c\u0435\u0434\u0438\u0430-\u0441\u0435\u0440\u0432\u0435\u0440\u044b
+device.router.view.title=\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u044b
+device.model.desc=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438
+device.model.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438
+device.model.num=\u041d\u043e\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0438
+device.manu.desc=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c
+device.router.is_mapping=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u043e\u0432
+device.router.req_map=\u0422\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0435 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435
+device.router.configure=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 UPnP
+device.mediaserver.configure=\u0421\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0439 \u043c\u0435\u0434\u0438\u0430-\u0441\u0435\u0440\u0432\u0435\u0440
+device.hide=\u0421\u043a\u0440\u044b\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+device.search=\u0418\u0441\u043a\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+device.router.con_type=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435: %1
+device.browse=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440
+device.upnp.desc_url=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+device.upnp.present_url=\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+ConfigView.label.maxStalledSeeding=\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0442\u0430\u043a\u0438\u0445 '\u0437\u0430\u0433\u043b\u043e\u0445\u0448\u0438\u0445' \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432 [0:\u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0438\u044f]
+device.search.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+devices.sidebar.simple=\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0438\u0434
+devices.xcode.working_dir=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+devices.xcode.prof_def=\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
+devices.xcode.profs=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0438 \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+device.lastseen=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u0437\u0430\u043c\u0435\u0447\u0435\u043d\u043e
+devices.contextmenu.xcode=\u0422\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+devices.device=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.profile=\u041f\u0440\u043e\u0444\u0438\u043b\u044c
+General.percent=\u041f\u0440\u043e\u0446\u0435\u043d\u0442
+devices.installed=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
+devices.comp.missing=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Vuze \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430
+devices.state=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+MainWindow.menu.help.donate=&\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435
+DonationWindow.noload.title=\u041f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435
+DonationWindow.noload.text=\u041e\u043a\u043d\u043e \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c\u0441\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.
+devices.xcode.only.show=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435
+device.quit.transcoding.title=\u0418\u0434\u0451\u0442 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+device.quit.transcoding.text='%1' \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f '%2' \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043d\u0430 %3%.\n\u0415\u0441\u043b\u0438 \u0412\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0439\u0434\u0435\u0442\u0435, \u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u0441  [...]
+download.removerules.unauthorised.data=\t\u0423\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435
+device.config.xcode.maxbps=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432 KB/\u0441\u0435\u043a [0: \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f]
+device.xcode=\u041f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+device.xcode.always=\u0412\u0441\u0435\u0433\u0434\u0430
+device.xcode.whenreq=\u041a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f
+device.xcode.never=\u041d\u0438\u043a\u043e\u0433\u0434\u0430
+devices.copy.pending=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438
+devices.sidebar.hide.rend.generic=\u0421\u043a\u0440\u044b\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+v3.devicesview.infobar.text2=\u0414\u043b\u044f \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0435\u0433\u043e \u0438\u0437 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 \u0423\u0441\u0442\u0440\u043e\u [...]
+iconBar.transcode=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+iconBar.transcode.tooltip=\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u0434\u0438\u0430-\u0444\u0430\u0439\u043b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+device.retry.copy=\u041f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+devices.copy.fail=\u041d\u0435\u0443\u0434\u0430\u0447\u043d\u043e\u0435 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.on.demand=\u041f\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044e
+devices.ready=\u0413\u043e\u0442\u043e\u0432\u043e
+TableColumn.header.trancode_qpos=\u2116
+TableColumn.header.trancode_qpos.info=\u041f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u041e\u0447\u0435\u0440\u0435\u0434\u0438 \u0422\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+TableColumn.header.profile=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+TableColumn.header.profile.info=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+TableColumn.header.copied=\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043e
+TableColumn.header.device=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+TableColumn.header.device.info=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e-\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044c
+TableColumn.header.trancode_completion=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438
+# This is the beginning of the word "View".  It's right aligned under the icon bar item
+v3.iconBar.view.big=\u0412\u0438
+v3.iconBar.view.big.tooltip=\u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e\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=\u0434
+v3.iconBar.view.small.tooltip=\u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a
+general.dont.ask.again=\u041d\u0435 \u0441\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430
+general.na.short=\u041d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e
+v3.menu.device.exploreTranscodes=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b
+v3.menu.device.exploreTranscodes._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u041f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435
+v3.menu.device.exploreTranscodes._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435
+v3.menu.device.defaultprofile=\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e
+devices.button.installitunes=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441 iTunes
+device.itunes.install=\u0412\u0430\u043c \u043d\u0430\u0434\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c iTunes
+device.itunes.start=\u0412\u0430\u043c \u043d\u0430\u0434\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c iTunes \u0438\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e-\u0437\u0430\u043f\u0443\u0441\u043a
+device.itunes.install_problem=\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 \u0441 iTunes
+devices.downloading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+TableColumn.header.duration=\u0414\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c
+TableColumn.header.resolution=\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430
+devices.xcode.autoStart=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0433\u0434\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f
+option.askeverytime=\u0421\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u044f\u043a\u0438\u0439 \u0440\u0430\u0437
+option.rememberthis=\u0417\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0432\u044b\u0431\u043e\u0440
+devices.associate=\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u0441 ...
+devices.associate.already=\u0423\u0436\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043e
+devices.always.cache=\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b
+devices.turnon.prepageload=\u0427\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0434\u043e\u043f. \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.
+devices.turnon.itunes=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 iTunes (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 Apple)
+devices.turnon.qos=\u0414\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u043e\u0439 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0441 Vuze
+devices.turnon.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+devices.choose.device.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0438\u0434\u0435\u043e:
+devices.choose.profile.info.text=\u041f\u043e\u0441\u043b\u0435 \u0412\u0430\u0448\u0435\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430, Vuze \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u0432\u0438\u0434\u0435\u043e-\u0444\u043e\u0440\u043c\u0430\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u043c \u0423\u0441\u04 [...]
+devices.choose.profile.info.title.selected=%1 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438:
+devices.view.heading=\u041f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435
+device.view.heading=\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0434\u043b\u044f  %1
+devices.choose.device.info.title=\u0421\u043e\u0432\u0435\u0442 \u043f\u043e \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443
+devices.choose.device.info.text=\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0430 \u043d\u0443\u0436\u043d\u043e\u0435 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432 \u0411\u043e\u043a\u043e\u0432\u043e\u0439 \u041f\u0430\u043d\u0435\u043b\u0438
+label.clickone=\u041e\u0434\u0438\u043d \u043a\u043b\u0438\u043a
+Button.turnon=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
+ConfigView.label.dm.dblclick=\u0414\u0432\u043e\u0439\u043d\u043e\u0439 \u043a\u043b\u0438\u043a \u0432 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430:
+ConfigView.option.dm.dblclick.play=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
+ConfigView.option.dm.dblclick.details=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439 \u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0435
+ConfigView.option.dm.dblclick.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b
+ConfigView.option.dm.dblclick.show._mac=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u041f\u043e\u0438\u0441\u043a\u043e\u0432\u0438\u043a\u0435
+ConfigView.option.dm.dblclick.show._windows=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u041f\u0440\u043e\u0432\u043e\u0434\u043d\u0438\u043a\u0435
+subscriptions.column.auto-download=\u0410\u0432\u0442\u043e-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+xcode.deletedata.title=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442?
+xcode.deletedata.message=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u043a\u043e\u043f\u0438\u044e '%1', \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0434\u043b\u044f '%2'%3?
+xcode.deletedata.message.2=\n(\u043a\u043e\u043f\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0442\u0430\u0442\u044c\u0441\u044f \u0432 '%1')
+v3.deviceview.infobar.line1=\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043e \u0438\u0437 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 \u0412\u0430\u0448\u0435 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e.
+v3.deviceview.infobar.line2=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043e \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0438\u0437 \u044d\u043a\u0440\u0430\u043d\u043e\u0432 - iPhone, iPod, TV
+v3.deviceview.infobar.line1.generic=\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043e \u0438\u0437 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 %1 \u0432 \u0411\u043e\u043a\u043e\u0432\u043e\u0439 \u041f\u0430\u043d\u0435\u043b\u0438.
+v3.deviceview.infobar.line2.itunes=\u0412\u0438\u0434\u0435\u043e \u043f\u043e\u044f\u0432\u044f\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 iTunes Movies \u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0433\u043e\u0442\u043e\u0432\u044b \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f.
+v3.deviceview.infobar.line2.xbox=\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u043e\u0442\u043e\u043a \u0432\u0438\u0434\u0435\u043e, \u0437\u0430\u0439\u0434\u044f \u0432 Xbox 360 \u0438 \u0432\u044b\u0431\u0440\u0430\u0432 My XBox -> Video Library -> Vuze.
+v3.deviceview.infobar.line2.ps3=\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u043e\u0442\u043e\u043a \u0432\u0438\u0434\u0435\u043e, \u0437\u0430\u0439\u0434\u044f \u0432 PS3 \u0438 \u0432\u044b\u0431\u0440\u0430\u0432 Videos -> Vuze.
+devices.copy_url=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c URL \u043f\u043e\u0442\u043e\u043a\u0430 \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+devices.converting=\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f
+Button.reload=\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c
+devices.auto.start=\u0410\u0432\u0442\u043e-\u0441\u0442\u0430\u0440\u0442
+Subscription.menu.setcookies=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Cookies
+general.enter.cookies=\u0412\u0432\u0435\u0441\u0442\u0438 'cookie'
+device.config.xcode.workdir=\u041f\u0430\u043f\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u043e\u0439
+MyTorrentsView.menu.clear_alloc_data=\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u044f
+DiskManager.error.nospace=\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430
+DiskManager.error.nospace_fat32={DiskManager.error.nospace} - \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 {wiki.fat32}
+ConfigView.section.file.rename.incomplete=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0435\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432
+subscriptions.config.auto=\u0410\u0432\u0442\u043e-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+subscriptions.config.autostartdls=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438 \u0438\u0445 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 (\u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u043d\u [...]
+subscriptions.config.autostart.min=\u0421\u0442\u0430\u0440\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 >= MB [0: \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f]
+subscriptions.config.autostart.max=\u0421\u0442\u0430\u0440\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 <= MB [0: \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f]
+dlg.corewait.title=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u044f\u0434\u0440\u0430
+dlg.corewait.text=\u0421\u0435\u043a\u0443\u043d\u0434\u043e\u0447\u0443...\n\n\u0412\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e Vuze \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442 \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+library.core.wait=\u0421\u0435\u043a\u0443\u043d\u0434\u043e\u0447\u043a\u0443...\n\u041a\u043b\u0438\u0435\u043d\u0442 Vuze \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0441\u044f \u043a \u0441\u0442\u0430\u0440\u0442\u0443
+ConfigView.label.StartUIBeforeCore=\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u044f\u0434\u0440\u0430
+general.add.friends=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0437\u0435\u0439!
+general.all.friends=\u0412\u0441\u0435 \u0434\u0440\u0443\u0437\u044c\u044f
+friend.mod.subs=\u041f\u0440\u0430\u0432\u044b\u0439 \u043a\u043b\u0438\u043a \u043c\u044b\u0448\u043a\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
+TableColumn.header.class=\u041a\u043b\u0430\u0441\u0441
+device.rss.group=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u043b\u0435\u043d\u0442\u0430 RSS
+devices.xcode.rsspub=\u041e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043b\u0435\u043d\u0442\u0443 RSS
+device.rss.enable=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043b\u0435\u043d\u0442\u0443 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 RSS \u0438\u0437 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 - \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c \u0434\u043b\u044f \ [...]
+device.rss.port=\u041f\u043e\u0440\u0442 \u043b\u0435\u043d\u0442\u044b RSS
+device.rss.view=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u043b\u0435\u043d\u0442\u044b RSS
+device.rss.localonly=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043e\u043c
+devices.xcode.autoCopy=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443
+devices.xcode.setcopyto=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 ...
+devices.xcode.setcopyto.title=\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+devices.copy.folder.auto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 \u043f\u0430\u043f\u043a\u0443
+devices.copy.folder.dest=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443
+TableColumn.menu.maxuploads=# M\u0430\u043a\u0441 \u0420\u0430\u0437\u0434\u0430\u0447
+devices.xcode.mancopy=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+devices.xcode.show.cat=\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
+ConfigView.label.alwaysShowLibraryHeader=\u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 (\u041c\u043e\u0438 \u0422\u043e\u0440\u0440\u0435\u043d\u0442\u044b)
+devices.cat.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438
+devices.tivo.machine=\u0438\u043c\u044f \u043c\u0430\u0448\u0438\u043d\u044b TiVo
+devices.info.copypending=%1 \u0444\u0430\u0439\u043b(\u044b) \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+device.error.xcodefail=\u041f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c
+device.error.copyfail=\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u043b \u0441\u0431\u043e\u0439 \u043f\u0440\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043f\u0430\u043f\u043a\u0443
+device.error.copytonotset='\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 ...' "%1" \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
+device.error.copytomissing='\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 ...' "%1" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e
+device.error.copytonowrite='\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0443 ...' "%1" \u043d\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u043e
+device.error.copyfail2=\u041f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u043b \u0441\u0431\u043e\u0439 \u043f\u0440\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+v3.deviceview.infobar.line2.tivo=\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u043f\u043e\u0442\u043e\u043a \u0432\u0438\u0434\u0435\u043e, \u0437\u0430\u0439\u0434\u044f \u0432 TiVo \u0438 \u0432\u044b\u0431\u0440\u0430\u0432 Vuze \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f.
+v3.deviceview.infobar.line2.psp=\u0412\u0438\u0434\u0435\u043e \u0431\u0443\u0434\u0443\u0442 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432 PSP \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.
+devices.info.copypending2=%1 \u0444\u0430\u0439\u043b(\u044b) \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+subscriptions.column.nb-subscribers=\u041f\u043e\u0434\u043f\u0438\u0441\u0447\u0438\u043a\u0438
+device.offlinedownloader.view.title=\u041e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0438
+device.od.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u043e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+device.odauto.enable=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u043c\u0438
+device.odpt.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u043d\u044b\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+devices.contextmenu.od=\u041e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+devices.contextmenu.od.auto=<\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438>
+devices.contextmenu.od.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
+devices.contextmenu.od.enabled=\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+devices.od.view.heading=\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0437\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+DevicesOD.column.od_completion=\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438
+devices.od.idle=\u0411\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+device.od.turnon.title=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+device.is.disabled=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+device.configure=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f...
+device.od.error.notfound=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e, \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+device.od.error.opfailstatus=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0430\u043d\u0434\u0443 %1: \u0441\u0442\u0430\u0442\u0443\u0441 %2
+device.od.error.opfailexcep=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0430\u043d\u0434\u0443 %1: \u043e\u0448\u0438\u0431\u043a\u0430 %2
+device.od.error.nospace=\u041d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043c\u0435\u0441\u0442\u0430 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0438\u043b\u0438 \u043d\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0434\u0438\u0441\u043a\u0430
+device.od.space=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e
+ConfigView.section.style.forceSIValues=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c IEC \u0431\u0435\u0437\u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0446\u0435\u043b\u044f\u0445 \u0441\u043e\u0432\u [...]
+ConfigView.label.enableSystrayToolTip=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043d\u0430 \u0438\u043a\u043e\u043d\u043a\u0443
+devices.activation=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+button.nothanks=\u041d\u0435\u0442, \u0441\u043f\u0430\u0441\u0438\u0431\u043e
+devices.od.turnon.text1=\u0417\u0430\u043c\u0435\u0447\u0435\u043d\u043e \u0447\u0442\u043e \u0412\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a %1.
+devices.od.turnon.text2=\u0412\u044b \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b %1 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043b \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440 \u043e\u0444\u0444\u043b\u0430\u0439\u043d?
+devices.od.turnon.text3=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u0434\u0438\u0441\u043a \u043a %1 \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e.
+devices.od.turnon.learn=\u0423\u0437\u043d\u0430\u0439\u0442\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 >
+devices.router=\u0440\u043e\u0443\u0442\u0435\u0440
+devices.od=\u043e\u0444\u0444\u043b\u0430\u0439\u043d-\u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a
+webui.pairingenable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0430\u0440
+webui.group.access=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043e\u043c
+ConfigView.section.Pairing=\u041f\u0430\u0440\u044b
+pairing.accesscode=\u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430
+pairing.ac.getnew=\u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430
+pairing.ac.getnew.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c
+pairing.ipv4=IPv4 \u0430\u0434\u0440\u0435\u0441
+pairing.ipv6=IPv6 \u0430\u0434\u0440\u0435\u0441
+pairing.local.ipv4=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 IPv4
+pairing.local.ipv6=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 IPv6
+pairing.host=\u0410\u0434\u0440\u0435\u0441 \u0445\u043e\u0441\u0442\u0430 (\u0438\u043c\u044f DNS)
+pairing.group.explicit=\u0423\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 IP
+pairing.explicit.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
+pairing.explicit.info=\u041e\u0431\u044b\u0447\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 IP \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0442.\u043a. \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\n\u0410\u0442\u0442\u0440\u0438\u0431\u0443\u0442 '\u0445\u043e\u0441\u0442' [...]
+pairing.op.fail=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u044b \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+pairing.alloc.fail=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430\n%1
+pairing.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440 Vuze \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 (\u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0445) \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c/\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u0432
+pairing.status.info=\u0421\u0442\u0430\u0442\u0443\u0441
+pairing.status.registered=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0443\u0434\u0430\u0447\u043d\u043e (%1)
+pairing.status.pending=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e \u0432 %1
+pairing.status.initialising=\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f...
+pairing.status.disabled=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e
+pairing.view.registered=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438
+webui.pairing.info.n=\u041f\u0430\u0440\u044b \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u044b, \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 -> \u041f\u0430\u0440\u044b \u0434\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438
+webui.pairing.info.y=\u041f\u0430\u0440\u044b \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b, \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 -> \u041f\u0430\u0440\u044b \u0434\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438
+webui.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c (*)
+ConfigView.section.rss=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043b\u0435\u043d\u0442\u044b RSS \u0438 \u0442.\u043f.
+subscriptions.rss.enable=\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043b\u0435\u043d\u0442\u044b RSS \u0438\u0437 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a
+device.tivo.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 TiVo
+Button.removeAll=\u0423\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0451
+label.rename=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c %1
+pairing.server.warning.title=\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0430\u0440
+wizard.webseedseditor.edit.title=\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440 HTTP-\u0441\u0438\u0434\u043e\u0432
+wizard.webseedseditor.edit.newseed=\u041d\u043e\u0432\u0439 \u0441\u0438\u0434
+MyTorrentsView.menu.editWebSeeds=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c HTTP Seeds
+ClientStats.title.full=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 BT-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432
+ClientStats.column.count=\u0421\u0447\u0451\u0442\u0447\u0438\u043a
+Scrape.status.cached=\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 scrape-\u043e\u043f\u0440\u043e\u0441\u044b
+network.ipv6.enable.support=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 IPv6
+ConfigView.section.plugins.magnetplugin=\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a Magnet URI
+MagnetPlugin.use.lookup.service=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u043e\u0438\u0441\u043a\u0430 Vuze, \u0435\u0441\u043b\u0438 \u043f\u043e\u0438\u0441\u043a Magnet \u0447\u0435\u0440\u0435\u0437 DHT \u0441\u0431\u043e\u0438\u0442
+MagnetPlugin.report.secondarylookup=\u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441
+MagnetPlugin.report.secondarylookup.ok=\u0417\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043e\u0438\u0441\u043a \u0443\u0434\u0430\u0447\u0435\u043d
+MagnetPlugin.report.secondarylookup.fail=\u0417\u0430\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u043e\u0438\u0441\u043a \u043d\u0435 \u0443\u0434\u0430\u0447\u0435\u043d: \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432
+TrackerView.title.short=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438
+TrackerView.title.full=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0438\u0440\u043e\u0432
+Trackers.column.type=\u0422\u0438\u043f
+Trackers.column.name=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438
+Trackers.column.status=\u0421\u0442\u0430\u0442\u0443\u0441
+Trackers.column.seeds=\u0421\u0438\u0434\u044b
+Trackers.column.seeds.info=\u0421\u0438\u0434\u044b \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+Trackers.column.leechers=\u041b\u0438\u0447\u0435\u0440\u044b
+Trackers.column.leechers.info=\u041b\u0438\u0447\u0435\u0440\u044b \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+Trackers.column.peers=\u041f\u0438\u0440\u044b
+Trackers.column.peers.info=\u041f\u0438\u0440\u044b, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0438\u043b \u0442\u0440\u0435\u043a\u0435\u0440
+Trackers.column.interval=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b
+Trackers.column.interval.info=\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043f\u043e\u0432\u0442\u043e\u0440\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445: \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b (\u043c\u0438\u043d.\u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b)
+Trackers.column.updatein=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435
+Trackers.column.updatein.info=\u0412\u0440\u0435\u043c\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+tps.status.available=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e
+tps.status.unavailable=\u041d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e
+tps.type.dht=DH\u0422
+tps.type.pex=PE\u0425
+tps.lan.details=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432: %1
+tps.pex.details=\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u043f\u0438\u0440\u043e\u0432: %1 (\u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445: pex=%2, \u0434\u0440\u0443\u0433\u0438\u0445=%3)
+tps.tracker.cache=\u041a\u044d\u0448 \u043f\u0438\u0440\u043e\u0432
+tps.tracker.cache1=\u041a\u044d\u0448 \u043f\u0438\u0440\u043e\u0432: \u0437\u0430\u043f\u0438\u0441\u0435\u0439=%1
+dht.status.disabled=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u0430\u044f \u0411\u0414 (DHT) \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+tps.type.incoming=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u0438\u0440\u044b
+tps.incoming.details=\u0421\u0435\u0439\u0447\u0430\u0441: \u043f\u043e TCP=%1, \u043f\u043e UDP=%2; \u0412\u0441\u0435\u0433\u043e \u0431\u044b\u043b\u043e=%3
+tps.type.plugin=\u041f\u043b\u0430\u0433\u0438\u043d\u044b
+group.auto=\u0410\u0432\u0442\u043e
+ConfigView.label.autoadjust=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
+ConfigView.label.start=\u0417\u0430\u043f\u0443\u0441\u043a
+ConfigView.label.stop=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435
+ConfigView.label.start.onlogin=\u0417\u0430\u043f\u0443\u0441\u043a Vuze \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443
+ConfigView.label.stop.seedcomp=\u041a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
+ConfigView.label.stop.downcomp=\u041a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
+ConfigView.label.stop.Nothing=\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c
+ConfigView.label.stop.QuitVuze=\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c Vuze
+ConfigView.label.stop.Sleep='\u0416\u0434\u0443\u0449\u0438\u0439' \u0440\u0435\u0436\u0438\u043c
+ConfigView.label.stop.Hibernate='\u0421\u043f\u044f\u0449\u0438\u0439' \u0440\u0435\u0436\u0438\u043c
+ConfigView.label.stop.Shutdown=\u0412\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440
+core.shutdown.alert=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 '%1' \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435: %2
+core.shutdown.dl=\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b
+core.shutdown.se=\u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b
+pairing.last.error=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043e\u0448\u0438\u0431\u043a\u0430
+MainWindow.menu.pairing=\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u041f\u0430\u0440\u044b
+ConfigView.label.pauseresume=\u0410\u0432\u0442\u043e-\u043f\u0430\u0443\u0437\u0430/\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435
+update.now.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435
+update.now.desc=Vuze \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438.\n\n\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0430\u043b\u043e\u0433\u0430  [...]
+ConfigView.label.jvm=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Java
+platform.jvmopt.sunonly=\u0422\u043e\u043b\u044c\u043a\u043e Java-\u043c\u0430\u0448\u0438\u043d\u044b Sun \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f (\u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a=%1)
+platform.jvmopt.configerror=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 JVM \u0432 \u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438
+platform.jvmopt.nolinkfile=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 JVM, \u0442.\u043a. \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d
+platform.jvmopt.nolink=\u041d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 JVM, \u0442.\u043a. \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439
+platform.jvmopt.accesserror=\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0444\u0430\u0439\u043b\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a JVM: %1
+pairing.status.noservices=\u041d\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432
+webui.pairingtest=\t\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440
+webui.connectiontest=\t\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f
+jvm.info=\u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 Vuze \u0435\u0441\u043b\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b.\n**************************************************\n\u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 - \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u [...]
+jvm.show.file=\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 JVM \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 '%1' - \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0422\u041e\u041b\u042c\u041a\u041e \u0432 \u0446\u0435\u043b\u044f\u0445 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+jvm.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 JVM \u043d\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043e\u0447\u043d\u044b\u0435 \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044f
+jvm.error=\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c JVM: %1
+jvm.max.mem=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043c\u044f\u0442\u0438 [\u043f\u0443\u0441\u0442\u043e=\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u0435,\u043c\u0438\u043d.=%1]
+jvm.min.mem=\u041c\u0438\u043d. \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u0430\u043c\u044f\u0442\u0438 [\u043f\u0443\u0441\u0442\u043e=\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u0435,\u043c\u0438\u043d.=%1]
+ConfigView.section.invalid.value.title=\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
+ConfigView.section.invalid.value=\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '%1' \u0432\u0432\u0435\u0434\u0435\u043d\u043e \u0434\u043b\u044f '%2': %3
+Button.dismiss=\u0423\u0431\u0440\u0430\u0442\u044c
+webui.pairing.autoauth=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0449\u0438\u0442\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e: \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c=vuze, \u043f\u0430\u0440\u043e\u043b\u044c=<\u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0432 \u041f\u0430\u0440\u0430\u043c>
+ConfigView.label.stop.autoreset=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430 '%1' \u043f\u043e\u0441\u043b\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u044f
+remote.pairing.title=\u0423\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u041f\u0430\u0440\u044b
+remote.pairing.subtitle=Vuze Remote \u0434\u0430\u0451\u0442 \u0432\u0430\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c Vuze \u0441 \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430 \u0438\u043b\u0438 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 - \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u043 [...]
+remote.pairing.instruction=\u041f\u0440\u043e\u0441\u0442\u043e \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0438\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u043f\u043e\u043b\u0435 \u0432 \u043b\u044e\u0431\u043e\u043c \u0432\u043d\u0435\u0448\u043d\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438
+remote.pairing.functions=<A HREF="clip">\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430</A>   |   <A HREF="new">\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0434</A>
+remote.pairing.tip.title=\u0421\u043e\u0432\u0435\u0442: \u0414\u0432\u0430 \u043b\u0451\u0433\u043a\u0438\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Vuze Remote:
+remote.pairing.tip.text=\u041f\u0430\u043d\u0435\u043b\u044c Vuze Remote: \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 <A HREF="http://remote.vuze.com/download/">remote.vuze.com/download</A>\nVuze Remote Mobile: \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 <A HREF="http://remote.vuze.com/">remote.vuze.com</A> in your mobile browser.
+remote.pairing.learnmore=<A HREF="http://www.vuze.com/pairing_learnmore.start">FAQ \u043f\u043e \u041f\u0430\u0440\u0430\u043c</A>
+remote.pairing.accesscode=\u041a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0430:
+remote.pairing.test.running=\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u0438...
+remote.pairing.test.success=Vuze \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437\u0432\u043d\u0435.
+remote.pairing.test.unavailable=\u0423\u043f\u0441, \u043d\u0435 \u0441\u043c\u043e\u0433\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0412\u0430\u0448\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u0432\u043d\u0435. <A HREF="retry">\u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430</A>
+remote.pairing.test.fail=Vuze \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u043d\u0435 \u0412\u0430\u0448\u0435\u0439 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.  <A HREF="http://www.vuze.com/pairing_error_faq.start">\u0423\u0437\u043d\u0430\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435</A>
+update.fail.app.changed.title=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f
+update.fail.app.changed=Vuze \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438, \u043d\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442.\u043a. \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u04 [...]
+webui.port.override=\u041f\u043e\u0434\u043c\u0435\u043d\u0430 \u043f\u043e\u0440\u0442\u0430: \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0438\u0437-\u0437\u0430 \u043a\u043e\u043d\u0444\u0438\u0 [...]
+MainWindow.status.warning.tooltip=\u0423 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f !\n\u041a\u043b\u0438\u043a \u0434\u043b\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0435\u0439...
+search.dialog.text=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u043e\u0432\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430:
+core.not.available=Vuze \u0432\u0441\u0451 \u0435\u0449\u0451 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0441\u043d\u043e\u0432\u0430 \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f.
+dlg.auth.title=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f
+dlg.auth.enter.subtitle.try.1=\u041f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u043e.
+dlg.auth.enter.line.try.1=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0412\u0430\u0448 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0430\u043f\u0433\u0440\u0435\u0439\u0434 Vuze \u0434\u043e Vuze Plus.
+dlg.auth.enter.line.try.2=\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0412\u0430\u0448 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u043e\u043c\u0435\u0440 \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\ [...]
+dlg.auth.enter.prompt=Vuze Plus \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438:
+Button.validate=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c
+Button.getstarted=\u041d\u0430\u0447\u0430\u043b\u043e
+Button.goLibrary=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043c\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443
+dlg.auth.success.subtitle=\u041f\u043e\u0437\u0434\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f!
+dlg.auth.success.line1=\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0430\u043f\u0433\u0440\u0435\u0439\u0434 \u0434\u043e Vuze Plus.
+dlg.auth.success.line2=\u0422\u0435\u043f\u0435\u0440\u044c \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b\u0445 DVD, \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b [...]
+dlg.auth.trial.success.line1=Vuze \u0433\u043e\u0442\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c DVD.
+dlg.auth.trial.success.subtitle=\u0417\u0430\u043f\u0438\u0441\u044c DVD \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0430
+dlg.auth.trial.success.info=\u041f\u0435\u0440\u0435\u044c\u0430\u0441\u043a\u0438\u0432\u0430\u0439\u0442\u0435 \u0432\u0438\u0434\u0435\u043e-\u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 \u043e\u043a\u043d\u043e "\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u041d\u043e\u0432\u044b\u0439 DVD". \u0415\u0441\u043b\u0438 \u0412\u044b \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u0438\u0434\u0435 [...]
+dlg.auth.revoked=\u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0430\u043d\u043d\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d
+dlg.auth.revoked.line1=\u0412\u0430\u0448 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 Vuze Plus \u0431\u044b\u043b \u0430\u043d\u043d\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0438\u0436\u0435 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0438\u043d\u0444\u043e\u0440\u [...]
+dlg.auth.revoked.link=<A HREF="info">\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e \u043a\u043e\u0434\u0430\u043c \u0430\u043d\u043d\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438</A>
+dlg.auth.denied=\u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u041e\u0442\u043a\u0430\u0437\u0430\u043d
+dlg.auth.denied.line1=\u0412\u0430\u0448 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0431\u044b\u043b \u043e\u0442\u043a\u043b\u043e\u043d\u0451\u043d. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0438\u0436\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.
+dlg.auth.denied.link=<A HREF="info">\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e \u043a\u043e\u0434\u0430\u043c \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u044f \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438</A>
+dlg.auth.cancelled=\u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u041e\u0442\u043c\u0435\u043d\u0451\u043d
+dlg.auth.cancelled.line1=\u0412\u0430\u0448\u0430 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f Vuze Plus \u0431\u044b\u043b\u0430 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0430.
+dlg.auth.cancelled.line2=\u0415\u0441\u043b\u0438 \u0412\u044b \u0434\u0443\u043c\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430, \u043f\u043e\u0436\u0430\u0434\u0443\u0439\u0441\u0442\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 e-mail.
+dlg.auth.enter.subtitle.try.2=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+dlg.auth.enter.link.try.2=<A HREF="link">\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c</A> \u0435\u0441\u043b\u0438 \u0432\u044b \u0435\u0449\u0451 \u043d\u0435 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u043b\u0438 Vuze Plus.
+dlg.auth.enter.link.try.1=\u041d\u0435\u0442 \u041a\u043e\u0434\u0430 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438? <A HREF="upgrade">\u0410\u043f\u0433\u0440\u0435\u0439\u0434 \u0441\u0435\u0439\u0447\u0430\u0441</A>.
+dlg.auth.enter.expiry=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442 %1.
+dlg.auth.enter.revoked=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0431\u044b\u043b \u0430\u043d\u043d\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d.
+dlg.auth.enter.cancelled=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0431\u044b\u043b \u043e\u0442\u043c\u0435\u043d\u0451\u043d.
+dlg.auth.enter.denied=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u041a\u043e\u0434 \u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0431\u044b\u043b \u043e\u0442\u043a\u0430\u0437\u0430\u043d.
+dlg.auth.validating.subtitle=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430...
+dlg.try.trial.title=\u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0417\u0430\u043f\u0438\u0441\u044c DVD
+dlg.try.trial.text=Vuze \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b\u0445 DVD \u0438\u0437 \u0432\u0430\u0448\u0438\u0445 \u0432\u0438\u0434\u0435\u043e-\u0444\u [...]
+dlg.auth.tos=\u042f \u043f\u0440\u043e\u0447\u0451\u043b \u0438 \u043f\u0440\u0438\u043d\u044f\u043b <A HREF="tos">\u0423\u0441\u043b\u043e\u0432\u0438\u044f \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f.</A>
+dlg.auth.install.subtitle.plus=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Vuze Plus...
+dlg.auth.install.subtitle.trial=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 DVD Burn (\u0417\u0430\u043f\u0438\u0441\u044c DVD)
+dlg.auth.install.progress=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 %1 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432...
+dlg.auth.install.pct=%1% \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+mdi.entry.dvdburn=\u0417\u0430\u043f\u0438\u0441\u044c DVD
+mdi.entry.dvdburn.new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u041d\u043e\u0432\u044b\u0439 DVD
+menu.register=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f Vuze Plus
+dlg.auth.trial.title=\u0417\u0430\u043f\u0438\u0441\u044c DVD (\u041e\u0446\u0435\u043d\u043e\u0447\u043d\u0430\u044f \u0434\u0435\u043c\u043e-\u0432\u0435\u0440\u0441\u0438\u044f)
+dlg.player.install.subtitle=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438
+dlg.player.install.description=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430...
+devices.xcode.remove.vetoed=\u041f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 '%1' \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0430 \u043f\u043e\u043a\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0438\u [...]
+Button.agree=\u042f \u0441\u043e\u0433\u043b\u0430\u0441\u0435\u043d
+dlg.auth.install.failed.title=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430
+dlg.auth.install.failed.text=\u0410\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 '%1' \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430 \u0432\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\n\n\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u043f\u044b\u0442\u0430\u0439\u0442\u0435\u0441\u044c \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\ [...]
+device.status.online=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043d\u0430 \u0441\u0432\u044f\u0437\u0438
+device.itunes.status.running=iTunes \u0437\u0430\u043f\u0443\u0449\u0435\u043d
+device.itunes.status.notrunning=iTunes \u043d\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d
+device.itunes.status.notinstalled=iTunes \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d
+OpenTorrentWindow.mb.notTorrent.retry=\u041f\u043e\u0438\u0441\u043a Magnet
+ConfigView.section.ipfilter.clear.on.reload=\u0421\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435. \u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u0430 IP-\u0430\u0434\u0440\u0435\u0441\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0431\u043b\u043e\u043a\u0438\u [...]
+view.waiting.core=\u0412\u0438\u0434 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044f\u0434\u0440\u043e Vuze \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f...
+devices.profile.direct=\u041f\u0440\u044f\u043c\u043e\u0439
+cat.autoxcode=\u0410\u0432\u0442\u043e-\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+ConfigView.section.tables=\u0422\u0430\u0431\u043b\u0438\u0446\u044b
+ConfigView.section.style.useTree=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u0432 {library.name} \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435 (\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+ConfigView.section.mode.resetdefaults=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+resetconfig.warn.title=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+resetconfig.warn=\u042d\u0442\u043e \u043e\u0442\u0440\u0430\u0437\u0438\u0442\u0441\u044f \u043d\u0430 \u0432\u0441\u0435\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0412\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u0432 Vuze, \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0432 \u0438\u0445.\n\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0441\u0431\u0440\u043e\u0441 \u043a\u043e\u043d\u0444\u0 [...]
+ConfigView.label.xfer.bias_up=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043d\u0435\u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u044b\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+ConfigView.label.xfer.bias_slack=\u041a\u0411/\u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0434\u043b\u044f \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+ConfigView.label.xfer.bias_no_limit=\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443
+SpeedView.stats.upload=\u0414\u0430\u043d\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438:
+SpeedView.stats.con=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f:
+SpeedView.stats.con_details=\u0432\u0441\u0435\u0433\u043e=%1, \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445=%2, \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438=%3, \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u043e=%4
+SpeedView.stats.upbias=\u041f\u043e\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438:
+dlg.install.mlab.subtitle=\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f
+dlg.install.mlab.description=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435 \u043f\u043e\u043a\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+auto.mode=\u0410\u0432\u0442\u043e (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)
+manual.mode=\u0420\u0443\u0447\u043d\u043e\u0439
+configureWizard.transfer2.hint=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0438\u043b\u0438 \u043c\u0430\u043b\u043e\u0433\u043e \u043b\u0438\u043c\u0438\u0442\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438!
+configureWizard.transfer2.message=\u0411\u0438\u0442\u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 \u0442\u0435\u0442-\u0430-\u0442\u0435\u0442 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0435 - \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c, \u0447\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0412\u044b \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0435, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u [...]
+configureWizard.transfer2.group=\u0420\u0435\u0436\u0438\u043c
+configureWizard.transfer2.test.info=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043c\u043f\u043b\u0435\u043a\u0441\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+configureWizard.transfer2.test=\u0417\u0430\u043f\u0443\u0441\u043a \u0422\u0435\u0441\u0442\u0430
+configureWizard.transfer2.mselect=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043b\u0438\u043c\u0438\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0420\u0410\u0417\u0414\u0410\u0427\u0423
+configureWizard.transfer2.mselect.info=xxx/<value> \u043f\u043e\u043b\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0443 <value> \u0431\u0438\u0442-\u0432-\u0441\u0435\u043a\u0443\u043d\u0434\u0443.\n\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 ADSL \u0441\u04 [...]
+configureWizard.transfer2.rate.unchanged=\u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b
+configureWizard.transfer2.rate.changed=\u041b\u0438\u043c\u0438\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f=%1\n\u041f\u0440\u0438\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u0431\u0443\u0434\u0435\u0442 %2 (\u043c\u0430\u043a\u0441. \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432=%3, \u043c\u0430\u043a\u0441. \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443=%4)
+speedtest.wizard.select.title=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u0438\u043f \u0442\u0435\u0441\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438
+speedtest.wizard.select.group=\u0422\u0438\u043f \u0442\u0435\u0441\u0442\u0430
+speedtest.wizard.select.general=\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0435\u0441\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f)
+speedtest.wizard.select.bt=\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0411\u0438\u0442\u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+FileItem.storage.reorder=\u0423\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0442\u044c
+ConfigView.label.piecereorder=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0444\u0430\u0439\u043b\u044b \u043f\u043e \u043c\u0435\u0440\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0437\u0430\u0442\u0435\u043c \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u0438
+ConfigView.label.piecereorderminmb=\u0423\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u044b, \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0447\u0435\u043c [\u0432 \u041c\u0431]
+configureWizard.transfer2.current=<\u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438>
+ConfigView.section.style.extendedErase=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0441\u0435\u0442\u043a\u0443 \u0438 \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u0435 \u043c\u0435\u0441\u0442\u0430
+iconBar.stream=\u041f\u043e\u0442\u043e\u043a
+FilesView.menu.setpriority.numeric=\u0427\u0438\u0441\u043b\u0435\u043d\u043d\u043e...
+FilesView.dialog.priority.title=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0446\u0438\u0444\u0440\u0430\u043c\u0438
+FilesView.dialog.priority.text=0=\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439, 1=\u0412\u044b\u0441\u043e\u043a\u0438\u0439, 2=\u0412\u044b\u0448\u0435...
+beta.wizard.title=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0431\u0435\u0442\u0430-\u0432\u0435\u0440\u0441\u0438\u0438
+beta.wizard.intro.title=\u041f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u0443\u0447\u0430\u0441\u0442\u0438\u044f
+beta.wizard.info=\u0417\u0430\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0432 \u0431\u0435\u0442\u0430-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 Vuze \u0434\u0430\u0451\u0442 \u0412\u0430\u043c \u0440\u0430\u043d\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0433\u0440\u044f\u0434\u0443\u0449\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430.\n\n\u042d\u04 [...]
+beta.wizard.link=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0437\u0434\u0435\u0441\u044c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a web-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0431\u0435\u0442\u0430-\u0440\u0435\u043b\u0438\u0437\u043e\u0432
+beta.wizard.off=\u041c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0435\u043b\u0438\u0437\u044b, \u0441\u043f\u0430\u0441\u0438\u0431\u043e, \u043d\u043e \u043d\u0435\u0442!
+beta.wizard.on=\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0431\u0435\u0442\u0430-\u0432\u0435\u0440\u0441\u0438\u0439.
+beta.wizard.version=\u0421\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f %1
+beta.wizard.disable.title=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 
+beta.wizard.disable.text=\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0412\u0430\u043c \u0437\u0430 \u0431\u0435\u0442\u0430-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435!\n\n\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0435\u043b\u0438\u0437 \u0447\u0442\u043e\ [...]
+beta.wizard.forum=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0444\u043e\u0440\u0443\u043c\u044b Vuze \u0447\u0442\u043e\u0431\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0437\u044b\u0432 \u0438 \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u044c \u043f\u0440\u043e \u043e\u0448\u0438\u0431\u043a\u0438
+dlg.install.vuzexcode.subtitle=\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043c\u0435\u0434\u0438\u0430-\u0430\u043d\u0430\u043b\u0438\u0437\u0430
+dlg.install.vuzexcode.description=\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u043e\u0436\u0434\u0438\u0442\u0435 \u043f\u043e\u043a\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043c\u0435\u0434\u0438\u0430-\u0430\u043d\u0430\u043b\u0438\u0437\u0430 
+TableColumn.header.filecount=\u0424\u0430\u0439\u043b\u043e\u0432
+TableColumn.header.torrentspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c
+FileProgress.deleted=\u0421\u0442\u0451\u0440\u0442\u043e
+priority.high=\u0412\u044b\u0441\u043e\u043a\u0438\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+priority.normal=\u041d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+label.wrap.text=\u041f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442
+ScrapeInfoView.title=\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0440\u0435\u043a\u0435\u0440
+Column.seedspeers.started=%1 \u0438\u0437 %2
+#connected to more seeds/peers than tracker reports
+library.all.header.p=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u0439: %2 \u0430\u043a\u0442\u0438\u0432\u043d\u043e
+library.incomplete.header.p=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f, %2 \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+library.unopened.header.p=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u0439
+library.all.header=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u044f: %2 \u0430\u043a\u0442\u0438\u0432\u043d\u043e
+library.incomplete.header=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f, %2 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+library.unopened.header=%1 \u043f\u043e\u0437\u0438\u0446\u0438\u044f
+ConfigView.section.style.status.show_rategraphs=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u043e\u0434 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438/\u0440\u0430\u0437\u0434\u0430\u0447\u0438
+device.error.mountrequired="%1" \u043d\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u043d\u0430 \u0412\u0430\u0448\u0435\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435
+v3.deviceview.infobar.line2.android=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 USB \u0432 \u0412\u0430\u0448\u0435\u043c \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0435 \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e.
+MyTorrents.column.ColumnProgressETA.compon=\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 %1
+Sidebar.beta.title=\u0411\u0435\u0442\u0430-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430
+MainWindow.menu.beta.on=\u041f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u043a \u0431\u0435\u0442\u0430-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e...
+MainWindow.menu.beta.off=\u041f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0431\u0435\u0442\u0430-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435...
+Button.sendNow=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0421\u0435\u0439\u0447\u0430\u0441
+Button.sendManual=\u041f\u043e\u0441\u043b\u0430\u0442\u044c \u0412\u0440\u0443\u0447\u043d\u0443\u044e (create .zip)
+deletecontent.also.deletetorrent=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0442\u0430\u043a\u0436\u0435 \u0438 *.torrent-\u0444\u0430\u0439\u043b\u044b
+ConfigView.section.file.deletion.section=\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432
+ConfigView.section.file.delete.torrent=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0443\u0434\u0430\u043b\u044f\u0442\u044c .torrent-\u0444\u0430\u0439\u043b \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 
+ConfigView.section.file.delete.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u041f\u0430\u043d\u0435\u043b\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0443 Delete
+MainWindow.menu.view.beta=\u0411\u0435\u0442\u0430-\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430
+ConfigView.section.server.enableudpprobe=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c UDP-\u0442\u0440\u0435\u043a\u0435\u0440\u043d\u044b\u0439 \u043c\u0430\u0440\u043a\u0435\u0440 \u0434\u043b\u044f HTTP-\u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432.
+memmon.low.warning=\u041f\u0430\u043c\u044f\u0442\u0438 \u043c\u0430\u043b\u043e, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c %1 \u0438\u0437 %2.\n\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0430\u0434\u0451\u0442 \u0438 \u0432 \u043a\u0440\u0430\u0439\u043d\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 Vuze \u043f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0443\n\u [...]
+jvm.max.mem.current=\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043f\u0430\u043c\u044f\u0442\u0438 *\u043a\u0443\u0447\u0430* %1
+jvm.max.direct.mem=\u041c\u0430\u043a\u0441. \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 [\u043f\u0443\u0441\u0442\u043e=\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u0435, \u043c\u0438\u043d.=%1]
+jvm.max.direct.mem.info=\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u044d\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 *\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439* \u043f\u0430\u043c\u044f\u0442\u0438, \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c *\u043a\u0443\u0447\u0430* \u0432\u044b\ [...]
+jvm.options.summary=\u0421\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u043f\u0446\u0438\u0439:
+memmon.heap.auto.increase.warning=\u041f\u0430\u043c\u044f\u0442\u044c *\u043a\u0443\u0447\u0430* \u0431\u044b\u043b\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0430 \u0434\u043e %1. \u042d\u0442\u043e \u0434\u0430\u0441\u0442 \u044d\u0444\u0444\u0435\u043a\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 Vuze.
+device.showGeneric=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+mdi.entry.games=\u0418\u0433\u0440\u044b
+Peers.column.Protocol=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b
+devices.copying=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+devices.cancel_xcode=\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+sidebar.header.transfers=\u0424\u0430\u0439\u043b\u044b
+sidebar.header.devices=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+sidebar.header.subscriptions=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
+sidebar.header.plugins=\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u0438 \u0414\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f
+mdi.entry.about.devices=\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+mdi.entry.about.plugins=\u041e \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445
+mdi.entry.about.dvdburn=\u041d\u0430\u0447\u043d\u0438\u0442\u0435
+ConfigView.section.file.tb.delete=\u041f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u041f\u0430\u043d\u0435\u043b\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0443 Delete:
+ConfigView.tb.delete.ask=\u0421\u043f\u0440\u043e\u0441\u0438\u0442\u044c
+ConfigView.tb.delete.content=\u0421\u0442\u0435\u0440\u0435\u0442\u044c \u0431\u0435\u0437 \u0432\u043e\u043f\u0440\u043e\u0441\u0430
+ConfigView.tb.delete.torrent=\u0422\u043e\u043b\u044c\u043a\u043e \u0443\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0437 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438
+search.export.all=\u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u043a\u043b\u0430\u0434\u043a\u0438 \u043f\u043e\u0438\u0441\u043a\u0430...
+subscriptions.search.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
+devices.cancel_xcode_del=\u041f\u0440\u0435\u0440\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435/\u0423\u0431\u0440\u0430\u0442\u044c
+subscriptions.add.tooltip=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
+subscriptions.overview=\u041e\u0431\u0437\u043e\u0440 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
+configureWizard.nat.title=NAT / \u041f\u043e\u0440\u0442\u044b \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 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 BitTorrent \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\ [...]
+configureWizard.nat.server.udp_listen_port=\u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0439 UDP-\u043f\u043e\u0440\u0442
+v3.menu.device.defaultprofile.never=\u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0442\u0440\u0430\u043d\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+subscriptions.info.avail=\u0412\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u043e\u043a. %1 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0434\u043b\u044f \u0412\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.
+subscriptions.dl_subs.enable=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438
+# Will be used for {library.name} in classic view
+library.name._classic=\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b
+# Will be used for {library.name} in VuzeUI view
+library.name._vuze=\u041c\u043e\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430
+ConfigView.section.style.units=\u0415\u0434\u0438\u043d\u0438\u0446\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
+ConfigView.section.style.CatInSidebar=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0432 \u0411\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438
+library.category.header=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f '%1'
+device.import.title=\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e?
+device.import.desc=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e '%1'?
+device.import.dup.title=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e
+device.import.dup.desc=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e '%1' \u0443\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442.
+device.export.select.template.file=\u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
+dlg.stream.plus.subtext=\u0423\u0441\u0442\u0430\u043b\u0438 \u0436\u0434\u0430\u0442\u044c \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430? \u0421\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 Play Now, \u044d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c Vuze Plus \u043f\u043e\u043 [...]
+dlg.stream.plus.text=\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0430\u043f\u0433\u0440\u0435\u0439\u0434 \u043d\u0430 Vuze Plus \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u043a\u0430 \u043e\u043d\u0438 \u0433\u0440\u0443\u0437\u044f\u0442\u0441\u044f.
+dlg.stream.plus.title=\u0410\u043f\u0433\u0440\u0435\u0439\u0434
+dlg.stream.plus.subtitle=\u0410\u043f\u0433\u0440\u0435\u0439\u0434
+devices.restrict_access=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f...
+devices.restrict_access.prompt=\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a '%1'
+devices.restrict_access.msg=\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u0437\u0430\u043f\u044f\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0445 IP-\u0430\u0434\u0440\u0435\u0441\u043e\u0432 [\u0438\u043b\u0438 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u043d\u044b\u0445 \u0435\u0441\u043b\u0438 \u0432\u043f\u0435\u0440\u0435\u0434\u0438 -]
+TableColumn.TorrentStream.tooltip.disabled=Play Now \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u044d\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430
+TableColumn.TorrentStream.tooltip.expand=\u0420\u0430\u0441\u0448\u0438\u0440\u044c\u0442\u0435 \u0441\u0442\u0440\u043e\u043a\u0443 \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c Play Now \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430
+table.columns.reset=\u0421\u0431\u0440\u043e\u0441 \u043a\u043e\u043b\u043e\u043d\u043e\u043a
+# The remaining keys were not in MessagesBundle.properties
+=
+ConfigView.label.noupafterdlremove=\u0422\u0430\u043a\u0436\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447
+v3.Share.add.buddy.existing=\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0434\u0440\u0443\u0437\u044c\u044f:
+v3.buddy.prop.pks=\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
+MyTorrentsView.availability.info=\u041a\u043e\u043b. \u0437\u0430\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439
+MyTorrentsView.sendto=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c
+ConfigView.label.fakeswarmspeed=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u043d\u044e\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u043a\u0430\u043a \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+MyTorrentsView.upspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+window.uiswitcher.AdvancedUI.title=\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 Vuze.
+Peers.column.RecentUpDownRatio=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0420\u0430\u0437\u0434\u0430\u0447\u0430:\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+v3.buddies.faq=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435...
+ConfigView.section.logging.log1component=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u0440\u0430\u0437\u0434\u0430\u044e\u0449\u0438\u043c\u0438
+MyTorrentsView.torrentpath=\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+login.optional.message=\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u044b \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438
+TableColumn.header.videoLength=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0438\u0434\u0435\u043e
+v3.Share.wizard.title=\u0414\u0435\u043b\u0438\u0442\u044c\u0441\u044f -- \u041c\u0430\u0441\u0442\u0435\u0440
+Splash.label.thx=\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438
+azbuddy.ui.dialog.disable.title=\u0412\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d "\u0414\u0440\u0443\u0437\u044c\u044f"
+v3.dialog.cnmanage.title=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044e "\u0421\u0435\u0442\u0438 HD"
+ConfigView.label.peerfake2=\u043f\u0438\u0440\u043e\u0432 (0-250) \u0418\u041b\u0418 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043b\u0438\u0447\u0435\u0440\u044b/\u0441\u0438\u0434\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u0447\u0435\u043c
+swt.update.window.title=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Vuze
+MyTorrentsView.trackername.info=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0435\u0440\u0430, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0432 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0435 (\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e URL \u0430\u043d\u043e\u043d\u0441\u0430)
+ConfigView.label.noupafterdl=\u041e\u0421\u0422\u0410\u041d\u041e\u0412\u0418\u0422\u042c \u0442\u043e\u0440\u0440\u0435\u043d\u0442 (\u043d\u0435 \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c), \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430 \u0438 \u0432\u0441\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u044b
+ConfigView.label.fakeuploadisratio=\u041f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u043e\u0434\u043b\u043e\u0433 \u043a\u043e\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e:
+TableColumn.header.Info.info=\u041a\u043d\u043e\u043f\u043a\u0430, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 Vuze
+ConfigView.label.utcustomid=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 ID:
+v3.Share.header.message=\u0414\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u0435\u043a\u0443\u0449\u0438\u043c\u0438 \u0434\u0440\u0443\u0437\u044c\u044f\u043c\u0438, \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0445 \u0434\u0440\u0443\u0437\u0435\u0439.
+Main.download.state.waiting=\u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438
+MyTorrentsView.downfake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+MyTorrentsView.done.info=\u041f\u0440\u043e\u0446\u0435\u043d\u0442 \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438
+MyTorrentsView.OnlyCDing4.info=\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+PeersView.menu.noupload=\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c \u043f\u0438\u0440\u0430\u043c
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message.2=\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u0432\u0435\u0434\u0435\u043d, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b.
+MyTorrentsView.swarm_average_speed=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+message.confirm.invite.error=Doh! \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u043b\u0438\u0441\u044c \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443. \u041e\u0434\u0438\u043d \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u043d\u044b\u0445 \u0438\u043c\u0435\u044e\u [...]
+v3.activity.header.friend.requests.fromyou=\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 - \u041e\u0442 \u0412\u0430\u0441
+MainWindow.dht.status.running=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f
+MyTorrentsView.tracker=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+v3.MainWindow.menu.view.buddies-viewer=\u041f\u0430\u043d\u0435\u043b\u044c \u0414\u0440\u0443\u0437\u0435\u0439 (Friends)
+ConfigView.label.fakeuploadspeedratiostxt=KB/s \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438
+v3.activity.header.rating.reminders=\u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f
+MyTorrentsView.torrentpath.info=\u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u0438\u0441\u043a\u0435
+v3.MainWindow.myMedia.noneSelected=\u0423 \u0412\u0430\u0441 %1 \u0447\u0430\u0441\u0442\u0435\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430.\n%2 \u0438\u0437 \u043d\u0438\u0445 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b.\n\n\u0429\u0435\u043b\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0435 \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043 [...]
+ConfigView.label.startfake=\u041d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0443\u044e \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u043a\u043e\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 % \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 (\u043f\u043e\u043a\u0430 \u043d\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u [...]
+Main.download.state.allocating=\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+MyTorrentsView.commenticon=\u0418\u043a\u043e\u043d\u043a\u0430 \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f
+ConfigView.label.popup.suppress_alerts=\u041f\u043e\u0434\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f
+swt.update.window.close=\u0417\u0430\u043a\u0440\u044b\u0442\u044c
+swt.update.window.columns.size=\u0420\u0430\u0437\u043c\u0435\u0440
+ConfigView.label.popup.use_message_boxes=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043e\u043a\u043d\u0430 (\u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443) \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0441\u043f\u043b\u044b\u0432\u0430\u044e\u0449\u0438\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (\u0432\u043d\u0438\u0437\u0443 \u0441\u043f\u0440\u0430\u0432\u0430)
+v3.chat.wrongversion=%1\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0440\u0443\u0433\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Vuze, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0427\u0430\u0442.
+IrcView.title.full=\u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e
+ConfigView.section.file.write_block_limit.explain=\u0415\u0441\u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 (\u043c\u043d\u043e\u0433\u043e \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u0432 \u043f\u043e\u043a\u0 [...]
+v3.buddy.menu.chat=\u0427\u0430\u0442
+MyTorrentsView.bad_avail_time.info=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f \u0431\u044b\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+v3.dialog.cnclose.noshow=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043d\u043e\u0432\u0430
+xmlhttp.config.group.debug=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438
+swt.update.window.columns.version=\u0412\u0435\u0440\u0441\u0438\u044f
+ConfigView.label.fakeuploadspeedratio="\u0420\u0435\u0436\u0438\u043c \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u0438 ++" (0-50)&(0-10000):
+swt.update.window.cancel=\u041e\u0442\u043c\u0435\u043d\u0430
+ConfigView.label.group.gpeer=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439 \u043e\u0442\u0447\u0435\u0442 \u0434\u043b\u044f \u043f\u0438\u0440\u043e\u0432
+MyTorrentsView.completion=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u044c
+v3.Share.send.now=\u041f\u043e\u0441\u043b\u0430\u0442\u044c
+v3.Share.add.buddy.all=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0432\u0441\u0435\u043c\u0438
+%2=
+xmlhttp.config.option.log_to_plugin=\u041e\u043a\u043d\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 (*)
+DonationWindow.options.already=\u042f \u0443\u0436\u0435 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043b.
+v3.AddFriends.wizard.title=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0414\u0440\u0443\u0437\u0435\u0439 -- \u041c\u0430\u0441\u0442\u0435\u0440
+sendTorrent.destination.title=\u041a\u0430\u043a \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c %1  \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442(\u044b)?
+message.confirm.share.singular=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0430\u043d.
+MyTorrentsView.category=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f
+sendTorrent.multi.email.body.eachTorrent=\u0414\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f "%1", \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0438\u0436\u0435:\n\n%2\n\n
+MyTorrentsView.completed.info=\u041a\u043e\u043b. \u043f\u0438\u0440\u043e\u0432, \u0441\u043a\u0430\u0447\u0430\u0432\u0448\u0438\u0445 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 (\u043f\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430)
+ConfigView.label.downloadreducalone="\u0415\u0414\u0418\u041d\u0421\u0422\u0412\u0415\u041d\u041d\u041e\u0415" - \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0411\u0415\u0417 \u0434\u0440\u0443\u0433\u0438\u0445 \u043e\u043f\u0446\u0438\u0439 \u043f\u043e\u0434\u043b\u043e\u0433\u0430. *(\u0440\u0435\u0436\u0438\u043c "\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438" \u0431\u0443\u0434\u0435\u044 [...]
+MyTorrentsView.timesinceupload=\u0411\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0420\u0430\u0437\u0434\u0430\u0447\u0438
+TorrentOptionsView.param.max.uploads.when.seeding.enable=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430 \u0441\u043b\u043e\u0442\u043e\u0432 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u0434\u0430\u0451\u0442\u0435
+v3.Share.invite.buddies.prompt=\u041f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0440\u0443\u0437\u0435\u0439, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f
+TableColumn.header.RateIt.info=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 Vuze
+MyTorrentsView.menu.rename.save_path.enter.message.2=\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u0432\u0435\u0434\u0435\u043d, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0438\u043c\u044f \u0437\u0430\u043a\u0430\u0447\u043a\u0438.
+MyTorrentsView.seed_to_peer_ratio=\u0421\u0438\u0434\u044b/\u041b\u0438\u0447\u0435\u0440\u044b
+ConfigView.label.serverportlow=\u0421\u0430\u043c\u044b\u0439 \u043d\u0438\u0436\u043d\u0438\u0439 \u043f\u043e\u0440\u0442
+MyTorrentsView.comment=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439
+MyTorrentsView.shareRatioFake.info=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 [\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430] / [\u0420\u0435\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e].
+swt.update.window.status.done=Ok
+PeersView.BitsAllocatedForUpload=\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u043e \u0431\u0438\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+v3.buddy.prop.catin=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u0443 \u0434\u0440\u0443\u0437\u0435\u0439, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0412\u0430\u043c
+MyTorrentsView.menu.rename.displayed.enter.message.2=\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0441\u0442 \u043d\u0435 \u0432\u0432\u0435\u0434\u0435\u043d, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e.
+MyTorrentsView.trackernextaccess.info=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0442 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+Content.alert.notuploaded.multi.text=%1 \u0412\u0430\u0448\u0435\u0433\u043e \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043d\u0435 \u0440\u043e\u0437\u0434\u0430\u043d\u043e. \u0415\u0441\u043b\u0438 \u0412\u044b %2 \u0441\u0435\u0439\u0447\u0430\u0441, \u043b\u044e\u0434\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043f\u [...]
+v3.buddies.online=\u0412 \u0441\u0435\u0442\u0438 (%1)
+ConfigView.label.noreport=\u041d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440\u0443 (0 \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0438 0 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430)
+ConfigView.label.noReportAuto=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 (\u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441)
+sendTorrent.title=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0414\u0440\u0443\u0433\u0443/\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0435
+MainWindow.about.internet.digitaldj.net=\u0441\u0430\u0439\u0442 digitaldj.net
+MyTorrentsView.AvgAvail.info=\u0421\u0443\u043c\u043c\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439, \u043f\u043e\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0447\u0430\u0441\u0442\u0435\u0439, \u043f\u043e\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u0447\u0438\u0441\u043b\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439
+ConfigView.label.spooftitle=\u041f\u043e\u0434\u043c\u0435\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430
+TableColumn.header.Quality.info=\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 Vuze, \u043a\u0430\u043a \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, HD, SD
+v3.MainWindow.menu.publish.about=\u041e \u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0438\u0438...
+ConfigView.label.fakeuploadsrintelligent=\u0423\u043c\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c (\u0427\u0438\u0442\u0435\u0440\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e)
+ConfigView.label.fakeuploadrm="\u0420\u0435\u0436\u0438\u043c \u0420\u0435\u0439\u0442\u0438\u043d\u0433\u0430" (0-50):
+ConfigView.label.showasseed=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0412\u0430\u0441 \u043a\u0430\u043a \u0441\u0438\u0434\u0430 (100% \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e \u0438 \u0431\u0435\u0437 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u043e\u0431 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438)
+DonationWindow.title=\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0412\u0430\u0448\u0430 \u043f\u043e\u043c\u043e\u0449\u044c!
+ConfigView.connection.group.proxy=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0440\u043e\u043a\u0441\u0438
+MyTorrentsView.pieces.info=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439
+v3.buddies.remove=\u0423\u0431\u0440\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0430
+MyTorrentsView.maxupspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440. \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+Content.alert.notuploaded.quit=\u0432\u044b\u0439\u0442\u0438
+LocaleUtil.column.filename=\u0418\u043c\u044f \u0424\u0430\u0439\u043b\u0430
+ConfigView.label.peernohave=\u041d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043f\u0438\u0440\u0430\u043c \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 (\u043f\u0438\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u0412\u0430\u0441 \u0432\u0438\u0434\u0435\u0442\u044c \u043a\u0430\u043a 0% \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e)
+ConfigView.label.allocatenewfiles=\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b
+sendTorrent.multi.email.body.bottom=\u041e\u043d\u0438 \u043d\u0430\u0447\u043d\u0443\u0442 \u043a\u0430\u0447\u0430\u0442\u044c \u0435\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c Azureus. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442 \u0435\u0449\u0435, \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442 \u043a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044 [...]
+configureWizard.nat.serverlow=\u041d\u0438\u0436\u043d\u0438\u0439 \u043f\u043e\u0440\u0442
+MyTorrentsView.availability=\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c
+swt.update.window.quit=\u0412\u044b\u0445\u043e\u0434
+SystemTray.menu.stopalldownloads=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+Content.alert.notuploaded.button.stop=&\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+MyTorrentsView.tracker.info=\u0421\u0442\u0430\u0442\u0443\u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+Main.download.state.error=o\u0448\u0438\u0431\u043a\u0430
+v3.buddies.dnd.info.dialog.remember=\u041d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043d\u043e\u0432\u0430
+ConfigView.label.bindip.info=\u041d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440, '192.168.1.2' or 'eth0' (\u0442\u0435\u043a\u0443\u0449\u0435\u0435: %1)
+DonationWindow.text.hours=\u0447\u0430\u0441\u043e\u0432
+ConfigView.label.fakeuploadmultipliermaxtxt=x \u0420\u0430\u0437\u0434\u0430\u0447\u0443
+message.confirm.invite.singular=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0414\u0440\u0443\u0436\u0435\u0441\u043a\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0430\u043d. \u0420\u0430\u0441\u0441\u043b\u0430\u0431\u044c\u0442\u0435\u0441\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0432\u0430\u0448\u0438\u0445 \u0434\u0440\u0443\u0437\u0435\u0439.
+MyTorrentsView.comment.info=\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0434\u043b\u044f \u0437\u0430\u043a\u0430\u0447\u043a\u0438
+ConfigView.label.maxclients=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 (0 : \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e) 
+ConfigView.section.connection.advanced.IPTOS=\u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (TOS) \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 [see http://azureus.aelitis.com/wiki/index.php/AdvancedNetworkSettings]
+PeersView.B=\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+v3.activity.header.friend.requests.accepted=\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 - \u041f\u0440\u0438\u043d\u044f\u0442\u044b\u0435
+MyTorrentsView.bad_avail_time=\u041f\u043e\u043b\u043d\u0430\u044f \u043a\u043e\u043f\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u044f\u043b\u0430\u0441\u044c
+MyTorrentsView.date_added.menu.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u0430\u0442\u0443
+MyTorrentsView.peersources.info=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0438\u0440\u043e\u0432, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u0438\u0440\u0430\u043c\u0438
+ConfigView.section.file.confirm_data_delete=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0441\u0442\u0438\u0440\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445
+window.welcome.version=2.5.0.0
+MyTorrentsView.completion.info=\u0421\u0442\u0430\u0442\u0443\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0432 %
+MainWindow.about.internet.Azureushomepage=\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 Azureus
+ConfigView.section.style.verticaloffset=\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 (\u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 GTK)
+MyTorrentsView.timesinceupload.info=\u0412\u0440\u0435\u043c\u044f, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u043e\u0442\u0434\u0430\u043d\u044b \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443
+TableColumn.header.activityAvatar=\u0410\u0432\u0430\u0442\u0430\u0440
+MyTorrentsView.date_completed=\u0414\u0430\u0442\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+MyTorrentsView.upfake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u043e \u0440\u043e\u0437\u0434\u0430\u043d\u043e
+TableColumn.header.Rating_global.info=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443
+MyTorrentsView.size=\u0420\u0430\u0437\u043c\u0435\u0440
+v3.buddy.prop.un=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+DonationWindow.text.footer=\u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439 \u043d\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c, \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f, \u0441\u0441\u [...]
+v3.dialog.cnmanage.intro=\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043d\u0438\u0436\u0435 \u043a\u0430\u043a\u0438\u0435 \u0441\u0435\u0442\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0412\u044b \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0432 \u043c\u0435\u043d\u044e "\u0421\u0435\u0442\u0438 HD"
+MyTorrentsView.done=\u0413\u043e\u0442\u043e\u0432\u043e
+ConfigView.label.fakeuploadrmtxt=:1 (\u0420\u043e\u0437\u0434\u0430\u043d\u043e:\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e) \u0438 
+MyTorrentsView.secondsseeding=\u0420\u0430\u0437\u0434\u0430\u0451\u043c \u0443\u0436\u0435
+v3.Share.optional.message=\u041d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0435 \u0447\u0435\u0440\u0435\u0437 \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f (\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 140 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432):
+MyTorrentsView.AvgAvail=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u0435\u0439
+message.confirm.share.invite.plural=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0430\u043d. \u0420\u0430\u0441\u0441\u043b\u0430\u0431\u044c\u0442\u0435\u0441\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u04 [...]
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.message=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438
+ConfigView.label.downloadreduc=\u0423\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 (%):
+ConfigView.label.fakeuploadspeedratiortxt=:1 (\u0420\u043e\u0437\u0434\u0430\u043d\u043e:\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e) \u0438
+MyTorrentsView.trackername=\u0422\u0440\u0435\u043a\u0435\u0440
+v3.buddies.disabled.text._mac=\u0412\u044b \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d Friends (\u0414\u0440\u0443\u0437\u044c\u044f), \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0412\u0430\u043c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0438\u043b\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0438\u043b\u0438 \u0437\u0430\u043f [...]
+sendTorrent.finish.button.startEMail=\u0421\u043e\u0437\u0434\u0430\u0442\u044c E-Mail
+ConfigView.section.style.sortDefaultAscending=\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0441\u0442\u043e\u043b\u0431\u0446\u044b \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u044e
+MyTorrentsView.down=\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e
+message.confirm.invite.plural=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0414\u0440\u0443\u0436\u0435\u0441\u043a\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0441\u043b\u0430\u043d. \u0420\u0430\u0441\u0441\u043b\u0430\u0431\u044c\u0442\u0435\u0441\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0432\u0430\u0448\u0438\u0445 \u0434\u0440\u0443\u0437\u0435\u0439.
+MyTorrentsView.swarm_average_completion=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u0438
+swt.update.window.ok=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c
+swt.update.window.restart=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
+ConfigView.connection.group.advanced=\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435
+Tab.closeHint=(\u041d\u0430\u0436\u043c\u0438\u0442\u0435 'Esc' \u0434\u043b\u044f \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f)
+ConfigView.label.popup.show.button=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c
+v3.buddies.dnd.info.dialog.ok=\u041e\u041a
+ConfigView.label.fakeuploadspeedratiomaxrtxt=:1 (\u0420\u0430\u0437\u0434\u0430\u0447\u0430:\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430). \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e: \u043c\u0435\u0436\u0434\u0443
+ConfigView.label.splashpreview=\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440
+ConfigView.label.fakeuploadrmtxt1=\u043c\u0435\u0436\u0434\u0443
+MyTorrentsView.peers.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u043b\u0438\u0447\u0435\u0440\u043e\u0432 (\u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0447\u0435\u0440\u043e\u0432 [0, \u0435\u0441\u043b\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e])
+xmlhttp.config.group.logging=\u0416\u0443\u0440\u043d\u0430\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+v3.Share.invitees=\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u043d\u044b\u0435
+deletetorrent.message2=\n\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c?
+deletetorrent.message1=\u0412\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0435\u0441\u044c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0422\u041e\u0420\u0420\u0415\u041d\u0422-\u0444\u0430\u0439\u043b:\n
+MyTorrentsView.menu.rename.save_path.enter.message=\u0412\u044b\u0431\u0435\u0440\u0438 \u043d\u043e\u0432\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 .
+MyTorrentsView.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
+sendTorrent.multi.email.subject=\u041c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0412\u0430\u043c \u0441\u043a\u0430\u0447\u0430\u0442\u044c %1
+MyTorrentsView.eta=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c
+ConfigView.label.manpeersrc=\u041f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c 'x' \u043f\u0438\u0440\u043e\u0432 (100-1000):
+MyTorrentsView.swarm_average_speed.info=\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u0438\u0440\u043e\u0432
+xmlhttp.config.group.logging.description=\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u0443\u0434\u0430 \u0412\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b:
+MyTorrentsView.completed=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+ConfigView.label.fakeuploadrmmaxtxt=:1 (\u0420\u043e\u0437\u0434\u0430\u043d\u043e:\u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e)
+ConfigView.section.interface.confirm_torrent_removal.tooltip=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u0438\u0437 "\u041c\u043e\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b"
+DonationWindow.options.nodonate=\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435, \u043d\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u0442\u044c.
+MyTorrentsView.up=\u041e\u0442\u0434\u0430\u043d\u043e
+ConfigView.label.fakeuploadspeedratiomaxstxt=KB/s \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 (\u043c\u0430\u043a\u0441. \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b)
+MyTorrentsView.secondsseeding.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+MyTorrentsView.downfake.info=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445
+ConfigView.label.noreportseed=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0412\u0430\u0441 \u043a\u0430\u043a \u0441\u0438\u0434\u0430 (100% \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e)
+v3.buddies.disabled.text._windows=\u0412\u044b \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043f\u043b\u0430\u0433\u0438\u043d Friends (\u0414\u0440\u0443\u0437\u044c\u044f), \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0412\u0430\u043c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0438\u043b\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0438\u043b\u0438 \u0437\u0430\u [...]
+MyTorrentsView.savepath=\u041c\u0435\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+v3.buddy.set.catout=\u041f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e
+MainWindow.menu.help.faq=FAQ        /\u0420\u0443\u0441\u0441\u043a\u0438\u0439 \u0441\u0430\u0439\u0442 \u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435 AZUREUS.NAROD.NNOV.RU/
+v3.MainWindow.menu.publish.new=\u041f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
+v3.activity.header.friend.requests.foryou=\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 - \u0412\u0430\u043c
+ConfigView.section.file.write_block_limit=\u041c\u0430\u043a\u0441. \u0434\u043b\u0438\u043d\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438\n[0: \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u0420\u0430\u0437\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u0432 %1
+MyTorrentsView.networks.info=\u0421\u0435\u0442\u0438, \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0442\u0438\u043f\u0430 \u043f\u0438\u0440<->\u043f\u0438\u0440
+DonationWindow.text.downloaded=(\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e)
+v3.MainWindow.recentDL.library=\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 >>
+v3.buddy.menu.remove=\u0423\u0431\u0440\u0430\u0442\u044c \u0414\u0440\u0443\u0433\u0430
+MainWindow.menu.help.abouthack=\u041e SB-Innovation Hack ...
+MyTorrentsView.menu.rename.displayed_and_save_path.enter.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0438 \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+MyTorrentsView.date_added.info=\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+message.confirm.share.plural=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430 \u043f\u043e\u0441\u043b\u0430\u043d.
+swt.update.window.status.downloading=\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f
+v3.buddies.add.to.share=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u043d\u0438\u043c
+MyTorrentsView.downspeed=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+v3.activity.buddy-request.multi=\u041a \u0412\u0430\u043c \u043f\u0440\u0438\u0448\u0435\u043b \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 [#%3] \u043e\u0442 %1
+iconBar.sendTorrent.tooltip=\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 E-Mail/\u0421\u0430\u0439\u0442
+MyTorrentsView.remaining.info=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0433\u0440\u0443\u0437\u0438\u0442\u044c
+ConfigView.label.noupafterdlremovetorrent=\u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u0435\u0440\u0435\u0442\u044c .torrent-\u0444\u0430\u0439\u043b
+ConfigView.section.logging.log2component=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u043a\u0435\u0440\u0430
+swt.update.window.columns.name=\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435
+swt.update.window.status.restartMaybeNeeded=\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a
+deletedata.message2=\n\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b \u0432 \u0441\u0432\u043e\u0451\u043c \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0438\u0438?
+deletedata.message1=\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0442\u0435\u0440\u0435\u0442\u044c '%1'?\n
+Content.alert.notuploaded.multi.title=\u041e\u0442\u0434\u0430\u0447\u0438 \u041d\u0435 \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b
+v3.activity.share-content.no-msg=%1 \u043f\u043e\u0434\u0435\u043b\u0438\u043b\u0441\u044f %2 \u0441 \u0412\u0430\u043c\u0438
+v3.activity.buddy-request.accept=\u041f\u0440\u0438\u043d\u044f\u0442\u044c
+Main.download.state.downloading=\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430
+Content.alert.notuploaded.text=\u0420\u0430\u0437\u0434\u0430\u0447\u0430  of '%1' \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u0415\u0441\u043b\u0438 \u0442\u044b %2 \u0441\u0435\u0439\u0447\u0430\u0441, \u043b\u044e\u0434\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u0442\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u0430\u0447\u0430\u0442\u044c \ [...]
+ConfigView.label.noReportCustom=\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e
+window.uiswitcher.AdvancedUI.text=* \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c \u0438\u0441\ [...]
+v3.MainWindow.button.sendtofriend=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c
+MyTorrentsView.upspeedfake.info=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438.
+ConfigView.label.onlyafter50=(\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043c\u0435\u043d\u0435\u0435 0.5)
+swt.update.window.restartLater=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043f\u043e\u0437\u0436\u0435
+ConfigView.label.splash=\u0417\u0430\u0441\u0442\u0430\u0432\u043a\u0430
+v3.MainWindow.button.newtag.share=\u041d\u043e\u0432\u044b\u0439! \u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u043c
+MyTorrentsView.seeds.fullcopycalc=%2 \u043f\u043e\u043b\u043d\u044b\u0445 \u043a\u043e\u043f\u0438\u0439 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u0443 %1 \u043f\u0438\u0440\u043e\u0432
+DonationWindow.text.uploaded=(\u0440\u043e\u0437\u0434\u0430\u043d\u043e)
+v3.dialog.cnclose.info1=\u0412\u044b \u0437\u0430\u043a\u0440\u044b\u043b\u0438 \u0421\u0435\u0442\u044c HD
+v3.dialog.cnclose.info2=\u0415\u0441\u043b\u0438 \u0412\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043e\u0442\u043a\u0440\u044b\u0442\u044c \u044d\u0442\u0443 \u0421\u0435\u0442\u044c HD, \u0442\u043e \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u043c\u0435\u043d\u044e "\u0421\u0435\u0442\u0438 HD" \u0432 \u0432\u0435\u0440\u0445\u0443 \u044d\u043a\u0440\u0430\u043d\u0430.
+ConfigView.label.restartmessage=\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442 Azureus \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438 \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0430!
+sendTorrent.one.email.body=\u0414\u043b\u044f \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044f  "%1", \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0438\u0436\u0435:\n\n%2\n\n"%1"  \u043d\u0430\u0447\u043d\u0451\u0442 \u043a\u0430\u0447\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c Azureus. \u0415\u0441\u043b\u04 [...]
+MyTorrentsView.maxuploads=\u041c\u0430\u043a\u0441. \u043a\u043e\u043b. \u0441\u043b\u043e\u0442\u043e\u0432 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+v3.activity.share-content=%1 \u043f\u043e\u0434\u0435\u043b\u0438\u043b\u0441\u044f %2 \u0441 \u0412\u0430\u043c\u0438. %3 <A HREF="%4" TITLE="%5">\u0433\u043e\u0432\u043e\u0440\u0438\u0442...</A>
+MyTorrentsView.donefake.info=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f
+DonationWindow.options.later=\u042f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c Azureus \u043f\u043e\u0434\u043e\u043b\u044c\u0448\u0435 \u043f\u0435\u0440\u0435\u0434 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435\u043c.
+MyTorrentsView.peersources=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0438\u0440\u043e\u0432
+MyTorrentsView.totalspeed.info=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u043f\u0438\u0440\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0435\u0441\u0442\u044c \u0441\u0432\u044f\u0437\u044c
+ConfigView.label.fakeuploadrmcontinue=\u041a\u043e\u0433\u0434\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0440\u0430\u0437\u0434\u0430\u0447, \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043f\u043e\u0432\u044b\u0448\u0430\u0442\u044c \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430 \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u04 [...]
+MyTorrentsView.OnlyCDing4=\u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u0434\u0438\u0440\u0443\u0435\u043c \u0443\u0436\u0435
+sendTorrent.finish.title=\u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e
+MainWindow.menu.community.add_friends=&\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0437\u0435\u0439
+ConfigView.label.safefakeupload=\u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0430\u044f \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0430\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0430
+v3.Share.header=\u0414\u0435\u043b\u0438\u0442\u044c\u0441\u044f
+MyTorrentsView.upfake.info=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0438\u0440\u0430\u043c.
+MainWindow.about.internet.SB-Innovation=\u0414\u043e\u043c\u0430\u0448\u043d\u044f\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 SB-Innovation
+ConfigView.label.safefakeupload1=\u041d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0442\u044c \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0443\u044e \u0440\u0430\u0437\u0434\u0430\u0447\u0443 \u0431\u043e\u043b\u0435\u0435, \u0447\u0435\u043c 
+ConfigView.label.safefakeupload2=x [\u0420\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430]. \u0420\u0430\u0437\u0434\u0430\u0447\u0430 = [\u0420\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430] x 'A' , \u0433\u0434\u0435 A = \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0435 \u0412\u0430\u043c\u0438 \u0447\u0438\u0441\u043b\u043e
+MyTorrentsView.SeedingRank=\u041f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+ConfigView.section.file.check_piece_limit.explain=\u0415\u0441\u043b\u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0451\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b "\u043d\u0430 \u043b\u0435\u0442\u0443" \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 (\u043f\u0440\u0438 \u043c\u043d\u043e\u0433\ [...]
+ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0431\u0435\u0437 \u043f\u043e\u043a\u0430\u0437\u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043e\u043a\u043d\u0430 Azureus.
+v3.MainWindow.recentDL=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 %1 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u043a
+ConfigView.label.serverportrange=\u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u043e\u0440\u0442\u043e\u0432
+ConfigView.label.fakeuploadrmintelligent=\u0423\u043c\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c (\u0427\u0438\u0442\u0435\u0440\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438)
+ConfigView.label.fakeuploadspeedratiostxt1=\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c: \u043c\u0435\u0436\u0434\u0443
+ConfigView.label.oldpollingstyle=\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u0441\u0435\u0442\u0438 - \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0426\u041f\u0423, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u043f\u0440\u0438 \u0447\u0430\u0441\u0442\u043e\u043c \u0440\u0430\u0441\u0441\u043e\u0435\u0434\u0438\ [...]
+swt.update.window.header=\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b :
+v3.dialog.cnclose.subtitle=\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435
+sendTorrent.destination.byEmail=E-mail'\u043e\u043c
+MyTorrentsView.confirm_torrent_removal=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0442\u043e\u0440\u0440\u0435\u043d\u0442?\n
+MyTorrentsView.status.info=\u0427\u0442\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0434\u0435\u043b\u0430\u0435\u0442
+ConfigView.section.style.alternateTablePainting=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u044b (\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u04 [...]
+message.intro.friends=\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0434\u0440\u0443\u0437\u0435\u0439. \u0414\u0435\u043b\u0438\u0442\u0435\u0441\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438. \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0439\u0442\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435.
+MyTorrentsView.peers=\u041b\u0438\u0447\u0435\u0440\u044b
+MyTorrentsView.maxdownspeed=\u041c\u0430\u043a\u0441. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+xmlhttp.config.option.debug.deserialisation=\u0412\u0445\u043e\u0434\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 XML
+v3.AddFriends.header.message=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0437\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u0438\u043c\u044b\u043c\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438
+v3.Share.add.edit.buddy=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c/\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0437\u0435\u0439
+ConfigView.label.stopifswarmdrops=\u041f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u043e\u0434\u043b\u043e\u0433 \u043a\u043e\u0433\u0434\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u0438\u0440\u043e\u0432 = 0
+v3.buddies.disabled.title=\u041f\u043b\u0430\u0433\u0438\u043d Friends (\u0414\u0440\u0443\u0437\u044c\u044f) \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d
+ConfigView.section.connection.advanced.IPTOS.tooltip=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0442\u0440\u0430\u0444\u0444\u0438\u043a\u0430  / \u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (TOS) \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 IP \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432.\nVuze \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u [...]
+ConfigView.section.security.vuze.login=\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0432 Vuze \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438
+MyTorrentsView.date_added=\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f
+DonationWindow.thanks.text=\u0412\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 Azureus \u0436\u0435\u043b\u0430\u0435\u0442 \u0412\u0430\u0441 \u043f\u043e\u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u0438\u0442\u044c \u0437\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443!
+ConfigView.label.manpeersrctxt== x = \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0438\u0440\u043e\u0432 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f
+MyTorrentsView.menu.removeand=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438...
+MyTorrentsView.priority=\u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442
+ConfigView.label.azureusspoof1=\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Azureus \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0435 \u0444\u0430\u0439\u043b AzureusSpoof.properties (\u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u0438\u0442\u0435 Azureus, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0442\u0443\ [...]
+ConfigView.label.azureusspoof2=\u0410\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043e ? (true-\u0434\u0430, false-\u043d\u0435\u0442) = 
+ConfigView.label.azureusspoof3=\u0432\u0435\u0440\u0441\u0438\u044f :
+ConfigView.section.proxy.description=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0430\u0446\u0438\u044e \u0442\u0440\u0435\u043a\u0435\u0440\u0430 \u0438 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u0451\u043c\u0430.\n\u042d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442 SOCKS-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u043f\u0440\u043e\u043a\u0441 [...]
+ConfigView.section.style.useNewStyleMessageBox=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u043e\u043a\u043e\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439
+v3.AddFriends.header=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0414\u0440\u0443\u0437\u0435\u0439
+ConfigView.section.interface.confirm_torrent_removal=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+ConfigView.label.fakeuploadadd=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0412\u0430\u0448 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043a \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043c\u0443 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (*\u0440\u0435\u0436\u0438\u043c "\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u [...]
+ConfigView.section.style.SeparateFilesViewRenameRetarget=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u043c\u0435\u0436\u0434\u0443  "\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c" \u0438 "\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c" \u0432 \u043c\u0435\u043d\u044e \u043e\u043f\u0446\u0438\u0439 \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 [...]
+message.prompt.add.friends=\u041a\u043b\u0438\u043a\u043d\u0438\u0442\u0435 \u0438\u043a\u043e\u043d\u043a\u0443 \u0434\u0440\u0443\u0433\u0430 \u0432\u043d\u0438\u0437\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430
+MyTorrentsView.status=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+ConfigView.label.enable_auto_max_connections=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u0443\u044e \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u0447\u0442\u043e\u0431\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0430\u043a\u0441. \u044 [...]
+MyTorrentsView.menu.sendTorrent=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0414\u0440\u0443\u0433\u0443/\u0421\u0430\u0439\u0442\u0443..
+SystemTray.menu.startalldownloads=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+v3.Share.buddies=\u0414\u0440\u0443\u0437\u044c\u044f
+ConfigView.label.spooftitlefuckseba=\u041f\u043e\u0434\u043c\u0435\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (by ghostf**ker)
+ConfigView.label.serverporthigh=\u0421\u0430\u043c\u044b\u0439 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u043f\u043e\u0440\u0442
+v3.activity.buddy-request=\u041a \u0412\u0430\u043c \u043f\u0440\u0438\u0448\u0435\u043b \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 \u043e\u0442 %1
+MyTorrentsView.shareRatio=\u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
+ConfigView.label.fakeofffakeaddedtoreal=\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439 \u043e\u0442\u0447\u0435\u0442 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439 \u043e\u0442\u0447\u0435\u0442 \u0438 \u0434\u0 [...]
+MyTorrentsView.menu.rename.save_path.enter.title=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+sendTorrent.finish.button.toClipboard=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0411\u0443\u0444\u0435\u0440 \u041e\u0431\u043c\u0435\u043d\u0430
+swt.update.window.status.restartNeeded=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a!
+v3.buddies.remove.buddy.dialog.title=\u0423\u0431\u0440\u0430\u0442\u044c
+Peers.column.RecentUpDownRatio.info=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 "\u0420\u043e\u0437\u0434\u0430\u043d\u043e : \u0417\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e" \u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u0438\u0440\u0430
+window.uiswitcher.bottom.text=\u0412\u0430\u0448 \u0432\u044b\u0431\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0435\u0433\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u0436\u0430\u0442\u0438\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
+ConfigView.label.noReportCustomAdditional=% \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e
+configureWizard.nat.serverhigh=\u0412\u0435\u0440\u0445\u043d\u0438\u0439 \u043f\u043e\u0440\u0442
+message.confirm.share.invite.singular=\u041e\u0442\u043b\u0438\u0447\u043d\u043e!  \u0412\u0430\u0448 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0440\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0430\u043d. \u0420\u0430\u0441\u0441\u043b\u0430\u0431\u044c\u0442\u0435\u0441\u044c \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u [...]
+MyTorrentsView.health=\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+Content.alert.notuploaded.title=\u041e\u0442\u0434\u0430\u0447\u0438 \u041d\u0435 \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u044b
+v3.dialog.cnclose.title=%1 \u0437\u0430\u043a\u0440\u044b\u0442
+MyTorrentsView.maxdownspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.section.proxy.description2=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0430\u0446\u044e \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0440\u0435\u043a\u0435\u0440\u0430.\n\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c  [...]
+MyTorrentsView.filesdone=\u0424\u0430\u0439\u043b\u043e\u0432 \u0441\u043a\u0430\u0447\u0430\u043d\u043e
+ConfigView.interface.start.library=\u0421\u0442\u0430\u0440\u0442\u043e\u0432\u0430\u0442\u044c \u0432 \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435
+sendTorrent.finish.byEmail=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435, \u043f\u043e e-mail:
+ConfigView.label.fakeuploadspeedratiortxt1=\u043c\u0435\u0436\u0434\u0443
+ConfigView.section.logging.log4component=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u0438\u0451\u043c\u0430
+MyTorrentsView.seeds.info=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0434\u043e\u0432 (\u0432\u0441\u0435\u0433\u043e \u0441\u0438\u0434\u043e\u0432 [0, \u0435\u0441\u043b\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e])
+webui.restart.info=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435! \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 *, \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+MyTorrentsView.seed_to_peer_ratio.info=\u041e\u0431\u0449\u0435\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0438\u0434\u043e\u0432/\u043b\u0438\u0447\u0435\u0440\u043e\u0432 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435
+v3.Share.add.buddy.new=\u041d\u043e\u0432\u044b\u0435 \u0434\u0440\u0443\u0437\u044c\u044f:
+v3.MainWindow.menu.publish.mine=\u0412\u0430\u0448 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442
+ConfigView.label.noreportleech=\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0412\u0430\u0441 \u043a\u0430\u043a \u043b\u0438\u0447\u0435\u0440\u0430 (0% \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e)
+v3.Share.add.buddy=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0437\u0435\u0439
+ConfigView.label.disablenoupload4lan=\u0412\u044b\u043a\u043b\u044e\u0447\u0430\u0442\u044c "\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438" \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 \u0432 LAN
+ConfigView.label.enableupdate=\u0412\u0441\u0435\u0433\u0434\u0430 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0443 "\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440"
+MyTorrentsView.pieces=\u0427\u0430\u0441\u0442\u0435\u0439
+v3.buddies.dnd.info.dialog.title=\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0420\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435
+ConfigView.section.file.confirm_data_delete.tooltip=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435\u0441\u0442\u0438\u0440\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0438 \u0441\u0442\u0435\u0440\u0435\u0442\u044c"
+ConfigView.label.fakeuploadspeedratiorrstxt=KB/s \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u0438
+v3.Share.disclaimer.link=\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435...
+MyTorrentsView.maxupspeed.info=\u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u044d\u0442\u043e\u0433\u043e \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+sendTorrent.finish.byHTML=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435, \u0432 \u0412\u0430\u0448\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443:
+v3.buddy.prop.catout=\u0412\u0430\u0448\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438, \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0412\u0430\u0448\u0438 \u0434\u0440\u0443\u0437\u044c\u044f
+MyTorrentsView.totalspeed=\u041e\u0431\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c
+window.welcome.title.2304=\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 Vuze 2.3.0.4
+v3.activity.buddy-linkup=\u0412\u044b \u0438 %1 \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0440\u0443\u0437\u044c\u044f
+ConfigView.section.logging.log3type=\u041e\u0448\u0438\u0431\u043a\u0438
+MyTorrentsView.remaining=\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c
+Content.alert.notuploaded.button.continue=&\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0441\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+ConfigView.label.stopRatio=\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442\u043e\u043c \u0444\u0430\u043a\u0442\u043e\u0440\u0435 \u0440\u0430\u0437\u0434\u0430\u0447
+v3.buddy.menu.viewprofile=\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u0440\u043e\u0444\u0438\u043b\u044c
+TableColumn.header.Info=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f
+v3.activity.buddy-invited.multi=\u0412\u044b \u043f\u043e\u0441\u043b\u0430\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043b\u044e\u0434\u044f\u043c:\n%1
+Content.alert.notuploaded.stop=\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+ConfigView.label.fakeuploadmultipliertxt=x \u0420\u0430\u0437\u0434\u0430\u0447\u0443 \u0438
+ConfigView.label.stopafterxhourstxt=\u0447\u0430\u0441\u043e\u0432 (2 \u0446\u0438\u0444\u0440\u044b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e), \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043d\u0435 \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u044b
+v3.buddy.prop.dn=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f
+v3.buddies.dnd.info.dialog.text=\u0412\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0420\u0430\u0441\u0448\u0430\u0440\u0438\u0432\u0430\u043d\u0438\u0435. \u0412\u0430\u0448 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\ [...]
+MyTorrentsView.menu.rename.displayed_and_save_path=\u041f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0438 \u043f\u0443\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f
+MyTorrentsView.networks=\u0421\u0435\u0442\u0438
+v3.activity.buddy-invited=\u0412\u044b \u043f\u043e\u0441\u043b\u0430\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0434\u0440\u0443\u0436\u0431\u0443 \u043a %1.
+ConfigView.label.downloadreducmix="\u0421\u041e\u0412\u041c\u0415\u0421\u0422\u041d\u041e\u0415" - \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0412\u041c\u0415\u0421\u0422\u0415 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0440\u0435\u0436\u0438\u043c\u0430\u043c\u0438 ("\u0420\u0435\u0436\u0438\u043c \u0420\u0435\u0439\u0442\u0438\u043d\u0433\u0430" \u0438\u043b\u0438 "\u0423\u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u0420\u0430\u0437\u [...]
+ConfigView.label.updatefaster=\u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u0430 (\u0432 1-20 \u0440\u0430\u0437):
+MyTorrentsView.timesincedownload.info=\u0412\u0440\u0435\u043c\u044f, \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u0441 \u0442\u0435\u0445 \u043f\u043e\u0440, \u043a\u0430\u043a \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u043a\u0430\u0447\u0435\u043d\u044b \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0443
+v3.buddy.set.catin=\u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e \u043e\u0442 \u0434\u0440\u0443\u0433\u0430
+azbuddy.ui.dialog.disable.text=\u0412\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 "\u0414\u0440\u0443\u0437\u044c\u044f" \u043f\u043e\u043c\u0435\u0448\u0430\u0435\u0442 \u0412\u0430\u043c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 \u041f\u0430\u043d\u0435\u043b\u044c \u0414\u0440\u0443\u0437\u0435\u0439 \u0432\u043d\u0438\u0437\u0443 \u04 [...]
+xmlhttp.config.option.debug.serialisation=\u0412\u044b\u0445\u043e\u0434\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 XML
+MyTorrentsView.trackernextaccess=\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u043c
+v3.buddy.prop.on=\u041e\u043d-\u043b\u0430\u0439\u043d
+MainWindow.about.internet.featurerequests=\u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435
+DonationWindow.options.donate=\u042f \u0445\u043e\u0447\u0443 \u043f\u043e\u043c\u043e\u0447\u044c \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u043f\u043e\u043a\u0430\u0436\u0438\u0442\u0435 \u043c\u043d\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439.
+ConfigView.label.noupload=\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438 (\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u0430\u044f, \u0435\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430)
+sendTorrent.one.email.subject=\u041c\u042b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0412\u0430\u043c \u0441\u043a\u0430\u0447\u0430\u0442\u044c %1
+v3.library.infobar.text2=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0412\u0438\u0434\u0430 \u0432 \u043f\u0430\u043d\u0435\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u044b\u0448\u0435.
+v3.library.infobar.text1=\u0418\u0449\u0438\u0442\u0435 \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0439 \u0412\u0438\u0434?
+v3.buddy.prop.pc=\u041e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u0430
+DonationWindow.ok=\u041e\u041a
+ConfigView.label.group.fake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439 \u043e\u0442\u0447\u0435\u0442 \u0434\u043b\u044f \u0442\u0440\u0435\u043a\u0435\u0440\u043e\u0432
+MyTorrentsView.secondsdownloading=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0423\u0436\u0435
+ConfigView.section.style.colorScheme=\u0421\u0445\u0435\u043c\u0430 \u0446\u0432\u0435\u0442\u043e\u0432\n - \u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0442\u0430
+xmlhttp.config.option.log_to_console=\u041a\u043e\u043d\u0441\u043e\u043b\u044c (*)
+Main.download.state.checking=\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430
+MyTorrentsView.seeds=\u0421\u0438\u0434\u044b
+ConfigView.label.downloadreductxt=\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0442\u044c \u043e\u0442\u0447\u0435\u0442 \u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043d\u0430
+ConfigView.label.fakeuploadmultipliertxt1=\u043c\u0435\u0436\u0434\u0443
+ConfigView.label.stopafterxhours=\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u0442\u043e\u0440\u0440\u0435\u043d\u0442 \u043f\u043e\u0441\u043b\u0435
+v3.buddies.remove.buddy.dialog.text=\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0431\u0440\u0430\u0442\u044c %1 \u043a\u0430\u043a \u0414\u0440\u0443\u0433\u0430?
+ConfigView.label.slowconnect=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435.\n\u041f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0445 \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u [...]
+MyTorrentsView.filesdone.info="\u0424\u0430\u0439\u043b\u043e\u0432 \u0441\u043a\u0430\u0447\u0430\u043d\u043e/\u0412\u0441\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432" \u0438\u043b\u0438 "\u041d\u0435\u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043a\u0430\u0447\u0430\u043d\u043e (\u0424\u0430\u0439\u043b\u044b \u0441\u043a\u0430\u0447\u0435\u043d\u044b)/\u0412\u0441\u0435\u0433\u043e \u043d\u0435\u043f\u0440\u [...]
+swt.update.window.status.failed=\u041d\u0435 \u0443\u0434\u0430\u0435\u0442\u0441\u044f
+ConfigView.label.dontsendcompletedflag=\u041d\u0435 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440\u0443 \u0441\u0438\u0433\u043d\u0430\u043b "\u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e" \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430
+v3.activity.header.share.requests=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u043e\u0432
+ConfigView.section.interface.display.add_torrents_silently=\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u044b \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435
+MyTorrentsView.upspeedfake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438
+TableColumn.header.videoLength.info=\u0412\u0440\u0435\u043c\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435\u043e-\u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 Vuze
+MyTorrentsView.secondsdownloading.info=\u041e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+v3.Share.menu=\u041a\u043e\u043d\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f
+xmlhttp.config.option.debug.method_lookup=\u041c\u0435\u0442\u043e\u0434 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f
+xmlhttp.legacy.error=\u042d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430 XML/HTTP \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 Vuze - \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0430\u043f\u0433\u0440\u0435\u0439\u0434\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u043d\u0430 \u0441\u0432\u0435\u04 [...]
+ConfigView.label.fakeuploadmultiplier="\u0423\u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438" (0-50): (*\u0440\u0435\u0436\u0438\u043c "\u041d\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438" \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d)
+v3.buddy.prop.lupd=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e
+ConfigView.label.fakeuploadspeedratiorrs2txt=KB/s \u043d\u0430 \u0442\u043e\u0440\u0440\u0435\u043d\u0442
+ConfigView.label.override=(\u041f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430)
+xmlhttp.config.option.debug.method_invocation=\u041c\u0435\u0442\u043e\u0434 \u0430\u043a\u0442\u0438\u0432\u0438\u0437\u0430\u0446\u0438\u0438
+v3.chat.offline=%1 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u0432 \u0441\u0435\u0442\u0438, \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0412\u0430\u0448\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0432 \u0441\u0435\u0442\u044c.
+MyTorrentsView.sendto.info=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0440\u0443\u0433\u0443 \u0438\u043d\u0444\u043e \u043e \u0444\u0430\u0439\u043b\u0435
+ConfigView.label.announceport.tooltip=\u0418\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u043a\u0435\u0440 \u043e \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e\u0440\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\ [...]
+ConfigView.label.popup.show=\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c)
+ConfigView.label.updatefastertxt== 'x'. \u0414\u0435\u043b\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f, \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0435\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c, \u043d\u0430 'x'
+DonationWindow.thanks.title=\u0421\u043f\u0430\u0441\u0438\u0431\u043e!
+ConfigView.connection.group.advanced.tooltip=http://azureus.aelitis.com/wiki/index.php/AdvancedNetworkSettings
+ConfigView.section.logging.log0component=\u041e\u0431\u0449\u0435\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
+DonationWindow.ok.waiting=\u041e\u0436\u0438\u0434\u0430\u043d\u0438\u0435...
+swt.update.window.columns.install=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c
+MyTorrentsView.priority.info=\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0442\u043e\u0440\u0440\u0435\u043d\u0442\u0430
+TableColumn.header.Rating_global=\u0420\u0435\u0439\u0442\u0438\u043d\u0433
+MyTorrentsView.shareRatioFake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u044b\u0439 \u0420\u0435\u0439\u0442\u0438\u043d\u0433 \u041e\u0431\u043c\u0435\u043d\u0430
+sendTorrent.destination.byHTML=blog'\u043e\u043c, \u0438\u043b\u0438 \u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u043e\u0439
+v3.MainWindow.button.share=\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c
+v3.buddies.friends=\u0414\u0440\u0443\u0437\u044c\u044f
+MyTorrentsView.donefake=\u041f\u043e\u0434\u043b\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e
+MyTorrentsView.commenticon.info=\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u0435\u0441\u043b\u0438 \u0443 \u0437\u0430\u043a\u0430\u0447\u043a\u0438 \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 
+ConfigView.label.peerfake=\u041f\u0440\u0435\u043a\u0440\u0430\u0442\u0438\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043b\u043e\u0436\u043d\u043e\u0439 \u0440\u0430\u0437\u0434\u0430\u0447\u0438, \u043a\u043e\u0433\u0434\u0430 \u0412\u044b \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u044b \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c \u0441
+MyTorrentsView.timesincedownload=\u0411\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0438
+MyTorrentsView.swarm_average_completion.info=\u0421\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0440\u0435\u0434\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u0438\u0440\u043e\u0432
+v3.Share.disclaimer=\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0418 \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0412\u044b \u0434\u0435\u043b\u0438\u0442\u0435\u0441\u044c, \u0438 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u044b.
+DonationWindow.text=\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e Azureus - \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435,\n\u043e\u043d \u0441\u0442\u043e\u0438\u0442 \u043d\u0430\u043c \u043c\u0430\u0441\u0441\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u0442\u0440\u0443\u0434\u043d\u043e\u0439 \u0440\u04 [...]
+Main.download.state.stopped=\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
+xmlhttp.config.group.debug.description=\u042d\u0442\u043e\u0442 \u0440\u0430\u0437\u0434\u0435\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u0432\u043e\u0434\u0430 \u043d\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043 [...]
diff --git a/org/gudy/azureus2/internat/MessagesBundle_sk_SK.properties b/org/gudy/azureus2/internat/MessagesBundle_sk_SK.properties
index 209a04d..8fbedb4 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_sk_SK.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_sk_SK.properties
@@ -32,11 +32,8 @@ MainWindow.menu.window.alltofront=Zobrazi\u0165 v\u0161etky navrchu
 MainWindow.menu.help=&N\u00e1poveda
 MainWindow.menu.help.about=&O programe Vuze
 MainWindow.about.title=O programe Vuze
-MainWindow.about.section.developers=V\u00fdvoj\u00e1ri
-MainWindow.about.section.translators=Prekladatelia
 MainWindow.about.internet.homepage=Domovsk\u00e1 str\u00e1nka programu Vuze
 MainWindow.about.internet.sourceforge=Sourceforge - Str\u00e1nka projektu
-MainWindow.about.internet.sourceforgedownloads=Sourceforge - Downloady
 MainWindow.about.internet.bugreports=Hl\u00e1senie ch\u00fdb
 MainWindow.about.internet.forumdiscussion=Diskusn\u00e9 f\u00f3ra
 MainWindow.dialog.choose.savepath=Vyberte cie\u013eov\u00fa zlo\u017eku
@@ -288,8 +285,6 @@ IrcView.errormsg=Zl\u00e1 syntax /msg : /msg pou\u017e\u00edvate\u013e spr\u00e1
 IrcView.help=Pou\u017eite\u013en\u00e9 pr\u00edkazy s\u00fa :\n . /help : zobraz\u00ed t\u00fato n\u00e1povedu\n . /nick | /name : zmen\u00ed va\u0161u prez\u00fdvku \n . /me \u00fakon : po\u0161le ako \u00fakon \n . /msg pou\u017e\u00edvate\u013e spr\u00e1va : po\u0161le priv\u00e1tnu spr\u00e1vu \n . /r message : odpove\u010f na posledn\u00fa priv\u00e1tnu spr\u00e1vu\n . /join #kan\u00e1l : zmen\u00ed aktu\u00e1lny kan\u00e1l  
 PasswordWindow.title=Vuze je uzamknut\u00fd
 PasswordWindow.passwordprotected=Vuze je chr\u00e1nen\u00fd heslom.\nPre zobrazenie hlavn\u00e9ho okna, vypl\u0148te heslo : 
-TrackerChangerWindow.title=Prida\u0165 Tracker
-TrackerChangerWindow.newtracker=Nov\u00e1 URL Trackera
 PeersView.discarded=Zahoden\u00fdch
 PeersView.discarded.info=D\u00e1ta, ktor\u00e9 v\u00e1m boli doru\u010den\u00e9 a pritom neboli potrebn\u00e9 a tak boli zahoden\u00e9
 discarded=zahoden\u00fdch
@@ -360,7 +355,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Zmaza\u0165 .&torrent
 MyTorrentsView.menu.removeand.deletedata=Zmaza\u0165 &d\u00e1ta 
 MyTorrentsView.menu.removeand.deleteboth=Zmaza\u0165 .torrent &aj d\u00e1ta
 deletedata.title=!!! Upozornenie !!! 
-deletedata.message1=Chyst\u00e1te sa zmaza\u0165 D\u00c1TA z :\n
 MainWindow.menu.file.configure=Sprievodca &nastaven\u00edm
 configureWizard.title=Sprievodca nastaven\u00edm
 configureWizard.welcome.title=Vitajte v Sprievodcovi nastaven\u00edm
@@ -382,7 +376,6 @@ configureWizard.transfer.maxActiveTorrents=Max. akt\u00edvnych Torrentov
 configureWizard.transfer.maxDownloads=Max. s\u0165ahovan\u00fdch Torrentov 
 configureWizard.transfer.maxUploadsPerTorrent=Max. uploadov na Torrent 
 configureWizard.nat.title=NAT / Port servera
-configureWizard.nat.message=Aby ste z\u00edskali \u010do najviac z BitTorrent siete, mali by ste by\u0165 pristupn\u00ed z internetu. V\u00fdchodz\u00ed port BitTorrentu je 6881.\nTento n\u00e1stroj v\u00e1m umo\u017en\u00ed tento port zmeni\u0165 a n\u00e1sledne ho otestova\u0165. 
 configureWizard.nat.test=Sk\u00fasi\u0165
 configureWizard.nat.testing=Testujem port 
 configureWizard.nat.ko=Chyba NAT
@@ -534,7 +527,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=Poskytovate\u013e dynamick\u00e9ho a statick\u00e9ho DNS\n(nepodporuje vo\u013ene slu\u017ebu zistenia adresy) 
 ConfigView.section.tracker.publicenable=Povoli\u0165 extern\u00e9 Torrenty
 ConfigView.label.playdownloadspeech=Hovori\u0165 po dokon\u010den\u00ed s\u0165ahovania
-ConfigView.label.playdownloadspeech.info=Re\u010dov\u00e9 slu\u017eby moment\u00e1lne najlep\u0161ie funguj\u00fa v angli\u010dtine
 #
 # Tooltips
 #
@@ -702,8 +694,6 @@ plugin.sharing.download.remove.veto=T\u00e1to polo\u017eka vznikla zdie\u013ean\
 ConfigView.section.tracker.main=Hlavn\u00fd
 ConfigView.label.prioritizefirstpiece=V\u00e4\u010d\u0161ia priorita pre prv\u00e9 diely s\u00faborov
 ConfigView.label.prioritizefirstpiece.tooltip=Vuze sa pok\u00fasi stiahnu\u0165 za\u010diatok s\u00faboru ako prv\u00fd.\nUmo\u017en\u00ed tak r\u00fdchly n\u00e1h\u013ead.
-ConfigView.section.file.confirm_data_delete=Potvrdi\u0165 zmazanie d\u00e1t
-ConfigView.section.file.confirm_data_delete.tooltip=Vy\u017eadova\u0165 potvrdenie akcie pri pou\u017eit\u00ed "Odobra\u0165 a zmaza\u0165 ..."
 TrayWindow.menu.startalldownloads=Spusti\u0165 v\u0161etky Torrenty
 SystemTray.menu.startalltransfers=Spusti\u0165 v\u0161etky prenosy
 sharing.progress.title=Proces zdie\u013eania
@@ -1011,7 +1001,6 @@ ConfigView.pluginlist.whereToPutOr=Pre zdie\u013ean\u00e9 pluginy pou\u017eite z
 MainWindow.statusText.checking=Kontrola aktualiz\u00e1ci\u00ed
 TableColumn.header.OnlyCDing4=Iba distribuovan\u00fd
 TableColumn.header.OnlyCDing4.info=Mno\u017estvo \u010dasu, po ktor\u00fd bol Torrent iba distribuovan\u00fd.  Nezah\u0155\u0148a \u010das, po ktor\u00fd sa Torrent s\u0165ahoval (a distribuoval).
-ConfigView.section.style.alternateTablePainting=Pou\u017ei\u0165 n\u00e1hradn\u00fa met\u00f3du kreslenia st\u013apcov tabu\u013eky [m\u00f4\u017ee vy\u017eadova\u0165 re\u0161tart]
 UpdateWindow.status.restartMaybeNeeded=M\u00f4\u017ee by\u0165 potrebn\u00fd re\u0161tart
 ConfigView.pluginlist.shared=zdie\u013ean\u00fd
 PeersView.host=Meno stroja
@@ -1236,18 +1225,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Ve\u013ekos\u0165 SO_RCVBUF [0:
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=Nastav\u00ed \u0161tandardn\u00fa hodnotu SO_RCVBUF socketu (v bajtoch), tozn. ve\u013ekos\u0165 prij\u00edmacieho okna TCP.\nVuze toto \u0161tandardne nenastavuje, pou\u017e\u00edva sa teda hodnota, ktor\u00fa nastav\u00ed OS.\nPozn.: Linux zdvojn\u00e1sob\u00ed zadan\u00fa hodnotu.
 ConfigView.section.connection.advanced.SO_SNDBUF=Ve\u013ekos\u0165 SO_SNDBUF [0: pou\u017ei \u0161tandardn\u00fa hodnotu OS]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Nastav\u00ed \u0161tandardn\u00fa hodnotu SO_RCVBUF socketu (v bajtoch), tozn. ve\u013ekos\u0165 vysielacieho okna TCP.\nVuze toto \u0161tandardne nenastavuje, pou\u017e\u00edva sa teda hodnota, ktor\u00fa nastav\u00ed OS.\nPozn.: Linux zdvojn\u00e1sob\u00ed zadan\u00fa hodnotu.
-ConfigView.section.interface.confirm_torrent_removal=Zobrazi\u0165 potvrdzuj\u00faci dial\u00f3g pri odoberan\u00ed Torrentu
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Potvrdenie pri odoberan\u00ed Torrentu zo zobrazenia 'Moje Torrenty'.
-MyTorrentsView.confirm_torrent_removal=Naozaj chcete odstr\u00e1ni\u0165?\n
 TableColumn.header.seed_to_peer_ratio=Zdroj:Klient pomer
 TableColumn.header.seed_to_peer_ratio.info=Celkov\u00fd pomer zdrojov ku klientom
 PeersView.connected_time=\u010cas pripojenia
 PeersView.connected_time.info=Celkov\u00fd \u010das pripojenia klienta
-ConfigView.section.interface.display.add_torrents_silently=Prid\u00e1va\u0165 Torrenty potichu
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Prid\u00e1va\u0165 Torrenty bez aktiv\u00e1cie hlavn\u00e9ho okna Azureusa.
 TableColumn.header.maxdownspeed=Max Down r\u00fdchlos\u0165
 TableColumn.header.maxdownspeed.info=Max. r\u00fdchlos\u0165 s\u0165ahovania na Torrent
-PeersGraphicView.title=\u00da\u010dastn\u00edci
+PeersGraphicView.title.full=\u00da\u010dastn\u00edci
 ConfigView.section.tracker.passwordwebhttpsonly=Povoli\u0165 pr\u00edstup iba cez HTTPS
 TableColumn.header.torrentpath=Umiestnenie Torrentu
 TableColumn.header.torrentpath.info=Umiestnenie Torrentu na disku
@@ -1303,8 +1287,6 @@ UpdateWindow.restartLater=Re\u0161tartova\u0165 nesk\u00f4r
 MainWindow.menu.file.restart=Re\u0161tart
 MainWindow.dialog.restartconfirmation.title=Re\u0161tartova\u0165 Vuze
 MainWindow.dialog.restartconfirmation.text=Naozaj chcete re\u0161tartova\u0165 Vuze
-deletetorrent.message1=Chyst\u00e1te sa zmaza\u0165 TORRENT pre :\n
-deletetorrent.message2=\nNaozaj chcete pokra\u010dova\u0165?
 ConfigView.label.prioritizemostcompletedfiles=Viac dokon\u010den\u00e9 s\u00fabory maj\u00fa v\u00e4\u010d\u0161iu prioritu
 splash.plugin.init=Inicializ\u00e1cia pluginu: 
 ConfigView.section.style.osx_small_fonts=Pou\u017e\u00edva\u0165 mal\u00e9 p\u00edsma [nutn\u00fd re\u0161tart]
@@ -1458,7 +1440,6 @@ MainWindow.menu.file.open.torrentfortracking=.torrent s\u00fabor (pre trackovani
 MyTrackerView.date_added=Pridan\u00fd
 ConfigView.section.tracker.portbackup=Z\u00e1lo\u017en\u00e9 porty (oddelen\u00e9 ';')
 ConfigView.label.playfilespeech=Skon\u010denie s\u00faboru ohl\u00e1si\u0165 hlasom
-ConfigView.label.playfilespeech.info=Hlasov\u00e9 slu\u017eby moment\u00e1lne funguj\u00fa najlep\u0161ie v angli\u010dtine
 ConfigView.label.playfilefinished=Zahra\u0165 zvuk po dokon\u010den\u00ed s\u00faboru
 ConfigView.label.backupconfigfiles=Z\u00e1lohova\u0165 konfigura\u010dn\u00e9 s\u00fabory
 dht.ipfilter.log=Protokolova\u0165 poru\u0161enia pravidiel IP filtra
diff --git a/org/gudy/azureus2/internat/MessagesBundle_sl_SI.properties b/org/gudy/azureus2/internat/MessagesBundle_sl_SI.properties
index 3520697..0ee09db 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_sl_SI.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_sl_SI.properties
@@ -26,12 +26,9 @@ ConfigView.section.language=Jezik
 MainWindow.menu.help=Pomo\u010d
 MainWindow.menu.help.about=O Azureusu
 MainWindow.about.title=O Programu...
-MainWindow.about.section.developers=Ustvarjalci
-MainWindow.about.section.translators=Prevajalci
 MainWindow.about.section.internet=Splet
 MainWindow.about.internet.homepage=Doma\u010da stran
 MainWindow.about.internet.sourceforge=Sourceforge Stran
-MainWindow.about.internet.sourceforgedownloads=Sourceforge datoteke
 MainWindow.about.internet.bugreports=Prijava hro\u0161\u010dev
 MainWindow.about.internet.forumdiscussion=Glavni forum
 MainWindow.about.internet.wiki=Vuze Wiki FAQ (pogosto zastavljena vpra\u0161anja)
@@ -283,8 +280,6 @@ IrcView.help=Veljavni ukazi so :\n . /help : prika\u017ee to sporo\u010dilo\n .
 PasswordWindow.title=Vuze je zaklenjen
 PasswordWindow.passwordprotected=Vuze je za\u0161\u010diten z geslom.\nZa prikaz Vuze ovega okna, vnesi geslo tukaj :
 Button.ok=V Redu
-TrackerChangerWindow.title=Dodaj Sledilnik
-TrackerChangerWindow.newtracker=Vnesi nov url sledilnika
 PeersView.discarded=Zavr\u017eeno
 PeersView.discarded.info=Podatki, ki si jih nekako dobil, \u010deprav jih nisi potreboval, zato si se jih znebil.
 discarded=zavr\u017eeno
@@ -355,7 +350,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Izbri\u0161i .torrent
 MyTorrentsView.menu.removeand.deletedata=Izbri\u0161i Datoteke
 MyTorrentsView.menu.removeand.deleteboth=Izbri\u0161i Oboje
 deletedata.title=!!! Opozorilo !!!
-deletedata.message1=Izbrisali boste vse PODATKE iz :\n
 MainWindow.menu.file.configure=Nastavitveni \u010carovnik
 configureWizard.title=Nastavitveni \u010carovnik
 configureWizard.welcome.title=Dobrodo\u0161li v Azureusov Nastavitveni \u010carovnik
@@ -376,7 +370,6 @@ configureWizard.transfer.maxActiveTorrents=Max Aktivnih
 configureWizard.transfer.maxDownloads=Max Odjemanj
 configureWizard.transfer.maxUploadsPerTorrent=Max Oddajanj na Torrent
 configureWizard.nat.title=NAT / Stre\u017enikovi porti
-configureWizard.nat.message=Da iz BitTorrenta iztisne\u0161 najve\u010d, je priporo\u010dljivo, da je klient s spleta popolno dostopen. Obseg privzetih bittorent portov je od 6881 do 6889. To orodje testira in / ali spremeni privzete porte. \u010ce potekajo aktivni prenosi, nekateri porti ne bodo dostopni.
 configureWizard.nat.test=Testiraj
 configureWizard.nat.testing=Testiram port
 configureWizard.nat.ok=V Redu
@@ -691,8 +684,6 @@ ConfigView.section.tracker.main=Glavni
 ConfigView.section.tracker.web=Internet
 ConfigView.label.prioritizefirstpiece=Daj prioriteto prvemu kosu datotek(e)
 ConfigView.label.prioritizefirstpiece.tooltip=Posku\u0161a najprej odjeti za\u010detek datoteke.\nZa podporo zgodnjemu predogledu
-ConfigView.section.file.confirm_data_delete=Potrdi pri brisanju podatkov
-ConfigView.section.file.confirm_data_delete.tooltip=Potrdi brisanje podatkov pri uporabi 'Odstrani in izbri\u0161i...'
 TrayWindow.menu.startalldownloads=Za\u010dni vse odjemke
 sharing.progress.title=Delitveni napredek
 sharing.progress.hide=Skrij
@@ -992,7 +983,6 @@ ConfigView.pluginlist.whereToPutOr=Za deljeno uporabo vklju\u010dkov:
 MainWindow.statusText.checking=Preverjam za posodobitve
 TableColumn.header.OnlyCDing4=SamoCDing4
 TableColumn.header.OnlyCDing4.info=Koli\u010dina \u010dasa, ko je torrent sejal. Ne pri\u0161teje koli\u010dine \u010dasa ko je torrent odjemal(in isto\u010dasno sejal).
-ConfigView.section.style.alternateTablePainting=Uporabi alternativno metodo risanja grafi\u010dnih stolpcev (lahko potrebuje ponovni zagon)
 UpdateWindow.status.restartMaybeNeeded=Ponovni zagon bo lahko potreben
 ConfigView.pluginlist.shared=deljeni
 PeersView.host=Ime gostitelja
diff --git a/org/gudy/azureus2/internat/MessagesBundle_sr.properties b/org/gudy/azureus2/internat/MessagesBundle_sr.properties
index 9bee999..ccaec0d 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_sr.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_sr.properties
@@ -36,13 +36,10 @@ MainWindow.menu.help=&\u041f\u043e\u043c\u043e\u045b
 MainWindow.menu.help.about=\u041e \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u0443
 MainWindow.menu.torrent=\u0422&\u043e\u0440\u0435\u043d\u0442
 MainWindow.about.title=\u041e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0443
-MainWindow.about.section.developers=\u0420\u0430\u0437\u0432\u0438\u0458\u0430\u0447\u0438
-MainWindow.about.section.translators=\u041f\u0440\u0435\u0432\u043e\u0434\u0438\u043e\u0446\u0438
 MainWindow.about.section.system=\u0421\u0438\u0441\u0442\u0435\u043c
 MainWindow.about.section.internet=\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442
 MainWindow.about.internet.homepage=\u0410\u0437\u0443\u0440\u0435\u0443\u0441\u043e\u0432\u0430 \u0441\u0442\u0440\u0430\u043d\u0430
 MainWindow.about.internet.sourceforge=\u0421\u0442\u0440\u0430\u043d\u0430 \u0421\u043e\u0440\u0441\u0444\u043e\u0440\u045f\u043e\u0432\u043e\u0433 \u043f\u0440\u043e\u0458\u0435\u043a\u0442\u0430
-MainWindow.about.internet.sourceforgedownloads=\u041f\u0440\u0438\u0458\u0435\u043c \u0441\u0430 \u0421\u043e\u0440\u0441\u0444\u043e\u0440\u045f\u0430
 MainWindow.about.internet.bugreports=\u041f\u0440\u0438\u0458\u0430\u0432\u0430 \u0433\u0440\u0435\u0448\u0430\u043a\u0430
 MainWindow.about.internet.forumdiscussion=\u0424\u043e\u0440\u0443\u043c\u0438
 MainWindow.about.internet.wiki=\u041f\u0438\u0442\u0430\u045a\u0430 \u043e \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u0443 \u043d\u0430 \u0412\u0438\u043a\u0438\u0458\u0443
@@ -311,8 +308,6 @@ IrcView.help=\u0412\u0430\u0436\u0435\u045b\u0435 \u043a\u043e\u043c\u0430\u043d
 PasswordWindow.title=\u0410\u0437\u0443\u0440\u0435\u0443\u0441 \u0458\u0435 \u0437\u0430\u043a\u0459\u0443\u0447\u0430\u043d
 PasswordWindow.passwordprotected=\u0414\u0430 \u0431\u0438 \u0431\u0438\u043e \u043f\u0440\u0438\u043a\u0430\u0437\u0430\u043d \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u043e\u0432 \u043f\u0440\u043e\u0437\u043e\u0440, \u043c\u043e\u043b\u0438\u043c\u043e \u0434\u0430 \u0443\u043d\u0435\u0441\u0435\u0442 \u043e\u0432\u0434\u0435 \u0412\u0430\u0448\u0443 \u043b\u043e\u0437\u0438\u043d\u043a\u0443 :
 Button.ok=&\u0423 \u0440\u0435\u0434\u0443
-TrackerChangerWindow.title=\u0414\u043e\u0434\u0430\u0458 \u043f\u0440\u0430\u0442\u0438\u043e\u0446\u0430
-TrackerChangerWindow.newtracker=\u0414\u043e\u0434\u0430\u0458 \u043d\u043e\u0432 \u0423\u0420\u041b \u0437\u0430 \u043f\u0440\u0430\u0442\u0438\u043e\u0446\u0430
 PeersView.discarded=\u041e\u0434\u0431\u0430\u0447\u0435\u043d\u043e
 PeersView.discarded.info=\u041f\u043e\u0434\u0430\u0446\u0438 \u043a\u043e\u0458\u0435 \u0441\u0442\u0435 \u043d\u0435\u043a\u0430\u043a\u043e \u043f\u0440\u0438\u043c\u0438\u043b\u0438 \u0438\u0430\u043a\u043e \u0412\u0430\u043c \u043d\u0438\u0441\u0443 \u0431\u0438\u043b\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u0438, \u043f\u0430 \u0441\u0442\u0435 \u0438\u0445 \u0441\u0435 \u043e\u0442\u0430\u0440\u0430\u0441\u0438\u043b\u0438.
 discarded=\u043e\u0434\u0431\u0430\u0447\u0435\u043d\u043e
@@ -384,7 +379,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u0423\u043a\u043b\u043e\u043d\u0438
 MyTorrentsView.menu.removeand.deletedata=\u0423\u043a\u043b\u043e\u043d\u0438 &\u043f\u043e\u0434\u0430\u0442\u043a\u0435
 MyTorrentsView.menu.removeand.deleteboth=\u0423\u043a\u043b\u043e\u043d\u0438 &\u043e\u0431\u043e\u0458\u0435
 deletedata.title=\u0423\u043f\u043e\u0437\u043e\u0440\u0435\u045a\u0435
-deletedata.message1=\u0421\u0430\u043c\u043e \u0448\u0442\u043e \u043d\u0438\u0441\u0442\u0435 \u0443\u043a\u043b\u043e\u043d\u0438\u043b\u0438 \u041f\u041e\u0414\u0410\u0422\u041a\u0415 \u0441\u0430 :\n
 MainWindow.menu.file.configure=&\u0427\u0430\u0440\u043e\u0431\u045a\u0430\u043a \u0437\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0430...
 configureWizard.title=\u0427\u0430\u0440\u043e\u0431\u045a\u0430\u043a \u0437\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0430
 configureWizard.welcome.title=\u0414\u043e\u0431\u0440\u043e\u0434\u043e\u0448\u043b\u0438 \u043a\u043e\u0434 \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u043e\u0432\u043e\u0433 \u0447\u0430\u0440\u043e\u0431\u045a\u0430\u043a\u0430 \u0437\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0430
@@ -406,7 +400,6 @@ configureWizard.transfer.maxActiveTorrents=\u041d\u0430\u0458\u0432\u0438\u0448\
 configureWizard.transfer.maxDownloads=\u041d\u0430\u0458\u0432\u0438\u0448\u0435 \u043f\u0440\u0438\u0458\u0435\u043c\u0430
 configureWizard.transfer.maxUploadsPerTorrent=\u041d\u0430\u0458\u0432\u0438\u0448\u0435 \u0441\u043b\u0430\u045a\u0430 \u043f\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
 configureWizard.nat.title=NAT / \u043f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
-configureWizard.nat.message=\u041a\u0430\u043a\u043e \u0431\u0438\u0441\u0442\u0435 \u0438\u0437\u0432\u0443\u043a\u043b\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0438\u0437 \u0411\u0438\u0442 \u0422\u043e\u0440\u0435\u043d\u0442\u0430, \u043f\u0440\u0435\u043f\u043e\u0440\u0443\u0447\u0443\u0458\u0435 \u0441\u0435 \u0434\u0430 \u0440\u0430\u0447\u0443\u043d\u0430\u0440 \u0431\u0443\u0434\u0435 \u043f\u043e\u0442\u043f\u0443\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f [...]
 configureWizard.nat.test=\u041f\u0440\u043e\u0431\u0430
 configureWizard.nat.testing=\u041f\u043e\u0440\u0442 \u0437\u0430 \u043f\u0440\u043e\u0431\u0443
 configureWizard.nat.ok=\u0423 \u0440\u0435\u0434\u0443 !
@@ -569,7 +562,6 @@ ConfigView.section.file.decoder.nodecoder=\u041d\u0438\u0458\u0435\u0434\u0430\u
 IPChecker.external.service.no-ip.description=\u0414\u043e\u0431\u0430\u0432\u0459\u0430\u0447 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043a\u0435 \u0438 \u0441\u0442\u0430\u0442\u0438\u0447\u043a\u0435 \u0414\u041d\u0421 \u0430\u0434\u0440\u0435\u0441\u0435\n(\u043d\u0435 \u043f\u043e\u0441\u0442\u043e\u0458\u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430 \u0443\u0441\u043b\u0443\u0433\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0435 \u0430\u0434\u0440\u0435\u0441\u0435)
 ConfigView.section.tracker.publicenable=\u0423\u043a\u0459\u0443\u0447\u0438 \u0441\u043f\u043e\u0459\u0430\u0448\u045a\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0435
 ConfigView.label.playdownloadspeech=\u041e\u0431\u0430\u0432\u0435\u0441\u0442\u0438 \u0433\u043b\u0430\u0441\u043e\u043c \u043e \u043a\u0440\u0430\u0458\u0443 \u043f\u0440\u0438\u0458\u0435\u043c\u0430
-ConfigView.label.playdownloadspeech.info=\u0413\u043e\u0432\u043e\u0440\u043d\u0435 \u0443\u0441\u043b\u0443\u0433\u0435 \u0442\u0440\u0435\u043d\u0443\u0442\u043d\u043e \u043d\u0430\u0458\u0431\u043e\u0459\u0435 \u0440\u0430\u0434\u0435 \u043d\u0430 \u0435\u043d\u0433\u043b\u0435\u0441\u043a\u043e\u043c \u0458\u0435\u0437\u0438\u043a\u0443
 #
 # Tooltips
 #
@@ -743,8 +735,6 @@ ConfigView.section.tracker.main=\u0413\u043b\u0430\u0432\u043d\u0438
 ConfigView.section.tracker.web=\u041c\u0440\u0435\u0436\u0430
 ConfigView.label.prioritizefirstpiece=\u0421\u0442\u0430\u0432\u0438 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043d\u0430 \u043f\u0440\u0432\u0438 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u045a\u0438 \u0434\u0435\u043e \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0430
 ConfigView.label.prioritizefirstpiece.tooltip=\u041f\u043e\u043a\u0443\u0448\u0430\u0432\u0430 \u0434\u0430 \u043f\u0440\u0432\u043e \u043f\u0440\u0435\u0443\u0437\u043c\u0435 \u0441\u0430\u043c \u043f\u043e\u0447\u0435\u0442\u0430\u043a \u0438 \u0441\u0430\u043c \u043a\u0440\u0430\u0458 \u0441\u0432\u0430\u043a\u0435 \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0435.\n\u0421\u043b\u0443\u0436\u0438 \u0434\u0430 \u043f\u043e\u0434\u0440\u0436\u0438 \u0440\u0430\u043d\u0438 \u043f\u0440\u0 [...]
-ConfigView.section.file.confirm_data_delete=\u0422\u0440\u0430\u0436\u0438 \u043f\u043e\u0442\u0432\u0440\u0434\u0443 \u043f\u0440\u0435 \u0443\u043a\u043b\u0430\u045a\u0430\u045a\u0430 \u043f\u043e\u0434\u0430\u0442\u0430\u043a\u0430
-ConfigView.section.file.confirm_data_delete.tooltip=\u041f\u043e\u0442\u0432\u0440\u0434\u0438 \u0443\u043a\u043b\u0430\u045a\u0430\u045a\u0435 \u043f\u043e\u0434\u0430\u0442\u0430\u043a\u0430 \u043f\u0440\u0438 \u0443\u043f\u043e\u0442\u0440\u0435\u0431\u0438 \u201e\u0423\u043a\u043b\u043e\u043d\u0438 \u0438 \u043e\u0431\u0440\u0438\u0448\u0438...\u201c
 TrayWindow.menu.startalldownloads=\u041f\u043e\u043a\u0440\u0435\u043d\u0438 \u0441\u0432\u0435 \u043f\u0440\u0438\u0458\u0435\u043c\u0435
 SystemTray.menu.startalltransfers=\u041f\u043e\u043a\u0440\u0435\u043d\u0438 \u0441\u0432\u0435 \u043f\u0440\u0435\u043d\u043e\u0441\u0435
 sharing.progress.title=\u0422\u043e\u043a \u0434\u0435\u0459\u0435\u045a\u0430
@@ -1063,7 +1053,6 @@ ConfigView.pluginlist.whereToPut=\u041f\u043e\u0441\u0442\u0430\u0432\u0438\u044
 ConfigView.pluginlist.whereToPutOr=\u0417\u0430 \u0434\u0435\u0459\u0435\u043d\u0435 \u0434\u043e\u0434\u0430\u0442\u043a\u0435 \u043a\u043e\u0440\u0438\u0441\u0442\u0438\u0442\u0435:
 MainWindow.statusText.checking=\u041f\u0440\u043e\u0432\u0435\u0440\u0430\u0432\u0430\u045a\u0435 \u0434\u043e\u0433\u0440\u0430\u0434\u045a\u0438...
 TableColumn.header.OnlyCDing4.info=\u0412\u0440\u0435\u043c\u0435 \u043a\u043e\u0458\u0435 \u0458\u0435 \u0442\u043e\u0440\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u043e \u0441\u0430\u043c\u043e \u0443 \u0437\u0430\u043c\u0435\u0442\u0430\u045a\u0443. \u041d\u0438\u0458\u0435 \u0443\u0440\u0430\u0447\u0443\u043d\u0430\u0442\u043e \u0432\u0440\u0435\u043c\u0435 \u043a\u0430\u0434\u0430 \u0458\u0435 \u0442\u043e\u0440\u0435\u043d\u0442 \u043f\u0440\u0438\u043c\u0430\u043d (\u0438 \ [...]
-ConfigView.section.style.alternateTablePainting=\u041a\u043e\u0440\u0438\u0441\u0442\u0438 \u0434\u0440\u0443\u0433\u0438 \u043d\u0430\u0447\u0438\u043d \u0437\u0430 \u0446\u0440\u0442\u0430\u045a\u0435 \u043a\u043e\u043b\u043e\u043d\u0430 \u0443 \u0442\u0430\u0431\u0435\u043b\u0430\u043c\u0430 (\u043c\u043e\u0436\u0435 \u0434\u0430 \u0442\u0440\u0430\u0436\u0438 \u0440\u0435\u0441\u0442\u0430\u0440\u0442)
 UpdateWindow.status.restartMaybeNeeded=\u041c\u043e\u0436\u0434\u0430 \u045b\u0435\u0442\u0435 \u043c\u043e\u0440\u0430\u0442\u0438 \u0434\u0430 \u043f\u043e\u043d\u043e\u0432\u043e \u043f\u043e\u043a\u0440\u0435\u043d\u0435\u0442\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c
 ConfigView.pluginlist.shared=\u0434\u0435\u0459\u0435\u043d\u043e
 PeersView.host=\u0418\u043c\u0435 \u0440\u0430\u0447\u0443\u043d\u0430\u0440\u0430
@@ -1300,18 +1289,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=\u0412\u0435\u043b\u0438\u0447\
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u041f\u043e\u0441\u0442\u0430\u0432\u0459\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0434\u043d\u0443 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443 SO_RCVBUF (\u0443 \u0431\u0430\u0458\u0442\u043e\u0432\u0438\u043c\u0430), \u0442\u0458. \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443 \u043f\u0440\u0438\u0458\u0435\u043c\u043d\u043e\u0433 \u043f\u0440\u043e\u0437\u043e\u0440\u0430 \u0438 \u0441\u043a\u0430\u043b\u0438\u0 [...]
 ConfigView.section.connection.advanced.SO_SNDBUF=\u0412\u0435\u043b\u0438\u0447\u0438\u043d\u0430 SO_SNDBUF \u0437\u0430 \u0443\u0442\u0438\u0447\u043d\u0438\u0446\u0443 [0: \u043a\u043e\u0440\u0438\u0441\u0442\u0438 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u043d\u043e \u0437\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0438 \u0441\u0438\u0441\u0442\u0435\u043c]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u041f\u043e\u0441\u0442\u0430\u0432\u0459\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u043d\u0443 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443 SO_SNDBUF (\u0443 \u0431\u0430\u0458\u0442\u043e\u0432\u0438\u043c\u0430), \u0442\u0458. \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443 \u0422\u0426\u041f\u043e\u0432\u043e\u0433 \u043f\u0440\u043e\u0437\u043e\u0440\u0430 \u0437\u0430 \u0441\u043b\u0430\u045a\u0435.\n\u0410\u0443 [...]
-ConfigView.section.interface.confirm_torrent_removal=\u041f\u0440\u0438\u043a\u0430\u0436\u0438 \u043f\u0440\u043e\u0437\u043e\u0440 \u0437\u0430 \u043f\u043e\u0442\u0432\u0440\u0434\u0443 \u0437\u0430 \u0443\u043a\u043b\u0430\u045a\u0430\u045a\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u041f\u043e\u0442\u0432\u0440\u0434\u0438 \u0443\u043a\u043b\u0430\u045a\u0430\u043b\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0430 \u0438\u0437 \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430 \u041c\u043e\u0458\u0438\u0445 \u0442\u043e\u0440\u0435\u043d\u0442\u0430.
-MyTorrentsView.confirm_torrent_removal=\u0414\u0430 \u043b\u0438 \u0441\u0438\u0433\u0443\u0440\u043d\u043e \u0436\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u0443\u043a\u043b\u043e\u043d\u0438\u0442\u0435?\n
 TableColumn.header.seed_to_peer_ratio=\u041e\u0434\u043d\u043e\u0441 \u0431\u0440\u043e\u0458\u0430 \u0437\u0430\u043c\u0435\u0442\u0430\u043a\u0430 \u0438 \u0440\u0430\u0447\u0443\u043d\u0430\u0440\u0430
 TableColumn.header.seed_to_peer_ratio.info=\u041e\u0434\u043d\u043e\u0441 \u0431\u0440\u043e\u0458\u0430 \u0437\u0430\u043c\u0435\u0442\u0430\u043a\u0430 \u0443 \u0440\u043e\u0458\u0443 \u0438 \u0431\u0440\u043e\u0458\u0430 \u0440\u0430\u0447\u0443\u043d\u0430\u0440\u0430
 PeersView.connected_time=\u0412\u0440\u0435\u043c\u0435 \u0432\u0435\u0437\u0435
 PeersView.connected_time.info=\u0423\u043a\u0443\u043f\u043d\u043e \u0432\u0440\u0435\u043c\u0435 \u0432\u0435\u0437\u0435 \u0441\u0430 \u0440\u0430\u0447\u0443\u043d\u0430\u0440\u0438\u043c\u0430
-ConfigView.section.interface.display.add_torrents_silently=\u0422\u0438\u0445\u043e \u0434\u043e\u0434\u0430\u0432\u0430\u045a\u0435 \u0442\u043e\u0440\u0435\u043d\u0442\u0430
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0414\u043e\u0434\u0430\u0458 \u0442\u043e\u0440\u0435\u043d\u0442\u0435 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0443\u0458\u0443\u045b\u0438 \u0433\u043b\u0430\u0432\u043d\u0438 \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u043e\u0432 \u043f\u0440\u043e\u0437\u043e\u0440
 TableColumn.header.maxdownspeed=\u041d\u0430\u0458\u0432\u0435\u045b\u0430 \u0431\u0440\u0437\u0438\u043d\u0430 \u043f\u0440\u0438\u0458\u0435\u043c\u0430
 TableColumn.header.maxdownspeed.info=\u041d\u0430\u0458\u0432\u0435\u045b\u0430 \u0431\u0440\u0437\u0438\u043d\u0430 \u043f\u0440\u0438\u0458\u0435\u043c\u0430 \u043f\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0443
-PeersGraphicView.title=\u0420\u043e\u0458
+PeersGraphicView.title.full=\u0420\u043e\u0458
 ConfigView.section.tracker.passwordwebhttpsonly=\u0414\u043e\u0437\u0432\u043e\u043b\u0438 \u043f\u0440\u0438\u0441\u0442\u0443\u043f \u0441\u0430\u043c\u043e \u043a\u0440\u043e\u0437 HTTPS
 TableColumn.header.torrentpath=\u041c\u0435\u0441\u0442\u043e \u0442\u043e\u0440\u0435\u043d\u0442\u0430
 TableColumn.header.torrentpath.info=\u041c\u0435\u0441\u0442\u043e \u0433\u0434\u0435 \u0441\u0435 \u0422\u043e\u0440\u0435\u043d\u0442\u0438 \u0447\u0443\u0432\u0430\u0458\u0443 \u043d\u0430 \u0434\u0438\u0441\u043a\u0443
@@ -1368,8 +1352,6 @@ UpdateWindow.restartLater=\u041f\u043e\u043a\u0440\u0435\u043d\u0438 \u0410\u043
 MainWindow.menu.file.restart=\u041f\u043e\u043a\u0440\u0435\u043d\u0438 \u043f\u043e\u043d\u043e\u0432\u043e
 MainWindow.dialog.restartconfirmation.title=\u0414\u0430 \u043b\u0438 \u0434\u0430 \u043f\u043e\u043d\u043e\u0432\u043e \u043f\u043e\u043a\u0440\u0435\u043d\u0435\u043c \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u0430?
 MainWindow.dialog.restartconfirmation.text=\u0414\u0430 \u043b\u0438 \u0437\u0430\u0438\u0441\u0442\u0430 \u0436\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0443\u0458\u0435\u0442\u0435 \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u0430?
-deletetorrent.message1=\u0421\u0430\u043c\u043e \u0448\u0442\u043e \u043d\u0438\u0441\u0442\u0435 \u0443\u043a\u043b\u043e\u043d\u0438\u043b\u0438 \u0422\u041e\u0420\u0415\u041d\u0422 \u0437\u0430 :\n
-deletetorrent.message2=\n\u0414\u0430 \u043b\u0438 \u0441\u0438\u0433\u0443\u0440\u043d\u043e \u0434\u0430 \u0436\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u043d\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u0435?
 ConfigView.label.prioritizemostcompletedfiles=\u0423\u0440\u0435\u0434\u0438 \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0435 \u0441\u0430 \u0432\u0438\u0441\u043e\u043a\u043e\u043c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c \u043f\u0440\u0435\u043c\u0430 \u043f\u0440\u043e\u0446\u0435\u043d\u0442\u0443 \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u043a\u0430 \u0438 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0438 \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0435
 splash.plugin.init=\u041f\u043e\u043a\u0440\u0435\u0442\u0430\u045a\u0435 \u0434\u043e\u0434\u0430\u0442\u043a\u0430:
 ConfigView.section.style.osx_small_fonts=\u041a\u043e\u0440\u0438\u0441\u0442\u0438 \u0441\u0438\u0442\u043d\u0430 \u0441\u043b\u043e\u0432\u0430 [\u0442\u0440\u0430\u0436\u0438 \u043f\u043e\u043d\u043e\u0432\u043d\u043e \u043f\u043e\u043a\u0440\u0435\u0442\u0430\u045a\u0435]
@@ -1537,7 +1519,6 @@ VivaldiView.title.full=\u0412\u0438\u0432\u0430\u043b\u0434\u0438
 MyTrackerView.date_added=\u0414\u043e\u0434\u0430\u0442\u043e
 ConfigView.section.tracker.portbackup=\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u0438 \u043f\u043e\u0440\u0442\u043e\u0432\u0438 (\u201e;\u201c \u0437\u0430 \u0440\u0430\u0437\u0434\u0432\u0430\u0458\u0430\u045a\u0435)
 ConfigView.label.playfilespeech=\u041e\u0431\u0430\u0432\u0435\u0441\u0442\u0438 \u0433\u043b\u0430\u0441\u043e\u043c \u043e \u043a\u0440\u0430\u0458\u0443 \u043f\u0440\u0438\u0458\u0435\u043c\u0430
-ConfigView.label.playfilespeech.info=\u0413\u043e\u0432\u043e\u0440\u043d\u0435 \u0443\u0441\u043b\u0443\u0433\u0435 \u0442\u0440\u0435\u043d\u0443\u0442\u043d\u043e \u043d\u0430\u0458\u0431\u043e\u0459\u0435 \u0440\u0430\u0434\u0435 \u043d\u0430 \u0435\u043d\u0433\u043b\u0435\u0441\u043a\u043e\u043c \u0458\u0435\u0437\u0438\u043a\u0443
 ConfigView.label.playfilefinished=\u041f\u0443\u0441\u0442\u0438 \u0437\u0432\u0443\u043a \u043a\u0430\u0434\u0430 \u0441\u0435 \u043f\u0440\u0435\u043d\u043e\u0441 \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0435 \u0437\u0430\u0432\u0440\u0448\u0438
 ConfigView.label.backupconfigfiles=\u041f\u0440\u0438 \u0441\u0432\u0430\u043a\u043e\u043c \u0434\u0435\u0458\u0441\u0442\u0432\u0443 \u043d\u0430\u043f\u0440\u0430\u0432\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0438 \u0443\u043c\u043d\u043e\u0436\u0430\u043a \u0434\u0430\u0442\u043e\u0442\u0435\u043a\u0430 \u0441\u0430 \u043f\u043e\u0434\u0435\u0448\u0430\u0432\u0430\u045a\u0438\u043c\u0430
 ConfigView.section.tracker.client.scrapesingleonly=\u0417\u0430\u0431\u0440\u0430\u043d\u0438 \u0443\u0434\u0440\u0443\u0436\u0438\u0432\u0430\u045a\u0435 \u0447\u0438\u0441\u0442\u0430\u0447\u0430 \u043f\u043e \u043f\u0440\u0430\u0442\u0438\u043e\u0446\u0443 (\u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u043e\u043c\u043e\u0433\u043d\u0435 \u043e\u043a\u043e \u043f\u0440\u0430\u0442\u0438\u043b\u0430\u0446\u0430 \u043a\u043e\u0458\u0438 \u0458\u0430\u0432\u0459\u0430\u0458\u0443 \u0434\u [...]
@@ -2157,16 +2138,11 @@ v3.mb.delPublished.title=\u041f\u0440\u0435\u043a\u0438\u043d\u0438 \u0437\u0430
 v3.mb.delPublished.text=\u0423\u041f\u041e\u0417\u041e\u0420\u0415\u040a\u0415: \u041e\u0432\u043e \u0434\u0435\u0458\u0441\u0442\u0432\u043e \u041d\u0415\u040b\u0415 \u0443\u043a\u043b\u043e\u043d\u0438\u0442\u0438 \u043e\u0431\u0458\u0430\u0432\u0459\u0435\u043d \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u201e%1\u201f \u0441\u0430 <A HREF="%2">%3</A> .\n\n\u041f\u0440\u0438\u0442\u0438\u0441\u043d\u0438\u0442\u0435 \u201e\u0423\u043a\u043b\u043e\u043d\u0438\u201f \u0441\u0430\u043c\u0 [...]
 v3.mb.delPublished.delete=&\u0423\u043a\u043b\u043e\u043d\u0438
 v3.mb.delPublished.cancel=\u041e\u0442\u043a\u0430&\u0436\u0438
-v3.mb.openFile.button.play=\u041f\u0443\u0441\u0442\u0438
 v3.mb.PlayFileNotFound.title=\u0414\u0430\u0442\u043e\u0442\u0435\u043a\u0430 \u043d\u0438\u0458\u0435 \u043d\u0430\u0452\u0435\u043d\u0430
 v3.mb.PlayFileNotFound.text=\u0414\u0430\u0442\u043e\u0442\u0435\u043a\u0435 \u0437\u0430 \u201e%1\u201f \u0441\u0443 \u0438\u043b\u0438 \u0443\u043a\u043b\u043e\u045a\u0435\u043d\u0435 \u0438\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0458\u0443.
 v3.mb.PlayFileNotFound.button.remove=\u0423\u043a\u043b\u043e\u043d\u0438 \u0438\u0437 \u0410\u0437\u0443\u0440\u0435\u0443\u0441\u0430
 v3.mb.PlayFileNotFound.button.redownload=\u041f\u043e\u043d\u043e\u0432\u043d\u0438 \u043f\u0440\u0438\u0458\u0435\u043c
 v3.mb.PlayFileNotFound.button.find=\u0420\u0443\u0447\u043d\u043e \u0442\u0440\u0430\u0436\u0435\u045a\u0435...
-v3.mb.deletePurchased.title=\u0423\u043a\u043b\u043e\u043d\u0438 \u043a\u0443\u043f\u0459\u0435\u043d\u0438 \u0441\u0430\u0434\u0440\u0436\u0430\u0458
-v3.mb.deletePurchased.text=\u0414\u0430 \u043b\u0438 \u0441\u0438\u0433\u0443\u0440\u043d\u043e \u0452\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u0443\u043a\u043b\u043e\u043d\u0438\u0442\u0435 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u201e%1\u201f?\n\n\u041e\u0432\u0430\u0458 \u0441\u0442\u0435 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u0438\u043b\u0438 \u043a\u0443\u043f\u0438\u043b\u0438 \u0438\u043b\u0438 \u0458\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u0430 \u043f\u044 [...]
-v3.mb.deletePurchased.button.delete=&\u0423\u043a\u043b\u043e\u043d\u0438
-v3.mb.deletePurchased.button.cancel=\u041e\u0442\u043a\u0430&\u0436\u0438
 v3.topbar.menu.show.logo=\u041b\u043e\u0433\u043e\u0442\u0438\u043f
 v3.topbar.menu.show.plugin=\u041e\u0431\u043b\u0430\u0441\u0442 \u0441\u0430 \u0434\u043e\u0434\u0430\u0446\u0438\u043c\u0430
 v3.topbar.menu.show.search=\u041f\u0440\u0435\u0442\u0440\u0430\u0433\u0430
diff --git a/org/gudy/azureus2/internat/MessagesBundle_sr_Latin.properties b/org/gudy/azureus2/internat/MessagesBundle_sr_Latin.properties
index b3a0209..5abacc7 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_sr_Latin.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_sr_Latin.properties
@@ -50,13 +50,10 @@ MainWindow.menu.help=&Pomo\u0107
 MainWindow.menu.help.about=O Azureusu
 MainWindow.menu.torrent=T&orent
 MainWindow.about.title=O programu
-MainWindow.about.section.developers=Razvija\u010di
-MainWindow.about.section.translators=Prevodioci
 MainWindow.about.section.system=Sistem
 MainWindow.about.section.internet=Internet
 MainWindow.about.internet.homepage=Azureusova strana
 MainWindow.about.internet.sourceforge=Strana Sorsford\u017eovog projekta
-MainWindow.about.internet.sourceforgedownloads=Prijem sa Sorsford\u017ea
 MainWindow.about.internet.bugreports=Prijava gre\u0161aka
 MainWindow.about.internet.forumdiscussion=Forumi
 MainWindow.about.internet.wiki=Pitanja o Azureusu na Vikiju
@@ -330,8 +327,6 @@ IrcView.help=Va\u017ee\u0107e komande su :\n . /help : prikazuje ovu poruku\n .
 PasswordWindow.title=Vuze je zaklju\u010dan
 PasswordWindow.passwordprotected=Da bi bio prikazan Azureusov prozor, molimo da uneset ovde Va\u0161u lozinku :
 Button.ok=&U redu
-TrackerChangerWindow.title=Dodaj pratioca
-TrackerChangerWindow.newtracker=Dodaj nov URL za pratioca
 PeersView.discarded=Odba\u010deno
 PeersView.discarded.info=Podaci koje ste nekako primili iako Vam nisu bili potrebni, pa ste ih se otarasili.
 discarded=odba\u010deno
@@ -403,7 +398,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Ukloni &torent datoteku
 MyTorrentsView.menu.removeand.deletedata=Ukloni &podatke
 MyTorrentsView.menu.removeand.deleteboth=Ukloni &oboje
 deletedata.title=Upozorenje
-deletedata.message1=Samo \u0161to niste uklonili PODATKE sa :\n
 deletedata.message2=\nDa li sigurno da \u017eelite da nastavite?
 MainWindow.menu.file.configure=&\u010carobnjak za pode\u0161avanja...
 configureWizard.title=\u010carobnjak za pode\u0161avanja
@@ -426,7 +420,6 @@ configureWizard.transfer.maxActiveTorrents=Najvi\u0161e aktivnih
 configureWizard.transfer.maxDownloads=Najvi\u0161e prijema
 configureWizard.transfer.maxUploadsPerTorrent=Najvi\u0161e slanja po torentu
 configureWizard.nat.title=NAT / port servera
-configureWizard.nat.message=Kako biste izvukli maksimum iz Bit Torenta, preporu\u010duje se da ra\u010dunar bude potpuno dostupan sa interneta. Ovaj alat vam dopu\u0161ta da proverite i promenite broj porta koji se koristi za prihvat dolaznih veza.\n\nPRIMEDBA: Ovaj alat samo proverava TCP veze. Raspodeljena baza podataka tra\u017ei i UDP veze, ali \u0107e Vas automatski obavestit ako otkrije blokiraju\u0107i vatrobran.\n\nPRIMEDBA: TCP port 6880 je rezervisann i ne mo\u017ee se koristiti.
 configureWizard.nat.test=Proba
 configureWizard.nat.testing=Port za probu
 configureWizard.nat.ok=U redu !
@@ -601,7 +594,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=Dobavlja\u010d dinami\u010dke i stati\u010dke DNS adrese\n(ne postoji besplatna usluga provere adrese)
 ConfigView.section.tracker.publicenable=Uklju\u010di spolja\u0161nje torente
 ConfigView.label.playdownloadspeech=Obavesti glasom o kraju prijema
-ConfigView.label.playdownloadspeech.info=Govorne usluge trenutno najbolje rade na engleskom jeziku
 #
 # Tooltips
 #
@@ -778,8 +770,6 @@ ConfigView.section.tracker.main=Glavni
 ConfigView.section.tracker.web=Mre\u017ea
 ConfigView.label.prioritizefirstpiece=Stavi prioritet na prvi i poslednji deo datoteka
 ConfigView.label.prioritizefirstpiece.tooltip=Poku\u0161ava da prvo preuzme sam po\u010detak i sam kraj svake datoteke.\nSlu\u017ei da podr\u017ei rani pregled sadr\u017eaja.
-ConfigView.section.file.confirm_data_delete=Tra\u017ei potvrdu pre uklanjanja podataka
-ConfigView.section.file.confirm_data_delete.tooltip=Potvrdi uklanjanje podataka pri upotrebi \u201eUkloni i obri\u0161i...\u201c
 TrayWindow.menu.startalldownloads=Pokreni sve prijeme
 SystemTray.menu.startalltransfers=Pokreni sve prenose
 sharing.progress.title=Tok deljenja
@@ -1101,7 +1091,6 @@ ConfigView.pluginlist.whereToPutOr=Za deljene dodatke koristite:
 MainWindow.statusText.checking=Proveravanje dogradnji...
 TableColumn.header.OnlyCDing4=OnlyCDing4
 TableColumn.header.OnlyCDing4.info=Vreme koje je torent proveo samo u zametanju. Nije ura\u010dunato vreme kada je torent priman (i zametan u isto vreme).
-ConfigView.section.style.alternateTablePainting=Koristi drugi na\u010din za crtanje kolona u tabelama (mo\u017ee da tra\u017ei restart)
 UpdateWindow.status.restartMaybeNeeded=Mo\u017eda \u0107ete morati da ponovo pokrenete program
 ConfigView.pluginlist.shared=deljeno
 PeersView.host=Ime ra\u010dunara
@@ -1344,18 +1333,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=Veli\u010dina SO_SNDBUF za uti\
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=Postavlja standarnu veli\u010dinu SO_SNDBUF (u bajtovima), tj. veli\u010dinu TCPovog prozora za slanje.\nAuzreus ostavlja ovo nepode\u0161eno, \u0161to zna\u010di da se koriste vrednosti zadate u operativnom sistemu.\nPrimedba:Linuks udvostru\u010duje ovu vrednost.
 ConfigView.section.connection.advanced.IPTOS=Vrsta usluge u odlaznim paketima (TOS)
 ConfigView.section.connection.advanced.IPTOS.tooltip=Postavlja vrstu saobra\u0107aja (TOS) u zaglavlju odlaze\u0107ih IP paketa.\nVuze ostavlja ovu vrednost nepode\u0161enu \u0161to zna\u010di da se koriste podrazumevane vrednosti u oprativnom sistemu.\nPrimeri vrednosti su:\n0x02 za IPTOS_LOWCOST\n0x04 za IPTOS_RELIABILITY\n0x08 za IPTOS_THROUGHPUT\n0x10 za IPTOS_LOWDELAY\nPRIMEDBA: implementacije mre\u017ee mogu da zanemare ovu vrednost, tako da ona jako zavisi od izdanja operativnog s [...]
-ConfigView.section.interface.confirm_torrent_removal=Prika\u017ei prozor za potvrdu za uklanjanje torenta
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Potvrdi uklanjale torenta iz pregleda Mojih torenta.
-MyTorrentsView.confirm_torrent_removal=Da li sigurno \u017eelite da uklonite?\n
 TableColumn.header.seed_to_peer_ratio=Odnos broja zametaka i ra\u010dunara
 TableColumn.header.seed_to_peer_ratio.info=Odnos broja zametaka u roju i broja ra\u010dunara
 PeersView.connected_time=Vreme veze
 PeersView.connected_time.info=Ukupno vreme veze sa ra\u010dunarima
-ConfigView.section.interface.display.add_torrents_silently=Tiho dodavanje torenta
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Dodaj torente ne pokazuju\u0107i glavni Azureusov prozor
 TableColumn.header.maxdownspeed=Najve\u0107a brzina prijema
 TableColumn.header.maxdownspeed.info=Najve\u0107a brzina prijema po torentu
-PeersGraphicView.title=Roj
+PeersGraphicView.title.full=Roj
 ConfigView.section.tracker.passwordwebhttpsonly=Dozvoli pristup samo kroz HTTPS
 TableColumn.header.torrentpath=Mesto torenta
 TableColumn.header.torrentpath.info=Mesto gde se Torenti \u010duvaju na disku
@@ -1412,8 +1396,6 @@ UpdateWindow.restartLater=Pokreni Azureusa ponovo, ali kasnije
 MainWindow.menu.file.restart=Pokreni ponovo
 MainWindow.dialog.restartconfirmation.title=Da li da ponovo pokrenem Azureusa?
 MainWindow.dialog.restartconfirmation.text=Da li zaista \u017eelite da restartujete Azureusa?
-deletetorrent.message1=Samo \u0161to niste uklonili TORENT za :\n
-deletetorrent.message2=\nDa li sigurno da \u017eelite da nastavite?
 ConfigView.label.prioritizemostcompletedfiles=Uredi datoteke sa visokom prioritetom prema procentu zavr\u0161etka i veli\u010dini datoteke
 splash.plugin.init=Pokretanje dodatka:
 ConfigView.section.style.osx_small_fonts=Koristi sitna slova [tra\u017ei ponovno pokretanje]
@@ -1584,7 +1566,6 @@ VivaldiView.title.full=Vivaldi
 MyTrackerView.date_added=Dodato
 ConfigView.section.tracker.portbackup=Rezervni portovi (\u201e;\u201c za razdvajanje)
 ConfigView.label.playfilespeech=Obavesti glasom o kraju prijema
-ConfigView.label.playfilespeech.info=Govorne usluge trenutno najbolje rade na engleskom jeziku
 ConfigView.label.playfilefinished=Pusti zvuk kada se prenos datoteke zavr\u0161i
 ConfigView.label.backupconfigfiles=Pri svakom dejstvu napravi rezervni umno\u017eak datoteka sa pode\u0161avanjima
 ConfigView.section.tracker.client.scrapesingleonly=Zabrani udru\u017eivanje \u010dista\u010da po pratiocu (mo\u017ee da pomogne oko pratilaca koji javljaju da je URL preduga\u010dak (gre\u0161ka 414))
@@ -2415,11 +2396,6 @@ v3.mb.PlayFileNotFound.button.remove=Ukloni iz Azureusa
 v3.mb.PlayFileNotFound.button.redownload=Ponovni prijem
 v3.mb.PlayFileNotFound.button.find=Ru\u010dno tra\u017eenje...
 
-v3.mb.deletePurchased.title=Ukloni kupljeni sadr\u017eaj
-v3.mb.deletePurchased.text=Da li sigurno \u0111elite da uklonite sadr\u017eaj \u201e%1\u201f?\n\nOvaj ste sadr\u017eaj ili kupili ili je potrebna prijava da biste ga preuzeli.
-v3.mb.deletePurchased.button.delete=&Ukloni
-v3.mb.deletePurchased.button.cancel=Otka&\u017ei
-
 v3.topbar.menu.show.logo=Logotip
 v3.topbar.menu.show.plugin=Oblast sa dodacima
 v3.topbar.menu.show.search=Pretraga
diff --git a/org/gudy/azureus2/internat/MessagesBundle_sv_SE.properties b/org/gudy/azureus2/internat/MessagesBundle_sv_SE.properties
index 39397c2..ac264ea 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_sv_SE.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_sv_SE.properties
@@ -36,13 +36,10 @@ MainWindow.menu.window.alltofront=Placera alla &fr\u00e4mst
 MainWindow.menu.help=&Hj\u00e4lp 
 MainWindow.menu.help.about=Om Vuze
 MainWindow.about.title=Om 
-MainWindow.about.section.developers=Utvecklare 
-MainWindow.about.section.translators=\u00d6vers\u00e4ttare 
 MainWindow.about.section.system=System 
 MainWindow.about.section.internet=Internet 
 MainWindow.about.internet.homepage=Vuze hemsida 
 MainWindow.about.internet.sourceforge=Projektets SourceForge-sida 
-MainWindow.about.internet.sourceforgedownloads=Nedladdningar fr\u00e5n SourceForge.net 
 MainWindow.about.internet.bugreports=Rapportera buggar 
 MainWindow.about.internet.forumdiscussion=Allm\u00e4nt diskussionsforum 
 MainWindow.about.internet.wiki=Vuze Wiki FAQ 
@@ -317,8 +314,6 @@ IrcView.help=Giltiga kommandon \u00e4r :\n . /help : visar detta meddelande\n .
 PasswordWindow.title=Vuze \u00e5r l\u00e5st 
 PasswordWindow.passwordprotected=Vuze \u00e4r l\u00f6senordsskyddat.\nSkriv in ditt l\u00f6senord f\u00f6r att forts\u00e4tta: 
 Button.ok=Ok
-TrackerChangerWindow.title=L\u00e4gg till tracker 
-TrackerChangerWindow.newtracker=Ange ny trackeradress
 PeersView.discarded=Bortkastat 
 PeersView.discarded.info=Data som du tagit emot men som du inte beh\u00f6vde. D\u00e4rf\u00f6r kastas den bort.
 discarded=bortkastat 
@@ -389,7 +384,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Radera &Torrentfilen
 MyTorrentsView.menu.removeand.deletedata=Radera &Data
 MyTorrentsView.menu.removeand.deleteboth=Radera Allt
 deletedata.title=Varning
-deletedata.message1=Vill du verkligen radera DATA fr\u00e5n '%1'?
 deletedata.noprompt=Fr\u00e5ga mig inte igen
 MainWindow.menu.file.configure=Guide -- Konfigurationsguide...
 configureWizard.title=Guide -- Konfigurationsguide
@@ -412,7 +406,6 @@ configureWizard.transfer.maxActiveTorrents=Max aktiva
 configureWizard.transfer.maxDownloads=Max nedladdningar
 configureWizard.transfer.maxUploadsPerTorrent=Max uppladdningar per torrent
 configureWizard.nat.title=NAT / serverportar
-configureWizard.nat.message=F\u00f6r att f\u00e5 b\u00e4sta prestanda beh\u00f6ver du ha full tillg\u00e4nglighet till internet. Standardportar \u00e4r 6881 till 6889. Guiden kan testa och \u00e4ndra dessa portar f\u00f6r att se vilka som \u00e4r b\u00e4st att anv\u00e4nda. Om du redan har n\u00e5gra torrents aktiva kan vissa portar vara upptagna.
 configureWizard.nat.test=Test 
 configureWizard.nat.testing=Testar port 
 configureWizard.nat.ko=NAT-fel 
@@ -580,7 +573,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=Dynamisk och statisk DNS-tj\u00e4nst
 ConfigView.section.tracker.publicenable=Till\u00e5t externa torrents 
 ConfigView.label.playdownloadspeech=Tala om n\u00e4r en nedladdning \u00e4r slutf\u00f6rd
-ConfigView.label.playdownloadspeech.info=Taltj\u00e4nsten fungerar f\u00f6r n\u00e4rvarande b\u00e4st med engelska
 #
 # Tooltips
 #
@@ -754,8 +746,6 @@ ConfigView.section.tracker.main=Tracker
 ConfigView.section.tracker.web=Webbsida
 ConfigView.label.prioritizefirstpiece=Prioritera f\u00f6rsta och sista delen p\u00e5 filerna
 ConfigView.label.prioritizefirstpiece.tooltip=F\u00f6rs\u00f6ker ladda ned b\u00f6rjan och slutet p\u00e5 varje fil allra f\u00f6rst s\u00e5 att det\nblir l\u00e4ttare att f\u00f6rhandsgranska innan hela filen \u00e4r nedladdad.
-ConfigView.section.file.confirm_data_delete=Bekr\u00e4fta vid radering av data 
-ConfigView.section.file.confirm_data_delete.tooltip=Bekr\u00e4fta radering av data n\u00e4r du anv\u00e4nder 'Ta bort..'
 TrayWindow.menu.startalldownloads=Starta alla nedladdningar
 SystemTray.menu.startalltransfers=Starta alla \u00f6verf\u00f6ringar
 sharing.progress.hide=D\u00f6lj
@@ -1063,7 +1053,6 @@ ConfigView.pluginlist.whereToPutOr=Anv\u00e4nd katalog f\u00f6r delade plugins:
 MainWindow.statusText.checking=Kontrollerar om det finns uppdateringar
 TableColumn.header.OnlyCDing4=Tid uppladdning
 TableColumn.header.OnlyCDing4.info=Tid som torrenten endast har laddat upp data.
-ConfigView.section.style.alternateTablePainting=Anv\u00e4nd en annan metod f\u00f6r att rita de grafiska tabellkolumnerna (kanske kr\u00e4ver omstart)
 UpdateWindow.status.restartMaybeNeeded=Omstart kan beh\u00f6vas
 ConfigView.pluginlist.shared=delade
 PeersView.host=Dom\u00e4nnamn
@@ -1294,18 +1283,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Storlek p\u00e5 "Socket SO_RCVB
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=St\u00e4ll in standardv\u00e4rdet f\u00f6r "Socket SO_RCVBUF" (i bytes), d v s storlek och skala p\u00e5 mottagningsf\u00f6nstret f\u00f6r TCP.\nVuze l\u00e4mnar normalt denna tom vilket betyder att operativsystemets standardv\u00e4rde anv\u00e4nds ist\u00e4llet.\nOBS: Linux dubblerar v\u00e4rdet.
 ConfigView.section.connection.advanced.SO_SNDBUF=Storlek p\u00e5 "Socket SO_SNDBUF" [0: operativsystemets standardv\u00e4rde]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=St\u00e4ll in standardv\u00e4rdet f\u00f6r "Socket SO_SNDBUF" (i bytes), d v s storlek p\u00e5 s\u00e4ndningsf\u00f6nstret f\u00f6r TCP.\nVuze l\u00e4mnar normalt denna tom vilket betyder att operativsystemets standardv\u00e4rde anv\u00e4nds ist\u00e4llet.\nOBS: Linux dubblerar v\u00e4rdet.
-ConfigView.section.interface.confirm_torrent_removal=Visa en dialogruta f\u00f6r bekr\u00e4ftelse vid borttagning av torrent
-ConfigView.section.interface.confirm_torrent_removal.tooltip=Bekr\u00e4fta vid borttagning av torrent fr\u00e5n "Mina Torrents".
-MyTorrentsView.confirm_torrent_removal=\u00c4r du s\u00e4ker p\u00e5 att du vill ta bort?\n
 TableColumn.header.seed_to_peer_ratio=Ratio
 TableColumn.header.seed_to_peer_ratio.info=Ratio totalt i sv\u00e4rmen
 PeersView.connected_time=Ansluten tid
 PeersView.connected_time.info=Totala tiden ansluten till klient
-ConfigView.section.interface.display.add_torrents_silently=L\u00e4gg till torrents automatiskt
-ConfigView.section.interface.display.add_torrents_silently.tooltip=L\u00e4gg till torrentnedladdningar utan att aktivera Vuze huvudf\u00f6nster.
 TableColumn.header.maxdownspeed=Max nedladdninghastighet
 TableColumn.header.maxdownspeed.info=Max nedladdningshastighet per torrent
-PeersGraphicView.title=Sv\u00e4rm
+PeersGraphicView.title.full=Sv\u00e4rm
 ConfigView.section.tracker.passwordwebhttpsonly=Till\u00e5t endast \u00e5tkomst via HTTPS
 TableColumn.header.torrentpath=Torrentfilens plats
 TableColumn.header.torrentpath.info=Var torrentfilen finns p\u00e5 h\u00e5rddisken
@@ -1362,8 +1346,6 @@ UpdateWindow.restartLater=Starta om senare
 MainWindow.menu.file.restart=Starta om Vuze
 MainWindow.dialog.restartconfirmation.title=Starta om Vuze
 MainWindow.dialog.restartconfirmation.text=Vill du verkligen starta om Vuze?
-deletetorrent.message1=Du \u00e4r p\u00e5 v\u00e4g att radera TORRENT filen f\u00f6r :\n\n
-deletetorrent.message2=\n\n\u00c4r du s\u00e4ker p\u00e5 att du vill forts\u00e4tta?
 ConfigView.label.prioritizemostcompletedfiles=Prioritera de mest kompletta filerna
 splash.plugin.init=Initialiserar plugin: 
 splash.plugin.UIinit=Initialiserar Plugin GUI: %1  
@@ -1530,7 +1512,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrentfile... (F\u00f6r tracking)
 MyTrackerView.date_added=Tillagd
 ConfigView.section.tracker.portbackup=Reservportar (Separeras med komma)
 ConfigView.label.playfilespeech=Tala om n\u00e4r en fil \u00e4r nedladdad
-ConfigView.label.playfilespeech.info=Taltj\u00e4nsten fungerar f\u00f6r n\u00e4rvarande b\u00e4st med engelska
 ConfigView.label.playfilefinished=Spela upp ett ljud n\u00e4r en fil \u00e4r nedladdad
 ConfigView.label.backupconfigfiles=S\u00e4kerhetskopiera konfigurationsfilerna i \u00e5terst\u00e4llningssyfte
 ConfigView.section.tracker.client.scrapesingleonly=Inaktivera skrapningsanhopning (Det kan avhj\u00e4lpa fel s\u00e5som "URL too long".
@@ -1792,7 +1773,7 @@ MyTorrentsView.dialog.setFilter.text=%1 kommer att filtreras med nedan angiven t
 MyTorrentsView.filter.tooltip=Anv\u00e4nd Ctrl+X f\u00f6r att byta mellan RegEx och normalt l\u00e4ge.\nAnv\u00e4nd tecknet | f\u00f6r att separera fraser.
 MyTorrentsView.clearFilter.tooltip=Rensa filter
 MyTorrentsView.menu.filter=Filter...
-ConfigView.section.file.resume.recheck.all=Vid onstart efter krash kontrollera alla delar i hela filen (Annars kontrolleras endast delar som var aktiva n\u00e4r Spara utf\u00f6rdes senast)
+ConfigView.section.file.resume.recheck.all=Vid omstart efter krash kontrollera alla delar i hela filen (annars kontrolleras endast delar som var aktiva n\u00e4r Spara utf\u00f6rdes senast)
 ConfigureWizard.language.choose=V\u00e4lj ett spr\u00e5k i listan:
 popup.closing.in=F\u00f6nstret st\u00e4ngs automatiskt om %1 sekunder
 popup.more.waiting=%1 meddelande(n) till..
@@ -2142,22 +2123,11 @@ v3.mb.delPublished.title=Stoppa uppladdning
 v3.mb.delPublished.text=VARNING: Detta tar INTE bort ditt publicerade inneh\u00e5ll "%1" fr\u00e5n <A HREF="%2">%3</A>.\n\nKlicka p\u00e5  "Radera" om du vill beh\u00e5lla ditt material publicerat och nedladdningsbart, men bara frig\u00f6ra bandbredd. F\u00f6rs\u00e4kra dig om att materialet \u00e4r f\u00e4rdiguppladdat f\u00f6rst. (<A HREF="%4">hur</A>?).\n\nKlicka "Avbryt" om du vill ta bort ditt publicerade material fr\u00e5n %3, och anv\u00e4nd ist\u00e4llet knappen (X) i panelen "Pu [...]
 v3.mb.delPublished.delete=Ra&dera
 v3.mb.delPublished.cancel=Avbryt
-v3.mb.openFile.title=\u00d6ppna
-v3.mb.openFile.text.known=Det h\u00e4r inneh\u00e5llet st\u00f6ds f\u00f6r tillf\u00e4llet inte av Vuze Player. L\u00e4s <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Uppspelningsguiden</a> f\u00f6r ytterliggare information och hj\u00e4lp.\n\nFiltypen verkar vara: %2 (%3)\n
-v3.mb.openFile.text.unknown=Det h\u00e4r inneh\u00e5llet st\u00f6ds f\u00f6r tillf\u00e4llet inte av Vuze Player. L\u00e4s <a href="http://www.azureuswiki.com/index.php/Playback_Guide">Uppspelningsguiden</a> f\u00f6r ytterliggare information och hj\u00e4lp.\n\nFil\u00e4ndelse: %2\n
-v3.mb.openFile.button.play=Spela Upp
-v3.mb.openFile.button.cancel=Avbryt
-v3.mb.openFile.button.guide=L\u00e4s Uppspelningsguiden
-v3.mb.openFile.remember=\u00d6ppna alltid filer utan att fr\u00e5ga mig
 v3.mb.PlayFileNotFound.title=Filen hittades inte
 v3.mb.PlayFileNotFound.text=Filerna "%1" saknas eller \u00e4r raderade.
 v3.mb.PlayFileNotFound.button.remove=Ta bort fr\u00e5n Vuze
 v3.mb.PlayFileNotFound.button.redownload=Ladda ned p\u00e5 nytt
 v3.mb.PlayFileNotFound.button.find=S\u00f6k manuellt..
-v3.mb.deletePurchased.title=Radera ink\u00f6pt material
-v3.mb.deletePurchased.text=\u00c4r du s\u00e4ker p\u00e5 att du vill radera "%1"?\n\nAntingen har du k\u00f6pt detta material eller s\u00e5 var du tvungen att logga in f\u00f6r att ladda ned.
-v3.mb.deletePurchased.button.delete=Ra&dera
-v3.mb.deletePurchased.button.cancel=Avbryt
 v3.topbar.menu.show.plugin=Pluginomr\u00e5de
 v3.topbar.menu.show.search=S\u00f6k
 splash.initializeCore=Initialiserar k\u00e4rna
@@ -2376,9 +2346,6 @@ metasearch.addtemplate.dup.title=Kopiera Mall
 metasearch.addtemplate.dup.desc=S\u00f6kmallen %1 \u00e4r redan installerad
 metasearch.export.select.template.file=Spara Mall
 metasearch.import.select.template.file=\u00d6ppna Mall
-dialog.uiswitch.title=V\u00e4xla till Vuze UI
-dialog.uiswitch.text=Du m\u00e5ste k\u00f6ra Vuze gr\u00e4nssnittet f\u00f6r att anv\u00e4nda den h\u00e4r funktionen\n\nVuze m\u00e5ste startas om.
-dialog.uiswitch.button=V\u00e4xla till Vuze UI
 v3.MainWindow.button.download=Ladda ned
 v3.MainWindow.button.run=\u00d6ppna det h\u00e4mtade objektet.
 v3.activity.header.downloads=Nedladdningar
@@ -2491,7 +2458,7 @@ Wizard.Subscription.rss.subtitle2=M\u00e5nga publicerar RSS fl\u00f6den av sitt
 Wizard.Subscription.rss.subtitle3=N\u00e4r du har sparat f\u00e5r du uppdateringar live via ditt RSS fl\u00f6de i sidpanelen n\u00e4r nya resultat \u00e4r tillg\u00e4ngliga.
 Wizard.Subscription.subscribe.library=Inneh\u00e5ll i ditt bibliotek
 Wizard.Subscription.subscribe.subscriptions=Tillh\u00f6rande prenumerationer
-Wizard.Subscription.subscribe.library.empty=\u00c4r inga prenumerationer tillg\u00e5ngliga?\n \nTitta efter den oranga prenumerationsknappen p\u00e5 Vuze HD N\u00e4tverket.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">L\u00e4s mer</A>
+Wizard.Subscription.subscribe.library.empty=\u00c4r inga prenumerationer tillg\u00e5ngliga?\n \nTitta efter den oranga prenumerationsknappen p\u00e5 Vuze HD N\u00e4tverket.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">L\u00e4s mer</A>
 message.confirm.delete.title=Bekr\u00e4fta Radering
 message.confirm.delete.text=Vill du verkligen radera '%1'?
 Subscription.menu.properties=Egenskaper
@@ -2519,7 +2486,7 @@ statusbar.feedback.tooltip=Klicka h\u00e4r f\u00f6r att skicka feedback
 sidebar.Activity=Notifieringar
 v3.activity.button.watchall=Markera Alla som Sedda
 subscriptions.view.help.1=Du kan l\u00e4gga till Prenumerationer d\u00e4r du ser
-subscriptions.view.help.2=F\u00e5 gratis och aktuell information om n\u00e4r nytt inneh\u00e5ll \u00e4r tillg\u00e4ngligt f\u00f6r nedladdning. <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">L\u00e4s mer</A>.
+subscriptions.view.help.2=F\u00e5 gratis och aktuell information om n\u00e4r nytt inneh\u00e5ll \u00e4r tillg\u00e4ngligt f\u00f6r nedladdning. <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">L\u00e4s mer</A>.
 sidebar.sash.tooltip=F7 f\u00f6r att snabbt visa/d\u00f6lja sidpanelen
 sidebar.expand.tooltip=Expandera Sidpanelen
 sidebar.dropdown.tooltip=Visa sidpanelen i menyformat
@@ -2548,7 +2515,6 @@ v3.MainWindow.menu.contentnetworks.manage=Hantera HD N\u00e4tverk
 azbuddy.ui.menu.cat=Kategorier
 azbuddy.ui.menu.cat.set_msg=Kommaseparerad lista av kategorier eller 'Alla'
 azbuddy.ui.menu.cat_subs=Prenumerera
-v3.dialog.cnmanage.title=Hantera menyn f\u00f6r HD N\u00e4tverk
 TableColumn.header.TableColumnChosenColumn=Vald Kolumn
 ColumnSetup.chosencolumns=Valda Kolumner
 ColumnSetup.categories=Kategorier:
diff --git a/org/gudy/azureus2/internat/MessagesBundle_th_TH.properties b/org/gudy/azureus2/internat/MessagesBundle_th_TH.properties
index df4c18a..2c5a162 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_th_TH.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_th_TH.properties
@@ -32,12 +32,9 @@ MainWindow.menu.window.alltofront=\u0e40\u0e2d\u0e32\u0e02\u0e36\u0e49\u0e19\u0e
 MainWindow.menu.help=&\u0e0a\u0e48\u0e27\u0e22\u0e40\u0e2b\u0e25\u0e37\u0e2d
 MainWindow.menu.help.about=\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a Vuze
 MainWindow.about.title=\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a
-MainWindow.about.section.developers=\u0e1c\u0e39\u0e49\u0e1e\u0e31\u0e12\u0e19\u0e32
-MainWindow.about.section.translators=\u0e1c\u0e39\u0e49\u0e41\u0e1b\u0e25
 MainWindow.about.section.internet=\u0e2d\u0e34\u0e19\u0e40\u0e15\u0e2d\u0e40\u0e19\u0e47\u0e15
 MainWindow.about.internet.homepage=Homepage \u0e02\u0e2d\u0e07 Vuze
 MainWindow.about.internet.sourceforge=\u0e2b\u0e19\u0e49\u0e32\u0e42\u0e04\u0e23\u0e07\u0e01\u0e32\u0e23\u0e02\u0e2d\u0e07 Sourceforge
-MainWindow.about.internet.sourceforgedownloads=\u0e2b\u0e19\u0e49\u0e32\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14\u0e02\u0e2d\u0e07 Sourceforge
 MainWindow.about.internet.bugreports=\u0e41\u0e08\u0e49\u0e07\u0e02\u0e49\u0e2d\u0e1c\u0e34\u0e14\u0e1e\u0e25\u0e32\u0e14
 MainWindow.about.internet.forumdiscussion=\u0e2d\u0e20\u0e34\u0e1b\u0e23\u0e32\u0e22
 MainWindow.about.internet.wiki=Wiki \u0e04\u0e33\u0e16\u0e32\u0e21\u0e17\u0e35\u0e48\u0e16\u0e39\u0e01\u0e16\u0e32\u0e21\u0e1a\u0e48\u0e2d\u0e22\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a Vuze
@@ -286,8 +283,6 @@ IrcView.help=\u0e04\u0e33\u0e2a\u0e31\u0e48\u0e07\u0e17\u0e35\u0e48\u0e16\u0e39\
 PasswordWindow.title=Vuze \u0e16\u0e39\u0e01\u0e25\u0e47\u0e2d\u0e01
 PasswordWindow.passwordprotected=Vuze \u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a\u0e01\u0e32\u0e23\u0e1b\u0e49\u0e2d\u0e07\u0e01\u0e31\u0e19\u0e08\u0e32\u0e01\u0e23\u0e2b\u0e31\u0e2a\u0e1c\u0e48\u0e32\u0e19\n\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e17\u0e35\u0e48\u0e08\u0e30\u0e41\u0e2a\u0e14\u0e07\u0e2b\u0e19\u0e49\u0e32\u0e15\u0e48\u0e32\u0e07 Vuze \u0e42\u0e1b\u0e23\u0e14\u0e43\u0e2a\u0e48\u0e23\u0e2b\u0e31\u0e2a\u0e1c\u0e48\u0e32\u0e19\u0e02\u0e2d\u0e07\u0e04\u0e38\u0e13\u0e17\u0e35\u0e48\u0e19\u [...]
 Button.ok=\u0e15\u0e01\u0e25\u0e07
-TrackerChangerWindow.title=\u0e40\u0e1e\u0e34\u0e48\u0e21 Tracker
-TrackerChangerWindow.newtracker=\u0e43\u0e2a\u0e48 tracker url \u0e43\u0e2b\u0e21\u0e48
 PeersView.discarded=\u0e25\u0e30\u0e17\u0e34\u0e49\u0e07
 PeersView.discarded.info=\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e35\u0e48\u0e04\u0e38\u0e13\u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a\u0e41\u0e21\u0e49\u0e44\u0e21\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23, \u0e04\u0e38\u0e13\u0e40\u0e2d\u0e32\u0e21\u0e31\u0e19\u0e2d\u0e2d\u0e01
 discarded=\u0e17\u0e34\u0e49\u0e07
@@ -354,7 +349,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u0e25\u0e1a .&torrent
 MyTorrentsView.menu.removeand.deletedata=\u0e25\u0e1a &\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25
 MyTorrentsView.menu.removeand.deleteboth=\u0e25\u0e1a &\u0e17\u0e31\u0e49\u0e07\u0e04\u0e39\u0e48
 deletedata.title=!!! \u0e04\u0e33\u0e40\u0e15\u0e37\u0e2d\u0e19 !!!
-deletedata.message1=\u0e04\u0e38\u0e13\u0e01\u0e33\u0e25\u0e31\u0e07\u0e08\u0e30\u0e25\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e32\u0e01 :\n
 MainWindow.menu.file.configure=\u0e1b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e07 &\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34
 configureWizard.title=\u0e01\u0e32\u0e23\u0e1b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e07\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34
 configureWizard.welcome.title=\u0e22\u0e34\u0e19\u0e14\u0e35\u0e15\u0e49\u0e2d\u0e19\u0e23\u0e31\u0e1a\u0e2a\u0e39\u0e48\u0e23\u0e30\u0e1a\u0e1a\u0e1b\u0e23\u0e31\u0e1a\u0e41\u0e15\u0e48\u0e07\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34\u0e02\u0e2d\u0e07 Vuze
@@ -370,7 +364,6 @@ configureWizard.transfer.maxActiveTorrents=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e01\
 configureWizard.transfer.maxDownloads=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14
 configureWizard.transfer.maxUploadsPerTorrent=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e2d\u0e31\u0e1e\u0e42\u0e2b\u0e25\u0e14\u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14\u0e15\u0e48\u0e2d Torrent
 configureWizard.nat.title=NAT / Server \u0e1e\u0e2d\u0e23\u0e4c\u0e15
-configureWizard.nat.message=\u0e43\u0e19\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49 BitTorrent \u0e17\u0e35\u0e48\u0e08\u0e30\u0e44\u0e14\u0e49\u0e1c\u0e25\u0e14\u0e35\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14\u0e02\u0e2d\u0e07, \u0e02\u0e2d\u0e41\u0e19\u0e30\u0e19\u0e33\u0e43\u0e2b\u0e49\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e2d\u0e34\u0e19\u0e40\u0e15\u0e2d\u0e23\u0e4c\u0e40\u0e19\u0e47\u0e15\u0e44\u0e14\u0e49\u0e2d\u0e22\u0e48\u0e32\u0e07\u0e40\u0e15\u0e47\u0e21 [...]
 configureWizard.nat.test=\u0e17\u0e14\u0e2a\u0e2d\u0e1a
 configureWizard.nat.testing=\u0e01\u0e33\u0e25\u0e31\u0e07\u0e17\u0e14\u0e2a\u0e2d\u0e1a\u0e1e\u0e2d\u0e23\u0e4c\u0e15
 configureWizard.nat.ok=\u0e40\u0e23\u0e35\u0e22\u0e1a\u0e23\u0e49\u0e2d\u0e22 !
@@ -515,7 +508,6 @@ IPChecker.external.service.no-ip.name=\u0e44\u0e21\u0e48\u0e21\u0e35-IP
 IPChecker.external.service.no-ip.description=Dynamic and Static DNS service provider\n('check address' \u0e44\u0e21\u0e48\u0e21\u0e35\u0e1a\u0e23\u0e34\u0e01\u0e32\u0e23\u0e1f\u0e23\u0e35)
 ConfigView.section.tracker.publicenable=\u0e40\u0e1b\u0e34\u0e14\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19 torrents \u0e20\u0e32\u0e22\u0e19\u0e2d\u0e01
 ConfigView.label.playdownloadspeech=\u0e1e\u0e39\u0e14\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e2a\u0e34\u0e49\u0e19
-ConfigView.label.playdownloadspeech.info=\u0e01\u0e32\u0e23\u0e1a\u0e23\u0e34\u0e01\u0e32\u0e23\u0e40\u0e2a\u0e35\u0e22\u0e07\u0e43\u0e0a\u0e49\u0e14\u0e35\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14\u0e01\u0e31\u0e1a\u0e20\u0e32\u0e29\u0e32\u0e2d\u0e31\u0e07\u0e01\u0e24\u0e29
 #
 # Tooltips
 #
@@ -681,8 +673,6 @@ ConfigView.section.tracker.main=\u0e2b\u0e25\u0e31\u0e01
 ConfigView.section.tracker.web=\u0e40\u0e27\u0e47\u0e1a
 ConfigView.label.prioritizefirstpiece=\u0e43\u0e2b\u0e49\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e33\u0e04\u0e31\u0e0d\u0e01\u0e31\u0e1a\u0e2a\u0e48\u0e27\u0e19\u0e15\u0e49\u0e19\u0e02\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25
 ConfigView.label.prioritizefirstpiece.tooltip=\u0e1e\u0e22\u0e32\u0e22\u0e32\u0e21\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14\u0e2a\u0e48\u0e27\u0e19\u0e41\u0e23\u0e01\u0e02\u0e2d\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e01\u0e48\u0e2d\u0e19\n\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2a\u0e19\u0e31\u0e1a\u0e2a\u0e19\u0e38\u0e19\u0e01\u0e32\u0e23\u0e14\u0e39\u0e01\u0e48\u0e2d\u0e19\u0e25\u0e48\u0e27\u0e07\u0e2b\u0e19\u0e49\u0e32
-ConfigView.section.file.confirm_data_delete=\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e2d\u0e35\u0e01\u0e04\u0e23\u0e31\u0e49\u0e07\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e25\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25
-ConfigView.section.file.confirm_data_delete.tooltip=\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e01\u0e32\u0e23\u0e25\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e43\u0e0a\u0e49 '\u0e40\u0e2d\u0e32\u0e2d\u0e2d\u0e01 \u0e41\u0e25\u0e30\u0e25\u0e1a...'
 TrayWindow.menu.startalldownloads=\u0e40\u0e23\u0e34\u0e48\u0e21\u0e01\u0e32\u0e23\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14\u0e17\u0e38\u0e01\u0e2d\u0e31\u0e19
 SystemTray.menu.startalltransfers=\u0e40\u0e23\u0e34\u0e48\u0e21\u0e01\u0e32\u0e23\u0e2a\u0e48\u0e07\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14
 sharing.progress.title=\u0e04\u0e27\u0e32\u0e21\u0e01\u0e49\u0e32\u0e27\u0e2b\u0e19\u0e49\u0e32\u0e43\u0e19\u0e01\u0e32\u0e23\u0e41\u0e1a\u0e48\u0e07\u0e1b\u0e31\u0e19
@@ -984,7 +974,6 @@ ConfigView.pluginlist.whereToPutOr=\u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e42\u0
 MainWindow.statusText.checking=\u0e15\u0e23\u0e27\u0e08\u0e2a\u0e2d\u0e1a\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e2d\u0e31\u0e1e\u0e40\u0e14\u0e17
 TableColumn.header.OnlyCDing4=\u0e40\u0e09\u0e1e\u0e32\u0e30 Seeding
 TableColumn.header.OnlyCDing4.info=\u0e08\u0e33\u0e19\u0e27\u0e19\u0e40\u0e27\u0e25\u0e32\u0e17\u0e35\u0e48 torrent seeding \u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19. \u0e44\u0e21\u0e48\u0e23\u0e27\u0e21\u0e40\u0e27\u0e25\u0e32\u0e17\u0e35\u0e48\u0e14\u0e32\u0e27\u0e42\u0e2b\u0e25\u0e14 (\u0e41\u0e25\u0e30 seeding)
-ConfigView.section.style.alternateTablePainting=\u0e43\u0e0a\u0e49\u0e01\u0e32\u0e23\u0e23\u0e30\u0e1a\u0e32\u0e22\u0e15\u0e32\u0e23\u0e32\u0e07\u0e41\u0e1c\u0e19\u0e20\u0e39\u0e21\u0e34\u0e2d\u0e35\u0e01\u0e41\u0e1a\u0e1a\u0e2b\u0e19\u0e36\u0e48\u0e07 (\u0e2d\u0e32\u0e08\u0e15\u0e49\u0e2d\u0e07\u0e40\u0e23\u0e34\u0e48\u0e21\u0e42\u0e1b\u0e23\u0e41\u0e01\u0e23\u0e21\u0e43\u0e2b\u0e21\u0e48)
 UpdateWindow.status.restartMaybeNeeded=\u0e2d\u0e32\u0e08\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e01\u0e32\u0e23\u0e40\u0e23\u0e34\u0e48\u0e21\u0e42\u0e1b\u0e23\u0e41\u0e01\u0e23\u0e21\u0e43\u0e2b\u0e21\u0e48
 ConfigView.pluginlist.shared=\u0e41\u0e1a\u0e48\u0e07\u0e1b\u0e31\u0e19
 PeersView.host=\u0e0a\u0e37\u0e48\u0e2d Host
@@ -1208,15 +1197,10 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Socket SO_RCVBUF size [0: \u0e4
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 standard socket SO_RCVBUF (\u0e2b\u0e19\u0e48\u0e27\u0e22 bytes), \u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07. TCP \u0e23\u0e31\u0e1a\u0e02\u0e19\u0e32\u0e14 window \u0e41\u0e25\u0e30 \u0e2a\u0e31\u0e14\u0e2a\u0e48\u0e27\u0e19\nVuze \u0e40\u0e27\u0e49\u0e19\u0e0a\u0e48\u0e2d\u0e07\u0e19\u0e35\u0e49\u0e44\u0e27\u0e49\u0e40\u0e1b\u0e47\u0e19\u0e04\u0e48\u0e32\u0e21\u0e32\u0e15\u0e23\u0e [...]
 ConfigView.section.connection.advanced.SO_SNDBUF=\u0e02\u0e19\u0e32\u0e14 Socket SO_SNDBUF [0: \u0e43\u0e0a\u0e49\u0e04\u0e48\u0e32\u0e21\u0e32\u0e15\u0e23\u0e32\u0e10\u0e32\u0e19\u0e02\u0e2d\u0e07 OS]
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 the standard socket SO_SNDBUF (\u0e43\u0e19 bytes), \u0e15.\u0e22.. TCP \u0e2a\u0e48\u0e07\u0e02\u0e19\u0e32\u0e14 window\nVuze \u0e40\u0e27\u0e49\u0e19\u0e04\u0e48\u0e32\u0e19\u0e35\u0e49\u0e44\u0e27\u0e49\u0e40\u0e1b\u0e47\u0e19\u0e21\u0e32\u0e15\u0e23\u0e32\u0e10\u0e32\u0e19,\u0e2b\u0e21\u0e32\u0e22\u0e04\u0e27\u0e32\u0e21\u0e27\u0e48\u0e32\u0e43\u0e0a\u0e49\u0e04\u0e48\u0e32 underlying [...]
-ConfigView.section.interface.confirm_torrent_removal=\u0e41\u0e2a\u0e14\u0e07\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e43\u0e19\u0e01\u0e32\u0e23\u0e40\u0e2d\u0e32 torrent \u0e2d\u0e2d\u0e01
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u0e22\u0e37\u0e19\u0e22\u0e31\u0e19\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e2d\u0e32 torrent \u0e2d\u0e2d\u0e01\u0e08\u0e32\u0e01 Torrents \u0e02\u0e2d\u0e07\u0e09\u0e31\u0e19
-MyTorrentsView.confirm_torrent_removal=\u0e04\u0e38\u0e13\u0e41\u0e19\u0e48\u0e43\u0e08\u0e40\u0e2b\u0e23\u0e2d\u0e17\u0e35\u0e48\u0e08\u0e30\u0e40\u0e2d\u0e32\u0e2d\u0e2d\u0e01?\n
 TableColumn.header.seed_to_peer_ratio=\u0e2d\u0e31\u0e15\u0e23\u0e32\u0e2a\u0e48\u0e27\u0e19 Seed2Peer
 TableColumn.header.seed_to_peer_ratio.info=\u0e2d\u0e31\u0e15\u0e23\u0e32\u0e2a\u0e48\u0e27\u0e19 seeds \u0e15\u0e48\u0e2d peers \u0e1a\u0e19 swarm
 PeersView.connected_time=\u0e40\u0e27\u0e25\u0e32\u0e17\u0e35\u0e48\u0e15\u0e34\u0e14\u0e15\u0e48\u0e2d
 PeersView.connected_time.info=\u0e40\u0e27\u0e25\u0e32\u0e17\u0e35\u0e48\u0e15\u0e34\u0e14\u0e15\u0e48\u0e2d\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e01\u0e31\u0e1a peer
-ConfigView.section.interface.display.add_torrents_silently=\u0e40\u0e1e\u0e34\u0e48\u0e21 torrents silently
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u0e40\u0e1e\u0e34\u0e48\u0e21 torrent downloads \u0e42\u0e14\u0e22\u0e44\u0e21\u0e48\u0e01\u0e25\u0e31\u0e1a\u0e44\u0e1b\u0e17\u0e35\u0e48\u0e2b\u0e19\u0e49\u0e32\u0e15\u0e48\u0e32\u0e07 Vuze
 TableColumn.header.maxdownspeed=\u0e04\u0e27\u0e32\u0e21\u0e40\u0e23\u0e47\u0e27 Down \u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14
 TableColumn.header.maxdownspeed.info=\u0e04\u0e27\u0e32\u0e21\u0e40\u0e23\u0e47\u0e27 Download \u0e2a\u0e39\u0e07\u0e2a\u0e38\u0e14\u0e15\u0e48\u0e2d torrent
 ConfigView.section.tracker.passwordwebhttpsonly=\u0e2d\u0e19\u0e38\u0e0d\u0e32\u0e15\u0e34\u0e01\u0e32\u0e23\u0e40\u0e02\u0e49\u0e32\u0e17\u0e32\u0e07 HTTPS \u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19
@@ -1273,8 +1257,6 @@ UpdateWindow.restartLater=\u0e40\u0e23\u0e34\u0e48\u0e21\u0e17\u0e35\u0e2b\u0e25
 MainWindow.menu.file.restart=\u0e40\u0e23\u0e34\u0e48\u0e21 Vuze \u0e43\u0e2b\u0e21\u0e48
 MainWindow.dialog.restartconfirmation.title=\u0e40\u0e23\u0e34\u0e48\u0e21 Vuze \u0e43\u0e2b\u0e21\u0e48?
 MainWindow.dialog.restartconfirmation.text=\u0e04\u0e38\u0e13\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e17\u0e35\u0e48\u0e08\u0e30\u0e40\u0e23\u0e34\u0e48\u0e21 Vuze \u0e43\u0e2b\u0e21\u0e48?
-deletetorrent.message1=\u0e04\u0e38\u0e13\u0e01\u0e33\u0e25\u0e31\u0e07\u0e08\u0e30\u0e25\u0e1a TORRENT\u0e40\u0e1e\u0e37\u0e48\u0e2d :\n
-deletetorrent.message2=\n\u0e04\u0e38\u0e13\u0e41\u0e19\u0e48\u0e43\u0e08\u0e17\u0e35\u0e48\u0e08\u0e30\u0e14\u0e33\u0e40\u0e19\u0e34\u0e19\u0e01\u0e32\u0e23\u0e15\u0e48\u0e2d?
 ConfigView.label.prioritizemostcompletedfiles=\u0e08\u0e31\u0e14\u0e2d\u0e31\u0e19\u0e14\u0e31\u0e1a\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e33\u0e04\u0e31\u0e0d\u0e01\u0e31\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e48\u0e2a\u0e21\u0e1a\u0e39\u0e23\u0e13\u0e4c\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14
 splash.plugin.init=\u0e40\u0e23\u0e34\u0e48\u0e21\u0e15\u0e31\u0e27\u0e40\u0e2a\u0e23\u0e34\u0e21: 
 ConfigView.section.style.osx_small_fonts=\u0e43\u0e0a\u0e49\u0e2d\u0e31\u0e01\u0e29\u0e23\u0e40\u0e25\u0e47\u0e01 [\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e01\u0e32\u0e23\u0e40\u0e23\u0e34\u0e48\u0e21\u0e43\u0e2b\u0e21\u0e48]
diff --git a/org/gudy/azureus2/internat/MessagesBundle_tr_TR.properties b/org/gudy/azureus2/internat/MessagesBundle_tr_TR.properties
index b7318ed..06b3d02 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_tr_TR.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_tr_TR.properties
@@ -33,13 +33,10 @@ MainWindow.menu.window.alltofront=T\u00fcm\u00fcn\u00fc \u00d6ne Getir
 MainWindow.menu.help=Yard\u0131m
 MainWindow.menu.help.about=Vuze Hakk\u0131nda
 MainWindow.about.title=Hakk\u0131nda
-MainWindow.about.section.developers=Geli\u015ftiriciler
-MainWindow.about.section.translators=\u00c7evirmenler
 MainWindow.about.section.system=Sistem
 MainWindow.about.section.internet=\u0130nternet 
 MainWindow.about.internet.homepage=Vuze Anasayfas\u0131
 MainWindow.about.internet.sourceforge=Sourceforge Proje Sayfas\u0131
-MainWindow.about.internet.sourceforgedownloads=Sourceforge \u0130ndirmeleri
 MainWindow.about.internet.bugreports=Hata Bildirme
 MainWindow.about.internet.forumdiscussion=Forumlar
 MainWindow.about.internet.wiki=Vuze Viki SSS
@@ -298,8 +295,6 @@ IrcView.help=Ge\u00e7erli komutlar :\n . /help : bu mesaj\u0131 g\u00f6sterir\n
 PasswordWindow.title=Vuze Kilitlendi
 PasswordWindow.passwordprotected=Vuze \u015fifreyle korunuyor.\nVuze penceresini g\u00f6rmek i\u00e7in l\u00fctfen buraya \u015fifrenizi girin :
 Button.ok=Tamam
-TrackerChangerWindow.title=\u0130zleyici Ekle
-TrackerChangerWindow.newtracker=Yeni izleyici adresi ekle
 PeersView.discarded=Vazge\u00e7ildi
 PeersView.discarded.info=Her ne kadar ihtiyac\u0131n\u0131z olmasa da bir \u015fekilde ald\u0131\u011f\u0131n\u0131z veri, dolay\u0131s\u0131yla ondan kurtulabilirsiniz.
 discarded=vazge\u00e7ildi
@@ -371,7 +366,6 @@ MyTorrentsView.menu.removeand.deletetorrent=Torrent Dosyas\u0131n\u0131 Sil
 MyTorrentsView.menu.removeand.deletedata=Veriyi Sil
 MyTorrentsView.menu.removeand.deleteboth=Her \u0130kisini de Sil
 deletedata.title=Uyar\u0131
-deletedata.message1=Buradaki VER\u0130'yi silmek \u00fczeresiniz :\n
 MainWindow.menu.file.configure=Yap\u0131land\u0131rma Sihirbaz\u0131
 configureWizard.title=Yap\u0131land\u0131rma Sihirbaz\u0131
 configureWizard.welcome.title=Vuze Yap\u0131land\u0131rma Sihirbaz\u0131na Ho\u015f Geldiniz
@@ -393,7 +387,6 @@ configureWizard.transfer.maxActiveTorrents=En fazla etkin torrent:
 configureWizard.transfer.maxDownloads=En fazla indirme say\u0131s\u0131:
 configureWizard.transfer.maxUploadsPerTorrent=Torrent ba\u015f\u0131na en fazla g\u00f6nderme say\u0131s\u0131: 
 configureWizard.nat.title=NAT / Sunucu Ba\u011flant\u0131 Noktalar\u0131
-configureWizard.nat.message=Bittorrent'ten en iyi verimi alabilmek i\u00e7in internet eri\u015fimine tam izin verilmesi \u0131srarla tavsiye edilir. Varsay\u0131lan bittorrent ba\u011flant\u0131 noktas\u0131 aral\u0131\u011f\u0131 6881'den 6889'a kadard\u0131r. Bu ara\u00e7 sizin varsay\u0131lan ba\u011flant\u0131 noktalar\u0131n\u0131 s\u0131naman\u0131za ve/veya de\u011fi\u015ftirmenize olanak verir. E\u011fer etkin indirmeleriniz varsa, baz\u0131 ba\u011flant\u0131 noktalar\u0131 eri\ [...]
 configureWizard.nat.test=S\u0131na
 configureWizard.nat.testing=Ba\u011flant\u0131 Noktas\u0131 s\u0131nan\u0131yor
 configureWizard.nat.ok=Tamam
@@ -557,7 +550,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=Devingen ve dura\u011fan DNS hizmet sa\u011flay\u0131c\u0131s\u0131\n(serbest adres denetimi hizmeti bulunmuyor)
 ConfigView.section.tracker.publicenable=D\u0131\u015f torrentleri etkinle\u015ftir
 ConfigView.label.playdownloadspeech=\u0130ndirme i\u015flemi itti\u011finde konu\u015f
-ConfigView.label.playdownloadspeech.info=Konu\u015fma hizmeti \u015fu an i\u00e7in en iyi \u0130ngilizce olarak \u00e7al\u0131\u015f\u0131yor
 #
 # Tooltips
 #
@@ -724,8 +716,6 @@ MainWindow.dialog.share.sharedircontents.recursive=\u00d6zyineli
 globalmanager.download.remove.veto=Kald\u0131rma \u0130\u015flemi Veto Edildi
 plugin.sharing.download.remove.veto=Bu indirme payla\u015f\u0131lan bir kayna\u011f\u0131n sonucu.\n\u0130ndirmeyi kald\u0131rmak i\u00e7in ili\u015fkili payla\u015f\u0131m\u0131 kald\u0131r\u0131n: go to Tools->My Classic-Shares.
 ConfigView.label.prioritizefirstpiece=\u00d6nceli\u011fi ilk ve son dosya(lar)a ver
-ConfigView.section.file.confirm_data_delete=Veri silerken onay iste
-ConfigView.section.file.confirm_data_delete.tooltip='Kald\u0131r\u0131rken...' se\u00e7ene\u011fini kullan\u0131rken veri silinmeden \u00f6nce onay ister
 TrayWindow.menu.startalldownloads=T\u00fcm \u0130ndirmeleri Ba\u015flat
 SystemTray.menu.startalltransfers=T\u00fcm Aktar\u0131mlar\u0131 Ba\u015flat
 sharing.progress.title=Payla\u015f\u0131m Oran\u0131
@@ -999,7 +989,6 @@ ConfigView.pluginlist.whereToPutOr=Payla\u015f\u0131lan eklentiler i\u00e7in:
 MainWindow.statusText.checking=G\u00fcncellemeler Kontrol Ediliyor
 TableColumn.header.OnlyCDing4=Sadece Yay\u0131mlanma
 TableColumn.header.OnlyCDing4.info=Sadece yay\u0131mlanma s\u00fcresini g\u00f6sterir.  \u0130ndirmek i\u00e7in ge\u00e7en s\u00fcreyi g\u00f6stermez.
-ConfigView.section.style.alternateTablePainting=Grafik tablo s\u00fctunlar\u0131n\u0131 boyamak i\u00e7in \u00f6teki y\u00f6ntemi kullan (Yeniden ba\u015flatma gerektirebilir)
 UpdateWindow.status.restartMaybeNeeded=Yeniden ba\u015flatma gerekebilir
 MainWindow.menu.help.whatsnew=Yenilikler
 ConfigView.label.checkonstart=Ba\u015flang\u0131\u00e7ta son s\u00fcr\u00fcm denetimi yap
@@ -1204,17 +1193,13 @@ ConfigView.section.connection.advanced=Geli\u015fmi\u015f A\u011f Ayarlar\u0131
 ConfigView.section.connection.advanced.mtu=Hat en y\u00fcksek iletim birimi (MTU)
 ConfigView.section.connection.advanced.SO_RCVBUF=SO_RCVBUF yuva b\u00fcy\u00fckl\u00fc\u011f\u00fc [0: \u0130\u015f. Sis. varsay\u0131lan\u0131n\u0131 kullan]
 ConfigView.section.connection.advanced.SO_SNDBUF=SO_SNDBUF yuva b\u00fcy\u00fckl\u00fc\u011f\u00fc [0: \u0130\u015f. Sis. varsay\u0131lan\u0131n\u0131 kullan]
-ConfigView.section.interface.confirm_torrent_removal=Torrenti kald\u0131r\u0131rken onay ileti\u015fim kutusunu g\u00f6ster
-MyTorrentsView.confirm_torrent_removal=Kald\u0131rmak istedi\u011finizden emin misiniz?\n
 TableColumn.header.seed_to_peer_ratio=OrtaktanE\u015fe Oran
 TableColumn.header.seed_to_peer_ratio.info=K\u00fcme toplam ortaktan e\u015fe oran\u0131
 PeersView.connected_time=Ba\u011flant\u0131 S\u00fcresi
 PeersView.connected_time.info=E\u015f ile ba\u011fl\u0131 kal\u0131nan toplam zaman
-ConfigView.section.interface.display.add_torrents_silently=Torrentleri sessizce ekle
-ConfigView.section.interface.display.add_torrents_silently.tooltip=Ana Vuze penceresini a\u00e7madan torrentleri ekler.
 TableColumn.header.maxdownspeed=En Y\u00fcksek \u0130nd. H\u0131z\u0131
 TableColumn.header.maxdownspeed.info=Torrent ba\u015f\u0131na en y\u00fcksek indirme h\u0131z\u0131
-PeersGraphicView.title=K\u00fcme
+PeersGraphicView.title.full=K\u00fcme
 ConfigView.section.tracker.passwordwebhttpsonly=Yaln\u0131zca HTTPS ile eri\u015fime izin ver
 TableColumn.header.torrentpath=Torrent Yeri
 TableColumn.header.torrentpath.info=Torrentin disk \u00fczerindeki yeri
@@ -1269,8 +1254,6 @@ UpdateWindow.restartLater=Daha Sonra Yeniden Ba\u015flat
 MainWindow.menu.file.restart=Vuze u Yeniden Ba\u015flat
 MainWindow.dialog.restartconfirmation.title=Vuze Yeniden Ba\u015flat\u0131ls\u0131n m\u0131?
 MainWindow.dialog.restartconfirmation.text=Vuze u ger\u00e7ekten yeniden ba\u015flatmak istiyor musunuz?
-deletetorrent.message1=TORRENT silmek \u00fczeresiniz :\n
-deletetorrent.message2=\nDevam etmek istedi\u011finizden emin misiniz?
 ConfigView.label.prioritizemostcompletedfiles=\u00d6nceli\u011fi en \u00e7ok tamamlanm\u0131\u015f dosyalara ver
 splash.plugin.init=Eklenti Ba\u015flat\u0131l\u0131yor: 
 ConfigView.section.style.osx_small_fonts=K\u00fc\u00e7\u00fck yaz\u0131 tipleri kullan [Yeniden ba\u015flatma gerekir]
@@ -1421,7 +1404,6 @@ VivaldiView.title.full=Sanal Konumland\u0131rma
 MyTrackerView.date_added=Eklenme Tarihi
 ConfigView.section.tracker.portbackup=Yedek ba\u011f. noktalar\u0131 (';' ile ayr\u0131lm\u0131\u015f)
 ConfigView.label.playfilespeech=Bir dosya tamamland\u0131\u011f\u0131nda konu\u015f
-ConfigView.label.playfilespeech.info=Konu\u015fma hizmeti \u015fu anda en iyi sadece \u0130ngilizce \u00e7al\u0131\u015fabiliyor
 ConfigView.label.playfilefinished=Bir dosya tamamland\u0131\u011f\u0131nda bir ses \u00e7al
 ConfigView.label.backupconfigfiles=Yap\u0131land\u0131rma dosyalar\u0131n\u0131 kurtarma ama\u00e7l\u0131 olarak yedekle
 ConfigView.section.tracker.client.scrapesingleonly=Herbir izleyici durum s\u0131nama k\u00fcmele\u015fmesini etkisizle\u015ftir
diff --git a/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties b/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
index f47bad3..5e8061c 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_uk_UA.properties
@@ -36,13 +36,10 @@ 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
 MainWindow.about.title=\u0406\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044f \u043f\u0440\u043e
-MainWindow.about.section.developers=\u0420\u043e\u0437\u0440\u043e\u0431\u043d\u0438\u043a\u0438
-MainWindow.about.section.translators=\u041f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u0430\u0447\u0456
 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 \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=\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
@@ -317,8 +314,6 @@ IrcView.help=\u0427\u0438\u043d\u043d\u0456 \u043a\u043e\u043c\u0430\u043d\u0434
 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 \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 \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
@@ -389,7 +384,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u0412\u0438\u043b\u0443\u0447\u0438
 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
 configureWizard.title=\u041c\u0430\u0439\u0441\u0442\u0435\u0440 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u044c
@@ -412,7 +406,6 @@ configureWizard.transfer.maxActiveTorrents=\u041c\u0430\u043a\u0441\u0438\u043c\
 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 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. [...]
 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
@@ -578,7 +571,6 @@ 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\u04 [...]
 ConfigView.section.tracker.publicenable=\u0414\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0438 \u0437\u043e\u0432\u043d\u0456\u0448\u043d\u0456 \u0442\u043e\u0440\u0435\u043d\u0442\u0438
 ConfigView.label.playdownloadspeech=\u041f\u043e\u0432\u0456\u0434\u043e\u043c\u043b\u044f\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u043c\u043e\u0432\u0438 \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.playdownloadspeech.info=\u0421\u0438\u043d\u0442\u0435\u0437\u0430\u0442\u043e\u0440 \u043c\u043e\u0432\u0438 \u043d\u0430\u0439\u043a\u0440\u0430\u0449\u0435 \u043f\u0440\u0430\u0446\u044e\u0454 \u0437 \u0430\u043d\u0433\u043b\u0456\u0439\u0441\u044c\u043a\u043e\u044e \u043c\u043e\u0432\u043e\u044e
 #
 # Tooltips
 #
@@ -754,8 +746,6 @@ 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 \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\ [...]
-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\u [...]
 TrayWindow.menu.startalldownloads=\u0417\u0430\u043f\u0443\u0441&\u0442\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f
 SystemTray.menu.startalltransfers=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0432\u0441\u0456 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0456 \u0440\u043e\u0437\u0434\u0430\u0447\u0456
@@ -1077,7 +1067,6 @@ ConfigView.pluginlist.whereToPutOr=\u0414\u043b\u044f \u0440\u043e\u0437\u0434\u
 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\u0 [...]
 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\u0439
 PeersView.host=\u0406\u043c'\u044f \u0445\u043e\u0441\u0442\u0430
@@ -1316,18 +1305,13 @@ ConfigView.section.connection.advanced.SO_SNDBUF=\u0420\u043e\u0437\u043c\u0456\
 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 \u044 [...]
 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\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 \u043 [...]
-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
 TableColumn.header.seed_to_peer_ratio=\u0421\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
 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 \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
+PeersGraphicView.title.full=\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 \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
@@ -1384,8 +1368,6 @@ UpdateWindow.restartLater=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441
 MainWindow.menu.file.restart=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0437\u043d\u043e\u0432\u0443 Vuze
 MainWindow.dialog.restartconfirmation.title=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 Vuze
 MainWindow.dialog.restartconfirmation.text=\u0412\u0438 \u0434\u0456\u0439\u0441\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0438 \u0437\u043d\u043e\u0432\u0443 Vuze
-deletetorrent.message1=\u0412\u0438 \u0437\u0431\u0438\u0440\u0430\u0454\u0442\u0435\u0441\u044f \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0422\u041e\u0420\u0415\u041d\u0422 \u0434\u043b\u044f :\n
-deletetorrent.message2=\n\u0412\u0438 \u0434\u0456\u0439\u0441\u043d\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u0432\u0436\u0438\u0442\u0438?
 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  
@@ -1554,7 +1536,6 @@ 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=\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 \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\ [...]
@@ -2176,22 +2157,11 @@ v3.mb.delPublished.title=\u041f\u0440\u0438\u043f\u0438\u043d\u0438\u0442\u0438
 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\u [...]
 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.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.azureuswi [...]
-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.azureus [...]
-v3.mb.openFile.button.play=\u0412\u0456\u0434\u0442\u0432\u043e\u0440\u0438\u0442\u0438
-v3.mb.openFile.button.cancel=\u0421\u043a\u0430\u0441\u0443\u0432\u0430\u0442\u0438
-v3.mb.openFile.button.guide=\u0414\u043e\u0432\u0456\u0434\u043a\u0430 \u043f\u043e \u0432\u0456\u0434\u0442\u0432\u043e\u0440\u0435\u043d\u043d\u044e
-v3.mb.openFile.remember=\u0417\u0430\u0432\u0436\u0434\u0438 \u0432\u0456\u0434\u043a\u0440\u0438\u0432\u0430\u0442\u0438 \u0444\u0430\u0439\u043b\u0438 \u0431\u0435\u0437 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0442\u0430\u043d\u043d\u044f
 v3.mb.PlayFileNotFound.title=\u0424\u0430\u0439\u043b \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e
 v3.mb.PlayFileNotFound.text=\u0424\u0430\u0439\u043b\u0438 \u0434\u043b\u044f '%1' \u0430\u0431\u043e \u0432\u0438\u043b\u0443\u0447\u0435\u043d\u0456, \u0430\u0431\u043e \u0432\u0456\u0434\u0441\u0443\u0442\u043d\u0456.
 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\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
 v3.topbar.menu.show.plugin=\u0414\u0456\u043b\u044f\u043d\u043a\u0430 \u0434\u043e\u043f\u043e\u0432\u043d\u0435\u043d\u044c
 v3.topbar.menu.show.search=\u041f\u043e\u0448\u0443\u043a
@@ -2382,10 +2352,6 @@ v3.splash.hookPluginUI=\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u
 OpenTorrentWindow.mb.notTorrent.cannot.display=\u041d\u0435 \u0432 \u0437\u043c\u043e\u0437\u0456 \u043d\u0430\u043b\u0435\u0436\u043d\u0438\u043c \u0447\u0438\u043d\u043e\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0438 \u0434\u0430\u043d\u0456
 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 \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\u04 [...]
 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.
@@ -2481,9 +2447,6 @@ metasearch.addtemplate.dup.title=\u0414\u0443\u0431\u043b\u044e\u0432\u0430\u044
 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
-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  \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\u0431\u0440\u0430\u0442\u0438
@@ -2639,7 +2602,7 @@ Wizard.Subscription.rss.subtitle2=\u0411\u0430\u0433\u0430\u0442\u043e \u043f\u0
 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\u [...]
 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= [...]
+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://wiki.vuze.com/w/FAQ [...]
 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
 message.confirm.delete.text=\u0412\u0438 \u0441\u043f\u0440\u0430\u0432\u0434\u0456 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0438\u043b\u0443\u0447\u0438\u0442\u0438 '%1'?
 Subscription.menu.properties=\u0412\u043b\u0430\u0441\u0442\u0438\u0432\u043e\u0441\u0442\u0456
@@ -2677,7 +2640,7 @@ statusbar.feedback.tooltip=\u041a\u043b\u0430\u0446\u043d\u0456\u0442\u044c \u04
 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\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 [...]
+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 [...]
 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
@@ -2720,13 +2683,6 @@ azbuddy.ui.menu.cat.set_msg=\u0421\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u0
 azbuddy.ui.menu.cat_subs=\u041f\u0435\u0440\u0435\u0434\u043f\u043b\u0430\u0442\u0430
 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\u045 [...]
 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
@@ -2879,7 +2835,7 @@ xcode.deletedata.title=\u0412\u0438\u043b\u0443\u0447\u0438\u0442\u0438 \u0437\u
 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.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 iPad, 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.
@@ -2912,9 +2868,6 @@ device.rss.enable=\u0421\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u0441\u0442\
 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
diff --git a/org/gudy/azureus2/internat/MessagesBundle_zh_CN.properties b/org/gudy/azureus2/internat/MessagesBundle_zh_CN.properties
index dea8e27..c291716 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_zh_CN.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_zh_CN.properties
@@ -37,13 +37,10 @@ MainWindow.menu.help=\u5e2e\u52a9\uff08&H\uff09
 MainWindow.menu.help.about=\u5173\u4e8e Vuze
 MainWindow.menu.torrent=Torrent\uff08&o\uff09
 MainWindow.about.title=\u5173\u4e8e
-MainWindow.about.section.developers=\u5f00\u53d1\u8005
-MainWindow.about.section.translators=\u7ffb\u8bd1\u8005
 MainWindow.about.section.system=\u7cfb\u7edf
 MainWindow.about.section.internet=\u56fd\u9645\u4e92\u8054\u7f51
 MainWindow.about.internet.homepage=Vuze \u7684\u4e3b\u9875
 MainWindow.about.internet.sourceforge=\u5728 Sourceforge \u9879\u76ee\u4e3b\u9875
-MainWindow.about.internet.sourceforgedownloads=Sourceforge \u4e0b\u8f7d
 MainWindow.about.internet.bugreports=\u9519\u8bef\u62a5\u544a
 MainWindow.about.internet.forumdiscussion=\u8bba\u575b
 MainWindow.about.internet.wiki=Vuze Wiki  FAQ
@@ -316,8 +313,6 @@ IrcView.help=\u5408\u6cd5\u7684\u547d\u4ee4\u5305\u62ec\uff1a\n . /help\uff1a\u6
 PasswordWindow.title=Vuze \u5df2\u88ab\u9501\u5b9a
 PasswordWindow.passwordprotected=Vuze \u5df2\u88ab\u5bc6\u7801\u4fdd\u62a4\u3002\n\u8bf7\u8f93\u5165\u4f60\u7684\u5bc6\u7801\u4ee5\u663e\u793a Vuze \u7a97\u53e3\uff1a
 Button.ok=\u786e\u5b9a\uff08&O\uff09
-TrackerChangerWindow.title=\u6dfb\u52a0 Tracker
-TrackerChangerWindow.newtracker=\u8f93\u5165\u65b0\u7684 Tracker \u7684\u94fe\u63a5
 PeersView.discarded=\u5df2\u629b\u5f03
 PeersView.discarded.info=\u4f60\u63a5\u6536\u5230\u7684\u6570\u636e\u5e76\u4e0d\u662f\u4f60\u6240\u9700\u8981\u7684\uff0c\u6240\u4ee5\u629b\u5f03\u3002
 discarded=\u6570\u636e\u5df2\u88ab\u629b\u5f03
@@ -388,7 +383,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u5220\u9664 .torrent \u6587\u4ef6\u
 MyTorrentsView.menu.removeand.deletedata=\u5220\u9664\u6570\u636e\uff08&D\uff09
 MyTorrentsView.menu.removeand.deleteboth=\u5220\u9664\u6570\u636e\u548c .torrent \u6587\u4ef6\uff08&B\uff09
 deletedata.title=\uff01\uff01\uff01 \u8b66\u544a \uff01\uff01\uff01
-deletedata.message1=\u4f60\u5c06\u8981\u4ece\uff1a\n\u5220\u9664\u6570\u636e
 deletedata.noprompt=\u4e0d\u8981\u518d\u63d0\u9192\u6211
 MainWindow.menu.file.configure=\u914d\u7f6e\u5411\u5bfc\uff08&W\uff09
 configureWizard.title=\u914d\u7f6e\u5411\u5bfc
@@ -411,7 +405,6 @@ configureWizard.transfer.maxActiveTorrents=\u6700\u5927\u7684\u6d3b\u52a8\u4efb\
 configureWizard.transfer.maxDownloads=\u6700\u5927\u7684\u6d3b\u52a8\u4e0b\u8f7d\u6570
 configureWizard.transfer.maxUploadsPerTorrent=\u6bcf\u4e2a Torrent \u6587\u4ef6\u6700\u5927\u4e0a\u4f20\u6570\u91cf
 configureWizard.nat.title=NAT / \u670d\u52a1\u5668\u7aef\u53e3
-configureWizard.nat.message=\u4e3a\u4e86\u66f4\u597d\u5730\u4f7f\u7528 Vuze uff0c\u5f3a\u70c8\u5efa\u8bae\u4f60\u80fd\u5904\u4e8e\u5916\u7f51\u72b6\u6001\u3002\u8fd9\u4e2a\u5de5\u5177\u4f7f\u4f60\u80fd\u6d4b\u8bd5/\u6539\u53d8\u8fd9\u4e9b\u9ed8\u8ba4\u7aef\u53e3\u3002\n\n\u6ce8\u610f\uff1a\u8fd9\u4e2a\u5de5\u5177\u4ec5\u6d4b\u8bd5 TCP \u8fde\u63a5\u3002 DHT \u529f\u80fd\u4f7f\u7528 UDP \u8fde\u63a5\uff0c\u4f46\u5982\u679c\u53d1\u73b0\u7aef\u53e3\u963b\u585e\uff0cVuze \u4f1a\u81ea\u52a8\u [...]
 configureWizard.nat.test=\u6d4b\u8bd5
 configureWizard.nat.testing=\u6b63\u5728\u6d4b\u8bd5\u7aef\u53e3
 configureWizard.nat.ok=\u6b63\u5e38
@@ -573,7 +566,6 @@ ConfigView.section.file.decoder.nodecoder=\u65e0
 IPChecker.external.service.no-ip.description=Dynamic and Static DNS service provider\n\uff08no freely available "check address" service\uff09
 ConfigView.section.tracker.publicenable=\u542f\u7528\u5916\u90e8\u7684 Torrent
 ConfigView.label.playdownloadspeech=\u4e0b\u8f7d\u5b8c\u6210\u540e\u8bed\u97f3\u63d0\u793a
-ConfigView.label.playdownloadspeech.info=\u8bed\u97f3\u670d\u52a1\u76ee\u524d\u5bf9\u82f1\u8bed\u652f\u6301\u662f\u6700\u597d\u7684
 #
 # Tooltips
 #
@@ -747,8 +739,6 @@ plugin.sharing.download.remove.veto=\u6b64\u4e0b\u8f7d\u662f\u7531\u8d44\u6e90\u
 ConfigView.section.tracker.main=\u4e3b\u8981
 ConfigView.label.prioritizefirstpiece=\u4f18\u5148\u4e0b\u8f7d\u6587\u4ef6\u7684\u7b2c\u4e00\u4e2a\u533a\u5757
 ConfigView.label.prioritizefirstpiece.tooltip=\u8bd5\u56fe\u4e0b\u8f7d\u6bcf\u4e00\u4e2a\u6587\u4ef6\u7684\u6587\u4ef6\u5934\u90e8\u5206\n\u4e3a\u4e86\u652f\u6301\u65e9\u671f\u9884\u89c8\u3002
-ConfigView.section.file.confirm_data_delete=\u5220\u9664\u6570\u636e\u65f6\u663e\u793a\u786e\u8ba4\u7a97\u53e3
-ConfigView.section.file.confirm_data_delete.tooltip=\u5f53\u4f7f\u7528\u201c\u5220\u9664\u201d\u65f6\u663e\u793a\u786e\u8ba4\u7a97\u53e3
 ConfigView.section.file.delete.include_files_outside_save_dir=\u5f53\u5220\u9664\u6570\u636e\u65f6\uff0c\u5141\u8bb8\u79fb\u9664\u5728 torrent \u4fdd\u5b58\u76ee\u5f55\u5916\u7684\u6587\u4ef6
 TrayWindow.menu.startalldownloads=\u542f\u52a8\u6240\u6709\u7684\u4e0b\u8f7d
 SystemTray.menu.startalltransfers=\u5f00\u59cb\u6240\u6709\u4f20\u8f93
@@ -1069,7 +1059,6 @@ ConfigView.pluginlist.whereToPutOr=\u5bf9\u4e8e\u5171\u4eab\u7684\u63d2\u4ef6\uf
 MainWindow.statusText.checking=\u68c0\u67e5\u66f4\u65b0
 TableColumn.header.OnlyCDing4=\u5355\u72ec\u505a\u79cd\u65f6\u95f4
 TableColumn.header.OnlyCDing4.info=Torrent \u5355\u72ec\u505a\u79cd\u7684\u603b\u65f6\u95f4\u3002 \u4e0d\u5305\u62ec Torrent \u4e0b\u8f7d\u65f6\u9644\u5e26\u505a\u79cd\u7684\u65f6\u95f4\u3002
-ConfigView.section.style.alternateTablePainting=\u4f7f\u7528\u4ea4\u66ff\u7684\u65b9\u5f0f\u7ed8\u5236\u56fe\u5f62\u8868\u884c\uff08\u53ef\u80fd\u9700\u8981\u91cd\u542f\uff09
 UpdateWindow.status.restartMaybeNeeded=\u53ef\u80fd\u9700\u8981\u91cd\u542f
 ConfigView.pluginlist.shared=\u5171\u4eab
 PeersView.host=\u4e3b\u673a\u540d
@@ -1305,18 +1294,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Socket SO_RCVBUF \u5927\u5c0f\u
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u8bbe\u7f6e\u6807\u51c6 socket SO_RCVBUF \u503c\uff08\u4ee5\u5b57\u8282\u8ba1\uff09\uff0c\u5982\uff1a TCP \u63a5\u6536\u7a97\u7684\u5927\u5c0f\u548c\u6bd4\u4f8b\u5c3a\u3002\n\u4e0d\u8bbe\u7f6e\u7684\u60c5\u51b5\u4e0b Vuze \u4f7f\u7528\u9ed8\u8ba4\u503c\uff0c\u8868\u793a\u4f18\u5148\u4f7f\u7528\u7cfb\u7edf\u9ed8\u8ba4\u503c\u3002\n\u6ce8\u610f\uff1a Linux \u628a\u8d4b\u4e88\u7684\u503c\u53cc\u500d\u8ba1\u7b97\u3002
 ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF \u5927\u5c0f\uff3b0\uff1a\u4f7f\u7528\u64cd\u4f5c\u7cfb\u7edf\u9ed8\u8ba4\uff3d
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u8bbe\u7f6e\u6807\u51c6 socket SO_SNDBUF \u503c\uff08\u4ee5\u5b57\u8282\u8ba1\uff09\uff0c\u5982\uff1a TCP \u63a5\u6536\u7a97\u7684\u5927\u5c0f\u548c\u6bd4\u4f8b\u5c3a\u3002\n\u4e0d\u8bbe\u7f6e\u7684\u60c5\u51b5\u4e0b Vuze \u4f7f\u7528\u9ed8\u8ba4\u503c\uff0c\u8868\u793a\u4f18\u5148\u4f7f\u7528\u7cfb\u7edf\u9ed8\u8ba4\u503c\u3002\n\u6ce8\u610f\uff1a Linux \u628a\u8d4b\u4e88\u7684\u503c\u53cc\u500d\u8ba1\u7b97\u3002
-ConfigView.section.interface.confirm_torrent_removal=\u5f53\u5220\u9664 Torrent \u65f6\u663e\u793a\u786e\u8ba4\u5bf9\u8bdd\u6846
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u4ece "\u6211\u7684 Torrents" \u7a97\u53e3\u5220\u9664 torrent \u65f6\u8981\u6c42\u786e\u8ba4\u3002
-MyTorrentsView.confirm_torrent_removal=\u4f60\u786e\u5b9a\u60f3\u79fb\u9664\u5417\uff1f\n
 TableColumn.header.seed_to_peer_ratio=\u79cd\u5b50\u4e0e\u7528\u6237\u6bd4\u7387
 TableColumn.header.seed_to_peer_ratio.info=\u7fa4\u4f53\u79cd\u5b50\u4e0e\u7528\u6237\u7684\u6bd4\u7387
 PeersView.connected_time=\u8fde\u63a5\u65f6\u95f4
 PeersView.connected_time.info=\u4e0e\u7528\u6237\u8fde\u63a5\u7684\u603b\u65f6\u95f4
-ConfigView.section.interface.display.add_torrents_silently=\u5b89\u9759\u5730\u6dfb\u52a0 Torrent
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u6dfb\u52a0 Torrent \u4e0b\u8f7d\u4e0d\u663e\u793a Vuze \u4e3b\u7a97\u53e3\u3002
 TableColumn.header.maxdownspeed=\u6700\u5927\u4e0b\u8f7d\u901f\u5ea6
 TableColumn.header.maxdownspeed.info=\u6bcf\u4e2a Torrent \u7684\u6700\u5927\u4e0b\u8f7d\u901f\u5ea6
-PeersGraphicView.title=\u7fa4\u4f53
+PeersGraphicView.title.full=\u7fa4\u4f53
 ConfigView.section.tracker.passwordwebhttpsonly=\u4ec5\u5141\u8bb8\u901a\u8fc7 HTTPS \u7684\u8fde\u63a5
 TableColumn.header.torrentpath=Torrent \u5730\u5740
 TableColumn.header.torrentpath.info=Torrent \u5728\u78c1\u76d8\u4e0a\u7684\u4f4d\u7f6e
@@ -1373,8 +1357,6 @@ UpdateWindow.restartLater=\u7a0d\u4faf\u91cd\u542f
 MainWindow.menu.file.restart=\u91cd\u542f
 MainWindow.dialog.restartconfirmation.title=\u91cd\u542f Vuze uff1f
 MainWindow.dialog.restartconfirmation.text=\u4f60\u60f3\u91cd\u542f Vuze \u5417\uff1f
-deletetorrent.message1=\u4f60\u5c06\u8981\u4ece\uff1a\n\u5220\u9664 TORRENT
-deletetorrent.message2=\n\u4f60\u786e\u5b9a\u8981\u7ee7\u7eed\u5417\uff1f
 ConfigView.label.prioritizemostcompletedfiles=\u4f18\u5148\u5373\u5c06\u4e0b\u8f7d\u5b8c\u6210\u7684\u6587\u4ef6
 splash.plugin.init=\u521d\u59cb\u5316\u63d2\u4ef6\uff1a
 splash.plugin.UIinit=\u521d\u59cb\u5316\u63d2\u4ef6 GUI: %1  
@@ -1540,7 +1522,6 @@ VivaldiView.title.full=\u7528\u6237\u865a\u62df\u5206\u5e03
 MyTrackerView.date_added=\u6dfb\u52a0\u65e5\u671f
 ConfigView.section.tracker.portbackup=\u5907\u7528\u7aef\u53e3\uff08\u7528\u201c\uff1b\u201d\u5206\u9694\uff09
 ConfigView.label.playfilespeech=\u6587\u4ef6\u4e0b\u8f7d\u5b8c\u6210\u540e\u8bed\u97f3\u63d0\u793a
-ConfigView.label.playfilespeech.info=\u8bed\u97f3\u670d\u52a1\u76ee\u524d\u5bf9\u82f1\u8bed\u652f\u6301\u662f\u6700\u597d\u7684
 ConfigView.label.playfilefinished=\u6587\u4ef6\u4e0b\u8f7d\u5b8c\u6210\u540e\u64ad\u653e\u58f0\u97f3
 ConfigView.label.backupconfigfiles=\u5907\u4efd\u914d\u7f6e\u6587\u4ef6
 ConfigView.section.tracker.client.scrapesingleonly=\u7981\u6b62\u6bcf\u6b21\u8bf7\u6c42\u5411 Tracker \u67e5\u8be2\u591a\u4e2a Hash \u503c\uff08\u53ef\u4ee5\u89e3\u51b3\u67d0\u4e9b Tracker \u62a5\u544a \u201c URL \u8fc7\u957f\u201d\uff08414\uff09 \u7684\u9519\u8bef\uff09
@@ -2145,22 +2126,11 @@ v3.mb.delPublished.title=\u505c\u6b62\u6b63\u5728\u505a\u79cd\u7684\u5185\u5bb9
 v3.mb.delPublished.text=\u8b66\u544a\uff1a\u8fd9\u4e0d\u4f1a\u5c06\u4f60\u53d1\u5e03\u7684 "%1" \u4ece <A HREF="%2">%3</A>\u5220\u9664\u3002\n\n\u4ec5\u5728\u4f60\u60f3\u89e3\u653e\u4f60\u7684\u5e26\u5bbd\u53c8\u4e0d\u60f3\u5220\u9664\u53d1\u5e03\u6216\u4e0b\u8f7d\u7684\u5185\u5bb9\u65f6\uff0c\u70b9\u51fb\u5220\u9664\u3002\u8bf7\u786e\u8ba4\u4f60\u5220\u9664\u524d\u5df2\u53d1\u5e03\u5b8c\u6bd5\uff08<A HREF="%4">how</A>\uff1f\uff09\u3002\n\n\u5982\u679c\u4f60\u60f3\u5b8c\u5168\u4ece%3\u52 [...]
 v3.mb.delPublished.delete=\u5220\u9664\uff08&D\uff09
 v3.mb.delPublished.cancel=\u53d6\u6d88\uff08&C\uff09
-v3.mb.openFile.title=\u6253\u5f00\u6587\u4ef6
-v3.mb.openFile.text.known=\u8be5\u5185\u5bb9\u76ee\u524d\u4e0d\u88ab Vuze Player \u6240\u652f\u6301.  \u68c0\u67e5\u793e\u533a\u521b\u5efa\u7684 <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u56de\u653e\u6307\u5357</a> \u5bfb\u6c42\u5e2e\u52a9.\n\n\u6587\u4ef6\u7c7b\u578b\u4f3c\u4e4e\u662f : %2 (%3)\n
-v3.mb.openFile.text.unknown=\u8be5\u5185\u5bb9\u76ee\u524d\u4e0d\u88ab Vuze Player \u6240\u652f\u6301.  \u68c0\u67e5\u793e\u533a\u521b\u5efa\u7684 <a href="http://www.azureuswiki.com/index.php/Playback_Guide">\u56de\u653e\u6307\u5357</a> \u5bfb\u6c42\u5e2e\u52a9.\n\n\u6587\u4ef6\u6269\u5c55\u540d : %2\n
-v3.mb.openFile.button.play=\u64ad\u653e
-v3.mb.openFile.button.cancel=\u53d6\u6d88
-v3.mb.openFile.button.guide=\u9605\u8bfb\u56de\u653e\u6307\u5357
-v3.mb.openFile.remember=\u4e00\u76f4\u6253\u5f00\u6587\u4ef6\u800c\u4e0d\u8981\u8be2\u95ee\u6211
 v3.mb.PlayFileNotFound.title=\u6587\u4ef6\u672a\u627e\u5230
 v3.mb.PlayFileNotFound.text=\u6587\u4ef6 "%1" \u5df2\u5220\u9664\u6216\u4e22\u5931\u3002
 v3.mb.PlayFileNotFound.button.remove=\u4ece Vuze \u5220\u9664
 v3.mb.PlayFileNotFound.button.redownload=\u91cd\u65b0\u4e0b\u8f7d\u6570\u636e
 v3.mb.PlayFileNotFound.button.find=\u624b\u52a8\u67e5\u627e..
-v3.mb.deletePurchased.title=\u5220\u9664\u8d2d\u4e70\u5185\u5bb9
-v3.mb.deletePurchased.text=\u4f60\u786e\u5b9a\u8981\u5220\u9664 "%1" \u5417\uff1f\n\n\u8fd9\u53ef\u80fd\u662f\u4f60\u8d2d\u4e70\u7684\uff0c \u6216\u662f\u88ab\u8bf7\u6c42\u767b\u9646\u4e0b\u8f7d\u7684\u5185\u5bb9\u3002
-v3.mb.deletePurchased.button.delete=\u5220\u9664\uff08&D\uff09
-v3.mb.deletePurchased.button.cancel=\u53d6\u6d88\uff08&C\uff09
 v3.topbar.menu.show.plugin=\u63d2\u4ef6\u533a\u57df
 v3.topbar.menu.show.search=\u641c\u7d22
 v3.topbar.menu.show.frog=\u5927\u84dd\u86d9
@@ -2350,10 +2320,6 @@ v3.splash.hookPluginUI=\u94a9\u4f4f\u63d2\u4ef6\u754c\u9762
 OpenTorrentWindow.mb.notTorrent.cannot.display=\u65e0\u6cd5\u6b63\u786e\u663e\u793a\u6570\u636e
 MainWindow.menu.window.zoom.maximize=\u6700\u5927\u5316
 MainWindow.menu.window.zoom.restore=\u8fd8\u539f
-ImageResizer.image.too.small=\u63d0\u4f9b\u7684\u56fe\u7247\u592a\u5c0f\u4e86\uff0c\u8bf7\u9009\u62e9\u53e6\u9009\u4e00\u4e2a (\u9700\u8981\u6700\u5c11 %1 x %2)
-ImageResizer.title=\u8fd9\u4e2a\u5de5\u5177\u8ba9\u4f60\u9884\u89c8\u4f60\u7684\u7f29\u7565\u56fe\u5728 Vuze \u5e73\u53f0\u4e0a\u7684\u6837\u5b50\u3002
-ImageResizer.move.image=\u62d6\u52a8\u4ee5\u79fb\u52a8\u56fe\u7247
-ImageResizer.move.image.with.slider=\u62d6\u52a8\u4ee5\u79fb\u52a8\u56fe\u7247\uff0c\u4f7f\u7528\u4e0b\u65b9\u7684\u6ed1\u5757\u6539\u53d8\u5927\u5c0f
 security.crypto.title=\u8bbf\u95ee\u52a0\u5bc6Key
 security.crypto.encrypt=\u8bf7\u8f93\u5165\u4e00\u4e2a\u5bc6\u7801\u6765\u4fdd\u62a4\u60a8\u65b0\u751f\u6210\u7684\u52a0\u5bc6 key\u3002\u8bf7\u7262\u8bb0\u6b64\u5bc6\u7801\uff0c\u5982\u679c\u5fd8\u8bb0\u5c06\u65e0\u6cd5\u6062\u590d\uff01
 security.crypto.decrypt=\u8bf7\u8f93\u5165\u5bc6\u7801\u4ee5\u89e3\u9501\u60a8\u7684\u52a0\u5bc6key
@@ -2447,9 +2413,6 @@ metasearch.addtemplate.dup.title=\u91cd\u590d\u7684\u6a21\u677f
 metasearch.addtemplate.dup.desc=\u641c\u7d22\u6a21\u677f %1 \u5df2\u7ecf\u5b89\u88c5\u4e86
 metasearch.export.select.template.file=\u4fdd\u5b58\u6a21\u677f
 metasearch.import.select.template.file=\u6253\u5f00\u6a21\u677f
-dialog.uiswitch.title=\u5207\u6362\u5230 Vuze UI
-dialog.uiswitch.text=\u60a8\u9700\u8981\u8fd0\u884c\u4e2d\u7684 Vuze UI \u6765\u4f7f\u7528\u6b64\u529f\u80fd\n\nVuze \u5c06\u9700\u8981\u91cd\u65b0\u542f\u52a8
-dialog.uiswitch.button=\u5207\u6362\u5230 Vuze UI
 azbuddy.tracker.enabled=\u542f\u7528 '\u597d\u53cb\u6367\u573a' \u6765\u901a\u8fc7\u597d\u53cb\u63d0\u5347\u4f60\u7684\u4e0b\u8f7d
 azbuddy.protocolspeed=KB/s \u6700\u5927\u597d\u53cb\u534f\u8bae\u603b\u5f00\u9500
 v3.MainWindow.button.download=\u4e0b\u8f7d
@@ -2599,7 +2562,7 @@ Wizard.Subscription.rss.subtitle2=\u8bb8\u591a\u53d1\u5e03\u8005\u4e3a\u4ed6\u4e
 Wizard.Subscription.rss.subtitle3=\u4e00\u65e6\u4fdd\u5b58\uff0c\u60a8\u5c31\u53ef\u4ee5\u5728\u4fa7\u9762\u677f\u4e2d\u83b7\u5f97\u901a\u8fc7 RSS \u8ba2\u9605\u5f97\u5230\u7684\u5b9e\u65f6\u66f4\u65b0\u3002
 Wizard.Subscription.subscribe.library=\u5a92\u4f53\u5e93\u4e2d\u7684\u5185\u5bb9
 Wizard.Subscription.subscribe.subscriptions=\u76f8\u5173\u7684\u8ba2\u9605
-Wizard.Subscription.subscribe.library.empty=\u6ca1\u6709\u53ef\u7528\u7684\u8ba2\u9605\uff1f\n \n\u627e\u627e Vuze HD Network \u4e0a\u4eae\u6a59\u8272\u7684\u8ba2\u9605\u6309\u94ae.\n \n<A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u66f4\u591a\u9605\u8bfb</A>
+Wizard.Subscription.subscribe.library.empty=\u6ca1\u6709\u53ef\u7528\u7684\u8ba2\u9605\uff1f\n \n\u627e\u627e Vuze HD Network \u4e0a\u4eae\u6a59\u8272\u7684\u8ba2\u9605\u6309\u94ae.\n \n<A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">\u66f4\u591a\u9605\u8bfb</A>
 message.confirm.delete.title=\u5220\u9664\u786e\u8ba4
 message.confirm.delete.text=\u4f60\u786e\u5b9a\u8981\u5220\u9664 '%1'?
 Subscription.menu.properties=\u5c5e\u6027
@@ -2635,7 +2598,7 @@ statusbar.feedback.tooltip=\u70b9\u51fb\u8fd9\u91cc\u53d1\u9001\u53cd\u9988\u4fe
 sidebar.Activity=\u63d0\u793a
 v3.activity.button.watchall=\u6807\u8bb0\u6240\u6709\u4e3a\u5df2\u770b
 subscriptions.view.help.1=\u6dfb\u52a0\u8ba2\u9605\u5230\u4f60\u6240\u770b\u7684\u4f4d\u7f6e
-subscriptions.view.help.2=\u5f53\u6709\u65b0\u5185\u5bb9\u53ef\u4ee5\u4e0b\u8f7d\u65f6\u83b7\u5f97\u5b9e\u65f6\u66f4\u65b0 <A HREF="http://faq.vuze.com/?View=entry&EntryID=288">\u66f4\u591a\u9605\u8bfb</A>.
+subscriptions.view.help.2=\u5f53\u6709\u65b0\u5185\u5bb9\u53ef\u4ee5\u4e0b\u8f7d\u65f6\u83b7\u5f97\u5b9e\u65f6\u66f4\u65b0 <A HREF="http://wiki.vuze.com/w/FAQ_Subscriptions">\u66f4\u591a\u9605\u8bfb</A>.
 sidebar.sash.tooltip=\u6309\u4e0b F7 \u5feb\u901f\u9690\u85cf/\u663e\u793a\u4fa7\u9762\u677f
 sidebar.expand.tooltip=\u6269\u5c55\u4fa7\u9762\u677f
 sidebar.dropdown.tooltip=\u4ee5\u83dc\u5355\u683c\u5f0f\u663e\u793a\u4fa7\u9762\u677f
@@ -2668,13 +2631,6 @@ azbuddy.ui.menu.cat.share=\u542f\u7528\u6765\u81ea\u597d\u53cb\u7684\u8ba2\u9605
 azbuddy.ui.menu.cat.set=\u8f93\u5165\u5206\u7c7b
 azbuddy.ui.menu.cat.set_msg=\u7528\u9017\u53f7\u5206\u9694\u7684\u5206\u7c7b\u5217\u8868\uff0c\u6216\u8005 'All'
 azbuddy.ui.menu.cat_subs=\u8ba2\u9605
-v3.dialog.cnclose.title=%1 \u5173\u95ed
-v3.dialog.cnclose.subtitle=\u63d0\u793a
-v3.dialog.cnclose.info1=\u60a8\u5df2\u7ecf\u5173\u95ed\u4e86\u4e00\u4e2a\u9ad8\u6e05\u7f51\u7edc
-v3.dialog.cnclose.info2=\u5982\u679c\u60a8\u60f3\u8981\u91cd\u65b0\u6253\u5f00\u5f00\u8bf7\u7f51\u7edc\uff0c\u60a8\u53ef\u4ee5\u5728\u5c4f\u5e55\u4e0a\u65b9\u7684\u201c\u9ad8\u6e05\u7f51\u7edc\u201d\u83dc\u5355\u4e2d\u5b8c\u6210\u3002
-v3.dialog.cnclose.noshow=\u4e0d\u8981\u518d\u663e\u793a
-v3.dialog.cnmanage.title=\u7ba1\u7406\u9ad8\u6e05\u7f51\u7edc\u83dc\u5355
-v3.dialog.cnmanage.intro=\u60a8\u53ef\u4ee5\u4ece\u4ee5\u4e0b\u6e05\u5355\u4e2d\u9009\u62e9\u60a8\u5e0c\u671b\u663e\u793a\u5728\u201c\u9ad8\u6e05\u7f51\u7edc\u201d\u83dc\u5355\u4e2d\u7684\u7f51\u7edc\u5185\u5bb9
 TableColumn.header.#.info=\u4f4d\u7f6e/\u6b21\u5e8f\u53f7
 TableColumn.header.category.info=torrent \u6240\u5c5e\u7684\u5206\u7c7b\u540d
 TableColumn.header.DateCompleted.info=torrent \u4e0b\u8f7d\u5b8c\u6210\u7684\u65e5\u671f
diff --git a/org/gudy/azureus2/internat/MessagesBundle_zh_TW.properties b/org/gudy/azureus2/internat/MessagesBundle_zh_TW.properties
index 0e2e761..7cee4a4 100644
--- a/org/gudy/azureus2/internat/MessagesBundle_zh_TW.properties
+++ b/org/gudy/azureus2/internat/MessagesBundle_zh_TW.properties
@@ -33,13 +33,10 @@ MainWindow.menu.window.alltofront=\u5168\u90e8\u79fb\u81f3\u6700\u524d (&F)
 MainWindow.menu.help=\u8f14\u52a9\u8aaa\u660e (&H)
 MainWindow.menu.help.about=\u95dc\u65bc Vuze
 MainWindow.about.title=\u95dc\u65bc
-MainWindow.about.section.developers=\u958b\u767c\u5718\u968a
-MainWindow.about.section.translators=\u7ffb\u8b6f\u8005
 MainWindow.about.section.system=\u7cfb\u7d71
 MainWindow.about.section.internet=\u7db2\u969b\u7db2\u8def
 MainWindow.about.internet.homepage=Vuze \u9996\u9801
 MainWindow.about.internet.sourceforge=\u958b\u653e\u539f\u59cb\u78bc\u9801\u9762
-MainWindow.about.internet.sourceforgedownloads=\u958b\u653e\u539f\u59cb\u78bc\u4e0b\u8f09
 MainWindow.about.internet.bugreports=\u932f\u8aa4\u56de\u5831
 MainWindow.about.internet.forumdiscussion=\u8a0e\u8ad6\u5340
 MainWindow.about.internet.wiki=Vuze Wiki \u5e38\u898b\u554f\u984c
@@ -306,8 +303,6 @@ IrcView.help=\u6709\u6548\u7684\u6307\u4ee4\uff1a\n . /help : \u986f\u793a\u672c
 PasswordWindow.title=Vuze \u5df2\u9396\u5b9a
 PasswordWindow.passwordprotected=Vuze \u5df2\u53d7\u5230\u5bc6\u78bc\u4fdd\u8b77\n\u60f3\u8981\u986f\u793a Vuze \u8996\u7a97,\u8acb\u5728\u9019\u908a\u8f38\u5165\u5bc6\u78bc :
 Button.ok=\u78ba\u5b9a
-TrackerChangerWindow.title=\u52a0\u5165 Tracker
-TrackerChangerWindow.newtracker=\u8f38\u5165\u65b0\u7684 tracker \u4f4d\u5740
 PeersView.discarded=\u4e1f\u68c4
 PeersView.discarded.info=\u4e1f\u68c4\u60a8\u5df2\u63a5\u6536,\u4f46\u662f\u4e0d\u9700\u8981\u7684\u6a94\u6848
 discarded=\u4e1f\u68c4
@@ -379,7 +374,6 @@ MyTorrentsView.menu.removeand.deletetorrent=\u522a\u9664 Torrent \u6a94\u6848 (&
 MyTorrentsView.menu.removeand.deletedata=\u522a\u9664\u8cc7\u6599 (&D)
 MyTorrentsView.menu.removeand.deleteboth=\u5169\u8005\u90fd\u522a\u9664 (&B)
 deletedata.title=\u8b66\u544a
-deletedata.message1=\u60a8\u5c07\u8981\u522a\u9664\u8cc7\u6599\uff0c\u8a72\u8cc7\u6599\u4f4d\u65bc\uff1a\n
 MainWindow.menu.file.configure=\u8a2d\u5b9a\u7cbe\u9748 (&W)
 configureWizard.title=\u8a2d\u5b9a\u7cbe\u9748
 configureWizard.welcome.title=\u6b61\u8fce\u4f7f\u7528 Vuze \u8a2d\u5b9a\u7cbe\u9748
@@ -401,7 +395,6 @@ configureWizard.transfer.maxActiveTorrents=\u6d3b\u52d5\u4e0a\u9650
 configureWizard.transfer.maxDownloads=\u4e0a\u50b3\u6578\u4e0a\u9650
 configureWizard.transfer.maxUploadsPerTorrent=\u6bcf\u500b Torrent \u4e0a\u50b3\u6578\u4e0a\u9650
 configureWizard.nat.title=NAT / \u4f3a\u670d\u5668\u9023\u63a5\u57e0
-configureWizard.nat.message=\u70ba\u4e86\u8b93 Vuze \u767c\u63ee\u5168\u90e8\u7684\u6548\u80fd\uff0c\u5f37\u70c8\u5efa\u8b70\u958b\u555f\u7db2\u969b\u7db2\u8def\u7684\u6240\u6709\u5b58\u53d6\u6b0a\u9650\u3002\u9019\u500b\u5de5\u5177\u53ef\u4ee5\u8b93\u60a8\u6e2c\u8a66\u4e26\u6539\u8b8a\u60a8\u548c\u5925\u4f34\u9023\u7dda\u6642\u6240\u4f7f\u7528\u7684\u9023\u63a5\u57e0.\n\n\u6ce8\u610f: \u9019\u500b\u5de5\u5177\u53ea\u80fd\u6e2c\u8a66 TCP \u9023\u7dda. \u5206\u6563\u6027\u8cc7\u6599\u5eab [...]
 configureWizard.nat.test=\u6e2c\u8a66
 configureWizard.nat.testing=\u6e2c\u8a66\u9023\u63a5\u57e0\u4e2d
 configureWizard.nat.ok=\u597d !
@@ -566,7 +559,6 @@ IPChecker.external.service.no-ip.url=http://www.no-ip.com/
 IPChecker.external.service.no-ip.description=\u865b\u64ec\u548c\u56fa\u5b9a\u5f0f DNS \u670d\u52d9\u63d0\u4f9b\u8005\n\uff08\u6c92\u6709\u53ef\u7528\u7684\u514d\u8cbb"\u6aa2\u67e5\u4f4d\u5740" \u670d\u52d9\uff09
 ConfigView.section.tracker.publicenable=\u555f\u7528\u5916\u90e8 torrents
 ConfigView.label.playdownloadspeech=\u4e0b\u8f09\u5b8c\u7562\u5f8c\u64ad\u653e\u8a9e\u97f3\u63d0\u793a
-ConfigView.label.playdownloadspeech.info=\u76ee\u524d\u53ea\u6709\u82f1\u8a9e\u767c\u97f3
 #
 # Tooltips
 #
@@ -739,8 +731,6 @@ ConfigView.section.tracker.main=\u4e3b\u8981
 ConfigView.section.tracker.web=\u7db2\u7ad9
 ConfigView.label.prioritizefirstpiece=\u7b2c\u4e00\u500b\u6a94\u6848\u584a\u548c\u6700\u5f8c\u4e00\u500b\u6a94\u6848\u584a\u5217\u70ba\u512a\u5148\u4e0b\u8f09
 ConfigView.label.prioritizefirstpiece.tooltip=\u5617\u8a66\u512a\u5148\u4e0b\u8f09\u6a94\u6848\u7684\u9996\u7aef\u548c\u5c3e\u7aef \n \u4ee5\u65b9\u4fbf\u9810\u89bd\u6a94\u6848
-ConfigView.section.file.confirm_data_delete=\u522a\u9664\u6a94\u6848\u6642\u9700\u8981\u78ba\u8a8d
-ConfigView.section.file.confirm_data_delete.tooltip="\u79fb\u52d5\u6216\u522a\u9664"\u6642\u9700\u8981\u78ba\u8a8d
 TrayWindow.menu.startalldownloads=\u555f\u52d5\u6240\u6709\u4e0b\u8f09
 SystemTray.menu.startalltransfers=\u555f\u52d5\u6240\u6709\u50b3\u8f38\u5de5\u4f5c
 sharing.progress.title=\u5171\u4eab\u72c0\u6cc1
@@ -1054,7 +1044,6 @@ ConfigView.pluginlist.whereToPutOr=\u5171\u7528\u7684\u5916\u639b\u6a21\u7d44\u6
 MainWindow.statusText.checking=\u6aa2\u67e5\u66f4\u65b0
 TableColumn.header.OnlyCDing4=\u7d14\u505a\u7a2e\u6642\u9593
 TableColumn.header.OnlyCDing4.info=\u8a72 torrent \u7d14\u505a\u7a2e\u7684\u6642\u9593,\u4e0d\u5305\u542b\u540c\u6642\u4e0b\u8f09/\u4e0a\u50b3\u7684\u6642\u9593
-ConfigView.section.style.alternateTablePainting=\u4f7f\u7528\u66ff\u4ee3\u65b9\u5f0f\u7e6a\u88fd\u5716\u5f62\u8868\u6b04\u4f4d\uff08\u53ef\u80fd\u9700\u8981\u91cd\u65b0\u555f\u52d5\uff09
 UpdateWindow.status.restartMaybeNeeded=\u5fc5\u9808\u91cd\u65b0\u555f\u52d5
 ConfigView.pluginlist.shared=\u5171\u4eab
 PeersView.host=\u7db2\u8def\u540d\u7a31
@@ -1288,18 +1277,13 @@ ConfigView.section.connection.advanced.SO_RCVBUF=Socket SO_RCVBUF size[0\uff1a\u
 ConfigView.section.connection.advanced.SO_RCVBUF.tooltip=\u8a2d\u5b9a\u6a19\u6e96 socket SO_RCVBUF \u6578\u503c\uff08bytes\uff09\uff0ci.e. TCP \u63a5\u6536\u7a97\u53e3\u7684\u5927\u5c0f\u548c\u6bd4\u4f8b\nVuze \u9810\u8a2d\u70ba\u7a7a\u767d\uff0c\u4e5f\u5c31\u662f\u6839\u64da\u6240\u4f7f\u7528\u7684\u5e95\u5c64\u4f5c\u696d\u7cfb\u7d71\u800c\u5b9a\n\u6ce8\u610f\uff1aLinux \u6703\u4f7f\u7528\u5169\u500d\u7684\u6307\u5b9a\u6578\u503c
 ConfigView.section.connection.advanced.SO_SNDBUF=Socket SO_SNDBUF size[0\uff1a\u9810\u8a2d]                   
 ConfigView.section.connection.advanced.SO_SNDBUF.tooltip=\u8a2d\u5b9a\u6a19\u6e96 socket SO_SNDBUF \u6578\u503c\uff08bytes\uff09\uff0ci.e. TCP \u50b3\u9001\u7a97\u53e3\u7684\u5927\u5c0f\nVuze \u9810\u8a2d\u70ba\u7a7a\u767d\uff0c\u4e5f\u5c31\u662f\u6839\u64da\u6240\u4f7f\u7528\u7684\u5e95\u5c64\u4f5c\u696d\u7cfb\u7d71\u800c\u5b9a\n\u6ce8\u610f\uff1aLinux \u6703\u4f7f\u7528\u5169\u500d\u7684\u6307\u5b9a\u6578\u503c
-ConfigView.section.interface.confirm_torrent_removal=torrent \u88ab\u79fb\u9664\u6642\uff0c\u986f\u793a\u78ba\u8a8d\u5c0d\u8a71\u8996\u7a97
-ConfigView.section.interface.confirm_torrent_removal.tooltip=\u5f9e"\u6211\u7684 torrent" \u4e2d\u79fb\u9664 torrent \u6642,\u8981\u6c42\u78ba\u8a8d
-MyTorrentsView.confirm_torrent_removal=\u60a8\u78ba\u5b9a\u8981\u522a\u9664\uff1f\n
 TableColumn.header.seed_to_peer_ratio=\u7a2e\u5b50\u5c0d\u5925\u4f34\u7684\u6bd4\u7387
 TableColumn.header.seed_to_peer_ratio.info=\u5168\u90e8 swarm \u88e1\u7a2e\u5b50\u5c0d\u5925\u4f34\u7684\u6bd4\u7387
 PeersView.connected_time=\u9023\u7dda\u6642\u9593
 PeersView.connected_time.info=\u60a8\u548c\u5925\u4f34\u9023\u7dda\u7684\u7e3d\u6642\u9593
-ConfigView.section.interface.display.add_torrents_silently=\u9ed8\u9ed8\u5730\u52a0\u5165 torrents
-ConfigView.section.interface.display.add_torrents_silently.tooltip=\u52a0\u5165 torrent \u4e0b\u8f09\u6642\uff0c\u4e0d\u8981\u555f\u52d5 Vuze \u4e3b\u8996\u7a97
 TableColumn.header.maxdownspeed=\u6700\u5927\u4e0b\u8f09\u901f\u5ea6
 TableColumn.header.maxdownspeed.info=\u6bcf\u500b torrent \u6700\u5927\u4e0b\u8f09\u901f\u5ea6
-PeersGraphicView.title=Swarm \u7fa4\u7d44
+PeersGraphicView.title.full=Swarm \u7fa4\u7d44
 ConfigView.section.tracker.passwordwebhttpsonly=\u50c5\u5141\u8a31\u900f\u904e HTTPS \u5b58\u53d6                                 
 TableColumn.header.torrentpath=Torrent \u4f4d\u7f6e
 TableColumn.header.torrentpath.info=Torrent \u5728\u78c1\u789f\u4e2d\u7684\u4f4d\u7f6e
@@ -1355,8 +1339,6 @@ UpdateWindow.restartLater=\u7a0d\u5f8c\u518d\u91cd\u65b0\u555f\u52d5
 MainWindow.menu.file.restart=\u91cd\u65b0\u555f\u52d5 Vuze
 MainWindow.dialog.restartconfirmation.title=\u91cd\u65b0\u555f\u52d5 Vuze
 MainWindow.dialog.restartconfirmation.text=\u60a8\u771f\u7684\u60f3\u8981\u91cd\u65b0\u555f\u52d5 Vuze
-deletetorrent.message1=\u60a8\u5c07\u8981\u522a\u9664 TORRENT\uff1a\n
-deletetorrent.message2=\n\u60a8\u78ba\u5b9a\u8981\u7e7c\u7e8c?
 ConfigView.label.prioritizemostcompletedfiles=\u4f9d\u7167\u6a94\u6848\u7684\u5927\u5c0f\u548c\u5b8c\u6210\u5ea6\u4f86\u6c7a\u5b9a\u9ad8\u512a\u5148\u9806\u5e8f
 splash.plugin.init=\u6b63\u5728\u521d\u59cb\u5316\u5916\u639b\u6a21\u7d44: 
 ConfigView.section.style.osx_small_fonts=\u4f7f\u7528\u5c0f\u5b57\u578b [\u9700\u8981\u91cd\u65b0\u555f\u52d5]
@@ -1514,7 +1496,6 @@ MainWindow.menu.file.open.torrentfortracking=Torrent \u6a94... (\u50c5\u4f5c\u70
 MyTrackerView.date_added=\u5df2\u52a0\u5165
 ConfigView.section.tracker.portbackup=\u5099\u7528\u9023\u63a5\u57e0\uff08\u7528 ';' \u5206\u9694\uff09
 ConfigView.label.playfilespeech=\u7576\u6a94\u6848\u5b8c\u6210\u5f8c\u64ad\u653e\u8a9e\u97f3
-ConfigView.label.playfilespeech.info=\u76ee\u524d\u53ea\u6709\u82f1\u8a9e\u767c\u97f3
 ConfigView.label.playfilefinished=\u7576\u6a94\u6848\u5b8c\u6210\u5f8c\u64ad\u653e\u8072\u97f3
 ConfigView.label.backupconfigfiles=\u5099\u4efd\u8a2d\u5b9a\u6a94\u4ee5\u4fbf\u56de\u5fa9\u3002
 ConfigView.section.tracker.client.scrapesingleonly=\u505c\u7528\u6bcf\u500b tracker \u7684 scrape \u96c6\u5408\uff08\u6709\u52a9\u65bc\u6e1b\u5c11 tracker \u56de\u5831 'URL \u904e\u9577'\uff08414\uff09\u932f\u8aa4\uff09
diff --git a/org/gudy/azureus2/platform/JavaBitMode.java b/org/gudy/azureus2/platform/JavaBitMode.java
new file mode 100644
index 0000000..0f8ab75
--- /dev/null
+++ b/org/gudy/azureus2/platform/JavaBitMode.java
@@ -0,0 +1,13 @@
+package org.gudy.azureus2.platform;
+
+import org.gudy.azureus2.core3.util.Constants;
+
+public class JavaBitMode
+{
+	public static void main(String[] args) {
+		String prop = System.getProperty ("sun.arch.data.model");
+		if (prop == null) prop = System.getProperty ("com.ibm.vm.bitmode");
+		if (prop == null) prop = Constants.is64Bit ? "64" : "32"; 
+		System.out.print(prop);
+	}
+}
diff --git a/org/gudy/azureus2/platform/PlatformManager.java b/org/gudy/azureus2/platform/PlatformManager.java
index e09e900..3adbcca 100644
--- a/org/gudy/azureus2/platform/PlatformManager.java
+++ b/org/gudy/azureus2/platform/PlatformManager.java
@@ -22,10 +22,13 @@
 
 package org.gudy.azureus2.platform;
 
+import java.io.File;
 import java.net.InetAddress;
 
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 
+import com.aelitis.azureus.core.AzureusCore;
+
 /**
  * @author parg
  *
@@ -37,11 +40,15 @@ PlatformManager
 	public static final int	PT_WINDOWS		= 1;
 	public static final int PT_OTHER		= 2;
     public static final int PT_MACOSX 		= 3;
-  	public static final int PT_UNIX		= 4;
+  	public static final int PT_UNIX			= 4;
 
-  	public static final int USER_REQUEST_INFO = 1;
-  	public static final int USER_REQUEST_WARNING = 2;
-  	public static final int USER_REQUEST_QUESTION = 3;  	
+  	public static final int USER_REQUEST_INFO 		= 1;
+  	public static final int USER_REQUEST_WARNING 	= 2;
+  	public static final int USER_REQUEST_QUESTION 	= 3;  	
+  	
+ 	public static final int	SD_SHUTDOWN		= 0x00000001;
+ 	public static final int	SD_HIBERNATE	= 0x00000002;
+ 	public static final int	SD_SLEEP		= 0x00000004;
   	
 	public int
 	getPlatformType();
@@ -51,6 +58,12 @@ PlatformManager
 	
 		throws PlatformManagerException;
 	
+	public void
+	startup(
+		AzureusCore		azureus_core )
+	
+		throws PlatformManagerException;
+	
 	public String
 	getUserDataDirectory()
 	
@@ -71,6 +84,51 @@ PlatformManager
 		
 		throws PlatformManagerException;
 
+	public File
+	getVMOptionFile()
+	
+		throws PlatformManagerException;
+	
+	public String[]
+	getExplicitVMOptions()
+	
+		throws PlatformManagerException;
+	
+	public void
+	setExplicitVMOptions(
+		String[]		options )
+	
+		throws PlatformManagerException;
+
+	public boolean
+	getRunAtLogin()
+	          	
+	 	throws PlatformManagerException;
+
+	public void
+	setRunAtLogin(
+		boolean		run )
+	          	
+	 	throws PlatformManagerException;
+
+	public int
+	getShutdownTypes();
+	
+	public void
+	shutdown(
+		int			type )
+	
+		throws PlatformManagerException;
+	
+	public void
+	setPreventComputerSleep(
+		boolean		prevent_it )
+	
+		throws PlatformManagerException;
+	
+	public boolean
+	getPreventComputerSleep();
+	
 	public void
 	createProcess(
 		String	command_line,
@@ -125,6 +183,17 @@ PlatformManager
 	
 		throws PlatformManagerException;
 	
+		/**
+		 * This max-open-files concept here is from linux/osx where network connections are treated as 'files' 
+		 * @return
+		 * @throws PlatformManagerException
+		 */
+	
+	public int
+	getMaxOpenFiles()
+	
+		throws PlatformManagerException;
+	
     /**
      * <p>Gets whether the platform manager supports a capability</p>
      * <p>Users of PlatformManager should check for supported capabilities before calling
@@ -154,12 +223,6 @@ PlatformManager
     	PlatformManagerListener		listener );
 
 		/**
-		 * @return
-		 * @throws PlatformManagerException 
-		 */
-		String getAzComputerID() throws PlatformManagerException;
-		
-		/**
 		 * Requests the user's attention such as bouncing the application icon on OSX
 		 *  
 		 * @param type
@@ -172,5 +235,4 @@ PlatformManager
 			Object 	data)
 		
 			throws PlatformManagerException;
-
 }
diff --git a/org/gudy/azureus2/platform/PlatformManagerCapabilities.java b/org/gudy/azureus2/platform/PlatformManagerCapabilities.java
index 372dfd0..f6af547 100644
--- a/org/gudy/azureus2/platform/PlatformManagerCapabilities.java
+++ b/org/gudy/azureus2/platform/PlatformManagerCapabilities.java
@@ -52,8 +52,14 @@ public final class PlatformManagerCapabilities
     
     public static final PlatformManagerCapabilities ComputerIDAvailability = new PlatformManagerCapabilities("CID");
 
-    public static final PlatformManagerCapabilities RequestUserAttention = new PlatformManagerCapabilities("RequestUserAttention");
+    public static final PlatformManagerCapabilities RequestUserAttention 	= new PlatformManagerCapabilities("RequestUserAttention");
     
+    public static final PlatformManagerCapabilities AccessExplicitVMOptions = new PlatformManagerCapabilities("AccessExplicitVMOptions");
+    
+    public static final PlatformManagerCapabilities RunAtLogin				= new PlatformManagerCapabilities("RunAtLogin");
+    public static final PlatformManagerCapabilities GetMaxOpenFiles			= new PlatformManagerCapabilities("GetMaxOpenFiles");
+    public static final PlatformManagerCapabilities PreventComputerSleep	= new PlatformManagerCapabilities("PreventComputerSleep");
+
     private final String myName; // for debug only
 
     private PlatformManagerCapabilities(String name)
diff --git a/org/gudy/azureus2/platform/PlatformManagerListener.java b/org/gudy/azureus2/platform/PlatformManagerListener.java
index 291bbc9..f1c8cb1 100644
--- a/org/gudy/azureus2/platform/PlatformManagerListener.java
+++ b/org/gudy/azureus2/platform/PlatformManagerListener.java
@@ -29,7 +29,9 @@ PlatformManagerListener
 	public static final int	ET_SUSPEND	= 2;
 	public static final int	ET_RESUME	= 3;
 	
-	public void
+	public static final int	RT_SUSPEND_DENY	= 1;
+
+	public int
 	eventOccurred(
 		int		type );
 }
diff --git a/org/gudy/azureus2/platform/PlatformManagerPluginDelegate.java b/org/gudy/azureus2/platform/PlatformManagerPluginDelegate.java
index 3beeb39..c8357dd 100644
--- a/org/gudy/azureus2/platform/PlatformManagerPluginDelegate.java
+++ b/org/gudy/azureus2/platform/PlatformManagerPluginDelegate.java
@@ -38,6 +38,16 @@ import org.gudy.azureus2.plugins.update.UpdateChecker;
 public class PlatformManagerPluginDelegate
 	implements Plugin, UpdatableComponent	// we have to implement this as it used as a mixin to declare that this plugin handles its own update process
 {
+	
+	public static void
+	load(
+		PluginInterface		plugin_interface )
+	{
+			// name it during initialisation
+		
+		plugin_interface.getPluginProperties().setProperty( "plugin.name", 	"Platform-Specific Support" );
+	}
+	
 	// @see org.gudy.azureus2.plugins.Plugin#initialize(org.gudy.azureus2.plugins.PluginInterface)
 	public void initialize(PluginInterface pluginInterface)
 			throws PluginException {
diff --git a/org/gudy/azureus2/platform/dummy/PlatformManagerImpl.java b/org/gudy/azureus2/platform/dummy/PlatformManagerImpl.java
index d69ae93..cb57b8d 100644
--- a/org/gudy/azureus2/platform/dummy/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/dummy/PlatformManagerImpl.java
@@ -28,6 +28,8 @@ import org.gudy.azureus2.platform.PlatformManagerListener;
 import org.gudy.azureus2.platform.PlatformManagerPingCallback;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 
+import com.aelitis.azureus.core.AzureusCore;
+
 
 
 /**
@@ -102,6 +104,86 @@ public class PlatformManagerImpl implements PlatformManager
 	    return( null );
 	}
 	
+	public File 
+	getVMOptionFile() 
+	
+		throws PlatformManagerException 
+	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public String[]
+   	getExplicitVMOptions()
+	          	
+   		throws PlatformManagerException
+	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	 
+	public boolean
+	getRunAtLogin()
+	          	
+	 	throws PlatformManagerException
+	{
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+
+	public void
+	setRunAtLogin(
+		boolean		run )
+	          	
+	 	throws PlatformManagerException
+	{
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public void
+	startup(
+		AzureusCore		azureus_core )
+	
+		throws PlatformManagerException
+	{	
+	}
+	
+	public int
+	getShutdownTypes()
+	{
+		return( 0 );
+	}
+	
+	public void
+	shutdown(
+		int			type )
+	
+		throws PlatformManagerException
+	{	
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public void
+	setPreventComputerSleep(
+		boolean			b )
+	
+		throws PlatformManagerException
+	{	
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public boolean
+	getPreventComputerSleep()
+	{
+		return( false );
+	}
+	
+	public void
+	setExplicitVMOptions(
+		String[]		options )
+	          	
+		throws PlatformManagerException
+	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");	
+	}
+	
 	public boolean
 	isAdditionalFileTypeRegistered(
 		String		name,				// e.g. "BitTorrent"
@@ -237,6 +319,14 @@ public class PlatformManagerImpl implements PlatformManager
 	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
 	}
 	
+	public int
+	getMaxOpenFiles()
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
+	}
+	
     /**
      * {@inheritDoc}
      */
diff --git a/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java b/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
index 087cd50..c090cbf 100644
--- a/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
+++ b/org/gudy/azureus2/platform/macosx/NativeInvocationBridge.java
@@ -47,11 +47,10 @@ public abstract class NativeInvocationBridge
 		if (instance == null) {
 			try {
 				Object newInstance = Class.forName(
-						"org.gudy.azureus2.platform.macosx.access.cocoa.CocoaJavaBridge").getConstructor(
-						null).newInstance(null);
+						"org.gudy.azureus2.platform.macosx.access.cocoa.CocoaJavaBridge").getConstructor().newInstance();
 				instance = (NativeInvocationBridge) newInstance;
 			} catch (Throwable e) {
-				Debug.out(e);
+				//Debug.out(e);
 				instance = new DummyBridge();
 			}
 		}
diff --git a/org/gudy/azureus2/platform/macosx/PListEditor.java b/org/gudy/azureus2/platform/macosx/PListEditor.java
index 9d5753d..dde9482 100644
--- a/org/gudy/azureus2/platform/macosx/PListEditor.java
+++ b/org/gudy/azureus2/platform/macosx/PListEditor.java
@@ -20,11 +20,16 @@
 
 package org.gudy.azureus2.platform.macosx;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileReader;
+import java.io.FileOutputStream;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 
+import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.FileUtil;
 
 public class 
@@ -32,6 +37,7 @@ PListEditor
 {	
 	private String plistFile;
 	
+	private boolean	found_bom;
 	
 	public 
 	PListEditor(
@@ -118,12 +124,11 @@ PListEditor
 	
 	private boolean 
 	isValuePresent(
-		String match )
+		String	fileContent,
+		String 	match )
 	
 		throws IOException
-	{
-		String fileContent = getFileContent();
-		
+	{		
 		//System.out.println("Searching for:\n" + match);
 		return fileContent.matches(match);
 	}
@@ -145,7 +150,7 @@ PListEditor
 	{
 		String fileContent = getFileContent();
 		
-		if( !isValuePresent(find)) {
+		if( !isValuePresent(fileContent,find)) {
 			//System.out.println("Changing " +plistFile);
 			fileContent = fileContent.replaceFirst(match, "$1"+value + "$3");
 			setFileContent(fileContent);
@@ -157,17 +162,41 @@ PListEditor
 	getFileContent()
 		throws IOException
 	{
-		FileReader fr = null;
-		
+		InputStreamReader reader = null;
+
 		try{
-			fr = new FileReader(plistFile);
+			byte[]	file_bytes = FileUtil.readFileAsByteArray( new File( plistFile ));
+			
+				// handle UTF-8 encoded BOM EFBBBF
+						
+			if ( 	file_bytes.length > 3 &&
+					file_bytes[0] == (byte)0xEF &&
+					file_bytes[1] == (byte)0xBB &&
+					file_bytes[2] == (byte)0xBF ){
+				
+				found_bom = true;
+				
+				reader = new InputStreamReader( new ByteArrayInputStream( file_bytes, 3, file_bytes.length - 3 ));
+				
+			}else{
+				
+				found_bom = false;
+				
+				reader = new InputStreamReader( new ByteArrayInputStream( file_bytes ));
+
+			}
+					
 			//max 32KB
+			
 			int length = 32 * 1024;
+			
 			char[] buffer = new char[length];
+			
 			int offset = 0;
+			
 			int len = 0;
 			
-			while((len = fr.read(buffer,offset,length-offset)) > 0) {
+			while((len = reader.read(buffer,offset,length-offset)) > 0) {
 				offset += len;
 			}
 			
@@ -176,8 +205,8 @@ PListEditor
 			return result;
 			
 		} finally {
-			if(fr != null) {
-				fr.close();
+			if(reader != null) {
+				reader.close();
 			}
 		}
 		
@@ -207,18 +236,34 @@ PListEditor
 		
 		try{
 			
-			FileWriter fw = null;
+			ByteArrayOutputStream	baos = new ByteArrayOutputStream( fileContent.length() + 256 );
 			
+			if ( found_bom ){
+				
+					// preserve UTF-8 BOM if it was found
+				
+				baos.write( new byte[]{ (byte)0xEF, (byte)0xBB, (byte)0xBF });
+			}
+			
+			OutputStreamWriter osw = new OutputStreamWriter( baos );
+			
+			osw.write( fileContent );
+			
+			osw.close();
+			
+			FileOutputStream out = null;
+						
 			try{
 				
-				fw = new FileWriter(plistFile);
-				fw.write(fileContent);
+				out = new FileOutputStream( plistFile );
+
+		    	out.write(  baos.toByteArray() );
 	
-			} finally {
+			}finally{
 				
-				if( fw != null ){
+				if( out != null ){
 					
-					fw.close();
+					out.close();
 					
 					ok = true;
 				}
diff --git a/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java b/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
index 4d0c6a6..ecbb24c 100644
--- a/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/macosx/PlatformManagerImpl.java
@@ -22,14 +22,11 @@
 
 package org.gudy.azureus2.platform.macosx;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import java.io.*;
+import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.text.MessageFormat;
-import java.util.HashSet;
+import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
@@ -51,7 +48,8 @@ import org.gudy.azureus2.platform.PlatformManagerPingCallback;
 import org.gudy.azureus2.platform.macosx.access.jnilib.OSXAccess;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 
-import com.apple.cocoa.application.NSApplication;
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreLifecycleAdapter;
 
 
 /**
@@ -75,6 +73,14 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 
     private volatile String		computer_name;
     private volatile boolean	computer_name_tried;
+
+	private Class<?> claFileManager;
+	
+	private AzureusCore	azureus_core;
+	
+	private boolean		prevent_computer_sleep_pending	= false;
+	private boolean 	prevent_computer_sleep			= false;
+	private Process		prevent_computer_proc;
     
     /**
      * Gets the platform manager singleton, which was already initialized
@@ -89,7 +95,7 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
      */
     static
     {
-        initializeSingleton();
+      initializeSingleton();
     }
 
     /**
@@ -137,9 +143,23 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
         if (OSXAccess.isLoaded()) {
 	        capabilitySet.add(PlatformManagerCapabilities.GetVersion);
         }
-        AEDiagnostics.addEvidenceGenerator(this);
+ 
+        if ( checkPList()){
+        	
+            // one day soon...
+            // capabilitySet.add(PlatformManagerCapabilities.AccessExplicitVMOptions);
+        }
+        
+        capabilitySet.add(PlatformManagerCapabilities.RunAtLogin);
+        capabilitySet.add(PlatformManagerCapabilities.GetMaxOpenFiles);
         
-        checkPList();
+        if ( 	new File( "/usr/bin/pmset" ).canRead() ||
+        		new File( "/usr/bin/caffeinate" ).canRead()){
+        	
+        	capabilitySet.add( PlatformManagerCapabilities.PreventComputerSleep );
+        }
+        
+        AEDiagnostics.addEvidenceGenerator(this);
     }
 
     /**
@@ -180,13 +200,15 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 		return( editor );
     }
     
-    protected void
+    protected boolean
     checkPList()
     {
     	try{
     		PListEditor editor = getPList();
+    		
     		if (editor == null) {
-    			return;
+    			
+    			return( false );
     		}
     		
     		editor.setFileTypeExtensions(new String[] {"torrent","tor","vuze","vuz"});
@@ -195,13 +217,21 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 			editor.setSimpleStringValue("CFBundleGetInfoString","Vuze");
 			editor.setSimpleStringValue("CFBundleShortVersionString",Constants.AZUREUS_VERSION);
 			editor.setSimpleStringValue("CFBundleVersion",Constants.AZUREUS_VERSION);
-			editor.setArrayValues("CFBundleURLSchemes", "string", new String[] { "magnet", "dht", "vuze"});
+			editor.setArrayValues("CFBundleURLSchemes", "string", new String[] { "magnet", "dht", "vuze", "bc", "bctp" });
+			
+				// always touch it, see if it helps ensure we are registered as magnet
+				// handler
+			
+			editor.touchFile();
+			
+			return( true );
 			
     	}catch( Throwable e ){
     		
     		Debug.out( "Failed to update plist", e );
+    		
+    		return( false );
     	}
-	
     }
     
     protected void
@@ -218,6 +248,599 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
     	}
     }
     
+	public File 
+	getVMOptionFile() 
+	
+		throws PlatformManagerException 
+	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public String[]
+   	getExplicitVMOptions()
+  	          	
+     	throws PlatformManagerException
+  	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");
+  	}
+  	 
+  	public void
+  	setExplicitVMOptions(
+  		String[]		options )
+  	          	
+  		throws PlatformManagerException
+  	{
+        throw new PlatformManagerException("Unsupported capability called on platform manager");	
+  	}
+  	
+	public void
+	startup(
+		AzureusCore		_azureus_core )
+	
+		throws PlatformManagerException
+	{	
+		synchronized( this ){
+			
+			azureus_core = _azureus_core;
+			
+			if ( prevent_computer_sleep_pending ){
+				
+				prevent_computer_sleep_pending = false;
+				
+				setPreventComputerSleep( true );
+			}
+		}
+		
+		azureus_core.addLifecycleListener(
+			new AzureusCoreLifecycleAdapter()
+			{
+				public void
+				stopping(
+					AzureusCore		core )
+				{
+					synchronized( PlatformManagerImpl.this ){
+					
+						try{
+							setPreventComputerSleep( false );
+							
+						}catch( Throwable e ){
+						}
+						
+						azureus_core = null;
+					}
+				}
+			});
+	}
+	
+	public int
+	getShutdownTypes()
+	{
+		return( 0 );
+	}
+	
+	public void
+	shutdown(
+		int			type )
+	
+		throws PlatformManagerException
+	{	
+		 throw new PlatformManagerException( "Unsupported capability called on platform manager" );
+	}
+	
+	public void
+	setPreventComputerSleep(
+		boolean		prevent_it )
+	
+		throws PlatformManagerException
+	{
+		synchronized( this ){
+			
+			if ( azureus_core == null ){
+				
+				prevent_computer_sleep_pending = prevent_it;
+				
+				return;
+			}
+			
+			if ( prevent_computer_sleep == prevent_it ){
+				
+				return;
+			}
+			
+			prevent_computer_sleep = prevent_it;
+			
+			if ( prevent_it ){
+				
+				String[] command;
+				
+				File binary = new File( "/usr/bin/caffeinate" );
+				
+				if ( binary.canRead()){
+					
+					command = new String[]{ binary.getAbsolutePath(), "-i" };
+					
+				}else{
+					
+					binary = new File( "/usr/bin/pmset" );
+				
+					if ( binary.canRead()){
+						
+						command = new String[]{ binary.getAbsolutePath(), "noidle" };
+						
+					}else{
+						
+						 throw new PlatformManagerException("Unsupported capability called on platform manager");
+					}
+				}
+			  
+				if ( prevent_computer_proc != null ){
+					
+					Debug.out( "eh?" );
+					
+					prevent_computer_proc.destroy();
+				}
+				
+				try{
+					System.out.println( "Starting idle sleep preventer: " + command[0] );
+
+					prevent_computer_proc = Runtime.getRuntime().exec( command );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}else{
+				
+				if ( prevent_computer_proc != null ){
+					
+					System.out.println( "Stopping idle sleep preventer" );
+					
+					prevent_computer_proc.destroy();
+					
+					prevent_computer_proc = null;
+				}
+			}
+		}	
+	}
+	
+	public boolean
+	getPreventComputerSleep()
+	{
+		synchronized( this ){
+			
+			return( prevent_computer_sleep );
+		}
+	}
+	
+  	public boolean 
+  	getRunAtLogin() 
+  	
+  		throws PlatformManagerException 
+  	{
+  		if ( Constants.isOSX_10_8_OrHigher ){
+  			
+  			String item_name = SystemProperties.getApplicationName();
+  			
+  			try{
+  				 
+                 StringBuffer sb = new StringBuffer();
+                 sb.append("tell application \"");
+                 sb.append("System Events");
+                 sb.append("\" to get the name of every login item");
+
+                 String[] items = performOSAScript(sb).split( "," );
+                 
+                 for ( String item: items ){
+                	 
+                	 if ( item.trim().equalsIgnoreCase( item_name )){
+                		 
+                		 return( true );
+                	 }
+                 }
+                 
+                 return( false );
+                 
+             }catch (Throwable e){
+            	 
+                 throw new PlatformManagerException("Failed to get login items", e);
+             }
+  		}
+  		
+  		File f = getLoginPList();
+  		
+  		if ( !f.exists()){
+  			
+  			return( false );
+  		}
+  		
+  		File	bundle_file = getAbsoluteBundleFile();
+  		
+  		if ( !bundle_file.exists()){
+  			
+  			return( false );
+  		}
+  		
+  		try{
+  			convertToXML( f );
+  			
+  			LineNumberReader lnr = new LineNumberReader( new InputStreamReader(new FileInputStream( f ), "UTF-8" ));
+  			
+  			int	state = 0;
+  			
+  			String	target = bundle_file.getAbsolutePath();
+  			
+  			try{
+  				while( true ){
+  					
+  					String line = lnr.readLine();
+  					
+  					if ( line == null ){
+  						
+  						break;
+  					}
+  				
+  					if ( state == 0 ){
+  					
+  						if ( containsTag( line, "AutoLaunchedApplicationDictionary" )){
+  						
+  							state = 1;
+  						}
+  					}else{
+  						
+  						if ( line.contains( target )){
+  							
+  							return( true );
+  						}
+  					}
+  				}
+  				
+  				return( false );
+  				
+  			}finally{
+  				
+  				lnr.close();
+  			}
+  		}catch( Throwable e ){
+  			
+  			throw( new PlatformManagerException( "Failed to read input file", e ));
+  		}
+  	}
+  	
+  	public void 
+  	setRunAtLogin(
+  		boolean run ) 
+  	
+  		throws PlatformManagerException 
+  	{
+  		if ( getRunAtLogin() == run ){
+  			
+  			return;
+  		}
+  		
+		File	bundle_file = getAbsoluteBundleFile();
+  		
+  		if ( !bundle_file.exists()){
+  			
+ 			throw( new PlatformManagerException( "Failed to write set run-at-login, bundle not found" ));
+  		}
+  		
+		String	abs_target = bundle_file.getAbsolutePath();
+
+  		if ( Constants.isOSX_10_8_OrHigher ){
+  		
+  			if ( run ){
+  				
+  	 			 try{
+  	  				 
+  	                 StringBuffer sb = new StringBuffer();
+  	                 sb.append("tell application \"");
+  	                 sb.append("System Events");
+  	                 sb.append("\" to make login item at end with properties {path:\"" );
+  	                 sb.append(abs_target);
+  	                 sb.append("\", hidden:false}" );
+  	                 
+  	                 System.out.println( performOSAScript(sb));
+  	                 
+  	                 return;
+  	                 
+  	             }catch (Throwable e){
+  	            	 
+  	                 throw new PlatformManagerException("Failed to add login item", e);
+  	             }	
+  			  		
+  			}else{
+  				
+  				
+ 	 			 try{
+  	  				 
+  	                 StringBuffer sb = new StringBuffer();
+  	                 sb.append("tell application \"");
+  	                 sb.append("System Events");
+  	                 sb.append("\" to delete login item \"" );
+  	                 sb.append(SystemProperties.getApplicationName());
+  	                 sb.append("\"" );
+  	                 
+  	                 System.out.println( performOSAScript(sb));
+  	                 
+  	                 return;
+  	                 
+  	             }catch (Throwable e){
+  	            	 
+  	                 throw new PlatformManagerException("Failed to delete login item", e);
+  	             }	  		
+  			}
+  		}
+  		
+
+  		
+  		File f = getLoginPList();
+  		
+  		if ( f.exists()){
+  			
+  			convertToXML( f );
+  			
+  		}else{
+  			
+  			try{
+  				PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f ), "UTF-8" ));
+  				
+  				try{
+  				
+  					pw.println( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" );
+  					pw.println( "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" );
+  					pw.println( "<plist version=\"1.0\">" );
+  					pw.println( "<dict>" );
+  					
+  					pw.println( "</dict>" );
+  					pw.println( "</plist>" );
+
+  				}finally{
+  					
+  					pw.close();
+  				}
+  			}catch( Throwable e ){
+  				
+  				throw( new PlatformManagerException( "Failed to write output file", e ));
+  			}
+  		}
+  		
+  
+  		try{
+  			List<String>	lines = new ArrayList<String>();
+  			
+  			LineNumberReader lnr = new LineNumberReader( new InputStreamReader(new FileInputStream( f ), "UTF-8" ));
+  			
+  			int	dict_line 			= -1;
+  			int	auto_launch_line 	= -1;
+  			int	target_index		= -1;
+  			  			
+  			try{
+  				while( true ){
+  					
+  					String line = lnr.readLine();
+  					
+  					if ( line == null ){
+  						
+  						break;
+  					}
+  				
+ 					lines.add( line );
+ 					 
+  					if ( dict_line == -1 && containsTag( line, "<dict>" )){
+  						
+  						dict_line = lines.size();
+  					}
+  					
+  					if ( auto_launch_line == -1 && containsTag( line, "AutoLaunchedApplicationDictionary" )){
+  						
+  						auto_launch_line = lines.size();
+  					}
+  					
+  					if ( line.contains( abs_target )){
+  						
+  						target_index = lines.size();
+  					}
+  				}
+  					
+  				if ( dict_line == -1 ){
+  					
+  					throw( new PlatformManagerException( "Malformed plist - no 'dict' entry" ));
+  				}
+  				
+  				if ( auto_launch_line == -1 ){
+  					
+  					lines.add( dict_line, "\t<key>AutoLaunchedApplicationDictionary</key>" );
+  					
+  					auto_launch_line = dict_line+1;
+  					
+  					lines.add( auto_launch_line, "\t<array>" );
+  					lines.add( auto_launch_line+1, "\t</array>" );
+  				}
+  			}finally{
+  				
+  				lnr.close();
+  			}
+  			
+  			if ( run ){
+  				
+  				if ( target_index != -1 || auto_launch_line == -1 ){
+  					
+  					return;
+  				}
+  				
+  				target_index = auto_launch_line+1;
+  				
+ 				lines.add( target_index++, "\t\t<dict>" );
+				lines.add( target_index++, "\t\t\t<key>Path</key>" );
+				lines.add( target_index++, "\t\t\t<string>" + abs_target + "</string>" );
+ 				lines.add( target_index++, "\t\t</dict>" );
+  				
+  			}else{
+  				
+  				if ( target_index == -1 ){
+  					
+  					return;
+  				}
+  				
+  				while( !containsTag( lines.get( target_index ), "</dict>" )){
+  					
+  					lines.remove( target_index );
+  				}
+  				
+  				lines.remove( target_index );
+  				
+  				target_index--;
+  				
+  				while( !containsTag( lines.get( target_index ), "<dict>" )){
+  					
+  					lines.remove( target_index );
+  					
+  					target_index--;
+  				}
+  				
+  				lines.remove( target_index );
+  			}
+  			
+  			File	backup = new File( f.getParentFile(), f.getName() + ".bak" );
+  			
+  			if ( backup.exists()){
+  				
+  				backup.delete();
+  			}
+  			
+  			if ( !f.renameTo( backup )){
+  				
+  				throw( new PlatformManagerException( "Failed to backup " + f ));
+  			}
+  			
+			boolean	ok = false;
+			
+			try{
+				PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f ), "UTF-8" ));
+				
+				try{
+				
+					for ( String line: lines ){
+						
+						pw.println( line );
+					}
+				}finally{
+					
+					pw.close();
+					
+					if ( pw.checkError()){
+						
+						throw( new PlatformManagerException( "Failed to write output file" ));
+					}
+					
+					ok = true;
+				}
+			}finally{
+				
+				if ( !ok ){
+					
+					backup.renameTo( f );
+				}
+			}
+ 	
+  		}catch( PlatformManagerException e ){
+  			
+  			throw( e );
+  			
+  		}catch( Throwable e ){
+  			
+  			throw( new PlatformManagerException( "Failed to write output file", e ));
+  		}
+   	}
+    
+  	private void
+  	convertToXML(
+  		File		file )
+  	
+  		throws PlatformManagerException
+  	{
+ 		try{
+			LineNumberReader lnr = new LineNumberReader( new InputStreamReader(new FileInputStream( file ), "UTF-8" ));
+	
+			try{
+				String 	line = lnr.readLine();
+				
+				if ( line == null ){
+					
+					return;
+				}
+				
+				if ( line.trim().toLowerCase().startsWith( "<?xml" )){
+					
+					return;
+				}
+			
+	 			Runtime.getRuntime().exec(
+					new String[]{
+						findCommand( "plutil" ),
+						"-convert",
+						"xml1",
+						file.getAbsolutePath()
+					}).waitFor();
+				
+	  		}finally{
+	  			
+	  			lnr.close();
+	  		}
+  		}catch( Throwable e ){
+  			
+  			throw( new PlatformManagerException( "Failed to convert plist to xml" ));
+  		}
+  	}
+  	
+  	private String
+  	findCommand(
+  		String	name )
+  	{
+  		final String[]  locations = { "/bin", "/usr/bin" };
+
+  		for ( String s: locations ){
+
+  			File f = new File( s, name );
+
+  			if ( f.exists() && f.canRead()){
+
+  				return( f.getAbsolutePath());
+  			}
+  		}
+
+  		return( name );
+  	}
+  	
+  	private boolean
+  	containsTag(
+  		String	line,
+  		String	tag )
+  	{
+  		line 	= line.trim().toLowerCase( Locale.US );
+  		tag		= tag.toLowerCase( Locale.US );
+  		
+  		StringBuffer line2 = new StringBuffer( line.length());
+  		
+  		for (char c:line.toCharArray()){
+  			
+  			if ( !Character.isWhitespace( c )){
+  				
+  				line2.append( c );
+  			}
+  		}
+  		
+  		return( line2.toString().contains( tag ));
+  	}
+  	
+    private File 
+    getLoginPList() 
+    
+    	throws PlatformManagerException
+    {
+    	return( new File(System.getProperty("user.home"), "/Library/Preferences/loginwindow.plist" )); 
+    }
+    
     /**
      * {@inheritDoc}
      * @see org.gudy.azureus2.core3.util.SystemProperties#getUserPath()
@@ -376,15 +999,24 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
         return true;
     }
 
+    private String
+    getBundlePath()
+    {
+		return( System.getProperty("user.dir") +SystemProperties.SEP+ SystemProperties.getApplicationName() + ".app" );
+    }
+    
+    private File
+    getAbsoluteBundleFile()
+    {
+    	return( new File( getBundlePath()).getAbsoluteFile());
+    }
     
 	public String
 	getApplicationCommandLine()
 		throws PlatformManagerException
 	{
 		try{	    
-			String	bundle_path = System.getProperty("user.dir") +SystemProperties.SEP+ SystemProperties.getApplicationName() + ".app";
-
-			File osx_app_bundle = new File( bundle_path ).getAbsoluteFile();
+			File osx_app_bundle = getAbsoluteBundleFile();
 			
 			if( !osx_app_bundle.exists() ) {
 				String msg = "OSX app bundle not found: [" +osx_app_bundle.toString()+ "]";
@@ -456,6 +1088,24 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
             throw new PlatformManagerException("Failed to create process", e);
         }
     }
+    
+    private Class<?> getFileManagerClass() {
+    	if (claFileManager != null) {
+    		return claFileManager;
+    	}
+    	
+			try {
+				// We can only use FileManager after CocoaUIEnhancer has been initialized
+				// because refering to FileManager earlier will prevent our main menu from
+				// working
+				Class<?> claCocoaUIEnhancer = Class.forName("org.gudy.azureus2.ui.swt.osx.CocoaUIEnhancer");
+				if (((Boolean) claCocoaUIEnhancer.getMethod("isInitialized").invoke(null)).booleanValue()) {
+					claFileManager = Class.forName("com.apple.eio.FileManager");
+				}
+			} catch (Exception e) {
+			}
+			return claFileManager;
+    }
 
     /**
      * {@inheritDoc}
@@ -471,6 +1121,29 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
             return;
         }
 
+				
+				try {
+					Class<?> claFileManager = getFileManagerClass();
+
+					if (claFileManager != null) {
+  					Method methMoveToTrash = claFileManager.getMethod("moveToTrash",
+    						new Class[] {
+    							File.class
+    						});
+    				if (methMoveToTrash != null) {
+  						Object result = methMoveToTrash.invoke(null, new Object[] {
+  							file
+  						});
+  						if (result instanceof Boolean) {
+  							if (((Boolean) result).booleanValue()) {
+  								return;
+  							}
+  						}
+    				}
+					}
+ 				} catch (Throwable e) {
+				}
+
         boolean useOSA = !NativeInvocationBridge.sharedInstance().isEnabled() || !NativeInvocationBridge.sharedInstance().performRecoverableFileDelete(file);
 
         if(useOSA)
@@ -576,6 +1249,28 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
      */
     public void showInFinder(File path)
     {
+			
+			try {
+				Class<?> claFileManager = getFileManagerClass();
+				if (claFileManager != null && getFileBrowserName().equals("Finder")) {
+  				Method methRevealInFinder = claFileManager.getMethod("revealInFinder",
+  						new Class[] {
+  							File.class
+  						});
+  				if (methRevealInFinder != null) {
+						Object result = methRevealInFinder.invoke(null, new Object[] {
+							path
+						});
+						if (result instanceof Boolean) {
+							if (((Boolean) result).booleanValue()) {
+								return;
+							}
+						}
+  				}
+				}
+			} catch (Throwable e) {
+			}
+
         boolean useOSA = !NativeInvocationBridge.sharedInstance().isEnabled() || !NativeInvocationBridge.sharedInstance().showInFinder(path,fileBrowserName);
 
         if(useOSA)
@@ -869,6 +1564,77 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
 	}
 	
+	public int
+	getMaxOpenFiles()
+	
+		throws PlatformManagerException
+	{
+        LineNumberReader lnr = null;
+        
+	    try{
+	        Process p = 
+	        	Runtime.getRuntime().exec( 
+	        		new String[]{
+	        				"/bin/sh",
+	        				"-c",
+	        				"ulimit -a" });
+          
+	        lnr = new LineNumberReader( new InputStreamReader( p.getInputStream()));
+	        		    	        
+	        Map<String,String>	map = new HashMap<String,String>();
+	        
+	        while( true ){
+	        	
+	        	String	line = lnr.readLine();
+	        	
+	        	if ( line == null ){
+	        		
+	        		break;
+	        	}
+	        	
+	        	int	pos1 = line.indexOf( '(' );
+	        	int pos2 = line.indexOf( ')', pos1+1 );
+	        	
+	        	String keyword 	= line.substring( 0, pos1 ).trim().toLowerCase();
+	        	String value	= line.substring( pos2+1 ).trim();
+	        	
+	        	map.put( keyword, value );
+	        }
+	        
+	        String open_files = map.get( "open files" );
+	        
+	        if ( open_files != null ){
+	        	
+	        	if ( open_files.equalsIgnoreCase( "unlimited" )){
+	        		
+	        		return( 0 );
+	        	}else{
+	        		try{
+	        			return( Integer.parseInt( open_files ));
+	        			
+	        		}catch( Throwable e ){
+	        			
+	        			Debug.out( "open files invalid: " + open_files );
+	        		}
+	        	}
+	        }
+	    }catch( Throwable e ){
+	    	
+	    }finally{
+	    	
+            if ( lnr != null ){
+            	
+                try{
+                	lnr.close();
+                    
+                }catch( Throwable e ){
+                }
+            }
+        }
+
+	    return( -1 );
+	}
+	
     public void
     addListener(
     	PlatformManagerListener		listener )
@@ -881,29 +1647,33 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
     {
     }
 
-		// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
-		public void generate(IndentWriter writer) {
-			writer.println("PlatformManager: MacOSX");
-			try {
-				writer.indent();
-				
-				if (OSXAccess.isLoaded()) {
-					try {
-						writer.println("Version " + getVersion());
-						writer.println("User Data Dir: " + getLocation(LOC_USER_DATA));
-						writer.println("User Doc Dir: " + getLocation(LOC_DOCUMENTS));
-					} catch (PlatformManagerException e) {
-					}
-				} else {
-					writer.println("Not loaded");
-				}
-				
-				writer.println("Computer Name: " + getComputerName());
+    public void generate(IndentWriter writer) {
+    	writer.println("PlatformManager: MacOSX");
+    	try {
+    		writer.indent();
+
+    		if (OSXAccess.isLoaded()) {
+    			try {
+    				writer.println("Version " + getVersion());
+    				writer.println("User Data Dir: " + getLocation(LOC_USER_DATA));
+    				writer.println("User Doc Dir: " + getLocation(LOC_DOCUMENTS));
+    			} catch (PlatformManagerException e) {
+    			}
+    		} else {
+    			writer.println("Not loaded");
+    		}
 
-			} finally {
-				writer.exdent();
-			}
-		}
+    		writer.println("Computer Name: " + getComputerName());
+    		
+    		try{
+    			writer.println("Max Open Files: " + getMaxOpenFiles());
+    		}catch( Throwable e ){
+    			writer.println("Max Open Files: " + Debug.getNestedExceptionMessage( e ));
+    		}
+    	} finally {
+    		writer.exdent();
+    	}
+    }
 
 	// @see org.gudy.azureus2.platform.PlatformManager#getAzComputerID()
 	public String getAzComputerID() throws PlatformManagerException {
@@ -921,14 +1691,22 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 	 */
 	public void requestUserAttention(int type, Object data)
 			throws PlatformManagerException {
+		if (type == USER_REQUEST_QUESTION) {
+			return;
+		}
 		try {
-			NSApplication app = NSApplication.sharedApplication();
+			Class<?> claNSApplication = Class.forName("com.apple.eawt.Application");
+			Method methGetApplication = claNSApplication.getMethod("getApplication");
+			Object app = methGetApplication.invoke(null);
+			
+			Method methRequestUserAttention = claNSApplication.getMethod(
+					"requestUserAttention", new Class[] {
+						Boolean.class
+					});
 			if (type == USER_REQUEST_INFO) {
-				app.requestUserAttention(NSApplication.UserAttentionRequestInformational);
+				methRequestUserAttention.invoke(app, false);
 			} else if (type == USER_REQUEST_WARNING) {
-				app.requestUserAttention(NSApplication.UserAttentionRequestCritical);
-			} else if (type == USER_REQUEST_QUESTION) {
-				// not applicable
+				methRequestUserAttention.invoke(app, true);
 			}
 
 		} catch (Exception e) {
@@ -936,4 +1714,24 @@ public class PlatformManagerImpl implements PlatformManager, AEDiagnosticsEviden
 		}
 
 	}
+
+	public static void
+	main(
+		String[]	args )
+	{
+		try{
+			SystemProperties.setApplicationName( "Vuze" );
+			
+			// System.out.println( new PlatformManagerImpl().getMaxOpenFiles());
+			
+			PlatformManagerImpl pm = new PlatformManagerImpl();
+			
+			pm.getRunAtLogin();
+			
+			pm.setRunAtLogin( false );
+		}catch( Throwable e ){
+			
+			e.printStackTrace();
+		}
+	}
 }
diff --git a/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java b/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
index b3473c7..340c290 100644
--- a/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
+++ b/org/gudy/azureus2/platform/macosx/PlatformManagerUpdateChecker.java
@@ -240,7 +240,17 @@ PlatformManagerUpdateChecker
 								installUpdate( checker, update, downloader, data );
 									
 								return( true );
-							}							
+							}	
+							
+							public void
+							failed(
+								ResourceDownloader			downloader,
+								ResourceDownloaderException e )
+							{
+								Debug.out( downloader.getName() + " failed", e );
+								
+								update.complete( false );
+							}
 						});
 			}
 		}catch( Throwable e ){
@@ -317,8 +327,13 @@ PlatformManagerUpdateChecker
 					}
 				}
 			}
+			
+			update.complete( true );
+			
 		} catch (Throwable e) {
 
+			update.complete( false );
+			
 			rd.reportActivity("Update install failed:" + e.getMessage());
 			
 		}finally{
diff --git a/org/gudy/azureus2/platform/macosx/access/cocoa/CocoaJavaBridge.java b/org/gudy/azureus2/platform/macosx/access/cocoa/CocoaJavaBridge.java
index 6a64a7d..4b5b0a3 100644
--- a/org/gudy/azureus2/platform/macosx/access/cocoa/CocoaJavaBridge.java
+++ b/org/gudy/azureus2/platform/macosx/access/cocoa/CocoaJavaBridge.java
@@ -22,10 +22,6 @@ package org.gudy.azureus2.platform.macosx.access.cocoa;
  *
  */
 
-import com.apple.cocoa.foundation.NSAppleEventDescriptor;
-import com.apple.cocoa.foundation.NSAppleScript;
-import com.apple.cocoa.foundation.NSAutoreleasePool;
-import com.apple.cocoa.foundation.NSMutableDictionary;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AERunnable;
@@ -34,9 +30,15 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.platform.macosx.NativeInvocationBridge;
 
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.text.MessageFormat;
 
 /**
+ * NOTE: This is only used for OSX 10.4 and non-up-to-date 10.5,10.6. 
+ * OSX 10.5 Update 6 and OSX 10.6 Update 1 provides revealInFinder and moveToTrash
+ * functionality.
+ * <p>
  * <p>Performs PlatformManager tasks using Cocoa-Java (FoundationKit only)</p>
  * <p>For now, operations are performed using NSAppleScript, rather than using NSWorkspace.
  * This is still significantly faster than calling the cmd-line osascript.</p>
@@ -64,13 +66,50 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
     protected boolean isDisposed = false;
 
     protected RunnableDispatcher scriptDispatcher;
+    
+    private Class claNSAppleEventDescriptor;
 
-    public CocoaJavaBridge()
+		private Class<?> claNSAutoreleasePool;
+
+		private Method methPush;
+
+		private Method methPop;
+
+		private Method methNSAppleEventDescriptor_descriptorWithBoolean;
+
+		private Class<?> claNSAppleScript;
+
+		private Class<?> claNSMutableDictionary;
+
+		private Method methNSAppleScript_execute;
+
+		private String NSAppleScript_AppleScriptErrorMessage;
+
+		private Method methNSMutableDictionary_objectForKey;
+
+    public CocoaJavaBridge() throws Throwable
     {
         try
         {
             classMon.enter();
-            mainPool = NSAutoreleasePool.push();
+
+            claNSMutableDictionary = Class.forName("com.apple.cocoa.foundation.NSMutableDictionary");
+            methNSMutableDictionary_objectForKey = claNSMutableDictionary.getMethod("objectForKey", Object.class);
+            
+            claNSAppleEventDescriptor = Class.forName("com.apple.cocoa.foundation.NSAppleEventDescriptor");
+            methNSAppleEventDescriptor_descriptorWithBoolean = claNSAppleEventDescriptor.getMethod("descriptorWithBoolean", new Class [] { boolean.class });
+
+            claNSAutoreleasePool = Class.forName("com.apple.cocoa.foundation.NSAutoreleasePool");
+            methPush = claNSAutoreleasePool.getMethod("push", new Class [0]);
+            methPop = claNSAutoreleasePool.getMethod("pop", new Class [] { int.class });
+
+            claNSAppleScript = Class.forName("com.apple.cocoa.foundation.NSAppleScript");
+            methNSAppleScript_execute = claNSAppleScript.getMethod("execute", new Class[] { claNSMutableDictionary });
+            NSAppleScript_AppleScriptErrorMessage = (String) claNSAppleScript.getField("AppleScriptErrorMessage").get(null);
+
+
+            //mainPool = NSAutoreleasePool.push();
+            mainPool = NSAutoreleasePool_push();
 
             scriptDispatcher = new RunnableDispatcher();
         }
@@ -79,6 +118,32 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
             classMon.exit();
         }
     }
+    
+    private int NSAutoreleasePool_push() throws Throwable
+    {
+      return ((Number) methPush.invoke(null)).intValue();
+    }
+
+    private void NSAutoreleasePool_pop(int i) throws Throwable
+    {
+      methPop.invoke(null, i);
+    }
+    
+    private Object new_NSAppleScript(String s) throws Throwable {
+    	return claNSAppleScript.getConstructor(new Class[] { String.class }).newInstance(s);
+    }
+    
+    private Object NSAppleScript_execute(Object NSAppleScript, Object NSMutableDictionary) throws Throwable {
+    	return methNSAppleScript_execute.invoke(NSAppleScript, NSMutableDictionary);
+    }
+    
+    private Object new_NSMutableDictionary() throws Throwable {
+    	return claNSMutableDictionary.newInstance();
+    }
+    
+    private Object NSMutableDictionary_objectForKey(Object NSMutableDictionary, String s) throws Throwable {
+    	return methNSMutableDictionary_objectForKey.invoke(NSMutableDictionary, s);
+    }
 
     // interface implementation
 
@@ -91,7 +156,13 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
             return false;
         }
         
-        NSAppleEventDescriptor result =  executeScriptWithAsync(DEL_SCRIPT_FORMAT, new Object[]{path.getAbsolutePath()});
+        Object result;
+				try {
+					result = executeScriptWithAsync(DEL_SCRIPT_FORMAT, new Object[]{path.getAbsolutePath()});
+				} catch (Throwable t) {
+					Debug.out(t);
+					return false;
+				}
         
         	// quick hack here for people where things take a while - too scared to make it a 
         	// sync call as I don't know the code...
@@ -135,15 +206,19 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
 		if (!path.exists())
 			return false;
 
-		NSAppleEventDescriptor result = null;
-		int pool = NSAutoreleasePool.push();
+		Object /*NSAppleEventDescriptor*/ result = null;
 		try {
-			result = executeScriptWithAsync(REVEAL_SCRIPT_FORMAT, new Object[] {
-				fileBrowserApp,
-				path.getAbsolutePath()
-			});
-		} finally {
-			NSAutoreleasePool.pop(pool);
+			int pool = NSAutoreleasePool_push();
+			try {
+				result = executeScriptWithAsync(REVEAL_SCRIPT_FORMAT, new Object[] {
+					fileBrowserApp,
+					path.getAbsolutePath()
+				});
+			} finally {
+				NSAutoreleasePool_pop(pool);
+			}
+		} catch (Throwable t) {
+			return false;
 		}
 		return (result != null);
 	}
@@ -153,8 +228,7 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
      */
     protected boolean isEnabled()
     {
-        // simple check with classpath
-        return System.getProperty("java.class.path").toLowerCase().indexOf(CLASS_PATH) != -1;
+    	return claNSAutoreleasePool != null;
     }
 
     // class utility methods
@@ -167,13 +241,13 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
      * @see MessageFormat#format(String, Object...)
      * @see NSAppleScript#execute(com.apple.cocoa.foundation.NSMutableDictionary)
      */
-    protected final NSAppleEventDescriptor executeScript(String scriptFormat, Object[] params)
+    protected final Object /*NSAppleEventDescriptor*/ executeScript(String scriptFormat, Object[] params) throws Throwable
     {
         try
         {
             scriptMon.enter();
 
-            int pool = NSAutoreleasePool.push();
+            int pool = NSAutoreleasePool_push();
             long start = System.currentTimeMillis();
 
             String src;
@@ -188,11 +262,11 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
 
             Debug.outNoStack("Executing: \n" + src);
 
-            NSAppleScript scp = new NSAppleScript(src);
-            NSAppleEventDescriptor result =  scp.execute(new NSMutableDictionary());
+            Object /*NSAppleScript*/ scp = new_NSAppleScript(src);
+            Object /*NSAppleEventDescriptor*/ result =  NSAppleScript_execute(scp, new_NSMutableDictionary());
 
             Debug.outNoStack(MessageFormat.format("Elapsed time: {0}ms\n", new Object[]{new Long(System.currentTimeMillis() - start)}));
-            NSAutoreleasePool.pop(pool);
+            NSAutoreleasePool_pop(pool);
             return result;
         }
         finally
@@ -212,45 +286,51 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
      * @see MessageFormat#format(String, Object...)
      * @see NSAppleScript#execute(com.apple.cocoa.foundation.NSMutableDictionary)
      * @return NSAppleEventDescriptor.descriptorWithBoolean(true)
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws IllegalArgumentException 
      */
-    protected final NSAppleEventDescriptor executeScriptWithNewThread(final String scriptFormat, final Object[] params)
-    {
-        Thread worker = new AEThread("ScriptObject", true)
-        {
-            public void runSupport()
-            {
-                int pool = NSAutoreleasePool.push();
-                long start = System.currentTimeMillis();
-
-                String src;
-                if(params == null || params.length == 0)
-                {
-                    src = scriptFormat;
-                }
-                else
-                {
-                    src = MessageFormat.format(scriptFormat, params);
-                }
-
-                Debug.outNoStack("Executing: \n" + src);
-
-                NSMutableDictionary errorInfo = new NSMutableDictionary();
-                if(new NSAppleScript(src).execute(errorInfo) == null)
-                {
-                    Debug.out(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorMessage)));
-                    //logWarning(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorBriefMessage)));
-                }
-
-                Debug.outNoStack(MessageFormat.format("Elapsed time: {0}ms\n", new Object[]{new Long(System.currentTimeMillis() - start)}));
-                NSAutoreleasePool.pop(pool);
-            }
-        };
-
-        worker.setPriority(Thread.NORM_PRIORITY - 1);
-        worker.start();
-
-        return NSAppleEventDescriptor.descriptorWithBoolean(true);
-    }
+  protected final Object /*NSAppleEventDescriptor*/ executeScriptWithNewThread(
+		final String scriptFormat, final Object[] params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
+  {
+		Thread worker = new AEThread("ScriptObject", true) {
+			public void runSupport() {
+				try {
+					int pool = NSAutoreleasePool_push();
+					long start = System.currentTimeMillis();
+
+					String src;
+					if (params == null || params.length == 0) {
+						src = scriptFormat;
+					} else {
+						src = MessageFormat.format(scriptFormat, params);
+					}		
+
+					Debug.outNoStack("Executing: \n" + src);
+
+					Object /*NSMutableDictionary*/ errorInfo = new_NSMutableDictionary();
+					if (NSAppleScript_execute(new_NSAppleScript(src), errorInfo) == null) {
+						Debug.out(String.valueOf(NSMutableDictionary_objectForKey(errorInfo, NSAppleScript_AppleScriptErrorMessage)));
+						//logWarning(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorBriefMessage)));
+					}
+
+					Debug.outNoStack(MessageFormat.format("Elapsed time: {0}ms\n",
+							new Object[] {
+								new Long(System.currentTimeMillis() - start)
+							}));
+					NSAutoreleasePool_pop(pool);
+				} catch (Throwable e) {
+					Debug.out(e);
+				}
+			}
+		};
+
+		worker.setPriority(Thread.NORM_PRIORITY - 1);
+		worker.start();
+
+		return methNSAppleEventDescriptor_descriptorWithBoolean.invoke(null, true);
+		//return NSAppleEventDescriptor.descriptorWithBoolean(true);
+	}
 
     /**
      * <p>Asynchronously executes a new instance of NSAppleScript</p>
@@ -263,39 +343,44 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
      * @see MessageFormat#format(String, Object...)
      * @see NSAppleScript#execute(com.apple.cocoa.foundation.NSMutableDictionary)
      * @return NSAppleEventDescriptor.descriptorWithBoolean(true)
+     * @throws InvocationTargetException 
+     * @throws IllegalAccessException 
+     * @throws IllegalArgumentException 
      */
-    protected final NSAppleEventDescriptor executeScriptWithAsync(final String scriptFormat, final Object[] params)
+    protected final Object /*NSAppleEventDescriptor*/ executeScriptWithAsync(final String scriptFormat, final Object[] params) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
     {
         final AERunnable worker = new AERunnable()
         {
-            public void runSupport()
-            {
-                int pool = NSAutoreleasePool.push();
-                long start = System.currentTimeMillis();
-
-                String src;
-                if(params == null || params.length == 0)
-                {
-                    src = scriptFormat;
-                }
-                else
-                {
-                    src = MessageFormat.format(scriptFormat, params);
-                }
-
-                Debug.outNoStack("Executing: \n" + src);
-
-                NSMutableDictionary errorInfo = new NSMutableDictionary();
-                if(new NSAppleScript(src).execute(errorInfo) == null)
-                {
-                    Debug.out(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorMessage)));
-                    //logWarning(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorBriefMessage)));
-                }
-
-                Debug.outNoStack(MessageFormat.format("Elapsed time: {0}ms\n", new Object[]{new Long(System.currentTimeMillis() - start)}));
-                NSAutoreleasePool.pop(pool);
-            }
-        };
+			public void runSupport() {
+				try {
+					int pool = NSAutoreleasePool_push();
+					long start = System.currentTimeMillis();
+
+					String src;
+					if (params == null || params.length == 0) {
+						src = scriptFormat;
+					} else {
+						src = MessageFormat.format(scriptFormat, params);
+					}
+
+					Debug.outNoStack("Executing: \n" + src);
+
+					Object /*NSMutableDictionary*/ errorInfo = new_NSMutableDictionary();
+					if (NSAppleScript_execute(new_NSAppleScript(src), errorInfo) == null) {
+						Debug.out(String.valueOf(NSMutableDictionary_objectForKey(errorInfo, NSAppleScript_AppleScriptErrorMessage)));
+						//logWarning(String.valueOf(errorInfo.objectForKey(NSAppleScript.AppleScriptErrorBriefMessage)));
+					}
+
+					Debug.outNoStack(MessageFormat.format("Elapsed time: {0}ms\n",
+							new Object[] {
+								new Long(System.currentTimeMillis() - start)
+							}));
+					NSAutoreleasePool_pop(pool);
+				} catch (Throwable t) {
+					Debug.out(t);
+				}
+			}
+		};
 
         AEThread t = new AEThread("ScriptObject", true)
         {
@@ -307,7 +392,8 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
         t.setPriority(Thread.NORM_PRIORITY - 1);
         t.start();
 
-        return NSAppleEventDescriptor.descriptorWithBoolean(true);
+    		return methNSAppleEventDescriptor_descriptorWithBoolean.invoke(null, true);
+    		//return NSAppleEventDescriptor.descriptorWithBoolean(true);
     }
 
     /**
@@ -340,7 +426,10 @@ public final class CocoaJavaBridge extends NativeInvocationBridge
             if(!isDisposed)
             {
                 Debug.outNoStack("Disposing Native PlatformManager...");
-                NSAutoreleasePool.pop(mainPool);
+                try {
+									NSAutoreleasePool_pop(mainPool);
+								} catch (Throwable e) {
+								}
                 isDisposed = true;
                 Debug.outNoStack("Done");
             }
diff --git a/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java b/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
index 32f940e..d5e101d 100644
--- a/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
+++ b/org/gudy/azureus2/platform/macosx/access/jnilib/OSXAccess.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import org.gudy.azureus2.core3.util.*;
 
+import com.aelitis.azureus.core.drivedetector.DriveDetectedInfo;
 import com.aelitis.azureus.core.drivedetector.DriveDetectorFactory;
 import com.aelitis.azureus.util.MapUtils;
 
@@ -53,7 +54,7 @@ public class OSXAccess
 			bLoaded = true;
 			initDriveDetection();
 		} catch (Throwable e1) {
-			Debug.out("Could not find lib" + lib + ".jnilib", e1);
+			Debug.outNoStack("Could not find lib" + lib + ".jnilib; " + e1.toString());
 		}
 		
 		return bLoaded;
@@ -99,9 +100,11 @@ public class OSXAccess
 					boolean isOptical = MapUtils.getMapLong(driveInfo, "isOptical", 0) != 0;
 					boolean isRemovable = MapUtils.getMapLong(driveInfo, "Removable", 0) != 0;
 					boolean isWritable = MapUtils.getMapLong(driveInfo, "Writable", 0) != 0;
-					if (isRemovable && isWritable && !isOptical) {
-						DriveDetectorFactory.getDeviceDetector().driveDetected(mount);
-					}
+					
+					boolean isWritableUSB = (isRemovable && isWritable && !isOptical);
+					driveInfo.put("isWritableUSB", isWritableUSB);
+					
+					DriveDetectorFactory.getDeviceDetector().driveDetected(mount, driveInfo);
 				}
 			});
 		} catch (Throwable t) {
@@ -126,4 +129,17 @@ public class OSXAccess
 	public static boolean isLoaded() {
 		return bLoaded;
 	}
+	
+	public static void main(String[] args) {
+		DriveDetectedInfo[] infos = DriveDetectorFactory.getDeviceDetector().getDetectedDriveInfo();
+		for (DriveDetectedInfo info : infos) {
+			System.out.println(info.getLocation());
+			
+			Map<String, Object> infoMap = info.getInfoMap();
+			for (String key : infoMap.keySet()) {
+				Object val = infoMap.get(key);
+				System.out.println("\t" + key + ": " + val);
+			}
+		}
+	}
 }
diff --git a/org/gudy/azureus2/platform/unix/PlatformManagerImpl.java b/org/gudy/azureus2/platform/unix/PlatformManagerImpl.java
index 1287100..ee619e0 100644
--- a/org/gudy/azureus2/platform/unix/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/unix/PlatformManagerImpl.java
@@ -33,6 +33,8 @@ import org.gudy.azureus2.platform.*;
 
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 
+import com.aelitis.azureus.core.AzureusCore;
+
 /**
  * @author TuxPaper
  * @created Dec 18, 2006
@@ -185,6 +187,14 @@ public class PlatformManagerImpl implements PlatformManager
 		throw new PlatformManagerException(ERR_UNSUPPORTED);
 	}
 
+	public int
+	getMaxOpenFiles()
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException(ERR_UNSUPPORTED);		
+	}
+	
 	// @see org.gudy.azureus2.platform.PlatformManager#registerApplication()
 	public void registerApplication() throws PlatformManagerException {
 		throw new PlatformManagerException(ERR_UNSUPPORTED);
@@ -200,6 +210,86 @@ public class PlatformManagerImpl implements PlatformManager
 		// No Listener Functionality
 	}
 
+	public File 
+	getVMOptionFile() 
+	
+		throws PlatformManagerException 
+	{
+		throw new PlatformManagerException(ERR_UNSUPPORTED);
+	}
+	
+	public String[]
+	getExplicitVMOptions()
+	          	
+	 	throws PlatformManagerException
+	{
+		throw new PlatformManagerException(ERR_UNSUPPORTED);
+	}
+	 
+	public void
+	setExplicitVMOptions(
+		String[]		options )
+	          	
+		throws PlatformManagerException
+	{
+		throw new PlatformManagerException(ERR_UNSUPPORTED);
+	}
+	
+  	public boolean 
+  	getRunAtLogin() 
+  	
+  		throws PlatformManagerException 
+  	{
+  		throw new PlatformManagerException(ERR_UNSUPPORTED);
+  	}
+  	
+  	public void 
+  	setRunAtLogin(
+  		boolean run ) 
+  	
+  		throws PlatformManagerException 
+  	{
+  		throw new PlatformManagerException(ERR_UNSUPPORTED);
+   	}
+	  
+	public void
+	startup(
+		AzureusCore		azureus_core )
+	
+		throws PlatformManagerException
+	{	
+	}
+	
+	public int
+	getShutdownTypes()
+	{
+		return( 0 );
+	}
+	
+	public void
+	shutdown(
+		int			type )
+	
+		throws PlatformManagerException
+	{	
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public void
+	setPreventComputerSleep(
+		boolean		b )
+	
+		throws PlatformManagerException
+	{	
+		 throw new PlatformManagerException("Unsupported capability called on platform manager");
+	}
+	
+	public boolean
+	getPreventComputerSleep()
+	{
+		return( false );
+	}
+	
 	// @see org.gudy.azureus2.platform.PlatformManager#setTCPTOSEnabled(boolean)
 	public void setTCPTOSEnabled(boolean enabled) throws PlatformManagerException {
 		throw new PlatformManagerException(ERR_UNSUPPORTED);
diff --git a/org/gudy/azureus2/platform/unix/startupScript b/org/gudy/azureus2/platform/unix/startupScript
index e627ca7..de8117f 100644
--- a/org/gudy/azureus2/platform/unix/startupScript
+++ b/org/gudy/azureus2/platform/unix/startupScript
@@ -14,7 +14,7 @@ JAVA_ARGS="-Xmx128m"
 
 ######## YOU PROBABLY DO NOT WANT TO TOUCH ANYTHING BELOW! ########
 
-SCRIPT_VERSION=2
+SCRIPT_VERSION=3
 START_CLASS="org.gudy.azureus2.ui.swt.Main"
 
 MSG_LOADING="Loading Azureus:"
@@ -130,6 +130,20 @@ runJavaOutput()
 	fi
 }
 
+moveInSWT()
+{
+	if [ ! -f "${PROGRAM_DIR}/swt.jar" ]; then
+		if [ ! "$(echo ${PROGRAM_DIR}/swt/*.jar)" = "${PROGRAM_DIR}/swt/*.jar" ]; then
+			if [ "`${JAVA_PROGRAM_DIR}java -cp \"${CLASSPATH}\" org.gudy.azureus2.platform.JavaBitMode`" = "64" ]; then 
+				cp ${PROGRAM_DIR}/swt/swt64.jar ${PROGRAM_DIR}/swt.jar
+			else
+				cp ${PROGRAM_DIR}/swt/swt32.jar ${PROGRAM_DIR}/swt.jar
+			fi
+		fi
+	fi
+}
+
+
 echo $MSG_STARTING
 
 # locate and test the java executable
@@ -161,6 +175,8 @@ for FILE in ./*.jar; do
 	CLASSPATH="${CLASSPATH:+${CLASSPATH}:}$FILE"
 done
 
+moveInSWT
+
 # setup Java System Properties (no spaces in values)
 JAVA_PROPS="-Dazureus.script.version=${SCRIPT_VERSION}"
 if [ ! "$JAVA_ISGCJ x" = " x" ] ; then
diff --git a/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java b/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
index f27387f..a62d79a 100644
--- a/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
+++ b/org/gudy/azureus2/platform/win32/PlatformManagerImpl.java
@@ -27,25 +27,36 @@ package org.gudy.azureus2.platform.win32;
  *
  */
 
-import java.io.File;
+import java.io.*;
 import java.net.InetAddress;
 import java.util.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.LogAlert;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.platform.*;
-import org.gudy.azureus2.platform.win32.access.AEWin32Access;
-import org.gudy.azureus2.platform.win32.access.AEWin32AccessListener;
-import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
+import org.gudy.azureus2.platform.win32.access.*;
+import org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessInterface;
 
+import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIManagerEvent;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.update.UpdateException;
+import org.gudy.azureus2.plugins.update.UpdateInstaller;
+import org.gudy.azureus2.plugins.update.UpdateInstallerListener;
+import org.gudy.azureus2.plugins.update.UpdateManager;
+import org.gudy.azureus2.plugins.update.UpdateManagerListener;
+import org.gudy.azureus2.plugins.utils.StaticUtilities;
 
+import com.aelitis.azureus.core.AzureusCore;
 
 public class 
 PlatformManagerImpl
-	implements PlatformManager, AEWin32AccessListener
+	implements PlatformManager, AEWin32AccessListener, AEDiagnosticsEvidenceGenerator
 {
 	public static final int			RT_NONE		= 0;
 	public static final int			RT_AZ 		= 1;
@@ -68,7 +79,9 @@ PlatformManagerImpl
 	private List	listeners = new ArrayList();
 	
 	static {
-		if (System.getProperty("os.arch", "").contains("64")) {
+		if (System.getProperty("aereg", null) != null) {
+			DLL_NAME = System.getProperty("aereg");
+		} else if (System.getProperty("os.arch", "").contains("64")) {
 			DLL_NAME += "64";
 		}
 	}
@@ -140,6 +153,9 @@ PlatformManagerImpl
 	private File					az_exe;
 	private boolean					az_exe_checked;
 
+	private boolean					prevent_computer_sleep;
+	private AEThread2				prevent_sleep_thread;
+	
 	protected
 	PlatformManagerImpl()
 	
@@ -151,7 +167,26 @@ PlatformManagerImpl
 		
 		app_name		= SystemProperties.getApplicationName();
 		
-		app_exe_name	= app_name + ".exe";
+		String mod_name = System.getProperty( "exe4j.moduleName", null );
+		
+		String exe_name = null;
+		
+		if ( mod_name != null && new File( mod_name ).exists() && mod_name.toLowerCase().endsWith( ".exe" )){
+			
+			int	pos = mod_name.lastIndexOf( File.separator );
+			
+			if ( pos != -1 ){
+				
+				exe_name = mod_name.substring( pos+1 );
+			}
+		}
+		
+		if ( exe_name == null ){
+		
+			exe_name	= app_name + ".exe";
+		}
+		
+		app_exe_name = exe_name;
 		
         initializeCapabilities();
 	}
@@ -170,29 +205,44 @@ PlatformManagerImpl
 	        capabilitySet.add(PlatformManagerCapabilities.SetTCPTOSEnabled);
 	        capabilitySet.add(PlatformManagerCapabilities.ComputerIDAvailability);
 	        
+	        String plugin_version = access.getVersion();
 	        
-	        if ( Constants.compareVersions( access.getVersion(), "1.11" ) >= 0 &&
+	        if ( Constants.compareVersions( plugin_version, "1.11" ) >= 0 &&
 	        		!Constants.isWindows9598ME ){
 	        	
 	            capabilitySet.add(PlatformManagerCapabilities.CopyFilePermissions);
 	            
 	        }
 	        
-	        if ( Constants.compareVersions( access.getVersion(), "1.12" ) >= 0 ){
+	        if ( Constants.compareVersions( plugin_version, "1.12" ) >= 0 ){
 	        	
 	            capabilitySet.add(PlatformManagerCapabilities.TestNativeAvailability);
 	        }
 	        
-	        if ( Constants.compareVersions( access.getVersion(), "1.14" ) >= 0 ){
+	        if ( Constants.compareVersions( plugin_version, "1.14" ) >= 0 ){
 	        	
 	            capabilitySet.add(PlatformManagerCapabilities.TraceRouteAvailability);
 	        }
 
-	        if ( Constants.compareVersions( access.getVersion(), "1.15" ) >= 0 ){
+	        if ( Constants.compareVersions( plugin_version, "1.15" ) >= 0 ){
 	        	
 	            capabilitySet.add(PlatformManagerCapabilities.PingAvailability);
 	        }
 
+	        try{
+	        	getUserDataDirectory();
+	        	
+	        		// if we can access the user dir then we're good to access vmoptions
+	        	
+	        	if ( Constants.compareVersions( plugin_version, "1.19" ) >= 0 ){
+	        	
+	        		capabilitySet.add(PlatformManagerCapabilities.AccessExplicitVMOptions );
+	        	}
+	        }catch( Throwable e ){
+	        }
+	        
+	        capabilitySet.add(PlatformManagerCapabilities.RunAtLogin);
+	        capabilitySet.add(PlatformManagerCapabilities.PreventComputerSleep);
     	}else{
     		
     			// disabled -> only available capability is that to get the version
@@ -208,7 +258,7 @@ PlatformManagerImpl
 		try{
 			File	exe_loc = getApplicationEXELocation();
 			
-			String	az_exe_string = exe_loc.toString();
+			String	az_exe_string = exe_loc.getAbsolutePath();
 			
 			//int	icon_index = getIconIndex();
 			
@@ -444,6 +494,825 @@ PlatformManagerImpl
 	    }
 	}
 	
+	private String
+	getJVMOptionRedirect()
+	{
+		return( "-include-options ${APPDATA}\\" + SystemProperties.getApplicationName() + "\\java.vmoptions" );
+	}
+	
+	private File[]
+	getJVMOptionFiles()
+	{
+		try{
+			File exe = getApplicationEXELocation();
+	
+			File shared_options 		= new File( exe.getParent(), exe.getName() + ".vmoptions" );
+			File local_options 			= new File( SystemProperties.getUserPath(), "java.vmoptions" );
+			
+			return( new File[]{ shared_options, local_options });
+			
+		}catch( Throwable e ){
+			
+			return( new File[0] );
+		}
+	}
+	
+	private File
+	checkAndGetLocalVMOptionFile()
+	
+		throws PlatformManagerException
+	{
+		String vendor = System.getProperty( "java.vendor", "<unknown>" );
+		
+		if ( !vendor.toLowerCase().startsWith( "sun " ) && !vendor.toLowerCase().startsWith( "oracle " )){
+			
+			throw( new PlatformManagerException( 
+						MessageText.getString( 
+							"platform.jvmopt.sunonly",
+							new String[]{ vendor })));
+		}
+		
+		File[] option_files = getJVMOptionFiles();
+		
+		if ( option_files.length != 2 ){
+			
+			throw( new PlatformManagerException( 
+					MessageText.getString( "platform.jvmopt.configerror" )));
+		}
+		
+		File shared_options = option_files[0];
+		
+		if ( shared_options.exists()){
+
+			try{
+				String s_options = FileUtil.readFileAsString( shared_options, -1 );
+	
+				if ( s_options.contains( getJVMOptionRedirect() )){
+									
+					File local_options = option_files[1];
+					
+					return( local_options );
+					
+				}else{
+					
+					throw( new PlatformManagerException( MessageText.getString( "platform.jvmopt.nolink" )));
+				}
+			}catch( Throwable e ){
+				
+				throw( new PlatformManagerException( MessageText.getString( "platform.jvmopt.accesserror", new String[]{ Debug.getNestedExceptionMessage(e) } )));
+			}
+		}else{
+			
+			throw( new PlatformManagerException( MessageText.getString( "platform.jvmopt.nolinkfile" )));
+		}			
+	}
+	
+	public File 
+	getVMOptionFile() 
+	
+		throws PlatformManagerException 
+	{
+		checkCapability( PlatformManagerCapabilities.AccessExplicitVMOptions );
+		
+		File local_options = checkAndGetLocalVMOptionFile();
+
+		if ( !local_options.exists()){
+			
+			try{
+				local_options.createNewFile();
+				
+			}catch( Throwable e ){
+			}
+		}
+		
+		return( local_options );
+	}
+	
+	public String[]
+   	getExplicitVMOptions()
+  	          	
+     	throws PlatformManagerException
+  	{
+		checkCapability( PlatformManagerCapabilities.AccessExplicitVMOptions );
+			
+		
+		File local_options = checkAndGetLocalVMOptionFile();
+
+		try{
+					
+			List<String>	list = new ArrayList<String>();
+			
+			if ( local_options.exists()){
+				
+				LineNumberReader lnr = new LineNumberReader( new InputStreamReader( new FileInputStream( local_options ), "UTF-8" ));
+					
+				try{
+					while( true ){
+						
+						String	line = lnr.readLine();
+						
+						if ( line == null ){
+							
+							break;
+						}
+						
+						line = line.trim();
+						
+						if ( line.length() > 0 ){
+							
+							list.add( line );
+						}
+					}
+					
+				}finally{
+					
+					lnr.close();
+				}
+			}
+			
+			return( list.toArray( new String[list.size()]));
+					
+		}catch( Throwable e ){
+			
+			throw( new PlatformManagerException( MessageText.getString( "platform.jvmopt.accesserror", new String[]{ Debug.getNestedExceptionMessage(e) } )));
+		}
+  	}
+  	 
+  	public void
+  	setExplicitVMOptions(
+  		String[]		options )
+  	          	
+  		throws PlatformManagerException
+  	{
+		checkCapability( PlatformManagerCapabilities.AccessExplicitVMOptions );
+
+		File local_options = checkAndGetLocalVMOptionFile();
+
+		try{				
+			List<String>	list = new ArrayList<String>();
+			
+			if ( local_options.exists()){
+				
+				File backup = new File( local_options.getParentFile(), local_options.getName() + ".bak" );
+				
+				if ( backup.exists()){
+					
+					backup.delete();
+				}
+				
+				if ( !local_options.renameTo( backup )){
+				
+					throw( new Exception( "Failed to move " + local_options + " to " + backup ));
+				}
+				
+				boolean	ok = false;
+				
+				try{
+					
+					PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream( local_options ), "UTF-8" ));
+					
+					try{
+						for ( String option: options ){
+							
+							pw.println( option );
+						}
+					
+						ok = true;
+						
+					}finally{
+						
+						pw.close();
+					}
+				}finally{
+					
+					if ( !ok ){
+						
+						local_options.delete();
+						
+						backup.renameTo( local_options );
+					}
+				}
+			}					
+		}catch( Throwable e ){
+			
+			throw( new PlatformManagerException( MessageText.getString( "platform.jvmopt.accesserror", new String[]{ Debug.getNestedExceptionMessage(e) } )));
+		}
+	}
+  	
+ 	public boolean 
+  	getRunAtLogin() 
+  	
+  		throws PlatformManagerException 
+  	{
+		File exe = getApplicationEXELocation();
+
+		if ( exe != null && exe.exists()){
+			
+	 		try{
+				String value = access.readStringValue(
+						AEWin32Access.HKEY_CURRENT_USER,
+						"Software\\Microsoft\\Windows\\CurrentVersion\\Run", app_name );
+				
+				return( value.equals( exe.getAbsolutePath()));
+				
+			}catch( Throwable e ){
+				
+				return( false );
+			}
+		}else{
+			
+			return( false );
+		}
+  	}
+  	
+  	public void 
+  	setRunAtLogin(
+  		boolean run ) 
+  	
+  		throws PlatformManagerException 
+  	{
+  		File exe = getApplicationEXELocation();
+  		
+  		if ( exe != null && exe.exists()){
+ 
+	  		try{
+	  			String key = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
+	  			
+	  			if ( run ){
+	  				
+					access.writeStringValue(
+						AEWin32Access.HKEY_CURRENT_USER,
+						key, app_name, exe.getAbsolutePath());
+	  			}else{
+	  				
+	  				access.deleteValue( AEWin32Access.HKEY_CURRENT_USER, key, app_name );
+	  			}
+			}catch( Throwable e ){
+				
+				throw( new PlatformManagerException( "Failed to write 'run at login' key", e ));
+			}
+  		}
+   	}
+  		
+	public int
+	getShutdownTypes()
+	{
+		int	result = SD_SLEEP | SD_SHUTDOWN;
+		
+		if ( canHibernate()){
+			
+			result |= SD_HIBERNATE;
+		}
+		
+		return( result );
+	}
+	
+	public boolean
+	getPreventComputerSleep()
+	{
+		synchronized( this ){
+		
+			return( prevent_computer_sleep );
+		}
+	}
+	
+	public void
+	setPreventComputerSleep(
+		boolean		prevent_it )
+	{
+		synchronized( this ){
+			
+			if ( prevent_computer_sleep == prevent_it ){
+				
+				return;
+			}
+			
+			prevent_computer_sleep = prevent_it;
+			
+			if ( prevent_it ){
+				
+				if ( prevent_sleep_thread == null ){
+					
+					prevent_sleep_thread = 
+						new AEThread2( "SleepPreventer")
+						{
+							public void run()
+							{
+								while( true ){
+									
+									synchronized( PlatformManagerImpl.this ){
+										
+										if ( !prevent_computer_sleep ){
+											
+											if ( prevent_sleep_thread == this ){
+												
+												prevent_sleep_thread = null;
+											}
+											
+											break;
+										}
+									}
+																		
+									try{
+										access.setThreadExecutionState( AEWin32AccessInterface.ES_SYSTEM_REQUIRED );
+
+										Thread.sleep( 30*1000 );
+										
+									}catch( Throwable e ){
+										
+										Debug.out( e );
+										
+										break;
+									}
+								}
+							}
+						};
+						
+					prevent_sleep_thread.start();
+				}
+			}
+		}
+	}
+	
+	private boolean
+	canHibernate()
+	{
+		try{
+			if ( Constants.isWindows7OrHigher ){
+				
+				int enabled = access.readWordValue( AEWin32Access.HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Power", "HibernateEnabled" );
+				
+				return( enabled != 0 );
+				
+			}else{
+				Process p = Runtime.getRuntime().exec(
+					new String[]{
+						"cmd.exe",
+						"/C",
+						"reg query \"HKLM\\System\\CurrentControlSet\\Control\\Session Manager\\Power\" /v Heuristics"
+						});
+							
+				LineNumberReader lnr = new LineNumberReader( new InputStreamReader( p.getInputStream()));
+				
+				while( true ){
+					
+					String	line = lnr.readLine();
+					
+					if ( line == null ){
+						
+						break;
+					}
+										
+					line = line.trim();
+					
+					if ( line.startsWith( "Heuristics" )){
+												
+						String[] bits =  line.split( "[\\s]+");
+												
+						byte[] value = ByteFormatter.decodeString( bits[2].trim());
+												
+						return(( value[6] & 0x01 ) != 0 );
+					}
+				}
+			}
+			
+			return( false );
+			
+		}catch( Throwable e ){
+						
+			return( false );
+		}
+	}
+	
+	public void
+	startup(
+		final AzureusCore		azureus_core )
+	
+		throws PlatformManagerException
+	{
+		AEDiagnostics.addEvidenceGenerator( this );
+		
+		if ( !hasCapability( PlatformManagerCapabilities.AccessExplicitVMOptions )){
+			
+			return;
+		}
+		
+		if ( COConfigurationManager.getBooleanParameter( "platform.win32.vmo.migrated", false )){
+			
+			try{
+				File local_options = checkAndGetLocalVMOptionFile();
+				
+				if ( local_options.exists()){
+					
+					File last_good = new File( local_options.getParentFile(), local_options.getName() + ".lastgood" );
+					
+					if ( 	!last_good.exists() ||
+							local_options.lastModified() > last_good.lastModified()){
+						
+						FileUtil.copyFile( local_options, last_good );
+					}
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}else{
+			
+			final int	fail_count = COConfigurationManager.getIntParameter( "platform.win32.vmo.migrated.fails", 0 );
+			
+			if ( fail_count >= 3 ){
+				
+				Debug.out( "Not attempting vmoption migration due to previous failures, please perform a full install to fix this" );
+				
+				return;
+			}
+			
+				// we need an up-to-date version of this to do the migration...
+			
+			PluginInterface pi = azureus_core.getPluginManager().getPluginInterfaceByID( "azupdater" );
+						
+			if ( pi != null && Constants.compareVersions( pi.getPluginVersion(), "1.8.15" ) >= 0 ){
+							
+				new AEThread2( "win32.vmo", true )
+				{
+					public void
+					run()
+					{
+						try{
+							String redirect = getJVMOptionRedirect();
+							
+							File[] option_files = getJVMOptionFiles();
+
+							if ( option_files.length != 2 ){
+								
+								return;
+							}
+							
+							File shared_options 		= option_files[0];
+							File old_shared_options 	= new File( shared_options.getParentFile(), shared_options.getName() + ".old" );
+							File local_options 			= option_files[1];
+
+							if ( shared_options.exists()){
+
+								String options = FileUtil.readFileAsString( shared_options, -1 );
+
+								if ( !options.contains( redirect )){
+
+										// if they're already linking somewhere then abandon
+									
+									if ( !options.contains( "-include-options" )){
+
+										if ( FileUtil.canReallyWriteToAppDirectory()){
+
+											if ( old_shared_options.exists()){
+
+												old_shared_options.delete();
+											}
+
+											if ( shared_options.renameTo( old_shared_options )){
+
+												if ( !local_options.exists()){
+
+													if ( !FileUtil.copyFile( old_shared_options, local_options )){
+
+														Debug.out( "Failed to copy " + old_shared_options + " to " + local_options );
+													}
+												}
+												
+												if ( !FileUtil.writeStringAsFile( shared_options, redirect + "\r\n" )){
+														
+													Debug.out( "Failed to write to " + shared_options );
+												}
+											}else{
+
+												Debug.out( "Rename of " + shared_options + " to " + old_shared_options + " failed" );
+											}
+										}else{
+
+												// insufficient perms
+											
+											UpdateInstaller installer = getInstaller( azureus_core );
+											
+												// retry later
+											
+											if ( installer == null ){
+												
+												return;
+											}
+											
+
+											if ( !informUpdateRequired()){
+												
+												return;
+											}
+
+											if ( old_shared_options.exists()){
+
+												installer.addRemoveAction( old_shared_options.getAbsolutePath());
+											}
+
+											installer.addMoveAction( shared_options.getAbsolutePath(), old_shared_options.getAbsolutePath());
+											
+											if ( !local_options.exists()){
+
+												installer.addResource( "local_options", new ByteArrayInputStream( options.getBytes( "UTF-8" )));
+												
+												installer.addMoveAction( "local_options", local_options.getAbsolutePath());
+											}														
+
+											installer.addResource( "redirect", new ByteArrayInputStream( ( redirect + "\r\n" ).getBytes( "UTF-8" )));
+											
+											installer.addMoveAction( "redirect", shared_options.getAbsolutePath());
+												
+											final AESemaphore sem = new AESemaphore( "vmopt" );
+											
+											final UpdateException[]	error = { null };
+											
+											installer.installNow(
+												new UpdateInstallerListener()
+												{
+													public void
+													reportProgress(
+														String		str )
+													{
+													}
+													
+													public void
+													complete()
+													{														
+														sem.release();
+													}
+													
+													public void
+													failed(
+														UpdateException	e )
+													{
+														error[0] = e;
+														
+														sem.release();
+													}
+												});
+											
+											sem.reserve();
+											
+											if ( error[0] != null ){
+												
+												throw( error[0] );
+											}
+											
+										}
+									}
+								}else{
+										// redirect in place, might be second user so migrate if needed
+
+									if ( old_shared_options.exists() && !local_options.exists()){
+
+										if ( !FileUtil.copyFile( old_shared_options, local_options )){
+
+											Debug.out( "Failed to copy " + old_shared_options + " to " + local_options );
+										}
+									}
+								}
+							}else{
+
+									// no options
+								
+								if ( FileUtil.canReallyWriteToAppDirectory()){
+									
+									if ( !FileUtil.writeStringAsFile( shared_options, redirect + "\r\n" )){
+										
+										Debug.out( "Failed to write to " + shared_options );
+									}
+								}else{
+									
+										// insufficient perms
+																		
+									UpdateInstaller installer = getInstaller( azureus_core );
+								
+										// retry later
+									
+									if ( installer == null ){
+										
+										return;
+									}
+									
+									
+									if ( !informUpdateRequired()){
+										
+										return;
+									}
+
+									installer.addResource( "redirect", new ByteArrayInputStream( ( redirect + "\r\n" ).getBytes( "UTF-8" )));
+									
+									installer.addMoveAction( "redirect", shared_options.getAbsolutePath());
+										
+									final AESemaphore sem = new AESemaphore( "vmopt" );
+									
+									final UpdateException[]	error = { null };
+									
+									installer.installNow(
+										new UpdateInstallerListener()
+										{
+											public void
+											reportProgress(
+												String		str )
+											{
+											}
+											
+											public void
+											complete()
+											{
+												sem.release();
+											}
+											
+											public void
+											failed(
+												UpdateException	e )
+											{
+												error[0] = e;
+												
+												sem.release();
+											}
+										});
+									
+									sem.reserve();
+									
+									if ( error[0] != null ){
+										
+										throw( error[0] );
+									}
+								}
+							}
+							
+							COConfigurationManager.setParameter( "platform.win32.vmo.migrated", true );
+														
+						}catch( Throwable e ){
+							
+							COConfigurationManager.setParameter( "platform.win32.vmo.migrated.fails", fail_count + 1 );
+							
+							Debug.out( "vmoption migration failed", e );
+						}
+					}
+				}.start();
+			}
+		}
+	}
+	
+	private UpdateInstaller
+	getInstaller(
+		AzureusCore		azureus_core )
+	
+		throws Exception
+	{
+			// we don't want our update to interfere with the normal update process so
+			// hang around until it completes
+		
+		PluginInterface pi = azureus_core.getPluginManager().getDefaultPluginInterface();
+		
+		UpdateManager update_manager = pi.getUpdateManager();
+		
+		final List<UpdateCheckInstance>	l_instances = new ArrayList<UpdateCheckInstance>();
+		
+		update_manager.addListener( 
+			new UpdateManagerListener()
+			{
+				public void
+				checkInstanceCreated(
+					UpdateCheckInstance	instance )
+				{
+					synchronized( l_instances ){
+						
+						l_instances.add( instance );
+					}
+				}
+			});
+		
+		UpdateCheckInstance[] instances = update_manager.getCheckInstances();
+		
+		l_instances.addAll( Arrays.asList( instances ));
+		
+		long start = SystemTime.getMonotonousTime();
+		
+		while( true ){
+			
+			if ( SystemTime.getMonotonousTime() - start >= 5*60*1000 ){
+				
+				break;
+			}
+			
+			try{
+				Thread.sleep(5000);
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+				
+				return( null );
+			}
+			
+			if ( l_instances.size() > 0 ){
+			
+				boolean	all_done = true;
+				
+				for ( UpdateCheckInstance instance: l_instances ){
+					
+					if ( !instance.isCompleteOrCancelled()){
+						
+						all_done = false;
+						
+						break;
+					}
+				}
+				
+				if ( all_done ){
+					
+					break;
+				}
+			}
+		}
+		
+		if ( update_manager.getInstallers().length > 0 ){
+			
+			return( null );
+		}
+		
+		UpdateInstaller installer = pi.getUpdateManager().createInstaller();
+	
+		return( installer );
+	}
+	
+	private boolean
+	informUpdateRequired()
+	{
+		UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+
+		long res = ui_manager.showMessageBox(
+				"update.now.title",
+				"update.now.desc",
+				UIManagerEvent.MT_OK | UIManagerEvent.MT_CANCEL );
+		
+		return( res == UIManagerEvent.MT_OK );
+	}
+	
+	public void
+	shutdown(
+		int			type )
+	
+		throws PlatformManagerException
+	{	
+		String windir = System.getenv( "windir" );
+		
+		boolean vista_or_higher = Constants.isWindowsVistaOrHigher;
+		
+		try{
+			if ( type == SD_SLEEP ){
+				
+				Runtime.getRuntime().exec(
+					new String[]{
+						windir + "\\system32\\rundll32.exe",
+						"powrprof.dll,SetSuspendState"	
+					});
+				
+			}else if ( type == SD_HIBERNATE ){
+				
+				if ( vista_or_higher ){
+					
+					Runtime.getRuntime().exec(
+							new String[]{
+								"shutdown",
+								"-h"	
+							});
+					
+				}else{
+					
+					Runtime.getRuntime().exec(
+							new String[]{
+								windir + "system32\\rundll32.exe",
+								"powrprof.dll,SetSuspendState Hibernate"	
+							});
+				}
+			}else if ( type == SD_SHUTDOWN ){
+				
+				Runtime.getRuntime().exec(
+						new String[]{
+							"shutdown",
+							"-s"	
+						});
+			}else{
+				
+				throw new PlatformManagerException("Unsupported capability called on platform manager");
+			}
+			
+		}catch( PlatformManagerException e ){
+			
+			throw( e );
+			
+		}catch( Throwable e ){
+			
+			throw( new PlatformManagerException( "shutdown failed", e ));
+		}
+	}
+	
 	public String
 	getApplicationCommandLine()
 	{
@@ -470,6 +1339,8 @@ PlatformManagerImpl
 			checkExeKey( exe_loc );
 		}
 		
+		String app_path = SystemProperties.getApplicationPath();
+		
 		try{
 				// always trigger magnet reg here if not owned so old users get it...
 					
@@ -492,6 +1363,16 @@ PlatformManagerImpl
 			Debug.printStackTrace(e);
 		}
 	
+		try{
+				// always trigger magnet reg here if not owned so old users get it...
+				
+			registerBC();
+			
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+		}
+	
 		if ( isAdditionalFileTypeRegistered( OLD_MAIN_ASS0C, ".torrent" )){
 			
 			unregisterAdditionalFileType( OLD_MAIN_ASS0C, ".torrent" );
@@ -538,22 +1419,38 @@ PlatformManagerImpl
 		File		exe )
 	{
 		String	exe_str = exe.getAbsolutePath();
+		String path_str = exe.getParent();
 		
-		String str = null;
+		String execReg = null;
+		String parentReg = null;
 		
 		try{
-			str = access.readStringValue( hkey, "software\\" + app_name, "exec" );
+			execReg = access.readStringValue( hkey, "software\\" + app_name, "exec" );
 
 		}catch( Throwable e ){
 		}
-		
+
 		try{
-			if ( str == null || !str.equals( exe_str )){
+			parentReg = access.readStringValue( hkey, "software\\" + app_name, "");
+
+		}catch( Throwable e ){
+		}
+
+		try{
+			if ( execReg == null || !execReg.equals( exe_str )){
 				
 				access.writeStringValue( hkey, "software\\" + app_name,	"exec",	exe_str );
 			}
 		}catch( Throwable e ){
 		}
+
+		try{
+			if ( parentReg == null || !parentReg.equals( path_str )){
+				
+				access.writeStringValue( hkey, "software\\" + app_name,	"",	path_str );
+			}
+		}catch( Throwable e ){
+		}
 	}
 	
 	public boolean
@@ -784,6 +1681,36 @@ PlatformManagerImpl
 		}
 	}
 	
+	protected void
+	registerBC()
+	{
+		try{
+			registerAdditionalFileType( 
+				"BC", 
+				"BC URI", 
+				".bcuri", 
+				"application/x-bc-uri",
+				true );
+			
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+		}
+		
+		try{
+			registerAdditionalFileType( 
+				"BCTP", 
+				"BCTP URI", 
+				".bctpuri", 
+				"application/x-bctp-uri",
+				true );
+			
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace(e);
+		}
+	}
+	
 	public void
 	registerAdditionalFileType(
 		String		name,				// e.g. "Azureus"
@@ -1128,6 +2055,13 @@ PlatformManagerImpl
 		}
 	}
 
+	public int
+	getMaxOpenFiles()
+	
+		throws PlatformManagerException
+	{
+	    throw new PlatformManagerException("Unsupported capability called on platform manager");		
+	}
 	
     /**
      * {@inheritDoc}
@@ -1138,6 +2072,18 @@ PlatformManagerImpl
     {
         return capabilitySet.contains(capability);
     }
+    
+    private void
+    checkCapability(
+    	PlatformManagerCapabilities capability )
+    
+    	throws PlatformManagerException
+    {
+    	if ( !hasCapability(capability)){
+    		
+    		throw( new PlatformManagerException( "Capability " + capability + " not supported" ));
+    	}
+    }
 
     /**
      * Does nothing
@@ -1146,12 +2092,13 @@ PlatformManagerImpl
     {
     }
     
-	public void
+	public int
 	eventOccurred(
 		int		type )
 	{
-		int	t_type;
-		
+		int	t_type 	= -1;
+		int	res 	= -1;
+
 		if ( type == AEWin32AccessListener.ET_SHUTDOWN ){
 			
 			t_type = PlatformManagerListener.ET_SHUTDOWN;
@@ -1160,21 +2107,26 @@ PlatformManagerImpl
 			
 			t_type = PlatformManagerListener.ET_SUSPEND;
 				
+			if ( prevent_computer_sleep ){
+				
+				res = AEWin32AccessListener.RT_SUSPEND_DENY;
+			}
 		}else if ( type == AEWin32AccessListener.ET_RESUME ){
 			
 			t_type = PlatformManagerListener.ET_RESUME;
-				
-		}else{
-			
-			return;
 		}
-		
+				
 		if ( t_type != -1 ){
 			
 			for (int i=0;i<listeners.size();i++){
 				
 				try{
-					((PlatformManagerListener)listeners.get(i)).eventOccurred( t_type );
+					int my_res = ((PlatformManagerListener)listeners.get(i)).eventOccurred( t_type );
+					
+					if ( my_res == PlatformManagerListener.RT_SUSPEND_DENY ){
+						
+						res = AEWin32AccessListener.RT_SUSPEND_DENY;
+					}
 					
 				}catch( Throwable e ){
 					
@@ -1182,6 +2134,8 @@ PlatformManagerImpl
 				}
 			}
 		}
+		
+		return( res );
 	}
 	
     public void
@@ -1198,96 +2152,44 @@ PlatformManagerImpl
     	listeners.remove( listener );
     }
 
-  /**
-   * Gets an ID to identify this computer to azureus.  Used when the computer
-   * has muliple user accounts and we need a way to not duplicate efforts
-   * (An example would be to skip downloading something another user on the
-   * computer has already downloaded)
-   * <p>
-   * The default for the ID is the AZID of the first user profile.
-	 * 
-	 * @return ID
-	 */
-	public String getAzComputerID() {
-		boolean needWrite = false;
-		String cid = null;
-		try {
-			cid = access.readStringValue(AEWin32Access.HKEY_LOCAL_MACHINE,
-					"SOFTWARE\\" + app_name, "CID");
-		} catch (Exception e) {
-		}
-
-		if (cid == null || cid.length() == 0) {
-			needWrite = true;
-			try {
-				File commonPath = new File(access.getCommonAppData(),app_name);
-				if (commonPath.isDirectory()) {
-					File fCID = new File(commonPath, "azCID.txt");
-					if (fCID.exists()) {
-						cid = FileUtil.readFileAsString(fCID, 255, "utf8");
-					}
-				}
-			} catch (Exception e) {
-			}
-		}
-
-		if (cid == null || cid.length() == 0) {
-			needWrite = true;
-			cid = COConfigurationManager.getStringParameter("ID");
-		}
-
-		if (cid == null || cid.length() == 0) {
-			needWrite = true;
-			cid = RandomUtils.generateRandomAlphanumerics(20);
-		}
-
-		if (needWrite) {
-			setAzComputerID(cid);
-		}
-		return cid;
+	
+	public void requestUserAttention(int type, Object data) throws PlatformManagerException {
+		throw new PlatformManagerException("Unsupported capability called on platform manager");
 	}
-
-	/**
-	 * @param cid
-	 */
-	private void setAzComputerID(String cid) {
-		try {
-			access.writeStringValue(AEWin32Access.HKEY_LOCAL_MACHINE,
-					"SOFTWARE\\" + app_name, "CID", cid);
-		} catch (Exception e) {
-			Debug.out("Could not write CID: " + e.getMessage());
-		}
-
-		try {
-			String sCommonAppData = access.getCommonAppData();
-			if (sCommonAppData != null && sCommonAppData.length() > 0) {
-				File commonPath = new File(sCommonAppData);
-				if (commonPath.isDirectory()) {
-					commonPath = new File(commonPath, app_name);
-					FileUtil.mkdirs(commonPath);
-
-					File fCID = new File(commonPath, "azCID.txt");
-					FileUtil.writeBytesAsFile(fCID.getAbsolutePath(),
-							cid.getBytes("utf8"));
+	
+	public void
+	generate(
+		IndentWriter		writer )
+	{
+		writer.println( "Platform" );
+		
+		try{
+			writer.indent();
+		
+			try{
+				String[] options = getExplicitVMOptions();
+				
+				writer.println( "VM Options" );
+				
+				try{
+					writer.indent();
+					
+					for ( String option: options ){
+						
+						writer.println( option );
+					}
+				}finally{
+					
+					writer.exdent();
 				}
+			}catch( Throwable e ){
+				
+				writer.println( "VM options not available: " + Debug.getNestedExceptionMessage(e));
 			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-	
-	public static void main(String[] args) {
-		try {
-			PlatformManagerImpl impl = new PlatformManagerImpl();
-			System.out.println(impl.getAzComputerID());
-		} catch (PlatformManagerException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
+			
+		}finally{
+			
+			writer.exdent();
 		}
-		
-	}
-
-	public void requestUserAttention(int type, Object data) throws PlatformManagerException {
-		throw new PlatformManagerException("Unsupported capability called on platform manager");
 	}
 }
diff --git a/org/gudy/azureus2/platform/win32/PlatformManagerUpdateChecker.java b/org/gudy/azureus2/platform/win32/PlatformManagerUpdateChecker.java
index 4640486..f75be28 100644
--- a/org/gudy/azureus2/platform/win32/PlatformManagerUpdateChecker.java
+++ b/org/gudy/azureus2/platform/win32/PlatformManagerUpdateChecker.java
@@ -240,7 +240,17 @@ PlatformManagerUpdateChecker
 								installUpdate( checker, update, downloader, data );
 									
 								return( true );
-							}							
+							}	
+							
+							public void
+							failed(
+								ResourceDownloader			downloader,
+								ResourceDownloaderException e )
+							{
+								Debug.out( downloader.getName() + " failed", e );
+								
+								update.complete( false );
+							}
 						});
 			}
 		}catch( Throwable e ){
@@ -304,9 +314,15 @@ PlatformManagerUpdateChecker
 					}
 				}
 			}
+			
+			update.complete( true );
+			
 		} catch (Throwable e) {
 
+			update.complete( false );
+			
 			rd.reportActivity("Update install failed:" + e.getMessage());
+			
 		}finally{
 			
 			if ( zip != null ){
diff --git a/org/gudy/azureus2/platform/win32/access/AEWin32Access.java b/org/gudy/azureus2/platform/win32/access/AEWin32Access.java
index 5b13035..275ad7c 100644
--- a/org/gudy/azureus2/platform/win32/access/AEWin32Access.java
+++ b/org/gudy/azureus2/platform/win32/access/AEWin32Access.java
@@ -24,6 +24,7 @@ package org.gudy.azureus2.platform.win32.access;
 
 import java.io.File;
 import java.net.InetAddress;
+import java.util.Map;
 
 import org.gudy.azureus2.platform.PlatformManagerPingCallback;
 
@@ -233,6 +234,25 @@ AEWin32Access
 	 *
 	 * @since 4.1.0.5
 	 */
-	public File[] 
-		getUSBDrives();
+	public Map<File, Map> 
+		getAllDrives();
+
+ 	public boolean isUSBDrive(Map driveInfo);
+
+	/**
+	 * @return
+	 * @throws AEWin32AccessException
+	 *
+	 * @since 4.5.0.3
+	 */
+	String getLocalAppData() throws AEWin32AccessException;
+	
+	/**
+	 * @since 4713
+	 * @param state
+	 */
+	
+	public void
+	setThreadExecutionState(
+		int		state );
 }
diff --git a/org/gudy/azureus2/platform/win32/access/AEWin32AccessListener.java b/org/gudy/azureus2/platform/win32/access/AEWin32AccessListener.java
index 87430ae..3b8797e 100644
--- a/org/gudy/azureus2/platform/win32/access/AEWin32AccessListener.java
+++ b/org/gudy/azureus2/platform/win32/access/AEWin32AccessListener.java
@@ -29,7 +29,9 @@ AEWin32AccessListener
 	public static final int ET_SUSPEND		= 0x0002;
 	public static final int ET_RESUME		= 0x0003;
 	
-	public void
+	public static final int RT_SUSPEND_DENY	= 0x0001;
+	
+	public int
 	eventOccurred(
 		int		type );
 }
diff --git a/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessImpl.java b/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessImpl.java
index 57654d6..44309ee 100644
--- a/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessImpl.java
+++ b/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessImpl.java
@@ -34,6 +34,7 @@ import java.util.*;
 
 // don't use any core stuff in here as we need this access stub to be able to run in isolation
 
+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.platform.PlatformManagerPingCallback;
@@ -107,13 +108,24 @@ AEWin32AccessImpl
 			}
 		}
 		
+		int	result = -1;
+		
 		if ( type != -1 ){
 					
 			for (int i=0;i<listeners.size();i++){
 				
 				try{
-					((AEWin32AccessListener)listeners.get(i)).eventOccurred( type );
+					int temp = ((AEWin32AccessListener)listeners.get(i)).eventOccurred( type );
 					
+					if ( temp != result ){
+						
+						if ( result != -1 ){
+							
+							Debug.out( "Incompatible results received: " + result + "/" + temp );
+						}
+						
+						result 	= temp;
+					}
 				}catch( Throwable e ){
 					
 					e.printStackTrace();
@@ -121,7 +133,19 @@ AEWin32AccessImpl
 			}
 		}
 		
-		return( -1 );
+		if ( result == AEWin32AccessListener.RT_SUSPEND_DENY ){
+			
+			if (( param2 & 0x0001 ) != 0 ){
+			
+				return( AEWin32AccessInterface.BROADCAST_QUERY_DENY );
+				
+			}else{
+				
+				Debug.out( "Ignoring suspend deny request as not permitted" );
+			}
+		}
+		
+		return( result );
 	}
 	
 	public long
@@ -248,6 +272,21 @@ AEWin32AccessImpl
 	}
 	
 	public String
+	getLocalAppData()
+	
+		throws AEWin32AccessException
+	{
+		String	app_data_key	= "software\\microsoft\\windows\\currentversion\\explorer\\shell folders";
+		String	app_data_name 	= "Local AppData";
+		
+		return(	readStringValue(
+					HKEY_CURRENT_USER,
+					app_data_key,
+					app_data_name ));
+
+	}
+	
+	public String
 	getUserDocumentsDir()
 	
 		throws AEWin32AccessException
@@ -557,38 +596,78 @@ AEWin32AccessImpl
 		}  	
 	}
     
-    public File[] getUSBDrives() {
+    public Map<File, Map> getAllDrives() {
     	
-    	ArrayList<File> listUSB = new ArrayList<File>();
-    	try {
-				List availableDrives = AEWin32AccessInterface.getAvailableDrives();
-				if (availableDrives != null) {
-					for (Object object : availableDrives) {
-						File f = (File) object;
-
-						Map driveInfo = AEWin32AccessInterface.getDriveInfo(f.getPath().charAt(0));
-						if (driveInfo != null) {
-							boolean removeable = MapUtils.getMapBoolean(driveInfo, "Removable", false);
-							// values GetDriveType
-							long driveType = MapUtils.getMapLong(driveInfo, "DriveType", 0);
-							// values STORAGE_BUS_TYPE
-							long busType = MapUtils.getMapLong(driveInfo, "BusType", 0);
-							// values MEDIA_TYPE
-							long mediaType = MapUtils.getMapLong(driveInfo, "MediaType", 0);
-
-							if (removeable && driveType == 2 && busType == 7 && mediaType == 11) {
-								listUSB.add(f);
-							}
+    	// gah, see http://pluscs.vuze.com/tickets/23804?col=1101604&page=1 we sometimes get crashes here
+    	
+    	String	state_key = "awein32.getalldrives.state.2";
+    	
+    	int state = COConfigurationManager.getIntParameter( state_key, 0 );
+    	
+    	if ( state == 1 ){
+    		
+    		Debug.out( "Not enumerating system drives as it crashed last time we tried" );
+    		
+    		return( new HashMap<File,Map>());
+    	}
+    	
+    	try{
+    		COConfigurationManager.setParameter( state_key, 1 );
+    	
+    		COConfigurationManager.save();
+    		
+	    	Map<File, Map> mapDrives = new HashMap<File, Map>();
+	    	try {
+					List availableDrives = AEWin32AccessInterface.getAvailableDrives();
+					if (availableDrives != null) {
+						for (Object object : availableDrives) {
+							File f = (File) object;
+							Map driveInfo = AEWin32AccessInterface.getDriveInfo(f.getPath().charAt(0));
+							boolean isWritableUSB = AEWin32Manager.getAccessor(false).isUSBDrive(driveInfo);
+							driveInfo.put("isWritableUSB", isWritableUSB);
+							mapDrives.put(f, driveInfo);
 						}
 					}
+					
+					return mapDrives;
+	    	} catch (UnsatisfiedLinkError ue) {
+	    		Debug.outNoStack("Old aereg.dll");
+				} catch (Throwable e) {
+					Debug.out(e);
 				}
-				
-				return listUSB.toArray(new File[0]);
-    	} catch (UnsatisfiedLinkError ue) {
-    		Debug.outNoStack("Old aereg.dll");
-			} catch (Throwable e) {
-				Debug.out(e);
-			}
-			return new File[0];
+				return Collections.emptyMap();
+    	}finally{
+    		
+    		COConfigurationManager.setParameter( state_key, 2 );
+    		
+    		COConfigurationManager.setDirty();
+    	}
     }
+    
+  public boolean isUSBDrive(Map driveInfo) {
+  	if (driveInfo == null) {
+  		return false;
+  	}
+  	boolean removeable = MapUtils.getMapBoolean(driveInfo, "Removable", false);
+  	// values GetDriveType: {UNKNOWN, NO_ROOT_DIR, REMOVABLE, FIXED, REMOTE, CDROM, RAMDISK}
+  	long driveType = MapUtils.getMapLong(driveInfo, "DriveType", 0);
+  	// STORAGE_BUS_TYPE: http://msdn.microsoft.com/en-us/library/aa363465%28VS.85%29.aspx
+  	long busType = MapUtils.getMapLong(driveInfo, "BusType", 0);
+  	// MEDIA_TYPE: http://msdn.microsoft.com/en-us/library/aa365231%28VS.85%29.aspx
+  	long mediaType = MapUtils.getMapLong(driveInfo, "MediaType", -1);
+  
+  	if (removeable && driveType == 2 && busType == 7
+  			&& (mediaType == 11 || mediaType == -1)) {
+  		return true;
+  	}
+  	
+  	return false;
+  }
+  
+	public void
+	setThreadExecutionState(
+		int		state )
+	{
+		AEWin32AccessInterface.setThreadExecutionState( state );
+	}
 }
diff --git a/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessInterface.java b/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessInterface.java
index c93aa7f..6f3f2f0 100644
--- a/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessInterface.java
+++ b/org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessInterface.java
@@ -49,13 +49,26 @@ AEWin32AccessInterface
 	public static final int	PBT_APMSUSPEND          = 0x0004;
 	public static final int	PBT_APMRESUMESUSPEND    = 0x0007;
 	
+	public static final long BROADCAST_QUERY_DENY		= 0x424D5144L;
+		
+
+	public static final int  ES_SYSTEM_REQUIRED   	= 0x00000001;
+	public static final int  ES_DISPLAY_REQUIRED  	= 0x00000002;
+	public static final int  ES_USER_PRESENT      	= 0x00000004;
+	public static final int  ES_AWAYMODE_REQUIRED 	= 0x00000040;
+	public static final int  ES_CONTINUOUS        	= 0x80000000;	
+	
 	private static boolean						enabled;
 	private static boolean						enabled_set;
 	
 	private static AEWin32AccessCallback		cb;
 	
 	static{
-		System.loadLibrary( PlatformManagerImpl.DLL_NAME );
+		try {
+			System.loadLibrary( PlatformManagerImpl.DLL_NAME );
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
 	}
 	
 	protected static boolean
@@ -258,4 +271,7 @@ AEWin32AccessInterface
 	public static native Map
 	getDriveInfo(char driveLetter)
 		throws AEWin32AccessExceptionImpl;
+	
+	public static native int 
+	setThreadExecutionState(int esFLAGS);
 }
diff --git a/org/gudy/azureus2/platform/win32/access/impl/StdAfx.cpp b/org/gudy/azureus2/platform/win32/access/impl/StdAfx.cpp
deleted file mode 100644
index 02186db..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/StdAfx.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-// stdafx.cpp : source file that includes just the standard includes
-//	aereg.pch will be the pre-compiled header
-//	stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
diff --git a/org/gudy/azureus2/platform/win32/access/impl/StdAfx.h b/org/gudy/azureus2/platform/win32/access/impl/StdAfx.h
deleted file mode 100644
index 92ecdb3..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/StdAfx.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// stdafx.h : include file for standard system include files,
-//  or project specific include files that are used frequently, but
-//      are changed infrequently
-//
-
-#if !defined(AFX_STDAFX_H__EB4D9027_DB05_4618_9310_821A191B789B__INCLUDED_)
-#define AFX_STDAFX_H__EB4D9027_DB05_4618_9310_821A191B789B__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-
-// Insert your headers here
-#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
-
-#include <windows.h>
-
-// TODO: reference additional headers your program requires here
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__EB4D9027_DB05_4618_9310_821A191B789B__INCLUDED_)
diff --git a/org/gudy/azureus2/platform/win32/access/impl/Test.java b/org/gudy/azureus2/platform/win32/access/impl/Test.java
deleted file mode 100644
index 860ecb4..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/Test.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Created on Apr 16, 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 org.gudy.azureus2.platform.win32.access.impl;
-
-/**
- * @author parg
- *
- */
-
-import java.io.File;
-import java.net.InetAddress;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.gudy.azureus2.platform.PlatformManagerPingCallback;
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String[]	args )
-	{
-		try{
-			
-			List availableDrives = AEWin32AccessInterface.getAvailableDrives();
-			
-			for (Object object : availableDrives) {
-				File f = (File) object;
-				System.out.println(f.getAbsolutePath());
-
-				Map driveInfo = AEWin32AccessInterface.getDriveInfo(f.getPath().charAt(0));
-				for (Iterator iter = driveInfo.keySet().iterator(); iter.hasNext();) {
-					Object key = (Object) iter.next();
-					Object val = driveInfo.get(key);
-					System.out.println(key + ": " + val);
-				}
-				
-			}
-			
-			if (true)
-				return;
-			/*
-			AEWin32Access access = AEWin32Manager.getAccessor();
-			
-			String	app_data = access.getUserAppData();
-			
-			System.out.println( "AppData = " + app_data );
-
-			String az_home = access.getApplicationInstallDir("azureus");
-			
-			File	az_exe = new File( az_home + File.separator + "Azureus.exe" ).getAbsoluteFile();
-			
-			if ( az_exe.exists()){
-				
-				//<Nolar> 	WriteRegStr HKCR ".torrent" "" "BitTorrent"
-				//<Nolar> 	WriteRegStr HKCR "BitTorrent" "" "Bittorrent File"
-				//<Nolar> 	WriteRegStr HKCR "BitTorrent\shell" "" "open"
-				//<Nolar> 	WriteRegStr HKCR "BitTorrent\DefaultIcon" "" $INSTDIR\Azureus.exe,1
-				//<Nolar>   	WriteRegStr HKCR "BitTorrent\shell\open\command" "" '"$INSTDIR\Azureus.exe" "%1"'
-				//<Nolar>   	WriteRegStr HKCR "BitTorrent\Content Type" "" "application/x-bittorrent"
-				
-				System.out.println( "current = " + 
-						access.readStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent\\shell\\open\\command",
-						"" ));
-				
-				access.deleteKey( 	AEWin32Access.HKEY_CLASSES_ROOT,
-									".torrent" );
-			
-				access.deleteKey( 	AEWin32Access.HKEY_CLASSES_ROOT,
-									"BitTorrent",
-									true );
-			
-				access.writeStringValue( 	AEWin32Access.HKEY_CLASSES_ROOT,
-											".torrent",
-											"",
-											"BitTorrent" );
-				
-				access.writeStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent",
-						"",
-						"Bittorrent File" );
-
-				access.writeStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent\\shell",
-						"",
-						"open" );
-				
-				access.writeStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent\\DefaultIcon",
-						"",
-						az_exe.toString() + ",1" );
-				
-				access.writeStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent\\shell\\open\\command",
-						"",
-						"\"" + az_exe.toString() + "\" \"%1\"" );
-				
-				access.writeStringValue( 	
-						AEWin32Access.HKEY_CLASSES_ROOT,
-						"BitTorrent\\Content Type" ,
-						"",
-						"application/x-bittorrent" );
-				
-			}else{
-				
-				System.out.println( "can't find Azureus.exe");
-			}
-		*/
-			
-			//AEWin32AccessInterface.copyPermission( "C:\\temp\\fred", "C:\\temp\\bill" );
-			
-			/*
-			AEWin32AccessImpl.getSingleton( false ).traceRoute(
-					InetAddress.getByName( "192.168.1.143" ),
-					InetAddress.getByName( "www.google.com"),
-					new PlatformManagerPingCallback()
-					{
-						public boolean
-						reportNode(
-							int				distance,
-							InetAddress		address,
-							int				millis )
-						{
-							System.out.println( distance + ": " + address + " - " + millis );
-							
-							return( true );
-						}
-					});
-			*/
-			
-			// AEWin32AccessInterface.ping( "www.google.com" );
-			
-			int res = AEWin32AccessImpl.getSingleton( false ).shellExecuteAndWait(
-				"c:\\temp\\3110\\Vuze_3.1.1.0_windows.exe",
-				"-VFORCE_LAUNCH=1" );
-			
-			System.out.println( "res=" + res );
-			
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-}
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aedevice.cpp b/org/gudy/azureus2/platform/win32/access/impl/aedevice.cpp
deleted file mode 100644
index 02b30a5..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aedevice.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-
-#include "stdafx.h"
-
-#include <windows.h>
-#include <winioctl.h>
-#include <stdio.h>
-#include "org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h"
-
-BOOL GetDriveGeometry(HANDLE hDevice, DISK_GEOMETRY *pdg)
-{
-	BOOL bResult;                 // results flag
-	DWORD junk;                   // discard results
-
-	bResult = DeviceIoControl(hDevice,  // device to be queried
-		IOCTL_DISK_GET_DRIVE_GEOMETRY,  // operation to perform
-		NULL, 0, // no input buffer
-		pdg, sizeof(*pdg),     // output buffer
-		&junk,                 // # bytes returned
-		(LPOVERLAPPED) NULL);  // synchronous I/O
-
-	return (bResult);
-}
-BOOL GetStorageProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR *p)
-{
-	DWORD junk;                   // discard results
-
-	STORAGE_PROPERTY_QUERY Query;   // input param for query
-
-	// specify the query type
-	Query.PropertyId = StorageDeviceProperty;
-	Query.QueryType = PropertyStandardQuery;
-
-
-	BOOL res = DeviceIoControl(hDevice,                     // device handle
-		IOCTL_STORAGE_QUERY_PROPERTY,             // info of device property
-		&Query, sizeof(STORAGE_PROPERTY_QUERY),  // input data buffer
-		*p, (*p)->Size,               // output data buffer
-		&junk,                           // out's length
-		(LPOVERLAPPED)NULL);
-
-	return (res);
-}
-
-JNIEXPORT jobject JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getAvailableDrives
-(JNIEnv *env, jclass cla)
-{
-	DISK_GEOMETRY pdg;            // disk drive geometry structure
-	BOOL bResult;                 // generic results flag
-	ULONGLONG DiskSize;           // size of the drive, in bytes
-
-	HANDLE hDevice;
-
-	// create List
-	jclass clsArrayList = env->FindClass("java/util/ArrayList");
-	jmethodID constArrayList = env->GetMethodID(clsArrayList, "<init>", "()V");
-	jobject arrayList = env->NewObject(clsArrayList, constArrayList, "");
-	jmethodID methAdd = env->GetMethodID(clsArrayList, "add", "(Ljava/lang/Object;)Z");
-
-
-	// each bit returned is one drive, starting with "A:"
-	DWORD dwLogicalDrives = GetLogicalDrives();
-
-	for ( int nDrive = 0; nDrive<32; nDrive++ )
-	{
-		if ( (dwLogicalDrives & (1 << nDrive)) == 0 ) {
-			continue;
-		}
-
-		// Do an aditional check by using GetDriveGeometry.  If it fails, then there's
-		// no "disk" in the drive
-
-		WCHAR drive[100];
-
-		wsprintfW(drive, L"\\\\.\\%C:", 'a' + nDrive);
-		hDevice = CreateFileW((LPCWSTR) drive,  // drive to open
-			0,                // no access to the drive
-			FILE_SHARE_READ | // share mode
-			FILE_SHARE_WRITE,
-			NULL,             // default security attributes
-			OPEN_EXISTING,    // disposition
-			0,                // file attributes
-			NULL);            // do not copy file attributes
-
-		char drive2[4];
-		wsprintfA(drive2, "%C:\\", 'a' + nDrive);
-
-		if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-		{
-			continue;
-		}
-
-
-		bResult = GetDriveGeometry (hDevice, &pdg);
-
-		if (bResult)
-		{
-			// Create File
-			jclass cls = env->FindClass("java/io/File");
-			jmethodID constructor = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;)V");
-			jobject object = env->NewObject(cls, constructor, env->NewStringUTF(drive2));
-
-			// add to list
-
-			env->CallBooleanMethod( arrayList, methAdd, object );
-		}
-
-		CloseHandle(hDevice);
-	}
-	return arrayList;
-}
-
-void addToMap(JNIEnv *env, jobject hashMap, jmethodID methPut, jclass clsLong, jmethodID longInit, char *key, jlong val) {
-	jobject longObj = env->NewObject(clsLong, longInit, val);
-	env->CallObjectMethod(hashMap, methPut, env->NewStringUTF(key), longObj);
-}
-
-void addToMap(JNIEnv *env, jobject hashMap, jmethodID methPut, jclass clsLong, jmethodID longInit, char *key, char *val) {
-	env->CallObjectMethod(hashMap, methPut, env->NewStringUTF(key), env->NewStringUTF(val));
-}
-
-JNIEXPORT jobject JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getDriveInfo
-(JNIEnv *env, jclass cla, jchar driveLetter)
-{
-	jclass clsHashMap = env->FindClass("java/util/HashMap");
-	jmethodID constHashMap = env->GetMethodID(clsHashMap, "<init>", "()V");
-	jobject hashMap = env->NewObject(clsHashMap, constHashMap, "");
-	jmethodID methPut = env->GetMethodID(clsHashMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-
-	jclass clsLong = env->FindClass("java/lang/Long");
-	jmethodID longInit = env->GetMethodID(clsLong, "<init>", "(J)V");
-
-	DISK_GEOMETRY pdg;            // disk drive geometry structure
-	BOOL bResult;                 // generic results flag
-	ULONGLONG DiskSize;           // size of the drive, in bytes
-
-	HANDLE hDevice;
-
-
-	WCHAR drive[100];
-
-	wsprintf(drive, L"\\\\.\\%C:", driveLetter);
-	hDevice = CreateFile((LPCWSTR) drive,  // drive to open
-		0,                // no access to the drive
-		FILE_SHARE_READ | // share mode
-		FILE_SHARE_WRITE, 
-		NULL,             // default security attributes
-		OPEN_EXISTING,    // disposition
-		0,                // file attributes
-		NULL);            // do not copy file attributes
-
-	WCHAR drive2[4];
-	wsprintf(drive2, L"%C:\\", driveLetter);
-	DWORD uType = GetDriveType(drive2);
-
-
-	addToMap(env, hashMap, methPut, clsLong, longInit, "DriveType", (jlong) uType);
-
-	if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
-	{
-		return hashMap;
-	}
-
-
-	bResult = GetDriveGeometry (hDevice, &pdg);
-
-	if (bResult) 
-	{
-		ULONG diskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
-			(ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
-		addToMap(env, hashMap, methPut, clsLong, longInit, "MediaType", (jlong) pdg.MediaType);
-		addToMap(env, hashMap, methPut, clsLong, longInit, "DiskSize", (jlong) diskSize);
-	}
-
-	char OutBuf[1024] = {0};  // good enough, usually about 100 bytes
-	PSTORAGE_DEVICE_DESCRIPTOR pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)OutBuf;
-	pDevDesc->Size = sizeof(OutBuf);
-
-	bResult = GetStorageProperty(hDevice, &pDevDesc);
-
-	if (bResult) {
-		addToMap(env, hashMap, methPut, clsLong, longInit, "BusType", (jlong) pDevDesc->BusType);
-		addToMap(env, hashMap, methPut, clsLong, longInit, "DeviceType", (jlong) pDevDesc->DeviceType);
-		addToMap(env, hashMap, methPut, clsLong, longInit, "Removable", (jlong) pDevDesc->RemovableMedia);
-
-		if (pDevDesc->VendorIdOffset != 0) {
-			addToMap(env, hashMap, methPut, clsLong, longInit, "VendorID", &OutBuf[pDevDesc->VendorIdOffset]);
-		}
-		if (pDevDesc->ProductIdOffset != 0) {
-			addToMap(env, hashMap, methPut, clsLong, longInit, "ProductID", &OutBuf[pDevDesc->ProductIdOffset]);
-		}
-
-	}
-
-	STORAGE_BUS_TYPE t;
-
-	CloseHandle(hDevice);
-	return hashMap;
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aenet.cpp b/org/gudy/azureus2/platform/win32/access/impl/aenet.cpp
deleted file mode 100644
index 9e67d60..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aenet.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- * Created on 1 Nov 2006
- * Created by Paul Gardner
- * 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.
- *
- */
-
-
-#include "stdafx.h"
-
-#include "stdio.h"
-#include "stdlib.h"
-#include "windows.h"
-#include "time.h"
-#include "winsock2.h"
-#include "WS2TCPIP.H"
-
-#include "aereg.h"
-#include "aenet.h"
-
-#include "org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h"
-
-
-// IP	ftp://ftp.rfc-editor.org/in-notes/rfc791.txt
-// ICMP	ftp://ftp.rfc-editor.org/in-notes/rfc792.txt
-// UDP  ftp://ftp.rfc-editor.org/in-notes/rfc768.txt	
-
-bool winsock_started_up = false;
-
-void 
-initialiseWinsock()
-{
-	if ( !winsock_started_up ){
-
-		winsock_started_up = true;
-
-		WSADATA wdData;
-
-		WSAStartup(MAKEWORD(2, 2), &wdData);
-	}
-}
-
-
-unsigned short
-calculateChecksum(
-	unsigned short const	words[], 
-	int						num_words )
-{
-    unsigned long  sum = 0;
-
-    while (num_words-- > 0){
-    
-        sum += *(words++);
-    }
-
-    sum = (sum >> 16) + (sum & 0xFFFF);
-    sum += sum >> 16;
-
-    unsigned short result =  ((unsigned short) ~sum);
-
-	if ( result == 0 ){
-
-		result = 0xffff;
-	}
-
-	return( result );
-} 
-
-unsigned short
-calculateChecksum2(
-	unsigned short const	words1[], 
-	int						num_words1,
-	unsigned short const	words2[], 
-	int						num_words2 )
-{
-    unsigned long  sum = 0;
-
-    while (num_words1-- > 0){
-    
-        sum += *(words1++);
-    }
-
-	while (num_words2-- > 0){
-    
-        sum += *(words2++);
-    }
-
-    sum = (sum >> 16) + (sum & 0xFFFF);
-    sum += sum >> 16;
-
-    unsigned short result =  ((unsigned short) ~sum);
-
-	if ( result == 0 ){
-
-		result = 0xffff;
-	}
-
-	return( result );
-} 
-
-int 
-sendTraceRouteMessage(
-	JNIEnv*			env,
-	unsigned short	trace_id,
-	int				time_to_live,
-    unsigned int	send_sock,
-	unsigned int	recv_sock,
-	unsigned long	source_ip,
-	unsigned short	source_port,
-    unsigned long	target_ip,
-	unsigned short	target_port,
-	bool			use_udp,
-	bool			use_icmp )
-{
-		// Advice is to use UDP rather than ICMP echos. However, reality is that UDP packets can be totally dropped with no ICMP response. So send both...
-
-		// UDP
-
-	if ( use_udp ){
-
-		udp_probe_packet  udp_probe;  
-		
-		struct sockaddr_in target;
-
-		memset( &target, 0, sizeof( target ));
-    
-		target.sin_family		= AF_INET;
-		target.sin_addr.s_addr	= htonl( target_ip );
-		target.sin_port			= htons( target_port );
-
-		// printf( "Sending to %lx from %lx: ip=%d,udp=%d,tot=%d\n", target_ip, source_ip, sizeof( ip_header ), sizeof( udp_header ), sizeof( probe_packet ));
-
-		memset( &udp_probe, 0, sizeof( udp_probe ));
-
-		udp_probe.ip.ip_version		= 4;
-		udp_probe.ip.ip_header_len	= sizeof( ip_header) >> 2;
-		udp_probe.ip.tos			= 0;
-		udp_probe.ip.total_len		= htons( sizeof( udp_probe_packet ));
-		udp_probe.ip.ident			= htons( trace_id );
-		udp_probe.ip.frag_and_flags = 0;
-		udp_probe.ip.ttl			= time_to_live;
-		udp_probe.ip.protocol		= IPPROTO_UDP;
-		udp_probe.ip.checksum		= 0;
-		udp_probe.ip.source_ip		= htonl( source_ip );
-		udp_probe.ip.dest_ip		= htonl( target_ip );
-
-		udp_probe.ip.checksum = calculateChecksum((unsigned short*)&udp_probe.ip, sizeof( ip_header ) / 2 );
-
-		udp_probe.udp.source_port	= htons( source_port );
-		udp_probe.udp.dest_port		= htons( target_port  );
-		udp_probe.udp.data_len		= htons( sizeof( udp_probe_packet ) - sizeof( ip_header ));
-		udp_probe.udp.checksum		= 0;
-
-		udp_probe.data			= 1234;
-
-		pseudo_udp_header	puh;
-
-		puh.source_ip	= htonl( source_ip );
-		puh.dest_ip		= htonl( target_ip );
-		puh.zero		= 0;
-		puh.protocol	= IPPROTO_UDP;
-		puh.data_len	= htons( sizeof( udp_probe_packet ) - sizeof( ip_header ));
-
-		udp_probe.udp.checksum = calculateChecksum2( (unsigned short*)&puh, sizeof( pseudo_udp_header ) / 2, (unsigned short *)&udp_probe.udp, (sizeof( udp_probe ) - sizeof( ip_header ))/2);
-
-
-
-		
-		/*
-		char* bytes = (char *)&probe;
-
-		for (int i=0;i<sizeof( probe );i++ ){
-
-			printf( "%x\n", bytes[i] & 0xff );
-		}
-		printf( "\n" );
-		*/
-			// whereto = to, contains sin_addr and sin_family
-
-		int	num_sent = sendto(send_sock, (char *)&udp_probe, sizeof( udp_probe ), 0, (struct sockaddr *)&target, sizeof(target));
-
-		if ( num_sent == sizeof( udp_probe ) ){
-
-			if ( !use_icmp ){
-
-				return( 1 );
-			}
-
-		}else if ( num_sent == SOCKET_ERROR ){
-
-			throwException( env, "sendto", "UDP operation failed", WSAGetLastError());
-
-			return 0;
-
-		}else{
-
-			throwException( env, "sendto", "UDP incomplete packet sent" );
-
-			return 0;
-
-		}
-	}
-
-		// ICMP
-
-	if ( use_icmp ){
-
-		icmp_probe_packet  icmp_probe;  
-		
-		struct sockaddr_in target;
-
-		memset( &target, 0, sizeof( target ));
-    
-		target.sin_family		= AF_INET;
-		target.sin_addr.s_addr	= htonl( target_ip );
-		target.sin_port			= htons( target_port );
-
-		// printf( "Sending to %lx from %lx: ip=%d,udp=%d,tot=%d\n", target_ip, source_ip, sizeof( ip_header ), sizeof( udp_header ), sizeof( probe_packet ));
-
-		memset( &icmp_probe, 0, sizeof( icmp_probe ));
-
-		icmp_probe.ip.ip_version		= 4;
-		icmp_probe.ip.ip_header_len	= sizeof( ip_header) >> 2;
-		icmp_probe.ip.tos			= 0;
-		icmp_probe.ip.total_len		= htons( sizeof( icmp_probe_packet ));
-		icmp_probe.ip.ident			= htons( trace_id );
-		icmp_probe.ip.frag_and_flags = 0;
-		icmp_probe.ip.ttl			= time_to_live;
-		icmp_probe.ip.protocol		= IPPROTO_ICMP;
-		icmp_probe.ip.checksum		= 0;
-		icmp_probe.ip.source_ip		= htonl( source_ip );
-		icmp_probe.ip.dest_ip		= htonl( target_ip );
-
-		icmp_probe.ip.checksum = calculateChecksum((unsigned short*)&icmp_probe.ip, sizeof( ip_header ) / 2 );
-
-		icmp_probe.icmp.type		= ICMP_TYPE_ECHO;
-		icmp_probe.icmp.code		= 0;
-		icmp_probe.icmp.checksum	= 0;
-		icmp_probe.icmp.ident		= htons( trace_id );
-		icmp_probe.icmp.sequence	= htons( target_port );
-
-
-		icmp_probe.icmp.checksum = calculateChecksum( (unsigned short*)&icmp_probe.icmp, sizeof( icmp_echo_header ) / 2 );
-
-
-
-		/*
-		char* bytes = (char *)&probe;
-
-		for (int i=0;i<sizeof( probe );i++ ){
-
-			printf( "%x\n", bytes[i] & 0xff );
-		}
-		printf( "\n" );
-		*/
-			// whereto = to, contains sin_addr and sin_family
-
-		int	num_sent = sendto(send_sock, (char *)&icmp_probe, sizeof( icmp_probe ), 0, (struct sockaddr *)&target, sizeof(target));
-
-		if ( num_sent == sizeof( icmp_probe ) ){
-
-			return 1;
-
-		}else if ( num_sent == SOCKET_ERROR ){
-
-			throwException( env, "sendto", "UDP operation failed", WSAGetLastError());
-
-			return 0;
-
-		}else{
-
-			throwException( env, "sendto", "UDP incomplete packet sent" );
-
-			return 0;
-
-		}
-	}
-
-	throwException( env, "sendto", "no protocol selected" );
-
-	return( 0 );
-}
-
-
-int
-traceRouteReport(
-	JNIEnv		*env,
-	jobject		callback,
-	char*		msg )
-{
-	jstring	j_msg = env->NewStringUTF( msg );
-
-	if ( j_msg == NULL ){
-
-		throwException( env, "NewStringUTF", "alloc failed" );
-
-		return 0;
-	}
-
-	int	res = 0;
-
-	jclass callback_class = env->GetObjectClass( callback );
-
-	if ( callback_class == NULL ){
-
-		throwException( env, "GetObjectClass", "failed" );
-
-		return 0;
-
-	}else{
-
-		jmethodID method = env->GetMethodID( callback_class, "generalMessage", "(Ljava/lang/String;)J");
-
-		if ( method == NULL ){
-
-			throwException( env, "GetMethodID", "method not found" );
-
-		}else{
-
-			res = (long)env->CallLongMethod( callback, method, j_msg );
-		}
-
-		env->DeleteLocalRef( callback_class );
-	}
-
-	env->ReleaseStringUTFChars( j_msg, msg );
-
-	return( res );
-}
-
-int
-traceRouteReportTimeout(
-	JNIEnv		*env,
-	jobject		callback,
-	int			ttl )
-{
-	char	buffer[1024];
-
-	sprintf( buffer, "%ld", ttl );
-
-	return( traceRouteReport( env, callback, buffer ));
-}
-
-int
-traceRouteReportResult(
-	JNIEnv			*env,
-	jobject			callback,
-	int				ttl,
-	unsigned long	address,
-	int				time,
-	bool			udp )
-{
-	char	buffer[1024];
-
-	sprintf( buffer, "%d, %ld, %d, %d", ttl, address, time, udp?1:0 );
-
-	return( traceRouteReport( env, callback, buffer ));
-}
-
-void
-traceRoute(
-	JNIEnv*			env,
-	jobject			callback,
-	unsigned short	trace_id,
-	unsigned long	source_ip,
-	unsigned long	target_ip,
-	unsigned int	send_sock,
-	unsigned int	receive_sock,
-	bool			ping_mode )
-{
-	char	receive_buffer[ sizeof(ip_header) + sizeof(icmp_header) + 1024];
-
-	unsigned short source_port = TRACE_ROUTE_BASE_PORT;
-	unsigned short target_port = TRACE_ROUTE_BASE_PORT;
-
-	int	seq			= 0;
-	int consec_bad	= 0;
-
-
-	bool	complete	= false;
-
-	bool	use_udp		= true;
-	bool	use_icmp	= true;
-
-	int	ttl;
-
-	if ( ping_mode ){
-
-		ttl = 32;
-
-	}else{
-
-		ttl = 0;
-	}
-
-	while( ttl < 33 && ( ping_mode || !complete )){
-
-	
-		complete = false;
-
-		if ( ping_mode ){
-
-			if ( consec_bad > 256 ){
-
-				throwException( env, "error", "too many consecutive bad packets in ping mode" );
-
-				return;
-			}
-
-		}else{
-
-			ttl++;
-		}
-
-			// try each node up to 3 times
-
-		bool probe_successful = false;
-
-		for (int probe_count=0; probe_count<3 && !( complete || probe_successful); probe_count++){
-
-			int	probe_sequence = seq++;
-
-			if ( !sendTraceRouteMessage( env, trace_id, ttl, send_sock, receive_sock, source_ip, source_port, target_ip, target_port + probe_sequence, use_udp, use_icmp )){
-			
-					// send failed, exception already reported
-
-				return;
-			}
-
-			unsigned long	start_ticks = 0;
-
-			while( !complete ){
-		
-				int receive_timeout = PROBE_TIMEOUT;
-
-				unsigned long	current_ticks = GetTickCount();
-
-				if ( start_ticks == 0 ){
-
-					start_ticks = current_ticks;
-
-				}else{
-
-					receive_timeout -= ( current_ticks - start_ticks );
-				}
-
-				if ( receive_timeout <= 0 ){
-
-					if ( !traceRouteReportTimeout( env, callback, ttl )){
-
-						return;
-					}
-
-					consec_bad = 0;
-
-					break;
-				}
-
-				if( setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &receive_timeout, sizeof(receive_timeout)) == SOCKET_ERROR ){
-
-					throwException( env, "setsockopt", "failed to set receive timeout socket options" );
-
-					return;
-				}
-
-				struct sockaddr_in from;
-				
-				int	from_len = sizeof( from );
-
-				unsigned int	read_len  = recvfrom( receive_sock, receive_buffer, sizeof( receive_buffer ), 0, (struct sockaddr *)&from, &from_len );
-				
-				if ( read_len == SOCKET_ERROR ){
-					
-					if ( WSAGetLastError() == WSAETIMEDOUT ){
-
-						if ( !traceRouteReportTimeout( env, callback, ttl )){
-
-							return;
-						}
-
-						consec_bad = 0;
-
-						break;
-
-					}else{
-
-						throwException( env, "recvfrom", "operation failed", WSAGetLastError());
-
-						return;
-					}
-
-				}else{
-
-					if ( read_len < sizeof( 4 )){
-
-						// printf( "invalid packet read - length < 4\n" );
-
-						consec_bad++;
-
-						continue;
-					}
-
-					ip_header	*ip = (ip_header *)receive_buffer;
-
-					unsigned char	ip_len		= ip->ip_header_len << 2;
-					unsigned short	total_len	= ntohs( ip->total_len );
-
-						// ensure we have a whole packet and an icmp reply
-
-					if ( read_len != total_len || read_len < ip_len + sizeof(icmp_header)){
-
-						// printf( "invalid packet read - read_len != total_len\n" );
-
-						consec_bad++;
-
-						continue;
-					}
-
-					int	elapsed_time = (int)( GetTickCount() - current_ticks );
-
-					icmp_header *icmp = (icmp_header *)(receive_buffer + ip_len );
-
-					unsigned char	icmp_type	= icmp->type;
-
-					if ( icmp_type == ICMP_TYPE_ECHO_REPLY ){
-
-						icmp_echo_header *icmp = (icmp_echo_header *)(receive_buffer + ip_len );
-
-						unsigned short	reply_seq = ntohs( icmp->sequence ) - TRACE_ROUTE_BASE_PORT;
-
-						if ( reply_seq != probe_sequence ){
-
-							consec_bad++;
-
-							continue;
-						}
-
-						if ( !traceRouteReportResult( env, callback, ttl, ntohl( from.sin_addr.s_addr ), elapsed_time, false )){
-
-							return;
-						}
-
-						consec_bad = 0;
-
-						if ( ping_mode ){
-
-							use_udp = false;
-						}
-
-						complete = true;
-
-						break;
-					}
-
-					if ( read_len != total_len || read_len < ip_len + sizeof(icmp_header) + sizeof( ip_header ) + 2){
-
-						// printf( "invalid packet read - read_len != total_len\n" );
-
-						consec_bad++;
-
-						continue;
-					}
-
-					
-					ip_header* old_ip = (ip_header *)(receive_buffer + ip_len + sizeof( icmp_header ));
-
-					if (	icmp_type != ICMP_TYPE_TTL_EXCEEDED &&
-							icmp_type != ICMP_TYPE_UNREACHABLE ){
-
-						// printf( "Unexpected ICMP reply type %d\n", icmp_type );
-
-						consec_bad++;
-
-						continue;
-					}
-		
-					if ( trace_id != ntohs(old_ip->ident )){
-
-							// not our reply
-
-						consec_bad++;
-
-						continue;
-					}
-
-					bool	reply_was_udp;
-
-					if ( old_ip->protocol == IPPROTO_ICMP ){
-
-						icmp_probe_packet*	probe = (icmp_probe_packet *)(receive_buffer + ip_len + sizeof( icmp_header ));
-
-						unsigned short	reply_seq = ntohs( probe->icmp.sequence ) - TRACE_ROUTE_BASE_PORT;
-
-						if ( reply_seq != probe_sequence ){
-
-							consec_bad++;
-
-							continue;
-						}
-
-						reply_was_udp = false;
-
-					}else{
-					
-						udp_probe_packet*	probe = (udp_probe_packet *)(receive_buffer + ip_len + sizeof( icmp_header ));
-
-						unsigned short	reply_seq = ntohs( probe->udp.dest_port ) - TRACE_ROUTE_BASE_PORT;
-
-						if ( reply_seq != probe_sequence ){
-
-							consec_bad++;
-
-							continue;
-						}
-
-						reply_was_udp = true;
-					}
-
-					probe_successful = true;
-
-					if ( icmp_type == ICMP_TYPE_ECHO_REPLY ){
-
-						complete = true;
-
-					}else if ( icmp_type == ICMP_TYPE_TTL_EXCEEDED ){
-					
-
-					}else if ( icmp_type == ICMP_TYPE_UNREACHABLE ){
-
-						unsigned char	icmp_code	= icmp->code;
-
-						if (	icmp_code == ICMP_CODE_PROTOCOL_UNREACHABLE ||
-								icmp_code == ICMP_CODE_PORT_UNREACHABLE ){
-
-								// these are received from the target host
-
-							complete	= true;
-
-						}else{
-
-						}		   
-					}
-
-					if ( ping_mode ){
-
-						if ( reply_was_udp ){
-
-							use_icmp = false;
-
-						}else{
-
-							use_udp = false;
-						}
-					}
-
-					if ( !traceRouteReportResult( env, callback, ttl, ntohl( from.sin_addr.s_addr ), elapsed_time, reply_was_udp )){
-
-						return;
-					}
-
-					consec_bad = 0;
-
-					break;
-				}
-	
-			}	
-		}
-	}
-
-	return;
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_traceRoute(
-	JNIEnv*		env,
-	jclass		cla, 
-	jint		trace_id,
-	jint		source_ip,
-	jint		target_ip,
-	jint		ping_mode,
-	jobject		callback )
-{
-	initialiseWinsock();
-
-	int receive_sock = socket( AF_INET, SOCK_RAW, IPPROTO_ICMP );
-
-	if ( receive_sock == SOCKET_ERROR ) {
-
-		throwException( env, "socket", "failed to create receive socket" );
-
-		return;
-	}
-
-	int receive_timeout = PROBE_TIMEOUT;
-
-	if( setsockopt(receive_sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &receive_timeout, sizeof(receive_timeout)) == SOCKET_ERROR ){
-
-		closesocket(receive_sock);
-
-		throwException( env, "setsockopt", "failed to set receive timeout socket options" );
-
-		return;
-	}
-
-	int so_reuseaddress = 1;
-
-	if( setsockopt(receive_sock, SOL_SOCKET, SO_REUSEADDR, (char *) &so_reuseaddress, sizeof(so_reuseaddress)) == SOCKET_ERROR ){
-
-		closesocket(receive_sock);
-
-		throwException( env, "setsockopt", "failed to set receive reuse address socket options" );
-
-		return;
-	}
-
-		// we have to bind the socket before we can receive ICMP messages on it
-	
-	struct sockaddr_in				recv_bind_addr;
-
-	recv_bind_addr.sin_family		= AF_INET;
-	recv_bind_addr.sin_addr.s_addr	= htonl( source_ip );
-	recv_bind_addr.sin_port			= 0;
-
-	if ( bind( receive_sock, (struct sockaddr *)&recv_bind_addr, sizeof( recv_bind_addr )) == SOCKET_ERROR ){
-
-		closesocket(receive_sock);
-	
-		throwException( env, "socket", "failed to bind send socket" );
-
-		return;
-	}
-
-
-	int send_sock = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
-
-	if ( send_sock == SOCKET_ERROR ) {
-
-		closesocket(receive_sock);
-	
-		throwException( env, "socket", "failed to create send socket" );
-
-		return;
-	}
-
-	int	enable = 1;
-
-	if ( setsockopt(send_sock, IPPROTO_IP, IP_HDRINCL, (char *)&enable,sizeof(enable)) == SOCKET_ERROR ){
-
-		closesocket(send_sock);
-		closesocket(receive_sock);
-
-		throwException( env, "setsockopt", "failed to set receive socket options" );
-
-		return;
-	}
-
-
-	traceRoute( env, callback, (unsigned short)trace_id, (unsigned long)source_ip, (unsigned long)target_ip, send_sock, receive_sock, ping_mode==1?true:false );
-
-	closesocket(send_sock);
-	closesocket(receive_sock);
-}
-
-
-
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aenet.h b/org/gudy/azureus2/platform/win32/access/impl/aenet.h
deleted file mode 100644
index baf60db..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aenet.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Created on 1 Nov 2006
- * Created by Paul Gardner
- * 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.
- *
- */
-
-#define PROBE_TIMEOUT			5000
-#define TRACE_ROUTE_BASE_PORT	48132
-
-#pragma pack (1)
-
-typedef struct
-{
-  unsigned char  ip_header_len:4;  
-  unsigned char  ip_version:4; 
-  unsigned char  tos;             
-  unsigned short total_len;       
-  unsigned short ident;          
-  unsigned short frag_and_flags;  
-  unsigned char  ttl;           
-  unsigned char  protocol;          
-  unsigned short checksum;    
-  unsigned int   source_ip;   
-  unsigned int   dest_ip;  
-} ip_header;
-
-
-typedef struct
-{
-	unsigned int	source_ip;
-	unsigned int	dest_ip;
-	unsigned char	zero;
-	unsigned char	protocol;
-	unsigned short	data_len;
-} pseudo_udp_header;
-
-typedef struct 
-{
-	unsigned short	source_port;
-	unsigned short	dest_port;		
-	unsigned short	data_len;	
-	unsigned short	checksum;	
-} udp_header;
-
-	// basic icmp header
-
-#define ICMP_TYPE_ECHO					8
-#define ICMP_TYPE_ECHO_REPLY			0
-#define ICMP_TYPE_UNREACHABLE			3
-#define ICMP_TYPE_TTL_EXCEEDED			11
-
-#define ICMP_CODE_PROTOCOL_UNREACHABLE	2
-#define ICMP_CODE_PORT_UNREACHABLE		3
-
-
-
-typedef struct
-{
-  unsigned char		type;   
-  unsigned char		code;  
-  unsigned short	checksum;  
-  unsigned int		unused;
-} icmp_header;
-
-typedef struct
-{
-  unsigned char		type;   
-  unsigned char		code;  
-  unsigned short	checksum;  
-  unsigned short	ident;
-  unsigned short	sequence;
-} icmp_echo_header;
-
-typedef struct 
-{
-    ip_header		ip;
-    udp_header		udp;
-	unsigned int	data;
-} udp_probe_packet;
-
-typedef struct 
-{
-    ip_header			ip;
-    icmp_echo_header	icmp;
-	unsigned int		data;
-} icmp_probe_packet;
\ No newline at end of file
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.cpp b/org/gudy/azureus2/platform/win32/access/impl/aereg.cpp
deleted file mode 100644
index c12ff4b..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.cpp
+++ /dev/null
@@ -1,2115 +0,0 @@
-/*
- * Created on Apr 16, 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.
- *
- */
-
-
-#include "stdafx.h"
-#include "aereg.h"
-#include "stdio.h"
-#include "stdlib.h"
-#include "windows.h"
-#include "shlwapi.h"
-#include "process.h"
-#include "shellapi.h"
-
-
-#include "org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h"
-
-
-#define VERSION "1.18"
-
- 
-HMODULE	application_module;
-bool	non_unicode			= false;
-
-jclass AEWin32AccessInterface_class;
-jclass AEWin32AccessExceptionImpl_class;
-
-UINT		uThreadId;
-HINSTANCE	hInstance;
-LRESULT CALLBACK WndProcW(HWND, UINT, WPARAM, LPARAM);
-void	RegisterWindowClassW();
-
-LRESULT CALLBACK WndProcA(HWND, UINT, WPARAM, LPARAM);
-void	RegisterWindowClassA();
-
-HRESULT
-callback(UINT	Msg, WPARAM	wParam, LPARAM	lParam) ;
-
-JavaVM*	jvm;
-
-BOOL APIENTRY 
-DllMain( 
-	HINSTANCE	hModule, 
-    DWORD		ul_reason_for_call, 
-    LPVOID		lpReserved )
-{
-    switch (ul_reason_for_call)
-	{
-		case DLL_PROCESS_ATTACH:
-		{
-			hInstance	= hModule;
-
-			OSVERSIONINFOA	osvi;
-
-			application_module = (HMODULE)hModule;
-
-			osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
-
-			GetVersionExA(&osvi);
-
-			non_unicode = ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS );
-
-			if ( non_unicode ){
-				RegisterWindowClassA();
-			}else{
-				RegisterWindowClassW();
-			}
-
-			break;
-		}
-		case DLL_THREAD_ATTACH:
-		case DLL_THREAD_DETACH:
-		case DLL_PROCESS_DETACH:
-			break;
-    }
-    return TRUE;
-}
-
-
-
-
-CAereg::CAereg()
-{ 
-	return; 
-}
-
-
-void
-throwException(
-	JNIEnv*			env,
-	char*			operation,
-	char*			message )
-{
-	bool	ok = false;
-
-	if ( AEWin32AccessExceptionImpl_class != NULL ){
-
-		jmethodID method = env->GetMethodID( AEWin32AccessExceptionImpl_class, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V" );
-	
-		if ( method != NULL ){
-
-	
-			jobject new_object =
-					env->NewObject( AEWin32AccessExceptionImpl_class, 
-									method, 
-									env->NewStringUTF((const char*)operation), 
-									env->NewStringUTF((const char*)message ));
-
-			if ( new_object != NULL ){
-
-				env->Throw( (jthrowable)new_object );
-
-				ok = true;
-			}
-		}else{
-
-			fprintf( stderr, "AEWin32AccessInterface: failed to resolve constructor" );
-		}
-	}
-
-	if ( !ok ){
-
-		fprintf( stderr, "AEWin32AccessInterface: failed to throw exception %s: %s\n", operation, message );
-	}
-}
-
-void
-throwException(
-	JNIEnv*			env,
-	char*			operation,
-	char*			message,
-	int				error_code )
-{
-	char	buffer[4096];
-
-	sprintf( buffer, "%s (error_code=%d)", message, error_code );
-
-	throwException( env, operation, buffer );
-}
-
-HKEY
-mapHKEY(
-	JNIEnv*		env,
-	jint		_type )
-{
-	if ( _type == org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CLASSES_ROOT ){
-
-		return( HKEY_CLASSES_ROOT );
-
-	}else if ( _type == org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_CONFIG ){
-
-		return( HKEY_CURRENT_CONFIG );
-
-	}else if ( _type == org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_LOCAL_MACHINE ){
-
-		return( HKEY_LOCAL_MACHINE );
-
-	}else if ( _type == org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_USER ){
-
-		return( HKEY_CURRENT_USER );
-
-	}else{
-
-		throwException( env, "readValue", "unsupported type" );
-
-		return( NULL );
-	}
-}
-
-
-// ******************************
-
-bool
-jstringToCharsW(
-	JNIEnv		*env,
-	jstring		jstr,
-	WCHAR		*chars,
-	int			chars_len )
-{
-	if ( jstr == NULL ){
-
-		chars[0] = 0;
-
-	}else{
-
-		int	jdata_len = env->GetStringLength(jstr);
-
-		if ( jdata_len >= chars_len ){
-
-			throwException( env, "jstringToChars", "jstring truncation occurred" );
-
-			return( false );
-		}
-
-		const jchar *jdata = env->GetStringChars( jstr, NULL );
-
-		for (int i=0;i<jdata_len;i++){
-
-			chars[i] = (WCHAR)jdata[i];
-		}
-
-		chars[jdata_len]=0;
-
-		env->ReleaseStringChars( jstr, jdata );
-	}
-
-	return( true );
-}
-
-
-// WINDOWS HOOK
-
-void
-RegisterWindowClassW() 
-{
-	WNDCLASSEXW wcex;
-
-	wcex.cbSize = sizeof(WNDCLASSEXW); 
-	wcex.style			= CS_HREDRAW | CS_VREDRAW;
-	wcex.lpfnWndProc	= WndProcW;
-	wcex.cbClsExtra		= 0;
-	wcex.cbWndExtra		= 0;
-	wcex.hInstance		= hInstance;
-	wcex.hIcon			= 0;
-	wcex.hCursor		= 0;
-	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
-	wcex.lpszMenuName	= 0;
-	wcex.lpszClassName	= L"Azureus Window Hook";
-	wcex.hIconSm		= 0;
-
-	RegisterClassExW(&wcex);
-}
-
-
-LRESULT CALLBACK 
-WndProcW(
-	HWND hWnd, 
-	UINT Msg, 
-	WPARAM wParam, 
-	LPARAM lParam) 
-{
-	long res = callback( Msg, wParam, lParam );
-
-	if ( res != -1 ){
-
-		return( res );
-	}
-
-	return DefWindowProcW(hWnd, Msg, wParam, lParam);
-}
-
-unsigned WINAPI 
-CreateWndThreadW(
-	LPVOID pThreadParam) 
-{
-	HWND hWnd = CreateWindowW( L"Azureus Window Hook", NULL, WS_OVERLAPPEDWINDOW,
-									CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-									NULL, NULL, hInstance, NULL);
-	if( hWnd == NULL){
-
-		printf( "Failed to create window\n" );
-
-		return( 0 );
-
-	}else{
-
-		MSG Msg;
-
-		while(GetMessageW(&Msg, hWnd, 0, 0)) {
-
-			TranslateMessage(&Msg);
-
-			DispatchMessageW(&Msg);
-		}
-
-		return Msg.wParam;
-	}
-} 
-
-
-//
-
-void
-RegisterWindowClassA() 
-{
-	WNDCLASSEXA wcex;
-
-	wcex.cbSize = sizeof(WNDCLASSEXA); 
-	wcex.style			= CS_HREDRAW | CS_VREDRAW;
-	wcex.lpfnWndProc	= WndProcA;
-	wcex.cbClsExtra		= 0;
-	wcex.cbWndExtra		= 0;
-	wcex.hInstance		= hInstance;
-	wcex.hIcon			= 0;
-	wcex.hCursor		= 0;
-	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW + 1);
-	wcex.lpszMenuName	= 0;
-	wcex.lpszClassName	= "Azureus Window Hook";
-	wcex.hIconSm		= 0;
-
-	RegisterClassExA(&wcex);
-}
-
-
-LRESULT CALLBACK 
-WndProcA(
-	HWND hWnd, 
-	UINT Msg, 
-	WPARAM wParam, 
-	LPARAM lParam) 
-{
-	long res = callback( Msg, wParam, lParam );
-
-	if ( res != -1 ){
-
-		return( res );
-	}
-
-	return DefWindowProcA(hWnd, Msg, wParam, lParam);
-}
-
-unsigned WINAPI 
-CreateWndThreadA(
-	LPVOID pThreadParam) 
-{
-	HWND hWnd = CreateWindowA( "Azureus Window Hook", NULL, WS_OVERLAPPEDWINDOW,
-									CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-									NULL, NULL, hInstance, NULL);
-	if( hWnd == NULL){
-
-		printf( "Failed to create window\n" );
-
-		return( 0 );
-
-	}else{
-
-		MSG Msg;
-
-		while(GetMessageA(&Msg, hWnd, 0, 0)) {
-
-			TranslateMessage(&Msg);
-
-			DispatchMessageA(&Msg);
-		}
-
-		return Msg.wParam;
-	}
-} 
-
-
-HRESULT
-callback(
-	UINT	Msg, 
-	WPARAM	wParam, 
-	LPARAM	lParam) 
-{
-	JNIEnv *env; 
-
-	if ( jvm->AttachCurrentThread((void **)&env, NULL )){
-
-		fprintf( stderr, "failed to attach current thread to JVM\n" );
-
-		return( -1 );
-	}
-
-
-	jlong result = -1;
-
-	if ( AEWin32AccessInterface_class != NULL ){
-
-		jint	j_msg		= Msg;
-		jint	j_param1	= wParam;
-		jlong	j_param2	= lParam;
-
-
-		jmethodID method = env->GetStaticMethodID( AEWin32AccessInterface_class, "callback", "(IIJ)J");
-
-		if ( method != NULL ){
-
-			result = env->CallStaticLongMethod( AEWin32AccessInterface_class, method, j_msg, j_param1, j_param2 );
-
-		}else{
-					
-			fprintf( stderr, "failed to resolve callback method\n" );
-		}
-	}
-
-
-	jvm->DetachCurrentThread();
-
-	return((HRESULT)result ); 
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_initialise(
-	JNIEnv *env, 
-	jclass	cla )
-{
-	HANDLE hThread;
-
-	env->GetJavaVM(&jvm);
-
-	jclass local_ref = env->FindClass("org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessInterface" );
-
-	if ( local_ref == NULL ){
-
-		fprintf( stderr, "failed to find AEWin32AccessInterface class\n" );
-
-	}else{
-
-		AEWin32AccessInterface_class = (jclass)env->NewGlobalRef( local_ref );
-
-		env->DeleteLocalRef( local_ref );
-	}
-
-	local_ref = env->FindClass( "org/gudy/azureus2/platform/win32/access/impl/AEWin32AccessExceptionImpl" );
-	
-	if ( local_ref == NULL ){
-
-		fprintf( stderr, "failed to find AEWin32AccessExceptionImpl class\n" );
-
-	}else{
-
-		AEWin32AccessExceptionImpl_class = (jclass)env->NewGlobalRef( local_ref );
-
-		env->DeleteLocalRef( local_ref );
-	}
-
-	if ( non_unicode ){
-
-		hThread = (HANDLE)_beginthreadex(NULL, 0, &CreateWndThreadA, NULL, 0, &uThreadId);
-
-	}else{
-
-		hThread = (HANDLE)_beginthreadex(NULL, 0, &CreateWndThreadW, NULL, 0, &uThreadId);
-	}
-
-	if(!hThread){
-
-		throwException( env, "_beginthreadex", "initialisation failed" );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_destroy(
-	JNIEnv *env, 
-	jclass	cla )
-{
-	if ( uThreadId ){
-
-		PostThreadMessage(uThreadId, WM_QUIT, 0, 0);
-	}
-}
-
-// UNICODE METHODS
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getModuleNameW(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	WCHAR	buffer[2048];
-
-	if ( !GetModuleFileNameW(application_module, buffer, sizeof( buffer ))){
-
-
-		throwException( env, "getModuleName", "GetModuleFileName fails" );
-
-		return( NULL );
-	}
-
-	return( env->NewString((const jchar *)buffer, wcslen(buffer)));
-}
-
-
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersionW(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	jstring	result = env->NewStringUTF((char *)VERSION);
-
-	return( result );
-}
-
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValueW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-	WCHAR		value_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsW( env, _value_name, value_name, sizeof( value_name ))){
-
-		return( NULL );
-	}
-
-	if ( RegOpenKeyW( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-		BYTE	value[1024];
-		DWORD	value_length	= sizeof( value );
-		DWORD	type;
-
-		if ( RegQueryValueExW( subkey, value_name, NULL, &type, (unsigned char*)value, &value_length ) == ERROR_SUCCESS){
-
-			if ( type == REG_SZ || type == REG_EXPAND_SZ || type == REG_MULTI_SZ ){
-
-				if ( type == REG_EXPAND_SZ ){
-
-					WCHAR	expanded_value[2048];
-
-					ExpandEnvironmentStringsW((const WCHAR*)value, expanded_value, sizeof( expanded_value ));
-			
-					result = env->NewString((const jchar *)expanded_value,wcslen(expanded_value));
-
-				}else{
-
-
-					result = env->NewString((const jchar *)value,wcslen((WCHAR *)value));
-				}			
-
-			}else{
-
-				throwException( env, "readValue", "type mismach" );
-			}
-		}else{
-
-			throwException( env, "readStringValue", "RegQueryValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "readStringValue", "RegOpenKey failed" );
-	}
-
-	return( result );
-}
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValueW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-	WCHAR		value_name[1024];
-
-	jint		result	= 0;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsW( env, _value_name, value_name, sizeof( value_name ))){
-
-		return( NULL );
-	}
-
-	if ( RegOpenKeyW( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-		BYTE	value[1024];
-		DWORD	value_length	= sizeof( value );
-		DWORD	type;
-
-		if ( RegQueryValueExW( subkey, value_name, NULL, &type, (unsigned char*)value, &value_length ) == ERROR_SUCCESS){
-
-			if ( type == REG_DWORD ){
-
-				result = (LONG)value[0];
-
-			}else{
-
-				throwException( env, "readValue", "type mismach" );
-			}
-		}else{
-
-			throwException( env, "readStringValue", "RegQueryValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "readStringValue", "RegOpenKey failed" );
-	}
-
-	return(result);
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValueW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jint		_value_value )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-	WCHAR		value_name[1024];
-	DWORD		value_value	= _value_value;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-
-
-	if ( RegCreateKeyExW( key, subkey_name, 0, REG_NONE, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL ) == ERROR_SUCCESS ){
-
-
-		if ( RegSetValueExW( subkey, value_name, 0, REG_DWORD, (const BYTE*)&value_value, sizeof(DWORD)) == ERROR_SUCCESS){
-
-		}else{
-
-			throwException( env, "writeWordValue", "RegSetValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "writeWordValue", "RegCreateKeyEx failed" );
-	}
-
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValueW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jstring		_value_value )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-	WCHAR		value_name[1024];
-	WCHAR		value_value[1024];
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-
-	if ( !jstringToCharsW( env, _value_value, value_value, sizeof( value_value ))){
-
-		return;
-	}
-
-
-	if ( RegCreateKeyExW( key, subkey_name, 0, REG_NONE, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL ) == ERROR_SUCCESS ){
-
-
-		if ( RegSetValueExW( subkey, value_name, 0, REG_SZ, (const BYTE*)value_value, (wcslen(value_value)+1)*sizeof(WCHAR)) == ERROR_SUCCESS){
-
-		}else{
-
-			throwException( env, "writeStringValue", "RegSetValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "writeStringValue", "RegCreateKeyEx failed" );
-	}
-
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKeyW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jboolean	_recursive )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( RegOpenKeyW( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-
-		RegCloseKey(subkey);
-
-		if ( _recursive ){
-
-			if ( SHDeleteKeyW( key, subkey_name ) != ERROR_SUCCESS ){
-
-				throwException( env, "deleteKey", "SHDeleteKey failed" );
-			}
-		}else{
-
-			if ( RegDeleteKeyW( key, subkey_name ) != ERROR_SUCCESS ){
-
-				throwException( env, "deleteKey", "RegDeleteKey failed" );
-			}
-		}
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValueW(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	WCHAR		subkey_name[1024];
-	WCHAR		value_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-	if ( RegOpenKeyW( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-
-		RegCloseKey(subkey);
-
-		if ( SHDeleteValueW( key, subkey_name, value_name ) != ERROR_SUCCESS ){
-
-			throwException( env, "deleteValue", "SHDeleteValue failed" );
-		}
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcessW(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_command_line, 
-	jboolean	_inherit_handles )
-{
-	WCHAR		command_line[16000];
-
-	STARTUPINFOW			start_info;
-	PROCESS_INFORMATION		proc_info;
-
-	if ( !jstringToCharsW( env, _command_line, command_line, sizeof( command_line ))){
-
-		return;
-	}
-
-	memset( &start_info, 0, sizeof( STARTUPINFO ));
-
-	start_info.cb = sizeof( STARTUPINFO );
-
-	if ( CreateProcessW(
-			NULL,				// LPCTSTR lpApplicationName,
-			command_line,		// LPTSTR lpCommandLine,
-			NULL,				// LPSECURITY_ATTRIBUTES lpProcessAttributes,
-			NULL,				// LPSECURITY_ATTRIBUTES lpThreadAttributes,
-			_inherit_handles,	// BOOL bInheritHandles,
-			DETACHED_PROCESS,	// DWORD dwCreationFlags,
-			NULL,				// LPVOID lpEnvironment,
-			NULL,				// LPCTSTR lpCurrentDirectory,
-			&start_info,		// LPSTARTUPINFO lpStartupInfo,
-			&proc_info )){		// LPPROCESS_INFORMATION lpProcessInformation
-
-
-		CloseHandle( proc_info.hThread );
-        CloseHandle( proc_info.hProcess );
-
-	}else{
-
-		throwException( env, "createProcess", "CreateProcess failed" );
-	}
-};
-
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecAndWaitW(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_file,
-	jstring		_params )
-{
-	WCHAR		file[2048];
-	WCHAR		params[2048];
-
-	if ( !jstringToCharsW( env, _file, file, sizeof( file ))){
-
-		return(0);
-	}
-
-	if ( !jstringToCharsW( env, _params, params, sizeof( params ))){
-
-		return(0);
-	}
-
-    SHELLEXECUTEINFO shExecInfo;
-
-    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
-
-    shExecInfo.fMask		= SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
-    shExecInfo.hwnd			= NULL;
-    shExecInfo.lpVerb		= L"runas";
-    shExecInfo.lpFile		= file;
-    shExecInfo.lpParameters = params;
-    shExecInfo.lpDirectory	= NULL;
-    shExecInfo.nShow		= SW_SHOWNORMAL;
-    shExecInfo.hInstApp		= NULL;
-
-    ShellExecuteExW(&shExecInfo);
-
-
-	int res = (int)shExecInfo.hInstApp;
-
-	if ( res <= 32 ){
-
-		throwException( env, "shellExec", "ShellExecW failed", res );
-
-		return( 0 );
-
-	}else{
-
-		HANDLE process = shExecInfo.hProcess;
-
-		WaitForSingleObject( process, INFINITE );
-
-		DWORD result;
-
-		if ( GetExitCodeProcess( process, &result ) == 0 ){
-
-			throwException( env, "shellExec", "GetExitCodeProcess failed", GetLastError());
-		}
-
-		CloseHandle( process );
-		
-		return((jint)result);
-	}
-};
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBinW(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _fileName )
-
-{
-	WCHAR		file_name[16000];
-
-    SHFILEOPSTRUCTW opFile;
-    
-	if ( !jstringToCharsW( env, _fileName, file_name, sizeof( file_name )-1)){
-
-		return;
-	}
-
-    HANDLE file = CreateFileW (	file_name, 
-								GENERIC_READ, 
-								FILE_SHARE_READ, 
-								NULL, 
-								OPEN_EXISTING, 
-								FILE_ATTRIBUTE_NORMAL, 
-								NULL );
-    
-		// Checks if file exists
-
-    if ( file == INVALID_HANDLE_VALUE ){
-   
-		throwException( env, "moveToRecycleBin", "file not found" );
-
-        return;
-    }
-    
-    CloseHandle(file);
-
-    file_name[ wcslen(file_name)+1 ] = 0;
-
-    ZeroMemory(&opFile, sizeof(opFile));
-
-    opFile.wFunc = FO_DELETE;
-
-    opFile.pFrom = file_name;
-
-    opFile.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
-    
-    if (SHFileOperationW (&opFile)){
-
-        throwException( env, "moveToRecycleBin", "SHFileOperation failed" );
-    }
-}
-
-#define myheapalloc(x) (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, x))
-#define myheapfree(x)  (HeapFree(GetProcessHeap(), 0, x))
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermissionW(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _fileNameIn,
-	jstring _fileNameOut )
-{
-	WCHAR		file_name_in[2048];
-	WCHAR		file_name_out[2048];
-    
-	if ( !jstringToCharsW( env, _fileNameIn, file_name_in, sizeof( file_name_in )-1)){
-
-		return;
-	}
-
-	if ( !jstringToCharsW( env, _fileNameOut, file_name_out, sizeof( file_name_out )-1)){
-
-		return;
-	}
-
-	SECURITY_INFORMATION secInfo	= DACL_SECURITY_INFORMATION;
-	DWORD				 cbFileSD   = 0;
-	PSECURITY_DESCRIPTOR pFileSD	= NULL;
-
-    BOOL ok = GetFileSecurityW(file_name_in, secInfo, pFileSD, 0, &cbFileSD);
-
-      // API should have failed with insufficient buffer.
-
-	if ( ok ){
-     
-		throwException( env, "copyPermission", "GetFileSecurity ok" );
-
-        return;
-
-    }else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
-
-		throwException( env, "copyPermission", "from file not found" );
-
-		return;
-
-	}else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-
-		throwException( env, "copyPermission", "GetFileSecurity unexpected response", GetLastError() );
-
-        return;
-	
-	}else{
-
-		pFileSD	= myheapalloc( cbFileSD );
-      
-		if (!pFileSD) {
-  
-			throwException( env, "copyPermission", "no memory" );
-
-			return;
-		}
-
-		ok = GetFileSecurityW(file_name_in, secInfo, pFileSD, cbFileSD, &cbFileSD );
-      
-		if (!ok) {
-
-			myheapfree( pFileSD );
-
-			throwException( env, "copyPermission", "GetFileSecurity", GetLastError());
-
-			return;
-		}	
-
-		ok = SetFileSecurityW( file_name_out, secInfo, pFileSD );
-
-	 	myheapfree( pFileSD );
-
-		if ( !ok ){
-
-			if (GetLastError() == ERROR_FILE_NOT_FOUND) {
-
-				throwException( env, "copyPermission", "to file not found" );
-
-			}else{
-
-				throwException( env, "copyPermission", "SetFileSecurity unexpected response", GetLastError() );
-
-			}
-		}
-	}
-}
-
-JNIEXPORT jboolean JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailabilityW(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _name )
-{
-	WCHAR		name[2048];
-    
-	if ( !jstringToCharsW( env, _name, name, sizeof( name )-1)){
-
-		return( 0 );
-	}
-
-
-	HMODULE	mod = 
-		LoadLibraryExW( 
-			name,
-			NULL,
-			LOAD_LIBRARY_AS_DATAFILE );
-
-	if ( mod == NULL ){
-
-		return( 0 );
-
-	}else{
-
-		FreeLibrary( mod );
-
-		return( 1 );
-	}
-}
-
-// 1.3
-JNIEXPORT jint JNICALL
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteW(
-	JNIEnv	*env,
-	jclass	cla,
-	jstring _operation,
-	jstring	_file,
-	jstring _parameters,
-	jstring _directory,
-	jint _showCmd )
-{
-	WCHAR		operation[20];
-	WCHAR		file[5192];
-	WCHAR		parameters[16000];
-	WCHAR		directory[5192];
-	INT			showCmd = _showCmd;
-	
-	if ( !jstringToCharsW( env, _operation, operation, sizeof( operation ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsW( env, _file, file, sizeof( file ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsW( env, _parameters, parameters, sizeof( parameters ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsW( env, _directory, directory, sizeof( directory ))){
-		return -1;
-	}
-	
-	// Not sure if ShellExecute treats "\0" as NULL, so do explicit check 
-	return(jint) ShellExecuteW(NULL,
-			_operation == NULL ? NULL : operation,
-			_file == NULL ? NULL : file,
-			_parameters == NULL ? NULL : parameters,
-			_directory == NULL ? NULL : directory,
-			showCmd);
-}
-
-
-// NON-UNICODE VARIANT FOR WIN95,98,ME
-
-
-
-
-bool
-jstringToCharsA(
-	JNIEnv		*env,
-	jstring		jstr,
-	char		*chars,
-	int			chars_len )
-{
-	if ( jstr == NULL ){
-
-		chars[0] = 0;
-
-	}else{
-
-		int	jdata_len = env->GetStringLength(jstr);
-
-		if ( jdata_len >= chars_len ){
-
-			throwException( env, "jstringToChars", "jstring truncation occurred" );
-
-			return( false );
-		}
-
-		const jchar *jdata = env->GetStringChars( jstr, NULL );
-
-		for (int i=0;i<jdata_len;i++){
-
-			chars[i] = (char)jdata[i];
-		}
-
-		chars[jdata_len]=0;
-
-		env->ReleaseStringChars( jstr, jdata );
-	}
-
-	return( true );
-}
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getModuleNameA(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	char	buffer[2048];
-
-	if ( !GetModuleFileNameA(application_module, buffer, sizeof( buffer ))){
-
-
-		throwException( env, "getModuleName", "GetModuleFileName fails" );
-
-		return( NULL );
-	}
-
-	return( env->NewStringUTF((char *)buffer));
-}
-
-
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersionA(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	jstring	result = env->NewStringUTF((char *)VERSION);
-
-	return( result );
-}
-
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValueA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-	char		value_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsA( env, _value_name, value_name, sizeof( value_name ))){
-
-		return( NULL );
-	}
-
-	if ( RegOpenKeyA( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-		BYTE	value[1024];
-		DWORD	value_length	= sizeof( value );
-		DWORD	type;
-
-		if ( RegQueryValueExA( subkey, value_name, NULL, &type, (unsigned char*)value, &value_length ) == ERROR_SUCCESS){
-
-			if ( type == REG_SZ || type == REG_EXPAND_SZ || type == REG_MULTI_SZ ){
-
-				if ( type == REG_EXPAND_SZ ){
-
-					char	expanded_value[2048];
-
-					ExpandEnvironmentStringsA((const char*)value, expanded_value, sizeof( expanded_value ));
-			
-					result = env->NewStringUTF((char *)expanded_value);
-
-				}else{
-
-
-					result = env->NewStringUTF((char *)value);
-				}			
-
-			}else{
-
-				throwException( env, "readValue", "type mismach" );
-			}
-		}else{
-
-			throwException( env, "readStringValue", "RegQueryValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "readStringValue", "RegOpenKey failed" );
-	}
-
-	return( result );
-}
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValueA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-	char		value_name[1024];
-
-	jint		result	= 0;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return( NULL );
-	}
-
-	if ( !jstringToCharsA( env, _value_name, value_name, sizeof( value_name ))){
-
-		return( NULL );
-	}
-
-	if ( RegOpenKeyA( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-		BYTE	value[1024];
-		DWORD	value_length	= sizeof( value );
-		DWORD	type;
-
-		if ( RegQueryValueExA( subkey, value_name, NULL, &type, (unsigned char*)value, &value_length ) == ERROR_SUCCESS){
-
-			if ( type == REG_DWORD ){
-
-				result = (LONG)value[0];
-
-			}else{
-
-				throwException( env, "readValue", "type mismach" );
-			}
-		}else{
-
-			throwException( env, "readStringValue", "RegQueryValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "readStringValue", "RegOpenKey failed" );
-	}
-
-	return(result);
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValueA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jint		_value_value )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-	char		value_name[1024];
-	DWORD		value_value	= _value_value;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-
-
-	if ( RegCreateKeyExA( key, subkey_name, 0, REG_NONE, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL ) == ERROR_SUCCESS ){
-
-
-		if ( RegSetValueExA( subkey, value_name, 0, REG_DWORD, (const BYTE*)&value_value, sizeof(DWORD)) == ERROR_SUCCESS){
-
-		}else{
-
-			throwException( env, "writeWordValue", "RegSetValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "writeWordValue", "RegCreateKeyEx failed" );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValueA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jstring		_value_value )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-	char		value_name[1024];
-	char		value_value[1024];
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-
-	if ( !jstringToCharsA( env, _value_value, value_value, sizeof( value_value ))){
-
-		return;
-	}
-
-
-	if ( RegCreateKeyExA( key, subkey_name, 0, REG_NONE, 0, KEY_ALL_ACCESS, NULL, &subkey, NULL ) == ERROR_SUCCESS ){
-
-
-		if ( RegSetValueExA( subkey, value_name, 0, REG_SZ, (const BYTE*)value_value, strlen(value_value)+1 ) == ERROR_SUCCESS){
-
-		}else{
-
-			throwException( env, "writeStringValue", "RegSetValueEx failed" );
-		}
-
-		RegCloseKey(subkey);
-
-	}else{
-
-		throwException( env, "writeStringValue", "RegCreateKeyEx failed" );
-	}
-
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKeyA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jboolean	_recursive )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( RegOpenKeyA( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-
-		RegCloseKey(subkey);
-
-		if ( _recursive ){
-
-			if ( SHDeleteKeyA( key, subkey_name ) != ERROR_SUCCESS ){
-
-				throwException( env, "deleteKey", "SHDeleteKey failed" );
-			}
-		}else{
-
-			if ( RegDeleteKeyA( key, subkey_name ) != ERROR_SUCCESS ){
-
-				throwException( env, "deleteKey", "RegDeleteKey failed" );
-			}
-		}
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValueA(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	HKEY		key;
-	HKEY		subkey;
-	char		subkey_name[1024];
-	char		value_name[1024];
-
-	jstring		result	= NULL;
-
-	key	= mapHKEY( env, _type );
-
-	if ( key == NULL ){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _subkey_name, subkey_name, sizeof( subkey_name ))){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _value_name, value_name, sizeof( value_name ))){
-
-		return;
-	}
-
-	if ( RegOpenKeyA( key, subkey_name, &subkey ) == ERROR_SUCCESS ){
-
-
-		RegCloseKey(subkey);
-
-		if ( SHDeleteValueA( key, subkey_name, value_name ) != ERROR_SUCCESS ){
-
-			throwException( env, "deleteValue", "SHDeleteValue failed" );
-		}
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcessA(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_command_line, 
-	jboolean	_inherit_handles )
-{
-	char		command_line[16000];
-
-	STARTUPINFOA			start_info;
-	PROCESS_INFORMATION		proc_info;
-
-	if ( !jstringToCharsA( env, _command_line, command_line, sizeof( command_line ))){
-
-		return;
-	}
-
-	memset( &start_info, 0, sizeof( STARTUPINFOA ));
-
-	start_info.cb = sizeof( STARTUPINFOA );
-
-	if ( CreateProcessA(
-			NULL,				// LPCTSTR lpApplicationName,
-			command_line,		// LPTSTR lpCommandLine,
-			NULL,				// LPSECURITY_ATTRIBUTES lpProcessAttributes,
-			NULL,				// LPSECURITY_ATTRIBUTES lpThreadAttributes,
-			_inherit_handles,	// BOOL bInheritHandles,
-			DETACHED_PROCESS,	// DWORD dwCreationFlags,
-			NULL,				// LPVOID lpEnvironment,
-			NULL,				// LPCTSTR lpCurrentDirectory,
-			&start_info,		// LPSTARTUPINFO lpStartupInfo,
-			&proc_info )){		// LPPROCESS_INFORMATION lpProcessInformation
-
-
-		CloseHandle( proc_info.hThread );
-        CloseHandle( proc_info.hProcess );
-
-	}else{
-
-		throwException( env, "createProcess", "CreateProcess failed" );
-	}
-};
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecAndWaitA(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_file,
-	jstring		_params )
-{
-	char		file[2048];
-	char		params[2048];
-
-	if ( !jstringToCharsA( env, _file, file, sizeof( file ))){
-
-		return(0);
-	}
-
-	if ( !jstringToCharsA( env, _params, params, sizeof( params ))){
-
-		return(0);
-	}
-
-    SHELLEXECUTEINFOA shExecInfo;
-
-    shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOA);
-
-    shExecInfo.fMask		= SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
-    shExecInfo.hwnd			= NULL;
-    shExecInfo.lpVerb		= "runas";
-    shExecInfo.lpFile		= file;
-    shExecInfo.lpParameters = params;
-    shExecInfo.lpDirectory	= NULL;
-    shExecInfo.nShow		= SW_SHOWNORMAL;
-    shExecInfo.hInstApp		= NULL;
-
-    ShellExecuteExA(&shExecInfo);
-
-
-	int res = (int)shExecInfo.hInstApp;
-
-	if ( res <= 32 ){
-
-		throwException( env, "shellExec", "ShellExecA failed", res );
-
-		return( 0 );
-
-	}else{
-
-		HANDLE process = shExecInfo.hProcess;
-
-		WaitForSingleObject( process, INFINITE );
-
-		DWORD result;
-
-		if ( GetExitCodeProcess( process, &result ) == 0 ){
-
-			throwException( env, "shellExec", "GetExitCodeProcess failed", GetLastError());
-		}
-
-		CloseHandle( process );
-		
-		return((jint)result);
-	}
-};
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBinA(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _fileName )
-
-{
-	char		file_name[16000];
-
-    SHFILEOPSTRUCTA opFile;
-    
-	if ( !jstringToCharsA( env, _fileName, file_name, sizeof( file_name )-1)){
-
-		return;
-	}
-
-    HANDLE file = CreateFileA (	file_name, 
-								GENERIC_READ, 
-								FILE_SHARE_READ, 
-								NULL, 
-								OPEN_EXISTING, 
-								FILE_ATTRIBUTE_NORMAL, 
-								NULL );
-    
-		// Checks if file exists
-
-    if ( file == INVALID_HANDLE_VALUE ){
-   
-		throwException( env, "moveToRecycleBin", "file not found" );
-
-        return;
-    }
-    
-    CloseHandle(file);
-
-    file_name[ strlen(file_name)+1 ] = 0;
-
-    ZeroMemory(&opFile, sizeof(opFile));
-
-    opFile.wFunc = FO_DELETE;
-
-    opFile.pFrom = file_name;
-
-    opFile.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
-    
-    if (SHFileOperationA (&opFile)){
-
-        throwException( env, "moveToRecycleBin", "SHFileOperation failed" );
-    }
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermissionA(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _fileNameIn,
-	jstring _fileNameOut )
-{
-	char		file_name_in[2048];
-	char		file_name_out[2048];
-    
-	if ( !jstringToCharsA( env, _fileNameIn, file_name_in, sizeof( file_name_in )-1)){
-
-		return;
-	}
-
-	if ( !jstringToCharsA( env, _fileNameOut, file_name_out, sizeof( file_name_out )-1)){
-
-		return;
-	}
-
-	SECURITY_INFORMATION secInfo	= DACL_SECURITY_INFORMATION;
-	DWORD				 cbFileSD   = 0;
-	PSECURITY_DESCRIPTOR pFileSD	= NULL;
-
-    BOOL ok = GetFileSecurityA(file_name_in, secInfo, pFileSD, 0, &cbFileSD);
-
-      // API should have failed with insufficient buffer.
-
-	if ( ok ){
-     
-		throwException( env, "copyPermission", "GetFileSecurity ok" );
-
-        return;
-
-    }else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
-
-		throwException( env, "copyPermission", "from file not found" );
-
-		return;
-
-	}else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
-
-		throwException( env, "copyPermission", "GetFileSecurity unexpected response", GetLastError() );
-
-        return;
-	
-	}else{
-
-		pFileSD	= myheapalloc( cbFileSD );
-      
-		if (!pFileSD) {
-  
-			throwException( env, "copyPermission", "no memory" );
-
-			return;
-		}
-
-		ok = GetFileSecurityA(file_name_in, secInfo, pFileSD, cbFileSD, &cbFileSD );
-      
-		if (!ok) {
-
-			myheapfree( pFileSD );
-
-			throwException( env, "copyPermission", "GetFileSecurity", GetLastError());
-
-			return;
-		}	
-
-		ok = SetFileSecurityA( file_name_out, secInfo, pFileSD );
-
-	 	myheapfree( pFileSD );
-
-		if ( !ok ){
-
-			if (GetLastError() == ERROR_FILE_NOT_FOUND) {
-
-				throwException( env, "copyPermission", "to file not found" );
-
-			}else{
-
-				throwException( env, "copyPermission", "SetFileSecurity unexpected response", GetLastError() );
-
-			}
-		}
-	}
-}
-
-JNIEXPORT jboolean JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailabilityA(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _name )
-{
-	char		name[2048];
-    
-	if ( !jstringToCharsA( env, _name, name, sizeof( name )-1)){
-
-		return( 0 );
-	}
-
-
-	HMODULE	mod = 
-		LoadLibraryExA( 
-			name,
-			NULL,
-			LOAD_LIBRARY_AS_DATAFILE );
-
-	if ( mod == NULL ){
-
-		return( 0 );
-
-	}else{
-
-		FreeLibrary( mod );
-
-		return( 1 );
-	}
-}
-
-// 1.3
-JNIEXPORT jint JNICALL
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteA(
-	JNIEnv	*env,
-	jclass	cla,
-	jstring _operation,
-	jstring	_file,
-	jstring _parameters,
-	jstring _directory,
-	jint _showCmd )
-{
-	char	operation[20];
-	char	file[5192];
-	char	parameters[16000];
-	char	directory[5192];
-	INT		showCmd = _showCmd;
-	
-	if ( !jstringToCharsA( env, _operation, operation, sizeof( operation ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsA( env, _file, file, sizeof( file ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsA( env, _parameters, parameters, sizeof( parameters ))){
-		return -1;
-	}
-
-	if ( !jstringToCharsA( env, _directory, directory, sizeof( directory ))){
-		return -1;
-	}
-	
-	// Not sure if ShellExecute treats "\0" as NULL, so do explicit check 
-	return (jint)ShellExecuteA(NULL,
-			_operation == NULL ? NULL : operation,
-			_file == NULL ? NULL : file,
-			_parameters == NULL ? NULL : parameters,
-			_directory == NULL ? NULL : directory,
-			showCmd);
-}
-
-
-// BLAH
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getModuleName(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getModuleNameA( env, cla ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getModuleNameW( env, cla ));
-	}
-}
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersion(
-	JNIEnv		*env,
-	jclass		cla )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersionA( env, cla ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersionW( env, cla ));
-	}
-}
-
-JNIEXPORT jstring JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValue(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValueA( env, cla, _type, _subkey_name, _value_name ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValueW( env, cla, _type, _subkey_name, _value_name ));
-	}
-}
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValue(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValueA( env, cla, _type, _subkey_name, _value_name ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValueW( env, cla, _type, _subkey_name, _value_name ));
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValue(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jstring		_value_value )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValueA( env, cla, _type, _subkey_name, _value_name, _value_value );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValueW( env, cla, _type, _subkey_name, _value_name, _value_value );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValue(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name,
-	jint		_value_value )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValueA( env, cla, _type, _subkey_name, _value_name, _value_value );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValueW( env, cla, _type, _subkey_name, _value_name, _value_value );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKey(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jboolean	_recursive )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKeyA( env, cla, _type, _subkey_name, _recursive );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKeyW( env, cla, _type, _subkey_name, _recursive );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValue(
-	JNIEnv		*env,
-	jclass		cla,
-	jint		_type, 
-	jstring		_subkey_name,
-	jstring		_value_name )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValueA( env, cla, _type, _subkey_name, _value_name );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValueW( env, cla, _type, _subkey_name, _value_name );
-	}
-}
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcess(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_command_line, 
-	jboolean	_inherit_handles )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcessA( env, cla, _command_line, _inherit_handles );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcessW( env, cla, _command_line, _inherit_handles );
-	}
-}
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBin(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_file_name )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBinA( env, cla, _file_name );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBinW( env, cla, _file_name );
-	}
-}
-
-
-
-JNIEXPORT void JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermission(
-	JNIEnv *env, 
-	jclass	cla, 
-	jstring _fileNameIn,
-	jstring _fileNameOut )
-{
-	if ( non_unicode ){
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermissionA( env, cla, _fileNameIn, _fileNameOut );
-	}else{
-		Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermissionW( env, cla, _fileNameIn, _fileNameOut );
-	}
-}
-
-JNIEXPORT jboolean JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailability(
-	JNIEnv	*env,
-	jclass	cla,
-	jstring	name )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailabilityA( env, cla,name ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailabilityW( env, cla, name ));
-	}
-}
-
-JNIEXPORT jint JNICALL
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecute(
-	JNIEnv	*env,
-	jclass	cla,
-	jstring operation,
-	jstring	file,
-	jstring parameters,
-	jstring directory,
-	jint showCmd )
-{
-	if ( non_unicode ){
-		return
-			Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteA(
-				env, cla, operation, file, parameters, directory, showCmd );
-	}else{
-		return
-			Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteW(
-				env, cla, operation, file, parameters, directory, showCmd );
-	}
-}
-
-JNIEXPORT jint JNICALL 
-Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteAndWait(
-	JNIEnv*		env,
-	jclass		cla, 
-	jstring		_command_line, 
-	jstring		_params )
-{
-	if ( non_unicode ){
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecAndWaitA( env, cla, _command_line, _params ));
-	}else{
-		return( Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecAndWaitW( env, cla, _command_line, _params ));
-	}
-}
-
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.dsp b/org/gudy/azureus2/platform/win32/access/impl/aereg.dsp
deleted file mode 100644
index efab1d0..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.dsp
+++ /dev/null
@@ -1,136 +0,0 @@
-# Microsoft Developer Studio Project File - Name="aereg" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=aereg - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE 
-!MESSAGE NMAKE /f "aereg.mak".
-!MESSAGE 
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE 
-!MESSAGE NMAKE /f "aereg.mak" CFG="aereg - Win32 Debug"
-!MESSAGE 
-!MESSAGE Possible choices for configuration are:
-!MESSAGE 
-!MESSAGE "aereg - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "aereg - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE 
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF  "$(CFG)" == "aereg - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AEREG_EXPORTS" /Yu"stdafx.h" /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "C:\JDK1.4\include" /I "C:\JDK1.4\include\win32" /I "C:\j2sdk1.4.2_04\include" /I "C:\j2sdk1.4.2_04\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "UNICODE" /D "_USRDLL" /D "AEREG_EXPORTS" /FR /Yu"stdafx.h" /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x809 /d "NDEBUG"
-# ADD RSC /l 0x809 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib shlwapi.lib Ws2_32.lib /nologo /dll /machine:I386
-
-!ELSEIF  "$(CFG)" == "aereg - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AEREG_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "C:\j2sdk1.4.2_04\include" /I "C:\j2sdk1.4.2_04\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AEREG_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x809 /d "_DEBUG"
-# ADD RSC /l 0x809 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib shlwapi.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-
-!ENDIF 
-
-# Begin Target
-
-# Name "aereg - Win32 Release"
-# Name "aereg - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\aenet.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\aereg.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=.\StdAfx.cpp
-# ADD CPP /Yc"stdafx.h"
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\aenet.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\aereg.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\StdAfx.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# Begin Source File
-
-SOURCE=.\ReadMe.txt
-# End Source File
-# End Target
-# End Project
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.dsw b/org/gudy/azureus2/platform/win32/access/impl/aereg.dsw
deleted file mode 100644
index 3ef397d..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.dsw
+++ /dev/null
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "aereg"=.\aereg.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.h b/org/gudy/azureus2/platform/win32/access/impl/aereg.h
deleted file mode 100644
index 47a4898..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-
-// The following ifdef block is the standard way of creating macros which make exporting 
-// from a DLL simpler. All files within this DLL are compiled with the AEREG_EXPORTS
-// symbol defined on the command line. this symbol should not be defined on any project
-// that uses this DLL. This way any other project whose source files include this file see 
-// AEREG_API functions as being imported from a DLL, wheras this DLL sees symbols
-// defined with this macro as being exported.
-#ifdef AEREG_EXPORTS
-#define AEREG_API __declspec(dllexport)
-#else
-#define AEREG_API __declspec(dllimport)
-#endif
-
-// This class is exported from the aereg.dll
-class AEREG_API CAereg {
-public:
-	CAereg(void);
-	// TODO: add your methods here.
-};
-
-#include <jni.h>
-
-extern void
-throwException(
-	JNIEnv*			env,
-	char*			operation,
-	char*			message );
-
-extern void
-throwException(
-	JNIEnv*			env,
-	char*			operation,
-	char*			message,
-	int				error_code );
-
-extern bool
-jstringToCharsA(
-	JNIEnv		*env,
-	jstring		jstr,
-	char		*chars,
-	int			chars_len );
\ No newline at end of file
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.sln b/org/gudy/azureus2/platform/win32/access/impl/aereg.sln
deleted file mode 100644
index af93b57..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aereg", "aereg.vcproj", "{283DCBCD-6013-4E01-87BC-A105A07AEB50}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{283DCBCD-6013-4E01-87BC-A105A07AEB50}.Debug|Win32.ActiveCfg = Debug|Win32
-		{283DCBCD-6013-4E01-87BC-A105A07AEB50}.Debug|Win32.Build.0 = Debug|Win32
-		{283DCBCD-6013-4E01-87BC-A105A07AEB50}.Release|Win32.ActiveCfg = Release|Win32
-		{283DCBCD-6013-4E01-87BC-A105A07AEB50}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.suo b/org/gudy/azureus2/platform/win32/access/impl/aereg.suo
deleted file mode 100644
index a9c28ae..0000000
Binary files a/org/gudy/azureus2/platform/win32/access/impl/aereg.suo and /dev/null differ
diff --git a/org/gudy/azureus2/platform/win32/access/impl/aereg.vcproj b/org/gudy/azureus2/platform/win32/access/impl/aereg.vcproj
deleted file mode 100644
index e5af36b..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/aereg.vcproj
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="aereg"
-	ProjectGUID="{283DCBCD-6013-4E01-87BC-A105A07AEB50}"
-	RootNamespace="aereg"
-	TargetFrameworkVersion="0"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory=".\Debug"
-			IntermediateDirectory=".\Debug"
-			ConfigurationType="2"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			CharacterSet="0"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="_DEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Debug/aereg.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				UseUnicodeResponseFiles="true"
-				Optimization="0"
-				AdditionalIncludeDirectories=""C:\Program Files\Java\jdk1.6.0_14\include\win32";"C:\Program Files\Java\jdk1.6.0_14\include""
-				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;AEREG_EXPORTS;UNICODE;"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="1"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderThrough="stdafx.h"
-				PrecompiledHeaderFile=".\Debug/aereg.pch"
-				AssemblerListingLocation=".\Debug/"
-				ObjectFile=".\Debug/"
-				ProgramDataBaseFileName=".\Debug/"
-				BrowseInformation="1"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="_DEBUG"
-				Culture="2057"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="Ws2_32.lib odbc32.lib odbccp32.lib shlwapi.lib"
-				OutputFile=".\Debug/aereg.dll"
-				LinkIncremental="2"
-				SuppressStartupBanner="true"
-				GenerateDebugInformation="true"
-				ProgramDatabaseFile=".\Debug/aereg.pdb"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				ImportLibrary=".\Debug/aereg.lib"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-				SuppressStartupBanner="true"
-				OutputFile=".\Debug/aereg.bsc"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory=".\Release"
-			IntermediateDirectory=".\Release"
-			ConfigurationType="2"
-			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
-			UseOfMFC="0"
-			ATLMinimizesCRunTimeLibraryUsage="false"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-				PreprocessorDefinitions="NDEBUG"
-				MkTypLibCompatible="true"
-				SuppressStartupBanner="true"
-				TargetEnvironment="1"
-				TypeLibraryName=".\Release/aereg.tlb"
-				HeaderFileName=""
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				InlineFunctionExpansion="1"
-				AdditionalIncludeDirectories=""C:\Program Files\Java\jdk1.6.0_14\include\win32";"C:\Program Files\Java\jdk1.6.0_14\include""
-				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;AEREG_EXPORTS"
-				StringPooling="true"
-				RuntimeLibrary="0"
-				EnableFunctionLevelLinking="true"
-				UsePrecompiledHeader="2"
-				PrecompiledHeaderThrough="stdafx.h"
-				PrecompiledHeaderFile=".\Release/aereg.pch"
-				AssemblerListingLocation=".\Release/"
-				ObjectFile=".\Release/"
-				ProgramDataBaseFileName=".\Release/"
-				BrowseInformation="1"
-				WarningLevel="3"
-				SuppressStartupBanner="true"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-				PreprocessorDefinitions="NDEBUG"
-				Culture="2057"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLinkerTool"
-				AdditionalDependencies="odbc32.lib odbccp32.lib shlwapi.lib Ws2_32.lib"
-				OutputFile=".\Release/aereg.dll"
-				LinkIncremental="1"
-				SuppressStartupBanner="true"
-				ProgramDatabaseFile=".\Release/aereg.pdb"
-				RandomizedBaseAddress="1"
-				DataExecutionPrevention="0"
-				ImportLibrary=".\Release/aereg.lib"
-				TargetMachine="1"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCManifestTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-				SuppressStartupBanner="true"
-				OutputFile=".\Release/aereg.bsc"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCAppVerifierTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-			>
-			<File
-				RelativePath=".\aedevice.cpp"
-				>
-			</File>
-			<File
-				RelativePath="aenet.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="aereg.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="StdAfx.cpp"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-						UsePrecompiledHeader="1"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						AdditionalIncludeDirectories=""
-						PreprocessorDefinitions=""
-						UsePrecompiledHeader="1"
-					/>
-				</FileConfiguration>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl"
-			>
-			<File
-				RelativePath="aenet.h"
-				>
-			</File>
-			<File
-				RelativePath="aereg.h"
-				>
-			</File>
-			<File
-				RelativePath="org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h"
-				>
-			</File>
-			<File
-				RelativePath="StdAfx.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-			>
-		</Filter>
-		<File
-			RelativePath="ReadMe.txt"
-			>
-		</File>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
diff --git a/org/gudy/azureus2/platform/win32/access/impl/generate_ini.bat b/org/gudy/azureus2/platform/win32/access/impl/generate_ini.bat
deleted file mode 100644
index ed117b2..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/generate_ini.bat
+++ /dev/null
@@ -1 +0,0 @@
-c:\j2sdk1.4.2_04\bin\javah -d . -classpath ..\..\..\..\..\..\.. org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessInterface
\ No newline at end of file
diff --git a/org/gudy/azureus2/platform/win32/access/impl/org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h b/org/gudy/azureus2/platform/win32/access/impl/org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h
deleted file mode 100644
index a59f86b..0000000
--- a/org/gudy/azureus2/platform/win32/access/impl/org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface */
-
-#ifndef _Included_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
-#define _Included_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CLASSES_ROOT
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CLASSES_ROOT 1L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_CONFIG
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_CONFIG 2L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_LOCAL_MACHINE
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_LOCAL_MACHINE 3L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_USER
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_HKEY_CURRENT_USER 4L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_QUERYENDSESSION
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_QUERYENDSESSION 17L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_ENDSESSION
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_ENDSESSION 22L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_POWERBROADCAST
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_WM_POWERBROADCAST 536L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMQUERYSUSPEND
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMQUERYSUSPEND 0L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMSUSPEND
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMSUSPEND 4L
-#undef org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMRESUMESUSPEND
-#define org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_PBT_APMRESUMESUSPEND 7L
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    initialise
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_initialise
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    destroy
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_destroy
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    getVersion
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getVersion
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    readStringValue
- * Signature: (ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readStringValue
-  (JNIEnv *, jclass, jint, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    writeStringValue
- * Signature: (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeStringValue
-  (JNIEnv *, jclass, jint, jstring, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    readWordValue
- * Signature: (ILjava/lang/String;Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_readWordValue
-  (JNIEnv *, jclass, jint, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    writeWordValue
- * Signature: (ILjava/lang/String;Ljava/lang/String;I)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_writeWordValue
-  (JNIEnv *, jclass, jint, jstring, jstring, jint);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    deleteKey
- * Signature: (ILjava/lang/String;Z)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteKey
-  (JNIEnv *, jclass, jint, jstring, jboolean);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    deleteValue
- * Signature: (ILjava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_deleteValue
-  (JNIEnv *, jclass, jint, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    createProcess
- * Signature: (Ljava/lang/String;Z)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_createProcess
-  (JNIEnv *, jclass, jstring, jboolean);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    moveToRecycleBin
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_moveToRecycleBin
-  (JNIEnv *, jclass, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    copyPermission
- * Signature: (Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_copyPermission
-  (JNIEnv *, jclass, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    testNativeAvailability
- * Signature: (Ljava/lang/String;)Z
- */
-JNIEXPORT jboolean JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_testNativeAvailability
-  (JNIEnv *, jclass, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    traceRoute
- * Signature: (IIIILorg/gudy/azureus2/platform/win32/access/impl/AEWin32AccessCallback;)V
- */
-JNIEXPORT void JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_traceRoute
-  (JNIEnv *, jclass, jint, jint, jint, jint, jobject);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    shellExecute
- * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)I
- */
-JNIEXPORT jint JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecute
-  (JNIEnv *, jclass, jstring, jstring, jstring, jstring, jint);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    shellExecuteAndWait
- * Signature: (Ljava/lang/String;Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_shellExecuteAndWait
-  (JNIEnv *, jclass, jstring, jstring);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    getAvailableDrives
- * Signature: ()Ljava/util/List;
- */
-JNIEXPORT jobject JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getAvailableDrives
-  (JNIEnv *, jclass);
-
-/*
- * Class:     org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface
- * Method:    getDriveInfo
- * Signature: (C)Ljava/util/Map;
- */
-JNIEXPORT jobject JNICALL Java_org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface_getDriveInfo
-  (JNIEnv *, jclass, jchar);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/org/gudy/azureus2/plugins/PluginConfig.java b/org/gudy/azureus2/plugins/PluginConfig.java
index 55f7503..a4e6d3e 100644
--- a/org/gudy/azureus2/plugins/PluginConfig.java
+++ b/org/gudy/azureus2/plugins/PluginConfig.java
@@ -68,18 +68,19 @@ public interface
 PluginConfig 
 {  
 	public static final String CORE_PARAM_INT_MAX_UPLOAD_SPEED_KBYTES_PER_SEC			= "Max Upload Speed KBs";
-	public static final String CORE_PARAM_INT_MAX_UPLOAD_SPEED_SEEDING_KBYTES_PER_SEC = "Max Upload Speed When Only Seeding KBs";
+	public static final String CORE_PARAM_INT_MAX_UPLOAD_SPEED_SEEDING_KBYTES_PER_SEC 	= "Max Upload Speed When Only Seeding KBs";
  	public static final String CORE_PARAM_INT_MAX_DOWNLOAD_SPEED_KBYTES_PER_SEC			= "Max Download Speed KBs";
  	public static final String CORE_PARAM_INT_MAX_CONNECTIONS_PER_TORRENT				= "Max Connections Per Torrent";
  	public static final String CORE_PARAM_INT_MAX_CONNECTIONS_GLOBAL					= "Max Connections Global";
  	public static final String CORE_PARAM_INT_MAX_DOWNLOADS								= "Max Downloads";
  	public static final String CORE_PARAM_INT_MAX_ACTIVE								= "Max Active Torrents";
- 	public static final String CORE_PARAM_INT_MAX_ACTIVE_SEEDING				= "Max Active Torrents When Only Seeding";
- 	public static final String CORE_PARAM_INT_MAX_UPLOADS							= "Max Uploads";
- 	public static final String CORE_PARAM_INT_MAX_UPLOADS_SEEDING				= "Max Uploads Seeding";
- 	public static final String CORE_PARAM_BOOLEAN_AUTO_SPEED_ON = "Auto Upload Speed Enabled";
- 	public static final String CORE_PARAM_BOOLEAN_MAX_UPLOAD_SPEED_SEEDING = "Max Upload Speed When Only Seeding Enabled";
- 	public static final String CORE_PARAM_BOOLEAN_MAX_ACTIVE_SEEDING = "Max Active Torrents When Only Seeding Enabled";
+ 	public static final String CORE_PARAM_INT_MAX_ACTIVE_SEEDING						= "Max Active Torrents When Only Seeding";
+ 	public static final String CORE_PARAM_INT_MAX_UPLOADS								= "Max Uploads";
+ 	public static final String CORE_PARAM_INT_MAX_UPLOADS_SEEDING						= "Max Uploads Seeding";
+ 	public static final String CORE_PARAM_BOOLEAN_AUTO_SPEED_ON 						= "Auto Upload Speed Enabled";
+ 	public static final String CORE_PARAM_BOOLEAN_AUTO_SPEED_SEEDING_ON 				= "Auto Upload Speed Seeding Enabled";
+ 	public static final String CORE_PARAM_BOOLEAN_MAX_UPLOAD_SPEED_SEEDING 				= "Max Upload Speed When Only Seeding Enabled";
+ 	public static final String CORE_PARAM_BOOLEAN_MAX_ACTIVE_SEEDING 					= "Max Active Torrents When Only Seeding Enabled";
 	public static final String CORE_PARAM_BOOLEAN_SOCKS_PROXY_NO_INWARD_CONNECTION		= "SOCKS Proxy No Inward Connection";
 	public static final String CORE_PARAM_BOOLEAN_NEW_SEEDS_START_AT_TOP				= "Newly Seeding Torrents Get First Priority";
 	
diff --git a/org/gudy/azureus2/plugins/PluginEvent.java b/org/gudy/azureus2/plugins/PluginEvent.java
index 884d922..c1b36eb 100644
--- a/org/gudy/azureus2/plugins/PluginEvent.java
+++ b/org/gudy/azureus2/plugins/PluginEvent.java
@@ -70,6 +70,10 @@ PluginEvent
 
 	public static final int	PEV_PLUGIN_NOT_OPERATIONAL			= 9;
 
+	public static final int	PEV_PLUGIN_INSTALLED				= 10;	// value is String plugin_id
+	public static final int	PEV_PLUGIN_UPDATED					= 11;	// value is String plugin_id
+	public static final int	PEV_PLUGIN_UNINSTALLED				= 12;	// value is String plugin_id
+
 		/**
 		 * Plugin specific events can be raised by a plugin to communicate with
 		 * other components. The event type must start from the number below
diff --git a/org/gudy/azureus2/plugins/PluginInterface.java b/org/gudy/azureus2/plugins/PluginInterface.java
index a3982f2..43b07b2 100644
--- a/org/gudy/azureus2/plugins/PluginInterface.java
+++ b/org/gudy/azureus2/plugins/PluginInterface.java
@@ -82,17 +82,6 @@ public interface PluginInterface {
 	getAzureusVersion();
 	
   /**
-   * A Plugin might call this method to add a View to Azureus's views
-   * The View will be accessible from View > Plugins > View name
-   * @param view The PluginView to be added
-   *
-   * @since 2.0.4.0
-   *
-   * @deprecated use {@link org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView}
-   */
-  public void addView(PluginView view);
-
-  /**
    * adds a tab under the 'plugins' tab in the config view.<br>
    * Use {@link #getPluginConfigUIFactory()} to get the 
    * {@link PluginConfigUIFactory} class, from which you can create different
@@ -269,6 +258,15 @@ public interface PluginInterface {
   public String getPluginDirectoryName();
   
   /**
+   * gives access to the per-user plugin directory. Useful for shared plugins that need to store
+   * per-user state. Will be same as getPluginDirectoryName for per-user installed plugins
+   * directory may not yet exist 
+   * @return
+   */
+  
+  public String getPerUserPluginDirectoryName();
+  
+  /**
    * Returns the value of "plugin.name" if it exists in the properties file, otherwise the directory name is returned.
    * @since 2.1.0.0
    */
diff --git a/org/gudy/azureus2/plugins/PluginState.java b/org/gudy/azureus2/plugins/PluginState.java
index e03c1c0..30b6e06 100644
--- a/org/gudy/azureus2/plugins/PluginState.java
+++ b/org/gudy/azureus2/plugins/PluginState.java
@@ -80,6 +80,8 @@ public interface PluginState {
 	   */
 	  public boolean isOperational();
 	  
+	  public boolean isInitialisationComplete();
+	  
 	  /**
 	   * Uninstall this plugin if it has been loaded from a plugin directory.
 	   * Deletes the plugin directory.
diff --git a/org/gudy/azureus2/plugins/PluginView.java b/org/gudy/azureus2/plugins/PluginView.java
deleted file mode 100644
index 5b0a711..0000000
--- a/org/gudy/azureus2/plugins/PluginView.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * File    : PluginView.java
- * Created : 2 nov. 2003 20:58:14
- * By      : Olivier 
- * 
- * 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.plugins;
-
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-
-/**
- * This Class must be extended by Plugin willing to have their own view in Azureus
- * @author Olivier
- * @deprecated 
- */
-public abstract class PluginView extends AbstractIView {
-  
-
-  /**
-   * @return The name of the Plugin, as seen in the View > Plugins menu
-   *
-   * @since 2.0.4.0
-   */	
-  public abstract String getPluginViewName();
-
-}
diff --git a/org/gudy/azureus2/plugins/clientid/ClientIDGenerator.java b/org/gudy/azureus2/plugins/clientid/ClientIDGenerator.java
index cb77b05..28bc82a 100644
--- a/org/gudy/azureus2/plugins/clientid/ClientIDGenerator.java
+++ b/org/gudy/azureus2/plugins/clientid/ClientIDGenerator.java
@@ -35,6 +35,7 @@ public interface
 ClientIDGenerator 
 {
 	public static final String PR_URL			= "URL";			// in/out, the target URL
+	public static final String PR_RAW_REQUEST	= "Raw-Request";	// in, Boolean
 	public static final String PR_USER_AGENT	= "User-Agent";		// out
 	
 		/**
diff --git a/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java b/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
index c89ffbe..839878f 100644
--- a/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
+++ b/org/gudy/azureus2/plugins/ddb/DistributedDatabase.java
@@ -42,6 +42,11 @@ DistributedDatabase
 	public static final byte	DT_FREQUENCY	= 2;
 	public static final byte	DT_SIZE			= 3;
 	
+		// dht types
+	
+	public static final int	DHT_MAIN	= 1;
+	public static final int	DHT_CVS		= 2;
+	
 	public boolean
 	isAvailable();
 
@@ -84,6 +89,14 @@ DistributedDatabase
 	
 		throws DistributedDatabaseException;
 	
+	public DistributedDatabaseContact
+	importContact(
+		InetSocketAddress				address,
+		byte							protocol_version,
+		int								preferred_dht )
+	
+		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 903fbe2..1a88ab3 100644
--- a/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java
+++ b/org/gudy/azureus2/plugins/ddb/DistributedDatabaseContact.java
@@ -32,12 +32,18 @@ import java.net.InetSocketAddress;
 public interface 
 DistributedDatabaseContact 
 {
+	public byte[]
+	getID();
+	
 	public String
 	getName();
 	
 	public InetSocketAddress
 	getAddress();
 	
+	public int
+	getDHT();
+	
 	public boolean
 	isAlive(
 		long		timeout );
diff --git a/org/gudy/azureus2/plugins/disk/DiskManager.java b/org/gudy/azureus2/plugins/disk/DiskManager.java
index 0d55b0b..bd01d45 100644
--- a/org/gudy/azureus2/plugins/disk/DiskManager.java
+++ b/org/gudy/azureus2/plugins/disk/DiskManager.java
@@ -21,6 +21,8 @@
 
 package org.gudy.azureus2.plugins.disk;
 
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+
 /**
  * @author parg
  *
@@ -29,4 +31,33 @@ package org.gudy.azureus2.plugins.disk;
 public interface 
 DiskManager 
 {
+	public static final int	BLOCK_SIZE	= 16384;
+
+	public DiskManagerReadRequest
+	read(
+		int								piece_number,
+		int								offset,
+		int								length,
+		DiskManagerReadRequestListener	listener )
+	
+		throws DiskManagerException;
+	
+		/**
+		 * Data length has to be consistent with block layout of the piece and piece size
+		 * @param piece_number
+		 * @param offset
+		 * @param data
+		 * @param listener
+		 * @return
+		 * @throws DiskManagerException
+		 */
+	
+	public DiskManagerWriteRequest
+	write(
+		int								piece_number,
+		int								offset,
+		PooledByteBuffer				data,
+		DiskManagerWriteRequestListener	listener )
+	
+		throws DiskManagerException;
 }
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerChannel.java b/org/gudy/azureus2/plugins/disk/DiskManagerChannel.java
index ece3903..dcf7983 100644
--- a/org/gudy/azureus2/plugins/disk/DiskManagerChannel.java
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerChannel.java
@@ -31,6 +31,12 @@ DiskManagerChannel
 	public DiskManagerFileInfo
 	getFile();
 	
+	public long
+	getPosition();
+	
+	public boolean
+	isDestroyed();
+	
 	public void
 	destroy();
 }
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerEvent.java b/org/gudy/azureus2/plugins/disk/DiskManagerEvent.java
index 197b038..bf30fbe 100644
--- a/org/gudy/azureus2/plugins/disk/DiskManagerEvent.java
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerEvent.java
@@ -33,10 +33,7 @@ DiskManagerEvent
 	
 	public int
 	getType();
-	
-	public DiskManagerRequest
-	getRequest();
-	
+		
 	public long
 	getOffset();
 	
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerException.java b/org/gudy/azureus2/plugins/disk/DiskManagerException.java
new file mode 100644
index 0000000..6e3760d
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerException.java
@@ -0,0 +1,48 @@
+/*
+ * File    : DownloadException.java
+ * Created : 08-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 org.gudy.azureus2.plugins.disk;
+
+/** Throws by various Download methods to indicate errors
+ *
+ * @author parg
+ * @since 2.0.7.0
+ */
+
+public class 
+DiskManagerException 
+	extends Exception
+{
+	public
+	DiskManagerException(
+			String	str )
+	{
+		super(str);
+	}
+	
+	public
+	DiskManagerException(
+		String		str,
+		Throwable 	cause )
+	{
+		super(str,cause);
+	}
+}
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerFileInfo.java b/org/gudy/azureus2/plugins/disk/DiskManagerFileInfo.java
index 81112ec..9c027dc 100644
--- a/org/gudy/azureus2/plugins/disk/DiskManagerFileInfo.java
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerFileInfo.java
@@ -44,6 +44,15 @@ DiskManagerFileInfo
 	setPriority(
 		boolean b );
 	
+		/**
+		 * @since 4407
+		 * @param priority
+		 */
+	
+	public void
+	setNumericPriority(
+		int		priority );
+	
 	public void 
 	setSkipped(
 		boolean b );
@@ -77,12 +86,26 @@ DiskManagerFileInfo
 	public long 
 	getDownloaded();
 	
+	/**
+	 * Size when file is complete
+	 */
 	public long
 	getLength();
 	
 	public File 
 	getFile();
-		
+	
+		/**
+		 * returns liked file if it exists, direct otherwise
+		 * @param follow_link
+		 * @return
+		 * @since 4.3.1.5
+		 */
+	
+	public File
+	getFile(
+		boolean	follow_link );
+	
 	public int
 	getIndex();
 	
@@ -98,6 +121,14 @@ DiskManagerFileInfo
 	public boolean 
 	isPriority();
 	
+		/**
+		 * @since 4407
+		 * @return
+		 */
+	
+	public int
+	getNumericPriorty();
+	
 	public boolean 
 	isSkipped();
 	
@@ -118,4 +149,24 @@ DiskManagerFileInfo
 	createChannel()
 	
 		throws DownloadException;
+	
+		/**
+		 * Creates a random read request - these will be executed against the download 
+		 * sequentially
+		 * @param file_offset
+		 * @param length
+		 * @param reverse_order	- deliver blocks to the listener in reverse order
+		 * @param listener
+		 * @return
+		 * @throws DownloadException
+		 */
+	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException;
 }
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerRandomReadRequest.java b/org/gudy/azureus2/plugins/disk/DiskManagerRandomReadRequest.java
new file mode 100644
index 0000000..e5542cb
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerRandomReadRequest.java
@@ -0,0 +1,41 @@
+/*
+ * Created on Oct 10, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.disk;
+
+public interface 
+DiskManagerRandomReadRequest 
+{
+	public DiskManagerFileInfo
+	getFile();
+	
+	public long
+	getOffset();
+	
+	public long
+	getLength();
+	
+	public boolean
+	isReverse();
+	
+	public void
+	cancel();
+}
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerReadRequest.java b/org/gudy/azureus2/plugins/disk/DiskManagerReadRequest.java
new file mode 100644
index 0000000..b5a32cb
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerReadRequest.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Feb 5, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.disk;
+
+public interface 
+DiskManagerReadRequest 
+{
+	public int
+	getPieceNumber();
+	
+	public int
+	getOffset();
+	
+	public int
+	getLength();
+}
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerReadRequestListener.java b/org/gudy/azureus2/plugins/disk/DiskManagerReadRequestListener.java
new file mode 100644
index 0000000..c7fa7a5
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerReadRequestListener.java
@@ -0,0 +1,38 @@
+/*
+ * Created on Feb 5, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.disk;
+
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+
+public interface 
+DiskManagerReadRequestListener 
+{
+	public void
+	complete(
+		DiskManagerReadRequest		request,
+		PooledByteBuffer			buffer );
+	
+	public void
+	failed(
+		DiskManagerReadRequest		request,
+		DiskManagerException		error );
+}
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerRequest.java b/org/gudy/azureus2/plugins/disk/DiskManagerRequest.java
index 6132479..6e7cb24 100644
--- a/org/gudy/azureus2/plugins/disk/DiskManagerRequest.java
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerRequest.java
@@ -62,6 +62,11 @@ DiskManagerRequest
 	public void
 	cancel();
 	
+		/**
+		 * Beware that invoking this method signifies that the media is being streamed and therefore may undergo transformations such as MOOV atom relocation in mp4s
+		 * @param agent
+		 */
+	
 	public void
 	setUserAgent(
 		String		agent );
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequest.java b/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequest.java
new file mode 100644
index 0000000..328d26a
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequest.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Feb 5, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.disk;
+
+public interface 
+DiskManagerWriteRequest 
+{
+	public int
+	getPieceNumber();
+	
+	public int
+	getOffset();
+	
+	public int
+	getLength();
+}
diff --git a/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequestListener.java b/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequestListener.java
new file mode 100644
index 0000000..f0b5e80
--- /dev/null
+++ b/org/gudy/azureus2/plugins/disk/DiskManagerWriteRequestListener.java
@@ -0,0 +1,35 @@
+/*
+ * Created on Feb 5, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.disk;
+
+public interface 
+DiskManagerWriteRequestListener 
+{
+	public void
+	complete(
+		DiskManagerWriteRequest		request );
+	
+	public void
+	failed(
+		DiskManagerWriteRequest		request,
+		DiskManagerException		error );
+}
diff --git a/org/gudy/azureus2/plugins/download/Download.java b/org/gudy/azureus2/plugins/download/Download.java
index 68f3295..bf7cb11 100644
--- a/org/gudy/azureus2/plugins/download/Download.java
+++ b/org/gudy/azureus2/plugins/download/Download.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
 import org.gudy.azureus2.plugins.disk.DiskManager;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.peers.PeerManager;
 
 /**
@@ -156,6 +157,28 @@ Download extends DownloadEventNotifier
      */
     public static final long FLAG_DO_NOT_DELETE_DATA_ON_REMOVE = 0x00000040;
     
+    /**
+     * Force direct delete of download data when delete requested, rather than recoverable delete,
+     * and no user prompt
+     * @since 4.3.1.5
+     */
+    
+    public static final long FLAG_FORCE_DIRECT_DELETE = 0x00000080;
+    
+    /**
+     * Used to disable IP filter rules for a download when ip-filtering is enabled
+     * @since 4.7.0.3
+     */
+    
+    public static final long FLAG_DISABLE_IP_FILTER = 0x00000100;
+
+    /**
+     * @since 4.7.0.4 indicates that the download is just a metadata downloader and not a 'real' one (yet)
+     */
+    
+    public static final long FLAG_METADATA_DOWNLOAD = 0x00000200;
+
+    
 	/** get state from above ST_ set
    * @return ST_ constant
    *
@@ -647,7 +670,7 @@ Download extends DownloadEventNotifier
 	public DownloadStats
 	getStats();
 	
-	/** Downloads can be persistent (be remembered accross Azureus sessions), or
+	/** Downloads can be persistent (be remembered across Azureus sessions), or
 	 * non-persistent.
 	 *
 	 * @return true - persistent<br>
@@ -704,6 +727,22 @@ Download extends DownloadEventNotifier
     public void setDownloadRateLimitBytesPerSecond( int max_rate_bps );
   
 
+    	/**
+    	 * @since 4.7.0.3
+    	 * @param limiter		create via ConnectionManager
+    	 * @param is_upload		false -> download limit
+    	 */
+    
+    public void
+    addRateLimiter(
+    	RateLimiter		limiter,
+    	boolean			is_upload );
+    	
+    public void
+    removeRateLimiter(
+    	RateLimiter		limiter,
+    	boolean			is_upload );
+    
 	/**
 	 * Indicates if the download has completed or not, exluding any files marked
 	 * as Do No Download
@@ -734,6 +773,14 @@ Download extends DownloadEventNotifier
 	public boolean
  	isChecking();
 	
+		/**
+		 * Returns true if the download is currently in the process of having its datafiles moved
+		 * @return
+		 */
+	
+	public boolean
+	isMoving();
+
 	/**
 	 * This returns the full save path for the download. If the download is a simple torrent,
 	 * this will be the full path of the file being downloaded. If the download is a multiple
@@ -742,6 +789,7 @@ Download extends DownloadEventNotifier
 	 * 
 	 * @return Full save path for this download.
 	 */
+		
   	public String
 	getSavePath();
   	
@@ -843,6 +891,23 @@ Download extends DownloadEventNotifier
 	public DiskManagerFileInfo[]
 	getDiskManagerFileInfo();
 	
+	/**
+	 * Returns file info for the given index. Note that this will return "stub" values if the 
+	 * download isn't running (not including info such as completion status)
+	 * @return null if index is invalid
+	 * @since 4.3.1.5
+	 */
+
+  public DiskManagerFileInfo
+  getDiskManagerFileInfo(int index);
+
+  /**
+   * Return the number of DiskManagerFile objects
+   * @return
+   * @since 4.6.0.5
+   */
+	public int getDiskManagerFileCount();
+
   		/**
   		 * request a tracker announce 
   		 * @since 2.1.0.5
@@ -1031,5 +1096,6 @@ Download extends DownloadEventNotifier
    * @since 3.0.5.3
    */
   public void stopDownload();
+
   
 }
diff --git a/org/gudy/azureus2/plugins/download/DownloadManager.java b/org/gudy/azureus2/plugins/download/DownloadManager.java
index 1431de8..0ea3c18 100644
--- a/org/gudy/azureus2/plugins/download/DownloadManager.java
+++ b/org/gudy/azureus2/plugins/download/DownloadManager.java
@@ -190,6 +190,24 @@ DownloadManager
 	
 		throws DownloadException;
 	
+	public Download
+	addNonPersistentDownloadStopped(
+		Torrent		torrent,
+		File		torrent_location,
+		File		data_location )
+	
+		throws DownloadException;
+	
+	/**
+	 * Although non-persistent downloads themselves aren't rememebered across restarts, some internal stats
+	 * are (for continuity, like total up/down, file allocation state) - this method allows this to be removed
+	 * @param hash
+	 */
+	
+	public void
+	clearNonPersistentDownloadState(
+		byte[]		hash );
+		
 	/**
 	 * Gets the download for a particular torrent, returns null if not found
 	 * @param torrent
diff --git a/org/gudy/azureus2/plugins/download/DownloadStats.java b/org/gudy/azureus2/plugins/download/DownloadStats.java
index d64876a..d6e8531 100644
--- a/org/gudy/azureus2/plugins/download/DownloadStats.java
+++ b/org/gudy/azureus2/plugins/download/DownloadStats.java
@@ -129,7 +129,16 @@ DownloadStats
 	public int
 	getCheckingDoneInThousandNotation();
 
+	/*
+	 * resets totals. stops and restarts torrent if running to do so
+	 * @since 4511. Supply -1 to leave a value unchanged
+	 */
 
+	public void
+	resetUploadedDownloaded(
+		long		new_up,
+		long		new_down );
+	
 	/**
 	 * Gives the number of bytes downloaded
 	 * @return
diff --git a/org/gudy/azureus2/plugins/download/savelocation/DefaultSaveLocationManager.java b/org/gudy/azureus2/plugins/download/savelocation/DefaultSaveLocationManager.java
index 0738235..ccf6b17 100644
--- a/org/gudy/azureus2/plugins/download/savelocation/DefaultSaveLocationManager.java
+++ b/org/gudy/azureus2/plugins/download/savelocation/DefaultSaveLocationManager.java
@@ -26,5 +26,6 @@ import org.gudy.azureus2.plugins.download.Download;
  * <p><b>Note:</b> Only for implementation by Azureus, not plugins.</p>
  */
 public interface DefaultSaveLocationManager extends SaveLocationManager {
+	public SaveLocationChange testOnCompletion(Download download, boolean for_move, boolean on_event);
 	public boolean isInDefaultSaveDir(Download d);
 }
diff --git a/org/gudy/azureus2/plugins/installer/PluginInstaller.java b/org/gudy/azureus2/plugins/installer/PluginInstaller.java
index f366969..9faeed9 100644
--- a/org/gudy/azureus2/plugins/installer/PluginInstaller.java
+++ b/org/gudy/azureus2/plugins/installer/PluginInstaller.java
@@ -27,6 +27,7 @@ import java.util.Map;
 
 import org.gudy.azureus2.plugins.PluginException;
 import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
 
 /**
  * @author parg
@@ -77,7 +78,7 @@ PluginInstaller
 	
 		throws PluginException;
 	
-	public void
+	public UpdateCheckInstance
 	install(
 		InstallablePlugin[]			plugins,
 		boolean						shared,
@@ -113,6 +114,12 @@ PluginInstaller
 	uninstall(
 		PluginInterface[]	plugin_interfaces )
 	
+		throws PluginException;
+	
+	public void
+	uninstall(
+		PluginInterface[]			plugin_interfaces,
+		PluginInstallationListener	listener )
 	
 		throws PluginException;
 	
diff --git a/org/gudy/azureus2/plugins/logging/LoggerChannel.java b/org/gudy/azureus2/plugins/logging/LoggerChannel.java
index 6bb474e..ae55bf1 100644
--- a/org/gudy/azureus2/plugins/logging/LoggerChannel.java
+++ b/org/gudy/azureus2/plugins/logging/LoggerChannel.java
@@ -74,6 +74,21 @@ public interface LoggerChannel {
 	public void setDiagnostic( long max_file_size, boolean timestamp );
 
 	/**
+	 * logging to file is disabled by default in non-beta builds. This forces writing to file
+	 * regardless
+	 * @param force_to_file
+	 * @since 4401
+	 */
+	public void setForce( boolean force_to_file );
+
+	/**
+	 * @since 4401
+	 * @return
+	 */
+	
+	public boolean getForce();
+	
+	/**
 	 * Log a message of a specific type to this channel's logger
 	 * 
 	 * @param log_type LT_* constant
diff --git a/org/gudy/azureus2/plugins/messaging/bittorrent/BTMessageManager.java b/org/gudy/azureus2/plugins/messaging/bittorrent/BTMessageManager.java
index 20a5b22..fe7fd17 100644
--- a/org/gudy/azureus2/plugins/messaging/bittorrent/BTMessageManager.java
+++ b/org/gudy/azureus2/plugins/messaging/bittorrent/BTMessageManager.java
@@ -96,8 +96,29 @@ public class BTMessageManager {
     return null;
   }
   
-
-  
+  public static MessageAdapter
+  wrapCoreMessage(
+	 BTMessage		core_msg )
+  {
+	  String	id = core_msg.getID();
+	  
+	  if ( id.equals( BTMessage.ID_BT_REQUEST )){
+		   
+		  return new BTMessageRequest( core_msg );
+		  
+	  }else if ( id.equals( BTMessage.ID_BT_CANCEL )){
+		   
+		  return new BTMessageCancel( core_msg );
+		  
+	  }else if ( id.equals( BTMessage.ID_BT_PIECE )){
+		   
+		  return new BTMessagePiece( core_msg );
+		  
+	  }else{
+		  
+		  return( new MessageAdapter( core_msg ));
+	  }
+  }
   
   /**
    * Create a core BT Request message instance.
diff --git a/org/gudy/azureus2/plugins/network/ConnectionManager.java b/org/gudy/azureus2/plugins/network/ConnectionManager.java
index 83c93e1..8f233b0 100644
--- a/org/gudy/azureus2/plugins/network/ConnectionManager.java
+++ b/org/gudy/azureus2/plugins/network/ConnectionManager.java
@@ -63,4 +63,13 @@ ConnectionManager
    */
   public TransportFilter createTransportFilter(Connection connection, TransportCipher read_cipher, TransportCipher write_cipher) throws TransportException;
   
+  /**
+   * @since 4.7.0.3
+   */
+  
+  public RateLimiter
+  createRateLimiter(
+	 String		name,
+	 int		bytes_per_second );
+  
 }
diff --git a/org/gudy/azureus2/plugins/network/ConnectionStub.java b/org/gudy/azureus2/plugins/network/ConnectionStub.java
new file mode 100644
index 0000000..65f92a7
--- /dev/null
+++ b/org/gudy/azureus2/plugins/network/ConnectionStub.java
@@ -0,0 +1,36 @@
+/*
+ * Created on May 25, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.network;
+
+public interface 
+ConnectionStub 
+{
+	  public void
+	  addRateLimiter(
+		  RateLimiter		limiter,
+		  boolean			is_upload );
+
+	  public void
+	  removeRateLimiter(
+		  RateLimiter		limiter,
+		  boolean			is_upload );
+}
diff --git a/org/gudy/azureus2/plugins/network/IncomingMessageQueue.java b/org/gudy/azureus2/plugins/network/IncomingMessageQueue.java
index 4f8c3aa..8f144cc 100644
--- a/org/gudy/azureus2/plugins/network/IncomingMessageQueue.java
+++ b/org/gudy/azureus2/plugins/network/IncomingMessageQueue.java
@@ -36,6 +36,12 @@ public interface IncomingMessageQueue {
    */
   public void registerListener( IncomingMessageQueueListener listener );
   
+  /**
+   * Register queue listener that will get to process messages *ahead* of the core.
+   * @param listener
+   */
+  public void registerPriorityListener( IncomingMessageQueueListener listener );
+
   
   /**
    * Remove registration of queue listener.
diff --git a/org/gudy/azureus2/plugins/network/OutgoingMessageQueue.java b/org/gudy/azureus2/plugins/network/OutgoingMessageQueue.java
index 74d35f0..eebb1d7 100644
--- a/org/gudy/azureus2/plugins/network/OutgoingMessageQueue.java
+++ b/org/gudy/azureus2/plugins/network/OutgoingMessageQueue.java
@@ -62,4 +62,10 @@ public interface OutgoingMessageQueue {
   public void notifyOfExternalSend( Message message );  
   
   public int getPercentDoneOfCurrentMessage();
+  
+  public int getDataQueuedBytes();
+  
+  public int getProtocolQueuedBytes();
+  
+  public boolean isBlocked();
 }
diff --git a/org/gudy/azureus2/plugins/network/RateLimiter.java b/org/gudy/azureus2/plugins/network/RateLimiter.java
index 6bc6945..c504fa6 100644
--- a/org/gudy/azureus2/plugins/network/RateLimiter.java
+++ b/org/gudy/azureus2/plugins/network/RateLimiter.java
@@ -21,12 +21,12 @@
 
 package org.gudy.azureus2.plugins.network;
 
-import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
-
 public interface 
 RateLimiter 
-	extends LimitedRateGroup
 {
+	public String
+	getName();
+	
 	/**
 	 * Get rate limit. 0 -> unlimited, -1 -> disabled
 	 * @return
@@ -34,4 +34,8 @@ RateLimiter
 	
 	public int 
 	getRateLimitBytesPerSecond();
+	
+	public void
+	setRateLimitBytesPerSecond(
+		int		bytes_per_second );
 }
diff --git a/org/gudy/azureus2/plugins/package.html b/org/gudy/azureus2/plugins/package.html
deleted file mode 100644
index d21670e..0000000
--- a/org/gudy/azureus2/plugins/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<body>
-Provides interfaces in order to create Azureus Plugins.
-<br><br>
-
-For non API information about developing plugins for Azureus, visit the Wiki at
-<a href="http://azureuswiki.com/index.php/Plugin_development">Plugin Documentation</A>
-</body>
\ No newline at end of file
diff --git a/org/gudy/azureus2/plugins/peers/Peer.java b/org/gudy/azureus2/plugins/peers/Peer.java
index 62d6966..a817afd 100644
--- a/org/gudy/azureus2/plugins/peers/Peer.java
+++ b/org/gudy/azureus2/plugins/peers/Peer.java
@@ -31,6 +31,8 @@ import java.util.List;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.plugins.messaging.Message;
 import org.gudy.azureus2.plugins.network.Connection;
+import org.gudy.azureus2.plugins.network.ConnectionStub;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 
 
 public interface 
@@ -43,7 +45,12 @@ Peer
 	public final static int DISCONNECTED 	= PEPeer.DISCONNECTED;
   
 
-	public final static Object PR_PRIORITY_CONNECTION = new Object();
+	public final static Object PR_PRIORITY_CONNECTION 	= new Object();
+	public final static Object PR_PROTOCOL				= new Object();
+	
+	public void
+	bindConnection(
+		ConnectionStub		stub );
 	
 	public PeerManager
 	getManager();
@@ -261,4 +268,20 @@ Peer
   public void
   setPriorityConnection(
 		boolean		is_priority );
+  
+	  /**
+	   * @since 4.7.0.3
+	   * @param limiter		create via ConnectionManager
+	   * @param is_upload		false -> download limit
+	   */
+
+  public void
+  addRateLimiter(
+		  RateLimiter		limiter,
+		  boolean			is_upload );
+
+  public void
+  removeRateLimiter(
+		  RateLimiter		limiter,
+		  boolean			is_upload );
 }
diff --git a/org/gudy/azureus2/plugins/peers/PeerDescriptor.java b/org/gudy/azureus2/plugins/peers/PeerDescriptor.java
index a3ba135..4875ac0 100644
--- a/org/gudy/azureus2/plugins/peers/PeerDescriptor.java
+++ b/org/gudy/azureus2/plugins/peers/PeerDescriptor.java
@@ -36,4 +36,12 @@ PeerDescriptor
 	
 	public boolean
 	useCrypto();
+	
+		/**
+		 * source as defined in DownloadAnnounceResultPeer
+		 * @return
+		 */
+	
+	public String
+	getPeerSource();
 }
diff --git a/org/gudy/azureus2/plugins/peers/PeerManagerEvent.java b/org/gudy/azureus2/plugins/peers/PeerManagerEvent.java
index ae4e043..081d2a6 100644
--- a/org/gudy/azureus2/plugins/peers/PeerManagerEvent.java
+++ b/org/gudy/azureus2/plugins/peers/PeerManagerEvent.java
@@ -29,6 +29,9 @@ PeerManagerEvent
 	public static final int ET_PEER_DISCOVERED		= 3;		// getPeerDescriptor; opt getPeer if discovered from a Peer
 	public static final int ET_PEER_SENT_BAD_DATA	= 4;		// getPeer; getData -> Integer piece number
 
+	public static final int ET_PIECE_ACTIVATED			= 5;		// opt getPeer; getData -> Piece object
+	public static final int ET_PIECE_DEACTIVATED		= 6;		// getData -> Piece object
+	public static final int ET_PIECE_COMPLETION_CHANGED	= 7;		// getData -> Piece object
 	
 	public PeerManager
 	getPeerManager();
diff --git a/org/gudy/azureus2/plugins/peers/PeerManagerStats.java b/org/gudy/azureus2/plugins/peers/PeerManagerStats.java
index a106560..2dd9de0 100644
--- a/org/gudy/azureus2/plugins/peers/PeerManagerStats.java
+++ b/org/gudy/azureus2/plugins/peers/PeerManagerStats.java
@@ -55,4 +55,52 @@ PeerManagerStats
 	
 	public long
 	getHashFailBytes();
+	
+		// rate controls
+	
+	/**
+	 * For an external process receiving bytes on behalf of this download this gives the current
+	 * rate-limited number of bytes that can be received. Update with actual send using 'received' below.
+	 * @since 4.4.0.7 
+	 * @return
+	 */
+	
+	public int getPermittedBytesToReceive();
+	
+	/**
+	 * The given number of data (payload) bytes have been received.
+	 * This number gets added to the total and is used to calculate the rate.
+	 * <p>
+	 * Use this if you are talking to stuff outside of Azureus' API, and
+	 * want your stats added into Azureus'
+	 * 
+	 * @param bytes
+	 * 
+	 *@since 4.4.0.7 
+	 */
+	
+	public void permittedReceiveBytesUsed(int bytes);
+
+	/**
+	 * For an external process sending bytes on behalf of this download this gives the current
+	 * rate-limited number of bytes that can be sent. Update with actual send using 'sent' below.
+	 * @since 4.4.0.7 
+	 * @return
+	 */
+	
+	public int getPermittedBytesToSend();
+	
+	/**
+	 * The given number of data (payload) bytes have been sent.
+	 * This number gets added to the total and is used to calculate the rate.
+	 * <p>
+	 * Use this if you are talking to stuff outside of Azureus' API, and
+	 * want your stats added into Azureus'
+	 * 
+	 * @param bytes
+	 * 
+	 * @since 4.4.0.7
+	 */
+		
+	public void permittedSendBytesUsed(int bytes);
 }
diff --git a/org/gudy/azureus2/plugins/peers/PeerReadRequest.java b/org/gudy/azureus2/plugins/peers/PeerReadRequest.java
index 2d4f311..bb61d32 100644
--- a/org/gudy/azureus2/plugins/peers/PeerReadRequest.java
+++ b/org/gudy/azureus2/plugins/peers/PeerReadRequest.java
@@ -21,6 +21,8 @@
 
 package org.gudy.azureus2.plugins.peers;
 
+import org.gudy.azureus2.plugins.disk.DiskManager;
+
 /**
  * @author parg
  *
@@ -30,7 +32,7 @@ package org.gudy.azureus2.plugins.peers;
 public interface 
 PeerReadRequest 
 {
-	public static final int	NORMAL_REQUEST_SIZE	= 16384;
+	public static final int	NORMAL_REQUEST_SIZE	= DiskManager.BLOCK_SIZE;
 	
 	public int
 	getPieceNumber();
diff --git a/org/gudy/azureus2/plugins/peers/PeerStats.java b/org/gudy/azureus2/plugins/peers/PeerStats.java
index 8ee7f07..6821203 100644
--- a/org/gudy/azureus2/plugins/peers/PeerStats.java
+++ b/org/gudy/azureus2/plugins/peers/PeerStats.java
@@ -94,6 +94,43 @@ public interface PeerStats
 	 */
 	public int getStatisticSentAverage();
 
+	
+	/**
+	 * For an external process receiving bytes on behalf of this peer this gives the current
+	 * rate-limited number of bytes that can be received. Update with actual send using 'permittedReceiveBytesUsed' below.
+	 * @since 4.4.0.7 
+	 * @return
+	 */
+	
+	public int getPermittedBytesToReceive();
+	
+	public void permittedReceiveBytesUsed( int bytes );
+
+	/**
+	 * For an external process sending bytes on behalf of this peer this gives the current
+	 * rate-limited number of bytes that can be sent. Update with actual send using 'sent' below.
+	 * @since 4.4.0.7 
+	 * @return
+	 */
+	
+	public int getPermittedBytesToSend();
+	
+	public void permittedSendBytesUsed( int bytes );
+
+	/**
+	 * The given number of data (payload) bytes have been sent to the peer.
+	 * This number gets added to the total and is used to calculate the rate.
+	 * <p>
+	 * Use this if you are talking to the peer outside of Azureus' API, and
+	 * want your stats added into Azureus'
+	 * 
+	 * @param bytes
+	 * 
+	 * @since 4.4.0.7
+	 */
+		
+	public void received(int bytes);
+
 	/**
 	 * The given number of data (payload) bytes have been received from the peer.
 	 * This number gets added to the total and is used to calculate the rate.
@@ -105,8 +142,9 @@ public interface PeerStats
 	 * 
 	 * @since 2.1.0.0
 	 */
-	public void received(int bytes);
 
+	public void sent(int bytes);
+	
 	/**
 	 * The given number of bytes received from the peer were discarded.
 	 * This number gets added to the total and is used to calculate rates that
@@ -137,4 +175,28 @@ public interface PeerStats
 	
 	public int
 	getDownloadRateLimit();
+	
+	/**
+	 * @since 4.7.0.1
+	 * @param bytes_per_sec
+	 */
+	
+	public void
+	setUploadRateLimit(
+		int	bytes_per_sec );
+	
+	/**
+	 * @since 4.7.0.1
+	 * @param bytes_per_sec
+	 */
+	
+	public int
+	getUploadRateLimit();
+	
+	/**
+	 * @since 4.4.0.1
+	 * @return
+	 */
+	public long
+	getOverallBytesRemaining();
 }
diff --git a/org/gudy/azureus2/plugins/peers/Piece.java b/org/gudy/azureus2/plugins/peers/Piece.java
index 91dd0ed..4e365a9 100644
--- a/org/gudy/azureus2/plugins/peers/Piece.java
+++ b/org/gudy/azureus2/plugins/peers/Piece.java
@@ -25,6 +25,12 @@ package org.gudy.azureus2.plugins.peers;
 public interface 
 Piece 
 {
+	public int
+	getIndex();
+	
+	public int
+	getLength();
+	
 	public boolean
 	isDone();
 	
@@ -50,4 +56,21 @@ Piece
 	
 	public int
 	getAllocatableRequestCount();
+	
+		/**
+		 * Reserve this peice for a given peer - no other peer will be asked for the piece
+		 * @return
+		 */
+	
+	public Peer
+	getReservedFor();
+	
+		/**
+		 * Set the peer that will be responsible for downloading the piece
+		 * @param peer
+		 */
+	
+	public void
+	setReservedFor(
+		Peer	peer );
 }
diff --git a/org/gudy/azureus2/plugins/sharing/ShareManager.java b/org/gudy/azureus2/plugins/sharing/ShareManager.java
index 44656ad..c40a2ba 100644
--- a/org/gudy/azureus2/plugins/sharing/ShareManager.java
+++ b/org/gudy/azureus2/plugins/sharing/ShareManager.java
@@ -27,10 +27,13 @@ package org.gudy.azureus2.plugins.sharing;
  */
 
 import java.io.File;
+import java.util.Map;
 
 public interface 
 ShareManager 
 {
+	public static final String	PR_PERSONAL		= "personal";		// "true"/"false"
+	
 	public void
 	initialise()
 	
@@ -58,12 +61,26 @@ ShareManager
 	
 		throws ShareException, ShareResourceDeletionVetoException;
 	
+	public ShareResourceFile
+	addFile(
+		File				file,
+		Map<String,String>	properties )
+	
+		throws ShareException, ShareResourceDeletionVetoException;
+
 	public ShareResourceDir
 	addDir(
 		File	dir )
 	
 		throws ShareException, ShareResourceDeletionVetoException;
 	
+	public ShareResourceDir
+	addDir(
+		File				dir,
+		Map<String,String>	properties )
+	
+		throws ShareException, ShareResourceDeletionVetoException;
+	
 	public ShareResourceDirContents
 	addDirContents(
 		File	dir,
@@ -71,6 +88,14 @@ ShareManager
 	
 		throws ShareException, ShareResourceDeletionVetoException;
 	
+	public ShareResourceDirContents
+	addDirContents(
+		File				dir,
+		boolean				recursive,
+		Map<String,String>	properties )
+	
+		throws ShareException, ShareResourceDeletionVetoException;
+	
 	/**
 	 * adding shares can take a long time due to the torrent creation process. The current
 	 * activity can be interrupted by calling this function, in which case the original 
diff --git a/org/gudy/azureus2/plugins/tracker/web/TrackerAuthenticationAdapter.java b/org/gudy/azureus2/plugins/tracker/web/TrackerAuthenticationAdapter.java
index 7cc5bd9..7e882b3 100644
--- a/org/gudy/azureus2/plugins/tracker/web/TrackerAuthenticationAdapter.java
+++ b/org/gudy/azureus2/plugins/tracker/web/TrackerAuthenticationAdapter.java
@@ -42,6 +42,24 @@ TrackerAuthenticationAdapter
 		return( false );
 	}
 
+		/**
+		 * Hack to support header-based auth - not included in listener for compatibility reasons
+		 * @param headers
+		 * @param resource
+		 * @param user
+		 * @param password
+		 * @return
+		 */
+	
+	public boolean
+	authenticate(
+		String		headers,
+		URL			resource,
+		String		user,
+		String		password )
+	{
+		return( authenticate( resource, user, password ));
+	}
 	
 	public byte[]
 	authenticate(
diff --git a/org/gudy/azureus2/plugins/tracker/web/TrackerWebContext.java b/org/gudy/azureus2/plugins/tracker/web/TrackerWebContext.java
index a58c703..6d450b5 100644
--- a/org/gudy/azureus2/plugins/tracker/web/TrackerWebContext.java
+++ b/org/gudy/azureus2/plugins/tracker/web/TrackerWebContext.java
@@ -26,6 +26,7 @@ package org.gudy.azureus2.plugins.tracker.web;
  *
  */
 
+import java.net.InetAddress;
 import java.net.URL;
 
 public interface 
@@ -42,6 +43,9 @@ TrackerWebContext
 	public URL[]
 	getURLs();
 	
+	public InetAddress
+	getBindIP();
+	
 	public void
 	setEnableKeepAlive(
 		boolean		enable );
diff --git a/org/gudy/azureus2/plugins/ui/SWT/GraphicSWT.java b/org/gudy/azureus2/plugins/ui/SWT/GraphicSWT.java
deleted file mode 100644
index 827d8ad..0000000
--- a/org/gudy/azureus2/plugins/ui/SWT/GraphicSWT.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Created on 2004/May/23
- * Created by TuxPaper
- * 
- * 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.plugins.ui.SWT;
-
-import org.gudy.azureus2.plugins.ui.Graphic;
-import org.eclipse.swt.graphics.Image;
-
-/** An SWT image to be used in Azureus
- *
- * @see SWTManager#createGraphic
- * @deprecated use {@link org.gudy.azureus2.ui.swt.plugins.UISWTGraphic}
- */
-public interface GraphicSWT extends Graphic {
-  /** Retrieve the Image object 
-   *
-   * @return image that is stored in this object
-   */
-  public Image getImage();
-
-  /** Sets the image stored in this object to the supplied parameter.
-   *
-   * @param img new image to be stored in this object
-   * @return true - Image Set<br>
-   *         false - Image already set to supplied parameter
-   */
-  public boolean setImage(Image img);
-}
diff --git a/org/gudy/azureus2/plugins/ui/SWT/SWTManager.java b/org/gudy/azureus2/plugins/ui/SWT/SWTManager.java
deleted file mode 100644
index cb7f1b8..0000000
--- a/org/gudy/azureus2/plugins/ui/SWT/SWTManager.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 org.gudy.azureus2.plugins.ui.SWT;
-
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.graphics.Image;
-
-import org.gudy.azureus2.plugins.PluginView;
-
-/** Evil SWT Specific stuff that plugins may need access to
- *
- * @author TuxPaper
- * @deprecated use {@link org.gudy.azureus2.ui.swt.plugins.UISWTInstance}
- */
-public interface SWTManager
-{
-  /** Retrieve the SWT Display object that Azureus uses (when in SWT mode).
-   * If you have a thread that does some periodic/asynchronous stuff, Azureus 
-   * will crashes with and 'InvalidThreadAccess' exception unless you
-   * embed your calls in a Runnable, and use getDisplay().aSyncExec(Runnable r);
-   *
-   * @return SWT Display object that Azureus uses
-   *
-   * @since 2.1.0.0
-   */
-  public Display getDisplay();
-
-  /** Creates an UIImageSWT object with the supplied SWT Image
-   *
-   * @param img Image to assign to the object
-   * @return a new UIImagetSWT object
-   *
-   * @since 2.1.0.0
-   */
-  public GraphicSWT createGraphic(Image img);
-
-  /**
-   * A Plugin might call this method to add a View to Azureus's views
-   * The View will be accessible from View > Plugins > View name
-   * @param view The PluginView to be added
-   *
-   * @since 2.1.0.2
-   */
-  public void addView(PluginView view);
-
-  /**
-   * A Plugin might call this method to add a View to Azureus's views
-   * The View will be accessible from View > Plugins > View name
-   * @param view The PluginView to be added
-   * @param autoOpen Whether the plugin should auto-open at startup
-   *
-   * @since 2.1.0.2
-   */
-  public void addView(PluginView view, boolean autoOpen);
-  
-  /**
-   * A Plugin might call this method to load an image from
-   * a resource (eg: "org/my_name/my_plugin/images/te_image.gif"
-   * @see getImage(String name)
-   * @param resource the resource path to the image
-   * @param name the name used for the image, please use names starting with your plugin name.
-   * @return true is the image was correctly loaded
-   * @since 2.1.0.6
-   */
-  //public boolean loadImage(String resource,String name);
-  
-  /**
-   * Once an image is loaded (@see loadImage(String resource,String name) )
-   * a plugin can retrieve it by calling this method.
-   * 
-   * @param name the name used in loadImage to identify the image.
-   * @return the image
-   *
-   */
-  //public Image getImage(String name);
-  
-}
diff --git a/org/gudy/azureus2/plugins/ui/UIDataSourceListener.java b/org/gudy/azureus2/plugins/ui/UIDataSourceListener.java
new file mode 100644
index 0000000..49854ef
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/UIDataSourceListener.java
@@ -0,0 +1,11 @@
+package org.gudy.azureus2.plugins.ui;
+
+public interface UIDataSourceListener
+{
+	/**
+	 * Triggered when the UIs data source has changed.
+	 * 
+	 * @param datasource Selected object or array of selected objects
+	 */
+	public void dataSourceChanged(Object datasource);
+}
diff --git a/org/gudy/azureus2/plugins/ui/UIInputReceiver.java b/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
index 43fac22..150fc89 100644
--- a/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
+++ b/org/gudy/azureus2/plugins/ui/UIInputReceiver.java
@@ -206,4 +206,11 @@ public interface UIInputReceiver {
 	 * for this by calling {@link #hasSubmittedInput()} first.
 	 */
 	public String getSubmittedInput();
+	
+	/**
+	 * set the maximum number of characters the user can type
+	 * 
+	 * @since 4.3.1.5
+	 */
+	public void setTextLimit(int limit);
 }
diff --git a/org/gudy/azureus2/plugins/ui/UIInstance.java b/org/gudy/azureus2/plugins/ui/UIInstance.java
index 5c244c6..69efe9b 100644
--- a/org/gudy/azureus2/plugins/ui/UIInstance.java
+++ b/org/gudy/azureus2/plugins/ui/UIInstance.java
@@ -22,6 +22,8 @@
 
 package org.gudy.azureus2.plugins.ui;
 
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+
 /**
  * This interface represents a UI running on the core (e.g. the SWT UI). 
  * The actual implementation of this will support UI-specific operations - 
@@ -65,4 +67,5 @@ UIInstance
 	 */
 	public UIMessage createMessage();
 
+	public UIToolBarManager getToolBarManager();
 }
diff --git a/org/gudy/azureus2/plugins/ui/UIManager.java b/org/gudy/azureus2/plugins/ui/UIManager.java
index b3b4736..c028a8b 100644
--- a/org/gudy/azureus2/plugins/ui/UIManager.java
+++ b/org/gudy/azureus2/plugins/ui/UIManager.java
@@ -25,13 +25,12 @@ package org.gudy.azureus2.plugins.ui;
 import java.io.File;
 import java.net.URL;
 
-import org.gudy.azureus2.plugins.PluginView;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
 import org.gudy.azureus2.plugins.ui.model.*;
-import org.gudy.azureus2.plugins.ui.SWT.SWTManager;
 import org.gudy.azureus2.plugins.ui.menus.MenuManager;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
 
 /**
  * Management tools for the user interface.
@@ -41,30 +40,6 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
 public interface 
 UIManager 
 {
-		/**
-		 * Gets a basic plugin view model that supports simple plugin requirements
-		 * After getting the model create the view using createPluginView
-		 * @param name name
-		 * @return BasicPluginViewModel
-		 * @deprecated Use createBasicPluginViewModel 
-		 */
-	
-	public BasicPluginViewModel
-	getBasicPluginViewModel(
-		String			name );
-
-		/**
-		 * Creates a view from the model. It is then necessary to add it to the plugin
-		 * as any other PluginView
-		 * @param model
-		 * @return PluginView
-		 * @deprecated Use createBasicPluginViewModel
-		 */
-	
-	public PluginView
-	createPluginView(
-		PluginViewModel	model );
-	
 	/**
 	 * 
 	 * @param section_name
@@ -193,17 +168,6 @@ UIManager
 	openTorrent(
 		Torrent		torrent );
 	
-	/** Retrieve a class of SWT specific functions 
-	 * 
-	 * @deprecated 
-	 * @return SWTManager
-	 * 
-	 * @since 2.1.0.0
-	 */
-	
-	public SWTManager getSWTManager();
-  
-	
 	/**
 	 * Open Config View to the section specified
 	 * 
@@ -260,8 +224,10 @@ UIManager
 		throws UIException;
 
 	/**
-	 * 
-	 * @param listener
+	 * Listen for {@link UIManagerListener#UIAttached(UIInstance)} and
+	 * {@link UIManagerListener#UIDetached(UIInstance)} events.  Typically,
+	 * you hook this listener so you can access {@link UISWTInstance} when it
+	 * gets created.
 	 * 
 	 * @since 2.3.0.5
 	 */
@@ -270,8 +236,9 @@ UIManager
   		UIManagerListener listener );
 
 	/**
+	 * Remove an existing {@link UIManagerListener}
 	 * 
-	 * @param listener
+	 * @param listener Listener to remove
 	 * 
 	 * @since 2.3.0.5
 	 */
@@ -365,5 +332,7 @@ UIManager
  	 * @since 3.0.5.3
  	 */
  	public void showFile(File file);
- 	
+
+ 	public void addDataSourceListener(UIDataSourceListener l, boolean triggerNow);
+ 	public void removeDataSourceListener(UIDataSourceListener l);
 }
diff --git a/org/gudy/azureus2/plugins/ui/UIPluginView.java b/org/gudy/azureus2/plugins/ui/UIPluginView.java
index 2fd6dff..c741f28 100644
--- a/org/gudy/azureus2/plugins/ui/UIPluginView.java
+++ b/org/gudy/azureus2/plugins/ui/UIPluginView.java
@@ -24,6 +24,8 @@
 
 package org.gudy.azureus2.plugins.ui;
 
+import org.gudy.azureus2.plugins.PluginInterface;
+
 /**
  * All plugin views should inherit from this interface so that we can always
  * check to see if they are a plugin view.
@@ -59,4 +61,22 @@ public interface UIPluginView {
 	 * @since 2.3.0.6
 	 */
 	public void closeView();
+	
+	/**
+	 * Gets the plugin interface associated with this view, null if none defined
+	 * 
+	 * @since 4.5.1.1
+	 */
+	public PluginInterface getPluginInterface();
+
+	/**
+	 * 
+	 * @since 4.6.0.5
+	 */
+	public void setToolBarListener(UIPluginViewToolBarListener l);
+
+	/**
+	 * @since 4.6.0.5
+	 */
+	public UIPluginViewToolBarListener getToolBarListener();
 }
diff --git a/org/gudy/azureus2/plugins/ui/UIPluginViewToolBarListener.java b/org/gudy/azureus2/plugins/ui/UIPluginViewToolBarListener.java
new file mode 100644
index 0000000..ccf88e8
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/UIPluginViewToolBarListener.java
@@ -0,0 +1,23 @@
+package org.gudy.azureus2.plugins.ui;
+
+import java.util.Map;
+
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarEnablerBase;
+
+/**
+ * 
+ * @author Vuze
+ *
+ */
+public interface UIPluginViewToolBarListener
+	extends UIToolBarActivationListener, UIToolBarEnablerBase
+{
+	/**
+	 * Fill in list with the toolbar ids and states you wish to set
+	 * 
+	 * @param list
+	 * @since 4.6.0.5
+	 */
+	public void refreshToolBarItems(Map<String, Long> list);
+}
diff --git a/org/gudy/azureus2/plugins/ui/config/PasswordParameter.java b/org/gudy/azureus2/plugins/ui/config/PasswordParameter.java
index 36981e9..d70c437 100644
--- a/org/gudy/azureus2/plugins/ui/config/PasswordParameter.java
+++ b/org/gudy/azureus2/plugins/ui/config/PasswordParameter.java
@@ -40,4 +40,8 @@ PasswordParameter
 	
 	public byte[]
 	getValue();
+	
+	public void
+	setValue(
+		String	plain_password );
 }
diff --git a/org/gudy/azureus2/plugins/ui/model/PluginViewModel.java b/org/gudy/azureus2/plugins/ui/model/PluginViewModel.java
index fc62a66..588898a 100644
--- a/org/gudy/azureus2/plugins/ui/model/PluginViewModel.java
+++ b/org/gudy/azureus2/plugins/ui/model/PluginViewModel.java
@@ -22,6 +22,8 @@
 
 package org.gudy.azureus2.plugins.ui.model;
 
+import org.gudy.azureus2.plugins.PluginInterface;
+
 /**
  * @author parg
  *
@@ -32,6 +34,9 @@ PluginViewModel
 	public String
 	getName();
 	
+	public PluginInterface
+	getPluginInterface();
+	
 	public void
 	destroy();
 }
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarCloseListener.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarCloseListener.java
deleted file mode 100644
index 7fc1930..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarCloseListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Created on Sep 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 org.gudy.azureus2.plugins.ui.sidebar;
-
-
-/**
- * @author TuxPaper
- * @created Sep 24, 2008
- *
- */
-public interface SideBarCloseListener
-{
-	public void sidebarClosed(SideBarEntry entry);
-}
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarDropListener.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarDropListener.java
deleted file mode 100644
index 42a5eb2..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarDropListener.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Created on Feb 13, 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.plugins.ui.sidebar;
-
-/**
- * @author TuxPaper
- * @created Feb 13, 2009
- *
- */
-public interface SideBarDropListener
-{
-	/**
-	 * @param entry
-	 * @param droppedObject
-	 * @return true if you handled it, false if you didn't
-	 */
-	public boolean sideBarEntryDrop(SideBarEntry entry, Object droppedObject);
-}
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarEntry.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarEntry.java
deleted file mode 100644
index 6670f05..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarEntry.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Created on Aug 13, 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 org.gudy.azureus2.plugins.ui.sidebar;
-
-/**
- * @author TuxPaper
- * @created Aug 13, 2008
- *
- */
-public interface SideBarEntry
-{
-
-	public String getParentID();
-
-	public Object getDatasource();
-
-	public boolean isCloseable();
-
-	public Class getIViewClass();
-
-	public Class[] getIViewClassArgs();
-
-	public Object[] getIViewClassVals();
-
-	public String getId();
-
-	public SideBarVitalityImage addVitalityImage(String imageID);
-
-	/**
-	 * @param l
-	 *
-	 * @since 4.1.0.3
-	 */
-	void addListener(SideBarCloseListener l);
-
-	/**
-	 * @param l
-	 *
-	 * @since 4.1.0.3
-	 */
-	void removeListener(SideBarCloseListener l);
-
-	/**
-	 * @param l
-	 *
-	 * @since 4.1.0.3
-	 */
-	void addListener(SideBarOpenListener l);
-
-	/**
-	 * @param l
-	 *
-	 * @since 4.1.0.3
-	 */
-	void removeListener(SideBarOpenListener l);
-}
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarOpenListener.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarOpenListener.java
deleted file mode 100644
index 716e904..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarOpenListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Created on Dec 3, 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 org.gudy.azureus2.plugins.ui.sidebar;
-
-/**
- * @author TuxPaper
- * @created Dec 3, 2008
- *
- */
-public interface SideBarOpenListener
-{
-	public void sideBarEntryOpen(SideBarEntry entry);
-}
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImage.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImage.java
deleted file mode 100644
index 6407726..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImage.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Created on Sep 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 org.gudy.azureus2.plugins.ui.sidebar;
-
-/**
- * @author TuxPaper
- * @created Sep 15, 2008
- *
- */
-public interface SideBarVitalityImage
-{
-	public String getImageID();
-
-	public void setImageID(String id );
-	
-	public SideBarEntry getSideBarEntry();
-	
-	public void addListener(SideBarVitalityImageListener l);
-	
-	public void setToolTip(String tooltip);
-	
-	public void setVisible(boolean visible);
-	
-	public boolean isVisible();
-
-	public void triggerClickedListeners(int x, int y);
-
-	public int getAlignment();
-	
-	public void setAlignment(int a);
-}
diff --git a/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImageListener.java b/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImageListener.java
deleted file mode 100644
index e20934c..0000000
--- a/org/gudy/azureus2/plugins/ui/sidebar/SideBarVitalityImageListener.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Created on Sep 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 org.gudy.azureus2.plugins.ui.sidebar;
-
-/**
- * @author TuxPaper
- * @created Sep 15, 2008
- *
- */
-public interface SideBarVitalityImageListener
-{
-	public void sbVitalityImage_clicked(int x, int y);
-}
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableCell.java b/org/gudy/azureus2/plugins/ui/tables/TableCell.java
index 6671113..a722b22 100644
--- a/org/gudy/azureus2/plugins/ui/tables/TableCell.java
+++ b/org/gudy/azureus2/plugins/ui/tables/TableCell.java
@@ -419,4 +419,11 @@ public interface TableCell {
 	 * @since 3.0.4.3
 	 */
 	public int[] getMouseOffset();
+
+	/**
+	 * Returns text that's meant for the clipboard
+	 * 
+	 * @since 4.3.1.5
+	 */
+	public String getClipboardText();
 }
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableCellClipboardListener.java b/org/gudy/azureus2/plugins/ui/tables/TableCellClipboardListener.java
new file mode 100644
index 0000000..967e69d
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/tables/TableCellClipboardListener.java
@@ -0,0 +1,24 @@
+/*
+ * Created : 2004/Apr/30
+ * 
+ * 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.plugins.ui.tables;
+
+public interface TableCellClipboardListener {
+  String getClipboardText(TableCell cell);
+}
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableCellRefresher.java b/org/gudy/azureus2/plugins/ui/tables/TableCellRefresher.java
index b2a6155..99e1486 100644
--- a/org/gudy/azureus2/plugins/ui/tables/TableCellRefresher.java
+++ b/org/gudy/azureus2/plugins/ui/tables/TableCellRefresher.java
@@ -1,12 +1,15 @@
 package org.gudy.azureus2.plugins.ui.tables;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.ui.swt.Utils;
 
+import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl;
+
 
 /**
  * 
@@ -47,6 +50,11 @@ public class TableCellRefresher {
   						//cc.cell.invalidate();
   						if (column instanceof TableCellRefreshListener) {
   							((TableCellRefreshListener) column).refresh(cell);
+  						}else if ( column instanceof TableColumnImpl ){
+  							List<TableCellRefreshListener> listeners =((TableColumnImpl)column).getCellRefreshListeners();
+  							for ( TableCellRefreshListener listener: listeners ){
+  								listener.refresh(cell);
+  							}
   						}
   
   					} catch (Throwable t) {
@@ -72,7 +80,7 @@ public class TableCellRefresher {
   						Utils.execSWTThread(runnable);
 						}
 
-						Thread.sleep(200);
+						Thread.sleep(100);
 
 						iterationNumber++;
 					}
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableColumn.java b/org/gudy/azureus2/plugins/ui/tables/TableColumn.java
index 0a5f51d..ede91a5 100644
--- a/org/gudy/azureus2/plugins/ui/tables/TableColumn.java
+++ b/org/gudy/azureus2/plugins/ui/tables/TableColumn.java
@@ -76,6 +76,10 @@ public interface TableColumn {
   public static final String CAT_CONNECTION = "connection";
   public static final String CAT_PROGRESS = "progress";
 
+  	// user-data properties
+  
+  public static final String UD_FORCE_VISIBLE = "ud_fv";	// Long
+  
   /** Initialize a group of variables all at once.  Saves on individual setXxx.
    *
    * @param iAlignment See {@link #setAlignment(int)}
@@ -580,4 +584,25 @@ public interface TableColumn {
 	 * @since 4.0.0.5
 	 */
 	Class getForDataSourceType();
+
+	/**
+	 * 
+	 * @since 4.4.0.7
+	 */
+	public void setIconReference(String iconID, boolean showOnlyIcon);
+	
+	/**
+	 * 
+	 * @since 4.4.0.7
+	 */
+	public String getIconReference();
+	
+	/**
+	 * *since 4501
+	 * @param mode from Parameter. constants
+	 */
+	
+	public void
+	setMinimumRequiredUserMode(
+		int		mode );
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableManager.java b/org/gudy/azureus2/plugins/ui/tables/TableManager.java
index c7436cf..30152dd 100644
--- a/org/gudy/azureus2/plugins/ui/tables/TableManager.java
+++ b/org/gudy/azureus2/plugins/ui/tables/TableManager.java
@@ -31,6 +31,7 @@ public interface TableManager
   public static final String TABLE_MYTORRENTS_INCOMPLETE = "MyTorrents";
   
   public static final String TABLE_MYTORRENTS_UNOPENED = "Unopened";
+
   /** Visible for Completed Torrents table (big version)*/
   public static final String TABLE_MYTORRENTS_COMPLETE_BIG   = "MySeeders.big";
   /** Visible for Incompleted Torrents table (big version)*/
@@ -50,6 +51,9 @@ public interface TableManager
   public static final String TABLE_TORRENT_PIECES        = "Pieces";
   /** Visible for Torrent Files table */
   public static final String TABLE_TORRENT_FILES         = "Files";
+  
+  public static final String TABLE_TORRENT_TRACKERS      = "Trackers";
+
   /** Visible for My Tracker table */
   public static final String TABLE_MYTRACKER             = "MyTracker";
   /** Visible for My Shares table */
diff --git a/org/gudy/azureus2/plugins/ui/tables/TableRow.java b/org/gudy/azureus2/plugins/ui/tables/TableRow.java
index c33119d..5276957 100644
--- a/org/gudy/azureus2/plugins/ui/tables/TableRow.java
+++ b/org/gudy/azureus2/plugins/ui/tables/TableRow.java
@@ -117,4 +117,25 @@ public interface TableRow {
 	 * @since 3.0.1.7
 	 */
 	public void removeMouseListener(TableRowMouseListener listener);
+
+	/**
+	 * Get a previously stored value
+	 * 
+	 * @param id
+	 * @return
+	 *
+	 * @since 4.3.1.5
+	 */
+	Object getData(String id);
+
+	/**
+	 * Store a value against the table row
+	 * 
+	 * @param id
+	 * @param data
+	 *
+	 * @since 4.3.1.5
+	 */
+	void setData(String id, Object data);
+
 }
diff --git a/org/gudy/azureus2/plugins/ui/tables/package.html b/org/gudy/azureus2/plugins/ui/tables/package.html
deleted file mode 100644
index f01cca7..0000000
--- a/org/gudy/azureus2/plugins/ui/tables/package.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
-  <head>
-    <title></title>
-  </head>
-  <body>
-    Classes that manage aspects of Azureus tables.
-  </body>
-</html>
diff --git a/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarActivationListener.java b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarActivationListener.java
new file mode 100644
index 0000000..08f8be5
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarActivationListener.java
@@ -0,0 +1,12 @@
+package org.gudy.azureus2.plugins.ui.toolbar;
+
+import com.aelitis.azureus.ui.common.ToolBarItem;
+
+public interface UIToolBarActivationListener
+{
+	public final static long ACTIVATIONTYPE_NORMAL = 0x0;
+	public final static long ACTIVATIONTYPE_HELD = 0x1;
+	public final static long ACTIVATIONTYPE_RIGHTCLICK = 0x2;
+
+  public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource);
+}
diff --git a/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarEnablerBase.java b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarEnablerBase.java
new file mode 100644
index 0000000..41b65a6
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarEnablerBase.java
@@ -0,0 +1,8 @@
+package org.gudy.azureus2.plugins.ui.toolbar;
+
+/**
+ * Not part of Public API
+ */
+public interface UIToolBarEnablerBase
+{
+}
diff --git a/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarItem.java b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarItem.java
new file mode 100644
index 0000000..d32cbb8
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarItem.java
@@ -0,0 +1,60 @@
+package org.gudy.azureus2.plugins.ui.toolbar;
+
+public interface UIToolBarItem
+{
+	public final static long STATE_ENABLED = 0x1;
+
+	public static final long STATE_DOWN = 0x2;
+
+	/**
+	 * Retrieve the ID of the toolbar item
+	 * 
+	 * @since 4.6.0.5
+	 */
+	public String getID();
+
+	/**
+	 * Return the message bundle ID for the button text
+	 * 
+	 * @since 4.6.0.5
+	 */
+	public String getTextID();
+
+	/**
+	 * Sets the button's text to a messagebundle value looked up using the id
+	 * 
+	 * @param id
+	 * @since 4.6.0.5
+	 */
+	public void setTextID(String id);
+
+	/**
+	 * Get the ID of the image used
+	 *
+	 * @since 4.6.0.5
+	 */
+	public String getImageID();
+
+	/**
+	 * Sets the toolbar item to use the specified image
+	 *
+	 * @since 4.6.0.5
+	 */
+	public void setImageID(String id);
+
+	/**
+	 * Returns if the toolbar item is always available (enabled)
+	 *
+	 * @since 4.6.0.5
+	 */
+	public boolean isAlwaysAvailable();
+
+	public long getState();
+	
+	public void setState(long state);
+
+	public boolean triggerToolBarItem(long activationType, Object datasource);
+
+	public void setDefaultActivationListener(
+			UIToolBarActivationListener defaultActivation);
+}
diff --git a/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarManager.java b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarManager.java
new file mode 100644
index 0000000..c0203a1
--- /dev/null
+++ b/org/gudy/azureus2/plugins/ui/toolbar/UIToolBarManager.java
@@ -0,0 +1,29 @@
+package org.gudy.azureus2.plugins.ui.toolbar;
+
+public interface UIToolBarManager
+{
+	public final static String GROUP_BIG = "big";
+	public final static String GROUP_MAIN = "main";
+
+	/**
+	 * Create a new {@link UIToolBarItem}.  You will still need to add it
+	 * via {@link #addToolBarItem(UIToolBarItem)}, after setting the item's
+	 * properties
+	 * 
+	 * @param id unique id
+	 * @return newly created toolbar
+	 */
+	public UIToolBarItem createToolBarItem(String id);
+	
+	/**
+	 * Adds a {@link UIToolBarItem} to the UI.  Make sure you at least set the
+	 * icon before adding
+	 * 
+	 * @param item
+	 */
+	public void addToolBarItem(UIToolBarItem item);
+
+	public UIToolBarItem getToolBarItem(String id);
+	public UIToolBarItem[] getAllToolBarItems();
+	public void removeToolBarItem(String id);
+}
diff --git a/org/gudy/azureus2/plugins/update/Update.java b/org/gudy/azureus2/plugins/update/Update.java
index cf9b0d5..4ebc3b9 100644
--- a/org/gudy/azureus2/plugins/update/Update.java
+++ b/org/gudy/azureus2/plugins/update/Update.java
@@ -97,7 +97,8 @@ Update
 		 */
 	
 	public void
-	complete();
+	complete(
+		boolean	success );
 	
 		/**
 		 * cancel this update
@@ -112,6 +113,9 @@ Update
 	public boolean
 	isComplete();
 	
+	public boolean
+	wasSuccessful();
+	
 	public UpdateCheckInstance
 	getCheckInstance();
 	
diff --git a/org/gudy/azureus2/plugins/update/UpdateCheckInstance.java b/org/gudy/azureus2/plugins/update/UpdateCheckInstance.java
index 20073c5..fec8894 100644
--- a/org/gudy/azureus2/plugins/update/UpdateCheckInstance.java
+++ b/org/gudy/azureus2/plugins/update/UpdateCheckInstance.java
@@ -37,6 +37,7 @@ UpdateCheckInstance
 	public static final int	PT_UI_STYLE				= 1;	//Integer
 	public static final int	PT_UI_STYLE_DEFAULT		= 1;
 	public static final int	PT_UI_STYLE_SIMPLE		= 2;
+	public static final int	PT_UI_STYLE_NONE		= 3;
 	
 	public static final int	PT_UI_PARENT_SWT_COMPOSITE					= 2;	// SWT Composite
 	
@@ -113,6 +114,9 @@ UpdateCheckInstance
 	public boolean
 	isLowNoise();
 	
+	public boolean
+	isCompleteOrCancelled();
+	
 	public Object
 	getProperty(
 		int		property_name );
diff --git a/org/gudy/azureus2/plugins/update/UpdateInstaller.java b/org/gudy/azureus2/plugins/update/UpdateInstaller.java
index 03cfbeb..dc89222 100644
--- a/org/gudy/azureus2/plugins/update/UpdateInstaller.java
+++ b/org/gudy/azureus2/plugins/update/UpdateInstaller.java
@@ -119,4 +119,18 @@ UpdateInstaller
 		String    file )
 
     	throws UpdateException;
+	
+		/**
+		 * Runs the action now, not as part of a shutdown/restart of Vuze
+		 * @throws UpdateException
+		 */
+	
+	public void
+	installNow(
+		UpdateInstallerListener		listener )
+	
+		throws UpdateException;
+	
+	public void
+	destroy();
 }
diff --git a/org/gudy/azureus2/plugins/update/UpdateInstallerListener.java b/org/gudy/azureus2/plugins/update/UpdateInstallerListener.java
new file mode 100644
index 0000000..0f5a9ad
--- /dev/null
+++ b/org/gudy/azureus2/plugins/update/UpdateInstallerListener.java
@@ -0,0 +1,37 @@
+/*
+ * Created on Jan 8, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.update;
+
+public interface 
+UpdateInstallerListener 
+{
+	public void
+	reportProgress(
+		String		str );
+	
+	public void
+	complete();
+	
+	public void
+	failed(
+		UpdateException	exception );
+}
diff --git a/org/gudy/azureus2/plugins/update/UpdateManager.java b/org/gudy/azureus2/plugins/update/UpdateManager.java
index bea92d0..a8fd910 100644
--- a/org/gudy/azureus2/plugins/update/UpdateManager.java
+++ b/org/gudy/azureus2/plugins/update/UpdateManager.java
@@ -75,6 +75,9 @@ UpdateManager
 		int			check_type,
 		String		name );
 
+	public UpdateCheckInstance[]
+	getCheckInstances();
+	
 		/**
 		 * create a stand alone update installer. you will need to restart Azureus for it to
 		 * be installed
diff --git a/org/gudy/azureus2/plugins/utils/ByteArrayWrapper.java b/org/gudy/azureus2/plugins/utils/ByteArrayWrapper.java
index 1c26a9a..a7e5a67 100644
--- a/org/gudy/azureus2/plugins/utils/ByteArrayWrapper.java
+++ b/org/gudy/azureus2/plugins/utils/ByteArrayWrapper.java
@@ -32,4 +32,7 @@ ByteArrayWrapper
 {
 	public byte[]
 	getBytes();
+
+	public String
+	toBase32String();
 }
diff --git a/org/gudy/azureus2/plugins/utils/FeatureManager.java b/org/gudy/azureus2/plugins/utils/FeatureManager.java
new file mode 100644
index 0000000..db9b026
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/FeatureManager.java
@@ -0,0 +1,234 @@
+/*
+ * Created on Feb 4, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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;
+
+import org.gudy.azureus2.plugins.PluginException;
+
+
+public interface 
+FeatureManager 
+{
+	public Licence[]
+	getLicences();
+	
+	public Licence[]
+	createLicences(
+		String[]				feature_ids )
+	
+		throws PluginException;
+	
+	public Licence
+	addLicence(
+		String		licence_key )
+	
+		throws PluginException;
+	
+	public FeatureDetails[]
+	getFeatureDetails(
+		String					feature_id );
+	
+		// feature present and not expired
+	
+	public boolean
+	isFeatureInstalled(
+		String					feature_id );
+	
+	public void
+	refreshLicences();
+	
+	public void
+	registerFeatureEnabler(
+		FeatureEnabler	enabler );
+	
+	public void
+	unregisterFeatureEnabler(
+		FeatureEnabler	enabler );
+	
+	public void
+	addListener(
+		FeatureManagerListener		listener );
+	
+	public void
+	removeListener(
+		FeatureManagerListener		listener );
+
+	
+	public interface
+	Licence
+	{
+		public final int LS_PENDING_AUTHENTICATION	= 1;
+		public final int LS_AUTHENTICATED			= 2;
+		public final int LS_INVALID_KEY				= 3;
+		public final int LS_CANCELLED				= 4;
+		public final int LS_REVOKED					= 5;
+		public final int LS_ACTIVATION_DENIED		= 6;
+		
+		public int
+		getState();
+		
+		public String
+		getKey();
+		
+		public String
+		getShortID();
+		
+		public FeatureDetails[]
+		getFeatures();
+		
+		public boolean
+		isFullyInstalled();
+		
+		public void
+		retryInstallation();
+		
+		public void
+		addInstallationListener(
+			LicenceInstallationListener	listener );
+		
+		public void
+		removeInstallationListener(
+			LicenceInstallationListener	listener );
+		
+		public void
+		remove();
+		
+		public interface
+		LicenceInstallationListener
+		{
+			public void
+			start(
+				String		licence_key );
+			
+			public void
+			reportActivity(
+				String		licence_key,
+				String		install,
+				String		activity );
+			
+			public void
+			reportProgress(
+				String		licence_key,
+				String		install,
+				int			percent );
+			
+			public void
+			complete(
+				String		licence_key );
+			
+			public void
+			failed(
+				String				licence_key,
+				PluginException		error );
+		}
+	}
+	
+	public interface
+	FeatureEnabler
+	{
+		public Licence[]
+       	getLicences();
+		
+		public Licence[]
+		createLicences(
+			String[]				feature_ids )
+		
+			throws PluginException;
+		
+       	public Licence
+       	addLicence(
+       		String		licence_key );
+       	
+       	public void
+       	refreshLicences();
+       	
+    	public void
+    	addListener(
+    		FeatureManagerListener		listener );
+    	
+    	public void
+    	removeListener(
+    		FeatureManagerListener		listener );
+	}
+	
+	public interface
+	FeatureDetails
+	{
+		public String	PR_PUBLIC_KEY				= "PublicKey";				// String
+		public String	PR_VALID_UNTIL				= "ValidUntil";				// Long
+		public String	PR_OFFLINE_VALID_UNTIL		= "OfflineValidUntil";		// Long
+		public String	PR_IS_INSTALL_TIME			= "IsInstallTime";			// Long (0=false)
+		public String	PR_IS_TRIAL					= "IsTrial";				// Long (0=false)
+		public String	PR_TRIAL_USES_LIMIT			= "TrialUsesLimit";			// Long
+		public String	PR_TRIAL_USES_FAIL_COUNT	= "TrialUsesFailCount";		// Long
+		public String	PR_TRIAL_USES_REMAINING		= "TrialUsesRemaining";		// Long
+		public String	PR_REQUIRED_PLUGINS			= "Plugins";				// String: comma separated plugin ids
+		public String	PR_FINGERPRINT				= "Fingerprint";			// String
+		public String	PR_RENEWAL_KEY				= "RenewalKey";				// String
+		
+		public Licence
+		getLicence();
+		
+		public String
+		getID();
+		
+			/**
+			 * Returns true if offline expired or overall expired. 
+			 * NOT to be used by verified plugins, they must do the check explicitly using the
+			 * signed properties
+			 * @return
+			 */
+		
+		public boolean
+		hasExpired();
+		
+		public byte[]
+		getEncodedProperties();
+		
+		public byte[]
+		getSignature();
+		
+		public Object
+		getProperty(
+			String		propery_name );
+		
+		public void
+		setProperty(
+			String		property_name,
+			Object		property_value );
+	}
+	
+	public interface
+	FeatureManagerListener
+	{
+		public void
+		licenceAdded(
+			Licence	licence );
+		
+		public void
+		licenceChanged(
+			Licence	licence );
+		
+		public void
+		licenceRemoved(
+			Licence	licence );
+	}
+}
diff --git a/org/gudy/azureus2/plugins/utils/PowerManagementListener.java b/org/gudy/azureus2/plugins/utils/PowerManagementListener.java
new file mode 100644
index 0000000..9e57e9d
--- /dev/null
+++ b/org/gudy/azureus2/plugins/utils/PowerManagementListener.java
@@ -0,0 +1,41 @@
+/*
+ * Created on Oct 10, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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;
+
+public interface 
+PowerManagementListener
+{
+	public static final int ST_SLEEP = 1;
+	
+	public String
+	getPowerName();
+	
+	public boolean
+	requestPowerStateChange(
+		int		new_state,
+		Object	data );
+
+	public void
+	informPowerStateChange(
+		int		new_state,
+		Object	data );
+}
diff --git a/org/gudy/azureus2/plugins/utils/Utilities.java b/org/gudy/azureus2/plugins/utils/Utilities.java
index bf96911..bc8f5a1 100644
--- a/org/gudy/azureus2/plugins/utils/Utilities.java
+++ b/org/gudy/azureus2/plugins/utils/Utilities.java
@@ -346,6 +346,12 @@ Utilities
 	
 		throws SearchException;
 
+	public void
+	unregisterSearchProvider(
+		SearchProvider		provider )
+	
+		throws SearchException;
+	
 	public SearchInitiator
 	getSearchInitiator()
 	
@@ -356,28 +362,20 @@ Utilities
 	
 		throws SubscriptionException;
 	
+	public FeatureManager
+	getFeatureManager();
+	
 	public boolean
-	isFeatureEnabled(
-		String					feature_id,
-		Map<String,Object>		feature_properties );
+	supportsPowerStateControl(
+		int		state );
 	
 	public void
-	registerFeatureEnabler(
-		FeatureEnabler	enabler );
-	
+	addPowerManagementListener(
+		PowerManagementListener	listener );
+		
 	public void
-	unregisterFeatureEnabler(
-		FeatureEnabler	enabler );
-	
-	public interface
-	FeatureEnabler
-	{
-		public boolean
-		isFeatureEnabled(
-			String					requester_id,
-			String					feature_id,
-			Map<String,Object>		feature_properties );
-	}
+	removePowerManagementListener(
+		PowerManagementListener	listener );
 }
 
 
diff --git a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloader.java b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloader.java
index 6b39b71..e8d27d5 100644
--- a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloader.java
+++ b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloader.java
@@ -109,6 +109,9 @@ ResourceDownloader
 	public boolean
 	isCancelled();
 	
+	public ResourceDownloader
+	getClone();
+	
 	public void
 	reportActivity(
 		String				activity );
diff --git a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderCancelledException.java b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderCancelledException.java
index a73a663..0e3b94a 100644
--- a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderCancelledException.java
+++ b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderCancelledException.java
@@ -23,9 +23,15 @@ package org.gudy.azureus2.plugins.utils.resourcedownloader;
 /**
  * @since 3.0.5.3
  */
-public class ResourceDownloaderCancelledException extends ResourceDownloaderException {
-	public ResourceDownloaderCancelledException() {
-		super("Download cancelled");
-	}
 
+public class 
+ResourceDownloaderCancelledException 
+	extends ResourceDownloaderException 
+{
+	public 
+	ResourceDownloaderCancelledException(
+		ResourceDownloader		rd )
+	{
+		super( rd, "Download cancelled" );
+	}
 }
diff --git a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderException.java b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderException.java
index 816c783..9b1e1ed 100644
--- a/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderException.java
+++ b/org/gudy/azureus2/plugins/utils/resourcedownloader/ResourceDownloaderException.java
@@ -32,16 +32,18 @@ ResourceDownloaderException
 {
 	public
 	ResourceDownloaderException(
-		String	str )
+		ResourceDownloader	rd,
+		String				str )
 	{
-		super(str);
+		super( rd.getName() + ": " + str);
 	}
 	
 	public
 	ResourceDownloaderException(
-		String		str,
-		Throwable	cause )
+		ResourceDownloader	rd,
+		String				str,
+		Throwable			cause )
 	{
-		super(str, cause);
+		super( rd.getName() + ": " + str, cause);
 	}
 }
diff --git a/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java b/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java
index 3bf4a29..9899b1d 100644
--- a/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java
+++ b/org/gudy/azureus2/plugins/utils/subscriptions/Subscription.java
@@ -30,6 +30,9 @@ Subscription
 	public String
 	getName();
 	
+	public boolean
+	isSearchTemplate();
+	
 	public SubscriptionResult[]
 	getResults();
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginConfigImpl.java b/org/gudy/azureus2/pluginsimpl/local/PluginConfigImpl.java
index a3870aa..0ad02cb 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginConfigImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginConfigImpl.java
@@ -43,7 +43,7 @@ PluginConfigImpl
 	implements PluginConfig 
 {
 
-	protected static Map	external_to_internal_key_map = new HashMap();
+	protected static Map<String,String>	external_to_internal_key_map = new HashMap<String,String>();
 	private PluginConfigSourceImpl external_source = null;
 
 	static{
@@ -60,7 +60,8 @@ PluginConfigImpl
 		external_to_internal_key_map.put( CORE_PARAM_INT_MAX_UPLOADS_SEEDING, "Max Uploads Seeding");
 		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_MAX_UPLOAD_SPEED_SEEDING, "enable.seedingonly.upload.rate");
 		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_MAX_ACTIVE_SEEDING, "StartStopManager_bMaxActiveTorrentsWhenSeedingEnabled");
-		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_AUTO_SPEED_ON, "Auto Upload Speed Enabled");
+		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_AUTO_SPEED_ON, CORE_PARAM_BOOLEAN_AUTO_SPEED_ON);
+		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_AUTO_SPEED_SEEDING_ON, CORE_PARAM_BOOLEAN_AUTO_SPEED_SEEDING_ON );
 		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_SOCKS_PROXY_NO_INWARD_CONNECTION, 	"Proxy.Data.SOCKS.inform" );
 		external_to_internal_key_map.put( CORE_PARAM_BOOLEAN_NEW_SEEDS_START_AT_TOP, 			CORE_PARAM_BOOLEAN_NEW_SEEDS_START_AT_TOP );
 		external_to_internal_key_map.put( CORE_PARAM_STRING_LOCAL_BIND_IP, 						"Bind IP" );
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java b/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
index 284cd3e..1a667ec 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginCoreUtils.java
@@ -23,13 +23,20 @@
 
 package org.gudy.azureus2.pluginsimpl.local;
 
+import java.io.File;
+import java.io.IOException;
+
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfoListener;
+import org.gudy.azureus2.core3.download.DownloadManager;
 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.TOTorrentFile;
 import org.gudy.azureus2.core3.tracker.host.TRHostTorrent;
 import org.gudy.azureus2.core3.tracker.server.TRTrackerServerTorrent;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.plugins.disk.DiskManager;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
@@ -38,6 +45,7 @@ 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;
@@ -98,6 +106,226 @@ PluginCoreUtils
 		}
 	}
 	
+	public static org.gudy.azureus2.plugins.disk.DiskManagerFileInfo
+	wrap(
+		DiskManagerFileInfo		info )
+	
+		throws DownloadException
+	{
+		if ( info == null ){
+			
+			return( null );
+		}
+		
+		return( new DiskManagerFileInfoImpl( DownloadManagerImpl.getDownloadStatic( info.getDownloadManager()), info ));
+	}
+	
+	public static DiskManagerFileInfo
+	unwrap(
+		final org.gudy.azureus2.plugins.disk.DiskManagerFileInfo		info )
+	
+		throws DownloadException
+	{
+		if ( info == null ){
+			
+			return( null );
+		}
+
+		try{
+			Download dl = info.getDownload();
+			
+			if ( dl != null ){
+				
+				org.gudy.azureus2.core3.download.DownloadManager dm = unwrap( dl );
+				
+				return( dm.getDiskManagerFileInfo()[ info.getIndex()]);
+			}
+		}catch( Throwable e ){
+		}
+		
+			// no underlying download, lash something up
+		
+		return(
+			new DiskManagerFileInfo()
+			{
+				public void 
+				setPriority(
+					int b )
+				{
+					info.setNumericPriority(b);
+				}
+				
+				public void 
+				setSkipped(
+					boolean b)
+				{
+					info.setSkipped(b);
+				}
+
+				public boolean
+				setLink(
+					File	link_destination )
+				{	
+					info.setLink(link_destination);
+					
+					return( true );
+				}
+				
+				public boolean 
+				setLinkAtomic(
+					File link_destination )
+				{	
+					info.setLink(link_destination);
+					
+					return( true );
+				}
+				
+				public File
+				getLink()
+				{
+					return( info.getLink());
+				}
+				
+				public boolean 
+				setStorageType(
+					int type )
+				{
+					return( false );
+				}
+				
+				public int
+				getStorageType()
+				{
+					return( ST_LINEAR );
+				}
+				
+				public int 
+				getAccessMode()
+				{
+					return( info.getAccessMode());
+				}
+				
+				public long 
+				getDownloaded()
+				{
+					return( info.getDownloaded());
+				}
+				
+				public String 
+				getExtension()
+				{
+					return( "" );
+				}
+					
+				public int 
+				getFirstPieceNumber()
+				{
+					return( info.getFirstPieceNumber());
+				}
+			  
+				public int 
+				getLastPieceNumber()
+				{
+					return((int)(( info.getLength() + info.getPieceSize()-1 )/info.getPieceSize()));
+				}
+				
+				public long 
+				getLength()
+				{
+					return( info.getLength());
+				}
+					
+				public int 
+				getNbPieces()
+				{
+					return( info.getNumPieces());
+				}
+						
+				public int 
+				getPriority()
+				{
+					return( info.getNumericPriorty());
+				}
+				
+				public boolean 
+				isSkipped()
+				{
+					return( info.isSkipped());
+				}
+				
+				public int	
+				getIndex()
+				{
+					return( info.getIndex());
+				}
+				
+				public DownloadManager	
+				getDownloadManager()
+				{
+					return( null );
+				}
+				
+				public org.gudy.azureus2.core3.disk.DiskManager 
+				getDiskManager()
+				{
+					return( null );
+				}
+				
+				public File 
+				getFile( boolean follow_link )
+				{
+					if ( follow_link ){
+						
+						return( info.getLink());
+						
+					}else{
+						
+						return( info.getFile());
+					}
+				}
+				
+				public TOTorrentFile
+				getTorrentFile()
+				{
+					return( null );
+				}
+				
+				public DirectByteBuffer
+				read(
+					long	offset,
+					int		length )
+				
+					throws IOException
+				{
+					throw( new IOException( "unsupported" ));
+				}
+				
+				public void
+				flushCache()
+				
+					throws	Exception
+				{	
+				}
+				
+				public void
+				close()
+				{
+				}
+				
+				public void
+				addListener(
+					DiskManagerFileInfoListener	listener )
+				{
+				}
+				
+				public void
+				removeListener(
+					DiskManagerFileInfoListener	listener )
+				{
+				}
+			});
+	}
+	
 	public static Object
 	convert(
 		Object datasource,
@@ -137,7 +365,7 @@ PluginCoreUtils
 					return datasource;
 				}
 				if (datasource instanceof org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl) {
-					((org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl) datasource).getCore();
+					return ((org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl) datasource).getCore();
 				}
 
 				if (datasource instanceof TRHostTorrent) {
@@ -241,4 +469,17 @@ PluginCoreUtils
 	{
 		return( ((TrackerTorrentImpl)torrent).getHostTorrent().getTrackerTorrent());
 	}
+	
+	public static PEPeer
+	unwrap(
+		Peer		peer )
+	{
+		return(((PeerImpl)peer).getDelegate());
+	}
+	
+	public static boolean
+	isInitialisationComplete()
+	{
+		return( PluginInitializer.getDefaultInterface().getPluginState().isInitialisationComplete());
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java b/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
index ccab1fd..dcc3c40 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginInitializer.java
@@ -30,11 +30,13 @@ import java.net.URLClassLoader;
 import java.net.URLConnection;
 import java.util.*;
 
+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.GlobalManagerListener;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.security.SESecurityManager;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.pluginsimpl.local.launch.PluginLauncherImpl;
@@ -45,7 +47,9 @@ import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl.runnableWithExcep
 import org.gudy.azureus2.update.UpdaterUpdateChecker;
 import org.gudy.azureus2.update.UpdaterUtils;
 
+
 import com.aelitis.azureus.core.*;
+import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 
 
 
@@ -57,6 +61,8 @@ public class
 PluginInitializer
 	implements GlobalManagerListener, AEDiagnosticsEvidenceGenerator
 {
+	public static final boolean DISABLE_PLUGIN_VERIFICATION = false;
+	
 	private static final LogIDs LOGID = LogIDs.CORE;
 	public static final String	INTERNAL_PLUGIN_ID = "<internal>";
 	
@@ -185,6 +191,15 @@ PluginInitializer
 			*/
         }; 
   
+  static VerifiedPluginHolder verified_plugin_holder;
+  
+  static{
+	  synchronized( PluginInitializer.class ){
+		  
+		  verified_plugin_holder = new VerifiedPluginHolder();
+	  }
+  }
+  
   	// these can be removed one day
   
   private static String[][]default_version_details =
@@ -200,6 +215,11 @@ PluginInitializer
   
   private static List		initThreads = new ArrayList(1);
   
+  private static AsyncDispatcher	async_dispatcher = new AsyncDispatcher();
+  private static List<PluginEvent>	plugin_event_history = new ArrayList<PluginEvent>();
+  
+  
+  
   private AzureusCoreOperation core_operation;
   
   private AzureusCore		azureus_core;
@@ -220,7 +240,8 @@ PluginInitializer
   
   private volatile boolean	plugins_initialised;
   
-  
+  private Set<String>	vc_disabled_plugins = VersionCheckClient.getSingleton().getDisabledPluginIDs();
+    
   public static PluginInitializer
   getSingleton(
   	AzureusCore		 		azureus_core,
@@ -242,6 +263,20 @@ PluginInitializer
 	}  	
   }
   
+  private static PluginInitializer
+  peekSingleton()
+  {
+  	try{
+  		class_mon.enter();
+  		 	
+	  	return( singleton );
+	 	 
+	}finally{
+	  		
+		class_mon.exit();
+	}  	
+  }
+  
   protected static void
   queueRegistration(
   	Class	_class )
@@ -787,440 +822,535 @@ PluginInitializer
   
   private List 
   loadPluginFromDir(
-  	File directory,
-  	boolean bSkipAlreadyLoaded,
-  	boolean loading_for_startup,
-  	boolean initialise) // initialise setting is used if loading_for_startup isnt
-  
-  	throws PluginException
+		  File directory,
+		  boolean bSkipAlreadyLoaded,
+		  boolean loading_for_startup,
+		  boolean initialise) // initialise setting is used if loading_for_startup isnt
+
+  throws PluginException
   {
-    List	loaded_pis = new ArrayList();
-    
-  	ClassLoader plugin_class_loader = root_class_loader;
-  	
-    if( !directory.isDirectory()){
-    	
-    	return( loaded_pis );
-    }
-    
-    String pluginName = directory.getName();
-    
-    File[] pluginContents = directory.listFiles();
-    
-    if ( pluginContents == null || pluginContents.length == 0){
-    	
-    	return( loaded_pis );
-    }
-    
-    	// first sanity check - dir must include either a plugin.properties or
-    	// at least one .jar file
-    
-    boolean	looks_like_plugin	= false;
-    
-    for (int i=0;i<pluginContents.length;i++){
-    	
-    	String	name = pluginContents[i].getName().toLowerCase();
-    	
-    	if ( name.endsWith( ".jar") || name.equals( "plugin.properties" )){
-    		
-    		looks_like_plugin = true;
-    		
-    		break;
-    	}
-    }
-    
-    if ( !looks_like_plugin ){
-    	
-    	if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
-						"Plugin directory '" + directory + "' has no plugin.properties "
-								+ "or .jar files, skipping"));
-    	
-    	return( loaded_pis );
-    }
-    
-    	// take only the highest version numbers of jars that look versioned
-    
-    String[]	plugin_version = {null};
-    String[]	plugin_id = {null};
-    
-    pluginContents	= PluginLauncherImpl.getHighestJarVersions( pluginContents, plugin_version, plugin_id, true );
-    
-    for( int i = 0 ; i < pluginContents.length ; i++){
-    	
-    	File	jar_file = pluginContents[i];
-    	
-    		// migration hack for i18nAZ_1.0.jar
-    	
-    	if ( pluginContents.length > 1 ){
-    		
-    		String	name = jar_file.getName();
-    		
-    		if ( name.startsWith( "i18nPlugin_" )){
-    			
-    				// non-versioned version still there, rename it
-    			
-    			if (Logger.isEnabled())
-						Logger.log(new LogEvent(LOGID, "renaming '" + name
-								+ "' to conform with versioning system"));
-    			
-    			jar_file.renameTo( new File( jar_file.getParent(), "i18nAZ_0.1.jar  " ));
-    			
-    			continue;
-    		}
-    	}
-    	
-        plugin_class_loader = PluginLauncherImpl.addFileToClassPath( root_class_loader, plugin_class_loader, jar_file);
-    }
-        
-    String plugin_class_string = null;
-    
-    try {
-      Properties props = new Properties();
-      
-      File	properties_file = new File(directory.toString() + File.separator + "plugin.properties");
- 
-      try {
-      	
-      		// if properties file exists on its own then override any properties file
-      		// potentially held within a jar
-      	
-      	if ( properties_file.exists()){
-      	
-      		FileInputStream	fis = null;
-      		
-      		try{
-      			fis = new FileInputStream( properties_file );
-      		
-      			props.load( fis );
-      			
-      		}finally{
-      			
-      			if ( fis != null ){
-      				
-      				fis.close();
-      			}
-      		}
-      		
-      	}else{
-      		
-      		if ( plugin_class_loader instanceof URLClassLoader ){
-      			
-      			URLClassLoader	current = (URLClassLoader)plugin_class_loader;
-      		    			
-      			URL url = current.findResource("plugin.properties");
-      		
-      			if ( url != null ){
-        			URLConnection connection = url.openConnection();
-        			
-        			InputStream is = connection.getInputStream();
-      				
-      				props.load(is);
-      				
-      			}else{
-      				
-      				throw( new Exception( "failed to load plugin.properties from jars"));
-      			}
-      		}else{
-      			
- 				throw( new Exception( "failed to load plugin.properties from dir or jars"));
- 				      			
-      		}
-      	}
-      }catch( Throwable e ){
-      	
-      	Debug.printStackTrace( e );
-      	
-      	String	msg =  "Can't read 'plugin.properties' for plugin '" + pluginName + "': file may be missing";
-      	
-      	Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg));
-      	  
-        System.out.println( msg );
-        
-        throw( new PluginException( msg, e ));
-      }
+	  List	loaded_pis = new ArrayList();
+
+	  ClassLoader plugin_class_loader = root_class_loader;
+
+	  if( !directory.isDirectory()){
+
+		  return( loaded_pis );
+	  }
+
+	  String pluginName = directory.getName();
+
+	  File[] pluginContents = directory.listFiles();
+
+	  if ( pluginContents == null || pluginContents.length == 0){
+
+		  return( loaded_pis );
+	  }
+
+	  // first sanity check - dir must include either a plugin.properties or
+	  // at least one .jar file
+
+	  boolean	looks_like_plugin	= false;
+
+	  for (int i=0;i<pluginContents.length;i++){
+
+		  String	name = pluginContents[i].getName().toLowerCase();
+
+		  if ( name.endsWith( ".jar") || name.equals( "plugin.properties" )){
+
+			  looks_like_plugin = true;
+
+			  break;
+		  }
+	  }
+
+	  if ( !looks_like_plugin ){
+
+		  if (Logger.isEnabled())
+			  Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
+					  "Plugin directory '" + directory + "' has no plugin.properties "
+					  + "or .jar files, skipping"));
+
+		  return( loaded_pis );
+	  }
+
+	  // take only the highest version numbers of jars that look versioned
+
+	  String[]	plugin_version = {null};
+	  String[]	plugin_id = {null};
+
+	  pluginContents	= PluginLauncherImpl.getHighestJarVersions( pluginContents, plugin_version, plugin_id, true );
+
+	  for( int i = 0 ; i < pluginContents.length ; i++){
+
+		  File	jar_file = pluginContents[i];
+
+		  // migration hack for i18nAZ_1.0.jar
+
+		  if ( pluginContents.length > 1 ){
+
+			  String	name = jar_file.getName();
+
+			  if ( name.startsWith( "i18nPlugin_" )){
+
+				  // non-versioned version still there, rename it
+
+				  if (Logger.isEnabled())
+					  Logger.log(new LogEvent(LOGID, "renaming '" + name
+							  + "' to conform with versioning system"));
+
+				  jar_file.renameTo( new File( jar_file.getParent(), "i18nAZ_0.1.jar  " ));
+
+				  continue;
+			  }
+		  }
+
+		  plugin_class_loader = PluginLauncherImpl.addFileToClassPath( root_class_loader, plugin_class_loader, jar_file);
+	  }
+
+	  String plugin_class_string = null;
+
+	  try {
+		  Properties props = new Properties();
+
+		  File	properties_file = new File(directory.toString() + File.separator + "plugin.properties");
+
+		  try {
+
+			  // if properties file exists on its own then override any properties file
+			  // potentially held within a jar
+
+			  if ( properties_file.exists()){
+
+				  FileInputStream	fis = null;
+
+				  try{
+					  fis = new FileInputStream( properties_file );
+
+					  props.load( fis );
+
+				  }finally{
+
+					  if ( fis != null ){
+
+						  fis.close();
+					  }
+				  }
+
+			  }else{
+
+				  if ( plugin_class_loader instanceof URLClassLoader ){
+
+					  URLClassLoader	current = (URLClassLoader)plugin_class_loader;
+
+					  URL url = current.findResource("plugin.properties");
+
+					  if ( url != null ){
+						  URLConnection connection = url.openConnection();
+
+						  InputStream is = connection.getInputStream();
+
+						  props.load(is);
+
+					  }else{
+
+						  throw( new Exception( "failed to load plugin.properties from jars"));
+					  }
+				  }else{
+
+					  throw( new Exception( "failed to load plugin.properties from dir or jars"));
+
+				  }
+			  }
+		  }catch( Throwable e ){
+
+			  Debug.printStackTrace( e );
+
+			  String	msg =  "Can't read 'plugin.properties' for plugin '" + pluginName + "': file may be missing";
+
+			  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg));
+
+			  System.out.println( msg );
+
+			  throw( new PluginException( msg, e ));
+		  }
+
+		  checkJDKVersion( pluginName, props, true );
+		  checkAzureusVersion(pluginName, props, true);
+
+		  plugin_class_string = (String)props.get( "plugin.class");
+
+		  if ( plugin_class_string == null ){
+
+			  plugin_class_string = (String)props.get( "plugin.classes");
+
+			  if ( plugin_class_string == null ){
+
+				  // set so we don't bork later will npe
+
+				  plugin_class_string = "";
+			  }
+		  }
+
+		  String	plugin_name_string = (String)props.get( "plugin.name");
+
+		  if ( plugin_name_string == null ){
+
+			  plugin_name_string = (String)props.get( "plugin.names");
+		  }
+
+		  int	pos1 = 0;
+		  int	pos2 = 0;
+
+		  while(true){
+			  int	p1 = plugin_class_string.indexOf( ";", pos1 );
+
+			  String	plugin_class;
+
+			  if ( p1 == -1 ){
+				  plugin_class = plugin_class_string.substring(pos1).trim();
+			  }else{
+				  plugin_class	= plugin_class_string.substring(pos1,p1).trim();
+				  pos1 = p1+1;
+			  }
+
+			  PluginInterfaceImpl existing_pi = getPluginFromClass( plugin_class );
+
+			  if ( existing_pi != null ){
+
+				  if (bSkipAlreadyLoaded) {
+					  break;
+				  }
+
+				  // allow user dir entries to override app dir entries without warning
+
+				  File	this_parent 	= directory.getParentFile();
+				  File	existing_parent = null;
+
+				  if ( existing_pi.getInitializerKey() instanceof File ){
+
+					  existing_parent	= ((File)existing_pi.getInitializerKey()).getParentFile();
+				  }
+
+				  if ( 	this_parent.equals( FileUtil.getApplicationFile("plugins")) &&
+						  existing_parent	!= null &&
+						  existing_parent.equals( FileUtil.getUserFile( "plugins" ))){
+
+					  // skip this overridden plugin
+
+					  if (Logger.isEnabled())
+						  Logger.log(new LogEvent(LOGID, "Plugin '" + plugin_name_string
+								  + "/" + plugin_class
+								  + ": shared version overridden by user-specific one"));
+
+					  return( new ArrayList());
+
+				  }else{
+					  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_WARNING,
+							  "Error loading '" + plugin_name_string + "', plugin class '"
+							  + plugin_class + "' is already loaded"));
+				  }
+
+			  }else{
+
+				  String	plugin_name = null;
+
+				  if ( plugin_name_string != null ){
+
+					  int	p2 = plugin_name_string.indexOf( ";", pos2 );
+
+
+					  if ( p2 == -1 ){
+						  plugin_name = plugin_name_string.substring(pos2).trim();
+					  }else{
+						  plugin_name	= plugin_name_string.substring(pos2,p2).trim();
+						  pos2 = p2+1;
+					  }    
+				  }
+
+				  Properties new_props = (Properties)props.clone();
+
+				  for (int j=0;j<default_version_details.length;j++){
+
+					  if ( plugin_class.equals( default_version_details[j][0] )){
+
+						  if ( new_props.get( "plugin.id") == null ){
+
+							  new_props.put( "plugin.id", default_version_details[j][1]);  
+						  }
+
+						  if ( plugin_name == null ){
+
+							  plugin_name	= default_version_details[j][2];
+						  }
+
+						  if ( new_props.get( "plugin.version") == null ){
+
+							  // no explicit version. If we've derived one then use that, otherwise defaults
+
+							  if ( plugin_version[0] != null ){
+
+								  new_props.put( "plugin.version", plugin_version[0]);
+
+							  }else{
+
+								  new_props.put( "plugin.version", default_version_details[j][3]);
+							  }
+						  }
+					  }
+				  }
+
+				  new_props.put( "plugin.class", plugin_class );
+
+				  if ( plugin_name != null ){
+
+					  new_props.put( "plugin.name", plugin_name );
+				  }
+
+				  // System.out.println( "loading plugin '" + plugin_class + "' using cl " + classLoader);
+
+				  // if the plugin load fails we still need to generate a plugin entry
+				  // as this drives the upgrade process
+
+
+				  Throwable	load_failure	= null;
+
+				  String pid = plugin_id[0]==null?directory.getName():plugin_id[0];
+
+				  List<File>	verified_files = null;
+
+				  Plugin plugin = null;
+
+				  if ( vc_disabled_plugins.contains ( pid )){
+
+					  log( "Plugin '" + pid + "' has been administratively disabled" );
+
+				  }else{
+					  try{
+						  String cl_key = "plugin.cl.ext." + pid;
+						  
+						  String str = COConfigurationManager.getStringParameter( cl_key, null );
+
+						  if ( str != null && str.length() > 0 ){
+
+							  COConfigurationManager.removeParameter( cl_key );
+							  
+							  plugin_class_loader = PluginLauncherImpl.extendClassLoader( root_class_loader, plugin_class_loader, new URL( str ));
+						  }
+					  }catch( Throwable e ){	
+					  }
+
+					  if ( pid.endsWith( "_v" )){
+
+						  verified_files = new ArrayList<File>();
+
+						  // 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 );
+
+									  verified_files.add( jar_file );
+
+									  log( "    OK" );
+
+								  }catch( Throwable e ){
+
+									  String	msg = "Error loading plugin '" + pluginName + "' / '" + plugin_class_string + "'";
+
+									  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, msg, e));
+
+									  plugin = new FailedPlugin(plugin_name,directory.getAbsolutePath());
+								  }
+							  }
+						  }
+					  }
+
+					  if ( plugin == null ){
+
+						  plugin = PluginLauncherImpl.getPreloadedPlugin( plugin_class );
+
+						  if ( plugin == null ){
+
+							  try{
+								  Class c = plugin_class_loader.loadClass(plugin_class);
+
+								  plugin	= (Plugin) c.newInstance();
+
+								  try{
+									  // kick off any pre-inits
+
+									  if ( plugin_class_loader instanceof URLClassLoader ){
+
+										  URL[] urls = ((URLClassLoader)plugin_class_loader).getURLs();
+
+										  for ( URL u: urls ){
+
+											  String path = u.getPath();
+
+											  if ( path.endsWith( ".jar" )){
+
+												  int	s1 = path.lastIndexOf( '/' );
+												  int	s2 = path.lastIndexOf( '\\' );
+
+												  path = path.substring( Math.max( s1, s2 )+1);
+
+												  s2 = path.indexOf( '_' );
+
+												  if ( s2 > 0 ){
+
+													  path = path.substring( 0, s2 );
+
+													  path = path.replaceAll( "-", "" );
+													  
+													  String cl = "plugin.preinit." + pid + ".PI" + path;
+													  
+													  try{
+														  Class pic = plugin_class_loader.loadClass( cl );
+
+														  if ( pic != null ){
+
+															  pic.newInstance();
+														  }
+													  }catch( Throwable e ){			    						  
+													  }
+												  }
+											  }
+										  }
+									  }
+								  }catch( Throwable e ){
+								  }
+							  }catch (java.lang.UnsupportedClassVersionError e) {
+								  plugin = new FailedPlugin(plugin_name,directory.getAbsolutePath());
+
+								  // shorten stack trace
+								  load_failure	= new UnsupportedClassVersionError(e.getMessage());
+
+							  }catch( Throwable e ){
+
+								  if ( 	e instanceof ClassNotFoundException &&
+										  props.getProperty( "plugin.install_if_missing", "no" ).equalsIgnoreCase( "yes" )){
+
+									  // don't report the failure
+
+								  }else{
+
+									  load_failure	= e;
+								  }
+
+								  plugin = new FailedPlugin(plugin_name,directory.getAbsolutePath());
+							  }
+						  }else{
+
+							  plugin_class_loader = plugin.getClass().getClassLoader();
+						  }
+					  }
+
+					  MessageText.integratePluginMessages((String)props.get("plugin.langfile"),plugin_class_loader);
+
+					  PluginInterfaceImpl plugin_interface = 
+						  new PluginInterfaceImpl(
+								  plugin, 
+								  this, 
+								  directory, 
+								  plugin_class_loader,
+								  verified_files,
+								  directory.getName(),	// key for config values
+								  new_props,
+								  directory.getAbsolutePath(),
+								  pid,
+								  plugin_version[0] );
+
+					  boolean bEnabled = (loading_for_startup) ? plugin_interface.getPluginState().isLoadedAtStartup() : initialise;
+					  
+					  plugin_interface.getPluginState().setDisabled(!bEnabled);
+
+					  try{
+
+						  Method	load_method = plugin.getClass().getMethod( "load", new Class[]{ PluginInterface.class });
+
+						  load_method.invoke( plugin, new Object[]{ plugin_interface });
+
+					  }catch( NoSuchMethodException e ){
+
+					  }catch( Throwable e ){
+
+						  load_failure	= e;
+					  }
+
+					  loaded_pis.add( plugin_interface );
+
+					  if ( load_failure != null ){
+						  
+						  plugin_interface.setAsFailed();
+
+						  	// don't complain about our internal one
+						  
+						  if ( !pid.equals(UpdaterUpdateChecker.getPluginID())){
+
+							  String msg = 
+								  MessageText.getString("plugin.init.load.failed", 
+									new String[]{
+										  plugin_name==null?pluginName:plugin_name,
+										  directory.getAbsolutePath()
+							  		});
+							  							  
+							  LogAlert la;
+							  
+							  if ( load_failure instanceof UnsupportedClassVersionError ){
+								  
+								  la = new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg + ".\n\n" + MessageText.getString("plugin.install.class_version_error"));
+								
+							  }else if ( load_failure instanceof ClassNotFoundException ){
+									  
+								  la = new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg + ".\n\n" + MessageText.getString("plugin.init.load.failed.classmissing") + "\n\n", load_failure );
+
+							  }else{
+								  
+								  la = new LogAlert(LogAlert.UNREPEATABLE, msg, load_failure);
+							  }
+							  
+							  Logger.log( la );
+
+							  System.out.println( msg + ": " + load_failure);
+						  }
+					  }
+				  }
+			  }
+			  if ( p1 == -1 ){
+				  break;
+
+			  }
+		  }
+
+		  return( loaded_pis );
+
+	  }catch(Throwable e) {
+
+		  if ( e instanceof PluginException ){
+
+			  throw((PluginException)e);
+		  }
 
-      checkJDKVersion( pluginName, props, true );
-      checkAzureusVersion(pluginName, props, true);
-      
-      plugin_class_string = (String)props.get( "plugin.class");
-      
-      if ( plugin_class_string == null ){
-      	
-      	plugin_class_string = (String)props.get( "plugin.classes");
-      	
-      	if ( plugin_class_string == null ){
-      		
-      			// set so we don't bork later will npe
-      		
-      		plugin_class_string = "";
-      	}
-      }
-      
-      String	plugin_name_string = (String)props.get( "plugin.name");
-      
-      if ( plugin_name_string == null ){
-      	
-      	plugin_name_string = (String)props.get( "plugin.names");
-      }
- 
-      int	pos1 = 0;
-      int	pos2 = 0;
-                 
-      while(true){
-  		int	p1 = plugin_class_string.indexOf( ";", pos1 );
-  	
-  		String	plugin_class;
-  	
-  		if ( p1 == -1 ){
-  			plugin_class = plugin_class_string.substring(pos1).trim();
-  		}else{
-  			plugin_class	= plugin_class_string.substring(pos1,p1).trim();
-  			pos1 = p1+1;
-  		}
-  
-  		PluginInterfaceImpl existing_pi = getPluginFromClass( plugin_class );
-  		
-  		if ( existing_pi != null ){
-  			
-  			if (bSkipAlreadyLoaded) {
-  				break;
-  			}
-  				
-  				// allow user dir entries to override app dir entries without warning
-  			
-  			File	this_parent 	= directory.getParentFile();
-  			File	existing_parent = null;
-  			
-  			if ( existing_pi.getInitializerKey() instanceof File ){
-  				
-  				existing_parent	= ((File)existing_pi.getInitializerKey()).getParentFile();
-  			}
-  			
-  			if ( 	this_parent.equals( FileUtil.getApplicationFile("plugins")) &&
-  					existing_parent	!= null &&
-  					existing_parent.equals( FileUtil.getUserFile( "plugins" ))){
-  				
-  					// skip this overridden plugin
-  	
-  				if (Logger.isEnabled())
-  					Logger.log(new LogEvent(LOGID, "Plugin '" + plugin_name_string
-								+ "/" + plugin_class
-								+ ": shared version overridden by user-specific one"));
-  				
-  				return( new ArrayList());
-  				
-  			}else{
-  				Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_WARNING,
-								"Error loading '" + plugin_name_string + "', plugin class '"
-										+ plugin_class + "' is already loaded"));
-  			}
+		  Debug.printStackTrace( e );
 
-  		}else{
-  			
-  		  String	plugin_name = null;
-  		  
-  		  if ( plugin_name_string != null ){
-  		  	
-  		  	int	p2 = plugin_name_string.indexOf( ";", pos2 );
-          	
-      	
-      		if ( p2 == -1 ){
-      			plugin_name = plugin_name_string.substring(pos2).trim();
-      		}else{
-      			plugin_name	= plugin_name_string.substring(pos2,p2).trim();
-      			pos2 = p2+1;
-      		}    
-  		  }
-  		  
-  		  Properties new_props = (Properties)props.clone();
-  		  
-  		  for (int j=0;j<default_version_details.length;j++){
-  		  	
-  		  	if ( plugin_class.equals( default_version_details[j][0] )){
-  		  
-		  		if ( new_props.get( "plugin.id") == null ){
-  		  			
-		  			new_props.put( "plugin.id", default_version_details[j][1]);  
-  		  		}
-		  		
-		  		if ( plugin_name == null ){
-		  			
-		  			plugin_name	= default_version_details[j][2];
-		  		}
-		  		
-		  		if ( new_props.get( "plugin.version") == null ){
+		  String	msg = "Error loading plugin '" + pluginName + "' / '" + plugin_class_string + "'";
 
-		  				// no explicit version. If we've derived one then use that, otherwise defaults
- 		  			
-		  			if ( plugin_version[0] != null ){
-		  
-		  				new_props.put( "plugin.version", plugin_version[0]);
-		     		    		  				
-		  			}else{
-		  				
-		  				new_props.put( "plugin.version", default_version_details[j][3]);
-		  			}
-  		  		}
-  		  	}
-  		  }
-  		  
-  		  new_props.put( "plugin.class", plugin_class );
-  		  
-  		  if ( plugin_name != null ){
-  		  	
-  		  	new_props.put( "plugin.name", plugin_name );
-  		  }
-  		       		       		  
- 	      // System.out.println( "loading plugin '" + plugin_class + "' using cl " + classLoader);
-	      
-	      	// if the plugin load fails we still need to generate a plugin entry
-  		  	// as this drives the upgrade process
-  		  
-	      
-	      Throwable	load_failure	= null;
-	      
-	      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 ){
-	    	  
-	    	  try{
-	    		  Class c = plugin_class_loader.loadClass(plugin_class);
-		      
-	    		  plugin	= (Plugin) c.newInstance();
-	    		  
-	    	  }catch (java.lang.UnsupportedClassVersionError e) {
-	    		  plugin = new FailedPlugin(plugin_name,directory.getAbsolutePath());
-	    		  
-	    		  // shorten stack trace
-	    		  load_failure	= new UnsupportedClassVersionError(e.getMessage());
-	    		  
-	    	  }catch( Throwable e ){
-	      	
-	    		  if ( 	e instanceof ClassNotFoundException &&
-	    				props.getProperty( "plugin.install_if_missing", "no" ).equalsIgnoreCase( "yes" )){
-	    			  
-	    			  // don't report the failure
-	    			  
-	    		  }else{
-	    			  
-	    			  load_failure	= e;
-	    		  }
-	      	
-	    		  plugin = new FailedPlugin(plugin_name,directory.getAbsolutePath());
-	    	  }
-	      }else{
-	    	  
-	    	  plugin_class_loader = plugin.getClass().getClassLoader();
-	      }
-	      
-	      MessageText.integratePluginMessages((String)props.get("plugin.langfile"),plugin_class_loader);
-
-	      PluginInterfaceImpl plugin_interface = 
-	      		new PluginInterfaceImpl(
-	      					plugin, 
-							this, 
-							directory, 
-							plugin_class_loader,
-							directory.getName(),	// key for config values
-							new_props,
-							directory.getAbsolutePath(),
-							pid,
-							plugin_version[0] );
-	      
-	      boolean bEnabled = (loading_for_startup) ? plugin_interface.getPluginState().isLoadedAtStartup() : initialise;
-	      plugin_interface.getPluginState().setDisabled(!bEnabled);
+		  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, msg, e));
 
-	      try{
-	      
-	      	Method	load_method = plugin.getClass().getMethod( "load", new Class[]{ PluginInterface.class });
-	      	
-	      	load_method.invoke( plugin, new Object[]{ plugin_interface });
-	      	
-	      }catch( NoSuchMethodException e ){
-	      	
-	      }catch( Throwable e ){
-	      	
-	      	load_failure	= e;
-	      }
-	      
-	      loaded_pis.add( plugin_interface );
-	      
-	      if ( load_failure != null ){
-	    	  plugin_interface.setAsFailed();
-	    	  
-	    	// don't complain about our internal one
-	    	  if ( !pid.equals(UpdaterUpdateChecker.getPluginID())){
-	    		  
-		      	String msg = "Error loading plugin '" + pluginName + "' / '" + plugin_class_string + "'";
-		      	LogAlert la;
-		      	if (load_failure instanceof UnsupportedClassVersionError) {
-		      		la = new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg + ". " + MessageText.getString("plugin.install.class_version_error"));
-		      	}
-		      	else {
-		      		la = new LogAlert(LogAlert.UNREPEATABLE, msg, load_failure);
-		      	}
-		      	Logger.log(la);
-	
-		      	System.out.println( msg + ": " + load_failure);
-		      }
-	      }
-  		}
-	      
-	    if ( p1 == -1 ){
-	    	break;
-	      	
-	    }
-      }
-            
-      return( loaded_pis );
-      
-    }catch(Throwable e) {
-    	
-    	if ( e instanceof PluginException ){
-    		
-    		throw((PluginException)e);
-    	}
-   
-    	Debug.printStackTrace( e );
-      
-    	String	msg = "Error loading plugin '" + pluginName + "' / '" + plugin_class_string + "'";
- 	 
-    	Logger.log(new LogAlert(LogAlert.UNREPEATABLE, msg, e));
+		  System.out.println( msg + ": " + e);
 
-    	System.out.println( msg + ": " + e);
-    	
-    	throw( new PluginException( msg, e ));
-    }
+		  throw( new PluginException( msg, e ));
+	  }
   }
   
   private void
@@ -1577,7 +1707,6 @@ PluginInitializer
   	}
   	    
   	try{
-  	
   		final Plugin plugin = (Plugin) plugin_class.newInstance();
   		
   		String	plugin_name;
@@ -1610,6 +1739,7 @@ PluginInitializer
 						this,
 						plugin_class,
 						plugin_class.getClassLoader(),
+						null,
 						plugin_config_key,
 						properties,
 						"",
@@ -1704,13 +1834,14 @@ PluginInitializer
   
   	throws PluginException
   {
-  	try{  		
+  	try{  	
   		final PluginInterfaceImpl plugin_interface = 
   			new PluginInterfaceImpl(
   						plugin, 
 						this,
 						plugin.getClass(),
 						plugin.getClass().getClassLoader(),
+						null,
 						plugin_config_key,
 						new Properties(),
 						"",
@@ -1839,24 +1970,31 @@ PluginInitializer
   
   	if ( default_plugin == null ){
   		
-  		default_plugin = 
-  			new PluginInterfaceImpl(
-  					new Plugin()
-					{
-  						public void
-						initialize(
-							PluginInterface pi)
-  						{
-  						}
-					},
-					this,
-					getClass(),
-					getClass().getClassLoader(),
-					"default",
-					new Properties(),
-					null,
-					INTERNAL_PLUGIN_ID,
-					null );
+  		try{
+	  		default_plugin = 
+	  			new PluginInterfaceImpl(
+	  					new Plugin()
+						{
+	  						public void
+							initialize(
+								PluginInterface pi)
+	  						{
+	  						}
+						},
+						this,
+						getClass(),
+						getClass().getClassLoader(),
+						null,
+						"default",
+						new Properties(),
+						null,
+						INTERNAL_PLUGIN_ID,
+						null );
+	  		
+  		}catch( Throwable e ){
+  			
+  			Debug.out( e );
+  		}
   	}
   	
   	return( default_plugin );
@@ -1921,50 +2059,116 @@ PluginInitializer
     /*nothing*/
   }
   
+  protected void
+  runPEVTask(
+		AERunnable	run )
+  {
+	  async_dispatcher.dispatch( run );
+  }
+  
+  
+  protected List<PluginEvent>
+  getPEVHistory()
+  {
+	  return( plugin_event_history );
+  }
   
   protected void
   fireEventSupport(
   	final int		type,
   	final Object	value )
   {
-  	PluginEvent	ev = 
-  		new PluginEvent()
-  		{ 
-  			public int 
-  			getType()
-  			{ 
-  				return( type );
-  			}
-  			
-  			public Object
-  			getValue()
-  			{
-  				return( value );
-  			}
-  		};
-  	
-  	List plugin_interfaces;
-  		  	
-  	synchronized( s_plugin_interfaces ){
-  			
-  		plugin_interfaces = new ArrayList( s_plugin_interfaces );
-  	}
-  	
-  	for (int i=0;i<plugin_interfaces.size();i++){
-  		
-  		try{
-  			((PluginInterfaceImpl)plugin_interfaces.get(i)).firePluginEvent(ev);
-  			
-  		}catch(Throwable e ){
-  			
-  			Debug.printStackTrace(e);
-  		}
-  	} 
-  	
- 	if ( default_plugin != null ){
-  		
-  		default_plugin.firePluginEvent(ev);
-  	}
+	  async_dispatcher.dispatch(
+		 new AERunnable()
+		 {
+			 public void
+			 runSupport()
+			 {		 
+			  	PluginEvent	ev = 
+			  		new PluginEvent()
+			  		{ 
+			  			public int 
+			  			getType()
+			  			{ 
+			  				return( type );
+			  			}
+			  			
+			  			public Object
+			  			getValue()
+			  			{
+			  				return( value );
+			  			}
+			  		};
+			  	
+			  	if ( 	type == PluginEvent.PEV_CONFIGURATION_WIZARD_STARTS ||
+			  			type == PluginEvent.PEV_CONFIGURATION_WIZARD_COMPLETES ||
+			  			type == PluginEvent.PEV_INITIAL_SHARING_COMPLETE ||
+			  			type == PluginEvent.PEV_INITIALISATION_UI_COMPLETES ||
+			  			type == PluginEvent.PEV_ALL_PLUGINS_INITIALISED ){
+			  		
+			  		plugin_event_history.add( ev );
+			  		
+			  		if ( plugin_event_history.size() > 1024 ){
+			  			
+			  			Debug.out( "Plugin event history too large!!!!" );
+			  			
+			  			plugin_event_history.remove( 0 );
+			  		}
+			  	}
+			  	
+			  	List plugin_interfaces;
+			  		  	
+			  	synchronized( s_plugin_interfaces ){
+			  			
+			  		plugin_interfaces = new ArrayList( s_plugin_interfaces );
+			  	}
+			  	
+			  	for (int i=0;i<plugin_interfaces.size();i++){
+			  		
+			  		try{
+			  			((PluginInterfaceImpl)plugin_interfaces.get(i)).firePluginEventSupport(ev);
+			  			
+			  		}catch(Throwable e ){
+			  			
+			  			Debug.printStackTrace(e);
+			  		}
+			  	} 
+			  	
+			 	if ( default_plugin != null ){
+			  		
+			  		default_plugin.firePluginEventSupport(ev);
+			  	}
+			  }
+		 });
+  }
+  
+  private void
+  waitForEvents()
+  {
+	  if ( async_dispatcher.isDispatchThread()){
+		  
+		  Debug.out( "Deadlock - recode this monkey boy" );
+		  
+	  }else{
+		  
+		  final AESemaphore sem = new AESemaphore( "waiter" );
+		  
+		  async_dispatcher.dispatch(
+				new AERunnable()
+				{
+					public void
+					runSupport()
+					{
+						sem.release();
+					}
+				});
+		  
+		  if ( !sem.reserve( 10*1000 )){
+			  
+			  Debug.out( "Timeout waiting for event dispatch" );
+		  }
+				 
+	  }
   }
   
   public static void
@@ -1982,6 +2186,12 @@ PluginInitializer
   	singleton.fireEventSupport(type, value);
   }
   
+  public static void
+  waitForPluginEvents()
+  {
+	  singleton.waitForEvents();
+  }
+  
   public void
   initialisationComplete()
   {
@@ -2123,5 +2333,229 @@ PluginInitializer
 			writer.exdent();
 		}
 	}
+	
+	protected static void
+	setVerified(
+		PluginInterfaceImpl		pi,
+		Plugin					plugin,
+		boolean					v,
+		boolean					bad )
+	
+		throws PluginException
+	{		
+		Object[] existing = (Object[])verified_plugin_holder.setValue( pi, new Object[]{ plugin, v });
+		
+		if ( existing != null && ( existing[0] != plugin || (Boolean)existing[1] != v )){
+			
+			throw( new PluginException( "Verified status change not permitted" ));
+		}
+		
+  	  	if ( bad && !DISABLE_PLUGIN_VERIFICATION ){
+		  
+		  throw( new RuntimeException( "Plugin verification failed" ));
+	  }
+	}
+	
+	public static boolean
+	isVerified(
+		PluginInterface		pi,
+		Plugin				plugin )
+	{
+		if ( !( pi instanceof PluginInterfaceImpl )){
+			
+			return( false );
+		}
+		
+		VerifiedPluginHolder holder = verified_plugin_holder;
+		
+		if ( holder.getClass() != VerifiedPluginHolder.class ){
+		
+			Debug.out( "class mismatch" );
+			
+			return( false );
+		}
+		
+		if ( DISABLE_PLUGIN_VERIFICATION ){
+			
+			Debug.out( " **************************** VERIFICATION DISABLED ******************" );
+			
+			return( true );
+		}
+		
+		Object[] ver = (Object[])verified_plugin_holder.getValue( pi );
+		
+		return( ver != null && ver[0] == plugin && (Boolean)ver[1] );
+	}
+	
+	public static boolean
+	isCoreOrVerifiedPlugin()
+	{
+		Class<?>[] stack = SESecurityManager.getClassContext();
+		
+		ClassLoader core = PluginInitializer.class.getClassLoader();
+		
+		PluginInitializer singleton = peekSingleton();
+		
+		PluginInterface[] pis = singleton==null?new PluginInterface[0]:singleton.getPlugins();
+
+		Set<ClassLoader>	ok_loaders = new HashSet<ClassLoader>();
+		
+		ok_loaders.add( core );
+		
+		for ( Class<?> c: stack ){
+			
+			ClassLoader cl = c.getClassLoader();
+			
+			if ( cl != null && !ok_loaders.contains( cl )){
+				
+				boolean ok = false;
+				
+				for ( PluginInterface pi: pis ){
+					
+					Plugin plugin = pi.getPlugin();
+					
+					if ( plugin.getClass().getClassLoader() == cl ){
+						
+						if ( isVerified( pi, plugin )){
+							
+							ok_loaders.add( cl );
+							
+							ok = true;
+							
+							break;
+						}
+					}
+				}
+				
+				if ( !ok ){
+					
+					Debug.out( "Class " + c.getCanonicalName() + " with loader " + cl + " isn't trusted" );
+					
+					return( false );
+				}
+			}
+		}
+		
+		return( true );
+	}
+	
+	private static final class
+	VerifiedPluginHolder
+	{	
+		private volatile boolean initialised;
+		
+		private AESemaphore	request_sem = new AESemaphore( "ValueHolder" );
+		
+		private List<Object[]>	request_queue = new ArrayList<Object[]>();
+				
+		private
+		VerifiedPluginHolder()
+		{
+			Class[] context = SESecurityManager.getClassContext();
+			
+			if ( context[2] != PluginInitializer.class ){
+				
+				Debug.out( "Illegal operation" );
+				
+				return;
+			}
+			
+			AEThread2 t = 
+				new AEThread2( "PluginVerifier" )
+				{
+					public void
+					run()
+					{
+						Map<Object,Object> values = new IdentityHashMap<Object,Object>();
+												
+						while( true ){
+														
+							request_sem.reserve();
+							
+							Object[] req;
+							
+							synchronized( request_queue ){
+								
+								req = request_queue.remove(0);
+							}
+							
+							if ( req[1] == null ){
+								
+								req[1] = values.get( req[0] );
+								
+							}else{
+								
+								Object existing = values.get( req[0] );
+								
+								if ( existing != null){
+									
+									req[1] = existing;
+									
+								}else{
+									
+									values.put( req[0], req[1] );
+								}
+							}
+							
+							((AESemaphore)req[2]).release();
+						}
+					}
+				};
+			
+			t.start();	
+			
+			initialised = true;
+		}
+		
+		public Object
+		setValue(
+			Object	key,
+			Object	value )
+		{	
+			if ( !initialised ){
+				
+				return( null );
+			}
+			
+			AESemaphore sem = new AESemaphore( "ValueHolder:set" );
+			
+			Object[] request = new Object[]{ key, value, sem };
+			
+			synchronized( request_queue ){
+				
+				request_queue.add( request );
+			}
+			
+			request_sem.release();
+			
+			sem.reserve();
+			
+			return(request[1]);
+		}
+		
+		public Object
+		getValue(
+			Object	key )
+		{	
+			if ( !initialised ){
+				
+				return( null );
+			}
+			
+			AESemaphore sem = new AESemaphore( "ValueHolder:get" );
+			
+			Object[] request = new Object[]{ key, null, sem };
 
+			synchronized( request_queue ){
+				
+				request_queue.add( request );
+			}
+			
+			request_sem.release();
+			
+			sem.reserve();
+			
+			return( request[1] );
+		}
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginInterfaceImpl.java b/org/gudy/azureus2/pluginsimpl/local/PluginInterfaceImpl.java
index 8d212f7..fb5ffa7 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginInterfaceImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginInterfaceImpl.java
@@ -36,7 +36,6 @@ import org.gudy.azureus2.pluginsimpl.local.dht.mainline.*;
 import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.ddb.DDBaseImpl;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
-import org.gudy.azureus2.pluginsimpl.local.installer.PluginInstallerImpl;
 import org.gudy.azureus2.pluginsimpl.local.ipc.IPCInterfaceImpl;
 import org.gudy.azureus2.pluginsimpl.local.ipfilter.IPFilterImpl;
 import org.gudy.azureus2.pluginsimpl.local.logging.LoggerImpl;
@@ -46,9 +45,7 @@ import org.gudy.azureus2.pluginsimpl.local.sharing.ShareManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.tracker.*;
 import org.gudy.azureus2.pluginsimpl.local.ui.*;
-import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionRepository;
-import org.gudy.azureus2.pluginsimpl.local.ui.config.ParameterRepository;
-import org.gudy.azureus2.pluginsimpl.local.ui.config.PluginConfigUIFactoryImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.config.*;
 import org.gudy.azureus2.pluginsimpl.local.utils.*;
 import org.gudy.azureus2.pluginsimpl.local.update.*;
 import org.gudy.azureus2.plugins.ipc.IPCInterface;
@@ -79,7 +76,7 @@ import com.aelitis.azureus.core.util.CopyOnWriteList;
  * @author Olivier
  *
  */
-public class 
+public final class 
 PluginInterfaceImpl 
 	implements PluginInterface, AzureusCoreComponent
 {
@@ -103,7 +100,6 @@ PluginInterfaceImpl
   private Logger				logger;
   private IPCInterfaceImpl		ipc_interface;
   protected List				children		= new ArrayList();
-  private List 					configSections 	= new ArrayList();
   private PluginStateImpl       state;
   
   /**
@@ -120,31 +116,97 @@ PluginInterfaceImpl
    */
   private String                plugin_id_to_use;
   
-  public 
+  protected 
   PluginInterfaceImpl(
   		Plugin				_plugin,
   		PluginInitializer	_initialiser,
 		Object				_initialiser_key,
 		ClassLoader			_class_loader,
+		List<File>			_verified_files,
 		String 				_key,
 		Properties 			_props,
 		String 				_pluginDir,
 		String				_plugin_id,
 		String				_plugin_version ) 
+  
+  	throws PluginException
   {
-  	plugin				= _plugin;
-  	initialiser			= _initialiser;
-  	initialiser_key		= _initialiser_key;
-  	class_loader		= _class_loader;
-  	key					= _key;
-  	pluginConfigKey 	= "Plugin." + _key;
-    props 				= new propertyWrapper(_props );
-    pluginDir 			= _pluginDir;
-    config 				= new PluginConfigImpl(this,pluginConfigKey);
-    given_plugin_id     = _plugin_id;
-    plugin_version		= _plugin_version;
-    ipc_interface		= new IPCInterfaceImpl( initialiser, plugin );
-    state               = new PluginStateImpl(this, initialiser);
+	  	// check we're being created by the core
+	  
+	  StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+
+	  int	pos = 0;
+
+	  while( !stack[pos].getClassName().equals( PluginInterfaceImpl.class.getName())){
+
+		  pos++;
+	  }	  
+	  
+	  String caller_class = stack[pos+1].getClassName();
+	  
+	  if ( !(	caller_class.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInitializer" ) ||
+			  	caller_class.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInterfaceImpl" ))){
+		  
+		  throw( new PluginException( "Invalid caller" ));
+	  }
+	  
+	  	// check we haven't been subclassed
+	  
+	  String class_name = getClass().getCanonicalName();
+	  
+	  if ( !class_name.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInterfaceImpl" )){
+		  
+		  throw( new PluginException( "Subclassing not permitted" ));
+	  }
+	  
+	  plugin				= _plugin;
+	  initialiser			= _initialiser;
+	  initialiser_key		= _initialiser_key;
+	  class_loader			= _class_loader;
+	  key					= _key;
+	  pluginConfigKey 		= "Plugin." + _key;
+	  props 				= new propertyWrapper(_props );
+	  pluginDir 			= _pluginDir;
+	  config 				= new PluginConfigImpl(this,pluginConfigKey);
+	  given_plugin_id    	= _plugin_id;
+	  plugin_version		= _plugin_version;
+	  ipc_interface			= new IPCInterfaceImpl( initialiser, plugin );
+	  state               	= new PluginStateImpl(this, initialiser);
+	  
+	  boolean verified 	= false;
+	  boolean bad		= false;
+	  
+	  if ( _plugin_id.endsWith( "_v" )){
+		  
+		  if ( plugin.getClass() == FailedPlugin.class ){
+			  
+			  verified = true;
+			  
+		  }else{
+		      if ( _verified_files != null  ){
+			    	
+	    		  File jar = FileUtil.getJarFileFromClass( plugin.getClass());
+	    		  
+	    		  if ( jar != null ){
+	    			  
+	    			  for ( File file: _verified_files ){
+	    				  
+	    				  if ( file.equals( jar )){
+	    					
+	    					  verified = true;
+	    				  }
+	    			  }
+	    		  }
+		      }
+		  }
+		  
+	      if ( !verified ){
+	    	  
+	    	  bad = true;
+	      }
+	  }
+	  
+	  PluginInitializer.setVerified( this, plugin, verified, bad );
   }
   
   	public Plugin
@@ -186,30 +248,28 @@ PluginInterfaceImpl
 		return( Constants.AZUREUS_VERSION );
 	}
 	
-
-	/**
-	 * @deprecated
-	 */
-  public void addView(PluginView view)
-  {
-    getUIManager().getSWTManager().addView(view);
-  } 
-  
   public void addConfigSection(ConfigSection section)
   {
 	// Method is used by autocat.
-  	ConfigSectionRepository.getInstance().addConfigSection(section);
-  	configSections.add(section);
+  	ConfigSectionRepository.getInstance().addConfigSection(section, this);
   }
 
   public void removeConfigSection(ConfigSection section)
   {
   	ConfigSectionRepository.getInstance().removeConfigSection(section);
-  	configSections.remove(section);
   }
   
   public ConfigSection[] getConfigSections() {
-  	return (ConfigSection[]) configSections.toArray(new ConfigSection[0]);
+  	ArrayList<ConfigSection> list = ConfigSectionRepository.getInstance().getList();
+  	for (Iterator<ConfigSection> iter = list.iterator(); iter.hasNext();) {
+			ConfigSection configSection = iter.next();
+			if (configSection instanceof ConfigSectionHolder) {
+				if (((ConfigSectionHolder)configSection).getPluginInterface() != this) {
+					iter.remove();
+				}
+			}
+		}
+  	return list.toArray(new ConfigSection[0]);
   }
   
   /**
@@ -335,6 +395,33 @@ PluginInterfaceImpl
     return pluginDir;
   }
 
+  public String getPerUserPluginDirectoryName(){
+	String name;
+	if ( pluginDir == null ){
+		name = getPluginID();
+	}else{
+		name = new File( pluginDir).getName();
+	}
+	
+	String str = new File(new File(SystemProperties.getUserPath(),"plugins"),name).getAbsolutePath();
+	
+	if ( pluginDir == null ){
+		
+		return( str );
+	}
+	
+	try{
+		if ( new File( pluginDir ).getCanonicalPath().equals( new File( str ).getCanonicalPath())){
+			
+			return( pluginDir );
+		}
+	}catch( Throwable e ){
+		
+	}
+	
+	return( str );
+  }
+  
   public void
   setPluginDirectoryName(
   	String		name )
@@ -581,30 +668,7 @@ PluginInterfaceImpl
 		  ((PluginInterfaceImpl)children.get(i)).closedownComplete();
 	  }
   }
-  
-  public void
-  firePluginEvent(
-	PluginEvent		event )
-  {
-	  Iterator it = event_listeners.iterator();
-	  
-	  while( it.hasNext()){
-
-		  try{
-			  ((PluginEventListener)it.next()).handleEvent( event );
-
-		  }catch( Throwable e ){
-
-			  Debug.printStackTrace( e );
-		  }
-	  } 
-
-	  for (int i=0;i<children.size();i++){
-
-		  ((PluginInterfaceImpl)children.get(i)).firePluginEvent(event);
-	  }
-  }
-  
+    
   public ClassLoader
   getPluginClassLoader()
   {
@@ -627,12 +691,19 @@ PluginInterfaceImpl
 			Properties local_props = new Properties(props);
 			local_props.remove("plugin.id");
 	
+			
+	 		if( id.endsWith( "_v" )){
+	  			
+	  			throw( new Exception( "Verified plugins must be loaded from a jar" ));
+	  		}
+	 		
 			PluginInterfaceImpl pi =
 				new PluginInterfaceImpl(
 			  		p,
 			  		initialiser,
 					initialiser_key,
 					class_loader,
+					null,
 					key + "." + id,
 					local_props,
 					pluginDir,
@@ -676,6 +747,17 @@ PluginInterfaceImpl
 		state.failed = true;
 	}
 	
+	protected void
+	destroy()
+	{
+		class_loader = null;
+		
+			// unhook the reference to the plugin but leave with a valid reference in case
+			// something tries to use it
+		
+		plugin = new FailedPlugin( "Plugin '" + getPluginID() + "' has been unloaded!", null );
+	}
+	
   public void
   addListener(
   	PluginListener	l )
@@ -714,18 +796,86 @@ PluginInterfaceImpl
   
   public void
   addEventListener(
-  	PluginEventListener	l )
+	  final PluginEventListener	l )
   {
-  	event_listeners.add(l);
+	  initialiser.runPEVTask(
+		 new AERunnable()
+		 {
+			 public void
+			 runSupport()
+			 {
+				 List<PluginEvent> events = initialiser.getPEVHistory();
+				 
+				 for ( PluginEvent event: events ){
+					 
+					 try{
+						 l.handleEvent( event );
+						 
+					 }catch( Throwable e ){
+						 
+						 Debug.out( e );
+					 }
+				 }
+				 event_listeners.add(l);
+			 }
+		 });
   }
-  
+
   public void
   removeEventListener(
-  	PluginEventListener	l )
+	  final PluginEventListener	l )
   {
-  	event_listeners.remove(l);
+	  initialiser.runPEVTask(
+		 new AERunnable()
+		 {
+			 public void
+			 runSupport()
+			 {
+				  event_listeners.remove(l);
+			 }
+		 });
   }
-  
+
+  public void
+  firePluginEvent(
+	  final PluginEvent		event )
+  {
+	  initialiser.runPEVTask(
+		 new AERunnable()
+		 {
+			 public void
+			 runSupport()
+			 {
+				 firePluginEventSupport( event );
+			 }
+		 });
+  }
+
+  protected void
+  firePluginEventSupport(
+	  PluginEvent		event )
+  {
+	  Iterator<PluginEventListener> it = event_listeners.iterator();
+
+	  while( it.hasNext()){
+
+		  try{
+			  PluginEventListener listener = it.next();
+			  			 
+			  listener.handleEvent( event );
+
+		  }catch( Throwable e ){
+
+			  Debug.printStackTrace( e );
+		  }
+	  } 
+
+	  for (int i=0;i<children.size();i++){
+
+		  ((PluginInterfaceImpl)children.get(i)).firePluginEvent(event);
+	  }
+  }
+
 	protected void
 	generateEvidence(
 		IndentWriter		writer )
@@ -743,6 +893,7 @@ PluginInterfaceImpl
 			String	plugin_dir = getPluginDirectoryName();
 			
 			String	type;
+			boolean	built_in = false;
 			
 			if ( plugin_dir.startsWith( shared_dir )){
 				
@@ -754,11 +905,60 @@ PluginInterfaceImpl
 
 			}else{
 				
+				built_in = true;
+				
 				type = "built-in";
 			}
 			
-			writer.println( "type:" + type + ",enabled:" + !getPluginState().isDisabled() + ",operational:" + getPluginState().isOperational());
+			PluginState ps = getPluginState();
 			
+			String	info = getPluginconfig().getPluginStringParameter( "plugin.info" );
+
+			writer.println( "type:" + type + ",enabled=" + !ps.isDisabled() + ",load_at_start=" + ps.isLoadedAtStartup() + ",operational=" + ps.isOperational() + (info==null||info.length()==0?"":( ",info=" + info )));
+			
+			if ( ps.isOperational()){
+				
+				Plugin plugin = getPlugin();
+				
+				if ( plugin instanceof AEDiagnosticsEvidenceGenerator ){
+					
+					try{
+						writer.indent();
+						
+						((AEDiagnosticsEvidenceGenerator)plugin).generate( writer );
+						
+					}catch( Throwable e ){
+						
+						writer.println( "Failed to generate plugin-specific info: " + Debug.getNestedExceptionMessage( e ));
+						
+					}finally{
+						
+						writer.exdent();
+					}
+				}
+			}else{
+				if ( !built_in ){
+					
+					File dir = new File( plugin_dir );
+					
+					if ( dir.exists()){
+						
+						String[] files = dir.list();
+						
+						if ( files != null ){
+							
+							String	files_str = "";
+							
+							for ( String f: files ){
+								
+								files_str += (files_str.length()==0?"":", ") + f;
+							}
+							
+							writer.println( "    files: " + files_str );
+						}
+					}
+				}
+			}
 		}finally{
 			
 			writer.exdent();
diff --git a/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java b/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
index a0730fa..27440fb 100644
--- a/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/PluginStateImpl.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.plugins.PluginException;
 import org.gudy.azureus2.plugins.PluginInterface;
@@ -111,6 +112,12 @@ public class PluginStateImpl implements PluginState {
 		return plugin_dir.startsWith(shared_dir);
 	}
 
+	public boolean
+	isInitialisationComplete()
+	{
+		return( initialiser.isInitialisationComplete());
+	}
+	
 	public void reload() throws PluginException {
 		// we use the "reload" method to load disabled plugins regardless of whether they are
 		// unloadable. If currently disabled then no unloading to do anyway  
@@ -141,7 +148,11 @@ public class PluginStateImpl implements PluginState {
 		  	
 		// if not dir based then just test this one
 		if (dir == null || dir.length() == 0) {
-			((UnloadablePlugin)pi.getPlugin()).unload();
+			try{
+				((UnloadablePlugin)pi.getPlugin()).unload();
+			}catch( Throwable e ){
+				Debug.out( "Plugin unload operation failed", e );
+			}
 			initialiser.unloadPlugin(this.pi);
 		} else {
 		  		
@@ -153,7 +164,11 @@ public class PluginStateImpl implements PluginState {
 				String other_dir = pi.getPluginDirectoryName();
 		  		if (other_dir == null || other_dir.length() == 0) {continue;}
 		  		if (dir.equals(other_dir)) {
-		  			((UnloadablePlugin)pi.getPlugin()).unload();
+		  			try{
+		  				((UnloadablePlugin)pi.getPlugin()).unload();
+		  			}catch( Throwable e ){
+						Debug.out( "Plugin unload operation failed", e );
+					}
 		  			initialiser.unloadPlugin( pi );
 		  		}
 			}
@@ -164,7 +179,7 @@ public class PluginStateImpl implements PluginState {
 		}
 		  	
 		setOperational(false, for_reload );
-		pi.class_loader = null;
+		pi.destroy();
 	}
 		
 	public boolean isUnloadable() {
diff --git a/org/gudy/azureus2/pluginsimpl/local/clientid/ClientIDManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/clientid/ClientIDManagerImpl.java
index 3d7a002..708079a 100644
--- a/org/gudy/azureus2/pluginsimpl/local/clientid/ClientIDManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/clientid/ClientIDManagerImpl.java
@@ -23,31 +23,22 @@
 package org.gudy.azureus2.pluginsimpl.local.clientid;
 
 import java.io.InputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URL;
-import java.net.UnknownHostException;
+import java.net.*;
 import java.util.*;
 
-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.torrent.TOTorrent;
-import org.gudy.azureus2.core3.util.AEThread;
-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.ThreadPool;
-import org.gudy.azureus2.core3.util.ThreadPoolTask;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.PluginManagerDefaults;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.clientid.ClientIDException;
 import org.gudy.azureus2.plugins.clientid.ClientIDGenerator;
 import org.gudy.azureus2.plugins.clientid.ClientIDManager;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
 
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.core.util.NetUtils;
 
 /**
  * @author parg
@@ -140,17 +131,15 @@ ClientIDManagerImpl
 	        		// incorrectly
 	        	
 	        	try{
-	        		Enumeration nis = NetworkInterface.getNetworkInterfaces();
-	        			        		
-	        		while( nis.hasMoreElements()){
+	    			List<NetworkInterface>	x = NetUtils.getNetworkInterfaces();
+	    			
+	    			for ( NetworkInterface network_interface: x ){
 	        			
-	        			NetworkInterface ni = (NetworkInterface)nis.nextElement();
-	        			
-	        			Enumeration addresses = ni.getInetAddresses();
+	        			Enumeration<InetAddress> addresses = network_interface.getInetAddresses();
 	        			
 	        			while( addresses.hasMoreElements()){
 	        				
-	        				InetAddress address = (InetAddress)addresses.nextElement();
+	        				InetAddress address = addresses.nextElement();
 	        				
 	        				if ( !address.isLoopbackAddress()){
 	        					
@@ -509,7 +498,8 @@ ClientIDManagerImpl
 				
 				Socket	target = new Socket();
 				
-			    InetAddress bindIP = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress();
+				InetSocketAddress targetSockAddress = new InetSocketAddress(  InetAddress.getByName(target_host) , target_port  );
+			    InetAddress bindIP = NetworkAdmin.getSingleton().getSingleHomedServiceBindAddress(targetSockAddress.getAddress() instanceof Inet6Address ? NetworkAdmin.IP_PROTOCOL_VERSION_REQUIRE_V6 : NetworkAdmin.IP_PROTOCOL_VERSION_REQUIRE_V4);
 			    
 		        if ( bindIP != null ){
 		        	
@@ -518,7 +508,7 @@ ClientIDManagerImpl
 
 		        // System.out.println( "filtering " + target_host + ":" + target_port );
 		        
-		        target.connect( new InetSocketAddress(  target_host, target_port  ));
+		        target.connect( targetSockAddress);
 		        
 				target.getOutputStream().write( header_out.getBytes(Constants.BYTE_ENCODING ));
 				
diff --git a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
index 2e18fbb..8546af1 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseContactImpl.java
@@ -24,6 +24,7 @@ package org.gudy.azureus2.pluginsimpl.local.ddb;
 
 import java.net.InetSocketAddress;
 
+import org.gudy.azureus2.plugins.ddb.DistributedDatabase;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseContact;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseEvent;
 import org.gudy.azureus2.plugins.ddb.DistributedDatabaseException;
@@ -34,6 +35,7 @@ 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.DHTPlugin;
 import com.aelitis.azureus.plugins.dht.DHTPluginContact;
 import com.aelitis.azureus.plugins.dht.DHTPluginOperationListener;
 import com.aelitis.azureus.plugins.dht.DHTPluginValue;
@@ -60,6 +62,12 @@ DDBaseContactImpl
 		contact		= _contact;
 	}
 	
+	public byte[] 
+	getID() 
+	{
+		return( contact.getID());
+	}
+	
 	public String
 	getName()
 	{
@@ -72,6 +80,12 @@ DDBaseContactImpl
 		return( contact.getAddress());
 	}
 	
+	public int 
+	getDHT() 
+	{
+		return( contact.getNetwork() == DHTPlugin.NW_CVS?DistributedDatabase.DHT_CVS:DistributedDatabase.DHT_MAIN );
+	}
+	
 	public boolean
 	isAlive(
 		long		timeout )
@@ -95,9 +109,10 @@ DDBaseContactImpl
 				{
 				}
 				
-				public void
+				public boolean
 				diversified()
 				{
+					return( true );
 				}
 				
 				public void
diff --git a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
index 11de6d2..b0ad0a9 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ddb/DDBaseImpl.java
@@ -307,6 +307,32 @@ DDBaseImpl
 		return( new DDBaseContactImpl( this, contact));
 	}
 	
+	public DistributedDatabaseContact
+	importContact(
+		InetSocketAddress				address,
+		byte							version,
+		int								preferred_dht )
+	
+		throws DistributedDatabaseException
+	{
+		throwIfNotAvailable();
+	
+		/*
+		if ( preferred_dht != DistributedDatabase.DHT_MAIN ){
+			Debug.outNoStack( "DDB: Importing CVS contact" );
+		}
+		*/
+		
+		DHTPluginContact	contact = getDHT().importContact( address, version, preferred_dht==DistributedDatabase.DHT_CVS );
+		
+		if ( contact == null ){
+			
+			throw( new DistributedDatabaseException( "import of '" + address + "' failed" ));
+		}
+		
+		return( new DDBaseContactImpl( this, contact ));
+	}
+	
 	public void
 	write(
 		DistributedDatabaseListener		listener,
@@ -785,9 +811,10 @@ DDBaseImpl
 			continuation_num	= _continuation_num;
 		}
 		
-		public void
+		public boolean
 		diversified()
 		{
+			return( true );
 		}
 		
 		public void 
diff --git a/org/gudy/azureus2/pluginsimpl/local/deprecate/PluginDeprecation.java b/org/gudy/azureus2/pluginsimpl/local/deprecate/PluginDeprecation.java
index 5267bef..0a5ad35 100644
--- a/org/gudy/azureus2/pluginsimpl/local/deprecate/PluginDeprecation.java
+++ b/org/gudy/azureus2/pluginsimpl/local/deprecate/PluginDeprecation.java
@@ -47,8 +47,8 @@ public class PluginDeprecation {
 	//
 
 	private final static String CONFIG_KEY = "PluginDeprecationWarnings";
-	private final static String FORUM_STABLE_LINK = "http://forum.vuze.com/forum.jspa?forumID=3";
-	private final static String FORUM_BETA_LINK = "http://forum.vuze.com/forum.jspa?forumID=4";
+	private final static String FORUM_STABLE_LINK = "http://forum.vuze.com/forum.jspa?forumID=124";
+	private final static String FORUM_BETA_LINK = "http://forum.vuze.com/forum.jspa?forumID=124";		// 01/01/2012 - only one forum now :(
 	
 	private final static int IGNORE = 0;
 	private final static int NOTIFY_ONCE = 1;
@@ -73,8 +73,6 @@ public class PluginDeprecation {
 		 * Here is where we define all deprecated call definitions that we manage.
 		 */
 		register("property listener", IGNORE, NOTIFY_EVERY);
-		register("createPluginView", IGNORE, NOTIFY_EVERY);
-		register("getSWTManager", IGNORE, IGNORE); // autostop still uses this. :(
 		register("openTorrentFile", IGNORE, NOTIFY_EVERY);
 		register("openTorrentURL", IGNORE, NOTIFY_EVERY);
 		
diff --git a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerChannelImpl.java b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerChannelImpl.java
index 1e0f403..a357d2d 100644
--- a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerChannelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerChannelImpl.java
@@ -27,6 +27,7 @@ import java.util.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfoListener;
+import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
@@ -43,6 +44,7 @@ import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.disk.DiskManagerListener;
 import org.gudy.azureus2.plugins.disk.DiskManagerRequest;
 import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadException;
 import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
@@ -55,8 +57,8 @@ public class
 DiskManagerChannelImpl 
 	implements DiskManagerChannel, DiskManagerFileInfoListener, DownloadManagerPeerListener, PieceRTAProvider
 {
-	private static int		BUFFER_MILLIS;
-	private static int		MIN_PIECES_TO_BUFFER;
+	private static int		DEFAULT_BUFFER_MILLIS;
+	private static int		DEFAULT_MIN_PIECES_TO_BUFFER;
 	
 	static{
 		COConfigurationManager.addAndFireParameterListeners(
@@ -70,8 +72,8 @@ DiskManagerChannelImpl
 				parameterChanged(
 					String parameterName )
 				{
-					BUFFER_MILLIS			= COConfigurationManager.getIntParameter( "filechannel.rt.buffer.millis" );
-					MIN_PIECES_TO_BUFFER 	= COConfigurationManager.getIntParameter( "filechannel.rt.buffer.pieces" );
+					DEFAULT_BUFFER_MILLIS			= COConfigurationManager.getIntParameter( "filechannel.rt.buffer.millis" );
+					DEFAULT_MIN_PIECES_TO_BUFFER 	= COConfigurationManager.getIntParameter( "filechannel.rt.buffer.pieces" );
 				}
 			});
 	}
@@ -83,17 +85,14 @@ DiskManagerChannelImpl
 	
 	private static final int MAX_READ_CHUNK_DEFAULT	= 64*1024;
 	
-	private static final Comparator comparator = new
-		Comparator()
+	private static final Comparator<dataEntry> comparator = new
+		Comparator<dataEntry>()
 		{
 			public int 
 		   	compare(
-		   		Object _o1, 
-				Object _o2)
+		   		dataEntry o1, 
+		   		dataEntry o2)
 			{
-				dataEntry	o1 = (dataEntry)_o1;
-				dataEntry	o2 = (dataEntry)_o2;
-				
 				long	offset1 = o1.getOffset();
 				long	length1	= o1.getLength();
 				
@@ -127,7 +126,7 @@ DiskManagerChannelImpl
 	
 		// hack to allow other components to be informed when channels are created
 	
-	private static CopyOnWriteList	listeners = new CopyOnWriteList();
+	private static CopyOnWriteList<channelCreateListener>	listeners = new CopyOnWriteList<channelCreateListener>();
 	
 	public static void 
 	addListener(
@@ -147,12 +146,12 @@ DiskManagerChannelImpl
 	reportCreated(
 		DiskManagerChannel	channel )
 	{
-		Iterator it = listeners.iterator();
+		Iterator<channelCreateListener> it = listeners.iterator();
 		
 		while( it.hasNext()){
 			
 			try{
-				((channelCreateListener)it.next()).channelCreated( channel );
+				it.next().channelCreated( channel );
 				
 			}catch( Throwable e ){
 				
@@ -174,11 +173,11 @@ DiskManagerChannelImpl
 	private org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl	plugin_file;
 	private org.gudy.azureus2.core3.disk.DiskManagerFileInfo					core_file;
 	
-	private Set	data_written = new TreeSet( comparator );
+	private Set<dataEntry>	data_written = new TreeSet<dataEntry>( comparator );
 	
 	private int compact_delay	= COMPACT_DELAY;
 	
-	private List	waiters	= new ArrayList();
+	private List<AESemaphore>	waiters	= new ArrayList<AESemaphore>();
 
 	private long	file_offset_in_torrent;
 	private long	piece_size;
@@ -187,11 +186,13 @@ DiskManagerChannelImpl
 	
 	private long	start_position;
 	private long	start_time;
-	private long	current_position;
+	
+	private volatile long	current_position;
 	
 	private request	current_request;
 	
-	private long	buffer_millis;
+	private long	buffer_millis_override;
+	private long	buffer_delay_millis;
 	
 	private PEPeerManager	peer_manager;
 	
@@ -199,15 +200,33 @@ DiskManagerChannelImpl
 	
 	private int		channel_id;
 	
+	private volatile boolean	destroyed;
+	
 	protected
 	DiskManagerChannelImpl(
 		DownloadImpl															_download,
 		org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl		_plugin_file )
+	
+		throws DownloadException
 	{
 		download		= _download;
 		plugin_file		= _plugin_file;
 		
 		core_file		= plugin_file.getCore();
+
+		DownloadManager core_download = core_file.getDownloadManager();
+		
+		if ( core_download.getTorrent() == null ){
+			
+			throw( new DownloadException( "Torrent invalid" ));
+		}
+		
+		if ( core_download.isDestroyed()){
+			
+			Debug.out( "Download has been removed" );
+			
+			throw( new DownloadException( "Download has been removed" ));
+		}
 		
 		synchronized( DiskManagerChannelImpl.class ){
 			
@@ -222,7 +241,7 @@ DiskManagerChannelImpl
 
 		rtas	= new long[torrent.getNumberOfPieces()];
 		
-		core_file.getDownloadManager().addPeerListener(this);
+		core_download.addPeerListener( this );
 			
 		for (int i=0;i<core_file.getIndex();i++){
 				
@@ -279,6 +298,18 @@ DiskManagerChannelImpl
 		return( current_request );
 	}
 	
+	public long 
+	getPosition() 
+	{
+		return( current_position );
+	}
+	
+	public boolean 
+	isDestroyed() 
+	{
+		return( destroyed );
+	}
+	
 	public void
 	dataWritten(
 		long	offset,
@@ -300,13 +331,13 @@ DiskManagerChannelImpl
 				
 				compact_delay	= COMPACT_DELAY;
 				
-				Iterator	it = data_written.iterator();
+				Iterator<dataEntry>	it = data_written.iterator();
 				
 				dataEntry	prev_e	= null;
 				
 				while( it.hasNext()){
 					
-					dataEntry	this_e = (dataEntry)it.next();
+					dataEntry	this_e = it.next();
 					
 					if ( prev_e == null ){
 						
@@ -343,7 +374,7 @@ DiskManagerChannelImpl
 		
 			for (int i=0;i<waiters.size();i++){
 					
-				((AESemaphore)waiters.get(i)).release();
+				waiters.get(i).release();
 			}
 		}
 	}
@@ -402,7 +433,9 @@ DiskManagerChannelImpl
    		
    		long	rate = byte_rate.getAverage();
    		
-   		long	buffer_bytes = ( BUFFER_MILLIS * rate ) / 1000;
+   		int	buffer_millis = (int)(buffer_millis_override==0?DEFAULT_BUFFER_MILLIS:buffer_millis_override);
+   		
+   		long	buffer_bytes = ( buffer_millis * rate ) / 1000;
    		
    		int	pieces_to_buffer = (int)( buffer_bytes / piece_size );
    		
@@ -411,11 +444,11 @@ DiskManagerChannelImpl
    			pieces_to_buffer	= 1;
    		}
    		
-   		int	millis_per_piece = BUFFER_MILLIS/pieces_to_buffer; 
+   		int	millis_per_piece = buffer_millis/pieces_to_buffer; 
 
-   		if ( pieces_to_buffer < MIN_PIECES_TO_BUFFER ){
+   		if ( pieces_to_buffer < DEFAULT_MIN_PIECES_TO_BUFFER ){
    			
-   			pieces_to_buffer = MIN_PIECES_TO_BUFFER;
+   			pieces_to_buffer = DEFAULT_MIN_PIECES_TO_BUFFER;
    		}
    		   		
    		// System.out.println( "rate = " + rate + ", buffer_bytes = " + buffer_bytes + ", pieces = " + pieces_to_buffer + ", millis_per_piece = " + millis_per_piece );
@@ -424,13 +457,13 @@ DiskManagerChannelImpl
    		 
    		long	now = SystemTime.getCurrentTime();
    		
-   		now += buffer_millis;
+   		now += buffer_delay_millis;
    		
    		for (int i=first_piece;i<first_piece+pieces_to_buffer&&i<rtas.length;i++){
    			
    			rtas[i]	= now + (( i - first_piece ) * millis_per_piece );
    		}
-   		
+   		   		
    		return( rtas );
    	}
    
@@ -443,13 +476,13 @@ DiskManagerChannelImpl
    	public long
    	getStartPosition()
    	{
-   		return( start_position );
+   		return( file_offset_in_torrent + start_position );
    	}
    
 	public long
 	getCurrentPosition()
 	{
-		return( current_position );
+		return( file_offset_in_torrent + current_position );
 	}
 	
 	public long
@@ -459,18 +492,21 @@ DiskManagerChannelImpl
 		
 		if ( r == null ){
 			
-			return( current_position );
+			return( file_offset_in_torrent + current_position );
 		}
 		
-		return( current_position + r.getAvailableBytes());
+		return( file_offset_in_torrent + current_position + r.getAvailableBytes());
 	}
 	
 	public void
 	setBufferMillis(
-		long	millis )
+		long	millis,
+		long	delay_millis )
 	{
-		buffer_millis = millis;
+		buffer_millis_override	= millis;
+		buffer_delay_millis 	= delay_millis;
 	}
+	
 	public String
 	getUserAgent()
 	{
@@ -487,10 +523,14 @@ DiskManagerChannelImpl
 	public void
 	destroy()
 	{
+		destroyed	= true;
+		
 		core_file.removeListener( this );
 		
 		core_file.getDownloadManager().removePeerListener(this);
 		
+		core_file.close();
+		
 		if ( peer_manager != null ){
 			
 			peer_manager.getPiecePicker().removeRTAProvider( this );
@@ -526,7 +566,7 @@ DiskManagerChannelImpl
 		private int		request_type;
 		private long	request_offset;
 		private long	request_length;
-		private List	listeners	= new ArrayList();
+		private List<DiskManagerListener>	listeners	= new ArrayList<DiskManagerListener>();
 		
 		private String	user_agent;
 		
@@ -619,7 +659,7 @@ DiskManagerChannelImpl
 			
 			synchronized( data_written ){
 
-				Iterator	it = data_written.iterator();
+				Iterator<dataEntry>	it = data_written.iterator();
 				
 					// may not have been compacted to we need to aggregate contigous entry lengths 
 				
@@ -627,7 +667,7 @@ DiskManagerChannelImpl
 				
 				while( it.hasNext()){
 					
-					dataEntry	entry = (dataEntry)it.next();
+					dataEntry	entry = it.next();
 					
 					long	entry_offset = entry.getOffset();
 					long	entry_length = entry.getLength();
@@ -674,21 +714,23 @@ DiskManagerChannelImpl
 			
 			long	pos = request_offset;
 			
+			long	download_not_running_time	= 0;
+			
 			try{
 
 				while( rem > 0 && !cancelled ){
 					
-					int	len = 0;
+					long	len = 0;
 					
 					synchronized( data_written ){
 						
 						current_position = pos;
 						
-						Iterator	it = data_written.iterator();
+						Iterator<dataEntry>	it = data_written.iterator();
 						
 						while( it.hasNext()){
 							
-							dataEntry	entry = (dataEntry)it.next();
+							dataEntry	entry = it.next();
 							
 							long	entry_offset = entry.getOffset();
 							
@@ -703,7 +745,7 @@ DiskManagerChannelImpl
 							
 							if ( available > 0 ){
 								
-								len = (int)available;
+								len = available;
 								
 								break;
 							}
@@ -711,10 +753,10 @@ DiskManagerChannelImpl
 					}				
 					
 					if ( len > 0 ){
-						
+												
 						if ( len > rem ){
 							
-							len = (int)rem;
+							len = rem;
 						}
 						
 						if ( len > max_read_chunk ){
@@ -722,9 +764,9 @@ DiskManagerChannelImpl
 							len = max_read_chunk;
 						}
 						
-						DirectByteBuffer buffer = core_file.read( pos, len );
+						DirectByteBuffer buffer = core_file.read( pos, (int)len );
 	
-						inform( new event( new PooledByteBufferImpl( buffer ), pos, len ));
+						inform( new event( new PooledByteBufferImpl( buffer ), pos, (int)len ));
 						
 						pos += len;
 						
@@ -737,7 +779,7 @@ DiskManagerChannelImpl
 							current_position = pos;
 						}
 					}else{
-	
+							
 						inform( new event( pos ));
 						
 						synchronized( data_written ){
@@ -747,8 +789,41 @@ DiskManagerChannelImpl
 						
 						try{
 
-							wait_sem.reserve();
+							while( true && !cancelled ){
 							
+								if ( wait_sem.reserve( 500 )){
+									
+									break;
+								}
+								
+								DownloadManager dm = core_file.getDownloadManager();
+								
+								if ( dm.isDestroyed()){
+									
+									throw( new Exception( "Download has been removed" ));
+									
+								}else{
+									
+									int	state = dm.getState();
+									
+									if ( state == DownloadManager.STATE_ERROR || state == DownloadManager.STATE_STOPPED ){
+										
+										long	now = SystemTime.getMonotonousTime();
+										
+										if ( download_not_running_time == 0 ){
+											
+											download_not_running_time = now;
+											
+										}else if ( now - download_not_running_time > 15*1000 ){ 
+											
+											throw( new Exception( "Download has been stopped" ));
+										}
+									}else{
+										
+										download_not_running_time = 0;
+									}
+								}
+							}
 						}finally{
 							
 							synchronized( data_written ){
diff --git a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerFileInfoImpl.java b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerFileInfoImpl.java
index 34eae69..3c8bbeb 100644
--- a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerFileInfoImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerFileInfoImpl.java
@@ -27,6 +27,8 @@ import java.io.File;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
@@ -38,8 +40,9 @@ import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
  *
  */
 
-public class DiskManagerFileInfoImpl
-       implements DiskManagerFileInfo 
+public class 
+DiskManagerFileInfoImpl
+	implements DiskManagerFileInfo 
 {
 	protected DownloadImpl										download;
 	protected org.gudy.azureus2.core3.disk.DiskManagerFileInfo 	core;
@@ -54,30 +57,74 @@ public class DiskManagerFileInfoImpl
 	}
 
 	public void setPriority(boolean b) {
-	  core.setPriority(b);
+	  core.setPriority(b?1:0);
 	}
 	
 	public void setSkipped(boolean b) {
 	  core.setSkipped(b);
 	}
 	 
+	public int 
+	getNumericPriorty() 
+	{
+		return( core.getPriority());
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		core.setPriority( priority );
+	}
+	
 	public void
 	setDeleted(boolean b)
 	{
+		int st = core.getStorageType();
+		
+		int	target_st;
+		
 		if ( b ){
-						
-			core.setStorageType( org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_COMPACT );
+			
+			if ( st == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_LINEAR ){
+				
+				target_st = org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_COMPACT;
+				
+			}else if ( st == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_REORDER ){
+				
+				target_st = org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_REORDER_COMPACT;
+				
+			}else{
+				
+				return;
+			}
 			
 		}else{
 			
-			core.setStorageType( org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_LINEAR );
+			if ( st == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_COMPACT ){
+				
+				target_st = org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_LINEAR;
+				
+			}else if ( st == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_REORDER_COMPACT ){
+				
+				target_st = org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_REORDER;
+				
+			}else{
+				
+				return;
+			}		
 		}
+		
+		core.setStorageType( target_st );
+
 	}
 	
 	public boolean
 	isDeleted()
 	{
-		return( core.getStorageType() ==  org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_COMPACT );
+		int st = core.getStorageType();
+		
+		return( st ==  org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_COMPACT || st == org.gudy.azureus2.core3.disk.DiskManagerFileInfo.ST_REORDER_COMPACT );
 	}
 	
 	public void
@@ -109,6 +156,13 @@ public class DiskManagerFileInfoImpl
 	  return core.getFile(false);
 	}
 	
+	public File
+	getFile(
+		boolean	follow_link )
+	{
+		return( core.getFile( follow_link ));
+	}
+	
 	public int getFirstPieceNumber() {
 	  return core.getFirstPieceNumber();
 	}
@@ -128,7 +182,7 @@ public class DiskManagerFileInfoImpl
 	}
 		
 	public boolean isPriority() {
-	  return core.isPriority();
+	  return core.getPriority() != 0;
 	}
 	
 	public boolean isSkipped() {
@@ -163,15 +217,23 @@ public class DiskManagerFileInfoImpl
 	public DiskManagerChannel
 	createChannel()
 	 	throws DownloadException
-	{
-		if ( core.getDownloadManager().getTorrent() == null ){
-			
-			throw( new DownloadException( "Torrent invalid" ));
-		}
-		
+	{	
 		return( new DiskManagerChannelImpl( download, this ));
 	}
 	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		return( DiskManagerRandomReadController.createRequest( download, this, file_offset, length, reverse_order, listener ));
+	}
+	
+	
 	// not visible to plugin interface
 	public org.gudy.azureus2.core3.disk.DiskManagerFileInfo
 	getCore()
diff --git a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerImpl.java
index 7af10db..df50d6d 100644
--- a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerImpl.java
@@ -27,7 +27,11 @@ package org.gudy.azureus2.pluginsimpl.local.disk;
  */
 
 
+import org.gudy.azureus2.core3.disk.DiskManagerPiece;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.plugins.disk.*;
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
 
 public class 
 DiskManagerImpl
@@ -47,4 +51,193 @@ DiskManagerImpl
 	{
 		return( disk_manager );	
 	}
+	
+	public DiskManagerReadRequest 
+	read(
+		int 									piece_number, 
+		int 									offset, 
+		int 									length,
+		final DiskManagerReadRequestListener	listener )
+	
+		throws DiskManagerException 
+	{
+		if ( !disk_manager.checkBlockConsistencyForRead( "plugin", false, piece_number, offset, length )){
+			
+			throw( new DiskManagerException( "read invalid - parameters incorrect or piece incomplete" ));
+		}
+		
+		final DMRR request = new DMRR( disk_manager.createReadRequest( piece_number, offset, length ));
+		
+		disk_manager.enqueueReadRequest( 
+			request.getDelegate(),
+			new org.gudy.azureus2.core3.disk.DiskManagerReadRequestListener()
+			{
+				public void 
+				readCompleted( 
+					org.gudy.azureus2.core3.disk.DiskManagerReadRequest 	_request, 
+					DirectByteBuffer 										_data )
+				{
+					listener.complete( request, new PooledByteBufferImpl( _data ));
+				}
+
+				public void 
+				readFailed( 
+					org.gudy.azureus2.core3.disk.DiskManagerReadRequest 	_request, 
+					Throwable		 										_cause )
+				{
+					listener.failed( request, new DiskManagerException( "read failed", _cause ));
+				}
+
+				public int
+				getPriority()
+				{
+					return( 0 );
+				}
+				
+				public void 
+				requestExecuted(
+					long 	bytes )
+				{					
+				}
+			});
+		
+		return( request );
+	}
+	
+	public DiskManagerWriteRequest
+	write(
+		final int								piece_number,
+		final int								offset,
+		PooledByteBuffer						data,
+		final DiskManagerWriteRequestListener	listener )
+	
+		throws DiskManagerException
+	{
+		DirectByteBuffer buffer = ((PooledByteBufferImpl)data).getBuffer();
+				
+		if ( !disk_manager.checkBlockConsistencyForWrite( "plugin", piece_number, offset, buffer )){
+			
+			throw( new DiskManagerException( "write invalid - parameters incorrect" ));
+		}
+		
+		final int	length = buffer.remaining( DirectByteBuffer.SS_EXTERNAL );
+		
+		final DMWR request = new DMWR( disk_manager.createWriteRequest( piece_number, offset, buffer, null ),length );
+		
+		disk_manager.enqueueWriteRequest(
+			request.getDelegate(),
+			new org.gudy.azureus2.core3.disk.DiskManagerWriteRequestListener()
+			{
+				public void 
+				writeCompleted( 
+					org.gudy.azureus2.core3.disk.DiskManagerWriteRequest 	_request )
+				{
+					DiskManagerPiece[]	dm_pieces = disk_manager.getPieces();
+				
+					DiskManagerPiece	dm_piece = dm_pieces[piece_number];
+
+					if (!dm_piece.isDone()){
+						
+						int	current_offset = offset;
+						
+						for ( int i=0;i<length;i+=DiskManager.BLOCK_SIZE ){
+						
+							dm_piece.setWritten( current_offset / DiskManager.BLOCK_SIZE );
+							
+							current_offset += DiskManager.BLOCK_SIZE;
+						}
+					}
+					
+					listener.complete( request );
+				}
+
+				public void 
+				writeFailed( 
+					org.gudy.azureus2.core3.disk.DiskManagerWriteRequest 	_request, 
+					Throwable		 										_cause )
+				{
+					listener.failed( request, new DiskManagerException( "read failed", _cause ));
+				}
+			});
+		
+		return( request );
+	}
+	
+	private class
+	DMRR
+		implements org.gudy.azureus2.plugins.disk.DiskManagerReadRequest
+	{
+		private org.gudy.azureus2.core3.disk.DiskManagerReadRequest		request;
+		
+		private
+		DMRR(
+			org.gudy.azureus2.core3.disk.DiskManagerReadRequest	_request )
+		{
+			request = _request;
+		}
+		
+		private org.gudy.azureus2.core3.disk.DiskManagerReadRequest
+		getDelegate()
+		{
+			return( request );
+		}
+		
+		public int
+		getPieceNumber()
+		{
+			return( request.getPieceNumber());
+		}
+		
+		public int
+		getOffset()
+		{
+			return( request.getOffset());
+		}
+		
+		public int
+		getLength()
+		{
+			return( request.getLength());
+		}
+	}
+	
+	private class
+	DMWR
+		implements org.gudy.azureus2.plugins.disk.DiskManagerWriteRequest
+	{
+		private org.gudy.azureus2.core3.disk.DiskManagerWriteRequest		request;
+		private int															length;
+		
+		private
+		DMWR(
+			org.gudy.azureus2.core3.disk.DiskManagerWriteRequest	_request,
+			int														_length )
+		{
+			request = _request;
+		}
+		
+		private org.gudy.azureus2.core3.disk.DiskManagerWriteRequest
+		getDelegate()
+		{
+			return( request );
+		}
+		
+		public int
+		getPieceNumber()
+		{
+			return( request.getPieceNumber());
+		}
+		
+		public int
+		getOffset()
+		{
+			return( request.getOffset());
+		}
+		
+		public int
+		getLength()
+		{
+			return( length );
+		}
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerRandomReadController.java b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerRandomReadController.java
new file mode 100644
index 0000000..ddd01ee
--- /dev/null
+++ b/org/gudy/azureus2/pluginsimpl/local/disk/DiskManagerRandomReadController.java
@@ -0,0 +1,847 @@
+/*
+ * Created on Oct 10, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.pluginsimpl.local.disk;
+
+import java.util.*;
+
+import org.gudy.azureus2.core3.disk.DiskManager;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfoListener;
+import org.gudy.azureus2.core3.disk.DiskManagerPiece;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.peer.PEPiece;
+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.core3.util.AESemaphore;
+import org.gudy.azureus2.core3.util.AsyncDispatcher;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DirectByteBuffer;
+import org.gudy.azureus2.core3.util.SimpleTimer;
+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.plugins.disk.DiskManagerEvent;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.download.DownloadException;
+import org.gudy.azureus2.plugins.download.DownloadListener;
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
+import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
+
+import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
+
+public class 
+DiskManagerRandomReadController 
+{
+	private static Map<DownloadImpl, DiskManagerRandomReadController>	controller_map = new HashMap<DownloadImpl, DiskManagerRandomReadController>();
+	
+	public static DiskManagerRandomReadRequest
+	createRequest(
+		DownloadImpl				download,
+		DiskManagerFileInfoImpl		file,
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		if ( file_offset < 0 || file_offset >= file.getLength()){
+			
+			throw( new DownloadException( "invalid file offset " + file_offset + ", file size=" + file.getLength()));
+		}
+		
+		if ( length <= 0 || file_offset + length > file.getLength()){
+			
+			throw( new DownloadException( "invalid read length " + length + ", offset=" + file_offset + ", file size=" + file.getLength()));
+		}
+		
+		DiskManagerRandomReadController controller;
+		
+		synchronized( controller_map ){
+			
+			controller = controller_map.get( download );
+			
+			if ( controller == null ){
+				
+				controller = new DiskManagerRandomReadController( download );
+				
+				controller_map.put( download, controller );
+			}
+		
+			return( controller.addRequest( file, file_offset, length, reverse_order, listener ));
+		}
+	}
+	
+	private DownloadImpl		download;
+	
+	private List<DiskManagerRandomReadRequestImpl>	requests = new ArrayList<DiskManagerRandomReadRequestImpl>();
+	
+	private AsyncDispatcher	dispatcher = new AsyncDispatcher( "dm_rand_reads");
+	
+	private boolean	set_force_start;
+	
+	private TimerEventPeriodic		timer_event;
+	private volatile boolean		busy;
+	private volatile long			last_busy_time;
+	
+	
+	private
+	DiskManagerRandomReadController(
+		DownloadImpl		_download )
+	{
+		download	= _download;
+		
+		timer_event = 
+			SimpleTimer.addPeriodicEvent(
+				"dmrr:timer",
+				5000,
+				new TimerEventPerformer()
+				{
+					public void 
+					perform(
+						TimerEvent event) 
+					{
+						if ( busy || SystemTime.getMonotonousTime() - last_busy_time < 5000 ){
+							
+							return;
+						}
+						
+						synchronized( controller_map ){
+							
+							synchronized( requests ){
+								
+								if ( requests.size() > 0 ){
+									
+									return;
+								}
+							}
+							
+							controller_map.remove( download );
+							
+							if ( set_force_start ){
+								
+								download.setForceStart( false );
+							}
+						}
+												
+						timer_event.cancel();
+
+					}
+				});
+	}
+	
+	private DiskManagerRandomReadRequest
+	addRequest(
+		DiskManagerFileInfoImpl		file,
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	{
+		DiskManagerRandomReadRequestImpl request = new DiskManagerRandomReadRequestImpl( file, file_offset, length, reverse_order, listener );
+		
+		synchronized( requests ){
+			
+			requests.add( request );
+		}
+		
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void
+				runSupport()
+				{
+					try{
+						busy	= true;
+					
+						executeRequest();
+						
+					}finally{
+						
+						busy 			= false;
+						last_busy_time	= SystemTime.getMonotonousTime();
+					}
+				}
+			});
+		
+		return( request );
+	}
+
+	private void
+	executeRequest()
+	{
+		DiskManagerRandomReadRequestImpl	request;
+	
+		synchronized( requests ){
+			
+			if ( requests.isEmpty()){
+				
+				return;
+			}
+			
+			request = requests.remove( 0 );
+		}
+		
+		if ( request.isCancelled()){
+			
+			return;
+		}
+	
+		DiskManagerFileInfoListener	info_listener	= null;
+		
+		org.gudy.azureus2.core3.disk.DiskManagerFileInfo core_file		= request.getFile().getCore();
+
+		DownloadManager core_download = core_file.getDownloadManager();
+
+		int			prev_hint_piece	= -1;
+		int			curr_hint_piece = -1;
+
+		try{
+			
+			if ( core_download.getTorrent() == null ){
+				
+				throw( new DownloadException( "Torrent invalid" ));
+			}
+			
+			if ( core_download.isDestroyed()){
+				
+				Debug.out( "Download has been removed" );
+				
+				throw( new DownloadException( "Download has been removed" ));
+			}
+				
+			TOTorrentFile	tf = core_file.getTorrentFile();
+			
+			TOTorrent 	torrent = tf.getTorrent();
+			
+			TOTorrentFile[]	tfs = torrent.getFiles();
+										
+			long	core_file_start_byte = 0;
+			
+			for (int i=0;i<core_file.getIndex();i++){
+					
+				core_file_start_byte += tfs[i].getLength();
+			}
+			
+			long download_byte_start 	= core_file_start_byte + request.getOffset();
+			long download_byte_end		= download_byte_start + request.getLength();
+			
+			if ( download_byte_end > core_file.getLength()){
+				
+				throw( new DownloadException( "Request too large: file size=" + core_file.getLength() + ", request=" + download_byte_start + " -> " + download_byte_end ));
+			}
+			
+			int piece_size	= (int)tf.getTorrent().getPieceLength();
+			
+			if ( core_file.getDownloaded() != core_file.getLength()){
+				
+				if ( core_file.isSkipped()){
+					
+					core_file.setSkipped( false );
+				}
+				
+				boolean	force_start = download.isForceStart();
+				
+				if ( !force_start ){
+										
+					download.setForceStart( true );
+					
+					set_force_start = true;
+					
+					final AESemaphore running_sem = new AESemaphore( "rs" );
+					
+					DownloadListener dl_listener = 
+						new DownloadListener()
+						{
+							public void
+							stateChanged(
+								Download		download,
+								int				old_state,
+								int				new_state )
+							{
+								if ( new_state == Download.ST_DOWNLOADING || new_state == Download.ST_SEEDING ){
+									
+									running_sem.release();
+								}
+							}
+	
+							public void
+							positionChanged(
+								Download	download, 
+								int oldPosition,
+								int newPosition )
+							{							
+							}
+						};
+						
+					download.addListener( dl_listener );
+					
+					try{			
+						if ( download.getState() != Download.ST_DOWNLOADING && download.getState() != Download.ST_SEEDING ){
+							
+							if ( !running_sem.reserve( 10*1000 )){
+								
+								throw( new DownloadException( "timeout waiting for download to start" ));
+							}
+						}
+					}finally{
+						
+						download.removeListener( dl_listener );
+					}
+				}
+			}
+			
+			boolean	is_reverse = request.isReverse();
+			
+			final AESemaphore	wait_sem = new AESemaphore( "rr:waiter" );
+			
+			info_listener = new 
+				DiskManagerFileInfoListener()
+				{
+					public void
+					dataWritten(
+						long	offset,
+						long	length )
+					{
+						wait_sem.release();
+					}
+					
+					public void
+					dataChecked(
+						long	offset,
+						long	length )
+					{	
+					}
+				};
+				
+			long 		start_time 		= SystemTime.getMonotonousTime();
+			boolean		has_started		= false;
+						
+			core_file.addListener( info_listener );
+			
+			//System.out.println( "Request starts" );
+			
+			while( download_byte_start < download_byte_end ){
+				
+				if ( request.isCancelled()){
+					
+					throw( new Exception( "request cancelled" ));
+				}
+				
+				//System.out.println( "Request current: " + download_byte_start + " -> " + download_byte_end );
+
+				long	now = SystemTime.getMonotonousTime();
+				
+				int	piece_start 		= (int)( download_byte_start / piece_size );
+				int	piece_start_offset	= (int)( download_byte_start % piece_size );
+				
+				int	piece_end	 		= (int)( ( download_byte_end - 1 ) / piece_size );
+				int	piece_end_offset 	= (int)( ( download_byte_end - 1 ) % piece_size ) + 1;	
+
+				//System.out.println( "    piece details: " + piece_start + "/" + piece_start_offset + " -> " + piece_end + "/" + piece_end_offset );
+				
+				DiskManagerPiece[] pieces = null;
+				
+				DiskManager disk_manager = core_download.getDiskManager();
+				
+				if ( disk_manager != null ){
+					
+					pieces = disk_manager.getPieces();					
+				}
+				
+				long	avail_start;
+				long	avail_end;
+				
+				if ( pieces == null ){
+					
+					if ( core_file.getDownloaded() == core_file.getLength()){
+						
+						avail_start = download_byte_start;
+						avail_end	= download_byte_end;
+						
+					}else{
+						
+						if ( now - start_time < 10000 && !has_started ){
+							
+							wait_sem.reserve( 250 );
+							
+							continue;
+						}
+						
+						throw( new Exception( "download stopped" ));
+					}
+				}else{
+					
+					has_started = true;
+
+					if ( is_reverse ){
+						
+						long	min_done = download_byte_end;
+						
+						for ( int i=piece_end; i>= piece_start; i-- ){
+						
+							int	p_start = i==piece_start?piece_start_offset:0;
+							int	p_end 	= i==piece_end?piece_end_offset:piece_size;
+							
+							DiskManagerPiece piece = pieces[i];
+							
+							boolean[] done = piece.getWritten();
+							
+							if ( done == null ){
+								
+								if ( piece.isDone()){
+									
+									min_done = i*piece_size;
+									
+									continue;
+									
+								}else{
+									
+									break;
+								}
+							}
+							
+							int	block_size = piece.getBlockSize( 0 );
+							
+							int	first_block = p_start/block_size;
+							int	last_block 	= (p_end-1)/block_size;
+														
+							for ( int j=last_block;j>=first_block;j--){
+								
+								if ( done[j] ){
+									
+									min_done = i*piece_size + j*block_size;
+									
+								}else{
+									
+									break;
+								}
+							}
+						}
+						
+						avail_start = Math.max( download_byte_start, min_done );
+						avail_end	= download_byte_end;
+					}else{
+						
+						long	max_done = download_byte_start;
+						
+						for ( int i=piece_start; i <= piece_end; i++ ){
+						
+							int	p_start = i==piece_start?piece_start_offset:0;
+							int	p_end 	= i==piece_end?piece_end_offset:piece_size;
+							
+							DiskManagerPiece piece = pieces[i];
+							
+							boolean[] done = piece.getWritten();
+							
+							if ( done == null ){
+								
+								if ( piece.isDone()){
+									
+									max_done = (i+1)*piece_size;
+									
+									continue;
+									
+								}else{
+									
+									break;
+								}
+							}
+							
+							int	block_size = piece.getBlockSize( 0 );
+							
+							int	first_block = p_start/block_size;
+							int	last_block 	= (p_end-1)/block_size;
+														
+							for ( int j=first_block;j<=last_block;j++){
+								
+								if ( done[j] ){
+									
+									max_done = i*piece_size + (j+1)*block_size;
+									
+								}else{
+									
+									break;
+								}
+							}
+						}
+						
+						avail_start = download_byte_start;
+						avail_end	= Math.min( download_byte_end, max_done );			
+					}
+				}
+				
+				//System.out.println( "    avail: " + avail_start + " -> " + avail_end );
+						
+				int max_chunk = 128*1024;
+								
+				if ( avail_end > avail_start ){
+					
+					long length = avail_end - avail_start;
+					
+					if ( length > max_chunk ){
+												
+						if ( is_reverse ){
+						
+							avail_start = avail_end - max_chunk;
+							
+						}else{
+							
+							avail_end	= avail_start + max_chunk;
+						}
+					}
+					
+					//System.out.println( "got data: " + avail_start + " -> " + avail_end );
+					
+					long	read_offset = avail_start - core_file_start_byte;
+					int		read_length	= (int)( avail_end - avail_start );
+					
+					DirectByteBuffer buffer = core_file.read( read_offset, read_length );
+					
+					request.dataAvailable( buffer, read_offset, read_length );
+						
+					if ( is_reverse ){
+						
+						download_byte_end = avail_start;
+						
+					}else{
+						
+						download_byte_start = avail_end;
+					}
+					
+					continue;
+				}
+				
+				PEPeerManager pm = core_download.getPeerManager();
+				
+				if ( pm == null ){
+					
+					if ( now - start_time < 10000 && !has_started ){
+						
+						wait_sem.reserve( 250 );
+						
+						continue;
+					}
+					
+					throw( new Exception( "download stopped" ));
+					
+				}else{
+					
+					has_started = true;
+				}
+				
+				PiecePicker picker = pm.getPiecePicker();
+				
+				picker.setReverseBlockOrder( is_reverse );
+				
+				int	hint_piece;
+				int	hint_offset;
+				int	hint_length;
+				
+				if ( piece_start == piece_end ){
+					
+					hint_piece	= piece_start;
+					hint_offset = piece_start_offset;
+					hint_length	= piece_end_offset - piece_start_offset;
+					
+				}else{
+					
+					if ( is_reverse ){
+					
+						hint_piece 	= piece_end;
+						hint_offset = 0;
+						hint_length	= piece_end_offset;
+	
+					}else{
+					
+						hint_piece	= piece_start;
+						hint_offset = piece_start_offset;
+						hint_length	= piece_size - piece_start_offset;
+					}
+				}
+				
+				if ( curr_hint_piece == -1 ){
+					
+					int[] existing = picker.getGlobalRequestHint();
+					
+					if ( existing != null ){
+						
+						curr_hint_piece = existing[0];
+					}
+				}
+				
+				//System.out.println( "hint: " + hint_piece + "/" + hint_offset + "/" + hint_length + ": curr=" + curr_hint_piece + ", prev=" + prev_hint_piece );
+				
+				picker.setGlobalRequestHint( hint_piece, hint_offset, hint_length );
+				
+				if ( hint_piece != curr_hint_piece ){
+					
+					prev_hint_piece = curr_hint_piece;
+					
+					curr_hint_piece = hint_piece;
+				}			
+				
+				if ( prev_hint_piece != -1  ){
+				
+					clearHint( pm, prev_hint_piece );
+				}
+				
+				wait_sem.reserve( 250 );
+			}
+		}catch( Throwable e ){
+			
+			request.failed( e );
+			
+		}finally{
+			
+			PEPeerManager pm = core_download.getPeerManager();
+			
+			if ( pm != null ){
+
+				PiecePicker picker = pm.getPiecePicker();
+				
+				if ( picker != null ){
+					
+					picker.setReverseBlockOrder( false );
+					
+					picker.setGlobalRequestHint( -1, 0, 0 );
+					
+					if ( curr_hint_piece != -1  ){
+						
+						clearHint( pm, curr_hint_piece );
+					}
+				}
+			}
+			
+			if ( info_listener != null ){
+				
+				core_file.removeListener( info_listener );
+			}
+		}
+	}
+	
+	private void
+	clearHint(
+		PEPeerManager	pm,
+		int				hint_piece )
+	{
+		PEPiece piece = pm.getPiece( hint_piece );
+		
+		if ( piece != null && piece.getReservedBy() != null ){
+		
+			piece.setReservedBy( null );
+			
+			//System.out.println( "clearing res by for " + hint_piece );
+		}
+		
+		List<PEPeer> peers = pm.getPeers();
+		
+		for ( PEPeer peer: peers ){
+			
+			int[] res = peer.getReservedPieceNumbers();
+			
+			if ( res != null ){
+				
+				for ( int i: res ){
+					
+					if ( i == hint_piece ){
+						
+						peer.removeReservedPieceNumber( hint_piece );
+						
+						//System.out.println( "removing res by on " + peer.getIp() + " for " + hint_piece );
+					}
+				}
+			}
+		}
+	}
+	private class
+	DiskManagerRandomReadRequestImpl
+		implements DiskManagerRandomReadRequest
+	{
+		private DiskManagerFileInfoImpl		file;
+		private long						file_offset;
+		private long						length;
+		private boolean						reverse_order;
+		private DiskManagerListener			listener;
+		
+		private volatile boolean	cancelled;
+		private boolean				failed;
+		
+		private
+		DiskManagerRandomReadRequestImpl(
+			DiskManagerFileInfoImpl		_file,
+			long						_file_offset,
+			long						_length,
+			boolean						_reverse_order,
+			DiskManagerListener			_listener )
+		{
+			file			= _file;
+			file_offset		= _file_offset;
+			length			= _length;
+			reverse_order	= _reverse_order;
+			listener		= _listener;
+		}
+		
+		public DiskManagerFileInfoImpl
+		getFile()
+		{
+			return( file );
+		}
+		
+		public long
+		getOffset()
+		{
+			return( file_offset );
+		}
+		
+		public long
+		getLength()
+		{
+			return( length );
+		}
+		
+		public boolean
+		isReverse()
+		{
+			return( reverse_order );
+		}
+		
+		private boolean
+		isCancelled()
+		{
+			return( cancelled );
+		}
+		
+		public void
+		cancel()
+		{
+			synchronized( requests ){
+				
+				requests.remove( this );
+			
+				cancelled = true;
+			}
+							
+			failed( new Exception( "request cancelled" ));
+		}
+		
+		private void
+		dataAvailable(
+			DirectByteBuffer		buffer,
+			final long				offset,
+			final int				length )
+		{
+			final PooledByteBuffer p_buffer = new PooledByteBufferImpl( buffer );
+			
+			listener.eventOccurred(
+				new DiskManagerEvent()
+				{
+					public int
+					getType()
+					{
+						return( EVENT_TYPE_SUCCESS );
+					}
+					
+					public long
+					getOffset()
+					{
+						return( offset );
+					}
+					
+					public int
+					getLength()
+					{
+						return( length );
+					}
+					
+					public PooledByteBuffer
+					getBuffer()
+					{
+						return( p_buffer );
+					}
+					
+					public Throwable
+					getFailure()
+					{
+						return( null );
+					}
+				});
+		}
+		
+		private void
+		failed(
+			final Throwable e )
+		{
+			Debug.out(e );
+			
+			synchronized( requests ){
+				
+				if ( failed ){
+					
+					return;
+				}
+				
+				failed = true;
+			}
+			
+			listener.eventOccurred(
+				new DiskManagerEvent()
+				{
+					public int
+					getType()
+					{
+						return( EVENT_TYPE_FAILED );
+					}
+					
+					public long
+					getOffset()
+					{
+						return( -1 );
+					}
+					
+					public int
+					getLength()
+					{
+						return( -1 );
+					}
+					
+					public PooledByteBuffer
+					getBuffer()
+					{
+						return( null );
+					}
+					
+					public Throwable
+					getFailure()
+					{
+						return( e );
+					}
+				});
+		}
+	}
+}
diff --git a/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java b/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
index 411df6b..19c3033 100644
--- a/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/download/DownloadImpl.java
@@ -29,47 +29,44 @@ package org.gudy.azureus2.pluginsimpl.local.download;
 import java.io.File;
 import java.util.*;
 
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.core3.category.*;
-import org.gudy.azureus2.core3.global.*;
+import org.gudy.azureus2.core3.category.Category;
+import org.gudy.azureus2.core3.category.CategoryManager;
 import org.gudy.azureus2.core3.download.*;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerListener;
 import org.gudy.azureus2.core3.download.impl.DownloadManagerMoveHandler;
-import org.gudy.azureus2.core3.peer.*;
-import org.gudy.azureus2.core3.torrent.*;
-import org.gudy.azureus2.core3.tracker.client.*;
-
+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.logging.LogRelation;
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.core3.peer.PEPeerManager;
+import org.gudy.azureus2.core3.peer.PEPeerSource;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
+import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.core3.util.BEncoder;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.SystemTime;
+import org.gudy.azureus2.plugins.disk.DiskManager;
+import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.download.*;
+import org.gudy.azureus2.plugins.download.savelocation.SaveLocationChange;
+import org.gudy.azureus2.plugins.network.RateLimiter;
+import org.gudy.azureus2.plugins.peers.PeerManager;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
-
-import org.gudy.azureus2.plugins.peers.*;
 import org.gudy.azureus2.pluginsimpl.local.deprecate.PluginDeprecation;
 import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl;
-import org.gudy.azureus2.pluginsimpl.local.peers.*;
+import org.gudy.azureus2.pluginsimpl.local.peers.PeerManagerImpl;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
-import org.gudy.azureus2.plugins.disk.DiskManager;
-import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadActivationEvent;
-import org.gudy.azureus2.plugins.download.DownloadActivationListener;
-import org.gudy.azureus2.plugins.download.DownloadAttributeListener;
-import org.gudy.azureus2.plugins.download.DownloadCompletionListener;
-import org.gudy.azureus2.plugins.download.DownloadListener;
-import org.gudy.azureus2.plugins.download.DownloadPeerListener;
-import org.gudy.azureus2.plugins.download.DownloadPropertyListener;
-import org.gudy.azureus2.plugins.download.DownloadPropertyEvent;
-import org.gudy.azureus2.plugins.download.DownloadTrackerListener;
-import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
-import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
-import org.gudy.azureus2.plugins.download.DownloadStats;
-import org.gudy.azureus2.plugins.download.DownloadException;
-import org.gudy.azureus2.plugins.download.DownloadRemovalVetoException;
-import org.gudy.azureus2.plugins.download.DownloadWillBeRemovedListener;
-import org.gudy.azureus2.plugins.download.savelocation.SaveLocationChange;
-
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.logging.LogRelation;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.core.tracker.TrackerPeerSourceAdapter;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.util.CopyOnWriteMap;
 
@@ -111,6 +108,8 @@ DownloadImpl
 	
 	private HashMap property_to_attribute_map = null;
 	
+	private Map<String,int[]>	announce_response_map;
+	
 	protected
 	DownloadImpl(
 		DownloadManager		_dm )
@@ -811,6 +810,19 @@ DownloadImpl
  		return( download_stats.getCheckingDoneInThousandNotation() != -1 );
  	}
 
+ 	public boolean
+ 	isMoving()
+ 	{
+ 		org.gudy.azureus2.core3.disk.DiskManager dm = download_manager.getDiskManager();
+ 		
+ 		if ( dm != null ){
+ 			
+ 			return( dm.getMoveProgress() != -1 );
+ 		}
+ 		
+ 		return( false );
+ 	}
+ 	
 	protected void
 	isRemovable()
 		throws DownloadRemovalVetoException
@@ -1033,8 +1045,16 @@ DownloadImpl
 	getLastScrapeResult()
 	{		
 		TRTrackerScraperResponse response = download_manager.getTrackerScrapeResponse();
-	
-		last_scrape_result.setContent( response );
+
+		if ( response != null ){
+			
+				// don't notify plugins of intermediate (initializing, scraping) states as they would be picked up as errors
+			
+			if ( response.getStatus() == TRTrackerScraperResponse.ST_ERROR || response.getStatus() == TRTrackerScraperResponse.ST_ONLINE ){
+				
+				last_scrape_result.setContent( response );
+			}
+		}
 		
 		return( last_scrape_result );
 	}
@@ -1044,6 +1064,10 @@ DownloadImpl
 	scrapeResult(
 		TRTrackerScraperResponse	response )
 	{
+		// don't notify plugins of intermediate (initializing, scraping) states as they would be picked up as errors 
+		if(response.getStatus() != TRTrackerScraperResponse.ST_ERROR && response.getStatus() != TRTrackerScraperResponse.ST_ONLINE)
+			return;
+		
 		last_scrape_result.setContent( response );
 		
 		for (int i=0;i<tracker_listeners.size();i++){
@@ -1084,10 +1108,240 @@ DownloadImpl
 		}
 	}
 	
+	public TrackerPeerSource
+	getTrackerPeerSource()
+	{
+		return( 
+			new TrackerPeerSourceAdapter()
+			{
+				private long	fixup;
+				private int		state;
+				private String 	details = "";
+				private int		seeds;
+				private int		leechers;
+				private int		peers;
+				
+				private void
+				fixup()
+				{
+					long	now = SystemTime.getCurrentTime();
+					
+					if ( now - fixup > 1000 ){
+					
+						if ( !download_manager.getDownloadState().isPeerSourceEnabled( PEPeerSource.PS_PLUGIN )){
+							
+							state = ST_DISABLED;
+							
+						}else{
+						
+							int s = getState();
+							
+							if ( s == ST_DOWNLOADING || s == ST_SEEDING ){
+								
+								state = ST_ONLINE;
+								
+							}else{
+								
+								state = ST_STOPPED;
+							}
+						}
+						
+						if ( state == ST_ONLINE ){
+							
+							try{
+								peer_listeners_mon.enter();
+		
+								int	s	= 0;
+								int	l	= 0;
+								int p 	= 0;
+								
+								String	str = "";
+								
+								if ( announce_response_map != null ){
+								
+									for (Map.Entry<String, int[]> entry: announce_response_map.entrySet()){
+										
+										String 	cn 		= entry.getKey();
+										int[]	data 	= entry.getValue();
+										
+										str += (str.length()==0?"":", ") + cn;
+										
+										str += " " + data[0] + "/" + data[1] + "/" + data[2];
+										
+										s += data[0];
+										l += data[1];
+										p += data[2];
+									}
+								}
+								
+								details 	= str;
+								seeds		= s;
+								leechers	= l;
+								peers		= p;
+								
+							}finally{
+								
+								peer_listeners_mon.exit();
+							}
+						}else{
+							
+							details = "";
+						}
+						
+						fixup = now;
+					}
+				}
+				
+				public int
+				getType()
+				{
+					return( TP_PLUGIN );
+				}
+				
+				public int
+				getStatus()
+				{
+					fixup();
+					
+					return( state );
+				}
+				
+				public String
+				getName()
+				{
+					fixup();
+				
+					if ( state == ST_ONLINE ){
+						
+						return( details );
+					}
+					
+					return( "" );
+				}
+				
+				public int
+				getSeedCount()
+				{
+					fixup();
+					
+					if ( state == ST_ONLINE ){
+						
+						return( seeds );
+					}
+					
+					return( -1 );
+				}
+				
+				public int
+				getLeecherCount()
+				{
+					fixup();
+					
+					if ( state == ST_ONLINE ){
+						
+						return( leechers );
+					}
+					
+					return( -1 );
+				}
+				
+				public int
+				getPeers()
+				{
+					fixup();
+					
+					if ( state == ST_ONLINE ){
+						
+						return( peers );
+					}
+					
+					return( -1 );
+				}
+			});
+	}
+	
+	private String
+	getTrackingName(
+		Object		obj )
+	{
+		String	name = obj.getClass().getName();
+		
+		int	pos = name.lastIndexOf( '.' );
+		
+		name = name.substring( pos+1 );
+		
+		pos = name.indexOf( '$' );
+		
+		if ( pos != -1 ){
+			
+			name = name.substring( 0, pos );
+		}
+		
+			// hack alert - could use classloader to find plugin I guess
+		
+		if ( name.equals( "DHTTrackerPlugin" )){
+			
+			name = null;
+			
+		}else if ( name.equals( "DHTAnnounceResult")){
+			
+			name = "mlDHT";
+		}
+		
+		return( name );
+	}
+	
 	public void
 	setAnnounceResult(
 		DownloadAnnounceResult	result )
 	{
+		String class_name = getTrackingName( result );
+		
+		if ( class_name != null ){
+			
+			int	seeds 		= result.getSeedCount();
+			int	leechers 	= result.getNonSeedCount();
+			
+			DownloadAnnounceResultPeer[] peers = result.getPeers();
+			
+			int	peer_count = peers==null?0:peers.length;
+			
+			try{
+				peer_listeners_mon.enter();
+				
+				if ( announce_response_map == null ){
+					
+					announce_response_map = new HashMap<String, int[]>();
+					
+				}else{
+					
+					if ( announce_response_map.size() > 32 ){
+						
+						Debug.out( "eh?" );
+						
+						announce_response_map.clear();
+					}
+				}
+				
+				int[]	data = (int[])announce_response_map.get( class_name );
+				
+				if ( data == null ){
+					
+					data = new int[3];
+					
+					announce_response_map.put( class_name, data );
+				}
+				
+				data[0]	= seeds;
+				data[1]	= leechers;
+				data[2]	= peer_count;
+				
+			}finally{
+				
+				peer_listeners_mon.exit();
+			}
+		}
+		
 		download_manager.setAnnounceResult( result );
 	}
 	
@@ -1095,6 +1349,48 @@ DownloadImpl
 	setScrapeResult(
 		DownloadScrapeResult	result )
 	{
+		String class_name = getTrackingName( result );
+		
+		if ( class_name != null ){
+			
+			int	seeds 		= result.getSeedCount();
+			int	leechers 	= result.getNonSeedCount();
+					
+			try{
+				peer_listeners_mon.enter();
+				
+				if ( announce_response_map == null ){
+					
+					announce_response_map = new HashMap<String, int[]>();
+					
+				}else{
+					
+					if ( announce_response_map.size() > 32 ){
+						
+						Debug.out( "eh?" );
+						
+						announce_response_map.clear();
+					}
+				}
+				
+				int[]	data = (int[])announce_response_map.get( class_name );
+				
+				if ( data == null ){
+					
+					data = new int[3];
+					
+					announce_response_map.put( class_name, data );
+				}
+				
+				data[0]	= seeds;
+				data[1]	= leechers;
+				
+			}finally{
+				
+				peer_listeners_mon.exit();
+			}
+		}
+		
 		download_manager.setScrapeResult( result );
 	}
 	
@@ -1537,7 +1833,22 @@ DownloadImpl
 		return( null );
 	}
 	
+	public int getDiskManagerFileCount() {
+		return download_manager.getNumFileInfos();
+	}
 	
+	public DiskManagerFileInfo getDiskManagerFileInfo(int index) {
+		org.gudy.azureus2.core3.disk.DiskManagerFileInfo[] info = download_manager.getDiskManagerFileInfo();
+
+		if (info == null) {
+			return null;
+		}
+		if (index < 0 || index >= info.length) {
+			return null;
+		}
+
+		return new DiskManagerFileInfoImpl(this, info[index]);
+	}
 	
 	public DiskManagerFileInfo[]
 	getDiskManagerFileInfo()
@@ -1593,6 +1904,22 @@ DownloadImpl
   		download_manager.getStats().setDownloadRateLimitBytesPerSecond( max_rate_bps );
   	}
 
+	public void
+	addRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		download_manager.addRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+	}
+		
+	public void
+	removeRateLimiter( 
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		download_manager.removeRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+	}
+  	
   public int getSeedingRank() {
     return download_manager.getSeedingRank();
   }
diff --git a/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
index 1107617..98dbc90 100644
--- a/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/download/DownloadManagerImpl.java
@@ -42,9 +42,7 @@ 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.core3.util.*;
 import org.gudy.azureus2.plugins.download.*;
 import org.gudy.azureus2.plugins.download.savelocation.DefaultSaveLocationManager;
 import org.gudy.azureus2.plugins.download.savelocation.SaveLocationManager;
@@ -441,6 +439,41 @@ DownloadManagerImpl
 		return( getDownload( dm ));
 	}
 	
+	public Download
+	addNonPersistentDownloadStopped(
+		Torrent		torrent,
+		File		torrent_file,
+		File		data_location )
+	
+		throws DownloadException
+	{
+
+		byte[] hash = null;
+		try {
+			hash = torrent.getHash();
+		} catch (Exception e) { }
+
+		DownloadManager dm = global_manager.addDownloadManager(
+				torrent_file.toString(), hash, data_location.toString(),
+				DownloadManager.STATE_STOPPED, false);
+		
+		if ( dm == null ){
+			
+			throw( new DownloadException( "DownloadManager::addDownload - failed"));
+		}
+		
+		addDownloadManager( dm );
+		
+		return( getDownload( dm ));
+	}
+	
+	public void 
+	clearNonPersistentDownloadState(
+		byte[] hash)
+	{
+		global_manager.clearNonPersistentDownloadState( hash );
+	}
+	
 	protected int
 	getInitialState()
 	{
@@ -594,8 +627,16 @@ DownloadManagerImpl
 	getDownload(
 		byte[]	hash )
 	{
-		List	dls = global_manager.getDownloadManagers();
+		DownloadManager manager = global_manager.getDownloadManager(new HashWrapper(hash));
+		if (manager != null) {
+			try {
+				return getDownload(manager);
+			} catch (DownloadException e) {
+			}
+		}
 
+		List	dls = global_manager.getDownloadManagers();
+		
 		for (int i=0;i<dls.size();i++){
 			
 			DownloadManager	man = (DownloadManager)dls.get(i);
diff --git a/org/gudy/azureus2/pluginsimpl/local/download/DownloadStatsImpl.java b/org/gudy/azureus2/pluginsimpl/local/download/DownloadStatsImpl.java
index 10df2c6..25f52fe 100644
--- a/org/gudy/azureus2/pluginsimpl/local/download/DownloadStatsImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/download/DownloadStatsImpl.java
@@ -103,6 +103,14 @@ DownloadStatsImpl
  		return( -1 );
 	}
 
+	public void
+	resetUploadedDownloaded(
+		long 	new_up, 
+		long 	new_down )
+	{
+		dm_stats.resetTotalBytesSentReceived( new_up, new_down );
+	}
+	
 	public long
 	getDownloaded()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/installer/PluginInstallerImpl.java b/org/gudy/azureus2/pluginsimpl/local/installer/PluginInstallerImpl.java
index 6dbf50d..1b41720 100644
--- a/org/gudy/azureus2/pluginsimpl/local/installer/PluginInstallerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/installer/PluginInstallerImpl.java
@@ -52,6 +52,7 @@ import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderAdapter;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderException;
 import org.gudy.azureus2.pluginsimpl.local.FailedPlugin;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.update.UpdateCheckInstanceImpl;
 import org.gudy.azureus2.pluginsimpl.local.update.UpdateManagerImpl;
 import org.gudy.azureus2.pluginsimpl.update.sf.*;
@@ -441,7 +442,7 @@ PluginInstallerImpl
 		install( plugins, shared, false, null, null );
 	}
 	
-	public void
+	public UpdateCheckInstance
 	install(
 		InstallablePlugin[]					plugins,
 		boolean								shared,
@@ -450,10 +451,10 @@ PluginInstallerImpl
 	
 		throws PluginException
 	{
-		install( plugins, shared, false, properties, listener );
+		return( install( plugins, shared, false, properties, listener ));
 	}
 	
-	protected void
+	protected UpdateCheckInstance
 	install(
 		InstallablePlugin[]					plugins,
 		boolean								shared,
@@ -463,7 +464,19 @@ PluginInstallerImpl
 	
 		throws PluginException
 	{
-		PluginUpdatePlugin	pup = (PluginUpdatePlugin)manager.getPluginInterfaceByClass( PluginUpdatePlugin.class ).getPlugin();
+		PluginInterface	pup_pi = manager.getPluginInterfaceByClass( PluginUpdatePlugin.class );
+		
+		if ( pup_pi == null ){
+			
+			throw( new PluginException( "Installation aborted, plugin-update plugin unavailable" ));
+		}
+		
+		if ( !pup_pi.getPluginState().isOperational()){
+			
+			throw( new PluginException( "Installation aborted, plugin-update plugin not operational" ));
+		}
+		
+		PluginUpdatePlugin	pup = (PluginUpdatePlugin)pup_pi.getPlugin();
 		
 		UpdateManagerImpl	uman = (UpdateManagerImpl)manager.getDefaultPluginInterface().getUpdateManager();
 		
@@ -531,12 +544,19 @@ PluginInstallerImpl
 										protected void
 										check()
 										{
-											for (int i=0;i<updates.length;i++){
+											Update failed_update = null;
+											
+											for ( Update update: updates ){
 												
-												if ( !updates[i].isCancelled() && !updates[i].isComplete()){
+												if ( !update.isCancelled() && !update.isComplete()){
 													
 													return;
 												}
+												
+												if ( !update.wasSuccessful()){
+													
+													failed_update = update;
+												}
 											}
 											
 											if ( cancelled ){
@@ -545,7 +565,20 @@ PluginInstallerImpl
 												
 											}else{
 												
-												listener.completed();
+												if ( failed_update == null ){
+													
+														// flush plugin events through before reporting complete
+													
+													PluginInitializer.waitForPluginEvents();
+													
+													listener.completed();
+													
+												}else{
+												
+													listener.failed(
+														new PluginException(
+															"Install of " + failed_update.getName() + " failed" ));
+												}
 											}
 										}
 									});
@@ -665,6 +698,8 @@ PluginInstallerImpl
 		
 			inst.start();
 			
+			return( inst );
+			
 		}catch( Throwable e ){
 			
 			inst.cancel();
@@ -710,6 +745,16 @@ PluginInstallerImpl
 	
 		throws PluginException
 	{
+		uninstall( pis, null );
+	}
+	
+	public void
+	uninstall(
+		final PluginInterface[]				pis,
+		final PluginInstallationListener	listener_maybe_null )
+	
+		throws PluginException
+	{
 		for (int i=0;i<pis.length;i++){
 			
 			PluginInterface	pi = pis[i];
@@ -740,6 +785,10 @@ PluginInstallerImpl
 						UpdateCheckInstance.UCI_UNINSTALL,
 						"update.instance.uninstall");
 
+			final int[]	rds_added = { 0 };
+			
+			final AESemaphore rd_waiter_sem = new AESemaphore( "uninst:rd:wait" );
+			
 			for (int i=0;i<pis.length;i++){
 				
 				final PluginInterface	pi = pis[i];
@@ -768,52 +817,6 @@ PluginInstallerImpl
 							try{
 								ResourceDownloader rd = 
 									manager.getDefaultPluginInterface().getUtilities().getResourceDownloaderFactory().create( new File( plugin_dir ));
-								
-								rd.addListener(
-									new ResourceDownloaderAdapter()
-									{
-										public boolean
-										completed(
-											ResourceDownloader	downloader,
-											InputStream			data )
-										{
-											try{
-												if ( pi.getPluginState().isUnloadable()){
-											
-													pi.getPluginState().unload();
-													
-													FileUtil.recursiveDelete( new File( plugin_dir ));
-												
-												}
-																
-												UpdateInstaller installer = checker.createInstaller();
-													
-												installer.addRemoveAction( new File( plugin_dir ).getCanonicalPath());
-											
-												
-											}catch( Throwable e ){
-												
-												Debug.printStackTrace(e);
-												Logger.log(new LogAlert(LogAlert.REPEATABLE,
-														"Plugin uninstall failed", e));
-											}
-											
-												// don't close the stream as we process it later
-												
-											return( true );
-										}
-										
-										public void
-										failed(
-											ResourceDownloader			downloader,
-											ResourceDownloaderException e )
-										{
-											if ( !downloader.isCancelled()){
-												Logger.log(new LogAlert(LogAlert.REPEATABLE,
-														"Plugin uninstall failed", e));
-											}
-										}
-									});
 	
 									// the plugin may have > 1 plugin interfaces, make the name up appropriately
 								
@@ -842,13 +845,94 @@ PluginInstallerImpl
 									}
 								}
 								
-								checker.addUpdate(
+								final Update update = checker.addUpdate(
 									update_name,
 									new String[]{ "Uninstall: " + plugin_dir},
 									pi.getPluginVersion(),
 									rd,
 									pi.getPluginState().isUnloadable()?Update.RESTART_REQUIRED_NO:Update.RESTART_REQUIRED_YES );
+								
+								synchronized( rds_added ){
 									
+									rds_added[0]++;
+								}
+								
+								rd.addListener(
+										new ResourceDownloaderAdapter()
+										{
+											public boolean
+											completed(
+												ResourceDownloader	downloader,
+												InputStream			data )
+											{
+												try{
+													try{
+														if ( pi.getPluginState().isUnloadable()){
+													
+															pi.getPluginState().unload();
+															
+															if ( !FileUtil.recursiveDelete( new File( plugin_dir ))){
+																
+																update.setRestartRequired( Update.RESTART_REQUIRED_YES );
+																
+																checker.reportProgress( "Failed to remove plugin, restart will be required" );
+															}
+														}
+																		
+														UpdateInstaller installer = checker.createInstaller();
+															
+														installer.addRemoveAction( new File( plugin_dir ).getCanonicalPath());
+													
+														update.complete( true );
+														
+														try{
+															PluginInitializer.fireEvent(
+																PluginEvent.PEV_PLUGIN_UNINSTALLED,
+																pi.getPluginID());
+															
+														}catch( Throwable e ){
+															
+															Debug.out( e );
+														}
+													}catch( Throwable e ){
+														
+														update.complete( false );
+														
+														Debug.printStackTrace(e);
+														
+														Logger.log(new LogAlert(LogAlert.REPEATABLE,
+																"Plugin uninstall failed", e));
+													}
+																									
+														// don't close the stream as we process it later
+														
+													return( true );
+													
+												}finally{
+													
+													rd_waiter_sem.release();
+												}
+											}
+											
+											public void
+											failed(
+												ResourceDownloader			downloader,
+												ResourceDownloaderException e )
+											{
+												try{
+													update.complete( false );
+													
+													if ( !downloader.isCancelled()){
+														
+														Logger.log(new LogAlert(LogAlert.REPEATABLE,
+																"Plugin uninstall failed", e));
+													}
+												}finally{
+													
+													rd_waiter_sem.release();
+												}
+											}
+										});
 							}finally{
 								
 								checker.completed();
@@ -858,10 +942,67 @@ PluginInstallerImpl
 					}, false );
 			}
 
+			if ( listener_maybe_null != null ){
+				
+				inst.addListener( 
+					new UpdateCheckInstanceListener()
+					{
+						public void
+						cancelled(
+							UpdateCheckInstance		instance )
+						{
+							listener_maybe_null.cancelled();
+						}
+						
+						public void
+						complete(
+							UpdateCheckInstance		instance )
+						{
+							int	wait_count;
+							
+							synchronized( rds_added ){
+							
+								wait_count = rds_added[0];
+							}
+							
+							for ( int i=0;i<wait_count;i++ ){
+								
+								rd_waiter_sem.reserve();
+							}
+							
+							listener_maybe_null.completed();
+						}
+					});
+			}
+			
 			inst.start();
+
+			/*
+			UpdateChecker[] checkers = inst.getCheckers();
+			
+			for ( UpdateChecker checker: checkers ){
+			
+				checker.
+			}*/
 			
 		}catch( Throwable e ){
 			
+			PluginException pe;
+			
+			if ( e instanceof PluginException ){
+				
+				pe = (PluginException)e;
+				
+			}else{
+				
+				pe = new PluginException( "Uninstall failed", e );
+			}
+			
+			if ( listener_maybe_null != null ){
+			
+				listener_maybe_null.failed( pe );
+			}
+			
 			Debug.printStackTrace(e);
 		}
 	}
diff --git a/org/gudy/azureus2/pluginsimpl/local/installer/Test.java b/org/gudy/azureus2/pluginsimpl/local/installer/Test.java
deleted file mode 100644
index 16cbf31..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/installer/Test.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Created on 28-Nov-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 org.gudy.azureus2.pluginsimpl.local.installer;
-
-import java.util.Properties;
-
-import org.gudy.azureus2.core3.util.AEThread;
-import org.gudy.azureus2.plugins.*;
-//import org.gudy.azureus2.plugins.installer.PluginInstaller;
-
-/**
- * @author parg
- *
- */
-public class 
-Test 
-	implements Plugin, PluginListener
-{
-	protected PluginManager		manager;
-	
-	public
-	Test()
-	{
-		// constructor for Plugin
-	}
-	
-	public 
-	Test(
-		boolean	ignore )
-	{
-		Properties props = new Properties();
-		
-		props.put( PluginManager.PR_MULTI_INSTANCE, "true" );
-		
-		PluginManager.registerPlugin( Test.class );
-	
-		PluginManager.startAzureus( PluginManager.UI_SWT, props );
-	}
-	
-	public void 
-	initialize(
-		PluginInterface pi )
-	  
-		throws PluginException
-	{
-		manager	= pi.getPluginManager();
-		
-		pi.addListener( this );
-	}
-	
-	public void
-	initializationComplete()
-	{
-		new AEThread("install tester" )
-		{
-			public void
-			runSupport()
-			{	
-				try{
-					sleep(10000);
-					
-					/*
-					PluginInstaller	installer = manager.getPluginInstaller();
-					
-					StandardPlugin[]	sps = installer.getStandardPlugins();
-					
-					String	install_name = "azshareexporter";
-					
-					StandardPlugin	install_act = null;
-					
-					for (int i=0;i<sps.length;i++){
-						
-						StandardPlugin	sp = sps[i];
-						
-						System.out.println( "Standard Plugin: " + sp.getId() + " - " + sp.getVersion() + ", installed = " + sp.getAlreadyInstalledPlugin());
-						
-						if ( sp.getId().equals( install_name )){
-							
-							install_act = sp;
-						}
-					}
-					
-					install_act.install( true );
-					*/
-					
-					/*
-					FilePluginInstaller inst = installer.installFromFile(new File("C:\\temp\\azshareexporter_0.1.jar"));
-					
-					inst.install( false );
-					*/
-					
-					PluginInterface pi = manager.getPluginInterfaceByID("azshareexporter");
-					
-					pi.getPluginState().uninstall();
-					
-				}catch( Throwable e ){
-					
-					e.printStackTrace();
-				}
-			}
-		}.start();
-	}
-	
-	public void
-	closedownInitiated()
-	{
-		
-	}
-	
-	public void
-	closedownComplete()
-	{
-		
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		new Test(true);
-	}
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/launch/PluginLauncherImpl.java b/org/gudy/azureus2/pluginsimpl/local/launch/PluginLauncherImpl.java
index c0a4e0c..d4abe80 100644
--- a/org/gudy/azureus2/pluginsimpl/local/launch/PluginLauncherImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/launch/PluginLauncherImpl.java
@@ -491,50 +491,62 @@ PluginLauncherImpl
   		return( res_array );
   	}
   	
-    public static ClassLoader 
-    addFileToClassPath(
+  	public static ClassLoader 
+  	addFileToClassPath(
+  			ClassLoader		root,
+  			ClassLoader		classLoader,
+  			File 			f) 
+  	{
+  		if ( 	f.exists() &&
+  				(!f.isDirectory())&&
+  				f.getName().endsWith(".jar")){
+
+  			try {
+
+  				classLoader = extendClassLoader( root, classLoader, f.toURL());
+
+  			}catch( Exception e){
+
+  				// don't use Debug/lglogger here as we can be called before AZ has been initialised
+
+  				e.printStackTrace();
+  			}
+  		}
+
+  		return( classLoader );
+  	}
+    
+    public static ClassLoader
+    extendClassLoader(
     	ClassLoader		root,
     	ClassLoader		classLoader,
-    	File 			f) 
+    	URL				url )
     {
-      if ( 	f.exists() &&
-      		(!f.isDirectory())&&
-      		f.getName().endsWith(".jar")){
-      
-      	try {
-      			
-      			// URL classloader doesn't seem to delegate to parent classloader properly
-      			// so if you get a chain of them then it fails to find things. Here we
-      			// make sure that all of our added URLs end up within a single URLClassloader
-      			// with its parent being the one that loaded this class itself
-      		
-      		if ( classLoader instanceof URLClassLoader ){
-      			
-      			URL[]	old = ((URLClassLoader)classLoader).getURLs();
-    
-      			URL[]	new_urls = new URL[old.length+1];
-      			
-      			System.arraycopy( old, 0, new_urls, 1, old.length );
-      			
-      			new_urls[0]= f.toURL();
-      			
-      			classLoader = new URLClassLoader(
-      								new_urls,
-  									classLoader==root?
-  											classLoader:
-  											classLoader.getParent());
-      		}else{
-      			  		
-      			classLoader = new URLClassLoader(new URL[]{f.toURL()},classLoader);
-      		}
-      	}catch( Exception e){
-      		
-      			// don't use Debug/lglogger here as we can be called before AZ has been initialised
-      		
-      		e.printStackTrace();
-      	}
-     	}
-      
-      return( classLoader );
+			// URL classloader doesn't seem to delegate to parent classloader properly
+			// so if you get a chain of them then it fails to find things. Here we
+			// make sure that all of our added URLs end up within a single URLClassloader
+			// with its parent being the one that loaded this class itself
+		
+		if ( classLoader instanceof URLClassLoader ){
+			
+			URL[]	old = ((URLClassLoader)classLoader).getURLs();
+
+			URL[]	new_urls = new URL[old.length+1];
+			
+			System.arraycopy( old, 0, new_urls, 1, old.length );
+			
+			new_urls[0]= url;
+			
+			classLoader = new URLClassLoader(
+								new_urls,
+								classLoader==root?
+										classLoader:
+										classLoader.getParent());
+		}else{
+			  		
+			classLoader = new URLClassLoader(new URL[]{ url },classLoader);
+		}
+		
+		return( classLoader );
     }
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/logging/LoggerChannelImpl.java b/org/gudy/azureus2/pluginsimpl/local/logging/LoggerChannelImpl.java
index 569eee7..fbe4673 100644
--- a/org/gudy/azureus2/pluginsimpl/local/logging/LoggerChannelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/logging/LoggerChannelImpl.java
@@ -44,11 +44,11 @@ LoggerChannelImpl
 	implements LoggerChannel
 {
 	private static final LogIDs LOGID = org.gudy.azureus2.core3.logging.LogIDs.PLUGIN;
-	private Logger		logger;
-	private String		name;
-	private boolean		timestamp;
-	private boolean		no_output;
-	private List		listeners = new ArrayList();
+	final private Logger		logger;
+	final private String		name;
+	final private boolean		timestamp;
+	final boolean		no_output;
+	final List		listeners = new ArrayList();
 	
 	private AEDiagnosticsLogger	diagnostic_logger;
 	
@@ -89,10 +89,23 @@ LoggerChannelImpl
 		setDiagnostic( 0, true );
 	}
 	
+	public void 
+	setForce(
+		boolean forceToFile) 
+	{
+		diagnostic_logger.setForced( forceToFile );
+	}
+	
+	public boolean
+	getForce()
+	{
+		return( diagnostic_logger.isForced());
+	}
+	
 	public void
 	setDiagnostic(
 		long	max_file_size,
-		boolean	timestamp )
+		boolean	diag_timestamp )
 	{
 		if ( diagnostic_logger == null ){
 			
@@ -102,8 +115,8 @@ LoggerChannelImpl
 				
 				diagnostic_logger.setMaxFileSize((int)max_file_size );
 			}
-			
-			diagnostic_logger.enableTimeStamp( timestamp );
+						
+			diagnostic_logger.enableTimeStamp( !timestamp && diag_timestamp );
 			
 			addListener(
 				new LoggerChannelListener()
@@ -182,7 +195,7 @@ LoggerChannelImpl
 	
 	public void log(Object[] relatedTo, int log_type, String data) {
 
-		String listenerData = data;
+		String listenerData;
 		if (relatedTo != null) {
 			StringBuffer text = new StringBuffer();
 			for (int i = 0; i < relatedTo.length; i++) {
@@ -203,7 +216,9 @@ LoggerChannelImpl
 				}
 			}
 			
-			listenerData += "\t" +  text.toString() + "] " + data;
+			listenerData = text.toString() + "] " + data;
+		}else{
+			listenerData = data;
 		}
 		
 		notifyListeners(log_type, addTimeStamp(listenerData));
diff --git a/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageConnectionDirect.java b/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageConnectionDirect.java
index a86a2fe..04cac90 100644
--- a/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageConnectionDirect.java
+++ b/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageConnectionDirect.java
@@ -26,6 +26,7 @@ import java.nio.ByteBuffer;
 import java.util.*;
 
 
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DirectByteBuffer;
 import org.gudy.azureus2.plugins.messaging.MessageException;
 import org.gudy.azureus2.plugins.messaging.MessageManager;
@@ -34,6 +35,7 @@ import org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpoint;
 import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
 import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
 import com.aelitis.azureus.core.networkmanager.IncomingMessageQueue;
@@ -77,8 +79,8 @@ GenericMessageConnectionDirect
 	private boolean				processing;
 	private volatile boolean	closed;
 	
-	private List				inbound_rls;
-	private List				outbound_rls;
+	private List<LimitedRateGroup>				inbound_rls;
+	private List<LimitedRateGroup>				outbound_rls;
 	
 		
 	protected 
@@ -160,8 +162,10 @@ GenericMessageConnectionDirect
 
 	public void
 	addInboundRateLimiter(
-		RateLimiter		limiter )
+		RateLimiter		_limiter )
 	{
+		LimitedRateGroup limiter = UtilitiesImpl.wrapLimiter( _limiter );
+
 		synchronized( this ){
 			
 			if ( processing ){
@@ -172,7 +176,7 @@ GenericMessageConnectionDirect
 				
 				if ( inbound_rls == null ){
 					
-					inbound_rls = new ArrayList();
+					inbound_rls = new ArrayList<LimitedRateGroup>();
 				}
 				
 				inbound_rls.add( limiter );
@@ -182,8 +186,10 @@ GenericMessageConnectionDirect
 	
 	public void
 	removeInboundRateLimiter(
-		RateLimiter		limiter )
+		RateLimiter		_limiter )
 	{
+		LimitedRateGroup limiter = UtilitiesImpl.wrapLimiter( _limiter );
+
 		synchronized( this ){
 			
 			if ( processing ){
@@ -202,8 +208,10 @@ GenericMessageConnectionDirect
 	
 	public void
 	addOutboundRateLimiter(
-		RateLimiter		limiter )
+		RateLimiter		_limiter )
 	{
+		LimitedRateGroup limiter = UtilitiesImpl.wrapLimiter( _limiter );
+
 		synchronized( this ){
 			
 			if ( processing ){
@@ -214,7 +222,7 @@ GenericMessageConnectionDirect
 				
 				if ( outbound_rls == null ){
 					
-					outbound_rls = new ArrayList();
+					outbound_rls = new ArrayList<LimitedRateGroup>();
 				}
 				
 				outbound_rls.add( limiter );
@@ -224,8 +232,10 @@ GenericMessageConnectionDirect
 	
 	public void
 	removeOutboundRateLimiter(
-		RateLimiter		limiter )
+		RateLimiter		_limiter )
 	{
+		LimitedRateGroup limiter = UtilitiesImpl.wrapLimiter( _limiter );
+		
 		synchronized( this ){
 			
 			if ( processing ){
@@ -257,11 +267,13 @@ GenericMessageConnectionDirect
 				ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM,
 				new NetworkConnection.ConnectionListener()
 				{
-					public void 
-					connectStarted()
-					{
+					public int 
+					connectStarted(
+						int default_connect_timeout )
+					{	
+						return( default_connect_timeout );
 					}
-	
+					
 					public void 
 					connectSuccess(
 						ByteBuffer remaining_initial_data )
@@ -275,7 +287,7 @@ GenericMessageConnectionDirect
 					{
 						owner.reportFailed( failure_msg );
 						
-						connection.close();
+						connection.close( failure_msg==null?null:Debug.getNestedExceptionMessage(failure_msg));
 					}
 					    
 					public void 
@@ -284,7 +296,7 @@ GenericMessageConnectionDirect
 					{
 						owner.reportFailed( error );
 						
-						connection.close();
+						connection.close( error==null?null:Debug.getNestedExceptionMessage(error));
 					}
 					
 					public String 
@@ -366,11 +378,13 @@ GenericMessageConnectionDirect
 				ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM,
 				new NetworkConnection.ConnectionListener()
 				{
-					public void 
-					connectStarted()
-					{
+					public int 
+					connectStarted(
+						int default_connect_timeout )
+					{	
+						return( default_connect_timeout );
 					}
-	
+					
 					public void 
 					connectSuccess(
 						ByteBuffer remaining_initial_data )
@@ -403,7 +417,7 @@ GenericMessageConnectionDirect
 					{
 						listener.connectFailure( failure_msg );
 						
-						connection.close();
+						connection.close(failure_msg==null?null:Debug.getNestedExceptionMessage(failure_msg));
 					}
 					    
 					public void 
@@ -412,7 +426,7 @@ GenericMessageConnectionDirect
 					{
 						listener.connectFailure( error );
 						
-						connection.close();
+						connection.close(error==null?null:Debug.getNestedExceptionMessage(error));
 					}
 					
 					public String 
@@ -451,6 +465,12 @@ GenericMessageConnectionDirect
 	    				int byte_count )
 	    			{	
 	    			}
+	    			
+	    			public boolean 
+	    			isPriority() 
+	    			{
+	    				return false;
+	    			}
 	    		});
 	    
 	    connection.getOutgoingMessageQueue().registerQueueListener( 
@@ -525,7 +545,7 @@ GenericMessageConnectionDirect
 	    			connection.addRateLimiter((LimitedRateGroup)outbound_rls.get(i),true);
 	    		}
 	    		
-	    		inbound_rls = null;
+	    		outbound_rls = null;
 	    	}
 	    	
 	    	processing	= true;
@@ -569,7 +589,7 @@ GenericMessageConnectionDirect
 	
 			closed	= true;
 			
-			connection.close();
+			connection.close( null );
 		}
 	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageEndpointImpl.java b/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageEndpointImpl.java
index 16976d3..a824971 100644
--- a/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageEndpointImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/messaging/GenericMessageEndpointImpl.java
@@ -28,6 +28,7 @@ import org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpoint;
 
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
 import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.impl.tcp.ProtocolEndpointTCP;
 import com.aelitis.azureus.core.networkmanager.impl.udp.ProtocolEndpointUDP;
 
@@ -67,7 +68,7 @@ GenericMessageEndpointImpl
 	addTCP(
 		InetSocketAddress	target )
 	{
-		ce.addProtocol( new ProtocolEndpointTCP( target ));
+		ce.addProtocol( ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, target ));
 	}
 	
 	public InetSocketAddress
@@ -90,7 +91,7 @@ GenericMessageEndpointImpl
 	addUDP(
 		InetSocketAddress	target )
 	{
-		ce.addProtocol( new ProtocolEndpointUDP( target ));
+		ce.addProtocol( ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_UDP, target ));
 	}
 	
 	public InetSocketAddress
diff --git a/org/gudy/azureus2/pluginsimpl/local/messaging/MessageManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/messaging/MessageManagerImpl.java
index a07b2a7..bc77857 100644
--- a/org/gudy/azureus2/pluginsimpl/local/messaging/MessageManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/messaging/MessageManagerImpl.java
@@ -292,14 +292,14 @@ public class MessageManagerImpl implements MessageManager, NATTraversalHandler {
 
 							}else{
 								
-								connection.close();
+								connection.close( "connection not accepted" );
 							}	
 							
 						}catch( Throwable e ){
 							
 							Debug.printStackTrace(e);
 							
-							connection.close();
+							connection.close( e==null?null:Debug.getNestedExceptionMessage(e));
 						}
 					}
 					
diff --git a/org/gudy/azureus2/pluginsimpl/local/network/ConnectionImpl.java b/org/gudy/azureus2/pluginsimpl/local/network/ConnectionImpl.java
index 1f4ca2c..ca021d0 100644
--- a/org/gudy/azureus2/pluginsimpl/local/network/ConnectionImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/network/ConnectionImpl.java
@@ -53,7 +53,7 @@ public class ConnectionImpl implements Connection {
   
   public void connect( final ConnectionListener listener ) {
     core_connection.connect( ProtocolEndpoint.CONNECT_PRIORITY_MEDIUM, new com.aelitis.azureus.core.networkmanager.NetworkConnection.ConnectionListener() {
-      public void connectStarted() { listener.connectStarted();  }
+      public int connectStarted( int ct ) { listener.connectStarted(); return( ct ); }
       
       public void connectSuccess( ByteBuffer remaining_initial_data) { listener.connectSuccess();  }
       
@@ -70,7 +70,7 @@ public class ConnectionImpl implements Connection {
   
   
   public void close() {
-    core_connection.close();
+    core_connection.close( null );
   }
 
   
diff --git a/org/gudy/azureus2/pluginsimpl/local/network/ConnectionManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/network/ConnectionManagerImpl.java
index b415e3f..339bf5f 100644
--- a/org/gudy/azureus2/pluginsimpl/local/network/ConnectionManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/network/ConnectionManagerImpl.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.plugins.messaging.MessageStreamDecoder;
 import org.gudy.azureus2.plugins.messaging.MessageStreamEncoder;
 import org.gudy.azureus2.plugins.network.Connection;
 import org.gudy.azureus2.plugins.network.ConnectionManager;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.network.Transport;
 import org.gudy.azureus2.plugins.network.TransportCipher;
 import org.gudy.azureus2.plugins.network.TransportException;
@@ -41,6 +42,8 @@ import org.gudy.azureus2.pluginsimpl.local.messaging.MessageStreamEncoderAdapter
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.networkmanager.ConnectionEndpoint;
 import com.aelitis.azureus.core.networkmanager.NetworkManager;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpoint;
+import com.aelitis.azureus.core.networkmanager.ProtocolEndpointFactory;
 import com.aelitis.azureus.core.networkmanager.impl.TransportHelper;
 import com.aelitis.azureus.core.networkmanager.impl.TransportHelperFilter;
 import com.aelitis.azureus.core.networkmanager.impl.udp.UDPNetworkManager;
@@ -88,7 +91,7 @@ public class ConnectionManagerImpl implements ConnectionManager {
   {
 	  ConnectionEndpoint connection_endpoint	= new ConnectionEndpoint( remote_address );
 	  
-	  connection_endpoint.addProtocol( new ProtocolEndpointTCP( remote_address ));
+	  connection_endpoint.addProtocol( ProtocolEndpointFactory.createEndpoint( ProtocolEndpoint.PROTOCOL_TCP, remote_address ));
 	 
 	  com.aelitis.azureus.core.networkmanager.NetworkConnection core_conn =
 		  NetworkManager.getSingleton().createConnection( connection_endpoint, new MessageStreamEncoderAdapter( encoder ), new MessageStreamDecoderAdapter( decoder ), false, false, null );
@@ -157,4 +160,49 @@ public class ConnectionManagerImpl implements ConnectionManager {
 	  return new TransportFilterImpl(core_filter);
   }
   
+  public RateLimiter 
+  createRateLimiter(
+	String 	name, 
+	int 	bps ) 
+  {
+	  return( new PluginRateLimiter( name, bps ));
+	
+  }
+  
+  public class
+  PluginRateLimiter
+	implements RateLimiter
+  {
+		
+		private String		name;
+		private int			rate;
+			
+		private
+		PluginRateLimiter(
+			String		_name,
+			int			_bps )
+		{
+			name	= _name;
+			rate	= _bps;
+		}
+		
+		public String
+		getName()
+		{
+			return( name );
+		}
+		
+		public int 
+		getRateLimitBytesPerSecond()
+		{
+			return( rate );
+		}
+		
+		public void
+		setRateLimitBytesPerSecond(
+			int		bytes_per_second )
+		{
+			rate = bytes_per_second;
+		}
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/network/IncomingMessageQueueImpl.java b/org/gudy/azureus2/pluginsimpl/local/network/IncomingMessageQueueImpl.java
index 2ec4bca..bb70e48 100644
--- a/org/gudy/azureus2/pluginsimpl/local/network/IncomingMessageQueueImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/network/IncomingMessageQueueImpl.java
@@ -25,9 +25,12 @@ package org.gudy.azureus2.pluginsimpl.local.network;
 import java.util.HashMap;
 
 import org.gudy.azureus2.plugins.messaging.*;
+import org.gudy.azureus2.plugins.messaging.bittorrent.BTMessageManager;
 import org.gudy.azureus2.plugins.network.*;
 import org.gudy.azureus2.pluginsimpl.local.messaging.MessageAdapter;
 
+import com.aelitis.azureus.core.peermanager.messaging.bittorrent.BTMessage;
+
 
 
 /**
@@ -42,7 +45,15 @@ public class IncomingMessageQueueImpl implements IncomingMessageQueue {
     this.core_queue = core_queue;
   } 
 
-  public void registerListener( final IncomingMessageQueueListener listener ) {
+  public void registerListener( IncomingMessageQueueListener listener ) {
+	  registerListenerSupport( listener, false );
+  }
+  
+  public void registerPriorityListener( IncomingMessageQueueListener listener ) {
+	  registerListenerSupport( listener, true );
+  }
+  
+  private void registerListenerSupport( final IncomingMessageQueueListener listener, final boolean is_priority ) {
     com.aelitis.azureus.core.networkmanager.IncomingMessageQueue.MessageQueueListener core_listener = 
       new com.aelitis.azureus.core.networkmanager.IncomingMessageQueue.MessageQueueListener() {
         public boolean messageReceived( com.aelitis.azureus.core.peermanager.messaging.Message message ) {
@@ -53,12 +64,26 @@ public class IncomingMessageQueueImpl implements IncomingMessageQueue {
           }
           
           //message originally decoded by core
-          return listener.messageReceived( new MessageAdapter( message ) );
+          
+          if ( message instanceof BTMessage ){
+        	  
+              return listener.messageReceived( BTMessageManager.wrapCoreMessage((BTMessage)message ));
+              
+          }else{
+          
+        	  return listener.messageReceived( new MessageAdapter( message ));
+          }
         }
       
         public void protocolBytesReceived( int byte_count ) {  listener.bytesReceived( byte_count );  }
 
         public void dataBytesReceived( int byte_count ) {  listener.bytesReceived( byte_count );  }
+        
+        public boolean 
+        isPriority() 
+        {
+        	return( is_priority );
+        }
     };
     
     registrations.put( listener, core_listener );  //save this mapping for later
diff --git a/org/gudy/azureus2/pluginsimpl/local/network/OutgoingMessageQueueImpl.java b/org/gudy/azureus2/pluginsimpl/local/network/OutgoingMessageQueueImpl.java
index 0108bea..9f5002a 100644
--- a/org/gudy/azureus2/pluginsimpl/local/network/OutgoingMessageQueueImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/network/OutgoingMessageQueueImpl.java
@@ -131,4 +131,22 @@ public class OutgoingMessageQueueImpl implements OutgoingMessageQueue {
   public int getPercentDoneOfCurrentMessage() {
     return core_queue.getPercentDoneOfCurrentMessage();
   }
+  
+  public int
+  getDataQueuedBytes()
+  {
+	  return(core_queue.getDataQueuedBytes());
+  }
+  
+  public int
+  getProtocolQueuedBytes()
+  {
+	  return(core_queue.getProtocolQueuedBytes());
+  }
+  
+  public boolean
+  isBlocked()
+  {
+	  return(core_queue.isBlocked());
+  }
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
index 5030258..930482f 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignDelegate.java
@@ -40,9 +40,13 @@ 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.network.ConnectionStub;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.peers.*;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.pluginsimpl.local.messaging.MessageAdapter;
+import org.gudy.azureus2.pluginsimpl.local.network.ConnectionImpl;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.networkmanager.NetworkConnectionBase;
@@ -68,7 +72,7 @@ PeerForeignDelegate
 	private long	create_time		= SystemTime.getCurrentTime();
 	private long	last_data_received_time =-1;
 	private long	last_data_message_received_time =-1;
-	private int		reserved_piece	= -1;
+	private int[]	reserved_pieces	= null;
 	private int		consecutive_no_requests;
 	
 	private BitFlags	bit_flags;
@@ -95,6 +99,26 @@ PeerForeignDelegate
 				
 		network_connection.addRateLimiter( pm.getUploadLimitedRateGroup(), true );
 		network_connection.addRateLimiter( pm.getDownloadLimitedRateGroup(), false );
+		
+		_foreign.bindConnection(
+			new ConnectionStub()
+			{
+				  public void
+				  addRateLimiter(
+					  RateLimiter		limiter,
+					  boolean			is_upload )
+				  {
+					  network_connection.addRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+				  }
+
+				  public void
+				  removeRateLimiter(
+					  RateLimiter		limiter,
+					  boolean			is_upload )
+				  {
+					  network_connection.removeRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+				  }
+			});
 	}
 	
 	public void
@@ -301,6 +325,12 @@ PeerForeignDelegate
   	{
   	}
   
+    public void
+    setSuspendedLazyBitFieldEnabled(
+  		boolean	enable )
+    {
+    }
+    
   	public long 
   	getTimeSinceConnectionEstablished() 
   	{
@@ -346,6 +376,11 @@ PeerForeignDelegate
   		return 0;
   	}
 
+  	public long
+  	getUnchokedForMillis()
+  	{
+  		return( 0 );
+  	}
   	 public int 
   	 getConsecutiveNoRequestCount()
   	 {
@@ -461,6 +496,11 @@ PeerForeignDelegate
 		return( foreign.isChoking());
 	}
 
+	public boolean 
+	isUnchokeOverride() 
+	{
+		return( false );
+	}
 
 	public boolean 
 	isInteresting()
@@ -527,11 +567,29 @@ PeerForeignDelegate
 	}
 	
 	public void 
+	sendRejectRequest(
+		DiskManagerReadRequest request) 
+	{
+	}
+	
+	public void 
 	sendBadPiece(
 		int piece_number) 
 	{
 	}
 	
+	public void
+	sendStatsRequest(
+		Map		request )
+	{
+	}
+	
+	public void
+	sendStatsReply(
+		Map		reply )
+	{
+	}		
+
 	public boolean
 	isTCP()
 	{
@@ -724,6 +782,19 @@ PeerForeignDelegate
 		return( "" );
 	}
 	
+	public String
+	getProtocol()
+	{
+		String res = (String)foreign.getUserData( Peer.PR_PROTOCOL );
+		
+		if ( res != null ){
+			
+			return( res );
+		}
+		
+		return( "Plugin" );
+	}
+	
 	public Message[] 
 	getSupportedMessages() 
 	{
@@ -805,18 +876,77 @@ PeerForeignDelegate
   
   
   
-	public int 
-	getReservedPieceNumber() 
+	public int[]
+	getReservedPieceNumbers() 
 	{
-		return( reserved_piece );
+		return( reserved_pieces );
 	}
  
   	public void 
-  	setReservedPieceNumber(int pieceNumber) 
+  	addReservedPieceNumber(int piece_number) 
   	{
-  		reserved_piece	= pieceNumber;
+  		int[]	existing = reserved_pieces;
+  		
+  		if ( existing == null ){
+  			
+  			reserved_pieces = new int[]{ piece_number };
+  			
+  		}else{
+  			
+  			int[] updated = new int[existing.length+1];
+  			
+  			System.arraycopy( existing, 0, updated, 0, existing.length );
+  					
+  			updated[existing.length] = piece_number;
+  			
+  			reserved_pieces = updated;
+  		}
   	}
 
+  	public void 
+  	removeReservedPieceNumber(int piece_number) 
+  	{
+  		int[]	existing = reserved_pieces;
+  		
+  		if ( existing != null ){
+  			
+  			if ( existing.length == 1 ){
+  				
+  				if ( existing[0] == piece_number ){
+  				
+  					reserved_pieces = null;
+  				}
+  			}else{
+  				
+  				int[] updated = new int[existing.length-1];
+  				
+  				int		pos 	= 0;
+  				boolean	found 	= false;
+  				
+  				for (int i=0;i<existing.length;i++){
+  				
+  					int	pn = existing[i];
+  					
+  					if ( found || pn != piece_number ){
+  						
+  						if ( pos == updated.length ){
+  							
+  							return;
+  						}
+  						
+  						updated[pos++] = pn;
+  						
+  					}else{
+  						
+  						found = true;
+  					}
+  				}
+  				
+  				reserved_pieces = updated;
+  			}
+  		}
+  	}
+  	
 	public int[] 
 	getIncomingRequestedPieceNumbers() 
 	{
@@ -897,6 +1027,13 @@ PeerForeignDelegate
 		network_connection.addRateLimiter( limiter, upload );
 	}
 	
+	public LimitedRateGroup[] 
+	getRateLimiters(
+		boolean	upload )
+	{
+		return( network_connection.getRateLimiters( upload ));
+	}
+	
 	public void
 	removeRateLimiter(
 		LimitedRateGroup	limiter,
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignNetworkConnection.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignNetworkConnection.java
index e4b3ee1..987d2aa 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignNetworkConnection.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerForeignNetworkConnection.java
@@ -283,6 +283,36 @@ PeerForeignNetworkConnection
 			return( 0 );
 		}
 		  
+		public int
+		getDataQueuedBytes()
+		{
+			return( 0 );
+		}
+		  
+		public int
+		getProtocolQueuedBytes()
+		{
+			return( 0 );
+		}
+		
+		public boolean 
+		getPriorityBoost()
+		{
+			return( false );
+		}
+			
+		public void 
+		setPriorityBoost( 
+			boolean	boost )
+		{
+		}
+
+		public boolean
+		isBlocked()
+		{
+			return( false );
+		}
+		
 		public boolean 
 		hasUrgentMessage()
 		{
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerImpl.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerImpl.java
index 24b580e..3cf25dc 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerImpl.java
@@ -34,8 +34,11 @@ import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.messaging.Message;
 import org.gudy.azureus2.plugins.network.Connection;
+import org.gudy.azureus2.plugins.network.ConnectionStub;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.peers.*;
 import org.gudy.azureus2.pluginsimpl.local.messaging.MessageAdapter;
+import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
 
 import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
 
@@ -66,13 +69,19 @@ PeerImpl
 		manager = PeerManagerImpl.getPeerManager( delegate.getManager());
 	}
 
+	public void
+	bindConnection(
+		ConnectionStub		stub )
+	{
+	}
+	
 	public PeerManager
 	getManager()
 	{
 		return( manager );
 	}
 	
-	protected PEPeer
+	public PEPeer
 	getDelegate()
 	{
 		return( delegate );
@@ -324,8 +333,23 @@ PeerImpl
 		throw( new RuntimeException( "not supported"));
 	}
 
+	public void
+	addRateLimiter(
+	  RateLimiter		limiter,
+	  boolean			is_upload )
+	{
+		delegate.addRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+	}
 
 	public void
+	removeRateLimiter(
+	  RateLimiter		limiter,
+	  boolean			is_upload )
+	{
+		delegate.removeRateLimiter( UtilitiesImpl.wrapLimiter( limiter ), is_upload );
+	}
+	
+	public void
 	close(
 		String 		reason,
 		boolean 	closedOnError,
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerImpl.java
index b2511a1..4fe81b2 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerImpl.java
@@ -28,6 +28,8 @@ package org.gudy.azureus2.pluginsimpl.local.peers;
 
 import java.util.*;
 
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.disk.DiskManagerListener;
 import org.gudy.azureus2.core3.disk.DiskManagerPiece;
 import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
 import org.gudy.azureus2.core3.peer.*;
@@ -82,7 +84,8 @@ PeerManagerImpl
 	
 	private Map		foreign_map		= new HashMap();
 	
-	private Map		listener_map 	= new HashMap();
+	private Map<PeerManagerListener,PEPeerManagerListener>	listener_map1 	= new HashMap<PeerManagerListener,PEPeerManagerListener>();
+	private Map<PeerManagerListener2,CoreListener>	listener_map2 	= new HashMap<PeerManagerListener2,CoreListener>();
 	
 	protected AEMonitor	this_mon	= new AEMonitor( "PeerManager" );
 
@@ -139,6 +142,21 @@ PeerManagerImpl
 				 {
 				 }
 				 
+				 public void 
+				 pieceAdded( 
+					 PEPeerManager 	manager, 
+					 PEPiece 		piece, 
+					 PEPeer 		for_peer )
+				 {
+				 }
+
+				 public void 
+				 pieceRemoved( 
+					 PEPeerManager 	manager, 
+					 PEPiece 		piece )
+				 {
+				 }
+					
 				 public void
 				 destroyed()
 				 {	
@@ -577,6 +595,21 @@ PeerManagerImpl
 				}
 				
 				public void 
+				pieceAdded( 
+					PEPeerManager 	manager, 
+					PEPiece 		piece, 
+					PEPeer 			for_peer )
+				{
+				}
+				  
+				public void 
+				pieceRemoved( 
+					PEPeerManager 	manager, 
+					PEPiece 		piece )
+				{
+				}
+				
+				public void 
 				peerSentBadData(PEPeerManager manager, PEPeer peer,	int pieceNumber) 
 				{
 				}
@@ -587,7 +620,7 @@ PeerManagerImpl
 				}
 			};
 
-			listener_map.put( l, core_listener );
+			listener_map1.put( l, core_listener );
 
 			manager.addListener( core_listener );
 		}finally{
@@ -603,9 +636,10 @@ PeerManagerImpl
 		try{
 			this_mon.enter();
 		
-			PEPeerManagerListener core_listener	= (PEPeerManagerListener)listener_map.remove( l );
+			PEPeerManagerListener core_listener	= (PEPeerManagerListener)listener_map1.remove( l );
 		
 			if ( core_listener != null ){
+				
 				manager.removeListener( core_listener );
 			}
       
@@ -621,140 +655,13 @@ PeerManagerImpl
 		try{
 			this_mon.enter();
 
-			final Map<PEPeer, Peer>	peer_map = new HashMap<PEPeer, Peer>();
-
-			PEPeerManagerListener core_listener = new 
-				PEPeerManagerListener() 
-				{
-					public void 
-					peerAdded( 
-						PEPeerManager manager, PEPeer peer )
-					{
-						PeerImpl pi = getPeerForPEPeer( peer );
-						
-						peer_map.put( peer, pi );
-						
-						fireEvent(
-							PeerManagerEvent.ET_PEER_ADDED,
-							pi,
-							null,
-							null );
-				}
-
-				public void 
-				peerRemoved( 
-					PEPeerManager manager, 
-					PEPeer peer ) 
-				{
-					PeerImpl  pi = (PeerImpl)peer_map.remove( peer );
-
-					if ( pi == null ){
-
-					}else{
-						
-						fireEvent(
-							PeerManagerEvent.ET_PEER_REMOVED,
-							pi,
-							null,
-							null );
-					}
-				}
-				
-				public void 
-				peerDiscovered(
-					PEPeerManager 	manager,
-					PeerItem 		peer_item, 
-					PEPeer 			finder ) 
-				{
-					PeerImpl	pi;
-					
-					if ( finder != null ){
-						
-						pi = getPeerForPEPeer( finder );
-						
-						peer_map.put( finder, pi );
-						
-					}else{
-						
-						pi = null;
-					}
-					
-					fireEvent(
-						PeerManagerEvent.ET_PEER_DISCOVERED,
-						pi,
-						peer_item,
-						null );
-				}
-				
-				public void 
-				peerSentBadData(
-					PEPeerManager 	manager,
-					PEPeer 			peer, 
-					int 			pieceNumber) 
-				{
-					PeerImpl pi = getPeerForPEPeer( peer );
-					
-					peer_map.put( peer, pi );
-					
-					fireEvent(
-						PeerManagerEvent.ET_PEER_SENT_BAD_DATA,
-						pi,
-						null,
-						new Integer( pieceNumber ));
-					
-				}
-				protected void
-				fireEvent(
-					final int			type,
-					final Peer			peer,
-					final PeerItem		peer_item,
-					final Object		data )
-				{
-					l.eventOccurred(
-						new PeerManagerEvent()
-						{
-							public PeerManager
-							getPeerManager()
-							{
-								return( PeerManagerImpl.this );
-							}
-							
-							public int
-							getType()
-							{
-								return( type );
-							}
-							
-							public Peer
-							getPeer()
-							{
-								return( peer );
-							}
-							
-							public PeerDescriptor
-							getPeerDescriptor()
-							{
-								return( peer_item );
-							}
-							
-							public Object 
-							getData() 
-							{
-								return( data );
-							}
-						});
-				}
-					
-					
-				public void
-				destroyed()
-				{
-				}
-			};
-
-			listener_map.put( l, core_listener );
+			CoreListener core_listener = new CoreListener( l );
+			
+			listener_map2.put( l, core_listener );
 
 			manager.addListener( core_listener );
+			
+			manager.getDiskManager().addListener( core_listener );
 		}finally{
 
 			this_mon.exit();
@@ -768,13 +675,17 @@ PeerManagerImpl
 		try{
 			this_mon.enter();
 		
-			PEPeerManagerListener core_listener	= (PEPeerManagerListener)listener_map.remove( l );
+			CoreListener core_listener	= listener_map2.remove( l );
 		
 			if ( core_listener != null ){
+				
 				manager.removeListener( core_listener );
+				
+				manager.getDiskManager().removeListener( core_listener );
 			}
       
 		}finally{
+			
 			this_mon.exit();
 		}
 	}
@@ -792,6 +703,18 @@ PeerManagerImpl
 			index	= _index;
 		}
 		
+		public int
+		getIndex()
+		{
+			return( index );
+		}
+		
+		public int
+		getLength()
+		{
+			return( dm_pieces[index].getLength());
+		}
+		
 		public boolean
 		isDone()
 		{
@@ -838,5 +761,246 @@ PeerManagerImpl
 			
 			return( 0 );
 		}
+		
+		public Peer
+		getReservedFor()
+		{
+			PEPiece piece = pe_pieces[index];
+
+			if ( piece != null ){
+							
+				String ip = piece.getReservedBy();
+				
+				if ( ip != null ){
+					
+					List<PEPeer> peers = manager.getPeers( ip );
+					
+					if ( peers.size() > 0 ){
+						
+						return( getPeerForPEPeer( peers.get(0)));
+					}
+				}
+			}
+			
+			return( null );
+		}
+		
+		public void
+		setReservedFor(
+			Peer	peer )
+		{
+			PEPiece piece = pe_pieces[index];
+			
+			PEPeer mapped_peer = mapForeignPeer( peer );
+			
+			if ( piece != null && mapped_peer != null ){
+				
+				piece.setReservedBy( peer.getIp());
+			
+				mapped_peer.addReservedPieceNumber( index );
+			}
+		}
+	}
+	
+	private class
+	CoreListener
+		implements PEPeerManagerListener, DiskManagerListener
+	{
+		private PeerManagerListener2		listener;
+		private Map<PEPeer, Peer>			peer_map = new HashMap<PEPeer, Peer>();
+
+		private
+		CoreListener(
+			PeerManagerListener2		_listener )
+		{
+			listener	= _listener;
+		}
+		
+		public void 
+		peerAdded( 
+			PEPeerManager manager, PEPeer peer )
+		{
+			PeerImpl pi = getPeerForPEPeer( peer );
+			
+			peer_map.put( peer, pi );
+			
+			fireEvent(
+				PeerManagerEvent.ET_PEER_ADDED,
+				pi,
+				null,
+				null );
+		}
+	
+		public void 
+		peerRemoved( 
+			PEPeerManager manager, 
+			PEPeer peer ) 
+		{
+			PeerImpl  pi = (PeerImpl)peer_map.remove( peer );
+	
+			if ( pi == null ){
+	
+			}else{
+				
+				fireEvent(
+					PeerManagerEvent.ET_PEER_REMOVED,
+					pi,
+					null,
+					null );
+			}
+		}
+		
+		public void 
+		peerDiscovered(
+			PEPeerManager 	manager,
+			PeerItem 		peer_item, 
+			PEPeer 			finder ) 
+		{
+			PeerImpl	pi;
+			
+			if ( finder != null ){
+				
+				pi = getPeerForPEPeer( finder );
+				
+				peer_map.put( finder, pi );
+				
+			}else{
+				
+				pi = null;
+			}
+			
+			fireEvent(
+				PeerManagerEvent.ET_PEER_DISCOVERED,
+				pi,
+				peer_item,
+				null );
+		}
+		
+		public void 
+		pieceAdded( 
+			PEPeerManager 	manager, 
+			PEPiece 		piece, 
+			PEPeer 			for_peer )
+		{
+			PeerImpl pi = for_peer==null?null:getPeerForPEPeer( for_peer );
+	
+			fireEvent(
+					PeerManagerEvent.ET_PIECE_ACTIVATED,
+					pi,
+					null,
+					new pieceFacade( piece.getPieceNumber()));
+		}
+		  
+		public void 
+		pieceRemoved( 
+			PEPeerManager 	manager, 
+			PEPiece 		piece )
+		{
+			fireEvent(
+					PeerManagerEvent.ET_PIECE_DEACTIVATED,
+					null,
+					null,
+					new pieceFacade( piece.getPieceNumber()));
+		}
+		
+		public void 
+		peerSentBadData(
+			PEPeerManager 	manager,
+			PEPeer 			peer, 
+			int 			pieceNumber) 
+		{
+			PeerImpl pi = getPeerForPEPeer( peer );
+			
+			peer_map.put( peer, pi );
+			
+			fireEvent(
+				PeerManagerEvent.ET_PEER_SENT_BAD_DATA,
+				pi,
+				null,
+				new Integer( pieceNumber ));
+			
+		}
+		
+			// disk manager methods
+		
+		public void
+		stateChanged(
+			int oldState, 
+			int	newState )
+		{
+		}
+		
+		public void
+		filePriorityChanged(
+			DiskManagerFileInfo		file )
+		{
+		}
+
+		public void
+		pieceDoneChanged(
+			DiskManagerPiece		piece )
+		{
+			fireEvent(
+					PeerManagerEvent.ET_PIECE_COMPLETION_CHANGED,
+					null,
+					null,
+					new pieceFacade( piece.getPieceNumber()));
+		}
+		
+		public void
+		fileAccessModeChanged(
+			DiskManagerFileInfo		file,
+			int						old_mode,
+			int						new_mode )
+		{
+		}
+		
+		protected void
+		fireEvent(
+			final int			type,
+			final Peer			peer,
+			final PeerItem		peer_item,
+			final Object		data )
+		{
+			listener.eventOccurred(
+				new PeerManagerEvent()
+				{
+					public PeerManager
+					getPeerManager()
+					{
+						return( PeerManagerImpl.this );
+					}
+					
+					public int
+					getType()
+					{
+						return( type );
+					}
+					
+					public Peer
+					getPeer()
+					{
+						return( peer );
+					}
+					
+					public PeerDescriptor
+					getPeerDescriptor()
+					{
+						return( peer_item );
+					}
+					
+					public Object 
+					getData() 
+					{
+						return( data );
+					}
+				});
+		}
+			
+			
+		public void
+		destroyed()
+		{
+		}
 	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerStatsImpl.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerStatsImpl.java
index 83d7f28..ff452df 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerStatsImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerManagerStatsImpl.java
@@ -94,4 +94,29 @@ PeerManagerStatsImpl
 		return( stats.getTotalHashFailBytes());
 	}
 	
+	public int 
+	getPermittedBytesToReceive()
+	{
+		return( stats.getPermittedBytesToReceive());
+	}
+	
+	public void 
+	permittedReceiveBytesUsed( 
+		int bytes )
+	{
+		stats.permittedReceiveBytesUsed( bytes );
+	}
+	
+	public int 
+	getPermittedBytesToSend()
+	{
+		return( stats.getPermittedBytesToSend());
+	}
+	
+	public void 
+	permittedSendBytesUsed( 
+		int bytes )
+	{
+		stats.permittedSendBytesUsed( bytes );
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/peers/PeerStatsImpl.java b/org/gudy/azureus2/pluginsimpl/local/peers/PeerStatsImpl.java
index 6a8d85e..6df2864 100644
--- a/org/gudy/azureus2/pluginsimpl/local/peers/PeerStatsImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/peers/PeerStatsImpl.java
@@ -97,6 +97,36 @@ PeerStatsImpl
 		return( (int)delegate.getEstimatedUploadRateOfPeer());
 	}
 	
+	public int 
+	getPermittedBytesToReceive()
+	{
+		return( delegate.getPermittedBytesToReceive());
+	}
+	
+	public void 
+	permittedReceiveBytesUsed( 
+		int bytes )
+	{
+		delegate.permittedReceiveBytesUsed( bytes );
+
+		received( bytes );
+	}
+	
+	public int 
+	getPermittedBytesToSend()
+	{
+		return( delegate.getPermittedBytesToSend());
+	}
+	
+	public void 
+	permittedSendBytesUsed( 
+		int bytes )
+	{
+		delegate.permittedSendBytesUsed( bytes );
+
+		sent( bytes );
+	}
+	
 	public void
 	received(
 		int		bytes )
@@ -107,6 +137,15 @@ PeerStatsImpl
 	}
 	
 	public void
+	sent(
+		int		bytes )
+	{		
+		delegate.dataBytesSent( bytes );
+		
+		manager.dataBytesSent( delegate.getPeer(), bytes );
+	}
+	
+	public void
 	discarded(
 		int		bytes )
 	{
@@ -133,4 +172,23 @@ PeerStatsImpl
 	{
 		delegate.setDownloadRateLimitBytesPerSecond( bytes );
 	}
+	
+	public int 
+	getUploadRateLimit() 
+	{
+		return( delegate.getUploadRateLimitBytesPerSecond());
+	}
+	
+	public void 
+	setUploadRateLimit( 
+		int bytes ) 
+	{
+		delegate.setUploadRateLimitBytesPerSecond( bytes );
+	}
+	
+	public long
+	getOverallBytesRemaining()
+	{
+		return( delegate.getPeer().getBytesRemaining());
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
index 87fbb79..a5cdb2f 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareManagerImpl.java
@@ -509,19 +509,50 @@ ShareManagerImpl
 		}
 	}
 	
+	private boolean
+	getBooleanProperty(
+		Map<String,String>	properties,
+		String				name )
+	{
+		if ( properties == null ){
+			
+			return( false );
+		}
+		
+		String	value = properties.get( name );
+		
+		if ( value == null ){
+			
+			return( false );
+		}
+		
+		return( value.equalsIgnoreCase( "true" ));
+	}
+	
 	public ShareResourceFile
 	addFile(
 		File	file )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
-		return( addFile( null, file ));
+		return( addFile( file, null ));
+	}
+	
+	public ShareResourceFile
+	addFile(
+		File				file,
+		Map<String,String>	properties )
+	
+		throws ShareException, ShareResourceDeletionVetoException
+	{
+		return( addFile( null, file, getBooleanProperty( properties, PR_PERSONAL )));
 	}
 	
 	protected ShareResourceFile
 	addFile(
 		ShareResourceDirContentsImpl	parent,
-		File							file )
+		File							file,
+		boolean							personal )
 
 		throws ShareException, ShareResourceDeletionVetoException
 	{
@@ -530,7 +561,7 @@ ShareManagerImpl
 					+ file.toString() + "'"));
 
 		try{
-			return( (ShareResourceFile)addFileOrDir( parent, file, ShareResource.ST_FILE ));
+			return( (ShareResourceFile)addFileOrDir( parent, file, ShareResource.ST_FILE, personal ));
 			
 		}catch( ShareException e ){
 			
@@ -551,17 +582,28 @@ ShareManagerImpl
 	
 	public ShareResourceDir
 	addDir(
-		File	dir )
+		File				dir )
+	
+		throws ShareException, ShareResourceDeletionVetoException
+	{
+		return( addDir( dir, null ));
+	}
+	
+	public ShareResourceDir
+	addDir(
+		File				dir,
+		Map<String,String>	properties )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
-		return( addDir( null, dir ));
+		return( addDir( null, dir, getBooleanProperty( properties, PR_PERSONAL )));
 	}
 	
 	public ShareResourceDir
 	addDir(
 		ShareResourceDirContentsImpl	parent,
-		File							dir )
+		File							dir,
+		boolean							personal )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
@@ -572,7 +614,7 @@ ShareManagerImpl
 		try{
 			this_mon.enter();
 			
-			return( (ShareResourceDir)addFileOrDir( parent, dir, ShareResource.ST_DIR ));
+			return( (ShareResourceDir)addFileOrDir( parent, dir, ShareResource.ST_DIR, personal ));
 			
 		}catch( ShareException e ){
 			
@@ -599,7 +641,8 @@ ShareManagerImpl
 	addFileOrDir(
 		ShareResourceDirContentsImpl	parent,
 		File							file,
-		int								type )
+		int								type,
+		boolean							personal )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
@@ -623,13 +666,13 @@ ShareManagerImpl
 		
 				reportCurrentTask( "Adding file '" + name + "'");
 				
-				new_resource = new ShareResourceFileImpl( this, parent, file );
+				new_resource = new ShareResourceFileImpl( this, parent, file, personal );
 				
 			}else{
 				
 				reportCurrentTask( "Adding dir '" + name + "'");
 				
-				new_resource = new ShareResourceDirImpl( this, parent, file );
+				new_resource = new ShareResourceDirImpl( this, parent, file, personal );
 			}
 			
 			shares.put(name, new_resource );
@@ -666,12 +709,21 @@ ShareManagerImpl
 		}
 	}
 	
-
+	public ShareResourceDirContents
+	addDirContents(
+		File				dir,
+		boolean				recursive )
+	
+		throws ShareException, ShareResourceDeletionVetoException
+	{
+		return( addDirContents( dir, recursive, null ));
+	}
 	
 	public ShareResourceDirContents
 	addDirContents(
-		File		dir,
-		boolean		recursive )
+		File				dir,
+		boolean				recursive,
+		Map<String,String>	properties )
 	
 		throws ShareException, ShareResourceDeletionVetoException
 	{
@@ -693,7 +745,7 @@ ShareManagerImpl
 				old_resource.delete( true );
 			}
 
-			ShareResourceDirContentsImpl new_resource = new ShareResourceDirContentsImpl( this, dir, recursive, true );
+			ShareResourceDirContentsImpl new_resource = new ShareResourceDirContentsImpl( this, dir, recursive, getBooleanProperty( properties, PR_PERSONAL ), true );
 						
 			shares.put( name, new_resource );
 			
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
index c45c75b..2e62fab 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirContentsImpl.java
@@ -39,8 +39,9 @@ ShareResourceDirContentsImpl
 	extends		ShareResourceImpl
 	implements 	ShareResourceDirContents
 {
-	protected File		root;
-	protected boolean	recursive;
+	private final File			root;
+	private final boolean		recursive;
+	private final byte[]		personal_key;
 	
 	protected ShareResource[]		children	= new ShareResource[0];
 	
@@ -49,6 +50,7 @@ ShareResourceDirContentsImpl
 		ShareManagerImpl	_manager,
 		File				_dir,
 		boolean				_recursive,
+		boolean				_personal,
 		boolean				_async_check )
 
 		throws ShareException
@@ -60,7 +62,7 @@ ShareResourceDirContentsImpl
 		
 		if ( !root.exists()){
 			
-			throw( new ShareException( "Dir '".concat(root.getName()).concat("' not found")));
+			throw( new ShareException( "Dir '" + root.getName() + "' not found"));
 		}
 		
 		if ( root.isFile()){
@@ -68,6 +70,8 @@ ShareResourceDirContentsImpl
 			throw( new ShareException( "Not a directory"));
 		}
 		
+		personal_key = _personal?RandomUtils.nextSecureHash():null;
+		
 			// new resource, trigger processing
 		
 		if ( _async_check ){
@@ -123,6 +127,8 @@ ShareResourceDirContentsImpl
 			}
 		}
 		
+		personal_key = (byte[])_map.get( "per_key" );
+		
 			// deserialised resource, checkConsistency will be called later to trigger sub-share adding
 	}
 	
@@ -214,7 +220,7 @@ ShareResourceDirContentsImpl
 								
 								if ( res == null ){
 								
-									res = manager.addDir( this, file );
+									res = manager.addDir( this, file, personal_key != null );
 								}
 								
 								kids.add( res );
@@ -231,7 +237,7 @@ ShareResourceDirContentsImpl
 							
 							if ( res == null ){
 								
-								res = manager.addFile( this, file );
+								res = manager.addFile( this, file, personal_key != null );
 							}
 							
 							kids.add( res );
@@ -299,6 +305,11 @@ ShareResourceDirContentsImpl
 			
 			Debug.printStackTrace( e );
 		}
+		
+		if ( personal_key != null ){
+			
+			map.put( "per_key", personal_key );
+		}
 	}
 	
 	protected static ShareResourceImpl
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirImpl.java
index ae672c0..1830369 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceDirImpl.java
@@ -57,11 +57,12 @@ ShareResourceDirImpl
 	ShareResourceDirImpl(
 		ShareManagerImpl				_manager,
 		ShareResourceDirContentsImpl	_parent,
-		File							_file )
+		File							_file,
+		boolean							_personal )
 	
 		throws ShareException
 	{
-		super( _manager, _parent, ST_DIR, _file );
+		super( _manager, _parent, ST_DIR, _file, _personal );
 	}
 	
 	protected
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileImpl.java
index 9d69d3f..a80972c 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileImpl.java
@@ -57,11 +57,12 @@ ShareResourceFileImpl
 	ShareResourceFileImpl(
 		ShareManagerImpl				_manager,
 		ShareResourceDirContentsImpl	_parent,
-		File							_file )
+		File							_file,
+		boolean							_personal )
 	
 		throws ShareException
 	{
-		super( _manager, _parent, ST_FILE, _file );
+		super( _manager, _parent, ST_FILE, _file, _personal );
 	}
 	
 	protected
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
index d3ba472..ac2f491 100644
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/sharing/ShareResourceFileOrDirImpl.java
@@ -45,9 +45,10 @@ public abstract class
 ShareResourceFileOrDirImpl
 	extends		ShareResourceImpl
 {
-	protected File		file;
+	private final File				file;
+	private	final byte[]			personal_key;
 	
-	protected ShareItemImpl		item;
+	private ShareItemImpl		item;
 	
 	protected static ShareResourceImpl
 	getResourceSupport(
@@ -70,46 +71,46 @@ ShareResourceFileOrDirImpl
 		ShareManagerImpl				_manager,
 		ShareResourceDirContentsImpl	_parent,
 		int								_type,
-		File							_file )
+		File							_file,
+		boolean							_personal )
 	
 		throws ShareException
 	{
 		super( _manager, _type );
 		
-		file		= _file;
-		
 		if ( getType() == ST_FILE ){
 			
-			if ( !file.exists()){
+			if ( !_file.exists()){
 			
-				throw( new ShareException( "File '".concat(file.getName()).concat("' not found")));
+				throw( new ShareException( "File '" + _file.getName() + "' not found"));
 			}
 		
-			if ( !file.isFile()){
+			if ( !_file.isFile()){
 			
 				throw( new ShareException( "Not a file"));
 			}
 		}else{
 			
-			if ( !file.exists()){
+			if ( !_file.exists()){
 				
-				throw( new ShareException( "Dir '".concat(file.getName()).concat("' not found")));
+				throw( new ShareException( "Dir '"+ _file.getName() + "' not found"));
 			}
 			
-			if ( file.isFile()){
+			if ( _file.isFile()){
 				
 				throw( new ShareException( "Not a directory"));
 			}		
 		}
 		
 		try{
-			file = file.getCanonicalFile();
+			file = _file.getCanonicalFile();
 						
 		}catch( IOException e ){
 	
 			throw( new ShareException("ShareResourceFile: failed to get canonical name", e));
 		}
 		
+		personal_key = _personal?RandomUtils.nextSecureHash():null;
 		
 		if ( _parent != null ){
 			
@@ -134,6 +135,8 @@ ShareResourceFileOrDirImpl
 		
 		file		= _file;
 		
+		personal_key = (byte[])_map.get( "per_key" );
+
 		item = ShareItemImpl.deserialiseItem( this, _map );
 	}
 	
@@ -184,6 +187,17 @@ ShareResourceFileOrDirImpl
 				manager.setTorrentCreator( null );
 			}
 			
+			if ( personal_key != null ){
+				
+				Map	map = to_torrent.serialiseToMap();
+				
+				Map	info = (Map)map.get( "info" );
+				
+				info.put( "az_salt", personal_key );
+			
+				to_torrent =  TOTorrentFactory.deserialiseFromMap( map );
+			}
+			
 			LocaleTorrentUtil.setDefaultTorrentEncoding( to_torrent );
 							
 			for (int i=1;i<urls.length;i++){
@@ -310,7 +324,7 @@ ShareResourceFileOrDirImpl
 				}
 			}else{
 				
-				manager.addFileOrDir( null, file, getType());
+				manager.addFileOrDir( null, file, getType(), personal_key != null );
 			}
 		}catch( Throwable e ){
 							
@@ -342,6 +356,7 @@ ShareResourceFileOrDirImpl
 			throw( new ShareException( "internal error", e ));
 		}
 	}
+	
 	protected void
 	serialiseResource(
 		Map		map )
@@ -358,6 +373,11 @@ ShareResourceFileOrDirImpl
 			Debug.printStackTrace( e );
 		}
 		
+		if ( personal_key != null ){
+			
+			map.put( "per_key", personal_key );
+		}
+		
 		item.serialiseItem( map );
 	}
 	
diff --git a/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java b/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java
deleted file mode 100644
index ddd676e..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/sharing/test/ShareTester.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * File    : ShareTester.java
- * Created : 30-Dec-2003
- * 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.pluginsimpl.local.sharing.test;
-
-
-
-import java.util.*;
-
-import org.gudy.azureus2.plugins.*;
-import org.gudy.azureus2.plugins.logging.*;
-import org.gudy.azureus2.plugins.sharing.*;
-import org.gudy.azureus2.plugins.download.*;
-import org.gudy.azureus2.plugins.peers.*;
-import org.gudy.azureus2.core3.util.*;
-
-public class 
-ShareTester
-	implements Plugin, PluginListener, ShareManagerListener
-{
-	protected static AESemaphore		init_sem 	= new AESemaphore("ShareTester");
-	private static AEMonitor			class_mon	= new AEMonitor( "ShareTester" );
-
-	protected static ShareTester		singleton;
-	
-	protected Map	seed_transport_map	= new HashMap();
-	
-	
-	public static ShareTester
-	getSingleton()
-	{
-		try{
-			class_mon.enter();
-		
-			if ( singleton == null ){
-				
-				new AEThread( "plugin initialiser ")
-				{
-					public void
-					runSupport()
-					{
-						PluginManager.registerPlugin( ShareTester.class );
-		
-						Properties props = new Properties();
-						
-						props.put( PluginManager.PR_MULTI_INSTANCE, "true" );
-						
-						PluginManager.startAzureus( PluginManager.UI_SWT, props );
-					}
-				}.start();
-			
-				init_sem.reserve();
-			}
-			
-			return( singleton );
-			
-		}finally{
-			
-			class_mon.exit();
-		}
-	}	
-	
-	protected PluginInterface		plugin_interface;
-	
-	public void 
-	initialize(
-		PluginInterface _pi )
-	{	
-		plugin_interface = _pi;
-		
-		singleton = this;
-		
-		init_sem.release();
-		
-		LoggerChannel log = plugin_interface.getLogger().getChannel("Plugin Test");
-		
-		log.log(LoggerChannel.LT_INFORMATION, "Plugin Initialised");
-		
-		plugin_interface.addListener( this );
-	}
-	
-	public void
-	initializationComplete()
-	{
-		try{
-			DownloadManager	dm = plugin_interface.getDownloadManager();
-			
-			dm.addListener(
-					new DownloadManagerListener()
-					{
-						public void
-						downloadAdded(
-							final Download	download )
-						{
-							System.out.println("downloadAdded: " + download );
-							
-							download.addListener(
-								new DownloadListener()
-								{
-									public void
-									stateChanged(
-										Download	dl,
-										int			old,
-										int			cur )
-									{
-										System.out.println( "statechange:" + old + "-> " + cur + "  (" + download + ")");
-									}
-					                public void
-					                positionChanged(
-					                    Download	download, 
-					                    int old,
-					                    int cur)
-									{
-										System.out.println( "statechange:" + old + "-> " + cur + "  (" + download + ")");
-									}
-								});
-							
-							download.addTrackerListener(
-								new DownloadTrackerListener()
-								{
-									public void
-									scrapeResult(
-										DownloadScrapeResult result )
-									{
-										System.out.println( "scrapeResult:" + result.getSeedCount() + "/" + result.getNonSeedCount());
-									}
-									
-									public void
-									announceResult(
-										DownloadAnnounceResult	result )
-									{
-										if ( result.getResponseType() == DownloadAnnounceResult.RT_SUCCESS ){
-										
-											System.out.println( "announceResult:" + result.getReportedPeerCount() + "/" + result.getSeedCount() + "/" + result.getNonSeedCount());
-											
-										}else{
-											
-											System.out.println( "announceResult:" + result.getError());
-										}
-									}								
-								});
-							
-							download.addPeerListener(
-								new DownloadPeerListener()
-								{
-									public void
-									peerManagerAdded(
-										Download		download,
-										PeerManager		peer_manager )
-									{
-										peer_manager.addListener(
-											new PeerManagerListener()
-											{											
-												public void
-												peerAdded(
-													PeerManager	manager,
-													Peer		peer )
-												{
-													System.out.println( "peerAdded:" + peer.getIp());
-												}
-												
-												public void
-												peerRemoved(
-													PeerManager	manager,
-													Peer		peer )
-												{
-													System.out.println( "peerRemoved:" + peer.getIp());
-												}
-											});
-									}
-									
-									public void
-									peerManagerRemoved(
-										Download		download,
-										PeerManager		peer_manager )
-									{
-									}
-								});
-						}
-						public void
-						downloadRemoved(
-							Download	download )
-						{
-							System.out.println("downloadRemoved" + download );
-						}
-					});
-			
-			ShareManager	sm = plugin_interface.getShareManager();
-		
-			sm.addListener( this );
-			
-			sm.initialise();
-			
-			// ShareResourceFile res = sm.addFile( new File("c:\\temp\\shares\\test.wmf"));
-			// ShareResourceDirContents res = sm.addDirContents( new File("D:\\music\\cd1"), false);
-			
-			//Torrent t = res.getItem().getTorrent();
-			
-			//System.out.println( t.getHash());
-			
-		}catch( ShareException e ){
-			
-			Debug.printStackTrace( e );
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	
-	}
-	
-	public void
-	closedownInitiated()
-	{
-	}
-	
-	public void
-	closedownComplete()
-	{
-	}
-	
-	public void
-	resourceAdded(
-		ShareResource		resource )
-	{
-		System.out.println( "resource added:" + resource.getName());
-		
-		if ( resource.getType() == ShareResource.ST_DIR_CONTENTS ){
-			
-			ShareResourceDirContents c = (ShareResourceDirContents)resource;
-			
-			ShareResource[]	kids = c.getChildren();
-			
-			for (int i=0;i<kids.length;i++){
-				
-				System.out.println( "\t" + kids[i].getName());
-			}
-		}
-	}
-	
-	public void
-	resourceModified(
-		ShareResource		old_resource ,
-		ShareResource		new_resource )
-	{
-		System.out.println( "resource modified:" + old_resource.getName());
-	}
-	
-	public void
-	resourceDeleted(
-		ShareResource		resource )
-	{
-		System.out.println( "resource deleted:" + resource.getName());
-	}
-	
-	public void
-	reportProgress(
-		int		percent_complete )
-	{
-	}
-	
-	public void
-	reportCurrentTask(
-		String	task_description )
-	{
-		System.out.println( task_description );
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		getSingleton();
-	}
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/test/Test.java b/org/gudy/azureus2/pluginsimpl/local/test/Test.java
deleted file mode 100644
index 8b5c262..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/test/Test.java
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Created on 02-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 org.gudy.azureus2.pluginsimpl.local.test;
-
-
-import org.gudy.azureus2.core3.util.AEMonitor;
-import org.gudy.azureus2.core3.util.AESemaphore;
-import org.gudy.azureus2.core3.util.AEThread;
-import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.plugins.Plugin;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginListener;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.ddb.*;
-import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.download.DownloadManagerListener;
-import org.gudy.azureus2.plugins.messaging.MessageException;
-import org.gudy.azureus2.plugins.messaging.MessageManager;
-import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnection;
-import org.gudy.azureus2.plugins.messaging.generic.GenericMessageConnectionListener;
-import org.gudy.azureus2.plugins.messaging.generic.GenericMessageEndpoint;
-import org.gudy.azureus2.plugins.messaging.generic.GenericMessageHandler;
-import org.gudy.azureus2.plugins.messaging.generic.GenericMessageRegistration;
-import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
-import org.gudy.azureus2.plugins.torrent.TorrentAttributeEvent;
-import org.gudy.azureus2.plugins.torrent.TorrentAttributeListener;
-import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
-import org.gudy.azureus2.plugins.utils.search.Search;
-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.search.SearchProviderResults;
-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;
-
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.util.*;
-
-
-/**
- * @author parg
- *
- */
-
-
-public class 
-Test 
-	implements Plugin
-{
-
-	protected PluginInterface		plugin_interface;
-	
-	public void 
-	initialize(
-		PluginInterface _pi )
-	{	
-		plugin_interface	= _pi;
-		
-		plugin_interface.addListener(
-				new PluginListener()
-				{
-					public void
-					initializationComplete()
-					{
-						Thread	t  = 
-							new AEThread("test")
-							{
-								public void
-								runSupport()
-								{
-									
-									// testLinks();
-									// testMessaging();
-									try{
-										// PlatformManagerFactory.getPlatformManager().performRecoverableFileDelete( "C:\\temp\\recycle.txt" );
-										// PlatformManagerFactory.getPlatformManager().setTCPTOSEnabled( false );
-										
-									}catch( Throwable e ){
-										
-										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{
-											Thread.sleep(1000);
-											
-											SearchInitiator si = plugin_interface.getUtilities().getSearchInitiator();
-			
-											SearchProvider[] providers = si.getProviders();
-											
-											System.out.println( "search providers=" + providers.length );
-											
-											if ( providers.length > 0 ){
-												
-												Map<String,String> properties = new HashMap<String,String>();
-											
-												properties.put( SearchInitiator.PR_SEARCH_TERM, "monkey" );
-												properties.put( SearchInitiator.PR_MATURE, "true" );
-												
-												/*
-												final boolean[] complete = {false};
-												
-												Search s = 
-													si.createSearch(
-														providers,
-														properties,
-														new SearchListener()
-														{
-															public void
-															receivedResults(
-																SearchProviderResults[]		results )
-															{
-																System.out.println( "received results" );
-																
-																for ( SearchProviderResults result: results ){
-																	
-																	System.out.println( "    " + result.getProvider().getProperty( SearchProvider.PR_NAME ) + ": comp=" + result.isComplete() + ", error=" + result.getError());
-																	
-																	SearchResult[] srs = result.getResults();
-																	
-																	for ( SearchResult sr: srs ){
-																		
-																		System.out.println( "        " + sr.getProperty( SearchResult.PR_NAME ));
-																	}
-																}
-															}
-															
-															public void
-															completed()
-															{
-																System.out.println( "received completed" );
-																
-																complete[0] = true;
-															}
-														});
-												
-												while( !complete[0] ){
-													
-													Thread.sleep(1000);
-													
-													System.out.println( "waiting for results" );
-												}
-												
-												
-												
-												Search s = si.createSearch(	providers, properties, null );
-												
-												while( !s.isComplete()){
-													
-													Thread.sleep(1000);
-													
-													SearchProviderResults[] results = s.getResults();
-													
-													if ( results.length > 0 ){
-													
-														System.out.println( "Got results: " + results.length );
-														
-														for ( SearchProviderResults result: results ){
-															
-															System.out.println( "    " + result.getProvider().getProperty( SearchProvider.PR_NAME ) + ": comp=" + result.isComplete() + ", error=" + result.getError());
-															
-															SearchResult[] srs = result.getResults();
-															
-															for ( SearchResult sr: srs ){
-																
-																System.out.println( "        " + sr.getProperty( SearchResult.PR_NAME ));
-															}
-														}
-													}
-												}
-												
-												break;
-											}
-										}catch( Throwable e){
-											
-											e.printStackTrace();
-										}
-									}
-									*/
-								}
-							};
-							
-						t.setDaemon(true);
-						
-						t.start();
-					}
-					
-					public void
-					closedownInitiated()
-					{	
-					}
-					
-					public void
-					closedownComplete()
-					{
-					}
-				});
-	}
-	
-	protected void
-	testMessaging()
-	{
-		try{
-			AzureusCoreFactory.getSingleton().getCryptoManager().addPasswordHandler(
-				new CryptoManagerPasswordHandler()
-				{
-					public int
-					getHandlerType()
-					{
-						return( HANDLER_TYPE_USER );
-					}
-					
-					public passwordDetails
-		        	getPassword(
-		        		int			handler_type,
-		        		int			action_type,
-		        		boolean		last_pw_incorrect,
-		        		String		reason )
-					{
-						System.out.println( "CryptoPassword (" + reason + ")");
-						
-						return(
-							new passwordDetails()
-							{
-								public char[]
-								getPassword()
-								{
-									return( "changeit".toCharArray());
-								}
-								
-								public int 
-								getPersistForSeconds() 
-								{
-									return( 0 );
-								}
-							});
-					}
-					
-					public void 
-					passwordOK(
-						int 				handler_type,
-						passwordDetails 	details) 
-					{
-					}
-				});
-			
-			final SESecurityManager	sec_man = plugin_interface.getUtilities().getSecurityManager();
-			
-			final SEPublicKey	my_key = sec_man.getPublicKey( SEPublicKey.KEY_TYPE_ECC_192, "test" );
-
-			final int	stream_crypto 	= MessageManager.STREAM_ENCRYPTION_RC4_REQUIRED;
-			final boolean	use_sts		= true;
-			final int	block_crypto 	= SESecurityManager.BLOCK_ENCRYPTION_AES;
-			
-			GenericMessageRegistration	reg = 
-				plugin_interface.getMessageManager().registerGenericMessageType(
-					"GENTEST", "Gen test desc", 
-					stream_crypto,
-					new GenericMessageHandler()
-					{
-						public boolean
-						accept(
-							GenericMessageConnection	connection )
-						
-							throws MessageException
-						{
-							System.out.println( "accept" );
-							
-							try{
-								if ( use_sts ){
-									
-									connection = sec_man.getSTSConnection(
-											connection, 
-											my_key,
-											new SEPublicKeyLocator()
-											{
-												public boolean
-												accept(
-													Object		context,
-													SEPublicKey	other_key )
-												{
-													System.out.println( "acceptKey" );
-													
-													return( true );
-												}
-											},
-											"test",
-											block_crypto );
-								}
-										
-								connection.addListener(
-									new GenericMessageConnectionListener()
-									{
-										public void
-										connected(
-											GenericMessageConnection	connection )
-										{
-										}
-										
-										public void
-										receive(
-											GenericMessageConnection	connection,
-											PooledByteBuffer			message )
-										
-											throws MessageException
-										{
-											System.out.println( "receive: " + message.toByteArray().length );
-											
-											PooledByteBuffer	reply = 
-												plugin_interface.getUtilities().allocatePooledByteBuffer( 
-														new byte[connection.getMaximumMessageSize()]);
-											
-											connection.send( reply );
-										}
-										
-										public void
-										failed(
-											GenericMessageConnection	connection,
-											Throwable 					error )
-										
-											throws MessageException
-										{
-											System.out.println( "Responder connection error:" );
-
-											error.printStackTrace();
-										}	
-									});
-								
-							}catch( Throwable e ){
-								
-								connection.close();
-								
-								e.printStackTrace();
-							}
-							
-							return( true );
-						}
-					});
-			
-			InetSocketAddress	tcp_target = new InetSocketAddress( "127.0.0.1", 		6889 );
-			InetSocketAddress	udp_target = new InetSocketAddress( "212.159.18.92", 	6881 );
-			
-			GenericMessageEndpoint	endpoint = reg.createEndpoint( tcp_target );
-			
-			endpoint.addTCP( tcp_target );
-			endpoint.addUDP( udp_target );
-			
-			while( true ){
-				
-				try{
-					for (int i=0;i<1000;i++){
-						
-						System.out.println( "Test: initiating connection" );
-						
-						final AESemaphore	sem = new AESemaphore( "wait!" );
-						
-						GenericMessageConnection	con = reg.createConnection( endpoint );
-						
-						if ( use_sts ){
-							
-							con = sec_man.getSTSConnection( 
-								con, my_key,
-								new SEPublicKeyLocator()
-								{
-									public boolean
-									accept(
-										Object			context,
-										SEPublicKey		other_key )
-									{
-										System.out.println( "acceptKey" );
-										
-										return( true );
-									}
-								},
-								"test", block_crypto );
-						}
-						
-						con.addListener(
-							new GenericMessageConnectionListener()
-							{
-								public void
-								connected(
-									GenericMessageConnection	connection )
-								{
-									System.out.println( "connected" );
-									
-									PooledByteBuffer	data = plugin_interface.getUtilities().allocatePooledByteBuffer( "1234".getBytes());
-									
-									try{
-										connection.send( data );
-										
-									}catch( Throwable e ){
-										
-										e.printStackTrace();
-									}
-								}
-								
-								public void
-								receive(
-									GenericMessageConnection	connection,
-									PooledByteBuffer			message )
-								
-									throws MessageException
-								{
-									System.out.println( "receive: " + message.toByteArray().length );
-									
-									
-									try{
-										Thread.sleep(30000);
-									}catch( Throwable e ){
-										
-									}
-								
-									/*
-									PooledByteBuffer	reply = 
-										plugin_interface.getUtilities().allocatePooledByteBuffer( new byte[16*1024]);
-									
-									
-									connection.send( reply );
-									*/
-									
-									System.out.println( "closing connection" );
-									
-									connection.close();
-									
-									sem.release();
-								}
-								
-								public void
-								failed(
-									GenericMessageConnection	connection,
-									Throwable 					error )
-								
-									throws MessageException
-								{
-									System.out.println( "Initiator connection error:" );
-									
-									error.printStackTrace();
-									
-									sem.release();
-								}
-							});
-						
-			
-						con.connect();
-						
-						sem.reserve();
-						
-						Thread.sleep( 1000 );
-					}
-				
-				}catch( Throwable e ){
-					
-					e.printStackTrace();
-					
-					try{
-						System.out.println( "Sleeping before retrying" );
-						
-						Thread.sleep( 30000 );
-						
-					}catch( Throwable f ){
-					}
-				}
-			}
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	protected void
-	testLinks()
-	{
-		plugin_interface.getDownloadManager().addListener(
-			new DownloadManagerListener()
-			{
-				public void
-				downloadAdded(
-					Download	download )
-				{
-					DiskManagerFileInfo[]	info = download.getDiskManagerFileInfo();
-					
-					for (int i=0;i<info.length;i++){
-						
-						info[i].setLink( new File( "C:\\temp" ));
-					}
-				}
-				
-				public void
-				downloadRemoved(
-					Download	download )
-				{
-					
-				}
-			});
-	}
-	
-	protected void
-	testDDB()
-	{
-		try{
-			DistributedDatabase	db = plugin_interface.getDistributedDatabase();
-			
-			DistributedDatabaseKey	key = db.createKey( new byte[]{ 4,7,1,2,5,8 });
-
-			boolean	do_write	= false;
-			
-			if ( do_write ){
-				
-				DistributedDatabaseValue[] values = new DistributedDatabaseValue[500];
-				
-				for (int i=0;i<values.length;i++){
-					
-					byte[]	val = new byte[20];
-					
-					Arrays.fill( val, (byte)i );
-					
-					values[i] = db.createValue( val );
-				}
-				
-				
-				db.write(
-					new DistributedDatabaseListener()
-					{
-						public void
-						event(
-							DistributedDatabaseEvent		event )
-						{
-							System.out.println( "Event:" + event.getType());
-							
-							if ( event.getType() == DistributedDatabaseEvent.ET_VALUE_WRITTEN ){
-								
-								try{
-									System.out.println( 
-											"    write - key = " + 
-											ByteFormatter.encodeString((byte[])event.getKey().getKey()) + 
-											", val = " + ByteFormatter.encodeString((byte[]) event.getValue().getValue(byte[].class)));
-									
-								}catch( Throwable e ){
-									
-									e.printStackTrace();
-								}
-							}
-						}
-					},
-					key,
-					values );
-			}else{
-				
-				db.read(
-						new DistributedDatabaseListener()
-						{
-							public void
-							event(
-								DistributedDatabaseEvent		event )
-							{
-								System.out.println( "Event:" + event.getType());
-								
-								if ( event.getType() == DistributedDatabaseEvent.ET_VALUE_READ ){
-									
-									try{
-										System.out.println( 
-												"    read - key = " + 
-												ByteFormatter.encodeString((byte[])event.getKey().getKey()) + 
-												", val = " + ByteFormatter.encodeString((byte[]) event.getValue().getValue(byte[].class)));
-										
-									}catch( Throwable e ){
-										
-										e.printStackTrace();
-									}
-								}
-							}
-						},
-						key,
-						60000 );			
-			}
-			
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	protected void
-	taTest()
-	{
-		try{
-			
-			final TorrentAttribute ta = plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_CATEGORY);
-			
-			ta.addTorrentAttributeListener(
-				new TorrentAttributeListener()
-				{
-					public void
-					event(
-						TorrentAttributeEvent	ev )
-					{
-						System.out.println( "ev: " + ev.getType() + ", " + ev.getData());
-						
-						if ( ev.getType() == TorrentAttributeEvent.ET_ATTRIBUTE_VALUE_ADDED ){
-							
-							if ( "plop".equals( ev.getData())){
-								
-								ta.removeDefinedValue( "plop" );
-							}
-						}
-					}
-				});
-			
-			ta.addDefinedValue( "wibble" );
-					
-			
-			plugin_interface.getDownloadManager().addListener(
-				new DownloadManagerListener()
-				{
-					public void
-					downloadAdded(
-						Download	download )
-					{
-						try{
-							download.setAttribute( ta, "wibble" );
-							
-						}catch( Throwable e ){
-							
-							e.printStackTrace();
-						}
-					}
-					
-					public void
-					downloadRemoved(
-						Download	download )
-					{
-						
-					}
-				});
-				
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		System.setProperty( "azureus.dynamic.plugins", "org.gudy.azureus2.pluginsimpl.local.test.Test" );
-		
-		org.gudy.azureus2.ui.swt.Main.main( args );
-	}
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentAttributeCategoryImpl.java b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentAttributeCategoryImpl.java
index 7f019d2..e0c1ef8 100644
--- a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentAttributeCategoryImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentAttributeCategoryImpl.java
@@ -74,6 +74,9 @@ public class TorrentAttributeCategoryImpl extends BaseTorrentAttributeImpl {
 							TorrentAttributeCategoryImpl.this.notifyListeners(ev);
 					}
 						
+					public void categoryChanged(Category category) {	
+					}
+					
 					public void
 					categoryRemoved(
 						final Category category )
diff --git a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentDownloaderImpl.java b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentDownloaderImpl.java
index b07bc6b..377bf1b 100644
--- a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentDownloaderImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentDownloaderImpl.java
@@ -44,7 +44,7 @@ TorrentDownloaderImpl
 	private static final LogIDs LOGID = LogIDs.PLUGIN;
 	protected TorrentManagerImpl		manager;
 	protected URL						url;
-	protected ResourceDownloader		downloader;
+	protected ResourceDownloader		_downloader;
 	
 	protected boolean					encoding_requested;
 	protected String					requested_encoding;
@@ -58,7 +58,7 @@ TorrentDownloaderImpl
 		manager		= _manager;
 		url			= _url;
 		
-		downloader = ResourceDownloaderFactoryImpl.getSingleton().create( url );
+		_downloader = ResourceDownloaderFactoryImpl.getSingleton().create( url );
 	}
 	
 	protected
@@ -79,9 +79,9 @@ TorrentDownloaderImpl
 		
 		set_encoding	= true;
 		
-		downloader = ResourceDownloaderFactoryImpl.getSingleton().create( url, _user_name, _password );
+		_downloader = ResourceDownloaderFactoryImpl.getSingleton().create( url, _user_name, _password );
 		
-		downloader.addListener(new ResourceDownloaderAdapter() {
+		_downloader.addListener(new ResourceDownloaderAdapter() {
 			public void reportActivity(ResourceDownloader downloader, String activity) {
 				if (Logger.isEnabled())
 					Logger.log(new LogEvent(LOGID, "TorrentDownloader:" + activity));
@@ -95,6 +95,27 @@ TorrentDownloaderImpl
 	
 		throws TorrentException
 	{
+		try{
+			return( downloadSupport( _downloader ));
+			
+		}catch( TorrentException e ){
+			
+			ResourceDownloader rd = _downloader.getClone();
+			
+				// try with referer
+			
+			UrlUtils.setBrowserHeaders( rd, url.toExternalForm());
+			
+			return( downloadSupport( rd ));
+		}
+	}
+	
+	private Torrent
+	downloadSupport(
+		ResourceDownloader downloader )
+	
+		throws TorrentException
+	{
 		InputStream	is = null;
 		
 		try{
diff --git a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentImpl.java b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentImpl.java
index 7d5fb7f..3b7420c 100644
--- a/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/torrent/TorrentImpl.java
@@ -78,7 +78,8 @@ TorrentImpl
 	public String
 	getName()
 	{
-		String	name = decode( torrent.getName());
+		String utf8Name = torrent.getUTF8Name();
+		String	name = utf8Name == null ? decode( torrent.getName()) : utf8Name;
 		
 		name = FileUtil.convertOSSpecificChars( name, false );
 
diff --git a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerImpl.java b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerImpl.java
index ebbd2c2..28bb1a6 100644
--- a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerImpl.java
@@ -51,7 +51,7 @@ TrackerImpl
 	
 	private TRHost		host;
 	
-	private List	auth_listeners	= new ArrayList();
+	private List<TrackerAuthenticationListener>	auth_listeners	= new ArrayList<TrackerAuthenticationListener>();
 	
 	
 	public static Tracker
@@ -112,6 +112,12 @@ TrackerImpl
 		return( res );
 	}
 
+	public InetAddress
+	getBindIP()
+	{
+		return( host.getBindIP());
+	}
+	
 	public TrackerTorrent
 	host(
 		Torrent		_torrent,
@@ -304,6 +310,7 @@ TrackerImpl
 	
 	public boolean
 	authenticate(
+		String		headers,
 		URL			resource,
 		String		user,
 		String		password )
@@ -311,7 +318,18 @@ TrackerImpl
 		for (int i=0;i<auth_listeners.size();i++){
 			
 			try{
-				boolean res = ((TrackerAuthenticationListener)auth_listeners.get(i)).authenticate( resource, user, password );
+				TrackerAuthenticationListener listener = auth_listeners.get(i);
+				
+				boolean res;
+				
+				if ( listener instanceof TrackerAuthenticationAdapter ){
+					
+					res = ((TrackerAuthenticationAdapter)listener).authenticate( headers, resource, user, password );
+					
+				}else{
+					
+					res = listener.authenticate( resource, user, password );
+				}
 				
 				if ( res ){
 					
diff --git a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebContextImpl.java b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebContextImpl.java
index 7dfaaa0..3483f11 100644
--- a/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebContextImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/tracker/TrackerWebContextImpl.java
@@ -43,7 +43,7 @@ TrackerWebContextImpl
 {
 	protected TRTrackerServer		server;
 	
-	protected List					auth_listeners	= new ArrayList();
+	protected List<TrackerAuthenticationListener>			auth_listeners	= new ArrayList<TrackerAuthenticationListener>();
 	
 	public 
 	TrackerWebContextImpl(
@@ -115,8 +115,15 @@ TrackerWebContextImpl
 		}
 	}
 	
+	public InetAddress 
+	getBindIP() 
+	{
+		return( server.getBindIP());
+	}
+	
 	public boolean
 	authenticate(
+		String		headers,
 		URL			resource,
 		String		user,
 		String		password )
@@ -124,7 +131,18 @@ TrackerWebContextImpl
 		for (int i=0;i<auth_listeners.size();i++){
 			
 			try{
-				boolean res = ((TrackerAuthenticationListener)auth_listeners.get(i)).authenticate( resource, user, password );
+				TrackerAuthenticationListener listener = auth_listeners.get(i);
+				
+				boolean res;
+				
+				if ( listener instanceof TrackerAuthenticationAdapter ){
+					
+					res = ((TrackerAuthenticationAdapter)listener).authenticate( headers, resource, user, password );
+					
+				}else{
+					
+					res = listener.authenticate( resource, user, password );
+				}
 				
 				if ( res ){
 					
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java b/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
index cd9cc21..2af69c0 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/AbstractUIInputReceiver.java
@@ -123,6 +123,10 @@ public abstract class AbstractUIInputReceiver implements UIInputReceiver {
 		this.prompted = true;
 	}
 	
+	protected boolean isResultRecorded() {
+		return result_recorded;
+	}
+	
 	public final void prompt(UIInputReceiverListener receiver_listener) {
 		assertPrePrompt();
 		this.receiver_listener = receiver_listener;
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/SWT/GraphicSWTImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/SWT/GraphicSWTImpl.java
deleted file mode 100644
index 9d37110..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/ui/SWT/GraphicSWTImpl.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Created on 2004/May/23
- * Created by TuxPaper
- * 
- * 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.pluginsimpl.local.ui.SWT;
-
-import org.gudy.azureus2.plugins.ui.SWT.GraphicSWT;
-import org.eclipse.swt.graphics.Image;
-
-/** An SWT image to be used in Azureus
- *
- * @see SWTManager.createGraphic
- */
-public class GraphicSWTImpl implements GraphicSWT {
-  Image img;
-  
-  public GraphicSWTImpl(Image newImage) {
-    img = newImage;
-  }
-
-  public Image getImage() {
-    return img;
-  }
-
-  public boolean setImage(Image newImage) {
-    if (img == newImage)
-      return false;
-    img = newImage;
-    return true;
-  }
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/SWT/SWTManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/SWT/SWTManagerImpl.java
deleted file mode 100644
index 6b16cd1..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/ui/SWT/SWTManagerImpl.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Created on 2004/May/14
- *
- * 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 org.gudy.azureus2.pluginsimpl.local.ui.SWT;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.util.AEMonitor;
-import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
-import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
-
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-
-import org.gudy.azureus2.plugins.PluginView;
-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.SWT.GraphicSWT;
-import org.gudy.azureus2.plugins.ui.SWT.SWTManager;
-import org.gudy.azureus2.plugins.ui.model.PluginViewModel;
-
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.pluginsimpl.local.deprecate.PluginDeprecation;
-
-/*
- * @deprecated
- */
-
-public class SWTManagerImpl
-	implements SWTManager
-{	
-	protected static SWTManagerImpl singleton;
-	
-	private static AEMonitor	class_mon	= new AEMonitor( "SWTManager" );
-
-	public static SWTManagerImpl getSingleton() {
-		try{
-			class_mon.enter();
-		
-			if (singleton == null)
-				singleton = new SWTManagerImpl();
-			return singleton;
-		}finally{
-			
-			class_mon.exit();
-		}
-	}
-  
-  public Display getDisplay() {
-  	SWTThread instance = SWTThread.getInstance();
-  	if (instance == null)
-  		return null;
-    return instance.getDisplay();
-  }
-  
-  public GraphicSWT createGraphic(Image img) {
-    return new GraphicSWTImpl(img);
-  }
-  
-
-	public void addView(final PluginView view, final boolean bAutoOpen) {
-		try {
-			
-			UIManager ui_manager = PluginInitializer.getDefaultInterface().getUIManager();
-
-			ui_manager.addUIListener(new UIManagerListener() {
-				public void UIAttached(UIInstance instance) {
-					if (instance instanceof UISWTInstance) {
-						if (view instanceof PluginViewWrapper) {
-
-							// legacy support for RSSImport plugin
-							// model already registered, no need to do anything as UI will pick it up
-
-						} else {
-							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-							if (uiFunctions instanceof UIFunctionsSWT) {
-								((UIFunctionsSWT)uiFunctions).addPluginView(view);
-
-								if (bAutoOpen) {
-									((UIFunctionsSWT)uiFunctions).openPluginView(view);
-								}
-							}
-						}
-					}
-				}
-
-				public void UIDetached(UIInstance instance) {
-				}
-			});
-
-		} catch (Throwable e) {
-			// SWT not available prolly
-		}
-	} 
-
-  	public void 
-  	addView(
-  		PluginView view)
-  	{
-  		addView(view, false);
-  	} 
-
-	public PluginView
-	createPluginView(
-		PluginViewModel	model )
-	{	
-		PluginDeprecation.call("createPluginView", model.getName());
-		return( new PluginViewWrapper(model));
-	
-	}
-	
-	protected class
-	PluginViewWrapper
-		extends PluginView
-	{
-		private	PluginViewModel		model;
-		
-		protected
-		PluginViewWrapper(
-			PluginViewModel	_model )
-		{
-			model	= _model;
-		}
-		
-		public String 
-		getPluginViewName()
-		{
-			return( model.getName());
-		}
-	}
-	
-  /* 
-   * Not working due to class loader being different between plugins and
-   * main program.
-   * 
-  public boolean loadImage(String resource,String name) {
-    try {
-      ImageRepository.loadImage(getDisplay(),resource,name);
-      return true;
-    } catch(Exception e) {
-      e.printStackTrace();
-      return false;
-    }
-  }
-  
-  public Image getImage(String name) {
-    return ImageRepository.getImage(name);
-  }*/
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/UIManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/UIManagerImpl.java
index 9b354af..a0b2dea 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/UIManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/UIManagerImpl.java
@@ -31,30 +31,28 @@ import java.util.List;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.pluginsimpl.local.deprecate.PluginDeprecation;
-import org.gudy.azureus2.pluginsimpl.local.ui.SWT.SWTManagerImpl;
-import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginConfigModelImpl;
-import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginViewModelImpl;
-import org.gudy.azureus2.pluginsimpl.local.ui.menus.MenuManagerImpl;
-import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableManagerImpl;
-
 import org.gudy.azureus2.plugins.PluginConfig;
 import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginView;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
 import org.gudy.azureus2.plugins.torrent.Torrent;
 import org.gudy.azureus2.plugins.ui.*;
-import org.gudy.azureus2.plugins.ui.menus.MenuManager;
-import org.gudy.azureus2.plugins.ui.SWT.SWTManager;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.ui.menus.MenuManager;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.plugins.ui.model.PluginConfigModel;
-import org.gudy.azureus2.plugins.ui.model.PluginViewModel;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.pluginsimpl.local.ui.menus.MenuManagerImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginConfigModelImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginViewModelImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableManagerImpl;
+import org.gudy.azureus2.ui.common.UIInstanceBase;
 
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.ui.IUIIntializer;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentListener;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 
 
 
@@ -72,8 +70,8 @@ UIManagerImpl
 	
 	protected static boolean				initialisation_complete;
 	
-	protected static CopyOnWriteList		ui_listeners		= new CopyOnWriteList();
-	protected static CopyOnWriteList		ui_event_listeners	= new CopyOnWriteList();
+	protected static CopyOnWriteList<Object[]>		ui_listeners		= new CopyOnWriteList<Object[]>();
+	protected static CopyOnWriteList				ui_event_listeners	= new CopyOnWriteList();
 	
 	protected static List<UIInstanceFactory>		ui_factories		= new ArrayList<UIInstanceFactory>();
 	protected static List<UIManagerEventAdapter>	ui_event_history	= new ArrayList<UIManagerEventAdapter>();
@@ -87,6 +85,8 @@ UIManagerImpl
 	
 	protected TableManager			table_manager;
 	protected MenuManager           menu_manager;
+
+	private static ArrayList<UIDataSourceListener> listDSListeners;
 	
 	public
 	UIManagerImpl(
@@ -109,29 +109,6 @@ UIManagerImpl
 	}
 	
 	public BasicPluginViewModel
-	getBasicPluginViewModel(
-		String			name )
-	{
-		// grrr, RSSImport plugin directly uses this method
-		
-		return( createBasicPluginViewModel( name ));
-		// throw( new RuntimeException( "Deprecated method - use createBasicPluginViewModel"));
-	}
-	
-	public PluginView
-	createPluginView(
-		PluginViewModel	model )
-	{
-		try{
-			return( SWTManagerImpl.getSingleton().createPluginView( model ));
-	
-		}catch( Throwable e ){
-			e.printStackTrace();
-			return( null );
-		}
-	}
-	
-	public BasicPluginViewModel
 	createBasicPluginViewModel(
 		String			name )
 	{
@@ -246,14 +223,18 @@ UIManagerImpl
 	  return menu_manager;
   }
 
-  public SWTManager getSWTManager() {
-	  PluginDeprecation.call("getSWTManager", pi.getPluginID());
-    return SWTManagerImpl.getSingleton();
-  }
-  
   	public static void
   	initialisationComplete()
   	{
+  		SelectedContentManager.addCurrentlySelectedContentListener(new SelectedContentListener() {
+  			public void currentlySelectedContentChanged(
+  					ISelectedContent[] currentContent, String viewID) {
+  				triggerDataSourceListeners(SelectedContentManager.convertSelectedContentToObject(currentContent));
+  			}
+  		});
+
+  		List<Object[]> to_fire = new ArrayList<Object[]>();
+  		
   		try{
   			class_mon.enter();
   			
@@ -261,38 +242,53 @@ UIManagerImpl
   			
 			for (int j=0;j<ui_factories.size();j++){
 
-				UIInstanceFactory	instance = (UIInstanceFactory)ui_factories.get(j);
+				UIInstanceFactory	factory = (UIInstanceFactory)ui_factories.get(j);
 				
-  				Iterator it = ui_listeners.iterator();
+  				Iterator<Object[]> it = ui_listeners.iterator();
 
   				while( it.hasNext()){
   					
- 					Object[]	entry = (Object[])it.next();
+ 					Object[]	entry = it.next();
   					
-  					try{
-  						((UIManagerListener)entry[0]).UIAttached( 
-  								instance.getInstance((PluginInterface)entry[1]) );
-						
-					}catch( Throwable e ){
-						
-						Debug.printStackTrace(e);
-					}
+ 					List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
+ 					
+ 					if ( !fired.contains( factory )){
+ 						
+ 						fired.add( factory );
+ 						
+ 						to_fire.add( new Object[]{ entry[0], factory.getInstance((PluginInterface)entry[1])});
+ 					}
 				}  				
 			}
   		}finally{
   			
   			class_mon.exit();
   		}
+  		
+  		for ( Object[] entry: to_fire ){
+  			
+			try{
+				((UIManagerListener)entry[0]).UIAttached( (UIInstance)entry[1] );
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+  		}
   	}
   	
+  	
   	public void attachUI(UIInstanceFactory factory) throws UIException {
   		attachUI(factory, null);
   	}
   
 	public void
 	attachUI(
-		UIInstanceFactory		factory, IUIIntializer init)
+		UIInstanceFactory		factory, 
+		IUIIntializer 			init )
 	{
+ 		List<Object[]> to_fire = new ArrayList<Object[]>();
+
 		try{
   			class_mon.enter();
   			
@@ -300,102 +296,131 @@ UIManagerImpl
   			
   			if ( initialisation_complete ){
   				
-  				Iterator it = ui_listeners.iterator();
+  				Iterator<Object[]> it = ui_listeners.iterator();
 
   				while( it.hasNext()){
   					
   					Object[]	entry = (Object[])it.next();
   					
-  					PluginInterface pi = (PluginInterface)entry[1];
-  					
-  					String name = pi.getPluginName();
-  					
-  					if(init != null)
-  					{
-  						init.reportCurrentTask(MessageText.getString("splash.plugin.UIinit",new String[] {name}));
-  						init.increaseProgress();
-  					}
-  					
-  					try{
-  						((UIManagerListener)entry[0]).UIAttached(factory.getInstance(pi));
-  						
-  					}catch( Throwable e ){
-  						
-  						Debug.printStackTrace(e);
-  					}
+					List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
+
+					fired.add( factory );
+						
+					to_fire.add( new Object[]{ entry[0], entry[1], factory.getInstance((PluginInterface)entry[1])});
   				}
   			}
   		}finally{
   			
   			class_mon.exit();
   		}		
+  		
+  		for ( Object[] entry: to_fire ){
+
+			PluginInterface pi = (PluginInterface)entry[1];
+				
+			String name = pi.getPluginName();
+				
+			if ( init != null ){
+					
+				init.reportCurrentTask(MessageText.getString("splash.plugin.UIinit",new String[] {name}));
+					
+				init.increaseProgress();
+			}
+				
+			try{
+				((UIManagerListener)entry[0]).UIAttached( (UIInstance)entry[2]);
+					
+			}catch( Throwable e ){
+					
+				Debug.printStackTrace(e);
+			}
+  		}
 	}
 	
 	public void
 	detachUI(
-		UIInstanceFactory		instance )
+		UIInstanceFactory		factory )
 	
 		throws UIException
 	{
+		factory.detach();
+
+ 		List<Object[]> to_fire = new ArrayList<Object[]>();
+
 		try{
   			class_mon.enter();
-  			
-  			instance.detach();
-  			
-  			ui_factories.remove( instance );
+  			  			
+  			ui_factories.remove( factory );
   			
   			if ( initialisation_complete ){
   				
-  				Iterator it = ui_listeners.iterator();
+  				Iterator<Object[]> it = ui_listeners.iterator();
 
   				while( it.hasNext()){
   					
  					Object[]	entry = (Object[])it.next();
   					
-  					try{
-   						((UIManagerListener)entry[0]).UIDetached( 
-   								instance.getInstance((PluginInterface)entry[1]));
-  						
-  					}catch( Throwable e ){
-  						
-  						Debug.printStackTrace(e);
-  					}
+					List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
+
+					fired.remove( factory );
+					
+ 					to_fire.add( new Object[]{ entry[0], factory.getInstance((PluginInterface)entry[1])});
   				}
   			}
   		}finally{
   			
   			class_mon.exit();
   		}		
+  		
+  		for ( Object[] entry: to_fire ){
+
+			try{
+				((UIManagerListener)entry[0]).UIDetached((UIInstance)entry[1]);
+					
+			}catch( Throwable e ){
+					
+				Debug.printStackTrace(e);
+			}
+  		}
 	}
 	
   	public void
   	addUIListener(
   		UIManagerListener listener )
   	{
+ 		List<UIInstance> to_fire = new ArrayList<UIInstance>();
+
 		try{
   			class_mon.enter();
   			
-  			ui_listeners.add( new Object[]{ listener, pi });
+  			List<UIInstanceFactory> fired = new ArrayList<UIInstanceFactory>();
+  			
+  			ui_listeners.add( new Object[]{ listener, pi, fired });
   			
  			if ( initialisation_complete ){
   				
   				for (int i=0;i<ui_factories.size();i++){
   					
-  					UIInstanceFactory	instance = (UIInstanceFactory)ui_factories.get(i);
-
-  					try{  						
-  						listener.UIAttached( instance.getInstance( pi ));
-  						
-  					}catch( Throwable e ){
-  						
-  						Debug.printStackTrace(e);
-  					}
+  					UIInstanceFactory	factory = (UIInstanceFactory)ui_factories.get(i);
+
+  					to_fire.add( factory.getInstance( pi ));
   				}
   			}
   		}finally{
   			
   			class_mon.exit();
   		} 		
+		
+  		for ( UIInstance instance: to_fire ){
+  			
+			try{  						
+				listener.UIAttached( instance );
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+  		}
   	}
   	
  	public void
@@ -693,9 +718,69 @@ UIManagerImpl
 					ev_it.remove();
 				}				
 			}
-  		}finally{
+			
+			for (UIInstanceFactory uif : ui_factories) {
+				UIInstance instance = uif.getInstance(pi);
+				if (instance instanceof UIInstanceBase) {
+					UIInstanceBase instanceBase = (UIInstanceBase) instance;
+					instanceBase.unload(pi);
+				}
+			}
+  	}finally{
   			
-  			class_mon.exit();
-  		}	
+  		class_mon.exit();
+  	}	
+	}
+	
+	public void addDataSourceListener(UIDataSourceListener l, boolean triggerNow) {
+		class_mon.enter();
+		try {
+			if (listDSListeners == null) {
+				listDSListeners = new ArrayList<UIDataSourceListener>();
+			}
+			listDSListeners.add(l);
+		} finally {
+			class_mon.exit();
+		}
+		if (triggerNow) {
+			try {
+				ISelectedContent[] contents = SelectedContentManager.getCurrentlySelectedContent();
+				l.dataSourceChanged(SelectedContentManager.convertSelectedContentToObject(contents));
+			} catch (Throwable t) {
+				Debug.out(t);
+			}
+		}
+	}
+	
+	public void removeDataSourceListener(UIDataSourceListener l) {
+		class_mon.enter();
+		try {
+			if (listDSListeners == null) {
+				return;
+			}
+			listDSListeners.remove(l);
+		} finally {
+			class_mon.exit();
+		}
+	}
+	
+	private static void triggerDataSourceListeners(Object ds) {
+		UIDataSourceListener[] listeners;
+		class_mon.enter();
+		try {
+			if (listDSListeners == null) {
+				return;
+			}
+			listeners = listDSListeners.toArray(new UIDataSourceListener[0]);
+		} finally {
+			class_mon.exit();
+		}
+		for (UIDataSourceListener l : listeners) {
+			try {
+				l.dataSourceChanged(ds);
+			} catch (Throwable t) {
+				Debug.out(t);
+			}
+		}
 	}
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionHolder.java b/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionHolder.java
new file mode 100644
index 0000000..d703994
--- /dev/null
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionHolder.java
@@ -0,0 +1,77 @@
+/*
+ * Created on Oct 19, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.pluginsimpl.local.ui.config;
+
+import java.lang.ref.WeakReference;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+
+public class 
+ConfigSectionHolder
+	implements ConfigSection
+{
+	private ConfigSection					section;
+	private WeakReference<PluginInterface>	pi;
+	protected
+	ConfigSectionHolder(
+		ConfigSection		_section,
+		PluginInterface		_pi )
+	{
+		section		= _section;
+		
+		if ( _pi != null ){
+			
+			pi = new WeakReference<PluginInterface>( _pi );
+		}
+	}
+	
+	public String 
+	configSectionGetParentSection()
+	{
+		return( section.configSectionGetParentSection());
+	}
+
+	public String 
+	configSectionGetName()
+	{
+		return( section.configSectionGetName());	
+	}
+
+	public void 
+	configSectionSave()
+	{
+		section.configSectionSave();
+	}
+
+	public void 
+	configSectionDelete()
+	{
+		section.configSectionDelete();
+	}
+	
+	public PluginInterface
+	getPluginInterface()
+	{
+		return( pi==null?null:pi.get());
+	}
+}
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionRepository.java b/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionRepository.java
index fd3c0bb..271f6ea 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionRepository.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/config/ConfigSectionRepository.java
@@ -21,8 +21,9 @@
 
 package org.gudy.azureus2.pluginsimpl.local.ui.config;
 
-import java.util.ArrayList;
+import java.util.*;
 
+import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.core3.util.*;
 
@@ -31,10 +32,10 @@ public class ConfigSectionRepository {
   private static ConfigSectionRepository 	instance;
   private static AEMonitor					class_mon	= new AEMonitor( "ConfigSectionRepository:class");
   
-  private ArrayList items;
+  private Map<ConfigSection,ConfigSectionHolder> items;
 
   private ConfigSectionRepository() {
-   items = new ArrayList();
+   items = new LinkedHashMap<ConfigSection, ConfigSectionHolder>();
   }
 
   public static ConfigSectionRepository getInstance() {
@@ -50,11 +51,11 @@ public class ConfigSectionRepository {
   	}
   }
 
-  public void addConfigSection(ConfigSection item) {
+  public void addConfigSection(ConfigSection item, PluginInterface pi ) {
   	try{
   		class_mon.enter();
   		
-  		items.add(item);
+  		items.put(item, new ConfigSectionHolder( item, pi ));
   		
     }finally{
     	
@@ -74,11 +75,23 @@ public class ConfigSectionRepository {
 	    }
 	  }
   
-  public ArrayList getList() {
+  public ArrayList<ConfigSection> getList() {
+	 	try{
+	  		class_mon.enter();
+	   
+	  		return (new ArrayList<ConfigSection>( items.keySet() ));
+	  		
+	 	  }finally{
+	    	
+	    	class_mon.exit();
+	    } 		
+	  }
+  
+  public ArrayList<ConfigSectionHolder> getHolderList() {
  	try{
   		class_mon.enter();
    
-  		return (ArrayList)items.clone();
+  		return (new ArrayList<ConfigSectionHolder>( items.values() ));
   		
  	  }finally{
     	
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/config/PasswordParameterImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/config/PasswordParameterImpl.java
index ab275e2..a63c540 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/config/PasswordParameterImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/config/PasswordParameterImpl.java
@@ -45,48 +45,50 @@ PasswordParameterImpl
 	public 
 	PasswordParameterImpl(
 		PluginConfigImpl 	config,
-		String 			key, 
-		String 			label,
-		int				_encoding_type,
-		byte[] 			_defaultValue)
+		String 				key, 
+		String 				label,
+		int					_encoding_type,
+		byte[] 				_default_value)
 	{ 
 		super(config,key, label);
 		
-		if ( _defaultValue == null ){
+		encoding_type	= _encoding_type;
+		
+		if ( _default_value == null ){
 			
 			defaultValue = new byte[0];
 			
 		}else{
 			
-			defaultValue = _defaultValue;
-
-			if ( _encoding_type == ET_SHA1 ){
-				
-		        SHA1Hasher hasher = new SHA1Hasher();
-		        
-		        defaultValue = hasher.calculateHash(defaultValue);
-		        
-			}else if ( _encoding_type == ET_MD5 ){
-				
-				try{
-					defaultValue = MessageDigest.getInstance( "md5").digest( defaultValue );
-					
-				}catch( Throwable e ){
-					
-					Debug.printStackTrace(e);
-				}
-			}
+			defaultValue = encode( _default_value );
 		}
 	
 		config.notifyParamExists(getKey());
+		
 		COConfigurationManager.setByteDefault( getKey(), defaultValue );
-
-		encoding_type	= _encoding_type;
 	}
 	
 	public byte[] getDefaultValue()
 	{
-		return defaultValue;
+		return( defaultValue );
+	}
+	
+	public void
+	setValue(
+		String	plain_password )
+	{
+		byte[] encoded;
+		
+		if ( plain_password == null || plain_password.length() == 0){
+		
+			encoded = new byte[0];
+			
+		}else{
+			
+			encoded = encode( plain_password );
+		}
+		
+		config.setUnsafeByteParameter( getKey(), encoded );
 	}
 	
 	public int
@@ -100,4 +102,46 @@ PasswordParameterImpl
 	{
 		return config.getUnsafeByteParameter(getKey(), getDefaultValue());
 	}
+	
+	protected byte[]
+   	encode(
+   		String		str )
+   	{
+		// bit of a mess here as all other than md5 use default char set whereas md5 uses utf-8
+		
+		try{
+		
+			return( encode( encoding_type == ET_MD5?str.getBytes( "UTF-8" ):str.getBytes()));
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			return( null );
+		}
+   	}
+	
+	protected byte[]
+	encode(
+		byte[]		bytes )
+	{
+		if ( encoding_type == ET_SHA1 ){
+			
+	        SHA1Hasher hasher = new SHA1Hasher();
+	        
+	        return( hasher.calculateHash( bytes ));
+	        
+		}else if ( encoding_type == ET_MD5 ){
+			
+			try{
+				return( MessageDigest.getInstance( "md5" ).digest( bytes ));
+				
+			}catch( Throwable e ){
+				
+				Debug.printStackTrace(e);
+			}
+		}
+		
+		return( bytes );
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/menus/MenuItemImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/menus/MenuItemImpl.java
index 3e656dc..9c28ed1 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/menus/MenuItemImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/menus/MenuItemImpl.java
@@ -152,15 +152,18 @@ public class MenuItemImpl implements MenuItem {
 		fill_listeners.remove(listener);
 	}
 	
-	  // Currently used by TableView (and other places).
-	  public void invokeListenersMulti(Object[] rows) {
-		  // We invoke the multi listeners first...
-		  invokeListenersOnList(this.m_listeners, rows);
-		  if (rows == null) {invokeListenersSingle(null); return;}
-		  for (int i=0; i<rows.length; i++) {
-			  invokeListenersSingle(rows[i]);
-		  }
-	  }
+	// Currently used by TableView (and other places).
+	public void invokeListenersMulti(Object[] rows) {
+		// We invoke the multi listeners first...
+		invokeListenersOnList(this.m_listeners, rows);
+		if (rows == null || rows.length == 0) {
+			invokeListenersSingle(null);
+			return;
+		}
+		for (int i = 0; i < rows.length; i++) {
+			invokeListenersSingle(rows[i]);
+		}
+	}
 	 
 	  public void addMultiListener(MenuItemListener l) {
 		  m_listeners.add(l);
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
index 4fc580e..5d803be 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginConfigModelImpl.java
@@ -31,6 +31,7 @@ import java.util.*;
 
 
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.plugins.ui.config.ActionParameter;
 import org.gudy.azureus2.plugins.ui.config.InfoParameter;
 import org.gudy.azureus2.plugins.ui.config.LabelParameter;
@@ -74,6 +75,10 @@ BasicPluginConfigModelImpl
 
 		key_prefix		= pi.getPluginconfig().getPluginConfigKeyPrefix();
 		configobj       = (PluginConfigImpl)pi.getPluginconfig();
+		
+		String version = pi.getPluginVersion();
+		
+		addLabelParameter2( "!" + MessageText.getString( "ConfigView.pluginlist.column.version" ) + ": " + (version==null?"<local>":version) + "!" );
 	}
 
 	public String
diff --git a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginViewModelImpl.java b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginViewModelImpl.java
index 7f89114..9cef1ae 100644
--- a/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginViewModelImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/ui/model/BasicPluginViewModelImpl.java
@@ -31,6 +31,7 @@ import java.io.PrintWriter;
 import java.io.StringWriter;
 
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
 import org.gudy.azureus2.plugins.logging.LoggerChannelListener;
 import org.gudy.azureus2.plugins.ui.model.*;
@@ -84,6 +85,12 @@ BasicPluginViewModelImpl
 		return( activity );
 	}
 	
+	public PluginInterface 
+	getPluginInterface() 
+	{
+		return( ui_manager.getPluginInterface());
+	}
+	
 	public UITextArea
 	getLogArea()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/update/Test.java b/org/gudy/azureus2/pluginsimpl/local/update/Test.java
deleted file mode 100644
index f3e404d..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/update/Test.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Created on 17-Dec-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 org.gudy.azureus2.pluginsimpl.local.update;
-
-import java.util.Properties;
-import java.io.*;
-
-import org.gudy.azureus2.core3.util.AEThread;
-import org.gudy.azureus2.plugins.Plugin;
-import org.gudy.azureus2.plugins.PluginException;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginListener;
-import org.gudy.azureus2.plugins.PluginManager;
-
-import org.gudy.azureus2.plugins.update.UpdateInstaller;
-import org.gudy.azureus2.plugins.update.UpdateManager;
-
-/**
- * @author parg
- *
- */
-public class 
-Test
-implements Plugin, PluginListener
-{
-	protected PluginManager		manager;
-	
-	public
-	Test()
-	{
-		// constructor for Plugin
-	}
-	
-	public 
-	Test(
-		boolean	ignore )
-	{
-		Properties props = new Properties();
-		
-		props.put( PluginManager.PR_MULTI_INSTANCE, "true" );
-		
-		PluginManager.registerPlugin( Test.class );
-	
-		PluginManager.startAzureus( PluginManager.UI_SWT, props );
-	}
-	
-	public void 
-	initialize(
-		PluginInterface pi )
-	  
-		throws PluginException
-	{
-		manager	= pi.getPluginManager();
-		
-		pi.addListener( this );
-	}
-	
-	public void
-	initializationComplete()
-	{
-		new AEThread("update tester" )
-		{
-			public void
-			runSupport()
-			{	
-				try{
-	
-					UpdateManager	update_man = manager.getDefaultPluginInterface().getUpdateManager();
-					
-					UpdateInstaller installer = update_man.createInstaller();
-					
-					File	from_file 	= new File( "C:\\temp\\update_from" );
-					File	to_file		= new File( "C:\\temp\\update_to" );
-					
-					PrintWriter pw = new PrintWriter( new FileWriter( from_file ));
-					
-					pw.println( "hello mum");
-					
-					pw.close();
-					
-					to_file.delete();
-					
-					installer.addMoveAction( from_file.toString(), to_file.toString());
-					
-					update_man.applyUpdates( false );
-					
-				}catch( Throwable e ){
-					
-					e.printStackTrace();
-				}
-			}
-		}.start();
-	}
-	
-	public void
-	closedownInitiated()
-	{
-		
-	}
-	
-	public void
-	closedownComplete()
-	{
-		
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		new Test(true);
-	}
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/update/UpdateCheckInstanceImpl.java b/org/gudy/azureus2/pluginsimpl/local/update/UpdateCheckInstanceImpl.java
index 6ad2c37..708b9ea 100644
--- a/org/gudy/azureus2/pluginsimpl/local/update/UpdateCheckInstanceImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/update/UpdateCheckInstanceImpl.java
@@ -40,6 +40,10 @@ UpdateCheckInstanceImpl
 	implements UpdateCheckInstance
 {
 	private static final LogIDs LOGID = LogIDs.CORE;
+	
+	private static UpdateCheckInstanceImpl	active_checker;
+	
+	
 	private List<UpdateCheckInstanceListener>	listeners			= new ArrayList<UpdateCheckInstanceListener>();
 	private List<UpdateImpl>					updates 			= new ArrayList<UpdateImpl>();
 	private List<UpdateManagerDecisionListener>	decision_listeners	= new ArrayList<UpdateManagerDecisionListener>();
@@ -176,6 +180,129 @@ UpdateCheckInstanceImpl
 	public void
 	start()
 	{
+			// only run one at a time - easiest approach is just to use a couple of threads
+			// to backoff + check for completion
+		
+		boolean	run_now;
+				
+		synchronized( UpdateCheckInstanceImpl.class ){
+			
+			if ( active_checker == null ){
+				
+				// System.out.println( "UCI: starting " + getName());
+				
+				active_checker = this;
+				
+				run_now = true;
+				
+				new AEThread2( "UCI:clearer" )
+				{
+					public void
+					run()
+					{
+							// wait until the process completes then clear down the 'active' one
+						
+						while( true ){
+														
+							try{
+								Thread.sleep(1000);
+								
+							}catch( Throwable e ){
+							}
+							
+							if ( isCompleteOrCancelled()){
+								
+								boolean	done = true;
+								
+								if ( completed ){
+									
+									Update[] updates = getUpdates();
+																		
+									for ( Update update: updates ){
+										
+										if ( !( update.isCancelled() || update.isComplete())){
+											
+											done = false;
+											
+											break;
+										}
+									}
+								}
+								
+								if ( done ){
+								
+									try{
+										Thread.sleep( 5000 );
+										
+									}catch( Throwable e ){
+									}
+									
+									// System.out.println( "UCI: done " + getName());
+									
+									synchronized( UpdateCheckInstanceImpl.class ){
+										
+										active_checker = null;
+									}
+									
+									break;
+								}
+							}
+						}	
+					}
+				}.start();
+				
+			}else{
+				
+				run_now = false;
+				
+				// System.out.println( "UCI: waiting " + getName());
+				
+				new AEThread2( "UCI:waiter" )
+				{
+					public void
+					run()
+					{
+							// wait until inactive then re-attempt
+						
+						while( true ){
+														
+							try{
+								Thread.sleep(1000);
+								
+							}catch( Throwable e ){
+							}
+							
+							boolean	retry = false;
+							
+							synchronized( UpdateCheckInstanceImpl.class ){
+								
+								if ( active_checker == null ){
+									
+									retry = true;
+								}
+							}
+							
+							if ( retry ){
+								
+								UpdateCheckInstanceImpl.this.start();
+									
+								break;
+							}
+						}
+					}
+				}.start();
+			}
+		}
+		
+		if ( run_now ){
+			
+			startSupport();
+		}
+	}
+	
+	private void
+	startSupport()
+	{
 		for (int i=0;i<components.length;i++){
 			
 			final UpdateCheckerImpl			checker = checkers[i];
@@ -211,78 +338,120 @@ UpdateCheckInstanceImpl
 					}
 					
 					try{
-						this_mon.enter();
+						boolean	mandatory_failed = false;
 						
-						if ( cancelled ){
+						for (int i=0;i<checkers.length;i++){
 							
-							return;
+							if ( components[i].isMandatory() && checkers[i].getFailed()){
+								
+								mandatory_failed	= true;
+								
+								break;
+							}
 						}
-					
-						completed	= true;
 						
-					}finally{
+						List<UpdateImpl>	target_updates = new ArrayList<UpdateImpl>();
 						
-						this_mon.exit();
-					}
-					
-					boolean	mandatory_failed = false;
-					
-					for (int i=0;i<checkers.length;i++){
+							// if any mandatory checks failed then we can't do any more
 						
-						if ( components[i].isMandatory() && checkers[i].getFailed()){
+						if ( mandatory_failed ){
 							
-							mandatory_failed	= true;
-							
-							break;
-						}
-					}
-					
-					List<UpdateImpl>	target_updates = new ArrayList<UpdateImpl>();
-					
-						// if any mandatory checks failed then we can't do any more
-					
-					if ( mandatory_failed ){
-						
-						if (Logger.isEnabled())
-							Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-										"Dropping all updates as a mandatory update check failed"));
-
-					}else{
-							// If there are any manadatory updates then we just go ahead with them and drop the rest
-						
-						boolean	mandatory_only	= false;
-						
-						for (int i=0;i<updates.size();i++){
+							if (Logger.isEnabled())
+								Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+											"Dropping all updates as a mandatory update check failed"));
+	
+						}else{
+								// If there are any manadatory updates then we just go ahead with them and drop the rest
 							
-							UpdateImpl	update = (UpdateImpl)updates.get(i);
+							boolean	mandatory_only	= false;
 							
-							if ( update.isMandatory()){
+							for (int i=0;i<updates.size();i++){
 								
-								mandatory_only	= true;
+								UpdateImpl	update = (UpdateImpl)updates.get(i);
 								
-								break;
+								if ( update.isMandatory()){
+									
+									mandatory_only	= true;
+									
+									break;
+								}
+							}
+							
+							for (int i=0;i<updates.size();i++){
+								
+								UpdateImpl	update = (UpdateImpl)updates.get(i);
+															
+								if ( update.isMandatory() || !mandatory_only ){
+									
+									target_updates.add( update );
+									
+								}else{
+									if (Logger.isEnabled())
+									  Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+									                          "Dropping update '" + update.getName()
+	                                            + "' as non-mandatory and "
+	                                            + "mandatory updates found"));
+								}
 							}
 						}
+	
+							// maintain order here as we apply updates in the order we
+							// were requested to
 						
-						for (int i=0;i<updates.size();i++){
-							
-							UpdateImpl	update = (UpdateImpl)updates.get(i);
-														
-							if ( update.isMandatory() || !mandatory_only ){
+						Collections.sort( 
+							target_updates,
+							new Comparator<UpdateImpl>()
+							{
+								public int 
+								compare(
+									UpdateImpl o1, UpdateImpl o2)
+								{
+									int i1 = getIndex( o1 );
+									int i2 = getIndex( o2 );
+									
+									return( i1 - i2 );
+								}
 								
-								target_updates.add( update );
+								private int
+								getIndex(
+									UpdateImpl	update )
+								{
+									UpdatableComponentImpl component = update.getComponent();
+									
+									for (int i=0;i<components.length;i++){
+										
+										if ( components[i] == component ){
+											
+											return( i );
+										}
+									}
+									
+									Debug.out( "Missing component!" );
+									
+									return( 0 );
+								}
+							});
+	
+						updates	= target_updates;					
+					
+					}finally{
+						
+						try{
+							this_mon.enter();
+							
+							if ( cancelled ){
 								
-							}else{
-								if (Logger.isEnabled())
-								  Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-								                          "Dropping update '" + update.getName()
-                                            + "' as non-mandatory and "
-                                            + "mandatory updates found"));
+								return;
 							}
+						
+							completed	= true;
+							
+						}finally{
+							
+							this_mon.exit();
 						}
+						
 					}
-
-					updates	= target_updates;
 					
 					for (int i=0;i<listeners.size();i++){
 					
@@ -311,7 +480,7 @@ UpdateCheckInstanceImpl
 			this_mon.enter();
 		
 			UpdateImpl	update = 
-				new UpdateImpl( this, update_name, desc, new_version, 
+				new UpdateImpl( this, comp, update_name, desc, new_version, 
 								downloaders, comp.isMandatory(), restart_required );
 			
 			updates.add( update );
@@ -361,6 +530,19 @@ UpdateCheckInstanceImpl
 		return( manager.createInstaller());
 	}
 	
+	public boolean 
+	isCompleteOrCancelled() 
+	{
+		try{
+			this_mon.enter();
+
+			return( completed || cancelled );
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
 	public void
 	cancel()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/update/UpdateImpl.java b/org/gudy/azureus2/pluginsimpl/local/update/UpdateImpl.java
index 6be4824..3383c7e 100644
--- a/org/gudy/azureus2/pluginsimpl/local/update/UpdateImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/update/UpdateImpl.java
@@ -42,6 +42,7 @@ UpdateImpl
 	implements Update
 {
 	private UpdateCheckInstanceImpl	instance;
+	private UpdatableComponentImpl	component;
 	private String					name;
 	private String[]				description;
 	private String					relative_url_base	= "";
@@ -56,10 +57,12 @@ UpdateImpl
 	private CopyOnWriteList			listeners = new CopyOnWriteList();
 	private volatile boolean		cancelled;
 	private volatile boolean		complete;
+	private volatile boolean		succeeded;
 	
 	protected
 	UpdateImpl(
 		UpdateCheckInstanceImpl	_instance,
+		UpdatableComponentImpl	_component,
 		String					_name,
 		String[]				_desc,
 		String					_new_version,
@@ -68,6 +71,7 @@ UpdateImpl
 		int						_restart_required )
 	{
 		instance			= _instance;
+		component			= _component;
 		name				= _name;
 		description			= _desc;
 		new_version			= _new_version;
@@ -101,6 +105,12 @@ UpdateImpl
 		return( instance );
 	}
 	
+	protected UpdatableComponentImpl
+	getComponent()
+	{
+		return( component );
+	}
+	
 	public String
 	getName()
 	{
@@ -215,9 +225,11 @@ UpdateImpl
 	}
 	
 	public void
-	complete()
+	complete(
+		boolean	success )
 	{
 		complete	= true;
+		succeeded	= success;
 		
 		Iterator it = listeners.iterator();
 		
@@ -245,6 +257,12 @@ UpdateImpl
 		return( complete );
 	}
 	
+	public boolean
+	wasSuccessful()
+	{
+		return( succeeded );
+	}
+	
 	public Object
 	getDecision(
 		int			decision_type,
diff --git a/org/gudy/azureus2/pluginsimpl/local/update/UpdateInstallerImpl.java b/org/gudy/azureus2/pluginsimpl/local/update/UpdateInstallerImpl.java
index c8bb516..b28e24a 100644
--- a/org/gudy/azureus2/pluginsimpl/local/update/UpdateInstallerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/update/UpdateInstallerImpl.java
@@ -38,23 +38,27 @@ import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.*;
 
+import com.aelitis.azureus.core.update.AzureusRestarter;
+import com.aelitis.azureus.core.update.AzureusRestarterFactory;
+
 public class 
 UpdateInstallerImpl
 	implements UpdateInstaller
 {
 		// change these and you'll need to change the Updater!!!!
 	
-	protected static final String	UPDATE_DIR 	= "updates";
-	protected static final String	ACTIONS		= "install.act";
+	protected static final String	UPDATE_DIR 		= "updates";
+	protected static final String	ACTIONS_LEGACY	= "install.act";
+	protected static final String	ACTIONS_UTF8	= "install.act.utf8";
 	
 	protected static AEMonitor	class_mon 	= new AEMonitor( "UpdateInstaller:class" );
 
-	private UpdateManager	manager;
-	private File			install_dir;
+	private UpdateManagerImpl	manager;
+	private File				install_dir;
 	
 	protected static void
 	checkForFailedInstalls(
-		UpdateManager	manager )
+		UpdateManagerImpl	manager )
 	{
 		try{
 			File	update_dir = new File( manager.getUserDir() + File.separator + UPDATE_DIR );
@@ -104,7 +108,7 @@ UpdateInstallerImpl
 	
 	protected
 	UpdateInstallerImpl(
-		UpdateManager	_manager )
+		UpdateManagerImpl	_manager )
 	
 		throws UpdateException
 	{
@@ -192,7 +196,7 @@ UpdateInstallerImpl
 		String		to_file )
 	
 		throws UpdateException
-	{
+	{		
 		// System.out.println( "move action:" + from_file_or_resource + " -> " + to_file );
 		
 		if ( from_file_or_resource.indexOf(File.separator) == -1 ){
@@ -212,12 +216,16 @@ UpdateInstallerImpl
 				parent.mkdirs();
 			}
 			
+			boolean	log_perm_set_fail = true;
+			
 			if ( parent != null ){
 				
 				// we're going to need write access to the parent, let's try
 				
 				if ( !parent.canWrite()){
 					
+					log_perm_set_fail = false;
+					
 						// Vista install process goes through permissions elevation process
 						// so don't warn about lack of write permissions
 					
@@ -244,12 +252,21 @@ UpdateInstallerImpl
 				}
 			}catch( Throwable e ){
 					
-				Debug.out( e );
+				if ( log_perm_set_fail ){
+					
+					if ( !Constants.isWindowsVistaOrHigher ){
+					
+						Debug.out( e );
+					}
+				}
 			}
 		}catch( Throwable e ){
 			
 		}
 		
+		from_file_or_resource 	= escapeFile( from_file_or_resource );
+		to_file					= escapeFile( to_file );
+
 		appendAction( "move," + from_file_or_resource  + "," + to_file );
 	}
   
@@ -261,6 +278,8 @@ UpdateInstallerImpl
   
     	throws UpdateException
 	{ 
+		to_file = escapeFile( to_file );
+		
 		appendAction( "chmod," + rights  + "," + to_file );
 	}
   
@@ -270,22 +289,38 @@ UpdateInstallerImpl
   
     	throws UpdateException
 	{ 
+		file = escapeFile( file );
+		
 		appendAction( "remove," + file );
 	}
 	
+	private String
+	escapeFile(
+		String		file )
+	{
+		if ( file.contains( "," )){
+			
+				// needs support in Updater... to fix :(
+			
+			Debug.out( "Installation is going to fail for '" + file + "' as ',' in name not supported" );
+		}
+		
+		return( file );
+	}
+	
 	protected void
 	appendAction(
 		String		data )
 	
 		throws UpdateException
 	{
-		PrintWriter	pw = null;
+		PrintWriter	pw_legacy = null;
 	
 		try{		
 			
-			pw = new PrintWriter(new FileWriter( install_dir.toString() + File.separator + ACTIONS, true ));
+			pw_legacy = new PrintWriter(new FileWriter( install_dir.toString() + File.separator + ACTIONS_LEGACY, true ));
 
-			pw.println( data );
+			pw_legacy.println( data );
 			
 		}catch( Throwable e ){
 			
@@ -293,11 +328,36 @@ UpdateInstallerImpl
 			
 		}finally{
 			
-			if ( pw != null ){
+			if ( pw_legacy != null ){
+		
+				try{	
+					pw_legacy.close();
+					
+				}catch( Throwable e ){
+	
+					throw( new UpdateException( "Failed to write actions file", e ));
+				}
+			}
+		}
 		
-				try{
+		PrintWriter	pw_utf8 = null;
 		
-					pw.close();
+		try{		
+			
+			pw_utf8 = new PrintWriter( new OutputStreamWriter( new FileOutputStream( install_dir.toString() + File.separator + ACTIONS_UTF8, true ), "UTF-8" ));
+
+			pw_utf8.println( data );
+			
+		}catch( Throwable e ){
+			
+			throw( new UpdateException( "Failed to write actions file", e ));
+			
+		}finally{
+			
+			if ( pw_utf8 != null ){
+		
+				try{		
+					pw_utf8.close();
 					
 				}catch( Throwable e ){
 	
@@ -306,4 +366,146 @@ UpdateInstallerImpl
 			}
 		}
 	}
+	
+	public void 
+	installNow(
+		final UpdateInstallerListener		listener )
+	
+		throws UpdateException 
+	{
+		try{
+			UpdateInstaller[] installers = manager.getInstallers();
+			
+			if ( installers.length != 1 || installers[0] != this ){
+				
+				throw( new UpdateException( "Other installers exist - aborting" ));
+			}
+						
+			listener.reportProgress( "Update starts" );
+			
+			AzureusRestarter ar = AzureusRestarterFactory.create( manager.getCore());
+			
+			ar.updateNow();
+			
+			new AEThread2( "installNow:waiter", true )
+			{
+				public void
+				run()
+				{
+					try{
+						long	start = SystemTime.getMonotonousTime();
+						
+						UpdateException pending_error = null;
+						
+						while( true ){
+							
+							Thread.sleep( 1000 );
+					
+							listener.reportProgress( "Checking progress" );
+							
+							if ( !install_dir.exists()){
+								
+								break;
+							}
+							
+							File	fail_file = new File( install_dir, "install.fail" );
+							
+							if ( fail_file.exists()){
+							
+								try{
+									String error = FileUtil.readFileAsString( fail_file, 1024 );
+									
+									throw( new UpdateException( error ));
+									
+								}catch( Throwable e ){
+									
+									if ( e instanceof UpdateException ){
+										
+										throw( e );
+									}
+									
+									if ( pending_error != null ){
+										
+										throw( pending_error );
+									}
+									
+									pending_error = new UpdateException( "Install failed, reason unknown" );
+								}
+							}
+							
+							if ( SystemTime.getMonotonousTime() - start >= 5*60*1000 ){
+								
+								listener.reportProgress( "Timeout" );
+								
+								throw( new UpdateException( "Timeout waiting for update to apply" ));
+							}
+						}
+						
+						listener.reportProgress( "Complete" );
+						
+						listener.complete();
+						
+					}catch( Throwable e ){
+						
+						UpdateException fail;
+						
+						if ( e instanceof UpdateException ){
+							
+							fail = (UpdateException)e;
+							
+						}else{
+							
+							fail = new UpdateException( "install failed", e );
+						}
+						
+						listener.reportProgress( fail.getMessage());
+						
+						listener.failed( fail );
+						
+					}finally{
+						
+						deleteInstaller();	
+					}
+				}
+			}.start();
+			
+		}catch( Throwable e ){
+			
+			deleteInstaller();	
+			
+			UpdateException fail;
+			
+			if ( e instanceof UpdateException ){
+				
+				fail = (UpdateException)e;
+				
+			}else{
+				
+				fail = new UpdateException( "install failed", e );
+			}
+			
+			listener.reportProgress( fail.getMessage());
+			
+			listener.failed( fail );
+			
+			throw( fail );
+		}
+	}
+	
+	public void
+	destroy()
+	{
+		deleteInstaller();
+	}
+	
+	private void
+	deleteInstaller()
+	{
+		manager.removeInstaller( this );
+
+		if ( install_dir.exists()){
+			
+			FileUtil.recursiveDelete( install_dir );
+		}
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/update/UpdateManagerImpl.java b/org/gudy/azureus2/pluginsimpl/local/update/UpdateManagerImpl.java
index 047b140..4483355 100644
--- a/org/gudy/azureus2/pluginsimpl/local/update/UpdateManagerImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/update/UpdateManagerImpl.java
@@ -48,7 +48,7 @@ public class
 UpdateManagerImpl
 	implements UpdateManager
 {
-	protected static UpdateManagerImpl		singleton;
+	private static UpdateManagerImpl		singleton;
 		
 	public static UpdateManager
 	getSingleton(
@@ -62,13 +62,15 @@ UpdateManagerImpl
 		return( singleton );
 	}
 
-	protected AzureusCore	azureus_core;
+	private AzureusCore	azureus_core;
 		
-	protected List	components 				= new ArrayList();
-	protected List	listeners				= new ArrayList();
-	protected List	verification_listeners	= new ArrayList();
+	private List<UpdateCheckInstanceImpl>	checkers = new ArrayList<UpdateCheckInstanceImpl>();
 	
-	protected List	installers	= new ArrayList();
+	private List<UpdatableComponentImpl>	components 				= new ArrayList<UpdatableComponentImpl>();
+	private List	listeners				= new ArrayList();
+	private List	verification_listeners	= new ArrayList();
+	
+	private List<UpdateInstaller>	installers	= new ArrayList<UpdateInstaller>();
 	
 	protected AEMonitor	this_mon 	= new AEMonitor( "UpdateManager" );
 
@@ -90,6 +92,12 @@ UpdateManagerImpl
 		}
 	}
 	
+	protected AzureusCore
+	getCore()
+	{
+		return( azureus_core );
+	}
+	
 	public void
 	registerUpdatableComponent(
 		UpdatableComponent		component,
@@ -105,6 +113,19 @@ UpdateManagerImpl
 		}
 	}
 	
+	public UpdateCheckInstance[] 
+	getCheckInstances() 
+	{
+		try{
+			this_mon.enter();
+
+			return( checkers.toArray( new UpdateCheckInstance[ checkers.size()]));
+			
+		}finally{
+			
+			this_mon.exit();
+		}
+	}
 	
 	public UpdateCheckInstance
 	createUpdateCheckInstance()
@@ -124,7 +145,9 @@ UpdateManagerImpl
 			
 			components.toArray( comps );
 			
-			UpdateCheckInstance	res = new UpdateCheckInstanceImpl( this, type, name, comps );
+			UpdateCheckInstanceImpl	res = new UpdateCheckInstanceImpl( this, type, name, comps );
+			
+			checkers.add( res );
 			
 			for (int i=0;i<listeners.size();i++){
 				
@@ -162,6 +185,8 @@ UpdateManagerImpl
 			
 			res.setLowNoise( low_noise );
 			
+			checkers.add( res );
+			
 			for (int i=0;i<listeners.size();i++){
 				
 				((UpdateManagerListener)listeners.get(i)).checkInstanceCreated( res );
@@ -197,6 +222,13 @@ UpdateManagerImpl
 		return( res );
 	}
 	
+	protected void
+	removeInstaller(
+		UpdateInstaller	installer )
+	{
+		installers.remove( installer );
+	}
+	
 	public String
 	getInstallDir()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
index d577e33..502559c 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/UtilitiesImpl.java
@@ -33,21 +33,20 @@ import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.URL;
 import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
 import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.network.RateLimiter;
+import org.gudy.azureus2.plugins.torrent.Torrent;
 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;
 import org.gudy.azureus2.plugins.utils.search.SearchException;
 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;
@@ -64,6 +63,7 @@ import org.gudy.azureus2.pluginsimpl.local.utils.security.*;
 import org.gudy.azureus2.pluginsimpl.local.utils.xml.rss.RSSFeedImpl;
 import org.gudy.azureus2.pluginsimpl.local.utils.xml.simpleparser.*;
 
+import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.ipchecker.extipchecker.ExternalIPChecker;
 import org.gudy.azureus2.core3.ipchecker.extipchecker.ExternalIPCheckerFactory;
 import org.gudy.azureus2.core3.ipchecker.extipchecker.ExternalIPCheckerService;
@@ -71,7 +71,6 @@ import org.gudy.azureus2.core3.ipchecker.extipchecker.ExternalIPCheckerServiceLi
 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.AEDiagnostics;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AESemaphore;
 import org.gudy.azureus2.core3.util.AEThread2;
@@ -86,18 +85,18 @@ import org.gudy.azureus2.core3.util.IPToHostNameResolverListener;
 import org.gudy.azureus2.core3.util.SystemProperties;
 import org.gudy.azureus2.core3.util.DirectByteBufferPool;
 import org.gudy.azureus2.core3.util.SystemTime;
-import org.gudy.azureus2.core3.util.TimeFormatter;
 import org.gudy.azureus2.core3.util.Timer;
 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.networkmanager.LimitedRateGroup;
 import com.aelitis.azureus.core.util.CopyOnWriteList;
 import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
 
 public class 
 UtilitiesImpl
-	implements Utilities
+	implements Utilities, FeatureManager
 {
 	private static InetAddress		last_public_ip_address;
 	private static long				last_public_ip_address_time;
@@ -115,11 +114,167 @@ UtilitiesImpl
 			}
 		};
 		
-		
+	private static ThreadLocal<Object[]>		verified_enablers_tls	= 
+		new ThreadLocal<Object[]>()
+		{
+			public Object[]
+			initialValue()
+			{
+				return( new Object[]{ 0L, 0, null });
+			}
+		};
+			
 	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>();
+	private static CopyOnWriteList<Object[]>				feature_enablers 	= new CopyOnWriteList<Object[]>();
+	private static CopyOnWriteList<FeatureManagerListener>	feature_listeners	= new CopyOnWriteList<FeatureManagerListener>();
+	
+	private static FeatureManagerListener 
+		feature_listener = new FeatureManagerListener()
+		{
+			public void
+			licenceAdded(
+				Licence	licence )
+			{
+				checkFeatureCache();
+				
+				for ( FeatureManagerListener listener: feature_listeners ){
+					
+					try{
+						listener.licenceAdded(licence);
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}				
+			}
+			
+			public void
+			licenceChanged(
+				Licence	licence )
+			{
+				checkFeatureCache();
+				
+				for ( FeatureManagerListener listener: feature_listeners ){
+					
+					try{
+						listener.licenceChanged(licence);
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}	
+			}
+			
+			public void
+			licenceRemoved(
+				Licence	licence )
+			{
+				checkFeatureCache();
+				
+				for ( FeatureManagerListener listener: feature_listeners ){
+					
+					try{
+						listener.licenceRemoved(licence);
+						
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+					}
+				}				
+			}
+		};
+	
+			// need to use a consistent wrapped group as its object identity drives byte allocs...
+		
+	private static WeakHashMap<RateLimiter,LimitedRateGroup>	limiter_map = new WeakHashMap<RateLimiter,LimitedRateGroup>();
+	
+	public static LimitedRateGroup
+	wrapLimiter(
+		final RateLimiter	limiter )
+	{
+		synchronized( limiter_map ){
+		
+			LimitedRateGroup l = limiter_map.get( limiter );
+			
+			if ( l == null ){
+				
+				l = new PluginLimitedRateGroup( limiter );
+				
+				limiter_map.put( limiter, l );
+			}
+			
+			return( l );
+		}
+	}
+	
+	private static void
+	checkFeatureCache()
+	{
+		Set<String> features = new TreeSet<String>();
+		
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+		
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				Licence[] licences = enabler.getLicences();
+					
+				for ( Licence licence: licences ){
+					
+					int	licence_state = licence.getState();
+					
+					if ( licence_state != Licence.LS_AUTHENTICATED ){
+						
+						continue;
+					}
+					
+					FeatureDetails[] details = licence.getFeatures();
+					
+					for ( FeatureDetails detail: details ){
+						
+						if ( !detail.hasExpired()){
+							
+							features.add( detail.getID());
+						}
+					}
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		if ( !getFeaturesInstalled().equals( features )){
+		
+			String str = "";
+			
+			for ( String f: features ){
+				
+				str += (str.length()==0?"":",") + f;
+			}
+			
+			COConfigurationManager.setParameter( "featman.cache.features.installed", str );
+		}
+	}
+	
+	public static Set<String>
+	getFeaturesInstalled()
+	{
+		String str = COConfigurationManager.getStringParameter( "featman.cache.features.installed", "" );
+		
+		Set<String>	result = new TreeSet<String>();
+		
+		if ( str.length() > 0 ){
+		
+			result.addAll( Arrays.asList( str.split( "," )));
+		}
+		
+		return( result );
+	}
 	
 	public
 	UtilitiesImpl(
@@ -1014,6 +1169,37 @@ UtilitiesImpl
 		}
 	}
 	
+	public void 
+	unregisterSearchProvider(
+		SearchProvider 		provider )
+	
+		throws SearchException
+	{
+		List<searchManager>	managers;
+		
+		synchronized( UtilitiesImpl.class ){
+			
+			Iterator<Object[]> it = search_providers.iterator();
+			
+			while( it.hasNext()){
+				
+				Object[] entry = it.next();
+				
+				if ( entry[0] == pi && entry[1] == provider ){
+					
+					it.remove();
+				}
+			}
+			
+			managers = new ArrayList<searchManager>( search_managers );
+		}
+		
+		for (int i=0;i<managers.size();i++){
+				
+			((searchManager)managers.get(i)).removeProvider( pi, provider );
+		}
+	}
+	
 	public SearchInitiator 
 	getSearchInitiator() 
 	
@@ -1055,46 +1241,361 @@ UtilitiesImpl
 		}
 	}
 	
-	public boolean 
-	isFeatureEnabled(
-		String 					feature_id,
-		Map<String, Object> 	feature_properties) 
+	public FeatureManager 
+	getFeatureManager()
+	{
+		return( this );
+	}
+	
+	public Licence[]
+	createLicences(
+		String[]				feature_ids )
+	
+		throws PluginException
+	{
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+		
+		Throwable last_error = null;
+		
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				Licence[] licences = enabler.createLicences( feature_ids );
+				
+				if ( licences != null ){
+					
+					return( licences );
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+				
+				last_error = e;
+			}
+		}
+		
+		if ( last_error == null ){
+			
+			throw( getLicenceException( "Failed to create licence" ));
+			
+		}else{
+			
+			throw( new PluginException( "Licence handler failed to create licence", last_error ));
+		}
+	}
+	
+	public Licence 
+	addLicence(
+		String licence_key ) 
+	
+		throws PluginException
+	{
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+		
+		Throwable last_error = null;
+		
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				Licence licence = enabler.addLicence( licence_key );
+				
+				if ( licence != null ){
+					
+					return( licence );
+				}
+			}catch( Throwable e ){
+		
+				last_error = e;
+				
+				Debug.out( e );
+			}
+		}
+		
+		if ( last_error == null ){
+		
+			throw( getLicenceException( "Licence addition failed" ));
+			
+		}else{
+			
+			throw( new PluginException( "Licence handler failed to add licence", last_error ));
+		}
+	}
+	
+	private PluginException
+	getLicenceException(
+		String		str )
+	{		
+		try{
+			String extra = "";
+
+			PluginInterface fm_pi = core.getPluginManager().getPluginInterfaceByID( "aefeatman_v", false );
+		
+			
+			if ( fm_pi == null || ( fm_pi.getPluginVersion() != null && fm_pi.getPluginVersion().equals( "0.0" ))){
+				
+				Download[] downloads = pi.getDownloadManager().getDownloads();
+				
+				Download hit = null;
+				
+				for ( Download download: downloads ){
+					
+					Torrent torrent = download.getTorrent();
+					
+					if ( torrent != null && torrent.isSimpleTorrent()){
+						
+						String name = torrent.getFiles()[0].getName();
+						
+						if ( name.startsWith( "aefeatman_v_") && name.endsWith( ".zip" )){
+							
+							hit = download;
+							
+							break;
+						}
+					}
+				}
+				
+				if ( hit == null ){
+				
+					extra = "The 'Vuze Feature Manager' plugin is required but isn't installed";
+					
+				}else{
+					
+					int	state = hit.getState();
+					
+					if (	(state == Download.ST_STOPPED && !hit.isComplete() ) || 
+							state == Download.ST_ERROR ){
+						
+						extra = "The 'Vuze Feature Manager' plugin has failed to download - check your Library's detailed view for errors or stopped downloads";
+						
+					}else{
+						
+						extra = "The 'Vuze Feature Manager' plugin is currently downloading, please wait for it to complete and install";
+					}
+				}
+			}else{
+				
+				PluginState ps = fm_pi.getPluginState();
+				
+				if ( !ps.isLoadedAtStartup()){
+					
+					extra = "You need to set the 'Vuze Feature Manager' plugin to 'load at startup' in the plugin options";
+					
+				}else if ( ps.isDisabled()){
+					
+					extra = "The 'Vuze Feature Manager' plugin needs to be enabled";
+
+				}else if ( !ps.isOperational()){
+					
+					extra = "The 'Vuze Feature Manager' plugin isn't operational";
+				}
+			}
+			
+			return( new PluginException( str + ": " + extra ));
+			
+		}catch( Throwable e ){
+			
+			return( new PluginException( str, e ));
+		}
+	}
+	
+	public Licence[] 
+	getLicences() 
+	{
+		List<Licence> all_licences = new ArrayList<Licence>();
+		
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+		
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				Licence[] licence = enabler.getLicences();
+				
+				all_licences.addAll( Arrays.asList( licence ));
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		return( all_licences.toArray( new Licence[ all_licences.size()]));
+	}
+	
+	public void
+	refreshLicences()
+	{
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+		
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				enabler.refreshLicences();
+				
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+	}
+	
+	public FeatureDetails[]
+ 	getFeatureDetails(
+ 		String 					feature_id )
+ 	{
+		return( getFeatureDetailsSupport( feature_id ));
+ 	}
+	
+	public boolean
+	isFeatureInstalled(
+		String					feature_id )
+	{
+		return( getVerifiedEnablers().size() > 0 && getFeaturesInstalled().contains( feature_id ));
+	}
+	
+	private static FeatureDetails[]
+	getFeatureDetailsSupport(
+		String 					feature_id )
+	{
+		List<FeatureDetails>	result = new ArrayList<FeatureDetails>();
+	
+		List<FeatureEnabler>	enablers = getVerifiedEnablers();
+			
+		for ( FeatureEnabler enabler: enablers ){
+			
+			try{
+				Licence[] licences = enabler.getLicences();
+					
+				for ( Licence licence: licences ){
+					
+					FeatureDetails[] details = licence.getFeatures();
+					
+					for ( FeatureDetails detail: details ){
+						
+						if ( detail.getID().equals( feature_id )){
+							
+							result.add( detail );
+						}
+					}
+				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+		}
+		
+		return( result.toArray( new FeatureDetails[ result.size() ]));
+	}
+	
+   	public void
+	addListener(
+		FeatureManagerListener		listener )
 	{
-		String pid = pi.getPluginID();
+   		synchronized( feature_enablers ){
+   			
+   			feature_listeners.add( listener );
+   		}
+	}
+   	
+	public void
+	removeListener(
+		FeatureManagerListener		listener )
+	{
+ 		synchronized( feature_enablers ){
+   			
+ 			feature_listeners.remove( listener );
+   		}
+	}
+	
+	private static final List<FeatureEnabler>
+	getVerifiedEnablers()
+	{		
+		long	now = SystemTime.getMonotonousTime();
+		int		mut = feature_enablers.getMutationCount();
+		
+		Object[] cache = verified_enablers_tls.get();
+		
+		long	last_time 	= (Long)cache[0];
+		int		old_mut		= (Integer)cache[1];
 		
-		if ( !pid.endsWith( "_v" )){
+		if ( 	last_time != 0 && now - last_time < 30*1000 &&
+				mut == old_mut ){
 			
-			return( false );
+			return((List<FeatureEnabler>)cache[2]);
 		}
 		
-		for ( FeatureEnabler fe: feature_enablers ){
+		List<FeatureEnabler>	enablers = new ArrayList<FeatureEnabler>();
+
+		for ( Object[] entry: feature_enablers ){
+			
+			PluginInterface enabler_pi 		= (PluginInterface)entry[0];
+			Plugin			enabler_plugin 	= (Plugin)entry[1];
+			FeatureEnabler	enabler 		= (FeatureEnabler)entry[2];
 			
-			if ( fe.isFeatureEnabled( pid, feature_id, feature_properties)){
+			if ( PluginInitializer.isVerified( enabler_pi, enabler_plugin )){
 				
-				return( true );
+				if ( PluginInitializer.DISABLE_PLUGIN_VERIFICATION ){
+					
+					enablers.add( enabler );
+					
+				}else{
+					
+					File f1 = FileUtil.getJarFileFromClass( enabler_plugin.getClass());
+					File f2 = FileUtil.getJarFileFromClass( enabler.getClass());
+					
+					if ( f1 != null && f1.equals( f2 )){
+				
+						enablers.add( enabler );
+					}
+				}
 			}
 		}
 		
-		return false;
+		verified_enablers_tls.set( new Object[]{ now, mut, enablers } );
+		
+		return( enablers );
 	}
 	
 	public void
 	registerFeatureEnabler(
 		FeatureEnabler	enabler )
 	{
-		if ( !pi.getPluginID().endsWith( "_v" )){
-						
+		Plugin plugin = pi.getPlugin();
+		
+		if ( !PluginInitializer.isVerified( pi, plugin )){
+				
+			Debug.out( "Feature enabler not registered as plugin unverified" );
+			
 			return;
 		}
 		
-		feature_enablers.add( enabler );
+		synchronized( feature_enablers ){
+			
+			feature_enablers.add( new Object[]{ pi, plugin, enabler });
+			
+			enabler.addListener( feature_listener );
+		}
+		
+		checkFeatureCache();
 	}
 	
 	public void
 	unregisterFeatureEnabler(
 		FeatureEnabler	enabler )
 	{
-		feature_enablers.remove( enabler );
+		synchronized( feature_enablers ){
+			
+			for ( Object[] entry: feature_enablers ){
+				
+				if ( entry[2] == enabler ){
+					
+					feature_enablers.remove( entry );
+					
+					return;
+				}
+			}
+		}
+		
+		checkFeatureCache();
 	}
 	
 	public interface
@@ -1105,6 +1606,11 @@ UtilitiesImpl
 		addProvider( 
 			PluginInterface		pi,
 			SearchProvider		provider );
+		
+		public void
+		removeProvider( 
+			PluginInterface		pi,
+			SearchProvider		provider );
 	}
 		
 	
@@ -1147,6 +1653,12 @@ UtilitiesImpl
 										return( p_sub.getName());
 									}
 									
+									public boolean 
+									isSearchTemplate() 
+									{
+										return( p_sub.isSearchTemplate());
+									}
+									
 									public SubscriptionResult[] 
 									getResults() 
 									{
@@ -1200,6 +1712,32 @@ UtilitiesImpl
 		}
 	}
 	
+	public boolean 
+	supportsPowerStateControl(
+		int state ) 
+	{
+		if ( state == PowerManagementListener.ST_SLEEP ){
+			
+			return( PlatformManagerFactory.getPlatformManager().hasCapability( PlatformManagerCapabilities.PreventComputerSleep ));
+		}
+		
+		return( false );
+	}
+	
+	public void
+	addPowerManagementListener(
+		PowerManagementListener	listener )
+	{
+		core.addPowerManagementListener( listener );
+	}
+		
+	public void
+	removePowerManagementListener(
+		PowerManagementListener	listener )
+	{
+		core.removePowerManagementListener( listener );
+	}
+	
 	public interface
 	PluginSubscriptionManager
 	{
@@ -1217,6 +1755,9 @@ UtilitiesImpl
 		public String
 		getName();
 		
+		public boolean 
+		isSearchTemplate();
+		
 		public PluginSubscriptionResult[]
 		getResults(
 			boolean		include_deleted );
@@ -1261,6 +1802,32 @@ UtilitiesImpl
 			throws S;
 	}
 	
+	public static class
+	PluginLimitedRateGroup
+		implements LimitedRateGroup
+	{
+		private RateLimiter	limiter;
+		
+		private
+		PluginLimitedRateGroup(
+			RateLimiter		_limiter )
+		{
+			limiter	= _limiter;
+		}
+		
+		public String 
+		getName()
+		{
+			return( limiter.getName());
+		}
+		  
+		public int 
+		getRateLimitBytesPerSecond()
+		{
+			 return( limiter.getRateLimitBytesPerSecond());
+		}
+	}
+	
 	static class
 	DelayedTaskImpl
 		implements DelayedTask
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderAlternateImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderAlternateImpl.java
index 16f743e..9154a53 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderAlternateImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderAlternateImpl.java
@@ -112,7 +112,7 @@ ResourceDownloaderAlternateImpl
 	{		
 		if( delegates.length == 0 ){
 			
-			ResourceDownloaderException error = new ResourceDownloaderException( "Alternate download fails - 0 alteratives");
+			ResourceDownloaderException error = new ResourceDownloaderException( this, "Alternate download fails - 0 alteratives");
 			
 			informFailed( error );
 			
@@ -217,7 +217,7 @@ ResourceDownloaderAlternateImpl
 	{
 		if( delegates.length == 0 ){
 			
-			ResourceDownloaderException error = new ResourceDownloaderException( "Alternate download fails - 0 alteratives");
+			ResourceDownloaderException error = new ResourceDownloaderException( this, "Alternate download fails - 0 alteratives");
 			
 			informFailed( error );
 			
@@ -274,7 +274,7 @@ ResourceDownloaderAlternateImpl
 		try{
 			this_mon.enter();
 		
-			result	= new ResourceDownloaderCancelledException();
+			result	= new ResourceDownloaderCancelledException( this );
 			
 			cancelled	= true;
 			
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderBaseImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderBaseImpl.java
index 6aa6498..7c027dd 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderBaseImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderBaseImpl.java
@@ -66,6 +66,12 @@ ResourceDownloaderBaseImpl
 		}
 	}
 	
+	public ResourceDownloader
+	getClone()
+	{
+		return( getClone( null ));
+	}
+	
 	public abstract ResourceDownloaderBaseImpl
 	getClone(
 		ResourceDownloaderBaseImpl	_parent );
@@ -74,6 +80,71 @@ ResourceDownloaderBaseImpl
 	setSize(
 		long	size );
 	
+	public boolean
+	getBooleanProperty(
+		String		key )
+	
+		throws ResourceDownloaderException
+	{
+		Object obj = getProperty( key );
+	
+		if ( obj instanceof Boolean ){
+			
+			return(((Boolean)obj).booleanValue());
+		}
+		
+		return( false );
+	}
+	
+	public long
+	getLongProperty(
+		String		key )
+	
+		throws ResourceDownloaderException
+	{
+		Object obj = getProperty( key );
+	
+		if ( obj == null || !( obj instanceof Number )){
+			
+			return( -1 );
+		}
+		
+		return(((Number)obj).longValue());
+	}
+	
+	public String
+	getStringProperty(
+		String		key )
+	
+		throws ResourceDownloaderException
+	{
+		Object obj = getProperty( key );
+		
+		if ( obj == null || obj instanceof String ){
+			
+			return((String)obj);
+		}
+			
+		if ( obj instanceof List ){
+			
+			List l = (List)obj;
+			
+			if ( l.size() == 0 ){
+				
+				return( null );
+			}
+			
+			obj = l.get( 0 );
+			
+			if ( obj instanceof String ){
+				
+				return((String)obj);
+			}
+		}
+		
+		return( null );
+	}
+	
 	public Object
 	getProperty(
 		String		name )
@@ -82,7 +153,13 @@ ResourceDownloaderBaseImpl
 	{
 		Object res = getPropertySupport( name );
 		
-		if ( res != null || getPropertySupport( PR_PROPERTIES_SET ) != null ){
+		if ( 	res != null || 
+				getPropertySupport( PR_PROPERTIES_SET ) != null ||
+				name.equalsIgnoreCase( "URL_Connection" ) ||
+				name.equalsIgnoreCase( "URL_Connect_Timeout" ) ||
+				name.equalsIgnoreCase( "URL_Read_Timeout" ) ||
+				name.equalsIgnoreCase( "URL_Trust_Content_Length" ) ||
+				name.equalsIgnoreCase( "URL_HTTP_VERB" )){
 			
 			return( res );
 		}
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderFileImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderFileImpl.java
index 4ef3a75..76dee82 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderFileImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderFileImpl.java
@@ -170,7 +170,7 @@ ResourceDownloaderFileImpl
 								
 							}catch( Throwable e ){
 								
-								failed( ResourceDownloaderFileImpl.this, new ResourceDownloaderException( "Failed to read file", e ));
+								failed( ResourceDownloaderFileImpl.this, new ResourceDownloaderException( ResourceDownloaderFileImpl.this, "Failed to read file", e ));
 								
 								Debug.printStackTrace( e );
 								
@@ -192,7 +192,7 @@ ResourceDownloaderFileImpl
 	public void
 	cancel()
 	{
-		cancel( new ResourceDownloaderCancelledException());
+		cancel( new ResourceDownloaderCancelledException(  this  ));
 	}
 	
 	protected void
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderMetaRefreshImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderMetaRefreshImpl.java
index a01c565..520603a 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderMetaRefreshImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderMetaRefreshImpl.java
@@ -132,7 +132,9 @@ ResourceDownloaderMetaRefreshImpl
 			
 			HTMLPage	page = HTMLPageFactory.loadPage( x.download());
 			
-			URL	redirect = page.getMetaRefreshURL();
+			URL base_url = (URL)x.getProperty( "URL_URL" );
+
+			URL	redirect = page.getMetaRefreshURL( base_url );
 	
 			if ( redirect == null ){
 				
@@ -159,7 +161,7 @@ ResourceDownloaderMetaRefreshImpl
 			}
 		}catch( HTMLException e ){
 			
-			throw( new ResourceDownloaderException( "getSize failed", e ));
+			throw( new ResourceDownloaderException( this, "getSize failed", e ));
 		}
 	}	
 	
@@ -232,7 +234,7 @@ ResourceDownloaderMetaRefreshImpl
 		try{
 			this_mon.enter();
 		
-			result	= new ResourceDownloaderCancelledException();
+			result	= new ResourceDownloaderCancelledException(  this  );
 			
 			cancelled	= true;
 			
@@ -275,13 +277,15 @@ ResourceDownloaderMetaRefreshImpl
 				
 				HTMLPage	page = HTMLPageFactory.loadPage( data, !marked );
 				
-				URL	redirect = page.getMetaRefreshURL();
+				URL base_url = (URL)downloader.getProperty( "URL_URL" );
+				
+				URL	redirect = page.getMetaRefreshURL( base_url );
 				
 				if ( redirect == null ){
 					
 					if ( !marked ){
 						
-						failed( downloader, new ResourceDownloaderException( "meta refresh tag not found and input stream not recoverable"));
+						failed( downloader, new ResourceDownloaderException( this, "meta refresh tag not found and input stream not recoverable"));
 						
 					}else{
 					
@@ -319,7 +323,7 @@ ResourceDownloaderMetaRefreshImpl
 			}
 		}catch( Throwable e ){
 			
-			failed( downloader, new ResourceDownloaderException("meta-refresh processing fails", e ));
+			failed( downloader, new ResourceDownloaderException( this, "meta-refresh processing fails", e ));
 		}
 		
 		return( true );
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderRetryImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderRetryImpl.java
index c197dd2..e14ad19 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderRetryImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderRetryImpl.java
@@ -209,7 +209,7 @@ ResourceDownloaderRetryImpl
 		try{
 			this_mon.enter();
 		
-			result	= new ResourceDownloaderCancelledException();
+			result	= new ResourceDownloaderCancelledException(  this  );
 			
 			cancelled	= true;
 			
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTimeoutImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTimeoutImpl.java
index 2f107fb..5e6dcf1 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTimeoutImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTimeoutImpl.java
@@ -180,7 +180,7 @@ ResourceDownloaderTimeoutImpl
 							try{
 								Thread.sleep( timeout_millis );
 								
-								cancel(new ResourceDownloaderException( "Download timeout"));
+								cancel(new ResourceDownloaderException( ResourceDownloaderTimeoutImpl.this, "Download timeout"));
 								
 							}catch( Throwable e ){
 								
@@ -259,7 +259,7 @@ ResourceDownloaderTimeoutImpl
 							try{
 								Thread.sleep( timeout_millis );
 								
-								cancel(new ResourceDownloaderException( "getSize timeout"));
+								cancel(new ResourceDownloaderException( ResourceDownloaderTimeoutImpl.this, "getSize timeout"));
 								
 							}catch( Throwable e ){
 								
@@ -281,7 +281,7 @@ ResourceDownloaderTimeoutImpl
 	public void
 	cancel()
 	{
-		cancel( new ResourceDownloaderCancelledException());
+		cancel( new ResourceDownloaderCancelledException(  this  ));
 	}
 	
 	protected void
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTorrentImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTorrentImpl.java
index 511cc81..9d9825c 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTorrentImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderTorrentImpl.java
@@ -62,6 +62,8 @@ ResourceDownloaderTorrentImpl
 	protected Download					download;
 	
 	protected boolean					cancelled;
+	protected boolean					completed;
+	
 	protected ResourceDownloader		current_downloader;
 	protected Object					result;
 	protected AESemaphore				done_sem	= new AESemaphore("RDTorrent");
@@ -167,7 +169,7 @@ ResourceDownloaderTorrentImpl
 				
 				if( !torrent_holder[0].isSimpleTorrent()){
 					
-					throw( new ResourceDownloaderException( "Only simple torrents supported" ));
+					throw( new ResourceDownloaderException( this, "Only simple torrents supported" ));
 				}
 			}
 			
@@ -199,7 +201,7 @@ ResourceDownloaderTorrentImpl
 			
 		}catch( TOTorrentException e ){
 			
-			throw( new ResourceDownloaderException( "Torrent deserialisation failed", e ));
+			throw( new ResourceDownloaderException( this, "Torrent deserialisation failed", e ));
 		}
 	}	
 	
@@ -281,13 +283,15 @@ ResourceDownloaderTorrentImpl
 	downloadTorrent()
 	{
 		try{
-			informActivity( getLogIndent() + "Downloading: " + new String( torrent_holder[0].getName(), Constants.DEFAULT_ENCODING ));
+			String name = new String( torrent_holder[0].getName(), Constants.DEFAULT_ENCODING );
+			
+			informActivity( getLogIndent() + "Downloading: " + name );
 			
 				// we *don't* want this temporary file to be deleted automatically as we're
 				// going to use it across Azureus restarts to hold the download data and
-				// to seed it afterwards. Therefore we don't use AETemporaryFileHandler!!!!
+				// to seed it afterwards. Therefore we don't use AETemporaryFileHandler.createTempFile!!!!
 			
-			final File	torrent_file 	= File.createTempFile("AZU", null );
+			final File	torrent_file 	= AETemporaryFileHandler.createSemiTempFile();
 			
 			if ( download_dir != null && !download_dir.exists()){
 				
@@ -301,7 +305,26 @@ ResourceDownloaderTorrentImpl
 			TorrentUtils.setFlag( torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE, true );
 
 			torrent.serialiseToBEncodedFile( torrent_file );
-				
+			
+				// see if already there in an error state and delete if so
+			
+			try{
+				Download existing = download_manager.getDownload( torrent.getHash());
+			
+				if ( existing != null ){
+					
+					int	existing_state = existing.getState();
+					
+					if ( existing_state == Download.ST_ERROR || existing_state == Download.ST_STOPPED ){
+						
+						informActivity( getLogIndent() + "Deleting existing stopped/error state download for " + name );
+
+						existing.remove( true, true );
+					}
+				}
+			}catch( Throwable e ){	
+			}
+			
 			if ( persistent ){
 				
 				download = download_manager.addDownload( new TorrentImpl(torrent), torrent_file, data_dir );
@@ -315,9 +338,15 @@ ResourceDownloaderTorrentImpl
 			
 			download.setForceStart( true );
 			
-			// Prevents any move-on-completion or move-on-removal behaviour happening.
+				// Prevents any move-on-completion or move-on-removal behaviour happening.
+			
 			download.setFlag(Download.FLAG_DISABLE_AUTO_FILE_MOVE, true);
 			
+			// seems reasonable to me but whatever: http://forum.vuze.com/thread.jspa?threadID=111012
+			if ( false ){
+				download.setFlag(Download.FLAG_DISABLE_IP_FILTER, true);
+			}
+			
 			download_manager.addListener(
 				new DownloadManagerListener()
 				{
@@ -353,11 +382,16 @@ ResourceDownloaderTorrentImpl
 							
 							download.removeListener( this );
 							
-							PluginInitializer.getDefaultInterface().getUtilities().createThread("resource complete event dispatcher", new Runnable() {
-								public void run() {
-									downloadSucceeded( download, torrent_file, data_dir );
-								}
-							});
+							PluginInitializer.getDefaultInterface().getUtilities().createThread(
+								"resource complete event dispatcher", 
+								new Runnable()
+								{
+									public void 
+									run()
+									{
+										downloadSucceeded( download, torrent_file, data_dir );
+									}
+								});
 							
 						}
 					}
@@ -381,7 +415,7 @@ ResourceDownloaderTorrentImpl
 						
 						while( result == null ){
 														
-							int	this_percentage = download.getStats().getCompleted()/10;
+							int	this_percentage = download.getStats().getDownloadCompleted(false)/10;
 							
 							long	total	= torrent.getSize();
 														
@@ -415,7 +449,7 @@ ResourceDownloaderTorrentImpl
 			}
 		}catch( Throwable e ){
 			
-			failed( this, new ResourceDownloaderException( "Torrent download failed", e ));
+			failed( this, new ResourceDownloaderException( this, "Torrent download failed", e ));
 		}
 	}
 	
@@ -425,9 +459,20 @@ ResourceDownloaderTorrentImpl
 		File		torrent_file,
 		File		data_dir )
 	{
+		synchronized( this ){
+			
+			if ( completed ){
+				
+				return;
+			}
+			
+			completed = true;
+		}
+		
 		reportActivity("Torrent download complete");
 		
-		// assumption is that this is a SIMPLE torrent
+			// assumption is that this is a SIMPLE torrent
+		
 		File target_file = 
 			new File( data_dir,	new String(torrent_holder[0].getFiles()[0].getPathComponents()[0]));
 					
@@ -467,7 +512,7 @@ ResourceDownloaderTorrentImpl
 			
 			Debug.printStackTrace( e );
 			
-			failed( this, new ResourceDownloaderException( "Failed to read downloaded torrent data: " + e.getMessage(), e ));
+			failed( this, new ResourceDownloaderException( this, "Failed to read downloaded torrent data: " + e.getMessage(), e ));
 		}
 	}
 	
@@ -480,7 +525,7 @@ ResourceDownloaderTorrentImpl
 
 		if (!( result instanceof InputStream )){
 			
-			failed( this, new ResourceDownloaderException( "Download did not complete" ));
+			failed( this, new ResourceDownloaderException( this, "Download did not complete" ));
 		}
 	}
 	
@@ -492,7 +537,7 @@ ResourceDownloaderTorrentImpl
 		try{
 			this_mon.enter();
 		
-			result	= new ResourceDownloaderCancelledException();
+			result	= new ResourceDownloaderCancelledException(  this  );
 			
 			cancelled	= true;
 			
@@ -524,12 +569,12 @@ ResourceDownloaderTorrentImpl
 				
 			}else{
 				
-				failed( this, new ResourceDownloaderException( "Only simple torrents supported" ));
+				failed( this, new ResourceDownloaderException( this, "Only simple torrents supported" ));
 			}
 			
 		}catch( TOTorrentException e ){
 			
-			failed( downloader, new ResourceDownloaderException( "Torrent deserialisation failed", e ));
+			failed( downloader, new ResourceDownloaderException( this, "Torrent deserialisation failed", e ));
 			
 		}finally{
 			
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderURLImpl.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderURLImpl.java
index 0d8f416..d9cb5ff 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderURLImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/ResourceDownloaderURLImpl.java
@@ -34,8 +34,12 @@ import java.net.*;
 
 import javax.net.ssl.*;
 import java.net.PasswordAuthentication;
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.InflaterInputStream;
 import java.util.zip.ZipException;
@@ -45,6 +49,7 @@ import org.gudy.azureus2.core3.util.AEThread2;
 import org.gudy.azureus2.core3.util.AddressUtils;
 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.TorrentUtils;
 import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -76,7 +81,7 @@ ResourceDownloaderURLImpl
 	protected boolean       force_no_proxy = false;
 
 	private final String post_data;
-	
+
 	public 
 	ResourceDownloaderURLImpl(
 		ResourceDownloaderBaseImpl	_parent,
@@ -218,9 +223,13 @@ ResourceDownloaderURLImpl
 		try{
 			String	protocol = original_url.getProtocol().toLowerCase();
 			
-			if ( protocol.equals( "magnet" ) || protocol.equals( "dht" )){
+			if ( protocol.equals( "magnet" ) || protocol.equals( "dht" ) || protocol.equals( "vuze" ) || protocol.equals( "ftp" )){
 				
 				return( -1 );
+				
+			}else if ( protocol.equals( "file" )){
+				
+				return( new File( original_url.toURI()).length());
 			}
 			
 			reportActivity(this, "Getting size of " + original_url );
@@ -279,11 +288,11 @@ ResourceDownloaderURLImpl
 				
 							int response = con.getResponseCode();
 							
+							setProperty( "URL_HTTP_Response", new Long( response ));
+
 							if ((response != HttpURLConnection.HTTP_ACCEPTED) && (response != HttpURLConnection.HTTP_OK)) {
 								
-								setProperty( "URL_HTTP_Response", new Long( response ));
-
-								throw( new ResourceDownloaderException("Error on connect for '" + trimForDisplay( url ) + "': " + Integer.toString(response) + " " + con.getResponseMessage()));    
+								throw( new ResourceDownloaderException( this, "Error on connect for '" + trimForDisplay( url ) + "': " + Integer.toString(response) + " " + con.getResponseMessage()));    
 							}
 															
 							getRequestProperties( con );
@@ -322,7 +331,7 @@ ResourceDownloaderURLImpl
 						}
 					}
 					
-					throw( new ResourceDownloaderException("Should never get here" ));
+					throw( new ResourceDownloaderException( this, "Should never get here" ));
 
 				}finally{
 					
@@ -333,15 +342,15 @@ ResourceDownloaderURLImpl
 				}
 			}catch (java.net.MalformedURLException e){
 				
-				throw( new ResourceDownloaderException("Exception while parsing URL '" + original_url + "':" + e.getMessage(), e));
+				throw( new ResourceDownloaderException( this, "Exception while parsing URL '" + original_url + "':" + e.getMessage(), e));
 				
 			}catch (java.net.UnknownHostException e){
 				
-				throw( new ResourceDownloaderException("Exception while initializing download of '" + trimForDisplay( original_url ) + "': Unknown Host '" + e.getMessage() + "'", e));
+				throw( new ResourceDownloaderException( this, "Exception while initializing download of '" + trimForDisplay( original_url ) + "': Unknown Host '" + e.getMessage() + "'", e));
 				
 			}catch (java.io.IOException e ){
 				
-				throw( new ResourceDownloaderException("I/O Exception while downloading '" + trimForDisplay( original_url )+ "'", e ));
+				throw( new ResourceDownloaderException( this, "I/O Exception while downloading '" + trimForDisplay( original_url )+ "'", e ));
 			}
 		}catch( Throwable e ){
 			
@@ -355,7 +364,7 @@ ResourceDownloaderURLImpl
 				
 				Debug.out(e);
 				
-				rde = new ResourceDownloaderException( "Unexpected error", e );
+				rde = new ResourceDownloaderException( this, "Unexpected error", e );
 			}
 						
 			throw( rde );
@@ -422,7 +431,7 @@ ResourceDownloaderURLImpl
 				
 				if ( download_initiated ){
 					
-					throw( new ResourceDownloaderException("Download already initiated"));
+					throw( new ResourceDownloaderException( this, "Download already initiated"));
 				}
 				
 				download_initiated	= true;
@@ -439,7 +448,26 @@ ResourceDownloaderURLImpl
 				
 				String	protocol = url.getProtocol().toLowerCase();
 				
-				if ( url.getPort() == -1 && ! ( protocol.equals( "magnet" ) || protocol.equals( "dht" ))){
+				if ( protocol.equals( "vuze" )){
+					
+					url = original_url;
+					
+				}else if ( protocol.equals( "file" )){
+					
+					File file = new File( original_url.toURI());
+										
+					FileInputStream fis = new FileInputStream( file );
+					
+					informAmountComplete( file.length());
+					
+					informPercentDone( 100 );
+
+					informComplete( fis );
+					
+					return( fis );
+
+				}else if ( 	url.getPort() == -1 && 
+							( protocol.equals( "http" ) || protocol.equals( "https" ))){
 					
 					int	target_port;
 					
@@ -488,17 +516,19 @@ ResourceDownloaderURLImpl
 					
 					boolean	follow_redirect = true;
 					
+					Set<String>	redirect_urls = new HashSet<String>();
+					
 redirect_label:
-					for (int redirect_loop=0;redirect_loop<2&&follow_redirect; redirect_loop++ ){
+					while( follow_redirect ){
 						
 						follow_redirect = false;
 					
-						for (int connect_loop=0;connect_loop<2;connect_loop++){
+						for ( int connect_loop=0;connect_loop<2;connect_loop++ ){
 					
 							File					temp_file	= null;
 	
 							try{
-								HttpURLConnection	con;
+								URLConnection	con;
 								
 								if ( url.getProtocol().equalsIgnoreCase("https")){
 							      	
@@ -524,14 +554,29 @@ redirect_label:
 					  	
 								}else{
 					  	
-									con = (HttpURLConnection)openConnection(url);
+									con = openConnection(url);
 					  	
 								}
 								
+								if ( con instanceof HttpURLConnection ){
+									
+										// we want this true but some plugins (grrr) set the global default not to follow
+										// redirects
+									
+									((HttpURLConnection)con).setInstanceFollowRedirects( true );
+								}
+								
 								con.setRequestProperty("User-Agent", Constants.AZUREUS_NAME + " " + Constants.AZUREUS_VERSION);     
 					  
-						 		con.setRequestProperty( "Connection", "close" );
-	
+								String connection = getStringProperty( "URL_Connection" );
+								
+								if ( connection == null || !connection.equals( "skip" )){
+									
+										// default is close
+									
+									con.setRequestProperty( "Connection", "close" );
+								}
+								
 						 		if ( use_compression ){
 								
 						 			con.addRequestProperty( "Accept-Encoding", "gzip" );
@@ -539,39 +584,120 @@ redirect_label:
 						 		
 								setRequestProperties( con, use_compression );
 								
-								if ( post_data != null ){
+								if ( post_data != null && con instanceof HttpURLConnection ){
 									
 									con.setDoOutput(true);
 									
-									con.setRequestMethod("POST");
+									String verb = (String)getStringProperty( "URL_HTTP_VERB" );
 									
-									OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
+									if ( verb == null ){
+										
+										verb = "POST";
+									}
 									
-									wr.write(post_data);
+									((HttpURLConnection)con).setRequestMethod( verb );
 									
-									wr.flush();
+									if ( post_data.length() > 0 ){
+										
+										OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
+										
+										wr.write(post_data);
+										
+										wr.flush();
+									}
 								}
 	
+								long	connect_timeout = getLongProperty( "URL_Connect_Timeout" );
+								
+								if ( connect_timeout >= 0 ){
+								
+									con.setConnectTimeout((int)connect_timeout );
+								}
+								
+								long	read_timeout = getLongProperty( "URL_Read_Timeout" );
+								
+								if ( read_timeout >= 0 ){
+								
+									con.setReadTimeout((int)read_timeout );
+								}
+								
+								boolean	trust_content_length = getBooleanProperty( "URL_Trust_Content_Length" );
+								
 								con.connect();
 					
-								int response = con.getResponseCode();
+								int response = con instanceof HttpURLConnection?((HttpURLConnection)con).getResponseCode():HttpURLConnection.HTTP_OK;
 													
 								if ( 	response == HttpURLConnection.HTTP_MOVED_TEMP ||
 										response == HttpURLConnection.HTTP_MOVED_PERM ){
 									
-										// auto redirect doesn't work from http to https
+										// auto redirect doesn't work from http to https or vice-versa
 									
 									String	move_to = con.getHeaderField( "location" );
 									
-									if ( move_to != null && url.getProtocol().equalsIgnoreCase( "http" )){
+									if ( move_to != null ){
+										
+										if ( redirect_urls.contains( move_to ) || redirect_urls.size() > 32 ){
+											
+											throw( new ResourceDownloaderException( this, "redirect loop" )); 
+										}
+										
+										redirect_urls.add( move_to );
 										
 										try{
-											URL	move_to_url = new URL( URLDecoder.decode( move_to, "UTF-8" ));
+												// don't URL decode the move-to as its already in the right format!
 											
-											if ( move_to_url.getProtocol().equalsIgnoreCase( "https" )){
+											URL	move_to_url = new URL( move_to ); // URLDecoder.decode( move_to, "UTF-8" ));
+											
+											String	original_protocol 	= url.getProtocol().toLowerCase();
+											String	new_protocol		= move_to_url.getProtocol().toLowerCase();
+											
+											if ( !original_protocol.equals( new_protocol )){
 												
 												url = move_to_url;
 												
+												try{
+													List<String>	cookies_list = con.getHeaderFields().get( "Set-cookie" );
+													
+													List<String>	cookies_set = new ArrayList();
+													
+													if ( cookies_list != null ){
+														
+														for (int i=0;i<cookies_list.size();i++){
+															
+															String[] cookie_bits = ((String)cookies_list.get(i)).split(";");
+															
+															if ( cookie_bits.length > 0 ){
+															
+																cookies_set.add( cookie_bits[0] );
+															}
+														}
+													}
+													
+													if ( cookies_set.size() > 0 ){
+														
+														String	new_cookies = "";
+														
+														Map properties = getLCKeyProperties();
+														
+														Object obj = properties.get( "url_cookie" );
+														
+														if ( obj instanceof String ){
+														
+															new_cookies = (String)obj;
+														}
+														
+														for ( String s: cookies_set ){
+															
+															new_cookies += (new_cookies.length()==0?"":"; ") + s;
+														}
+														
+														setProperty( "URL_Cookie", new_cookies );
+													}
+												}catch( Throwable e ){
+													
+													Debug.out( e );
+												}
+												
 												follow_redirect = true;
 												
 												continue redirect_label;
@@ -582,12 +708,43 @@ redirect_label:
 									}
 								}
 								
-								if ( 	response != HttpURLConnection.HTTP_ACCEPTED && 
+								setProperty( "URL_HTTP_Response", new Long( response ));
+
+								if ( 	response != HttpURLConnection.HTTP_CREATED && 
+										response != HttpURLConnection.HTTP_ACCEPTED && 
+										response != HttpURLConnection.HTTP_NO_CONTENT && 
 										response != HttpURLConnection.HTTP_OK ) {
 									
-									setProperty( "URL_HTTP_Response", new Long( response ));
-
-									throw( new ResourceDownloaderException("Error on connect for '" + trimForDisplay( url ) + "': " + Integer.toString(response) + " " + con.getResponseMessage()));    
+									HttpURLConnection	http_con = (HttpURLConnection)con;
+									
+									InputStream error_stream = http_con.getErrorStream();
+									
+									String error_str = null;
+									
+									if ( error_stream != null ){
+										
+										String encoding = con.getHeaderField( "content-encoding");
+						 				
+						 				if ( encoding != null ){
+						 					
+						 					if ( encoding.equalsIgnoreCase( "gzip"  )){
+						 									 					
+						 						error_stream = new GZIPInputStream( error_stream );
+							 					
+						 					}else if ( encoding.equalsIgnoreCase( "deflate" )){
+							 						
+						 						error_stream = new InflaterInputStream( error_stream );
+						 					}
+						 				}
+						 				
+										error_str = FileUtil.readInputStreamAsString( error_stream, 512 );
+									}
+									
+										// grab properties anyway as they may be useful
+									
+									getRequestProperties( con );
+									
+									throw( new ResourceDownloaderException( this, "Error on connect for '" + trimForDisplay( url ) + "': " + Integer.toString(response) + " " + http_con.getResponseMessage() + (error_str==null?"":( ": error=" + error_str ))));    
 								}
 									
 								getRequestProperties( con );
@@ -646,6 +803,11 @@ redirect_label:
 									
 									while( !cancel_download ){
 										
+										if ( size >= 0 && total_read >= size && trust_content_length ){
+											
+											break;
+										}
+										
 										int read = input_stream.read(buf);
 											
 										if ( read > 0 ){
@@ -740,7 +902,7 @@ redirect_label:
 									}
 								}
 								
-								throw( new ResourceDownloaderException("Contents downloaded but rejected: '" + trimForDisplay( original_url ) + "'" ));
+								throw( new ResourceDownloaderException( this, "Contents downloaded but rejected: '" + trimForDisplay( original_url ) + "'" ));
 		
 							}catch( SSLException e ){
 								
@@ -804,7 +966,7 @@ redirect_label:
 						}
 					}
 					
-					throw( new ResourceDownloaderException("Should never get here" ));
+					throw( new ResourceDownloaderException( this, "Should never get here" ));
 					
 				}finally{
 							
@@ -815,15 +977,15 @@ redirect_label:
 				}
 			}catch (java.net.MalformedURLException e){
 				
-				throw( new ResourceDownloaderException("Exception while parsing URL '" + trimForDisplay( original_url ) + "':" + e.getMessage(), e));
+				throw( new ResourceDownloaderException( this, "Exception while parsing URL '" + trimForDisplay( original_url ) + "':" + e.getMessage(), e));
 				
 			}catch (java.net.UnknownHostException e){
 				
-				throw( new ResourceDownloaderException("Exception while initializing download of '" + trimForDisplay( original_url ) + "': Unknown Host '" + e.getMessage() + "'", e));
+				throw( new ResourceDownloaderException( this, "Exception while initializing download of '" + trimForDisplay( original_url ) + "': Unknown Host '" + e.getMessage() + "'", e));
 				
 			}catch (java.io.IOException e ){
 				
-				throw( new ResourceDownloaderException("I/O Exception while downloading '" + trimForDisplay( original_url ) + "'", e ));
+				throw( new ResourceDownloaderException( this, "I/O Exception while downloading '" + trimForDisplay( original_url ) + "'", e ));
 			}
 		}catch( Throwable e ){
 			
@@ -836,7 +998,7 @@ redirect_label:
 			}else{
 				Debug.out(e);
 				
-				rde = new ResourceDownloaderException( "Unexpected error", e );
+				rde = new ResourceDownloaderException( this, "Unexpected error", e );
 			}
 			
 			informFailed(rde);
@@ -869,13 +1031,13 @@ redirect_label:
 			this_mon.exit();
 		}
 		
-		informFailed( new ResourceDownloaderCancelledException());
+		informFailed( new ResourceDownloaderCancelledException(  this  ));
 	}
 	
 	protected void
 	setRequestProperties(
-		HttpURLConnection		con,
-		boolean					use_compression )
+		URLConnection		con,
+		boolean				use_compression )
 	{
 		Map properties = getLCKeyProperties();
 		
@@ -890,6 +1052,16 @@ redirect_label:
 			
 			if ( key.startsWith( "url_" ) && value instanceof String ){
 			
+				if ( value.equals( "skip" )){
+					
+					continue;
+				}
+				
+				if ( key.equalsIgnoreCase( "URL_HTTP_VERB" )){
+					
+					continue;
+				}
+				
 				key = key.substring(4);
 				
 				if ( key.equals( "accept-encoding" ) && !use_compression ){
@@ -906,7 +1078,7 @@ redirect_label:
 	
 	protected void
 	getRequestProperties(
-		HttpURLConnection		con )
+		URLConnection		con )
 	{
 		try{
 			setProperty( ResourceDownloader.PR_STRING_CONTENT_TYPE, con.getContentType() );
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java b/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java
deleted file mode 100644
index d5bb341..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/utils/resourcedownloader/Test.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Created on 25-Apr-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 org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader;
-
-/**
- * @author parg
- *
- */
-
-import java.io.*;
-import java.net.*;
-import java.util.Properties;
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.FileUtil;
-import org.gudy.azureus2.plugins.*;
-import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
-
-public class 
-Test
-	implements ResourceDownloaderListener, Plugin
-{
-	public void
-	initialize(
-		PluginInterface pi )
-	{
-		try{
-			ResourceDownloaderFactory	rdf = pi.getUtilities().getResourceDownloaderFactory();
-			
-			// ResourceDownloader rd_t = rdf.create(new URL("http://torrent.vuze.com:88/torrents/Azureus2201-B22.jar.torrent"));
-			
-			//rd_t = rdf.getMetaRefreshDownloader(rd_t);
-			
-			//rd_t = rdf.getRetryDownloader(rd_t, 3);
-			
-			//rd_t = rdf.getTimeoutDownloader(rd_t,1000);
-			
-			//rd_t = rdf.getTorrentDownloader(rd_t, true, new File("C:\\temp"));
-
-			//ResourceDownloader rd_u = rdf.create(new URL("http://azureus.sourceforge.net/cvs/Azureus2201-B22.jar"));
-			
-			//rd_u = rdf.getMetaRefreshDownloader(rd_u);
-			
-			//rd_u = rdf.getRetryDownloader(rd_u, 3);
-			
-			//rd_u = rdf.getSuffixBasedDownloader(rd_u);
-
-			ResourceDownloader rd_u = rdf.create( new URL( "http://torrent.vuze.com:88/files/Azureus3009-B5.jar" ));
-			
-			// rd_u = rdf.getTorrentDownloader( rd_u, true );
-
-			rd_u.addListener(
-					new ResourceDownloaderAdapter()
-				    {
-						public boolean
-				        completed(
-				        	ResourceDownloader 	downloader,
-				            InputStream 		data )
-						{
-				        	System.out.println( "complete" );
-
-							return( true );
-						}
-						
-				        public void 
-						reportPercentComplete(
-							ResourceDownloader 	downloader, 
-							final int 			percentage )
-				        {
-				        	System.out.println( "percentage = " + percentage );
-				        }
-				            
-				    	public void
-				    	reportAmountComplete(
-				    		ResourceDownloader	downloader,
-				    		long				amount )
-				    	{	
-				    		System.out.println( "amount = " + amount );
-				    	}
-				    	
-				        public void 
-						reportActivity(
-							ResourceDownloader	downloader, 
-							String 				activity) 
-				        {
-				        	System.out.println( "activity = " + activity );
-			            }
-
-				        public void 
-						failed(
-							ResourceDownloader 			downloader,
-							ResourceDownloaderException e) 
-				        {
-				        	System.out.println( "failed" );
-				        	
-				        	e.printStackTrace();
-				        }
-				    });
-
-			InputStream is = rd_u.download();
-
-			FileUtil.copyFile( is, new File( "C:\\temp\\file.jar" ));
-			
-			is.close();
-			
-			/*
-			ResourceDownloader top_downloader =
-				rdf.getAlternateDownloader(
-						new ResourceDownloader[]{rd_t,rd_u,});
-
-			final long totalk = top_downloader.getSize();
-			
-			top_downloader.addListener(
-				new ResourceDownloaderListener()
-			    {
-					public boolean
-			        completed(
-			        		final ResourceDownloader downloader,
-			                InputStream data )
-					{
-			        	System.out.println( "top - complete" );
-
-						return( true );
-					}
-					
-			        public void 
-					reportPercentComplete(
-						ResourceDownloader 	downloader, 
-						final int 			percentage )
-			        {
-			        	System.out.println( "top - percentage = " + percentage );
-			        }
-			            
-
-			        public void 
-					reportActivity(
-						ResourceDownloader	downloader, 
-						String 				activity) 
-			        {
-			        	System.out.println( "top - activity = " + activity );
-		            }
-
-			        public void 
-					failed(
-						ResourceDownloader 			downloader,
-						ResourceDownloaderException e) 
-			        {
-			        	System.out.println( "top - failed" );
-			        }
-			    });
-					
-			top_downloader.asyncDownload();
-				*/
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-	
-	public void
-	reportPercentComplete(
-		ResourceDownloader	downloader,
-		int					percentage )
-	{
-		System.out.println( "percent = " + percentage );
-	}
-	
-	public void
-	reportAmountComplete(
-		ResourceDownloader	downloader,
-		long				amount )
-	{	
-	}
-	
-	public void
-	reportActivity(
-		ResourceDownloader	downloader,
-		String				activity )
-	{
-		System.out.println( "activity = " + activity );
-	}
-	
-	public boolean
-	completed(
-		ResourceDownloader	downloader,
-		InputStream			data )
-	{
-		System.out.println( "Completed" );
-		
-		return( true );
-	}
-	
-	public void
-	failed(
-		ResourceDownloader			downloader,
-		ResourceDownloaderException e )
-	{
-		System.out.println( "Failed");
-		
-		Debug.printStackTrace( e );
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		try{
-			PluginManager.registerPlugin( Test.class );
-										
-			PluginManager.startAzureus( PluginManager.UI_NONE, new Properties() );
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-}
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSUtils.java b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSUtils.java
index 9d415bf..fb0d013 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSUtils.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/RSSUtils.java
@@ -104,20 +104,39 @@ RSSUtils
 		final String[]	formats = {
 				"yyyy-MM-dd'T'kk:mm:ss'Z'",
 				"yyyy-MM-dd'T'kk:mm:ssz", 
-				"yyyy-MM-dd'T'kk:mm:ss" };
+				"yyyy-MM-dd'T'kk:mm:ssZ", 
+				"yyyy-MM-dd'T'kk:mm:ss",
+				
+				"yyyy-MM-dd'T'kk:mm'Z'",
+				"yyyy-MM-dd'T'kk:mmz", 
+				"yyyy-MM-dd'T'kk:mmZ", 
+				"yyyy-MM-dd'T'kk:mm",
+				
+				"yyyy-MM-dd-hh:mm:ss a",				// 2012-03-13-10:33:55 PM
+		};
+
 		
-		try{
-			for (int i=0;i<formats.length;i++){
+		for (int i=0;i<formats.length;i++){
+
+			try{
 				
 				SimpleDateFormat format = new SimpleDateFormat( formats[i], Locale.US );
 							
 				return( format.parse( date_str ));
-			}
-		}catch( ParseException e ){
+
+			}catch( ParseException e ){
 			
-			Debug.printStackTrace(e);
+				// Debug.printStackTrace(e);
+			}
 		}
 		
 		return( null );
 	}
+	
+	public static void
+	main(
+		String[]	args )
+	{
+		System.out.println( parseRSSDate( "2012-03-13-10:33:55 PM" ));
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/Test.java b/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/Test.java
deleted file mode 100644
index 7080d7b..0000000
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/rss/Test.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Created on 02-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 org.gudy.azureus2.pluginsimpl.local.utils.xml.rss;
-
-import java.net.URL;
-import java.util.Properties;
-
-import org.gudy.azureus2.core3.util.AEMonitor;
-import org.gudy.azureus2.core3.util.AESemaphore;
-import org.gudy.azureus2.core3.util.AEThread;
-import org.gudy.azureus2.plugins.Plugin;
-import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.PluginManager;
-import org.gudy.azureus2.plugins.utils.xml.rss.RSSChannel;
-import org.gudy.azureus2.plugins.utils.xml.rss.RSSFeed;
-import org.gudy.azureus2.plugins.utils.xml.rss.RSSItem;
-import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentNode;
-
-/**
- * @author parg
- *
- */
-
-
-public class 
-Test 
-	implements Plugin
-{
-	private static AESemaphore		init_sem 	= new AESemaphore("RSSTester");
-	private static AEMonitor		class_mon	= new AEMonitor( "RSSTester" );
-
-	private static Test		singleton;
-		
-	
-	public static Test
-	getSingleton()
-	{
-		try{
-			class_mon.enter();
-		
-			if ( singleton == null ){
-				
-				new AEThread( "plugin initialiser" )
-				{
-					public void
-					runSupport()
-					{
-						PluginManager.registerPlugin( Test.class );
-		
-						Properties props = new Properties();
-						
-						props.put( PluginManager.PR_MULTI_INSTANCE, "true" );
-						
-						PluginManager.startAzureus( PluginManager.UI_SWT, props );
-					}
-				}.start();
-			
-				init_sem.reserve();
-			}
-			
-			return( singleton );
-			
-		}finally{
-			
-			class_mon.exit();
-		}
-	}	
-	
-	protected PluginInterface		plugin_interface;
-	
-	public void 
-	initialize(
-		PluginInterface _pi )
-	{	
-		plugin_interface	= _pi;
-		
-		singleton = this;
-		
-		init_sem.release();
-		
-		try{
-			RSSFeed feed = plugin_interface.getUtilities().getRSSFeed(new URL("http://aelitis.com:7979/rss_feed.xml"));
-			
-			RSSChannel[]	channels = feed.getChannels();
-			
-			for (int i=0;i<channels.length;i++){
-				
-				RSSChannel	channel = channels[i];
-				
-				System.out.println( "chan: title = " + channel.getTitle() + ", desc = " + channel.getDescription() +
-									", link = " + channel.getLink() + ", pub = " + channel.getPublicationDate());
-				
-				RSSItem[]	items = channel.getItems();
-				
-				for (int j=0;j<items.length;j++){
-					
-					RSSItem	item = items[j];
-					
-					System.out.println( "    item:" + item.getTitle() + ", desc = " + item.getDescription() + ", link = " + item.getLink());
-					
-					SimpleXMLParserDocumentNode	node = item.getNode();
-					
-					System.out.println( "        [hash] " + node.getChild( "torrent_sha1" ).getValue());
-					System.out.println( "        [size] " + node.getChild( "torrent_size" ).getValue());
-					System.out.println( "        [seed] " + node.getChild( "torrent_seeders" ).getValue());
-					System.out.println( "        [leec] " + node.getChild( "torrent_leechers" ).getValue());
-				}
-			}
-							
-		}catch( Throwable e ){
-			
-			e.printStackTrace();
-		}
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		getSingleton();
-	}
-}
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 4c5e1e3..7a0829a 100644
--- a/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/local/utils/xml/simpleparser/SimpleXMLParserDocumentImpl.java
@@ -31,6 +31,9 @@ import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentN
 import org.w3c.dom.*;
 
 import java.io.*;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
 import java.util.*;
 
 public class 
@@ -142,6 +145,35 @@ SimpleXMLParserDocumentImpl
 
 			db.setErrorHandler( error_handler );
 
+			db.setEntityResolver(
+				new EntityResolver()
+				{
+					public InputSource 
+					resolveEntity(
+						String publicId, String systemId )
+					{
+						// System.out.println( publicId + ", " + systemId );
+						
+						// handle bad DTD external refs
+						
+						try{
+							String host = new URL( systemId ).getHost();
+							
+							InetAddress.getByName( host );
+							
+							return( null );
+							
+						}catch( UnknownHostException e ){
+							
+							return new InputSource(	new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
+							
+						}catch( Throwable e ){
+							
+							return( null );
+						}
+					}
+				});
+	
 			// Step 3: parse the input file
 					
 			document = db.parse( input_stream );
@@ -171,7 +203,7 @@ SimpleXMLParserDocumentImpl
 						
 		}catch( Throwable e ){
 			
-			// e.printStackTrace();
+			e.printStackTrace();
 			
 			throw( new SimpleXMLParserDocumentException( e ));
 		}
diff --git a/org/gudy/azureus2/pluginsimpl/remote/RPPluginInterface.java b/org/gudy/azureus2/pluginsimpl/remote/RPPluginInterface.java
index b0a6ae8..d19d95d 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/RPPluginInterface.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/RPPluginInterface.java
@@ -228,12 +228,6 @@ RPPluginInterface
   		return Constants.APP_NAME;
   	}
 	
-	public void 
-	addView(PluginView view)
-	{
-		notSupported();
-	}
-	
 	public void addConfigUIParameters(Parameter[] parameters, String displayName)
 	{
 		notSupported();
@@ -363,6 +357,13 @@ RPPluginInterface
 		return( null );
 	}
 	
+	public String getPerUserPluginDirectoryName()
+	{
+		notSupported();
+		
+		return( null );
+	}
+
 	public boolean
 	isShared()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/remote/disk/RPDiskManagerFileInfo.java b/org/gudy/azureus2/pluginsimpl/remote/disk/RPDiskManagerFileInfo.java
index 0b6f585..6cea63a 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/disk/RPDiskManagerFileInfo.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/disk/RPDiskManagerFileInfo.java
@@ -26,6 +26,8 @@ import java.io.File;
 
 import org.gudy.azureus2.plugins.disk.DiskManagerChannel;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
+import org.gudy.azureus2.plugins.disk.DiskManagerRandomReadRequest;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadException;
 import org.gudy.azureus2.pluginsimpl.remote.RPException;
@@ -118,6 +120,22 @@ RPDiskManagerFileInfo
 	{
 		notSupported();
 	}
+	
+	public int 
+	getNumericPriorty() 
+	{
+		notSupported();
+		
+		return( 0 );
+	}
+	
+	public void 
+	setNumericPriority(
+		int priority) 
+	{
+		notSupported();
+	}
+	
 	public void
 	setDeleted(boolean b)
 	{
@@ -151,6 +169,18 @@ RPDiskManagerFileInfo
 		return( file );
 	}
 		
+	public File
+	getFile(
+		boolean	follow_link )
+	{
+		if ( follow_link ){
+			
+			notSupported();
+		}
+
+		return( file );
+	}		
+	
 	public int getFirstPieceNumber()
 	{
 		return( first_piece_number );
@@ -225,4 +255,18 @@ RPDiskManagerFileInfo
 		
 		return( null );		
 	}
+	
+	public DiskManagerRandomReadRequest
+	createRandomReadRequest(
+		long						file_offset,
+		long						length,
+		boolean						reverse_order,
+		DiskManagerListener			listener )
+	
+		throws DownloadException
+	{
+		notSupported();
+		
+		return( null );		
+	}
 }
diff --git a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
index fd152fa..ed3e7ce 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownload.java
@@ -33,6 +33,7 @@ import org.gudy.azureus2.plugins.disk.DiskManager;
 import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.plugins.download.*;
 import org.gudy.azureus2.plugins.download.savelocation.*;
+import org.gudy.azureus2.plugins.network.RateLimiter;
 import org.gudy.azureus2.plugins.peers.PeerManager;
 import org.gudy.azureus2.plugins.torrent.*;
 
@@ -798,6 +799,22 @@ RPDownload
   		return(0);
   	}
   	
+	public void
+	addRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		notSupported();
+	}
+		
+	public void
+	removeRateLimiter(
+		RateLimiter		limiter,
+		boolean			is_upload )
+	{
+		notSupported();
+	}
+	
  	public boolean
 	isComplete()
  	{
@@ -822,6 +839,14 @@ RPDownload
  		return( false );
  	}
 	
+	public boolean
+ 	isMoving()
+ 	{
+		notSupported();
+		
+		return( false );
+ 	}
+	
 	public PeerManager
 	getPeerManager()
 	{
@@ -855,7 +880,32 @@ RPDownload
 		
 		return( resp );
 	}
+
+	public DiskManagerFileInfo
+	getDiskManagerFileInfo(int index)
+	{
+		// TODO: Make it only return the index one
+
+		RPDiskManagerFileInfo[] resp = (RPDiskManagerFileInfo[])_dispatcher.dispatch( 
+				new RPRequest( 
+						this, 
+						"getDiskManagerFileInfo", 
+						null)).getResponse();
+
+		if (index >= 0 && index < resp.length) {
+			resp[index]._setRemote( _dispatcher );
+			return resp[index];
+		}
+		
+		return( null );
+	}
 	
+	public int 
+	getDiskManagerFileCount() {
+		notSupported();
+		return 0;
+	}
+
 	public long
 	getCreationTime()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadManager.java b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadManager.java
index a569c0d..e5227d3 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadManager.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadManager.java
@@ -316,6 +316,25 @@ RPDownloadManager
 		return( null );
 	}
 	
+	public Download 
+	addNonPersistentDownloadStopped(
+		Torrent torrent,
+		File torrentLocation, 
+		File dataLocation) 
+		
+		throws DownloadException 
+	{
+		notSupported();
+		
+		return( null );
+	}
+	
+	public void 
+	clearNonPersistentDownloadState(
+		byte[] hash) 
+	{
+		notSupported();
+	}
 	
 	public Download
 	getDownload(
diff --git a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadStats.java b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadStats.java
index 47d671c..7eeffaa 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadStats.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/download/RPDownloadStats.java
@@ -172,6 +172,14 @@ RPDownloadStats
 		return( 0 );
 	}
 
+	public void
+	resetUploadedDownloaded(
+		long l1, 
+		long l2 )
+	{
+		notSupported();
+	}
+	
 	public long
 	getDownloaded()
 	{
diff --git a/org/gudy/azureus2/pluginsimpl/remote/tracker/RPTracker.java b/org/gudy/azureus2/pluginsimpl/remote/tracker/RPTracker.java
index 5c340ab..17647ea 100644
--- a/org/gudy/azureus2/pluginsimpl/remote/tracker/RPTracker.java
+++ b/org/gudy/azureus2/pluginsimpl/remote/tracker/RPTracker.java
@@ -276,6 +276,14 @@ RPTracker
 		return( null );				
 	}
 	
+	public InetAddress 
+	getBindIP()
+	{
+	   	notSupported();
+		
+		return( null );		
+	}
+	
 	public void
 	addPageGenerator(
 		TrackerWebPageGenerator	generator )
diff --git a/org/gudy/azureus2/pluginsimpl/update/PluginUpdatePlugin.java b/org/gudy/azureus2/pluginsimpl/update/PluginUpdatePlugin.java
index ff6604e..17811c5 100644
--- a/org/gudy/azureus2/pluginsimpl/update/PluginUpdatePlugin.java
+++ b/org/gudy/azureus2/pluginsimpl/update/PluginUpdatePlugin.java
@@ -37,6 +37,8 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 
 import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.installer.InstallablePlugin;
+import org.gudy.azureus2.plugins.installer.PluginInstallationListener;
 import org.gudy.azureus2.plugins.installer.PluginInstaller;
 import org.gudy.azureus2.plugins.installer.StandardPlugin;
 import org.gudy.azureus2.plugins.logging.*;
@@ -46,6 +48,7 @@ import org.gudy.azureus2.plugins.ui.*;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.plugins.ui.model.*;
 import org.gudy.azureus2.pluginsimpl.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.update.sf.*;
 import org.gudy.azureus2.update.CorePatchChecker;
 
@@ -79,6 +82,10 @@ PluginUpdatePlugin
 
 		log = plugin_interface.getLogger().getChannel("Plugin Update");
 
+		log.setDiagnostic();
+		
+		log.setForce( true );
+		
 		UIManager	ui_manager = plugin_interface.getUIManager();
 		
 		final BasicPluginViewModel model = 
@@ -199,7 +206,9 @@ PluginUpdatePlugin
 				{
 					if ( checkForUpdateSupport( checker, null, false ) == 0 ){
 						
-						String[] rps = VersionCheckClient.getSingleton(). getRecommendedPlugins();
+						VersionCheckClient vc = VersionCheckClient.getSingleton();
+						
+						String[] rps = vc.getRecommendedPlugins();
 						
 						boolean	found_one = false;
 						
@@ -267,6 +276,172 @@ PluginUpdatePlugin
 								break;
 							}
 						}
+						
+						if ( !found_one ){
+							
+							Set<String>	auto_install = vc.getAutoInstallPluginIDs();
+							
+							final List<String>	to_do = new ArrayList<String>();
+							
+							for ( String pid: auto_install ){
+								
+								if ( plugin_manager.getPluginInterfaceByID( pid, false ) == null ){
+									
+									to_do.add( pid );
+								}
+							}
+							
+							if ( to_do.size() > 0 ){
+								
+								new AEThread2( "pup:autoinst" )
+								{
+									public void 
+									run() 
+									{		
+										try{
+											Thread.sleep( 120*1000 );
+											
+										}catch( Throwable e ){
+											
+											Debug.out( e );
+											
+											return;
+										}
+										
+										UpdateManager update_manager = plugin_interface.getUpdateManager();
+										
+										final List<UpdateCheckInstance>	l_instances = new ArrayList<UpdateCheckInstance>();
+										
+										update_manager.addListener( 
+											new UpdateManagerListener()
+											{
+												public void
+												checkInstanceCreated(
+													UpdateCheckInstance	instance )
+												{
+													synchronized( l_instances ){
+														
+														l_instances.add( instance );
+													}
+												}
+											});
+										
+										UpdateCheckInstance[] instances = update_manager.getCheckInstances();
+										
+										l_instances.addAll( Arrays.asList( instances ));
+										
+										long start = SystemTime.getMonotonousTime();
+										
+										while( true ){
+											
+											if ( SystemTime.getMonotonousTime() - start >= 5*60*1000 ){
+												
+												break;
+											}
+											
+											try{
+												Thread.sleep(5000);
+												
+											}catch( Throwable e ){
+												
+												Debug.out( e );
+												
+												return;
+											}
+											
+											if ( l_instances.size() > 0 ){
+											
+												boolean	all_done = true;
+												
+												for ( UpdateCheckInstance instance: l_instances ){
+													
+													if ( !instance.isCompleteOrCancelled()){
+														
+														all_done = false;
+														
+														break;
+													}
+												}
+												
+												if ( all_done ){
+													
+													break;
+												}
+											}
+										}
+										
+										if ( update_manager.getInstallers().length > 0 ){
+											
+											return;
+										}
+										
+										PluginInstaller installer = plugin_interface.getPluginManager().getPluginInstaller();
+										
+										List<InstallablePlugin>	sps = new ArrayList<InstallablePlugin>();
+										
+										for ( String pid: to_do ){
+											
+											try{
+												StandardPlugin sp = installer.getStandardPlugin( pid );
+												
+												if ( sp != null ){
+													
+													log.log( "Auto-installing " + pid );
+													
+													sps.add( sp );
+													
+												}else{
+													
+													log.log( "Standard plugin '" + pid + "' missing" );
+												}
+											}catch( Throwable e ){
+												
+												log.log( "Standard plugin '" + pid + "' missing", e );
+											}
+										}	
+								 		
+										if ( sps.size() > 0 ){
+											
+											Map<Integer, Object> properties = new HashMap<Integer, Object>();
+									
+											properties.put( UpdateCheckInstance.PT_UI_STYLE, UpdateCheckInstance.PT_UI_STYLE_NONE );
+												
+											properties.put(UpdateCheckInstance.PT_UI_DISABLE_ON_SUCCESS_SLIDEY, true);
+	
+											try{
+												installer.install(
+													sps.toArray( new InstallablePlugin[ sps.size()]),
+													false,
+													properties,
+													new PluginInstallationListener() {
+		
+														public void
+														completed()
+														{
+														}
+														
+														public void
+														cancelled()
+														{
+														}
+														
+														public void
+														failed(
+															PluginException	e )
+														{
+			
+														}
+													});
+												
+											}catch( Throwable e ){
+												
+												log.log( "Auto install failed", e );
+											}
+										}
+									};
+								}.start();
+							}
+						}
 					}
 				}
 				
@@ -795,6 +970,16 @@ PluginUpdatePlugin
 						log.removeListener( list );
 					}
 				}
+				
+				public void
+				failed(
+					ResourceDownloader			downloader,
+					ResourceDownloaderException e )
+				{
+					Debug.out( downloader.getName() + " failed", e );
+					
+					update.complete( false );
+				}
 			});	
 		
 		return( update );
@@ -819,6 +1004,8 @@ PluginUpdatePlugin
 
 		UpdateInstaller	installer	= null;
 		
+		boolean	update_successful = false;
+		
 		try{
 		
 			data = update.verifyData( data, verify );
@@ -847,6 +1034,8 @@ PluginUpdatePlugin
 				final File	user_dir	= new File( plugin_interface.getUtilities().getAzureusUserDir());
 				final File	prog_dir	= new File( plugin_interface.getUtilities().getAzureusProgramDir());
 	
+				Map<String,List<String[]>> install_properties = new HashMap<String, List<String[]>>();
+				
 					// .jar files get copied straight in with the right version number
 					// .zip files need to be unzipped. There are various possibilities for
 					// target dir depending on the contents of the zip file. Basically we
@@ -948,7 +1137,70 @@ PluginUpdatePlugin
 							
 							String	name = entry.getName();
 							
-							if ( !( name.equals( "azureus.sig" ) || name.endsWith("/"))){
+							
+							if ( name.equals( "plugin_install.properties" )){
+								
+								ByteArrayOutputStream baos = new ByteArrayOutputStream( 32*1024 );
+								
+								byte[]	buffer = new byte[65536];
+								
+								while( true ){
+								
+									int	len = zis.read( buffer );
+									
+									if ( len <= 0 ){
+										
+										break;
+									}
+																			
+									baos.write( buffer, 0, len );
+								}
+										
+								try{
+									LineNumberReader lnr = new LineNumberReader( new InputStreamReader( new ByteArrayInputStream( baos.toByteArray()), "UTF-8"));
+									
+									while( true ){
+										
+										String	line = lnr.readLine();
+										
+										if ( line == null ){
+											
+											break;
+										}
+										
+										line = line.trim();
+										
+										if ( line.endsWith( "defer_install" )){
+											
+											force_indirect_install = true;
+											
+										}else{
+											
+											String[] command = line.split( "," );
+											
+											if ( command.length > 1 ){
+												
+												List<String[]> commands = install_properties.get( command[0] );
+												
+												if ( commands == null ){
+													
+													commands = new ArrayList<String[]>();
+													
+													install_properties.put( command[0], commands );
+												}
+												
+												commands.add( command );
+											}
+										}
+									}
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+								
+								continue;
+								
+							}else if ( !( name.equals( "azureus.sig" ) || name.endsWith("/"))){
 								
 								if ( common_prefix == null ){
 									
@@ -1482,7 +1734,7 @@ PluginUpdatePlugin
 											
 											throw( new IOException( "Failed to rename '" + tmp_file.toString() + "' to '" + initial_target.toString() + "'" ));
 										}
-										
+																				
 										bak_file.delete();
 									}
 									
@@ -1562,20 +1814,68 @@ PluginUpdatePlugin
 						// create installation move actions for the files that have been installed
 						// into temp location
 					
-					addInstallationActions( installer, target_plugin_dir, plugin_dir );
-					addInstallationActions( installer, target_prog_dir, prog_dir );
-					addInstallationActions( installer, target_user_dir, user_dir );					
+					boolean	defer_restart = false;
+					
+					if ( addInstallationActions( installer, install_properties, "%plugin%", target_plugin_dir, plugin_dir )){
+						
+						defer_restart = true;
+					}
+					
+					if ( addInstallationActions( installer, install_properties, "%app%", target_prog_dir, prog_dir )){
+						
+						defer_restart = true;
+					}
+					
+					if ( addInstallationActions( installer, install_properties, "%user%", target_user_dir, user_dir )){
+						
+						defer_restart = true;
+					}
 				
+					if ( defer_restart && update.getRestartRequired() == Update.RESTART_REQUIRED_YES ){
+						
+						log.log( "Deferring restart for '" + plugin.getPluginID() + "'" );
+						
+						update.setRestartRequired( Update.RESTART_REQUIRED_NO );
+					}
+					
 						// don't delete temp store, it'll get deleted on restart
 					
-				}else if ( unloadable ){
+				}else{
 					
-					log.log( "Plugin initialising, please wait... " );
+					boolean	defer_restart = false;
 					
-					plugin.getPluginState().reload();	// this will reload all if > 1 defined
+					if ( applyInstallProperties( install_properties, "%plugin%", plugin_dir )){
+						
+						defer_restart = true;
+					}
 					
-					log.log( "... initialisation complete." );
-	
+					if ( applyInstallProperties( install_properties, "%app%", prog_dir )){
+						
+						defer_restart = true;
+					}
+					
+					if ( applyInstallProperties( install_properties, "%user%", user_dir )){
+						
+						defer_restart = true;
+					}
+					
+					if ( unloadable ){
+					
+						log.log( "Plugin initialising, please wait... " );
+						
+						plugin.getPluginState().reload();	// this will reload all if > 1 defined
+						
+						log.log( "... initialisation complete." );
+						
+					}else{
+						
+						if ( defer_restart && update.getRestartRequired() == Update.RESTART_REQUIRED_YES ){
+							
+							log.log( "Deferring restart for '" + plugin.getPluginID() + "'" );
+							
+							update.setRestartRequired( Update.RESTART_REQUIRED_NO );
+						}
+					}
 				}	
 			}
 			
@@ -1593,6 +1893,20 @@ PluginUpdatePlugin
 				
 				log.logAlertRepeatable( update_txt_found?LoggerChannel.LT_WARNING:LoggerChannel.LT_INFORMATION, msg );			
 			}
+			
+			try{
+				String plugin_id = plugin.getPluginID();
+					
+				PluginInitializer.fireEvent(
+					checker.getCheckInstance().getType() == UpdateCheckInstance.UCI_INSTALL?PluginEvent.PEV_PLUGIN_INSTALLED:PluginEvent.PEV_PLUGIN_UPDATED,
+					plugin_id );
+					
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+			}
+			update_successful = true;
+			
 		}catch( Throwable e ){
 					
 			String msg =   "Version " + version + " of plugin '" + 	update.getName() + "' " +
@@ -1602,18 +1916,22 @@ PluginUpdatePlugin
 			
 		}finally{
 			
-			update.complete();
+			update.complete( update_successful );
 		}
 	}
-	
-	protected void
+		
+	protected boolean
 	addInstallationActions(
-		UpdateInstaller		installer,
-		File				from_file,
-		File				to_file )
+		UpdateInstaller				installer,
+		Map<String,List<String[]>>	install_properties,
+		String						prefix,
+		File						from_file,
+		File						to_file )
 	
 		throws UpdateException
 	{
+		boolean	defer_restart = false;
+		
 		if ( from_file.isDirectory()){
 			
 			File[]	files = from_file.listFiles();
@@ -1621,16 +1939,179 @@ PluginUpdatePlugin
 			if ( files != null ){
 				
 				for (int i=0;i<files.length;i++){
-					
-					addInstallationActions( installer, files[i], new File( to_file, files[i].getName()));
+										
+					if ( addInstallationActions( installer, install_properties, prefix + "/" + files[i].getName(), files[i], new File( to_file, files[i].getName()))){
+						
+						defer_restart = true;
+					}
 				}
 			}
 		}else{
 			
 			installer.addMoveAction( from_file.getAbsolutePath(), to_file.getAbsolutePath());
+			
+			List<String[]> commands = install_properties.get( prefix );
+			
+			if ( commands != null ){
+				
+				for( String[] command: commands ){
+					
+					String	cmd = command[1];
+					
+					if ( cmd.equals( "chmod" )){
+						
+						if ( !Constants.isWindows ){
+							
+							log.log( "Applying " + cmd + " " + command[2] + " to " + to_file );
+							
+							installer.addChangeRightsAction( command[2], to_file.getAbsolutePath());
+						}
+					}else if ( cmd.equals( "rm" )){
+						
+						log.log( "Deleting " + to_file );
+						
+						installer.addRemoveAction( to_file.getAbsolutePath());
+						
+					}else if ( cmd.equals( "defer_restart" )){
+						
+						defer_restart = true;
+					}
+				}
+			}
+		}
+		
+		return( defer_restart );
+	}
+		
+	protected boolean
+	applyInstallProperties(
+		Map<String,List<String[]>>	install_properties,
+		String						prefix,
+		File						to_file )
+	{
+		boolean	defer_restart = false;
+
+		if ( to_file.isDirectory()){
+			
+			File[]	files = to_file.listFiles();
+			
+			if ( files != null ){
+				
+				for (int i=0;i<files.length;i++){
+							
+					File file = files[i];
+					
+					String	file_name = file.getName();
+					
+					if ( file_name.equals( "." ) || file_name.equals( ".." )){
+						
+						continue;
+					}
+					
+					String	new_prefix = prefix + "/" + file_name;
+					
+					boolean	match = false;
+					
+					for ( String s: install_properties.keySet()){
+					
+						if ( s.startsWith( new_prefix )){
+							
+							match = true;
+							
+							break;
+						}
+					}
+					
+					if ( match ){
+					
+						if ( applyInstallProperties( install_properties, new_prefix, files[i] )){
+							
+							defer_restart = true;
+						}
+					}
+				}
+			}
+		}else{
+						
+			List<String[]> commands = install_properties.get( prefix );
+
+			if ( commands != null ){
+				
+				for( String[] command: commands ){
+					
+					String	cmd = command[1];
+					
+					if ( cmd.equals( "chmod" )){
+						
+						if ( !Constants.isWindows ){
+							
+							runCommand(
+								new String[]{
+									"chmod",
+									command[2],
+									to_file.getAbsolutePath().replaceAll(" ", "\\ ")
+								});
+						}
+					}else if ( cmd.equals( "rm" )){
+						
+						log.log( "Deleting " + to_file );
+						
+						to_file.delete();
+
+					}else if ( cmd.equals( "defer_restart" )){
+						
+						defer_restart = true;
+					}
+				}
+			}
+		}
+		
+		return( defer_restart );
+	}
+	
+	private void
+	runCommand(
+		String[]	command )
+	{
+		try{
+			command[0] = findCommand( command[0] );
+		
+			String	str = "";
+			
+			for ( String s: command ){
+				
+				str += " " + s;
+			}
+			
+			log.log( "Executing" + str );
+			
+			Runtime.getRuntime().exec( command ).waitFor();
+			
+		}catch( Throwable e ){
+			
+			log.log( "Failed to execute command", e );
 		}
 	}
 	
+	private String
+	findCommand(
+		String	name )
+	{
+		final String[]  locations = { "/bin", "/usr/bin" };
+
+		for ( String s: locations ){
+
+			File f = new File( s, name );
+
+			if ( f.exists() && f.canRead()){
+
+				return( f.getAbsolutePath());
+			}
+		}
+
+		return( name );
+	}
+	
 	protected boolean
 	isVersioned(
 		String	name )
diff --git a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java b/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
index 0aa95c0..4a30c94 100644
--- a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
+++ b/org/gudy/azureus2/pluginsimpl/update/sf/impl2/SFPluginDetailsLoaderImpl.java
@@ -30,23 +30,27 @@ package org.gudy.azureus2.pluginsimpl.update.sf.impl2;
 import java.util.*;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.io.IOException;
 import java.io.InputStream;
 
 import org.gudy.azureus2.platform.PlatformManager;
 import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginState;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
 import org.gudy.azureus2.pluginsimpl.update.sf.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.html.*;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEMonitor;
 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.core3.util.SystemTime;
+import org.gudy.azureus2.core3.util.UrlUtils;
 import org.gudy.azureus2.core3.logging.*;
 
 import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
@@ -97,6 +101,19 @@ SFPluginDetailsLoaderImpl
 			
 			base_url_params += "&java=" + URLEncoder.encode(System.getProperty( "java.version" ),"UTF-8" );
 			
+			  try {
+			      Class c = Class.forName( "org.eclipse.swt.SWT" );
+			      
+			      String swt_platform = (String)c.getMethod( "getPlatform", new Class[]{} ).invoke( null, new Object[]{} );
+			      
+			      base_url_params += "&swt_platform=" + swt_platform;
+			      
+			      Integer swt_version = (Integer)c.getMethod( "getVersion", new Class[]{} ).invoke( null, new Object[]{} );
+			      
+			      base_url_params += "&swt_version=" + swt_version;
+			      
+			  }catch( Throwable e ){
+			  }
 		}catch( Throwable e ){
 			
 			Debug.printStackTrace(e);
@@ -172,8 +189,10 @@ SFPluginDetailsLoaderImpl
 	
 		throws SFPluginDetailsException
 	{
-		try{			
-			ResourceDownloader dl = rd_factory.create( new URL(page_url));
+		try{
+			String	page_url_to_use = addEPIDS( page_url );
+			
+			ResourceDownloader dl = rd_factory.create( new URL(page_url_to_use));
 			
 			dl = rd_factory.getRetryDownloader( dl, 5 );
 			
@@ -249,171 +268,132 @@ SFPluginDetailsLoaderImpl
 		}
 	}
 	
-	protected void
-	loadPluginDetails(
-		SFPluginDetailsImpl		details )
-	
-		throws SFPluginDetailsException
+	private String
+	addEPIDS(
+		String	str )
 	{
 		try{
-			ResourceDownloader p_dl = rd_factory.create( new URL( site_prefix + "plugin_details.php?plugin=" + details.getId() + "&" + base_url_params ));
-		
-			p_dl = rd_factory.getRetryDownloader( p_dl, 5 );
-		
-			p_dl.addListener( this );
-
-			HTMLPage	plugin_page = HTMLPageFactory.loadPage( p_dl.download(), "UTF-8" );
-			
-			if ( !processPluginPage( details, plugin_page )){
-							
-				throw( new SFPluginDetailsException( "Plugin details load fails for '" + details.getId() + "': data not found" ));
-			}
-					
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-			
-			throw( new SFPluginDetailsException( "Plugin details load fails", e ));
-		}
-	}
-	
-	protected boolean
-	processPluginPage(
-		SFPluginDetailsImpl		details,
-		HTMLPage				page )
-	
-		throws SFPluginDetailsException
-	{
-		HTMLTable[]	tables = page.getTables();
-		
-		// dumpTables("", tables );
-		
-		return( processPluginPage( details, tables ));
-	}
-	
-	protected boolean
-	processPluginPage(
-		SFPluginDetailsImpl		details,
-		HTMLTable[]				tables )
-	
-		throws SFPluginDetailsException
-	{
-		for (int i=0;i<tables.length;i++){
+			String pids = "";
 			
-			HTMLTable	table = tables[i];
+			PluginInterface[] pis = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaces();
 			
-			HTMLTableRow[]	rows = table.getRows();
-		
-			if ( rows.length == 10 ){
-				
-				HTMLTableCell[]	cells = rows[0].getCells();
-				
-				if ( cells.length == 6 &&
-						cells[0].getContent().trim().equals("Name") &&
-						cells[5].getContent().trim().equals("Contact")){
+			for ( PluginInterface pi: pis ){
 				
-					
-					// got the plugin details table
+				PluginState ps = pi.getPluginState();
 				
-					HTMLTableCell[]	detail_cells = rows[2].getCells();
-					
-					//String	plugin_name			= detail_cells[0].getContent();
-					//String	plugin_version		= detail_cells[1].getContent();
-					String	plugin_auth			= detail_cells[4].getContent();
+				if ( !( ps.isBuiltIn() || ps.isDisabled())){
 					
-					String[]	dl_links = detail_cells[2].getLinks();
+					String version = pi.getPluginVersion();
 					
-					String	plugin_download;
-					
-					if ( dl_links.length == 0 ){
+					if ( version != null && Constants.compareVersions( version, "0" ) > 0 ){
 						
-						plugin_download	= "<unknown>";
+						String pid = pi.getPluginID();
 						
-					}else{
-						
-						plugin_download = site_prefix + dl_links[0];
-					}
+						if ( pid != null && pid.length() > 0 ){
 					
-					HTMLTableCell[]	cvs_detail_cells = rows[3].getCells();
-
-					// String	plugin_cvs_version		= cvs_detail_cells[1].getContent();
-
-					String[]	cvs_dl_links 		= cvs_detail_cells[2].getLinks();
-					
-					String	plugin_cvs_download;
-					
-					if ( cvs_dl_links.length == 0 ){
-						
-						plugin_cvs_download	= "<unknown>";
-						
-					}else{
-						
-						plugin_cvs_download = site_prefix + cvs_dl_links[0];
-					}
-					
-					String info_url = null;
-					if (rows[9].getCells().length > 1) {
-						info_url = rows[9].getCells()[1].getContent();
+							pids += pid + ":";
+						}
 					}
-
-
-					// System.out.println( "got plugin:" + plugin_name + "/" + plugin_version + "/" + plugin_download + "/" + plugin_auth );
-					
-					details.setDetails(
-									plugin_download,
-									plugin_auth,
-									plugin_cvs_download,
-									rows[6].getCells()[0].getContent(),
-									rows[9].getCells()[0].getContent(),
-									info_url);
-					
-					return( true );
 				}
 			}
+
+			str += "&epids=" + UrlUtils.encode( pids );
 			
-			HTMLTable[]	sub_tables = table.getTables();
-			
-			boolean	res = processPluginPage( details, sub_tables );
+		}catch( Throwable e ){
 			
-			if( res ){
-				
-				return( res );
-			}
+			Debug.out( e );
 		}
 		
-		return( false );
+		return( str );
 	}
 	
 	protected void
-	dumpTables(
-		String			indent,
-		HTMLTable[]		tables )
+	loadPluginDetails(
+		SFPluginDetailsImpl		details )
+	
+		throws SFPluginDetailsException
 	{
-		for (int i=0;i<tables.length;i++){
-			
-			HTMLTable	tab = tables[i];
-			
-			System.out.println( indent + "tab:" + tab.getContent());
+		try{			
+			String page_url_to_use = site_prefix + "update/pluginlist3.php?plugin="
+					+ UrlUtils.encode(details.getId()) + "&" + base_url_params;
 			
-			HTMLTableRow[] rows = tab.getRows();
+			page_url_to_use = addEPIDS( page_url_to_use );
 			
-			for (int j=0;j<rows.length;j++){
-				
-				HTMLTableRow	row = rows[j];
-				
-				System.out.println( indent + "  row[" + j + "]: " + rows[j].getContent());
-				
-				HTMLTableCell[]	cells = row.getCells();
-				
-				for (int k=0;k<cells.length;k++){
-					
-					System.out.println( indent + "    cell[" + k + "]: " + cells[k].getContent());
+			try{
+				PluginInterface defPI = PluginInitializer.getDefaultInterface();
+				PluginInterface pi = defPI == null ? null : defPI.getPluginManager().getPluginInterfaceByID( details.getId(), false );
+	
+				if ( pi != null ){
 					
+					String existing_version = pi.getPluginVersion();
+				
+					if ( existing_version != null ){
+						
+						page_url_to_use += "&ver_" + details.getId() + "=" + UrlUtils.encode( existing_version );
+					}
 				}
+			}catch( Throwable e ){
+				
+				Debug.out( e );
 			}
 			
-			dumpTables( indent + "  ", tab.getTables());
+			ResourceDownloader p_dl = rd_factory.create( new URL( page_url_to_use ));
+		
+			p_dl = rd_factory.getRetryDownloader( p_dl, 5 );
+		
+			p_dl.addListener( this );
+			
+			InputStream is = p_dl.download();
+
+			try {
+  			if ( !processPluginStream( details, is )){
+  							
+  				throw( new SFPluginDetailsException( "Plugin details load fails for '" + details.getId() + "': data not found" ));
+  			}
+			} finally {
+				is.close();
+			}
+					
+		}catch( Throwable e ){
+			
+			Debug.printStackTrace( e );
+			
+			throw( new SFPluginDetailsException( "Plugin details load fails", e ));
+		}
+	}
+
+	protected boolean
+	processPluginStream(SFPluginDetailsImpl details, InputStream is) {
+    Properties properties = new Properties();
+    try {
+			properties.load(is);
+			
+			String pid = details.getId();
+			
+			String download_url = properties.getProperty(pid + ".dl_link", "");
+			download_url = download_url.length() == 0 ? "<unknown>" : site_prefix + download_url;
+
+			String author = properties.getProperty(pid + ".author", "");
+			String desc = properties.getProperty(pid + ".description", "");
+			String cvs_download_url = properties.getProperty(pid + ".dl_link_cvs", null);
+			cvs_download_url = cvs_download_url.length() == 0 ? "<unknown>" : site_prefix + cvs_download_url;
+
+			String comment = properties.getProperty(pid + ".comment", "");
+			// I don't think this one is ever set (not even in the old html scraping code)
+			String info_url = properties.getProperty(pid + ".info_url", null);
+
+			details.setDetails(
+					download_url,
+					author,
+					cvs_download_url,
+					desc,
+					comment,
+					info_url);
+			return true;
+		} catch (IOException e) {
+			Debug.out(e);
 		}
+		return false;
 	}
 	
 	public String[]
diff --git a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/Test.java b/org/gudy/azureus2/pluginsimpl/update/sf/impl2/Test.java
deleted file mode 100644
index 631b893..0000000
--- a/org/gudy/azureus2/pluginsimpl/update/sf/impl2/Test.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Created on 27-Apr-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 org.gudy.azureus2.pluginsimpl.update.sf.impl2;
-
-/**
- * @author parg
- *
- */
-
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.pluginsimpl.update.sf.*;
-
-public class 
-Test 
-{
-	public static void
-	main(
-		String[]	args )
-	{
-		SFPluginDetailsLoader dl = SFPluginDetailsLoaderFactory.getSingleton();
-		
-		try{
-			String[]	keys = dl.getPluginIDs();
-			
-			for (int i=0;i<keys.length;i++){
-				
-				SFPluginDetails det = dl.getPluginDetails( keys[i] );
-				
-				System.out.println( "key = " + keys[i] + ", version = " + det.getVersion());
-			
-				System.out.println( "parp = " + det.getDownloadURL());
-			}
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-	}
-}
diff --git a/org/gudy/azureus2/ui/common/UIInstanceBase.java b/org/gudy/azureus2/ui/common/UIInstanceBase.java
new file mode 100644
index 0000000..6474bdb
--- /dev/null
+++ b/org/gudy/azureus2/ui/common/UIInstanceBase.java
@@ -0,0 +1,18 @@
+package org.gudy.azureus2.ui.common;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIInstance;
+
+/** 
+ * Stuff that all UIInstances need to implements, but not visible to plugins
+ * 
+ */
+public interface UIInstanceBase extends UIInstance
+{
+
+	/**
+	 * PluginInterface is unloading.. destroy anything related to it
+	 */
+	public void unload(PluginInterface pi);
+
+}
diff --git a/org/gudy/azureus2/ui/common/util/MenuItemManager.java b/org/gudy/azureus2/ui/common/util/MenuItemManager.java
index f913c83..f76cd05 100644
--- a/org/gudy/azureus2/ui/common/util/MenuItemManager.java
+++ b/org/gudy/azureus2/ui/common/util/MenuItemManager.java
@@ -46,12 +46,14 @@ public class MenuItemManager {
 	 *    key = MENU_* type (see MenuManager in the plugin API)
 	 *    value = Map: key = menu key value = MenuItem object
 	 */
-	private Map items;
+	private Map<String, Map<String, MenuItem>> items;
 
 	private AEMonitor items_mon = new AEMonitor("MenuManager:items");
+	
+	private ArrayList<MenuItemManagerListener> listeners = new ArrayList<MenuItemManagerListener>(0);
 
 	private MenuItemManager() {
-		this.items = new HashMap();
+		this.items = new HashMap<String, Map<String, MenuItem>>();
 	}
 
 	/**
@@ -74,10 +76,10 @@ public class MenuItemManager {
 			String sMenuID = item.getMenuID();
 			try {
 				this.items_mon.enter();
-				Map mTypes = (Map) this.items.get(sMenuID);
+				Map<String, MenuItem> mTypes = this.items.get(sMenuID);
 				if (mTypes == null) {
 					// LinkedHashMap to preserve order
-					mTypes = new LinkedHashMap();
+					mTypes = new LinkedHashMap<String, MenuItem>();
 					this.items.put(sMenuID, mTypes);
 				}
 				mTypes.put(name, item);
@@ -96,37 +98,84 @@ public class MenuItemManager {
 	}
 	
 	public void removeMenuItem(MenuItem item) {
-		Map menu_item_map = (Map)this.items.get(item.getMenuID());
+		Map<String, MenuItem> menu_item_map = this.items.get(item.getMenuID());
 		if (menu_item_map != null) {menu_item_map.remove(item.getResourceKey());}
 	}
 
 	public MenuItem[] getAllAsArray(String sMenuID) {
-		Map local_menu_item_map = (Map)this.items.get(sMenuID);
-		Map global_menu_item_map = (Map)this.items.get(null);
+		if (sMenuID != null) {
+			triggerMenuItemQuery(sMenuID);
+		}
+		Map<String, MenuItem> local_menu_item_map = this.items.get(sMenuID);
+		Map<String, MenuItem> global_menu_item_map = this.items.get(null);
 		if (local_menu_item_map == null && global_menu_item_map == null) {
 			return new MenuItem[0];
 		}
 		
 		if (sMenuID == null) {local_menu_item_map = null;}
 		
-		ArrayList l = new ArrayList();
+		ArrayList<MenuItem> l = new ArrayList<MenuItem>();
 		if (local_menu_item_map != null) {l.addAll(local_menu_item_map.values());}
 		if (global_menu_item_map != null) {l.addAll(global_menu_item_map.values());}
-		return (MenuItem[]) l.toArray(new MenuItem[l.size()]);
+		return l.toArray(new MenuItem[l.size()]);
 	}
 	
 	public MenuItem[] getAllAsArray(String[] menu_ids) {
-		ArrayList l  = new ArrayList();
+		ArrayList<MenuItem> l  = new ArrayList<MenuItem>();
 		for (int i=0; i<menu_ids.length; i++) {
+			if (menu_ids[i] != null) {
+				triggerMenuItemQuery(menu_ids[i]);
+			}
 			addMenuItems(menu_ids[i], l);
 		}
 		addMenuItems(null, l);
-		return (MenuItem[]) l.toArray(new MenuItem[l.size()]);
+		return l.toArray(new MenuItem[l.size()]);
 	}
 	
-	private void addMenuItems(String menu_id, ArrayList l) {
-		Map menu_map = (Map)this.items.get(menu_id);
+	private void addMenuItems(String menu_id, ArrayList<MenuItem> l) {
+		Map<String, MenuItem> menu_map = this.items.get(menu_id);
 		if (menu_map != null) {l.addAll(menu_map.values());}
 	}
 
+	public void addListener(MenuItemManagerListener l) {
+		synchronized (listeners) {
+			if (!listeners.contains(l)) {
+				listeners.add(l);
+			}
+		}
+	}
+	
+	public void removeListener(MenuItemManagerListener l) {
+		synchronized (listeners) {
+			listeners.remove(l);
+		}
+	}
+	
+	private void triggerMenuItemQuery(String id) {
+		MenuItemManagerListener[] listenersArray;
+		synchronized (listeners) {
+			listenersArray = listeners.toArray(new MenuItemManagerListener[0]);
+		}
+		for (MenuItemManagerListener l : listenersArray) {
+			try {
+				l.queryForMenuItem(id);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
+
+	public void triggerMenuItemCleanup(String id) {
+		MenuItemManagerListener[] listenersArray;
+		synchronized (listeners) {
+			listenersArray = listeners.toArray(new MenuItemManagerListener[0]);
+		}
+		for (MenuItemManagerListener l : listenersArray) {
+			try {
+				l.cleanupMenuItem(id);
+			} catch (Exception e) {
+				Debug.out(e);
+			}
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/common/util/MenuItemManagerListener.java b/org/gudy/azureus2/ui/common/util/MenuItemManagerListener.java
new file mode 100644
index 0000000..47e70d4
--- /dev/null
+++ b/org/gudy/azureus2/ui/common/util/MenuItemManagerListener.java
@@ -0,0 +1,33 @@
+/**
+ * Created on Nov 15, 2010
+ *
+ * Copyright 2010 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.common.util;
+
+/**
+ * @author TuxPaper
+ * @created Nov 15, 2010
+ *
+ */
+public class MenuItemManagerListener
+{
+	public void queryForMenuItem(String id) {
+	}
+
+	public void cleanupMenuItem(String id) {
+	}
+}
diff --git a/org/gudy/azureus2/ui/common/util/UserAlerts.java b/org/gudy/azureus2/ui/common/util/UserAlerts.java
index 3d6c442..ec4cff1 100644
--- a/org/gudy/azureus2/ui/common/util/UserAlerts.java
+++ b/org/gudy/azureus2/ui/common/util/UserAlerts.java
@@ -145,7 +145,8 @@ UserAlerts
 					DownloadManager dm = file.getDownloadManager();
 				
 					if ( 	old_mode == DiskManagerFileInfo.WRITE &&
-							new_mode == DiskManagerFileInfo.READ ){
+							new_mode == DiskManagerFileInfo.READ &&
+							file.getDownloaded() == file.getLength()){
 						
 						if( dm == null || !dm.getDownloadState().getFlag( DownloadManagerState.FLAG_LOW_NOISE )){
 
@@ -201,7 +202,11 @@ UserAlerts
 							String popup_text = MessageText.getString("popup.download.added",
 										new String[] { manager.getDisplayName()
 									});
-								Logger.log(new LogAlert(manager, true, LogAlert.AT_INFORMATION, popup_text));
+							UIFunctionsManager.getUIFunctions().forceNotify(
+									UIFunctions.STATUSICON_NONE, null, popup_text, null,
+									new Object[] {
+										manager
+									}, -1);
 						}
 					}
 				}
@@ -266,27 +271,32 @@ UserAlerts
   			
   			if (COConfigurationManager.getBooleanParameter(popup_enabler)) {
   				String popup_text = MessageText.getString(popup_def_text, new String[]{item_name});
-  				Logger.log(new LogAlert(relatedObject, true, LogAlert.AT_INFORMATION, popup_text));
+					UIFunctionsManager.getUIFunctions().forceNotify(
+							UIFunctions.STATUSICON_NONE, null, popup_text, null,
+							new Object[] {
+								relatedObject
+							}, -1);
   			}
 
-            if(Constants.isOSX) { // OS X cannot concurrently use SWT and AWT
-                new AEThread("DownloadSound") {
-                    public void runSupport()
-                    {
-                        try {
-                            if(COConfigurationManager.getBooleanParameter( speech_enabler ))
-                                Runtime.getRuntime().exec(new String[]{"say", COConfigurationManager.getStringParameter( speech_text )}); // Speech Synthesis services
-
-                            if(COConfigurationManager.getBooleanParameter( sound_enabler ))
-                                Runtime.getRuntime().exec(new String[]{"osascript", "-e" ,"beep"}); // Beep alert type is in accordance with System Preferences
-
-                            Thread.sleep(2500);
-                        }
-                        catch(Throwable e) {}
-                    }
-                }.start();
-            }
-	    	else if( COConfigurationManager.getBooleanParameter( sound_enabler, false)){
+			if (Constants.isOSX
+					&& COConfigurationManager.getBooleanParameter(speech_enabler)) {
+				new AEThread("SaySound") {
+					public void runSupport() {
+						try {
+							if (COConfigurationManager.getBooleanParameter(speech_enabler))
+								Runtime.getRuntime().exec(new String[] {
+									"say",
+									COConfigurationManager.getStringParameter(speech_text)
+								}); // Speech Synthesis services
+
+							Thread.sleep(2500);
+						} catch (Throwable e) {
+						}
+					}
+				}.start();
+			}
+
+        if( COConfigurationManager.getBooleanParameter( sound_enabler, false)){
 
 	    		String	file = COConfigurationManager.getStringParameter( sound_file );
 
diff --git a/org/gudy/azureus2/ui/console/ConsoleInput.java b/org/gudy/azureus2/ui/console/ConsoleInput.java
index 93fa7be..c0d9037 100644
--- a/org/gudy/azureus2/ui/console/ConsoleInput.java
+++ b/org/gudy/azureus2/ui/console/ConsoleInput.java
@@ -89,14 +89,14 @@ public class ConsoleInput extends Thread {
 	private final UserProfile userProfile;
 	
 	/**
-	 * can be used by plugins to register console commands since they may not have access o
+	 * can be used by plugins to register console commands since they may not have access to
 	 * each ConsoleInput object that is created.
 	 */
 	public static void registerPluginCommand(Class clazz)
 	{
-		if( ! clazz.isInstance(IConsoleCommand.class) )
+		if( ! IConsoleCommand.class.isAssignableFrom(clazz))
 		{
-			throw new IllegalArgumentException("Class must be extend IConsoleCommand");
+			throw new IllegalArgumentException("Class must implement IConsoleCommand");
 		}
 		pluginCommands.add( clazz );
 	}
@@ -168,23 +168,25 @@ public class ConsoleInput extends Thread {
 		registerCommands();
 		registerPluginCommands();
 		
-		azureus_core.addLifecycleListener(
-			new AzureusCoreLifecycleAdapter()
-			{
-				public void
-				started(
-					AzureusCore		core )
+		if ( azureus_core != null ){
+			azureus_core.addLifecycleListener(
+				new AzureusCoreLifecycleAdapter()
 				{
-					registerUpdateChecker();
-				}
-			});
-		
+					public void
+					started(
+						AzureusCore		core )
+					{
+						registerUpdateChecker();
+					}
+				});
 	
-		try {
-			loadAliases();
-		} catch (IOException e) {
-			out.println("Error while loading aliases: " + e.getMessage());
+			try {
+				loadAliases();
+			} catch (IOException e) {
+				out.println("Error while loading aliases: " + e.getMessage());
+			}
 		}
+		
 		// populate the old command so that '.' does something sensible first time around
 		oldcommand.add("sh");
 		oldcommand.add("t");
diff --git a/org/gudy/azureus2/ui/console/UI.java b/org/gudy/azureus2/ui/console/UI.java
index 241d521..5de24b5 100644
--- a/org/gudy/azureus2/ui/console/UI.java
+++ b/org/gudy/azureus2/ui/console/UI.java
@@ -18,19 +18,13 @@ import java.net.URL;
 import org.apache.log4j.Logger;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloaderFactory;
-import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.plugins.ui.UIException;
-import org.gudy.azureus2.plugins.ui.UIInputReceiver;
-import org.gudy.azureus2.plugins.ui.UIInstance;
-import org.gudy.azureus2.plugins.ui.UIInstanceFactory;
-import org.gudy.azureus2.plugins.ui.UIManager;
-import org.gudy.azureus2.plugins.ui.UIManagerEvent;
-import org.gudy.azureus2.plugins.ui.UIManagerEventListener;
-import org.gudy.azureus2.plugins.ui.UIMessage;
+import org.gudy.azureus2.plugins.ui.*;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
 import org.gudy.azureus2.ui.common.IUserInterface;
 import org.gudy.azureus2.ui.common.UIConst;
+import org.gudy.azureus2.ui.common.UIInstanceBase;
 import org.gudy.azureus2.ui.console.multiuser.UserManager;
 import org.gudy.azureus2.ui.console.multiuser.commands.UserCommand;
 
@@ -41,7 +35,7 @@ import org.gudy.azureus2.ui.console.multiuser.commands.UserCommand;
 public class 
 UI 
 	extends org.gudy.azureus2.ui.common.UITemplateHeadless 
-	implements IUserInterface, UIInstanceFactory, UIInstance, UIManagerEventListener
+	implements IUserInterface, UIInstanceFactory, UIInstanceBase, UIManagerEventListener
 {
   
   private ConsoleInput console = null;
@@ -287,4 +281,11 @@ UI
 		// TODO Auto-generated method stub
 		return null;
 	}
+
+	public UIToolBarManager getToolBarManager() {
+		return null;
+	}
+
+	public void unload(PluginInterface pi) {
+	}
 }
diff --git a/org/gudy/azureus2/ui/console/commands/Hack.java b/org/gudy/azureus2/ui/console/commands/Hack.java
index a6b91e4..f123b8c 100644
--- a/org/gudy/azureus2/ui/console/commands/Hack.java
+++ b/org/gudy/azureus2/ui/console/commands/Hack.java
@@ -258,15 +258,15 @@ public class Hack extends TorrentCommand
 				String c = (String) args.get(1);
 				if (c.equalsIgnoreCase("normal") || c.equalsIgnoreCase("n")) {
 					files[file - 1].setSkipped(false);
-					files[file - 1].setPriority(false);
+					files[file - 1].setPriority(0);
 					ci.out.println("> Set file '"+files[file - 1].getFile(true).getName()+"' to normal priority.");
 				} else if (c.equalsIgnoreCase("high") || c.equalsIgnoreCase("h") || c.equalsIgnoreCase("+")) {
 					files[file - 1].setSkipped(false);
-					files[file - 1].setPriority(true);
+					files[file - 1].setPriority(1);
 					ci.out.println("> Set file '"+files[file - 1].getFile(true).getName()+"' to high priority.");
 				} else if (c.equalsIgnoreCase("nodownload") || c.equalsIgnoreCase("!") || c.equalsIgnoreCase("-")) {
 					files[file - 1].setSkipped(true);
-					files[file - 1].setPriority(false);
+					files[file - 1].setPriority(0);
 					ci.out.println("> Stopped to download file '"+files[file - 1].getFile(true).getName()+"'.");
 				} else {
 					ci.out.println("> Command 'hack': Unknown priority '" + c + "' for command parameter 'file'.");
diff --git a/org/gudy/azureus2/ui/console/commands/Priority.java b/org/gudy/azureus2/ui/console/commands/Priority.java
index f1439bb..66156f1 100644
--- a/org/gudy/azureus2/ui/console/commands/Priority.java
+++ b/org/gudy/azureus2/ui/console/commands/Priority.java
@@ -193,17 +193,25 @@ public class Priority extends OptionsConsoleCommand {
 				// DEBUG
 //				console.out.println("Setting priority for file " + i + " to " + newprio);
 				if (newprio == NORMAL) {
-					files[i].setPriority(false);
+					files[i].setPriority(0);
 					files[i].setSkipped(false);
 				} else if (newprio == HIGH) {
-					files[i].setPriority(true);
+					files[i].setPriority(1);
 					files[i].setSkipped(false);
 				} else if (newprio == DONOTDOWNLOAD) {
-					files[i].setPriority(false);
+					files[i].setPriority(0);
 					files[i].setSkipped(true);
 				} else if (newprio == DELETE) {
-					if (files[i].setStorageType(DiskManagerFileInfo.ST_COMPACT)) {
-						files[i].setPriority(false);
+					int st = files[i].getStorageType();
+					int target_st = -1;
+					if ( st == DiskManagerFileInfo.ST_LINEAR ){
+						target_st = DiskManagerFileInfo.ST_COMPACT;
+					}else if ( st == DiskManagerFileInfo.ST_REORDER ){
+						target_st = DiskManagerFileInfo.ST_REORDER_COMPACT;
+					}
+					if (target_st != -1 &&
+						files[i].setStorageType(target_st)) {
+						files[i].setPriority(0);
 						files[i].setSkipped(true);
 					} else {
 						console.out.println("> Command 'prio': Failed to delete file " + (i+1));
diff --git a/org/gudy/azureus2/ui/console/commands/Show.java b/org/gudy/azureus2/ui/console/commands/Show.java
index 88795c7..f33c7af 100644
--- a/org/gudy/azureus2/ui/console/commands/Show.java
+++ b/org/gudy/azureus2/ui/console/commands/Show.java
@@ -559,7 +559,7 @@ public class Show extends IConsoleCommand {
 				out.print(((i < 9) ? "   " : "  ") + Integer.toString(i + 1)
 						+ " (");
 				String tmp = ">";
-				if (files[i].isPriority())
+				if (files[i].getPriority()>0)
 					tmp = "+";
 				if (files[i].isSkipped())
 					tmp = "!";
diff --git a/org/gudy/azureus2/ui/icons/aligncentre.png b/org/gudy/azureus2/ui/icons/aligncentre.png
new file mode 100644
index 0000000..443c4d6
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/aligncentre.png differ
diff --git a/org/gudy/azureus2/ui/icons/alignleft.png b/org/gudy/azureus2/ui/icons/alignleft.png
new file mode 100644
index 0000000..0ad451e
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/alignleft.png differ
diff --git a/org/gudy/azureus2/ui/icons/alignright.png b/org/gudy/azureus2/ui/icons/alignright.png
new file mode 100644
index 0000000..1cc877e
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/alignright.png differ
diff --git a/org/gudy/azureus2/ui/icons/blackdot.gif b/org/gudy/azureus2/ui/icons/blackdot.gif
new file mode 100644
index 0000000..5bd91cd
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/blackdot.gif differ
diff --git a/org/gudy/azureus2/ui/icons/blackdot.png b/org/gudy/azureus2/ui/icons/blackdot.png
new file mode 100644
index 0000000..fc139bf
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/blackdot.png differ
diff --git a/org/gudy/azureus2/ui/icons/blacktick.gif b/org/gudy/azureus2/ui/icons/blacktick.gif
new file mode 100644
index 0000000..3256e00
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/blacktick.gif differ
diff --git a/org/gudy/azureus2/ui/icons/btn_add_rss.png b/org/gudy/azureus2/ui/icons/btn_add_rss.png
deleted file mode 100644
index 1e2cfc3..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_add_rss.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_all_rss.png b/org/gudy/azureus2/ui/icons/btn_all_rss.png
deleted file mode 100644
index 587a57f..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_all_rss.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_gray_bud.png b/org/gudy/azureus2/ui/icons/btn_rss_gray_bud.png
deleted file mode 100644
index 78d1941..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_gray_bud.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_green_bud.png b/org/gudy/azureus2/ui/icons/btn_rss_green_bud.png
deleted file mode 100644
index 6a2d76e..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_green_bud.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_orange_bud.png b/org/gudy/azureus2/ui/icons/btn_rss_orange_bud.png
deleted file mode 100644
index f0e69f8..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_orange_bud.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_subscribe_green_30x14.png b/org/gudy/azureus2/ui/icons/btn_rss_subscribe_green_30x14.png
deleted file mode 100644
index 7db2cf0..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_subscribe_green_30x14.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_subscribe_orange_30x14.png b/org/gudy/azureus2/ui/icons/btn_rss_subscribe_orange_30x14.png
deleted file mode 100644
index 9bac74c..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_subscribe_orange_30x14.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_subscribed_gray_30x14.png b/org/gudy/azureus2/ui/icons/btn_rss_subscribed_gray_30x14.png
deleted file mode 100644
index 616a072..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_subscribed_gray_30x14.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/btn_rss_subscribed_green_30x14.png b/org/gudy/azureus2/ui/icons/btn_rss_subscribed_green_30x14.png
deleted file mode 100644
index 47b5b17..0000000
Binary files a/org/gudy/azureus2/ui/icons/btn_rss_subscribed_green_30x14.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/delete2.gif b/org/gudy/azureus2/ui/icons/delete2.gif
new file mode 100644
index 0000000..bce2644
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/delete2.gif differ
diff --git a/org/gudy/azureus2/ui/icons/icons.properties b/org/gudy/azureus2/ui/icons/icons.properties
index b476603..da981ce 100644
--- a/org/gudy/azureus2/ui/icons/icons.properties
+++ b/org/gudy/azureus2/ui/icons/icons.properties
@@ -1,13 +1,10 @@
 forcestart=org/gudy/azureus2/ui/icons/forcestart.gif
 progress_cancel=org/gudy/azureus2/ui/icons/progress_cancel.png
-cb_editcolumns=org/gudy/azureus2/ui/icons/toolbar/editcolumns.gif
-cb_run=org/gudy/azureus2/ui/icons/toolbar/run.gif
 st_no_remote=org/gudy/azureus2/ui/icons/status/no_remote.gif
 columns=org/gudy/azureus2/ui/icons/columns.gif
 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
 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
@@ -16,9 +13,7 @@ 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
-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
 redled=org/gudy/azureus2/ui/icons/redled.gif
 add_to_share=com/aelitis/azureus/ui/images/buddy_add_to_share.png
 spinner_big=multi,32,org/gudy/azureus2/ui/icons/spinning_indicator_big_white.png
@@ -26,15 +21,11 @@ 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
 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
 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
-cb_bottom=org/gudy/azureus2/ui/icons/toolbar/bottom.gif
-cb_open_folder=org/gudy/azureus2/ui/icons/toolbar/open_folder.gif
+delete2=org/gudy/azureus2/ui/icons/delete2.gif
 cb_open_no_default=org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif
 st_ok=org/gudy/azureus2/ui/icons/status/ok.gif
 publish=org/gudy/azureus2/ui/icons/publish.gif
@@ -42,9 +33,7 @@ st_stopped=org/gudy/azureus2/ui/icons/status/stopped.gif
 subitem=org/gudy/azureus2/ui/icons/subitem.gif
 bbb_out=org/gudy/azureus2/ui/icons/statusbar/bbb_boosting.png
 add_tracker=org/gudy/azureus2/ui/icons/add_tracker.gif
-cb_up=org/gudy/azureus2/ui/icons/toolbar/up.gif
 st_no_tracker=org/gudy/azureus2/ui/icons/status/no_tracker.gif
-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
@@ -65,18 +54,15 @@ azureus32=org/gudy/azureus2/ui/icons/a32.png
 st_explain=org/gudy/azureus2/ui/icons/status/explain.gif
 progress_error=org/gudy/azureus2/ui/icons/progress_viewer_has_error.png
 smallx-gray=org/gudy/azureus2/ui/icons/smallx-gray.png
-cb_open=org/gudy/azureus2/ui/icons/toolbar/open.gif
 tray=org/gudy/azureus2/ui/icons/Azureus_big.png
 foldersmall=org/gudy/azureus2/ui/icons/foldersmall.png
 stop=org/gudy/azureus2/ui/icons/stop.gif
-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
 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
-cb_down=org/gudy/azureus2/ui/icons/toolbar/down.gif
 grayled=org/gudy/azureus2/ui/icons/grayled.gif
 top=org/gudy/azureus2/ui/icons/top.gif
 export=org/gudy/azureus2/ui/icons/export.gif
@@ -100,10 +86,26 @@ dl_bar_end=org/gudy/azureus2/ui/icons/dl_bar_end.png
 dl_bar_0=org/gudy/azureus2/ui/icons/dl_bar_0.png
 dl_bar_1=org/gudy/azureus2/ui/icons/dl_bar_1.png
 
-rss_buddy_orange=org/gudy/azureus2/ui/icons/btn_rss_orange_bud.png
-rss_buddy_gray=org/gudy/azureus2/ui/icons/btn_rss_gray_bud.png
-rss_buddy_green=org/gudy/azureus2/ui/icons/btn_rss_green_bud.png
+image.systemwarning.closeitem=com/aelitis/azureus/ui/images/ic_x.png
+image.sidebar.vitality.alert=com/aelitis/azureus/ui/images/sb/ic_alert.png
 
+zoom=org/gudy/azureus2/ui/icons/zoom.png
+
+azureus_splash=com/aelitis/azureus/ui/images/logo-150.png
+
+blackdot=org/gudy/azureus2/ui/icons/blackdot.gif
+blackdot=org/gudy/azureus2/ui/icons/blacktick.gif
+
+alignleft=org/gudy/azureus2/ui/icons/alignleft.png
+aligncentre=org/gudy/azureus2/ui/icons/aligncentre.png
+alignright=org/gudy/azureus2/ui/icons/alignright.png
+
+tick_mark=com/aelitis/azureus/ui/images/success.png
+cross_mark=com/aelitis/azureus/ui/images/failure.png
+
+pair_sb_idle=org/gudy/azureus2/ui/icons/statusbar/pa_idle.png
+pair_sb_green=org/gudy/azureus2/ui/icons/statusbar/pa_green.png
+pair_sb_red=org/gudy/azureus2/ui/icons/statusbar/pa_red.png
 
 #		if ( Utils.isAZ2UI()){ 
 #			addPath("org/gudy/azureus2/ui/icons/recheck.gif", "progress_retry");
diff --git a/org/gudy/azureus2/ui/icons/popup.png b/org/gudy/azureus2/ui/icons/popup.png
deleted file mode 100644
index bd070b2..0000000
Binary files a/org/gudy/azureus2/ui/icons/popup.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/statusbar/pa_green.png b/org/gudy/azureus2/ui/icons/statusbar/pa_green.png
new file mode 100644
index 0000000..2ed7936
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/statusbar/pa_green.png differ
diff --git a/org/gudy/azureus2/ui/icons/statusbar/pa_idle.png b/org/gudy/azureus2/ui/icons/statusbar/pa_idle.png
new file mode 100644
index 0000000..3b2a691
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/statusbar/pa_idle.png differ
diff --git a/org/gudy/azureus2/ui/icons/statusbar/pa_red.png b/org/gudy/azureus2/ui/icons/statusbar/pa_red.png
new file mode 100644
index 0000000..672a18f
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/statusbar/pa_red.png differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/bottom.gif b/org/gudy/azureus2/ui/icons/toolbar/bottom.gif
deleted file mode 100644
index 36f3c90..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/bottom.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/down.gif b/org/gudy/azureus2/ui/icons/toolbar/down.gif
deleted file mode 100644
index e5c16cb..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/down.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/editcolumns.gif b/org/gudy/azureus2/ui/icons/toolbar/editcolumns.gif
deleted file mode 100644
index fc7be53..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/editcolumns.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/open.gif b/org/gudy/azureus2/ui/icons/toolbar/open.gif
deleted file mode 100644
index 32dac06..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/open.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/open_folder.gif b/org/gudy/azureus2/ui/icons/toolbar/open_folder.gif
deleted file mode 100644
index b8ad506..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/open_folder.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif b/org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif
index a6abf8d..95e8190 100644
Binary files a/org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif and b/org/gudy/azureus2/ui/icons/toolbar/open_no_default.gif differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/open_url.gif b/org/gudy/azureus2/ui/icons/toolbar/open_url.gif
deleted file mode 100644
index 8c4a5e8..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/open_url.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/remove.gif b/org/gudy/azureus2/ui/icons/toolbar/remove.gif
deleted file mode 100644
index 04ad9f7..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/remove.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/run.gif b/org/gudy/azureus2/ui/icons/toolbar/run.gif
deleted file mode 100644
index e3210b2..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/run.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/start.gif b/org/gudy/azureus2/ui/icons/toolbar/start.gif
deleted file mode 100644
index 4458e92..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/start.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/stop.gif b/org/gudy/azureus2/ui/icons/toolbar/stop.gif
deleted file mode 100644
index d50d277..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/stop.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/switchui.png b/org/gudy/azureus2/ui/icons/toolbar/switchui.png
deleted file mode 100644
index a8734f1..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/switchui.png and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/top.gif b/org/gudy/azureus2/ui/icons/toolbar/top.gif
deleted file mode 100644
index 7c7cd2b..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/top.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/toolbar/up.gif b/org/gudy/azureus2/ui/icons/toolbar/up.gif
deleted file mode 100644
index 37134ec..0000000
Binary files a/org/gudy/azureus2/ui/icons/toolbar/up.gif and /dev/null differ
diff --git a/org/gudy/azureus2/ui/icons/zoom.png b/org/gudy/azureus2/ui/icons/zoom.png
new file mode 100644
index 0000000..65e9894
Binary files /dev/null and b/org/gudy/azureus2/ui/icons/zoom.png differ
diff --git a/org/gudy/azureus2/ui/splash/splash_frog.jpg b/org/gudy/azureus2/ui/splash/splash_frog.jpg
deleted file mode 100644
index 503916c..0000000
Binary files a/org/gudy/azureus2/ui/splash/splash_frog.jpg and /dev/null differ
diff --git a/org/gudy/azureus2/ui/swt/Alerts.java b/org/gudy/azureus2/ui/swt/Alerts.java
index 2935d75..f5ac535 100644
--- a/org/gudy/azureus2/ui/swt/Alerts.java
+++ b/org/gudy/azureus2/ui/swt/Alerts.java
@@ -23,65 +23,83 @@ package org.gudy.azureus2.ui.swt;
 
 import java.util.*;
 
-import com.aelitis.azureus.core.util.GeneralUtils;
-import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.UIStatusTextClickListener;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.MessageBox;
+
 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.logging.ILogAlertListener;
+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.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
-import org.gudy.azureus2.core3.util.*;
+
+import com.aelitis.azureus.util.MapUtils;
 
 /**
  * Utility methods to display popup window
- * 
- * TODO: Finish up moving from LGLogger to Logger/LogAlert.  ie alert_queue
- *        could store LogAlert instead of an object array.
  */
 public class Alerts
 {
 
-	private static List alert_queue = new ArrayList();
+	/**
+	 * alert queue is used at startup, prior to initialization to collect
+	 * and incoming alerts and start them.  Once initialization is complete,
+	 * the queue is processed (and moved to alert_history) and cleared
+	 */
+	private static List<LogAlert> alert_queue = new ArrayList<LogAlert>();
 
 	private static AEMonitor alert_queue_mon = new AEMonitor("Alerts:Q");
 
-	private static List alert_history = new ArrayList();
+	private static ArrayList<String> alert_history = new ArrayList<String>(0);
+	
+	private static ArrayList<LogAlert> listUnviewedLogAlerts = new ArrayList<LogAlert>(0);
 
 	private static AEMonitor alert_history_mon = new AEMonitor("Alerts:H");
 
-	private static boolean initialisation_complete = false;
+	private static ArrayList<AlertHistoryListener> listMessageHistoryListeners = new ArrayList<AlertHistoryListener>(1); 
 
-	private static boolean has_unshown_messages = false;
+	private static boolean initialisation_complete = false;
 
-	private static transient boolean stopping;
+	private static volatile boolean stopping;
 
-	private static List listeners = new ArrayList();
+	private static List<AlertListener> listeners = new ArrayList<AlertListener>();
 
 	private Alerts() {
 	}
+	/**
+	 * @param alert
+	 *
+	 * @since 3.0.0.9
+	 */
+	protected static void showAlert(final LogAlert alert) {
+		final Display display = SWTThread.getInstance().getDisplay();
 
-	private static void showWarningMessageBox(Object[] relatedTo, String message, int timeoutSecs) {
-		showMessageBoxUsingResourceString(relatedTo, SWT.ICON_WARNING,
-				"AlertMessageBox.warning", message, timeoutSecs);
-	}
-
-	private static void showMessageBoxUsingResourceString(Object[] relatedTo,
-			int type, String key, String message, int timeoutSecs ) {
-		showMessageBox(relatedTo, type, MessageText.getString(key), message, null, timeoutSecs );
-	}
+		if (alert.err != null) {
+			alert.details = Debug.getStackTrace(alert.err);
+		}
 
-	// All ShowMessageBox* functions should end up here..
-	private static void showMessageBox(Object[] relatedTo, final int type,
-			String title, String message, String details, int timeoutSecs ) {
-		final Display display = SWTThread.getInstance().getDisplay();
+		/*
+		final String message2;
+		if (alert.text != null
+				&& COConfigurationManager.getBooleanParameter("Show Timestamp For Alerts")) {
+			message2 = "["
+					+ DisplayFormatters.formatDateShort(SystemTime.getCurrentTime())
+					+ "] " + alert.text;
+		} else {
+			message2 = (alert.text == null) ? "" : alert.text;
+		}
+		*/
 
+		for (Iterator<AlertListener> iter = listeners.iterator(); iter.hasNext();) {
+			AlertListener l = (AlertListener) iter.next();
+			if (!l.allowPopup(alert.relatedTo, alert.entryType)) {
+				return;
+			}
+		}
+		
+	
 		if (stopping || display.isDisposed()) {
 
 			try {
@@ -92,13 +110,12 @@ public class Alerts
 
 				Map alert_map = new HashMap();
 
-				alert_map.put("type", new Long(type));
-				alert_map.put("title", title);
-				alert_map.put("message", message);
-				alert_map.put("timeout", new Long( timeoutSecs));
+				alert_map.put("type", new Long(alert.entryType));
+				alert_map.put("message", alert.text);
+				alert_map.put("timeout", new Long( alert.getGivenTimeoutSecs()));
 				
-				if (details != null) {
-					alert_map.put("details", details);
+				if (alert.details != null) {
+					alert_map.put("details", alert.details);
 				}
 
 				close_alerts.add(alert_map);
@@ -116,133 +133,7 @@ public class Alerts
 			return;
 		}
 
-		final String message2;
-		if (message != null
-				&& COConfigurationManager.getBooleanParameter("Show Timestamp For Alerts")) {
-			message2 = "["
-					+ DisplayFormatters.formatDateShort(SystemTime.getCurrentTime())
-					+ "] " + message;
-		} else {
-			message2 = (message == null) ? "" : message;
-		}
-
-		boolean suppress_popups = COConfigurationManager.getBooleanParameter("Suppress Alerts");
-		boolean use_message_box = COConfigurationManager.getBooleanParameter("Use Message Box For Popups");
-
-		// We'll add the message to the list and then force it to be displayed if necessary.
-		MessageSlideShell.recordMessage(type, title, message2 == null ? ""
-				: message2, details, relatedTo, timeoutSecs );
-
 		
-		for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-			AlertListener l = (AlertListener) iter.next();
-			if (!l.allowPopup(relatedTo, type)) {
-				suppress_popups = true;
-				return;
-			}
-		}
-		
-		if (suppress_popups) {
-			try {
-				alert_queue_mon.enter();
-				if (!has_unshown_messages) {
-					final UIFunctions ui_functions = UIFunctionsManager.getUIFunctions();
-					if (ui_functions != null) {
-						ui_functions.setStatusText(UIFunctions.STATUSICON_WARNING,
-								MessageText.getString("AlertMessageBox.unread"),
-								new UIStatusTextClickListener() {
-									public void UIStatusTextClicked() {
-										MessageSlideShell.displayLastMessage(display, true);
-										ui_functions.setStatusText("");
-										has_unshown_messages = false;
-									}
-								});
-						has_unshown_messages = true;
-					}
-				}
-				return;
-			} finally {
-				alert_queue_mon.exit();
-			}
-		} else if (!use_message_box) {
-			MessageSlideShell.displayLastMessage(display, true);
-		} else {
-			/**
-			 * I don't like displaying dialog boxes with titles like "Information" and "Error".
-			 * So if we are going to be displaying those message titles, then just revert back
-			 * to something like "Azureus" (sounds good to me!).
-			 */
-			String amb_key_suffix;
-			switch (type) {
-				case SWT.ICON_ERROR:
-					amb_key_suffix = "error";
-					break;
-				case SWT.ICON_INFORMATION:
-					amb_key_suffix = "information";
-					break;
-				case SWT.ICON_WARNING:
-					amb_key_suffix = "warning";
-					break;
-				default:
-					amb_key_suffix = null;
-					break;
-			}
-
-			final String title2;
-			if (amb_key_suffix != null
-					&& title.equals(MessageText.getString("AlertMessageBox."
-							+ amb_key_suffix))) {
-				title2 = Constants.APP_NAME;
-			} else {
-				title2 = title;
-			}
-
-			display.asyncExec(new AERunnable() {
-				public void runSupport() {
-					// XXX: Not sure whether findAnyShell is the best thing to use here...
-					Shell s = Utils.findAnyShell();
-					if (s == null) {
-						return;
-					}
-
-					MessageBox mb = new MessageBox(s, type | SWT.OK);
-					mb.setText(title2);
-					mb.setMessage(GeneralUtils.stripOutHyperlinks(message2));
-					mb.open();
-				}
-			});
-		} // end else
-	} // end method
-
-	public static void showErrorMessageBoxUsingResourceString(Object[] relatedTo,
-			String title_key, Throwable error, int timeoutSecs ) {
-		showErrorMessageBox(relatedTo, MessageText.getString(title_key), error, timeoutSecs );
-	}
-
-	private static void showErrorMessageBox(Object[] relatedTo, String message,
-			Throwable error, int timeoutSecs ) {
-		String error_message = Debug.getStackTrace(error);
-		showMessageBox(relatedTo, SWT.ICON_ERROR,
-				MessageText.getString("AlertMessageBox.error"), message + "\n"
-						+ Debug.getExceptionMessage(error), error_message, timeoutSecs );
-	}
-
-	private static void showErrorMessageBox(Object[] relatedTo, String message, int timeoutSecs ) {
-		showMessageBoxUsingResourceString(relatedTo, SWT.ICON_ERROR,
-				"AlertMessageBox.error", message, timeoutSecs );
-	}
-
-	private static void showCommentMessageBox(Object[] relatedTo, String message, int timeoutSecs) {
-		showMessageBoxUsingResourceString(relatedTo, SWT.ICON_INFORMATION,
-				"AlertMessageBox.information", message, timeoutSecs );
-	}
-
-	/**
-	 * @param alert
-	 *
-	 * @since 3.0.0.9
-	 */
-	protected static void showAlert(LogAlert alert) {
 		String key = (alert.err == null) ? alert.text : alert.text + ":"
 				+ alert.err.toString();
 		try {
@@ -259,23 +150,56 @@ public class Alerts
 					alert_history.remove(0);
 				}
 			}
+
+			listUnviewedLogAlerts.add(alert);
 		} finally {
 			alert_history_mon.exit();
 		}
-
-		if (alert.err == null) {
-			if (alert.entryType == LogAlert.AT_INFORMATION) {
-				showCommentMessageBox(alert.relatedTo, alert.text, alert.timeoutSecs );
-			} else if (alert.entryType == LogAlert.AT_WARNING) {
-				showWarningMessageBox(alert.relatedTo, alert.text, alert.timeoutSecs );
-			} else {
-				showErrorMessageBox(alert.relatedTo, alert.text, alert.timeoutSecs );
-			}
-
-		} else {
-			showErrorMessageBox(alert.relatedTo, alert.text, alert.err, alert.timeoutSecs );
+		
+		AlertHistoryListener[] array = listMessageHistoryListeners.toArray(new AlertHistoryListener[0]);
+		for (AlertHistoryListener l : array) {
+			l.alertHistoryAdded(alert);
+		}
+		
+		if ( alert.forceNotify ){
+			
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					int swtIconID = SWT.ICON_INFORMATION;
+					switch (alert.getType()) {
+						case LogAlert.LT_WARNING:
+							swtIconID = SWT.ICON_WARNING;
+							break;
+							
+						case LogAlert.LT_ERROR:
+							swtIconID = SWT.ICON_ERROR;
+							break;
+					}
+					
+					String	text = alert.getText();
+					
+					int	pos = text.indexOf( ":" );
+					
+					String	title;
+					
+					if ( pos == -1 ){
+						
+						title = "";
+						
+					}else{
+						
+						title = text.substring( 0, pos ).trim();
+						
+						text = text.substring( pos+1 ).trim();
+					}
+					
+					new MessageSlideShell(
+							SWTThread.getInstance().getDisplay(), swtIconID,
+							title, text, alert.details, alert.getContext(), alert.getTimeoutSecs());
+					
+				}
+			});
 		}
-
 	}
 
 	public static void initComplete() {
@@ -287,7 +211,7 @@ public class Alerts
 					initialisation_complete = true;
 
 					for (int i = 0; i < alert_queue.size(); i++) {
-						LogAlert alert = (LogAlert) alert_queue.get(i);
+						LogAlert alert = alert_queue.get(i);
 
 						showAlert(alert);
 					}
@@ -295,6 +219,7 @@ public class Alerts
 					List close_alerts = COConfigurationManager.getListParameter(
 							"Alerts.raised.at.close", new ArrayList());
 
+					
 					if (close_alerts.size() > 0) {
 
 						COConfigurationManager.setParameter("Alerts.raised.at.close",
@@ -308,19 +233,20 @@ public class Alerts
 							try {
 								Map alert_map = (Map) close_alerts.get(i);
 
-								byte[] details = (byte[]) alert_map.get("details");
-
-								Long	l_timeout = (Long)alert_map.get( "timeout" );
+								BDecoder.decodeStrings(alert_map);
+								
+								String details = MapUtils.getMapString(alert_map, "details", null);
+								
+								int timeout = MapUtils.getMapInt(alert_map, "timeout", -1);
 								
-								int timeout = l_timeout==null?-1:l_timeout.intValue();
+								int entryType = MapUtils.getMapInt(alert_map, "type", 0);
 								
-								showMessageBox(
-									null, 
-									((Long) alert_map.get("type")).intValue(),
-									new String((byte[]) alert_map.get("title")), 
-									intro + new String((byte[]) alert_map.get("message")),
-									details == null ? null : new String(details),
-									timeout);
+								String message = intro + MapUtils.getMapString(alert_map, "message", "");
+								
+								LogAlert logAlert = new LogAlert(false, entryType, message, timeout);
+								logAlert.details = details;
+								
+								showAlert(logAlert);
 
 							} catch (Throwable e) {
 
@@ -376,4 +302,28 @@ public class Alerts
 	public static interface AlertListener {
 		public boolean allowPopup(Object[] relatedObjects, int configID);
 	}
+
+	
+	public static ArrayList<LogAlert> getUnviewedLogAlerts() {
+		return new ArrayList<LogAlert>(listUnviewedLogAlerts);
+	}
+
+	public static void addMessageHistoryListener(AlertHistoryListener l) {
+		listMessageHistoryListeners.add(l);
+	}
+	
+	public static void markAlertAsViewed(LogAlert alert) {
+		boolean removed = listUnviewedLogAlerts.remove(alert);
+		if (removed) {
+			AlertHistoryListener[] array = listMessageHistoryListeners.toArray(new AlertHistoryListener[0]);
+			for (AlertHistoryListener l : array) {
+				l.alertHistoryRemoved(alert);
+			}
+		}
+	}
+	
+	public interface AlertHistoryListener {
+		public void alertHistoryAdded(LogAlert alert);
+		public void alertHistoryRemoved(LogAlert alert);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java b/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
index ce61317..3429eea 100644
--- a/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
+++ b/org/gudy/azureus2/ui/swt/CategoryAdderWindow.java
@@ -34,7 +34,7 @@ public class CategoryAdderWindow
 {
 	private Category newCategory;
 
-	public CategoryAdderWindow(final Display display) {
+	public CategoryAdderWindow(final Display displayNotUsed) {
 		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
 				"CategoryAddWindow.title", "CategoryAddWindow.message");
 		entryWindow.prompt();
diff --git a/org/gudy/azureus2/ui/swt/DelayedListenerMultiCombiner.java b/org/gudy/azureus2/ui/swt/DelayedListenerMultiCombiner.java
new file mode 100644
index 0000000..21e05ff
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/DelayedListenerMultiCombiner.java
@@ -0,0 +1,63 @@
+/**
+ * Created on Dec 30, 2010
+ *
+ * Copyright 2010 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;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+import org.gudy.azureus2.core3.util.AERunnable;
+
+/**
+ * Delayed {@link Listener} that denies more triggers while one is pending
+ * 
+ * @author TuxPaper
+ * @created Dec 30, 2010
+ *
+ */
+public abstract class DelayedListenerMultiCombiner
+	implements Listener
+{
+	Object lock = new Object();
+	private boolean pending = false;
+
+	public final void handleEvent(final Event event) {
+		synchronized (lock) {
+			if (pending) {
+				return;
+			}
+			
+			pending = true;
+		}
+
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				try {
+					handleDelayedEvent(event);
+				} finally {
+  				synchronized (lock) {
+  					pending = false;
+  				}
+				}
+			}
+		});
+	}
+
+	public abstract void handleDelayedEvent(Event firstEvent);
+}
diff --git a/org/gudy/azureus2/ui/swt/FileDownloadWindow.java b/org/gudy/azureus2/ui/swt/FileDownloadWindow.java
index 0ed1f4b..5b1ad84 100644
--- a/org/gudy/azureus2/ui/swt/FileDownloadWindow.java
+++ b/org/gudy/azureus2/ui/swt/FileDownloadWindow.java
@@ -23,6 +23,8 @@ package org.gudy.azureus2.ui.swt;
 
 import java.net.URLDecoder;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.*;
@@ -35,6 +37,7 @@ import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloader;
 import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloaderCallBackInterface;
 import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloaderFactory;
 import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.progress.*;
 
@@ -50,7 +53,8 @@ public class FileDownloadWindow
 	TorrentDownloader downloader;
 
 	TorrentDownloaderCallBackInterface listener;
-
+	boolean	force_dialog;
+	
 	IProgressReporter pReporter;
 
 	Shell parent;
@@ -95,7 +99,7 @@ public class FileDownloadWindow
 	public FileDownloadWindow(final Shell parent, final String url,
 			final String referrer, final Map request_properties,
 			final TorrentDownloaderCallBackInterface listener) {
-
+		
 		this.parent = parent;
 		this.original_url = url;
 		this.referrer = referrer;
@@ -114,6 +118,29 @@ public class FileDownloadWindow
 			}
 		});
 	}
+	
+	public FileDownloadWindow(final Shell parent, final String url,
+			final String referrer, final Map request_properties,
+			final boolean force_dialog) {
+
+		this.parent = parent;
+		this.original_url = url;
+		this.referrer = referrer;
+		this.force_dialog = force_dialog;
+		this.request_properties = request_properties;
+
+		try {
+			decoded_url = URLDecoder.decode(original_url, "UTF8");
+		} catch (Throwable e) {
+			decoded_url = original_url;
+
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				init();
+			}
+		});
+	}
 
 	private void init() {
 
@@ -238,7 +265,8 @@ public class FileDownloadWindow
 				 * was just downloaded
 				 */
 				if (listener == null) {
-					TorrentOpener.openTorrent(downloader.getFile().getAbsolutePath());
+					
+					TorrentOpener.openTorrent(downloader.getFile().getAbsolutePath(), force_dialog );
 				}
 				return;
 			default:
@@ -273,25 +301,22 @@ public class FileDownloadWindow
 	 */
 	private String getFileName(String url) {
 		try {
-			String	lc_url = url.toLowerCase(MessageText.LOCALE_ENGLISH);
-
 			/*
 			 * First try to retrieve the 'title' field if it has one
 			 */
-
-			int idx = lc_url.indexOf("&title=");
-			if (idx >= 0) {
-				String title = url.substring(idx + "&title=".length());
-				idx = title.indexOf('&');
-				if (idx > 0) {
-					title = title.substring(0, idx);
-					title = title.replace('+', ' ');
-					if (title.length() > 0) {
-						return title;
-					}
+			
+			final String[] titles = {
+				"title",
+				"dn"
+			};
+			for (String toMatch : titles) {
+				Matcher matcher = Pattern.compile("[?&]" + toMatch + "=(.*)&?",
+						Pattern.CASE_INSENSITIVE).matcher(url);
+				if (matcher.find()) {
+					return matcher.group(1);
 				}
 			}
-
+			
 			/*
 			 * If no 'title' field was found then just get the file name instead
 			 * 
@@ -303,16 +328,25 @@ public class FileDownloadWindow
 
 			url = getShortURL(url);
 			
-			lc_url = url.toLowerCase(MessageText.LOCALE_ENGLISH);
+			String lc_url = url.toLowerCase(MessageText.LOCALE_ENGLISH);
 
-			if ( lc_url.startsWith( "magnet:") || lc_url.startsWith( "dht:" )){
+			if ( lc_url.startsWith( "magnet:") || lc_url.startsWith( "dht:" ) || lc_url.startsWith( "bc:" ) || lc_url.startsWith( "bctp:" )){
 				
 				return( url );
 			}
 			
 			String tmp = url.substring(url.lastIndexOf('/') + 1);
-			if (tmp.toLowerCase(MessageText.LOCALE_ENGLISH).lastIndexOf(".torrent") > 0) {
-				tmp = tmp.substring(0, tmp.toLowerCase(MessageText.LOCALE_ENGLISH).lastIndexOf(".torrent"));
+			
+			int pos = tmp.toLowerCase(MessageText.LOCALE_ENGLISH).lastIndexOf(".vuze");
+			
+			if ( pos > 0) {
+				return( tmp.substring(0, pos + 5 ));			
+			}
+
+			pos = tmp.toLowerCase(MessageText.LOCALE_ENGLISH).lastIndexOf(".torrent");
+			
+			if (pos > 0) {
+				tmp = tmp.substring(0, pos );
 			}
 			return tmp + ".torrent";
 		} catch (Exception t) {
diff --git a/org/gudy/azureus2/ui/swt/ITwistieConstants.java b/org/gudy/azureus2/ui/swt/ITwistieConstants.java
deleted file mode 100644
index 54b61ea..0000000
--- a/org/gudy/azureus2/ui/swt/ITwistieConstants.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.gudy.azureus2.ui.swt;
-
-public interface ITwistieConstants
-{
-	public static final int NONE = 1 << 1;
-
-	public static final int SHOW_DESCRIPTION = 1 << 2;
-
-	public static final int SHOW_SEPARATOR = 1 << 3;
-
-	public static final int SHOW_EXPANDED = 1 << 4;
-
-}
diff --git a/org/gudy/azureus2/ui/swt/ITwistieListener.java b/org/gudy/azureus2/ui/swt/ITwistieListener.java
deleted file mode 100644
index 8877221..0000000
--- a/org/gudy/azureus2/ui/swt/ITwistieListener.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.gudy.azureus2.ui.swt;
-
-/**
- * A convenience listener that will be notified whenever the control changes state between being
- * collapse and being expanded
- * @author knguyen
- *
- */
-public interface ITwistieListener
-{
-	/**
-	 * <code>true</code> is the control is in a collapsed state; <code>false otherwise</code>
-	 * @param value
-	 */
-	public void isCollapsed(boolean value);
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/IconBar.java b/org/gudy/azureus2/ui/swt/IconBar.java
deleted file mode 100644
index cdc7225..0000000
--- a/org/gudy/azureus2/ui/swt/IconBar.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * File    : IconBar.java
- * Created : 7 d�c. 2003
- * By      : Olivier
- *
- * 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.swt;
-
-import java.util.*;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-
-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.ui.swt.components.BufferedToolItem;
-
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-/**
- * @author Olivier
- *
- */
-public class IconBar {
-	private final boolean OVERRIDE_SHOW_UISWITCHER = System.getProperty(
-			"ui.toolbar.uiswitcher", "0").equals("1");
-  
-  CoolBar coolBar;
-  Composite parent;    
-  Map itemKeyToControl;
-  
-  IconBarEnabler currentEnabler;
-	private Composite cIconBar;
-	
-	private static List listeners = new ArrayList(0);
-
-	private Listener listenerToolItem;
-  
-  public IconBar(Composite parent) {
-    this.parent = parent;
-    
-    listenerToolItem = new Listener() {
-			public void handleEvent(Event e) {
-				if (e.type == SWT.Selection) {
-					if (currentEnabler != null) {
-						currentEnabler.itemActivated((String) e.widget.getData("key"));
-					}
-				} else if (e.type == SWT.Dispose) {
-					ImageLoader.getInstance().releaseImage(
-							(String) e.widget.getData("ImageID"));
-				}
-			}
-		};
-    
-    cIconBar = new Composite(parent, SWT.NONE);
-    
-    GridLayout layout = new GridLayout(2, false);
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    layout.horizontalSpacing = 0;
-    layout.verticalSpacing = 0;
-    cIconBar.setLayout(layout);
-    
-    this.itemKeyToControl = new HashMap();    
-    	// 3.1 onwards the default is gradient-fill - the disabled icons' transparency no workies
-    	// so disabled buttons look bad on the gradient-filled background
-    this.coolBar = new CoolBar(cIconBar,Constants.isWindows?SWT.FLAT:SWT.NULL);
-    initBar();       
-    this.coolBar.setLocked(true);
-    
-    coolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-    // We could setup a listener on the parameter and dynamically remove/add
-    // ui switcher button, but it's not worth the effort
-		boolean enableUISwitcher = OVERRIDE_SHOW_UISWITCHER
-				|| COConfigurationManager.getBooleanParameter("ui.toolbar.uiswitcher")
-				|| COConfigurationManager.getBooleanParameter("ui.asked", false);
-    
-		if (enableUISwitcher) {
-			ToolBar tbSwitch = new ToolBar(cIconBar, SWT.FLAT);
-			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-			tbSwitch.setLayoutData(gridData);
-			ToolItem tiSwitch = new ToolItem(tbSwitch, SWT.PUSH);
-			tiSwitch.setImage(ImageLoader.getInstance().getImage("cb_switch"));
-			Messages.setLanguageText(tiSwitch, "iconBar.switch.tooltip", true);
-			tiSwitch.addSelectionListener(new SelectionListener() {
-				public void widgetSelected(SelectionEvent e) {
-					UISwitcherUtil.openSwitcherWindow();
-				}
-
-				public void widgetDefaultSelected(SelectionEvent e) {
-				}
-			});
-			tiSwitch.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					ImageLoader.getInstance().releaseImage("cb_switch");
-				}
-			});
-		}
-	}
-
-	public void setEnabled(String itemKey,boolean enabled) {
-    BufferedToolItem BufferedToolItem = (BufferedToolItem) itemKeyToControl.get(itemKey);
-    if(BufferedToolItem != null)
-      BufferedToolItem.setEnabled(enabled);
-  }
-  
-  public void setSelection(String itemKey,boolean selection) {
-    BufferedToolItem BufferedToolItem = (BufferedToolItem) itemKeyToControl.get(itemKey);
-    if(BufferedToolItem != null)
-      BufferedToolItem.setSelection(selection);
-  }
-  
-  public void setCurrentEnabler(IconBarEnabler enabler) {
-    this.currentEnabler = enabler;
-    refreshEnableItems();
-  }
-
-    // dead
-  public IconBarEnabler getCurrentEnabler() {
-  	return this.currentEnabler;
-  }
-  
-  private void refreshEnableItems() {
-    Iterator iter = itemKeyToControl.keySet().iterator();
-    while(iter.hasNext()) {
-      String key = (String) iter.next();
-      BufferedToolItem BufferedToolItem = (BufferedToolItem) itemKeyToControl.get(key);
-      if(BufferedToolItem == null )
-        continue;
-      if(currentEnabler != null) {
-        BufferedToolItem.setEnabled(currentEnabler.isEnabled(key));
-        BufferedToolItem.setSelection(currentEnabler.isSelected(key));
-      }
-      else {        
-        BufferedToolItem.setEnabled(false);
-        BufferedToolItem.setSelection(false);
-      }
-    }
-  }
-  
-  private BufferedToolItem createBufferedToolItem(ToolBar toolBar,int style,String key,final String imageName,String toolTipKey) {    
-    final BufferedToolItem bufferedToolItem = new BufferedToolItem(toolBar,style);
-    bufferedToolItem.setData("key",key);
-    bufferedToolItem.setData("ImageID",key);
-    Messages.setLanguageText(bufferedToolItem.getWidget(),toolTipKey,true);
-    bufferedToolItem.setImage(ImageLoader.getInstance().getImage(imageName));
-   
-    bufferedToolItem.addListener(SWT.Selection, listenerToolItem);
-    bufferedToolItem.addListener(SWT.Dispose, listenerToolItem);
-
-    itemKeyToControl.put(key,bufferedToolItem);
-    return bufferedToolItem;
-  }  
-  
-  public void addItemKeyToControl(String key, BufferedToolItem item) {
-  	itemKeyToControl.put(key, item);
-  }
-  
-  private void initBar() {
-    //The File Menu
-    CoolItem coolItem = new CoolItem(coolBar,SWT.NULL);
-
-    ToolBar toolBar = new ToolBar(coolBar,SWT.FLAT);
-    createBufferedToolItem(toolBar,SWT.PUSH,"open","cb_open_no_default","iconBar.open.tooltip");
-    // XXX TuxPaper: Remove images (open, open_url, open_folder) from CVS and ImageRepository
-    createBufferedToolItem(toolBar,SWT.PUSH,"new","cb_new","iconBar.new.tooltip");
-    toolBar.pack(); 
-    Point p = toolBar.getSize();
-    coolItem.setControl(toolBar);
-    coolItem.setSize(coolItem.computeSize (p.x,p.y));
-    coolItem.setMinimumSize(p.x,p.y);
-    
-    
-    coolItem = new CoolItem(coolBar,SWT.NULL);
-    toolBar = new ToolBar(coolBar,SWT.FLAT);    
-    createBufferedToolItem(toolBar,SWT.PUSH,"top","cb_top","iconBar.top.tooltip");
-    createBufferedToolItem(toolBar,SWT.PUSH,"up","cb_up","iconBar.up.tooltip");
-    createBufferedToolItem(toolBar,SWT.PUSH,"down","cb_down","iconBar.down.tooltip");
-    createBufferedToolItem(toolBar,SWT.PUSH,"bottom","cb_bottom","iconBar.bottom.tooltip");
-    new BufferedToolItem(toolBar,SWT.SEPARATOR);
-    createBufferedToolItem(toolBar,SWT.PUSH,"run","cb_run","iconBar.run.tooltip");
-    new BufferedToolItem(toolBar,SWT.SEPARATOR);
-    createBufferedToolItem(toolBar,SWT.PUSH,"start","cb_start","iconBar.start.tooltip");
-    createBufferedToolItem(toolBar,SWT.PUSH,"stop","cb_stop","iconBar.stop.tooltip");
-    createBufferedToolItem(toolBar,SWT.PUSH,"remove","cb_remove","iconBar.remove.tooltip");
-    new BufferedToolItem(toolBar,SWT.SEPARATOR);
-    createBufferedToolItem(toolBar,SWT.PUSH,"editcolumns","cb_editcolumns","iconBar.editcolumns.tooltip");
-
-    for (Iterator iter = listeners.iterator(); iter.hasNext();) {
-    	try {
-    		IconBarListener l = (IconBarListener) iter.next();
-    		l.iconBarInitialized(coolBar, this);
-    	} catch (Exception e) {
-    		Debug.out(e);
-    	}
-		}
-    
-    toolBar.pack();
-    p = toolBar.getSize();
-    coolItem.setControl(toolBar);
-    if (Constants.isOSX) {
-    	p.x += 12;
-    }
-    coolItem.setSize(p.x,p.y);
-  	coolItem.setMinimumSize(p.x,p.y);
-  }
-  
-  public void setLayoutData(Object layoutData) {
-  	cIconBar.setLayoutData(layoutData);
-  }
-  
-  public static void main(String args[]) {
-    Display display = new Display();
-    Shell shell = new Shell(display);
-    FormLayout layout = new FormLayout();
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    shell.setLayout(layout);
-    IconBar ibar = new IconBar(shell);
-    FormData formData = new FormData();
-    formData.left = new FormAttachment(0,0);
-    formData.right = new FormAttachment(100,0);
-    ibar.setLayoutData(formData);
-    shell.open();
-    while (!shell.isDisposed()) {
-      if (!display.readAndDispatch ()) display.sleep ();
-    }
-    display.dispose ();        
-  }
-  
-	public Composite getComposite() {
-		return cIconBar;
-	}
-
-	/**
-	 * 
-	 */
-	public void delete() {
-		Utils.disposeComposite(cIconBar);
-		itemKeyToControl.clear();
-		currentEnabler = null;
-	}
-
-	public static void addListener(IconBarListener l) {
-		if (!listeners.contains(l)) {
-			listeners.add(l);
-		}
-	}
-	
-	public static interface IconBarListener {
-		public void iconBarInitialized(CoolBar coolBar, IconBar ib);
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/IconBarEnabler.java b/org/gudy/azureus2/ui/swt/IconBarEnabler.java
deleted file mode 100644
index 6d95fd9..0000000
--- a/org/gudy/azureus2/ui/swt/IconBarEnabler.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * File    : IconBarEnabler.java
- * Created : 7 d�c. 2003
- * By      : Olivier
- *
- * 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.swt;
-
-/**
- * @author Olivier
- *
- */
-public interface IconBarEnabler {
-  public boolean isEnabled(String itemKey);
-  public boolean isSelected(String itemKey);
-  public void itemActivated(String itemKey);
-}
diff --git a/org/gudy/azureus2/ui/swt/ImageRepository.java b/org/gudy/azureus2/ui/swt/ImageRepository.java
index 3459089..5fe1497 100644
--- a/org/gudy/azureus2/ui/swt/ImageRepository.java
+++ b/org/gudy/azureus2/ui/swt/ImageRepository.java
@@ -299,28 +299,31 @@ public class ImageRepository
 
 			java.awt.Image awtImage = null;
 
-			final Class sfClass = Class.forName("sun.awt.shell.ShellFolder");
-			if (sfClass != null && file != null) {
-				Method method = sfClass.getMethod("getShellFolder", new Class[] {
-					File.class
-				});
-				if (method != null) {
-					Object sfInstance = method.invoke(null, new Object[] {
-						file
-					});
-
-					if (sfInstance != null) {
-						method = sfClass.getMethod("getIcon", new Class[] {
-							Boolean.TYPE
-						});
-						if (method != null) {
-							awtImage = (java.awt.Image) method.invoke(sfInstance,
-									new Object[] {
-										new Boolean(bBig)
-									});
-						}
-					}
-				}
+			try {
+  			final Class sfClass = Class.forName("sun.awt.shell.ShellFolder");
+  			if (sfClass != null && file != null) {
+  				Method method = sfClass.getMethod("getShellFolder", new Class[] {
+  					File.class
+  				});
+  				if (method != null) {
+  					Object sfInstance = method.invoke(null, new Object[] {
+  						file
+  					});
+  
+  					if (sfInstance != null) {
+  						method = sfClass.getMethod("getIcon", new Class[] {
+  							Boolean.TYPE
+  						});
+  						if (method != null) {
+  							awtImage = (java.awt.Image) method.invoke(sfInstance,
+  									new Object[] {
+  										new Boolean(bBig)
+  									});
+  						}
+  					}
+  				}
+  			}
+			} catch (Throwable e) {
 			}
 
 			if (awtImage != null) {
diff --git a/org/gudy/azureus2/ui/swt/Main.java b/org/gudy/azureus2/ui/swt/Main.java
index d9e8463..1d6d752 100644
--- a/org/gudy/azureus2/ui/swt/Main.java
+++ b/org/gudy/azureus2/ui/swt/Main.java
@@ -21,15 +21,17 @@
 package org.gudy.azureus2.ui.swt;
 
 import java.io.File;
-
-import com.aelitis.azureus.core.*;
-import com.aelitis.azureus.launcher.Launcher;
+import java.lang.reflect.Constructor;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.util.Base32;
 import org.gudy.azureus2.core3.util.ByteFormatter;
-import org.gudy.azureus2.ui.swt.mainwindow.Initializer;
+
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreException;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.launcher.Launcher;
 
 /**
  * @author Olivier
@@ -56,6 +58,26 @@ Main
   			// This *has* to be done first as it sets system properties that are read and cached by Java
   		
   		COConfigurationManager.preInitialise();
+
+			Constructor constructor = null;
+			try {
+				Class az3Class = Class.forName("com.aelitis.azureus.ui.swt.Initializer");
+
+				constructor = az3Class.getConstructor(new Class[] {
+						AzureusCore.class,
+						StartServer.class,
+						String[].class
+				});
+			} catch (ClassNotFoundException cnfe) {
+				System.err.println(cnfe.toString() + "\nDid you include the azureus3 module?");
+				return;
+			} catch (Throwable t) {
+
+				t.printStackTrace();
+
+				return;
+			}
+
   		
 	  	String	mi_str = System.getProperty( PR_MULTI_INSTANCE );
 	  	
@@ -73,8 +95,12 @@ Main
 	    	
 		  AzureusCore		core = AzureusCoreFactory.create();
 
-	      new Initializer(core,startServer,args);
-	      
+  			constructor.newInstance(new Object[] {
+  				core,
+  				startServer,
+  				args
+  			});
+
 	      return;
 	    }
 	    
@@ -85,13 +111,22 @@ Main
 	    	
 	    	startServer.pollForConnections(core);
 	
-	    	new Initializer(core,startServer,args);
+  			constructor.newInstance(new Object[] {
+  				core,
+  				startServer,
+  				args
+  			});
 	      
 	    }
 	    
   	}catch( AzureusCoreException e ){
   		
   		Logger.log(new LogEvent(LOGID, "Start failed", e));
+
+  	}catch( Throwable t ){
+
+			t.printStackTrace();
+ 
   	}
   }
   
@@ -169,6 +204,8 @@ Main
         if( 	filename.toUpperCase().startsWith( "HTTP:" ) || 
         		filename.toUpperCase().startsWith( "HTTPS:" ) || 
         		filename.toUpperCase().startsWith( "MAGNET:" ) ||
+           		filename.toUpperCase().startsWith( "BC:" ) ||
+           		filename.toUpperCase().startsWith( "BCTP:" ) ||
         		filename.toUpperCase().startsWith( "DHT:" ) ) {
 
         	if ( !another_instance ){
diff --git a/org/gudy/azureus2/ui/swt/MenuBuildUtils.java b/org/gudy/azureus2/ui/swt/MenuBuildUtils.java
index 6279cce..9058581 100644
--- a/org/gudy/azureus2/ui/swt/MenuBuildUtils.java
+++ b/org/gudy/azureus2/ui/swt/MenuBuildUtils.java
@@ -76,6 +76,9 @@ public class MenuBuildUtils {
 	public static void addMaintenanceListenerForMenu(final Menu menu,
 			final MenuBuilder builder) {
 
+		if (Constants.isLinux) { // Hack for Ubuntu Unity -- Show not called when no items
+			new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR);
+		}
 		// Was taken from TableView.java
 		menu.addMenuListener(new MenuListener() {
 			boolean bShown = false;
@@ -97,6 +100,9 @@ public class MenuBuildUtils {
 						for (int i = 0; i < items.length; i++) {
 							items[i].dispose();
 						}
+						if (Constants.isLinux) { // Hack for Ubuntu Unity -- Show not called when no items
+							new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR);
+						}
 					}
 				});
 			};
@@ -108,6 +114,11 @@ public class MenuBuildUtils {
 
 				bShown = true;
 				builder.buildMenu(menu, e);
+				if (Constants.isLinux) { // Hack for Ubuntu Unity -- Show not called when no items
+					if (menu.getItemCount() == 0) {
+						new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR);
+					}
+				}
 			}
 		});
 	}
diff --git a/org/gudy/azureus2/ui/swt/Messages.java b/org/gudy/azureus2/ui/swt/Messages.java
index b27da7e..6974fe5 100644
--- a/org/gudy/azureus2/ui/swt/Messages.java
+++ b/org/gudy/azureus2/ui/swt/Messages.java
@@ -28,6 +28,7 @@ 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.ui.swt.views.table.TableColumnOrTreeColumn;
 
 import java.util.regex.Pattern;
 
@@ -267,7 +268,11 @@ public class Messages {
         else if(widget instanceof ToolItem) 
             ((ToolItem) widget).setText(message);
         else if(widget instanceof Text) 
-            ((Text) widget).setText(message);
+          ((Text) widget).setText(message);
+        else if(widget instanceof TableColumnOrTreeColumn) 
+          ((TableColumnOrTreeColumn) widget).setText(message);
+        else if(widget instanceof TreeColumn) 
+          ((TreeColumn) widget).setText(message);
         else{
           Debug.out( "No cast for " + widget.getClass().getName());
         }
diff --git a/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java b/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
index 798ee1b..8e79f61 100644
--- a/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
+++ b/org/gudy/azureus2/ui/swt/OpenTorrentWindow.java
@@ -47,10 +47,15 @@ import org.gudy.azureus2.core3.config.StringList;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerInitialisationAdapter;
+import org.gudy.azureus2.core3.download.DownloadManagerState;
 import org.gudy.azureus2.core3.global.GlobalManager;
+import org.gudy.azureus2.core3.global.GlobalManagerEvent;
 import org.gudy.azureus2.core3.internat.LocaleTorrentUtil;
 import org.gudy.azureus2.core3.internat.LocaleUtilDecoder;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
+import org.gudy.azureus2.core3.logging.LogAlert;
+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;
@@ -65,7 +70,11 @@ import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+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.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
 
@@ -212,13 +221,14 @@ public class OpenTorrentWindow
 	 */
 	public synchronized static final void invoke(Shell parent, GlobalManager gm,
 			String sPathOfFilesToOpen, String[] sFilesToOpen,
-			boolean bDefaultStopped, boolean bForSeeding, boolean bPopupOpenURL) {
+			boolean bDefaultStopped, boolean bForSeeding, 
+			boolean bPopupOpenURL, boolean forceOpen ){
 
 		String saveSilentlyDir = null;
 
 		if (stOpenTorrentWindow == null) {
 			boolean bMustOpen = (sPathOfFilesToOpen == null && sFilesToOpen == null)
-					|| bForSeeding;
+					|| bForSeeding || forceOpen;
 			if (!bMustOpen) {
 				saveSilentlyDir = getSaveSilentlyDir();
 				bMustOpen = saveSilentlyDir == null;
@@ -248,7 +258,7 @@ public class OpenTorrentWindow
 			}
 
 			if (bPopupOpenURL)
-				openTorrentWindow.browseURL();
+				openTorrentWindow.browseURL( false );
 
 			if (saveSilentlyDir != null) {
 				openTorrentWindow.sDestDir = saveSilentlyDir;
@@ -270,12 +280,12 @@ public class OpenTorrentWindow
 	 */
 	public synchronized static final void invoke(final Shell parent,
 			GlobalManager gm) {
-		invoke(parent, gm, null, null, false, false, false);
+		invoke(parent, gm, null, null, false, false, false, false);
 	}
 
 	public synchronized static final void invokeURLPopup(final Shell parent,
 			GlobalManager gm) {
-		invoke(parent, gm, null, null, false, false, true);
+		invoke(parent, gm, null, null, false, false, true, false );
 	}
 
 	/**
@@ -372,10 +382,18 @@ public class OpenTorrentWindow
 		Messages.setLanguageText(browseURL, "OpenTorrentWindow.addFiles.URL");
 		browseURL.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
-				browseURL();
+				browseURL( false );
 			}
 		});
 
+		Button browseMagnet = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(browseMagnet, "OpenTorrentWindow.addFiles.magnet");
+		browseMagnet.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				browseURL( true );
+			}
+		});
+		
 		Button browseFolder = new Button(cButtons, SWT.PUSH);
 		Messages.setLanguageText(browseFolder, "OpenTorrentWindow.addFiles.Folder");
 		browseFolder.addListener(SWT.Selection, new Listener() {
@@ -1015,8 +1033,8 @@ public class OpenTorrentWindow
 		}
 	}
 
-	private void browseURL() {
-		new OpenUrlWindow(shellForChildren, null, null,
+	private void browseURL( boolean default_magnet ) {
+		new OpenUrlWindow(shellForChildren, null, default_magnet, null,
 				OpenTorrentWindow.this);
 	}
 
@@ -1225,6 +1243,69 @@ public class OpenTorrentWindow
 
 		item = new MenuItem(menu, SWT.SEPARATOR);
 
+			// ip filter mode
+		
+		final MenuItem ipf_enable = new MenuItem(menu, SWT.CHECK );
+		// steal text
+		Messages.setLanguageText(ipf_enable, "MyTorrentsView.menu.ipf_enable");
+		ipf_enable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int[] indexes = torrentTable.getSelectionIndices();
+				for (int i = 0; i < indexes.length; i++){
+					
+					TorrentInfo info = (TorrentInfo) torrentList.get(indexes[i]);
+					
+					info.disableIPFilter = !ipf_enable.getSelection();
+				}
+			}
+		});
+		
+		menu.addListener(
+			SWT.Show, 
+			new Listener()
+			{
+				public void
+				handleEvent(Event e) 
+				{
+					int[] indexes = torrentTable.getSelectionIndices();
+
+					boolean bEnabled = 	indexes.length > 0 &&
+										IpFilterManagerFactory.getSingleton().getIPFilter().isEnabled();
+					
+					if ( bEnabled ){
+						boolean allChecked 		= true;
+						boolean allUnchecked	= true;
+				
+						for (int i = 0; i < indexes.length; i++){
+							
+							TorrentInfo info = (TorrentInfo) torrentList.get(indexes[i]);
+							
+							boolean b = info.disableIPFilter;
+								
+							if ( b ){
+								allUnchecked 	= false;
+							}else{
+								allChecked 		= false;
+							}
+						}
+			
+						boolean	bChecked;
+						
+						if ( allUnchecked ){
+							bChecked = true;
+						}else if ( allChecked ){
+							bChecked = false;
+						}else{
+							bChecked = false;
+						}
+						
+						ipf_enable.setSelection(bChecked);
+					}
+					
+					ipf_enable.setEnabled(bEnabled);	
+				}
+			});
+		
 		item = new MenuItem(menu, SWT.PUSH);
 		// steal text
 		Messages.setLanguageText(item, "MyTorrentsView.menu.remove");
@@ -1409,8 +1490,13 @@ public class OpenTorrentWindow
 					if (!fileInfo.bDownload)
 						continue;
 
+					File file = fileInfo.getInitialLink();
 
-					File file = fileInfo.getDestFileFullName();
+					if ( file == null ){
+					
+						file = fileInfo.getDestFileFullName();
+					}
+					
 					if (!file.exists()) {
 						fileInfo.isValid = false;
 						bTorrentValid = false;
@@ -1963,7 +2049,7 @@ public class OpenTorrentWindow
 					if (COConfigurationManager.getBooleanParameter("Add URL Silently")) {
 						new FileDownloadWindow(shellForChildren, sURL, null, null, this);
 					} else {
-						new OpenUrlWindow(shellForChildren, sURL, null, this);
+						new OpenUrlWindow(shellForChildren, sURL, false, null, this);
 					}
 					numAdded++;
 					continue;
@@ -2028,6 +2114,28 @@ public class OpenTorrentWindow
 				return null;
 			}
 
+			if (fOriginal.length() > 20*1024*1024) {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						if (shell == null)
+							new MessageSlideShell(Display.getCurrent(), SWT.ICON_ERROR,
+									"OpenTorrentWindow.mb.openError", fOriginal.toString(), new String[] {
+										UrlUtils.decode(sOriginatingLocation),
+										"Too large to be a torrent"
+									}, -1 );
+						else {
+							MessageBoxShell mb = new MessageBoxShell(SWT.OK,
+									"OpenTorrentWindow.mb.openError", new String[] {
+										sOriginatingLocation,
+										"Too large to be a torrent"
+									});
+							mb.open(null);
+						}
+					}
+				});
+				return null;
+			}
+
 			torrentFile = TorrentUtils.copyTorrentFileToSaveDir(fOriginal, true);
 			bDeleteFileOnCancel = !fOriginal.equals(torrentFile);
 			// TODO if the files are still equal, and it isn't in the save
@@ -2040,6 +2148,17 @@ public class OpenTorrentWindow
 			torrentFile = new File(sFileName);
 		}
 
+		VuzeFileHandler vfh = VuzeFileHandler.getSingleton();
+		
+		VuzeFile vf = vfh.loadVuzeFile( torrentFile );
+		
+		if ( vf != null ){
+			
+  			vfh.handleFiles( new VuzeFile[]{ vf }, VuzeFileComponent.COMP_TYPE_NONE );
+
+  			return null;
+		}
+		
 		// Do a quick check to see if it's a torrent
 		if (!TorrentUtil.isFileTorrent(torrentFile, shellForChildren,
 				torrentFile.getName())) {
@@ -2053,6 +2172,7 @@ public class OpenTorrentWindow
 		try {
 			torrent = TorrentUtils.readFromFile(torrentFile, false);
 		} catch (final TOTorrentException e) {
+			
 			Utils.execSWTThread(new AERunnable() {
 				public void runSupport() {
 					if (shell == null)
@@ -2121,9 +2241,13 @@ public class OpenTorrentWindow
 
 			final String sfExistingName = sExistingName;
 			final DownloadManager fExistingDownload = existingDownload;
+			
+			fExistingDownload.fireGlobalManagerEvent( GlobalManagerEvent.ET_REQUEST_ATTENTION );
+			
 			Utils.execSWTThread(new AERunnable() {
 				public void runSupport() {
-					if (shell == null)
+					Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
+					if (Display.getDefault().getActiveShell() == null || !mainShell.isVisible() || mainShell.getMinimized() ) {
 						new MessageSlideShell(Display.getCurrent(), SWT.ICON_INFORMATION,
 								MSG_ALREADY_EXISTS, null, new String[] {
 									":" + sOriginatingLocation,
@@ -2132,7 +2256,7 @@ public class OpenTorrentWindow
 								}, new Object[] {
 									fExistingDownload
 								}, -1 );
-					else {
+					} else {
 						MessageBoxShell mb = new MessageBoxShell(SWT.OK, MSG_ALREADY_EXISTS,
 								new String[] {
 									":" + sOriginatingLocation,
@@ -2244,12 +2368,20 @@ public class OpenTorrentWindow
 				{
 					public void initialised(DownloadManager dm) {
 						DiskManagerFileInfo[] fileInfos = dm.getDiskManagerFileInfo();
+						
+						boolean	reorder_mode 		= COConfigurationManager.getBooleanParameter( "Enable reorder storage mode" );
+						int		reorder_mode_min_mb = COConfigurationManager.getIntParameter( "Reorder storage mode min MB" );
+						
 						try
 						{
 							dm.getDownloadState().suppressStateSave(true);
 							
-							boolean[] toSkip = new boolean[fileInfos.length];
-							boolean[] toCompact = new boolean[fileInfos.length];
+							boolean[] toSkip 			= new boolean[fileInfos.length];
+							boolean[] toCompact 		= new boolean[fileInfos.length];
+							boolean[] toReorderCompact 	= new boolean[fileInfos.length];
+							
+							int	comp_num 			= 0;
+							int reorder_comp_num	= 0;
 							
 							for (int iIndex = 0; iIndex < fileInfos.length; iIndex++)
 							{
@@ -2260,27 +2392,58 @@ public class OpenTorrentWindow
 									// TorrentFileInfo because the destination may have changed
 									// by magic code elsewhere
 									File fDest = fileInfo.getFile(true);
-									if (files[iIndex].isLinked())
-									{
+									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);
+										
+											// Can't use fileInfo.setLink(fDest) as it renames
+											// the existing file if there is one
+										
+										dm.getDownloadState().setFileLink( fileInfo.getFile(false), fDest);
 									}
-									if (!files[iIndex].bDownload)
-									{
+									
+									if (!files[iIndex].bDownload){
+									
 										toSkip[iIndex] = true;
-										if (!fDest.exists())
-											toCompact[iIndex] = true;
+										
+										if (!fDest.exists()){
+											
+											if ( reorder_mode && ( fileInfo.getLength()/(1024*1024)) >= reorder_mode_min_mb ){
+												
+												toReorderCompact[iIndex] = true;
+												
+												reorder_comp_num++;
+												
+											}else{
+												
+												toCompact[iIndex] = true;
+												
+												comp_num++;
+											}
+										}
 									}
 								}
 							}
 							
-							dm.getDiskManagerFileInfoSet().setStorageTypes(toCompact, DiskManagerFileInfo.ST_COMPACT);
+							if ( comp_num > 0 ){
+								
+								dm.getDiskManagerFileInfoSet().setStorageTypes(toCompact, DiskManagerFileInfo.ST_COMPACT);
+							}
+							
+							if ( reorder_comp_num > 0 ){
+								
+								dm.getDiskManagerFileInfoSet().setStorageTypes(toReorderCompact, DiskManagerFileInfo.ST_REORDER_COMPACT );
+							}
+							
 							dm.getDiskManagerFileInfoSet().setSkipped(toSkip, true);
-						} finally
-						{
+							
+							if ( info.disableIPFilter ){
+								
+								dm.getDownloadState().setFlag( DownloadManagerState.FLAG_DISABLE_IP_FILTER, true );
+							}
+							
+						}finally{
+						
 							dm.getDownloadState().suppressStateSave(false);
 						}
 					}
@@ -2476,6 +2639,10 @@ public class OpenTorrentWindow
 
 		private TorrentFileInfo[] files = null;
 
+		boolean disableIPFilter = false;
+		
+		Map<Integer,File>		initial_linkage_map;
+		
 		/**
 		 * Init
 		 * 
@@ -2491,6 +2658,8 @@ public class OpenTorrentWindow
 			this.torrent = torrent;
 			this.sDestDir = OpenTorrentWindow.this.sDestDir;
 
+			initial_linkage_map	= TorrentUtils.getInitialLinkage( torrent );
+			
 			iStartID = getDefaultStartMode();
 			iQueueLocation = QUEUELOCATION_BOTTOM;
 			isValid = true;
@@ -2509,6 +2678,13 @@ public class OpenTorrentWindow
 			}
 		}
 
+		public File
+		getInitialLinkage(
+			int		index )
+		{
+			return( initial_linkage_map.get( index ));
+		}
+		
 		public String getParentDir() {
 			return sDestDir;
 		}
@@ -2620,20 +2796,7 @@ public class OpenTorrentWindow
 		}
 
 		public String getTorrentName() {
-			if (torrent == null)
-				return "";
-			try {
-				LocaleUtilDecoder decoder = LocaleTorrentUtil.getTorrentEncodingIfAvailable(torrent);
-				if (decoder != null)
-					return decoder.decodeString(torrent.getName());
-			} catch (Exception e) {
-			}
-
-			try {
-				return new String(torrent.getName());
-			} catch (Exception e) {
-				return "TextDecodingError";
-			}
+			return TorrentUtils.getLocalisedName(torrent);
 		}
 
 		public boolean allFilesMoving() {
@@ -2759,7 +2922,7 @@ public class OpenTorrentWindow
 		private String destFileName;
 		private String destPathName;
 
-		long iIndex;
+		int iIndex;
 
 		boolean isValid;
 
@@ -2779,7 +2942,7 @@ public class OpenTorrentWindow
 			this.iIndex = iIndex;
 			bDownload = true;
 			isValid = true;
-
+			
 			orgFullName = torrentFile.getRelativePath(); // translated to locale
 			orgFileName = new File(orgFullName).getName();
 		}
@@ -2837,6 +3000,12 @@ public class OpenTorrentWindow
 		public boolean okToDisable() {
 			return /* lSize >= MIN_NODOWNLOAD_SIZE	|| */parent.okToDisableAll();
 		}
+
+		public File
+		getInitialLink()
+		{
+			return( parent.getInitialLinkage( iIndex ));
+		}
 		
 		public boolean isLinked()
 		{
diff --git a/org/gudy/azureus2/ui/swt/OpenUrlWindow.java b/org/gudy/azureus2/ui/swt/OpenUrlWindow.java
index ed5196d..34404a0 100644
--- a/org/gudy/azureus2/ui/swt/OpenUrlWindow.java
+++ b/org/gudy/azureus2/ui/swt/OpenUrlWindow.java
@@ -66,7 +66,7 @@ OpenUrlWindow
 	 */
 	public OpenUrlWindow(final Shell parent,
 			String linkURL, final String referrer) {
-		this(parent, linkURL, referrer, null);
+		this(parent, linkURL, false, referrer, null);
 	}
 
 	/**
@@ -79,7 +79,7 @@ OpenUrlWindow
 	 * @param listener
 	 */
 	public OpenUrlWindow(final Shell parent,
-			String linkURL, final String referrer,
+			String linkURL, boolean default_magnet, final String referrer, 
 			final TorrentDownloaderCallBackInterface listener) {
 
     final Shell shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM
@@ -106,7 +106,7 @@ OpenUrlWindow
     gridData.horizontalSpan	= 2;
     url.setLayoutData(gridData);
     if(linkURL == null)
-      Utils.setTextLinkFromClipboard(shell, url, true);
+      Utils.setTextLinkFromClipboard(shell, url, true, default_magnet );
     else
     	url.setText(linkURL);
     url.setSelection(url.getText().length());
@@ -198,7 +198,11 @@ OpenUrlWindow
       	
       	String	url_str = url.getText();
       	
-      	url_str = UrlUtils.parseHTMLforURL( url_str );
+      	url_str = UrlUtils.parseTextForURL( url_str, true );
+      	
+      	if (url_str == null) {
+      		url_str = UrlUtils.parseTextForMagnets(url.getText());
+      	}
       	
       	if ( url_str == null ){
       		
diff --git a/org/gudy/azureus2/ui/swt/PropertiesWindow.java b/org/gudy/azureus2/ui/swt/PropertiesWindow.java
index af6825a..84e7b91 100644
--- a/org/gudy/azureus2/ui/swt/PropertiesWindow.java
+++ b/org/gudy/azureus2/ui/swt/PropertiesWindow.java
@@ -47,7 +47,7 @@ PropertiesWindow
 		String[]	keys,
 		String[]	values )
 	{	
-		shell = ShellFactory.createMainShell(SWT.APPLICATION_MODAL | SWT.TITLE | SWT.CLOSE |SWT.RESIZE );
+		shell = ShellFactory.createMainShell(SWT.TITLE | SWT.CLOSE |SWT.RESIZE );
 
 		shell.setText( MessageText.getString( "props.window.title", new String[]{ object_name }));
 		
@@ -103,7 +103,9 @@ PropertiesWindow
 		    BufferedLabel	msg_label = new BufferedLabel(main, SWT.NULL);
 		    String msg;
 		    String key = keys[i];
-		    if ( key.startsWith( "!" ) && key.endsWith( "!" )){
+		    if ( key.length() == 0 ){
+		    	msg = "";
+		    }else if ( key.startsWith( "!" ) && key.endsWith( "!" )){
 		    	msg = key.substring(1, key.length()-1 );
 		    }else{
 		    	msg = MessageText.getString( key );
@@ -120,7 +122,7 @@ PropertiesWindow
 		    	value = "";
 		    }else{
 		    	
-		    	msg_label.setText( msg + ":" );
+		    	msg_label.setText( msg.length()==0?"":(msg + ":" ));
 		    }
 		    
 		    gridData = new GridData();
@@ -179,17 +181,19 @@ PropertiesWindow
 			}
 		});
 	
-	 	int	shell_width = 400;
-	 	
-	 	int	main_height = main.computeSize(shell_width, SWT.DEFAULT).y;
-	 	
-	 	main_height = Math.max( main_height, 250 );
-	 	
-	 	main_height = Math.min( main_height, 500 );
-
-	 	int shell_height = main_height + 50;
-	 		
-	 	shell.setSize( shell_width, shell_height );
+	 	if (!Utils.linkShellMetricsToConfig(shell, "PropWin")) {
+  	 	int	shell_width = 400;
+  	 	
+  	 	int	main_height = main.computeSize(shell_width, SWT.DEFAULT).y;
+  	 	
+  	 	main_height = Math.max( main_height, 250 );
+  	 	
+  	 	main_height = Math.min( main_height, 500 );
+  
+  	 	int shell_height = main_height + 50;
+  	 		
+  	 	shell.setSize( shell_width, shell_height );
+	 	}
 
 		Utils.centreWindow( shell );
 
diff --git a/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java b/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
index 112bfb7..65b7406 100644
--- a/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
+++ b/org/gudy/azureus2/ui/swt/SimpleTextEntryWindow.java
@@ -21,16 +21,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.events.*;
 import org.eclipse.swt.layout.*;
 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.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;
 
 /**
@@ -41,6 +40,9 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	
 	private Display display;
 	private Shell shell;
+	private int textLimit;
+	private Combo text_entry_combo;
+	private Text text_entry_text;
 	
 	public SimpleTextEntryWindow() {
 	}
@@ -91,6 +93,7 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 		Utils.setShellIcon(shell);
 		
 	    GridLayout layout = new GridLayout();
+	    layout.verticalSpacing = 10;
 	    shell.setLayout(layout);
 	    
 	    // Default width hint is 330.
@@ -111,8 +114,6 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    
 	    // Create Text object with pre-entered text.
 	    final Scrollable text_entry;
-	    final Combo text_entry_combo;
-	    final Text text_entry_text;
 	    if (this.choices != null) {
 	    	int text_entry_flags = SWT.DROP_DOWN;
 	    	if (!this.choices_allow_edit) {
@@ -121,6 +122,9 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    	
 	    	text_entry_combo = new Combo(shell, text_entry_flags);
 	    	text_entry_combo.setItems(this.choices);
+	    	if (textLimit > 0) {
+	    		text_entry_combo.setTextLimit(textLimit);
+	    	}
 	    	text_entry_text = null;
 	    	text_entry = text_entry_combo;
 	    }
@@ -137,6 +141,9 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    	
 	    	text_entry_text = new Text(shell, text_entry_flags);
 	    	
+	    	if (textLimit > 0) {
+	    		text_entry_text.setTextLimit(textLimit);
+	    	}
 	    	text_entry_combo = null;
 	    	text_entry = text_entry_text;
 	    }
@@ -161,6 +168,26 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    	}
 	    });
 	    
+	    text_entry.addKeyListener(new KeyListener() {
+
+				public void keyPressed(KeyEvent e) {
+					int key = e.character;
+					if (key <= 26 && key > 0) {
+						key += 'a' - 1;
+					}
+					
+					if (key == 'a' && e.stateMask == SWT.MOD1) {
+						if (text_entry_text != null) {
+							text_entry_text.selectAll();
+						}
+					}
+				}
+
+				public void keyReleased(KeyEvent e) {
+				}
+	    	
+	    });
+	    
 	    // Default behaviour - single mode results in default height of 1 line,
 	    // multiple lines has default height of 3.
 	    int line_height = this.line_height;
@@ -186,14 +213,21 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    } catch (NoSuchFieldError e) {
 	    	// SWT 2.x
 	    }
-	    rLayout.spacing = ControlUtils.getButtonMargin();
+	    rLayout.spacing = Utils.BUTTON_MARGIN;
 	    panel.setLayout(rLayout);
 	    gridData = new GridData();
 	    gridData.horizontalAlignment = (Constants.isOSX) ? SWT.END : SWT.CENTER;
 	    panel.setLayoutData(gridData);
 
-	    Button ok = createAlertButton(panel, "Button.ok");
-	    Button cancel = createAlertButton(panel, "Button.cancel");
+	    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() {
 	    	
@@ -219,12 +253,16 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    		  else if (text_entry_combo != null) {
 	    			  entered_data = text_entry_combo.getText();
 	    		  }
-	    		  
+
 	    		  
 	    		  if (!SimpleTextEntryWindow.this.maintain_whitespace) {
 	    			  entered_data = entered_data.trim();
 	    		  }
 	    		  
+	    		  if (textLimit > 0 && entered_data.length() > textLimit) {
+	    		  	entered_data = entered_data.substring(0, textLimit);
+	    		  }
+	    		  
 	    		  if (!SimpleTextEntryWindow.this.allow_empty_input && entered_data.length() == 0) {
 	    			  showError(MessageText.getString("UI.cannot_submit_blank_text"));
 	    			  return;
@@ -271,6 +309,9 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 		
 		shell.addListener(SWT.Dispose, new Listener() {
 			public void handleEvent(Event event) {
+				if (!isResultRecorded()) {
+					recordUserAbort();
+				}
 				triggerReceiverListener();
 			}
 		});
@@ -278,7 +319,11 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
 	    shell.pack();
 	    if (text_entry_text != null)
 	    	Utils.createURLDropTarget(shell, text_entry_text);
-	    Utils.centreWindow(shell);
+	    
+	    	// don't shrink this control otherwise the manual speed entry for up/down speed on
+	    	// the transfers bar doesn't work as parent shell small...
+	    
+	    Utils.centreWindow(shell,false);
 	    shell.open();
 	  }
 
@@ -288,11 +333,24 @@ public class SimpleTextEntryWindow extends AbstractUISWTInputReceiver {
       button.setText(MessageText.getString(localizationKey));
       final RowData rData = new RowData();
       rData.width = Math.max(
-              ControlUtils.getDialogButtonMinWidth(),
+              Utils.BUTTON_MINWIDTH,
               button.computeSize(SWT.DEFAULT,  SWT.DEFAULT).x
         );
       button.setLayoutData(rData);
       return button;
   }
 
+  public void setTextLimit(int limit) {
+  	textLimit = limit;
+  	Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (text_entry_combo != null && !text_entry_combo.isDisposed()) {
+					text_entry_combo.setTextLimit(textLimit);
+				}
+				if (text_entry_text != null && !text_entry_text.isDisposed()) {
+					text_entry_text.setTextLimit(textLimit);
+				}
+			}
+		});
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/Sleak.java b/org/gudy/azureus2/ui/swt/Sleak.java
deleted file mode 100644
index 0f3d9ed..0000000
--- a/org/gudy/azureus2/ui/swt/Sleak.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Created on Sep 10, 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;
-
-/*
- * Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
- * This file is made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- */
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Code to detect swt leak
- *
- */
-public class Sleak
-{
-	Display display;
-
-	Shell shell;
-
-	List list;
-
-	Canvas canvas;
-
-	Button start, stop, check;
-
-	Text text;
-
-	Text label;
-
-	Object[] oldObjects = new Object[0];
-
-	Error[] oldErrors = new Error[0];
-
-	Object[] objects = new Object[0];
-
-	Error[] errors = new Error[0];
-	
-	Map all = new HashMap();
-	
-	ArrayList oldNonResources = new ArrayList();
-
-	public void open() {
-		display = Display.getCurrent();
-		shell = new Shell(display);
-		shell.setText("S-Leak");
-		list = new List(shell, SWT.BORDER | SWT.V_SCROLL);
-		list.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshObject();
-			}
-		});
-		text = new Text(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
-		canvas = new Canvas(shell, SWT.BORDER);
-		canvas.addListener(SWT.Paint, new Listener() {
-			public void handleEvent(Event event) {
-				paintCanvas(event);
-			}
-		});
-		check = new Button(shell, SWT.CHECK);
-		check.setText("Stack");
-		check.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				toggleStackTrace();
-			}
-		});
-		start = new Button(shell, SWT.PUSH);
-		start.setText("Snap");
-		start.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshAll();
-			}
-		});
-		stop = new Button(shell, SWT.PUSH);
-		stop.setText("Diff");
-		stop.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event event) {
-				refreshDifference();
-			}
-		});
-		label = new Text(shell, SWT.BORDER | SWT.READ_ONLY + SWT.MULTI);
-		label.setText("0 object(s)");
-		shell.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event e) {
-				layout();
-			}
-		});
-		check.setSelection(false);
-		text.setVisible(false);
-		Point size = shell.getSize();
-		shell.setSize(size.x / 2, size.y / 2);
-		shell.open();
-	}
-
-	void refreshLabel() {
-		int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0, regions = 0, others = 0, composites = 0, labels = 0;
-		for (int i = 0; i < objects.length; i++) {
-			Object object = objects[i];
-			if (object instanceof Color) {
-				colors++;
-			} else if (object instanceof Cursor) {
-				cursors++;
-			} else if (object instanceof Font) {
-				fonts++;
-			} else if (object instanceof GC) {
-				gcs++;
-			} else if (object instanceof Image) {
-				images++;
-			} else if (object instanceof Region) {
-				regions++;
-			} else if (object instanceof Composite) {
-				composites++;
-			} else if (object instanceof Label) {
-				labels++;
-			} else {
-				others++;
-			}
-		}
-		String string = "";
-		if (colors != 0) {
-			string += colors + " Color(s)\n";
-		}
-		if (cursors != 0) {
-			string += cursors + " Cursor(s)\n";
-		}
-		if (fonts != 0) {
-			string += fonts + " Font(s)\n";
-		}
-		if (gcs != 0) {
-			string += gcs + " GC(s)\n";
-		}
-		if (images != 0) {
-			string += images + " Image(s)\n";
-		}
-		if (composites != 0) {
-			string += composites + " composite(s)\n";
-		}
-		if (labels != 0) {
-			string += labels + " label(s)\n";
-		}
-		if (others != 0) {
-			string += others + " Other(s)\n";
-		}
-		/* Currently regions are not counted. */
-		//	if (regions != 0) string += regions + " Region(s)\n";
-		if (string.length() != 0) {
-			string = string.substring(0, string.length() - 1);
-		}
-		label.setText(string);
-	}
-
-	void refreshDifference() {
-		DeviceData info = display.getDeviceData();
-		if (!info.tracking) {
-			MessageBox dialog = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
-			dialog.setText(shell.getText());
-			dialog.setMessage("Warning: Device is not tracking resource allocation");
-			dialog.open();
-		}
-		Object[] newObjects = info.objects;
-		Error[] newErrors = info.errors;
-		Object[] diffObjects = new Object[newObjects.length];
-		Error[] diffErrors = new Error[newErrors.length];
-		int countResourceType = 0;
-		for (int i = 0; i < newObjects.length; i++) {
-			int index = 0;
-			while (index < oldObjects.length) {
-				if (newObjects[i] == oldObjects[index]) {
-					break;
-				}
-				index++;
-			}
-			if (index == oldObjects.length) {
-				diffObjects[countResourceType] = newObjects[i];
-				diffErrors[countResourceType] = newErrors[i];
-				countResourceType++;
-			}
-		}
-
-		Shell[] shells = display.getShells();
-		ArrayList nonResourceList = new ArrayList();
-		for (int i = 0; i < shells.length; i++) {
-			Shell shell = shells[i];
-			if (shell != this.shell) {
-				buildObjectList(shell, nonResourceList);
-			}
-		}
-		oldNonResources = nonResourceList;
-		Object[] nonResources = nonResourceList.toArray();
-		int countNonResources = nonResources.length;
-
-		int total = countResourceType + countNonResources;
-
-		objects = new Object[total];
-		errors = new Error[total];
-		System.arraycopy(diffObjects, 0, objects, 0, countResourceType);
-		System.arraycopy(diffErrors, 0, errors, 0, countResourceType);
-		System.arraycopy(nonResources, 0, objects, countResourceType,
-				countNonResources);
-		list.removeAll();
-		text.setText("");
-		canvas.redraw();
-		for (int i = 0; i < objects.length; i++) {
-			list.add(objectName(objects[i]));
-		}
-		System.out.println(countResourceType);
-		refreshLabel();
-		layout();
-	}
-
-	/**
-	 * @param shell2
-	 * @param list2
-	 */
-	private void buildObjectList(Control control, ArrayList list) {
-		if (!oldNonResources.contains(control)) {
-			list.add(control);
-		}
-
-		if (control instanceof Composite) {
-			Composite c = (Composite) control;
-			Control[] children = c.getChildren();
-			for (int i = 0; i < children.length; i++) {
-				Control control2 = children[i];
-				buildObjectList(control2, list);
-			}
-		}
-	}
-
-	String objectName(Object object) {
-		Date timeAdded = (Date)all.get(object);
-		if (timeAdded == null) {
-			timeAdded = new Date();
-			all.put(object, timeAdded);
-		}
-
-		String string = timeAdded + "] " + object.toString();
-		if (object instanceof Resource) {
-			return string;
-		}
-
-		int index = string.indexOf(" {");
-		if (index == -1) {
-			return string;
-		}
-		string = string.substring(0, index);
-		if (object instanceof Composite) {
-			Control[] children = ((Composite) object).getChildren();
-			string += ": " + children.length + " kids";
-		}
-		return string;
-	}
-
-	void toggleStackTrace() {
-		refreshObject();
-		layout();
-	}
-
-	void paintCanvas(Event event) {
-		canvas.setCursor(null);
-		int index = list.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-		GC gc = event.gc;
-		Object object = objects[index];
-		if (object instanceof Color) {
-			if (((Color) object).isDisposed()) {
-				gc.drawString("Color disposed", 0, 0);
-				return;
-			}
-			gc.setBackground((Color) object);
-			gc.fillRectangle(canvas.getClientArea());
-			return;
-		}
-		if (object instanceof Cursor) {
-			if (((Cursor) object).isDisposed()) {
-				gc.drawString("Cursor disposed", 0, 0);
-				return;
-			}
-			canvas.setCursor((Cursor) object);
-			return;
-		}
-		if (object instanceof Font) {
-			if (((Font) object).isDisposed()) {
-				gc.drawString("Font disposed", 0, 0);
-				return;
-			}
-			gc.setFont((Font) object);
-			FontData[] array = gc.getFont().getFontData();
-			String string = "";
-			String lf = text.getLineDelimiter();
-			for (int i = 0; i < array.length; i++) {
-				FontData data = array[i];
-				String style = "NORMAL";
-				int bits = data.getStyle();
-				if (bits != 0) {
-					if ((bits & SWT.BOLD) != 0) {
-						style = "BOLD ";
-					}
-					if ((bits & SWT.ITALIC) != 0) {
-						style += "ITALIC";
-					}
-				}
-				string += data.getName() + " " + data.getHeight() + " " + style + lf;
-			}
-			gc.drawString(string, 0, 0);
-			return;
-		}
-		//NOTHING TO DRAW FOR GC
-		//	if (object instanceof GC) {
-		//		return;
-		//	}
-		if (object instanceof Image) {
-			if (((Image) object).isDisposed()) {
-				gc.drawString("Image disposed", 0, 0);
-				return;
-			}
-			gc.drawImage((Image) object, 0, 0);
-			return;
-		}
-		if (object instanceof Region) {
-			if (((Region) object).isDisposed()) {
-				return;
-			}
-			String string = ((Region) object).getBounds().toString();
-			gc.drawString(string, 0, 0);
-			return;
-		}
-
-		if (object instanceof Control) {
-			gc.drawString(object.toString(), 0, 0);
-			gc.drawString(((Control) object).getBounds().toString(), 0, 20);
-
-			if (object instanceof Widget) {
-				Object data = ((Widget)object).getData("sleak");
-				if (data != null) {
-					gc.drawString(data.toString(), 0, 35);
-				}
-			}
-			return;
-		}
-	}
-
-	void refreshObject() {
-		int index = list.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-		if (check.getSelection() && index < errors.length && errors[index] == null) {
-			ByteArrayOutputStream stream = new ByteArrayOutputStream();
-			PrintStream s = new PrintStream(stream);
-			errors[index].printStackTrace(s);
-			text.setText(stream.toString());
-			text.setVisible(true);
-			canvas.setVisible(false);
-		} else {
-			canvas.setVisible(true);
-			text.setVisible(false);
-			canvas.redraw();
-		}
-	}
-
-	void refreshAll() {
-		oldObjects = new Object[0];
-		oldErrors = new Error[0];
-		oldNonResources = new ArrayList();
-		refreshDifference();
-		oldObjects = objects;
-		oldErrors = errors;
-	}
-
-	void layout() {
-		Rectangle rect = shell.getClientArea();
-		int width = 0;
-		String[] items = list.getItems();
-		GC gc = new GC(list);
-		for (int i = 0; i < objects.length; i++) {
-			width = Math.max(width, gc.stringExtent(items[i]).x);
-		}
-		gc.dispose();
-		Point size1 = start.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size2 = stop.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size3 = check.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		Point size4 = label.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-		width = Math.max(size1.x, Math.max(size2.x, Math.max(size3.x, width)));
-		width = Math.max(64, Math.max(size4.x,
-				list.computeSize(width, SWT.DEFAULT).x));
-		start.setBounds(0, 0, width, size1.y);
-		stop.setBounds(0, size1.y, width, size2.y);
-		check.setBounds(0, size1.y + size2.y, width, size3.y);
-		label.setBounds(0, rect.height - size4.y, width, size4.y);
-		int height = size1.y + size2.y + size3.y;
-		list.setBounds(0, height, width, rect.height - height - size4.y);
-		text.setBounds(width, 0, rect.width - width, rect.height);
-		canvas.setBounds(width, 0, rect.width - width, rect.height);
-	}
-
-	public static void main(String[] args) {
-    DeviceData data = new DeviceData();
-    data.tracking = true;
-    Display display = new Display (data);
-		Sleak sleak = new Sleak();
-    Main.main(args);
-		sleak.open();
-		while (!sleak.shell.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-		try {
-			if (!display.isDisposed()) {
-				display.dispose();
-			}
-		} catch (Exception e) {
-			// TODO: handle exception
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/StartServer.java b/org/gudy/azureus2/ui/swt/StartServer.java
index 1e21ca0..6e1ff06 100644
--- a/org/gudy/azureus2/ui/swt/StartServer.java
+++ b/org/gudy/azureus2/ui/swt/StartServer.java
@@ -38,6 +38,8 @@ import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.plugins.update.UpdateInstaller;
+import org.gudy.azureus2.plugins.update.UpdateManager;
 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
 import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
 
@@ -117,7 +119,7 @@ StartServer
 		    		public void 
 		    		runSupport()
 					{
-		    			pollForConnectionsSupport();
+		    			pollForConnectionsSupport( azureus_core );
 		    		}
 				};
 		    
@@ -128,7 +130,8 @@ StartServer
 	}
     
   private void 
-  pollForConnectionsSupport() 
+  pollForConnectionsSupport(
+		 final AzureusCore		core )
   {
     bContinue = true;
     while (bContinue) {
@@ -153,7 +156,7 @@ StartServer
         			  debug_str += " ; " + args[i];
         		  }
         		  Logger.log(new LogEvent(LOGID, "Main::startServer: decoded to '" + debug_str + "'"));
-        		  processArgs(args);
+        		  processArgs(core,args);
         	  }
           }
         }
@@ -197,6 +200,7 @@ StartServer
   
   protected void 
   processArgs(
+    AzureusCore		core,
    	String 			args[]) 
   {
     if (args.length < 1 || !args[0].equals( "args" )){
@@ -204,8 +208,8 @@ StartServer
     	return;
     }
     
-    boolean addSilent = COConfigurationManager.getBooleanParameter("add_torrents_silently");
-    boolean showMainWindow = !addSilent;
+    boolean addSilent = COConfigurationManager.getBooleanParameter("Use default data dir");
+    boolean showMainWindow = !addSilent || args.length == 1;
 
     boolean	open	= true;
     
@@ -217,8 +221,25 @@ StartServer
     		
 	  	    if ( arg.equalsIgnoreCase( "--closedown" )){
 	
+	  	    		// discard any pending updates as we need to shutdown immediately (this
+	  	    		// is called from installer to close running instance)
+	  	    	
+	  	    	try{
+	  	    		UpdateManager um = core.getPluginManager().getDefaultPluginInterface().getUpdateManager();
+	  	    		
+	  	    		UpdateInstaller[] installers = um.getInstallers();
+	  	    		
+	  	    		for ( UpdateInstaller installer: installers ){
+	  	    			
+	  	    			installer.destroy();
+	  	    		}
+	  	    	}catch( Throwable e ){
+	  	    	}
+	  	    	
 	  	    	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-	  	    	if (uiFunctions != null) {
+	  	    	
+	  	    	if ( uiFunctions != null ){
+	  	    		
 	  	    		uiFunctions.dispose(false, false);
 	  	    	}
 	  	    	
@@ -316,10 +337,12 @@ StartServer
   {
       String file_name_lower = file_name.toLowerCase();
       
-	  return( file_name_lower.startsWith( "http:" ) || 
-			  file_name_lower.startsWith( "https:" ) || 
-			  file_name_lower.startsWith( "magnet:" ) ||
-			  file_name_lower.startsWith( "dht:" ));
+	  return( 	file_name_lower.startsWith( "http:" ) || 
+			  	file_name_lower.startsWith( "https:" ) || 
+			  	file_name_lower.startsWith( "magnet:" ) ||
+			  	file_name_lower.startsWith( "bc:" ) ||
+			  	file_name_lower.startsWith( "bctp:" ) ||
+	  			file_name_lower.startsWith( "dht:" ));
   }
   
   protected void
diff --git a/org/gudy/azureus2/ui/swt/Tab.java b/org/gudy/azureus2/ui/swt/Tab.java
deleted file mode 100644
index 19f29e4..0000000
--- a/org/gudy/azureus2/ui/swt/Tab.java
+++ /dev/null
@@ -1,993 +0,0 @@
-/*
- * Created on 29 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;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.*;
-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.GridData;
-import org.eclipse.swt.layout.GridLayout;
-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.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.mainwindow.MainWindow;
-import org.gudy.azureus2.ui.swt.plugins.UISWTPluginView;
-import org.gudy.azureus2.ui.swt.plugins.UISWTView;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
-import org.gudy.azureus2.ui.swt.views.*;
-
-import com.aelitis.azureus.ui.common.updater.UIUpdatable;
-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.PluginView;
-import org.gudy.azureus2.plugins.ui.UIPluginView;
-
-/**
- * @author Olivier
- * @author James Yeh Added Add/Remove event listeners
- */
-public class Tab implements ParameterListener, UIUpdatable {
-	private static final LogIDs LOGID = LogIDs.GUI;
-	
-	private static final String ID = "TabSet";
-
-  private HashMap 	tabs;
-  private AEMonitor  class_mon 	= new AEMonitor(ID);
-
-  private boolean useCustomTab;
-
-  private Composite folder;
-
-
-  private boolean eventCloseAllowed = true;
-  private Item selectedItem = null;
-
-
-	private MainWindow mainwindow;
-
-	private Listener activateListener;
-
-  /**
-	 * 
-	 */
-	public Tab(MainWindow _mainWindow) {
-		mainwindow = _mainWindow;
-
-		tabs = new HashMap();
-		
-		COConfigurationManager.addParameterListener("GUI_SWT_bFancyTab", this);
-
-    activateListener = new Listener() {
-			public void handleEvent(Event event) {
-				IView view = null;
-				Composite parent = (Composite) event.widget;
-				IView oldView = getView(selectedItem);
-				if (oldView instanceof IViewExtension) {
-					((IViewExtension) oldView).viewDeactivated();
-				}
-
-				while (parent != null && !parent.isDisposed() && view == null) {
-					if (parent instanceof CTabFolder) {
-						CTabFolder folder = (CTabFolder) parent;
-						selectedItem = folder.getSelection();
-						view = getView(selectedItem);
-					} else if (parent instanceof TabFolder) {
-						TabFolder folder = (TabFolder) parent;
-						TabItem[] selection = folder.getSelection();
-						if (selection.length > 0) {
-							selectedItem = selection[0];
-							view = getView(selectedItem);
-						}
-					}
-
-					if (view == null)
-						parent = parent.getParent();
-				}
-
-				if (view != null) {
-					if (view instanceof IViewExtension) {
-						((IViewExtension) view).viewActivated();
-					}
-					view.refresh();
-				}
-			}
-		};
-		
-		mainwindow.getUIFunctions().getUIUpdater().addUpdater(this);
-	}
-
-	public Composite createFolderWidget(Composite parent) {
-		Display display = parent.getDisplay();
-
-		if (tabs == null) {
-			tabs = new HashMap();
-		}
-		if (folder != null && !folder.isDisposed()) {
-			return folder;
-		}
-
-		useCustomTab = COConfigurationManager.getBooleanParameter("useCustomTab");
-
-		if (!useCustomTab) {
-			folder = new TabFolder(parent, SWT.V_SCROLL);
-		} else {
-			folder = new CTabFolder(parent, SWT.CLOSE | SWT.BORDER);
-
-			float[] hsb = folder.getBackground().getRGB().getHSB();
-			hsb[2] *= (Constants.isOSX) ? 0.9 : 0.97;
-			folder.setBackground(ColorCache.getColor(parent.getDisplay(), hsb));
-
-			hsb = folder.getForeground().getRGB().getHSB();
-			hsb[2] *= (Constants.isOSX) ? 1.1 : 0.03;
-			folder.setForeground(ColorCache.getColor(parent.getDisplay(), hsb));
-
-			//((CTabFolder)folder).setBorderVisible(false);
-
-			((CTabFolder) folder).addCTabFolder2Listener(new CTabFolder2Adapter() {
-				public void close(CTabFolderEvent event) {
-					if (!closed((Item) event.item)) {
-						event.doit = false;
-					}
-				}
-			});
-
-			// I think this closes the tab on middle click
-			folder.addMouseListener(new MouseAdapter() {
-				public void mouseDown(MouseEvent arg0) {
-					CTabItem tabItem = ((CTabFolder) folder).getItem(new Point(arg0.x,
-							arg0.y));
-					if (arg0.button == 2) {
-						if (eventCloseAllowed) {
-							Rectangle rectangle = ((CTabItem) tabItem).getBounds();
-							if (rectangle.contains(arg0.x, arg0.y)) {
-								eventCloseAllowed = false;
-								selectedItem = null;
-								//folder.removeMouseListener(this);
-								closed(tabItem);
-							}
-						}
-					} else {
-						selectedItem = ((CTabFolder) folder).getSelection();
-					}
-				}
-
-				public void mouseUp(MouseEvent arg0) {
-					eventCloseAllowed = true;
-					if (selectedItem != null) {
-						((CTabFolder) folder).setSelection((CTabItem) selectedItem);
-						ensureVisibilities();
-					}
-				}
-			});
-		}
-
-		folder.getDisplay().addFilter(SWT.KeyDown, new Listener() {
-			public void handleEvent(Event event) {
-				// Another window has control, skip filter
-				Control focus_control = folder.getDisplay().getFocusControl();
-				if (focus_control != null
-						&& focus_control.getShell() != folder.getShell()) {
-					return;
-				}
-
-				int key = event.character;
-				if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
-						&& event.character > 0)
-					key += 'a' - 1;
-
-				// ESC or CTRL+F4 closes current Tab
-				if (key == SWT.ESC
-						|| (event.keyCode == SWT.F4 && event.stateMask == SWT.CTRL)) {
-					closeCurrent();
-					event.doit = false;
-				} else if (event.keyCode == SWT.F6
-						|| (event.character == SWT.TAB && (event.stateMask & SWT.CTRL) != 0)) {
-					// F6 or Ctrl-Tab selects next Tab
-					// On Windows the tab key will not reach this filter, as it is
-					// processed by the traversal TRAVERSE_TAB_NEXT.  It's unknown
-					// what other OSes do, so the code is here in case we get TAB
-					if ((event.stateMask & SWT.SHIFT) == 0) {
-						event.doit = false;
-						selectNextTab(true);
-						// Shift+F6 or Ctrl+Shift+Tab selects previous Tab
-					} else if (event.stateMask == SWT.SHIFT) {
-						selectNextTab(false);
-						event.doit = false;
-					}
-				}
-			}
-		});
-
-		SelectionAdapter selectionAdapter = new SelectionAdapter() {
-			public void widgetSelected(final SelectionEvent event) {
-				if (folder == null || folder.isDisposed()) {
-					return;
-				}
-
-				if (useCustomTab && !folder.isDisposed()) {
-					ensureVisibilities();
-				}
-
-				mainwindow.getUIFunctions().refreshIconBar();
-				mainwindow.getUIFunctions().refreshTorrentMenu();
-			}
-		};
-
-		if (!useCustomTab) {
-			((TabFolder) folder).addSelectionListener(selectionAdapter);
-		} else {
-			try {
-				((CTabFolder) folder).setMinimumCharacters(75);
-			} catch (Exception e) {
-				Logger.log(new LogEvent(LOGID, "Can't set MIN_TAB_WIDTH", e));
-			}
-			//try {
-			///  TabFolder2ListenerAdder.add((CTabFolder)folder);
-			//} catch (NoClassDefFoundError e) {
-			((CTabFolder) folder).addCTabFolderListener(new CTabFolderAdapter() {
-				public void itemClosed(CTabFolderEvent event) {
-					if (!event.doit) {
-						return;
-					}
-					closed((CTabItem) event.item);
-					event.doit = true;
-					((CTabItem) event.item).dispose();
-				}
-			});
-			//}
-
-			((CTabFolder) folder).addSelectionListener(selectionAdapter);
-
-			try {
-				((CTabFolder) folder).setSelectionBackground(new Color[] {
-					display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
-					display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
-					display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)
-				}, new int[] {
-					10,
-					90
-				}, true);
-			} catch (NoSuchMethodError e) {
-				/** < SWT 3.0M8 **/
-				((CTabFolder) folder).setSelectionBackground(new Color[] {
-					display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)
-				}, new int[0]);
-			}
-			((CTabFolder) folder).setSelectionForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
-
-			try {
-				/* Pre 3.0M8 doesn't have Simple-mode (it's always simple mode)
-				   in 3.0M9, it was called setSimpleTab(boolean)
-				   in 3.0RC1, it's called setSimple(boolean)
-				   Prepare for the future, and use setSimple()
-				 */
-				((CTabFolder) folder).setSimple(!COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab"));
-			} catch (NoSuchMethodError e) {
-				/** < SWT 3.0RC1 **/
-			}
-		}
-		
-
-		return folder;
-	}
-
-  
-
-	/**
-	 * 
-	 *
-	 * @since 4.0.0.5
-	 */
-	protected void ensureVisibilities() {
-		if (!(folder instanceof CTabFolder)) {
-			return;
-		}
-		CTabItem[] items = ((CTabFolder) folder).getItems();
-		CTabItem item = ((CTabFolder) folder).getSelection();
-		for (int i = 0; i < items.length; i++) {
-			CTabItem tabItem = items[i];
-			if (tabItem == null || tabItem.isDisposed()) {
-				continue;
-			}
-			if (tabItem == item) {
-				try {
-					((CTabFolder) folder).setSelection(tabItem);
-					Control control = getView(tabItem).getComposite();
-					if (control != null) {
-						control.setVisible(true);
-						control.setFocus();
-					}
-					
-				} catch (Throwable e) {
-					Debug.printStackTrace(e);
-					//Do nothing
-				}
-			} else {
-				try {
-					Control control = getView(tabItem).getComposite();
-					if (control != null) {
-						control.setVisible(false);
-					}
-				} catch (Throwable e) {
-					Debug.printStackTrace(e);
-					//Do nothing
-				}
-			}
-		}
-	}
-
-	public Item createTabItem(final IView _view, boolean bFocus) {
-		if (folder.isDisposed()) {
-			return null;
-		}
-
-		Item tabItem;
-
-		if (folder instanceof CTabFolder) {
-			CTabFolder tabFolder = (CTabFolder) folder;
-			tabItem = new CTabItem(tabFolder, SWT.NULL,
-					(_view instanceof MyTorrentsSuperView) ? 0 : tabFolder.getItemCount());
-
-		} else {
-			TabFolder tabFolder = (TabFolder) folder;
-			tabItem = new TabItem(tabFolder, SWT.NULL,
-					(_view instanceof MyTorrentsSuperView) ? 0 : tabFolder.getItemCount());
-		}
-
-
-		tabs.put(tabItem, _view);
-
-		try {
-			// Always create a composite around the IView, because a lot of them
-			// assume that their parent is of GridLayout layout.
-			final Composite tabArea = new Composite(folder, SWT.NONE);
-			GridLayout layout = new GridLayout();
-			layout.marginHeight = 0;
-			layout.marginWidth = 0;
-			tabArea.setLayout(layout);
-
-			_view.initialize(tabArea);
-			tabItem.setText(escapeAccelerators(_view.getShortTitle()));
-
-			Composite viewComposite = _view.getComposite();
-			if (viewComposite != null && !viewComposite.isDisposed()) {
-				viewComposite.addListener(SWT.Activate, activateListener);
-
-				// make sure the view's layout data is of GridLayoutData
-				if ((tabArea.getLayout() instanceof GridLayout)
-						&& !(viewComposite.getLayoutData() instanceof GridData)) {
-					viewComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
-				}
-
-				if (viewComposite != tabArea) {
-					viewComposite.addDisposeListener(new DisposeListener() {
-						boolean alreadyHere = false;
-
-						public void widgetDisposed(DisposeEvent e) {
-							if (alreadyHere) {
-								return;
-							}
-							alreadyHere = true;
-							Item tab = getTab(_view);
-							if (tab != null) {
-								closed(tab);
-							}
-						}
-					});
-				}
-			}
-
-			if (folder instanceof CTabFolder) {
-				((CTabItem) tabItem).setControl(tabArea);
-				// Disabled for SWT 3.2RC5.. CTabItem tooltip doesn't always disappear
-				//				((CTabItem) tabItem).setToolTipText(view.getFullTitle());
-				if (bFocus) {
-					((CTabFolder) folder).setSelection((CTabItem) tabItem);
-					ensureVisibilities();
-				}
-			} else {
-				((TabItem) tabItem).setControl(tabArea);
-				((TabItem) tabItem).setToolTipText(_view.getFullTitle());
-				TabItem items[] = {
-					(TabItem) tabItem
-				};
-				if (bFocus) {
-					((TabFolder) folder).setSelection(items);
-				}
-			}
-		} catch (Exception e) {
-			tabs.remove(tabItem);
-			Debug.printStackTrace(e);
-		}
-
-		if (bFocus) {
-			UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (uif != null) {
-				uif.refreshIconBar();
-				uif.refreshTorrentMenu();
-			}
-			selectedItem = tabItem;
-		}
-		
-		return tabItem;
-	}
-
-
-  public IView getView(Item item) {
-    return (IView) tabs.get(item);
-  }
-  
-  public Item
-  getTab(
-		IView	view )
-  {
-	   try{
-		   class_mon.enter();
-	    	
-		   Iterator iter = tabs.keySet().iterator();
-		   
-		   while( iter.hasNext()){
-			 
-			   Item item = (Item) iter.next();
-			   
-			   IView this_view = (IView) tabs.get(item); 
-			   
-			   if ( this_view == view ){
-				   
-				   return( item );
-			   }
-		   }
-		   
-		   return( null );
-		   
-	   }finally{
-		   
-		   class_mon.exit();
-	   }
-  }
-  
-  public Item[] getAllTabs() {
-		try {
-			class_mon.enter();
-
-			Item[] tabItems = new Item[tabs.size()];
-			if (tabItems.length > 0) {
-				tabItems = (Item[]) tabs.keySet().toArray(tabItems);
-			}
-
-			return tabItems;
-		} finally {
-
-			class_mon.exit();
-		}
-	}
-  
-  public IView[] getAllViews() {
-		try {
-			class_mon.enter();
-
-			IView[] views = new IView[tabs.size()];
-			if (views.length > 0) {
-				views = (IView[])tabs.values().toArray(views);
-			}
-			
-			return views;
-		} finally {
-
-			class_mon.exit();
-		}
-	}
-
-  
-  public void refresh() {
-    try{
-    	class_mon.enter();
-    	
-      Iterator iter = tabs.keySet().iterator();
-      while (iter.hasNext()) {
-        //TabItem item = (TabItem) iter.next();
-        //CTabItem item = (CTabItem) iter.next();
-        Item item = (Item) iter.next();
-        IView view = (IView) tabs.get(item);
-        try {
-          if (item.isDisposed())
-            continue;
-          String lastTitle = item.getText();
-          String newTitle = view.getShortTitle();
-          if (lastTitle == null || !lastTitle.equals(newTitle)) {
-            item.setText(escapeAccelerators(newTitle));
-          }
-          if (item instanceof CTabItem) {
-// Disabled for SWT 3.2RC5.. CTabItem tooltip doesn't always disappear
-//            String lastToolTip = ((CTabItem) item).getToolTipText();
-//            String newToolTip = view.getFullTitle();
-//            if (lastToolTip == null || !lastToolTip.equals(newToolTip)) {
-//              ((CTabItem) item).setToolTipText(newToolTip);
-//            }
-          }
-          else if (item instanceof TabItem) {
-            String lastToolTip = ((TabItem) item).getToolTipText();
-            String newToolTip = view.getFullTitle();
-            if (lastToolTip == null || !lastToolTip.equals(newToolTip)) {
-              ((TabItem) item).setToolTipText(newToolTip);
-            }
-          }
-        }
-        catch (Exception e){
-        	
-        	Debug.printStackTrace(e);
-        }
-      }
-    }finally{
-    	
-    	class_mon.exit();
-    }
-  }
-
-  public void 
-  updateLanguage() 
-  {
-  	IView[] views;
-  	
-    try{
-    	class_mon.enter();
-      
-    	views = (IView[]) tabs.values().toArray(new IView[tabs.size()]);
-    	   	
-    }finally{
-    	
-    	class_mon.exit();
-    }   
-    
-    for (int i = 0; i < views.length; i++) {
-
-    	IView view = views[i];
-    	
-        try {
-          view.updateLanguage();
-          view.refresh();
-        }
-        catch (Exception e) {
-        	Debug.printStackTrace(e);
-        }
-    }
-  }
-
-
-  public void 
-  closeAllTabs() 
-  {
-  	Item[] tab_items;
-  	
-    try{
-    	class_mon.enter();
-      
-    	tab_items = (Item[]) tabs.keySet().toArray(new Item[tabs.size()]);
-    	
-    }finally{
-    	
-    	class_mon.exit();
-    }
-    
-    for (int i = 0; i < tab_items.length; i++) {
-    	
-        closed(tab_items[i], true);
-      }
-  }
-
-  public boolean hasDetails()
-  {
-      boolean hasDetails = false;
-      try
-      {
-          class_mon.enter();
-
-          Iterator iter = tabs.values().iterator();
-          while (iter.hasNext())
-          {
-              IView view = (IView) iter.next();
-              if(view instanceof ManagerView)
-              {
-                  hasDetails = true;
-                  break;
-              }else if ( view instanceof UIPluginView && ((UIPluginView)view).getViewID().equals( "DMView" )){
-            	  hasDetails = true;
-                  break;
-              }
-          }
-      }
-      finally
-      {
-          class_mon.exit();
-      }
-
-      return hasDetails;
-  }
-
-  public void
-  closeAllDetails() 
-  {
-  	Item[] tab_items;
-  	
-    try{
-    	class_mon.enter();
-    	
-    	tab_items = (Item[]) tabs.keySet().toArray(new Item[tabs.size()]);
-
-    }finally{
-    	
-    	class_mon.exit();
-    }
-    
-    for (int i = 0; i < tab_items.length; i++) {
-        IView view = (IView) tabs.get(tab_items[i]);
-        if (view instanceof ManagerView) {
-          closed(tab_items[i]);
-        }else if ( view instanceof UIPluginView && ((UIPluginView)view).getViewID().equals( "DMView" )){
-          closed(tab_items[i]);
-        }
-      }
-  }
-
-  public void closeCurrent() {
-    if (folder == null || folder.isDisposed())
-      return;
-    if(folder instanceof TabFolder) {    
-      TabItem[] items =  ((TabFolder)folder).getSelection();
-      if(items.length == 1) {
-        closed(items[0]);		
-      }
-     } else {
-       closed(((CTabFolder)folder).getSelection());
-     }
-  }
-
-  /**
-   * @param selectNext if true, the next tab is selected, else the previous
-   *
-   * @author Rene Leonhardt
-   */
-  public void selectNextTab(boolean selectNext) {
-    if (folder == null || folder.isDisposed())
-      return;
-    final int nextOrPrevious = selectNext ? 1 : -1;
-    if(folder instanceof TabFolder) {
-      TabFolder tabFolder = (TabFolder)folder;
-      int index = tabFolder.getSelectionIndex() + nextOrPrevious;
-      if(index == 0 && selectNext || index == -2 || tabFolder.getItemCount() < 2)
-        return;
-      if(index == tabFolder.getItemCount())
-        index = 0;
-      else if(index < 0)
-        index = tabFolder.getItemCount() - 1;
-      tabFolder.setSelection(index);
-    } else {
-      CTabFolder tabFolder = (CTabFolder)folder;
-      int index = tabFolder.getSelectionIndex() + nextOrPrevious;
-      if(index == 0 && selectNext || index == -2 || tabFolder.getItemCount() < 2)
-        return;
-      if(index == tabFolder.getItemCount())
-        index = 0;
-      else if(index < 0)
-        index = tabFolder.getItemCount() - 1;
-      tabFolder.setSelection(index);
-			ensureVisibilities();
-    }
-  }
-
-  public boolean 
-  closed(Item item) 
-  {
-  	return closed(item, false);
-  }
-  
-  public boolean 
-  closed(Item item, boolean bForceClose) 
-  {
-  	if (item == null) {
-  		return true;
-  	}
-
-    IView view = (IView) tabs.get(item);
-    if (!bForceClose && view instanceof UISWTViewImpl) {
-    	if (!((UISWTViewImpl)view).requestClose()) {
-    		return false;
-    	}
-    }
-
-    try{
-    	class_mon.enter();
-    	
-    	view = (IView) tabs.remove(item);
-    }finally{
-    	
-    	class_mon.exit();
-    }
-    
-    if (view != null) {
-        try {
-          if(view instanceof PluginView) {
-          	mainwindow.removeActivePluginView(((PluginView)view).getPluginViewName());
-          }
-          if(view instanceof UISWTPluginView) {
-          	mainwindow.removeActivePluginView(((UISWTPluginView)view).getPluginViewName());
-          }
-          if(view instanceof UISWTView)
-          	mainwindow.removeActivePluginView(((UISWTView)view).getViewID());
-   
-          view.delete();
-        } catch (Exception e) {
-        	Debug.printStackTrace( e );
-        }
-
-        if (view instanceof MyTorrentsSuperView) {
-          //TODO : There is a problem here on OSX when using Normal TABS
-          /*  org.eclipse.swt.SWTException: Widget is disposed
-                at org.eclipse.swt.SWT.error(SWT.java:2691)
-                at org.eclipse.swt.SWT.error(SWT.java:2616)
-                at org.eclipse.swt.SWT.error(SWT.java:2587)
-                at org.eclipse.swt.widgets.Widget.error(Widget.java:546)
-                at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:296)
-                at org.eclipse.swt.widgets.Control.setVisible(Control.java:2573)
-                at org.eclipse.swt.widgets.TabItem.releaseChild(TabItem.java:180)
-                at org.eclipse.swt.widgets.Widget.dispose(Widget.java:480)
-                at org.gudy.azureus2.ui.swt.Tab.closed(Tab.java:322)
-           */
-          //Tried to add a if(! item.isDisposed()) but it's not fixing it
-          //Need to investigate...
-          item.dispose();
-          return true;
-        }
-        if (view instanceof MyTrackerView) {
-          item.dispose();
-          return true;
-        }
-        if (view instanceof MySharesView) {
-        	item.dispose();
-          return true;
-        }
-      }
-      try {
-        /*Control control;
-        if(item instanceof CTabItem) {
-          control = ((CTabItem)item).getControl();
-        } else {
-          control = ((TabItem)item).getControl();
-        }
-        if (control != null && !control.isDisposed())
-          control.dispose();
-        */
-        item.dispose();
-      }
-      catch (Exception e) {
-      	Debug.printStackTrace( e );
-      }
-      return true;
-  }
-
-  public void setFocus(Item item) {
-  	if (item == null || item.isDisposed()) {
-  		return;
-  	}
-
-		if (folder != null && !folder.isDisposed()) {
-			if (useCustomTab) {
-				((CTabFolder) folder).setSelection((CTabItem) item);
-				ensureVisibilities();
-			} else {
-				TabItem items[] = {
-					(TabItem) item
-				};
-				((TabFolder) folder).setSelection(items);
-			}
-		}
-	}
-
-  public void dispose(Item tabItem) {
-    IView localView = null;
-    try{
-    	class_mon.enter();
-      
-      localView = (IView) tabs.get(tabItem);
-
-      if (localView instanceof UISWTViewImpl) {
-				if (!((UISWTViewImpl) localView).requestClose())
-					return;
-			}
-
-      tabs.remove(tabItem);
-    }finally{
-    
-    	class_mon.exit();
-    }
-    try {
-      if (localView != null) {
-        if(localView instanceof PluginView) {
-        	mainwindow.removeActivePluginView(((PluginView)localView).getPluginViewName());
-        }
-        if(localView instanceof UISWTPluginView) {
-        	mainwindow.removeActivePluginView(((UISWTPluginView)localView).getPluginViewName());
-        }
-
-        localView.delete();
-      }
-      tabItem.dispose();
-    }
-    catch (Exception e) {}
-  }
-
-
-  protected String
-  escapeAccelerators(
-	 String	str )
-  {
-	  if ( str == null ){
-		  
-		  return( str );
-	  }
-	  
-	  return( str.replaceAll( "&", "&&" ));
-  }
-  
-  public void generateDiagnostics(IndentWriter writer) {
-		Object[] views = tabs.values().toArray();
-		for (int i = 0; i < views.length; i++) {
-			IView view = (IView) views[i];
-
-			if (view != null) {
-				writer.println(view.getFullTitle());
-
-				try {
-					writer.indent();
-
-					view.generateDiagnostics(writer);
-				} catch (Exception e) {
-
-				} finally {
-
-					writer.exdent();
-				}
-			}
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void update() {
-		if (folder != null) {
-			if (useCustomTab) {
-				((CTabFolder) folder).update();
-			} else {
-				((TabFolder) folder).update();
-			}
-		}
-	}
-
-	/**
-	 * @param viewID
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void closePluginViews(String viewID) {
-		Item[] items;
-
-		if (folder instanceof CTabFolder)
-			items = ((CTabFolder) folder).getItems();
-		else if (folder instanceof TabFolder)
-			items = ((TabFolder) folder).getItems();
-		else
-			return;
-
-		for (int i = 0; i < items.length; i++) {
-			IView view = getView(items[i]);
-			if (view instanceof UISWTViewImpl) {
-				String sID = ((UISWTViewImpl) view).getViewID();
-				if (sID != null && sID.equals(viewID)) {
-					try {
-						Item tab = getTab(view);
-						if (tab != null) {
-							closed(tab);
-						}
-					} catch (Exception e) {
-						Debug.printStackTrace(e);
-					}
-				}
-			}
-		} // for
-	}
-
-	// @see org.gudy.azureus2.core3.config.ParameterListener#parameterChanged(java.lang.String)
-	public void parameterChanged(String parameterName) {
-		if (parameterName.equals("GUI_SWT_bFancyTab")
-				&& folder instanceof CTabFolder && folder != null
-				&& !folder.isDisposed()) {
-			try {
-				((CTabFolder) folder).setSimple(!COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab"));
-			} catch (NoSuchMethodError e) {
-				/** < SWT 3.0RC1 **/
-			}
-		}
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public IView getCurrentView() {
-		try {
-			if (!useCustomTab) {
-				TabItem[] selection = ((TabFolder) folder).getSelection();
-				if (selection.length > 0) {
-					return getView(selection[0]);
-				}
-				return null;
-			}
-			return getView(((CTabFolder) folder).getSelection());
-		} catch (Exception e) {
-			return null;
-		}
-	}
-	
-	// @see com.aelitis.azureus.ui.common.updater.UIUpdatable#getUpdateUIName()
-	public String getUpdateUIName() {
-		IView currentView = getCurrentView();
-		if (currentView != null) {
-			return ID + "-" + currentView.getFullTitle();
-		}
-		return ID;
-	}
-	
-	// @see com.aelitis.azureus.ui.common.updater.UIUpdatable#updateUI()
-	public void updateUI() {
-		if (folder == null || folder.isDisposed()) {
-			return;
-		}
-
-		IView currentView = getCurrentView();
-		if (currentView != null) {
-			try {
-				currentView.refresh();
-			} catch (Exception e) {
-				Debug.out(e);
-			}
-		}
-		
-		refresh();
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/TextViewerWindow.java b/org/gudy/azureus2/ui/swt/TextViewerWindow.java
index b83bc79..09bdded 100644
--- a/org/gudy/azureus2/ui/swt/TextViewerWindow.java
+++ b/org/gudy/azureus2/ui/swt/TextViewerWindow.java
@@ -20,7 +20,11 @@
  */
 package org.gudy.azureus2.ui.swt;
 
+import java.util.*;
+
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -32,33 +36,71 @@ import org.eclipse.swt.widgets.Shell;
 import org.eclipse.swt.widgets.Text;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 public class TextViewerWindow {
-  public TextViewerWindow(String sTitleID, String sMessageID, String sText) {
-    final Display display = SWTThread.getInstance().getDisplay();
-    final Shell shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(display, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
-
+  private Shell shell;
+  private Text txtInfo;
+  private  Button ok;
+  
+  private List<TextViewerWindowListener> listeners = new ArrayList<TextViewerWindowListener>();
+  
+  public 
+  TextViewerWindow(
+		 String sTitleID, String sMessageID, String sText )
+  {
+	  this( sTitleID, sMessageID, sText, true );
+  }
+  
+  public 
+  TextViewerWindow(
+		 String sTitleID, String sMessageID, String sText, boolean modal )
+  {
+	this( sTitleID, sMessageID, sText, modal, false );		
+  }
+  
+  public 
+  TextViewerWindow(
+		 String sTitleID, String sMessageID, String sText, boolean modal, boolean defer_modal )
+  {    
+    if ( modal ){
+    
+    	shell = ShellFactory.createMainShell( SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE );
+    	
+    }else{
+    	
+    	shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.RESIZE );
+    }
+    
     if (sTitleID != null) shell.setText(MessageText.keyExists(sTitleID)?MessageText.getString(sTitleID):sTitleID);
     
     Utils.setShellIcon(shell);
     
     GridLayout layout = new GridLayout();
+    layout.numColumns = 2;
     shell.setLayout(layout);
 
     Label label = new Label(shell, SWT.NONE);
     if (sMessageID != null) label.setText(MessageText.keyExists(sMessageID)?MessageText.getString(sMessageID):sMessageID);
-    GridData gridData = new GridData();
+    GridData gridData = new GridData(  GridData.FILL_HORIZONTAL );
     gridData.widthHint = 200;
+    gridData.horizontalSpan = 2;
     label.setLayoutData(gridData);
 
-    final Text txtInfo = new Text(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
-    gridData = new GridData();
-    gridData.widthHint = 300;
+    txtInfo = new Text(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+    gridData = new GridData(  GridData.FILL_BOTH );
+    gridData.widthHint = 500;
+    gridData.heightHint = 400;
+    gridData.horizontalSpan = 2;
     txtInfo.setLayoutData(gridData);
     txtInfo.setText(sText);
 
-    Button ok = new Button(shell, SWT.PUSH);
+    label = new Label(shell, SWT.NONE);
+    gridData = new GridData( GridData.FILL_HORIZONTAL );
+    label.setLayoutData(gridData);
+    
+    ok = new Button(shell, SWT.PUSH);
     ok.setText(MessageText.getString("Button.ok"));
     gridData = new GridData();
     gridData.widthHint = 70;
@@ -78,15 +120,109 @@ public class TextViewerWindow {
 	shell.addListener(SWT.Traverse, new Listener() {	
 		public void handleEvent(Event e) {
 			if ( e.character == SWT.ESC){
-				shell.dispose();
+				if ( ok.isEnabled()){
+					shell.dispose();
+				}
 			}
 		}
 	});
 	
+	shell.addDisposeListener(
+		new DisposeListener()
+		{
+			public void 
+			widgetDisposed(
+				DisposeEvent arg0) 
+			{
+				for ( TextViewerWindowListener l: listeners ){
+					
+					l.closed();
+				}
+			}
+		});
+	
     shell.pack();
 	Utils.centreWindow( shell );
     shell.open();
-    while (!shell.isDisposed())
-      if (!display.readAndDispatch()) display.sleep();
+    
+    if ( modal && !defer_modal ){
+    	goModal();
+    }
+  }
+  
+  public void
+  goModal()
+  {
+	    final Display display = SWTThread.getInstance().getDisplay();
+
+	  	while (!shell.isDisposed()){
+    		if (!display.readAndDispatch()) display.sleep();
+	  	}
+  }
+  
+  public void
+  append(
+	String	str )
+  {
+	  txtInfo.setText( txtInfo.getText() + str );
+	  
+	  txtInfo.setSelection( txtInfo.getTextLimit());
+  }
+  
+  public String
+  getText()
+  {
+	  return( txtInfo.getText());
+  }
+  
+  public void
+  setText(
+	 String	text )
+  {
+	  txtInfo.setText( text);
+	  
+	  txtInfo.setSelection( txtInfo.getTextLimit());
+  }
+  
+  public void
+  setEditable(
+	boolean	editable )
+  {
+	  txtInfo.setEditable( editable );
+  }
+  
+  public void
+  setOKEnabled(
+	boolean	enabled )
+  {
+	  ok.setEnabled( enabled );
+  }
+  
+  public void
+  addListener(
+	 TextViewerWindowListener		l )
+  {
+	  listeners.add( l );
+  }
+  
+  public boolean
+  isDisposed()
+  {
+	  return( shell.isDisposed());
+  }
+  
+  public void
+  close()
+  {
+	  if ( !shell.isDisposed()){
+		  
+		  shell.dispose();
+	  }
+  }
+  public interface
+  TextViewerWindowListener
+  {
+	  public void
+	  closed();
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/TorrentUtil.java b/org/gudy/azureus2/ui/swt/TorrentUtil.java
index f1ef781..d7c33eb 100644
--- a/org/gudy/azureus2/ui/swt/TorrentUtil.java
+++ b/org/gudy/azureus2/ui/swt/TorrentUtil.java
@@ -28,6 +28,7 @@ import java.util.*;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MenuEvent;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.widgets.*;
@@ -35,42 +36,58 @@ 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;
+import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
 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.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentException;
 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.plugins.download.Download;
+import org.gudy.azureus2.plugins.sharing.ShareManager;
+import org.gudy.azureus2.plugins.ui.*;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
 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.IMenuConstants;
+import org.gudy.azureus2.ui.swt.mainwindow.MenuFactory;
 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.maketorrent.*;
 import org.gudy.azureus2.ui.swt.minibar.DownloadBar;
+import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
 import org.gudy.azureus2.ui.swt.shells.AdvRenameWindow;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.views.FilesViewMenuUtil;
 import org.gudy.azureus2.ui.swt.views.ViewUtils;
+import org.gudy.azureus2.ui.swt.views.tableitems.mytorrents.RankItem;
 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.core.speedmanager.SpeedLimitHandler;
 import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
 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.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableView;
+import com.aelitis.azureus.ui.selectedcontent.*;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
+
 
 /**
  * @author Allan Crooks
@@ -84,6 +101,8 @@ public class TorrentUtil {
 			final Composite composite, boolean include_show_details,
 			int selected_dl_types, final TableView tv) {
 
+		// TODO: Build submenus on the fly
+		
 		final boolean isSeedingView;
 		switch (selected_dl_types) {
 			case 1:
@@ -179,7 +198,6 @@ public class TorrentUtil {
 				if (barsOpened && !DownloadBar.getManager().isOpen(dm)) {
 					barsOpened = false;
 				}
-
 				stop = stop || ManagerUtils.isStopable(dm);
 
 				start = start || ManagerUtils.isStartable(dm);
@@ -207,7 +225,6 @@ public class TorrentUtil {
 				}
 				int state = dm.getState();
 				bChangeDir &= (state == DownloadManager.STATE_ERROR || state == DownloadManager.STATE_STOPPED || state == DownloadManager.STATE_QUEUED);;
-
 				/**
 				 * Only perform a test on disk if:
 				 *    1) We are currently set to allow the "Change Data Directory" option, and
@@ -215,7 +232,13 @@ public class TorrentUtil {
 				 *       amounts of files across multiple torrents before we generate a menu.
 				 */
 				if (bChangeDir && dms.length == 1) {
-					bChangeDir = dm.isDataAlreadyAllocated() && !dm.filesExist( true );
+					bChangeDir = dm.isDataAlreadyAllocated();
+					if (bChangeDir && state == DownloadManager.STATE_ERROR) {
+						// filesExist is way too slow!
+						bChangeDir = !dm.filesExist( true );
+					} else {
+						bChangeDir = false;
+					}
 				}
 
 				boolean scan = dm.getDownloadState().getFlag(DownloadManagerState.FLAG_SCAN_INCOMPLETE_PIECES);
@@ -326,7 +349,7 @@ public class TorrentUtil {
 		Utils.setMenuItemImage(itemOpen, "run");
 		itemOpen.addListener(SWT.Selection, new DMTask(dms) {
 			public void run(DownloadManager[] dms) {
-				runTorrents(dms);
+				runDataSources(dms);
 			}
 		});
 		itemOpen.setEnabled(hasSelection);
@@ -378,6 +401,155 @@ public class TorrentUtil {
 					}
 				});
 
+		// advanced > Speed Limits
+		
+		final Menu speedLimitsMenu = new Menu(menuAdvanced.getShell(), SWT.DROP_DOWN);
+		final MenuItem speedLimitsMenuItem = new MenuItem(menuAdvanced, SWT.CASCADE);
+		Messages.setLanguageText(speedLimitsMenuItem,IMenuConstants.MENU_ID_SPEED_LIMITS);
+		speedLimitsMenuItem.setMenu(speedLimitsMenu);
+		
+		MenuBuildUtils.addMaintenanceListenerForMenu(speedLimitsMenu,
+			new MenuBuildUtils.MenuBuilder() {
+				public void 
+				buildMenu(
+					Menu 		menu, 
+					MenuEvent 	menuEvent) 
+				{
+					final SpeedLimitHandler slh = SpeedLimitHandler.getSingleton( azureus_core );
+
+					boolean	all_have_limit = true;
+					
+					Set<String>	common_profiles = new HashSet<String>();
+					
+					final List<byte[]>	dm_hashes = new ArrayList<byte[]>();
+					
+					for (int i = 0; i < dms.length; i++) {
+						DownloadManager dm = (DownloadManager) dms[i];
+
+						int maxul = dm.getStats().getUploadRateLimitBytesPerSecond();
+						int maxdl = dm.getStats().getDownloadRateLimitBytesPerSecond();
+						
+						if ( maxul == 0 && maxdl == 0 ){
+							
+							all_have_limit = false;
+						}
+						
+						TOTorrent t = dm.getTorrent();
+						
+						if ( t == null ){
+							
+							common_profiles.clear();
+							
+						}else{
+							
+							try{
+								byte[] hash = t.getHash();
+							
+								dm_hashes.add( hash );
+								
+								List<String>	profs = slh.getProfilesForDownload( hash );
+								
+								if ( i == 0 ){
+									
+									common_profiles.addAll( profs );
+									
+								}else{
+									
+									common_profiles.retainAll( profs );
+								}
+							}catch( TOTorrentException e ){
+								
+								Debug.out( e );
+								
+								common_profiles.clear();
+							}
+						}
+					}
+						
+					java.util.List<String>	profiles = slh.getProfileNames();
+
+						// add to profile
+					
+					final Menu add_to_prof_menu = new Menu(speedLimitsMenu.getShell(), SWT.DROP_DOWN);
+					MenuItem add_to_prof_item = new MenuItem( menu, SWT.CASCADE);
+					add_to_prof_item.setMenu(add_to_prof_menu);
+			
+												
+					Messages.setLanguageText(add_to_prof_item, "MyTorrentsView.menu.sl_add_to_prof" );
+			
+					if ( !all_have_limit ){
+						
+						add_to_prof_item.setEnabled( false );
+						
+					}else{
+						
+						for ( final String p: profiles ){
+
+							MenuItem addItem = new MenuItem(add_to_prof_menu, SWT.PUSH);
+							addItem.setText( p );
+
+							addItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg0 )
+									{
+										slh.addDownloadsToProfile( p, dm_hashes );
+										
+										MenuFactory.showText(
+												"MainWindow.menu.speed_limits.info.title",
+												MessageText.getString( "MainWindow.menu.speed_limits.info.prof", new String[]{ p }),
+												slh.getProfile( p ) );
+									}
+								});
+						}
+					}
+					
+						// remove from profile
+					
+					final Menu remove_from_prof_menu = new Menu(speedLimitsMenu.getShell(), SWT.DROP_DOWN);
+					MenuItem remove_from_prof_item = new MenuItem( menu, SWT.CASCADE);
+					remove_from_prof_item.setMenu(remove_from_prof_menu);
+			
+												
+					Messages.setLanguageText(remove_from_prof_item, "MyTorrentsView.menu.sl_remove_from_prof" );
+			
+					if ( common_profiles.isEmpty()){
+						
+						remove_from_prof_item.setEnabled( false );
+						
+					}else{
+						
+						for ( final String p: common_profiles ){
+
+							MenuItem addItem = new MenuItem(remove_from_prof_menu, SWT.PUSH);
+							addItem.setText( p );
+
+							addItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg0 )
+									{
+										slh.removeDownloadsFromProfile( p, dm_hashes );
+										
+										MenuFactory.showText(
+												"MainWindow.menu.speed_limits.info.title",
+												MessageText.getString( "MainWindow.menu.speed_limits.info.prof", new String[]{ p }),
+												slh.getProfile( p ) );
+									}
+								});
+						}
+					}
+				}
+		});
+		
+		
+		
 		// advanced > Tracker Menu //
 		final Menu menuTracker = new Menu(menu.getShell(), SWT.DROP_DOWN);
 		final MenuItem itemTracker = new MenuItem(menuAdvanced, SWT.CASCADE);
@@ -390,7 +562,7 @@ public class TorrentUtil {
 		itemChangeTracker.addListener(SWT.Selection, new DMTask(dms) {
 			public void run(DownloadManager[] dms) {
 				if ( dms.length > 0 ){
-					new TrackerChangerWindow(composite.getDisplay(), dms);
+					new TrackerChangerWindow(dms);
 				}
 			}
 		});
@@ -446,6 +618,7 @@ public class TorrentUtil {
 					List<List<String>> group = TorrentUtils.announceGroupsToList(torrent);
 
 					new MultiTrackerEditor(
+						null,
 						null, 
 						group, 
 						new TrackerEditorListener() 
@@ -621,6 +794,17 @@ public class TorrentUtil {
 		});
 		itemManualScrape.setEnabled(manualScrape);
 
+			// explore torrent file
+		
+		final MenuItem itemTorrentExplore = new MenuItem(menuTracker, SWT.PUSH);
+		Messages.setLanguageText(itemTorrentExplore, "MyTorrentsView.menu." + (use_open_containing_folder ? "open_parent_folder" : "explore"));
+		itemTorrentExplore.addListener(SWT.Selection, new DMTask(dms, false) {
+			public void run(DownloadManager dm) {
+				ManagerUtils.open(new File(dm.getTorrentFileName()), use_open_containing_folder);
+			}
+		});
+		itemExplore.setEnabled(hasSelection);
+		
 		// advanced > files
 
 		final MenuItem itemFiles = new MenuItem(menuAdvanced, SWT.CASCADE);
@@ -757,14 +941,75 @@ public class TorrentUtil {
 		// Advanced - > Rename
 		final MenuItem itemRename = new MenuItem(menuAdvanced, SWT.DROP_DOWN);
 		Messages.setLanguageText(itemRename, "MyTorrentsView.menu.rename");
-		itemRename.setEnabled(hasSelection && dms.length == 1);
+		itemRename.setEnabled(hasSelection);
 		itemRename.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
-				AdvRenameWindow window = new AdvRenameWindow();
-				window.open(dms[0]);
+				for (DownloadManager dm : dms) {
+					AdvRenameWindow window = new AdvRenameWindow();
+					window.open(dm);
+				}
 			}
 		});
 
+		// === advanced > quick view
+				
+		final Menu quickViewMenu = new Menu(menuAdvanced.getShell(), SWT.DROP_DOWN);
+		final MenuItem quickViewMenuItem = new MenuItem(menuAdvanced, SWT.CASCADE);
+		Messages.setLanguageText(quickViewMenuItem,IMenuConstants.MENU_ID_QUICK_VIEW);
+		quickViewMenuItem.setMenu(quickViewMenu);
+		
+		MenuBuildUtils.addMaintenanceListenerForMenu(quickViewMenu,
+			new MenuBuildUtils.MenuBuilder() {
+				public void 
+				buildMenu(
+					Menu 		menu, 
+					MenuEvent 	menuEvent) 
+				{
+					DownloadManager dm = dms[0];
+					
+					DiskManagerFileInfo[]	files = dm.getDiskManagerFileInfoSet().getFiles();
+					
+					int	added = 0;
+					
+					for ( final DiskManagerFileInfo file: files ){
+						
+						if ( Utils.isQuickViewSupported( file )){
+								
+							final MenuItem addItem = new MenuItem(menu, SWT.CHECK );
+							
+							addItem.setSelection( Utils.isQuickViewActive( file ));
+							
+							addItem.setText( file.getTorrentFile().getRelativePath());
+
+							addItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg ) 
+									{
+										Utils.setQuickViewActive( file, addItem.getSelection());
+									}
+								});
+							
+							added++;
+						}
+					}
+					
+					if ( added == 0 ){
+						
+						final MenuItem addItem = new MenuItem(menu, SWT.PUSH );
+												
+						addItem.setText( MessageText.getString( "quick.view.no.files"));
+
+						addItem.setEnabled( false );
+					}
+				}
+		});
+		
+		quickViewMenuItem.setEnabled( dms.length == 1 );
+		
 		// === advanced > export ===
 		// =========================
 
@@ -940,7 +1185,7 @@ public class TorrentUtil {
 
 		if (userMode > 0) {
 			final MenuItem itemExportXML = new MenuItem(menuAdvanced, SWT.PUSH);
-			Messages.setLanguageText(itemExportXML, "MainWindow.menu.view.configuration");
+			Messages.setLanguageText(itemExportXML, "label.options.and.info");
 			itemExportXML.addListener(SWT.Selection, new DMTask(dms) {
 				public void run(DownloadManager[] dms) {
 					UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
@@ -996,6 +1241,53 @@ public class TorrentUtil {
 			}
 		}
 
+		// IP Filter Enable
+		if (userMode > 0) {
+			
+			final MenuItem ipf_enable = new MenuItem(menuAdvanced, SWT.CHECK);
+			Messages.setLanguageText(ipf_enable, "MyTorrentsView.menu.ipf_enable");
+			
+
+			ipf_enable.addListener(SWT.Selection, new DMTask(dms) {
+				public void run(DownloadManager dm) {
+					dm.getDownloadState().setFlag( DownloadManagerState.FLAG_DISABLE_IP_FILTER, !ipf_enable.getSelection());
+				}
+			});
+
+			boolean bEnabled = IpFilterManagerFactory.getSingleton().getIPFilter().isEnabled();
+			
+			if ( bEnabled ){
+				boolean allChecked 		= true;
+				boolean allUnchecked	= true;
+		
+				for (int j = 0; j < dms.length; j++) {
+					DownloadManager dm = (DownloadManager) dms[j];
+	
+					boolean b = dm.getDownloadState().getFlag( DownloadManagerState.FLAG_DISABLE_IP_FILTER );
+						
+					if ( b ){
+						allUnchecked 	= false;
+					}else{
+						allChecked 		= false;
+					}
+				}
+	
+				boolean	bChecked;
+				
+				if ( allUnchecked ){
+					bChecked = true;
+				}else if ( allChecked ){
+					bChecked = false;
+				}else{
+					bChecked = false;
+				}
+				
+				ipf_enable.setSelection(bChecked);
+			}
+			
+			ipf_enable.setEnabled(bEnabled);	
+		}
+		
 		// === advanced > networks ===
 		// ===========================
 
@@ -1207,6 +1499,41 @@ public class TorrentUtil {
 
 		addCategorySubMenu(dms, menuCategory, composite);
 		
+		if ( isSeedingView ){
+			final MenuItem itemPersonalShare = new MenuItem(menu, SWT.PUSH);
+			Messages.setLanguageText(itemPersonalShare, "MyTorrentsView.menu.create_personal_share");
+			itemPersonalShare.addListener(SWT.Selection, new DMTask(dms, false) {
+				public void run(DownloadManager dm) {
+					File file = dm.getSaveLocation();
+					
+					Map<String,String>	properties = new HashMap<String, String>();
+					
+					properties.put( ShareManager.PR_PERSONAL, "true" );
+					
+					if ( file.isFile()){
+					
+						ShareUtils.shareFile( file.getAbsolutePath(), properties );
+						
+					}else if ( file.isDirectory()){
+						
+						ShareUtils.shareDir( file.getAbsolutePath(), properties );
+					}
+				}
+			});
+			
+			boolean	can_share_pers = dms.length > 0;
+			
+			for ( DownloadManager dm: dms ){
+				
+				if ( !( dm.isDownloadComplete( true ) && dm.filesExist( true ))){
+				
+					can_share_pers = false;
+				}
+			}
+			
+			itemPersonalShare.setEnabled( can_share_pers );
+		}
+		
 		// ---
 		new MenuItem(menu, SWT.SEPARATOR);
 
@@ -1214,9 +1541,13 @@ public class TorrentUtil {
 		final MenuItem itemQueue = new MenuItem(menu, SWT.PUSH);
 		Messages.setLanguageText(itemQueue, "MyTorrentsView.menu.queue"); //$NON-NLS-1$
 		Utils.setMenuItemImage(itemQueue, "start");
-		itemQueue.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager[] dms) {
-				queueTorrents(dms, menu.getShell());
+		itemQueue.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						queueDataSources(dms, true);
+					}
+				});
 			}
 		});
 		itemQueue.setEnabled(start);
@@ -1241,11 +1572,15 @@ public class TorrentUtil {
 		final MenuItem itemStop = new MenuItem(menu, SWT.PUSH);
 		Messages.setLanguageText(itemStop, "MyTorrentsView.menu.stop"); //$NON-NLS-1$
 		Utils.setMenuItemImage(itemStop, "stop");
-		itemStop.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager[] dms) {
-				stopTorrents(dms, menu.getShell());
+		itemStop.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						stopDataSources(dms);
+					}
+				});
 			}
-		});
+		}); 
 		itemStop.setEnabled(stop);
 
 		// Force Recheck
@@ -1261,54 +1596,17 @@ public class TorrentUtil {
 		});
 		itemRecheck.setEnabled(recheck);
 
-		// Remove
+		// Delete
 		final MenuItem itemRemove = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(itemRemove, "MyTorrentsView.menu.remove"); //$NON-NLS-1$
+		Messages.setLanguageText(itemRemove, "menu.delete.options");
 		Utils.setMenuItemImage(itemRemove, "delete");
-		itemRemove.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager dm) {
-				removeTorrent(dm, false, false, menu.getShell());
+		itemRemove.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				removeDownloads(dms, null, true);
 			}
 		});
 		itemRemove.setEnabled(hasSelection);
 
-		// === Remove And ===
-		// ==================
-
-		final MenuItem itemRemoveAnd = new MenuItem(menu, SWT.CASCADE);
-		Messages.setLanguageText(itemRemoveAnd, "MyTorrentsView.menu.removeand"); //$NON-NLS-1$
-		Utils.setMenuItemImage(itemRemoveAnd, "delete");
-		itemRemoveAnd.setEnabled(hasSelection);
-
-		final Menu menuRemove = new Menu(composite.getShell(), SWT.DROP_DOWN);
-		itemRemoveAnd.setMenu(menuRemove);
-
-		// Remove And > Delete Torrent
-		final MenuItem itemDeleteTorrent = new MenuItem(menuRemove, SWT.PUSH);
-		Messages.setLanguageText(itemDeleteTorrent, "MyTorrentsView.menu.removeand.deletetorrent"); //$NON-NLS-1$
-		itemDeleteTorrent.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager dm) {
-				removeTorrent(dm, true, false, menu.getShell());
-			}
-		});
-
-		// Remove And > Delete Data
-		final MenuItem itemDeleteData = new MenuItem(menuRemove, SWT.PUSH);
-		Messages.setLanguageText(itemDeleteData, "MyTorrentsView.menu.removeand.deletedata");
-		itemDeleteData.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager dm) {
-				removeTorrent(dm, false, true, menu.getShell());
-			}
-		});
-
-		// Remove And > Delete Both
-		final MenuItem itemDeleteBoth = new MenuItem(menuRemove, SWT.PUSH);
-		Messages.setLanguageText(itemDeleteBoth, "MyTorrentsView.menu.removeand.deleteboth");
-		itemDeleteBoth.addListener(SWT.Selection, new DMTask(dms) {
-			public void run(DownloadManager dm) {
-				removeTorrent(dm, true, true, menu.getShell());
-			}
-		});
 	}
 
 	private static void addCategorySubMenu(final DownloadManager[] dms, Menu menuCategory, final Composite composite) {
@@ -1431,7 +1729,15 @@ public class TorrentUtil {
 			File fSavePath = new File(sSavePath);
 			for (int i = 0; i < dms.length; i++) {
 				DownloadManager dm = dms[i];
-				if (dm.getState() == DownloadManager.STATE_ERROR) {
+				
+				int state = dm.getState();
+				if (state == DownloadManager.STATE_STOPPED) {
+					if (!dm.filesExist(true)) {
+						state = DownloadManager.STATE_ERROR;
+					}
+				}
+
+				if (state == DownloadManager.STATE_ERROR) {
 					
 					dm.setTorrentSaveDir(sSavePath);
 					
@@ -1459,11 +1765,18 @@ public class TorrentUtil {
 		}
 	}
 
-	public static void runTorrents(Object[] download_managers) {
-		for (int i = download_managers.length - 1; i >= 0; i--) {
-			DownloadManager dm = (DownloadManager) download_managers[i];
-			if (dm != null) {
+	/**
+	 * Runs a DownloadManager or DiskManagerFileInfo
+	 */
+	public static void runDataSources(Object[] datasources) {
+		for (int i = datasources.length - 1; i >= 0; i--) {
+			Object ds = PluginCoreUtils.convert(datasources[i], true);
+			if (ds instanceof DownloadManager) {
+				DownloadManager dm = (DownloadManager) ds;
 				ManagerUtils.run(dm);
+			} else if (ds instanceof DiskManagerFileInfo) {
+				DiskManagerFileInfo info = (DiskManagerFileInfo) ds;
+				Utils.launch(info);
 			}
 		}
 	}
@@ -1496,36 +1809,84 @@ public class TorrentUtil {
 		}
 	}
 
-	public static void removeTorrent(final DownloadManager dm, final boolean bDeleteTorrent, final boolean bDeleteData,
-			Shell shell) {
-		ManagerUtils.remove(dm, shell, bDeleteTorrent, bDeleteData);
+	public static void removeDataSources(final Object[] datasources) {
+		DownloadManager[] dms = toDMS(datasources);
+		removeDownloads(dms, null);
+		DiskManagerFileInfo[] fileInfos = toDMFI(datasources);
+		if (fileInfos.length > 0) {
+			FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_DELETE,
+					fileInfos);
+		}
 	}
 
-	public static void removeTorrents(Object[] download_managers, final Shell shell) {
-		DMTask task = new DMTask(toDMS(download_managers)) {
-			public void run(DownloadManager dm) {
-				removeTorrent(dm, false, false, shell);
+	public static boolean shouldStopGroup(Object[] datasources) {
+		DownloadManager[] dms = toDMS(datasources);
+		DiskManagerFileInfo[] dmfi = toDMFI(datasources);
+		if (dms.length == 0 && dmfi.length == 0) {
+			return true;
+		}
+		for (DownloadManager dm : dms) {
+			int state = dm.getState();
+			boolean stopped = state == DownloadManager.STATE_STOPPED
+					|| state == DownloadManager.STATE_STOPPING;
+			if (!stopped) {
+				return true;
 			}
-		};
-		task.go();
+		}
+		
+		for (DiskManagerFileInfo fileInfo : dmfi) {
+			if (!fileInfo.isSkipped()) {
+				return true;
+			}
+		}
+		return false;
 	}
 
-	public static void stopTorrents(Object[] download_managers, final Shell shell) {
-		DMTask task = new DMTask(toDMS(download_managers)) {
-			public void run(DownloadManager dm) {
-				ManagerUtils.stop(dm, shell);
-			}
-		};
-		task.go();
+	public static void stopOrStartDataSources(Object[] datasources) {
+		DownloadManager[] dms = toDMS(datasources);
+		DiskManagerFileInfo[] dmfi = toDMFI(datasources);
+		if (dms.length == 0 && dmfi.length == 0) {
+			return;
+		}
+		boolean doStop = shouldStopGroup(datasources);
+		if (doStop) {
+			stopDataSources(datasources);
+		} else {
+			queueDataSources(datasources, true);
+		}
 	}
 
-	public static void queueTorrents(Object[] download_managers, final Shell shell) {
-		DMTask task = new DMTask(toDMS(download_managers)) {
-			public void run(DownloadManager dm) {
-				ManagerUtils.queue(dm, shell);
+	public static void stopDataSources(Object[] datasources) {
+		DownloadManager[] dms = toDMS(datasources);
+		for (DownloadManager dm : dms) {
+			ManagerUtils.stop(dm, null);
+		}
+		DiskManagerFileInfo[] fileInfos = toDMFI(datasources);
+		if (fileInfos.length > 0) {
+			FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_SKIPPED,
+					fileInfos);
+		}
+	}
+
+	public static void queueDataSources(Object[] datasources,
+			boolean startStoppedParents) {
+		DownloadManager[] dms = toDMS(datasources);
+		for (DownloadManager dm : dms) {
+			ManagerUtils.queue(dm, null);
+		}
+		DiskManagerFileInfo[] fileInfos = toDMFI(datasources);
+		if (fileInfos.length > 0) {
+			FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_NORMAL,
+					fileInfos);
+
+			if (startStoppedParents) {
+				for (DiskManagerFileInfo fileInfo : fileInfos) {
+					if (fileInfo.getDownloadManager().getState() == DownloadManager.STATE_STOPPED) {
+						ManagerUtils.queue(fileInfo.getDownloadManager(), null);
+					}
+				}
 			}
-		};
-		task.go();
+		}
 	}
 
 	public static void resumeTorrents(Object[] download_managers) {
@@ -1578,10 +1939,48 @@ public class TorrentUtil {
 
 
 	private static DownloadManager[] toDMS(Object[] objects) {
-		if (objects instanceof DownloadManager[]) { return (DownloadManager[]) objects; }
+		int count = 0;
 		DownloadManager[] result = new DownloadManager[objects.length];
-		System.arraycopy(objects, 0, result, 0, result.length);
-		return result;
+		for (Object object : objects) {
+			if (object instanceof DownloadManager) {
+				DownloadManager dm = (DownloadManager) object;
+				result[count++] = dm;
+			} else if (object instanceof SelectedContent) {
+				SelectedContent sc = (SelectedContent) object;
+				if (sc.getFileIndex() == -1 && sc.getDownloadManager() != null) {
+					result[count++] = sc.getDownloadManager();
+				}
+			}
+		}
+		DownloadManager[] resultTrim = new DownloadManager[count];
+		System.arraycopy(result, 0, resultTrim, 0, count);
+		return resultTrim;
+	}
+
+	private static DiskManagerFileInfo[] toDMFI(Object[] objects) {
+		int count = 0;
+		DiskManagerFileInfo[] result = new DiskManagerFileInfo[objects.length];
+		for (Object object : objects) {
+			if (object instanceof DiskManagerFileInfo) {
+				DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) object;
+				result[count++] = fileInfo;
+			} else if (object instanceof SelectedContent) {
+				SelectedContent sc = (SelectedContent) object;
+				int fileIndex = sc.getFileIndex();
+				if (fileIndex >= 0 && sc.getDownloadManager() != null) {
+					DownloadManager dm = sc.getDownloadManager();
+					if (dm != null) {
+						DiskManagerFileInfo[] infos = dm.getDiskManagerFileInfo();
+						if (fileIndex < infos.length) {
+							result[count++] = infos[fileIndex];
+						}
+					}
+				}
+			}
+		}
+		DiskManagerFileInfo[] resultTrim = new DiskManagerFileInfo[count];
+		System.arraycopy(result, 0, resultTrim, 0, count);
+		return resultTrim;
 	}
 
 	private abstract static class DMTask implements Listener {
@@ -1670,20 +2069,49 @@ public class TorrentUtil {
 
 		if (!sFirstChunk.startsWith("d")) {
 			if (parentShell != null) {
-  			boolean isHTML = sFirstChunk.indexOf("<html") >= 0;
-  			MessageBoxShell boxShell = new MessageBoxShell(
-  					MessageText.getString("OpenTorrentWindow.mb.notTorrent.title"),
-  					MessageText.getString("OpenTorrentWindow.mb.notTorrent.text",
-  							new String[] {
-									torrentName,
-									isHTML ? "" : MessageText.getString("OpenTorrentWindow.mb.notTorrent.cannot.display")
-  							}), new String[] {
-  						MessageText.getString("Button.ok")
-  					}, 0);
-  			if (isHTML) {
-  				boxShell.setHtml(sFirstChunk);
-  			}
-  			boxShell.open(null);
+				boolean isHTML = sFirstChunk.indexOf("<html") >= 0;
+				
+				final String retry_url = UrlUtils.parseTextForMagnets( torrentName );
+				
+				String[] buttons;
+				
+				if ( retry_url == null ){
+					
+					buttons = new String[]{ MessageText.getString("Button.ok") };
+				}else{
+					
+					buttons = 
+						new String[]{
+							MessageText.getString( "OpenTorrentWindow.mb.notTorrent.retry" ),
+							MessageText.getString( "Button.cancel" )};
+				}
+				
+				MessageBoxShell boxShell = new MessageBoxShell(
+						MessageText.getString("OpenTorrentWindow.mb.notTorrent.title"),
+						MessageText.getString("OpenTorrentWindow.mb.notTorrent.text",
+								new String[] {
+								torrentName,
+								isHTML ? "" : MessageText.getString("OpenTorrentWindow.mb.notTorrent.cannot.display")
+						}),
+						buttons
+						, 0 );
+				
+				if (isHTML) {
+					boxShell.setHtml(sFirstChunk);
+				}
+				boxShell.open(
+					new UserPrompterResultListener()
+					{
+						public void 
+						prompterClosed(
+							int result )
+						{
+							if ( result == 0 && retry_url != null ){
+								
+								TorrentOpener.openTorrent( retry_url );
+							}
+						}
+					});
 			}
 
 			return false;
@@ -1691,4 +2119,321 @@ public class TorrentUtil {
 
 		return true;
 	}
+
+	public static Map<String, Long> calculateToolbarStates(
+				ISelectedContent[] currentContent, String viewID) {
+			//System.out.println("updateCoreItems(" + currentContent.length + ", " + viewID + " via " + Debug.getCompressedStackTrace());
+			String[] TBKEYS = new String[] {
+				"download",
+				"play",
+				"stream",
+				"run",
+				"top",
+				"up",
+				"down",
+				"bottom",
+				"start",
+				"stop",
+				"remove"
+			};
+			
+			Map<String, Long> mapNewToolbarStates = new HashMap<String, Long>();
+			
+			String[] itemsNeedingSelection = {};
+	
+			String[] itemsNeedingRealDMSelection = {
+				"remove",
+				"top",
+				"bottom",
+				"transcode",
+				"startstop",
+			};
+	
+			String[] itemsRequiring1DMwithHash = {
+				"details",
+				"comment",
+				"up",
+				"down",
+			};
+	
+			String[] itemsRequiring1DMSelection = {};
+	
+			int numSelection = currentContent.length;
+			boolean hasSelection = numSelection > 0;
+			boolean has1Selection = numSelection == 1;
+	
+			for (int i = 0; i < itemsNeedingSelection.length; i++) {
+				String itemID = itemsNeedingSelection[i];
+			mapNewToolbarStates.put(itemID, hasSelection
+					? UIToolBarItem.STATE_ENABLED : 0);
+			}
+	
+			TableView tv = SelectedContentManager.getCurrentlySelectedTableView();
+			boolean hasRealDM = tv != null;
+			if (!hasRealDM) {
+				MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT();
+				if (mdi != null) {
+					MdiEntrySWT entry = mdi.getCurrentEntrySWT();
+					if (entry != null) {
+						if (entry.getDatasource() instanceof DownloadManager) {
+							hasRealDM = true;
+						} else if ((entry.getView() instanceof UIPluginView)
+								&& (((UIPluginView) entry.getView()).getDataSource() instanceof DownloadManager)) {
+							hasRealDM = true;
+						}
+					}
+				}
+			}
+	
+			boolean canStart = false;
+			boolean canStop = false;
+	    boolean canRemoveFileInfo = false;
+	    boolean canRunFileInfo = false;
+	    boolean hasDM = false;
+	
+			if (currentContent.length > 0 && hasRealDM) {
+				for (int i = 0; i < currentContent.length; i++) {
+					ISelectedContent content = currentContent[i];
+					DownloadManager dm = content.getDownloadManager();
+					int fileIndex = content.getFileIndex();
+					if (fileIndex == -1) {
+						hasDM = true;
+	  				if (!canStart && ManagerUtils.isStartable(dm)) {
+	  					canStart = true;
+	  				}
+	  				if (!canStop && ManagerUtils.isStopable(dm)) {
+	  					canStop = true;
+	  				}
+					} else {
+						DiskManagerFileInfo[] fileInfos = dm.getDiskManagerFileInfo();
+						if (fileIndex < fileInfos.length) {
+							DiskManagerFileInfo fileInfo = fileInfos[fileIndex];
+			    		if (!canStart && (fileInfo.isSkipped())) {
+			    			canStart = true;
+			    		}
+			    		
+			    		if (!canStop && !fileInfo.isSkipped()) {
+			    			canStop = true;
+			    		}
+			    		
+							if (!canRemoveFileInfo && !fileInfo.isSkipped()) {
+								int storageType = fileInfo.getStorageType();
+								if (storageType == DiskManagerFileInfo.ST_LINEAR
+										|| storageType == DiskManagerFileInfo.ST_COMPACT) {
+									canRemoveFileInfo = true;
+								}
+			    		}
+							
+							if (!canRunFileInfo
+									&& fileInfo.getAccessMode() == DiskManagerFileInfo.READ
+									&& fileInfo.getDownloaded() == fileInfo.getLength()
+									&& fileInfo.getFile(true).exists()) {
+								canRunFileInfo = true;
+							}
+						}
+					}
+				}
+				boolean canRemove = hasDM || canRemoveFileInfo;
+			mapNewToolbarStates.put("remove", canRemove
+					? UIToolBarItem.STATE_ENABLED : 0);
+			}
+	
+	    boolean canRun = has1Selection && ((hasDM && !canRunFileInfo) || (!hasDM && canRunFileInfo));
+			if (canRun) {
+				ISelectedContent content = currentContent[0];
+				DownloadManager dm = content.getDownloadManager();
+	
+				if (dm == null) {
+					canRun = false;
+				} else {
+					TOTorrent torrent = dm.getTorrent();
+	
+					if (torrent == null) {
+	
+						canRun = false;
+	
+					} else if (!dm.getAssumedComplete() && torrent.isSimpleTorrent()) {
+	
+						canRun = false;
+	/*
+					} else if (PlatformTorrentUtils.useEMP(torrent)
+							&& PlatformTorrentUtils.embeddedPlayerAvail()
+							&& PlayUtils.canProgressiveOrIsComplete(torrent)) {
+						// play button enabled and not UMP.. don't need launch
+	
+						canRun = false;
+	
+					}
+					*/
+					}
+				}
+			}
+			mapNewToolbarStates.put("run", canRun ? UIToolBarItem.STATE_ENABLED : 0);
+	
+			mapNewToolbarStates.put("start", canStart ? UIToolBarItem.STATE_ENABLED : 0);
+			mapNewToolbarStates.put("stop", canStop ? UIToolBarItem.STATE_ENABLED : 0);
+	
+			for (int i = 0; i < itemsNeedingRealDMSelection.length; i++) {
+				String itemID = itemsNeedingRealDMSelection[i];
+				if (!mapNewToolbarStates.containsKey(itemID)) {
+	  			mapNewToolbarStates.put(itemID, hasSelection && hasDM
+	  					&& hasRealDM ? UIToolBarItem.STATE_ENABLED : 0);
+				}
+			}
+			for (int i = 0; i < itemsRequiring1DMSelection.length; i++) {
+				String itemID = itemsRequiring1DMSelection[i];
+				if (!mapNewToolbarStates.containsKey(itemID)) {
+					mapNewToolbarStates.put(itemID, has1Selection && hasDM ? UIToolBarItem.STATE_ENABLED : 0);
+				}
+			}
+	
+			for (int i = 0; i < itemsRequiring1DMwithHash.length; i++) {
+				String itemID = itemsRequiring1DMwithHash[i];
+				if (!mapNewToolbarStates.containsKey(itemID)) {
+					mapNewToolbarStates.put(itemID, hasDM ? UIToolBarItem.STATE_ENABLED : 0);
+				}
+			}
+	
+		mapNewToolbarStates.put(
+				"download",
+				has1Selection
+						&& (!(currentContent[0] instanceof ISelectedVuzeFileContent))
+						&& currentContent[0].getDownloadManager() == null
+						&& (currentContent[0].getHash() != null || currentContent[0].getDownloadInfo() != null)
+						? UIToolBarItem.STATE_ENABLED : 0);
+
+		if (tv != null) {
+			TableColumn tc = tv.getTableColumn(RankItem.COLUMN_ID);
+			if (tc != null && !tc.isVisible()) {
+				mapNewToolbarStates.put("up", 0L);
+				mapNewToolbarStates.put("down", 0L);
+			}
+		}
+			
+		return mapNewToolbarStates;
+	}
+
+	public static void removeDownloads(DownloadManager[] dms, AERunnable deleteFailed) {
+		removeDownloads(dms, deleteFailed, false);
+	}
+
+	public static void removeDownloads(final DownloadManager[] dms,
+			final AERunnable deleteFailed, final boolean forcePrompt) {
+		if (dms == null) {
+			return;
+		}
+
+		// 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) {
+				continue;
+			}
+
+			boolean deleteTorrent = COConfigurationManager.getBooleanParameter("def.deletetorrent");
+
+			int confirm = COConfigurationManager.getIntParameter("tb.confirm.delete.content");
+			boolean doPrompt = confirm == 0 | forcePrompt;
+
+			if (doPrompt) {
+				String title = MessageText.getString("deletedata.title");
+				String text = MessageText.getString("v3.deleteContent.message",
+						new String[] {
+							dm.getDisplayName()
+						});
+
+				String[] buttons;
+				int[] buttonVals;
+				int defaultButtonPos;
+				buttons = new String[] {
+					MessageText.getString("Button.cancel"),
+					MessageText.getString("Button.deleteContent.fromComputer"),
+					MessageText.getString("Button.deleteContent.fromLibrary"),
+				};
+				buttonVals = new int[] {
+					SWT.CANCEL,
+					1,
+					2
+				};
+				defaultButtonPos = 2;
+
+				final MessageBoxShell mb = new MessageBoxShell(title, text, buttons,
+						defaultButtonPos);
+				int numLeft = (dms.length - i);
+				if (numLeft > 1) {
+					mb.setRemember("na", false, MessageText.getString(
+							"v3.deleteContent.applyToAll", new String[] {
+								"" + numLeft
+							}));
+					// never store remember state
+					mb.setRememberOnlyIfButton(-3);
+				}
+				mb.setRelatedObject(dm);
+				mb.setLeftImage("image.trash");
+				mb.addCheckBox("deletecontent.also.deletetorrent", 2, deleteTorrent);
+
+				final int index = i;
+
+				mb.open(new UserPrompterResultListener() {
+
+					public void prompterClosed(int result) {
+						ImageLoader.getInstance().releaseImage("image.trash");
+
+						removeDownloadsPrompterClosed(dms, index, deleteFailed, result,
+								mb.isRemembered(), mb.getCheckBoxEnabled());
+					}
+				});
+				return;
+			} else {
+				boolean deleteData = confirm == 1;
+				removeDownloadsPrompterClosed(dms, i, deleteFailed, deleteData ? 1 : 2,
+						true, deleteTorrent);
+			}
+		}
+	}
+
+	private static void removeDownloadsPrompterClosed(DownloadManager[] dms,
+			int index, AERunnable deleteFailed, int result, boolean doAll,
+			boolean deleteTorrent) {
+		if (result == -1) {
+			// user pressed ESC (as opposed to clicked Cancel), cancel whole
+			// list
+			return;
+		}
+		if (doAll) {
+			if (result == 1 || result == 2) {
+
+				for (int i = index; i < dms.length; i++) {
+					DownloadManager dm = dms[i];
+					boolean deleteData = result == 2 ? false
+							: !dm.getDownloadState().getFlag(
+									Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE);
+					ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED,
+							deleteTorrent, deleteData, deleteFailed);
+				}
+			} //else cancel
+		} else { // not remembered
+			if (result == 1 || result == 2) {
+				DownloadManager dm = dms[index];
+				boolean deleteData = result == 2 ? false
+						: !dm.getDownloadState().getFlag(
+								Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE);
+
+				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, deleteFailed, true);
+			}
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/TrackerChangerWindow.java b/org/gudy/azureus2/ui/swt/TrackerChangerWindow.java
index aa1084d..1fdf6fd 100644
--- a/org/gudy/azureus2/ui/swt/TrackerChangerWindow.java
+++ b/org/gudy/azureus2/ui/swt/TrackerChangerWindow.java
@@ -20,6 +20,10 @@
  */
 package org.gudy.azureus2.ui.swt;
 
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -43,8 +47,8 @@ import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
  * 
  */
 public class TrackerChangerWindow {
-  public TrackerChangerWindow(final Display display, final DownloadManager[] dms ) {
-    final Shell shell = ShellFactory.createShell(display);
+  public TrackerChangerWindow(final DownloadManager[] dms ) {
+    final Shell shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM );
     shell.setText(MessageText.getString("TrackerChangerWindow.title"));
     Utils.setShellIcon(shell);
     GridLayout layout = new GridLayout();
@@ -53,41 +57,76 @@ public class TrackerChangerWindow {
     Label label = new Label(shell, SWT.NONE);
     Messages.setLanguageText(label, "TrackerChangerWindow.newtracker");    
     GridData gridData = new GridData();
-    gridData.widthHint = 200;
+    gridData.widthHint = 400;
     label.setLayoutData(gridData);
 
     final Text url = new Text(shell, SWT.BORDER);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.widthHint = 300;
+    gridData.widthHint = 400;
     url.setLayoutData(gridData);
-    Utils.setTextLinkFromClipboard(shell, url, false);
+    Utils.setTextLinkFromClipboard(shell, url, false, false);
+
+    Label labelSeparator = new Label(shell,SWT.SEPARATOR | SWT.HORIZONTAL);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    labelSeparator.setLayoutData(gridData);
 
-    Composite panel = new Composite(shell, SWT.NULL);
+    Composite panel = new Composite(shell, SWT.NONE);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    panel.setLayoutData(gridData);
     layout = new GridLayout();
     layout.numColumns = 3;
     panel.setLayout(layout);        
-    gridData = new GridData();
-    gridData.horizontalSpan = 2;
-    panel.setLayoutData(gridData);
+ 
+    
+    
+    label = new Label( panel, SWT.NONE );
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    label.setLayoutData(gridData );
+    
     Button ok = new Button(panel, SWT.PUSH);
     ok.setText(MessageText.getString("Button.ok"));
     gridData = new GridData();
     gridData.widthHint = 70;
+    gridData.horizontalAlignment = GridData.END;
     ok.setLayoutData(gridData);
     shell.setDefaultButton(ok);
     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 {
+        	String[] _urls = url.getText().split( "," );
+        	
+        	List<String>	urls = new ArrayList<String>();
+        	
+    		for ( String url: _urls ){
+    			
+    			url = url.trim();
+    			
+    			if ( url.length() > 0 ){
+    				
+    				try{
+    					new URL( url );
+    					
+    					urls.add( 0, url );
+    					
+    				}catch( Throwable e ){
+    					
+    					Debug.out( "Invalid URL: " + url );
+    				}
+    			}
+    		}
+    		
         	for ( DownloadManager dm: dms ){
+        		
 	        	TOTorrent	torrent = dm.getTorrent();
 	        	
 	        	if ( torrent != null ){
 	        	
-	        		TorrentUtils.announceGroupsInsertFirst( torrent, url.getText());
-	        	
+	        		for ( String url: urls ){
+	        		
+	        			TorrentUtils.announceGroupsInsertFirst( torrent, url );
+	        		}
+	        		
 	        		TorrentUtils.writeToFile( torrent );
 	        	
 	        		TRTrackerAnnouncer announcer = dm.getTrackerClient();
@@ -111,17 +150,17 @@ public class TrackerChangerWindow {
     cancel.setText(MessageText.getString("Button.cancel"));
     gridData = new GridData();
     gridData.widthHint = 70;
+    gridData.horizontalAlignment = GridData.END;
     cancel.setLayoutData(gridData);
     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.pack();
+	Utils.centreWindow( shell );
     Utils.createURLDropTarget(shell, url);
     shell.open();
   }
diff --git a/org/gudy/azureus2/ui/swt/TrayWindow.java b/org/gudy/azureus2/ui/swt/TrayWindow.java
index f6e45f2..17c8322 100644
--- a/org/gudy/azureus2/ui/swt/TrayWindow.java
+++ b/org/gudy/azureus2/ui/swt/TrayWindow.java
@@ -28,6 +28,7 @@ import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerStats;
@@ -36,14 +37,13 @@ import org.gudy.azureus2.core3.global.GlobalManagerListener;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 import org.gudy.azureus2.ui.swt.mainwindow.ListenerNeedingCoreRunning;
-import org.gudy.azureus2.ui.swt.mainwindow.MainWindow;
 import org.gudy.azureus2.ui.swt.mainwindow.MenuFactory;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 import org.gudy.azureus2.ui.systray.SystemTraySWT;
 
 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.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
@@ -65,7 +65,6 @@ public class TrayWindow
   protected AEMonitor managers_mon 	= new AEMonitor(ID);
 
 
-  MainWindow main;
   Display display;
   Shell minimized;
   Label label;
@@ -77,9 +76,8 @@ public class TrayWindow
   private int yPressed;
   private boolean moving;
 
-  public TrayWindow(MainWindow _main) {
+  public TrayWindow() {
     this.managers = new ArrayList();
-    this.main = _main;
     UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
     Shell mainShell = uif == null ? Utils.findAnyShell() : uif.getMainShell();
     this.display = mainShell.getDisplay();
@@ -192,7 +190,7 @@ public class TrayWindow
     Messages.setLanguageText(file_exit, "TrayWindow.menu.exit"); //$NON-NLS-1$
     file_exit.addListener(SWT.Selection, new Listener() {
       public void handleEvent(Event e) {
-        main.dispose(false,false);
+      	UIFunctionsManager.getUIFunctions().dispose(false, false);
       }
     });
 
diff --git a/org/gudy/azureus2/ui/swt/TwistieLabel.java b/org/gudy/azureus2/ui/swt/TwistieLabel.java
deleted file mode 100644
index 6f7f0ca..0000000
--- a/org/gudy/azureus2/ui/swt/TwistieLabel.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/**
- * 
- */
-package org.gudy.azureus2.ui.swt;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseListener;
-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.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-
-/**
- * A Label with a twistie graphic at the beginning; every time this label is clicked the
- * twistie graphic toggles between pointing to the right and pointing down.
- * 
- * @author knguyen
- *
- */
-public class TwistieLabel
-	extends Composite
-	implements ITwistieConstants
-{
-
-	private int style = NONE;
-
-	/**
-	 * An array of points for a triangle pointing downward
-	 */
-	static final int[] points_for_expanded = {
-		0,
-		2,
-		8,
-		2,
-		4,
-		6
-	};
-
-	/**
-	 * An array of points for a triangle pointing to the right
-	 * 
-	 */
-	static final int[] points_for_collapsed = {
-		2,
-		-1,
-		2,
-		8,
-		6,
-		4
-	};
-
-	/**
-	 * <code>Label</code> to display the text for this twistie
-	 */
-	private Label titleLabel = null;
-
-	/**
-	 * The <code>Color</code> to use for the twistie graphic itself;
-	 * defaults to the same as the foreground color of the titleLabel
-	 */
-	private Color twistieColor = null;
-
-	/**
-	 * The state of the control; callers can check this state by calling {@link #isCollapsed()}
-	 */
-	private boolean isCollapsed = true;
-
-	/**
-	 * An optional Label to display the description
-	 */
-	private Label descriptionLabel = null;
-
-	private List listeners = new ArrayList();
-
-	/**
-	 * Create a twistie Label with the given style bit.
-	 * <p>Style bit can be one or more of:</p>
-	 * <ul>
-	 * <li> TwistieLabel.NONE</li> -- The default; does not show description and separator, and is collapsed
-	 * <li> TwistieLabel.SHOW_DESCRIPTION</li> -- Show the description below the separator (or title if separator s not shown)
-	 * <li> TwistieLabel.SHOW_SEPARATOR</li> -- Show a separator below the title
-	 * <li> TwistieLabel.SHOW_EXPANDED</li> -- Show a separator below the title
-	 * </ul>
-	 * 
-	 * @param parent
-	 * @param style
-	 */
-	public TwistieLabel(Composite parent, int style) {
-		super(parent, SWT.NONE);
-		setBackgroundMode(SWT.INHERIT_FORCE);
-		this.style = style;
-
-		GridLayout gLayout = new GridLayout();
-		gLayout.marginHeight = 0;
-		gLayout.marginWidth = 0;
-		gLayout.verticalSpacing = 0;
-		gLayout.horizontalSpacing = 0;
-		setLayout(gLayout);
-
-		titleLabel = new Label(this, SWT.NONE);
-
-		if ((this.style & SHOW_SEPARATOR) != 0) {
-			Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
-			GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
-			labelData.horizontalIndent = 10;
-			separator.setLayoutData(labelData);
-		}
-
-		if ((this.style & SHOW_DESCRIPTION) != 0) {
-			descriptionLabel = new Label(this, SWT.WRAP);
-			GridData labelData = new GridData(SWT.FILL, SWT.FILL, true, false);
-			labelData.horizontalIndent = 10;
-			descriptionLabel.setLayoutData(labelData);
-
-			/*
-			 * Change the font to be italic for the description
-			 */
-			Font initialFont = descriptionLabel.getFont();
-			FontData[] fontData = initialFont.getFontData();
-			for (int i = 0; i < fontData.length; i++) {
-				fontData[i].setStyle(fontData[i].getStyle() | SWT.ITALIC);
-			}
-			descriptionLabel.setFont(new Font(getDisplay(), fontData));
-
-		}
-
-		if ((this.style & SHOW_EXPANDED) != 0) {
-			isCollapsed = false;
-		}
-
-		/*
-		 * Leaving a little margin on the left; this is where we draw the twistie graphic
-		 */
-		GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
-		labelData.horizontalIndent = 10;
-		titleLabel.setLayoutData(labelData);
-
-		/*
-		 * Add our mouse interceptor to the control and the title label
-		 */
-		MouseInterceptor interceptor = new MouseInterceptor();
-		super.addMouseListener(interceptor);
-		titleLabel.addMouseListener(interceptor);
-
-		/*
-		 * Listens to the paint event and do the drawing here
-		 */
-		addPaintListener(new PaintListener() {
-			public void paintControl(PaintEvent e) {
-
-				/*
-				 * The graphic is drawn to the left of the titleLabel so define the offset from the titleLabel
-				 */
-				int offsetX = titleLabel.getBounds().x - 10;
-				int offsetY = titleLabel.getBounds().y + 3;
-
-				if (null != twistieColor) {
-					e.gc.setBackground(twistieColor);
-				} else {
-					e.gc.setBackground(getForeground());
-				}
-
-				if (true == isCollapsed) {
-					e.gc.fillPolygon(translate(points_for_collapsed, offsetX, offsetY));
-				} else {
-					e.gc.fillPolygon(translate(points_for_expanded, offsetX, offsetY));
-				}
-			}
-		});
-	}
-
-	/**
-	 * Translates the twistie points array to compensate for the given x and y offset
-	 * @param data
-	 * @param x
-	 * @param y
-	 * @return
-	 */
-	private int[] translate(int[] data, int x, int y) {
-
-		int[] target = new int[data.length];
-		for (int i = 0; i < data.length; i += 2) {
-			target[i] = data[i] + x;
-		}
-		for (int i = 1; i < data.length; i += 2) {
-			target[i] = data[i] + y;
-		}
-		return target;
-	}
-
-	/**
-	 * Add a mouse listener to the control and also the <code>titleLabel</code>
-	 */
-	public void addMouseListener(MouseListener listener) {
-		if (null != titleLabel) {
-			titleLabel.addMouseListener(listener);
-		}
-		super.addMouseListener(listener);
-	}
-
-	/**
-	 * Remove the mouse listener from the control and also the <code>titleLabel</code>
-	 */
-	public void removeMouseListener(MouseListener listener) {
-		if (null != titleLabel) {
-			titleLabel.removeMouseListener(listener);
-		}
-		super.removeMouseListener(listener);
-	}
-
-	/**
-	 * Sets the color to be used for drawing the twistie graphic
-	 * @param color
-	 */
-	public void setTwistieForeground(Color color) {
-		twistieColor = color;
-	}
-
-	/**
-	 * Sets the foreground color for the control and also all the text-base children
-	 */
-	public void setForeground(Color color) {
-		if (null != titleLabel && false == titleLabel.isDisposed()) {
-			titleLabel.setForeground(color);
-		}
-		if (null != descriptionLabel && false == descriptionLabel.isDisposed()) {
-			descriptionLabel.setForeground(color);
-		}
-
-		if (null == twistieColor) {
-			twistieColor = color;
-		}
-
-		super.setForeground(color);
-	}
-
-	/**
-	 * Sets the background color for the control and also all the text-base children
-	 */
-	public void setBackground(Color color) {
-		if (null != titleLabel) {
-			titleLabel.setBackground(color);
-		}
-		if (null != descriptionLabel) {
-			descriptionLabel.setBackground(color);
-		}
-
-		super.setBackground(color);
-	}
-
-	/**
-	 * Sets the text to display as the title
-	 * @param string
-	 */
-	public void setTitle(String string) {
-		if (null != titleLabel) {
-			titleLabel.setText(string);
-		}
-	}
-
-	/**
-	 * Sets the text to display as the description; this is not in effect unless the {@link #SHOW_DESCRIPTION} flag is also set
-	 * @param string
-	 */
-	public void setDescription(String string) {
-		if (null != descriptionLabel) {
-			descriptionLabel.setText(string);
-		}
-	}
-
-	/**
-	 * Sets the tooltip for the control and also all the text-base children
-	 */
-	public void setToolTipText(String string) {
-		if (null != titleLabel) {
-			titleLabel.setToolTipText(string);
-		}
-
-		if (null != descriptionLabel) {
-			descriptionLabel.setToolTipText(string);
-		}
-
-		super.setToolTipText(string);
-	}
-
-	/**
-	 * Sets the enablement for the control and also all the text-base children
-	 */
-	public void setEnabled(boolean enabled) {
-		if (null != titleLabel) {
-			titleLabel.setEnabled(enabled);
-		}
-
-		super.setEnabled(enabled);
-	}
-
-	/**
-	 * Returns whether this control is in a collapsed state
-	 * @return
-	 */
-	public boolean isCollapsed() {
-		return isCollapsed;
-	}
-
-	/**
-	 * Add a listener to be notified whenever this control is collapsed or expanded; listeners
-	 * can check the collapsed/expanded state on the control and perform layout changes if need be.
-	 * @param listener
-	 */
-	public void addTwistieListener(ITwistieListener listener) {
-		listeners.add(listener);
-	}
-
-	public void removeTwistieListener(ITwistieListener listener) {
-		listeners.remove(listener);
-	}
-
-	private void notifyTwistieListeners() {
-		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
-			((ITwistieListener) iterator.next()).isCollapsed(isCollapsed());
-
-		}
-	}
-
-	/**
-	 * A listener that intercepts mouseDown events from the control and the title label so we can
-	 * fire a single event to the listener to signal that the control has been collapsed or expanded.
-	 * 
-	 * 
-	 * @author knguyen
-	 *
-	 */
-	private class MouseInterceptor
-		extends MouseAdapter
-	{
-
-		/*
-		 * Listens to the mouse click and toggle the isCollapsed flag then force a redraw to update the control
-		 */
-		public void mouseDown(MouseEvent e) {
-			isCollapsed = !isCollapsed;
-			redraw();
-			notifyTwistieListeners();
-		}
-
-	}
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/TwistieSection.java b/org/gudy/azureus2/ui/swt/TwistieSection.java
deleted file mode 100644
index 0bf3880..0000000
--- a/org/gudy/azureus2/ui/swt/TwistieSection.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package org.gudy.azureus2.ui.swt;
-
-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;
-
-public class TwistieSection
-	extends Composite
-	implements ITwistieConstants
-{
-	private TwistieContentPanel content = null;
-
-	private TwistieLabel label = null;
-
-	/**
-	 * Create a TwistieSection with the given style bit.
-	 * <p>Style bit can be one or more of:</p>
-	 * <ul>
-	 * <li> TwistieLabel.NONE</li> -- The default; does not show description and separator, and is collapsed
-	 * <li> TwistieLabel.SHOW_DESCRIPTION</li> -- Show the description below the separator (or title if separator s not shown)
-	 * <li> TwistieLabel.SHOW_SEPARATOR</li> -- Show a separator below the title
-	 * <li> TwistieLabel.SHOW_EXPANDED</li> -- Show a separator below the title
-	 * </ul>
-		*/
-	public TwistieSection(Composite parent, int style) {
-		super(parent, SWT.NONE);
-		setBackgroundMode(SWT.INHERIT_FORCE);
-		GridLayout gLayout = new GridLayout();
-		gLayout.marginHeight = 0;
-		gLayout.marginWidth = 0;
-		gLayout.verticalSpacing = 0;
-		setLayout(gLayout);
-
-		label = new TwistieLabel(this, style);
-		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
-
-		content = new TwistieContentPanel(this, SWT.NONE);
-		final GridData gDataExpanded = new GridData(SWT.FILL, SWT.FILL, true, true);
-		gDataExpanded.horizontalIndent = 10;
-		final GridData gDataCollapsed = new GridData(SWT.FILL, SWT.FILL, true,
-				false);
-		gDataCollapsed.heightHint = 0;
-
-		content._setLayoutData((true == label.isCollapsed()) ? gDataCollapsed
-				: gDataExpanded);
-
-		label.addTwistieListener(new ITwistieListener() {
-			public void isCollapsed(boolean value) {
-				content._setLayoutData((true == value) ? gDataCollapsed : gDataExpanded);
-				layout(true, true);
-
-			}
-
-		});
-
-	}
-
-	/**
-	 * Returns the main body of the section.  Callers can add custom controls onto the returned
-	 * <code>Composite</code>
-	 * @return
-	 */
-	public Composite getContent() {
-		return content;
-	}
-
-	public void setBackground(Color color) {
-		if (null != label && false == label.isDisposed()) {
-			label.setBackground(color);
-		}
-
-		if (null != content && false == content.isDisposed()) {
-			content.setBackground(color);
-		}
-
-		super.setBackground(color);
-	}
-
-	public void setForeground(Color color) {
-		if (null != label && false == label.isDisposed()) {
-			label.setForeground(color);
-		}
-
-		if (null != content && false == content.isDisposed()) {
-			content.setForeground(color);
-		}
-		super.setForeground(color);
-	}
-
-	public void setEnabled(boolean enabled) {
-		if (null != label && false == label.isDisposed()) {
-			label.setEnabled(enabled);
-		}
-		super.setEnabled(enabled);
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param listener
-	 */
-	public void addTwistieListener(ITwistieListener listener) {
-		if (null != label && false == label.isDisposed()) {
-			label.addTwistieListener(listener);
-		}
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param listener
-	 */
-	public void removeTwistieListener(ITwistieListener listener) {
-		if (null != label && false == label.isDisposed()) {
-			label.removeTwistieListener(listener);
-		}
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param string
-	 */
-
-	public void setDescription(String string) {
-		if (null != label && false == label.isDisposed()) {
-			label.setDescription(string);
-		}
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param string
-	 */
-
-	public void setTitle(String string) {
-		if (null != label && false == label.isDisposed()) {
-			label.setTitle(string);
-		}
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param string
-	 */
-
-	public void setToolTipText(String string) {
-		if (null != label && false == label.isDisposed()) {
-			label.setToolTipText(string);
-		}
-	}
-
-	/**
-	 * Delegating to the <code>TwistieLabel</code>
-	 * @param color
-	 */
-
-	public void setTwistieForeground(Color color) {
-		if (null != label && false == label.isDisposed()) {
-			label.setTwistieForeground(color);
-		}
-	}
-
-	/**
-	 * A simple extension of <code>Composite</code> that disallow modifying its layout data
-	 * @author knguyen
-	 *
-	 */
-	private class TwistieContentPanel
-		extends Composite
-	{
-
-		public TwistieContentPanel(Composite parent, int style) {
-			super(parent, style);
-			setBackgroundMode(SWT.INHERIT_FORCE);
-		}
-
-		private void _setLayoutData(GridData gData) {
-			super.setLayoutData(gData);
-		}
-
-		public void setLayoutData(Object layoutData) {
-			throw new IllegalArgumentException(
-					"This is a managed class therefore overriding its LayoutData is an illegal operation");
-		}
-
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java b/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
index 9efbfc1..a5e7755 100644
--- a/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
+++ b/org/gudy/azureus2/ui/swt/UIConfigDefaultsSWT.java
@@ -24,6 +24,8 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
 import org.gudy.azureus2.core3.util.Constants;
 
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+
 /**
  * @author TuxPaper
  * @created Nov 3, 2006
@@ -53,29 +55,24 @@ public class UIConfigDefaultsSWT
 		def.addParameter("DefaultDir.AutoUpdate", true);
 		def.addParameter("DefaultDir.AutoSave.AutoRename", true);
 		def.addParameter("GUI_SWT_bFancyTab", true);
-		def.addParameter("GUI_SWT_bAlternateTablePainting", false);
 		def.addParameter("Colors.progressBar.override", false);
 		def.addParameter("GUI_SWT_DisableAlertSliding", false);
 		def.addParameter("NameColumn.showProgramIcon", !Constants.isWindowsVista);
-		def.addParameter("Open MyTorrents", true);
 		def.addParameter("DND Always In Incomplete", false);
 
 		def.addParameter("Message Popup Autoclose in Seconds", 15);
 
 		def.addParameter("Add URL Silently", false);
-		def.addParameter("config.style.dropdiraction", "0");
 		def.addParameter("MyTorrents.SplitAt", 30);
 
 		def.addParameter("Wizard Completed", false);
+		def.addParameter("SpeedTest Completed", false);
 		def.addParameter("Color Scheme.red", 0);
 		def.addParameter("Color Scheme.green", 128);
 		def.addParameter("Color Scheme.blue", 255);
 		def.addParameter("Show Splash", true);
 		def.addParameter("window.maximized", true);
 		def.addParameter("window.rectangle", "");
-		def.addParameter("Open Console", false);
-		def.addParameter("Open Config", false);
-		def.addParameter("Open Stats On Start", false);
 		def.addParameter("Start Minimized", false);
 		def.addParameter("Open Transfer Bar On Start", false);
 		
@@ -91,6 +88,7 @@ public class UIConfigDefaultsSWT
 		def.addParameter("Status Area Show NAT", true);
 		def.addParameter("Status Area Show DDB", true);
 		def.addParameter("Status Area Show IPF", true);
+		def.addParameter("status.rategraphs", Utils.getUserMode() > 0);
 		
 		def.addParameter("GUI_SWT_share_count_at_close", 0 );
 
@@ -99,8 +97,6 @@ public class UIConfigDefaultsSWT
 		def.addParameter("ui.toolbar.uiswitcher", false);
 		def.addParameter("ui.systray.tooltip.enable", false);
 		
-		def.addParameter("ui", "az2");
-		
 		def.addParameter("Remember transfer bar location", true);
 		
 		if ( COConfigurationManager.getBooleanParameter( "Open Bar" )){
@@ -126,6 +122,23 @@ public class UIConfigDefaultsSWT
 		def.addParameter("MyTorrentsView.table.style", 0);
 		def.addParameter("MyTorrentsView.alwaysShowHeader", true);
 		
-		def.addParameter("ConfigView.section.style.swt.library.selection", "cocoa");
+		if (Constants.isOSX) {
+			def.addParameter("ConfigView.section.style.swt.library.selection", "cocoa");
+		}
+		def.addParameter("v3.topbar.height", 60);
+		def.addParameter("v3.topbar.show.plugin", false);
+		def.addParameter("pluginbar.visible", false);
+		def.addParameter("ui.toolbar.uiswitcher", false);
+		def.addParameter("Table.extendedErase", false);
+		def.addParameter("Table.useTree", false);
+
+		if ("az2".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui", "az3"))) {
+			def.addParameter("v3.Show Welcome", false);
+
+			def.addParameter("list.dm.dblclick", "1");
+			def.addParameter(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY + ".viewmode", 1);
+  		def.addParameter(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY_DL + "DL.viewmode", 1);
+  		def.addParameter(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY_CD + ".viewmode", 1);
+		}
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java b/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
index f66aee6..fe52d27 100644
--- a/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
+++ b/org/gudy/azureus2/ui/swt/UIExitUtilsSWT.java
@@ -57,6 +57,13 @@ public class UIExitUtilsSWT
 		listeners.add( l );
 	}
 	
+	public static void
+	removeListener(
+		canCloseListener	l )
+	{
+		listeners.remove( l );
+	}
+	
 	public static void setSkipCloseCheck(boolean b) {
 		skipCloseCheck = b;
 	}
@@ -95,94 +102,6 @@ public class UIExitUtilsSWT
 			}
 		}
 		
-		if (globalManager != null) {
-			ArrayList listUnfinished = new ArrayList();
-			Object[] dms = globalManager.getDownloadManagers().toArray();
-			for (int i = 0; i < dms.length; i++) {
-				DownloadManager dm = (DownloadManager) dms[i];
-				if (dm.getState() == DownloadManager.STATE_SEEDING
-						&& dm.getDownloadState().isOurContent()
-						&& dm.getStats().getAvailability() < 2) {
-					TRTrackerScraperResponse scrape = dm.getTrackerScrapeResponse();
-					int numSeeds = scrape.getSeeds();
-					long seedingStartedOn = dm.getStats().getTimeStartedSeeding();
-					if ((numSeeds > 0) && (seedingStartedOn > 0)
-							&& (scrape.getScrapeStartTime() > seedingStartedOn))
-						numSeeds--;
-
-					if (numSeeds == 0) {
-						listUnfinished.add(dm);
-					}
-				}
-			}
-
-			if (listUnfinished.size() > 0) {
-				boolean allowQuit;
-				final List flistUnfinished = listUnfinished;
-				if (listUnfinished.size() == 1) {
-					allowQuit = Utils.execSWTThreadWithBool("quitSeeding",
-							new AERunnableBoolean() {
-								public boolean runSupport() {
-									String title = MessageText.getString("Content.alert.notuploaded.title");
-									String text = MessageText.getString(
-											"Content.alert.notuploaded.text",
-											new String[] {
-												((DownloadManager) flistUnfinished.get(0)).getDisplayName(),
-												MessageText.getString("Content.alert.notuploaded.quit")
-											});
-
-									MessageBoxShell mb = new MessageBoxShell(
-											title,
-											text,
-											new String[] {
-												MessageText.getString("UpdateWindow.quit"),
-												MessageText.getString("Content.alert.notuploaded.button.abort")
-											}, 1);
-									mb.setRelatedObject(((DownloadManager) flistUnfinished.get(0)));
-
-									mb.open(null);
-									return mb.waitUntilClosed() == 0;
-								}
-							}, 0);
-				} else {
-					allowQuit = Utils.execSWTThreadWithBool("quitSeeding",
-							new AERunnableBoolean() {
-								public boolean runSupport() {
-									String sList = "";
-									for (int i = 0; i < flistUnfinished.size() && i < 5; i++) {
-										DownloadManager dm = ((DownloadManager) flistUnfinished.get(i));
-										if (sList != "") {
-											sList += "\n";
-										}
-										sList += dm.getDisplayName();
-									}
-
-									String title = MessageText.getString("Content.alert.notuploaded.multi.title");
-									String text = MessageText.getString(
-											"Content.alert.notuploaded.multi.text",
-											new String[] {
-												"" + flistUnfinished.size(),
-												MessageText.getString("Content.alert.notuploaded.quit"),
-												sList
-											});
-
-									MessageBoxShell mb = new MessageBoxShell(
-											title,
-											text,
-											new String[] {
-												MessageText.getString("UpdateWindow.quit"),
-												MessageText.getString("Content.alert.notuploaded.button.abort")
-											}, 1);
-
-									mb.open(null);
-									return mb.waitUntilClosed() == 0;
-								}
-							}, 0);
-				}
-				return allowQuit;
-			}
-		}
-
 		return true;
 	}
 
diff --git a/org/gudy/azureus2/ui/swt/UISwitcherUtil.java b/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
index 2278384..d46f252 100644
--- a/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
+++ b/org/gudy/azureus2/ui/swt/UISwitcherUtil.java
@@ -68,10 +68,6 @@ public class UISwitcherUtil
 	}
 
 	public static String calcUIMode() {
-		if (!isAZ3Avail()) {
-			return "az2";
-		}
-
 		// Can't use Constants.isSafeMode - it's not set by the time we
 		// get here.
 		if ("1".equals(System.getProperty("azureus.safemode"))) {
@@ -181,14 +177,4 @@ public class UISwitcherUtil
 
 		return;
 	}
-
-	public static boolean isAZ3Avail() {
-		Class uiswClass = null;
-		try {
-			uiswClass = Class.forName("com.aelitis.azureus.ui.swt.shells.uiswitcher.UISwitcherWindow");
-			return true;
-		} catch (ClassNotFoundException e1) {
-		}
-		return false;
-	}
 }
diff --git a/org/gudy/azureus2/ui/swt/Utils.java b/org/gudy/azureus2/ui/swt/Utils.java
index cc388d0..0ef5041 100644
--- a/org/gudy/azureus2/ui/swt/Utils.java
+++ b/org/gudy/azureus2/ui/swt/Utils.java
@@ -22,6 +22,7 @@
 package org.gudy.azureus2.ui.swt;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.*;
 import java.util.List;
 
@@ -29,26 +30,38 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.SWTException;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.dnd.*;
-import org.eclipse.swt.events.*;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
 import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.layout.*;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.program.Program;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.download.DownloadManager;
 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.disk.DiskManagerEvent;
+import org.gudy.azureus2.plugins.disk.DiskManagerListener;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
+import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 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.table.*;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableOrTreeUtils;
 
+import com.aelitis.azureus.core.util.GeneralUtils;
+import com.aelitis.azureus.core.util.LaunchManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
@@ -73,7 +86,11 @@ public class Utils
 	public static final boolean LAST_TABLECOLUMN_EXPANDS = isGTK;
 
 	/** GTK already handles alternating background for tables */
-	public static final boolean TABLE_GRIDLINE_IS_ALTERNATING_COLOR = isGTK;
+	public static final boolean TABLE_GRIDLINE_IS_ALTERNATING_COLOR = isGTK || isCocoa;
+	
+	public static int BUTTON_MARGIN;
+
+	public static int BUTTON_MINWIDTH = Constants.isOSX ? 90 : 70;
 
 	/**
 	 * Debug/Diagnose SWT exec calls.  Provides usefull information like how
@@ -99,9 +116,14 @@ public class Utils
 	};
 
 	public static final Rectangle EMPTY_RECT = new Rectangle(0, 0, 0, 0);
+	
+	private static int userMode;
+
+	private static boolean isAZ2;
 
 	static {
 		if (DEBUG_SWTEXEC) {
+			System.out.println("==== debug.swtexec=1, performance may be affected ====");
 			queue = new ArrayList<Runnable>();
 			diag_logger = AEDiagnostics.getLogger("swt");
 			diag_logger.log("\n\nSWT Logging Starts");
@@ -120,12 +142,24 @@ public class Utils
 			queue = null;
 			diag_logger = null;
 		}
+		
+		COConfigurationManager.addAndFireParameterListener("User Mode", new ParameterListener() {
+			public void parameterChanged(String parameterName) {
+				userMode = COConfigurationManager.getIntParameter("User Mode");
+			}
+		});
+		COConfigurationManager.addAndFireParameterListener("ui", new ParameterListener() {
+			public void parameterChanged(String parameterName) {
+				isAZ2 = "az2".equals(COConfigurationManager.getStringParameter("ui"));
+			}
+		});
+		// no need to listen, changing param requires restart
+    boolean smallOSXControl = COConfigurationManager.getBooleanParameter("enable_small_osx_fonts");
+    BUTTON_MARGIN = Constants.isOSX ? (smallOSXControl ? 10 : 12) : 6;
 	}
 
 	public static boolean isAZ2UI() {
-		String ui_type = COConfigurationManager.getStringParameter("ui");
-
-		return (ui_type.equals("az2"));
+		return isAZ2;
 	}
 
 	public static void disposeComposite(Composite composite, boolean disposeSelf) {
@@ -173,11 +207,16 @@ public class Utils
 			return;
 		}
 		for (int i = 0; i < disposeList.length; i++) {
-			Object o = disposeList[i];
-			if (o instanceof Widget && !((Widget) o).isDisposed())
-				((Widget) o).dispose();
-			else if ((o instanceof Resource) && !((Resource) o).isDisposed()) {
-				((Resource) o).dispose();
+			try {
+  			Object o = disposeList[i];
+  			if (o instanceof Widget && !((Widget) o).isDisposed())
+  				((Widget) o).dispose();
+  			else if ((o instanceof Resource) && !((Resource) o).isDisposed()) {
+  				((Resource) o).dispose();
+  			}
+			} catch (Exception e) {
+				Debug.out("Warning: Disposal failed "
+						+ Debug.getCompressedStackTrace(e, 0, -1, true));
 			}
 		}
 	}
@@ -193,8 +232,8 @@ public class Utils
 	 * @author Rene Leonhardt
 	 */
 	public static void setTextLinkFromClipboard(final Shell shell,
-			final Text url, boolean accept_magnets) {
-		String link = getLinkFromClipboard(shell.getDisplay(), accept_magnets);
+			final Text url, boolean accept_magnets, boolean default_magnet ) {
+		String link = getLinkFromClipboard(shell.getDisplay(), accept_magnets, default_magnet );
 		if (link != null)
 			url.setText(link);
 	}
@@ -204,10 +243,10 @@ public class Utils
 	 * <p>The supported protocols currently are http, https, and magnet.</p>
 	 * @param display
 	 * @param accept_magnets 
-	 * @return first valid link from clipboard, else "http://"
+	 * @return first valid link from clipboard, else "http://" or "magnet:"
 	 */
 	public static String getLinkFromClipboard(Display display,
-			boolean accept_magnets) {
+			boolean accept_magnets, boolean default_magnet ) {
 		final Clipboard cb = new Clipboard(display);
 		final TextTransfer transfer = TextTransfer.getInstance();
 
@@ -215,13 +254,17 @@ public class Utils
 
 		String text = UrlUtils.parseTextForURL(data, accept_magnets);
 		if (text == null) {
-			return "http://";
+			return default_magnet?"magnet:":"http://";
 		}
 
 		return text;
 	}
 
 	public static void centreWindow(Shell shell) {
+		centreWindow( shell, true );
+	}
+	
+	public static void centreWindow(Shell shell, boolean shrink_if_needed) {
 		Rectangle displayArea; // area to center in
 		if (shell.getParent() != null) {
 			displayArea = shell.getParent().getBounds();
@@ -235,13 +278,15 @@ public class Utils
 
 		Rectangle shellRect = shell.getBounds();
 
-		if (shellRect.height > displayArea.height) {
-			shellRect.height = displayArea.height;
-		}
-		if (shellRect.width > displayArea.width - 50) {
-			shellRect.width = displayArea.width;
+		if ( shrink_if_needed ){
+			if (shellRect.height > displayArea.height) {
+				shellRect.height = displayArea.height;
+			}
+			if (shellRect.width > displayArea.width - 50) {
+				shellRect.width = displayArea.width;
+			}
 		}
-
+		
 		shellRect.x = displayArea.x + (displayArea.width - shellRect.width) / 2;
 		shellRect.y = displayArea.y + (displayArea.height - shellRect.height) / 2;
 
@@ -255,6 +300,9 @@ public class Utils
 	 */
 	public static void centerWindowRelativeTo(final Shell window,
 			final Control control) {
+		if (control == null || control.isDisposed() || window == null || window.isDisposed()) {
+			return;
+		}
 		final Rectangle bounds = control.getBounds();
 		final Point shellSize = window.getSize();
 		window.setLocation(bounds.x + (bounds.width / 2) - shellSize.x / 2,
@@ -381,6 +429,10 @@ public class Utils
 	}
 
 	public static void alternateRowBackground(TableItem item) {
+		alternateRowBackground(TableOrTreeUtils.getEventItem(item));
+	}
+
+	public static void alternateRowBackground(TableItemOrTreeItem item) {
 		if (Utils.TABLE_GRIDLINE_IS_ALTERNATING_COLOR) {
 			if (!item.getParent().getLinesVisible())
 				item.getParent().setLinesVisible(true);
@@ -413,10 +465,11 @@ public class Utils
 		}
 
 		int iTopIndex = table.getTopIndex();
-		if (iTopIndex < 0) {
+		if (iTopIndex < 0 || (iTopIndex == 0 && table.getItemCount() == 0)) {
 			return;
 		}
-		int iBottomIndex = getTableBottomIndex(table, iTopIndex);
+		TableOrTreeSWT tt = TableOrTreeUtils.getTableOrTreeSWT(table);
+		int iBottomIndex = getTableBottomIndex(tt, iTopIndex);
 
 		Color[] colors = {
 			table.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND),
@@ -424,7 +477,7 @@ public class Utils
 		};
 		int iFixedIndex = iTopIndex;
 		for (int i = iTopIndex; i <= iBottomIndex; i++) {
-			TableItem row = table.getItem(i);
+			TableItemOrTreeItem row = tt.getItem(i);
 			// Rows can be disposed!
 			if (!row.isDisposed()) {
 				Color newColor = colors[iFixedIndex % colors.length];
@@ -532,9 +585,14 @@ public class Utils
 
 		Display display;
 		if (swt == null) {
-			display = Display.getDefault();
-			if (display == null) {
-				System.err.println("SWT Thread not started yet!");
+			try {
+  			display = Display.getDefault();
+  			if (display == null) {
+  				System.err.println("SWT Thread not started yet!");
+  				return null;
+  			}
+			} catch (Throwable t) {
+				// ignore
 				return null;
 			}
 		} else {
@@ -595,6 +653,18 @@ public class Utils
 	 *
 	 * @since 3.0.4.3
 	 */
+	
+	public static boolean
+	isSWTThread()
+	{
+		final Display display = getDisplay();
+		if (display == null ){
+			return false;
+		}
+
+		return( display.getThread() == Thread.currentThread());
+	}
+	
 	private static boolean execSWTThread(final Runnable code, final int msLater) {
 		final Display display = getDisplay();
 		if (display == null || code == null) {
@@ -613,7 +683,7 @@ public class Utils
 				long wait = SystemTime.getCurrentTime() - lStartTimeRun;
 				if (wait > 700) {
 					diag_logger.log(SystemTime.getCurrentTime() + "] took " + wait
-							+ "ms to run " + Debug.getCompressedStackTrace());
+							+ "ms to run " + Debug.getCompressedStackTrace(-5));
 				}
 			}
 		} else if (msLater >= -1) {
@@ -640,11 +710,11 @@ public class Utils
 
 					diag_logger.log(SystemTime.getCurrentTime() + "] + Q. size= "
 							+ queue.size() + "; add " + code + " via "
-							+ Debug.getCompressedStackTrace());
+							+ Debug.getCompressedStackTrace(-5));
 					final long lStart = SystemTime.getCurrentTime();
 
 					final Display fDisplay = display;
-					AERunnable runnableWrapper = new AERunnable() {
+					final AERunnable runnableWrapper = new AERunnable() {
 						public void runSupport() {
 							long wait = SystemTime.getCurrentTime() - lStart - msLater;
 							if (wait > 700) {
@@ -691,13 +761,13 @@ public class Utils
 						display.asyncExec(runnableWrapper);
 					} else {
 						if(isSWTThread) {
-							display.timerExec(msLater, code);
+							display.timerExec(msLater, runnableWrapper);
 						} else {
   						SimpleTimer.addEvent("execSWTThreadLater",
   								SystemTime.getOffsetTime(msLater), new TimerEventPerformer() {
   									public void perform(TimerEvent event) {
   										if (!display.isDisposed()) {
-  											display.asyncExec(code);
+  											display.asyncExec(runnableWrapper);
   										}
   									}
   								});
@@ -735,7 +805,7 @@ public class Utils
 		SWTThread swt = SWTThread.getInstance();
 
 		if (swt == null) {
-			System.err.println("WARNING: SWT Thread not started yet");
+			//System.err.println("WARNING: SWT Thread not started yet");
 		}
 
 		Display display = (swt == null) ? Display.getCurrent() : swt.getDisplay();
@@ -759,55 +829,130 @@ public class Utils
 	/**
 	 * Bottom Index may be negative. Returns bottom index even if invisible.
 	 */
-	public static int getTableBottomIndex(Table table, int iTopIndex) {
-		// on Linux, getItemHeight is slow AND WRONG. so is getItem(x).getBounds().y 
-		// getItem(Point) is slow on OSX
-		
-		// On Windows, in rare cases, getItem(Point(2,y)) doesn't return the item
-		// (such as within a paint event)
+	public static int getTableBottomIndex(TableOrTreeSWT table, int iTopIndex) {
 
-		int itemCount = table.getItemCount();
-		if (iTopIndex >= itemCount || iTopIndex < 0)
+		// Shortcut: if lastBottomIndex is present, assume it's accurate
+		Object lastBottomIndex = table.getData("lastBottomIndex");
+		if (lastBottomIndex instanceof Number) {
+			return ((Number)lastBottomIndex).intValue();
+		}
+		
+		int columnCount = table.getColumnCount();
+		if (columnCount == 0) {
 			return -1;
+		}
+		int xPos = table.getColumn(0).getWidth() - 1;
+		if (columnCount > 1) {
+			xPos += table.getColumn(1).getWidth();
+		}
 
-		if (Constants.isOSX || Constants.isWindows) {
-			try {
-				TableItem item = table.getItem(iTopIndex);
-				Rectangle bounds = item.getBounds();
-				Rectangle clientArea = table.getClientArea();
-
-				int itemHeight = table.getItemHeight();
-				int iBottomIndex = Math.min(iTopIndex
-						+ (clientArea.height + clientArea.y - bounds.y - 1) / itemHeight,
-						itemCount - 1);
-
-				//			System.out.println(bounds + ";" + clientArea + ";" + itemHeight + ";bi="
-				//					+ iBottomIndex + ";ti=" + iTopIndex + ";"
-				//					+ (clientArea.height + clientArea.y - bounds.y - 1));
-				return iBottomIndex;
-			} catch (NoSuchMethodError e) {
-				// item.getBounds is 3.2
-				return Math.min(
-						iTopIndex
-								+ ((table.getClientArea().height - table.getHeaderHeight() - 1) / table.getItemHeight())
-								+ 1, table.getItemCount() - 1);
-			}
-		}
-
-		// getItem will return null if clientArea's height is smaller than
-		// header height.
-		int areaHeight = table.getClientArea().height;
-		if (areaHeight <= table.getHeaderHeight())
-			return -1;
+		Rectangle clientArea = table.getClientArea();
+		TableItemOrTreeItem bottomItem = table.getItem(new Point(xPos,
+				clientArea.y + clientArea.height - 2));
+		if (bottomItem != null) {
+			while (bottomItem.getParentItem() != null) {
+				bottomItem = bottomItem.getParentItem();
+			}
+			return table.indexOf(bottomItem);
+		}
+		return table.getItemCount() - 1;
+	}
+	
+	public static List<TableItemOrTreeItem> getVisibleTableItems(TableOrTreeSWT table) {
 
-		// 2 offset to be on the safe side
-		TableItem bottomItem = table.getItem(new Point(2,
-				table.getClientArea().height - 1));
-		int iBottomIndex = (bottomItem != null) ? table.indexOf(bottomItem)
-				: itemCount - 1;
-		return iBottomIndex;
+		if (table.getColumnCount() < 2) {
+			return Collections.emptyList();
+		}
+
+		int xPos = table.getColumn(0).getWidth() + table.getColumn(1).getWidth() - 1;
+
+		Rectangle clientArea = table.getClientArea();
+		TableItemOrTreeItem bottomItem = table.getItem(new Point(xPos,
+				clientArea.y + clientArea.height - 1));
+		if (bottomItem == null) {
+			if (clientArea.height + clientArea.y <= 0) {
+				return Collections.emptyList();
+			}
+		}
+
+		TableItemOrTreeItem curItem = table.getTopItem();
+		if (curItem == null) {
+			if (table.getItemCount() > 0) {
+				// BUG in GTK: topitem of tree will be null after setItemCount
+				curItem = table.getItem(0);
+			} else {
+				return Collections.emptyList();
+			}
+		}
+		List<TableItemOrTreeItem> items = new ArrayList<TableItemOrTreeItem>();
+		int i = table.indexOf(curItem);
+		int count = table.getItemCount();
+		while (true) {
+			if (curItem == bottomItem) {
+				items.add(curItem);
+				break;
+			} else if (curItem == null) {
+				break;
+			}
+			items.add(curItem);
+			if (curItem.getExpanded() && curItem.getItemCount() > 0) {
+				if (!addItemsToList(items, curItem.getItems(), bottomItem)) {
+					break;
+				}
+			}
+			i++;
+			if (i >= count) {
+				break;
+			}
+			curItem = table.getItem(i);
+		}
+		return items;
+	}
+
+	private static boolean addItemsToList(List<TableItemOrTreeItem> list, TableItemOrTreeItem[] items,
+			TableItemOrTreeItem stopOnItem) {
+		
+		for (TableItemOrTreeItem item : items) {
+			list.add(item);
+			if (item == stopOnItem) {
+				return false;
+			}
+		}
+		return true;
 	}
 
+	public static void launch( final DiskManagerFileInfo fileInfo ){
+		LaunchManager	launch_manager = LaunchManager.getManager();
+		
+		LaunchManager.LaunchTarget target = launch_manager.createTarget( fileInfo );
+		
+		launch_manager.launchRequest(
+			target,
+			new LaunchManager.LaunchAction()
+			{
+				public void
+				actionAllowed()
+				{
+					Utils.execSWTThread(
+						new Runnable()
+						{
+							public void
+							run()
+							{
+								launch(fileInfo.getFile(true).toString());
+							}
+						});
+				}
+				
+				public void
+				actionDenied(
+					Throwable			reason )
+				{
+					Debug.out( "Launch request denied", reason );
+				}
+			});
+		
+	}
 	public static void launch(String sFile) {
 		if (sFile == null || sFile.trim().length() == 0) {
 			return;
@@ -824,10 +969,74 @@ public class Utils
 			}
 		}
 
+		sFile = sFile.replaceAll( "&vzemb=1", "" );
+
+		int	pos = sFile.lastIndexOf( "." );
+		
+		if ( pos >= 0 ){
+			
+			String	ext = sFile.substring( pos+1 ).toLowerCase().trim();
+			
+			for ( int i=0;i<10;i++){
+				
+				String exts = COConfigurationManager.getStringParameter( "Table.lh" + i + ".exts", "" ).trim();
+				String exe 	= COConfigurationManager.getStringParameter( "Table.lh" + i + ".prog", "" ).trim();
+				
+				if ( exts.length() > 0 && exe.length() > 0 && new File( exe ).exists()){
+			
+					exts = "," + exts.toLowerCase();
+					
+					exts = exts.replaceAll( "\\.", "," );
+					exts = exts.replaceAll( ";", "," );
+					exts = exts.replaceAll( " ", "," );
+					
+					exts = exts.replaceAll( "[,]+", "," );
+					
+					File	file = new File( sFile );
+					
+					if ( exts.contains( ","+ext )){
+					
+						try{
+							System.out.println( "Launching " + sFile + " with " + exe );
+							
+							if ( Constants.isWindows ){
+								
+									// need to use createProcess as we want to force the process to decouple correctly (otherwise Vuze won't close until the child closes)
+								
+								try{
+									PlatformManagerFactory.getPlatformManager().createProcess( exe + " \"" + sFile + "\"", false );
+								
+									return;
+									
+								}catch( Throwable e ){
+								}
+							}
+							
+							ProcessBuilder pb = GeneralUtils.createProcessBuilder( file.getParentFile(), new String[]{ exe, file.getName()}, null );
+							
+							pb.start();
+							
+							return;
+							
+						}catch( Throwable e ){
+							
+							Debug.out( "Launch failed", e );
+						}
+					}
+				}
+			}
+		}
+			
 		boolean launched = Program.launch(sFile);
 		if (!launched && Constants.isUnix) {
+			
+			sFile = sFile.replaceAll( " ", "\\ " );
+			
 			if (!Program.launch("xdg-open " + sFile)) {
-				Program.launch("htmlview " + sFile);
+				if ( !Program.launch("htmlview " + sFile)){
+					
+					Debug.out( "Failed to launch '" + sFile + "'" );
+				}
 			}
 		}
 	}
@@ -875,9 +1084,11 @@ public class Utils
 				if (i == 4) {
 					Rectangle shellBounds = new Rectangle(values[0], values[1],
 							values[2], values[3]);
-					shell.setBounds(shellBounds);
-					verifyShellRect(shell, true);
-					bDidResize = true;
+					if (shellBounds.width > 100 && shellBounds.height > 50) {
+  					shell.setBounds(shellBounds);
+  					verifyShellRect(shell, true);
+  					bDidResize = true;
+					}
 				}
 			} catch (Exception e) {
 			}
@@ -1032,6 +1243,48 @@ public class Utils
 		return true;
 	}
 
+	public static Control
+	findChild(
+		Composite	comp,
+		int			x,
+		int			y )
+	{
+		Rectangle comp_bounds = comp.getBounds();
+		
+		if ( comp.isVisible() && comp_bounds.contains( x, y )){
+								
+			x -= comp_bounds.x;
+			y -= comp_bounds.y;
+			
+			Control[] children = comp.getChildren();
+			
+			for ( int i = 0; i < children.length; i++){
+				
+				Control child = children[i];
+				
+				if ( child.isVisible()){
+					
+					if (child instanceof Composite) {
+						
+						Control res = findChild((Composite) child, x, y );
+						
+						if ( res != null ){
+							
+							return( res );
+						}
+					}else{
+						
+						return( child );
+					}
+				}
+			}
+			
+			return( comp );
+		}
+		
+		return( null );
+	}
+	
 	/**
 	 * @param area
 	 * @param event id
@@ -1188,154 +1441,6 @@ public class Utils
 	}
 
 	/**
-	 * 
-	 * @param baseFont
-	 * @param gc Can be null
-	 * @param heightInPixels
-	 * @return
-	 *
-	 * @since 3.0.0.7
-	 */
-	public static int getFontHeightFromPX(Font baseFont, GC gc, int heightInPixels) {
-		Font font = null;
-		Device device = baseFont.getDevice();
-
-		// hack..
-		heightInPixels++;
-
-		// This isn't accurate, but gets us close
-		int size = Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1;
-		if (size <= 0) {
-			return 0;
-		}
-
-		boolean bOurGC = gc == null || gc.isDisposed();
-		try {
-			if (bOurGC) {
-				gc = new GC(device);
-			}
-			FontData[] fontData = baseFont.getFontData();
-
-			do {
-				if (font != null) {
-					size--;
-					font.dispose();
-				}
-				fontData[0].setHeight(size);
-
-				font = new Font(device, fontData);
-
-				gc.setFont(font);
-
-			} while (gc.textExtent(GOOD_STRING).y > heightInPixels && size > 1);
-
-		} finally {
-			if (bOurGC) {
-				gc.dispose();
-			}
-			if (font != null && !font.isDisposed()) {
-				font.dispose();
-			}
-		}
-		return size;
-	}
-
-	public static int getFontHeightFromPX(Device device, FontData[] fontData,
-			GC gc, int heightInPixels) {
-		Font font = null;
-
-		// hack..
-		heightInPixels++;
-
-		// This isn't accurate, but gets us close
-		int size = Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1;
-		if (size <= 0) {
-			return 0;
-		}
-
-		boolean bOurGC = gc == null || gc.isDisposed();
-		try {
-			if (bOurGC) {
-				gc = new GC(device);
-			}
-
-			do {
-				if (font != null) {
-					size--;
-					font.dispose();
-				}
-				fontData[0].setHeight(size);
-
-				font = new Font(device, fontData);
-
-				gc.setFont(font);
-
-			} while (font != null && gc.textExtent(GOOD_STRING).y > heightInPixels
-					&& size > 1);
-
-		} finally {
-			if (bOurGC) {
-				gc.dispose();
-			}
-			if (font != null && !font.isDisposed()) {
-				font.dispose();
-			}
-		}
-		return size;
-	}
-
-	public static Font getFontWithHeight(Font baseFont, GC gc, int heightInPixels) {
-		return getFontWithHeight(baseFont, gc, heightInPixels, SWT.DEFAULT);
-	}
-
-	public static Font getFontWithHeight(Font baseFont, GC gc,
-			int heightInPixels, int style) {
-		Font font = null;
-		Device device = baseFont.getDevice();
-
-		// hack..
-		heightInPixels++;
-
-		// This isn't accurate, but gets us close
-		int size = Utils.pixelsToPoint(heightInPixels, device.getDPI().y) + 1;
-		if (size <= 0) {
-			size = 2;
-		}
-
-		boolean bOurGC = gc == null || gc.isDisposed();
-		try {
-			if (bOurGC) {
-				gc = new GC(device);
-			}
-			FontData[] fontData = baseFont.getFontData();
-
-			do {
-				if (font != null) {
-					size--;
-					font.dispose();
-				}
-				fontData[0].setHeight(size);
-				if (style != SWT.DEFAULT) {
-					fontData[0].setStyle(style);
-				}
-
-				font = new Font(device, fontData);
-
-				gc.setFont(font);
-
-			} while (font != null && gc.textExtent(GOOD_STRING).y > heightInPixels
-					&& size > 1);
-
-		} finally {
-			if (bOurGC) {
-				gc.dispose();
-			}
-		}
-
-		return font;
-	}
-
-	/**
 	 * @deprecated Use {@link #execSWTThread(AERunnableWithCallback)} to avoid
 	 *             thread locking issues
 	 */
@@ -1455,12 +1560,15 @@ public class Utils
 			}
 		} catch (Throwable e) {
 			if (sem != null) {
-				sem.release();
+				sem.releaseForever();
 			}
 			Debug.out(ID, e);
 		}
 		if (sem != null) {
-			sem.reserve(millis);
+			if (!sem.reserve(millis) && DEBUG_SWTEXEC) {
+				System.out.println("Timeout in execSWTThreadWithObject(" + ID + ", "
+						+ code + ", " + millis + ") via " + Debug.getCompressedStackTrace());
+			}
 		}
 
 		return returnValueObject[0];
@@ -1531,6 +1639,9 @@ public class Utils
 				0xFF, 0xFF00, 0xFF0000));
 		Arrays.fill(imageData.data, 0, imageData.data.length, (byte) 0);
 		imageData.alphaData = alphaData;
+		if (device == null) {
+			device = Display.getDefault();
+		}
 		Image image = new Image(device, imageData);
 		return image;
 	}
@@ -1911,180 +2022,9 @@ public class Utils
 		return style | browserStyle;
 	}
 
-	/**
-	 * Change the height of the installed <code>Font</code> and takes care of disposing
-	 * the new font when the control is disposed
-	 * @param control
-	 * @param height
-	 * @param style one or both of SWT.BOLD, SWT.ITALIC, or SWT.NORMAL
-	 */
-	public static void setFontHeight(Control control, int height, int style) {
-		FontData[] fDatas = control.getFont().getFontData();
-		for (int i = 0; i < fDatas.length; i++) {
-			fDatas[i].height = height;
-			fDatas[i].setStyle(style);
-		}
-		final Font newFont = new Font(control.getDisplay(), fDatas);
-		control.setFont(newFont);
-		control.addDisposeListener(new DisposeListener() {
-
-			public void widgetDisposed(DisposeEvent e) {
-				if (null != newFont && false == newFont.isDisposed()) {
-					newFont.dispose();
-				}
-			}
-		});
-	}
-	
-	public static final long IMMEDIATE_ADDREMOVE_DELAY = 150;
-
-	private static final long IMMEDIATE_ADDREMOVE_MAXDELAY = 2000;
-
-	private static Timer timerProcessDataSources = new Timer("Process Data Sources");
-
-	private static TimerEvent timerEventProcessDS;
-
-	private static List processDataSourcesOutstanding = new ArrayList();
-	
-
-	public static boolean
-	addDataSourceAggregated(
-		addDataSourceCallback		callback )
-	{
-		if ( callback == null ){
-			
-			return( true );
-		}
-		
-		boolean processQueueImmediately = false;
-		
-		List	to_do_now = null;
-		
-		synchronized( timerProcessDataSources ){
-						
-			if ( timerEventProcessDS != null && !timerEventProcessDS.hasRun()){
-				
-					// Push timer forward, unless we've pushed it forward for over x seconds
-				
-				long now = SystemTime.getCurrentTime();
-				
-				if (now - timerEventProcessDS.getCreatedTime() < IMMEDIATE_ADDREMOVE_MAXDELAY) {
-					
-					long lNextTime = now + IMMEDIATE_ADDREMOVE_DELAY;
-										
-					timerProcessDataSources.adjustAllBy( lNextTime - timerEventProcessDS.getWhen());
-					
-					if ( !processDataSourcesOutstanding.contains( callback )){
-						
-						processDataSourcesOutstanding.add( callback );
-					}
-				}else{
-										
-					timerEventProcessDS.cancel();
-					
-					timerEventProcessDS = null;
-
-					processQueueImmediately = true;
-					
-					to_do_now = processDataSourcesOutstanding;
-					
-					processDataSourcesOutstanding = new ArrayList();
-				}
-			}else{
-				
-				if ( !processDataSourcesOutstanding.contains( callback )){
-					
-					processDataSourcesOutstanding.add( callback );
-				}
-
-				timerEventProcessDS = 
-					timerProcessDataSources.addEvent(
-						SystemTime.getCurrentTime() + IMMEDIATE_ADDREMOVE_DELAY,
-						new TimerEventPerformer() 
-						{
-							public void 
-							perform(
-								TimerEvent event ) 
-							{
-								List	to_do;
-																
-								synchronized( timerProcessDataSources ){
-								
-									timerEventProcessDS = null;
-
-									to_do = processDataSourcesOutstanding;
-									
-									processDataSourcesOutstanding = new ArrayList();
-								}
-								
-								for (int i=0;i<to_do.size();i++){
-									
-									try{
-										
-										addDataSourceCallback this_callback = (addDataSourceCallback)to_do.get(i);
-														
-										if (TableViewSWT.DEBUGADDREMOVE ) {
-											this_callback.debug("processDataSourceQueue after "
-													+ (SystemTime.getCurrentTime() - event.getCreatedTime())
-													+ "ms");
-										}
-										
-										this_callback.process();
-										
-									}catch( Throwable e ){
-										
-										Debug.printStackTrace(e);
-									}
-								}
-							}
-						});
-			}
-			
-			if ( to_do_now != null ){
-								
-					// process outside the synchronized block, otherwise we'll end up with deadlocks
-
-				to_do_now.remove( callback );
-				
-				for (int i=0;i<to_do_now.size();i++){
-					
-					try{
-						
-						addDataSourceCallback this_callback = (addDataSourceCallback)to_do_now.get(i);
-
-						if ( TableViewSWT.DEBUGADDREMOVE ){
-							
-							this_callback.debug("Over immediate delay limit, processing queue now");
-						}
-						
-						this_callback.process();
-						
-					}catch( Throwable e ){
-						
-						Debug.printStackTrace(e);
-					}
-				}
-			}
-		}
-		
-		return( processQueueImmediately );
-	}
-	
-	public interface
-	addDataSourceCallback
-	{
-		public void
-		process();
-		
-		public void
-		debug(
-			String		str );
-	}
-	
-	
 	private static Map truncatedTextCache = new HashMap();
 
-	private static ThreadPool tp = new ThreadPool("GetOffSWT", 2);
+	private static ThreadPool tp = new ThreadPool("GetOffSWT", 3, true);
 	
 	private static class TruncatedTextResult {
 		String text;
@@ -2212,4 +2152,536 @@ public class Utils
 		}
 		return null;
 	}
+	
+	public static int getUserMode() {
+		return userMode;
+	}
+	
+	public static Point getLocationRelativeToShell(Control control) {
+		Point controlLocation = control.toDisplay(0, 0);
+		Point shellLocation = control.getShell().getLocation();
+		return new Point(controlLocation.x - shellLocation.x, controlLocation.y - shellLocation.y);
+	}
+	
+	private static Set<String>	qv_exts = new HashSet<String>();
+	private static int			qv_max_bytes;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{ "quick.view.exts", "quick.view.maxkb" },
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String name ) 
+				{
+					String	exts_str 	= COConfigurationManager.getStringParameter( "quick.view.exts" );
+					int		max_bytes	= COConfigurationManager.getIntParameter( "quick.view.maxkb" )*1024;
+					
+					String[]	bits = exts_str.split( "[;, ]");
+					
+					Set<String>	exts = new HashSet<String>();
+					
+					for ( String bit: bits ){
+						
+						bit = bit.trim();
+						
+						if ( bit.startsWith( "." )){
+							
+							bit = bit.substring(1);
+						}
+						
+						if ( bit.length() > 0 ){
+							
+							exts.add( bit.toLowerCase());
+						}
+					}
+					
+					qv_exts 		= exts;
+					qv_max_bytes	= max_bytes;
+				}
+			});
+	}
+
+	private static Set<DiskManagerFileInfo>	quick_view_active = new HashSet<DiskManagerFileInfo>();
+	private static TimerEventPeriodic		quick_view_event;
+	
+	public static boolean
+	isQuickViewSupported(
+		DiskManagerFileInfo	file )
+	{
+		String ext = file.getExtension().toLowerCase();
+		
+		if ( ext.startsWith( "." )){
+			
+			ext = ext.substring(1);
+		}
+		
+			// always support .rar
+		
+		if ( ext.equals( "rar" )){
+			
+			return( true );
+		}
+		
+		if ( qv_exts.contains( ext )){
+			
+			if ( file.getLength() <= qv_max_bytes ){	
+			
+				return( true );
+			}
+		}
+				
+		return( false );
+	}
+	
+	public static boolean
+	isQuickViewActive(
+		DiskManagerFileInfo	file )
+	{
+		synchronized( quick_view_active ){
+		
+			return( quick_view_active.contains( file ));
+		}
+	}
+	
+	public static void
+	setQuickViewActive(
+		DiskManagerFileInfo	file,
+		boolean				active )
+	{
+		synchronized( quick_view_active ){
+
+			if ( !active ){
+				
+				quick_view_active.remove( file );
+				
+				return;
+			}
+			
+			if ( quick_view_active.contains( file )){
+					
+				return;
+			}
+	
+			String ext = file.getExtension().toLowerCase();
+
+			boolean	file_complete = file.getDownloaded() == file.getLength();
+			
+			if ( ext.equals( ".rar" )){
+				
+				quick_view_active.add( file );
+				
+				quickViewRAR( file );
+								
+			}else{
+				
+				if ( file_complete ){
+					
+					quickView( file );
+					
+				}else{
+				
+					quick_view_active.add( file );
+					
+					file.setPriority( 1 );
+					
+					DiskManagerFileInfo[] all_files = file.getDownloadManager().getDiskManagerFileInfoSet().getFiles();
+					
+					for ( DiskManagerFileInfo f: all_files ){
+						
+						if ( !quick_view_active.contains( f )){
+							
+							f.setPriority( 0 );
+						}
+					}
+					
+					if ( quick_view_event == null ){
+						
+						quick_view_event = 
+							SimpleTimer.addPeriodicEvent(
+								"qv_checker",
+								5*1000,
+								new TimerEventPerformer()
+								{
+									public void 
+									perform(
+										TimerEvent event) 
+									{
+										synchronized( quick_view_active ){
+											
+											Iterator<DiskManagerFileInfo> it = quick_view_active.iterator();
+											
+											while( it.hasNext()){
+												
+												DiskManagerFileInfo file = it.next();
+												
+												if ( file.getDownloadManager().isDestroyed()){
+													
+													it.remove();
+													
+												}else{
+													
+													if ( file.getDownloaded() == file.getLength()){
+														
+														quickView( file );
+														
+														it.remove();
+													}
+												}
+											}
+											
+											if ( quick_view_active.isEmpty()){
+												
+												quick_view_event.cancel();
+												
+												quick_view_event = null;
+											}
+										}
+									}
+								});
+					}
+				}
+			}
+			
+			if ( !file_complete ){
+				
+				execSWTThreadLater(
+					10,
+					new Runnable()
+					{
+						public void
+						run()
+						{
+							MessageBoxShell mb = 
+								new MessageBoxShell(
+										SWT.OK,
+										MessageText.getString("quick.view.scheduled.title"),
+										MessageText.getString("quick.view.scheduled.text"));
+	
+							mb.setDefaultButtonUsingStyle(SWT.OK);
+							mb.setRemember("quick.view.inform.activated.id", false, MessageText.getString( "label.dont.show.again" ));
+							mb.setLeftImage(SWT.ICON_INFORMATION);
+							mb.open(null);
+						}
+					});
+			}
+		}
+	}
+	
+	private static void
+	quickView(
+		final DiskManagerFileInfo		file )
+	{
+		try{
+			final File		target_file = file.getFile( true );
+			
+			final String contents = FileUtil.readFileAsString( target_file, qv_max_bytes );
+			
+			execSWTThread(
+				new Runnable()
+				{
+					public void
+					run()
+					{
+						DownloadManager dm = file.getDownloadManager();
+						
+						new TextViewerWindow(
+								MessageText.getString( "MainWindow.menu.quick_view" ) + ": " + target_file.getName(),
+								MessageText.getString( 
+									"MainWindow.menu.quick_view.msg",
+									new String[]{ target_file.getName(), dm.getDisplayName() }),
+								contents, false  );
+					}
+				});
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	private static void
+	quickViewRAR(
+		final DiskManagerFileInfo		file )
+	{
+		boolean went_async = false;
+		
+		try{
+			final org.gudy.azureus2.plugins.disk.DiskManagerFileInfo plugin_file =  PluginCoreUtils.wrap( file );
+			
+			final RARTOCDecoder decoder = 
+				new RARTOCDecoder(
+					new RARTOCDecoder.DataProvider()
+					{
+						private long	file_position;
+						private long	file_size = file.getLength();
+						
+						public int
+						read(
+							final byte[]		buffer )
+						
+							throws IOException
+						{
+							long	read_from 	= file_position;
+							int		read_length	= buffer.length;
+														
+							long	read_to = Math.min( file_size, read_from + read_length );
+							
+							read_length = (int)( read_to - read_from );
+							
+							if ( read_length <= 0 ){
+								
+								return( -1 );
+							}
+								
+							final int f_read_length = read_length;
+							
+							try{
+								final AESemaphore sem = new AESemaphore( "rarwait" );
+								
+								final Object[] result = { null };
+
+								plugin_file.createRandomReadRequest(
+									read_from, read_length, false,
+									new DiskManagerListener()
+									{
+										private int	buffer_pos;
+										
+										public void
+										eventOccurred(
+											DiskManagerEvent	event )
+										{
+											int	event_type = event.getType();
+											
+											if ( event_type == DiskManagerEvent.EVENT_TYPE_SUCCESS ){
+																								
+												PooledByteBuffer pooled_buffer = event.getBuffer();
+												
+												try{
+													byte[] data = pooled_buffer.toByteArray();
+													
+													System.arraycopy( data, 0, buffer, buffer_pos, data.length );
+													
+													buffer_pos += data.length;
+													
+													if ( buffer_pos == f_read_length ){
+														
+														sem.release();
+													}
+													
+												}finally{
+													
+													pooled_buffer.returnToPool();
+												}
+											}else if ( event_type == DiskManagerEvent.EVENT_TYPE_FAILED ){
+												
+												result[0] = event.getFailure();
+												
+												sem.release();
+											}
+										}
+									});
+								
+								sem.reserve();
+								
+								if ( result[0] instanceof Throwable ){
+									
+									throw((Throwable)result[0]);
+								}
+								
+								file_position += read_length;
+								
+								return( read_length );
+								
+							}catch( Throwable e ){
+								
+								throw( new IOException( "read failed: " + Debug.getNestedExceptionMessage( e )));
+							}
+						}
+						
+						public void
+						skip(
+							long		bytes )
+						
+							throws IOException
+						{
+							file_position += bytes;
+						}
+					});
+			
+			new AEThread2( "rardecoder" )
+			{
+				public void
+				run()
+				{
+					try{
+						decoder.analyse(
+							new RARTOCDecoder.TOCResultHandler()
+							{
+								private TextViewerWindow	viewer;
+								private List<String>		lines = new ArrayList<String>();
+								
+								private int	pw_entries 	= 0;
+								private int pw_text		= 0;
+								
+								private volatile boolean	abandon = false;
+								
+								public void
+								entryRead(
+									final String 		name, 
+									final long 			size,
+									final boolean 		password ) 
+								
+									throws IOException
+								{
+									if ( abandon ){
+										
+										throw( new IOException( "Operation abandoned" ));
+									}
+									
+									String line = name + ":    " + DisplayFormatters.formatByteCountToKiBEtc( size );
+									
+									if ( password ){
+										
+										line += "    **** password protected ****";
+										
+										pw_entries++;
+									}
+
+									if ( password || name.toLowerCase().contains( "password" )){
+										
+										line = "*\t" + line;
+										
+										pw_text++;
+										
+									}else{
+										
+										line = " \t" + line;
+									}
+									
+									appendLine( line, false );
+								}
+								
+								public void
+								complete()
+								{									
+									appendLine( "Done", true );
+								}
+								
+								public void
+								failed(
+									IOException error )
+								{
+									appendLine( "Failed: " + Debug.getNestedExceptionMessage( error ), true );
+								}
+								
+								private String
+								getInfo()
+								{
+									if ( pw_entries > 0 ){
+										
+										return( pw_entries + " password protected file(s) found" );
+										
+									}else if ( pw_text > 0 ){
+										
+										return( pw_text + " file(s) mentioning 'password' found" );
+									}
+									
+									return( "" );
+								}
+								
+								private void
+								appendLine(
+									final String	line,
+									final boolean	complete )
+								{
+									execSWTThread(
+										new Runnable()
+										{
+											public void
+											run()
+											{												
+												lines.add( line );
+												
+												StringBuffer	content = new StringBuffer();
+												
+												for ( String l: lines ){
+													
+													content.append( l + "\r\n" );
+												}
+												
+												if ( !complete ){
+												
+													content.append( "processing..." );
+													
+												}else{
+													
+													String info = getInfo();
+													
+													if ( info.length() > 0 ){
+														
+														content.append( info + "\r\n" );
+													}
+												}
+												
+												if ( viewer == null ){
+													
+													final File		target_file = file.getFile( true );
+													
+													DownloadManager dm = file.getDownloadManager();
+												
+													viewer = new TextViewerWindow(
+														MessageText.getString( "MainWindow.menu.quick_view" ) + ": " + target_file.getName(),
+														MessageText.getString( 
+															"MainWindow.menu.quick_view.msg",
+															new String[]{ target_file.getName(), dm.getDisplayName() }),
+														content.toString(), false  );
+													
+												}else{
+													
+													if ( viewer.isDisposed()){
+													
+														abandon = true;
+														
+													}else{
+														
+														viewer.setText( content.toString());
+													}
+												}
+											}
+										});
+								}
+								
+							});
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+						
+					}finally{
+						
+						synchronized( quick_view_active ){
+
+							quick_view_active.remove( file );
+						}
+					}
+				}
+			}.start();
+			
+			went_async = true;
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+		}finally{
+			
+			if ( !went_async ){
+				
+				synchronized( quick_view_active ){
+
+					quick_view_active.remove( file );
+				}
+			}
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/about.properties b/org/gudy/azureus2/ui/swt/about.properties
index 803694e..ae66a4e 100644
--- a/org/gudy/azureus2/ui/swt/about.properties
+++ b/org/gudy/azureus2/ui/swt/about.properties
@@ -24,4 +24,5 @@ translators=Mika Vainikka\n\
 	Ondrej Zarevucky\n\
 	Andreas Rudisch\n\
 	Jeroen Zuiddam\n\
+	GamBIT\n\
 	...And many others\n\
diff --git a/org/gudy/azureus2/ui/swt/animations/Animator.java b/org/gudy/azureus2/ui/swt/animations/Animator.java
deleted file mode 100644
index f42cd1a..0000000
--- a/org/gudy/azureus2/ui/swt/animations/Animator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * File    : Animator.java
- * Created : 14 mars 2004
- * By      : Olivier
- * 
- * 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.swt.animations;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-
-import org.gudy.azureus2.core3.util.AEThread;
-
-public abstract class Animator extends AEThread {  
-  public abstract void interrupt();
-  
-  public Animator(String name) {
-    super(name);
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/animations/shell/AnimableShell.java b/org/gudy/azureus2/ui/swt/animations/shell/AnimableShell.java
deleted file mode 100644
index 338f2fe..0000000
--- a/org/gudy/azureus2/ui/swt/animations/shell/AnimableShell.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * File    : AnimableShell.java
- * Created : 14 mars 2004
- * By      : Olivier
- * 
- * 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.swt.animations.shell;
-
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.ui.swt.animations.Animator;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public interface AnimableShell {
-  
-  public Shell getShell();
-  
-  public void animationStarted(Animator source);
-  public void reportPercent(int percent);
-  public void animationEnded(Animator source);
-    
-}
diff --git a/org/gudy/azureus2/ui/swt/animations/shell/LinearAnimator.java b/org/gudy/azureus2/ui/swt/animations/shell/LinearAnimator.java
deleted file mode 100644
index cccf46a..0000000
--- a/org/gudy/azureus2/ui/swt/animations/shell/LinearAnimator.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * File    : LinearAnimator.java
- * Created : 14 mars 2004
- * By      : Olivier
- * 
- * 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.swt.animations.shell;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Display;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.animations.Animator;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class LinearAnimator extends Animator{
-  
-  private AnimableShell shell;
-  private Display display;
-  
-  private int startX;
-  private int startY;
-  
-  private int endX;
-  private int endY;
-  
-  private int nbSteps;
-  private int period;
-  
-  private boolean interrupted;
-  
-  public LinearAnimator(AnimableShell shell,Point start,Point end,int nbSteps,int period) {
-    super("Linear Shell Animator");
-    if(period < 20) period = 20;
-    if(nbSteps <= 0) nbSteps = 1;
-    this.shell = shell;
-    this.display = shell.getShell().getDisplay();
-    
-    this.startX = start.x;
-    this.startY = start.y;
-    
-    this.endX = end.x;
-    this.endY = end.y;
-    
-    this.nbSteps = nbSteps;
-    this.period = period;    
-    
-    this.interrupted = false;
-  }
-  
-  public void runSupport() {
-  	try {
-	    shell.animationStarted(this);
-	    int step = 0;
-	    while(step <= nbSteps && !interrupted) {
-	      setShellAtStep(step);
-	      shell.reportPercent(100 * step  /nbSteps);
-	      step++;
-	      try {
-	        Thread.sleep(period);
-	      } catch(Exception e) {
-	        //Stop animating
-	        step = nbSteps;
-	      }
-	    }
-  	} finally {
-  		shell.animationEnded(this);
-  	}
-  }
-  
-  public void interrupt() {
-    this.interrupted = true;
-  }
-  
-  private void setShellAtStep(int step) {
-    if(display == null || display.isDisposed())
-      return;
-    final int x = startX + ((endX - startX) * step ) / nbSteps;
-    final int y = startY + ((endY - startY) * step ) / nbSteps;
-    display.asyncExec(new AERunnable() {
-      public void runSupport() {
-        if(shell == null || shell.getShell() == null || shell.getShell().isDisposed())
-          return;
-        shell.getShell().setLocation(x,y);
-      }    
-    });
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/animations/shell/TestWindow.java b/org/gudy/azureus2/ui/swt/animations/shell/TestWindow.java
deleted file mode 100644
index a719c74..0000000
--- a/org/gudy/azureus2/ui/swt/animations/shell/TestWindow.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * File    : TestWindow.java
- * Created : 14 mars 2004
- * By      : Olivier
- * 
- * 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.swt.animations.shell;
-
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.ui.swt.animations.Animator;
-import org.gudy.azureus2.ui.swt.shells.PopupShell;
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class TestWindow extends PopupShell implements AnimableShell {
-  
-  int nbAnimation = 0;
-  int x0,y0,x1,y1;
-  
-  public TestWindow(Display display) {
-    super(display);    
-    
-    layout();
-    
-    Rectangle bounds = display.getClientArea();    
-    x0 = bounds.x + bounds.width - 250;
-    x1 = bounds.x + bounds.width;
-
-    y0 = bounds.y + bounds.height;
-    y1 = bounds.y + bounds.height - 150;
-    
-    shell.setLocation(x0,y0);
-    shell.open();
-    new LinearAnimator(this,new Point(x0,y0),new Point(x0,y1),30,30).start();
-  }
-
-  
-  public void animationEnded(Animator source) {
-    if(nbAnimation == 0) {
-      nbAnimation++;
-      new LinearAnimator(this,new Point(x0,y1),new Point(x0,y1),1,3000).start();
-      return;
-    }
-    if(nbAnimation == 1) {
-      nbAnimation++;
-      new LinearAnimator(this,new Point(x0,y1),new Point(x1,y1),50,30).start();
-      return;
-    }
-    if(nbAnimation == 2) {
-     shell.getDisplay().asyncExec(new AERunnable() {
-      public void runSupport() {
-        shell.dispose();
-      }
-    });
-   }
-  }
-
-  public void animationStarted(Animator source) {
-    
-  }
-
-  public Shell getShell() {
-   return shell;
-  }
-
-  public void reportPercent(int percent) {    
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java b/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
index 4af1ef7..6c6f00b 100644
--- a/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
+++ b/org/gudy/azureus2/ui/swt/associations/AssociationChecker.java
@@ -107,7 +107,7 @@ AssociationChecker
 		if (display.isDisposed())
 			return;
 
- 		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+ 		shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM);
  	
  		Utils.setShellIcon(shell);
 	 	shell.setText(MessageText.getString("dialog.associations.title"));
diff --git a/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java b/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
index fc4f199..8cb9996 100644
--- a/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/CertificateTrustWindow.java
@@ -36,8 +36,10 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.security.SECertificateListener;
 import org.gudy.azureus2.core3.security.SESecurityManager;
+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.core3.util.TorrentUtils;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
@@ -56,7 +58,7 @@ CertificateTrustWindow
 	
 	public boolean
 	trustCertificate(
-		final String			resource,
+		final String			_resource,
 		final X509Certificate	cert )
 	{
 		final Display	display = SWTThread.getInstance().getDisplay();
@@ -66,6 +68,19 @@ CertificateTrustWindow
 			return( false );
 		}
 		
+		TOTorrent		torrent = TorrentUtils.getTLSTorrent();
+		
+		final String resource;
+			
+		if ( torrent != null ){
+			
+			
+			resource	= TorrentUtils.getLocalisedName( torrent ) + "\n" + _resource;
+		}else{
+			
+			resource	= _resource;
+		}
+		
 		final trustDialog[]	dialog = new trustDialog[1];
 		
 		try{
@@ -132,7 +147,7 @@ CertificateTrustWindow
 			gridData.horizontalSpan = 1;
 			resource_label.setLayoutData(gridData);
 			
-			Label resource_value = new Label(shell,SWT.NULL);
+			Label resource_value = new Label(shell,SWT.WRAP);
 			resource_value.setText(resource.replaceAll("&", "&&"));
 			gridData = new GridData(GridData.FILL_BOTH);
 			gridData.horizontalSpan = 2;
diff --git a/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java b/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
index e0495a0..0eecce7 100644
--- a/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
+++ b/org/gudy/azureus2/ui/swt/auth/CryptoWindow.java
@@ -36,9 +36,7 @@ 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;
 
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -46,7 +44,6 @@ import org.gudy.azureus2.core3.util.*;
 
 import com.aelitis.azureus.core.security.CryptoManagerFactory;
 import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler;
-import com.aelitis.azureus.core.security.CryptoManagerPasswordHandler.passwordDetails;
 
 public class 
 CryptoWindow 
@@ -337,8 +334,8 @@ CryptoWindow
 						
 			final Label linkLabel = new Label(shell, SWT.NULL);
 			linkLabel.setText(MessageText.getString("ConfigView.label.please.visit.here"));
-			linkLabel.setData("http://www.azureuswiki.com/index.php?title=Public_Private_Keys");
-			linkLabel.setCursor(Cursors.handCursor);
+			linkLabel.setData("http://wiki.vuze.com/w/Public_Private_Keys");
+			linkLabel.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
 			linkLabel.setForeground(Colors.blue);
 			gridData = new GridData();
 			gridData.horizontalSpan = 3;
diff --git a/org/gudy/azureus2/ui/swt/beta/BetaWizard.java b/org/gudy/azureus2/ui/swt/beta/BetaWizard.java
new file mode 100644
index 0000000..db28778
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/beta/BetaWizard.java
@@ -0,0 +1,116 @@
+/*
+ * Created on May 24, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.beta;
+
+import org.eclipse.swt.SWT;
+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.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.update.UpdateMonitor;
+import org.gudy.azureus2.ui.swt.wizard.Wizard;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+
+public class 
+BetaWizard
+	extends Wizard
+{	
+	private boolean beta_enabled = COConfigurationManager.getBooleanParameter( "Beta Programme Enabled" );
+	
+	private boolean beta_was_enabled = beta_enabled;
+	
+	private boolean	finished;
+	
+	public
+	BetaWizard()
+	{
+		super( "beta.wizard.title", false );
+	
+		BetaWizardStart panel = new BetaWizardStart( this );
+		
+		setFirstPanel( panel );
+	}
+	
+	public void 
+	onClose()
+	{
+		super.onClose();
+		
+		if ( finished ){
+			
+			COConfigurationManager.setParameter( "Beta Programme Enabled", beta_enabled );
+			
+			if ( !beta_enabled && Constants.IS_CVS_VERSION ){
+				
+				MessageBoxShell mb = new MessageBoxShell( 
+						SWT.ICON_INFORMATION | SWT.OK,
+						MessageText.getString( "beta.wizard.disable.title" ),
+						MessageText.getString( "beta.wizard.disable.text" ));
+				
+				mb.open(null);
+				
+			}else if ( beta_enabled && !beta_was_enabled ){
+				
+				UpdateMonitor.getSingleton( 
+					AzureusCoreFactory.getSingleton()).performCheck(
+						true, false, false,
+						new UpdateCheckInstanceListener() {
+							public void 
+							cancelled(
+								UpdateCheckInstance instance) 
+							{
+							}
+
+							public void 
+							complete(
+								UpdateCheckInstance instance) 
+							{
+							}
+						});
+			}
+		}
+	}
+	
+	protected boolean
+	getBetaEnabled()
+	{
+		return( beta_enabled );
+	}
+	
+	protected void
+	setBetaEnabled(
+		boolean b )
+	{
+		beta_enabled = b;
+	}
+	
+	public void
+	finish()
+	{
+		finished = true;
+		
+		close();
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/beta/BetaWizardStart.java b/org/gudy/azureus2/ui/swt/beta/BetaWizardStart.java
new file mode 100644
index 0000000..f948622
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/beta/BetaWizardStart.java
@@ -0,0 +1,132 @@
+/*
+ * Created on May 24, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.beta;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Label;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.components.LinkLabel;
+import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
+import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
+
+public class 
+BetaWizardStart
+	extends AbstractWizardPanel<BetaWizard> 
+{
+	protected
+	BetaWizardStart(
+		BetaWizard		wizard )
+	{
+		super( wizard, null );
+	}
+
+	public void 
+	show() 
+	{
+		wizard.setTitle(MessageText.getString( "beta.wizard.intro.title" ));
+        wizard.setCurrentInfo( "" );
+        wizard.setPreviousEnabled(false);
+        wizard.setNextEnabled(false);
+        wizard.setFinishEnabled(true);
+
+        Composite rootPanel = wizard.getPanel();
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		rootPanel.setLayout(layout);
+		
+        
+		Label info_label = new Label( rootPanel, SWT.WRAP );
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		info_label.setLayoutData(gridData);
+		info_label.setText( MessageText.getString( "beta.wizard.info" ));
+ 
+		LinkLabel link = new LinkLabel( rootPanel, "beta.wizard.link", MessageText.getString( "beta.wizard.link.url" ));
+		Label link_label = link.getlabel();
+		
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.verticalIndent=10;
+		link_label.setLayoutData(gridData);
+
+		final Composite gRadio = new Composite(rootPanel, SWT.NULL);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+	    gridData.verticalIndent=10;
+		gRadio.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 1;
+		gRadio.setLayout( layout );
+
+
+		Button off_button = new Button (gRadio, SWT.RADIO);
+		Messages.setLanguageText(off_button, "beta.wizard.off");
+		final Button on_button = new Button (gRadio, SWT.RADIO);
+		Messages.setLanguageText(on_button, "beta.wizard.on");
+		
+		SelectionAdapter l = new SelectionAdapter()
+    	{
+    		public void 
+    		widgetSelected(
+    			SelectionEvent arg0 ) 
+    		{
+    			wizard.setBetaEnabled( on_button.getSelection());
+    		}
+    	};
+		off_button.addSelectionListener(l);
+		on_button.addSelectionListener(l);
+		
+		on_button.setSelection( wizard.getBetaEnabled());
+		off_button.setSelection( !wizard.getBetaEnabled());
+
+		LinkLabel forum = new LinkLabel( rootPanel, "beta.wizard.forum", MessageText.getString( "beta.wizard.forum.url" ));
+		Label forum_label = link.getlabel();
+		
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.verticalIndent=10;
+		forum_label.setLayoutData(gridData);
+
+		Label version_label = new Label( rootPanel, SWT.WRAP );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.verticalIndent=10;
+		version_label.setLayoutData(gridData);
+		version_label.setText( MessageText.getString( "beta.wizard.version", new String[]{ Constants.AZUREUS_VERSION } ));
+	}
+	
+	public IWizardPanel
+	getFinishPanel()
+	{
+		return( this );
+	}
+	
+	public void
+	finish()
+	{
+		wizard.finish();
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java b/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
index 5af5950..2353a41 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem1.java
@@ -26,8 +26,6 @@ import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.graphics.Point;
 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;
 
 /** Draws an image at a column in a row of a table using direct paints to the 
@@ -55,11 +53,6 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
 
 	//The Buffered image
   private Image image;
-  /** Track if we have ever drawn the cell.  Don't draw the cell using our
-   * own GC if we've never drawn before.  ie.  If we setGraphic before the
-   * cell is visible, don't paint.
-   */
-  private boolean neverDrawn = true;
   
   
   public BufferedGraphicTableItem1(BufferedTableRow row,int position) {
@@ -98,158 +91,7 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
   public boolean needsPainting() {
   	return true;
   }
-  
-
-  /**
-   * Clear old image from screen (if needed) and paint image
-   * 
-   * @param bForceClear Force clear of area before drawing.  Normally, a
-   *                     non-transparent image will draw overtop of the
-   *                     area, instead of first clearing it. 
-   */
-  private void doPaint(boolean bForceClear) {
-		if (image == null || image.isDisposed())
-			return;
-
-		if (bForceClear
-				|| image.getImageData().getTransparencyType() != SWT.TRANSPARENCY_NONE) {
-			// images with transparency need their area cleared first, otherwise we 
-			// end up multiplying values (alpha type) or not clearing pixels 
-			// (all types)
-			Table table = getTable();
-
-			Rectangle bounds = getBoundsForCanvas();
-			//In case item isn't displayed bounds is null
-			if (bounds == null)
-				return;
-
-			// This should trigger a doPaint(gc)
-			table.redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
-		} else {
-			doPaint((GC) null);
-		}
-	}
-
-  /** Paint the bar without updating it's data.  Unless the size changed.
-   */
-  public void doPaint(GC gc) {
-  	if (neverDrawn) {
-  		if (gc == null)
-  			return;
-  		neverDrawn = false;
-  	}
-
-    //Compute bounds ...
-    Rectangle bounds = getBoundsForCanvas();
-    //In case item isn't displayed bounds is null
-    if (bounds == null || image == null || image.isDisposed()) {
-      //System.out.println(row.getIndex() + " nb");
-      return;
-    }
-    
-    Table table = getTable();
-
-//    System.out.println("doPnt#" + row.getIndex()+": " + 
-//    		((gc == null) ? "GC NULL" : String.valueOf(gc.getClipping())) + 
-//        "ta="+table.getClientArea()+";bounds="+bounds);
-
-    Rectangle imageBounds = image.getBounds();
-    
-    if (imageBounds.width <= 0 || imageBounds.height <= 0 || bounds.width <= 0
-				|| bounds.height <= 0) {
-      //System.out.println(row.getIndex() + " < 0");
-    	return;
-    }
-
-    Rectangle tableBounds = table.getClientArea();
-		// 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);
-    if (orientation == SWT.FILL || fits) {
-      if (fits) {
-        //System.out.println("doPaint() sizewrong #"+row.getIndex()+ ".  Image="+imageBounds +";us="+bounds);
-/**/
-        // Enable this for semi-fast visual update with some flicker
-        boolean ourGC = (gc == null);
-        if (ourGC) {
-          gc = new GC(table);
-        }
-        if (gc != null) {
-          gc.drawImage(image, bounds.x, bounds.y);
-          if (ourGC) {
-            gc.dispose();
-          }
-        }
-        // _OR_ enable refresh() for slower visual update with lots of flicker
-        //refresh();
-        
-        // OR, disable both and image will be updated on next graphic bar update
-        
-        // TODO: make config option to choose
-/**/
-        //invalidate();
-        return;
-      }
-    } else {
-  		if (imageBounds.width < bounds.width) {
-	    	if (orientation == SWT.CENTER)
-	    		bounds.x += (bounds.width - imageBounds.width) / 2;
-	    	else if (orientation == SWT.RIGHT)
-	    		bounds.x = (bounds.x + bounds.width) - imageBounds.width;
-  		}
-
-  		if (imageBounds.height < bounds.height) {
-  			bounds.y += (bounds.height - imageBounds.height) / 2;
-  		}
-    }
-    
-    Rectangle clipping = new Rectangle(bounds.x, bounds.y, 
-                                       bounds.width, 
-                                       bounds.height);
-    int iMinY = table.getHeaderHeight() + tableBounds.y;
-    if (clipping.y < iMinY) {
-      clipping.height -= iMinY - clipping.y;
-      clipping.y = iMinY;
-    }
-    int iMaxY = tableBounds.height + tableBounds.y;
-    if (clipping.y + clipping.height > iMaxY)
-      clipping.height = iMaxY - clipping.y + 1;
-
-    if (clipping.width <= 0 || clipping.height <= 0) {
-      //System.out.println(row.getIndex() + " clipping="+clipping + ";" + iMinY + ";" + iMaxY + ";tca=" + tableBounds);
-      return;
-    }
-
-    boolean ourGC = (gc == null);
-    if (ourGC) {
-      gc = new GC(table);
-    }
-    try {
-
-      Point srcStart = new Point(clipping.x - bounds.x, clipping.y - bounds.y); 
-      Rectangle dstRect = new Rectangle(clipping.x, clipping.y, 
-      		imageBounds.width - srcStart.x, imageBounds.height - srcStart.y);
-  
-      Utils.drawImage(gc, image, srcStart, dstRect, clipping, 0, 0, false);
-    } finally {
-      if (ourGC) {
-        gc.dispose();
-      }
-    }
-  }
 
-  
   public void dispose() {
     super.dispose();
     image = null;
@@ -259,7 +101,7 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
     * @return what size/position the canvas should be
     */
   public Rectangle getBoundsForCanvas() {
-    Rectangle bounds = getBounds();
+    Rectangle bounds = super.getBounds();
     if(bounds == null)
       return null;
     bounds.y += marginHeight;
@@ -268,9 +110,18 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
     bounds.width -= (marginWidth * 2);
     return bounds;
   }
+  
+  // @see {getBounds}
+  public Rectangle getBounds() {
+  	return getBoundsForCanvas();
+  }
+  
+  public Rectangle getBoundsRaw() {
+    return super.getBounds();
+  }
 
   public Point getSize() {
-    Rectangle bounds = getBounds();
+    Rectangle bounds = super.getBounds();
     if(bounds == null)
       return new Point(0, 0);
     return new Point(bounds.width - (marginWidth * 2), 
@@ -309,7 +160,7 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
   public Image getBackgroundImage() {
   	Image imageRowBG = row.getBackgroundImage();
   	if (imageRowBG != null) {
-  		Rectangle bounds = getBounds();
+  		Rectangle bounds = super.getBounds();
   		
   		int wInside = bounds.width - (marginWidth * 2);
   		int hInside = bounds.height - (marginHeight * 2);
@@ -322,9 +173,7 @@ public abstract class BufferedGraphicTableItem1 extends BufferedTableItemImpl
   		return imageCellBG;
   	}
   	
-		Table table = row.getTable();
-		
-		Rectangle bounds = getBounds();
+		Rectangle bounds = super.getBounds();
 		
 		if (bounds.isEmpty()) {
 			return null;
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem2.java b/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem2.java
deleted file mode 100644
index 85a5582..0000000
--- a/org/gudy/azureus2/ui/swt/components/BufferedGraphicTableItem2.java
+++ /dev/null
@@ -1,378 +0,0 @@
- /*
- * File    : BufferedGraphicTableItem.java
- * Created : 24 nov. 2003
- *
- * 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.swt.components;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-import org.eclipse.swt.widgets.Canvas;
-import org.gudy.azureus2.ui.swt.components.BufferedTableRow;
-
-/** Draws an image at a column in a row of a table using a Canvas.
- * In comparison to BufferedGraphicTable, which uses direct paints to table,
- * Pros:
- *  - Skip the table redrawing and overdrawing bugs in 3.0M8 (or greater?)
- *
- * Cons:
- *  - Lag
- *  - A lot more control is needed to do the same thing
- *
- * @see BufferedGraphicTable
- * @author TuxPaper
- *
- */
-public abstract class BufferedGraphicTableItem2 extends BufferedTableItemImpl
-		implements BufferedGraphicTableItem
-{
-  private int marginHeight = 1;
-  private int marginWidth = 1;
-  private int orientation = SWT.CENTER;
-
-  /** Canvas that image is drawn on */
-  Canvas cBlockView = null;
-  //The Buffered image
-  private Image image;
-  
-  /** Used for !fillCell */
-  private Color lastBackColor = null;
-  
-  
-  public BufferedGraphicTableItem2(BufferedTableRow row,int position) {
-    super(row, position);
-  }
-  
-  private void createBlockView() {
-    // For !fillCell, we draw the background manually, because some OSes
-    // send a paint listener after setBackground() (causing another doPaint),
-    // and some do not.
-    int iStyle = SWT.NO_FOCUS | SWT.NO_BACKGROUND;
-    if (orientation == SWT.FILL) {
-      iStyle |= SWT.NO_REDRAW_RESIZE;
-    }
-    cBlockView = new Canvas(getTable(), iStyle);
-    cBlockView.setBackground(null);
-    cBlockView.addPaintListener(new PaintListener() {
-    	public void paintControl(PaintEvent event) {
-        if (event.width == 0 || event.height == 0)
-          return;
-    		doPaint(event.gc.getClipping());
-    	}
-    });
-    //cBlockView.moveAbove(null);
-
-    cBlockView.addMouseListener(new MouseAdapter() {
-        public void mouseDown(MouseEvent e) {
-          Table table = getTable();
-          Rectangle r = cBlockView.getBounds();
-          TableItem[] item = { table.getItem(new Point(r.x, r.y)) };
-          if (item[0] != null) {
-            table.setSelection(item);
-          }
-          table.setFocus();
-        }
-        public void mouseUp(MouseEvent e) {
-          getTable().setFocus();
-        }
-      }
-    );
-  }
-    
-
-  /** Retrieve the graphic related to this table item.
-   * @return the Image that is draw in the cell, or null if there is none.
-   */
-  public Image getGraphic() {
-    return image;
-  }
-  
-  /* Sets image to be drawn.
-   * @param img Image to be stored & drawn
-   * @return true - image was changed.  false = image was the same
-   */
-  public boolean setGraphic(Image img) {
-    boolean bImageSet = (image != img);
-
-    if (bImageSet) {
-      if (cBlockView == null) {
-        createBlockView();
-      }
-      image = img;
-    }
-    if (img != null) {
-      doPaint((Rectangle)null);
-    }
-
-    return bImageSet;
-  }
-
-  public boolean needsPainting() {
-  	return true;
-  }
-  
-  public void locationChanged() {
-    if (cBlockView == null || cBlockView.isDisposed())
-      return;
-
-    Rectangle bounds = getBoundsForCanvas();
-    //In case item isn't displayed bounds is null
-    if (bounds == null || image == null || image.isDisposed()) {
-      return;
-    }
-    // moveAbove reduces the # redraws
-    //cBlockView.moveAbove(null);
-    cBlockView.setLocation(bounds.x, bounds.y);
-  }
-
-  /** Inherited doPaint(GC) call.  This is called when the Table needs 
-   * repainting.  Since we capture the Canvas' paint, most of the Table
-   * repainting can be ignored.  Cases where the cell bounds or background
-   * color changed, however, require action.
-   */
-  public void doPaint(GC gc) {
-    if (cBlockView == null || cBlockView.isDisposed())
-      return;
-
-    //Compute bounds ...
-    Rectangle bounds = getBoundsForCanvas();
-    //In case item isn't displayed bounds is null
-    if (bounds == null || image == null || image.isDisposed()) {
-      return;
-    }
-    Rectangle canvasBounds = cBlockView.getBounds();
-    if (canvasBounds.x != bounds.x || canvasBounds.y != bounds.y) {
-      //cBlockView.moveAbove(null);
-      cBlockView.setLocation(bounds.x, bounds.y);
-      canvasBounds = cBlockView.getBounds();
-      //debugOut("doPaint(GC): move cBlockView to " + bounds.x + "x" + bounds.y, false);
-    }
-
-    Table table = getTable();
-    Rectangle tableBounds = table.getClientArea();
-    if (tableBounds.y < table.getHeaderHeight()) {
-      tableBounds.y = table.getHeaderHeight();
-    }
-    Rectangle rNewCanvas = bounds.intersection(tableBounds);
-    //debugOut("doPaint(gc) rNewCanvas="+rNewCanvas+";canvasBounds="+canvasBounds+";tableBounds="+tableBounds, false);
-    if (rNewCanvas.width <= 0 || rNewCanvas.height <= 0) {
-      return;
-    }
-    if (!rNewCanvas.equals(canvasBounds) ||
-        (orientation != SWT.FILL && !getRowBackground(table).equals(lastBackColor))) {
-      rNewCanvas.x -= canvasBounds.x;
-      rNewCanvas.y -= canvasBounds.y;
-      doPaint(rNewCanvas);
-    }
-  }
-
-  /** Paint the bar without updating it's data.  Unless the size changed.
-   */
-  public void doPaint(Rectangle clipping) {
-    //debugOut("doPaint() clipping="+clipping, false);
-    if (cBlockView == null || cBlockView.isDisposed())
-      return;
-
-    Table table = getTable();
-    //Compute bounds ...
-    Rectangle bounds = getBoundsForCanvas();
-    //In case item isn't displayed bounds is null
-    if (bounds == null || image == null || image.isDisposed()) {
-      return;
-    }
-    
-    Rectangle canvasBounds = cBlockView.getBounds();
-    //debugOut("Block:"+canvasBounds+";cell:"+bounds,false);
-    if (canvasBounds.x != bounds.x || canvasBounds.y != bounds.y) {
-      //cBlockView.moveAbove(null);
-      cBlockView.setLocation(bounds.x, bounds.y);
-      canvasBounds = cBlockView.getBounds();
-      //debugOut("doPaint(clipping): move cBlockView to " + bounds.x + "x" + bounds.y, false);
-    }
-    if (bounds.width != canvasBounds.width ||
-        bounds.height != canvasBounds.height) {
-      cBlockView.setSize(bounds.width, bounds.height);
-      canvasBounds = cBlockView.getBounds();
-    }
-    //debugOut("doPaint()" + ((gc == null) ? "GC NULL" : String.valueOf(gc.getClipping())) + 
-    //         "ta="+table.getClientArea()+";bounds="+bounds, false);
-    
-    if (orientation == SWT.FILL) {
-      Rectangle imageBounds = image.getBounds();
-      if (imageBounds.width != bounds.width ||
-          imageBounds.height != bounds.height) {
-        // Enable this for semi-fast visual update with some flicker
-        cBlockView.setSize(bounds.width, bounds.height);
-        GC gc = new GC(cBlockView);
-        gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, 
-                     0, 0, bounds.width, bounds.height);
-        gc.dispose();
-/*
-        // _OR_ enable refresh() for slower visual update with lots of flicker
-        //refresh();
-        
-        // OR, disable both and image will be updated on next graphic bar update
-        
-        // TODO: make config option to choose
-*/
-        invalidate();
-        return;
-      }
-    }
-    
-    if (clipping == null) {
-      clipping = new Rectangle(0, 0, bounds.width, bounds.height);
-    }
-    Rectangle tableBounds = table.getClientArea();
-    if (tableBounds.y < table.getHeaderHeight()) {
-      tableBounds.y = table.getHeaderHeight();
-    }
-    //debugOut("doPaint() tableBounds="+tableBounds+";canvasBounds="+canvasBounds+";clipping="+clipping, false);
-    tableBounds.x -= canvasBounds.x;
-    tableBounds.y -= canvasBounds.y;
-    clipping = clipping.intersection(tableBounds);
-    //debugOut("doPaint() clipping="+clipping, false);
-
-    if (clipping.x + clipping.width <= 0 && clipping.y + clipping.height <= 0) {
-      return;
-    }
-    
-
-    GC gc = new GC(cBlockView);
-    if (orientation == SWT.FILL) {
-      gc.setClipping(clipping);
-      gc.drawImage(image, 0, 0);
-    } else {
-/*
-      // Grab a pixel beside the cell and draw that as our background
-      // Advantage: paints correct color when hilighted and not in focus
-      // Disadvatage: doesn't always work!
-      GC gc2 = new GC(table);
-      Image i = new Image(table.getDisplay(), 1, 1);
-      gc2.copyArea(i, bounds.x + bounds.width + 1, bounds.y + (bounds.width / 2));
-      gc2.dispose();
-      
-      gc.drawImage(i, 0, 0, 1, 1, 
-                   0,0, rBlockViewBounds.width, rBlockViewBounds.height);
-*/      
-
-      lastBackColor = getRowBackground(table);
-      gc.setBackground(lastBackColor);
-      gc.fillRectangle(clipping);
-/*      
-      Rectangle imageBounds = image.getBounds();
-      Rectangle r = canvasBounds.intersection(tableBounds);
-      int x = (r.width - imageBounds.width) / 2;
-      if (x <= 0)
-        x = 0;
-      clipping.x += x;
-*/
-      int x = 0;
-      gc.setClipping(clipping);
-      gc.drawImage(image, x, 0);
-    }
-    gc.dispose();
-  }
-
-  /** Don't forget to call super.dispose()! */
-  public void dispose() {
-    super.dispose();
-    image = null;
-    if (cBlockView != null) {
-      if (!cBlockView.isDisposed())
-        cBlockView.dispose();
-      cBlockView = null;
-    }
-  }
-  
-  /** Calculate the bounds of the receiver should be drawing in
-    * @return what size/position the canvas should be
-    */
-  public Rectangle getBoundsForCanvas() {
-    Rectangle bounds = getBounds();
-    if(bounds == null)
-      return null;
-    bounds.y += marginHeight;
-    bounds.height -= (marginHeight * 2);
-    bounds.x += marginWidth;
-    bounds.width -= (marginWidth * 2);
-    
-    if (bounds.width <= 0 || bounds.height <= 0)
-      return null;
-
-    return bounds;
-  }
-  
-  public Point getSize() {
-    Rectangle bounds = getBounds();
-    if(bounds == null)
-      return new Point(0, 0);
-    return new Point(bounds.width - (marginWidth * 2), 
-                     bounds.height - (marginHeight * 2));
-  }
-
-  private Color getRowBackground(Table table) {
-    if (row.isSelected() && false) {
-      if (table.isFocusControl())
-        return table.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);
-      else
-        return table.getDisplay().getSystemColor(SWT.COLOR_GRAY);
-    } else {
-      return getBackground();
-    }
-  }
-
-  public void invalidate() {
-  }
-
-	public int getMarginHeight() {
-		return marginHeight;
-	}
-
-	public int getMarginWidth() {
-		return marginWidth;
-	}
-
-  public void setMargin(int width, int height) {
-  	if (width >= 0) {
-  		marginWidth = width;
-  	}
-  	
-  	if (height >= 0) {
-  		marginHeight = height;
-  	}
-  }
-
-	public int getOrientation() {
-		return orientation;
-	}
-  
-  public void setOrientation(int orientation) {
-  	this.orientation = orientation;
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedLabel.java b/org/gudy/azureus2/ui/swt/components/BufferedLabel.java
index 804bff0..4a97d1f 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedLabel.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedLabel.java
@@ -27,6 +27,7 @@ package org.gudy.azureus2.ui.swt.components;
  */
 
 
+import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
@@ -40,13 +41,12 @@ import org.eclipse.swt.layout.GridData;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 
 public class 
 BufferedLabel
 	extends BufferedWidget 
 {
-	private Label	label;
+	private Control	label;
 	
 	private String	value = "";
 	
@@ -55,9 +55,9 @@ BufferedLabel
 		Composite	composite,
 		int			attrs )
 	{
-		super( new Label( composite, attrs ));
+		super((attrs&SWT.DOUBLE_BUFFERED)==0?new Label( composite, attrs ):new DoubleBufferedLabel( composite, attrs ));
 		
-		label = (Label)getWidget();
+		label = (Control)getWidget();
 		
 		ClipboardCopy.addCopyToClipMenu(
 			label,
@@ -66,7 +66,7 @@ BufferedLabel
 				public String 
 				getText() 
 				{
-					return( label.getText());
+					return( BufferedLabel.this.getText());
 				}
 			});
 	}
@@ -130,7 +130,15 @@ BufferedLabel
 			// cause the nect character to be underlined on Windows. This is generally NOT
 			// the desired behaviour of a label in Azureus so by default we escape them
 		
-		label.setText( value==null?"":value.replaceAll("&", "&&" ));	
+		String fixed_value = value==null?"":value.replaceAll("&", "&&" );
+		
+		if ( label instanceof Label ){
+			
+			((Label)label).setText( fixed_value );
+		}else{
+			
+			((DoubleBufferedLabel)label).setText( fixed_value );
+		}
 	}	
 	
 	public void
@@ -163,7 +171,7 @@ BufferedLabel
 
 			label.setToolTipText(url);
 		
-		    label.setCursor(Cursors.handCursor);
+		    label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 		    label.setForeground(Colors.blue);
 		    label.addMouseListener(new MouseAdapter() {
 		      public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedTableItem.java b/org/gudy/azureus2/ui/swt/components/BufferedTableItem.java
index 526be84..941f9f6 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedTableItem.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedTableItem.java
@@ -50,6 +50,8 @@ public interface BufferedTableItem
 
 	public abstract Rectangle getBounds();
 
+	public abstract Rectangle getBoundsRaw();
+
 	public abstract void refresh();
 
 	public abstract void dispose();
@@ -63,10 +65,6 @@ public interface BufferedTableItem
 
 	public abstract boolean needsPainting();
 
-	/** Paint the image only (no update needed)
-	 */
-	public abstract void doPaint(GC gc);
-
 	/** Column location (not position) changed.  Usually due to a resize of
 	 * a column in a position prior to this one.
 	 */
@@ -115,4 +113,18 @@ public interface BufferedTableItem
 	 * @since 3.0.5.3
 	 */
 	public abstract boolean isMouseOver();
+
+	/**
+	 * @return
+	 *
+	 * @since 4.5.1.1
+	 */
+	boolean isInPaintItem();
+
+	/**
+	 * @return
+	 *
+	 * @since 4.6.0.5
+	 */
+	public int getHeight();
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java b/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
index edc2691..fa76df0 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedTableItemImpl.java
@@ -25,7 +25,12 @@ import org.eclipse.swt.graphics.*;
 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;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+import com.aelitis.azureus.ui.swt.utils.ColorCache2;
+import com.aelitis.azureus.ui.swt.utils.ColorCache2.*;
 
 /**
  * @author Olivier
@@ -37,7 +42,7 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 
 	private int position;
 
-	private Color ourFGColor = null;
+	private CachedColor ourFGColor_cache = null;
 	
 	private String text = "";
 	
@@ -45,6 +50,8 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 
 	private AERunnable runnableDirtyCell;
 
+	private boolean isDirty;
+
 	public BufferedTableItemImpl(BufferedTableRow row, int position) {
 		this.row = row;
 		this.position = position;
@@ -60,23 +67,57 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 		}
 		this.text = (text == null) ? "" : text;
 		
-		dirtyCell();
+		redraw();
 		
 		return true;
-	}
-	private void dirtyCell() {
+	}
+
+  // @see org.gudy.azureus2.ui.swt.components.BufferedTableItem#redraw()
+  public void redraw() {
+		//System.out.println("redraw via " + Debug.getCompressedStackTrace(5));
+
+  	synchronized (this) {
+			if (isDirty) {
+				return;
+			}
+		}
+  	
+  	if (!row.isVisibleNoSWT()) {
+  		return;
+  	}
+
+		// Might be a good optimization.. haven't tried it
+  	//if (isInPaintItem()) {
+		//		&& row.getTable().getData("fullPaint") == Boolean.TRUE) {
+  	//	return;
+  	//}
+  	
 		if (runnableDirtyCell == null) {
 			synchronized (this) {
 				if (runnableDirtyCell == null) {
-					runnableDirtyCell = new AERunnable(){
+					runnableDirtyCell = new AERunnable() {
 						public void runSupport() {
-							Rectangle bounds = getBounds();
+							synchronized (this) {
+								isDirty = false;
+							}
+							if (isInPaintItem()
+									&& row.getTable().getData("fullPaint") == Boolean.TRUE) {
+								return;
+							}
+							// row.isVisible is time consuming.  getBounds intersecting 
+							// clientArea will probably be empty when not visible
+							//if (!row.isVisible()) {
+							//	return;
+							//}
+							Rectangle bounds = getBoundsRaw();
 							if (bounds != null) {
-								Table table = row.getTable();
+								TableOrTreeSWT 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);
+
+								if (!dirty.isEmpty()) {
+									quickRedrawCell(table, dirty, bounds);
+								}
 							}
 						}
 					};
@@ -84,9 +125,17 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 			}
 		}
 		
+		synchronized (this) {
+			isDirty = true;
+		}
 		Utils.execSWTThread(runnableDirtyCell);
 	}
 
+	protected void quickRedrawCell(TableOrTreeSWT table, Rectangle dirty,
+			Rectangle cellBounds) {
+		table.redraw(dirty.x, dirty.y, dirty.width, dirty.height, false);
+	}
+
 	public void setIcon(Image img) {
 		if (position != -1) {
 			row.setImage(position, img);
@@ -112,9 +161,9 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 			return false;
 
 		boolean ok = row.setForeground(position, color);
-		if (ok && ourFGColor != null) {
-			if (!ourFGColor.isDisposed()) {ourFGColor.dispose();}
-			ourFGColor = null;
+		if (ok && ourFGColor_cache != null) {
+			if (!ourFGColor_cache.isDisposed()) {ourFGColor_cache.dispose();}
+			ourFGColor_cache = null;
 		}
 		return ok;
 	}
@@ -126,10 +175,30 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 		return row.getForeground(position);
 	}
 
-	public boolean setForeground(int red, int green, int blue) {
-		if (position == -1)
+	public boolean setForeground(final int red, final int green, final int blue) {
+		if (position == -1) {
 			return false;
-		
+		}
+
+		Color oldColor = row.getForeground(position);
+		if (oldColor != null) {
+
+  		RGB newRGB = new RGB(red, green, blue);
+  
+  		if (oldColor.getRGB().equals(newRGB)) {
+  			return false;
+  		}
+		}
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_setForeground(red, green, blue);
+			}
+		});
+		return true;
+	}
+
+	private boolean swt_setForeground(final int red, final int green, final int blue) {
 		if (red == -1 && green == -1 && blue == -1) {
 			return setForeground(null);
 		}
@@ -142,12 +211,12 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 			return false;
 		}
 
-		Color newColor = new Color(row.getTable().getDisplay(), newRGB);
-		boolean ok = row.setForeground(position, newColor);
+		CachedColor newColor = ColorCache2.getColor( row.getTable().getDisplay(), newRGB );
+		boolean ok = row.setForeground(position, newColor.getColor());
 		if (ok) {
-			if (ourFGColor != null && !ourFGColor.isDisposed())
-				ourFGColor.dispose();
-			ourFGColor = newColor;
+			if (ourFGColor_cache != null && !ourFGColor_cache.isDisposed())
+				ourFGColor_cache.dispose();
+			ourFGColor_cache = newColor;
 		} else {
 			if (!newColor.isDisposed())
 				newColor.dispose();
@@ -161,18 +230,29 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 	}
 
 	public Rectangle getBounds() {
-		if (position != -1)
-			return row.getBounds(position);
-		return null;
+		if (position == -1) {
+			return null;
+		}
+		if (isInPaintItem()) {
+			InPaintInfo data = (InPaintInfo) row.getTable().getData("inPaintInfo");
+			return new Rectangle(data.curCellBounds.x, data.curCellBounds.y,
+					data.curCellBounds.width, data.curCellBounds.height);
+		}
+		return row.getBounds(position);
 	}
+	
+  public Rectangle getBoundsRaw() {
+    return getBounds();
+  }
 
-	public Table getTable() {
+
+	public TableOrTreeSWT getTable() {
 		return row.getTable();
 	}
 
 	public void dispose() {
-		if (ourFGColor != null && !ourFGColor.isDisposed())
-			ourFGColor.dispose();
+		if (ourFGColor_cache != null && !ourFGColor_cache.isDisposed())
+			ourFGColor_cache.dispose();
 	}
 
 	public boolean isShown() {
@@ -195,9 +275,6 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 		return false;
 	}
 
-	public void doPaint(GC gc) {
-	}
-
 	public void locationChanged() {
 	}
 
@@ -206,7 +283,7 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 	}
 
 	public Image getBackgroundImage() {
-		Table table = row.getTable();
+		TableOrTreeSWT table = row.getTable();
 		
 		Rectangle bounds = getBounds();
 		
@@ -226,24 +303,6 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 		return image;
 	}
 
-  // @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();
-				if (bounds != null) {
-					Table table = row.getTable();
-					Rectangle dirty = table.getClientArea().intersection(bounds);
-					if (!dirty.isEmpty()) {
-						table.redraw(dirty.x, dirty.y, dirty.width, dirty.height, false);
-					}
-				}
-			}
-		});
-  }
-  
   // @see org.gudy.azureus2.ui.swt.components.BufferedTableItem#getMaxLines()
   public int getMaxLines() {
   	return 1;
@@ -256,7 +315,7 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 				if (row == null) {
 					return;
 				}
-				Table table = row.getTable();
+				TableOrTreeSWT table = row.getTable();
 				if (table == null || table.isDisposed()) {
 					return;
 				}
@@ -267,7 +326,7 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
   
   // @see org.gudy.azureus2.ui.swt.components.BufferedTableItem#isMouseOver()
   public boolean isMouseOver() {
-		Table table = row.getTable();
+		TableOrTreeSWT table = row.getTable();
 		if (table == null || table.isDisposed()) {
 			return false;
 		}
@@ -277,4 +336,17 @@ public abstract class BufferedTableItemImpl implements BufferedTableItem
 		Rectangle bounds = getBounds();
 		return bounds == null ? false : bounds.contains(pt);
   }
+  
+	public boolean isInPaintItem() {
+		if (row.inPaintItem()) {
+			InPaintInfo data = (InPaintInfo) row.getTable().getData("inPaintInfo");
+			return data.curCellIndex == position;
+		}
+		return false;
+	}
+	
+	// @see org.gudy.azureus2.ui.swt.components.BufferedTableItem#getHeight()
+	public int getHeight() {
+		return row.getHeight();
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedTableRow.java b/org/gudy/azureus2/ui/swt/components/BufferedTableRow.java
index 81ef21d..6291be8 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedTableRow.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedTableRow.java
@@ -23,13 +23,15 @@ package org.gudy.azureus2.ui.swt.components;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-import org.gudy.azureus2.core3.config.ParameterListener;
+
 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.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+import com.aelitis.azureus.ui.swt.utils.ColorCache2;
+import com.aelitis.azureus.ui.swt.utils.ColorCache2.*;
 
 /**
  * A buffered Table Row.
@@ -53,95 +55,44 @@ public class
 BufferedTableRow
 {
 	private static final int VALUE_SIZE_INC	= 8;
-	
-	private static Color[] alternatingColors = null;
 
 	// for checkWidget(int)
 	public final static int REQUIRE_TABLEITEM = 0;
 	public final static int REQUIRE_TABLEITEM_INITIALIZED = 1;
 	public final static int REQUIRE_VISIBILITY = 2;
 	
-	protected Table table;
-	protected TableItem	item;
+	protected TableOrTreeSWT table;
+	protected TableItemOrTreeItem	item;
 	
 	protected Image[]	image_values	= new Image[0];
 	protected Color[]	foreground_colors	= new Color[0];
 	
-	protected Color		foreground;
-	protected Color     ourForeground;
+	protected CachedColor		foreground_cache;
+	protected CachedColor     	ourForeground_cache;
 	
 	private Point ptIconSize = null;
 
 	private Image imageBG;
+
+	private int numSubItems;
+
+	private boolean expanded;
+
+	private boolean isVirtual;
 	
 	
-	static {
-		Colors.getInstance().addColorsChangedListener(new ParameterListener() {
-			public void parameterChanged(String parameterName) {
-				alternatingColors = null;
-			}
-		});
-	}
-	
 	/**
 	 * Default constructor
 	 * 
 	 * @param _table
 	 */
-	public BufferedTableRow(Table _table)
+	public BufferedTableRow(TableOrTreeSWT _table)
 	{
 		table = _table;
 		item = null;
 	}
 	
 	/**
-	 * Create a row in the SWT table
-	 *
-	 */
-	public void createSWTRow() {
-    item = new TableItem(table, SWT.NULL);
-		setAlternatingBGColor(true);
-	}
-
-	public void createSWTRow(int index) {
-    new TableItem(table, SWT.NULL);
-    setTableItem(index, false);
-	}
-	
-	public void setAlternatingBGColor(boolean bEvenIfNotVisible) {
-		if (Utils.TABLE_GRIDLINE_IS_ALTERNATING_COLOR)
-			return;
-			
-		if ((table.getStyle() & SWT.VIRTUAL) != 0 && !bEvenIfNotVisible
-				&& !isVisible()) {
-			return;
-		} else if (item == null || item.isDisposed()) {
-			return;
-		}
-
-		int index = table.indexOf(item);
-		if (index == -1) {
-			return;
-		}
-
-		try {
-			if (alternatingColors == null || alternatingColors[1].isDisposed()) {
-				alternatingColors = new Color[] {
-					table.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND),
-					Colors.colorAltRow
-				};
-			}
-
-			Color newColor = alternatingColors[index % alternatingColors.length];
-			if (!newColor.equals(getBackground())) {
-				item.setBackground(newColor);
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-	}
-
-	/**
 	 * Disposes of underlying SWT TableItem. If no TableItem has been
 	 * assigned to the row yet, an unused TableItem will be disposed of, if
 	 * available.
@@ -157,9 +108,9 @@ BufferedTableRow
 				// No assigned spot yet, or not our spot:
 				// find a row with no TableRow data
 
-				TableItem[] items = table.getItems();
+				TableItemOrTreeItem[] items = table.getItems();
 				for (int i = items.length - 1; i >= 0; i--) {
-					TableItem item = items[i];
+					TableItemOrTreeItem item = items[i];
 					if (!item.isDisposed()) {
 						Object itemRow = item.getData("TableRow");
 						if (itemRow == null || itemRow == this) {
@@ -172,14 +123,14 @@ BufferedTableRow
 
 			boolean itemNeedsDisposal = item != null && !item.isDisposed(); 
 			
-			if (this.ourForeground != null && !this.ourForeground.isDisposed()) {
+			if (ourForeground_cache != null && !ourForeground_cache.isDisposed()) {
 				// Even though we are going to dispose soon, set foreground to null
 				// in case for some reason the OS gets a paint event in between
 				// the color disposal and the item disposal
 				if (itemNeedsDisposal) {
 					item.setForeground(null);
 				}
-				this.ourForeground.dispose();
+				this.ourForeground_cache.dispose();
 			}
 
 			if (itemNeedsDisposal) {
@@ -248,14 +199,14 @@ BufferedTableRow
 	 * @return True: Ok; False: Not ok
 	 */
 	public boolean checkWidget(int checkFlags) {
-		boolean bWidgetOk = !table.isDisposed() && item != null
-				&& !item.isDisposed() && item.getData("TableRow") == this;
+		boolean bWidgetOk = item != null && !item.isDisposed()
+				&& item.getData("TableRow") == this;
 
 		final boolean bCheckVisibility = (checkFlags & REQUIRE_VISIBILITY) > 0;
 		final boolean bCheckInitialized = (checkFlags & REQUIRE_TABLEITEM_INITIALIZED) > 0;
 
 		if (bWidgetOk && bCheckInitialized) {
-			bWidgetOk = (table.getStyle() & SWT.VIRTUAL) == 0
+			bWidgetOk = !isVirtual
 					|| item.getData("SD") != null;
 		}
 
@@ -263,7 +214,7 @@ BufferedTableRow
 			if (_isVisible()) {
 				// Caller assumes that a visible item can be modified, so 
 				// make sure we initialize it.
-				if (!bCheckInitialized && (table.getStyle() & SWT.VIRTUAL) != 0
+				if (!bCheckInitialized && isVirtual
 						&& item.getData("SD") == null) {
 					// This is catch is temporary for SWT 3212, because there are cases where
 					// it says it isn't disposed, when it really almost is
@@ -272,7 +223,6 @@ BufferedTableRow
 					} catch (NullPointerException badSWT) {
 					}
 
-		   		setAlternatingBGColor(true);
 		    	setIconSize(ptIconSize);
 					invalidate();
 				}
@@ -286,10 +236,27 @@ BufferedTableRow
 	
 	private boolean _isVisible() {
 		// Least time consuming checks first
+
+		if (inPaintItem()) {
+			return true;
+		}
+
 		if (!table.isVisible()) {
 			return false;
 		}
 		
+		//if (table.getData("inPaintItem") != null) {
+		//	System.out.println(table.indexOf((Widget) table.getData("inPaintItem")) + ";" + table.indexOf(item));
+		//	System.out.println(Debug.getCompressedStackTrace());
+		//}
+		
+		Rectangle bounds = getBounds(0);
+		if (bounds == null) {
+			return false;
+		}
+		return table.getClientArea().contains(bounds.x, bounds.y);
+
+		/*
 		int index = table.indexOf(item);
 		if (index == -1)
 			return false;
@@ -302,148 +269,179 @@ BufferedTableRow
 		if (index > iBottomIndex)
 			return false;
 
+  	//System.out.println("i-" + index + ";top=" + iTopIndex + ";b=" + iBottomIndex);
+		
 		return true;
+		*/
 	}
 	
 	
 	public Color
 	getForeground()
 	{
-		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
-  	  return null;
+		if (foreground_cache != null) {
+			return foreground_cache.getColor();
+		}
 		
-		if (ourForeground == null && table.isSelected(table.indexOf(item))) {
-			return table.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
+		if (!Utils.isSWTThread()) {
+			return null;
 		}
 
-		return( item.getForeground());
-	}
-	
-	private static final boolean DEBUG_SET_FOREGROUND = System.getProperty("debug.setforeground") != null;
-	private static void setForegroundDebug(String method_sig, Color c) {
-		if (DEBUG_SET_FOREGROUND && c != null) {
-			Debug.out("BufferedTableRow " + method_sig + " -> " + c);
+		if (foreground_cache == null && isSelected()) {
+			return table.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
 		}
-	}
-	private static void setForegroundDebug(String method_sig, int r, int g, int b) {
-		if (DEBUG_SET_FOREGROUND && (!(r == 0 && g == 0 && b == 0))) {
-			Debug.out("BufferedTableRow " + method_sig + " -> " + r + "," + g + "," + b);
+
+		if (!checkWidget(REQUIRE_TABLEITEM)) {
+			return null;
 		}
+
+		return( item.getForeground());
 	}
 	
-	public void
+	public boolean
 	setForeground(
 		Color	c )
 	{
-		setForegroundDebug("setForeground(Color)", c);
-		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
-			return;
-
-		if (foreground == null && c == null) {return;}
+		if (foreground_cache == null && c == null) {return false;}
 		
-		if (foreground != null && foreground.equals(c))
-		  return;
+		if (foreground_cache != null ){
+			
+			Color existing = foreground_cache.getColor();
+			
+			if ( existing != null && existing.equals(c)){
 		
-		foreground = c;
-		if (this.ourForeground != null) {
-			if (!this.ourForeground.isDisposed()) {
-				this.ourForeground.dispose();
+				return false;
 			}
-			this.ourForeground = null;
 		}
 		
-		item.setForeground(foreground);
-	}
-	
-	public void setForeground(int red, int green, int blue) {
-		setForegroundDebug("setForeground(r,g,b)", red, green, blue);
-		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED)) {
-			return;
+		foreground_cache = ColorCache2.getColor( c );
+		if (this.ourForeground_cache != null) {
+			if (!this.ourForeground_cache.isDisposed()) {
+				this.ourForeground_cache.dispose();
+			}
+			this.ourForeground_cache = null;
 		}
 		
+		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
+			return false;
+
+		item.setForeground(c);
+		return true;
+	}
+
+	public void setForeground(final int red, final int green, final int blue) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_setForeground(red, green, blue);
+			}
+		});
+	}
+
+	
+	public void swt_setForeground(int red, int green, int blue) {
 		if (red == -1 && green == -1 && blue == -1) {
 			this.setForeground(null);
 			return;
 		}
 		
 		RGB newRGB = new RGB(red, green, blue);
-		if (this.foreground != null && this.foreground.getRGB().equals(newRGB)) {
-			return;
+		if (this.foreground_cache != null ){
+			
+			Color c = this.foreground_cache.getColor();
+			
+			if ( c != null && c.getRGB().equals(newRGB)){
+		
+				return;
+			}
 		}
 		
 		// Hopefully it is OK to just assume it is safe to dispose of the colour,
 		// since we're expecting it to match this.foreground.
-		Color newColor = new Color(getTable().getDisplay(), newRGB);
-		item.setForeground(newColor);
-		if (ourForeground != null && !ourForeground.isDisposed()) {
-			ourForeground.dispose();
+		CachedColor newColor = ColorCache2.getColor(getTable().getDisplay(), newRGB);
+		if (checkWidget(REQUIRE_TABLEITEM_INITIALIZED)) {
+			item.setForeground(newColor.getColor());
 		}
-		this.foreground = newColor;
-		this.ourForeground = newColor;
+		if (ourForeground_cache != null && !ourForeground_cache.isDisposed()) {
+			ourForeground_cache.dispose();
+		}
+		this.foreground_cache = newColor;
+		this.ourForeground_cache = newColor;
 	}
 	
 	public boolean
 	setForeground(
-	  int index,
-		Color	new_color )
+	  final int index,
+		final Color	new_color )
 	{
-		setForegroundDebug("setForeground(int,Color)", new_color);
-		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
-			return false;
 				
-		if ( index >= foreground_colors.length ){
+		synchronized (this) {
 			
-			int	new_size = Math.max( index+1, foreground_colors.length+VALUE_SIZE_INC );
-			
-			Color[]	new_colors = new Color[new_size];
-			
-			System.arraycopy( foreground_colors, 0, new_colors, 0, foreground_colors.length );
-			
-			foreground_colors = new_colors;
+  		if ( index >= foreground_colors.length ){
+  			
+  			int	new_size = Math.max( index+1, foreground_colors.length+VALUE_SIZE_INC );
+  			
+  			Color[]	new_colors = new Color[new_size];
+  			
+  			System.arraycopy( foreground_colors, 0, new_colors, 0, foreground_colors.length );
+  			
+  			foreground_colors = new_colors;
+  		}
+  
+  		Color value = foreground_colors[index];
+  		
+  		if ( new_color == value ){
+  			
+  			return false;
+  		}
+  		
+  		if (	new_color != null && 
+  				value != null &&
+  				new_color.equals( value )){
+  					
+  			return false;
+  		}
+  		
+  		foreground_colors[index] = new_color;
 		}
 
-		Color value = foreground_colors[index];
-		
-		if ( new_color == value ){
-			
-			return false;
-		}
-		
-		if (	new_color != null && 
-				value != null &&
-				new_color.equals( value )){
-					
-			return false;
+		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED)) {
+			return true;
 		}
-		
-		foreground_colors[index] = new_color;
 
-    try {
-      item.setForeground(index, new_color);
-    } catch (NoSuchMethodError e) {
-      /* Ignore for Pre 3.0 SWT.. */
-    }
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if ( !item.isDisposed()){
+					item.setForeground(index, new_color);
+				}
+			}
+		});
     
     return true;
 	}
 
 	public Color getForeground(int index)
 	{
-		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
-  	  return null;
-
-		if (index >= foreground_colors.length) {
-		  return getForeground();
-		}
-		
-		if (foreground_colors[index] == null && isSelected()) {
-			Color systemColor = table.getDisplay().getSystemColor(
-					table.isFocusControl() ? SWT.COLOR_LIST_SELECTION_TEXT
-							: SWT.COLOR_WIDGET_FOREGROUND);
-			return systemColor;
+		synchronized (this) {
+  		if (index >= foreground_colors.length) {
+  		  return getForeground();
+  		}
+  
+  		if (foreground_colors[index] == null) {
+  			if (isSelected()) {
+  				if (!Utils.isSWTThread()) {
+  					return null;
+  				}
+  
+    			Color systemColor = table.getDisplay().getSystemColor(
+    					table.isFocusControl() ? SWT.COLOR_LIST_SELECTION_TEXT
+    							: SWT.COLOR_WIDGET_FOREGROUND);
+    			return systemColor;
+  			}
+  			return getForeground();
+  		}
+  
+  		return foreground_colors[index];
 		}
-
-		return foreground_colors[index];
 	}
 	
 	protected String
@@ -489,11 +487,6 @@ BufferedTableRow
 		if (!checkWidget(REQUIRE_TABLEITEM_INITIALIZED))
 			return null;
 
-		// Some Platforms (OSX) don't handle getBounds properly (3.2M4) when
-		// item doesn't exist in table
-		if (table.indexOf(item) == -1)
-			return null;
-
 		Rectangle r = item.getBounds(index);
 		if (r == null || r.width == 0 || r.height == 0)
 			return null;
@@ -501,7 +494,7 @@ BufferedTableRow
 		return r; 
 	}
 
-  protected Table getTable() {
+  protected TableOrTreeSWT getTable() {
   	return table;
   }
   
@@ -510,6 +503,7 @@ BufferedTableRow
       return null;
 		
 		if (isSelected()) {
+			// XXX This isn't the right color on Cocoa when in focus
 			return table.getDisplay().getSystemColor(
 					table.isFocusControl() ? SWT.COLOR_LIST_SELECTION
 							: SWT.COLOR_WIDGET_BACKGROUND);
@@ -529,82 +523,40 @@ BufferedTableRow
     return table.indexOf(item);
   }
   
-  private void copyToItem(TableItem newItem) {
-    Table table = getTable();
-    if (table == null || item == null)
-      return;
-
-//    newItem.setText(text_values);
-		newItem.setImage(image_values);
-		Color colorFG = item.getForeground();
-		Color colorBG = item.getBackground();
-		newItem.setForeground(colorFG);
-		newItem.setBackground(colorBG);
-		int numColumns = table.getColumnCount();
-		for (int i = 0; i < numColumns; i++) {
-      try {
-      	newItem.setText(i, item.getText(i));
-        Color colorColumnFG = item.getForeground(i);
-        Color colorColumnBG = item.getBackground(i);
-        if (!colorColumnFG.equals(colorFG))
-          newItem.setForeground(i, colorColumnFG);
-        if (!colorColumnBG.equals(colorBG))
-          newItem.setBackground(i, colorColumnBG);
-      } catch (NoSuchMethodError e) {
-        /* Ignore for Pre 3.0 SWT.. */
-      }
-		}
-    if (isSelected())
-      table.select(table.indexOf(newItem));
-    else
-      table.deselect(table.indexOf(newItem));
-
-    newItem.setData("TableRow", item.getData("TableRow"));
-	}
-  
   public boolean isSelected() {
 		if (!checkWidget(REQUIRE_TABLEITEM))
   		return false;
 
-  	// Invalid Indexes are checked/ignored by SWT.
-    return table.isSelected(table.indexOf(item));
+    return table.isSelected(item);
   }
 
-  public void setSelected(boolean bSelected) {
+  public void setSelected(final boolean bSelected) {
+  	Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_setSelected(bSelected);
+			}
+		});
+  }
+  
+  private void swt_setSelected(boolean bSelected) {
 		if (!checkWidget(REQUIRE_TABLEITEM))
   		return;
 
     if (bSelected)
-      table.select(getIndex());
+      table.select(item);
     else
-      table.deselect(getIndex());
+      table.deselect(item);
   }
 
-  /**
-   * Set the TableItem associated with this row to the TableItem at the
-   * specified index.
-   * 
-   * @param newIndex Index of TableItem that will be associated with this row
-   * @param bCopyFromOld True: Copy the visuals from the old TableItem to
-   *                            the new TableItem
-   * @return success level
-   */
-  public boolean setTableItem(int newIndex, boolean bCopyFromOld) {
-	  return setTableItem(newIndex, bCopyFromOld, true);	  
-  }
-  
-  public boolean setTableItem(int newIndex, boolean bCopyFromOld, boolean isVisible) {
-  	TableItem newRow;
-
-  	boolean needsNewAltBG = false;
-		if (alternatingColors != null) {
-			int newAltRowNo = newIndex % alternatingColors.length;
-			int oldAltRowNo = item == null ? -1 : table.indexOf(item)
-					% alternatingColors.length;
-			needsNewAltBG = newAltRowNo != oldAltRowNo;
-		}
-  	
+  public boolean setTableItem(int newIndex, boolean isVisible) {
+  	TableItemOrTreeItem newRow;
+
   	try {
+//  		if (item != null && !item.isDisposed() && table.indexOf(item) == newIndex) {
+//  			return false;
+//  		}
+  		
+  		//System.out.println((item == null ? null : "" + table.indexOf(item)) + ":" + newIndex + ":" + isVisible + ":" + table.getData("maxItemShown"));
   		newRow = table.getItem(newIndex);
   	} catch (IllegalArgumentException er) {
   		if (item == null || item.isDisposed()) {
@@ -613,51 +565,70 @@ BufferedTableRow
   		item = null;
   		return true;
   	} catch (Throwable e) {
-  		System.out.println("setTableItem(" + newIndex + ", " + bCopyFromOld + ")");
+  		System.out.println("setTableItem(" + newIndex + ", " + isVisible + ")");
   		e.printStackTrace();
   		return false;
   	}
   	
+  	return setTableItem(newRow, isVisible);
+  }
+
+  public boolean setTableItem(TableItemOrTreeItem newRow, boolean isVisible) {
+  	if (item == null) {
+  		isVirtual = (table.getStyle() & SWT.VIRTUAL) > 0;
+  		if (ptIconSize == null) {
+  			ptIconSize = new Point(1, table.getItemHeight());
+  		}
+  	}
   	if (newRow.isDisposed()) {
   		Debug.out("newRow disposed from " + Debug.getCompressedStackTrace());
   		return false;
   	}
 
-  	if (newRow == item) {
+  	if (newRow.equals(item)) {
   		if (newRow.getData("TableRow") == this) {
-  			if(isVisible && needsNewAltBG)
-  				setAlternatingBGColor(true);
   			return false;
   		}
   	}
 
-  	if (newRow.getParent() != table)
-  		return false;
-
-  	if (bCopyFromOld) {
-  		copyToItem(newRow);
-  	} else if (newRow.getData("SD") != null) {
-  		// clear causes too much flicker
-  		//table.clear(table.indexOf(newRow));
-  		newRow.setForeground(null);
-  		//newRow.setBackground(null);
-
-  		int numColumns = table.getColumnCount();
-  		for (int i = 0; i < numColumns; i++) {
-  			try {
-  				newRow.setImage(i, null);
-  				newRow.setForeground(i, null);
-  			} catch (NoSuchMethodError e) {
-  				/* Ignore for Pre 3.0 SWT.. */
-  			}
-  		}
+  	//if (!newRow.getParent().equalsTableOrTree(table))
+  	//	return false;
+
+// The following is commented out after moving visible logic to TableRowImpl
+//  	if (!isVisible) {
+//  		// Q&D, clear out.. we'll fill it correctly when it's visible
+//  		if (newRow.getData("TableRow") != null) {
+//    		newRow.setData("TableRow", null);
+//    		table.deselect(newRow);
+//    		return true;
+//  		}
+//  		//System.out.println("quickclear " + table.indexOf(newRow));
+//  		return false;
+//  	}
+		//System.out.println("slowset " + table.indexOf(newRow));
+
+  	boolean lastItemExisted = item != null && !item.isDisposed();
+  	// can't base newRowHadItem on "TableRow" as we clear it in "unlinking" stage
+  	//boolean newRowHadItem = newRow.getData("TableRow") != null;
+
+  	if (newRow.getData("SD") != null) {
   	} else {
   		newRow.setData("SD", "1");
   		setIconSize(ptIconSize);
   	}
 
-  	if(isVisible && needsNewAltBG)
-  		setAlternatingBGColor(false);
+		newRow.setForeground(foreground_cache==null?null:foreground_cache.getColor());
+
+		int numColumns = table.getColumnCount();
+		for (int i = 0; i < numColumns; i++) {
+			try {
+				//newRow.setImage(i, null);
+				newRow.setForeground(i, i < foreground_colors.length
+						? foreground_colors[i] : null);
+			} catch (NoSuchMethodError e) {
+				/* Ignore for Pre 3.0 SWT.. */
+			}
+		}
 
   	try {
   		newRow.setData("TableRow", this);
@@ -671,25 +642,57 @@ BufferedTableRow
   	}
 
 	  image_values	= new Image[0];
-	  foreground_colors	= new Color[0];
-    foreground = null;
+	  //foreground_colors	= new Color[0];
+    //foreground = null;
 
     // unlink old item from tablerow
-    if (item != null && !item.isDisposed() && item.getData("TableRow") == this && newRow != item) {
+    if (lastItemExisted && item.getData("TableRow") == this && !newRow.equals(item)) {
     	item.setData("TableRow", null);
+    	table.deselect(item);
+    	/*
   		int numColumns = table.getColumnCount();
   		for (int i = 0; i < numColumns; i++) {
         try {
-        	item.setImage(i, null);
+        	//item.setImage(i, null);
         	item.setForeground(i, null);
         } catch (NoSuchMethodError e) {
-          /* Ignore for Pre 3.0 SWT.. */
         }
   		}
+  		*/
     }
 
     item = newRow;
-   	invalidate();
+
+  	setSubItemCount(numSubItems);
+		item.setExpanded(expanded);
+		// Need to execute (de)select later, because if we are in a paint event
+		// that paint event may be reporting a row selected before the selection
+		// event fired (Cocoa 3650 fires paint before select yet the row is marked
+		// selected)
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				if (table.isDisposed() || item == null) {
+					return;
+				}
+				if (item.isDisposed()
+						|| item.getData("TableRow") != BufferedTableRow.this) {
+					return;
+				}
+				// select/deselect takes less time than a table.isSelected (tree)
+				if (isSelected()) {
+					table.select(item);
+				} else {
+					table.deselect(item);
+				}
+			}
+		});
+		if (isVisible && !inPaintItem()) {
+		//if (newRowHadItem && isVisible && !inPaintItem()) {
+			//invalidate();
+			// skip the visibility check and SWT thread wrapping of invalidate
+			Rectangle r = item.getBounds(0);
+			table.redraw(0, r.y, table.getClientArea().width, r.height, true);
+		}
 
     return true;
   }
@@ -698,6 +701,10 @@ BufferedTableRow
   	return setIconSize(new Point(1, iHeight));
   }
   
+  public int getHeight() {
+  	return ptIconSize == null ? 0 : ptIconSize.y;
+  }
+  
   public boolean setIconSize(Point pt) {
     ptIconSize = pt;
 
@@ -760,4 +767,68 @@ BufferedTableRow
   public Image getBackgroundImage() {
   	return imageBG;
   }
+
+	public void setSubItemCount(int i) {
+		numSubItems = i;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (item != null && !item.isDisposed()) {
+					item.setItemCount(numSubItems == 0 ? 0 : 1);
+				}
+			}
+		});
+	}
+	
+	public int getSubItemCount() {
+		return numSubItems;
+	}
+	
+	public TableItemOrTreeItem[] getSubItems() {
+		return table.getItems();
+	}
+
+	public void setExpanded(boolean b) {
+		expanded = b;
+		if (item != null && !item.isDisposed()) {
+	    if (item.getItemCount() != numSubItems) {
+	    	item.setItemCount(numSubItems);
+				Rectangle r = item.getBounds(0);
+				if (r != null) {
+					table.redraw(0, r.y, table.getClientArea().width, r.height, true);
+				}
+	    }
+	    TableItemOrTreeItem[] items = item.getItems();
+	    for (TableItemOrTreeItem subItem : items) {
+				subItem.setData("TableRow", null);
+			}
+	    item.setExpanded(b);
+		}
+	}
+	
+	public boolean isExpanded() {
+		return expanded;
+	}
+
+	/**
+	 * @return
+	 *
+	 * @since 4.4.0.5
+	 */
+	public boolean inPaintItem() {
+		if (item != null && !item.isDisposed()) {
+			InPaintInfo info = (InPaintInfo) table.getData("inPaintInfo");
+			if (info != null && item.equals(info.item)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public boolean isVisibleNoSWT() {
+		return true;  // assume the worst
+	}
+	
+	public TableItemOrTreeItem getItem() {
+		return item;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/components/BufferedWidget.java b/org/gudy/azureus2/ui/swt/components/BufferedWidget.java
index 500c60c..7cc81ec 100644
--- a/org/gudy/azureus2/ui/swt/components/BufferedWidget.java
+++ b/org/gudy/azureus2/ui/swt/components/BufferedWidget.java
@@ -32,7 +32,6 @@ public class
 BufferedWidget 
 {
 	protected Widget	widget;
-	protected Object	data;
 	
 	protected
 	BufferedWidget(
@@ -46,17 +45,4 @@ BufferedWidget
 	{
 		return( widget );
 	}
-	
-	public void
-	setData(
-		Object	d )
-	{
-		data	= d;
-	}
-	
-	public Object
-	getData()
-	{
-		return( data );
-	}
 }
diff --git a/org/gudy/azureus2/ui/swt/components/CompositeMinSize.java b/org/gudy/azureus2/ui/swt/components/CompositeMinSize.java
new file mode 100644
index 0000000..f4a5968
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/components/CompositeMinSize.java
@@ -0,0 +1,96 @@
+package org.gudy.azureus2.ui.swt.components;
+
+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.Composite;
+
+import org.gudy.azureus2.core3.util.Debug;
+
+public class CompositeMinSize
+	extends Composite
+{
+	int minWidth = SWT.DEFAULT;
+	int minHeight = SWT.DEFAULT;
+
+	public CompositeMinSize(Composite parent, int style) {
+		super(parent, style);
+	}
+
+	public void setMinSize(Point pt) {
+		minWidth = pt.x;
+		minHeight = pt.y;
+	}
+	
+	public Point computeSize(int wHint, int hHint, boolean changed) {
+		try {
+			Point size = super.computeSize(wHint, hHint, changed);
+			return betterComputeSize(this, size, wHint, hHint, changed);
+		} catch (Throwable t) {
+			Debug.out(t);
+			return new Point(wHint == -1 ? 10 : wHint, hHint == -1 ? 10
+					: hHint);
+		}
+	}
+	
+	public Point computeSize(int wHint, int hHint) {
+		try {
+			Point size = super.computeSize(wHint, hHint);
+			return betterComputeSize(this, size, wHint, hHint);
+		} catch (Throwable t) {
+			Debug.out(t);
+			return new Point(wHint == -1 ? 10 : wHint, hHint == -1 ? 10
+					: hHint);
+		}
+	}
+
+	protected Point betterComputeSize(Composite c, Point size, int wHint,
+			int hHint) {
+		if (c.getChildren().length == 0 && (size.x == 64 || size.y == 64)) {
+			Object ld = c.getLayoutData();
+			if (ld instanceof FormData) {
+				FormData fd = (FormData) ld;
+				if (fd.width != 0 && fd.height != 0) {
+					Rectangle trim = c.computeTrim (0, 0, fd.width, fd.height);
+					return new Point(trim.width, trim.height);
+				}
+			}
+			return new Point(1, 1);
+		}
+		if (size.x == 0 || size.y == 0) {
+			return size;
+		}
+		if (minWidth > 0 && size.x < minWidth) {
+			size.x = minWidth;
+		}
+		if (minHeight > 0 && size.y < minHeight) {
+			size.y = minHeight;
+		}
+		return size;
+	}
+
+	protected Point betterComputeSize(Composite c, Point size, int wHint, int hHint, boolean changed) {
+		if (c.getChildren().length == 0 && (size.x == 64 || size.y == 64)) {
+			Object ld = c.getLayoutData();
+			if (ld instanceof FormData) {
+				FormData fd = (FormData) ld;
+				if (fd.width != 0 && fd.height != 0) {
+					Rectangle trim = c.computeTrim (0, 0, fd.width, fd.height);
+					return new Point(trim.width, trim.height);
+				}
+			}
+			return new Point(1, 1);
+		}
+		if (size.x == 0 || size.y == 0) {
+			return size;
+		}
+		if (minWidth > 0 && size.x < minWidth) {
+			size.x = minWidth;
+		}
+		if (minHeight > 0 && size.y < minHeight) {
+			size.y = minHeight;
+		}
+		return size;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/components/ControlUtils.java b/org/gudy/azureus2/ui/swt/components/ControlUtils.java
deleted file mode 100644
index 8e25124..0000000
--- a/org/gudy/azureus2/ui/swt/components/ControlUtils.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.gudy.azureus2.ui.swt.components;
-
-/*
- * Created on 8-Feb-2005
- * Created by James Yeh
- * 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.
- *
- */
-
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-
-/**
- * General utility methods for SWT controls and components
- * @version 1.0
- * @author James Yeh
- * @deprecated JFace has higher-level classes and fields to cover this
- */
-public final class ControlUtils
-{
-    private static boolean smallOSXControl = COConfigurationManager.getBooleanParameter("enable_small_osx_fonts");
-
-    /**
-     * <p>Gets the margin between buttons</p>
-     * <p>The margin may vary between platforms, as specified by their guidelines</p>
-     * @return Margin
-     */
-    public static int getButtonMargin()
-    {
-        if(Constants.isOSX)
-            return (smallOSXControl) ? 10 : 12;
-        else if(Constants.isWindows)
-            return 6;
-        else
-            return 6; // this is gnome's
-    }
-
-    /**
-     * <p>Gets the minimum width of a button in a dialog (usually for alerts)</p>
-     * <p>The size may vary between platforms, as specified by their guidelines</p>
-     * @return Width
-     */
-    public static int getDialogButtonMinWidth()
-    {
-        if(Constants.isOSX)
-            return 90;
-        else
-            return 70;
-    }
-}
diff --git a/org/gudy/azureus2/ui/swt/components/CustomTableTooltipHandler.java b/org/gudy/azureus2/ui/swt/components/CustomTableTooltipHandler.java
deleted file mode 100644
index 683ed49..0000000
--- a/org/gudy/azureus2/ui/swt/components/CustomTableTooltipHandler.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Created on Oct 21, 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.ui.swt.components;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Point;
-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.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableItem;
-
-public class 
-CustomTableTooltipHandler 
-	implements Listener
-{
-	Shell toolTipShell = null;
-
-	Shell mainShell = null;
-
-	Label toolTipLabel = null;
-
-	private final Table table;
-
-	/**
-	 * Initialize
-	 */
-	public CustomTableTooltipHandler(
-		Table _table) 
-	{
-		table = _table;
-		mainShell = table.getShell();
-
-		table.addListener(SWT.Dispose, this);
-		table.addListener(SWT.KeyDown, this);
-		table.addListener(SWT.MouseMove, this);
-		table.addListener(SWT.MouseHover, this);
-		mainShell.addListener(SWT.Deactivate, this);
-		table.addListener(SWT.Deactivate, this);
-		
-		table.setToolTipText( "" );	// disable native tooltip
-	}
-
-	public void handleEvent(Event event) {
-		switch (event.type) {
-			case SWT.MouseHover: {
-				if (toolTipShell != null && !toolTipShell.isDisposed())
-					toolTipShell.dispose();
-
-				TableItem item = table.getItem( new Point( event.x, event.y ));
-				
-				if (item == null)
-					return;
-				
-				Object oToolTip = item.getData( "tooltip" );
-				
-				if ( oToolTip == null ){
-				
-					oToolTip = item.getText(0);
-				}
-				
-				// TODO: support composite, image, etc
-				if (oToolTip == null || !(oToolTip instanceof String))
-					return;
-				String sToolTip = (String) oToolTip;
-
-				Display d = table.getDisplay();
-				if (d == null)
-					return;
-
-				// We don't get mouse down notifications on trim or borders..
-				toolTipShell = new Shell(table.getShell(), SWT.ON_TOP);
-				FillLayout f = new FillLayout();
-				try {
-					f.marginWidth = 3;
-					f.marginHeight = 1;
-				} catch (NoSuchFieldError e) {
-					/* Ignore for Pre 3.0 SWT.. */
-				}
-				toolTipShell.setLayout(f);
-				toolTipShell.setBackground(d.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-
-				toolTipLabel = new Label(toolTipShell, SWT.WRAP);
-				toolTipLabel.setForeground(d.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
-				toolTipLabel.setBackground(d.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
-				//toolTipShell.setData("TableCellSWT", item);
-				toolTipLabel.setText(sToolTip.replaceAll("&", "&&"));
-				// compute size on label instead of shell because label
-				// calculates wrap, while shell doesn't
-				Point size = toolTipLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-				if (size.x > 600) {
-					size = toolTipLabel.computeSize(600, SWT.DEFAULT, true);
-				}
-				size.x += toolTipShell.getBorderWidth() * 2 + 2;
-				size.y += toolTipShell.getBorderWidth() * 2;
-				try {
-					size.x += toolTipShell.getBorderWidth() * 2 + (f.marginWidth * 2);
-					size.y += toolTipShell.getBorderWidth() * 2 + (f.marginHeight * 2);
-				} catch (NoSuchFieldError e) {
-					/* Ignore for Pre 3.0 SWT.. */
-				}
-				Point pt = table.toDisplay(event.x, event.y);
-				Rectangle displayRect;
-				try {
-					displayRect = table.getMonitor().getClientArea();
-				} catch (NoSuchMethodError e) {
-					displayRect = table.getDisplay().getClientArea();
-				}
-				if (pt.x + size.x > displayRect.x + displayRect.width) {
-					pt.x = displayRect.x + displayRect.width - size.x;
-				}
-
-				if (pt.y + size.y > displayRect.y + displayRect.height) {
-					pt.y -= size.y + 2;
-				} else {
-					pt.y += 21;
-				}
-
-				if (pt.y < displayRect.y)
-					pt.y = displayRect.y;
-
-				toolTipShell.setBounds(pt.x, pt.y, size.x, size.y);
-				toolTipShell.setVisible(true);
-
-				break;
-			}
-
-			case SWT.Dispose:
-				if (mainShell != null && !mainShell.isDisposed())
-					mainShell.removeListener(SWT.Deactivate, this);
-				if (table != null && !table.isDisposed())
-					mainShell.removeListener(SWT.Deactivate, this);
-				// fall through
-
-			default:
-				if (toolTipShell != null) {
-					toolTipShell.dispose();
-					toolTipShell = null;
-					toolTipLabel = null;
-				}
-				break;
-		} // switch
-	} // handlEvent()
-}
diff --git a/org/gudy/azureus2/ui/swt/components/DoubleBufferedLabel.java b/org/gudy/azureus2/ui/swt/components/DoubleBufferedLabel.java
new file mode 100644
index 0000000..e8efae8
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/components/DoubleBufferedLabel.java
@@ -0,0 +1,184 @@
+/*
+ * Created on Jan 9, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.components;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+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.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+
+public class 
+DoubleBufferedLabel 
+	extends Canvas implements PaintListener
+{
+	private String text = "";
+
+	public DoubleBufferedLabel(
+		Composite 	parent, 
+		int 		style ) 
+	{
+		super( parent, style | SWT.DOUBLE_BUFFERED );
+
+			// only support GridLayout I'm afraid...
+				
+		GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER | GridData.VERTICAL_ALIGN_FILL);
+		
+		setLayoutData(gridData);
+	
+		addPaintListener(this);
+	}
+	
+	public void
+	setLayoutData(
+		Object	ld )
+	{
+		if ( ld instanceof GridData ){
+			
+			GridData gd = (GridData)ld;
+			
+				// need to ensure we have the right vertical align
+			
+			gd.verticalAlignment	= 4;
+		}
+		
+		super.setLayoutData( ld );
+	}
+	
+	public void 
+	paintControl(
+		PaintEvent e) 
+	{
+		e.gc.setAdvanced(true);
+
+		Rectangle clientArea = getClientArea();
+
+		GCStringPrinter sp = 
+			new GCStringPrinter(e.gc, getText(), clientArea, true, true, SWT.LEFT);
+
+		sp.printString(e.gc, clientArea, SWT.LEFT);
+	}
+
+
+	public Point 
+	computeSize(
+		int wHint, 
+		int hHint)
+	{
+		return computeSize(wHint, hHint, true);
+	}
+
+	public Point 
+	computeSize(
+		int 	wHint, 
+		int 	hHint, 
+		boolean changed ) 
+	{
+		try {
+			Point pt = computeSize(wHint, hHint, changed, false);
+
+			return pt;
+			
+		} catch (Throwable t){
+			
+			Debug.out("Error while computing size for DoubleBufferedLabel with text:"
+					+ getText() + "; " + t.toString());
+			
+			return new Point(0, 0);
+		}
+	}
+
+	public Point 
+	computeSize(
+		int 	wHint, 
+		int 	hHint, 
+		boolean changed, 
+		boolean realWidth ) 
+	{
+		if (!isVisible()){
+			
+			return (new Point(0, 0));
+		}
+
+		if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
+			return new Point(wHint, hHint);
+		}
+		Point pt = new Point(wHint, hHint);
+
+		Point lastSize = new Point(0, 0);
+
+
+
+		GC gc = new GC(this);
+		
+		GCStringPrinter sp = new GCStringPrinter(gc, getText(), new Rectangle(0,
+				0, 10000, 20), true, true, SWT.LEFT);
+		
+		sp.calculateMetrics();
+		
+		Point lastTextSize = sp.getCalculatedSize();
+		
+		gc.dispose();
+
+		lastSize.x += lastTextSize.x + 10;
+		lastSize.y = Math.max(lastSize.y, lastTextSize.y);
+
+		if (wHint == SWT.DEFAULT) {
+			pt.x = lastSize.x;
+		}
+		if (hHint == SWT.DEFAULT) {
+			pt.y = lastSize.y;
+		}
+
+		return pt;
+	}
+
+	public String 
+	getText() 
+	{
+		return text;
+	}
+
+	public void 
+	setText(
+		String text) 
+	{
+		if (text == null){
+			text = "";
+		}
+		
+		if (text.equals(getText())){
+			return;
+		}
+		
+		this.text = text;
+
+		redraw();
+	}
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/components/InPaintInfo.java b/org/gudy/azureus2/ui/swt/components/InPaintInfo.java
new file mode 100644
index 0000000..d3d4e43
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/components/InPaintInfo.java
@@ -0,0 +1,40 @@
+/**
+ * Created on Feb 4, 2011
+ *
+ * Copyright 2010 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.components;
+
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Item;
+
+/**
+ * @author TuxPaper
+ * @created Feb 4, 2011
+ *
+ */
+public class InPaintInfo
+{
+	public Item item;
+	public int curCellIndex;
+	public Rectangle curCellBounds;
+
+	public InPaintInfo(Item item, int curCellIndex, Rectangle curCellBounds) {
+		this.item = item;
+		this.curCellIndex = curCellIndex;
+		this.curCellBounds = curCellBounds;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/components/LinkLabel.java b/org/gudy/azureus2/ui/swt/components/LinkLabel.java
index cf945ec..53122b7 100644
--- a/org/gudy/azureus2/ui/swt/components/LinkLabel.java
+++ b/org/gudy/azureus2/ui/swt/components/LinkLabel.java
@@ -32,12 +32,11 @@ import org.eclipse.swt.widgets.Label;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 
 public class 
 LinkLabel 
 {
-	
+	private final Label	linkLabel;
 	public
 	LinkLabel(
 		Composite	composite,
@@ -54,12 +53,18 @@ LinkLabel
 		String		resource,
 		String		link )
 	{
-	    Label linkLabel = new Label(composite, SWT.NULL);
+	    linkLabel = new Label(composite, SWT.NULL);
 	    Messages.setLanguageText(linkLabel,resource);
 	    linkLabel.setLayoutData( gridData );
 	    makeLinkedLabel(linkLabel, link);
 	}
 	
+	public Label
+	getlabel()
+	{
+		return( linkLabel );
+	}
+	
 	/**
 	 * Alters a given label to make it appear like a launchable
 	 * link. This should preferably be done after all other changes
@@ -73,9 +78,9 @@ LinkLabel
 		// We only set a tooltip if one isn't set already and it isn't
 		// identical to the label text.
 		if (tooltip == null && !hyperlink.equals(label.getText())) {
-			label.setToolTipText(hyperlink);
+			label.setToolTipText(hyperlink==null?null:hyperlink.replaceAll("&", "&&"));
 		}
-	    label.setCursor(Cursors.handCursor);
+	    label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 	    label.setForeground(Colors.blue);
 	    label.addMouseListener(new MouseAdapter() {
 	      public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/components/graphics/PieUtils.java b/org/gudy/azureus2/ui/swt/components/graphics/PieUtils.java
index 328cbb2..f31eb2e 100644
--- a/org/gudy/azureus2/ui/swt/components/graphics/PieUtils.java
+++ b/org/gudy/azureus2/ui/swt/components/graphics/PieUtils.java
@@ -24,8 +24,7 @@ package org.gudy.azureus2.ui.swt.components.graphics;
 
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
+
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 
 /**
@@ -34,18 +33,6 @@ import org.gudy.azureus2.ui.swt.mainwindow.Colors;
  */
 public class PieUtils {
 
-  private static Image computePie(Display display,int width,int height,int percent) {
-    Image image = new Image(display,width,height);
-    GC gcImage = new GC(image);
-    gcImage.setForeground(Colors.blue);
-    int angle = (percent * 360) / 100;
-    gcImage.setBackground(Colors.blues[Colors.BLUES_MIDDARK]);
-    gcImage.fillArc(0,0,width,height,90-angle,angle);
-    gcImage.drawOval(0 , 0 , width-1, height-1);
-    gcImage.dispose();
-    return image;
-  }
-  
   public static void drawPie(GC gc,int x, int y,int width,int height,int percent) {
     Color background = gc.getBackground();
     gc.setForeground(Colors.blue);
diff --git a/org/gudy/azureus2/ui/swt/components/graphics/PingGraphic.java b/org/gudy/azureus2/ui/swt/components/graphics/PingGraphic.java
index 6db6bbb..daa7cc0 100644
--- a/org/gudy/azureus2/ui/swt/components/graphics/PingGraphic.java
+++ b/org/gudy/azureus2/ui/swt/components/graphics/PingGraphic.java
@@ -121,8 +121,9 @@ public class PingGraphic extends ScaledGraphic implements ParameterListener {
   }
   
   public void refresh() {  
-    if(drawCanvas == null || drawCanvas.isDisposed())
+    if(drawCanvas == null || drawCanvas.isDisposed()){
       return;
+		}
     
     Rectangle bounds = drawCanvas.getClientArea();
     if(bounds.height < 30 || bounds.width  < 100 || bounds.width > 2000 || bounds.height > 2000)
@@ -140,17 +141,24 @@ public class PingGraphic extends ScaledGraphic implements ParameterListener {
 	    drawChart(sizeChanged);
     }
     
-    GC gc = new GC(drawCanvas);
-    gc.drawImage(bufferImage,bounds.x,bounds.y);
-    gc.dispose();    
+    if (bufferImage != null && !bufferImage.isDisposed()) {
+      GC gc = new GC(drawCanvas);
+      gc.drawImage(bufferImage,bounds.x,bounds.y);
+      gc.dispose();
+    }
   }
   
   protected void drawChart(boolean sizeChanged) {
    try{
    	  this_mon.enter();
-   		
+
+   	  // should create bufferscale
       drawScale(sizeChanged);
-      
+
+    	if (bufferScale == null || bufferScale.isDisposed()) {
+    		return;
+    	}
+
       Rectangle bounds = drawCanvas.getClientArea();    
         
       //If bufferedImage is not null, dispose it
diff --git a/org/gudy/azureus2/ui/swt/components/graphics/Plot3D.java b/org/gudy/azureus2/ui/swt/components/graphics/Plot3D.java
index 91bbdf0..9b6338f 100644
--- a/org/gudy/azureus2/ui/swt/components/graphics/Plot3D.java
+++ b/org/gudy/azureus2/ui/swt/components/graphics/Plot3D.java
@@ -42,6 +42,8 @@ public class
 Plot3D
 	implements Graphic, ParameterListener
 {
+	private int			Z_MAX		= Integer.MAX_VALUE;
+	
 	private Canvas		canvas;
 	
 	private String			title	= "";
@@ -199,6 +201,7 @@ Plot3D
 				}
 			}
 			
+			max_z = Math.min( max_z, Z_MAX );
 			
 			int usable_width 	= bounds.width - PAD_LEFT - PAD_RIGHT;
 			int usable_height	= bounds.height - PAD_TOP - PAD_BOTTOM;
@@ -280,13 +283,15 @@ Plot3D
 				
 				int[]	entry = (int[])values[i];
 				
+				int	z = Math.min( entry[2], Z_MAX );
+				
 				int	draw_x = (int)( x_ratio * entry[0] );
 				int	draw_y = (int)( y_ratio * entry[1] );
-				int	draw_z = (int)( z_ratio * entry[2] );
+				int	draw_z = (int)( z_ratio * z );
 				
 				draw_x += draw_y / ANGLE_TAN;
 				
-				image.setForeground( colours[(int)(((float)entry[2]/max_z)*(colours.length-1))]);
+				image.setForeground( colours[(int)(((float)z/max_z)*(colours.length-1))]);
 			
 				image.drawLine( 
 						PAD_LEFT + draw_x, 
@@ -351,6 +356,13 @@ Plot3D
 		}
 	}
 	 
+	public void
+	setMaxZ(
+		int		m )
+	{
+		Z_MAX = m;
+	}
+	
 	public void 
 	parameterChanged(
 		String parameter) 
diff --git a/org/gudy/azureus2/ui/swt/components/graphics/SpeedGraphic.java b/org/gudy/azureus2/ui/swt/components/graphics/SpeedGraphic.java
index 792c86a..6fa7f44 100644
--- a/org/gudy/azureus2/ui/swt/components/graphics/SpeedGraphic.java
+++ b/org/gudy/azureus2/ui/swt/components/graphics/SpeedGraphic.java
@@ -138,6 +138,10 @@ public class SpeedGraphic extends ScaledGraphic implements ParameterListener {
     });
   }
   
+  public static SpeedGraphic getInstance(ValueFormater formatter) {
+	    return new SpeedGraphic(new Scale(),formatter);
+	  }
+  
   public void addIntsValue(int[] new_values) {  	
     try{
     	this_mon.enter();
diff --git a/org/gudy/azureus2/ui/swt/components/graphics/Test.java b/org/gudy/azureus2/ui/swt/components/graphics/Test.java
deleted file mode 100644
index 2b92e5e..0000000
--- a/org/gudy/azureus2/ui/swt/components/graphics/Test.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Created on 11 oct. 2004
- * Created by Olivier Chalouhi
- * 
- * 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.components.graphics;
-
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class Test {
-
-  final static int IMAGES_TO_CREATE = 100;
-  
-  public static void main (String [] args) {
-  	Display display = new Display ();
-  	Image[] images = new Image[IMAGES_TO_CREATE];
-  	for(int i = 0 ; i < IMAGES_TO_CREATE ; i++) {
-  	  images[i] = new Image(display,800,600);
-  	}
-  	for(int i = 0 ; i < IMAGES_TO_CREATE ; i++) {
-  	  images[i].dispose();
-  	}
-  	display.dispose ();
-  }
-  
-}
diff --git a/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java b/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
index ef99036..dc5ae35 100644
--- a/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
+++ b/org/gudy/azureus2/ui/swt/components/shell/ShellFactory.java
@@ -144,10 +144,11 @@ public final class ShellFactory
 
 		if (Constants.isOSX) {
 			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (uiFunctions == null)
-				throw new IllegalStateException("Main window is not initialized yet");
-
-			uiFunctions.createMainMenu(toRegister);
+			if (uiFunctions == null) {
+				System.err.println("Main window is not initialized yet");
+			} else {
+				uiFunctions.createMainMenu(toRegister);
+			}
 		}
 
 		ShellManager.sharedManager().addWindow(toRegister);
@@ -267,7 +268,9 @@ public final class ShellFactory
 				firstShellWithStyle.setVisible(true);
 				firstShellWithStyle.forceActive();
 			} else {
-				super.open();
+				if (!isDisposed()) {
+					super.open();
+				}
 			}
 		}
 	}
diff --git a/org/gudy/azureus2/ui/swt/components/shell/ShellManager.java b/org/gudy/azureus2/ui/swt/components/shell/ShellManager.java
index 29f8ae3..2ba4fb5 100644
--- a/org/gudy/azureus2/ui/swt/components/shell/ShellManager.java
+++ b/org/gudy/azureus2/ui/swt/components/shell/ShellManager.java
@@ -46,7 +46,7 @@ public class ShellManager
 {
     private static ShellManager instance;
 
-    private final Collection shells = new ArrayList();
+    private final Collection<Shell> shells = new ArrayList<Shell>();
     private final List addHandlers = new LinkedList();
     private final List removeHandlers = new LinkedList();
 
@@ -113,7 +113,7 @@ public class ShellManager
      * <p><b>Note</b>: This method must be invoked by the SWT display thread</p>
      * @return The iterator
      */
-    public final Iterator getWindows()
+    public final Iterator<Shell> getWindows()
     {
         return shells.iterator();
     }
diff --git a/org/gudy/azureus2/ui/swt/config/LinkParameter.java b/org/gudy/azureus2/ui/swt/config/LinkParameter.java
index 41020fe..6454212 100644
--- a/org/gudy/azureus2/ui/swt/config/LinkParameter.java
+++ b/org/gudy/azureus2/ui/swt/config/LinkParameter.java
@@ -34,7 +34,6 @@ import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 
 
 public class 
@@ -51,7 +50,7 @@ LinkParameter
   	super(name_resource);
     link_label = new Label(composite, SWT.NULL);
     Messages.setLanguageText(link_label, name_resource);
-    link_label.setCursor(Cursors.handCursor);
+    link_label.setCursor(link_label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
     link_label.setForeground(Colors.blue);
     link_label.addMouseListener(new MouseAdapter() {
       public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/config/Parameter.java b/org/gudy/azureus2/ui/swt/config/Parameter.java
index c30d3db..c328d1a 100644
--- a/org/gudy/azureus2/ui/swt/config/Parameter.java
+++ b/org/gudy/azureus2/ui/swt/config/Parameter.java
@@ -94,6 +94,16 @@ Parameter
  		}
 	}
 	
+	public void
+	setEnabled(
+		boolean	enabled )
+	{
+		for ( Control c: getControls()){
+			
+			c.setEnabled(enabled);
+		}
+	}
+	
 	public boolean
 	isDisposed()
 	{
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java b/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
index 9e78c73..e6ba89b 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/ConfigureWizard.java
@@ -35,15 +35,24 @@ import com.aelitis.azureus.ui.UserPrompterResultListener;
  */
 public class ConfigureWizard extends Wizard {
 
+	  public static final int WIZARD_MODE_FULL				= 0;
+	  public static final int WIZARD_MODE_SPEED_TEST_AUTO	= 1;
+	  public static final int WIZARD_MODE_SPEED_TEST_MANUAL	= 2;
+  
+	private int wizard_mode;
+	
   //Transfer settings
-  int upSpeed = 4;
-  int maxUpSpeed = 40;
-  int maxActiveTorrents = 7;
-  int maxDownloads = 5;
-  int nbUploadsPerTorrent = 4;
+
+  private int connectionUploadLimit;
+  private boolean uploadLimitManual;
+  private int uploadLimit;
+  
+  int maxActiveTorrents;
+  int maxDownloads;
   
   //Server / NAT Settings
   int serverTCPListenPort = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
+  int serverUDPListenPort = COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
   //Files / Torrents
   private String 	_dataPath;
   private boolean 	_dataPathChanged;
@@ -54,10 +63,14 @@ public class ConfigureWizard extends Wizard {
 
   public 
   ConfigureWizard(
-		boolean modal) 
+	  boolean 	_modal,
+	  int		_wizard_mode ) 
   {
-    super("configureWizard.title",modal);
-    IWizardPanel panel = new LanguagePanel(this,null);
+    super("configureWizard.title",_modal);
+    
+    wizard_mode = _wizard_mode;
+    
+    IWizardPanel panel = wizard_mode==WIZARD_MODE_FULL?new LanguagePanel(this,null):new TransferPanel2( this, null );
     try  {
       torrentPath = COConfigurationManager.getDirectoryParameter("General_sDefaultTorrent_Directory");
     } catch(Exception e) {
@@ -77,8 +90,10 @@ public class ConfigureWizard extends Wizard {
   
   public void onClose() {
 		try {
-			if (!completed
-					&& !COConfigurationManager.getBooleanParameter("Wizard Completed")) {
+			if (	!completed && 
+					wizard_mode != WIZARD_MODE_SPEED_TEST_AUTO && 
+					!COConfigurationManager.getBooleanParameter("Wizard Completed")){
+				
 				MessageBoxShell mb = new MessageBoxShell(
 						MessageText.getString("wizard.close.confirmation"),
 						MessageText.getString("wizard.close.message"), new String[] {
@@ -122,4 +137,74 @@ public class ConfigureWizard extends Wizard {
   {
 	  return( _dataPathChanged );
   }
+  
+  protected void
+  setConnectionUploadLimit(
+	int		rate,
+	boolean	is_manual )
+  {
+	  connectionUploadLimit = rate;
+	  
+	  if ( connectionUploadLimit != 0 ){
+
+		  uploadLimitManual = is_manual;
+		  
+		  uploadLimit = (connectionUploadLimit/5)*4;
+		  
+		  uploadLimit = (uploadLimit/1024)*1024;
+		  
+		  if ( uploadLimit < 5*1024 ){
+			  
+			  uploadLimit = 5*1024;
+		  }
+		  
+		  int nbMaxActive = (int) (Math.pow(uploadLimit/1024,0.34) * 0.92);
+		  int nbMaxUploads = (int) (Math.pow(uploadLimit/1024,0.25) * 1.68);
+		  int nbMaxDownloads = (nbMaxActive * 4) / 5;
+
+		  if (nbMaxDownloads == 0){
+			  nbMaxDownloads = 1;
+		  }
+		  
+		  if (nbMaxUploads > 50){
+			  nbMaxUploads = 50;
+		  }
+
+		  maxActiveTorrents = nbMaxActive;
+		  maxDownloads = nbMaxDownloads;
+		  
+	  }else{	  
+		  
+		  	// reset to defaults
+		  
+		  uploadLimitManual	= false;
+		  uploadLimit 		= 0;
+		  maxActiveTorrents	= 0;
+		  maxDownloads		= 0;
+	  }
+  }
+  
+  protected int
+  getConnectionUploadLimit()
+  {
+	  return( connectionUploadLimit );
+  }
+  
+  protected int
+  getUploadLimit()
+  {
+	  return( uploadLimit );
+  }
+  
+  protected boolean
+  isUploadLimitManual()
+  {
+	  return( uploadLimitManual );
+  }
+  
+  protected int
+  getWizardMode()
+  {
+	  return( wizard_mode );
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/FinishPanel.java b/org/gudy/azureus2/ui/swt/config/wizard/FinishPanel.java
index 65715ed..c867e45 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/FinishPanel.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/FinishPanel.java
@@ -28,16 +28,22 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.speedmanager.SpeedManager;
+import com.aelitis.azureus.core.speedmanager.SpeedManagerLimitEstimate;
+
 /**
  * @author Olivier
  * 
  */
-public class FinishPanel extends AbstractWizardPanel {
+public class FinishPanel extends AbstractWizardPanel<ConfigureWizard> {
 
   public FinishPanel(ConfigureWizard wizard, IWizardPanel previous) {
     super(wizard, previous);
@@ -67,29 +73,55 @@ public class FinishPanel extends AbstractWizardPanel {
   }
 
   public void finish() {
-    ConfigureWizard cfWizard = ((ConfigureWizard)wizard);
-    COConfigurationManager.setParameter("Max Upload Speed KBs",cfWizard.maxUpSpeed);
-    COConfigurationManager.setParameter("Max Uploads",cfWizard.nbUploadsPerTorrent);
-    COConfigurationManager.setParameter("max active torrents",cfWizard.maxActiveTorrents);
-    COConfigurationManager.setParameter("max downloads",cfWizard.maxDownloads);
-    COConfigurationManager.setParameter("TCP.Listen.Port",cfWizard.serverTCPListenPort);
-    COConfigurationManager.setParameter("UDP.Listen.Port",cfWizard.serverTCPListenPort);
-    COConfigurationManager.setParameter("UDP.NonData.Listen.Port",cfWizard.serverTCPListenPort);
-    //COConfigurationManager.setParameter("Low Port",cfWizard.serverMinPort);
-	//COConfigurationManager.setParameter("High Port",cfWizard.serverMaxPort);
-	//COConfigurationManager.setParameter("Server.shared.port",cfWizard.serverSharePort);
-    COConfigurationManager.setParameter("General_sDefaultTorrent_Directory",cfWizard.torrentPath);
-    //COConfigurationManager.setParameter("Use Resume",cfWizard.fastResume);
-    
-    if ( cfWizard.hasDataPathChanged()){
-    	COConfigurationManager.setParameter( "Use default data dir", true );
-    	COConfigurationManager.setParameter( "Default save path", cfWizard.getDataPath());
+	  
+	wizard.completed = true;
+
+    int	upLimit = wizard.getUploadLimit();
+    if (upLimit > 0 ){
+    	COConfigurationManager.setParameter( TransferSpeedValidator.AUTO_UPLOAD_ENABLED_CONFIGKEY, false );
+    	COConfigurationManager.setParameter( TransferSpeedValidator.AUTO_UPLOAD_SEEDING_ENABLED_CONFIGKEY, false );
+    	COConfigurationManager.setParameter( "Max Upload Speed KBs", upLimit/1024 );
+    	COConfigurationManager.setParameter( "enable.seedingonly.upload.rate", false );
+	    COConfigurationManager.setParameter( "max active torrents",wizard.maxActiveTorrents);
+	    COConfigurationManager.setParameter( "max downloads",wizard.maxDownloads);
+	    
+	    try{
+	    	SpeedManager sm = AzureusCoreFactory.getSingleton().getSpeedManager();
+	    
+	    	boolean is_manual = wizard.isUploadLimitManual();
+	    	
+	    	sm.setEstimatedUploadCapacityBytesPerSec( upLimit, is_manual?SpeedManagerLimitEstimate.TYPE_MANUAL:SpeedManagerLimitEstimate.TYPE_MEASURED );
+	    	
+	    }catch( Throwable e ){
+	    	
+	    	Debug.out( e );
+	    }
+	    
+	    	// toggle to ensure listeners get the message that they should recalc things
+	    
+        COConfigurationManager.setParameter( "Auto Adjust Transfer Defaults", false );
+        COConfigurationManager.setParameter( "Auto Adjust Transfer Defaults", true );
+    }
+   	
+    if ( wizard.getWizardMode() != ConfigureWizard.WIZARD_MODE_FULL ){
+    	
+    	wizard.close();
+    	
+    }else{
+	    COConfigurationManager.setParameter("TCP.Listen.Port",wizard.serverTCPListenPort);
+	    COConfigurationManager.setParameter("UDP.Listen.Port",wizard.serverUDPListenPort);
+	    COConfigurationManager.setParameter("UDP.NonData.Listen.Port",wizard.serverUDPListenPort);
+	    COConfigurationManager.setParameter("General_sDefaultTorrent_Directory",wizard.torrentPath);
+	    
+	    if ( wizard.hasDataPathChanged()){
+	    	COConfigurationManager.setParameter( "Use default data dir", true );
+	    	COConfigurationManager.setParameter( "Default save path", wizard.getDataPath());
+	    }
+	    
+	    COConfigurationManager.setParameter("Wizard Completed",true);
+	    COConfigurationManager.save();
+	    wizard.switchToClose();
     }
-    
-    COConfigurationManager.setParameter("Wizard Completed",true);
-    COConfigurationManager.save();
-    wizard.switchToClose();
-    cfWizard.completed = true;
   }
   
   public boolean isPreviousEnabled() {
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/LanguagePanel.java b/org/gudy/azureus2/ui/swt/config/wizard/LanguagePanel.java
index 55d9f93..efaa704 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/LanguagePanel.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/LanguagePanel.java
@@ -74,7 +74,7 @@ public class LanguagePanel extends AbstractWizardPanel {
 		final List lstLanguage = new List(rootPanel, SWT.BORDER | SWT.V_SCROLL
 				| SWT.SINGLE);
 		gridData = new GridData(GridData.FILL_BOTH);
-		gridData.heightHint = 200;
+		gridData.heightHint = 350;
 		lstLanguage.setLayoutData(gridData);
 
 		final Locale[] locales = MessageText.getLocales(true);
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/NatPanel.java b/org/gudy/azureus2/ui/swt/config/wizard/NatPanel.java
index cc6164c..3240a98 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/NatPanel.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/NatPanel.java
@@ -21,6 +21,7 @@
 
 package org.gudy.azureus2.ui.swt.config.wizard;
 
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.layout.GridData;
@@ -31,6 +32,7 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.ipchecker.natchecker.NatChecker;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AEThread;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
 import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
@@ -39,6 +41,8 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProgressListener;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProtocol;
 
 /**
  * @author Olivier
@@ -47,61 +51,115 @@ import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 public class NatPanel extends AbstractWizardPanel {
 
   StyledText textResults;
-  Checker checker;
 
-  Button bTest;
-  Button bCancel;
+  Button bTestTCP,bTestUDP;
 
  
-  public class Checker extends AEThread {
-
-    //private int lowPort;
-    //private int highPort;
-    private int TCPListenPort;
-
-    private boolean bContinue;
-
-		private final AzureusCore core;
-
-    //public Checker(int lowPort, int highPort) {
-    public Checker(AzureusCore core, int tcp_listen_port) {
-      super("NAT Checker");
-			this.core = core;
-      //this.lowPort = lowPort;
-      //this.highPort = highPort;
-      this.TCPListenPort = tcp_listen_port;
-      this.bContinue = true;
-    }
-
-    public void runSupport() {
-      //if (lowPort <= highPort && (highPort-lowPort < 10)) {
-        //for (int port = lowPort; port <= highPort && bContinue; port++) {
-          printMessage(MessageText.getString("configureWizard.nat.testing") + " " + TCPListenPort + " ... ");
-          NatChecker checker = new NatChecker(core, NetworkAdmin.getSingleton().getMultiHomedServiceBindAddresses(true)[0], TCPListenPort, false );
-          switch (checker.getResult()) {
-            case NatChecker.NAT_OK :
-              String	additional_info = checker.getAdditionalInfo();
-              printMessage(MessageText.getString("configureWizard.nat.ok") + "\n" + additional_info );
-              break;
-            case NatChecker.NAT_KO :
-              printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + " - " + checker.getAdditionalInfo()+".\n");
-              bContinue = false;
-              break;
-            default :
-              printMessage( "\n" + MessageText.getString("configureWizard.nat.unable") + ". \n(" + checker.getAdditionalInfo()+").\n");
-              break;
-          }
-        //}
-      //}else {
-      //  printMessage(MessageText.getString("configureWizard.nat.tooManyPorts") + "\n");
-      //}
-      enableNext();
-    }
-
-    public void stopIt() {
-      bContinue = false;
-    }
-  }
+  public class CheckerTCP extends AEThread {
+
+	  	private AzureusCore	core;
+	    private int TCPListenPort;
+	    
+	    public CheckerTCP(AzureusCore _core, int tcp_listen_port) {
+	      super("NAT Checker TCP");
+	      core		= _core;
+	      this.TCPListenPort = tcp_listen_port;
+	    }
+
+	    public void 
+	    runSupport() 
+	    {
+	    	try{
+		          printMessage(MessageText.getString("configureWizard.nat.testing") + " TCP " + TCPListenPort + " ... ");
+		          NatChecker checker = new NatChecker(core, NetworkAdmin.getSingleton().getMultiHomedServiceBindAddresses(true)[0], TCPListenPort, false);          
+		          switch (checker.getResult()) {
+		          case NatChecker.NAT_OK :
+		            printMessage( "\n" + MessageText.getString("configureWizard.nat.ok") + "\n" + checker.getAdditionalInfo());
+		            break;
+		          case NatChecker.NAT_KO :
+		            printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + " - " + checker.getAdditionalInfo()+".\n");
+		            break;
+		          default :
+		            printMessage( "\n" + MessageText.getString("configureWizard.nat.unable") + ". \n(" + checker.getAdditionalInfo()+").\n");
+		            break;
+		          }
+	    	}finally{
+	          enableNext();
+	    	}
+	    }
+	  }
+	  
+	  public class CheckerUDP extends AEThread {
+
+		    private AzureusCore	core;
+		    private int			udp_port;
+		    
+		    public CheckerUDP(AzureusCore _core, int _udp_port ){
+		      super("NAT Checker UDP");
+		      core 		= _core;
+		      udp_port	= _udp_port;
+		    }
+
+		    public void 
+		    runSupport() 
+		    {
+		    	try{
+			    	final NetworkAdmin	admin = NetworkAdmin.getSingleton();
+			    	
+					NetworkAdminProtocol[] inbound_protocols = admin.getInboundProtocols(core);
+					
+					NetworkAdminProtocol selected = null;
+					
+					for ( NetworkAdminProtocol p: inbound_protocols ){
+						
+						if ( p.getType() == NetworkAdminProtocol.PT_UDP && p.getPort() == udp_port ){
+							
+							selected = p;
+							
+							break;
+						}
+					}
+						
+					if ( selected == null ){
+						
+						selected = admin.createInboundProtocol( core, NetworkAdminProtocol.PT_UDP, udp_port );
+					}
+					
+			        if ( selected == null ){
+			        	
+			        	printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + ". \n( No UDP protocols enabled ).\n");
+			        	
+			        }else{
+			        	
+			        	printMessage(MessageText.getString("configureWizard.nat.testing") + " UDP " + udp_port + " ... ");
+						
+							try{
+								selected.test( 
+									null,
+									true,
+									new NetworkAdminProgressListener()
+									{
+										public void 
+										reportProgress(
+											String task )
+										{
+											printMessage( "\n    " + task );
+										}
+									});
+								
+					            printMessage( "\n" + MessageText.getString("configureWizard.nat.ok"));
+									
+							}catch( Throwable e ){
+								
+					            printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + ". " + Debug.getNestedExceptionMessage(e)+".\n");
+							}
+						}
+			   
+		    	}finally{
+		    		enableNext();
+		    	}
+		    }
+	  }
 
   public NatPanel(ConfigureWizard wizard, IWizardPanel previous) {
     super(wizard, previous);
@@ -133,6 +191,7 @@ public class NatPanel extends AbstractWizardPanel {
     gridData.horizontalSpan = 4;
     label.setLayoutData(gridData);
     
+    	// TCP
     
     label = new Label(panel, SWT.NULL);
     gridData = new GridData();
@@ -168,16 +227,27 @@ public class NatPanel extends AbstractWizardPanel {
       }
     });
 
-    /*
+    bTestTCP = new Button(panel, SWT.PUSH);
+    Messages.setLanguageText(bTestTCP, "configureWizard.nat.test");
+    gridData = new GridData();
+    gridData.widthHint = 70;
+    bTestTCP.setLayoutData(gridData);
+
     label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.nat.serverhigh");
+    
+    	// UDP
 
-    final Text textServerHigh = new Text(panel, SWT.BORDER);
+    label = new Label(panel, SWT.NULL);
     gridData = new GridData();
-    gridData.widthHint = 100;
-    textServerHigh.setLayoutData(gridData);
-    textServerHigh.setText("" + ((ConfigureWizard) wizard).serverMaxPort);
-    textServerHigh.addListener(SWT.Verify, new Listener() {
+    label.setLayoutData(gridData);
+    Messages.setLanguageText(label, "configureWizard.nat.server.udp_listen_port");
+
+    final Text textServerUDPListen = new Text(panel, SWT.BORDER);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.widthHint = 80;
+    textServerUDPListen.setLayoutData(gridData);
+    textServerUDPListen.setText("" + ((ConfigureWizard) wizard).serverUDPListenPort);
+    textServerUDPListen.addListener(SWT.Verify, new Listener() {
       public void handleEvent(Event e) {
         String text = e.text;
         char[] chars = new char[text.length()];
@@ -190,46 +260,27 @@ public class NatPanel extends AbstractWizardPanel {
         }
       }
     });
-    textServerHigh.addListener(SWT.Modify, new Listener() {
+    textServerUDPListen.addListener(SWT.Modify, new Listener() {
       public void handleEvent(Event e) {
-        int highPort = 0;
-        try{
-          highPort = Integer.parseInt(textServerHigh.getText());
-        } catch(Exception ignore) { }
-        ((ConfigureWizard) wizard).serverMaxPort = highPort;
+      	try {
+	        final int UDPListenPort = Integer.parseInt(textServerUDPListen.getText());
+	        ((ConfigureWizard) wizard).serverUDPListenPort = UDPListenPort;
+      	} catch (NumberFormatException ex) {
+      		// ignore
+      	}
       }
     });
 
-    final Button sharePort = new Button(panel,SWT.CHECK);
-    sharePort.setSelection(((ConfigureWizard)wizard).serverSharePort);
-    sharePort.addListener(SWT.Selection,new Listener() {
-    	public void handleEvent(Event arg0) {
-    		((ConfigureWizard)wizard).serverSharePort = sharePort.getSelection();
-    		textServerHigh.setEnabled(!((ConfigureWizard)wizard).serverSharePort);
-    	}
-    });
-    gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-    sharePort.setLayoutData(gridData);
-    
-	label = new Label(panel,SWT.NULL);
-	Messages.setLanguageText(label, "configureWizard.nat.sharePort");
-	 
-    textServerHigh.setEnabled(!((ConfigureWizard)wizard).serverSharePort);
-    */
-
-    bTest = new Button(panel, SWT.PUSH);
-    Messages.setLanguageText(bTest, "configureWizard.nat.test");
-    gridData = new GridData();
-    gridData.widthHint = 70;
-    bTest.setLayoutData(gridData);
-
-    bCancel = new Button(panel, SWT.PUSH);
-    Messages.setLanguageText(bCancel, "Button.cancel");
+    bTestUDP = new Button(panel, SWT.PUSH);
+    Messages.setLanguageText(bTestUDP, "configureWizard.nat.test");
     gridData = new GridData();
     gridData.widthHint = 70;
-    bCancel.setLayoutData(gridData);
-    bCancel.setEnabled(false);
-
+    bTestUDP.setLayoutData(gridData);
+    
+    label = new Label(panel, SWT.NULL);
+    
+    	// blah
+    
     textResults = new StyledText(panel, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP );
     gridData = new GridData(GridData.FILL_BOTH);
     gridData.heightHint = 70;
@@ -237,34 +288,43 @@ public class NatPanel extends AbstractWizardPanel {
     textResults.setLayoutData(gridData);
     textResults.setBackground(panel.getDisplay().getSystemColor(SWT.COLOR_WHITE));
 
-    bTest.addListener(SWT.Selection, new Listener() {
+    bTestTCP.addListener(SWT.Selection, new Listener() {
       public void handleEvent(Event event) {
         wizard.setNextEnabled(false);
-        bTest.setEnabled(false);
-        bCancel.setEnabled(true);
+        bTestTCP.setEnabled(false);
+        bTestUDP.setEnabled(false);
         textResults.setText("");
         CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
 				
 					public void azureusCoreRunning(AzureusCore core) {
 						ConfigureWizard cw = (ConfigureWizard) wizard;
 						
-						//int lowPort = cw.serverMinPort;
-						//int highPort = cw.serverSharePort?cw.serverMinPort:cw.serverMaxPort;
 						int TCPListenPort = cw.serverTCPListenPort;
-						checker = new Checker(core, TCPListenPort);
+						CheckerTCP checker = new CheckerTCP(core, TCPListenPort);
 						checker.start();
 					}
 				});
       }
     });
 
-    bCancel.addListener(SWT.Selection, new Listener() {
-      public void handleEvent(Event event) {
-        if (checker != null)
-          checker.stopIt();
-        bCancel.setEnabled(false);
-      }
-    });
+    bTestUDP.addListener(SWT.Selection, new Listener() {
+        public void handleEvent(Event event) {
+          wizard.setNextEnabled(false);
+          bTestTCP.setEnabled(false);
+          bTestUDP.setEnabled(false);
+          textResults.setText("");
+          CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+  				
+  					public void azureusCoreRunning(AzureusCore core) {
+  						ConfigureWizard cw = (ConfigureWizard) wizard;
+  						
+  						int UDPListenPort = cw.serverUDPListenPort;
+  						CheckerUDP checker = new CheckerUDP(core, UDPListenPort);
+  						checker.start();
+  					}
+  				});
+        }
+      });
   }
 
   public void printMessage(final String message) {
@@ -286,17 +346,19 @@ public class NatPanel extends AbstractWizardPanel {
       return;
     display.asyncExec(new AERunnable(){
       public void runSupport() {
-      	if (bTest == null || bTest.isDisposed()) {
+       	if (bTestTCP == null || bTestTCP.isDisposed()) {
+      		return;
+      	}
+     	if (bTestUDP == null || bTestUDP.isDisposed()) {
       		return;
       	}
-      	
       	if (wizard.getCurrentPanel().equals(this)) {
       		return;
       	}
 
         wizard.setNextEnabled(true);
-        bTest.setEnabled(true);
-        bCancel.setEnabled(false);
+        bTestTCP.setEnabled(true);
+        bTestUDP.setEnabled(true);
       }
     });
   }
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel.java b/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel.java
deleted file mode 100644
index f39b25b..0000000
--- a/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * File    : TransferPanel.java
- * Created : 12 oct. 2003 19:41:14
- * By      : Olivier 
- * 
- * 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.swt.config.wizard;
-
-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.ui.swt.Messages;
-import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
-import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
-
-/**
- * @author Olivier
- * 
- */
-public class TransferPanel extends AbstractWizardPanel {
-
-  Label nbMaxActive;
-  Label nbMaxDownloads;
-  Label nbMaxUploadsPerTorrent;
-
-  private static final int upRates[] =
-    {
-      0,
-      5,
-      6,
-      7,
-      8,
-      9,
-      10,
-      11,
-      12,
-      13,
-      14,
-      15,
-      20,
-      25,
-      30,
-      35,
-      40,
-      45,
-      50,
-      55,
-      60,
-      70,
-      80,
-      85,
-      90,
-      100,
-      110,
-      150,
-      200,
-      250,
-      300,
-      350,
-      400,
-      450,
-      500,
-      600,
-      700,
-      800,
-      900,
-      1000 };
-
-  public TransferPanel(ConfigureWizard wizard, IWizardPanel previous) {
-    super(wizard, previous);
-  }
-
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.wizard.IWizardPanel#show()
-   */
-  public void show() {
-    wizard.setTitle(MessageText.getString("configureWizard.transfer.title"));
-    wizard.setCurrentInfo(MessageText.getString("configureWizard.transfer.hint"));
-    Composite rootPanel = wizard.getPanel();
-    GridLayout layout = new GridLayout();
-    layout.numColumns = 1;
-    rootPanel.setLayout(layout);
-
-    Composite panel = new Composite(rootPanel, SWT.NULL);
-    GridData gridData = new GridData(GridData.FILL_BOTH);
-    panel.setLayoutData(gridData);
-    layout = new GridLayout();
-    layout.numColumns = 2;
-    panel.setLayout(layout);
-
-    Label label = new Label(panel, SWT.WRAP);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 2;
-    label.setLayoutData(gridData);
-    Messages.setLanguageText(label, "configureWizard.transfer.message");
-
-    label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.transfer.connection");
-
-    final Combo connections = new Combo(panel, SWT.SINGLE | SWT.READ_ONLY);
-    for (int i = 0; i < 8; i++) {
-      connections.add(MessageText.getString("configureWizard.transfer.connection." + i));
-    }
-
-    label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.transfer.maxUpSpeed");
-
-    final String upsLabels[] = new String[upRates.length];
-    final int upsValues[] = new int[upRates.length];
-    upsLabels[0] = MessageText.getString("ConfigView.unlimited"); //$NON-NLS-1$
-    upsValues[0] = 0;
-    for (int i = 1; i < upRates.length; i++) {
-      upsLabels[i] = " " + upRates[i] + " KB/s"; //$NON-NLS-1$ //$NON-NLS-2$
-      upsValues[i] = 1024 * upRates[i];
-    }
-    final Combo cMaxUpSpeed = new Combo(panel, SWT.SINGLE | SWT.READ_ONLY);
-    for (int i = 0; i < upRates.length; i++) {
-      cMaxUpSpeed.add(upsLabels[i]);
-    }
-
-    //final Text textMaxUpSpeed = new Text(panel, SWT.BORDER);
-    gridData = new GridData();
-    gridData.widthHint = 100;
-    cMaxUpSpeed.setLayoutData(gridData);
-
-    label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.transfer.maxActiveTorrents");
-    nbMaxActive = new Label(panel, SWT.NULL);
-    gridData = new GridData();
-    gridData.widthHint = 100;
-    nbMaxActive.setLayoutData(gridData);
-
-    label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.transfer.maxDownloads");
-    nbMaxDownloads = new Label(panel, SWT.NULL);
-    gridData = new GridData();
-    gridData.widthHint = 100;
-    nbMaxDownloads.setLayoutData(gridData);
-
-    label = new Label(panel, SWT.NULL);
-    Messages.setLanguageText(label, "configureWizard.transfer.maxUploadsPerTorrent");
-    nbMaxUploadsPerTorrent = new Label(panel, SWT.NULL);
-    gridData = new GridData();
-    gridData.widthHint = 100;
-    nbMaxUploadsPerTorrent.setLayoutData(gridData);
-
-    connections.addListener(SWT.Selection, new Listener() {
-      public void handleEvent(Event event) {
-        int index = connections.getSelectionIndex();
-        ((ConfigureWizard) wizard).upSpeed = index;
-        if (index == 0) {
-          cMaxUpSpeed.setEnabled(true);
-        }
-        else {
-          cMaxUpSpeed.setEnabled(false);
-          int upSpeeds[] = { 0, 5, 13, 25, 40, 55, 85, 110 };
-          cMaxUpSpeed.select(findIndex(upSpeeds[index], upRates));
-          int maxUp = upRates[cMaxUpSpeed.getSelectionIndex()];
-          ((ConfigureWizard) wizard).maxUpSpeed = maxUp;
-          computeAll(maxUp);
-        }
-      }
-    });
-
-    cMaxUpSpeed.addListener(SWT.Selection, new Listener() {
-      public void handleEvent(Event event) {
-        int maxUp = upRates[cMaxUpSpeed.getSelectionIndex()];
-        ((ConfigureWizard) wizard).maxUpSpeed = maxUp;
-        computeAll(maxUp);
-      }
-    });
-
-    connections.select(((ConfigureWizard) wizard).upSpeed);
-    cMaxUpSpeed.select(findIndex(((ConfigureWizard) wizard).maxUpSpeed, upRates));
-    cMaxUpSpeed.setEnabled(((ConfigureWizard) wizard).upSpeed == 0);
-    computeAll(((ConfigureWizard) wizard).maxUpSpeed);
-
-  }
-
-  public void computeAll(int maxUploadSpeed) {
-    if (maxUploadSpeed != 0) {
-
-      int nbMaxActive = (int) (Math.pow(maxUploadSpeed,0.34) * 0.92);
-      int nbMaxUploads = (int) (Math.pow(maxUploadSpeed,0.25) * 1.68);
-      int nbMaxDownloads = (nbMaxActive * 4) / 5;
-      
-      if (nbMaxDownloads == 0)
-      	nbMaxDownloads = 1;
-      if (nbMaxUploads > 50)
-        nbMaxUploads = 50;
-
-      ((ConfigureWizard) wizard).maxActiveTorrents = nbMaxActive;
-      ((ConfigureWizard) wizard).maxDownloads = nbMaxDownloads;
-      ((ConfigureWizard) wizard).nbUploadsPerTorrent = nbMaxUploads;
-    	
-    }
-    else {
-      ((ConfigureWizard) wizard).maxActiveTorrents = 0;
-      ((ConfigureWizard) wizard).maxDownloads = 0;
-      ((ConfigureWizard) wizard).nbUploadsPerTorrent = 4;
-    }
-    refresh();
-  }
-
-  public void refresh() {
-    nbMaxActive.setText("" + ((ConfigureWizard) wizard).maxActiveTorrents);
-    nbMaxDownloads.setText("" + ((ConfigureWizard) wizard).maxDownloads);
-    nbMaxUploadsPerTorrent.setText("" + ((ConfigureWizard) wizard).nbUploadsPerTorrent);
-  }
-
-  private int findIndex(int value, int values[]) {
-    for (int i = 0; i < values.length; i++) {
-      if (values[i] == value)
-        return i;
-    }
-    return 0;
-  }
-  
-  public boolean isNextEnabled() {
-    return true;
-  }
-  
-  public IWizardPanel getNextPanel() {
-    return new NatPanel(((ConfigureWizard)wizard),this);
-  }
-
-}
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel2.java b/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel2.java
new file mode 100644
index 0000000..3bf4ac5
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/config/wizard/TransferPanel2.java
@@ -0,0 +1,457 @@
+/*
+ * File    : TransferPanel.java
+ * Created : 12 oct. 2003 19:41:14
+ * By      : Olivier 
+ * 
+ * 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.swt.config.wizard;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.Debug;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ipc.IPCInterface;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
+import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+
+/**
+ * @author Olivier
+ * 
+ */
+public class 
+TransferPanel2
+	extends AbstractWizardPanel<ConfigureWizard> 
+{
+	private static final int kbit = 1000;
+	private static final int mbit = 1000*1000;
+	
+	private static final int[] connection_rates = { 
+		0,
+		28800,
+		56 * kbit,
+		64 * kbit,
+		96 * kbit,
+		128 * kbit,
+		192 * kbit,
+		256 * kbit,
+		384 * kbit,
+		512 * kbit,
+		640 * kbit,
+		768 * kbit,
+		1 * mbit,
+		2 * mbit,
+		5 * mbit,
+		10 * mbit,
+		20 * mbit,
+		50 * mbit,
+		100 * mbit,
+	};
+		
+
+	private volatile boolean test_in_progress;
+
+	private boolean manual_mode;
+	
+	private Label	uprate_label;
+	
+  public TransferPanel2(ConfigureWizard wizard, IWizardPanel previous) {
+    super(wizard, previous);
+  }
+
+  /* (non-Javadoc)
+   * @see org.gudy.azureus2.ui.swt.wizard.IWizardPanel#show()
+   */
+  public void show() {
+    wizard.setTitle(MessageText.getString("configureWizard.transfer.title"));
+    wizard.setCurrentInfo(MessageText.getString("configureWizard.transfer2.hint"));
+    final Composite rootPanel = wizard.getPanel();
+    GridLayout layout = new GridLayout();
+    layout.numColumns = 1;
+    rootPanel.setLayout(layout);
+
+    Composite panel = new Composite(rootPanel, SWT.NULL);
+    GridData gridData = new GridData(GridData.FILL_BOTH);
+    panel.setLayoutData(gridData);
+    layout = new GridLayout();
+    layout.numColumns = 2;
+    panel.setLayout(layout);
+
+    Label label = new Label(panel, SWT.WRAP);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 2;
+    label.setLayoutData(gridData);
+    Messages.setLanguageText(label, "configureWizard.transfer2.message");
+
+    final Group gRadio = new Group(panel, SWT.NULL);
+    Messages.setLanguageText(gRadio, "configureWizard.transfer2.group");
+    gRadio.setLayoutData(gridData);
+    layout = new GridLayout();
+    layout.numColumns = 2;
+    gRadio.setLayout( layout );
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 2;
+    gRadio.setLayoutData(gridData);
+
+
+    	// auto button
+    
+    Button auto_button = new Button (gRadio, SWT.RADIO);
+    Messages.setLanguageText(auto_button, "auto.mode");
+    auto_button.setSelection( true );
+    
+    new Label( gRadio, SWT.NULL );
+    
+    	// speed test button
+    
+    label = new Label( gRadio, SWT.NULL );
+    Messages.setLanguageText(label, "configureWizard.transfer2.test.info");
+
+    final Button speed_test = new Button( gRadio, SWT.NULL );
+    
+    Messages.setLanguageText( speed_test, "configureWizard.transfer2.test" );
+        		
+    final SelectionAdapter speed_test_listener = 
+    	new SelectionAdapter()
+    	{
+    		public void 
+    		widgetSelected(
+    			SelectionEvent arg0 ) 
+    		{
+    			speed_test.setEnabled( false );
+    			
+    			test_in_progress = true;
+    			
+    			updateNextEnabled();
+
+				rootPanel.getShell().setEnabled( false );
+				
+    			UIFunctionsManager.getUIFunctions().installPlugin(
+    				"mlab",
+    				"dlg.install.mlab",
+    				new UIFunctions.actionListener()
+    				{
+    					public void 
+    					actionComplete(
+    						Object result )
+    					{
+    						if ( result instanceof Boolean ){
+    							
+    							PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID( "mlab" );
+
+    							IPCInterface callback = 
+    								new IPCInterface()
+	    							{
+    									public Object 
+    									invoke(
+    										String 		methodName, 
+    										Object[]	params )
+    									{
+    										try{
+	    										if ( methodName.equals( "results" )){
+	    											   											
+		    										Map<String,Object> 	results = (Map<String,Object>)params[0];
+		    										
+		    										Long	up_rate = (Long)results.get( "up" );
+		    										
+		    										if ( up_rate != null ){
+		    											
+		    											final int u = up_rate.intValue();
+		    											
+		    											if ( u > 0 ){
+		    												
+		    												Utils.execSWTThread(
+		    													new Runnable()
+		    													{
+		    														public void
+		    														run()
+		    														{
+		    															updateUp( u, false );
+		    														}								
+		    													});
+		    											}
+		    										}
+	    										}
+	    										
+	    										return( null );
+	    										
+    										}finally{
+    											
+    											enableTest();
+    										}
+    									}
+    								
+    									public boolean 
+    									canInvoke( 
+    										String methodName, 
+    										Object[] params )
+    									{
+    										return( true );
+    									}
+	    							};
+    							
+	    						try{
+	    							pi.getIPC().invoke(
+	    								"runTest",
+	    								new Object[]{ new HashMap<String,Object>(), callback, false });
+	    							
+	    						}catch( Throwable e ){
+	    							
+	    							Debug.out( e );
+	    							
+	    							enableTest();
+	    						}
+    						}else{
+    						
+    							try{
+    								Throwable error = (Throwable)result;
+    							
+    								Debug.out( error );
+    								
+    							}finally{
+    								
+    								enableTest();
+    							}
+    						}
+    					}
+    					
+    					protected void
+    					enableTest()
+    					{
+							Utils.execSWTThread(
+									new Runnable()
+									{
+										public void 
+										run() 
+										{
+											speed_test.setEnabled( true );
+											
+											test_in_progress = false;
+											
+											updateNextEnabled();
+											
+											rootPanel.getShell().setEnabled( true );
+										};
+									});
+    					}
+    				});	
+    		}
+    	};
+    
+ 	speed_test.addSelectionListener( speed_test_listener );
+    
+    	// manual
+    
+    final Button manual_button = new Button( gRadio, SWT.RADIO );
+    Messages.setLanguageText(manual_button, "manual.mode");
+
+    new Label( gRadio, SWT.NULL );
+    
+    	// drop down speed selector
+        
+    final Label manual_label = new Label( gRadio, SWT.NULL );
+    Messages.setLanguageText(manual_label, "configureWizard.transfer2.mselect");
+
+    String connection_labels[] = new String[connection_rates.length];
+
+    connection_labels[0] = MessageText.getString( "configureWizard.transfer2.current" );
+ 
+    String dial_up = MessageText.getString( "dial.up" );
+    
+    for (int i = 1; i < connection_rates.length; i++) {
+    	
+    	connection_labels[i] = (i<3?(dial_up+ " "):"xxx/") + DisplayFormatters.formatByteCountToBitsPerSec( connection_rates[i]/8);
+    }
+    
+    final Combo connection_speed = new Combo(gRadio, SWT.SINGLE | SWT.READ_ONLY);
+    
+    for ( int i=0; i<connection_rates.length; i++ ){
+    	
+    	connection_speed.add(connection_labels[i]);
+    }
+    
+    connection_speed.select(0);
+    
+    connection_speed.addListener(
+    	SWT.Selection,
+    	new Listener()
+    	{
+    		public void 
+    		handleEvent(
+    			Event arg0 ) 
+    		{
+    			int index = connection_speed.getSelectionIndex();
+    			    			
+    			updateUp( connection_rates[index]/8, true );
+     		}
+    	});
+    
+    final Label manual2_label = new Label( gRadio, SWT.WRAP );
+    Messages.setLanguageText(manual2_label, "configureWizard.transfer2.mselect.info");
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 2;
+    manual2_label.setLayoutData( gridData );
+
+    Listener listener = 
+    	new Listener()
+		{
+			public void 
+			handleEvent(
+				Event arg0 ) 
+			{
+				boolean is_manual = manual_button.getSelection();
+					
+				speed_test.setEnabled( !is_manual );
+				
+				connection_speed.setEnabled( is_manual );
+				manual_label.setEnabled( is_manual );
+				manual2_label.setEnabled( is_manual );
+				
+				manual_mode = is_manual;
+				
+				updateNextEnabled();
+			}
+		};
+    manual_button.addListener( SWT.Selection, listener );
+ 
+    listener.handleEvent( null );
+    
+    uprate_label = new Label( panel, SWT.WRAP );
+    gridData = new GridData(GridData.FILL_BOTH);
+    gridData.verticalIndent=10;
+    uprate_label.setLayoutData( gridData );
+    updateUp( 0, true );
+    
+    manual_mode = false;
+    
+    updateNextEnabled();
+    
+    if ( wizard.getWizardMode() == ConfigureWizard.WIZARD_MODE_SPEED_TEST_AUTO ){
+    	
+    	Utils.execSWTThreadLater(
+    		0,
+    		new Runnable()
+    		{
+    			public void
+    			run()
+    			{
+    				speed_test_listener.widgetSelected( null );
+    			}
+    		});
+    }
+  }
+
+  private void
+  updateUp(
+	  int		rate,
+	  boolean	manual )
+  {
+	wizard.setConnectionUploadLimit( rate, manual );
+	
+	if ( rate == 0 ){
+		
+		uprate_label.setText( MessageText.getString( "configureWizard.transfer2.rate.unchanged" ));
+		
+	}else{
+	
+		uprate_label.setText(
+			MessageText.getString( "configureWizard.transfer2.rate.changed",
+			new String[]{
+				DisplayFormatters.formatByteCountToBitsPerSec( rate ) + " (" + DisplayFormatters.formatByteCountToKiBEtcPerSec( rate ) + ")" ,
+				DisplayFormatters.formatByteCountToKiBEtcPerSec( wizard.getUploadLimit()),
+				String.valueOf( wizard.maxActiveTorrents ),
+				String.valueOf( wizard.maxDownloads )
+			}));
+	}
+  }
+  
+  private void
+  updateNextEnabled()
+  {
+	 wizard.setPreviousEnabled( isPreviousEnabled() );
+	 
+	 boolean enabled = isProgressEnabled();
+	 	  
+	   
+	 if ( wizard.getWizardMode() != ConfigureWizard.WIZARD_MODE_FULL ){
+		 
+		 wizard.setNextEnabled( false );
+		 
+	   	 wizard.setFinishEnabled( enabled );
+	 }else{
+		 
+		 wizard.setNextEnabled( enabled );
+	 }
+  }
+  
+  public boolean 
+  isProgressEnabled() 
+  {
+    if ( test_in_progress ){
+    	
+    	return( false );
+    }
+    
+    if ( manual_mode || wizard.getConnectionUploadLimit() > 0 ){
+    	
+    	return( true );
+    }
+    
+    return( false );
+  }
+  
+  public boolean 
+  isNextEnabled() 
+  {
+	  return( isProgressEnabled() && wizard.getWizardMode() == ConfigureWizard.WIZARD_MODE_FULL);
+  }
+  
+  public boolean 
+  isPreviousEnabled() 
+  {
+    return( ! ( test_in_progress || wizard.getWizardMode() != ConfigureWizard.WIZARD_MODE_FULL ));
+  }
+  
+  public IWizardPanel 
+  getFinishPanel() 
+  {
+    return( new FinishPanel(wizard,this));
+  }
+  
+  public IWizardPanel 
+  getNextPanel() 
+  {
+    return( new NatPanel((wizard),this));
+  }
+
+}
diff --git a/org/gudy/azureus2/ui/swt/config/wizard/WelcomePanel.java b/org/gudy/azureus2/ui/swt/config/wizard/WelcomePanel.java
index f298375..b458b09 100644
--- a/org/gudy/azureus2/ui/swt/config/wizard/WelcomePanel.java
+++ b/org/gudy/azureus2/ui/swt/config/wizard/WelcomePanel.java
@@ -34,7 +34,6 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 
@@ -55,6 +54,8 @@ public class WelcomePanel extends AbstractWizardPanel {
   public void show() {
     wizard.setTitle(MessageText.getString("configureWizard.welcome.title"));
     
+    Display display = wizard.getDisplay();
+
     String initsMode = "";
     final String[] text = {""};
     int userMode = COConfigurationManager.getIntParameter("User Mode");
@@ -63,10 +64,10 @@ public class WelcomePanel extends AbstractWizardPanel {
     		"ConfigView.section.mode.advanced.wiki.main",
     		"ConfigView.section.mode.intermediate.wiki.publish"
     };
-    final String[] links = {"http://www.azureuswiki.com/index.php/This_funny_word",
-    		"http://www.azureuswiki.com/index.php/HostingFiles",
-    		"http://www.azureuswiki.com/index.php/Main_Page",
-    		"http://www.azureuswiki.com/index.php/PublishingFiles"
+    final String[] links = {"http://wiki.vuze.com/w/This_funny_word",
+    		"http://wiki.vuze.com/w/HostingFiles",
+    		"http://wiki.vuze.com/w/Main_Page",
+    		"http://wiki.vuze.com/w/PublishingFiles"
     };
     
     Composite rootPanel = wizard.getPanel();
@@ -153,7 +154,7 @@ public class WelcomePanel extends AbstractWizardPanel {
 	    final Label linkLabel = new Label(gWiki, SWT.NULL);
 	    linkLabel.setText( MessageText.getString( messTexts[userMode] ) );
 	    linkLabel.setData( links[userMode] );
-	    linkLabel.setCursor(Cursors.handCursor);
+	    linkLabel.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
 	    linkLabel.setForeground(Colors.blue);
 	    gridData = new GridData(GridData.FILL_HORIZONTAL);
 	    gridData.horizontalIndent = 10;
@@ -170,7 +171,7 @@ public class WelcomePanel extends AbstractWizardPanel {
 	    final Label linkLabel1 = new Label(gWiki, SWT.NULL);
 	    linkLabel1.setText( (userMode == 1)?MessageText.getString(messTexts[3]):"");
 	    linkLabel1.setData( links[3] );
-	    linkLabel1.setCursor(Cursors.handCursor);
+	    linkLabel1.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
 	    linkLabel1.setForeground(Colors.blue);
 	    gridData = new GridData(GridData.FILL_HORIZONTAL);
 	    gridData.horizontalIndent = 10;
@@ -235,7 +236,7 @@ public class WelcomePanel extends AbstractWizardPanel {
    * @see org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel#getNextPanel()
    */
   public IWizardPanel getNextPanel() {
-    return new TransferPanel(((ConfigureWizard)wizard),this);
+    return new TransferPanel2(((ConfigureWizard)wizard),this);
   }
 
 }
diff --git a/org/gudy/azureus2/ui/swt/debug/ObfusticateImage.java b/org/gudy/azureus2/ui/swt/debug/ObfusticateImage.java
index a20e79b..944eee5 100644
--- a/org/gudy/azureus2/ui/swt/debug/ObfusticateImage.java
+++ b/org/gudy/azureus2/ui/swt/debug/ObfusticateImage.java
@@ -20,7 +20,6 @@
 package org.gudy.azureus2.ui.swt.debug;
 
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
 
 /**
  * @author TuxPaper
@@ -29,5 +28,5 @@ import org.eclipse.swt.graphics.Point;
  */
 public interface ObfusticateImage
 {
-	Image obfusticatedImage(Image image, Point shellOffset);
+	Image obfusticatedImage(Image image);
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java b/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
index f9b6b34..c4044be 100644
--- a/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
+++ b/org/gudy/azureus2/ui/swt/debug/UIDebugGenerator.java
@@ -20,15 +20,16 @@
 package org.gudy.azureus2.ui.swt.debug;
 
 import java.io.*;
+import java.net.URL;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
 
+import org.bouncycastle.util.encoders.Base64;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.logging.LogEvent;
 import org.gudy.azureus2.core3.logging.LogIDs;
@@ -36,13 +37,20 @@ import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.logging.impl.FileLogging;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
-import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
+import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.ResourceDownloaderFactoryImpl;
+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.CoreWaiterSWT;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT.TriggerInThread;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
 
 import com.aelitis.azureus.core.*;
+import com.aelitis.azureus.core.util.AZ3Functions;
 import com.aelitis.azureus.ui.UserPrompterResultListener;
 
 /**
@@ -52,19 +60,148 @@ import com.aelitis.azureus.ui.UserPrompterResultListener;
  */
 public class UIDebugGenerator
 {
-	public static void generate() {
+	public static class GeneratedResults
+	{
+		File file;
+
+		String message;
+		
+		boolean sendNow;
+
+		public String email;
+	}
+
+	public static void generate(final String sourceRef, String additionalText) {
+		final GeneratedResults gr = generate(null, false,
+				"UIDebugGenerator.messageask");
+		if (gr != null) {
+			AZ3Functions.provider az3 = AZ3Functions.getProvider();
+
+			if (az3 != null && gr.sendNow) {
+				
+				if (gr.email != null && gr.email.length() > 0) {
+					additionalText += "\n" + gr.email;
+				}
+				
+				ResourceDownloaderFactory rdf = ResourceDownloaderFactoryImpl.getSingleton();
+				String url = az3.getDefaultContentNetworkURL(az3.SERVICE_SITE_RELATIVE,
+						new Object[] {
+							"/debugSender.start",
+							true
+						});
+				StringBuffer postData = new StringBuffer();
+
+				PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getDefaultPluginInterface();
+				FeatureManager featman = pi.getUtilities().getFeatureManager();
+
+				if (featman != null) {
+					FeatureDetails[] featureDetails = featman.getFeatureDetails("dvdburn");
+					if (featureDetails != null && featureDetails.length > 0) {
+						// Could walk through details and find the most valid..
+
+						FeatureDetails bestDetails = featureDetails[0];
+						postData.append("license=");
+						postData.append(UrlUtils.encode(bestDetails.getLicence().getKey()));
+						postData.append("&");
+					}
+				}
+
+				postData.append("message=");
+				postData.append(UrlUtils.encode(gr.message));
+				postData.append("&error=");
+				postData.append(UrlUtils.encode(additionalText));
+				postData.append("&sourceRef=");
+				postData.append(UrlUtils.encode(sourceRef));
+				if (gr.email != null && gr.email.length() > 0) {
+					postData.append("&email=");
+					postData.append(UrlUtils.encode(gr.email));
+				}
+				postData.append("&debug_zip=");
+				try {
+					byte[] fileArray = FileUtil.readFileAsByteArray(gr.file);
+					postData.append(UrlUtils.encode(new String(Base64.encode(fileArray))));
+
+					ResourceDownloader rd = rdf.create(new URL(url), postData.toString());
+
+					rd.addListener(new ResourceDownloaderListener() {
+
+						public void reportPercentComplete(ResourceDownloader downloader,
+								int percentage) {
+						}
+
+						public void reportAmountComplete(ResourceDownloader downloader,
+								long amount) {
+						}
+
+						public void reportActivity(ResourceDownloader downloader,
+								String activity) {
+						}
+
+						public void failed(ResourceDownloader downloader,
+								ResourceDownloaderException e) {
+							Debug.out(e);
+						}
+
+						public boolean completed(ResourceDownloader downloader,
+								InputStream data) {
+							try {
+								int i = data.available();
+								byte[] b = new byte[i];
+								data.read(b);
+							} catch (Throwable t) {
+
+							}
+							return true;
+						}
+					});
+
+					rd.asyncDownload();
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			} else {
+
+				MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL
+						| SWT.ICON_INFORMATION | SWT.APPLICATION_MODAL,
+						"UIDebugGenerator.complete", new String[] {
+							gr.file.toString()
+						});
+				mb.open(new UserPrompterResultListener() {
+					public void prompterClosed(int result) {
+						if (result == SWT.OK) {
+							try {
+								PlatformManagerFactory.getPlatformManager().showFile(
+										gr.file.getAbsolutePath());
+							} catch (Exception e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							}
+						}
+					}
+				});
+			}
+		}
+	}
+
+	public static GeneratedResults generate(File[] extraLogDirs,
+			boolean allowEmpty, String msgPrefix) {
 		Display display = Display.getCurrent();
 		if (display == null) {
-			return;
+			return null;
 		}
-
+		
+		Shell activeShell = display.getActiveShell();
+		if (activeShell != null) {
+			activeShell.setCursor(display.getSystemCursor(SWT.CURSOR_WAIT));
+		}
+		
 		// make sure display is up to date
 		while (display.readAndDispatch()) {
 		}
-
+		
 		Shell[] shells = display.getShells();
 		if (shells == null || shells.length == 0) {
-			return;
+			return null;
 		}
 
 		final File path = new File(SystemProperties.getUserPath(), "debug");
@@ -84,6 +221,10 @@ public class UIDebugGenerator
 			try {
 				Shell shell = shells[i];
 				Image image = null;
+				
+				if (shell.isDisposed() || !shell.isVisible()) {
+					continue;
+				}
 
 				if (shell.getData("class") instanceof ObfusticateShell) {
 					ObfusticateShell shellClass = (ObfusticateShell) shell.getData("class");
@@ -91,7 +232,7 @@ public class UIDebugGenerator
 					try {
 						image = shellClass.generateObfusticatedImage();
 					} catch (Exception e) {
-						Debug.out("Obfusticating shell " + shell, e);
+						Debug.out("Obfuscating shell " + shell, e);
 					}
 				} else {
 
@@ -107,31 +248,29 @@ public class UIDebugGenerator
 				}
 
 				if (image != null) {
-					File file = new File(path, "image-" + i + ".jpg");
+					File file = new File(path, "image-" + i + ".vpg");
 					String sFileName = file.getAbsolutePath();
 
 					ImageLoader imageLoader = new ImageLoader();
-					imageLoader.data = new ImageData[] { image.getImageData() };
+					imageLoader.data = new ImageData[] {
+						image.getImageData()
+					};
 					imageLoader.save(sFileName, SWT.IMAGE_JPEG);
 				}
+
 			} catch (Exception e) {
 				Logger.log(new LogEvent(LogIDs.GUI, "Creating Obfusticated Image", e));
 			}
 		}
 
-		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
-				"UIDebugGenerator.messageask.title",
-				"UIDebugGenerator.messageask.text", true);
-		entryWindow.prompt();
-		if (!entryWindow.hasSubmittedInput()) {
-			return;
-		}
-		String message = entryWindow.getSubmittedInput();
+		GeneratedResults gr = new GeneratedResults();
 
-		if (message == null || message.length() == 0) {
-			new MessageBoxShell(SWT.OK, "UIDebugGenerator.message.cancel",
-					(String[]) null).open(null);
-			return;
+		if (activeShell != null) {
+			activeShell.setCursor(null);
+		}
+		promptUser(allowEmpty, gr);
+		if (gr.message == null) {
+			return null;
 		}
 
 		try {
@@ -139,8 +278,8 @@ public class UIDebugGenerator
 			FileWriter fw;
 			fw = new FileWriter(fUserMessage);
 
-			fw.write(message);
-
+			fw.write(gr.message  + "\n" + gr.email);
+			
 			fw.close();
 		} catch (IOException e) {
 			// TODO Auto-generated catch block
@@ -157,13 +296,11 @@ public class UIDebugGenerator
 										try {
 
 											File fEvidence = new File(path, "evidence.log");
-											FileWriter fw;
-											fw = new FileWriter(fEvidence);
-											PrintWriter pw = new PrintWriter(fw);
+											PrintWriter pw = new PrintWriter(fEvidence, "UTF-8");
 
 											AEDiagnostics.generateEvidence(pw);
 
-											fw.close();
+											pw.close();
 
 										} catch (IOException e) {
 
@@ -174,13 +311,14 @@ public class UIDebugGenerator
 					}
 				});
 
-
 		try {
 			final File outFile = new File(SystemProperties.getUserPath(), "debug.zip");
 			if (outFile.exists()) {
 				outFile.delete();
 			}
 
+			AEDiagnostics.flushPendingLogs();
+
 			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFile));
 
 			// %USERDIR%\logs
@@ -227,36 +365,47 @@ public class UIDebugGenerator
 				addFilesToZip(out, files);
 			}
 
+			// recent OSX crashes
+			File diagReportspath = new File(System.getProperty("user.home"), "Library"
+					+ File.separator + "Logs" + File.separator + "DiagnosticReports");
+			if (diagReportspath.isDirectory()) {
+				files = diagReportspath.listFiles(new FileFilter() {
+					public boolean accept(File pathname) {
+						return (pathname.getName().endsWith("crash") && pathname.lastModified() > ago);
+					}
+				});
+				addFilesToZip(out, files);
+			}
+
 			boolean bLogToFile = COConfigurationManager.getBooleanParameter("Logging Enable");
 			String sLogDir = COConfigurationManager.getStringParameter("Logging Dir",
 					"");
 			if (bLogToFile && sLogDir != null) {
 				File loggingFile = new File(sLogDir, FileLogging.LOG_FILE_NAME);
 				if (loggingFile.isFile()) {
-					addFilesToZip(out, new File[] { loggingFile });
+					addFilesToZip(out, new File[] {
+						loggingFile
+					});
+				}
+			}
+
+			if (extraLogDirs != null) {
+				for (File file : extraLogDirs) {
+					files = file.listFiles(new FileFilter() {
+						public boolean accept(File pathname) {
+							return pathname.getName().endsWith("stackdump")
+									|| pathname.getName().endsWith("log");
+						}
+					});
+					addFilesToZip(out, files);
 				}
 			}
 
 			out.close();
 
 			if (outFile.exists()) {
-				MessageBoxShell mb = new MessageBoxShell(SWT.OK | SWT.CANCEL
-						| SWT.ICON_INFORMATION | SWT.APPLICATION_MODAL,
-						"UIDebugGenerator.complete", new String[] { outFile.toString() });
-				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();
-							}
-						}
-					}
-				});
-
+				gr.file = outFile;
+				return gr;
 			}
 
 		} catch (IOException e) {
@@ -264,6 +413,138 @@ public class UIDebugGenerator
 			e.printStackTrace();
 		}
 
+		return null;
+	}
+
+	private static void promptUser(final boolean allowEmpty, GeneratedResults gr) {
+		final Shell shell = ShellFactory.createShell(Utils.findAnyShell(), SWT.SHELL_TRIM);
+
+		final String[] text = { null, null };
+		final int[] sendMode = {-1};
+		
+		Utils.setShellIcon(shell);
+		
+		Messages.setLanguageText(shell, "UIDebugGenerator.messageask.title");
+		
+		shell.setLayout(new FormLayout());
+		
+		Label lblText = new Label(shell, SWT.NONE);
+		Messages.setLanguageText(lblText, "UIDebugGenerator.messageask.text");
+		
+		final Text textMessage = new Text(shell, SWT.MULTI | SWT.BORDER | SWT.WRAP);
+		final Text textEmail = new Text(shell, SWT.BORDER);
+		
+		textEmail.setMessage("optional at email.here");
+
+		Composite cButtonsSuper = new Composite(shell, SWT.NONE);
+		GridLayout gl = new GridLayout();
+		cButtonsSuper.setLayout(gl);
+
+		Composite cButtons = new Composite(cButtonsSuper, SWT.NONE);
+		cButtons.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
+		cButtons.setLayout(new RowLayout());
+		
+		Button btnSendNow = new Button(cButtons, SWT.PUSH);
+		btnSendNow.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				if (emptyCheck(textMessage, allowEmpty)) {
+  				text[0] = textMessage.getText();
+  				text[1] = textEmail.getText();
+  				sendMode[0] = 0;
+				}
+				shell.dispose();
+			}
+		});
+		Button btnSendLater = new Button(cButtons, SWT.PUSH);
+		btnSendLater.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				if (emptyCheck(textMessage, allowEmpty)) {
+  				text[0] = textMessage.getText();
+  				text[1] = textEmail.getText();
+  				sendMode[0] = 1;
+				}
+				shell.dispose();
+			}
+		});
+		Button btnCancel = new Button(cButtons, SWT.PUSH);
+		btnCancel.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				shell.dispose();
+			}
+		});
+
+		if (Constants.isOSX) {
+			btnCancel.moveAbove(null);
+		}
+		Messages.setLanguageText(btnCancel, "Button.cancel");
+		Messages.setLanguageText(btnSendNow, "Button.sendNow");
+		Messages.setLanguageText(btnSendLater, "Button.sendManual");
+
+		FormData fd;
+		
+		fd = new FormData();
+		fd.top = new FormAttachment(0, 5);
+		fd.left = new FormAttachment(0, 5);
+		fd.right = new FormAttachment(100, -5);
+		lblText.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.top = new FormAttachment(lblText, 10);
+		fd.left = new FormAttachment(0, 5);
+		fd.right = new FormAttachment(100, -5);
+		fd.bottom = new FormAttachment(textEmail, -10);
+		textMessage.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.left = new FormAttachment(0, 5);
+		fd.right = new FormAttachment(100, -5);
+		fd.bottom = new FormAttachment(cButtonsSuper, -2);
+		textEmail.setLayoutData(fd);
+		
+		fd = new FormData();
+		fd.left = new FormAttachment(0, 5);
+		fd.right = new FormAttachment(100, -5);
+		fd.bottom = new FormAttachment(100, -1);
+		cButtonsSuper.setLayoutData(fd);
+
+		textMessage.setFocus();
+
+		shell.setSize(500, 300);
+		shell.layout();
+		Utils.centreWindow(shell);
+		shell.open();
+
+		while (!shell.isDisposed()) {
+			if (!shell.getDisplay().readAndDispatch()) {
+				shell.getDisplay().sleep();
+			}
+		}
+		if (sendMode[0] != -1) {
+			gr.message = text[0];
+			gr.email = text[1];
+		}
+		gr.sendNow = sendMode[0] == 0;
+	}
+
+	/**
+	 * @param textMessage
+	 * @param allowEmpty
+	 * @return
+	 *
+	 * @since 4.5.0.3
+	 */
+	protected static boolean emptyCheck(Text textMessage, boolean allowEmpty) {
+		if (allowEmpty) {
+			return true;
+		}
+		if (textMessage.getText().length() > 0) {
+			return true;
+		}
+		
+		new MessageBoxShell(SWT.OK, "UIDebugGenerator.message.cancel",
+				(String[]) null).open(null);
+
+		return false;
 	}
 
 	private static void addFilesToZip(ZipOutputStream out, File[] files) {
@@ -312,15 +593,11 @@ public class UIDebugGenerator
 	 * @param image
 	 * @param bounds
 	 */
-	// XXX After we swith to 3.2, display param can be removed, and 
-	// image.getDevice() can be used
-	public static void obfusticateArea(Display display, Image image,
-			Rectangle bounds)
-	{
+	public static void obfusticateArea(Image image, Rectangle bounds) {
 		GC gc = new GC(image);
 		try {
-			gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-			gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
+			gc.setBackground(image.getDevice().getSystemColor(SWT.COLOR_WHITE));
+			gc.setForeground(image.getDevice().getSystemColor(SWT.COLOR_RED));
 			gc.fillRectangle(bounds);
 			gc.drawRectangle(bounds);
 			int x2 = bounds.x + bounds.width;
@@ -337,22 +614,21 @@ public class UIDebugGenerator
 	 * @param bounds
 	 * @param text
 	 */
-	public static void obfusticateArea(Display display, Image image,
-			Rectangle bounds, String text)
-	{
+	public static void obfusticateArea(Image image, Rectangle bounds, String text) {
 
 		if (bounds.isEmpty())
 			return;
 
-		if (text == "") {
-			obfusticateArea(display, image, bounds);
+		if (text == null || text.length() == 0) {
+			obfusticateArea(image, bounds);
 			return;
 		}
 
 		GC gc = new GC(image);
 		try {
-			gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-			gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
+			Device device = image.getDevice();
+			gc.setBackground(device.getSystemColor(SWT.COLOR_WHITE));
+			gc.setForeground(device.getSystemColor(SWT.COLOR_RED));
 			gc.fillRectangle(bounds);
 			gc.drawRectangle(bounds);
 			gc.setClipping(bounds);
@@ -368,14 +644,12 @@ public class UIDebugGenerator
 	 * @param shellOffset 
 	 * @param text 
 	 */
-	public static void obfusticateArea(Image image, Control control,
-			Point shellOffset, String text)
-	{
+	public static void obfusticateArea(Image image, Control control, String text) {
 		Rectangle bounds = control.getBounds();
-		Point offset = control.getParent().toDisplay(bounds.x, bounds.y);
-		bounds.x = offset.x - shellOffset.x;
-		bounds.y = offset.y - shellOffset.y;
+		Point location = Utils.getLocationRelativeToShell(control);
+		bounds.x = location.x;
+		bounds.y = location.y;
 
-		obfusticateArea(control.getDisplay(), image, bounds, text);
+		obfusticateArea(image, bounds, text);
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/donations/DonationWindow.java b/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
index b785d32..4e5dc68 100644
--- a/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
+++ b/org/gudy/azureus2/ui/swt/donations/DonationWindow.java
@@ -17,7 +17,7 @@
  */
 
 package org.gudy.azureus2.ui.swt.donations;
-
+ 
 import java.util.Locale;
 
 import org.eclipse.swt.SWT;
@@ -33,6 +33,9 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.stats.transfer.OverallStats;
 import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.utils.FeatureManager;
+import org.gudy.azureus2.plugins.utils.FeatureManager.FeatureDetails;
+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;
@@ -60,6 +63,8 @@ public class DonationWindow
 
 	private static Browser browser;
 
+	private static BrowserFunction browserFunction;
+
 	public static void checkForDonationPopup() {
 		if (shell != null) {
 			if (DEBUG) {
@@ -67,11 +72,26 @@ public class DonationWindow
 			}
 			return;
 		}
+		
+		FeatureManager fm = PluginInitializer.getDefaultInterface().getUtilities().getFeatureManager();
+		
+		FeatureDetails[] fds = fm.getFeatureDetails( "core" );
+		
+		for ( FeatureDetails fd: fds ){
+			
+			if ( !fd.hasExpired()){
+				
+				return;
+			}
+		}
 
+		long maxDate = COConfigurationManager.getLongParameter("donations.maxDate", 0);
+		boolean force = maxDate > 0 && SystemTime.getCurrentTime() > maxDate ? true : false;	
+		
 		//Check if user has already donated first
 		boolean alreadyDonated = COConfigurationManager.getBooleanParameter(
 				"donations.donated", false);
-		if (alreadyDonated) {
+		if (alreadyDonated && !force) {
 			if (DEBUG) {
 				new MessageBoxShell(SWT.OK, "Donations Test",
 						"Already Donated! I like you.").open(null);
@@ -103,7 +123,7 @@ public class DonationWindow
 			return;
 		}
 
-		if (hours < nextAsk) {
+		if (hours < nextAsk && !force) {
 			if (DEBUG) {
 				new MessageBoxShell(SWT.OK, "Donations Test", "Wait "
 						+ (nextAsk - hours) + ".").open(null);
@@ -172,6 +192,9 @@ public class DonationWindow
 				if (parentShell != null) {
 					parentShell.setCursor(e.display.getSystemCursor(SWT.CURSOR_ARROW));
 				}
+				if (browserFunction != null && !browserFunction.isDisposed()) {
+					browserFunction.dispose();
+				}
 				shell = null;
 			}
 		});
@@ -190,20 +213,30 @@ public class DonationWindow
 				shell.setText(event.title);
 			}
 		});
+		
+		browserFunction = new BrowserFunction(browser, "sendDonationEvent") {
+			public Object function(Object[] arguments) {
 
-		browser.addStatusTextListener(new StatusTextListener() {
-			String last = null;
-
-			public void changed(StatusTextEvent event) {
 				if (shell == null || shell.isDisposed()) {
-					return;
+					return null;
 				}
-
-				String text = event.text.toLowerCase();
-				if (last != null && last.equals(text)) {
-					return;
+				
+				if (arguments == null) {
+					Debug.out("Invalid sendDonationEvent null ");
+					return null;
 				}
-				last = text;
+				if (arguments.length < 1) {
+					Debug.out("Invalid sendDonationEvent length " + arguments.length + " not 1");
+					return null;
+				}
+				if (!(arguments[0] instanceof String)) {
+					Debug.out("Invalid sendDonationEvent "
+							+ (arguments[0] == null ? "NULL"
+									: arguments.getClass().getSimpleName()) + " not String");
+					return null;
+				}
+
+				String text = (String) arguments[0];
 				if (text.contains("page-loaded")) {
 					pageLoadedOk = true;
 					COConfigurationManager.setParameter("donations.count",
@@ -228,11 +261,13 @@ public class DonationWindow
 				} else if (text.contains("close")) {
 					Utils.execSWTThreadLater(0, new AERunnable() {	
 						public void runSupport() {
-							shell.dispose();
+							if (shell != null && !shell.isDisposed()) {
+								shell.dispose();
+							}
 						}
 					});
 				} else if (text.startsWith("open-url")) {
-					String url = event.text.substring(9);
+					String url = text.substring(9);
 					Utils.launch(url);
 				} else if (text.startsWith("set-size")) {
 					String[] strings = text.split(" ");
@@ -247,6 +282,22 @@ public class DonationWindow
 						}
 					}
 				}
+				return null;
+			}
+		};
+
+		browser.addStatusTextListener(new StatusTextListener() {
+			String last = null;
+
+			public void changed(StatusTextEvent event) {
+				String text = event.text.toLowerCase();
+				if (last != null && last.equals(text)) {
+					return;
+				}
+				last = text;
+				browserFunction.function(new Object[] {
+					text
+				});
 			}
 		});
 
@@ -264,7 +315,7 @@ public class DonationWindow
 		final String url = "http://"
 				+ System.getProperty("platform_address", "www.vuze.com") + ":"
 				+ System.getProperty("platform_port", "80") + "/"
-				+ "donate.start?locale=" + Locale.getDefault().toString() + "&azv="
+				+ "donate.start?locale=" + MessageText.getCurrentLocale().toString() + "&azv="
 				+ Constants.AZUREUS_VERSION + "&count="
 				+ COConfigurationManager.getLongParameter("donations.count", 1)
 				+ "&uphours=" + upHours + "&azid=" + azid + "&sourceref="
@@ -302,6 +353,7 @@ public class DonationWindow
 	 */
 	protected static void  neverAskAgain() {
 		COConfigurationManager.setParameter("donations.donated", true);
+		updateMinDate();
 		COConfigurationManager.save();
 	}
 
@@ -319,21 +371,22 @@ public class DonationWindow
 		int hours = (int) (upTime / (60 * 60)); //secs * mins
 		int nextAsk = hours + askEveryHours;
 		COConfigurationManager.setParameter("donations.nextAskHours", nextAsk);
-		COConfigurationManager.setParameter("donations.lastVersion",
-				Constants.AZUREUS_VERSION);
+		COConfigurationManager.setParameter("donations.lastVersion", Constants.AZUREUS_VERSION);
+		updateMinDate();
 		COConfigurationManager.save();
 	}
 
 	public static void updateMinDate() {
-		COConfigurationManager.setParameter("donations.minDate",
-				SystemTime.getOffsetTime(1000l * 3600 * 24 * 30));
-		COConfigurationManager.save();
-	}
-
-	public static void setMinDate(long timestamp) {
-		COConfigurationManager.setParameter("donations.minDate", timestamp);
-		COConfigurationManager.save();
+		COConfigurationManager.setParameter("donations.minDate", SystemTime.getOffsetTime(1000l * 3600 * 24 * 30));  //30d ahead
+		COConfigurationManager.setParameter("donations.maxDate", SystemTime.getOffsetTime(1000l * 3600 * 24 * 120));  //4mo ahead
+		//COConfigurationManager.save();
 	}
+	
+   //unused
+	//public static void setMinDate(long timestamp) {
+	//	COConfigurationManager.setParameter("donations.minDate", timestamp);
+	//	COConfigurationManager.save();
+	//}
 
 	public static int getInitialAskHours() {
 		return initialAskHours;
diff --git a/org/gudy/azureus2/ui/swt/help/AboutWindow.java b/org/gudy/azureus2/ui/swt/help/AboutWindow.java
index c969145..4d2f456 100644
--- a/org/gudy/azureus2/ui/swt/help/AboutWindow.java
+++ b/org/gudy/azureus2/ui/swt/help/AboutWindow.java
@@ -20,8 +20,6 @@
  */
 package org.gudy.azureus2.ui.swt.help;
 
-import java.util.Properties;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CLabel;
 import org.eclipse.swt.events.*;
@@ -71,15 +69,6 @@ public class AboutWindow {
     
     paintColorTo = 0;
 
-    Properties properties = new Properties();
-    try {
-      properties.load(AboutWindow.class.getClassLoader().getResourceAsStream("org/gudy/azureus2/ui/swt/about.properties"));
-    }
-    catch (Exception e1) {
-    	Debug.printStackTrace( e1 );
-      return;
-    }
-        
     final Shell window = ShellFactory.createMainShell((Constants.isOSX)
 				? SWT.DIALOG_TRIM : (SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL));
     Utils.setShellIcon(window);
@@ -87,27 +76,22 @@ public class AboutWindow {
 
     window.setText(MessageText.getString("MainWindow.about.title") + " " + Constants.AZUREUS_VERSION); //$NON-NLS-1$
     GridData gridData;
-    window.setLayout(new GridLayout(3, false));
+    window.setLayout(new GridLayout(2, false));
 
     ImageLoader imageLoader = ImageLoader.getInstance();
-    image = imageLoader.getImage(IMG_SPLASH);
-    if (image != null) {
-      int w = image.getBounds().width;
+    imgSrc = imageLoader.getImage(IMG_SPLASH);
+    if (imgSrc != null) {
+      int w = imgSrc.getBounds().width;
       int ow = w;
       if (w > 350) {
       	w = 350;
       }
-      int h = image.getBounds().height;
-      h = 220;
-      imgSrc = new Image(display, w, h);
-      GC gc = new GC(imgSrc);
-      gc.drawImage(image, (w - ow) / 2, 0);
-      gc.dispose();
+      int h = imgSrc.getBounds().height;
       
       Image imgGray = new Image(display, imageLoader.getImage(IMG_SPLASH),
 					SWT.IMAGE_GRAY);
       imageLoader.releaseImage(IMG_SPLASH);
-      gc = new GC(imgGray);
+      GC gc = new GC(imgGray);
       if (Constants.isOSX) {
       	gc.drawImage(imgGray, (w - ow) / 2, 0);
       } else {
@@ -117,63 +101,39 @@ public class AboutWindow {
       
       Image image2 = new Image(display, w, h);
       gc = new GC(image2);
-      gc.setBackground(Colors.black);
+      gc.setBackground(window.getBackground());
       gc.fillRectangle(image2.getBounds());
       gc.dispose();
       image = Utils.renderTransparency(display, image2, imgGray, new Point(0, 0), 180);
       image2.dispose();
       imgGray.dispose();
     }
-    imageLoader.releaseImage(IMG_SPLASH);
     
-    Group gDevelopers = new Group(window, SWT.NULL);
-    gDevelopers.setLayout(new GridLayout());
-    Messages.setLanguageText(gDevelopers, "MainWindow.about.section.developers"); //$NON-NLS-1$
-    gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
-    gDevelopers.setLayoutData(gridData);
-    
-    Label label = new Label(gDevelopers, SWT.LEFT);
-    label.setText(properties.getProperty("developers")); //$NON-NLS-1$ //$NON-NLS-2$
-    label.setLayoutData(gridData = new GridData());
-    
-    final Canvas labelImage = new Canvas(window, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
+    final Canvas labelImage = new Canvas(window, SWT.DOUBLE_BUFFERED);
     //labelImage.setImage(image);
-    gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+    gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL);
+    gridData.horizontalSpan = 2;
+    gridData.horizontalIndent = gridData.verticalIndent = 0;
     Rectangle imgBounds = image.getBounds();
-    gridData.widthHint = imgBounds.width;
-    gridData.heightHint = imgBounds.height;
+    gridData.widthHint = 300;
+    gridData.heightHint = imgBounds.height + imgBounds.y + 20;
     labelImage.setLayoutData(gridData);
     labelImage.addPaintListener(new PaintListener() {
 			public void paintControl(PaintEvent e) {
 				Rectangle boundsColor = imgSrc.getBounds();
+				int ofs = (labelImage.getSize().x - boundsColor.width) / 2;
 				if (paintColorTo > 0) {
-					e.gc.drawImage(imgSrc, 0, 0, paintColorTo, boundsColor.height, 0, 0, paintColorTo, boundsColor.height);
+					e.gc.drawImage(imgSrc, 0, 0, paintColorTo, boundsColor.height, ofs, 10, 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);
+							paintColorTo + 1 + ofs, 10, imgBounds.width - paintColorTo - 1, imgBounds.height);
 				}
 			}
 		});
   
-    Group gTranslators = new Group(window, SWT.NULL);
-    GridLayout gl = new GridLayout();
-    gl.marginHeight = 2;
-    gl.marginWidth = 0;
-    gTranslators.setLayout(gl);
-    Messages.setLanguageText(gTranslators, "MainWindow.about.section.translators"); //$NON-NLS-1$
-    gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
-    gTranslators.setLayoutData(gridData);
-  
-    Text txtTrans = new Text(gTranslators, SWT.READ_ONLY | SWT.MULTI | SWT.WRAP | SWT.NO_FOCUS);
-    txtTrans.setText(properties.getProperty("translators")); //$NON-NLS-1$ //$NON-NLS-2$
-    gridData = new GridData(GridData.FILL_BOTH);
-    gridData.heightHint = txtTrans.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + 10;
-    txtTrans.setLayoutData(gridData);
-    txtTrans.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
-    
     Group gInternet = new Group(window, SWT.NULL);
     GridLayout gridLayout = new GridLayout();
     gridLayout.numColumns = 2;
@@ -181,7 +141,6 @@ public class AboutWindow {
     gInternet.setLayout(gridLayout);
     Messages.setLanguageText(gInternet, "MainWindow.about.section.internet"); //$NON-NLS-1$
     gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
-    gridData.horizontalSpan = 2;
     gInternet.setLayoutData(gridData);
   
     Group gSys = new Group(window, SWT.NULL);
@@ -199,27 +158,36 @@ 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 + "/" + CorePatchLevel.getCurrentPatchLevel() + " " 
+				+ Constants.APP_NAME.charAt(0) + Constants.AZUREUS_VERSION + (Constants.AZUREUS_SUBVER.length()==0?"":("-"+Constants.AZUREUS_SUBVER)) + "/" + CorePatchLevel.getCurrentPatchLevel() + " " 
 				+ COConfigurationManager.getStringParameter("ui"));
     txtSysInfo.setLayoutData(gridData = new GridData(GridData.FILL_BOTH));
     if (window.getCaret() != null)
     	window.getCaret().setVisible(false);
 
-    final String[][] link =
-      { { "homepage", "sourceforge", "sourceforgedownloads", "bugreports", "forumdiscussion", "wiki" }, {
-          "http://www.vuze.com",
-          "http://azureus.sourceforge.net",
-          "http://sourceforge.net/project/showfiles.php?group_id=84122",
-          "http://forum.vuze.com/category.jspa?categoryID=3",
-          "http://forum.vuze.com",
-          Constants.AZUREUS_WIKI }
-    };
+		final String[][] link = {
+			{
+				"homepage",
+				"sourceforge",
+				"bugreports",
+				"forumdiscussion",
+				"wiki",
+				"contributors"
+			},
+			{
+				"http://www.vuze.com",
+				"http://azureus.sourceforge.net",
+				"http://forum.vuze.com/forum.jspa?forumID=124",
+				"http://forum.vuze.com",
+				Constants.AZUREUS_WIKI,
+				Constants.AZUREUS_WIKI + "Contributors"
+			}
+		};
   
     for (int i = 0; i < link[0].length; i++) {
       final CLabel linkLabel = new CLabel(gInternet, SWT.NULL);
       linkLabel.setText(MessageText.getString("MainWindow.about.internet." + link[0][i]));
       linkLabel.setData(link[1][i]);
-      linkLabel.setCursor(Cursors.handCursor);
+      linkLabel.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
       linkLabel.setForeground(Colors.blue);
       gridData = new GridData(GridData.FILL_HORIZONTAL);
       gridData.horizontalSpan = 1;
@@ -278,7 +246,9 @@ public class AboutWindow {
               if(labelImage.isDisposed())
                 return;
               paintColorTo++;
-              labelImage.redraw(paintColorTo - 1, 0, 2, maxY, true);
+      				Rectangle boundsColor = imgSrc.getBounds();
+      				int ofs = (labelImage.getSize().x - boundsColor.width) / 2;
+              labelImage.redraw(paintColorTo - 1 + ofs, 10, 2, maxY, true);
             }
           });
           try {
@@ -296,11 +266,12 @@ public class AboutWindow {
   {
   	try{
   		class_mon.enter();
-	    if(image != null && ! image.isDisposed())
+	    if(image != null && ! image.isDisposed()) {
 	      image.dispose();
+	    }
+	    ImageLoader imageLoader = ImageLoader.getInstance();
+	    imageLoader.releaseImage(IMG_SPLASH);
 	    image = null;
-	    if(imgSrc != null && ! imgSrc.isDisposed())
-	      imgSrc.dispose();
 	    imgSrc = null;
   	}finally{
   		
@@ -310,10 +281,20 @@ public class AboutWindow {
 
   public static void main(String[] args) {
   	try {
-  		new Display();
+  		Display display = new Display();
   		Colors.getInstance();
 			SWTThread.createInstance(null);
 			show();
+			
+			while (!display.isDisposed() && instance != null && !instance.isDisposed()) {
+				if (!display.readAndDispatch()) {
+					display.sleep();
+				}
+			}
+			
+			if (!display.isDisposed()) {
+				display.dispose();
+			}
 		} catch (SWTThreadAlreadyInstanciatedException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/ClipboardCopy.java b/org/gudy/azureus2/ui/swt/mainwindow/ClipboardCopy.java
index 59f4a38..0d8b954 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/ClipboardCopy.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/ClipboardCopy.java
@@ -49,7 +49,7 @@ public class ClipboardCopy {
     String    data )
   {
 	  new Clipboard(SWTThread.getInstance().getDisplay()).setContents(
-			  new Object[] {data }, 
+			  new Object[] {data.replaceAll("\\x00", " " )  }, 
 			  new Transfer[] {TextTransfer.getInstance()});
   }
   
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Colors.java b/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
index 2f862c7..4598694 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/Colors.java
@@ -74,6 +74,9 @@ public class Colors implements ParameterListener {
   public static Color red_ConsoleView;
   
   private static AEMonitor	class_mon	= new AEMonitor( "Colors" );
+	public static int diffHue;
+	public static float diffSatPct;
+	public static float diffLumPct;
   
   private void allocateBlues() {    
     int r = 0;
@@ -85,6 +88,16 @@ public class Colors implements ParameterListener {
       b = COConfigurationManager.getIntParameter("Color Scheme.blue", b);
       
       boolean bGrayScale = (r == b) && (b == g);
+      
+      HSLColor hslDefault = new HSLColor();
+      hslDefault.initHSLbyRGB(0, 128, 255);
+      
+      HSLColor hslScheme = new HSLColor();
+      hslScheme.initHSLbyRGB(r, g, b);
+      
+      diffHue = hslScheme.getHue() - hslDefault.getHue();
+      diffSatPct = hslScheme.getSaturation() == 0 ? 0 : (float) hslDefault.getSaturation() / hslScheme.getSaturation();
+      diffLumPct = hslScheme.getLuminence() == 0 ? 0 : (float) hslDefault.getLuminence() / hslScheme.getLuminence();
 
       HSLColor hslColor = new HSLColor();
       Color colorTables = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
@@ -226,11 +239,18 @@ public class Colors implements ParameterListener {
 						colorTables.getBlue());
 
 				int lum = hslColor.getLuminence();
-				if (lum > 127)
-					lum -= 16;
-				else
+				int sat = hslColor.getSaturation();
+				int hue = hslColor.getHue();
+				if (lum > 127) {
+					lum -= 10;
+					sat = 127;
+					hue = 155;
+				} else {
 					lum += 30; // it's usually harder to see difference in darkness
+				}
 				hslColor.setLuminence(lum);
+				hslColor.setHue(hue);
+				hslColor.setSaturation(sat);
 				
 				//HSLColor blueHSL = new HSLColor();
 				//RGB rgb = blues[BLUES_DARKEST].getRGB();
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Cursors.java b/org/gudy/azureus2/ui/swt/mainwindow/Cursors.java
deleted file mode 100644
index 29eab80..0000000
--- a/org/gudy/azureus2/ui/swt/mainwindow/Cursors.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Created on 2 mai 2004 Created by Olivier Chalouhi
- * 
- * 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 Alle Lenotre, La Grille Royale,
- * 78600 Le Mesnil le Roi, France.
- */
-
-package org.gudy.azureus2.ui.swt.mainwindow;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Cursor;
-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;
-
-/**
- * @author Olivier Chalouhi
- *  
- */
-public class Cursors
-{
-	public static Cursor handCursor = null;
-
-	public static void init() {
-		try {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					Display display = SWTThread.getInstance().getDisplay();
-					if (display != null && !display.isDisposed()) {
-						handCursor = new Cursor(display, SWT.CURSOR_HAND);
-					}
-				}
-			});
-		} catch (Exception e) {
-			Debug.out("Cursor Init", e);
-		}
-	}
-
-	public static void dispose() {
-		try {
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					if (handCursor != null && !handCursor.isDisposed()) {
-						handCursor.dispose();
-					}
-				}
-			});
-		} catch (Exception e) {
-			Debug.out("Cursor Destroy", e);
-		}
-	}
-
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/IMainStatusBar.java b/org/gudy/azureus2/ui/swt/mainwindow/IMainStatusBar.java
new file mode 100644
index 0000000..599f39f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/mainwindow/IMainStatusBar.java
@@ -0,0 +1,69 @@
+/*
+ * Created on Sep 13, 2012
+ * Created by Paul Gardner
+ * 
+ * Copyright 2012 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.mainwindow;
+
+import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar.CLabelPadding;
+import org.gudy.azureus2.ui.swt.update.UpdateWindow;
+
+import com.aelitis.azureus.ui.UIStatusTextClickListener;
+
+
+public interface 
+IMainStatusBar 
+{
+	public void
+	createStatusEntry(
+		CLabelUpdater 	updater );
+	
+	public boolean
+	isMouseOver();
+	
+	public void
+	setUpdateNeeded(
+		UpdateWindow	update_window );
+	
+	public void
+	setStatusText(
+		String			text );
+	
+	public void 
+	setStatusText(
+		int 						statustype, 
+		String 						string,
+		UIStatusTextClickListener 	l );
+	
+	public void
+	setDebugInfo(
+		String			text );
+	
+	public interface 
+	CLabelUpdater
+	{
+		public void 
+		created(
+			CLabelPadding label );
+		
+		public boolean 
+		update(
+			CLabelPadding label );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/IMainWindow.java b/org/gudy/azureus2/ui/swt/mainwindow/IMainWindow.java
index ee10807..1060e7e 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/IMainWindow.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/IMainWindow.java
@@ -13,9 +13,6 @@ public interface IMainWindow
 
 	public static final int WINDOW_ELEMENT_TOPBAR = 4;
 
-	// 3.2 TODO: rename to searchbar or profilebar or something
-	public static final int WINDOW_ELEMENT_TABBAR = 5;
-	
 	public static final int WINDOW_CLIENT_AREA = 6;
 	
 	public static final int WINDOW_CONTENT_DISPLAY_AREA = 7;
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java b/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
index a28f13e..7832095 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/IMenuConstants.java
@@ -1,5 +1,6 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
+
 /**
  * Constants for working with menus
  * 
@@ -57,6 +58,12 @@ public interface IMenuConstants
 
 	public static final String MENU_ID_PLUGINS = "MainWindow.menu.view.plugins";
 
+	public static final String MENU_ID_SPEED_LIMITS = "MainWindow.menu.speed_limits";
+	
+	public static final String MENU_ID_QUICK_VIEW = "MainWindow.menu.quick_view";
+
+	public static final String MENU_ID_ADVANCED_TOOLS = "MainWindow.menu.advanced_tools";
+
 	public static final String MENU_ID_WINDOW = "MainWindow.menu.window";
 
 	public static final String MENU_ID_HELP = "MainWindow.menu.help";
@@ -68,6 +75,8 @@ public interface IMenuConstants
 	public static final String MENU_ID_LOG_VIEWS = "MainWindow.menu.view.plugins.logViews";
 
 	public static final String MENU_ID_OPEN_TORRENT = "MainWindow.menu.file.open.torrent";
+	
+	public static final String MENU_ID_OPEN_URI = "MainWindow.menu.file.open.uri";
 
 	public static final String MENU_ID_OPEN_TORRENT_FOR_TRACKING = "MainWindow.menu.file.open.torrentfortracking";
 
@@ -114,6 +123,10 @@ 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_DEVICEMANAGER = "MainWindow.menu.view.devicemanager";
+
+	public static final String MENU_ID_SUBSCRIPTIONS = "subscriptions.view.title";
 
 	public static final String MENU_ID_MY_TRACKERS = "MainWindow.menu.view.mytracker";
 
@@ -137,6 +150,8 @@ public interface IMenuConstants
 
 	public static final String MENU_ID_OPTIONS = "MainWindow.menu.view.configuration";
 
+	public static final String MENU_ID_PAIRING = "MainWindow.menu.pairing";
+
 	public static final String MENU_ID_WINDOW_MINIMIZE = "MainWindow.menu.window.minimize";
 
 	public static final String MENU_ID_WINDOW_ALL_TO_FRONT = "MainWindow.menu.window.alltofront";
@@ -153,8 +168,6 @@ public interface IMenuConstants
 
 	public static final String MENU_ID_WHATS_NEW = "MainWindow.menu.help.whatsnew";
 
-	public static final String MENU_ID_FAQ = "MainWindow.menu.help.faq";
-
 	public static final String MENU_ID_RELEASE_NOTES = "MainWindow.menu.help.releasenotes";
 
 	public static final String MENU_ID_PLUGINS_HELP = "MainWindow.menu.help.plugins";
@@ -162,6 +175,8 @@ public interface IMenuConstants
 	public static final String MENU_ID_DEBUG_HELP = "MainWindow.menu.help.debug";
 
 	public static final String MENU_ID_UPDATE_CHECK = "MainWindow.menu.help.checkupdate";
+	
+	public static final String MENU_ID_BETA_PROG = "MainWindow.menu.beta";
 
 	public static final String MENU_ID_PLUGINS_INSTALL = "MainWindow.menu.plugins.installPlugins";
 
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java b/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
deleted file mode 100644
index 620829f..0000000
--- a/org/gudy/azureus2/ui/swt/mainwindow/Initializer.java
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Created on Apr 30, 2004
- * Created by Olivier Chalouhi
- * 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.mainwindow;
-
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.eclipse.swt.widgets.Display;
-
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.global.GlobalManager;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.ipfilter.IpFilterManager;
-import org.gudy.azureus2.core3.logging.*;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.plugins.PluginEvent;
-import org.gudy.azureus2.plugins.utils.DelayedTask;
-import org.gudy.azureus2.pluginsimpl.local.utils.UtilitiesImpl;
-import org.gudy.azureus2.ui.common.util.UserAlerts;
-import org.gudy.azureus2.ui.swt.*;
-import org.gudy.azureus2.ui.swt.auth.AuthenticatorWindow;
-import org.gudy.azureus2.ui.swt.auth.CertificateTrustWindow;
-import org.gudy.azureus2.ui.swt.auth.CryptoWindow;
-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;
-import org.gudy.azureus2.ui.swt.updater2.PreUpdateChecker;
-import org.gudy.azureus2.ui.swt.updater2.SWTUpdateChecker;
-
-import com.aelitis.azureus.core.*;
-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.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.utils.UIMagnetHandler;
-
-/**
- * this class initiatize all GUI and Core components which are :
- * 1. The SWT Thread
- * 2. Images
- * 3. The Splash Screen if needed
- * 4. The GlobalManager
- * 5. The Main Window in correct state or the Password window if needed.
- */
-public class 
-Initializer 
-	implements AzureusCoreListener, IUIIntializer
-{
-	private static final LogIDs LOGID = LogIDs.GUI;
-  private AzureusCore		azureus_core;
-  private GlobalManager 	gm;
-  private StartServer 		startServer;
-  
-  private CopyOnWriteList listeners = new CopyOnWriteList();
-  
-  private AEMonitor	listeners_mon	= new AEMonitor( "Initializer:l" );
-
-  private String[] args;
-  
-  private AESemaphore semFilterLoader = new AESemaphore("filter loader");
-  
-  private AESemaphore init_task = new AESemaphore("delayed init");
-  
-  public 
-  Initializer(
-  		final AzureusCore		_azureus_core,
-  		StartServer 			_server,
-		String[] 				_args ) 
-  {   
-    azureus_core	= _azureus_core;
-    startServer 	= _server;
-    args 			= _args;
-    
-    Thread filterLoaderThread = new AEThread("filter loader", true) {
-			public void runSupport() {
-				try {
-					azureus_core.getIpFilterManager().getIPFilter();
-				} finally {
-					semFilterLoader.releaseForever();
-				}
-			}
-		};
-		filterLoaderThread.setPriority(Thread.MIN_PRIORITY);
-		filterLoaderThread.start();
-
-    try {
-      SWTThread.createInstance(this);
-    } catch(SWTThreadAlreadyInstanciatedException e) {
-    	Debug.printStackTrace( e );
-    }
-  }  
-
-  public static boolean
-  handleStopRestart(
-  	final boolean	restart )
-  {
-		UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		if (functionsSWT != null) {
-			return functionsSWT.dispose(restart, true);
-		}
-
-		return false;
-	}
-	
-
-  public void run() {
-
-  	try{
-  		if (initializer != null) {
-  			
-  			try {
-  				initializer.run();
-  			} catch (Throwable t) {
-  				// use print stack trace because we don't want to introduce logger
-  				t.printStackTrace();
-  				// Ignore and use AZ2
-  			}
-  			return;
-  		}
-  		// else AZ2UI
-  		
-		DelayedTask delayed_task = UtilitiesImpl.addDelayedTask("SWT Initialisation", new Runnable()
-				{
-					public void
-					run()
-					{
-						init_task.reserve();
-					}
-				});
-
-		delayed_task.queue();
-			  
-
-		
-  		// initialise the SWT locale util
-	  	
-	    new LocaleUtilSWT( azureus_core );
-
-			Display display = SWTThread.getInstance().getDisplay();
-
-			new UIMagnetHandler(azureus_core);
-
-			UIConfigDefaultsSWT.initialize();
-			
-	    //Splash Window is not always shown
-	    if (COConfigurationManager.getBooleanParameter("Show Splash")) {
-	      SplashWindow.create(display,this);
-	    }
-	    	    
-	    setNbTasks(6);
-	    
-	    nextTask(); 
-	    reportCurrentTaskByKey("splash.firstMessageNoI18N");
-	    
-	    Alerts.init();
-	    
-	    final ArrayList logEvents = new ArrayList();
-	    ILogEventListener logListener = null;
-	    if (COConfigurationManager.getBooleanParameter("Open Console", false)) {
-	    	logListener = new ILogEventListener() {
-					public void log(LogEvent event) {
-						logEvents.add(event);
-					}
-	    	};
-	    	Logger.addListener(logListener);
-	    }
-	    final ILogEventListener finalLogListener = logListener;
-
-	    ProgressWindow.register( azureus_core );
-	    
-	    new SWTNetworkSelection();
-	    
-	    new AuthenticatorWindow();
-	    new CryptoWindow();
-	    
-	    new CertificateTrustWindow();
-
-	    InstallPluginWizard.register( azureus_core, display );
-	    
-	    nextTask();
-	    reportCurrentTaskByKey("splash.initializeGM");
-	    
-	    azureus_core.addListener( this );
-	    
-	    azureus_core.addLifecycleListener(new AzureusCoreLifecycleAdapter() {
-				public void componentCreated(AzureusCore core, AzureusCoreComponent comp) {
-					if (comp instanceof GlobalManager) {
-
-						gm = (GlobalManager) comp;
-
-						nextTask();
-						reportCurrentTask(MessageText.getString("splash.initializePlugins"));
-					}
-				}
-
-				public void 
-				started(
-					final AzureusCore core) 
-				{
-					boolean	main_window_will_report_complete = false;
-					
-					try{
-						if (gm == null)
-							return;
-	
-						new UserAlerts(gm);
-	
-						nextTask();
-						IpFilterManager ipFilterManager = azureus_core.getIpFilterManager();
-						if (ipFilterManager != null) {
-							String s = MessageText.getString("splash.loadIpFilters");
-	  					do {
-	  						reportCurrentTask(s);
-	  						s += ".";
-	  					} while (!semFilterLoader.reserve(3000));
-						}
-						
-						nextTask();
-						reportCurrentTaskByKey("splash.initializeGui");
-	
-						Colors.getInstance();
-	
-						Cursors.init();
-	
-						main_window_will_report_complete = true;
-						
-						// main window controls further progress now
-						new MainWindow(core, Initializer.this,
-								logEvents);
-	
-						if (finalLogListener != null)
-							Logger.removeListener(finalLogListener);
-	
-						SWTUpdateChecker.initialize();
-	
-						PreUpdateChecker.initialize( core, COConfigurationManager.getStringParameter("ui"));
-	
-						UpdateMonitor.getSingleton(core); // setup the update monitor
-	
-						//Tell listeners that all is initialized :
-						Alerts.initComplete();
-	
-	
-						
-	
-						//Finally, open torrents if any.
-						for (int i = 0; i < args.length; i++) {
-	
-							try {
-								TorrentOpener.openTorrent(args[i]);
-	
-							} catch (Throwable e) {
-	
-								Debug.printStackTrace(e);
-							}
-						}
-					}finally{
-					
-						if ( !main_window_will_report_complete ){
-							init_task.release();
-						}
-					}
-				}
-
-				public void stopping(AzureusCore core) {
-					Alerts.stopInitiated();
-				}
-
-				public void stopped(AzureusCore core) {
-				}
-
-				public boolean syncInvokeRequired() {
-					return (true);
-				}
-
-				public boolean
-				requiresPluginInitCompleteBeforeStartedEvent()
-				{
-					return( false );
-				}
-				
-				public boolean stopRequested(AzureusCore _core)
-
-				throws AzureusCoreException {
-					return (handleStopRestart(false));
-				}
-
-				public boolean restartRequested(final AzureusCore core) {
-					return (handleStopRestart(true));
-				}
-			});
-	    
-	    azureus_core.start();
-
-  	}catch( Throwable e ){
-  		Logger.log(new LogEvent(LOGID, "Initialization fails:", e));
-  		init_task.release();
-  	} 
-  }
-  
-  public void addListener(InitializerListener listener){
-    try{
-    	listeners_mon.enter();
-    	
-    	listeners.add(listener);
-    }finally{
-    	
-    	listeners_mon.exit();
-    }
-  }
-  
-  public void removeListener(InitializerListener listener) {
-    try{
-    	listeners_mon.enter();
-		
-    	listeners.remove(listener);
-    }finally{
-    	
-    	listeners_mon.exit();
-    }
-  }
-  
-  public void 
-  reportCurrentTask(
-	AzureusCoreOperation	operation,
-	String 					currentTask )
-  {
-	  if ( operation.getOperationType() == AzureusCoreOperation.OP_INITIALISATION ){
-		  reportCurrentTask( currentTask );
-	  }
-  }
-	  
-  public void 
-  reportPercent(
-	AzureusCoreOperation	operation,
-	int 					percent )
-  {
-	  if ( operation.getOperationType() == AzureusCoreOperation.OP_INITIALISATION ){
-		  reportPercent( percent );
-	  }
-  }
-  
-  public void reportCurrentTask(String currentTaskString) {
-     try{
-     	listeners_mon.enter();
-     
-	    Iterator iter = listeners.iterator();
-	    while(iter.hasNext()) {
-	    	try{
-	    		InitializerListener listener = (InitializerListener) iter.next();
-	      
-	    		listener.reportCurrentTask(currentTaskString);
-	    		
-	    	}catch( Throwable e ){
-	    		
-	    		Debug.printStackTrace( e );
-	    	}
-	    }
-    }finally{
-    	
-    	listeners_mon.exit();
-    }
-  }
-  
-  public void
-  initializationComplete()
-  {
-	  azureus_core.getPluginManager().firePluginEvent( PluginEvent.PEV_INITIALISATION_UI_COMPLETES );
-	  
-	  new DelayedEvent( 
-			  "SWTInitComplete:delay",
-			  8500,
-			  new AERunnable()
-			  {
-				  public void
-				  runSupport()
-				  {
-					  init_task.release();
-				  }
-			  });
-  }
-  
-  // AzureusCoreListener
-  public void reportPercent(int percent) {
-  	int overallPercent = overallPercent(percent);
-    try{
-    	listeners_mon.enter();
-    
-	    Iterator iter = listeners.iterator();
-	    while(iter.hasNext()) {
-	    	try{
-	    		InitializerListener listener = (InitializerListener) iter.next();
-	      
-	    		listener.reportPercent(overallPercent);
-	    		
-	    	}catch( Throwable e ){
-	    		
-	    		Debug.printStackTrace( e );
-	    	}
-	    }
-
-	    if (overallPercent > 100) {
-	    	listeners.clear();
-	    }
-    }finally{
-    	
-    	listeners_mon.exit();
-    }
-  }
-  
-  public void 
-  stopIt(
-  	boolean	for_restart,
-	boolean	close_already_in_progress ) 
-  
-  	throws AzureusCoreException
-  {
-    if ( azureus_core != null && !close_already_in_progress ){
-
-    	if ( for_restart ){
-
-    		azureus_core.checkRestartSupported();
-    	}
-    }
-    
-  	try{
-	    Cursors.dispose();
-	    
-	    SWTThread.getInstance().terminate();  
-	    
-	}finally{
-	  	
-		try{
-	    if ( azureus_core != null && !close_already_in_progress ){
-
-	    	try{
-		    	if ( for_restart ){
-		    			
-		    		azureus_core.restart();
-		    			
-		    	}else{
-		    			
-		    		azureus_core.stop();
-		    	}
-	    	}catch( Throwable e ){
-	    		
-	    			// don't let any failure here cause the stop operation to fail
-	    		
-	    		Debug.out( e );
-	    	}
-	    }
-		}finally{
-			
-				// do this after closing core to minimise window when the we aren't 
-				// listening and therefore another Azureus start can potentially get
-				// in and screw things up
-			
-		    if ( startServer != null ){
-			    
-		    	startServer.stopIt();
-		    }
-		}
-	}
-  }
-  
-  private int nbTasks = 1;
-  private int currentTask = 0;
-  private int currentPercent = 0;
-  private int lastTaskPercent = 0;
-	private IUIIntializer initializer;
-  
-  private void setNbTasks(int _nbTasks) {
-    currentTask = 0;
-    nbTasks = _nbTasks;
-  }
-  
-  public void nextTask() {
-    currentTask++;
-    currentPercent = 100 * currentTask / (nbTasks) ;
-    //0% done of current task
-    reportPercent(0);
-  }
-  
-  private int overallPercent(int taskPercent) {
-  	lastTaskPercent = taskPercent;
-    //System.out.println("ST percent " + currentPercent + " / " + taskPercent + " : " + (currentPercent + (taskPercent / nbTasks)));
-    return currentPercent + taskPercent / nbTasks;
-  }
-  
-  private void reportCurrentTaskByKey(String key) {
-    reportCurrentTask(MessageText.getString(key));
-  }
- 
-  // @see com.aelitis.azureus.ui.IUIIntializer#increaseProgresss()
-  public void increaseProgress() {
-  	if (lastTaskPercent < 100) {
-  		reportPercent(lastTaskPercent + 1);
-  	}
-  }
-  
-	public void abortProgress() {
-		currentTask = nbTasks;
-		nextTask();
-		reportPercent(101);
-	}
-  
-  public static void main(String args[]) 
-  {
-	  if(Launcher.checkAndLaunch(Initializer.class, args))
-		  return;
-	  
-  	System.err.println("Shouldn't you be starting with org.gudy.azureus2.ui.swt.Main?");
- 	AzureusCore		core = AzureusCoreFactory.create();
-
- 	new Initializer( core, null,args);
-  }
-
-	public void runInSWTThread() {
-  		String uiMode = UISwitcherUtil.calcUIMode();
-  		
-  		if (uiMode.equals("az3")) {
-  			try {
-  				final Class az3Class = Class.forName("com.aelitis.azureus.ui.swt.Initializer");
-
-  				final Constructor constructor = az3Class.getConstructor(new Class[] {
-  						AzureusCore.class,
-  						Boolean.TYPE,
-  						String[].class
-  				});
-
-  				initializer = (IUIIntializer) constructor.newInstance(new Object[] {
-  						azureus_core,
-  						new Boolean(false),
-  						args
-  				});
-
-  				initializer.runInSWTThread();
-  				return;
-  			} catch (Throwable t) {
-  				// use print stack trace because we don't want to introduce logger
-  				t.printStackTrace();
-  				// Ignore and use AZ2
-  			}
-  		}
-  		// else AZ2UI
-	}
- 
-}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java b/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
index 49ce854..df72b83 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MainMenu.java
@@ -23,9 +23,7 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
-import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.util.Constants;
@@ -33,29 +31,16 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.SystemProperties;
 import org.gudy.azureus2.ui.swt.Utils;
 
+import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+
 /**
  * @author Olivier Chalouhi
  */
 public class MainMenu
 	implements IMainMenu
 {
-	/**
-	 * @deprecated
-	 */
-	public static int MENU_BAR = 0;
-
-	/**
-	 * @deprecated
-	 */
-	public static int MENU_TRANSFER = 1;
-
-	/**
-	 * @deprecated
-	 */
-	public static int MENU_VIEW = 2;
-
-	private MainWindow mainWindow;
-
 	private Menu menuBar;
 
 	/**
@@ -63,14 +48,9 @@ public class MainMenu
 	 * @param shell A shell
 	 */
 	public MainMenu(Shell shell) {
-		mainWindow = MainWindow.getWindow();
 		createMenus(shell);
 	}
 
-	public void setMainWindow(MainWindow mainWindow) {
-		this.mainWindow = mainWindow;
-	}
-
 	public void linkMenuBar(Shell parent) {
 		parent.setMenuBar(menuBar);
 	}
@@ -162,6 +142,7 @@ public class MainMenu
 
 		Menu openSubMenu = openMenuItem.getMenu();
 		MenuFactory.addOpenTorrentMenuItem(openSubMenu);
+		MenuFactory.addOpenURIMenuItem(openSubMenu);
 		MenuFactory.addOpenTorrentForTrackingMenuItem(openSubMenu);
 		MenuFactory.addOpenVuzeFileMenuItem(openSubMenu);
 		
@@ -173,13 +154,15 @@ public class MainMenu
 		MenuFactory.addShareFolderContentMenuItem(shareSubMenu);
 		MenuFactory.addShareFolderContentRecursiveMenuItem(shareSubMenu);
 
+		MenuFactory.addSearchMenuItem(fileMenu);
+		
 		MenuFactory.addSeparatorMenuItem(fileMenu);
 		MenuFactory.addImportMenuItem(fileMenu);
 		MenuFactory.addExportMenuItem(fileMenu);
 
 		MenuFactory.addSeparatorMenuItem(fileMenu);
 		MenuFactory.addCloseWindowMenuItem(fileMenu);
-		MenuFactory.addCloseTabMenuItem(fileMenu, mainWindow);
+		MenuFactory.addCloseTabMenuItem(fileMenu);
 		MenuFactory.addCloseDetailsMenuItem(fileMenu);
 		MenuFactory.addCloseDownloadBarsToMenu(fileMenu);
 
@@ -212,9 +195,38 @@ public class MainMenu
 	private void addViewMenu(final Shell parent) {
 		try {
 			MenuItem viewItem = MenuFactory.createViewMenuItem(menuBar);
-			Menu viewMenu = viewItem.getMenu();
+			final Menu viewMenu = viewItem.getMenu();
+			
+			viewMenu.addListener(SWT.Show, new Listener() {
+				public void handleEvent(Event event) {
+					Utils.disposeSWTObjects(viewMenu.getItems());
+					buildSimpleViewMenu(viewMenu);
+				}
+			});
+		} catch (Exception e) {
+			Debug.out("Error creating View Menu", e);
+		}
+	}
 
+	protected void buildSimpleViewMenu(final Menu viewMenu) {
+		try {
 			MenuFactory.addLabelMenuItem(viewMenu, "MainWindow.menu.view.show");
+			boolean enabled = COConfigurationManager.getBooleanParameter("Beta Programme Enabled");
+			if (enabled) {
+				indent(MenuFactory.addMenuItem(viewMenu, SWT.CHECK, "MainWindow.menu.view.beta",
+						new Listener() {
+							public void handleEvent(Event event) {
+								MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+          			MdiEntry entry = mdi.createEntryFromSkinRef(null,
+          					"BetaProgramme", "main.area.beta",
+          					"{Sidebar.beta.title}", null, null,
+          					true, "");
+          			
+          			entry.setImageLeftID( "image.sidebar.beta" );
+          			mdi.showEntry(entry);
+							}
+				}));
+			}
 
 			indent(MenuFactory.addMyTorrentsMenuItem(viewMenu));
 			indent(MenuFactory.addMyTrackerMenuItem(viewMenu));
@@ -223,22 +235,24 @@ public class MainMenu
 			indent(MenuFactory.addTransferBarToMenu(viewMenu));
 			indent(MenuFactory.addAllPeersMenuItem(viewMenu));
 			indent(MenuFactory.addClientStatsMenuItem(viewMenu));
-			if (Constants.isCVSVersion()) {
-				indent(MenuFactory.addDetailedListMenuItem(viewMenu));
-			}
+			//indent(MenuFactory.addDetailedListMenuItem(viewMenu));
+			//indent(MenuFactory.addDeviceManagerMenuItem(viewMenu));
+			//indent(MenuFactory.addSubscriptionMenuItem(viewMenu));
 
 			/*
-			 * These 2 menus resides on the Tools menu on non-OSX platforms;
+			 * These 3 menus resides on the Tools menu on non-OSX platforms;
 			 * since the Tools menu is not present in the OSX version these menus are added here to the View menu 
 			 */
 			if (Constants.isOSX) {
 				indent(MenuFactory.addConsoleMenuItem(viewMenu));
 				indent(MenuFactory.addStatisticsMenuItem(viewMenu));
+				indent(MenuFactory.addSpeedLimitsToMenu(viewMenu));
 			}
 
 		} catch (Exception e) {
 			Debug.out("Error creating View Menu", e);
 		}
+		
 	}
 
 	/**
@@ -267,6 +281,7 @@ public class MainMenu
 		MenuFactory.addBlockedIPsMenuItem(toolsMenu);
 		MenuFactory.addConsoleMenuItem(toolsMenu);
 		MenuFactory.addStatisticsMenuItem(toolsMenu);
+		MenuFactory.addSpeedLimitsToMenu(toolsMenu);
 		MenuFactory.addNatTestMenuItem(toolsMenu);
 		MenuFactory.addSpeedTestMenuItem(toolsMenu);
 
@@ -312,10 +327,12 @@ public class MainMenu
 
 		if (false == SystemProperties.isJavaWebStartInstance()) {
 			MenuFactory.addCheckUpdateMenuItem(helpMenu);
+			MenuFactory.addBetaMenuItem(helpMenu);
 		}
 		MenuFactory.addDonationMenuItem(helpMenu);
 
 		MenuFactory.addSeparatorMenuItem(helpMenu);
+		MenuFactory.addAdvancedHelpMenuItem(helpMenu);
 		MenuFactory.addDebugHelpMenuItem(helpMenu);
 
 	}
@@ -325,31 +342,6 @@ public class MainMenu
 		item.setText("  " + item.getText());
 	}
 
-	/**
-	 * @deprecated This method has been replaced with {@link #getMenu(String)};
-	 * use {@link #getMenu(IMenuConstants.MENU_ID_MENU_BAR)} ,
-	 *     {@link #getMenu(IMenuConstants.MENU_ID_TRANSFERS)}, or
-	 *     {@link #getMenu(IMenuConstants.MENU_ID_VIEW)} instead
-	 * @param id
-	 * @return
-	 */
-	public Menu getMenu(int id) {
-		/*
-		 * KN: Retrofitted to use the new getMenu(String) method
-		 */
-		if (id == MENU_BAR) {
-			return getMenu(IMenuConstants.MENU_ID_MENU_BAR);
-		}
-		if (id == MENU_TRANSFER) {
-			return getMenu(IMenuConstants.MENU_ID_TRANSFERS);
-		}
-		if (id == MENU_VIEW) {
-			return getMenu(IMenuConstants.MENU_ID_VIEW);
-		}
-
-		return null;
-	}
-
 	public Menu getMenu(String id) {
 		if (true == IMenuConstants.MENU_ID_MENU_BAR.equals(id)) {
 			return menuBar;
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java b/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
index 69f8658..af89ffb 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MainStatusBar.java
@@ -36,6 +36,7 @@ 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.ipfilter.IpFilter;
+import org.gudy.azureus2.core3.logging.LogAlert;
 import org.gudy.azureus2.core3.stats.transfer.OverallStats;
 import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 import org.gudy.azureus2.core3.util.*;
@@ -45,9 +46,12 @@ import org.gudy.azureus2.plugins.network.ConnectionManager;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.Alerts.AlertHistoryListener;
 import org.gudy.azureus2.ui.swt.progress.*;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.update.UpdateWindow;
+import org.gudy.azureus2.ui.swt.views.stats.StatsView;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreFactory;
@@ -66,7 +70,7 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
  * Moved from MainWindow and GUIUpdater
  */
 public class MainStatusBar
-	implements UIUpdatable
+	implements IMainStatusBar, UIUpdatable
 {
 	/**
 	 * Warning status icon identifier
@@ -91,17 +95,17 @@ public class MainStatusBar
 
 	private AZProgressBar progressBar;
 
-	private CLabel ipBlocked;
+	private CLabelPadding ipBlocked;
 
-	private CLabel srStatus;
+	private CLabelPadding srStatus;
 
-	private CLabel natStatus;
+	private CLabelPadding natStatus;
 
-	private CLabel dhtStatus;
+	private CLabelPadding dhtStatus;
 
-	private CLabel statusDown;
+	private CLabelPadding statusDown;
 
-	private CLabel statusUp;
+	private CLabelPadding statusUp;
 
 	private Composite plugin_label_composite;
 	
@@ -177,6 +181,18 @@ public class MainStatusBar
 
 	private long last_rec_prot;
 
+	private long[] max_rec = { 0 };
+	private long[] max_sent = { 0 };
+
+	private Image imgRec;
+	private Image imgSent;
+
+	private Image	warningIcon;
+	private Image	warningGreyIcon;
+	private Image	infoIcon;
+	
+	private CLabelPadding statusWarnings;
+
 	/**
 	 * 
 	 */
@@ -212,6 +228,18 @@ public class MainStatusBar
 		statusBar.setForeground(fgColor);
 		isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
 		
+		statusBar.getShell().addListener(SWT.Deiconify, new Listener() {
+			public void handleEvent(Event event) {
+				Utils.execSWTThreadLater(0, new AERunnable() {
+					public void runSupport() {
+						if (!statusBar.isDisposed()) {
+							statusBar.layout();
+						}
+					}
+				});
+			}
+		});
+		
 		GridLayout layout_status = new GridLayout();
 		layout_status.numColumns = 20;
 		layout_status.horizontalSpacing = 0;
@@ -278,15 +306,6 @@ public class MainStatusBar
 		progressGridData.widthHint = 5;
 		progressBar.setLayoutData(progressGridData);
 
-		if ( isAZ3 ){
-		
-			try{
-				addFeedBack();
-			}catch( Throwable e ){
-				
-				Debug.printStackTrace(e);
-			}
-		}
 		
 		/*
 		 * Progress reporting window image label
@@ -387,6 +406,9 @@ public class MainStatusBar
 						statusBar.layout();
 					}
 				});
+		
+			// ip filters
+		
 		ipBlocked = new CLabelPadding(statusBar, borderFlag);
 		ipBlocked.setText("{} IPs:"); //$NON-NLS-1$
 		Messages.setLanguageText(ipBlocked, "MainWindow.IPs.tooltip");
@@ -396,6 +418,71 @@ public class MainStatusBar
 			}
 		});
 
+		final Menu menuIPFilter = new Menu(statusBar.getShell(), SWT.POP_UP);
+		ipBlocked.setMenu( menuIPFilter );
+		
+		menuIPFilter.addListener(
+			SWT.Show, 
+			new Listener()
+			{
+				public void
+				handleEvent(Event e) 
+				{
+					MenuItem[] oldItems = menuIPFilter.getItems();
+					
+					for(int i = 0; i < oldItems.length; i++){
+						
+						oldItems[i].dispose();
+					}
+
+					if ( !AzureusCoreFactory.isCoreRunning()){
+						
+						return;
+					}
+					
+					AzureusCore azureusCore = AzureusCoreFactory.getSingleton();
+
+					final IpFilter ip_filter = azureusCore.getIpFilterManager().getIPFilter();
+					
+					final MenuItem ipfEnable = new MenuItem(menuIPFilter, SWT.CHECK);
+					
+					ipfEnable.setSelection( ip_filter.isEnabled());
+					
+					Messages.setLanguageText(ipfEnable, "MyTorrentsView.menu.ipf_enable");
+					
+					ipfEnable.addSelectionListener(
+						new SelectionAdapter() 
+						{
+							public void 
+							widgetSelected(
+								SelectionEvent e) 
+							{
+								ip_filter.setEnabled( ipfEnable.getSelection());
+							}
+						});
+
+					final MenuItem ipfOptions = new MenuItem(menuIPFilter, SWT.PUSH);
+										
+					Messages.setLanguageText(ipfOptions, "ipfilter.options");
+					
+					ipfOptions.addSelectionListener(
+						new SelectionAdapter() 
+						{
+							public void 
+							widgetSelected(
+								SelectionEvent e) 
+							{
+								UIFunctions uif = UIFunctionsManager.getUIFunctions();
+
+								if (uif != null) {
+
+									uif.openView(UIFunctions.VIEW_CONFIG, "ipfilter");
+								}
+							}
+						});
+				}
+			});
+				
 		COConfigurationManager.addAndFireParameterListener("Status Area Show IPF",
 				new ParameterListener() {
 					public void parameterChanged(String parameterName) {
@@ -404,6 +491,9 @@ public class MainStatusBar
 					}
 				});
 
+			// down speed
+		
+		
 		statusDown = new CLabelPadding(statusBar, borderFlag);
 		statusDown.setImage(imageLoader.getImage("down"));
 		//statusDown.setText(/*MessageText.getString("ConfigView.download.abbreviated") +*/"n/a");
@@ -412,7 +502,7 @@ public class MainStatusBar
 
 		Listener lStats = new Listener() {
 			public void handleEvent(Event e) {
-				uiFunctions.openView(UIFunctions.VIEW_STATS, null);
+				uiFunctions.getMDI().loadEntryByID(StatsView.VIEW_ID, true, false, "transfers");
 			}
 		};
 
@@ -427,7 +517,7 @@ public class MainStatusBar
 
 		Listener lDHT = new Listener() {
 			public void handleEvent(Event e) {
-				uiFunctions.openView(UIFunctions.VIEW_STATS, "dht");
+				uiFunctions.getMDI().loadEntryByID(StatsView.VIEW_ID, true, false, "dht");
 			}
 		};
 
@@ -436,7 +526,7 @@ public class MainStatusBar
 		Listener lSR = new Listener() {
 			public void handleEvent(Event e) {
 
-				uiFunctions.openView(UIFunctions.VIEW_STATS, "transfers");
+				uiFunctions.getMDI().loadEntryByID(StatsView.VIEW_ID, true, false, "activity");
 
 				OverallStats stats = StatsFactory.getStats();
 				
@@ -448,7 +538,7 @@ public class MainStatusBar
 
 				if (ratio < 900) {
 
-					Utils.launch(Constants.AZUREUS_WIKI + "Share_Ratio");
+					//Utils.launch(Constants.AZUREUS_WIKI + "Share_Ratio");
 				}
 			}
 		};
@@ -546,6 +636,81 @@ public class MainStatusBar
 			});
 		}
 
+		statusWarnings = new CLabelPadding(statusBar, borderFlag);
+		warningIcon 	= imageLoader.getImage("image.sidebar.vitality.alert");
+		warningGreyIcon = imageLoader.getImage("image.sidebar.vitality.alert-gray");
+		infoIcon 		= imageLoader.getImage("image.sidebar.vitality.info");
+		updateStatusWarnings( null, false );
+		Messages.setLanguageText(statusWarnings,
+				"MainWindow.status.warning.tooltip");
+		Alerts.addMessageHistoryListener(new AlertHistoryListener() {
+			public void alertHistoryAdded(LogAlert alert) {
+				updateStatusWarnings( alert, true );
+			}
+			public void alertHistoryRemoved(LogAlert alert) {
+				updateStatusWarnings( alert, false );
+			}
+		});
+		statusWarnings.addMouseListener(new MouseListener() {
+			public void mouseUp(MouseEvent e) {
+				if (SystemWarningWindow.numWarningWindowsOpen > 0) {
+					return;
+				}
+				ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+				if (alerts.size() == 0) {
+					return;
+				}
+
+				Shell shell = statusWarnings.getShell();
+				Rectangle bounds = statusWarnings.getClientArea();
+				Point ptBottomRight = statusWarnings.toDisplay(bounds.x + bounds.width, bounds.y);
+				new SystemWarningWindow(alerts.get(0), ptBottomRight, shell, 0);
+			}
+			
+			public void mouseDown(MouseEvent e) {
+			}
+			
+			public void mouseDoubleClick(MouseEvent e) {
+			}
+		});
+		
+		COConfigurationManager.addAndFireParameterListener("status.rategraphs",
+				new ParameterListener() {
+			public void parameterChanged(String parameterName) {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						boolean doRateGraphs = COConfigurationManager.getBooleanParameter("status.rategraphs");
+						if (doRateGraphs) {
+							if (imgRec == null || imgRec.isDisposed()) {
+  							imgRec = new Image(display, 100, 20);
+  							GC gc = new GC(imgRec);
+  							gc.setBackground(statusDown.getBackground());
+  							gc.fillRectangle(0, 0, 100, 20);
+  							gc.dispose();
+  							statusDown.setBackgroundImage(imgRec);
+							}
+							
+							if (imgSent == null || imgSent.isDisposed()) {
+  							imgSent = new Image(display, 100, 20);
+  							GC gc = new GC(imgSent);
+  							gc.setBackground(statusUp.getBackground());
+  							gc.fillRectangle(0, 0, 100, 20);
+  							gc.dispose();
+  							statusUp.setBackgroundImage(imgSent);
+							}
+						} else {
+							statusUp.setBackgroundImage(null);
+							statusDown.setBackgroundImage(null);
+							Utils.disposeSWTObjects(new Object[] { imgRec, imgSent });
+							imgRec = imgSent = null;
+						}
+					}
+				});
+			}
+		});
+		
+		/////////
+		
 		PRManager.addListener(new ProgressListener());
 		setProgressImage();
 		
@@ -572,6 +737,129 @@ public class MainStatusBar
 		return statusBar;
 	}
 
+	private TimerEventPeriodic		alert_flasher_event;
+	private long					alert_flasher_event_start_time;
+	private boolean					alert_flash_activate;
+	
+	
+	protected void updateStatusWarnings( final LogAlert current_alert, final boolean current_added ) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (statusWarnings == null || statusWarnings.isDisposed()) {
+					return;
+				}
+				
+				ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+				int count = alerts.size();
+				
+				Image icon = infoIcon;
+				
+				for ( LogAlert alert: alerts ){
+					int type = alert.getType();
+					
+					if ( type == LogAlert.LT_ERROR || type == LogAlert.LT_WARNING ){
+						
+						icon = warningIcon;
+						
+						break;
+					}
+				}
+				
+				if ( statusWarnings.getImage() != icon ){
+					statusWarnings.setImage( icon );
+				}
+				
+				statusWarnings.setVisible(count > 0);
+				statusWarnings.setText("" + count);
+				statusWarnings.layoutNow();
+				
+				if ( current_added ){
+					
+					alert_flash_activate = true;
+					
+					if ( current_alert.getType() != LogAlert.LT_INFORMATION ){
+											
+						alert_flasher_event_start_time = SystemTime.getMonotonousTime();
+
+						if ( alert_flasher_event == null ){
+																																	
+							alert_flasher_event = 
+								SimpleTimer.addPeriodicEvent(
+									"MSB:alertFlasher",
+									500,
+									new TimerEventPerformer()
+									{
+										private long	last_tick_time = -1;
+										
+										public void 
+										perform(
+											TimerEvent event )
+										{
+											Utils.execSWTThread(
+												new AERunnable() 
+												{
+													public void 
+													runSupport() 
+													{
+														long now = SystemTime.getMonotonousTime();
+														
+															// during init timing can go a bit askew, try
+															// and prevent too-quick transitions
+														
+														if ( 	last_tick_time != -1 &&
+																now - last_tick_time < 400 ){
+															
+															return;
+														}
+														
+														last_tick_time = now;
+														
+															// all logic is single threaded via SWT thread...
+														
+														if (	statusWarnings == null || 
+																statusWarnings.isDisposed() ||
+																alert_flasher_event == null ||
+																!alert_flash_activate ){
+																	
+															if ( alert_flasher_event != null ){
+																
+																alert_flasher_event.cancel();
+																
+																alert_flasher_event = null;
+															}
+															
+															return;
+														}
+														
+														Image current_icon = statusWarnings.getImage();
+														
+														if ( 	now > alert_flasher_event_start_time + 15*1000 &&
+																current_icon == warningIcon ){
+															
+															alert_flasher_event.cancel();
+															
+															alert_flasher_event = null;
+															
+															return;
+														}
+														
+														Image target_icon = current_icon == warningIcon?warningGreyIcon:warningIcon;
+														
+														statusWarnings.setImage( target_icon );
+													}
+												});
+										}									
+									});
+						}
+					}
+				}else{
+					
+					alert_flash_activate = false;
+				}
+			}
+		});
+	}
+
 	private void addFeedBack() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
@@ -606,10 +894,11 @@ public class MainStatusBar
 		} else if (secs_uptime - last_uptime > 15 * 60) {
 
 			createStatusEntry(new CLabelUpdater() {
-				public void update(CLabel label) {
+				public boolean update(CLabelPadding label) {
+					return( false );
 				}
 
-				public void created(CLabel feedback) {
+				public void created(CLabelPadding feedback) {
 					feedback.setText(MessageText.getString("statusbar.feedback"));
 					
 					Listener feedback_listener = new Listener() {
@@ -629,7 +918,7 @@ public class MainStatusBar
 					};
 					
 					feedback.setToolTipText(MessageText.getString("statusbar.feedback.tooltip"));
-					feedback.setCursor(Cursors.handCursor);
+					feedback.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
 					feedback.setForeground(Colors.blue);
 					feedback.addListener(SWT.MouseUp, feedback_listener);
 					feedback.addListener(SWT.MouseDoubleClick, feedback_listener);
@@ -728,7 +1017,7 @@ public class MainStatusBar
 			statusTextKey = "MainWindow.status.unofficialversion ("
 					+ Constants.AZUREUS_VERSION + ")";
 			setStatusImageKey(STATUS_ICON_WARN);
-		} else if (!Constants.isOSX) { //don't show official version numbers for OSX L&F
+		} else if (!Constants.isOSX && COConfigurationManager.getStringParameter("ui").equals("az2")) { //don't show official version numbers for OSX L&F
 			statusTextKey = Constants.APP_NAME + " " + Constants.AZUREUS_VERSION;
 			setStatusImageKey(null);
 		}
@@ -800,7 +1089,7 @@ public class MainStatusBar
 	public void setUpdateNeeded(UpdateWindow updateWindow) {
 		this.updateWindow = updateWindow;
 		if (updateWindow != null) {
-			statusText.setCursor(Cursors.handCursor);
+			statusText.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
 			statusText.setForeground(Colors.colorWarning);
 			updateStatusText();
 		} else {
@@ -861,8 +1150,7 @@ public class MainStatusBar
 				statusDown.setText((dl_limit == 0 ? "" : "[" + dl_limit + "K] ")
 						+ DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(rec_data, rec_prot));
 			}
-
-
+			
 			boolean auto_up = TransferSpeedValidator.isAutoSpeedActive(gm)
 					&& TransferSpeedValidator.isAutoUploadAvailable(core);
 
@@ -881,12 +1169,50 @@ public class MainStatusBar
 				seeding_only = "";
 			}
 
+			int sent_data = stats.getDataSendRate();
+			if (imgRec != null && !imgRec.isDisposed()) {
+				updateGraph(statusDown, imgRec, rec_data, max_rec);
+				updateGraph(statusUp, imgSent, sent_data, max_sent);
+			}
+
+
 			statusUp.setText((ul_limit_norm == 0 ? "" : "[" + ul_limit_norm + "K"
 					+ seeding_only + "]")
 					+ (auto_up ? "* " : " ")
 					+ DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(
-							stats.getDataSendRate(), stats.getProtocolSendRate()));
+							sent_data, stats.getProtocolSendRate()));
+		}
+	}
+
+	private void updateGraph(CLabelPadding label, Image img,
+			long newVal, long[] max) {
+		GC gc = new GC(img);
+		try {
+  		long val = newVal;
+  		Rectangle bounds = img.getBounds();
+  		final int padding = 2;
+  		int x = bounds.width - padding - padding;
+  		if (val > max[0]) {
+  			int y = 20 - (int) (max[0] * 20 / val);
+  			gc.setBackground(label.getBackground());
+  			gc.fillRectangle(padding, 0, x, y);
+  			// gc.drawImage(imgRec, 1, 0, x, 20, 0, y, x, 20 - y);
+  			gc.copyArea(padding + 1, 0, x, 20, padding, y);
+  			max[0] = val;
+  		} else {
+  			gc.copyArea(padding + 1, 0, x, 20, padding, 0);
+  			// gc.drawImage(imgRec, 1, 0, x, 20, 0, 0, x, 20);
+  		}
+  		gc.setForeground(label.getBackground());
+  		int breakPoint = 20 - (max[0] == 0 ? 0
+  				: (int) (val * 20 / max[0]));
+  		gc.drawLine(x, 0, x, breakPoint);
+  		gc.setForeground(Colors.blues[5]);
+  		gc.drawLine(x, breakPoint, x, 20);
+		} finally {
+  		gc.dispose();
 		}
+		label.redraw();
 	}
 
 	/**
@@ -1148,6 +1474,8 @@ public class MainStatusBar
 		// IP Filter Status Section
 		IpFilter ip_filter = azureusCore.getIpFilterManager().getIPFilter();
 
+		ipBlocked.setForeground( display.getSystemColor(ip_filter.isEnabled()? SWT.COLOR_WIDGET_FOREGROUND : SWT.COLOR_WIDGET_NORMAL_SHADOW));
+		
 		ipBlocked.setText("IPs: "
 				+ numberFormat.format(ip_filter.getNbRanges())
 				+ " - "
@@ -1156,9 +1484,11 @@ public class MainStatusBar
 				+ numberFormat.format(ip_filter.getNbBannedIps())
 				+ "/"
 				+ numberFormat.format(azureusCore.getIpFilterManager().getBadIps().getNbBadIps()));
+		
 		ipBlocked.setToolTipText(MessageText.getString("MainWindow.IPs.tooltip",
 				new String[] {
-					DisplayFormatters.formatDateShort(ip_filter.getLastUpdateTime())
+					ip_filter.isEnabled()?
+					DisplayFormatters.formatDateShort(ip_filter.getLastUpdateTime()):MessageText.getString( "ipfilter.disabled" )
 				}));
 	}
 
@@ -1177,12 +1507,6 @@ public class MainStatusBar
 		return statusText.getDisplay().getCursorControl() == statusText;
 	}
 
-	public static interface CLabelUpdater
-	{
-		public void created(CLabel label);
-		public void update(CLabel label);
-	}
-
 	/**
 	 * CLabel that shrinks to fit text after a specific period of time.
 	 * Makes textual changes less jumpy
@@ -1191,14 +1515,20 @@ public class MainStatusBar
 	 * @created Mar 21, 2006
 	 *
 	 */
-	private class CLabelPadding
-		extends CLabel
+	public class CLabelPadding
+		extends Canvas implements PaintListener
 	{
 		private int lastWidth = 0;
 
 		private long widthSetOn = 0;
 
 		private static final int KEEPWIDTHFOR_MS = 30 * 1000;
+		
+		String text = "";
+
+		private Image image;
+
+		private Image bgImage;
 
 		/**
 		 * Default Constructor
@@ -1207,12 +1537,156 @@ public class MainStatusBar
 		 * @param style
 		 */
 		public CLabelPadding(Composite parent, int style) {
-			super(parent, style | SWT.CENTER);
+			super(parent, style | SWT.DOUBLE_BUFFERED);
 
 			GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER
 					| GridData.VERTICAL_ALIGN_FILL);
 			setLayoutData(gridData);
 			setForeground(parent.getForeground());
+			
+			addPaintListener(this);
+		}
+
+		public void paintControl(PaintEvent e) {
+			Point size = getSize();
+			e.gc.setAdvanced(true);
+			if (bgImage != null && !bgImage.isDisposed()) {
+				Rectangle bounds = bgImage.getBounds();
+				if (display.getCursorControl() != this) {
+					e.gc.setAlpha(100);
+				}
+				e.gc.drawImage(bgImage, 0, 0, bounds.width, bounds.height, 0, 2,
+						size.x, size.y - 4);
+				e.gc.setAlpha(255);
+			}
+			Rectangle clientArea = getClientArea();
+			
+
+			Image image = getImage();
+			Rectangle imageBounds = null;
+			if (image != null && !image.isDisposed()) {
+				imageBounds = image.getBounds();
+			}
+			GCStringPrinter sp = new GCStringPrinter(e.gc, getText(), clientArea,
+					true, true, SWT.CENTER);
+			sp.calculateMetrics();
+			Point textSize = sp.getCalculatedSize();
+
+			if (imageBounds != null) {
+				int pad = 2;
+				int ofs = imageBounds.width + imageBounds.x;
+				int xStartImage = (clientArea.width - textSize.x - ofs - pad) / 2;
+				e.gc.drawImage(image, xStartImage,
+						(clientArea.height / 2) - (imageBounds.height / 2));
+				clientArea.x += xStartImage + ofs + pad;
+				clientArea.width -= xStartImage + ofs + pad;
+			} else {
+				int ofs = (clientArea.width / 2) - (textSize.x / 2);
+				clientArea.x += ofs;
+				clientArea.width -= ofs;
+			}
+			sp.printString(e.gc, clientArea, SWT.LEFT);
+
+			int x = clientArea.x + clientArea.width - 1;
+			e.gc.setAlpha(20);
+			e.gc.drawLine(x, 3, x, clientArea.height - 3);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.swt.custom.CLabel#computeSize(int, int, boolean)
+		 */
+		public Point computeSize(int wHint, int hHint) {
+			return computeSize(wHint, hHint, true);
+		}
+
+		public Point computeSize(int wHint, int hHint, boolean changed) {
+			try {
+				Point pt = computeSize(wHint, hHint, changed, false);
+
+				return pt;
+			} catch (Throwable t) {
+				Debug.out("Error while computing size for CLabel with text:"
+						+ getText() + "; " + t.toString());
+				return new Point(0, 0);
+			}
+		}
+
+		// @see org.eclipse.swt.widgets.Control#computeSize(int, int)
+		public Point computeSize(int wHint, int hHint, boolean changed, boolean realWidth) {
+			if (!isVisible()) {
+				return (new Point(0, 0));
+			}
+
+			if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
+				return new Point(wHint, hHint);
+			}
+			Point pt = new Point(wHint, hHint);
+
+			Point lastSize = new Point(0, 0);
+
+			Image image = getImage();
+			if (image != null && !image.isDisposed()) {
+				Rectangle bounds = image.getBounds();
+				int ofs = bounds.width + bounds.x + 5;
+				lastSize.x += ofs;
+				lastSize.y = bounds.height;
+			}
+
+			GC gc = new GC(this);
+			GCStringPrinter sp = new GCStringPrinter(gc, getText(), new Rectangle(0,
+					0, 10000, 20), true, true, SWT.LEFT);
+			sp.calculateMetrics();
+			Point lastTextSize = sp.getCalculatedSize();
+			gc.dispose();
+
+			lastSize.x += lastTextSize.x + 10;
+			lastSize.y = Math.max(lastSize.y, lastTextSize.y);
+
+			if (wHint == SWT.DEFAULT) {
+				pt.x = lastSize.x;
+			}
+			if (hHint == SWT.DEFAULT) {
+				pt.y = lastSize.y;
+			}
+
+			if (!realWidth) {
+	  			long now = System.currentTimeMillis();
+	  			if (lastWidth > pt.x && now - widthSetOn < KEEPWIDTHFOR_MS) {
+	  				pt.x = lastWidth;
+	  			} else {
+	  				if (lastWidth != pt.x) {
+	  					lastWidth = pt.x;
+	  				}
+	  				widthSetOn = now;
+	  			}
+			}
+
+			return pt;
+		}
+		
+
+		public void setImage(Image image) {
+			this.image = image;
+			
+			redraw();
+		}
+		
+		public Image getImage() {
+			return image;
+		}
+		
+		public void setBackgroundImage(Image image) {
+			bgImage = image;
+			
+			redraw();
+		}
+		
+		public Image getBackgroundImage() {
+			return bgImage;
+		}
+		
+		public String getText() {
+			return text;
 		}
 		
 		public void setText(String text) {
@@ -1222,47 +1696,36 @@ public class MainStatusBar
 			if (text.equals(getText())) {
 				return;
 			}
-			super.setText(text);
+			this.text = text;
 			int oldWidth = lastWidth;
-			Point pt = super.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
-			pt.x += 4;
+			Point pt = computeSize(SWT.DEFAULT, SWT.DEFAULT, true, true);
 			if (pt.x > oldWidth && text.length() > 0) {
 				statusBar.layout();
 			} else if (pt.x < oldWidth) {
 				Utils.execSWTThreadLater(KEEPWIDTHFOR_MS, new AERunnable() {
 					public void runSupport() {
+						if (statusBar == null || statusBar.isDisposed()) {
+							return;
+						}
 						statusBar.layout();
 					}
 				});
 			}
+			redraw();
 		}
-
-		/* (non-Javadoc)
-		 * @see org.eclipse.swt.custom.CLabel#computeSize(int, int, boolean)
-		 */
-		public Point computeSize(int wHint, int hHint, boolean changed) {
-			if (!isVisible()) {
-				return (new Point(0, 0));
-			}
-			try {
-				Point pt = super.computeSize(wHint, hHint, changed);
-  			pt.x += 4;
-  
-  			long now = System.currentTimeMillis();
-  			if (lastWidth > pt.x && now - widthSetOn < KEEPWIDTHFOR_MS) {
-  				pt.x = lastWidth;
-  			} else {
-  				if (lastWidth != pt.x)
-  					lastWidth = pt.x;
-  				widthSetOn = now;
-  			}
-  
-  			return pt;
-			} catch (Throwable t) {
-				Debug.out("Error while computing size for CLabel with text:" + getText());
-				return new Point(0, 0);
-			}
+		
+		public void
+		reset()
+		{
+			widthSetOn 	= 0;
+			lastWidth	= 0;
+		}
+		
+		public void layoutNow() {
+			widthSetOn = 0;
+			statusBar.layout();
 		}
+
 	}
 
 	private class UpdateableCLabel
@@ -1277,7 +1740,9 @@ public class MainStatusBar
 		}
 
 		private void checkForRefresh() {
-			updater.update(this);
+			if ( updater.update(this)){
+				layoutPluginComposite();
+			}
 		}
 	}
 
@@ -1287,6 +1752,7 @@ public class MainStatusBar
 				UpdateableCLabel result = new UpdateableCLabel(plugin_label_composite, borderFlag,
 						updater);
 				result.setLayoutData(new GridData(GridData.FILL_BOTH));
+				layoutPluginComposite();
 				updater.created(result);
 			}
 		};
@@ -1303,6 +1769,17 @@ public class MainStatusBar
 		Utils.execSWTThread(r);
 	}
 
+	private void
+	layoutPluginComposite()
+	{
+		Control[] plugin_elements = this.plugin_label_composite.getChildren();
+		for (int i = 0; i < plugin_elements.length; i++) {
+			if (plugin_elements[i] instanceof UpdateableCLabel) {
+				((UpdateableCLabel) plugin_elements[i]).reset();
+			}
+		}
+		statusBar.layout();
+	}
 	// =============================================================
 	// Below code are ProgressBar/Status text specific
 	// =============================================================	
@@ -1405,7 +1882,7 @@ public class MainStatusBar
 		} else {
 			imageID = "progress_viewer";
 		}
-
+		
 		if (!imageID.equals(lastProgressImageID)) {
 			final String fImageID = imageID;
 			Utils.execSWTThread(new AERunnable() {
@@ -1431,7 +1908,7 @@ public class MainStatusBar
 	 *
 	 */
 	private class ProgressListener
-		implements IProgressReportingListener, IProgressReportConstants
+		implements IProgressReportingListener
 	{
 
 		public int reporting(int eventType, IProgressReporter reporter) {
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java b/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java
deleted file mode 100644
index b81c5ec..0000000
--- a/org/gudy/azureus2/ui/swt/mainwindow/MainWindow.java
+++ /dev/null
@@ -1,1820 +0,0 @@
-/*
- * Created on Jun 25, 2003
- * Modified Apr 13, 2004 by Alon Rohter
- * Modified Apr 17, 2004 by Olivier Chalouhi (OSX system menu)
- * 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.mainwindow;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.SWTError;
-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.config.COConfigurationManager;
-import org.gudy.azureus2.core3.config.ParameterListener;
-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.GlobalManagerAdapter;
-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.plugins.*;
-import org.gudy.azureus2.plugins.sharing.ShareException;
-import org.gudy.azureus2.plugins.sharing.ShareManager;
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
-import org.gudy.azureus2.ui.swt.*;
-import org.gudy.azureus2.ui.swt.associations.AssociationChecker;
-import org.gudy.azureus2.ui.swt.components.shell.ShellManager;
-import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateShell;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateTab;
-import org.gudy.azureus2.ui.swt.donations.DonationWindow;
-import org.gudy.azureus2.ui.swt.maketorrent.NewTorrentWizard;
-import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
-import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
-import org.gudy.azureus2.ui.swt.plugins.UISWTView;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-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;
-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.welcome.WelcomeWindow;
-import org.gudy.azureus2.ui.systray.SystemTraySWT;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreException;
-import com.aelitis.azureus.core.AzureusCoreFactory;
-import com.aelitis.azureus.core.versioncheck.VersionCheckClient;
-import com.aelitis.azureus.ui.UIFunctionsManager;
-import com.aelitis.azureus.ui.UIStatusTextClickListener;
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.util.MapUtils;
-
-/**
- * @author Olivier
- * Runnable : so that GUI initialization is done via asyncExec(this)
- * STProgressListener : To make it visible once initialization is done
- */
-public class MainWindow
-	extends AERunnable
-	implements ParameterListener, IconBarEnabler, AEDiagnosticsEvidenceGenerator,
-	ObfusticateShell, IMainWindow
-{
-	private static final LogIDs LOGID = LogIDs.GUI;
-
-	private static MainWindow window;
-
-	private Initializer initializer;
-
-	private AzureusCore azureus_core;
-
-	private GlobalManager globalManager;
-
-	//NICO handle swt on macosx
-	public static boolean isAlreadyDead = false;
-
-	public static boolean isDisposeFromListener = false;
-
-	private Display display;
-
-	private Composite parent;
-
-	private Shell shell;
-
-	private IMainMenu mainMenu;
-
-	private IconBar iconBar;
-
-	private Composite folder;
-
-	/** 
-	 * Handles initializing and refreshing the status bar (w/help of GUIUpdater)
-	 */
-	private MainStatusBar mainStatusBar;
-
-	private TrayWindow downloadBasket;
-
-	private SystemTraySWT systemTraySWT;
-
-	private HashMap downloadViews;
-
-	private AEMonitor downloadViews_mon = new AEMonitor("MainWindow:dlviews");
-
-	private Item mytorrents;
-	
-	private Item detailed_list;
-
-	private Item all_peers;
-
-	private Item my_tracker_tab;
-
-	private Item my_shares_tab;
-
-	private Item stats_tab;
-
-	private Item console;
-
-	private Item multi_options_tab;
-
-	private Item config;
-
-	private Item viewClientStats;
-	
-	private ConfigView config_view;
-
-	protected AEMonitor this_mon = new AEMonitor("MainWindow");
-
-	private UISWTInstanceImpl uiSWTInstanceImpl = null;
-
-	private ArrayList events;
-
-	private UIFunctionsSWT uiFunctions;
-
-	private boolean bIconBarEnabled = false;
-
-	private boolean bShowMainWindow;
-
-	private boolean bSettingVisibility = false;
-
-	private Tab mainTabSet;
-
-	public MainWindow(AzureusCore _azureus_core, Initializer _initializer,
-			ArrayList events) {
-		bShowMainWindow = true;
-		try {
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "MainWindow start"));
-
-			AEDiagnostics.addEvidenceGenerator(this);
-
-			azureus_core = _azureus_core;
-
-			globalManager = azureus_core.getGlobalManager();
-
-			initializer = _initializer;
-
-			display = SWTThread.getInstance().getDisplay();
-
-			window = this;
-
-			this.events = events;
-
-			display.asyncExec(this);
-
-		} catch (AzureusCoreException e) {
-
-			Debug.printStackTrace(e);
-		}
-	}
-
-	/**
-	 * runSupport() MUST BE CALLED TO FINISH INITIALIZATION
-	 * @param _azureus_core
-	 * @param _initializer
-	 * @param shell
-	 * @param parent
-	 */
-	public MainWindow(AzureusCore _azureus_core, Initializer _initializer,
-			Shell shell, Composite parent, UISWTInstanceImpl swtinstance) {
-		this.shell = shell;
-		this.parent = parent;
-		bShowMainWindow = true;
-
-		try {
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "MainWindow start"));
-
-			AEDiagnostics.addEvidenceGenerator(this);
-
-			azureus_core = _azureus_core;
-
-			globalManager = azureus_core.getGlobalManager();
-
-			initializer = _initializer;
-
-			display = SWTThread.getInstance().getDisplay();
-
-			window = this;
-
-			uiSWTInstanceImpl = swtinstance;
-
-		} catch (AzureusCoreException e) {
-
-			Debug.printStackTrace(e);
-		}
-	}
-	
-	public MainWindow() {
-		bShowMainWindow = true;
-
-		try {
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "MainWindow start"));
-
-			AEDiagnostics.addEvidenceGenerator(this);
-
-			azureus_core = AzureusCoreFactory.getSingleton();
-
-			globalManager = azureus_core.getGlobalManager();
-
-			display = SWTThread.getInstance().getDisplay();
-
-			window = this;
-
-		} catch (AzureusCoreException e) {
-
-			Debug.printStackTrace(e);
-		}
-	}
-	
-	public void init(Composite parent, UISWTInstanceImpl swtInstance) {
-		this.parent = parent;
-		this.shell = parent.getShell();
-		uiSWTInstanceImpl = swtInstance;
-	}
-
-
-	public void setShowMainWindow(boolean b) {
-		bShowMainWindow = b;
-	}
-
-	// @see org.gudy.azureus2.core3.util.AERunnable#runSupport()
-	public void runSupport() {
-		FormData formData;
-
-		try {
-			uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (uiFunctions == null) {
-				uiFunctions = new UIFunctionsImpl(this);
-				UIFunctionsManager.setUIFunctions(uiFunctions);
-			} else {
-				uiFunctions = new UIFunctionsImpl(this);
-			}
-
-			globalManager.loadExistingTorrentsNow(true);
-
-			COConfigurationManager.addParameterListener("config.style.useSIUnits", this);
-			COConfigurationManager.addParameterListener("config.style.forceSIValues", this);
-
-			mytorrents = null;
-			my_tracker_tab = null;
-			console = null;
-			config = null;
-			config_view = null;
-			downloadViews = new HashMap();
-
-			Control attachToTopOf = null;
-			Control controlAboveFolder = null;
-			Control controlBelowFolder = null;
-
-			//The Main Window
-			if (shell == null) {
-				shell = new Shell(display, SWT.RESIZE | SWT.BORDER | SWT.CLOSE
-						| SWT.MAX | SWT.MIN);
-				shell.setData("class", this);
-				shell.setText(Constants.APP_NAME); //$NON-NLS-1$
-				Utils.setShellIcon(shell);
-
-				if (parent == null) {
-					parent = shell;
-				}
-
-				// register window
-				ShellManager.sharedManager().addWindow(shell);
-
-				mainMenu = new MainMenu(shell);
-
-				FormLayout mainLayout = new FormLayout();
-				mainLayout.marginHeight = 0;
-				mainLayout.marginWidth = 0;
-				try {
-					mainLayout.spacing = 0;
-				} catch (NoSuchFieldError e) { /* Pre SWT 3.0 */
-				}
-				shell.setLayout(mainLayout);
-
-				Utils.linkShellMetricsToConfig(shell, "window");
-
-				//NICO catch the dispose event from file/quit on osx
-				shell.addDisposeListener(new DisposeListener() {
-					public void widgetDisposed(DisposeEvent event) {
-						if (!isAlreadyDead) {
-							isDisposeFromListener = true;
-							if (shell != null) {
-								shell.removeDisposeListener(this);
-								dispose(false, false);
-							}
-							isAlreadyDead = true;
-						}
-					}
-				});
-
-				shell.addShellListener(new ShellAdapter() {
-					public void shellClosed(ShellEvent event) {
-						if (bSettingVisibility) {
-							return;
-						}
-						if (systemTraySWT != null
-								&& COConfigurationManager.getBooleanParameter("Enable System Tray")
-								&& COConfigurationManager.getBooleanParameter("Close To Tray")) {
-
-							minimizeToTray(event);
-						} else {
-							event.doit = dispose(false, false);
-						}
-					}
-
-					public void shellIconified(ShellEvent event) {
-						if (bSettingVisibility) {
-							return;
-						}
-						if (systemTraySWT != null
-								&& COConfigurationManager.getBooleanParameter("Enable System Tray")
-								&& COConfigurationManager.getBooleanParameter("Minimize To Tray")) {
-
-							minimizeToTray(event);
-						}
-					}
-
-					public void shellDeiconified(ShellEvent e) {
-						if (Constants.isOSX
-								&& COConfigurationManager.getBooleanParameter("Password enabled")) {
-							shell.setVisible(false);
-							if (PasswordWindow.showPasswordWindow(display)) {
-								shell.setVisible(true);
-							}
-						}
-					}
-				});
-
-				// Separator between menu and icon bar
-				Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
-				formData = new FormData();
-				formData.top = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
-				formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
-				formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
-				separator.setLayoutData(formData);
-
-				attachToTopOf = separator;
-
-				mainStatusBar = new MainStatusBar();
-				Composite statusBar = mainStatusBar.initStatusBar(shell);
-
-				controlAboveFolder = attachToTopOf;
-				controlBelowFolder = statusBar;
-
-			}
-
-			try {
-				Utils.createTorrentDropTarget(parent, true);
-			} catch (SWTError e) {
-				// "Cannot initialize Drop".. don't spew stack trace
-				Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING,
-						"Drag and Drop not available: " + e.getMessage()));
-			} catch (Throwable e) {
-				Logger.log(new LogEvent(LOGID, "Drag and Drop not available", e));
-			}
-
-			mainTabSet = new Tab(this);
-			folder = mainTabSet.createFolderWidget(parent);
-
-			formData = new FormData();
-			if (controlAboveFolder == null) {
-				formData.top = new FormAttachment(0, 0);
-			} else {
-				formData.top = new FormAttachment(controlAboveFolder);
-			}
-
-			if (controlBelowFolder == null) {
-				formData.bottom = new FormAttachment(100, 0);
-			} else {
-				formData.bottom = new FormAttachment(controlBelowFolder);
-			}
-			formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
-			formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
-			folder.setLayoutData(formData);
-
-			display.addFilter(SWT.KeyDown, new Listener() {
-				public void handleEvent(Event event) {
-					// Another window has control, skip filter
-					Control focus_control = display.getFocusControl();
-					if (focus_control != null && focus_control.getShell() != shell)
-						return;
-
-					int key = event.character;
-					if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
-							&& event.character > 0)
-						key += 'a' - 1;
-
-					if (key == 'l' && (event.stateMask & SWT.MOD1) != 0) {
-						// Ctrl-L: Open URL
-						OpenTorrentWindow.invokeURLPopup(shell, globalManager);
-						event.doit = false;
-					}
-				}
-			});
-
-			if (Logger.isEnabled())
-				Logger.log(new LogEvent(LOGID, "Initializing GUI complete"));
-
-			globalManager.addListener(new GlobalManagerAdapter() {
-				public void downloadManagerAdded(DownloadManager dm) {
-					MainWindow.this.downloadManagerAdded(dm);
-				}
-
-				public void downloadManagerRemoved(DownloadManager dm) {
-					MainWindow.this.downloadManagerRemoved(dm);
-				}
-			});
-
-			PluginManager plugin_manager = azureus_core.getPluginManager();
-
-			plugin_manager.firePluginEvent(PluginEvent.PEV_CONFIGURATION_WIZARD_STARTS);
-
-			if (!COConfigurationManager.getBooleanParameter("Wizard Completed")) {
-				// returns after the wizard is done
-				new ConfigureWizard(true);
-			}
-
-			plugin_manager.firePluginEvent(PluginEvent.PEV_CONFIGURATION_WIZARD_COMPLETES);
-
-			// attach the UI to plugins
-			// Must be done before initializing views, since plugins may register
-			// table columns and other objects
-			if (uiSWTInstanceImpl == null) {
-				TableColumnCreator.initCoreColumns();
-
-				uiSWTInstanceImpl = new UISWTInstanceImpl(azureus_core);
-				uiSWTInstanceImpl.init(initializer);
-
-				// check if any plugins shut us down
-				if (isAlreadyDead) {
-					return;
-				}
-
-				postPluginSetup(0, 50);
-			}
-
-		} catch (Throwable e) {
-			Debug.printStackTrace(e);
-		}
-
-		showMainWindow();
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.0.4.3
-	 */
-	public void postPluginSetup(int delay, final int delayInc) {
-		if (initializer != null) {
-			initializer.reportCurrentTask(MessageText.getString("splash.openViews"));
-			initializer.nextTask();
-		}
-
-		if (!Constants.isSafeMode && azureus_core.getTrackerHost().getTorrents().length > 0) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					showMyTracker();
-				}
-			});
-		}
-
-		// share manager init is async so we need to deal with this
-
-		PluginInterface default_pi = PluginInitializer.getDefaultInterface();
-
-		try {
-			final ShareManager share_manager = default_pi.getShareManager();
-
-			default_pi.addListener(new PluginListener() {
-				public void initializationComplete() {
-				}
-
-				public void closedownInitiated() {
-					int share_count = share_manager.getShares().length;
-
-					if (share_count != COConfigurationManager.getIntParameter("GUI_SWT_share_count_at_close")) {
-
-						COConfigurationManager.setParameter("GUI_SWT_share_count_at_close",
-								share_count);
-					}
-				}
-
-				public void closedownComplete() {
-				}
-			});
-
-			if (share_manager.getShares().length > 0
-					|| COConfigurationManager.getIntParameter("GUI_SWT_share_count_at_close") > 0) {
-
-				Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-					public void run() {
-						showMyShares();
-					}
-				});
-			}
-		} catch (ShareException e) {
-			Debug.out(e);
-		}
-
-		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open MyTorrents")) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					showMyTorrents();
-				}
-			});
-		}
-
-		//  share progress window
-
-		new ProgressWindow();
-
-		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open Console")) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					showConsole();
-				}
-			});
-		}
-		events = null;
-
-		if (Constants.isSafeMode || COConfigurationManager.getBooleanParameter("Open Config")) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					showConfig();
-				}
-			});
-		}
-
-		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open Stats On Start")) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					showStats();
-				}
-			});
-		}
-
-		if (!Constants.isSafeMode && COConfigurationManager.getBooleanParameter("Open Transfer Bar On Start")) {
-			Utils.execSWTThreadLater(delay += delayInc, new Runnable() {
-				public void run() {
-					uiFunctions.showGlobalTransferBar();
-				}
-			});
-		}
-
-		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) {
-						setIconBarEnabled(COConfigurationManager.getBooleanParameter(parameterName));
-					}
-				});
-
-		// init done
-		if (initializer != null)
-			initializer.abortProgress();
-	}
-
-	protected boolean getIconBarEnabled() {
-		return bIconBarEnabled;
-	}
-
-	protected void setIconBarEnabled(boolean enabled) {
-		if (enabled == bIconBarEnabled || shell.isDisposed()) {
-			return;
-		}
-		bIconBarEnabled = enabled;
-		COConfigurationManager.setParameter("IconBar.enabled", bIconBarEnabled);
-		if (bIconBarEnabled) {
-			try {
-				iconBar = new IconBar(parent);
-				iconBar.setCurrentEnabler(this);
-				Composite cIconBar = iconBar.getComposite();
-
-				FormData folderLayoutData = (FormData) folder.getLayoutData();
-
-				FormData formData = new FormData();
-				if (folderLayoutData.top != null
-						&& folderLayoutData.top.control != null) {
-					formData.top = new FormAttachment(folderLayoutData.top.control);
-				} else {
-					formData.top = new FormAttachment(0, 0);
-				}
-				folderLayoutData.top = new FormAttachment(cIconBar);
-
-				formData.left = new FormAttachment(0, 0); // 2 params for Pre SWT 3.0
-				formData.right = new FormAttachment(100, 0); // 2 params for Pre SWT 3.0
-				this.iconBar.setLayoutData(formData);
-
-			} catch (Exception e) {
-				Logger.log(new LogEvent(LOGID, "Creating Icon Bar", e));
-			}
-		} else if (iconBar != null) {
-			try {
-				FormData folderLayoutData = (FormData) folder.getLayoutData();
-				FormData iconBarLayoutData = (FormData) iconBar.getComposite().getLayoutData();
-
-				if (iconBarLayoutData.top != null
-						&& iconBarLayoutData.top.control != null) {
-					folderLayoutData.top = new FormAttachment(
-							iconBarLayoutData.top.control);
-				} else {
-					folderLayoutData.top = new FormAttachment(0, 0);
-				}
-
-				iconBar.delete();
-				iconBar = null;
-			} catch (Exception e) {
-				Logger.log(new LogEvent(LOGID, "Removing Icon Bar", e));
-			}
-		}
-		shell.layout(true, true);
-	}
-
-	private void showMainWindow() {
-		COConfigurationManager.addAndFireParameterListener("Show Download Basket",this);
-
-		if (!bShowMainWindow) {
-			return;
-		}
-
-		boolean bEnableTray = COConfigurationManager.getBooleanParameter("Enable System Tray");
-		boolean bPassworded = COConfigurationManager.getBooleanParameter("Password enabled");
-		boolean bStartMinimize = bEnableTray
-				&& (bPassworded || COConfigurationManager.getBooleanParameter("Start Minimized"));
-
-		if (!bStartMinimize) {
-			shell.layout();
-			shell.open();
-			if (!Constants.isOSX) {
-				shell.forceActive();
-			}
-		} else if (Constants.isOSX) {
-			shell.setMinimized(true);
-			shell.setVisible(true);
-		}
-
-		if (bEnableTray) {
-
-			try {
-				systemTraySWT = new SystemTraySWT();
-
-			} catch (Throwable e) {
-
-				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-						"Upgrade to SWT3.0M8 or later for system tray support."));
-			}
-
-			if (bStartMinimize) {
-				minimizeToTray(null);
-			}
-			//Only show the password if not started minimized
-			//Correct bug #878227
-			else {
-				if (bPassworded) {
-					minimizeToTray(null);
-					setVisible(true, true); // invokes password
-				}
-			}
-		}
-
-			// do this before other checks as these are blocking dialogs to force order
-
-		if ( initializer != null ){
-			
-			initializer.initializationComplete();
-		}
-		
-		checkForWhatsNewWindow();
-
-			// check file associations  
-	
-		AssociationChecker.checkAssociations();
-
-		// Donation stuff
-		Map map = VersionCheckClient.getSingleton().getMostRecentVersionCheckData();
-		DonationWindow.setInitialAskHours(MapUtils.getMapInt(map,
-				"donations.askhrs", DonationWindow.getInitialAskHours()));
-
-		azureus_core.triggerLifeCycleComponentCreated(uiFunctions);
-	}
-
-	protected void showMyTracker() {
-		if (my_tracker_tab == null) {
-			my_tracker_tab = mainTabSet.createTabItem(new MyTrackerView(), true);
-			mainTabSet.getView(my_tracker_tab).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							my_tracker_tab = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(my_tracker_tab);
-			refreshIconBar();
-			refreshTorrentMenu();
-		}
-	}
-
-	protected void showMyShares() {
-		if (my_shares_tab == null) {
-			my_shares_tab = mainTabSet.createTabItem(new MySharesView(), true);
-			mainTabSet.getView(my_shares_tab).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							my_shares_tab = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(my_shares_tab);
-			refreshIconBar();
-			refreshTorrentMenu();
-		}
-	}
-
-	protected void showMyTorrents() {
-		if (mytorrents == null) {
-			MyTorrentsSuperView view = new MyTorrentsSuperView();
-			mytorrents = mainTabSet.createTabItem(view, true);
-			mainTabSet.getView(mytorrents).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							mytorrents = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(mytorrents);
-		}
-		refreshIconBar();
-		refreshTorrentMenu();
-	}
-	
-	protected void showDetailedListView() {
-		if (detailed_list == null) {
-			DetailedListView view = new DetailedListView(azureus_core);
-			detailed_list = mainTabSet.createTabItem(view, true);
-			mainTabSet.getView(detailed_list).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							detailed_list = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(detailed_list);
-		}
-		refreshIconBar();
-		refreshTorrentMenu();
-	}
-
-	protected void showAllPeersView() {
-		if (all_peers == null) {
-			PeerSuperView view = new PeerSuperView();
-			all_peers = mainTabSet.createTabItem(view, true);
-			mainTabSet.getView(all_peers).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							all_peers = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(all_peers);
-		}
-		refreshIconBar();
-		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();
-		}
-
-		TorrentOptionsView view = new TorrentOptionsView(managers);
-
-		multi_options_tab = mainTabSet.createTabItem(view, true);
-
-		view.getComposite().addDisposeListener(new DisposeListener() {
-			public void widgetDisposed(DisposeEvent e) {
-				multi_options_tab = null;
-			}
-		});
-
-		refreshIconBar();
-		refreshTorrentMenu();
-	}
-
-	private void minimizeToTray(ShellEvent event) {
-		//Added this test so that we can call this method with null parameter.
-		if (event != null)
-			event.doit = false;
-
-		// XXX hack for release.. should not access param outside Utils.linkShellMetrics
-		COConfigurationManager.setParameter("window.maximized",
-				shell.getMaximized());
-		shell.setVisible(false);
-
-		if (downloadBasket != null)
-			downloadBasket.setVisible(true);
-
-		MiniBarManager.getManager().setAllVisible(true);
-	}
-
-	private void updateComponents() {
-		if (mainStatusBar != null)
-			mainStatusBar.refreshStatusText();
-
-		if (mainTabSet != null) {
-			mainTabSet.update();
-		}
-	}
-
-	private void downloadManagerAdded(DownloadManager created) {
-		// only do donation check if swt instance is initialized, which means
-		// initial download managers are loaded and this main window is really
-		// the main window
-		if (uiSWTInstanceImpl != null
-				&& !created.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-			DonationWindow.checkForDonationPopup();
-		}
-	}
-
-	protected void openManagerView(DownloadManager downloadManager) {
-		try {
-			downloadViews_mon.enter();
-
-			if (downloadViews.containsKey(downloadManager)) {
-				mainTabSet.setFocus((Item) downloadViews.get(downloadManager));
-				refreshIconBar();
-				refreshTorrentMenu();
-			} else {
-				Item tab = openPluginView(null, "DMView", new ManagerView(),
-						downloadManager, true, true);
-//				Item tab = mainTabSet.createTabItem(new ManagerView(azureus_core,
-//						downloadManager), true);
-				downloadViews.put(downloadManager, tab);
-			}
-		} finally {
-
-			downloadViews_mon.exit();
-		}
-	}
-
-	protected void removeManagerView(DownloadManager downloadManager) {
-		try {
-			downloadViews_mon.enter();
-
-			downloadViews.remove(downloadManager);
-		} finally {
-
-			downloadViews_mon.exit();
-		}
-	}
-
-	private void downloadManagerRemoved(DownloadManager removed) {
-		try {
-			downloadViews_mon.enter();
-
-			if (downloadViews.containsKey(removed)) {
-				final Item tab = (Item) downloadViews.get(removed);
-				Utils.execSWTThread(new AERunnable() {
-					public void runSupport() {
-						if (display == null || display.isDisposed())
-							return;
-
-						mainTabSet.dispose(tab);
-					}
-				});
-
-			}
-		} finally {
-
-			downloadViews_mon.exit();
-		}
-	}
-
-	protected Display getDisplay() {
-		return this.display;
-	}
-
-	protected Shell getShell() {
-		return shell;
-	}
-
-	public void setVisible(final boolean visible, final boolean tryTricks) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				bSettingVisibility = true;
-				try {
-					boolean currentlyVisible = shell.getVisible()
-							&& !shell.getMinimized();
-					if (visible && !currentlyVisible) {
-						if (COConfigurationManager.getBooleanParameter("Password enabled",
-								false)) {
-							if (!PasswordWindow.showPasswordWindow(display)) {
-								shell.setVisible(false);
-								return;
-							}
-						}
-					}
-
-					ArrayList wasVisibleList = null;
-					boolean bHideAndShow = false;
-					// temp disabled
-					//tryTricks && visible && Constants.isWindows && display.getActiveShell() != shell;
-					if (bHideAndShow) {
-						wasVisibleList = new ArrayList();
-						// We don't want the window to just flash and not open, so:
-						// -Minimize main shell
-						// -Set all shells invisible
-						try {
-							shell.setMinimized(true);
-							Shell[] shells = shell.getDisplay().getShells();
-							for (int i = 0; i < shells.length; i++) {
-								if (shells[i].isVisible()) {
-									wasVisibleList.add(shells[i]);
-									shells[i].setVisible(false);
-								}
-							}
-						} catch (Exception e) {
-						}
-					}
-
-					if (visible) {
-						if (shell.getMinimized()) {
-							shell.setMinimized(false);
-						}
-						if (!currentlyVisible
-								&& COConfigurationManager.getBooleanParameter("window.maximized")) {
-							shell.setMaximized(true);
-						}
-					} else {
-						// XXX hack for release.. should not access param outside Utils.linkShellMetrics
-						COConfigurationManager.setParameter("window.maximized",
-								shell.getMaximized());
-					}
-
-					shell.setVisible(visible);
-					if (visible) {
-						if (downloadBasket != null) {
-							downloadBasket.setVisible(false);
-							downloadBasket.setMoving(false);
-						}
-
-						/*
-						 if (trayIcon != null)
-						 trayIcon.showIcon();
-						 */
-						shell.forceActive();
-
-						if (bHideAndShow) {
-							try {
-								Shell[] shells = shell.getDisplay().getShells();
-								for (int i = 0; i < shells.length; i++) {
-									if (shells[i] != shell) {
-										if (wasVisibleList.contains(shells[i])) {
-											shells[i].setVisible(visible);
-										}
-										shells[i].setFocus();
-									}
-								}
-							} catch (Exception e) {
-							}
-						}
-					}
-				} finally {
-					bSettingVisibility = false;
-				}
-
-			}
-		});
-	}
-
-	protected boolean isVisible() {
-		return shell.isVisible();
-	}
-
-	public boolean dispose(final boolean for_restart,
-			final boolean close_already_in_progress) {
-		return Utils.execSWTThreadWithBool("MainWindow.dispose",
-				new AERunnableBoolean() {
-					public boolean runSupport() {
-						return _dispose(for_restart, close_already_in_progress);
-					}
-				});
-	}
-
-	private boolean _dispose(boolean for_restart,
-			boolean close_already_in_progress) {
-		if (isAlreadyDead) {
-			return true;
-		}
-
-		if (!UIExitUtilsSWT.canClose(globalManager, for_restart)) {
-			return false;
-		}
-
-		if (systemTraySWT != null) {
-			systemTraySWT.dispose();
-		}
-
-		/**
-		 * Explicitly force the transfer bar location to be saved (if appropriate and open).
-		 * 
-		 * We can't rely that the normal mechanism for doing this won't fail (which it usually does)
-		 * when the GUI is being disposed of.
-		 */
-		try {
-  		AllTransfersBar transfer_bar = AllTransfersBar.getBarIfOpen(AzureusCoreFactory.getSingleton().getGlobalManager());
-  		if (transfer_bar != null) {
-  			transfer_bar.forceSaveLocation();
-  		}
-		} catch (Exception e) {
-			// ignore
-		}
-
-		// close all tabs
-		mainTabSet.closeAllTabs();
-
-		isAlreadyDead = true; //NICO try to never die twice...
-		/*
-		if (this.trayIcon != null)
-		  SysTrayMenu.dispose();
-		*/
-
-		if (initializer != null) {
-			initializer.stopIt(for_restart, close_already_in_progress);
-		}
-
-		//NICO swt disposes the mainWindow all by itself (thanks... ;-( ) on macosx
-		if (!shell.isDisposed() && !isDisposeFromListener) {
-			shell.dispose();
-		}
-
-		COConfigurationManager.removeParameterListener("config.style.useSIUnits", this);
-		COConfigurationManager.removeParameterListener("config.style.forceSIValues", this);
-		
-		COConfigurationManager.removeParameterListener("Show Download Basket", this);
-
-		UIExitUtilsSWT.uiShutdown();
-
-		return true;
-	}
-
-	protected GlobalManager getGlobalManager() {
-		return globalManager;
-	}
-
-	/**
-	 * @return
-	 */
-	protected static MainWindow getWindow() {
-		return window;
-	}
-
-	/**
-	 * @return
-	 */
-	protected TrayWindow getTray() {
-		return downloadBasket;
-	}
-
-	Map pluginTabs = new HashMap();
-
-	protected Item openPluginView(String sParentID, String sViewID,
-			UISWTViewEventListener l, Object dataSource, boolean bSetFocus,
-			boolean useCoreDS) {
-
-		UISWTViewImpl view = null;
-		try {
-			view = new UISWTViewImpl(sParentID, sViewID, l);
-		} catch (Exception e) {
-			Item tab = (Item) pluginTabs.get(sViewID);
-			if (tab != null) {
-				mainTabSet.setFocus(tab);
-			}
-			return tab;
-		}
-		view.setUseCoreDataSource(useCoreDS);
-		view.dataSourceChanged(dataSource);
-
-		Item tab = mainTabSet.createTabItem(view, bSetFocus);
-
-		pluginTabs.put(sViewID, tab);
-		return tab;
-	}
-
-	/**
-	 * Close all plugin views with the specified ID
-	 * 
-	 * @param sViewID
-	 */
-	protected void closePluginViews(String sViewID) {
-		if (mainTabSet != null) {
-			mainTabSet.closePluginViews(sViewID);
-		}
-	}
-
-	/**
-	 * Get all open Plugin Views
-	 * 
-	 * @return open plugin views
-	 */
-	protected UISWTView[] getPluginViews() {
-		IView[] allViews = mainTabSet.getAllViews();
-
-		ArrayList views = new ArrayList();
-
-		for (int i = 0; i < allViews.length; i++) {
-			IView view = allViews[i];
-
-			if (view instanceof UISWTViewImpl) {
-				views.add(view);
-			}
-		}
-
-		return (UISWTView[]) views.toArray(new UISWTView[0]);
-	}
-
-	protected void openPluginView(final AbstractIView view, final String name) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				Item tab = (Item) pluginTabs.get(name);
-				if (tab != null) {
-					mainTabSet.setFocus(tab);
-				} else {
-					tab = mainTabSet.createTabItem(view, true);
-					pluginTabs.put(name, tab);
-				}
-			}
-		});
-	}
-
-	protected void closePluginView(IView view) {
-		Item tab = mainTabSet.getTab(view);
-
-		if (tab != null) {
-
-			mainTabSet.closed(tab);
-		}
-	}
-
-	public void removeActivePluginView(String view_name) {
-		pluginTabs.remove(view_name);
-	}
-
-	// @see org.gudy.azureus2.core3.config.ParameterListener#parameterChanged(java.lang.String)
-	public void parameterChanged(String parameterName) {
-		if (parameterName.equals("Show Download Basket")) {
-			if (COConfigurationManager.getBooleanParameter("Show Download Basket")) {
-				if (downloadBasket == null) {
-					downloadBasket = new TrayWindow(this);
-					downloadBasket.setVisible(true);
-				}
-			} else if (downloadBasket != null) {
-				downloadBasket.setVisible(false);
-				downloadBasket = null;
-			}
-		}
-
-		if (parameterName.equals("config.style.useSIUnits") || parameterName.equals("config.style.forceSIValues")) {
-			updateComponents();
-		}
-	}
-
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isEnabled(java.lang.String)
-	public boolean isEnabled(String itemKey) {
-		if (itemKey.equals("open"))
-			return true;
-		if (itemKey.equals("new"))
-			return true;
-		IView currentView = getCurrentView();
-		if (currentView instanceof UISWTViewImpl) {
-			UISWTViewEventListener eventListener = ((UISWTViewImpl) currentView).getEventListener();
-			if (eventListener instanceof IconBarEnabler) {
-				return ((IconBarEnabler)eventListener).isEnabled(itemKey);
-			}
-		}
-		if (currentView != null)
-			return currentView.isEnabled(itemKey);
-		return false;
-	}
-
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#isSelected(java.lang.String)
-	public boolean isSelected(String itemKey) {
-		return false;
-	}
-
-	// @see org.gudy.azureus2.ui.swt.IconBarEnabler#itemActivated(java.lang.String)
-	public void itemActivated(String itemKey) {
-		if (itemKey.equals("open")) {
-			TorrentOpener.openTorrentWindow();
-			return;
-		}
-		if (itemKey.equals("new")) {
-			new NewTorrentWizard(display);
-			return;
-		}
-		IView currentView = getCurrentView();
-		if (currentView instanceof UISWTViewImpl) {
-			UISWTViewEventListener eventListener = ((UISWTViewImpl) currentView).getEventListener();
-			if (eventListener instanceof IconBarEnabler) {
-				((IconBarEnabler)eventListener).itemActivated(itemKey);
-				return;
-			}
-		}
-		if (currentView != null)
-			currentView.itemActivated(itemKey);
-	}
-
-	IView getCurrentView() {
-		if (mainTabSet != null) {
-			return mainTabSet.getCurrentView();
-		}
-		return null;
-	}
-
-	protected void refreshIconBar() {
-		if (iconBar != null) {
-			iconBar.setCurrentEnabler(this);
-		}
-	}
-
-	protected void refreshTorrentMenu() {
-		if (this.mainMenu == null) {
-			return;
-		}
-		DownloadManager[] dm;
-		boolean detailed_view;
-		TableViewSWT tv = null;
-		IView currentView = getCurrentView();
-
-		if (currentView instanceof ManagerView) {
-			dm = new DownloadManager[] {
-				((ManagerView) currentView).getDownload(),
-			};
-			detailed_view = true;
-		} else if (currentView instanceof UISWTView) {
-			UISWTView current_swt_view = (UISWTView)currentView;
-			Object core_object = PluginCoreUtils.convert(current_swt_view.getDataSource(), true);
-			if (core_object instanceof DownloadManager) {
-				dm = new DownloadManager[] {(DownloadManager)core_object};
-				
-				// We should be using a constant somewhere!
-				detailed_view = "DMView".equals(current_swt_view.getViewID());
-			}
-			else {
-				dm = null;
-				detailed_view = false;
-			}
-		} else if (currentView instanceof MyTorrentsSuperView) {
-			dm = ((MyTorrentsSuperView) this.getCurrentView()).getSelectedDownloads();
-			detailed_view = false;
-		} else {
-			dm = null;
-			detailed_view = false;
-		}
-
-		if (currentView instanceof TableViewTab) {
-			tv = ((TableViewTab) currentView).getTableView();
-		}
-
-		/*
-		 * KN: Reflectively find the Torrents menu item and update its data
-		 */
-		final MenuItem torrentItem = MenuFactory.findMenuItem(
-				mainMenu.getMenu(IMenuConstants.MENU_ID_MENU_BAR),
-				MenuFactory.MENU_ID_TORRENT);
-
-		if (null != torrentItem) {
-			final DownloadManager[] dm_final = dm;
-			final TableViewSWT tv_final = tv;
-			final boolean detailed_view_final = detailed_view;
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					if (null == dm_final) {
-						torrentItem.setEnabled(false);
-					} else {
-						torrentItem.setData("downloads", dm_final);
-						torrentItem.setData("TableView", tv_final);
-						torrentItem.setData("is_detailed_view",
-								Boolean.valueOf(detailed_view_final));
-						torrentItem.setEnabled(true);
-					}
-				}
-			}, true); // async
-		}
-
-	}
-
-	protected void close() {
-		getShell().close();
-	}
-
-	protected void closeViewOrWindow() {
-		if (getCurrentView() != null)
-			mainTabSet.closeCurrent();
-		else
-			close();
-	}
-
-	protected ConfigView showConfig() {
-		if (config == null) {
-			config_view = new ConfigView();
-			config = mainTabSet.createTabItem(config_view, true);
-			config_view.getComposite().addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					config = null;
-					config_view = null;
-				}
-			});
-		} else {
-			mainTabSet.setFocus(config);
-			refreshIconBar();
-			refreshTorrentMenu();
-		}
-		return config_view;
-	}
-
-	protected boolean showConfig(String id) {
-		boolean has_rebuilt = config_view == null;
-		showConfig();
-		if (config_view == null) {
-			return false;
-		}
-		if (id == null) {
-			return true;
-		}
-		boolean result = config_view.selectSection(id);
-		if (!result && !has_rebuilt) {
-			config.dispose();
-			if (config_view != null) {throw new RuntimeException("something has gone wrong");}
-			return showConfig(id);
-		}
-		return result;	
-	}
-
-	protected void showConsole() {
-		if (console == null) {
-			console = mainTabSet.createTabItem(new LoggerView(events), true);
-			mainTabSet.getView(console).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							console = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(console);
-			refreshIconBar();
-			refreshTorrentMenu();
-		}
-	}
-
-	protected void showStats() {
-		if (stats_tab == null) {
-			stats_tab = mainTabSet.createTabItem(new StatsView(), true);
-			mainTabSet.getView(stats_tab).getComposite().addDisposeListener(
-					new DisposeListener() {
-						public void widgetDisposed(DisposeEvent e) {
-							stats_tab = null;
-						}
-					});
-		} else {
-			mainTabSet.setFocus(stats_tab);
-			refreshIconBar();
-			refreshTorrentMenu();
-		}
-	}
-
-	protected void showStatsDHT() {
-		showStats();
-		if (stats_tab == null) {
-			return;
-		}
-		IView view = mainTabSet.getView(stats_tab);
-		if (view instanceof StatsView) {
-			((StatsView) view).showDHT();
-		}
-	}
-
-	protected void showStatsTransfers() {
-		showStats();
-		if (stats_tab == null) {
-			return;
-		}
-		IView view = mainTabSet.getView(stats_tab);
-		if (view instanceof StatsView) {
-			((StatsView) view).showTransfers();
-		}
-	}
-
-	protected void setSelectedLanguageItem() {
-		try {
-			this_mon.enter();
-
-			Messages.updateLanguageForControl(shell);
-
-			if (systemTraySWT != null) {
-				systemTraySWT.updateLanguage();
-			}
-
-			if (mainStatusBar != null) {
-				mainStatusBar.refreshStatusText();
-			}
-
-			if (folder != null) {
-				folder.update();
-			}
-
-			if (downloadBasket != null) {
-				downloadBasket.updateLanguage();
-			}
-
-			mainTabSet.updateLanguage();
-
-			if (mainStatusBar != null) {
-				mainStatusBar.updateStatusText();
-			}
-
-			if (mainMenu != null) {
-				MenuFactory.updateMenuText(mainMenu.getMenu(IMenuConstants.MENU_ID_MENU_BAR));
-			}
-		} finally {
-
-			this_mon.exit();
-		}
-	}
-
-	/**
-	 * @deprecated Use {@link #getMainMenu()} instead
-	 * @return
-	 */
-	public MainMenu getMenu() {
-		return (MainMenu) mainMenu;
-	}
-
-	/**
-	 * @deprecated Use {@link #setMainMenu(IMainMenu)} instead
-	 * @param menu
-	 */
-	public void setMenu(MainMenu menu) {
-		mainMenu = menu;
-	}
-
-	public IMainMenu getMainMenu() {
-		return mainMenu;
-	}
-
-	public void setMainMenu(IMainMenu menu) {
-		mainMenu = menu;
-	}
-
-	protected AzureusCore getAzureusCore() {
-		return (azureus_core);
-	}
-
-	// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
-	public void generate(IndentWriter writer) {
-		writer.println("SWT UI");
-
-		try {
-			writer.indent();
-			
-			mainTabSet.generateDiagnostics(writer);
-
-			TableColumnManager.getInstance().generateDiagnostics(writer);
-		} finally {
-
-			writer.exdent();
-		}
-	}
-
-	private void checkForWhatsNewWindow() {
-		final String CONFIG_LASTSHOWN = "welcome.version.lastshown";
-
-		// Config used to store int, such as 2500.  Now, it stores a string
-		// getIntParameter will return default value if parameter is string (user
-		// downgraded)
-		// getStringParameter will bork if parameter isn't really a string
-
-		try {
-			String lastShown = "";
-			boolean bIsStringParam = true;
-			try {
-				lastShown = COConfigurationManager.getStringParameter(CONFIG_LASTSHOWN,
-						"");
-			} catch (Exception e) {
-				bIsStringParam = false;
-			}
-
-			if (lastShown.length() == 0) {
-				// check if we have an old style version
-				int latestDisplayed = COConfigurationManager.getIntParameter(
-						CONFIG_LASTSHOWN, 0);
-				if (latestDisplayed > 0) {
-					bIsStringParam = false;
-					String s = "" + latestDisplayed;
-					for (int i = 0; i < s.length(); i++) {
-						if (i != 0) {
-							lastShown += ".";
-						}
-						lastShown += s.charAt(i);
-					}
-				}
-			}
-
-			if (Constants.compareVersions(lastShown, Constants.getBaseVersion()) < 0) {
-				new WelcomeWindow(shell);
-				if (!bIsStringParam) {
-					// setting parameter to a different value type makes az unhappy
-					COConfigurationManager.removeParameter(CONFIG_LASTSHOWN);
-				}
-				COConfigurationManager.setParameter(CONFIG_LASTSHOWN,
-						Constants.getBaseVersion());
-				COConfigurationManager.save();
-			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-	}
-
-	protected UISWTInstanceImpl getUISWTInstanceImpl() {
-		return uiSWTInstanceImpl;
-	}
-
-	/**
-	 * @param string
-	 */
-	protected void setStatusText(String string) {
-		// TODO Auto-generated method stub
-		if (mainStatusBar != null)
-			mainStatusBar.setStatusText(string);
-	}
-
-	/**
-	 * @param statustype
-	 * @param string
-	 * @param l
-	 */
-	protected void setStatusText(int statustype, String string,
-			UIStatusTextClickListener l) {
-		if (mainStatusBar != null) {
-			mainStatusBar.setStatusText(statustype, string, l);
-		}
-	}
-
-	protected SystemTraySWT getSystemTraySWT() {
-		return systemTraySWT;
-	}
-
-	protected MainStatusBar getMainStatusBar() {
-		return mainStatusBar;
-	}
-
-	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateShell#generateObfusticatedImage()
-	public Image generateObfusticatedImage() {
-		Image image;
-
-		IView[] allViews = mainTabSet.getAllViews();
-		for (int i = 0; i < allViews.length; i++) {
-			IView view = allViews[i];
-
-			if (view instanceof ObfusticateTab) {
-				Item tab = mainTabSet.getTab(view);
-				tab.setText(((ObfusticateTab) view).getObfusticatedHeader());
-				folder.update();
-			}
-		}
-
-		Rectangle clientArea = shell.getClientArea();
-		image = new Image(display, clientArea.width, clientArea.height);
-
-		GC gc = new GC(shell);
-		try {
-			gc.copyArea(image, clientArea.x, clientArea.y);
-		} finally {
-			gc.dispose();
-		}
-
-		IView currentView = getCurrentView();
-
-		if (currentView instanceof ObfusticateImage) {
-			Point ofs = shell.toDisplay(clientArea.x, clientArea.y);
-			try {
-				((ObfusticateImage) currentView).obfusticatedImage(image, ofs);
-			} catch (Exception e) {
-				Debug.out("Obfusticating " + currentView, e);
-			}
-		}
-
-		for (int i = 0; i < allViews.length; i++) {
-			IView view = allViews[i];
-
-			if (view instanceof ObfusticateTab) {
-				view.refresh();
-			}
-		}
-
-		return image;
-	}
-
-	private static Point getStoredWindowSize() {
-		Point size = null;
-
-		boolean isMaximized = COConfigurationManager.getBooleanParameter(
-				"window.maximized", false);
-		if (isMaximized) {
-			Monitor monitor = SWTThread.getInstance().getPrimaryMonitor();
-			if (Utils.isThisThreadSWT()) {
-				if (window != null && window.getShell() != null
-						&& !window.getShell().isDisposed()) {
-					monitor = window.getShell().getMonitor();
-				}
-			}
-			if (monitor != null) {
-				Rectangle clientArea = monitor.getClientArea();
-				size = new Point(clientArea.width, clientArea.height);
-				return size;
-			}
-		}
-
-		String windowRectangle = COConfigurationManager.getStringParameter(
-				"window.rectangle", null);
-		if (windowRectangle != null) {
-			String[] values = windowRectangle.split(",");
-			if (values.length == 4) {
-				try {
-					size = new Point(Integer.parseInt(values[2]),
-							Integer.parseInt(values[3]));
-				} catch (Exception e) {
-				}
-			}
-		}
-		return size;
-	}
-
-	public static void addToVersionCheckMessage(final Map map) {
-		try {
-				Point size = getStoredWindowSize();
-				if (size == null) {
-					return;
-				}
-
-				map.put("mainwindow.w", new Long(size.x));
-				map.put("mainwindow.h", new Long(size.y));
-		} catch (Throwable e) {
-			e.printStackTrace();
-		}
-	}
-
-	public UIFunctionsSWT getUIFunctions() {
-		return uiFunctions;
-	}
-
-	public boolean isVisible(int windowElement) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-			return bIconBarEnabled;
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-			//TODO:
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
-			//TODO:
-		}
-
-		return true;
-	}
-
-	public void setVisible(int windowElement, boolean value) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-			setIconBarEnabled(value);
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-			//TODO:
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_MENU) {
-			//TODO:
-		}
-	}
-
-	public Rectangle getMetrics(int windowElement) {
-		if (windowElement == IMainWindow.WINDOW_ELEMENT_TOOLBAR) {
-			if (null != iconBar && null != iconBar.getComposite()) {
-				return iconBar.getComposite().getBounds();
-			}
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_STATUSBAR) {
-
-			return mainStatusBar.getBounds();
-
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TOPBAR) {
-
-			//KN: No search bar in classic UI
-
-		} else if (windowElement == IMainWindow.WINDOW_ELEMENT_TABBAR) {
-
-			//KN: No tab bar in classic UI
-
-		} else if (windowElement == IMainWindow.WINDOW_CLIENT_AREA) {
-
-			return shell.getClientArea();
-
-		} else if (windowElement == IMainWindow.WINDOW_CONTENT_DISPLAY_AREA) {
-
-			Rectangle r = shell.getClientArea();
-
-			r.x += iconBar.getComposite().getBounds().x;
-			r.height -= iconBar.getComposite().getBounds().height;
-
-			r.height -= mainStatusBar.getBounds().height;
-
-			return r;
-
-		}
-
-		return new Rectangle(0, 0, 0, 0);
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void closeAllDetails() {
-		if (mainTabSet != null) {
-			mainTabSet.closeAllDetails();
-		}
-	}
-
-	/**
-	 * @return
-	 *
-	 * @since 3.1.1.1
-	 */
-	public boolean hasDetailViews() {
-		if (mainTabSet != null) {
-			return( mainTabSet.hasDetails());
-		}
-		return false;
-	}
-
-	public Tab getMainTabSet() {
-		return mainTabSet;
-	}
-
-}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java b/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
index 5086a4a..67bfd3f 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/MenuFactory.java
@@ -1,6 +1,11 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
@@ -10,19 +15,14 @@ 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.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.AERunnable;
-import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.plugins.ui.menus.MenuManager;
-import org.gudy.azureus2.plugins.ui.tables.*;
-import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
-import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
+import org.gudy.azureus2.core3.logging.*;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
 import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.ui.swt.beta.BetaWizard;
 import org.gudy.azureus2.ui.swt.components.shell.ShellManager;
 import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
 import org.gudy.azureus2.ui.swt.debug.UIDebugGenerator;
@@ -35,6 +35,7 @@ import org.gudy.azureus2.ui.swt.maketorrent.NewTorrentWizard;
 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
 import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
 import org.gudy.azureus2.ui.swt.nat.NatTestWindow;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInputReceiver;
 import org.gudy.azureus2.ui.swt.pluginsinstaller.InstallPluginWizard;
 import org.gudy.azureus2.ui.swt.pluginsuninstaller.UnInstallPluginWizard;
 import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
@@ -42,21 +43,31 @@ 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.stats.StatsView;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableContextMenuManager;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 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.*;
+import com.aelitis.azureus.core.speedmanager.SpeedLimitHandler;
 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.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuManager;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.plugins.update.Update;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstanceListener;
+
 public class MenuFactory
 	implements IMenuConstants
 {
@@ -86,8 +97,8 @@ public class MenuFactory
 		transferMenu.addMenuListener(new MenuListener() {
 			public void menuShown(MenuEvent menu) {
 				if (!AzureusCoreFactory.isCoreRunning()) {
-					itemPause.setEnabled(false);
-					itemResume.setEnabled(false);
+					itemPause.setEnabled(true);
+					itemResume.setEnabled(true);
 				} else {
 					AzureusCore core = AzureusCoreFactory.getSingleton();
 					itemPause.setEnabled(core.getGlobalManager().canPauseDownloads());
@@ -96,6 +107,10 @@ public class MenuFactory
 			}
 
 			public void menuHidden(MenuEvent menu) {
+					// this behaviour required to get the accelerators to work properly as they won't fire if the menu item is
+					// disabled even if if the menu were to be shown they would be...
+				itemPause.setEnabled(true);
+				itemResume.setEnabled(true);
 			}
 		});
 
@@ -110,94 +125,98 @@ public class MenuFactory
 		return createTopLevelMenuItem(menuParent, MENU_ID_ADVANCED);
 	}
 
-	public static MenuItem createTorrentMenuItem(final Menu menuParent) {
-		final MenuItem torrentItem = createTopLevelMenuItem(menuParent,
-				MENU_ID_TORRENT);
+	public static Menu createTorrentMenuItem(final Menu menuParent) {
+		final Menu torrentMenu = createTopLevelMenuItem(menuParent,
+				MENU_ID_TORRENT).getMenu();
 
 		/*
 		 * The Torrents menu is context-sensitive to which torrent is selected in the UI.
 		 * For this reason we need to dynamically build the menu when ever it is about to be displayed
 		 * so that the states of the menu items accurately reflect what was selected in the UI. 
 		 */
-		MenuBuildUtils.addMaintenanceListenerForMenu(torrentItem.getMenu(),
+		MenuBuildUtils.addMaintenanceListenerForMenu(torrentMenu,
 				new MenuBuildUtils.MenuBuilder() {
 					public void buildMenu(Menu menu, MenuEvent menuEvent) {
-						DownloadManager[] current_dls = (DownloadManager[]) torrentItem.getData("downloads");
-						if (current_dls == null) {
-							return;
-						}
+						buildTorrentMenu(menu);
+					}
+				});
+		return torrentMenu;
+	}
 
-						if (AzureusCoreFactory.isCoreRunning()) {
-							boolean is_detailed_view = ((Boolean) torrentItem.getData("is_detailed_view")).booleanValue();
-							TableViewSWT tv = (TableViewSWT) torrentItem.getData("TableView");
-							AzureusCore core = AzureusCoreFactory.getSingleton();
+	public static void buildTorrentMenu(Menu menu) {
+		DownloadManager[] current_dls = (DownloadManager[]) menu.getData("downloads");
+		if (current_dls == null) {
+			return;
+		}
 
-							TorrentUtil.fillTorrentMenu(menu, current_dls, core,
-									menuParent.getShell(), !is_detailed_view, 0, tv);
-						}
+		if (AzureusCoreFactory.isCoreRunning()) {
+			boolean is_detailed_view = ((Boolean) menu.getData("is_detailed_view")).booleanValue();
+			TableViewSWT<?> tv = (TableViewSWT<?>) menu.getData("TableView");
+			AzureusCore core = AzureusCoreFactory.getSingleton();
 
-						org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items;
+			TorrentUtil.fillTorrentMenu(menu, current_dls, core,
+					menu.getShell(), !is_detailed_view, 0, tv);
+		}
 
-						menu_items = MenuItemManager.getInstance().getAllAsArray(
-								new String[] {
-									MenuManager.MENU_TORRENT_MENU,
-									MenuManager.MENU_DOWNLOAD_CONTEXT
-								});
+		org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items;
 
-						final Object[] plugin_dls = DownloadManagerImpl.getDownloadStatic(current_dls);
+		menu_items = MenuItemManager.getInstance().getAllAsArray(
+				new String[] {
+					MenuManager.MENU_TORRENT_MENU,
+					MenuManager.MENU_DOWNLOAD_CONTEXT
+				});
 
-						if (menu_items.length > 0) {
-							addSeparatorMenuItem(menu);
+		final Object[] plugin_dls = DownloadManagerImpl.getDownloadStatic(current_dls);
 
-							MenuBuildUtils.addPluginMenuItems(menuParent.getShell(),
-									menu_items, menu, true, true,
-									new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
-											plugin_dls));
-						}
+		if (menu_items.length > 0) {
+			addSeparatorMenuItem(menu);
 
-						menu_items = null;
-
-						/**
-						 * OK, "hack" time - we'll allow plugins which add menu items against
-						 * a table to appear in this menu. We'll have to fake the table row
-						 * object though. All downloads need to share a common table.
-						 */
-						String table_to_use = null;
-						for (int i = 0; i < current_dls.length; i++) {
-							String table_name = (current_dls[i].isDownloadComplete(false)
-									? TableManager.TABLE_MYTORRENTS_COMPLETE
-									: TableManager.TABLE_MYTORRENTS_INCOMPLETE);
-							if (table_to_use == null || table_to_use.equals(table_name)) {
-								table_to_use = table_name;
-							} else {
-								table_to_use = null;
-								break;
-							}
-						}
+			MenuBuildUtils.addPluginMenuItems(menu.getShell(),
+					menu_items, menu, true, true,
+					new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
+							plugin_dls));
+		}
 
-						if (table_to_use != null) {
-							menu_items = TableContextMenuManager.getInstance().getAllAsArray(
-									table_to_use);
-						}
+		menu_items = null;
 
-						if (menu_items != null) {
-							addSeparatorMenuItem(menu);
+		/**
+		 * OK, "hack" time - we'll allow plugins which add menu items against
+		 * a table to appear in this menu. We'll have to fake the table row
+		 * object though. All downloads need to share a common table.
+		 */
+			String table_to_use = null;
+		for (int i = 0; i < current_dls.length; i++) {
+			String table_name = (current_dls[i].isDownloadComplete(false)
+					? TableManager.TABLE_MYTORRENTS_COMPLETE
+							: TableManager.TABLE_MYTORRENTS_INCOMPLETE);
+			if (table_to_use == null || table_to_use.equals(table_name)) {
+				table_to_use = table_name;
+			} else {
+				table_to_use = null;
+				break;
+			}
+		}
 
-							TableRow[] dls_as_rows = null;
-							dls_as_rows = new TableRow[plugin_dls.length];
-							for (int i = 0; i < plugin_dls.length; i++) {
-								dls_as_rows[i] = wrapAsRow(plugin_dls[i], table_to_use);
-							}
+		if (table_to_use != null) {
+			menu_items = TableContextMenuManager.getInstance().getAllAsArray(
+					table_to_use);
+		}
 
-							MenuBuildUtils.addPluginMenuItems(menuParent.getShell(),
-									menu_items, menu, true, true,
-									new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
-											dls_as_rows));
-						}
+		if (menu_items != null) {
+			addSeparatorMenuItem(menu);
+
+			TableRow[] dls_as_rows = null;
+			dls_as_rows = new TableRow[plugin_dls.length];
+			for (int i = 0; i < plugin_dls.length; i++) {
+				dls_as_rows[i] = wrapAsRow(plugin_dls[i], table_to_use);
+			}
+
+			MenuBuildUtils.addPluginMenuItems(menu.getShell(),
+					menu_items, menu, true, true,
+					new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
+							dls_as_rows));
+		}
 
-					}
-				});
-		return torrentItem;
 	}
 
 	public static MenuItem createToolsMenuItem(Menu menuParent) {
@@ -255,11 +274,18 @@ public class MenuFactory
 	public static MenuItem addOpenTorrentMenuItem(Menu menuParent) {
 		return addMenuItem(menuParent, MENU_ID_OPEN_TORRENT, new Listener() {
 			public void handleEvent(Event e) {
-				TorrentOpener.openTorrentWindow();
+				TorrentOpener.openTorrentWindow( false );
 			}
 		});
 	}
 
+	public static MenuItem addOpenURIMenuItem(Menu menuParent) {
+		return addMenuItem(menuParent, MENU_ID_OPEN_URI, new Listener() {
+			public void handleEvent(Event e) {
+				TorrentOpener.openTorrentWindow( true );
+			}
+		});
+	}
 	public static MenuItem addOpenTorrentForTrackingMenuItem(Menu menuParent) {
 		MenuItem file_new_torrent_for_tracking = addMenuItem(menuParent,
 				MENU_ID_OPEN_TORRENT_FOR_TRACKING, new Listener() {
@@ -269,6 +295,17 @@ public class MenuFactory
 				});
 		return file_new_torrent_for_tracking;
 	}
+	
+	public static MenuItem addSearchMenuItem(Menu menuParent) {
+		MenuItem item = addMenuItem(menuParent,
+				"Button.search", new Listener() {
+					public void handleEvent(Event e) {
+						UIFunctionsManagerSWT.getUIFunctionsSWT().promptForSearch();
+					}
+				});
+		return item;
+	}
+
 
 	public static MenuItem addOpenVuzeFileMenuItem(final Menu menuParent) {
 		return addMenuItem(menuParent, MENU_ID_OPEN_VUZE_FILE, new Listener() {
@@ -394,16 +431,35 @@ public class MenuFactory
 		return closeWindow;
 	}
 
-	public static MenuItem addCloseTabMenuItem(Menu menu,
-			final MainWindow mainWindow) {
-		return addMenuItem(menu, MENU_ID_CLOSE_TAB, new Listener() {
+	public static MenuItem addCloseTabMenuItem(Menu menu) {
+		final MenuItem menuItem = addMenuItem(menu, MENU_ID_CLOSE_TAB, new Listener() {
 			public void handleEvent(Event event) {
-				if (MainWindow.isAlreadyDead) {
-					return;
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				if (mdi != null) {
+					MdiEntry currentEntry = mdi.getCurrentEntry();
+					if (currentEntry != null && currentEntry.isCloseable()) {
+						mdi.closeEntry(currentEntry.getId());
+					}
+				}
+			}
+		});
+		menu.addMenuListener(new MenuListener() {
+			public void menuShown(MenuEvent e) {
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				if (mdi != null) {
+					MdiEntry currentEntry = mdi.getCurrentEntry();
+					if (currentEntry != null && currentEntry.isCloseable()) {
+						menuItem.setEnabled(true);
+						return;
+					}
 				}
-				mainWindow.closeViewOrWindow();
+				menuItem.setEnabled(false);
+			}
+			
+			public void menuHidden(MenuEvent e) {
 			}
 		});
+		return menuItem;
 	}
 
 	public static MenuItem addCloseDetailsMenuItem(Menu menu) {
@@ -542,17 +598,6 @@ public class MenuFactory
 			}
 		});
 	}
-
-	public static MenuItem addDetailedListMenuItem(Menu menu) {
-		return addMenuItem(menu, MENU_ID_DETAILED_LIST, new Listener() {
-			public void handleEvent(Event e) {
-				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-				if (uiFunctions != null) {
-					uiFunctions.openView(UIFunctions.VIEW_DETAILED_LISTVIEW, null);
-				}
-			}
-		});
-	}
 	
 	public static MenuItem addAllPeersMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_ALL_PEERS, new Listener() {
@@ -576,6 +621,24 @@ public class MenuFactory
 		});
 	}
 
+	public static MenuItem addDeviceManagerMenuItem(Menu menu) {
+		return addMenuItem(menu, MENU_ID_DEVICEMANAGER, new Listener() {
+			public void handleEvent(Event e) {
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_DEVICES);
+			}
+		});
+	}
+
+	public static MenuItem addSubscriptionMenuItem(Menu menu) {
+		return addMenuItem(menu, MENU_ID_SUBSCRIPTIONS, new Listener() {
+			public void handleEvent(Event e) {
+				MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_HEADER_SUBSCRIPTIONS);
+			}
+		});
+	}
+
 	public static MenuItem addMyTrackerMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_MY_TRACKERS, new Listener() {
 			public void handleEvent(Event e) {
@@ -642,15 +705,459 @@ public class MenuFactory
 						}
 					}
 				});
+		item.setSelection(!MiniBarManager.getManager().getShellManager().isEmpty());
 
 		menu.addListener(SWT.Show, new Listener() {
 			public void handleEvent(Event event) {
-				item.setSelection(!MiniBarManager.getManager().getShellManager().isEmpty());
+				if (item.isDisposed()) {
+					menu.removeListener(SWT.Show, this);
+				} else {
+					item.setSelection(!MiniBarManager.getManager().getShellManager().isEmpty());
+				}
 			}
 		});
 		return item;
 	}
+	
+	public static MenuItem addSpeedLimitsToMenu(final Menu menuParent) {
+		MenuItem speedLimitsMenuItem = createTopLevelMenuItem(menuParent,
+				MENU_ID_SPEED_LIMITS);
+		MenuBuildUtils.addMaintenanceListenerForMenu(speedLimitsMenuItem.getMenu(),
+				new MenuBuildUtils.MenuBuilder() {
+					public void 
+					buildMenu(
+						Menu menu, MenuEvent menuEvent) 
+					{
+						if ( AzureusCoreFactory.isCoreRunning()){
+					
+							AzureusCore core = AzureusCoreFactory.getSingleton();
+							
+							final SpeedLimitHandler slh = SpeedLimitHandler.getSingleton( core );
+							
+							MenuItem viewCurrentItem = new MenuItem(menu, SWT.PUSH);
+							Messages.setLanguageText(viewCurrentItem, "MainWindow.menu.speed_limits.view_current" );
+																	
+							viewCurrentItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg0 )
+									{
+										showText(
+											"MainWindow.menu.speed_limits.info.title",
+											"MainWindow.menu.speed_limits.info.curr",
+											slh.getCurrent());
+									}
+								});
+							
+							java.util.List<String>	profiles = slh.getProfileNames();
+							
+							Menu profiles_menu = new Menu(menuParent.getShell(), SWT.DROP_DOWN);
+							MenuItem profiles_item = new MenuItem( menu, SWT.CASCADE);
+							profiles_item.setMenu(profiles_menu);
+
+														
+							Messages.setLanguageText(profiles_item, "MainWindow.menu.speed_limits.profiles" );
+
+							if ( profiles.size() == 0 ){
+								
+								profiles_item.setEnabled( false );
+								
+							}else{
+								
+								for ( final String p: profiles ){
+									
+									Menu profile_menu = new Menu(menuParent.getShell(), SWT.DROP_DOWN);
+									MenuItem profile_item = new MenuItem( profiles_menu, SWT.CASCADE);
+									profile_item.setMenu(profile_menu);
+									profile_item.setText( p );
+
+									MenuItem loadItem = new MenuItem(profile_menu, SWT.PUSH);
+									Messages.setLanguageText(loadItem, "MainWindow.menu.speed_limits.load" );
+																			
+									loadItem.addListener(
+										SWT.Selection,
+										new Listener()
+										{
+											public void 
+											handleEvent(
+												Event arg0 )
+											{
+												showText(
+													"MainWindow.menu.speed_limits.info.title",
+													MessageText.getString( "MainWindow.menu.speed_limits.info.prof", new String[]{ p }),
+													slh.loadProfile( p ) );
+											}
+										});
+									
+									MenuItem viewItem = new MenuItem(profile_menu, SWT.PUSH);
+									Messages.setLanguageText(viewItem, "MainWindow.menu.speed_limits.view" );
+																			
+									viewItem.addListener(
+										SWT.Selection,
+										new Listener()
+										{
+											public void 
+											handleEvent(
+												Event arg0 )
+											{
+												showText(
+													"MainWindow.menu.speed_limits.info.title", 
+													MessageText.getString( "MainWindow.menu.speed_limits.info.prof", new String[]{ p }),					
+													slh.getProfile( p ) );
+											}
+										});
+									
+									addSeparatorMenuItem( profile_menu );
+									
+									MenuItem deleteItem = new MenuItem(profile_menu, SWT.PUSH);
+									Messages.setLanguageText(deleteItem, "MainWindow.menu.speed_limits.delete" );
+																			
+									deleteItem.addListener(
+										SWT.Selection,
+										new Listener()
+										{
+											public void 
+											handleEvent(
+												Event arg0 )
+											{
+												slh.deleteProfile( p );
+											}
+										});
+								}
+							}
+							
+							MenuItem saveItem = new MenuItem(menu, SWT.PUSH);
+							Messages.setLanguageText(saveItem, "MainWindow.menu.speed_limits.save_current" );
+							
+							saveItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg0 )
+									{
+										UISWTInputReceiver entry = new SimpleTextEntryWindow();
+										
+										entry.allowEmptyInput( false );
+										entry.setLocalisedTitle(MessageText.getString("MainWindow.menu.speed_limits.profile" ));
+										entry.prompt(new UIInputReceiverListener() {
+											public void UIInputReceiverClosed(UIInputReceiver entry) {
+												if (!entry.hasSubmittedInput()){
+													
+													return;
+												}
+												
+												String input = entry.getSubmittedInput().trim();
+												
+												if ( input.length() > 0 ){
+																										
+													showText(
+														"MainWindow.menu.speed_limits.info.title", 
+														MessageText.getString( "MainWindow.menu.speed_limits.info.prof", new String[]{ input }),					
+														slh.saveProfile( input ) );
+												}
+											}
+										});
+									}
+								});
+							
+							addSeparatorMenuItem( menu );
+							
+							MenuItem resetItem = new MenuItem(menu, SWT.PUSH);
+							Messages.setLanguageText(resetItem, "MainWindow.menu.speed_limits.reset" );
+																	
+							resetItem.addListener(
+								SWT.Selection,
+								new Listener()
+								{
+									public void 
+									handleEvent(
+										Event arg0 )
+									{
+										showText(
+											"MainWindow.menu.speed_limits.info.title", 
+											"MainWindow.menu.speed_limits.info.curr",
+											slh.reset());
+									}
+								});
+							
+						addSeparatorMenuItem( menu );
+							
+						MenuItem scheduleItem = new MenuItem(menu, SWT.PUSH);
+						Messages.setLanguageText(scheduleItem, "MainWindow.menu.speed_limits.schedule" );
+																
+						scheduleItem.addListener(
+							SWT.Selection,
+							new Listener()
+							{
+								public void 
+								handleEvent(
+									Event arg0 )
+								{
+									Utils.execSWTThreadLater(
+											1,
+											new Runnable()
+											{
+												public void
+												run()
+												{
+													java.util.List<String> lines = slh.getSchedule();
+													
+													String	text = "";
+													
+													for ( String s: lines ){
+														
+														text += (text.length()==0?"":"\n") + s;
+													}
+													
+													final TextViewerWindow viewer =
+														new TextViewerWindow(
+															"MainWindow.menu.speed_limits.schedule.title", 
+															"MainWindow.menu.speed_limits.schedule.msg", 
+															text, false );
+													
+													viewer.setEditable( true );
+													
+													viewer.addListener(
+														new TextViewerWindow.TextViewerWindowListener()
+														{
+															public void 
+															closed() 
+															{
+																String text = viewer.getText();
+																
+																String[] lines = text.split( "\n" );
+																
+																java.util.List<String> updated_lines = new ArrayList<String>( Arrays.asList( lines ));
+																
+																java.util.List<String> result = slh.setSchedule( updated_lines );
+																
+																if ( result != null && result.size() > 0 ){
+																	
+																	showText(
+																			"MainWindow.menu.speed_limits.schedule.title", 
+																			"MainWindow.menu.speed_limits.schedule.err", 
+																			result );
+																}
+															}	
+														});
+												}
+											});
+								}
+							});
+						}
+					}
+				});
+		
+		return( speedLimitsMenuItem );
+	}
 
+	public static MenuItem addAdvancedHelpMenuItem(final Menu menuParent) {
+		MenuItem advancedHelpMenuItem = createTopLevelMenuItem(menuParent,
+				MENU_ID_ADVANCED_TOOLS);
+		MenuBuildUtils.addMaintenanceListenerForMenu(advancedHelpMenuItem.getMenu(),
+				new MenuBuildUtils.MenuBuilder() {
+					public void 
+					buildMenu(
+						final Menu menu, MenuEvent menuEvent) 
+					{
+						MenuItem fixTorrent = new MenuItem(menu, SWT.PUSH);
+						
+						Messages.setLanguageText(fixTorrent, "torrent.fix.corrupt" );
+																
+						fixTorrent.addListener(
+							SWT.Selection,
+							new Listener()
+							{
+								public void 
+								handleEvent(
+									Event arg )
+								{
+									Utils.execSWTThreadLater(
+											1,
+											new Runnable()
+											{
+												public void
+												run()
+												{
+													handleTorrentFixup();
+												}
+											});
+								}
+							});
+					}
+		});
+		
+		return( advancedHelpMenuItem );
+	}
+	
+	private static void
+	handleTorrentFixup()
+	{
+			// had some OSX SWT crash issues in this code so moved everything async
+		
+		final Shell shell = Utils.findAnyShell();
+		
+		try{
+			FileDialog dialog = new FileDialog( shell.getShell(), SWT.SYSTEM_MODAL | SWT.OPEN );
+			
+			dialog.setFilterExtensions(new String[] { "*.torrent", "*.tor", Constants.FILE_WILDCARD });
+			
+			dialog.setFilterNames(new String[] { "*.torrent", "*.tor", Constants.FILE_WILDCARD });
+			
+			dialog.setFilterPath( TorrentOpener.getFilterPathTorrent());
+									
+			dialog.setText(MessageText.getString( "torrent.fix.corrupt.browse" ));
+			
+			String str = dialog.open();
+													
+			if ( str != null ){
+			
+				TorrentOpener.setFilterPathTorrent( str );
+
+				File file = new File( str );
+				
+				byte[] bytes = FileUtil.readFileAsByteArray( file );
+
+				Map existing_map = BDecoder.decode( bytes );
+				
+				Map existing_info = (Map)existing_map.get( "info" );
+				
+				byte[]	existing_info_encoded = BEncoder.encode( existing_info );
+				
+				final TOTorrent t = TOTorrentFactory.deserialiseFromMap( existing_map );
+				
+				final byte[] old_hash = t.getHash();
+				byte[] new_hash	= null;
+				
+				for ( int i=0;i<bytes.length-5;i++){
+					
+					if ( 	bytes[i] == ':' && 
+							bytes[i+1] == 'i' && 
+							bytes[i+2] == 'n' && 
+							bytes[i+3] == 'f' && 
+							bytes[i+4] == 'o' ){
+							
+						new_hash = new SHA1Simple().calculateHash( bytes, i+5, existing_info_encoded.length );
+						
+						break;
+					}
+				}
+				
+				if ( new_hash != null ){
+					
+					final byte[] f_new_hash = new_hash;
+					
+					Utils.execSWTThreadLater(
+							1,
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									String	title = MessageText.getString( "torrent.fix.corrupt.result.title" );
+									
+									if ( Arrays.equals( old_hash, f_new_hash )){
+										
+										MessageBoxShell mb = 
+											new MessageBoxShell( SWT.OK, title, MessageText.getString( "torrent.fix.corrupt.result.nothing" ) ); 
+						 						
+						 				mb.setParent( shell );
+						 				
+						 				mb.open( null );
+						 				
+									}else{
+										
+										MessageBoxShell mb = 
+											new MessageBoxShell( SWT.OK, title, MessageText.getString( "torrent.fix.corrupt.result.fixed", new String[]{ ByteFormatter.encodeString( f_new_hash ) })); 
+						 						
+						 				mb.setParent( shell );
+						 				
+						 				mb.open( null );
+						 				
+						 				mb.waitUntilClosed();
+						 				
+						 				try{
+						 					t.setHashOverride( f_new_hash );
+						 				
+							 				Utils.execSWTThreadLater(
+													1,
+													new Runnable()
+													{
+														public void
+														run()
+														{
+											 				FileDialog dialog2 = new FileDialog( shell, SWT.SYSTEM_MODAL | SWT.SAVE );
+																												
+															dialog2.setFilterPath( TorrentOpener.getFilterPathTorrent());
+																					
+															dialog2.setFilterExtensions(new String[]{ "*.torrent" });
+															
+															String str2 = dialog2.open();
+																									
+															if ( str2 != null ){
+																
+																if ( !( str2.toLowerCase( Locale.US ).endsWith( ".tor" ) || str2.toLowerCase( Locale.US ).endsWith( ".torrent" ))){
+																	
+																	str2 += ".torrent";
+																}
+																
+																try{
+																	t.serialiseToBEncodedFile( new File( str2 ));
+																	
+																}catch( Throwable e ){
+																	
+																	Debug.out( e );
+																}
+															}
+														}
+													});
+						 				}catch( Throwable e ){
+						 					
+						 					Debug.out( e );
+						 				}
+									}
+								}
+							});
+				}
+			}
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+		}
+	}
+	
+	public static void
+	showText(
+		final String					title,
+		final String					message,
+		final java.util.List<String>	lines )
+	{
+		Utils.execSWTThreadLater(
+			1,
+			new Runnable()
+			{
+				public void
+				run()
+				{
+					String	text = "";
+					
+					for ( String s: lines ){
+						
+						text += (text.length()==0?"":"\n") + s;
+					}
+					
+					TextViewerWindow viewer = new TextViewerWindow(title, message, text, false );
+					
+					viewer.setEditable( false );
+				}
+			});
+	}
+	
 	public static MenuItem addBlockedIPsMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_IP_FILTER, new ListenerNeedingCoreRunning() {
 			public void handleEvent(AzureusCore core, Event e) {
@@ -676,7 +1183,8 @@ public class MenuFactory
 			public void handleEvent(Event e) {
 				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 				if (uiFunctions != null) {
-					uiFunctions.openView(UIFunctions.VIEW_STATS, null);
+					MultipleDocumentInterface mdi = uiFunctions.getMDI();
+					mdi.showEntryByID(StatsView.VIEW_ID);
 				}
 			}
 		});
@@ -705,7 +1213,7 @@ public class MenuFactory
 	public static MenuItem addConfigWizardMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_CONFIGURE, new Listener() {
 			public void handleEvent(Event e) {
-				new ConfigureWizard(false);
+				new ConfigureWizard(false,ConfigureWizard.WIZARD_MODE_FULL);
 			}
 		});
 	}
@@ -763,9 +1271,9 @@ public class MenuFactory
 		final MenuItem item = addMenuItem(menu, MENU_ID_WINDOW_ALL_TO_FRONT,
 				new Listener() {
 					public void handleEvent(Event event) {
-						Iterator iter = ShellManager.sharedManager().getWindows();
+						Iterator<Shell> iter = ShellManager.sharedManager().getWindows();
 						while (iter.hasNext()) {
-							Shell shell = (Shell) iter.next();
+							Shell shell = iter.next();
 							if (!shell.isDisposed() && !shell.getMinimized())
 								shell.open();
 						}
@@ -777,10 +1285,10 @@ public class MenuFactory
 				if (item.isDisposed()) {
 					return;
 				}
-				Iterator iter = ShellManager.sharedManager().getWindows();
+				Iterator<Shell> iter = ShellManager.sharedManager().getWindows();
 				boolean hasNonMaximizedShell = false;
 				while (iter.hasNext()) {
-					Shell shell = (Shell) iter.next();
+					Shell shell = iter.next();
 					if (false == shell.isDisposed() && false == shell.getMinimized()) {
 						hasNonMaximizedShell = true;
 						break;
@@ -831,9 +1339,9 @@ public class MenuFactory
 					for (int i = numTopItems; i < menuParent.getItemCount();)
 						menuParent.getItem(i).dispose();
 
-					Iterator iter = ShellManager.sharedManager().getWindows();
+					Iterator<Shell> iter = ShellManager.sharedManager().getWindows();
 					for (int i = 0; i < size; i++) {
-						final Shell sh = (Shell) iter.next();
+						final Shell sh = iter.next();
 
 						if (sh.isDisposed() || sh.getText().length() == 0)
 							continue;
@@ -932,7 +1440,7 @@ public class MenuFactory
 	public static MenuItem addWhatsNewMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_WHATS_NEW, new Listener() {
 			public void handleEvent(Event e) {
-				Utils.launch("http://azureus.sourceforge.net/changelog.php?version="
+				Utils.launch("http://plugins.vuze.com/changelog.php?version="
 						+ Constants.AZUREUS_VERSION);
 			}
 		});
@@ -975,7 +1483,9 @@ public class MenuFactory
 	public static MenuItem addGetPluginsMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_PLUGINS_HELP, new Listener() {
 			public void handleEvent(Event e) {
-				Utils.launch("http://azureus.sourceforge.net/plugin_list.php");
+				Utils.launch("http://plugins.vuze.com/plugin_list.php");
+				//MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
+				//mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_ABOUTPLUGINS);
 			}
 		});
 	}
@@ -983,7 +1493,8 @@ public class MenuFactory
 	public static MenuItem addDebugHelpMenuItem(Menu menu) {
 		return addMenuItem(menu, MENU_ID_DEBUG_HELP, new Listener() {
 			public void handleEvent(Event e) {
-				UIDebugGenerator.generate();
+				UIDebugGenerator.generate(Constants.APP_NAME + " "
+						+ Constants.AZUREUS_VERSION, "Generated via Help Menu");
 			}
 		});
 	}
@@ -1001,7 +1512,15 @@ public class MenuFactory
 							}
 
 							public void complete(UpdateCheckInstance instance) {
-								if (instance.getUpdates().length == 0) {
+								Update[] updates = instance.getUpdates();
+								boolean hasUpdates = false;
+								for (Update update : updates) {
+									if (update.getDownloaders().length > 0) {
+										hasUpdates = true;
+										break;
+									}
+								}
+								if (!hasUpdates) {
 									MessageBoxShell mb = new MessageBoxShell(
 											SWT.ICON_INFORMATION | SWT.OK,
 											"window.update.noupdates", (String[]) null);
@@ -1013,6 +1532,35 @@ public class MenuFactory
 		});
 	}
 
+	public static MenuItem addBetaMenuItem(Menu menuParent) {
+		final MenuItem menuItem = addMenuItem(menuParent, MENU_ID_BETA_PROG,
+				new Listener() {
+					public void handleEvent(Event e) {
+						new BetaWizard();
+			}
+		});
+
+		COConfigurationManager.addAndFireParameterListener(
+				"Beta Programme Enabled", new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						Utils.execSWTThread(new AERunnable() {
+							public void runSupport() {
+								if ( menuItem.isDisposed()){
+									return;
+								}
+								boolean enabled = COConfigurationManager.getBooleanParameter("Beta Programme Enabled");
+								Messages.setLanguageText(
+										menuItem,
+										MessageText.resolveLocalizationKey(MENU_ID_BETA_PROG
+												+ (enabled ? ".off" : ".on")));
+							}
+						});
+					}
+				});
+
+		return menuItem;
+	}
+	
 	public static MenuItem addPluginInstallMenuItem(Menu menuParent) {
 		return addMenuItem(menuParent, MENU_ID_PLUGINS_INSTALL,
 				new Listener() {
@@ -1383,6 +1931,8 @@ public class MenuFactory
 			  public boolean isSelected()  {notSupported(); return false;}
 			  public void addMouseListener(TableRowMouseListener listener) {notSupported();}
 			  public void removeMouseListener(TableRowMouseListener listener) {notSupported();}
+			  public Object getData(String id) {return null;}
+			  public void setData(String id, Object data) {}
 		};
 	}
 
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/PluginsMenuHelper.java b/org/gudy/azureus2/ui/swt/mainwindow/PluginsMenuHelper.java
index 09523b8..5dc1066 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/PluginsMenuHelper.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/PluginsMenuHelper.java
@@ -5,6 +5,7 @@ import java.util.List;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEMonitor;
 import org.gudy.azureus2.core3.util.AERunnable;
@@ -13,12 +14,12 @@ import org.gudy.azureus2.ui.swt.MenuBuildUtils;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.pluginsimpl.BasicPluginViewImpl;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
 
+import com.aelitis.azureus.ui.mdi.MdiEntryCreationListener;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
 
 public class PluginsMenuHelper
 {
@@ -26,11 +27,11 @@ public class PluginsMenuHelper
 
 	private AEMonitor plugin_helper_mon = new AEMonitor("plugin_helper_mon");
 
-	private Map plugin_view_info_map = new TreeMap();
+	private Map<String, IViewInfo> plugin_view_info_map = new TreeMap<String, IViewInfo>();
 
-	private Map plugin_logs_view_info_map = new TreeMap();
+	private Map<String, IViewInfo> plugin_logs_view_info_map = new TreeMap<String, IViewInfo>();
 	
-	private List pluginAddedViewListener = new ArrayList();
+	private List<PluginAddedViewListener> pluginAddedViewListener = new ArrayList<PluginAddedViewListener>();
 
 	private PluginsMenuHelper() {
 		//Making this private
@@ -42,6 +43,44 @@ public class PluginsMenuHelper
 		}
 		return INSTANCE;
 	}
+	
+	public void buildPluginLogsMenu(Menu parentMenu) {
+		try {
+
+			plugin_helper_mon.enter();
+
+			createViewInfoMenuItems(parentMenu, plugin_logs_view_info_map);
+
+		} finally {
+			plugin_helper_mon.exit();
+		}
+	}
+
+	public boolean buildViewMenu(Menu viewMenu, Shell parent) {
+
+		int itemCount = viewMenu.getItemCount();
+		org.gudy.azureus2.plugins.ui.menus.MenuItem[] plugin_items;
+		plugin_items = MenuItemManager.getInstance().getAllAsArray("mainmenu");
+		if (plugin_items.length > 0) {
+			MenuBuildUtils.addPluginMenuItems(parent, plugin_items, viewMenu, true,
+					true, MenuBuildUtils.BASIC_MENU_ITEM_CONTROLLER);
+		}
+		if (viewMenu.getItemCount() > itemCount) {
+			MenuFactory.addSeparatorMenuItem(viewMenu);
+		}
+
+		try {
+
+			plugin_helper_mon.enter();
+			createViewInfoMenuItems(viewMenu, plugin_view_info_map);
+
+		} finally {
+			plugin_helper_mon.exit();
+		}
+
+
+		return viewMenu.getItemCount() > itemCount;
+	}
 
 	public void buildPluginMenu(Menu pluginMenu, Shell parent,
 			boolean includeGetPluginsMenu) {
@@ -49,10 +88,11 @@ public class PluginsMenuHelper
 		try {
 
 			plugin_helper_mon.enter();
-			createIViewInfoMenuItems(pluginMenu, plugin_view_info_map);
+			createViewInfoMenuItems(pluginMenu, plugin_view_info_map);
+
 
 			MenuItem menu_plugin_logViews = MenuFactory.addLogsViewMenuItem(pluginMenu);
-			createIViewInfoMenuItems(menu_plugin_logViews.getMenu(),
+			createViewInfoMenuItems(menu_plugin_logViews.getMenu(),
 					plugin_logs_view_info_map);
 
 		} finally {
@@ -82,14 +122,20 @@ public class PluginsMenuHelper
 		view_info.viewID = sViewID;
 		view_info.event_listener = l;
 
+		String name = null;
+
 		String sResourceID = UISWTViewImpl.CFG_PREFIX + sViewID + ".title";
 		boolean bResourceExists = MessageText.keyExists(sResourceID);
-
-		String name;
+		if (!bResourceExists) {
+			if (l instanceof UISWTViewEventListenerHolder) {
+				name = ((UISWTViewEventListenerHolder) l).getPluginInterface().getPluginconfig().getPluginStringParameter(
+						sResourceID, null);
+			}
+		}
 
 		if (bResourceExists) {
 			name = MessageText.getString(sResourceID);
-		} else {
+		} else if (name == null) {
 			// try plain resource
 			sResourceID = sViewID;
 			bResourceExists = MessageText.keyExists(sResourceID);
@@ -103,8 +149,16 @@ public class PluginsMenuHelper
 
 		view_info.name = name;
 
-		Map map_to_use = (l instanceof BasicPluginViewImpl)
-				? this.plugin_logs_view_info_map : this.plugin_view_info_map;
+		Map<String, IViewInfo> map_to_use;
+		
+		if ( 	( l instanceof BasicPluginViewImpl ) ||
+				(	( l instanceof UISWTViewEventListenerHolder )) && ((UISWTViewEventListenerHolder)l).isLogView()){
+					
+			map_to_use = plugin_logs_view_info_map;
+			
+		}else{
+			map_to_use = plugin_view_info_map;
+		}
 
 		try {
 			plugin_helper_mon.enter();
@@ -147,7 +201,7 @@ public class PluginsMenuHelper
 		});
 	}
 
-	public void addPluginView(final AbstractIView view, final String name) {
+	public void addPluginView(final UISWTViewCore view, final String name) {
 		IViewInfo view_info = new IViewInfo();
 		view_info.name = name;
 		view_info.view = view;
@@ -160,11 +214,11 @@ public class PluginsMenuHelper
 		triggerPluginAddedViewListeners(view_info);
 	}
 
-	public void removePluginView(final AbstractIView view, final String name) {
+	public void removePluginView(final UISWTViewCore view, final String name) {
 		IViewInfo view_info = null;
 		try {
 			plugin_helper_mon.enter();
-			view_info = (IViewInfo) this.plugin_view_info_map.remove(name);
+			view_info = plugin_view_info_map.remove(name);
 		} finally {
 			plugin_helper_mon.exit();
 		}
@@ -187,7 +241,7 @@ public class PluginsMenuHelper
 	 * @param parent
 	 */
 
-	private void createIViewInfoMenuItem(Menu parent, final IViewInfo info) {
+	private void createViewInfoMenuItem(Menu parent, final IViewInfo info) {
 		MenuItem item = new MenuItem(parent, SWT.NULL);
 		item.setText(info.name);
 		if (info.viewID != null) {
@@ -203,24 +257,24 @@ public class PluginsMenuHelper
 		});
 	}
 
-	private void createIViewInfoMenuItems(Menu parent, Map menu_data) {
+	private void createViewInfoMenuItems(Menu parent, Map menu_data) {
 		Iterator itr = menu_data.values().iterator();
 		while (itr.hasNext()) {
-			createIViewInfoMenuItem(parent, (IViewInfo) itr.next());
+			createViewInfoMenuItem(parent, (IViewInfo) itr.next());
 		}
 	}
 	
 	public IViewInfo[] getPluginViewsInfo() {
-		return (IViewInfo[])plugin_view_info_map.values().toArray(new IViewInfo[0]);
+		return plugin_view_info_map.values().toArray(new IViewInfo[0]);
 	}
 
 	public IViewInfo[] getPluginLogViewsInfo() {
-		return (IViewInfo[])plugin_logs_view_info_map.values().toArray(new IViewInfo[0]);
+		return plugin_logs_view_info_map.values().toArray(new IViewInfo[0]);
 	}
 
 	public static class IViewInfo
 	{
-		public AbstractIView view;
+		public UISWTViewCore view;
 
 		public String name;
 
@@ -241,17 +295,56 @@ public class PluginsMenuHelper
 	
 	public void addPluginAddedViewListener(PluginAddedViewListener l) {
 		pluginAddedViewListener.add(l);
+
+		IViewInfo[] viewsInfo = getPluginViewsInfo();
+		for (IViewInfo info : viewsInfo) {
+			l.pluginViewAdded(info);
+		}
+		viewsInfo = getPluginLogViewsInfo();
+		for (IViewInfo info : viewsInfo) {
+			l.pluginViewAdded(info);
+		}
 	}
 	
-	public void triggerPluginAddedViewListeners(IViewInfo viewInfo) {
-		Object[] listeners = pluginAddedViewListener.toArray();
-		for (int i = 0; i < listeners.length; i++) {
-			PluginAddedViewListener l = (PluginAddedViewListener) listeners[i];
-			l.pluginViewAdded(viewInfo);
+	public void triggerPluginAddedViewListeners(final IViewInfo viewInfo) {
+		final Object[] listeners = pluginAddedViewListener.toArray();
+		if (pluginAddedViewListener.size() > 0) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					for (int i = 0; i < listeners.length; i++) {
+						PluginAddedViewListener l = (PluginAddedViewListener) listeners[i];
+						l.pluginViewAdded(viewInfo);
+					}
+				}
+			});
 		}
 	}
 	
 	public static interface PluginAddedViewListener {
 		public void pluginViewAdded(IViewInfo viewInfo);
 	}
+
+	public IViewInfo findIViewInfo(UISWTViewEventListener l) {
+		IViewInfo foundViewInfo = null;
+
+		IViewInfo[] pluginViewsInfo = getPluginViewsInfo();
+		for (int i = 0; i < pluginViewsInfo.length; i++) {
+			IViewInfo viewInfo = pluginViewsInfo[i];
+			if (viewInfo.event_listener == l) {
+				foundViewInfo = viewInfo;
+				break;
+			}
+		}
+		if (foundViewInfo == null) {
+			pluginViewsInfo = getPluginLogViewsInfo();
+			for (int i = 0; i < pluginViewsInfo.length; i++) {
+				IViewInfo viewInfo = pluginViewsInfo[i];
+				if (viewInfo.event_listener == l) {
+					foundViewInfo = viewInfo;
+					break;
+				}
+			}
+		}
+		return foundViewInfo;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/Refreshable.java b/org/gudy/azureus2/ui/swt/mainwindow/Refreshable.java
deleted file mode 100644
index 825951c..0000000
--- a/org/gudy/azureus2/ui/swt/mainwindow/Refreshable.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.gudy.azureus2.ui.swt.mainwindow;
-
-public interface Refreshable {
-	
-	  /**
-	   * This method is called on each refresh.
-	   * The view should not instanciate a Thread to refresh itself, unless this is for async purposes. In which case, don't forget to call the display.asyncexec method.
-	   * Called by the GUI Thread
-	   */
-	  public void refresh();
-
-}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java b/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
index 1c3898d..39289ab 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/SWTThread.java
@@ -22,6 +22,7 @@
 package org.gudy.azureus2.ui.swt.mainwindow;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 import org.eclipse.swt.SWT;
@@ -35,6 +36,9 @@ 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.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.ui.*;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
@@ -68,6 +72,7 @@ public class SWTThread {
   private final IUIIntializer initializer;
   
 	private Monitor primaryMonitor;
+	protected boolean displayDispoed;
   
   private 
   SWTThread(
@@ -118,6 +123,7 @@ public class SWTThread {
 			}
 			return;
 		}
+    Thread.currentThread().setName("SWT Thread");
     
     primaryMonitor = display.getPrimaryMonitor();
     
@@ -165,17 +171,58 @@ public class SWTThread {
 				});
 			}
 		});
+    
+    // SWT.OpenDocument is only available on 3637
+		try {
+			Field fldOpenDoc = SWT.class.getDeclaredField("OpenDocument");
+			int SWT_OpenDocument = fldOpenDoc.getInt(null);
+
+			display.addListener(SWT_OpenDocument, new Listener() {
+				public void handleEvent(final Event event) {
+					AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+						public void azureusCoreRunning(AzureusCore core) {
+							TorrentOpener.openTorrents(new String[] { event.text } );
+						}
+					});
+				}
+			});
+		} catch (Throwable t) {
+		}
+
 
-		display.addListener(SWT.Activate, new Listener() {
+		Listener lShowMainWindow = new Listener() {
 			public void handleEvent(Event event) {
-				if (event.detail != 1) {
+				if ( event.type == SWT.Activate ){
+					
+					if ( AERunStateHandler.isDelayedUI()){
+						
+						Debug.out( "Ignoring activate event as delay start" );
+						
+						return;
+					}
+				}
+				Shell as = Display.getDefault().getActiveShell();
+				if (as != null) {
+					as.setVisible(true);
+					as.forceActive();
 					return;
 				}
 				UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
 				if (uif != null) {
-					uif.bringToFront(false);
+					Shell mainShell = uif.getMainShell();
+					if (mainShell == null || !mainShell.isVisible() || mainShell.getMinimized()) {
+  					uif.bringToFront(false);
+  				}
 				}
 			}
+		};
+		display.addListener(SWT.Activate, lShowMainWindow);
+		display.addListener(SWT.Selection, lShowMainWindow);
+		
+		display.addListener(SWT.Dispose, new Listener() {
+			public void handleEvent(Event event) {
+				displayDispoed = true;
+			}
 		});
 
 		if (Constants.isOSX) {
@@ -265,6 +312,8 @@ public class SWTThread {
   							e.printStackTrace();
   						if (Constants.isCVSVersion()) {
   							Logger.log(new LogAlert(LogAlert.UNREPEATABLE,MessageText.getString("SWT.alert.erroringuithread"),e));
+  						} else {
+  							Debug.out(MessageText.getString("SWT.alert.erroringuithread"), e);
   						}
 						}
 						
@@ -330,7 +379,8 @@ public class SWTThread {
   }
   
   public boolean isTerminated() {
-  	return terminated;
+  	//System.out.println("isTerm" + terminated + ";" + display.isDisposed() + Debug.getCompressedStackTrace(3));
+  	return terminated || display.isDisposed() || displayDispoed;
   }
 
 	public IUIIntializer getInitializer() {
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/SplashWindow.java b/org/gudy/azureus2/ui/swt/mainwindow/SplashWindow.java
index e69df95..3756174 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/SplashWindow.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/SplashWindow.java
@@ -32,7 +32,6 @@ 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.ImageRepository;
 import org.gudy.azureus2.ui.swt.Utils;
 
 import com.aelitis.azureus.ui.IUIIntializer;
@@ -54,7 +53,7 @@ public class SplashWindow
 	// config 4 : PB_HEIGHT = 3, PB_INVERTED = true, PB_INVERTED_BG_HEIGHT = 1, PB_INVERTED_X_OFFSET = 4
 	
 	protected static final int OFFSET_LEFT = 10;
-	protected static final int OFFSET_RIGHT = 139;
+	protected static final int OFFSET_RIGHT = 10;
 	protected static final int OFFSET_BOTTOM = 12;
 	protected static final int PB_HEIGHT = 2;
 	
@@ -151,6 +150,11 @@ public class SplashWindow
     if (ImageLoader.isRealImage(background)) {
     	width = background.getBounds().width;
     	height = background.getBounds().height;
+    	
+    	width = 500;
+    	height = 250;
+
+    	current = new Image(display, background, SWT.IMAGE_COPY);
     } else {
     	width = 400;
     	height = 80;
@@ -164,8 +168,8 @@ public class SplashWindow
     	} finally {
     		gc.dispose();
     	}
+    	current = new Image(display, background, SWT.IMAGE_COPY);
     }
-  	current = new Image(display, background, SWT.IMAGE_COPY);
 
 		progressBarColor = new Color(display, 21, 92, 198);
 		textColor = new Color(display, 90, 90, 90);
@@ -187,7 +191,56 @@ public class SplashWindow
 				if (current == null) {
 					return;
 				}
-				event.gc.drawImage(current, 0, 0);
+				Rectangle imgBounds = current.getBounds();
+				Rectangle canvasBounds = canvas.getBounds();
+				event.gc.drawImage(current, (canvasBounds.width - imgBounds.width) / 2, (canvasBounds.height - imgBounds.height - 30) / 2);
+
+				GC gc = event.gc;
+				
+				try {
+					gc.setAntialias(SWT.ON);
+					gc.setTextAntialias(SWT.ON);
+				} catch (Exception e) {
+
+				}
+				
+				int y = pbY;
+
+				if (task != null) {
+					gc.setFont(textFont);
+					gc.setForeground(textColor);
+					Point extent = gc.textExtent(task);
+					y = pbY - extent.y - 5;
+					gc.setClipping(OFFSET_LEFT, y, width - (OFFSET_LEFT * 2), extent.y);
+					gc.drawText(task, OFFSET_LEFT, y, true);
+					gc.setClipping((Rectangle) null);
+				}
+
+				if(PB_INVERTED){
+					gc.setForeground(fadedGreyColor);
+					gc.setBackground(fadedGreyColor);
+					gc.fillRectangle(pbX-PB_INVERTED_X_OFFSET, pbY + Math.abs(PB_HEIGHT - PB_INVERTED_BG_HEIGHT) / 2, pbWidth+2*PB_INVERTED_X_OFFSET, PB_INVERTED_BG_HEIGHT);
+					gc.setForeground(progressBarColor);
+					gc.setBackground(progressBarColor);
+					gc.fillRectangle(pbX, pbY, percent * pbWidth / 100, PB_HEIGHT);
+					
+				} else {
+					gc.setForeground(progressBarColor);
+					gc.setBackground(progressBarColor);
+					if(!DISPLAY_BORDER){
+						gc.fillRectangle(pbX, pbY, percent * pbWidth / 100, PB_HEIGHT);
+					}
+				}
+				
+				if(DISPLAY_BORDER){
+					gc.setForeground(fadedGreyColor);
+					gc.setBackground(fadedGreyColor);
+					canvasBounds.height--;
+					canvasBounds.width--;
+					gc.drawRectangle(canvasBounds);
+				}
+
+			
 			}
 		});
 
@@ -202,7 +255,7 @@ public class SplashWindow
 		}
 	}
 
-	public static void create(final Display display, final Initializer initializer) {
+	public static void create(final Display display, final IUIIntializer initializer) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (display == null || display.isDisposed())
@@ -286,61 +339,7 @@ public class SplashWindow
 					return;
 				}
 
-				Image newCurrent = new Image(display, background, SWT.IMAGE_COPY);
-				GC gc = new GC(newCurrent);
-
-				try {
-					gc.setAntialias(SWT.ON);
-					gc.setTextAntialias(SWT.ON);
-				} catch (Exception e) {
-
-				}
-				
-				int y = pbY;
-
-				if (task != null) {
-					gc.setFont(textFont);
-					gc.setForeground(textColor);
-					Point extent = gc.textExtent(task);
-					y = pbY - extent.y - 5;
-					gc.setClipping(OFFSET_LEFT, y, width - (OFFSET_LEFT * 2), extent.y);
-					gc.drawText(task, OFFSET_LEFT, y, true);
-					gc.setClipping((Rectangle) null);
-				}
-
-				if(PB_INVERTED){
-					gc.setForeground(fadedGreyColor);
-					gc.setBackground(fadedGreyColor);
-					gc.fillRectangle(pbX-PB_INVERTED_X_OFFSET, pbY + Math.abs(PB_HEIGHT - PB_INVERTED_BG_HEIGHT) / 2, pbWidth+2*PB_INVERTED_X_OFFSET, PB_INVERTED_BG_HEIGHT);
-					gc.setForeground(progressBarColor);
-					gc.setBackground(progressBarColor);
-					gc.fillRectangle(pbX, pbY, percent * pbWidth / 100, PB_HEIGHT);
-					
-				} else {
-					gc.setForeground(progressBarColor);
-					gc.setBackground(progressBarColor);
-					if(DISPLAY_BORDER){
-						gc.fillRectangle(pbX + 1, pbY, percent * (pbWidth - 2) / 100, PB_HEIGHT);
-						gc.setForeground(fadedGreyColor);
-						gc.setBackground(fadedGreyColor);
-						gc.fillRectangle(pbX, pbY - 1, pbWidth, 1);
-						gc.fillRectangle(pbX + pbWidth - 1, pbY, 1, PB_HEIGHT);
-						gc.fillRectangle(pbX, pbY + PB_HEIGHT, pbWidth, 1);
-						gc.fillRectangle(pbX, pbY, 1, PB_HEIGHT);
-					} else {
-						gc.fillRectangle(pbX, pbY, percent * pbWidth / 100, PB_HEIGHT);
-					}
-				}
-				
-				Image old = current;
-				current = newCurrent;
-				if (old != null && !old.isDisposed()) {
-					old.dispose();
-				}
-
-				gc.dispose();
-
-				canvas.redraw(0, y, width, height - y, true);
+				canvas.redraw(0, height - 50, width, height, true);
 				canvas.update();
 			}
 		});
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/SystemWarningWindow.java b/org/gudy/azureus2/ui/swt/mainwindow/SystemWarningWindow.java
new file mode 100644
index 0000000..33a8128
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/mainwindow/SystemWarningWindow.java
@@ -0,0 +1,420 @@
+/**
+ * Created on Jan 4, 2010
+ *
+ * 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.mainwindow;
+
+import java.util.ArrayList;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+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.ui.swt.Alerts;
+import org.gudy.azureus2.ui.swt.Messages;
+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 com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+/**
+ * @author TuxPaper
+ * @created Jan 4, 2010
+ *
+ */
+public class SystemWarningWindow
+{
+	private final static int WIDTH = 230;
+
+	private final static int BORDER_X = 12;
+
+	private final static int BORDER_Y0 = 10;
+
+	private final static int BORDER_Y1 = 6;
+
+	private final static int GAP_Y = 5;
+
+	private final static int GAP_BUTTON_Y = 20;
+
+	private final static int GAP_Y_TITLE_COUNT = 3;
+
+	private final LogAlert logAlert;
+
+	private final Point ptBottomRight;
+
+	private final Shell parent;
+
+	private Shell shell;
+
+	private Image imgClose;
+
+	private Rectangle boundsClose;
+
+	private GCStringPrinter spText;
+
+	private GCStringPrinter spTitle;
+
+	private GCStringPrinter spCount;
+
+	private Point sizeTitle;
+
+	private Point sizeText;
+
+	private Point sizeCount;
+
+	private Font fontTitle;
+
+	private Font fontCount;
+
+	private int height;
+
+	private Rectangle rectX;
+
+	private int historyPosition;
+
+	private String title;
+
+	private String text;
+	
+	public static int numWarningWindowsOpen = 0;
+
+	public SystemWarningWindow(LogAlert logAlert, Point ptBottomRight,
+			Shell parent, int historyPosition) {
+		this.logAlert = logAlert;
+		this.ptBottomRight = ptBottomRight;
+		this.parent = parent;
+		this.historyPosition = historyPosition;
+
+		String amb_key_suffix;
+		switch (logAlert.entryType) {
+			case LogAlert.AT_ERROR:
+				amb_key_suffix = "error";
+				break;
+			case LogAlert.AT_INFORMATION:
+				amb_key_suffix = "information";
+				break;
+			case LogAlert.AT_WARNING:
+				amb_key_suffix = "warning";
+				break;
+			default:
+				amb_key_suffix = null;
+				break;
+		}
+		title = amb_key_suffix == null ? Constants.APP_NAME
+				: MessageText.getString("AlertMessageBox." + amb_key_suffix);
+
+		if (logAlert.text.startsWith("{")) {
+			text = MessageText.expandValue(logAlert.text);
+		} else {
+			text = logAlert.text;
+		}
+		
+		if (logAlert.err != null) {
+			text += "\n" + Debug.getExceptionMessage(logAlert.err);
+		}
+
+		if (logAlert.details != null) {
+			text += "\n<A HREF=\"details\">" + MessageText.getString("v3.MainWindow.button.viewdetails") + "</A>";
+		}
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				openWindow();
+			}
+		});
+	}
+
+	protected void openWindow() {
+		Display display = parent.getDisplay();
+		//shell = new Shell(parent, SWT.TOOL | SWT.TITLE | SWT.CLOSE);
+		//shell.setText("Warning (X of X)");
+		shell = new Shell(parent, SWT.TOOL);
+		shell.setLayout(new FormLayout());
+		shell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+		shell.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+		
+		Menu menu = new Menu(shell);
+		MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(menuItem, "MyTorrentsView.menu.thisColumn.toClipboard");
+		menuItem.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				ClipboardCopy.copyToClipBoard(logAlert.text
+						+ (logAlert.details == null ? "" : "\n" + logAlert.details));
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		shell.setMenu(menu);
+
+
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		imgClose = imageLoader.getImage("image.systemwarning.closeitem");
+		boundsClose = imgClose.getBounds();
+
+		GC gc = new GC(shell);
+
+		FontData[] fontdata = gc.getFont().getFontData();
+		fontdata[0].setHeight(fontdata[0].getHeight() + 1);
+		fontdata[0].setStyle(SWT.BOLD);
+		fontTitle = new Font(display, fontdata);
+		
+		fontdata = gc.getFont().getFontData();
+		fontdata[0].setHeight(fontdata[0].getHeight() - 1);
+		fontCount = new Font(display, fontdata);
+
+		shell.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				Utils.disposeSWTObjects(new Object[] {
+					fontTitle,
+					fontCount,
+				});
+				numWarningWindowsOpen--;
+			}
+		});
+
+		Rectangle printArea = new Rectangle(BORDER_X, 0, WIDTH - (BORDER_X * 2),
+				5000);
+		spText = new GCStringPrinter(gc, text, printArea, true, false, SWT.WRAP);
+		spText.setUrlColor(Colors.blues[Colors.FADED_DARKEST]);
+		spText.calculateMetrics();
+
+		gc.setFont(fontCount);
+		String sCount = MessageText.getString("OpenTorrentWindow.xOfTotal",
+				new String[] {
+					"" + historyPosition + 1,
+					"" + getWarningCount()
+				});
+		spCount = new GCStringPrinter(gc, sCount, printArea, true, false, SWT.WRAP);
+		spCount.calculateMetrics();
+
+		gc.setFont(fontTitle);
+		spTitle = new GCStringPrinter(gc, title, printArea, true, false, SWT.WRAP);
+		spTitle.calculateMetrics();
+
+		gc.dispose();
+		sizeText = spText.getCalculatedSize();
+		sizeTitle = spTitle.getCalculatedSize();
+		sizeCount = spCount.getCalculatedSize();
+
+		FormData fd;
+
+		Button btnDismiss = new Button(shell, SWT.PUSH);
+		Messages.setLanguageText(btnDismiss, "Button.dismiss");
+		final int btnHeight = btnDismiss.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+
+		Button btnPrev = new Button(shell, SWT.PUSH);
+		btnPrev.setText("<");
+
+		Button btnNext = new Button(shell, SWT.PUSH);
+		btnNext.setText(">");
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -BORDER_Y1);
+		fd.right = new FormAttachment(100, -BORDER_X);
+		btnNext.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -BORDER_Y1);
+		fd.right = new FormAttachment(btnNext, -BORDER_X);
+		btnPrev.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.bottom = new FormAttachment(100, -BORDER_Y1);
+		fd.right = new FormAttachment(btnPrev, -BORDER_X);
+		btnDismiss.setLayoutData(fd);
+
+		height = BORDER_Y0 + sizeTitle.y + GAP_Y + sizeText.y + GAP_Y_TITLE_COUNT
+				+ sizeCount.y + GAP_BUTTON_Y + btnHeight + BORDER_Y1;
+
+		Rectangle area = shell.computeTrim(ptBottomRight.x - WIDTH, ptBottomRight.y
+				- height, WIDTH, height);
+		shell.setBounds(area);
+		shell.setLocation(ptBottomRight.x - area.width, ptBottomRight.y
+				- area.height - 2);
+
+		rectX = new Rectangle(area.width - BORDER_X - boundsClose.width, BORDER_Y0,
+				boundsClose.width, boundsClose.height);
+
+		shell.addMouseMoveListener(new MouseMoveListener() {
+			int lastCursor = SWT.CURSOR_ARROW;
+
+			public void mouseMove(MouseEvent e) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
+				URLInfo hitUrl = spText.getHitUrl(e.x, e.y);
+
+				int cursor = (rectX.contains(e.x, e.y)) || hitUrl != null
+						? SWT.CURSOR_HAND : SWT.CURSOR_ARROW;
+				if (cursor != lastCursor) {
+					lastCursor = cursor;
+					shell.setCursor(e.display.getSystemCursor(cursor));
+				}
+			}
+		});
+
+		shell.addMouseListener(new MouseListener() {
+			public void mouseUp(MouseEvent e) {
+				if (shell == null || shell.isDisposed()) {
+					return;
+				}
+				if (rectX.contains(e.x, e.y)) {
+					shell.dispose();
+				}
+				URLInfo hitUrl = spText.getHitUrl(e.x, e.y);
+				if (hitUrl != null) {
+					if (hitUrl.url.equals("details")) {
+						MessageBoxShell mb = new MessageBoxShell(Constants.APP_NAME,
+								logAlert.details, new String[] {
+									MessageText.getString("Button.ok")
+								}, 0);
+						mb.setUseTextBox(true);
+						mb.setParent(Utils.findAnyShell());
+						mb.open(null);
+					} else {
+						Utils.launch(hitUrl.url);
+					}
+				}
+			}
+
+			public void mouseDown(MouseEvent e) {
+			}
+
+			public void mouseDoubleClick(MouseEvent e) {
+			}
+		});
+
+		shell.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent e) {
+				e.gc.drawImage(imgClose, WIDTH - BORDER_X - boundsClose.width,
+						BORDER_Y0);
+
+				Rectangle printArea;
+				printArea = new Rectangle(BORDER_X, BORDER_Y0 + sizeTitle.y + GAP_Y_TITLE_COUNT,
+						WIDTH, 100);
+				String sCount = MessageText.getString("OpenTorrentWindow.xOfTotal",
+						new String[] {
+							"" + (historyPosition + 1),
+							"" + getWarningCount()
+						});
+				e.gc.setAlpha(180);
+				Font lastFont = e.gc.getFont();
+				e.gc.setFont(fontCount);
+				spCount = new GCStringPrinter(e.gc, sCount, printArea, true, false,
+						SWT.WRAP | SWT.TOP);
+				spCount.printString();
+				e.gc.setAlpha(255);
+				sizeCount = spCount.getCalculatedSize();
+
+				e.gc.setFont(lastFont);
+				spText.printString(e.gc, new Rectangle(BORDER_X, BORDER_Y0
+						+ sizeTitle.y + GAP_Y_TITLE_COUNT + sizeCount.y + GAP_Y, WIDTH - BORDER_X
+						- BORDER_X, 5000), SWT.WRAP | SWT.TOP);
+
+				e.gc.setFont(fontTitle);
+
+				e.gc.setForeground(ColorCache.getColor(e.gc.getDevice(), "#54728c"));
+				spTitle.printString(e.gc, new Rectangle(BORDER_X, BORDER_Y0, WIDTH
+						- BORDER_X - BORDER_X, 5000), SWT.WRAP | SWT.TOP);
+
+				e.gc.setLineStyle(SWT.LINE_DOT);
+				e.gc.setLineWidth(1);
+				e.gc.setAlpha(180);
+				e.gc.drawLine(BORDER_X, height - btnHeight - (GAP_BUTTON_Y / 2)
+						- BORDER_Y1, WIDTH - BORDER_X, height - btnHeight
+						- (GAP_BUTTON_Y / 2) - BORDER_Y1);
+
+			}
+		});
+
+		shell.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE) {
+					shell.dispose();
+					return;
+				}
+			}
+		});
+
+		btnPrev.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+				int pos = historyPosition - 1;
+				if (pos < 0 || pos >= alerts.size()) {
+					return;
+				}
+
+				new SystemWarningWindow(alerts.get(pos), ptBottomRight, parent, pos);
+				shell.dispose();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		btnPrev.setEnabled(historyPosition > 0); 
+
+		btnNext.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+				int pos = historyPosition + 1;
+				if (pos >= alerts.size()) {
+					return;
+				}
+
+				new SystemWarningWindow(alerts.get(pos), ptBottomRight, parent, pos);
+				shell.dispose();
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+		btnNext.setEnabled(alerts.size() != historyPosition + 1); 
+
+		btnDismiss.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				ArrayList<LogAlert> alerts = Alerts.getUnviewedLogAlerts();
+				for (int i = 0; i < alerts.size() && i <= historyPosition; i++) {
+					Alerts.markAlertAsViewed(alerts.get(i));
+				}
+				shell.dispose();
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		
+		shell.open();
+		numWarningWindowsOpen++;
+	}
+
+	private int getWarningCount() {
+		ArrayList<LogAlert> historyList = Alerts.getUnviewedLogAlerts();
+		return historyList.size();
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/TorrentOpener.java b/org/gudy/azureus2/ui/swt/mainwindow/TorrentOpener.java
index 8e47cf8..b46fb43 100644
--- a/org/gudy/azureus2/ui/swt/mainwindow/TorrentOpener.java
+++ b/org/gudy/azureus2/ui/swt/mainwindow/TorrentOpener.java
@@ -30,6 +30,7 @@ import java.util.List;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.DND;
 import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Shell;
@@ -63,19 +64,22 @@ public class TorrentOpener {
 	 * @param torrentFile Torrent to open (file, url, etc)
 	 */
 	public static void openTorrent(String torrentFile) {
-		openTorrentWindow(null, new String[] { torrentFile }, false);
+		openTorrentWindow(null, new String[] { torrentFile }, false, false );
 	}
 	
+	public static void openTorrent(String torrentFile, boolean force_open ) {
+		openTorrentWindow(null, new String[] { torrentFile }, false, false, force_open );
+	}
 	public static void openTorrents(String[] torrentFiles) {
-		openTorrentWindow(null, torrentFiles, false);
+		openTorrentWindow(null, torrentFiles, false, false );
 	}
   
 	/**
 	 * Open the torrent window
 	 *
 	 */
-  public static void openTorrentWindow() {
-  	openTorrentWindow(null, null, false);
+  public static void openTorrentWindow( boolean for_uri ) {
+  	openTorrentWindow(null, null, false, for_uri );
   }
 
   protected static void 
@@ -158,13 +162,12 @@ public class TorrentOpener {
 				if (path == null)
 					return;
 
-				openTorrentWindow(path, fDialog.getFileNames(), false);
+				openTorrentWindow(path, fDialog.getFileNames(), false, false );
 			}
 		});
 	}
 
-  public static void openDroppedTorrents(DropTargetEvent event,
-			final boolean bAllowShareAdd) {
+  public static void openDroppedTorrents(DropTargetEvent event, boolean deprecated_sharing_param ){
 		if (event.data == null)
 			return;
 
@@ -183,7 +186,7 @@ public class TorrentOpener {
 				String sURL = UrlUtils.parseTextForURL(sourceNames[i], true);
 
 				if (sURL != null && !source.exists()) {
-					openTorrentWindow(null, new String[] { sURL }, bOverrideToStopped);
+					openTorrentWindow(null, new String[] { sURL }, bOverrideToStopped, false );
 				} else if (source.isFile()) {
 					
 						// go async as vuze file handling can require UI access which then blocks
@@ -205,14 +208,8 @@ public class TorrentOpener {
 							
 							
 							try {
-								if (!TorrentUtils.isTorrentFile(filename) && bAllowShareAdd) {
-									Logger.log(new LogEvent(LogIDs.GUI,
-													"openDroppedTorrents: file not a torrent file, sharing"));
-									ShareUtils.shareFile(filename);
-								} else {
-									openTorrentWindow(null, new String[] { filename },
-											bOverrideToStopped);
-								}
+								openTorrentWindow(null, new String[] { filename }, bOverrideToStopped, false );
+				
 							} catch (Exception e) {
 								Logger.log(new LogAlert(LogAlert.REPEATABLE,
 										"Torrent open fails for '" + filename + "'", e));
@@ -224,28 +221,13 @@ public class TorrentOpener {
 					
 					String dir_name = source.getAbsolutePath();
 
-					if (!bAllowShareAdd) {
-						openTorrentWindow(dir_name, null, bOverrideToStopped);
-					} else {
-						String drop_action = COConfigurationManager.getStringParameter(
-								"config.style.dropdiraction" );
-	
-						if (drop_action.equals("1")) {
-							ShareUtils.shareDir(dir_name);
-						} else if (drop_action.equals("2")) {
-							ShareUtils.shareDirContents(dir_name, false);
-						} else if (drop_action.equals("3")) {
-							ShareUtils.shareDirContents(dir_name, true);
-						} else {
-							openTorrentWindow(dir_name, null, bOverrideToStopped);
-						}
-					}
+					openTorrentWindow(dir_name, null, bOverrideToStopped, false );
 				}
 			}
 		} else if (event.data instanceof URLTransfer.URLType) {
 			openTorrentWindow(null,
 					new String[] { ((URLTransfer.URLType) event.data).linkURL },
-					bOverrideToStopped);
+					bOverrideToStopped, false );
 		}
 	}
   
@@ -303,20 +285,35 @@ public class TorrentOpener {
     return path;
   }
 
-  private static void openTorrentWindow(final String path,
-			final String[] torrents, final boolean bOverrideStartModeToStopped)
+  private static void 
+  openTorrentWindow(
+	final String path,
+	final String[] torrents, 
+	final boolean bOverrideStartModeToStopped,
+	final boolean for_uri )
+  {
+	  openTorrentWindow( path, torrents, bOverrideStartModeToStopped, for_uri, false );
+  }
+  
+  private static void 
+  openTorrentWindow(
+	final String path,
+	final String[] torrents, 
+	final boolean bOverrideStartModeToStopped,
+	final boolean for_uri,
+	final boolean force_open )
 	{
   	// loadVuzeFile takes a long time if it's fetching a URL, so prevent it
   	// from blocking the calling thread (like the SWT Thread)
   	new AEThread2("openTorrentWindow", true) {
 			public void run() {
-				_openTorrentWindow(path, torrents, bOverrideStartModeToStopped);
+				_openTorrentWindow(path, torrents, bOverrideStartModeToStopped, for_uri, force_open );
 			}
 		}.start();
 	}
 
   private static void _openTorrentWindow(final String path,
-			String[] torrents, final boolean bOverrideStartModeToStopped)
+			String[] torrents, final boolean bOverrideStartModeToStopped, final boolean for_uri, final boolean force_open )
 	{
 	  		// this is a good place to trim out any .vuze files
 	  
@@ -388,12 +385,12 @@ public class TorrentOpener {
 											AzureusCoreComponent component) {
 										if (component instanceof UIFunctionsSWT) {
 											openTorrentWindow(path, f_torrents,
-													bOverrideStartModeToStopped);
+													bOverrideStartModeToStopped, for_uri );
 										}
 									}
 								});
 							} else {
-								openTorrentWindow(path, f_torrents, bOverrideStartModeToStopped);
+								openTorrentWindow(path, f_torrents, bOverrideStartModeToStopped, for_uri );
 							}
 						}
 					});
@@ -406,8 +403,50 @@ public class TorrentOpener {
 
 				OpenTorrentWindow.invoke(shell,
 						AzureusCoreFactory.getSingleton().getGlobalManager(), path,
-						f_torrents, bOverrideStartModeToStopped, false, false);
+						f_torrents, bOverrideStartModeToStopped, false, for_uri, force_open );
 			}
 		});
 	}
+
+	public static boolean doesDropHaveTorrents(DropTargetEvent event) {
+		boolean isTorrent = false;
+		if (event.data == null && event.currentDataType != null) {
+			FileTransfer ft = FileTransfer.getInstance();
+			if (ft.isSupportedType(event.currentDataType)) {
+				Object data = ft.nativeToJava(event.currentDataType);
+				String[] fileList = (data instanceof String) ? new String[] {
+					(String) data
+				} : (String[]) data;
+				if (fileList != null) {
+					for (String file : fileList) {
+						if (file.endsWith(".torrent") || file.endsWith(".vuze")) {
+							isTorrent = true;
+							break;
+						}
+					}
+				}
+			} else {
+				Object object = URLTransfer.getInstance().nativeToJava(
+						event.currentDataType);
+				if (object instanceof URLTransfer.URLType) {
+					isTorrent = true;
+				}
+			}
+		} else if (event.data instanceof String[] || event.data instanceof String) {
+			final String[] sourceNames = (event.data instanceof String[])
+					? (String[]) event.data : new String[] {
+						(String) event.data
+					};
+			for (String name : sourceNames) {
+				String sURL = UrlUtils.parseTextForURL(name, true);
+				if (sURL != null) {
+					isTorrent = true;
+					break;
+				}
+			}
+		} else if (event.data instanceof URLTransfer.URLType) {
+			isTorrent = true;
+		}
+		return isTorrent;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java b/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java
deleted file mode 100644
index 1348027..0000000
--- a/org/gudy/azureus2/ui/swt/mainwindow/UIFunctionsImpl.java
+++ /dev/null
@@ -1,567 +0,0 @@
-/*
- * Created on Jul 12, 2006 2:56:52 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 org.gudy.azureus2.ui.swt.mainwindow;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.FillLayout;
-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;
-import org.gudy.azureus2.ui.swt.plugins.*;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-import org.gudy.azureus2.ui.swt.shells.SimpleBrowserWindow;
-import org.gudy.azureus2.ui.swt.update.FullUpdateWindow;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-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;
-
-/**
- * @author TuxPaper
- * @created Jul 12, 2006
- *
- */
-public class UIFunctionsImpl
-	implements UIFunctionsSWT
-{
-
-	private final MainWindow mainwindow;
-
-	/**
-	 * @param window
-	 */
-	public UIFunctionsImpl(MainWindow mainwindow) {
-		this.mainwindow = mainwindow;
-	}
-
-	// UIFunctions
-	public void bringToFront() {
-		bringToFront(true);
-	}
-
-	public void bringToFront(final boolean tryTricks) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.setVisible(true, tryTricks);
-			}
-		});
-	}
-
-	// UIFunctions
-	public void addPluginView(final PluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().addPluginView(view,
-						view.getPluginViewName());
-			}
-		});
-	}
-
-	public void openPluginView(final PluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.openPluginView(view, view.getPluginViewName());
-			}
-		});
-	}
-
-	public void removePluginView(final PluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().removePluginView(view,
-						view.getPluginViewName());
-			}
-		});
-	}
-
-	private void showStats() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showStats();
-			}
-		});
-	}
-
-	private void showStatsDHT() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showStatsDHT();
-			}
-		});
-	}
-
-	private void showStatsTransfers() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showStatsTransfers();
-			}
-		});
-	}
-
-	public Shell getMainShell() {
-		return mainwindow.getShell();
-	}
-
-	public void addPluginView(final UISWTPluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().addPluginView(view,
-						view.getPluginViewName());
-			}
-		});
-	}
-
-	public void openPluginView(final UISWTPluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.openPluginView(view, view.getPluginViewName());
-			}
-		});
-	}
-
-	public void removePluginView(final UISWTPluginView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().removePluginView(view,
-						view.getPluginViewName());
-			}
-		});
-	}
-
-	public boolean showConfig(String string) {
-		return mainwindow.showConfig(string);
-	}
-
-	public void addPluginView(final String viewID, final UISWTViewEventListener l) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().addPluginView(viewID, l);
-			}
-		});
-	}
-
-	public void refreshLanguage() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.setSelectedLanguageItem();
-			}
-		});
-	}
-
-	public void closeDownloadBars() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				MiniBarManager.getManager().closeAll();
-			}
-		});
-	}
-
-	public boolean isGlobalTransferBarShown() {
-		return AllTransfersBar.getManager().isOpen(mainwindow.getGlobalManager());
-	}
-
-	public void showGlobalTransferBar() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				AllTransfersBar.open(mainwindow.getGlobalManager(),
-						mainwindow.getShell());
-			}
-		});
-	}
-
-	public void closeGlobalTransferBar() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				AllTransfersBar.close(mainwindow.getGlobalManager());
-			}
-		});
-	}
-
-	public UISWTInstanceImpl getSWTPluginInstanceImpl() {
-		return mainwindow.getUISWTInstanceImpl();
-	}
-
-	public void openManagerView(final DownloadManager dm) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.openManagerView(dm);
-			}
-		});
-	}
-
-	public void refreshIconBar() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.refreshIconBar();
-			}
-		});
-	}
-
-	public void removeManagerView(final DownloadManager dm) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.removeManagerView(dm);
-			}
-		});
-	}
-
-	private void showMyTracker() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showMyTracker();
-			}
-		});
-	}
-
-	public void closePluginView(final IView view) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.closePluginView(view);
-			}
-		});
-	}
-
-	public UISWTView[] getPluginViews() {
-		return mainwindow.getPluginViews();
-	}
-
-	public void openPluginView(final String sParentID, final String sViewID,
-			final UISWTViewEventListener l, final Object dataSource,
-			final boolean bSetFocus) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.openPluginView(sParentID, sViewID, l, dataSource, bSetFocus,
-						false);
-			}
-		});
-	}
-
-	public void removePluginView(final String viewID) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				PluginsMenuHelper.getInstance().removePluginViews(viewID);
-			}
-		});
-	}
-
-	public void setStatusText(final String string) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.setStatusText(string);
-			}
-		});
-	}
-
-	public void setStatusText(final int statustype, final String string,
-			final UIStatusTextClickListener l) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.setStatusText(statustype, string, l);
-			}
-		});
-	}
-
-	public boolean dispose(boolean for_restart, boolean close_already_in_progress) {
-		return mainwindow.dispose(for_restart, close_already_in_progress);
-	}
-
-	public Menu getMenu(int id) {
-		if (mainwindow.getMenu() != null) {
-			return mainwindow.getMenu().getMenu(id);
-		}
-		return null;
-	}
-
-	public void closePluginViews(final String sViewID) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.closePluginViews(sViewID);
-			}
-		});
-	}
-
-	public void openPluginView(final AbstractIView view, final String name) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.openPluginView(view, name);
-			}
-		});
-	}
-
-	private void showMyShares() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showMyShares();
-			}
-		});
-	}
-
-	private void showMyTorrents() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showMyTorrents();
-			}
-		});
-	}
-
-	private void showDetailedListView() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showDetailedListView();
-			}
-		});
-	}
-	
-	private void showAllPeersView() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showAllPeersView();
-			}
-		});
-	}
-
-	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() {
-				mainwindow.showMultiOptionsView(dms);
-			}
-		});
-	}
-
-	private void showConsole() {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				mainwindow.showConsole();
-			}
-		});
-	}
-
-	public UISWTInstance getUISWTInstance() {
-		return mainwindow.getUISWTInstanceImpl();
-	}
-	
-	// @see com.aelitis.azureus.ui.UIFunctions#viewURL(java.lang.String, java.lang.String, java.lang.String)
-	public void viewURL(String url, String target, String sourceRef) {
-		viewURL(url, target, 0.9, 0.9, true, false);
-	}
-
-	// @see com.aelitis.azureus.ui.UIFunctions#viewURL(java.lang.String, java.lang.String, int, int, boolean, boolean)
-	public boolean viewURL(final String url, final String target, final int w,
-			final int h, final boolean allowResize, final boolean isModal) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				SimpleBrowserWindow window = new SimpleBrowserWindow(
-						mainwindow.getShell(), url, w, h, allowResize, isModal);
-				window.waitUntilClosed();
-			}
-		});
-		return true;
-	}
-
-	// @see com.aelitis.azureus.ui.UIFunctions#viewURL(java.lang.String, java.lang.String, double, double, boolean, boolean)
-	public boolean viewURL(final String url, final String target, final double w,
-			final double h, final boolean allowResize, final boolean isModal) {
-		Utils.execSWTThreadLater(0, new AERunnable() {
-			public void runSupport() {
-				SimpleBrowserWindow window = new SimpleBrowserWindow(
-						mainwindow.getShell(), url, w, h, allowResize, isModal);
-				window.waitUntilClosed();
-			}
-		});
-		return true;
-	}
-
-	// @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 void promptUser(String title, String text, String[] buttons,
-			int defaultOption, String rememberID, String rememberText,
-			boolean rememberByDefault, int autoCloseInMS, UserPrompterResultListener l) {
-		MessageBoxShell.open(getMainShell(), title, text, buttons,
-				defaultOption, rememberID, rememberText, rememberByDefault,
-				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(title, text, buttons,
-				defaultOption);
-		return mb;
-	}
-
-	public void refreshTorrentMenu() {
-		mainwindow.refreshTorrentMenu();
-	}
-
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMainStatusBar()
-	public MainStatusBar getMainStatusBar() {
-		return mainwindow.getMainStatusBar();
-	}
-
-	public IMainMenu createMainMenu(Shell shell) {
-		return new MainMenu(shell);
-	}
-
-	public IMainWindow getMainWindow() {
-		return mainwindow;
-	}
-
-	// @see com.aelitis.azureus.ui.UIFunctions#getUIUpdater()
-	public UIUpdater getUIUpdater() {
-		return UIUpdaterSWT.getInstance();
-	}
-	
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closeAllDetails()
-	public void closeAllDetails() {
-		mainwindow.closeAllDetails();
-	}
-	
-	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#hasDetailViews()
-	public boolean hasDetailViews() {
-		return mainwindow.hasDetailViews();
-	}
-
-	// @see com.aelitis.azureus.ui.UIFunctions#openView(int, java.lang.Object)
-	public void openView(int viewID, Object datasource) {
-		switch (viewID) {
-			case VIEW_CONSOLE:
-				showConsole();
-				break;
-
-			case VIEW_ALLPEERS:
-				showAllPeersView();
-				break;
-
-			case VIEW_PEERS_STATS:
-				showClientStatsView();
-				break;
-
-			case VIEW_CONFIG:
-				showConfig((datasource instanceof String) ? (String) datasource : null);
-				break;
-
-			case VIEW_DM_DETAILS:
-				if (datasource instanceof DownloadManager) {
-					openManagerView((DownloadManager) datasource);
-				}
-				break;
-
-			case VIEW_DM_MULTI_OPTIONS:
-				if (datasource instanceof DownloadManager[]) {
-					DownloadManager[] dms = (DownloadManager[]) datasource;
-					showMultiOptionsView(dms);
-				}
-				break;
-
-			case VIEW_MYSHARES:
-				showMyShares();
-				break;
-
-			case VIEW_MYTORRENTS:
-				showMyTorrents();
-				break;
-
-			case VIEW_MYTRACKER:
-				showMyTracker();
-				break;
-
-			case VIEW_STATS:
-				if ("dht".equals(datasource)) {
-					showStatsDHT();
-				} else if ("transfers".equals(datasource)) {
-					showStatsTransfers();
-				} else {
-					showStats();
-				}
-				break;
-
-			case VIEW_DETAILED_LISTVIEW:
-				showDetailedListView();
-				break;
-
-			default:
-				break;
-		}
-	}
-	
-	
-	public void 
-	performAction(
-		int 			action_id, 
-		Object 			args, 
-		actionListener 	listener )
-	{
-		if ( action_id == ACTION_FULL_UPDATE ){
-			
-			FullUpdateWindow.handleUpdate((String)args, listener );
-			
-		}else{
-			
-			Debug.out( "Unknown action " + action_id );
-		}
-	}
-
-	public Shell showCoreWaitDlg() {
-		Shell activeShell = Display.getDefault().getActiveShell();
-		if (activeShell == null) {
-			activeShell = Utils.findAnyShell();
-		}
-		Shell shell = new Shell(activeShell, SWT.TITLE | SWT.BORDER
-				| SWT.APPLICATION_MODAL);
-		shell.setText("Please Wait");
-		FillLayout fillLayout = new FillLayout();
-		fillLayout.marginHeight = 5;
-		fillLayout.marginWidth = 5;
-		shell.setLayout(fillLayout);
-
-		Label label = new Label(shell, SWT.NONE);
-		label.setText("Your operation will run momentarily");
-
-		shell.pack();
-		//shell.setSize(300,50);
-		Utils.centreWindow(shell);
-		shell.open();
-		return shell;
-	}
-	
-	// @see com.aelitis.azureus.ui.UIFunctions#doSearch(java.lang.String)
-	public void doSearch(String searchText) {
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/BYOPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/BYOPanel.java
new file mode 100644
index 0000000..682a4a9
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/maketorrent/BYOPanel.java
@@ -0,0 +1,521 @@
+/*
+ * File : SingleFilePanel.java Created : 30 sept. 2003 02:50:19 By : Olivier
+ * 
+ * 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.swt.maketorrent;
+
+import java.io.File;
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.*;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
+import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
+
+import com.aelitis.azureus.util.MapUtils;
+
+/**
+ * @author Olivier
+ *  
+ */
+public class BYOPanel
+	extends AbstractWizardPanel<NewTorrentWizard>
+{
+
+	private Tree tree;
+
+	public BYOPanel(NewTorrentWizard wizard,
+			IWizardPanel<NewTorrentWizard> previous) {
+		super(wizard, previous);
+
+		wizard.byo_map = null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#show()
+	 */
+	public void show() {
+		wizard.setTitle(MessageText.getString("wizard.newtorrent.byo"));
+		wizard.setCurrentInfo(MessageText.getString("wizard.newtorrent.byo.info"));
+		Composite panel = wizard.getPanel();
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		panel.setLayout(layout);
+
+		GridData gridData;
+
+		tree = new Tree(panel, SWT.BORDER | SWT.MULTI);
+		tree.setHeaderVisible(true);
+		TreeColumn treeColumn = new TreeColumn(tree, 0);
+		Messages.setLanguageText(treeColumn, "label.torrent.structure");
+		treeColumn.setWidth(180);
+		treeColumn = new TreeColumn(tree, 0);
+		Messages.setLanguageText(treeColumn, "label.original.file");
+		treeColumn.setWidth(500);
+		gridData = new GridData(GridData.FILL_BOTH);
+		tree.setLayoutData(gridData);
+
+		createDropTarget(tree);
+		createDragSource(tree);
+		
+		tree.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+				editSelected();
+				e.doit = false;
+			}
+		});
+
+		tree.addKeyListener(new KeyListener() {
+			public void keyReleased(KeyEvent e) {
+			}
+
+			public void keyPressed(KeyEvent e) {
+				if (e.keyCode == SWT.F2) {
+					editSelected();
+				} else if (e.keyCode == SWT.DEL) {
+					TreeItem[] selection = tree.getSelection();
+					for (TreeItem treeItem : selection) {
+						Object data = treeItem.getData();
+						treeItem.dispose();
+					}
+				}
+			}
+		});
+		
+		Composite cButtons = new Composite(panel, 0);
+		cButtons.setLayout(new RowLayout());
+		cButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		Button btnAddContainer = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnAddContainer, "button.add.container");
+		btnAddContainer.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+						"wizard.newtorrent.byo.addcontainer.title",
+						"wizard.newtorrent.byo.addcontainer.text");
+				entryWindow.setPreenteredText("files", true);
+				entryWindow.prompt();
+				if (entryWindow.hasSubmittedInput()) {
+					createContainer(null, entryWindow.getSubmittedInput());
+				}
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		Button btnAddFiles = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnAddFiles, "OpenTorrentWindow.addFiles");
+		btnAddFiles.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog fDialog = new FileDialog(Utils.findAnyShell(), SWT.OPEN | SWT.MULTI);
+				fDialog.setFilterPath(TorrentOpener.getFilterPathData());
+				fDialog.setText(MessageText.getString("MainWindow.dialog.choose.file"));
+				if (fDialog.open() != null) {
+					String[] fileNames = fDialog.getFileNames();
+					for (String fileName : fileNames) {
+						addFilename(new File(fDialog.getFilterPath(), fileName));
+					}
+				}
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		Button btnAddFolder = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnAddFolder, "OpenTorrentWindow.addFiles.Folder");
+		btnAddFolder.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				DirectoryDialog fDialog = new DirectoryDialog(Utils.findAnyShell(), SWT.NULL);
+				fDialog.setFilterPath(TorrentOpener.getFilterPathData());
+				fDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.folder"));
+				String path = fDialog.open();
+				if (path != null) {
+					addFilename(new File(path));
+				}
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		
+		
+		if (wizard.byo_map != null) {
+			List list = (List) wizard.byo_map.get("file_map");
+			if (list != null) {
+				for (Iterator iterator = list.iterator(); iterator.hasNext();) {
+					Map map = (Map) iterator.next();
+					String target = MapUtils.getMapString(map, "target", null);
+					List path = MapUtils.getMapList(map, "logical_path", null);
+					if (target != null && path != null) {
+						File targetFile = new File(target);
+						if (path.size() == 1) {
+							addFilename(targetFile, (String) path.get(0), null, true);
+						} else {
+							TreeItem[] items = tree.getItems();
+							TreeItem parent = null;
+							for (int i = 0; i < path.size() - 1; i++) {
+								TreeItem lastParent = parent;
+								String name = (String) path.get(i);
+
+								boolean found = false;
+								for (TreeItem item : items) {
+									if (item.getText().equals(name)) {
+										parent = item;
+										found = true;
+										break;
+									}
+								}
+								if (!found) {
+									parent = createContainer(lastParent, name);
+								}
+								items = parent.getItems();
+							}
+							String name = (String) path.get(path.size() - 1);
+							addFilename(targetFile, name, parent, false);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void createDragSource(final Tree tree) {
+		Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
+    int operations = DND.DROP_MOVE;
+
+    final DragSource source = new DragSource(tree, operations);
+    source.setTransfer(types);
+    source.addDragListener(new DragSourceListener() {
+
+			public void dragStart(DragSourceEvent event) {
+				TreeItem[] selection = tree.getSelection();
+        event.doit = selection.length > 0;
+				tree.setData("dragging", 1);
+      };
+
+      public void dragSetData(DragSourceEvent event) {
+        event.data = "drag";
+        event.detail = DND.DROP_MOVE;
+      }
+
+			public void dragFinished(DragSourceEvent event) {
+				tree.setData("dragging", null);
+			}
+
+    });
+    
+    tree.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				source.dispose();
+			}
+		});
+	}
+
+	protected void editSelected() {
+		TreeItem[] selection = tree.getSelection();
+		if (selection.length == 1) {
+			SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+					"wizard.newtorrent.byo.editname.title",
+					"wizard.newtorrent.byo.editname.text");
+			entryWindow.setPreenteredText(selection[0].getText(), false);
+			entryWindow.prompt();
+			if (entryWindow.hasSubmittedInput()) {
+				selection[0].setText(entryWindow.getSubmittedInput());
+			}
+		}
+	}
+
+	private void createDropTarget(final Tree tree) {
+		final DropTarget dropTarget = new DropTarget(tree, DND.DROP_MOVE
+				| DND.DROP_LINK);
+		dropTarget.setTransfer(new Transfer[] {
+			TextTransfer.getInstance(),
+			FileTransfer.getInstance()
+		});
+		dropTarget.addDropListener(new DropTargetAdapter() {
+			public void dragOver(DropTargetEvent event) {
+				event.detail = DND.DROP_DEFAULT;
+				event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
+				if (event.item instanceof TreeItem) {
+					TreeItem item = (TreeItem) event.item;
+					
+					if (tree.getData("dragging") != null) {
+						TreeItem[] selection = tree.getSelection();
+						boolean ok = true;
+						for (TreeItem treeItem : selection) {
+							if (treeItem == item) {
+								ok = false;
+								break;
+							}
+							if (item.getData() == null) {
+								// dragging to container
+								if (treeItem.getParentItem() == item) { 
+									ok = false;
+									break;
+								}
+							} else {
+								if (treeItem.getParentItem() == item.getParentItem()) { 
+									ok = false;
+									break;
+								}
+							}
+						}
+						if (!ok) {
+							event.detail = DND.DROP_NONE;
+							return;
+						}
+					}
+
+
+					if (item.getData() == null) {
+						event.feedback |= DND.FEEDBACK_SELECT;
+					} else {
+						event.feedback |= DND.FEEDBACK_INSERT_AFTER;
+					}
+				}
+			}
+
+			public void drop(DropTargetEvent event) {
+				if (event.data instanceof String[]) {
+					String[] sourceNames = (String[]) event.data;
+					if (sourceNames == null)
+						event.detail = DND.DROP_NONE;
+					if (event.detail == DND.DROP_NONE)
+						return;
+
+					for (String droppedFileStr : sourceNames) {
+						File droppedFile = new File(droppedFileStr);
+						addFilename(droppedFile, (TreeItem) event.item);
+					}
+				} else if ("drag".equals(event.data)) {
+					TreeItem[] selection = tree.getSelection();
+					for (TreeItem treeItem : selection) {
+						if (!treeItem.isDisposed()) {
+							moveItem(treeItem, (TreeItem) event.item);
+						}
+					}
+				}
+			}
+		});
+		
+    tree.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				dropTarget.dispose();
+			}
+		});
+
+	}
+
+	protected void addFilename(File file) {
+		addFilename(file, file.getName(), null, false);
+	}
+
+	protected void addFilename(File file, TreeItem parent) {
+		addFilename(file, file.getName(),parent, false);
+	}
+
+	protected void addFilename(File file, String name, TreeItem parent, boolean init) {
+		if (parent != null && parent.getData() != null) {
+			parent = parent.getParentItem();
+		}
+		TreeItem firstItem = tree.getItemCount() > 0 ? tree.getItem(0) : null;
+		if (firstItem != null && firstItem.getData() != null) {
+			parent = createContainer(null, file.getParentFile().getName());
+		} else if (parent == null) {
+			parent = firstItem;
+		}
+		
+		if (!file.exists()) {
+			//dropping container from a drag
+			createContainer(null, name);
+		}
+
+		TreeItem treeItem = parent == null ? new TreeItem(tree, 0)
+				: new TreeItem(parent, 0);
+		treeItem.setText(new String[] {
+			name,
+			file.getAbsolutePath()
+		});
+		treeItem.setData(file);
+		
+		if (parent != null) {
+			parent.setExpanded(true);
+		}
+
+		wizard.setNextEnabled(tree.getItemCount() >= 1);
+	}
+
+	private TreeItem createContainer(TreeItem parent, String name) {
+		TreeItem[] selection = tree.getSelection();
+		boolean moveSelected = false;
+		if (parent == null) {
+  		if (selection.length == 1 && selection[0].getData() == null) {
+  			parent = selection[0];
+  		} else if (selection.length > 0) {
+  			parent = selection[0].getParentItem();
+  			//moveSelected = true;
+  		} else {
+  			TreeItem firstItem = tree.getItemCount() > 0 ? tree.getItem(0) : null;
+  			if (firstItem != null && firstItem.getData() == null) {
+  				parent = firstItem;
+  			}
+  		}
+		}
+
+		TreeItem item = parent == null ? new TreeItem(tree, 0, 0) : new TreeItem(parent, 0, 0);
+		item.setText(new String[] {
+			name,
+			MessageText.getString( "label.container.display")
+		});
+
+		while (tree.getItemCount() > 1) {
+			TreeItem itemToMove = tree.getItem(1);
+			moveItem(itemToMove, item);
+		}
+		item.setExpanded(true);
+		
+		if (moveSelected) {
+			// move selected into new item
+			for (TreeItem itemToMove : selection) {
+				moveItem(itemToMove, item);
+			}
+		}
+		
+		return item;
+	}
+
+	private void moveItem(TreeItem itemToMove, TreeItem parent) {
+		if (parent == null) {
+			if (tree.getItemCount() == 0) {
+				return;
+			}
+			parent = tree.getItem(0);
+		}
+		File parentFile = (File) parent.getData();
+		if (parentFile != null && !parentFile.isDirectory()) {
+			parent = parent.getParentItem();
+		}
+		TreeItem itemNew = new TreeItem(parent, 0);
+		for (int i = 0; i < tree.getColumnCount(); i++) {
+			itemNew.setText(i, itemToMove.getText(i));
+		}
+		File file = (File) itemToMove.getData();
+		itemNew.setData(file);
+		while (itemToMove.getItemCount() > 0) {
+			TreeItem subitemToMove = itemToMove.getItem(0);
+			moveItem(subitemToMove, itemNew);
+		}
+		itemToMove.dispose();
+	}
+
+	public IWizardPanel<NewTorrentWizard> getNextPanel() {
+		if (tree.getItemCount() == 1) {
+			// might be single file or single directory
+			TreeItem item = tree.getItem(0);
+			String name = item.getText();
+			File file = (File) item.getData();
+			if (file != null && file.getName().equals(name) && file.exists()) {
+				String	parent = file.getParent();
+        if ( parent != null ){
+        	((NewTorrentWizard) wizard).setDefaultOpenDir( parent );
+        }
+
+        if (file.isDirectory()) {
+					wizard.directoryPath = file.getAbsolutePath();
+					wizard.create_mode = wizard.MODE_DIRECTORY;
+					
+					return new SavePathPanel(wizard, this);
+				} else {
+					wizard.singlePath = file.getAbsolutePath();
+					wizard.create_mode = wizard.MODE_SINGLE_FILE;
+					return new SavePathPanel(wizard, this);
+				}
+			}
+		}
+		Map map = new HashMap();
+
+		List<Map> list = new ArrayList<Map>();
+
+		map.put("file_map", list);
+
+		buildList(list, tree.getItems());
+
+		wizard.byo_map = map;
+
+		try {
+			wizard.byo_desc_file = AETemporaryFileHandler.createTempFile();
+
+			FileUtil.writeBytesAsFile(wizard.byo_desc_file.getAbsolutePath(),
+					BEncoder.encode(map));
+
+		} catch (Throwable e) {
+
+			Debug.out(e);
+		}
+
+		return new SavePathPanel(wizard, this);
+	}
+
+	private void buildList(List list, TreeItem[] items) {
+		for (TreeItem treeItem : items) {
+			if (treeItem == null || treeItem.isDisposed()) {
+				continue;
+			}
+
+			TreeItem[] subItems = treeItem.getItems();
+			File file = (File) treeItem.getData();
+			if (file != null) {
+				Map m = new HashMap();
+
+				list.add(m);
+				
+				List<String> path = new ArrayList<String>();
+				do {
+					path.add(0, treeItem.getText());
+					treeItem = treeItem.getParentItem();
+				} while (treeItem != null);
+				
+
+				m.put("logical_path", path);
+				m.put("target", file.getAbsolutePath());
+			}
+			if (subItems.length > 0) {
+				buildList(list, subItems);
+			}
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/DirectoryPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/DirectoryPanel.java
index 558d9e7..15ecce7 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/DirectoryPanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/DirectoryPanel.java
@@ -43,11 +43,11 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
  * @author Olivier
  *  
  */
-public class DirectoryPanel extends AbstractWizardPanel {
+public class DirectoryPanel extends AbstractWizardPanel<NewTorrentWizard> {
 
   private Text file;
 
-  public DirectoryPanel(NewTorrentWizard wizard, IWizardPanel previous) {
+  public DirectoryPanel(NewTorrentWizard wizard, IWizardPanel<NewTorrentWizard> previous) {
     super(wizard, previous);
   }
 
@@ -90,10 +90,10 @@ public class DirectoryPanel extends AbstractWizardPanel {
           }
         }
         wizard.setErrorMessage(error);
-        wizard.setNextEnabled(!((NewTorrentWizard) wizard).directoryPath.equals("") && error.equals(""));
+        wizard.setNextEnabled(! wizard.directoryPath.equals("") && error.equals(""));
       }
     });
-    file.setText(((NewTorrentWizard) wizard).directoryPath);
+    file.setText( wizard.directoryPath);
     GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
     file.setLayoutData(gridData);
     Button browse = new Button(panel, SWT.PUSH);
@@ -105,10 +105,10 @@ public class DirectoryPanel extends AbstractWizardPanel {
 			 */
       public void handleEvent(Event arg0) {
         DirectoryDialog fd = new DirectoryDialog(wizard.getWizardWindow());
-        if (wizard.getErrorMessage().equals("") && !((NewTorrentWizard) wizard).directoryPath.equals("")) {
-          fd.setFilterPath(((NewTorrentWizard) wizard).directoryPath);
+        if (wizard.getErrorMessage().equals("") && !wizard.directoryPath.equals("")) {
+          fd.setFilterPath( wizard.directoryPath);
         }else{
-        	String	def = ((NewTorrentWizard) wizard).getDefaultOpenDir();
+        	String	def = wizard.getDefaultOpenDir();
         	
         	if ( def.length() > 0 ){
         		
@@ -125,7 +125,7 @@ public class DirectoryPanel extends AbstractWizardPanel {
           
           if ( parent != null ){
           	
-          	((NewTorrentWizard) wizard).setDefaultOpenDir( parent );
+          	wizard.setDefaultOpenDir( parent );
           }
         }
       }
@@ -151,9 +151,9 @@ public class DirectoryPanel extends AbstractWizardPanel {
 	 * 
 	 * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#getNextPanel()
 	 */
-  public IWizardPanel getNextPanel() {
+  public IWizardPanel<NewTorrentWizard> getNextPanel() {
     // TODO Auto-generated method stub
-    return new SavePathPanel(((NewTorrentWizard) wizard), this);
+    return new SavePathPanel(wizard, this);
   }
 
   public void setFilename(String filename) {
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java b/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
index e773eff..e122f26 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/ModePanel.java
@@ -46,10 +46,8 @@ import java.util.List;
  * @author Olivier
  *  
  */
-public class ModePanel extends AbstractWizardPanel {
+public class ModePanel extends AbstractWizardPanel<NewTorrentWizard> {
 
-  private Button bSingle;
-  private Button bDirectory;
   private Combo tracker;
 
   public ModePanel(NewTorrentWizard wizard, AbstractWizardPanel previous) {
@@ -274,7 +272,7 @@ public class ModePanel extends AbstractWizardPanel {
     final Button btnMultiTracker = new Button(panel,SWT.CHECK);
     Messages.setLanguageText(btnMultiTracker, "wizard.multitracker");
     gridData = new GridData();
-    gridData.horizontalSpan = 2;
+    gridData.horizontalSpan = 4;
     btnMultiTracker.setLayoutData(gridData);
     btnMultiTracker.addListener(SWT.Selection, new Listener() {
 
@@ -289,7 +287,7 @@ public class ModePanel extends AbstractWizardPanel {
     final Button btnWebSeed = new Button(panel,SWT.CHECK);
     Messages.setLanguageText(btnWebSeed, "wizard.webseed");
     gridData = new GridData();
-    gridData.horizontalSpan = 2;
+    gridData.horizontalSpan = 4;
     btnWebSeed.setLayoutData(gridData);
     btnWebSeed.addListener(SWT.Selection, new Listener() {
 
@@ -321,7 +319,7 @@ public class ModePanel extends AbstractWizardPanel {
     gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER | GridData.FILL_HORIZONTAL);
     panel.setLayoutData(gridData);
     layout = new GridLayout();
-    layout.numColumns = 4;
+    layout.numColumns = 6;
     panel.setLayout(layout);
 
     //Line:
@@ -329,37 +327,11 @@ public class ModePanel extends AbstractWizardPanel {
     
     Label label1 = new Label(panel, SWT.SEPARATOR | SWT.HORIZONTAL);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 4;
+    gridData.horizontalSpan = 6;
     label1.setLayoutData(gridData);
 
-    //Line:
-    // O single file O Directory mode
-    bSingle = new Button(panel, SWT.RADIO);
-    bSingle.setSelection(!((NewTorrentWizard) wizard).create_from_dir);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 2;
-    bSingle.setLayoutData(gridData);
-    Messages.setLanguageText(bSingle, "wizard.singlefile");
+    activateMode(NewTorrentWizard.MODE_BYO);
     
-    bSingle.addListener(SWT.Selection, new Listener() {
-      public void handleEvent(Event arg0) {
-        activateMode(true);
-      }
-    });
-    
-    bDirectory = new Button(panel, SWT.RADIO);
-    bDirectory.setSelection(((NewTorrentWizard) wizard).create_from_dir);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 2;
-    bDirectory.setLayoutData(gridData);
-    Messages.setLanguageText(bDirectory, "wizard.directory");
-    
-    bDirectory.addListener(SWT.Selection, new Listener() {
-      public void handleEvent(Event arg0) {
-        activateMode(false);
-      }
-    });
-
     btnSSL.addListener(SWT.Selection, new Listener() {
 		  public void handleEvent(Event arg0) {
 		  	String	url;
@@ -430,13 +402,6 @@ public class ModePanel extends AbstractWizardPanel {
         }
       });
     
-    //Line:
-    // ------------------------------
-    
-    label = new Label(panel, SWT.SEPARATOR | SWT.HORIZONTAL);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 4;
-    label.setLayoutData(gridData);
 
     //Line:
     //Comment: [               ]
@@ -445,7 +410,7 @@ public class ModePanel extends AbstractWizardPanel {
 
     final Text comment = new Text(panel, SWT.BORDER);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 3;
+    gridData.horizontalSpan = 5;
     comment.setLayoutData(gridData);
     comment.setText(((NewTorrentWizard) wizard).getComment());
 
@@ -454,19 +419,6 @@ public class ModePanel extends AbstractWizardPanel {
         ((NewTorrentWizard) wizard).setComment(comment.getText());
       }
     });
-
-    label = new Label(panel, SWT.NULL);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 4;
-    label.setLayoutData(gridData);
-    label.setText("\n");
-
-    label = new Label(panel, SWT.NULL);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 4;
-    label.setLayoutData(gridData);
-    label.setForeground(Colors.blue);
-    Messages.setLanguageText(label, "wizard.hint.mode");
   }
 
   /*
@@ -474,30 +426,27 @@ public class ModePanel extends AbstractWizardPanel {
 	 * 
 	 * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#getNextPanel()
 	 */
-  public IWizardPanel getNextPanel() {
+  public IWizardPanel<NewTorrentWizard> getNextPanel() {
     
     //OSX work-arround to Fix SWT BUG #43396 :
     //Combo doesn't fire Selection Event
     if(Constants.isOSX) {
       //In case we're not using the localTracker, refresh the
       //Tracker URL from the Combo text
-      if( ((NewTorrentWizard) wizard).getTrackerType() == NewTorrentWizard.TT_EXTERNAL ){
+      if( wizard.getTrackerType() == NewTorrentWizard.TT_EXTERNAL ){
         setTrackerUrl(tracker.getText());
       }
     }
     
+    if( wizard.useMultiTracker){
+      return new MultiTrackerPanel( wizard, this);
+    }
     
-    if(((NewTorrentWizard) wizard).useMultiTracker)
-      return new MultiTrackerPanel((NewTorrentWizard) wizard, this);
-
-    if(((NewTorrentWizard) wizard).useWebSeed)
-        return new WebSeedPanel((NewTorrentWizard) wizard, this);
-
-    if (((NewTorrentWizard) wizard).create_from_dir) {
-      return new DirectoryPanel(((NewTorrentWizard) wizard), this);
-    } else {
-      return new SingleFilePanel(((NewTorrentWizard) wizard), this);
+    if(  wizard.useWebSeed ){
+        return new WebSeedPanel( wizard, this);
     }
+    
+    return( wizard.getNextPanelForMode( this ));
   }
 
   /*
@@ -509,11 +458,9 @@ public class ModePanel extends AbstractWizardPanel {
     return true;
   }
 
-  void activateMode(boolean singleFile) {
-    wizard.setCurrentInfo(MessageText.getString(singleFile ? "wizard.singlefile.help" : "wizard.directory.help"));
-    ((NewTorrentWizard) wizard).create_from_dir = !singleFile;
-    bDirectory.setSelection(!singleFile);
-    bSingle.setSelection(singleFile);
+  void activateMode(int mode) {
+    wizard.setCurrentInfo(MessageText.getString(mode==NewTorrentWizard.MODE_SINGLE_FILE?"wizard.singlefile.help" :(mode==NewTorrentWizard.MODE_DIRECTORY?"wizard.directory.help":"wizard.newtorrent.byo.help")));
+    ((NewTorrentWizard) wizard).create_mode = mode;
   }
 
   void updateTrackerURL() {
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerEditor.java b/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerEditor.java
index bcef598..f9cba0e 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerEditor.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerEditor.java
@@ -28,8 +28,11 @@ import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
+import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.TextViewerWindow;
 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 java.net.URL;
@@ -50,7 +53,6 @@ public class MultiTrackerEditor {
   
   List trackers;
   
-  Display display;
   Shell shell;    
   Text textName;
   Tree treeGroups;
@@ -61,12 +63,13 @@ public class MultiTrackerEditor {
   
   Menu menu;
   
-  public MultiTrackerEditor(String name,List trackers,TrackerEditorListener listener) {
-  	this( name, trackers, listener, false );
+  public MultiTrackerEditor(Shell parent_shell, String name,List trackers,TrackerEditorListener listener) {
+  	this( parent_shell, name, trackers, listener, false );
   }
   
   public 
   MultiTrackerEditor(
+		Shell 					parent_shell,
   		String 					name,
 		List 					trackers,
 		TrackerEditorListener 	listener,
@@ -80,13 +83,17 @@ public class MultiTrackerEditor {
     this.listener = listener;
     anonymous = _anonymous;
     this.trackers = new ArrayList(trackers);
-    createWindow();
+    createWindow( parent_shell );
     
   }
   
-  private void createWindow() {
-    this.display = Display.getCurrent();
-    this.shell = org.gudy.azureus2.ui.swt.components.shell.ShellFactory.createShell(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
+  private void createWindow( Shell parent_shell) {
+	if ( parent_shell == null ){
+		this.shell = ShellFactory.createMainShell(SWT.DIALOG_TRIM | SWT.RESIZE);
+	}else{
+		this.shell = ShellFactory.createShell(parent_shell,SWT.DIALOG_TRIM | SWT.RESIZE);
+	}
+	
     Messages.setLanguageText(this.shell,"wizard.multitracker.edit.title");
     Utils.setShellIcon(shell);
     GridLayout layout = new GridLayout();
@@ -148,8 +155,70 @@ public class MultiTrackerEditor {
     gridData.horizontalSpan = 3;
     cButtons.setLayoutData(gridData);
     GridLayout layoutButtons = new GridLayout();
-    layoutButtons.numColumns = 3;
+    layoutButtons.numColumns = 4;
     cButtons.setLayout(layoutButtons);
+    
+    Button btnedittext = new Button(cButtons,SWT.PUSH);
+    gridData = new GridData();
+    gridData.widthHint = 70;
+    gridData.horizontalAlignment = GridData.END;
+    btnedittext.setLayoutData(gridData);
+    Messages.setLanguageText(btnedittext,"wizard.multitracker.edit.text");
+    btnedittext.addListener(SWT.Selection, new Listener() {
+      public void handleEvent(Event e) {
+ 
+    	  final String	old_text = TorrentUtils.announceGroupsToText( trackers );
+    	  
+    	  final TextViewerWindow viewer =
+    		  new TextViewerWindow(
+    				  "wizard.multitracker.edit.text.title", 
+    				  "wizard.multitracker.edit.text.msg", 
+    				  old_text, true, true );
+
+    	  viewer.setEditable( true );
+			
+    	  viewer.addListener(
+				new TextViewerWindow.TextViewerWindowListener()
+				{
+					public void 
+					closed() 
+					{
+				    	  String new_text = viewer.getText();
+				    	  
+				    	  if ( !old_text.equals( new_text )){
+				    		  
+				    		  String[] lines = new_text.split( "\n" );
+				    		  
+				    		  StringBuffer valid_text = new StringBuffer( new_text.length()+1 );
+				    		  
+				    		  for ( String line: lines ){
+				    			  
+				    			  line = line.trim();
+				    			  
+				    			  if ( line.length() > 0 ){
+				    				  
+				    				  if ( !validURL( line )){
+				    					  
+				    					  continue;
+				    				  }
+				    			  }
+				    			  
+				    			  valid_text.append( line );
+				    			  valid_text.append( "\n" );
+				    		  }
+				    		  
+				    		  trackers = TorrentUtils.announceTextToGroups( valid_text.toString());
+				    		  
+				    		  refresh();
+				    	  }
+					}
+				});
+    	  
+    	  viewer.goModal();
+
+      }
+    });
+    
     Label label = new Label(cButtons,SWT.NULL);
     gridData = new GridData(GridData.FILL_HORIZONTAL );
     label.setLayoutData(gridData);
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerPanel.java
index a7428aa..c3c7c28 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerPanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/MultiTrackerPanel.java
@@ -45,7 +45,7 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
  * @author Olivier
  *  
  */
-public class MultiTrackerPanel extends AbstractWizardPanel implements TrackerEditorListener{
+public class MultiTrackerPanel extends AbstractWizardPanel<NewTorrentWizard> implements TrackerEditorListener{
 
   private Combo configList;
   private Tree configDetails;
@@ -54,7 +54,7 @@ public class MultiTrackerPanel extends AbstractWizardPanel implements TrackerEdi
   private Button btnEdit;
   private Button btnDelete; 
 
-  public MultiTrackerPanel(NewTorrentWizard wizard, AbstractWizardPanel previous) {
+  public MultiTrackerPanel(NewTorrentWizard wizard, AbstractWizardPanel<NewTorrentWizard> previous) {
     super(wizard, previous);
   }
 
@@ -109,7 +109,7 @@ public class MultiTrackerPanel extends AbstractWizardPanel implements TrackerEdi
         List tracker = new ArrayList();
         tracker.add(((NewTorrentWizard)wizard).trackerURL);
         group.add(tracker);
-        new MultiTrackerEditor(null,group,MultiTrackerPanel.this);
+        new MultiTrackerEditor(wizard.getWizardWindow(), null,group,MultiTrackerPanel.this);
       }
     });
     
@@ -123,7 +123,7 @@ public class MultiTrackerPanel extends AbstractWizardPanel implements TrackerEdi
         int selection = configList.getSelectionIndex();
         String selected = configList.getItem(selection);
         Map multiTrackers = TrackersUtil.getInstance().getMultiTrackers();
-        new MultiTrackerEditor(selected,(List)multiTrackers.get(selected),MultiTrackerPanel.this);
+        new MultiTrackerEditor( wizard.getWizardWindow(),selected,(List)multiTrackers.get(selected),MultiTrackerPanel.this);
       }
     });
     
@@ -165,14 +165,11 @@ public class MultiTrackerPanel extends AbstractWizardPanel implements TrackerEdi
 	 */
   public IWizardPanel getNextPanel() {
 	  
-	if(((NewTorrentWizard) wizard).useWebSeed)
+	if(((NewTorrentWizard) wizard).useWebSeed){
 	     return new WebSeedPanel((NewTorrentWizard) wizard, this);
-	   
-    if (((NewTorrentWizard) wizard).create_from_dir) {
-      return new DirectoryPanel(((NewTorrentWizard) wizard), this);
-    } else {
-      return new SingleFilePanel(((NewTorrentWizard) wizard), this);
-    }
+	}
+	
+	return(((NewTorrentWizard)wizard).getNextPanelForMode( this ));
   }
 
 
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/NewTorrentWizard.java b/org/gudy/azureus2/ui/swt/maketorrent/NewTorrentWizard.java
index 05ce787..18f7917 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/NewTorrentWizard.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/NewTorrentWizard.java
@@ -29,9 +29,13 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.torrent.TOTorrentCreator;
+import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.ui.swt.URLTransfer;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
+import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.Wizard;
 
 /**
@@ -64,11 +68,17 @@ NewTorrentWizard
 	}
 	
   //false : singleMode, true: directory
-  boolean create_from_dir;
+	 protected static final int MODE_SINGLE_FILE	= 1;
+	 protected static final int MODE_DIRECTORY		= 2;
+	 protected static final int MODE_BYO			= 3;
+  
+  int create_mode = MODE_BYO;
   String singlePath = "";
   String directoryPath = "";
   String savePath = "";
   
+  File	byo_desc_file;
+  Map	byo_map;
     
   String trackerURL = TT_EXTERNAL_DEFAULT;
   
@@ -107,7 +117,7 @@ NewTorrentWizard
     });
     
     trackers.add(new ArrayList());
-    trackerURL = Utils.getLinkFromClipboard(display,false);
+    trackerURL = Utils.getLinkFromClipboard(display,false,false);
     ModePanel panel = new ModePanel(this, null);
     createDropTarget(getWizardWindow());
     this.setFirstPanel(panel);
@@ -180,30 +190,31 @@ NewTorrentWizard
       public void drop(DropTargetEvent event) {
         if (event.data instanceof String[]) {
           String[] sourceNames = (String[]) event.data;
-          if (sourceNames == null || sourceNames.length != 1)
+          if (sourceNames == null )
             event.detail = DND.DROP_NONE;
           if (event.detail == DND.DROP_NONE)
             return;
-          File droppedFile = new File(sourceNames[0]);
-          if (getCurrentPanel() instanceof ModePanel) {
-            if (droppedFile.isFile()) {
-              singlePath = droppedFile.getAbsolutePath();
-              ((ModePanel) getCurrentPanel()).activateMode(true);
-            } else if (droppedFile.isDirectory()) {
-              directoryPath = droppedFile.getAbsolutePath();
-              ((ModePanel) getCurrentPanel()).activateMode(false);
-            }
-          } else if (getCurrentPanel() instanceof DirectoryPanel) {
-            if (droppedFile.isDirectory())
-              ((DirectoryPanel) getCurrentPanel()).setFilename(droppedFile.getAbsolutePath());
-          } else if (getCurrentPanel() instanceof SingleFilePanel) {
-            if (droppedFile.isFile())
-              ((SingleFilePanel) getCurrentPanel()).setFilename(droppedFile.getAbsolutePath());
+          
+          for ( String droppedFileStr: sourceNames ){
+        	  File droppedFile = new File( droppedFileStr );
+	          if (getCurrentPanel() instanceof ModePanel) {
+	          } else if (getCurrentPanel() instanceof DirectoryPanel) {
+	            if (droppedFile.isDirectory())
+	              ((DirectoryPanel) getCurrentPanel()).setFilename(droppedFile.getAbsolutePath());
+	          } else if (getCurrentPanel() instanceof SingleFilePanel) {
+	            if (droppedFile.isFile())
+	              ((SingleFilePanel) getCurrentPanel()).setFilename(droppedFile.getAbsolutePath());
+	          } else if (getCurrentPanel() instanceof BYOPanel) {
+	        	  ((BYOPanel) getCurrentPanel()).addFilename(droppedFile);
+	        	  
+	        	  continue;
+	          }
+	          break;
           }
-         } else if (getCurrentPanel() instanceof ModePanel) {
-           trackerURL = ((URLTransfer.URLType)event.data).linkURL;
-           ((ModePanel) getCurrentPanel()).updateTrackerURL();
-         }
+        } else if (getCurrentPanel() instanceof ModePanel) {
+        	trackerURL = ((URLTransfer.URLType)event.data).linkURL;
+        	((ModePanel) getCurrentPanel()).updateTrackerURL();
+        }
        }
     });
   }
@@ -249,4 +260,18 @@ NewTorrentWizard
   {
   	return( addOtherHashes );
   }
+  
+  protected IWizardPanel<NewTorrentWizard>
+  getNextPanelForMode(
+	  AbstractWizardPanel<NewTorrentWizard>		prev )
+  {
+	  switch( create_mode ){
+	  	case MODE_DIRECTORY:
+		  return new DirectoryPanel( this, prev);
+	  	case MODE_SINGLE_FILE:
+		  return new SingleFilePanel( this, prev );
+		default:
+		  return new BYOPanel( this, prev );  
+	  }
+  }
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/ProgressPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/ProgressPanel.java
index e90217e..e6020c2 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/ProgressPanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/ProgressPanel.java
@@ -53,14 +53,14 @@ import com.aelitis.azureus.core.AzureusCoreRunningListener;
  * @author Olivier
  * 
  */
-public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgressListener {
+public class ProgressPanel extends AbstractWizardPanel<NewTorrentWizard> implements TOTorrentProgressListener {
 
   Text tasks;
   ProgressBar progress;
   Display display;
 
-  public ProgressPanel(NewTorrentWizard _wizard, IWizardPanel _previousPanel) {
-    super(_wizard, _previousPanel);
+  public ProgressPanel(NewTorrentWizard wizard, IWizardPanel<NewTorrentWizard> _previousPanel) {
+    super(wizard, _previousPanel);
   }
   /* (non-Javadoc)
    * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#show()
@@ -110,47 +110,51 @@ public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgr
   }
   
   public void makeTorrent() {
-  	final NewTorrentWizard _wizard = (NewTorrentWizard)wizard;
   	
-  	int	tracker_type = _wizard.getTrackerType();
+  	int	tracker_type = wizard.getTrackerType();
   	
     if( tracker_type == NewTorrentWizard.TT_EXTERNAL ){
     	
-      TrackersUtil.getInstance().addTracker(_wizard.trackerURL);
+      TrackersUtil.getInstance().addTracker(wizard.trackerURL);
     }
     
     File f;
     
-    if (_wizard.create_from_dir) {
-      f = new File(_wizard.directoryPath);
-    }
-    else {
-      f = new File(_wizard.singlePath);
+    if ( wizard.create_mode == NewTorrentWizard.MODE_DIRECTORY ){
+      f = new File(wizard.directoryPath);
+    }else if ( wizard.create_mode == NewTorrentWizard.MODE_SINGLE_FILE ){
+      f = new File(wizard.singlePath);
+    }else{
+      f = wizard.byo_desc_file;
     }
 
     try {
-      URL url = new URL(_wizard.trackerURL);
+      URL url = new URL(wizard.trackerURL);
       
       final TOTorrent torrent;
       
-      if ( _wizard.getPieceSizeComputed()){
+      if ( wizard.getPieceSizeComputed()){
       	
-        _wizard.creator = 
+        wizard.creator = 
       		TOTorrentFactory.createFromFileOrDirWithComputedPieceLength(
-      					f, url, _wizard.getAddOtherHashes());
+      					f, url, wizard.getAddOtherHashes());
       	
-        _wizard.creator.addListener( this );
+        wizard.creator.addListener( this );
       	
-      	torrent = _wizard.creator.create();
+        wizard.creator.setFileIsLayoutDescriptor( wizard.create_mode == NewTorrentWizard.MODE_BYO );
+        
+      	torrent = wizard.creator.create();
       	
       }else{
-      	TOTorrentCreator c = 
+    	wizard.creator = 
       		TOTorrentFactory.createFromFileOrDirWithFixedPieceLength(
-      					f, url, _wizard.getAddOtherHashes(), _wizard.getPieceSizeManual());
+      					f, url, wizard.getAddOtherHashes(), wizard.getPieceSizeManual());
       	
-    	c.addListener( this );
+    	wizard.creator.addListener( this );
       	
-      	torrent = c.create();
+        wizard.creator.setFileIsLayoutDescriptor( wizard.create_mode == NewTorrentWizard.MODE_BYO );
+
+      	torrent = wizard.creator.create();
       }
       
       if ( tracker_type == NewTorrentWizard.TT_DECENTRAL ){
@@ -158,11 +162,11 @@ public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgr
       	TorrentUtils.setDecentralised( torrent );
       }
 	  
-      torrent.setComment(_wizard.getComment());
+      torrent.setComment(wizard.getComment());
  
-      TorrentUtils.setDHTBackupEnabled( torrent, _wizard.permitDHT );
+      TorrentUtils.setDHTBackupEnabled( torrent, wizard.permitDHT );
 	  
-      TorrentUtils.setPrivate( torrent, _wizard.privateTorrent );
+      TorrentUtils.setPrivate( torrent, wizard.privateTorrent );
       
       LocaleTorrentUtil.setDefaultTorrentEncoding( torrent );
       
@@ -170,24 +174,37 @@ public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgr
       
       final File save_dir;
       
-      if (_wizard.create_from_dir){
+      if ( wizard.create_mode == NewTorrentWizard.MODE_DIRECTORY ){
       	
       	save_dir = f;
       	
-      }else{
+      }else if ( wizard.create_mode == NewTorrentWizard.MODE_SINGLE_FILE ){
       	
       	save_dir = f.getParentFile();
+      	
+      }else{
+    	  
+    	  String save_path = COConfigurationManager.getStringParameter( "Default save path" );
+    	  
+    	  File f_save_path = new File( save_path );
+    	  
+    	  if ( !f_save_path.canWrite()){
+    		  
+    		  throw( new Exception( "Default save path is not configured: See Tools->Options->File" ));
+    	  }
+    	  
+    	  save_dir = f_save_path;
       }
       
-      if(_wizard.useMultiTracker) {
+      if( wizard.useMultiTracker ){
           this.reportCurrentTask(MessageText.getString("wizard.addingmt"));
-          TorrentUtils.listToAnnounceGroups(_wizard.trackers, torrent);
-         }
+          TorrentUtils.listToAnnounceGroups(wizard.trackers, torrent);
+      }
 
-      if (_wizard.useWebSeed && _wizard.webseeds.size() > 0 ){
+      if (wizard.useWebSeed && wizard.webseeds.size() > 0 ){
           this.reportCurrentTask(MessageText.getString("wizard.webseed.adding"));
           
-          Map	ws = _wizard.webseeds;
+          Map	ws = wizard.webseeds;
           
           List	getright = (List)ws.get( "getright" );
           
@@ -227,13 +244,13 @@ public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgr
       
       this.reportCurrentTask(MessageText.getString("wizard.savingfile"));
       
-      final File torrent_file = new File(_wizard.savePath);
+      final File torrent_file = new File(wizard.savePath);
       
       torrent.serialiseToBEncodedFile(torrent_file);
       this.reportCurrentTask(MessageText.getString("wizard.filesaved"));
 	  wizard.switchToClose();
 	  
-	  if ( _wizard.autoOpen ){
+	  if ( wizard.autoOpen ){
 	  	CoreWaiterSWT.waitForCore(TriggerInThread.NEW_THREAD,
 						new AzureusCoreRunningListener() {
 							public void azureusCoreRunning(AzureusCore core) {
@@ -265,8 +282,8 @@ public class ProgressPanel extends AbstractWizardPanel implements TOTorrentProgr
 									});
 								}
 
-								if (_wizard.autoHost
-										&& _wizard.getTrackerType() != NewTorrentWizard.TT_EXTERNAL) {
+								if (wizard.autoHost
+										&& wizard.getTrackerType() != NewTorrentWizard.TT_EXTERNAL) {
 
 									try {
 										core.getTrackerHost().hostTorrent(torrent, true, false);
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/SavePathPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/SavePathPanel.java
index 5cca741..ffa2736 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/SavePathPanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/SavePathPanel.java
@@ -21,12 +21,16 @@
  
 package org.gudy.azureus2.ui.swt.maketorrent;
 
+import java.io.File;
+import java.util.Map;
+
 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.*;
+import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.torrent.TOTorrentFactory;
 import org.gudy.azureus2.core3.util.Debug;
@@ -35,32 +39,31 @@ import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 
-import java.io.File;
-
 /**
  * @author Olivier
  * 
  */
-public class SavePathPanel extends AbstractWizardPanel {
+public class SavePathPanel extends AbstractWizardPanel<NewTorrentWizard> {
 
 	protected long	file_size;
 	protected long	piece_size;
 	protected long	piece_count;	
 
-  public SavePathPanel(NewTorrentWizard _wizard,AbstractWizardPanel _previousPanel) {
-    super(_wizard,_previousPanel);
+  public SavePathPanel(NewTorrentWizard wizard,AbstractWizardPanel<NewTorrentWizard> _previousPanel) {
+    super(wizard,_previousPanel);
   }
   
   /* (non-Javadoc)
    * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#show()
    */
   public void show() {
-  	
-  	final NewTorrentWizard _wizard = (NewTorrentWizard)wizard;
-  	
+  	  	
   	try{
-  		file_size = TOTorrentFactory.getTorrentDataSizeFromFileOrDir(new File(_wizard.create_from_dir?_wizard.directoryPath:_wizard.singlePath));
-  		
+  		if (wizard.create_mode == NewTorrentWizard.MODE_BYO ){
+  			file_size = TOTorrentFactory.getTorrentDataSizeFromFileOrDir( wizard.byo_desc_file, true );
+  		}else{
+  			file_size = TOTorrentFactory.getTorrentDataSizeFromFileOrDir( new File( wizard.create_mode==NewTorrentWizard.MODE_DIRECTORY? wizard.directoryPath: wizard.singlePath), false );
+  		}
   		piece_size = TOTorrentFactory.getComputedPieceSize( file_size );
   		
   		piece_count = TOTorrentFactory.getPieceCount( file_size, piece_size );
@@ -83,7 +86,7 @@ public class SavePathPanel extends AbstractWizardPanel {
        */
       public void modifyText(ModifyEvent arg0) {       
         String fName = file.getText();
-        ((NewTorrentWizard)wizard).savePath = fName;
+        wizard.savePath = fName;
         String error = "";
         if(! fName.equals("")) {          
           File f = new File(file.getText());
@@ -94,28 +97,50 @@ public class SavePathPanel extends AbstractWizardPanel {
             
             if ( parent != null ){
             	
-            	((NewTorrentWizard) wizard).setDefaultSaveDir( parent );
+            	wizard.setDefaultSaveDir( parent );
             }
           }
         }
         wizard.setErrorMessage(error);
-        wizard.setFinishEnabled(!((NewTorrentWizard)wizard).savePath.equals("") && error.equals(""));
+        wizard.setFinishEnabled(!wizard.savePath.equals("") && error.equals(""));
       }
     });
     
+    String	default_save = wizard.getDefaultSaveDir();
+
     	// if we have a default save dir then use this as the basis for save location
     
     String	target_file;
     
-    if(((NewTorrentWizard)wizard).create_from_dir) {
-    	target_file = ((NewTorrentWizard)wizard).directoryPath + ".torrent";
-    } else {      
-    	target_file = ((NewTorrentWizard)wizard).singlePath + ".torrent";
+    if( wizard.create_mode == NewTorrentWizard.MODE_BYO ){
+    	target_file = "";
+    	
+    	if (wizard.byo_map != null) {
+    		java.util.List list = (java.util.List) wizard.byo_map.get("file_map");
+    		if (list != null) {
+    			Map map = (Map) list.get(0);
+    			if (map != null) {
+    				java.util.List path = (java.util.List) map.get("logical_path");
+    				if (path != null) {
+							target_file = new File(
+									COConfigurationManager.getStringParameter("General_sDefaultTorrent_Directory"),
+									(String) path.get(0) + ".torrent").getAbsolutePath();
+    				}
+    			}
+    		}
+    	}
+    	
+    }else if ( wizard.create_mode == NewTorrentWizard.MODE_DIRECTORY ){ 
+    		
+    	target_file = wizard.directoryPath + ".torrent";
+    	
+    }else{
+    	
+    	target_file = wizard.singlePath + ".torrent";
     }
     
-    String	default_save = ((NewTorrentWizard)wizard).getDefaultSaveDir();
     
-    if (default_save.length() > 0 ){
+    if ( default_save.length() > 0 && target_file.length() > 0 ){
     
     	File temp = new File( target_file );
     	
@@ -127,9 +152,9 @@ public class SavePathPanel extends AbstractWizardPanel {
     	}
     }
     
-    ((NewTorrentWizard)wizard).savePath = target_file;
+    wizard.savePath = target_file;
     
-    file.setText(((NewTorrentWizard)wizard).savePath);
+    file.setText( wizard.savePath);
     GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
     gridData.horizontalSpan = 2;
     file.setLayoutData(gridData);
@@ -140,7 +165,7 @@ public class SavePathPanel extends AbstractWizardPanel {
        */
       public void handleEvent(Event arg0) {
         FileDialog fd = new FileDialog(wizard.getWizardWindow(),SWT.SAVE);
-        final String path = ((NewTorrentWizard)wizard).savePath;
+        final String path = wizard.savePath;
         if(wizard.getErrorMessage().equals("") && !path.equals("")) {
             File fsPath = new File(path);
             if(!path.endsWith(File.separator)) {
@@ -159,8 +184,9 @@ public class SavePathPanel extends AbstractWizardPanel {
 
             String	parent = ff.getParent();
 
-            if ( parent != null )
-                ((NewTorrentWizard) wizard).setDefaultSaveDir( parent );
+            if ( parent != null ){
+                wizard.setDefaultSaveDir( parent );
+            }
           }
       }
     });   
@@ -234,14 +260,14 @@ public class SavePathPanel extends AbstractWizardPanel {
     		
     		if ( index == 0 ){
     			
-    			_wizard.setPieceSizeComputed();
+    			wizard.setPieceSizeComputed();
     			
     			piece_size = TOTorrentFactory.getComputedPieceSize( file_size );
     			
      		}else{
     			piece_size = sizes[index-1];
     			
-    			_wizard.setPieceSizeManual(piece_size);	
+    			wizard.setPieceSizeManual(piece_size);	
     		}
     		
     		piece_count = TOTorrentFactory.getPieceCount( file_size, piece_size );
@@ -274,15 +300,15 @@ public class SavePathPanel extends AbstractWizardPanel {
     
     bAutoOpen.addListener(SWT.Selection,new Listener() {
         public void handleEvent(Event event) {
-          _wizard.autoOpen = bAutoOpen.getSelection();
+          wizard.autoOpen = bAutoOpen.getSelection();
           
-          bAutoHost.setEnabled( _wizard.autoOpen && _wizard.getTrackerType() != NewTorrentWizard.TT_EXTERNAL );
+          bAutoHost.setEnabled( wizard.autoOpen && wizard.getTrackerType() != NewTorrentWizard.TT_EXTERNAL );
         }
       });
     
     bAutoHost.addListener(SWT.Selection,new Listener() {
       public void handleEvent(Event event) {
-        _wizard.autoHost = bAutoHost.getSelection();
+        wizard.autoHost = bAutoHost.getSelection();
       }
     });
     
@@ -302,33 +328,33 @@ public class SavePathPanel extends AbstractWizardPanel {
     
     bAllowDHT.addListener(SWT.Selection,new Listener() {
         public void handleEvent(Event event) {
-          _wizard.permitDHT = bAllowDHT.getSelection();
+          wizard.permitDHT = bAllowDHT.getSelection();
         }
       });
       
 	
 	bPrivateTorrent.addListener(SWT.Selection,new Listener() {
         public void handleEvent(Event event) {
-          _wizard.privateTorrent = bPrivateTorrent.getSelection();
+          wizard.privateTorrent = bPrivateTorrent.getSelection();
 		  
-          if ( _wizard.privateTorrent ){
+          if ( wizard.privateTorrent ){
         	  
         	  bAllowDHT.setSelection( false );
-        	  _wizard.permitDHT = false;
+        	  wizard.permitDHT = false;
           }
-		  bAllowDHT.setEnabled( !_wizard.privateTorrent );
+		  bAllowDHT.setEnabled( !wizard.privateTorrent );
         }
       });
 
-    if ( _wizard.getTrackerType() == NewTorrentWizard.TT_DECENTRAL ){
+    if ( wizard.getTrackerType() == NewTorrentWizard.TT_DECENTRAL ){
 
 		bAllowDHT.setEnabled( false );
 		bPrivateTorrent.setEnabled( false );
     }
   }
   
-  public IWizardPanel getFinishPanel() {
-    return new ProgressPanel((NewTorrentWizard)wizard,this);
+  public IWizardPanel<NewTorrentWizard> getFinishPanel() {
+    return new ProgressPanel( wizard, this );
   }
 
 }
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/SingleFilePanel.java b/org/gudy/azureus2/ui/swt/maketorrent/SingleFilePanel.java
index 998b6c1..75addd8 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/SingleFilePanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/SingleFilePanel.java
@@ -43,10 +43,10 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
  * @author Olivier
  *  
  */
-public class SingleFilePanel extends AbstractWizardPanel {
+public class SingleFilePanel extends AbstractWizardPanel<NewTorrentWizard> {
   private Text file;
 
-  public SingleFilePanel(NewTorrentWizard wizard, AbstractWizardPanel previous) {
+  public SingleFilePanel(NewTorrentWizard wizard, AbstractWizardPanel<NewTorrentWizard> previous) {
     super(wizard, previous);
   }
 
@@ -75,7 +75,7 @@ public class SingleFilePanel extends AbstractWizardPanel {
 			 */
       public void modifyText(ModifyEvent arg0) {
         String fName = file.getText();
-        ((NewTorrentWizard) wizard).singlePath = fName;
+        wizard.singlePath = fName;
         String error = "";
         if (!fName.equals("")) {
           File f = new File(file.getText());
@@ -86,12 +86,12 @@ public class SingleFilePanel extends AbstractWizardPanel {
             
             if ( parent != null ){
             	
-            	((NewTorrentWizard) wizard).setDefaultOpenDir( parent );
+            	wizard.setDefaultOpenDir( parent );
             }
           }
         }
         wizard.setErrorMessage(error);
-        wizard.setNextEnabled(!((NewTorrentWizard) wizard).singlePath.equals("") && error.equals(""));
+        wizard.setNextEnabled(!wizard.singlePath.equals("") && error.equals(""));
       }
     });
     file.setText(((NewTorrentWizard) wizard).singlePath);
@@ -107,10 +107,10 @@ public class SingleFilePanel extends AbstractWizardPanel {
 			 */
       public void handleEvent(Event arg0) {
         FileDialog fd = new FileDialog(wizard.getWizardWindow());
-        if (wizard.getErrorMessage().equals("") && !((NewTorrentWizard) wizard).singlePath.equals("")) {
-          fd.setFileName(((NewTorrentWizard) wizard).singlePath);
+        if (wizard.getErrorMessage().equals("") && !wizard.singlePath.equals("")) {
+          fd.setFileName(wizard.singlePath);
         }else{
-        	String	def = ((NewTorrentWizard) wizard).getDefaultOpenDir();
+        	String	def = wizard.getDefaultOpenDir();
         	
         	if ( def.length() > 0 & new File(def).isDirectory() ){
         		
@@ -127,7 +127,7 @@ public class SingleFilePanel extends AbstractWizardPanel {
             
             if ( parent != null ){
             	
-            	((NewTorrentWizard) wizard).setDefaultOpenDir( parent );
+            	wizard.setDefaultOpenDir( parent );
             }
           }
 
@@ -154,7 +154,7 @@ public class SingleFilePanel extends AbstractWizardPanel {
 	 * 
 	 * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#getNextPanel()
 	 */
-  public IWizardPanel getNextPanel() {
+  public IWizardPanel<NewTorrentWizard> getNextPanel() {
     // TODO Auto-generated method stub
     return new SavePathPanel(((NewTorrentWizard) wizard), this);
   }
diff --git a/org/gudy/azureus2/ui/swt/maketorrent/WebSeedPanel.java b/org/gudy/azureus2/ui/swt/maketorrent/WebSeedPanel.java
index dd35ec3..5795dcc 100644
--- a/org/gudy/azureus2/ui/swt/maketorrent/WebSeedPanel.java
+++ b/org/gudy/azureus2/ui/swt/maketorrent/WebSeedPanel.java
@@ -46,7 +46,7 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
  * @author Olivier
  *  
  */
-public class WebSeedPanel extends AbstractWizardPanel implements WebSeedsEditorListener{
+public class WebSeedPanel extends AbstractWizardPanel<NewTorrentWizard> implements WebSeedsEditorListener{
 
   private Combo configList;
   private Tree configDetails;
@@ -55,7 +55,7 @@ public class WebSeedPanel extends AbstractWizardPanel implements WebSeedsEditorL
   private Button btnEdit;
   private Button btnDelete; 
 
-  public WebSeedPanel(NewTorrentWizard wizard, AbstractWizardPanel previous) {
+  public WebSeedPanel(NewTorrentWizard wizard, AbstractWizardPanel<NewTorrentWizard> previous) {
     super(wizard, previous);
   }
 
@@ -153,7 +153,7 @@ public class WebSeedPanel extends AbstractWizardPanel implements WebSeedsEditorL
     gridData.horizontalSpan = 3;
     configDetails.setLayoutData(gridData);    
     
-    refreshList(((NewTorrentWizard)wizard).webSeedConfig);
+    refreshList( wizard.webSeedConfig);
     refreshDetails(); 
     setEditDeleteEnable();
 }
@@ -163,12 +163,8 @@ public class WebSeedPanel extends AbstractWizardPanel implements WebSeedsEditorL
 	 * 
 	 * @see org.gudy.azureus2.ui.swt.maketorrent.IWizardPanel#getNextPanel()
 	 */
-  public IWizardPanel getNextPanel() {
-    if (((NewTorrentWizard) wizard).create_from_dir) {
-      return new DirectoryPanel(((NewTorrentWizard) wizard), this);
-    } else {
-      return new SingleFilePanel(((NewTorrentWizard) wizard), this);
-    }
+  public IWizardPanel<NewTorrentWizard> getNextPanel() {
+	  return( wizard.getNextPanelForMode( this ));
   }
 
 
@@ -178,7 +174,7 @@ public class WebSeedPanel extends AbstractWizardPanel implements WebSeedsEditorL
   
   void refreshDetails() {
     configDetails.removeAll();
-    Map webseeds = ((NewTorrentWizard) wizard).webseeds;
+    Map webseeds = wizard.webseeds;
     Iterator iter = webseeds.entrySet().iterator();
     while(iter.hasNext()) {
         Map.Entry	entry = (Map.Entry)iter.next();
diff --git a/org/gudy/azureus2/ui/swt/minibar/AllTransfersBar.java b/org/gudy/azureus2/ui/swt/minibar/AllTransfersBar.java
index 4649b13..977bae3 100644
--- a/org/gudy/azureus2/ui/swt/minibar/AllTransfersBar.java
+++ b/org/gudy/azureus2/ui/swt/minibar/AllTransfersBar.java
@@ -20,6 +20,8 @@
  */
 package org.gudy.azureus2.ui.swt.minibar;
 
+import java.util.List;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
@@ -30,12 +32,19 @@ import org.eclipse.swt.events.MenuEvent;
 import org.eclipse.swt.graphics.Point;
 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.global.GlobalManager;
 import org.gudy.azureus2.core3.global.GlobalManagerStats;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.DoubleBufferedLabel;
+import org.gudy.azureus2.ui.swt.mainwindow.SelectableSpeedMenu;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
+import com.aelitis.azureus.core.AzureusCoreFactory;
+
 /**
  * @author Allan Crooks
  *
@@ -69,8 +78,9 @@ public class AllTransfersBar extends MiniBar {
 	}
 	
 	private GlobalManager g_manager;
-	private Label down_speed;
-	private Label up_speed;
+	private DoubleBufferedLabel down_speed;
+	private DoubleBufferedLabel up_speed;
+	private DoubleBufferedLabel next_eta;
 	
 	private AllTransfersBar(GlobalManager gmanager, Shell main) {
 		super(manager);
@@ -84,17 +94,54 @@ public class AllTransfersBar extends MiniBar {
 		this.createFixedTextLabel("MinimizedWindow.all_transfers", false, true);
 		this.createGap(40);
 
-		// Download speed.
-		this.createFixedTextLabel("ConfigView.download.abbreviated", false, false);
+			// Download speed.
+		
+		Label dlab = this.createFixedTextLabel("ConfigView.download.abbreviated", false, false);
 		this.down_speed = this.createSpeedLabel();
 		
-		// Upload speed.
-		this.createFixedTextLabel("ConfigView.upload.abbreviated", false, false);
+		final Menu downloadSpeedMenu = new Menu(getShell(),	SWT.POP_UP);
+
+		downloadSpeedMenu.addListener(SWT.Show, new Listener() {
+			public void handleEvent(Event event) {
+				if ( AzureusCoreFactory.isCoreRunning()){
+					SelectableSpeedMenu.generateMenuItems(
+						downloadSpeedMenu, AzureusCoreFactory.getSingleton(),
+						g_manager, false);
+				}
+			}
+		});
+
+		dlab.setMenu(downloadSpeedMenu);
+		down_speed.setMenu(downloadSpeedMenu);
+		
+			// Upload speed.
+		
+		Label ulab = this.createFixedTextLabel("ConfigView.upload.abbreviated", false, false);
 		this.up_speed = this.createSpeedLabel();
+		
+		final Menu uploadSpeedMenu = new Menu(getShell(),	SWT.POP_UP);
+
+		uploadSpeedMenu.addListener(SWT.Show, new Listener() {
+			public void handleEvent(Event event) {
+				if ( AzureusCoreFactory.isCoreRunning()){
+					SelectableSpeedMenu.generateMenuItems(
+						uploadSpeedMenu, AzureusCoreFactory.getSingleton(),
+						g_manager, true);
+				}
+			}
+		});
+
+		ulab.setMenu(uploadSpeedMenu);
+		up_speed.setMenu(uploadSpeedMenu);
+		
+			// next eta
+		
+		this.createFixedTextLabel("TableColumn.header.eta_next", true, false);
+		this.next_eta = this.createDataLabel(65);
 	}
 	
 	public void buildMenu(Menu menu, MenuEvent menuEvent) {
-
+		
 		// Start All
 		MenuItem start_all = new MenuItem(menu, SWT.PUSH);
 		Messages.setLanguageText(start_all, "MainWindow.menu.transfers.startalltransfers");
@@ -147,6 +194,30 @@ public class AllTransfersBar extends MiniBar {
 		GlobalManagerStats stats = g_manager.getStats();
 		this.updateSpeedLabel(down_speed, stats.getDataReceiveRate(),stats.getProtocolReceiveRate());
 		this.updateSpeedLabel(up_speed, stats.getDataSendRate(),stats.getProtocolSendRate());
+		
+		long	min_eta = Long.MAX_VALUE;
+		int		num_downloading = 0;
+		
+		List<DownloadManager> dms = g_manager.getDownloadManagers();
+		for ( DownloadManager dm: dms ){
+			if ( dm.getState() == DownloadManager.STATE_DOWNLOADING ){
+				
+				num_downloading++;
+				
+				long eta = dm.getStats().getETA();
+				
+				if ( eta < min_eta ){
+					
+					min_eta = eta;
+				}
+			}
+		}
+		
+		if ( min_eta == Long.MAX_VALUE ){
+			
+			min_eta = Constants.CRAPPY_INFINITE_AS_LONG;
+		}
+		next_eta.setText(num_downloading==0?"":DisplayFormatters.formatETA(min_eta));
 	}
 	
 	public String getPluginMenuIdentifier(Object context) {
diff --git a/org/gudy/azureus2/ui/swt/minibar/DownloadBar.java b/org/gudy/azureus2/ui/swt/minibar/DownloadBar.java
index 07de0cb..3fbe007 100644
--- a/org/gudy/azureus2/ui/swt/minibar/DownloadBar.java
+++ b/org/gudy/azureus2/ui/swt/minibar/DownloadBar.java
@@ -27,6 +27,7 @@ import org.gudy.azureus2.plugins.download.DownloadException;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.DoubleBufferedLabel;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MenuEvent;
@@ -67,11 +68,11 @@ public class DownloadBar extends MiniBar {
 	}
 	
 	private DownloadManager download;
-	private Label download_name;
+	private DoubleBufferedLabel download_name;
 	private ProgressBar progress_bar;
-	private Label down_speed;
-	private Label up_speed;
-	private Label eta;
+	private DoubleBufferedLabel down_speed;
+	private DoubleBufferedLabel up_speed;
+	private DoubleBufferedLabel eta;
 	
 	private DownloadBar(DownloadManager download, Shell main) {
 		super(manager);
diff --git a/org/gudy/azureus2/ui/swt/minibar/MiniBar.java b/org/gudy/azureus2/ui/swt/minibar/MiniBar.java
index 33ab2ad..1da9188 100644
--- a/org/gudy/azureus2/ui/swt/minibar/MiniBar.java
+++ b/org/gudy/azureus2/ui/swt/minibar/MiniBar.java
@@ -25,15 +25,20 @@ import java.util.Iterator;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.GridData;
 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.Constants;
+import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 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.components.DoubleBufferedLabel;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
 
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
@@ -112,7 +117,7 @@ public abstract class MiniBar implements MenuBuildUtils.MenuBuilder {
 	    this.xSize += width;
 	}
 	
-	protected final void createFixedTextLabel(String msg_key, boolean add_colon, boolean bold) {
+	protected final Label createFixedTextLabel(String msg_key, boolean add_colon, boolean bold) {
 		assertConstructing();
 	    Label result = new Label(splash, SWT.NONE);
 	    result.setBackground(Colors.blues[Colors.BLUES_LIGHTEST]);
@@ -135,11 +140,13 @@ public abstract class MiniBar implements MenuBuildUtils.MenuBuilder {
 	        this.hSize = hSizeText > hSizeImage ? hSizeText : hSizeImage;
 	    }
 	    this.xSize += result.getSize().x + 3;
+	    
+	    return( result );
 	}
 	
-	protected final Label createDataLabel(int width, boolean centered) {
+	protected final DoubleBufferedLabel createDataLabel(int width, boolean centered) {
 		assertConstructing();
-	    Label result = new Label(splash, (centered ? SWT.CENTER : SWT.NULL));
+		DoubleBufferedLabel result = new DoubleBufferedLabel(splash, (centered ? SWT.CENTER : SWT.NULL) | SWT.DOUBLE_BUFFERED );
 	    result.setBackground(Colors.blues[Colors.BLUES_LIGHTEST]);
 	    result.setText("");
 	    result.addMouseListener(this.mListener);
@@ -154,20 +161,20 @@ public abstract class MiniBar implements MenuBuildUtils.MenuBuilder {
 	    return result;
 	}
 
-	protected final Label createDataLabel(int width) {
+	protected final DoubleBufferedLabel createDataLabel(int width) {
 		return createDataLabel(width, false);
 	}
 
-	protected final Label createSpeedLabel() {
+	protected final DoubleBufferedLabel createSpeedLabel() {
 		return createDataLabel(separateDataProt ? 110 : 65, separateDataProt); 
 	}
 	
-	protected void updateSpeedLabel(Label label, long data_rate, long protocol_rate) {
+	protected void updateSpeedLabel(DoubleBufferedLabel label, long data_rate, long protocol_rate) {
 		if (separateDataProt) {
 			label.setText(DisplayFormatters.formatDataProtByteCountToKiBEtcPerSec(data_rate, protocol_rate));
 		}
 		else {
-			label.setText(DisplayFormatters.formatByteCountToKiBEtcPerSec(data_rate));
+			label.setText(DisplayFormatters.formatByteCountToKiBEtcPerSec(data_rate+protocol_rate));
 		}
 	}
 	
@@ -551,5 +558,4 @@ public abstract class MiniBar implements MenuBuildUtils.MenuBuilder {
 	protected void storeLastLocation(Point point) {
 		// Do nothing.
 	}
-
 }
diff --git a/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java b/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
index ab7f0f1..cef5020 100644
--- a/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
+++ b/org/gudy/azureus2/ui/swt/nat/NatTestWindow.java
@@ -22,6 +22,8 @@
  */
 package org.gudy.azureus2.ui.swt.nat;
 
+import java.net.InetAddress;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.layout.GridData;
@@ -32,6 +34,7 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.ipchecker.natchecker.NatChecker;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AEThread;
+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;
@@ -42,53 +45,147 @@ import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProgressListener;
+import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminProtocol;
 
 public class NatTestWindow {
   
   Display display;
   
-  Button bTest,bApply,bCancel;
+  Button bTestTCP,bTestUDP,bApply,bCancel;
   StyledText textResults;
   
-  Checker checker;
   int serverTCPListenPort;
-  public class Checker extends AEThread {
+  int serverUDPListenPort;
+  
+  public class CheckerTCP extends AEThread {
 
-    //private int lowPort;
-    //private int highPort;
     private int TCPListenPort;
     
-    public Checker(int tcp_listen_port) {
-      super("NAT Checker");
+    public CheckerTCP(int tcp_listen_port) {
+      super("NAT Checker TCP");
       this.TCPListenPort = tcp_listen_port;
     }
 
-    public void runSupport() {
-          printMessage(MessageText.getString("configureWizard.nat.testing") + " " + TCPListenPort + " ... ");
-          NatChecker checker = new NatChecker(AzureusCoreFactory.getSingleton(), NetworkAdmin.getSingleton().getMultiHomedServiceBindAddresses(true)[0], TCPListenPort, false);          
-          switch (checker.getResult()) {
-          case NatChecker.NAT_OK :
-            printMessage(MessageText.getString("configureWizard.nat.ok") + "\n" + checker.getAdditionalInfo());
-            break;
-          case NatChecker.NAT_KO :
-            printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + " - " + checker.getAdditionalInfo()+".\n");
-            break;
-          default :
-            printMessage( "\n" + MessageText.getString("configureWizard.nat.unable") + ". \n(" + checker.getAdditionalInfo()+").\n");
-            break;
-          }
+    public void 
+    runSupport() 
+    {
+    	try{
+	          printMessage(MessageText.getString("configureWizard.nat.testing") + " TCP " + TCPListenPort + " ... ");
+	          NatChecker checker = new NatChecker(AzureusCoreFactory.getSingleton(), NetworkAdmin.getSingleton().getMultiHomedServiceBindAddresses(true)[0], TCPListenPort, false);          
+	          switch (checker.getResult()) {
+	          case NatChecker.NAT_OK :
+	            printMessage( "\n" + MessageText.getString("configureWizard.nat.ok") + "\n" + checker.getAdditionalInfo());
+	            break;
+	          case NatChecker.NAT_KO :
+	            printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + " - " + checker.getAdditionalInfo()+".\n");
+	            break;
+	          default :
+	            printMessage( "\n" + MessageText.getString("configureWizard.nat.unable") + ". \n(" + checker.getAdditionalInfo()+").\n");
+	            break;
+	          }
+    	}finally{
           if (display.isDisposed()) {return;}
           display.asyncExec(new AERunnable()  {
             public void runSupport() {
-              if(bTest != null && ! bTest.isDisposed())
-               bTest.setEnabled(true);
+              if(bTestTCP != null && ! bTestTCP.isDisposed())
+            	  bTestTCP.setEnabled(true);
+			if(bTestUDP != null && ! bTestUDP.isDisposed())
+				bTestUDP.setEnabled(true);
+			if(bApply != null && ! bApply.isDisposed())
+				bApply.setEnabled(true);
             }
           });
+    	}
     }
   }
   
+  public class CheckerUDP extends AEThread {
+
+	    private AzureusCore	core;
+	    private int			udp_port;
+	    
+	    public CheckerUDP(AzureusCore _core, int _udp_port ){
+	      super("NAT Checker UDP");
+	      core 		= _core;
+	      udp_port	= _udp_port;
+	    }
+
+	    public void 
+	    runSupport() 
+	    {
+	    	try{
+		    	final NetworkAdmin	admin = NetworkAdmin.getSingleton();
+		    	
+				NetworkAdminProtocol[] inbound_protocols = admin.getInboundProtocols(core);
+				
+				NetworkAdminProtocol selected = null;
+				
+				for ( NetworkAdminProtocol p: inbound_protocols ){
+					
+					if ( p.getType() == NetworkAdminProtocol.PT_UDP && p.getPort() == udp_port ){
+						
+						selected = p;
+						
+						break;
+					}
+				}
+					
+				if ( selected == null ){
+					
+					selected = admin.createInboundProtocol( core, NetworkAdminProtocol.PT_UDP, udp_port );
+				}
+
+		        if ( selected == null ){
+		        	
+		        	printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + ". \n( No UDP protocols enabled ).\n");
+		        	
+		        }else{
+		        	
+		        	printMessage(MessageText.getString("configureWizard.nat.testing") + " UDP " + udp_port + " ... ");
+
+		        	try{
+		        		selected.test( 
+		        				null,
+		        				true,
+		        				new NetworkAdminProgressListener()
+		        				{
+		        					public void 
+		        					reportProgress(
+		        							String task )
+		        					{
+		        						printMessage( "\n    " + task );
+		        					}
+		        				});
+
+		        		printMessage( "\n" + MessageText.getString("configureWizard.nat.ok"));
+
+		        	}catch( Throwable e ){
+
+		        		printMessage( "\n" + MessageText.getString("configureWizard.nat.ko") + ". " + Debug.getNestedExceptionMessage(e)+".\n");
+		        	}
+		        }
+		   
+	    	}finally{
+	    		if (display.isDisposed()) {return;}
+	    		display.asyncExec(new AERunnable()  {
+	    			public void runSupport() {
+	    				if(bTestTCP != null && ! bTestTCP.isDisposed())
+	    					bTestTCP.setEnabled(true);
+	    				if(bTestUDP != null && ! bTestUDP.isDisposed())
+	    					bTestUDP.setEnabled(true);
+	    				if(bApply != null && ! bApply.isDisposed())
+	    					bApply.setEnabled(true);
+	    			}
+	    		});
+	    	}
+	    }
+  }
+  
+  
   public NatTestWindow() {
-    serverTCPListenPort = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
+	serverTCPListenPort = COConfigurationManager.getIntParameter( "TCP.Listen.Port" );
+	serverUDPListenPort = COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
     
     final Shell shell = ShellFactory.createMainShell(SWT.BORDER | SWT.TITLE | SWT.CLOSE);        
     shell.setText(MessageText.getString("configureWizard.nat.title"));
@@ -118,6 +215,9 @@ public class NatTestWindow {
     label = new Label(panel, SWT.NULL);
     label = new Label(panel, SWT.NULL);
     label = new Label(panel, SWT.NULL);
+    
+    	// TCP 
+    
     Messages.setLanguageText(label, "configureWizard.nat.server.tcp_listen_port");
 
     final Text textServerTCPListen = new Text(panel, SWT.BORDER);
@@ -147,14 +247,53 @@ public class NatTestWindow {
       }
     });
 
-   
-
-    bTest = new Button(panel, SWT.PUSH);
-    Messages.setLanguageText(bTest, "configureWizard.nat.test");
+    bTestTCP = new Button(panel, SWT.PUSH);
+    Messages.setLanguageText(bTestTCP, "configureWizard.nat.test");
     gridData = new GridData();
     gridData.widthHint = 70;
-    bTest.setLayoutData(gridData);
+    bTestTCP.setLayoutData(gridData);
+
+    label = new Label(panel, SWT.NULL);
+
+    	// UDP 
+    
+    Messages.setLanguageText(label, "configureWizard.nat.server.udp_listen_port");
+
+    final Text textServerUDPListen = new Text(panel, SWT.BORDER);
+    gridData = new GridData();    
+    gridData.grabExcessHorizontalSpace = true;
+    gridData.horizontalAlignment = SWT.FILL;
+    textServerUDPListen.setLayoutData(gridData);
+    textServerUDPListen.setText("" + serverUDPListenPort);
+    textServerUDPListen.addListener(SWT.Verify, new Listener() {
+      public void handleEvent(Event e) {
+        String text = e.text;
+        char[] chars = new char[text.length()];
+        text.getChars(0, chars.length, chars, 0);
+        for (int i = 0; i < chars.length; i++) {
+          if (!('0' <= chars[i] && chars[i] <= '9')) {
+            e.doit = false;
+            return;
+          }
+        }
+      }
+    });
+    
+    textServerUDPListen.addListener(SWT.Modify, new Listener() {
+      public void handleEvent(Event e) {
+        final int UDPListenPort = Integer.parseInt(textServerUDPListen.getText());
+        serverUDPListenPort =UDPListenPort;
+      }
+    });
 
+    bTestUDP = new Button(panel, SWT.PUSH);
+    Messages.setLanguageText(bTestUDP, "configureWizard.nat.test");
+    gridData = new GridData();
+    gridData.widthHint = 70;
+    bTestUDP.setLayoutData(gridData);
+    
+    	// results
+    
     textResults = new StyledText(panel, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.WRAP );
     gridData = new GridData();
     gridData.widthHint = 400;
@@ -165,22 +304,41 @@ public class NatTestWindow {
     textResults.setLayoutData(gridData);
     textResults.setBackground(panel.getDisplay().getSystemColor(SWT.COLOR_WHITE));
 
-    bTest.addListener(SWT.Selection, new Listener() {
+    bTestTCP.addListener(SWT.Selection, new Listener() {
       public void handleEvent(Event event) {
-        bTest.setEnabled(false);
+      	bTestUDP.setEnabled(false);
+    	bTestTCP.setEnabled(false);
+    	bApply.setEnabled(false);
         textResults.setText("");
 
         CoreWaiterSWT.waitForCore(TriggerInThread.ANY_THREAD,
 						new AzureusCoreRunningListener() {
 							public void azureusCoreRunning(AzureusCore core) {
-						checker = new Checker(serverTCPListenPort);
-						checker.start();
+								CheckerTCP checker = new CheckerTCP(serverTCPListenPort);
+								checker.start();
 					}
 				});
       }
     });
         
-        
+      
+    bTestUDP.addListener(SWT.Selection, new Listener() {
+        public void handleEvent(Event event) {
+          bTestUDP.setEnabled(false);
+          bTestTCP.setEnabled(false);
+          bApply.setEnabled(false);
+          textResults.setText("");
+
+          CoreWaiterSWT.waitForCore(TriggerInThread.ANY_THREAD,
+  						new AzureusCoreRunningListener() {
+  							public void azureusCoreRunning(AzureusCore core) {
+  								CheckerUDP checker = new CheckerUDP(core,serverUDPListenPort);
+  								checker.start();
+  					}
+  				});
+        }
+      });
+    
     bApply = new Button(panel,SWT.PUSH);
     bApply.setText(MessageText.getString("Button.apply"));
     gridData = new GridData();
@@ -197,15 +355,18 @@ public class NatTestWindow {
 	   	int	old_udp 	= COConfigurationManager.getIntParameter( "UDP.Listen.Port" );
 	   	int	old_udp2 	= COConfigurationManager.getIntParameter( "UDP.NonData.Listen.Port" );
     	
-        COConfigurationManager.setParameter("TCP.Listen.Port",serverTCPListenPort);
+	   	if ( old_tcp != serverTCPListenPort ){
+	   		COConfigurationManager.setParameter("TCP.Listen.Port",serverTCPListenPort);
+	   	}
         
-        if ( old_tcp == old_udp ){
-        	COConfigurationManager.setParameter("UDP.Listen.Port",serverTCPListenPort);
+        if ( old_udp != serverUDPListenPort ){
+        	COConfigurationManager.setParameter("UDP.Listen.Port",serverUDPListenPort);
+     
+	        if ( old_udp == old_udp2 ){
+	        	COConfigurationManager.setParameter("UDP.NonData.Listen.Port",serverUDPListenPort);
+	        }
         }
-        if ( old_tcp == old_udp2 ){
-        	COConfigurationManager.setParameter("UDP.NonData.Listen.Port",serverTCPListenPort);
-        }
-
+        
         COConfigurationManager.save();
         
         shell.close();
diff --git a/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java b/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
index 049f6d5..2878dc9 100644
--- a/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
+++ b/org/gudy/azureus2/ui/swt/osx/CarbonUIEnhancer.java
@@ -9,12 +9,10 @@
  *******************************************************************************/
 package org.gudy.azureus2.ui.swt.osx;
 
-import java.io.IOException;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.internal.Callback;
-import org.eclipse.swt.internal.carbon.*;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -35,12 +33,59 @@ 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;
-
-//import com.apple.eawt.*; //Application and ApplicationAdapter
 
 public class CarbonUIEnhancer
 {
+	// Most of these constants come from SWT OS.java.  Could have used reflection
+	// to get them, but I assume they are truly constant (will never change)
+	private static final int noErr = 0;
+
+	private static final int eventNotHandledErr = -9874;
+
+	private static final int kEventWindowToolbarSwitchMode = 150;
+
+	private static final int kWindowToolbarButtonAttribute = (1 << 6);
+
+	private static final int kEventAppleEvent = 1;
+
+	private static final int kEventProcessCommand = 1;
+
+	private static final int kCFAllocatorDefault = 0;
+
+	private static final int kMenuItemAttrSeparator = 64;
+
+	private static final int kCFURLPOSIXPathStyle = 0;
+
+	private static final int kEventClassWindow = ('w' << 24) + ('i' << 16)
+			+ ('n' << 8) + 'd';
+
+	private static final int kAEQuitApplication = ('q' << 24) + ('u' << 16)
+			+ ('i' << 8) + 't';
+
+	private static final int kEventClassAppleEvent = ('e' << 24) + ('p' << 16)
+			+ ('p' << 8) + 'c';
+
+	private static final int kEventParamDirectObject = ('-' << 24) + ('-' << 16)
+			+ ('-' << 8) + '-';
+
+	private static final int kEventClassCommand = ('c' << 24) + ('m' << 16)
+			+ ('d' << 8) + 's';
+
+	private static final int kEventParamAEEventID = ('e' << 24) + ('v' << 16)
+			+ ('t' << 8) + 'i';
+
+	private static final int typeHICommand = ('h' << 24) + ('c' << 16)
+			+ ('m' << 8) + 'd';
+
+	private static final int typeFSRef = ('f' << 24) + ('s' << 16) + ('r' << 8)
+			+ 'f';
+
+	private static final int typeWindowRef = ('w' << 24) + ('i' << 16)
+			+ ('n' << 8) + 'd';
+
+	private static final int typeType = ('t' << 24) + ('y' << 16) + ('p' << 8)
+			+ 'e';
+
 	private static final int kHICommandPreferences = ('p' << 24) + ('r' << 16)
 			+ ('e' << 8) + 'f';
 
@@ -83,8 +128,6 @@ public class CarbonUIEnhancer
 	private static final int typeText = ('T' << 24) + ('E' << 16) + ('X' << 8)
 			+ 'T';
 
-	private static final String RESOURCE_BUNDLE = "org.eclipse.ui.carbon.Messages"; //$NON-NLS-1$
-
 	private static String fgAboutActionName;
 
 	private static String fgWizardActionName;
@@ -104,9 +147,55 @@ public class CarbonUIEnhancer
 	 */
 	private boolean isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
 
-	public static final int BOUNCE_SINGLE = NSApplication.UserAttentionRequestInformational;
+	private static Class<?> claCallback;
+
+	private static Constructor<?> constCallback3;
 
-	public static final int BOUNCE_CONTINUOUS = NSApplication.UserAttentionRequestCritical;
+	private static Method mCallback_getAddress;
+
+	private static Method mCallback_dispose;
+
+	private static Class<?> claOS;
+
+	private static Class<?> claHICommand;
+
+	private static Class<?> claCFRange;
+
+	private static Class<?> claAEDesc;
+
+	private static Class<?> claEventRecord;
+
+	//public static final int BOUNCE_SINGLE = NSApplication.UserAttentionRequestInformational;
+
+	//public static final int BOUNCE_CONTINUOUS = NSApplication.UserAttentionRequestCritical;
+
+	static {
+		try {
+			claCallback = Class.forName("org.eclipse.swt.internal.Callback");
+			//public Callback (Object object, String method, int argCount) {
+			constCallback3 = claCallback.getConstructor(new Class[] {
+				Object.class,
+				String.class,
+				int.class,
+			});
+			// public int /*long*/ getAddress () {
+			mCallback_getAddress = claCallback.getMethod("getAddress", new Class[] {});
+			// public void dispose () {
+			mCallback_dispose = claCallback.getMethod("dispose", new Class[] {});
+
+			claOS = Class.forName("org.eclipse.swt.internal.carbon.OS");
+
+			claHICommand = Class.forName("org.eclipse.swt.internal.carbon.HICommand");
+
+			claCFRange = Class.forName("org.eclipse.swt.internal.carbon.CFRange");
+
+			claAEDesc = Class.forName("org.eclipse.swt.internal.carbon.AEDesc");
+
+			claEventRecord = Class.forName("org.eclipse.swt.internal.carbon.EventRecord");
+		} catch (Exception e) {
+		}
+
+	}
 
 	public CarbonUIEnhancer() {
 		if (fgAboutActionName == null) {
@@ -139,122 +228,214 @@ public class CarbonUIEnhancer
 	}
 
 	public static void registerToolbarToggle(Shell shell) {
-		final Callback toolbarToggleCB = new Callback(target, "toolbarToggle", 3);
-		int toolbarToggle = toolbarToggleCB.getAddress();
-		if (toolbarToggle == 0) {
-			Debug.out("OSX: Could not find callback 'toolbarToggle'");
-			toolbarToggleCB.dispose();
-			return;
-		}
-
-		shell.getDisplay().disposeExec(new Runnable() {
-			public void run() {
-				toolbarToggleCB.dispose();
+		try {
+			final Object toolbarToggleCB = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "toolbarToggle", 3);
+			int toolbarToggle = ((Number) mCallback_getAddress.invoke(
+					toolbarToggleCB, new Object[] {})).intValue();
+			if (toolbarToggle == 0) {
+				Debug.out("OSX: Could not find callback 'toolbarToggle'");
+				mCallback_dispose.invoke(toolbarToggleCB, new Object[] {});
+				return;
 			}
-		});
 
-		//	 add the button to the window trim
-		int windowHandle = OS.GetControlOwner(shell.handle);
-		OS.ChangeWindowAttributes(windowHandle, OS.kWindowToolbarButtonAttribute, 0);
-
-		int[] mask = new int[] {
-			OS.kEventClassWindow,
-			OS.kEventWindowToolbarSwitchMode
-		};
-		// register the handler with the OS
-		OS.InstallEventHandler(OS.GetApplicationEventTarget(), toolbarToggle,
-				mask.length / 2, mask, 0, null);
+			shell.getDisplay().disposeExec(new Runnable() {
+				public void run() {
+					try {
+						mCallback_dispose.invoke(toolbarToggleCB, new Object[] {});
+					} catch (Exception e) {
+					}
+				}
+			});
+
+			//	 add the button to the window trim
+			Object oHandle = shell.getClass().getField("handle").get(shell);
+			int windowHandle = ((Number) invoke(claOS, null, "GetControlOwner",
+					new Object[] {
+						oHandle
+					})).intValue();
+			invoke(claOS, null, "ChangeWindowAttributes", new Object[] {
+				windowHandle,
+				kWindowToolbarButtonAttribute,
+				0
+			});
+
+			int[] mask = new int[] {
+				kEventClassWindow,
+				kEventWindowToolbarSwitchMode
+			};
+			// register the handler with the OS
+			int applicationEventTarget = ((Number) invoke(claOS, null,
+					"GetApplicationEventTarget", new Object[] {})).intValue();
+			// int InstallEventHandler(int inTarget, int inHandler, int inNumTypes, int[] inList, int inUserData, int[] outRef);
+			invoke(claOS, null, "InstallEventHandler", new Class[] {
+				int.class,
+				int.class,
+				int.class,
+				int[].class,
+				int.class,
+				int[].class
+			}, new Object[] {
+				applicationEventTarget,
+				toolbarToggle,
+				mask.length / 2,
+				mask,
+				0,
+				null
+			});
+		} catch (Throwable e) {
+			Debug.out("RegisterToolbarToggle failed", e);
+		}
 	}
 
 	private void registerTorrentFile() {
-		int result;
-
-		Callback clickDockIconCallback = new Callback(target, "clickDockIcon", 3);
-		int clickDocIcon = clickDockIconCallback.getAddress();
-		if (clickDocIcon == 0) {
-			clickDockIconCallback.dispose();
-		} else {
-			result = OS.AEInstallEventHandler(kCoreEventClass, kAEReopenApplication,
-					clickDocIcon, 0, false);
+		try {
+			int result;
+
+			Object clickDockIconCallback = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "clickDockIcon", 3);
+			int clickDocIcon = ((Number) mCallback_getAddress.invoke(
+					clickDockIconCallback, new Object[] {})).intValue();
+			if (clickDocIcon == 0) {
+				mCallback_dispose.invoke(clickDockIconCallback, new Object[] {});
+			} else {
+				result = ((Number) invoke(claOS, null, "AEInstallEventHandler",
+						new Object[] {
+							kCoreEventClass,
+							kAEReopenApplication,
+							clickDocIcon,
+							(int) 0,
+							false
+						})).intValue();
+
+				if (result != noErr) {
+					Debug.out("OSX: Could Install ReopenApplication Event Handler. Error: "
+							+ result);
+				}
+			}
 
-			if (result != OS.noErr) {
-				Debug.out("OSX: Could Install ReopenApplication Event Handler. Error: "
-						+ result);
+			Object openContentsCallback = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "openContents", 3);
+			int openContents = ((Number) mCallback_getAddress.invoke(
+					openContentsCallback, new Object[] {})).intValue();
+			if (openContents == 0) {
+				mCallback_dispose.invoke(openContentsCallback, new Object[] {});
+			} else {
+				result = ((Number) invoke(claOS, null, "AEInstallEventHandler",
+						new Object[] {
+							kCoreEventClass,
+							kAEOpenContents,
+							openContents,
+							(int) 0,
+							false
+						})).intValue();
+
+				if (result != noErr) {
+					Debug.out("OSX: Could Install OpenContents Event Handler. Error: "
+							+ result);
+				}
 			}
-		}
 
-		Callback openContentsCallback = new Callback(target, "openContents", 3);
-		int openContents = openContentsCallback.getAddress();
-		if (openContents == 0) {
-			openContentsCallback.dispose();
-		} else {
-			result = OS.AEInstallEventHandler(kCoreEventClass, kAEOpenContents,
-					openContents, 0, false);
+			Object openDocCallback = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "openDocProc", 3);
+			int openDocProc = ((Number) mCallback_getAddress.invoke(openDocCallback,
+					new Object[] {})).intValue();
+			if (openDocProc == 0) {
+				Debug.out("OSX: Could not find Callback 'openDocProc'");
+				mCallback_dispose.invoke(openDocCallback, new Object[] {});
+				return;
+			}
 
-			if (result != OS.noErr) {
-				Debug.out("OSX: Could Install OpenContents Event Handler. Error: "
+			result = ((Number) invoke(claOS, null, "AEInstallEventHandler",
+					new Object[] {
+						kCoreEventClass,
+						kAEOpenDocuments,
+						openDocProc,
+						(int) 0,
+						false
+					})).intValue();
+
+			if (result != noErr) {
+				Debug.out("OSX: Could not Install OpenDocs Event Handler. Error: "
 						+ result);
+				return;
 			}
-		}
 
-		Callback openDocCallback = new Callback(target, "openDocProc", 3);
-		int openDocProc = openDocCallback.getAddress();
-		if (openDocProc == 0) {
-			Debug.out("OSX: Could not find Callback 'openDocProc'");
-			openDocCallback.dispose();
-			return;
-		}
-
-		result = OS.AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
-				openDocProc, 0, false);
-
-		if (result != OS.noErr) {
-			Debug.out("OSX: Could not Install OpenDocs Event Handler. Error: "
-					+ result);
-			return;
-		}
-
-		result = OS.AEInstallEventHandler(kURLEventClass, kURLEventClass,
-				openDocProc, 0, false);
-		if (result != OS.noErr) {
-			Debug.out("OSX: Could not Install URLEventClass Event Handler. Error: "
-					+ result);
-			return;
-		}
+			result = ((Number) invoke(claOS, null, "AEInstallEventHandler",
+					new Object[] {
+						kURLEventClass,
+						kURLEventClass,
+						openDocProc,
+						(int) 0,
+						false
+					})).intValue();
+			if (result != noErr) {
+				Debug.out("OSX: Could not Install URLEventClass Event Handler. Error: "
+						+ result);
+				return;
+			}
 
-		///
+			///
 
-		Callback quitAppCallback = new Callback(target, "quitAppProc", 3);
-		int quitAppProc = quitAppCallback.getAddress();
-		if (quitAppProc == 0) {
-			Debug.out("OSX: Could not find Callback 'quitApp'");
-			quitAppCallback.dispose();
-		} else {
-			result = OS.AEInstallEventHandler(kCoreEventClass, OS.kAEQuitApplication,
-					quitAppProc, 0, false);
-			if (result != OS.noErr) {
-				Debug.out("OSX: Could not install QuitApplication Event Handler. Error: "
-						+ result);
+			Object quitAppCallback = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "quitAppProc", 3);
+			int quitAppProc = ((Number) mCallback_getAddress.invoke(quitAppCallback,
+					new Object[] {})).intValue();
+			if (quitAppProc == 0) {
+				Debug.out("OSX: Could not find Callback 'quitApp'");
+				mCallback_dispose.invoke(quitAppCallback, new Object[] {});
+			} else {
+				result = ((Number) invoke(claOS, null, "AEInstallEventHandler",
+						new Object[] {
+							kCoreEventClass,
+							kAEQuitApplication,
+							quitAppProc,
+							(int) 0,
+							false
+						})).intValue();
+				if (result != noErr) {
+					Debug.out("OSX: Could not install QuitApplication Event Handler. Error: "
+							+ result);
+				}
 			}
-		}
 
-		///
-
-		int appTarget = OS.GetApplicationEventTarget();
-		Callback appleEventCallback = new Callback(this, "appleEventProc", 3);
-		int appleEventProc = appleEventCallback.getAddress();
-		int[] mask3 = new int[] {
-			OS.kEventClassAppleEvent,
-			OS.kEventAppleEvent,
-			kURLEventClass,
-			kAEReopenApplication,
-			kAEOpenContents,
-		};
-		result = OS.InstallEventHandler(appTarget, appleEventProc,
-				mask3.length / 2, mask3, 0, null);
-		if (result != OS.noErr) {
-			Debug.out("OSX: Could Install Event Handler. Error: " + result);
-			return;
+			///
+
+			int appTarget = ((Number) invoke(claOS, null,
+					"GetApplicationEventTarget", new Object[] {})).intValue();
+			Object appleEventCallback = constCallback3.newInstance(this,
+					"appleEventProc", 3);
+			int appleEventProc = ((Number) mCallback_getAddress.invoke(
+					appleEventCallback, new Object[] {})).intValue();
+			int[] mask3 = new int[] {
+				kEventClassAppleEvent,
+				kEventAppleEvent,
+				kURLEventClass,
+				kAEReopenApplication,
+				kAEOpenContents,
+			};
+			result = ((Number) invoke(claOS, null, "InstallEventHandler",
+					new Class[] {
+						int.class,
+						int.class,
+						int.class,
+						int[].class,
+						int.class,
+						int[].class
+					}, new Object[] {
+						appTarget,
+						appleEventProc,
+						mask3.length / 2,
+						mask3,
+						0,
+						null
+					})).intValue();
+			if (result != noErr) {
+				Debug.out("OSX: Could Install Event Handler. Error: " + result);
+				return;
+			}
+		} catch (Throwable e) {
+			Debug.out("registerTorrentFile failed", e);
 		}
 	}
 
@@ -275,197 +456,252 @@ public class CarbonUIEnhancer
 	* Also http://developer.apple.com/documentation/Carbon/Reference/Menu_Manager/menu_mgr_ref/function_group_10.html
 	*/
 	public void hookApplicationMenu(final Display display) {
-		// Callback target
-		Object target = new Object() {
-			int commandProc(int nextHandler, int theEvent, int userData) {
-				if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) {
-					HICommand command = new HICommand();
-					OS.GetEventParameter(theEvent, OS.kEventParamDirectObject,
-							OS.typeHICommand, null, HICommand.sizeof, null, command);
-					switch (command.commandID) {
-						case kHICommandPreferences: {
-							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-							if (uiFunctions != null) {
-								uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
-							}
-							return OS.noErr;
-						}
-						case kHICommandAbout:
-							AboutWindow.show();
-							return OS.noErr;
-						case kHICommandRestart: {
-							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-							if (uiFunctions != null) {
-								uiFunctions.dispose(true, false);
-							}
-							return OS.noErr;
-						}
-						case kHICommandWizard:
-							new ConfigureWizard(false);
-							return OS.noErr;
-						case kHICommandNatTest:
-							new NatTestWindow();
-							return OS.noErr;
-						case kHICommandSpeedTest:
-							new SpeedTestWizard();
-							return OS.noErr;
-
-						case OS.kAEQuitApplication:
-							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-							if (uiFunctions != null) {
-								uiFunctions.dispose(false, false);
-								return OS.noErr;
-							} else {
-								UIExitUtilsSWT.setSkipCloseCheck(true);
-							}
-						default:
-							break;
-					}
-				}
-				return OS.eventNotHandledErr;
+		try {
+			final Object commandCallback = constCallback3.newInstance(
+					CarbonUIEnhancer.class, "commandProc", 3); //$NON-NLS-1$
+			int commandProc = ((Number) mCallback_getAddress.invoke(commandCallback,
+					new Object[] {})).intValue();
+			if (commandProc == 0) {
+				mCallback_dispose.invoke(commandCallback, new Object[] {});
+				return; // give up
 			}
-		};
-		final Callback commandCallback = new Callback(target, "commandProc", 3); //$NON-NLS-1$
-		int commandProc = commandCallback.getAddress();
-		if (commandProc == 0) {
-			commandCallback.dispose();
-			return; // give up
-		}
 
-		// Install event handler for commands
-		int[] mask = new int[] {
-			OS.kEventClassCommand,
-			OS.kEventProcessCommand
-		};
-		OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc,
-				mask.length / 2, mask, 0, null);
-
-		// create About menu command
-		int[] outMenu = new int[1];
-		short[] outIndex = new short[1];
-		if (OS.GetIndMenuItemWithCommandID(0, kHICommandPreferences, 1, outMenu,
-				outIndex) == OS.noErr
-				&& outMenu[0] != 0) {
-			int menu = outMenu[0];
-
-			int l = fgAboutActionName.length();
-			char buffer[] = new char[l];
-			fgAboutActionName.getChars(0, l, buffer, 0);
-			int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer,
-					l);
-			OS.InsertMenuItemTextWithCFString(menu, str, (short) 0, 0,
-					kHICommandAbout);
-			OS.CFRelease(str);
-			// add separator between About & Preferences
-			OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1,
-					OS.kMenuItemAttrSeparator, 0);
-
-			// enable pref menu
-			OS.EnableMenuCommand(menu, kHICommandPreferences);
-			// disable services menu
-			OS.DisableMenuCommand(menu, kHICommandServices);
-
-			if (false == isAZ3) {
-				// wizard menu
-				l = fgWizardActionName.length();
-				buffer = new char[l];
-				fgWizardActionName.getChars(0, l, buffer, 0);
-				str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l);
-				OS.InsertMenuItemTextWithCFString(menu, str, (short) 3, 0,
-						kHICommandWizard);
-				OS.CFRelease(str);
-
-				// NAT test menu
-				l = fgNatTestActionName.length();
-				buffer = new char[l];
-				fgNatTestActionName.getChars(0, l, buffer, 0);
-				str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l);
-				OS.InsertMenuItemTextWithCFString(menu, str, (short) 4, 0,
-						kHICommandNatTest);
-				OS.CFRelease(str);
-
-				//SpeedTest
-				l = fgSpeedTestActionName.length();
-				buffer = new char[l];
-				fgSpeedTestActionName.getChars(0, l, buffer, 0);
-				str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l);
-				OS.InsertMenuItemTextWithCFString(menu, str, (short) 5, 0,
-						kHICommandSpeedTest);
-				OS.CFRelease(str);
-			}
+			// Install event handler for commands
+			int[] mask = new int[] {
+				kEventClassCommand,
+				kEventProcessCommand
+			};
+			int appTarget = ((Number) invoke(claOS, null,
+					"GetApplicationEventTarget", new Object[] {})).intValue();
+			invoke(claOS, null, "InstallEventHandler", new Class[] {
+				int.class,
+				int.class,
+				int.class,
+				int[].class,
+				int.class,
+				int[].class
+			}, new Object[] {
+				appTarget,
+				commandProc,
+				mask.length / 2,
+				mask,
+				0,
+				null
+			});
 
-			OS.InsertMenuItemTextWithCFString(menu, 0, (short) 6,
-					OS.kMenuItemAttrSeparator, 0);
+			// create About menu command
+			int[] outMenu = new int[1];
+			short[] outIndex = new short[1];
+			// int GetIndMenuItemWithCommandID(int mHandle, int commandId, int index, int[] outMenu, short[] outIndex);
+			int ind = ((Number) invoke(claOS, null, "GetIndMenuItemWithCommandID",
+					new Class[] {
+						int.class,
+						int.class,
+						int.class,
+						int[].class,
+						short[].class
+					}, new Object[] {
+						0,
+						kHICommandPreferences,
+						1,
+						outMenu,
+						outIndex
+					})).intValue();
+			if (ind == noErr && outMenu[0] != 0) {
+				int menu = outMenu[0];
+
+				int l = fgAboutActionName.length();
+				char buffer[] = new char[l];
+				fgAboutActionName.getChars(0, l, buffer, 0);
+				int str = CFStringCreateWithCharacters(kCFAllocatorDefault, buffer, l);
+				InsertMenuItemTextWithCFString(menu, str, (short) 0, 0, kHICommandAbout);
+				invoke(claOS, null, "CFRelease", new Object[] {
+					str
+				});
+				// add separator between About & Preferences
+				InsertMenuItemTextWithCFString(menu, 0, (short) 1,
+						kMenuItemAttrSeparator, 0);
+
+				// enable pref menu
+				invoke(claOS, null, "EnableMenuCommand", new Object[] {
+					menu,
+					kHICommandPreferences
+				});
+				// disable services menu
+				invoke(claOS, null, "DisableMenuCommand", new Object[] {
+					menu,
+					kHICommandServices
+				});
 
-			// restart menu
-			l = fgRestartActionName.length();
-			buffer = new char[l];
-			fgRestartActionName.getChars(0, l, buffer, 0);
-			str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l);
-			OS.InsertMenuItemTextWithCFString(menu, str, (short) 7, 0,
-					kHICommandRestart);
-			OS.CFRelease(str);
+				if (!isAZ3) {
+					// wizard menu
+					l = fgWizardActionName.length();
+					buffer = new char[l];
+					fgWizardActionName.getChars(0, l, buffer, 0);
+					str = CFStringCreateWithCharacters(kCFAllocatorDefault, buffer, l);
+					InsertMenuItemTextWithCFString(menu, str, (short) 3, 0,
+							kHICommandWizard);
+					invoke(claOS, null, "CFRelease", new Object[] {
+						str
+					});
 
-			OS.InsertMenuItemTextWithCFString(menu, 0, (short) 8,
-					OS.kMenuItemAttrSeparator, 0);
-		}
+					// NAT test menu
+					l = fgNatTestActionName.length();
+					buffer = new char[l];
+					fgNatTestActionName.getChars(0, l, buffer, 0);
+					str = CFStringCreateWithCharacters(kCFAllocatorDefault, buffer, l);
+					InsertMenuItemTextWithCFString(menu, str, (short) 4, 0,
+							kHICommandNatTest);
+					invoke(claOS, null, "CFRelease", new Object[] {
+						str
+					});
 
-		// schedule disposal of callback object
-		display.disposeExec(new AERunnable() {
-			public void runSupport() {
-				commandCallback.dispose();
-				//               stopSidekick();
+					//SpeedTest
+					l = fgSpeedTestActionName.length();
+					buffer = new char[l];
+					fgSpeedTestActionName.getChars(0, l, buffer, 0);
+					str = CFStringCreateWithCharacters(kCFAllocatorDefault, buffer, l);
+					InsertMenuItemTextWithCFString(menu, str, (short) 5, 0,
+							kHICommandSpeedTest);
+					invoke(claOS, null, "CFRelease", new Object[] {
+						str
+					});
+				}
+
+				InsertMenuItemTextWithCFString(menu, 0, (short) 6,
+						kMenuItemAttrSeparator, 0);
+
+				// restart menu
+				l = fgRestartActionName.length();
+				buffer = new char[l];
+				fgRestartActionName.getChars(0, l, buffer, 0);
+				str = CFStringCreateWithCharacters(kCFAllocatorDefault, buffer, l);
+				InsertMenuItemTextWithCFString(menu, str, (short) 7, 0,
+						kHICommandRestart);
+				invoke(claOS, null, "CFRelease", new Object[] {
+					str
+				});
+
+				InsertMenuItemTextWithCFString(menu, 0, (short) 8,
+						kMenuItemAttrSeparator, 0);
 			}
-		});
-	}
 
-	private static void stopSidekick() {
-		try {
-			Runtime.getRuntime().exec(new String[] {
-				"osascript",
-				"-e",
-				"tell application \"Azureus\" to quit"
+			// schedule disposal of callback object
+			display.disposeExec(new AERunnable() {
+				public void runSupport() {
+					try {
+						mCallback_dispose.invoke(commandCallback, new Object[] {});
+					} catch (Throwable e) {
+					}
+					//               stopSidekick();
+				}
 			});
-		} catch (IOException e) {
-			Debug.printStackTrace(e);
+		} catch (Throwable e) {
+			Debug.out("Failed hookApplicatioMenu", e);
 		}
 	}
 
+	private void InsertMenuItemTextWithCFString(int mHandle, int sHandle,
+			short index, int attributes, int commandID) {
+		//OS.InsertMenuItemTextWithCFString(mHandle, sHandle, index, attributes, commandID);
+		invoke(claOS, null, "InsertMenuItemTextWithCFString", new Class[] {
+			int.class,
+			int.class,
+			short.class,
+			int.class,
+			int.class
+		}, new Object[] {
+			mHandle,
+			sHandle,
+			index,
+			attributes,
+			commandID
+		});
+	}
+
+	private int CFStringCreateWithCharacters(int alloc, char[] buffer,
+			int numChars) {
+		//return OS.CFStringCreateWithCharacters(alloc, buffer, numChars);
+		return ((Number) invoke(claOS, null, "CFStringCreateWithCharacters",
+				new Object[] {
+					alloc,
+					buffer,
+					numChars
+				})).intValue();
+	}
+
 	int appleEventProc(int nextHandler, int theEvent, int userData) {
-		int eventClass = OS.GetEventClass(theEvent);
-		//int eventKind = OS.GetEventKind(theEvent);
-
-		//System.out.println("appleEventProc " + OSXtoString(eventClass) + ";"
-		//		+ OS.GetEventKind(theEvent) + ";" + OSXtoString(theEvent) + ";"
-		//		+ OSXtoString(userData));
-
-		// Process teh odoc event
-		if (eventClass == OS.kEventClassAppleEvent) {
-			int[] aeEventID = new int[1];
-			if (OS.GetEventParameter(theEvent, OS.kEventParamAEEventID, OS.typeType,
-					null, 4, null, aeEventID) != OS.noErr) {
-				return OS.eventNotHandledErr;
-			}
-			//System.out.println("EventID = " + OSXtoString(aeEventID[0]));
-			if (aeEventID[0] != kAEOpenDocuments && aeEventID[0] != kURLEventClass
-					&& aeEventID[0] != kAEReopenApplication
-					&& aeEventID[0] != kAEOpenContents
-					&& aeEventID[0] != OS.kAEQuitApplication) {
-				return OS.eventNotHandledErr;
-			}
+		try {
+			int eventClass = ((Number) invoke(claOS, null, "GetEventClass",
+					new Object[] {
+						theEvent
+					})).intValue();
+			//int eventKind = OS.GetEventKind(theEvent);
+
+			//System.out.println("appleEventProc " + OSXtoString(eventClass) + ";"
+			//		+ OS.GetEventKind(theEvent) + ";" + OSXtoString(theEvent) + ";"
+			//		+ OSXtoString(userData));
+
+			// Process the odoc event
+			if (eventClass == kEventClassAppleEvent) {
+				int[] aeEventID = new int[1];
+				// int GetEventParameter(int inEvent, int inName, int inDesiredType, 
+				// int[] outActualType, int inBufferSize, int[] outActualSize, int[] outData);
+
+				int ret = ((Number) invoke(claOS, null, "GetEventParameter",
+						new Class[] {
+							int.class,
+							int.class,
+							int.class,
+							int[].class,
+							int.class,
+							int[].class,
+							int[].class
+						}, new Object[] {
+							theEvent,
+							kEventParamAEEventID,
+							typeType,
+							null,
+							4,
+							null,
+							aeEventID
+						})).intValue();
+
+				if (ret != noErr) {
+					return eventNotHandledErr;
+				}
+				//System.out.println("EventID = " + OSXtoString(aeEventID[0]));
+				if (aeEventID[0] != kAEOpenDocuments && aeEventID[0] != kURLEventClass
+						&& aeEventID[0] != kAEReopenApplication
+						&& aeEventID[0] != kAEOpenContents
+						&& aeEventID[0] != kAEQuitApplication) {
+					return eventNotHandledErr;
+				}
 
-			// Handle Event
-			EventRecord eventRecord = new EventRecord();
-			OS.ConvertEventRefToEventRecord(theEvent, eventRecord);
-			OS.AEProcessAppleEvent(eventRecord);
+				// Handle Event
+				Object eventRecord = claEventRecord.newInstance();
+				invoke(claOS, null, "ConvertEventRefToEventRecord", new Class[] {
+					int.class,
+					claEventRecord
+				}, new Object[] {
+					theEvent,
+					eventRecord
+				});
+				invoke(claOS, null, "AEProcessAppleEvent", new Object[] {
+					eventRecord
+				});
 
-			// Tell Mac we are handling this event
-			return OS.noErr;
-		}
+				// Tell Mac we are handling this event
+				return noErr;
+			}
 
-		return OS.eventNotHandledErr;
+		} catch (Throwable e) {
+			Debug.out(e);
+		}
+		return eventNotHandledErr;
 	}
 
+	/*
 	private static String OSXtoString(int i) {
 		char[] c = new char[4];
 		c[0] = (char) ((i >> 24) & 0xff);
@@ -474,6 +710,7 @@ public class CarbonUIEnhancer
 		c[3] = (char) (i & 0xff);
 		return new String(c);
 	}
+	*/
 
 	private static void memmove(byte[] dest, int src, int size) {
 		switch (memmove_type) {
@@ -488,7 +725,7 @@ public class CarbonUIEnhancer
 
 			case 1:
 				try {
-					Class cMemMove = Class.forName("org.eclipse.swt.internal.carbon.OS");
+					Class<?> cMemMove = Class.forName("org.eclipse.swt.internal.carbon.OS");
 
 					Method method = cMemMove.getMethod("memmove", new Class[] {
 						byte[].class,
@@ -509,7 +746,7 @@ public class CarbonUIEnhancer
 				// FALL THROUGH
 			case 2:
 				try {
-					Class cMemMove = Class.forName("org.eclipse.swt.internal.carbon.OS");
+					Class<?> cMemMove = Class.forName("org.eclipse.swt.internal.carbon.OS");
 
 					Method method = cMemMove.getMethod("memcpy", new Class[] {
 						byte[].class,
@@ -537,67 +774,214 @@ public class CarbonUIEnhancer
 		memmove_type = 3;
 	}
 
-	final static Object target = new Object() {
-		int quitAppProc(int theAppleEvent, int reply, int handlerRefcon) {
-			UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-			if (uiFunctions != null) {
-				uiFunctions.dispose(false, false);
-			} else {
-				UIExitUtilsSWT.setSkipCloseCheck(true);
-				Display.getDefault().dispose();
+	final static int commandProc(int nextHandler, int theEvent, int userData) {
+		try {
+			int kind = ((Number) invoke(claOS, null, "GetEventKind", new Object[] {
+				theEvent
+			})).intValue();
+			if (kind == kEventProcessCommand) {
+				Object command = claHICommand.newInstance();
+				// int GetEventParameter(int inEvent, int inName, int inDesiredType, 
+				// int[] outActualType, int inBufferSize, int[] outActualSize, HICommand outData);
+				invoke(claOS, null, "GetEventParameter", new Class[] {
+					int.class,
+					int.class,
+					int.class,
+					int[].class,
+					int.class,
+					int[].class,
+					claHICommand
+				}, new Object[] {
+					theEvent,
+					kEventParamDirectObject,
+					typeHICommand,
+					null,
+					claHICommand.getField("sizeof").getInt(command),
+					null,
+					command
+				});
+				int commandID = claHICommand.getField("commandID").getInt(command);
+				switch (commandID) {
+					case kHICommandPreferences: {
+						UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+						if (uiFunctions != null) {
+							uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
+						}
+						return noErr;
+					}
+					case kHICommandAbout:
+						AboutWindow.show();
+						return noErr;
+					case kHICommandRestart: {
+						UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+						if (uiFunctions != null) {
+							uiFunctions.dispose(true, false);
+						}
+						return noErr;
+					}
+					case kHICommandWizard:
+						new ConfigureWizard(false,ConfigureWizard.WIZARD_MODE_FULL);
+						return noErr;
+					case kHICommandNatTest:
+						new NatTestWindow();
+						return noErr;
+					case kHICommandSpeedTest:
+						new SpeedTestWizard();
+						return noErr;
+
+					case kAEQuitApplication:
+						UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+						if (uiFunctions != null) {
+							uiFunctions.dispose(false, false);
+							return noErr;
+						} else {
+							UIExitUtilsSWT.setSkipCloseCheck(true);
+						}
+					default:
+						break;
+				}
 			}
-			return OS.noErr;
+		} catch (Throwable t) {
+			Debug.out(t);
+		}
+		return eventNotHandledErr;
+	}
+
+	final static int quitAppProc(int theAppleEvent, int reply, int handlerRefcon) {
+		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+		if (uiFunctions != null) {
+			uiFunctions.dispose(false, false);
+		} else {
+			UIExitUtilsSWT.setSkipCloseCheck(true);
+			Display.getDefault().dispose();
 		}
+		return noErr;
+	}
 
-		int openDocProc(int theAppleEvent, int reply, int handlerRefcon) {
-			AEDesc aeDesc = new AEDesc();
-			EventRecord eventRecord = new EventRecord();
-			OS.ConvertEventRefToEventRecord(theAppleEvent, eventRecord);
+	final static int openDocProc(int theAppleEvent, int reply, int handlerRefcon) {
+		try {
+			Object aeDesc = claAEDesc.newInstance();
+			Object eventRecord = claEventRecord.newInstance();
+			invoke(claOS, null, "ConvertEventRefToEventRecord", new Class[] {
+				int.class,
+				claEventRecord
+			}, new Object[] {
+				theAppleEvent,
+				eventRecord
+			});
 			try {
 				int result = OSXAccess.AEGetParamDesc(theAppleEvent,
-						OS.kEventParamDirectObject, typeAEList, aeDesc);
-				if (result != OS.noErr) {
+						kEventParamDirectObject, typeAEList, aeDesc);
+				if (result != noErr) {
 					Debug.out("OSX: Could call AEGetParamDesc. Error: " + result);
-					return OS.noErr;
+					return noErr;
 				}
 			} catch (java.lang.UnsatisfiedLinkError e) {
 				Debug.out("OSX: AEGetParamDesc not available.  Can't open sent file");
-				return OS.noErr;
+				return noErr;
 			}
 
 			int[] count = new int[1];
-			OS.AECountItems(aeDesc, count);
+			invoke(claOS, null, "AECountItems", new Class[] {
+				claAEDesc,
+				int[].class
+			}, new Object[] {
+				aeDesc,
+				count
+			});
 			//System.out.println("COUNT: " + count[0]);
 			if (count[0] > 0) {
 				final String[] fileNames = new String[count[0]];
 				int maximumSize = 80; // size of FSRef
-				int dataPtr = OS.NewPtr(maximumSize);
+				int dataPtr = ((Number) invoke(claOS, null, "NewPtr", new Object[] {
+					maximumSize
+				})).intValue();
 				int[] aeKeyword = new int[1];
 				int[] typeCode = new int[1];
 				int[] actualSize = new int[1];
 				for (int i = 0; i < count[0]; i++) {
-					if (OS.AEGetNthPtr(aeDesc, i + 1, OS.typeFSRef, aeKeyword, typeCode,
-							dataPtr, maximumSize, actualSize) == OS.noErr) {
-						byte[] fsRef = new byte[actualSize[0]];
-						memmove(fsRef, dataPtr, actualSize[0]);
-						int dirUrl = OS.CFURLCreateFromFSRef(OS.kCFAllocatorDefault, fsRef);
-						int dirString = OS.CFURLCopyFileSystemPath(dirUrl,
-								OS.kCFURLPOSIXPathStyle);
-						int length = OS.CFStringGetLength(dirString);
-						char[] buffer = new char[length];
-						CFRange range = new CFRange();
-						range.length = length;
-						OS.CFStringGetCharacters(dirString, range, buffer);
-						fileNames[i] = new String(buffer);
-						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);
+					try {
+						// int AEGetNthPtr(AEDesc theAEDescList, int index, int desiredType, 
+						// int[] theAEKeyword, int[] typeCode, int dataPtr, int maximumSize, int[] actualSize);
+						Class<?>[] sigAEGetNthPtr = new Class[] {
+							claAEDesc,
+							int.class,
+							int.class,
+							int[].class,
+							int[].class,
+							int.class,
+							int.class,
+							int[].class
+						};
+						int ret = ((Number) invoke(claOS, null, "AEGetNthPtr",
+								sigAEGetNthPtr, new Object[] {
+									aeDesc,
+									i + 1,
+									typeFSRef,
+									aeKeyword,
+									typeCode,
+									dataPtr,
+									maximumSize,
+									actualSize
+								})).intValue();
+						if (ret == noErr) {
+							byte[] fsRef = new byte[actualSize[0]];
+							memmove(fsRef, dataPtr, actualSize[0]);
+							int dirUrl = ((Number) invoke(claOS, null,
+									"CFURLCreateFromFSRef", new Object[] {
+										kCFAllocatorDefault,
+										fsRef
+									})).intValue();
+							int dirString = ((Number) invoke(claOS, null,
+									"CFURLCopyFileSystemPath", new Object[] {
+										dirUrl,
+										kCFURLPOSIXPathStyle
+									})).intValue();
+							int length = ((Number) invoke(claOS, null, "CFStringGetLength",
+									new Object[] {
+										dirString
+									})).intValue();
+							char[] buffer = new char[length];
+							Object range = claCFRange.newInstance();
+							claCFRange.getField("length").setInt(range, length);
+							invoke(claOS, null, "CFStringGetCharacters", new Class[] {
+								int.class,
+								claCFRange,
+								char[].class
+							}, new Object[] {
+								dirString,
+								range,
+								buffer
+							});
+							fileNames[i] = new String(buffer);
+							invoke(claOS, null, "CFRelease", new Object[] {
+								dirString
+							});
+							invoke(claOS, null, "CFRelease", new Object[] {
+								dirUrl
+							});
+						} else {
+							ret = ((Number) invoke(claOS, null, "AEGetNthPtr",
+									sigAEGetNthPtr, new Object[] {
+										aeDesc,
+										i + 1,
+										typeText,
+										aeKeyword,
+										typeCode,
+										dataPtr,
+										2048,
+										actualSize
+									})).intValue();
+
+							if (ret == noErr) {
+								byte[] urlRef = new byte[actualSize[0]];
+								memmove(urlRef, dataPtr, actualSize[0]);
+								fileNames[i] = new String(urlRef);
+							}
+						}
+					} catch (Throwable t) {
+						Debug.out(t);
 					}
-
 					//System.out.println(fileNames[i]);
 				}
 
@@ -608,65 +992,125 @@ public class CarbonUIEnhancer
 				});
 			}
 
-			return OS.noErr;
+			return noErr;
+		} catch (Throwable e) {
+			Debug.out(e);
 		}
+		return eventNotHandledErr;
+	}
 
-		int clickDockIcon(int nextHandler, int theEvent, int userData) {
-			UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-			if (uiFunctions != null) {
-				uiFunctions.bringToFront();
-				return OS.noErr;
-			}
-			return OS.eventNotHandledErr;
+	final static int clickDockIcon(int nextHandler, int theEvent, int userData) {
+		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+		if (uiFunctions != null) {
+			uiFunctions.bringToFront();
+			return noErr;
 		}
+		return eventNotHandledErr;
+	}
+
+	final static int openContents(int nextHandler, int theEvent, int userData) {
+		Debug.out("openDocContents");
+		return noErr;
+	}
 
-		int openContents(int nextHandler, int theEvent, int userData) {
-			Debug.out("openDocContents");
-			return OS.noErr;
+	final static int toolbarToggle(int nextHandler, int theEvent, int userData) {
+		int eventKind = ((Number) invoke(claOS, null, "GetEventKind", new Object[] {
+			theEvent
+		})).intValue();
+		if (eventKind != kEventWindowToolbarSwitchMode) {
+			return eventNotHandledErr;
 		}
 
-		int toolbarToggle(int nextHandler, int theEvent, int userData) {
-			int eventKind = OS.GetEventKind(theEvent);
-			if (eventKind != OS.kEventWindowToolbarSwitchMode) {
-				return OS.eventNotHandledErr;
-			}
+		int[] theWindow = new int[1];
+		//int GetEventParameter(int inEvent, int inName, int inDesiredType, 
+		// int[] outActualType, int inBufferSize, int[] outActualSize, int[] outData);
+		invoke(claOS, null, "GetEventParameter", new Class[] {
+			int.class,
+			int.class,
+			int.class,
+			int[].class,
+			int.class,
+			int[].class,
+			int[].class
+		}, new Object[] {
+			theEvent,
+			kEventParamDirectObject,
+			typeWindowRef,
+			null,
+			4,
+			null,
+			theWindow
+		});
 
-			int[] theWindow = new int[1];
-			OS.GetEventParameter(theEvent, OS.kEventParamDirectObject,
-					OS.typeWindowRef, null, 4, null, theWindow);
+		int[] theRoot = new int[1];
+		invoke(claOS, null, "GetRootControl", new Object[] {
+			theWindow[0],
+			theRoot
+		});
+		final Widget widget = Display.getCurrent().findWidget(theRoot[0]);
 
-			int[] theRoot = new int[1];
-			OS.GetRootControl(theWindow[0], theRoot);
-			final Widget widget = Display.getCurrent().findWidget(theRoot[0]);
+		if (!(widget instanceof Shell)) {
+			return eventNotHandledErr;
+		}
+		final Shell shellAffected = (Shell) widget;
 
-			if (!(widget instanceof Shell)) {
-				return OS.eventNotHandledErr;
-			}
-			final Shell shellAffected = (Shell) widget;
+		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;
+				}
 
-			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 = widget.getDisplay();
+				event.widget = widget;
+				shellAffected.notifyListeners(type, event);
+
+				shellAffected.setData("OSX.ToolBarToggle", new Long(
+						type == SWT.Collapse ? 1 : 0));
+			}
+		});
 
-					Event event = new Event();
-					event.type = type;
-					event.display = widget.getDisplay();
-					event.widget = widget;
-					shellAffected.notifyListeners(type, event);
+		return noErr;
+	}
 
-					shellAffected.setData("OSX.ToolBarToggle", new Long(
-							type == SWT.Collapse ? 1 : 0));
-				}
-			});
+	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);
+		}
+	}
 
-			return OS.noErr;
+	private static Object invoke(Class<?> clazz, Object target,
+			String methodName, Class<?>[] signature, Object[] args) {
+		try {
+			Method method = clazz.getDeclaredMethod(methodName, signature);
+			method.setAccessible(true);
+			return method.invoke(target, args);
+		} catch (Exception e) {
+			throw new IllegalStateException(e);
 		}
-	};
+	}
 
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java b/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java
index ee1b4da..f9430bb 100644
--- a/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java
+++ b/org/gudy/azureus2/ui/swt/osx/CocoaUIEnhancer.java
@@ -3,17 +3,17 @@ package org.gudy.azureus2.ui.swt.osx;
 import java.lang.reflect.*;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 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.eclipse.swt.widgets.*;
 
 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.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
 import org.gudy.azureus2.ui.swt.help.AboutWindow;
@@ -61,9 +61,6 @@ public class CocoaUIEnhancer
 
 	private static CocoaUIEnhancer instance;
 
-	private static final int kAboutMenuItem = 0;
-
-	private static final int kPreferencesMenuItem = 2;
 
 	private static final int kServicesMenuItem = 4;
 
@@ -81,25 +78,15 @@ public class CocoaUIEnhancer
 
 	//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_applicationShouldHandleReopen_;
 
 	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_;
+	private static boolean alreadyHaveOpenDoc;
 
 	static final byte[] SWT_OBJECT = {
 		'S',
@@ -121,13 +108,14 @@ public class CocoaUIEnhancer
 
 	private Object delegate;
 
+	private static boolean initialized = false;
+
 	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");
@@ -135,10 +123,18 @@ public class CocoaUIEnhancer
 	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 {
+			SWT.class.getDeclaredField("OpenDocument");
+			alreadyHaveOpenDoc = true;
+		} catch (Throwable t) {
+			alreadyHaveOpenDoc = false;
+		}
+
+		try {
 			Method mGetAddress = callbackCls.getMethod("getAddress", new Class[0]);
 			Constructor<?> consCallback = callbackCls.getConstructor(new Class<?>[] {
 				Object.class,
@@ -173,25 +169,18 @@ public class CocoaUIEnhancer
 		}
 	}
 
-	static int actionProc(int id, int sel, int arg0) {
+	static int /*long*/actionProc(int /*long*/id, int /*long*/sel,
+			int /*long*/arg0) {
+		return actionProc(id, sel, arg0);
+	}
+
+	static long actionProc(long id, long sel,
+			long 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_) {
+		if (sel == sel_toolbarButtonClicked_) {
 			try {
 				Field fldsel_window = osCls.getField("sel_window");
 				Object windowId = invoke(osCls, "objc_msgSend", new Object[] {
@@ -227,11 +216,6 @@ public class CocoaUIEnhancer
 				Debug.out(t);
 			}
 
-		} else if (sel == sel_preferencesMenuItemSelected_) {
-			UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-			if (uiFunctions != null) {
-				uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
-			}
 		}
 		return 0;
 	}
@@ -239,6 +223,13 @@ public class CocoaUIEnhancer
 	static int /*long*/actionProc(int /*long*/id, int /*long*/sel,
 			int /*long*/arg0, int /*long*/arg1)
 			throws Throwable {
+		return actionProc(id, sel, arg0, arg1);
+	}
+
+	
+	static long actionProc(long id, long sel,
+			long arg0, long arg1)
+			throws Throwable {
 		if (DEBUG) {
 			System.err.println("actionProc 4 " + id + "/" + sel);
 		}
@@ -246,7 +237,7 @@ public class CocoaUIEnhancer
 		if (display == null)
 			return 0;
 
-		if (sel == sel_application_openFile_) {
+		if (!alreadyHaveOpenDoc && sel == sel_application_openFile_) {
 			Constructor<?> conNSString = nsstringCls.getConstructor(new Class[] {
 				int.class
 			});
@@ -258,7 +249,7 @@ public class CocoaUIEnhancer
 			fileOpen(new String[] {
 				fileString
 			});
-		} else if (sel == sel_application_openFiles_) {
+		} else if (!alreadyHaveOpenDoc && sel == sel_application_openFiles_) {
 			Constructor<?> conNSArray = nsarrayCls.getConstructor(new Class[] {
 				int.class
 			});
@@ -450,14 +441,6 @@ public class CocoaUIEnhancer
 	 * 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();
@@ -494,6 +477,10 @@ public class CocoaUIEnhancer
 
 	public void hookDocumentOpen()
 			throws Throwable {
+		
+		if (alreadyHaveOpenDoc) {
+			return;
+		}
 
 		if (sel_application_openFile_ == 0) {
 			sel_application_openFile_ = registerName(osCls, "application:openFile:");
@@ -516,65 +503,16 @@ public class CocoaUIEnhancer
 		});
 	}
 
-	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:");
-			sel_applicationShouldHandleReopen_ = registerName(osCls, "applicationShouldHandleReopen:hasVisibleWindows:");
+	static MenuItem getItem(Menu menu, int id) {
+		MenuItem[] items = menu.getItems();
+		for (int i = 0; i < items.length; i++) {
+			if (items[i].getID() == id) return items[i];
 		}
+		return null;
+	}
 
-		// 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),
-			"@:@"
-		});
-		invoke(osCls, "class_addMethod", new Object[] {
-			wrapPointer(delegateIdSWTApplication),
-			wrapPointer(sel_applicationShouldHandleReopen_),
-			wrapPointer(callBack4Addr),
-			"@:@c"
-		});
+	private void initialize()
+			throws Exception {
 
 		// Get the Mac OS X Application menu.
 		Object sharedApplication = invoke(nsapplicationCls, "sharedApplication");
@@ -585,21 +523,8 @@ public class CocoaUIEnhancer
 				});
 		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
-		});
 
+		// disable services menu
 		Object servicesMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
 				new Object[] {
 					wrapPointer(kServicesMenuItem)
@@ -608,101 +533,95 @@ public class CocoaUIEnhancer
 			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"));
+		Menu systemMenu = Display.getCurrent().getSystemMenu();
+		if (systemMenu != null) {
 
-		if (!isAZ3) {
-			// add Wizard, NAT Test, Speed Test
+			MenuItem sysItem = getItem(systemMenu, SWT.ID_ABOUT);
+			if (sysItem != null) {
+				sysItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						AboutWindow.show();
+					};
+				});
+			}
 
-			addMenuItem(menuId, 5, (int) sel_wizardMenuSelected_,
-					MessageText.getString("MainWindow.menu.file.configure").replaceAll(
-							"&", ""));
+			sysItem = getItem(systemMenu, SWT.ID_PREFERENCES);
+			if (sysItem != null) {
+				sysItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+						if (uiFunctions != null) {
+							uiFunctions.openView(UIFunctions.VIEW_CONFIG, null);
+						}
+					};
+				});
+			}
 
-			addMenuItem(menuId, 6, (int) sel_natMenuSelected_, MessageText.getString(
-					"MainWindow.menu.tools.nattest").replaceAll("&", ""));
+			int quitIndex = systemMenu.indexOf(getItem(systemMenu, SWT.ID_QUIT));
+			MenuItem restartItem = new MenuItem(systemMenu, SWT.CASCADE, quitIndex);
+			Messages.setLanguageText(restartItem, "MainWindow.menu.file.restart");
+			restartItem.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+					if (uiFunctions != null) {
+						uiFunctions.dispose(true, false);
+					}
+				}
+			});
 
-			addMenuItem(menuId, 7, (int) sel_speedMenuSelected_,
-					MessageText.getString("MainWindow.menu.tools.speedtest").replaceAll(
-							"&", ""));
+			// Add other menus
+			boolean isAZ3 = "az3".equalsIgnoreCase(COConfigurationManager.getStringParameter("ui"));
 
-		}
+			if (!isAZ3) {
+				// add Wizard, NAT Test, Speed Test
 
-		int numOfItems = ((Number) invoke(appMenu, "numberOfItems")).intValue();
+				int prefIndex = systemMenu.indexOf(getItem(systemMenu,
+						SWT.ID_PREFERENCES)) + 1;
+				MenuItem wizItem = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
+				Messages.setLanguageText(wizItem, "MainWindow.menu.file.configure");
+				wizItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						new ConfigureWizard(false, ConfigureWizard.WIZARD_MODE_FULL);
+					}
+				});
 
-		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
-		});
+				MenuItem natMenu = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
+				Messages.setLanguageText(natMenu, "MainWindow.menu.tools.nattest");
+				natMenu.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						new NatTestWindow();
+					}
+				});
 
-		numOfItems++;
+				MenuItem speedMenu = new MenuItem(systemMenu, SWT.CASCADE, prefIndex);
+				Messages.setLanguageText(speedMenu, "MainWindow.menu.tools.speedtest");
+				speedMenu.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						new SpeedTestWizard();
+					}
+				});
 
-		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");
+		// Register names in objective-c.
+		if (sel_applicationShouldHandleReopen_ == 0) {
+			sel_applicationShouldHandleReopen_ = registerName(osCls, "applicationShouldHandleReopen:hasVisibleWindows:");
+		}
 
-			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)
-			});
+		// Add the action callbacks for menu items.
+		invoke(osCls, "class_addMethod", new Object[] {
+			wrapPointer(delegateIdSWTApplication),
+			wrapPointer(sel_applicationShouldHandleReopen_),
+			wrapPointer(callBack4Addr),
+			"@:@c"
+		});
 
-			//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);
-		}
+		initialized = true;
 	}
 
+
 	private Object invoke(Class<?> cls, String methodName) {
 		return invoke(cls, methodName, (Class<?>[]) null, (Object[]) null);
 	}
@@ -863,4 +782,8 @@ public class CocoaUIEnhancer
 		return null;
 	}
 
+
+	public static boolean isInitialized() {
+		return initialized;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/plugins/PluginUISWTSkinObject.java b/org/gudy/azureus2/ui/swt/plugins/PluginUISWTSkinObject.java
new file mode 100644
index 0000000..eb5c9d6
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/plugins/PluginUISWTSkinObject.java
@@ -0,0 +1,9 @@
+package org.gudy.azureus2.ui.swt.plugins;
+
+/**
+ * Don't use me :)
+ *
+ */
+public interface PluginUISWTSkinObject
+{
+}
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTAWTPluginView.java b/org/gudy/azureus2/ui/swt/plugins/UISWTAWTPluginView.java
deleted file mode 100644
index 69d493a..0000000
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTAWTPluginView.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Created on 06-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 org.gudy.azureus2.ui.swt.plugins;
-
-import java.awt.Component;
-
-/**
- * 
- * @deprecated Use {@link org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(String, String, UISWTViewEventListener)}
- */
-public interface 
-UISWTAWTPluginView 
-{
-	public String 
-	getPluginViewName();
-	
-		/**
-		 * Create an AWT component for this view instance
-		 * @return
-		 */
-	
-	public Component
-	create();
-	
-		/**
-		 * The view instance is visible 
-		 * @param component
-		 */
-	
-	public void
-	open(
-		Component	component );
-	
-		/**
-		 * The view instance has been closed
-		 * @param component
-		 */
-	
-	public void 
-	delete(
-		Component	component );
-}
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java b/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
index f5cd95c..5c971e4 100644
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
+++ b/org/gudy/azureus2/ui/swt/plugins/UISWTInstance.java
@@ -31,6 +31,7 @@ import org.gudy.azureus2.plugins.ui.UIInstance;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
 import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.common.UIInstanceBase;
 
 /**
  * Tools to manage a SWT Instance
@@ -38,7 +39,7 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
  * @see org.gudy.azureus2.plugins.ui.UIManagerListener
  * @see org.gudy.azureus2.plugins.ui.UIManager#addUIListener(UIManagerListener)
  */
-public interface UISWTInstance extends UIInstance {
+public interface UISWTInstance extends UIInstanceBase {
 	/** ID of main view */
 	public static final String VIEW_MAIN = "Main";
 
@@ -77,6 +78,9 @@ public interface UISWTInstance extends UIInstance {
 	 */
 	public static final String VIEW_TOPBAR = "TopBar";
 
+	public static final String VIEW_STATISTICS = "StatsView";
+
+	
 	/** Retrieve the SWT Display object that Azureus uses (when in SWT mode).
 	 * If you have a thread that does some periodic/asynchronous stuff, Azureus 
 	 * will crashes with and 'InvalidThreadAccess' exception unless you
@@ -120,6 +124,27 @@ public interface UISWTInstance extends UIInstance {
 	public void addView(String sParentID, String sViewID, UISWTViewEventListener l);
 
 	/**
+	 * Add a view to an Azureus parent view.  For views added to the {@link #VIEW_MAIN}
+	 * window, this adds a menu option.<P>
+	 * In comparison to {@link #addView(String, String, UISWTViewEventListener)},
+	 * this method saves memory by not creating the {@link UISWTViewEventListener}
+	 * until it is needed.  It also ensures that only one 
+	 * {@link UISWTViewEvent#TYPE_CREATE} event is triggered per instance.
+	 * 
+	 * @param sParentID VIEW_* constant
+	 * @param sViewID of your view.  Used as part of the resource id.<br>
+	 *          "Views.plugins." + ID + ".title" = title of your view
+	 * @param l Class of the Listener to be created and triggered
+	 *           
+	 * @note If you want the window to auto-open, use openMainView when you gain
+	 *        access to the UISWTInstance
+	 *
+	 * @since 4.6.0.5
+	 */
+	public void addView(String sParentID, String sViewID,
+			Class<? extends UISWTViewEventListener> cla, Object initalDatasource);
+
+	/**
 	 * Open a previously added view
 	 * 
 	 * @param sParentID ParentID of the view to be shown
@@ -204,45 +229,9 @@ public interface UISWTInstance extends UIInstance {
 	 */
 	public UISWTView[] getOpenViews(String sParentID);
 
-	/**
-	 * A Plugin might call this method to add a View to Azureus's views
-	 * The View will be accessible from View > Plugins > View name
-	 * @param view The PluginView to be added
-	 * @param autoOpen Whether the plugin should auto-open at startup
-	 *
-	 * @since 2.3.0.5
-	 * @deprecated Use {@link #addView(String, String, UISWTViewEventListener)}
-	 */
-
-	public void addView(UISWTPluginView view, boolean autoOpen);
-
-	/**
-	 * Remove a view
-	 * @param view
-	 * 
-	 * @since 2.3.0.5
-	 * @deprecated Use {@link #removeViews(String, String)}
-	 */
-	public void removeView(UISWTPluginView view);
-
-	/**
-	 * Add an AWT panel as the plugin view
-	 * @param view
-	 * @param auto_open
-	 * 
-	 * @since 2.3.0.5
-	 * @deprecated Use {@link #addView(String, String, UISWTViewEventListener)}
-	 */
-	public void addView(UISWTAWTPluginView view, boolean auto_open);
-
-	/**
-	 * Remove a view
-	 * @param view
-	 * 
-	 * @since 2.3.0.5
-	 * @deprecated Use {@link #removeViews(String, String)}
-	 */
-	public void removeView(UISWTAWTPluginView view);
+	public UISWTViewEventListenerWrapper[] 
+	getViewListeners(
+		String sParentID );
 	
 	/**
 	 * Shows or hides a download bar for a given download.
@@ -293,6 +282,13 @@ public interface UISWTInstance extends UIInstance {
 	 * 
 	 * @since 4.2.0.9
 	 */
-	Shell createShell(int style);
+	public Shell createShell(int style);
 
+	public interface
+	UISWTViewEventListenerWrapper
+		extends UISWTViewEventListener
+	{
+		public String
+		getViewID();
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTPluginView.java b/org/gudy/azureus2/ui/swt/plugins/UISWTPluginView.java
deleted file mode 100644
index 31198cf..0000000
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTPluginView.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * File    : PluginView.java
- * Created : 2 nov. 2003 20:58:14
- * By      : Olivier 
- * 
- * 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.swt.plugins;
-
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-
-/**
- * This Class must be extended by Plugin willing to have their own view in Azureus
- * @author Olivier
- * 
- * @deprecated Use {@link org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(String, String, UISWTViewEventListener)}
- */
-public abstract class 
-UISWTPluginView 
-	extends AbstractIView 
-{
-  /**
-   * @return The name of the Plugin, as seen in the View > Plugins menu
-   *
-   * @since 2.0.4.0
-   */
-	
-  public abstract String 
-  getPluginViewName();
-}
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTView.java b/org/gudy/azureus2/ui/swt/plugins/UISWTView.java
index 1312d27..2f38f48 100644
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTView.java
+++ b/org/gudy/azureus2/ui/swt/plugins/UISWTView.java
@@ -24,6 +24,7 @@
 
 package org.gudy.azureus2.ui.swt.plugins;
 
+import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.ui.UIPluginView;
 
 /**
@@ -65,6 +66,14 @@ public interface UISWTView extends UIPluginView {
 	 */
 	public void setControlType(int iControlType);
 
+	/**
+	 * 
+	 * @return CONTROLTYPE_*
+	 * 
+	 * @since 4.3.1.3
+	 */
+	int getControlType();
+
 	/** 
 	 * Retrieve the data sources related to this view.
 	 *   
@@ -105,4 +114,12 @@ public interface UISWTView extends UIPluginView {
 	 * @since 2.3.0.6
 	 */
 	public void setTitle(String title);
+	
+	/**
+	 * Gets the plugin interface associated with this view, null if none defined
+	 * 
+	 * @since 4.5.1.1
+	 */
+	public PluginInterface getPluginInterface();
+	
 }
diff --git a/org/gudy/azureus2/ui/swt/plugins/UISWTViewEvent.java b/org/gudy/azureus2/ui/swt/plugins/UISWTViewEvent.java
index b16793b..d50e1a8 100644
--- a/org/gudy/azureus2/ui/swt/plugins/UISWTViewEvent.java
+++ b/org/gudy/azureus2/ui/swt/plugins/UISWTViewEvent.java
@@ -120,6 +120,16 @@ public interface UISWTViewEvent {
 	 */
 	public static final int TYPE_CLOSE = 8;
 
+
+	/**
+	 * Triggered when the UI needs a privacy sensitive view.
+	 * <P>
+	 * Currently, getData() will return a map, with "image" key containing Image
+	 * 
+	 *  @since 4.7.0.3
+	 */
+	public static final int TYPE_OBFUSCATE = 9;
+
 	/**
 	 * Get the type.
 	 * 
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
index 72e1b8f..f815aa0 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginConfigImpl.java
@@ -58,6 +58,7 @@ import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.components.LinkLabel;
+import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
 import org.gudy.azureus2.ui.swt.plugins.UISWTParameterContext;
 
@@ -227,10 +228,29 @@ BasicPluginConfigImpl
 
 				label = new Label(current_composite, (param instanceof LabelParameterImpl) ? SWT.WRAP : SWT.NULL);
 	
+				boolean	add_copy;
+				
 				if ( label_key == null ){	
 					label.setText( param.getLabelText());
+					add_copy = true;
 				}else{
 					Messages.setLanguageText(label, label_key );
+					add_copy = label_key.startsWith( "!" );
+				}
+				
+				if ( add_copy ){
+					final Label f_label = label;
+					
+					ClipboardCopy.addCopyToClipMenu(
+							label,
+							new ClipboardCopy.copyToClipProvider()
+							{
+								public String 
+								getText() 
+								{
+									return( f_label.getText().trim());
+								}
+							});
 				}
 				
 				if (hyperlink != null) {
@@ -716,9 +736,16 @@ BasicPluginConfigImpl
 								(Control[]) controlsToDisable.toArray(cd));
 				    
 	
-				    BooleanParameter	target = (BooleanParameter)((Object[])comp_map.get(param))[0];
+				    Object[] data = (Object[])comp_map.get(param);
+				    
+				    	// might not be visible (e.g. user mode too low) in which case it won't be in the map
 				    
-				    target.setAdditionalActionPerformer(ap);
+				    if ( data != null ){
+				    	
+					    BooleanParameter	target = (BooleanParameter)data[0];
+					    
+					    target.setAdditionalActionPerformer(ap);
+				    }
 				}
 			}
 		}
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginViewImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginViewImpl.java
index a89bff8..80d747e 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginViewImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/BasicPluginViewImpl.java
@@ -42,6 +42,7 @@ import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.components.BufferedLabel;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 
@@ -80,17 +81,33 @@ BasicPluginViewImpl
     isCreated = false;
   }
   
+  public BasicPluginViewModel
+  getModel()
+  {
+	  return( model );
+  }
+  
 	public boolean eventOccurred(UISWTViewEvent event) {
 		switch (event.getType()) {
-			case UISWTViewEvent.TYPE_CREATE:
+			case UISWTViewEvent.TYPE_CREATE: {
 				if (isCreated)
 					return false;
 				isCreated = true;
+				UISWTView swtView = event.getView();
+				if (swtView != null) {
+					swtView.setTitle(model.getName());
+				}
 				break;
+			}
 				
-			case UISWTViewEvent.TYPE_INITIALIZE:
+			case UISWTViewEvent.TYPE_INITIALIZE: {
 				initialize((Composite)event.getData());
+				UISWTView swtView = event.getView();
+				if (swtView != null) {
+					swtView.setTitle(model.getName());
+				}
 				break;
+			}
 			
 			case UISWTViewEvent.TYPE_REFRESH:
 				refresh();
@@ -100,6 +117,23 @@ BasicPluginViewImpl
 				delete();
 				isCreated = false;
 				break;
+			
+			case UISWTViewEvent.TYPE_FOCUSGAINED:
+		   	String	text = model.getLogArea().getText().trim();
+		   	
+		   	if (log != null && !log.isDisposed()) {
+  	    	log.setText( text);
+  	    	
+  	    	log.setTopIndex(log.getLineCount());
+		   	}
+				break;
+				
+			case UISWTViewEvent.TYPE_FOCUSLOST:
+		   	if (log != null && !log.isDisposed()) {
+		   		log.setText("");
+		   	}
+				break;
+				
 		}
 		return true;
 	}
@@ -310,34 +344,7 @@ BasicPluginViewImpl
 		});
 
     }
-    
-	composite.addListener(
-			SWT.Hide,
-			new Listener()
-			{
-				public void 
-				handleEvent(
-					Event arg0 )
-				{
-					log.setText("");
-				}
-			});
 	
-	composite.addListener(
-			SWT.Show,
-			new Listener()
-			{
-				public void 
-				handleEvent(
-					Event arg0 )
-				{
-				   	String	text = model.getLogArea().getText().trim();
-				   	
-			    	log.setText( text);
-			    	
-			    	log.setTopIndex(log.getLineCount());
-				}
-			});
   }
   
   private void refresh() {
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTGraphicImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTGraphicImpl.java
index 69f8207..eee7746 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTGraphicImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTGraphicImpl.java
@@ -28,18 +28,13 @@ import org.eclipse.swt.graphics.Image;
 
 import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
 
-import org.gudy.azureus2.plugins.ui.SWT.GraphicSWT;
-import org.gudy.azureus2.plugins.ui.SWT.SWTManager;
-
 /** An SWT image to be used in Azureus
  *
  * @see SWTManager.createGraphic
  */
 public class 
 UISWTGraphicImpl 
-	implements UISWTGraphic, GraphicSWT 	// we *have* to implement GraphicsSWT as there are plugins
-											// out there (e.g. ProgressBar) that assume that
-											// Graphics returned to them are instances of GraphicsSWT
+	implements UISWTGraphic
 {
 	Image img;
   
@@ -60,4 +55,19 @@ UISWTGraphicImpl
     img = newImage;
     return true;
   }
+  
+  @Override
+  public boolean equals(Object obj) {
+  	if (super.equals(obj)) {
+  		return true;
+  	}
+  	if (obj instanceof UISWTGraphic) {
+  		Image img2 = ((UISWTGraphic) obj).getImage();
+  		if (img2 == null) {
+  			return img == null;
+  		}
+  		return img2.equals(img);
+  	}
+  	return false;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
index 28430f1..f4ac1ca 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTInstanceImpl.java
@@ -22,22 +22,18 @@
 
 package org.gudy.azureus2.ui.swt.pluginsimpl;
 
-import java.awt.*;
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
 import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
+import java.util.*;
 
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.awt.SWT_AWT;
 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.Display;
+import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.download.DownloadManager;
@@ -45,6 +41,8 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.AETemporaryFileHandler;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginEvent;
+import org.gudy.azureus2.plugins.PluginEventListener;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.torrent.Torrent;
@@ -55,9 +53,12 @@ import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
 import org.gudy.azureus2.plugins.ui.tables.TableColumn;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
 import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 import org.gudy.azureus2.pluginsimpl.local.ui.UIManagerImpl;
+import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionRepository;
 import org.gudy.azureus2.ui.common.util.MenuItemManager;
 import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
@@ -66,17 +67,16 @@ import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
 import org.gudy.azureus2.ui.swt.minibar.DownloadBar;
 import org.gudy.azureus2.ui.swt.plugins.*;
 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableContextMenuManager;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.ui.IUIIntializer;
 import com.aelitis.azureus.ui.UIFunctions;
-import com.aelitis.azureus.ui.UIFunctionsManager;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableStructureEventDispatcher;
 import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
@@ -86,24 +86,25 @@ UISWTInstanceImpl
 {
 	private AzureusCore		core;
 	
-	private Map<UISWTAWTPluginView,UISWTPluginView> 			awt_view_map 	= new WeakHashMap<UISWTAWTPluginView,UISWTPluginView>();
 	private Map<BasicPluginConfigModel,BasicPluginConfigImpl> 	config_view_map = new WeakHashMap<BasicPluginConfigModel,BasicPluginConfigImpl>();
 	
-	private Map<String,Map<String,UISWTViewEventListener>> views = new HashMap<String,Map<String,UISWTViewEventListener>>();
-	
+	// Map<Parent ID, Map<ViewID, Event Listener>>
+	private Map<String,Map<String,UISWTViewEventListenerHolder>> views = new HashMap<String,Map<String,UISWTViewEventListenerHolder>>();
+
 	private Map<PluginInterface,UIInstance>	plugin_map = new WeakHashMap<PluginInterface,UIInstance>();
+	private Map<PluginInterface,toolbarWrapper>	toolbar_map = new WeakHashMap<PluginInterface,toolbarWrapper>();
 	
 	private boolean bUIAttaching;
 
 	private final UIFunctionsSWT uiFunctions;
-	
+
 	
 	public UISWTInstanceImpl(AzureusCore _core) {
 		core		= _core;
 
 		// Since this is a UI **SWT** Instance Implementor, it's assumed
 		// that the UI Functions are of UIFunctionsSWT 
-		uiFunctions = (UIFunctionsSWT) UIFunctionsManager.getUIFunctions();
+		uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
 	}
 	
 	public void init(IUIIntializer init) {
@@ -121,7 +122,7 @@ UISWTInstanceImpl
 	getInstance(
 		PluginInterface		plugin_interface )
 	{
-		UIInstance	instance = (UIInstance)plugin_map.get( plugin_interface );
+		UIInstance	instance = plugin_map.get( plugin_interface );
 		
 		if ( instance == null ){
 			
@@ -263,14 +264,10 @@ UISWTInstanceImpl
 						URL 		target 				= (URL) params[0];
 						URL 		referrer 			= (URL) params[1];
 						boolean 	auto_download 		= ((Boolean) params[2]).booleanValue();
-						Map			request_properties	= (Map)params[3];
+						Map<?, ?>			request_properties	= (Map<?, ?>)params[3];
 						
 						// programmatic request to add a torrent, make sure az is visible
 
-						if (!COConfigurationManager.getBooleanParameter("add_torrents_silently")) {
-							uiFunctions.bringToFront();
-						}
-
 						if (auto_download) {
 							Shell shell = uiFunctions.getMainShell();
 							if (shell != null) {
@@ -329,7 +326,7 @@ UISWTInstanceImpl
 					   
 					config_view_map.put( model, view );
 					
-					model.getPluginInterface().addConfigSection( view );
+			  	ConfigSectionRepository.getInstance().addConfigSection(view, model.getPluginInterface());
 				}
 				
 				break;
@@ -340,11 +337,12 @@ UISWTInstanceImpl
 					
 					BasicPluginConfigModel	model = (BasicPluginConfigModel)data;
 					
-					BasicPluginConfigImpl view = (BasicPluginConfigImpl)config_view_map.get( model );
+					BasicPluginConfigImpl view = config_view_map.get( model );
 					   
 					if ( view != null ){
 						
-						model.getPluginInterface().removeConfigSection( view );
+				  	ConfigSectionRepository.getInstance().removeConfigSection(view);
+
 					}
 				}
 				
@@ -365,7 +363,7 @@ UISWTInstanceImpl
 			case UIManagerEvent.ET_CREATE_TABLE_COLUMN:{
 				
 				if (data instanceof TableColumn) {
-					event.setResult((TableColumn) data);
+					event.setResult(data);
 				} else {
 					String[] args = (String[]) data;
 
@@ -399,7 +397,7 @@ UISWTInstanceImpl
 				
 				TableColumnManager tcManager = TableColumnManager.getInstance();
 				
-				Class 	dataSource 	= (Class)params[0];
+				Class<?> 	dataSource 	= (Class<?>)params[0];
 				String	columnName	= (String)params[1];
 				
 				tcManager.registerColumn(dataSource, columnName, (TableColumnCreationListener)params[2]);
@@ -425,7 +423,7 @@ UISWTInstanceImpl
 				
 				TableColumnManager tcManager = TableColumnManager.getInstance();
 				
-				Class 	dataSource 	= (Class)params[0];
+				Class<?> 	dataSource 	= (Class<?>)params[0];
 				String	columnName	= (String)params[1];
 
 				tcManager.unregisterColumn(dataSource, columnName, (TableColumnCreationListener)params[2]);
@@ -522,6 +520,12 @@ UISWTInstanceImpl
 		if ( is != null ){
 		        
 			ImageData imageData = new ImageData(is);
+			
+			try {
+				is.close();
+			} catch (IOException e) {
+				Debug.out(e);
+			}
 		    
 			return new Image(getDisplay(), imageData);
 		}
@@ -543,133 +547,6 @@ UISWTInstanceImpl
 	}
   
 
-	/** @deprecated */
-	public void addView(final UISWTPluginView view, boolean bAutoOpen) {
-		// Currently used by firefrog.
-		try {
-			uiFunctions.addPluginView(view);
-			if (bAutoOpen) {
-				uiFunctions.openPluginView(view);
-			}
-		} catch (Throwable e) {
-			// SWT not available prolly
-		}
-	} 
-  
-
-	public void removeView(UISWTPluginView view) {
-		try {
-			uiFunctions.removePluginView(view);
-		} catch (Throwable e) {
-			// SWT not available prolly
-		}
-	}
-
-	/** @deprecated */
-	public void
-	addView(
-		UISWTAWTPluginView			view,
-		boolean						auto_open )
-	{
-		final WeakReference<UISWTAWTPluginView> view_ref = new WeakReference<UISWTAWTPluginView>( view );
-		
-		UISWTPluginView	v = 
-			new UISWTPluginView()
-			{
-				Composite		composite;
-				Component		component;
-				
-				boolean	first_paint = true;
-				
-				public String
-				getPluginViewName()
-				{
-					return( view_ref.get().getPluginViewName());
-				}
-				
-				public String 
-				getFullTitle() 
-				{
-					return( view_ref.get().getPluginViewName());
-				}
-				 
-				public void 
-				initialize(
-					Composite _composite )
-				{
-					first_paint	= true;
-					
-					composite	= _composite;
-					
-					Composite frame_composite = new Composite(composite, SWT.EMBEDDED);
-	
-					GridData data = new GridData(GridData.FILL_BOTH);
-					
-					frame_composite.setLayoutData(data);
-	
-					Frame	f = SWT_AWT.new_Frame(frame_composite);
-	
-					BorderLayout	layout = 
-						new BorderLayout()
-						{
-							public void 
-							layoutContainer(Container parent)
-							{
-								try{
-									super.layoutContainer( parent );
-								
-								}finally{
-									if ( first_paint ){
-										
-										first_paint	= false;
-											
-										view_ref.get().open( component );
-									}
-								}
-							}
-						};
-					
-					Panel	pan = new Panel( layout );
-	
-					f.add( pan );
-							
-					component	= view_ref.get().create();
-					
-					pan.add( component, BorderLayout.CENTER );
-				}
-				
-				public Composite 
-				getComposite()
-				{
-					return( composite );
-				}
-				
-				public void 
-				delete() 
-				{
-					super.delete();
-					
-					view_ref.get().delete( component );
-				}
-			};
-			
-		awt_view_map.put( view, v );
-		
-		addView( v, auto_open );
-	}
-	
-	public void
-	removeView(
-		UISWTAWTPluginView		view )
-	{
-		UISWTPluginView	v = (UISWTPluginView)awt_view_map.remove(view );
-		
-		if ( v != null ){
-			
-			removeView( v );
-		}
-	}
-	
 	public void
 	detach()
 	
@@ -679,21 +556,50 @@ UISWTInstanceImpl
 	}
 
 
-	public void addView(String sParentID, final String sViewID,
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(java.lang.String, java.lang.String, java.lang.Class, java.lang.Object)
+	 */
+	public void addView(String sParentID, String sViewID,
+			Class<? extends UISWTViewEventListener> cla, Object datasource) {
+		addView(null, sParentID, sViewID, cla, datasource);
+	}
+
+	public void addView(PluginInterface pi, String sParentID, String sViewID,
+			Class<? extends UISWTViewEventListener> cla, Object datasource) {
+
+		UISWTViewEventListenerHolder _l = new UISWTViewEventListenerHolder(sViewID,
+				cla, datasource, pi);
+		addView( sParentID, sViewID, _l );
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(java.lang.String, java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener)
+	 */
+	public void addView(String sParentID, String sViewID,
 			final UISWTViewEventListener l) {
-		Map<String,UISWTViewEventListener> subViews = views.get(sParentID);
+		UISWTViewEventListenerHolder _l = new UISWTViewEventListenerHolder(sViewID, l, null );
+		addView( sParentID, sViewID, _l );
+	}
+	
+	public void addView( String sParentID, 
+			final String sViewID, final UISWTViewEventListenerHolder holder)
+	{
+		if (sParentID == null) {
+			sParentID = UISWTInstance.VIEW_MAIN;
+		}
+		Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID);
 		if (subViews == null) {
-			subViews = new HashMap<String,UISWTViewEventListener>();
+			subViews = new LinkedHashMap<String,UISWTViewEventListenerHolder>();
 			views.put(sParentID, subViews);
 		}
 
-		subViews.put(sViewID, l);
+		subViews.put(sViewID, holder );
 
 		if (sParentID.equals(UISWTInstance.VIEW_MAIN)) {
 			Utils.execSWTThread(new AERunnable() {
 				public void runSupport() {
 					try {
-						uiFunctions.addPluginView(sViewID, l);
+						uiFunctions.addPluginView(sViewID, holder );
 					} catch (Throwable e) {
 						// SWT not available prolly
 					}
@@ -704,7 +610,7 @@ UISWTInstanceImpl
 	
 	// TODO: Remove views from PeersView, etc
 	public void removeViews(String sParentID, final String sViewID) {
-		Map<String,UISWTViewEventListener> subViews = views.get(sParentID);
+		Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID);
 		if (subViews == null)
 			return;
 
@@ -731,12 +637,12 @@ UISWTInstanceImpl
 	
 	public boolean openView(final String sParentID, final String sViewID,
 			final Object dataSource, final boolean setfocus) {
-		Map<String,UISWTViewEventListener> subViews = views.get(sParentID);
+		Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID);
 		if (subViews == null) {
 			return false;
 		}
 
-		final UISWTViewEventListener l = subViews.get(sViewID);
+		final UISWTViewEventListenerHolder l = subViews.get(sViewID);
 		if (l == null) {
 			return false;
 		}
@@ -744,7 +650,8 @@ UISWTInstanceImpl
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (uiFunctions != null) {
-					uiFunctions.openPluginView(sParentID, sViewID, l, dataSource,
+					uiFunctions.openPluginView(
+							sParentID, sViewID, l, dataSource,
 							setfocus && !bUIAttaching);
 				}
 			}
@@ -754,16 +661,28 @@ UISWTInstanceImpl
 	}
 
 	public void openMainView(final String sViewID,
-			final UISWTViewEventListener l, final Object dataSource) {
-		openMainView(sViewID, l, dataSource, true);
+			UISWTViewEventListener l, Object dataSource) {
+		openMainView(null,sViewID, l, dataSource, true);
+	}
+	
+	public void openMainView(PluginInterface pi, String sViewID,
+			UISWTViewEventListener l, Object dataSource) {
+		openMainView( pi, sViewID, l, dataSource, true);
 	}
 	
 	public void openMainView(final String sViewID,
 			final UISWTViewEventListener l, final Object dataSource,
 			final boolean setfocus) {
+		openMainView( null, sViewID, l, dataSource, setfocus );
+	}
+	public void openMainView(final PluginInterface pi, final String sViewID,
+			final UISWTViewEventListener _l, final Object dataSource,
+			final boolean setfocus) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (uiFunctions != null) {
+					UISWTViewEventListenerHolder l = new UISWTViewEventListenerHolder(sViewID, _l, pi );
+					
 					uiFunctions.openPluginView(UISWTInstance.VIEW_MAIN, sViewID, l, dataSource, setfocus && !bUIAttaching);
 				}
 			}
@@ -826,17 +745,25 @@ UISWTInstanceImpl
 	// Core Functions
 	// ==============
 	
-	public Map<String,UISWTViewEventListener> getViewListeners(String sParentID) {
-		return views.get(sParentID);
-	}
-	
-	/**
-	 * @return  Map(key=parentid, value=Map(key=id, value=UISWTViewEventListener))
-	 *
-	 * @since 3.1.1.1
-	 */
-	public Map<String,Map<String,UISWTViewEventListener>> getAllViews() {
-		return views;
+	public UISWTViewEventListenerHolder[] getViewListeners(String sParentID) {
+		Map<String, UISWTViewEventListenerHolder> map = views.get(sParentID);
+		if (map == null) {
+			return new UISWTViewEventListenerHolder[0];
+		}
+		UISWTViewEventListenerHolder[] array = map.values().toArray(new UISWTViewEventListenerHolder[0]);
+		Arrays.sort(array, new Comparator<UISWTViewEventListenerHolder>() {
+			public int compare(UISWTViewEventListenerHolder o1,
+					UISWTViewEventListenerHolder o2) {
+				if ((o1.getPluginInterface() == null) && (o2.getPluginInterface() == null)) {
+					return 0;
+				}
+				if ((o1.getPluginInterface() != null) && (o2.getPluginInterface() != null)) {
+					return 0;
+				}
+				return o1.getPluginInterface() == null ? -1 : 1;
+			}
+		});
+		return array;
 	}
 	
 	public UIInputReceiver getInputReceiver() {
@@ -855,7 +782,7 @@ UISWTInstanceImpl
 			return null;
 		}
 		
-		MainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
+		IMainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
 		if (mainStatusBar == null) {
 			Debug.outNoStack("No MainStatusBar on createStatusEntry");
 			return null;
@@ -877,6 +804,82 @@ UISWTInstanceImpl
 		});
 	}
 	
+	public UIToolBarManager getToolBarManager() {
+		throw( new RuntimeException( "plugin specific instance required" ));
+	}
+
+	public UIToolBarManager getToolBarManager(PluginInterface pi) {
+		toolbarWrapper	instance = toolbar_map.get(pi);
+		
+		if ( instance == null ){
+			UIToolBarManager toolBarManager = uiFunctions.getToolBarManager();
+			if (toolBarManager instanceof UIToolBarManagerCore) {
+				instance = new toolbarWrapper(pi, (UIToolBarManagerCore) toolBarManager);
+				
+				toolbar_map.put(pi, instance );
+			}
+		}
+		
+		return( instance );
+	}
+	
+	protected static class
+	toolbarWrapper
+		implements UIToolBarManager
+	{
+
+		private final UIToolBarManagerCore toolBarManager;
+		private final PluginInterface pi;
+		private List<UIToolBarItem> listItems;
+
+		public toolbarWrapper(PluginInterface pi, UIToolBarManagerCore toolBarManager) {
+			this.pi = pi;
+			this.toolBarManager = toolBarManager;
+			pi.addEventListener(new PluginEventListener() {
+				public void handleEvent(PluginEvent ev) {
+				}
+			});
+		}
+
+		public UIToolBarItem getToolBarItem(String id) {
+			return toolBarManager.getToolBarItem(id);
+		}
+
+		public UIToolBarItem[] getAllToolBarItems() {
+			return toolBarManager.getAllToolBarItems();
+		}
+
+		public UIToolBarItem createToolBarItem(String id) {
+			UIToolBarItem addToolBarItem = toolBarManager.createToolBarItem(pi, id);
+			synchronized (this) {
+				if (listItems == null) {
+					listItems = new ArrayList<UIToolBarItem>();
+				}
+				listItems.add(addToolBarItem);
+			}
+			return addToolBarItem;
+		}
+
+		public void addToolBarItem(UIToolBarItem item) {
+			toolBarManager.addToolBarItem(item);
+		}
+
+		public void piDestroyed() {
+			synchronized (this) {
+				for (UIToolBarItem item : listItems) {
+					toolBarManager.removeToolBarItem(item.getID());
+				}
+				listItems = null;
+			}
+		}
+
+		public void removeToolBarItem(String id) {
+			toolBarManager.removeToolBarItem(id);
+		}
+
+	}
+
+	
 	protected static class
 	instanceWrapper
 		implements UISWTInstance
@@ -931,19 +934,33 @@ UISWTInstanceImpl
 		public void 
 		addView(String sParentID, String sViewID, UISWTViewEventListener l)
 		{
-			delegate.addView( sParentID, sViewID, l );
+			PluginInterface pi = pi_ref.get();
+			
+			delegate.addView( sParentID, sViewID, new UISWTViewEventListenerHolder(sViewID, l, pi) );
+		}
+		
+		public void addView(String sParentID, String sViewID,
+				Class<? extends UISWTViewEventListener> cla, Object datasource) {
+			PluginInterface pi = pi_ref.get();
+			
+			delegate.addView(sParentID, sViewID, new UISWTViewEventListenerHolder(sViewID,
+					cla, datasource, pi));
 		}
 
 		public void 
 		openMainView(String sViewID, UISWTViewEventListener l,Object dataSource)
 		{
-			delegate.openMainView( sViewID, l, dataSource );
+			PluginInterface pi = pi_ref.get();
+			
+			delegate.openMainView( pi, sViewID, l, dataSource );
 		}
 
 		public void 
 		openMainView(String sViewID, UISWTViewEventListener l,Object dataSource, boolean setfocus)
 		{
-			delegate.openMainView( sViewID, l, dataSource, setfocus );
+			PluginInterface pi = pi_ref.get();
+			
+			delegate.openMainView( pi, sViewID, l, dataSource, setfocus );
 		}
 
 		
@@ -960,33 +977,6 @@ UISWTInstanceImpl
 			return( delegate.getOpenViews(sParentID));
 		}
 
-
-		public void 
-		addView(UISWTPluginView view, boolean autoOpen)
-		{
-			delegate.addView( view, autoOpen );
-		}
-
-
-		public void 
-		removeView(UISWTPluginView view)
-		{
-			delegate.removeView( view );
-		}
-
-		public void 
-		addView(UISWTAWTPluginView view, boolean auto_open)
-		{
-			delegate.addView( view, auto_open );
-		}
-
-
-		public void 
-		removeView(UISWTAWTPluginView view)
-		{
-			delegate.removeView( view );
-		}
-		
 		public int promptUser(String title, String text, String[] options,
 				int defaultOption) {
 			return delegate.promptUser(title, text, options, defaultOption);
@@ -1000,6 +990,9 @@ UISWTInstanceImpl
 			return delegate.openView(sParentID, sViewID, dataSource, setfocus);
 		}
 		
+		public UISWTViewEventListenerWrapper[] getViewListeners(String sParentId) {
+			return delegate.getViewListeners(sParentId);
+		}
 		public UIInputReceiver getInputReceiver() {
 			return delegate.getInputReceiver();
 		}
@@ -1031,9 +1024,22 @@ UISWTInstanceImpl
 		public Shell createShell(int style) {
 			return delegate.createShell(style);
 		}
+
+		public UIToolBarManager getToolBarManager() {
+			PluginInterface pi = pi_ref.get();
+			return delegate.getToolBarManager(pi);
+		}
+
+		public void unload(PluginInterface pi) {
+			delegate.unload(pi);
+		}
 		
 	}
-	
-	
-	
+
+	public void unload(PluginInterface pi) {
+		toolbarWrapper toolBarManager = toolbar_map.remove(pi);
+		if (toolBarManager != null) {
+			toolBarManager.piDestroyed();
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
index 248e248..0e8b419 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTStatusEntryImpl.java
@@ -7,7 +7,6 @@ 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;
@@ -21,6 +20,7 @@ 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.mainwindow.MainStatusBar.CLabelPadding;
 import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntry;
 import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntryListener;
 
@@ -42,6 +42,7 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 	
 	// Used by "update".
 	private boolean needs_update = false;
+	private boolean needs_layout = false;
 	private String text = null;
 	private String tooltip = null;
 	private boolean image_enabled = false;
@@ -63,7 +64,7 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 		return this.menu_context;
 	}
 	
-	public void update(CLabel label) {
+	public boolean update(CLabelPadding label) {
 		if (needs_disposing && !label.isDisposed()) {
 			if (menu != null && !menu.isDisposed()) {
 				menu.dispose();
@@ -76,11 +77,15 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 			}
 			releaseOldImages();
 			
-			return;
+			return( true );
 		}
 		
+		boolean do_layout = needs_layout;
+		
+		needs_layout = false;
+		
 		if (menu_context.is_dirty) {needs_update = true; menu_context.is_dirty = false;} 
-		if (!needs_update) {return;}
+		if (!needs_update) {return do_layout;}
 		
 		// This is where we do a big update.
 		try {
@@ -90,6 +95,8 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 		finally {
 			this_mon.exit();
 		}
+		
+		return do_layout;
 	}
 	
 	/**
@@ -109,7 +116,7 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 		}
 	}
 
-	private void update0(final CLabel label) {
+	private void update0(final CLabelPadding label) {
 		label.setText(text);
 		label.setToolTipText(tooltip);
 		label.setImage(image_enabled ? image : null);
@@ -192,6 +199,9 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 	public void setImage(Image image) {
 		checkDestroyed();
 		this_mon.enter();
+		if( image != this.image ){
+			needs_layout = true;
+		}
 		this.image = image;
 		this.needs_update = true;
 		this_mon.exit();
@@ -200,6 +210,9 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 	public void setImageEnabled(boolean enabled) {
 		checkDestroyed();
 		this_mon.enter();
+		if ( enabled != image_enabled ){
+			needs_layout = true;
+		}
 		this.image_enabled = enabled;
 		this.needs_update = true;
 		this_mon.exit();
@@ -234,7 +247,7 @@ public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLa
 		this_mon.exit();
 	}
 
-	public void created(final CLabel label) {
+	public void created(final MainStatusBar.CLabelPadding label) {
 		final Listener click_listener = new Listener() {
 			public void handleEvent(Event e) {
 				onClick();
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewCore.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewCore.java
new file mode 100644
index 0000000..8e594d4
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewCore.java
@@ -0,0 +1,65 @@
+package org.gudy.azureus2.ui.swt.pluginsimpl;
+
+import org.eclipse.swt.widgets.Composite;
+
+import org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+
+/**
+ * A holding area between the public UISWTView plugin interface,
+ * and things that we may eventually move into UISWTView
+ * 
+ */
+public interface UISWTViewCore
+	extends UISWTView
+{
+	public static final int CONTROLTYPE_SKINOBJECT = 0x100 + 1;
+
+	// >> From IView
+  /**
+   * This method is called when the view is instanciated, it should initialize all GUI
+   * components. Must NOT be blocking, or it'll freeze the whole GUI.
+   * Caller is the GUI Thread.
+   * 
+   * @param composite the parent composite. Each view should create a child 
+   *         composite, and then use this child composite to add all elements
+   *         to.
+   *         
+   * @note It's possible that the view may be created, but never initialize'd.
+   *        In these cases, delete will still be called.
+   */
+  public void initialize(Composite composite);
+  
+  /**
+   * This method is called after initialize so that the Tab is set its control
+   * Caller is the GUI Thread.
+   * @return the Composite that should be set as the control for the Tab item
+   */
+  public Composite getComposite();
+  
+  /**
+   * Messagebundle ID for title
+   */
+  public String getTitleID();
+  
+  /**
+   * Called in order to set / update the title of this View.  When the view
+   * is being displayed in a tab, the full title is used for the tooltip.
+   * 
+   * @return the full title for the view
+   */
+  public String getFullTitle();
+  
+  // << From IView
+
+	public void setSkinObject(PluginUISWTSkinObject so, Composite composite);
+	
+	public PluginUISWTSkinObject getSkinObject();
+	
+	public void setUseCoreDataSource(boolean useCoreDataSource);
+
+	public boolean useCoreDataSource();
+
+	public UISWTViewEventListener getEventListener();
+}
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewEventListenerHolder.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewEventListenerHolder.java
new file mode 100644
index 0000000..d0e3246
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewEventListenerHolder.java
@@ -0,0 +1,182 @@
+/*
+ * Created on Oct 19, 2010
+ * Created by Paul Gardner
+ * 
+ * Copyright 2010 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.pluginsimpl;
+
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance.UISWTViewEventListenerWrapper;
+
+/**
+ * Holds information to create a real {@link UISWTViewEventListener} from
+ * its {@link Class}
+ * <p>
+ * Holds {@link PluginInterface} reference
+ */
+public class 
+UISWTViewEventListenerHolder
+	implements UISWTViewEventListenerWrapper
+{
+	private UISWTViewEventListener		listener;
+	private Reference<PluginInterface>	pi;
+	private Object datasource;
+	private String viewID;
+
+	// when there is no #listener, we create a new #cla for each TYPE_CREATE event
+	Map<UISWTView, UISWTViewEventListener> mapSWTViewToEventListener;
+	private Class<? extends UISWTViewEventListener> cla;
+
+	public
+	UISWTViewEventListenerHolder(
+		String viewID,
+		Class<? extends UISWTViewEventListener> _cla,
+		Object datasource,
+		PluginInterface					_pi )
+	{
+		this(viewID, (UISWTViewEventListener) null, _pi);
+		cla = _cla;
+		this.datasource = datasource;
+	}
+			
+	
+	protected
+	UISWTViewEventListenerHolder(
+		String viewID,
+		UISWTViewEventListener			_listener,
+		PluginInterface					_pi )
+	{
+		this.viewID = viewID;
+		listener	= _listener;
+		
+		if ( _pi == null ){
+			
+			if ( listener instanceof BasicPluginViewImpl ){
+				
+				_pi = ((BasicPluginViewImpl)listener).getModel().getPluginInterface();
+			}
+		}
+		
+		if ( _pi != null ){
+					
+			pi = new WeakReference<PluginInterface>( _pi );
+		}
+	}
+	
+	public boolean
+	isLogView()
+	{
+		return( listener instanceof BasicPluginViewImpl );
+	}
+	
+	public PluginInterface
+	getPluginInterface()
+	{
+		return( pi==null?null:pi.get());
+	}
+	
+	public boolean 
+	eventOccurred(
+		UISWTViewEvent event )
+	{
+		if (listener == null) {
+			UISWTViewEventListener eventListener = null;
+
+			synchronized (UISWTViewEventListenerHolder.this) {
+				int type = event.getType();
+				if (type == UISWTViewEvent.TYPE_CREATE) {
+					try {
+						eventListener = cla.newInstance();
+						UISWTView view = event.getView();
+						if (eventListener instanceof UISWTViewCoreEventListener) {
+							if (view instanceof UISWTViewCore) {
+								UISWTViewCore coreView = (UISWTViewCore) view;
+								coreView.setUseCoreDataSource(true);
+							}
+						}
+						if (mapSWTViewToEventListener == null) {
+							mapSWTViewToEventListener = new HashMap<UISWTView, UISWTViewEventListener>();
+						}
+						mapSWTViewToEventListener.put(view, eventListener);
+
+						if (datasource != null) {
+							if (view instanceof UISWTViewImpl) {
+								UISWTViewImpl swtView = (UISWTViewImpl) view;
+								swtView.triggerEventRaw(
+										UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+										PluginCoreUtils.convert(datasource,
+												((UISWTViewImpl) view).useCoreDataSource()));
+							} else {
+								view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+										datasource);
+							}
+						}
+					} catch (Exception e) {
+						Debug.out(e);
+						return false;
+					}
+				} else if (mapSWTViewToEventListener != null) {
+					if (type == UISWTViewEvent.TYPE_DESTROY) {
+						eventListener = mapSWTViewToEventListener.remove(event.getView());
+					} else {
+						eventListener = mapSWTViewToEventListener.get(event.getView());
+					}
+				}
+			}
+
+			if (eventListener == null) {
+				return false;
+			}
+			
+			return eventListener.eventOccurred(event);
+		} else if (event.getType() == UISWTViewEvent.TYPE_CREATE && (listener instanceof UISWTViewCoreEventListener)){
+			if (event.getView() instanceof UISWTViewCore) {
+				UISWTViewCore coreView = (UISWTViewCore) event.getView();
+				coreView.setUseCoreDataSource(true);
+			}
+		}
+
+		return( listener.eventOccurred( event ));
+	}
+	
+	public UISWTViewEventListener getDelegatedEventListener(UISWTView view) {
+		if (listener != null) {
+			return listener;
+		}
+		if (mapSWTViewToEventListener == null) {
+			return null;
+		}
+		return mapSWTViewToEventListener.get(view);
+	}
+
+
+	public String getViewID() {
+		return viewID;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewImpl.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewImpl.java
index 084aed1..0396023 100644
--- a/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewImpl.java
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UISWTViewImpl.java
@@ -26,9 +26,12 @@ package org.gudy.azureus2.ui.swt.pluginsimpl;
 
 import java.awt.Frame;
 import java.awt.Panel;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.awt.SWT_AWT;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
@@ -36,18 +39,22 @@ 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.Debug;
-import org.gudy.azureus2.ui.swt.plugins.UISWTView;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.UIRuntimeException;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.plugins.*;
 
+import com.aelitis.azureus.ui.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-
-import org.gudy.azureus2.plugins.ui.UIRuntimeException;
-
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import com.aelitis.azureus.util.MapUtils;
 
 /**
  * This class creates an IView that triggers UISWTViewEventListener 
@@ -56,71 +63,91 @@ import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
  * @author TuxPaper
  *
  */
-public class UISWTViewImpl extends AbstractIView implements UISWTView {
+public class UISWTViewImpl
+	implements UISWTViewCore, AEDiagnosticsEvidenceGenerator
+{
 	public static final String CFG_PREFIX = "Views.plugins.";
 
+	private PluginUISWTSkinObject skinObject;
+
 	private Object dataSource = null;
-	
+
 	private boolean useCoreDataSource = false;
 
 	private final UISWTViewEventListener eventListener;
 
-	public UISWTViewEventListener getEventListener() {
-		return eventListener;
-	}
-
 	private Composite composite;
 
 	private final String sViewID;
 
 	private int iControlType = UISWTView.CONTROLTYPE_SWT;
-	
+
 	private boolean bFirstGetCompositeCall = true;
 
-	private final String sParentID;
-	
+	//private final String sParentID;
+
 	private String sTitle = null;
 
+	private String lastFullTitleKey = null;
+
+	private String lastFullTitle = "";
+
+	private Boolean hasFocus = null;
+
+	private UIPluginViewToolBarListener toolbarListener;
+
 	public UISWTViewImpl(String sParentID, String sViewID,
-			UISWTViewEventListener eventListener) throws Exception {
-		this(sParentID, sViewID, eventListener, null);
-	}
-	
-	/**
-	 * 
-	 * @param sViewID
-	 * @param eventListener
-	 */
-	public UISWTViewImpl(String sParentID, String sViewID,
-			UISWTViewEventListener eventListener, Object datasource)
+			UISWTViewEventListener eventListener, Object initialDatasource)
 			throws Exception {
-		this.sParentID = sParentID;
+		//this.sParentID = sParentID;
 		this.sViewID = sViewID;
 		this.eventListener = eventListener;
-		this.dataSource = datasource;
 		if (eventListener instanceof UISWTViewCoreEventListener) {
 			useCoreDataSource = true;
 		}
 
+		AEDiagnostics.addEvidenceGenerator(this);
+
+		if (initialDatasource != null) {
+			triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, initialDatasource);
+		}
+
 		if (!eventListener.eventOccurred(new UISWTViewEventImpl(this,
 				UISWTViewEvent.TYPE_CREATE, this)))
 			throw new UISWTViewEventCancelledException();
+
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getEventListener()
+	 */
+	public UISWTViewEventListener getEventListener() {
+		return eventListener;
 	}
 
 	// UISWTPluginView implementation
 	// ==============================
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getDataSource()
+	 */
 	public Object getDataSource() {
 		return dataSource;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginView#getViewID()
+	 */
 	public String getViewID() {
 		return sViewID;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginView#closeView()
+	 */
 	public void closeView() {
 		try {
-			
+
 			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
 			if (uiFunctions != null) {
 				uiFunctions.closePluginView(this);
@@ -130,49 +157,105 @@ public class UISWTViewImpl extends AbstractIView implements UISWTView {
 		}
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#setControlType(int)
+	 */
 	public void setControlType(int iControlType) {
-		if (iControlType == UISWTView.CONTROLTYPE_AWT
-				|| iControlType == UISWTView.CONTROLTYPE_SWT)
+		if (iControlType == CONTROLTYPE_AWT || iControlType == CONTROLTYPE_SWT
+				|| iControlType == CONTROLTYPE_SKINOBJECT)
 			this.iControlType = iControlType;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getControlType()
+	 */
+	public int getControlType() {
+		return iControlType;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#triggerEvent(int, java.lang.Object)
+	 */
 	public void triggerEvent(int eventType, Object data) {
+		// prevent double fire of focus gained/lost
+		if (eventType == UISWTViewEvent.TYPE_FOCUSGAINED && hasFocus != null
+				&& hasFocus) {
+			return;
+		}
+		if (eventType == UISWTViewEvent.TYPE_FOCUSLOST && hasFocus != null
+				&& !hasFocus) {
+			return;
+		}
+		if (eventType == UISWTViewEvent.TYPE_DATASOURCE_CHANGED) {
+			Object newDataSource = PluginCoreUtils.convert(data, useCoreDataSource);
+			if (dataSource == newDataSource) {
+				return;
+			}
+			data = dataSource = newDataSource;
+		} else if (eventType == UISWTViewEvent.TYPE_LANGUAGEUPDATE) {
+			lastFullTitle = "";
+			Messages.updateLanguageForControl(getComposite());
+		} else if (eventType == UISWTViewEvent.TYPE_OBFUSCATE
+				&& (eventListener instanceof ObfusticateImage)) {
+			if (data instanceof Map) {
+				((ObfusticateImage) eventListener).obfusticatedImage((Image) MapUtils.getMapObject(
+						(Map) data, "image", null, Image.class));
+			}
+		}
+
 		try {
 			eventListener.eventOccurred(new UISWTViewEventImpl(this, eventType, data));
 		} catch (Throwable t) {
-			throw (new UIRuntimeException("UISWTView.triggerEvent:: ViewID="
-					+ sViewID + "; EventID=" + eventType + "; data=" + data, t));
+			Debug.out("ViewID=" + sViewID + "; EventID=" + eventType + "; data="
+					+ data, t);
+			//throw (new UIRuntimeException("UISWTView.triggerEvent:: ViewID="
+			//		+ sViewID + "; EventID=" + eventType + "; data=" + data, t));
 		}
+		
+		if (eventType == UISWTViewEvent.TYPE_DESTROY) {
+			Utils.disposeComposite(getComposite());
+		}	
 	}
 
-	private boolean triggerEvent2(int eventType, Object data) {
+	protected boolean triggerEventRaw(int eventType, Object data) {
 		try {
-			return eventListener.eventOccurred(new UISWTViewEventImpl(this, eventType, data));
+			return eventListener.eventOccurred(new UISWTViewEventImpl(this,
+					eventType, data));
 		} catch (Throwable t) {
 			throw (new UIRuntimeException("UISWTView.triggerEvent:: ViewID="
 					+ sViewID + "; EventID=" + eventType + "; data=" + data, t));
 		}
 	}
-	
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#setTitle(java.lang.String)
+	 */
 	public void setTitle(String title) {
+		if ( title.contains( "." ) && MessageText.keyExists(title)){
+				// it if appears to be a resource key then resolve it here
+			title = MessageText.getString( title );
+		}
 		sTitle = title;
-		
 	}
 
-	// AbstractIView Implementation
-	// ============================
-
-	public void dataSourceChanged(Object newDataSource) {
-		dataSource = PluginCoreUtils.convert(newDataSource, useCoreDataSource);
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getPluginInterface()
+	 */
+	public PluginInterface getPluginInterface() {
+		if (eventListener instanceof UISWTViewEventListenerHolder) {
+			return (((UISWTViewEventListenerHolder) eventListener).getPluginInterface());
+		}
 
-		triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, dataSource);
+		return null;
 	}
 
-	public void delete() {
-		triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
-		super.delete();
-	}
+	
+	// Core Functions
 
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getComposite()
+	 */
 	public Composite getComposite() {
 		if (bFirstGetCompositeCall) {
 			bFirstGetCompositeCall = false;
@@ -180,23 +263,58 @@ public class UISWTViewImpl extends AbstractIView implements UISWTView {
 		return composite;
 	}
 
-	public String getData() {
-		final String key = CFG_PREFIX + sViewID + ".title";
-		if (MessageText.keyExists(key))
-			return key;
-		// For now, to get plugin developers to update their plugins
-		// return key;
-		// For release, change it to this, to make it at least shorter:
-		return sViewID;
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getTitleID()
+	 */
+	public String getTitleID() {
+		if (sTitle == null) {
+			// still need this crappy check because some plugins still expect their
+			// view id to be their name
+			if (MessageText.keyExists(sViewID)) {
+				return sViewID;
+			}
+			String id = CFG_PREFIX + sViewID + ".title";
+			if (MessageText.keyExists(id)) {
+				return id;
+			}
+			return "!" + sViewID + "!";
+		}
+		return "!" + sTitle + "!";
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getFullTitle()
+	 */
 	public String getFullTitle() {
-		if (sTitle != null)
+		//System.out.println("getFullTitle " + sTitle + ";" + getTitleID() + ";" + lastFullTitle + ";" + lastFullTitleKey);
+		if (sTitle != null) {
 			return sTitle;
+		}
+
+		String key = getTitleID();
+		if (key == null) {
+			return "";
+		}
 
-		return super.getFullTitle();
+		if (lastFullTitle.length() > 0 && key.equals(lastFullTitleKey)) {
+			return lastFullTitle;
+		}
+
+		lastFullTitleKey = key;
+
+		if (MessageText.keyExists(key) || key.startsWith("!") && key.endsWith("!")) {
+			lastFullTitle = MessageText.getString(key);
+		} else {
+			lastFullTitle = key.replace('.', ' '); // support old plugins
+		}
+
+		return lastFullTitle;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#initialize(org.eclipse.swt.widgets.Composite)
+	 */
 	public void initialize(Composite parent) {
 		if (iControlType == UISWTView.CONTROLTYPE_SWT) {
 			GridData gridData;
@@ -204,17 +322,17 @@ public class UISWTViewImpl extends AbstractIView implements UISWTView {
 			if (parentLayout instanceof FormLayout) {
 				composite = parent;
 			} else {
-  			composite = new Composite(parent, SWT.NULL);
-  			GridLayout layout = new GridLayout(1, false);
-  			layout.marginHeight = 0;
-  			layout.marginWidth = 0;
-  			composite.setLayout(layout);
+				composite = new Composite(parent, SWT.NULL);
+				GridLayout layout = new GridLayout(1, false);
+				layout.marginHeight = 0;
+				layout.marginWidth = 0;
+				composite.setLayout(layout);
 				gridData = new GridData(GridData.FILL_BOTH);
 				composite.setLayoutData(gridData);
 			}
 
 			triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, composite);
-			
+
 			if (composite.getLayout() instanceof GridLayout) {
 				// Force children to have GridData layoutdata.
 				Control[] children = composite.getChildren();
@@ -226,17 +344,17 @@ public class UISWTViewImpl extends AbstractIView implements UISWTView {
 							Logger.log(new LogEvent(LogIDs.PLUGIN, LogEvent.LT_WARNING,
 									"Plugin View '" + sViewID + "' tried to setLayoutData of "
 											+ control + " to a " + layoutData.getClass().getName()));
-	
+
 						if (children.length == 1)
 							gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
 						else
 							gridData = new GridData();
-						
+
 						control.setLayoutData(gridData);
 					}
 				}
 			}
-		} else {
+		} else if (iControlType == UISWTView.CONTROLTYPE_AWT) {
 			composite = new Composite(parent, SWT.EMBEDDED);
 			FillLayout layout = new FillLayout();
 			layout.marginHeight = 0;
@@ -252,52 +370,109 @@ public class UISWTViewImpl extends AbstractIView implements UISWTView {
 			f.add(pan);
 
 			triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, pan);
-		}
-		
-		if (composite != null) {
-			composite.addListener(SWT.Activate, new Listener() {
-				public void handleEvent(Event event) {
-					triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
-				}
-			});
-	
-			composite.addListener(SWT.Deactivate, new Listener() {
-				public void handleEvent(Event event) {
-					triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
-				}
-			});
+		} else if (iControlType == UISWTViewCore.CONTROLTYPE_SKINOBJECT) {
+			triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, getSkinObject());
 		}
 	}
 
-	public void refresh() {
-		triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
-	}
-
-	public void updateLanguage() {
-		super.updateLanguage();
-
-		triggerEvent(UISWTViewEvent.TYPE_LANGUAGEUPDATE, null);
-	}
-	
-	// Core Functions
-	public String getParentID() {
-		return sParentID;
-	}
-	
+	/**
+	 * @return
+	 */
 	public boolean requestClose() {
-		return triggerEvent2(UISWTViewEvent.TYPE_CLOSE, null);
+		return triggerEventRaw(UISWTViewEvent.TYPE_CLOSE, null);
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#useCoreDataSource()
+	 */
 	public boolean useCoreDataSource() {
 		return useCoreDataSource;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#setUseCoreDataSource(boolean)
+	 */
 	public void setUseCoreDataSource(boolean useCoreDataSource) {
 		if (this.useCoreDataSource == useCoreDataSource) {
 			return;
 		}
 
 		this.useCoreDataSource = useCoreDataSource;
-		dataSourceChanged(dataSource);
+		triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, dataSource);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getSkinObject()
+	 */
+	public PluginUISWTSkinObject getSkinObject() {
+		return skinObject;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#setSkinObject(org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject, org.eclipse.swt.widgets.Composite)
+	 */
+	public void setSkinObject(PluginUISWTSkinObject skinObject, Composite c) {
+		this.skinObject = skinObject;
+		this.composite = c;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
+	 */
+	public void generate(IndentWriter writer) {
+		if (eventListener instanceof AEDiagnosticsEvidenceGenerator) {
+			writer.println("View: " + sViewID + ": " + sTitle);
+
+			try {
+				writer.indent();
+
+				((AEDiagnosticsEvidenceGenerator) eventListener).generate(writer);
+			} catch (Exception e) {
+
+			} finally {
+
+				writer.exdent();
+			}
+		} else {
+			writer.println("View (no generator): " + sViewID + ": " + sTitle);
+		}
+	}
+
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
+		if (toolbarListener != null) {
+			return toolbarListener.toolBarItemActivated(item, activationType, datasource);
+		}
+		if (eventListener instanceof UIPluginViewToolBarListener) {
+			return ((UIPluginViewToolBarListener) eventListener).toolBarItemActivated(item, activationType, datasource);
+		} else if (eventListener instanceof ToolBarEnabler) {
+			return ((ToolBarEnabler) eventListener).toolBarItemActivated(item.getID());
+		} 
+		return false;
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		if (eventListener instanceof UIPluginViewToolBarListener) {
+			((UIPluginViewToolBarListener) eventListener).refreshToolBarItems(list);
+		} else if (eventListener instanceof ToolBarEnabler) {
+			Map<String, Boolean> states = new HashMap<String, Boolean>();
+			for (String id: list.keySet()) {
+				states.put(id, (list.get(id) & UIToolBarItem.STATE_ENABLED) > 0);
+			}
+			
+			((ToolBarEnabler) eventListener).refreshToolBar(states);
+
+			for (String id : states.keySet()) {
+				Boolean visible = states.get(id);
+				list.put(id, visible ? UIToolBarItem.STATE_ENABLED : 0);
+			}
+		}
+	}
+
+	public void setToolBarListener(UIPluginViewToolBarListener l) {
+		toolbarListener = l;
+	}
+	
+	public UIPluginViewToolBarListener getToolBarListener() {
+		return toolbarListener;
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/pluginsimpl/UIToolBarManagerCore.java b/org/gudy/azureus2/ui/swt/pluginsimpl/UIToolBarManagerCore.java
new file mode 100644
index 0000000..bb95962
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/pluginsimpl/UIToolBarManagerCore.java
@@ -0,0 +1,11 @@
+package org.gudy.azureus2.ui.swt.pluginsimpl;
+
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
+
+public interface UIToolBarManagerCore
+	extends UIToolBarManager
+{
+	UIToolBarItem createToolBarItem(PluginInterface pi, String id);
+}
diff --git a/org/gudy/azureus2/ui/swt/progress/ProgressReporterPanel.java b/org/gudy/azureus2/ui/swt/progress/ProgressReporterPanel.java
index a67821e..d7ee951 100644
--- a/org/gudy/azureus2/ui/swt/progress/ProgressReporterPanel.java
+++ b/org/gudy/azureus2/ui/swt/progress/ProgressReporterPanel.java
@@ -14,6 +14,9 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.twistie.ITwistieListener;
+import org.gudy.azureus2.ui.swt.twistie.TwistieLabel;
+import org.gudy.azureus2.ui.swt.twistie.TwistieSection;
 
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
@@ -424,7 +427,7 @@ public class ProgressReporterPanel
 				getDisplay().asyncExec(new Runnable() {
 					public void run() {
 						if (null != nameLabel && false == nameLabel.isDisposed()) {
-							nameLabel.setText(pReport.getName());
+							nameLabel.setText(formatForDisplay(pReport.getName()));
 						}
 						if (true == pReport.isIndeterminate()) {
 							updateStatusLabel(Constants.INFINITY_STRING, false);
@@ -708,6 +711,10 @@ public class ProgressReporterPanel
 			detailListWidget.setStyleRange(style2);
 		}
 		detailSection.setEnabled(true);
+		if ( isError ){
+			detailSection.setCollapsed( false );
+			detailListWidget.setSelection( detailListWidget.getCharCount(), detailListWidget.getCharCount());
+		}
 	}
 	
 	/**
diff --git a/org/gudy/azureus2/ui/swt/progress/ProgressReporterWindow.java b/org/gudy/azureus2/ui/swt/progress/ProgressReporterWindow.java
index 548c950..4c56b5d 100644
--- a/org/gudy/azureus2/ui/swt/progress/ProgressReporterWindow.java
+++ b/org/gudy/azureus2/ui/swt/progress/ProgressReporterWindow.java
@@ -25,9 +25,9 @@ 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.ui.swt.ITwistieListener;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.twistie.ITwistieListener;
 
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
@@ -345,8 +345,13 @@ public class ProgressReporterWindow
 			if (controls[i] instanceof ProgressReporterPanel) {
 				IProgressReporter pReporter = ((ProgressReporterPanel) controls[i]).getProgressReporter();
 				if (false == pReporter.getProgressReport().isActive()) {
-					ProgressReportingManager.getInstance().remove(pReporter);
-					controls[i].dispose();
+					
+					if ( !pReporter.getProgressReport().isInErrorState()){
+						
+						ProgressReportingManager.getInstance().remove(pReporter);
+						
+						controls[i].dispose();
+					}
 				}
 			}
 		}
@@ -590,7 +595,7 @@ public class ProgressReporterWindow
 
 		public int report(IProgressReport progressReport) {
 
-			if (true == isAutoRemove && false == progressReport.isActive()) {
+			if (true == isAutoRemove && false == progressReport.isActive() && !progressReport.isInErrorState()) {
 				if (null != panel && false == panel.isDisposed()) {
 					ProgressReportingManager.getInstance().remove(
 							panel.getProgressReporter());
diff --git a/org/gudy/azureus2/ui/swt/sharing/ShareUtils.java b/org/gudy/azureus2/ui/swt/sharing/ShareUtils.java
index c67c5a7..9ffcd7a 100644
--- a/org/gudy/azureus2/ui/swt/sharing/ShareUtils.java
+++ b/org/gudy/azureus2/ui/swt/sharing/ShareUtils.java
@@ -27,6 +27,7 @@ package org.gudy.azureus2.ui.swt.sharing;
  */
 
 import java.io.File;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.*;
@@ -158,13 +159,21 @@ ShareUtils
 	shareFile(
 		final String		file_name )
 	{
+		shareFile( file_name, null );
+	}
+	
+	public static void
+	shareFile(
+		final String				file_name,
+		final Map<String,String>	properties )
+	{
 		new AEThread("shareFile")
 		{
 			public void
 			runSupport()
 			{
 				try{
-					PluginInitializer.getDefaultInterface().getShareManager().addFile(new File(file_name));
+					PluginInitializer.getDefaultInterface().getShareManager().addFile( new File(file_name), properties );
 					
 				}catch( Throwable e ){
 					
@@ -173,18 +182,26 @@ ShareUtils
 			}
 		}.start();
 	}
-
+	
 	public static void
 	shareDir(
 		final String		file_name )
 	{
+		shareDir( file_name, null );
+	}
+
+	public static void
+	shareDir(
+		final String				file_name,
+		final Map<String,String>	properties )
+	{
 		new AEThread("shareDir")
 		{
 			public void
 			runSupport()
 			{
 				try{
-					PluginInitializer.getDefaultInterface().getShareManager().addDir(new File(file_name));
+					PluginInitializer.getDefaultInterface().getShareManager().addDir(new File(file_name), properties );
 					
 				}catch( Throwable e ){
 					
diff --git a/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java b/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
index 486c9f9..146fa03 100644
--- a/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
+++ b/org/gudy/azureus2/ui/swt/sharing/progress/ProgressWindow.java
@@ -27,7 +27,6 @@ package org.gudy.azureus2.ui.swt.sharing.progress;
  */
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
@@ -38,10 +37,6 @@ import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.animations.Animator;
-import org.gudy.azureus2.ui.swt.animations.shell.AnimableShell;
-import org.gudy.azureus2.ui.swt.animations.shell.LinearAnimator;
-import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.shells.PopupShell;
 
 import org.gudy.azureus2.plugins.sharing.ShareException;
@@ -67,18 +62,14 @@ ProgressWindow
 	private boolean			manually_hidden;
 	
 	public
-	ProgressWindow()
+	ProgressWindow(
+		Display		_display )
 	{
 		try{
 			share_manager	= PluginInitializer.getDefaultInterface().getShareManager();
 			
-			display = SWTThread.getInstance().getDisplay();
-			
-			if ( display.isDisposed()){
-				
-				return;
-			}
-		
+			display = _display;
+					
 			share_manager.addListener(this);
 			
 		}catch( ShareException e ){
@@ -91,7 +82,6 @@ ProgressWindow
 	private class
 	progressDialog 
 		extends 	PopupShell 
-		implements 	AnimableShell
 	{		
 		protected
 		progressDialog(
@@ -183,23 +173,19 @@ ProgressWindow
 			});
 
 			
-	      Rectangle bounds = dialog_display.getClientArea();    
+	      Rectangle bounds = shell.getMonitor().getClientArea();    
 	      x0 = bounds.x + bounds.width - 255;
-	      x1 = bounds.x + bounds.width;
 	
-	      y0 = bounds.y + bounds.height;
 	      y1 = bounds.y + bounds.height - 155;
-					
-			shell.setLocation(x0,y0);
+				
+    	  shell.setLocation(x0,y1);
 		}
 		
 		protected void
 		hidePanel()
 		{		
 			manually_hidden	= true;
-			currentAnimator = new LinearAnimator(this,new Point(x0,y1),new Point(x1,y1),15,30);
-			currentAnimator.start();
-			hideAfter = true;
+			shell.setVisible( false );
 		}
 		
 		protected void
@@ -207,32 +193,22 @@ ProgressWindow
 		{
 			manually_hidden	= false;
 			
-			boolean animate = false ;
 			if ( !shell_opened ){
 			
 				shell_opened = true;
 				
 				shell.open();	
-				
-				animate = true ;
 			}
       
       
             
-			Shell otherShell = Utils.findAnyShell();
-			if (otherShell != null) {
-				shell.moveAbove(otherShell);
-			}
 			
 			if ( !shell.isVisible()){				
 				shell.setVisible(true);
-				animate = true ;
 			}
 			
-			if(animate && currentAnimator == null) {
-		        currentAnimator = new LinearAnimator(this,new Point(x0,y0),new Point(x0,y1),15,30);
-		        currentAnimator.start();
-			}
+			shell.moveAbove(null);
+
 		}
 		
 	protected boolean
@@ -244,38 +220,8 @@ ProgressWindow
     
     
     //Animation properties
-    Animator currentAnimator;
-    int x0,y0,x1,y1;
+    int x0,y1;
     
-    boolean isAnimated;
-    boolean hideAfter;
-    
-    public void animationEnded(Animator source) {
-      if(source != currentAnimator) 
-        return;
-      isAnimated = false;
-      currentAnimator = null;
-      if(hideAfter) {
-        hideAfter = false;
-        if(display == null || display.isDisposed())
-          return;
-        display.asyncExec(new AERunnable() {          
-          public void runSupport() {
-            shell.setVisible(false);
-          }
-        });
-      }
-    }
-
-    public void animationStarted(Animator source) {
-    }
-
-    public Shell getShell() {
-      return shell;
-    }
-
-    public void reportPercent(int percent) {
-    }
 	}
 	
 	public void
diff --git a/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java b/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java
index ed8c170..a97bb0f 100644
--- a/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java
+++ b/org/gudy/azureus2/ui/swt/shells/AdvRenameWindow.java
@@ -27,6 +27,7 @@ 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.torrent.TOTorrentException;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
@@ -108,6 +109,17 @@ public class AdvRenameWindow
 		rowLayout.fill = true;
 		rowLayout.spacing = 5;
 		cButtons.setLayout(rowLayout);
+		
+		Button btnReset = new Button(cButtons, SWT.PUSH);
+		Messages.setLanguageText(btnReset, "Button.reset");
+		btnReset.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				txtInput.setText(TorrentUtils.getLocalisedName(dm.getTorrent()));
+			}
+			
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
 
 		Button btnOk = new Button(cButtons, SWT.PUSH);
 		Messages.setLanguageText(btnOk, "Button.ok");
diff --git a/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java b/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
index ff4eecb..b00cdb6 100644
--- a/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
+++ b/org/gudy/azureus2/ui/swt/shells/GCStringPrinter.java
@@ -21,7 +21,6 @@
 package org.gudy.azureus2.ui.swt.shells;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -33,6 +32,7 @@ import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
+import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.Debug;
 
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
@@ -75,6 +75,8 @@ public class GCStringPrinter
 	private static final int MAX_WORD_LEN = 4000;
 
 	private boolean cutoff;
+	
+	private boolean isWordCut;
 
 	private GC gc;
 
@@ -90,7 +92,7 @@ public class GCStringPrinter
 
 	private Color urlColor;
 
-	private List listUrlInfo;
+	private List<URLInfo> listUrlInfo;
 
 	private Image[] images;
 	
@@ -113,7 +115,7 @@ public class GCStringPrinter
 		int relStartPos;
 
 		// We could use a region, but that uses a resource that requires disposal
-		public List hitAreas = null;
+		public List<Rectangle> hitAreas = null;
 
 		int titleLength;
 
@@ -135,8 +137,6 @@ public class GCStringPrinter
 
 	private class LineInfo
 	{
-		public int width;
-
 		String originalLine;
 
 		String lineOutputed;
@@ -145,10 +145,10 @@ public class GCStringPrinter
 
 		public int relStartPos;
 		
-		public int height;
-		
 		public int imageIndexes[];
 
+		public Point outputLineExtent = new Point(0, 0);
+
 		public LineInfo(String originalLine, int relStartPos) {
 			this.originalLine = originalLine;
 			this.relStartPos = relStartPos;
@@ -196,13 +196,26 @@ public class GCStringPrinter
 	}
 
 	private boolean _printString() {
+		if (Constants.isWindows) {
+			return swt_printString_NoAdvanced();
+		}
+		return swt_printString();
+	}
+	
+	private boolean swt_printString_NoAdvanced() {
 		boolean b = false;
 		try {
 			boolean wasAdvanced = gc.getAdvanced();
 			Rectangle clipping = null;
-			// With Advanced ontext antialias in SWT.DEFAULT is not the system's default
+			// With Advanced on text antialias in SWT.DEFAULT is not the system's 
+			// default (Try flipping the "Turn on ClearType" checkbox on
+			// the ClearType Text Tuner", and you'll see the text redraw correctly
+			// when advanced is off, but not when it's on)
+			// Other problems with text and GDIP, see http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/362ab21b-1dc4-4140-a39a-a366beea9e40
+			
 			// Turn off Advanced while drawing text so it antialiases based on 
 			// system prefs.
+			// NOTE: This messes up any Transforms :(
 			if (gc.getAdvanced() && gc.getTextAntialias() == SWT.DEFAULT
 					&& gc.getAlpha() == 255) {
 				clipping = gc.getClipping();
@@ -225,6 +238,21 @@ public class GCStringPrinter
 		return b;
 	}
 
+	private boolean swt_printString() {
+		boolean b = false;
+		try {
+			b = __printString();
+		} catch (Throwable t) {
+			Debug.out(t);
+		}
+
+		if (DEBUG) {
+			System.out.println("");
+		}
+
+		return b;
+	}
+
 	/**
 	 * @param gc
 	 * @param string
@@ -237,6 +265,7 @@ public class GCStringPrinter
 	 */
 	private boolean __printString() {
 		size = new Point(0, 0);
+		isWordCut = false;
 
 		if (string == null) {
 			return false;
@@ -246,67 +275,81 @@ public class GCStringPrinter
 			return false;
 		}
 
-		ArrayList lines = new ArrayList();
+		ArrayList<LineInfo> lines = new ArrayList<LineInfo>(1);
 		
 		while (string.indexOf('\t') >= 0) {
 			string = string.replace('\t', ' ');
 		}
+		
+		if (string.indexOf("  ") > 0) {
+			string = string.replaceAll("  +", " ");
+		}
+		
+		boolean hasSlashR = string.indexOf('\r') > 0;
 
 		boolean fullLinesOnly = (printFlags & FLAG_FULLLINESONLY) > 0;
 		boolean skipClip = (printFlags & FLAG_SKIPCLIP) > 0;
 		boolean noDraw = (printFlags & FLAG_NODRAW) > 0;
 		wrap = (swtFlags & SWT.WRAP) > 0;
+		
+		if ((swtFlags & (SWT.TOP & SWT.BOTTOM)) == 0) {
+			// center vertically -- must be fullLinesOnly
+			fullLinesOnly = true;
+			printFlags |= FLAG_FULLLINESONLY;
+		}
 
-		if ((printFlags & FLAG_KEEP_URL_INFO) == 0) {
-			Matcher htmlMatcher = patHREF.matcher(string);
-			boolean hasURL = htmlMatcher.find();
-			if (hasURL) {
-				listUrlInfo = new ArrayList(1);
-
-				while (hasURL) {
-					URLInfo urlInfo = new URLInfo();
-
-					// Store the full ahref string once, then use substring which doesn't
-					// create real strings :)
-					urlInfo.fullString = htmlMatcher.group();
-					urlInfo.relStartPos = htmlMatcher.start(0);
-
-					urlInfo.url = string.substring(htmlMatcher.start(1),
-							htmlMatcher.end(1));
-					urlInfo.text = string.substring(htmlMatcher.start(2),
-							htmlMatcher.end(2));
-					urlInfo.titleLength = urlInfo.text.length();
-
-					Matcher matcherTitle = patAHREF_TITLE.matcher(urlInfo.fullString);
-					if (matcherTitle.find()) {
-						urlInfo.title = string.substring(urlInfo.relStartPos
-								+ matcherTitle.start(1), urlInfo.relStartPos
-								+ matcherTitle.end(1));
-					}
-
-					Matcher matcherTarget = patAHREF_TARGET.matcher(urlInfo.fullString);
-					if (matcherTarget.find()) {
-						urlInfo.target = string.substring(urlInfo.relStartPos
-								+ matcherTarget.start(1), urlInfo.relStartPos
-								+ matcherTarget.end(1));
-					}
-
-					//System.out.println("URLINFO! " + urlInfo.fullString 
-					//		+ "\ntarget="
-					//		+ urlInfo.target + "\ntt=" + urlInfo.title + "\nurl="
-					//		+ urlInfo.url + "\ntext=" + urlInfo.text + "\n\n");
-
-					string = htmlMatcher.replaceFirst(urlInfo.text.replaceAll("\\$",
-							"\\\\\\$"));
-					
-					listUrlInfo.add(urlInfo);
-					htmlMatcher = patHREF.matcher(string);
-					hasURL = htmlMatcher.find(urlInfo.relStartPos);
-				}
-			}
-		} else {
-			Matcher htmlMatcher = patHREF.matcher(string);
-			string = htmlMatcher.replaceAll("$2");
+		if (string.indexOf('<') >= 0) {
+  		if ((printFlags & FLAG_KEEP_URL_INFO) == 0) {
+  			Matcher htmlMatcher = patHREF.matcher(string);
+  			boolean hasURL = htmlMatcher.find();
+  			if (hasURL) {
+  				listUrlInfo = new ArrayList<URLInfo>(1);
+  
+  				while (hasURL) {
+  					URLInfo urlInfo = new URLInfo();
+  
+  					// Store the full ahref string once, then use substring which doesn't
+  					// create real strings :)
+  					urlInfo.fullString = htmlMatcher.group();
+  					urlInfo.relStartPos = htmlMatcher.start(0);
+  
+  					urlInfo.url = string.substring(htmlMatcher.start(1),
+  							htmlMatcher.end(1));
+  					urlInfo.text = string.substring(htmlMatcher.start(2),
+  							htmlMatcher.end(2));
+  					urlInfo.titleLength = urlInfo.text.length();
+  
+  					Matcher matcherTitle = patAHREF_TITLE.matcher(urlInfo.fullString);
+  					if (matcherTitle.find()) {
+  						urlInfo.title = string.substring(urlInfo.relStartPos
+  								+ matcherTitle.start(1), urlInfo.relStartPos
+  								+ matcherTitle.end(1));
+  					}
+  
+  					Matcher matcherTarget = patAHREF_TARGET.matcher(urlInfo.fullString);
+  					if (matcherTarget.find()) {
+  						urlInfo.target = string.substring(urlInfo.relStartPos
+  								+ matcherTarget.start(1), urlInfo.relStartPos
+  								+ matcherTarget.end(1));
+  					}
+  
+  					//System.out.println("URLINFO! " + urlInfo.fullString 
+  					//		+ "\ntarget="
+  					//		+ urlInfo.target + "\ntt=" + urlInfo.title + "\nurl="
+  					//		+ urlInfo.url + "\ntext=" + urlInfo.text + "\n\n");
+  
+  					string = htmlMatcher.replaceFirst(urlInfo.text.replaceAll("\\$",
+  							"\\\\\\$"));
+  					
+  					listUrlInfo.add(urlInfo);
+  					htmlMatcher = patHREF.matcher(string);
+  					hasURL = htmlMatcher.find(urlInfo.relStartPos);
+  				}
+  			}
+  		} else {
+  			Matcher htmlMatcher = patHREF.matcher(string);
+  			string = htmlMatcher.replaceAll("$2");
+  		}
 		}
 
 		Rectangle rectDraw = new Rectangle(printArea.x, printArea.y,
@@ -325,12 +368,14 @@ public class GCStringPrinter
 			iCurrentHeight = 0;
 			int currentCharPos = 0;
 			
-			int pos1 = string.indexOf('\n');
-			int pos2 = string.indexOf('\r');
-			if (pos2 == -1) {
-				pos2 = pos1;
+			int posNewLine = string.indexOf('\n');
+			if (hasSlashR) {
+  			int posR = string.indexOf('\r');
+  			if (posR == -1) {
+  				posR = posNewLine;
+  			}
+  			posNewLine = Math.min(posNewLine, posR);
 			}
-			int posNewLine = Math.min(pos1, pos2);
 			if (posNewLine < 0) {
 				posNewLine = string.length();
 			}
@@ -342,20 +387,13 @@ public class GCStringPrinter
 					LineInfo lineInfo = new LineInfo(sLine, currentCharPos);
 					lineInfo = processLine(gc, lineInfo, printArea,  fullLinesOnly,
 							false);
-					String sProcessedLine = (String) lineInfo.lineOutputed;
+					String sProcessedLine = lineInfo.lineOutputed;
 
 					if (sProcessedLine != null && sProcessedLine.length() > 0) {
-						if (lineInfo.width == 0 || lineInfo.height == 0) {
-							Point gcExtent = gc.stringExtent(sProcessedLine);
-							if (lineInfo.width == 0) {
-								lineInfo.width = gcExtent.x;
-							}
-							if (lineInfo.height == 0) {
-								lineInfo.height = gcExtent.y;
-							}
+						if (lineInfo.outputLineExtent.x == 0 || lineInfo.outputLineExtent.y == 0) {
+							lineInfo.outputLineExtent = gc.stringExtent(sProcessedLine);
 						}
-						Point extent = new Point(lineInfo.width, lineInfo.height);
-						iCurrentHeight += extent.y;
+						iCurrentHeight += lineInfo.outputLineExtent.y;
 						boolean isOverY = iCurrentHeight > printArea.height;
 
 						if (DEBUG) {
@@ -369,12 +407,13 @@ public class GCStringPrinter
 							//fullLinesOnly = true; // <-- don't know why we needed this
 							lines.add(lineInfo);
 						} else if (isOverY && fullLinesOnly && lines.size() > 0) {
+							/*
 							String excess = lineInfo.excessPos >= 0
 									? sLine.substring(lineInfo.excessPos) : null;
 							if (excess != null) {
 								if (fullLinesOnly) {
 									if (lines.size() > 0) {
-										lineInfo = (LineInfo) lines.remove(lines.size() - 1);
+										lineInfo = lines.remove(lines.size() - 1);
 										sProcessedLine = lineInfo.originalLine.length() > MAX_LINE_LEN
 												? lineInfo.originalLine.substring(0, MAX_LINE_LEN)
 												: lineInfo.originalLine;
@@ -397,14 +436,14 @@ public class GCStringPrinter
 								}
 
 								StringBuffer outputLine = new StringBuffer(sProcessedLine);
-								lineInfo.width = extent.x;
+								lineInfo.outputLineExtent.x = extent.x;
 								wrap = false;
 								int newExcessPos = processWord(gc, sProcessedLine,
 										" " + excess, printArea, lineInfo, outputLine,
 										new StringBuffer());
 								if (DEBUG) {
-									System.out.println("  with word [" + excess + "] len is "
-											+ lineInfo.width + "(" + printArea.width + ") w/excess "
+									System.out.println("  (overY+full+lineSize>0) with word [" + excess + "] len is "
+											+ lineInfo.outputLineExtent.x + "(" + printArea.width + ") w/excess "
 											+ newExcessPos);
 								}
 
@@ -419,7 +458,11 @@ public class GCStringPrinter
 									System.out.println("No Excess");
 								}
 							}
+							*/
 							cutoff = true;
+							if (DEBUG) {
+								System.out.println("set cutoff");
+							}
 							return false;
 						} else {
 							lines.add(lineInfo);
@@ -430,6 +473,7 @@ public class GCStringPrinter
 						if (DEBUG) {
 							System.out.println("Line process resulted in no text: " + sLine);
 						}
+						iCurrentHeight += lineInfo.outputLineExtent.y;
 						lines.add(lineInfo);
 						currentCharPos++;
 						break;
@@ -450,12 +494,14 @@ public class GCStringPrinter
 				posLastNewLine = posNewLine + 1;
 				currentCharPos = posLastNewLine;
 
-				pos1 = string.indexOf('\n', posLastNewLine);
-				pos2 = string.indexOf('\r', posLastNewLine);
-				if (pos2 == -1) {
-					pos2 = pos1;
+				posNewLine = string.indexOf('\n', posLastNewLine);
+				if (hasSlashR) {
+	  			int posR = string.indexOf('\r', posLastNewLine);
+	  			if (posR == -1) {
+	  				posR = posNewLine;
+	  			}
+	  			posNewLine = Math.min(posNewLine, posR);
 				}
-				posNewLine = Math.min(pos1, pos2);
 				if (posNewLine < 0) {
 					posNewLine = string.length();
 				}
@@ -465,9 +511,9 @@ public class GCStringPrinter
 				// rebuild full text to get the exact y-extent of the output
 				// this may be different (but shouldn't be!) than the height of each
 				// line
+				/*
 				StringBuffer fullText = new StringBuffer(string.length() + 10);
-				for (Iterator iter = lines.iterator(); iter.hasNext();) {
-					LineInfo lineInfo = (LineInfo) iter.next();
+				for (LineInfo lineInfo : lines) {
 					if (fullText.length() > 0) {
 						fullText.append('\n');
 					}
@@ -475,11 +521,11 @@ public class GCStringPrinter
 				}
 
 				//size = gc.textExtent(fullText.toString());
+				 */
 
-				for (Iterator iter = lines.iterator(); iter.hasNext();) {
-					LineInfo lineInfo = (LineInfo) iter.next();
-					size.x = Math.max(lineInfo.width, size.x);
-					size.y += lineInfo.height;
+				for (LineInfo lineInfo : lines) {
+					size.x = Math.max(lineInfo.outputLineExtent.x, size.x);
+					size.y += lineInfo.outputLineExtent.y;
 				}
 				
 				if ((swtFlags & (SWT.BOTTOM)) != 0) {
@@ -490,8 +536,7 @@ public class GCStringPrinter
 				}
 
 				if (!noDraw || listUrlInfo != null) {
-					for (Iterator iter = lines.iterator(); iter.hasNext();) {
-						LineInfo lineInfo = (LineInfo) iter.next();
+					for (LineInfo lineInfo : lines) {
 						try {
 							drawLine(gc, lineInfo, swtFlags, rectDraw, noDraw);
 						} catch (Throwable t) {
@@ -523,15 +568,24 @@ public class GCStringPrinter
 
 		if (lineInfo.originalLine.length() == 0) {
 			lineInfo.lineOutputed = "";
-			lineInfo.height = gc.stringExtent(GOOD_STRING).y;
+			lineInfo.outputLineExtent = new Point(0, gc.stringExtent(GOOD_STRING).y);
 			return lineInfo;
 		}
 		
-		StringBuffer outputLine = new StringBuffer();
+		StringBuffer outputLine = null;
 		int excessPos = -1;
 
-		if (images != null || lineInfo.originalLine.length() > MAX_LINE_LEN
-				|| gc.stringExtent(lineInfo.originalLine).x > printArea.width) {
+		boolean b = images != null || lineInfo.originalLine.length() > MAX_LINE_LEN;
+		if (!b) {
+			Point outputLineExtent = gc.stringExtent(lineInfo.originalLine);
+			b = outputLineExtent.x > printArea.width;
+			if (!b) {
+				lineInfo.outputLineExtent = outputLineExtent;
+			}
+		}
+
+		if (b) {
+			outputLine = new StringBuffer();
 			if (DEBUG) {
 				System.out.println("Line to process: " + lineInfo.originalLine);
 			}
@@ -582,7 +636,7 @@ public class GCStringPrinter
 								printArea, lineInfo, outputLine, space);
 						if (DEBUG) {
 							System.out.println("  with word [" + subWord + "] len is "
-									+ lineInfo.width + "(" + printArea.width + ") w/excess "
+									+ lineInfo.outputLineExtent.x + "(" + printArea.width + ") w/excess "
 									+ excessPos);
 						}
 						if (excessPos >= 0) {
@@ -605,11 +659,12 @@ public class GCStringPrinter
 					}
 				}
 			}
-		} else {
-			outputLine.append(lineInfo.originalLine);
 		}
 
 		if (!wrap && hasMoreElements && excessPos >= 0) {
+			if (outputLine == null) {
+				outputLine = new StringBuffer(lineInfo.originalLine);
+			}
 			int len = outputLine.length();
 			if (len > 2) {
 				len -= 2;
@@ -617,13 +672,16 @@ public class GCStringPrinter
 			outputLine.setLength(len);
 			outputLine.append("\u2026");
 			cutoff = true;
+			if (DEBUG) {
+				System.out.println("set cutoff");
+			}
 		}
 		//drawLine(gc, outputLine, swtFlags, rectDraw);
 		//		if (!wrap) {
 		//			return hasMoreElements;
 		//		}
 		lineInfo.excessPos = excessPos;
-		lineInfo.lineOutputed = outputLine.toString();
+		lineInfo.lineOutputed = outputLine == null ? lineInfo.originalLine : outputLine.toString();
 		return lineInfo;
 	}
 
@@ -653,14 +711,14 @@ public class GCStringPrinter
 				}
 				
 				Point spaceExtent = gc.stringExtent(space.toString());
-				int newWidth = lineInfo.width + bounds.width + spaceExtent.x;
+				int newWidth = lineInfo.outputLineExtent.x + bounds.width + spaceExtent.x;
 
 
 				if (newWidth > printArea.width) {
-					if (bounds.width + spaceExtent.x < printArea.width || lineInfo.width > 0) {
+					if (bounds.width + spaceExtent.x < printArea.width || lineInfo.outputLineExtent.x > 0) {
 						//outputLine.append(space);
 						//outputLine.append(word, 0, 2);
-						//System.out.println("w1 = " + lineInfo.width + ";h=" + lineInfo.height);
+						//System.out.println("w1 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 						return 0;
 					}
 				}
@@ -670,16 +728,15 @@ public class GCStringPrinter
 				}
 				
 				
-				int targetWidth = lineInfo.width + newWidth;
+				//int targetWidth = lineInfo.outputLineExtent.x + newWidth;
 				
-				lineInfo.width = newWidth;
-				lineInfo.height = Math.max(bounds.height, lineInfo.height);
+				lineInfo.outputLineExtent = new Point(newWidth, Math.max(bounds.height, lineInfo.outputLineExtent.y));
 
 				Point ptWordSize = gc.stringExtent(word.substring(2) + " ");
-				if (lineInfo.width + ptWordSize.x > printArea.width) {
+				if (lineInfo.outputLineExtent.x + ptWordSize.x > printArea.width) {
 					outputLine.append(space);
 					outputLine.append(word.substring(0,2));
-					//System.out.println("w8 = " + lineInfo.width + ";h=" + lineInfo.height);
+					//System.out.println("w8 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 					return 2;
 				}
 				
@@ -693,22 +750,27 @@ public class GCStringPrinter
 				//}
 				//space.append(' ');
 				
-				//System.out.println("w2 = " + lineInfo.width + ";h=" + lineInfo.height);
+				//System.out.println("w2 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 				//return -1;
 			}
 		}
 
 		Point ptLineAndWordSize = gc.stringExtent(outputLine + word + " ");
-		//System.out.println(ptLineAndWordSize + ";" + outputLine  + "::WordComp " + (ptLineAndWordSize.x - lineInfo.width));
+		//System.out.println(ptLineAndWordSize + ";" + outputLine  + "::WordComp " + (ptLineAndWordSize.x - lineInfo.outputLineExtent.x));
 		if (ptLineAndWordSize.x > printArea.width) {
 			// word is longer than space avail, split
 
 			Point ptWordSize2 = gc.stringExtent(word + " ");
 			boolean bWordLargerThanWidth = ptWordSize2.x > printArea.width;
+
+			if (bWordLargerThanWidth) {
+				isWordCut = true;
+			}
+			
 			// 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);
+			if (bWordLargerThanWidth && lineInfo.outputLineExtent.x > 0) {
+				//System.out.println("w3 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 				return 0;
 			}
 
@@ -769,7 +831,7 @@ public class GCStringPrinter
 				outputLine.append(space);
 			}
 
-			int w = ptLineAndWordSize.x - lineInfo.width;
+			//int w = ptLineAndWordSize.x - lineInfo.outputLineExtent.x;
 			if (wrap && !nothingFit && !bWordLargerThanWidth) {
 				// whole word is excess
 				return 0;
@@ -791,18 +853,21 @@ public class GCStringPrinter
 					outputLine.setLength(len);
 					outputLine.append("\u2026");
 					cutoff = true;
+					if (DEBUG) {
+						System.out.println("set cutoff");
+					}
 				}
 			}
 			//drawLine(gc, outputLine, swtFlags, rectDraw);
 			if (DEBUG) {
 				System.out.println("excess " + word.substring(endIndex));
 			}
-			//System.out.println("w9 = " + lineInfo.width + ";h=" + lineInfo.height);
+			//System.out.println("w9 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 			return endIndex;
 		}
 
-		lineInfo.width = ptLineAndWordSize.x;
-		if (lineInfo.width > printArea.width) {
+		lineInfo.outputLineExtent.x = ptLineAndWordSize.x;
+		if (lineInfo.outputLineExtent.x > printArea.width) {
 			if (space.length() > 0) {
 				space.delete(0, space.length());
 			}
@@ -822,11 +887,14 @@ public class GCStringPrinter
 					outputLine.setLength(len);
 					outputLine.append("\u2026");
 					cutoff = true;
+					if (DEBUG) {
+						System.out.println("set cutoff");
+					}
 				}
-				//System.out.println("w5 = " + lineInfo.width + ";h=" + lineInfo.height);
+				//System.out.println("w5 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 				return -1;
 			} else {
-				//System.out.println("w6 = " + lineInfo.width + ";h=" + lineInfo.height);
+				//System.out.println("w6 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 				return 0;
 			}
 			//drawLine(gc, outputLine, swtFlags, rectDraw);
@@ -841,7 +909,7 @@ public class GCStringPrinter
 		}
 		space.append(' ');
 
-		//System.out.println("w4 = " + lineInfo.width + ";h=" + lineInfo.height);
+		//System.out.println("w4 = " + lineInfo.outputLineExtent.x + ";h=" + lineInfo.outputLineExtent.y);
 		return -1;
 	}
 
@@ -858,22 +926,15 @@ public class GCStringPrinter
 			Rectangle printArea, boolean noDraw) {
 		String text = lineInfo.lineOutputed;
 		// TODO: ensure width and height have values
-		if (lineInfo.width == 0 || lineInfo.height == 0) {
-			Point gcExtent = gc.stringExtent(text);;
-			if (lineInfo.width == 0) {
-				lineInfo.width = gcExtent.x;
-			}
-			if (lineInfo.height == 0) {
-				lineInfo.height = gcExtent.y;
-			}
+		if (lineInfo.outputLineExtent.x == 0 || lineInfo.outputLineExtent.y == 0) {
+			lineInfo.outputLineExtent = gc.stringExtent(text);
 		}
-		Point drawSize = new Point(lineInfo.width, lineInfo.height);
 		
 		int x0;
 		if ((swtFlags & SWT.RIGHT) > 0) {
-			x0 = printArea.x + printArea.width - drawSize.x;
+			x0 = printArea.x + printArea.width - lineInfo.outputLineExtent.x;
 		} else if ((swtFlags & SWT.CENTER) > 0) {
-			x0 = printArea.x + (printArea.width - drawSize.x) / 2;
+			x0 = printArea.x + (printArea.width - lineInfo.outputLineExtent.x) / 2;
 		} else {
 			x0 = printArea.x;
 		}
@@ -919,7 +980,7 @@ public class GCStringPrinter
 				if (i > 0 && i > lineStartPos && i <= text.length()) {
 					String s = text.substring(lineStartPos, i);
 					//gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_RED));
-					x0 += drawText(gc, s, x0, y0, lineInfo.height, null, noDraw).x;
+					x0 += drawText(gc, s, x0, y0, lineInfo.outputLineExtent.y, null, noDraw, true).x;
 
 					relStartPos += (i - lineStartPos);
 					lineStartPos += (i - lineStartPos);
@@ -946,7 +1007,8 @@ public class GCStringPrinter
 
 					if (urlInfo.dropShadowColor != null) {
 						gc.setForeground(urlInfo.dropShadowColor);
-						drawText(gc, s, x0 + 1, y0 + 1, lineInfo.height, null, noDraw);
+						drawText(gc, s, x0 + 1, y0 + 1, lineInfo.outputLineExtent.y, null, noDraw,
+								false);
 					}
 
 					if (urlInfo.urlColor != null) {
@@ -956,9 +1018,10 @@ public class GCStringPrinter
 					}
 				}
 				if (urlInfo.hitAreas == null) {
-					urlInfo.hitAreas = new ArrayList(1);
+					urlInfo.hitAreas = new ArrayList<Rectangle>(1);
 				}
-				pt = drawText(gc, s, x0, y0, lineInfo.height, urlInfo.hitAreas, noDraw);
+				pt = drawText(gc, s, x0, y0, lineInfo.outputLineExtent.y, urlInfo.hitAreas, noDraw,
+						true);
 				if (!noDraw) {
 					if (urlInfo.urlUnderline) {
 						gc.drawLine(x0, y0 + pt.y - 1, x0 + pt.x - 1, y0 + pt.y - 1); 
@@ -967,9 +1030,9 @@ public class GCStringPrinter
 				}
 
 				if (urlInfo.hitAreas == null) {
-					urlInfo.hitAreas = new ArrayList(1);
+					urlInfo.hitAreas = new ArrayList<Rectangle>(1);
 				}
-				//gc.drawRectangle(new Rectangle(x0, y0, pt.x, lineInfo.height));
+				//gc.drawRectangle(new Rectangle(x0, y0, pt.x, lineInfo.outputLineExtent.y));
 
 				x0 += pt.x;
 			}
@@ -979,14 +1042,14 @@ public class GCStringPrinter
 		if (lineStartPos < text.length()) {
 			String s = text.substring(lineStartPos);
 			if (!noDraw) {
-				drawText(gc, s, x0, y0, lineInfo.height, null, noDraw);
+				drawText(gc, s, x0, y0, lineInfo.outputLineExtent.y, null, noDraw, false);
 			}
 		}
-		printArea.y += drawSize.y;
+		printArea.y += lineInfo.outputLineExtent.y;
 	}
 	
 	private Point drawText(GC gc, String s, int x, int y, int height,
-			List hitAreas, boolean nodraw) {
+			List<Rectangle> hitAreas, boolean nodraw, boolean calcExtent) {
 		Point textExtent;
 
 		if (images != null) {
@@ -1079,6 +1142,9 @@ public class GCStringPrinter
 		if (!nodraw) {
 			gc.drawText(s, x, y, true);
 		}
+		if (!calcExtent && hitAreas == null) {
+			return null;
+		}
 		textExtent = gc.textExtent(s);
 		if (hitAreas != null) {
 			hitAreas.add(new Rectangle(x, y, textExtent.x, textExtent.y));
@@ -1111,7 +1177,7 @@ public class GCStringPrinter
 		};
 
 		//final String text = "Opil Wrir, Na Poys Iysk, Yann Only. test of the string printer averlongwordthisisyesindeed";
-		final String text = "Apple <A HREF=\"aa\">Banana</a>, Cow <A HREF=\"ss\">Dug Ergo</a>, Flip Only. test of the string printer averlongwordthisisyesindeed";
+		final String text = "Apple <A HREF=\"aa\">Banana</a>, Cow <A HREF=\"ss\">Dug Ergo</a>, Flip Only. test of the string printer averlongwordthisisyesindeed " + Constants.INFINITY_STRING;
 		//final String text = "Apple, Cow sfjkhsd %1 f, Flip Only. test of %0 the string printer averlongwordthisisyesindeed";
 
 		shell.setSize(500, 500);
@@ -1119,12 +1185,13 @@ public class GCStringPrinter
 		GridLayout gridLayout = new GridLayout(2, false);
 		shell.setLayout(gridLayout);
 
+		int initHeight = 67;
 		Composite cButtons = new Composite(shell, SWT.NONE);
 		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.NONE, true, false);
-		gridData.heightHint = 40;
+		gridData.heightHint = initHeight;
 		cPaint.setLayoutData(gridData);
 
 		cButtons.setLayout(new RowLayout(SWT.VERTICAL));
@@ -1180,6 +1247,22 @@ public class GCStringPrinter
 		btnWrap.setSelection(true);
 		btnWrap.addListener(SWT.Selection, l);
 		
+		final Button btnGCAdvanced = new Button(cButtons, SWT.CHECK);
+		btnGCAdvanced.setText("gc.Advanced");
+		btnGCAdvanced.setSelection(true);
+		btnGCAdvanced.addListener(SWT.Selection, l);
+		
+		final Spinner spinnerHeight = new Spinner(cButtons, SWT.BORDER);
+		spinnerHeight.setSelection(initHeight);
+		spinnerHeight.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				GridData gridData = (GridData) cPaint.getLayoutData();
+				gridData.heightHint = spinnerHeight.getSelection();
+				cPaint.setLayoutData(gridData);
+				shell.layout();
+			}
+		});
+		
 		final Label lblInfo = new Label(shell, SWT.WRAP);
 		lblInfo.setText("Welcome");
 		
@@ -1195,6 +1278,7 @@ public class GCStringPrinter
 					gc = new GC(cPaint);
 				}
 				try {
+					gc.setAdvanced(btnGCAdvanced.getSelection());
 					GCStringPrinter sp = buildSP(gc);
 					Color colorURL = gc.getDevice().getSystemColor(SWT.COLOR_RED);
 					Color colorURL2 = gc.getDevice().getSystemColor(
@@ -1241,6 +1325,11 @@ public class GCStringPrinter
 
 					gc.setForeground(colorBox);
 					gc.drawRectangle(bounds);
+					
+					bounds.height -= 20;
+					bounds.y += 10;
+					gc.setLineStyle(SWT.LINE_DOT);
+					gc.drawRectangle(bounds);
 
 					//System.out.println("-         " + System.currentTimeMillis());
 
@@ -1258,6 +1347,9 @@ public class GCStringPrinter
 				//gc.setFont(Utils.getFontWithHeight(shell.getFont(), gc, 15));
 				//gc.setTextAntialias(SWT.ON);
 				Rectangle bounds = cPaint.getClientArea();
+				bounds.y += 10;
+				bounds.height -= 20;
+				
 
 				int style = btnWrap.getSelection() ? SWT.WRAP : 0;
 				if (cboVAlign.getSelectionIndex() == 0) {
@@ -1344,11 +1436,13 @@ public class GCStringPrinter
 	}
 
 	/**
-	 * @param rectangle
-	 *
-	 * @since 3.0.4.3
+	 * DO NOT REMOVE OR CHANGE RETURN TYPE -- USED BY PLUGINS
 	 */
 	public void printString(GC gc, Rectangle rectangle, int swtFlags) {
+		printString2(gc, rectangle, swtFlags);
+	}
+
+	public boolean printString2(GC gc, Rectangle rectangle, int swtFlags) {
 		this.gc = gc;
 		int printFlags = this.printFlags;
 		if (printArea.width == rectangle.width) {
@@ -1356,7 +1450,7 @@ public class GCStringPrinter
 		}
 		printArea = rectangle;
 		this.swtFlags = swtFlags;
-		printString(printFlags);
+		return printString(printFlags);
 	}
 
 	public Point getCalculatedSize() {
@@ -1375,11 +1469,9 @@ public class GCStringPrinter
 		if (listUrlInfo == null || listUrlInfo.size() == 0) {
 			return null;
 		}
-		for (Iterator iter = listUrlInfo.iterator(); iter.hasNext();) {
-			URLInfo urlInfo = (URLInfo) iter.next();
+		for (URLInfo urlInfo : listUrlInfo) {
 			if (urlInfo.hitAreas != null) {
-				for (Iterator iter2 = urlInfo.hitAreas.iterator(); iter2.hasNext();) {
-					Rectangle r = (Rectangle) iter2.next();
+				for (Rectangle r : urlInfo.hitAreas) {
 					if (r.contains(x, y)) {
 						return urlInfo;
 					}
@@ -1425,6 +1517,10 @@ public class GCStringPrinter
 		return string;
 	}
 
+	public boolean isWordCut() {
+		return isWordCut;
+	}
+
 	/*
 	private Point stringExtent(GC gc, String s) {
 		Matcher m = patOver1000.matcher(s);
diff --git a/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java b/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
index bf33d2f..f77eee3 100644
--- a/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/MessageBoxShell.java
@@ -12,6 +12,7 @@ import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
 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 org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
@@ -107,6 +108,14 @@ public class MessageBoxShell
 	private Shell shell;
 
 	private boolean opened;
+
+	private boolean useTextBox;
+
+	private String cbMessageID;
+
+	private int cbMinUserMode;
+
+	private boolean cbEnabled;
 	
 	public static void open(Shell parent, String title, String text,
 			String[] buttons, int defaultOption, String rememberID,
@@ -135,7 +144,7 @@ public class MessageBoxShell
 			final String text, final String[] buttons, final int defaultOption) {
 		this.title = title;
 		this.text = text;
-		this.buttons = buttons;
+		this.buttons = buttons == null ? new String[0] : buttons;
 		this.defaultButtonPos = defaultOption;
 	}
 
@@ -295,7 +304,7 @@ public class MessageBoxShell
 			public void runSupport() {
 				_open();
 			}
-		}, false);
+		});
 
 		return;
 	}
@@ -316,8 +325,11 @@ public class MessageBoxShell
 		MouseTrackAdapter mouseAdapter = null;
 		final Display display = parent.getDisplay();
 
-		shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM
-				| SWT.RESIZE | SWT.APPLICATION_MODAL);
+		//APPLICATION_MODAL causes some crazy sht to happen on Windows.  
+		// Example: 5 windows open in APPLICATION MODAL mode, 
+		// and somehow none of them show until you do a "Window->Bring To Front"
+		// which only makes ONE visible
+		shell = ShellFactory.createShell(parent, SWT.DIALOG_TRIM | SWT.RESIZE);
 		if (title != null) {
 			shell.setText(title);
 		}
@@ -377,7 +389,11 @@ public class MessageBoxShell
 
 		Control linkControl;
 		if ( text != null && text.length() > 0 ){
-			linkControl = createLinkLabel(textComposite, text);
+			if (useTextBox()) {
+				linkControl = createTextBox(textComposite, text);
+			} else {
+				linkControl = createLinkLabel(textComposite, text);
+			}
 		}else{
 			linkControl = null;
 		}
@@ -460,9 +476,12 @@ public class MessageBoxShell
 		}
 
 
-		if (!squish && (autoCloseInMS > 0 || rememberID != null)) {
-			Label lblPadding = new Label(shell, SWT.NONE );
-			lblPadding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		if (!squish
+				&& (autoCloseInMS > 0 || rememberID != null || (cbMessageID != null && Utils.getUserMode() >= cbMinUserMode))) {
+			Label lblPadding = new Label(shell, SWT.NONE);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.heightHint = 5;
+			lblPadding.setLayoutData(gridData);
 		}
 
 		// Closing in..
@@ -553,6 +572,22 @@ public class MessageBoxShell
 			});
 		}
 
+		if (cbMessageID != null && Utils.getUserMode() >= cbMinUserMode) {
+			Button cb = new Button(shell, SWT.CHECK);
+			cb.addSelectionListener(new SelectionListener() {
+				
+				public void widgetSelected(SelectionEvent e) {
+					cbEnabled = ((Button) e.widget).getSelection();
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+			Messages.setLanguageText(cb, cbMessageID);
+			cb.setSelection(cbEnabled);
+		}
+		
+		
 		// Remember Me
 		Button checkRemember = null;
 		if (rememberID != null) {
@@ -578,15 +613,30 @@ public class MessageBoxShell
 					}
 				}
 			});
+		} else {
+			Button spacer = new Button(shell, SWT.CHECK);
+			spacer.setVisible(false);
 		}
 
+
 		// Buttons
 
 		if ( buttons.length > 0 ){
+			Canvas line = new Canvas(shell,SWT.NO_BACKGROUND);
+			line.addListener(SWT.Paint, new Listener() {
+				public void handleEvent(Event e) {
+					Rectangle clientArea = ((Canvas) e.widget).getClientArea();
+					e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW));
+					e.gc.drawRectangle(clientArea);
+					clientArea.y++;
+					e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+					e.gc.drawRectangle(clientArea);
+				}
+			});
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.heightHint = 2;
+			line.setLayoutData(gridData);
 			
-			Label labelSeparator = new Label(shell,SWT.SEPARATOR | SWT.HORIZONTAL);
-			labelSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
 			Composite cButtons = new Composite(shell, SWT.NONE);
 			FormLayout layout = new FormLayout();
 	
@@ -646,7 +696,7 @@ public class MessageBoxShell
 				}
 			}
 		}
-		
+
 		shell.addTraverseListener(new TraverseListener() {
 			public void keyTraversed(TraverseEvent event) {
 				if (event.detail == SWT.TRAVERSE_ESCAPE) {
@@ -709,6 +759,19 @@ public class MessageBoxShell
 	}
 
 	/**
+	 * @param textComposite
+	 * @param text2
+	 * @return
+	 */
+	private Control createTextBox(Composite textComposite, String text2) {
+		Text tb = new Text(textComposite, SWT.BORDER | SWT.MULTI | SWT.H_SCROLL
+				| SWT.V_SCROLL | SWT.READ_ONLY);
+		tb.setText(text2);
+		
+		return tb;
+	}
+
+	/**
 	 * Adds mousetracklistener to composite and all it's children
 	 * 
 	 * @param parent Composite to start at
@@ -1029,22 +1092,32 @@ public class MessageBoxShell
 	 *       {@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();
+		final AESemaphore sem = new AESemaphore("waitUntilClosed");
+		
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				try {
+					if (shell == null) {
+						return;
+					}
+					if (!opened) {
+						shell.open();
 					}
+					while (shell != null && !shell.isDisposed()) {
+						if (shell.getDisplay() != null
+								&& !shell.getDisplay().readAndDispatch()) {
+							shell.getDisplay().sleep();
+						}
+					}
+					return;
+				} finally {
+					sem.releaseForever();
 				}
-				return true;
 			}
 		});
+		
+		sem.reserve();
+
 		int realResult = getButtonVal(result);
 
 		return realResult;
@@ -1112,6 +1185,16 @@ public class MessageBoxShell
 		this.buttons = buttons;
 		this.buttonVals = buttonVals;
 	}
+	
+	public void addCheckBox(String cbMessageID, int cbMinUserMode, boolean defaultOn) {
+		this.cbMessageID = cbMessageID;
+		this.cbMinUserMode = cbMinUserMode;
+		this.cbEnabled = defaultOn;
+	}
+	
+	public boolean getCheckBoxEnabled() {
+		return cbEnabled;
+	}
 
 	public Shell getParent() {
 		return parent;
@@ -1121,4 +1204,36 @@ public class MessageBoxShell
 		this.parent = parent;
 	}
 
+	public void close() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (shell != null && !shell.isDisposed()) {
+					shell.dispose();
+				}
+			}
+		});
+	}
+
+	/**
+	 * @param useTextBox The useTextBox to set.
+	 */
+	public void setUseTextBox(boolean useTextBox) {
+		this.useTextBox = useTextBox;
+	}
+
+	/**
+	 * @return Returns the useTextBox.
+	 */
+	public boolean useTextBox() {
+		return useTextBox;
+	}
+
+	public void setLeftImage(final String id) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				setLeftImage(ImageLoader.getInstance().getImage(id));
+			}
+		});
+	}
+
 }
diff --git a/org/gudy/azureus2/ui/swt/shells/MessagePopupShell.java b/org/gudy/azureus2/ui/swt/shells/MessagePopupShell.java
deleted file mode 100644
index 63aae40..0000000
--- a/org/gudy/azureus2/ui/swt/shells/MessagePopupShell.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * File    : ErrorPopupShell.java
- * Created : 15 mars 2004
- * By      : Olivier
- * 
- * 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.swt.shells;
-
-import java.lang.ref.WeakReference;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.graphics.*;
-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.config.COConfigurationManager;
-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.Messages;
-import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.animations.Animator;
-import org.gudy.azureus2.ui.swt.animations.shell.AnimableShell;
-import org.gudy.azureus2.ui.swt.animations.shell.LinearAnimator;
-
-import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
-import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
-
-
-/**
- * @author Olivier Chalouhi
- *
- */
-public class MessagePopupShell implements AnimableShell {
-  
-  private Shell shell;
-  private Shell detailsShell;  
-  Image shellImg;
-  private Display display;
-
-  public static final String ICON_ERROR 	= "error";
-  public static final String ICON_WARNING 	= "warning";
-  public static final String ICON_INFO	 	= "info";
-
-   private static LinkedList viewStack;
-   private Timer closeTimer;
-
-    private String icon;
-
-  static {
-      viewStack = new LinkedList();
-  }
-  
-	/** Open a popup using resource keys for title/text
-	 * 
-	 * @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 details actual text for details (not a key)
-	 * @param textParams any parameters for text
-	 * 
-	 * @note Display moved to end to remove conflict in constructors
-	 */
-  public MessagePopupShell(String icon, String keyPrefix,
-			String details, String[] textParams, Display display) {
-  	this(display, icon, MessageText.getString(keyPrefix + ".title"),
-				MessageText.getString(keyPrefix + ".text", textParams), details);
-	}
-
-  public MessagePopupShell(Display display,String icon,String title,String errorMessage,String details) {
-    closeTimer = new Timer(true);
-
-    this.display = display;
-    this.icon = icon;
-    detailsShell = new Shell(display,SWT.BORDER | SWT.ON_TOP);
-    Utils.setShellIcon(detailsShell);
-    
-    detailsShell.setLayout(new FillLayout());
-    StyledText textDetails = new StyledText(detailsShell, SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);  
-    textDetails.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
-    textDetails.setWordWrap( true );
-    detailsShell.layout();    
-    detailsShell.setSize(550,300);    
-    
-
-    int popupWidth = 280;
-    int popupHeight = 170;
-
-    shell = new Shell(display,SWT.ON_TOP);
-    Utils.setShellIcon(shell);
-
-    FormLayout layout = new FormLayout();
-    layout.marginHeight = 0; layout.marginWidth = 0; 
-    try {
-      layout.spacing = 0;
-    } catch (NoSuchFieldError e) {
-      /* Ignore for Pre 3.0 SWT.. */
-    }
-    shell.setLayout(layout);
-    
-    ImageLoader imageLoader = ImageLoader.getInstance();
-    Image popup_image = imageLoader.getImage("popup");
-
-		// this code is here to ensure that we can still show error messages even if images
-		// are failing to load (e.g. coz there's a ! in AZ install dir... )
-
-		GC gcImage = null;
-		if (ImageLoader.isRealImage(popup_image)) {
-			shellImg = new Image(display, popup_image, SWT.IMAGE_COPY);
-	    popupWidth = popup_image.getBounds().width; 
-	    popupHeight = popup_image.getBounds().height;
-		} else {
-			shellImg = new Image(display,
-					new Rectangle(0, 0, popupWidth, popupHeight));
-		}
-    imageLoader.releaseImage("popup");
-
-    shell.setSize(popupWidth, popupHeight);
-
-		gcImage = new GC(shellImg);
-
-		Image imgIcon = imageLoader.getImage(icon);
-		int iconWidth = 0;
-		int iconHeight = 15;
-		if (ImageLoader.isRealImage(imgIcon)) {
-			gcImage.drawImage(imgIcon, 5, 5);
-	    iconWidth = imgIcon.getBounds().width;
-			iconHeight = imgIcon.getBounds().height;
-		}
-    imageLoader.releaseImage(icon);
-	    
-
-		Font tempFont = shell.getFont();
-		FontData[] fontDataMain = tempFont.getFontData();
-		for (int i = 0; i < fontDataMain.length; i++) {
-			fontDataMain[i].setStyle(SWT.BOLD);
-			fontDataMain[i].setHeight((int) (fontDataMain[i].getHeight() * 1.2));
-		}
-
-		Font fontTitle = new Font(display, fontDataMain);
-		gcImage.setFont(fontTitle);
-
-		Rectangle rect = new Rectangle(iconWidth + 10, 5, popupWidth - iconWidth
-				- 15, iconHeight);
-		GCStringPrinter.printString(gcImage, title, rect);
-
-		gcImage.setFont(tempFont);
-		fontTitle.dispose();
-
-		rect = new Rectangle(5, iconHeight + 5, popupWidth - 10, popupHeight
-				- iconHeight - 60);
-		boolean bItFit = GCStringPrinter.printString(gcImage, errorMessage, rect);
-
-		gcImage.dispose(); 
-		if (!bItFit && details == null)
-			details = errorMessage;
-    
-    if(details != null)
-      textDetails.setText(details);
-
-    final Button btnDetails = new Button(shell,SWT.TOGGLE);
-    Messages.setLanguageText(btnDetails,"popup.error.details");    
-    btnDetails.setEnabled(details != null);
-    
-    final Button btnHide = new Button(shell,SWT.PUSH);
-    Messages.setLanguageText(btnHide,"popup.error.hide");
-    
-    Label lblImage = new Label(shell,SWT.NULL);
-	
-	if ( shellImg != null ){
-		lblImage.setImage(shellImg);
-	}
-    
-    FormData formData;
-    
-    formData = new FormData();    
-    formData.right = new FormAttachment(btnHide,-5);
-    formData.bottom = new FormAttachment(100,-5);
-    btnDetails.setLayoutData(formData);
-    
-    formData = new FormData();
-    formData.right = new FormAttachment(100,-5);
-    formData.bottom = new FormAttachment(100,-5);
-    btnHide.setLayoutData(formData);
-    
-    formData = new FormData();
-    formData.left = new FormAttachment(0,0);
-    formData.top = new FormAttachment(0,0);
-    lblImage.setLayoutData(formData);
-    
-    Button btnHideAll = null;
-    if (viewStack.size() > 0) {
-    	btnHideAll = new Button(shell, SWT.PUSH);
-    	btnHideAll.moveAbove(btnDetails);
-    	Messages.setLanguageText(btnHideAll, "popup.error.hideall");
-    	
-    	formData = new FormData();
-    	formData.right = new FormAttachment(btnDetails, -5);
-    	formData.bottom  = new FormAttachment(100,-5);
-    	btnHideAll.setLayoutData(formData);
-    	
-    	btnHideAll.addListener(SWT.MouseUp, new Listener() {
-    		public void handleEvent(Event event) {
-          btnHide.setEnabled(false);
-          btnDetails.setEnabled(false);
-          
-          for (Iterator iter = viewStack.iterator(); iter.hasNext();) {
-						WeakReference wr = (WeakReference) iter.next();
-						MessagePopupShell popup = (MessagePopupShell) wr.get();
-						iter.remove();
-
-						if (popup == null)
-							return;
-
-						popup.shell.dispose();
-						popup.detailsShell.dispose();
-						if (popup.shellImg != null) {
-							popup.shellImg.dispose();
-						}
-					}
-    		}
-    	});
-    }
-    
-    shell.layout();
-    shell.setTabList(new Control[] {btnDetails, btnHide});
-
-    btnHide.addListener(SWT.MouseUp, new Listener() {
-      public void handleEvent(Event arg0) {
-          btnHide.setEnabled(false);
-          btnDetails.setEnabled(false);
-          hideShell();
-      }
-    });
-    
-    btnDetails.addListener(SWT.MouseUp, new Listener() {
-      public void handleEvent(Event arg0) {
-       detailsShell.setVisible(btnDetails.getSelection());
-      }
-    });
-    
-    Rectangle bounds = null;
-    try {
-    	UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-    	if (uiFunctions != null) {
-				Shell mainShell = uiFunctions.getMainShell();
-				bounds = mainShell.getMonitor().getClientArea();
-    	}
-    } catch (Exception e) {
-    }
-    if (bounds == null) {
-    	bounds = display.getClientArea();
-    }
-
-    x0 = bounds.x + bounds.width - popupWidth - 5;
-    x1 = bounds.x + bounds.width;
-
-    y0 = bounds.y + bounds.height;
-    y1 = bounds.y + bounds.height - popupHeight - 5;
-    
-    	// currently always animate
-    
-    if ( true ){
-	    shell.setLocation(x0,y0);
-	    viewStack.addFirst(new WeakReference(this));
-	    detailsShell.setLocation(x1-detailsShell.getSize().x,y1-detailsShell.getSize().y);
-	    currentAnimator = new LinearAnimator(this,new Point(x0,y0),new Point(x0,y1),20,30);
-	    currentAnimator.start();
-	    shell.open();
-    }else{
-        shell.setLocation(x0,y1);
-	    viewStack.addFirst(new WeakReference(this));
-	    detailsShell.setLocation(x1-detailsShell.getSize().x,y1-detailsShell.getSize().y);
-	    currentAnimator = new LinearAnimator(this,new Point(x0,y1),new Point(x0,y1),20,30);
-	    animationStarted(currentAnimator);
-	    shell.open();
-	    animationEnded(currentAnimator);
-    }
-    }
-
-    private void hideShell()
-    {
-    	try {
-        if(currentAnimator == null) {
-          closeTimer.cancel();
-          detailsShell.setVisible(false);
-          detailsShell.forceActive();
-          if(!Constants.isOSX){detailsShell.forceFocus();}
-          currentAnimator = new LinearAnimator(this,new Point(x0,y1),new Point(x1,y1),20,30);
-          currentAnimator.start();
-          closeAfterAnimation = true;
-        }
-    	} catch (Exception e) {
-    		closeAfterAnimation = true;
-    		animationEnded(null);
-    	}
-    }
-
-
-  private Animator currentAnimator;
-  private boolean closeAfterAnimation;
-  int x0,y0,x1,y1;
-  
-  public void animationEnded(Animator source) {
-    if(source == currentAnimator) {
-      currentAnimator = null;
-    }
-    if(closeAfterAnimation) {   
-      if(display == null || display.isDisposed())
-        return;
-      display.asyncExec(new AERunnable(){
-        public void runSupport() {
-          viewStack.removeFirst();
-          shell.dispose();
-          detailsShell.dispose();
-		  if ( shellImg != null ){
-			  shellImg.dispose();
-		  }
-        }
-      });     
-    }
-    else {
-        scheduleAutocloseTask();
-    }
-  }
-
-   private void scheduleAutocloseTask() {
-       final int delay = COConfigurationManager.getIntParameter("Message Popup Autoclose in Seconds") * 1000;
-        if(delay < 1000)
-            return;
-
-       closeTimer.scheduleAtFixedRate(new TimerTask() {
-           public void run() {
-               display.syncExec(new AERunnable() {
-                    public void runSupport() {
-                        if(shell.isDisposed()) {
-                            closeTimer.cancel();
-                            return;
-                        }
-
-                        final boolean notInfoType = MessagePopupShell.this.icon != ICON_INFO;
-                        if(notInfoType) {
-                            closeTimer.cancel();
-                            return;
-                        }
-
-                        final boolean notTopWindow = ((WeakReference)viewStack.getFirst()).get() != MessagePopupShell.this;
-                        final boolean animationInProgress = currentAnimator != null;
-                        final boolean detailsOpen = (!detailsShell.isDisposed() && detailsShell.isVisible());
-
-                        final Control cc = display.getCursorControl();
-                        boolean mouseOver = (cc == shell);
-                        if(!mouseOver) {
-                            final Control[] childControls = shell.getChildren();
-                            for(int i = 0; i < childControls.length; i++) {
-                                if(childControls[i] == cc) {
-                                    mouseOver = true;
-                                    break;
-                                }
-                            }
-                        }
-
-                        if(notTopWindow || mouseOver || animationInProgress || detailsOpen)
-                            return;
-
-                        hideShell();
-                    }
-                });
-           }
-       }, delay, delay);
-   }
-
-  public void animationStarted(Animator source) {
-  }
-
-  
-  public Shell getShell() {
-    return shell;
-  }
-  
-  public void reportPercent(int percent) {    
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java b/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
index 668f717..2a4d023 100644
--- a/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/MessageSlideShell.java
@@ -40,7 +40,6 @@ import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter.URLInfo;
 
 import com.aelitis.azureus.ui.swt.*;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 /**
@@ -89,8 +88,8 @@ public class MessageSlideShell
 	private final static AEMonitor monitor = new AEMonitor("slidey_mon");
 
 	/** List of all popups ever created */
-	private static ArrayList historyList = new ArrayList();
-
+	private static ArrayList<PopupParams> historyList = new ArrayList<PopupParams>();
+	
 	/** Current popup being displayed */
 	private static int currentPopupIndex = -1;
 
@@ -120,7 +119,7 @@ public class MessageSlideShell
 	private boolean bDelayPaused = false;
 
 	/** List of SWT objects needing disposal */
-	private ArrayList disposeList = new ArrayList();
+	private ArrayList<Object> disposeList = new ArrayList<Object>();
 
 	/** Text to put into details popup */
 	private String sDetails;
@@ -128,8 +127,6 @@ public class MessageSlideShell
 	/** Position this popup is in the history list */
 	private int idxHistory;
 
-	private Image imgPopup;
-
 	protected Color colorURL;
 
 	private Color colorFG;
@@ -195,7 +192,7 @@ public class MessageSlideShell
 
 			PopupParams popupParams = new PopupParams(iconID, title, text, details,
 					relatedObjects, timeoutSecs );
-			historyList.add(popupParams);
+			addToHistory(popupParams);
 			if (currentPopupIndex < 0) {
 				create(display, popupParams, true);
 			}
@@ -208,6 +205,20 @@ public class MessageSlideShell
 		}
 	}
 
+	/**
+	 * @param popupParams
+	 *
+	 * @since 4.1.0.5
+	 */
+	private static void addToHistory(PopupParams popupParams) {
+		monitor.enter();
+		try {
+			historyList.add(popupParams);
+		} finally {
+			monitor.exit();
+		}
+	}
+
 	private MessageSlideShell(Display display, PopupParams popupParams,
 			boolean bSlide) {
 		create(display, popupParams, bSlide);
@@ -227,8 +238,7 @@ public class MessageSlideShell
 				if (!last_unread || msg_index == -1) {
 					msg_index = historyList.size() - 1;
 				}
-				new MessageSlideShell(display,
-						(PopupParams) historyList.get(msg_index), true);
+				new MessageSlideShell(display, historyList.get(msg_index), true);
 			}
 		});
 	}
@@ -241,7 +251,7 @@ public class MessageSlideShell
 			String details, Object[] relatedTo, int timeoutSecs ) {
 		try {
 			monitor.enter();
-			historyList.add(new PopupParams(iconID, title, text, details, relatedTo, timeoutSecs));
+			addToHistory(new PopupParams(iconID, title, text, details, relatedTo, timeoutSecs));
 			if (firstUnreadMessage == -1) {
 				firstUnreadMessage = historyList.size() - 1;
 			}
@@ -340,35 +350,12 @@ public class MessageSlideShell
 			// ignore
 		}
 		Utils.setShellIcon(shell);
-		shell.setText(popupParams.title);
-
-		// Disable BG Image on OSX
-		if (imgPopup == null) {
-			imgPopup = ImageLoader.getInstance().getImage("popup");
-			shell.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					ImageLoader.getInstance().releaseImage("popup");
-				}
-			});
-		}
-		Rectangle imgPopupBounds;
-		if (imgPopup != null) {
-			shellWidth = imgPopup.getBounds().width;
-			
-			/*
-			 * KN: The buttons at the bottom of the shell has an automatic horizontal spacing on OSX;
-			 * compensating the shellWidth so that the buttons will not overlap the image at the bottom left
-			 * of the shell
-			 */
-			if (true == Constants.isOSX) {
-				shellWidth += 30;
-			}
-			imgPopupBounds = imgPopup.getBounds();
-		} else {
-			shellWidth = SHELL_DEF_WIDTH;
-			imgPopupBounds = null;
+		if (popupParams.title != null) {
+			shell.setText(popupParams.title);
 		}
 
+		shellWidth = SHELL_DEF_WIDTH;
+
 		UISkinnableSWTListener[] listeners = UISkinnableManagerSWT.getInstance().getSkinnableListeners(
 				MessageSlideShell.class.toString());
 		for (int i = 0; i < listeners.length; i++) {
@@ -399,20 +386,22 @@ public class MessageSlideShell
 		lblIcon.setImage(imgIcon);
 		lblIcon.setLayoutData(new GridData());
 
-		Label lblTitle = new Label(cShell, SWT.getVersion() < 3100 ? SWT.NONE
-				: SWT.WRAP);
-		gridData = new GridData(GridData.FILL_HORIZONTAL);
-		if (SWT.getVersion() < 3100)
-			gridData.widthHint = 140;
-		lblTitle.setLayoutData(gridData);
-		lblTitle.setForeground(colorFG);
-		lblTitle.setText(popupParams.title);
-		FontData[] fontData = lblTitle.getFont().getFontData();
-		fontData[0].setStyle(SWT.BOLD);
-		fontData[0].setHeight((int) (fontData[0].getHeight() * 1.5));
-		Font boldFont = new Font(display, fontData);
-		disposeList.add(boldFont);
-		lblTitle.setFont(boldFont);
+		if (popupParams.title != null) {
+  		Label lblTitle = new Label(cShell, SWT.getVersion() < 3100 ? SWT.NONE
+  				: SWT.WRAP);
+  		gridData = new GridData(GridData.FILL_HORIZONTAL);
+  		if (SWT.getVersion() < 3100)
+  			gridData.widthHint = 140;
+  		lblTitle.setLayoutData(gridData);
+  		lblTitle.setForeground(colorFG);
+  		lblTitle.setText(popupParams.title);
+  		FontData[] fontData = lblTitle.getFont().getFontData();
+  		fontData[0].setStyle(SWT.BOLD);
+  		fontData[0].setHeight((int) (fontData[0].getHeight() * 1.5));
+  		Font boldFont = new Font(display, fontData);
+  		disposeList.add(boldFont);
+  		lblTitle.setFont(boldFont);
+		}
 
 		final Button btnDetails = new Button(cShell, SWT.TOGGLE);
 		btnDetails.setForeground(colorFG);
@@ -469,7 +458,7 @@ public class MessageSlideShell
 		lblCloseIn = new Label(cShell, SWT.TRAIL);
 		lblCloseIn.setForeground(colorFG);
 		// Ensure computeSize computes for 2 lined label
-		lblCloseIn.setText("\n");
+		lblCloseIn.setText(" \n ");
 		gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
 		gridData.horizontalSpan = 3;
 		lblCloseIn.setLayoutData(gridData);
@@ -512,7 +501,7 @@ public class MessageSlideShell
 					disposeShell(shell);
 					int idx = historyList.indexOf(popupParams) - 1;
 					if (idx >= 0) {
-						PopupParams item = (PopupParams) historyList.get(idx);
+						PopupParams item = historyList.get(idx);
 						showPopup(display, item, false);
 						disposeShell(shell);
 					}
@@ -531,8 +520,7 @@ public class MessageSlideShell
 					System.out.println("Next Pressed");
 
 				if (idxHistory + 1 < historyList.size()) {
-					showPopup(display, (PopupParams) historyList.get(idxHistory + 1),
-							false);
+					showPopup(display, historyList.get(idxHistory + 1), false);
 				}
 
 				disposeShell(shell);
@@ -553,101 +541,6 @@ public class MessageSlideShell
 			}
 		}
 
-		if (imgPopup != null) {
-			// no text on the frog in the bottom left
-			int bottomHeight = cButtons.computeSize(SWT.DEFAULT, SWT.DEFAULT).y
-					+ lblCloseIn.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
-			if (bottomHeight < 50)
-				bestSize.y += 50 - bottomHeight;
-
-			final Image imgBackground = new Image(display, bestSize.x, bestSize.y);
-
-			disposeList.add(imgBackground);
-			GC gc = new GC(imgBackground);
-			int dstY = imgPopupBounds.height - bestSize.y;
-			if (dstY < 0)
-				dstY = 0;
-			gc.drawImage(imgPopup, 0, dstY, imgPopupBounds.width,
-					imgPopupBounds.height - dstY, 0, 0, bestSize.x, bestSize.y);
-			gc.dispose();
-
-			boolean bAlternateDrawing = true;
-			try {
-				shell.setBackgroundImage(imgBackground);
-				bAlternateDrawing = false;
-			} catch (NoSuchMethodError e) {
-			}
-
-			if (bAlternateDrawing) {
-				// Drawing of BG Image for pre SWT 3.2
-
-				cShell.addPaintListener(new PaintListener() {
-					public void paintControl(PaintEvent e) {
-						e.gc.drawImage(imgBackground, e.x, e.y, e.width, e.height, e.x,
-								e.y, e.width, e.height);
-					}
-				});
-
-				Color colorBG = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
-				final RGB bgRGB = colorBG.getRGB();
-
-				PaintListener paintListener = new PaintListener() {
-					// OSX: copyArea() causes a paint event, resulting in recursion
-					boolean alreadyPainting = false;
-
-					public void paintControl(PaintEvent e) {
-						if (alreadyPainting || e.width <= 0 || e.height <= 0) {
-							return;
-						}
-
-						alreadyPainting = true;
-
-						try {
-							Rectangle bounds = ((Control) e.widget).getBounds();
-
-							Image img = new Image(display, e.width, e.height);
-							e.gc.copyArea(img, e.x, e.y);
-
-							e.gc.drawImage(imgBackground, -bounds.x, -bounds.y);
-
-							// Set the background color to invisible.  img.setBackground
-							// doesn't work, so change transparentPixel directly and roll
-							// a new image
-							ImageData data = img.getImageData();
-							data.transparentPixel = data.palette.getPixel(bgRGB);
-							Image imgTransparent = new Image(display, data);
-
-							// This is an alternative way of setting the transparency.
-							// Probably much slower
-
-							//int bgIndex = data.palette.getPixel(bgRGB);
-							//ImageData transparencyMask = data.getTransparencyMask();
-							//for (int y = 0; y < data.height; y++) {
-							//	for (int x = 0; x < data.width; x++) {
-							//		if (bgIndex == data.getPixel(x, y))
-							//			transparencyMask.setPixel(x, y, 0);
-							//	}
-							//}
-							//
-							//Image imgTransparent = new Image(display, data, transparencyMask);
-
-							e.gc.drawImage(imgTransparent, 0, 0, e.width, e.height, e.x, e.y,
-									e.width, e.height);
-
-							img.dispose();
-							imgTransparent.dispose();
-						} finally {
-							alreadyPainting = false;
-						}
-					}
-				};
-
-				shell.setBackground(colorBG);
-				cShell.setBackground(colorBG);
-				addPaintListener(cShell, paintListener, colorBG, true);
-			}
-		}
-
 		Rectangle bounds = null;
 		try {
 			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
@@ -884,28 +777,6 @@ public class MessageSlideShell
 		}
 	}
 
-	private void addPaintListener(Composite parent, PaintListener listener,
-			Color colorBG, boolean childrenOnly) {
-		if (parent == null || listener == null || parent.isDisposed())
-			return;
-
-		if (!childrenOnly) {
-			parent.addPaintListener(listener);
-			parent.setBackground(colorBG);
-		}
-
-		Control[] children = parent.getChildren();
-		for (int i = 0; i < children.length; i++) {
-			Control control = children[i];
-
-			control.addPaintListener(listener);
-			control.setBackground(colorBG);
-
-			if (control instanceof Composite)
-				addPaintListener((Composite) control, listener, colorBG, true);
-		}
-	}
-
 	/**
 	 * removes mousetracklistener from composite and all it's children
 	 * 
@@ -1038,7 +909,7 @@ public class MessageSlideShell
 				// and that it has handled whether to show the next popup or not
 				if (shell != null && !shell.isDisposed()) {
 					if (idx + 1 < historyList.size()) {
-						showPopup(display, (PopupParams) historyList.get(idx + 1), true);
+						showPopup(display, historyList.get(idx + 1), true);
 					}
 
 					// slide out current popup
@@ -1077,21 +948,21 @@ public class MessageSlideShell
 		}
 	}
 
-	private static class PopupParams
+	public static class PopupParams
 	{
-		int iconID;
+		public int iconID;
 
-		String title;
+		public String title;
 
-		String text;
+		public String text;
 
-		String details;
+		public String details;
 
-		long addedOn;
+		public long addedOn;
 
-		Object[] relatedTo;
+		public Object[] relatedTo;
 
-		int	timeoutSecs;
+		public int	timeoutSecs;
 		
 		/**
 		 * @param iconID
@@ -1193,20 +1064,6 @@ public class MessageSlideShell
 		MessageSlideShell.waitUntilClosed();
 	}
 
-	/**
-	 * @return the imgPopup
-	 */
-	public Image getImgPopup() {
-		return imgPopup;
-	}
-
-	/**
-	 * @param imgPopup the imgPopup to set
-	 */
-	public void setImgPopup(Image imgPopup) {
-		this.imgPopup = imgPopup;
-	}
-
 	public Color getUrlColor() {
 		return colorURL;
 	}
diff --git a/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java b/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
index e9c360b..f48cae2 100644
--- a/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
+++ b/org/gudy/azureus2/ui/swt/shells/MultipageWizard.java
@@ -20,6 +20,8 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
 
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+
 abstract public class MultipageWizard
 {
 
@@ -86,7 +88,7 @@ abstract public class MultipageWizard
 
 		titleLabel = new Label(topPanel, SWT.NONE);
 		titleLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
-		Utils.setFontHeight(titleLabel, 16, SWT.NORMAL);
+		FontUtils.setFontHeight(titleLabel, 16, SWT.NORMAL);
 
 		descriptionLabel = new Label(topPanel, SWT.WRAP);
 		GridData gData = new GridData(SWT.FILL, SWT.FILL, true, true);
diff --git a/org/gudy/azureus2/ui/swt/shells/PopupShell.java b/org/gudy/azureus2/ui/swt/shells/PopupShell.java
index 8c9b8cb..75db3e0 100644
--- a/org/gudy/azureus2/ui/swt/shells/PopupShell.java
+++ b/org/gudy/azureus2/ui/swt/shells/PopupShell.java
@@ -77,15 +77,6 @@ public class PopupShell {
   }
   
   protected void layout() {
-    Label label = new Label(shell,SWT.NULL);
-		ImageLoader.getInstance().setLabelImage(label, "popup");
-    
-    FormData formData = new FormData();
-    formData.left = new FormAttachment(0,0);
-    formData.top = new FormAttachment(0,0);
-    
-    label.setLayoutData(formData); 
-    
     shell.layout();
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/speedtest/SpeedTestPanel.java b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestPanel.java
index 7582a59..d743588 100644
--- a/org/gudy/azureus2/ui/swt/speedtest/SpeedTestPanel.java
+++ b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestPanel.java
@@ -42,7 +42,6 @@ import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
 import org.gudy.azureus2.ui.swt.wizard.WizardListener;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdminSpeedTestScheduledTest;
@@ -132,8 +131,8 @@ SpeedTestPanel
 
         final Label linkLabel = new Label(azWiki, SWT.NULL);
         linkLabel.setText( Constants.APP_NAME + " Wiki Speed Test" );
-        linkLabel.setData("http://www.azureuswiki.com/index.php/Speed_Test_FAQ");
-        linkLabel.setCursor(Cursors.handCursor);
+        linkLabel.setData("http://wiki.vuze.com/w/Speed_Test_FAQ");
+        linkLabel.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
         linkLabel.setForeground(Colors.blue);
         azwGridData = new GridData();
         azwGridData.horizontalIndent = 10;
diff --git a/org/gudy/azureus2/ui/swt/speedtest/SpeedTestSelector.java b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestSelector.java
new file mode 100644
index 0000000..5e6209f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestSelector.java
@@ -0,0 +1,195 @@
+package org.gudy.azureus2.ui.swt.speedtest;
+
+
+
+import java.util.HashMap;
+
+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.config.COConfigurationManager;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.ipc.IPCException;
+import org.gudy.azureus2.plugins.ipc.IPCInterface;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.config.wizard.ConfigureWizard;
+import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.wizard.AbstractWizardPanel;
+import org.gudy.azureus2.ui.swt.wizard.IWizardPanel;
+
+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.aelitis.azureus.ui.UserPrompterResultListener;
+
+public class 
+SpeedTestSelector
+	extends AbstractWizardPanel<SpeedTestWizard> 
+{
+	private boolean	mlab_test = true;
+
+	public SpeedTestSelector(SpeedTestWizard wizard, IWizardPanel previous) {
+		super(wizard, previous);
+	}
+
+	public void show() {
+		wizard.setTitle(MessageText.getString("speedtest.wizard.select.title"));
+		wizard.setCurrentInfo( "" );
+		final Composite rootPanel = wizard.getPanel();
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		rootPanel.setLayout(layout);
+
+		Composite panel = new Composite(rootPanel, SWT.NULL);
+		GridData gridData = new GridData(GridData.FILL_BOTH);
+		panel.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 1;
+		panel.setLayout(layout);
+
+		final Group gRadio = new Group(panel, SWT.NULL);
+		Messages.setLanguageText(gRadio, "speedtest.wizard.select.group");
+		gRadio.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 1;
+		gRadio.setLayout( layout );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gRadio.setLayoutData(gridData);
+
+
+		// general test
+
+		Button auto_button = new Button (gRadio, SWT.RADIO);
+		Messages.setLanguageText(auto_button, "speedtest.wizard.select.general");
+		auto_button.setSelection( true );
+
+		// BT
+
+		final Button manual_button = new Button( gRadio, SWT.RADIO );
+		Messages.setLanguageText(manual_button, "speedtest.wizard.select.bt");   
+
+		manual_button.addListener(
+				SWT.Selection,
+				new Listener()
+				{
+					public void 
+					handleEvent(
+							Event arg0 ) 
+					{
+						mlab_test = !manual_button.getSelection();
+					}
+				});
+	}
+
+
+
+	public boolean 
+	isNextEnabled() 
+	{
+		return( true );
+	}
+
+	public boolean 
+	isPreviousEnabled() 
+	{
+		return( false );
+	}
+
+	public IWizardPanel 
+	getNextPanel() 
+	{
+		if ( mlab_test ){
+
+			wizard.close();
+
+			runMLABTest(true, null);
+			
+			//new ConfigureWizard( false, ConfigureWizard.WIZARD_MODE_SPEED_TEST_AUTO );
+			
+			return( null );
+
+		}else{
+
+			return( new SpeedTestPanel( wizard, null ));
+		}
+	}
+
+	public static void runMLABTest(final boolean allowShaperProbeLogic,
+			final Runnable runWhenClosed) {
+		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				UIFunctionsManager.getUIFunctions().installPlugin("mlab",
+						"dlg.install.mlab", new UIFunctions.actionListener() {
+							public void actionComplete(Object result) {
+								if (result instanceof Boolean) {
+									_runMLABTest(allowShaperProbeLogic, runWhenClosed);
+								} else {
+
+									try {
+										Throwable error = (Throwable) result;
+
+										Debug.out(error);
+
+									} finally {
+										if (runWhenClosed != null) {
+											runWhenClosed.run();
+										}
+									}
+								}
+							}
+						});
+			}
+		});
+	}
+	
+	private static void _runMLABTest(final boolean allowShaperProbeLogic,
+			final Runnable runWhenClosed) {
+		PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByID(
+				"mlab");
+		try {
+			HashMap<String, Object> map = new HashMap<String, Object>();
+			map.put("allowShaperProbeLogic", Boolean.valueOf(allowShaperProbeLogic));
+			pi.getIPC().invoke("runTest", new Object[] {
+				map,
+				new IPCInterface() {
+					public Object invoke(String methodName, Object[] params)
+							throws IPCException {
+						// we could set SpeedTest Completed when methodName == "results"
+						// or ask user if they want to be prompted again if it isn't
+						// But, we'd have to pass a param into runMLABTest (so we don't
+						// get prompt on menu invocation).
+
+						// For now, show only once, with no reprompt (even if they cancel).
+						// They can use the menu
+						COConfigurationManager.setParameter("SpeedTest Completed", true);
+
+						if (runWhenClosed != null) {
+							runWhenClosed.run();
+						}
+						return null;
+					}
+
+					public boolean canInvoke(String methodName, Object[] params) {
+						return true;
+					}
+				},
+				true
+			});
+
+		} catch (Throwable e) {
+
+			Debug.out(e);
+			if (runWhenClosed != null) {
+				runWhenClosed.run();
+			}
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/speedtest/SpeedTestWizard.java b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestWizard.java
index 48f3859..8d9742c 100644
--- a/org/gudy/azureus2/ui/swt/speedtest/SpeedTestWizard.java
+++ b/org/gudy/azureus2/ui/swt/speedtest/SpeedTestWizard.java
@@ -39,7 +39,7 @@ SpeedTestWizard
 	SpeedTestWizard() 
 	{
 		super("speedtest.wizard.title");
-		SpeedTestPanel panel = new SpeedTestPanel(this, null);
+		SpeedTestSelector panel = new SpeedTestSelector(this, null);
 		setFirstPanel(panel);
     }
 
diff --git a/org/gudy/azureus2/ui/swt/test/Main.java b/org/gudy/azureus2/ui/swt/test/Main.java
deleted file mode 100644
index a6dbfb3..0000000
--- a/org/gudy/azureus2/ui/swt/test/Main.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2000, 2003 IBM Corp.  All rights reserved.
- * This file is made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- */
- 
-/*
- * Table example snippet: place arbitrary controls in a table
- *
- * For a list of all SWT example snippets see
- * http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-swt-home/dev.html#snippets
- */
-
-package org.gudy.azureus2.ui.swt.test;
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.swt.custom.*;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-
-public class Main {
-  
-  private Color blue;
-  private Table table;
-  
-  
-  private boolean mousePressed;
-  private TableItem selectedItem;
-  Rectangle oldBounds;
-  Image oldImage;
-  
-  public Main() {
-    final Display display = new Display ();
-    blue = new Color(display,0,0,128);
-    final Shell shell = new Shell (display);
-    GridLayout layout = new GridLayout();
-    layout.numColumns = 3;
-    GridData gridData;
-    shell.setLayout (layout); 
-    table = new Table (shell, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
-    gridData = new GridData(GridData.FILL_BOTH);
-    gridData.horizontalSpan = 3;
-    table.setLayoutData(gridData);
-    table.setLinesVisible (true);    
-    Font f = table.getFont();
-    FontData fd = f.getFontData()[0];
-    fd.setHeight(9);
-    Font font = new Font(display, fd);
-    table.setFont(font);
-    
-    Button bOk = new Button(shell,SWT.PUSH);
-    bOk.setText("Ok");
-    gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_END | GridData.HORIZONTAL_ALIGN_FILL);
-    gridData.grabExcessHorizontalSpace = true;
-    gridData.widthHint = 70;
-    bOk.setLayoutData(gridData);
-      
-    Button bCancel = new Button(shell,SWT.PUSH);
-    bCancel.setText("Cancel");
-    gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-    gridData.grabExcessHorizontalSpace = false;
-    gridData.widthHint = 70;
-    bCancel.setLayoutData(gridData);
-      
-    Button bApply = new Button(shell,SWT.PUSH);
-    bApply.setText("Apply");
-    gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-    gridData.grabExcessHorizontalSpace = false;
-    gridData.widthHint = 70;
-    bApply.setLayoutData(gridData);
-    
-    for (int i=0; i<2; i++) {
-      new TableColumn(table, SWT.NONE);    
-    }
-    for (int i=0; i<12; i++) {
-      createTableRow(-1,"Toto" + i , false);
-    }
-    TableItem item  = new TableItem(table,SWT.NULL);
-    item.setText(1,"---");
-    //Hack to get a correct width
-    table.getColumn(0).setWidth(20);
-    table.getColumn(1).setWidth(200);
-    
-    
-    table.addMouseListener(new MouseAdapter() {
-      
-      public void mouseDown(MouseEvent arg0) {
-        mousePressed = true;
-        selectedItem = table.getItem(new Point(arg0.x,arg0.y));
-        if(selectedItem.getText(1).equals("---")) {
-          selectedItem = null;
-        }
-      }
-      
-      public void mouseUp(MouseEvent e) {
-        mousePressed = false;
-        //1. Restore old image
-        if(oldBounds != null && oldImage != null) {
-          GC gc = new GC(table);
-          gc.drawImage(oldImage,oldBounds.x,oldBounds.y);
-          oldImage.dispose();
-          oldImage = null;
-          oldBounds = null;
-        }
-        Point p = new Point(e.x,e.y);
-        TableItem item = table.getItem(p);
-        if(item != null && selectedItem != null) {
-          int index = table.indexOf(item);
-          int oldIndex = table.indexOf(selectedItem);
-          if(index == oldIndex)
-            return;
-          String name = (String) selectedItem.getData("name");
-          Button oldBtn = (Button)selectedItem.getData("button");
-          boolean selected = oldBtn.getSelection();
-          oldBtn.dispose();
-          createTableRow(index,name,selected);
-          selectedItem.dispose();        
-          Point size = shell.getSize();
-          shell.setSize(size.x+1,size.y+1);
-          shell.setSize(size);
-        }
-      }
-    });
-    
-    table.addMouseMoveListener(new MouseMoveListener(){
-      public void mouseMove(MouseEvent e) {
-        if(mousePressed && selectedItem != null) {
-          Point p = new Point(e.x,e.y);
-          TableItem item = table.getItem(p);
-          if(item != null) {
-            GC gc = new GC(table);
-            Rectangle bounds = item.getBounds(1);
-            //1. Restore old image
-            if(oldBounds != null && oldImage != null) {
-              gc.drawImage(oldImage,oldBounds.x,oldBounds.y);
-              oldImage.dispose();
-              oldImage = null;
-              oldBounds = null;
-            }
-            //2. Store the image
-            oldImage = new Image(display,bounds.width,2);
-            gc.copyArea(oldImage,bounds.x,bounds.y);
-            oldBounds = bounds;
-            
-            //3. Draw a thick line
-            gc.setBackground(blue);
-            gc.fillRectangle(bounds.x,bounds.y,bounds.width,2);
-          }
-        }
-      }
-    });
-    shell.pack ();
-    shell.open ();
-    while (!shell.isDisposed ()) {
-      if (!display.readAndDispatch ()) display.sleep ();
-    }
-    display.dispose ();
-    if (font != null && !font.isDisposed()) {
-      font.dispose();
-    }
-}
-  
-  private void createTableRow(int index,String name,boolean selected) {
-    TableItem item;
-    
-    if(index == -1)
-      item = new TableItem (table, SWT.NONE);
-    else
-      item = new TableItem (table, SWT.NONE,index);
-    
-    item.setText(1,name);
-    item.setData("name",name);
-    TableEditor editor = new TableEditor (table);
-    Button button = new Button (table, SWT.CHECK);
-    button.setSelection(selected);
-    button.pack ();
-    editor.minimumWidth = button.getSize ().x;    
-    editor.horizontalAlignment = SWT.CENTER;
-    editor.setEditor (button, item, 0);
-    item.setData("button",button);      
-  }
-  
-public static void main(String[] args) {
-  new Main();
-}
-}
-
diff --git a/org/gudy/azureus2/ui/swt/test/PrintTransferTypes.java b/org/gudy/azureus2/ui/swt/test/PrintTransferTypes.java
deleted file mode 100644
index b1bc280..0000000
--- a/org/gudy/azureus2/ui/swt/test/PrintTransferTypes.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package org.gudy.azureus2.ui.swt.test;
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.dnd.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Application to identify supported URL drag and drop IDs from different
- * browsers.
- * 
- * @see org.gudy.azureus2.ui.swt.URLTransfer
- * @author Rene Leonhardt
- */
-public class PrintTransferTypes extends ByteArrayTransfer {
-
-  private static PrintTransferTypes _instance = new PrintTransferTypes();
-  private int[] ids;
-  private String[] names;
-
-  public static void main(String[] args) {
-    Display display = new Display();
-    Shell shell = new Shell(display);
-    shell.setLayout(new FillLayout());
-    Canvas canvas = new Canvas(shell, SWT.NONE);
-    DropTarget target = new DropTarget(canvas, DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_TARGET_MOVE | DND.DROP_NONE);
-    target.setTransfer(new Transfer[] { PrintTransferTypes.getInstance(), TextTransfer.getInstance(), FileTransfer.getInstance()});
-    target.addDropListener(new DropTargetAdapter() {
-      public void dragEnter(DropTargetEvent event) {
-        //        if(event.detail == DND.DROP_NONE)
-        event.detail = DND.DROP_LINK;
-        String ops = "";
-        if ((event.operations & DND.DROP_COPY) != 0)
-          ops += "Copy;";
-        if ((event.operations & DND.DROP_MOVE) != 0)
-          ops += "Move;";
-        if ((event.operations & DND.DROP_LINK) != 0)
-          ops += "Link;";
-        System.out.println("Allowed Operations are " + ops);
-
-        TransferData[] data = event.dataTypes;
-        for (int i = 0; i < data.length; i++) {
-          int id = data[i].type;
-          String name = getNameFromId(id);
-          System.out.println("Data type is " + id + " " + name);
-        }
-      }
-      public void dragOver(DropTargetEvent event) {
-        event.detail = DND.DROP_LINK;
-      }
-      public void drop(DropTargetEvent event) {
-        System.out.println("URL dropped: " + event.data);
-        System.out.println("Data type is " + event.currentDataType.type + " " + getNameFromId(event.currentDataType.type));
-      }
-    });
-
-    shell.setSize(400, 400);
-    shell.open();
-    while (!shell.isDisposed()) {
-      if (!display.readAndDispatch())
-        display.sleep();
-    }
-    display.dispose();
-  }
-
-  public static PrintTransferTypes getInstance() {
-    return _instance;
-  }
-  PrintTransferTypes() {
-    ids = new int[50000];
-    names = new String[50000];
-    for (int i = 0; i < ids.length; i++) {
-      ids[i] = i;
-      names[i] = getNameFromId(i);
-    }
-  }
-  public void javaToNative(Object object, TransferData transferData) {}
-  public Object nativeToJava(TransferData transferData) {
-    byte[] buffer = (byte[]) super.nativeToJava(transferData);
-    if (buffer == null)
-      return null;
-    int size = buffer.length;
-    byte[] text = new byte[size];
-    int j = 0;
-    for (int i = 0; i < buffer.length; i++) {
-      if (buffer[i] != 0)
-        text[j++] = buffer[i];
-    }
-    String data = new String(text, 0, j);
-    int end = data.indexOf("\n");
-    return end >= 0 ? data.substring(0, end) : data;
-  }
-  protected String[] getTypeNames() {
-    return names;
-  }
-  protected int[] getTypeIds() {
-    return ids;
-  }
-  static String getNameFromId(int id) {
-    switch (id) {
-      case 1 :
-        return "CF_TEXT";
-      case 8 :
-        return "CF_DIB";
-      case 13 :
-        return "CF_UNICODETEXT";
-      case 15 :
-        return "CF_HDROP";
-      case 49158 :
-        return "FileName";
-      case 49159 :
-        return "FileNameW";
-      case 49267 :
-        return "Shell IDList Array";
-      case 49350 :
-        return "FileContents";
-      case 49351 :
-        return "FileGroupDescriptor";
-      case 49352 :
-        return "FileGroupDescriptorW";
-      case 49356 :
-        return "HTML Format";
-      case 49357 :
-        return "Preferred DropEffect";
-      case 49361 :
-        return "UniformResourceLocator";
-      case 49362 :
-        return "UniformResourceLocator"; // or InShellDragLoop
-      case 49368 :
-        return "UniformResourceLocator";
-      case 49429 :
-        return "UniformResourceLocatorW";
-      case 49458 :
-        return "UniformResourceLocatorW";
-      case 49569 :
-        return "text/html";
-      case 49570 :
-        return "text/_moz_htmlcontext";
-      case 49571 :
-        return "text/_moz_htmlinfo";
-      case 49624 :
-        return "application/x-moz-nativeimage";
-
-    }
-    return "*UNKNOWN_TYPE*";
-  }
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/test/SashFormTest.java b/org/gudy/azureus2/ui/swt/test/SashFormTest.java
deleted file mode 100644
index 1201d77..0000000
--- a/org/gudy/azureus2/ui/swt/test/SashFormTest.java
+++ /dev/null
@@ -1,58 +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 org.gudy.azureus2.ui.swt.test;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * @author TuxPaper
- * @created Dec 1, 2006
- *
- */
-public class SashFormTest
-{
-	public static void main(String[] args) {
-		Display display = Display.getDefault();
-
-		Shell shell = new Shell(display, SWT.SHELL_TRIM);
-		shell.setLayout(new FillLayout());
-
-		SashForm sf = new SashForm(shell, SWT.VERTICAL);
-		sf.SASH_WIDTH = 10;
-		sf.setLayout(new FillLayout());
-		
-		new Composite(sf, SWT.BORDER);
-		new Composite(sf, SWT.BORDER);
-		
-		shell.open();
-
-		while (!shell.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/test/TableTest.java b/org/gudy/azureus2/ui/swt/test/TableTest.java
deleted file mode 100644
index d200182..0000000
--- a/org/gudy/azureus2/ui/swt/test/TableTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Created on Jul 18, 2006 11:13:05 AM
- * 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 org.gudy.azureus2.ui.swt.test;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * @author TuxPaper
- * @created Jul 18, 2006
- *
- */
-public class TableTest
-{
-	static Table tableNormal;
-
-	private static Table tableVirtual;
-
-	static Display display;
-
-	public static void main(String[] args) {
-		display = Display.getDefault();
-
-		Shell shell = new Shell(display, SWT.SHELL_TRIM);
-		shell.setLayout(new FillLayout());
-
-		tableNormal = new Table(shell, SWT.BORDER);
-		tableVirtual = new Table(shell, SWT.BORDER | SWT.VIRTUAL);
-
-		Button btnStart = new Button(shell, SWT.PUSH);
-		btnStart.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				runtest();
-			}
-		});
-
-		shell.open();
-
-		while (!shell.isDisposed()) {
-			if (!display.readAndDispatch()) {
-				display.sleep();
-			}
-		}
-	}
-
-	/**
-	 * 
-	 */
-	protected static void runtest() {
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest1();
-
-		tableNormal.clearAll();
-		waitForComplete();
-
-		runtest2();
-
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest3();
-
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest4();
-		
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest5();
-
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest6();
-
-		tableNormal.clearAll();
-		waitForComplete();
-		runtest7();
-	}
-
-	static void runtest1() {
-		long lStartTime = System.currentTimeMillis();
-
-		for (int i = 0; i < 500; i++) {
-			new TableItem(tableNormal, SWT.None);
-		}
-		waitForComplete();
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("NVI: " + (lEndTime - lStartTime));
-	}
-
-	static void runtest2() {
-		long lStartTime = System.currentTimeMillis();
-
-		tableNormal.setItemCount(500);
-		waitForComplete();
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("NVS: " + (lEndTime - lStartTime));
-		
-	}
-
-	static void runtest3() {
-		long lStartTime = System.currentTimeMillis();
-
-		for (int i = 0; i < 500; i++) {
-			new TableItem(tableVirtual, SWT.None);
-		}
-		waitForComplete();
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("VI:" + (lEndTime - lStartTime));
-	}
-
-	static void runtest4() {
-		long lStartTime = System.currentTimeMillis();
-
-		tableVirtual.setItemCount(500);
-		
-		waitForComplete();
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("Vs:" + (lEndTime - lStartTime));
-	}
-	
-	static void waitForComplete() {
-		while (display.readAndDispatch()) {}
-	}
-
-	static void runtest5() {
-		tableNormal.setItemCount(1000);
-		waitForComplete();
-
-		long lStartTime = System.currentTimeMillis();
-		
-		tableNormal.setItemCount(500);
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("NVD1: " + (lEndTime - lStartTime));
-		
-	}
-
-	static void runtest6() {
-		tableNormal.setItemCount(1000);
-		waitForComplete();
-
-		long lStartTime = System.currentTimeMillis();
-		
-		for (int i = 0; i < 500; i++) {
-			tableNormal.getItem(2).dispose();
-		}
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("NVD2: " + (lEndTime - lStartTime));
-	}
-
-	static void runtest7() {
-		tableNormal.setItemCount(1000);
-		waitForComplete();
-
-
-		int indexes[] = new int[500];
-		for (int i = 0; i < 200; i++) {
-			indexes[i] = i * 2;
-		}
-		int x = 400;
-		for (int i = 200; i < 500; i++) {
-			indexes[i] = x++;
-		}
-
-		long lStartTime = System.currentTimeMillis();
-		
-		tableNormal.remove(indexes);
-
-		long lEndTime = System.currentTimeMillis();
-		System.out.println("NVD3: " + (lEndTime - lStartTime));
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/test/Win32TransferTypes.java b/org/gudy/azureus2/ui/swt/test/Win32TransferTypes.java
deleted file mode 100644
index 638a9ea..0000000
--- a/org/gudy/azureus2/ui/swt/test/Win32TransferTypes.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package org.gudy.azureus2.ui.swt.test;
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.dnd.*;
-import org.eclipse.swt.internal.ole.win32.*;
-import org.eclipse.swt.internal.win32.*;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Application to identify supported URL drag and drop IDs from different browsers on Windows.
- * 
- * @see org.gudy.azureus2.ui.swt.URLTransfer
- * @author Rene Leonhardt
- */
-public class Win32TransferTypes extends ByteArrayTransfer {
-
-  private static Win32TransferTypes _instance = new Win32TransferTypes();
-  private int[] ids;
-  private String[] names;
-
-  public static void main(String[] args) {
-    Display display = new Display();
-    Shell shell = new Shell(display);
-    shell.setLayout(new FillLayout());
-    Canvas canvas = new Canvas(shell, SWT.NONE);
-    DropTarget target = new DropTarget(canvas, DND.DROP_DEFAULT | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_TARGET_MOVE | DND.DROP_NONE);
-    target.setTransfer(new Transfer[] { Win32TransferTypes.getInstance(), TextTransfer.getInstance(), FileTransfer.getInstance()});
-    target.addDropListener(new DropTargetAdapter() {
-      public void dragEnter(DropTargetEvent event) {
-//        if(event.detail == DND.DROP_NONE)
-          event.detail = DND.DROP_LINK;
-        String ops = "";
-        if ((event.operations & DND.DROP_COPY) != 0)
-          ops += "Copy;";
-        if ((event.operations & DND.DROP_MOVE) != 0)
-          ops += "Move;";
-        if ((event.operations & DND.DROP_LINK) != 0)
-          ops += "Link;";
-        System.out.println("Allowed Operations are " + ops);
-
-        TransferData[] data = event.dataTypes;
-        for (int i = 0; i < data.length; i++) {
-          int id = data[i].type;
-          String name = getNameFromId(id);
-          System.out.println("Data type is " + id + " " + name);
-        }
-      }
-      public void dragOver(DropTargetEvent event) {
-        event.detail = DND.DROP_LINK;
-      }
-      public void drop(DropTargetEvent event) {
-        System.out.println("URL dropped: " + event.data);
-        System.out.println("Data type is " + event.currentDataType.type + " " + getNameFromId(event.currentDataType.type));
-      }
-    });
-
-    shell.setSize(400, 400);
-    shell.open();
-    while (!shell.isDisposed()) {
-      if (!display.readAndDispatch())
-        display.sleep();
-    }
-    display.dispose();
-  }
-
-  public static Win32TransferTypes getInstance() {
-    return _instance;
-  }
-  Win32TransferTypes() {
-    ids = new int[50000];
-    names = new String[50000];
-    for (int i = 0; i < ids.length; i++) {
-      ids[i] = i;
-      names[i] = getNameFromId(i);
-    }
-  }
-  public void javaToNative(Object object, TransferData transferData) {}
-  public Object nativeToJava(TransferData transferData) {
-    byte[] buffer = (byte[]) super.nativeToJava(transferData);
-    if (buffer == null)
-      return null;
-    int size = buffer.length;
-    byte[] text = new byte[size];
-    int j = 0;
-    for (int i = 0; i < buffer.length; i++) {
-      if (buffer[i] != 0)
-        text[j++] = buffer[i];
-    }
-    String data = new String(text, 0, j);
-    int end = data.indexOf("\n");
-    return end >= 0 ? data.substring(0, end) : data;
-  }
-  protected String[] getTypeNames() {
-    return names;
-  }
-  protected int[] getTypeIds() {
-    return ids;
-  }
-  static String getNameFromId(int id) {
-    String name = null;
-    int maxSize = 128;
-    TCHAR buffer = new TCHAR(0, maxSize);
-    int size = COM.GetClipboardFormatName(id, buffer, maxSize);
-    if (size != 0) {
-      name = buffer.toString(0, size);
-    } else {
-      switch (id) {
-        case COM.CF_HDROP :
-          name = "CF_HDROP";
-          break;
-        case COM.CF_TEXT :
-          name = "CF_TEXT";
-          break;
-        case COM.CF_BITMAP :
-          name = "CF_BITMAP";
-          break;
-        case COM.CF_METAFILEPICT :
-          name = "CF_METAFILEPICT";
-          break;
-        case COM.CF_SYLK :
-          name = "CF_SYLK";
-          break;
-        case COM.CF_DIF :
-          name = "CF_DIF";
-          break;
-        case COM.CF_TIFF :
-          name = "CF_TIFF";
-          break;
-        case COM.CF_OEMTEXT :
-          name = "CF_OEMTEXT";
-          break;
-        case COM.CF_DIB :
-          name = "CF_DIB";
-          break;
-        case COM.CF_PALETTE :
-          name = "CF_PALETTE";
-          break;
-        case COM.CF_PENDATA :
-          name = "CF_PENDATA";
-          break;
-        case COM.CF_RIFF :
-          name = "CF_RIFF";
-          break;
-        case COM.CF_WAVE :
-          name = "CF_WAVE";
-          break;
-        case COM.CF_UNICODETEXT :
-          name = "CF_UNICODETEXT";
-          break;
-        case COM.CF_ENHMETAFILE :
-          name = "CF_ENHMETAFILE";
-          break;
-        case COM.CF_LOCALE :
-          name = "CF_LOCALE";
-          break;
-        case COM.CF_MAX :
-          name = "CF_MAX";
-          break;
-      }
-    }
-    return name;
-  }
-}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/twistie/ITwistieConstants.java b/org/gudy/azureus2/ui/swt/twistie/ITwistieConstants.java
new file mode 100644
index 0000000..f84c3f6
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/twistie/ITwistieConstants.java
@@ -0,0 +1,13 @@
+package org.gudy.azureus2.ui.swt.twistie;
+
+public interface ITwistieConstants
+{
+	public static final int NONE = 1 << 1;
+
+	public static final int SHOW_DESCRIPTION = 1 << 2;
+
+	public static final int SHOW_SEPARATOR = 1 << 3;
+
+	public static final int SHOW_EXPANDED = 1 << 4;
+
+}
diff --git a/org/gudy/azureus2/ui/swt/twistie/ITwistieListener.java b/org/gudy/azureus2/ui/swt/twistie/ITwistieListener.java
new file mode 100644
index 0000000..ed411b3
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/twistie/ITwistieListener.java
@@ -0,0 +1,16 @@
+package org.gudy.azureus2.ui.swt.twistie;
+
+/**
+ * A convenience listener that will be notified whenever the control changes state between being
+ * collapse and being expanded
+ * @author knguyen
+ *
+ */
+public interface ITwistieListener
+{
+	/**
+	 * <code>true</code> is the control is in a collapsed state; <code>false otherwise</code>
+	 * @param value
+	 */
+	public void isCollapsed(boolean value);
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/twistie/TwistieLabel.java b/org/gudy/azureus2/ui/swt/twistie/TwistieLabel.java
new file mode 100644
index 0000000..2d35337
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/twistie/TwistieLabel.java
@@ -0,0 +1,369 @@
+/**
+ * 
+ */
+package org.gudy.azureus2.ui.swt.twistie;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * A Label with a twistie graphic at the beginning; every time this label is clicked the
+ * twistie graphic toggles between pointing to the right and pointing down.
+ * 
+ * @author knguyen
+ *
+ */
+public class TwistieLabel
+	extends Composite
+	implements ITwistieConstants
+{
+
+	private int style = NONE;
+
+	/**
+	 * An array of points for a triangle pointing downward
+	 */
+	static final int[] points_for_expanded = {
+		0,
+		2,
+		8,
+		2,
+		4,
+		6
+	};
+
+	/**
+	 * An array of points for a triangle pointing to the right
+	 * 
+	 */
+	static final int[] points_for_collapsed = {
+		2,
+		-1,
+		2,
+		8,
+		6,
+		4
+	};
+
+	/**
+	 * <code>Label</code> to display the text for this twistie
+	 */
+	private Label titleLabel = null;
+
+	/**
+	 * The <code>Color</code> to use for the twistie graphic itself;
+	 * defaults to the same as the foreground color of the titleLabel
+	 */
+	private Color twistieColor = null;
+
+	/**
+	 * The state of the control; callers can check this state by calling {@link #isCollapsed()}
+	 */
+	private boolean isCollapsed = true;
+
+	/**
+	 * An optional Label to display the description
+	 */
+	private Label descriptionLabel = null;
+
+	private List listeners = new ArrayList();
+
+	/**
+	 * Create a twistie Label with the given style bit.
+	 * <p>Style bit can be one or more of:</p>
+	 * <ul>
+	 * <li> TwistieLabel.NONE</li> -- The default; does not show description and separator, and is collapsed
+	 * <li> TwistieLabel.SHOW_DESCRIPTION</li> -- Show the description below the separator (or title if separator s not shown)
+	 * <li> TwistieLabel.SHOW_SEPARATOR</li> -- Show a separator below the title
+	 * <li> TwistieLabel.SHOW_EXPANDED</li> -- Show a separator below the title
+	 * </ul>
+	 * 
+	 * @param parent
+	 * @param style
+	 */
+	public TwistieLabel(Composite parent, int style) {
+		super(parent, SWT.NONE);
+		setBackgroundMode(SWT.INHERIT_FORCE);
+		this.style = style;
+
+		GridLayout gLayout = new GridLayout();
+		gLayout.marginHeight = 0;
+		gLayout.marginWidth = 0;
+		gLayout.verticalSpacing = 0;
+		gLayout.horizontalSpacing = 0;
+		setLayout(gLayout);
+
+		titleLabel = new Label(this, SWT.NONE);
+
+		if ((this.style & SHOW_SEPARATOR) != 0) {
+			Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
+			GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+			labelData.horizontalIndent = 10;
+			separator.setLayoutData(labelData);
+		}
+
+		if ((this.style & SHOW_DESCRIPTION) != 0) {
+			descriptionLabel = new Label(this, SWT.WRAP);
+			GridData labelData = new GridData(SWT.FILL, SWT.FILL, true, false);
+			labelData.horizontalIndent = 10;
+			descriptionLabel.setLayoutData(labelData);
+
+			/*
+			 * Change the font to be italic for the description
+			 */
+			Font initialFont = descriptionLabel.getFont();
+			FontData[] fontData = initialFont.getFontData();
+			for (int i = 0; i < fontData.length; i++) {
+				fontData[i].setStyle(fontData[i].getStyle() | SWT.ITALIC);
+			}
+			descriptionLabel.setFont(new Font(getDisplay(), fontData));
+
+		}
+
+		if ((this.style & SHOW_EXPANDED) != 0) {
+			isCollapsed = false;
+		}
+
+		/*
+		 * Leaving a little margin on the left; this is where we draw the twistie graphic
+		 */
+		GridData labelData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+		labelData.horizontalIndent = 10;
+		titleLabel.setLayoutData(labelData);
+
+		/*
+		 * Add our mouse interceptor to the control and the title label
+		 */
+		MouseInterceptor interceptor = new MouseInterceptor();
+		super.addMouseListener(interceptor);
+		titleLabel.addMouseListener(interceptor);
+
+		/*
+		 * Listens to the paint event and do the drawing here
+		 */
+		addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent e) {
+
+				/*
+				 * The graphic is drawn to the left of the titleLabel so define the offset from the titleLabel
+				 */
+				int offsetX = titleLabel.getBounds().x - 10;
+				int offsetY = titleLabel.getBounds().y + 3;
+
+				if (null != twistieColor) {
+					e.gc.setBackground(twistieColor);
+				} else {
+					e.gc.setBackground(getForeground());
+				}
+
+				if (true == isCollapsed) {
+					e.gc.fillPolygon(translate(points_for_collapsed, offsetX, offsetY));
+				} else {
+					e.gc.fillPolygon(translate(points_for_expanded, offsetX, offsetY));
+				}
+			}
+		});
+	}
+
+	/**
+	 * Translates the twistie points array to compensate for the given x and y offset
+	 * @param data
+	 * @param x
+	 * @param y
+	 * @return
+	 */
+	private int[] translate(int[] data, int x, int y) {
+
+		int[] target = new int[data.length];
+		for (int i = 0; i < data.length; i += 2) {
+			target[i] = data[i] + x;
+		}
+		for (int i = 1; i < data.length; i += 2) {
+			target[i] = data[i] + y;
+		}
+		return target;
+	}
+
+	/**
+	 * Add a mouse listener to the control and also the <code>titleLabel</code>
+	 */
+	public void addMouseListener(MouseListener listener) {
+		if (null != titleLabel) {
+			titleLabel.addMouseListener(listener);
+		}
+		super.addMouseListener(listener);
+	}
+
+	/**
+	 * Remove the mouse listener from the control and also the <code>titleLabel</code>
+	 */
+	public void removeMouseListener(MouseListener listener) {
+		if (null != titleLabel) {
+			titleLabel.removeMouseListener(listener);
+		}
+		super.removeMouseListener(listener);
+	}
+
+	/**
+	 * Sets the color to be used for drawing the twistie graphic
+	 * @param color
+	 */
+	public void setTwistieForeground(Color color) {
+		twistieColor = color;
+	}
+
+	/**
+	 * Sets the foreground color for the control and also all the text-base children
+	 */
+	public void setForeground(Color color) {
+		if (null != titleLabel && false == titleLabel.isDisposed()) {
+			titleLabel.setForeground(color);
+		}
+		if (null != descriptionLabel && false == descriptionLabel.isDisposed()) {
+			descriptionLabel.setForeground(color);
+		}
+
+		if (null == twistieColor) {
+			twistieColor = color;
+		}
+
+		super.setForeground(color);
+	}
+
+	/**
+	 * Sets the background color for the control and also all the text-base children
+	 */
+	public void setBackground(Color color) {
+		if (null != titleLabel) {
+			titleLabel.setBackground(color);
+		}
+		if (null != descriptionLabel) {
+			descriptionLabel.setBackground(color);
+		}
+
+		super.setBackground(color);
+	}
+
+	/**
+	 * Sets the text to display as the title
+	 * @param string
+	 */
+	public void setTitle(String string) {
+		if (null != titleLabel) {
+			titleLabel.setText(string);
+		}
+	}
+
+	/**
+	 * Sets the text to display as the description; this is not in effect unless the {@link #SHOW_DESCRIPTION} flag is also set
+	 * @param string
+	 */
+	public void setDescription(String string) {
+		if (null != descriptionLabel) {
+			descriptionLabel.setText(string);
+		}
+	}
+
+	/**
+	 * Sets the tooltip for the control and also all the text-base children
+	 */
+	public void setToolTipText(String string) {
+		if (null != titleLabel) {
+			titleLabel.setToolTipText(string);
+		}
+
+		if (null != descriptionLabel) {
+			descriptionLabel.setToolTipText(string);
+		}
+
+		super.setToolTipText(string);
+	}
+
+	/**
+	 * Sets the enablement for the control and also all the text-base children
+	 */
+	public void setEnabled(boolean enabled) {
+		if (null != titleLabel) {
+			titleLabel.setEnabled(enabled);
+		}
+
+		super.setEnabled(enabled);
+	}
+
+	/**
+	 * Returns whether this control is in a collapsed state
+	 * @return
+	 */
+	public boolean isCollapsed() {
+		return isCollapsed;
+	}
+
+	public void
+	setCollapsed(
+		boolean	c )
+	{
+		if ( c != isCollapsed ){
+			isCollapsed = c;
+			redraw();
+			notifyTwistieListeners();
+		}
+	}
+	
+	/**
+	 * Add a listener to be notified whenever this control is collapsed or expanded; listeners
+	 * can check the collapsed/expanded state on the control and perform layout changes if need be.
+	 * @param listener
+	 */
+	public void addTwistieListener(ITwistieListener listener) {
+		listeners.add(listener);
+	}
+
+	public void removeTwistieListener(ITwistieListener listener) {
+		listeners.remove(listener);
+	}
+
+	private void notifyTwistieListeners() {
+		for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
+			((ITwistieListener) iterator.next()).isCollapsed(isCollapsed());
+
+		}
+	}
+
+	/**
+	 * A listener that intercepts mouseDown events from the control and the title label so we can
+	 * fire a single event to the listener to signal that the control has been collapsed or expanded.
+	 * 
+	 * 
+	 * @author knguyen
+	 *
+	 */
+	private class MouseInterceptor
+		extends MouseAdapter
+	{
+
+		/*
+		 * Listens to the mouse click and toggle the isCollapsed flag then force a redraw to update the control
+		 */
+		public void mouseDown(MouseEvent e) {
+			isCollapsed = !isCollapsed;
+			redraw();
+			notifyTwistieListeners();
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/twistie/TwistieSection.java b/org/gudy/azureus2/ui/swt/twistie/TwistieSection.java
new file mode 100644
index 0000000..85cd448
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/twistie/TwistieSection.java
@@ -0,0 +1,201 @@
+package org.gudy.azureus2.ui.swt.twistie;
+
+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;
+
+public class TwistieSection
+	extends Composite
+	implements ITwistieConstants
+{
+	private TwistieContentPanel content = null;
+
+	private TwistieLabel label = null;
+
+	/**
+	 * Create a TwistieSection with the given style bit.
+	 * <p>Style bit can be one or more of:</p>
+	 * <ul>
+	 * <li> TwistieLabel.NONE</li> -- The default; does not show description and separator, and is collapsed
+	 * <li> TwistieLabel.SHOW_DESCRIPTION</li> -- Show the description below the separator (or title if separator s not shown)
+	 * <li> TwistieLabel.SHOW_SEPARATOR</li> -- Show a separator below the title
+	 * <li> TwistieLabel.SHOW_EXPANDED</li> -- Show a separator below the title
+	 * </ul>
+		*/
+	public TwistieSection(Composite parent, int style) {
+		super(parent, SWT.NONE);
+		setBackgroundMode(SWT.INHERIT_FORCE);
+		GridLayout gLayout = new GridLayout();
+		gLayout.marginHeight = 0;
+		gLayout.marginWidth = 0;
+		gLayout.verticalSpacing = 0;
+		setLayout(gLayout);
+
+		label = new TwistieLabel(this, style);
+		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+		content = new TwistieContentPanel(this, SWT.NONE);
+		final GridData gDataExpanded = new GridData(SWT.FILL, SWT.FILL, true, true);
+		gDataExpanded.horizontalIndent = 10;
+		final GridData gDataCollapsed = new GridData(SWT.FILL, SWT.FILL, true,
+				false);
+		gDataCollapsed.heightHint = 0;
+
+		content._setLayoutData((true == label.isCollapsed()) ? gDataCollapsed
+				: gDataExpanded);
+
+		label.addTwistieListener(new ITwistieListener() {
+			public void isCollapsed(boolean value) {
+				content._setLayoutData((true == value) ? gDataCollapsed : gDataExpanded);
+				layout(true, true);
+
+			}
+
+		});
+
+	}
+
+	/**
+	 * Returns the main body of the section.  Callers can add custom controls onto the returned
+	 * <code>Composite</code>
+	 * @return
+	 */
+	public Composite getContent() {
+		return content;
+	}
+
+	public void setBackground(Color color) {
+		if (null != label && false == label.isDisposed()) {
+			label.setBackground(color);
+		}
+
+		if (null != content && false == content.isDisposed()) {
+			content.setBackground(color);
+		}
+
+		super.setBackground(color);
+	}
+
+	public void setForeground(Color color) {
+		if (null != label && false == label.isDisposed()) {
+			label.setForeground(color);
+		}
+
+		if (null != content && false == content.isDisposed()) {
+			content.setForeground(color);
+		}
+		super.setForeground(color);
+	}
+
+	public void setEnabled(boolean enabled) {
+		if (null != label && false == label.isDisposed()) {
+			label.setEnabled(enabled);
+		}
+		super.setEnabled(enabled);
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param listener
+	 */
+	public void addTwistieListener(ITwistieListener listener) {
+		if (null != label && false == label.isDisposed()) {
+			label.addTwistieListener(listener);
+		}
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param listener
+	 */
+	public void removeTwistieListener(ITwistieListener listener) {
+		if (null != label && false == label.isDisposed()) {
+			label.removeTwistieListener(listener);
+		}
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param string
+	 */
+
+	public void setDescription(String string) {
+		if (null != label && false == label.isDisposed()) {
+			label.setDescription(string);
+		}
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param string
+	 */
+
+	public void setTitle(String string) {
+		if (null != label && false == label.isDisposed()) {
+			label.setTitle(string);
+		}
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param string
+	 */
+
+	public void setToolTipText(String string) {
+		if (null != label && false == label.isDisposed()) {
+			label.setToolTipText(string);
+		}
+	}
+
+	/**
+	 * Delegating to the <code>TwistieLabel</code>
+	 * @param color
+	 */
+
+	public void setTwistieForeground(Color color) {
+		if (null != label && false == label.isDisposed()) {
+			label.setTwistieForeground(color);
+		}
+	}
+
+	public boolean
+	isCollapsed()
+	{
+		return( label.isCollapsed());
+	}
+	
+	public void
+	setCollapsed(
+		boolean	c )
+	{
+		label.setCollapsed( c );
+	}
+	
+	/**
+	 * A simple extension of <code>Composite</code> that disallow modifying its layout data
+	 * @author knguyen
+	 *
+	 */
+	private class TwistieContentPanel
+		extends Composite
+	{
+
+		public TwistieContentPanel(Composite parent, int style) {
+			super(parent, style);
+			setBackgroundMode(SWT.INHERIT_FORCE);
+		}
+
+		private void _setLayoutData(GridData gData) {
+			super.setLayoutData(gData);
+		}
+
+		public void setLayoutData(Object layoutData) {
+			throw new IllegalArgumentException(
+					"This is a managed class therefore overriding its LayoutData is an illegal operation");
+		}
+
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java b/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
index 457df25..a950850 100644
--- a/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
+++ b/org/gudy/azureus2/ui/swt/update/FullUpdateWindow.java
@@ -19,8 +19,6 @@
 package org.gudy.azureus2.ui.swt.update;
 
 
-import java.util.Locale;
-
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.*;
 import org.eclipse.swt.events.DisposeEvent;
@@ -30,6 +28,7 @@ import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
@@ -43,6 +42,8 @@ public class FullUpdateWindow
 
 	private static Browser browser;
 
+	private static BrowserFunction browserFunction;
+
 	public static void 
 	handleUpdate(
 		final String						url,
@@ -95,6 +96,9 @@ public class FullUpdateWindow
 						if (parentShell != null) {
 							parentShell.setCursor(e.display.getSystemCursor(SWT.CURSOR_ARROW));
 						}
+						if (browserFunction != null && !browserFunction.isDisposed()) {
+							browserFunction.dispose();
+						}
 						current_shell = null;
 						
 					}finally{
@@ -128,16 +132,33 @@ public class FullUpdateWindow
 				}
 			});
 	
-			browser.addStatusTextListener(new StatusTextListener() {
-				String last = null;
-	
-				public void changed(StatusTextEvent event) {
+			browserFunction = new BrowserFunction(browser, "sendVuzeUpdateEvent") {
+				private String last = null;
+
+				public Object function(Object[] arguments) {
+
 					if (shell == null || shell.isDisposed()) {
-						return;
+						return null;
 					}
-					String text = event.text.toLowerCase();
-					if (last != null && last.equals(text)) {
-						return;
+					
+					if (arguments == null) {
+						Debug.out("Invalid sendVuzeUpdateEvent null ");
+						return null;
+					}
+					if (arguments.length < 1) {
+						Debug.out("Invalid sendVuzeUpdateEvent length " + arguments.length + " not 1");
+						return null;
+					}
+					if (!(arguments[0] instanceof String)) {
+						Debug.out("Invalid sendVuzeUpdateEvent "
+								+ (arguments[0] == null ? "NULL"
+										: arguments.getClass().getSimpleName()) + " not String");
+						return null;
+					}
+
+					String text = ((String) arguments[0]).toLowerCase();
+					if (last  != null && last.equals(text)) {
+						return null;
 					}
 					last = text;
 					if ( text.contains("page-loaded")) {
@@ -191,9 +212,18 @@ public class FullUpdateWindow
 							}
 						});
 					}
+					return null;
+				}
+			};
+
+			browser.addStatusTextListener(new StatusTextListener() {
+				public void changed(StatusTextEvent event) {
+					browserFunction.function(new Object[] {
+						event.text
+					});
 				}
 			});
-	
+
 			browser.addLocationListener(new LocationListener() {
 				public void changing(LocationEvent event) {
 				}
@@ -203,7 +233,7 @@ public class FullUpdateWindow
 			});
 	
 			String final_url = url + ( url.indexOf('?')==-1?"?":"&") + 
-						"locale=" + Locale.getDefault().toString() + 
+						"locale=" + MessageText.getCurrentLocale().toString() + 
 						"&azv=" + Constants.AZUREUS_VERSION; 
 				
 			SimpleTimer.addEvent(
diff --git a/org/gudy/azureus2/ui/swt/update/SilentInstallUI.java b/org/gudy/azureus2/ui/swt/update/SilentInstallUI.java
new file mode 100644
index 0000000..d0fcc8e
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/update/SilentInstallUI.java
@@ -0,0 +1,107 @@
+/*
+ * Created on Mar 6, 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.ui.swt.update;
+
+
+import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.update.Update;
+import org.gudy.azureus2.plugins.update.UpdateCheckInstance;
+import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
+
+
+public class 
+SilentInstallUI 
+{
+	private UpdateMonitor			monitor;
+	private	UpdateCheckInstance		instance;
+	
+	private  boolean				cancelled;
+	
+	protected
+	SilentInstallUI(
+		UpdateMonitor			_monitor,
+		UpdateCheckInstance		_instance )
+	{
+		monitor		= _monitor;
+		instance	= _instance;
+		
+		try{
+			monitor.addDecisionHandler(_instance );
+					
+			new AEThread2( "SilentInstallerUI", true )
+			{
+				public void
+				run()
+				{
+					try{
+						Update[] updates = instance.getUpdates();
+
+						for ( Update update: updates ){
+														
+							ResourceDownloader[] downloaders = update.getDownloaders();
+							
+							for ( ResourceDownloader downloader: downloaders ){
+								
+								synchronized( SilentInstallUI.this ){
+									
+									if ( cancelled ){
+										
+										return;
+									}									
+								}
+								
+								downloader.download();
+							}
+						}
+						
+						boolean	restart_required = false;
+						
+						for (int i=0;i<updates.length;i++){
+			
+							if ( updates[i].getRestartRequired() == Update.RESTART_REQUIRED_YES ){
+								
+								restart_required = true;
+							}
+						}
+						
+						if ( restart_required ){
+							
+							monitor.handleRestart();
+						}
+					}catch( Throwable e ){
+						
+						Debug.out( "Install failed", e );
+						
+						instance.cancel();
+					}
+				}
+			}.start();
+			
+		}catch( Throwable e ){
+			
+			Debug.out( e );
+			
+			instance.cancel();
+		}
+	}
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/update/SimpleInstallUI.java b/org/gudy/azureus2/ui/swt/update/SimpleInstallUI.java
index 1f9326b..873157b 100644
--- a/org/gudy/azureus2/ui/swt/update/SimpleInstallUI.java
+++ b/org/gudy/azureus2/ui/swt/update/SimpleInstallUI.java
@@ -92,6 +92,10 @@ SimpleInstallUI
 		
 		if ( parent != null ){
 			
+			if (parent.isDisposed()) {
+				throw( new RuntimeException( "cancelled" ));
+			}
+			
 			build( parent );
 			
 		}else{
diff --git a/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java b/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
index 44f1645..9407165 100644
--- a/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
+++ b/org/gudy/azureus2/ui/swt/update/UpdateMonitor.java
@@ -43,6 +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.core.versioncheck.VersionCheckClient;
 import com.aelitis.azureus.ui.*;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 
@@ -62,7 +63,8 @@ public class UpdateMonitor
 {
 	private static final LogIDs LOGID = LogIDs.GUI;
 
-	public static final long AUTO_UPDATE_CHECK_PERIOD = 23 * 60 * 60 * 1000; // 23 hours
+	public static final long AUTO_UPDATE_CHECK_PERIOD 		= 23 * 60 * 60 * 1000; // 23 hours
+	public static final long AUTO_UPDATE_CHECK_PERIOD_BETA 	= 4 * 60 * 60 * 1000; // 4 hours
 
 	private static final String MSG_PREFIX = "UpdateMonitor.messagebox.";
 
@@ -156,7 +158,8 @@ public class UpdateMonitor
 
 
 		SimpleTimer.addPeriodicEvent("UpdateMon:autocheck",
-				AUTO_UPDATE_CHECK_PERIOD, new TimerEventPerformer() {
+				COConfigurationManager.getBooleanParameter( "Beta Programme Enabled" )?AUTO_UPDATE_CHECK_PERIOD_BETA:AUTO_UPDATE_CHECK_PERIOD,
+				new TimerEventPerformer() {
 					public void perform(TimerEvent ev) {
 						performAutoCheck(false);
 					}
@@ -468,6 +471,11 @@ public class UpdateMonitor
 			current_update_instance.cancel();
 		}
 
+		if ( bForce ){
+			
+			VersionCheckClient.getSingleton().clearCache();
+		}
+		
 		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 		if (uiFunctions != null) {
 			// XXX What kind of format is this!?
@@ -533,6 +541,12 @@ public class UpdateMonitor
 				new SimpleInstallUI( this, instance );
 				
 				return;
+				
+			}else if ( ui == UpdateCheckInstance.PT_UI_STYLE_NONE ){
+				
+				new SilentInstallUI( this, instance );
+				
+				return;
 			}
 			
 		}catch( Throwable e ){
@@ -641,25 +655,25 @@ public class UpdateMonitor
 	handleRestart()
  {
 		final UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-		if (uiFunctions != null) {
-			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;
-			}
-			uiFunctions.promptUser(title, text, new String[] {
-				MessageText.getString("UpdateWindow.restart"),
-				MessageText.getString("UpdateWindow.restartLater")
-			}, 0, null, null, false, timeout, new UserPrompterResultListener() {
-
-				public void prompterClosed(int result) {
-					if (result == 0) {
-						uiFunctions.dispose(true, false);
-					}
-				}
-			});
+		
+		if ( uiFunctions != null ){
+			
+			uiFunctions.performAction( 
+					UIFunctions.ACTION_UPDATE_RESTART_REQUEST,
+					Constants.isWindows7OrHigher,		// no timer for in 7 as they always get an elevation prompt so we don't want to shutdown and then leave\
+														// Vuze down pending user authorisation of the update
+					new UIFunctions.actionListener()
+					{
+						public void
+						actionComplete(
+							Object	result )
+						{
+							if ((Boolean)result){
+								
+								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 4fd7709..dcca41c 100644
--- a/org/gudy/azureus2/ui/swt/update/UpdateWindow.java
+++ b/org/gudy/azureus2/ui/swt/update/UpdateWindow.java
@@ -42,7 +42,7 @@ import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.LinkArea;
 import org.gudy.azureus2.ui.swt.components.StringListChooser;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
-import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar;
+import org.gudy.azureus2.ui.swt.mainwindow.IMainStatusBar;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -305,6 +305,16 @@ UpdateWindow
 		}
     });
     
+    updateWindow.addDisposeListener(
+    	new DisposeListener()
+    	{
+    		public void widgetDisposed(DisposeEvent arg0) {
+    			if ( !check_instance.isCancelled()){
+    				check_instance.cancel();
+    			}
+    		}
+    	});
+    
     formData = new FormData();
     formData.left = new FormAttachment(0,0);
     formData.right = new FormAttachment(100,0);
@@ -380,7 +390,7 @@ UpdateWindow
 		    updateWindow.dispose();
       	UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
       	if (functionsSWT != null) {
-      		MainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
+      		IMainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
       		if (mainStatusBar != null) {
       			mainStatusBar.setUpdateNeeded(null);
       		}
@@ -440,7 +450,7 @@ UpdateWindow
         	
         	UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
         	if (functionsSWT != null) {
-        		MainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
+        		IMainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
         		if (mainStatusBar != null) {
         			mainStatusBar.setUpdateNeeded(UpdateWindow.this);
         		}
@@ -680,7 +690,7 @@ UpdateWindow
     //When completing, remove the link in mainWindow :
   	UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT();
   	if (functionsSWT != null) {
-  		MainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
+  		IMainStatusBar mainStatusBar = functionsSWT.getMainStatusBar();
   		if (mainStatusBar != null) {
   			mainStatusBar.setUpdateNeeded(null);
   		}
diff --git a/org/gudy/azureus2/ui/swt/updater2/PreUpdateChecker.java b/org/gudy/azureus2/ui/swt/updater2/PreUpdateChecker.java
index 4e56de9..931b757 100644
--- a/org/gudy/azureus2/ui/swt/updater2/PreUpdateChecker.java
+++ b/org/gudy/azureus2/ui/swt/updater2/PreUpdateChecker.java
@@ -44,6 +44,7 @@ public class PreUpdateChecker
 	{
 		if ( ui.equals( "az3") && !"0".equals(System.getProperty("azureus.loadplugins"))) {
 			
+			/* EMP is no longer auto-install
 			if ( UpdaterUtils.ensurePluginPresent(
 					"azemp",
 					"com.azureus.plugins.azemp.EmbeddedMediaPlayerPlugin",
@@ -53,6 +54,7 @@ public class PreUpdateChecker
 				
 				core.getPluginManager().refreshPluginList();
 			}
+			*/
 		}
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/updater2/SWTUpdateChecker.java b/org/gudy/azureus2/ui/swt/updater2/SWTUpdateChecker.java
index 0bff914..77456d7 100644
--- a/org/gudy/azureus2/ui/swt/updater2/SWTUpdateChecker.java
+++ b/org/gudy/azureus2/ui/swt/updater2/SWTUpdateChecker.java
@@ -210,8 +210,15 @@ public class SWTUpdateChecker implements UpdatableComponent
 	      	Debug.printStackTrace( e );
 	      }
 	      
+	      String	extra = "";
+	      
+	      if ( Constants.isWindows && Constants.is64Bit ){
+	    	
+	    	  extra = " (64-bit)";
+	      }
+	      
 	      final Update update = 
-	    	  checker.addUpdate("SWT Library for " + versionGetter.getPlatform(),
+	    	  checker.addUpdate("SWT Library for " + versionGetter.getPlatform() + extra,
 		          new String[] {"SWT is the graphical library used by " + Constants.APP_NAME},
 		          "" + versionGetter.getLatestVersion(),
 		          swtDownloader,
@@ -222,10 +229,25 @@ public class SWTUpdateChecker implements UpdatableComponent
 	      
 	      swtDownloader.addListener(new ResourceDownloaderAdapter() {
 		        
-		        public boolean completed(ResourceDownloader downloader, InputStream data) {
-		          //On completion, process the InputStream to store temp files
+		        public boolean 
+		        completed(
+		        	ResourceDownloader downloader, 
+		        	InputStream data) 
+		        {
+		        		//On completion, process the InputStream to store temp files
+		        	
 		          return processData(checker,update,downloader,data);
 		        }
+		        
+				public void
+				failed(
+					ResourceDownloader			downloader,
+					ResourceDownloaderException e )
+				{
+					Debug.out( downloader.getName() + " failed", e );
+					
+					update.complete( false );
+				}
 		      });
 	    }
   	}catch( Throwable e ){
@@ -313,7 +335,13 @@ public class SWTUpdateChecker implements UpdatableComponent
     	   Debug.outNoStack( "SWTUpdate: ignoring zip entry '" + name + "'" );
        }
       }     
-    } catch(Exception e) {
+      
+      update.complete( true );
+      
+    } catch(Throwable e) {
+    	
+    	update.complete( false );
+    	
   		Logger.log(new LogAlert(LogAlert.UNREPEATABLE,
 				"SWT Update failed", e));
       return false;
diff --git a/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java b/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
index df75cf4..de54e2d 100644
--- a/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
+++ b/org/gudy/azureus2/ui/swt/updater2/SWTVersionGetter.java
@@ -59,7 +59,10 @@ public class SWTVersionGetter {
   SWTVersionGetter(
   		UpdateChecker	_checker ) 
   {
-    this.platform 		= SWT.getPlatform();
+    this.platform 		= COConfigurationManager.getStringParameter("ConfigView.section.style.swt.library.selection");
+    if (this.platform == null || this.platform.length() == 0) {
+    	this.platform = SWT.getPlatform();
+    }
     this.currentVersion = SWT.getVersion();
     
 
diff --git a/org/gudy/azureus2/ui/swt/views/AbstractIView.java b/org/gudy/azureus2/ui/swt/views/AbstractIView.java
deleted file mode 100644
index 3d1a872..0000000
--- a/org/gudy/azureus2/ui/swt/views/AbstractIView.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Created on 29 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.views;
-
-import org.eclipse.swt.widgets.Composite;
-import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.AEMonitor;
-import org.gudy.azureus2.core3.util.IndentWriter;
-import org.gudy.azureus2.ui.swt.Messages;
-
-/**
- * @author Ren�
- * 
- */
-
-// XXX This class is used by plugins.  Don't remove any functions from it!
-public abstract class AbstractIView implements IView {
-	// XXX AEMonitor introduced to plugin interface..
-	protected AEMonitor this_mon 	= new AEMonitor( "AbstractIView" );
-	
-	private String lastFullTitleKey = null;
-	
-	private String lastFullTitle = "";
-
-  public void initialize(Composite composite){    
-  }
-  
-  public Composite getComposite(){ return null; }
-  public void refresh(){}
-  
-  /**
-   * A basic implementation that disposes the composite
-   * Should be called with super.delete() from any extending class.
-   * Images, Colors and such SWT handles must be disposed by the class itself.
-   */
-  public void delete(){
-    Composite comp = getComposite();
-    if (comp != null && !comp.isDisposed())
-      comp.dispose();
-  }
-
-  public String getData(){ return null; }
-
-  /**
-   * Called in order to set / update the title of this View.  When the view
-   * is being displayed in a tab, the full title is used for the tooltip.
-   * 
-   * By default, this function will return text from the message bundles which
-   * correspond to the key returned in #getData()
-   * 
-   * @return the full title for the view
-   */
-	public String getFullTitle() {
-		String key = getData();
-		if (key == null) {
-			return "";
-		}
-
-		if ( lastFullTitle.length() > 0 && key.equals(lastFullTitleKey)) {
-			return lastFullTitle;
-		}
-
-		lastFullTitleKey = key;
-
-		if (MessageText.keyExists(key)) {
-			lastFullTitle = MessageText.getString(key);
-		} else {
-			lastFullTitle = key.replace('.', ' '); // support old plugins
-		}
-
-		return lastFullTitle;
-	}
-
-  /**
-   * Called in order to set / update the short title of this view.  When the 
-   * view is being displayed in a tab, the short title is used for the tab's
-   * text.
-   * 
-   * By default, this function will return the full title. If the full title
-   * is over 30 characters, it will be trimmed and "..." will be added
-   * 
-   * @return A short title for the view
-   */
-  public final String getShortTitle() {
-    String shortTitle = getFullTitle();
-    if(shortTitle != null && shortTitle.length() > 30) {
-      shortTitle = shortTitle.substring(0,30) + "...";
-    }
-    return shortTitle;
-	}
-  
-  public void updateLanguage() {
-	lastFullTitle = "";
-    Messages.updateLanguageForControl(getComposite());
-  }
-  
-  
-  // IconBarEnabler
-  public boolean isEnabled(String itemKey) {
-    return false;
-  }
-  
-  // IconBarEnabler
-  public boolean isSelected(String itemKey) {
-    return false;
-  }
-
-  // IconBarEnabler
-  public void itemActivated(String itemKey) {   
-  }
-
-  public void
-  generateDiagnostics(
-	IndentWriter	writer )
-  {
-	  writer.println( "Diagnostics for " + this + " (" + getFullTitle()+ ")");
-  }
-
-  public void dataSourceChanged(Object newDataSource) {
-  }
-}
diff --git a/org/gudy/azureus2/ui/swt/views/ConfigShell.java b/org/gudy/azureus2/ui/swt/views/ConfigShell.java
index 9d1fd1c..848a540 100644
--- a/org/gudy/azureus2/ui/swt/views/ConfigShell.java
+++ b/org/gudy/azureus2/ui/swt/views/ConfigShell.java
@@ -14,10 +14,12 @@ 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.Debug;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 
-import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
@@ -37,6 +39,8 @@ public class ConfigShell
 
 	private ConfigView configView;
 
+	private UISWTViewImpl swtView;
+
 	public static ConfigShell getInstance() {
 		if (null == instance) {
 			instance = new ConfigShell();
@@ -67,7 +71,12 @@ public class ConfigShell
 			shell.setText(MessageText.getString(MessageText.resolveLocalizationKey("ConfigView.title.full")));
 			Utils.setShellIcon(shell);
 			configView = new ConfigView();
-			configView.initialize(shell);
+			try {
+				swtView = new UISWTViewImpl(null, "ConfigView", configView, section);
+			} catch (Exception e1) {
+				Debug.out(e1);
+			}
+			swtView.initialize(shell);
 			configView.selectSection(section);
 
 			/*
@@ -131,7 +140,10 @@ public class ConfigShell
 		// }
 			// clear these down as view now dead
 		
-		configView.delete();
+		if (swtView != null) {
+  		swtView.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+  		swtView = null;
+		}
 		
 		shell		= null;
 		configView	= null;
diff --git a/org/gudy/azureus2/ui/swt/views/ConfigView.java b/org/gudy/azureus2/ui/swt/views/ConfigView.java
index 2222958..d7a1f57 100644
--- a/org/gudy/azureus2/ui/swt/views/ConfigView.java
+++ b/org/gudy/azureus2/ui/swt/views/ConfigView.java
@@ -30,6 +30,7 @@ import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.List;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -43,16 +44,16 @@ import org.gudy.azureus2.plugins.ui.config.ConfigSectionSWT;
 import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionRepository;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
+import org.gudy.azureus2.ui.swt.plugins.*;
 import org.gudy.azureus2.ui.swt.views.configsections.*;
 
+import com.aelitis.azureus.core.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
-/**
- * @author Olivier
- *
- */
-public class ConfigView extends AbstractIView {
+ at SuppressWarnings("deprecation")
+public class ConfigView implements UISWTViewEventListener {
 	private static final LogIDs LOGID = LogIDs.GUI;
   public static final String sSectionPrefix = "ConfigView.section.";
   
@@ -67,7 +68,7 @@ public class ConfigView extends AbstractIView {
   Font headerFont;
   Font filterFoundFont;
   Tree tree;
-  ArrayList pluginSections;
+  ArrayList<ConfigSection> pluginSections;
 
 	private Timer filterDelayTimer;
 	private String filterText = "";
@@ -76,52 +77,69 @@ public class ConfigView extends AbstractIView {
 	
 	private Image imgSmallX;
 	private Image imgSmallXGray;
+	private String startSection;
+	private UISWTView swtView;
 
-  public 
-  ConfigView() 
-  {
+	public ConfigView() {
   }
   
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#initialize(org.eclipse.swt.widgets.Composite)
-   */
-  public void initialize(final Composite composite) {
+  private void initialize(final Composite composite) {
   	// need to initalize composite now, since getComposite can
   	// be called at any time
     cConfig = new Composite(composite, SWT.NONE);
-		_initialize(composite);
+
+    GridLayout configLayout = new GridLayout();
+    configLayout.marginHeight = 0;
+    configLayout.marginWidth = 0;
+    cConfig.setLayout(configLayout);
+    GridData gridData = new GridData(GridData.FILL_BOTH);
+    cConfig.setLayoutData(gridData);
+
+    final Label label = new Label(cConfig, SWT.CENTER);
+    Messages.setLanguageText(label, "view.waiting.core");
+    gridData = new GridData(GridData.FILL_BOTH);
+    label.setLayoutData(gridData);
+    
+    // Need to delay initialation until core is done so we can guarantee
+    // all config sections are loaded (ie. plugin ones).
+    // TODO: Maybe add them on the fly?
+    AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+			public void azureusCoreRunning(AzureusCore core) {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						_initialize(composite);
+						label.dispose();
+						composite.layout(true, true);
+					}
+				});
+			}
+		});
   }
   	
-  public void _initialize(Composite composite) {
+  private void _initialize(Composite composite) {
   	
     GridData gridData;
     /*
     /--cConfig-----------------------------------------------------------\
     | ###SashForm#form################################################## |
     | # /--cLeftSide-\ /--cRightSide---------------------------------\ # |
-    | # |txtFilter X | | ***cHeader********************************* | # |
-    | # | ##tree#### | | * lHeader                    usermodeHint * | # |
+    | # | ##tree#### | | ***cHeader********************************* | # |
+    | # | #        # | | * lHeader                    usermodeHint * | # |
     | # | #        # | | ******************************************* | # |
     | # | #        # | | ###Composite cConfigSection################ | # |
     | # | #        # | | #                                         # | # |
     | # | #        # | | #                                         # | # |
     | # | #        # | | #                                         # | # |
-    | # | #        # | | #                                         # | # |
-    | # | ########## | | ########################################### | # |
+    | # | ########## | | #                                         # | # |
+    | # |txtFilter X | | ########################################### | # |
     | # \------------/ \---------------------------------------------/ # |
     | ################################################################## |
-    |  [Button]                                                          |
+    |                                                          [Buttons] |
     \--------------------------------------------------------------------/
     */
     try {
       Display d = composite.getDisplay();
-
-      GridLayout configLayout = new GridLayout();
-      configLayout.marginHeight = 0;
-      configLayout.marginWidth = 0;
-      cConfig.setLayout(configLayout);
-      gridData = new GridData(GridData.FILL_BOTH);
-      cConfig.setLayoutData(gridData);
+      GridLayout configLayout;
   
       SashForm form = new SashForm(cConfig,SWT.HORIZONTAL);
       gridData = new GridData(GridData.FILL_BOTH);
@@ -168,6 +186,14 @@ public class ConfigView extends AbstractIView {
       	}
       });
       
+      lblX.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent arg0) {
+			    ImageLoader imageLoader = ImageLoader.getInstance();
+			    imageLoader.releaseImage("smallx-gray");
+			    imageLoader.releaseImage("smallx");
+				}
+			});
+      
       Label lblSearch = new Label(cFilterArea, SWT.NONE);
       imageLoader.setLabelImage(lblSearch, "search");
   
@@ -297,6 +323,8 @@ public class ConfigView extends AbstractIView {
 
     ConfigSection[] internalSections = { 
                                          new ConfigSectionMode(),
+                                         new ConfigSectionStartShutdown(),
+                                         new ConfigSectionBackupRestore(),
                                          new ConfigSectionConnection(),
                                          new ConfigSectionConnectionProxy(),
                                          new ConfigSectionConnectionAdvanced(),
@@ -315,6 +343,7 @@ public class ConfigView extends AbstractIView {
                                          new ConfigSectionInterfaceLanguage(),
                                          new ConfigSectionInterfaceStart(),
                                          new ConfigSectionInterfaceDisplay(),
+                                         new ConfigSectionInterfaceTables(),
                                          new ConfigSectionInterfaceColor(),
                                          new ConfigSectionInterfaceAlerts(),
                                          new ConfigSectionInterfacePassword(),
@@ -339,7 +368,7 @@ public class ConfigView extends AbstractIView {
     	
       boolean	plugin_section = i >= internalSections.length;
       
-      ConfigSection section = (ConfigSection)pluginSections.get(i);
+      ConfigSection section = pluginSections.get(i);
       
       if (section instanceof ConfigSectionSWT || section instanceof UISWTConfigSection ) {
         String name;
@@ -368,18 +397,25 @@ public class ConfigView extends AbstractIView {
          	section_key = sSectionPrefix + name;
          }
          
+         String	section_name = MessageText.getString( section_key );
+         
          try {
           TreeItem treeItem;
           String location = section.configSectionGetParentSection();
   
-          if (location.equalsIgnoreCase(ConfigSection.SECTION_ROOT))
-        	  treeItem = new TreeItem(tree, SWT.NULL);
-          else if (location != "") {
+          if ( location.length() == 0 || location.equalsIgnoreCase(ConfigSection.SECTION_ROOT)){
+        	  //int position = findInsertPointFor(section_name, tree);
+        	  //if ( position == -1 ){
+        		  treeItem = new TreeItem(tree, SWT.NULL);
+        	  // }else{
+        	  //	  treeItem = new TreeItem(tree, SWT.NULL, position); 
+        	  //}
+         }else{
         	  TreeItem treeItemFound = findTreeItem(tree, location);
         	  if (treeItemFound != null){
         		  if (location.equalsIgnoreCase(ConfigSection.SECTION_PLUGINS)) {
         			  // Force ordering by name here.
-        			  int position = findInsertPointFor(MessageText.getString(section_key), treeItemFound);
+        			  int position = findInsertPointFor(section_name, treeItemFound);
         			  if (position == -1) {
         				  treeItem = new TreeItem(treeItemFound, SWT.NULL);
         			  }
@@ -393,8 +429,6 @@ public class ConfigView extends AbstractIView {
         	  }else{
         		  treeItem = new TreeItem(tree, SWT.NULL);
         	  }
-          }else{
-        	  treeItem = new TreeItem(tree, SWT.NULL); 
           }
   
           ScrolledComposite sc = new ScrolledComposite(cConfigSection, SWT.H_SCROLL | SWT.V_SCROLL);
@@ -444,6 +478,12 @@ public class ConfigView extends AbstractIView {
     } else {
     	initSaveButton();
     }
+    
+    if (startSection != null) {
+    	if (selectSection(startSection)) {
+    		return;
+    	}
+    }
 
     TreeItem[] items = { tree.getItems()[0] };
     tree.setSelection(items);
@@ -451,7 +491,7 @@ public class ConfigView extends AbstractIView {
     showSection(items[0]);
   }
 
-	public void setupSC(ScrolledComposite sc) {
+	private void setupSC(ScrolledComposite sc) {
 		Composite c = (Composite) sc.getContent();
 		if (c != null) {
 			Point size1 = c.computeSize(sc.getClientArea().width, SWT.DEFAULT);
@@ -487,18 +527,35 @@ public class ConfigView extends AbstractIView {
 
 						Utils.execSWTThread(new AERunnable() {
 							public void runSupport() {
-								// TODO Auto-generated method stub
-								ArrayList foundItems = new ArrayList();
-								TreeItem[] items = tree.getItems();
+								if (filterDelayTimer != null) {
+									return;
+								}
+								Shell shell = tree.getShell();
+								if (shell != null) {
+									shell.setCursor(shell.getDisplay().getSystemCursor(
+											SWT.CURSOR_WAIT));
+								}
 								try {
-									tree.setRedraw(false);
-									for (int i = 0; i < items.length; i++) {
-										items[i].setExpanded(false);
-									}
+									ArrayList<TreeItem> foundItems = new ArrayList<TreeItem>();
+									TreeItem[] items = tree.getItems();
+									try {
+										tree.setRedraw(false);
+										for (int i = 0; i < items.length; i++) {
+											items[i].setExpanded(false);
+										}
 
-									filterTree(items, filterText, foundItems);
+										filterTree(items, filterText, foundItems);
+									} finally {
+										tree.setRedraw(true);
+									}
 								} finally {
-									tree.setRedraw(true);
+									if (shell != null) {
+										shell.setCursor(null);
+									}
+									TreeItem[] selection = tree.getSelection();
+									if (selection != null && selection.length > 0) {
+										showSection(selection[0]);
+									}
 								}
 							}
 						});
@@ -506,11 +563,11 @@ public class ConfigView extends AbstractIView {
 				});
 	}
 
-	protected void filterTree(TreeItem[] items, String text, ArrayList foundItems)
-	{
+	protected void filterTree(TreeItem[] items, String text,
+			ArrayList<TreeItem> foundItems) {
 		text = text.toLowerCase();
 		for (int i = 0; i < items.length; i++) {
-			ensureSectionBuilt(items[i]);
+			ensureSectionBuilt(items[i], false);
 			ScrolledComposite composite = (ScrolledComposite) items[i].getData("Panel");
 
 			if (text.length() > 0
@@ -557,6 +614,20 @@ public class ConfigView extends AbstractIView {
 				if (((Button)child).getText().toLowerCase().indexOf(text) >= 0) {
 					return true;
 				}
+			} else if (child instanceof List) {
+				String[] items = ((List)child).getItems();
+				for (String item : items) {
+					if (item.toLowerCase().indexOf(text) >= 0) {
+						return true;
+					}
+				}
+			} else if (child instanceof Combo) {
+				String[] items = ((Combo)child).getItems();
+				for (String item : items) {
+					if (item.toLowerCase().indexOf(text) >= 0) {
+						return true;
+					}
+				}
 			}
 
 			if (child instanceof Composite) {
@@ -574,18 +645,75 @@ public class ConfigView extends AbstractIView {
 
     if (item != null) {
     	
-    	ensureSectionBuilt(section);
+    	ensureSectionBuilt(section, true);
     	
       layoutConfigSection.topControl = item;
       
       setupSC(item);
+
+      if (filterText != null && filterText.length() > 0) {
+      	hilightText(item, filterText);
+        item.layout(true, true);
+      }
+
       cConfigSection.layout();
       
       updateHeader(section);
     }
   }
 	
-	private void ensureSectionBuilt(TreeItem treeSection) {
+	private void hilightText(Composite c, String text) {
+		Control[] children = c.getChildren();
+		for (Control child : children) {
+			if (child instanceof Composite) {
+				hilightText((Composite) child, text);
+			}
+
+			if (child instanceof Label) {
+				if (((Label)child).getText().toLowerCase().indexOf(text) >= 0) {
+					hilightControl(child);
+				}
+			} else if (child instanceof Group) {
+				if (((Group)child).getText().toLowerCase().indexOf(text) >= 0) {
+					hilightControl(child);
+				}
+			} else if (child instanceof Button) {
+				if (((Button)child).getText().toLowerCase().indexOf(text) >= 0) {
+					hilightControl(child);
+				}
+			} else if (child instanceof List) {
+				String[] items = ((List)child).getItems();
+				for (String item : items) {
+					if (item.toLowerCase().indexOf(text) >= 0) {
+						hilightControl(child);
+						break;
+					}
+				}
+			} else if (child instanceof Combo) {
+				String[] items = ((Combo)child).getItems();
+				for (String item : items) {
+					if (item.toLowerCase().indexOf(text) >= 0) {
+						hilightControl(child);
+						break;
+					}
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * @param child
+	 *
+	 * @since 4.5.1.1
+	 */
+	private void hilightControl(Control child) {
+		child.setFont(headerFont);
+		child.setBackground(child.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+		child.setForeground(child.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
+	}
+
+	private void ensureSectionBuilt(TreeItem treeSection, boolean recreateIfAlreadyThere) {
     ScrolledComposite item = (ScrolledComposite)treeSection.getData("Panel");
 
     if (item != null) {
@@ -596,6 +724,9 @@ public class ConfigView extends AbstractIView {
     	  
         Control previous = item.getContent();
         if (previous instanceof Composite) {
+        	if (!recreateIfAlreadyThere) {
+        		return;
+        	}
         	configSection.configSectionDelete();
           sectionsCreated.remove(configSection);    	
           Utils.disposeComposite((Composite)previous,true);
@@ -653,14 +784,6 @@ public class ConfigView extends AbstractIView {
 	}
 
 
-  private Composite createConfigSection(String sNameID) {
-    return createConfigSection(null, sNameID, -1, true);
-  }
-
-  private Composite createConfigSection(String sNameID, int position) {
-    return createConfigSection(null, sNameID, position, true);
-  }
-
   public Composite createConfigSection(TreeItem treeItemParent, 
                                         String sNameID, 
                                         int position, 
@@ -700,7 +823,7 @@ public class ConfigView extends AbstractIView {
     return cConfigSection;
   }
   
-  private static Comparator insert_point_comparator = new Comparator() {
+  private static Comparator<Object> insert_point_comparator = new Comparator<Object>() {
 	  
 	  private String asString(Object o) {
 		  if (o instanceof String) {
@@ -720,7 +843,7 @@ public class ConfigView extends AbstractIView {
 	  }
   };
   
-  public static int findInsertPointFor(String name, Object structure) {
+  private static int findInsertPointFor(String name, Object structure) {
 	  TreeItem[] children = null;
 	  if (structure instanceof Tree) {
 	      children = ((Tree)structure).getItems();
@@ -834,20 +957,19 @@ public class ConfigView extends AbstractIView {
 		});
   }
   
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#getComposite()
-   */
-  public Composite getComposite() {
+  private Composite getComposite() {
     return cConfig;
   }
 
-  public void updateLanguage() {
-    super.updateLanguage();
+  private void updateLanguage() {
     updateHeader(tree.getSelection()[0]);
+    if (swtView != null) {
+    	swtView.setTitle(getFullTitle());
+    }
 //    cConfig.setSize(cConfig.computeSize(SWT.DEFAULT, SWT.DEFAULT));
   }
 
-  public void delete() {
+  private void delete() {
   	for (ConfigSection section : sectionsCreated) {
     	try {
     		section.configSectionDelete();
@@ -856,29 +978,29 @@ public class ConfigView extends AbstractIView {
     	}
     }
   	sectionsCreated.clear();
-    pluginSections.clear();
-    if(! tree.isDisposed()) {
-	    TreeItem[] items = tree.getItems();
-	    for (int i = 0; i < items.length; i++) {
-	      Composite c = (Composite)items[i].getData("Panel");
-	      Utils.disposeComposite(c);
-	      items[i].setData("Panel", null);
-	
-	      items[i].setData("ConfigSectionSWT", null);
+  	if ( pluginSections != null ){
+  		pluginSections.clear();
+  	}
+  	if ( tree != null ){
+	    if(! tree.isDisposed()) {
+		    TreeItem[] items = tree.getItems();
+		    for (int i = 0; i < items.length; i++) {
+		      Composite c = (Composite)items[i].getData("Panel");
+		      Utils.disposeComposite(c);
+		      items[i].setData("Panel", null);
+		
+		      items[i].setData("ConfigSectionSWT", null);
+		    }
 	    }
-    }
+  	}
     Utils.disposeComposite(cConfig);
 
   	Utils.disposeSWTObjects(new Object[] { headerFont, filterFoundFont });
 		headerFont = null;
 		filterFoundFont = null;
-
-    ImageLoader imageLoader = ImageLoader.getInstance();
-    imageLoader.releaseImage("smallx-gray");
-    imageLoader.releaseImage("smallx");
   }
 
-  public String getFullTitle() {
+  private String getFullTitle() {
   	/*
   	 * Using resolveLocalizationKey because there are different version for Classic vs. Vuze
   	 */
@@ -896,7 +1018,7 @@ public class ConfigView extends AbstractIView {
 
   public void
   selectSection(
-  	Class	config_section_class )
+  	Class<?>	config_section_class )
   {
 	  TreeItem[]	items = tree.getItems();
 	  
@@ -923,8 +1045,56 @@ public class ConfigView extends AbstractIView {
 
 		if (null != pluginSections) {
 			for (int i = 0; i < pluginSections.size(); i++) {
-				((ConfigSection) pluginSections.get(i)).configSectionSave();
+				pluginSections.get(i).configSectionSave();
 			}
 		}
 	}
+  
+  private void dataSourceChanged(Object newDataSource) {
+  	
+  	if (newDataSource instanceof String) {
+			String id = (String) newDataSource;
+	  	startSection = id;
+	  	Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					selectSection(startSection);
+				}
+			});
+		}
+  }
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	updateLanguage();
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        break;
+    }
+
+    return true;
+  }
+
 }
diff --git a/org/gudy/azureus2/ui/swt/views/DetailedListView.java b/org/gudy/azureus2/ui/swt/views/DetailedListView.java
deleted file mode 100644
index 2d67cf5..0000000
--- a/org/gudy/azureus2/ui/swt/views/DetailedListView.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Created on 30 Jun 2008
- * Created by Allan Crooks
- * 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 org.gudy.azureus2.ui.swt.views;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.*;
-import org.eclipse.swt.widgets.*;
-
-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.IndentWriter;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
-import org.gudy.azureus2.ui.swt.plugins.UISWTView;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
-
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.ui.common.table.*;
-import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-
-import org.gudy.azureus2.plugins.download.Download;
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-
-/**
- * @author MjrTom
- *			2005/Dec/08: Avg Avail Item
- */
-
-public class DetailedListView extends AbstractIView implements
-		ObfusticateImage, IViewExtension
-{
-	private static int SASH_WIDTH = 8;
-
-	final static TableColumnCore[] tableIncompleteItems = TableColumnCreator.createIncompleteDM(TableManager.TABLE_MYTORRENTS_INCOMPLETE);
-	
-	private AzureusCore	azureus_core;
-  
-  private MyTorrentsView torrentview;
-  private UISWTViewImpl managerview;
-  private Composite managerview_parent;
-
-	private Composite form;
-
-	private MyTorrentsView lastSelectedView;
-
-  public DetailedListView(AzureusCore	_azureus_core) {
-  	azureus_core		= _azureus_core;
-
-    TableColumnManager tcManager = TableColumnManager.getInstance();
-    tcManager.addColumns(tableIncompleteItems);
-  }
-
-  public Composite getComposite() {
-    return form;
-  }
-  
-  public void delete() {
-    if (torrentview != null)
-      torrentview.delete();
-    super.delete();
-  }
-
-  public void initialize(Composite parent) {
-    if (form != null) {
-      return;
-    }
-    
-    form = new Composite(parent, SWT.NONE);
-		FormLayout flayout = new FormLayout();
-		flayout.marginHeight = 0;
-		flayout.marginWidth = 0;
-		form.setLayout(flayout);
-		GridData gridData;
-		gridData = new GridData(GridData.FILL_BOTH);
-		form.setLayoutData(gridData);
-    
-		GridLayout layout;
-
-    
-    final Composite child1 = new Composite(form,SWT.NULL);
-    layout = new GridLayout();
-    layout.numColumns = 1;
-    layout.horizontalSpacing = 0;
-    layout.verticalSpacing = 0;
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    child1.setLayout(layout);
-    torrentview = new MyTorrentsView(azureus_core, "DetailedTorrentList",
-				false, tableIncompleteItems);
-    torrentview.initialize(child1);
-    
-    torrentview.getTableView().addSelectionListener(new TableSelectionAdapter() {
-    	public void selected(TableRowCore[] rows) {
-    		try {
-    		DownloadManager[] dms = new DownloadManager[rows.length];
-    		for (int i=0; i<rows.length; i++) {
-    			dms[i] = (DownloadManager)rows[i].getDataSource(true);
-    		}
-    		refreshDownloadView(dms);
-    		}
-    		catch (Exception e) {e.printStackTrace();}
-    	}
-    }, true);
-    
-    final Sash sash = new Sash(form, SWT.HORIZONTAL);
-
-    final Composite child2 = new Composite(form,SWT.NULL);
-    this.managerview_parent = child2;
-    layout = new GridLayout();
-    layout.numColumns = 1;
-    layout.horizontalSpacing = 0;
-    layout.verticalSpacing = 0;
-    layout.marginHeight = 0;
-    layout.marginWidth = 0;
-    child2.setLayout(layout);
-
-    FormData formData;
-
-		// FormData for table child1
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.top = new FormAttachment(0, 0);
-		child1.setLayoutData(formData);
-		final FormData child1Data = formData;
-    
-		// sash
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.top = new FormAttachment(child1);
-		formData.height = SASH_WIDTH;
-		sash.setLayoutData(formData);
-
-    // child2
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.bottom = new FormAttachment(100, 0);
-		formData.top = new FormAttachment(sash);
-    // More precision, times by 100
-    int weight = (int) (COConfigurationManager.getFloatParameter("DetailedList.SplitAt"));
-		if (weight > 10000) {
-			weight = 10000;
-		} else if (weight < 100) {
-			weight *= 100;
-		}
-		// Min/max of 5%/95%
-		if (weight < 500) {
-			weight = 500;
-		} else if (weight > 9000) {
-			weight = 9000;
-		}
-		
-		// height will be set on first resize call
-		sash.setData("PCT", new Double((float)weight / 10000));
-		child2.setLayoutData(formData);
-
-		
-		// Listeners to size the folder
-		sash.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				final boolean FASTDRAG = true;
-
-				if (FASTDRAG && e.detail == SWT.DRAG)
-					return;
-
-				child1Data.height = e.y + e.height - SASH_WIDTH;
-				form.layout();
-
-				Double l = new Double((double) child1.getBounds().height
-						/ form.getBounds().height);
-				sash.setData("PCT", l);
-				if (e.detail != SWT.DRAG)
-					COConfigurationManager.setParameter("DetailedList.SplitAt", (int) (l
-							.doubleValue() * 10000));
-			}
-		});
-
-		form.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event e) {
-				Double l = (Double) sash.getData("PCT");
-				if (l != null) {
-					child1Data.height = (int) (form.getBounds().height * l
-							.doubleValue());
-					form.layout();
-				}
-			}
-		});
-  }
-
-  public void refresh() {
-    if (getComposite() == null || getComposite().isDisposed())
-      return;
-
-    torrentview.refresh();
-  }
-
-  public void updateLanguage() {
-  	// no super call, the views will do their own
-  	
-    if (getComposite() == null || getComposite().isDisposed())
-      return;
-
-    torrentview.updateLanguage();
-	}
-
-	public String getFullTitle() {
-    return MessageText.getString("DetailedListView.title");
-  }
-  
-  // XXX: Is there an easier way to find out what has the focus?
-  private MyTorrentsView getCurrentView() {
-    // wrap in a try, since the controls may be disposed
-    try {
-      if (torrentview.isTableFocus())
-        lastSelectedView = torrentview;
-    } catch (Exception ignore) {/*ignore*/}
-
-    return lastSelectedView;
-  }
-
-  // IconBarEnabler
-  public boolean isEnabled(String itemKey) {
-    IView currentView = getCurrentView();
-    if (currentView != null)
-      return currentView.isEnabled(itemKey);
-    else
-      return false;
-  }
-  
-  // IconBarEnabler
-  // @see org.gudy.azureus2.ui.swt.views.AbstractIView#itemActivated(java.lang.String)
-  public void itemActivated(String itemKey) {
-    IView currentView = getCurrentView();
-    if (currentView != null)
-      currentView.itemActivated(itemKey);    
-  }
-  
-  public String getIconBarPluginIdentity() {return "torrents";}
-  public Object[] getIconBarPluginContextData() {
-	  DownloadManager[] dms = getSelectedDownloads();
-	  if (dms == null) {return null;}
-	  Download[] res = new Download[dms.length];
-	  for (int i=0; i<res.length; i++) {
-		  res[i] = PluginCoreUtils.wrap(dms[i]);
-	  }
-	  return res;
-  }
-  
-  public DownloadManager[] getSelectedDownloads() {
-	  MyTorrentsView currentView = getCurrentView();
-	  if (currentView == null) {return null;}
-	  return currentView.getSelectedDownloads();
-  }
-  
-  public void
-  generateDiagnostics(
-	IndentWriter	writer )
-  {
-	  super.generateDiagnostics( writer );
-
-	  try{
-		  writer.indent();
-	  
-		  writer.println( "Downloading" );
-		  
-		  writer.indent();
-
-		  torrentview.generateDiagnostics( writer );
-	  
-	  }finally{
-		  
-		  writer.exdent();
-		  
-		  writer.exdent();
-	  }
-	  
-	  try{
-		  writer.indent();
-	  
-		  writer.println( "Seeding" );
-		  
-		  writer.indent();
-	  
-	  }finally{
-		  
-		  writer.exdent();
-
-		  writer.exdent();
-	  }
-  }
-
-	public Image obfusticatedImage(Image image, Point shellOffset) {
-		if (torrentview != null) {
-			torrentview.obfusticatedImage(image, shellOffset);
-		}
-		return image;
-	}
-
-	public Menu getPrivateMenu() {
-		return null;
-	}
-
-	public void viewActivated() {
-    IView currentView = getCurrentView();
-    if (currentView instanceof IViewExtension) {
-    	((IViewExtension)currentView).viewActivated();
-    }
-    if (currentView instanceof MyTorrentsView) {
-    	((MyTorrentsView)currentView).updateSelectedContent();
-    }
-	}
-
-	public void viewDeactivated() {
-    IView currentView = getCurrentView();
-    if (currentView == null) {return;}
-    if (currentView instanceof IViewExtension) {
-    	((IViewExtension)currentView).viewDeactivated();
-    }
-    String ID = currentView.getShortTitle();
-    if (currentView instanceof MyTorrentsView) {
-    	ID = ((MyTorrentsView)currentView).getTableView().getTableID();
-    }
-
-    SelectedContentManager.changeCurrentlySelectedContent(ID, null,
-				torrentview == null ? null : torrentview.getTableView());
-	}
-	
-	  public void refreshDownloadView(DownloadManager[] dms) {
-		  System.out.println("refreshDownloadView change");
-		  if (dms.length != 1) return;
-		  boolean change = this.managerview == null || !dms[0].equals(this.managerview.getDataSource());
-		  if (!change) {return;}
-		  
-		  if (this.managerview != null) {
-			  this.managerview.delete();
-		  }
-		  try {
-				this.managerview = new UISWTViewImpl(null, "DMView", new ManagerView(), dms[0]);
-				this.managerview.setUseCoreDataSource(true);
-			  this.managerview.initialize(this.managerview_parent);
-			  this.managerview_parent.layout();
-			} catch (Exception e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-			}
-	  }
-}
diff --git a/org/gudy/azureus2/ui/swt/views/FilesView.java b/org/gudy/azureus2/ui/swt/views/FilesView.java
index 00cc9a2..de57691 100644
--- a/org/gudy/azureus2/ui/swt/views/FilesView.java
+++ b/org/gudy/azureus2/ui/swt/views/FilesView.java
@@ -26,40 +26,55 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.*;
-
+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.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 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.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.torrent.TOTorrent;
 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.plugins.ui.tables.TableManager;
-import org.gudy.azureus2.ui.swt.*;
-import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
 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;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 import org.gudy.azureus2.ui.swt.views.tableitems.files.*;
-import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
-import com.aelitis.azureus.core.AzureusCoreOperation;
-import com.aelitis.azureus.core.AzureusCoreOperationTask;
+import com.aelitis.azureus.core.util.AZ3Functions;
+import com.aelitis.azureus.core.util.RegExUtil;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+
 
 /**
  * @author Olivier
@@ -70,8 +85,9 @@ public class FilesView
 	extends TableViewTab<DiskManagerFileInfo>
 	implements TableDataSourceChangedListener, TableSelectionListener,
 	TableViewSWTMenuFillListener, TableRefreshListener, DownloadManagerStateAttributeListener,
-	TableLifeCycleListener
+	TableLifeCycleListener, TableViewFilterCheck<DiskManagerFileInfo>, KeyListener
 {
+	private static boolean registeredCoreSubViews = false;
 	boolean refreshing = false;
   private DragSource dragSource = null;
 
@@ -89,7 +105,12 @@ public class FilesView
     new PriorityItem(),
     new StorageTypeItem(),
     new FileExtensionItem(), 
+    new FileIndexItem(),
+    new TorrentRelativePathItem(),
+    new FileCRC32Item(),
+    new FileMD5Item(),
   };
+	public static final String MSGID_PREFIX = "FilesView";
   
   private DownloadManager manager = null;
   
@@ -112,30 +133,52 @@ public class FilesView
   private MenuItem path_item;
 
   private TableViewSWT<DiskManagerFileInfo> tv;
+	private final boolean allowTabViews;
   
 
   /**
    * Initialize 
    */
 	public FilesView() {
+		super(MSGID_PREFIX);
+		allowTabViews = true;
+	}
+
+	public FilesView(boolean allowTabViews) {
 		super("FilesView");
+		this.allowTabViews = allowTabViews;
 	}
 
+
 	public TableViewSWT<DiskManagerFileInfo> initYourTableView() {
-		tv = new TableViewSWTImpl<DiskManagerFileInfo>(
+		tv = TableViewFactory.createTableViewSWT(
 				org.gudy.azureus2.plugins.disk.DiskManagerFileInfo.class,
 				TableManager.TABLE_TORRENT_FILES, getPropertiesPrefix(), basicItems,
 				"firstpiece", SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
 		tv.setRowDefaultIconSize(new Point(16, 16));
-		tv.setEnableTabViews(true);
-		tv.setCoreTabViews(new IView[] { new FileInfoView()
-		});
+		if (allowTabViews) {
+  		tv.setEnableTabViews(true);
+  		
+  		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+  		if (uiFunctions != null) {
+  			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+  			
+  			if (pluginUI != null && !registeredCoreSubViews) {
+
+  				pluginUI.addView(TableManager.TABLE_TORRENT_FILES, "FileInfoView",
+							FileInfoView.class, manager);
+
+  				registeredCoreSubViews = true;
+  			}
+  		}
+		}
 
 		tv.addTableDataSourceChangedListener(this, true);
 		tv.addRefreshListener(this, true);
 		tv.addSelectionListener(this, false);
 		tv.addMenuFillListener(this);
 		tv.addLifeCycleListener(this);
+		tv.addKeyListener(this);
 
 		return tv;
 	}
@@ -163,6 +206,7 @@ public class FilesView
 	
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#deselected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void deselected(TableRowCore[] rows) {
+		updateSelectedContent();
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#focusChanged(com.aelitis.azureus.ui.common.table.TableRowCore)
@@ -171,477 +215,101 @@ public class FilesView
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void selected(TableRowCore[] rows) {
+		updateSelectedContent();
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[])
-	public void defaultSelected(TableRowCore[] rows, int stateMask) {
-		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) tv.getFirstSelectedDataSource();
-		if (fileInfo != null
-				&& fileInfo.getAccessMode() == DiskManagerFileInfo.READ)
-			Utils.launch(fileInfo.getFile(true).toString());
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.TableViewSWTMenuFillListener#fillMenu(org.eclipse.swt.widgets.Menu)
-	public void fillMenu(String sColumnName, final Menu menu) {
-		Shell shell = menu.getShell();
-		Object[] data_sources = tv.getSelectedDataSources().toArray();
-		boolean hasSelection = (data_sources.length > 0);
-
-    final MenuItem itemOpen = new MenuItem(menu, SWT.PUSH);
-    Messages.setLanguageText(itemOpen, "FilesView.menu.open");
-    Utils.setMenuItemImage(itemOpen, "run");
-    // Invoke open on enter, double click
-    menu.setDefaultItem(itemOpen);
-
-	// Explore  (Copied from MyTorrentsView)
-	final boolean use_open_containing_folder = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
-	final MenuItem itemExplore = new MenuItem(menu, SWT.PUSH);
-	Messages.setLanguageText(itemExplore, "MyTorrentsView.menu." + (use_open_containing_folder ? "open_parent_folder" : "explore"));
-	itemExplore.addListener(SWT.Selection, new Listener() {
-		public void handleEvent(Event event) {
-		    Object[] dataSources = tv.getSelectedDataSources().toArray();
-		    for (int i = dataSources.length - 1; i >= 0; i--) {
-		    	DiskManagerFileInfo info = (DiskManagerFileInfo)dataSources[i];
-		    	if (info != null) {
-		    		File this_file = info.getFile(true);
-		    		File parent_file = (use_open_containing_folder) ? this_file.getParentFile() : null;
-		    		ManagerUtils.open((parent_file == null) ? this_file : parent_file);
-		    	}
-		    }
-		}
-	});
-	itemExplore.setEnabled(hasSelection);
-
-	MenuItem itemRenameOrRetarget = null, itemRename = null, itemRetarget = null;
-
-	itemRenameOrRetarget = new MenuItem(menu, SWT.PUSH);
-	Messages.setLanguageText(itemRenameOrRetarget, "FilesView.menu.rename");
-	itemRenameOrRetarget.setData("rename", Boolean.valueOf(true));
-	itemRenameOrRetarget.setData("retarget", Boolean.valueOf(true));
-	
-	itemRename = new MenuItem(menu, SWT.PUSH);
-	itemRetarget = new MenuItem(menu, SWT.PUSH);
-	Messages.setLanguageText(itemRename, "FilesView.menu.rename_only");
-	Messages.setLanguageText(itemRetarget, "FilesView.menu.retarget");
-	
-	itemRename.setData("rename", Boolean.valueOf(true));
-	itemRename.setData("retarget", Boolean.valueOf(false));
-	itemRetarget.setData("rename", Boolean.valueOf(false));
-	itemRetarget.setData("retarget", Boolean.valueOf(true));
-		
-    final MenuItem itemPriority = new MenuItem(menu, SWT.CASCADE);
-    Messages.setLanguageText(itemPriority, "FilesView.menu.setpriority"); //$NON-NLS-1$
-    
-    final Menu menuPriority = new Menu(shell, SWT.DROP_DOWN);
-    itemPriority.setMenu(menuPriority);
-    
-    final MenuItem itemHigh = new MenuItem(menuPriority, SWT.CASCADE);
-    itemHigh.setData("Priority", new Integer(0));
-    Messages.setLanguageText(itemHigh, "FilesView.menu.setpriority.high"); //$NON-NLS-1$
-    
-    final MenuItem itemLow = new MenuItem(menuPriority, SWT.CASCADE);
-    itemLow.setData("Priority", new Integer(1));
-    Messages.setLanguageText(itemLow, "FilesView.menu.setpriority.normal"); //$NON-NLS-1$
-    
-    final MenuItem itemSkipped = new MenuItem(menuPriority, SWT.CASCADE);
-    itemSkipped.setData("Priority", new Integer(2));
-    Messages.setLanguageText(itemSkipped, "FilesView.menu.setpriority.skipped"); //$NON-NLS-1$
-
-    final MenuItem itemDelete = new MenuItem(menuPriority, SWT.CASCADE);
-    itemDelete.setData("Priority", new Integer(3));
-    Messages.setLanguageText(itemDelete, "wizard.multitracker.delete");	// lazy but we're near release
-
-    new MenuItem(menu, SWT.SEPARATOR);
-
-	if (!hasSelection) {
-		itemOpen.setEnabled(false);
-		itemPriority.setEnabled(false);
-		itemRenameOrRetarget.setEnabled(false);
-		itemRename.setEnabled(false);
-		itemRetarget.setEnabled(false);
-		return;
-	}
-
-	boolean open 				= true;
-	boolean all_compact 		= true;
-	boolean	all_skipped			= true;
-	boolean	all_priority		= true;
-	boolean	all_not_priority	= true;
-		
-	DiskManagerFileInfo[] dmi_array = new DiskManagerFileInfo[data_sources.length];
-	
-	System.arraycopy(data_sources, 0, dmi_array, 0, data_sources.length);
-	
-	int[] storage_types = manager.getStorageType(dmi_array);
-		
-	for (int i = 0; i < dmi_array.length; i++) {
-
-		DiskManagerFileInfo file_info = dmi_array[i];
-
-		if (open && file_info.getAccessMode() != DiskManagerFileInfo.READ) {
-
-			open = false;
-		}
-
-		if (all_compact && storage_types[i] != DiskManagerFileInfo.ST_COMPACT) {
-			all_compact = false;
-		}
-
-		if (all_skipped || all_priority || all_not_priority) {
-			if ( file_info.isSkipped()){
-				all_priority		= false;
-				all_not_priority	= false;
-			}else{
-				all_skipped = false;
-
-				// Only do this check if we need to.
-				if (all_not_priority || all_priority) {
-					if (file_info.isPriority()){
-						all_not_priority = false;
-					}else{
-						all_priority = false;
-					}
-				}
-			}
-		}
-	}
-
-	// we can only open files if they are read-only
-
-	itemOpen.setEnabled(open);
-
-	// can't rename files for non-persistent downloads (e.g. shares) as these
-	// are managed "externally"
-
-	itemRenameOrRetarget.setEnabled(manager.isPersistent());
-	itemRename.setEnabled(manager.isPersistent());
-	itemRetarget.setEnabled(manager.isPersistent());
-
-	itemSkipped.setEnabled( !all_skipped );
-
-	itemHigh.setEnabled( !all_priority );
-
-	itemLow.setEnabled( !all_not_priority );
-
-	itemDelete.setEnabled( !all_compact );
-
-	itemOpen.addListener(SWT.Selection, new TableSelectedRowsListener(tv) {
-		public void run(TableRowCore row) {
-			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)row.getDataSource(true);
-			if (fileInfo.getAccessMode() == DiskManagerFileInfo.READ) {
-				Utils.launch(fileInfo.getFile(true).toString());
-			}
-		}
-	});
-    
-    Listener rename_listener = new Listener() {
-    	public void handleEvent(Event event) {
-    		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);
-    	}
-    };
-    
-   	itemRenameOrRetarget.addListener(SWT.Selection, rename_listener);
-   	itemRename.addListener(SWT.Selection, rename_listener);
-   	itemRetarget.addListener(SWT.Selection, rename_listener);
-    
-    Listener priorityListener = new Listener() {
-			public void handleEvent(Event event) {
-				final int priority = ((Integer) event.widget.getData("Priority")).intValue();
-				final TableRowCore[] selectedRows = tv.getSelectedRows();
-				Utils.getOffOfSWTThread(new AERunnable(){
-					public void runSupport() {
-						changePriority(priority, selectedRows);
-					}
-				});
-			}
-    };
-
-    itemHigh.addListener(SWT.Selection, priorityListener); 
-    itemLow.addListener(SWT.Selection, priorityListener);
-    itemSkipped.addListener(SWT.Selection, priorityListener); 
-    itemDelete.addListener(SWT.Selection, priorityListener);
-	}
-
-	private String askForRenameFilename(DiskManagerFileInfo fileInfo) {
-		SimpleTextEntryWindow dialog = new SimpleTextEntryWindow(
-				"FilesView.rename.filename.title", "FilesView.rename.filename.text");
-		dialog.setPreenteredText(fileInfo.getFile(true).getName(), false); // false -> it's not "suggested", it's a previous value
-		dialog.allowEmptyInput(false);
-		dialog.prompt();
-		if (!dialog.hasSubmittedInput()) {return null;}
-		return dialog.getSubmittedInput();
-	}
-	
-	private String askForRetargetedFilename(DiskManagerFileInfo fileInfo) {
-		FileDialog fDialog = new FileDialog(Utils.findAnyShell(), SWT.SYSTEM_MODAL | SWT.SAVE);  
-		File existing_file = fileInfo.getFile(true);
-		fDialog.setFilterPath(existing_file.getParent());
-		fDialog.setFileName(existing_file.getName());
-		fDialog.setText(MessageText.getString("FilesView.rename.choose.path"));
-		return fDialog.open();
-	}
-	
-	private String askForSaveDirectory(DiskManagerFileInfo fileInfo) {
-		DirectoryDialog dDialog = new DirectoryDialog(Utils.findAnyShell(), SWT.SYSTEM_MODAL | SWT.SAVE);
-		File current_dir = fileInfo.getFile(true).getParentFile();
-		dDialog.setFilterPath(current_dir.getPath());
-		dDialog.setText(MessageText.getString("FilesView.rename.choose.path.dir"));
-		return dDialog.open();
-	}
-	
-	private boolean askCanOverwrite(File file) {
-		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
-	private void moveFile(final DiskManagerFileInfo fileInfo, final File target) {
-
-		// this behaviour should be put further down in the core but I'd rather not
-		// do so close to release :(
-		final boolean[] result = { false };
-
-		is_changing_links = true;
-		FileUtil.runAsTask(new AzureusCoreOperationTask() {
-			public void run(AzureusCoreOperation operation) {
-					result[0] = fileInfo.setLink(target);
-				}
-			}
-		);
-		is_changing_links = false;
-
-		if (!result[0]){
-			new MessageBoxShell(SWT.ICON_ERROR | SWT.OK, 
-					MessageText.getString("FilesView.rename.failed.title"),
-					MessageText.getString("FilesView.rename.failed.text")).open(null);
+	public boolean 
+	filterCheck(
+		DiskManagerFileInfo ds, String filter, boolean regex )
+	{
+		if ( filter == null || filter.length() == 0 ){
+			
+			return( true );
 		}
 
-	}
-  
-	protected void rename(TableRowCore[] rows, boolean rename_it, boolean retarget_it) {
-	 	if (manager == null) {return;}
-	 	if (rows.length == 0) {return;}
-	 	
-	 	String save_dir = null;
-	 	if (!rename_it && retarget_it) {
-	 		save_dir = askForSaveDirectory((DiskManagerFileInfo)rows[0].getDataSource(true));
-	 		if (save_dir == null) {return;}
-	 	}
-	 	
-		boolean	paused = false;
 		try {
-			for (int i=0; i<rows.length; i++) {
-				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) {
-					String s_target = askForRetargetedFilename(fileInfo);
-					if (s_target != null)
-						f_target = new File(s_target);
-				}
-				else if (rename_it) {
-					String s_target = askForRenameFilename(fileInfo);
-					if (s_target != null)
-						f_target = new File(existing_file.getParentFile(), s_target);
-				}
-				else {
-					// Parent directory has changed.
-					f_target = new File(save_dir, existing_file.getName());
-				}
-				
-				// So are we doing a rename?
-				// If the user has decided against it - abort the op.
-				if (f_target == null) {return;}
+			File file = ds.getFile(true);
+
+			String name = filter.contains( File.separator )?file.getAbsolutePath():file.getName();
 			
-			    if (!paused) {paused = manager.pause();}
-			    
-    			if (f_target.exists()){
-    				
-    				// Nothing to do.
-    				if (f_target.equals(existing_file))
-    					continue;
-    					
-    				// A rewrite will occur, so we need to ask the user's permission.
-    				else if (existing_file.exists() && !askCanOverwrite(existing_file))
-    					continue;
-    				
-    				// If we reach here, then it means we are doing a real move, but there is
-    				// no existing file.
-    			}
-    					
-    			final File ff_target = f_target;
-  				Utils.getOffOfSWTThread(new AERunnable(){
-  					public void runSupport() {
-  						moveFile(fileInfo, ff_target);
-  	    			row.invalidate();
-  					}
-  				});
-			}
-		}
-		finally {
-			if (paused){manager.resume();}
-		}
-	}
-	
-	
-  private void
-  changePriority(
-	  int				type ,
-	  TableRowCore[]	rows )
-  {
-	  	if ( manager == null){
-	  		
-	  		return;
-	  	}
-  				
-	  	boolean paused = false;
-		try{
-            DiskManagerFileInfo[] file_infos = new DiskManagerFileInfo[rows.length];
-     	 	for (int i=0; i<rows.length; i++) {
-     	 		file_infos[i] = (DiskManagerFileInfo)rows[i].getDataSource(true);
-     	 		if (type == 0 || type == 1) {
-     	 			file_infos[i].setPriority(type==0);
-				}
-     	 	}
-     	 	boolean skipped = (type == 2 || type == 3);
-     	 	boolean delete_action = (type == 3);
-     	 	paused = setSkipped(file_infos, skipped, delete_action);
-		}finally{
+			String s = regex ? filter : "\\Q" + filter.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E";
 			
-			if ( paused ){
+			boolean	match_result = true;
 			
-				manager.resume();
+			if ( regex && s.startsWith( "!" )){
+				
+				s = s.substring(1);
+				
+				match_result = false;
 			}
-		}
-  }
+			
+			Pattern pattern = RegExUtil.getCachedPattern( "fv:search", s, Pattern.CASE_INSENSITIVE);
   
-  // Returns true if it was paused here.
-  private boolean
-  setSkipped(
-	 DiskManagerFileInfo[]	infos,
-	 boolean				skipped,
-	 boolean				delete_action)
-  {
-		// if we're not managing the download then don't do anything other than
-		// change the file's priority
-	
-	if (!manager.isPersistent()){
-		for (int i=0; i<infos.length; i++) {
-			infos[i].setSkipped(skipped);
-		}
-		return false;
+			return( pattern.matcher(name).find() == match_result );
+			
+		} catch (Exception e) {
+			
+			return true;
+		}	
 	}
 	
-	int[] existing_storage_types = manager.getStorageType(infos);
-	int nbFiles = manager.getDiskManagerFileInfoSet().nbFiles();
-	boolean[] setLinear = new boolean[nbFiles];
-	boolean[] setCompact = new boolean[nbFiles];
-	int compactCount = 0;
-	int linearCount = 0;
-
-
-	if(infos.length > 1)
+	public void filterSet(String filter)
 	{
-		
+		// System.out.println( filter );
 	}
-	// This should hopefully reduce the number of "exists" checks.
-	File save_location = manager.getAbsoluteSaveLocation();
-	boolean root_exists = save_location.isDirectory() || (infos.length <= 1 && save_location.exists());
 	
-	boolean type_has_been_changed = false;
-	boolean requires_pausing = false;
-
-	for (int i=0; i<infos.length; i++) {
-		int existing_storage_type = existing_storage_types[i];  
-		int new_storage_type = DiskManagerFileInfo.ST_LINEAR;
-		if (skipped) {
-
-			// Check to see if the file exists, but try to avoid doing an
-			// actual disk check if possible.
-			File existing_file = infos[i].getFile(true);
-			
-			// Avoid performing existing_file.exists if we know that it is meant
-			// to reside in the default save location and that location does not
-			// exist.
-			boolean perform_check;
-			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) {
-						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;}
-				}
+	public void updateSelectedContent() {
+		Object[] dataSources = tv.getSelectedDataSources(true);
+		List<SelectedContent> listSelected = new ArrayList<SelectedContent>(
+				dataSources.length);
+		for (Object ds : dataSources) {
+			if (ds instanceof DiskManagerFileInfo) {
+				DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+				listSelected.add(new SelectedContent(fileInfo.getDownloadManager(),
+						fileInfo.getIndex()));
 			}
-			// File does not exist.
-			else {new_storage_type = DiskManagerFileInfo.ST_COMPACT;}			
 		}
+		SelectedContent[] sc = listSelected.toArray(new SelectedContent[0]);
+		SelectedContentManager.changeCurrentlySelectedContent(tv.getTableID(),
+				sc, tv);
+	}
+
+	
+	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[])
+	public void defaultSelected(TableRowCore[] rows, int stateMask) {
+		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) tv.getFirstSelectedDataSource();
 		
-		boolean has_changed = existing_storage_type != new_storage_type;
-		type_has_been_changed |= has_changed;
-		requires_pausing |= (has_changed && new_storage_type == DiskManagerFileInfo.ST_COMPACT);
+		if ( fileInfo == null ){
+			return;
+		}
 		
-		type_has_been_changed = 
-			existing_storage_type != new_storage_type;
+		AZ3Functions.provider az3 = AZ3Functions.getProvider();
 		
-		if(new_storage_type == DiskManagerFileInfo.ST_COMPACT)
-		{
-			setCompact[infos[i].getIndex()] = true;
-			compactCount++;
-		} else
-		{
-			setLinear[infos[i].getIndex()] = true;
-			linearCount++;			
+		if ( az3 != null ){
+			
+			DownloadManager dm = fileInfo.getDownloadManager();
+			
+			if ( az3.canPlay(dm, fileInfo.getIndex()) || (stateMask & SWT.CONTROL) > 0 ){
+				
+				az3.play( dm, fileInfo.getIndex() );
+				
+				return;
+			}
 		}
-	}
-	
-	boolean ok = true;
-	boolean paused = false;
-	if (type_has_been_changed) {
-		if (requires_pausing) paused = manager.pause();
-		if(linearCount > 0)
-			ok &= Arrays.equals(setLinear, manager.getDiskManagerFileInfoSet().setStorageTypes(setLinear, DiskManagerFileInfo.ST_LINEAR));
-		if(compactCount > 0)
-			ok &= Arrays.equals(setCompact, manager.getDiskManagerFileInfoSet().setStorageTypes(setCompact, DiskManagerFileInfo.ST_COMPACT));
-	}	
-	
-	if (ok) {
-		for (int i=0; i<infos.length; i++) {
-			infos[i].setSkipped(skipped);
+		
+		if ( fileInfo.getAccessMode() == DiskManagerFileInfo.READ ){
+			
+			Utils.launch(fileInfo);
 		}
 	}
-	
-	return paused;
-  }
 
+	// @see org.gudy.azureus2.ui.swt.views.TableViewSWTMenuFillListener#fillMenu(org.eclipse.swt.widgets.Menu)
+	public void fillMenu(String sColumnName, final Menu menu) {
+		Object[] data_sources = tv.getSelectedDataSources().toArray();
+		FilesViewMenuUtil.fillMenu(tv, menu, manager, data_sources);
+	}
+
+	
   // @see com.aelitis.azureus.ui.common.table.TableRefreshListener#tableRefresh()
   private boolean force_refresh = false;
   public void tableRefresh() {
@@ -675,7 +343,7 @@ public class FilesView
 		    	}
 		    	tv.removeDataSources(toRemove.toArray(new DiskManagerFileInfo[toRemove.size()]));
 		    	tv.addDataSources(toAdd.toArray(new DiskManagerFileInfo[toAdd.size()]));
-		    	((TableViewSWTImpl)tv).tableInvalidate();
+		    	tv.tableInvalidate();
 	    	} else
 	    	{
 		    	tv.removeAllTableRows();
@@ -703,15 +371,18 @@ public class FilesView
 		for (int i = 0; i < files.length; i++) {
 			DiskManagerFileInfo fileinfo = files[i];
 
-			// We can't just use tv.dataSourceExists(), since it does a .equals()
-			// comparison, and we want a reference comparison
-			TableRowCore row = tv.getRow(fileinfo);
-			if (row == null) {
-				return false;
-			}
-			// reference comparison
-			if (row.getDataSource(true) != fileinfo) {
-				return false;
+			if ( tv.isFiltered( fileinfo )){
+				// We can't just use tv.dataSourceExists(), since it does a .equals()
+				// comparison, and we want a reference comparison
+								
+				TableRowCore row = tv.getRow(fileinfo);
+				if (row == null) {
+					return false;
+				}
+				// reference comparison
+				if (row.getDataSource(true) != fileinfo) {
+					return false;
+				}
 			}
 		}
 		return true;
@@ -746,14 +417,16 @@ public class FilesView
   {
   	if (manager == null)
   		return null;
-	  return( manager.getDiskManagerFileInfo());
+	  return( manager.getDiskManagerFileInfoSet().getFiles());
   }
   
   // Used to notify us of when we need to refresh - normally for external changes to the
   // file links.
-  private boolean is_changing_links = false;
   public void attributeEventOccurred(DownloadManager dm, String attribute_name, int event_type) {
-	  if (is_changing_links) {return;}
+  	Object oIsChangingLinks = dm.getUserData("is_changing_links");
+  	if ((oIsChangingLinks instanceof Boolean) && ((Boolean)oIsChangingLinks).booleanValue()) {
+  		return;
+  	}
 	  this.force_refresh = true;
   }
   
@@ -761,6 +434,11 @@ public class FilesView
     createDragDrop();
   }
   
+  public void tableViewTabInitComplete() {
+  	updateSelectedContent();
+  	super.tableViewTabInitComplete();
+  }
+  
   public void tableViewDestroyed() {
   	Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
@@ -840,4 +518,68 @@ public class FilesView
 			Logger.log(new LogEvent(LogIDs.GUI, "failed to init drag-n-drop", t));
 		}
 	}
+	
+	public void refreshToolBarItems(Map<String, Long> list) {
+		super.refreshToolBarItems(list);
+		ISelectedContent[] content = SelectedContentManager.getCurrentlySelectedContent();
+		long hasEnabledSelect = content.length > 0
+				? UIToolBarItem.STATE_ENABLED : 0;
+		list.put("run", hasEnabledSelect);
+		list.put("start", hasEnabledSelect);
+		list.put("stop", hasEnabledSelect);
+		list.put("remove", hasEnabledSelect);
+		list.put("startstop", hasEnabledSelect);
+	}
+
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
+		String itemKey = item.getID();
+
+		Object[] selected = tv.getSelectedDataSources().toArray();
+		
+		if ( selected.length > 0 ){
+	    if(itemKey.equals("run")){
+	      TorrentUtil.runDataSources(selected);
+	      return true;
+	    }
+	    if(itemKey.equals("start")){
+	      TorrentUtil.queueDataSources(selected, false);
+	      UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+	      return true;
+	    }
+	    if(itemKey.equals("stop")){
+	      TorrentUtil.stopDataSources(selected);
+	      UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+	      return true;
+	    }
+	    if(itemKey.equals("remove")){
+	      TorrentUtil.removeDataSources(selected);
+	      UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+	      return true;
+	    }
+		}
+		
+    return super.toolBarItemActivated(item, activationType, datasource);
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+		boolean b = super.eventOccurred(event);
+		if (event.getType() == UISWTViewEvent.TYPE_FOCUSGAINED) {
+	    updateSelectedContent();
+		} else if (event.getType() == UISWTViewEvent.TYPE_FOCUSLOST) {
+		}
+		return b;
+	}
+
+	// @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
+	public void keyPressed(KeyEvent e) {
+		if (e.keyCode == SWT.F2 && (e.stateMask & SWT.MODIFIER_MASK) == 0) {
+			FilesViewMenuUtil.rename(tv, null, tv.getSelectedDataSources(true), true, false);
+			e.doit = false;
+			return;
+		}
+	}
+
+	// @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent)
+	public void keyReleased(KeyEvent e) {
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/FilesViewMenuUtil.java b/org/gudy/azureus2/ui/swt/views/FilesViewMenuUtil.java
new file mode 100644
index 0000000..b7a9607
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/FilesViewMenuUtil.java
@@ -0,0 +1,765 @@
+/**
+ * Created on May 12, 2010
+ *
+ * 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;
+
+import java.io.File;
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+
+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.internat.MessageText;
+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.plugins.sharing.ShareManager;
+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.Utils;
+import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
+import org.gudy.azureus2.ui.swt.shells.AdvRenameWindow;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+
+import com.aelitis.azureus.core.AzureusCoreOperation;
+import com.aelitis.azureus.core.AzureusCoreOperationTask;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.common.table.TableView;
+
+/**
+ * @author TuxPaper
+ * @created May 12, 2010
+ *
+ */
+public class FilesViewMenuUtil
+{
+	public static final Object PRIORITY_HIGH 	= new Object();
+	public static final Object PRIORITY_NORMAL 	= new Object();
+	public static final Object PRIORITY_LOW 	= new Object();
+	public static final Object PRIORITY_NUMERIC = new Object();
+	public static final Object PRIORITY_SKIPPED = new Object();
+	public static final Object PRIORITY_DELETE 	= new Object();
+
+	public static void fillMenu(final TableView tv,
+			final Menu menu, final DownloadManager manager,
+			final Object[] data_sources) {
+		Shell shell = menu.getShell();
+		boolean hasSelection = (data_sources.length > 0);
+
+		final MenuItem itemOpen = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemOpen, "FilesView.menu.open");
+		Utils.setMenuItemImage(itemOpen, "run");
+		// Invoke open on enter, double click
+		menu.setDefaultItem(itemOpen);
+
+		// Explore  (Copied from MyTorrentsView)
+		final boolean use_open_containing_folder = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
+		final MenuItem itemExplore = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemExplore, "MyTorrentsView.menu."
+				+ (use_open_containing_folder ? "open_parent_folder" : "explore"));
+		itemExplore.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				for (int i = data_sources.length - 1; i >= 0; i--) {
+					DiskManagerFileInfo info = (DiskManagerFileInfo) data_sources[i];
+					if (info != null) {
+						ManagerUtils.open(info, use_open_containing_folder);
+					}
+				}
+			}
+		});
+		itemExplore.setEnabled(hasSelection);
+
+		MenuItem itemRenameOrRetarget = null, itemRename = null, itemRetarget = null;
+
+		itemRenameOrRetarget = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemRenameOrRetarget, "FilesView.menu.rename");
+		itemRenameOrRetarget.setData("rename", Boolean.valueOf(true));
+		itemRenameOrRetarget.setData("retarget", Boolean.valueOf(true));
+
+		itemRename = new MenuItem(menu, SWT.PUSH);
+		itemRetarget = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemRename, "FilesView.menu.rename_only");
+		Messages.setLanguageText(itemRetarget, "FilesView.menu.retarget");
+
+		itemRename.setData("rename", Boolean.valueOf(true));
+		itemRename.setData("retarget", Boolean.valueOf(false));
+		itemRetarget.setData("rename", Boolean.valueOf(false));
+		itemRetarget.setData("retarget", Boolean.valueOf(true));
+
+			// quick view
+		
+		final MenuItem itemQuickView = new MenuItem(menu, SWT.CHECK);
+		Messages.setLanguageText(itemQuickView, "MainWindow.menu.quick_view");
+
+		itemQuickView.setEnabled( data_sources.length==1 && Utils.isQuickViewSupported((DiskManagerFileInfo)data_sources[0]));
+		itemQuickView.setSelection( data_sources.length==1 && Utils.isQuickViewActive((DiskManagerFileInfo)data_sources[0]));
+		
+		itemQuickView.addListener(
+				SWT.Selection,
+				new Listener()
+				{
+					public void 
+					handleEvent(
+						Event arg ) 
+					{
+						Utils.setQuickViewActive( (DiskManagerFileInfo)data_sources[0], itemQuickView.getSelection());
+					}
+				});
+		
+			// personal share
+		
+		final MenuItem itemPersonalShare = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemPersonalShare, "MyTorrentsView.menu.create_personal_share");
+		
+			// priority
+		
+		final MenuItem itemPriority = new MenuItem(menu, SWT.CASCADE);
+		Messages.setLanguageText(itemPriority, "FilesView.menu.setpriority");
+
+		final Menu menuPriority = new Menu(shell, SWT.DROP_DOWN);
+		itemPriority.setMenu(menuPriority);
+
+		final MenuItem itemHigh = new MenuItem(menuPriority, SWT.CASCADE);
+		itemHigh.setData("Priority", PRIORITY_HIGH);
+		Messages.setLanguageText(itemHigh, "FilesView.menu.setpriority.high"); 
+
+		final MenuItem itemNormal = new MenuItem(menuPriority, SWT.CASCADE);
+		itemNormal.setData("Priority", PRIORITY_NORMAL);
+		Messages.setLanguageText(itemNormal, "FilesView.menu.setpriority.normal");
+		
+		final MenuItem itemLow = new MenuItem(menuPriority, SWT.CASCADE);
+		itemLow.setData("Priority", PRIORITY_LOW);
+		Messages.setLanguageText(itemLow, "FileItem.low");
+
+		final MenuItem itemNumeric = new MenuItem(menuPriority, SWT.CASCADE);
+		itemNumeric.setData("Priority", PRIORITY_NUMERIC);
+		Messages.setLanguageText(itemNumeric, "FilesView.menu.setpriority.numeric"); 
+
+		final MenuItem itemSkipped = new MenuItem(menuPriority, SWT.CASCADE);
+		itemSkipped.setData("Priority", PRIORITY_SKIPPED);
+		Messages.setLanguageText(itemSkipped, "FilesView.menu.setpriority.skipped"); 
+
+		final MenuItem itemDelete = new MenuItem(menuPriority, SWT.CASCADE);
+		itemDelete.setData("Priority", PRIORITY_DELETE);
+		Messages.setLanguageText(itemDelete, "wizard.multitracker.delete"); // lazy but we're near release
+
+		new MenuItem(menu, SWT.SEPARATOR);
+
+		if (!hasSelection) {
+			itemOpen.setEnabled(false);
+			itemPriority.setEnabled(false);
+			itemRenameOrRetarget.setEnabled(false);
+			itemRename.setEnabled(false);
+			itemRetarget.setEnabled(false);
+			itemPersonalShare.setEnabled(false);
+			
+			return;
+		}
+
+		boolean open 			= true;
+		boolean all_compact 	= true;
+		boolean all_skipped 	= true;
+		boolean all_high_pri 	= true;
+		boolean all_normal_pri 	= true;
+		boolean all_low_pri 	= true;
+		boolean	all_complete	= true;
+		
+		final DiskManagerFileInfo[] dmi_array = new DiskManagerFileInfo[data_sources.length];
+
+		System.arraycopy(data_sources, 0, dmi_array, 0, data_sources.length);
+
+		int[] storage_types = manager.getStorageType(dmi_array);
+
+		for (int i = 0; i < dmi_array.length; i++) {
+
+			DiskManagerFileInfo file_info = dmi_array[i];
+
+			if (open && file_info.getAccessMode() != DiskManagerFileInfo.READ) {
+
+				open = false;
+			}
+
+			if (all_compact && storage_types[i] != DiskManagerFileInfo.ST_COMPACT && storage_types[i] != DiskManagerFileInfo.ST_REORDER_COMPACT ) {
+				all_compact = false;
+			}
+
+			if (all_skipped || all_high_pri || all_normal_pri || all_low_pri ) {
+				if (file_info.isSkipped()) {
+					all_high_pri = all_normal_pri = all_low_pri = false;
+				} else {
+					all_skipped = false;
+
+					// Only do this check if we need to.
+					if ( all_high_pri || all_normal_pri || all_low_pri ) {
+						int file_pri = file_info.getPriority();
+						if ( file_pri == 0 ){
+							all_high_pri = all_low_pri = false;
+						}else if ( file_pri == 1 ){
+							all_normal_pri = all_low_pri = false;
+						} else if ( file_pri == -1 ){
+							all_normal_pri = all_high_pri = false;
+						}else{
+							all_low_pri = all_normal_pri = all_high_pri = false;
+						}
+					}
+				}
+			}
+			
+			if ( 	file_info.getDownloaded() != file_info.getLength() ||
+					file_info.getFile( true ).length() != file_info.getLength()){
+				
+				all_complete = false;
+			}
+		}
+
+		// we can only open files if they are read-only
+
+		itemOpen.setEnabled(open);
+
+		// can't rename files for non-persistent downloads (e.g. shares) as these
+		// are managed "externally"
+
+		itemRenameOrRetarget.setEnabled(manager.isPersistent());
+		itemRename.setEnabled(manager.isPersistent());
+		itemRetarget.setEnabled(manager.isPersistent());
+		
+			// only enable for single files - people prolly don't expect a multi-selection to result
+			// in multiple shares, rather they would expect one share with the files they selected
+			// which we don't support
+		
+		itemPersonalShare.setEnabled( all_complete && dmi_array.length == 1 );
+		
+		itemSkipped.setEnabled(!all_skipped);
+
+		itemHigh.setEnabled(!all_high_pri);
+
+		itemNormal.setEnabled(!all_normal_pri);
+		
+		itemLow.setEnabled(!all_low_pri);
+
+		itemDelete.setEnabled(!all_compact);
+
+		itemOpen.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				for (int i = 0; i < data_sources.length; i++) {
+					DiskManagerFileInfo info = (DiskManagerFileInfo) data_sources[i];
+					if (info != null && info.getAccessMode() == DiskManagerFileInfo.READ) {
+						Utils.launch(info);
+					}
+				}
+			}
+		});
+
+		Listener rename_listener = new Listener() {
+			public void handleEvent(Event event) {
+				final boolean rename_it = ((Boolean) event.widget.getData("rename")).booleanValue();
+				final boolean retarget_it = ((Boolean) event.widget.getData("retarget")).booleanValue();
+				rename(tv, manager, data_sources, rename_it, retarget_it);
+			}
+		};
+
+		itemRenameOrRetarget.addListener(SWT.Selection, rename_listener);
+		itemRename.addListener(SWT.Selection, rename_listener);
+		itemRetarget.addListener(SWT.Selection, rename_listener);
+
+		itemPersonalShare.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				Map<String,String>	properties = new HashMap<String, String>();
+				
+				properties.put( ShareManager.PR_PERSONAL, "true" );
+				
+				for (int i = 0; i < dmi_array.length; i++) {
+
+					DiskManagerFileInfo file_info = dmi_array[i];
+				
+					File file = file_info.getFile( true );
+					
+					if ( file.isFile()){
+					
+						ShareUtils.shareFile( file.getAbsolutePath(), properties );
+						
+					}else if ( file.isDirectory()){
+						
+						ShareUtils.shareDir( file.getAbsolutePath(), properties );
+					}
+				}
+			}
+		});
+		
+		
+		Listener priorityListener = new Listener() {
+			public void handleEvent(Event event) {
+				final Object priority = event.widget.getData("Priority");
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						changePriority(priority, data_sources);
+					}
+				});
+			}
+		};
+
+		itemNumeric.addListener(SWT.Selection, priorityListener);
+		itemHigh.addListener(SWT.Selection, priorityListener);
+		itemNormal.addListener(SWT.Selection, priorityListener);
+		itemLow.addListener(SWT.Selection, priorityListener);
+		itemSkipped.addListener(SWT.Selection, priorityListener);
+		itemDelete.addListener(SWT.Selection, priorityListener);
+	}
+
+	public static void rename(final TableView tv, final DownloadManager not_used,
+			final Object[] datasources, boolean rename_it, boolean retarget_it) {
+		if (datasources.length == 0) {
+			return;
+		}
+
+		String save_dir = null;
+		if (!rename_it && retarget_it) {
+			save_dir = askForSaveDirectory((DiskManagerFileInfo) datasources[0]);
+			if (save_dir == null) {
+				return;
+			}
+		}
+
+		List<DownloadManager> pausedDownloads = new ArrayList<DownloadManager>(0);
+		boolean paused = false;
+		try {
+			for (int i = 0; i < datasources.length; i++) {
+				if (datasources[i] instanceof DownloadManager) {
+					AdvRenameWindow window = new AdvRenameWindow();
+					window.open((DownloadManager) datasources[i]);
+					continue;
+				}
+				if (!(datasources[i] instanceof DiskManagerFileInfo)) {
+					continue;
+				}
+				final DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) datasources[i];
+				File existing_file = fileInfo.getFile(true);
+				File f_target = null;
+				if (rename_it && retarget_it) {
+					String s_target = askForRetargetedFilename(fileInfo);
+					if (s_target != null)
+						f_target = new File(s_target);
+				} else if (rename_it) {
+					String s_target = askForRenameFilename(fileInfo);
+					if (s_target != null)
+						f_target = new File(existing_file.getParentFile(), s_target);
+				} else {
+					// Parent directory has changed.
+					f_target = new File(save_dir, existing_file.getName());
+				}
+
+				// So are we doing a rename?
+				// If the user has decided against it - abort the op.
+				if (f_target == null) {
+					return;
+				}
+
+				if (!paused) {
+					DownloadManager manager = fileInfo.getDownloadManager();
+					if (!pausedDownloads.contains(manager)) {
+						pausedDownloads.add(manager);
+					}
+					paused = manager.pause();
+				}
+
+				if (f_target.exists()) {
+
+					// Nothing to do.
+					if (f_target.equals(existing_file))
+						continue;
+
+					// A rewrite will occur, so we need to ask the user's permission.
+					else if (existing_file.exists() && !askCanOverwrite(existing_file))
+						continue;
+
+					// If we reach here, then it means we are doing a real move, but there is
+					// no existing file.
+				}
+
+				final File ff_target = f_target;
+				final TableRowCore row = tv == null ? null : tv.getRow(datasources[i]);
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						moveFile(fileInfo.getDownloadManager(), fileInfo, ff_target);
+						if (row != null) {
+							row.invalidate(true);
+						}
+					}
+				});
+			}
+		} finally {
+			for (DownloadManager manager : pausedDownloads) {
+				manager.resume();
+			}
+		}
+	}
+
+	public static void changePriority(Object type, final Object[] datasources) {
+
+		if (datasources == null || datasources.length == 0) {
+			return;
+		}
+
+		if (type == PRIORITY_NUMERIC) {
+			changePriorityManual(datasources);
+			return;
+		}
+
+		Map<DownloadManager, ArrayList<DiskManagerFileInfo>> mapDMtoDMFI = new HashMap<DownloadManager, ArrayList<DiskManagerFileInfo>>();
+
+		DiskManagerFileInfo[] file_infos = new DiskManagerFileInfo[datasources.length];
+		for (int i = 0; i < datasources.length; i++) {
+			file_infos[i] = (DiskManagerFileInfo) datasources[i];
+
+			DownloadManager dm = file_infos[i].getDownloadManager();
+			ArrayList<DiskManagerFileInfo> listFileInfos = mapDMtoDMFI.get(dm);
+			if (listFileInfos == null) {
+				listFileInfos = new ArrayList<DiskManagerFileInfo>(1);
+				mapDMtoDMFI.put(dm, listFileInfos);
+			}
+			listFileInfos.add(file_infos[i]);
+
+			if ( type == PRIORITY_NORMAL ){
+				
+				file_infos[i].setPriority( 0 );
+	
+			}else if (type == PRIORITY_HIGH ){
+				
+				file_infos[i].setPriority( 1 );
+				
+			}else if (type == PRIORITY_LOW ){
+				
+				file_infos[i].setPriority( -1 );
+			}
+		}
+		boolean skipped = (type == PRIORITY_SKIPPED || type == PRIORITY_DELETE);
+		boolean delete_action = (type == PRIORITY_DELETE);
+		for (DownloadManager dm : mapDMtoDMFI.keySet()) {
+			ArrayList<DiskManagerFileInfo> list = mapDMtoDMFI.get(dm);
+			DiskManagerFileInfo[] fileInfos = list.toArray(new DiskManagerFileInfo[0]);
+			boolean paused = setSkipped(dm, fileInfos, skipped, delete_action);
+
+			if (paused) {
+
+				dm.resume();
+			}
+		}
+	}
+
+	private static void changePriorityManual(final Object[] datasources) {
+
+		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+				"FilesView.dialog.priority.title",
+				"FilesView.dialog.priority.text");
+		entryWindow.prompt(new UIInputReceiverListener() {
+			public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+				if (!entryWindow.hasSubmittedInput()) {
+					return;
+				}
+				String sReturn = entryWindow.getSubmittedInput();
+				
+				if (sReturn == null)
+					return;
+				
+				int priority = 0;
+				try {
+					priority = Integer.valueOf(sReturn).intValue();
+				} catch (NumberFormatException er) {
+					
+					Debug.out( "Invalid priority: " + sReturn );
+					
+					new MessageBoxShell(SWT.ICON_ERROR | SWT.OK,
+							MessageText.getString("FilePriority.invalid.title"),
+							MessageText.getString("FilePriority.invalid.text", new String[]{ sReturn })).open(null);
+					
+					return;
+				}
+				
+				Map<DownloadManager, ArrayList<DiskManagerFileInfo>> mapDMtoDMFI = new HashMap<DownloadManager, ArrayList<DiskManagerFileInfo>>();
+
+				DiskManagerFileInfo[] file_infos = new DiskManagerFileInfo[datasources.length];
+				for (int i = 0; i < datasources.length; i++) {
+					file_infos[i] = (DiskManagerFileInfo) datasources[i];
+
+					DownloadManager dm = file_infos[i].getDownloadManager();
+					ArrayList<DiskManagerFileInfo> listFileInfos = mapDMtoDMFI.get(dm);
+					if (listFileInfos == null) {
+						listFileInfos = new ArrayList<DiskManagerFileInfo>(1);
+						mapDMtoDMFI.put(dm, listFileInfos);
+					}
+					listFileInfos.add(file_infos[i]);
+
+					file_infos[i].setPriority(priority);
+				}
+
+				for (DownloadManager dm : mapDMtoDMFI.keySet()) {
+					ArrayList<DiskManagerFileInfo> list = mapDMtoDMFI.get(dm);
+					DiskManagerFileInfo[] fileInfos = list.toArray(new DiskManagerFileInfo[0]);
+					boolean paused = setSkipped(dm, fileInfos, false, false);
+
+					if (paused) {
+
+						dm.resume();
+					}
+				}
+			}
+		});
+	}
+
+	private static String askForRenameFilename(DiskManagerFileInfo fileInfo) {
+		SimpleTextEntryWindow dialog = new SimpleTextEntryWindow(
+				"FilesView.rename.filename.title", "FilesView.rename.filename.text");
+		dialog.setPreenteredText(fileInfo.getFile(true).getName(), false); // false -> it's not "suggested", it's a previous value
+		dialog.allowEmptyInput(false);
+		dialog.prompt();
+		if (!dialog.hasSubmittedInput()) {
+			return null;
+		}
+		return dialog.getSubmittedInput();
+	}
+
+	private static String askForRetargetedFilename(DiskManagerFileInfo fileInfo) {
+		FileDialog fDialog = new FileDialog(Utils.findAnyShell(), SWT.SYSTEM_MODAL
+				| SWT.SAVE);
+		File existing_file = fileInfo.getFile(true);
+		fDialog.setFilterPath(existing_file.getParent());
+		fDialog.setFileName(existing_file.getName());
+		fDialog.setText(MessageText.getString("FilesView.rename.choose.path"));
+		return fDialog.open();
+	}
+
+	private static String askForSaveDirectory(DiskManagerFileInfo fileInfo) {
+		DirectoryDialog dDialog = new DirectoryDialog(Utils.findAnyShell(),
+				SWT.SYSTEM_MODAL | SWT.SAVE);
+		File current_dir = fileInfo.getFile(true).getParentFile();
+		dDialog.setFilterPath(current_dir.getPath());
+		dDialog.setText(MessageText.getString("FilesView.rename.choose.path.dir"));
+		return dDialog.open();
+	}
+
+	private static boolean askCanOverwrite(File file) {
+		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
+	private static void moveFile(final DownloadManager manager,
+			final DiskManagerFileInfo fileInfo, final File target) {
+
+		// this behaviour should be put further down in the core but I'd rather not
+		// do so close to release :(
+
+		manager.setUserData("is_changing_links", true);
+		try {
+			final boolean[] result = {
+				false
+			};
+
+			FileUtil.runAsTask(new AzureusCoreOperationTask() {
+				public void run(AzureusCoreOperation operation) {
+					result[0] = fileInfo.setLink(target);
+
+					manager.setUserData("is_changing_links", false);
+					if (!result[0]) {
+						new MessageBoxShell(SWT.ICON_ERROR | SWT.OK,
+								MessageText.getString("FilesView.rename.failed.title"),
+								MessageText.getString("FilesView.rename.failed.text")).open(null);
+					}
+				}
+			});
+		} catch (Exception e) {
+			manager.setUserData("is_changing_links", false);
+		}
+	}
+
+	// Returns true if it was paused here.
+	private static boolean setSkipped(DownloadManager manager,
+			DiskManagerFileInfo[] infos, boolean skipped, boolean delete_action) {
+		// if we're not managing the download then don't do anything other than
+		// change the file's priority
+
+		if (!manager.isPersistent()) {
+			for (int i = 0; i < infos.length; i++) {
+				infos[i].setSkipped(skipped);
+			}
+			return false;
+		}
+		int[] existing_storage_types = manager.getStorageType(infos);
+		int nbFiles = manager.getDiskManagerFileInfoSet().nbFiles();
+		boolean[] setLinear = new boolean[nbFiles];
+		boolean[] setCompact = new boolean[nbFiles];
+		boolean[] setReorder = new boolean[nbFiles];
+		boolean[] setReorderCompact = new boolean[nbFiles];
+		int compactCount = 0;
+		int linearCount = 0;
+		int reorderCount = 0;
+		int reorderCompactCount = 0;
+
+		if (infos.length > 1) {
+
+		}
+		// This should hopefully reduce the number of "exists" checks.
+		File save_location = manager.getAbsoluteSaveLocation();
+		boolean root_exists = save_location.isDirectory()
+				|| (infos.length <= 1 && save_location.exists());
+
+		boolean type_has_been_changed = false;
+		boolean requires_pausing = false;
+
+		for (int i = 0; i < infos.length; i++) {
+			int existing_storage_type = existing_storage_types[i];
+			int compact_target;
+			int non_compact_target;
+			if ( existing_storage_type == DiskManagerFileInfo.ST_COMPACT || existing_storage_type == DiskManagerFileInfo.ST_LINEAR ){
+				compact_target 		= DiskManagerFileInfo.ST_COMPACT;
+				non_compact_target	= DiskManagerFileInfo.ST_LINEAR;
+			}else{
+				compact_target 		= DiskManagerFileInfo.ST_REORDER_COMPACT;
+				non_compact_target	= DiskManagerFileInfo.ST_REORDER;
+			}
+			int new_storage_type;
+			if (skipped) {
+
+				// Check to see if the file exists, but try to avoid doing an
+				// actual disk check if possible.
+				File existing_file = infos[i].getFile(true);
+
+				// Avoid performing existing_file.exists if we know that it is meant
+				// to reside in the default save location and that location does not
+				// exist.
+				boolean perform_check;
+				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) {
+						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", false, null);
+						mb.setLeftImage(SWT.ICON_WARNING);
+						mb.open(null);
+
+						boolean wants_to_delete = mb.waitUntilClosed() == SWT.OK;
+
+						if ( wants_to_delete ){
+							
+							new_storage_type = compact_target;
+							
+						}else{
+							
+							new_storage_type = non_compact_target;
+						}
+					}else{
+						
+						new_storage_type = non_compact_target;
+					}
+				}
+				// File does not exist.
+				else {
+					new_storage_type = compact_target;
+				}
+			}else{
+				new_storage_type = non_compact_target;
+			}
+
+			boolean has_changed = existing_storage_type != new_storage_type;
+			type_has_been_changed |= has_changed;
+			requires_pausing |= (has_changed && ( new_storage_type == DiskManagerFileInfo.ST_COMPACT || new_storage_type == DiskManagerFileInfo.ST_REORDER_COMPACT ));
+
+			type_has_been_changed = existing_storage_type != new_storage_type;
+
+			if (new_storage_type == DiskManagerFileInfo.ST_COMPACT) {
+				setCompact[infos[i].getIndex()] = true;
+				compactCount++;
+			} else if (new_storage_type == DiskManagerFileInfo.ST_LINEAR) {
+				setLinear[infos[i].getIndex()] = true;
+				linearCount++;
+			} else if (new_storage_type == DiskManagerFileInfo.ST_REORDER) {
+				setReorder[infos[i].getIndex()] = true;
+				reorderCount++;
+			} else if (new_storage_type == DiskManagerFileInfo.ST_REORDER_COMPACT) {
+				setReorderCompact[infos[i].getIndex()] = true;
+				reorderCompactCount++;
+			}
+		}
+
+		boolean ok = true;
+		boolean paused = false;
+		if (type_has_been_changed) {
+			if (requires_pausing)
+				paused = manager.pause();
+			if (linearCount > 0)
+				ok &= Arrays.equals(
+						setLinear,
+						manager.getDiskManagerFileInfoSet().setStorageTypes(setLinear,
+								DiskManagerFileInfo.ST_LINEAR));
+			if (compactCount > 0)
+				ok &= Arrays.equals(
+						setCompact,
+						manager.getDiskManagerFileInfoSet().setStorageTypes(setCompact,
+								DiskManagerFileInfo.ST_COMPACT));
+			if (reorderCount > 0)
+				ok &= Arrays.equals(
+						setReorder,
+						manager.getDiskManagerFileInfoSet().setStorageTypes(setReorder,
+								DiskManagerFileInfo.ST_REORDER));
+			if (reorderCompactCount > 0)
+				ok &= Arrays.equals(
+						setReorderCompact,
+						manager.getDiskManagerFileInfoSet().setStorageTypes(setReorderCompact,
+								DiskManagerFileInfo.ST_REORDER_COMPACT));
+		}
+
+		if (ok) {
+			for (int i = 0; i < infos.length; i++) {
+				infos[i].setSkipped(skipped);
+			}
+		}
+
+		return paused;
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/GeneralView.java b/org/gudy/azureus2/ui/swt/views/GeneralView.java
index 8edc31d..60c8952 100644
--- a/org/gudy/azureus2/ui/swt/views/GeneralView.java
+++ b/org/gudy/azureus2/ui/swt/views/GeneralView.java
@@ -20,24 +20,16 @@
  */
 package org.gudy.azureus2.ui.swt.views;
 
-import java.net.URL;
 import java.text.DecimalFormat;
-import java.util.Iterator;
-import java.util.List;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.Clipboard;
 import org.eclipse.swt.dnd.TextTransfer;
 import org.eclipse.swt.dnd.Transfer;
-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.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
+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.Rectangle;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -52,23 +44,23 @@ import org.gudy.azureus2.core3.download.DownloadManagerStats;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 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.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.TorrentUtil;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.BufferedLabel;
-import org.gudy.azureus2.ui.swt.components.BufferedTruncatedLabel;
-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.mainwindow.Cursors;
-import org.gudy.azureus2.ui.swt.maketorrent.MultiTrackerEditor;
-import org.gudy.azureus2.ui.swt.maketorrent.TrackerEditorListener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
-import com.aelitis.azureus.core.util.AZ3Functions;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.util.MapUtils;
 
 /**
  * View of General information on the torrent
@@ -76,9 +68,12 @@ import com.aelitis.azureus.core.util.AZ3Functions;
  * @author Olivier
  * 
  */
-public class GeneralView extends AbstractIView implements ParameterListener,
-		ObfusticateImage
+public class GeneralView
+	implements ParameterListener, UISWTViewCoreEventListener, UIPluginViewToolBarListener
 {
+	public static final String MSGID_PREFIX = "GeneralView";
+
+	protected AEMonitor this_mon 	= new AEMonitor( MSGID_PREFIX );
 
   private Display display;
   private DownloadManager manager = null;
@@ -115,12 +110,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
   BufferedLabel fileSize;
   BufferedLabel saveIn;
   BufferedLabel hash;
-  BufferedTruncatedLabel tracker_status;
-  BufferedLabel trackerUpdateIn;
-  Menu menuTracker;
-  MenuItem itemSelect;
-  
-  BufferedTruncatedLabel trackerUrlValue;
   
   BufferedLabel pieceNumber;
   BufferedLabel pieceSize;
@@ -130,11 +119,11 @@ public class GeneralView extends AbstractIView implements ParameterListener,
   Control user_comment;
   BufferedLabel hashFails;
   BufferedLabel shareRatio;
-  Button		updateButton;
   
   private int graphicsUpdate = COConfigurationManager.getIntParameter("Graphics Update");
 
   private Composite parent;
+	private UISWTView swtView;
 
   /**
    * Initialize GeneralView
@@ -150,12 +139,13 @@ public class GeneralView extends AbstractIView implements ParameterListener,
 		else
 			manager = (DownloadManager)newDataSource;
 
-		refreshInfo();
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_refreshInfo();
+			}
+		});
 	}
 
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#initialize(org.eclipse.swt.widgets.Composite)
-   */
   public void initialize(Composite composite) {
   	parent = composite;
 
@@ -175,13 +165,13 @@ public class GeneralView extends AbstractIView implements ParameterListener,
 
     Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
-				refreshInfo();
+				swt_refreshInfo();
 			}
 		});
     COConfigurationManager.addParameterListener("Graphics Update", this);
   }
   
-  private void refreshInfo() {
+  private void swt_refreshInfo() {
   	if (manager == null || parent == null)
   		return;
   	
@@ -211,7 +201,7 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     gridData.heightHint = 25;
     piecesImage.setLayoutData(gridData);
 
-    piecesPercent = new BufferedLabel(gFile, SWT.RIGHT);
+    piecesPercent = new BufferedLabel(gFile, SWT.RIGHT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
     gridData.widthHint = 50;
     piecesPercent.setLayoutData(gridData);
@@ -228,7 +218,7 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     availabilityImage.setLayoutData(gridData);
     Messages.setLanguageText(availabilityImage, "GeneralView.label.status.pieces_available.tooltip");
 
-    availabilityPercent = new BufferedLabel(gFile, SWT.RIGHT);
+    availabilityPercent = new BufferedLabel(gFile, SWT.RIGHT | SWT.DOUBLE_BUFFERED );
     gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
     gridData.widthHint = 50;
     availabilityPercent.setLayoutData(gridData);
@@ -245,28 +235,28 @@ public class GeneralView extends AbstractIView implements ParameterListener,
 
     Label label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.timeelapsed"); //$NON-NLS-1$
-    timeElapsed = new BufferedLabel(gTransfer, SWT.LEFT);
+    timeElapsed = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED );
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     timeElapsed.setLayoutData(gridData);
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.remaining"); //$NON-NLS-1$
-    timeRemaining = new BufferedLabel(gTransfer, SWT.LEFT);
+    timeRemaining = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     timeRemaining.setLayoutData(gridData);
     label = new Label(gTransfer, SWT.LEFT); //$NON-NLS-1$
     Messages.setLanguageText(label, "GeneralView.label.shareRatio");
-    shareRatio = new BufferedLabel(gTransfer, SWT.LEFT); //$NON-NLS-1$
+    shareRatio = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED); //$NON-NLS-1$
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     shareRatio.setLayoutData(gridData);
 
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.downloaded"); //$NON-NLS-1$
-    download = new BufferedLabel(gTransfer, SWT.LEFT);
+    download = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     download.setLayoutData(gridData);
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.downloadspeed"); //$NON-NLS-1$
-    downloadSpeed = new BufferedLabel(gTransfer, SWT.LEFT);
+    downloadSpeed = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     downloadSpeed.setLayoutData(gridData);
     label = new Label(gTransfer, SWT.LEFT); //$NON-NLS-1$
@@ -277,12 +267,12 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.uploaded"); //$NON-NLS-1$
-    upload = new BufferedLabel(gTransfer, SWT.LEFT);
+    upload = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED );
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     upload.setLayoutData(gridData);    
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.uploadspeed"); //$NON-NLS-1$
-    uploadSpeed = new BufferedLabel(gTransfer, SWT.LEFT);
+    uploadSpeed = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     gridData.horizontalSpan = 3;
     uploadSpeed.setLayoutData(gridData);
@@ -311,20 +301,20 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.totalspeed"); 
-    totalSpeed = new BufferedLabel(gTransfer, SWT.LEFT);
+    totalSpeed = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     totalSpeed.setLayoutData(gridData);
     
     
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.swarm_average_completion"); 
-    ave_completion = new BufferedLabel(gTransfer, SWT.LEFT);
+    ave_completion = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     ave_completion.setLayoutData(gridData);
     
     label = new Label(gTransfer, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.distributedCopies"); 
-    distributedCopies = new BufferedLabel(gTransfer, SWT.LEFT);
+    distributedCopies = new BufferedLabel(gTransfer, SWT.LEFT | SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     distributedCopies.setLayoutData(gridData);
     
@@ -356,6 +346,7 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     Messages.setLanguageText(label, "GeneralView.label.savein"); //$NON-NLS-1$
     saveIn = new BufferedLabel(gInfo, SWT.LEFT);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 3;
     saveIn.setLayoutData(gridData);
 
     label = new Label(gInfo, SWT.LEFT);
@@ -378,7 +369,7 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     hash.setLayoutData(gridData);
     	// click on hash -> copy to clipboard
-    hash.setCursor(Cursors.handCursor);
+    hash.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
     hash.setForeground(Colors.blue);
     label.addMouseListener(new MouseAdapter() {
     	public void mouseDoubleClick(MouseEvent arg0) {
@@ -405,158 +396,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     	}
     });
     
-    label = new Label(gInfo, SWT.LEFT);
-    Messages.setLanguageText(label, "GeneralView.label.trackerurl"); //$NON-NLS-1$
-    label.setCursor(Cursors.handCursor);
-    label.setForeground(Colors.blue);
-    label.addMouseListener(new MouseAdapter() {
-      public void mouseDoubleClick(MouseEvent arg0) {
-        String announce = trackerUrlValue.getText();
-        if(announce != null && announce.length() != 0)
-          new Clipboard(display).setContents(new Object[] {announce}, new Transfer[] {TextTransfer.getInstance()});
-      }
-      public void mouseDown(MouseEvent arg0) {
-        String announce = trackerUrlValue.getText();
-        if(announce != null && announce.length() != 0)
-          new Clipboard(display).setContents(new Object[] {announce}, new Transfer[] {TextTransfer.getInstance()});
-      }
-    });
-    
-    menuTracker = new Menu(genComposite.getShell(),SWT.POP_UP);
-    itemSelect = new MenuItem(menuTracker,SWT.CASCADE);
-    Messages.setLanguageText(itemSelect, "GeneralView.menu.selectTracker");
-    MenuItem itemEdit = new MenuItem(menuTracker,SWT.NULL);
-    Messages.setLanguageText(itemEdit, "MyTorrentsView.menu.editTracker");
-     
-    itemEdit.addListener(
-    	SWT.Selection,
-    	new Listener()
-    	{
-    		public void 
-    		handleEvent(Event e)
-    		{
-    			final TOTorrent	torrent = manager.getTorrent();
-    		
-    			if ( torrent == null ){
-    				return;
-    			}
-    			
-	    		List	group = TorrentUtils.announceGroupsToList( torrent );
-	    		
-	    		new MultiTrackerEditor(null,group,
-	    				new TrackerEditorListener()
-	    				{
-	    					public void
-	    					trackersChanged(
-	    							String	str,
-									String	str2,
-									List	_group )
-	    					{
-	    						TorrentUtils.listToAnnounceGroups( _group, torrent );
-	    						
-	    						try{
-	    							TorrentUtils.writeToFile( torrent );
-	    						}catch( Throwable e2 ){
-	    							
-	    							Debug.printStackTrace( e2 );
-	    						}
-	    						
-	    						TRTrackerAnnouncer	tc = manager.getTrackerClient();
-	    						
-	    						if ( tc != null ){
-	    							
-	    							tc.resetTrackerUrl( true );
-	    						}
-	    					}
-	    				}, true);	
-    		}  		
-    	});
-    
-    final Listener menuListener = new Listener() 
-    {
-      public void 
-      handleEvent(Event e)
-      {
-         if( e.widget instanceof MenuItem) {
-        	
-          String text = ((MenuItem)e.widget).getText();
-                   
-          	
-          TOTorrent	torrent = manager.getTorrent();
-          	
-          TorrentUtils.announceGroupsSetFirst(torrent,text);   
-          	
-          try{
-          	TorrentUtils.writeToFile(torrent);
-          	
-          }catch( TOTorrentException f){
-          		
-          	Debug.printStackTrace( f );
-          }
-          	
-          TRTrackerAnnouncer	tc = manager.getTrackerClient();
-          	
-          if ( tc != null ){
-          		
-          	tc.resetTrackerUrl( false );
-          }    	
-        }
-      }
-    };
-    
-    menuTracker.addListener(SWT.Show,new Listener() {
-      public void handleEvent(Event e) {
-    		Menu menuSelect = itemSelect.getMenu();
-    		if(menuSelect != null && ! menuSelect.isDisposed()) {
-    		  menuSelect.dispose();
-    		}
-    		if(manager == null || genComposite == null || genComposite.isDisposed())
-    		  return;
-     		List groups = TorrentUtils.announceGroupsToList(manager.getTorrent());        		
-    		menuSelect = new Menu(genComposite.getShell(),SWT.DROP_DOWN);
-    		itemSelect.setMenu(menuSelect);
-    		Iterator iterGroups = groups.iterator();
-    		while(iterGroups.hasNext()) {
-    		  List trackers = (List) iterGroups.next();
-    		  MenuItem menuItem = new MenuItem(menuSelect,SWT.CASCADE);
-    		  Messages.setLanguageText(menuItem,"wizard.multitracker.group");
-    		  Menu menu = new Menu(genComposite.getShell(),SWT.DROP_DOWN);
-    		  menuItem.setMenu(menu);
-    		  Iterator iterTrackers = trackers.iterator();
-    		  while(iterTrackers.hasNext()) {
-    		    String url = (String) iterTrackers.next();
-    		    MenuItem menuItemTracker = new MenuItem(menu,SWT.CASCADE);
-    		    menuItemTracker.setText(url);
-    		    menuItemTracker.addListener(SWT.Selection,menuListener);
-    		  }
-    		}
-      }
-    });
-    
-    trackerUrlValue = new BufferedTruncatedLabel(gInfo, SWT.LEFT,70);        
-    
-    trackerUrlValue.addMouseListener(new MouseAdapter() {
-			public void mouseDown(MouseEvent event) {
-				if (event.button == 3
-						|| (event.button == 1 && event.stateMask == SWT.CONTROL)) {
-					menuTracker.setVisible(true);
-				} else if (event.button == 1) {
-					String url = trackerUrlValue.getText();
-					if (url.startsWith("http://") || url.startsWith("https://")) {
-						int pos = -1;
-						if ((pos = url.indexOf("/announce")) != -1) {
-							url = url.substring(0, pos + 1);
-						}
-						Utils.launch(url);
-					}
-				}
-			}
-		});
-    
-    
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 1;
-    trackerUrlValue.setLayoutData(gridData);
     
     label = new Label(gInfo, SWT.LEFT);
     Messages.setLanguageText(label, "GeneralView.label.size");
@@ -583,61 +422,8 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     label.setLayoutData(gridData);
     
     
-    
     label = new Label(gInfo, SWT.LEFT);
-    Messages.setLanguageText(label, "GeneralView.label.tracker");
-    tracker_status = new BufferedTruncatedLabel(gInfo, SWT.LEFT,150);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    tracker_status.setLayoutData(gridData);
-    
-    tracker_status.addMouseListener(new MouseAdapter() {
-		public void mouseDown(MouseEvent event) {
-			if ( event.button == 1 ){
-				if ( manager.isUnauthorisedOnTracker()){
-					
-					AZ3Functions.provider az3 = AZ3Functions.getProvider();
-					
-					if ( az3 != null && az3.canShowCDP( manager )){
-						
-						az3.showCDP( manager, "tracker.unauth" );
-					}
-				}
-			}
-		}
-	});
-    
-    updateButton = new Button(gInfo, SWT.PUSH);
-    Messages.setLanguageText(updateButton, "GeneralView.label.trackerurlupdate");
-    gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
-    gridData.verticalSpan = 2;
-    gridData.horizontalSpan = 2;
-    updateButton.setLayoutData(gridData);
-    updateButton.addSelectionListener(new SelectionAdapter()
-    {
-    	public void widgetSelected(SelectionEvent event) {
-    		manager.requestTrackerAnnounce(false);
-    	}
-    });
-        
-    label = new Label(gInfo, SWT.LEFT);
-    Messages.setLanguageText(label, "GeneralView.label.updatein");
-    trackerUpdateIn = new BufferedLabel(gInfo, SWT.LEFT);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    trackerUpdateIn.setLayoutData(gridData);
-    
-
-	// empty row
-    
-    label = new Label(gInfo, SWT.LEFT);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 4;
-    label.setLayoutData(gridData);
-    
-    
-
-    
-    label = new Label(gInfo, SWT.LEFT);
-    label.setCursor(Cursors.handCursor);
+    label.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
     label.setForeground(Colors.blue);
     Messages.setLanguageText(label, "GeneralView.label.user_comment");
 
@@ -700,26 +486,14 @@ public class GeneralView extends AbstractIView implements ParameterListener,
       }
     });
 
-    genComposite.addDisposeListener(new DisposeListener() {
-    	public void widgetDisposed(DisposeEvent e) {
-    		menuTracker.dispose();
-    	}
-    });
-    
     genComposite.layout();
     //Utils.changeBackgroundComposite(genComposite,MainWindow.getWindow().getBackground());
   }
 
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#getComposite()
-   */
   public Composite getComposite() {
     return genComposite;
   }
 
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#refresh()
-   */
   public void refresh() {
     if(gFile == null || gFile.isDisposed() || manager == null)
       return;
@@ -834,8 +608,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
       	distributedCopies
     );
       
-    setTracker();
-    
     TOTorrent	torrent = manager.getTorrent();
     
     String creation_date = DisplayFormatters.formatDate(manager.getTorrentCreationDate()*1000);
@@ -871,9 +643,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     }
   }
 
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#delete()
-   */
   public void delete() {
 	if (aImage != null)
 		aImage.dispose();
@@ -885,15 +654,8 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     COConfigurationManager.removeParameterListener("Graphics Update", this);
   }
 
-  public String getData() {
-    return "GeneralView.title.short"; //$NON-NLS-1$
-  }
-
-  /* (non-Javadoc)
-   * @see org.gudy.azureus2.ui.swt.IView#getFullTitle()
-   */
-  public String getFullTitle() {
-    return MessageText.getString("GeneralView.title.full"); //$NON-NLS-1$
+  private String getFullTitle() {
+    return MessageText.getString(MSGID_PREFIX + ".title.full");
   }
 
   private void updateAvailability() {
@@ -1212,96 +974,6 @@ public class GeneralView extends AbstractIView implements ParameterListener,
 	shareRatio.setText( share_ratio);     
   }
 
-  private void setTracker(){
-    if (display == null || display.isDisposed())
-      return;
-    
-    String	status 	= manager.getTrackerStatus();
-    int		time	= manager.getTrackerTime();
-     
-    TRTrackerAnnouncer	trackerClient = manager.getTrackerClient();
-	
-	tracker_status.setText( status );
-		
-	boolean show_cdp_link = false;
-	
-	if ( manager.isUnauthorisedOnTracker()){
-		
-		AZ3Functions.provider az3 = AZ3Functions.getProvider();
-		
-		show_cdp_link = az3 != null && az3.canShowCDP( manager );	
-	}
-	
-	if ( show_cdp_link ){
-		tracker_status.setForeground(Colors.colorError);
-		tracker_status.setCursor(Cursors.handCursor);
-	}else{
-		tracker_status.setForeground(null);
-		tracker_status.setCursor(null);
-	}
-	
-	if ( time < 0 ){
-		
-		trackerUpdateIn.setText( MessageText.getString("GeneralView.label.updatein.querying"));
-		
-	}else{
- 	    
-		trackerUpdateIn.setText(  TimeFormatter.formatColon( time )); 
-	}
-    
-    boolean	update_state;
-    
-    String trackerURL = null;
-    
-    if ( trackerClient != null ){
-    	
-    	URL	temp = trackerClient.getTrackerURL();
-    	
-    	if ( temp != null ){
-    		
-    		trackerURL	= temp.toString();
-    	}
-    }
-    
-    if ( trackerURL == null ){
-    	
-       	TOTorrent	torrent = manager.getTorrent();
-       	
-       	if( torrent != null ){
-       		
-       		trackerURL = torrent.getAnnounceURL().toString();
-       	}
-    }
-    
-    if ( trackerURL != null ){
-    	
-		trackerUrlValue.setText( trackerURL );
-				
-		if((trackerURL.startsWith("http://")||trackerURL.startsWith("https://"))) {
-		  trackerUrlValue.setForeground(Colors.blue);
-		  trackerUrlValue.setCursor(Cursors.handCursor);
-		  Messages.setLanguageText(trackerUrlValue.getWidget(), "GeneralView.label.trackerurlopen.tooltip", true);
-		} else {
-		  trackerUrlValue.setForeground(null);
-		  trackerUrlValue.setCursor(null);
-		  Messages.setLanguageText(trackerUrlValue.getWidget(), null);	
-		  trackerUrlValue.setToolTipText(null);
-		}
-   	}
-    
-    if ( trackerClient != null ){
-    	
-    	update_state = ((SystemTime.getCurrentTime()/1000 - trackerClient.getLastUpdateTime() >= TRTrackerAnnouncer.REFRESH_MINIMUM_SECS ));
-    	
-    }else{
-    	update_state = false;
-    }
-    
-    if ( updateButton.getEnabled() != update_state ){
-    
-    	updateButton.setEnabled( update_state );
-    }
-  }
 
   private void setInfos(
     final String _fileName,
@@ -1376,11 +1048,77 @@ public class GeneralView extends AbstractIView implements ParameterListener,
     graphicsUpdate = COConfigurationManager.getIntParameter("Graphics Update");
   }
 
-	public Image obfusticatedImage(Image image, Point shellOffset) {
+	private Image obfusticatedImage(Image image) {
 		UIDebugGenerator.obfusticateArea(image, (Control) fileName.getWidget(),
-				shellOffset, manager.toString());
+				manager.toString());
 		UIDebugGenerator.obfusticateArea(image, (Control) saveIn.getWidget(),
-				shellOffset, Debug.secretFileName(saveIn.getText()));
+				Debug.secretFileName(saveIn.getText()));
 		return image;
 }
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+      	swtView.setToolBarListener(this);
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	String id = "DMDetails_General";
+      	if (manager != null) {
+      		if (manager.getTorrent() != null) {
+  					id += "." + manager.getInternalName();
+      		} else {
+      			id += ":" + manager.getSize();
+      		}
+      	}
+  
+      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+      		new SelectedContent(manager)
+      	});
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+        
+      case UISWTViewEvent.TYPE_OBFUSCATE:
+				Object data = event.getData();
+				if (data instanceof Map) {
+					obfusticatedImage((Image) MapUtils.getMapObject((Map) data, "image",
+							null, Image.class));
+					((Map) data).put("obfuscateSideBar", true);
+				}
+      	break;
+    }
+
+    return true;
+  }
+
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		return( ViewUtils.toolBarItemActivated(manager, item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(manager, list);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/IView.java b/org/gudy/azureus2/ui/swt/views/IView.java
deleted file mode 100644
index b3dd95c..0000000
--- a/org/gudy/azureus2/ui/swt/views/IView.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Created on 29 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.views;
-
-import org.eclipse.swt.widgets.Composite;
-import org.gudy.azureus2.core3.util.IndentWriter;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
-import org.gudy.azureus2.ui.swt.mainwindow.Refreshable;
-
-/**
- * @author Olivier
- */
-
-// XXX This class is used by plugins.  Don't remove any functions from it!
-public interface IView extends IconBarEnabler, Refreshable {
-  /**
-   * This method is called when the view is instanciated, it should initialize all GUI
-   * components. Must NOT be blocking, or it'll freeze the whole GUI.
-   * Caller is the GUI Thread.
-   * 
-   * @param composite the parent composite. Each view should create a child 
-   *         composite, and then use this child composite to add all elements
-   *         to.
-   *         
-   * @note It's possible that the view may be created, but never initialize'd.
-   *        In these cases, delete will still be called.
-   */
-  public void initialize(Composite composite);
-  
-  /**
-   * This method is called after initialize so that the Tab is set its control
-   * Caller is the GUI Thread.
-   * @return the Composite that should be set as the control for the Tab item
-   */
-  public Composite getComposite();
-  
-  /**
-   * This method is caled when the view is destroyed.
-   * Each color instanciated, images and such things should be disposed.
-   * The caller is the GUI thread.
-   *
-   */
-  public void delete();
-  
-  /**
-   * Data 'could' store a key to a language file, in order to support multi-language titles
-   * @return a String which is the key of this view title.
-   */
-  public String getData();
-  
-  /**
-   * Called in order to set / update the short title of this view.  When the 
-   * view is being displayed in a tab, the short title is used for the tab's
-   * text
-   * 
-   * @return A short title for the view
-   */
-  public String getShortTitle();
-  
-  /**
-   * Called in order to set / update the title of this View.  When the view
-   * is being displayed in a tab, the full title is used for the tooltip.
-   * 
-   * @return the full title for the view
-   */
-  public String getFullTitle();
-  
-  /**
-   * Called when the language needs updating
-   *
-   */
-  public void updateLanguage();
-  
-  
-  /**
-   * Called when Azureus generates Diagnostics.
-   * Write any diagnostic information you want to the writer. 
-   * 
-   * @param writer
-   * @since 2.3.0.4
-   */
-  // XXX Introduced IndentWriter to plugins..
-  public void
-  generateDiagnostics(
-		IndentWriter	writer );
-  
-
-  /**
-   * Called when the selected dataSource has changed.
-   * If this view is dependent upon a selected datasource, implement this 
-   * function and update your view.
-   * 
-   * @param newDataSource null if no datasource is selected.  May be an array
-   *                       of Object[] if multiple dataSources are selected
-   * @since 2.3.0.7
-   */
-  public void dataSourceChanged(Object newDataSource);
-}
diff --git a/org/gudy/azureus2/ui/swt/views/IViewAlwaysInitialize.java b/org/gudy/azureus2/ui/swt/views/IViewAlwaysInitialize.java
new file mode 100644
index 0000000..d7c1e2c
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/IViewAlwaysInitialize.java
@@ -0,0 +1,29 @@
+/**
+ * Created on Mar 30, 2010
+ *
+ * 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;
+
+/**
+ * @author TuxPaper
+ * @created Mar 30, 2010
+ *
+ */
+public interface IViewAlwaysInitialize
+{
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/IViewExtension.java b/org/gudy/azureus2/ui/swt/views/IViewExtension.java
deleted file mode 100644
index 2d3bc4d..0000000
--- a/org/gudy/azureus2/ui/swt/views/IViewExtension.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Created on Jul 19, 2006 3:46:25 AM
- * 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 org.gudy.azureus2.ui.swt.views;
-
-import org.eclipse.swt.widgets.Menu;
-
-/**
- * IView extensions (not added to IView because that's used in the Plugin
- * Interface
- * 
- * @author TuxPaper
- * @created Jul 19, 2006
- *
- */
-public interface IViewExtension
-{
-	public Menu getPrivateMenu();
-	
-	public void viewActivated();
-	
-	public void viewDeactivated();
-}
diff --git a/org/gudy/azureus2/ui/swt/views/LoggerView.java b/org/gudy/azureus2/ui/swt/views/LoggerView.java
index d101e63..2128013 100644
--- a/org/gudy/azureus2/ui/swt/views/LoggerView.java
+++ b/org/gudy/azureus2/ui/swt/views/LoggerView.java
@@ -48,14 +48,18 @@ 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.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 /**
  * @author TuxPaper
  *
  * @since 2.3.0.5
  */
-public class LoggerView extends AbstractIView implements ILogEventListener,
-		ParameterListener {
+public class LoggerView
+	implements ILogEventListener, ParameterListener, UISWTViewCoreEventListener
+{
 	//private final static LogIDs LOGID = LogIDs.GUI;
 
 	private static final int COLOR_INFO = 0;
@@ -74,6 +78,8 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 
 	private static final FieldPosition formatPos;
 
+	public static final String MSGID_PREFIX = "ConsoleView";
+
 	private Display display;
 
 	private Composite panel;
@@ -85,7 +91,7 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 	private Object[] filter = null;
 
 	// LinkedList is better for removing entries when full
-	private LinkedList buffer = new LinkedList();
+	private LinkedList<LogEvent> buffer = new LinkedList<LogEvent>();
 
 	private boolean bPaused = false;
 
@@ -104,6 +110,8 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 
 	private boolean stopOnNull = false;
 
+	private UISWTView swtView;
+
 	static {
 		dateFormatter = new SimpleDateFormat("[HH:mm:ss.SSS] ");
 		formatPos = new FieldPosition(0);
@@ -121,17 +129,14 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 		this.stopOnNull = stopOnNull;
 	}
 
-	public LoggerView(java.util.List initialList) {
+	public LoggerView(java.util.List<? extends LogEvent> initialList) {
 		this();
 		if (initialList != null)
 			buffer.addAll(initialList);
 		setEnabled(true);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.IView#initialize(org.eclipse.swt.widgets.Composite)
-	 */
-	public void initialize(Composite composite) {
+	private void initialize(Composite composite) {
 		display = composite.getDisplay();
 
 		Colors.getInstance().addColorsChangedListener(this);
@@ -454,17 +459,11 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.IView#getComposite()
-	 */
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return panel;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.IView#refresh()
-	 */
-	public void refresh() {
+	private void refresh() {
 		if (bPaused)
 			return;
 		
@@ -474,7 +473,7 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 
 			for (int i = 0; i < buffer.size(); i++) {
 				try {
-					LogEvent event = (LogEvent) buffer.get(i);
+					LogEvent event = buffer.get(i);
 
 					int nbLinesBefore = consoleText.getLineCount();
 					if (nbLinesBefore > MAX_LINES)
@@ -542,27 +541,17 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.IView#delete()
-	 */
-	public void delete() {
+	private void delete() {
 		Logger.removeListener(this);
 		if (panel != null && !panel.isDisposed())
 			panel.dispose();
 		Colors.getInstance().removeColorsChangedListener(this);
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.IView#getFullTitle()
-	 */
-	public String getFullTitle() {
+	private String getFullTitle() {
 		return MessageText.getString("ConsoleView.title.full");
 	}
 
-	public String getData() {
-		return "ConsoleView.title.short";
-	}
-
 	// @see org.gudy.azureus2.core3.logging.ILogEventListener#log(org.gudy.azureus2.core3.logging.LogEvent)
 	public synchronized void log(final LogEvent event) {
 		if (display == null || display.isDisposed())
@@ -627,7 +616,9 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				consoleText.setText("");
+				if (consoleText != null && !consoleText.isDisposed()) {
+					consoleText.setText("");
+				}
 			}
 		});
 	}
@@ -650,7 +641,7 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 	}
 
 	// TODO: Support multiple selection
-	public void dataSourceChanged(Object newDataSource) {
+	private void dataSourceChanged(Object newDataSource) {
 		if (newDataSource == null) {
 			if (stopOnNull) {
 				setEnabled(false);
@@ -678,6 +669,7 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 		return 0;
 	}
 
+	/*
 	private int indexToLogType(int index) {
 		switch (index) {
 			case 0:
@@ -689,6 +681,7 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 		}
 		return LogEvent.LT_INFORMATION;
 	}
+	*/
 
 	public void parameterChanged(String parameterName) {
 		if (parameterName.startsWith("Color")) {
@@ -720,4 +713,39 @@ public class LoggerView extends AbstractIView implements ILogEventListener,
 			});
 		}
 	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/ManagerView.java b/org/gudy/azureus2/ui/swt/views/ManagerView.java
index 7308ac9..4db7d63 100644
--- a/org/gudy/azureus2/ui/swt/views/ManagerView.java
+++ b/org/gudy/azureus2/ui/swt/views/ManagerView.java
@@ -26,16 +26,13 @@ import java.util.Map;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CTabFolder;
 import org.eclipse.swt.custom.CTabItem;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-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.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
 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.download.DownloadManagerListener;
 import org.gudy.azureus2.core3.global.GlobalManager;
@@ -43,29 +40,38 @@ import org.gudy.azureus2.core3.global.GlobalManagerAdapter;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.download.DownloadException;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl;
 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
-import org.gudy.azureus2.ui.swt.IconBarEnabler;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
 import org.gudy.azureus2.ui.swt.debug.ObfusticateTab;
+import org.gudy.azureus2.ui.swt.mainwindow.MenuFactory;
 import org.gudy.azureus2.ui.swt.plugins.*;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
-import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
-import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance.UISWTViewEventListenerWrapper;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 
 import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarEnabler;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.common.table.TableView;
+import com.aelitis.azureus.ui.common.table.TableViewFilterCheck;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
-import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo2;
 import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfoManager;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-
-import org.gudy.azureus2.plugins.download.DownloadException;
+import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT;
+import com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
 /**
  * Torrent download view, consisting of several information tabs
@@ -74,20 +80,29 @@ import org.gudy.azureus2.plugins.download.DownloadException;
  * 
  */
 public class ManagerView
-	implements DownloadManagerListener, ObfusticateTab, ObfusticateImage,
-	ViewTitleInfo, UISWTViewCoreEventListener, IconBarEnabler, UIUpdatable
+	implements DownloadManagerListener, ObfusticateTab,
+	ViewTitleInfo2, UISWTViewCoreEventListener, UIUpdatable, UIPluginViewToolBarListener
 {
 
+	private static boolean registeredCoreSubViews = false;
   private DownloadManager 	manager;
   private CTabFolder folder;
-  private ArrayList tabViews = new ArrayList();
+  private ArrayList<UISWTViewCore> tabViews = new ArrayList<UISWTViewCore>();
   
   int lastCompleted = -1;
 	private UISWTView swtView;
 	private GlobalManagerAdapter gmListener;
 	private Composite parent;
-	protected IView activeView;
+	protected UISWTViewCore activeView;
   
+	private final int 	TOP_BAR_HEIGHT = 30;
+	private Label		header_label;
+	private Font		header_font;
+	private Text		txtFilter;
+	private Control		txtControl;
+	private Composite	filterParent; 
+	private boolean 	forceHeaderVisible = false;
+	
   /**
 	 * 
 	 */
@@ -134,13 +149,9 @@ public class ManagerView
     }
 
 		for (int i = 0; i < tabViews.size(); i++) {
-			IView view = (IView) tabViews.get(i);
+			UISWTViewCore view = tabViews.get(i);
 			if (view != null) {
-				if (view instanceof UISWTViewImpl) {
-					((UISWTViewImpl) view).dataSourceChanged(dataSourcePlugin);
-				} else {
-					view.dataSourceChanged(newDataSource);
-				}
+				view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, newDataSource);
 			}
 		}
 		
@@ -151,7 +162,6 @@ public class ManagerView
   private void delete() {
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
-  		uiFunctions.removeManagerView(manager);
   		uiFunctions.getUIUpdater().removeUpdater(this);
   	}
   	if (manager != null) {
@@ -166,28 +176,22 @@ public class ManagerView
   	}
 
     if (folder != null && !folder.isDisposed()){
-    	
     	folder.setSelection(0);
     }
     
-    //Don't ask me why, but without this an exception is thrown further
-    // (in folder.dispose() )
+    //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(Utils.isCarbon) {
       if(folder != null && !folder.isDisposed()) {
-        CTabItem[] items = folder.getItems();
-        for(int i=0 ; i < items.length ; i++) {
-          if (!items[i].isDisposed())
-            items[i].dispose();
-        }
+        Utils.disposeSWTObjects(folder.getItems());
       }
     }
 
     for (int i = 0; i < tabViews.size(); i++) {
-    	IView view = (IView) tabViews.get(i);
+    	UISWTViewCore view = tabViews.get(i);
     	try {
       	if (view != null) {
-      		view.delete();
+      		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
       	}
     	} catch (Throwable t) {
     		Debug.out(t);
@@ -195,24 +199,134 @@ public class ManagerView
     }
     tabViews.clear();
 
+    if ( header_font != null ){
+    	header_font.dispose();
+    }
     Utils.disposeSWTObjects(new Object[] { folder, parent });
   }
 
   private void initialize(Composite composite) {
+	  
+	  forceHeaderVisible = COConfigurationManager.getBooleanParameter("MyTorrentsView.alwaysShowHeader");
+	  
+	  Composite main_area = new Composite( composite, SWT.NULL );
+	  main_area.setLayout( new FormLayout());
+	  
+	  final Composite top_bar = new Composite( main_area, SWT.NULL );
+	  
+	  boolean az2 = Utils.isAZ2UI();
+	  
+	  Color bg_color = ColorCache.getColor( composite.getDisplay(), "#c0cbd4" );
+	  
+	  if ( !az2 ){
+		  top_bar.setBackground( bg_color );
+	  }
+	  
+	  FormData formData = new FormData();
+	  formData.left = new FormAttachment(0, 0);
+	  formData.right = new FormAttachment(100, 0);
+	  formData.top = new FormAttachment(0, 0);
+	  formData.height = forceHeaderVisible?TOP_BAR_HEIGHT:0;
+	  
+	  top_bar.setLayoutData(formData);
+	  
+	  top_bar.setLayout( new FormLayout());
+	  	  
+	  searchBox sb = new searchBox( top_bar );
+	  
+	  txtControl = sb.getControl();
+	  
+	  Label padding = new Label( top_bar, SWT.NULL );
+	  padding.setVisible( false );
+	  formData = new FormData();
+	  formData.top = new FormAttachment(0, 0);
+	  formData.bottom = new FormAttachment(100, 0);
+	  padding.setLayoutData(formData);
+	  
+	  header_label = new Label( top_bar, SWT.CENTER );
+	  header_label.setVisible( false );
+	  formData = new FormData();
+	  formData.top = new FormAttachment(padding, 0,SWT.CENTER);;
+	  formData.left = new FormAttachment(padding, 0,SWT.CENTER);
+	  formData.right = new FormAttachment(txtControl, 0 );
+	  header_label.setLayoutData(formData);
+	
+	  FontData[] fontdata = header_label.getFont().getFontData();
+	  //fontdata[0].setHeight(fontdata[0].getHeight() + 1);
+	  fontdata[0].setStyle(SWT.BOLD);
+	  header_font = new Font(composite.getDisplay(), fontdata);
+	  
+	  if ( !az2 ){
+		  header_label.setBackground( bg_color );
+		  header_label.setFont( header_font );
+	  }
+	  	  
+	  txtFilter = sb.getTextControl();
+	  formData = new FormData();
+	  formData.top = new FormAttachment(padding, 0,SWT.CENTER);
+	  formData.right = new FormAttachment(100, -10);
+	  formData.width=150;
+	  txtControl.setLayoutData(formData);
+	  
+
+	  
+	  filterParent = top_bar;
+
+	  Menu menuFilterHeader = new Menu(filterParent);
+	  final MenuItem menuItemAlwaysShow = new MenuItem(menuFilterHeader,
+			  SWT.CHECK);
+	  Messages.setLanguageText(menuItemAlwaysShow,
+	  "ConfigView.label.alwaysShowLibraryHeader");
+	  menuFilterHeader.addMenuListener(new MenuListener() {
+		  public void menuShown(MenuEvent e) {
+			  menuItemAlwaysShow.setSelection(forceHeaderVisible);
+		  }
+
+		  public void menuHidden(MenuEvent e) {
+		  }
+	  });
+	  menuItemAlwaysShow.addSelectionListener(new SelectionListener() {
+		  public void widgetSelected(SelectionEvent e) {
+			  COConfigurationManager.setParameter(
+					  "MyTorrentsView.alwaysShowHeader", !forceHeaderVisible);
+		  }
+
+		  public void widgetDefaultSelected(SelectionEvent e) {
+		  }
+	  });
+	  filterParent.setMenu(menuFilterHeader);
+	  Control[] children = filterParent.getChildren();
+	  for (Control control : children) {
+		  if (control != txtFilter) {
+			  control.setMenu(menuFilterHeader);
+		  }
+	  }
+	  
+		Object x = filterParent.getData( "SBC_LibraryView" );
 
+		
   	this.parent = composite;
-		if (folder == null) {
-			folder = new CTabFolder(composite, SWT.LEFT);
-			folder.setBorderVisible(true);
-		} else {
-			System.out.println("ManagerView::initialize : folder isn't null !!!");
-		}
+  	if (folder == null) {
+  		folder = new CTabFolder(main_area, SWT.LEFT);
+  		folder.setBorderVisible(true);
+  	} else {
+  		System.out.println("ManagerView::initialize : folder isn't null !!!");
+  	}
+
+  	formData = new FormData();
+  	formData.left = new FormAttachment(0, 0);
+  	formData.right = new FormAttachment(100, 0);
+ 	formData.top = new FormAttachment(top_bar, 0);
+ 	formData.bottom =  new FormAttachment(100, 0);
+ 	
+ 	folder.setLayoutData(formData);
+
   	if (composite.getLayout() instanceof FormLayout) {
-  		folder.setLayoutData(Utils.getFilledFormData());
+  		main_area.setLayoutData(Utils.getFilledFormData());
   	} else if (composite.getLayout() instanceof GridLayout) {
-  		folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+  		main_area.setLayoutData(new GridData(GridData.FILL_BOTH));
   	}
-  	
+  	  	
   	Label lblClose = new Label(folder, SWT.WRAP);
   	lblClose.setText("x");
   	lblClose.addListener(SWT.MouseUp, new Listener() {
@@ -223,91 +337,309 @@ public class ManagerView
   	folder.setTopRight(lblClose);
   	folder.setTabHeight(20);
   	
-  	ArrayList iviews_to_use = new ArrayList();
-  	iviews_to_use.add(new GeneralView());
-  	iviews_to_use.add(new PeersView());
-  	iviews_to_use.add(new PeersGraphicView());
-  	iviews_to_use.add(new PiecesView());
-  	iviews_to_use.add(new FilesView());
-  	iviews_to_use.add(new TorrentInfoView());
-  	iviews_to_use.add(new TorrentOptionsView());
-  	if (Logger.isEnabled()) {
-  		iviews_to_use.add(new LoggerView(true));
-  	}
-  	
-  	final IView[] views = (IView[])iviews_to_use.toArray(new IView[iviews_to_use.size()]);
-
-  	for (int i = 0; i < views.length; i++)
-		addSection(views[i], manager);
-
-
     // Call plugin listeners
 		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
 		if (uiFunctions != null) {
-			UISWTInstanceImpl pluginUI = uiFunctions.getSWTPluginInstanceImpl();
-			Map pluginViews = pluginUI == null ? null
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+			
+			if (pluginUI != null && !registeredCoreSubViews) {
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						GeneralView.MSGID_PREFIX, GeneralView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						TrackerView.MSGID_PREFIX, TrackerView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS, PeersView.MSGID_PREFIX,
+						PeersView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						PeersGraphicView.MSGID_PREFIX, PeersGraphicView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						PiecesView.MSGID_PREFIX, PiecesView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS, FilesView.MSGID_PREFIX,
+						FilesView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						TorrentInfoView.MSGID_PREFIX, TorrentInfoView.class, null);
+				pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+						TorrentOptionsView.MSGID_PREFIX, TorrentOptionsView.class, null);
+
+				if (Logger.isEnabled()) {
+					pluginUI.addView(UISWTInstance.VIEW_MYTORRENTS,
+							LoggerView.MSGID_PREFIX, LoggerView.class, null);
+				}
+				registeredCoreSubViews = true;
+			}
+			
+			UISWTViewEventListenerWrapper[] pluginViews = pluginUI == null ? null
 					: pluginUI.getViewListeners(UISWTInstance.VIEW_MYTORRENTS);
-			if (pluginViews != null) {
-				String[] sNames = (String[]) pluginViews.keySet().toArray(new String[0]);
-				for (int i = 0; i < sNames.length; i++) {
-					UISWTViewEventListener l = (UISWTViewEventListener) pluginViews.get(sNames[i]);
-					if (l != null) {
-						try {
-							UISWTViewImpl view = new UISWTViewImpl(
-									UISWTInstance.VIEW_MYTORRENTS, sNames[i], l);
-							addSection(view);
-						} catch (Exception e) {
-							// skip
-						}
+			for (UISWTViewEventListenerWrapper l : pluginViews) {
+				if (l != null) {
+					try {
+						UISWTViewImpl view = new UISWTViewImpl(
+								UISWTInstance.VIEW_MYTORRENTS, l.getViewID(), l, null);
+						addSection(view);
+					} catch (Exception e) {
+						// skip
 					}
 				}
 			}
 		}
 		
+	 COConfigurationManager.addAndFireParameterListeners(new String[] {
+		"MyTorrentsView.alwaysShowHeader" },
+		new ParameterListener()
+		 {
+			 public void 
+			 parameterChanged(
+				String parameterName) 
+			 {
+				Utils.execSWTThread(new AERunnable() {
+					public void runSupport() {
+						if ( txtFilter != null && !txtFilter.isDisposed()) {
+							forceHeaderVisible = COConfigurationManager.getBooleanParameter("MyTorrentsView.alwaysShowHeader");
+
+							boolean	is_visible = forceHeaderVisible || txtFilter.getText().length() > 0;
+							
+							FormData fd = (FormData)filterParent.getLayoutData();
+							boolean wasVisible = fd.height != 0;
+						
+							if (is_visible != wasVisible) {
+		  						fd.height = is_visible ? TOP_BAR_HEIGHT : 0;
+		  						filterParent.setLayoutData(fd);
+		  						filterParent.getParent().layout();
+							}
+						}
+					}
+				});
+			 }
+		 });
+	 
+
+	 Menu menu = new Menu(folder);
 
+	 menu.setData( "downloads", new DownloadManager[]{ manager });
+	 menu.setData( "is_detailed_view", true );
+
+	 MenuFactory.buildTorrentMenu( menu );
+
+	 folder.setMenu( menu );
+		
+	
     // Initialize view when user selects it
     folder.addSelectionListener(new SelectionAdapter() {
       public void widgetSelected(SelectionEvent e) {
-      	folder.getShell().setCursor(e.display.getSystemCursor(SWT.CURSOR_WAIT));
-      	try {
-        	// Send one last refresh to previous tab, just in case it
-        	// wants to do something when view goes invisible
-          refresh();
-  
-          CTabItem item = (CTabItem)e.item;
-          if (item != null) {
-          	IView view = (IView)item.getData("IView");
-            activeView = view;
-          	
-          	if (item.getControl() == null) {
-            	view.initialize(folder);
-            	item.setControl(view.getComposite());
-          	}
-          	
-          	item.getControl().setFocus();
-          }
-          refresh();
-      		ViewTitleInfoManager.refreshTitleInfo(ManagerView.this);
-      	} finally {
-      		folder.getShell().setCursor(null);
-      	}
+        CTabItem item = (CTabItem)e.item;
+        selectView(item);
       }
     });
     
     Utils.execSWTThreadLater(0, new AERunnable() {
 			public void runSupport() {
-				views[0].initialize(folder);
-				folder.getItem(0).setControl(views[0].getComposite());
-				views[0].refresh();
-				views[0].getComposite().layout(true);
-				views[0].getComposite().setFocus();
-				activeView = views[0];
-				ViewTitleInfoManager.refreshTitleInfo(ManagerView.this);
+        selectView(folder.getItem(0));
 			}
 		});
   }
   
-  private IView getActiveView() {
+	private void selectView(CTabItem item) {
+		if (item == null) {
+			return;
+		}
+		if (folder.getSelection() != item) {
+			folder.setSelection(item);
+		}
+		folder.getShell().setCursor(
+				folder.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+		try {
+			// Send one last refresh to previous tab, just in case it
+			// wants to do something when view goes invisible
+			refresh();
+			
+			if (activeView != null) {
+				activeView.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
+				
+			   	UISWTViewEventListener listener = activeView.getEventListener();
+		    	
+		    	if ( listener instanceof UISWTViewEventListenerHolder ){
+		    		
+		    		listener = ((UISWTViewEventListenerHolder)listener).getDelegatedEventListener( activeView );
+		    	}
+		    	
+		    		// unhook filtering
+		    	
+		    	if ( listener instanceof TableViewTab<?> && listener instanceof TableViewFilterCheck<?>){
+		    		
+		    		TableViewTab<?> tvt = (TableViewTab<?>)listener;
+		    		
+		    		TableViewSWT tv = tvt.getTableView();
+		    		
+		    		tv.disableFilterCheck();
+		    	}
+			}
+
+    	UISWTViewCore view = (UISWTViewCore)item.getData("IView");
+    	if (view == null) {
+    		Class<?> cla = (Class<?>)item.getData("claEventListener");
+    		UISWTViewEventListener l = (UISWTViewEventListener) cla.newInstance();
+    		view = new UISWTViewImpl(UISWTInstance.VIEW_MAIN, cla.getSimpleName(), l, manager);
+    		item.setData("IView", view);
+    	}
+      
+    	activeView = view;
+    	 
+    	if (item.getControl() == null) {
+    		view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, manager);
+      	view.initialize(folder);
+      	item.setControl(view.getComposite());
+    	}
+    	
+    	UISWTViewEventListener listener = view.getEventListener();
+    	
+    	if ( listener instanceof UISWTViewEventListenerHolder ){
+    		
+    		listener = ((UISWTViewEventListenerHolder)listener).getDelegatedEventListener( view );
+    	}
+    	
+    		// hook in filtering
+    	
+    	if ( listener instanceof TableViewTab<?> && listener instanceof TableViewFilterCheck<?>){
+    		
+    		final TableViewTab<Object> tvt = (TableViewTab<Object>)listener;
+    		
+    		final TableViewFilterCheck	delegate = (TableViewFilterCheck)tvt;
+    		
+    		txtControl.setVisible( true );
+    		
+     		header_label.setVisible( true );
+    		
+    		tvt.getTableView().enableFilterCheck(
+    			txtFilter, 
+    			new TableViewFilterCheck.TableViewFilterCheckEx<Object>()
+    			{
+    				boolean		enabled;
+    				int			value;
+    				
+    				{
+    					updateHeader();
+    				}
+    				
+    				public boolean 
+    				filterCheck(
+    					Object ds, 
+    					String filter, 
+    					boolean regex) 
+    				{
+    					return( delegate.filterCheck( ds, filter, regex ));
+    				};
+    				
+    				public void 
+    				filterSet(
+    					String filter ) 
+    				{
+    					boolean	was_enabled = enabled;
+    					
+    					enabled = filter != null && filter.length() > 0;
+    					
+    					ManagerView.this.filterSet( tvt.getTableView(), filter );
+    					
+    					delegate.filterSet( filter );
+    					
+    					if ( enabled != was_enabled ){
+    						
+    						Utils.execSWTThread(new AERunnable() {
+    							public void runSupport() {
+    								updateHeader();
+    							}});
+    					}
+     				}
+    				
+    				public void 
+    				viewChanged( 
+    					TableView<Object>	view )
+    				{
+    					value = view.size( false );
+    					
+    					if ( enabled ){
+    						
+    						Utils.execSWTThread(new AERunnable() {
+    							public void runSupport() {
+    								updateHeader();
+    							}});
+    					}
+    				}
+    				
+    				private void
+    				updateHeader()
+    				{
+    					int	total = manager.getNumFileInfos();
+    					
+    					String s = MessageText.getString( 
+    								"library.unopened.header" + (total>1?".p":"" ),
+    								new String[]{ String.valueOf( total )});
+    					
+    					if ( enabled ){
+    						
+    						String extra = 
+								MessageText.getString(
+										"filter.header.matches1",
+										new String[]{ String.valueOf( value ) });
+							
+							s += " " + extra;
+    					}
+    					
+    					header_label.setText( s );
+    				}
+    			});
+    	}else{
+    		txtControl.setVisible( false );
+    		header_label.setVisible( false );
+    	}
+    	
+    	item.getControl().setFocus();
+			SelectedContentManager.clearCurrentlySelectedContent();
+    	
+			view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
+
+
+	    UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+			if (uiFunctions != null) {
+				uiFunctions.refreshIconBar(); // For edit columns view
+			}
+
+			refresh();
+  		ViewTitleInfoManager.refreshTitleInfo(ManagerView.this);
+		} catch (Exception e) {
+			Debug.out(e);
+		} finally {
+			folder.getShell().setCursor(null);
+		}
+	}
+
+	public void 
+	filterSet(
+		final TableViewSWT<?>	tv,
+		final String 			filter) 
+	{
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (txtFilter != null) {
+					boolean visible = forceHeaderVisible || filter.length() > 0;
+					Object layoutData = filterParent.getLayoutData();
+					if (layoutData instanceof FormData) {
+						FormData fd = (FormData) layoutData;
+						boolean wasVisible = fd.height != 0;
+						if (visible != wasVisible) {
+  						fd.height = visible ? TOP_BAR_HEIGHT : 0;
+  						filterParent.setLayoutData(layoutData);
+  						filterParent.getParent().layout();
+						}
+					}
+					if (!visible) {
+						tv.setFocus();
+					}
+				}
+			}
+		});
+	}
+
+  
+  private UISWTViewCore getActiveView() {
   	return activeView;
   }
 
@@ -319,20 +651,22 @@ public class ManagerView
 			return;
 
 		try {
-			IView view = getActiveView();
-			if (view != null)
-				view.refresh();
+			UISWTViewCore view = getActiveView();
+			if (view != null) {
+				view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
+			}
 
 			CTabItem[] items = folder.getItems();
 			
 	    for (int i = 0; i < items.length; i++) {
 	    	CTabItem item = items[i];
-	    	view = (IView) item.getData("IView");
+	    	view = (UISWTViewCore) item.getData("IView");
         try {
-          if (item.isDisposed())
+          if (item.isDisposed() || view == null) {
             continue;
+          }
           String lastTitle = item.getText();
-          String newTitle = view.getShortTitle();
+          String newTitle = view.getFullTitle();
           if (lastTitle == null || !lastTitle.equals(newTitle)) {
             item.setText(escapeAccelerators(newTitle));
           }
@@ -347,11 +681,6 @@ public class ManagerView
         }
       }
 	    
-	    UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-			if (uiFunctions != null) {
-				uiFunctions.refreshIconBar(); // For edit columns view
-			}
-
 		} catch (Exception e) {
 			Debug.printStackTrace(e);
 		}
@@ -367,9 +696,8 @@ public class ManagerView
 			int completed = manager == null ? -1
 					: manager.getStats().getCompleted();
 			if (lastCompleted != completed) {
-				swtView.setTitle(DisplayFormatters.formatPercentFromThousands(completed)
-						+ " : " + manager.getDisplayName());
 				ViewTitleInfoManager.refreshTitleInfo(this);
+				lastCompleted = completed;
 			}
 		}
 	}
@@ -386,57 +714,44 @@ public class ManagerView
 	  return( str.replaceAll( "&", "&&" ));
   }
   
-  public boolean isEnabled(String itemKey) {
-		if (itemKey.equals("run"))
-			return true;
-
-		if (itemKey.equals("start"))
-			return ManagerUtils.isStartable(manager);
-
-		if (itemKey.equals("stop"))
-			return ManagerUtils.isStopable(manager);
-
-		if (itemKey.equals("remove"))
-			return true;
-		
-		if (itemKey.equals("editcolumns")) {
-			IView active_view = getActiveView();
-			if (active_view != null) {
-				return active_view.isEnabled(itemKey);
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		UISWTViewCore active_view = getActiveView();
+		if (active_view != null) {
+			UIPluginViewToolBarListener l = active_view.getToolBarListener();
+			if (l != null) {
+				l.refreshToolBarItems(list);
+				return;
 			}
 		}
 		
-		return false;
 	}
 
-	public void itemActivated(String itemKey) {
-		if (itemKey.equals("run")) {
-			ManagerUtils.run(manager);
-			return;
-		}
-		
-		if (itemKey.equals("start")) {
-			ManagerUtils.queue(manager, folder.getShell());
-			return;
-		}
-		
-		if (itemKey.equals("stop")) {
-			ManagerUtils.stop(manager, folder.getShell());
-			return;
-		}
-		
-		if (itemKey.equals("remove")) {
-			ManagerUtils.remove(manager, null, false, false);
-			return;
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		UISWTViewCore active_view = getActiveView();
+		if (active_view != null) {
+			UIPluginViewToolBarListener l = active_view.getToolBarListener();
+			if (l != null && l.toolBarItemActivated(item, activationType, datasource)) {
+				return true;
+			}
 		}
+
 		
+		String itemKey = item.getID();
+
 		if (itemKey.equals("editcolumns")) {
-			IView active_view = getActiveView();
-			if (active_view != null) {
-				active_view.itemActivated(itemKey);
-				return;
+			if (active_view instanceof ToolBarEnabler) {
+				return ((ToolBarEnabler)active_view).toolBarItemActivated(itemKey);
 			}
 		}
+
+		return false;
 	}
   
   
@@ -480,30 +795,18 @@ public class ManagerView
 		addSection(view, pluginDataSource);
 	}
 	
-	private void addSection(IView view, Object dataSource) {
+	private void addSection(UISWTViewCore view, Object dataSource) {
 		if (view == null)
 			return;
 
-		view.dataSourceChanged(dataSource);
+		view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, dataSource);
 
 		CTabItem item = new CTabItem(folder, SWT.NULL);
-		Messages.setLanguageText(item, view.getData());
+		Messages.setLanguageText(item, view.getTitleID());
 		item.setData("IView", view);
 		tabViews.add(view);
 	}
 
-	public Image obfusticatedImage(Image image, Point shellOffset) {
-		IView view = getActiveView();
-		if (view instanceof ObfusticateImage) {
-			try {
-				((ObfusticateImage)view).obfusticatedImage(image, shellOffset);
-			} catch (Exception e) {
-				Debug.out("Obfusticating " + view, e);
-			}
-		}
-		return image;
-	}
-
 	public String getObfusticatedHeader() {
     int completed = manager.getStats().getCompleted();
     return DisplayFormatters.formatPercentFromThousands(completed) + " : " + manager;
@@ -511,16 +814,42 @@ public class ManagerView
 	
 	public DownloadManager getDownload() {return manager;}
 
+	
+	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo2#titleInfoLinked(com.aelitis.azureus.ui.mdi.MultipleDocumentInterface, com.aelitis.azureus.ui.mdi.MdiEntry)
+	public void titleInfoLinked(MultipleDocumentInterface mdi, MdiEntry mdiEntry) {
+		if (mdiEntry instanceof MdiEntrySWT) {
+			((MdiEntrySWT) mdiEntry).addListener(new MdiSWTMenuHackListener() {
+				public void menuWillBeShown(MdiEntry entry, Menu menuTree) {
+					TableView<?> tv = SelectedContentManager.getCurrentlySelectedTableView();
+					menuTree.setData("TableView", tv);
+					menuTree.setData("downloads", new DownloadManager[] { manager });
+					menuTree.setData("is_detailed_view", new Boolean(true));
+
+					MenuFactory.buildTorrentMenu(menuTree);
+				}
+			});
+		}
+	}
+
 	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo#getTitleInfoProperty(int)
 	public Object getTitleInfoProperty(int propertyID) {
 		if (propertyID == TITLE_TEXT) {
+			if (Utils.isAZ2UI()) {
+				if (manager == null) {
+					return null;
+				}
+		    int completed = manager.getStats().getCompleted();
+				return DisplayFormatters.formatPercentFromThousands(completed)
+						+ " : " + manager.getDisplayName();
+			}
+
 			return manager == null ? "" : manager.getDisplayName();
 		}
 
 		if (manager == null) {
 			return null;
 		}
-		if (propertyID == TITLE_INDICATOR_TEXT) {
+		if (propertyID == TITLE_INDICATOR_TEXT && !Utils.isAZ2UI()) {
 	    int completed = manager.getStats().getCompleted();
 	    if (completed != 1000) {
 	    	return (completed / 10) + "%";
@@ -549,6 +878,8 @@ public class ManagerView
 				id = "??";
 			}
 			return "DMDetails-" + id;
+		} else if (propertyID == TITLE_IMAGEID) {
+			return "image.sidebar.details";
 		}
 		return null;
 	}
@@ -557,6 +888,7 @@ public class ManagerView
     switch (event.getType()) {
       case UISWTViewEvent.TYPE_CREATE:
       	swtView = (UISWTView)event.getData();
+      	swtView.setToolBarListener(this);
         break;
 
       case UISWTViewEvent.TYPE_DESTROY:
@@ -574,11 +906,28 @@ public class ManagerView
       case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
       	dataSourceChanged(event.getData());
         break;
-
         
+      case UISWTViewEvent.TYPE_OBFUSCATE:
+      case UISWTViewEvent.TYPE_FOCUSLOST: {
+      	UISWTViewCore view = getActiveView();
+  			if (view != null) {
+  				view.triggerEvent(event.getType(), event.getData());
+  			}
+  			break;
+      }
+
+      case UISWTViewEvent.TYPE_FOCUSGAINED: {
+      	UISWTViewCore view = getActiveView();
+  			if (view != null) {
+  				view.triggerEvent(event.getType(), null);
+  			}
+      }
+      // Fallthrough
+
       case UISWTViewEvent.TYPE_REFRESH:
         refresh();
         break;
+
     }
 
     return true;
@@ -598,4 +947,174 @@ public class ManagerView
 	public void updateUI() {
 		refreshTitle();
 	}
+	
+	
+	private class 
+	searchBox
+	{
+			// shameless hack from SWTSkinObjectTextbox
+		
+		private Control	control;
+		private Text textWidget;
+		
+		private Composite cBubble;
+		
+		private String text = "";
+	
+		public 
+		searchBox(
+			Composite createOn )
+		{		
+			int style = SWT.BORDER;		
+	
+			style |= SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL;
+			
+			if (Constants.isWindows) {
+				cBubble = new Composite(createOn, SWT.NONE);
+				cBubble.setLayout(new FormLayout());
+			}
+				
+			if ( cBubble == null ){
+				
+				textWidget = new Text(createOn, style);
+				
+			} else {
+				
+				textWidget = new Text(cBubble, SWT.NULL );
+				
+				FormData fd = new FormData();
+				fd.top = new FormAttachment(0, 2);
+				fd.bottom = new FormAttachment(100, -2);
+				fd.left = new FormAttachment(0, 17);
+				fd.right = new FormAttachment(100, -14);
+				textWidget.setLayoutData(fd);
+	
+				cBubble.addPaintListener(new PaintListener() {
+					public void paintControl(PaintEvent e) {
+						Rectangle clientArea = cBubble.getClientArea();
+						e.gc.setBackground(textWidget.getBackground());
+						e.gc.setAdvanced(true);
+						e.gc.setAntialias(SWT.ON);
+						e.gc.fillRoundRectangle(clientArea.x, clientArea.y,
+								clientArea.width - 1, clientArea.height - 1, clientArea.height,
+								clientArea.height);
+						e.gc.setAlpha(127);
+						e.gc.drawRoundRectangle(clientArea.x, clientArea.y,
+								clientArea.width - 1, clientArea.height - 1, clientArea.height,
+								clientArea.height);
+	
+						e.gc.setLineCap(SWT.CAP_ROUND);
+	
+						int iconHeight = clientArea.height - 9;
+						if (iconHeight > 13) {
+							iconHeight = 13;
+						}
+						int iconY = clientArea.y + ((clientArea.height - iconHeight + 1) / 2);
+						
+						e.gc.setAlpha(120);
+						e.gc.setLineWidth(2);
+						e.gc.drawOval(clientArea.x + 6, iconY, 7, 6); 
+						e.gc.drawPolyline(new int[] {
+							clientArea.x + 12,
+							iconY + 6,
+							clientArea.x + 15,
+							iconY + iconHeight,
+						});
+						
+						boolean textIsBlank = text.length() == 0;
+						if (!textIsBlank) {
+							//e.gc.setLineWidth(1);
+							e.gc.setAlpha(80);
+							Rectangle rXArea = new Rectangle(clientArea.x + clientArea.width
+									- 16, clientArea.y + 1, 11, clientArea.height - 2);
+							cBubble.setData("XArea", rXArea);
+	
+							e.gc.drawPolyline(new int[] {
+								clientArea.x + clientArea.width - 7,
+								clientArea.y + 7,
+								clientArea.x + clientArea.width - (7 + 5),
+								clientArea.y + clientArea.height - 7,
+							});
+							e.gc.drawPolyline(new int[] {
+								clientArea.x + clientArea.width - 7,
+								clientArea.y + clientArea.height - 7,
+								clientArea.x + clientArea.width - (7 + 5),
+								clientArea.y + 7,
+							});
+						}
+					}
+				});
+				
+				cBubble.addListener(SWT.MouseDown, new Listener() {
+					public void handleEvent(Event event) {
+						Rectangle r = (Rectangle) event.widget.getData("XArea");
+						if (r != null && r.contains(event.x, event.y)) {
+							textWidget.setText("");
+						}
+					}
+				});
+				
+					// pick up changes in the text control's bg color and propagate to the bubble
+				
+				textWidget.addPaintListener(
+					new PaintListener()
+					{
+						private Color existing_bg;
+						
+						public void 
+						paintControl(
+							PaintEvent arg0 )
+						{
+							Color current_bg = textWidget.getBackground();
+							
+							if ( current_bg != existing_bg ){
+								
+								existing_bg = current_bg;
+								
+								cBubble.redraw();
+							}
+						}
+					});
+			}
+			
+			textWidget.addModifyListener(new ModifyListener() {
+				public void modifyText(ModifyEvent e) {
+					boolean textWasBlank = text.length() == 0;
+					text = textWidget.getText();
+					boolean textIsBlank = text.length() == 0;
+					if (textWasBlank != textIsBlank && cBubble != null) {
+						cBubble.redraw();
+					}
+				}
+			});
+			
+			control = cBubble == null ? textWidget : cBubble;
+		}
+	
+	
+		public void setText(final String val) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (textWidget != null && !textWidget.isDisposed()) {
+						textWidget.setText(val == null ? "" : val);
+						text = val;
+					}
+				}
+			});
+	
+		}
+		public Control
+		getControl()
+		{
+			return( control );
+		}
+		
+		public String getText() {
+			return text;
+		}
+	
+		public Text getTextControl() {
+			return textWidget;
+		}
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/MySharesView.java b/org/gudy/azureus2/ui/swt/views/MySharesView.java
index b8eb7b9..f0912cc 100644
--- a/org/gudy/azureus2/ui/swt/views/MySharesView.java
+++ b/org/gudy/azureus2/ui/swt/views/MySharesView.java
@@ -25,17 +25,21 @@
 
 package org.gudy.azureus2.ui.swt.views;
 
-import java.util.ArrayList;
-import java.util.Arrays;
+import java.io.File;
+import java.util.*;
 import java.util.List;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
 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.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.TorrentUtils;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.sharing.*;
@@ -44,23 +48,32 @@ import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
 import org.gudy.azureus2.plugins.tracker.Tracker;
 import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
 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.URLTransfer;
+import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener;
+import org.gudy.azureus2.ui.swt.sharing.ShareUtils;
 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.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 import org.gudy.azureus2.ui.swt.views.tableitems.myshares.CategoryItem;
 import org.gudy.azureus2.ui.swt.views.tableitems.myshares.NameItem;
 import org.gudy.azureus2.ui.swt.views.tableitems.myshares.TypeItem;
 
 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.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo2;
+import com.aelitis.azureus.ui.mdi.MdiEntry;
+import com.aelitis.azureus.ui.mdi.MdiEntryDropListener;
+import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
 
 /**
  * @author parg
@@ -69,10 +82,10 @@ import com.aelitis.azureus.ui.common.table.*;
  *         2004/Apr/21: extends TableView instead of IAbstractView
  */
 public class MySharesView 
-extends TableViewTab
+extends TableViewTab<ShareResource>
 implements ShareManagerListener,
 		TableLifeCycleListener, TableViewSWTMenuFillListener,
-		TableRefreshListener, TableSelectionListener
+		TableRefreshListener, TableSelectionListener, ViewTitleInfo2
 {
   private static final TableColumnCore[] basicItems = {
     new NameItem(),
@@ -85,13 +98,15 @@ implements ShareManagerListener,
 
 	private Menu			menuCategory;
 
-	private TableViewSWTImpl<ShareResource> tv;
+	private TableViewSWT<ShareResource> tv;
+
+	private DropTarget dropTarget;
 
 	public 
 	MySharesView()
 	{	
 		super("MySharesView");
-		tv = new TableViewSWTImpl<ShareResource>(ShareResource.class, TableManager.TABLE_MYSHARES,
+		tv = TableViewFactory.createTableViewSWT(ShareResource.class, TableManager.TABLE_MYSHARES,
 				getPropertiesPrefix(), basicItems, "name", SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.BORDER | SWT.VIRTUAL);
 
@@ -113,7 +128,7 @@ implements ShareManagerListener,
   }
 	
 	private void defaultSelected(TableRowCore[] rows) {
-		ShareResource share = tv.getFirstSelectedDataSource();
+		ShareResource share = (ShareResource) tv.getFirstSelectedDataSource();
 		if (share == null) {
 			return;
 		}
@@ -159,8 +174,54 @@ implements ShareManagerListener,
 				createRows(core);
 			}
 		});
+
+		if ( dropTarget == null ){
+			dropTarget = tv.createDropTarget(DND.DROP_DEFAULT | DND.DROP_MOVE
+					| DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE);
+			if (dropTarget != null) {
+				dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(),
+						URLTransfer.getInstance(), FileTransfer.getInstance(),
+						TextTransfer.getInstance() });
+	
+				dropTarget.addDropListener(new DropTargetAdapter() {
+					public void drop(DropTargetEvent event) {
+						if (!share(event.data)) {
+							TorrentOpener.openDroppedTorrents(event, true);
+						}
+					}
+				});
+			};
+		}
 	}
 	
+	protected boolean share(Object eventData) {
+		boolean shared = false;
+		if (eventData instanceof String[] || eventData instanceof String) {
+			final String[] sourceNames = (eventData instanceof String[])
+					? (String[]) eventData : new String[] {
+						(String) eventData
+					};
+			if (sourceNames == null) {
+				return false;
+			}
+			for (int i = 0; (i < sourceNames.length); i++) {
+				final File source = new File(sourceNames[i]);
+				String filename = source.getAbsolutePath();
+				try {
+					if (source.isFile() && !TorrentUtils.isTorrentFile(filename)) {
+						ShareUtils.shareFile(filename);
+						shared = true;
+					} else if (source.isDirectory()) {
+						ShareUtils.shareDir(filename);
+						shared = true;
+					}
+				} catch (Exception e) {
+				}
+			}
+		}
+		return shared;
+	}
+
 	public void tableViewDestroyed() {
 		try {
 			PluginInitializer.getDefaultInterface().getShareManager().removeListener(
@@ -252,7 +313,6 @@ implements ShareManagerListener,
 	public void	reportCurrentTask(final String task_description) { }
  
 	public void tableRefresh() {
-		computePossibleActions();
 	  	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
  	  	if (uiFunctions != null) {
  	  		uiFunctions.refreshIconBar();
@@ -344,13 +404,11 @@ implements ShareManagerListener,
 	      }
 	    });
 	  }
-	  
-  private boolean start,stop,remove;
-  
-  private void 
-  computePossibleActions() 
-  {
-    start = stop = remove = false;
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+	  	super.refreshToolBarItems(list);
+
+	  	boolean start = false, stop = false, remove = false;
     
     if (!AzureusCoreFactory.isCoreRunning()) {
     	return;
@@ -398,31 +456,28 @@ implements ShareManagerListener,
     	}
       }
     }
-  }
   
-  public boolean isEnabled(String itemKey) {
-    if(itemKey.equals("start"))
-      return start;
-    if(itemKey.equals("stop"))
-      return stop;
-    if(itemKey.equals("remove"))
-      return remove;
-    return super.isEnabled(itemKey);
+  	list.put("start", start ? UIToolBarItem.STATE_ENABLED : 0);
+  	list.put("stop", stop ? UIToolBarItem.STATE_ENABLED : 0);
+  	list.put("remove", remove ? UIToolBarItem.STATE_ENABLED : 0);
   }
   
 
-  public void itemActivated(String itemKey) {
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		String itemKey = item.getID();
+
     if(itemKey.equals("remove")){
       removeSelectedShares();
-      return;
+      return true;
     }else if ( itemKey.equals( "stop" )){
     	stopSelectedShares();
-    	return;
+    	return true;
     }else if ( itemKey.equals( "start" )){
     	startSelectedShares();
-    	return;
+    	return true;
     }
-    super.itemActivated(itemKey);
+		return super.toolBarItemActivated(item, activationType, datasource);
   }
   
   private List
@@ -606,9 +661,8 @@ implements ShareManagerListener,
     		
     	}catch( Throwable e ){
     		
-    	  Alerts.showErrorMessageBoxUsingResourceString(
-						new Object[] { shares[i] },
-    	  		"globalmanager.download.remove.veto", e, 0 );
+				Logger.log(new LogAlert(shares[i], false,
+						"{globalmanager.download.remove.veto}", e));
     	}
     }
   }
@@ -622,7 +676,6 @@ implements ShareManagerListener,
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#deselected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void deselected(TableRowCore[] rows) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
@@ -631,7 +684,6 @@ implements ShareManagerListener,
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#focusChanged(com.aelitis.azureus.ui.common.table.TableRowCore)
 	public void focusChanged(TableRowCore focus) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
@@ -648,10 +700,22 @@ implements ShareManagerListener,
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void selected(TableRowCore[] row) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
   	}
 	}
+	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo#getTitleInfoProperty(int)
+	public Object getTitleInfoProperty(int propertyID) {
+		return null;
+	}
+
+	// @see com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo2#titleInfoLinked(com.aelitis.azureus.ui.mdi.MultipleDocumentInterface, com.aelitis.azureus.ui.mdi.MdiEntry)
+	public void titleInfoLinked(MultipleDocumentInterface mdi, MdiEntry mdiEntry) {
+		mdiEntry.addListener(new MdiEntryDropListener() {
+			public boolean mdiEntryDrop(MdiEntry entry, Object droppedObject) {
+				return share(droppedObject);
+			}
+		});
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/MyTorrentsSuperView.java b/org/gudy/azureus2/ui/swt/views/MyTorrentsSuperView.java
index f398853..8426e65 100644
--- a/org/gudy/azureus2/ui/swt/views/MyTorrentsSuperView.java
+++ b/org/gudy/azureus2/ui/swt/views/MyTorrentsSuperView.java
@@ -18,40 +18,48 @@
  */
 package org.gudy.azureus2.ui.swt.views;
 
+import java.util.Arrays;
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
 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.AERunnable;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.IndentWriter;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.swt.DelayedListenerMultiCombiner;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 
 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.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
-
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import com.aelitis.azureus.util.MapUtils;
 
 /**
- * @author MjrTom
- *			2005/Dec/08: Avg Avail Item
+ * Wraps a "Incomplete" torrent list and a "Complete" torrent list into
+ * one view
  */
-
-public class MyTorrentsSuperView extends AbstractIView implements
-		ObfusticateImage, IViewExtension
+public class MyTorrentsSuperView
+	implements UISWTViewCoreEventListener,
+	AEDiagnosticsEvidenceGenerator, UIPluginViewToolBarListener
 {
 	private static int SASH_WIDTH = 5;
 
@@ -69,8 +77,25 @@ public class MyTorrentsSuperView extends AbstractIView implements
 
 	private Composite child2;
 
-  public MyTorrentsSuperView() {
-  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+	private final Text txtFilter;
+
+
+	private final Composite cCats;
+
+
+	private Object ds;
+
+
+	private UISWTView swtView;
+
+
+	private MyTorrentsView viewWhenDeactivated;
+
+  public MyTorrentsSuperView(Text txtFilter, Composite cCats) {
+  	this.txtFilter = txtFilter;
+		this.cCats = cCats;
+		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
 				Utils.execSWTThread(new AERunnable() {
 					public void runSupport() {
@@ -88,14 +113,6 @@ public class MyTorrentsSuperView extends AbstractIView implements
     return form;
   }
   
-  public void delete() {
-    if (torrentview != null)
-      torrentview.delete();
-    if (seedingview != null)
-      seedingview.delete();
-    super.delete();
-  }
-
   public void initialize(final Composite parent) {
     if (form != null) {
       return;
@@ -110,10 +127,11 @@ public class MyTorrentsSuperView extends AbstractIView implements
   	gridData = new GridData(GridData.FILL_BOTH);
   	form.setLayoutData(gridData);
   	
+
   	GridLayout layout;
   	
   	
-  	child1 = new Composite(form,SWT.NULL);
+  	child1 = new Composite(form,SWT.NONE);
   	layout = new GridLayout();
   	layout.numColumns = 1;
   	layout.horizontalSpacing = 0;
@@ -123,6 +141,29 @@ public class MyTorrentsSuperView extends AbstractIView implements
   	child1.setLayout(layout);
 
     final Sash sash = new Sash(form, SWT.HORIZONTAL);
+    Image image = new Image(sash.getDisplay(), 9, SASH_WIDTH);
+    ImageData imageData = image.getImageData();
+    int[] row = new int[imageData.width];
+    for (int i = 0; i < row.length; i++) {
+   		row[i] = (i % 3) != 0 ? 0xE0E0E0 : 0x808080;
+    	if (imageData.depth == 32) {
+    		row[i] = (row[i] & 255) + (row[i] << 8);
+    	}
+		}
+    for (int y = 1; y < imageData.height - 1; y++) {
+    	imageData.setPixels(0, y, row.length, row, 0);
+    }
+    Arrays.fill(row, 0xE0E0E0E0);
+  	imageData.setPixels(0, 0, row.length, row, 0);
+  	imageData.setPixels(0, imageData.height - 1, row.length, row, 0);
+    image.dispose();
+    image = new Image(sash.getDisplay(), imageData);
+    sash.setBackgroundImage(image);
+    sash.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				sash.getBackgroundImage().dispose();
+			}
+		});
 
     child2 = new Composite(form,SWT.NULL);
     layout = new GridLayout();
@@ -135,11 +176,28 @@ public class MyTorrentsSuperView extends AbstractIView implements
 
     FormData formData;
 
+    // More precision, times by 100
+    int weight = (int) (COConfigurationManager.getFloatParameter("MyTorrents.SplitAt"));
+		if (weight > 10000) {
+			weight = 10000;
+		} else if (weight < 100) {
+			weight *= 100;
+		}
+		// Min/max of 5%/95%
+		if (weight < 500) {
+			weight = 500;
+		} else if (weight > 9000) {
+			weight = 9000;
+		}
+		double pct = (float)weight / 10000;		
+		sash.setData("PCT", new Double(pct));
+
 		// FormData for table child1
 		formData = new FormData();
 		formData.left = new FormAttachment(0, 0);
 		formData.right = new FormAttachment(100, 0);
 		formData.top = new FormAttachment(0, 0);
+		formData.bottom = new FormAttachment((int) (pct * 100), 0);
 		child1.setLayoutData(formData);
 		final FormData child1Data = formData;
     
@@ -157,22 +215,7 @@ public class MyTorrentsSuperView extends AbstractIView implements
 		formData.right = new FormAttachment(100, 0);
 		formData.bottom = new FormAttachment(100, 0);
 		formData.top = new FormAttachment(sash);
-    // More precision, times by 100
-    int weight = (int) (COConfigurationManager.getFloatParameter("MyTorrents.SplitAt"));
-		if (weight > 10000) {
-			weight = 10000;
-		} else if (weight < 100) {
-			weight *= 100;
-		}
-		// Min/max of 5%/95%
-		if (weight < 500) {
-			weight = 500;
-		} else if (weight > 9000) {
-			weight = 9000;
-		}
-		
-		// height will be set on first resize call
-		sash.setData("PCT", new Double((float)weight / 10000));
+
 		child2.setLayoutData(formData);
 
 		
@@ -197,25 +240,20 @@ public class MyTorrentsSuperView extends AbstractIView implements
 			}
 		});
 
-		form.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event e) {
+		form.addListener(SWT.Resize, new DelayedListenerMultiCombiner() {
+			public void handleDelayedEvent(Event e) {
 				Double l = (Double) sash.getData("PCT");
-				if (l != null) {
-					child1Data.height = (int) (form.getBounds().height * l
-							.doubleValue());
+				if (l == null) {
+					return;
+				}
+				int newHeight = (int) (form.getBounds().height * l.doubleValue());
+				if (child1Data.height != newHeight || child1Data.bottom != null) {
+					child1Data.bottom = null;
+					child1Data.height = newHeight;
 					form.layout();
 				}
 			}
 		});
-		try {
-  		Double l = (Double) sash.getData("PCT");
-  		if (l != null) {
-  			child1Data.height = (int) (form.getBounds().height * l
-  					.doubleValue());
-  		}
-		} catch (Exception e) {
-			
-		}
 
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(final AzureusCore core) {
@@ -246,18 +284,6 @@ public class MyTorrentsSuperView extends AbstractIView implements
 	}
 
 
-	public void refresh() {
-    if (getComposite() == null || getComposite().isDisposed())
-      return;
-
-    if (seedingview != null) {
-    	seedingview.refresh();
-    }
-    if (torrentview != null) {
-    	torrentview.refresh();
-    }
-  }
-
   public void updateLanguage() {
   	// no super call, the views will do their own
   	
@@ -280,30 +306,37 @@ public class MyTorrentsSuperView extends AbstractIView implements
   private MyTorrentsView getCurrentView() {
     // wrap in a try, since the controls may be disposed
     try {
-      if (torrentview != null && torrentview.isTableFocus())
+      if (torrentview != null && torrentview.isTableFocus()) {
         lastSelectedView = torrentview;
-      else if (seedingview != null && seedingview.isTableFocus())
+      } else if (seedingview != null && seedingview.isTableFocus()) {
       	lastSelectedView = seedingview;
+      }
     } catch (Exception ignore) {/*ignore*/}
 
     return lastSelectedView;
   }
 
-  // IconBarEnabler
-  public boolean isEnabled(String itemKey) {
-    IView currentView = getCurrentView();
-    if (currentView != null)
-      return currentView.isEnabled(itemKey);
-    else
-      return false;
+  /* (non-Javadoc)
+   * @see com.aelitis.azureus.ui.common.ToolBarEnabler2#refreshToolBarItems(java.util.Map)
+   */
+  public void refreshToolBarItems(Map<String, Long> list) {
+    MyTorrentsView currentView = getCurrentView();
+    if (currentView != null) {
+      currentView.refreshToolBarItems(list);
+    }
   }
-  
-  // IconBarEnabler
-  // @see org.gudy.azureus2.ui.swt.views.AbstractIView#itemActivated(java.lang.String)
-  public void itemActivated(String itemKey) {
-    IView currentView = getCurrentView();
-    if (currentView != null)
-      currentView.itemActivated(itemKey);    
+
+  /* (non-Javadoc)
+   * @see com.aelitis.azureus.ui.common.ToolBarActivation#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long)
+   */
+  public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
+    MyTorrentsView currentView = getCurrentView();
+    if (currentView != null) {
+      if (currentView.toolBarItemActivated(item, activationType, null)) {
+      	return true;
+      }
+    }
+    return false;
   }
   
   public DownloadManager[] getSelectedDownloads() {
@@ -313,10 +346,9 @@ public class MyTorrentsSuperView extends AbstractIView implements
   }
   
   public void
-  generateDiagnostics(
+  generate(
 	IndentWriter	writer )
   {
-	  super.generateDiagnostics( writer );
 
 	  try{
 		  writer.indent();
@@ -325,7 +357,7 @@ public class MyTorrentsSuperView extends AbstractIView implements
 		  
 		  writer.indent();
 
-		  torrentview.generateDiagnostics( writer );
+		  torrentview.generate( writer );
 	  
 	  }finally{
 		  
@@ -341,7 +373,7 @@ public class MyTorrentsSuperView extends AbstractIView implements
 		  
 		  writer.indent();
 
-		  seedingview.generateDiagnostics( writer );
+		  seedingview.generate( writer );
 	  
 	  }finally{
 		  
@@ -351,12 +383,12 @@ public class MyTorrentsSuperView extends AbstractIView implements
 	  }
   }
 
-	public Image obfusticatedImage(Image image, Point shellOffset) {
+	private Image obfusticatedImage(Image image) {
 		if (torrentview != null) {
-			torrentview.obfusticatedImage(image, shellOffset);
+			torrentview.obfusticatedImage(image);
 		}
 		if (seedingview != null) {
-			seedingview.obfusticatedImage(image, shellOffset);
+			seedingview.obfusticatedImage(image);
 		}
 		return image;
 	}
@@ -368,22 +400,22 @@ public class MyTorrentsSuperView extends AbstractIView implements
 	public void viewActivated() {
 		SelectedContentManager.clearCurrentlySelectedContent();
 
-		IView currentView = getCurrentView();
-    if (currentView instanceof IViewExtension) {
-    	((IViewExtension)currentView).viewActivated();
-    }
-    if (currentView instanceof MyTorrentsView) {
-    	((MyTorrentsView)currentView).updateSelectedContent();
-    }
+		if (viewWhenDeactivated != null) {
+			viewWhenDeactivated.getComposite().setFocus();
+			viewWhenDeactivated.updateSelectedContent(true);
+		} else {
+			MyTorrentsView currentView = getCurrentView();
+			if (currentView != null ) {
+				currentView.updateSelectedContent();
+			}
+		}
 	}
 
 	public void viewDeactivated() {
-    IView currentView = getCurrentView();
-    if (currentView == null) {return;}
-    if (currentView instanceof IViewExtension) {
-    	((IViewExtension)currentView).viewDeactivated();
-    }
+		viewWhenDeactivated = getCurrentView();
     /*
+    MyTorrentsView currentView = getCurrentView();
+    if (currentView == null) {return;}
     String ID = currentView.getShortTitle();
     if (currentView instanceof MyTorrentsView) {
     	ID = ((MyTorrentsView)currentView).getTableView().getTableID();
@@ -428,8 +460,17 @@ public class MyTorrentsSuperView extends AbstractIView implements
 	 */
 	protected MyTorrentsView createTorrentView(AzureusCore _azureus_core,
 			String tableID, boolean isSeedingView, TableColumnCore[] columns, Composite c) {
-		MyTorrentsView view = new MyTorrentsView(_azureus_core, tableID, isSeedingView, columns);
-    view.initialize(c);
+		MyTorrentsView view = new MyTorrentsView(_azureus_core, tableID,
+				isSeedingView, columns, txtFilter, cCats);
+		
+		try {
+			UISWTViewImpl swtView = new UISWTViewImpl(UISWTInstance.VIEW_MAIN, tableID, view, ds);
+			swtView.initialize(c);
+		} catch (Exception e) {
+			Debug.out(e);
+		}
+
+		/*
 		c.addListener(SWT.Activate, new Listener() {
 			public void handleEvent(Event event) {
 				viewActivated();
@@ -440,6 +481,8 @@ public class MyTorrentsSuperView extends AbstractIView implements
 				viewDeactivated();
 			}
 		});
+		*/
+		c.layout();
 		return view;
 	}
 
@@ -452,4 +495,80 @@ public class MyTorrentsSuperView extends AbstractIView implements
 	public MyTorrentsView getSeedingview() {
 		return seedingview;
 	}
+	
+	public void dataSourceChanged(Object newDataSource) {
+		ds = newDataSource;
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+		switch (event.getType()) {
+			case UISWTViewEvent.TYPE_CREATE:
+				swtView = (UISWTView) event.getData();
+      	swtView.setToolBarListener(this);
+				swtView.setTitle(getFullTitle());
+				break;
+
+			case UISWTViewEvent.TYPE_DESTROY:
+				break;
+
+			case UISWTViewEvent.TYPE_INITIALIZE:
+				initialize((Composite) event.getData());
+				return true;
+
+			case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+				swtView.setTitle(getFullTitle());
+				Messages.updateLanguageForControl(getComposite());
+				break;
+
+			case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+				dataSourceChanged(event.getData());
+				break;
+
+			case UISWTViewEvent.TYPE_REFRESH:
+				break;
+				
+			case UISWTViewEvent.TYPE_OBFUSCATE:
+				Object data = event.getData();
+				if (data instanceof Map) {
+					obfusticatedImage((Image) MapUtils.getMapObject((Map) data, "image",
+							null, Image.class));
+				}
+				break;
+		}
+		
+		if (seedingview != null) {
+    	try {
+    		seedingview.getSWTView().triggerEvent(event.getType(), event.getData());
+    	} catch (Exception e) {
+    		Debug.out(e);
+    	}
+		}
+
+		if (torrentview != null) {
+    	try {
+    		torrentview.getSWTView().triggerEvent(event.getType(), event.getData());
+    	} catch (Exception e) {
+    		Debug.out(e);
+    	}
+		}
+
+		// both subviews will get focusgained, resulting in the last one grabbing
+		// "focus".  We restore last used focus, but only after the subviews are
+		// done being greedy
+		switch (event.getType()) {
+			case UISWTViewEvent.TYPE_FOCUSGAINED:
+				viewActivated();
+				break;
+
+			case UISWTViewEvent.TYPE_FOCUSLOST:
+				viewDeactivated();
+				break;
+		}
+
+		return true;
+	}
+	
+	public UISWTView getSWTView() {
+		return swtView;
+	}
 }
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java b/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
index 9c28abc..12443f9 100644
--- a/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
+++ b/org/gudy/azureus2/ui/swt/views/MyTorrentsView.java
@@ -22,6 +22,8 @@
 
 package org.gudy.azureus2.ui.swt.views;
 
+import java.io.File;
+import java.net.URL;
 import java.util.*;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -37,42 +39,50 @@ import org.gudy.azureus2.core3.category.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfoSet;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerListener;
 import org.gudy.azureus2.core3.global.GlobalManager;
+import org.gudy.azureus2.core3.global.GlobalManagerEvent;
+import org.gudy.azureus2.core3.global.GlobalManagerEventListener;
 import org.gudy.azureus2.core3.global.GlobalManagerListener;
 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.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.download.DownloadTypeComplete;
 import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
-import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
+import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener;
 import org.gudy.azureus2.ui.swt.*;
 import org.gudy.azureus2.ui.swt.URLTransfer;
+import org.gudy.azureus2.ui.swt.components.CompositeMinSize;
 import org.gudy.azureus2.ui.swt.help.HealthHelpWindow;
 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.plugins.UISWTViewEvent;
 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.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
+import org.gudy.azureus2.ui.swt.views.table.painted.TableRowPainted;
+import org.gudy.azureus2.ui.swt.views.utils.CategoryUIUtils;
 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPlugin;
-import com.aelitis.azureus.plugins.net.buddy.BuddyPluginBuddy;
+import com.aelitis.azureus.core.util.RegExUtil;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
-import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.common.table.TableViewFilterCheck;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
-import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 /** Displays a list of torrents in a table view.
  *
@@ -84,7 +94,7 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
  *         2005/Oct/01: Column moving in SWT >= 3.1
  */
 public class MyTorrentsView
-       extends TableViewTab
+       extends TableViewTab<DownloadManager>
        implements GlobalManagerListener,
                   ParameterListener,
                   DownloadManagerListener,
@@ -96,26 +106,115 @@ public class MyTorrentsView
                   TableSelectionListener,
                   TableViewSWTMenuFillListener,
                   TableRefreshListener,
-                  TableCountChangeListener,
-                  TableViewFilterCheck
+                  TableViewFilterCheck.TableViewFilterCheckEx<DownloadManager>,
+                  TableRowRefreshListener,
+                  TableCountChangeListener
 {
 	private static final LogIDs LOGID = LogIDs.GUI;
 	
+	public static volatile Set<String>	preferred_tracker_names;
+	public static volatile boolean		eta_absolute;
+	public static volatile boolean		progress_eta_absolute;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListeners(
+			new String[]{
+				"mtv.trackername.pref.hosts",
+				"mtv.eta.show_absolute",
+				"mtv.progress_eta.show_absolute",
+			},
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					String name )
+				{
+					String prefs = COConfigurationManager.getStringParameter( "mtv.trackername.pref.hosts", null );
+					
+					Set<String>	new_vals = new HashSet<String>();
+					
+					if ( prefs != null ){
+						
+						String[] bits = prefs.split( ";" );
+						
+						for ( String s: bits ){
+							
+							s = s.trim();
+							
+							if ( s.length() > 0 ){
+								
+								new_vals.add( s );
+							}
+						}
+					}
+					
+					preferred_tracker_names = new_vals;
+					
+					eta_absolute			= COConfigurationManager.getBooleanParameter( "mtv.eta.show_absolute", false );
+					progress_eta_absolute	= COConfigurationManager.getBooleanParameter( "mtv.progress_eta.show_absolute", false );
+				}
+			});
+	}
+	
 	private AzureusCore		azureus_core;
 
   private GlobalManager globalManager;
+  
+  	// keep this listener separate class as there is confusion within the globalmanager
+  	// if the same instance is registered as both a GlobalManagerListener and a GlobalManagerEventListener
+  	// yes, I know 
+  
+  private GlobalManagerEventListener gm_event_listener = 
+	  new GlobalManagerEventListener()
+  	{
+		public void 
+		eventOccurred(
+			GlobalManagerEvent event ) 
+		{
+			if ( event.getEventType() == GlobalManagerEvent.ET_REQUEST_ATTENTION ){
+		
+				DownloadManager dm = event.getDownload();
+				
+				if ( isOurDownloadManager( dm )){
+				
+					TableRowCore row = tv.getRow( dm );
+					
+					if ( row != null ){
+						
+						TableRowCore[] existing = tv.getSelectedRows();
+						
+						if ( existing != null ){
+							
+							for ( TableRowCore e: existing ){
+							
+								if ( e != row ){
+								
+									e.setSelected( false );
+								}
+							}
+						}
+						
+						if ( !row.isSelected()){
+						
+							row.setSelected( true );
+						}
+						
+					}
+				}
+			}
+		}
+  	};
+  	
   protected boolean isSeedingView;
 
   private Composite cTablePanel;
   private Font fontButton = null;
-  private Composite cCategories;
-  private ControlAdapter catResizeAdapter;
+  protected Composite cCategories;
   private DragSource dragSource = null;
   private DropTarget dropTarget = null;
-  private Composite cHeader = null;
-  private Label lblHeader = null;
-  private Text txtFilter = null;
-  private Label lblX = null;
+  protected Text txtFilter = null;
+  private TimerEventPeriodic	txtFilterUpdateEvent;
+
   
   private Category currentCategory;
 
@@ -124,16 +223,17 @@ public class MyTorrentsView
   private TableRowCore[] drag_drop_rows = null;
 
 	private boolean bDNDalwaysIncomplete;
-	private TableViewSWT tv;
+	private TableViewSWT<DownloadManager> tv;
 	private Composite cTableParentPanel;
 	protected boolean viewActive;
 	private boolean forceHeaderVisible = false;
 	private TableSelectionListener defaultSelectedListener;
-	private Composite cFilterArea;
-	protected boolean resizeHeaderEventQueued;
-	private Button btnFilter;
 
-	private Composite cSizer;
+	private Composite filterParent;
+
+	private boolean neverShowCatButtons;
+	
+	private boolean rebuildListOnFocusGain = false;
 
 	public MyTorrentsView() {
 		super("MyTorrentsView");
@@ -145,31 +245,35 @@ public class MyTorrentsView
    * @param _azureus_core
    * @param isSeedingView
    * @param basicItems
+   * @param cCats 
    */
   public 
   MyTorrentsView(
   		AzureusCore				_azureus_core,
   		String						tableID,
   		boolean 					isSeedingView,
-      TableColumnCore[]	basicItems) 
+      TableColumnCore[]	basicItems,
+      Text txtFilter, Composite cCats) 
   {
 		super("MyTorrentsView");
-  	init(_azureus_core, tableID, isSeedingView, basicItems);
+		this.txtFilter = txtFilter;
+		this.cCategories = cCats;
+		init(_azureus_core, tableID, isSeedingView, isSeedingView
+				? DownloadTypeComplete.class : DownloadTypeIncomplete.class, basicItems);
   }
   
   // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
-  public TableViewSWT initYourTableView() {
+  public TableViewSWT<DownloadManager> initYourTableView() {
   	return tv;
   }
   
   public void init(AzureusCore _azureus_core, String tableID,
-			boolean isSeedingView, TableColumnCore[] basicItems) {
+			boolean isSeedingView, Class<?> forDataSourceType, TableColumnCore[] basicItems) {
 
   	this.isSeedingView 	= isSeedingView;
   	
-    tv = createTableView(isSeedingView ? DownloadTypeComplete.class
-				: DownloadTypeIncomplete.class, tableID, basicItems);
-    tv.setRowDefaultIconSize(new Point(16, 16));
+    tv = createTableView(forDataSourceType, tableID, basicItems);
+    tv.setRowDefaultHeight(17);
     
     /*
      * 'Big' table has taller row height
@@ -182,15 +286,65 @@ public class MyTorrentsView
     this.globalManager 	= azureus_core.getGlobalManager();
     
 
-    currentCategory = CategoryManager.getCategory(Category.TYPE_ALL);
+    if (currentCategory == null) {
+    	currentCategory = CategoryManager.getCategory(Category.TYPE_ALL);
+    }
     tv.addLifeCycleListener(this);
     tv.setMainPanelCreator(this);
     tv.addSelectionListener(this, false);
     tv.addMenuFillListener(this);
     tv.addRefreshListener(this, false);
-    tv.addCountChangeListener(this);
+    if (tv.canHaveSubItems()) {
+    	tv.addRefreshListener(this);
+    	tv.addCountChangeListener(this);
+    }
     
+    tv.addTableDataSourceChangedListener(new TableDataSourceChangedListener() {
+			public void tableDataSourceChanged(Object newDataSource) {
+				if (newDataSource instanceof Category) {
+		    	neverShowCatButtons = true;
+					activateCategory((Category) newDataSource);
+				}
+			}
+		}, true);
+
     forceHeaderVisible = COConfigurationManager.getBooleanParameter("MyTorrentsView.alwaysShowHeader");
+		if (txtFilter != null) {
+			filterParent = txtFilter.getParent();
+			if (Constants.isWindows) {
+				// dirty hack because window's filter box is within a bubble of it's own
+				filterParent = filterParent.getParent();
+			}
+			Menu menuFilterHeader = new Menu(filterParent);
+			final MenuItem menuItemAlwaysShow = new MenuItem(menuFilterHeader,
+					SWT.CHECK);
+			Messages.setLanguageText(menuItemAlwaysShow,
+					"ConfigView.label.alwaysShowLibraryHeader");
+			menuFilterHeader.addMenuListener(new MenuListener() {
+				public void menuShown(MenuEvent e) {
+					menuItemAlwaysShow.setSelection(forceHeaderVisible);
+				}
+
+				public void menuHidden(MenuEvent e) {
+				}
+			});
+			menuItemAlwaysShow.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					COConfigurationManager.setParameter(
+							"MyTorrentsView.alwaysShowHeader", !forceHeaderVisible);
+				}
+
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+			filterParent.setMenu(menuFilterHeader);
+			Control[] children = filterParent.getChildren();
+			for (Control control : children) {
+				if (control != txtFilter) {
+					control.setMenu(menuFilterHeader);
+				}
+			}
+		}
 
 		//tv.setEnableTabViews(true);
 		//IView views[] = { new GeneralView(), new PeersView(),
@@ -201,7 +355,6 @@ public class MyTorrentsView
 
   // @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized()
   public void tableViewInitialized() {
- 
   	tv.addKeyListener(this);
 
     createTabs();
@@ -212,35 +365,40 @@ public class MyTorrentsView
 
     createDragDrop();
 
-    COConfigurationManager.addAndFireParameterListeners(new String[] {
-			"DND Always In Incomplete",
-			"Confirm Data Delete",
-			"MyTorrentsView.alwaysShowHeader",
-			"User Mode"
-		}, this);
-
-    if (currentCategory != null) {
-    	currentCategory.addCategoryListener(this);
-    }
-    CategoryManager.addCategoryManagerListener(this);
-    globalManager.addListener(this, false);
-    Object[] dms = globalManager.getDownloadManagers().toArray();
-    for (int i = 0; i < dms.length; i++) {
-			DownloadManager dm = (DownloadManager) dms[i];
-			dm.addListener(this);
-			if (!isOurDownloadManager(dm)) {
-				dms[i] = null;
+    Utils.getOffOfSWTThread(new AERunnable() {
+			
+			public void runSupport() {
+		    COConfigurationManager.addAndFireParameterListeners(new String[] {
+					"DND Always In Incomplete",
+					"MyTorrentsView.alwaysShowHeader",
+					"User Mode"
+				}, MyTorrentsView.this);
+
+		    if (currentCategory != null) {
+		    	currentCategory.addCategoryListener(MyTorrentsView.this);
+		    }
+		    CategoryManager.addCategoryManagerListener(MyTorrentsView.this);
+		    globalManager.addListener(MyTorrentsView.this, false);
+		    globalManager.addEventListener( gm_event_listener );
+		    DownloadManager[] dms = globalManager.getDownloadManagers().toArray(new DownloadManager[0]);
+		    for (int i = 0; i < dms.length; i++) {
+					DownloadManager dm = dms[i];
+					dm.addListener(MyTorrentsView.this);
+					if (!isOurDownloadManager(dm)) {
+						dms[i] = null;
+					}
+				}
+		    tv.addDataSources(dms);
+		    tv.processDataSourceQueue();
 			}
-		}
-    tv.addDataSources(dms);
-    tv.processDataSourceQueue();
+		});
     
     cTablePanel.layout();
   }
 
   // @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewDestroyed()
   public void tableViewDestroyed() {
-  	tv.removeKeyListener(this);
+    tv.removeKeyListener(this);
   	
   	Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
@@ -268,8 +426,8 @@ public class MyTorrentsView
     }
     CategoryManager.removeCategoryManagerListener(this);
     globalManager.removeListener(this);
+    globalManager.removeEventListener( gm_event_listener );
     COConfigurationManager.removeParameterListener("DND Always In Incomplete", this);
-    COConfigurationManager.removeParameterListener("Confirm Data Delete", this);
     COConfigurationManager.removeParameterListener("User Mode", this);
   }
   
@@ -280,7 +438,7 @@ public class MyTorrentsView
 			public void handleEvent(Event event) {
 				viewActive = true;
 		    updateSelectedContent();
-		    refreshIconBar();
+		    //refreshIconBar();
 			}
 		});
   	composite.addListener(SWT.Deactivate, new Listener() {
@@ -293,7 +451,7 @@ public class MyTorrentsView
 		});
   	
     GridData gridData;
-    cTableParentPanel = new Composite(composite, SWT.NULL);
+    cTableParentPanel = new Composite(composite, SWT.NONE);
     GridLayout layout = new GridLayout();
     layout.horizontalSpacing = 0;
     layout.verticalSpacing = 0;
@@ -305,8 +463,6 @@ public class MyTorrentsView
     }
     
     cTablePanel = new Composite(cTableParentPanel, SWT.NULL);
-    cTablePanel.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
-    cTablePanel.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
 
     gridData = new GridData(GridData.FILL_BOTH);
     cTablePanel.setLayoutData(gridData);
@@ -330,327 +486,74 @@ public class MyTorrentsView
   }
 
   private void createTabs() {
-    GridData gridData;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_createTabs();
+			}
+		});
+  }
+  
+  private void swt_createTabs() {
     Category[] categories = CategoryManager.getCategories();
     Arrays.sort(categories);
-    boolean showCat = tv.getFilterText().length() > 0;
-    if (!showCat) {
-	    for(int i = 0; i < categories.length; i++) {
-	        if(categories[i].getType() == Category.TYPE_USER) {
-	            showCat = true;
-	            break;
-	        }
-	    }
+    boolean showCat = false;
+    if (!neverShowCatButtons) {
+      for(int i = 0; i < categories.length; i++) {
+          if(categories[i].getType() == Category.TYPE_USER) {
+              showCat = true;
+              break;
+          }
+      }
     }
-    boolean show = showCat || forceHeaderVisible;
 
-    if (!showCat) {
-    	if (cCategories != null && !cCategories.isDisposed()) {
-        Control[] controls = cCategories.getChildren();
-        for (int i = 0; i < controls.length; i++) {
-          controls[i].dispose();
-        }
-    	}
-    }
-    
-    if (show) {
-      if (cCategories == null || cCategories.isDisposed()) {
-      	buildHeaderArea();
-      } else {
-        Control[] controls = cCategories.getChildren();
-        for (int i = 0; i < controls.length; i++) {
-          controls[i].dispose();
-        }
+   	buildHeaderArea();
+  	if (cCategories != null && !cCategories.isDisposed()) {
+      Control[] controls = cCategories.getChildren();
+      for (int i = 0; i < controls.length; i++) {
+        controls[i].dispose();
       }
-      
-      if (showCat) {
-      	buildCat(categories);
-      }
-    } else {
-    	if (cHeader != null && !cHeader.isDisposed()) {
-    		cHeader.dispose();
-    	}
-    	if (cTableParentPanel != null && !cTableParentPanel.isDisposed()) {
-    		cTableParentPanel.layout();
-    	}
-    }
+  	}
+    
+    if (showCat) {
+    	buildCat(categories);
+    } else if (cTableParentPanel != null && !cTableParentPanel.isDisposed()) {
+  		cTableParentPanel.layout();
+  	}
   }
   
-  /**
-	 * 
-	 *
-	 * @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() && !cFilterArea.isVisible()) {
-			cFilterArea.setVisible(true);
-		}
-		if (btnFilter != null && !btnFilter.isDisposed() && !btnFilter.getSelection()) {
-			btnFilter.setSelection(true);
-		}
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 4.1.0.5
-	 */
-	protected void resizeHeader() {
-		if (cCategories == null || cCategories.isDisposed()) {
+		if (cCategories == null) {
+			cCategories = new CompositeMinSize(cTableParentPanel, SWT.NONE);
+			((CompositeMinSize) cCategories).setMinSize(new Point(SWT.DEFAULT, 24));
+			GridData gridData = new GridData(SWT.RIGHT, SWT.TOP, true, false);
+			cCategories.setLayoutData(gridData);
+			cCategories.moveAbove(null);
+		}else if ( cCategories.isDisposed()){
 			return;
 		}
-		Point curCatPos = cCategories.getLocation();
-		int posEndFilter = cFilterArea.getLocation().x + (cFilterArea.isVisible() ? 170 : 0);
-		
-		boolean onNewLine = ((FormData)cCategories.getLayoutData()).left != null;
 		
-		//System.out.println("posend=" + posEndFilter + ";curcat" + curCatPos);
-		if (onNewLine) {
-			Point prefSizeCat = cCategories.computeSize(SWT.DEFAULT, SWT.DEFAULT);
-			//System.out.println("pref=" + prefSizeCat + ";sz=" + cHeader.getClientArea());
-			if (prefSizeCat.x + posEndFilter + cSizer.getSize().x < cHeader.getClientArea().width) {
-				//System.out.println("MOVE UP");
-				FormData 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);
-
-        fd = new FormData();
-        fd.left = new FormAttachment(btnFilter, 0);
-        fd.right = new FormAttachment(cCategories, -10);
-        cFilterArea.setLayoutData(fd);
-
-				cHeader.getShell().layout(new Control[] {
-					cFilterArea,
-					cCategories
-				});
-			}
-			// assume on new line
-		} else {
-			if (curCatPos.x < posEndFilter) {
-				//System.out.println("MOVE DOWN");
-				FormData fd = new FormData();
-				fd.top = new FormAttachment(cFilterArea, 2);
-				fd.bottom = new FormAttachment(100, -3);
-				fd.left = new FormAttachment(0,0);
-				fd.right = new FormAttachment(100,0);
-				cCategories.setLayoutData(fd);
-
-				fd = new FormData();
-        fd.left = new FormAttachment(btnFilter, 0);
-        fd.right = new FormAttachment(cSizer, -10);
-        cFilterArea.setLayoutData(fd);
-
-				cHeader.getShell().layout(new Control[] {
-					cFilterArea,
-					cCategories
-				});
-			}
+		if (!(cCategories.getLayout() instanceof RowLayout)) {
+      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);
 		}
+
+    tv.enableFilterCheck(txtFilter, this);
 	}
 
-	/**
+  /**
 	 * 
 	 *
 	 * @param categories 
    * @since 3.1.1.1
 	 */
 	private void buildCat(Category[] categories) {
-		int iFontPixelsHeight = 11;
+		int iFontPixelsHeight = 10;
 		int iFontPointHeight = (iFontPixelsHeight * 72)
 				/ cCategories.getDisplay().getDPI().y;
 		for (int i = 0; i < categories.length; i++) {
@@ -717,23 +620,23 @@ public class MyTorrentsView
 				public void handleEvent(Event event) {
 					Button curButton = (Button) event.widget;
 					Category curCategory = (Category) curButton.getData("Category");
-					List dms = curCategory.getDownloadManagers(globalManager.getDownloadManagers());
+					List<DownloadManager> dms = curCategory.getDownloadManagers(globalManager.getDownloadManagers());
 
 					long ttlActive = 0;
 					long ttlSize = 0;
 					long ttlRSpeed = 0;
 					long ttlSSpeed = 0;
 					int count = 0;
-					for (Iterator iter = dms.iterator(); iter.hasNext();) {
-						DownloadManager dm = (DownloadManager) iter.next();
+					for (DownloadManager dm : dms) {
 
 						if (!isInCategory(dm, currentCategory))
 							continue;
 
 						count++;
 						if (dm.getState() == DownloadManager.STATE_DOWNLOADING
-								|| dm.getState() == DownloadManager.STATE_SEEDING)
+								|| dm.getState() == DownloadManager.STATE_SEEDING){
 							ttlActive++;
+						}
 						ttlSize += dm.getSize();
 						ttlRSpeed += dm.getStats().getDataReceiveRate();
 						ttlSSpeed += dm.getStats().getDataSendRate();
@@ -776,12 +679,17 @@ public class MyTorrentsView
 							+ ttlActive
 							+ "\n"
 							+ "\n"
-							+ "Speed: "
+							+ "Total Speed: "
+							+ DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlRSpeed)
+							+ " / "
+							+ DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlSSpeed)
+							+ "\n"
+							+ "Average Speed: "
 							+ DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlRSpeed
-									/ count)
-							+ "/"
+									/ (ttlActive==0?1:ttlActive))
+							+ " / "
 							+ DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlSSpeed
-									/ count)
+									/ (ttlActive==0?1:ttlActive))
 							+ "\n"
 							+ "Size: "
 							+ DisplayFormatters.formatByteCountToKiBEtc(ttlSize));
@@ -796,346 +704,45 @@ public class MyTorrentsView
 			tabDropTarget.setTransfer(types);
 			tabDropTarget.addDropListener(new DropTargetAdapter() {
 				public void dragOver(DropTargetEvent e) {
-					if (drag_drop_line_start >= 0)
+					//System.out.println("dragging over: " + drag_drop_line_start);
+					if (drag_drop_line_start >= 0) {
 						e.detail = DND.DROP_MOVE;
-					else
+					} else {
 						e.detail = DND.DROP_NONE;
+					}
 				}
 
 				public void drop(DropTargetEvent e) {
 					e.detail = DND.DROP_NONE;
 					//System.out.println("DragDrop on Button:" + drag_drop_line_start);
-					if (drag_drop_line_start >= 0) {
-						drag_drop_line_start = -1;
-						drag_drop_rows = null;
-
-						TorrentUtil.assignToCategory(tv.getSelectedDataSources().toArray(),
-								(Category) catButton.getData("Category"));
-					}
-				}
-			});
-
-			catButton.addDisposeListener(new DisposeListener() {
-				public void widgetDisposed(DisposeEvent e) {
-					if (tabDropTarget != null && !tabDropTarget.isDisposed()) {
-						tabDropTarget.dispose();
-					}
-				}
-			});
-
-			final Menu menu = new Menu(catButton.getShell(), SWT.POP_UP);
-
-			catButton.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;
-
-					if (category.getType() == Category.TYPE_USER) {
-
-						final MenuItem itemDelete = new MenuItem(menu, SWT.PUSH);
-
-						Messages.setLanguageText(itemDelete,
-								"MyTorrentsView.menu.category.delete");
-
-						menu.setDefaultItem(itemDelete);
-
-						itemDelete.addListener(SWT.Selection, new Listener() {
-							public void handleEvent(Event event) {
-								Category catToDelete = (Category) catButton.getData("Category");
-								if (catToDelete != null) {
-									java.util.List managers = catToDelete.getDownloadManagers(globalManager.getDownloadManagers());
-									// move to array,since setcategory removed it from the category,
-									// which would mess up our loop
-									DownloadManager dms[] = (DownloadManager[]) managers.toArray(new DownloadManager[managers.size()]);
-									for (int i = 0; i < dms.length; i++) {
-										dms[i].getDownloadState().setCategory(null);
-									}
-									if (currentCategory == catToDelete) {
-
-										activateCategory(CategoryManager.getCategory(Category.TYPE_ALL));
-
-									} else {
-										// always activate as deletion of this one might have
-										// affected the current view 
-										activateCategory(currentCategory);
-									}
-									CategoryManager.removeCategory(catToDelete);
-								}
-							}
-						});
-					}
-
-					if (category.getType() != Category.TYPE_ALL) {
-
-						long maxDownload = COConfigurationManager.getIntParameter(
-								"Max Download Speed KBs", 0) * 1024;
-						long maxUpload = COConfigurationManager.getIntParameter(
-								"Max Upload Speed KBs", 0) * 1024;
-
-						int down_speed = category.getDownloadSpeed();
-						int up_speed = category.getUploadSpeed();
-
-						ViewUtils.addSpeedMenu(menu.getShell(), menu, true, true, false,
-								down_speed == 0, down_speed, down_speed, maxDownload, false,
-								up_speed == 0, up_speed, up_speed, maxUpload, 1,
-								new SpeedAdapter() {
-									public void setDownSpeed(int val) {
-										category.setDownloadSpeed(val);
-									}
-
-									public void setUpSpeed(int val) {
-										category.setUploadSpeed(val);
-
-									}
-								});
-					}
-
-					java.util.List managers = category.getDownloadManagers(globalManager.getDownloadManagers());
-
-					final DownloadManager dms[] = (DownloadManager[]) managers.toArray(new DownloadManager[managers.size()]);
-
-					boolean start = false;
-					boolean stop = false;
-
-					for (int i = 0; i < dms.length; i++) {
-
-						DownloadManager dm = dms[i];
-
-						stop = stop || ManagerUtils.isStopable(dm);
-
-						start = start || ManagerUtils.isStartable(dm);
-
-					}
-
-					// Queue
-
-					final MenuItem itemQueue = new MenuItem(menu, SWT.PUSH);
-					Messages.setLanguageText(itemQueue, "MyTorrentsView.menu.queue");
-					Utils.setMenuItemImage(itemQueue, "start");
-					itemQueue.addListener(SWT.Selection, new Listener() {
-						public void handleEvent(Event event) {
-							TorrentUtil.queueTorrents(dms, menu.getShell());
-						}
-					});
-					itemQueue.setEnabled(start);
-
-					// Stop
-
-					final MenuItem itemStop = new MenuItem(menu, SWT.PUSH);
-					Messages.setLanguageText(itemStop, "MyTorrentsView.menu.stop");
-					Utils.setMenuItemImage(itemStop, "stop");
-					itemStop.addListener(SWT.Selection, new Listener() {
-						public void handleEvent(Event event) {
-							TorrentUtil.stopTorrents(dms, menu.getShell());
-						}
-					});
-					itemStop.setEnabled(stop);
-
-					// share with friends
-					
-					PluginInterface bpi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByClass( BuddyPlugin.class );
-					
-					int cat_type = category.getType();
-					
-					if ( bpi != null && cat_type != Category.TYPE_UNCATEGORIZED ){
-						
-						final BuddyPlugin	buddy_plugin = (BuddyPlugin)bpi.getPlugin();
-						
-						if ( buddy_plugin.isEnabled()){
-							
-							final Menu share_menu = new Menu(menu.getShell(), SWT.DROP_DOWN);
-							final MenuItem share_item = new MenuItem(menu, SWT.CASCADE);
-							Messages.setLanguageText(share_item, "azbuddy.ui.menu.cat.share" );
-							share_item.setMenu(share_menu);
-
-							List<BuddyPluginBuddy> buddies = buddy_plugin.getBuddies();
-
-							if ( buddies.size() == 0 ){
-								
-								final MenuItem item = new MenuItem(share_menu, SWT.CHECK );
-								
-								item.setText( MessageText.getString( "general.add.friends" ));
-								
-								item.setEnabled( false );
-
-							}else{
-								final String cname;
-								
-								if ( cat_type == Category.TYPE_ALL ){
-									
-									cname = "All";
-									
-								}else{
-									
-									cname = category.getName();
-								}
-	
-								final boolean is_public = buddy_plugin.isPublicCategory( cname );
-							
-								final MenuItem itemPubCat = new MenuItem(share_menu, SWT.CHECK );
-								
-								Messages.setLanguageText( itemPubCat, "general.all.friends" );
-								
-								itemPubCat.setSelection( is_public );
-								
-								itemPubCat.addListener(
-									SWT.Selection, 
-									new Listener() 
-									{
-										public void 
-										handleEvent(
-											Event event) 
-										{
-											if ( is_public ){
-											
-												buddy_plugin.removePublicCategory( cname );
-												
-											}else{
-												
-												buddy_plugin.addPublicCategory( cname );
-											}
-										}
-									});
-								
-								new MenuItem(share_menu, SWT.SEPARATOR );
-															
-								for ( final BuddyPluginBuddy buddy: buddies ){
-									
-									if ( buddy.getNickName() == null ){
-										
-										continue;
-									}
-																	
-									final boolean auth = buddy.isLocalRSSCategoryAuthorised( cname );
-									
-									final MenuItem itemShare = new MenuItem(share_menu, SWT.CHECK );
-									
-									itemShare.setText( buddy.getName());
-									
-									itemShare.setSelection( auth || is_public );
-									
-									if ( is_public ){
-										
-										itemShare.setEnabled( false );
-									}
-									
-									itemShare.addListener(
-										SWT.Selection, 
-										new Listener() 
-										{
-											public void 
-											handleEvent(
-												Event event) 
-											{
-												if ( auth ){
-												
-													buddy.removeLocalAuthorisedRSSCategory( cname );
-													
-												}else{
-													
-													buddy.addLocalAuthorisedRSSCategory( cname );
-												}
-											}
-										});
-									
-								}
-							}
-						}
-					}
-					
-					// options
-
-					MenuItem itemOptions = new MenuItem(menu, SWT.PUSH);
-
-					Messages.setLanguageText(itemOptions,
-							"MainWindow.menu.view.configuration");
-					itemOptions.addListener(SWT.Selection, new Listener() {
-						public void handleEvent(Event event) {
-							UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-
-							uiFunctions.openView(UIFunctions.VIEW_DM_MULTI_OPTIONS, dms);
-						}
-					});
+					if (drag_drop_line_start >= 0) {
+						drag_drop_line_start = -1;
+						drag_drop_rows = null;
 
-					if (dms.length == 0) {
+						TorrentUtil.assignToCategory(tv.getSelectedDataSources().toArray(),
+								(Category) catButton.getData("Category"));
+					}
+				}
+			});
 
-						itemOptions.setEnabled(false);
+			catButton.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					if (!tabDropTarget.isDisposed()) {
+						tabDropTarget.dispose();
 					}
 				}
 			});
-		}
 
-		cHeader.layout(true, true);
-		Utils.execSWTThreadLater(0, new AERunnable(){
-			public void runSupport() {
-				resizeHeader();
-			}
-		});
+			final Menu menu = new Menu(catButton.getShell(), SWT.POP_UP);
 
-		// layout hack - relayout
-//		if (catResizeAdapter == null) {
-//			catResizeAdapter = new ControlAdapter() {
-//				public void controlResized(ControlEvent event) {
-//					if (getComposite().isDisposed() || cCategories.isDisposed())
-//						return;
-//
-//					GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
-//
-//					int parentWidth = cCategories.getParent().getClientArea().width;
-//					int catsWidth = cCategories.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
-//					// give text a 5 pixel right padding
-//					int textWidth = 200;
-//					System.out.println("TW=" + textWidth + ";" + (cHeader.computeSize(20, SWT.DEFAULT).x));
-//
-//					Object layoutData = cHeader.getLayoutData();
-//					if (layoutData instanceof GridData) {
-//						GridData labelGrid = (GridData) layoutData;
-//						textWidth += labelGrid.horizontalIndent;
-//					}
-//
-//					if (textWidth + catsWidth > parentWidth) {
-//						gridData.widthHint = parentWidth - textWidth;
-//					}
-//					cCategories.setLayoutData(gridData);
-//					cCategories.getParent().layout(true);
-//
-//				}
-//			};
-//
-//			tv.getTableComposite().addControlListener(catResizeAdapter);
-//		}
-//
-//		catResizeAdapter.controlResized(null);
-	}
+			catButton.setMenu(menu);
 
+			CategoryUIUtils.setupCategoryMenu(menu, category);
+		}
+		
+		cCategories.getParent().layout(true, true);
+	}
+	
 	public boolean isOurDownloadManager(DownloadManager dm) {
   	if (!isInCategory(dm, currentCategory)) {
   		return false;
@@ -1153,91 +760,274 @@ public class MyTorrentsView
 		return bOurs;
 	}
 
-	public boolean filterCheck(Object odm, String sLastSearch, boolean bRegexSearch) {
-		boolean bOurs = true;
-		DownloadManager dm = (DownloadManager) odm;
-
+	public boolean filterCheck(DownloadManager dm, String sLastSearch, boolean bRegexSearch) {
+		boolean bOurs;
 		if (sLastSearch.length() > 0) {
 			try {
-				String[][] names = {
+				String	comment = dm.getDownloadState().getUserComment();
+				if ( comment == null ){
+					comment = "";
+				}
+				
+				String[][] name_mapping = {
 					{
 						"",
 						dm.getDisplayName()
 					},
 					{
 						"t:",
-						dm.getTorrent().getAnnounceURL().getHost()
+						"", 	// defer (index = 1)this as costly dm.getTorrent().getAnnounceURL().getHost()
 					},
 					{
 						"st:",
 						"" + dm.getState()
+					},
+					{
+						"c:",
+						comment
+					},
+					{
+						"f:",
+						"",		//defer (index = 4)
 					}
 				};
 
-				String name = names[0][1];
+				Object o_name = name_mapping[0][1];
+				
 				String tmpSearch = sLastSearch;
 
-				for (int i = 0; i < names.length; i++) {
-					if (tmpSearch.startsWith(names[i][0])) {
-						tmpSearch = tmpSearch.substring(names[i][0].length());
-						name = names[i][1];
+				for ( int i = 1; i < name_mapping.length; i++ ){
+					
+					if ( tmpSearch.startsWith(name_mapping[i][0])) {
+						
+						tmpSearch = tmpSearch.substring(name_mapping[i][0].length());
+						
+						if ( i == 1 ){
+							
+							List<String> names = new ArrayList<String>();
+							
+							o_name = names;
+							
+							TOTorrent t = dm.getTorrent();
+														
+							names.add( t.getAnnounceURL().getHost());
+							
+							TOTorrentAnnounceURLSet[] sets = t.getAnnounceURLGroup().getAnnounceURLSets();
+							
+							for ( TOTorrentAnnounceURLSet set: sets ){
+								
+								URL[] urls = set.getAnnounceURLs();
+								
+								for ( URL u: urls ){
+									
+									names.add( u.getHost());
+								}
+							}
+							
+						}else if ( i == 4 ){
+							
+							List<String> names = new ArrayList<String>();
+							
+							o_name = names;
+							
+							DiskManagerFileInfoSet file_set = dm.getDiskManagerFileInfoSet();
+							
+							DiskManagerFileInfo[] files = file_set.getFiles();
+							
+							for ( DiskManagerFileInfo f: files ){
+								
+								File file = f.getFile(true);
+
+								String name = tmpSearch.contains( File.separator )?file.getAbsolutePath():file.getName();
+								
+								names.add( name );
+							}
+						}else{
+							o_name = name_mapping[i][1];
+						}
 					}
 				}
 
 				String s = bRegexSearch ? tmpSearch : "\\Q"
 						+ tmpSearch.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E";
-				Pattern pattern = Pattern.compile(s, Pattern.CASE_INSENSITIVE);
+				
+				boolean	match_result = true;
+				
+				if ( bRegexSearch && s.startsWith( "!" )){
+					s = s.substring(1);
+					
+					match_result = false;
+				}
+				
+				Pattern pattern = RegExUtil.getCachedPattern( "tv:search", s, Pattern.CASE_INSENSITIVE);
 
-				if (!pattern.matcher(name).find())
-					bOurs = false;
+				if ( o_name instanceof String ){
+					
+					bOurs = pattern.matcher((String)o_name).find() == match_result;
+					
+				}else{
+					List<String>	names = (List<String>)o_name;
+					
+						// match_result: true -> at least one match; false -> any fail
+					
+					bOurs = !match_result;
+					
+					for ( String name: names ){
+						if ( pattern.matcher( name ).find()){
+							bOurs = match_result;
+							break;
+						}
+					}
+				}
 			} catch (Exception e) {
 				// Future: report PatternSyntaxException message to user.
+				
+				bOurs = true;
 			}
+		}else{
+			
+			bOurs = true;
 		}
+		
 		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(){
+		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 (txtFilter != null) {
+					boolean visible = forceHeaderVisible || filter.length() > 0;
+					Object layoutData = filterParent.getLayoutData();
+					if (layoutData instanceof FormData) {
+						FormData fd = (FormData) layoutData;
+						boolean wasVisible = fd.height != 0;
+						if (visible != wasVisible) {
+  						fd.height = visible ? SWT.DEFAULT : 0;
+  						filterParent.setLayoutData(layoutData);
+  						filterParent.getParent().layout();
+						}
+					}
+					if (!visible) {
+						tv.setFocus();
+					}
+					
+					Object x = filterParent.getData( "ViewUtils:ViewTitleExtraInfo" );
+					
+					if ( x instanceof ViewUtils.ViewTitleExtraInfo ){
+						
+						boolean	enabled = filter.length() > 0;
+						
+						if ( enabled ){
+							
+							if ( txtFilterUpdateEvent == null ){
+								
+								txtFilterUpdateEvent = 
+									SimpleTimer.addPeriodicEvent(
+										"MTV:updater",
+										1000,
+										new TimerEventPerformer()
+										{
+											public void 
+											perform(
+												TimerEvent event )
+											{
+												Utils.execSWTThread(
+													new AERunnable() 
+													{
+														public void
+														runSupport()
+														{
+															if ( txtFilterUpdateEvent != null ){
+																
+																if ( tv.isDisposed()){
+																	
+																	txtFilterUpdateEvent.cancel();
+																	
+																	txtFilterUpdateEvent = null;
+																	
+																}else{
+																	
+																	viewChanged( tv );
+																}
+															}
+														}
+													});
+											}
+										});
+							}
+						}else{
+							
+							if ( txtFilterUpdateEvent != null ){
+								
+								txtFilterUpdateEvent.cancel();
+								
+								txtFilterUpdateEvent = null;
+							}
+						}
+						
+						((ViewUtils.ViewTitleExtraInfo)x).setEnabled( tv.getComposite(), isSeedingView, enabled );
 					}
 				}
+			}
+		});
+	}
+	
+	public void 
+	viewChanged(
+		final TableView<DownloadManager> view ) 
+	{
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_viewChanged(view);
+			}
+		});
+	}
+	
+	private void swt_viewChanged(final TableView<DownloadManager> view) {
 
-				if (filter.length() > 0) {
-					if (txtFilter == null) {
-				    createTabs();
-					} else {
-						showFilterArea();
+		if ( filterParent != null && !filterParent.isDisposed()){
+			Object x = filterParent.getData( "ViewUtils:ViewTitleExtraInfo" );
+		
+			if ( x instanceof ViewUtils.ViewTitleExtraInfo ){
+				
+				TableRowCore[] rows = view.getRows();
+				
+				int	active = 0;
+				
+				for ( TableRowCore row: rows ){
+					
+					DownloadManager dm = (DownloadManager)row.getDataSource( true );
+					
+					int	state = dm.getState();
+					
+					if ( state == DownloadManager.STATE_DOWNLOADING || state == DownloadManager.STATE_SEEDING ){
+						
+						active++;
 					}
 				}
+				
+				((ViewUtils.ViewTitleExtraInfo)x).update( tv.getComposite(), isSeedingView, rows.length, active );
 			}
-		});
+		}
 	}
 
   // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[])
   public void selected(TableRowCore[] rows) {
   	updateSelectedContent();
   	refreshTorrentMenu();
-  	refreshIconBar();
   }
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#deselected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void deselected(TableRowCore[] rows) {
   	updateSelectedContent();
   	refreshTorrentMenu();
-  	refreshIconBar();
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#focusChanged(com.aelitis.azureus.ui.common.table.TableRowCore)
 	public void focusChanged(TableRowCore focus) {
-  	refreshIconBar();
+		updateSelectedContent();
   	refreshTorrentMenu();
 	}
 
@@ -1250,41 +1040,36 @@ public class MyTorrentsView
 	}
 
 	public void updateSelectedContent() {
-		if (cTablePanel == null || cTablePanel.isDisposed()
-				|| !cTablePanel.isVisible()) {
+		updateSelectedContent( false );
+	}
+	
+	public void updateSelectedContent( boolean force ) {
+		if (cTablePanel == null || cTablePanel.isDisposed()) {
 			return;
 		}
-		DownloadManager[] dms = getSelectedDownloads();
-		ISelectedContent[] sc = new ISelectedContent[dms.length];
-		int pos = 0;
-		for (int i = 0; i < dms.length; i++) {
-			DownloadManager dm = dms[i];
-			if (dm != null) {
-				try {
-					sc[pos] = new SelectedContent(dm);
-					pos++;
-				} catch (Exception e) {
-				}
+			// if we're not active then ignore this update as we don't want invisible components
+			// updating the toolbar with their invisible selection. Note that unfortunately the 
+			// call we get here when activating a view does't yet have focus
+		
+		if ( !isTableFocus()){
+			if ( !force ){
+				return;
 			}
 		}
-		if (pos != dms.length) {
-			ISelectedContent[] sc_temp = new ISelectedContent[pos];
-			
-			System.arraycopy(sc, 0, sc_temp, 0, pos);
-			
-			sc = sc_temp;
+		Object[] dataSources = tv.getSelectedDataSources(true);
+		List<SelectedContent> listSelected = new ArrayList<SelectedContent>(dataSources.length);
+		for (Object ds : dataSources) {
+			if (ds instanceof DownloadManager) {
+				listSelected.add(new SelectedContent((DownloadManager) ds));
+			} else if (ds instanceof DiskManagerFileInfo) {
+				DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+				listSelected.add(new SelectedContent(fileInfo.getDownloadManager(), fileInfo.getIndex()));
+			}
 		}
-		SelectedContentManager.changeCurrentlySelectedContent(tv.getTableID(), sc, tv);
+		SelectedContent[] content = listSelected.toArray(new SelectedContent[0]);
+		SelectedContentManager.changeCurrentlySelectedContent(tv.getTableID(), content, tv);
 	}
 	
-  private void refreshIconBar() {
-  	computePossibleActions();
-  	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
-  	if (uiFunctions != null) {
-  		uiFunctions.refreshIconBar();
-  	}
-  }
-  
 	private void refreshTorrentMenu() {
 		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 		if (uiFunctions != null && uiFunctions instanceof UIFunctionsSWT) {
@@ -1294,9 +1079,13 @@ public class MyTorrentsView
 	
 	public DownloadManager[] getSelectedDownloads() {
 		Object[] data_sources = tv.getSelectedDataSources().toArray();
-		DownloadManager[] result = new DownloadManager[data_sources.length];
-		System.arraycopy(data_sources, 0, result, 0, result.length);
-		return result;
+		List<DownloadManager> list = new ArrayList<DownloadManager>();
+		for (Object ds : data_sources) {
+			if (ds instanceof DownloadManager) {
+				list.add((DownloadManager) ds);
+			}
+		}
+		return list.toArray(new DownloadManager[0]);
 	}
 
   // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[])
@@ -1312,12 +1101,11 @@ public class MyTorrentsView
 		Object[] dm_sources = tv.getSelectedDataSources().toArray();
 		UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
 		for (int i = 0; i < dm_sources.length; i++) {
-			if (dm_sources[i] == null) {
+			if (!(dm_sources[i] instanceof DownloadManager)) {
 				continue;
 			}
 			if (uiFunctions != null) {
-				uiFunctions.openView(UIFunctions.VIEW_DM_DETAILS,
-						(DownloadManager) dm_sources[i]);
+				uiFunctions.openView(UIFunctions.VIEW_DM_DETAILS, dm_sources[i]);
 			}
 		}  	
   }
@@ -1342,19 +1130,82 @@ public class MyTorrentsView
         }
       });
 
+    }else if (sColumnName.equals("trackername")) {
+        MenuItem item = new MenuItem(menuThisColumn, SWT.PUSH);
+        Messages.setLanguageText(item, "MyTorrentsView.menu.trackername.editprefs");
+        item.addListener(SWT.Selection, new Listener() {
+          public void handleEvent(Event e) {
+      		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+    				"trackername.prefs.title", "trackername.prefs.message");
+      		entryWindow.setPreenteredText( COConfigurationManager.getStringParameter( "mtv.trackername.pref.hosts", "" ), true );
+      		entryWindow.selectPreenteredText( false );
+    		entryWindow.prompt();
+    		if (entryWindow.hasSubmittedInput()) {
+    			String text = entryWindow.getSubmittedInput();
+    			
+    			COConfigurationManager.setParameter( "mtv.trackername.pref.hosts", text.trim());
+    		}
+          }
+        });
+
+    }else if (sColumnName.equals("eta")) {
+        final MenuItem item = new MenuItem(menuThisColumn, SWT.CHECK );
+        Messages.setLanguageText(item, "MyTorrentsView.menu.eta.abs");
+        item.setSelection( eta_absolute );
+                
+        item.addListener(SWT.Selection, new Listener() {
+          public void handleEvent(Event e) {
+        	eta_absolute = item.getSelection();
+            tv.columnInvalidate("eta");
+            tv.refreshTable(false);
+            COConfigurationManager.setParameter( "mtv.eta.show_absolute", eta_absolute );
+          }
+        });
+    }else if ( sColumnName.equals( "ProgressETA" )) {
+        final MenuItem item = new MenuItem(menuThisColumn, SWT.CHECK );
+        Messages.setLanguageText(item, "MyTorrentsView.menu.eta.abs");
+        item.setSelection( progress_eta_absolute );
+                
+        item.addListener(SWT.Selection, new Listener() {
+          public void handleEvent(Event e) {
+        	progress_eta_absolute = item.getSelection();
+            tv.columnInvalidate("ProgressETA");
+            tv.refreshTable(false);
+            COConfigurationManager.setParameter( "mtv.progress_eta.show_absolute", progress_eta_absolute );
+          }
+        });
     }
   }
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener#fillMenu(java.lang.String, org.eclipse.swt.widgets.Menu)
 	public void fillMenu(String sColumnName, final Menu menu) {
-		Object[] dm_items = tv.getSelectedDataSources().toArray();
-		boolean hasSelection = (dm_items.length > 0);
+		Object[] dataSources = tv.getSelectedDataSources(true);
+		DownloadManager[] dms = getSelectedDownloads();
+		
+		if (dms.length == 0 && dataSources.length > 0) {
+  		List<DiskManagerFileInfo> listFileInfos = new ArrayList<DiskManagerFileInfo>();
+  		DownloadManager firstFileDM = null;
+  		for (Object ds : dataSources) {
+  			if (ds instanceof DiskManagerFileInfo) {
+  				DiskManagerFileInfo info = (DiskManagerFileInfo) ds;
+  				// for now, FilesViewMenuUtil.fillmenu can only handle one DM
+  				if (firstFileDM != null && !firstFileDM.equals(info.getDownloadManager())) {
+  					break;
+  				}
+  				firstFileDM = info.getDownloadManager();
+  				listFileInfos.add(info);
+  			}
+  		}
+  		if (listFileInfos.size() > 0) {
+  			FilesViewMenuUtil.fillMenu(tv, menu, firstFileDM,
+  					listFileInfos.toArray(new DiskManagerFileInfo[0]));
+  			return;
+  		}
+		}
+		
+		boolean hasSelection = (dms.length > 0);
 
 		if (hasSelection) {
-			DownloadManager[] dms = new DownloadManager[dm_items.length];
-			for (int i = 0; i < dm_items.length; i++) {
-				dms[i] = (DownloadManager) dm_items[i];
-			}
 			TorrentUtil.fillTorrentMenu(menu, dms, azureus_core, cTablePanel, true,
 					(isSeedingView) ? 2 : 1, tv);
 
@@ -1386,7 +1237,7 @@ public class MyTorrentsView
 						TableRowCore[] rows = tv.getSelectedRows();
 						if (rows.length != 0) {
 							event.doit = true;
-							// System.out.println("DragStart");
+							//System.out.println("DragStart");
 							drag_drop_line_start = rows[0].getIndex();
 							drag_drop_rows = rows;
 						} else {
@@ -1397,17 +1248,38 @@ public class MyTorrentsView
 
 						// Build eventData here because on OSX, selection gets cleared
 						// by the time dragSetData occurs
-						DownloadManager[] selectedDownloads = getSelectedDownloads();
-						eventData = "DownloadManager\n";
-						for (int i = 0; i < selectedDownloads.length; i++) {
-							DownloadManager dm = selectedDownloads[i];
-							
-							TOTorrent torrent = dm.getTorrent();
-							try {
-								eventData += torrent.getHashWrapper().toBase32String() + "\n";
-							} catch (Exception e) {
+						boolean onlyDMs = true;
+						StringBuffer sb = new StringBuffer();
+						Object[] selectedDataSources = tv.getSelectedDataSources(true);
+						for (Object ds : selectedDataSources) {
+							if (ds instanceof DownloadManager) {
+								DownloadManager dm = (DownloadManager) ds;
+								TOTorrent torrent = dm.getTorrent();
+								if (torrent != null) {
+									try {
+										sb.append(torrent.getHashWrapper().toBase32String());
+										sb.append('\n');
+									} catch (TOTorrentException e) {
+									}
+								}
+							} else if (ds instanceof DiskManagerFileInfo) {
+								DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+								DownloadManager dm = fileInfo.getDownloadManager();
+								TOTorrent torrent = dm.getTorrent();
+								if (torrent != null) {
+									try {
+										sb.append(torrent.getHashWrapper().toBase32String());
+										sb.append(';');
+										sb.append(fileInfo.getIndex());
+										sb.append('\n');
+										onlyDMs = false;
+									} catch (TOTorrentException e) {
+									}
+								}
 							}
 						}
+						
+						eventData = (onlyDMs ? "DownloadManager\n" : "DiskManagerFileInfo\n") + sb.toString();
 					}
 
 					public void dragSetData(DragSourceEvent event) {
@@ -1425,6 +1297,7 @@ public class MyTorrentsView
 						TextTransfer.getInstance() });
 
 				dropTarget.addDropListener(new DropTargetAdapter() {
+					Point enterPoint = null;
 					public void dropAccept(DropTargetEvent event) {
 						event.currentDataType = URLTransfer.pickBestType(event.dataTypes,
 								event.currentDataType);
@@ -1442,21 +1315,53 @@ public class MyTorrentsView
 							}
 						} else if (TextTransfer.getInstance().isSupportedType(
 								event.currentDataType)) {
-							event.detail = event.item == null ? DND.DROP_NONE : DND.DROP_MOVE;
-							event.feedback = DND.FEEDBACK_SCROLL | DND.FEEDBACK_INSERT_BEFORE;
+							event.detail = tv.getTableRowWithCursor() == null ? DND.DROP_NONE : DND.DROP_MOVE;
+							event.feedback = DND.FEEDBACK_SCROLL;
+							enterPoint = new Point(event.x, event.y);
 						}
 					}
+					
+					// @see org.eclipse.swt.dnd.DropTargetAdapter#dragLeave(org.eclipse.swt.dnd.DropTargetEvent)
+					public void dragLeave(DropTargetEvent event) {
+						super.dragLeave(event);
+
+						tv.getComposite().redraw();
+					}
 
 					public void dragOver(DropTargetEvent event) {
 						if (drag_drop_line_start >= 0) {
-							event.detail = event.item == null ? DND.DROP_NONE : DND.DROP_MOVE;
-							event.feedback = DND.FEEDBACK_SCROLL | DND.FEEDBACK_INSERT_BEFORE;
+							if (drag_drop_rows.length > 0
+									&& !(drag_drop_rows[0].getDataSource(true) instanceof DownloadManager)) {
+								event.detail = DND.DROP_NONE;
+								return;
+							}
+							TableRowCore row = tv.getTableRowWithCursor();
+							if (row instanceof TableRowPainted) {
+  							Rectangle bounds = ((TableRowPainted) row).getBounds();
+  							tv.getComposite().redraw();
+  							tv.getComposite().update();
+  							GC gc = new GC(tv.getComposite());
+  							gc.setLineWidth(2);
+  							gc.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
+  							gc.dispose();
+							}
+							event.detail = row == null ? DND.DROP_NONE : DND.DROP_MOVE;
+							event.feedback = DND.FEEDBACK_SCROLL
+									| ((enterPoint != null && enterPoint.y > event.y)
+											? DND.FEEDBACK_INSERT_BEFORE : DND.FEEDBACK_INSERT_AFTER);
 						}
 					}
 
 					public void drop(DropTargetEvent event) {
-						if (!(event.data instanceof String)
-								|| !((String) event.data).startsWith("DownloadManager\n")) {
+						if (!(event.data instanceof String)) {
+							TorrentOpener.openDroppedTorrents(event, true);
+							return;
+						}
+						String data = (String) event.data;
+						if (data.startsWith("DiskManagerFileInfo\n")) {
+							return;
+						}
+						if (!data.startsWith("DownloadManager\n")) {
 							TorrentOpener.openDroppedTorrents(event, true);
 							return;
 						}
@@ -1468,6 +1373,9 @@ public class MyTorrentsView
 							TableRowCore row = tv.getRow(event);
 							if (row == null)
 								return;
+							if (row.getParentRowCore() != null) {
+								row = row.getParentRowCore();
+							}
 							int drag_drop_line_end = row.getIndex();
 							if (drag_drop_line_end != drag_drop_line_start) {
 								DownloadManager dm = (DownloadManager) row.getDataSource(true);
@@ -1497,10 +1405,11 @@ public class MyTorrentsView
 
     for (int i = 0; i < rows.length; i++) {
 			TableRowCore row = rows[i];
-      DownloadManager dm = (DownloadManager)row.getDataSource(true);
-      if (dm == null) {
+      Object ds = row.getDataSource(true);
+      if (!(ds instanceof DownloadManager)) {
       	continue;
       }
+      DownloadManager dm = (DownloadManager) ds;
       int iOldPos = dm.getPosition();
       
       globalManager.moveTo(dm, iNewPos);
@@ -1513,7 +1422,7 @@ public class MyTorrentsView
       }
     }
 
-    boolean bForceSort = sortColumn.getName().equals("#");
+    boolean bForceSort = sortColumn == null ? false : sortColumn.getName().equals("#");
     tv.columnInvalidate("#");
     tv.refreshTable(bForceSort);
   }
@@ -1608,8 +1517,11 @@ public class MyTorrentsView
 					e.doit = false;
 					break;
 				case 's': // CTRL+S stop selected Torrents
-					TorrentUtil.stopTorrents(tv.getSelectedDataSources().toArray(),
-							cTablePanel.getShell());
+					Utils.getOffOfSWTThread(new AERunnable() {
+						public void runSupport() {
+							TorrentUtil.stopDataSources(tv.getSelectedDataSources().toArray());
+						}
+					});
 					e.doit = false;
 					break;
 			}
@@ -1617,10 +1529,21 @@ public class MyTorrentsView
 			if (!e.doit)
 				return;
 		}
+		
+		if (e.keyCode == SWT.F2 && (e.stateMask & SWT.MODIFIER_MASK) == 0) {
+			FilesViewMenuUtil.rename(tv, null,tv.getSelectedDataSources(true), true, false);
+			e.doit = false;
+			return;
+		}
 
+		
 		// DEL remove selected Torrents
 		if (e.stateMask == 0 && e.keyCode == SWT.DEL && e.widget != txtFilter) {
-			TorrentUtil.removeTorrents(tv.getSelectedDataSources().toArray(), cTablePanel.getShell());
+			Utils.getOffOfSWTThread(new AERunnable() {
+				public void runSupport() {
+					TorrentUtil.removeDataSources(tv.getSelectedDataSources().toArray());
+				}
+			});
 			e.doit = false;
 			return;
 		}
@@ -1641,14 +1564,14 @@ public class MyTorrentsView
 
   private void moveSelectedTorrentsDown() {
     // Don't use runForSelectDataSources to ensure the order we want
-    Object[] dataSources = tv.getSelectedDataSources().toArray();
-    Arrays.sort(dataSources, new Comparator() {
-      public int compare (Object a, Object b) {
-        return ((DownloadManager)a).getPosition() - ((DownloadManager)b).getPosition();
-      }
+  	DownloadManager[] dms = getSelectedDownloads();
+    Arrays.sort(dms, new Comparator<DownloadManager>() {
+			public int compare(DownloadManager a, DownloadManager b) {
+        return a.getPosition() - b.getPosition();
+			}
     });
-    for (int i = dataSources.length - 1; i >= 0; i--) {
-      DownloadManager dm = (DownloadManager)dataSources[i];
+    for (int i = dms.length - 1; i >= 0; i--) {
+      DownloadManager dm = dms[i];
       if (dm.getGlobalManager().isMoveableDown(dm)) {
         dm.getGlobalManager().moveDown(dm);
       }
@@ -1661,14 +1584,14 @@ public class MyTorrentsView
 
   private void moveSelectedTorrentsUp() {
     // Don't use runForSelectDataSources to ensure the order we want
-    Object[] dataSources = tv.getSelectedDataSources().toArray();
-    Arrays.sort(dataSources, new Comparator() {
-      public int compare (Object a, Object b) {
-        return ((DownloadManager)a).getPosition() - ((DownloadManager)b).getPosition();
+  	DownloadManager[] dms = getSelectedDownloads();
+    Arrays.sort(dms, new Comparator<DownloadManager>() {
+    	public int compare(DownloadManager a, DownloadManager b) {
+        return a.getPosition() - b.getPosition();
       }
     });
-    for (int i = 0; i < dataSources.length; i++) {
-      DownloadManager dm = (DownloadManager)dataSources[i];
+    for (int i = 0; i < dms.length; i++) {
+      DownloadManager dm = dms[i];
       if (dm.getGlobalManager().isMoveableUp(dm)) {
         dm.getGlobalManager().moveUp(dm);
       }
@@ -1681,31 +1604,29 @@ public class MyTorrentsView
 
 	private void moveSelectedTorrents(int by) {
 		// Don't use runForSelectDataSources to ensure the order we want
-		Object[] dataSources = tv.getSelectedDataSources().toArray();
-		if (dataSources.length <= 0)
+  	DownloadManager[] dms = getSelectedDownloads();
+		if (dms.length <= 0)
 			return;
 
-		int[] newPositions = new int[dataSources.length];
+		int[] newPositions = new int[dms.length];
 
 		if (by < 0) {
-			Arrays.sort(dataSources, new Comparator() {
-				public int compare(Object a, Object b) {
-					return ((DownloadManager) a).getPosition()
-							- ((DownloadManager) b).getPosition();
+			Arrays.sort(dms, new Comparator<DownloadManager>() {
+				public int compare(DownloadManager a, DownloadManager b) {
+					return a.getPosition() - b.getPosition();
 				}
 			});
 		} else {
-			Arrays.sort(dataSources, new Comparator() {
-				public int compare(Object a, Object b) {
-					return ((DownloadManager) b).getPosition()
-							- ((DownloadManager) a).getPosition();
+			Arrays.sort(dms, new Comparator<DownloadManager>() {
+				public int compare(DownloadManager a, DownloadManager b) {
+					return b.getPosition() - a.getPosition();
 				}
 			});
 		}
 
 		int count = globalManager.downloadManagerCount(isSeedingView); 
-		for (int i = 0; i < dataSources.length; i++) {
-			DownloadManager dm = (DownloadManager) dataSources[i];
+		for (int i = 0; i < dms.length; i++) {
+			DownloadManager dm = dms[i];
 			int pos = dm.getPosition() + by;
 			if (pos < i + 1)
 				pos = i + 1;
@@ -1715,8 +1636,8 @@ public class MyTorrentsView
 			newPositions[i] = pos;
 		}
 
-		for (int i = 0; i < dataSources.length; i++) {
-			DownloadManager dm = (DownloadManager) dataSources[i];
+		for (int i = 0; i < dms.length; i++) {
+			DownloadManager dm = dms[i];
 			globalManager.moveTo(dm, newPositions[i]);
 		}
 
@@ -1734,16 +1655,14 @@ public class MyTorrentsView
   }
 
   private void moveSelectedTorrentsTopOrEnd(boolean moveToTop) {
-  	Object[] datasources = tv.getSelectedDataSources().toArray();
-    if (datasources.length == 0)
+  	DownloadManager[] dms = getSelectedDownloads();
+    if (dms.length == 0)
       return;
-  	DownloadManager[] downloadManagers = new DownloadManager[datasources.length];
-  	System.arraycopy(datasources, 0, downloadManagers, 0, datasources.length);
 
     if(moveToTop)
-      globalManager.moveTop(downloadManagers);
+      globalManager.moveTop(dms);
     else
-      globalManager.moveEnd(downloadManagers);
+      globalManager.moveEnd(dms);
 
     boolean bForceSort = tv.getSortColumn().getName().equals("#");
     if (bForceSort) {
@@ -1764,93 +1683,69 @@ 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 void computePossibleActions() {
-    Object[] dataSources = tv.getSelectedDataSources().toArray();
-    // enable up and down so that we can do the "selection rotate trick"
-    up = down = run =  remove = (dataSources.length > 0);
-    top = bottom = start = stop = false;
-    for (int i = 0; i < dataSources.length; i++) {
-      DownloadManager dm = (DownloadManager)dataSources[i];
-
-      if(!start && ManagerUtils.isStartable(dm))
-        start =  true;
-      if(!stop && ManagerUtils.isStopable(dm))
-        stop = true;
-      if(!top && dm.getGlobalManager().isMoveableUp(dm))
-        top = true;
-      if(!bottom && dm.getGlobalManager().isMoveableDown(dm))
-        bottom = true;
-    }
-  }
 
-  public boolean isEnabled(String itemKey) {
-    if(itemKey.equals("run"))
-      return run;
-    if(itemKey.equals("start"))
-      return start;
-    if(itemKey.equals("stop"))
-      return stop;
-    if(itemKey.equals("remove"))
-      return remove;
-    if(itemKey.equals("top"))
-      return top;
-    if(itemKey.equals("bottom"))
-      return bottom;
-    if(itemKey.equals("up"))
-      return up;
-    if(itemKey.equals("down"))
-      return down;
-    if(itemKey.equals("share"))
-      return remove;
-    if(itemKey.equals("transcode"))
-      return remove;
-    return super.isEnabled(itemKey);
-  }
+  public void refreshToolBarItems(Map<String, Long> list) {
+		Map<String, Long> states = TorrentUtil.calculateToolbarStates(
+				SelectedContentManager.getCurrentlySelectedContent(), tv.getTableID());
+		list.putAll(states);
+  }  
+
+  public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
+  	String itemKey = item.getID();
+  	if (activationType == UIToolBarActivationListener.ACTIVATIONTYPE_HELD) {
+      if(itemKey.equals("up")) {
+        moveSelectedTorrentsTop();
+        return true;
+      }
+      if(itemKey.equals("down")){
+        moveSelectedTorrentsEnd();
+        return true;
+      }
+      return false;
+  	}
 
-  public void itemActivated(String itemKey) {
+  	if (activationType != UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL) {
+  		return false;
+  	}
     if(itemKey.equals("top")) {
       moveSelectedTorrentsTop();
-      return;
+      return true;
     }
     if(itemKey.equals("bottom")){
       moveSelectedTorrentsEnd();
-      return;
+      return true;
     }
     if(itemKey.equals("up")) {
       moveSelectedTorrentsUp();
-      return;
+      return true;
     }
     if(itemKey.equals("down")){
       moveSelectedTorrentsDown();
-      return;
+      return true;
     }
     if(itemKey.equals("run")){
-      TorrentUtil.runTorrents(tv.getSelectedDataSources().toArray());
-      return;
+      TorrentUtil.runDataSources(tv.getSelectedDataSources().toArray());
+      return true;
     }
     if(itemKey.equals("start")){
-      TorrentUtil.queueTorrents(tv.getSelectedDataSources().toArray(),
-					cTablePanel.getShell());
-      return;
+      TorrentUtil.queueDataSources(tv.getSelectedDataSources().toArray(), true);
+      return true;
     }
     if(itemKey.equals("stop")){
-      TorrentUtil.stopTorrents(tv.getSelectedDataSources().toArray(),
-					cTablePanel.getShell());
-      return;
+      TorrentUtil.stopDataSources(tv.getSelectedDataSources().toArray());
+      return true;
+    }
+    if (itemKey.equals("startstop")) {
+    	TorrentUtil.stopOrStartDataSources(tv.getSelectedDataSources().toArray());
+    	return true;
     }
     if(itemKey.equals("remove")){
-      TorrentUtil.removeTorrents(tv.getSelectedDataSources().toArray(),
-					cTablePanel.getShell());
-      return;
+      TorrentUtil.removeDataSources(tv.getSelectedDataSources().toArray());
+      return true;
     }
-    super.itemActivated(itemKey);
+    return false;
   }
   
 
@@ -1872,11 +1767,11 @@ public class MyTorrentsView
   public void stateChanged(DownloadManager manager, int state) {
     final TableRowCore row = tv.getRow(manager);
     if (row != null) {
-    	Utils.execSWTThreadLater(0, new AERunnable() {
+    	Utils.getOffOfSWTThread(new AERunnable() {
 				public void runSupport() {
 		    	row.refresh(true);
 		    	if (row.isSelected()) {
-		    		refreshIconBar();
+		    		updateSelectedContent();
 		    	}
 				}
     	});
@@ -1888,7 +1783,7 @@ public class MyTorrentsView
   	if (isOurDownloadManager(download)) {
     	Utils.execSWTThreadLater(0, new AERunnable() {
 				public void runSupport() {
-					refreshIconBar();
+					updateSelectedContent();
 				}
     	});
   	}
@@ -1958,15 +1853,15 @@ public class MyTorrentsView
 			currentCategory = category;
 		}
 		
+		tv.processDataSourceQueue();
 		Object[] managers = globalManager.getDownloadManagers().toArray();
-		Set existing = new HashSet(tv.getDataSources());
-		List listRemoves = new ArrayList();
-		List listAdds = new ArrayList();
+		List<DownloadManager> listRemoves = new ArrayList<DownloadManager>();
+		List<DownloadManager> listAdds = new ArrayList<DownloadManager>();
 		
 		for (int i = 0; i < managers.length; i++) {
 			DownloadManager dm = (DownloadManager) managers[i];
 		
-			boolean bHave = existing.contains(dm);
+			boolean bHave = tv.isUnfilteredDataSourceAdded(dm);
 			if (!isOurDownloadManager(dm)) {
 				if (bHave) {
 					listRemoves.add(dm);
@@ -1977,8 +1872,8 @@ public class MyTorrentsView
 				}
 			}
 		}
-		tv.removeDataSources(listRemoves.toArray());
-		tv.addDataSources(listAdds.toArray());
+		tv.removeDataSources(listRemoves.toArray(new DownloadManager[0]));
+		tv.addDataSources(listAdds.toArray(new DownloadManager[0]));
 		
   	tv.processDataSourceQueue();
 		//tv.refreshTable(false);
@@ -2007,28 +1902,23 @@ public class MyTorrentsView
 
 
   // CategoryManagerListener Functions
-  public void categoryAdded(Category category) {
-  	Utils.execSWTThread(
-	  		new AERunnable() 
-			{
-	  			public void 
-				runSupport() 
-	  			{
-	  				createTabs();
-	  			}
-			});
-  }
+	public void categoryAdded(Category category) {
+		createTabs();
+	}
 
-  public void categoryRemoved(Category category) {
-  	Utils.execSWTThread(
-	  		new AERunnable() 
-			{
-	  			public void 
-				runSupport() 
-	  			{
-	  				createTabs();
-	  			}
-			});
+	public void categoryRemoved(Category category) {
+		if (currentCategory == category) {
+			activateCategory(CategoryManager.getCategory(Category.TYPE_ALL));
+		} else {
+			// always activate as deletion of this one might have
+			// affected the current view 
+			activateCategory(currentCategory);
+		}
+
+		createTabs();
+	}
+  
+  public void categoryChanged(Category category) {	
   }
 
   // globalmanagerlistener Functions
@@ -2051,56 +1941,19 @@ public class MyTorrentsView
   
 
 
-  // @see com.aelitis.azureus.ui.common.table.TableCountChangeListener#rowAdded(com.aelitis.azureus.ui.common.table.TableRowCore)
-  public void rowAdded(TableRowCore row) {
-		updateTableLabel();
-  }
-
-  // @see com.aelitis.azureus.ui.common.table.TableCountChangeListener#rowRemoved(com.aelitis.azureus.ui.common.table.TableRowCore)
-  public void rowRemoved(TableRowCore row) {
-		updateTableLabel();
-	}
-	
 
 	public void updateLanguage() {
 		super.updateLanguage();
-		updateTableLabel();
 		getComposite().layout(true, true);
 	}
 
-	/**
-	 * 
-	 */
-	private boolean refreshingTableLabel = false;
-	private void updateTableLabel() {
-		if (refreshingTableLabel || lblHeader == null || lblHeader.isDisposed()) {
-			return;
-		}
-		refreshingTableLabel = true;
-		lblHeader.getDisplay().asyncExec(new AERunnable() {
-			public void runSupport() {
-				try {
-					if (lblHeader != null && !lblHeader.isDisposed()) {
-						String sText = MessageText.getString(tv.getTableID() + "View"
-								+ ".header")
-								+ " (" + tv.size(true) + ")";
-						lblHeader.setText(sText);
-						lblHeader.getParent().layout();
-					}
-				} finally {
-					refreshingTableLabel = false;
-				}
-			}
-		});
-	}
-
 	public boolean isTableFocus() {
 		return viewActive;
 		//return tv.isTableFocus();
 	}
 	
-	public Image obfusticatedImage(final Image image, Point shellOffset) {
-		return tv.obfusticatedImage(image, shellOffset);
+	public Image obfusticatedImage(final Image image) {
+		return tv.obfusticatedImage(image);
 	}
 	
 	/**
@@ -2109,17 +1962,12 @@ public class MyTorrentsView
 	 * @param basicItems
 	 * @return
 	 */
-	protected TableViewSWT createTableView(Class forDataSourceType, String tableID,
-			TableColumnCore[] basicItems) {
+	protected TableViewSWT<DownloadManager> createTableView(
+			Class<?> forDataSourceType, String tableID, TableColumnCore[] basicItems) {
 		int tableExtraStyle = COConfigurationManager.getIntParameter("MyTorrentsView.table.style");
-		return new TableViewSWTImpl(forDataSourceType, tableID, getPropertiesPrefix(),
-				basicItems, "#", tableExtraStyle | SWT.MULTI | SWT.FULL_SELECTION
-						| SWT.VIRTUAL) {
-			protected void setSelectedRowIndexes(int[] newSelectedRowIndices) {
-				super.setSelectedRowIndexes(newSelectedRowIndices);
-				updateSelectedContent();
-			}			
-		};
+		return TableViewFactory.createTableViewSWT(forDataSourceType, tableID,
+				getPropertiesPrefix(), basicItems, "#", tableExtraStyle | SWT.MULTI
+						| SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.CASCADE);
 	}
 
 	/**
@@ -2130,4 +1978,94 @@ public class MyTorrentsView
 	protected int getRowDefaultHeight(){
 		return -1;
 	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener#rowRefresh(org.gudy.azureus2.plugins.ui.tables.TableRow)
+	public void rowRefresh(TableRow row) {
+		if (!(row instanceof TableRowCore)) {
+			return;
+		}
+
+		TableRowCore rowCore = (TableRowCore) row;
+		Object ds = rowCore.getDataSource(true);
+		if (!(ds instanceof DownloadManager)) {
+			return;
+		}
+
+		DownloadManager dm = (DownloadManager) ds;
+		if (rowCore.getSubItemCount() == 0 && dm.getTorrent() != null
+				&& !dm.getTorrent().isSimpleTorrent() && rowCore.isVisible()
+				&& dm.getNumFileInfos() > 0) {
+			DiskManagerFileInfoSet fileInfos = dm.getDiskManagerFileInfoSet();
+			if (fileInfos != null) {
+				DiskManagerFileInfo[] files = fileInfos.getFiles();
+				boolean copied = false;
+				int pos = 0;
+				for (int i = 0; i < files.length; i++) {
+					DiskManagerFileInfo fileInfo = files[i];
+					if (fileInfo.isSkipped()
+							&& (fileInfo.getStorageType() == DiskManagerFileInfo.ST_COMPACT || fileInfo.getStorageType() == DiskManagerFileInfo.ST_REORDER_COMPACT)) {
+						continue;
+					}
+					if (pos != i) {
+						if ( !copied ){
+								// we *MUSTN'T* modify the returned array!!!!
+							
+							DiskManagerFileInfo[] oldFiles = files;
+							files = new DiskManagerFileInfo[files.length];
+							System.arraycopy(oldFiles, 0, files, 0, files.length);
+							
+							copied = true;
+						}
+						
+						files[pos] = files[i];
+					}
+					pos++;
+				}
+				if (pos != files.length) {
+					DiskManagerFileInfo[] oldFiles = files;
+					files = new DiskManagerFileInfo[pos];
+					System.arraycopy(oldFiles, 0, files, 0, pos);
+				}
+				rowCore.setSubItems(files);
+			}
+		}
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+		boolean b = super.eventOccurred(event);
+		if (event.getType() == UISWTViewEvent.TYPE_FOCUSGAINED) {
+			if (rebuildListOnFocusGain) {
+  			List<?> dms = globalManager.getDownloadManagers();
+  			List<DownloadManager> listAdds = new ArrayList();
+  			List<DownloadManager> listRemoves = new ArrayList();
+  			for (Iterator<?> iter = dms.iterator(); iter.hasNext();) {
+  				DownloadManager dm = (DownloadManager) iter.next();
+  
+  				if (!isOurDownloadManager(dm)) {
+  					listRemoves.add(dm);
+  				} else {
+  					listAdds.add(dm);
+  				}
+  			}
+  			tv.removeDataSources(listRemoves.toArray(new DownloadManager[0]));
+  			tv.addDataSources(listAdds.toArray(new DownloadManager[0]));
+			}
+	    updateSelectedContent(true);
+		} else if (event.getType() == UISWTViewEvent.TYPE_FOCUSLOST) {
+		}
+		return b;
+	}
+
+	public void setRebuildListOnFocusGain(boolean rebuildListOnFocusGain) {
+		this.rebuildListOnFocusGain = rebuildListOnFocusGain;
+	}
+
+	public void rowAdded(TableRowCore row) {
+		//if (getRowDefaultHeight() > 0 && row.getParentRowCore() != null) {
+		//	row.setHeight(20);
+		//}
+	}
+
+	public void rowRemoved(TableRowCore row) {
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/MyTrackerView.java b/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
index e285612..e4dab9d 100644
--- a/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
+++ b/org/gudy/azureus2/ui/swt/views/MyTrackerView.java
@@ -30,6 +30,7 @@ import java.io.OutputStream;
 import java.net.InetSocketAddress;
 import java.net.URL;
 import java.util.Arrays;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Color;
@@ -39,38 +40,39 @@ import org.gudy.azureus2.core3.category.Category;
 import org.gudy.azureus2.core3.category.CategoryManager;
 import org.gudy.azureus2.core3.category.CategoryManagerListener;
 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.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.host.TRHostListener;
 import org.gudy.azureus2.core3.tracker.host.TRHostTorrent;
 import org.gudy.azureus2.core3.tracker.host.TRHostTorrentRemovalVetoException;
-import org.gudy.azureus2.core3.util.AERunnable;
-import org.gudy.azureus2.core3.util.AsyncController;
-import org.gudy.azureus2.core3.util.Debug;
-import org.gudy.azureus2.core3.util.TorrentUtils;
-import org.gudy.azureus2.ui.swt.*;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
+import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
+import org.gudy.azureus2.ui.swt.CategoryAdderWindow;
+import org.gudy.azureus2.ui.swt.Messages;
+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.CoreWaiterSWT;
 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.TableViewSWTMenuFillListener;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 import org.gudy.azureus2.ui.swt.views.tableitems.mytracker.*;
 
 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.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
 
-import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
-import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
-
-import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
-
 
 /**
  * @author parg
@@ -80,7 +82,7 @@ import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
  */
 
 public class MyTrackerView
-	extends TableViewTab
+	extends TableViewTab<TRHostTorrent>
 	implements TRHostListener, CategoryManagerListener, TableLifeCycleListener,
 	TableSelectionListener, TableViewSWTMenuFillListener, TableRefreshListener
 {
@@ -119,7 +121,7 @@ public class MyTrackerView
 			};
 		}
 
-		tv = new TableViewSWTImpl<TRHostTorrent>(TrackerTorrent.class,
+		tv = TableViewFactory.createTableViewSWT(TrackerTorrent.class,
 				TableManager.TABLE_MYTRACKER, getPropertiesPrefix(), basicItems, "name",
 				SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
 		tv.addLifeCycleListener(this);
@@ -128,7 +130,7 @@ public class MyTrackerView
 		tv.addRefreshListener(this, false);
 	}
 
-  public TableViewSWT initYourTableView() {
+  public TableViewSWT<TRHostTorrent> initYourTableView() {
   	return tv;
   }
 
@@ -151,7 +153,7 @@ public class MyTrackerView
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void defaultSelected(TableRowCore[] rows, int stateMask) {
-		final TRHostTorrent torrent = tv.getFirstSelectedDataSource();
+		final TRHostTorrent torrent = (TRHostTorrent) tv.getFirstSelectedDataSource();
 		if (torrent == null)
 			return;
 		CoreWaiterSWT.waitForCoreRunning(new AzureusCoreRunningListener() {
@@ -301,7 +303,6 @@ public class MyTrackerView
 			return;
 	   	}
 		
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
@@ -347,10 +348,10 @@ public class MyTrackerView
 		}
 	}	 
 
-  private boolean start,stop,remove;
-  
-  private void computePossibleActions() {
-    start = stop = remove = false;
+	public void refreshToolBarItems(Map<String, Long> list) {
+		super.refreshToolBarItems(list);
+
+		boolean start = false, stop = false, remove = false;
     Object[] hostTorrents = tv.getSelectedDataSources().toArray();
     if (hostTorrents.length > 0) {
       remove = true;
@@ -378,33 +379,32 @@ public class MyTrackerView
         */
       }
     }
-  }
-  
-  public boolean isEnabled(String itemKey) {
-    if(itemKey.equals("start"))
-      return start;
-    if(itemKey.equals("stop"))
-      return stop;
-    if(itemKey.equals("remove"))
-      return remove;
-    return false;
+
+    list.put("start", start ? UIToolBarItem.STATE_ENABLED : 0);
+    list.put("stop", stop ? UIToolBarItem.STATE_ENABLED : 0);
+    list.put("remove", remove ? UIToolBarItem.STATE_ENABLED : 0);
   }
   
 
-  public void itemActivated(String itemKey) {
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		String itemKey = item.getID();
+
     if(itemKey.equals("start")) {
       startSelectedTorrents();
-      return;
+      return true;
     }
     if(itemKey.equals("stop")){
       stopSelectedTorrents();
-      return;
+      return true;
     }
     if(itemKey.equals("remove")){
       removeSelectedTorrents();
-      return;
+      return true;
     }
-  }
+
+		return super.toolBarItemActivated(item, activationType, datasource);
+	}
   
   private void stopSelectedTorrents() {
     tv.runForSelectedRows(new TableGroupRowRunner() {
@@ -435,9 +435,8 @@ public class MyTrackerView
       		
       	}catch( TRHostTorrentRemovalVetoException f ){
       		
-      		Alerts.showErrorMessageBoxUsingResourceString(
-					new Object[] { torrent },
-      				"globalmanager.download.remove.veto", f, 0 );
+  				Logger.log(new LogAlert(torrent, false,
+  						"{globalmanager.download.remove.veto}", f));
       	}
       }
     });
@@ -528,6 +527,8 @@ public class MyTrackerView
 		});
   }
 
+  public void categoryChanged(Category category) {	
+  }
   
   private void addCategory() {
     CategoryAdderWindow adderWindow = new CategoryAdderWindow(SWTThread.getInstance().getDisplay());
@@ -593,7 +594,6 @@ public class MyTrackerView
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#deselected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void deselected(TableRowCore[] rows) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
@@ -602,7 +602,6 @@ public class MyTrackerView
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#focusChanged(com.aelitis.azureus.ui.common.table.TableRowCore)
 	public void focusChanged(TableRowCore focus) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
@@ -611,7 +610,6 @@ public class MyTrackerView
 
 	// @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[])
 	public void selected(TableRowCore[] rows) {
-		computePossibleActions();
   	UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
   	if (uiFunctions != null) {
   		uiFunctions.refreshIconBar();
diff --git a/org/gudy/azureus2/ui/swt/views/PeerSuperView.java b/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
index bdecbca..1a107bf 100644
--- a/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
+++ b/org/gudy/azureus2/ui/swt/views/PeerSuperView.java
@@ -37,10 +37,13 @@ import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
 import org.gudy.azureus2.ui.swt.views.peer.PeerInfoView;
 import org.gudy.azureus2.ui.swt.views.peer.RemotePieceDistributionView;
 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.TableViewFactory;
 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.tableitems.peers.DownloadNameItem;
@@ -50,6 +53,8 @@ import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableLifeCycleListener;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * @author Olivier
@@ -69,6 +74,7 @@ public class PeerSuperView
 	private TableViewSWT<PEPeer> tv;
 	private Shell shell;
 	private boolean active_listener = true;
+	private static boolean registeredCoreSubViews = false;
 
 
   /**
@@ -83,16 +89,29 @@ public class PeerSuperView
   	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,
+  	tv = TableViewFactory.createTableViewSWT(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[] {
-			new PeerInfoView(),
-			new RemotePieceDistributionView(),
-			new LoggerView(true)
-		});
+
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+			
+			if (pluginUI != null && !registeredCoreSubViews) {
+
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "PeerInfoView",
+						new PeerInfoView());
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "RemotePieceDistributionView",
+						new RemotePieceDistributionView());
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "LoggerView",
+						new LoggerView(true));
+
+				registeredCoreSubViews = true;
+			}
+		}
+
 		tv.addLifeCycleListener(this);
 		tv.addMenuFillListener(this);
 		
@@ -142,7 +161,7 @@ public class PeerSuperView
 		}
 
 		ArrayList<PEPeer> sources = new ArrayList<PEPeer>();
-		Iterator itr = core.getGlobalManager().getDownloadManagers().iterator();
+		Iterator<?> itr = core.getGlobalManager().getDownloadManagers().iterator();
 		while (itr.hasNext()) {
 			PEPeer[] peers = ((DownloadManager)itr.next()).getCurrentPeers();
 			if (peers != null) {
@@ -171,7 +190,7 @@ public class PeerSuperView
 		try {
 			GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
 			gm.removeListener(this);
-			Iterator itr = gm.getDownloadManagers().iterator();
+			Iterator<?> itr = gm.getDownloadManagers().iterator();
 			while(itr.hasNext()) {
 				DownloadManager dm = (DownloadManager)itr.next();
 				downloadManagerRemoved(dm);
diff --git a/org/gudy/azureus2/ui/swt/views/PeersGraphicView.java b/org/gudy/azureus2/ui/swt/views/PeersGraphicView.java
index b557764..eb3aaf1 100644
--- a/org/gudy/azureus2/ui/swt/views/PeersGraphicView.java
+++ b/org/gudy/azureus2/ui/swt/views/PeersGraphicView.java
@@ -25,8 +25,9 @@ package org.gudy.azureus2.ui.swt.views;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
@@ -36,25 +37,38 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
+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.peer.impl.PEPeerTransport;
 import org.gudy.azureus2.core3.util.AEMonitor;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.components.graphics.PieUtils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
+
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 
 /**
  * @author Olivier Chalouhi
  *
  */
-public class PeersGraphicView extends AbstractIView implements DownloadManagerPeerListener {
-
+public class PeersGraphicView
+	implements DownloadManagerPeerListener, UISWTViewCoreEventListener, UIPluginViewToolBarListener
+{
   
-  private DownloadManager manager = null;
+  public static String MSGID_PREFIX = "PeersGraphicView";
+
+	private DownloadManager manager = null;
   
   private static final int NB_ANGLES = 1000;  
   private double[] angles;
-  private double[] deltaPerimeters;
+  //private double[] deltaPerimeters;
   private double perimeter;
   private double[] rs;
   private double[] deltaXXs;
@@ -64,7 +78,7 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
   
   private Point oldSize;
   
-  private List peers;
+  private List<PEPeer> peers;
   private AEMonitor peers_mon = new AEMonitor( "PeersGraphicView:peers" );;
   private PeerComparator peerComparator;
   
@@ -72,18 +86,16 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
   //UI Stuff
   private Display display;
   private Composite panel;
+
+	private UISWTView swtView;
   private static final int PEER_SIZE = 15;
-  private static final int PACKET_SIZE = 10;
+  //private static final int PACKET_SIZE = 10;
   private static final int OWN_SIZE = 75;
   
-  private boolean antiAliasingAvailable = true;
-  
   //Comparator Class
   //Note: this comparator imposes orderings that are inconsistent with equals.
-  class PeerComparator implements Comparator {
-    public int compare(Object arg0, Object arg1) {
-      PEPeer peer0 = (PEPeer) arg0;
-      PEPeer peer1 = (PEPeer) arg1;
+  class PeerComparator implements Comparator<PEPeer> {
+  	public int compare(PEPeer peer0, PEPeer peer1) {
 
       //Then we sort on %, but depending on interested ...
       int percent0 = peer0.getPercentDoneInThousandNotation();
@@ -96,7 +108,7 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
   
   public PeersGraphicView() {
     angles = new double[NB_ANGLES];
-    deltaPerimeters = new double[NB_ANGLES];
+    //deltaPerimeters = new double[NB_ANGLES];
     rs = new double[NB_ANGLES];
     deltaXXs = new double[NB_ANGLES];
     deltaXYs = new double[NB_ANGLES];
@@ -111,45 +123,51 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
       deltaYYs[i] = Math.sin(angles[i]+Math.PI / 2);
     }
     
-    this.peers = new ArrayList();
+    this.peers = new ArrayList<PEPeer>();
     this.peerComparator = new PeerComparator();
   } 
   
-	public void dataSourceChanged(Object newDataSource) {
-  	if (manager != null)
-  		manager.removePeerListener(this);
+  private void dataSourceChanged(Object newDataSource) {
+	  if (manager != null)
+		  manager.removePeerListener(this);
 
-		if (newDataSource == null)
-			manager = null;
-		else if (newDataSource instanceof Object[])
-			manager = (DownloadManager)((Object[])newDataSource)[0];
-		else
-			manager = (DownloadManager)newDataSource;
+	  if (newDataSource == null)
+		  manager = null;
+	  else if (newDataSource instanceof Object[])
+		  manager = (DownloadManager)((Object[])newDataSource)[0];
+	  else
+		  manager = (DownloadManager)newDataSource;
 
-    if (manager != null)
-    	manager.addPeerListener(this);
-	}
+	  try {
+		  peers_mon.enter();
+		  
+		  peers.clear();
+	  } finally {
+		  peers_mon.exit();
+	  }
+	  if (manager != null)
+		  manager.addPeerListener(this);
+  }
 
-  public void delete() {
+  private void delete() {
   	if (manager != null)
   		manager.removePeerListener(this);
-    super.delete();
   }
 
-  public Composite getComposite() {    
+  private Composite getComposite() {    
     return panel;
   }
   
-  public String getData() {
-    return "PeersGraphicView.title";
+  private String getData() {
+    return "PeersGraphicView.title.full";
   }
 
-  public void initialize(Composite composite) {
+  private void initialize(Composite composite) {
     display = composite.getDisplay();
     panel = new Canvas(composite,SWT.NULL);
   }
 
-  public void refresh() {
+  private void refresh() {
     doRefresh();
   }
   
@@ -160,15 +178,16 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
     PEPeer[] sortedPeers;
     try {      
       peers_mon.enter();      
-      List connectedPeers = new ArrayList();
-      Iterator iter = peers.iterator();
-      while(iter.hasNext()) {
-        PEPeerTransport peer = (PEPeerTransport) iter.next();
-        if(peer.getConnectionState() == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED)
-          connectedPeers.add(peer);
+      List<PEPeerTransport> connectedPeers = new ArrayList<PEPeerTransport>();
+      for (PEPeer peer : peers) {
+      	if (peer instanceof PEPeerTransport) {
+      		PEPeerTransport peerTransport = (PEPeerTransport) peer;
+      		if(peerTransport.getConnectionState() == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED)
+      			connectedPeers.add(peerTransport);
+      	}
       }
       
-      sortedPeers = (PEPeer[]) connectedPeers.toArray(new PEPeer[connectedPeers.size()]);      
+      sortedPeers = connectedPeers.toArray(new PEPeer[connectedPeers.size()]);      
     } finally {
       peers_mon.exit();
     }
@@ -203,13 +222,10 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
     gcBuffer.setForeground(Colors.blue);
     gcBuffer.fillRectangle(0,0,panelSize.x,panelSize.y);
 
-    if(SWT.getVersion() >= 3138 && antiAliasingAvailable) {
-      try {
-        //gcBuffer.setTextAntialias(SWT.ON);
-        //gcBuffer.setAntialias(SWT.ON);
-      } catch(Exception e) {
-        antiAliasingAvailable = false;
-      }
+    try {
+      gcBuffer.setTextAntialias(SWT.ON);
+      gcBuffer.setAntialias(SWT.ON);
+    } catch(Exception e) {
     }
     
     gcBuffer.setBackground(Colors.blues[Colors.BLUES_MIDLIGHT]);      
@@ -218,78 +234,98 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
     
     int iAngle = 0;
     double currentPerimeter = 0;    
-    double angle,r;   
+    //double angle;
+    double r;   
 
     for(int i = 0 ; i < nbPeers ; i++) {
       PEPeer peer = sortedPeers[i];
       do {
-        angle = angles[iAngle];
+        //angle = angles[iAngle];
         r     = rs[iAngle];
         currentPerimeter += r;
         if(iAngle + 1 < NB_ANGLES) iAngle++;
       } while( currentPerimeter < i * perimeter / nbPeers);
             
-      angle = (4 * i - nbPeers) * Math.PI  / (2 * nbPeers) - Math.PI / 2;
+      //angle = (4 * i - nbPeers) * Math.PI  / (2 * nbPeers) - Math.PI / 2;
       
-      int[] rectangle = new int[8];
+      int[] triangle = new int[6];
       
       
+      int percent_received 	= peer.getPercentDoneOfCurrentIncomingRequest();
+      int percent_sent 		= peer.getPercentDoneOfCurrentOutgoingRequest();
+
+      	// set up base line state
       
-      if(! peer.isChokedByMe() || ! peer.isChokingMe()) {
-        gcBuffer.setForeground(Colors.blues[Colors.BLUES_MIDLIGHT]);
-        int x1 = x0 + (int) ( r * deltaYXs[iAngle] );
-        int y1 = y0 + (int) ( r * deltaYYs[iAngle] );        
-        gcBuffer.drawLine(x0,y0,x1,y1);
-        /*
-        rectangle[0] = x0 + (int) (deltaXXs[iAngle] * 3 + 0.5);
-        rectangle[1] = y0 + (int) (deltaXYs[iAngle] * 3 + 0.5);
-        rectangle[2] = x0 - (int) (deltaXXs[iAngle] * 3 + 0.5);
-        rectangle[3] = y0 - (int) (deltaXYs[iAngle] * 3 + 0.5);
-        
-        
-        rectangle[4] = x0 - (int) (deltaXXs[iAngle] * 3 - r * deltaYXs[iAngle]+ 0.5);
-        rectangle[5] = y0 - (int) (deltaXYs[iAngle] * 3 - r * deltaYYs[iAngle] + 0.5);
-        rectangle[6] = x0 + (int) (deltaXXs[iAngle] * 3 + r * deltaYXs[iAngle] + 0.5);
-        rectangle[7] = y0 + (int) (deltaXYs[iAngle] * 3 + r * deltaYYs[iAngle] + 0.5);
-        gcBuffer.drawPolygon(rectangle);        
-        */
+
+      boolean	drawLine = false;
+      
+      	// unchoked
+      
+      if ( !peer.isChokingMe() || percent_received >= 0 ){
+      	gcBuffer.setForeground(Colors.blues[1] );
+     	drawLine = true;
+      }
+
+      	// unchoking
+      
+      if ( !peer.isChokedByMe() || percent_sent >= 0 ){
+  		gcBuffer.setForeground(Colors.blues[3]);
+  		drawLine = true;
+      }
+         
+      	// receiving from choked peer (fast request in)
+      
+      if ( !peer.isChokingMe() && peer.isUnchokeOverride() && peer.isInteresting()){
+  		gcBuffer.setForeground(Colors.green);
+  		drawLine = true;
+      }
+      
+      	// sending to choked peer (fast request out)
+      
+      if ( peer.isChokedByMe() && percent_sent >= 0 ){
+    	gcBuffer.setForeground(Colors.green);
+    	drawLine = true;
+      }
+      
+      if ( drawLine ){
+		int x1 = x0 + (int) ( r * deltaYXs[iAngle] );
+		int y1 = y0 + (int) ( r * deltaYYs[iAngle] );        
+		gcBuffer.drawLine(x0,y0,x1,y1);
       }    
       
       
-      int percentSent = peer.getPercentDoneOfCurrentIncomingRequest();
-      if(percentSent >= 0) {
+      
+      if(percent_received >= 0) {
         gcBuffer.setBackground(Colors.blues[Colors.BLUES_MIDDARK]);
-        double r1 = r - r * percentSent / 100;
-        rectangle[0] = (int) (x0 + r1 * deltaYXs[iAngle] + 0.5);
-        rectangle[1] = (int) (y0 + r1 * deltaYYs[iAngle] + 0.5);
-        rectangle[2] = (int) (x0 + deltaXXs[iAngle] * 4 + r1 * deltaYXs[iAngle] + 0.5);
-        rectangle[3] = (int) (y0 + deltaXYs[iAngle] * 4 + r1 * deltaYYs[iAngle] + 0.5);
+        double r1 = r - r * percent_received / 100;
+        triangle[0] = (int) (x0 + (r1-10) * deltaYXs[iAngle] + 0.5);
+        triangle[1] = (int) (y0 + (r1-10) * deltaYYs[iAngle] + 0.5);
         
+        triangle[2] =  (int) (x0 + deltaXXs[iAngle] * 4 + (r1) * deltaYXs[iAngle] + 0.5);
+        triangle[3] =  (int) (y0 + deltaXYs[iAngle] * 4 + (r1) * deltaYYs[iAngle] + 0.5);
         
-        rectangle[4] =  (int) (x0 + deltaXXs[iAngle] * 4 + (r1-10) * deltaYXs[iAngle] + 0.5);
-        rectangle[5] =  (int) (y0 + deltaXYs[iAngle] * 4 + (r1-10) * deltaYYs[iAngle] + 0.5);
-        rectangle[6] =  (int) (x0 + (r1-10) * deltaYXs[iAngle] + 0.5);
-        rectangle[7] =  (int) (y0 + (r1-10) * deltaYYs[iAngle] + 0.5);
-        gcBuffer.fillPolygon(rectangle); 
+        
+        triangle[4] =  (int) (x0 - deltaXXs[iAngle] * 4 + (r1) * deltaYXs[iAngle] + 0.5);
+        triangle[5] =  (int) (y0 - deltaXYs[iAngle] * 4 + (r1) * deltaYYs[iAngle] + 0.5);
+        
+        gcBuffer.fillPolygon(triangle); 
       }
       
       
       
-      percentSent = peer.getPercentDoneOfCurrentOutgoingRequest();
-      if(percentSent >= 0) {
+      if(percent_sent >= 0) {
         gcBuffer.setBackground(Colors.blues[Colors.BLUES_MIDLIGHT]);
-        double r1 = r * percentSent / 100;
-        rectangle[0] =  (int) (x0 + r1 * deltaYXs[iAngle] + 0.5);
-        rectangle[1] =  (int) (y0 + r1 * deltaYYs[iAngle] + 0.5);
-        rectangle[2] =  (int) (x0 - deltaXXs[iAngle] * 4 + r1 * deltaYXs[iAngle] + 0.5);
-        rectangle[3] =  (int) (y0 - deltaXYs[iAngle] * 4 + r1 * deltaYYs[iAngle] + 0.5);
+        double r1 = r * percent_sent / 100;
+        triangle[0] = (int) (x0 + r1 * deltaYXs[iAngle] + 0.5);
+        triangle[1] = (int) (y0 + r1 * deltaYYs[iAngle] + 0.5);
+        
+        triangle[2] =  (int) (x0 + deltaXXs[iAngle] * 4 + (r1-10) * deltaYXs[iAngle] + 0.5);
+        triangle[3] =  (int) (y0 + deltaXYs[iAngle] * 4 + (r1-10) * deltaYYs[iAngle] + 0.5);
         
         
-        rectangle[4] =  (int) (x0 - deltaXXs[iAngle] * 4 + (r1-10) * deltaYXs[iAngle] + 0.5);
-        rectangle[5] =  (int) (y0 - deltaXYs[iAngle] * 4 + (r1-10) * deltaYYs[iAngle] + 0.5);
-        rectangle[6] =  (int) (x0 + (r1-10) * deltaYXs[iAngle] + 0.5);
-        rectangle[7] =  (int) (y0 + (r1-10) * deltaYYs[iAngle] + 0.5);
-        gcBuffer.fillPolygon(rectangle); 
+        triangle[4] =  (int) (x0 - deltaXXs[iAngle] * 4 + (r1-10) * deltaYXs[iAngle] + 0.5);
+        triangle[5] =  (int) (y0 - deltaXYs[iAngle] * 4 + (r1-10) * deltaYYs[iAngle] + 0.5);
+        gcBuffer.fillPolygon(triangle); 
       }
       
       
@@ -346,4 +382,61 @@ public class PeersGraphicView extends AbstractIView implements DownloadManagerPe
       peers_mon.exit();
     }
   }
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(getData()));
+      	swtView.setToolBarListener(this);
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(MessageText.getString(getData()));
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+        	String id = "DMDetails_Swarm";
+	      	if (manager != null) {
+	      		if (manager.getTorrent() != null) {
+	  					id += "." + manager.getInternalName();
+	      		} else {
+	      			id += ":" + manager.getSize();
+	      		}
+	      	}
+	  
+	      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+	      		new SelectedContent(manager)
+	      	});
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
+	
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		return( ViewUtils.toolBarItemActivated(manager, item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(manager, list);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/PeersView.java b/org/gudy/azureus2/ui/swt/views/PeersView.java
index d02fe8d..0010f5d 100644
--- a/org/gudy/azureus2/ui/swt/views/PeersView.java
+++ b/org/gudy/azureus2/ui/swt/views/PeersView.java
@@ -21,8 +21,12 @@
  */
 package org.gudy.azureus2.ui.swt.views;
 
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
@@ -31,19 +35,27 @@ import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.util.Debug;
-
 import org.gudy.azureus2.plugins.peers.Peer;
 import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
 import org.gudy.azureus2.ui.swt.views.peer.PeerInfoView;
 import org.gudy.azureus2.ui.swt.views.peer.RemotePieceDistributionView;
 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.TableViewFactory;
 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.tableitems.peers.*;
 
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * @author Olivier
@@ -56,7 +68,7 @@ import com.aelitis.azureus.ui.common.table.*;
  */
 
 public class PeersView
-	extends TableViewTab
+	extends TableViewTab<PEPeer>
 	implements DownloadManagerPeerListener, TableDataSourceChangedListener,
 	TableLifeCycleListener, TableViewSWTMenuFillListener
 {
@@ -68,6 +80,7 @@ public class PeersView
 			new TypeItem(table_id),
 			new MessagingItem(table_id),
 			new EncryptionItem(table_id),
+			new ProtocolItem(table_id),
 			new PiecesItem(table_id),
 			new PercentItem(table_id),
 			new DownSpeedItem(table_id),
@@ -110,32 +123,49 @@ public class PeersView
 	}
 	
   private static final TableColumnCore[] basicItems = getBasicColumnItems(TableManager.TABLE_TORRENT_PEERS);
+
+	public static final String MSGID_PREFIX = "PeersView";
   
   private DownloadManager manager;
-	private TableViewSWT tv;
+	private TableViewSWT<PEPeer> tv;
 	private Shell shell;
 
+	private static boolean registeredCoreSubViews = false;
+
 
   /**
    * Initialize
    *
    */
   public PeersView() {
-  	super("PeersView");
+  	super(MSGID_PREFIX);
   }
   
   // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
-  public TableViewSWT initYourTableView() {
-		tv = new TableViewSWTImpl(Peer.class, TableManager.TABLE_TORRENT_PEERS,
+  public TableViewSWT<PEPeer> initYourTableView() {
+  	tv = TableViewFactory.createTableViewSWT(Peer.class, TableManager.TABLE_TORRENT_PEERS,
 				getPropertiesPrefix(), basicItems, "pieces", SWT.MULTI | SWT.FULL_SELECTION
 						| SWT.VIRTUAL);
 		tv.setRowDefaultHeight(16);
 		tv.setEnableTabViews(true);
-		tv.setCoreTabViews(new IView[] {
-			new PeerInfoView(),
-			new RemotePieceDistributionView(),
-			new LoggerView(true)
-		});
+
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+			
+			if (pluginUI != null && !registeredCoreSubViews) {
+
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "PeerInfoView",
+						PeerInfoView.class, manager);
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "RemotePieceDistributionView",
+						RemotePieceDistributionView.class, manager);
+				pluginUI.addView(TableManager.TABLE_TORRENT_PEERS, "LoggerView",
+						new LoggerView(true));
+
+				registeredCoreSubViews = true;
+			}
+		}
+
 		tv.addTableDataSourceChangedListener(this, true);
 		tv.addLifeCycleListener(this);
 		tv.addMenuFillListener(this);
@@ -179,8 +209,7 @@ public class PeersView
 	
 	public void fillMenu(String sColumnName, Menu menu) {fillMenu(menu, tv, shell, true);}
 
-	public static void fillMenu(final Menu menu, final TableView tv, final Shell shell, boolean download_specific) {
-		
+	public static void fillMenu(final Menu menu, final TableView<?> tv, final Shell shell, boolean download_specific) {
 		Object[] peers = tv.getSelectedDataSources().toArray();
 		
 		boolean hasSelection = (peers.length > 0);
@@ -254,14 +283,18 @@ public class PeersView
 				block_item.setEnabled(true);
 				block_item.setSelection(peer.isSnubbed());
 			}
-	
-			Messages.setLanguageText(block_item, "PeersView.menu.blockupload");
-			block_item.addListener(SWT.Selection, new TableSelectedRowsListener(tv) {
-				public void run(TableRowCore row) {
-					((PEPeer) row.getDataSource(true))
-							.setSnubbed(block_item.getSelection());
-				}
-			});
+
+			if (peer != null) {
+  			final boolean newSnubbedValue = !peer.isSnubbed();
+  	
+  			Messages.setLanguageText(block_item, "PeersView.menu.blockupload");
+  			block_item.addListener(SWT.Selection, new TableSelectedRowsListener(tv) {
+  				public void run(TableRowCore row) {
+  					PEPeer peer = ((PEPeer) row.getDataSource(true));
+  					peer.setSnubbed(newSnubbedValue);
+  				}
+  			});
+			}
 		}
 
 		final MenuItem ban_item = new MenuItem(menu, SWT.PUSH);
@@ -326,7 +359,7 @@ public class PeersView
 	public void addThisColumnSubMenu(String columnName, Menu menuThisColumn) {
 	}
 
-	private static void setSelectedPeersUpSpeed(int speed, TableView tv) {      
+	private static void setSelectedPeersUpSpeed(int speed, TableView<?> tv) {      
 		Object[] peers = tv.getSelectedDataSources().toArray();
 		if(peers.length > 0) {            
 			for (int i = 0; i < peers.length; i++) {
@@ -340,7 +373,7 @@ public class PeersView
 		}
 	}
 
-	private static void setSelectedPeersDownSpeed(int speed, TableView tv) {      
+	private static void setSelectedPeersDownSpeed(int speed, TableView<?> tv) {      
 		Object[] peers = tv.getSelectedDataSources().toArray();
 		if(peers.length > 0) {            
 			for (int i = 0; i < peers.length; i++) {
@@ -378,7 +411,7 @@ public class PeersView
 			return;
 		}
 
-		Object[] dataSources = manager.getCurrentPeers();
+		PEPeer[] dataSources = manager.getCurrentPeers();
 		if (dataSources == null || dataSources.length == 0) {
 			return;
 		}
@@ -386,4 +419,40 @@ public class PeersView
 		tv.addDataSources(dataSources);
 		tv.processDataSourceQueue();
 	}
+	
+	public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	     
+	        
+	      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	String id = "DMDetails_Peers";
+	      	if (manager != null) {
+	      		if (manager.getTorrent() != null) {
+	  					id += "." + manager.getInternalName();
+	      		} else {
+	      			id += ":" + manager.getSize();
+	      		}
+	      	}
+	  
+	      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+	      		new SelectedContent(manager)
+	      	});
+	      	break;
+	    }
+	    
+	    return( super.eventOccurred(event));
+	}
+	
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if ( ViewUtils.toolBarItemActivated(manager, item, activationType, datasource)){
+			return( true );
+		}
+		return( super.toolBarItemActivated(item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(manager, list);
+		super.refreshToolBarItems(list);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java b/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
index d8fb551..473275f 100644
--- a/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
+++ b/org/gudy/azureus2/ui/swt/views/PieceDistributionView.java
@@ -31,8 +31,12 @@ import org.gudy.azureus2.core3.disk.DiskManagerPiece;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPiece;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 import org.gudy.azureus2.ui.swt.views.utils.CoordinateTransform;
 
 import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
@@ -42,8 +46,7 @@ import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
  * @create 02.10.2007
  */
 public abstract class PieceDistributionView
-	extends AbstractIView
-	implements IViewExtension
+	implements UISWTViewCoreEventListener
 {
 	private Composite		comp;
 	private Canvas			pieceDistCanvas;
@@ -55,6 +58,7 @@ public abstract class PieceDistributionView
 	protected boolean		isMe		= false;
 	private boolean			initialized	= false;
 	private Image imgToPaint = null;
+	private UISWTView swtView;
 	
 	/**
 	 * implementors of this method must provide an appropriate peer manager and
@@ -62,17 +66,11 @@ public abstract class PieceDistributionView
 	 */
 	abstract public void dataSourceChanged(Object newDataSource);
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
-	 */
-	public String getData() {
-		return "PiecesView.DistributionView.title";
+	private String getFullTitle() {
+		return MessageText.getString("PiecesView.DistributionView.title");
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#initialize(org.eclipse.swt.widgets.Composite)
-	 */
-	public void initialize(Composite parent) {
+	private void initialize(Composite parent) {
 		comp = new Composite(parent,SWT.NONE);
 		createPieceDistPanel();
 		initialized = true;
@@ -109,7 +107,7 @@ public abstract class PieceDistributionView
 		final int upperBound = 1 + (1 << (int) Math.ceil(Math.log(connected + 0.0) / Math.log(2.0)));
 		// System.out.println("conn:"+connected+" bound:"+upperBound);
 		final int minAvail = (int) picker.getMinAvailability();
-		final int maxAvail = picker.getMaxAvailability();
+		//final int maxAvail = picker.getMaxAvailability();
 		final int nbPieces = picker.getNumberOfPieces();
 		final int[] availabilties = picker.getAvailability();
 		final DiskManagerPiece[] dmPieces = pem.getDiskManager().getPieces();
@@ -121,7 +119,7 @@ public abstract class PieceDistributionView
 		final boolean[] downloading = new boolean[upperBound];
 		
 		int avlPeak = 0;
-		int avlPeakIdx = -1;
+		//int avlPeakIdx = -1;
 		
 		for (int i = 0; i < nbPieces; i++)
 		{
@@ -131,7 +129,7 @@ public abstract class PieceDistributionView
 			if (avlPeak < (newPeak = ++globalPiecesPerAvailability[availabilties[i]]))
 			{
 				avlPeak = newPeak;
-				avlPeakIdx = availabilties[i];
+				//avlPeakIdx = availabilties[i];
 			}
 			if ((isMe && dmPieces[i].isDone()) || (!isMe && hasPieces != null && hasPieces[i]))
 				++datasourcePiecesPerAvailability[availabilties[i]];
@@ -275,38 +273,64 @@ public abstract class PieceDistributionView
 		if (!initialized || pem == null)
 			return;
 		updateDistribution();
-		super.refresh();
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
-	 */
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return comp;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
-	 */
-	public void delete() {
+	private void delete() {
 		if (!initialized)
 			return;
 		initialized = false;
 		Utils.disposeSWTObjects(new Object[] { pieceDistCanvas, comp, imgToPaint });
-		super.delete();
-	}
-	
-	public Menu getPrivateMenu() {
-		return null;
 	}
 	
-	public void viewActivated() {
+	private void viewActivated() {
 		updateDistribution();
 	}
 	
-	public void viewDeactivated() {
+	private void viewDeactivated() {
 		Utils.disposeSWTObjects(new Object[] { imgToPaint });
 	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	viewActivated();
+      	break;
+        
+      case UISWTViewEvent.TYPE_FOCUSLOST:
+      	viewDeactivated();
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/PiecesView.java b/org/gudy/azureus2/ui/swt/views/PiecesView.java
index a5ea618..3f97035 100644
--- a/org/gudy/azureus2/ui/swt/views/PiecesView.java
+++ b/org/gudy/azureus2/ui/swt/views/PiecesView.java
@@ -21,6 +21,8 @@
  */
 package org.gudy.azureus2.ui.swt.views;
 
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 
@@ -30,19 +32,30 @@ import org.gudy.azureus2.core3.download.DownloadManagerPieceListener;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.peer.PEPiece;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.components.Legend;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 import org.gudy.azureus2.ui.swt.views.piece.MyPieceDistributionView;
 import org.gudy.azureus2.ui.swt.views.piece.PieceInfoView;
 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.TableViewFactory;
 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab;
 import org.gudy.azureus2.ui.swt.views.tableitems.pieces.*;
 
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 import com.aelitis.azureus.ui.common.table.TableDataSourceChangedListener;
 import com.aelitis.azureus.ui.common.table.TableLifeCycleListener;
-
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
  * @author Olivier
@@ -54,12 +67,15 @@ import org.gudy.azureus2.plugins.ui.tables.TableManager;
  */
 
 public class PiecesView 
-	extends TableViewTab
+	extends TableViewTab<PEPiece>
 	implements DownloadManagerPeerListener, 
 	DownloadManagerPieceListener,
 	TableDataSourceChangedListener,
-	TableLifeCycleListener
+	TableLifeCycleListener,
+	UISWTViewCoreEventListener
 {
+	private static boolean registeredCoreSubViews = false;
+
 	private final static TableColumnCore[] basicItems = {
 		new PieceNumberItem(),
 		new SizeItem(),
@@ -75,34 +91,46 @@ public class PiecesView
 		new RequestedItem()
 	};
 
+	public static final String MSGID_PREFIX = "PiecesView";
+
 	DownloadManager manager;
   
-	private TableViewSWTImpl<PEPiece> tv;
+	private TableViewSWT<PEPiece> tv;
 
 	private Composite legendComposite;
 
-	private PieceInfoView pieceInfoView;
-	private MyPieceDistributionView pieceDistView;
   
 	/**
 	 * Initialize
 	 *
 	 */
 	public PiecesView() {
-		super("PiecesView");
+		super(MSGID_PREFIX);
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView()
-	public TableViewSWT initYourTableView() {
-		tv = new TableViewSWTImpl<PEPiece>(PEPiece.class,
+	public TableViewSWT<PEPiece> initYourTableView() {
+		tv = TableViewFactory.createTableViewSWT(PEPiece.class,
 				TableManager.TABLE_TORRENT_PIECES, getPropertiesPrefix(), basicItems,
 				basicItems[0].getName(), SWT.SINGLE | SWT.FULL_SELECTION | SWT.VIRTUAL);
 		tv.setEnableTabViews(true);
-		pieceInfoView = new PieceInfoView();
-		pieceDistView = new MyPieceDistributionView();
-		tv.setCoreTabViews(new IView[] {
-			pieceInfoView,pieceDistView
-		});
+
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+			
+			if (pluginUI != null && !registeredCoreSubViews) {
+				
+				pluginUI.addView(TableManager.TABLE_TORRENT_PIECES,
+						"PieceInfoView", PieceInfoView.class, manager);
+
+				pluginUI.addView(TableManager.TABLE_TORRENT_PIECES,
+						"MyPieceDistributionView", MyPieceDistributionView.class, manager);
+
+				registeredCoreSubViews = true;
+			}
+		}
+
 		tv.addTableDataSourceChangedListener(this, true);
 		tv.addLifeCycleListener(this);
 
@@ -128,18 +156,12 @@ public class PiecesView
 			manager.addPieceListener(this, false);
 			addExistingDatasources();
     }
-  	if (pieceInfoView != null) {
-  		pieceInfoView.dataSourceChanged(manager);
-		}
-  	if (pieceDistView != null) {
-  		pieceDistView.dataSourceChanged(manager);
-		}
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized()
 	public void tableViewInitialized() {
-		if (legendComposite != null && (tv instanceof TableViewSWT)) {
-			Composite composite = ((TableViewSWT) tv).getTableComposite();
+		if (legendComposite != null && tv != null) {
+			Composite composite = ((TableViewSWT<PEPiece>) tv).getTableComposite();
 
 			legendComposite = Legend.createLegendComposite(composite,
 					BlocksItem.colors, new String[] {
@@ -211,4 +233,40 @@ public class PiecesView
 	public DownloadManager getManager() {
 		return manager;
 	}
+	
+	public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	     
+	        
+	      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	String id = "DMDetails_Pieces";
+	      	if (manager != null) {
+	      		if (manager.getTorrent() != null) {
+	  					id += "." + manager.getInternalName();
+	      		} else {
+	      			id += ":" + manager.getSize();
+	      		}
+	      	}
+	  
+	      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+	      		new SelectedContent(manager)
+	      	});
+	      	break;
+	    }
+	    
+	    return( super.eventOccurred(event));
+	}
+	
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if ( ViewUtils.toolBarItemActivated(manager, item, activationType, datasource)){
+			return( true );
+		}
+		return( super.toolBarItemActivated(item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(manager, list);
+		super.refreshToolBarItems(list);
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/ScrapeInfoView.java b/org/gudy/azureus2/ui/swt/views/ScrapeInfoView.java
new file mode 100644
index 0000000..c684f03
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/ScrapeInfoView.java
@@ -0,0 +1,442 @@
+package org.gudy.azureus2.ui.swt.views;
+
+import java.net.URL;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+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.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraper;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
+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.BufferedLabel;
+import org.gudy.azureus2.ui.swt.components.BufferedTruncatedLabel;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.maketorrent.MultiTrackerEditor;
+import org.gudy.azureus2.ui.swt.maketorrent.TrackerEditorListener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
+
+public class ScrapeInfoView
+	implements UISWTViewCoreEventListener
+{
+	private DownloadManager manager;
+
+	private Composite	cParent;
+	private Composite 	cScrapeInfoView;
+
+	private BufferedTruncatedLabel tracker_status;
+
+	private Button updateButton;
+
+	private BufferedLabel trackerUpdateIn;
+
+	private Menu menuTracker;
+
+	private MenuItem itemSelect;
+
+	private BufferedTruncatedLabel trackerUrlValue;
+
+	private long lastRefreshSecs;
+
+	private UISWTView swtView;
+
+	private String getFullTitle() {
+		return MessageText.getString("ScrapeInfoView.title");
+	}
+
+	private void initialize(Composite parent) {
+		cParent = parent;
+		Label label;
+		GridData gridData;
+		final Display display = parent.getDisplay();
+
+		if (cScrapeInfoView == null || cScrapeInfoView.isDisposed()) {
+			cScrapeInfoView = new Composite(parent, SWT.NONE);
+		}
+
+		gridData = new GridData(GridData.FILL_BOTH);
+		cScrapeInfoView.setLayoutData(gridData);
+
+		GridLayout layoutInfo = new GridLayout();
+		layoutInfo.numColumns = 4;
+		cScrapeInfoView.setLayout(layoutInfo);
+
+		label = new Label(cScrapeInfoView, SWT.LEFT);
+		Messages.setLanguageText(label, "GeneralView.label.trackerurl"); //$NON-NLS-1$
+		label.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
+		label.setForeground(Colors.blue);
+		label.addMouseListener(new MouseAdapter() {
+			public void mouseDoubleClick(MouseEvent arg0) {
+				String announce = trackerUrlValue.getText();
+				if (announce != null && announce.length() != 0) {
+					new Clipboard(display).setContents(new Object[] {
+						announce
+					}, new Transfer[] {
+						TextTransfer.getInstance()
+					});
+				}
+			}
+
+			public void mouseDown(MouseEvent arg0) {
+				String announce = trackerUrlValue.getText();
+				if (announce != null && announce.length() != 0) {
+					new Clipboard(display).setContents(new Object[] {
+						announce
+					}, new Transfer[] {
+						TextTransfer.getInstance()
+					});
+				}
+			}
+		});
+
+		menuTracker = new Menu(parent.getShell(), SWT.POP_UP);
+		itemSelect = new MenuItem(menuTracker, SWT.CASCADE);
+		Messages.setLanguageText(itemSelect, "GeneralView.menu.selectTracker");
+		MenuItem itemEdit = new MenuItem(menuTracker, SWT.NULL);
+		Messages.setLanguageText(itemEdit, "MyTorrentsView.menu.editTracker");
+
+		cScrapeInfoView.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				menuTracker.dispose();
+			}
+		});
+
+		itemEdit.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event e) {
+				final TOTorrent torrent = manager.getTorrent();
+
+				if (torrent == null) {
+					return;
+				}
+
+				List<List<String>> group = TorrentUtils.announceGroupsToList(torrent);
+
+				new MultiTrackerEditor(null,null, group, new TrackerEditorListener() {
+					public void trackersChanged(String str, String str2, List<List<String>> _group) {
+						TorrentUtils.listToAnnounceGroups(_group, torrent);
+
+						try {
+							TorrentUtils.writeToFile(torrent);
+						} catch (Throwable e2) {
+
+							Debug.printStackTrace(e2);
+						}
+
+						TRTrackerAnnouncer tc = manager.getTrackerClient();
+
+						if (tc != null) {
+
+							tc.resetTrackerUrl(true);
+						}
+					}
+				}, true);
+			}
+		});
+
+		final Listener menuListener = new Listener() {
+			public void handleEvent(Event e) {
+				if (e.widget instanceof MenuItem) {
+
+					String text = ((MenuItem) e.widget).getText();
+
+					TOTorrent torrent = manager.getTorrent();
+
+					TorrentUtils.announceGroupsSetFirst(torrent, text);
+
+					try {
+						TorrentUtils.writeToFile(torrent);
+
+					} catch (TOTorrentException f) {
+
+						Debug.printStackTrace(f);
+					}
+
+					TRTrackerAnnouncer tc = manager.getTrackerClient();
+
+					if (tc != null) {
+
+						tc.resetTrackerUrl(false);
+					}
+				}
+			}
+		};
+
+		menuTracker.addListener(SWT.Show, new Listener() {
+			public void handleEvent(Event e) {
+				Menu menuSelect = itemSelect.getMenu();
+				if (menuSelect != null && !menuSelect.isDisposed()) {
+					menuSelect.dispose();
+				}
+				if (manager == null || cScrapeInfoView == null
+						|| cScrapeInfoView.isDisposed()) {
+					return;
+				}
+				List<List<String>> groups = TorrentUtils.announceGroupsToList(manager.getTorrent());
+				menuSelect = new Menu(cScrapeInfoView.getShell(), SWT.DROP_DOWN);
+				itemSelect.setMenu(menuSelect);
+				
+				for (List<String> trackers : groups) {
+					MenuItem menuItem = new MenuItem(menuSelect, SWT.CASCADE);
+					Messages.setLanguageText(menuItem, "wizard.multitracker.group");
+					Menu menu = new Menu(cScrapeInfoView.getShell(), SWT.DROP_DOWN);
+					menuItem.setMenu(menu);
+					
+					for (String url : trackers) {
+						MenuItem menuItemTracker = new MenuItem(menu, SWT.CASCADE);
+						menuItemTracker.setText(url);
+						menuItemTracker.addListener(SWT.Selection, menuListener);
+					}
+				}
+			}
+		});
+
+		trackerUrlValue = new BufferedTruncatedLabel(cScrapeInfoView, SWT.LEFT, 70);
+
+		trackerUrlValue.addMouseListener(new MouseAdapter() {
+			public void mouseDown(MouseEvent event) {
+				if (event.button == 3
+						|| (event.button == 1 && event.stateMask == SWT.CONTROL)) {
+					menuTracker.setVisible(true);
+				} else if (event.button == 1) {
+					String url = trackerUrlValue.getText();
+					if (url.startsWith("http://") || url.startsWith("https://")) {
+						int pos = -1;
+						if ((pos = url.indexOf("/announce")) != -1) {
+							url = url.substring(0, pos + 1);
+						}
+						Utils.launch(url);
+					}
+				}
+			}
+		});
+
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 3;
+		trackerUrlValue.setLayoutData(gridData);
+
+		////////////////////////
+
+		label = new Label(cScrapeInfoView, SWT.LEFT);
+		Messages.setLanguageText(label, "GeneralView.label.tracker");
+		tracker_status = new BufferedTruncatedLabel(cScrapeInfoView, SWT.LEFT, 150);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 3;
+		tracker_status.setLayoutData(gridData);
+
+		label = new Label(cScrapeInfoView, SWT.LEFT);
+		Messages.setLanguageText(label, "GeneralView.label.updatein");
+		trackerUpdateIn = new BufferedLabel(cScrapeInfoView, SWT.LEFT);
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_CENTER);
+		trackerUpdateIn.setLayoutData(gridData);
+
+		updateButton = new Button(cScrapeInfoView, SWT.PUSH);
+		Messages.setLanguageText(updateButton, "GeneralView.label.trackerurlupdate");
+		updateButton.setLayoutData(new GridData());
+		updateButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent event) {
+				new AEThread2( "SIV:async" )
+				{
+					public void
+					run()
+					{
+						if ( manager.getTrackerClient() != null ){
+						
+							manager.requestTrackerAnnounce( false );
+							
+						}else{
+							
+							manager.requestTrackerScrape( true );
+						}
+					}
+				}.start();
+			}
+		});
+
+		cScrapeInfoView.layout(true);
+
+	}
+
+	private void refresh() {
+		if (manager == null) {
+			return;
+		}
+
+		long thisRefreshSecs = SystemTime.getCurrentTime() / 1000;
+		if (lastRefreshSecs != thisRefreshSecs) {
+			lastRefreshSecs = thisRefreshSecs;
+			setTracker();
+		}
+	}
+
+	private Composite getComposite() {
+		return cScrapeInfoView;
+	}
+
+	private void setTracker() {
+		if (cScrapeInfoView == null || cScrapeInfoView.isDisposed()) {
+			return;
+		}
+
+		Display display = cScrapeInfoView.getDisplay();
+
+		String status 	= manager.getTrackerStatus();
+		int time 		= manager.getTrackerTime();
+
+		TRTrackerAnnouncer trackerClient = manager.getTrackerClient();
+
+		if ( trackerClient != null ){
+			
+			tracker_status.setText( trackerClient.getStatusString());
+			
+			time = trackerClient.getTimeUntilNextUpdate();
+			
+		}else{
+			
+			tracker_status.setText( status );
+		}
+
+		if (time < 0) {
+
+			trackerUpdateIn.setText(MessageText.getString("GeneralView.label.updatein.querying"));
+
+		} else {
+
+			trackerUpdateIn.setText(TimeFormatter.formatColon(time));
+		}
+
+		boolean update_state;
+
+		String trackerURL = null;
+
+		if (trackerClient != null) {
+
+			URL temp = trackerClient.getTrackerURL();
+
+			if (temp != null) {
+
+				trackerURL = temp.toString();
+			}
+		}
+
+		if (trackerURL == null) {
+
+			TOTorrent torrent = manager.getTorrent();
+
+			if (torrent != null) {
+
+				trackerURL = torrent.getAnnounceURL().toString();
+			}
+		}
+
+		if (trackerURL != null) {
+
+			trackerUrlValue.setText(trackerURL);
+
+			if ((trackerURL.startsWith("http://") || trackerURL.startsWith("https://"))) {
+				trackerUrlValue.setForeground(Colors.blue);
+				trackerUrlValue.setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
+				Messages.setLanguageText(trackerUrlValue.getWidget(),
+						"GeneralView.label.trackerurlopen.tooltip", true);
+			} else {
+				trackerUrlValue.setForeground(null);
+				trackerUrlValue.setCursor(null);
+				Messages.setLanguageText(trackerUrlValue.getWidget(), null);
+				trackerUrlValue.setToolTipText(null);
+			}
+		}
+
+		if (trackerClient != null) {
+
+			update_state = ((SystemTime.getCurrentTime() / 1000
+					- trackerClient.getLastUpdateTime() >= TRTrackerAnnouncer.REFRESH_MINIMUM_SECS));
+
+		} else {
+			TRTrackerScraperResponse sr = manager.getTrackerScrapeResponse();
+			
+			if ( sr == null ){
+				
+				update_state = true;
+				
+			}else{
+				
+				update_state = ((SystemTime.getCurrentTime()
+						- sr.getScrapeStartTime() >= TRTrackerScraper.REFRESH_MINIMUM_SECS * 1000));
+			}
+		}
+
+		if (updateButton.getEnabled() != update_state) {
+
+			updateButton.setEnabled(update_state);
+		}
+		cScrapeInfoView.layout();
+	}
+
+	private void setDownlaodManager(DownloadManager dm) {
+		manager = dm;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if ( cScrapeInfoView != null ){
+					Utils.disposeComposite(cScrapeInfoView, false);
+				}
+				if ( cParent != null ){
+					
+					initialize( cParent );
+				}
+			}
+		});
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        //delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	Object ds = event.getData();
+      	if (ds instanceof DownloadManager) {
+					DownloadManager dm = (DownloadManager) ds;
+					setDownlaodManager(dm);
+				}
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
+}
diff --git a/org/gudy/azureus2/ui/swt/views/TorrentInfoView.java b/org/gudy/azureus2/ui/swt/views/TorrentInfoView.java
index 630ba11..2820fb8 100644
--- a/org/gudy/azureus2/ui/swt/views/TorrentInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/TorrentInfoView.java
@@ -42,23 +42,31 @@ import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLGroup;
 import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.download.DownloadTypeComplete;
+import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
+import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
 import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.BufferedLabel;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 import org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 
+import com.aelitis.azureus.ui.common.ToolBarItem;
 import com.aelitis.azureus.ui.common.table.TableCellCore;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
 
-import org.gudy.azureus2.plugins.download.*;
-import org.gudy.azureus2.plugins.ui.tables.TableManager;
-
-public class 
-TorrentInfoView
-	extends AbstractIView
+public class TorrentInfoView
+	implements UISWTViewCoreEventListener, UIPluginViewToolBarListener
 {
-	private static final String	TEXT_PREFIX	= "TorrentInfoView.";
+	public static final String MSGID_PREFIX = "TorrentInfoView";
 		
 	private DownloadManager			download_manager;
 		
@@ -70,13 +78,10 @@ TorrentInfoView
 	private ScrolledComposite sc;
 
 	private Composite parent;
+
+	private UISWTView swtView;
 	
-	protected
-	TorrentInfoView( )
-	{
-	}
-	
-	public void 
+	private void 
 	initialize(
 		Composite composite) 
 	{
@@ -94,9 +99,10 @@ TorrentInfoView
 		}
 
 		sc = new ScrolledComposite(composite, SWT.V_SCROLL | SWT.H_SCROLL );
+		sc.getVerticalBar().setIncrement(16);
 		sc.setExpandHorizontal(true);
 		sc.setExpandVertical(true);
-		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1);
+		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1);
 		sc.setLayoutData(gridData);	
 		
 		outer_panel = sc;
@@ -155,7 +161,7 @@ TorrentInfoView
 		Label label = new Label(gTorrentInfo, SWT.NULL);
 		gridData = new GridData();
 		label.setLayoutData( gridData );
-		label.setText( MessageText.getString( TEXT_PREFIX + "torrent.encoding" ) + ": " );
+		label.setText( MessageText.getString( MSGID_PREFIX + ".torrent.encoding" ) + ": " );
 
 		TOTorrent	torrent = download_manager.getTorrent();
 		BufferedLabel blabel = new BufferedLabel(gTorrentInfo, SWT.NULL);
@@ -179,7 +185,7 @@ TorrentInfoView
 			
 			TOTorrentAnnounceURLSet[]	sets = group.getAnnounceURLSets();
 			
-			List	tracker_list = new ArrayList();
+			List<String>	tracker_list = new ArrayList<String>();
 			
 			URL	url = torrent.getAnnounceURL();
 			
@@ -253,14 +259,14 @@ TorrentInfoView
 			// columns
 				 
 		Group gColumns = new Group(panel, SWT.NULL);
-		Messages.setLanguageText(gColumns, TEXT_PREFIX + "columns" );
-		gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
+		Messages.setLanguageText(gColumns, MSGID_PREFIX + ".columns" );
+		gridData = new GridData(GridData.FILL_BOTH);
 		gColumns.setLayoutData(gridData);
 		layout = new GridLayout();
 		layout.numColumns = 4;
 		gColumns.setLayout(layout);
 		
-		Map	usable_cols = new HashMap();
+		Map<String, FakeTableCell>	usable_cols = new HashMap<String, FakeTableCell>();
 		
 		TableColumnManager col_man = TableColumnManager.getInstance();
 		
@@ -288,9 +294,9 @@ TorrentInfoView
 				
 				FakeTableCell fakeTableCell = null;
 				try {
-  				fakeTableCell = new FakeTableCell(col);
+  				fakeTableCell = new FakeTableCell(col, download_manager);
   				fakeTableCell.setOrentation(SWT.LEFT);
-  				fakeTableCell.setDataSource(download_manager);
+  				fakeTableCell.setWrapText(false);
 					col.invokeCellAddedListeners(fakeTableCell);
   				// One refresh to see if it throws up
   				fakeTableCell.refresh();
@@ -308,7 +314,7 @@ TorrentInfoView
 			}
 		}
 		
-		Collection values = usable_cols.values();
+		Collection<FakeTableCell> values = usable_cols.values();
 		
 		cells = new FakeTableCell[values.size()];
 		
@@ -316,15 +322,11 @@ TorrentInfoView
 		
 		Arrays.sort( 
 				cells,
-				new Comparator()
+				new Comparator<FakeTableCell>()
 				{
-					public int
-					compare(
-						Object	o1,
-						Object	o2 )
-					{
-						TableColumnCore	c1 = (TableColumnCore) ((TableCellCore)o1).getTableColumn();
-						TableColumnCore	c2 = (TableColumnCore) ((TableCellCore)o2).getTableColumn();
+					public int compare(FakeTableCell o1, FakeTableCell o2) {
+						TableColumnCore	c1 = (TableColumnCore) o1.getTableColumn();
+						TableColumnCore	c2 = (TableColumnCore) o2.getTableColumn();
 
 						String key1 = MessageText.getString(c1.getTitleLanguageKey());
 						String key2 = MessageText.getString(c2.getTitleLanguageKey());
@@ -347,7 +349,7 @@ TorrentInfoView
 			label.setText(MessageText.getString(key) + ": ");
 			label.setToolTipText(MessageText.getString(key + ".info", ""));
 
-			final Composite c = new Composite(gColumns, SWT.NONE);
+			final Composite c = new Composite(gColumns, SWT.DOUBLE_BUFFERED);
 			gridData = new GridData( GridData.FILL_HORIZONTAL);
 			gridData.heightHint = 16;
 			c.setLayoutData(gridData);
@@ -370,7 +372,7 @@ TorrentInfoView
 		sc.setMinSize( panel.computeSize( SWT.DEFAULT, SWT.DEFAULT ));
 	}
 	
-	public void
+	private void
 	refresh()
 	{
 		if ( cells != null ){
@@ -385,29 +387,21 @@ TorrentInfoView
 	}
 
 	
-	public Composite 
+	private Composite 
 	getComposite() 
 	{
 		return outer_panel;
 	}
 	
-	public String 
+	private String 
 	getFullTitle() 
 	{
-		return MessageText.getString("GeneralView.section.info");
+		return MessageText.getString("TorrentInfoView.title.full");
 	}
 
-	public String 
-	getData() 
-	{
-		return( "GeneralView.section.info" );
-	}
-	
-	public void 
+	private void 
 	delete()
 	{
-		super.delete();
-		
 		if ( headerFont != null ){
 			
 			headerFont.dispose();
@@ -424,13 +418,74 @@ TorrentInfoView
 		}
 	}
 	
-	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#dataSourceChanged(java.lang.Object)
-	public void dataSourceChanged(Object newDataSource) {
+	private void dataSourceChanged(Object newDataSource) {
 		if (newDataSource instanceof DownloadManager) {
 			download_manager = (DownloadManager) newDataSource;
 		}
-		if (parent != null) {
-			initialize(parent);
-		}
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (parent != null) {
+					initialize(parent);
+				}
+			}
+		});
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+      	swtView.setToolBarListener(this);
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	String id = "DMDetails_Info";
+	      	if (download_manager != null) {
+	      		if (download_manager.getTorrent() != null) {
+	  					id += "." + download_manager.getInternalName();
+	      		} else {
+	      			id += ":" + download_manager.getSize();
+	      		}
+	      	}
+	  
+	      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+	      		new SelectedContent(download_manager)
+	      	});
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
+	
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		return( ViewUtils.toolBarItemActivated(download_manager, item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(download_manager, list);
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java b/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
index a120440..9177d73 100644
--- a/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
+++ b/org/gudy/azureus2/ui/swt/views/TorrentOptionsView.java
@@ -22,13 +22,13 @@
 
 package org.gudy.azureus2.ui.swt.views;
 
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
+import java.util.*;
+import java.util.Map.Entry;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
@@ -37,22 +37,28 @@ import org.gudy.azureus2.core3.config.COConfigurationManager;
 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.DownloadManagerStats;
 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.core3.util.DisplayFormatters;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.BufferedLabel;
 import org.gudy.azureus2.ui.swt.config.ChangeSelectionActionPerformer;
 import org.gudy.azureus2.ui.swt.config.generic.GenericBooleanParameter;
 import org.gudy.azureus2.ui.swt.config.generic.GenericIntParameter;
 import org.gudy.azureus2.ui.swt.config.generic.GenericParameterAdapter;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 public class 
 TorrentOptionsView
-	extends AbstractIView
-	implements DownloadManagerStateAttributeListener
+	implements DownloadManagerStateAttributeListener, UISWTViewCoreEventListener
 {
 	private static final String	TEXT_PREFIX	= "TorrentOptionsView.param.";
 	
@@ -60,6 +66,8 @@ TorrentOptionsView
 	
 	private static final String	MAX_UPLOAD		= "max.upload";
 	private static final String	MAX_DOWNLOAD	= "max.download";
+
+	public static final String MSGID_PREFIX = "TorrentOptionsView";
 	
 	private boolean						multi_view;
 	private DownloadManager[]			managers;
@@ -67,13 +75,25 @@ TorrentOptionsView
 	private GenericParameterAdapter	ds_param_adapter	= new downloadStateParameterAdapter();
 	private GenericParameterAdapter	adhoc_param_adapter	= new adhocParameterAdapter();
 	
-	private Map adhoc_parameters	= new HashMap();
-	private Map	ds_parameters 		= new HashMap();
+	private Map<String, Object> adhoc_parameters	= new HashMap<String, Object>();
+	private Map<String, Object>	ds_parameters 		= new HashMap<String, Object>();
 	
 	private Composite 			panel;
 	private Font 				headerFont;
 
+	// info panel
+	
+	private BufferedLabel	agg_size;
+	private BufferedLabel	agg_uploaded;
+	private BufferedLabel	agg_downloaded;
+	private BufferedLabel	agg_share_ratio;
+	private BufferedLabel	agg_upload_speed;
+	private BufferedLabel	agg_download_speed;
+	
+	
 	private Composite parent;
+
+	private UISWTView swtView;
 	
 	public
 	TorrentOptionsView()
@@ -87,30 +107,40 @@ TorrentOptionsView
 		dataSourceChanged(managers2);
 	}
 
-	public void 
+	private void 
 	initialize(
 		Composite composite) 
 	{
 		this.parent = composite;
 		
-		if (managers == null) {
-			return;
-		}
-
+		GridLayout layout;
+		
 		// cheap trick to allow datasource changes.  Normally we'd just
 		// refill the components with new info, but I didn't write this and
 		// I don't want to waste my time :) [tux]
 		if (panel != null && !panel.isDisposed()) {
-			panel.dispose();
+			Utils.disposeComposite(panel, false);
+		} else {
+			panel = new Composite(composite, SWT.NULL);
+
+			layout = new GridLayout();
+			layout.marginHeight = 0;
+			layout.marginWidth = 0;
+			layout.numColumns = 1;
+			panel.setLayout(layout);
+			
+			Layout parentLayout = parent.getLayout();
+			if (parentLayout instanceof FormLayout) {
+				panel.setLayoutData(Utils.getFilledFormData());
+			} else {
+				panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+			}
 		}
 
-		panel = new Composite(composite, SWT.NULL);
 		
-		GridLayout layout = new GridLayout();
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		layout.numColumns = 1;
-		panel.setLayout(layout);
+		if (managers == null) {
+			return;
+		}
 
 		int userMode = COConfigurationManager.getIntParameter("User Mode");
 
@@ -341,6 +371,28 @@ TorrentOptionsView
 			max_seeds.setLayoutData(gridData);
 		}
 		
+			// upload priority
+		
+		if ( userMode > 0){
+			
+			label = new Label(gTorrentOptions, SWT.NULL);
+			gridData = new GridData();
+			label.setLayoutData( gridData );
+			Messages.setLanguageText(label, TEXT_PREFIX + "upload.priority" );
+			
+			gridData = new GridData();
+			GenericIntParameter	upload_priority_enabled = 
+				new GenericIntParameter( 
+						ds_param_adapter, 
+						gTorrentOptions, 
+						DownloadManagerState.PARAM_UPLOAD_PRIORITY, 0, 1 );
+						
+			ds_parameters.put( DownloadManagerState.PARAM_UPLOAD_PRIORITY, upload_priority_enabled );
+			upload_priority_enabled.setLayoutData( gridData );		
+		}
+		
+			// reset
+		
 	    Label reset_label = new Label(gTorrentOptions, SWT.NULL );
 	    Messages.setLanguageText(reset_label, TEXT_PREFIX + "reset.to.default");
 
@@ -361,12 +413,159 @@ TorrentOptionsView
 	    for (int i=0;i<managers.length;i++){		
 	    	managers[i].getDownloadState().addListener(this, DownloadManagerState.AT_PARAMETERS, DownloadManagerStateAttributeListener.WRITTEN);
 	    }
+	    
+	    
+		Group gTorrentInfo = new Group(panel, SWT.NULL);
+		Messages.setLanguageText(gTorrentInfo, "label.aggregate.info");
+		gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL);
+		gTorrentInfo.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		gTorrentInfo.setLayout(layout);
+
+			// total size
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "TableColumn.header.size" ) + ": " );
+	    
+		agg_size = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_size.setLayoutData( gridData );
+
+			// uploaded
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "MyTrackerView.uploaded" ) + ": " );
+	    
+		agg_uploaded = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_uploaded.setLayoutData( gridData );
+
+			// downloaded
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "MyTrackerView.downloaded" ) + ": " );
+	    
+		agg_downloaded = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_downloaded.setLayoutData( gridData );
+
+			// upload speed
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "SpeedView.uploadSpeed.title" ) + ": " );
+	    
+		agg_upload_speed = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_upload_speed.setLayoutData( gridData );
+
+			// download speed
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "SpeedView.downloadSpeed.title" ) + ": " );
+	    
+		agg_download_speed = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_download_speed.setLayoutData( gridData );
+		
+			// share ratio
+		
+		label = new Label(gTorrentInfo, SWT.NULL );
+	    label.setText( MessageText.getString( "TableColumn.header.shareRatio" ) + ": " );
+	    
+		agg_share_ratio = new BufferedLabel( gTorrentInfo, SWT.LEFT | SWT.DOUBLE_BUFFERED );
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		agg_share_ratio.setLayoutData( gridData );
+	
+	
+	    panel.layout(true, true);
+	}
+	
+	private void
+	refresh()
+	{
+		long	total_size 				= 0;
+		long	total_good_downloaded	= 0;
+		long	total_downloaded		= 0;
+		long	total_uploaded			= 0;
+		
+		long	total_data_up_speed		= 0;
+		long	total_prot_up_speed		= 0;
+		
+		long	total_data_down_speed		= 0;
+		long	total_prot_down_speed		= 0;
+		
+		for (int i=0;i<managers.length;i++){		
+
+			DownloadManager	dm = managers[i];
+
+			total_size += dm.getSize();
+
+			DownloadManagerStats stats = dm.getStats();
+
+			long	good_received 	= stats.getTotalGoodDataBytesReceived();
+			long	received 		= stats.getTotalDataBytesReceived();
+			long	sent			= stats.getTotalDataBytesSent();
+
+			total_good_downloaded 	+= good_received;
+			total_downloaded 		+= received;
+			total_uploaded			+= sent;
+			
+			total_data_up_speed 		+= stats.getDataSendRate();
+			total_prot_up_speed 		+= stats.getProtocolSendRate();
+			
+			total_data_down_speed 	+= stats.getDataReceiveRate();
+			total_prot_down_speed 	+= stats.getProtocolReceiveRate();
+		}
+		
+		agg_size.setText( DisplayFormatters.formatByteCountToKiBEtc( total_size ));
+		agg_uploaded.setText( DisplayFormatters.formatByteCountToKiBEtc( total_uploaded ));
+		agg_downloaded.setText( DisplayFormatters.formatByteCountToKiBEtc( total_downloaded ));
+		
+		agg_upload_speed.setText( DisplayFormatters.formatDataProtByteCountToKiBEtc( total_data_up_speed, total_prot_up_speed ));
+		agg_download_speed.setText( DisplayFormatters.formatDataProtByteCountToKiBEtc( total_data_down_speed, total_prot_down_speed));
+		
+		long	sr;
+		
+		if ( total_good_downloaded == 0 ){
+			
+			if ( total_uploaded == 0 ){
+				
+				sr = 1;
+			}else{
+				
+				sr = -1;
+			}
+		}else{
+			
+			sr = 1000*total_uploaded/total_good_downloaded;
+		}
+		
+		String	share_ratio_str;
+		
+		if ( sr == -1 ){
+			
+			share_ratio_str = Constants.INFINITY_STRING;
+			
+		}else{
+			
+			String partial = "" + sr%1000;
+			
+			while( partial.length() < 3 ){
+				
+				partial = "0" + partial;
+			}
+			
+			share_ratio_str = (sr/1000) + "." + partial;
+		}
+		
+		agg_share_ratio.setText( share_ratio_str );
 	}
 	
 	protected void
 	setDefaults()
 	{
-		Iterator	it = ds_parameters.keySet().iterator();
+		Iterator<?>	it = ds_parameters.keySet().iterator();
 		
 		while( it.hasNext()){
 						
@@ -396,14 +595,17 @@ TorrentOptionsView
 		}
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.core3.download.DownloadManagerStateAttributeListener#attributeEventOccurred(org.gudy.azureus2.core3.download.DownloadManager, java.lang.String, int)
+	 */
 	public void attributeEventOccurred(DownloadManager dm, String attribute_name, int event_type) {
 		final DownloadManagerState state = dm.getDownloadState();
 		Utils.execSWTThread(new Runnable() {
 			public void	run() {
-				Iterator it = ds_parameters.entrySet().iterator();
+				Iterator<Entry<String, Object>> it = ds_parameters.entrySet().iterator();
 				while (it.hasNext()) {
-					Map.Entry	entry = (Map.Entry)it.next();
-					String	key 	= (String)entry.getKey();
+					Map.Entry<String, Object>	entry = it.next();
+					String	key 	= entry.getKey();
 					Object	param 	= entry.getValue();
 								
 					if (param instanceof GenericIntParameter) {
@@ -422,29 +624,21 @@ TorrentOptionsView
 		}, true);
 	}
 	
-	public Composite 
+	private Composite 
 	getComposite() 
 	{
 		return panel;
 	}
 	
-	public String 
+	private String 
 	getFullTitle() 
 	{
 		return MessageText.getString( multi_view?"TorrentOptionsView.multi.title.full":"TorrentOptionsView.title.full");
 	}
 
-	public String 
-	getData() 
-	{
-		return MessageText.getString( multi_view?"TorrentOptionsView.multi.title.short":"TorrentOptionsView.title.short");
-	}
-	
-	public void 
+	private void 
 	delete()
 	{
-		super.delete();
-		
 		if ( headerFont != null ){
 			
 			headerFont.dispose();
@@ -634,8 +828,7 @@ TorrentOptionsView
 		}
 	}
 	
-	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#dataSourceChanged(java.lang.Object)
-	public void dataSourceChanged(Object newDataSource) {
+	private void dataSourceChanged(Object newDataSource) {
 		if (newDataSource instanceof DownloadManager) {
 			multi_view = false;
 			managers = new DownloadManager[] { (DownloadManager) newDataSource };
@@ -644,7 +837,46 @@ TorrentOptionsView
 			managers = (DownloadManager[]) newDataSource;
 		}
 		if (parent != null) {
-			initialize(parent);
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					initialize(parent);
+				}
+			});
 		}
 	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+    	refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/TrackerView.java b/org/gudy/azureus2/ui/swt/views/TrackerView.java
new file mode 100644
index 0000000..f7f2ad2
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/TrackerView.java
@@ -0,0 +1,369 @@
+/*
+ * Created on 2 juil. 2003
+ *
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerTPSListener;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.TorrentUtils;
+import org.gudy.azureus2.plugins.ui.tables.TableManager;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.maketorrent.MultiTrackerEditor;
+import org.gudy.azureus2.ui.swt.maketorrent.TrackerEditorListener;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTInstanceImpl;
+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.TableViewFactory;
+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.tableitems.tracker.*;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+
+
+
+public class TrackerView 
+	extends TableViewTab<TrackerPeerSource>
+	implements 	TableLifeCycleListener, TableDataSourceChangedListener, 
+				DownloadManagerTPSListener, TableViewSWTMenuFillListener
+{
+	private static boolean registeredCoreSubViews = false;
+
+	private final static TableColumnCore[] basicItems = {
+		new TypeItem(),
+		new NameItem(),
+		new StatusItem(),
+		new PeersItem(),
+		new SeedsItem(),
+		new LeechersItem(),
+		new UpdateInItem(),
+		new IntervalItem(),
+	};
+
+	public static final String MSGID_PREFIX = "TrackerView";
+
+	DownloadManager manager;
+  
+	private TableViewSWT<TrackerPeerSource> tv;
+
+	/**
+	 * Initialize
+	 *
+	 */
+	public TrackerView() {
+		super(MSGID_PREFIX);
+	}
+
+	public TableViewSWT<TrackerPeerSource>
+	initYourTableView() 
+	{
+		tv = TableViewFactory.createTableViewSWT(
+				TrackerPeerSource.class,
+				TableManager.TABLE_TORRENT_TRACKERS, 
+				getPropertiesPrefix(), 
+				basicItems,
+				basicItems[0].getName(), 
+				SWT.SINGLE | SWT.FULL_SELECTION | SWT.VIRTUAL );
+
+		tv.addLifeCycleListener(this);
+		tv.addMenuFillListener(this);
+		tv.addTableDataSourceChangedListener(this, true);
+		tv.setEnableTabViews(true);
+		
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+			
+			if (pluginUI != null && !registeredCoreSubViews) {
+
+				pluginUI.addView(TableManager.TABLE_TORRENT_TRACKERS, "ScrapeInfoView",
+						ScrapeInfoView.class, manager);
+
+				registeredCoreSubViews = true;
+			}
+		}
+
+		return tv;
+	}
+
+	
+	public void 
+	fillMenu(
+		String sColumnName, Menu menu) 
+	{
+		final Object[] sources = tv.getSelectedDataSources().toArray();
+		
+		boolean	found_tracker	= false;
+		boolean	update_ok 		= false;
+		
+		for ( Object o: sources ){
+	
+			TrackerPeerSource ps = (TrackerPeerSource)o;
+		
+			if ( ps.getType() == TrackerPeerSource.TP_TRACKER ){
+				
+				found_tracker = true;
+			}
+			
+			int	state = ps.getStatus();
+						
+			if ( 	( 	state == TrackerPeerSource.ST_ONLINE || 
+						state == TrackerPeerSource.ST_QUEUED || 
+						state == TrackerPeerSource.ST_ERROR ) &&
+					!ps.isUpdating() &&
+					ps.canManuallyUpdate()){
+				
+				update_ok = true;
+				
+				break;
+			}
+		}
+		
+		if ( found_tracker ){
+			final MenuItem update_item = new MenuItem( menu, SWT.PUSH);
+	
+			Messages.setLanguageText(update_item, "GeneralView.label.trackerurlupdate");
+			
+			update_item.setEnabled( update_ok );
+			
+			update_item.addListener(
+				SWT.Selection, 
+				new TableSelectedRowsListener(tv) 
+				{
+					public void 
+					run(
+						TableRowCore row )
+					{
+						for ( Object o: sources ){
+							
+							TrackerPeerSource ps = (TrackerPeerSource)o;
+	
+							if ( ps.canManuallyUpdate()){
+								
+								ps.manualUpdate();
+							}
+						}
+					}
+				});
+			
+			final MenuItem edit_item = new MenuItem( menu, SWT.PUSH);
+			
+			Messages.setLanguageText(edit_item, "MyTorrentsView.menu.editTracker");
+						
+			edit_item.addListener(
+				SWT.Selection, 
+				new TableSelectedRowsListener(tv) 
+				{
+					public void 
+					run(
+						TableRowCore row )
+					{
+						final TOTorrent torrent = manager.getTorrent();
+
+						if (torrent == null) {
+							return;
+						}
+
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									List<List<String>> group = TorrentUtils.announceGroupsToList(torrent);
+			
+									new MultiTrackerEditor(null,null, group, new TrackerEditorListener() {
+										public void trackersChanged(String str, String str2, List<List<String>> _group) {
+											TorrentUtils.listToAnnounceGroups(_group, torrent);
+			
+											try {
+												TorrentUtils.writeToFile(torrent);
+											} catch (Throwable e2) {
+			
+												Debug.printStackTrace(e2);
+											}
+			
+											TRTrackerAnnouncer tc = manager.getTrackerClient();
+			
+											if (tc != null) {
+			
+												tc.resetTrackerUrl(true);
+											}
+										}
+									}, true);
+								}
+							});
+					}
+				});
+			
+			new MenuItem( menu, SWT.SEPARATOR );
+		}
+	}
+	
+	public void 
+	addThisColumnSubMenu(
+		String columnName, 
+		Menu menuThisColumn) 
+	{
+	}
+	
+	public void 
+	trackerPeerSourcesChanged() 
+	{
+		Utils.execSWTThread(
+			new AERunnable() 
+			{
+				public void
+				runSupport()
+				{
+					if ( manager == null || tv.isDisposed()){
+						
+						return;
+					}
+					
+					tv.removeAllTableRows();
+					
+					addExistingDatasources();
+				}
+			});
+	}
+	
+	public void 
+	tableDataSourceChanged(
+		Object newDataSource ) 
+	{
+	  	if ( manager != null ){
+	  		
+	  		manager.removeTPSListener( this );
+		}
+	
+		if ( newDataSource == null ){
+			
+			manager = null;
+			
+		}else if ( newDataSource instanceof Object[] ){
+		
+			manager = (DownloadManager)((Object[])newDataSource)[0];
+			
+		}else{
+			
+			manager = (DownloadManager)newDataSource;
+		}
+		
+	  	if ( manager != null && !tv.isDisposed()){
+	    	
+  			manager.addTPSListener( this );
+	  		
+	    	addExistingDatasources();
+	    }
+	}
+	
+	public void 
+	tableViewInitialized() 
+	{
+		if ( manager != null ){
+
+			manager.addTPSListener( this );
+			
+			addExistingDatasources();
+		}
+    }
+
+	public void 
+	tableViewDestroyed() 
+	{
+		if ( manager != null ){
+			
+			manager.removeTPSListener( this );
+		}
+	}
+
+	private void 
+	addExistingDatasources() 
+	{
+		if ( manager == null || tv.isDisposed()){
+			
+			return;
+		}
+
+		List<TrackerPeerSource> tps = manager.getTrackerPeerSources();
+		
+		tv.addDataSources( tps.toArray( (new TrackerPeerSource[tps.size()])));
+		
+		tv.processDataSourceQueue();
+	}
+	
+	public boolean eventOccurred(UISWTViewEvent event) {
+	    switch (event.getType()) {
+	     
+	        
+	      case UISWTViewEvent.TYPE_FOCUSGAINED:
+	      	String id = "DMDetails_Sources";
+	      	if (manager != null) {
+	      		if (manager.getTorrent() != null) {
+	  					id += "." + manager.getInternalName();
+	      		} else {
+	      			id += ":" + manager.getSize();
+	      		}
+	      	}
+	  
+	      	SelectedContentManager.changeCurrentlySelectedContent(id, new SelectedContent[] {
+	      		new SelectedContent(manager)
+	      	});
+	      	break;
+	    }
+	    
+	    return( super.eventOccurred(event));
+	}
+	
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if ( ViewUtils.toolBarItemActivated(manager, item, activationType, datasource)){
+			return( true );
+		}
+		return( super.toolBarItemActivated(item, activationType, datasource));
+	}
+
+	public void refreshToolBarItems(Map<String, Long> list) {
+		ViewUtils.refreshToolBarItems(manager, list);
+		super.refreshToolBarItems(list);
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/ViewUtils.java b/org/gudy/azureus2/ui/swt/views/ViewUtils.java
index 38ae173..a458e06 100644
--- a/org/gudy/azureus2/ui/swt/views/ViewUtils.java
+++ b/org/gudy/azureus2/ui/swt/views/ViewUtils.java
@@ -24,16 +24,37 @@
  
 package org.gudy.azureus2.ui.swt.views;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 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.internat.MessageText;
+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.SystemTime;
+import org.gudy.azureus2.plugins.ui.UIInputReceiver;
+import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
 import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+
+import com.aelitis.azureus.ui.common.ToolBarItem;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
 
 /**
  * @author parg
@@ -42,6 +63,185 @@ import org.gudy.azureus2.ui.swt.Utils;
 public class 
 ViewUtils 
 {
+	private static SimpleDateFormat formatOverride = null;
+	
+	static{
+		COConfigurationManager.addAndFireParameterListener(
+			"Table.column.dateformat", new ParameterListener() {
+				public void parameterChanged(String parameterName) {
+					String temp = COConfigurationManager.getStringParameter(
+										"Table.column.dateformat", "");
+					
+					if ( temp == null || temp.trim().length() == 0 ){
+						
+						formatOverride = null;
+						
+					}else{
+						
+						try{
+							SimpleDateFormat format = new SimpleDateFormat( temp.trim());
+							
+							format.format(new Date());
+							
+							formatOverride = format;
+							
+						}catch( Throwable e ){
+							
+							formatOverride = null;
+						}
+					}
+				}
+			});
+	}
+	
+	public static String
+	formatETA(
+		long				value,
+		boolean				absolute,
+		SimpleDateFormat	override )
+	{
+		SimpleDateFormat df = override!=null?override:formatOverride;
+		
+		if (	absolute && 
+				df != null && 
+				value > 0 && 
+				!(value == Constants.CRAPPY_INFINITY_AS_INT || value >= Constants.CRAPPY_INFINITE_AS_LONG )){
+			
+			try{
+				return( df.format( new Date( SystemTime.getCurrentTime() + 1000*value )));
+				
+			}catch( Throwable e ){
+			}
+		}
+		
+		return( DisplayFormatters.formatETA( value, absolute ));
+	}
+	
+
+	public static class
+	CustomDateFormat
+	{
+		private CoreTableColumn			column;
+		private TableContextMenuItem	custom_date_menu;
+		private SimpleDateFormat		custom_date_format;
+
+		private
+		CustomDateFormat(
+			CoreTableColumn	_column )
+		{
+			column	= _column;
+			
+			custom_date_menu = column.addContextMenuItem(
+					"label.date.format", CoreTableColumn.MENU_STYLE_HEADER );
+			custom_date_menu.setStyle(TableContextMenuItem.STYLE_PUSH);
+			
+			custom_date_menu.addListener(new MenuItemListener() {
+				public void selected(org.gudy.azureus2.plugins.ui.menus.MenuItem menu, Object target){
+					
+					Object existing_o = column.getUserData( "CustomDate" );
+					
+					String existing_text = "";
+					
+					if ( existing_o instanceof String ){
+						existing_text = (String)existing_o;
+					}else if ( existing_o instanceof byte[] ){
+						try{
+							existing_text = new String((byte[])existing_o, "UTF-8" );
+						}catch( Throwable e ){
+						}
+					}
+					SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow(
+							"ConfigView.section.style.customDateFormat",
+							"label.date.format");
+					
+					entryWindow.setPreenteredText( existing_text, false );
+					
+					entryWindow.prompt(new UIInputReceiverListener() {
+						public void UIInputReceiverClosed(UIInputReceiver entryWindow) {
+							if (!entryWindow.hasSubmittedInput()) {
+								return;
+							}
+							String date_format = entryWindow.getSubmittedInput();
+							
+							if ( date_format == null ){
+								return;
+							}
+							
+							date_format = date_format.trim();
+							
+							column.setUserData( "CustomDate", date_format );
+							
+							column.invalidateCells();
+							
+							update();
+						}
+					});
+				}
+			});
+		}
+			
+		public void
+		update()
+		{
+			Object cd = column.getUserData( "CustomDate" );
+			
+			String	format = null;
+			
+			if ( cd instanceof byte[]){
+				
+				try{
+					cd = new String((byte[])cd, "UTF-8");
+					
+				}catch( Throwable e ){
+					
+				}
+			}
+			
+			if ( cd instanceof String ){
+				
+				String	str = (String)cd;
+				
+				str = str.trim();
+				
+				if ( str.length() > 0 ){
+					
+					format = str;
+				}
+			}
+			
+			if ( format == null ){
+				
+				format = MessageText.getString( "label.table.default" );
+				
+				custom_date_format = null;
+				
+			}else{
+				
+				try{
+					custom_date_format = new SimpleDateFormat( format );
+					
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+				}
+			}
+			
+			custom_date_menu.setText( MessageText.getString( "label.date.format" )  + " <" + format + "> ..." );
+		}
+		
+		public SimpleDateFormat
+		getDateFormat()
+		{
+			return( custom_date_format );
+		}
+	}
+	
+	public static CustomDateFormat
+	addCustomDateFormat(
+		CoreTableColumn	column )
+	{
+		return( new CustomDateFormat( column ));
+	}
 	public static void
 	addSpeedMenu(
 		final Shell 		shell,
@@ -346,6 +546,45 @@ ViewUtils
 		return result;
 	}
 	
+	public static boolean toolBarItemActivated( DownloadManager manager, ToolBarItem item, long activationType,
+			Object datasource) {
+		String itemKey = item.getID();
+
+		if (itemKey.equals("run")) {
+			ManagerUtils.run(manager);
+			return true;
+		}
+		
+		if (itemKey.equals("start")) {
+			ManagerUtils.queue(manager, null);
+			UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+			return true;
+		}
+		
+		if (itemKey.equals("stop")) {
+			ManagerUtils.stop(manager, null);
+			UIFunctionsManagerSWT.getUIFunctionsSWT().refreshIconBar();
+			return true;
+		}
+		
+		if (itemKey.equals("remove")) {
+			TorrentUtil.removeDownloads(new DownloadManager[] {
+				manager
+			}, null);
+			return true;
+		}
+		
+		return false;
+	}
+
+	public static void refreshToolBarItems( DownloadManager manager, Map<String, Long> list) {
+		list.put("run", UIToolBarItem.STATE_ENABLED);
+		list.put("start", ManagerUtils.isStartable(manager) ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("startstop", UIToolBarItem.STATE_ENABLED);
+		list.put("stop", ManagerUtils.isStopable(manager) ? UIToolBarItem.STATE_ENABLED : 0);
+		list.put("remove", UIToolBarItem.STATE_ENABLED);
+	}	
+	
 	public interface
 	SpeedAdapter
 	{
@@ -357,4 +596,22 @@ ViewUtils
 		setDownSpeed(
 			int		val );
 	}
+	
+	public interface
+	ViewTitleExtraInfo
+	{
+		public void
+		update(
+			Composite	composite,
+			boolean		seeding_view,
+			int			count,
+			int			active );
+			
+		public void
+		setEnabled(
+			Composite	composite,
+			boolean		seeding_view,
+			boolean		enabled );
+			
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java
index 812d21a..3869148 100644
--- a/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java
+++ b/org/gudy/azureus2/ui/swt/views/clientstats/ClientStatsView.java
@@ -10,13 +10,16 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
 
-import org.gudy.azureus2.core3.download.*;
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerPeerListener;
+import org.gudy.azureus2.core3.download.DownloadManagerState;
 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.core3.util.DisplayFormatters;
+import org.gudy.azureus2.core3.util.FileUtil;
+import org.gudy.azureus2.core3.util.SystemTime;
 import org.gudy.azureus2.plugins.ui.UIManager;
 import org.gudy.azureus2.plugins.ui.tables.TableColumn;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
@@ -25,9 +28,8 @@ 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.TableViewFactory;
 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;
@@ -38,6 +40,7 @@ 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.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.util.MapUtils;
 
 public class ClientStatsView
@@ -57,7 +60,7 @@ public class ClientStatsView
 
 	private AzureusCore core;
 
-	private TableViewSWTImpl<ClientStatsDataSource> tv;
+	private TableViewSWT<ClientStatsDataSource> tv;
 
 	private boolean columnsAdded;
 
@@ -199,6 +202,7 @@ public class ClientStatsView
 						return v1 > v2 ? -1 : 1;
 					}
 				});
+				/*
 				int top = 5;
 				first = true;
 				sb.append("\nBest Seeders (");
@@ -302,7 +306,7 @@ public class ClientStatsView
 						break;
 					}
 				}
-
+				*/
 				ClipboardCopy.copyToClipBoard(sb.toString());
 			}
 		});
@@ -312,7 +316,7 @@ public class ClientStatsView
 	}
 
 	public TableViewSWT<ClientStatsDataSource> initYourTableView() {
-		tv = new TableViewSWTImpl<ClientStatsDataSource>(
+		tv = TableViewFactory.createTableViewSWT(
 				ClientStatsDataSource.class, TABLEID, getPropertiesPrefix(),
 				new TableColumnCore[0], ColumnCS_Count.COLUMN_ID, SWT.MULTI
 						| SWT.FULL_SELECTION | SWT.VIRTUAL);
@@ -354,6 +358,7 @@ public class ClientStatsView
 						new ColumnCS_Count(column);
 					}
 				});
+		/*
 		tableManager.registerColumn(ClientStatsDataSource.class,
 				ColumnCS_Discarded.COLUMN_ID, new TableColumnCreationListener() {
 					public void tableColumnCreated(TableColumn column) {
@@ -378,6 +383,7 @@ public class ClientStatsView
 						new ColumnCS_Sent(column);
 					}
 				});
+		*/
 		tableManager.registerColumn(ClientStatsDataSource.class,
 				ColumnCS_Pct.COLUMN_ID, new TableColumnCreationListener() {
 					public void tableColumnCreated(TableColumn column) {
@@ -390,9 +396,11 @@ public class ClientStatsView
 			ColumnCS_Name.COLUMN_ID,
 			ColumnCS_Pct.COLUMN_ID,
 			ColumnCS_Count.COLUMN_ID,
+			/*
 			ColumnCS_Received.COLUMN_ID,
 			ColumnCS_Sent.COLUMN_ID,
 			ColumnCS_Discarded.COLUMN_ID,
+			*/
 		});
 	}
 
diff --git a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_ChosenColumn.java b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_ChosenColumn.java
index 88773fe..923a7a7 100644
--- a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_ChosenColumn.java
+++ b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_ChosenColumn.java
@@ -19,15 +19,12 @@
 package org.gudy.azureus2.ui.swt.views.columnsetup;
 
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
-import com.aelitis.azureus.ui.common.table.TableCellCore;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
 
-import org.gudy.azureus2.plugins.ui.tables.TableCell;
-import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
-
 /**
  * @author TuxPaper
  * @created Jan 3, 2009
@@ -51,17 +48,15 @@ public class ColumnTC_ChosenColumn
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
 	public void refresh(TableCell cell) {
 		TableColumnCore column = (TableColumnCore) cell.getDataSource();
-		String key = column.getTitleLanguageKey();
-		if (!cell.setSortValue(column.getPosition()) && cell.isValid()) {
+		int colPos = column.getPosition();
+		// colPos can have gaps in numbers
+		if (!cell.setSortValue(colPos) && cell.isValid()) {
 			return;
 		}
-		String s = "";
-		try {
-			s = (((TableCellCore) cell).getTableRowCore().getIndex() + 1) + ". ";
-		} catch (Throwable e) {
-		}
-		s += MessageText.getString(key, column.getName());
+		String key = column.getTitleLanguageKey();
+		String s = MessageText.getString(key, column.getName());
 		//s = column.getPosition() + "] " + s;
 		cell.setText(s);
+		cell.setToolTip("");
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_NameInfo.java b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_NameInfo.java
index f8a7e24..41d6f83 100644
--- a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_NameInfo.java
+++ b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_NameInfo.java
@@ -22,22 +22,20 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.*;
 
 import org.gudy.azureus2.core3.internat.MessageText;
-import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.plugins.ui.tables.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
-import org.gudy.azureus2.ui.swt.views.columnsetup.TableColumnSetupWindow.TableViewColumnSetup;
 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 org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
 
 import com.aelitis.azureus.ui.common.table.TableCellCore;
 import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableView;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.swt.utils.ColorCache;
 
-import org.gudy.azureus2.plugins.ui.tables.*;
-
 /**
  * @author TuxPaper
  * @created Jan 3, 2009
@@ -106,7 +104,7 @@ public class ColumnTC_NameInfo
 				+ 5, bounds.width - 15, bounds.height - 20);
 		GCStringPrinter.printString(gc, info, infoBounds, true, false);
 
-		TableColumnInfo columnInfo = (TableColumnInfo) cell.getTableRowCore().getData(
+		TableColumnInfo columnInfo = (TableColumnInfo) cell.getTableRow().getData(
 				"columninfo");
 		if (columnInfo == null) {
 			final TableColumnManager tcm = TableColumnManager.getInstance();
@@ -117,18 +115,19 @@ public class ColumnTC_NameInfo
 		Rectangle profBounds = new Rectangle(bounds.width - 100, bounds.y - 2, 100, 20);
 		byte proficiency = columnInfo.getProficiency();
 		if (proficiency > 0 && proficiency < profText.length) {
-			Color oldColor = gc.getForeground();
-			gc.setForeground(Colors.grey);
+			int alpha = gc.getAlpha();
+			gc.setAlpha(0xA0);
 			GCStringPrinter.printString(gc,
 					MessageText.getString("ConfigView.section.mode."
 							+ profText[proficiency]), profBounds, true,
 					false, SWT.RIGHT | SWT.TOP);
-			gc.setForeground(oldColor);
+			gc.setAlpha(alpha);
 		}
 
 		Rectangle hitArea;
-		TableViewColumnSetup tv = (TableViewColumnSetup) ((TableCellCore) cell).getTableRowCore().getView();
-		if (tv.isColumnAdded(column)) {
+		TableView<?> tv = ((TableCellCore) cell).getTableRowCore().getView();
+		TableColumnSetupWindow tvs = (TableColumnSetupWindow) tv.getParentDataSource();
+		if (tvs.isColumnAdded(column)) {
 			hitArea = Utils.EMPTY_RECT;
 		} else {
 			int x = bounds.x + titleSize.x + 15;
@@ -165,22 +164,21 @@ public class ColumnTC_NameInfo
 		if (event.button == 1
 				&& event.eventType == TableRowMouseEvent.EVENT_MOUSEUP
 				&& (event.cell instanceof TableCellCore)) {
-			Object data = ((TableCellCore) event.cell).getTableRowCore().getData(
-					"AddHitArea");
+			Object data = event.cell.getTableRow().getData("AddHitArea");
 			if (data instanceof Rectangle) {
 				Rectangle hitArea = (Rectangle) data;
 				if (hitArea.contains(event.x, event.y)) {
-					TableViewColumnSetup tv = (TableViewColumnSetup) ((TableCellCore) event.cell).getTableRowCore().getView();
+					TableView<?> tv = ((TableCellCore) event.cell).getTableRowCore().getView();
+					TableColumnSetupWindow tvs = (TableColumnSetupWindow) tv.getParentDataSource();
 					Object dataSource = event.cell.getDataSource();
 					if (dataSource instanceof TableColumnCore) {
 						TableColumnCore column = (TableColumnCore) dataSource;
-						tv.chooseColumn(column);
+						tvs.chooseColumn(column);
 					}
 				}
 			}
 		} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEMOVE) {
-			Object data = ((TableCellCore) event.cell).getTableRowCore().getData(
-					"AddHitArea");
+			Object data = event.cell.getTableRow().getData("AddHitArea");
 			if (data instanceof Rectangle) {
 				Rectangle hitArea = (Rectangle) data;
 				if (hitArea.contains(event.x, event.y)) {
diff --git a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_Sample.java b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_Sample.java
index 6a56bb0..e1fbef1 100644
--- a/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_Sample.java
+++ b/org/gudy/azureus2/ui/swt/views/columnsetup/ColumnTC_Sample.java
@@ -20,22 +20,19 @@ package org.gudy.azureus2.ui.swt.views.columnsetup;
 
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
 
 import org.gudy.azureus2.core3.util.AERunnable;
 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.views.columnsetup.TableColumnSetupWindow.TableViewColumnSetup;
 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.TableViewSWT;
 import org.gudy.azureus2.ui.swt.views.table.impl.FakeTableCell;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableCellImpl;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
-import com.aelitis.azureus.ui.common.table.TableCellCore;
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
+import com.aelitis.azureus.ui.common.table.*;
 
 /**
  * @author TuxPaper
@@ -59,35 +56,40 @@ public class ColumnTC_Sample
 	public void cellAdded(final TableCell cell) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
+				if (cell.isDisposed()) {
+					return;
+				}
 				TableColumnCore column = (TableColumnCore) cell.getDataSource();
-				TableViewColumnSetup tv = (TableViewColumnSetup) ((TableCellCore) cell).getTableRowCore().getView();
-				TableRowCore sampleRow = (TableRowCore) tv.getSampleRow();
+				TableViewSWT<?> tv = (TableViewSWT<?>) ((TableCellCore) cell).getTableRowCore().getView();
+				TableColumnSetupWindow tvs = (TableColumnSetupWindow) tv.getParentDataSource();
+				TableRowCore sampleRow = (TableRowCore) tvs.getSampleRow();
 
-				cell.addListeners(new Cell(cell, column, tv, sampleRow));
+				cell.addListeners(new Cell(cell, column, tv.getTableComposite(), sampleRow));
 			}
 		});
 	}
 
 	public class Cell
 		implements TableCellRefreshListener, TableCellSWTPaintListener,
-		TableCellVisibilityListener
+		TableCellVisibilityListener, TableCellDisposeListener
 	{
 		private final TableColumnCore column;
 		private FakeTableCell sampleCell;
 
-		public Cell(TableCell parentCell, TableColumnCore column, TableViewColumnSetup tv, TableRowCore sampleRow) {
+		public Cell(TableCell parentCell, TableColumnCore column, Composite c, TableRowCore sampleRow) {
 			this.column = column;
 			if (sampleRow == null) {
 				return;
 			}
-			sampleCell = new FakeTableCell(column);
+			Object ds = sampleRow.getDataSource(true);
+			sampleCell = new FakeTableCell(column, ds);
 
-			sampleCell.setControl(tv.getTableComposite());
-			Rectangle bounds = ((TableCellImpl)parentCell).getBounds();
-			sampleCell.setCellArea(bounds);
-			if (sampleRow != null) {
-				sampleCell.setDataSource(((TableRowCore)sampleRow).getDataSource(true));
-			}
+			Rectangle bounds = ((TableCellSWT)parentCell).getBounds();
+			sampleCell.setControl(c, bounds, false);
+		}
+		
+		public void dispose(TableCell cell) {
+			sampleCell = null;
 		}
 
 		// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWTPaintListener#cellPaint(org.eclipse.swt.graphics.GC, org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
@@ -95,7 +97,7 @@ public class ColumnTC_Sample
 			if (sampleCell == null) {
 				return;
 			}
-			Rectangle bounds = ((TableCellImpl)cell).getBounds();
+			Rectangle bounds = cell.getBounds();
 			sampleCell.setCellArea(bounds);
 			try {
 				sampleCell.doPaint(gc);
@@ -110,7 +112,7 @@ public class ColumnTC_Sample
 				return;
 			}
 			try {
-				column.invokeCellVisibilityListeners((TableCellCore) sampleCell, visibility);
+				column.invokeCellVisibilityListeners(sampleCell, visibility);
 			} catch (Throwable e) {
 				Debug.out(e);
 			}
@@ -126,6 +128,10 @@ public class ColumnTC_Sample
 			}
 			sampleCell.refresh(true, true, true);
 			cell.setSortValue(sampleCell.getSortValue());
+			cell.invalidate();
+			if (cell instanceof TableCellSWT) {
+				((TableCellSWT) cell).redraw();
+			}
 			//cell.setText(sampleCell.getText());
 		}
 
diff --git a/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java b/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
index db7ed0f..a24aba3 100644
--- a/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
+++ b/org/gudy/azureus2/ui/swt/views/columnsetup/TableColumnSetupWindow.java
@@ -25,6 +25,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.*;
 import org.eclipse.swt.events.*;
 import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.layout.*;
 import org.eclipse.swt.widgets.*;
@@ -33,23 +34,23 @@ 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.Constants;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
 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.GCStringPrinter;
 import org.gudy.azureus2.ui.swt.views.table.TableRowSWT;
-import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWTImpl;
-import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnManager;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory;
 
 import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
 
-import org.gudy.azureus2.plugins.ui.tables.TableColumn;
-import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
-import org.gudy.azureus2.plugins.ui.tables.TableRow;
-
 /**
  * @author TuxPaper
  * @created Jan 3, 2009
@@ -66,17 +67,17 @@ public class TableColumnSetupWindow
 
 	private Shell shell;
 
-	private TableViewColumnSetup tvAvail;
+	private TableViewSWT tvAvail;
 
 	private final String forTableID;
 
-	private final Class forDataSourceType;
+	private final Class<?> forDataSourceType;
 
 	private Composite cTableAvail;
 
 	private Composite cCategories;
 
-	private TableViewColumnSetup tvChosen;
+	private TableViewSWT tvChosen;
 
 	private Composite cTableChosen;
 
@@ -86,7 +87,7 @@ public class TableColumnSetupWindow
 
 	private DragSourceListener dragSourceListener;
 
-	private final TableStructureModificationListener listener;
+	private final TableStructureModificationListener<?> listener;
 
 	private TableColumnCore[] columnsOriginalOrder;
 
@@ -94,7 +95,7 @@ public class TableColumnSetupWindow
 
 	private Button[] radProficiency = new Button[3];
 
-	private Map<TableColumnCore, Boolean> mapNewVisibility = new HashMap();
+	private Map<TableColumnCore, Boolean> mapNewVisibility = new HashMap<TableColumnCore, Boolean>();
 
 	private ArrayList<TableColumnCore> listColumnsNoCat;
 
@@ -106,8 +107,8 @@ public class TableColumnSetupWindow
 
 	protected boolean doReset;
 
-	public TableColumnSetupWindow(final Class forDataSourceType, String _tableID,
-			TableRow sampleRow, TableStructureModificationListener _listener) {
+	public TableColumnSetupWindow(final Class<?> forDataSourceType, String _tableID,
+			TableRow sampleRow, TableStructureModificationListener<?> _listener) {
 		this.sampleRow = sampleRow;
 		this.listener = _listener;
 		FormData fd;
@@ -120,8 +121,12 @@ public class TableColumnSetupWindow
 			public void dragStart(DragSourceEvent event) {
 				event.doit = true;
 
-				Table table = (Table) ((DragSource) event.widget).getControl();
-				TableView tv = (TableView) table.getData("TableView");
+				if (!(event.widget instanceof DragSource)) {
+					event.doit = false;
+					return;
+				}
+				
+				TableView<?> tv = (TableView<?>) ((DragSource) event.widget).getData("tv");
 				// drag start happens a bit after the mouse moves, so the
 				// cursor location isn't accurate
 				//Point cursorLocation = event.display.getCursorLocation();
@@ -139,6 +144,7 @@ public class TableColumnSetupWindow
 				}
 
 				tableColumn = (TableColumnCore) row.getDataSource();
+				
 
 				if (event.image != null && !Constants.isLinux) {
 					try {
@@ -169,8 +175,11 @@ public class TableColumnSetupWindow
 			}
 
 			public void dragSetData(DragSourceEvent event) {
-				Table table = (Table) ((DragSource) event.widget).getControl();
-				TableView tv = (TableView) table.getData("TableView");
+				if (!(event.widget instanceof DragSource)) {
+					return;
+				}
+				
+				TableView<?> tv = (TableView<?>) ((DragSource) event.widget).getData("tv");
 				event.data = "" + (tv == tvChosen ? "c" : "a");
 			}
 
@@ -198,6 +207,13 @@ public class TableColumnSetupWindow
 		shell.setLayout(formLayout);
 		shell.setSize(780, 550);
 
+		shell.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				if (e.detail == SWT.TRAVERSE_ESCAPE) {
+					shell.dispose();
+				}
+			}
+		});
 		shell.addDisposeListener(new DisposeListener() {
 			public void widgetDisposed(DisposeEvent e) {
 				close();
@@ -414,7 +430,40 @@ public class TableColumnSetupWindow
 		// >>>>>>> Chosen
 
 		ImageLoader imageLoader = ImageLoader.getInstance();
+		
+		Button btnLeft = new Button(cResultButtonArea, SWT.PUSH);
+		imageLoader.setButtonImage(btnLeft, "alignleft");
+		btnLeft.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				alignChosen( TableColumnCore.ALIGN_LEAD);
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		
+		Button btnCentre = new Button(cResultButtonArea, SWT.PUSH);
+		imageLoader.setButtonImage(btnCentre, "aligncentre");
+		btnCentre.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				alignChosen( TableColumnCore.ALIGN_CENTER );
+			}
 
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		
+		Button btnRight = new Button(cResultButtonArea, SWT.PUSH);
+		imageLoader.setButtonImage(btnRight, "alignright");
+		btnRight.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				alignChosen( TableColumnCore.ALIGN_TRAIL );
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+		
 		Button btnUp = new Button(cResultButtonArea, SWT.PUSH);
 		imageLoader.setButtonImage(btnUp, "up");
 		btnUp.addSelectionListener(new SelectionListener() {
@@ -438,7 +487,7 @@ public class TableColumnSetupWindow
 		});
 
 		Button btnDel = new Button(cResultButtonArea, SWT.PUSH);
-		imageLoader.setButtonImage(btnDel, "delete");
+		imageLoader.setButtonImage(btnDel, "delete2");
 		btnDel.addSelectionListener(new SelectionListener() {
 			public void widgetSelected(SelectionEvent e) {
 				removeSelectedChosen();
@@ -447,7 +496,7 @@ public class TableColumnSetupWindow
 			public void widgetDefaultSelected(SelectionEvent e) {
 			}
 		});
-
+		
 		tvChosen = createTVChosen();
 
 		cTableChosen = new Composite(cResultArea, SWT.NONE);
@@ -510,7 +559,7 @@ public class TableColumnSetupWindow
   		});
 		}
 		
-		Button btnCancel = new Button(shell, SWT.PUSH);
+		final Button btnCancel = new Button(shell, SWT.PUSH);
 		Messages.setLanguageText(btnCancel, "Button.cancel");
 		btnCancel.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
@@ -523,6 +572,7 @@ public class TableColumnSetupWindow
 		btnApply.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
 				apply();
+				btnCancel.setEnabled(false);
 			}
 		});
 
@@ -536,50 +586,68 @@ public class TableColumnSetupWindow
 		fd.top = new FormAttachment(topInfo, 5);
 		fd.right = new FormAttachment(100, -3);
 		fd.bottom = new FormAttachment(btnOk, -5);
-		fd.width = 200;
+		fd.width = 210;
 		cResultArea.setLayoutData(fd);
-		
+
+		fd = new FormData();
+		fd.top = new FormAttachment(0, 3);
+		fd.left = new FormAttachment(0, 3);
+		fd.right = new FormAttachment(100, -3);
+		fd.bottom = new FormAttachment(cResultButtonArea, -3);
+		cTableChosen.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);
+	
+			// align
+		
+		fd = new FormData();
+		fd.top = new FormAttachment(0, 3);
+		fd.left = new FormAttachment(0, 3);
+		btnLeft.setLayoutData(fd);
+
+		fd = new FormData();
+		fd.left = new FormAttachment(btnLeft, 3);
+		fd.top = new FormAttachment(btnLeft, 0, SWT.TOP);
+		fd.bottom = new FormAttachment(btnLeft, 0, SWT.BOTTOM);
+		btnCentre.setLayoutData(fd);
 
 		fd = new FormData();
-		fd.right = new FormAttachment(btnDown, -5);
-		fd.bottom = new FormAttachment(btnApply, -3);
+		fd.left = new FormAttachment(btnCentre, 3);
+		fd.top = new FormAttachment(btnLeft, 0, SWT.TOP);
+		fd.bottom = new FormAttachment(btnLeft, 0, SWT.BOTTOM);
+		btnRight.setLayoutData(fd);
+
+			// move
+		
+		fd = new FormData();
+		fd.left = new FormAttachment(0, 3);
+		fd.top = new FormAttachment(btnLeft, 2);
 		btnUp.setLayoutData(fd);
 
 		fd = new FormData();
-		fd.right = new FormAttachment(btnDel, -5);
+		fd.left = new FormAttachment(btnUp, 3);
 		fd.top = new FormAttachment(btnUp, 0, SWT.TOP);
-		fd.bottom = new FormAttachment(btnUp, 0, SWT.BOTTOM);
 		btnDown.setLayoutData(fd);
 
 		fd = new FormData();
-		fd.right = new FormAttachment(100, -5);
+		fd.left = new FormAttachment(btnDown, 3);
 		fd.top = new FormAttachment(btnUp, 0, SWT.TOP);
-		fd.bottom = new FormAttachment(btnUp, 0, SWT.BOTTOM);
 		btnDel.setLayoutData(fd);
-
-		fd = new FormData();
-		fd.top = new FormAttachment(0, 3);
-		fd.left = new FormAttachment(0, 0);
-		fd.right = new FormAttachment(100, 0);
-		//fd.bottom = new FormAttachment(100, 0);
-		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);
+		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, -5);
-		fd.bottom = new FormAttachment(100, -3);
+		fd.right = new FormAttachment(100, -3);
+		fd.top = new FormAttachment(btnUp, 3, SWT.BOTTOM);
 		//fd.width = 64;
 		btnApply.setLayoutData(fd);
 
@@ -647,8 +715,8 @@ public class TableColumnSetupWindow
 
 		fd = new FormData();
 		fd.top = new FormAttachment(0, 3);
-		fd.left = new FormAttachment(0, 0);
-		fd.right = new FormAttachment(100, 0);
+		fd.left = new FormAttachment(0, 3);
+		fd.right = new FormAttachment(100, -3);
 		fd.bottom = new FormAttachment(expandFilters, -3);
 		cTableAvail.setLayoutData(fd);
 
@@ -730,7 +798,7 @@ public class TableColumnSetupWindow
 				forDataSourceType, forTableID);
 		
 		if (selectedCat == "uncat") {
-			datasources = (TableColumnCore[]) listColumnsNoCat.toArray( new TableColumnCore[listColumnsNoCat.size()]);
+			datasources = listColumnsNoCat.toArray( new TableColumnCore[listColumnsNoCat.size()]);
 		}
 		for (int i = 0; i < datasources.length; i++) {
 			TableColumnCore column = datasources[i];
@@ -823,6 +891,8 @@ public class TableColumnSetupWindow
 					rows[oldRowPos - 1] = rows[oldRowPos];
 					rows[oldRowPos] = displacedRow;
 					column.setPositionNoShift(oldColumnPos - 1);
+					
+					column.setAlignment( TableColumnCore.ALIGN_CENTER );
 				}
 			}
 		}
@@ -830,6 +900,20 @@ public class TableColumnSetupWindow
 		tvChosen.refreshTable(true);
 	}
 
+	protected void alignChosen( int align ) {
+		TableRowCore[] selectedRows = tvChosen.getSelectedRows();
+		for (int i = 0; i < selectedRows.length; i++) {
+			TableRowCore row = selectedRows[i];
+			TableColumnCore column = (TableColumnCore) row.getDataSource();
+			if (column != null) {
+				column.setAlignment( align );
+			}
+		}
+		tvChosen.tableInvalidate();
+		tvChosen.refreshTable(true);
+	}
+	
+	
 	/**
 	 * 
 	 *
@@ -853,7 +937,7 @@ public class TableColumnSetupWindow
 	 *
 	 * @since 4.0.0.5
 	 */
-	private TableViewColumnSetup createTVChosen() {
+	private TableViewSWT<?> createTVChosen() {
 		final TableColumnManager tcm = TableColumnManager.getInstance();
 		TableColumnCore[] columnTVChosen = tcm.getAllTableColumnCoreAsArray(
 				TableColumn.class, TABLEID_CHOSEN);
@@ -868,11 +952,12 @@ public class TableColumnSetupWindow
 			}
 		}
 
-		final TableViewColumnSetup tvChosen = new TableViewColumnSetup(
-				this, TableColumn.class, TABLEID_CHOSEN, columnTVChosen,
-				ColumnTC_ChosenColumn.COLUMN_ID, true);
+		final TableViewSWT<?> tvChosen = TableViewFactory.createTableViewSWT(
+				TableColumn.class, TABLEID_CHOSEN, TABLEID_CHOSEN, columnTVChosen,
+				ColumnTC_ChosenColumn.COLUMN_ID, SWT.FULL_SELECTION | SWT.VIRTUAL
+						| SWT.MULTI);
+		tvAvail.setParentDataSource(this);
 		tvChosen.setMenuEnabled(false);
-		tvChosen.setSampleRow(sampleRow);
 		tvChosen.setHeaderVisible(false);
 		//tvChosen.setRowDefaultHeight(16);
 
@@ -886,6 +971,7 @@ public class TableColumnSetupWindow
 				dragSource.setTransfer(new Transfer[] {
 					TextTransfer.getInstance()
 				});
+				dragSource.setData("tv", tvChosen);
 				dragSource.addDragListener(dragSourceListener);
 
 				dropTarget = tvChosen.createDropTarget(DND.DROP_DEFAULT
@@ -905,7 +991,7 @@ public class TableColumnSetupWindow
 						String id = (String) event.data;
 						TableRowCore destRow = tvChosen.getRow(event);
 
-						TableView tv = id.equals("c") ? tvChosen : tvAvail;
+						TableView<?> tv = id.equals("c") ? tvChosen : tvAvail;
 
 						Object[] dataSources = tv.getSelectedDataSources().toArray();
 						for (int i = 0; i < dataSources.length; i++) {
@@ -982,20 +1068,21 @@ public class TableColumnSetupWindow
 	 *
 	 * @since 4.0.0.5
 	 */
-	private TableViewColumnSetup createTVAvail() {
+	private TableViewSWT<?> createTVAvail() {
 		final TableColumnManager tcm = TableColumnManager.getInstance();
-		Map mapColumns = tcm.getTableColumnsAsMap(TableColumn.class, TABLEID_AVAIL);
+		Map<String, TableColumnCore> mapColumns = tcm.getTableColumnsAsMap(
+				TableColumn.class, TABLEID_AVAIL);
 		TableColumnCore[] columns;
-		int[] widths = { 405, 120 };
+		int[] widths = { 405, 110 };
 		if (sampleRow == null) {
 			columns = new TableColumnCore[] {
-				(TableColumnCore) mapColumns.get(ColumnTC_NameInfo.COLUMN_ID),
+				mapColumns.get(ColumnTC_NameInfo.COLUMN_ID),
 			};
 			widths = new int[] { 525 };
 		} else {
 			columns = new TableColumnCore[] {
-				(TableColumnCore) mapColumns.get(ColumnTC_NameInfo.COLUMN_ID),
-				(TableColumnCore) mapColumns.get(ColumnTC_Sample.COLUMN_ID),
+				mapColumns.get(ColumnTC_NameInfo.COLUMN_ID),
+				mapColumns.get(ColumnTC_Sample.COLUMN_ID),
 			};
 		}
 		for (int i = 0; i < columns.length; i++) {
@@ -1007,11 +1094,12 @@ public class TableColumnSetupWindow
 			}
 		}
 
-		final TableViewColumnSetup tvAvail = new TableViewColumnSetup(this,
-				TableColumn.class, TABLEID_AVAIL, columns,
-				ColumnTC_ChosenColumn.COLUMN_ID, false);
+		final TableViewSWT<?> tvAvail = TableViewFactory.createTableViewSWT(
+				TableColumn.class, TABLEID_AVAIL, TABLEID_AVAIL, columns,
+				ColumnTC_NameInfo.COLUMN_ID, SWT.FULL_SELECTION | SWT.VIRTUAL
+						| SWT.SINGLE);
+		tvAvail.setParentDataSource(this);
 		tvAvail.setMenuEnabled(false);
-		tvAvail.setSampleRow(sampleRow);
 		tvAvail.setRowDefaultHeight(65);
 
 		tvAvail.addLifeCycleListener(new TableLifeCycleListener() {
@@ -1024,6 +1112,7 @@ public class TableColumnSetupWindow
 				dragSource.setTransfer(new Transfer[] {
 					TextTransfer.getInstance()
 				});
+				dragSource.setData("tv", tvAvail);
 				dragSource.addDragListener(dragSourceListener);
 
 			
@@ -1126,42 +1215,24 @@ public class TableColumnSetupWindow
 		}
 	}
 
-	public class TableViewColumnSetup
-		extends TableViewSWTImpl
-	{
-		private TableRow sampleRow = null;
-
-		private final TableColumnSetupWindow setupWindow;
-
-		public TableViewColumnSetup(TableColumnSetupWindow setupWindow,
-				Class forPluginDataSourceType,
-				String tableID, TableColumnCore[] items, String defaultSortOn,
-				boolean multi) {
-			super(forPluginDataSourceType, tableID, tableID, items, defaultSortOn,
-					SWT.FULL_SELECTION | SWT.VIRTUAL | (multi ? SWT.MULTI : SWT.SINGLE));
-			this.setupWindow = setupWindow;
-		}
-
-		public TableRow getSampleRow() {
-			return sampleRow;
-		}
-
-		public void setSampleRow(TableRow sampleRow) {
-			this.sampleRow = sampleRow;
-		}
+	public TableRow getSampleRow() {
+		return sampleRow;
+	}
 
-		public void chooseColumn(TableColumnCore column) {
-			setupWindow.chooseColumn(column, null, false);
-			TableRowCore row = tvAvail.getRow(column);
-			if (row != null) {
-				row.redraw();
-			}
+	public void chooseColumn(TableColumnCore column) {
+		chooseColumn(column, null, false);
+		TableRowCore row = tvAvail.getRow(column);
+		if (row != null) {
+			row.redraw();
 		}
+	}
 
-		public boolean isColumnAdded(TableColumnCore column) {
-			TableRowCore row = tvChosen.getRow(column);
-			return row != null;
+	public boolean isColumnAdded(TableColumnCore column) {
+		if (tvChosen == null) {
+			return false;
 		}
+		TableRowCore row = tvChosen.getRow(column);
+		return row != null;
 	}
 
 	/**
@@ -1178,7 +1249,7 @@ public class TableColumnSetupWindow
 
 			row = placeAboveRow == null && !ignoreExisting ? tvChosen.getFocusedRow()
 					: placeAboveRow;
-			if (row == null) {
+			if (row == null || row.getDataSource() == null) {
 				if (columnsChosen.length > 0) {
 					newPosition = columnsChosen.length;
 				}
@@ -1206,9 +1277,8 @@ public class TableColumnSetupWindow
 						if (i == 0) {
 							if (column == arg0) {
 								return shiftDir ? -1 : 1;
-							} else {
-								return shiftDir ? 1 : -1;
 							}
+							return shiftDir ? 1 : -1;
 						}
 						return i;
 					}
@@ -1244,11 +1314,12 @@ public class TableColumnSetupWindow
 				});
 			}
 
+			Arrays.sort(columnsChosen,
+					TableColumnManager.getTableColumnOrderComparator());
+
 			tvChosen.tableInvalidate();
 			tvChosen.refreshTable(true);
 
-			Arrays.sort(columnsChosen,
-					TableColumnManager.getTableColumnOrderComparator());
 		} else {
 			row.setSelected(true);
 		}
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionBackupRestore.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionBackupRestore.java
new file mode 100644
index 0000000..3c272d5
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionBackupRestore.java
@@ -0,0 +1,546 @@
+/*
+ * File    : ConfigPanel*.java
+ * Created : 11 mar. 2004
+ * By      : TuxPaper
+ * 
+ * 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.configsections;
+
+import java.io.File;
+import java.util.Date;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.Image;
+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.core3.util.AERunnable;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.TextViewerWindow;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.config.BooleanParameter;
+import org.gudy.azureus2.ui.swt.config.ChangeSelectionActionPerformer;
+import org.gudy.azureus2.ui.swt.config.IntParameter;
+import org.gudy.azureus2.ui.swt.config.StringParameter;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.backup.BackupManager;
+import com.aelitis.azureus.core.backup.BackupManagerFactory;
+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;
+
+
+public class ConfigSectionBackupRestore implements UISWTConfigSection {
+
+
+	public String configSectionGetParentSection() {
+		return ConfigSection.SECTION_ROOT;
+	}
+
+	public String configSectionGetName() {
+		return "backuprestore";
+	}
+
+	public void configSectionSave() {
+	}
+
+	public void configSectionDelete() {
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		imageLoader.releaseImage("openFolderButton");
+	}
+	
+	public int maxUserMode() {
+		return 0;
+	}
+
+
+	public Composite 
+	configSectionCreate(
+		final Composite parent) 
+	{
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		Image imgOpenFolder = imageLoader.getImage("openFolderButton");
+		
+		GridData gridData;
+		GridLayout layout;
+
+		final Composite cBR = new Composite( parent, SWT.NULL );
+
+		gridData = new GridData(GridData.VERTICAL_ALIGN_FILL |  GridData.HORIZONTAL_ALIGN_FILL);
+		cBR.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 1;
+		cBR.setLayout(layout);
+				
+	    Label	info_label = new Label( cBR, SWT.WRAP );
+	    Messages.setLanguageText( info_label, "ConfigView.section.br.overview" );
+	    gridData = Utils.getWrappableLabelGridData(1, GridData.HORIZONTAL_ALIGN_FILL );
+	    
+	    info_label.setLayoutData( gridData );
+	    
+	    
+		// wiki link
+		
+		final Label linkLabel = new Label(cBR, SWT.NULL);
+		linkLabel.setText(MessageText.getString("ConfigView.label.please.visit.here"));
+		linkLabel.setData("http://wiki.vuze.com/w/Backup_And_Restore");
+		linkLabel.setCursor(linkLabel.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
+		linkLabel.setForeground(Colors.blue);
+    gridData = Utils.getWrappableLabelGridData(1, 0);
+		linkLabel.setLayoutData(gridData);
+		linkLabel.addMouseListener(new MouseAdapter() {
+			public void mouseDoubleClick(MouseEvent arg0) {
+				Utils.launch((String) ((Label) arg0.widget).getData());
+			}
+
+			public void mouseDown(MouseEvent arg0) {
+				Utils.launch((String) ((Label) arg0.widget).getData());
+			}
+		});
+		
+	    final BackupManager	backup_manager = BackupManagerFactory.getManager( AzureusCoreFactory.getSingleton());
+	    
+	    	// backup
+	    
+		Group gBackup = new Group(cBR, SWT.NULL);
+		Messages.setLanguageText(gBackup, "br.backup");
+		layout = new GridLayout(2, false);
+		gBackup.setLayout(layout);
+		gBackup.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+	    
+			// info
+		
+	    Label last_backup_label = new Label(gBackup, SWT.NULL );
+	    Messages.setLanguageText(last_backup_label, "br.backup.last.time");
+	    
+	    final Label last_backup_time = new Label(gBackup, SWT.NULL );
+
+	    Label last_backup_error_label = new Label(gBackup, SWT.NULL );
+	    Messages.setLanguageText(last_backup_error_label, "br.backup.last.error");
+	    
+	    final Label last_backup_error = new Label(gBackup, SWT.NULL );
+	    
+	    final Runnable stats_updater = 
+	    	new Runnable()
+	    	{
+	    		public void 
+	    		run() 
+	    		{
+	    		    long	backup_time = backup_manager.getLastBackupTime();
+	    		    
+	    		    last_backup_time.setText( backup_time==0?"":String.valueOf( new Date( backup_time )));
+	    		    
+	    		    last_backup_error.setText( backup_manager.getLastBackupError());
+
+	    		};
+	    	};
+	    	
+	    stats_updater.run();
+	    
+	    	// manual button
+	    
+	    Label backup_manual_label = new Label(gBackup, SWT.NULL );
+	    Messages.setLanguageText(backup_manual_label, "br.backup.manual.info");
+
+	    Button backup_button = new Button(gBackup, SWT.PUSH);
+	    Messages.setLanguageText(backup_button, "br.backup");
+	    
+	    backup_button.addListener(SWT.Selection, 
+	    		new Listener() 
+				{
+			        public void 
+					handleEvent(Event event) 
+			        {
+			        	String	def_dir = COConfigurationManager.getStringParameter( "br.backup.folder.default" );
+			        	
+						DirectoryDialog dialog = new DirectoryDialog(parent.getShell(),	SWT.APPLICATION_MODAL);
+						
+						if ( def_dir != null ){
+							dialog.setFilterPath( def_dir );
+						}
+						
+						dialog.setMessage(MessageText.getString("br.backup.folder.info"));
+						dialog.setText(MessageText.getString("br.backup.folder.title"));
+						
+						String path = dialog.open();
+						
+						if ( path != null ){
+																
+							COConfigurationManager.setParameter( "br.backup.folder.default", path );
+								
+							runBackup( backup_manager, path, stats_updater );
+						}
+			        }
+				});
+	    
+		final BooleanParameter auto_backup_enable = new BooleanParameter( gBackup, "br.backup.auto.enable", "br.backup.auto.enable" );
+		gridData = new GridData();
+		gridData.horizontalSpan = 2;
+		auto_backup_enable.setLayoutData( gridData );
+
+		Composite gDefaultDir = new Composite(gBackup, SWT.NONE);
+		layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.marginHeight = 2;
+		gDefaultDir.setLayout(layout);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 2;
+		gDefaultDir.setLayoutData(gridData);
+		
+		Label lblDefaultDir = new Label(gDefaultDir, SWT.NONE);
+		Messages.setLanguageText(lblDefaultDir,	"ConfigView.section.file.defaultdir.ask");
+		lblDefaultDir.setLayoutData(new GridData());
+
+
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		final StringParameter pathParameter = new StringParameter(gDefaultDir, "br.backup.auto.dir", "" );
+		pathParameter.setLayoutData(gridData);
+
+		if ( pathParameter.getValue().length() == 0 ){
+		   	String	def_dir = COConfigurationManager.getStringParameter( "br.backup.folder.default" );
+
+			pathParameter.setValue( def_dir );
+		}
+		
+		Button browse = new Button(gDefaultDir, SWT.PUSH);
+		browse.setImage(imgOpenFolder);
+		imgOpenFolder.setBackground(browse.getBackground());
+		browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
+
+		browse.addListener(SWT.Selection, new Listener() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+			 */
+			public void handleEvent(Event event) {
+				DirectoryDialog dialog = new DirectoryDialog(parent.getShell(),
+						SWT.APPLICATION_MODAL);
+				dialog.setFilterPath(pathParameter.getValue());
+				dialog.setMessage(MessageText.getString("br.backup.auto.dir.select"));
+				dialog.setText(MessageText.getString("ConfigView.section.file.defaultdir.ask"));
+				String path = dialog.open();
+				if (path != null) {
+					pathParameter.setValue(path);
+					
+					COConfigurationManager.setParameter( "br.backup.folder.default", path );
+				}
+			}
+		});
+		
+		
+		Label lbl_backup_days = new Label(gDefaultDir, SWT.NULL);
+		Messages.setLanguageText(lbl_backup_days, "br.backup.auto.everydays" );
+
+		IntParameter backup_everydays = new IntParameter( gDefaultDir, "br.backup.auto.everydays", 1, Integer.MAX_VALUE );
+		gridData = new GridData();
+		gridData.horizontalSpan = 2;
+		backup_everydays.setLayoutData( gridData );
+		
+		Label lbl_backup_retain = new Label(gDefaultDir, SWT.NULL);
+		Messages.setLanguageText(lbl_backup_retain, "br.backup.auto.retain" );
+
+		IntParameter backup_retain = new IntParameter( gDefaultDir, "br.backup.auto.retain", 1, Integer.MAX_VALUE );
+		gridData = new GridData();
+		gridData.horizontalSpan = 2;
+		backup_retain.setLayoutData( gridData );
+
+		BooleanParameter chkNotify = new BooleanParameter(gDefaultDir, "br.backup.notify", "br.backup.notify");
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 3;
+		chkNotify.setLayoutData(gridData);
+		
+
+	    Label backup_auto_label = new Label(gDefaultDir, SWT.NULL );
+	    Messages.setLanguageText(backup_auto_label, "br.backup.auto.now");
+
+	    Button backup_auto_button = new Button(gDefaultDir, SWT.PUSH);
+	    Messages.setLanguageText(backup_auto_button, "br.test");
+	    
+	    backup_auto_button.addListener(SWT.Selection, 
+	    		new Listener() 
+				{
+			        public void 
+					handleEvent(Event event) 
+			        {
+			        	runBackup( backup_manager, null, stats_updater );
+			        }
+				});
+	    
+	  auto_backup_enable.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(gDefaultDir));
+		
+	    	// restore
+	    
+		Group gRestore = new Group(cBR, SWT.NULL);
+		Messages.setLanguageText(gRestore, "br.restore");
+		layout = new GridLayout(2, false);
+		gRestore.setLayout(layout);
+		gRestore.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+		
+	    Label restore_label = new Label(gRestore, SWT.NULL );
+	    Messages.setLanguageText(restore_label, "br.restore.info");
+
+	    Button restore_button = new Button(gRestore, SWT.PUSH);
+	    Messages.setLanguageText(restore_button, "br.restore");
+
+	    restore_button.addListener(SWT.Selection, 
+	    		new Listener() 
+				{
+			        public void 
+					handleEvent(Event event) 
+			        {
+			        	String	def_dir = COConfigurationManager.getStringParameter( "br.backup.folder.default" );
+			        	
+						DirectoryDialog dialog = new DirectoryDialog(parent.getShell(),	SWT.APPLICATION_MODAL );
+						
+						if ( def_dir != null ){
+							dialog.setFilterPath( def_dir );
+						}
+						
+						dialog.setMessage(MessageText.getString("br.restore.folder.info"));
+						
+						dialog.setText(MessageText.getString("br.restore.folder.title"));
+						
+						final String path = dialog.open();
+						
+						if ( path != null ){
+
+				        	MessageBoxShell mb = new MessageBoxShell(
+				        			SWT.ICON_WARNING | SWT.OK | SWT.CANCEL,
+				        			MessageText.getString("br.restore.warning.title"),
+				        			MessageText.getString("br.restore.warning.info"));
+				        	
+				        	mb.setDefaultButtonUsingStyle(SWT.CANCEL);
+				        	mb.setParent(parent.getShell());
+	
+				        	mb.open(new UserPrompterResultListener() {
+										public void prompterClosed(int returnVal) {
+											if (returnVal != SWT.OK) {
+												return;
+											}
+	
+											final TextViewerWindow viewer = 
+												new TextViewerWindow(
+														MessageText.getString( "br.backup.progress" ),
+														null, "", true, true );
+															
+											viewer.setEditable( false );
+
+											viewer.setOKEnabled( false );
+											
+											backup_manager.restore(
+												new File( path ),
+												new BackupManager.BackupListener()
+												{
+													public boolean
+													reportProgress(
+														String		str )
+													{
+														return( append( str, false ));
+													}
+													
+													public void
+													reportComplete()
+													{
+														append( "Restore Complete!", true );	
+														
+														Utils.execSWTThread(
+															new AERunnable() 
+															{
+																public void 
+																runSupport() 
+																{
+																	MessageBoxShell mb = new MessageBoxShell( 
+													        				SWT.ICON_INFORMATION | SWT.OK,
+													        				MessageText.getString( "ConfigView.section.security.restart.title" ),
+													        				MessageText.getString( "ConfigView.section.security.restart.msg" ));
+												      				mb.setParent(parent.getShell());
+												        			mb.open(
+												        				new UserPrompterResultListener() 
+												        				{
+																			public void 
+																			prompterClosed(
+																				int returnVal) 
+																			{		
+																        		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+																        		
+																            	if ( uiFunctions != null ){
+																            		
+																            		uiFunctions.dispose(true, false);
+																            	}
+																			}
+												        				});
+																}
+															});
+													}
+													
+													public void
+													reportError(
+														Throwable 	error )
+													{
+														append( "Restore Failed: " + Debug.getNestedExceptionMessage( error ), true );
+													}
+													
+													private boolean
+													append(
+														final String		str,
+														final boolean		complete )
+													{	
+														if ( viewer.isDisposed()){
+															
+															return( false );
+														}
+														
+														Utils.execSWTThread(
+															new AERunnable() 
+															{
+																public void 
+																runSupport() 
+																{
+																	if ( str.endsWith( "..." )){
+																		
+																		viewer.append( str );
+																		
+																	}else{
+																	
+																		viewer.append( str + "\r\n" );
+																	}
+																	
+																	if ( complete ){
+																		
+																		viewer.setOKEnabled( true );
+																	}
+																}
+															});
+														
+														return( true );
+													}													
+												});
+											
+											viewer.goModal();
+												
+										}
+									});
+						}
+			        }
+			    });
+	    
+		return( cBR );
+	}
+	
+	private void
+	runBackup(
+		BackupManager		backup_manager,
+		String				path,
+		final Runnable		stats_updater )
+		
+	{
+		final TextViewerWindow viewer = 
+			new TextViewerWindow(
+					MessageText.getString( "br.backup.progress" ),
+					null, "", true, true );
+						
+		viewer.setEditable( false );
+		
+		viewer.setOKEnabled( false );
+		
+		BackupManager.BackupListener	listener = 
+			new BackupManager.BackupListener()
+			{
+				public boolean
+				reportProgress(
+					String		str )
+				{
+					return( append( str, false ));
+				}
+				
+				public void
+				reportComplete()
+				{
+					append( "Backup Complete!", true );
+				}
+				
+				public void
+				reportError(
+					Throwable 	error )
+				{
+					append( "Backup Failed: " + Debug.getNestedExceptionMessage( error ), true );
+				}
+				
+				private boolean
+				append(
+					final String		str,
+					final boolean		complete )
+				{	
+					if ( viewer.isDisposed()){
+						
+						return( false );
+					}
+					
+					Utils.execSWTThread(
+						new AERunnable() 
+						{
+							public void 
+							runSupport() 
+							{
+								if ( str.endsWith( "..." )){
+									
+									viewer.append( str );
+									
+								}else{
+								
+									viewer.append( str + "\r\n" );
+								}
+								
+								if ( complete ){
+									
+									viewer.setOKEnabled( true );
+									
+									stats_updater.run();
+								}								
+							}
+						});
+					
+					return( true );
+				}
+			};
+			
+		if ( path == null ){
+			
+			backup_manager.runAutoBackup( listener );
+			
+		}else{
+		
+			backup_manager.backup( new File( path ), listener );
+		}
+		
+		viewer.goModal();
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
index 00171c7..c260f1f 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnection.java
@@ -40,7 +40,6 @@ import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.ui.swt.components.LinkLabel;
 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.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
@@ -98,7 +97,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 
 		label = new Label(cMiniArea, SWT.NULL);
 		Messages.setLanguageText(label, separate_ports?"ConfigView.label.tcplistenport":"ConfigView.label.serverport");
-		gridData = new GridData();
+		gridData = new GridData(GridData.HORIZONTAL_ALIGN_END);
 		label.setLayoutData(gridData);
 
 		final IntParameter tcplisten = new IntParameter(cMiniArea,
@@ -246,13 +245,50 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			}
 		}
 		
+		if ( userMode > 0 ){
+			
+			Composite cRandPortArea = new Composite(cMiniArea, SWT.NULL);
+			layout = new GridLayout();
+			layout.numColumns = 4;
+			layout.marginHeight = 0;
+			layout.marginWidth = 0;
+			cRandPortArea.setLayout(layout);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 2;
+			
+			cRandPortArea.setLayoutData(gridData);
+
+			BooleanParameter rand_enable = 
+				new BooleanParameter(cRandPortArea, "Listen.Port.Randomize.Enable",	CFG_PREFIX + "port.rand.enable");
+
+			label = new Label(cRandPortArea, SWT.NULL);
+
+			label.setText(MessageText.getString( CFG_PREFIX + "port.rand.range" ));
+			gridData = new GridData();
+			gridData.horizontalIndent = 20;
+			label.setLayoutData( gridData );
+
+			StringParameter rand_range = new StringParameter( cRandPortArea, "Listen.Port.Randomize.Range" );
+			gridData = new GridData();
+			gridData.widthHint = 100;
+			rand_range.setLayoutData( gridData );
+			
+			BooleanParameter rand_together = 
+				new BooleanParameter(cRandPortArea, "Listen.Port.Randomize.Together",	CFG_PREFIX + "port.rand.together");
+
+			rand_enable.setAdditionalActionPerformer(
+					new ChangeSelectionActionPerformer( label ));
+			rand_enable.setAdditionalActionPerformer(
+					new ChangeSelectionActionPerformer( new Parameter[]{ rand_range, rand_together }));
+		}
+		
 		if ( userMode > 1 ){
 		
 			final BooleanParameter prefer_udp = 
 				new BooleanParameter(cMiniArea, "peercontrol.prefer.udp",	CFG_PREFIX + "prefer.udp");
 			gridData = new GridData();
+			gridData.horizontalSpan = 2;
 			prefer_udp.setLayoutData( gridData );
-			label = new Label(cMiniArea, SWT.NULL);
 		}
 		
 		if (userMode < 2) {
@@ -266,8 +302,8 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			linkLabel.setText(MessageText
 					.getString(CFG_PREFIX + "serverport.wiki"));
 			linkLabel
-					.setData("http://www.azureuswiki.com/index.php?title=Why_ports_like_6881_are_no_good_choice");
-			linkLabel.setCursor(Cursors.handCursor);
+					.setData("http://wiki.vuze.com/w/Why_ports_like_6881_are_no_good_choice");
+			linkLabel.setCursor(linkLabel.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 			linkLabel.setForeground(Colors.blue);
 			gridData = new GridData();
 			linkLabel.setLayoutData(gridData);
@@ -304,7 +340,7 @@ public class ConfigSectionConnection implements UISWTConfigSection {
 			new LinkLabel(
 					http_group, 
 					"ConfigView.label.please.visit.here",
-					"http://www.azureuswiki.com/index.php?title=HTTP_Seeding");
+					"http://wiki.vuze.com/w/HTTP_Seeding");
 
 			final BooleanParameter enable_http = 
 				new BooleanParameter(http_group, "HTTP.Data.Listen.Port.Enable", CFG_PREFIX + "http.enable");
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
index a44ce60..4d39306 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionAdvanced.java
@@ -285,7 +285,7 @@ public class ConfigSectionConnectionAdvanced implements UISWTConfigSection {
 		PlatformManager mgr = PlatformManagerFactory.getPlatformManager();
 
 		if (mgr.hasCapability(PlatformManagerCapabilities.SetTCPTOSEnabled)) { 
-			//see http://www.azureuswiki.com/index.php/AdvancedNetworkSettings
+			//see http://wiki.vuze.com/w/AdvancedNetworkSettings
 			try {
 				mgr.setTCPTOSEnabled(enable);
 			} catch (PlatformManagerException pe) {
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionEncryption.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionEncryption.java
index d5f13a2..5f31c20 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionEncryption.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionConnectionEncryption.java
@@ -116,7 +116,7 @@ public class ConfigSectionConnectionEncryption implements UISWTConfigSection {
 		gridData.horizontalSpan = 2;
 		new LinkLabel(gCrypto, gridData, CFG_PREFIX
 				+ "encrypt.info.link",
-				"http://www.azureuswiki.com/index.php/Avoid_traffic_shaping");
+				"http://wiki.vuze.com/w/Avoid_traffic_shaping");
 		
 		final BooleanParameter require = new BooleanParameter(gCrypto,	"network.transport.encrypted.require", CFG_PREFIX + "require_encrypted_transport");
 		gridData = new GridData();
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
index 308f4c4..04986f9 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionFile.java
@@ -49,482 +49,609 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 
-public class ConfigSectionFile implements UISWTConfigSection {
-  public String configSectionGetParentSection() {
-    return ConfigSection.SECTION_ROOT;
-  }
-
-  public String configSectionGetName() {
-    return ConfigSection.SECTION_FILES;
-  }
-
-  public void configSectionSave() {
-  }
-  
+public class ConfigSectionFile
+	implements UISWTConfigSection
+{
+	public String configSectionGetParentSection() {
+		return ConfigSection.SECTION_ROOT;
+	}
+
+	public String configSectionGetName() {
+		return ConfigSection.SECTION_FILES;
+	}
+
+	public void configSectionSave() {
+	}
+
 	public int maxUserMode() {
 		return 2;
 	}
 
-
-  public void configSectionDelete() {
+	public void configSectionDelete() {
 		ImageLoader imageLoader = ImageLoader.getInstance();
 		imageLoader.releaseImage("openFolderButton");
-  }
+	}
 
-  public Composite configSectionCreate(final Composite parent) {
+	public Composite configSectionCreate(final Composite parent) {
 		ImageLoader imageLoader = ImageLoader.getInstance();
 		Image imgOpenFolder = imageLoader.getImage("openFolderButton");
 
-    GridData gridData;
-    Label label;
-    String sCurConfigID;
-    final ArrayList allConfigIDs = new ArrayList();
-
-    Composite gFile = new Composite(parent, SWT.NULL);
-
-    GridLayout layout = new GridLayout();
-    layout.numColumns = 2;
-    layout.marginHeight = 0;
-    gFile.setLayout(layout);
-
-    
-    int userMode = COConfigurationManager.getIntParameter("User Mode");
-
-    // Default Dir Sction
-    Group gDefaultDir = new Group(gFile, SWT.NONE);
-    Messages.setLanguageText(gDefaultDir, "ConfigView.section.file.defaultdir.section");
-    layout = new GridLayout();
-    layout.numColumns = 3;
-    layout.marginHeight = 0;
-    gDefaultDir.setLayout(layout);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 2;
-    gDefaultDir.setLayoutData(gridData);
-
-    // Save Path
-    sCurConfigID = "Default save path";
-    allConfigIDs.add(sCurConfigID);
-    Label lblDefaultDir = new Label(gDefaultDir, SWT.NONE);
-    Messages.setLanguageText(lblDefaultDir, "ConfigView.section.file.defaultdir.ask");
-    lblDefaultDir.setLayoutData(new GridData());
-    
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    final StringParameter pathParameter = new StringParameter(gDefaultDir, sCurConfigID);
-    pathParameter.setLayoutData(gridData);
-
-    Button browse = new Button(gDefaultDir, SWT.PUSH);
-    browse.setImage(imgOpenFolder);
-    imgOpenFolder.setBackground(browse.getBackground());
-    browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
-
-    browse.addListener(SWT.Selection, new Listener() {
-      /* (non-Javadoc)
-       * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
-       */
-      public void handleEvent(Event event) {
-        DirectoryDialog dialog = new DirectoryDialog(parent.getShell(), SWT.APPLICATION_MODAL);
-        dialog.setFilterPath(pathParameter.getValue());
-        dialog.setMessage(MessageText.getString("ConfigView.dialog.choosedefaultsavepath"));
-        dialog.setText(MessageText.getString("ConfigView.section.file.defaultdir.ask"));
-        String path = dialog.open();
-        if (path != null) {
-          pathParameter.setValue(path);
-        }
-      }
-    });
-    
-    // def dir: autoSave
-    sCurConfigID = "Use default data dir";
-    allConfigIDs.add(sCurConfigID);
-    BooleanParameter autoSaveToDir = new BooleanParameter(gDefaultDir,
-				sCurConfigID, "ConfigView.section.file.defaultdir.auto");
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 3;
-    autoSaveToDir.setLayoutData(gridData);
-    
-    // def dir: autoSave -> auto-rename
-    sCurConfigID = "DefaultDir.AutoSave.AutoRename";
-    allConfigIDs.add(sCurConfigID);
-    BooleanParameter autoSaveAutoRename = new BooleanParameter(gDefaultDir,
-    		sCurConfigID, "ConfigView.section.file.defaultdir.autorename");
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 3;
-    gridData.horizontalIndent = 20;
-    autoSaveAutoRename.setLayoutData(gridData);
-    IAdditionalActionPerformer aapDefaultDirStuff3 = new ChangeSelectionActionPerformer(
-				autoSaveAutoRename.getControls(), false);
-		autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff3);
-    
-    
-    // def dir: best guess
-    sCurConfigID = "DefaultDir.BestGuess";
-    allConfigIDs.add(sCurConfigID);
-    BooleanParameter bestGuess = new BooleanParameter(gDefaultDir,
-				sCurConfigID, "ConfigView.section.file.defaultdir.bestguess");
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 3;
-    bestGuess.setLayoutData(gridData);
-
-    IAdditionalActionPerformer aapDefaultDirStuff = new ChangeSelectionActionPerformer(
-				bestGuess.getControls(), true);
-    autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff);
-
-    // def dir: auto update
-    sCurConfigID = "DefaultDir.AutoUpdate";
-    allConfigIDs.add(sCurConfigID);
-    BooleanParameter autoUpdateSaveDir = new BooleanParameter(gDefaultDir, 
-    		sCurConfigID, "ConfigView.section.file.defaultdir.lastused");
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.horizontalSpan = 3;
-    autoUpdateSaveDir.setLayoutData(gridData);
-
-    IAdditionalActionPerformer aapDefaultDirStuff2 = new ChangeSelectionActionPerformer(
-    		autoUpdateSaveDir.getControls(), true);
-    autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff2);
-
-
-    ////////////////////
-    
-    sCurConfigID = "XFS Allocation";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 && !Constants.isWindows ) {
-    	BooleanParameter xfsAllocation = 
-    		new BooleanParameter(gFile, sCurConfigID,
-                                    "ConfigView.label.xfs.allocation");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	xfsAllocation.setLayoutData(gridData);
-    }
-
-    BooleanParameter zeroNew = null;
-
-    sCurConfigID = "Zero New";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 ) {
-    	// zero new files
-    	zeroNew = new BooleanParameter(gFile, sCurConfigID,
-                                                    "ConfigView.label.zeronewfiles");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	zeroNew.setLayoutData(gridData);
-    }
-
-    
-    sCurConfigID = "File.truncate.if.too.large";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 ) {
-    	// truncate too large
-    	BooleanParameter truncateLarge = 
-    		new BooleanParameter(gFile, sCurConfigID,
-                                    "ConfigView.section.file.truncate.too.large");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	truncateLarge.setLayoutData(gridData);
-    }
-    
-    sCurConfigID = "Enable incremental file creation";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 ) {
-    	// incremental file creation
-    	BooleanParameter incremental = new BooleanParameter(gFile, sCurConfigID,
-                                                        "ConfigView.label.incrementalfile");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	incremental.setLayoutData(gridData);
-
-    	//Make the incremental checkbox (button) deselect when zero new is used
-    	Button[] btnIncremental = {(Button)incremental.getControl()};
-    	zeroNew.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(btnIncremental));
-
-    	//Make the zero new checkbox(button) deselct when incremental is used
-    	Button[] btnZeroNew = {(Button)zeroNew.getControl()};
-    	incremental.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(btnZeroNew));
-    }
-    
-    
-    sCurConfigID = "Check Pieces on Completion";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 ) {
-    	// check on complete
-    	BooleanParameter checkOnComp = new BooleanParameter(gFile, sCurConfigID,
-                                                        "ConfigView.label.checkOncompletion");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	checkOnComp.setLayoutData(gridData);
-    }
-    
-    sCurConfigID = "Seeding Piece Check Recheck Enable";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 0 ) {
-    	// check on complete
-    	BooleanParameter checkOnSeeding = new BooleanParameter(gFile, sCurConfigID,
-                                                        "ConfigView.label.checkOnSeeding");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	checkOnSeeding.setLayoutData(gridData);
-    }
-    
-
-    sCurConfigID = "File.strict.locking";
-    allConfigIDs.add(sCurConfigID);
-    if( userMode > 1 ) {
-    	
-    	BooleanParameter strictLocking = 
-    		new BooleanParameter(gFile, sCurConfigID,
-                                    "ConfigView.label.strictfilelocking");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	strictLocking.setLayoutData(gridData);
-    }
-    
-    if( userMode == 0 ) {
-      allConfigIDs.add("Use Resume");
-      sCurConfigID = "Save Resume Interval";
-      allConfigIDs.add(sCurConfigID);
-      sCurConfigID = "On Resume Recheck All";
-      allConfigIDs.add(sCurConfigID);
-      sCurConfigID = "File.save.peers.enable";
-      allConfigIDs.add(sCurConfigID);
-      sCurConfigID = "File.save.peers.max";
-      allConfigIDs.add(sCurConfigID);
-    } else {
-      sCurConfigID = "Use Resume";
-      allConfigIDs.add(sCurConfigID);
-    	// resume data
-      final BooleanParameter bpUseResume = new BooleanParameter(gFile, sCurConfigID,
-                                                              "ConfigView.label.usefastresume");
-      bpUseResume.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
-
-      Composite cResumeGroup = new Composite(gFile, SWT.NULL);
-      layout = new GridLayout();
-      layout.marginHeight = 0;
-      layout.marginWidth = 4;
-      layout.numColumns = 3;
-      cResumeGroup.setLayout(layout);
-      gridData = new GridData(GridData.FILL_HORIZONTAL);
-      gridData.horizontalIndent = 25;
-      gridData.horizontalSpan = 2;
-      cResumeGroup.setLayoutData(gridData);
-
-      sCurConfigID = "Save Resume Interval";
-      allConfigIDs.add(sCurConfigID);
-      Label lblSaveResumeInterval = new Label(cResumeGroup, SWT.NULL);
-      Messages.setLanguageText(lblSaveResumeInterval, "ConfigView.label.saveresumeinterval");
-
-      IntParameter paramSaveInterval = new IntParameter(cResumeGroup, sCurConfigID);
-      gridData = new GridData();
-      paramSaveInterval.setLayoutData(gridData);
-
-      Label lblMinutes = new Label(cResumeGroup, SWT.NULL);
-      Messages.setLanguageText(lblMinutes, "ConfigView.text.minutes");
-
-      // save peers
-
-      sCurConfigID = "On Resume Recheck All";
-      allConfigIDs.add(sCurConfigID);
-      final BooleanParameter recheck_all = new BooleanParameter(cResumeGroup, sCurConfigID,
-                                                               "ConfigView.section.file.resume.recheck.all");
-      gridData = new GridData();
-      gridData.horizontalSpan = 3;
-      recheck_all.setLayoutData(gridData);
-      // save peers
-
-      sCurConfigID = "File.save.peers.enable";
-      allConfigIDs.add(sCurConfigID);
-      final BooleanParameter save_peers = new BooleanParameter(cResumeGroup, sCurConfigID,
-                                                               "ConfigView.section.file.save.peers.enable");
-      gridData = new GridData();
-      gridData.horizontalSpan = 3;
-      save_peers.setLayoutData(gridData);
-
-      // save peers max
-
-
-      sCurConfigID = "File.save.peers.max";
-      allConfigIDs.add(sCurConfigID);
-      final Label lblSavePeersMax = new Label(cResumeGroup, SWT.NULL);
-      Messages.setLanguageText(lblSavePeersMax, "ConfigView.section.file.save.peers.max");
-      final IntParameter savePeersMax = new IntParameter(cResumeGroup, sCurConfigID);
-      gridData = new GridData();
-      savePeersMax.setLayoutData(gridData);
-      final Label lblPerTorrent = new Label(cResumeGroup, SWT.NULL);
-      Messages.setLanguageText(lblPerTorrent, "ConfigView.section.file.save.peers.pertorrent");
-
-
-      final Control[] controls = { cResumeGroup };
-
-      /*
-      IAdditionalActionPerformer performer = new ChangeSelectionActionPerformer(controls);
-      bpUseResume.setAdditionalActionPerformer(performer);
-      */
-
-      IAdditionalActionPerformer f_enabler =
-        new GenericActionPerformer(controls) {
-          public void performAction() {
-            controlsSetEnabled(controls, bpUseResume.isSelected());
-
-            if ( bpUseResume.isSelected()){
-              lblSavePeersMax.setEnabled( save_peers.isSelected());
-              savePeersMax.getControl().setEnabled( save_peers.isSelected());
-              lblPerTorrent.setEnabled( save_peers.isSelected());
-            }
-          }
-        };
-
-      bpUseResume.setAdditionalActionPerformer(f_enabler);
-      save_peers.setAdditionalActionPerformer(f_enabler);
-
-    } //end usermode>0
-
-      if( userMode > 0 ) {   	
-        sCurConfigID = "priorityExtensions";
-        allConfigIDs.add(sCurConfigID);
-
-      	// Auto-Prioritize
-      	label = new Label(gFile, SWT.WRAP);
-      	gridData = new GridData();
-      	gridData.widthHint = 180;
-      	label.setLayoutData(gridData);
-      	Messages.setLanguageText(label, "ConfigView.label.priorityExtensions");
-
-      	Composite cExtensions = new Composite(gFile, SWT.NULL);
-      	gridData = new GridData(GridData.FILL_HORIZONTAL);
-      	cExtensions.setLayoutData(gridData);
-      	layout = new GridLayout();
-      	layout.marginHeight = 0;
-      	layout.marginWidth = 0;
-      	layout.numColumns = 3;
-      	cExtensions.setLayout(layout);
-
-      	gridData = new GridData(GridData.FILL_HORIZONTAL);
-      	new StringParameter(cExtensions, sCurConfigID).setLayoutData(gridData);
-
-        sCurConfigID = "priorityExtensionsIgnoreCase";
-        allConfigIDs.add(sCurConfigID);
-      	new BooleanParameter(cExtensions, sCurConfigID, "ConfigView.label.ignoreCase");
-      } else {
-        sCurConfigID = "priorityExtensions";
-        allConfigIDs.add(sCurConfigID);
-        sCurConfigID = "priorityExtensionsIgnoreCase";
-        allConfigIDs.add(sCurConfigID);
-      }
-      
-
-      // rename incomplete
-      
-    sCurConfigID = "Rename Incomplete Files";
-    allConfigIDs.add(sCurConfigID);
-
-    gridData = new GridData();
-    gridData.horizontalSpan = 1;
-    BooleanParameter rename_incomplete = new BooleanParameter(gFile, sCurConfigID,
-  		"ConfigView.section.file.rename.incomplete");
-    rename_incomplete.setLayoutData(gridData);
-    
-    sCurConfigID = "Rename Incomplete Files Extension";
-    allConfigIDs.add(sCurConfigID);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    StringParameter rename_incomplete_ext = new StringParameter(gFile, sCurConfigID);
-    rename_incomplete_ext.setLayoutData(gridData);
-
-    IAdditionalActionPerformer incompFileAP = new ChangeSelectionActionPerformer(
-    		rename_incomplete_ext.getControls(), false);
-    rename_incomplete.setAdditionalActionPerformer(incompFileAP);
-    
-      // Confirm Delete
-    sCurConfigID = "Confirm Data Delete";
-    allConfigIDs.add(sCurConfigID);
-
-    gridData = new GridData();
-    gridData.horizontalSpan = 2;
-    new BooleanParameter(gFile, sCurConfigID,
-				"ConfigView.section.file.confirm_data_delete").setLayoutData(gridData);
-
-
-    sCurConfigID = "File.delete.include_files_outside_save_dir";
-    allConfigIDs.add(sCurConfigID);
-
-    gridData = new GridData();
-    gridData.horizontalSpan = 2;
-    new BooleanParameter(gFile, sCurConfigID,
-				"ConfigView.section.file.delete.include_files_outside_save_dir").setLayoutData(gridData);
-
-    if ( userMode > 0 ){
-
-		Label lIgnoreFiles = new Label(gFile, SWT.NULL);
-		Messages.setLanguageText(lIgnoreFiles,
-				"ConfigView.section.file.torrent.ignorefiles");
+		GridData gridData;
+		Label label;
+		String sCurConfigID;
+		final ArrayList allConfigIDs = new ArrayList();
+
+		Composite gFile = new Composite(parent, SWT.NULL);
+
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 0;
+		gFile.setLayout(layout);
+
+		int userMode = COConfigurationManager.getIntParameter("User Mode");
 
+		// Default Dir Sction
+		Group gDefaultDir = new Group(gFile, SWT.NONE);
+		Messages.setLanguageText(gDefaultDir,
+				"ConfigView.section.file.defaultdir.section");
+		layout = new GridLayout();
+		layout.numColumns = 3;
+		layout.marginHeight = 2;
+		gDefaultDir.setLayout(layout);
 		gridData = new GridData(GridData.FILL_HORIZONTAL);
-		new StringParameter(gFile, "File.Torrent.IgnoreFiles",
-				TOTorrent.DEFAULT_IGNORE_FILES).setLayoutData(gridData);
+		gridData.horizontalSpan = 2;
+		gDefaultDir.setLayoutData(gridData);
 
-	}
+		// Save Path
+		sCurConfigID = "Default save path";
+		allConfigIDs.add(sCurConfigID);
+		Label lblDefaultDir = new Label(gDefaultDir, SWT.NONE);
+		Messages.setLanguageText(lblDefaultDir,
+				"ConfigView.section.file.defaultdir.ask");
+		lblDefaultDir.setLayoutData(new GridData());
 
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		final StringParameter pathParameter = new StringParameter(gDefaultDir,
+				sCurConfigID);
+		pathParameter.setLayoutData(gridData);
+
+		Button browse = new Button(gDefaultDir, SWT.PUSH);
+		browse.setImage(imgOpenFolder);
+		imgOpenFolder.setBackground(browse.getBackground());
+		browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
+
+		browse.addListener(SWT.Selection, new Listener() {
+			/* (non-Javadoc)
+			 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+			 */
+			public void handleEvent(Event event) {
+				DirectoryDialog dialog = new DirectoryDialog(parent.getShell(),
+						SWT.APPLICATION_MODAL);
+				dialog.setFilterPath(pathParameter.getValue());
+				dialog.setMessage(MessageText.getString("ConfigView.dialog.choosedefaultsavepath"));
+				dialog.setText(MessageText.getString("ConfigView.section.file.defaultdir.ask"));
+				String path = dialog.open();
+				if (path != null) {
+					pathParameter.setValue(path);
+				}
+			}
+		});
 
-    try{
-	    final PlatformManager	platform  = PlatformManagerFactory.getPlatformManager();
-	    
-	    if (platform.hasCapability(PlatformManagerCapabilities.RecoverableFileDelete)){
-	      sCurConfigID = "Move Deleted Data To Recycle Bin";
-	      allConfigIDs.add(sCurConfigID);
-
-		    gridData = new GridData();
-		    gridData.horizontalSpan = 2;
-		    new BooleanParameter(gFile, sCurConfigID,
-		                         "ConfigView.section.file.nativedelete").setLayoutData(gridData);
-
-	    }    
-    }catch( Throwable e ){
-    	
-    }
-
-    if( userMode > 0 ) {
-    	Group gConfigSettings = new Group(gFile, SWT.NONE);
-    	Messages.setLanguageText(gConfigSettings, "ConfigView.section.file.config.section");
-    	layout = new GridLayout();
-    	layout.numColumns = 2;
-    	layout.marginHeight = 5;
-    	gConfigSettings.setLayout(layout);
-    	gridData = new GridData(GridData.FILL_HORIZONTAL);
-    	gridData.horizontalSpan = 2;
-    	gConfigSettings.setLayoutData(gridData);
-
-    	// Configuration directory information.
-    	Label config_label = new Label(gConfigSettings, SWT.NULL);
-    	Messages.setLanguageText(config_label, "ConfigView.section.file.config.currentdir");
-    	config_label.setLayoutData(new GridData());
-    	Label config_link = new Label(gConfigSettings, SWT.NULL);
-    	config_link.setText(SystemProperties.getUserPath());
-    	config_link.setLayoutData(new GridData());
-    	LinkLabel.makeLinkedLabel(config_link, SystemProperties.getUserPath());
-    
-    	sCurConfigID = "Use Config File Backups";
-    	allConfigIDs.add(sCurConfigID);
-    	
-    	// check on complete
-    	BooleanParameter backupConfig = 
-    		new BooleanParameter(gConfigSettings, sCurConfigID,
-                                    "ConfigView.label.backupconfigfiles");
-    	gridData = new GridData();
-    	gridData.horizontalSpan = 2;
-    	backupConfig.setLayoutData(gridData);
-    }
-/*
-    Button buttonReset = new Button(gFile, SWT.PUSH);
-    Messages.setLanguageText(buttonReset, "Button.reset");
-    gridData = new GridData(GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_END);
-  	gridData.horizontalSpan = 2;
-  	buttonReset.setLayoutData(gridData);
-  	buttonReset.addSelectionListener(new SelectionAdapter() {
-  		public void widgetSelected(SelectionEvent e) {
-  			for (Iterator iter = allConfigIDs.iterator(); iter.hasNext();) {
-					String sConfigID = (String) iter.next();
-					COConfigurationManager.removeParameter(sConfigID);
+		// def dir: autoSave
+		sCurConfigID = "Use default data dir";
+		allConfigIDs.add(sCurConfigID);
+		BooleanParameter autoSaveToDir = new BooleanParameter(gDefaultDir,
+				sCurConfigID, "ConfigView.section.file.defaultdir.auto");
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 3;
+		autoSaveToDir.setLayoutData(gridData);
+
+		if (userMode > 0) {
+			// def dir: autoSave -> auto-rename
+			sCurConfigID = "DefaultDir.AutoSave.AutoRename";
+			allConfigIDs.add(sCurConfigID);
+			BooleanParameter autoSaveAutoRename = new BooleanParameter(gDefaultDir,
+					sCurConfigID, "ConfigView.section.file.defaultdir.autorename");
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 3;
+			gridData.horizontalIndent = 20;
+			autoSaveAutoRename.setLayoutData(gridData);
+			IAdditionalActionPerformer aapDefaultDirStuff3 = new ChangeSelectionActionPerformer(
+					autoSaveAutoRename.getControls(), false);
+			autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff3);
+
+			// def dir: best guess
+			sCurConfigID = "DefaultDir.BestGuess";
+			allConfigIDs.add(sCurConfigID);
+			BooleanParameter bestGuess = new BooleanParameter(gDefaultDir,
+					sCurConfigID, "ConfigView.section.file.defaultdir.bestguess");
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 3;
+			bestGuess.setLayoutData(gridData);
+
+			IAdditionalActionPerformer aapDefaultDirStuff = new ChangeSelectionActionPerformer(
+					bestGuess.getControls(), true);
+			autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff);
+
+			// def dir: auto update
+			sCurConfigID = "DefaultDir.AutoUpdate";
+			allConfigIDs.add(sCurConfigID);
+			BooleanParameter autoUpdateSaveDir = new BooleanParameter(gDefaultDir,
+					sCurConfigID, "ConfigView.section.file.defaultdir.lastused");
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 3;
+			autoUpdateSaveDir.setLayoutData(gridData);
+
+			IAdditionalActionPerformer aapDefaultDirStuff2 = new ChangeSelectionActionPerformer(
+					autoUpdateSaveDir.getControls(), true);
+			autoSaveToDir.setAdditionalActionPerformer(aapDefaultDirStuff2);
+		}
+
+		new Label(gFile, SWT.NONE);
+
+		////////////////////
+
+		sCurConfigID = "XFS Allocation";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0 && !Constants.isWindows) {
+			BooleanParameter xfsAllocation = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.label.xfs.allocation");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			xfsAllocation.setLayoutData(gridData);
+		}
+
+		BooleanParameter zeroNew = null;
+
+		sCurConfigID = "Zero New";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+			// zero new files
+			zeroNew = new BooleanParameter(gFile, sCurConfigID,
+					"ConfigView.label.zeronewfiles");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			zeroNew.setLayoutData(gridData);
+		}
+
+		BooleanParameter pieceReorder = null;
+
+		sCurConfigID = "Enable reorder storage mode";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+
+			pieceReorder = new BooleanParameter(gFile, sCurConfigID,
+					"ConfigView.label.piecereorder");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			pieceReorder.setLayoutData(gridData);
+
+			//Make the reorder checkbox (button) deselect when zero new is used
+			Button[] btnReorder = {
+				(Button) pieceReorder.getControl()
+			};
+			zeroNew.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(
+					btnReorder));
+
+			//Make the zero new checkbox(button) deselct when reorder is used
+			Button[] btnZeroNew = {
+				(Button) zeroNew.getControl()
+			};
+			pieceReorder.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(
+					btnZeroNew));
+		}
+
+		sCurConfigID = "Reorder storage mode min MB";
+		allConfigIDs.add(sCurConfigID);
+
+		if (userMode > 0) {
+			Label lblMinMB = new Label(gFile, SWT.NULL);
+			Messages.setLanguageText(lblMinMB, "ConfigView.label.piecereorderminmb");
+			gridData = new GridData();
+			gridData.horizontalIndent = 25;
+			lblMinMB.setLayoutData(gridData);
+
+			IntParameter minMB = new IntParameter(gFile, sCurConfigID);
+			gridData = new GridData();
+			minMB.setLayoutData(gridData);
+
+			pieceReorder.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+					lblMinMB));
+			pieceReorder.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+					minMB));
+		}
+
+		sCurConfigID = "Enable incremental file creation";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+			// incremental file creation
+			BooleanParameter incremental = new BooleanParameter(gFile, sCurConfigID,
+					"ConfigView.label.incrementalfile");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			incremental.setLayoutData(gridData);
+
+			//Make the incremental checkbox (button) deselect when zero new is used
+			Button[] btnIncremental = {
+				(Button) incremental.getControl()
+			};
+			zeroNew.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(
+					btnIncremental));
+
+			//Make the zero new checkbox(button) deselct when incremental is used
+			Button[] btnZeroNew = {
+				(Button) zeroNew.getControl()
+			};
+			incremental.setAdditionalActionPerformer(new ExclusiveSelectionActionPerformer(
+					btnZeroNew));
+		}
+
+		sCurConfigID = "File.truncate.if.too.large";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+			// truncate too large
+			BooleanParameter truncateLarge = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.section.file.truncate.too.large");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			truncateLarge.setLayoutData(gridData);
+		}
+
+		sCurConfigID = "Check Pieces on Completion";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+			// check on complete
+			BooleanParameter checkOnComp = new BooleanParameter(gFile, sCurConfigID,
+					"ConfigView.label.checkOncompletion");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			checkOnComp.setLayoutData(gridData);
+		}
+
+		sCurConfigID = "Seeding Piece Check Recheck Enable";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 0) {
+			// check on complete
+			BooleanParameter checkOnSeeding = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.label.checkOnSeeding");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			checkOnSeeding.setLayoutData(gridData);
+		}
+
+		sCurConfigID = "File.strict.locking";
+		allConfigIDs.add(sCurConfigID);
+		if (userMode > 1) {
+
+			BooleanParameter strictLocking = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.label.strictfilelocking");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			strictLocking.setLayoutData(gridData);
+		}
+
+		if (userMode == 0) {
+			allConfigIDs.add("Use Resume");
+			sCurConfigID = "Save Resume Interval";
+			allConfigIDs.add(sCurConfigID);
+			sCurConfigID = "On Resume Recheck All";
+			allConfigIDs.add(sCurConfigID);
+			sCurConfigID = "File.save.peers.enable";
+			allConfigIDs.add(sCurConfigID);
+			sCurConfigID = "File.save.peers.max";
+			allConfigIDs.add(sCurConfigID);
+		} else {
+			sCurConfigID = "Use Resume";
+			allConfigIDs.add(sCurConfigID);
+			// resume data
+			final BooleanParameter bpUseResume = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.label.usefastresume");
+			bpUseResume.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+
+			Composite cResumeGroup = new Composite(gFile, SWT.NULL);
+			layout = new GridLayout();
+			layout.marginHeight = 0;
+			layout.marginWidth = 4;
+			layout.numColumns = 3;
+			cResumeGroup.setLayout(layout);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalIndent = 25;
+			gridData.horizontalSpan = 2;
+			cResumeGroup.setLayoutData(gridData);
+
+			sCurConfigID = "Save Resume Interval";
+			allConfigIDs.add(sCurConfigID);
+			Label lblSaveResumeInterval = new Label(cResumeGroup, SWT.NULL);
+			Messages.setLanguageText(lblSaveResumeInterval,
+					"ConfigView.label.saveresumeinterval");
+
+			IntParameter paramSaveInterval = new IntParameter(cResumeGroup,
+					sCurConfigID);
+			gridData = new GridData();
+			paramSaveInterval.setLayoutData(gridData);
+
+			Label lblMinutes = new Label(cResumeGroup, SWT.NULL);
+			Messages.setLanguageText(lblMinutes, "ConfigView.text.minutes");
+
+			// save peers
+
+			sCurConfigID = "On Resume Recheck All";
+			allConfigIDs.add(sCurConfigID);
+			final BooleanParameter recheck_all = new BooleanParameter(cResumeGroup,
+					sCurConfigID, "ConfigView.section.file.resume.recheck.all");
+			gridData = new GridData();
+			gridData.horizontalSpan = 3;
+			recheck_all.setLayoutData(gridData);
+			// save peers
+
+			sCurConfigID = "File.save.peers.enable";
+			allConfigIDs.add(sCurConfigID);
+			final BooleanParameter save_peers = new BooleanParameter(cResumeGroup,
+					sCurConfigID, "ConfigView.section.file.save.peers.enable");
+			gridData = new GridData();
+			gridData.horizontalSpan = 3;
+			save_peers.setLayoutData(gridData);
+
+			// save peers max
+
+			sCurConfigID = "File.save.peers.max";
+			allConfigIDs.add(sCurConfigID);
+			final Label lblSavePeersMax = new Label(cResumeGroup, SWT.NULL);
+			Messages.setLanguageText(lblSavePeersMax,
+					"ConfigView.section.file.save.peers.max");
+			final IntParameter savePeersMax = new IntParameter(cResumeGroup,
+					sCurConfigID);
+			gridData = new GridData();
+			savePeersMax.setLayoutData(gridData);
+			final Label lblPerTorrent = new Label(cResumeGroup, SWT.NULL);
+			Messages.setLanguageText(lblPerTorrent,
+					"ConfigView.section.file.save.peers.pertorrent");
+
+			final Control[] controls = {
+				cResumeGroup
+			};
+
+			/*
+			IAdditionalActionPerformer performer = new ChangeSelectionActionPerformer(controls);
+			bpUseResume.setAdditionalActionPerformer(performer);
+			*/
+
+			IAdditionalActionPerformer f_enabler = new GenericActionPerformer(
+					controls) {
+				public void performAction() {
+					controlsSetEnabled(controls, bpUseResume.isSelected());
+
+					if (bpUseResume.isSelected()) {
+						lblSavePeersMax.setEnabled(save_peers.isSelected());
+						savePeersMax.getControl().setEnabled(save_peers.isSelected());
+						lblPerTorrent.setEnabled(save_peers.isSelected());
+					}
 				}
-  		}
-  	});
-*/
-    return gFile;
-  }
+			};
+
+			bpUseResume.setAdditionalActionPerformer(f_enabler);
+			save_peers.setAdditionalActionPerformer(f_enabler);
+
+		} //end usermode>0
+
+		if (userMode > 0) {
+			sCurConfigID = "priorityExtensions";
+			allConfigIDs.add(sCurConfigID);
+
+			// Auto-Prioritize
+			label = new Label(gFile, SWT.WRAP);
+			gridData = new GridData();
+			gridData.widthHint = 180;
+			label.setLayoutData(gridData);
+			Messages.setLanguageText(label, "ConfigView.label.priorityExtensions");
+
+			Composite cExtensions = new Composite(gFile, SWT.NULL);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			cExtensions.setLayoutData(gridData);
+			layout = new GridLayout();
+			layout.marginHeight = 0;
+			layout.marginWidth = 0;
+			layout.numColumns = 3;
+			cExtensions.setLayout(layout);
+
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			new StringParameter(cExtensions, sCurConfigID).setLayoutData(gridData);
+
+			sCurConfigID = "priorityExtensionsIgnoreCase";
+			allConfigIDs.add(sCurConfigID);
+			new BooleanParameter(cExtensions, sCurConfigID,
+					"ConfigView.label.ignoreCase");
+		} else {
+			sCurConfigID = "priorityExtensions";
+			allConfigIDs.add(sCurConfigID);
+			sCurConfigID = "priorityExtensionsIgnoreCase";
+			allConfigIDs.add(sCurConfigID);
+		}
+		
+		// quick view
+		
+		sCurConfigID = "quick.view.exts";
+		allConfigIDs.add(sCurConfigID);
+
+		label = new Label(gFile, SWT.WRAP);
+		gridData = new GridData();
+		gridData.widthHint = 180;
+		label.setLayoutData(gridData);
+		Messages.setLanguageText(label, "ConfigView.label.quickviewexts");
+
+		Composite cQuickView = new Composite(gFile, SWT.NULL);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		cQuickView.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.numColumns = 3;
+		cQuickView.setLayout(layout);
+
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		new StringParameter(cQuickView, sCurConfigID ).setLayoutData(gridData);
+
+		label = new Label(cQuickView, SWT.NONE);
+		Messages.setLanguageText(label, "ConfigView.label.quickviewmaxkb");
+
+		sCurConfigID = "quick.view.maxkb";
+		allConfigIDs.add(sCurConfigID);
+		IntParameter qvmax = new IntParameter(cQuickView, sCurConfigID, 1, 256 );
+		
+		
+		// rename incomplete
+
+		if (userMode > 0) {
+			sCurConfigID = "Rename Incomplete Files";
+			allConfigIDs.add(sCurConfigID);
+
+			gridData = new GridData();
+			gridData.horizontalSpan = 1;
+			BooleanParameter rename_incomplete = new BooleanParameter(gFile,
+					sCurConfigID, "ConfigView.section.file.rename.incomplete");
+			rename_incomplete.setLayoutData(gridData);
+
+			sCurConfigID = "Rename Incomplete Files Extension";
+			allConfigIDs.add(sCurConfigID);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			StringParameter rename_incomplete_ext = new StringParameter(gFile,
+					sCurConfigID);
+			rename_incomplete_ext.setLayoutData(gridData);
+
+			IAdditionalActionPerformer incompFileAP = new ChangeSelectionActionPerformer(
+					rename_incomplete_ext.getControls(), false);
+			rename_incomplete.setAdditionalActionPerformer(incompFileAP);
+
+			Label lIgnoreFiles = new Label(gFile, SWT.NULL);
+			Messages.setLanguageText(lIgnoreFiles,
+					"ConfigView.section.file.torrent.ignorefiles");
+
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			new StringParameter(gFile, "File.Torrent.IgnoreFiles",
+					TOTorrent.DEFAULT_IGNORE_FILES).setLayoutData(gridData);
+
+		}
+
+		Group gDeletion = new Group(gFile, SWT.NONE);
+		Messages.setLanguageText(gDeletion,
+				"ConfigView.section.file.deletion.section");
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 5;
+		gDeletion.setLayout(layout);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 2;
+		gDeletion.setLayoutData(gridData);
+		
+		if (userMode > 0) {
+  		Composite c = new Composite(gDeletion, SWT.NONE);
+  		layout = new GridLayout();
+  		layout.numColumns = 2;
+  		layout.marginHeight = 0;
+  		layout.marginWidth = 0;
+  		c.setLayout(layout);
+  		gridData = new GridData(GridData.FILL_HORIZONTAL);
+  		gridData.horizontalSpan = 2;
+  		c.setLayoutData(gridData);
+  		
+  		sCurConfigID = "tb.confirm.delete.content";
+  		label = new Label(c, SWT.NULL);
+  		Messages.setLanguageText(label, "ConfigView.section.file.tb.delete");
+  		int[] values = {
+  			0,
+  			1,
+  			2,
+  		};
+  		String[] labels = {
+  			MessageText.getString("ConfigView.tb.delete.ask"),
+  			MessageText.getString("ConfigView.tb.delete.content"),
+  			MessageText.getString("ConfigView.tb.delete.torrent"),
+  		};
+  		new IntListParameter(c, sCurConfigID, labels, values);
+
+  		
+  		sCurConfigID = "def.deletetorrent";
+  		allConfigIDs.add(sCurConfigID);
+  		gridData = new GridData();
+  		gridData.horizontalSpan = 2;
+  		new BooleanParameter(gDeletion, sCurConfigID, "ConfigView.section.file.delete.torrent").setLayoutData(gridData);
+		}
+
+		
+		try {
+			final PlatformManager platform = PlatformManagerFactory.getPlatformManager();
+
+			if (platform.hasCapability(PlatformManagerCapabilities.RecoverableFileDelete)) {
+				sCurConfigID = "Move Deleted Data To Recycle Bin";
+				allConfigIDs.add(sCurConfigID);
+
+				gridData = new GridData();
+				gridData.horizontalSpan = 2;
+				new BooleanParameter(gDeletion, sCurConfigID,
+						"ConfigView.section.file.nativedelete").setLayoutData(gridData);
+
+			}
+		} catch (Throwable e) {
+
+		}
+		
+		if (userMode > 0) {
+			sCurConfigID = "File.delete.include_files_outside_save_dir";
+			allConfigIDs.add(sCurConfigID);
+
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			new BooleanParameter(gDeletion, sCurConfigID,
+					"ConfigView.section.file.delete.include_files_outside_save_dir").setLayoutData(gridData);
+		}
+
+		if (userMode > 0) {
+			Group gConfigSettings = new Group(gFile, SWT.NONE);
+			Messages.setLanguageText(gConfigSettings,
+					"ConfigView.section.file.config.section");
+			layout = new GridLayout();
+			layout.numColumns = 2;
+			layout.marginHeight = 5;
+			gConfigSettings.setLayout(layout);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 2;
+			gConfigSettings.setLayoutData(gridData);
+
+			// Configuration directory information.
+			Label config_label = new Label(gConfigSettings, SWT.NULL);
+			Messages.setLanguageText(config_label,
+					"ConfigView.section.file.config.currentdir");
+			config_label.setLayoutData(new GridData());
+			Label config_link = new Label(gConfigSettings, SWT.NULL);
+			config_link.setText(SystemProperties.getUserPath());
+			config_link.setLayoutData(new GridData());
+			LinkLabel.makeLinkedLabel(config_link, SystemProperties.getUserPath());
+
+			sCurConfigID = "Use Config File Backups";
+			allConfigIDs.add(sCurConfigID);
+
+			// check on complete
+			BooleanParameter backupConfig = new BooleanParameter(gConfigSettings,
+					sCurConfigID, "ConfigView.label.backupconfigfiles");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			backupConfig.setLayoutData(gridData);
+		}
+		/*
+		    Button buttonReset = new Button(gFile, SWT.PUSH);
+		    Messages.setLanguageText(buttonReset, "Button.reset");
+		    gridData = new GridData(GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_END);
+		  	gridData.horizontalSpan = 2;
+		  	buttonReset.setLayoutData(gridData);
+		  	buttonReset.addSelectionListener(new SelectionAdapter() {
+		  		public void widgetSelected(SelectionEvent e) {
+		  			for (Iterator iter = allConfigIDs.iterator(); iter.hasNext();) {
+							String sConfigID = (String) iter.next();
+							COConfigurationManager.removeParameter(sConfigID);
+						}
+		  		}
+		  	});
+		*/
+		return gFile;
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
index 54c5849..edf11e1 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionIPFilter.java
@@ -32,9 +32,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 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.layout.*;
 import org.eclipse.swt.widgets.*;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -203,6 +201,7 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
     			Parameter	p,
     			boolean		caused_internally )
 			{
+    			
     			setPercentageBlocked();
 			}
 		});
@@ -285,24 +284,34 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
     				discard_min.getControl(), discard_min_label }));
 
 
+    
+    
+    
+    
+    
+    
+    
+    
     Group gAutoLoad = new Group(gFilter, SWT.NONE);
     Messages.setLanguageText(gAutoLoad, "ConfigView.section.ipfilter.autoload.group");
-    layout = new GridLayout();
-    layout.numColumns = 4;
-    gAutoLoad.setLayout(layout);
-    gAutoLoad.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+    FormLayout flayout = new FormLayout();
+    flayout.marginHeight =flayout.marginWidth = 5; 
+    gAutoLoad.setLayout(flayout);
+    gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+    gridData.widthHint = 500;
+    gAutoLoad.setLayoutData(gridData);
+
+    FormData fd;
     
     // Load from file
     sCurConfigID = "Ip Filter Autoload File";
     //allConfigIDs.add(sCurConfigID);
     Label lblDefaultDir = new Label(gAutoLoad, SWT.NONE);
     Messages.setLanguageText(lblDefaultDir, "ConfigView.section.ipfilter.autoload.file");
-    lblDefaultDir.setLayoutData(new GridData());
+    fd = new FormData();
+    lblDefaultDir.setLayoutData(fd);
     
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
-    gridData.minimumWidth = 50;
     final StringParameter pathParameter = new StringParameter(gAutoLoad, sCurConfigID);
-    pathParameter.setLayoutData(gridData);
 
     Button browse = new Button(gAutoLoad, SWT.PUSH);
     browse.setImage(imgOpenFolder);
@@ -325,33 +334,65 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
         }
       }
     });
-    browse.setLayoutData(new GridData());
     
     final Button btnLoadNow = new Button(gAutoLoad, SWT.PUSH);
     Messages.setLanguageText(btnLoadNow, "ConfigView.section.ipfilter.autoload.loadnow");
     btnLoadNow.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event event) {
-				try {
-					btnLoadNow.getShell().setCursor(btnLoadNow.getDisplay().getSystemCursor(
-							SWT.CURSOR_WAIT));
-					COConfigurationManager.setParameter(IpFilterAutoLoaderImpl.CFG_AUTOLOAD_LAST, 0);
-					filter.reload();
-					btnLoadNow.getShell().setCursor(btnLoadNow.getDisplay().getSystemCursor(
-							SWT.CURSOR_ARROW));
-				} catch (Exception e) {
-					e.printStackTrace();
-				}
+				btnLoadNow.setEnabled(false);
+				COConfigurationManager.setParameter(
+						IpFilterAutoLoaderImpl.CFG_AUTOLOAD_LAST, 0);
+				Utils.getOffOfSWTThread(new AERunnable() {
+					public void runSupport() {
+						try {
+							filter.reloadSync();
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+						Utils.execSWTThread(new AERunnable() {
+							public void runSupport() {
+								if (!btnLoadNow.isDisposed()) {
+									btnLoadNow.setEnabled(true);
+								}
+							}
+						});
+					}
+				});
 			}
 		});
-    btnLoadNow.setLayoutData(new GridData());
+
+    fd = new FormData();
+    fd.right = new FormAttachment(100, 0);
+    btnLoadNow.setLayoutData(fd);
     
+    fd = new FormData();
+    fd.right = new FormAttachment(btnLoadNow, -5);
+    browse.setLayoutData(fd);
+
+    fd = new FormData();
+    fd.left = new FormAttachment(lblDefaultDir, 5);
+    fd.right = new FormAttachment(browse, -5);
+    pathParameter.setLayoutData(fd);
+
     Label lblAutoLoadInfo = new Label(gAutoLoad, SWT.WRAP);
     Messages.setLanguageText(lblAutoLoadInfo, "ConfigView.section.ipfilter.autoload.info");
-    lblAutoLoadInfo.setLayoutData(Utils.getWrappableLabelGridData(4, 0));
-
-    
-    
-    // description scratch file
+    fd = new FormData();
+    fd.top = new FormAttachment(btnLoadNow, 3);
+    fd.left = new FormAttachment(0, 0);
+    fd.right = new FormAttachment(100, 0);
+    lblAutoLoadInfo.setLayoutData(fd);
+
+    BooleanParameter clear_on_reload = new BooleanParameter(gAutoLoad, "Ip Filter Clear On Reload" );
+    fd = new FormData();
+    fd.top = new FormAttachment(lblAutoLoadInfo, 3);
+    fd.left = new FormAttachment(0, 0);
+    fd.right = new FormAttachment(100, 0);
+    clear_on_reload.setLayoutData(fd);
+	Messages.setLanguageText(clear_on_reload.getControl(),
+		"ConfigView.section.ipfilter.clear.on.reload");
+	
+    	// description scratch file
+	
     if (userMode > 0) {
     	gridData = new GridData();
     	BooleanParameter enableDesc = new BooleanParameter(gFilter,
@@ -464,7 +505,9 @@ public class ConfigSectionIPFilter implements UISWTConfigSection {
     });
 
     percentage_blocked  = new Label(cArea, SWT.WRAP | SWT.RIGHT);
-    percentage_blocked.setLayoutData(Utils.getWrappableLabelGridData(1, 0));
+    gridData = new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.FILL_HORIZONTAL);
+    percentage_blocked.setLayoutData(gridData);
+    percentage_blocked.setLayoutData(Utils.getWrappableLabelGridData(1, GridData.HORIZONTAL_ALIGN_FILL));
     setPercentageBlocked();
     
 
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
index 63f86b5..e4d038a 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterface.java
@@ -96,12 +96,15 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		layout.marginHeight = 0;
 		cDisplay.setLayout(layout);
 
-		/////////////
-    Group gAutoOpen = new Group(cDisplay, SWT.NULL);
-    Messages.setLanguageText(gAutoOpen, LBLKEY_PREFIX + "autoopen");
-    layout = new GridLayout(3, false);
-    gAutoOpen.setLayout(layout);
-    gAutoOpen.setLayoutData(new GridData());
+		final PlatformManager platform = PlatformManagerFactory.getPlatformManager();
+		
+			// ***** auto open group
+		
+		Group gAutoOpen = new Group(cDisplay, SWT.NULL);
+		Messages.setLanguageText(gAutoOpen, LBLKEY_PREFIX + "autoopen");
+		layout = new GridLayout(3, false);
+		gAutoOpen.setLayout(layout);
+		gAutoOpen.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
 
 
 		label = new Label(gAutoOpen, SWT.NULL);
@@ -117,7 +120,7 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		new BooleanParameter(gAutoOpen, "Open Bar Incomplete", LBLKEY_PREFIX + "autoopen.dl");
 		new BooleanParameter(gAutoOpen, "Open Bar Complete", LBLKEY_PREFIX + "autoopen.cd");
 		
-		/////////////
+			// **** 
 		
 		new BooleanParameter(cDisplay, "Remember transfer bar location", LBLKEY_PREFIX + "transferbar.remember_location");
 
@@ -125,7 +128,7 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		Messages.setLanguageText(gSysTray, LBLKEY_PREFIX + "systray");
 		layout = new GridLayout();
 		gSysTray.setLayout(layout);
-		gSysTray.setLayoutData(new GridData());
+		gSysTray.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
 
 		BooleanParameter est = new BooleanParameter(gSysTray, "Enable System Tray",
 				KEY_PREFIX + "enabletray");
@@ -150,11 +153,12 @@ public class ConfigSectionInterface implements UISWTConfigSection {
         Group limit_group = new Group(cDisplay, SWT.NULL);
         Messages.setLanguageText(limit_group, LBLKEY_PREFIX + "set_ui_transfer_speeds");
         layout = new GridLayout();
+        layout.numColumns = 2;
         limit_group.setLayout(layout);
         limit_group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
         
         Label limit_group_label = new Label(limit_group, SWT.WRAP);
-        limit_group_label.setLayoutData(Utils.getWrappableLabelGridData(1, GridData.GRAB_HORIZONTAL));
+        limit_group_label.setLayoutData(Utils.getWrappableLabelGridData(2, GridData.GRAB_HORIZONTAL));
         Messages.setLanguageText(limit_group_label, LBLKEY_PREFIX + "set_ui_transfer_speeds.description");
         
         String[] limit_types = new String[] {"download", "upload"};
@@ -187,7 +191,7 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		cArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 		
 		new LinkLabel(cArea, LBLKEY_PREFIX + "version.info.link",
-				"http://www.azureuswiki.com/index.php/Version.azureusplatform.com");
+				"http://wiki.vuze.com/w/Version.azureusplatform.com");
 
 		if (!Constants.isOSX) {
 
@@ -207,14 +211,6 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		cArea.setLayout(layout);
 		cArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
-		// config torrent removal
-		
-		BooleanParameter confirm_removal = new BooleanParameter(cArea,
-				"confirm_torrent_removal", KEY_PREFIX + "confirm_torrent_removal");
-		gridData = new GridData();
-		gridData.horizontalSpan = 2;
-		confirm_removal.setLayoutData(gridData);
-
 		// clear remembered decisions
 
 		final Label clear_label = new Label(cArea, SWT.NULL);
@@ -284,7 +280,7 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 				decisions_parameter_listener);
 
 		// drag-drop
-
+		/* gone to comply with whateverooo
 		label = new Label(cArea, SWT.NULL);
 		Messages.setLanguageText(label, "ConfigView.section.style.dropdiraction");
 
@@ -303,39 +299,11 @@ public class ConfigSectionInterface implements UISWTConfigSection {
 		}
 		new StringListParameter(cArea, "config.style.dropdiraction",
 				dropLabels, dropValues);
+		*/
 		
-		// double-click
-		
-    if (COConfigurationManager.getStringParameter("ui").equals("az3")) {
-  		label = new Label(cArea, SWT.NULL);
-  		Messages.setLanguageText(label, LBLKEY_PREFIX + "dm.dblclick");
-  
-  		String[] dblclickOptions = {
-  			"ConfigView.option.dm.dblclick.play",
-  			"ConfigView.option.dm.dblclick.details",
-  			"ConfigView.option.dm.dblclick.show",
-  		};
-  
-  		String dblclickLabels[] = new String[dblclickOptions.length];
-  		String dblclickValues[] = new String[dblclickOptions.length];
-  
-  		for (int i = 0; i < dblclickOptions.length; i++) {
-  
-  			dblclickLabels[i] = MessageText.getString(dblclickOptions[i]);
-  			dblclickValues[i] = "" + i;
-  		}
-  		new StringListParameter(cArea, "list.dm.dblclick", dblclickLabels,
-  				dblclickValues);
-    }
-		
-
 		// reset associations
 
-		final PlatformManager platform = PlatformManagerFactory
-				.getPlatformManager();
-
-		if (platform
-				.hasCapability(PlatformManagerCapabilities.RegisterFileAssociations)) {
+		if (platform.hasCapability(PlatformManagerCapabilities.RegisterFileAssociations)) {
 
 			Composite cResetAssoc = new Composite(cArea, SWT.NULL);
 			layout = new GridLayout();
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
index 896a05f..1d5c225 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceAlerts.java
@@ -33,22 +33,19 @@ import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.*;
 
-import org.gudy.azureus2.plugins.ui.config.ConfigSection;
-
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.AEThread;
 import org.gudy.azureus2.core3.util.Constants;
-import org.gudy.azureus2.ui.swt.ImageRepository;
+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.config.*;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
-import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
 
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
-public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
+public class ConfigSectionInterfaceAlerts
+	implements UISWTConfigSection
 {
 	private final static String INTERFACE_PREFIX = "ConfigView.section.interface.";
 
@@ -76,18 +73,15 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 		ImageLoader imageLoader = ImageLoader.getInstance();
 		imageLoader.releaseImage("openFolderButton");
 	}
-	
+
 	public int maxUserMode() {
 		return REQUIRED_MODE;
 	}
 
-
 	public Composite configSectionCreate(final Composite parent) {
 		Image imgOpenFolder = null;
-		if (!Constants.isOSX) {
-			ImageLoader imageLoader = ImageLoader.getInstance();
-			imgOpenFolder = imageLoader.getImage("openFolderButton");			
-		}
+		ImageLoader imageLoader = ImageLoader.getInstance();
+		imgOpenFolder = imageLoader.getImage("openFolderButton");
 
 		GridData gridData;
 		GridLayout layout;
@@ -141,21 +135,10 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 		cArea.setLayout(layout);
 		cArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
-		BooleanParameter d_play_sound = new BooleanParameter(cArea,
-				"Play Download Finished", LBLKEY_PREFIX + "playdownloadfinished");
-
 		// OS X counterpart for alerts (see below for what is disabled)
 		if (Constants.isOSX) {
 			// download info 
 
-			gridData = new GridData();
-			gridData.horizontalSpan = 3;
-			gridData.widthHint = 0;
-			gridData.heightHint = 0;
-			Composite d_filler = new Composite(cArea, SWT.NONE);
-			d_filler.setSize(0, 0);
-			d_filler.setLayoutData(gridData);
-
 			final BooleanParameter d_speechEnabledParameter = new BooleanParameter(
 					cArea, "Play Download Finished Announcement", LBLKEY_PREFIX
 							+ "playdownloadspeech");
@@ -170,110 +153,90 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 
 			d_speechEnabledParameter.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
 					d_speechParameter.getControls()));
-
-			final Label d_speechInfo = new Label(cArea, SWT.NONE);
-			gridData = new GridData();
-			gridData.horizontalSpan = 4;
-			gridData.horizontalIndent = 24;
-			d_speechInfo.setLayoutData(gridData);
-
-			Messages.setLanguageText(d_speechInfo, LBLKEY_PREFIX
-					+ "playdownloadspeech.info");
 		}
 
-		//Option disabled on OS X, as impossible to make it work correctly
-		if (!Constants.isOSX) {
+		BooleanParameter d_play_sound = new BooleanParameter(cArea,
+				"Play Download Finished", LBLKEY_PREFIX + "playdownloadfinished");
 
-			// download info
+		// download info
 
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
 
-			final StringParameter d_pathParameter = new StringParameter(cArea,
-					"Play Download Finished File", "");
+		final StringParameter d_pathParameter = new StringParameter(cArea,
+				"Play Download Finished File", "");
 
-			if (d_pathParameter.getValue().length() == 0) {
+		if (d_pathParameter.getValue().length() == 0) {
 
-				d_pathParameter.setValue("<default>");
-			}
+			d_pathParameter.setValue("<default>");
+		}
 
-			d_pathParameter.setLayoutData(gridData);
+		d_pathParameter.setLayoutData(gridData);
 
-			Button d_browse = new Button(cArea, SWT.PUSH);
+		Button d_browse = new Button(cArea, SWT.PUSH);
 
-			d_browse.setImage(imgOpenFolder);
+		d_browse.setImage(imgOpenFolder);
 
-			imgOpenFolder.setBackground(d_browse.getBackground());
+		imgOpenFolder.setBackground(d_browse.getBackground());
 
-			d_browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
+		d_browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
 
-			d_browse.addListener(SWT.Selection, new Listener() {
-				public void handleEvent(Event event) {
-					FileDialog dialog = new FileDialog(parent.getShell(),
-							SWT.APPLICATION_MODAL);
-					dialog.setFilterExtensions(new String[] { "*.wav"
-					});
-					dialog.setFilterNames(new String[] { "*.wav"
-					});
+		d_browse.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				FileDialog dialog = new FileDialog(parent.getShell(),
+						SWT.APPLICATION_MODAL);
+				dialog.setFilterExtensions(new String[] {
+					"*.wav"
+				});
+				dialog.setFilterNames(new String[] {
+					"*.wav"
+				});
 
-					dialog.setText(MessageText.getString(INTERFACE_PREFIX + "wavlocation"));
+				dialog.setText(MessageText.getString(INTERFACE_PREFIX + "wavlocation"));
 
-					final String path = dialog.open();
+				final String path = dialog.open();
 
-					if (path != null) {
+				if (path != null) {
 
-						d_pathParameter.setValue(path);
+					d_pathParameter.setValue(path);
 
-						new AEThread("SoundTest") {
-							public void runSupport() {
-								try {
-									Applet.newAudioClip(new File(path).toURL()).play();
+					new AEThread("SoundTest") {
+						public void runSupport() {
+							try {
+								Applet.newAudioClip(new File(path).toURL()).play();
 
-									Thread.sleep(2500);
+								Thread.sleep(2500);
 
-								} catch (Throwable e) {
+							} catch (Throwable e) {
 
-								}
 							}
-						}.start();
-					}
+						}
+					}.start();
 				}
-			});
-
-			Label d_sound_info = new Label(cArea, SWT.WRAP);
-			Messages.setLanguageText(d_sound_info, INTERFACE_PREFIX
-					+ "wavlocation.info");
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
-			gridData.widthHint = 100;
-			d_sound_info.setLayoutData(gridData);
-
-			d_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-					d_pathParameter.getControls()));
-			d_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-					new Control[] {
-						d_browse,
-						d_sound_info
-					}));
+			}
+		});
 
-			// 
-		}
+		Label d_sound_info = new Label(cArea, SWT.WRAP);
+		Messages.setLanguageText(d_sound_info, INTERFACE_PREFIX
+				+ "wavlocation.info");
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.widthHint = 100;
+		d_sound_info.setLayoutData(gridData);
 
-		BooleanParameter f_play_sound = new BooleanParameter(cArea,
-				"Play File Finished", LBLKEY_PREFIX + "playfilefinished");
+		d_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				d_pathParameter.getControls()));
+		d_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				new Control[] {
+					d_browse,
+					d_sound_info
+				}));
 
-		// OS X counterpart for alerts (see below for what is disabled)
+		// 
 
+		// OS X counterpart for alerts
 		if (Constants.isOSX) {
 
 			// per-file info
 
-			gridData = new GridData();
-			gridData.horizontalSpan = 3;
-			gridData.widthHint = 0;
-			gridData.heightHint = 0;
-			Composite f_filler = new Composite(cArea, SWT.NONE);
-			f_filler.setSize(0, 0);
-			f_filler.setLayoutData(gridData);
-
 			final BooleanParameter f_speechEnabledParameter = new BooleanParameter(
 					cArea, "Play File Finished Announcement", LBLKEY_PREFIX
 							+ "playfilespeech");
@@ -288,90 +251,82 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 
 			f_speechEnabledParameter.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
 					f_speechParameter.getControls()));
-
-			final Label speechInfo = new Label(cArea, SWT.NONE);
-			gridData = new GridData();
-			gridData.horizontalSpan = 4;
-			gridData.horizontalIndent = 24;
-			speechInfo.setLayoutData(gridData);
-
-			Messages.setLanguageText(speechInfo, LBLKEY_PREFIX
-					+ "playfilespeech.info");
 		}
 
-		//Option disabled on OS X, as impossible to make it work correctly
-		if (!Constants.isOSX) {
+		BooleanParameter f_play_sound = new BooleanParameter(cArea,
+				"Play File Finished", LBLKEY_PREFIX + "playfilefinished");
 
-			// file info
+		// file info
 
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
 
-			final StringParameter f_pathParameter = new StringParameter(cArea,
-					"Play File Finished File", "");
+		final StringParameter f_pathParameter = new StringParameter(cArea,
+				"Play File Finished File", "");
 
-			if (f_pathParameter.getValue().length() == 0) {
+		if (f_pathParameter.getValue().length() == 0) {
 
-				f_pathParameter.setValue("<default>");
-			}
+			f_pathParameter.setValue("<default>");
+		}
 
-			f_pathParameter.setLayoutData(gridData);
+		f_pathParameter.setLayoutData(gridData);
 
-			Button f_browse = new Button(cArea, SWT.PUSH);
+		Button f_browse = new Button(cArea, SWT.PUSH);
 
-			f_browse.setImage(imgOpenFolder);
+		f_browse.setImage(imgOpenFolder);
 
-			imgOpenFolder.setBackground(f_browse.getBackground());
+		imgOpenFolder.setBackground(f_browse.getBackground());
 
-			f_browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
+		f_browse.setToolTipText(MessageText.getString("ConfigView.button.browse"));
 
-			f_browse.addListener(SWT.Selection, new Listener() {
-				public void handleEvent(Event event) {
-					FileDialog dialog = new FileDialog(parent.getShell(),
-							SWT.APPLICATION_MODAL);
-					dialog.setFilterExtensions(new String[] { "*.wav"
-					});
-					dialog.setFilterNames(new String[] { "*.wav"
-					});
+		f_browse.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				FileDialog dialog = new FileDialog(parent.getShell(),
+						SWT.APPLICATION_MODAL);
+				dialog.setFilterExtensions(new String[] {
+					"*.wav"
+				});
+				dialog.setFilterNames(new String[] {
+					"*.wav"
+				});
 
-					dialog.setText(MessageText.getString(INTERFACE_PREFIX + "wavlocation"));
+				dialog.setText(MessageText.getString(INTERFACE_PREFIX + "wavlocation"));
 
-					final String path = dialog.open();
+				final String path = dialog.open();
 
-					if (path != null) {
+				if (path != null) {
 
-						f_pathParameter.setValue(path);
+					f_pathParameter.setValue(path);
 
-						new AEThread("SoundTest") {
-							public void runSupport() {
-								try {
-									Applet.newAudioClip(new File(path).toURL()).play();
+					new AEThread("SoundTest") {
+						public void runSupport() {
+							try {
+								Applet.newAudioClip(new File(path).toURL()).play();
 
-									Thread.sleep(2500);
+								Thread.sleep(2500);
 
-								} catch (Throwable e) {
+							} catch (Throwable e) {
 
-								}
 							}
-						}.start();
-					}
+						}
+					}.start();
 				}
-			});
-
-			Label f_sound_info = new Label(cArea, SWT.WRAP);
-			Messages.setLanguageText(f_sound_info, INTERFACE_PREFIX
-					+ "wavlocation.info");
-			gridData = new GridData(GridData.FILL_HORIZONTAL);
-			gridData.widthHint = 100;
-			f_sound_info.setLayoutData(gridData);
-
-			f_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-					f_pathParameter.getControls()));
-			f_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-					new Control[] {
-						f_browse,
-						f_sound_info
-					}));
-		}
+			}
+		});
+
+		Label f_sound_info = new Label(cArea, SWT.WRAP);
+		Messages.setLanguageText(f_sound_info, INTERFACE_PREFIX
+				+ "wavlocation.info");
+		gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.widthHint = 100;
+		f_sound_info.setLayoutData(gridData);
+
+		f_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				f_pathParameter.getControls()));
+		f_play_sound.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
+				new Control[] {
+					f_browse,
+					f_sound_info
+				}));
 
 		cArea = new Composite(cSection, SWT.NULL);
 		layout = new GridLayout();
@@ -386,7 +341,7 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 		gridData = new GridData();
 		gridData.horizontalSpan = 2;
 		popup_dl_added.setLayoutData(gridData);
-		
+
 		BooleanParameter popup_dl_completed = new BooleanParameter(cArea,
 				"Popup Download Finished", LBLKEY_PREFIX + "popupdownloadfinished");
 		gridData = new GridData();
@@ -415,42 +370,12 @@ public class ConfigSectionInterfaceAlerts implements UISWTConfigSection
 		// Auto-hide popup setting.
 		Label label = new Label(cArea, SWT.WRAP);
 		Messages.setLanguageText(label, LBLKEY_PREFIX + "popup.autohide");
-		label.setLayoutData(Utils.getWrappableLabelGridData(1, 0));
+		label.setLayoutData(new GridData());
 		IntParameter auto_hide_alert = new IntParameter(cArea,
 				"Message Popup Autoclose in Seconds", 0, 86400);
 		gridData = new GridData();
 		gridData.horizontalSpan = 1;
 		auto_hide_alert.setLayoutData(gridData);
-		
-		// Use popup boxes rather than Mr Slidey.
-		BooleanParameter use_popup_boxes = new BooleanParameter(cArea,
-				"Use Message Box For Popups", LBLKEY_PREFIX + "popup.use_message_boxes");
-		gridData = new GridData();
-		gridData.horizontalSpan = 2;
-		use_popup_boxes.setLayoutData(gridData);
-		
-		// Suppress alerts.
-		BooleanParameter suppress_alerts = new BooleanParameter(cArea,
-				"Suppress Alerts", LBLKEY_PREFIX + "popup.suppress_alerts");
-		gridData = new GridData();
-		gridData.horizontalSpan = 2;
-		suppress_alerts.setLayoutData(gridData);
-		
-		// Show alerts.
-		label = new Label(cArea, SWT.NULL);
-		Messages.setLanguageText(label, LBLKEY_PREFIX + "popup.show");
-		ButtonParameter show_alerts = new ButtonParameter(cArea, LBLKEY_PREFIX + "popup.show.button");
-		show_alerts.addChangeListener(new ParameterChangeAdapter() {
-			public void parameterChanged(Parameter p, boolean b) {
-				Display display = parent.getDisplay();
-				if (display.isDisposed()) {return;}
-				MessageSlideShell.displayLastMessage(display, true);
-			}
-		});
-		gridData = new GridData();
-		gridData.horizontalSpan = 1;
-		gridData.widthHint = 60;
-		show_alerts.setLayoutData(gridData);
 
 		return cSection;
 	}
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceColor.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceColor.java
index 46b9eee..ea163ab 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceColor.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceColor.java
@@ -32,6 +32,7 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 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.config.ColorParameter;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
@@ -101,6 +102,9 @@ public class ConfigSectionInterfaceColor implements UISWTConfigSection {
 		cColorOverride.setLayoutData(gridData);
 
 		for (int i = 0; i < sColorsToOverride.length; i++) {
+			if (Utils.TABLE_GRIDLINE_IS_ALTERNATING_COLOR && sColorsToOverride[i].equals("altRow")) {
+				continue;
+			}
 			String sConfigID = "Colors." + sColorsToOverride[i];
 			label = new Label(cColorOverride, SWT.NULL);
 			Messages.setLanguageText(label, "ConfigView.section.style.colorOverride."
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
index 651f943..dd6ca57 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceDisplay.java
@@ -38,16 +38,13 @@ import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.platform.PlatformManagerCapabilities;
 import org.gudy.azureus2.platform.PlatformManagerFactory;
+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.config.*;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
 
-import org.gudy.azureus2.plugins.ui.config.ConfigSection;
-
 public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 	private final static String MSG_PREFIX = "ConfigView.section.style.";
-	private final static String LBLKEY_PREFIX = "ConfigView.label.";
 
 	public String configSectionGetParentSection() {
 		return ConfigSection.SECTION_INTERFACE;
@@ -79,44 +76,41 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 		Label label;
 		GridLayout layout;
 		GridData gridData;
-		Composite cLook = new Composite(parent, SWT.NULL);
-		cLook.setLayoutData(new GridData(GridData.FILL_BOTH));
+		Composite cSection = new Composite(parent, SWT.NULL);
+		cSection.setLayoutData(new GridData(GridData.FILL_BOTH));
 		layout = new GridLayout();
 		layout.numColumns = 1;
-		cLook.setLayout(layout);
+		cSection.setLayout(layout);
 
-		new BooleanParameter(cLook, "Show Download Basket", MSG_PREFIX
+		new BooleanParameter(cSection, "Show Download Basket", MSG_PREFIX
 				+ "showdownloadbasket");
 
 		if (!isAZ3) {
-  		new BooleanParameter(cLook, "IconBar.enabled", MSG_PREFIX
+  		new BooleanParameter(cSection, "IconBar.enabled", MSG_PREFIX
   				+ "showiconbar");
 		}
 
-		Composite cStatusBar = new Composite(cLook, SWT.NULL);
+		Group cStatusBar = new Group(cSection, SWT.NULL);
+		Messages.setLanguageText(cStatusBar, MSG_PREFIX + "status");
 		layout = new GridLayout();
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		layout.numColumns = 5;
+		layout.numColumns = 1;
 		cStatusBar.setLayout(layout);
 		cStatusBar.setLayoutData(new GridData());
 
-		label = new Label(cStatusBar, SWT.NULL);
-		Messages.setLanguageText(label, MSG_PREFIX + "status");
 		new BooleanParameter(cStatusBar, "Status Area Show SR", MSG_PREFIX	+ "status.show_sr");
 		new BooleanParameter(cStatusBar, "Status Area Show NAT",  MSG_PREFIX + "status.show_nat");
 		new BooleanParameter(cStatusBar, "Status Area Show DDB", MSG_PREFIX + "status.show_ddb");
 		new BooleanParameter(cStatusBar, "Status Area Show IPF", MSG_PREFIX + "status.show_ipf");
+		new BooleanParameter(cStatusBar, "status.rategraphs", MSG_PREFIX + "status.show_rategraphs");
 		
-		new BooleanParameter(cLook, "Add URL Silently", MSG_PREFIX	+ "addurlsilently");
-		new BooleanParameter(cLook, "add_torrents_silently", "ConfigView.section.interface.display.add_torrents_silently");
+		new BooleanParameter(cSection, "Add URL Silently", MSG_PREFIX	+ "addurlsilently");
 
-		new BooleanParameter(cLook, "suppress_file_download_dialog", "ConfigView.section.interface.display.suppress.file.download.dialog");
+		new BooleanParameter(cSection, "suppress_file_download_dialog", "ConfigView.section.interface.display.suppress.file.download.dialog");
 
-		new BooleanParameter(cLook, "show_torrents_menu", "Menu.show.torrent.menu");
+		new BooleanParameter(cSection, "show_torrents_menu", "Menu.show.torrent.menu");
 
 		if (Constants.isWindowsXP) {
-			final Button enableXPStyle = new Button(cLook, SWT.CHECK);
+			final Button enableXPStyle = new Button(cSection, SWT.CHECK);
 			Messages.setLanguageText(enableXPStyle, MSG_PREFIX + "enableXPStyle");
 
 			boolean enabled = false;
@@ -165,33 +159,40 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 		}
 
 		if (Constants.isOSX) {
-			new BooleanParameter(cLook, "enable_small_osx_fonts", MSG_PREFIX
+			new BooleanParameter(cSection, "enable_small_osx_fonts", MSG_PREFIX
 					+ "osx_small_fonts");
 		}
 
-		if (userMode > 1) {
-  		new BooleanParameter(cLook, "GUI_SWT_bAlternateTablePainting", MSG_PREFIX
-  				+ "alternateTablePainting");
-		}
+		if (userMode > 0) {
+			Group cUnits = new Group(cSection, SWT.NULL);
+			Messages.setLanguageText(cUnits, MSG_PREFIX + "units");
+			layout = new GridLayout();
+			layout.numColumns = 1;
+			cUnits.setLayout(layout);
+			cUnits.setLayoutData(new GridData());
 
-	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.separateProtDataStats", MSG_PREFIX + "separateProtDataStats");
-	}
-		
+			new BooleanParameter(cUnits, "config.style.useSIUnits", MSG_PREFIX
+					+ "useSIUnits");
+
+			new BooleanParameter(cUnits, "config.style.forceSIValues", MSG_PREFIX
+					+ "forceSIValues");
+
+			new BooleanParameter(cUnits, "config.style.useUnitsRateBits", MSG_PREFIX
+					+ "useUnitsRateBits");
+
+			new BooleanParameter(cUnits, "config.style.doNotUseGB", MSG_PREFIX
+					+ "doNotUseGB");
+
+			new BooleanParameter(cUnits, "config.style.dataStatsOnly", MSG_PREFIX
+					+ "dataStatsOnly");
+
+			new BooleanParameter(cUnits, "config.style.separateProtDataStats",
+					MSG_PREFIX + "separateProtDataStats");
+		}
 		
     if( userMode > 1 ) {
-  		final BooleanParameter fMoz = new BooleanParameter(cLook, "swt.forceMozilla",MSG_PREFIX + "forceMozilla");
-  		Composite pArea = new Composite(cLook,SWT.NULL);
+  		final BooleanParameter fMoz = new BooleanParameter(cSection, "swt.forceMozilla",MSG_PREFIX + "forceMozilla");
+  		Composite pArea = new Composite(cSection,SWT.NULL);
   		pArea.setLayout(new GridLayout(3,false));
   		pArea.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
   		Messages.setLanguageText(new Label(pArea,SWT.NONE), MSG_PREFIX+"xulRunnerPath");
@@ -199,7 +200,7 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
   		fMoz.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(xulDir.getControls(), false));
     }
 		
-		Composite cArea = new Composite(cLook, SWT.NULL);
+		Composite cArea = new Composite(cSection, SWT.NULL);
 		layout = new GridLayout();
 		layout.marginHeight = 0;
 		layout.marginWidth = 0;
@@ -225,33 +226,10 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 		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();
-		IntParameter reorderDelay = new IntParameter(cArea, "ReOrder Delay");
-		reorderDelay.setLayoutData(gridData);
-
-		label = new Label(cArea, SWT.NULL);
-		Messages.setLanguageText(label, MSG_PREFIX + "defaultSortOrder");
-		int[] sortOrderValues = { 0, 1, 2 };
-		String[] sortOrderLabels = {
-				MessageText.getString(MSG_PREFIX + "defaultSortOrder.asc"),
-				MessageText.getString(MSG_PREFIX + "defaultSortOrder.desc"),
-				MessageText.getString(MSG_PREFIX + "defaultSortOrder.flip") };
-		new IntListParameter(cArea, "config.style.table.defaultSortOrder",
-				sortOrderLabels, sortOrderValues);
-		
-		new BooleanParameter(cLook, "NameColumn.showProgramIcon", MSG_PREFIX
-				+ "showProgramIcon");
-
-		new BooleanParameter(cLook, "DND Always In Incomplete", MSG_PREFIX
-				+ "DNDalwaysInIncomplete");
-		
-		new BooleanParameter(cLook, "MyTorrentsView.alwaysShowHeader", "ConfigView.label.alwaysShowLibraryHeader");
 		
 		// Reuse the labels of the other menu actions.
 		if (PlatformManagerFactory.getPlatformManager().hasCapability(PlatformManagerCapabilities.ShowFileInBrowser)) {
-			BooleanParameter bp = new BooleanParameter(cLook, "MyTorrentsView.menu.show_parent_folder_enabled", MSG_PREFIX
+			BooleanParameter bp = new BooleanParameter(cSection, "MyTorrentsView.menu.show_parent_folder_enabled", MSG_PREFIX
 					+ "use_show_parent_folder");
 			Messages.setLanguageText(bp.getControl(), "ConfigView.section.style.use_show_parent_folder", new String[] {
 				MessageText.getString("MyTorrentsView.menu.open_parent_folder"),
@@ -259,14 +237,14 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 			});
 			
 			if (Constants.isOSX) {
-				new BooleanParameter(cLook, "FileBrowse.usePathFinder", 
+				new BooleanParameter(cSection, "FileBrowse.usePathFinder", 
 						MSG_PREFIX + "usePathFinder");
 			}
 		}
 		
 		if ( Constants.isOSX_10_5_OrHigher ){
 			
-			Composite cSWT = new Composite(cLook, SWT.NULL);
+			Composite cSWT = new Composite(cSection, SWT.NULL);
 			layout = new GridLayout();
 			layout.marginHeight = 0;
 			layout.marginWidth = 0;
@@ -281,6 +259,6 @@ public class ConfigSectionInterfaceDisplay implements UISWTConfigSection {
 			new StringListParameter(cSWT, MSG_PREFIX + "swt.library.selection", swtLibraries, swtLibraries);
 		}
 		
-		return cLook;
+		return cSection;
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
index 4506952..bc5b76d 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceStart.java
@@ -84,12 +84,6 @@ public class ConfigSectionInterfaceStart implements UISWTConfigSection {
 				new Control[] { openDialog.getControl() }, true ));
     
     new Label(cStart,SWT.NULL);
-    if (!isAZ3) {
-      new BooleanParameter(cStart, "Open MyTorrents", "ConfigView.label.openmytorrents");
-      new BooleanParameter(cStart, "Open Console", "ConfigView.label.openconsole");
-      new BooleanParameter(cStart, "Open Stats On Start", "ConfigView.label.openstatsonstart");
-      new BooleanParameter(cStart, "Open Config", "ConfigView.label.openconfig");
-    }
     new BooleanParameter(cStart, "Open Transfer Bar On Start", "ConfigView.label.open_transfer_bar_on_start");
     new BooleanParameter(cStart, "Start Minimized", "ConfigView.label.startminimized");
     
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceTables.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceTables.java
new file mode 100644
index 0000000..cb4e023
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionInterfaceTables.java
@@ -0,0 +1,382 @@
+/*
+ * File    : ConfigPanel*.java
+ * Created : 11 mar. 2004
+ * By      : TuxPaper
+ * 
+ * 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.configsections;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+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.config.ParameterListener;
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.util.Constants;
+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.config.*;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
+
+public class ConfigSectionInterfaceTables
+	implements UISWTConfigSection
+{
+	private final static String MSG_PREFIX = "ConfigView.section.style.";
+
+	public String configSectionGetParentSection() {
+		return ConfigSection.SECTION_INTERFACE;
+	}
+
+	public String configSectionGetName() {
+		return "tables";
+	}
+
+	public void configSectionSave() {
+	}
+
+	public void configSectionDelete() {
+	}
+
+	public int maxUserMode() {
+		return 2;
+	}
+
+	public Composite configSectionCreate(final Composite parent) {
+		int userMode = COConfigurationManager.getIntParameter("User Mode");
+		boolean isAZ3 = COConfigurationManager.getStringParameter("ui").equals(
+				"az3");
+
+		// "Display" Sub-Section:
+		// ----------------------
+		// Any Look & Feel settings that don't really change the way the user 
+		// normally interacts
+		Label label;
+		GridLayout layout;
+		GridData gridData;
+		Composite cSection = new Composite(parent, SWT.NULL);
+		cSection.setLayoutData(new GridData(GridData.FILL_BOTH));
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		cSection.setLayout(layout);
+
+		label = new Label(cSection, SWT.NULL);
+		Messages.setLanguageText(label, MSG_PREFIX + "defaultSortOrder");
+		int[] sortOrderValues = {
+			0,
+			1,
+			2
+		};
+		String[] sortOrderLabels = {
+			MessageText.getString(MSG_PREFIX + "defaultSortOrder.asc"),
+			MessageText.getString(MSG_PREFIX + "defaultSortOrder.desc"),
+			MessageText.getString(MSG_PREFIX + "defaultSortOrder.flip")
+		};
+		new IntListParameter(cSection, "config.style.table.defaultSortOrder",
+				sortOrderLabels, sortOrderValues);
+
+		if (userMode > 0) {
+			label = new Label(cSection, SWT.NULL);
+			Messages.setLanguageText(label, MSG_PREFIX + "guiUpdate");
+			int[] values = {
+				100,
+				250,
+				500,
+				1000,
+				2000,
+				5000,
+				10000,
+				15000
+			};
+			String[] labels = {
+				"100 ms",
+				"250 ms",
+				"500 ms",
+				"1 s",
+				"2 s",
+				"5 s",
+				"10 s",
+				"15 s"
+			};
+			new IntListParameter(cSection, "GUI Refresh", 1000, labels, values);
+
+			label = new Label(cSection, SWT.NULL);
+			Messages.setLanguageText(label, MSG_PREFIX + "graphicsUpdate");
+			gridData = new GridData();
+			IntParameter graphicUpdate = new IntParameter(cSection, "Graphics Update",
+					1, -1);
+			graphicUpdate.setLayoutData(gridData);
+
+			label = new Label(cSection, SWT.NULL);
+			Messages.setLanguageText(label, MSG_PREFIX + "reOrderDelay");
+			gridData = new GridData();
+			IntParameter reorderDelay = new IntParameter(cSection, "ReOrder Delay");
+			reorderDelay.setLayoutData(gridData);
+
+			new BooleanParameter(cSection, "NameColumn.showProgramIcon", MSG_PREFIX
+					+ "showProgramIcon").setLayoutData(new GridData(SWT.FILL, SWT.LEFT, true, false, 2, 1));
+
+			////
+
+			new BooleanParameter(cSection, "Table.extendedErase", MSG_PREFIX
+					+ "extendedErase").setLayoutData(new GridData(SWT.FILL, SWT.LEFT,
+					true, false, 2, 1));
+
+			////
+			
+			boolean hhEnabled = COConfigurationManager.getIntParameter("Table.headerHeight") > 0;
+
+			Button chkHeaderHeight = new Button(cSection, SWT.CHECK);
+			Messages.setLanguageText(chkHeaderHeight, MSG_PREFIX + "enableHeaderHeight");
+			chkHeaderHeight.setSelection(hhEnabled);
+			
+			final IntParameter paramHH = new IntParameter(cSection, "Table.headerHeight", 0, 100);
+			paramHH.setEnabled(hhEnabled);
+			
+			chkHeaderHeight.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					if (((Button) e.widget).getSelection()) {
+						COConfigurationManager.setParameter("Table.headerHeight", 16);
+						paramHH.setEnabled(true);
+					} else {
+						COConfigurationManager.setParameter("Table.headerHeight", 0);
+						paramHH.setEnabled(false);
+					}
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+			
+			/////
+
+			boolean cdEnabled = COConfigurationManager.getStringParameter("Table.column.dateformat", "").length() > 0;
+
+			Button chkCustomDate = new Button(cSection, SWT.CHECK);
+			Messages.setLanguageText(chkCustomDate, MSG_PREFIX + "customDateFormat");
+			chkCustomDate.setSelection(cdEnabled);
+			
+			final StringParameter paramCustomDate = new StringParameter(cSection, "Table.column.dateformat", "");
+			paramCustomDate.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+			paramCustomDate.setEnabled(cdEnabled);
+			paramCustomDate.addChangeListener(new ParameterChangeAdapter() {
+				
+				public void parameterChanged(Parameter p, boolean caused_internally) {
+					String s = (String) p.getValueObject();
+					boolean ok = false;
+					try {
+						SimpleDateFormat temp = new SimpleDateFormat(s);
+						temp.format(new Date());
+						ok = true;
+					} catch (Exception e) {
+						// probably illegalargumentexception
+					}
+					p.getControl().setBackground(ok ? null : Colors.colorErrorBG);
+				}
+				
+			});
+			
+			chkCustomDate.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					if (((Button) e.widget).getSelection()) {
+						COConfigurationManager.setParameter("Table.column.dateformat", "yyyy/MM/dd");
+						paramCustomDate.setEnabled(true);
+					} else {
+						COConfigurationManager.setParameter("Table.column.dateformat", "");
+						paramCustomDate.setEnabled(false);
+					}
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+		}
+
+		{
+			Group cLibrary = new Group(cSection, SWT.NULL);
+			Messages.setLanguageText(cLibrary, MSG_PREFIX + "library");
+			layout = new GridLayout();
+			layout.numColumns = 2;
+			cLibrary.setLayout(layout);
+			cLibrary.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 2, 1));
+
+			// double-click
+
+			label = new Label(cLibrary, SWT.NULL);
+			Messages.setLanguageText(label, "ConfigView.label.dm.dblclick");
+
+			String[] dblclickOptions = {
+				"ConfigView.option.dm.dblclick.play",
+				"ConfigView.option.dm.dblclick.details",
+				"ConfigView.option.dm.dblclick.show",
+				"ConfigView.option.dm.dblclick.launch",
+			};
+
+			String dblclickLabels[] = new String[dblclickOptions.length];
+			String dblclickValues[] = new String[dblclickOptions.length];
+
+			for (int i = 0; i < dblclickOptions.length; i++) {
+
+				dblclickLabels[i] = MessageText.getString(dblclickOptions[i]);
+				dblclickValues[i] = "" + i;
+			}
+			new StringListParameter(cLibrary, "list.dm.dblclick", dblclickLabels,
+					dblclickValues);
+
+				// Launch helpers
+			
+			Group cLaunch = new Group(cLibrary, SWT.NULL);
+			Messages.setLanguageText(cLaunch, MSG_PREFIX + "launch");
+			layout = new GridLayout();
+			layout.numColumns = 5;
+			cLaunch.setLayout(layout);
+			cLaunch.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
+
+		    Label	info_label = new Label( cLaunch, SWT.WRAP );
+		    Messages.setLanguageText( info_label, "ConfigView.label.lh.info" );
+		    gridData = Utils.getWrappableLabelGridData(5, GridData.HORIZONTAL_ALIGN_FILL );
+		    info_label.setLayoutData( gridData );
+		    
+			for ( int i=0;i<3;i++){
+				
+				label = new Label(cLaunch, SWT.NULL);
+				Messages.setLanguageText(label, "ConfigView.label.lh.ext");
+
+				StringParameter exts = new StringParameter(cLaunch, "Table.lh" + i + ".exts", "");
+				gridData = new GridData();
+				gridData.widthHint = 200;
+				exts.setLayoutData( gridData );
+				
+				label = new Label(cLaunch, SWT.NULL);
+				Messages.setLanguageText(label, "ConfigView.label.lh.prog");
+
+				final FileParameter prog = new FileParameter(cLaunch, "Table.lh" + i + ".prog", "", new String[0]);
+
+				gridData = new GridData();
+				gridData.widthHint = 400;
+				prog.getControls()[0].setLayoutData( gridData );
+				
+				if ( Constants.isOSX ){
+					COConfigurationManager.addParameterListener(
+							"Table.lh" + i + ".prog",
+							new ParameterListener()
+							{		
+								private boolean changing 		= false;
+								private String 	last_changed	= "";
+								
+								public void 
+								parameterChanged(
+									String parameter_name)
+								{
+									if ( prog.isDisposed()){
+										
+										COConfigurationManager.removeParameterListener(	parameter_name, this );
+										
+									}else if ( changing ){
+										
+										return;
+										
+									}else{
+										
+										final String value = COConfigurationManager.getStringParameter( parameter_name );
+										
+										if ( value.equals( last_changed )){
+											
+											return;
+										}
+										
+										if ( value.endsWith( ".app" )){
+											
+											Utils.execSWTThreadLater( 
+												1,
+												new Runnable()
+												{
+													public void 
+													run()
+													{
+														last_changed = value;
+														
+														try{
+															changing = true;
+															
+															File file = new File( value );
+																
+															String app_name = file.getName();
+				
+															int pos = app_name.lastIndexOf( "." );
+															
+															app_name = app_name.substring( 0,pos );
+															
+															String new_value = value + "/Contents/MacOS/" + app_name;
+															
+															if ( new File( new_value ).exists()){
+															
+																prog.setValue( new_value );
+															}
+														}finally{
+															
+															changing = false;
+														}
+													}
+												});
+										}
+									}
+								}
+							});
+				}
+			}
+			
+			
+				// User tree
+			
+			new BooleanParameter(cLibrary, "Table.useTree", MSG_PREFIX
+					+ "useTree").setLayoutData(new GridData(SWT.FILL,
+							SWT.LEFT, true, false, 2, 1));
+
+			if (userMode > 1) {
+				new BooleanParameter(cLibrary, "DND Always In Incomplete", MSG_PREFIX
+						+ "DNDalwaysInIncomplete").setLayoutData(new GridData(SWT.FILL,
+								SWT.LEFT, true, false, 2, 1));
+			}
+
+			new BooleanParameter(cLibrary, "MyTorrentsView.alwaysShowHeader",
+					"ConfigView.label.alwaysShowLibraryHeader").setLayoutData(new GridData(
+							SWT.FILL, SWT.LEFT, true, false, 2, 1));
+
+			if (isAZ3) {
+				new BooleanParameter(cLibrary, "Library.CatInSideBar", MSG_PREFIX
+						+ "CatInSidebar").setLayoutData(new GridData(SWT.FILL,
+								SWT.LEFT, true, false, 2, 1));
+			}
+		}
+
+		return cSection;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionLogging.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionLogging.java
index 7d58b47..7533639 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionLogging.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionLogging.java
@@ -53,11 +53,18 @@ import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
 
+import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
 import com.aelitis.azureus.core.stats.AzureusCoreStats;
 import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.PluginManager;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
+import org.gudy.azureus2.plugins.update.UpdateException;
+import org.gudy.azureus2.plugins.update.UpdateInstaller;
+import org.gudy.azureus2.plugins.update.UpdateInstallerListener;
+import org.gudy.azureus2.plugins.utils.StaticUtilities;
 
 public class ConfigSectionLogging implements UISWTConfigSection {
   private static final LogIDs LOGID = LogIDs.GUI;
@@ -418,6 +425,61 @@ public class ConfigSectionLogging implements UISWTConfigSection {
 				}
 			});
 	
+	if ( false ){
+		Button test_button = new Button(gLogging, SWT.PUSH);
+	
+		test_button.setText( "Test" );
+	
+		test_button.addListener(
+				SWT.Selection, 
+				new Listener() 
+				{
+					public void 
+					handleEvent(Event event) 
+					{
+						try{
+							PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getDefaultPluginInterface();
+							
+							UpdateInstaller installer = pi.getUpdateManager().createInstaller();
+						
+							installer.addMoveAction(
+								"C:\\temp\\file1", "C:\\temp\\file2" );
+						
+							installer.installNow(
+								new UpdateInstallerListener()
+								{
+									public void
+									reportProgress(
+										String		str )
+									{
+										System.out.println( str );
+									}
+									
+									public void
+									complete()
+									{
+										System.out.println( "complete" );
+									}
+									
+									public void
+									failed(
+										UpdateException	e )
+									{
+										System.out.println( "failed" );
+										
+										e.printStackTrace();
+										
+									}
+								});
+							
+						}catch( Throwable e ){
+							
+							e.printStackTrace();
+						}
+					}
+				});
+	}
+	
     return gLogging;
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionMode.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionMode.java
index 52dabc1..7490a15 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionMode.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionMode.java
@@ -41,13 +41,15 @@ import org.eclipse.swt.widgets.Listener;
 
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 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 org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
 
+import com.aelitis.azureus.ui.UserPrompterResultListener;
+
 
 
 public class ConfigSectionMode implements UISWTConfigSection {
@@ -81,10 +83,10 @@ public class ConfigSectionMode implements UISWTConfigSection {
     		"ConfigView.section.mode.advanced.wiki.main",
     		"ConfigView.section.mode.intermediate.wiki.publish"
     };
-    final String[] links = {"http://www.azureuswiki.com/index.php/This_funny_word",
-    		"http://www.azureuswiki.com/index.php/HostingFiles",
-    		"http://www.azureuswiki.com/index.php/Main_Page",
-    		"http://www.azureuswiki.com/index.php/PublishingFiles"
+    final String[] links = {"http://wiki.vuze.com/w/This_funny_word",
+    		"http://wiki.vuze.com/w/HostingFiles",
+    		"http://wiki.vuze.com/w/Main_Page",
+    		"http://wiki.vuze.com/w/PublishingFiles"
     };
     
     int userMode = COConfigurationManager.getIntParameter("User Mode");
@@ -157,7 +159,7 @@ public class ConfigSectionMode implements UISWTConfigSection {
 	    final Label linkLabel = new Label(gWiki, SWT.NULL);
 	    linkLabel.setText( MessageText.getString( messTexts[userMode] ) );
 	    linkLabel.setData( links[userMode] );
-	    linkLabel.setCursor(Cursors.handCursor);
+	    linkLabel.setCursor(linkLabel.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 	    linkLabel.setForeground(Colors.blue);
 	    gridData = new GridData(GridData.FILL_HORIZONTAL);
 	    gridData.horizontalIndent = 10;
@@ -174,7 +176,7 @@ public class ConfigSectionMode implements UISWTConfigSection {
 	    final Label linkLabel1 = new Label(gWiki, SWT.NULL);
 	    linkLabel1.setText( (userMode == 1)?MessageText.getString(messTexts[3]):"");
 	    linkLabel1.setData( links[3] );
-	    linkLabel1.setCursor(Cursors.handCursor);
+	    linkLabel1.setCursor(linkLabel1.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 	    linkLabel1.setForeground(Colors.blue);
 	    gridData = new GridData(GridData.FILL_HORIZONTAL);
 	    gridData.horizontalIndent = 10;
@@ -224,6 +226,64 @@ public class ConfigSectionMode implements UISWTConfigSection {
     button1.addListener (SWT.Selection, radioGroup);
     button2.addListener (SWT.Selection, radioGroup);
 
+    Label padding = new Label(cMode, SWT.NULL );
+    gridData = new GridData();
+    gridData.horizontalSpan = 3;
+    padding.setLayoutData( gridData );
+    
+    	// reset to defaults
+    
+	Composite gReset = new Composite(cMode, SWT.WRAP);
+    gridData = new GridData();
+    gridData.horizontalSpan = 4;
+    gReset.setLayoutData(gridData);
+    layout = new GridLayout();
+    layout.numColumns = 3;
+    gReset.setLayout(layout);
+
+    Label reset_label = new Label(gReset, SWT.NULL );
+    Messages.setLanguageText(reset_label, "ConfigView.section.mode.resetdefaults" );
+    
+    Button reset_button = new Button(gReset, SWT.PUSH);
+
+    Messages.setLanguageText(reset_button, "Button.reset" );
+
+    reset_button.addListener(SWT.Selection, 
+		new Listener() 
+		{
+	        public void 
+			handleEvent(Event event) 
+	        {
+	        	MessageBoxShell mb = new MessageBoxShell(
+	        			SWT.ICON_WARNING | SWT.OK | SWT.CANCEL,
+	        			MessageText.getString("resetconfig.warn.title"),
+	        			MessageText.getString("resetconfig.warn"));
+	        	
+	        	mb.setDefaultButtonUsingStyle(SWT.CANCEL);
+	        	
+	        	mb.setParent(parent.getShell());
+
+	        	mb.open(
+	        		new UserPrompterResultListener() 
+	        		{
+	        			public void 
+	        			prompterClosed(
+	        				int returnVal ) 
+	        			{
+							if (returnVal != SWT.OK) {
+								return;
+							}
+
+							COConfigurationManager.resetToDefaults();
+	        			}
+	        		});
+	        }
+	    });
+    
+    padding = new Label(gReset, SWT.NULL );
+    gridData = new GridData();
+    padding.setLayoutData( gridData );
+    
     return cMode;
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
index 9490a27..2db29da 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionPlugins.java
@@ -37,7 +37,11 @@ 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.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
 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.Debug;
 import org.gudy.azureus2.core3.util.FileUtil;
 import org.gudy.azureus2.ui.swt.Messages;
@@ -46,8 +50,8 @@ import org.gudy.azureus2.ui.swt.config.DualChangeSelectionActionPerformer;
 import org.gudy.azureus2.ui.swt.config.IAdditionalActionPerformer;
 import org.gudy.azureus2.ui.swt.config.plugins.PluginParameter;
 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.pluginsinstaller.InstallPluginWizard;
 import org.gudy.azureus2.ui.swt.views.ConfigView;
 
 import com.aelitis.azureus.core.AzureusCore;
@@ -59,6 +63,7 @@ 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.installer.PluginInstallationListener;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.plugins.ui.config.Parameter;
@@ -359,7 +364,7 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		label.setLayoutData(gridData);
 		label.setText(sUserPluginDir.replaceAll("&", "&&"));
 		label.setForeground(Colors.blue);
-		label.setCursor(Cursors.handCursor);
+		label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 
 		final String _sUserPluginDir = sUserPluginDir;
 
@@ -388,7 +393,7 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		label.setLayoutData(gridData);
 		label.setText(sAppPluginDir.replaceAll("&", "&&"));
 		label.setForeground(Colors.blue);
-		label.setCursor(Cursors.handCursor);
+		label.setCursor(label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 
 		final String _sAppPluginDir = sAppPluginDir;
 
@@ -453,7 +458,7 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		layout = new GridLayout();
 		layout.marginHeight = 0;
 		layout.marginWidth = 0;
-		layout.numColumns = 3;
+		layout.numColumns = 5;
 		cButtons.setLayout(layout);
 		cButtons.setLayoutData(new GridData());
 		
@@ -462,27 +467,43 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		Messages.setLanguageText(btnUnload, "ConfigView.pluginlist.unloadSelected");
 		btnUnload.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
-				int[] items = table.getSelectionIndices();
-				for (int i = 0; i < items.length; i++) {
-					int index = items[i];
-					if (index >= 0 && index < pluginIFs.size()) {
-						PluginInterface pluginIF = (PluginInterface) pluginIFs.get(index);
-						if (pluginIF.getPluginState().isOperational()) {
-							if (pluginIF.getPluginState().isUnloadable()) {
-								try {
-									pluginIF.getPluginState().unload();
-								} catch (PluginException e1) {
-									// TODO Auto-generated catch block
-									e1.printStackTrace();
+				final int[] items = table.getSelectionIndices();
+
+				new AEThread2( "unload" ){
+					public void
+					run()
+					{
+						for (int i = 0; i < items.length; i++) {
+							int index = items[i];
+							if (index >= 0 && index < pluginIFs.size()) {
+								PluginInterface pluginIF = (PluginInterface) pluginIFs.get(index);
+								if (pluginIF.getPluginState().isOperational()) {
+									if (pluginIF.getPluginState().isUnloadable()) {
+										try {
+											pluginIF.getPluginState().unload();
+										} catch (PluginException e1) {
+											// TODO Auto-generated catch block
+											e1.printStackTrace();
+										}
+									}
 								}
+								
+								Utils.execSWTThread(
+									new Runnable()
+									{
+										public void
+										run()
+										{
+											pluginIFs = rebuildPluginIFs();
+											table.setItemCount(pluginIFs.size());
+											Collections.sort(pluginIFs, comparator);
+											table.clearAll();
+										}
+									});
 							}
 						}
-						pluginIFs = rebuildPluginIFs();
-						table.setItemCount(pluginIFs.size());
-						Collections.sort(pluginIFs, comparator);
-						table.clearAll();
 					}
-				}
+				}.start();
 			}
 		});
 		btnUnload.setEnabled( false );
@@ -492,38 +513,54 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 		Messages.setLanguageText(btnLoad, "ConfigView.pluginlist.loadSelected");
 		btnLoad.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
-				int[] items = table.getSelectionIndices();
-				for (int i = 0; i < items.length; i++) {
-					int index = items[i];
-					if (index >= 0 && index < pluginIFs.size()) {
-						
-						PluginInterface pluginIF = (PluginInterface) pluginIFs.get(index);
-						if (pluginIF.getPluginState().isOperational()) {continue;} // Already loaded. 
-
-						// Re-enable disabled plugins, as long as they haven't failed on
-						// initialise.
-						if (pluginIF.getPluginState().isDisabled()) {
-							if (pluginIF.getPluginState().hasFailed()) {continue;}
-							pluginIF.getPluginState().setDisabled(false);
-						}
-						
-						try {
-							pluginIF.getPluginState().reload();
-						} catch (PluginException e1) {
-							// TODO Auto-generated catch block
-							Debug.printStackTrace(e1);
+				final int[] items = table.getSelectionIndices();
+
+				new AEThread2( "load" ){
+					public void
+					run()
+					{
+						for (int i = 0; i < items.length; i++) {
+							int index = items[i];
+							if (index >= 0 && index < pluginIFs.size()) {
+								
+								PluginInterface pluginIF = (PluginInterface) pluginIFs.get(index);
+								if (pluginIF.getPluginState().isOperational()) {continue;} // Already loaded. 
+		
+								// Re-enable disabled plugins, as long as they haven't failed on
+								// initialise.
+								if (pluginIF.getPluginState().isDisabled()) {
+									if (pluginIF.getPluginState().hasFailed()) {continue;}
+									pluginIF.getPluginState().setDisabled(false);
+								}
+								
+								try {
+									pluginIF.getPluginState().reload();
+								} catch (PluginException e1) {
+									// TODO Auto-generated catch block
+									Debug.printStackTrace(e1);
+								}
+								
+								Utils.execSWTThread(
+									new Runnable()
+									{
+										public void
+										run()
+										{
+											pluginIFs = rebuildPluginIFs();
+											table.setItemCount(pluginIFs.size());
+											Collections.sort(pluginIFs, comparator);
+											table.clearAll();
+										}
+									});
+							}
 						}
-						
-						pluginIFs = rebuildPluginIFs();
-						table.setItemCount(pluginIFs.size());
-						Collections.sort(pluginIFs, comparator);
-						table.clearAll();
 					}
-				}
+				}.start();
 			}
 		});
 		btnLoad.setEnabled( false );
 		
+			// scan
 		
 		final Button btnScan = new Button(cButtons, SWT.PUSH);
 		btnScan.setLayoutData(new GridData());
@@ -538,7 +575,109 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 			}
 		});
 
+			// uninstall
+		
+		final Button btnUninstall = new Button(cButtons, SWT.PUSH);
+		btnUninstall.setLayoutData(new GridData());
+		Messages.setLanguageText(btnUninstall, "ConfigView.pluginlist.uninstallSelected");
+		btnUninstall.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				
+				btnUninstall.setEnabled( false );
+				
+				final int[] items = table.getSelectionIndices();
+
+				new AEThread2( "uninstall" ){
+					public void
+					run()
+					{
+						try{
+	
+							List<PluginInterface> pis = new ArrayList<PluginInterface>();
+							
+							for (int i = 0; i < items.length; i++) {
+								int index = items[i];
+								if (index >= 0 && index < pluginIFs.size()) {
+									PluginInterface pluginIF = (PluginInterface) pluginIFs.get(index);
+									
+									pis.add( pluginIF );
+								}
+							}
+							
+							if ( pis.size() > 0 ){
+								
+								PluginInterface[]	ps = new PluginInterface[ pis.size()];
+	
+								pis.toArray( ps );
+	
+								try{
+
+									final AESemaphore wait_sem = new AESemaphore( "unist:wait" );
+									
+									ps[0].getPluginManager().getPluginInstaller().uninstall(
+										ps,
+										new PluginInstallationListener()
+										{
+											public void
+											completed()
+											{
+												wait_sem.release();
+											}
+											
+											public void
+											cancelled()
+											{
+												wait_sem.release();
+											}
+											
+											public void
+											failed(
+												PluginException	e )
+											{
+												wait_sem.release();
+											}
+										});
+	
+									wait_sem.reserve();
+									
+								}catch(Exception e){
+	
+									Debug.printStackTrace(e);
+								}
+							}
+						}finally{	
+							
+							Utils.execSWTThread(
+								new Runnable()
+								{
+									public void
+									run()
+									{
+										pluginIFs = rebuildPluginIFs();
+										table.setItemCount(pluginIFs.size());
+										Collections.sort(pluginIFs, comparator);
+										table.clearAll();
+										table.setSelection(new int[0]);
+									}
+								});
+						}
+					}
+				}.start();
+			}
+		});
+		btnUninstall.setEnabled( false );
 
+			// install
+		
+		final Button btnInstall = new Button(cButtons, SWT.PUSH);
+		btnInstall.setLayoutData(new GridData());
+		btnInstall.setText( MessageText.getString( "UpdateWindow.columns.install" ) + "..." );
+		btnInstall.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				new InstallPluginWizard();
+			}
+		});
+		
 		table.addListener(SWT.SetData, new Listener() {
 			public void handleEvent(Event event) {
 				TableItem item = (TableItem) event.item;
@@ -584,6 +723,7 @@ public class ConfigSectionPlugins implements UISWTConfigSection, ParameterListen
 				
 				btnUnload.setEnabled(pluginIF.getPluginState().isOperational() && pluginIF.getPluginState().isUnloadable()); 
 				btnLoad.setEnabled(!pluginIF.getPluginState().isOperational() && !pluginIF.getPluginState().hasFailed());
+				btnUninstall.setEnabled(! (pluginIF.getPluginState().isBuiltIn()||pluginIF.getPluginState().isMandatory()));
 			}
 		});
 
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
index 4fbf1ee..624c21f 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionSecurity.java
@@ -45,7 +45,6 @@ import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.auth.CertificateCreatorWindow;
 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;
 
@@ -218,8 +217,8 @@ ConfigSectionSecurity
 			
 			final Label linkLabel = new Label(crypto_group, SWT.NULL);
 			linkLabel.setText(MessageText.getString("ConfigView.label.please.visit.here"));
-			linkLabel.setData("http://www.azureuswiki.com/index.php?title=Public_Private_Keys");
-			linkLabel.setCursor(Cursors.handCursor);
+			linkLabel.setData("http://wiki.vuze.com/w/Public_Private_Keys");
+			linkLabel.setCursor(linkLabel.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 			linkLabel.setForeground(Colors.blue);
 			gridData = new GridData();
 			gridData.horizontalSpan = 3;
@@ -255,7 +254,7 @@ ConfigSectionSecurity
 			
 		    Messages.setLanguageText(public_key_value, "ConfigView.copy.to.clipboard.tooltip", true);
 
-		    public_key_value.setCursor(Cursors.handCursor);
+		    public_key_value.setCursor(public_key_value.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
 		    public_key_value.setForeground(Colors.blue);
 		    public_key_value.addMouseListener(new MouseAdapter() {
 		    	public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStartShutdown.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStartShutdown.java
new file mode 100644
index 0000000..53ee6b4
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStartShutdown.java
@@ -0,0 +1,807 @@
+/*
+ * File    : ConfigPanel*.java
+ * Created : 11 mar. 2004
+ * By      : TuxPaper
+ * 
+ * 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.configsections;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+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.core3.util.AEMemoryMonitor;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.platform.PlatformManager;
+import org.gudy.azureus2.platform.PlatformManagerFactory;
+import org.gudy.azureus2.platform.PlatformManagerCapabilities;
+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.components.LinkLabel;
+import org.gudy.azureus2.ui.swt.config.*;
+import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
+import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
+import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ConfigSectionStartShutdown implements UISWTConfigSection {
+
+	private final static String LBLKEY_PREFIX = "ConfigView.label.";
+
+	public String configSectionGetParentSection() {
+		return ConfigSection.SECTION_ROOT;
+	}
+
+	public String configSectionGetName() {
+		return "startstop";
+	}
+
+	public void configSectionSave() {
+	}
+
+	public void configSectionDelete() {
+
+	}
+	
+	public int maxUserMode() {
+		return 1;
+	}
+
+
+	public Composite configSectionCreate(final Composite parent) {
+		GridData gridData;
+		GridLayout layout;
+		Label label;
+
+		final Composite cDisplay = new Composite(parent, SWT.NULL);
+
+		gridData = new GridData(GridData.VERTICAL_ALIGN_FILL
+				| GridData.HORIZONTAL_ALIGN_FILL);
+		cDisplay.setLayoutData(gridData);
+		layout = new GridLayout();
+		layout.numColumns = 1;
+		layout.marginWidth = 0;
+		layout.marginHeight = 0;
+		cDisplay.setLayout(layout);
+
+		final PlatformManager platform = PlatformManagerFactory.getPlatformManager();
+		
+		int userMode = COConfigurationManager.getIntParameter("User Mode");
+		
+			// ***** start group
+		
+		boolean can_ral = platform.hasCapability(PlatformManagerCapabilities.RunAtLogin );
+				
+		if ( can_ral || userMode > 0 ){
+			
+			Group gStartStop = new Group(cDisplay, SWT.NULL);
+			Messages.setLanguageText(gStartStop, LBLKEY_PREFIX + "start");
+			layout = new GridLayout(2, false);
+			gStartStop.setLayout(layout);
+			gStartStop.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+		
+			if ( can_ral ){
+				
+				gridData = new GridData();
+				gridData.horizontalSpan = 2;
+				BooleanParameter start_on_login = new BooleanParameter(gStartStop, "Start On Login", LBLKEY_PREFIX + "start.onlogin");
+				
+				try{
+					start_on_login.setSelected( platform.getRunAtLogin());
+					
+					start_on_login.addChangeListener(
+						new ParameterChangeAdapter()
+						{
+							public void 
+							booleanParameterChanging(
+								Parameter p,
+								boolean toValue) 
+							{
+								try{
+									platform.setRunAtLogin( toValue );
+									
+								}catch( Throwable e ){
+									
+									Debug.out( e );
+								}
+							}
+						});
+					
+				}catch( Throwable e ){
+					
+					start_on_login.setEnabled( false );
+					
+					Debug.out( e );
+				}
+			
+				start_on_login.setLayoutData(gridData);
+			}
+			
+			if ( userMode > 0 ){
+				
+				gridData = new GridData();
+				gridData.horizontalSpan = 2;
+	
+				BooleanParameter start_in_lr_mode = new BooleanParameter(gStartStop, "Start In Low Resource Mode", LBLKEY_PREFIX + "start.inlrm");
+				
+				start_in_lr_mode.setLayoutData(gridData);
+			}
+		}
+		
+		if ( platform.hasCapability( PlatformManagerCapabilities.PreventComputerSleep )){
+			
+			Group gSleep = new Group(cDisplay, SWT.NULL);
+			Messages.setLanguageText(gSleep, LBLKEY_PREFIX + "sleep");
+			layout = new GridLayout(2, false);
+			gSleep.setLayout(layout);
+			gSleep.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+		
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			label = new Label(gSleep, SWT.NULL);
+		    Messages.setLanguageText(label, "ConfigView.label.sleep.info");
+		    label.setLayoutData( gridData );
+
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			BooleanParameter no_sleep_dl = new BooleanParameter(gSleep, "Prevent Sleep Downloading", LBLKEY_PREFIX + "sleep.download");
+			no_sleep_dl.setLayoutData(gridData);
+			
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			BooleanParameter no_sleep_se = new BooleanParameter(gSleep, "Prevent Sleep FP Seeding", LBLKEY_PREFIX + "sleep.fpseed");
+			no_sleep_se.setLayoutData(gridData);
+		}
+		
+		if ( userMode > 0 ){
+				
+			Group gPR = new Group(cDisplay, SWT.NULL);
+			Messages.setLanguageText(gPR, LBLKEY_PREFIX + "pauseresume");
+			layout = new GridLayout(2, false);
+			gPR.setLayout(layout);
+			gPR.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			BooleanParameter pauseOnExit = new BooleanParameter(gPR,
+					"Pause Downloads On Exit", "ConfigView.label.pause.downloads.on.exit");
+			pauseOnExit.setLayoutData(gridData);
+	
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			BooleanParameter resumeOnStart = new BooleanParameter(gPR,
+					"Resume Downloads On Start", "ConfigView.label.resume.downloads.on.start");
+			resumeOnStart.setLayoutData(gridData);
+		}
+		
+		if ( userMode >= 0 ){
+			
+			Group gStop = new Group(cDisplay, SWT.NULL);
+			Messages.setLanguageText(gStop, LBLKEY_PREFIX + "stop");
+			layout = new GridLayout(2, false);
+			gStop.setLayout(layout);
+			gStop.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+
+				// done downloading
+			
+			gridData = new GridData();
+			label = new Label(gStop, SWT.NULL);
+		    Messages.setLanguageText(label, "ConfigView.label.stop.downcomp");
+		    label.setLayoutData( gridData );
+			
+		    int	shutdown_types = platform.getShutdownTypes();
+		    
+			List<String>	l_action_values = new ArrayList<String>();
+			List<String>	l_action_descs 	= new ArrayList<String>();
+
+			l_action_values.add( "Nothing" ); 
+			l_action_values.add( "QuitVuze" );
+			
+			if (( shutdown_types & PlatformManager.SD_SLEEP ) != 0 ){
+				
+				l_action_values.add( "Sleep" );
+			}
+			if (( shutdown_types & PlatformManager.SD_HIBERNATE ) != 0 ){
+				
+				l_action_values.add( "Hibernate" );
+			}
+			if (( shutdown_types & PlatformManager.SD_SHUTDOWN ) != 0 ){
+				
+				l_action_values.add( "Shutdown" );
+			}
+			
+			String[] action_values = l_action_values.toArray( new String[ l_action_values.size()]);
+					
+			for ( String s: action_values ){
+				
+				l_action_descs.add( MessageText.getString( "ConfigView.label.stop." + s ));
+			}
+			
+			String[] action_descs = l_action_descs.toArray( new String[ l_action_descs.size()]);
+
+			new StringListParameter(gStop, "On Downloading Complete Do", "Nothing", action_descs, action_values );
+
+				// done seeding
+			
+			gridData = new GridData();
+		    label = new Label(gStop, SWT.NULL);
+		    Messages.setLanguageText(label, "ConfigView.label.stop.seedcomp");
+		    label.setLayoutData( gridData );
+					    
+			new StringListParameter(gStop, "On Seeding Complete Do", "Nothing", action_descs, action_values );
+			
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			BooleanParameter resetOnTrigger = 
+				new BooleanParameter( 
+					gStop, "Stop Triggers Auto Reset",
+					"!" + MessageText.getString( 
+						"ConfigView.label.stop.autoreset",
+						new String[]{ MessageText.getString( "ConfigView.label.stop.Nothing" )})+ "!");
+				
+			resetOnTrigger.setLayoutData(gridData);
+		}
+		
+		if ( userMode > 0 && platform.hasCapability( PlatformManagerCapabilities.AccessExplicitVMOptions )){
+			
+			Group gJVM = new Group(cDisplay, SWT.NULL);
+			Messages.setLanguageText(gJVM, LBLKEY_PREFIX + "jvm");
+			layout = new GridLayout(2, false);
+			gJVM.setLayout(layout);
+			gJVM.setLayoutData(new GridData( GridData.FILL_HORIZONTAL ));
+			
+				// wiki link
+			
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+
+			LinkLabel link = new LinkLabel(	gJVM, gridData, "ConfigView.label.please.visit.here",
+											"http://wiki.vuze.com/w/Java_VM_memory_usage");
+			
+				// info
+			
+			label = new Label(gJVM, SWT.NULL);
+			Messages.setLanguageText(label, "jvm.info");
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			label.setLayoutData( gridData );
+			
+			try{
+				final File option_file = platform.getVMOptionFile();
+			 	
+				final Group gJVMOptions = new Group(gJVM, SWT.NULL);
+				layout = new GridLayout(3, false);
+				gJVMOptions.setLayout(layout);
+				gridData = new GridData( GridData.FILL_HORIZONTAL );
+				gridData.horizontalSpan = 2;
+				gJVMOptions.setLayoutData( gridData );
+				
+				buildOptions( cDisplay, platform, gJVMOptions, false );
+				
+					// show option file
+				
+				label = new Label(gJVM, SWT.NULL);
+				Messages.setLanguageText(label, "jvm.show.file", new String[]{ option_file.getAbsolutePath() });
+
+				Button show_folder_button = new Button( gJVM, SWT.PUSH );
+				
+			 	Messages.setLanguageText( show_folder_button, "MyTorrentsView.menu.explore");
+			 	
+			 	show_folder_button.addSelectionListener(
+			 		new SelectionAdapter()
+			 		{
+			 			public void
+			 			widgetSelected(
+			 				SelectionEvent e )
+			 			{
+			 				ManagerUtils.open( option_file );
+			 			}
+			 		});
+
+			 	label = new Label(gJVM, SWT.NULL);			
+				Messages.setLanguageText(label, "jvm.reset");
+
+				Button reset_button = new Button( gJVM, SWT.PUSH );
+				
+			 	Messages.setLanguageText( reset_button, "Button.reset");
+			 	
+			 	reset_button.addSelectionListener(
+			 		new SelectionAdapter()
+			 		{
+			 			public void
+			 			widgetSelected(
+			 				SelectionEvent event )
+			 			{
+			 				try{
+			 					platform.setExplicitVMOptions( new String[0] );
+			 					
+			 					buildOptions( cDisplay, platform, gJVMOptions, true );
+			 					
+			 				}catch( Throwable e ){
+			 					
+			 					Debug.out( e );
+			 				}
+			 			}
+			 		});
+			 	
+			}catch( Throwable e ){
+				
+				Debug.out( e );
+				
+				label = new Label(gJVM, SWT.NULL);
+				Messages.setLanguageText(label, "jvm.error", new String[]{ Debug.getNestedExceptionMessage(e) });
+				gridData = new GridData();
+				gridData.horizontalSpan = 2;
+				label.setLayoutData( gridData );
+			}
+		}
+
+		return cDisplay;
+	}
+
+	private void
+	buildOptions(
+		final Composite			parent,
+		final PlatformManager	platform,
+		final Composite			area,
+		boolean					rebuild )
+	
+		throws PlatformManagerException
+	{
+		if ( rebuild ){
+			
+			Control[] kids = area.getChildren();
+			
+			for ( Control k: kids ){
+				k.dispose();
+			}
+		}
+		
+		String[] options = platform.getExplicitVMOptions();
+		
+		{
+				// max mem
+			
+			long	max_mem = AEMemoryMonitor.getJVMLongOption( options, "-Xmx" );
+			
+			final int MIN_MAX_JVM = 32*1024*1024;
+	
+			GridData gridData = new GridData();
+			Label label = new Label(area, SWT.NULL);
+			label.setLayoutData(gridData);
+			Messages.setLanguageText(label,	"jvm.max.mem", new String[]{encodeDisplayLong(MIN_MAX_JVM)});
+	
+			gridData = new GridData();
+			gridData.widthHint = 125;
+			final StringParameter max_vm = new StringParameter(area, "jvm.max.mem", "", false );
+			max_vm.setLayoutData(gridData);
+				
+			max_vm.setValue( max_mem == -1?"":encodeDisplayLong( max_mem ));
+			
+			max_vm.addChangeListener(
+				new ParameterChangeAdapter()
+				{
+					private String	last_value;
+					
+					public void
+					parameterChanged(
+						Parameter	p,
+						boolean		caused_internally )
+					{
+						if ( max_vm.isDisposed()){
+							
+							max_vm.removeChangeListener( this );
+							
+							return;
+						}
+						
+						String val = max_vm.getValue();
+						
+						if ( last_value != null && last_value.equals( val )){
+							
+							return;
+						}
+						
+						last_value = val;
+											
+						try{
+							long max_mem = decodeDisplayLong( val );
+							
+							if ( max_mem < MIN_MAX_JVM ){
+								
+								throw( new Exception( "Min=" + encodeDisplayLong( MIN_MAX_JVM )));
+							}
+													
+							String[] options = platform.getExplicitVMOptions();
+							
+							options = AEMemoryMonitor.setJVMLongOption( options, "-Xmx", max_mem );
+	
+							long	min_mem = AEMemoryMonitor.getJVMLongOption( options, "-Xms" );
+	
+							if ( min_mem == -1 || min_mem > max_mem ){
+								
+								options = AEMemoryMonitor.setJVMLongOption( options, "-Xms", max_mem );
+							}
+							
+							platform.setExplicitVMOptions( options );
+							
+							buildOptions( parent, platform, area, true );
+							
+						}catch( Throwable e ){
+							
+							String param_name = MessageText.getString( "jvm.max.mem" );
+							
+							int	pos = param_name.indexOf( '[' );
+							
+							if ( pos != -1 ){
+								
+								param_name = param_name.substring( 0, pos ).trim();
+							}
+							
+							MessageBoxShell mb = 
+								new MessageBoxShell( 
+									SWT.ICON_ERROR | SWT.OK,
+									MessageText.getString( "ConfigView.section.invalid.value.title"),
+									MessageText.getString( 
+										"ConfigView.section.invalid.value", 
+										new String[]{ val, param_name, Debug.getNestedExceptionMessage(e)}));
+		  				
+									mb.setParent( parent.getShell());
+									mb.open(null);
+						}
+					}
+				});
+			
+			label = new Label(area, SWT.NULL);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			label.setLayoutData(gridData);
+			
+			Long max_heap_mb = AEMemoryMonitor.getMaxHeapMB();
+			
+			if ( max_heap_mb > 0 ){
+				
+				Messages.setLanguageText(label,	"jvm.max.mem.current", new String[]{ DisplayFormatters.formatByteCountToKiBEtc( max_heap_mb*1024*1024, true )});
+			}
+		}
+		
+		{
+				// min mem
+			
+			final int MIN_MIN_JVM = 8*1024*1024;
+	
+			long	min_mem = AEMemoryMonitor.getJVMLongOption( options, "-Xms" );
+	
+			GridData gridData = new GridData();
+			Label label = new Label(area, SWT.NULL);
+			label.setLayoutData(gridData);
+			Messages.setLanguageText(label,	"jvm.min.mem", new String[]{encodeDisplayLong(MIN_MIN_JVM)});
+	
+			gridData = new GridData();
+			gridData.widthHint = 125;
+			final StringParameter min_vm = new StringParameter(area, "jvm.min.mem", "", false );
+			min_vm.setLayoutData(gridData);
+				
+			min_vm.setValue( min_mem == -1?"":encodeDisplayLong( min_mem ));
+			
+			min_vm.addChangeListener(
+				new ParameterChangeAdapter()
+				{
+					private String	last_value;
+					
+					public void
+					parameterChanged(
+						Parameter	p,
+						boolean		caused_internally )
+					{
+						if ( min_vm.isDisposed()){
+							
+							min_vm.removeChangeListener( this );
+							
+							return;
+						}
+						
+						String val = min_vm.getValue();
+						
+						if ( last_value != null && last_value.equals( val )){
+							
+							return;
+						}
+						
+						last_value = val;
+											
+						try{
+							long min_mem = decodeDisplayLong( val );
+							
+							if ( min_mem < MIN_MIN_JVM ){
+								
+								throw( new Exception( "Min=" + encodeDisplayLong( MIN_MIN_JVM )));
+							}
+													
+							String[] options = platform.getExplicitVMOptions();
+							
+							options = AEMemoryMonitor.setJVMLongOption( options, "-Xms", min_mem );
+	
+							long	max_mem = AEMemoryMonitor.getJVMLongOption( options, "-Xmx" );
+	
+							if ( max_mem == -1 || max_mem < min_mem ){
+								
+								options = AEMemoryMonitor.setJVMLongOption( options, "-Xmx", min_mem );
+							}
+							
+							platform.setExplicitVMOptions( options );
+							
+							buildOptions( parent, platform, area, true );
+							
+						}catch( Throwable e ){
+							
+							String param_name = MessageText.getString( "jvm.min.mem" );
+							
+							int	pos = param_name.indexOf( '[' );
+							
+							if ( pos != -1 ){
+								
+								param_name = param_name.substring( 0, pos ).trim();
+							}
+							
+							MessageBoxShell mb = 
+								new MessageBoxShell( 
+									SWT.ICON_ERROR | SWT.OK,
+									MessageText.getString( "ConfigView.section.invalid.value.title"),
+									MessageText.getString( 
+										"ConfigView.section.invalid.value", 
+										new String[]{ val, param_name, Debug.getNestedExceptionMessage(e)}));
+		  				
+									mb.setParent( parent.getShell());
+									mb.open(null);
+						}
+					}
+				});
+			
+			label = new Label(area, SWT.NULL);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			label.setLayoutData(gridData);
+		}
+		
+		{
+				// max DIRECT mem
+			
+			final int MIN_DIRECT_JVM = 32*1024*1024;
+			
+			final String OPTION_KEY = "-XX:MaxDirectMemorySize=";
+			
+			long	max_direct = AEMemoryMonitor.getJVMLongOption( options, OPTION_KEY );
+	
+			GridData gridData = new GridData();
+			Label label = new Label(area, SWT.NULL);
+			label.setLayoutData(gridData);
+			Messages.setLanguageText(label,	"jvm.max.direct.mem", new String[]{encodeDisplayLong(MIN_DIRECT_JVM)});
+	
+			gridData = new GridData();
+			gridData.widthHint = 125;
+			final StringParameter max_direct_vm = new StringParameter(area, "jvm.max.direct.mem", "", false );
+			max_direct_vm.setLayoutData(gridData);
+				
+			max_direct_vm.setValue( max_direct == -1?"":encodeDisplayLong( max_direct ));
+			
+			max_direct_vm.addChangeListener(
+				new ParameterChangeAdapter()
+				{
+					private String	last_value;
+					
+					public void
+					parameterChanged(
+						Parameter	p,
+						boolean		caused_internally )
+					{
+						if ( max_direct_vm.isDisposed()){
+							
+							max_direct_vm.removeChangeListener( this );
+							
+							return;
+						}
+						
+						String val = max_direct_vm.getValue();
+						
+						if ( last_value != null && last_value.equals( val )){
+							
+							return;
+						}
+						
+						last_value = val;
+											
+						try{
+							long max_direct = decodeDisplayLong( val );
+							
+							if ( max_direct < MIN_DIRECT_JVM ){
+								
+								throw( new Exception( "Min=" + encodeDisplayLong( MIN_DIRECT_JVM )));
+							}
+													
+							String[] options = platform.getExplicitVMOptions();
+							
+							options = AEMemoryMonitor.setJVMLongOption( options, OPTION_KEY, max_direct );
+								
+							platform.setExplicitVMOptions( options );
+							
+							buildOptions( parent, platform, area, true );
+							
+						}catch( Throwable e ){
+							
+							String param_name = MessageText.getString( "jvm.max.direct.mem" );
+							
+							int	pos = param_name.indexOf( '[' );
+							
+							if ( pos != -1 ){
+								
+								param_name = param_name.substring( 0, pos ).trim();
+							}
+							
+							MessageBoxShell mb = 
+								new MessageBoxShell( 
+									SWT.ICON_ERROR | SWT.OK,
+									MessageText.getString( "ConfigView.section.invalid.value.title"),
+									MessageText.getString( 
+										"ConfigView.section.invalid.value", 
+										new String[]{ val, param_name, Debug.getNestedExceptionMessage(e)}));
+		  				
+									mb.setParent( parent.getShell());
+									mb.open(null);
+						}
+					}
+				});
+			
+			label = new Label(area, SWT.NULL);
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			label.setLayoutData(gridData);
+			Messages.setLanguageText(label,	"jvm.max.direct.mem.info" );
+		}		
+		
+			// all options
+
+		Label label = new Label(area, SWT.NULL);
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.horizontalSpan = 3;
+		label.setLayoutData(gridData);
+		Messages.setLanguageText(label,	"jvm.options.summary" );
+
+		for ( String option: options ){
+			
+			label = new Label(area, SWT.NULL);
+			label.setText( option );
+			gridData = new GridData( );
+			gridData.horizontalSpan = 3;
+			gridData.horizontalIndent = 20;
+			label.setLayoutData( gridData );
+		}
+		
+		if ( rebuild ){
+			
+			parent.layout( true, true );
+		}
+	}
+	
+	private static  String
+	encodeDisplayLong(
+		long		val )
+	{
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ));
+		}
+		
+		val = val/1024;
+		
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ) + " KB" );
+		}
+		
+		val = val/1024;
+		
+		if ( val < 1024 ){
+			
+			return( String.valueOf( val ) + " MB" );
+		}
+		
+		val = val/1024;
+		
+		return( String.valueOf( val ) + " GB" );
+	}
+	
+	private static  long
+	decodeDisplayLong(
+		String		val )
+	
+		throws Exception
+	{
+		char[] chars = val.trim().toCharArray();
+		
+		String	digits = "";
+		String	units = "";
+		
+		for ( char c: chars ){
+			
+			if ( Character.isDigit( c )){
+				
+				if ( units.length() > 0 ){
+					
+					throw( new Exception( "Invalid unit" ));
+				}
+				
+				digits += c;
+				
+			}else{
+				
+				if ( digits.length() == 0 ){
+				
+					throw( new Exception( "Missing digits" ));
+					
+				}else if ( units.length() == 0 && Character.isWhitespace( c )){
+					
+				}else{
+				
+					units += c;
+				}
+			}
+		}
+		
+		long value = Long.parseLong( digits );
+		
+		if( units.length() == 0 ){
+			
+			units = "m";
+		}
+		
+		if ( units.length() > 0 ){
+			
+			char c = Character.toLowerCase( units.charAt(0));
+			
+			if ( c == 'k' ){
+				
+				value = value * 1024;
+				
+			}else if ( c == 'm' ){
+				
+				value = value * 1024 * 1024;
+				
+			}else if ( c == 'g' ){
+				
+				value = value * 1024 * 1024 * 1024;
+				
+			}else{
+				
+				throw( new Exception( "Invalid size unit '" + units + "'" ));
+			}
+		}
+		
+		return( value );
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStats.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStats.java
index 312381d..8586491 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStats.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionStats.java
@@ -44,7 +44,6 @@ import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Utils;
 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.Messages;
 import org.gudy.azureus2.core3.stats.StatsWriterPeriodic;
@@ -167,8 +166,8 @@ public class ConfigSectionStats implements UISWTConfigSection {
     controls[6] = xslParameter.getControl();
     Label lxslDetails = new Label(gStats, SWT.NULL);
     Messages.setLanguageText(lxslDetails, "ConfigView.section.stats.xslfiledetails"); //$NON-NLS-1$
-    final String linkFAQ = "http://azureus.sourceforge.net/faq.php#20";
-    lxslDetails.setCursor(Cursors.handCursor);
+    final String linkFAQ = "http://plugins.vuze.com/faq.php#20";
+    lxslDetails.setCursor(lxslDetails.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
     lxslDetails.setForeground(Colors.blue);
     lxslDetails.addMouseListener(new MouseAdapter() {
       public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
index fce3910..319deb7 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerClient.java
@@ -104,36 +104,75 @@ ConfigSectionTrackerClient
     new BooleanParameter(scrapeGroup, "Tracker Client Scrape Single Only",
     							"ConfigView.section.tracker.client.scrapesingleonly");
     
-    /////////////////////////
+    	/////////////// INFO GROUP
     
-    // row
+    Group infoGroup = new Group(gMainTab,SWT.NULL);
+    Messages.setLanguageText(infoGroup,"label.information");
+    gridLayout = new GridLayout();
+    gridLayout.numColumns = 2;
+    infoGroup.setLayout(gridLayout);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 3;
+    infoGroup.setLayoutData( gridData );
+    
+    	// send info
 
     gridData = new GridData();
     gridData.horizontalSpan = 2;
   
-    new BooleanParameter(gMainTab, "Tracker Client Send OS and Java Version",
+    new BooleanParameter(infoGroup, "Tracker Client Send OS and Java Version",
                          "ConfigView.section.tracker.sendjavaversionandos").setLayoutData(gridData);
-
-    label = new Label(gMainTab, SWT.NULL);
+   
+    	// show warnings
     
-
-//////////////////////
+    BooleanParameter showWarnings = new BooleanParameter(infoGroup, "Tracker Client Show Warnings", "ConfigView.section.tracker.client.showwarnings" );
+    gridData = new GridData();
+    gridData.horizontalSpan = 2;
+	showWarnings.setLayoutData(gridData); 
+	
+		// exclude LAN
+	
+	BooleanParameter excludeLAN = new BooleanParameter(infoGroup, "Tracker Client Exclude LAN", "ConfigView.section.tracker.client.exclude_lan" );
+	gridData = new GridData();
+	gridData.horizontalSpan = 2;
+	excludeLAN.setLayoutData(gridData); 
+	
+   		/////////////// PROTOCOL GROUP
+    
+    Group protocolGroup = new Group(gMainTab,SWT.NULL);
+    Messages.setLanguageText(protocolGroup,"label.protocol");
+    gridLayout = new GridLayout();
+    gridLayout.numColumns = 2;
+    protocolGroup.setLayout(gridLayout);
+    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.horizontalSpan = 3;
+    protocolGroup.setLayoutData( gridData );
+    
+    	// tcp enable
+    
+    BooleanParameter enableTCP = new BooleanParameter(protocolGroup, "Tracker Client Enable TCP", "ConfigView.section.tracker.client.enabletcp");
+    gridData = new GridData();
+    gridData.horizontalSpan = 2;
+    enableTCP.setLayoutData(gridData); 
+    
+    	// udp enable
     
-    BooleanParameter enableUDP = new BooleanParameter(gMainTab, "Server Enable UDP", "ConfigView.section.server.enableudp");
+    BooleanParameter enableUDP = new BooleanParameter(protocolGroup, "Server Enable UDP", "ConfigView.section.server.enableudp");
     gridData = new GridData();
     gridData.horizontalSpan = 2;
     enableUDP.setLayoutData(gridData); 
     
-    label = new Label(gMainTab, SWT.NULL);
-  
-//////////////////////
+    	// udp probe enable
     
-    BooleanParameter showWarnings = new BooleanParameter(gMainTab, "Tracker Client Show Warnings", "ConfigView.section.tracker.client.showwarnings" );
+    BooleanParameter enableUDPProbe = new BooleanParameter(protocolGroup, "Tracker UDP Probe Enable", "ConfigView.section.server.enableudpprobe");
     gridData = new GridData();
     gridData.horizontalSpan = 2;
-	showWarnings.setLayoutData(gridData); 
+    enableUDPProbe.setLayoutData(gridData); 
+      
+    enableUDP.setAdditionalActionPerformer(new ChangeSelectionActionPerformer( enableUDPProbe.getControls()));
+
     
-    label = new Label(gMainTab, SWT.NULL);
+
     
     if (userMode > 0) {
     
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
index 33fbf44..96a9830 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTrackerServer.java
@@ -43,7 +43,6 @@ import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.ipchecker.IpCheckerWizard;
 import org.gudy.azureus2.ui.swt.ipchecker.IpSetterCallBack;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
 
 public class 
@@ -234,8 +233,8 @@ ConfigSectionTrackerServer
     gridData.horizontalSpan = 2;
     ssl_faq_label.setLayoutData(gridData);
     Messages.setLanguageText(ssl_faq_label, CFG_PREFIX + "tracker.sslport.info");
-    final String linkFAQ = "http://azureus.sourceforge.net/faq.php#19";
-    ssl_faq_label.setCursor(Cursors.handCursor);
+    final String linkFAQ = "http://plugins.vuze.com/faq.php#19";
+    ssl_faq_label.setCursor(ssl_faq_label.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
     ssl_faq_label.setForeground(Colors.blue);
     ssl_faq_label.addMouseListener(new MouseAdapter() {
        public void mouseDoubleClick(MouseEvent arg0) {
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
index 7075bfc..2b1ad49 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransfer.java
@@ -29,7 +29,9 @@ import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Listener;
 
@@ -38,7 +40,6 @@ import org.gudy.azureus2.ui.swt.components.LinkLabel;
 import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.plugins.UISWTConfigSection;
 import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;
-import org.gudy.azureus2.ui.swt.ImageRepository;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
@@ -164,7 +165,7 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			gridData.horizontalIndent = 10;
 			gridData.horizontalSpan = 2;
 			new LinkLabel(cWiki, gridData, "ConfigView.section.transfer.speeds.wiki",
-					"http://www.azureuswiki.com/index.php/Good_settings");
+					"http://wiki.vuze.com/w/Good_settings");
 		}
 
 		if ( userMode > 1 ){
@@ -188,8 +189,8 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 		final IntParameter paramMaxDownSpeed = new IntParameter(cSection,
 				"Max Download Speed KBs", 0, -1);
 		paramMaxDownSpeed.setLayoutData(gridData);
-		
-		// max upload/download limit dependencies
+				
+			// max upload/download limit dependencies
 		
 		Listener l = new Listener() {
 	
@@ -303,24 +304,112 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 				});
 			}
 		});
+		
+		if (userMode > 0) {
+			
+				// bias upload to incomplete
+			
+			BooleanParameter bias_upload = new BooleanParameter(
+					cSection, 
+					"Bias Upload Enable",
+					"ConfigView.label.xfer.bias_up" );
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+			bias_upload.setLayoutData(gridData);
+			
+
+			final Composite bias_slack_area = new Composite(cSection, SWT.NULL);
+			layout = new GridLayout();
+			layout.numColumns = 3;
+			layout.marginWidth = 0;
+			layout.marginHeight = 0;
+			bias_slack_area.setLayout(layout);
+			gridData = new GridData();
+			gridData.horizontalIndent = 15;
+			gridData.horizontalSpan = 2;
+			bias_slack_area.setLayoutData(gridData);
+
+			label = new Label(bias_slack_area, SWT.NULL);
+			gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
+			label.setLayoutData(gridData);
+			label.setImage(img);
+			
+			label = new Label(bias_slack_area, SWT.NULL);
+			Messages.setLanguageText(label, "ConfigView.label.xfer.bias_slack");
+
+			IntParameter bias_slack = new IntParameter(
+					bias_slack_area, "Bias Upload Slack KBs", 1, -1);
+			
+			
+			final Composite bias_unlimited_area = new Composite(cSection, SWT.NULL);
+			layout = new GridLayout();
+			layout.numColumns = 2;
+			layout.marginWidth = 0;
+			layout.marginHeight = 0;
+			bias_unlimited_area.setLayout(layout);
+			gridData = new GridData();
+			gridData.horizontalIndent = 15;
+			gridData.horizontalSpan = 2;
+			bias_unlimited_area.setLayoutData(gridData);
+
+			label = new Label(bias_unlimited_area, SWT.NULL);
+			gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
+			label.setLayoutData(gridData);
+			label.setImage(img);
+
+			
+			BooleanParameter bias_no_limit = new BooleanParameter(
+					bias_unlimited_area, 
+					"Bias Upload Handle No Limit",
+					"ConfigView.label.xfer.bias_no_limit" );
+						
+			bias_upload.setAdditionalActionPerformer(
+					new ChangeSelectionActionPerformer(
+					new Parameter[]{ bias_slack, bias_no_limit} ));
+		}
 
 		if (userMode > 0) {
 			
+				// AUTO GROUP
+			
+			Group auto_group = new Group(cSection, SWT.NULL);
+			
+			Messages.setLanguageText(auto_group, "group.auto");
+			
+			GridLayout auto_layout = new GridLayout();
+			
+			auto_layout.numColumns = 2;
+
+			auto_group.setLayout(auto_layout);
+
+			gridData = new GridData(GridData.FILL_HORIZONTAL);
+			gridData.horizontalSpan = 2;
+			auto_group.setLayoutData(gridData);
+
+			BooleanParameter auto_adjust = new BooleanParameter(
+					auto_group, 
+					"Auto Adjust Transfer Defaults",
+					"ConfigView.label.autoadjust" );
+			
+			gridData = new GridData();
+			gridData.horizontalSpan = 2;
+
+			auto_adjust.setLayoutData( gridData );
 
 			// max uploads
 			gridData = new GridData();
-			label = new Label(cSection, SWT.NULL);
+			label = new Label(auto_group, SWT.NULL);
 			label.setLayoutData(gridData);
 			Messages.setLanguageText(label, "ConfigView.label.maxuploads");
 
 			gridData = new GridData();
-			IntParameter paramMaxUploads = new IntParameter(cSection, "Max Uploads",
+			IntParameter paramMaxUploads = new IntParameter(auto_group, "Max Uploads",
 					2, -1);
 			paramMaxUploads.setLayoutData(gridData);
 
 				// max uploads when seeding
 			
-			final Composite cMaxUploadsOptionsArea = new Composite(cSection, SWT.NULL);
+			final Composite cMaxUploadsOptionsArea = new Composite(auto_group, SWT.NULL);
 			layout = new GridLayout();
 			layout.numColumns = 3;
 			layout.marginWidth = 0;
@@ -343,23 +432,21 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			enable_seeding_uploads.setLayoutData(gridData);
 
 			gridData = new GridData();
-			IntParameter paramMaxUploadsSeeding = new IntParameter(
+			final IntParameter paramMaxUploadsSeeding = new IntParameter(
 					cMaxUploadsOptionsArea, "Max Uploads Seeding", 2, -1);
 			paramMaxUploadsSeeding.setLayoutData(gridData);
-			enable_seeding_uploads
-					.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-							paramMaxUploadsSeeding.getControl()));
+
 			
 			
 			////
 
 			gridData = new GridData();
-			label = new Label(cSection, SWT.NULL);
+			label = new Label(auto_group, SWT.NULL);
 			label.setLayoutData(gridData);
 			Messages.setLanguageText(label, "ConfigView.label.max_peers_per_torrent");
 
 			gridData = new GridData();
-			IntParameter paramMaxClients = new IntParameter(cSection,
+			IntParameter paramMaxClients = new IntParameter(auto_group,
 					"Max.Peer.Connections.Per.Torrent");
 			paramMaxClients.setLayoutData(gridData);
 
@@ -368,7 +455,7 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			
 				// max peers when seeding
 			
-			final Composite cMaxPeersOptionsArea = new Composite(cSection, SWT.NULL);
+			final Composite cMaxPeersOptionsArea = new Composite(auto_group, SWT.NULL);
 			layout = new GridLayout();
 			layout.numColumns = 3;
 			layout.marginWidth = 0;
@@ -391,34 +478,71 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			enable_max_peers_seeding.setLayoutData(gridData);
 
 			gridData = new GridData();
-			IntParameter paramMaxPeersSeeding = new IntParameter(
+			final IntParameter paramMaxPeersSeeding = new IntParameter(
 					cMaxPeersOptionsArea, "Max.Peer.Connections.Per.Torrent.When.Seeding", 0, -1);
-			paramMaxPeersSeeding.setLayoutData(gridData);
-			enable_max_peers_seeding
-					.setAdditionalActionPerformer(new ChangeSelectionActionPerformer(
-							paramMaxPeersSeeding.getControl()));
-	
+			paramMaxPeersSeeding.setLayoutData(gridData);	
 			
 			/////
 
 			gridData = new GridData();
-			label = new Label(cSection, SWT.NULL);
+			label = new Label(auto_group, SWT.NULL);
 			label.setLayoutData(gridData);
 			Messages.setLanguageText(label, "ConfigView.label.max_peers_total");
 
 			gridData = new GridData();
-			IntParameter paramMaxClientsTotal = new IntParameter(cSection,
+			IntParameter paramMaxClientsTotal = new IntParameter(auto_group,
 					"Max.Peer.Connections.Total");
 			paramMaxClientsTotal.setLayoutData(gridData);
 			
 			gridData = new GridData();
-			label = new Label(cSection, SWT.NULL);
+			label = new Label(auto_group, SWT.NULL);
 			label.setLayoutData(gridData);
 			Messages.setLanguageText(label, "ConfigView.label.maxseedspertorrent");
 
 			gridData = new GridData();
-			new IntParameter(cSection,"Max Seeds Per Torrent").setLayoutData(gridData);
+			IntParameter max_seeds_per_torrent = new IntParameter(auto_group,"Max Seeds Per Torrent");
+			max_seeds_per_torrent.setLayoutData(gridData);
 
+			final Parameter[] parameters = {
+					paramMaxUploads, enable_seeding_uploads, paramMaxUploadsSeeding,
+					paramMaxClients, enable_max_peers_seeding, paramMaxPeersSeeding,
+					paramMaxClientsTotal, max_seeds_per_torrent,
+			};
+			
+		    IAdditionalActionPerformer f_enabler =
+		        new GenericActionPerformer( new Control[0])
+		    	{
+		        	public void 
+		        	performAction()
+		        	{
+		        		boolean auto = COConfigurationManager.getBooleanParameter( "Auto Adjust Transfer Defaults" );
+		        		
+		        		for ( Parameter p: parameters ){
+		        			
+		        			Control[] c = p.getControls();
+		        			
+		        			for ( Control x: c ){
+		        				
+		        				x.setEnabled( !auto );
+		        			}
+		        		}
+		        			
+		        		if ( !auto ){
+		        			
+		        			paramMaxUploadsSeeding.getControl().setEnabled( COConfigurationManager.getBooleanParameter( "enable.seedingonly.maxuploads" ));
+		        			
+		        			paramMaxPeersSeeding.getControl().setEnabled(  COConfigurationManager.getBooleanParameter( "Max.Peer.Connections.Per.Torrent.When.Seeding.Enable" ));
+		        		}
+		        	}
+		        };
+			
+		    f_enabler.performAction();
+		    
+			enable_seeding_uploads.setAdditionalActionPerformer( f_enabler );
+			enable_max_peers_seeding.setAdditionalActionPerformer( f_enabler );
+			auto_adjust.setAdditionalActionPerformer( f_enabler );
+			
+				// END AUTO GROUP
 			
 			gridData = new GridData();
 			gridData.horizontalSpan = 2;
@@ -489,18 +613,6 @@ public class ConfigSectionTransfer implements UISWTConfigSection {
 			StringParameter ignore_ports = new StringParameter(cMiniArea,
 					"Ignore.peer.ports", "0");
 			ignore_ports.setLayoutData(gridData);
-	
-			gridData = new GridData();
-			gridData.horizontalSpan = 2;
-			BooleanParameter pauseOnExit = new BooleanParameter(cSection,
-					"Pause Downloads On Exit", "ConfigView.label.pause.downloads.on.exit");
-			pauseOnExit.setLayoutData(gridData);
-	
-			gridData = new GridData();
-			gridData.horizontalSpan = 2;
-			BooleanParameter resumeOnStart = new BooleanParameter(cSection,
-					"Resume Downloads On Start", "ConfigView.label.resume.downloads.on.start");
-			resumeOnStart.setLayoutData(gridData);
 		}
 		
 		return cSection;
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeed.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeed.java
index 22877f3..c8e2446 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeed.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeed.java
@@ -86,7 +86,7 @@ public class ConfigSectionTransferAutoSpeed implements UISWTConfigSection {
 		gridData = new GridData();
 		gridData.horizontalSpan = 2;
 		new LinkLabel(cSection, gridData, "ConfigView.label.please.visit.here",
-				"http://www.azureuswiki.com/index.php/Auto_Speed");
+				"http://wiki.vuze.com/w/Auto_Speed");
 
 		
 		String[]	units = { DisplayFormatters.getRateUnit( DisplayFormatters.UNIT_KB )};
diff --git a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeedSelect.java b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeedSelect.java
index 9a3ab97..362a318 100644
--- a/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeedSelect.java
+++ b/org/gudy/azureus2/ui/swt/views/configsections/ConfigSectionTransferAutoSpeedSelect.java
@@ -5,7 +5,6 @@ import org.gudy.azureus2.ui.swt.views.stats.TransferStatsView;
 import org.gudy.azureus2.ui.swt.config.*;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
-import org.gudy.azureus2.ui.swt.mainwindow.Cursors;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
 import org.gudy.azureus2.plugins.ui.config.ConfigSection;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
@@ -575,8 +574,8 @@ public class ConfigSectionTransferAutoSpeedSelect
 
         final Label linkLabel = new Label(azWiki, SWT.NULL);
         linkLabel.setText( Constants.APP_NAME + " Wiki AutoSpeed (beta)" );
-        linkLabel.setData("http://www.azureuswiki.com/index.php/Auto_Speed");
-        linkLabel.setCursor(Cursors.handCursor);
+        linkLabel.setData("http://wiki.vuze.com/w/Auto_Speed");
+        linkLabel.setCursor(linkLabel.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
         linkLabel.setForeground(Colors.blue);
         gridData = new GridData();
         linkLabel.setLayoutData( gridData );
diff --git a/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java b/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
index 43d6411..8373964 100644
--- a/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/file/FileInfoView.java
@@ -26,10 +26,7 @@ package org.gudy.azureus2.ui.swt.views.file;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
-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.events.*;
 import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
@@ -40,23 +37,26 @@ 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.logging.*;
+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.peer.PEPeerManager;
 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.Messages;
 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.views.AbstractIView;
-import org.gudy.azureus2.ui.swt.views.IViewExtension;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 
 
 public class FileInfoView
-	extends AbstractIView
-	implements IViewExtension
+	implements UISWTViewCoreEventListener
 {
 	private final static int BLOCK_FILLSIZE = 14;
 
@@ -95,6 +95,8 @@ public class FileInfoView
 	// accessed only in SWT Thread
 	private boolean refreshInfoCanvasQueued;
 
+	private UISWTView swtView;
+
 	/**
 	 * Initialize
 	 *
@@ -110,28 +112,26 @@ public class FileInfoView
 
 	}
 
-	public void dataSourceChanged(Object newDataSource) {
+	private void dataSourceChanged(Object newDataSource) {
 		if (newDataSource == null)
 			file = null;
 		else if (newDataSource instanceof Object[])
 			file = (DiskManagerFileInfo) ((Object[]) newDataSource)[0];
-		else
+		else if (newDataSource instanceof DiskManagerFileInfo)
 			file = (DiskManagerFileInfo) newDataSource;
 
-		fillFileInfoSection();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
-	 */
-	public String getData() {
-		return "FileView.BlockView.title";
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				fillFileInfoSection();
+			}
+		});
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#initialize(org.eclipse.swt.widgets.Composite)
-	 */
-	public void initialize(Composite composite) {
+  private String getFullTitle() {
+    return MessageText.getString("FileView.BlockView.title");
+  }
+	
+  private void initialize(Composite composite) {
 		if (fileInfoComposite != null && !fileInfoComposite.isDisposed()) {
 			Logger.log(new LogEvent(LogIDs.GUI, LogEvent.LT_ERROR,
 					"FileInfoView already initialized! Stack: "
@@ -272,15 +272,16 @@ public class FileInfoView
 		return fileInfoComposite;
 	}
 
-	public void fillFileInfoSection() {
+	private void fillFileInfoSection() {
+		if (topLabel == null) {
+			return;
+		}
 		topLabel.setText( "" );
 		
 		refreshInfoCanvas();
 	}
 
-	public void refresh() {
-		super.refresh();
-
+	private void refresh() {
 		if (loopFactor++ % graphicsUpdate == 0) {
 			refreshInfoCanvas();
 		}
@@ -455,17 +456,11 @@ public class FileInfoView
 		fileInfoCanvas.redraw();
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
-	 */
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return fileInfoComposite;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
-	 */
-	public void delete() {
+	private void delete() {
 		if (img != null && !img.isDisposed()) {
 			img.dispose();
 			img = null;
@@ -475,18 +470,42 @@ public class FileInfoView
 			font.dispose();
 			font = null;
 		}
-		
-		super.delete();
-	}
-
-	public Menu getPrivateMenu() {
-		return null;
 	}
 
-	public void viewActivated() {
-		refreshInfoCanvas();
-	}
-
-	public void viewDeactivated() {
-	}
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	refreshInfoCanvas();
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+        
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java b/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
index 77e77ab..09daf88 100644
--- a/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/peer/PeerInfoView.java
@@ -27,6 +27,7 @@ package org.gudy.azureus2.ui.swt.views.peer;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
@@ -40,7 +41,10 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.disk.DiskManagerPiece;
-import org.gudy.azureus2.core3.logging.*;
+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.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPeerManager;
 import org.gudy.azureus2.core3.util.AERunnable;
@@ -49,18 +53,20 @@ 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.Messages;
 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 org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 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.util.MapUtils;
 
 /**
  * Piece Map subview for Peers View.
@@ -72,8 +78,7 @@ 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, IViewExtension
+	implements UISWTViewCoreEventListener
 {
 	private final static int BLOCK_FILLSIZE = 14;
 
@@ -125,6 +130,8 @@ public class PeerInfoView
 
 	protected boolean refreshInfoCanvasQueued;
 
+	private UISWTView swtView;
+
 	/**
 	 * Initialize
 	 *
@@ -171,28 +178,27 @@ public class PeerInfoView
 		}
 	}
 
-	public void dataSourceChanged(Object newDataSource) {
-		if (newDataSource == null)
-			peer = null;
-		else if (newDataSource instanceof Object[])
+	private void dataSourceChanged(Object newDataSource) {
+		if (newDataSource instanceof Object[]) {
 			peer = (PEPeer) ((Object[]) newDataSource)[0];
-		else
+		} else if (newDataSource instanceof PEPeer) {
 			peer = (PEPeer) newDataSource;
+		} else {
+			peer = null;
+		}
 
-		fillPeerInfoSection();
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				swt_fillPeerInfoSection();
+			}
+		});
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
-	 */
-	public String getData() {
-		return "PeersView.BlockView.title";
+	private String getFullTitle() {
+		return MessageText.getString("PeersView.BlockView.title");
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#initialize(org.eclipse.swt.widgets.Composite)
-	 */
-	public void initialize(Composite composite) {
+	private void initialize(Composite composite) {
 		if (peerInfoComposite != null && !peerInfoComposite.isDisposed()) {
 			Logger.log(new LogEvent(LogIDs.GUI, LogEvent.LT_ERROR,
 					"PeerInfoView already initialized! Stack: "
@@ -325,7 +331,7 @@ public class PeerInfoView
 		return peerInfoComposite;
 	}
 
-	public void fillPeerInfoSection() {
+	private void swt_fillPeerInfoSection() {
 		if (imageLabel.getImage() != null) {
 			Image image = imageLabel.getImage();
 			imageLabel.setImage(null);
@@ -377,17 +383,27 @@ public class PeerInfoView
 		refreshInfoCanvas();
 	}
 
-	public void refresh() {
-		super.refresh();
-
+	private void refresh() {
 		if (loopFactor++ % graphicsUpdate == 0) {
 			refreshInfoCanvas();
 		}
 	}
 
+	/**
+	 * Constructs and image representing the download state of _all_
+	 * the pieces in the torrent.  Particularily slow when there's lots of pieces,
+	 * and also wasteful since only a fraction of them ever get painted at
+	 * any given time.
+	 * 
+	 * TODO: Construct image for visible area only or something
+	 */
 	private void refreshInfoCanvas() {
 		refreshInfoCanvasQueued = false;
 
+		if (peerInfoComposite == null || !peerInfoComposite.isVisible()) {
+			return;
+		}
+
 		peerInfoCanvas.layout(true);
 		Rectangle bounds = peerInfoCanvas.getClientArea();
 		if (bounds.width <= 0 || bounds.height <= 0)
@@ -434,7 +450,7 @@ public class PeerInfoView
 		
 		img = new Image(peerInfoCanvas.getDisplay(), bounds.width, iNeededHeight);
 		GC gcImg = new GC(img);
-
+		
 		try {
 			// use advanced capabilities for faster drawText
 			gcImg.setAdvanced(true);
@@ -506,6 +522,7 @@ public class PeerInfoView
 
 						gcImg.setBackground(blockColors[colorIndex]);
 
+						@SuppressWarnings("null") // partiallyDone false when dm_pieces null
 						int iNewWidth = (int) (((float) dm_pieces[i].getNbWritten() / dm_pieces[i]
 								.getNbBlocks()) * width);
 						if (iNewWidth >= width)
@@ -556,18 +573,15 @@ public class PeerInfoView
 							iXPos + (BLOCK_FILLSIZE / 2), iYPos + 2 });
 				}
 
-				if (availability != null) {
+				if (availability != null && availability[i] < 10) {
 					gcImg.setFont(font);
-
 					String sNumber = String.valueOf(availability[i]);
 					Point size = gcImg.stringExtent(sNumber);
 
-					if (availability[i] < 100) {
-						int x = iXPos + (BLOCK_FILLSIZE / 2) - (size.x / 2);
-						int y = iYPos + (BLOCK_FILLSIZE / 2) - (size.y / 2);
-						gcImg.setForeground(blockColors[BLOCKCOLOR_AVAILCOUNT]);
-						gcImg.drawText(sNumber, x, y, true);
-					}
+					int x = iXPos + (BLOCK_FILLSIZE / 2) - (size.x / 2);
+					int y = iYPos + (BLOCK_FILLSIZE / 2) - (size.y / 2);
+					gcImg.setForeground(blockColors[BLOCKCOLOR_AVAILCOUNT]);
+					gcImg.drawText(sNumber, x, y, true);
 				}
 
 				iCol++;
@@ -581,21 +595,15 @@ public class PeerInfoView
 		} finally {
 			gcImg.dispose();
 		}
-
+		
 		peerInfoCanvas.redraw();
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
-	 */
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return peerInfoComposite;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
-	 */
-	public void delete() {
+	private void delete() {
 		if (!imageLabel.isDisposed() && imageLabel.getImage() != null) {
 			Image image = imageLabel.getImage();
 			imageLabel.setImage(null);
@@ -611,23 +619,54 @@ public class PeerInfoView
 			font.dispose();
 			font = null;
 		}
-
-		super.delete();
 	}
 
-	public Image obfusticatedImage(Image image, Point shellOffset) {
-		UIDebugGenerator.obfusticateArea(image, topLabel, shellOffset, "");
+	private Image obfusticatedImage(Image image) {
+		UIDebugGenerator.obfusticateArea(image, topLabel, "");
 		return image;
 	}
 
-	public Menu getPrivateMenu() {
-		return null;
-	}
-
-	public void viewActivated() {
-		refreshInfoCanvas();
-	}
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+    		refreshInfoCanvas();
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+
+			case UISWTViewEvent.TYPE_OBFUSCATE:
+				Object data = event.getData();
+				if (data instanceof Map) {
+					obfusticatedImage((Image) MapUtils.getMapObject((Map) data, "image",
+							null, Image.class));
+				}
+				break;
+    }
 
-	public void viewDeactivated() {
-	}
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/peer/RemotePieceDistributionView.java b/org/gudy/azureus2/ui/swt/views/peer/RemotePieceDistributionView.java
index 058cad3..2c82b7c 100644
--- a/org/gudy/azureus2/ui/swt/views/peer/RemotePieceDistributionView.java
+++ b/org/gudy/azureus2/ui/swt/views/peer/RemotePieceDistributionView.java
@@ -23,6 +23,8 @@ import java.util.Arrays;
 
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.impl.transport.PEPeerTransportProtocol;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.views.PieceDistributionView;
 
 import com.aelitis.azureus.core.peermanager.piecepicker.util.BitFlags;
@@ -38,18 +40,22 @@ public class RemotePieceDistributionView extends PieceDistributionView {
 	 * @see org.gudy.azureus2.ui.swt.views.PieceDistributionView#dataSourceChanged(java.lang.Object)
 	 */
 	public void dataSourceChanged(Object newDataSource) {
-		if (newDataSource instanceof Object[])
+		if (newDataSource instanceof Object[]) {
 			newDataSource = ((Object[]) newDataSource)[0];
-		if (newDataSource instanceof PEPeer)
-		{
-			peer = (PEPeer) newDataSource;
-			pem = peer.getManager();
-		} else
-		{
+		}
+		if (newDataSource == null) {
 			peer = null;
 			pem = null;
+		} else if (newDataSource instanceof PEPeer) {
+			peer = (PEPeer) newDataSource;
+			pem = peer.getManager();
 		}
-		refresh();
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				refresh();
+			}
+		});
 	}
 
 	public void refresh() {
diff --git a/org/gudy/azureus2/ui/swt/views/piece/MyPieceDistributionView.java b/org/gudy/azureus2/ui/swt/views/piece/MyPieceDistributionView.java
index 112d8fc..0117af6 100644
--- a/org/gudy/azureus2/ui/swt/views/piece/MyPieceDistributionView.java
+++ b/org/gudy/azureus2/ui/swt/views/piece/MyPieceDistributionView.java
@@ -22,6 +22,8 @@ package org.gudy.azureus2.ui.swt.views.piece;
 
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.peer.PEPiece;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.views.PieceDistributionView;
 
 
@@ -40,18 +42,22 @@ public class MyPieceDistributionView
 	
 	public void dataSourceChanged(Object newDataSource) {
 		if (newDataSource instanceof DownloadManager) {
-			pem = ((DownloadManager)newDataSource).getPeerManager();
-			refresh();
-		} else if(newDataSource instanceof Object[])
-		{
-			newDataSource = ((Object[])newDataSource)[0];
-			if(newDataSource instanceof PEPiece)
-			{
-				PEPiece piece = (PEPiece)newDataSource;
+			pem = ((DownloadManager) newDataSource).getPeerManager();
+		} else if (newDataSource instanceof Object[]) {
+			newDataSource = ((Object[]) newDataSource)[0];
+			if (newDataSource instanceof PEPiece) {
+				PEPiece piece = (PEPiece) newDataSource;
 				pem = piece.getManager();
 			}
-				
-		} else
+
+		} else {
 			pem = null;
+		}
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				refresh();
+			}
+		});
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java b/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
index 1659d59..b6d3241 100644
--- a/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
+++ b/org/gudy/azureus2/ui/swt/views/piece/PieceInfoView.java
@@ -21,6 +21,7 @@
 package org.gudy.azureus2.ui.swt.views.piece;
 
 import java.util.Iterator;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.ScrolledComposite;
@@ -34,6 +35,7 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.disk.DiskManagerPiece;
+import org.gudy.azureus2.core3.disk.impl.DiskManagerImpl;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerPieceListener;
 import org.gudy.azureus2.core3.internat.MessageText;
@@ -45,12 +47,16 @@ import org.gudy.azureus2.core3.peer.PEPeerManager;
 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.Messages;
 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.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
+
+import com.aelitis.azureus.util.MapUtils;
 
 /**
  * @author TuxPaper
@@ -58,8 +64,8 @@ import org.gudy.azureus2.ui.swt.views.AbstractIView;
  *
  */
 public class PieceInfoView
-	extends AbstractIView
-	implements ObfusticateImage, DownloadManagerPieceListener
+	implements DownloadManagerPieceListener,
+	UISWTViewCoreEventListener
 {
 
 	private final static int BLOCK_FILLSIZE = 14;
@@ -117,7 +123,7 @@ public class PieceInfoView
 		};
 	}
 
-	public void dataSourceChanged(Object newDataSource) {
+	private void dataSourceChanged(Object newDataSource) {
 		if (newDataSource instanceof DownloadManager) {
 			oldBlockInfo = null;
 			if (dlm != null) {
@@ -127,19 +133,30 @@ public class PieceInfoView
 			dlm.addPieceListener(this, false);
 			fillPieceInfoSection();
 		}
+		
+		if (newDataSource instanceof Object[]) {
+			Object[] objects = (Object[]) newDataSource;
+			if (objects.length > 0 && (objects[0] instanceof PEPiece)) {
+  			PEPiece piece = (PEPiece) objects[0];
+  			DiskManager diskManager = piece.getDMPiece().getManager();
+  			if (diskManager instanceof DiskManagerImpl) {
+  				DiskManagerImpl dmi = (DiskManagerImpl) diskManager;
+  				if (dlm != null) {
+  					dlm.removePieceListener(this);
+  				}
+  				dlm = dmi.getDownloadManager();
+  				dlm.addPieceListener(this, false);
+  				fillPieceInfoSection();
+  			}
+			}
+		}
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
-	 */
-	public String getData() {
-		return "PeersView.BlockView.title";
+	private String getFullTitle() {
+		return MessageText.getString("PeersView.BlockView.title");
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#initialize(org.eclipse.swt.widgets.Composite)
-	 */
-	public void initialize(Composite composite) {
+	private void initialize(Composite composite) {
 		if (pieceInfoComposite != null && !pieceInfoComposite.isDisposed()) {
 			Logger.log(new LogEvent(LogIDs.GUI, LogEvent.LT_ERROR,
 					"PeerInfoView already initialized! Stack: "
@@ -226,9 +243,17 @@ public class PieceInfoView
 
 		pieceInfoCanvas.addListener(SWT.Resize, new Listener() {
 			public void handleEvent(Event e) {
+				synchronized (PieceInfoView.this) {
+  				if (alreadyFilling) {
+  					return;
+  				}
+  				
+  				alreadyFilling = 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)
-				e.widget.getDisplay().asyncExec(new AERunnable() {
+				Utils.execSWTThreadLater(0, new AERunnable() {
 					public void runSupport() {
 						if (img != null) {
 							int iOldColCount = img.getBounds().width / BLOCK_SIZE;
@@ -237,6 +262,9 @@ public class PieceInfoView
 							if (iOldColCount != iNewColCount)
 								refreshInfoCanvas();
 						}
+						synchronized (PieceInfoView.this) {
+							alreadyFilling = false;
+						}
 					}
 				});
 			}
@@ -266,11 +294,16 @@ public class PieceInfoView
 
 	private boolean alreadyFilling = false;
 
-	public void fillPieceInfoSection() {
-		if (alreadyFilling) {
-			return;
+	private UISWTView swtView;
+
+	private void fillPieceInfoSection() {
+		synchronized (this) {
+			if (alreadyFilling) {
+				return;
+			}
+			alreadyFilling = true;
 		}
-		alreadyFilling = true;
+
 		Utils.execSWTThreadLater(100, new AERunnable() {
 			public void runSupport() {
 				if (!alreadyFilling) {
@@ -289,22 +322,24 @@ public class PieceInfoView
 
   				refreshInfoCanvas();
 				} finally {
-					alreadyFilling = false;
+					synchronized (PieceInfoView.this) {
+						alreadyFilling = false;
+					}
 				}
 			}
 		});
 	}
 
-	public void refresh() {
-		super.refresh();
-
+	private void refresh() {
 		if (loopFactor++ % graphicsUpdate == 0) {
 			refreshInfoCanvas();
 		}
 	}
 
 	protected void refreshInfoCanvas() {
-		alreadyFilling = false;
+		synchronized (PieceInfoView.this) {
+			alreadyFilling = false;
+		}
 		
 		if (!pieceInfoCanvas.isVisible()) {
 			return;
@@ -590,17 +625,11 @@ public class PieceInfoView
 
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
-	 */
-	public Composite getComposite() {
+	private Composite getComposite() {
 		return pieceInfoComposite;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
-	 */
-	public void delete() {
+	private void delete() {
 		if (imageLabel != null && !imageLabel.isDisposed()
 				&& imageLabel.getImage() != null) {
 			Image image = imageLabel.getImage();
@@ -620,12 +649,10 @@ public class PieceInfoView
 		
 		if(dlm != null)
 			dlm.removePieceListener(this);
-
-		super.delete();
 	}
 
-	public Image obfusticatedImage(Image image, Point shellOffset) {
-		UIDebugGenerator.obfusticateArea(image, topLabel, shellOffset, "");
+	private Image obfusticatedImage(Image image) {
+		UIDebugGenerator.obfusticateArea(image, topLabel, "");
 		return image;
 	}
 
@@ -663,4 +690,48 @@ public class PieceInfoView
 					&& downloadingIndicator == otherBlockInfo.downloadingIndicator;
 		}
 	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+      	swtView.setTitle(getFullTitle());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	dataSourceChanged(event.getData());
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+
+			case UISWTViewEvent.TYPE_OBFUSCATE:
+				Object data = event.getData();
+				if (data instanceof Map) {
+					obfusticatedImage((Image) MapUtils.getMapObject((Map) data, "image",
+							null, Image.class));
+				}
+				break;
+    }
+
+    return true;
+  }
+
 }
diff --git a/org/gudy/azureus2/ui/swt/views/stats/ActivityView.java b/org/gudy/azureus2/ui/swt/views/stats/ActivityView.java
index 4ffbc40..b386db3 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/ActivityView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/ActivityView.java
@@ -37,25 +37,29 @@ import org.gudy.azureus2.core3.config.impl.TransferSpeedValidator;
 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.stats.transfer.OverallStats;
-import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.Legend;
 import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreRunningListener;
 import com.aelitis.azureus.core.AzureusCoreFactory;
+import com.aelitis.azureus.core.AzureusCoreRunningListener;
 
 /**
  * @author Olivier
  *
  */
-public class ActivityView extends AbstractIView implements ParameterListener {
+public class ActivityView 
+	implements ParameterListener, UISWTViewCoreEventListener
+{
 
-  GlobalManager manager = null;
+  public static final String MSGID_PREFIX = "SpeedView";
+  
+	GlobalManager manager = null;
   GlobalManagerStats stats = null;
   
   Composite panel;
@@ -64,9 +68,13 @@ public class ActivityView extends AbstractIView implements ParameterListener {
   SpeedGraphic downSpeedGraphic;
   
   Canvas upSpeedCanvas;
-  SpeedGraphic upSpeedGraphic;  
+  SpeedGraphic upSpeedGraphic;
+
+	private UISWTView swtView;  
   
   public ActivityView() {
+    downSpeedGraphic = SpeedGraphic.getInstance();
+    upSpeedGraphic = SpeedGraphic.getInstance();
   	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
 				manager = core.getGlobalManager();
@@ -75,6 +83,9 @@ public class ActivityView extends AbstractIView implements ParameterListener {
 		});
   }
   
+  /* (non-Javadoc)
+   * @see org.gudy.azureus2.ui.swt.views.stats.PeriodicViewUpdate#periodicUpdate()
+   */
   public void periodicUpdate() {
   	if (manager == null || stats == null) {
   		return;
@@ -95,7 +106,7 @@ public class ActivityView extends AbstractIView implements ParameterListener {
     				swarms_peer_speed });
   }
   
-  public void initialize(Composite composite) {
+  private void initialize(Composite composite) {
     panel = new Composite(composite,SWT.NULL);
     panel.setLayout(new GridLayout());
     GridData gridData;
@@ -109,7 +120,6 @@ public class ActivityView extends AbstractIView implements ParameterListener {
     downSpeedCanvas = new Canvas(gDownSpeed,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     downSpeedCanvas.setLayoutData(gridData);
-    downSpeedGraphic = SpeedGraphic.getInstance();
     downSpeedGraphic.initialize(downSpeedCanvas);
     Color[] colors = downSpeedGraphic.colors;
     
@@ -122,7 +132,6 @@ public class ActivityView extends AbstractIView implements ParameterListener {
     upSpeedCanvas = new Canvas(gUpSpeed,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     upSpeedCanvas.setLayoutData(gridData);
-    upSpeedGraphic = SpeedGraphic.getInstance();
     upSpeedGraphic.initialize(upSpeedCanvas);
     
     COConfigurationManager.addAndFireParameterListener("Stats Graph Dividers", this);
@@ -141,35 +150,63 @@ public class ActivityView extends AbstractIView implements ParameterListener {
 	Legend.createLegendComposite(panel, colors, colorConfigs);
   }
   
-  public void delete() {    
+  private void delete() {    
     Utils.disposeComposite(panel);
     downSpeedGraphic.dispose();
     upSpeedGraphic.dispose();
     COConfigurationManager.removeParameterListener("Stats Graph Dividers", this);
   }
 
-  public String getFullTitle() {
-    return MessageText.getString("SpeedView.title.full"); //$NON-NLS-1$
-  }
-  
-  public Composite getComposite() {
+  private Composite getComposite() {
     return panel;
   }
   
-  public void refresh() {
+  private void refresh() {
     downSpeedGraphic.refresh();
     upSpeedGraphic.refresh();
   }  
   
-  public String getData() {
-    return "SpeedView.title.full";
-  }
-
   public void parameterChanged(String param_name) {
 	  boolean update_dividers = COConfigurationManager.getBooleanParameter("Stats Graph Dividers");
 	  int update_divider_width = update_dividers ? 60 : 0;
       downSpeedGraphic.setUpdateDividerWidth(update_divider_width);
       upSpeedGraphic.setUpdateDividerWidth(update_divider_width);
   }
-  
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(MSGID_PREFIX + ".title.full"));
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+
+      case StatsView.EVENT_PERIODIC_UPDATE:
+      	periodicUpdate();
+      	break;
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/stats/CacheView.java b/org/gudy/azureus2/ui/swt/views/stats/CacheView.java
index 923ad17..2b24afb 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/CacheView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/CacheView.java
@@ -25,18 +25,17 @@ package org.gudy.azureus2.ui.swt.views.stats;
 import org.eclipse.swt.SWT;
 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.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.ProgressBar;
+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.DisplayFormatters;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerFactory;
 import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerStats;
@@ -44,9 +43,13 @@ import com.aelitis.azureus.core.diskmanager.cache.CacheFileManagerStats;
 /**
  * 
  */
-public class CacheView extends AbstractIView {
+public class CacheView
+	implements UISWTViewCoreEventListener
+{
   
-  CacheFileManagerStats stats;
+  public static final String MSGID_PREFIX = "CacheView";
+
+	CacheFileManagerStats stats;
   
   Composite panel;
   
@@ -67,16 +70,22 @@ public class CacheView extends AbstractIView {
   Canvas  readsFromFile,readsFromCache,writesToCache,writesToFile;
   
   SpeedGraphic rffGraph,rfcGraph,wtcGraph,wtfGraph;
+
+	private UISWTView swtView;
   
   public CacheView() {
     try {
       this.stats = CacheFileManagerFactory.getSingleton().getStats();
+      rfcGraph = SpeedGraphic.getInstance();
+      wtcGraph = SpeedGraphic.getInstance();
+      rffGraph = SpeedGraphic.getInstance();
+      wtfGraph = SpeedGraphic.getInstance();
     } catch(Exception e) {
     	Debug.printStackTrace( e );
     }
   }
   
-  public void initialize(Composite composite) {
+  private void initialize(Composite composite) {
     panel = new Composite(composite,SWT.NULL);
     panel.setLayout(new GridLayout());
     
@@ -250,14 +259,12 @@ public class CacheView extends AbstractIView {
     readsFromCache = new Canvas(gCacheSpeeds,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     readsFromCache.setLayoutData(gridData);
-    rfcGraph = SpeedGraphic.getInstance();
     rfcGraph.initialize(readsFromCache);
     
     
     writesToCache = new Canvas(gCacheSpeeds,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     writesToCache.setLayoutData(gridData);
-    wtcGraph = SpeedGraphic.getInstance();
     wtcGraph.initialize(writesToCache);
     
     lbl = new Label(gCacheSpeeds,SWT.NULL);
@@ -266,16 +273,17 @@ public class CacheView extends AbstractIView {
     readsFromFile = new Canvas(gCacheSpeeds,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     readsFromFile.setLayoutData(gridData);
-    rffGraph = SpeedGraphic.getInstance();
     rffGraph.initialize(readsFromFile);
     
     writesToFile = new Canvas(gCacheSpeeds,SWT.NO_BACKGROUND);
     gridData = new GridData(GridData.FILL_BOTH);
     writesToFile.setLayoutData(gridData);
-    wtfGraph = SpeedGraphic.getInstance();
     wtfGraph.initialize(writesToFile);
   }
   
+  /* (non-Javadoc)
+   * @see org.gudy.azureus2.ui.swt.views.stats.PeriodicViewUpdate#periodicUpdate()
+   */
   public void periodicUpdate() {
     rfcGraph.addIntValue((int)stats.getAverageBytesReadFromCache());
     rffGraph.addIntValue((int)stats.getAverageBytesReadFromFile());
@@ -366,7 +374,7 @@ public class CacheView extends AbstractIView {
     lblAvgSizeToFile.setLayoutData(gridData);
   }
 
-  public void delete() {
+  private void delete() {
     Utils.disposeComposite(panel);
     rfcGraph.dispose();
     rffGraph.dispose();
@@ -374,15 +382,11 @@ public class CacheView extends AbstractIView {
     wtfGraph.dispose();
   }
 
-  public String getFullTitle() {
-    return MessageText.getString("CacheView.title.full"); //$NON-NLS-1$
-  }
-  
-  public Composite getComposite() {
+  private Composite getComposite() {
     return panel;
   }
   
-  public void refresh() {
+  private void refresh() {
     //General Part    
     lblSize.setText(DisplayFormatters.formatByteCountToKiBEtc(stats.getSize()));
     lblInUse.setText(DisplayFormatters.formatByteCountToKiBEtc(stats.getUsedSize()));
@@ -475,10 +479,42 @@ public class CacheView extends AbstractIView {
     }
   }
 
-  public String getData() {
-    return "CacheView.title.full";
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(MSGID_PREFIX + ".title.full"));
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+
+      case StatsView.EVENT_PERIODIC_UPDATE:
+      	periodicUpdate();
+      	break;
+    }
+
+    return true;
   }
-    
 }
 
 
diff --git a/org/gudy/azureus2/ui/swt/views/stats/DHTView.java b/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
index 8162907..7fa5a7f 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/DHTView.java
@@ -25,29 +25,21 @@ package org.gudy.azureus2.ui.swt.views.stats;
 import org.eclipse.swt.SWT;
 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.Event;
-import org.eclipse.swt.widgets.Group;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Table;
-import org.eclipse.swt.widgets.TableColumn;
-import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.*;
+
 import org.gudy.azureus2.core3.internat.MessageText;
-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.TimeFormatter;
+import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.plugins.PluginInterface;
 import org.gudy.azureus2.ui.swt.Messages;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 
 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.dht.DHT;
 import com.aelitis.azureus.core.dht.DHTStorageAdapter;
 import com.aelitis.azureus.core.dht.control.DHTControlActivity;
@@ -64,11 +56,14 @@ import com.aelitis.azureus.plugins.dht.DHTPlugin;
 /**
  * 
  */
-public class DHTView extends AbstractIView {
+public class DHTView
+	implements UISWTViewEventListener
+{
   
   public static final int DHT_TYPE_MAIN 	= DHT.NW_MAIN;
   public static final int DHT_TYPE_CVS  	= DHT.NW_CVS;
   public static final int DHT_TYPE_MAIN_V6 	= DHT.NW_MAIN_V6;
+	public static final String MSGID_PREFIX = "DHTView";
 
   DHT dht;
   
@@ -103,19 +98,13 @@ public class DHTView extends AbstractIView {
   Table activityTable;
   DHTControlActivity[] activities;
   
-  private final int dht_type;
+  private int dht_type;
 	protected AzureusCore core;
   
 
-  public DHTView( int dht_type ) {
-    this.dht_type = dht_type;
-  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-
-			public void azureusCoreRunning(AzureusCore core) {
-				DHTView.this.core = core;
-				init(core);
-			}
-		});
+  public DHTView( ) {
+    inGraph = SpeedGraphic.getInstance();
+    outGraph = SpeedGraphic.getInstance();
   }
   
   private void init(AzureusCore core) {
@@ -153,8 +142,16 @@ public class DHTView extends AbstractIView {
     }
   }
   
-  public void initialize(Composite composite) {
-    panel = new Composite(composite,SWT.NULL);
+  private void initialize(Composite composite) {
+  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+			public void azureusCoreRunning(AzureusCore core) {
+				DHTView.this.core = core;
+				init(core);
+			}
+		});
+
+  	panel = new Composite(composite,SWT.NULL);
     GridLayout layout = new GridLayout();
     layout.numColumns = 2;
     panel.setLayout(layout);
@@ -383,7 +380,6 @@ public class DHTView extends AbstractIView {
     data = new GridData(GridData.FILL_BOTH);
     data.horizontalSpan = 3;
     in.setLayoutData(data);
-    inGraph = SpeedGraphic.getInstance();
     inGraph.initialize(in);
     
     label = new Label(gTransport,SWT.NONE);
@@ -396,7 +392,6 @@ public class DHTView extends AbstractIView {
     data = new GridData(GridData.FILL_BOTH);
     data.horizontalSpan = 3;
     out.setLayoutData(data);
-    outGraph = SpeedGraphic.getInstance();
     outGraph.initialize(out);
   }
   
@@ -546,7 +541,7 @@ public class DHTView extends AbstractIView {
   }
   
 
-  public void delete() {
+  private void delete() {
     Utils.disposeComposite(panel);
     if (dht != null) {
       dht.getControl().removeListener(controlListener);
@@ -555,7 +550,7 @@ public class DHTView extends AbstractIView {
     inGraph.dispose();
   }
 
-  public String getFullTitle() {
+  private String getTitleID() {
 	  if ( dht_type == DHT_TYPE_MAIN ){
 
 		  return( "DHTView.title.full" );
@@ -569,11 +564,11 @@ public class DHTView extends AbstractIView {
 	  }
   }
   
-  public Composite getComposite() {
+  private Composite getComposite() {
     return panel;
   }
   
-  public void refresh() {    
+  private void refresh() {    
   	if (dht == null) {
   		if (core != null) {
   			// keep trying until dht is avail
@@ -628,6 +623,7 @@ public class DHTView extends AbstractIView {
   }
   
   private int refreshIter = 0;
+	private UISWTView swtView;
   
   private void refreshDB() {    
     if(refreshIter == 0) {
@@ -718,8 +714,50 @@ public class DHTView extends AbstractIView {
     outGraph.addIntValue((int)fullStats.getAverageBytesSent());
   }
   
-  public String getData() {
-	  return( getFullTitle());
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(getTitleID()));
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+    		if (swtView != null) {
+        	swtView.setTitle(MessageText.getString(getTitleID()));
+    		}
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	if (event.getData() instanceof Number) {
+      		dht_type = ((Number) event.getData()).intValue();
+      		if (swtView != null) {
+          	swtView.setTitle(MessageText.getString(getTitleID()));
+      		}
+      	}
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+
+      case StatsView.EVENT_PERIODIC_UPDATE:
+      	periodicUpdate();
+      	break;
+    }
+
+    return true;
   }
 }
 
diff --git a/org/gudy/azureus2/ui/swt/views/stats/StatsView.java b/org/gudy/azureus2/ui/swt/views/stats/StatsView.java
index d31bb85..a5e7b46 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/StatsView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/StatsView.java
@@ -22,288 +22,437 @@
 package org.gudy.azureus2.ui.swt.views.stats;
 
 import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.TabFolder;
-import org.eclipse.swt.widgets.TabItem;
-import org.gudy.azureus2.core3.global.GlobalManager;
+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.Constants;
 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.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
-import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.ui.swt.plugins.*;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance.UISWTViewEventListenerWrapper;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
+import org.gudy.azureus2.ui.swt.views.IViewAlwaysInitialize;
 
-import com.aelitis.azureus.core.AzureusCore;
-import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.networkmanager.admin.NetworkAdmin;
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
 
 /**
- * 
+ * aka "Statistics View" that contains {@link ActivityView}, 
+ * {@link TransferStatsView}, {@link CacheView}, {@link DHTView},
+ * {@link VivaldiView}
  */
-public class StatsView extends AbstractIView {
-  
-  TabFolder folder;
-  
-  TabItem itemActivity;
-  TabItem itemStats;
-  TabItem itemCache;
-  TabItem[] itemDHTs;
-  TabItem[] itemVivaldis;
-  
-  ActivityView viewActivity;
-  TransferStatsView viewStats;
-  CacheView viewCache;
-  DHTView[] viewDHTs;
-  IView[] viewVivaldis;
-  UpdateThread updateThread;
-  
-  public StatsView() {
-   }
-
-  private class UpdateThread extends Thread {
-    boolean bContinue;
-    
+public class StatsView
+	implements IViewAlwaysInitialize, UISWTViewCoreEventListener
+{
+	public static String VIEW_ID = UISWTInstance.VIEW_STATISTICS;
+	
+	public static final int EVENT_PERIODIC_UPDATE = 0x100;
+
+	private CTabFolder folder;
+
+	private ArrayList<UISWTViewCore> tabViews = new ArrayList<UISWTViewCore>();
+
+	private int idxActivityTab = -1;
+
+	private int idxDHTView = -1;
+
+	private int idxTransfersView = -1;
+
+	private UpdateThread updateThread;
+
+	private Object dataSource;
+
+	private UISWTViewCore activeView;
+
+	private UISWTView swtView;
+
+	private Composite parent;
+
+	private static boolean registeredCoreSubViews;
+
+	private class UpdateThread
+		extends Thread
+	{
+		boolean bContinue;
+
 		public UpdateThread() {
 			super("StatsView Update Thread");
 		}
-    
+
 		public void run() {
 			bContinue = true;
-			while(bContinue) {  
-				try {
 
-					viewActivity.periodicUpdate();
-					viewCache.periodicUpdate(); 
-					viewStats.periodicUpdate();
+			while (bContinue) {
 
-					for (int i=0;i<viewDHTs.length;i++){
-						viewDHTs[i].periodicUpdate();
+				for (UISWTViewCore iview : tabViews) {
+					try {
+						iview.triggerEvent(EVENT_PERIODIC_UPDATE, null);
+					} catch (Exception e) {
+						Debug.printStackTrace(e);
 					}
-				} catch(Exception e) {
-					Debug.printStackTrace( e );  
 				}
-				try{
+
+				try {
 					Thread.sleep(1000);
-				}catch( Throwable e ){
+				} catch (Throwable e) {
 
-					Debug.out( e );
+					Debug.out(e);
 					break;
 				}
 			}
 		}
-    
-    public void stopIt() {
-      bContinue = false;
-    }
-  }
-  
-  public void initialize(Composite composite) {
-    folder = new TabFolder(composite, SWT.LEFT);
-    folder.setBackground(Colors.background);
-    
-    List	dhts = new ArrayList();
-    List  vivaldis = new ArrayList();
-
-    dhts.add( new DHTView( DHTView.DHT_TYPE_MAIN ));  
-    vivaldis.add( new VivaldiView( VivaldiView.DHT_TYPE_MAIN ));  
-
-    if ( NetworkAdmin.getSingleton().hasDHTIPV6()){
-  
-    	dhts.add(  new DHTView( DHTView.DHT_TYPE_MAIN_V6 ));
-    	vivaldis.add(  new VivaldiView( VivaldiView.DHT_TYPE_MAIN_V6 ));
-    }
-    
-    if( Constants.isCVSVersion()){
-    	
-       	dhts.add(  new DHTView( DHTView.DHT_TYPE_CVS ));
-       	vivaldis.add(  new VivaldiView( VivaldiView.DHT_TYPE_CVS ));
-    }
-    
-    viewDHTs = new DHTView[dhts.size()];
-    viewVivaldis = new IView[vivaldis.size()];
-    
-    dhts.toArray( viewDHTs );
-    vivaldis.toArray( viewVivaldis );
-    
-    itemActivity = new TabItem(folder, SWT.NULL);
-    itemStats = new TabItem(folder, SWT.NULL);
-    itemCache  = new TabItem(folder, SWT.NULL);
-    
-    itemDHTs = new TabItem[viewDHTs.length];
-    
-    for (int i=0;i<itemDHTs.length;i++){
-    	itemDHTs[i] = new TabItem(folder, SWT.NULL);
-    }
-
-    itemVivaldis = new TabItem[viewVivaldis.length];
-
-    for (int i=0;i<itemVivaldis.length;i++){
-      itemVivaldis[i] = new TabItem(folder,SWT.NULL);
-    }
-
-    viewActivity = new ActivityView();
-    viewStats = new TransferStatsView();
-    viewCache = new CacheView();
-    
- 
-    
-    
-    Messages.setLanguageText(itemActivity, viewActivity.getData());
-    Messages.setLanguageText(itemStats, viewStats.getData());
-    Messages.setLanguageText(itemCache, viewCache.getData());
-    
-    for (int i=0;i<viewDHTs.length;i++){
-    	Messages.setLanguageText(itemDHTs[i], viewDHTs[i].getData());
-    	Messages.setLanguageText(itemVivaldis[i], viewVivaldis[i].getData());
-    }
-    
-    TabItem items[] = {itemActivity};
-    folder.setSelection(items);
-    
-    viewActivity.initialize(folder);
-    itemActivity.setControl(viewActivity.getComposite());
-    
-    viewStats.initialize(folder);
-    itemStats.setControl(viewStats.getComposite());
-    
-    viewCache.initialize(folder);
-    itemCache.setControl(viewCache.getComposite());
-    
-    for (int i=0;i<viewDHTs.length;i++){
-    	viewDHTs[i].initialize(folder);
-    	itemDHTs[i].setControl(viewDHTs[i].getComposite());
-    }
-    
-    for (int i=0;i<viewVivaldis.length;i++){
-    	viewVivaldis[i].initialize(folder);
-    	itemVivaldis[i].setControl(viewVivaldis[i].getComposite());
-    }
-    
-    folder.addSelectionListener(new SelectionListener() {
-      public void widgetSelected(SelectionEvent e) {
-        refresh();
-      }
-      public void widgetDefaultSelected(SelectionEvent e) {
-      }
-    });
-    
-    
-    refresh();
-    viewActivity.getComposite().layout(true);
-    for (int i=0;i<viewVivaldis.length;i++){
-      viewVivaldis[i].getComposite().layout(true);
-    }
-    
-    updateThread = new UpdateThread(); 
-    updateThread.setDaemon(true);
-    updateThread.start();
-  }
-  
-  public void refresh() {
-    if(getComposite() == null || getComposite().isDisposed())
-      return;
-
-    try {
-      int index = folder.getSelectionIndex();
-      
-      if( index == 0 ) {
-        if (viewActivity != null && !itemActivity.isDisposed())   viewActivity.refresh();
-        return;
-      }
-      
-      if( index == 1 ) {
-        if (viewStats != null && !itemStats.isDisposed())  viewStats.refresh();
-        return;
-      }
-      
-      if( index == 2 ) {
-        if (viewCache != null && !itemCache.isDisposed())  viewCache.refresh();
-        return;
-      }
-      
-      if ( index-3 < viewDHTs.length ){
-    	  if ( !itemDHTs[index-3].isDisposed()){
-    		  viewDHTs[index-3].refresh();
-    	  }
-    	  return;
-      }
-      
-      if ( index-3-viewDHTs.length < viewVivaldis.length ){
-        if ( !itemVivaldis[index-3-viewDHTs.length].isDisposed()){
-          viewVivaldis[index-3-viewDHTs.length].refresh();
-        }
-        return;
-      }
-  
-    } catch (Exception e) {
-    	Debug.printStackTrace( e );
-    }
-  }
-  
-  public void
-  showTransfers()
-  {
-	  folder.setSelection( new TabItem[]{ itemStats });
-  }
-  
-  public void
-  showDHT()
-  {
-	  folder.setSelection( new TabItem[]{ itemDHTs[0] });
-  }
-  
-  public Composite getComposite() {
-    return folder;
-  }
-
-  public String getFullTitle() {
-    return MessageText.getString("Stats.title.full"); //$NON-NLS-1$
-  }
-  
-  public void delete() {
-    updateThread.stopIt();
-
-    //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(folder != null && !folder.isDisposed()) {
-        TabItem[] items = folder.getItems();
-        for(int i=0 ; i < items.length ; i++) {
-          if (!items[i].isDisposed())
-            items[i].dispose();
-        }
-      }
-    }
-    
-    viewActivity.delete();
-    viewStats.delete();
-    viewCache.delete();
-    
-    for (int i=0;i<viewDHTs.length;i++){
-    	viewDHTs[i].delete();
-    }
-
-    if(! folder.isDisposed()) {
-      Utils.disposeComposite(folder);
-    }
-  }
-  
-  // @see org.gudy.azureus2.ui.swt.views.AbstractIView#dataSourceChanged(java.lang.Object)
-  public void dataSourceChanged(Object newDataSource) {
-  	if (newDataSource instanceof String) {
-  		if ("dht".equals(newDataSource)) {
-  			showDHT();
-  		} else if ("transfers".equals(newDataSource)) {
-  			showTransfers();
+
+		public void stopIt() {
+			bContinue = false;
+		}
+	}
+
+	private void initialize(Composite composite) {
+		parent = composite;
+		folder = new CTabFolder(composite, SWT.LEFT);
+		folder.setBorderVisible(true);
+
+		Label lblClose = new Label(folder, SWT.WRAP);
+		lblClose.setText("x");
+		lblClose.addListener(SWT.MouseUp, new Listener() {
+			public void handleEvent(Event event) {
+				delete();
+			}
+		});
+		folder.setTopRight(lblClose);
+		folder.setTabHeight(20);
+
+    // Call plugin listeners
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+
+			if (pluginUI != null && !registeredCoreSubViews) {
+				pluginUI.addView(UISWTInstance.VIEW_STATISTICS,
+						ActivityView.MSGID_PREFIX, ActivityView.class, null);
+
+				pluginUI.addView(UISWTInstance.VIEW_STATISTICS,
+						TransferStatsView.MSGID_PREFIX, TransferStatsView.class, null);
+
+				pluginUI.addView(UISWTInstance.VIEW_STATISTICS, CacheView.MSGID_PREFIX,
+						CacheView.class, null);
+
+				pluginUI.addView(UISWTInstance.VIEW_STATISTICS, DHTView.MSGID_PREFIX,
+						DHTView.class, DHTView.DHT_TYPE_MAIN);
+
+				pluginUI.addView(UISWTInstance.VIEW_STATISTICS,
+						VivaldiView.MSGID_PREFIX, VivaldiView.class,
+						VivaldiView.DHT_TYPE_MAIN);
+
+				if (NetworkAdmin.getSingleton().hasDHTIPV6()) {
+					pluginUI.addView(UISWTInstance.VIEW_STATISTICS, DHTView.MSGID_PREFIX
+							+ ".6", DHTView.class, DHTView.DHT_TYPE_MAIN_V6);
+					pluginUI.addView(UISWTInstance.VIEW_STATISTICS,
+							VivaldiView.MSGID_PREFIX + ".6", VivaldiView.class,
+							VivaldiView.DHT_TYPE_MAIN_V6);
+				}
+
+				if (Constants.isCVSVersion()) {
+					pluginUI.addView(UISWTInstance.VIEW_STATISTICS, DHTView.MSGID_PREFIX
+							+ ".cvs", DHTView.class, DHTView.DHT_TYPE_CVS);
+					pluginUI.addView(UISWTInstance.VIEW_STATISTICS,
+							VivaldiView.MSGID_PREFIX + ".cvs", VivaldiView.class,
+							VivaldiView.DHT_TYPE_CVS);
+				}
+
+				registeredCoreSubViews = true;
+			}
+
+			UISWTViewEventListenerWrapper[] pluginViews = pluginUI == null
+					? null : pluginUI.getViewListeners(UISWTInstance.VIEW_STATISTICS);
+			for (int i = 0; i < pluginViews.length; i++) {
+				UISWTViewEventListenerWrapper l = pluginViews[i];
+				String name = l.getViewID();
+				if (name.equals(ActivityView.MSGID_PREFIX)) {
+					idxActivityTab = i;
+				} else if (name.equals(TransferStatsView.MSGID_PREFIX)) {
+					idxTransfersView = i;
+				} else if (idxDHTView == -1 && name.equals(DHTView.MSGID_PREFIX)) {
+					idxTransfersView = i;
+				}
+				if (l != null) {
+					try {
+						UISWTViewImpl view = new UISWTViewImpl(
+								UISWTInstance.VIEW_STATISTICS, name, l, null);
+						addSection(view, null);
+					} catch (Exception e) {
+						// skip
+					}
+				}
+			}
+		}
+
+		// Initialize view when user selects it
+		folder.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				CTabItem item = (CTabItem) e.item;
+				selectView(item);
+			}
+		});
+
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				if (folder == null || folder.isDisposed() || folder.getItemCount() == 0) {
+					return;
+				}
+				selectView(folder.getItem(0));
+			}
+		});
+
+		updateThread = new UpdateThread();
+		updateThread.setDaemon(true);
+		updateThread.start();
+
+		dataSourceChanged(dataSource);
+	}
+
+	private void selectView(CTabItem item) {
+		if (item == null) {
+			return;
+		}
+		if (folder.getSelection() != item) {
+			folder.setSelection(item);
+		}
+		folder.getShell().setCursor(
+				folder.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+		try {
+			// Send one last refresh to previous tab, just in case it
+			// wants to do something when view goes invisible
+			refresh();
+
+  		Object ds = item.getData("ds");
+  		if (ds == null) {
+  			ds = dataSource;
   		}
-  	}
-  }
+
+			UISWTViewCore view = (UISWTViewCore) item.getData("IView");
+    	if (view == null) {
+    		Class<?> cla = (Class<?>)item.getData("claEventListener");
+    		UISWTViewEventListener l = (UISWTViewEventListener) cla.newInstance();
+				view = new UISWTViewImpl(UISWTInstance.VIEW_MAIN, cla.getSimpleName(),
+						l, ds);
+    		item.setData("IView", view);
+    	}
+			activeView = view;
+
+			if (item.getControl() == null) {
+    		view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, ds);
+				view.initialize(folder);
+				item.setControl(view.getComposite());
+			}
+
+			item.getControl().setFocus();
+
+			UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+			if (uiFunctions != null) {
+				uiFunctions.refreshIconBar(); // For edit columns view
+			}
+
+			refresh();
+		} catch (Exception e) {
+			Debug.out(e);
+		} finally {
+			folder.getShell().setCursor(null);
+		}
+	}
+
+	// Copied from ManagerView
+	private UISWTViewCore getActiveView() {
+		return activeView;
+	}
+
+	// Copied from ManagerView
+	private void refresh() {
+		if (folder == null || folder.isDisposed())
+			return;
+
+		try {
+			UISWTViewCore view = getActiveView();
+			if (view != null) {
+				view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
+			}
+
+			CTabItem[] items = folder.getItems();
+
+			for (int i = 0; i < items.length; i++) {
+				CTabItem item = items[i];
+				view = (UISWTViewCore) item.getData("IView");
+				try {
+					if (item.isDisposed() || view == null) {
+						continue;
+					}
+					String lastTitle = item.getText();
+					String newTitle = view.getFullTitle();
+					if (lastTitle == null || !lastTitle.equals(newTitle)) {
+						item.setText(escapeAccelerators(newTitle));
+					}
+					String lastToolTip = item.getToolTipText();
+					String newToolTip = view.getFullTitle();
+					if (lastToolTip == null || !lastToolTip.equals(newToolTip)) {
+						item.setToolTipText(newToolTip);
+					}
+				} catch (Exception e) {
+					Debug.printStackTrace(e);
+				}
+			}
+
+		} catch (Exception e) {
+			Debug.printStackTrace(e);
+		}
+	}
+
+	// Copied from ManagerView
+	private static String escapeAccelerators(String str) {
+		if (str == null) {
+
+			return (str);
+		}
+
+		return (str.replaceAll("&", "&&"));
+	}
+
+	private String getFullTitle() {
+		return MessageText.getString("Stats.title.full");
+	}
+
+	private void delete() {
+		if (updateThread != null) {
+			updateThread.stopIt();
+		}
+
+		if (folder != null && !folder.isDisposed()) {
+
+			folder.setSelection(0);
+		}
+
+		//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 (Utils.isCarbon) {
+			if (folder != null && !folder.isDisposed()) {
+				CTabItem[] items = folder.getItems();
+				for (int i = 0; i < items.length; i++) {
+					if (!items[i].isDisposed())
+						items[i].dispose();
+				}
+			}
+		}
+
+		for (int i = 0; i < tabViews.size(); i++) {
+			UISWTViewCore view = tabViews.get(i);
+			if (view != null) {
+    		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+			}
+		}
+		tabViews.clear();
+
+		Utils.disposeSWTObjects(new Object[] {
+			folder,
+			parent
+		});
+	}
+
+	private void dataSourceChanged(Object newDataSource) {
+		dataSource = newDataSource;
+		if (folder == null) {
+			return;
+		}
+		if (newDataSource instanceof String) {
+			int i = -1;
+
+			if ("dht".equals(newDataSource)) {
+				i = idxDHTView;
+			} else if ("transfers".equals(newDataSource)) {
+				i = idxTransfersView;
+			} else {
+				i = idxActivityTab;
+			}
+
+			if (i >= 0) {
+				CTabItem item = folder.getItem(i);
+				selectView(item);
+			}
+
+		}
+	}
+
+	private int addSection(String titleIdPrefix, Class<?> claEventListener) {
+		return addSection(titleIdPrefix, claEventListener, null);
+	}
+
+	private int addSection(String titleIdPrefix, Class<?> claEventListener, Object ds) {
+		CTabItem item = new CTabItem(folder, SWT.NULL);
+		Messages.setLanguageText(item, titleIdPrefix + ".title.full");
+		item.setData("claEventListener", claEventListener);
+		if (ds != null) {
+			item.setData("ds", ds);
+		}
+		return folder.indexOf(item);
+	}
+
+	private void addSection(UISWTViewCore view, Object dataSource) {
+		if (view == null)
+			return;
+
+		view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, dataSource);
+
+		CTabItem item = new CTabItem(folder, SWT.NULL);
+		Messages.setLanguageText(item, view.getTitleID());
+		item.setData("IView", view);
+		tabViews.add(view);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener#eventOccurred(org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent)
+	 */
+	public boolean eventOccurred(UISWTViewEvent event) {
+		switch (event.getType()) {
+			case UISWTViewEvent.TYPE_CREATE:
+				swtView = (UISWTView) event.getData();
+				swtView.setTitle(getFullTitle());
+				break;
+
+			case UISWTViewEvent.TYPE_DESTROY:
+				delete();
+				break;
+
+			case UISWTViewEvent.TYPE_INITIALIZE:
+				initialize((Composite) event.getData());
+				break;
+
+			case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+				swtView.setTitle(getFullTitle());
+				Messages.updateLanguageForControl(folder);
+				break;
+
+			case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+				dataSourceChanged(event.getData());
+				break;
+
+			case UISWTViewEvent.TYPE_FOCUSGAINED:
+				break;
+
+			case UISWTViewEvent.TYPE_REFRESH:
+				refresh();
+				break;
+		}
+
+		return true;
+	}
+
 }
diff --git a/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java b/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java
deleted file mode 100644
index 3092871..0000000
--- a/org/gudy/azureus2/ui/swt/views/stats/TrackerStatsView.java
+++ /dev/null
@@ -1,44 +0,0 @@
-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 98fae7f..1679d38 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/TransferStatsView.java
@@ -44,9 +44,12 @@ import org.eclipse.swt.widgets.TabFolder;
 import org.eclipse.swt.widgets.TabItem;
 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.download.impl.DownloadManagerRateController;
 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.peer.PEPeerManager;
 import org.gudy.azureus2.core3.stats.transfer.OverallStats;
 import org.gudy.azureus2.core3.stats.transfer.StatsFactory;
 import org.gudy.azureus2.core3.util.AERunnable;
@@ -57,9 +60,12 @@ import org.gudy.azureus2.ui.swt.components.BufferedLabel;
 import org.gudy.azureus2.ui.swt.components.Legend;
 import org.gudy.azureus2.ui.swt.components.graphics.PingGraphic;
 import org.gudy.azureus2.ui.swt.components.graphics.Plot3D;
+import org.gudy.azureus2.ui.swt.components.graphics.SpeedGraphic;
 import org.gudy.azureus2.ui.swt.components.graphics.ValueFormater;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 
 import com.aelitis.azureus.core.AzureusCore;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
@@ -73,48 +79,66 @@ import com.aelitis.azureus.core.speedmanager.SpeedManagerPingZone;
 /**
  * 
  */
-public class TransferStatsView extends AbstractIView {
+public class TransferStatsView
+	implements UISWTViewCoreEventListener
+{
+	public static final String MSGID_PREFIX = "TransferStatsView";
 
-  GlobalManagerStats stats = null;
-  SpeedManager speedManager = null;
+	private static final int MAX_DISPLAYED_PING_MILLIS		= 1199;	// prevents us hitting 1200 and resulting in graph expanding to 1400
+	private static final int MAX_DISPLAYED_PING_MILLIS_DISP	= 1200;	// tidy display
+	
+	private GlobalManager		global_manager;
+	private GlobalManagerStats 	stats;
+	private SpeedManager 		speedManager;
   
-  OverallStats totalStats;
+	private OverallStats totalStats;
   
-  Composite mainPanel;  
+	private Composite mainPanel;  
   
-  Composite blahPanel;
-  BufferedLabel asn,estUpCap,estDownCap;
-
-  Composite generalPanel;
-  BufferedLabel nowUp, nowDown, sessionDown, sessionUp, session_ratio, sessionTime, totalDown, totalUp, total_ratio, totalTime;
+	private Composite blahPanel;
+	private BufferedLabel asn,estUpCap,estDownCap;
+	private BufferedLabel uploadBiaser;
+	
+	private Composite 		connectionPanel;
+	private BufferedLabel	upload_label, connection_label;
+	private SpeedGraphic	upload_graphic;
+	private SpeedGraphic	connection_graphic;
+	
+	private Composite generalPanel;
+	private BufferedLabel nowUp, nowDown, sessionDown, sessionUp, session_ratio, sessionTime, totalDown, totalUp, total_ratio, totalTime;
   
-  Group autoSpeedPanel;
-  StackLayout autoSpeedPanelLayout;
-  Composite autoSpeedInfoPanel;
-  Composite autoSpeedDisabledPanel;
-  PingGraphic pingGraph;
-
-  plotView[]	plot_views;
-  zoneView[] 	zone_views;
+	private Group autoSpeedPanel;
+	private StackLayout autoSpeedPanelLayout;
+	private Composite autoSpeedInfoPanel;
+	private Composite autoSpeedDisabledPanel;
+	private PingGraphic pingGraph;
+
+	private plotView[]	plot_views;
+	private zoneView[] 	zone_views;
   
-  limitToTextHelper	limit_to_text = new limitToTextHelper();
+	private limitToTextHelper	limit_to_text = new limitToTextHelper();
   
-  private final DecimalFormat formatter = new DecimalFormat( "##.#" );
+	private final DecimalFormat formatter = new DecimalFormat( "##.#" );
   
+	private boolean	initialised;
+
+	private UISWTView swtView;
   
   
   public TransferStatsView() {
   	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
-				stats = core.getGlobalManager().getStats();
-		    speedManager = core.getSpeedManager();
-		    totalStats = StatsFactory.getStats();
+				global_manager = core.getGlobalManager();
+				stats = global_manager.getStats();
+				speedManager = core.getSpeedManager();
+				totalStats = StatsFactory.getStats();
 			}
 		});
+    pingGraph = PingGraphic.getInstance();
     
   }
   
-  public void initialize(Composite composite) {
+  private void initialize(Composite composite) {
     
     mainPanel = new Composite(composite,SWT.NULL);
     GridLayout mainLayout = new GridLayout();
@@ -124,9 +148,15 @@ public class TransferStatsView extends AbstractIView {
 			public void azureusCoreRunning(AzureusCore core) {
 				Utils.execSWTThread(new AERunnable() {
 					public void runSupport() {
+						if (mainPanel == null || mainPanel.isDisposed()) {
+							return;
+						}
 						createGeneralPanel();
-						createBlahPanel();
+						createConnectionPanel();
+						createCapacityPanel();
 						createAutoSpeedPanel();
+						
+						initialised	= true;
 					}
 				});
 			}
@@ -169,11 +199,11 @@ public class TransferStatsView extends AbstractIView {
     lbl = new Label(generalPanel,SWT.NULL);
     Messages.setLanguageText(lbl,"SpeedView.stats.now");
     
-    nowDown = new BufferedLabel(generalPanel,SWT.NULL);
+    nowDown = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     nowDown.setLayoutData(gridData);
     
-    nowUp = new BufferedLabel(generalPanel,SWT.NULL);
+    nowUp = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     nowUp.setLayoutData(gridData);
     
@@ -184,19 +214,19 @@ public class TransferStatsView extends AbstractIView {
     //////// SESSION ////////
     lbl = new Label(generalPanel,SWT.NULL);
     Messages.setLanguageText(lbl,"SpeedView.stats.session");
-    sessionDown = new BufferedLabel(generalPanel,SWT.NULL);
+    sessionDown = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     sessionDown.setLayoutData(gridData);
     
-    sessionUp = new BufferedLabel(generalPanel,SWT.NULL);
+    sessionUp = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     sessionUp.setLayoutData(gridData);
     
-    session_ratio = new BufferedLabel(generalPanel,SWT.NULL);
+    session_ratio = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     session_ratio.setLayoutData(gridData);    
     
-    sessionTime = new BufferedLabel(generalPanel,SWT.NULL);
+    sessionTime = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED );
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     sessionTime.setLayoutData(gridData);
     
@@ -205,25 +235,25 @@ public class TransferStatsView extends AbstractIView {
     lbl = new Label(generalPanel,SWT.NULL);
     Messages.setLanguageText(lbl,"SpeedView.stats.total");
     
-    totalDown = new BufferedLabel(generalPanel,SWT.NULL);
+    totalDown = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     totalDown.setLayoutData(gridData);
     
-    totalUp = new BufferedLabel(generalPanel,SWT.NULL);
+    totalUp = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     totalUp.setLayoutData(gridData);
     
-    total_ratio = new BufferedLabel(generalPanel,SWT.NULL);
+    total_ratio = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     total_ratio.setLayoutData(gridData);
     
-    totalTime = new BufferedLabel(generalPanel,SWT.NULL);
+    totalTime = new BufferedLabel(generalPanel,SWT.DOUBLE_BUFFERED);
     gridData = new GridData(GridData.FILL_HORIZONTAL);
     totalTime.setLayoutData(gridData);
   }
   
   private void
-  createBlahPanel()
+  createCapacityPanel()
   {
 	  blahPanel = new Composite(mainPanel,SWT.NONE);
 	  GridData blahPanelData = new GridData(GridData.FILL_HORIZONTAL);
@@ -257,14 +287,105 @@ public class TransferStatsView extends AbstractIView {
 
 	  label = new Label(blahPanel,SWT.NONE);
 	  label = new Label(blahPanel,SWT.NONE);
+	  
+	  label = new Label(blahPanel,SWT.NONE);
+	  Messages.setLanguageText(label,"SpeedView.stats.upbias");    
+	  uploadBiaser = new BufferedLabel(blahPanel,SWT.NONE);
+	  gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  gridData.horizontalSpan = 7;
+	  uploadBiaser.setLayoutData(gridData);
+
   }
   
+  private void
+  createConnectionPanel()
+  {
+	  connectionPanel = new Composite(mainPanel,SWT.NONE);
+	  GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  connectionPanel.setLayoutData(gridData);
+
+	  GridLayout panelLayout = new GridLayout();
+	  panelLayout.numColumns = 2;
+	  connectionPanel.setLayout(panelLayout);
+
+	  Composite conn_area = new Composite( connectionPanel, SWT.NULL );
+	  gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  conn_area.setLayoutData(gridData);
+
+	  panelLayout = new GridLayout();
+	  panelLayout.numColumns = 2;
+	  conn_area.setLayout(panelLayout);
+
+	  Label label = new Label( conn_area, SWT.NULL );
+	  Messages.setLanguageText( label, "SpeedView.stats.con" );
+	  
+	  connection_label = new BufferedLabel( conn_area, SWT.DOUBLE_BUFFERED );
+	  gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  connection_label.setLayoutData(gridData);
+
+	  Composite upload_area = new Composite( connectionPanel, SWT.NULL );
+	  gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  upload_area.setLayoutData(gridData);
+
+	  panelLayout = new GridLayout();
+	  panelLayout.numColumns = 2;
+	  upload_area.setLayout(panelLayout);
+
+	  label = new Label( upload_area, SWT.NULL );
+	  Messages.setLanguageText( label, "SpeedView.stats.upload" );
+
+	  upload_label = new BufferedLabel( upload_area, SWT.DOUBLE_BUFFERED );
+	  gridData = new GridData(GridData.FILL_HORIZONTAL);
+	  upload_label.setLayoutData(gridData);
+
+
+	  	// connections
+	  
+	  Canvas connection_canvas = new Canvas(connectionPanel,SWT.NO_BACKGROUND);
+	  gridData = new GridData(GridData.FILL_BOTH);
+	  gridData.heightHint = 200;
+	  connection_canvas.setLayoutData(gridData);
+	  connection_graphic = 
+		  SpeedGraphic.getInstance(
+			new ValueFormater()
+			{
+			    public String 
+			    format(int value) 
+			    {
+			         return( String.valueOf( value ));
+			    }
+			});
+	  
+	  connection_graphic.initialize(connection_canvas);
+	  Color[] colors = connection_graphic.colors;
+
+	  connection_graphic.setLineColors( colors );
+	  
+	  	// upload queued
+	  
+	  Canvas upload_canvas = new Canvas(connectionPanel,SWT.NO_BACKGROUND);
+	  gridData = new GridData(GridData.FILL_BOTH);
+	  upload_canvas.setLayoutData(gridData);
+	  upload_graphic = 
+		  SpeedGraphic.getInstance(
+			new ValueFormater()
+			{
+			    public String 
+			    format(int value) 
+			    {
+			         return DisplayFormatters.formatByteCountToKiBEtc(value);
+			    }
+			});
+	  
+	  upload_graphic.initialize(upload_canvas);
+	  
+  }
   
   private void createAutoSpeedPanel() {
     autoSpeedPanel = new Group(mainPanel,SWT.NONE);
     GridData generalPanelData = new GridData(GridData.FILL_BOTH);
     autoSpeedPanel.setLayoutData(generalPanelData);
-    Messages.setLanguageText(autoSpeedPanel,"SpeedView.stats.autospeed");
+    Messages.setLanguageText(autoSpeedPanel,"SpeedView.stats.autospeed", new String[]{ String.valueOf( MAX_DISPLAYED_PING_MILLIS_DISP )});
     
     
     autoSpeedPanelLayout = new StackLayout();
@@ -282,7 +403,6 @@ public class TransferStatsView extends AbstractIView {
     gridData.horizontalSpan = 4;
     pingCanvas.setLayoutData(gridData);
     
-    pingGraph = PingGraphic.getInstance();
     pingGraph.initialize(pingCanvas);
     
     TabFolder folder = new TabFolder(autoSpeedInfoPanel, SWT.LEFT);
@@ -373,9 +493,18 @@ public class TransferStatsView extends AbstractIView {
     		gridData );
   }
   
-  public void delete() {
+  private void delete() {
 		Utils.disposeComposite(generalPanel);
 		Utils.disposeComposite(blahPanel);
+		
+		if ( upload_graphic != null ){
+			upload_graphic.dispose();
+		}
+		
+		if ( connection_graphic != null ){
+			connection_graphic.dispose();
+		}
+		
 		if (pingGraph != null) {
 			pingGraph.dispose();
 		}
@@ -395,27 +524,31 @@ public class TransferStatsView extends AbstractIView {
 		}
 	}
 
-  public String getFullTitle() {
-    return MessageText.getString("SpeedView.title.full"); //$NON-NLS-1$
-  }
-  
-  public Composite getComposite() {
+  private Composite getComposite() {
     return mainPanel;
   }
   
   
   
-  public void refresh() {
+  private void refresh() {
 
-    refreshGeneral();
-    
-    refreshBlahPanel();
-    
-    refreshPingPanel();
-    
+	  if ( !initialised ){
+		  return;
+	  }
+	  refreshGeneral();
+
+	  refreshCapacityPanel();
+
+	  refreshConnectionPanel();
+
+	  refreshPingPanel();
   }
 
   private void refreshGeneral() {
+	if ( stats == null ){
+		return;
+	}
+	
     int now_prot_down_rate = stats.getProtocolReceiveRate();
     int now_prot_up_rate = stats.getProtocolSendRate();
     
@@ -488,20 +621,78 @@ public class TransferStatsView extends AbstractIView {
   }  
   
   private void
-  refreshBlahPanel()
+  refreshCapacityPanel()
   {
+	  if ( speedManager == null ){
+		  return;
+	  }
+	  
 	  asn.setText(speedManager.getASN());
 
 	  estUpCap.setText(limit_to_text.getLimitText(speedManager.getEstimatedUploadCapacityBytesPerSec()));
 
 	  estDownCap.setText(limit_to_text.getLimitText(speedManager.getEstimatedDownloadCapacityBytesPerSec()));
+	  
+	  uploadBiaser.setText( DownloadManagerRateController.getString());
+  }
+  
+  private void
+  refreshConnectionPanel()
+  {
+	  if ( global_manager == null ){
+		  return;
+	  }
+	  
+	  int	total_connections	= 0;
+	  int	total_con_queued	= 0;
+	  int	total_con_blocked	= 0;
+	  int	total_con_unchoked	= 0;
+	  
+	  int	total_data_queued	= 0;
+	  
+	  List<DownloadManager> dms = global_manager.getDownloadManagers();
+	  
+	  for ( DownloadManager dm: dms ){
+		  
+		  PEPeerManager pm = dm.getPeerManager();
+		  
+		  if ( pm != null ){
+			  
+			  total_data_queued += pm.getBytesQueuedForUpload();
+			  
+			  total_connections += pm.getNbPeers() + pm.getNbSeeds();
+			  
+			  total_con_queued 	+= pm.getNbPeersWithUploadQueued();
+			  total_con_blocked	+= pm.getNbPeersWithUploadBlocked();
+			  
+			  total_con_unchoked += pm.getNbPeersUnchoked();
+		  }
+		  
+	  }
+	  
+	  connection_label.setText(
+			MessageText.getString(
+					"SpeedView.stats.con_details",
+					new String[]{ String.valueOf(total_connections), String.valueOf(total_con_unchoked), String.valueOf(total_con_queued), String.valueOf(total_con_blocked) }));
+	  
+	  connection_graphic.addIntsValue( new int[]{ total_connections, total_con_unchoked, total_con_queued, total_con_blocked });
+	  
+	  upload_label.setText(
+			MessageText.getString(
+					"SpeedView.stats.upload_details",
+					new String[]{ DisplayFormatters.formatByteCountToKiBEtc( total_data_queued )}));
+	  
+	  upload_graphic.addIntValue( total_data_queued );
+	  
+	  upload_graphic.refresh();
+	  connection_graphic.refresh();
   }
   
   private void refreshPingPanel() {
   	if (speedManager == null) {
   		return;
   	}
-    if(speedManager.isAvailable() && speedManager.isEnabled()) {
+    if(speedManager.isAvailable()){// && speedManager.isEnabled()) {
       autoSpeedPanelLayout.topControl = autoSpeedInfoPanel;
       autoSpeedPanel.layout();
    
@@ -522,35 +713,49 @@ public class TransferStatsView extends AbstractIView {
     }  
   }
   
+  /* (non-Javadoc)
+   * @see org.gudy.azureus2.ui.swt.views.stats.PeriodicViewUpdate#periodicUpdate()
+   */
   public void periodicUpdate() {
   	if (speedManager == null) {
   		return;
   	}
-    if(speedManager.isAvailable() && speedManager.isEnabled()) {
+    if(speedManager.isAvailable()){// && speedManager.isEnabled()) {
       SpeedManagerPingSource sources[] = speedManager.getPingSources();
       if(sources.length > 0) {
         int[] pings = new int[sources.length];
         for(int i = 0 ; i < sources.length ; i++) {
-          pings[i] = sources[i].getPingTime();
+        	
+        	SpeedManagerPingSource source = sources[i];
+        	
+        	if ( source != null ){
+        		
+	        	int	ping = source.getPingTime();
+	        	
+	        	ping = Math.min( ping, MAX_DISPLAYED_PING_MILLIS );
+	        	
+	        	pings[i] = ping;
+        	}
         }
         pingGraph.addIntsValue(pings);
         
-        for (int i=0;i<plot_views.length;i++){
-        	
-        	plot_views[i].update();
+        if (plot_views != null) {
+          for (int i=0;i<plot_views.length;i++){
+          	
+          	plot_views[i].update();
+          }
         }
         
-        for (int i=0;i<zone_views.length;i++){
-        	
-        	zone_views[i].update();
+        if (zone_views != null) {
+          for (int i=0;i<zone_views.length;i++){
+          	
+          	zone_views[i].update();
+          }
         }
       }
     }
   }
   
-  public String getData() {
-    return "TransferStatsView.title.full";
-  }
 
   protected String
   getMapperTitle(
@@ -588,6 +793,8 @@ public class TransferStatsView extends AbstractIView {
 		  
 		  plotGraph = new Plot3D( _labels, _formatters );
 
+		  plotGraph.setMaxZ( MAX_DISPLAYED_PING_MILLIS );
+		  
 		  plotGraph.initialize(_canvas);
 	  }
 	  
@@ -768,7 +975,7 @@ public class TransferStatsView extends AbstractIView {
 				  double x_ratio = (double)usable_width/max_x;
 				  double y_ratio = (double)usable_height/max_y;
 				  
-				  List	texts = new ArrayList();
+				  List<Object[]>	texts = new ArrayList<Object[]>();
 				  
 				  for (int i=0;i<zones.length;i++){
 		
@@ -817,11 +1024,11 @@ public class TransferStatsView extends AbstractIView {
 									
 							  	// check for overlap with existing and delete older
 							  
-							  Iterator it = texts.iterator();
+							  Iterator<Object[]> it = texts.iterator();
 							  
 							  while( it.hasNext()){
 								  
-								  Object[]	old = (Object[])it.next();
+								  Object[]	old = it.next();
 								  
 								  Rectangle old_coords = (Rectangle)old[1];
 								  
@@ -842,7 +1049,7 @@ public class TransferStatsView extends AbstractIView {
 				  
 				  for (int i=(text_num>100?(text_num-100):0);i<text_num;i++){
 					  
-					  Object[]	entry = (Object[])texts.get(i);
+					  Object[]	entry = texts.get(i);
 					  
 					  String	str = String.valueOf(entry[0]);
 					  
@@ -1227,5 +1434,42 @@ public class TransferStatsView extends AbstractIView {
 		  return( msg_unlimited );
 	  }
   }
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(MSGID_PREFIX + ".title.full"));
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+        
+      case StatsView.EVENT_PERIODIC_UPDATE:
+      	periodicUpdate();
+      	break;
+    }
+
+    return true;
+  }
 }
 
diff --git a/org/gudy/azureus2/ui/swt/views/stats/VivaldiPanel.java b/org/gudy/azureus2/ui/swt/views/stats/VivaldiPanel.java
index 25ff7e1..70613bc 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/VivaldiPanel.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/VivaldiPanel.java
@@ -22,7 +22,6 @@
  */
 package org.gudy.azureus2.ui.swt.views.stats;
 
-import java.util.Iterator;
 import java.util.List;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.*;
@@ -57,7 +56,7 @@ public class VivaldiPanel {
   private int yDown;
   
   private boolean antiAliasingAvailable = true;
-	private List lastContacts;
+	private List<DHTControlContact> lastContacts;
 	private DHTTransportContact lastSelf;
 	
 	private Image img;
@@ -179,13 +178,13 @@ public class VivaldiPanel {
 
     canvas.addMouseMoveListener(new MouseMoveListener() {
       public void mouseMove(MouseEvent event) {
-        if(mouseLeftDown) {
+        if(mouseLeftDown && (event.stateMask & SWT.MOD4) == 0) {
           int deltaX = event.x - xDown;
           int deltaY = event.y - yDown;
-          int width = scale.width;
-          int height = scale.height;
-          float ratioX = (float) (scale.saveMaxX - scale.saveMinX) / (float) width;
-          float ratioY = (float) (scale.saveMaxY - scale.saveMinY) / (float) height;
+          float width = scale.width;
+          float height = scale.height;
+          float ratioX = (scale.saveMaxX - scale.saveMinX) / width;
+          float ratioY = (scale.saveMaxY - scale.saveMinY) / height;
           float realDeltaX = deltaX * ratioX;
           float realDeltaY  = deltaY * ratioY;
           scale.minX = scale.saveMinX - realDeltaX;
@@ -194,7 +193,7 @@ public class VivaldiPanel {
           scale.maxY = scale.saveMaxY - realDeltaY;
           refreshContacts(lastContacts, lastSelf);
         }
-        if(mouseRightDown) {
+        if(mouseRightDown || (mouseLeftDown && (event.stateMask & SWT.MOD4) > 0)) {
           int deltaX = event.x - xDown;
           scale.rotation = scale.saveRotation - (float) deltaX / 100;
 
@@ -241,7 +240,8 @@ public class VivaldiPanel {
     canvas.setLayoutData(data);
   }
   
-  public void refreshContacts(List contacts,DHTTransportContact self) {
+	public void refreshContacts(List<DHTControlContact> contacts,
+			DHTTransportContact self) {
   	if (contacts == null || self == null) {
   		return;
   	}
@@ -304,9 +304,7 @@ public class VivaldiPanel {
     gc.setBackground(black); // Color of the squares
 
     // Draw all known positions of other contacts
-    Iterator iter = contacts.iterator();
-    while(iter.hasNext()) {
-      DHTControlContact contact = (DHTControlContact) iter.next();
+    for (DHTControlContact contact : contacts) {
       DHTNetworkPosition _position = contact.getTransportContact().getNetworkPosition(DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1);
       if ( _position == null ){
     	  continue;
@@ -330,7 +328,7 @@ public class VivaldiPanel {
     canvas.redraw();
   }
   
-  public void refresh(List vivaldiPositions) {
+  public void refresh(List<VivaldiPosition> vivaldiPositions) {
     if(canvas.isDisposed()) return;
     Rectangle size = canvas.getBounds();
     
@@ -355,9 +353,7 @@ public class VivaldiPanel {
     
     
     
-    Iterator iter = vivaldiPositions.iterator();
-    while(iter.hasNext()) {
-      VivaldiPosition position  = (VivaldiPosition)iter.next();
+    for (VivaldiPosition position : vivaldiPositions) {
       HeightCoordinatesImpl coord = (HeightCoordinatesImpl) position.getCoordinates();
       
       float error = position.getErrorEstimate() - VivaldiPosition.ERROR_MIN;
diff --git a/org/gudy/azureus2/ui/swt/views/stats/VivaldiView.java b/org/gudy/azureus2/ui/swt/views/stats/VivaldiView.java
index 5bc6ac0..36644bc 100644
--- a/org/gudy/azureus2/ui/swt/views/stats/VivaldiView.java
+++ b/org/gudy/azureus2/ui/swt/views/stats/VivaldiView.java
@@ -28,50 +28,45 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FillLayout;
 import org.eclipse.swt.widgets.Composite;
 
+import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.util.Debug;
 import org.gudy.azureus2.plugins.PluginInterface;
-import org.gudy.azureus2.ui.swt.views.AbstractIView;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
 
 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.dht.DHT;
+import com.aelitis.azureus.core.dht.control.DHTControlContact;
 import com.aelitis.azureus.plugins.dht.DHTPlugin;
 
 public class VivaldiView 
-  extends AbstractIView
+	implements UISWTViewEventListener
 {
   public static final int DHT_TYPE_MAIN   = DHT.NW_MAIN;
   public static final int DHT_TYPE_CVS    = DHT.NW_CVS;
   public static final int DHT_TYPE_MAIN_V6  = DHT.NW_MAIN_V6;
+	public static final String MSGID_PREFIX = "VivaldiView";
 
   DHT dht;
   Composite panel;
   VivaldiPanel drawPanel;
 	private final boolean autoAlpha;
-  private final int dht_type;
+  private int dht_type;
   private AzureusCore core;
+	private UISWTView swtView;
   
 
-  public VivaldiView(int dht_type, boolean autoAlpha) {
-    this.dht_type = dht_type;
+  public VivaldiView(boolean autoAlpha) {
   	this.autoAlpha = autoAlpha;
 
-  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
-
-			public void azureusCoreRunning(AzureusCore core) {
-				VivaldiView.this.core = core;
-				init(core);
-			}
-		});
   }
 
-  public VivaldiView(int dht_type) {
-  	this(dht_type, false);
-  }
-  
-  public VivaldiView(boolean autoAlpha) {
-  	this(DHT_TYPE_MAIN, autoAlpha);
+  public VivaldiView() {
+  	this(false);
   }
   
   private void init(AzureusCore core) {
@@ -101,18 +96,26 @@ public class VivaldiView
     }
   }
   
-  public void initialize(Composite composite) {
-    panel = new Composite(composite,SWT.NULL);
+  private void initialize(Composite composite) {
+  	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
+
+			public void azureusCoreRunning(AzureusCore core) {
+				VivaldiView.this.core = core;
+				init(core);
+			}
+		});
+
+  	panel = new Composite(composite,SWT.NULL);
     panel.setLayout(new FillLayout());    
     drawPanel = new VivaldiPanel(panel);    
   	drawPanel.setAutoAlpha(autoAlpha);
   }
   
-  public Composite getComposite() {
+  private Composite getComposite() {
    return panel;
   }
   
-  public void refresh() {
+  private void refresh() {
   	if (dht == null) {
   		if (core != null) {
   			// keep trying until dht is avail
@@ -123,16 +126,12 @@ public class VivaldiView
   	}
   	
     if(dht != null) {
-      List l = dht.getControl().getContacts();
+      List<DHTControlContact> l = dht.getControl().getContacts();
       drawPanel.refreshContacts(l,dht.getControl().getTransport().getLocalContact());
     }
   }
   
-  public String getData() {
-    return( getFullTitle());
-  }
-
-  public String getFullTitle() {
+  private String getTitleID() {
     if ( dht_type == DHT_TYPE_MAIN ){
 
       return( "VivaldiView.title.full" );
@@ -146,8 +145,51 @@ public class VivaldiView
     }
   }
   
-	public void delete() {
-		drawPanel.delete();
-		super.delete();
+  private void delete() {
+		if (drawPanel != null) {
+			drawPanel.delete();
+		}
 	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+    switch (event.getType()) {
+      case UISWTViewEvent.TYPE_CREATE:
+      	swtView = (UISWTView)event.getData();
+      	swtView.setTitle(MessageText.getString(getTitleID()));
+        break;
+
+      case UISWTViewEvent.TYPE_DESTROY:
+        delete();
+        break;
+
+      case UISWTViewEvent.TYPE_INITIALIZE:
+        initialize((Composite)event.getData());
+        break;
+
+      case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+      	Messages.updateLanguageForControl(getComposite());
+    		if (swtView != null) {
+    			swtView.setTitle(MessageText.getString(getTitleID()));
+    		}
+        break;
+
+      case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+      	if (event.getData() instanceof Number) {
+      		dht_type = ((Number) event.getData()).intValue();
+      		if (swtView != null) {
+          	swtView.setTitle(MessageText.getString(getTitleID()));
+      		}
+      	}
+        break;
+        
+      case UISWTViewEvent.TYPE_FOCUSGAINED:
+      	break;
+        
+      case UISWTViewEvent.TYPE_REFRESH:
+        refresh();
+        break;
+    }
+
+    return true;
+  }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableCellSWT.java b/org/gudy/azureus2/ui/swt/views/table/TableCellSWT.java
index e9aed7c..03b6740 100644
--- a/org/gudy/azureus2/ui/swt/views/table/TableCellSWT.java
+++ b/org/gudy/azureus2/ui/swt/views/table/TableCellSWT.java
@@ -37,10 +37,6 @@ import org.gudy.azureus2.ui.swt.components.BufferedTableItem;
  */
 public interface TableCellSWT extends com.aelitis.azureus.ui.common.table.TableCellCore
 {
-	/**
-	 * @return
-	 */
-	BufferedTableItem getBufferedTableItem();
 
 	/** 
 	 * Change the cell's foreground color.
@@ -76,6 +72,8 @@ public interface TableCellSWT extends com.aelitis.azureus.ui.common.table.TableC
 
 	public Rectangle getBounds();
 
+	public Rectangle getBoundsOnDisplay();
+
 	public boolean setGraphic(Image img);
 
 	public Image getGraphicSWT();
@@ -115,16 +113,6 @@ public interface TableCellSWT extends com.aelitis.azureus.ui.common.table.TableC
 	 * @since 3.1.1.1
 	 */
 	void setTextAlpha(int textOpacity);
-	
-		/**
-		 * Sets tooltip to be shown in absence of an explicit one
-		 * @param str
-		 */
-	
-	public void
-	setDefaultToolTip(
-		Object	tt );
-	
-	public Object
-	getDefaultToolTip();
+
+	void setMouseOver(boolean b);
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableColumnCoreCreationListener.java b/org/gudy/azureus2/ui/swt/views/table/TableColumnCoreCreationListener.java
deleted file mode 100644
index 99ac91c..0000000
--- a/org/gudy/azureus2/ui/swt/views/table/TableColumnCoreCreationListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Created on Sep 20, 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 org.gudy.azureus2.ui.swt.views.table;
-
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-
-import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener;
-
-/**
- * @author TuxPaper
- * @created Sep 20, 2008
- *
- */
-public interface TableColumnCoreCreationListener
-	extends TableColumnCreationListener
-{
-	public TableColumnCore createTableColumnCore(Class forDataSourceType,
-			String tableID, String columnID);
-}
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableColumnOrTreeColumn.java b/org/gudy/azureus2/ui/swt/views/table/TableColumnOrTreeColumn.java
new file mode 100644
index 0000000..e740955
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableColumnOrTreeColumn.java
@@ -0,0 +1,113 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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;
+
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public interface TableColumnOrTreeColumn
+{
+
+	public Image getImage();
+
+	public String getText();
+
+	public void addControlListener(ControlListener listener);
+
+	public void addListener(int eventType, Listener listener);
+
+	public void addSelectionListener(SelectionListener listener);
+
+	public void addDisposeListener(DisposeListener listener);
+
+	public boolean getMoveable();
+
+	public TableOrTreeSWT getParent();
+
+	public boolean getResizable();
+
+	public String getToolTipText();
+
+	public int getWidth();
+
+	public void dispose();
+
+	public boolean equals(Object obj);
+
+	public int getAlignment();
+
+	public Object getData();
+
+	public Object getData(String key);
+
+	public Display getDisplay();
+
+	public Listener[] getListeners(int eventType);
+
+	public int getStyle();
+
+	public int hashCode();
+
+	public void pack();
+
+	public void removeControlListener(ControlListener listener);
+
+	public void removeSelectionListener(SelectionListener listener);
+
+	public void setAlignment(int alignment);
+
+	public void setImage(Image image);
+
+	public void setMoveable(boolean moveable);
+
+	public void setResizable(boolean resizable);
+
+	public void setText(String string);
+
+	public void setToolTipText(String string);
+
+	public boolean isDisposed();
+
+	public boolean isListening(int eventType);
+
+	public void setWidth(int width);
+
+	public void notifyListeners(int eventType, Event event);
+
+	public void removeListener(int eventType, Listener listener);
+
+	public void removeDisposeListener(DisposeListener listener);
+
+	public void setData(Object data);
+
+	public void setData(String key, Object value);
+
+	public String toString();
+
+	public Item getColumn();
+
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableItemOrTreeItem.java b/org/gudy/azureus2/ui/swt/views/table/TableItemOrTreeItem.java
new file mode 100644
index 0000000..1bd7925
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableItemOrTreeItem.java
@@ -0,0 +1,157 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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;
+
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+
+/**
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public interface TableItemOrTreeItem
+{
+
+	public void addListener(int eventType, Listener listener);
+
+	public void addDisposeListener(DisposeListener listener);
+
+	public void clear(int index, boolean all);
+
+	public void clearAll(boolean all);
+
+	public void dispose();
+
+	public boolean equals(Object obj);
+
+	public Color getBackground();
+
+	public Color getBackground(int index);
+
+	public Rectangle getBounds();
+
+	public Rectangle getBounds(int index);
+
+	public Object getData();
+
+	public Object getData(String key);
+
+	public Display getDisplay();
+
+	public boolean getChecked();
+
+	public Listener[] getListeners(int eventType);
+
+	public boolean getExpanded();
+
+	public int getStyle();
+
+	public Font getFont();
+
+	public Font getFont(int index);
+
+	public Color getForeground();
+
+	public Color getForeground(int index);
+
+	public boolean getGrayed();
+
+	public void notifyListeners(int eventType, Event event);
+
+	public TableItemOrTreeItem getItem(int index);
+
+	public int getItemCount();
+
+	public TableItemOrTreeItem[] getItems();
+
+	public Image getImage();
+
+	public Image getImage(int index);
+
+	public Rectangle getImageBounds(int index);
+
+	public void removeListener(int eventType, Listener listener);
+
+	public TableOrTreeSWT getParent();
+
+	public TableItemOrTreeItem getParentItem();
+
+	public String getText();
+
+	public String getText(int index);
+
+	public void removeDisposeListener(DisposeListener listener);
+
+	public Rectangle getTextBounds(int index);
+
+	public int hashCode();
+
+	public boolean isDisposed();
+
+	public boolean isListening(int eventType);
+
+	public int indexOf(TableItemOrTreeItem item);
+
+	public void removeAll();
+
+	public void setBackground(Color color);
+
+	public void setBackground(int index, Color color);
+
+	public void setData(Object data);
+
+	public void setData(String key, Object value);
+
+	public void setChecked(boolean checked);
+
+	public void setExpanded(boolean expanded);
+
+	public void setFont(Font font);
+
+	public String toString();
+
+	public void setFont(int index, Font font);
+
+	public void setForeground(Color color);
+
+	public void setForeground(int index, Color color);
+
+	public void setGrayed(boolean grayed);
+
+	public void setImage(Image[] images);
+
+	public void setImage(int index, Image image);
+
+	public void setImage(Image image);
+
+	public void setItemCount(int count);
+
+	public void setText(String[] strings);
+
+	public void setText(int index, String string);
+
+	public void setText(String string);
+
+	///////////////
+	
+	public Item getItem();
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableOrTreeSWT.java b/org/gudy/azureus2/ui/swt/views/table/TableOrTreeSWT.java
new file mode 100644
index 0000000..f452e89
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableOrTreeSWT.java
@@ -0,0 +1,394 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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;
+
+import org.eclipse.swt.accessibility.Accessible;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+
+/**
+ * Provides caller with access to a tree or table without needing to know
+ * which it's operating on
+ * 
+ * @author TuxPaper
+ * @created May 3, 2010
+ */
+public interface TableOrTreeSWT
+{
+
+	public Rectangle computeTrim(int x, int y, int width, int height);
+
+	public void addControlListener(ControlListener listener);
+
+	public void changed(Control[] changed);
+
+	public void addDragDetectListener(DragDetectListener listener);
+
+	public Rectangle getClientArea();
+
+	public void addListener(int eventType, Listener listener);
+
+	public void addFocusListener(FocusListener listener);
+
+	public ScrollBar getHorizontalBar();
+
+	public void addDisposeListener(DisposeListener listener);
+
+	public ScrollBar getVerticalBar();
+
+	public void addHelpListener(HelpListener listener);
+
+	public void addKeyListener(KeyListener listener);
+
+	public void addMenuDetectListener(MenuDetectListener listener);
+
+	public void addMouseListener(MouseListener listener);
+
+	public void addSelectionListener(SelectionListener listener);
+
+	public void addMouseTrackListener(MouseTrackListener listener);
+
+	public void addMouseMoveListener(MouseMoveListener listener);
+
+	public void addMouseWheelListener(MouseWheelListener listener);
+
+	public int getBackgroundMode();
+
+	public void addPaintListener(PaintListener listener);
+
+	public Control[] getChildren();
+
+	public void addTraverseListener(TraverseListener listener);
+
+	public void dispose();
+
+	public Layout getLayout();
+
+	public Control[] getTabList();
+
+	public boolean getLayoutDeferred();
+
+	public Point computeSize(int wHint, int hHint);
+
+	public boolean isLayoutDeferred();
+
+	public Object getData();
+
+	public void layout();
+
+	public Object getData(String key);
+
+	public void layout(boolean changed);
+
+	public Display getDisplay();
+
+	public Listener[] getListeners(int eventType);
+
+	public void layout(boolean changed, boolean all);
+
+	public int getStyle();
+
+	public boolean dragDetect(Event event);
+
+	public boolean isListening(int eventType);
+
+	public boolean dragDetect(MouseEvent event);
+
+	public void notifyListeners(int eventType, Event event);
+
+	public void removeListener(int eventType, Listener listener);
+
+	public void removeDisposeListener(DisposeListener listener);
+
+	public void setBackgroundMode(int mode);
+
+	public boolean setFocus();
+
+	public void setLayout(Layout layout);
+
+	public int getBorderWidth();
+
+	public void setLayoutDeferred(boolean defer);
+
+	public Rectangle getBounds();
+
+	public void setTabList(Control[] tabList);
+
+	public void setData(Object data);
+
+	public Cursor getCursor();
+
+	public void setData(String key, Object value);
+
+	public boolean getDragDetect();
+
+	public boolean getEnabled();
+
+	public Font getFont();
+
+	public Color getForeground();
+
+	public Object getLayoutData();
+
+	public Point getLocation();
+
+	public Menu getMenu();
+
+	public Monitor getMonitor();
+
+	public Composite getParent();
+
+	public Region getRegion();
+
+	public Shell getShell();
+
+	public Point getSize();
+
+	public String getToolTipText();
+
+	public boolean getVisible();
+
+	public String toString();
+
+	public boolean isEnabled();
+
+	public boolean isFocusControl();
+
+	public boolean isReparentable();
+
+	public boolean isVisible();
+
+	public void moveAbove(Control control);
+
+	public void moveBelow(Control control);
+
+	public void pack();
+
+	public void pack(boolean changed);
+
+	public void clear(int index, boolean all);
+
+	public boolean print(GC gc);
+
+	public void clearAll(boolean all);
+
+	public Point computeSize(int wHint, int hHint, boolean changed);
+
+	public void redraw();
+
+	public void redraw(int x, int y, int width, int height, boolean all);
+
+	public void removeControlListener(ControlListener listener);
+
+	public void removeDragDetectListener(DragDetectListener listener);
+
+	public void removeFocusListener(FocusListener listener);
+
+	public void removeHelpListener(HelpListener listener);
+
+	public void removeKeyListener(KeyListener listener);
+
+	public void removeMenuDetectListener(MenuDetectListener listener);
+
+	public void removeMouseTrackListener(MouseTrackListener listener);
+
+	public void removeMouseListener(MouseListener listener);
+
+	public void removeMouseMoveListener(MouseMoveListener listener);
+
+	public void removeMouseWheelListener(MouseWheelListener listener);
+
+	public void removePaintListener(PaintListener listener);
+
+	public void removeTraverseListener(TraverseListener listener);
+
+	public void deselect(TableItemOrTreeItem item);
+
+	public void setBackground(Color color);
+
+	public void deselectAll();
+
+	public boolean equals(Object obj);
+
+	public boolean forceFocus();
+
+	public Accessible getAccessible();
+
+	public Color getBackground();
+
+	public Image getBackgroundImage();
+
+	public void setBackgroundImage(Image image);
+
+	public void setBounds(int x, int y, int width, int height);
+
+	public void setBounds(Rectangle rect);
+
+	public void setCapture(boolean capture);
+
+	public void setCursor(Cursor cursor);
+
+	public void setDragDetect(boolean dragDetect);
+
+	public void setEnabled(boolean enabled);
+
+	public void setForeground(Color color);
+
+	public void setLayoutData(Object layoutData);
+
+	public void setLocation(int x, int y);
+
+	public void setLocation(Point location);
+
+	public void setMenu(Menu menu);
+
+	public int getGridLineWidth();
+
+	public int getHeaderHeight();
+
+	public boolean getHeaderVisible();
+
+	public void setRegion(Region region);
+
+	public void setSize(int width, int height);
+
+	public TableColumnOrTreeColumn getColumn(int index);
+
+	public void setSize(Point size);
+
+	public int getColumnCount();
+
+	public void setToolTipText(String string);
+
+	public int[] getColumnOrder();
+
+	public void setVisible(boolean visible);
+
+	public TableColumnOrTreeColumn[] getColumns();
+
+	public TableItemOrTreeItem getItem(int index);
+
+	public Point toControl(int x, int y);
+
+	public Point toControl(Point point);
+
+	public TableItemOrTreeItem getItem(Point point);
+
+	public Point toDisplay(int x, int y);
+
+	public Point toDisplay(Point point);
+
+	public int getItemCount();
+
+	public int getItemHeight();
+
+	public TableItemOrTreeItem[] getItems();
+
+	public boolean getLinesVisible();
+
+	public TableItemOrTreeItem getParentItem();
+
+	public TableItemOrTreeItem[] getSelection();
+
+	public int getSelectionCount();
+
+	public TableColumnOrTreeColumn getSortColumn();
+
+	public int getSortDirection();
+
+	public TableItemOrTreeItem getTopItem();
+
+	public int hashCode();
+
+	public boolean isDisposed();
+
+	public void update();
+
+	public int indexOf(TableColumnOrTreeColumn column);
+
+	public int indexOf(TableItemOrTreeItem item);
+
+	public boolean setParent(Composite parent);
+
+	public void removeAll();
+
+	public void removeSelectionListener(SelectionListener listener);
+
+	public void removeTreeListener(TreeListener listener);
+
+	public void setInsertMark(TableItemOrTreeItem item, boolean before);
+
+	public void setItemCount(int count);
+
+	public void setLinesVisible(boolean show);
+
+	public void select(TableItemOrTreeItem item);
+
+	public void selectAll();
+
+	public void setColumnOrder(int[] order);
+
+	public void setFont(Font font);
+
+	public void setHeaderVisible(boolean show);
+
+	public void setRedraw(boolean redraw);
+
+	public void setSelection(TableItemOrTreeItem item);
+
+	public void setSelection(TableItemOrTreeItem[] items);
+
+	public void setSortColumn(TableColumnOrTreeColumn column);
+
+	public void setSortDirection(int direction);
+
+	public void setTopItem(TableItemOrTreeItem item);
+
+	public void showColumn(TableColumnOrTreeColumn column);
+
+	public void showItem(TableItemOrTreeItem item);
+
+	public void showSelection();
+
+	////////////
+	
+	public Composite getComposite();
+
+	public int getTopIndex();
+
+	public int getSelectionIndex();
+
+	public int[] getSelectionIndices();
+
+	public void setSelection(int[] newSelectedRowIndices);
+
+	public void select(int[] newSelectedRowIndices);
+
+	public boolean isSelected(TableItemOrTreeItem item);
+
+	boolean equalsTableOrTree(TableOrTreeSWT tt);
+	
+	public TableItemOrTreeItem createNewItem(int style);
+
+	public TableColumnOrTreeColumn createNewColumn(int style);
+
+	public int indexOf(Widget item);
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableRowSWT.java b/org/gudy/azureus2/ui/swt/views/table/TableRowSWT.java
index 5af436d..5929adf 100644
--- a/org/gudy/azureus2/ui/swt/views/table/TableRowSWT.java
+++ b/org/gudy/azureus2/ui/swt/views/table/TableRowSWT.java
@@ -24,17 +24,14 @@ import com.aelitis.azureus.ui.common.table.TableRowCore;
 import org.eclipse.swt.graphics.*;
 
 /**
+ * SWT specifics interfaces for TableRow
+ * 
  * @author TuxPaper
  * @created Jan 22, 2007
  *
  */
 public interface TableRowSWT extends TableRowCore
 {
-	/** re-paint an area of the row
-	 *
-	 * @param gc Area needing repainting, and GC object one can use to repaint it
-	 */
-	public void doPaint(GC gc);
 
 	public boolean setIconSize(Point pt);
 
@@ -48,17 +45,11 @@ public interface TableRowSWT extends TableRowCore
 	 *
 	 * @param c new color
 	 */
-	public void setForeground(Color c);
+	public boolean setForeground(Color c);
 
 	public Color getBackground();
 
 	/**
-	 * @param gc
-	 * @param b
-	 */
-	public void doPaint(GC gc, boolean bVisible);
-
-	/**
 	 * @param cellName
 	 * @return
 	 */
@@ -96,4 +87,15 @@ public interface TableRowSWT extends TableRowCore
 	 * @since 3.1.1.1
 	 */
 	public boolean setAlpha(int alpha);
+
+	/**
+	 * @param selected
+	 *
+	 * @since 4.4.0.5
+	 */
+	void setWidgetSelected(boolean selected);
+
+	void setShown(boolean shown, boolean force);
+
+	public int getFullHeight();
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableRowSWTPaintListener.java b/org/gudy/azureus2/ui/swt/views/table/TableRowSWTPaintListener.java
new file mode 100644
index 0000000..30eb0a0
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableRowSWTPaintListener.java
@@ -0,0 +1,37 @@
+/**
+ * Created on May 6, 2010
+ *
+ * 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;
+
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+
+
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+
+/**
+ * @author TuxPaper
+ * @created May 6, 2010
+ *
+ */
+public interface TableRowSWTPaintListener
+{
+	public void rowPaint(GC gc, TableRowCore row, TableColumnCore column,
+			Rectangle cellArea);
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java b/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java
index fc1931f..71e432e 100644
--- a/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java
+++ b/org/gudy/azureus2/ui/swt/views/table/TableViewFilterCheck.java
@@ -18,15 +18,9 @@
  
 package org.gudy.azureus2.ui.swt.views.table;
 
-
 /**
- * @author TuxPaper
- * @created Oct 4, 2009
- *
+ * @deprecated Use common one
  */
-public interface TableViewFilterCheck<DATASOURCETYPE>
+public interface TableViewFilterCheck<DATASOURCETYPE> extends com.aelitis.azureus.ui.common.table.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 199c13e..3216c03 100644
--- a/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java
+++ b/org/gudy/azureus2/ui/swt/views/table/TableViewSWT.java
@@ -24,17 +24,15 @@ import org.eclipse.swt.dnd.DragSource;
 import org.eclipse.swt.dnd.DropTarget;
 import org.eclipse.swt.dnd.DropTargetEvent;
 import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Text;
 
-import org.gudy.azureus2.ui.swt.views.IView;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.views.table.painted.TableRowPainted;
 
-import com.aelitis.azureus.ui.common.table.TableRowCore;
-import com.aelitis.azureus.ui.common.table.TableView;
-
-import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
+import com.aelitis.azureus.ui.common.table.*;
 
 /**
  * @author TuxPaper
@@ -44,9 +42,6 @@ import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
 public interface TableViewSWT<DATASOURCETYPE>
 	extends TableView<DATASOURCETYPE>
 {
-	/** Helpful output when trying to debug add/removal of rows */
-	public final static boolean DEBUGADDREMOVE = System.getProperty("debug.swt.table.addremove", "0").equals("1");
-
 	void addKeyListener(KeyListener listener);
 
 	public void addMenuFillListener(TableViewSWTMenuFillListener l);
@@ -57,11 +52,6 @@ public interface TableViewSWT<DATASOURCETYPE>
 
 	public Composite getComposite();
 
-	/**
-	 * @return
-	 */
-	IView[] getCoreTabViews();
-
 	TableRowCore getRow(DropTargetEvent event);
 
 	/**
@@ -78,10 +68,9 @@ public interface TableViewSWT<DATASOURCETYPE>
 
 	/**
 	 * @param image
-	 * @param shellOffset
 	 * @return
 	 */
-	Image obfusticatedImage(Image image, Point shellOffset);
+	Image obfusticatedImage(Image image);
 
 	/**
 	 * @param listener
@@ -101,18 +90,13 @@ public interface TableViewSWT<DATASOURCETYPE>
 	
 
 	/**
-	 * @param coreTabViews
-	 */
-	void setCoreTabViews(IView[] coreTabViews);
-
-	/**
 	 * @param x
 	 * @param y
 	 * @return
 	 *
 	 * @since 3.0.0.7
 	 */
-	TableCellSWT getTableCell(int x, int y);
+	TableCellCore getTableCell(int x, int y);
 
 	/**
 	 * @return Offset potision of the cursor relative to the cell the cursor is in
@@ -147,9 +131,16 @@ public interface TableViewSWT<DATASOURCETYPE>
 	 *
 	 * @since 4.1.0.9
 	 */
-	void enableFilterCheck(Text txtFilter, TableViewFilterCheck<DATASOURCETYPE> filterCheck);
+	void enableFilterCheck(Text txtFilter, com.aelitis.azureus.ui.common.table.TableViewFilterCheck<DATASOURCETYPE> filterCheck);
 
 	/**
+	 * @since 4.7.0.1
+	 */
+	void disableFilterCheck();
+	
+	boolean isFiltered( DATASOURCETYPE ds );
+	
+	/**
 	 * @param s
 	 *
 	 * @since 4.1.0.8
@@ -166,4 +157,105 @@ public interface TableViewSWT<DATASOURCETYPE>
 	boolean enableSizeSlider(Composite composite, int min, int max);
 
 	void disableSizeSlider();
+
+	/**
+	 * @param listener
+	 *
+	 * @since 4.2.0.3
+	 */
+	void addRowPaintListener(TableRowSWTPaintListener listener);
+
+	/**
+	 * @param listener
+	 *
+	 * @since 4.2.0.3
+	 */
+	void removeRowPaintListener(TableRowSWTPaintListener listener);
+
+	/**
+	 * @param listener
+	 *
+	 * @since 4.4.0.7
+	 */
+	void removeRowMouseListener(TableRowMouseListener listener);
+
+	/**
+	 * @param listener
+	 *
+	 * @since 4.4.0.7
+	 */
+	void addRowMouseListener(TableRowMouseListener listener);
+
+	TableOrTreeSWT getTableOrTreeSWT();
+
+	/**
+	 * @since 4.5.0.5
+	 */
+	void refilter();
+
+	/**
+	 * @param menuEnabled
+	 *
+	 * @since 4.6.0.5
+	 */
+	void setMenuEnabled(boolean menuEnabled);
+
+	/**
+	 * @return
+	 *
+	 * @since 4.6.0.5
+	 */
+	boolean isMenuEnabled();
+
+	void packColumns();
+
+	void visibleRowsChanged();
+
+	void invokePaintListeners(GC gc, TableRowCore row, TableColumnCore column,
+			Rectangle cellArea);
+
+	boolean isVisible();
+
+	TableColumnCore getTableColumnByOffset(int x);
+
+	TableRowSWT getTableRow(int x, int y, boolean anyX);
+
+	public void setRowSelected(final TableRowCore row, boolean selected, boolean trigger);
+
+	void editCell(int column, int row);
+
+	void invokeRowMouseListener(TableRowMouseEvent event);
+
+	int getColumnNo(int iMouseX);
+
+	boolean isDragging();
+
+	KeyListener[] getKeyListeners();
+
+	TableViewSWTFilter getSWTFilter();
+
+	void triggerDefaultSelectedListeners(TableRowCore[] selectedRows,
+			int stateMask);
+
+	void sortColumn(boolean bForceDataRefresh);
+
+	void openFilterDialog();
+
+	boolean isSingleSelection();
+
+	void expandColumns();
+
+	void showColumnEditor();
+
+	boolean isTabViewsEnabled();
+
+	Composite createMainPanel(Composite composite);
+
+	void tableInvalidate();
+
+	void showRow(TableRowCore rowToShow);
+
+	TableRowCore getRowQuick(int index);
+
+	void invokeRefreshListeners(TableRowCore row);
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/TableViewSWTFilter.java b/org/gudy/azureus2/ui/swt/views/table/TableViewSWTFilter.java
new file mode 100644
index 0000000..739edf1
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/TableViewSWTFilter.java
@@ -0,0 +1,12 @@
+package org.gudy.azureus2.ui.swt.views.table;
+
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.widgets.Text;
+
+import com.aelitis.azureus.ui.common.table.impl.TableViewImpl.filter;
+
+public class TableViewSWTFilter<DATASOURCETYPE> extends filter {
+	public Text widget = null;
+
+	public ModifyListener widgetModifyListener;
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/FakeTableCell.java b/org/gudy/azureus2/ui/swt/views/table/impl/FakeTableCell.java
index 4dcbcb1..50872d5 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/FakeTableCell.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/FakeTableCell.java
@@ -22,6 +22,7 @@ package org.gudy.azureus2.ui.swt.views.table.impl;
 
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.dnd.Clipboard;
@@ -37,9 +38,7 @@ import org.gudy.azureus2.core3.internat.MessageText;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.PEPiece;
 import org.gudy.azureus2.core3.tracker.host.TRHostTorrent;
-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.*;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.BufferedTableItem;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
@@ -49,6 +48,7 @@ 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.TableRowSWT;
+import org.gudy.azureus2.ui.swt.views.table.painted.TableCellPainted;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
 
@@ -89,6 +89,8 @@ public class FakeTableCell
 
 	private ArrayList cellVisibilityListeners;
 
+	private ArrayList<TableCellClipboardListener> cellClipboardListeners;
+
 	private Image image;
 
 	private Rectangle imageBounds;
@@ -120,6 +122,8 @@ public class FakeTableCell
 
 	private boolean hadMore;
 
+	private boolean wrapText	= true;
+	
 	private ArrayList cellSWTPaintListeners;
 	
 	private boolean valid;
@@ -129,16 +133,20 @@ public class FakeTableCell
 	/**
 	 * @param columnRateUpDown
 	 */
-	public FakeTableCell(TableColumn column) {
+	public FakeTableCell(TableColumn column, Object ds) {
 		valid = false;
+		coreDataSource = ds;
 		this.tableColumn = (TableColumnCore) column;
 		setOrientationViaColumn();
+		tableColumn.invokeCellAddedListeners(this);
 	}
 
-	public FakeTableCell(TableColumnCore column) {
+	public FakeTableCell(TableColumnCore column, Object ds) {
 		valid = false;
+		coreDataSource = ds;
 		this.tableColumn = column;
 		setOrientationViaColumn();
+		tableColumn.invokeCellAddedListeners(this);
 	}
 
 	public void addRefreshListener(TableCellRefreshListener listener) {
@@ -365,7 +373,46 @@ public class FakeTableCell
 			}
 		}
 	}
+	
+	private void addCellClipboardListener(TableCellClipboardListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellClipboardListeners == null)
+				cellClipboardListeners = new ArrayList<TableCellClipboardListener>(1);
+
+			cellClipboardListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public String getClipboardText() {
+		String text = null;
+		try {
+			this_mon.enter();
 
+			if (cellClipboardListeners != null) {
+				for (TableCellClipboardListener l : cellClipboardListeners) {
+					try {
+						text = l.getClipboardText(this);
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+					if (text != null) {
+						break;
+					}
+				}
+			}
+		} finally {
+			this_mon.exit();
+		}
+		if (text == null) {
+			text = this.getText();
+		}
+		return text;
+	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#addListeners(java.lang.Object)
 	public void addListeners(Object listenerObject) {
@@ -392,6 +439,10 @@ public class FakeTableCell
 		if (listenerObject instanceof TableCellSWTPaintListener) {
 			addSWTPaintListener((TableCellSWTPaintListener) listenerObject);
 		}
+
+		if (listenerObject instanceof TableCellClipboardListener) {
+			addCellClipboardListener((TableCellClipboardListener) listenerObject);
+		}
 	}
 
 	public void invokeMouseListeners(TableCellMouseEvent event) {
@@ -477,6 +528,11 @@ public class FakeTableCell
 				pluginDataSource = new TrackerTorrentImpl(item);
 			}
 		}
+		
+		if (pluginDataSource == null) {
+			// No translation available, make pluginDataSource the same as core
+			pluginDataSource = coreDataSource;
+		}
 
 		return pluginDataSource;
 	}
@@ -583,6 +639,9 @@ public class FakeTableCell
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getHeight()
 	public int getHeight() {
 		if (composite != null && !composite.isDisposed()) {
+			if (cellArea != null) {
+				return cellArea.height;
+			}
 			return composite.getSize().y;
 		}
 		return 0;
@@ -595,6 +654,9 @@ public class FakeTableCell
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getSortValue()
 	public Comparable getSortValue() {
+		if ( sortValue == null ){
+			return( "" );
+		}
 		return sortValue;
 	}
 
@@ -612,6 +674,8 @@ public class FakeTableCell
 	public TableRow getTableRow() {
 		if (fakeRow == null) {
 			fakeRow = new TableRow() {
+				Map<String, Object> data = new LightHashMap<String,Object>(1);
+
 				public void setForegroundToErrorColor() {
 				}
 
@@ -646,6 +710,18 @@ public class FakeTableCell
 
 				public void addMouseListener(TableRowMouseListener listener) {
 				}
+
+				public Object getData(String id) {
+					synchronized (data) {
+						return data.get(id);
+					}
+				}
+
+				public void setData(String id, Object val) {
+					synchronized (data) {
+						data.put(id, val);
+					}
+				}
 			};
 		}
 		return fakeRow;
@@ -667,6 +743,9 @@ public class FakeTableCell
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getWidth()
 	public int getWidth() {
 		if (!isDisposed()) {
+			if (cellArea != null) {
+				return cellArea.width - 2;
+			}
 			return composite.getSize().x;
 		}
 		return 0;
@@ -697,6 +776,10 @@ public class FakeTableCell
 		// TODO Auto-generated method stub
 
 	}
+	
+	public void setWrapText( boolean wrap ){
+		wrapText = wrap;
+	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setForeground(int, int, int)
 	public boolean setForeground(int red, int green, int blue) {
@@ -773,14 +856,12 @@ public class FakeTableCell
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setSortValue(java.lang.Comparable)
 	public boolean setSortValue(Comparable valueToSort) {
-		// TODO Auto-generated method stub
-		return false;
+		return _setSortValue(valueToSort);
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setSortValue(float)
 	public boolean setSortValue(float valueToSort) {
-		// TODO Auto-generated method stub
-		return false;
+		return _setSortValue(Float.valueOf(valueToSort));
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setText(java.lang.String)
@@ -861,7 +942,7 @@ public class FakeTableCell
 		}
 		// TODO: Cleanup and stop calling me so often!
 		
-		//gc.setBackground(getBackground());
+		//gc.setBackground(getBackgroundSWT());
 		//if (DEBUG_COLORCELL) {
 		//	gc.setBackground(Display.getDefault().getSystemColor(
 		//			(int) (Math.random() * 16)));
@@ -870,6 +951,10 @@ public class FakeTableCell
 			return;
 		}
 		//gc.fillRectangle(bounds);
+		if (!bounds.intersects(gc.getClipping())) {
+			return;
+		}
+		
 
 		if (image != null && !image.isDisposed()) {
 			Point size = new Point(bounds.width, bounds.height);
@@ -900,7 +985,7 @@ public class FakeTableCell
 
 		if (text != null && text.length() > 0) {
 			GCStringPrinter sp = new GCStringPrinter(gc, text, bounds, true, false,
-					orientation | SWT.WRAP);
+					wrapText?( orientation | SWT.WRAP ):orientation );
 			sp.printString();
 			hadMore = sp.isCutoff();
 		}
@@ -930,19 +1015,19 @@ public class FakeTableCell
 		return true;
 	}
 
-	public void setDataSource(Object datasource) {
-		coreDataSource = datasource;
-		if (datasource != null && !isDisposed()) {
+	public void setDataSource(Object _coreDataSource) {
+		coreDataSource = _coreDataSource;
+		if (_coreDataSource != null && !isDisposed()) {
 			invokeVisibilityListeners(TableCellVisibilityListener.VISIBILITY_SHOWN,
 					true);
 		}
 	}
 
 	public void setControl(final Composite composite) {
-		setControl(composite, null);
+		setControl(composite, null, true);
 	}
 
-	public void setControl(final Composite composite, Rectangle cellArea) {
+	public void setControl(final Composite composite, Rectangle cellArea, boolean addListeners) {
 		if (composite == null) {
 			dispose();
 			this.composite = null;
@@ -952,10 +1037,12 @@ public class FakeTableCell
 		this.composite = composite;
 		this.cellArea = cellArea;
 
-		composite.addPaintListener(this);
-		composite.addMouseListener(this);
-		composite.addMouseMoveListener(this);
-		composite.addMouseTrackListener(this);
+		if (addListeners) {
+  		composite.addPaintListener(this);
+  		composite.addMouseListener(this);
+  		composite.addMouseMoveListener(this);
+  		composite.addMouseTrackListener(this);
+		}
 
 		setForeground(-1, -1, -1);
 		setText(null);
@@ -1209,6 +1296,10 @@ public class FakeTableCell
 		Point ptCursor = composite.getDisplay().getCursorLocation();
 		return r.contains(ptCursor);
 	}
+	
+	public void setMouseOver(boolean b) {
+		// ignored, we calc mouseover on the fly
+	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableCellCore#isUpToDate()
 	public boolean isUpToDate() {
@@ -1243,9 +1334,9 @@ public class FakeTableCell
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableCellCore#setCursorID(int)
-	public void setCursorID(int cursorID) {
+	public boolean setCursorID(int cursorID) {
 		// TODO Auto-generated method stub
-
+		return false;
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableCellCore#setUpToDate(boolean)
@@ -1419,4 +1510,16 @@ public class FakeTableCell
 		// TODO Auto-generated method stub
 		
 	}
+
+	public Rectangle getBoundsOnDisplay() {
+		Rectangle bounds = getBounds();
+		Point pt = composite.toDisplay(bounds.x, bounds.y);
+		bounds.x = pt.x;
+		bounds.y = pt.y;
+		return bounds;
+	}
+
+	public TableColumnCore getTableColumnCore() {
+		return tableColumn;
+	}
 }
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 899a290..21ef4ea 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableCellImpl.java
@@ -25,45 +25,31 @@
  
 package org.gudy.azureus2.ui.swt.views.table.impl;
 
-import java.text.Collator;
-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.eclipse.swt.widgets.Item;
+
 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.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.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
 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.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.*;
 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
 
 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.  
@@ -76,92 +62,23 @@ import com.aelitis.azureus.ui.common.table.TableView;
  * This object is needed to split core code from plugin code.
  */
 public class TableCellImpl 
-       implements TableCellSWT
+	extends TableCellSWTBase
 {
 	private static final LogIDs LOGID = LogIDs.GUI;
 	
-	private static final byte FLAG_VALID = 1;
-	private static final byte FLAG_SORTVALUEISTEXT = 2;
-	private static final byte FLAG_TOOLTIPISAUTO = 4;
-  /**
-   * For refreshing, this flag manages whether the row is actually up to date.
-   * 
-   * We don't update any visuals while the row isn't visible.  But, validility
-   * does get set to true so that the cell isn't forced to refresh every
-   * cycle when not visible.  (We can't just never call refresh when the row
-   * is not visible, as refresh also sets the sort value)
-   *  
-   * When the row does become visible, we have to invalidate the row so
-   * that the row will set its visuals again (this time, actually
-   * updating a viewable object).
-   */
-	private static final byte FLAG_UPTODATE = 8;
-	private static final byte FLAG_DISPOSED = 16;
-	private static final byte FLAG_MUSTREFRESH = 32;
-	private static final byte FLAG_VISUALLY_CHANGED_SINCE_REFRESH = 64;
+	private static final boolean canUseQuickDraw = Constants.isWindows;
+	
 	
-	private byte flags;
-
-  private TableRowCore tableRow;
-  private Comparable sortValue;
   private BufferedTableItem bufferedTableItem;
-  private ArrayList refreshListeners;
-  private ArrayList disposeListeners;
-  private ArrayList tooltipListeners;
-	private ArrayList cellMouseListeners;
-	private ArrayList cellMouseMoveListeners;
-	private ArrayList cellVisibilityListeners;
-	private ArrayList cellSWTPaintListeners;
-  private TableColumnCore tableColumn;
-  private byte refreshErrLoopCount;
-  private byte tooltipErrLoopCount;
-  private byte loopFactor;
-  private Object oToolTip;
-  private Object defaultToolTip;
-	private int iCursorID = -1;
-	private Graphic graphic = null;
 	
-	private ArrayList childCells;
-  
-	public boolean bDebug = false;
-  
-  private static AEMonitor 	this_mon 	= new AEMonitor( "TableCell" );
-
-  private static final String CFG_PAINT = "GUI_SWT_bAlternateTablePainting";
-  private static boolean bAlternateTablePainting;
-
-	private static int MAX_REFRESHES = 10;
-	private static int MAX_REFRESHES_WITHIN_MS = 100;
-
-	private boolean bInRefresh = false;
-	private long lastRefresh;
-	private int numFastRefreshes;
-
-	private byte restartRefresh = 0;
-	private boolean bInRefreshAsync = false;
-	
-	private int textAlpha = 255;
-	
-	static {
-  	COConfigurationManager.addAndFireParameterListener(CFG_PAINT,
-				new ParameterListener() {
-					public void parameterChanged(String parameterName) {
-						bAlternateTablePainting = COConfigurationManager
-								.getBooleanParameter(CFG_PAINT);
-					}
-				});
-  }
+  // Getting the cell's bounds can be slow.  QUICK_WIDTH uses TableColumn's width
+	private static final boolean QUICK_WIDTH = true;
 
   public TableCellImpl(TableRowCore _tableRow, TableColumnCore _tableColumn,
       int position, BufferedTableItem item) {
-    this.tableColumn = _tableColumn;
-    this.tableRow = _tableRow;
-    flags = FLAG_SORTVALUEISTEXT;
-    refreshErrLoopCount = 0;
-    tooltipErrLoopCount = 0;
-    loopFactor = 0;
-
-    if (item != null) {
+  	super(_tableRow, _tableColumn);
+
+  	if (item != null) {
     	bufferedTableItem = item;
     } else {
     	createBufferedTableItem(position);
@@ -186,42 +103,137 @@ public class TableCellImpl
   private void createBufferedTableItem(int position) {
     BufferedTableRow bufRow = (BufferedTableRow)tableRow;
     if (tableColumn.getType() == TableColumnCore.TYPE_GRAPHIC) {
-    	if (bAlternateTablePainting) {
-	      bufferedTableItem = new BufferedGraphicTableItem2(bufRow, position) {
-	        public void refresh() {
-	          TableCellImpl.this.refresh();
-	        }
-	        public void invalidate() {
-	        	clearFlag(FLAG_VALID);
-	        	redraw();
-	        }
-	      };
-	    } else {
-	      bufferedTableItem = new BufferedGraphicTableItem1(bufRow, position) {
-	        public void refresh() {
-	          TableCellImpl.this.refresh();
-	        }
-	        public void invalidate() {
-	        	clearFlag(FLAG_VALID);
-	        	redraw();
-	        }
-	      };
-	    }
-    	setOrientationViaColumn();
-    } else {
-      bufferedTableItem = new BufferedTableItemImpl(bufRow, position) {
+      bufferedTableItem = new BufferedGraphicTableItem1(bufRow, position) {
         public void refresh() {
           TableCellImpl.this.refresh();
         }
         public void invalidate() {
         	clearFlag(FLAG_VALID);
+        	redraw();
+        }
+        protected void quickRedrawCell(TableOrTreeSWT table, Rectangle dirty, Rectangle cellBounds) {
+        	TableItemOrTreeItem item = row.getItem();
+					boolean ourQuickRedraw = canUseQuickDraw && tableRow != null
+							&& !tableRow.isMouseOver() && !tableRow.isSelected();
+					if (ourQuickRedraw) {
+      			TableCellImpl.this.quickRedrawCell2(table, item, dirty, cellBounds);
+      		} else {
+      			super.quickRedrawCell(table, dirty, cellBounds);
+      		}
         }
       };
+    	setOrientationViaColumn();
+    } else {
+			bufferedTableItem = new BufferedTableItemImpl(bufRow, position) {
+				public void refresh() {
+					TableCellImpl.this.refresh();
+				}
+
+				public void invalidate() {
+					clearFlag(FLAG_VALID);
+				}
+
+				protected void quickRedrawCell(TableOrTreeSWT table, Rectangle dirty,
+						Rectangle cellBounds) {
+					TableItemOrTreeItem item = row.getItem();
+					boolean ourQuickRedraw = canUseQuickDraw && tableRow != null
+							&& !tableRow.isMouseOver() && !tableRow.isSelected();
+					if (ourQuickRedraw) {
+						TableCellImpl.this.quickRedrawCell2(table, item, dirty, cellBounds);
+					} else {
+						super.quickRedrawCell(table, dirty, cellBounds);
+					}
+				}
+			};
     }
   }
 
-  private void pluginError(Throwable e) {
-    String sTitleLanguageKey = tableColumn.getTitleLanguageKey();
+	protected void quickRedrawCell2(TableOrTreeSWT table,
+			TableItemOrTreeItem tableItemOrTreeItem, Rectangle dirty,
+			Rectangle cellBounds) {
+		if (bufferedTableItem.isInPaintItem()) {
+			return;
+		}
+		Rectangle bounds = new Rectangle(0, 0, cellBounds.width, cellBounds.height);
+		Point pt = new Point(cellBounds.x, cellBounds.y);
+		Image img = new Image(table.getDisplay(), bounds);
+
+		int colPos = bufferedTableItem.getPosition();
+
+		Item item = tableItemOrTreeItem.getItem();
+		table.setData("inPaintInfo", new InPaintInfo(item, colPos, bounds));
+		table.setData("fullPaint", Boolean.TRUE);
+
+		GC gc = new GC(img);
+		try {
+			TableViewSWTImpl<?> tv = (TableViewSWTImpl<?>) tableRow.getView();
+			TableViewSWT_EraseItem.eraseItem(null, gc, tableItemOrTreeItem, colPos,
+					false, bounds, tv, true);
+			//gc.setBackground(ColorCache.getRandomColor());
+			//gc.fillRectangle(bounds);
+
+			Color fg = getForegroundSWT();
+			if (fg != null) {
+				gc.setForeground(fg);
+			}
+			gc.setBackground(getBackgroundSWT());
+
+			TableViewSWT_PaintItem.paintItem(gc, (TableRowSWT) tableRow, colPos,
+					tableRow.getIndex(), bounds, tv, true);
+		} finally {
+			gc.dispose();
+		}
+
+		gc = new GC(table.getComposite());
+		try {
+			//System.out.println("draw " + bounds);
+			gc.drawImage(img, pt.x, pt.y);
+		} finally {
+			img.dispose();
+			gc.dispose();
+		}
+
+		table.setData("inPaintInfo", null);
+		table.setData("fullPaint", Boolean.FALSE);
+	}
+
+	protected void quickRedrawCell(TableOrTreeSWT table,
+			TableItemOrTreeItem tableItemOrTreeItem, Rectangle dirty,
+			Rectangle cellBounds) {
+		if (bufferedTableItem.isInPaintItem()) {
+			return;
+		}
+		
+		int colPos = bufferedTableItem.getPosition();
+
+		Item item = tableItemOrTreeItem.getItem();
+		table.setData("inPaintInfo", new InPaintInfo(item, colPos, cellBounds));
+		table.setData("fullPaint", Boolean.TRUE);
+
+		GC gc = new GC(table.getComposite());
+		try {
+			TableViewSWTImpl<?> tv = (TableViewSWTImpl<?>) tableRow.getView();
+			TableViewSWT_EraseItem.eraseItem(null, gc, tableItemOrTreeItem,
+					bufferedTableItem.getPosition(), true, cellBounds, tv, true);
+
+			Color fg = getForegroundSWT();
+			if (fg != null) {
+				gc.setForeground(fg);
+			}
+			gc.setBackground(getBackgroundSWT());
+			
+			TableViewSWT_PaintItem.paintItem(gc, (TableRowSWT) tableRow,
+					bufferedTableItem.getPosition(), tableRow.getIndex(), cellBounds, tv, true);
+		} finally {
+			gc.dispose();
+		}
+
+		table.setData("inPaintInfo", null);
+		table.setData("fullPaint", Boolean.FALSE);
+	}
+
+	protected void pluginError(Throwable e) {
+    String sTitleLanguageKey = (tableColumn==null?"?":tableColumn.getTitleLanguageKey());
 
     String sPosition = (bufferedTableItem == null) 
       ? "null" 
@@ -231,8 +243,8 @@ public class TableCellImpl
 				+ " generated an exception ", e));
   }
 
-  private void pluginError(String s) {
-    String sTitleLanguageKey = tableColumn.getTitleLanguageKey();
+	protected void pluginError(String s) {
+    String sTitleLanguageKey = (tableColumn==null?"?":tableColumn.getTitleLanguageKey());
 
 		String sPosition = "r"
 				+ tableRow.getIndex()
@@ -244,11 +256,6 @@ public class TableCellImpl
 						+ Debug.getStackTrace(true, true)));
   }
   
-  private void checkCellForSetting() {
-  	if (isDisposed())
-  		throw new UIRuntimeException("Table Cell is disposed.");
-  }
-  
   /* Public API */
   ////////////////
   
@@ -277,58 +284,27 @@ public class TableCellImpl
     return tableRow.getTableID();
   }
   
-  public boolean isValid() {
-  	// Called often.. inline faster
-  	return (flags & FLAG_VALID) != 0;
-    //return hasFlag(FLAG_VALID);
-  }
-  
   public Color getForegroundSWT() {
-  	checkCellForSetting();
+		if (isDisposed()) {
+			return null;
+		}
 
     return bufferedTableItem.getForeground();
   }
   
   public Color getBackgroundSWT() {
-		checkCellForSetting();
-
-		return bufferedTableItem.getBackground();
-	}
-
-  public int[] getBackground() {
-		if (bufferedTableItem == null) {
-			return null;
-		}
-		Color color = bufferedTableItem.getBackground();
-
-		if (color == null) {
+		if (isDisposed()) {
 			return null;
 		}
 
-		return new int[] {
-			color.getRed(),
-			color.getGreen(),
-			color.getBlue()
-		};
+		return bufferedTableItem.getBackground();
 	}
 
-  // @see org.gudy.azureus2.plugins.ui.tables.TableCell#getForeground()
-  public int[] getForeground() {
-  	if (bufferedTableItem == null) {
-  		return new int[] { 0, 0, 0 };
-  	}
-		Color color = bufferedTableItem.getForeground();
-
-		if (color == null) {
-			return new int[3];
-		}
-
-		return new int[] { color.getRed(), color.getGreen(), color.getBlue()
-		};
-	}
   
   public boolean setForeground(Color color) {
-  	checkCellForSetting();
+		if (isDisposed()) {
+			return false;
+		}
 
   	// Don't need to set when not visible
   	if (isInvisibleAndCanRefresh())
@@ -341,95 +317,21 @@ public class TableCellImpl
     return set;
   }
 
-	public boolean setForeground(int red, int green, int blue) {
-		checkCellForSetting();
-
-		// Don't need to set when not visible
-		if (isInvisibleAndCanRefresh())
-			return false;
-
-		boolean set;
-		if (red < 0 || green < 0 || blue < 0) {
-			set = bufferedTableItem.setForeground(null);
-		} else {
-			set = bufferedTableItem.setForeground(red, green, blue);
-		}
-		if (set) {
-			setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-		}
-		return set;
-	}
-
-	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setForeground(int[])
-	public boolean setForeground(int[] rgb) {
-		if (rgb == null || rgb.length < 3) {
-			return setForeground((Color) null);
-		}
-		return setForeground(rgb[0], rgb[1], rgb[2]);
-	}
-
-  public boolean setForegroundToErrorColor() {
-	  return setForeground(Colors.colorError);
-  }
-
-  public boolean setText(String text) {
-  	checkCellForSetting();
-  	if (text == null)
-  		text = "";
-  	boolean bChanged = false;
-
-  	if (hasFlag(FLAG_SORTVALUEISTEXT) && !text.equals(sortValue)) {
-  		bChanged = true;
-  		sortValue = text;
-    	tableColumn.setLastSortValueChange(SystemTime.getCurrentTime());
-    	if (bDebug)
-    		debug("Setting SortValue to text;");
-  	}
-  	
-
-// Slower than setText(..)!
-//  	if (isInvisibleAndCanRefresh()) {
-//  		if (bDebug) {
-//  			debug("setText ignored: invisible");
-//  		}
-//  		return false;
-//  	}
-
-    if (bufferedTableItem.setText(text) && !hasFlag(FLAG_SORTVALUEISTEXT))
-    	bChanged = true;
-
-		if (bDebug) {
-			debug("setText (" + bChanged + ") : " + text);
-		}
-
-		if (bChanged) {
-			setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-		}
-
-		boolean do_auto = this.tableColumn.doesAutoTooltip();
-		
-		// If we were using auto tooltips (and we aren't any more), then
-		// clear up previously set tooltips.
-		if (!do_auto) {
-			if (hasFlag(FLAG_TOOLTIPISAUTO)) {
-				this.oToolTip = null;
-				clearFlag(FLAG_TOOLTIPISAUTO);
-			}
-		}
-		
-		else {
-			this.oToolTip = text;
-			setFlag(FLAG_TOOLTIPISAUTO);
-		}
-		
-  	return bChanged;
+  @Override
+  public boolean uiSetText(String text) {
+  	return bufferedTableItem.setText(text);
   }
   
-  private boolean isInvisibleAndCanRefresh() {
-  	return !isShown()
-				&& (refreshListeners != null || tableColumn.hasCellRefreshListener());
+  @Override
+  public boolean setGraphic(Graphic img) {
+  	boolean changed = super.setGraphic(img);
+  	if (changed && img != null) {
+    	Image imgSWT = ((UISWTGraphic)img).getImage();
+    	((BufferedGraphicTableItem)bufferedTableItem).setGraphic(imgSWT);
+  	}
+  	return changed;
   }
-  
+
   public String getText() {
   	if (hasFlag(FLAG_SORTVALUEISTEXT) && sortValue instanceof String)
   		return (String)sortValue;
@@ -448,110 +350,16 @@ public class TableCellImpl
 				&& tableRow.getView().isColumnVisible(tableColumn);
   }
   
-  public boolean setSortValue(Comparable valueToSort) {
-		if (!tableColumn.isSortValueLive()) {
-			// objects that can't change aren't live
-			if (!(valueToSort instanceof Number) && !(valueToSort instanceof String)
-					&& !(valueToSort instanceof TableColumnSortObject)) {
-				tableColumn.setSortValueLive(true);
-			}
-		}
-		return _setSortValue(valueToSort);
-	}
-
-  private boolean _setSortValue(Comparable valueToSort) {
-  	checkCellForSetting();
-
-    if (sortValue == valueToSort)
-      return false;
-
-    if (hasFlag(FLAG_SORTVALUEISTEXT)) {
-    	clearFlag(FLAG_SORTVALUEISTEXT);
-    	if (sortValue instanceof String)
-	    	// Make sure text is actually in the cell (it may not have been if
-	      // cell wasn't created at the time of setting)
-	      setText((String)sortValue);
-    }
-    
-    if ((valueToSort instanceof String) && (sortValue instanceof String)
-				&& sortValue.equals(valueToSort)) {
-			return false;
-		}
-
-    if ((valueToSort instanceof Number) && (sortValue instanceof Number)
-				&& sortValue.equals(valueToSort)) {
-			return false;
-		}
-
-  	if (bDebug)
-  		debug("Setting SortValue to "
-					+ ((valueToSort == null) ? "null" : valueToSort.getClass().getName()));
-  	
-  	tableColumn.setLastSortValueChange(SystemTime.getCurrentTime());
-    sortValue = valueToSort;
-    
-  	if (cellSWTPaintListeners != null
-				|| tableColumn.hasCellOtherListeners("SWTPaint")) {
-  		redraw();
-  	}
-
-    return true;
-  }
-  
-  public boolean setSortValue(long valueToSort) {
-  	checkCellForSetting();
-
-		if ((sortValue instanceof Long)
-				&& ((Long) sortValue).longValue() == valueToSort)
-			return false;
-
-		return _setSortValue(Long.valueOf(valueToSort));
-  }
-  
-  public boolean setSortValue( float valueToSort ) {
-  	checkCellForSetting();
-
-		if (sortValue instanceof Float
-				&& ((Float) sortValue).floatValue() == valueToSort)
-			return false;
-
-		return _setSortValue(new Float(valueToSort));
-  }
-
-  public Comparable getSortValue() {
-  	if (bDebug)
-			debug("GetSortValue;"
-					+ (sortValue == null ? "null" : sortValue.getClass().getName() + ";"
-							+ sortValue.toString()));
-
-    if (sortValue == null) {
+  public Comparable<?> getSortValue() {
+  	Comparable<?> v = super.getSortValue();
+  	if (v == null) {
       if (bufferedTableItem != null)
         return bufferedTableItem.getText();
       return "";
-    }
-    return sortValue;
-  }
-  
-  public void setToolTip(Object tooltip) {
-    oToolTip = tooltip;
-    clearFlag(FLAG_TOOLTIPISAUTO);
-  }
-
-  public Object getToolTip() {
-    return oToolTip;
-  }
-
-  public Object getDefaultToolTip() {
-	return defaultToolTip;
-  }
-  public void setDefaultToolTip(Object tt) {
-	defaultToolTip = tt;
+  	}
+    return v;
   }
   
-	public boolean isDisposed() {
-		return hasFlag(FLAG_DISPOSED);
-	}
-	
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMaxLines()
 	public int getMaxLines() {
 		if (bufferedTableItem == null) {
@@ -569,116 +377,45 @@ public class TableCellImpl
     return ((BufferedGraphicTableItem)bufferedTableItem).getSize();
   }
 
+	public int getWidthRaw() {
+		return tableColumn.getWidth() - 2;
+	}
+	
   public int getWidth() {
-  	Point pt = null;
-  	
-    if (bufferedTableItem instanceof BufferedGraphicTableItem) {
-    	pt = ((BufferedGraphicTableItem)bufferedTableItem).getSize();
-    } else {
-    	Rectangle bounds = bufferedTableItem.getBounds();
-    	if (bounds != null) {
-    		pt = new Point(bounds.width, bounds.height);
-    	}
-    }
-    if (pt == null)
-      return -1;
-    return pt.x;
-  }
-
-  public int getHeight() {
-  	Point pt = null;
-  	
-    if (bufferedTableItem instanceof BufferedGraphicTableItem) {
-    	pt = ((BufferedGraphicTableItem)bufferedTableItem).getSize();
-    } else {
-    	Rectangle bounds = bufferedTableItem.getBounds();
-    	if (bounds != null) {
-    		pt = new Point(bounds.width, bounds.height);
-    	}
-    }
-    if (pt == null)
-      return -1;
-    return pt.y;
-  }
-
-  // @see org.gudy.azureus2.ui.swt.views.table.TableCellSWT#setGraphic(org.eclipse.swt.graphics.Image)
-  public boolean setGraphic(Image img) {
-  	checkCellForSetting();
-
-    if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
-      return false;
-
-    graphic = null;
-    boolean b = ((BufferedGraphicTableItem)bufferedTableItem).setGraphic(img);
-    if (b) {
-    	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-			bufferedTableItem.redraw();
-    }
-    return b;
-  }
-
-  // @see org.gudy.azureus2.plugins.ui.tables.TableCell#setGraphic(org.gudy.azureus2.plugins.ui.Graphic)
-  public boolean setGraphic(Graphic img) {
-  	if (img != null){
-  		checkCellForSetting();
+  	if (isDisposed()) {
+  		return -1;
   	}
-
-    if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
-      return false;
-
-    if (img == graphic && numFastRefreshes >= MAX_REFRESHES) {
-    	pluginError("TableCellImpl::setGraphic to same Graphic object. "
-					+ "Forcing refresh.");
-    }
-    
-    graphic = img;
-
-    if (img == null) {
-      boolean b = ((BufferedGraphicTableItem)bufferedTableItem).setGraphic(null);
-      if (b) {
-      	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-  			bufferedTableItem.redraw();
-      }
-    }
-
-    if (img instanceof GraphicSWT){
-    	Image imgSWT = ((GraphicSWT)img).getImage();
-    	boolean b = ((BufferedGraphicTableItem)bufferedTableItem).setGraphic(imgSWT);
-      if (b) {
-      	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-  			bufferedTableItem.redraw();
-      }
-    } else if (img instanceof UISWTGraphic){
-    	Image imgSWT = ((UISWTGraphic)img).getImage();
-    	boolean b = ((BufferedGraphicTableItem)bufferedTableItem).setGraphic(imgSWT);
-      if (b) {
-      	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-  			bufferedTableItem.redraw();
+  	if (QUICK_WIDTH) {
+  		return tableColumn.getWidth() - 2 - (getMarginWidth() * 2);
+  	} else {
+    	Point pt = null;
+    	
+      if (bufferedTableItem instanceof BufferedGraphicTableItem) {
+      	pt = ((BufferedGraphicTableItem)bufferedTableItem).getSize();
+      } else {
+      	Rectangle bounds = bufferedTableItem.getBounds();
+      	if (bounds != null) {
+      		pt = new Point(bounds.width, bounds.height);
+      	}
       }
-    }
-    
-    return( false );
-  }
-
-  public Graphic getGraphic() {
-  	if (graphic != null) {
-  		return graphic;
+      if (pt == null)
+        return -1;
+      return pt.x;
   	}
-
-    if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
-      return null;
-    Image img = ((BufferedGraphicTableItem)bufferedTableItem).getGraphic();
-    return new UISWTGraphicImpl(img);
   }
 
-  public Image getGraphicSWT() {
-    if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
-      return null;
-    return ((BufferedGraphicTableItem)bufferedTableItem).getGraphic();
+  public int getHeight() {
+  	return bufferedTableItem.getHeight();
   }
 
+  /* (non-Javadoc)
+   * @see org.gudy.azureus2.plugins.ui.tables.TableCell#setFillCell(boolean)
+   */
   public void setFillCell(boolean bFillCell) {
-  	checkCellForSetting();
+  	super.setFillCell(bFillCell);
+		if (isDisposed()) {
+			return;
+		}
 
     if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
       return;
@@ -691,7 +428,9 @@ public class TableCellImpl
   }
 
 	public void setMarginHeight(int height) {
-  	checkCellForSetting();
+		if (isDisposed()) {
+			return;
+		}
 
     if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
       return;
@@ -700,7 +439,9 @@ public class TableCellImpl
   }
 
   public void setMarginWidth(int width) {
-  	checkCellForSetting();
+		if (isDisposed()) {
+			return;
+		}
 
     if (!(bufferedTableItem instanceof BufferedGraphicTableItem))
       return;
@@ -722,544 +463,45 @@ public class TableCellImpl
 
   /* End TYPE_GRAPHIC Functions */
 
-  public void addRefreshListener(TableCellRefreshListener listener) {
-  	try{
-  		this_mon.enter();
-  	
-  		if (refreshListeners == null)
-  			refreshListeners = new ArrayList(1);
-
-  		if (bDebug) {
-  			debug("addRefreshListener; count=" + refreshListeners.size());
-  		}
-  		refreshListeners.add(listener);
-  		
-  	}finally{
-  		this_mon.exit();
-  	}
-  }
-
-  public void removeRefreshListener(TableCellRefreshListener listener) {
-  	try{
-  		this_mon.enter();
-  
-	    if (refreshListeners == null)
-	      return;
-	
-	    refreshListeners.remove(listener);
-  	}finally{
-  		
-  		this_mon.exit();
-  	}
-  }
-
-  public void addDisposeListener(TableCellDisposeListener listener) {
-  	try{
-  		this_mon.enter();
-  
-	    if (disposeListeners == null) {
-	      disposeListeners = new ArrayList(1);
-	    }
-	    disposeListeners.add(listener);
-  	}finally{
-  		
-  		this_mon.exit();
-  	}
-  }
-
-  public void removeDisposeListener(TableCellDisposeListener listener) {
-  	try{
-  		this_mon.enter();
-  
-  		if (disposeListeners == null)
-  			return;
-
-  		disposeListeners.remove(listener);
-  		
-  	}finally{
-  		
-  		this_mon.exit();
-  	}
-  }
-  
-  public void addToolTipListener(TableCellToolTipListener listener) {
-  	try{
-  		this_mon.enter();
-  
-  		if (tooltipListeners == null) {
-  			tooltipListeners = new ArrayList(1);
-  		}
-  		tooltipListeners.add(listener);
-  		
-  	}finally{
-  		this_mon.exit();
-  	}
-  }
-
-  public void removeToolTipListener(TableCellToolTipListener listener) {
-  	try{
-  		this_mon.enter();
-  	
-  		if (tooltipListeners == null)
-  			return;
-
-  		tooltipListeners.remove(listener);
-  	}finally{
-  		
-  		this_mon.exit();
-  	}
-  }
-  
-  
-	public void addMouseListener(TableCellMouseListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellMouseListeners == null)
-				cellMouseListeners = new ArrayList(1);
-
-			cellMouseListeners.add(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void removeMouseListener(TableCellMouseListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellMouseListeners == null)
-				return;
-
-			cellMouseListeners.remove(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void addMouseMoveListener(TableCellMouseMoveListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellMouseMoveListeners == null)
-				cellMouseMoveListeners = new ArrayList(1);
-
-			cellMouseMoveListeners.add(listener);
-			
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void removeMouseMoveListener(TableCellMouseMoveListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellMouseMoveListeners == null)
-				return;
-
-			cellMouseMoveListeners.remove(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void addVisibilityListener(TableCellVisibilityListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellVisibilityListeners == null)
-				cellVisibilityListeners = new ArrayList(1);
-
-			cellVisibilityListeners.add(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void removeVisibilityListener(TableCellVisibilityListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellVisibilityListeners == null)
-				return;
-
-			cellVisibilityListeners.remove(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	/**
-	 * @param listenerObject
-	 *
-	 * @since 3.1.1.1
-	 */
-	private void addSWTPaintListener(TableCellSWTPaintListener listener) {
-		try {
-			this_mon.enter();
-
-			if (cellSWTPaintListeners == null)
-				cellSWTPaintListeners = new ArrayList(1);
-
-			cellSWTPaintListeners.add(listener);
-
-		} finally {
-			this_mon.exit();
-		}
-	}
-
-	public void invokeSWTPaintListeners(GC gc) {
-  	if (tableColumn != null) {
-			Object[] swtPaintListeners = tableColumn.getCellOtherListeners("SWTPaint");
-			if (swtPaintListeners != null) { 
-  			for (int i = 0; i < swtPaintListeners.length; i++) {
-  				try {
-  					TableCellSWTPaintListener l = (TableCellSWTPaintListener) swtPaintListeners[i];
-  
-  					l.cellPaint(gc, this);
-  
-  				} catch (Throwable e) {
-  					Debug.printStackTrace(e);
-  				}
-  			}
-			}
-		}
-
-		if (cellSWTPaintListeners == null) {
-			return;
-		}
-		
-
-		for (int i = 0; i < cellSWTPaintListeners.size(); i++) {
-			try {
-				TableCellSWTPaintListener l = (TableCellSWTPaintListener) (cellSWTPaintListeners.get(i));
-
-				l.cellPaint(gc, this);
-
-			} catch (Throwable e) {
-				Debug.printStackTrace(e);
-			}
-		}
-	}
-	
-	public void addListeners(Object listenerObject) {
-		if (listenerObject instanceof TableCellDisposeListener) {
-			addDisposeListener((TableCellDisposeListener)listenerObject);
-		}
-
-		if (listenerObject instanceof TableCellRefreshListener)
-			addRefreshListener((TableCellRefreshListener)listenerObject);
-
-		if (listenerObject instanceof TableCellToolTipListener)
-			addToolTipListener((TableCellToolTipListener)listenerObject);
-
-		if (listenerObject instanceof TableCellMouseMoveListener) {
-			addMouseMoveListener((TableCellMouseMoveListener) listenerObject);
-		}
-
-		if (listenerObject instanceof TableCellMouseListener) {
-			addMouseListener((TableCellMouseListener) listenerObject);
-		}
-
-		if (listenerObject instanceof TableCellVisibilityListener)
-			addVisibilityListener((TableCellVisibilityListener)listenerObject);
-
-		if (listenerObject instanceof TableCellSWTPaintListener)
-			addSWTPaintListener((TableCellSWTPaintListener)listenerObject);
-	}
-
-	/**
-	 * If a plugin in trying to invalidate a cell, then clear the sort value
-	 * too.
-	 */
-	public void invalidate() {
-  	checkCellForSetting();
-
-  	invalidate(true);
-	}
 
 	/* Start of Core-Only function */
   //////////////////////////////////
 	
 	public void redraw() {
+		if (!tableRow.isVisible()) {
+			return;
+		}
 		if (bufferedTableItem != null) {
 			bufferedTableItem.redraw();
 		}
 	}
 	
   public void invalidate(final boolean bMustRefresh) {
-  	if (!hasFlag(FLAG_VALID)) {
-  		if (bMustRefresh) {
-  			if (hasFlag(FLAG_MUSTREFRESH)) {
-  				return;
-  			}
-  		} else {
-  			return;
-  		}
-  	}
-  	clearFlag(FLAG_VALID);
-  	
-  	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-
-  	if (bDebug)
-  		debug("Invalidate Cell;" + bMustRefresh);
-
+  	super.invalidate(bMustRefresh);
   	if (bMustRefresh) {
-  		setFlag(FLAG_MUSTREFRESH);
   		if (bufferedTableItem != null) {
   			bufferedTableItem.invalidate();
   		}
   	}
   }
   
-  // @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh()
-  public boolean refresh() {
-    return refresh(true);
-  }
-  
-  // @see com.aelitis.azureus.ui.common.table.TableCellCore#refreshAsync()
-  public void refreshAsync() {
-  	if (bInRefreshAsync) {
-  		//System.out.println(System.currentTimeMillis() + "] SKIP " + restartRefresh);
-  		if (restartRefresh < Byte.MAX_VALUE) {
-  			restartRefresh++;
-  		}
-  		return;
-  	}
-  	bInRefreshAsync = true;
-
-		AERunnable runnable = new AERunnable() {
-			public void runSupport() {
-				//System.out.println(System.currentTimeMillis() + "] REFRESH!");
-				restartRefresh = 0;
-				refresh(true);
-				bInRefreshAsync = false;
-				//System.out.println(System.currentTimeMillis() + "] REFRESH OUT!");
-				if (restartRefresh > 0) {
-					refreshAsync();
-				}
-			}
-		};
-		Utils.execSWTThreadLater(25, runnable);
-  }
-  
-  // @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean)
-  public boolean refresh(boolean bDoGraphics) {
-  	boolean isRowShown;
-  	if (tableRow != null) {
-  		TableView view = tableRow.getView();
-  		isRowShown = view.isRowVisible(tableRow);
-  	} else {
-  		isRowShown = true;
-  	}
-		boolean isCellShown = isRowShown && isShown();
-		return refresh(bDoGraphics, isRowShown, isCellShown);
-  }
-
-  // @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean, boolean)
-  public boolean refresh(boolean bDoGraphics, boolean bRowVisible) {
-		boolean isCellShown = bRowVisible && isShown();
-		return refresh(bDoGraphics, bRowVisible, isCellShown);
-  }
-
-  // @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean, boolean, boolean)
-  public boolean refresh(boolean bDoGraphics, boolean bRowVisible,  boolean bCellVisible)
-  {
-  	if (tableColumn == null) {
-  		return false;
-  	}
-	  boolean ret = getVisuallyChangedSinceRefresh();
-  	clearFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-
-	  int iErrCount = 0;
-	  if (refreshErrLoopCount > 2) {
-		  return ret;
-	  }
-
-	  iErrCount = tableColumn.getConsecutiveErrCount();
-	  if (iErrCount > 10) {
-		  refreshErrLoopCount = 3;
-		  return ret;
-	  }
-
-	  if (bInRefresh) {
-		  // Skip a Refresh call when being called from within refresh.
-		  // This could happen on virtual tables where SetData calls us again, or
-		  // if we ever introduce plugins to refresh.
-		  if (bDebug)
-			  debug("Calling Refresh from Refresh :) Skipping.");
-		  return ret;
-	  }
-	  try {
-		  bInRefresh = true;
-		  if (ret) {
-  		  long now = SystemTime.getCurrentTime();
-  		  if (now - lastRefresh < MAX_REFRESHES_WITHIN_MS) {
-  		  	numFastRefreshes++;
-  		  	if (numFastRefreshes >= MAX_REFRESHES) {
-  		  		if ((numFastRefreshes % MAX_REFRESHES) == 0) {
-    			  	pluginError("this plugin is crazy. tried to refresh "
-									+ numFastRefreshes + " times in " + (now - lastRefresh)
-									+ "ms");
-  		  		}
-  		  		return ret;
-  		  	}
-  		  } else {
-  		  	numFastRefreshes = 0;
-  			  lastRefresh = now;
-  		  }
-		  }
-
-		  // See bIsUpToDate variable comments
-		  if (bCellVisible && !isUpToDate()) {
-			  if (bDebug)
-				  debug("Setting Invalid because visible & not up to date");
-			  clearFlag(FLAG_VALID);
-			  setFlag(FLAG_UPTODATE);
-		  } else if (!bCellVisible && isUpToDate()) {
-			  if (bDebug)
-				  debug("Setting not up to date because cell not visible " + Debug.getCompressedStackTrace());
-		  	clearFlag(FLAG_UPTODATE);
-		  }
-		  
-		  if (bDebug) {
-			  debug("Cell Valid?" + hasFlag(FLAG_VALID) + "; Visible?" + tableRow.isVisible() + "/" + bufferedTableItem.isShown());
-		  }
-		  int iInterval = tableColumn.getRefreshInterval();
-		  if (iInterval == TableColumnCore.INTERVAL_INVALID_ONLY 
-		  	&& !hasFlag(FLAG_MUSTREFRESH | FLAG_VALID) && hasFlag(FLAG_SORTVALUEISTEXT) && sortValue != null
-			  && tableColumn.getType() == TableColumnCore.TYPE_TEXT_ONLY) {
-			  if (bCellVisible) {
-				  if (bDebug)
-					  debug("fast refresh: setText");
-				  ret = setText((String)sortValue);
-				  setFlag(FLAG_VALID);
-			  }
-		  } else if ((iInterval == TableColumnCore.INTERVAL_LIVE ||
-			  (iInterval == TableColumnCore.INTERVAL_GRAPHIC && bDoGraphics) ||
-			  (iInterval > 0 && (loopFactor % iInterval) == 0) ||
-			  !hasFlag(FLAG_VALID) || hasFlag(FLAG_MUSTREFRESH))) 
-		  {
-			  boolean bWasValid = isValid();
-
-			  if (hasFlag(FLAG_MUSTREFRESH)) {
-			  	clearFlag(FLAG_MUSTREFRESH);
-			  }
-
-			  if (bDebug)
-				  debug("invoke refresh; wasValid? " + bWasValid);
-
-			  long lTimeStart = Constants.isCVSVersion()?SystemTime.getMonotonousTime():0;
-			  tableColumn.invokeCellRefreshListeners(this, !bCellVisible);
-			  if (refreshListeners != null) {
-				  for (int i = 0; i < refreshListeners.size(); i++) {
-					  TableCellRefreshListener l = (TableCellRefreshListener)refreshListeners.get(i);
-					  if(l instanceof TableCellLightRefreshListener)
-						  ((TableCellLightRefreshListener)l).refresh(this,!bCellVisible);
-					  else
-						  l.refresh(this);
-				  }
-			  }
-			  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)) {
-			  	setFlag(FLAG_VALID);
-			  }
-		  }
-		  loopFactor++;
-		  refreshErrLoopCount = 0;
-		  if (iErrCount > 0)
-			  tableColumn.setConsecutiveErrCount(0);
-
-		  ret = getVisuallyChangedSinceRefresh();
-		  if (bDebug)
-			  debug("refresh done; visual change? " + ret + ";" + Debug.getCompressedStackTrace());
-	  } catch (Throwable e) {
-		  refreshErrLoopCount++;
-		  if (tableColumn != null) {
-			  tableColumn.setConsecutiveErrCount(++iErrCount);
-		  }
-		  pluginError(e);
-		  if (refreshErrLoopCount > 2)
-			  Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-				  "TableCell will not be refreshed anymore this session."));
-	  } finally {
-		  bInRefresh = false;
-	  }
-
-    if (childCells != null) {
-    	Object[] childCellsArray = childCells.toArray();
-    	for (int i = 0; i < childCellsArray.length; i++) {
-				TableCellImpl childCell = (TableCellImpl) childCellsArray[i];
-				childCell.refresh(bDoGraphics, bRowVisible, bCellVisible);
-			}
-    }
-	  return ret;
-  }
-  
-  public boolean getVisuallyChangedSinceRefresh() {
-  	return hasFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-  }
-
 
   public void dispose() {
-  	setFlag(FLAG_DISPOSED);
-
-    tableColumn.invokeCellDisposeListeners(this);
+  	super.dispose();
 
-    if (disposeListeners != null) {
-      try {
-        for (Iterator iter = disposeListeners.iterator(); iter.hasNext();) {
-          TableCellDisposeListener listener = (TableCellDisposeListener)iter.next();
-          listener.dispose(this);
-        }
-        disposeListeners = null;
-      } catch (Throwable e) {
-        pluginError(e);
-      }
-    }
-    
     if (bufferedTableItem != null) {
-			bufferedTableItem.setForeground(null);
+			//bufferedTableItem.setForeground(null);
 			bufferedTableItem.dispose();
 		}
     
-    refreshListeners = null;
     bufferedTableItem = null;
-    tableColumn = null;
-    tableRow = null;
-    sortValue = null;
   }
   
-  public boolean setIcon(Image img) {
-  	if (isInvisibleAndCanRefresh())
-  		return false;
-
-    bufferedTableItem.setIcon(img);
-    graphic = null;
-    setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
-    return true;
-  }
-  
-  public Image getIcon() {
-  	if (bufferedTableItem == null) {
-  		return null;
-  	}
-  	return bufferedTableItem.getIcon();
-  }
-
   public boolean needsPainting() {
+		if (isDisposed()) {
+			return false;
+		}
+
   	if (cellSWTPaintListeners != null || tableColumn.hasCellOtherListeners("SWTPaint")) {
   		return true;
   	}
@@ -1269,58 +511,18 @@ public class TableCellImpl
     return bufferedTableItem.needsPainting();
   }
   
-  public void doPaint(GC gc) {
-  	//This sometimes causes a infinite loop if the listener invalidates
-  	//the drawing area
-  	//if ((!hasFlag(FLAG_UPTODATE) || !hasFlag(FLAG_VALID)) && !bInRefresh && !bInRefreshAsync
-		//		&& (refreshListeners != null || tableColumn.hasCellRefreshListener())) {
-  	//	if (bDebug) {
-  	//		debug("doPaint: invoke refresh");
-  	//	}
-  	//	refresh(true);
-  	//}
-
-		if (bDebug) {
-			debug("doPaint up2date:" + hasFlag(FLAG_UPTODATE) + ";v:" + hasFlag(FLAG_VALID) + ";rl=" + refreshListeners);
-		}
-		
-		invokeSWTPaintListeners(gc);
-		
-    bufferedTableItem.doPaint(gc);
-    
-    if (childCells != null) {
-    	Object[] childCellsArray = childCells.toArray();
-    	for (int i = 0; i < childCellsArray.length; i++) {
-				TableCellImpl childCell = (TableCellImpl) childCellsArray[i];
-				childCell.doPaint(gc);
-			}
-    }
-  }
-
   public void locationChanged() {
   	if (bufferedTableItem != null) {
   		bufferedTableItem.locationChanged();
   	}
   }
 
-  public TableRowCore getTableRowCore() {
-    return tableRow;
-  }
-
-	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWT#getTableRowSWT()
-	public TableRowSWT getTableRowSWT() {
-		if (tableRow instanceof TableRowSWT) {
-			return (TableRowSWT)tableRow;
-		}
-		return null;
-	}
-
 	/* (non-Javadoc)
 	 * @see java.lang.Object#toString()
 	 */
 	public String toString() {
 		return "TableCell {"
-				+ tableColumn.getName()
+				+ (tableColumn == null ? "disposed" : tableColumn.getName())
 				+ ","
 				+ (tableRow == null ? "" : "r" + tableRow.getIndex())
 				+ (bufferedTableItem == null ? "c?" : "c"
@@ -1330,112 +532,6 @@ public class TableCellImpl
 
 	/* Comparable Implementation */
   
-  /** Compare our sortValue to the specified object.  Assumes the object 
-   * is TableCellImp (safe assumption)
-   */
-  public int compareTo(Object o) {
-    try {
-      Comparable ourSortValue = getSortValue();
-      Comparable otherSortValue = ((TableCellImpl)o).getSortValue();
-      if (ourSortValue instanceof String && otherSortValue instanceof String) {
-        // Collator.getInstance cache's Collator object, so this is relatively
-        // fast.  However, storing it as static somewhere might give a small
-        // performance boost.  If such an approach is take, ensure that the static
-        // variable is updated the user chooses an different language.
-        Collator collator = Collator.getInstance(Locale.getDefault());
-        return collator.compare(ourSortValue, otherSortValue);
-      }
-      try {
-        return ourSortValue.compareTo(otherSortValue);
-      } catch (ClassCastException e) {
-        // It's possible that a row was created, but not refreshed yet.
-        // In that case, one sortValue will be String, and the other will be
-        // a comparable object that the plugin defined.  Those two sortValues 
-        // may not be compatable (for good reason!), so just skip it.
-      }
-    } catch (Exception e) {
-      System.out.println("Could not compare cells");
-      Debug.printStackTrace( e );
-    }
-    return 0;
-  }
-
-  public void invokeToolTipListeners(int type) {
-  	if (tableColumn == null)
-  		return;
-
-    tableColumn.invokeCellToolTipListeners(this, type);
-
-    if (tooltipListeners == null || tooltipErrLoopCount > 2)
-      return;
-
-    int iErrCount = tableColumn.getConsecutiveErrCount();
-    if (iErrCount > 10)
-      return;
-
-    try {
-	    if (type == TOOLTIPLISTENER_HOVER) {
-	      for (int i = 0; i < tooltipListeners.size(); i++)
-	        ((TableCellToolTipListener)(tooltipListeners.get(i))).cellHover(this);
-	    } else {
-	      for (int i = 0; i < tooltipListeners.size(); i++)
-	        ((TableCellToolTipListener)(tooltipListeners.get(i))).cellHoverComplete(this);
-	    }
-	    tooltipErrLoopCount = 0;
-    } catch (Throwable e) {
-      tooltipErrLoopCount++;
-      tableColumn.setConsecutiveErrCount(++iErrCount);
-      pluginError(e);
-      if (tooltipErrLoopCount > 2)
-      	Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
-						"TableCell's tooltip will not be refreshed anymore this session."));
-    }
-  }
-
-  public void invokeMouseListeners(TableCellMouseEvent event) {
-		ArrayList listeners = event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE
-				? cellMouseMoveListeners : cellMouseListeners;
-		if (listeners == null)
-			return;
-		
-		if (event.cell != null && event.row == null) {
-			event.row = event.cell.getTableRow();
-		}
-		
-		for (int i = 0; i < listeners.size(); i++) {
-			try {
-				TableCellMouseListener l = (TableCellMouseListener) (listeners.get(i));
-
-				l.cellMouseTrigger(event);
-
-			} catch (Throwable e) {
-				Debug.printStackTrace(e);
-			}
-		}
-	}
-
-	public void invokeVisibilityListeners(int visibility,
-			boolean invokeColumnListeners) {
-		if (invokeColumnListeners) {
-			tableColumn.invokeCellVisibilityListeners(this, visibility);
-		}
-
-		if (cellVisibilityListeners == null)
-			return;
-
-		for (int i = 0; i < cellVisibilityListeners.size(); i++) {
-			try {
-				TableCellVisibilityListener l = (TableCellVisibilityListener) (cellVisibilityListeners.get(i));
-
-				l.cellVisibilityChanged(this, visibility);
-
-			} catch (Throwable e) {
-				Debug.printStackTrace(e);
-			}
-		}
-	}
-
-
   public static final Comparator TEXT_COMPARATOR = new TextComparator();
   private static class TextComparator implements Comparator {
 		public int compare(Object arg0, Object arg1) {
@@ -1443,29 +539,6 @@ public class TableCellImpl
 		}
   }
   
-	public void setUpToDate(boolean upToDate) {
-	  if (bDebug)
-		  debug("set up to date to " + upToDate);
-		if (upToDate) {
-			setFlag(FLAG_UPTODATE);
-		} else {
-			clearFlag(FLAG_UPTODATE);
-		}
-	}
-	
-	public boolean isUpToDate() {
-		return hasFlag(FLAG_UPTODATE);
-	}
-	
-	public void debug(final String s) {
-		Utils.execSWTThread(new AERunnable() {
-			public void runSupport() {
-				System.out.println(SystemTime.getCurrentTime() + ": r"
-						+ tableRow.getIndex() + "c" + tableColumn.getPosition() + "r.v?"
-						+ ((tableRow.isVisible() ? "Y" : "N")) + ";" + s);
-			}
-		}, true);
-	}
 
 	public Rectangle getBounds() {
 		if (isDisposed()) {
@@ -1487,17 +560,9 @@ public class TableCellImpl
 		ti.setOrientation(TableColumnSWTUtils.convertColumnAlignmentToSWT(align));
 	}
 
-	public String getObfusticatedText() {
-		if (tableColumn.isObfusticated()) {
-			if (tableColumn instanceof ObfusticateCellText) {
-				return ((ObfusticateCellText)tableColumn).getObfusticatedText(this);
-			}
-			
-			return "";
-		}
-		return null;
-	}
-
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getBackgroundGraphic()
+	 */
 	public Graphic getBackgroundGraphic() {
 		if (bufferedTableItem == null) {
 			return null;
@@ -1505,6 +570,9 @@ public class TableCellImpl
   	return new UISWTGraphicImpl(bufferedTableItem.getBackgroundImage());
 	}
 
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableCellSWT#getBackgroundImage()
+	 */
 	public Image getBackgroundImage() {
 		if (bufferedTableItem == null) {
 			return null;
@@ -1516,64 +584,45 @@ public class TableCellImpl
 		return bufferedTableItem;
 	}
 
-	public int getCursorID() {
-		return iCursorID;
-	}
-	
-	public void setCursorID(int cursorID) {
-		iCursorID = cursorID;
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableCellCore#setCursorID(int)
+	 */
+	public boolean setCursorID(int cursorID) {
+		if (!super.setCursorID(cursorID)) {
+			return false;
+		}
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (isMouseOver()) {
-					bufferedTableItem.setCursor(iCursorID);
+					bufferedTableItem.setCursor(getCursorID());
 				}
 			}
 		});
+		return true;
 	}
 	
 	public boolean isMouseOver() {
 		if (bufferedTableItem == null) {
 			return false;
 		}
+		if (!tableRow.isVisible()) {
+			return false;
+		}
 		return bufferedTableItem.isMouseOver();
 	}
 	
-	public int[] getMouseOffset() {
-		Point ofs = ((TableViewSWT) tableRow.getView()).getTableCellMouseOffset(this);
-		return ofs == null ? null : new int[] { ofs.x, ofs.y };
-	}
-	
-	private boolean hasFlag(int flag) {
-		return (flags & flag) != 0;
+	public Rectangle getBoundsOnDisplay() {
+		Rectangle bounds = getBounds();
+		Point pt = ((TableViewSWT<?>) tableRow.getView()).getTableOrTreeSWT().toDisplay(bounds.x, bounds.y);
+		bounds.x = pt.x;
+		bounds.y = pt.y;
+		return bounds;
 	}
 	
-	private void setFlag(int flag) {
-		flags |= flag;
-	}
-	
-	private void clearFlag(int flag) {
-		flags &= ~flag;
-	}
-
-	/**
-	 * @param childCell
-	 *
-	 * @since 3.0.5.3
-	 */
-	public void addChildCell(TableCellImpl childCell) {
-		if (childCells == null) {
-			childCells = new ArrayList(1);
-		}
-		//TODO: childCell.setParentCell(this);
-		childCells.add(childCell);
-	}
-
-  public int getTextAlpha() {
-		return textAlpha;
-	}
-
-	public void setTextAlpha(int textOpacity) {
-		this.textAlpha = textOpacity;
+	@Override
+	public boolean refresh(boolean bDoGraphics, boolean bRowVisible,
+			boolean bCellVisible) {
+		return super.refresh(bDoGraphics, bRowVisible, bCellVisible);
 	}
 
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableCellSWTBase.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableCellSWTBase.java
new file mode 100644
index 0000000..b34231b
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableCellSWTBase.java
@@ -0,0 +1,1341 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Locale;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Display;
+
+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.plugins.ui.Graphic;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.Utils;
+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 com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+public abstract class TableCellSWTBase
+	implements TableCellSWT
+{
+	private static final LogIDs LOGID = LogIDs.GUI;
+
+	private static AEMonitor this_mon = new AEMonitor("TableCell");
+
+	/**
+	 * Plugins read this to see if their datasource has changed.
+	 * {@link #invalidate()} will clear this flag, causing the cell to set its ui again
+	 */
+	protected static final int FLAG_VALID = 1;
+
+	/**
+	 * Indicates if the sort value is also the text displayed.  We can optimize.
+	 */
+	protected static final int FLAG_SORTVALUEISTEXT = 2;
+
+	/**
+	 * Indicates if the tooltip is autogenerated
+	 */
+	protected static final int FLAG_TOOLTIPISAUTO = 4;
+
+	/**
+	 * For refreshing, this flag manages whether the row is actually up to date.
+	 * 
+	 * We don't update any visuals while the row isn't visible.  But, validility
+	 * does get set to true so that the cell isn't forced to refresh every
+	 * cycle when not visible.  (We can't just never call refresh when the row
+	 * is not visible, as refresh also sets the sort value)
+	 *  
+	 * When the row does become visible, we have to invalidate the row so
+	 * that the row will set its visuals again (this time, actually
+	 * updating a viewable object).
+	 */
+	protected static final int FLAG_UPTODATE = 8;
+
+	protected static final int FLAG_DISPOSED = 16;
+
+	/**
+	 * Cell has been invalidated, it must refresh on next cycle
+	 */
+	protected static final int FLAG_MUSTREFRESH = 32;
+
+	/**
+	 * If any visuals change between 2 refreshes, this flag gets set
+	 */
+	public static final int FLAG_VISUALLY_CHANGED_SINCE_REFRESH = 64;
+
+	private static final boolean DEBUGONLYZERO = false;
+
+	private static final boolean DEBUG_FLAGS = false;
+
+	private int flags;
+
+	protected TableRowCore tableRow;
+
+	protected TableColumnCore tableColumn;
+
+	private byte tooltipErrLoopCount;
+
+	public boolean bDebug = false;
+
+	protected ArrayList<TableCellRefreshListener> refreshListeners;
+
+	private ArrayList<TableCellDisposeListener> disposeListeners;
+
+	private ArrayList<TableCellToolTipListener> tooltipListeners;
+
+	private ArrayList<TableCellMouseListener> cellMouseListeners;
+
+	private ArrayList<TableCellMouseMoveListener> cellMouseMoveListeners;
+
+	private ArrayList<TableCellVisibilityListener> cellVisibilityListeners;
+
+	protected ArrayList<TableCellSWTPaintListener> cellSWTPaintListeners;
+
+	private ArrayList<TableCellClipboardListener> cellClipboardListeners;
+
+	protected Comparable sortValue;
+
+	private byte restartRefresh = 0;
+
+	private boolean bInRefreshAsync = false;
+
+	private byte refreshErrLoopCount;
+
+	private byte loopFactor;
+
+	// TODO: private
+	protected static int MAX_REFRESHES = 10;
+
+	private static int MAX_REFRESHES_WITHIN_MS = 100;
+
+	private boolean bInRefresh = false;
+
+	private long lastRefresh;
+
+	// TODO: Private
+	protected int numFastRefreshes;
+
+	private Object oToolTip;
+
+	private Object defaultToolTip;
+
+	private int textAlpha = 255;
+
+	private boolean doFillCell = false;
+
+	private int iCursorID = SWT.CURSOR_ARROW;
+
+	private boolean mouseOver;
+
+	private Image icon;
+	
+	private Graphic graphic = null;
+
+	public TableCellSWTBase(TableRowCore row, TableColumnCore column) {
+		flags = FLAG_SORTVALUEISTEXT;
+		tableRow = row;
+		tableColumn = column;
+		tooltipErrLoopCount = 0;
+		refreshErrLoopCount = 0;
+		loopFactor = 0;
+		if (column != null && column.getType() == TableColumnCore.TYPE_GRAPHIC) {
+			setMarginHeight(1);
+			setMarginWidth(1);
+		}
+	}
+
+	public void addRefreshListener(TableCellRefreshListener listener) {
+		try {
+			this_mon.enter();
+
+			if (refreshListeners == null)
+				refreshListeners = new ArrayList(1);
+
+			if (bDebug) {
+				debug("addRefreshListener; count=" + refreshListeners.size());
+			}
+			refreshListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeRefreshListener(TableCellRefreshListener listener) {
+		try {
+			this_mon.enter();
+
+			if (refreshListeners == null)
+				return;
+
+			refreshListeners.remove(listener);
+		} finally {
+
+			this_mon.exit();
+		}
+	}
+
+	public void addDisposeListener(TableCellDisposeListener listener) {
+		try {
+			this_mon.enter();
+
+			if (disposeListeners == null) {
+				disposeListeners = new ArrayList(1);
+			}
+			disposeListeners.add(listener);
+		} finally {
+
+			this_mon.exit();
+		}
+	}
+
+	public void removeDisposeListener(TableCellDisposeListener listener) {
+		try {
+			this_mon.enter();
+
+			if (disposeListeners == null)
+				return;
+
+			disposeListeners.remove(listener);
+
+		} finally {
+
+			this_mon.exit();
+		}
+	}
+
+	public void addToolTipListener(TableCellToolTipListener listener) {
+		try {
+			this_mon.enter();
+
+			if (tooltipListeners == null) {
+				tooltipListeners = new ArrayList(1);
+			}
+			tooltipListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeToolTipListener(TableCellToolTipListener listener) {
+		try {
+			this_mon.enter();
+
+			if (tooltipListeners == null)
+				return;
+
+			tooltipListeners.remove(listener);
+		} finally {
+
+			this_mon.exit();
+		}
+	}
+
+	public void addMouseListener(TableCellMouseListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellMouseListeners == null)
+				cellMouseListeners = new ArrayList(1);
+
+			cellMouseListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeMouseListener(TableCellMouseListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellMouseListeners == null)
+				return;
+
+			cellMouseListeners.remove(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void addMouseMoveListener(TableCellMouseMoveListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellMouseMoveListeners == null)
+				cellMouseMoveListeners = new ArrayList(1);
+
+			cellMouseMoveListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeMouseMoveListener(TableCellMouseMoveListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellMouseMoveListeners == null)
+				return;
+
+			cellMouseMoveListeners.remove(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void addVisibilityListener(TableCellVisibilityListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellVisibilityListeners == null)
+				cellVisibilityListeners = new ArrayList(1);
+
+			cellVisibilityListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void removeVisibilityListener(TableCellVisibilityListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellVisibilityListeners == null)
+				return;
+
+			cellVisibilityListeners.remove(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	/**
+	 * @param listenerObject
+	 *
+	 * @since 3.1.1.1
+	 */
+	private void addSWTPaintListener(TableCellSWTPaintListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellSWTPaintListeners == null)
+				cellSWTPaintListeners = new ArrayList(1);
+
+			cellSWTPaintListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public void invokeSWTPaintListeners(GC gc) {
+		if (tableColumn != null) {
+			Object[] swtPaintListeners = tableColumn.getCellOtherListeners("SWTPaint");
+			if (swtPaintListeners != null) {
+				for (int i = 0; i < swtPaintListeners.length; i++) {
+					try {
+						TableCellSWTPaintListener l = (TableCellSWTPaintListener) swtPaintListeners[i];
+
+						l.cellPaint(gc, this);
+
+					} catch (Throwable e) {
+						Debug.printStackTrace(e);
+					}
+				}
+			}
+		}
+
+		if (cellSWTPaintListeners == null) {
+			return;
+		}
+
+		for (int i = 0; i < cellSWTPaintListeners.size(); i++) {
+			try {
+				TableCellSWTPaintListener l = (TableCellSWTPaintListener) (cellSWTPaintListeners.get(i));
+
+				l.cellPaint(gc, this);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	private void addCellClipboardListener(TableCellClipboardListener listener) {
+		try {
+			this_mon.enter();
+
+			if (cellClipboardListeners == null)
+				cellClipboardListeners = new ArrayList<TableCellClipboardListener>(1);
+
+			cellClipboardListeners.add(listener);
+
+		} finally {
+			this_mon.exit();
+		}
+	}
+
+	public String getClipboardText() {
+		if (isDisposed()) {
+			return "";
+		}
+		String text = tableColumn.getClipboardText(this);
+		if (text != null) {
+			return text;
+		}
+
+		try {
+			this_mon.enter();
+
+			if (cellClipboardListeners != null) {
+				for (TableCellClipboardListener l : cellClipboardListeners) {
+					try {
+						text = l.getClipboardText(this);
+					} catch (Exception e) {
+						Debug.out(e);
+					}
+					if (text != null) {
+						break;
+					}
+				}
+			}
+		} finally {
+			this_mon.exit();
+		}
+		if (text == null) {
+			text = this.getText();
+		}
+		return text;
+	}
+
+	public void addListeners(Object listenerObject) {
+		if (listenerObject instanceof TableCellDisposeListener) {
+			addDisposeListener((TableCellDisposeListener) listenerObject);
+		}
+
+		if (listenerObject instanceof TableCellRefreshListener)
+			addRefreshListener((TableCellRefreshListener) listenerObject);
+
+		if (listenerObject instanceof TableCellToolTipListener)
+			addToolTipListener((TableCellToolTipListener) listenerObject);
+
+		if (listenerObject instanceof TableCellMouseMoveListener) {
+			addMouseMoveListener((TableCellMouseMoveListener) listenerObject);
+		}
+
+		if (listenerObject instanceof TableCellMouseListener) {
+			addMouseListener((TableCellMouseListener) listenerObject);
+		}
+
+		if (listenerObject instanceof TableCellVisibilityListener)
+			addVisibilityListener((TableCellVisibilityListener) listenerObject);
+
+		if (listenerObject instanceof TableCellSWTPaintListener)
+			addSWTPaintListener((TableCellSWTPaintListener) listenerObject);
+
+		if (listenerObject instanceof TableCellClipboardListener)
+			addCellClipboardListener((TableCellClipboardListener) listenerObject);
+	}
+
+	public void invokeToolTipListeners(int type) {
+		if (tableColumn == null)
+			return;
+
+		tableColumn.invokeCellToolTipListeners(this, type);
+
+		if (tooltipListeners == null || tooltipErrLoopCount > 2)
+			return;
+
+		int iErrCount = tableColumn.getConsecutiveErrCount();
+		if (iErrCount > 10)
+			return;
+
+		try {
+			if (type == TOOLTIPLISTENER_HOVER) {
+				for (int i = 0; i < tooltipListeners.size(); i++)
+					((TableCellToolTipListener) (tooltipListeners.get(i))).cellHover(this);
+			} else {
+				for (int i = 0; i < tooltipListeners.size(); i++)
+					((TableCellToolTipListener) (tooltipListeners.get(i))).cellHoverComplete(this);
+			}
+			tooltipErrLoopCount = 0;
+		} catch (Throwable e) {
+			tooltipErrLoopCount++;
+			tableColumn.setConsecutiveErrCount(++iErrCount);
+			pluginError(e);
+			if (tooltipErrLoopCount > 2)
+				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+						"TableCell's tooltip will not be refreshed anymore this session."));
+		}
+	}
+
+	public void invokeMouseListeners(TableCellMouseEvent event) {
+		ArrayList listeners = event.eventType == TableCellMouseEvent.EVENT_MOUSEMOVE
+				? cellMouseMoveListeners : cellMouseListeners;
+		if (listeners == null)
+			return;
+
+		if (event.cell != null && event.row == null) {
+			event.row = event.cell.getTableRow();
+		}
+
+		for (int i = 0; i < listeners.size(); i++) {
+			try {
+				TableCellMouseListener l = (TableCellMouseListener) (listeners.get(i));
+
+				l.cellMouseTrigger(event);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	public void invokeVisibilityListeners(int visibility,
+			boolean invokeColumnListeners) {
+		if (invokeColumnListeners && tableColumn != null) {
+			tableColumn.invokeCellVisibilityListeners(this, visibility);
+		}
+
+		if (cellVisibilityListeners == null)
+			return;
+
+		for (int i = 0; i < cellVisibilityListeners.size(); i++) {
+			try {
+				TableCellVisibilityListener l = cellVisibilityListeners.get(i);
+
+				l.cellVisibilityChanged(this, visibility);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	public void dispose() {
+		setFlag(FLAG_DISPOSED);
+
+		if (tableColumn != null) {
+			tableColumn.invokeCellDisposeListeners(this);
+		}
+
+		if (disposeListeners != null) {
+			try {
+				for (Iterator iter = disposeListeners.iterator(); iter.hasNext();) {
+					TableCellDisposeListener listener = (TableCellDisposeListener) iter.next();
+					listener.dispose(this);
+				}
+				disposeListeners = null;
+			} catch (Throwable e) {
+				pluginError(e);
+			}
+		}
+
+		refreshListeners = null;
+		tableColumn = null;
+		tableRow = null;
+		sortValue = null;
+	}
+
+	public void debug(final String s) {
+		if (DEBUGONLYZERO && tableColumn.getPosition() != 0) {
+			return;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (tableRow == null) {
+					System.out.println(SystemTime.getCurrentTime() + ": c"
+							+ (tableColumn == null ? null : tableColumn.getPosition()) + ";F=" + flagToText(flags, false)
+							+ ";" + s);
+
+				} else {
+					System.out.println(SystemTime.getCurrentTime() + ": r"
+							+ tableRow.getIndex() + "c"
+							+ (tableColumn == null ? null : tableColumn.getPosition())
+							+ ";r.v?" + ((tableRow.isVisible() ? "Y" : "N")) + "F="
+							+ flagToText(flags, false) + ";" + s);
+				}
+			}
+		}, true);
+	}
+
+	protected void pluginError(Throwable e) {
+		if (tableColumn != null) {
+  		String sTitleLanguageKey = tableColumn.getTitleLanguageKey();
+  
+  		String sPosition = tableColumn.getPosition() + " ("
+  				+ MessageText.getString(sTitleLanguageKey) + ")";
+  		Logger.log(new LogEvent(LOGID, "Table Cell Plugin for Column #" + sPosition
+  				+ " generated an exception ", e));
+		} else {
+  		Logger.log(new LogEvent(LOGID, "Table Cell Plugin generated an exception ", e));
+		}
+	}
+
+	protected void pluginError(String s) {
+		String sPosition = "r" + tableRow.getIndex() + "c"
+				+ tableColumn.getPosition();
+		Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+				"Table Cell Plugin for Column #" + sPosition + ":" + s + "\n  "
+						+ Debug.getStackTrace(true, true)));
+	}
+
+	public boolean refresh() {
+		return refresh(true);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean)
+	public boolean refresh(boolean bDoGraphics) {
+		boolean isRowShown;
+		if (tableRow != null) {
+			TableView view = tableRow.getView();
+			isRowShown = view.isRowVisible(tableRow);
+		} else {
+			isRowShown = true;
+		}
+		boolean isCellShown = isRowShown && isShown();
+		return refresh(bDoGraphics, isRowShown, isCellShown);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean, boolean)
+	public boolean refresh(boolean bDoGraphics, boolean bRowVisible) {
+		boolean isCellShown = bRowVisible && isShown();
+		return refresh(bDoGraphics, bRowVisible, isCellShown);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableCellCore#refresh(boolean, boolean, boolean)
+	public boolean refresh(boolean bDoGraphics, boolean bRowVisible,
+			boolean bCellVisible) {
+		//  	if (Utils.isThisThreadSWT()) {
+		//  		System.out.println("ONSWT: " + Debug.getCompressedStackTrace());
+		//  	}
+		TableColumnCore	tc = tableColumn;
+
+		if (tc == null) {
+			return false;
+		}
+		boolean ret = getVisuallyChangedSinceRefresh();
+		// don't clear flag -- since anyone can call refresh(), only the code that
+		// actually refreshes the display should clear the flag.
+		//clearFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+
+		int iErrCount = 0;
+		if (refreshErrLoopCount > 2) {
+			return ret;
+		}
+
+		iErrCount = tc.getConsecutiveErrCount();
+		if (iErrCount > 10) {
+			refreshErrLoopCount = 3;
+			return ret;
+		}
+
+		if (bInRefresh) {
+			// Skip a Refresh call when being called from within refresh.
+			// This could happen on virtual tables where SetData calls us again, or
+			// if we ever introduce plugins to refresh.
+			if (bDebug)
+				debug("Calling Refresh from Refresh :) Skipping.");
+			return ret;
+		}
+		try {
+			bInRefresh = true;
+			if (ret) {
+				long now = SystemTime.getCurrentTime();
+				if (now - lastRefresh < MAX_REFRESHES_WITHIN_MS) {
+					numFastRefreshes++;
+					if (numFastRefreshes >= MAX_REFRESHES) {
+						if ((numFastRefreshes % MAX_REFRESHES) == 0) {
+							pluginError("this plugin is crazy. tried to refresh "
+									+ numFastRefreshes + " times in " + (now - lastRefresh)
+									+ "ms");
+						}
+						return ret;
+					}
+				} else {
+					numFastRefreshes = 0;
+					lastRefresh = now;
+				}
+			}
+
+			// See bIsUpToDate variable comments
+			if (bCellVisible && !isUpToDate()) {
+				if (bDebug)
+					debug("Setting Invalid because visible & not up to date");
+				clearFlag(FLAG_VALID);
+				setFlag(FLAG_UPTODATE);
+			} else if (!bCellVisible && isUpToDate()) {
+				if (bDebug)
+					debug("Setting not up to date because cell not visible "
+							+ Debug.getCompressedStackTrace());
+				clearFlag(FLAG_UPTODATE);
+			}
+
+			if (bDebug) {
+				debug("Cell Valid?" + hasFlag(FLAG_VALID) + "; Visible?"
+						+ tableRow.isVisible() + "/" + isShown());
+			}
+			int iInterval = tc.getRefreshInterval();
+			if (iInterval == TableColumnCore.INTERVAL_INVALID_ONLY
+					&& !hasFlag(FLAG_MUSTREFRESH | FLAG_VALID)
+					&& hasFlag(FLAG_SORTVALUEISTEXT) && sortValue != null
+					&& tc.getType() == TableColumnCore.TYPE_TEXT_ONLY) {
+				if (bCellVisible) {
+					if (bDebug)
+						debug("fast refresh: setText");
+					ret = setText((String) sortValue);
+					setFlag(FLAG_VALID);
+				}
+			} else if ((iInterval == TableColumnCore.INTERVAL_LIVE
+					|| (iInterval == TableColumnCore.INTERVAL_GRAPHIC && bDoGraphics)
+					|| (iInterval > 0 && (loopFactor % iInterval) == 0)
+					|| !hasFlag(FLAG_VALID) || hasFlag(FLAG_MUSTREFRESH))) {
+				boolean bWasValid = isValid();
+
+				ret = hasFlag(FLAG_MUSTREFRESH);
+				if (ret) {
+					clearFlag(FLAG_MUSTREFRESH);
+				}
+
+				if (bDebug) {
+					debug("invoke refresh; wasValid? " + bWasValid);
+				}
+
+				long lTimeStart = Constants.isCVSVersion()
+						? SystemTime.getMonotonousTime() : 0;
+				tc.invokeCellRefreshListeners(this, !bCellVisible);
+				if (refreshListeners != null) {
+					for (TableCellRefreshListener l : refreshListeners) {
+						if (l instanceof TableCellLightRefreshListener) {
+							((TableCellLightRefreshListener) l).refresh(this, !bCellVisible);
+						} else {
+							l.refresh(this);
+						}
+					}
+				}
+				if (Constants.isCVSVersion()) {
+					long lTimeEnd = SystemTime.getMonotonousTime();
+					tc.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)) {
+					setFlag(FLAG_VALID);
+				}
+			}
+			loopFactor++;
+			refreshErrLoopCount = 0;
+			if (iErrCount > 0)
+				tc.setConsecutiveErrCount(0);
+
+			// has changed if visually changed or "must refresh"
+			ret |= getVisuallyChangedSinceRefresh();
+			if (bDebug)
+				debug("refresh done; visual change? " + ret + ";"
+						+ Debug.getCompressedStackTrace());
+		} catch (Throwable e) {
+			refreshErrLoopCount++;
+			if (tc != null) {
+				tc.setConsecutiveErrCount(++iErrCount);
+			}
+			pluginError(e);
+			if (refreshErrLoopCount > 2)
+				Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
+						"TableCell will not be refreshed anymore this session."));
+		} finally {
+			bInRefresh = false;
+		}
+
+		return ret;
+	}
+
+	public boolean setSortValue(Comparable valueToSort) {
+		if (!tableColumn.isSortValueLive()) {
+			// objects that can't change aren't live
+			if (!(valueToSort instanceof Number) && !(valueToSort instanceof String)
+					&& !(valueToSort instanceof TableColumnSortObject)) {
+				tableColumn.setSortValueLive(true);
+			}
+		}
+		return _setSortValue(valueToSort);
+	}
+
+	private boolean _setSortValue(Comparable valueToSort) {
+		if (isDisposed()) {
+			return false;
+		}
+
+		if (sortValue == valueToSort)
+			return false;
+
+		if (hasFlag(FLAG_SORTVALUEISTEXT)) {
+			clearFlag(FLAG_SORTVALUEISTEXT);
+			if (sortValue instanceof String)
+				// Make sure text is actually in the cell (it may not have been if
+				// cell wasn't created at the time of setting)
+				setText((String) sortValue);
+		}
+
+		if ((valueToSort instanceof String) && (sortValue instanceof String)
+				&& sortValue.equals(valueToSort)) {
+			return false;
+		}
+
+		if ((valueToSort instanceof Number) && (sortValue instanceof Number)
+				&& sortValue.equals(valueToSort)) {
+			return false;
+		}
+
+		if (bDebug)
+			debug("Setting SortValue to "
+					+ ((valueToSort == null) ? "null" : valueToSort.getClass().getName()));
+
+		tableColumn.setLastSortValueChange(SystemTime.getCurrentTime());
+		sortValue = valueToSort;
+
+		// Columns with SWT Paint Listeners usually rely on a repaint whenever the
+		// sort value changes
+		if (cellSWTPaintListeners != null
+				|| tableColumn.hasCellOtherListeners("SWTPaint")) {
+    	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+			//redraw();
+		}
+
+		return true;
+	}
+
+	public boolean setSortValue(long valueToSort) {
+		if (isDisposed()) {
+			return false;
+		}
+
+		if ((sortValue instanceof Long)
+				&& ((Long) sortValue).longValue() == valueToSort)
+			return false;
+
+		return _setSortValue(Long.valueOf(valueToSort));
+	}
+
+	public boolean setSortValue(float valueToSort) {
+		if (isDisposed()) {
+			return false;
+		}
+
+		if (sortValue instanceof Float
+				&& ((Float) sortValue).floatValue() == valueToSort)
+			return false;
+
+		return _setSortValue(new Float(valueToSort));
+	}
+
+	public Comparable getSortValue() {
+		return sortValue;
+	}
+
+	public boolean isValid() {
+		// Called often.. inline faster
+		return (flags & FLAG_VALID) != 0;
+		//return hasFlag(FLAG_VALID);
+	}
+
+	public boolean isDisposed() {
+		return (flags & FLAG_DISPOSED) != 0;
+	}
+
+	public boolean hasFlag(int flag) {
+		return (flags & flag) != 0;
+	}
+
+	public void setFlag(int flag) {
+		if (DEBUG_FLAGS && (flags & flag) != flag) {
+			debug("SET FLAG " + flagToText((~flags) & flag, true) + " via "
+					+ Debug.getStackTrace(true, true, 1, 7));
+		}
+		flags |= flag;
+	}
+
+	public void clearFlag(int flag) {
+		if (DEBUG_FLAGS && (flags & flag) != 0) {
+			debug("CLEAR FLAG " + flagToText(flags & flag, true) + " via "
+					+ Debug.getStackTrace(true, true, 1, 7));
+		}
+		flags &= ~flag;
+	}
+
+	/**
+	 * If a plugin in trying to invalidate a cell, then clear the sort value
+	 * too.
+	 */
+	public void invalidate() {
+		if (isDisposed()) {
+			return;
+		}
+
+		invalidate(true);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableCellCore#invalidate(boolean)
+	 */
+	public void invalidate(boolean bMustRefresh) {
+		//if (bInRefresh && Utils.isThisThreadSWT()) {
+		//	System.out.println("Invalidating when in refresh via " + Debug.getCompressedStackTrace());
+		//}
+		if ((flags & (FLAG_VALID | FLAG_VISUALLY_CHANGED_SINCE_REFRESH)) == FLAG_VISUALLY_CHANGED_SINCE_REFRESH) { //!hasFlag(FLAG_VALID)
+			if (bMustRefresh) {
+				if ((flags & FLAG_MUSTREFRESH) != 0) {
+					return;
+				}
+			} else {
+				if (DEBUG_FLAGS) {
+					debug("ALREADY FLAGGED for invalidate via " + Debug.getCompressedStackTrace(7));
+				}
+				return;
+			}
+		}
+		clearFlag(FLAG_VALID);
+
+		if (bDebug)
+			debug("Invalidate Cell;" + bMustRefresh);
+
+		if (bMustRefresh) {
+			setFlag(FLAG_MUSTREFRESH | FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+		} else {
+			setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableCellCore#refreshAsync()
+	public void refreshAsync() {
+		if (bInRefreshAsync) {
+			//System.out.println(System.currentTimeMillis() + "] SKIP " + restartRefresh);
+			if (restartRefresh < Byte.MAX_VALUE) {
+				restartRefresh++;
+			}
+			return;
+		}
+		bInRefreshAsync = true;
+
+		AERunnable runnable = new AERunnable() {
+			public void runSupport() {
+				//System.out.println(System.currentTimeMillis() + "] REFRESH!");
+				restartRefresh = 0;
+				refresh(true);
+				bInRefreshAsync = false;
+				//System.out.println(System.currentTimeMillis() + "] REFRESH OUT!");
+				if (restartRefresh > 0) {
+					refreshAsync();
+				}
+			}
+		};
+		Utils.execSWTThreadLater(25, runnable);
+	}
+
+	public void setUpToDate(boolean upToDate) {
+		if (bDebug)
+			debug("set up to date to " + upToDate);
+		if (upToDate) {
+			setFlag(FLAG_UPTODATE);
+		} else {
+			clearFlag(FLAG_UPTODATE);
+		}
+	}
+
+	public boolean isUpToDate() {
+		return hasFlag(FLAG_UPTODATE);
+	}
+
+	public boolean getVisuallyChangedSinceRefresh() {
+		return hasFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+	}
+
+	public void clearVisuallyChangedSinceRefresh() {
+		clearFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+	}
+
+	/** Compare our sortValue to the specified object.  Assumes the object 
+	 * is TableCellSWTBase (safe assumption)
+	 */
+	public int compareTo(Object o) {
+		try {
+			Comparable ourSortValue = getSortValue();
+			Comparable otherSortValue = ((TableCellSWTBase) o).getSortValue();
+			if (ourSortValue instanceof String && otherSortValue instanceof String) {
+				// Collator.getInstance cache's Collator object, so this is relatively
+				// fast.  However, storing it as static somewhere might give a small
+				// performance boost.  If such an approach is take, ensure that the static
+				// variable is updated the user chooses an different language.
+				Collator collator = Collator.getInstance(Locale.getDefault());
+				return collator.compare(ourSortValue, otherSortValue);
+			}
+			try {
+				return ourSortValue.compareTo(otherSortValue);
+			} catch (ClassCastException e) {
+				// It's possible that a row was created, but not refreshed yet.
+				// In that case, one sortValue will be String, and the other will be
+				// a comparable object that the plugin defined.  Those two sortValues 
+				// may not be compatable (for good reason!), so just skip it.
+			}
+		} catch (Exception e) {
+			System.out.println("Could not compare cells");
+			Debug.printStackTrace(e);
+		}
+		return 0;
+	}
+
+	public boolean needsPainting() {
+		if (isDisposed()) {
+			return false;
+		}
+
+		if (cellSWTPaintListeners != null
+				|| tableColumn.hasCellOtherListeners("SWTPaint")) {
+			return true;
+		}
+
+		return getGraphic() != null;
+	}
+
+	public boolean setText(String text) {
+		if (isDisposed()) {
+			return false;
+		}
+
+		if (text == null)
+			text = "";
+		boolean bChanged = false;
+
+		if (hasFlag(FLAG_SORTVALUEISTEXT) && !text.equals(sortValue)) {
+			bChanged = true;
+			sortValue = text;
+			tableColumn.setLastSortValueChange(SystemTime.getCurrentTime());
+			if (bDebug)
+				debug("Setting SortValue to text;");
+		}
+
+		// Slower than setText(..)!
+		//  	if (isInvisibleAndCanRefresh()) {
+		//  		if (bDebug) {
+		//  			debug("setText ignored: invisible");
+		//  		}
+		//  		return false;
+		//  	}
+
+		if (uiSetText(text) && !hasFlag(FLAG_SORTVALUEISTEXT))
+			bChanged = true;
+
+		if (bDebug) {
+			debug("setText (" + bChanged + ") : " + text);
+		}
+
+		if (bChanged) {
+			setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+		}
+
+		boolean do_auto = tableColumn == null ? false : tableColumn.doesAutoTooltip();
+
+		// If we were using auto tooltips (and we aren't any more), then
+		// clear up previously set tooltips.
+		if (!do_auto) {
+			if (hasFlag(FLAG_TOOLTIPISAUTO)) {
+				this.oToolTip = null;
+				clearFlag(FLAG_TOOLTIPISAUTO);
+			}
+		}
+
+		else {
+			this.oToolTip = text;
+			setFlag(FLAG_TOOLTIPISAUTO);
+		}
+
+		return bChanged;
+	}
+
+	public void setToolTip(Object tooltip) {
+		oToolTip = tooltip;
+
+		if (tooltip == null) {
+			setFlag(FLAG_TOOLTIPISAUTO);
+		} else {
+			clearFlag(FLAG_TOOLTIPISAUTO);
+		}
+	}
+
+	public Object getToolTip() {
+		return oToolTip;
+	}
+
+	public Object getDefaultToolTip() {
+		return defaultToolTip;
+	}
+
+	public void setDefaultToolTip(Object tt) {
+		defaultToolTip = tt;
+	}
+
+	public abstract boolean uiSetText(String text);
+
+  public void doPaint(GC gc) {
+  	//This sometimes causes a infinite loop if the listener invalidates
+  	//the drawing area
+  	//if ((!hasFlag(FLAG_UPTODATE) || !hasFlag(FLAG_VALID)) && !bInRefresh && !bInRefreshAsync
+		//		&& (refreshListeners != null || tableColumn.hasCellRefreshListener())) {
+  	//	if (bDebug) {
+  	//		debug("doPaint: invoke refresh");
+  	//	}
+  	//	refresh(true);
+  	//}
+
+		if (bDebug) {
+			debug("doPaint up2date:" + hasFlag(FLAG_UPTODATE) + ";v:" + hasFlag(FLAG_VALID) + ";rl=" + refreshListeners);
+		}
+		
+		invokeSWTPaintListeners(gc);
+  }
+
+  public int getTextAlpha() {
+		return textAlpha;
+	}
+
+	public void setTextAlpha(int textOpacity) {
+		this.textAlpha = textOpacity;
+	}
+
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableCellSWT#getTableRowSWT()
+	public TableRowSWT getTableRowSWT() {
+		if (tableRow instanceof TableRowSWT) {
+			return (TableRowSWT)tableRow;
+		}
+		return null;
+	}
+
+  public TableRowCore getTableRowCore() {
+    return tableRow;
+  }
+  
+  private String flagToText(int flag, boolean onlySet) {
+  	StringBuilder sb = new StringBuilder();
+  	sb.append((flag & FLAG_DISPOSED) > 0 ? 'D' : onlySet ? ' ' : 'd');
+  	sb.append((flag & FLAG_MUSTREFRESH) > 0 ? 'M' : onlySet ? ' ' : 'm');
+  	sb.append((flag & FLAG_SORTVALUEISTEXT) > 0 ? 'S' : onlySet ? ' ' : 's');
+  	sb.append((flag & FLAG_TOOLTIPISAUTO) > 0 ? 'T' : onlySet ? ' ' : 't');
+  	sb.append((flag & FLAG_UPTODATE) > 0 ? 'U' : onlySet ? ' ' : 'u');
+  	sb.append((flag & FLAG_VALID) > 0 ? 'V' : onlySet ? ' ' : 'v');
+  	sb.append((flag & FLAG_VISUALLY_CHANGED_SINCE_REFRESH) > 0 ? "VC" : onlySet ? ' ' : "vc");
+  	return sb.toString();
+  }
+
+	public abstract int getWidthRaw();
+
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#setFillCell(boolean)
+	 */
+	public void setFillCell(boolean doFillCell) {
+		this.doFillCell = doFillCell;
+	}
+	
+	public boolean getFillCell() {
+		return doFillCell;
+	}
+
+
+	public TableColumnCore getTableColumnCore() {
+		return tableColumn;
+	}
+	
+	public boolean setCursorID(int cursorID) {
+		if (iCursorID == cursorID) {
+			return false;
+		}
+		iCursorID = cursorID;
+		return true;
+	}
+
+
+	public int getCursorID() {
+		return iCursorID;
+	}
+
+	public void setMouseOver(boolean b) {
+		mouseOver = b;
+	}
+
+	public boolean isMouseOver() {
+		if (tableRow != null && !tableRow.isVisible()) {
+			// XXX: Should trigger event and set mouseOver false?
+			return false;
+		}
+		return mouseOver;
+	}
+
+  public boolean setIcon(Image img) {
+  	if (isInvisibleAndCanRefresh())
+  		return false;
+
+  	icon = img;
+  	
+    graphic = null;
+    setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+    return true;
+  }
+  
+  public Image getIcon() {
+  	return icon;
+  }
+
+  // @see org.gudy.azureus2.ui.swt.views.table.TableCellSWT#setGraphic(org.eclipse.swt.graphics.Image)
+  public boolean setGraphic(Image img) {
+  	return setGraphic(new UISWTGraphicImpl(img));
+  }
+
+  // @see org.gudy.azureus2.plugins.ui.tables.TableCell#setGraphic(org.gudy.azureus2.plugins.ui.Graphic)
+  public boolean setGraphic(Graphic img) {
+  	if (img != null && isDisposed()) {
+			return false;
+  	}
+
+		if (tableColumn == null
+				|| tableColumn.getType() != TableColumnCore.TYPE_GRAPHIC) {
+      return false;
+    }
+
+    if (img == graphic && numFastRefreshes >= MAX_REFRESHES) {
+    	pluginError("TableCellImpl::setGraphic to same Graphic object. "
+					+ "Forcing refresh.");
+    }
+    
+    boolean changed = (img == graphic || (img != null && !img.equals(graphic)) || (graphic != null && !graphic.equals(img)));
+    
+    graphic = img;
+    
+    if (changed) {
+    	setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+    	redraw();
+    }
+    
+    return changed;
+  }
+
+  public Graphic getGraphic() {
+  	return graphic;
+  }
+  
+  public Image getGraphicSWT() {
+		return (graphic instanceof UISWTGraphic)
+				? ((UISWTGraphic) graphic).getImage() : null;
+  }
+
+	public boolean isInvisibleAndCanRefresh() {
+  	return !isDisposed() && !isShown()
+				&& (refreshListeners != null || tableColumn.hasCellRefreshListener());
+	}
+
+  public int[] getBackground() {
+		Color color = getBackgroundSWT();
+
+		if (color == null) {
+			return null;
+		}
+
+		return new int[] {
+			color.getRed(),
+			color.getGreen(),
+			color.getBlue()
+		};
+	}
+
+  // @see org.gudy.azureus2.plugins.ui.tables.TableCell#getForeground()
+  public int[] getForeground() {
+		Color color = getForegroundSWT();
+
+		if (color == null) {
+			return new int[3];
+		}
+
+		return new int[] { color.getRed(), color.getGreen(), color.getBlue()
+		};
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#setForeground(int, int, int)
+	 */
+	public boolean setForeground(int red, int green, int blue) {
+		// Don't need to set when not visible
+		if (isInvisibleAndCanRefresh()) {
+			return false;
+		}
+
+		if (red < 0 || green < 0 || blue < 0) {
+			return setForeground((Color) null);
+		}
+		return setForeground(new RGB(red, green, blue));
+	}
+
+	private boolean setForeground(final RGB rgb) {
+		Color colorFG = getForegroundSWT();
+		boolean changed = colorFG == null || colorFG.isDisposed()
+				|| !colorFG.getRGB().equals(rgb);
+		if (changed) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					setForeground(ColorCache.getColor(Display.getCurrent(), rgb));
+				}
+			});
+		}
+		return changed;
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCell#setForeground(int[])
+	public boolean setForeground(int[] rgb) {
+		if (rgb == null || rgb.length < 3) {
+			return setForeground((Color) null);
+		}
+		return setForeground(rgb[0], rgb[1], rgb[2]);
+	}
+
+  public boolean setForegroundToErrorColor() {
+	  return setForeground(Colors.colorError);
+  }
+
+	public int[] getMouseOffset() {
+		Point ofs = ((TableViewSWT) tableRow.getView()).getTableCellMouseOffset(this);
+		return ofs == null ? null : new int[] { ofs.x, ofs.y };
+	}
+
+	public String getObfusticatedText() {
+		if (isDisposed()) {
+			return null;
+		}
+		if (tableColumn.isObfusticated()) {
+			if (tableColumn instanceof ObfusticateCellText) {
+				return ((ObfusticateCellText)tableColumn).getObfusticatedText(this);
+			}
+			
+			return "";
+		}
+		return null;
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableColumnDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableColumnDelegate.java
new file mode 100644
index 0000000..db29858
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableColumnDelegate.java
@@ -0,0 +1,205 @@
+/**
+ * Created on May 5, 2010
+ *
+ * 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.impl;
+
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * @author TuxPaper
+ * @created May 5, 2010
+ *
+ */
+public class TableColumnDelegate
+	implements TableColumnOrTreeColumn
+{
+	TableColumn column;
+
+	public TableColumnDelegate(TableColumn column) {
+		this.column = column;
+	}
+
+	public TableColumnDelegate(Table table, int style) {
+		column = new TableColumn(table, style);
+	}
+
+	public Image getImage() {
+		return column.getImage();
+	}
+
+	public String getText() {
+		return column.getText();
+	}
+
+	public void addControlListener(ControlListener listener) {
+		column.addControlListener(listener);
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		column.addListener(eventType, listener);
+	}
+
+	public void addSelectionListener(SelectionListener listener) {
+		column.addSelectionListener(listener);
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		column.addDisposeListener(listener);
+	}
+
+	public TableOrTreeSWT getParent() {
+		return TableOrTreeUtils.getTableOrTreeSWT(column.getParent());
+	}
+
+	public boolean getMoveable() {
+		return column.getMoveable();
+	}
+
+	public boolean getResizable() {
+		return column.getResizable();
+	}
+
+	public String getToolTipText() {
+		return column.getToolTipText();
+	}
+
+	public int getWidth() {
+		return column.getWidth();
+	}
+
+	public void dispose() {
+		column.dispose();
+	}
+
+	public boolean equals(Object obj) {
+		return column.equals(obj);
+	}
+
+	public int getAlignment() {
+		return column.getAlignment();
+	}
+
+	public Object getData() {
+		return column.getData();
+	}
+
+	public Object getData(String key) {
+		return column.getData(key);
+	}
+
+	public Display getDisplay() {
+		return column.getDisplay();
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return column.getListeners(eventType);
+	}
+
+	public int getStyle() {
+		return column.getStyle();
+	}
+
+	public int hashCode() {
+		return column.hashCode();
+	}
+
+	public void pack() {
+		column.pack();
+	}
+
+	public void removeControlListener(ControlListener listener) {
+		column.removeControlListener(listener);
+	}
+
+	public void removeSelectionListener(SelectionListener listener) {
+		column.removeSelectionListener(listener);
+	}
+
+	public void setAlignment(int alignment) {
+		column.setAlignment(alignment);
+	}
+
+	public void setImage(Image image) {
+		column.setImage(image);
+	}
+
+	public void setMoveable(boolean moveable) {
+		column.setMoveable(moveable);
+	}
+
+	public boolean isDisposed() {
+		return column.isDisposed();
+	}
+
+	public void setResizable(boolean resizable) {
+		column.setResizable(resizable);
+	}
+
+	public boolean isListening(int eventType) {
+		return column.isListening(eventType);
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		column.notifyListeners(eventType, event);
+	}
+
+	public void setText(String string) {
+		column.setText(string);
+	}
+
+	public void setToolTipText(String string) {
+		column.setToolTipText(string);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		column.removeListener(eventType, listener);
+	}
+
+	public void setWidth(int width) {
+		column.setWidth(width);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		column.removeDisposeListener(listener);
+	}
+
+	public void setData(Object data) {
+		column.setData(data);
+	}
+
+	public void setData(String key, Object value) {
+		column.setData(key, value);
+	}
+
+	public String toString() {
+		return column.toString();
+	}
+
+	/////////
+	
+	public Item getColumn() {
+		return column;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableDelegate.java
new file mode 100644
index 0000000..2861d24
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableDelegate.java
@@ -0,0 +1,921 @@
+/**
+ * Created on May 5, 2010
+ *
+ * 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.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.accessibility.Accessible;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * Delegates a SWT {@link Table} into a {@link TableOrTreeSWT} allowing easy
+ * switching from Table and Tree.
+ * <p>
+ * Uses own map for setData and getData for faster lookups and no SWT thread
+ * checking
+ * 
+ * @author TuxPaper
+ * @created May 5, 2010
+ *
+ */
+public class TableDelegate
+	implements TableOrTreeSWT
+{
+	Table table;
+	
+	Map<String, Object> data = new HashMap<String, Object>(5);
+
+	private TableDelegate() {
+	}
+
+	protected TableDelegate(Table table) {
+		this.table = table;
+	}
+
+	protected TableDelegate(Composite parent, int style) {
+		table = new Table(parent, style);
+	}
+
+	public Rectangle computeTrim(int x, int y, int width, int height) {
+		return table.computeTrim(x, y, width, height);
+	}
+
+	public void addControlListener(ControlListener listener) {
+		table.addControlListener(listener);
+	}
+
+	public void changed(Control[] changed) {
+		table.changed(changed);
+	}
+
+	public void addDragDetectListener(DragDetectListener listener) {
+		table.addDragDetectListener(listener);
+	}
+
+	public Rectangle getClientArea() {
+		return table.getClientArea();
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		table.addListener(eventType, listener);
+	}
+
+	public void addFocusListener(FocusListener listener) {
+		table.addFocusListener(listener);
+	}
+
+	public ScrollBar getHorizontalBar() {
+		return table.getHorizontalBar();
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		table.addDisposeListener(listener);
+	}
+
+	public ScrollBar getVerticalBar() {
+		return table.getVerticalBar();
+	}
+
+	public void addHelpListener(HelpListener listener) {
+		table.addHelpListener(listener);
+	}
+
+	public void addKeyListener(KeyListener listener) {
+		table.addKeyListener(listener);
+	}
+
+	public void addMenuDetectListener(MenuDetectListener listener) {
+		table.addMenuDetectListener(listener);
+	}
+
+	public void addMouseListener(MouseListener listener) {
+		table.addMouseListener(listener);
+	}
+
+	public void addMouseTrackListener(MouseTrackListener listener) {
+		table.addMouseTrackListener(listener);
+	}
+
+	public void addMouseMoveListener(MouseMoveListener listener) {
+		table.addMouseMoveListener(listener);
+	}
+
+	public void addMouseWheelListener(MouseWheelListener listener) {
+		table.addMouseWheelListener(listener);
+	}
+
+	public int getBackgroundMode() {
+		return table.getBackgroundMode();
+	}
+
+	public void addPaintListener(PaintListener listener) {
+		table.addPaintListener(listener);
+	}
+
+	public void addSelectionListener(SelectionListener listener) {
+		table.addSelectionListener(listener);
+	}
+
+	public Control[] getChildren() {
+		return table.getChildren();
+	}
+
+	public void addTraverseListener(TraverseListener listener) {
+		table.addTraverseListener(listener);
+	}
+
+	public void dispose() {
+		table.dispose();
+	}
+
+	public Layout getLayout() {
+		return table.getLayout();
+	}
+
+	public Control[] getTabList() {
+		return table.getTabList();
+	}
+
+	public boolean getLayoutDeferred() {
+		return table.getLayoutDeferred();
+	}
+
+	public Point computeSize(int wHint, int hHint) {
+		return table.computeSize(wHint, hHint);
+	}
+
+	public boolean isLayoutDeferred() {
+		return table.isLayoutDeferred();
+	}
+
+	public Object getData() {
+		return getData(null);
+	}
+
+	public void layout() {
+		table.layout();
+	}
+
+	public Object getData(String key) {
+		synchronized (data) {
+			return data.get(key);
+		}
+	}
+
+	public void layout(boolean changed) {
+		table.layout(changed);
+	}
+
+	public Display getDisplay() {
+		return table.getDisplay();
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return table.getListeners(eventType);
+	}
+
+	public void layout(boolean changed, boolean all) {
+		table.layout(changed, all);
+	}
+
+	public int getStyle() {
+		return table.getStyle();
+	}
+
+	public boolean dragDetect(Event event) {
+		return table.dragDetect(event);
+	}
+
+	public boolean isDisposed() {
+		return table.isDisposed();
+	}
+
+	public boolean isListening(int eventType) {
+		return table.isListening(eventType);
+	}
+
+	public boolean dragDetect(MouseEvent event) {
+		return table.dragDetect(event);
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		table.notifyListeners(eventType, event);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		table.removeListener(eventType, listener);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		table.removeDisposeListener(listener);
+	}
+
+	public void setBackgroundMode(int mode) {
+		table.setBackgroundMode(mode);
+	}
+
+	public boolean setFocus() {
+		return table.setFocus();
+	}
+
+	public Image getBackgroundImage() {
+		return table.getBackgroundImage();
+	}
+
+	public void setLayout(Layout layout) {
+		table.setLayout(layout);
+	}
+
+	public int getBorderWidth() {
+		return table.getBorderWidth();
+	}
+
+	public void setLayoutDeferred(boolean defer) {
+		table.setLayoutDeferred(defer);
+	}
+
+	public Rectangle getBounds() {
+		return table.getBounds();
+	}
+
+	public void setTabList(Control[] tabList) {
+		table.setTabList(tabList);
+	}
+
+	public void setData(Object data) {
+		setData(null, data);
+	}
+
+	public Cursor getCursor() {
+		return table.getCursor();
+	}
+
+	public void setData(String key, Object value) {
+		synchronized (data) {
+			data.put(key, value);
+		}
+	}
+
+	public boolean getDragDetect() {
+		return table.getDragDetect();
+	}
+
+	public boolean getEnabled() {
+		return table.getEnabled();
+	}
+
+	public Font getFont() {
+		return table.getFont();
+	}
+
+	public Color getForeground() {
+		return table.getForeground();
+	}
+
+	public Object getLayoutData() {
+		return table.getLayoutData();
+	}
+
+	public Point getLocation() {
+		return table.getLocation();
+	}
+
+	public Menu getMenu() {
+		return table.getMenu();
+	}
+
+	public Monitor getMonitor() {
+		return table.getMonitor();
+	}
+
+	public void clear(int index) {
+		table.clear(index);
+	}
+
+	public Composite getParent() {
+		return table.getParent();
+	}
+
+	public Region getRegion() {
+		return table.getRegion();
+	}
+
+	public void clear(int start, int end) {
+		table.clear(start, end);
+	}
+
+	public Shell getShell() {
+		return table.getShell();
+	}
+
+	public Point getSize() {
+		return table.getSize();
+	}
+
+	public String getToolTipText() {
+		return table.getToolTipText();
+	}
+
+	public boolean getVisible() {
+		return table.getVisible();
+	}
+
+	public String toString() {
+		return table.toString();
+	}
+
+	public void clear(int[] indices) {
+		table.clear(indices);
+	}
+
+	public void clearAll() {
+		table.clearAll();
+	}
+
+	public boolean isEnabled() {
+		return table.isEnabled();
+	}
+
+	public Point computeSize(int wHint, int hHint, boolean changed) {
+		return table.computeSize(wHint, hHint, changed);
+	}
+
+	public boolean isFocusControl() {
+		return table.isFocusControl();
+	}
+
+	public boolean isReparentable() {
+		return table.isReparentable();
+	}
+
+	public boolean isVisible() {
+		return table.isVisible();
+	}
+
+	public void moveAbove(Control control) {
+		table.moveAbove(control);
+	}
+
+	public void moveBelow(Control control) {
+		table.moveBelow(control);
+	}
+
+	public void pack() {
+		table.pack();
+	}
+
+	public void pack(boolean changed) {
+		table.pack(changed);
+	}
+
+	public boolean print(GC gc) {
+		return table.print(gc);
+	}
+
+	public void deselect(int[] indices) {
+		table.deselect(indices);
+	}
+
+	public void deselect(int index) {
+		table.deselect(index);
+	}
+
+	public void redraw() {
+		table.redraw();
+	}
+
+	public void deselect(int start, int end) {
+		table.deselect(start, end);
+	}
+
+	public void redraw(int x, int y, int width, int height, boolean all) {
+		table.redraw(x, y, width, height, all);
+	}
+
+	public void deselectAll() {
+		table.deselectAll();
+	}
+
+	public boolean equals(Object obj) {
+		return table.equals(obj);
+	}
+
+	public boolean forceFocus() {
+		return table.forceFocus();
+	}
+
+	public Accessible getAccessible() {
+		return table.getAccessible();
+	}
+
+	public Color getBackground() {
+		return table.getBackground();
+	}
+
+	public void removeControlListener(ControlListener listener) {
+		table.removeControlListener(listener);
+	}
+
+	public void removeDragDetectListener(DragDetectListener listener) {
+		table.removeDragDetectListener(listener);
+	}
+
+	public void removeFocusListener(FocusListener listener) {
+		table.removeFocusListener(listener);
+	}
+
+	public void removeHelpListener(HelpListener listener) {
+		table.removeHelpListener(listener);
+	}
+
+	public void removeKeyListener(KeyListener listener) {
+		table.removeKeyListener(listener);
+	}
+
+	public void removeMenuDetectListener(MenuDetectListener listener) {
+		table.removeMenuDetectListener(listener);
+	}
+
+	public void removeMouseTrackListener(MouseTrackListener listener) {
+		table.removeMouseTrackListener(listener);
+	}
+
+	public void removeMouseListener(MouseListener listener) {
+		table.removeMouseListener(listener);
+	}
+
+	public void removeMouseMoveListener(MouseMoveListener listener) {
+		table.removeMouseMoveListener(listener);
+	}
+
+	public void removeMouseWheelListener(MouseWheelListener listener) {
+		table.removeMouseWheelListener(listener);
+	}
+
+	public void removePaintListener(PaintListener listener) {
+		table.removePaintListener(listener);
+	}
+
+	public void removeTraverseListener(TraverseListener listener) {
+		table.removeTraverseListener(listener);
+	}
+
+	public TableColumnOrTreeColumn getColumn(int index) {
+		return wrapOrNull(table.getColumn(index));
+	}
+
+	public int getColumnCount() {
+		return table.getColumnCount();
+	}
+
+	public void setBackground(Color color) {
+		table.setBackground(color);
+	}
+
+	public int[] getColumnOrder() {
+		return table.getColumnOrder();
+	}
+
+	public void setBackgroundImage(Image image) {
+		table.setBackgroundImage(image);
+	}
+
+	public TableColumnOrTreeColumn[] getColumns() {
+		return wrapOrNull(table.getColumns());
+	}
+
+	public void setBounds(int x, int y, int width, int height) {
+		table.setBounds(x, y, width, height);
+	}
+
+	public int getGridLineWidth() {
+		return table.getGridLineWidth();
+	}
+
+	public int getHeaderHeight() {
+		return table.getHeaderHeight();
+	}
+
+	public boolean getHeaderVisible() {
+		return table.getHeaderVisible();
+	}
+
+	public TableItemOrTreeItem getItem(int index) {
+		return wrapOrNull(table.getItem(index));
+	}
+
+	public void setBounds(Rectangle rect) {
+		table.setBounds(rect);
+	}
+
+	public TableItemOrTreeItem getItem(Point point) {
+		return wrapOrNull(table.getItem(point));
+	}
+
+	public void setCapture(boolean capture) {
+		table.setCapture(capture);
+	}
+
+	public void setCursor(Cursor cursor) {
+		table.setCursor(cursor);
+	}
+
+	public void setDragDetect(boolean dragDetect) {
+		table.setDragDetect(dragDetect);
+	}
+
+	public void setEnabled(boolean enabled) {
+		table.setEnabled(enabled);
+	}
+
+	public int getItemCount() {
+		return table.getItemCount();
+	}
+
+	public int getItemHeight() {
+		return table.getItemHeight();
+	}
+
+	public TableItemOrTreeItem[] getItems() {
+		return wrapOrNull(table.getItems());
+	}
+
+	public boolean getLinesVisible() {
+		return table.getLinesVisible();
+	}
+
+	public void setForeground(Color color) {
+		table.setForeground(color);
+	}
+
+	public TableItemOrTreeItem[] getSelection() {
+		return wrapOrNull(table.getSelection());
+	}
+
+	public void setLayoutData(Object layoutData) {
+		table.setLayoutData(layoutData);
+	}
+
+	public int getSelectionCount() {
+		return table.getSelectionCount();
+	}
+
+	public void setLocation(int x, int y) {
+		table.setLocation(x, y);
+	}
+
+	public int getSelectionIndex() {
+		return table.getSelectionIndex();
+	}
+
+	public void setLocation(Point location) {
+		table.setLocation(location);
+	}
+
+	public int[] getSelectionIndices() {
+		return table.getSelectionIndices();
+	}
+
+	public void setMenu(Menu menu) {
+		table.setMenu(menu);
+	}
+
+	public TableColumnOrTreeColumn getSortColumn() {
+		return wrapOrNull(table.getSortColumn());
+	}
+
+	public int getSortDirection() {
+		return table.getSortDirection();
+	}
+
+	public int getTopIndex() {
+		int topIndex = table.getTopIndex();
+		if (topIndex == 0 && table.getItemCount() == 0) {
+			return -1;
+		}
+		return topIndex;
+	}
+
+	public int hashCode() {
+		return table.hashCode();
+	}
+
+	public void setRegion(Region region) {
+		table.setRegion(region);
+	}
+
+	public void setSize(int width, int height) {
+		table.setSize(width, height);
+	}
+
+	public void setSize(Point size) {
+		table.setSize(size);
+	}
+
+	public int indexOf(TableColumnOrTreeColumn column) {
+		if (column == null) {
+			return -1;
+		}
+		return table.indexOf((TableColumn) column.getColumn());
+	}
+
+	public void setToolTipText(String string) {
+		table.setToolTipText(string);
+	}
+
+	public int indexOf(TableItemOrTreeItem item) {
+		if (item == null) {
+			return -1;
+		}
+		return table.indexOf((TableItem) item.getItem());
+	}
+
+	public void setVisible(boolean visible) {
+		table.setVisible(visible);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#isSelected(org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem)
+	public boolean isSelected(TableItemOrTreeItem item) {
+		return table.isSelected(indexOf(item));
+	}
+
+	public Point toControl(int x, int y) {
+		return table.toControl(x, y);
+	}
+
+	public Point toControl(Point point) {
+		return table.toControl(point);
+	}
+
+	public Point toDisplay(int x, int y) {
+		return table.toDisplay(x, y);
+	}
+
+	public Point toDisplay(Point point) {
+		return table.toDisplay(point);
+	}
+
+	public void remove(int[] indices) {
+		table.remove(indices);
+	}
+
+	public void remove(int index) {
+		table.remove(index);
+	}
+
+	public void remove(int start, int end) {
+		table.remove(start, end);
+	}
+
+	public void removeAll() {
+		table.removeAll();
+	}
+
+	public void removeSelectionListener(SelectionListener listener) {
+		table.removeSelectionListener(listener);
+	}
+
+	public void select(int[] indices) {
+		table.select(indices);
+	}
+
+	public void select(int index) {
+		table.select(index);
+	}
+
+	public void select(int start, int end) {
+		table.select(start, end);
+	}
+
+	public void selectAll() {
+		table.selectAll();
+	}
+
+	public void update() {
+		table.update();
+	}
+
+	public boolean setParent(Composite parent) {
+		return table.setParent(parent);
+	}
+
+	public void setColumnOrder(int[] order) {
+		table.setColumnOrder(order);
+	}
+
+	public void setFont(Font font) {
+		table.setFont(font);
+	}
+
+	public void setHeaderVisible(boolean show) {
+		table.setHeaderVisible(show);
+	}
+
+	public void setItemCount(int count) {
+		table.setItemCount(count);
+	}
+
+	public void setLinesVisible(boolean show) {
+		table.setLinesVisible(show);
+	}
+
+	public void setRedraw(boolean redraw) {
+		table.setRedraw(redraw);
+	}
+
+	public void setSelection(int[] indices) {
+		table.setSelection(indices);
+	}
+
+	public void setSelection(TableItemOrTreeItem item) {
+		table.setSelection(item == null ? null : (TableItem) item.getItem());
+	}
+
+	public void setSelection(TableItem[] items) {
+		table.setSelection(items);
+	}
+
+	public void setSelection(int index) {
+		table.setSelection(index);
+	}
+
+	public void setSelection(int start, int end) {
+		table.setSelection(start, end);
+	}
+
+	public void setSortColumn(TableColumnOrTreeColumn column) {
+		table.setSortColumn(column == null ? null
+				: (TableColumn) column.getColumn());
+	}
+
+	public void setSortDirection(int direction) {
+		table.setSortDirection(direction);
+	}
+
+	public void setTopIndex(int index) {
+		table.setTopIndex(index);
+	}
+
+	public void showColumn(TableColumnOrTreeColumn column) {
+		table.showColumn(column == null ? null : (TableColumn) column.getColumn());
+	}
+
+	public void showItem(TableItemOrTreeItem item) {
+		table.showItem(item == null ? null : (TableItem) item.getItem());
+	}
+
+	public void showSelection() {
+		table.showSelection();
+	}
+
+	///////
+
+	private TableItemOrTreeItem wrapOrNull(TableItem item) {
+		if (item == null) {
+			return null;
+		}
+		return TableOrTreeUtils.getEventItem(item);
+	}
+
+	private TableItemOrTreeItem[] wrapOrNull(TableItem[] items) {
+		if (items == null) {
+			return null;
+		}
+		TableItemOrTreeItem[] returnItems = new TableItemOrTreeItem[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = TableOrTreeUtils.getEventItem(items[i]);
+		}
+		return returnItems;
+	}
+
+	private TableColumnOrTreeColumn wrapOrNull(TableColumn item) {
+		if (item == null) {
+			return null;
+		}
+		return new TableColumnDelegate(item);
+	}
+
+	private TableColumnOrTreeColumn[] wrapOrNull(TableColumn[] items) {
+		if (items == null) {
+			return null;
+		}
+		TableColumnOrTreeColumn[] returnItems = new TableColumnOrTreeColumn[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = new TableColumnDelegate(items[i]);
+		}
+		return returnItems;
+	}
+
+	private TableItem[] toTableItemArray(TableItemOrTreeItem[] items) {
+		if (items == null) {
+			return null;
+		}
+		TableItem[] returnItems = new TableItem[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = (TableItem) items[i].getItem();
+		}
+		return returnItems;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#clear(int, boolean)
+	public void clear(int index, boolean allChildren) {
+		table.clear(index);
+	}
+
+	public void clearAll(boolean allChildren) {
+		table.clearAll();
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#deselect(org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem)
+	public void deselect(TableItemOrTreeItem item) {
+		table.deselect(table.indexOf((TableItem) item.getItem()));
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#getParentItem()
+	public TableItemOrTreeItem getParentItem() {
+		return null;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#getTopItem()
+	public TableItemOrTreeItem getTopItem() {
+		int i = table.getTopIndex();
+		return i < 0 || (i == 0 && table.getItemCount() == 0) ? null : getItem(i);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#removeTreeListener(org.eclipse.swt.events.TreeListener)
+	public void removeTreeListener(TreeListener listener) {
+		// TODO Auto-generated method stub
+
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#setInsertMark(org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem, boolean)
+	public void setInsertMark(TableItemOrTreeItem item, boolean before) {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void select(TableItemOrTreeItem item) {
+		table.select(table.indexOf((TableItem) item.getItem()));
+	}
+
+	public void setSelection(TableItemOrTreeItem[] items) {
+		int[] indexes = new int[items.length];
+		for (int i = 0; i < indexes.length; i++) {
+			indexes[i] = table.indexOf((TableItem) items[i].getItem());
+		}
+		table.select(indexes);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#setTopItem(org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem)
+	public void setTopItem(TableItemOrTreeItem item) {
+		// TODO Auto-generated method stub
+
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#getComposite()
+	public Composite getComposite() {
+		return table;
+	}
+
+	public boolean equalsTableOrTree(TableOrTreeSWT tt) {
+		return table.equals(tt.getComposite());
+	}
+
+	public TableItemOrTreeItem createNewItem(int style) {
+		return TableOrTreeUtils.createNewItem(this, style);
+	}
+
+	public TableColumnOrTreeColumn createNewColumn(int style) {
+		return new TableColumnDelegate(table, style);
+	}
+
+  public int indexOf(Widget item) {
+  	if (item instanceof TableItem) {
+  		return table.indexOf((TableItem) item);
+  	}
+  	return -1;
+  }
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableItemDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableItemDelegate.java
new file mode 100644
index 0000000..e5f1e50
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableItemDelegate.java
@@ -0,0 +1,338 @@
+/**
+ * Created on May 5, 2010
+ *
+ * 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.impl;
+
+import java.util.Map;
+
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.LightHashMap;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * @author TuxPaper
+ * @created May 5, 2010
+ *
+ */
+public class TableItemDelegate
+	implements TableItemOrTreeItem
+{
+	TableItem item;
+
+	Map data = new LightHashMap(2);
+
+	protected TableItemDelegate(TableItem item2) {
+		item = item2;
+		if (item == null) {
+			System.out.println("NULL");
+		}
+	}
+
+	protected TableItemDelegate(TableDelegate tableDelegate, int style) {
+		item = new TableItem(tableDelegate.table, style);
+		if (item == null) {
+			System.out.println("NULL");
+		}
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		item.addListener(eventType, listener);
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		item.addDisposeListener(listener);
+	}
+
+	public void dispose() {
+		item.dispose();
+	}
+
+	public boolean equals(Object obj) {
+		if (obj instanceof TableItemOrTreeItem) {
+			return item.equals(((TableItemOrTreeItem) obj).getItem());
+		}
+		return item.equals(obj);
+	}
+
+	public Color getBackground() {
+		return item.getBackground();
+	}
+
+	public Color getBackground(int index) {
+		return item.getBackground(index);
+	}
+
+	public Rectangle getBounds() {
+		return item.getBounds();
+	}
+
+	public Rectangle getBounds(int index) {
+		return item.getBounds(index);
+	}
+
+	public boolean getChecked() {
+		return item.getChecked();
+	}
+
+	public Font getFont() {
+		return item.getFont();
+	}
+
+	public Font getFont(int index) {
+		return item.getFont(index);
+	}
+
+	public Color getForeground() {
+		return item.getForeground();
+	}
+
+	public Color getForeground(int index) {
+		return item.getForeground(index);
+	}
+
+	public Object getData() {
+		return getData(null);
+	}
+	
+	public Object getData(String key) {
+		synchronized (data) {
+			return data.get(key);
+		}
+	}
+
+	public boolean getGrayed() {
+		return item.getGrayed();
+	}
+
+	public Image getImage() {
+		return item.getImage();
+	}
+
+	public Image getImage(int index) {
+		return item.getImage(index);
+	}
+
+	public Display getDisplay() {
+		return item.getDisplay();
+	}
+
+	public Rectangle getImageBounds(int index) {
+		return item.getImageBounds(index);
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return item.getListeners(eventType);
+	}
+
+	public int getImageIndent() {
+		return item.getImageIndent();
+	}
+
+	public TableOrTreeSWT getParent() {
+		return TableOrTreeUtils.getTableOrTreeSWT(item.getParent());
+	}
+
+	public int getStyle() {
+		return item.getStyle();
+	}
+
+	public String getText() {
+		return item.getText();
+	}
+
+	public String getText(int index) {
+		return item.getText(index);
+	}
+
+	public Rectangle getTextBounds(int index) {
+		return item.getTextBounds(index);
+	}
+
+	public int hashCode() {
+		return item.hashCode();
+	}
+
+	public boolean isDisposed() {
+		return item.isDisposed();
+	}
+
+	public boolean isListening(int eventType) {
+		return item.isListening(eventType);
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		item.notifyListeners(eventType, event);
+	}
+
+	public void setBackground(Color color) {
+		item.setBackground(color);
+	}
+
+	public void setBackground(int index, Color color) {
+		item.setBackground(index, color);
+	}
+
+	public void setChecked(boolean checked) {
+		item.setChecked(checked);
+	}
+
+	public void setFont(Font font) {
+		item.setFont(font);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		item.removeListener(eventType, listener);
+	}
+
+	public void setFont(int index, Font font) {
+		item.setFont(index, font);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		item.removeDisposeListener(listener);
+	}
+
+	public void setForeground(Color color) {
+		item.setForeground(color);
+	}
+
+	public void setForeground(int index, Color color) {
+		item.setForeground(index, color);
+	}
+
+	public void setGrayed(boolean grayed) {
+		item.setGrayed(grayed);
+	}
+
+	public void setImage(Image[] images) {
+		item.setImage(images);
+	}
+
+	public void setImage(int index, Image image) {
+		item.setImage(index, image);
+	}
+
+	public void setImage(Image image) {
+		item.setImage(image);
+	}
+
+	public void setImageIndent(int indent) {
+		item.setImageIndent(indent);
+	}
+
+	public void setText(String[] strings) {
+		item.setText(strings);
+	}
+	
+	public void setData(Object data) {
+		setData(null, data);
+	}
+	
+	public void setData(String key, Object value) {
+		synchronized (data) {
+			data.put(key, value);
+		}
+	}
+
+	public void setText(int index, String string) {
+		item.setText(index, string);
+	}
+
+	public void setText(String string) {
+		item.setText(string);
+	}
+
+	public String toString() {
+		return item.toString();
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#clear(int, boolean)
+	public void clear(int index, boolean all) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#clearAll(boolean)
+	public void clearAll(boolean all) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#getExpanded()
+	public boolean getExpanded() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#getItem(int)
+	public TableItemOrTreeItem getItem(int index) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public int getItemCount() {
+		return 0;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#getItems()
+	public TableItemOrTreeItem[] getItems() {
+		return new TableItemOrTreeItem[0];
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#getParentItem()
+	public TableItemOrTreeItem getParentItem() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#indexOf(org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem)
+	public int indexOf(TableItemOrTreeItem item) {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#removeAll()
+	public void removeAll() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#setExpanded(boolean)
+	public void setExpanded(boolean expanded) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem#setItemCount(int)
+	public void setItemCount(int count) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public Item getItem() {
+		return item;
+	}
+	
+	public boolean equals(TableItemOrTreeItem ti) {
+		return item.equals(ti.getItem());
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableOrTreeUtils.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableOrTreeUtils.java
new file mode 100644
index 0000000..f8560a2
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableOrTreeUtils.java
@@ -0,0 +1,190 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.custom.ControlEditor;
+import org.eclipse.swt.custom.TableEditor;
+import org.eclipse.swt.custom.TreeEditor;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public class TableOrTreeUtils
+{
+	private static Map<Object, Object> mapDelegates = new HashMap<Object, Object>();
+
+	public static TableItemOrTreeItem getEventItem(Widget item) {
+		synchronized (mapDelegates) {
+			Object object = mapDelegates.get(item);
+			if (object instanceof TableItemOrTreeItem) {
+				return (TableItemOrTreeItem) object;
+			}
+		}
+
+		TableItemOrTreeItem delegate = null;
+		synchronized (mapDelegates) {
+			if (item instanceof TreeItem) {
+				delegate = new TreeItemDelegate((TreeItem) item);
+				mapDelegates.put(item, delegate);
+			} else if (item instanceof TableItem) {
+				delegate = new TableItemDelegate((TableItem) item);
+				mapDelegates.put(item, delegate);
+			}
+		}
+
+		if (delegate != null) {
+			delegate.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					synchronized (mapDelegates) {
+						mapDelegates.remove(e.widget);
+					}
+				}
+			});
+		}
+		return delegate;
+	}
+
+	public static TableOrTreeSWT getTableOrTreeSWT(Widget widget) {
+		synchronized (mapDelegates) {
+			Object object = mapDelegates.get(widget);
+			if (object instanceof TableOrTreeSWT) {
+				return (TableOrTreeSWT) object;
+			}
+		}
+
+		TableOrTreeSWT delegate = null;
+		synchronized (mapDelegates) {
+			if (widget instanceof Tree) {
+				delegate = new TreeDelegate((Tree) widget);
+				mapDelegates.put(widget, delegate);
+			} else if (widget instanceof Table) {
+				delegate = new TableDelegate((Table) widget);
+				mapDelegates.put(widget, delegate);
+			}
+		}
+
+		if (delegate != null) {
+			delegate.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					synchronized (mapDelegates) {
+						mapDelegates.remove(e.widget);
+					}
+				}
+			});
+		}
+		return delegate;
+	}
+
+	public static TableItemOrTreeItem createNewItem(TableOrTreeSWT parent,
+			int style) {
+		TableItemOrTreeItem delegate = null;
+		synchronized (mapDelegates) {
+			if (parent instanceof TreeDelegate) {
+				delegate = new TreeItemDelegate(parent, style);
+				mapDelegates.put(((TreeItemDelegate) delegate).item, delegate);
+			} else if (parent instanceof TableDelegate) {
+				delegate = new TableItemDelegate((TableDelegate) parent, style);
+				mapDelegates.put(((TableItemDelegate)delegate).item, delegate);
+			}
+		}
+
+		if (delegate != null) {
+			delegate.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					synchronized (mapDelegates) {
+						mapDelegates.remove(e.widget);
+					}
+				}
+			});
+		}
+		return delegate;
+	}
+
+	public static TableColumnOrTreeColumn getTableColumnEventItem(Widget item) {
+		if (item instanceof TreeColumn) {
+			return new TreeColumnDelegate((TreeColumn) item);
+		}
+		if (item instanceof TableColumn) {
+			return new TableColumnDelegate((TableColumn) item);
+		}
+		return null;
+	}
+
+	public static TableOrTreeSWT createGrid(Composite parent, int style,
+			boolean tree) {
+		TableOrTreeSWT delegate = null;
+		synchronized (mapDelegates) {
+			if (tree) {
+				try {
+					delegate = new TreeDelegate(parent, style);
+					mapDelegates.put(((TreeDelegate) delegate).getComposite(), delegate);
+				} catch (Exception e) {
+					Debug.out(e);
+				}
+			} else {
+				delegate = new TableDelegate(parent, style);
+				mapDelegates.put(((TableDelegate)delegate).getComposite(), delegate);
+			}
+		}
+
+		if (delegate != null) {
+			delegate.addDisposeListener(new DisposeListener() {
+				public void widgetDisposed(DisposeEvent e) {
+					synchronized (mapDelegates) {
+						mapDelegates.remove(e.widget);
+					}
+				}
+			});
+		}
+		return delegate;
+	}
+
+	public static ControlEditor createTableOrTreeEditor(TableOrTreeSWT tableOrTree) {
+		return (tableOrTree instanceof TreeDelegate) ? new TreeEditor(
+				(Tree) tableOrTree.getComposite()) : new TableEditor(
+				(Table) tableOrTree.getComposite());
+	}
+
+	/**
+	 * @since 4.4.0.5
+	 */
+	public static void setEditorItem(ControlEditor editor, Control input,
+			int column, TableItemOrTreeItem item) {
+		if (item instanceof TreeItemDelegate) {
+			((TreeEditor) editor).setEditor(input, (TreeItem) item.getItem(), column);
+		} else {
+			((TableEditor) editor).setEditor(input, (TableItem) item.getItem(),
+					column);
+		}
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableRowImpl.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableRowImpl.java
index 59cd846..3d4d904 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableRowImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableRowImpl.java
@@ -25,25 +25,18 @@ package org.gudy.azureus2.ui.swt.views.table.impl;
 import java.util.*;
 
 import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Table;
 
 import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.ui.swt.Utils;
 import org.gudy.azureus2.ui.swt.components.BufferedTableRow;
 import org.gudy.azureus2.ui.swt.mainwindow.Colors;
-import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
-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.*;
 
 import com.aelitis.azureus.ui.common.table.*;
-
-import org.gudy.azureus2.plugins.ui.tables.*;
-
-import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
-
-
+import com.aelitis.azureus.ui.common.table.impl.TableViewImpl;
 
 /** Represents an entire row in a table.  Stores each cell belonging to the
  * row and handles refreshing them.
@@ -55,103 +48,165 @@ import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
  *                         BufferedTableRow
  *            2005/Oct/07: Removed all calls to BufferedTableRoe.getItem()
  */
-public class TableRowImpl 
-       extends BufferedTableRow 
-       implements TableRowSWT
+public class TableRowImpl<COREDATASOURCE>
+	extends BufferedTableRow
+	implements TableRowSWT
 {
-  /** List of cells in this column.  They are not stored in display order */
-  private Map mTableCells;
-  private String sTableID;
-  
-  private Object coreDataSource;
-  private Object pluginDataSource;
-  private boolean bDisposed;
-  private boolean bSetNotUpToDateLastRefresh = false;
-	private TableView tableView;
-
-  private static AEMonitor this_mon = new AEMonitor( "TableRowImpl" );
-	private ArrayList mouseListeners;
+	/** 
+	 * List of cells in this row.  
+	 * They are not stored in display order.
+	 * Not written to after initializer
+	 */
+	private Map<String, TableCellCore> mTableCells;
+
+	private Object coreDataSource;
+
+	private Object pluginDataSource;
+
+	private boolean bDisposed;
+
+	private boolean bSetNotUpToDateLastRefresh = false;
+
+	private TableView<COREDATASOURCE> tableView;
+
+	private static AEMonitor this_mon = new AEMonitor("TableRowImpl");
+
+	private ArrayList<TableRowMouseListener> mouseListeners;
+
 	private boolean wasShown = false;
-	private Map dataList;
-	
+
+	private Map<String, Object> dataList;
+
 	private int lastIndex = -1;
+
 	private int fontStyle;
+
 	private int alpha = 255;
 
-  // XXX add rowVisuallyupdated bool like in ListRow
-
-  /**
-   * Default constructor
-   * 
-   * @param table
-   * @param sTableID
-   * @param columnsSorted
-   * @param dataSource
-   * @param bSkipFirstColumn
-   */
-  public TableRowImpl(TableView tv, Table table, String sTableID,
+	private TableRowCore parentRow;
+
+	private TableRowImpl<Object>[] subRows;
+
+	private AEMonitor mon_SubRows = new AEMonitor("subRows");
+
+	private TableColumnCore[] columnsSorted;
+
+	private boolean bSkipFirstColumn;
+
+	// XXX add rowVisuallyupdated bool like in ListRow
+
+	public TableRowImpl(TableRowCore parentRow, TableView<COREDATASOURCE> tv,
+			TableOrTreeSWT table, TableColumnCore[] columnsSorted, String sTableID,
+			Object dataSource, int index, boolean bSkipFirstColumn) {
+		super(table);
+		this.parentRow = parentRow;
+		this.tableView = tv;
+		coreDataSource = dataSource;
+		bDisposed = false;
+		lastIndex = index;
+
+		mTableCells = new LightHashMap<String, TableCellCore>(columnsSorted.length,
+				1);
+
+		// create all the cells for the column
+		for (int i = 0; i < columnsSorted.length; i++) {
+			if (columnsSorted[i] == null) {
+				continue;
+			}
+
+			if (!columnsSorted[i].handlesDataSourceType(getDataSource(false).getClass())) {
+				mTableCells.put(columnsSorted[i].getName(), null);
+				continue;
+			}
+
+			//System.out.println(dataSource + ": " + tableColumns[i].getName() + ": " + tableColumns[i].getPosition());
+			TableCellImpl cell = new TableCellImpl(TableRowImpl.this,
+					columnsSorted[i], bSkipFirstColumn ? i + 1 : i);
+			mTableCells.put(columnsSorted[i].getName(), cell);
+			//if (i == 10) cell.bDebug = true;
+		}
+	}
+
+	/**
+	 * Default constructor
+	 * 
+	 * @param table
+	 * @param sTableID
+	 * @param columnsSorted
+	 * @param dataSource
+	 * @param bSkipFirstColumn
+	 */
+	public TableRowImpl(TableView<COREDATASOURCE> tv, TableOrTreeSWT table,
 			TableColumnCore[] columnsSorted, Object dataSource,
 			boolean bSkipFirstColumn) {
 		super(table);
 		this.tableView = tv;
-    this.sTableID = sTableID;
-    coreDataSource = dataSource;
-    mTableCells = new LightHashMap();
-    bDisposed = false;
-
-    // create all the cells for the column
-    for (int i = 0; i < columnsSorted.length; i++) {
-    	if (columnsSorted[i] == null)
-    		continue;
-      //System.out.println(dataSource + ": " + tableColumns[i].getName() + ": " + tableColumns[i].getPosition());
-    	TableCellImpl cell = new TableCellImpl(TableRowImpl.this, columnsSorted[i], 
-          bSkipFirstColumn ? i+1 : i);
-      mTableCells.put(columnsSorted[i].getName(), cell);
-      //if (i == 10) cell.bDebug = true;
-    }
-  }
-
-  public boolean isValid() {
-  	if (bDisposed)
-  		return true;
-
-    boolean valid = true;
-    Iterator iter = mTableCells.values().iterator();
-    while (iter.hasNext()) {
-    	TableCellSWT cell = (TableCellSWT)iter.next();
-      if (cell != null)
-        valid &= cell.isValid();
-    }
-    return valid;
-  }
-
-  /** TableRow Implementation which returns the 
-   * associated plugin object for the row.  Core Column Object who wish to get 
-   * core data source must re-class TableRow as TableRowCore and use
-   * getDataSource(boolean)
-   *
-   * @see TableRowCore.getDataSource()
-   */
-  public Object getDataSource() {
-    return getDataSource(false);
-  }
-
-  public String getTableID() {
-    return sTableID;
-  }
-  
-  public TableCell getTableCell(String field) {
-  	if (bDisposed)
-  		return null;
-    return (TableCell)mTableCells.get(field);
-  }
+		this.columnsSorted = columnsSorted;
+		coreDataSource = dataSource;
+		this.bSkipFirstColumn = bSkipFirstColumn;
+		bDisposed = false;
+
+		mTableCells = new LightHashMap<String, TableCellCore>(columnsSorted.length,
+				1);
+
+		// create all the cells for the column
+		for (int i = 0; i < columnsSorted.length; i++) {
+			if (columnsSorted[i] == null) {
+				continue;
+			}
+			//System.out.println(dataSource + ": " + tableColumns[i].getName() + ": " + tableColumns[i].getPosition());
+			TableCellImpl cell = new TableCellImpl(TableRowImpl.this,
+					columnsSorted[i], bSkipFirstColumn ? i + 1 : i);
+			mTableCells.put(columnsSorted[i].getName(), cell);
+			//if (i == 10) cell.bDebug = true;
+		}
+	}
+
+	public boolean isValid() {
+		if (bDisposed || mTableCells == null) {
+			return true;
+		}
+
+		boolean valid = true;
+		for (TableCell cell : mTableCells.values()) {
+			if (cell != null && cell.isValid()) {
+				return false;
+			}
+		}
+
+		return valid;
+	}
+
+	/** TableRow Implementation which returns the 
+	 * associated plugin object for the row.  Core Column Object who wish to get 
+	 * core data source must re-class TableRow as TableRowCore and use
+	 * getDataSource(boolean)
+	 *
+	 * @see TableRowCore.getDataSource()
+	 */
+	public Object getDataSource() {
+		return getDataSource(false);
+	}
+
+	public String getTableID() {
+		return tableView.getTableID();
+	}
+
+	public TableCell getTableCell(String field) {
+		if (bDisposed || mTableCells == null) {
+			return null;
+		}
+
+		return mTableCells.get(field);
+	}
 
 	public void addMouseListener(TableRowMouseListener listener) {
 		try {
 			this_mon.enter();
 
-			if (mouseListeners == null)
-				mouseListeners = new ArrayList(1);
+			if (mouseListeners == null) {
+				mouseListeners = new ArrayList<TableRowMouseListener>(1);
+			}
 
 			mouseListeners.add(listener);
 
@@ -164,8 +219,9 @@ public class TableRowImpl
 		try {
 			this_mon.enter();
 
-			if (mouseListeners == null)
+			if (mouseListeners == null) {
 				return;
+			}
 
 			mouseListeners.remove(listener);
 
@@ -174,14 +230,15 @@ public class TableRowImpl
 		}
 	}
 
-  public void invokeMouseListeners(TableRowMouseEvent event) {
-		ArrayList listeners = mouseListeners;
-		if (listeners == null)
+	public void invokeMouseListeners(TableRowMouseEvent event) {
+		ArrayList<TableRowMouseListener> listeners = mouseListeners;
+		if (listeners == null) {
 			return;
-		
+		}
+
 		for (int i = 0; i < listeners.size(); i++) {
 			try {
-				TableRowMouseListener l = (TableRowMouseListener) (listeners.get(i));
+				TableRowMouseListener l = listeners.get(i);
 
 				l.rowMouseTrigger(event);
 
@@ -191,163 +248,152 @@ public class TableRowImpl
 		}
 	}
 
-  /* Start Core-Only functions */
-  ///////////////////////////////
+	/* Start Core-Only functions */
+	///////////////////////////////
 
-  public void delete() {
+	public void delete() {
 		this_mon.enter();
 
 		try {
-			if (bDisposed)
+			if (bDisposed) {
 				return;
+			}
 
-			if (TableViewSWT.DEBUGADDREMOVE)
+			if (TableViewImpl.DEBUGADDREMOVE) {
 				System.out.println((table.isDisposed() ? "" : table.getData("Name"))
 						+ " row delete; index=" + getIndex());
+			}
 
-			Iterator iter = mTableCells.values().iterator();
-			while (iter.hasNext()) {
-				TableCellSWT item = (TableCellSWT) iter.next();
-				item.dispose();
+			for (TableCellCore cell : mTableCells.values()) {
+				try {
+					if (cell != null) {
+						cell.dispose();
+					}
+				} catch (Exception e) {
+					Debug.out(e);
+				}
 			}
-			
-			setForeground((Color) null);
+
+			//setForeground((Color) null);
 
 			bDisposed = true;
 		} finally {
 			this_mon.exit();
 		}
 	}
-  
-  public List refresh(boolean bDoGraphics) {
-    if (bDisposed) {
-      return Collections.EMPTY_LIST;
-    }
-    
-    boolean bVisible = isVisible();
-
-    return refresh(bDoGraphics, bVisible);
-  }
-
-  public List refresh(boolean bDoGraphics, boolean bVisible) {
-    // If this were called from a plugin, we'd have to refresh the sorted column
-    // even if we weren't visible
-    List list = Collections.EMPTY_LIST;
-
-  	if (bDisposed) {
-  		return list;
-  	}
-
-    if (!bVisible) {
-    	if (!bSetNotUpToDateLastRefresh) {
-    		setUpToDate(false);
-    		bSetNotUpToDateLastRefresh = true;
-    	}
-  		return list;
-  	}
-    
+
+	public List<TableCellCore> refresh(boolean bDoGraphics) {
+		if (bDisposed) {
+			return Collections.EMPTY_LIST;
+		}
+
+		boolean bVisible = isVisible();
+
+		return refresh(bDoGraphics, bVisible);
+	}
+
+	public List<TableCellCore> refresh(boolean bDoGraphics, boolean bVisible) {
+		// If this were called from a plugin, we'd have to refresh the sorted column
+		// even if we weren't visible
+		List<TableCellCore> list = Collections.EMPTY_LIST;
+
+		if (bDisposed) {
+			return list;
+		}
+
+		if (!bVisible) {
+			if (!bSetNotUpToDateLastRefresh) {
+				setUpToDate(false);
+				bSetNotUpToDateLastRefresh = true;
+			}
+			return list;
+		}
+
 		bSetNotUpToDateLastRefresh = false;
-		
+
 		//System.out.println(SystemTime.getCurrentTime() + "refresh " + getIndex() + ";vis=" + bVisible);
-		
-		((TableViewSWTImpl)tableView).invokeRefreshListeners(this);
-
-    Iterator iter = mTableCells.values().iterator();
-    while (iter.hasNext())
-		{
-			TableCellSWT item = (TableCellSWT) iter.next();
-			TableColumn column = item.getTableColumn();
+
+		((TableViewSWTImpl<COREDATASOURCE>) tableView).invokeRefreshListeners(this);
+
+		for (TableCellCore cell : mTableCells.values()) {
+			if (cell == null || cell.isDisposed()) {
+				continue;
+			}
+			TableColumn column = cell.getTableColumn();
 			//System.out.println(column);
-			if (column != tableView.getSortColumn() && !tableView.isColumnVisible(column)) {
+			if (column != tableView.getSortColumn()
+					&& !tableView.isColumnVisible(column)) {
 				//System.out.println("skip " + column);
 				continue;
 			}
-			boolean changed = item.refresh(bDoGraphics, bVisible);
-			if (changed)
-			{
-				if(list == Collections.EMPTY_LIST)
-					list = new ArrayList(mTableCells.size());
-				list.add(item);
-			}
-				
-		}
-    //System.out.println();
-    return list;
-  }
-
-  public void setAlternatingBGColor(boolean bEvenIfNotVisible) {
-  	super.setAlternatingBGColor(bEvenIfNotVisible);
-  }
-
-  public void locationChanged(int iStartColumn) {
-    if (bDisposed || !isVisible())
-      return;
-
-  	Iterator iter = mTableCells.values().iterator();
-  	while(iter.hasNext()) {
-  		TableCellSWT item = (TableCellSWT)iter.next();
-  		if (item.getTableColumn().getPosition() > iStartColumn)
-  		  item.locationChanged();
-  	}
-  }
-
-  public void doPaint(GC gc) {
-  	doPaint(gc, isVisible());
-  }
-
-  // @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#doPaint(org.eclipse.swt.graphics.GC, boolean, boolean)
-  public void doPaint(GC gc, boolean bVisible) {
-    if (bDisposed || !bVisible)
-      return;
-
-    Iterator iter = mTableCells.values().iterator();
-    while(iter.hasNext()) {
-    	TableCellSWT cell = (TableCellSWT) iter.next();
-    	if (cell == null) {
-    		continue;
-    	}
-//    	if (bOnlyIfChanged && !cell.getVisuallyChangedSinceRefresh()) {
-//    		continue;
-//    	}
-  		if (cell.needsPainting()) {
-  			cell.doPaint(gc);
-  		}
-    }
-  }
-
-  public TableCellCore getTableCellCore(String field) {
-  	if (bDisposed)
-  		return null;
-
-    return (TableCellCore)mTableCells.get(field);
-  }
+			boolean changed = cell.refresh(bDoGraphics, bVisible);
+			if (changed) {
+				if (list == Collections.EMPTY_LIST) {
+					list = new ArrayList<TableCellCore>(mTableCells.size());
+				}
+				list.add(cell);
+			}
+
+		}
+
+		//System.out.println();
+		return list;
+	}
+
+	public void locationChanged(int iStartColumn) {
+		if (bDisposed || !isVisible()) {
+			return;
+		}
+
+		for (TableCellCore cell : mTableCells.values()) {
+			if (cell != null && cell.getTableColumn().getPosition() > iStartColumn) {
+				cell.locationChanged();
+			}
+		}
+	}
+
+	public TableCellCore getTableCellCore(String name) {
+		if (bDisposed || mTableCells == null) {
+			return null;
+		}
+
+		return mTableCells.get(name);
+	}
 
 	/**
 	 * @param name
 	 * @return
 	 */
 	public TableCellSWT getTableCellSWT(String name) {
-  	if (bDisposed)
-  		return null;
+		if (bDisposed || mTableCells == null) {
+			return null;
+		}
 
-    return (TableCellSWT)mTableCells.get(name);
+		TableCellCore cell = mTableCells.get(name);
+		if (cell instanceof TableCellSWT) {
+			return (TableCellSWT) cell;
+		}
+		return null;
 	}
-  
-  public Object getDataSource(boolean bCoreObject) {
-		if (bDisposed)
+
+	public Object getDataSource(boolean bCoreObject) {
+		if (bDisposed) {
 			return null;
+		}
 
-		if (bCoreObject)
+		if (bCoreObject) {
 			return coreDataSource;
+		}
 
-		if (pluginDataSource != null)
+		if (pluginDataSource != null) {
 			return pluginDataSource;
-		
+		}
+
 		pluginDataSource = PluginCoreUtils.convert(coreDataSource, bCoreObject);
 
 		return pluginDataSource;
 	}
-  
+
 	public boolean isRowDisposed() {
 		return bDisposed;
 	}
@@ -356,60 +402,95 @@ public class TableRowImpl
 	 * @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#getIndex()
 	 */
 	public int getIndex() {
-		if (bDisposed)
+		if (bDisposed) {
 			return -1;
+		}
 
 		if (lastIndex >= 0) {
-			TableRowCore row = ((TableViewSWTImpl) tableView).getRowQuick(lastIndex);
+			if (parentRow != null) {
+				return lastIndex;
+			}
+			TableRowCore row = ((TableViewSWTImpl<COREDATASOURCE>) tableView).getRowQuick(lastIndex);
 			if (row == this) {
 				return lastIndex;
 			}
 		}
 
-		lastIndex = ((TableViewSWTImpl) tableView).indexOf(this);
-		return lastIndex;
+		// don't set directly to lastIndex, so setTableItem will eventually do
+		// its job
+		return tableView.indexOf(this);
 
 		//return super.getIndex();
 	}
-	
+
 	public int getRealIndex() {
 		return super.getIndex();
 	}
-	
-	public boolean setTableItem(int newIndex, boolean isVisible)
-	{
+
+	public boolean setTableItem(int newIndex, boolean isVisible) {
 		if (bDisposed) {
-			System.out.println("XXX setTI: bDisposed from " + Debug.getCompressedStackTrace());
+			System.out.println("XXX setTI: bDisposed from "
+					+ Debug.getCompressedStackTrace());
 			return false;
 		}
-		
+
+		int maxItemShown = tableView.getMaxItemShown();
+		if (newIndex > maxItemShown) {
+				//System.out.println((item == null ? null : "" + table.indexOf(item)) + ":" + newIndex + ":" + isVisible + ":" + tableView.getMaxItemShown());
+				tableView.setMaxItemShown(newIndex);
+			if (!isVisible) {
+				return false;
+			}
+		}
+
+		boolean changedIndex = lastIndex != newIndex || item == null;
+
 		//if (getRealIndex() != newIndex) {
 		//	((TableViewSWTImpl)tableView).debug("sTI " + newIndex + "; via " + Debug.getCompressedStackTrace(4));
 		//}
-		boolean changed = super.setTableItem(newIndex, false, isVisible);
-		if (lastIndex != newIndex) {
+		boolean changedSWTRow = !changedIndex ? false : super.setTableItem(newIndex, isVisible);
+		//if (changedSWTRow) {
+		//	System.out.println((item == null ? null : "" + table.indexOf(item)) + ":" + newIndex + ":" + isVisible + ":" + tableView.getMaxItemShown());
+		//}
+		if (changedIndex) {
+			//System.out.println("row " + newIndex + " from " + lastIndex + ";" + tableView.isRowVisible(this) + ";" + changedSWTRow);
 			lastIndex = newIndex;
 		}
-		setShown(tableView.isRowVisible(this), changed);
-		return changed; 
+		//boolean rowVisible = tableView.isRowVisible(this);
+		setShown(isVisible, changedSWTRow);
+		if (changedSWTRow && isVisible) {
+			redraw();
+			//invalidate();
+			//refresh(true, true);
+			setUpToDate(false);
+		}
+		return changedSWTRow;
 	}
 
 	public boolean setTableItem(int newIndex) {
-		return setTableItem(newIndex,true);
+		if (!Utils.isThisThreadSWT()) {
+			return false;
+		}
+		return setTableItem(newIndex, true);
 	}
-	
+
 	private static final boolean DEBUG_SET_FOREGROUND = System.getProperty("debug.setforeground") != null;
+
+	private Object[] subDataSources;
+
 	private static void setForegroundDebug(String method_sig, Color c) {
 		if (DEBUG_SET_FOREGROUND && c != null) {
 			Debug.out("BufferedTableRow " + method_sig + " -> " + c);
 		}
 	}
+
 	private static void setForegroundDebug(String method_sig, int r, int g, int b) {
 		if (DEBUG_SET_FOREGROUND && (!(r == 0 && g == 0 && b == 0))) {
-			Debug.out("BufferedTableRow " + method_sig + " -> " + r + "," + g + "," + b);
+			Debug.out("BufferedTableRow " + method_sig + " -> " + r + "," + g + ","
+					+ b);
 		}
 	}
-	
+
 	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#setForeground(int, int, int)
 	public void setForeground(int r, int g, int b) {
 		setForegroundDebug("setForeground(r, g, b)", r, g, b);
@@ -422,28 +503,30 @@ public class TableRowImpl
 	}
 
 	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#setForeground(org.eclipse.swt.graphics.Color)
-	public void setForeground(final Color c) {
+	public boolean setForeground(final Color c) {
 		setForegroundDebug("setForeground(Color)", c);
 		// Don't need to set when not visible
-		if (!isVisible())
-			return;
+		if (!isVisible()) {
+			return true;
+		}
 
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				TableRowImpl.this.setForegroundInSWTThread(c);
 			}
 		});
+		return true;
 	}
-	
+
 	private void setForegroundInSWTThread(Color c) {
 		setForegroundDebug("setForegroundInSWTThread(Color)", c);
-		if (!isVisible())
+		if (!isVisible()) {
 			return;
+		}
 
 		super.setForeground(c);
 	}
 
-
 	// @see org.gudy.azureus2.plugins.ui.tables.TableRow#setForeground(int[])
 	public void setForeground(int[] rgb) {
 		if (rgb == null || rgb.length < 3) {
@@ -460,34 +543,42 @@ public class TableRowImpl
 	/* (non-Javadoc)
 	 * @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#invalidate()
 	 */
+	
 	public void invalidate() {
+		invalidate(false);
+	}
+	public void invalidate(boolean mustRefresh) {
 		super.invalidate();
-		
-  	if (bDisposed)
-  		return;
 
-    Iterator iter = mTableCells.values().iterator();
-    while (iter.hasNext()) {
-    	TableCellSWT cell = (TableCellSWT)iter.next();
-      if (cell != null)
-        cell.invalidate(true);
-    }
+		if (bDisposed) {
+			return;
+		}
+
+		for (TableCellCore cell : mTableCells.values()) {
+			if (cell != null) {
+				cell.invalidate(mustRefresh);
+			}
+		}
 	}
-	
+
 	public void setUpToDate(boolean upToDate) {
-  	if (bDisposed)
-  		return;
+		if (bDisposed) {
+			return;
+		}
 
-    Iterator iter = mTableCells.values().iterator();
-    while (iter.hasNext()) {
-    	TableCellSWT cell = (TableCellSWT)iter.next();
-      if (cell != null)
-        cell.setUpToDate(upToDate);
-    }
+		for (TableCellCore cell : mTableCells.values()) {
+			if (cell != null) {
+				cell.setUpToDate(upToDate);
+			}
+		}
 	}
-	
-	// @see com.aelitis.azureus.ui.common.table.TableRowCore#redraw()
+
 	public void redraw() {
+		redraw(false);
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableRowCore#redraw()
+	public void redraw(boolean doChildren) {
 		// this will call paintItem which may call refresh
 		Rectangle bounds = getBounds();
 		table.redraw(bounds.x, bounds.y, bounds.width, bounds.height, false);
@@ -500,7 +591,7 @@ public class TableRowImpl
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableRowCore#getView()
-	public TableView getView() {
+	public TableView<COREDATASOURCE> getView() {
 		return tableView;
 	}
 
@@ -510,56 +601,64 @@ public class TableRowImpl
 	 * @since 3.0.4.3
 	 */
 	public void setShown(boolean b, boolean force) {
-  	if (bDisposed)
-  		return;
-  	
-  	if (b == wasShown && !force) {
-  		return;
-  	}
-  	wasShown  = b;
-
-    Iterator iter = mTableCells.values().iterator();
-    while (iter.hasNext()) {
-    	TableCellSWT cell = (TableCellSWT)iter.next();
-      if (cell != null) {
-        cell.invokeVisibilityListeners(b
+		if (bDisposed) {
+			return;
+		}
+
+		if (b == wasShown && !force) {
+			return;
+		}
+		wasShown = b;
+
+		for (TableCellCore cell : mTableCells.values()) {
+			if (cell != null) {
+				cell.invokeVisibilityListeners(b
 						? TableCellVisibilityListener.VISIBILITY_SHOWN
 						: TableCellVisibilityListener.VISIBILITY_HIDDEN, true);
-      }
-    }
+			}
+		}
+
+		/* Don't need to refresh; paintItem will trigger a refresh on
+		 * !cell.isUpToDate()
+		 *
+		if (b) {
+			refresh(b, true);
+		}
+		/**/
 	}
+
 	public boolean isMouseOver() {
 		return tableView.getTableRowWithCursor() == this;
 	}
 
 	public void setData(String id, Object data) {
-		if (dataList == null) {
-			dataList = new HashMap(1);
-		}
-		if (data == null) {
-			dataList.remove("id");
-		} else {
-			dataList.put(id, data);
+		synchronized (this) {
+			if (dataList == null) {
+				dataList = new HashMap<String, Object>(1);
+			}
+			if (data == null) {
+				dataList.remove(id);
+			} else {
+				dataList.put(id, data);
+			}
 		}
 	}
-	
+
 	public Object getData(String id) {
-		return dataList == null ? null : dataList.get(id);
+		synchronized (this) {
+			return dataList == null ? null : dataList.get(id);
+		}
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableRowCore#setDrawableHeight(int)
-	public boolean setDrawableHeight(int height) {
-		return setHeight(height);
-	}
-	
 	// @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getBounds()
 	public Rectangle getBounds() {
 		Rectangle bounds = getBounds(1);
 		if (bounds == null) {
 			return new Rectangle(0, 0, 0, 0);
 		}
-		bounds.x = 0;
-		bounds.width = table.getSize().x;
+		Rectangle tableBounds = table.getClientArea();
+		bounds.x = tableBounds.x;
+		bounds.width = tableBounds.width;
 		return bounds;
 	}
 
@@ -568,10 +667,10 @@ public class TableRowImpl
 		if (fontStyle == style) {
 			return false;
 		}
-		
+
 		fontStyle = style;
 		invalidate();
-		
+
 		return true;
 	}
 
@@ -580,47 +679,225 @@ public class TableRowImpl
 		if (this.alpha == alpha) {
 			return false;
 		}
-		
+
 		this.alpha = alpha;
 		invalidate();
-		
+
 		return true;
 	}
-	
+
 	// @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getAlpha()
 	public int getAlpha() {
 		return alpha;
 	}
-	
+
 	// @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getFontStyle()
 	public int getFontStyle() {
 		return fontStyle;
 	}
-	
+
 	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#isVisible()
 	public boolean isVisible() {
-		return Utils.execSWTThreadWithBool("isVisible", new AERunnableBoolean() {
-			public boolean runSupport() {
-				return TableRowImpl.super.isVisible();
-			}
-		}, 1000);
+		return tableView.isRowVisible(this);
+		//return Utils.execSWTThreadWithBool("isVisible", new AERunnableBoolean() {
+		//	public boolean runSupport() {
+		//		return TableRowImpl.super.isVisible();
+		//	}
+		//}, 1000);
+	}
+
+	public boolean isVisibleNoSWT() {
+		return tableView.isRowVisible(this);
 	}
 
 	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#setSelected(boolean)
 	public void setSelected(boolean selected) {
+		if (tableView instanceof TableViewSWT) {
+			((TableViewSWT<COREDATASOURCE>) tableView).setRowSelected(this, selected, true);
+		}
+	}
+
+	public void setWidgetSelected(boolean selected) {
 		super.setSelected(selected);
+	}
 
-		if (tableView instanceof TableViewSWTImpl) {
-			((TableViewSWTImpl)tableView).updateSelectedRowIndexes();
-		}
-	}	
-	
 	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#isSelected()
 	public boolean isSelected() {
+		return tableView.isSelected(this);
+		/*
 		return Utils.execSWTThreadWithBool("isSelected", new AERunnableBoolean() {
 			public boolean runSupport() {
 				return TableRowImpl.super.isSelected();
 			}
 		}, 1000);
+		*/
+	}
+
+	// @see org.gudy.azureus2.ui.swt.components.BufferedTableRow#setSubItemCount(int)
+	@SuppressWarnings("rawtypes")
+	public void setSubItemCount(final int count) {
+		super.setSubItemCount(count);
+		if (count == getSubItemCount()) {
+			if (count == 0 || (subRows != null && subRows[0] == null)) {
+				return;
+			}
+		}
+		mon_SubRows.enter();
+		try {
+			subRows = new TableRowImpl[count];
+			for (int i = 0; i < count; i++) {
+				//subRows[i] = new TableRowImpl(this, tableView, table, columnsSorted,
+				//		getTableID(), null, i, bSkipFirstColumn);
+				subRows[i] = null;
+			}
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+
+	@SuppressWarnings("rawtypes")
+	public void setSubItems(Object[] datasources) {
+		this.subDataSources = datasources;
+		super.setSubItemCount(datasources.length);
+
+		mon_SubRows.enter();
+		try {
+			subRows = new TableRowImpl[datasources.length];
+			for (int i = 0; i < datasources.length; i++) {
+				//subRows[i] = new TableRowImpl(this, tableView, table, columnsSorted,
+				//		getTableID(), datasources[i], i, bSkipFirstColumn);
+				subRows[i] = null;
+			}
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+
+	public TableRowCore linkSubItem(int indexOf) {
+		mon_SubRows.enter();
+		try {
+			if (indexOf >= subRows.length) {
+				return null;
+			}
+			TableRowImpl<Object> subRow = subRows[indexOf];
+			if (subRow == null) {
+				subRows[indexOf] = subRow = new TableRowImpl(this, tableView, table,
+						columnsSorted, getTableID(), subDataSources[indexOf], indexOf,
+						bSkipFirstColumn);
+			}
+			TableItemOrTreeItem subItem = item.getItem(indexOf);
+			subRow.setTableItem(subItem, true);
+			return subRow;
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+
+	public TableRowCore[] getSubRowsWithNull() {
+		mon_SubRows.enter();
+		try {
+			TableRowCore[] copyOf = new TableRowCore[subRows.length];
+			System.arraycopy(subRows, 0, copyOf, 0, subRows.length);
+			return copyOf;
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+	
+	public TableRowCore getSubRow(int pos) {
+		mon_SubRows.enter();
+		try {
+			int i = -1;
+			for (TableRowCore row : subRows) {
+				if (row != null) {
+					i++;
+					if (i == pos) {
+						return row;
+					}
+				}
+			}
+			return null;
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+
+	public void removeSubRow(final Object datasource) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				swt_removeSubRow(datasource);
+			}
+		});
+	}
+
+	public void swt_removeSubRow(Object datasource) {
+		if (datasource instanceof TableRowImpl) {
+			removeSubRow(((TableRowImpl) datasource).getDataSource());
+		}
+
+		mon_SubRows.enter();
+		try {
+			if (subDataSources == null || subDataSources.length == 0
+					|| subDataSources.length != subRows.length) {
+				return;
+			}
+
+			for (int i = 0; i < subDataSources.length; i++) {
+				Object ds = subDataSources[i];
+				if (ds == datasource) { // use .equals instead?
+					TableRowImpl rowToDel = subRows[i];
+					TableRowImpl[] newSubRows = new TableRowImpl[subRows.length - 1];
+					System.arraycopy(subRows, 0, newSubRows, 0, i);
+					System.arraycopy(subRows, i + 1, newSubRows, i, subRows.length - i
+							- 1);
+					subRows = newSubRows;
+
+					Object[] newDatasources = new Object[subRows.length];
+					System.arraycopy(subDataSources, 0, newDatasources, 0, i);
+					System.arraycopy(subDataSources, i + 1, newDatasources, i,
+							subDataSources.length - i - 1);
+					subDataSources = newDatasources;
+
+					rowToDel.dispose();
+					rowToDel.delete();
+
+					super.setSubItemCount(subRows.length);
+
+					break;
+				}
+			}
+		} finally {
+			mon_SubRows.exit();
+		}
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableRowCore#isInPaintItem()
+	public boolean isInPaintItem() {
+		return super.inPaintItem();
+	}
+
+	// @see com.aelitis.azureus.ui.common.table.TableRowCore#getParentRowCore()
+	public TableRowCore getParentRowCore() {
+		return parentRow;
+	}
+
+	public TableItemOrTreeItem getItem() {
+		return super.item;
+	}
+
+	public int getFullHeight() {
+		// TODO: should include subitems
+		return getBounds(1).height;
+	}
+
+	public void setSortColumn(String columnID) {
+		// ignored
+	}
+
+	public TableCellCore getSortColumnCell(String hint) {
+		if (bDisposed || mTableCells == null) {
+			return null;
+		}
+		return mTableCells.get(hint);
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableRowSWTBase.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableRowSWTBase.java
new file mode 100644
index 0000000..7bfe39d
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableRowSWTBase.java
@@ -0,0 +1,760 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import java.util.*;
+
+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.plugins.ui.tables.*;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableRowSWT;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.common.table.TableView;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+ at SuppressWarnings("rawtypes")
+public abstract class TableRowSWTBase
+	implements TableRowSWT
+{
+	public static boolean DEBUG_ROW_PAINT = false;
+
+	protected Object lock;
+
+	private final TableViewSWT tv;
+
+	private final TableRowCore parentRow;
+
+	private final Object coreDataSource;
+
+	private int lastIndex = -1;
+
+	protected Map<String, TableCellCore> mTableCells;
+
+	private boolean bDisposed;
+
+	private Object pluginDataSource;
+
+	protected boolean wasShown = false;
+
+	private boolean bSetNotUpToDateLastRefresh;
+
+	private ArrayList<TableRowMouseListener> mouseListeners;
+
+	private Map<String, Object> dataList;
+
+	private int alpha = 255;
+
+	private int fontStyle;
+
+	private boolean expanded;
+
+
+	public TableRowSWTBase(Object lock, TableRowCore parentRow, TableViewSWT tv,
+			Object dataSource) {
+		this.lock = lock;
+		this.parentRow = parentRow;
+		this.tv = tv;
+		this.coreDataSource = dataSource;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#invalidate()
+	 */
+	public void invalidate() {
+		invalidate(false);
+	}
+	public void invalidate(boolean mustRefersh) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return;
+  		}
+  
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if (cell != null) {
+  				cell.invalidate(mustRefersh);
+  			}
+  		}
+		}
+	}
+
+	public boolean doesAnyCellHaveFlag(int flag) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return false;
+  		}
+  
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if ((cell instanceof TableCellSWTBase)
+  					&& ((TableCellSWTBase) cell).hasFlag(flag)) {
+  				return true;
+  			}
+  		}
+  		return false;
+		}
+	}
+
+
+	public void setCellFlag(int flag) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return;
+  		}
+  
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if (cell != null) {
+  				((TableCellSWTBase) cell).setFlag(flag);
+  			}
+  		}
+		}
+	}
+
+	public void clearCellFlag(int flag, boolean subRows) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return;
+  		}
+  
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if (cell != null) {
+  				((TableCellSWTBase) cell).clearFlag(flag);
+  			}
+  		}
+  		if (subRows) {
+  			TableRowCore[] subRowsWithNull = getSubRowsWithNull();
+  			for (TableRowCore row : subRowsWithNull) {
+  				((TableRowSWTBase) row).clearCellFlag(flag, false);
+  			}
+  		}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#delete()
+	 */
+	public void delete() {
+		synchronized (lock) {
+
+			if (bDisposed) {
+				return;
+			}
+
+			if (mTableCells != null) {
+  			for (TableCellCore cell : mTableCells.values()) {
+  				try {
+  					if (cell != null) {
+  						cell.dispose();
+  					}
+  				} catch (Exception e) {
+  					Debug.out(e);
+  				}
+  			}
+			}
+
+			setHeight(0);
+			
+			bDisposed = true;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#refresh(boolean)
+	 */
+	public List refresh(boolean bDoGraphics) {
+		if (bDisposed) {
+			return Collections.EMPTY_LIST;
+		}
+
+		boolean bVisible = isVisible();
+
+		return refresh(bDoGraphics, bVisible);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#locationChanged(int)
+	 */
+	public void locationChanged(int iStartColumn) {
+		if (bDisposed || !isVisible()) {
+			return;
+		}
+		synchronized (lock) {
+			if (mTableCells == null) {
+				return;
+			}
+
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if (cell != null && cell.getTableColumn().getPosition() > iStartColumn) {
+  				cell.locationChanged();
+  			}
+  		}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getDataSource(boolean)
+	 */
+	public Object getDataSource(boolean bCoreObject) {
+		if (bDisposed) {
+			return null;
+		}
+
+		if (bCoreObject) {
+			return coreDataSource;
+		}
+
+		if (pluginDataSource != null) {
+			return pluginDataSource;
+		}
+
+		pluginDataSource = PluginCoreUtils.convert(coreDataSource, bCoreObject);
+
+		return pluginDataSource;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getIndex()
+	 */
+	public int getIndex() {
+		if (bDisposed) {
+			return -1;
+		}
+
+		if (lastIndex >= 0) {
+			if (parentRow != null) {
+				return lastIndex;
+			}
+			TableRowCore row = tv.getRowQuick(lastIndex);
+			if (row == this) {
+				return lastIndex;
+			}
+		}
+
+		// don't set directly to lastIndex, so setTableItem will eventually do
+		// its job
+		return tv.indexOf(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getTableCellCore(java.lang.String)
+	 */
+	public TableCellCore getTableCellCore(String name) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return null;
+  		}
+  
+  		return mTableCells.get(name);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#isVisible()
+	 */
+	public boolean isVisible() {
+		return tv.isRowVisible(this);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setTableItem(int)
+	 */
+	public boolean setTableItem(int newIndex) {
+		return setTableItem(newIndex, true);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setTableItem(int, boolean)
+	 */
+	public boolean setTableItem(int newIndex, boolean isVisible) {
+		if (bDisposed) {
+			System.out.println("XXX setTI: bDisposed from "
+					+ Debug.getCompressedStackTrace());
+			return false;
+		}
+		boolean changedIndex = lastIndex != newIndex;
+		if (changedIndex) {
+			//System.out.println("row " + newIndex + " from " + lastIndex + ";" + getView().isRowVisible(this) + ";" + Debug.getCompressedStackTrace());
+			lastIndex = newIndex;
+		}
+
+		setShown(isVisible, changedIndex);
+
+		return changedIndex;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setSelected(boolean)
+	 */
+	public void setSelected(boolean selected) {
+		TableView tableView = getView();
+		if (tableView instanceof TableViewSWT) {
+			((TableViewSWT<?>) tableView).setRowSelected(this, selected, true);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#isRowDisposed()
+	 */
+	public boolean isRowDisposed() {
+		return bDisposed;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setUpToDate(boolean)
+	 */
+	public void setUpToDate(boolean upToDate) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return;
+  		}
+  
+  		for (TableCellCore cell : mTableCells.values()) {
+  			if (cell != null) {
+  				cell.setUpToDate(upToDate);
+  			}
+  		}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#refresh(boolean, boolean)
+	 */
+	public List<TableCellCore> refresh(boolean bDoGraphics, boolean bVisible) {
+		// If this were called from a plugin, we'd have to refresh the sorted column
+		// even if we weren't visible
+		List<TableCellCore> list = Collections.EMPTY_LIST;
+
+		if (bDisposed) {
+			return list;
+		}
+
+		if (!bVisible) {
+			if (!bSetNotUpToDateLastRefresh) {
+				setUpToDate(false);
+				bSetNotUpToDateLastRefresh = true;
+			}
+			return list;
+		}
+
+		bSetNotUpToDateLastRefresh = false;
+
+		//System.out.println(SystemTime.getCurrentTime() + "refresh " + getIndex() + ";vis=" + bVisible + " via " + Debug.getCompressedStackTrace(8));
+
+		tv.invokeRefreshListeners(this);
+
+		// Make a copy of cells so we don't lock while refreshing
+		Collection<TableCellCore> lTableCells = null;
+		synchronized (lock) {
+			if (mTableCells != null) {
+				lTableCells = new ArrayList<TableCellCore>(mTableCells.values());
+			}
+		}
+
+		if (lTableCells != null) {
+  		for (TableCellCore cell : lTableCells) {
+  			if (cell == null || cell.isDisposed()) {
+  				continue;
+  			}
+  			TableColumn column = cell.getTableColumn();
+  			//System.out.println(column);
+  			if (column != tv.getSortColumn()
+  					&& !tv.isColumnVisible(column)) {
+  				//System.out.println("skip " + column);
+  				continue;
+  			}
+  			boolean cellVisible = bVisible && cell.isShown();
+				boolean changed = cell.refresh(bDoGraphics, bVisible, cellVisible);
+  			if (changed) {
+  				if (list == Collections.EMPTY_LIST) {
+  					list = new ArrayList<TableCellCore>(lTableCells.size());
+  				}
+  				list.add(cell);
+  			}
+  
+  		}
+		}
+
+		//System.out.println();
+		return list;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getView()
+	 */
+	public TableView getView() {
+		return tv;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#addMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void addMouseListener(TableRowMouseListener listener) {
+		synchronized (lock) {
+
+			if (mouseListeners == null) {
+				mouseListeners = new ArrayList<TableRowMouseListener>(1);
+			}
+
+			mouseListeners.add(listener);
+
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#removeMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void removeMouseListener(TableRowMouseListener listener) {
+		synchronized (lock) {
+
+			if (mouseListeners == null) {
+				return;
+			}
+
+			mouseListeners.remove(listener);
+
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#invokeMouseListeners(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
+	 */
+	public void invokeMouseListeners(TableRowMouseEvent event) {
+		ArrayList<TableRowMouseListener> listeners = mouseListeners;
+		if (listeners == null) {
+			return;
+		}
+
+		for (int i = 0; i < listeners.size(); i++) {
+			try {
+				TableRowMouseListener l = listeners.get(i);
+
+				l.rowMouseTrigger(event);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#isMouseOver()
+	 */
+	public boolean isMouseOver() {
+		return tv.getTableRowWithCursor() == this;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#isExpanded()
+	 */
+	public boolean isExpanded() {
+		return expanded;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setExpanded(boolean)
+	 */
+	public void setExpanded(boolean b) {
+		expanded = b;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getParentRowCore()
+	 */
+	public TableRowCore getParentRowCore() {
+		return parentRow;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#isInPaintItem()
+	 */
+	public boolean isInPaintItem() {
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#getDataSource()
+	 */
+	public Object getDataSource() {
+		return getDataSource(false);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#getTableID()
+	 */
+	public String getTableID() {
+		return tv.getTableID();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setForeground(org.eclipse.swt.graphics.Color)
+	 */
+	public abstract boolean setForeground(Color c);
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#setForeground(int, int, int)
+	 */
+	public void setForeground(int red, int green, int blue) {
+		setForeground2(red, green, blue);
+	}
+	
+	public boolean setForeground2(int red, int green, int blue) {
+		if (red < 0 || green < 0 || blue < 0) {
+			return setForeground((Color) null);
+		}
+		return setForeground(new RGB(red, green, blue));
+	}
+
+	private boolean setForeground(final RGB rgb) {
+		Color colorFG = getForeground();
+		boolean changed = colorFG == null || colorFG.isDisposed()
+				|| !colorFG.getRGB().equals(rgb);
+		if (changed) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					setForeground(ColorCache.getColor(Display.getCurrent(), rgb));
+				}
+			});
+		}
+		return changed;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#setForeground(int[])
+	 */
+	public void setForeground(int[] rgb) {
+		setForeground2(rgb);
+	}
+
+	public boolean setForeground2(int[] rgb) {
+		if (rgb == null || rgb.length < 3) {
+			return setForeground((Color) null);
+		}
+		return setForeground2(rgb[0], rgb[1], rgb[2]);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#setForegroundToErrorColor()
+	 */
+	public void setForegroundToErrorColor() {
+		this.setForeground(Colors.colorError);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#isValid()
+	 */
+	public boolean isValid() {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return true;
+  		}
+  
+  		boolean valid = true;
+  		for (TableCell cell : mTableCells.values()) {
+  			if (cell != null && cell.isValid()) {
+  				return false;
+  			}
+  		}
+  
+ 		return valid;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#getTableCell(java.lang.String)
+	 */
+	public TableCell getTableCell(String field) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return null;
+  		}
+  
+  		return mTableCells.get(field);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#isSelected()
+	 */
+	public boolean isSelected() {
+		return getView().isSelected(this);
+	}
+
+	public boolean isFocused() {
+		return getView().getFocusedRow() == this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#getData(java.lang.String)
+	 */
+	public Object getData(String id) {
+		synchronized (this) {
+			return dataList == null ? null : dataList.get(id);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableRow#setData(java.lang.String, java.lang.Object)
+	 */
+	public void setData(String id, Object data) {
+		synchronized (this) {
+			if (dataList == null) {
+				dataList = new HashMap<String, Object>(1);
+			}
+			if (data == null) {
+				dataList.remove(id);
+			} else {
+				dataList.put(id, data);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setIconSize(org.eclipse.swt.graphics.Point)
+	 */
+	public abstract boolean setIconSize(Point pt);
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getForeground()
+	 */
+	public abstract Color getForeground();
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getBackground()
+	 */
+	public abstract Color getBackground();
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getTableCellSWT(java.lang.String)
+	 */
+	public TableCellSWT getTableCellSWT(String name) {
+		synchronized (lock) {
+  		if (bDisposed || mTableCells == null) {
+  			return null;
+  		}
+  
+  		TableCellCore cell = mTableCells.get(name);
+  		if (cell instanceof TableCellSWT) {
+  			return (TableCellSWT) cell;
+  		}
+  		return null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getBounds()
+	 */
+	public abstract Rectangle getBounds();
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setBackgroundImage(org.eclipse.swt.graphics.Image)
+	 */
+	public abstract void setBackgroundImage(Image image);
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getFontStyle()
+	 */
+	public int getFontStyle() {
+		return fontStyle;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setFontStyle(int)
+	 */
+	public boolean setFontStyle(int style) {
+		if (fontStyle == style) {
+			return false;
+		}
+
+		fontStyle = style;
+		invalidate();
+
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#getAlpha()
+	 */
+	public int getAlpha() {
+		return alpha;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setAlpha(int)
+	 */
+	public boolean setAlpha(int alpha) {
+		if (alpha == this.alpha) {
+			return false;
+		}
+		this.alpha = alpha;
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableRowSWT#setWidgetSelected(boolean)
+	 */
+	public abstract void setWidgetSelected(boolean selected);
+
+
+	public void setShown(boolean b, boolean force) {
+		if (bDisposed) {
+			return;
+		}
+
+		if (b == wasShown && !force) {
+			return;
+		}
+		wasShown = b;
+
+		Collection<TableCellCore> lTableCells = null;
+		synchronized (lock) {
+			if (mTableCells != null) {
+				lTableCells = new ArrayList<TableCellCore>(mTableCells.values());
+			}
+		}
+
+		if (lTableCells != null) {
+  		for (TableCellCore cell : lTableCells) {
+  			if (cell != null) {
+  				cell.invokeVisibilityListeners(b
+  						? TableCellVisibilityListener.VISIBILITY_SHOWN
+  						: TableCellVisibilityListener.VISIBILITY_HIDDEN, true);
+  			}
+  		}
+		}
+
+		/* Don't need to refresh; paintItem will trigger a refresh on
+		 * !cell.isUpToDate()
+		 *
+		if (b) {
+			refresh(b, true);
+		}
+		/**/
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#redraw()
+	 */
+	public void redraw() {
+		redraw(false);
+	}
+
+	/*
+	public abstract void setSubItemCount(int length);
+
+	public abstract int getSubItemCount();
+
+	public abstract TableRowCore linkSubItem(int indexOf);
+
+	public abstract void setSubItems(Object[] datasources);
+
+	public abstract TableRowCore[] getSubRowsWithNull();
+
+	public abstract void removeSubRow(Object datasource);
+	*/
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableTooltips.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableTooltips.java
index e2208b1..3fd772a 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableTooltips.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableTooltips.java
@@ -30,6 +30,8 @@ import org.eclipse.swt.widgets.*;
 import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+
 /**
  * @author TuxPaper
  * @created Mar 1, 2007
@@ -70,7 +72,7 @@ public class TableTooltips
 				if (toolTipShell != null && !toolTipShell.isDisposed())
 					toolTipShell.dispose();
 
-				TableCellSWT cell = tv.getTableCell(event.x, event.y);
+				TableCellCore cell = tv.getTableCell(event.x, event.y);
 				if (cell == null)
 					return;
 				cell.invokeToolTipListeners(TableCellSWT.TOOLTIPLISTENER_HOVER);
@@ -80,7 +82,7 @@ public class TableTooltips
 				}
 				
 				// TODO: support composite, image, etc
-				if (oToolTip == null)
+				if (oToolTip == null || oToolTip.toString().length() == 0)
 					return;
 
 				Display d = composite.getDisplay();
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewFactory.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewFactory.java
new file mode 100644
index 0000000..d3fd734
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewFactory.java
@@ -0,0 +1,25 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.painted.TableViewPainted;
+
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+
+public class TableViewFactory
+{
+	public static<V> TableViewSWT<V> createTableViewSWT(Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, TableColumnCore[] _basicItems,
+			String _sDefaultSortOn, int _iTableStyle) {
+		//return new TableViewSWTImpl<V>(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems, _sDefaultSortOn, _iTableStyle);
+		return (TableViewSWT<V>) new TableViewPainted(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems, _sDefaultSortOn, _iTableStyle);
+	}
+
+	public static<V> TableViewSWT<V> createTableViewSWT(boolean newCode, Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, TableColumnCore[] _basicItems,
+			String _sDefaultSortOn, int _iTableStyle) {
+		if (newCode) {
+			return (TableViewSWT<V>) new TableViewPainted(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems, _sDefaultSortOn, _iTableStyle);
+		}
+		return new TableViewSWTImpl<V>(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems, _sDefaultSortOn, _iTableStyle);
+	}
+}
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 fd00c27..c86d1c6 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWTImpl.java
@@ -1,5 +1,4 @@
 /*
- * Created on 2004/Apr/18
  *
  * Copyright (C) 2004, 2005, 2006 Aelitis SAS, All rights Reserved
  *
@@ -24,8 +23,6 @@ package org.gudy.azureus2.ui.swt.views.table.impl;
 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.*;
@@ -35,46 +32,37 @@ import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.layout.*;
 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.ConfigurationManager;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 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.common.util.MenuItemManager;
+import org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent;
+import org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener;
 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;
-import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
-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.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
 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 com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.TableViewFilterCheck;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 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;
-import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
-
-import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 
 /** 
  * An IView with a sortable table.  Handles composite/menu/table creation
  * and management.
  *
+ * @deprecated This implementation requires much massaging of the native table/tree widget
+ * 
  * @author Olivier (Original PeersView/MyTorrentsView/etc code)
  * @author TuxPaper
  *         2004/Apr/20: Remove need for tableItemToObject
@@ -103,49 +91,19 @@ import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
 public class TableViewSWTImpl<DATASOURCETYPE>
 	extends TableViewImpl<DATASOURCETYPE>
 	implements ParameterListener, TableViewSWT<DATASOURCETYPE>,
-	TableStructureModificationListener<DATASOURCETYPE>, ObfusticateImage,
-	KeyListener
+	ObfusticateImage, MessageTextListener
 {
-	private final static LogIDs LOGID = LogIDs.GUI;
-
-	/** Virtual Tables still a work in progress */
-	// Non-Virtual tables scroll faster with they keyboard
-	// Virtual tables don't flicker when updating a cell (Windows)
-	private final static boolean DISABLEVIRTUAL = SWT.getVersion() < 3138;
-
-	private static final boolean DEBUG_SORTER = false;
-
-	// Shorter name for ConfigManager, easier to read code
-	private static final ConfigurationManager configMan = ConfigurationManager.getInstance();
-
-	private static final String CFG_SORTDIRECTION = "config.style.table.defaultSortOrder";
-
-	private static final long BREAKOFF_ADDTOMAP = 1000;
+	protected final static boolean DRAW_VERTICAL_LINES = Constants.isWindows;
 
-	private static final long BREAKOFF_ADDROWSTOSWT = 800;
+	protected static final boolean DRAW_FULL_ROW = Constants.isWindows;
 
-	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 final static LogIDs LOGID = LogIDs.GUI;
 
-	private static final Color COLOR_FILTER_REGEX	= Colors.fadedYellow;
-	
-	private static final boolean DEBUG_CELL_CHANGES = false;
+	protected 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 
-	 * "Table.<i>TableID</i>"
-	 */
-	protected String sTableID;
+	private static final boolean DEBUG_ROWCHANGE = false;
 
-	/** Prefix for retrieving text from the properties file (MessageText)
-	 * Typically <i>TableID</i> + "View"
-	 */
-	protected String sPropertiesPrefix;
+	private static final boolean OBEY_COLUMN_MINWIDTH = false;
 
 	/** Column name to sort on if user hasn't chosen one yet 
 	 */
@@ -154,16 +112,10 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	/** 1st column gap problem (Eclipse Bug 43910).  Set to true when table is 
 	 * using TableItem.setImage 
 	 */
-	private boolean bSkipFirstColumn;
+	protected boolean bSkipFirstColumn = true;
 
 	private Point ptIconSize = null;
 
-	/** Basic (pre-defined) Column Definitions */
-	private TableColumnCore[] basicItems;
-
-	/** All Column Definitions.  The array is not necessarily in column order */
-	private TableColumnCore[] tableColumns;
-
 	/** Composite for IView implementation */
 	private Composite mainComposite;
 
@@ -171,43 +123,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	private Composite tableComposite;
 
 	/** Table for SortableTable implementation */
-	private Table table;
+	private TableOrTreeSWT table;
 
-	private TableEditor editor;
+	private ControlEditor editor;
 
 	/** SWT style options for the creation of the Table */
 	protected int iTableStyle;
 
-	/** Whether the Table is Virtual */
-	private boolean bTableVirtual;
-
 	/** Context Menu */
 	private Menu menu;
 
-	/** Link DataSource to their row in the table.
-	 * key = DataSource
-	 * value = TableRowSWT
-	 */
-	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;
-
-	private AEMonitor sortedRows_mon = new AEMonitor("TableView:sR");
-
-	private AEMonitor sortColumn_mon = new AEMonitor("TableView:sC");
-
-	/** Sorting functions */
-	protected TableColumnCore sortColumn;
-
-	/** TimeStamp of when last sorted all the rows was */
-	private long lLastSortedOn;
-
 	/** For updating GUI.  
 	 * Some UI objects get updating every X cycles (user configurable) 
 	 */
@@ -223,111 +148,46 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 * Cache of selected table items to bypass insufficient drawing on Mac OS X
 	 */
 	//private ArrayList oldSelectedItems;
-	/** We need to remember the order of the columns at the time we added them
-	 * in case the user drags the columns around.
-	 */
-	private TableColumnCore[] columnsOrdered;
-
-	private boolean[] columnsVisible;
 
 	private ColumnMoveListener columnMoveListener = new ColumnMoveListener();
 
-	/** Queue added datasources and add them on refresh */
-	private LightHashSet dataSourcesToAdd = new LightHashSet(4);
-
-	/** Queue removed datasources and add them on refresh */
-	private LightHashSet dataSourcesToRemove = new LightHashSet(4);
-
-	private boolean bReallyAddingDataSources = false;
-
 	/** TabViews */
 	public boolean bEnableTabViews = false;
 
-	/** TabViews */
-	private CTabFolder tabFolder;
-
-	/** TabViews */
-	private ArrayList<IView> tabViews = new ArrayList<IView>(1);
-
-	private int lastTopIndex = 0;
+	private TableRowSWT[] visibleRows;
 
-	private int lastBottomIndex = -1;
-
-	protected IView[] coreTabViews = null;
-
-	private long lCancelSelectionTriggeredOn = -1;
-
-	private List<TableViewSWTMenuFillListener> listenersMenuFill = new ArrayList<TableViewSWTMenuFillListener>(
-			1);
+	private boolean[] columnsVisible;
 
 	private TableViewSWTPanelCreator mainPanelCreator;
 
-	private List<KeyListener> listenersKey = new ArrayList<KeyListener>(1);
-
 	private boolean columnPaddingAdjusted = false;
 
 	private boolean columnVisibilitiesChanged = true;
 
-	// What type of data is stored in this table
-	private final Class classPluginDataSourceType;
-
-	private AEMonitor listeners_mon = new AEMonitor("tablelisteners");
-
-	private ArrayList<TableRowRefreshListener> refreshListeners;
-
-	private Font fontBold;
-
-	private Rectangle clientArea;
+	/**
+	 * Up to date table client area.  So far, the best places to refresh
+	 * this variable are in the PaintItem event and the scrollbar's events.
+	 * Typically table.getClientArea() is time consuming 
+	 */
+	protected Rectangle clientArea;
 
 	private boolean isVisible;
 
-	private boolean menuEnabled = true;
-
-	private boolean headerVisible = true;
+	// private Rectangle firstClientArea;
 
-	/**
-	 * Up to date list of selected rows, so we can access rows without being on SWT Thread
-	 */
-	private int[] selectedRowIndexes;
+	private int lastHorizontalPos;
+	
 
-	private List<DATASOURCETYPE> listSelectedCoreDataSources;
+	private boolean useTree;
 
-	private Utils.addDataSourceCallback processDataSourceQueueCallback = new Utils.addDataSourceCallback() {
-		public void process() {
-			processDataSourceQueue();
-		}
+	protected int headerHeight;
 
-		public void debug(String str) {
-			TableViewSWTImpl.this.debug(str);
-		}
-	};
+	private Shell shell;
 
-	// private Rectangle firstClientArea;
+	private TableViewSWT_Common tvSWTCommon;
 
-	private int lastHorizontalPos;
-	
+	private TableViewSWT_TabsCommon tvTabsCommon;
 
-	// 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
@@ -342,22 +202,41 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 * @param _sDefaultSortOn Column name to sort on if user hasn't chosen one yet
 	 * @param _iTableStyle SWT style constants used when creating the table
 	 */
-	public TableViewSWTImpl(Class pluginDataSourceType, String _sTableID, String _sPropertiesPrefix,
-			TableColumnCore[] _basicItems, String _sDefaultSortOn, int _iTableStyle) {
-		classPluginDataSourceType = pluginDataSourceType;
-		sTableID = _sTableID;
-		basicItems = _basicItems;
-		sPropertiesPrefix = _sPropertiesPrefix;
-		sDefaultSortOn = _sDefaultSortOn;
-		iTableStyle = _iTableStyle | SWT.V_SCROLL;
-		if (DISABLEVIRTUAL) {
-			iTableStyle &= ~(SWT.VIRTUAL);
+	public TableViewSWTImpl(Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, TableColumnCore[] _basicItems,
+			String _sDefaultSortOn, int _iTableStyle) {
+		super(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems);
+		setProvideIndexesOnRemove(true);
+		boolean wantTree = (_iTableStyle & SWT.CASCADE) != 0;
+		_iTableStyle &= ~SWT.CASCADE;
+		if (wantTree) {
+			useTree = COConfigurationManager.getBooleanParameter("Table.useTree")
+					&& !Utils.isCarbon;
 		}
-		bTableVirtual = (iTableStyle & SWT.VIRTUAL) != 0;
+		sDefaultSortOn = _sDefaultSortOn;
+		iTableStyle = _iTableStyle | SWT.V_SCROLL | SWT.DOUBLE_BUFFERED;
+
+		tvSWTCommon = new TableViewSWT_Common(this) {
+			@Override
+			public void mouseDown(TableRowSWT row, TableCellCore cell, int button,
+					int stateMask) {
+				if (row != null && !row.isRowDisposed()) {
+					tv.setRowSelected(row, true, true);
+				}
+			}
+			
+			public void widgetSelected(SelectionEvent event) {
+				updateSelectedRows(table.getSelection(), true);
+			}
+			
+			@Override
+			public void keyReleased(KeyEvent e) {
+				swt_calculateClientArea();
+				visibleRowsChanged();
 
-		mapDataSourceToRow = new LightHashMap<DATASOURCETYPE, TableRowCore>();
-		sortedRows = new ArrayList<TableRowSWT>();
-		listUnfilteredDataSources = new HashSet<DATASOURCETYPE>();
+				super.keyReleased(e);
+			}
+		};
 	}
 
 	/**
@@ -370,63 +249,30 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 * @param _sPropertiesPrefix Prefix for retrieving text from the properties
 	 *                            file (MessageText).  
 	 *                            Typically <i>TableID</i> + "View"
-	 * @param _basicItems Column Definitions
 	 * @param _sDefaultSortOn Column name to sort on if user hasn't chosen one
 	 *                         yet
 	 */
-	public TableViewSWTImpl(Class pluginDataSourceType,
-			String _sTableID, String _sPropertiesPrefix,
-			TableColumnCore[] _basicItems, String _sDefaultSortOn) {
-		this(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems,
-				_sDefaultSortOn, SWT.SINGLE | SWT.FULL_SELECTION | SWT.VIRTUAL);
-	}
-
-	private void initializeColumnDefs() {
-		// XXX Adding Columns only has to be done once per TableID.  
-		// Doing it more than once won't harm anything, but it's a waste.
-		TableColumnManager tcManager = TableColumnManager.getInstance();
-
-		if (basicItems != null) {
-			if (tcManager.getTableColumnCount(sTableID) != basicItems.length) {
-				tcManager.addColumns(basicItems);
-			}
-			basicItems = null;
-		}
-
-		tableColumns = tcManager.getAllTableColumnCoreAsArray(classPluginDataSourceType,
-				sTableID);
+	public TableViewSWTImpl(Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, String _sDefaultSortOn) {
 
-		// fixup order
-		tcManager.ensureIntegrety(sTableID);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#setColumnList(com.aelitis.azureus.ui.common.table.TableColumnCore[], java.lang.String)
-	// XXX This isn't right
-	public void setColumnList(TableColumnCore[] columns,
-			String defaultSortColumnID, boolean defaultSortOrder,
-			boolean titleIsMinWidth) {
-		// XXX Adding Columns only has to be done once per TableID.  
-		// Doing it more than once won't harm anything, but it's a waste.
-		TableColumnManager tcManager = TableColumnManager.getInstance();
-		if (tcManager.getTableColumnCount(sTableID) != columns.length) {
-			tcManager.addColumns(basicItems);
-		}
-
-		tableColumns = tcManager.getAllTableColumnCoreAsArray(classPluginDataSourceType,
-				sTableID);
-
-		// fixup order
-		tcManager.ensureIntegrety(sTableID);
+		this(pluginDataSourceType, _sTableID, _sPropertiesPrefix,
+				new TableColumnCore[0], _sDefaultSortOn, SWT.SINGLE
+						| SWT.FULL_SELECTION | SWT.VIRTUAL);
 	}
 
 	// AbstractIView::initialize
 	public void initialize(Composite composite) {
 		composite.setRedraw(false);
-		mainComposite = createSashForm(composite);
+
+		tvTabsCommon = new TableViewSWT_TabsCommon(this);
+
+		shell = composite.getShell();
+		mainComposite = tvTabsCommon.createSashForm(composite);
+		tableComposite = tvTabsCommon.tableComposite;
 		table = createTable(tableComposite);
 		menu = createMenu(table);
 		clientArea = table.getClientArea();
-		editor = new TableEditor(table);
+		editor = TableOrTreeUtils.createTableOrTreeEditor(table);
 		editor.minimumWidth = 80;
 		editor.grabHorizontal = true;
 		initializeTable(table);
@@ -439,260 +285,10 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		// So all TableView objects of the same TableID have the same columns,
 		// and column widths, etc
-		TableStructureEventDispatcher.getInstance(sTableID).addListener(this);
+		TableStructureEventDispatcher.getInstance(tableID).addListener(this);
 		composite.setRedraw(true);
 	}
 
-	private Composite createSashForm(final Composite composite) {
-		if (!bEnableTabViews) {
-			tableComposite = createMainPanel(composite);
-			return tableComposite;
-		}
-
-		int iNumViews = coreTabViews == null ? 0 : coreTabViews.length;
-
-		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
-		Map<String, UISWTViewEventListener> pluginViews = null;
-		if (uiFunctions != null) {
-			UISWTInstanceImpl pluginUI = uiFunctions.getSWTPluginInstanceImpl();
-
-			if (pluginUI != null) {
-				pluginViews = pluginUI.getViewListeners(sTableID);
-				if (pluginViews != null) {
-					iNumViews += pluginViews.size();
-				}
-			}
-		}
-
-		if (iNumViews == 0) {
-			tableComposite = createMainPanel(composite);
-			return tableComposite;
-		}
-
-		FormData formData;
-
-		final Composite form = new Composite(composite, SWT.NONE);
-		FormLayout flayout = new FormLayout();
-		flayout.marginHeight = 0;
-		flayout.marginWidth = 0;
-		form.setLayout(flayout);
-		GridData gridData;
-		gridData = new GridData(GridData.FILL_BOTH);
-		form.setLayoutData(gridData);
-
-		// Create them in reverse order, so we can have the table auto-grow, and
-		// set the tabFolder's height manually
-
-		final int TABHEIGHT = 20;
-		tabFolder = new CTabFolder(form, SWT.TOP | SWT.BORDER);
-		tabFolder.setMinimizeVisible(true);
-		tabFolder.setTabHeight(TABHEIGHT);
-		final int iFolderHeightAdj = tabFolder.computeSize(SWT.DEFAULT, 0).y;
-
-		final Sash sash = new Sash(form, SWT.HORIZONTAL);
-
-		tableComposite = createMainPanel(form);
-		Composite cFixLayout = tableComposite;
-		while (cFixLayout != null && cFixLayout.getParent() != form) {
-			cFixLayout = cFixLayout.getParent();
-		}
-		if (cFixLayout == null) {
-			cFixLayout = tableComposite;
-		}
-		GridLayout layout = new GridLayout();
-		layout.numColumns = 1;
-		layout.horizontalSpacing = 0;
-		layout.verticalSpacing = 0;
-		layout.marginHeight = 0;
-		layout.marginWidth = 0;
-		cFixLayout.setLayout(layout);
-
-		// FormData for Folder
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.bottom = new FormAttachment(100, 0);
-		int iSplitAt = configMan.getIntParameter(sPropertiesPrefix + ".SplitAt",
-				3000);
-		// Was stored at whole
-		if (iSplitAt < 100) {
-			iSplitAt *= 100;
-		}
-
-		double pct = iSplitAt / 10000.0;
-		if (pct < 0.03) {
-			pct = 0.03;
-		} else if (pct > 0.97) {
-			pct = 0.97;
-		}
-
-		// height will be set on first resize call
-		sash.setData("PCT", new Double(pct));
-		tabFolder.setLayoutData(formData);
-		final FormData tabFolderData = formData;
-
-		// FormData for Sash
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.bottom = new FormAttachment(tabFolder);
-		formData.height = 5;
-		sash.setLayoutData(formData);
-
-		// FormData for table Composite
-		formData = new FormData();
-		formData.left = new FormAttachment(0, 0);
-		formData.right = new FormAttachment(100, 0);
-		formData.top = new FormAttachment(0, 0);
-		formData.bottom = new FormAttachment(sash);
-		cFixLayout.setLayoutData(formData);
-
-		// Listeners to size the folder
-		sash.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				final boolean FASTDRAG = true;
-
-				if (FASTDRAG && e.detail == SWT.DRAG) {
-					return;
-				}
-
-				if (tabFolder.getMinimized()) {
-					tabFolder.setMinimized(false);
-					refreshSelectedSubView();
-					configMan.setParameter(sPropertiesPrefix + ".subViews.minimized",
-							false);
-				}
-
-				Rectangle area = form.getClientArea();
-				tabFolderData.height = area.height - e.y - e.height - iFolderHeightAdj;
-				form.layout();
-
-				Double l = new Double((double) tabFolder.getBounds().height
-						/ form.getBounds().height);
-				sash.setData("PCT", l);
-				if (e.detail != SWT.DRAG) {
-					configMan.setParameter(sPropertiesPrefix + ".SplitAt",
-							(int) (l.doubleValue() * 10000));
-				}
-			}
-		});
-
-		final CTabFolder2Adapter folderListener = new CTabFolder2Adapter() {
-			public void minimize(CTabFolderEvent event) {
-				tabFolder.setMinimized(true);
-				tabFolderData.height = iFolderHeightAdj;
-				CTabItem[] items = tabFolder.getItems();
-				for (int i = 0; i < items.length; i++) {
-					CTabItem tabItem = items[i];
-					tabItem.getControl().setVisible(false);
-				}
-				form.layout();
-
-				configMan.setParameter(sPropertiesPrefix + ".subViews.minimized", true);
-			}
-
-			public void restore(CTabFolderEvent event) {
-				tabFolder.setMinimized(false);
-				CTabItem selection = tabFolder.getSelection();
-				if (selection != null) {
-					selection.getControl().setVisible(true);
-				}
-				form.notifyListeners(SWT.Resize, null);
-
-				refreshSelectedSubView();
-
-				configMan.setParameter(sPropertiesPrefix + ".subViews.minimized", false);
-			}
-
-		};
-		tabFolder.addCTabFolder2Listener(folderListener);
-
-		tabFolder.addSelectionListener(new SelectionListener() {
-			public void widgetSelected(SelectionEvent e) {
-				// make sure its above
-				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) {
-				}
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-			}
-		});
-
-		tabFolder.addMouseListener(new MouseAdapter() {
-			public void mouseDown(MouseEvent e) {
-				if (tabFolder.getMinimized()) {
-					folderListener.restore(null);
-					// If the user clicked down on the restore button, and we restore
-					// before the CTabFolder does, CTabFolder will minimize us again
-					// There's no way that I know of to determine if the mouse is 
-					// on that button!
-
-					// one of these will tell tabFolder to cancel
-					e.button = 0;
-					tabFolder.notifyListeners(SWT.MouseExit, null);
-				}
-			}
-		});
-
-		form.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event e) {
-				if (tabFolder.getMinimized()) {
-					return;
-				}
-
-				Double l = (Double) sash.getData("PCT");
-				if (l != null) {
-					tabFolderData.height = (int) (form.getBounds().height * l.doubleValue())
-							- iFolderHeightAdj;
-					form.layout();
-				}
-			}
-		});
-
-		if (coreTabViews != null) {
-			for (int i = 0; i < coreTabViews.length; i++) {
-				addTabView(coreTabViews[i]);
-			}
-		}
-
-		// Call plugin listeners
-		if (pluginViews != null) {
-			String[] sNames = pluginViews.keySet().toArray(new String[0]);
-			for (int i = 0; i < sNames.length; i++) {
-				UISWTViewEventListener l = pluginViews.get(sNames[i]);
-				if (l != null) {
-					try {
-						UISWTViewImpl view = new UISWTViewImpl(sTableID, sNames[i], l);
-						addTabView(view);
-					} catch (Exception e) {
-						// skip, plugin probably specifically asked to not be added
-					}
-				}
-			}
-		}
-
-		if (configMan.getBooleanParameter(
-				sPropertiesPrefix + ".subViews.minimized", false)) {
-			tabFolder.setMinimized(true);
-			tabFolderData.height = iFolderHeightAdj;
-		} else {
-			tabFolder.setMinimized(false);
-		}
-
-		tabFolder.setSelection(0);
-
-		return form;
-	}
 
 	/** Creates a composite within the specified composite and sets its layout
 	 * to a default FillLayout().
@@ -706,12 +302,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			return mainPanelCreator.createTableViewPanel(composite);
 		}
 		Composite panel = new Composite(composite, SWT.NO_FOCUS);
+		composite.getLayout();
 		GridLayout layout = new GridLayout();
 		layout.marginHeight = 0;
 		layout.marginWidth = 0;
 		panel.setLayout(layout);
 
-		panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+		Object parentLayout = composite.getLayout();
+		if (parentLayout == null || (parentLayout instanceof GridLayout)) {
+			panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+		}
 
 		return panel;
 	}
@@ -720,8 +320,8 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 *
 	 * @return The created Table.
 	 */
-	public Table createTable(Composite panel) {
-		table = new Table(panel, iTableStyle);
+	public TableOrTreeSWT createTable(Composite panel) {
+		table = TableOrTreeUtils.createGrid(panel, iTableStyle, useTree);
 		table.setLayoutData(new GridData(GridData.FILL_BOTH));
 
 		return table;
@@ -731,23 +331,29 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 *
 	 * @param table Table to be initialized
 	 */
-	public void initializeTable(final Table table) {
-		initializeColumnDefs();
-
+	public void initializeTable(final TableOrTreeSWT table) {
 		iTableStyle = table.getStyle();
-		bTableVirtual = (iTableStyle & SWT.VIRTUAL) != 0;
+		if ((iTableStyle & SWT.VIRTUAL) == 0) {
+			throw new Error("Virtual Table Required");
+		}
 
 		table.setLinesVisible(Utils.TABLE_GRIDLINE_IS_ALTERNATING_COLOR);
 		table.setMenu(menu);
-		table.setData("Name", sTableID);
-		table.setData("TableView", this);
+		table.setData("Name", tableID);
+		table.setData("ObfusticateImage", this);
+		
+		// On Windows, TreeItems POSTPAINT event spendsabout 7% of it's time in getFont()
+		// calling the OS API.  If we set the font, it skips the API call.
+		// This could be optimized further by setting the font on each table item,
+		// however, it's unknown what performace hit we'd get on row creation.
+		table.setFont(table.getFont());
 
 		// Setup table
 		// -----------
 
 		table.addPaintListener(new PaintListener() {
 			public void paintControl(PaintEvent event) {
-				changeColumnIndicator();
+				swt_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.
@@ -757,28 +363,32 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			}
 		});
 
-		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.addListener(SWT.PaintItem, new TableViewSWT_PaintItem(this, table));
+
+		if (Constants.isWindows) {
+			TableViewSWT_EraseItem eraseItemListener = new TableViewSWT_EraseItem(this, table);
+			table.addListener(SWT.EraseItem, eraseItemListener);
+			table.addListener(SWT.Paint, eraseItemListener);
+		}
 
 		ScrollBar horizontalBar = table.getHorizontalBar();
 		if (horizontalBar != null) {
 			horizontalBar.addSelectionListener(new SelectionListener() {
 				public void widgetDefaultSelected(SelectionEvent e) {
-					calculateClientArea();
+					Utils.execSWTThreadLater(0, new AERunnable() {
+						public void runSupport() {
+							swt_calculateClientArea();
+						}
+					});
 					//updateColumnVisibilities();
 				}
 
 				public void widgetSelected(SelectionEvent e) {
-					calculateClientArea();
+					Utils.execSWTThreadLater(0, new AERunnable() {
+						public void runSupport() {
+							swt_calculateClientArea();
+						}
+					});
 					//updateColumnVisibilities();
 				}
 			});
@@ -792,6 +402,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 					iColumnNo--;
 				}
 
+				TableColumnCore[] columnsOrdered = getVisibleColumns();
 				if (iColumnNo >= 0 && iColumnNo < columnsOrdered.length) {
 					TableColumnCore tc = columnsOrdered[iColumnNo];
 					int preferredWidth = tc.getPreferredWidth();
@@ -806,438 +417,164 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		});
 
 		// Deselect rows if user clicks on a blank spot (a spot with no row)
-		table.addMouseListener(new MouseAdapter() {
-			public void mouseDoubleClick(MouseEvent e) {
-				TableColumnCore tc = getTableColumnByOffset(e.x);
-				TableCellSWT cell = getTableCell(e.x, e.y);
-				if (cell != null && tc != null) {
-					TableCellMouseEvent event = createMouseEvent(cell, e,
-							TableCellMouseEvent.EVENT_MOUSEDOUBLECLICK, false);
-					if (event != null) {
-						tc.invokeCellMouseListeners(event);
-						cell.invokeMouseListeners(event);
-						if (event.skipCoreFunctionality) {
-							lCancelSelectionTriggeredOn = System.currentTimeMillis();
+		table.addMouseListener(tvSWTCommon);
+		table.addMouseMoveListener(tvSWTCommon);
+		table.addSelectionListener(tvSWTCommon);
+		
+		// we are sent a SWT.Settings event when the language changes and
+		// when System fonts/colors change.  In both cases, invalidate
+		table.addListener(SWT.Settings, new Listener() {
+			public void handleEvent(Event e) {
+				tableInvalidate();
+			}
+		});
+		
+		if (useTree) {
+  		Listener listenerExpandCollapse = new Listener() {
+  			public void handleEvent(Event event) {
+  				TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item);
+  				if (item == null) {
+  					return;
+  				}
+  				TableRowCore row = getRow(item);
+  				if (row == null || row.isRowDisposed()) {
+  					return;
+  				}
+  				row.setExpanded(event.type == SWT.Expand ? true : false);
+  				Utils.execSWTThreadLater(0, new AERunnable() {
+						public void runSupport() {
+							visibleRowsChanged();
 						}
-					}
+					});
+  			}
+  		};
+  		table.addListener(SWT.Expand, listenerExpandCollapse);
+  		table.addListener(SWT.Collapse, listenerExpandCollapse);
+		}
+
+		new TableTooltips(this, table.getComposite());
+
+		table.addKeyListener(tvSWTCommon);
+		
+		table.addDisposeListener(new DisposeListener(){
+			public void widgetDisposed(DisposeEvent e) {
+				TableViewSWTFilter<?> filter = getSWTFilter();
+				if (filter != null && filter.widget != null && !filter.widget.isDisposed()) {
+					filter.widget.removeKeyListener(tvSWTCommon);
+					filter.widget.removeModifyListener(filter.widgetModifyListener);
 				}
+				Utils.disposeSWTObjects(new Object[] { sliderArea } );
 			}
-
-			long lastMouseUpEventTime = 0;
-			public void mouseUp(MouseEvent e) {
-				long time = e.time & 0xFFFFFFFFL;
-				long diff = time - lastMouseUpEventTime;
-				if (diff < 10 && diff >= 0) {
-					return;
+		});
+/*
+		if (Utils.isCocoa) {
+			table.addListener(SWT.MouseVerticalWheel, new Listener() {
+				public void handleEvent(Event event) {
+					calculateClientArea();
+					visibleRowsChanged();
 				}
-				lastMouseUpEventTime = time;
-
-				TableColumnCore tc = getTableColumnByOffset(e.x);
-				TableCellSWT cell = getTableCell(e.x, e.y);
-				if (cell != null && tc != null) {
-					TableCellMouseEvent event = createMouseEvent(cell, e,
-							TableCellMouseEvent.EVENT_MOUSEUP, false);
-					if (event != null) {
-						tc.invokeCellMouseListeners(event);
-						cell.invokeMouseListeners(event);
-						if (event.skipCoreFunctionality) {
-							lCancelSelectionTriggeredOn = System.currentTimeMillis();
+			});
+		}
+*/		
+		ScrollBar bar = table.getVerticalBar();
+		if (bar != null) {
+			bar.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					Utils.execSWTThreadLater(0, new AERunnable() {
+						public void runSupport() {
+							// need to calc later as getClientArea isn't up to date yet
+							// on Win
+							swt_calculateClientArea();
+							visibleRowsChanged();
 						}
+					});
+					// Bug: Scroll is slow when table is not focus
+					if (!table.isFocusControl()) {
+						table.setFocus();
 					}
 				}
-			}
+			});
+		}
 
-			TableRowCore lastClickRow;
+		table.setHeaderVisible(getHeaderVisible());
+		headerHeight = table.getHeaderHeight();
 
-			public void mouseDown(MouseEvent e) {
-				// we need to fill the selected row indexes here because the
-				// dragstart event can occur before the SWT.SELECTION event and
-				// our drag code needs to know the selected rows..
-				updateSelectedRowIndexes();
+		clientArea = table.getClientArea();
+		//firstClientArea = table.getClientArea();
+		table.addListener(SWT.Resize, new Listener() {
+			public void handleEvent(Event event) {
+				swt_calculateClientArea();
+			}
+		});
 
-				TableColumnCore tc = getTableColumnByOffset(e.x);
-				TableCellSWT cell = getTableCell(e.x, e.y);
+		swt_initializeTableColumns(table);
 
-				editCell(-1, -1); // clear out current cell editor
+		MessageText.addListener(this);
+	}
+	
+	public void localeChanged(Locale old_locale, Locale new_locale) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				if (tvTabsCommon != null) {
+					tvTabsCommon.localeChanged();
+				}
+				tableInvalidate();
+				refreshTable(true);
 
-				if (cell != null && tc != null) {
-					if (e.button == 2 && e.stateMask == SWT.CONTROL) {
-						((TableCellImpl) cell).bDebug = !((TableCellImpl) cell).bDebug;
-						System.out.println("Set debug for " + cell + " to "
-								+ ((TableCellImpl) cell).bDebug);
-					}
-					TableCellMouseEvent event = createMouseEvent(cell, e,
-							TableCellMouseEvent.EVENT_MOUSEDOWN, false);
-					if (event != null) {
-						tc.invokeCellMouseListeners(event);
-						cell.invokeMouseListeners(event);
-						if (event.skipCoreFunctionality) {
-							lCancelSelectionTriggeredOn = System.currentTimeMillis();
-						}
-					}
-					if (tc.isInplaceEdit() && e.button == 1
-							&& lastClickRow == cell.getTableRowCore()) {
-						editCell(getColumnNo(e.x), cell.getTableRowCore().getIndex());
-					}
-					if (e.button == 1) {
-						lastClickRow = cell.getTableRowCore();
-					}
-				}
-
-				try {
-					if (table.getItemCount() <= 0) {
-						return;
-					}
-
-					// skip if outside client area (ie. scrollbars)
-					//System.out.println("Mouse="+iMouseX+"x"+e.y+";TableArea="+clientArea);
-					Point pMousePosition = new Point(e.x, e.y);
-					if (clientArea.contains(pMousePosition)) {
-
-						int[] columnOrder = table.getColumnOrder();
-						if (columnOrder.length == 0) {
-							return;
-						}
-						TableItem ti = table.getItem(table.getItemCount() - 1);
-						Rectangle cellBounds = ti.getBounds(columnOrder[columnOrder.length - 1]);
-						// OSX returns 0 size if the cell is not on screen (sometimes? all the time?)
-						if (cellBounds.width <= 0 || cellBounds.height <= 0) {
-							return;
-						}
-						//System.out.println("cellbounds="+cellBounds);
-						if (e.x > cellBounds.x + cellBounds.width
-								|| e.y > cellBounds.y + cellBounds.height) {
-							table.deselectAll();
-							updateSelectedRowIndexes();
-						}
-						/*        // This doesn't work because of OS inconsistencies when table is scrolled
-						 // Re-enable once SWT fixes the problem
-						 // Bug 103934: Table.getItem(Point) uses incorrect calculation on Motif
-						 //             Fixed 20050718 SWT 3.2M1 (3201) & SWT 3.1.1 (3139)
-						 // TODO: Get Build IDs and use this code (if it works)
-						 TableItem ti = table.getItem(pMousePosition);
-						 if (ti == null)
-						 table.deselectAll();
-						 */
-					}
-				} catch (Exception ex) {
-					System.out.println("MouseDownError");
-					Debug.printStackTrace(ex);
-				}
-			}
-		});
-
-		table.addMouseMoveListener(new MouseMoveListener() {
-			TableCellSWT lastCell = null;
-
-			int lastCursorID = 0;
-
-			public void mouseMove(MouseEvent e) {
-				try {
-					TableCellSWT cell = getTableCell(e.x, e.y);
-					
-					if (lastCell != null && cell != lastCell && !lastCell.isDisposed()) {
-						TableCellMouseEvent event = createMouseEvent(lastCell, e,
-								TableCellMouseEvent.EVENT_MOUSEEXIT, true);
-						if (event != null) {
-							TableColumnCore tc = ((TableColumnCore) lastCell.getTableColumn());
-							if (tc != null) {
-								tc.invokeCellMouseListeners(event);
-							}
-							lastCell.invokeMouseListeners(event);
-						}
-					}
-
-					int iCursorID = 0;
-					if (cell == null) {
-						lastCell = null;
-					} else if (cell == lastCell) {
-						iCursorID = lastCursorID;
-					} else {
-						iCursorID = cell.getCursorID();
-						lastCell = cell;
-					}
-
-					if (iCursorID < 0) {
-						iCursorID = 0;
-					}
-
-					if (iCursorID != lastCursorID) {
-						lastCursorID = iCursorID;
-
-						if (iCursorID >= 0) {
-							table.setCursor(table.getDisplay().getSystemCursor(iCursorID));
-						} else {
-							table.setCursor(null);
-						}
-					}
-
-					if (cell != null) {
-						TableCellMouseEvent event = createMouseEvent(cell, e,
-								TableCellMouseEvent.EVENT_MOUSEMOVE, false);
-						if (event != null) {
-							TableColumnCore tc = ((TableColumnCore) cell.getTableColumn());
-							if (tc.hasCellMouseMoveListener()) {
-								((TableColumnCore) cell.getTableColumn()).invokeCellMouseListeners(event);
-							}
-							cell.invokeMouseListeners(event);
-
-							// listener might have changed it
-
-							lastCursorID = cell.getCursorID();
-						}
-					}
-				} catch (Exception ex) {
-					Debug.out(ex);
-				}
-			}
-		});
-
-		table.addSelectionListener(new SelectionListener() {
-			int[] wasSelected = new int[0];
-
-			public void widgetSelected(SelectionEvent event) {
-				updateSelectedRowIndexes();
-
-				Arrays.sort(selectedRowIndexes);
-				int x = 0;
-				for (int i = 0; x < wasSelected.length && i < selectedRowIndexes.length; i++) {
-					int index = selectedRowIndexes[i];
-					if (wasSelected[x] == index) {
-						x++;
-						continue;
-					} else {
-						triggerDeselectionListeners(new TableRowCore[] {
-							getRow(wasSelected[x])
-						});
-					}
-				}
-
-				wasSelected = selectedRowIndexes;
-
-				//System.out.println(table.getSelection().length);
-				if (selectedRowIndexes.length > 0 && event.item != null) {
-					triggerSelectionListeners(new TableRowCore[] {
-						getRow((TableItem) event.item)
-					});
-				}
-
-				triggerTabViewsDataSourceChanged();
-			}
-
-			public void widgetDefaultSelected(SelectionEvent e) {
-				if (lCancelSelectionTriggeredOn > 0
-						&& System.currentTimeMillis() - lCancelSelectionTriggeredOn < 200) {
-					e.doit = false;
-					lCancelSelectionTriggeredOn = -1;
-				} else {
-					runDefaultAction(e.stateMask);
-				}
-			}
-		});
-
-		// we are sent a SWT.Settings event when the language changes and
-		// when System fonts/colors change.  In both cases, invalidate
-		table.addListener(SWT.Settings, new Listener() {
-			public void handleEvent(Event e) {
-				tableInvalidate();
-			}
-		});
-
-		new TableTooltips(this, table);
-
-		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 } );
-			}
-		});
-/*
-		if (Utils.isCocoa) {
-			table.addListener(SWT.MouseVerticalWheel, new Listener() {
-				public void handleEvent(Event event) {
-					calculateClientArea();
-					visibleRowsChanged();
-				}
-			});
-		}
-*/		
-		ScrollBar bar = table.getVerticalBar();
-		if (bar != null) {
-			bar.addSelectionListener(new SelectionAdapter() {
-				public void widgetSelected(SelectionEvent e) {
-					calculateClientArea();
-					visibleRowsChanged();
-					// Bug: Scroll is slow when table is not focus
-					if (!table.isFocusControl()) {
-						table.setFocus();
+				TableColumnOrTreeColumn[] tableColumnsSWT = table.getColumns();
+				for (int i = 0; i < tableColumnsSWT.length; i++) {
+					TableColumnCore column = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
+					if (column != null) {
+						Messages.setLanguageText(tableColumnsSWT[i].getColumn(),
+								column.getTitleLanguageKey());
 					}
 				}
-			});
-		}
-
-		table.setHeaderVisible(getHeaderVisible());
 
-		clientArea = table.getClientArea();
-		//firstClientArea = table.getClientArea();
-		table.addListener(SWT.Resize, new Listener() {
-			public void handleEvent(Event event) {
-				calculateClientArea();
 			}
 		});
-
-		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;
-			}
-
-		}
+	
+	// @see com.aelitis.azureus.ui.common.table.TableView#setHeaderVisible(boolean)
+	public void setHeaderVisible(boolean visible) {
+		super.setHeaderVisible(visible);
 
-		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();
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (table != null && !table.isDisposed()) {
+					table.setHeaderVisible(getHeaderVisible());
+					headerHeight = table.getHeaderHeight();
 				}
 			}
-		}
-		
-		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;
-	}
-
-	public void setHeaderVisible(boolean visible) {
-		headerVisible = visible;
-		if (table != null && !table.isDisposed()) {
-			table.setHeaderVisible(visible);
-		}
+		});
 	}
 
-	protected void calculateClientArea() {
+	protected void swt_calculateClientArea() {
 		Rectangle oldClientArea = clientArea;
 		clientArea = table.getClientArea();
 		ScrollBar horizontalBar = table.getHorizontalBar();
+		boolean clientAreaCausedVisibilityChanged = false;
 		if (horizontalBar != null) {
 			int pos = horizontalBar.getSelection();
 			if (pos != lastHorizontalPos) {
 				lastHorizontalPos = pos;
-				columnVisibilitiesChanged = true;
+				clientAreaCausedVisibilityChanged = true;
 			}
 		}
 		if (oldClientArea != null
 				&& (oldClientArea.x != clientArea.x || oldClientArea.width != clientArea.width)) {
-			columnVisibilitiesChanged = true;
+			clientAreaCausedVisibilityChanged = true;
 		}
-		if (columnVisibilitiesChanged) {
+		if (oldClientArea != null
+				&& (oldClientArea.y != clientArea.y || oldClientArea.height != clientArea.height)) {
+			visibleRowsChanged();
+		}
+		if (oldClientArea != null
+				&& (oldClientArea.height < table.getHeaderHeight())) {
+			clientAreaCausedVisibilityChanged = true;
+		}
+		if (clientAreaCausedVisibilityChanged) {
+			columnVisibilitiesChanged = true;
 			Utils.execSWTThreadLater(50, new AERunnable() {
 				public void runSupport() {
 					if (columnVisibilitiesChanged) {
@@ -1248,64 +585,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#triggerSelectionListeners(com.aelitis.azureus.ui.common.table.TableRowCore[])
-	protected void triggerSelectionListeners(TableRowCore[] rows) {
-		//System.out.println("triggerSelectionLis" + rows[0]);
-		if (TRIGGER_PAINT_ON_SELECTIONS) {
-			for (int i = 0; i < rows.length; i++) {
-				TableRowCore row = rows[i];
-				row.redraw();
-				table.update();
-			}
-		}
-		//System.out.println("e triggerSelectionLis" + rows[0]);
-		super.triggerSelectionListeners(rows);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#triggerDeselectionListeners(com.aelitis.azureus.ui.common.table.TableRowCore[])
-	protected void triggerDeselectionListeners(TableRowCore[] rows) {
-		if (TRIGGER_PAINT_ON_SELECTIONS) {
-			for (int i = 0; i < rows.length; i++) {
-				TableRowCore row = rows[i];
-				row.redraw();
-				table.update();
-			}
-		}
-		super.triggerDeselectionListeners(rows);
-	}
-
-	/**
-	 * 
-	 *
-	 * @since 3.1.1.1
-	 */
-	protected void triggerTabViewsDataSourceChanged() {
-		if (tabViews == null || tabViews.size() == 0) {
-			return;
-		}
-
-		// Set Data Object for all tabs.  Tabs of PluginView are sent the plugin
-		// Peer object, while Tabs of IView are sent the core PEPeer object.
-
-		// TODO: Send all datasources
-		Object[] dataSourcesCore = getSelectedDataSources(true);
-		Object[] dataSourcesPlugin = null;
-
-		for (int i = 0; i < tabViews.size(); i++) {
-			IView view = tabViews.get(i);
-			if (view != null) {
-				if (view instanceof UISWTViewImpl) {
-					if (dataSourcesPlugin == null) {
-						dataSourcesPlugin = getSelectedDataSources(false);
-					}
-
-					((UISWTViewImpl) view).dataSourceChanged(dataSourcesPlugin.length == 0
-							? null : dataSourcesPlugin);
-				} else {
-					view.dataSourceChanged(dataSourcesCore.length == 0 ? null
-							: dataSourcesCore);
-				}
-			}
+	public void triggerTabViewsDataSourceChanged(boolean sendParent) {
+		if (tvTabsCommon != null) {
+			tvTabsCommon.triggerTabViewsDataSourceChanged(sendParent);
 		}
 	}
 
@@ -1318,9 +600,24 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	private SourceReplaceListener cellEditNotifier;
 
-	private Scale slider;
+	private Control sliderArea;
+
+	private boolean isDragging;
+
+	private int maxItemShown = -1;
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#editCell(int, int)
+	 */
+	public void editCell(final int column, final int row) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_editCell(column, row);
+			}
+		});
+	}
 
-	private void editCell(final int column, final int row) {
+	private void swt_editCell(final int column, final int row) {
 		Text oldInput = (Text) editor.getEditor();
 		if (column >= table.getColumnCount() || row < 0
 				|| row >= table.getItemCount()) {
@@ -1331,8 +628,8 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			return;
 		}
 
-		TableColumn tcColumn = table.getColumn(column);
-		final TableItem item = table.getItem(row);
+		TableColumnOrTreeColumn tcColumn = table.getColumn(column);
+		final TableItemOrTreeItem item = table.getItem(row);
 
 		String cellName = (String) tcColumn.getData("Name");
 		final TableRowSWT rowSWT = (TableRowSWT) getRow(row);
@@ -1340,7 +637,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		// reuse widget if possible, this way we'll keep the focus all the time on jumping through the rows
 		final Text newInput = oldInput == null || oldInput.isDisposed() ? new Text(
-				table, Constants.isOSX ? SWT.NONE : SWT.BORDER) : oldInput;
+				table.getComposite(), Constants.isOSX ? SWT.NONE : SWT.BORDER) : oldInput;
 		final DATASOURCETYPE datasource = (DATASOURCETYPE) cell.getDataSource();
 		if (cellEditNotifier != null) {
 			cellEditNotifier.cleanup(newInput);
@@ -1450,7 +747,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 				Point sel = newInput.getSelection();
 
-				editor.setEditor(newInput, item, column);
+				TableOrTreeUtils.setEditorItem(editor, newInput, column, item);
 
 				editor.minimumWidth = newInput.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
 
@@ -1479,285 +776,71 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		l.modifyText(null);
 
-		editor.setEditor(newInput, item, column);
+		TableOrTreeUtils.setEditorItem(editor, newInput, column, item);
 		table.deselectAll();
-		table.select(row);
-		updateSelectedRowIndexes();
+		table.select(table.getItem(row));
+		setSelectedRows(new TableRowCore[] { getRow(row) }, true);
 
 		l.resizing = false;
 
 		l.controlMoved(null);
 	}
 
-	private TableCellMouseEvent createMouseEvent(TableCellSWT cell, MouseEvent e,
-			int type, boolean allowOOB) {
-		TableCellMouseEvent event = new TableCellMouseEvent();
-		event.cell = cell;
-		if (cell != null) {
-			event.row = cell.getTableRow();
-		}
-		event.eventType = type;
-		event.button = e.button;
-		// TODO: Change to not use SWT masks
-		event.keyboardState = e.stateMask;
-		event.skipCoreFunctionality = false;
-		if (cell != null) {
-			Rectangle r = cell.getBounds();
-			event.x = e.x - r.x;
-			if (!allowOOB && event.x < 0) {
-				return null;
-			}
-			event.y = e.y - r.y;
-			if (!allowOOB && event.y < 0) {
-				return null;
-			}
+	private void swt_updateColumnVisibilities(boolean doInvalidate) {
+		TableColumnOrTreeColumn[] columns = table.getColumns();
+		if (table.getItemCount() < 1 || columns.length == 0 || !table.isVisible()) {
+			return;
 		}
-
-		return event;
-	}
-
-	/**
-	 * @param event
-	 */
-	protected void paintItem(Event event) {
-		try {
-			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());
+		columnVisibilitiesChanged = false;
+		TableItemOrTreeItem topRow = table.getTopItem();
+		if (topRow == null) {
+			return;
+		}
+		for (int i = 0; i < columns.length; i++) {
+			final TableColumnCore tc = (TableColumnCore) columns[i].getData("TableColumnCore");
+			if (tc == null) {
+				continue;
 			}
 
-			TableItem item = (TableItem) event.item;
-			if (item == null || item.isDisposed()) {
-				return;
+			int position = tc.getPosition();
+			if (position < 0 || position >= columnsVisible.length) {
+				continue;
 			}
-			int iColumnNo = event.index;
 
-			//System.out.println(SystemTime.getCurrentTime() + "] paintItem " + table.indexOf(item) + ":" + iColumnNo);
-			if (bSkipFirstColumn) {
-				if (iColumnNo == 0) {
-					return;
+			Rectangle size = topRow.getBounds(i);
+			//System.out.println(tableID + ": column " + i + ":" + tc.getName() + ": size="  + size + "; ca=" + clientArea + "; pos=" + position);
+			size.intersect(clientArea);
+			boolean nowVisible = !size.isEmpty();
+			//System.out.println("  visible; was=" + columnsVisible[position] + "; now=" + nowVisible + ";doValidae=" + doInvalidate);
+			if (columnsVisible[position] != nowVisible) {
+				columnsVisible[position] = nowVisible;
+				if (nowVisible && doInvalidate) {
+					swt_runForVisibleRows(new TableGroupRowRunner() {
+						public void run(TableRowCore row) {
+							TableCellCore cell = row.getTableCellCore(tc.getName());
+							if (cell != null) {
+  							cell.invalidate();
+  							cell.redraw();
+							}
+						}
+					});
 				}
-				iColumnNo--;
 			}
+		}
+	}
 
-			if (iColumnNo >= columnsOrdered.length) {
-				System.out.println("Col #" + iColumnNo + " >= " + columnsOrdered.length
-						+ " count");
-				return;
-			}
+	public boolean isColumnVisible(
+			org.gudy.azureus2.plugins.ui.tables.TableColumn column) {
+		int position = column.getPosition();
+		if (position < 0 || position >= columnsVisible.length) {
+			return false;
+		}
+		return columnsVisible[position];
 
-			if (!isColumnVisible(columnsOrdered[iColumnNo])) {
-				//System.out.println("col not visible " + iColumnNo);
-				return;
-			}
+	}
 
-			TableRowSWT row = (TableRowSWT) getRow(item);
-			if (row == null) {
-				//System.out.println("no row");
-				return;
-			}
-
-			int rowPos = indexOf(row);
-			if (rowPos < lastTopIndex || rowPos > lastBottomIndex) {
-				// this refreshes whole row (perhaps multiple), saving the many
-				// cell.refresh calls later because !cell.isUpToDate()
-				visibleRowsChanged();
-			}
-
-			int rowAlpha = row.getAlpha();
-
-			int fontStyle = row.getFontStyle();
-			if (fontStyle == SWT.BOLD) {
-				if (fontBold == null) {
-					FontData[] fontData = event.gc.getFont().getFontData();
-					for (int i = 0; i < fontData.length; i++) {
-						FontData fd = fontData[i];
-						fd.setStyle(SWT.BOLD);
-					}
-					fontBold = new Font(event.gc.getDevice(), fontData);
-				}
-				event.gc.setFont(fontBold);
-			}
-
-			// SWT 3.2 only.  Code Ok -- Only called in SWT 3.2 mode
-			Rectangle cellBounds = item.getBounds(event.index);
-
-			//if (item.getImage(event.index) != null) {
-			//	cellBounds.x += 18;
-			//	cellBounds.width -= 18;
-			//}
-
-			if (cellBounds.width <= 0 || cellBounds.height <= 0) {
-				//System.out.println("no bounds");
-				return;
-			}
-
-			TableCellSWT cell = row.getTableCellSWT(columnsOrdered[iColumnNo].getName());
-
-			if (cell == null) {
-				return;
-			}
-
-			if (!cell.isUpToDate()) {
-				//System.out.println("R " + table.indexOf(item) + ":" + iColumnNo);
-				cell.refresh(true, true);
-				//return;
-			}
-
-			String text = cell.getText();
-
-			Rectangle clipping = new Rectangle(cellBounds.x, cellBounds.y,
-					cellBounds.width, cellBounds.height);
-			// 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) {
-				//System.out.println(row.getIndex() + " clipping="+clipping + ";" + iMinY + ";" + iMaxY + ";tca=" + tableBounds);
-				return;
-			}
-
-			event.gc.setClipping(clipping);
-
-			if (rowAlpha < 255) {
-				event.gc.setAlpha(rowAlpha);
-			}
-
-			if (cell.needsPainting()) {
-				cell.doPaint(event.gc);
-			} else if (text.length() > 0) {
-				int ofsx = 0;
-				Image image = item.getImage(event.index);
-				if (image != null && !image.isDisposed()) {
-					int ofs = image.getBounds().width;
-					ofsx += ofs;
-					cellBounds.x += ofs;
-					cellBounds.width -= ofs;
-				}
-				//System.out.println("PS " + table.indexOf(item) + ";" + cellBounds + ";" + cell.getText());
-				int style = TableColumnSWTUtils.convertColumnAlignmentToSWT(columnsOrdered[iColumnNo].getAlignment());
-				if (cellBounds.height > 20) {
-					style |= SWT.WRAP;
-				}
-				int textOpacity = cell.getTextAlpha();
-				if (textOpacity < 255) {
-					event.gc.setAlpha(textOpacity);
-				}
-				// put some padding on text
-				ofsx += 6;
-				cellBounds.x += 3;
-				cellBounds.width -= 6;
-				if (!cellBounds.isEmpty()) {
-					GCStringPrinter sp = new GCStringPrinter(event.gc, text, cellBounds,
-							true, cellBounds.height > 20, style);
-
-					boolean fit = sp.printString();
-					if (fit) {
-						
-						cell.setDefaultToolTip(null);
-					}else{
-						
-						cell.setDefaultToolTip(text);
-					}
-
-					Point size = sp.getCalculatedSize();
-					size.x += ofsx;
-
-					if (cell.getTableColumn().getPreferredWidth() < size.x) {
-						cell.getTableColumn().setPreferredWidth(size.x);
-					}
-				}else{
-					cell.setDefaultToolTip(null);
-				}
-			}
-
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	public void runDefaultAction(int stateMask) {
-		// plugin may have cancelled the default action
-
-		if (lCancelSelectionTriggeredOn > 0
-				&& System.currentTimeMillis() - lCancelSelectionTriggeredOn < 200) {
-			lCancelSelectionTriggeredOn = -1;
-		} else {
-			TableRowCore[] selectedRows = getSelectedRows();
-			triggerDefaultSelectedListeners(selectedRows, stateMask);
-		}
-	}
-
-	private void updateColumnVisibilities() {
-		TableColumn[] columns = table.getColumns();
-		int topIdx = table.getTopIndex();
-		if (topIdx < 0 || table.getItemCount() < 1) {
-			return;
-		}
-		columnVisibilitiesChanged = false;
-		TableItem topRow = table.getItem(topIdx);
-		for (int i = 0; i < columns.length; i++) {
-			final TableColumnCore tc = (TableColumnCore) columns[i].getData("TableColumnCore");
-			if (tc == null) {
-				continue;
-			}
-
-			int position = tc.getPosition();
-			if (position < 0 || position >= columnsVisible.length) {
-				continue;
-			}
-
-			Rectangle size = topRow.getBounds(i);
-			//System.out.println("column " + i + ": size="  + size + "; ca=" + clientArea);
-			size.intersect(clientArea);
-			boolean nowVisible = !size.isEmpty();
-			if (columnsVisible[position] != nowVisible) {
-				columnsVisible[position] = nowVisible;
-				if (nowVisible) {
-					runForVisibleRows(new TableGroupRowRunner() {
-						public void run(TableRowCore row) {
-							TableCellCore cell = row.getTableCellCore(tc.getName());
-							cell.invalidate();
-							cell.redraw();
-						}
-					});
-				}
-			}
-		}
-	}
-
-	public boolean isColumnVisible(
-			org.gudy.azureus2.plugins.ui.tables.TableColumn column) {
-		int position = column.getPosition();
-		if (position < 0 || position >= columnsVisible.length) {
-			return false;
-		}
-		return columnsVisible[position];
-
-	}
-
-	protected void initializeTableColumns(final Table table) {
-		TableColumn[] oldColumns = table.getColumns();
+	protected void swt_initializeTableColumns(final TableOrTreeSWT table) {
+		TableColumnOrTreeColumn[] oldColumns = table.getColumns();
 
 		for (int i = 0; i < oldColumns.length; i++) {
 			oldColumns[i].removeListener(SWT.Move, columnMoveListener);
@@ -1776,7 +859,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			private boolean bInFunction = false;
 
 			public void controlResized(ControlEvent e) {
-				TableColumn column = (TableColumn) e.widget;
+				TableColumnOrTreeColumn column = TableOrTreeUtils.getTableColumnEventItem(e.widget);
 				if (column == null || column.isDisposed() || bInFunction) {
 					return;
 				}
@@ -1788,7 +871,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 					if (tc != null) {
 						Long lPadding = (Long) column.getData("widthOffset");
 						int padding = (lPadding == null) ? 0 : lPadding.intValue();
-						tc.setWidth(column.getWidth() - padding);
+						int newWidth = column.getWidth();
+						if (OBEY_COLUMN_MINWIDTH) {
+  						int minWidth = tc.getMinWidth();
+  						if (minWidth > 0 && newWidth - padding < minWidth) {
+  							newWidth = minWidth + padding;
+  							column.setWidth(minWidth);
+  						}
+						}
+						tc.setWidth(newWidth - padding);
 					}
 
 					int columnNumber = table.indexOf(column);
@@ -1804,15 +895,17 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 		// SWT does not set 0 column width as expected in OS X; see bug 43910
 		// this will be removed when a SWT-provided solution is available to satisfy all platforms with identation issue
-		bSkipFirstColumn = bSkipFirstColumn && !Constants.isOSX;
+		//bSkipFirstColumn = bSkipFirstColumn && !Constants.isOSX;
 
 		if (bSkipFirstColumn) {
-			TableColumn tc = new TableColumn(table, SWT.NULL);
+			TableColumnOrTreeColumn tc = table.createNewColumn(SWT.NULL);
+			//tc.setWidth(useTree ? 25 : 0);
 			tc.setWidth(0);
 			tc.setResizable(false);
 			tc.setMoveable(false);
 		}
 
+		TableColumnCore[] tableColumns = getAllColumns();
 		TableColumnCore[] tmpColumnsOrdered = new TableColumnCore[tableColumns.length];
 		//Create all columns
 		int columnOrderPos = 0;
@@ -1821,15 +914,16 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		for (int i = 0; i < tableColumns.length; i++) {
 			int position = tableColumns[i].getPosition();
 			if (position != -1 && tableColumns[i].isVisible()) {
-				new TableColumn(table, SWT.NULL);
+				table.createNewColumn(SWT.NULL);
 				//System.out.println(i + "] " + tableColumns[i].getName() + ";" + position);
 				tmpColumnsOrdered[columnOrderPos++] = tableColumns[i];
 			}
 		}
 		int numSWTColumns = table.getColumnCount();
 		int iNewLength = numSWTColumns - (bSkipFirstColumn ? 1 : 0);
-		columnsOrdered = new TableColumnCore[iNewLength];
+		TableColumnCore[] columnsOrdered = new TableColumnCore[iNewLength];
 		System.arraycopy(tmpColumnsOrdered, 0, columnsOrdered, 0, iNewLength);
+		setColumnsOrdered(columnsOrdered);
 		columnsVisible = new boolean[tableColumns.length];
 
 		ColumnSelectionListener columnSelectionListener = new ColumnSelectionListener();
@@ -1839,14 +933,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		//may not be in the natural order (if the user re-order the columns).
 		int swtColumnPos = (bSkipFirstColumn ? 1 : 0);
 		for (int i = 0; i < tableColumns.length; i++) {
-			int position = tableColumns[i].getPosition();
-			if (position == -1 || !tableColumns[i].isVisible()) {
+			TableColumnCore columnCore = tableColumns[i];
+			int position = columnCore.getPosition();
+			if (position == -1 || !columnCore.isVisible()) {
 				continue;
 			}
 
-			columnsVisible[i] = true;
+			columnsVisible[i] = false;
 
-			String sName = tableColumns[i].getName();
+			String sName = columnCore.getName();
 			// +1 for Eclipse Bug 43910 (see above)
 			// user has reported a problem here with index-out-of-bounds - not sure why
 			// but putting in a preventative check so that hopefully the view still opens
@@ -1858,26 +953,32 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				continue;
 			}
 
-			TableColumn column = table.getColumn(swtColumnPos);
+			TableColumnOrTreeColumn column = table.getColumn(swtColumnPos);
 			try {
 				column.setMoveable(true);
 			} catch (NoSuchMethodError e) {
 				// Ignore < SWT 3.1
 			}
-			column.setAlignment(TableColumnSWTUtils.convertColumnAlignmentToSWT(tableColumns[i].getAlignment()));
-			Messages.setLanguageText(column, tableColumns[i].getTitleLanguageKey());
-			if (!Constants.isUnix) {
-				column.setWidth(tableColumns[i].getWidth());
+			column.setAlignment(TableColumnSWTUtils.convertColumnAlignmentToSWT(columnCore.getAlignment()));
+			String iconReference = columnCore.getIconReference();
+			if (iconReference != null) {
+				Image image = ImageLoader.getInstance().getImage(iconReference);
+				column.setImage(image);
+			} else {
+				Messages.setLanguageText(column.getColumn(), columnCore.getTitleLanguageKey());
+			}
+			if (!Constants.isUnix && !Utils.isCarbon) {
+				column.setWidth(columnCore.getWidth());
 			} else {
 				column.setData("widthOffset", new Long(1));
-				column.setWidth(tableColumns[i].getWidth() + 1);
+				column.setWidth(columnCore.getWidth() + 1);
 			}
-			if (tableColumns[i].getMinWidth() == tableColumns[i].getMaxWidth()
-					&& tableColumns[i].getMinWidth() > 0) {
+			if (columnCore.getMinWidth() == columnCore.getMaxWidth()
+					&& columnCore.getMinWidth() > 0) {
 				column.setResizable(false);
 			}
-			column.setData("TableColumnCore", tableColumns[i]);
-			column.setData("configName", "Table." + sTableID + "." + sName);
+			column.setData("TableColumnCore", columnCore);
+			column.setData("configName", "Table." + tableID + "." + sName);
 			column.setData("Name", sName);
 
 			column.addControlListener(resizeListener);
@@ -1892,24 +993,24 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		// Initialize the sorter after the columns have been added
 		TableColumnManager tcManager = TableColumnManager.getInstance();
 
-		String sSortColumn = tcManager.getDefaultSortColumnName(sTableID);
+		String sSortColumn = tcManager.getDefaultSortColumnName(tableID);
 		if (sSortColumn == null || sSortColumn.length() == 0) {
 			sSortColumn = sDefaultSortOn;
 		}
 
-		TableColumnCore tc = tcManager.getTableColumnCore(sTableID, sSortColumn);
+		TableColumnCore tc = tcManager.getTableColumnCore(tableID, sSortColumn);
 		if (tc == null && tableColumns.length > 0) {
 			tc = tableColumns[0];
 		}
-		sortColumn = tc;
+		setSortColumn(tc, false);
 		fixAlignment(tc, true);
-		changeColumnIndicator();
+		swt_changeColumnIndicator();
 
 		// Add move listener at the very end, so we don't get a bazillion useless 
 		// move triggers
-		TableColumn[] columns = table.getColumns();
+		TableColumnOrTreeColumn[] columns = table.getColumns();
 		for (int i = 0; i < columns.length; i++) {
-			TableColumn column = columns[i];
+			TableColumnOrTreeColumn column = columns[i];
 			column.addListener(SWT.Move, columnMoveListener);
 		}
 
@@ -1926,7 +1027,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			if (i < 0 || i >= columnOrder.length) {
 				return;
 			}
-			TableColumn swtColumn = table.getColumn(columnOrder[i]);
+			TableColumnOrTreeColumn swtColumn = table.getColumn(columnOrder[i]);
 			if (swtColumn != null) {
 				if (swtColumn.getAlignment() == SWT.RIGHT && sorted) {
 					swtColumn.setText("   " + swtColumn.getText() + "   ");
@@ -1942,275 +1043,54 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 *
 	 * @return a new Menu object
 	 */
-	private Menu createMenu(final Table table) {
+	private Menu createMenu(final TableOrTreeSWT table) {
 		if (!isMenuEnabled()) {
 			return null;
 		}
 		
-		final Menu menu = new Menu(tableComposite.getShell(), SWT.POP_UP);
+		final Menu menu = new Menu(shell, SWT.POP_UP);
 		table.addListener(SWT.MenuDetect, new Listener() {
 			public void handleEvent(Event event) {
-				Point pt = event.display.map(null, table, new Point(event.x, event.y));
+				Point pt = event.display.map(null, table.getComposite(), new Point(event.x, event.y));
+				boolean noRow = table.getItem(pt) == null;
+
 				Rectangle clientArea = table.getClientArea();
-				boolean header = clientArea.y <= pt.y && pt.y < (clientArea.y + table.getHeaderHeight());
-				// give clicks on blank rows a header menu.
-				header |= table.getItem(pt) == null;
+				boolean inHeader = clientArea.y <= pt.y && pt.y < (clientArea.y + headerHeight);
+				if (!noRow) {
+					noRow = inHeader;
+				}
 				
-				menu.setData("isHeader", new Boolean(header));
+				menu.setData("inBlankArea", (!inHeader && noRow));
 
-				int columnNo = getColumnNo(pt.x);
-				menu.setData("column", columnNo < 0
-						|| columnNo >= table.getColumnCount() ? null
-						: table.getColumn(columnNo)); 
+				menu.setData("isHeader", new Boolean(noRow));
+
+				menu.setData("column",getTableColumnByOffset(event.x)); 
 			}
 		});
 		MenuBuildUtils.addMaintenanceListenerForMenu(menu,
 				new MenuBuildUtils.MenuBuilder() {
 					public void buildMenu(Menu menu, MenuEvent menuEvent) {
 						Object oIsHeader = menu.getData("isHeader");
-						boolean isHeader = (oIsHeader instanceof Boolean) ? ((Boolean)oIsHeader).booleanValue() : false;
+						boolean isHeader = (oIsHeader instanceof Boolean)
+								? ((Boolean) oIsHeader).booleanValue() : false;
+						Object oInBlankArea = menu.getData("inBlankArea");
+						boolean inBlankArea = (oInBlankArea instanceof Boolean)
+								? ((Boolean) oInBlankArea).booleanValue() : false;
 
-						TableColumn tcColumn = (TableColumn) menu.getData("column");
-						
-						if (!isHeader) {
-							fillMenu(menu, tcColumn);
+						TableColumnCore column = (TableColumnCore) menu.getData("column");
+
+						if (isHeader) {
+							tvSWTCommon.fillColumnMenu(menu, column, inBlankArea);
 						} else {
-							fillColumnMenu(tcColumn);
+							tvSWTCommon.fillMenu(menu, column);
 						}
-					}
-				});
-
-		return menu;
-	}
 
-	/** Fill the Context Menu with items.  Called when menu is about to be shown.
-	 *
-	 * By default, a "Edit Columns" menu and a Column specific menu is set up.
-	 *
-	 * @param menu Menu to fill
-	 * @param tcColumn 
-	 */
-	public void fillMenu(final Menu menu, final TableColumn tcColumn) {
-		String columnName = tcColumn == null ? null : (String) tcColumn.getData("Name");
-
-		Object[] listeners = listenersMenuFill.toArray();
-		for (int i = 0; i < listeners.length; i++) {
-			TableViewSWTMenuFillListener l = (TableViewSWTMenuFillListener) listeners[i];
-			l.fillMenu(columnName, menu);
-		}
-		// Add Plugin Context menus..
-		boolean enable_items = table != null && table.getSelection().length > 0;
-
-		TableContextMenuItem[] items = TableContextMenuManager.getInstance().getAllAsArray(
-				sTableID);
-
-		// We'll add download-context specific menu items - if the table is download specific.
-		// We need a better way to determine this...
-		org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items = null;
-		if ("MySeeders".equals(sTableID) || "MyTorrents".equals(sTableID)) {
-			menu_items = MenuItemManager.getInstance().getAllAsArray(
-					"download_context");
-		} else {
-			menu_items = MenuItemManager.getInstance().getAllAsArray((String) null);
-		}
-		
-		MenuItem item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.toClipboard");
-		item.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				String sToClipboard = "";
-				if (tcColumn == null) {
-					return;
-				}
-				String columnName = (String) tcColumn.getData("Name");
-				if (columnName == null) {
-					return;
-				}
-				TableItem[] tis = table.getSelection();
-				for (int i = 0; i < tis.length; i++) {
-					if (i != 0) {
-						sToClipboard += "\n";
-					}
-					TableRowCore row = (TableRowCore) tis[i].getData("TableRow");
-					TableCellCore cell = row.getTableCellCore(columnName);
-					if (cell != null) {
-						sToClipboard += cell.getText();
 					}
-				}
-				if (sToClipboard.length() == 0) {
-					return;
-				}
-				new Clipboard(mainComposite.getDisplay()).setContents(new Object[] {
-					sToClipboard
-				}, new Transfer[] {
-					TextTransfer.getInstance()
 				});
-			}
-		});
-		
-		if (items.length > 0 || menu_items.length > 0) {
-			new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR);
-
-			// Add download context menu items.
-			if (menu_items != null) {
-				// getSelectedDataSources(false) returns us plugin items.
-				MenuBuildUtils.addPluginMenuItems(getComposite(), menu_items, menu,
-						true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
-								getSelectedDataSources(false)));
-			}
-
-			if (items.length > 0) {
-				MenuBuildUtils.addPluginMenuItems(getComposite(), items, menu, true,
-						enable_items, new MenuBuildUtils.PluginMenuController() {
-							public Listener makeSelectionListener(
-									final org.gudy.azureus2.plugins.ui.menus.MenuItem plugin_menu_item) {
-								return new TableSelectedRowsListener(TableViewSWTImpl.this) {
-									public boolean run(TableRowCore[] rows) {
-										if (rows.length != 0) {
-											((TableContextMenuItemImpl) plugin_menu_item).invokeListenersMulti(rows);
-										}
-										return true;
-									}
-								};
-							}
-
-							public void notifyFillListeners(
-									org.gudy.azureus2.plugins.ui.menus.MenuItem menu_item) {
-								((TableContextMenuItemImpl) menu_item).invokeMenuWillBeShownListeners(getSelectedRows());
-							}
-						});
-			}
-		}
-		
-		// Add Plugin Context menus..
-		if (tcColumn != null) {
-  		TableColumnCore tc = (TableColumnCore) tcColumn.getData("TableColumnCore");
-  		TableContextMenuItem[] columnItems = tc.getContextMenuItems(TableColumnCore.MENU_STYLE_COLUMN_DATA);
-  		if (columnItems.length > 0) {
-  			new MenuItem(menu, SWT.SEPARATOR);
-  
-  			MenuBuildUtils.addPluginMenuItems(getComposite(), columnItems, menu,
-  					true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
-  							getSelectedDataSources(true)));
-  
-  		}
-		}
-
-		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() {
-		TableRowCore focusedRow = getFocusedRow();
-		if (focusedRow == null) {
-			focusedRow = getRow(0);
-		}
-		new TableColumnSetupWindow(classPluginDataSourceType, sTableID, focusedRow,
-				TableStructureEventDispatcher.getInstance(sTableID)).open();
+		return menu;
 	}
 
-	/**
-	 * SubMenu for column specific tasks. 
-	 *
-	 * @param iColumn Column # that tasks apply to.
-	 */
-	private void fillColumnMenu(final TableColumn tcColumn) {
-		
-		final MenuItem itemChangeTable = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(itemChangeTable,
-				"MyTorrentsView.menu.editTableColumns");
-		Utils.setMenuItemImage(itemChangeTable, "columns");
-
-		itemChangeTable.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				showColumnEditor();
-			}
-		});
-
-		if (menu != null) {
-			menu.setData("column", tcColumn);
-		}
-		
-		if (tcColumn == null) {
-			return;
-		}
-
-		String sColumnName = (String) tcColumn.getData("Name");
-		if (sColumnName != null) {
-			Object[] listeners = listenersMenuFill.toArray();
-			for (int i = 0; i < listeners.length; i++) {
-				TableViewSWTMenuFillListener l = (TableViewSWTMenuFillListener) listeners[i];
-				l.addThisColumnSubMenu(sColumnName, menu);
-			}
-		}
-
-		if (menu.getItemCount() > 0) {
-			new MenuItem(menu, SWT.SEPARATOR);
-		}
-
-		MenuItem item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.sort");
-		item.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				tcColumn.notifyListeners(SWT.Selection, new Event());
-			}
-		});
-
-		final MenuItem at_item = new MenuItem(menu, SWT.CHECK);
-		Messages.setLanguageText(at_item,
-				"MyTorrentsView.menu.thisColumn.autoTooltip");
-		at_item.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				TableColumn tc = (TableColumn) menu.getData("column");
-				TableColumnCore tcc = (TableColumnCore) tc.getData("TableColumnCore");
-				tcc.setAutoTooltip(at_item.getSelection());
-				tcc.invalidateCells();
-			}
-		});
-		at_item.setSelection(((TableColumnCore) tcColumn.getData("TableColumnCore")).doesAutoTooltip());
-
-		item = new MenuItem(menu, SWT.PUSH);
-		Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.remove");
-
-		item.addListener(SWT.Selection, new Listener() {
-			public void handleEvent(Event e) {
-				TableColumn tc = (TableColumn) menu.getData("column");
-				if (tc == null) {
-					return;
-				}
-				String columnName = (String) tcColumn.getData("Name");
-				if (columnName == null) {
-					return;
-				}
-				for (int i = 0; i < tableColumns.length; i++) {
-					if (tableColumns[i].getName().equals(columnName)) {
-						tableColumns[i].setVisible(false);
-					}
-				}
-
-				tableStructureChanged(false, null);
-			}
-		});
-
-		// Add Plugin Context menus..
-		TableColumnCore tc = (TableColumnCore) tcColumn.getData("TableColumnCore");
-		TableContextMenuItem[] items = tc.getContextMenuItems(TableColumnCore.MENU_STYLE_HEADER);
-		if (items.length > 0) {
-			new MenuItem(menu, SWT.SEPARATOR);
-
-			MenuBuildUtils.addPluginMenuItems(getComposite(), items, menu,
-					true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
-							getSelectedDataSources(true)));
-
-		}
-	}
 
 	/** IView.getComposite()
 	 * @return the composite for this TableView
@@ -2222,45 +1102,27 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	public Composite getTableComposite() {
 		return tableComposite;
 	}
-
-	public IView getActiveSubView() {
-		if (!bEnableTabViews || tabFolder == null || tabFolder.isDisposed()
-				|| tabFolder.getMinimized()) {
-			return null;
-		}
-
-		CTabItem item = tabFolder.getSelection();
-		if (item != null) {
-			return (IView) item.getData("IView");
-		}
-
-		return null;
-	}
-
-	public void refreshSelectedSubView() {
-		IView view = getActiveSubView();
-		if (view != null && view.getComposite().isVisible()) {
-			view.refresh();
-		}
+	
+	public TableOrTreeSWT getTableOrTreeSWT() {
+		return table;
 	}
 
 	// see common.TableView
 	public void refreshTable(final boolean bForceSort) {
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
-				_refreshTable(bForceSort);
+				swt_refreshTable(bForceSort);
 
-				if (bEnableTabViews && tabFolder != null && !tabFolder.isDisposed()
-						&& !tabFolder.getMinimized()) {
-					refreshSelectedSubView();
+				if (tvTabsCommon != null) {
+					tvTabsCommon.swt_refresh();
 				}
 			}
 		});
 
-		triggerTableRefreshListeners();
+		super.refreshTable(bForceSort);
 	}
 
-	private void _refreshTable(boolean bForceSort) {
+	private void swt_refreshTable(boolean bForceSort) {
 		// don't refresh while there's no table
 		if (table == null) {
 			return;
@@ -2278,7 +1140,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			}
 
 			if (columnVisibilitiesChanged == true) {
-				updateColumnVisibilities();
+				swt_updateColumnVisibilities(true);
 			}
 
 			final boolean bDoGraphics = (loopFactor % graphicsUpdate) == 0;
@@ -2287,7 +1149,9 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			//System.out.println("Refresh.. WillSort? " + bWillSort);
 
 			if (bWillSort) {
+				TableColumnCore sortColumn = getSortColumn();
 				if (bForceSort && sortColumn != null) {
+					resetLastSortedOn();
 					sortColumn.setLastSortValueChange(SystemTime.getCurrentTime());
 				}
 				_sortColumn(true, false, false);
@@ -2295,14 +1159,18 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 			long lTimeStart = SystemTime.getMonotonousTime();
 
-			//Refresh all visible items in table...
-			runForAllRows(new TableGroupRowVisibilityRunner() {
-				public void run(TableRowCore row, boolean bVisible) {
-					row.refresh(bDoGraphics, bVisible);
+			Utils.getOffOfSWTThread(new AERunnable() {
+				public void runSupport() {
+					//Refresh all visible items in table...
+					runForAllRows(new TableGroupRowVisibilityRunner() {
+						public void run(TableRowCore row, boolean bVisible) {
+							row.refresh(bDoGraphics, bVisible);
+						}
+					});
 				}
 			});
 
-			if (DEBUGADDREMOVE) {
+			if (TableViewImpl.DEBUGADDREMOVE) {
 				long lTimeDiff = (SystemTime.getMonotonousTime() - lTimeStart);
 				if (lTimeDiff > 500) {
 					debug(lTimeDiff + "ms to refresh rows");
@@ -2314,57 +1182,18 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	private void refreshVisibleRows() {
+	private void swt_refreshVisibleRows() {
 		if (getComposite() == null || getComposite().isDisposed()) {
 			return;
 		}
 
-		runForVisibleRows(new TableGroupRowRunner() {
+		swt_runForVisibleRows(new TableGroupRowRunner() {
 			public void run(TableRowCore row) {
 				row.refresh(false, true);
 			}
 		});
 	}
 
-	// see common.TableView
-	public void processDataSourceQueue() {
-		Object[] dataSourcesAdd = null;
-		Object[] dataSourcesRemove = null;
-
-		try {
-			dataSourceToRow_mon.enter();
-			if (dataSourcesToAdd.size() > 0) {
-				if (dataSourcesToAdd.removeAll(dataSourcesToRemove) && DEBUGADDREMOVE) {
-					debug("Saved time by not adding a row that was removed");
-				}
-				dataSourcesAdd = dataSourcesToAdd.toArray();
-
-				dataSourcesToAdd.clear();
-			}
-
-			if (dataSourcesToRemove.size() > 0) {
-				dataSourcesRemove = dataSourcesToRemove.toArray();
-				if (DEBUGADDREMOVE && dataSourcesRemove.length > 1) {
-					debug("Streamlining removing " + dataSourcesRemove.length + " rows");
-				}
-				dataSourcesToRemove.clear();
-			}
-		} finally {
-			dataSourceToRow_mon.exit();
-		}
-
-		if (dataSourcesAdd != null && dataSourcesAdd.length > 0) {
-			reallyAddDataSources(dataSourcesAdd);
-			if (DEBUGADDREMOVE && dataSourcesAdd.length > 1) {
-				debug("Streamlined adding " + dataSourcesAdd.length + " rows");
-			}
-		}
-
-		if (dataSourcesRemove != null && dataSourcesRemove.length > 0) {
-			reallyRemoveDataSources(dataSourcesRemove);
-		}
-	}
-
 	private void locationChanged(final int iStartColumn) {
 		if (getComposite() == null || getComposite().isDisposed()) {
 			return;
@@ -2379,12 +1208,13 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		});
 	}
 
+	/*
 	private void doPaint(final GC gc, final Rectangle dirtyArea) {
 		if (getComposite() == null || getComposite().isDisposed()) {
 			return;
 		}
 
-		runForVisibleRows(new TableGroupRowRunner() {
+		swt_runForVisibleRows(new TableGroupRowRunner() {
 			public void run(TableRowCore row) {
 				if (!(row instanceof TableRowSWT)) {
 					return;
@@ -2414,6 +1244,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			}
 		});
 	}
+	*/
 
 	/** IView.delete: This method is called when the view is destroyed.
 	 * Each color instanciated, images and such things should be disposed.
@@ -2422,19 +1253,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	public void delete() {
 		triggerLifeCycleListener(TableLifeCycleListener.EVENT_DESTROYED);
 
-		if (tabViews != null && tabViews.size() > 0) {
-			for (int i = 0; i < tabViews.size(); i++) {
-				IView view = tabViews.get(i);
-				if (view != null) {
-					view.delete();
-				}
-			}
+		if (tvTabsCommon != null) {
+			tvTabsCommon.delete();
+			tvTabsCommon = null;
 		}
 
-		TableStructureEventDispatcher.getInstance(sTableID).removeListener(this);
+		TableStructureEventDispatcher.getInstance(tableID).removeListener(this);
 		TableColumnManager tcManager = TableColumnManager.getInstance();
 		if (tcManager != null) {
-			tcManager.saveTableColumns(classPluginDataSourceType, sTableID);
+			tcManager.saveTableColumns(getDataSourceType(), tableID);
 		}
 
 		if (table != null && !table.isDisposed()) {
@@ -2445,270 +1272,33 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		configMan.removeParameterListener("Graphics Update", this);
 		Colors.getInstance().removeColorsChangedListener(this);
 
-		processDataSourceQueueCallback = null;
+		super.delete();
 
 		//oldSelectedItems =  null;
 		Composite comp = getComposite();
 		if (comp != null && !comp.isDisposed()) {
 			comp.dispose();
 		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.gudy.azureus2.ui.swt.views.AbstractIView#updateLanguage()
-	 */
-	public void updateLanguage() {
-		if (tabViews != null && tabViews.size() > 0) {
-			for (int i = 0; i < tabViews.size(); i++) {
-				IView view = tabViews.get(i);
-				if (view != null) {
-					view.updateLanguage();
-				}
-			}
-		}
+		
+		MessageText.removeListener(this);
 	}
 
 	// 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();
+	private void addDataSourcesToSWT(final Object dataSources[], boolean async) {
 		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
-			});
-			return;
-		}
-
-		// In order to save time, we cache entries to be added and process them
-		// in a refresh cycle.  This is a huge benefit to tables that have
-		// many rows being added and removed in rapid succession
-
-		try {
-			dataSourceToRow_mon.enter();
-
-				boolean alreadyThere = dataSourcesToAdd.contains(dataSource);
-				if (alreadyThere) {
-					// added twice.. ensure it's not in the remove list
-					dataSourcesToRemove.remove(dataSource);
-					if (DEBUGADDREMOVE) {
-						debug("AddDS: Already There.  Total Queued: " + dataSourcesToAdd.size());
-					}
-				} else {
-					dataSourcesToAdd.add(dataSource);
-					if (DEBUGADDREMOVE) {
-						debug("Queued 1 dataSource to add.  Total Queued: " + dataSourcesToAdd.size());
-					}
-					refreshenProcessDataSourcesTimer();
-				}
-
-		} finally {
-
-			dataSourceToRow_mon.exit();
-		}
-	}
-
-	// 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;
-		}
-
-		// In order to save time, we cache entries to be added and process them
-		// in a refresh cycle.  This is a huge benefit to tables that have
-		// many rows being added and removed in rapid succession
-
-		try {
-			dataSourceToRow_mon.enter();
-
-			int count = 0;
-
-			for (int i = 0; i < dataSources.length; i++) {
-				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
-					dataSourcesToRemove.remove(dataSources[i]);
-				} else {
-					count++;
-					dataSourcesToAdd.add(dataSources[i]);
-				}
-			}
-
-			if (DEBUGADDREMOVE) {
-				debug("Queued " + count + " of " + dataSources.length
-						+ " dataSources to add.  Total Queued: " + dataSourcesToAdd.size());
-			}
-
-		} finally {
-
-			dataSourceToRow_mon.exit();
-		}
-
-		refreshenProcessDataSourcesTimer();
-	}
-
-	private void refreshenProcessDataSourcesTimer() {
-		if (bReallyAddingDataSources || processDataSourceQueueCallback == null) {
-			// when processDataSourceQueueCallback is null, we are disposing
-			return;
-		}
-
-		if (cellEditNotifier != null) {
-			cellEditNotifier.sourcesChanged();
-		}
-
-		boolean processQueueImmediately = Utils.addDataSourceAggregated(processDataSourceQueueCallback);
-
-		if (processQueueImmediately) {
-			processDataSourceQueue();
-		}
-	}
-
-	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;
-		}
-
-		bReallyAddingDataSources = true;
-		if (DEBUGADDREMOVE) {
-			debug(">>" + " Add " + dataSources.length + " rows;");
-		}
-
-		Object[] remainingDataSources = null;
-		Object[] doneDataSources = dataSources;
-
-		// Create row, and add to map immediately
-		try {
-			dataSourceToRow_mon.enter();
-
-			long lStartTime = SystemTime.getCurrentTime();
-
-			for (int i = 0; i < dataSources.length; i++) {
-				if (dataSources[i] == null) {
-					continue;
-				}
-
-				// Break off and add the rows to the UI if we've taken too long to
-				// create them
-				if (SystemTime.getCurrentTime() - lStartTime > BREAKOFF_ADDTOMAP) {
-					int iNewSize = dataSources.length - i;
-					if (DEBUGADDREMOVE) {
-						debug("Breaking off adding datasources to map after " + i
-								+ " took " + (SystemTime.getCurrentTime() - lStartTime)
-								+ "ms; # remaining: " + iNewSize);
-					}
-					remainingDataSources = new Object[iNewSize];
-					doneDataSources = new Object[i];
-					System.arraycopy(dataSources, i, remainingDataSources, 0, iNewSize);
-					System.arraycopy(dataSources, 0, doneDataSources, 0, i);
-					break;
-				}
-
-				if (mapDataSourceToRow.containsKey(dataSources[i])) {
-					dataSources[i] = null;
-				} else {
-					TableRowImpl row = new TableRowImpl(this, table, sTableID,
-							columnsOrdered, dataSources[i], bSkipFirstColumn);
-					mapDataSourceToRow.put((DATASOURCETYPE) dataSources[i], row);
-				}
-			}
-		} catch (Exception e) {
-			Logger.log(new LogEvent(LOGID, "Error while added row to Table "
-					+ sTableID, e));
-		} finally {
-			dataSourceToRow_mon.exit();
-		}
-
-		if (DEBUGADDREMOVE) {
-			debug("--" + " Add " + doneDataSources.length + " rows;");
-		}
-
-		if (remainingDataSources == null) {
-			addDataSourcesToSWT(doneDataSources, true);
-		} else {
-			final Object[] fDoneDataSources = doneDataSources;
-			final Object[] fRemainingDataSources = remainingDataSources;
-			// wrap both calls in a SWT thread so that continuation of adding 
-			// remaining datasources will be on SWT thread.  OSX has horrible handling
-			// of switching to SWT thread.
-			Utils.execSWTThread(new AERunnable() {
-				public void runSupport() {
-					addDataSourcesToSWT(fDoneDataSources, false);
-					reallyAddDataSources(fRemainingDataSources);
-				}
-			}, false);
-		}
-	}
-
-	private void addDataSourcesToSWT(final Object dataSources[], boolean async) {
-		try {
-			if (isDisposed()) {
-				return;
-			}
-			if (DEBUGADDREMOVE) {
-				debug("--" + " Add " + dataSources.length + " rows to SWT "
-						+ (async ? " async " : " NOW"));
-			}
+			if (isDisposed()) {
+				return;
+			}
+			if (DEBUGADDREMOVE) {
+				debug("--" + " Add " + dataSources.length + " rows to SWT "
+						+ (async ? " async " : " NOW"));
+			}
 
+			
 			if (async) {
-				table.getDisplay().asyncExec(new AERunnable() {
+				Utils.execSWTThreadLater(0, new AERunnable() {
 					public void runSupport() {
 						_addDataSourcesToSWT(dataSources);
 					}
@@ -2721,15 +1311,34 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				}, false);
 			}
 
+			for (int i = 0; i < dataSources.length; i++) {
+				Object dataSource = dataSources[i];
+				if (dataSource == null) {
+					continue;
+				}
+				TableRowCore row = getRow((DATASOURCETYPE) dataSource);
+				TableColumnCore sortColumn = getSortColumn();
+  			if (row != null && sortColumn != null) {
+  				TableCellCore cell = row.getSortColumnCell(sortColumn.getName());
+  				if (cell != null) {
+  					try {
+  						cell.invalidate();
+  						cell.refresh(true);
+  					} catch (Exception e) {
+  						Logger.log(new LogEvent(LOGID,
+  								"Minor error adding a row to table " + tableID, e));
+  					}
+  				}
+  			}
+			}
+
 		} catch (Exception e) {
-			bReallyAddingDataSources = false;
 			e.printStackTrace();
 		}
 	}
 
 	private void _addDataSourcesToSWT(final Object dataSources[]) {
 		if (table == null || table.isDisposed()) {
-			bReallyAddingDataSources = false;
 			return;
 		}
 
@@ -2737,168 +1346,32 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				table.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
 
 		TableRowCore[] selectedRows = getSelectedRows();
-
-		boolean bBrokeEarly = false;
-		boolean bReplacedVisible = false;
+			
 		boolean bWas0Rows = table.getItemCount() == 0;
 		try {
-			dataSourceToRow_mon.enter();
-			sortedRows_mon.enter();
 
 			if (DEBUGADDREMOVE) {
-				debug("--" + " Add " + dataSources.length + " rows to SWT");
+				debug("--" + " Add " + dataSources.length + " rows to SWT. size(false) == " + size(false));
 			}
 
 			// purposefully not included in time check 
-			table.setItemCount(sortedRows.size() + dataSources.length);
-
-			long lStartTime = SystemTime.getCurrentTime();
-
-			int iTopIndex = table.getTopIndex();
-			int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
+			int size = size(false);
+			// Bug in Windows (7).  If you add 10 rows by setItemCount,
+			// Windows will do some crappy shifting down of the non-row area
+			table.setItemCount(size);
 
-			// add to sortedRows list in best position.  
-			// We need to be in the SWT thread because the rowSorter may end up
-			// calling SWT objects.
-			for (int i = 0; i < dataSources.length; i++) {
-				Object dataSource = dataSources[i];
-				if (dataSource == null) {
-					continue;
-				}
-
-				// If we've been processing on the SWT thread for too long,
-				// break off and allow SWT a breather to update.
-				if (SystemTime.getCurrentTime() - lStartTime > BREAKOFF_ADDROWSTOSWT) {
-					int iNewSize = dataSources.length - i;
-					if (DEBUGADDREMOVE) {
-						debug("Breaking off adding datasources to SWT after " + i
-								+ " took " + (SystemTime.getCurrentTime() - lStartTime)
-								+ "ms; # remaining: " + iNewSize);
-					}
-					Object[] remainingDataSources = new Object[iNewSize];
-					System.arraycopy(dataSources, i, remainingDataSources, 0, iNewSize);
-					addDataSourcesToSWT(remainingDataSources, true);
-					bBrokeEarly = true;
-					break;
-				}
-
-				TableRowImpl row = (TableRowImpl) mapDataSourceToRow.get(dataSource);
-				if (row == null || row.getIndex() >= 0) {
-					continue;
-				}
-				if (sortColumn != null) {
-					TableCellSWT cell = row.getTableCellSWT(sortColumn.getName());
-					if (cell != null) {
-						try {
-							cell.invalidate();
-							cell.refresh(true);
-						} catch (Exception e) {
-							Logger.log(new LogEvent(LOGID,
-									"Minor error adding a row to table " + sTableID, e));
-						}
-					}
-				}
-
-				try {
-					int index = 0;
-					if (sortedRows.size() > 0) {
-						// If we are >= to the last item, then just add it to the end
-						// instead of relying on binarySearch, which may return an item
-						// in the middle that also is equal.
-						TableRowSWT lastRow = sortedRows.get(sortedRows.size() - 1);
-						if (sortColumn == null || sortColumn.compare(row, lastRow) >= 0) {
-							index = sortedRows.size();
-							sortedRows.add(row);
-							if (DEBUGADDREMOVE) {
-								debug("Adding new row to bottom");
-							}
-						} else {
-							index = Collections.binarySearch(sortedRows, row, sortColumn);
-							if (index < 0) {
-								index = -1 * index - 1; // best guess
-							}
-
-							if (index > sortedRows.size()) {
-								index = sortedRows.size();
-							}
-
-							if (DEBUGADDREMOVE) {
-								debug("Adding new row at position " + index + " of "
-										+ (sortedRows.size() - 1));
-							}
-							sortedRows.add(index, row);
-						}
-					} else {
-						if (DEBUGADDREMOVE) {
-							debug("Adding new row to bottom (1st Entry)");
-						}
-						index = sortedRows.size();
-						sortedRows.add(row);
-					}
-
-					// NOTE: if the listener tries to do something like setSelected,
-					// it will fail because we aren't done adding.
-					// we should trigger after fillRowGaps()
-					triggerListenerRowAdded(row);
-
-					if (!bReplacedVisible && index >= iTopIndex && index <= iBottomIndex) {
-						bReplacedVisible = true;
-					}
-
-					// XXX Don't set table item here, it will mess up selected rows
-					//     handling (which is handled in fillRowGaps called later on)
-					//row.setTableItem(index);
-					row.setIconSize(ptIconSize);
-				} catch (Exception e) {
-					Logger.log(new LogEvent(LOGID, "Error adding a row to table "
-							+ sTableID, e));
-					try {
-						if (!sortedRows.contains(row)) {
-							sortedRows.add(row);
-						}
-					} catch (Exception e2) {
-						Debug.out(e2);
-					}
-				}
-			} // for dataSources
-
-			if (DEBUGADDREMOVE) {
-				debug("Adding took " + (SystemTime.getCurrentTime() - lStartTime)
-						+ "ms");
-			}
-
-			// Sanity Check: Make sure # of rows in table and in array match
-			if (table.getItemCount() > sortedRows.size() && !bBrokeEarly) {
-				// This could happen if one of the datasources was null, or
-				// an error occured
-				table.setItemCount(sortedRows.size());
+			if (size == 1) {
+				columnVisibilitiesChanged = true;
 			}
 
 		} catch (Exception e) {
 			Logger.log(new LogEvent(LOGID, "Error while adding row to Table "
-					+ sTableID, e));
-		} finally {
-			sortedRows_mon.exit();
-			dataSourceToRow_mon.exit();
-
-			if (!bBrokeEarly) {
-				bReallyAddingDataSources = false;
-				refreshenProcessDataSourcesTimer();
-			}
-		}
-
-		if (!bBrokeEarly || bReplacedVisible) {
-			fillRowGaps(false);
-			if (bReplacedVisible) {
-				lastTopIndex = 0;
-				lastBottomIndex = -1;
-				visibleRowsChanged();
-			}
+					+ tableID, e));
 		}
 
 		if (!columnPaddingAdjusted && table.getItemCount() > 0 && bWas0Rows) {
-			TableColumn[] tableColumnsSWT = table.getColumns();
-			TableItem item = table.getItem(0);
+			TableColumnOrTreeColumn[] tableColumnsSWT = table.getColumns();
+			TableItemOrTreeItem item = table.getItem(0);
 			// on *nix, the last column expands to fill remaining space.. let's just not touch it
 			int len = Constants.isUnix ? tableColumnsSWT.length - 1
 					: tableColumnsSWT.length;
@@ -2920,283 +1393,108 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 						}
 					}
 					if (foundOne) {
-						tc.triggerColumnSizeChange();
+						tc.triggerColumnSizeChange(0);
 					}
 				}
 			}
 			columnPaddingAdjusted = true;
+		} 
+		if (bWas0Rows) {
+			swt_updateColumnVisibilities(false);
 		}
 
 		setSelectedRows(selectedRows);
 		if (DEBUGADDREMOVE) {
-			debug("<< " + sortedRows.size());
-		}
-
-		mainComposite.getParent().setCursor(null);
-	}
-
-	// @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;
+			debug("<< " + size(false));
 		}
 
-		try {
-			dataSourceToRow_mon.enter();
-
-			dataSourcesToRemove.add(dataSource);
-
-			if (DEBUGADDREMOVE) {
-				debug("Queued 1 dataSource to remove.  Total Queued: " + dataSourcesToRemove.size());
+		boolean bReplacedVisible = false;
+		for (Object ds : dataSources) {
+			TableRowCore row = getRow((DATASOURCETYPE) ds);
+			if (row != null) {
+				int i = indexOf(row);
+				int iTopIndex = uiGetTopIndex();
+				int iBottomIndex = uiGetBottomIndex(iTopIndex);
+				if (i >= iTopIndex && i <= iBottomIndex) {
+					bReplacedVisible = true;
+					break;
+				}
 			}
-		} finally {
-			dataSourceToRow_mon.exit();
-		}
-
-		refreshenProcessDataSourcesTimer();
-	}
-
-	/** Remove the specified dataSource from the table.
-	 *
-	 * @param dataSources data sources to be removed
-	 * @param bImmediate Remove immediately, or queue and remove at next refresh
-	 */
-	public void removeDataSources(final DATASOURCETYPE[] dataSources) {
-		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;
 		}
-
-		try {
-			dataSourceToRow_mon.enter();
-
-			for (int i = 0; i < dataSources.length; i++) {
-				dataSourcesToRemove.add(dataSources[i]);
-			}
-
-			if (DEBUGADDREMOVE) {
-				debug("Queued " + dataSources.length
-						+ " dataSources to remove.  Total Queued: "
-						+ dataSourcesToRemove.size());
-			}
-		} finally {
-			dataSourceToRow_mon.exit();
+		if (bReplacedVisible) {
+			visibleRowsChanged();
 		}
-
-		refreshenProcessDataSourcesTimer();
+		
+		mainComposite.getParent().setCursor(null);
 	}
+	
+	@Override
+	public void reallyAddDataSources(Object[] dataSources) {
+		super.reallyAddDataSources(dataSources);
 
-	private void reallyRemoveDataSources(final Object[] dataSources) {
-
-		if (DEBUGADDREMOVE) {
-			debug(">> Remove rows");
-		}
-
-		final long lStart = SystemTime.getCurrentTime();
+		addDataSourcesToSWT(dataSources, true);
+	}
 
-		boolean ok = Utils.execSWTThread(new AERunnable() {
+	@Override
+	public void uiRemoveRows(TableRowCore[] rows, final Integer[] rowIndexes) {
+		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
 				if (table == null || table.isDisposed()) {
 					return;
 				}
 
-				int numSelected = table.getSelectionCount();
-
+				//TableRowCore[] oldSelectedRows = getSelectedRows();
+				
 				mainComposite.getParent().setCursor(
 						table.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
 
-				StringBuffer sbWillRemove = null;
-				if (DEBUGADDREMOVE) {
-					debug(">>> Remove rows.  Start w/" + mapDataSourceToRow.size()
-							+ "ds; tc=" + table.getItemCount() + ";"
-							+ (SystemTime.getCurrentTime() - lStart) + "ms wait");
-
-					sbWillRemove = new StringBuffer("Will soon remove row #");
-				}
-
-				ArrayList<TableRowSWT> itemsToRemove = new ArrayList<TableRowSWT>();
-				ArrayList<Long> swtItemsToRemove = new ArrayList<Long>();
-				int iTopIndex = table.getTopIndex();
-				int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-				boolean bRefresh = false;
-
-				if (DEBUGADDREMOVE) {
-					debug("--- Remove: vis rows " + iTopIndex + " to " + iBottomIndex);
-				}
-
-				// pass one: get the SWT indexes of the items we are going to remove
-				//           This will re-link them if they lost their link
-				for (int i = 0; i < dataSources.length; i++) {
-					if (dataSources[i] == null) {
-						continue;
-					}
-
-					TableRowSWT item = (TableRowSWT) mapDataSourceToRow.get(dataSources[i]);
-					if (item != null) {
-						// use sortedRows position instead of item.getIndex(), because
-						// getIndex may have a wrong value (unless we fillRowGaps() which
-						// is more time consuming and we do afterwards anyway)
-						int index = sortedRows.indexOf(item);
-						if (!bRefresh) {
-							bRefresh = index >= iTopIndex && index <= iBottomIndex;
-						}
-						if (DEBUGADDREMOVE) {
-							if (i != 0) {
-								sbWillRemove.append(", ");
-							}
-							sbWillRemove.append(index);
-						}
-						if (index >= 0) {
-							swtItemsToRemove.add(new Long(index));
-						}
-					}
-				}
-
-				if (DEBUGADDREMOVE) {
-					debug(sbWillRemove.toString());
-					debug("#swtItemsToRemove=" + swtItemsToRemove.size());
-				}
-
-				boolean hasSelected = false;
-				// pass 2: remove from map and list, add removed to seperate list
-				for (int i = 0; i < dataSources.length; i++) {
-					if (dataSources[i] == null) {
-						continue;
+				try {
+					int iTopIndex = uiGetTopIndex();
+					int iBottomIndex = uiGetBottomIndex(iTopIndex);
+					if (DEBUGADDREMOVE) {
+						debug("--- Remove: vis rows " + iTopIndex + " to " + iBottomIndex);
 					}
-
-					// Must remove from map before deleted from gui
-					TableRowSWT item = (TableRowSWT) mapDataSourceToRow.remove(dataSources[i]);
-					if (item != null) {
-						if (item.isSelected()) {
-							hasSelected = true;
+					
+					boolean needRefresh = false;
+					for (Integer i : rowIndexes) {
+						if (i >= iTopIndex && i <= iBottomIndex) {
+							needRefresh = true;
+							break;
 						}
-						itemsToRemove.add(item);
-						sortedRows.remove(item);
-						triggerListenerRowRemoved(item);
 					}
-				}
-
-				if (DEBUGADDREMOVE) {
-					debug("-- Removed from map and list");
-				}
-				// Remove the rows from SWT first.  On SWT 3.2, this currently has 
-				// zero perf gain, and a small perf gain on Windows.  However, in the
-				// future it may be optimized.
-				if (swtItemsToRemove.size() > 0) {
-					//					int[] swtRowsToRemove = new int[swtItemsToRemove.size()];
-					//					for (int i = 0; i < swtItemsToRemove.size(); i++) {
-					//						swtRowsToRemove[i] = ((Long) swtItemsToRemove.get(i)).intValue();
-					//					}
-					//					table.remove(swtRowsToRemove);
-					// refreshVisibleRows should fix up the display
-					table.setItemCount(mapDataSourceToRow.size());
-				}
-
-				if (DEBUGADDREMOVE) {
-					debug("-- Removed from SWT");
-				}
-
-				// Finally, delete the rows
-				for (Iterator<TableRowSWT> iter = itemsToRemove.iterator(); iter.hasNext();) {
-					TableRowCore row = iter.next();
-					row.delete();
-				}
 
-				if (bRefresh) {
+					table.setItemCount(getRowCount());
 					fillRowGaps(false);
-					refreshVisibleRows();
-					if (DEBUGADDREMOVE) {
-						debug("-- Fill row gaps and refresh after remove");
+					
+					if (needRefresh || iBottomIndex == table.getItemCount() - 1) {
+						table.redraw();
 					}
-				}
-
-				if (DEBUGADDREMOVE) {
-					debug("<< Remove " + itemsToRemove.size() + " rows. now "
-							+ mapDataSourceToRow.size() + "ds; tc=" + table.getItemCount());
-				}
-				mainComposite.getParent().setCursor(null);
-
-				if (numSelected != table.getSelectionCount()) {
-					triggerDeselectionListeners(new TableRowCore[0]);
-				}
-				if (hasSelected) {
-					updateSelectedRowIndexes();
-					triggerSelectionListeners(getSelectedRows());
+				} finally {
+					mainComposite.getParent().setCursor(null);
+					
 				}
 			}
 		});
-
-		if (!ok) {
-			// execRunnable will only fail if we are closing
-			for (int i = 0; i < dataSources.length; i++) {
-				if (dataSources[i] == null) {
-					continue;
-				}
-
-				TableRowSWT item = (TableRowSWT) mapDataSourceToRow.get(dataSources[i]);
-				mapDataSourceToRow.remove(dataSources[i]);
-				if (item != null) {
-					sortedRows.remove(item);
-				}
-			}
-
-			if (DEBUGADDREMOVE) {
-				debug("<< Remove row(s), noswt");
-			}
-		}
+		
 	}
-
+	
 	// from common.TableView
 	public void removeAllTableRows() {
+
 		long lTimeStart = System.currentTimeMillis();
 
 		final TableRowCore[] rows = getRows();
 
-		try {
-			dataSourceToRow_mon.enter();
-			sortedRows_mon.enter();
-
-			mapDataSourceToRow.clear();
-			sortedRows.clear();
-
-			dataSourcesToAdd.clear();
-			dataSourcesToRemove.clear();
-
-			if (DEBUGADDREMOVE) {
-				debug("removeAll");
-			}
 
-		} finally {
+		super.removeAllTableRows();
 
-			sortedRows_mon.exit();
-			dataSourceToRow_mon.exit();
-		}
 
 		Utils.execSWTThread(new AERunnable() {
 			public void runSupport() {
+				if (DEBUGADDREMOVE) {
+					debug("removeAll (SWT)");
+				}
+
 				if (table != null && !table.isDisposed()) {
 					table.removeAll();
 				}
@@ -3217,11 +1515,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#getTableID()
-	public String getTableID() {
-		return sTableID;
-	}
-
 	/* ParameterListener Implementation */
 
 	public void parameterChanged(String parameterName) {
@@ -3236,11 +1529,14 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// ITableStructureModificationListener
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#tableStructureChanged(boolean, java.lang.Class)
+	 */
 	public void tableStructureChanged(final boolean columnAddedOrRemoved,
 			Class forPluginDataSourceType) {
 		if (forPluginDataSourceType == null
-				|| forPluginDataSourceType.equals(classPluginDataSourceType)) {
+				|| forPluginDataSourceType.equals(getDataSourceType())) {
+			super.tableStructureChanged(columnAddedOrRemoved, forPluginDataSourceType);
 			Utils.execSWTThread(new AERunnable() {
 				public void runSupport() {
 					if (table.isDisposed()) {
@@ -3253,46 +1549,53 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	}
 	
 	private void _tableStructureChanged(boolean columnAddedOrRemoved) {
-		triggerLifeCycleListener(TableLifeCycleListener.EVENT_DESTROYED);
-
-		removeAllTableRows();
-
-		if (columnAddedOrRemoved) {
-			tableColumns = TableColumnManager.getInstance().getAllTableColumnCoreAsArray(
-					classPluginDataSourceType, sTableID);
-		}
 
-		initializeTableColumns(table);
+		swt_initializeTableColumns(table);
 		refreshTable(false);
 
 		triggerLifeCycleListener(TableLifeCycleListener.EVENT_INITIALIZED);
 	}
 
 	// ITableStructureModificationListener
-	public void columnOrderChanged(int[] positions) {
-		try {
-			table.setColumnOrder(positions);
-			updateColumnVisibilities();
-		} catch (NoSuchMethodError e) {
-			// Pre SWT 3.1
-			// This shouldn't really happen, since this function only gets triggered
-			// from SWT >= 3.1
-			tableStructureChanged(false, null);
-		}
+	public void columnOrderChanged(final int[] positions) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				try {
+					if (table.isDisposed()) {
+						return;
+					}
+					table.setColumnOrder(positions);
+					swt_updateColumnVisibilities(true);
+				} catch (NoSuchMethodError e) {
+					// Pre SWT 3.1
+					// This shouldn't really happen, since this function only gets triggered
+					// from SWT >= 3.1
+					tableStructureChanged(false, null);
+				}
+			}
+		});
 	}
 
 	/** 
 	 * The Columns width changed
 	 */
 	// ITableStructureModificationListener
-	public void columnSizeChanged(TableColumnCore tableColumn) {
+	public void columnSizeChanged(final TableColumnCore tableColumn, int diff) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_columnSizeChanged(tableColumn);
+			}
+		});
+	}
+
+	public void swt_columnSizeChanged(TableColumnCore tableColumn) {
 		int newWidth = tableColumn.getWidth();
 		if (table == null || table.isDisposed()) {
 			return;
 		}
 
-		TableColumn column = null;
-		TableColumn[] tableColumnsSWT = table.getColumns();
+		TableColumnOrTreeColumn column = null;
+		TableColumnOrTreeColumn[] tableColumnsSWT = table.getColumns();
 		for (int i = 0; i < tableColumnsSWT.length; i++) {
 			if (tableColumnsSWT[i].getData("TableColumnCore") == tableColumn) {
 				column = tableColumnsSWT[i];
@@ -3306,13 +1609,14 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		if (lOfs != null) {
 			newWidth += lOfs.intValue();
 		}
+		swt_refreshVisibleRows();
 		if (column.isDisposed() || (column.getWidth() == newWidth)) {
 			return;
 		}
 
 		if (Constants.isUnix) {
 			final int fNewWidth = newWidth;
-			final TableColumn fTableColumn = column;
+			final TableColumnOrTreeColumn fTableColumn = column;
 			column.getDisplay().asyncExec(new AERunnable() {
 				public void runSupport() {
 					if (!fTableColumn.isDisposed()) {
@@ -3325,24 +1629,11 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// ITableStructureModificationListener
-	// TableView
-	public void columnInvalidate(TableColumnCore tableColumn) {
-		// We are being called from a plugin (probably), so we must refresh
-		columnInvalidate(tableColumn, true);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableStructureModificationListener#cellInvalidate(com.aelitis.azureus.ui.common.table.TableColumnCore, java.lang.Object)
-	public void cellInvalidate(TableColumnCore tableColumn,
-			DATASOURCETYPE data_source) {
-		cellInvalidate(tableColumn, data_source, true);
-	}
-
 	public void columnRefresh(TableColumnCore tableColumn) {
 		final String sColumnName = tableColumn.getName();
 		runForAllRows(new TableGroupRowVisibilityRunner() {
 			public void run(TableRowCore row, boolean bVisible) {
-				TableCellSWT cell = ((TableRowSWT) row).getTableCellSWT(sColumnName);
+				TableCellCore cell = row.getTableCellCore(sColumnName);
 				if (cell != null) {
 					cell.refresh(true, bVisible);
 				}
@@ -3350,387 +1641,59 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		});
 	}
 
-	/**
-	 * Invalidate and refresh whole table
-	 */
-	public void tableInvalidate() {
-		runForAllRows(new TableGroupRowVisibilityRunner() {
-			public void run(TableRowCore row, boolean bVisible) {
-				row.invalidate();
-				row.refresh(true, bVisible);
-			}
-		});
-	}
-
-	// see common.TableView
-	public void columnInvalidate(final String sColumnName) {
-		TableColumnCore tc = TableColumnManager.getInstance().getTableColumnCore(
-				sTableID, sColumnName);
-		if (tc != null) {
-			columnInvalidate(tc, tc.getType() == TableColumnCore.TYPE_TEXT_ONLY);
-		}
-	}
-
-	public void columnInvalidate(TableColumnCore tableColumn,
-			final boolean bMustRefresh) {
-		final String sColumnName = tableColumn.getName();
-
-		runForAllRows(new TableGroupRowRunner() {
-			public void run(TableRowCore row) {
-				TableCellSWT cell = ((TableRowSWT) row).getTableCellSWT(sColumnName);
-				if (cell != null) {
-					cell.invalidate(bMustRefresh);
-				}
-			}
-		});
-	}
-
-	public void cellInvalidate(TableColumnCore tableColumn,
-			final DATASOURCETYPE data_source, final boolean bMustRefresh) {
-		final String sColumnName = tableColumn.getName();
-
-		runForAllRows(new TableGroupRowRunner() {
-			public void run(TableRowCore row) {
-				TableCellSWT cell = ((TableRowSWT) row).getTableCellSWT(sColumnName);
-				if (cell != null && cell.getDataSource() != null
-						&& cell.getDataSource().equals(data_source)) {
-					cell.invalidate(bMustRefresh);
-				}
-			}
-		});
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getColumnCells(java.lang.String)
-	public TableCellCore[] getColumnCells(String sColumnName) {
-		TableCellCore[] cells = new TableCellCore[sortedRows.size()];
-
-		try {
-			sortedRows_mon.enter();
-
-			int i = 0;
-			for (Iterator<TableRowSWT> iter = sortedRows.iterator(); iter.hasNext();) {
-				TableRowCore row = iter.next();
-				cells[i++] = row.getTableCellCore(sColumnName);
-			}
-
-		} finally {
-			sortedRows_mon.exit();
-		}
-
-		return cells;
-	}
-
-	public org.gudy.azureus2.plugins.ui.tables.TableColumn getTableColumn(
-			String sColumnName) {
-		for (int i = 0; i < tableColumns.length; i++) {
-			TableColumnCore tc = tableColumns[i];
-			if (tc.getName().equals(sColumnName)) {
-				return tc;
-			}
-		}
-		return null;
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getRows()
-	public TableRowCore[] getRows() {
-		try {
-			sortedRows_mon.enter();
 
-			return sortedRows.toArray(new TableRowCore[0]);
-
-		} finally {
-			sortedRows_mon.exit();
-		}
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getRow(java.lang.Object)
-	public TableRowCore getRow(DATASOURCETYPE dataSource) {
-		return mapDataSourceToRow.get(dataSource);
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getRowSWT(java.lang.Object)
-	public TableRowSWT getRowSWT(DATASOURCETYPE dataSource) {
-		return (TableRowSWT) mapDataSourceToRow.get(dataSource);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getRow(int)
-	public TableRowCore getRow(int iPos) {
-		try {
-			sortedRows_mon.enter();
-
-			if (iPos >= 0 && iPos < sortedRows.size()) {
-				TableRowCore row = sortedRows.get(iPos);
-
-				if (row.getIndex() != iPos) {
-					row.setTableItem(iPos);
-				}
-				return row;
-			}
-		} finally {
-			sortedRows_mon.exit();
-		}
-		return null;
-	}
-
-	protected TableRowCore getRowQuick(int iPos) {
-		try {
-			return sortedRows.get(iPos);
-		} catch (Exception e) {
+	/** Warning: this method may require SWT Thread! 
+	 * 
+	 * TODO: Make sure callers are okay with that
+	 */
+	protected TableRowCore getRow(TableItemOrTreeItem item) {
+		if (item == null) {
 			return null;
 		}
-	}
-
-	public int indexOf(TableRowCore row) {
-		int i = ((TableRowImpl) row).getRealIndex();
-		if (i == -1) {
-			i = sortedRows.indexOf(row);
-			if (i >= 0) {
-				row.setTableItem(i);
-			}
-		}
-		return i;
-	}
-
-	private TableRowCore getRow(TableItem item) {
 		try {
 			Object o = item.getData("TableRow");
-			if (o instanceof TableRowCore) {
+			if ((o instanceof TableRowCore) && !((TableRowCore) o).isRowDisposed()) {
 				return (TableRowCore) o;
-			} else {
-				int iPos = table.indexOf(item);
-				//System.out.println(iPos + " has no table row.. associating. " + Debug.getCompressedStackTrace(4));
-				if (iPos >= 0 && iPos < sortedRows.size()) {
-					TableRowSWT row = sortedRows.get(iPos);
-					//System.out.print(".. associating to " + row);
-					if (row != null) {
-						row.setTableItem(iPos);
-					}
-					//System.out.println(", now " + row);
-					return row;
-				}
 			}
-		} catch (Exception e) {
-			Debug.out(e);
-		}
-		return null;
-	}
 
-	public int getRowCount() {
-		// don't use sortedRows here, it's not always up to date 
-		return mapDataSourceToRow.size();
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getDataSources()
-	public ArrayList<DATASOURCETYPE> getDataSources() {
-		return new ArrayList<DATASOURCETYPE>(mapDataSourceToRow.keySet());
-	}
-
-	/* various selected rows functions */
-	/***********************************/
-
-	public List<DATASOURCETYPE> getSelectedDataSourcesList() {
-		if (listSelectedCoreDataSources != null) {
-			return listSelectedCoreDataSources;
-		}
-		if (table == null || table.isDisposed() || selectedRowIndexes == null
-				|| selectedRowIndexes.length == 0) {
-			return Collections.emptyList();
-		}
-
-		final ArrayList<DATASOURCETYPE> l = new ArrayList<DATASOURCETYPE>(
-				selectedRowIndexes.length);
-		for (int index : selectedRowIndexes) {
-			TableRowCore row = getRowQuick(index);
-			if (row != null) {
-				Object ds = row.getDataSource(true);
-				if (ds != null) {
-					l.add((DATASOURCETYPE) ds);
-				}
+			if (item.getParentItem() != null) {
+				TableRowCore row = getRow(item.getParentItem());
+				return row.linkSubItem(item.getParentItem().indexOf(item));
 			}
-		}
-		listSelectedCoreDataSources = l;
-		return l;
-	}
-
-	/** Returns an array of all selected Data Sources.  Null data sources are
-	 * ommitted.
-	 *
-	 * @return an array containing the selected data sources
-	 * 
-	 * @TODO TuxPaper: Virtual row not created when using getSelection?
-	 *                  computePossibleActions isn't being calculated right
-	 *                  because of non-created rows when select user selects all
-	 */
-	public List<Object> getSelectedPluginDataSourcesList() {
-		if (table == null || table.isDisposed() || selectedRowIndexes == null
-				|| selectedRowIndexes.length == 0) {
-			return Collections.emptyList();
-		}
-
-		final ArrayList<Object> l = new ArrayList<Object>(selectedRowIndexes.length);
-		for (int index : selectedRowIndexes) {
-			TableRowCore row = getRowQuick(index);
-			if (row != null) {
-				Object ds = row.getDataSource(false);
-				if (ds != null) {
-					l.add(ds);
-				}
-			}
-		}
-		return l;
-	}
-
-	/** Returns an array of all selected Data Sources.  Null data sources are
-	 * ommitted.
-	 *
-	 * @return an array containing the selected data sources
-	 *
-	 **/
-	// see common.TableView
-	public List<DATASOURCETYPE> getSelectedDataSources() {
-		return new ArrayList<DATASOURCETYPE>(getSelectedDataSourcesList());
-	}
-
-	// see common.TableView
-	public Object[] getSelectedDataSources(boolean bCoreDataSource) {
-		if (bCoreDataSource) {
-			return getSelectedDataSourcesList().toArray();
-		}
-		return getSelectedPluginDataSourcesList().toArray();
-	}
-
-	/** @see com.aelitis.azureus.ui.common.table.TableView#getSelectedRows() */
-	public TableRowCore[] getSelectedRows() {
-		return getSelectedRowsList().toArray(new TableRowCore[0]);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getSelectedRowsSize()
-	public int getSelectedRowsSize() {
-		return selectedRowIndexes == null ? 0 : selectedRowIndexes.length;
-	}
-
-	public TableRowSWT[] getSelectedRowsSWT() {
-		return getSelectedRowsList().toArray(new TableRowSWT[0]);
-	}
-
-	/** Returns an list of all selected TableRowSWT objects.  Null data sources are
-	 * ommitted.
-	 *
-	 * @return an list containing the selected TableRowSWT objects
-	 */
-	public List<TableRowCore> getSelectedRowsList() {
-		List<TableRowCore> l = new ArrayList<TableRowCore>();
-		if (table != null && !table.isDisposed()) {
-			TableItem[] tis = table.getSelection();
-			for (int i = 0; i < tis.length; i++) {
-				TableRowSWT row = (TableRowSWT) getRow(tis[i]);
-				if (row != null && row.getDataSource(true) != null) {
-					l.add(row);
-				}
-			}
-		}
-		return l;
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getFocusedRow()
-	public TableRowCore getFocusedRow() {
-		TableRowSWT[] selectedRows = getSelectedRowsSWT();
-		if (selectedRows.length == 0) {
-			return null;
-		}
-		return selectedRows[0];
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getFirstSelectedDataSource()
-	@SuppressWarnings("unchecked")
-	public DATASOURCETYPE getFirstSelectedDataSource() {
-		return (DATASOURCETYPE) getFirstSelectedDataSource(true);
-	}
-
-	public TableRowSWT[] getVisibleRows() {
-		if (!isVisible()) {
-			return new TableRowSWT[0];
-		}
-
-		int iTopIndex = table.getTopIndex();
-		if (iTopIndex < 0) {
-			return new TableRowSWT[0];
-		}
-		int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-
-		int size = iBottomIndex - iTopIndex + 1;
-		if (size <= 0) {
-			return new TableRowSWT[0];
-		}
-
-		TableRowSWT[] rows = new TableRowSWT[size];
-		int pos = 0;
-		for (int i = iTopIndex; i <= iBottomIndex; i++) {
-			TableItem item = table.getItem(i);
-			if (item != null && !item.isDisposed()) {
-				TableRowSWT row = (TableRowSWT) getRow(item);
-				if (row != null) {
-					rows[pos++] = row;
+			
+			int iPos = table.indexOf(item);
+			//System.out.println(iPos + " has no table row.. associating. " + Debug.getCompressedStackTrace(4));
+			Object sortedRows_sync = getRowsSync();
+			synchronized (sortedRows_sync) {
+				if (iPos >= 0 && iPos < getRowCount()) {
+					TableRowSWT row = (TableRowSWT) getRow(iPos);
+					//System.out.print(".. associating to " + row);
+					if (row != null && !row.isRowDisposed()) {
+						row.setTableItem(iPos);
+						//System.out.println(", now " + row);
+						return row;
+					}
+					return null;
 				}
 			}
+		} catch (Exception e) {
+			Debug.out(e);
 		}
-
-		if (pos <= rows.length) {
-			// Some were null, shrink array
-			TableRowSWT[] temp = new TableRowSWT[pos];
-			System.arraycopy(rows, 0, temp, 0, pos);
-			return temp;
-		}
-
-		return rows;
-	}
-
-	/** Returns the first selected data sources.
-	 *
-	 * @return the first selected data source, or null if no data source is 
-	 *         selected
-	 */
-	public Object getFirstSelectedDataSource(boolean bCoreObject) {
-		if (table == null || table.isDisposed() || table.getSelectionCount() == 0) {
-			return null;
-		}
-
-		TableRowCore row = getRow(table.getSelection()[0]);
-		if (row == null) {
-			return null;
-		}
-		return row.getDataSource(bCoreObject);
+		return null;
 	}
 
-	/** For each row source that the user has selected, run the code
-	 * provided by the specified parameter.
-	 *
-	 * @param runner Code to run for each selected row/datasource
-	 */
-	public void runForSelectedRows(TableGroupRowRunner runner) {
-		if (table == null || table.isDisposed()) {
-			return;
-		}
 
-		TableItem[] tis = table.getSelection();
-		List<TableRowCore> rows_to_use = new ArrayList<TableRowCore>(tis.length);
-		for (int i = 0; i < tis.length; i++) {
-			TableRowCore row = getRow(tis[i]);
-			if (row != null) {
-				if (rows_to_use != null) {
-					rows_to_use.add(row);
-				}
-			}
+	public TableRowSWT[] swt_getVisibleRows() {
+		if (!isVisible()) {
+			return new TableRowSWT[0];
 		}
-		if (rows_to_use != null) {
-			TableRowCore[] rows = rows_to_use.toArray(new TableRowCore[rows_to_use.size()]);
-			boolean ran = runner.run(rows);
-			if (!ran) {
-				for (int i = 0; i < rows.length; i++) {
-					TableRowCore row = rows[i];
-					runner.run(row);
-				}
-			}
+		
+		synchronized (this) {
+  		if (visibleRows == null) {
+  			visibleRowsChanged();
+  		}
+  		
+  		return visibleRows;
 		}
 	}
 
@@ -3739,8 +1702,8 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 *
 	 * @param runner Code to run for each selected row/datasource
 	 */
-	public void runForVisibleRows(TableGroupRowRunner runner) {
-		TableRowSWT[] rows = getVisibleRows();
+	public void swt_runForVisibleRows(TableGroupRowRunner runner) {
+		TableRowSWT[] rows = swt_getVisibleRows();
 		if (runner.run(rows)) {
 			return;
 		}
@@ -3750,49 +1713,27 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// see common.tableview
-	public void runForAllRows(TableGroupRowVisibilityRunner runner) {
-		if (table == null || table.isDisposed()) {
-			return;
-		}
-
-		// put to array instead of synchronised iterator, so that runner can remove
-		TableRowCore[] rows = getRows();
-		int iTopIndex;
-		int iBottomIndex;
-		if (isVisible()) {
-			iTopIndex = table.getTopIndex();
-			iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-		} else {
-			iTopIndex = -1;
-			iBottomIndex = -2;
-		}
-
-		for (int i = 0; i < rows.length; i++) {
-			runner.run(rows[i], i >= iTopIndex && i <= iBottomIndex);
-		}
-	}
 
 	/**
 	 * Runs a specified task for a list of table items that the table contains
 	 * @param items A list of TableItems that are part of the table view
 	 * @param runner A task
 	 */
-	public void runForTableItems(List<TableItem> items, TableGroupRowRunner runner) {
+	public void runForTableItems(List<TableItemOrTreeItem> items, TableGroupRowRunner runner) {
 		if (table == null || table.isDisposed()) {
 			return;
 		}
 
-		final Iterator<TableItem> iter = items.iterator();
+		final Iterator<TableItemOrTreeItem> iter = items.iterator();
 		List<TableRowCore> rows_to_use = new ArrayList<TableRowCore>(items.size());
 		while (iter.hasNext()) {
-			TableItem tableItem = iter.next();
+			TableItemOrTreeItem tableItem = iter.next();
 			if (tableItem.isDisposed()) {
 				continue;
 			}
 
 			TableRowSWT row = (TableRowSWT) getRow(tableItem);
-			if (row != null) {
+			if (row != null && !row.isRowDisposed()) {
 				rows_to_use.add(row);
 			}
 		}
@@ -3818,14 +1759,21 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			sToClipboard += table.getColumn(j).getText();
 		}
 
-		TableItem[] tis = table.getSelection();
-		for (int i = 0; i < tis.length; i++) {
+		TableRowCore[] rows = getSelectedRows();
+		for (TableRowCore row : rows) {
 			sToClipboard += "\n";
-			for (int j = 0; j < table.getColumnCount(); j++) {
-				if (j != 0) {
-					sToClipboard += "\t";
+			TableColumnCore[] visibleColumns = getVisibleColumns();
+			for (int j = 0; j < visibleColumns.length; j++) {
+				TableColumnCore column = visibleColumns[j];
+				if (column.isVisible()) {
+  				if (j != 0) {
+  					sToClipboard += "\t";
+  				}
+  				TableCellCore cell = row.getTableCellCore(column.getName());
+  				if (cell != null) {
+  					sToClipboard += cell.getClipboardText();
+  				}
 				}
-				sToClipboard += tis[i].getText(j);
 			}
 		}
 		new Clipboard(getComposite().getDisplay()).setContents(new Object[] {
@@ -3843,13 +1791,17 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		 * @param event event information
 		 */
 		public void handleEvent(final Event event) {
-			TableColumn column = (TableColumn) event.widget;
+			int maskNoButton = (event.stateMask & ~SWT.BUTTON_MASK);
+			if (maskNoButton != 0) {
+				return;
+			}
+			TableColumnOrTreeColumn column = TableOrTreeUtils.getTableColumnEventItem(event.widget);
 			if (column == null) {
 				return;
 			}
 			TableColumnCore tableColumnCore = (TableColumnCore) column.getData("TableColumnCore");
 			if (tableColumnCore != null) {
-				sortColumnReverse(tableColumnCore);
+				setSortColumn(tableColumnCore, true);
 				columnVisibilitiesChanged = true;
 				refreshTable(true);
 			}
@@ -3864,7 +1816,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		implements Listener
 	{
 		public void handleEvent(Event event) {
-			TableColumn column = (TableColumn) event.widget;
+			TableColumnOrTreeColumn column = TableOrTreeUtils.getTableColumnEventItem(event.widget);
 			if (column == null) {
 				return;
 			}
@@ -3874,15 +1826,15 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				return;
 			}
 
-			Table table = column.getParent();
+			TableOrTreeSWT table = column.getParent();
 
 			// Get the 'added position' of column
 			// It would have been easier if event (.start, .end) contained the old
 			// and new position..
-			TableColumn[] tableColumns = table.getColumns();
+			TableColumnOrTreeColumn[] tableColumns = table.getColumns();
 			int iAddedPosition;
 			for (iAddedPosition = 0; iAddedPosition < tableColumns.length; iAddedPosition++) {
-				if (column == tableColumns[iAddedPosition]) {
+				if (column.getColumn() == tableColumns[iAddedPosition].getColumn()) {
 					break;
 				}
 			}
@@ -3911,7 +1863,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 						//System.out.println("Moving " + tableColumnCore.getName() + " to Position " + i);
 						tableColumnCore.setPositionNoShift(iNewPosition);
 						tableColumnCore.saveSettings(null);
-						TableStructureEventDispatcher.getInstance(sTableID).columnOrderChanged(
+						TableStructureEventDispatcher.getInstance(tableID).columnOrderChanged(
 								iColumnOrder);
 					}
 					break;
@@ -3920,7 +1872,10 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	private int getColumnNo(int iMouseX) {
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getColumnNo(int)
+	 */
+	public int getColumnNo(int iMouseX) {
 		int iColumn = -1;
 		int itemCount = table.getItemCount();
 		if (table.getItemCount() > 0) {
@@ -3930,7 +1885,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			if (topIndex >= itemCount || topIndex < 0) {
 				topIndex = itemCount - 1;
 			}
-			TableItem ti = table.getItem(topIndex);
+			TableItemOrTreeItem ti = table.getItem(topIndex);
 			if (ti.isDisposed()) {
 				return -1;
 			}
@@ -3950,112 +1905,94 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		return iColumn;
 	}
 
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getRow(int, int)
+	 */
 	public TableRowCore getRow(int x, int y) {
 		int iColumn = getColumnNo(x);
 		if (iColumn < 0) {
 			return null;
 		}
 
-		TableItem item = table.getItem(new Point(2, y));
+		TableItemOrTreeItem item = table.getItem(new Point(2, y));
 		if (item == null) {
 			return null;
 		}
 		return getRow(item);
 	}
 
-	public TableCellSWT getTableCell(int x, int y) {
+	public TableCellCore getTableCell(int x, int y) {
 		int iColumn = getColumnNo(x);
 		if (iColumn < 0) {
 			return null;
 		}
 
-		TableItem item = table.getItem(new Point(2, y));
+		TableItemOrTreeItem item = table.getItem(new Point(2, y));
+		if (item == null) {
+			item = table.getItem(new Point(x, y));
+		}
+
 		if (item == null) {
 			return null;
 		}
 		TableRowSWT row = (TableRowSWT) getRow(item);
 
-		if (row == null) {
+		if (row == null || row.isRowDisposed()) {
 			return null;
 		}
 
-		TableColumn tcColumn = table.getColumn(iColumn);
+		TableColumnOrTreeColumn tcColumn = table.getColumn(iColumn);
 		String sCellName = (String) tcColumn.getData("Name");
 		if (sCellName == null) {
 			return null;
 		}
 
-		return row.getTableCellSWT(sCellName);
+		return row.getTableCellCore(sCellName);
 	}
 
-	public TableRowSWT getTableRow(int x, int y) {
-		TableItem item = table.getItem(new Point(2, y));
+	public TableRowSWT getTableRow(int x, int y, boolean anyX) {
+		TableItemOrTreeItem item = table.getItem(new Point(anyX ? 2 : x, y));
 		if (item == null) {
 			return null;
 		}
 		return (TableRowSWT) getRow(item);
 	}
 
-	private TableColumnCore getTableColumnByOffset(int x) {
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableColumnByOffset(int)
+	 */
+	public TableColumnCore getTableColumnByOffset(int x) {
 		int iColumn = getColumnNo(x);
 		if (iColumn < 0) {
 			return null;
 		}
 
-		TableColumn column = table.getColumn(iColumn);
+		TableColumnOrTreeColumn column = table.getColumn(iColumn);
 		return (TableColumnCore) column.getData("TableColumnCore");
 	}
 
 	// @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
 	public void generate(IndentWriter writer) {
-		writer.println("Diagnostics for " + this + " (" + sTableID + ")");
-
-		try {
-			dataSourceToRow_mon.enter();
-
-			writer.println("DataSources scheduled to Add/Remove: "
-					+ dataSourcesToAdd.size() + "/" + dataSourcesToRemove.size());
-
-			writer.println("TableView: " + mapDataSourceToRow.size() + " datasources");
-			Iterator<DATASOURCETYPE> it = mapDataSourceToRow.keySet().iterator();
-
-			while (it.hasNext()) {
-
-				Object key = it.next();
-
-				writer.println("  " + key + " -> " + mapDataSourceToRow.get(key));
-			}
+		super.generate(writer);
 
-			writer.println("# of SubViews: " + tabViews.size());
-			writer.indent();
-			try {
-				for (Iterator<IView> iter = tabViews.iterator(); iter.hasNext();) {
-					IView view = iter.next();
-					view.generateDiagnostics(writer);
-				}
-			} finally {
-				writer.exdent();
-			}
+		if (tvTabsCommon != null) {
+			tvTabsCommon.generate(writer);
+		}
 
-			writer.println("Columns:");
-			writer.indent();
-			try {
-				TableColumn[] tableColumnsSWT = table.getColumns();
-				for (int i = 0; i < tableColumnsSWT.length; i++) {
-					final TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
-					if (tc != null) {
-						writer.println(tc.getName() + ";w=" + tc.getWidth() + ";w-offset="
-								+ tableColumnsSWT[i].getData("widthOffset"));
-					}
+		writer.println("Columns:");
+		writer.indent();
+		try {
+			TableColumnOrTreeColumn[] tableColumnsSWT = table.getColumns();
+			for (int i = 0; i < tableColumnsSWT.length; i++) {
+				final TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
+				if (tc != null) {
+					writer.println(tc.getName() + ";w=" + tc.getWidth() + ";w-offset="
+							+ tableColumnsSWT[i].getData("widthOffset"));
 				}
-			} catch (Throwable t) {
-			} finally {
-				writer.exdent();
 			}
-
+		} catch (Throwable t) {
 		} finally {
-
-			dataSourceToRow_mon.exit();
+			writer.exdent();
 		}
 	}
 
@@ -4090,246 +2027,108 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		}
 	}
 
-	// TabViews Functions
-	public void addTabView(IView view) {
-		if (view == null || tabFolder == null) {
-			return;
-		}
-
-		CTabItem item = new CTabItem(tabFolder, SWT.NULL);
-		item.setData("IView", view);
-		Messages.setLanguageText(item, view.getData());
-		view.initialize(tabFolder);
-		item.setControl(view.getComposite());
-		tabViews.add(view);
-	}
 
-	private void fillRowGaps(boolean bForceDataRefresh) {
-		_sortColumn(bForceDataRefresh, true, false);
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#selectRow(com.aelitis.azureus.ui.common.table.TableRowCore, boolean)
+	 */
+	public void setRowSelected(final TableRowCore row, boolean selected, boolean trigger) {
+		super.setRowSelected(row, selected, trigger);
+		
+		if (row instanceof TableRowSWT) {
+			((TableRowSWT) row).setWidgetSelected(selected);
+		}
 	}
 
-	private void sortColumn(boolean bForceDataRefresh) {
-		_sortColumn(bForceDataRefresh, false, false);
-	}
+	protected void updateSelectedRows(TableItemOrTreeItem[] newSelectionArray, boolean trigger) {
+		List<TableRowCore> newSelectionList = new ArrayList<TableRowCore>(1);
 
-	private void _sortColumn(boolean bForceDataRefresh, boolean bFillGapsOnly,
-			boolean bFollowSelected) {
-		if (table == null || table.isDisposed()) {
-			return;
+		//System.out.print("Selected Items: ");
+		for (TableItemOrTreeItem item : newSelectionArray) {
+			//System.out.print(table.indexOf(item));
+			TableRowCore row = getRow(item);
+			if (row != null && !row.isRowDisposed()) {
+				newSelectionList.add(row);
+			}// else { System.out.print("( NO ROW)"); }
+			//System.out.print(", ");
 		}
+		//System.out.println();
+		setSelectedRows(newSelectionList.toArray(new TableRowCore[0]), trigger);
+	}
 
-		try {
-			sortColumn_mon.enter();
-
-			long lTimeStart;
-			if (DEBUG_SORTER) {
-				//System.out.println(">>> Sort.. ");
-				lTimeStart = System.currentTimeMillis();
-			}
-
-			int iNumMoves = 0;
-
-			// This actually gets the focus, assuming the focus is selected
-			int iFocusIndex = table.getSelectionIndex();
-			TableRowCore focusedRow = (iFocusIndex == -1) ? null
-					: getRow(iFocusIndex);
-
-			int iTopIndex = table.getTopIndex();
-			int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-			boolean allSelectedRowsVisible = true;
-
-			int[] selectedRowIndices = table.getSelectionIndices();
-			TableRowCore[] selectedRows = new TableRowCore[selectedRowIndices.length];
-			for (int i = 0; i < selectedRowIndices.length; i++) {
-				int index = selectedRowIndices[i];
-				selectedRows[i] = getRow(table.getItem(index));
-				if (allSelectedRowsVisible
-						&& (index < iTopIndex || index > iBottomIndex)) {
-					allSelectedRowsVisible = false;
-				}
-				//System.out.println("Selected: " + selectedRowIndices[i] + ";" + selectedRows[i].getDataSource(true));
-			}
-
-			try {
-				sortedRows_mon.enter();
-
-				if (bForceDataRefresh && sortColumn != null) {
-					int i = 0;
-					String sColumnID = sortColumn.getName();
-					for (Iterator<TableRowSWT> iter = sortedRows.iterator(); iter.hasNext();) {
-						TableRowSWT row = iter.next();
-						TableCellSWT cell = row.getTableCellSWT(sColumnID);
-						if (cell != null) {
-							cell.refresh(true, i >= iTopIndex && i <= iBottomIndex);
-						}
-						i++;
-					}
+	@Override
+	public void uiSelectionChanged(final TableRowCore[] newlySelectedRows,
+			final TableRowCore[] deselectedRows) {
+		Utils.execSWTThread(new AERunnable() {
+			
+			@Override
+			public void runSupport() {
+				if (table.isDisposed()) {
+					return;
 				}
-
-				if (!bFillGapsOnly) {
-					if (sortColumn != null
-							&& sortColumn.getLastSortValueChange() > lLastSortedOn) {
-						lLastSortedOn = SystemTime.getCurrentTime();
-						Collections.sort(sortedRows, sortColumn);
-						if (DEBUG_SORTER) {
-							long lTimeDiff = (System.currentTimeMillis() - lTimeStart);
-							if (lTimeDiff > 150) {
-								System.out.println("--- Build & Sort took " + lTimeDiff + "ms");
-							}
-						}
-					} else {
-						if (DEBUG_SORTER) {
-							System.out.println("Skipping sort :)");
+				
+				for (TableRowCore row : deselectedRows) {
+					if (row instanceof TableRowImpl) {
+						TableRowImpl rowImpl = (TableRowImpl) row;
+						TableItemOrTreeItem item = rowImpl.getItem();
+						if (item != null && !item.isDisposed()) {
+							table.deselect(item);
 						}
 					}
 				}
 
-				int count = sortedRows.size();
-				if (iBottomIndex >= count) {
-					iBottomIndex = count - 1;
-				}
-				if (bTableVirtual && allSelectedRowsVisible) {
-					for (int i = 0; i < sortedRows.size(); i++) {
-						TableRowSWT row = sortedRows.get(i);
-						boolean visible = i >= iTopIndex && i <= iBottomIndex;
-						if (visible) {
-							if (row.setTableItem(i)) {
-								iNumMoves++;
-							}
-						} else {
-							if (row instanceof TableRowImpl) {
-								((TableRowImpl) row).setShown(visible, false);
-							}
-						}
-					}
-
-					// visibleRowsChanged() will setTableItem for the rest
-				} else {
-					for (int i = 0; i < sortedRows.size(); i++) {
-						boolean visible = i >= iTopIndex && i <= iBottomIndex;
-						TableRowSWT row = sortedRows.get(i);
-						if (row.setTableItem(i, visible)) {
-							iNumMoves++;
-						} else {
-							if (row instanceof TableRowImpl) {
-								((TableRowImpl) row).setShown(visible, false);
-							}
+				for (TableRowCore row : newlySelectedRows) {
+					if (row instanceof TableRowImpl) {
+						TableRowImpl rowImpl = (TableRowImpl) row;
+						TableItemOrTreeItem item = rowImpl.getItem();
+						if (item != null && !item.isDisposed()) {
+							table.select(item);
 						}
 					}
 				}
-			} finally {
-				sortedRows_mon.exit();
-			}
-
-			// move cursor to selected row
-			/** SWT/Windows Bug:
-			 * When we set selection, the first index is the focus row.
-			 * This works visually, however, if you press shift-up or shift-down,
-			 * it uses an older selection index.
-			 * 
-			 * ie. User selects row #10
-			 *     Programmically change selection to Row #15 only
-			 *     Shift-down
-			 *     Rows 10 through 26 will be selected
-			 *     
-			 * This is Eclipse bug #77106, and is marked WONTFIX 
-			 */
-			if (focusedRow != null) {
-				int pos = selectedRows.length == 1 ? 0 : 1;
-				int numSame = 0;
-				int[] newSelectedRowIndices = new int[selectedRows.length];
-				Arrays.sort(selectedRowIndices);
-				for (int i = 0; i < selectedRows.length; i++) {
-					if (selectedRows[i] == null) {
-						continue;
-					}
-					int index = selectedRows[i].getIndex();
-					int iNewPos = (selectedRows[i] == focusedRow) ? 0 : pos++;
-					//System.out.println("new selected, index=" + index + ";row=" + selectedRows[i].getDataSource(true));
-					newSelectedRowIndices[iNewPos] = index;
-					if (Arrays.binarySearch(selectedRowIndices, index) >= 0) {
-						numSame++;
-					}
-				}
-
-				if (numSame < selectedRows.length) {
-					if (bFollowSelected) {
-						table.setSelection(newSelectedRowIndices);
-					} else {
-						table.deselectAll();
-						table.select(newSelectedRowIndices);
-					}
-					setSelectedRowIndexes(table.getSelectionIndices());
-				}
-			}
 
-			if (DEBUG_SORTER) {
-				long lTimeDiff = (System.currentTimeMillis() - lTimeStart);
-				if (lTimeDiff >= 500) {
-					System.out.println("<<< Sort & Assign took " + lTimeDiff + "ms with "
-							+ iNumMoves + " rows (of " + sortedRows.size() + ") moved. "
-							+ focusedRow + ";" + Debug.getCompressedStackTrace());
-				}
 			}
-		} finally {
-			sortColumn_mon.exit();
-		}
+		});
 	}
 
-	/**
-	 * @param newSelectedRowIndices
-	 *
-	 * @since 4.1.0.5
-	 */
-	protected void setSelectedRowIndexes(int[] newSelectedRowIndices) {
-		selectedRowIndexes = newSelectedRowIndices;
-		listSelectedCoreDataSources = null;
-	}
 
-	protected void updateSelectedRowIndexes() {
-		if (!table.isDisposed()) {
-			setSelectedRowIndexes(table.getSelectionIndices());
+	@Override
+	protected boolean setSortColumn(TableColumnCore newSortColumn,
+			boolean allowOrderChange) {
+		final TableColumnCore oldSortColumn = getSortColumn();
+		
+		boolean columnChanged = super.setSortColumn(newSortColumn, allowOrderChange);
+		if (columnChanged) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					TableColumnCore sortColumn = getSortColumn();
+					fixAlignment(oldSortColumn, false);
+					fixAlignment(sortColumn, true);
+				}
+			});
 		}
+		return columnChanged;
 	}
 
-	public void sortColumnReverse(TableColumnCore sorter) {
-		if (sortColumn == null) {
-			return;
-		}
-		boolean bSameColumn = sortColumn.equals(sorter);
-		if (!bSameColumn) {
-			fixAlignment(sortColumn, false);
-			sortColumn = sorter;
-			fixAlignment(sorter, true);
-			int iSortDirection = configMan.getIntParameter(CFG_SORTDIRECTION);
-			if (iSortDirection == 0) {
-				sortColumn.setSortAscending(true);
-			} else if (iSortDirection == 1) {
-				sortColumn.setSortAscending(false);
-			} else {
-				sortColumn.setSortAscending(!sortColumn.isSortAscending());
+	@Override
+	protected void uiChangeColumnIndicator() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_changeColumnIndicator();
 			}
-
-			TableColumnManager.getInstance().setDefaultSortColumnName(sTableID,
-					sortColumn.getName());
-		} else {
-			sortColumn.setSortAscending(!sortColumn.isSortAscending());
-		}
-
-		changeColumnIndicator();
-		sortColumn(!bSameColumn);
+		});
 	}
 
-	private void changeColumnIndicator() {
+	private void swt_changeColumnIndicator() {
 		if (table == null || table.isDisposed()) {
 			return;
 		}
 
 		try {
+			TableColumnCore sortColumn = getSortColumn();
 			// can't use TableColumnCore.getPosition, because user may have moved
 			// columns around, messing up the SWT column indexes.  
 			// We can either use search columnsOrdered, or search table.getColumns()
-			TableColumn[] tcs = table.getColumns();
+			TableColumnOrTreeColumn[] tcs = table.getColumns();
 			for (int i = 0; i < tcs.length; i++) {
 				String sName = (String) tcs[i].getData("Name");
 				if (sName != null && sortColumn != null
@@ -4349,127 +2148,112 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	// @see com.aelitis.azureus.ui.common.table.TableView#isRowVisible(com.aelitis.azureus.ui.common.table.TableRowCore)
 	public boolean isRowVisible(TableRowCore row) {
-		if (!isVisible()) {
-			return false;
+		if (row.isInPaintItem()) {
+			return true;
 		}
-		int i = row.getIndex();
-		int iTopIndex = table.getTopIndex();
-		if (iTopIndex < 0) {
+		if (visibleRows == null) {
 			return false;
 		}
-		int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-		return i >= iTopIndex && i <= iBottomIndex;
+		for (TableRowCore visibleRow : visibleRows) {
+			if (row == visibleRow) {
+				if (Utils.isThisThreadSWT() && !isVisible()) {
+					return false;
+				}
+				return true;
+			}
+		}
+		return false;
 	}
 
-	private void visibleRowsChanged() {
-		if (!isVisible()) {
-			lastTopIndex = 0;
-			lastBottomIndex = -1;
-			return;
-		}
+	@Override
+	public void visibleRowsChanged() {
 		//debug("VRC " + Debug.getCompressedStackTrace());
-
-		boolean bTableUpdate = false;
-		int iTopIndex = table.getTopIndex();
-		int iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-
-		if (lastTopIndex != iTopIndex) {
-			if (Utils.isCocoa) {
-				calculateClientArea();
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				swt_visibleRowsChanged();
 			}
-			int tmpIndex = lastTopIndex;
-			lastTopIndex = iTopIndex;
 
-			if (iTopIndex < tmpIndex) {
-				if (tmpIndex > iBottomIndex + 1 && iBottomIndex >= 0) {
-					tmpIndex = iBottomIndex + 1;
-				}
+		});
+	}
 
-				//debug("Refresh top rows " + iTopIndex + " to " + (tmpIndex - 1));
-				try {
-					sortedRows_mon.enter();
-					for (int i = iTopIndex; i < tmpIndex && i < sortedRows.size(); i++) {
-						TableRowSWT row = (TableRowSWT) getRow(i);
-						if (row != null) {
-							row.setAlternatingBGColor(true);
-							row.refresh(true, true);
-							if (row instanceof TableRowImpl) {
-								((TableRowImpl) row).setShown(true, false);
-							}
-							if (Constants.isOSX) {
-								bTableUpdate = true;
-							}
-						}
-					}
-				} finally {
-					sortedRows_mon.exit();
-				}
+	private void swt_visibleRowsChanged() {
+		final List<TableRowSWT> newlyVisibleRows = new ArrayList<TableRowSWT>();
+		final List<TableRowSWT> nowInVisibleRows;
+		synchronized (this) {
+  		List<TableItemOrTreeItem> visibleTableItems;
+  		if (isVisible()) {
+  			visibleTableItems = Utils.getVisibleTableItems(table);
+  		} else {
+  			visibleTableItems = Collections.emptyList();
+  		}
+			nowInVisibleRows = new ArrayList<TableRowSWT>(0);
+  		if (visibleRows != null) {
+  			nowInVisibleRows.addAll(Arrays.asList(visibleRows));
+  		}
+  		TableRowSWT[] rows = new TableRowSWT[visibleTableItems.size()];
+  		int pos = 0;
+  		for (TableItemOrTreeItem item : visibleTableItems) {
+  			TableRowCore row = getRow(item);
+  			if (row instanceof TableRowSWT) {
+  				rows[pos++] = (TableRowSWT) row;
+  				boolean removed = nowInVisibleRows.remove(row);
+  				if (!removed) {
+  					newlyVisibleRows.add((TableRowSWT) row);
+  				}
+  			}
+  		}
+  
+  		if (pos < rows.length) {
+  			// Some were null, shrink array
+  			TableRowSWT[] temp = new TableRowSWT[pos];
+  			System.arraycopy(rows, 0, temp, 0, pos);
+  			visibleRows = temp;
+  		} else {
+  			visibleRows = rows;
+  		}
+		}
+		
+		if (DEBUG_ROWCHANGE) {
+			System.out.println("visRowsChanged; shown=" + visibleRows.length + "; +"
+					+ newlyVisibleRows.size() + "/-" + nowInVisibleRows.size() + " via "
+					+ Debug.getCompressedStackTrace(8));
+		}
+		Utils.getOffOfSWTThread(new AERunnable() {
+			
+			public void runSupport() {
+				boolean bTableUpdate = false;
 
-				// A refresh might have triggered a row height resize, so
-				// bottom index needs updating
-				iBottomIndex = Utils.getTableBottomIndex(table, iTopIndex);
-			} else {
-				//System.out.println("Made T.Invisible " + (tmpIndex) + " to " + (iTopIndex - 1));
-				for (int i = tmpIndex; i < iTopIndex; i++) {
-					TableRowSWT row = (TableRowSWT) getRow(i);
-					if (row instanceof TableRowImpl) {
-						((TableRowImpl) row).setShown(false, false);
+				for (TableRowSWT row : newlyVisibleRows) {
+					row.refresh(true, true);
+					row.setShown(true, false);
+					if (Constants.isOSX) {
+						bTableUpdate = true;
 					}
 				}
-			}
-		}
-
-		if (lastBottomIndex != iBottomIndex) {
-			int tmpIndex = lastBottomIndex;
-			lastBottomIndex = iBottomIndex;
-
-			if (tmpIndex < iTopIndex - 1) {
-				tmpIndex = iTopIndex - 1;
-			}
 
-			if (tmpIndex <= iBottomIndex) {
-				//debug("Refresh bottom rows " + (tmpIndex + 1) + " to " + iBottomIndex);
-				try {
-					sortedRows_mon.enter();
-					for (int i = tmpIndex + 1; i <= iBottomIndex && i < sortedRows.size(); i++) {
-						TableRowSWT row = (TableRowSWT) getRow(i);
-						if (row != null) {
-							row.setAlternatingBGColor(true);
-							row.refresh(true, true);
-							if (row instanceof TableRowImpl) {
-								((TableRowImpl) row).setShown(true, false);
-							}
+				for (TableRowSWT row : nowInVisibleRows) {
+					row.setShown(false, false);
+				}
 
-							if (Constants.isOSX) {
-								bTableUpdate = true;
-							}
+				if (bTableUpdate) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							table.update();
 						}
-					}
-				} finally {
-					sortedRows_mon.exit();
-				}
-			} else {
-				//System.out.println("Made B.Invisible " + (tmpIndex) + " to " + (iBottomIndex + 1));
-				for (int i = tmpIndex; i <= iBottomIndex; i++) {
-					TableRowSWT row = (TableRowSWT) getRow(i);
-					if (row instanceof TableRowImpl) {
-						((TableRowImpl) row).setShown(false, false);
-					}
+					});
 				}
+
 			}
-		}
+		});
 
-		if (bTableUpdate) {
-			table.update();
-		}
 	}
 
-	public Image obfusticatedImage(final Image image, Point shellOffset) {
+	public Image obfusticatedImage(final Image image) {
 		if (table.getItemCount() == 0 || !isVisible()) {
 			return image;
 		}
 
-		TableColumn[] tableColumnsSWT = table.getColumns();
+		TableColumnOrTreeColumn[] tableColumnsSWT = table.getColumns();
 		for (int i = 0; i < tableColumnsSWT.length; i++) {
 			final TableColumnCore tc = (TableColumnCore) tableColumnsSWT[i].getData("TableColumnCore");
 
@@ -4483,32 +2267,32 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				}
 
 				for (int j = iTopIndex; j <= iBottomIndex; j++) {
-					TableItem rowSWT = table.getItem(j);
+					TableItemOrTreeItem rowSWT = table.getItem(j);
 					TableRowSWT row = (TableRowSWT) table.getItem(j).getData("TableRow");
-					if (row != null) {
+					if (row != null && !row.isRowDisposed()) {
 						TableCellSWT cell = row.getTableCellSWT(tc.getName());
-						final Rectangle columnBounds = rowSWT.getBounds(i);
-						if (columnBounds.y + columnBounds.height > clientArea.y
-								+ clientArea.height) {
-							columnBounds.height -= (columnBounds.y + columnBounds.height)
-									- (clientArea.y + clientArea.height);
-						}
-						if (columnBounds.x + columnBounds.width > clientArea.x
-								+ clientArea.width) {
-							columnBounds.width -= (columnBounds.x + columnBounds.width)
-									- (clientArea.x + clientArea.width);
-						}
-
-						final Point offset = table.toDisplay(columnBounds.x, columnBounds.y);
-
-						columnBounds.x = offset.x - shellOffset.x;
-						columnBounds.y = offset.y - shellOffset.y;
 
 						String text = cell.getObfusticatedText();
 
 						if (text != null) {
-							UIDebugGenerator.obfusticateArea(table.getDisplay(), image,
-									columnBounds, text);
+							final Rectangle columnBounds = rowSWT.getBounds(i);
+							if (columnBounds.y + columnBounds.height > clientArea.y
+									+ clientArea.height) {
+								columnBounds.height -= (columnBounds.y + columnBounds.height)
+										- (clientArea.y + clientArea.height);
+							}
+							if (columnBounds.x + columnBounds.width > clientArea.x
+									+ clientArea.width) {
+								columnBounds.width -= (columnBounds.x + columnBounds.width)
+										- (clientArea.x + clientArea.width);
+							}
+							
+							Point location = Utils.getLocationRelativeToShell(table.getComposite());
+							
+							columnBounds.x += location.x;
+							columnBounds.y += location.y;
+
+							UIDebugGenerator.obfusticateArea(image, columnBounds, text);
 						}
 					}
 				}
@@ -4517,46 +2301,28 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 			}
 		}
 
-		IView view = getActiveSubView();
+		UISWTViewCore view = tvTabsCommon == null ? null : tvTabsCommon.getActiveSubView();
 		if (view instanceof ObfusticateImage) {
 			try {
-				((ObfusticateImage) view).obfusticatedImage(image, shellOffset);
+				((ObfusticateImage) view).obfusticatedImage(image);
 			} catch (Exception e) {
-				Debug.out("Obfusticating " + view, e);
+				Debug.out("Obfuscating " + view, e);
 			}
 		}
 		return image;
 	}
 
-	void debug(String s) {
-		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("table");
-		diag_logger.log(SystemTime.getCurrentTime() + ":" + sTableID + ": " + s);
-
-		System.out.println(SystemTime.getCurrentTime() + ": " + sTableID + ": " + s);
-	}
-
-	// from common.TableView
-	public boolean isEnableTabViews() {
-		return bEnableTabViews;
-	}
-
 	// from common.TableView
 	public void setEnableTabViews(boolean enableTabViews) {
 		bEnableTabViews = enableTabViews;
 	}
-
-	// from common.TableView
-	public IView[] getCoreTabViews() {
-		return coreTabViews;
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#setCoreTabViews(org.gudy.azureus2.ui.swt.views.IView[])
-	public void setCoreTabViews(IView[] coreTabViews) {
-		this.coreTabViews = coreTabViews;
+	
+	public boolean isTabViewsEnabled() {
+		return bEnableTabViews;
 	}
 
 	public void addMenuFillListener(TableViewSWTMenuFillListener l) {
-		listenersMenuFill.add(l);
+		tvSWTCommon.addMenuFillListener(l);
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableView#isDisposed()
@@ -4565,26 +2331,6 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 				|| table.isDisposed();
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#size(boolean)
-	public int size(boolean bIncludeQueue) {
-		int size = sortedRows.size();
-
-		if (bIncludeQueue) {
-			if (dataSourcesToAdd != null) {
-				size += dataSourcesToAdd.size();
-			}
-			if (dataSourcesToRemove != null) {
-				size += dataSourcesToRemove.size();
-			}
-		}
-		return size;
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getPropertiesPrefix()
-	public String getPropertiesPrefix() {
-		return sPropertiesPrefix;
-	}
-
 	// @see com.aelitis.azureus.ui.common.table.TableView#setFocus()
 	public void setFocus() {
 		if (table != null && !table.isDisposed()) {
@@ -4594,32 +2340,38 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	// @see org.gudy.azureus2.ui.swt.views.TableViewSWT#addKeyListener(org.eclipse.swt.events.KeyListener)
 	public void addKeyListener(KeyListener listener) {
-		if (listenersKey.contains(listener)) {
+		if (tvSWTCommon == null || isDisposed()) {
 			return;
 		}
-
-		listenersKey.add(listener);
+		tvSWTCommon.addKeyListener(listener);
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableView#removeKeyListener(org.eclipse.swt.events.KeyListener)
 	public void removeKeyListener(KeyListener listener) {
-		listenersKey.remove(listener);
+		if (tvSWTCommon == null || isDisposed()) {
+			return;
+		}
+		tvSWTCommon.removeKeyListener(listener);
 	}
-
-	// @see org.gudy.azureus2.ui.swt.views.TableViewSWT#getSortColumn()
-	public TableColumnCore getSortColumn() {
-		return sortColumn;
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getKeyListeners()
+	 */
+	public KeyListener[] getKeyListeners() {
+		if (tvSWTCommon == null || isDisposed()) {
+			return new KeyListener[0];
+		}
+		return tvSWTCommon.getKeyListeners();
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.TableView#selectAll()
 	public void selectAll() {
 		if (table != null && !table.isDisposed()) {
-			ensureAllRowsHaveIndex();
+			// Used to ensure all rows have index, but I don't see a reason why.
+			// Uses a lot of CPU, so kill it :)
+			//ensureAllRowsHaveIndex();
 			table.selectAll();
-			updateSelectedRowIndexes();
-
-			triggerSelectionListeners(getSelectedRows());
-			triggerTabViewsDataSourceChanged();
+			super.selectAll();
 		}
 	}
 
@@ -4627,40 +2379,35 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	 * 
 	 *
 	 * @since 3.0.0.7
-	 */
+	 *
 	private void ensureAllRowsHaveIndex() {
 		for (int i = 0; i < sortedRows.size(); i++) {
 			TableRowSWT row = sortedRows.get(i);
 			row.setTableItem(i);
 		}
 	}
+	*/
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#setSelectedRows(com.aelitis.azureus.ui.common.table.TableRowCore[])
-	public void setSelectedRows(TableRowCore[] rows) {
-		table.deselectAll();
-		for (int i = 0; i < rows.length; i++) {
-			TableRowCore row = rows[i];
-			if (row.getIndex() == -1) {
-				int j = sortedRows.indexOf(row);
-				if (j == -1) {
-					System.err.println("BOO");
-				} else {
-					row.setTableItem(j);
-				}
-			}
-			row.setSelected(true);
-		}
-		updateSelectedRowIndexes();
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#isTableFocus()
-	public boolean isTableFocus() {
-		return table.isFocusControl();
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#isDragging()
+	 */
+	public boolean isDragging() {
+		return isDragging;
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#createDragSource(int)
 	public DragSource createDragSource(int style) {
-		final DragSource dragSource = new DragSource(table, style);
+		final DragSource dragSource = new DragSource(table.getComposite(), style);
+		dragSource.addDragListener(new DragSourceAdapter() {
+			public void dragStart(DragSourceEvent event) {
+				table.setCursor(null);
+				isDragging = true;
+			}
+			
+			public void dragFinished(DragSourceEvent event) {
+				isDragging = false;
+			}
+		});
 		table.addDisposeListener(new DisposeListener() {
 			// @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
 			public void widgetDisposed(DisposeEvent e) {
@@ -4674,7 +2421,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#createDropTarget(int)
 	public DropTarget createDropTarget(int style) {
-		final DropTarget dropTarget = new DropTarget(table, style);
+		final DropTarget dropTarget = new DropTarget(table.getComposite(), style);
 		table.addDisposeListener(new DisposeListener() {
 			// @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
 			public void widgetDisposed(DisposeEvent e) {
@@ -4688,24 +2435,13 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#indexOf(org.eclipse.swt.widgets.Widget)
 	public TableRowCore getRow(DropTargetEvent event) {
-		if (event.item instanceof TableItem) {
-			TableItem ti = (TableItem) event.item;
+		TableItemOrTreeItem ti = TableOrTreeUtils.getEventItem(event.item);
+		if (ti != null) {
 			return (TableRowCore) ti.getData("TableRow");
 		}
 		return null;
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#dataSourceExists(java.lang.Object)
-	public boolean dataSourceExists(DATASOURCETYPE dataSource) {
-		return mapDataSourceToRow.containsKey(dataSource)
-				|| dataSourcesToAdd.contains(dataSource);
-	}
-
-	// @see com.aelitis.azureus.ui.common.table.TableView#getVisibleColumns()
-	public TableColumnCore[] getVisibleColumns() {
-		return tableColumns;
-	}
-
 	/**
 	 * @return
 	 */
@@ -4728,7 +2464,7 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	public TableRowCore getTableRowWithCursor() {
 		Point pt = table.getDisplay().getCursorLocation();
 		pt = table.toControl(pt);
-		return getTableRow(pt.x, pt.y);
+		return getTableRow(pt.x, pt.y, true);
 	}
 
 	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableCellMouseOffset()
@@ -4751,108 +2487,50 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		return new Point(x, y);
 	}
 
-	// @see com.aelitis.azureus.ui.common.table.TableView#getDataSourceType()
-	public Class getDataSourceType() {
-		return classPluginDataSourceType;
-	}
-
-	public void addRefreshListener(TableRowRefreshListener listener) {
-		try {
-			listeners_mon.enter();
-
-			if (refreshListeners == null) {
-				refreshListeners = new ArrayList<TableRowRefreshListener>(1);
-			}
-
-			refreshListeners.add(listener);
-
-		} finally {
-			listeners_mon.exit();
-		}
-	}
-
-	public void removeRefreshListener(TableRowRefreshListener listener) {
-		try {
-			listeners_mon.enter();
-
-			if (refreshListeners == null) {
-				return;
-			}
-
-			refreshListeners.remove(listener);
-
-		} finally {
-			listeners_mon.exit();
-		}
-	}
-
-	public void invokeRefreshListeners(TableRowCore row) {
-		Object[] listeners;
-		try {
-			listeners_mon.enter();
-			if (refreshListeners == null) {
-				return;
-			}
-			listeners = refreshListeners.toArray();
-
-		} finally {
-			listeners_mon.exit();
-		}
-
-		for (int i = 0; i < listeners.length; i++) {
-			try {
-				TableRowRefreshListener l = (TableRowRefreshListener) listeners[i];
-
-				l.rowRefresh(row);
-
-			} catch (Throwable e) {
-				Debug.printStackTrace(e);
-			}
-		}
-	}
 
+	/** Note: Callers need to be on SWT Thread */
 	public boolean isVisible() {
+		if (!Utils.isThisThreadSWT()) {
+			return isVisible;
+		}
 		boolean wasVisible = isVisible;
-		isVisible = table != null && !table.isDisposed() && table.isVisible();
+		isVisible = table != null && !table.isDisposed() && table.isVisible() && !shell.getMinimized();
 		if (isVisible != wasVisible) {
+			visibleRowsChanged();
+			UISWTViewCore view = tvTabsCommon == null ? null : tvTabsCommon.getActiveSubView();
 			if (isVisible) {
-				runForVisibleRows(new TableGroupRowRunner() {
-					public void run(TableRowCore row) {
-						row.invalidate();
-					}
-				});
 				loopFactor = 0;
 
-				IView view = getActiveSubView();
-				if (view instanceof IViewExtension) {
-					((IViewExtension)view).viewActivated();
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
 				}
 			} else {
-				IView view = getActiveSubView();
-				if (view instanceof IViewExtension) {
-					((IViewExtension)view).viewDeactivated();
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
 				}
 			}
 		}
 		return isVisible;
 	}
 
-	public void showRow(TableRowCore row) {
-		int index = row.getIndex();
-		if (index >= 0 && index < table.getItemCount()) {
-			table.showItem(table.getItem(index));
-		}
-	}
-
-	public boolean isMenuEnabled() {
-		return menuEnabled;
-	}
-
-	public void setMenuEnabled(boolean menuEnabled) {
-		this.menuEnabled = menuEnabled;
+	public void showRow(final TableRowCore row) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (isDisposed()) {
+    			return;
+    		}
+				int index = row.getIndex();
+				if (index >= 0 && index < table.getItemCount()) {
+					table.showItem(table.getItem(index));
+				}
+			}
+		});
 	}
 
-	private void openFilterDialog() {
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#openFilterDialog()
+	 */
+	public void openFilterDialog() {
 		if (filter == null) {
 			return;
 		}
@@ -4875,192 +2553,43 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		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();
+		if (tvSWTCommon != null) {
+			tvSWTCommon.setFilterText(s);
 		}
-		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;
+	
+	public TableViewSWTFilter<?> getSWTFilter() {
+		return (TableViewSWTFilter<?>) filter;
 	}
 
-	@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 boolean
+	isFiltered(
+		DATASOURCETYPE	ds )
+	{
+		if ( filter == null ){
+			return( true );
 		}
+		
+		return( filter.checker.filterCheck( ds, filter.text, filter.regex ));
 	}
-
+	
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#enableFilterCheck(org.eclipse.swt.widgets.Text, org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck)
 	public void enableFilterCheck(Text txtFilter,
 			TableViewFilterCheck<DATASOURCETYPE> filterCheck) {
+		TableViewSWTFilter<?> filter = getSWTFilter();
 		if (filter != null) {
 			if (filter.widget != null && !filter.widget.isDisposed()) {
-				filter.widget.removeKeyListener(TableViewSWTImpl.this);
+				filter.widget.removeKeyListener(tvSWTCommon);
 				filter.widget.removeModifyListener(filter.widgetModifyListener);
 			}
 		} else{
-			filter = new filter();
+			this.filter = filter = new TableViewSWTFilter<DATASOURCETYPE>();
 		}
 		filter.widget = txtFilter;
 		if (txtFilter != null) {
-  		txtFilter.addKeyListener(this);
+			txtFilter.setMessage("Filter");
+  		txtFilter.addKeyListener(tvSWTCommon);
   
   		filter.widgetModifyListener = new ModifyListener() {
   			public void modifyText(ModifyEvent e) {
@@ -5083,41 +2612,98 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 		filter.checker.filterSet(filter.text);
 		refilter();
 	}
-
-	public boolean enableSizeSlider(Composite composite, int min, int max) {
+	
+	public void disableFilterCheck()
+	{
+		TableViewSWTFilter<?> filter = getSWTFilter();
+		if ( filter == null ){
+			return;
+		}
+		
+		if (filter.widget != null && !filter.widget.isDisposed()) {
+			filter.widget.removeKeyListener(tvSWTCommon);
+			filter.widget.removeModifyListener(filter.widgetModifyListener);
+		}
+		filter = null;
+	}
+	
+	public boolean enableSizeSlider(Composite composite, final int min, final int max) {
 		try {
-			if (slider != null && !slider.isDisposed()) {
-				slider.dispose();
+			if (sliderArea != null && !sliderArea.isDisposed()) {
+				sliderArea.dispose();
 			}
-			final Method method = Table.class.getDeclaredMethod("setItemHeight", new Class<?>[] {
+			Class<?> claTable = Class.forName("org.eclipse.swt.widgets."
+					+ (useTree ? "Tree" : "Table"));
+			final Method method = claTable.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());
+			sliderArea = new Label(composite, SWT.NONE);
+			((Label)sliderArea).setImage(ImageLoader.getInstance().getImage("zoom"));
+			sliderArea.addListener(SWT.MouseUp, new Listener() {
+				public void handleEvent(Event event) {
+					final Shell shell = new Shell(sliderArea.getShell(), SWT.BORDER);
+					Listener l = new Listener() {
+						public void handleEvent(Event event) {
+							if (event.type == SWT.MouseExit) {
+								Control curControl = event.display.getCursorControl();
+								Point curPos = event.display.getCursorLocation();
+								Point curPosRelShell = shell.toControl(curPos);
+								Rectangle bounds = shell.getBounds();
+								bounds.x = bounds.y = 0;
+								if (!bounds.contains(curPosRelShell)) {
+									shell.dispose();
+									return;
+								}
+								if (curControl != null
+										&& (curControl == shell || curControl.getParent() == shell)) {
+									return;
+								}
+							}
+							shell.dispose();
+						}
+					};
+					shell.setBackgroundMode(SWT.INHERIT_FORCE);
+					shell.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
+					shell.addListener(SWT.MouseExit, l);
+					shell.addListener(SWT.Deactivate, l);
+					FillLayout fillLayout = new FillLayout();
+					fillLayout.marginHeight = 4;
+					shell.setLayout(fillLayout);
+					final Scale slider = new Scale(shell, SWT.VERTICAL);
+					slider.addListener(SWT.MouseExit, l);
+					slider.addListener(SWT.Deactivate, l);
+					slider.setMinimum(min);
+					slider.setMaximum(max);
+					slider.setSelection(getRowDefaultHeight());
 					try {
-						method.invoke(table, new Object[] { slider.getSelection() } );
+						method.invoke(table.getComposite(), new Object[] { slider.getSelection() } );
 					} catch (Throwable e1) {
-						e1.printStackTrace();
 					}
-					tableInvalidate();
-				}
-				
-				public void widgetDefaultSelected(SelectionEvent e) {
+					slider.addSelectionListener(new SelectionListener() {
+						public void widgetSelected(SelectionEvent e) {
+							setRowDefaultHeight(slider.getSelection());
+							try {
+								method.invoke(table.getComposite(), new Object[] { slider.getSelection() } );
+							} catch (Throwable e1) {
+								e1.printStackTrace();
+							}
+							tableInvalidate();
+						}
+						
+						public void widgetDefaultSelected(SelectionEvent e) {
+						}
+					});
+					Point pt = sliderArea.toDisplay(event.x - 2, event.y - 5);
+					int width = Constants.isOSX ? 20 : 50;
+					shell.setBounds(pt.x - (width / 2), pt.y, width, 120);
+					shell.open();
 				}
 			});
-			slider.setLayoutData(Utils.getFilledFormData());
+			
+			sliderArea.setLayoutData(Utils.getFilledFormData());
 			composite.layout();
 		} catch (Throwable t) {
 			return false;
@@ -5126,6 +2712,225 @@ public class TableViewSWTImpl<DATASOURCETYPE>
 	}
 	
 	public void disableSizeSlider() {
-		Utils.disposeSWTObjects(new Object[] { slider });
+		Utils.disposeSWTObjects(new Object[] { sliderArea });
+	}
+	
+	public void setEnabled(final boolean enable) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (!isDisposed()) {
+					table.setEnabled(enable);
+					/*
+					if (enable) {
+						Image oldImage = table.getBackgroundImage();
+						table.setBackgroundImage(null);
+						Utils.disposeSWTObjects(new Object[] { oldImage } );
+					} else {
+						final Image image = new Image(table.getDisplay(), 50, 50);
+						
+						GC gc = new GC(image);
+						gc.setBackground(ColorCache.getColor(gc.getDevice(), 0xee, 0xee, 0xee));
+						gc.fillRectangle(0, 0, 50, 50);
+						gc.dispose();
+						table.addDisposeListener(new DisposeListener() {
+							public void widgetDisposed(DisposeEvent e) {
+								Utils.disposeSWTObjects(new Object[] { image } );
+							}
+						});
+						
+						table.setBackgroundImage(image);
+					}
+					*/
+				}
+			}
+		});
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void addRowMouseListener(TableRowMouseListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.addRowMouseListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void removeRowMouseListener(TableRowMouseListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.removeRowMouseListener(listener);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#invokeRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
+	 */
+	public void invokeRowMouseListener(TableRowMouseEvent event) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.invokeRowMouseListener(event);
+		}
+	}
+
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void addRowPaintListener(TableRowSWTPaintListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.addRowPaintListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void removeRowPaintListener(TableRowSWTPaintListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.removeRowPaintListener(listener);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#invokePaintListeners(org.eclipse.swt.graphics.GC, com.aelitis.azureus.ui.common.table.TableRowCore, com.aelitis.azureus.ui.common.table.TableColumnCore, org.eclipse.swt.graphics.Rectangle)
+	 */
+	public void invokePaintListeners(GC gc, TableRowCore row,
+			TableColumnCore column, Rectangle cellArea) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.invokePaintListeners(gc, row, column, cellArea);
+		}
+	}
+
+	public boolean canHaveSubItems() {
+		return useTree;
+	}
+		
+	public void setParentDataSource(Object newDataSource) {
+		super.setParentDataSource(newDataSource);
+
+		triggerTabViewsDataSourceChanged(true);
+	}
+	
+	public void packColumns() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (table != null && !table.isDisposed()) {
+					table.pack(true);
+				}
+			}
+		});
+	}
+	
+	public int getMaxItemShown() {
+		return maxItemShown;
+	}
+	
+	public void setMaxItemShown(int i) {
+		maxItemShown  = i;
+	}
+	
+	public int indexOf(TableRowCore row) {
+		if (!Utils.isThisThreadSWT()) {
+			return super.indexOf(row);
+		}
+		int i = ((TableRowImpl) row).getRealIndex();
+		if (i == -1) {
+			i = super.indexOf(row);
+			if (i >= 0) {
+				row.setTableItem(i);
+			}
+		}
+		return i;
+	}
+
+
+	@Override
+	public TableRowCore createNewRow(Object ds) {
+		TableRowImpl row = new TableRowImpl(this, table, getVisibleColumns(), ds,
+				bSkipFirstColumn);
+		return row;
+	}
+
+	private int uiGetTopIndex() {
+		return ((Number) Utils.execSWTThreadWithObject("uiGetTopIndex", new AERunnableObject() {
+			public Object runSupport() {
+				 return table.getTopIndex();
+			}
+		}, 500)).intValue();
+	}
+	
+	@Override
+	public int uiGuessMaxVisibleRows() {
+		return 0;
+	}
+	
+	private int uiGetBottomIndex(final int iTopIndex) {
+		return ((Number) Utils.execSWTThreadWithObject("uiGetBottomIndex", new AERunnableObject() {
+			public Object runSupport() {
+				return Utils.getTableBottomIndex(table, iTopIndex);
+			}
+		}, 500)).intValue();
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getRowSWT(java.lang.Object)
+	public TableRowSWT getRowSWT(DATASOURCETYPE dataSource) {
+		return (TableRowSWT) getRow(dataSource);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#enableFilterCheck(org.eclipse.swt.widgets.Text, com.aelitis.azureus.ui.common.table.TableViewFilterCheck)
+	 */
+	public void enableFilterCheck(
+			Text txtFilter,
+			org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck<DATASOURCETYPE> filterCheck) {
+	}
+
+	@Override
+	public void getOffUIThread(AERunnable runnable) {
+		Utils.getOffOfSWTThread(runnable);
+	}
+	
+	@Override
+	protected void _sortColumn(final boolean bForceDataRefresh, final boolean bFillGapsOnly,
+			final boolean bFollowSelected) {
+		if (Utils.isThisThreadSWT()) {
+			super._sortColumn(bForceDataRefresh, bFillGapsOnly, bFollowSelected);
+			return;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			
+			@Override
+			public void runSupport() {
+				_sortColumn(bForceDataRefresh, bFillGapsOnly, bFollowSelected);
+			}
+		});
+	}
+	
+	public boolean isSingleSelection() {
+		return (iTableStyle & SWT.MULTI) > 0;
+	}
+	
+	public void expandColumns() {
+		TableColumnOrTreeColumn[] 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);
+			}
+		}
+	}
+	
+	public void showColumnEditor() {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.showColumnEditor();
+		}
 	}
-}
+}
\ No newline at end of file
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_Common.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_Common.java
new file mode 100644
index 0000000..c955438
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_Common.java
@@ -0,0 +1,1069 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+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.plugins.ui.tables.*;
+import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableContextMenuItemImpl;
+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.mainwindow.Colors;
+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.TableContextMenuManager;
+
+import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+
+public class TableViewSWT_Common
+	implements MouseListener, MouseMoveListener, SelectionListener, KeyListener
+{
+
+	TableViewSWT<?> tv;
+	private long lCancelSelectionTriggeredOn = -1;
+	private long lastSelectionTriggeredOn = -1;
+
+	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 Font FONT_NO_REGEX;
+	private static Font FONT_REGEX;
+	private static Font FONT_REGEX_ERROR;
+	
+	private List<TableViewSWTMenuFillListener> listenersMenuFill = new ArrayList<TableViewSWTMenuFillListener>(
+			1);
+
+	private List<KeyListener> listenersKey = new ArrayList<KeyListener>(1);
+
+	private ArrayList<TableRowMouseListener> rowMouseListeners;
+
+  private static AEMonitor mon_RowMouseListener = new AEMonitor( "rml" );
+
+	private static AEMonitor mon_RowPaintListener = new AEMonitor("rpl");
+
+	public int xAdj = 0;
+	public int yAdj = 0;
+
+	private ArrayList<TableRowSWTPaintListener> rowPaintListeners;
+
+
+	public TableViewSWT_Common(TableViewSWT<?> tv) {
+		this.tv = tv;
+	}
+
+	long lastMouseDblClkEventTime = 0;
+	public void mouseDoubleClick(MouseEvent e) {
+		long time = e.time & 0xFFFFFFFFL;
+		long diff = time - lastMouseDblClkEventTime;
+		// We fake a double click on MouseUp.. this traps 2 double clicks
+		// in quick succession and ignores the 2nd.
+		if (diff <= e.display.getDoubleClickTime() && diff >= 0) {
+			return;
+		}
+		lastMouseDblClkEventTime = time;
+
+		TableColumnCore tc = tv.getTableColumnByOffset(e.x);
+		TableCellCore cell = tv.getTableCell(e.x, e.y);
+		if (cell != null && tc != null) {
+			TableCellMouseEvent event = createMouseEvent(cell, e,
+					TableCellMouseEvent.EVENT_MOUSEDOUBLECLICK, false);
+			if (event != null) {
+				tc.invokeCellMouseListeners(event);
+				cell.invokeMouseListeners(event);
+				if (event.skipCoreFunctionality) {
+					lCancelSelectionTriggeredOn = System.currentTimeMillis();
+				}
+			}
+		}
+	}
+
+	long lastMouseUpEventTime = 0;
+	Point lastMouseUpPos = new Point(0, 0);
+	boolean mouseDown = false;
+	TableRowSWT mouseDownOnRow = null;
+	public void mouseUp(MouseEvent e) {
+		// SWT OSX Bug: two mouseup events when app not in focus and user
+		// clicks on the table.  Only one mousedown, so track that and ignore
+		if (!mouseDown) {
+			return;
+		}
+		mouseDown = false;
+
+		TableColumnCore tc = tv.getTableColumnByOffset(e.x);
+		TableCellCore cell = tv.getTableCell(e.x, e.y);
+		//TableRowCore row = tv.getTableRow(e.x, e.y, true);
+		mouseUp(mouseDownOnRow, cell, e.button, e.stateMask);
+
+		if (e.button == 1) {
+			long time = e.time & 0xFFFFFFFFL;
+			long diff = time - lastMouseUpEventTime;
+			if (diff <= e.display.getDoubleClickTime() && diff >= 0
+					&& lastMouseUpPos.x == e.x && lastMouseUpPos.y == e.y) {
+				// Fake double click because Cocoa SWT 3650 doesn't always trigger
+				// DefaultSelection listener on a Tree on dblclick (works find in Table)
+				runDefaultAction(e.stateMask);
+				return;
+			}
+			lastMouseUpEventTime = time;
+			lastMouseUpPos = new Point(e.x, e.y);
+		}
+		
+		if (cell != null && tc != null) {
+			TableCellMouseEvent event = createMouseEvent(cell, e,
+					TableCellMouseEvent.EVENT_MOUSEUP, false);
+			if (event != null) {
+				tc.invokeCellMouseListeners(event);
+				cell.invokeMouseListeners(event);
+				if (event.skipCoreFunctionality) {
+					lCancelSelectionTriggeredOn = System.currentTimeMillis();
+				}
+			}
+		}
+	}
+
+	TableRowCore lastClickRow;
+
+	public void mouseDown(MouseEvent e) {
+		mouseDown = true;
+		// we need to fill the selected row indexes here because the
+		// dragstart event can occur before the SWT.SELECTION event and
+		// our drag code needs to know the selected rows..
+		TableRowSWT row = mouseDownOnRow = tv.getTableRow(e.x, e.y, false);
+		TableCellCore cell = tv.getTableCell(e.x, e.y);
+		TableColumnCore tc = cell == null ? null : cell.getTableColumnCore();
+
+		mouseDown(row, cell, e.button, e.stateMask);
+
+		if (row == null) {
+			tv.setSelectedRows(new TableRowCore[0]);
+		}
+
+		tv.editCell(-1, -1); // clear out current cell editor
+
+		if (cell != null && tc != null) {
+			if (e.button == 2 && e.stateMask == SWT.CONTROL) {
+				((TableCellImpl) cell).bDebug = !((TableCellImpl) cell).bDebug;
+				System.out.println("Set debug for " + cell + " to "
+						+ ((TableCellImpl) cell).bDebug);
+			}
+			TableCellMouseEvent event = createMouseEvent(cell, e,
+					TableCellMouseEvent.EVENT_MOUSEDOWN, false);
+			if (event != null) {
+				tc.invokeCellMouseListeners(event);
+				cell.invokeMouseListeners(event);
+				tv.invokeRowMouseListener(event);
+				if (event.skipCoreFunctionality) {
+					lCancelSelectionTriggeredOn = System.currentTimeMillis();
+				}
+			}
+			if (tc.isInplaceEdit() && e.button == 1
+					&& lastClickRow == cell.getTableRowCore()) {
+				tv.editCell(tv.getColumnNo(e.x), cell.getTableRowCore().getIndex());
+			}
+			if (e.button == 1) {
+				lastClickRow = cell.getTableRowCore();
+			}
+		} else if (row != null) {
+			TableRowMouseEvent event = createMouseEvent(row, e,
+					TableCellMouseEvent.EVENT_MOUSEDOWN, false);
+			if (event != null) {
+				tv.invokeRowMouseListener(event);
+			}
+		}
+	}
+
+	public void mouseDown(TableRowSWT row, TableCellCore cell, int button,
+			int stateMask) {
+	}
+
+	public void mouseUp(TableRowCore row, TableCellCore cell, int button,
+			int stateMask) {
+	}
+
+	private TableCellMouseEvent createMouseEvent(TableCellCore cell, MouseEvent e,
+			int type, boolean allowOOB) {
+		TableCellMouseEvent event = new TableCellMouseEvent();
+		event.cell = cell;
+		if (cell != null) {
+			event.row = cell.getTableRow();
+		}
+		event.eventType = type;
+		event.button = e.button;
+		// TODO: Change to not use SWT masks
+		event.keyboardState = e.stateMask;
+		event.skipCoreFunctionality = false;
+		if (cell instanceof TableCellSWT) {
+			Rectangle r = ((TableCellSWT) cell).getBounds();
+			if (r == null) {
+				return event;
+			}
+			event.x = e.x - r.x - xAdj;
+			if (!allowOOB && event.x < 0) {
+				return null;
+			}
+			event.y = e.y - r.y - yAdj;
+			if (!allowOOB && event.y < 0) {
+				return null;
+			}
+		}
+
+		return event;
+	}
+
+	private TableRowMouseEvent createMouseEvent(TableRowSWT row, MouseEvent e,
+			int type, boolean allowOOB) {
+		TableCellMouseEvent event = new TableCellMouseEvent();
+		event.row = row;
+		event.eventType = type;
+		event.button = e.button;
+		// TODO: Change to not use SWT masks
+		event.keyboardState = e.stateMask;
+		event.skipCoreFunctionality = false;
+		if (row != null) {
+			Rectangle r = row.getBounds();
+			event.x = e.x - r.x - xAdj;
+			if (!allowOOB && event.x < 0) {
+				return null;
+			}
+			event.y = e.y - r.y - yAdj;
+			if (!allowOOB && event.y < 0) {
+				return null;
+			}
+		}
+
+		return event;
+	}
+
+
+
+	TableCellCore lastCell = null;
+
+	int lastCursorID = 0;
+
+	public void mouseMove(MouseEvent e) {
+		lCancelSelectionTriggeredOn = -1;
+		if (tv.isDragging()) {
+			return;
+		}
+		try {
+			TableCellCore cell = tv.getTableCell(e.x, e.y);
+			
+			if (cell != lastCell) {
+  			if (lastCell != null && !lastCell.isDisposed()) {
+  				TableCellMouseEvent event = createMouseEvent(lastCell, e,
+  						TableCellMouseEvent.EVENT_MOUSEEXIT, true);
+  				if (event != null) {
+  					((TableCellSWT) lastCell).setMouseOver(false);
+  					TableColumnCore tc = ((TableColumnCore) lastCell.getTableColumn());
+  					if (tc != null) {
+  						tc.invokeCellMouseListeners(event);
+  					}
+  					lastCell.invokeMouseListeners(event);
+  				}
+  			}
+  			
+  			if (cell != null && !cell.isDisposed()) {
+  				TableCellMouseEvent event = createMouseEvent(cell, e,
+  						TableCellMouseEvent.EVENT_MOUSEENTER, false);
+  				if (event != null) {
+  					((TableCellSWT) cell).setMouseOver(true);
+  					TableColumnCore tc = ((TableColumnCore) cell.getTableColumn());
+  					if (tc != null) {
+  						tc.invokeCellMouseListeners(event);
+  					}
+  					cell.invokeMouseListeners(event);
+  				}
+  			}
+			}
+
+			int iCursorID = 0;
+			if (cell == null) {
+				lastCell = null;
+			} else if (cell == lastCell) {
+				iCursorID = lastCursorID;
+			} else {
+				iCursorID = cell.getCursorID();
+				lastCell = cell;
+			}
+
+			if (iCursorID < 0) {
+				iCursorID = 0;
+			}
+
+			if (iCursorID != lastCursorID) {
+				lastCursorID = iCursorID;
+
+				if (iCursorID >= 0) {
+					tv.getComposite().setCursor(tv.getComposite().getDisplay().getSystemCursor(iCursorID));
+				} else {
+					tv.getComposite().setCursor(null);
+				}
+			}
+
+			if (cell != null) {
+				TableCellMouseEvent event = createMouseEvent(cell, e,
+						TableCellMouseEvent.EVENT_MOUSEMOVE, false);
+				if (event != null) {
+					TableColumnCore tc = ((TableColumnCore) cell.getTableColumn());
+					if (tc.hasCellMouseMoveListener()) {
+						((TableColumnCore) cell.getTableColumn()).invokeCellMouseListeners(event);
+					}
+					cell.invokeMouseListeners(event);
+
+					// listener might have changed it
+
+					int cellCursorID = cell.getCursorID();
+					if (cellCursorID != -1) {
+						lastCursorID = cellCursorID;
+					}
+				}
+			}
+		} catch (Exception ex) {
+			Debug.out(ex);
+		}
+	}
+
+	public void widgetSelected(SelectionEvent e) {
+	}
+
+	public void widgetDefaultSelected(SelectionEvent e) {
+		if (lCancelSelectionTriggeredOn > 0
+				&& System.currentTimeMillis() - lCancelSelectionTriggeredOn < 200) {
+			e.doit = false;
+		} else {
+			runDefaultAction(e.stateMask);
+		}
+	}
+
+	public void keyPressed(KeyEvent event) {
+		// Note: Both table key presses and txtFilter keypresses go through this
+		//       method.
+
+		TableViewSWTFilter<?> filter = tv.getSWTFilter();
+		if (event.widget != null && filter != null && event.widget == filter.widget) {
+			if (event.character == SWT.DEL || event.character == SWT.BS) {
+				handleSearchKeyPress(event);
+				return;
+			}
+		}
+
+		KeyListener[] listeners = tv.getKeyListeners();
+		for (KeyListener l : listeners) {
+			l.keyPressed(event);
+			if (!event.doit) {
+				lCancelSelectionTriggeredOn = SystemTime.getCurrentTime();
+				return;
+			}
+		}
+
+		if (event.keyCode == SWT.F5) {
+			if ((event.stateMask & SWT.SHIFT) > 0) {
+				tv.runForSelectedRows(new TableGroupRowRunner() {
+					public void run(TableRowCore row) {
+						row.invalidate();
+						row.refresh(true);
+					}
+				});
+			} else if ((event.stateMask & SWT.CONTROL) > 0) {
+				tv.runForAllRows(new TableGroupRowRunner() {
+					public void run(TableRowCore row) {
+						row.invalidate();
+						row.refresh(true);
+					}
+				});
+			} else {
+				tv.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 (!tv.isSingleSelection()) {
+							tv.selectAll();
+							event.doit = false;
+						}
+					} else {
+						filter.widget.selectAll();
+						event.doit = false;
+					}
+				}
+				break;
+
+				case '+': {
+					if (Constants.isUnix) {
+						tv.expandColumns();
+						event.doit = false;
+					}
+					break;
+				}
+				case 'f': // CTRL+F Find/Filter
+					tv.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);
+						validateFilterRegex();
+						tv.refilter();
+						return;
+					}
+				}
+					break;
+				case 'g':
+					System.out.println("force sort");
+					tv.resetLastSortedOn();
+					tv.sortColumn(true);
+					break;
+			}
+
+		}
+
+		if (event.stateMask == 0) {
+			if (filter != null && filter.widget == event.widget) {
+				if (event.keyCode == SWT.ARROW_DOWN) {
+					tv.setFocus();
+					event.doit = false;
+				} else if (event.character == 13) {
+					tv.refilter();
+				}
+			}
+		}
+
+		if (!event.doit) {
+			return;
+		}
+
+		handleSearchKeyPress(event);
+	}
+	
+	private void handleSearchKeyPress(KeyEvent e) {
+		TableViewSWTFilter<?> filter = tv.getSWTFilter();
+		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 > 32 && e.character != SWT.DEL) {
+			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();
+			}
+			tv.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;
+	}
+
+	private void
+	validateFilterRegex()
+	{
+		TableViewSWTFilter<?> filter = tv.getSWTFilter();
+		if (filter.regex) {
+			if ( FONT_NO_REGEX == null ){
+				FONT_NO_REGEX = filter.widget.getFont();
+				FontData[] fd = FONT_NO_REGEX.getFontData();
+				for (int i = 0; i < fd.length; i++) {
+					fd[i].setStyle(SWT.BOLD);
+				}
+				FONT_REGEX = new Font( filter.widget.getDisplay(), fd );
+				for (int i = 0; i < fd.length; i++) {
+					fd[i].setStyle(SWT.ITALIC);
+				}
+				FONT_REGEX_ERROR = new Font( filter.widget.getDisplay(), fd );
+			}
+			try {
+				Pattern.compile(filter.nextText, Pattern.CASE_INSENSITIVE);
+				filter.widget.setBackground(COLOR_FILTER_REGEX);
+				filter.widget.setFont( FONT_REGEX );
+				
+				Messages.setLanguageTooltip(filter.widget,
+						"MyTorrentsView.filter.tooltip");
+			} catch (Exception e) {
+				filter.widget.setBackground(Colors.colorErrorBG);
+				filter.widget.setToolTipText(e.getMessage());
+				filter.widget.setFont( FONT_REGEX_ERROR );
+			}
+		} else {
+			filter.widget.setBackground(null);
+			Messages.setLanguageTooltip(filter.widget,
+					"MyTorrentsView.filter.tooltip");
+			if ( FONT_NO_REGEX != null ){
+				filter.widget.setFont( FONT_NO_REGEX );
+			}
+		}
+	}
+	
+	public void setFilterText(String s) {
+		TableViewSWTFilter<?> filter = tv.getSWTFilter();
+		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());
+			}
+
+			validateFilterRegex();
+		}
+
+		if (filter.eventUpdate != null) {
+			filter.eventUpdate.cancel();
+		}
+		filter.eventUpdate = SimpleTimer.addEvent("SearchUpdate",
+				SystemTime.getOffsetTime(ASYOUTYPE_UPDATEDELAY),
+				new TimerEventPerformer() {
+					public void perform(TimerEvent event) {
+						TableViewSWTFilter<?> filter = tv.getSWTFilter();
+
+						if (filter == null) {
+							return;
+						}
+						if (filter.eventUpdate == null || 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);
+							tv.refilter();
+						}
+					}
+				});
+	}
+
+	public void runDefaultAction(int stateMask) {
+		// Don't allow mutliple run defaults in quick succession
+		if (lastSelectionTriggeredOn > 0
+				&& System.currentTimeMillis() - lastSelectionTriggeredOn < 200) {
+			return;
+		}
+		
+		// plugin may have cancelled the default action
+		if (System.currentTimeMillis() - lCancelSelectionTriggeredOn > 200) {
+			lastSelectionTriggeredOn = System.currentTimeMillis();
+			TableRowCore[] selectedRows = tv.getSelectedRows();
+			tv.triggerDefaultSelectedListeners(selectedRows, stateMask);
+		}
+	}
+
+	public void keyReleased(KeyEvent event) {
+		KeyListener[] listeners = tv.getKeyListeners();
+		for (KeyListener l : listeners) {
+			l.keyReleased(event);
+			if (!event.doit) {
+				return;
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addKeyListener(org.eclipse.swt.events.KeyListener)
+	 */
+	public void addKeyListener(KeyListener listener) {
+		if (listenersKey.contains(listener)) {
+			return;
+		}
+
+		listenersKey.add(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeKeyListener(org.eclipse.swt.events.KeyListener)
+	 */
+	public void removeKeyListener(KeyListener listener) {
+		listenersKey.remove(listener);
+	}
+	
+	public KeyListener[] getKeyListeners() {
+		return listenersKey.toArray(new KeyListener[0]);
+	}
+
+	public void addRowMouseListener(TableRowMouseListener listener) {
+		try {
+			mon_RowMouseListener.enter();
+
+			if (rowMouseListeners == null)
+				rowMouseListeners = new ArrayList<TableRowMouseListener>(1);
+
+			rowMouseListeners.add(listener);
+
+		} finally {
+			mon_RowMouseListener.exit();
+		}
+	}
+
+	public void removeRowMouseListener(TableRowMouseListener listener) {
+		try {
+			mon_RowMouseListener.enter();
+
+			if (rowMouseListeners == null)
+				return;
+
+			rowMouseListeners.remove(listener);
+
+		} finally {
+			mon_RowMouseListener.exit();
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#invokeRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
+	 */
+	public void invokeRowMouseListener(TableRowMouseEvent event) {
+		if (rowMouseListeners == null) {
+			return;
+		}
+		ArrayList<TableRowMouseListener> listeners = new ArrayList<TableRowMouseListener>(
+				rowMouseListeners);
+
+		for (int i = 0; i < listeners.size(); i++) {
+			try {
+				TableRowMouseListener l = (listeners.get(i));
+
+				l.rowMouseTrigger(event);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void addRowPaintListener(TableRowSWTPaintListener listener) {
+		try {
+			mon_RowPaintListener.enter();
+
+			if (rowPaintListeners == null)
+				rowPaintListeners = new ArrayList<TableRowSWTPaintListener>(1);
+
+			rowPaintListeners.add(listener);
+
+		} finally {
+			mon_RowPaintListener.exit();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void removeRowPaintListener(TableRowSWTPaintListener listener) {
+		try {
+			mon_RowPaintListener.enter();
+
+			if (rowPaintListeners == null)
+				return;
+
+			rowPaintListeners.remove(listener);
+
+		} finally {
+			mon_RowPaintListener.exit();
+		}
+	}
+
+	public void invokePaintListeners(GC gc, TableRowCore row,
+			TableColumnCore column, Rectangle cellArea) {
+
+		if (rowPaintListeners == null) {
+			return;
+		}
+		ArrayList<TableRowSWTPaintListener> listeners = new ArrayList<TableRowSWTPaintListener>(
+				rowPaintListeners);
+
+		for (int i = 0; i < listeners.size(); i++) {
+			try {
+				TableRowSWTPaintListener l = (listeners.get(i));
+
+				l.rowPaint(gc, row, column, cellArea);
+
+			} catch (Throwable e) {
+				Debug.printStackTrace(e);
+			}
+		}
+	}
+
+	/** Fill the Context Menu with items.  Called when menu is about to be shown.
+	 *
+	 * By default, a "Edit Columns" menu and a Column specific menu is set up.
+	 *
+	 * @param menu Menu to fill
+	 * @param tcColumn 
+	 */
+	public void fillMenu(final Menu menu, final TableColumnCore column) {
+		String columnName = column == null ? null : column.getName();
+
+		Object[] listeners = listenersMenuFill.toArray();
+		for (int i = 0; i < listeners.length; i++) {
+			TableViewSWTMenuFillListener l = (TableViewSWTMenuFillListener) listeners[i];
+			l.fillMenu(columnName, menu);
+		}
+
+		boolean hasLevel1 = false;
+		boolean hasLevel2 = false;
+		// quick hack so we don't show plugin menus on selections of subitems
+		TableRowCore[] selectedRows = tv.getSelectedRows();
+		for (TableRowCore row : selectedRows) {
+			if (row.getParentRowCore() != null) {
+				hasLevel2 = true;
+			} else {
+				hasLevel1 = true;
+			}
+		}
+		
+		String tableID = tv.getTableID();
+		String sMenuID = hasLevel1 ? tableID : TableManager.TABLE_TORRENT_FILES;
+		
+		// Add Plugin Context menus..
+		boolean enable_items = selectedRows.length > 0;
+
+		TableContextMenuItem[] items = TableContextMenuManager.getInstance().getAllAsArray(
+				sMenuID);
+
+		// We'll add download-context specific menu items - if the table is download specific.
+		// We need a better way to determine this...
+		org.gudy.azureus2.plugins.ui.menus.MenuItem[] menu_items = null;
+		if ("MySeeders".equals(tableID) || "MyTorrents".equals(tableID)) {
+			menu_items = MenuItemManager.getInstance().getAllAsArray(
+					"download_context");
+		} else {
+			menu_items = MenuItemManager.getInstance().getAllAsArray((String) null);
+		}
+		
+		if (columnName == null) {
+			MenuItem itemChangeTable = new MenuItem(menu, SWT.PUSH);
+			Messages.setLanguageText(itemChangeTable,
+					"MyTorrentsView.menu.editTableColumns");
+			Utils.setMenuItemImage(itemChangeTable, "columns");
+
+			itemChangeTable.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event e) {
+					showColumnEditor();
+				}
+			});
+
+		} else {
+
+ 		MenuItem item = new MenuItem(menu, SWT.PUSH);
+ 		Messages.setLanguageText(item, "MyTorrentsView.menu.thisColumn.toClipboard");
+ 		item.addListener(SWT.Selection, new Listener() {
+ 			public void handleEvent(Event e) {
+ 				String sToClipboard = "";
+ 				if (column == null) {
+ 					return;
+ 				}
+ 				String columnName = column.getName();
+ 				if (columnName == null) {
+ 					return;
+ 				}
+ 				TableRowCore[] rows = tv.getSelectedRows();
+ 				for (TableRowCore row : rows) {
+ 					if (row != rows[0]) {
+ 						sToClipboard += "\n";
+ 					}
+ 					TableCellCore cell = row.getTableCellCore(columnName);
+ 					if (cell != null) {
+ 						sToClipboard += cell.getClipboardText();
+ 					}
+ 				}
+ 				if (sToClipboard.length() == 0) {
+ 					return;
+ 				}
+ 				new Clipboard(Display.getDefault()).setContents(new Object[] {
+ 					sToClipboard
+ 				}, new Transfer[] {
+ 					TextTransfer.getInstance()
+ 				});
+ 			}
+ 		});
+		}
+		
+		if (items.length > 0 || menu_items.length > 0) {
+			new org.eclipse.swt.widgets.MenuItem(menu, SWT.SEPARATOR);
+
+			// Add download context menu items.
+			if (menu_items != null) {
+				// getSelectedDataSources(false) returns us plugin items.
+				MenuBuildUtils.addPluginMenuItems(tv.getComposite(), menu_items, menu,
+						true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
+								tv.getSelectedDataSources(false)));
+			}
+
+			if (items.length > 0) {
+				MenuBuildUtils.addPluginMenuItems(tv.getComposite(), items, menu, true,
+						enable_items, new MenuBuildUtils.PluginMenuController() {
+							public Listener makeSelectionListener(
+									final org.gudy.azureus2.plugins.ui.menus.MenuItem plugin_menu_item) {
+								return new TableSelectedRowsListener(tv, false) {
+									public boolean run(TableRowCore[] rows) {
+										if (rows.length != 0) {
+											((TableContextMenuItemImpl) plugin_menu_item).invokeListenersMulti(rows);
+										}
+										return true;
+									}
+								};
+							}
+
+							public void notifyFillListeners(
+									org.gudy.azureus2.plugins.ui.menus.MenuItem menu_item) {
+								((TableContextMenuItemImpl) menu_item).invokeMenuWillBeShownListeners(tv.getSelectedRows());
+							}
+						});
+			}
+		}
+		
+		if (hasLevel1) {
+		// Add Plugin Context menus..
+		if (column != null) {
+ 		TableContextMenuItem[] columnItems = column.getContextMenuItems(TableColumnCore.MENU_STYLE_COLUMN_DATA);
+ 		if (columnItems.length > 0) {
+ 			new MenuItem(menu, SWT.SEPARATOR);
+ 
+ 			MenuBuildUtils.addPluginMenuItems(tv.getComposite(), columnItems, menu,
+ 					true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
+ 							tv.getSelectedDataSources(true)));
+ 
+ 		}
+		}
+
+		if (tv.getSWTFilter() != 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) {
+ 				tv.openFilterDialog();
+ 			}
+ 		});
+		}
+		}
+	}
+
+	public void showColumnEditor() {
+		TableRowCore focusedRow = tv.getFocusedRow();
+		if (focusedRow == null || focusedRow.isRowDisposed()) {
+			focusedRow = tv.getRow(0);
+		}
+		String tableID = tv.getTableID();
+		new TableColumnSetupWindow(tv.getDataSourceType(), tableID, focusedRow,
+				TableStructureEventDispatcher.getInstance(tableID)).open();
+	}
+
+
+	/**
+	 * SubMenu for column specific tasks. 
+	 *
+	 * @param iColumn Column # that tasks apply to.
+	 */
+	public void fillColumnMenu(final Menu menu, final TableColumnCore column,
+			boolean isBlankArea) {
+		String tableID = tv.getTableID();
+		if (!isBlankArea) {
+			TableColumnManager tcm = TableColumnManager.getInstance();
+			TableColumnCore[] allTableColumns = tcm.getAllTableColumnCoreAsArray(
+					tv.getDataSourceType(), tableID);
+
+			Arrays.sort(allTableColumns,
+					TableColumnManager.getTableColumnOrderComparator());
+
+			for (final TableColumnCore tc : allTableColumns) {
+				boolean visible = tc.isVisible();
+				if (!visible) {
+					TableColumnInfo columnInfo = tcm.getColumnInfo(
+							tv.getDataSourceType(), tableID, tc.getName());
+					if (columnInfo.getProficiency() != TableColumnInfo.PROFICIENCY_BEGINNER) {
+						continue;
+					}
+				}
+				MenuItem menuItem = new MenuItem(menu, SWT.CHECK);
+				Messages.setLanguageText(menuItem, tc.getTitleLanguageKey());
+				if (visible) {
+					menuItem.setSelection(true);
+				}
+				menuItem.addListener(SWT.Selection, new Listener() {
+					public void handleEvent(Event e) {
+						tc.setVisible(!tc.isVisible());
+						if (tv instanceof TableStructureModificationListener) {
+							((TableStructureModificationListener) tv).tableStructureChanged(
+									true, null);
+						}
+					}
+				});
+			}
+		}
+
+		if (menu.getItemCount() > 0) {
+			new MenuItem(menu, SWT.SEPARATOR);
+		}
+
+		final MenuItem itemResetColumns = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemResetColumns, "table.columns.reset");
+		itemResetColumns.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event e) {
+				String tableID = tv.getTableID();
+				TableColumnManager tcm = TableColumnManager.getInstance();
+				String[] defaultColumnNames = tcm.getDefaultColumnNames(tableID);
+				if (defaultColumnNames != null) {
+					TableColumnCore[] tableColumns = tv.getVisibleColumns();
+					for (TableColumnCore column : tableColumns) {
+						column.setVisible(false);
+					}
+					int i = 0;
+					for (String name : defaultColumnNames) {
+						TableColumnCore column = tcm.getTableColumnCore(tableID, name);
+						if (column != null) {
+							column.reset();
+							column.setVisible(true);
+							column.setPositionNoShift(i++);
+						}
+					}
+					tcm.saveTableColumns(tv.getDataSourceType(), tableID);
+					TableStructureEventDispatcher.getInstance(tableID).tableStructureChanged(true, tv.getDataSourceType());
+				}
+			}
+		});
+
+
+		final MenuItem itemChangeTable = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemChangeTable,
+				"MyTorrentsView.menu.editTableColumns");
+		Utils.setMenuItemImage(itemChangeTable, "columns");
+
+		itemChangeTable.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event e) {
+				showColumnEditor();
+			}
+		});
+
+		if (menu != null) {
+			menu.setData("column", column);
+		}
+		
+		if (column == null) {
+			return;
+		}
+
+		String sColumnName = column.getName();
+		if (sColumnName != null) {
+			Object[] listeners = listenersMenuFill.toArray();
+			for (int i = 0; i < listeners.length; i++) {
+				TableViewSWTMenuFillListener l = (TableViewSWTMenuFillListener) listeners[i];
+				l.addThisColumnSubMenu(sColumnName, menu);
+			}
+		}
+
+		final MenuItem at_item = new MenuItem(menu, SWT.CHECK);
+		Messages.setLanguageText(at_item,
+				"MyTorrentsView.menu.thisColumn.autoTooltip");
+		at_item.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event e) {
+				TableColumnCore tcc = (TableColumnCore) menu.getData("column");
+				tcc.setAutoTooltip(at_item.getSelection());
+				tcc.invalidateCells();
+			}
+		});
+		at_item.setSelection(column.doesAutoTooltip());
+
+
+		// Add Plugin Context menus..
+		TableContextMenuItem[] items = column.getContextMenuItems(TableColumnCore.MENU_STYLE_HEADER);
+		if (items.length > 0) {
+			new MenuItem(menu, SWT.SEPARATOR);
+
+			MenuBuildUtils.addPluginMenuItems(tv.getComposite(), items, menu,
+					true, true, new MenuBuildUtils.MenuItemPluginMenuControllerImpl(
+							tv.getSelectedDataSources(true)));
+
+		}
+	}
+
+	public void addMenuFillListener(TableViewSWTMenuFillListener l) {
+		listenersMenuFill.add(l);
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_EraseItem.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_EraseItem.java
new file mode 100644
index 0000000..36122df
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_EraseItem.java
@@ -0,0 +1,235 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Widget;
+
+import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+import org.gudy.azureus2.ui.swt.mainwindow.HSLColor;
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+
+public class TableViewSWT_EraseItem
+	implements Listener
+{
+	final static public Color[] alternatingColors = new Color[] {
+		null,
+		Colors.colorAltRow
+	};
+
+	private final TableOrTreeSWT table;
+	
+	private TableViewSWTImpl<?> tv;
+	
+	private boolean drawExtended;
+	
+	private boolean first = true;
+
+	private static Color colorLine;
+	
+	public TableViewSWT_EraseItem(TableViewSWTImpl<?> _tv, TableOrTreeSWT table) {
+		this.table = table;
+		this.tv = _tv;
+		COConfigurationManager.addAndFireParameterListener("Table.extendedErase",
+				new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						Utils.execSWTThread(new AERunnable() {
+							public void runSupport() {
+								drawExtended = COConfigurationManager.getBooleanParameter("Table.extendedErase");
+								if (!first) {
+									Rectangle bounds = tv.getTableOrTreeSWT().getBounds();
+									tv.getTableOrTreeSWT().redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
+								}
+								first = false;
+							}
+						});
+					}
+				});
+
+		if (colorLine == null) {
+  		colorLine = tv.getComposite().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+  		HSLColor hslColor = new HSLColor();
+  		hslColor.initHSLbyRGB(colorLine.getRed(), colorLine.getGreen(),
+  				colorLine.getBlue());
+  
+  		int lum = hslColor.getLuminence();
+  		if (lum > 127)
+  			lum -= 25;
+  		else
+  			lum += 40;
+  		hslColor.setLuminence(lum);
+  		
+  		colorLine = new Color(tv.getComposite().getDisplay(), hslColor.getRed(), hslColor.getGreen(), hslColor.getBlue());
+		}
+
+		/* Background image badly slows down tree drawing
+		int itemHeight = table.getItemHeight() + 1;
+		int height = 1920;
+		Image image = new Image(table.getComposite().getDisplay(), 10, height);
+		GC gc = new GC(image);
+		int y = table.getHeaderHeight();
+		while (y < height) {
+			gc.setBackground(table.getBackground());
+			gc.fillRectangle(0, y, 10, itemHeight);
+			gc.setBackground(alternatingColors[1]);
+			gc.fillRectangle(0, y + itemHeight, 10, itemHeight);
+			y += itemHeight * 2;
+		}
+		gc.dispose();
+		table.setBackgroundImage(image);
+		*/
+	}
+	
+	public void handleEvent(Event event) {
+		if (event.type == SWT.EraseItem) {
+			TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item);
+			eraseItem(event, event.gc, item, event.index, drawExtended, item.getBounds(event.index), tv, false);
+		} else if (drawExtended) {
+			paint(event);
+		}
+	}
+
+	private void paint(Event event) {
+		//System.out.println("paint " + event.getBounds() + ";" + table.getColumnCount());
+		int numItems = table.getItemCount();
+		int rowHeight = table.getItemHeight();
+		int height = rowHeight * numItems;
+		int rowAreaHeight = tv.clientArea.height + tv.clientArea.y;
+
+		int blankHeight = rowAreaHeight - height;
+		if (blankHeight > 0) {
+			int startY;
+			if (numItems > 0) {
+				TableItemOrTreeItem lastItem = table.getItem(numItems - 1);
+					// dunno how, but I have a stacktrace with an NPE caused by lastItem being null (even though numItems > 0 ...)
+				if ( lastItem != null ){
+					Rectangle lastItemBounds;
+					if (lastItem.getExpanded()) {
+	  				TableItemOrTreeItem[] subItems = lastItem.getItems();
+	  				lastItemBounds = subItems == null || subItems.length == 0
+	  						? lastItem.getBounds() : subItems[subItems.length - 1].getBounds();
+					} else {
+						lastItemBounds = lastItem.getBounds();
+					}
+					startY = lastItemBounds.y + lastItemBounds.height;
+				}else{
+					startY = 0;
+				}
+			} else {
+				startY = 0;
+			}
+			//if (event.width == tv.clientArea.width && event.height < blankHeight) {
+			//	System.out.println("MOO");
+			//	table.redraw(tv.clientArea.x, startY, tv.clientArea.width, blankHeight, false);
+			//	return;
+			//}
+			//System.out.println("numItems=" + numItems + ";" + startY);
+			GC gc = event.gc;
+			gc.setClipping((Rectangle) null);
+			for (int i = 0; i < blankHeight / rowHeight; i++) {
+				int curY = (startY + (i * rowHeight));
+				int pos = (i + numItems) % 2;
+				//System.out.println(i + "==" + pos + " for " + (startY + (i * rowHeight)));
+				Color color = i <= -1 ? ColorCache.getRandomColor() : alternatingColors[pos];
+				if (color == null) {
+					//color = event.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+					continue;
+				}
+				gc.setBackground(color);
+				gc.fillRectangle(tv.clientArea.x, startY + (i * rowHeight),
+						tv.clientArea.width, rowHeight);
+			}
+
+			// Vertical lines between columns
+			if (TableViewSWTImpl.DRAW_VERTICAL_LINES) {
+				TableColumnOrTreeColumn[] columns = table.getColumns();
+				int pos = 0;
+				//gc.setForeground(ColorCache.getColor(event.display, 245, 245, 245));
+
+				gc.setForeground(Colors.black);
+				gc.setAdvanced(true);
+				gc.setAlpha(10);
+				for (TableColumnOrTreeColumn tc : columns) {
+					gc.drawLine(pos - 1, startY, pos - 1, startY + blankHeight);
+					pos += tc.getWidth();
+				}
+				gc.drawLine(pos - 1, startY, pos - 1, startY + blankHeight);
+			}
+		}
+	}
+
+	public static void eraseItem(Event event, GC gc, TableItemOrTreeItem item,
+			int columnNo, boolean drawExtended, Rectangle bounds, TableViewSWTImpl<?> tv, boolean alwaysDrawBG) {
+
+		TableOrTreeSWT table = tv.getTableOrTreeSWT();
+
+		if (event == null || (event.detail & (SWT.HOT | SWT.SELECTED | SWT.FOCUSED)) == 0) {
+
+			int pos;
+			TableItemOrTreeItem parentItem = item.getParentItem();
+			if (parentItem != null) {
+				pos = parentItem.indexOf(item) + ((table.indexOf(parentItem) + 1) % 2);
+			} else {
+				pos = table.indexOf(item);
+			}
+			Color color = alternatingColors[pos % 2];
+			if (color != null) {
+				gc.setBackground(color);
+				if (parentItem != null) {
+					gc.setAlpha(128);
+				}
+			}
+			Rectangle drawBounds = bounds;
+			if (TableViewSWTImpl.DRAW_FULL_ROW && drawExtended
+					&& columnNo == table.getColumnCount() - 1) {
+				tv.swt_calculateClientArea();
+				drawBounds = new Rectangle(bounds.x, bounds.y, tv.clientArea.x
+						+ tv.clientArea.width - bounds.x, bounds.height);
+				gc.setClipping(drawBounds);
+				//System.out.println(bounds.width);
+			}
+			if (alwaysDrawBG || color != null) {
+				if (color == null) {
+					gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
+				}
+				gc.fillRectangle(drawBounds);
+				if (event != null) {
+					event.detail &= ~SWT.BACKGROUND;
+				}
+			}
+		}
+		
+		if (event != null && (event.detail & SWT.SELECTED) > 0 && !table.isFocusControl()) {
+			gc.setBackground(Colors.blues[3]);
+			gc.fillRectangle(bounds);
+			if (event != null) {
+				event.detail &= ~SWT.BACKGROUND;
+			}
+		}
+
+		// Vertical lines between columns
+		if (TableViewSWTImpl.DRAW_VERTICAL_LINES && drawExtended && colorLine != null) {
+			if (item != null
+					&& (bounds.width == item.getParent().getColumn(columnNo).getWidth())
+					&& bounds.width > 0) {
+				Color fg = gc.getForeground();
+				gc.setForeground(colorLine);
+				// needed because windows shifts the area over, dragging our old line
+				// around.  Clear clipping so we can erase it
+				gc.setClipping((Rectangle) null);
+				gc.drawLine(bounds.x + bounds.width - 1, bounds.y - 1, bounds.x
+						+ bounds.width - 1, bounds.y + bounds.height);
+				gc.setForeground(fg);
+			}
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_PaintItem.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_PaintItem.java
new file mode 100644
index 0000000..9cdef39
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_PaintItem.java
@@ -0,0 +1,459 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import java.util.Random;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+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.tables.TableColumn;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.BufferedGraphicTableItem;
+import org.gudy.azureus2.ui.swt.components.BufferedTableItem;
+import org.gudy.azureus2.ui.swt.components.InPaintInfo;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.views.table.*;
+import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
+
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+
+public class TableViewSWT_PaintItem
+	implements Listener
+{
+	Widget lastItem;
+
+	int lastRowIndex = -1;
+
+	private final TableOrTreeSWT table;
+
+	private TableViewSWTImpl<?> tv;
+
+	private boolean bSkipFirstColumn;
+
+	public TableViewSWT_PaintItem(TableViewSWTImpl<?> tv, TableOrTreeSWT table) {
+		this.table = table;
+		this.tv = tv;
+	}
+
+	private int[] getColumnRange(TableItemOrTreeItem ti, int iMouseX, int width) {
+		int[] columnRange = {
+			-1,
+			-1
+		};
+		int numColumns = table.getColumnCount();
+		if (numColumns <= 0) {
+			return columnRange;
+		}
+		for (int i = bSkipFirstColumn ? 1 : 0; i < numColumns; i++) {
+			Rectangle cellBounds = ti.getBounds(i);
+			if (iMouseX >= cellBounds.x && iMouseX < cellBounds.x + cellBounds.width
+					&& cellBounds.width > 0) {
+				columnRange[0] = i;
+				break;
+			}
+		}
+
+		if (columnRange[0] == -1) {
+			return columnRange;
+		}
+
+		if (columnRange[0] + 1 == numColumns) {
+			columnRange[1] = columnRange[0];
+		} else {
+
+			int end = iMouseX + width;
+			for (int i = columnRange[0] + 1; i < numColumns; i++) {
+				Rectangle cellBounds = ti.getBounds(i);
+				//System.out.println(cellBounds + ";" + end);
+				if (cellBounds.x > end && cellBounds.width > 0) {
+					columnRange[1] = i - 1;
+					break;
+				}
+			}
+			if (columnRange[1] == -1) {
+				columnRange[1] = numColumns - 1;
+			}
+		}
+
+		return columnRange;
+	}
+
+	public void handleEvent(Event event) {
+
+		if (event.gc.getClipping().isEmpty()) {
+			return;
+		}
+
+		if (!table.isEnabled()) {
+			// added disable affect
+			event.gc.setAlpha(100);
+		}
+
+		if (event.type == SWT.Paint) {
+			int numPainted = 0;
+			//Color fg = event.gc.getForeground();
+			//Color bg = event.gc.getBackground();
+			Region r = new Region();
+			event.gc.getClipping(r);
+			//System.out.println(r.contains(event.x, event.y));
+			//event.gc.setForeground(ColorCache.getRandomColor());
+			//event.gc.drawRectangle(event.x, event.y, event.width - 1, event.height - 1);
+			//event.gc.setForeground(fg);
+			// paint only gets bounds, gotta fill event.item and event.index
+			TableItemOrTreeItem item = table.getItem(new Point(5, event.y));
+			if (item == null) {
+				return;
+			}
+			event.item = item.getItem();
+			int[] columnRange = getColumnRange(item, event.x, event.width);
+			if (columnRange[0] == -1) {
+				return;
+			}
+
+			int height = tv.getRowDefaultHeight();
+
+			//System.out.println("Dirty: " + event.getBounds() + "; +" + height + "; " + event.gc.getClipping());
+			for (int i = columnRange[0]; i <= columnRange[1]; i++) {
+				event.index = i;
+
+
+				for (int y = event.y; y < (event.y + event.height); y += item.getBounds().height) {
+					item = table.getItem(new Point(5, y));
+					if (item == null) {
+						break;
+					}
+					Rectangle bounds = item.getBounds(i);
+					if (!r.intersects(bounds)) {
+						//event.gc.setForeground(ColorCache.getRandomColor());
+						//event.gc.
+						continue;
+					}
+					event.item = item.getItem();
+					//System.out.println(table.indexOf(event.item) + ": " + i);
+
+					
+					table.setData("inPaintInfo", new InPaintInfo(item.getItem(), event.index, bounds));
+
+					if (event.item != lastItem) {
+						table.setData("lastIndex", null);
+						lastRowIndex = table.indexOf(event.item);
+						table.setData("lastIndex", lastRowIndex);
+					}
+
+					boolean doErase = true;
+					if (Constants.isWindows7OrHigher) {
+						Point location = table.toControl(event.display.getCursorLocation());
+						if (location.y >= bounds.y && location.y < bounds.y + bounds.height) {
+							doErase = false;
+						}
+					}
+
+					Font f = event.gc.getFont();
+					if (doErase) {
+						//TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item);
+						TableViewSWT_EraseItem.eraseItem(event, event.gc, item, event.index, true, bounds, tv, true);
+					}
+					//TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item);
+					paintItem(event.gc, (TableRowSWT) tv.getRow(item), event.index, lastRowIndex, bounds, tv, false);
+					event.gc.setFont(f);
+					event.gc.setClipping(r);
+					
+					numPainted++;
+
+					lastItem = event.item;
+				}
+
+			}
+			
+			//System.out.println("# Painted:" + numPainted);
+
+		} else {
+			TableItemOrTreeItem item = TableOrTreeUtils.getEventItem(event.item);
+			Rectangle bounds = item.getBounds(event.index);
+
+			table.setData("inPaintInfo", new InPaintInfo((Item) event.item, event.index, bounds));
+
+			if (event.item != lastItem) {
+				table.setData("lastIndex", null);
+				lastRowIndex = table.indexOf(event.item);
+				table.setData("lastIndex", lastRowIndex);
+			}
+
+			//visibleRowsChanged();
+			paintItem(event.gc, (TableRowSWT) tv.getRow(item), event.index, lastRowIndex, bounds, tv, false);
+
+			lastItem = event.item;
+		}
+
+		table.setData("inPaintInfo", null);
+		table.setData("lastIndex", null);
+	}
+
+	/**
+	 * @param event
+	 * @param rowIndex 
+	 */
+	public static void paintItem(GC gc, TableRowSWT row, int columnIndex,
+			int rowIndex, Rectangle _cellBounds, TableViewSWT<?> tv, boolean skipClipCalc) {
+		//if (columnIndex == 1 && rowIndex == 0) {
+		//	System.out.println("paintItem " + gc.getClipping() +":" + rowIndex + ":" + columnIndex + ": " + Debug.getCompressedStackTrace());
+		//}
+		try {
+			//System.out.println(gc.getForeground().getRGB().toString());
+			//System.out.println("paintItem " + gc.getClipping());
+			if (TableViewSWTImpl.DEBUG_CELL_CHANGES) {
+				Random random = new Random(SystemTime.getCurrentTime() / 500);
+				gc.setBackground(ColorCache.getColor(gc.getDevice(),
+						210 + random.nextInt(45), 210 + random.nextInt(45),
+						210 + random.nextInt(45)));
+				gc.fillRectangle(gc.getClipping());
+			}
+
+			if (row == null || row.isRowDisposed()) {
+				return;
+			}
+			int iColumnNo = columnIndex;
+
+			//System.out.println(SystemTime.getCurrentTime() + "] paintItem " + rowIndex + ":" + iColumnNo);
+			if ((tv instanceof TableViewSWTImpl) && ((TableViewSWTImpl)tv).bSkipFirstColumn) {
+				if (iColumnNo == 0) {
+					return;
+				}
+				iColumnNo--;
+			}
+
+			TableColumnCore[] columnsOrdered = tv.getVisibleColumns();
+
+			if (iColumnNo >= columnsOrdered.length) {
+				System.out.println("Col #" + iColumnNo + " >= " + columnsOrdered.length
+						+ " count");
+				return;
+			}
+
+			if (!tv.isColumnVisible(columnsOrdered[iColumnNo])) {
+				System.out.println("col not visible " + iColumnNo);
+				return;
+			}
+
+			//if (rowIndex < tv.lastTopIndex || rowIndex > tv.lastBottomIndex) {
+			// this refreshes whole row (perhaps multiple), saving the many
+			// cell.refresh calls later because !cell.isUpToDate()
+			//tv.visibleRowsChanged();
+			//}
+
+			Rectangle cellBounds = new Rectangle(_cellBounds.x, _cellBounds.y, _cellBounds.width, _cellBounds.height); // item.getBounds(columnIndex);
+
+			//System.out.println("cb=" + cellBounds + ";b=" + event.getBounds() + ";clip=" + gc.getClipping());
+			Rectangle origClipping = gc.getClipping();
+
+			TableOrTreeSWT table = tv.getTableOrTreeSWT();
+			if (table != null) {
+  			if (origClipping.isEmpty()
+  					|| (origClipping.width >= cellBounds.width && origClipping.height >= cellBounds.height)) {
+  				table.setData("fullPaint", Boolean.TRUE);
+  			} else {
+  				table.setData("fullPaint", Boolean.FALSE);
+  				//System.out.println("not full paint: " + origClipping + ";cellbounds=" + cellBounds);
+  			}
+			}
+
+			if (!tv.isRowVisible(row)) {
+				tv.visibleRowsChanged();
+			}
+
+			tv.invokePaintListeners(gc, row, columnsOrdered[iColumnNo], cellBounds);
+
+			int rowAlpha = row.getAlpha();
+
+			int fontStyle = row.getFontStyle();
+			if (fontStyle == SWT.BOLD) {
+				gc.setFont(FontUtils.getAnyFontBold(gc));
+			}
+
+			//if (item.getImage(columnIndex) != null) {
+			//	cellBounds.x += 18;
+			//	cellBounds.width -= 18;
+			//}
+
+			if (cellBounds.width <= 0 || cellBounds.height <= 0) {
+				//System.out.println("no bounds");
+				return;
+			}
+
+			TableCellSWT cell = row.getTableCellSWT(columnsOrdered[iColumnNo].getName());
+
+			if (cell == null) {
+				return;
+			}
+
+			if (!cell.isUpToDate()) {
+				//System.out.println("R " + rowIndex + ":" + iColumnNo);
+				cell.refresh(true, true);
+				//return;
+			}
+
+			String text = cell.getText();
+
+			if (!skipClipCalc) {
+				Rectangle clipping = new Rectangle(cellBounds.x, cellBounds.y,
+  					cellBounds.width, cellBounds.height);
+  			// Cocoa calls paintitem while row is below tablearea, and painting there
+  			// is valid!
+  			if (!Utils.isCocoa && (tv instanceof TableViewSWTImpl)) {
+  				int iMinY = ((TableViewSWTImpl) tv).headerHeight + ((TableViewSWTImpl) tv).clientArea.y;
+  
+  				if (clipping.y < iMinY) {
+  					clipping.height -= iMinY - clipping.y;
+  					clipping.y = iMinY;
+  				}
+  				int iMaxY = ((TableViewSWTImpl) tv).clientArea.height + ((TableViewSWTImpl) tv).clientArea.y;
+  				if (clipping.y + clipping.height > iMaxY) {
+  					clipping.height = iMaxY - clipping.y + 1;
+  				}
+  			}
+  
+  			if (clipping.width <= 0 || clipping.height <= 0) {
+  				//System.out.println(row.getIndex() + " clipping="+clipping + ";" );
+  				return;
+  			}
+  
+  			if (!origClipping.contains(clipping.x, clipping.y)
+  					|| !origClipping.contains(clipping.x + clipping.width - 1, clipping.y
+  							+ clipping.height - 1)) {
+  				gc.setClipping(clipping);
+  			}
+			}
+
+			if (rowAlpha < 255) {
+				gc.setAlpha(rowAlpha);
+			}
+
+			if (cell.needsPainting()) {
+				Image graphicSWT = cell.getGraphicSWT();
+				if (graphicSWT != null && !graphicSWT.isDisposed()) {
+					int marginWidth = cell.getMarginWidth();
+					int marginHeight = cell.getMarginHeight();
+					Rectangle graphicBounds = new Rectangle(cellBounds.x + marginWidth,
+							cellBounds.y + marginHeight,
+							cellBounds.width - (marginWidth * 2), cellBounds.height
+									- (marginHeight * 2));
+					Rectangle imageBounds = graphicSWT.getBounds();
+					BufferedTableItem bufferedTableItem = null;
+					if (cell instanceof TableCellImpl) {
+						bufferedTableItem = ((TableCellImpl) cell).getBufferedTableItem();
+					}
+					if (bufferedTableItem instanceof BufferedGraphicTableItem) {
+						BufferedGraphicTableItem ti = (BufferedGraphicTableItem) bufferedTableItem;
+						int orientation = ti.getOrientation();
+						
+						if (orientation == SWT.FILL) {
+							if (!graphicBounds.isEmpty()) {
+								gc.setAdvanced(true);
+								//System.out.println(imageBounds + ";" + graphicBounds);
+  							gc.drawImage(graphicSWT, 0, 0, imageBounds.width,
+  									imageBounds.height, graphicBounds.x, graphicBounds.y,
+  									graphicBounds.width, graphicBounds.height);
+							}
+						} else {
+						
+  			  		if (imageBounds.width < graphicBounds.width) {
+    			    	if (orientation == SWT.CENTER) {
+    			    		graphicBounds.x += (graphicBounds.width - imageBounds.width) / 2;
+    			    	} else if (orientation == SWT.RIGHT) {
+    			    		graphicBounds.x = (graphicBounds.x + graphicBounds.width) - imageBounds.width;
+    			    	}
+  			  		}
+  			  		
+  			  		if (imageBounds.height < graphicBounds.height) {
+  			  			graphicBounds.y += (graphicBounds.height - imageBounds.height) / 2;
+  			  		}
+
+  			  		gc.drawImage(graphicSWT, graphicBounds.x, graphicBounds.y);
+						}
+
+					} else {
+			  		gc.drawImage(graphicSWT, graphicBounds.x, graphicBounds.y);
+					}
+				}
+				cell.doPaint(gc);
+			}
+			if (text.length() > 0) {
+				int ofsx = 0;
+				Image image = cell.getIcon();
+				Rectangle imageBounds = null;
+				if (image != null && !image.isDisposed()) {
+					imageBounds = image.getBounds();
+					int ofs = imageBounds.width;
+					ofsx += ofs;
+					cellBounds.x += ofs;
+					cellBounds.width -= ofs;
+				}
+				//System.out.println("PS " + rowIndex + ";" + cellBounds + ";" + cell.getText());
+				int style = TableColumnSWTUtils.convertColumnAlignmentToSWT(columnsOrdered[iColumnNo].getAlignment());
+				if (cellBounds.height > 20) {
+					style |= SWT.WRAP;
+				}
+				int textOpacity = cell.getTextAlpha();
+				if (textOpacity < 255) {
+					gc.setTextAntialias(SWT.ON);
+					gc.setAlpha(textOpacity);
+				} else if (textOpacity > 255) {
+					gc.setFont(FontUtils.getAnyFontBold(gc));
+					gc.setTextAntialias(SWT.ON);
+					gc.setAlpha(textOpacity & 255);
+				}
+				// put some padding on text
+				ofsx += 6;
+				cellBounds.x += 3;
+				cellBounds.width -= 6;
+				cellBounds.y += 2;
+				cellBounds.height -= 4;
+				if (!cellBounds.isEmpty()) {
+					GCStringPrinter sp = new GCStringPrinter(gc, text, cellBounds, true,
+							cellBounds.height > 20, style);
+					
+					boolean fit = sp.printString();
+					if (fit) {
+
+						cell.setDefaultToolTip(null);
+					} else {
+
+						cell.setDefaultToolTip(text);
+					}
+
+					Point size = sp.getCalculatedSize();
+					size.x += ofsx;
+
+					TableColumn tableColumn = cell.getTableColumn();
+					if (tableColumn != null && tableColumn.getPreferredWidth() < size.x) {
+						tableColumn.setPreferredWidth(size.x);
+					}
+
+					if (imageBounds != null) {
+						int drawToY = cellBounds.y + (cellBounds.height / 2)
+								- (imageBounds.height / 2);
+						if ((style & SWT.RIGHT) > 0) {
+							int drawToX = cellBounds.x + cellBounds.width - size.x;
+							gc.drawImage(image, drawToX, drawToY);
+						} else {
+							gc.drawImage(image, cellBounds.x - imageBounds.width - 3, drawToY);
+						}
+					}
+				} else {
+					cell.setDefaultToolTip(null);
+				}
+			}
+			if (cell instanceof TableCellSWTBase) {
+				((TableCellSWTBase) cell).clearVisuallyChangedSinceRefresh();
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_TabsCommon.java b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_TabsCommon.java
new file mode 100644
index 0000000..2d8f1a6
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewSWT_TabsCommon.java
@@ -0,0 +1,446 @@
+package org.gudy.azureus2.ui.swt.views.table.impl;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.config.impl.ConfigurationManager;
+import org.gudy.azureus2.core3.util.IndentWriter;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.plugins.UISWTInstance.UISWTViewEventListenerWrapper;
+import org.gudy.azureus2.ui.swt.pluginsimpl.*;
+import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
+
+import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
+import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
+
+public class TableViewSWT_TabsCommon
+{
+	TableViewSWT<?> tv;
+	
+	/** TabViews */
+	private ArrayList<UISWTViewCore> tabViews = new ArrayList<UISWTViewCore>(1);
+
+	/** TabViews */
+	private CTabFolder tabFolder;
+
+	/** Composite that stores the table (sometimes the same as mainComposite) */
+	public Composite tableComposite;
+
+
+	public TableViewSWT_TabsCommon(TableViewSWT<?> tv) {
+		this.tv = tv;
+	}
+
+	public void triggerTabViewsDataSourceChanged(boolean sendParent) {
+		if (tabViews == null || tabViews.size() == 0) {
+			return;
+		}
+		
+		if (sendParent) {
+			for (int i = 0; i < tabViews.size(); i++) {
+				UISWTViewCore view = tabViews.get(i);
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+							tv.getParentDataSource());
+				}
+			}
+			return;
+		}
+
+		// Set Data Object for all tabs.  
+
+		Object[] dataSourcesCore = tv.getSelectedDataSources(true);
+		Object[] dataSourcesPlugin = null;
+
+		for (int i = 0; i < tabViews.size(); i++) {
+			UISWTViewCore view = tabViews.get(i);
+			if (view != null) {
+				if (view.useCoreDataSource()) {
+					view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+							dataSourcesCore.length == 0 ? tv.getParentDataSource()
+									: dataSourcesCore);
+				} else {
+					if (dataSourcesPlugin == null) {
+						dataSourcesPlugin = tv.getSelectedDataSources(false);
+					}
+
+					view.triggerEvent(
+							UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+							dataSourcesPlugin.length == 0 ? PluginCoreUtils.convert(
+									tv.getParentDataSource(), false) : dataSourcesPlugin);
+				}
+			}
+		}
+	}
+
+	public void triggerTabViewDataSourceChanged(UISWTViewCore view) {
+		if (view != null) {
+			view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, tv.getParentDataSource());
+
+			if (view.useCoreDataSource()) {
+				Object[] dataSourcesCore = tv.getSelectedDataSources(true);
+				if (dataSourcesCore.length > 0) {
+					view.triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+							dataSourcesCore.length == 0 ? tv.getParentDataSource()
+									: dataSourcesCore);
+				}
+			} else {
+				Object[] dataSourcesPlugin = tv.getSelectedDataSources(false);
+				if (dataSourcesPlugin.length > 0) {
+					view.triggerEvent(
+							UISWTViewEvent.TYPE_DATASOURCE_CHANGED,
+							dataSourcesPlugin.length == 0 ? PluginCoreUtils.convert(
+									tv.getParentDataSource(), false) : dataSourcesPlugin);
+				}
+			}
+		}
+		
+	}
+
+	public void delete() {
+		if (tabViews != null && tabViews.size() > 0) {
+			for (int i = 0; i < tabViews.size(); i++) {
+				UISWTViewCore view = tabViews.get(i);
+				if (view != null) {
+      		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
+				}
+			}
+		}
+	}
+
+	public void generate(IndentWriter writer) {
+		writer.println("# of SubViews: " + tabViews.size());
+		writer.indent();
+		try {
+			for (Iterator<UISWTViewCore> iter = tabViews.iterator(); iter.hasNext();) {
+				UISWTViewCore view = iter.next();
+				writer.println(view.getTitleID() + ": " + view.getFullTitle());
+			}
+		} finally {
+			writer.exdent();
+		}
+	}
+
+	public void localeChanged() {
+		if (tabViews != null && tabViews.size() > 0) {
+			for (int i = 0; i < tabViews.size(); i++) {
+				UISWTViewCore view = tabViews.get(i);
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_LANGUAGEUPDATE, null);
+				}
+			}
+		}
+	}
+
+	public UISWTViewCore getActiveSubView() {
+		if (!tv.isTabViewsEnabled() || tabFolder == null || tabFolder.isDisposed()
+				|| tabFolder.getMinimized()) {
+			return null;
+		}
+
+		CTabItem item = tabFolder.getSelection();
+		if (item != null) {
+			return (UISWTViewCore) item.getData("IView");
+		}
+
+		return null;
+	}
+
+	public void refreshSelectedSubView() {
+		UISWTViewCore view = getActiveSubView();
+		if (view != null && view.getComposite().isVisible()) {
+			view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
+		}
+	}
+
+	// TabViews Functions
+	public void addTabView(UISWTViewCore view) {
+		if (view == null || tabFolder == null) {
+			return;
+		}
+		
+		triggerTabViewDataSourceChanged(view);
+
+		CTabItem item = new CTabItem(tabFolder, SWT.NULL);
+		item.setData("IView", view);
+		Messages.setLanguageText(item, view.getTitleID());
+		view.initialize(tabFolder);
+		item.setControl(view.getComposite());
+		tabViews.add(view);
+	}
+
+
+	public Composite createSashForm(final Composite composite) {
+		if (!tv.isTabViewsEnabled()) {
+			tableComposite = tv.createMainPanel(composite);
+			return tableComposite;
+		}
+
+		ConfigurationManager configMan = ConfigurationManager.getInstance();
+
+		int iNumViews = 0;
+
+		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
+		UISWTViewEventListenerWrapper[] pluginViews = null;
+		if (uiFunctions != null) {
+			UISWTInstance pluginUI = uiFunctions.getUISWTInstance();
+
+			if (pluginUI != null) {
+				pluginViews = pluginUI.getViewListeners(tv.getTableID());
+				iNumViews += pluginViews.length;
+			}
+		}
+
+		if (iNumViews == 0) {
+			tableComposite = tv.createMainPanel(composite);
+			return tableComposite;
+		}
+
+		FormData formData;
+
+		final Composite form = new Composite(composite, SWT.NONE);
+		FormLayout flayout = new FormLayout();
+		flayout.marginHeight = 0;
+		flayout.marginWidth = 0;
+		form.setLayout(flayout);
+		GridData gridData;
+		gridData = new GridData(GridData.FILL_BOTH);
+		form.setLayoutData(gridData);
+
+		// Create them in reverse order, so we can have the table auto-grow, and
+		// set the tabFolder's height manually
+
+		final int TABHEIGHT = 20;
+		tabFolder = new CTabFolder(form, SWT.TOP | SWT.BORDER);
+		tabFolder.setMinimizeVisible(true);
+		tabFolder.setTabHeight(TABHEIGHT);
+		final int iFolderHeightAdj = tabFolder.computeSize(SWT.DEFAULT, 0).y;
+
+		final Sash sash = new Sash(form, SWT.HORIZONTAL);
+
+		tableComposite = tv.createMainPanel(form);
+		Composite cFixLayout = tableComposite;
+		while (cFixLayout != null && cFixLayout.getParent() != form) {
+			cFixLayout = cFixLayout.getParent();
+		}
+		if (cFixLayout == null) {
+			cFixLayout = tableComposite;
+		}
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		layout.horizontalSpacing = 0;
+		layout.verticalSpacing = 0;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		cFixLayout.setLayout(layout);
+
+		// FormData for Folder
+		formData = new FormData();
+		formData.left = new FormAttachment(0, 0);
+		formData.right = new FormAttachment(100, 0);
+		formData.bottom = new FormAttachment(100, 0);
+		int iSplitAt = configMan.getIntParameter(tv.getPropertiesPrefix() + ".SplitAt",
+				3000);
+		// Was stored at whole
+		if (iSplitAt < 100) {
+			iSplitAt *= 100;
+		}
+
+		double pct = iSplitAt / 10000.0;
+		if (pct < 0.03) {
+			pct = 0.03;
+		} else if (pct > 0.97) {
+			pct = 0.97;
+		}
+
+		// height will be set on first resize call
+		sash.setData("PCT", new Double(pct));
+		tabFolder.setLayoutData(formData);
+		final FormData tabFolderData = formData;
+
+		// FormData for Sash
+		formData = new FormData();
+		formData.left = new FormAttachment(0, 0);
+		formData.right = new FormAttachment(100, 0);
+		formData.bottom = new FormAttachment(tabFolder);
+		formData.height = 5;
+		sash.setLayoutData(formData);
+
+		// FormData for table Composite
+		formData = new FormData();
+		formData.left = new FormAttachment(0, 0);
+		formData.right = new FormAttachment(100, 0);
+		formData.top = new FormAttachment(0, 0);
+		formData.bottom = new FormAttachment(sash);
+		cFixLayout.setLayoutData(formData);
+
+		// Listeners to size the folder
+		sash.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				final boolean FASTDRAG = true;
+
+				if (FASTDRAG && e.detail == SWT.DRAG) {
+					return;
+				}
+
+				if (tabFolder.getMinimized()) {
+					tabFolder.setMinimized(false);
+					refreshSelectedSubView();
+					ConfigurationManager configMan = ConfigurationManager.getInstance();
+					configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized",
+							false);
+				}
+
+				Rectangle area = form.getClientArea();
+				tabFolderData.height = area.height - e.y - e.height - iFolderHeightAdj;
+				form.layout();
+
+				Double l = new Double((double) tabFolder.getBounds().height
+						/ form.getBounds().height);
+				sash.setData("PCT", l);
+				if (e.detail != SWT.DRAG) {
+					ConfigurationManager configMan = ConfigurationManager.getInstance();
+					configMan.setParameter(tv.getPropertiesPrefix() + ".SplitAt",
+							(int) (l.doubleValue() * 10000));
+				}
+			}
+		});
+
+		final CTabFolder2Adapter folderListener = new CTabFolder2Adapter() {
+			public void minimize(CTabFolderEvent event) {
+				tabFolder.setMinimized(true);
+				tabFolderData.height = iFolderHeightAdj;
+				CTabItem[] items = tabFolder.getItems();
+				for (int i = 0; i < items.length; i++) {
+					CTabItem tabItem = items[i];
+					tabItem.getControl().setVisible(false);
+				}
+				form.layout();
+
+				UISWTViewCore view = getActiveSubView();
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
+				}
+
+				
+				ConfigurationManager configMan = ConfigurationManager.getInstance();
+				configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized", true);
+			}
+
+			public void restore(CTabFolderEvent event) {
+				tabFolder.setMinimized(false);
+				CTabItem selection = tabFolder.getSelection();
+				if (selection != null) {
+					selection.getControl().setVisible(true);
+				}
+				form.notifyListeners(SWT.Resize, null);
+
+				UISWTViewCore view = getActiveSubView();
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
+				}
+				refreshSelectedSubView();
+
+				ConfigurationManager configMan = ConfigurationManager.getInstance();
+				configMan.setParameter(tv.getPropertiesPrefix() + ".subViews.minimized", false);
+			}
+
+		};
+		tabFolder.addCTabFolder2Listener(folderListener);
+
+		tabFolder.addSelectionListener(new SelectionListener() {
+			public void widgetSelected(SelectionEvent e) {
+				// make sure its above
+				try {
+					((CTabItem) e.item).getControl().setVisible(true);
+					((CTabItem) e.item).getControl().moveAbove(null);
+
+					// TODO: Need to viewDeactivated old one
+					UISWTViewCore view = getActiveSubView();
+					if (view != null) {
+						view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
+					}
+					
+				} catch (Exception t) {
+				}
+			}
+
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}
+		});
+
+		tabFolder.addMouseListener(new MouseAdapter() {
+			public void mouseDown(MouseEvent e) {
+				if (tabFolder.getMinimized()) {
+					folderListener.restore(null);
+					// If the user clicked down on the restore button, and we restore
+					// before the CTabFolder does, CTabFolder will minimize us again
+					// There's no way that I know of to determine if the mouse is 
+					// on that button!
+
+					// one of these will tell tabFolder to cancel
+					e.button = 0;
+					tabFolder.notifyListeners(SWT.MouseExit, null);
+				}
+			}
+		});
+
+		form.addListener(SWT.Resize, new Listener() {
+			public void handleEvent(Event e) {
+				if (tabFolder.getMinimized()) {
+					return;
+				}
+
+				Double l = (Double) sash.getData("PCT");
+				if (l != null) {
+					tabFolderData.height = (int) (form.getBounds().height * l.doubleValue())
+							- iFolderHeightAdj;
+					form.layout();
+				}
+			}
+		});
+
+		// Call plugin listeners
+		if (pluginViews != null) {
+			for (UISWTViewEventListenerWrapper l : pluginViews) {
+				if (l != null) {
+					try {
+						UISWTViewImpl view = new UISWTViewImpl(tv.getTableID(), l.getViewID(), l, null);
+						addTabView(view);
+					} catch (Exception e) {
+						// skip, plugin probably specifically asked to not be added
+					}
+				}
+			}
+		}
+
+		if (configMan.getBooleanParameter(
+				tv.getPropertiesPrefix() + ".subViews.minimized", false)) {
+			tabFolder.setMinimized(true);
+			tabFolderData.height = iFolderHeightAdj;
+		} else {
+			tabFolder.setMinimized(false);
+		}
+
+		tabFolder.setSelection(0);
+
+		return form;
+	}
+
+	public void swt_refresh() {
+		if (tv.isTabViewsEnabled() && tabFolder != null && !tabFolder.isDisposed()
+				&& !tabFolder.getMinimized()) {
+			refreshSelectedSubView();
+		}
+	}
+}
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 ca97cdc..04c996d 100644
--- a/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TableViewTab.java
@@ -1,22 +1,32 @@
 package org.gudy.azureus2.ui.swt.views.table.impl;
 
+import java.util.Map;
+
 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.AEDiagnosticsEvidenceGenerator;
 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.plugins.ui.UIPluginViewToolBarListener;
+import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.plugins.UISWTView;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCoreEventListener;
 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
 
+import com.aelitis.azureus.ui.common.ToolBarItem;
+
 public abstract class TableViewTab<DATASOURCETYPE>
-	extends AbstractIView
-	implements IViewExtension
+	implements UISWTViewCoreEventListener, UIPluginViewToolBarListener,
+	AEDiagnosticsEvidenceGenerator
 {
 	private TableViewSWT<DATASOURCETYPE> tv;
 	private Object parentDataSource;
 	private final String propertiesPrefix;
 	private Composite composite;
+	private UISWTView swtView;
 
 	
 	public TableViewTab(String propertiesPrefix) {
@@ -29,6 +39,9 @@ public abstract class TableViewTab<DATASOURCETYPE>
 
 	public final void initialize(Composite composite) {
 		tv = initYourTableView();
+		if (parentDataSource != null) {
+			tv.setParentDataSource(parentDataSource);
+		}
 		Composite parent = initComposite(composite);
 		tv.initialize(parent);
 		if (parent != composite) {
@@ -38,9 +51,6 @@ public abstract class TableViewTab<DATASOURCETYPE>
 		}
 		
 		tableViewTabInitComplete();
-		if (parentDataSource != null) {
-			tv.setParentDataSource(parentDataSource);
-		}
 	}
 	
 	public void tableViewTabInitComplete() {
@@ -59,61 +69,56 @@ public abstract class TableViewTab<DATASOURCETYPE>
 		}
 	}
 
-	public void updateLanguage() {
-		super.updateLanguage();
-		if (tv != null) {
-			tv.updateLanguage();
-		}
-	}
-
 	public final void refresh() {
 		if (tv != null) {
 			tv.refreshTable(false);
 		}
 	}
 
-	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#delete()
-	public final void delete() {
+	private final void delete() {
 		if (tv != null) {
 			tv.delete();
 		}
-		super.delete();
-	}
-
-	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#getData()
-	public final String getData() {
-		return getPropertiesPrefix() + ".title.short";
 	}
 
 	public final String getFullTitle() {
 		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) {
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter)
+	 */
+	public void generate(IndentWriter writer) {
 		if (tv != null) {
 			tv.generate(writer);
 		}
 	}
 	
-	// @see org.gudy.azureus2.ui.swt.views.AbstractIView#getComposite()
 	public Composite getComposite() {
 		return composite;
 	}
-	
-	public void itemActivated(String itemKey) {
-		if (itemKey.equals("editcolumns")) {
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener#toolBarItemActivated(com.aelitis.azureus.ui.common.ToolBarItem, long, java.lang.Object)
+	 */
+	public boolean toolBarItemActivated(ToolBarItem item, long activationType,
+			Object datasource) {
+		if (item.getID().equals("editcolumns")) {
 			if (tv instanceof TableViewSWTImpl) {
-				((TableViewSWTImpl)tv).showColumnEditor();
+				((TableViewSWT<?>)tv).showColumnEditor();
+				return true;
 			}
 		}
+		return false;
 	}
 	
-	public boolean isEnabled(String itemKey) {
-		if (itemKey.equals("editcolumns")) {return true;}
-		return false;
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.ToolBarEnabler2#refreshToolBarItems(java.util.Map)
+	 */
+	public void refreshToolBarItems(Map<String, Long> list) {
+		list.put("editcolumns", UIToolBarItem.STATE_ENABLED);
 	}
-
+	
 	public String getPropertiesPrefix() {
 		return propertiesPrefix;
 	}
@@ -126,13 +131,62 @@ public abstract class TableViewTab<DATASOURCETYPE>
 		// cheap hack.. calling isVisible freshens table's visible status (and
 		// updates subviews)
 		if (tv instanceof TableViewSWTImpl) {
-			((TableViewSWTImpl)tv).isVisible();
+			((TableViewSWTImpl<?>)tv).isVisible();
 		}
 	}
 	
-	public void viewDeactivated() {
+	private void viewDeactivated() {
 		if (tv instanceof TableViewSWTImpl) {
-			((TableViewSWTImpl)tv).isVisible();
+			((TableViewSWTImpl<?>)tv).isVisible();
+		}
+	}
+
+	public boolean eventOccurred(UISWTViewEvent event) {
+		switch (event.getType()) {
+			case UISWTViewEvent.TYPE_CREATE:
+				swtView = (UISWTView) event.getData();
+				swtView.setToolBarListener(this);
+				swtView.setTitle(getFullTitle());
+				break;
+
+			case UISWTViewEvent.TYPE_DESTROY:
+				delete();
+				break;
+
+			case UISWTViewEvent.TYPE_INITIALIZE:
+				initialize((Composite) event.getData());
+				break;
+
+			case UISWTViewEvent.TYPE_LANGUAGEUPDATE:
+				swtView.setTitle(getFullTitle());
+				updateLanguage();
+				Messages.updateLanguageForControl(composite);
+				break;
+
+			case UISWTViewEvent.TYPE_DATASOURCE_CHANGED:
+				dataSourceChanged(event.getData());
+				break;
+
+			case UISWTViewEvent.TYPE_FOCUSGAINED:
+				viewActivated();
+				break;
+
+			case UISWTViewEvent.TYPE_FOCUSLOST:
+				viewDeactivated();
+				break;
+
+			case UISWTViewEvent.TYPE_REFRESH:
+				refresh();
+				break;
 		}
+
+		return true;
+	}
+
+	public void updateLanguage() {
+	}
+
+	public UISWTView getSWTView() {
+		return swtView;
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TreeColumnDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TreeColumnDelegate.java
new file mode 100644
index 0000000..188ecf4
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TreeColumnDelegate.java
@@ -0,0 +1,204 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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.impl;
+
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public class TreeColumnDelegate implements TableColumnOrTreeColumn
+{
+	TreeColumn treeColumn;
+
+	public TreeColumnDelegate(TreeColumn item) {
+		treeColumn = item;
+	}
+
+	public TreeColumnDelegate(TableOrTreeSWT parent, int style) {
+		treeColumn = new TreeColumn((Tree) parent.getComposite(), style);
+	}
+
+	public Image getImage() {
+		return treeColumn.getImage();
+	}
+
+	public String getText() {
+		return treeColumn.getText();
+	}
+
+	public void addControlListener(ControlListener listener) {
+		treeColumn.addControlListener(listener);
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		treeColumn.addListener(eventType, listener);
+	}
+
+	public void addSelectionListener(SelectionListener listener) {
+		treeColumn.addSelectionListener(listener);
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		treeColumn.addDisposeListener(listener);
+	}
+
+	public boolean getMoveable() {
+		return treeColumn.getMoveable();
+	}
+
+	public TableOrTreeSWT getParent() {
+		return TableOrTreeUtils.getTableOrTreeSWT(treeColumn.getParent());
+	}
+
+	public boolean getResizable() {
+		return treeColumn.getResizable();
+	}
+
+	public String getToolTipText() {
+		return treeColumn.getToolTipText();
+	}
+
+	public int getWidth() {
+		return treeColumn.getWidth();
+	}
+
+	public void dispose() {
+		treeColumn.dispose();
+	}
+
+	public boolean equals(Object obj) {
+		return treeColumn.equals(obj);
+	}
+
+	public int getAlignment() {
+		return treeColumn.getAlignment();
+	}
+
+	public Object getData() {
+		return treeColumn.getData();
+	}
+
+	public Object getData(String key) {
+		return treeColumn.getData(key);
+	}
+
+	public Display getDisplay() {
+		return treeColumn.getDisplay();
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return treeColumn.getListeners(eventType);
+	}
+
+	public int getStyle() {
+		return treeColumn.getStyle();
+	}
+
+	public int hashCode() {
+		return treeColumn.hashCode();
+	}
+
+	public void pack() {
+		treeColumn.pack();
+	}
+
+	public void removeControlListener(ControlListener listener) {
+		treeColumn.removeControlListener(listener);
+	}
+
+	public void removeSelectionListener(SelectionListener listener) {
+		treeColumn.removeSelectionListener(listener);
+	}
+
+	public void setAlignment(int alignment) {
+		treeColumn.setAlignment(alignment);
+	}
+
+	public void setImage(Image image) {
+		treeColumn.setImage(image);
+	}
+
+	public void setMoveable(boolean moveable) {
+		treeColumn.setMoveable(moveable);
+	}
+
+	public void setResizable(boolean resizable) {
+		treeColumn.setResizable(resizable);
+	}
+
+	public void setText(String string) {
+		treeColumn.setText(string);
+	}
+
+	public void setToolTipText(String string) {
+		treeColumn.setToolTipText(string);
+	}
+
+	public boolean isDisposed() {
+		return treeColumn.isDisposed();
+	}
+
+	public boolean isListening(int eventType) {
+		return treeColumn.isListening(eventType);
+	}
+
+	public void setWidth(int width) {
+		treeColumn.setWidth(width);
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		treeColumn.notifyListeners(eventType, event);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		treeColumn.removeListener(eventType, listener);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		treeColumn.removeDisposeListener(listener);
+	}
+
+	public void setData(Object data) {
+		treeColumn.setData(data);
+	}
+
+	public void setData(String key, Object value) {
+		treeColumn.setData(key, value);
+	}
+
+	public String toString() {
+		return treeColumn.toString();
+	}
+
+	/////////////////
+	
+	public Item getColumn() {
+		return treeColumn;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TreeDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TreeDelegate.java
new file mode 100644
index 0000000..d3a79b1
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TreeDelegate.java
@@ -0,0 +1,916 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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.impl;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.swt.accessibility.Accessible;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.core3.util.Debug;
+import org.gudy.azureus2.ui.swt.components.InPaintInfo;
+import org.gudy.azureus2.ui.swt.views.table.TableColumnOrTreeColumn;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * Delegates a SWT {@link Tree} into a {@link TableOrTreeSWT} allowing easy
+ * switching from Table and Tree.
+ * <p>
+ * Uses own map for setData and getData for faster lookups and no SWT thread
+ * checking
+ * 
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public class TreeDelegate implements TableOrTreeSWT
+{
+	static Constructor<?> constTree;
+	Tree tree;
+
+	Map<String, Object> data = new HashMap<String, Object>(5);
+	private int style;
+	
+	static {
+		try {
+			Class<?> claTree;
+			if (Constants.isWindows) {
+				claTree = Class.forName("org.eclipse.swt.widgets.Tree2");
+			} else {
+				claTree = Tree.class;
+			}
+			constTree = claTree.getConstructor(new Class[] {
+				Composite.class,
+				int.class
+			});
+		} catch (Throwable t) {
+		}
+	}
+
+	protected TreeDelegate(Composite parent, int style)
+			throws Exception {
+		this(constTree == null ? new Tree(parent,
+				style) : (Tree) constTree.newInstance(new Object[] { parent, style }));
+		this.style = style;
+	}
+
+	protected TreeDelegate(Tree t) {
+		tree = t;
+		this.style = t.getStyle();
+	}
+
+	public Composite getComposite() {
+		return tree;
+	}
+
+	public Rectangle computeTrim(int x, int y, int width, int height) {
+		return tree.computeTrim(x, y, width, height);
+	}
+
+	public void addControlListener(ControlListener listener) {
+		tree.addControlListener(listener);
+	}
+
+	public void changed(Control[] changed) {
+		tree.changed(changed);
+	}
+
+	public void addDragDetectListener(DragDetectListener listener) {
+		tree.addDragDetectListener(listener);
+	}
+
+	public Rectangle getClientArea() {
+		return tree.getClientArea();
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		tree.addListener(eventType, listener);
+	}
+
+	public void addFocusListener(FocusListener listener) {
+		tree.addFocusListener(listener);
+	}
+
+	public ScrollBar getHorizontalBar() {
+		return tree.getHorizontalBar();
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		tree.addDisposeListener(listener);
+	}
+
+	public ScrollBar getVerticalBar() {
+		return tree.getVerticalBar();
+	}
+
+	public void addHelpListener(HelpListener listener) {
+		tree.addHelpListener(listener);
+	}
+
+	public void addKeyListener(KeyListener listener) {
+		tree.addKeyListener(listener);
+	}
+
+	public void addMenuDetectListener(MenuDetectListener listener) {
+		tree.addMenuDetectListener(listener);
+	}
+
+	public void addMouseListener(MouseListener listener) {
+		tree.addMouseListener(listener);
+	}
+
+	public void addSelectionListener(SelectionListener listener) {
+		tree.addSelectionListener(listener);
+	}
+
+	public void addMouseTrackListener(MouseTrackListener listener) {
+		tree.addMouseTrackListener(listener);
+	}
+
+	public void addMouseMoveListener(MouseMoveListener listener) {
+		tree.addMouseMoveListener(listener);
+	}
+
+	public void addTreeListener(TreeListener listener) {
+		tree.addTreeListener(listener);
+	}
+
+	public void addMouseWheelListener(MouseWheelListener listener) {
+		tree.addMouseWheelListener(listener);
+	}
+
+	public int getBackgroundMode() {
+		return tree.getBackgroundMode();
+	}
+
+	public void addPaintListener(PaintListener listener) {
+		tree.addPaintListener(listener);
+	}
+
+	public Control[] getChildren() {
+		return tree.getChildren();
+	}
+
+	public void addTraverseListener(TraverseListener listener) {
+		tree.addTraverseListener(listener);
+	}
+
+	public void dispose() {
+		tree.dispose();
+	}
+
+	public Layout getLayout() {
+		return tree.getLayout();
+	}
+
+	public Control[] getTabList() {
+		return tree.getTabList();
+	}
+
+	public boolean getLayoutDeferred() {
+		return tree.getLayoutDeferred();
+	}
+
+	public Point computeSize(int wHint, int hHint) {
+		return tree.computeSize(wHint, hHint);
+	}
+
+	public boolean isLayoutDeferred() {
+		return tree.isLayoutDeferred();
+	}
+
+	public void layout() {
+		tree.layout();
+	}
+
+	public Object getData() {
+		return getData(null);
+	}
+	
+	public Object getData(String key) {
+		synchronized (data) {
+			return data.get(key);
+		}
+	}
+
+	public void layout(boolean changed) {
+		tree.layout(changed);
+	}
+
+	public Display getDisplay() {
+		return tree.getDisplay();
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return tree.getListeners(eventType);
+	}
+
+	public void layout(boolean changed, boolean all) {
+		tree.layout(changed, all);
+	}
+
+	public int getStyle() {
+		return style;
+	}
+
+	public boolean dragDetect(Event event) {
+		return tree.dragDetect(event);
+	}
+
+	public boolean isListening(int eventType) {
+		return tree.isListening(eventType);
+	}
+
+	public boolean dragDetect(MouseEvent event) {
+		return tree.dragDetect(event);
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		tree.notifyListeners(eventType, event);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		tree.removeListener(eventType, listener);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		tree.removeDisposeListener(listener);
+	}
+
+	public void setBackgroundMode(int mode) {
+		tree.setBackgroundMode(mode);
+	}
+
+	public boolean setFocus() {
+		return tree.setFocus();
+	}
+
+	public void setLayout(Layout layout) {
+		tree.setLayout(layout);
+	}
+
+	public int getBorderWidth() {
+		return tree.getBorderWidth();
+	}
+
+	public void setLayoutDeferred(boolean defer) {
+		tree.setLayoutDeferred(defer);
+	}
+
+	public Rectangle getBounds() {
+		return tree.getBounds();
+	}
+
+	public void setTabList(Control[] tabList) {
+		tree.setTabList(tabList);
+	}
+
+	public Cursor getCursor() {
+		return tree.getCursor();
+	}
+
+	public void setData(Object data) {
+		setData(null, data);
+	}
+	
+	public void setData(String key, Object value) {
+		synchronized (data) {
+			data.put(key, value);
+		}
+	}
+
+	public boolean getDragDetect() {
+		return tree.getDragDetect();
+	}
+
+	public boolean getEnabled() {
+		return tree.getEnabled();
+	}
+
+	public Font getFont() {
+		return tree.getFont();
+	}
+
+	public Color getForeground() {
+		return tree.getForeground();
+	}
+
+	public Object getLayoutData() {
+		return tree.getLayoutData();
+	}
+
+	public Point getLocation() {
+		return tree.getLocation();
+	}
+
+	public Menu getMenu() {
+		return tree.getMenu();
+	}
+
+	public Monitor getMonitor() {
+		return tree.getMonitor();
+	}
+
+	public Composite getParent() {
+		return tree.getParent();
+	}
+
+	public Region getRegion() {
+		return tree.getRegion();
+	}
+
+	public Shell getShell() {
+		return tree.getShell();
+	}
+
+	public Point getSize() {
+		return tree.getSize();
+	}
+
+	public String getToolTipText() {
+		return tree.getToolTipText();
+	}
+
+	public boolean getVisible() {
+		return tree.getVisible();
+	}
+
+	public String toString() {
+		return tree.toString();
+	}
+
+	public boolean isEnabled() {
+		return tree.isEnabled();
+	}
+
+	public boolean isFocusControl() {
+		return tree.isFocusControl();
+	}
+
+	public boolean isReparentable() {
+		return tree.isReparentable();
+	}
+
+	public boolean isVisible() {
+		return tree.isVisible();
+	}
+
+	public void moveAbove(Control control) {
+		tree.moveAbove(control);
+	}
+
+	public void moveBelow(Control control) {
+		tree.moveBelow(control);
+	}
+
+	public void pack() {
+		tree.pack();
+	}
+
+	public void pack(boolean changed) {
+		tree.pack(changed);
+	}
+
+	public void clear(int index, boolean all) {
+		tree.clear(index, all);
+	}
+
+	public boolean print(GC gc) {
+		return tree.print(gc);
+	}
+
+	public void clearAll(boolean all) {
+		tree.clearAll(all);
+	}
+
+	public Point computeSize(int wHint, int hHint, boolean changed) {
+		return tree.computeSize(wHint, hHint, changed);
+	}
+
+	public void redraw() {
+		tree.redraw();
+	}
+
+	public void redraw(int x, int y, int width, int height, boolean all) {
+		tree.redraw(x, y, width, height, all);
+	}
+
+	public void removeControlListener(ControlListener listener) {
+		tree.removeControlListener(listener);
+	}
+
+	public void removeDragDetectListener(DragDetectListener listener) {
+		tree.removeDragDetectListener(listener);
+	}
+
+	public void removeFocusListener(FocusListener listener) {
+		tree.removeFocusListener(listener);
+	}
+
+	public void removeHelpListener(HelpListener listener) {
+		tree.removeHelpListener(listener);
+	}
+
+	public void removeKeyListener(KeyListener listener) {
+		tree.removeKeyListener(listener);
+	}
+
+	public void removeMenuDetectListener(MenuDetectListener listener) {
+		tree.removeMenuDetectListener(listener);
+	}
+
+	public void removeMouseTrackListener(MouseTrackListener listener) {
+		tree.removeMouseTrackListener(listener);
+	}
+
+	public void removeMouseListener(MouseListener listener) {
+		tree.removeMouseListener(listener);
+	}
+
+	public void removeMouseMoveListener(MouseMoveListener listener) {
+		tree.removeMouseMoveListener(listener);
+	}
+
+	public void removeMouseWheelListener(MouseWheelListener listener) {
+		tree.removeMouseWheelListener(listener);
+	}
+
+	public void removePaintListener(PaintListener listener) {
+		tree.removePaintListener(listener);
+	}
+
+	public void removeTraverseListener(TraverseListener listener) {
+		tree.removeTraverseListener(listener);
+	}
+
+	public void deselect(TableItemOrTreeItem item) {
+		//System.out.println("DESEL " + Debug.getCompressedStackTrace());
+		tree.deselect((TreeItem) item.getItem());
+	}
+
+	public void setBackground(Color color) {
+		tree.setBackground(color);
+	}
+
+	public void deselectAll() {
+		tree.deselectAll();
+	}
+
+	public boolean equals(Object obj) {
+		return tree.equals(obj);
+	}
+
+	public boolean forceFocus() {
+		return tree.forceFocus();
+	}
+
+	public Accessible getAccessible() {
+		return tree.getAccessible();
+	}
+
+	public Color getBackground() {
+		return tree.getBackground();
+	}
+
+	public Image getBackgroundImage() {
+		return tree.getBackgroundImage();
+	}
+
+	public void setBackgroundImage(Image image) {
+		tree.setBackgroundImage(image);
+	}
+
+	public void setBounds(int x, int y, int width, int height) {
+		tree.setBounds(x, y, width, height);
+	}
+
+	public void setBounds(Rectangle rect) {
+		tree.setBounds(rect);
+	}
+
+	public void setCapture(boolean capture) {
+		tree.setCapture(capture);
+	}
+
+	public void setCursor(Cursor cursor) {
+		tree.setCursor(cursor);
+	}
+
+	public void setDragDetect(boolean dragDetect) {
+		tree.setDragDetect(dragDetect);
+	}
+
+	public void setEnabled(boolean enabled) {
+		tree.setEnabled(enabled);
+	}
+
+	public void setForeground(Color color) {
+		tree.setForeground(color);
+	}
+
+	public void setLayoutData(Object layoutData) {
+		tree.setLayoutData(layoutData);
+	}
+
+	public void setLocation(int x, int y) {
+		tree.setLocation(x, y);
+	}
+
+	public void setLocation(Point location) {
+		tree.setLocation(location);
+	}
+
+	public void setMenu(Menu menu) {
+		tree.setMenu(menu);
+	}
+
+	public int getGridLineWidth() {
+		return tree.getGridLineWidth();
+	}
+
+	public int getHeaderHeight() {
+		return tree.getHeaderHeight();
+	}
+
+	public boolean getHeaderVisible() {
+		return tree.getHeaderVisible();
+	}
+
+	public void setRegion(Region region) {
+		tree.setRegion(region);
+	}
+
+	public void setSize(int width, int height) {
+		tree.setSize(width, height);
+	}
+
+	public TableColumnOrTreeColumn getColumn(int index) {
+		return wrapOrNull(tree.getColumn(index));
+	}
+
+	public void setSize(Point size) {
+		tree.setSize(size);
+	}
+
+	public int getColumnCount() {
+		return tree.getColumnCount();
+	}
+
+	public void setToolTipText(String string) {
+		tree.setToolTipText(string);
+	}
+
+	public int[] getColumnOrder() {
+		return tree.getColumnOrder();
+	}
+
+	public void setVisible(boolean visible) {
+		tree.setVisible(visible);
+	}
+
+	public TableColumnOrTreeColumn[] getColumns() {
+		return wrapOrNull(tree.getColumns());
+	}
+
+	public TableItemOrTreeItem getItem(int index) {
+		if (index < 0) {
+			return null;
+		}
+		return wrapOrNull(tree.getItem(index));
+	}
+
+	public Point toControl(int x, int y) {
+		return tree.toControl(x, y);
+	}
+
+	public Point toControl(Point point) {
+		return tree.toControl(point);
+	}
+
+	public TableItemOrTreeItem getItem(Point point) {
+		return wrapOrNull(tree.getItem(point));
+	}
+
+	public Point toDisplay(int x, int y) {
+		return tree.toDisplay(x, y);
+	}
+
+	public Point toDisplay(Point point) {
+		return tree.toDisplay(point);
+	}
+
+	public int getItemCount() {
+		return tree.getItemCount();
+	}
+
+	public int getItemHeight() {
+		return tree.getItemHeight();
+	}
+
+	public TableItemOrTreeItem[] getItems() {
+		return wrapOrNull(tree.getItems());
+	}
+
+	public boolean getLinesVisible() {
+		return tree.getLinesVisible();
+	}
+
+	public TableItemOrTreeItem getParentItem() {
+		return wrapOrNull(tree.getParentItem());
+	}
+
+	public TableItemOrTreeItem[] getSelection() {
+		return wrapOrNull(tree.getSelection());
+	}
+
+	public int getSelectionCount() {
+		return tree.getSelectionCount();
+	}
+
+	public TableColumnOrTreeColumn getSortColumn() {
+		return wrapOrNull(tree.getSortColumn());
+	}
+
+	public int getSortDirection() {
+		return tree.getSortDirection();
+	}
+
+	public TableItemOrTreeItem getTopItem() {
+		return wrapOrNull(tree.getTopItem());
+	}
+
+	public int hashCode() {
+		return tree.hashCode();
+	}
+
+	public boolean isDisposed() {
+		return tree.isDisposed();
+	}
+
+	public void update() {
+		tree.update();
+	}
+
+	public int indexOf(TableColumnOrTreeColumn column) {
+		return tree.indexOf((TreeColumn) column.getColumn());
+	}
+
+	public int indexOf(TableItemOrTreeItem item) {
+		TreeItem ti = (TreeItem) item.getItem();
+		if (ti.isDisposed()) {
+			return -1;
+		}
+
+		InPaintInfo info = (InPaintInfo) tree.getData("inPaintInfo");
+		if (info != null && ti.equals(info.item)) {
+			Object data = tree.getData("lastIndex");
+			if (data instanceof Number) {
+				int idx = ((Number)data).intValue();
+				//System.out.println("yay " + idx);
+				return idx;
+			}
+		}
+
+		return tree.indexOf(ti);
+	}
+
+	public boolean setParent(Composite parent) {
+		return tree.setParent(parent);
+	}
+
+	public void removeAll() {
+		tree.removeAll();
+	}
+
+	public void removeSelectionListener(SelectionListener listener) {
+		tree.removeSelectionListener(listener);
+	}
+
+	public void removeTreeListener(TreeListener listener) {
+		tree.removeTreeListener(listener);
+	}
+
+	public void setInsertMark(TableItemOrTreeItem item, boolean before) {
+		tree.setInsertMark((TreeItem) item.getItem(), before);
+	}
+
+	public void setItemCount(int count) {
+		tree.setItemCount(count);
+	}
+
+	public void setLinesVisible(boolean show) {
+		tree.setLinesVisible(show);
+	}
+
+	public void select(TableItemOrTreeItem item) {
+		tree.select((TreeItem) item.getItem());
+	}
+
+	public void selectAll() {
+		tree.selectAll();
+	}
+
+	public void setColumnOrder(int[] order) {
+		tree.setColumnOrder(order);
+	}
+
+	public void setFont(Font font) {
+		tree.setFont(font);
+	}
+
+	public void setHeaderVisible(boolean show) {
+		tree.setHeaderVisible(show);
+	}
+
+	public void setRedraw(boolean redraw) {
+		tree.setRedraw(redraw);
+	}
+
+	public void setSelection(TableItemOrTreeItem item) {
+		tree.setSelection((TreeItem) item.getItem());
+	}
+
+	public void setSelection(TableItemOrTreeItem[] items) {
+		tree.setSelection(toTreeItemArray(items));
+	}
+
+	public void setSortColumn(TableColumnOrTreeColumn column) {
+		tree.setSortColumn(column == null ? null : (TreeColumn) column.getColumn());
+	}
+
+	public void setSortDirection(int direction) {
+		tree.setSortDirection(direction);
+	}
+
+	public void setTopItem(TableItemOrTreeItem item) {
+		tree.setTopItem((TreeItem) item.getItem());
+	}
+
+	public void showColumn(TableColumnOrTreeColumn column) {
+		tree.showColumn((TreeColumn) column.getColumn());
+	}
+
+	public void showItem(TableItemOrTreeItem item) {
+		tree.showItem((TreeItem) item.getItem());
+	}
+
+	public void showSelection() {
+		tree.showSelection();
+	}
+
+	///////
+	
+	private TableItemOrTreeItem wrapOrNull(TreeItem item) {
+		if (item == null) {
+			return null;
+		}
+		return TableOrTreeUtils.getEventItem(item);
+	}
+
+	private TableItemOrTreeItem[] wrapOrNull(TreeItem[] items) {
+		if (items == null) {
+			return null;
+		}
+		TableItemOrTreeItem[] returnItems = new TableItemOrTreeItem[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = TableOrTreeUtils.getEventItem(items[i]);
+		}
+		return returnItems;
+	}
+	
+	private TableColumnOrTreeColumn wrapOrNull(TreeColumn item) {
+		if (item == null) {
+			return null;
+		}
+		return new TreeColumnDelegate(item);
+	}
+
+	private TableColumnOrTreeColumn[] wrapOrNull(TreeColumn[] items) {
+		if (items == null) {
+			return null;
+		}
+		TableColumnOrTreeColumn[] returnItems = new TableColumnOrTreeColumn[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = new TreeColumnDelegate(items[i]);
+		}
+		return returnItems;
+	}
+	
+	private TreeItem[] toTreeItemArray(TableItemOrTreeItem[] items) {
+		if (items == null) {
+			return null;
+		}
+		TreeItem[] returnItems = new TreeItem[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = (TreeItem) items[i].getItem();
+		}
+		return returnItems;
+	}
+	
+	public int getTopIndex() {
+		
+		TreeItem topItem = tree.getTopItem();
+		if (topItem == null) {
+			return -1;
+		}
+		return tree.indexOf(topItem);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#getSelectionIndex()
+	public int getSelectionIndex() {
+		TreeItem[] selection = tree.getSelection();
+		if (selection == null || selection.length == 0) {
+			return -1;
+		}
+		return tree.indexOf(selection[0]);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#getSelectionIndices()
+	public int[] getSelectionIndices() {
+		TreeItem[] selection = tree.getSelection();
+		if (selection == null || selection.length == 0) {
+			return new int[0];
+		}
+		
+		int[] vals = new int[selection.length];
+		for (int i = 0; i < vals.length; i++) {
+			vals[i] = tree.indexOf(selection[i]);
+		}
+		return vals;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#setSelection(int[])
+	public void setSelection(int[] newSelectedRowIndices) {
+		TreeItem[] items = new TreeItem[newSelectedRowIndices.length];
+		int itemCount = tree.getItemCount();
+		for (int i = 0; i < items.length; i++) {
+			if (newSelectedRowIndices[i] >= 0 && newSelectedRowIndices[i] < itemCount) {
+				items[i] = tree.getItem(newSelectedRowIndices[i]);
+			}
+		}
+		tree.setSelection(items);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT#select(int[])
+	public void select(int[] newSelectedRowIndices) {
+		for (int i : newSelectedRowIndices) {
+			if (i >= 0) {
+				tree.select(tree.getItem(i));
+			}
+		}
+	}
+
+	public boolean isSelected(TableItemOrTreeItem item) {
+		TreeItem[] selection = tree.getSelection();
+		for (TreeItem treeItem : selection) {
+			if (treeItem == item.getItem()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public boolean equalsTableOrTree(TableOrTreeSWT tt) {
+		return tree.equals(tt.getComposite());
+	}
+
+	public TableItemOrTreeItem createNewItem(int style) {
+		return TableOrTreeUtils.createNewItem(this, style);
+	}
+
+  public TableColumnOrTreeColumn createNewColumn(int style) {
+  	return  new TreeColumnDelegate(this, style);
+  }
+  
+  public int indexOf(Widget item) {
+  	if (item instanceof TreeItem) {
+  		return tree.indexOf((TreeItem) item);
+  	}
+  	return -1;
+  }
+}
+
diff --git a/org/gudy/azureus2/ui/swt/views/table/impl/TreeItemDelegate.java b/org/gudy/azureus2/ui/swt/views/table/impl/TreeItemDelegate.java
new file mode 100644
index 0000000..8a23e13
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/impl/TreeItemDelegate.java
@@ -0,0 +1,334 @@
+/**
+ * Created on May 3, 2010
+ *
+ * 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.impl;
+
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+import org.gudy.azureus2.core3.util.LightHashMap;
+import org.gudy.azureus2.ui.swt.views.table.TableItemOrTreeItem;
+import org.gudy.azureus2.ui.swt.views.table.TableOrTreeSWT;
+
+/**
+ * @author TuxPaper
+ * @created May 3, 2010
+ *
+ */
+public class TreeItemDelegate implements TableItemOrTreeItem
+{
+	TreeItem item;
+
+	Map data = new LightHashMap(2);
+
+	int index = -1;
+
+	protected TreeItemDelegate(TreeItem treeItem) {
+		this.item = treeItem;
+	}
+
+	protected TreeItemDelegate(TableOrTreeSWT tree, int style) {
+		item = new TreeItem((Tree) tree.getComposite(), style);
+	}
+
+	public void addListener(int eventType, Listener listener) {
+		item.addListener(eventType, listener);
+	}
+
+	public void addDisposeListener(DisposeListener listener) {
+		item.addDisposeListener(listener);
+	}
+
+	public void clear(int index, boolean all) {
+		item.clear(index, all);
+	}
+
+	public void clearAll(boolean all) {
+		item.clearAll(all);
+	}
+
+	public void dispose() {
+		item.dispose();
+	}
+
+	public boolean equals(Object obj) {
+		if (obj instanceof TableItemOrTreeItem) {
+			return item.equals(((TableItemOrTreeItem) obj).getItem());
+		}
+		return item.equals(obj);
+	}
+
+	public Color getBackground() {
+		return item.getBackground();
+	}
+
+	public Color getBackground(int index) {
+		return item.getBackground(index);
+	}
+
+	public Rectangle getBounds() {
+		return item.getBounds();
+	}
+
+	public Rectangle getBounds(int index) {
+		return item.getBounds(index);
+	}
+
+	public Object getData() {
+		return getData(null);
+	}
+	
+	public Object getData(String key) {
+		synchronized (data) {
+			return data.get(key);
+		}
+	}
+
+	public Display getDisplay() {
+		return item.getDisplay();
+	}
+
+	public boolean getChecked() {
+		return item.getChecked();
+	}
+
+	public Listener[] getListeners(int eventType) {
+		return item.getListeners(eventType);
+	}
+
+	public boolean getExpanded() {
+		return item.getExpanded();
+	}
+
+	public int getStyle() {
+		return item.getStyle();
+	}
+
+	public Font getFont() {
+		return item.getFont();
+	}
+
+	public Font getFont(int index) {
+		return item.getFont(index);
+	}
+
+	public Color getForeground() {
+		return item.getForeground();
+	}
+
+	public Color getForeground(int index) {
+		return item.getForeground(index);
+	}
+
+	public boolean getGrayed() {
+		return item.getGrayed();
+	}
+
+	public void notifyListeners(int eventType, Event event) {
+		item.notifyListeners(eventType, event);
+	}
+
+	public TableItemOrTreeItem getItem(int index) {
+		TreeItem treeItem = item.getItem(index);
+		return TableOrTreeUtils.getEventItem(treeItem);
+	}
+
+	public int getItemCount() {
+		return item.getItemCount();
+	}
+
+	public TableItemOrTreeItem[] getItems() {
+		TreeItem[] items = item.getItems();
+		TableItemOrTreeItem[] returnItems = new TableItemOrTreeItem[items.length];
+		for (int i = 0; i < returnItems.length; i++) {
+			returnItems[i] = TableOrTreeUtils.getEventItem(items[i]);
+		}
+		return returnItems;
+	}
+
+	public Image getImage() {
+		return item.getImage();
+	}
+
+	public Image getImage(int index) {
+		return item.getImage(index);
+	}
+
+	public Rectangle getImageBounds(int index) {
+		return item.getImageBounds(index);
+	}
+
+	public void removeListener(int eventType, Listener listener) {
+		item.removeListener(eventType, listener);
+	}
+
+	public TableOrTreeSWT getParent() {
+		return TableOrTreeUtils.getTableOrTreeSWT(item.getParent());
+	}
+
+	public TableItemOrTreeItem getParentItem() {
+		TreeItem treeItem = item.getParentItem();
+		return TableOrTreeUtils.getEventItem(treeItem);
+	}
+
+	public String getText() {
+		return item.getText();
+	}
+
+	public String getText(int index) {
+		return item.getText(index);
+	}
+
+	public void removeDisposeListener(DisposeListener listener) {
+		item.removeDisposeListener(listener);
+	}
+
+	public Rectangle getTextBounds(int index) {
+		return item.getTextBounds(index);
+	}
+
+	public int hashCode() {
+		return item.hashCode();
+	}
+
+	public boolean isDisposed() {
+		return item.isDisposed();
+	}
+
+	public boolean isListening(int eventType) {
+		return item.isListening(eventType);
+	}
+
+	public int indexOf(TableItemOrTreeItem item2) {
+		return item.indexOf((TreeItem) item2.getItem());
+	}
+
+	public void removeAll() {
+		item.removeAll();
+	}
+
+	public void setBackground(Color color) {
+		item.setBackground(color);
+	}
+
+	public void setBackground(int index, Color color) {
+		item.setBackground(index, color);
+	}
+
+	public void setData(Object data) {
+		setData(null, data);
+	}
+	
+	public void setData(String key, Object value) {
+		synchronized (data) {
+			data.put(key, value);
+		}
+	}
+
+	public void setChecked(boolean checked) {
+		item.setChecked(checked);
+	}
+
+	private Boolean settingExpandTo = null;
+	public void setExpanded(boolean expanded) {
+		boolean wasExpanded = item.getExpanded();
+		item.setExpanded(expanded);
+		if (expanded != wasExpanded && (settingExpandTo == null || settingExpandTo != expanded)) {
+			try {
+				settingExpandTo = expanded;
+  			Event event = new Event();
+  			event.widget = item.getParent();
+  			event.item = item;
+  			event.type = expanded ? SWT.Expand : SWT.Collapse;
+  			item.getParent().notifyListeners(event.type, event);
+			} finally {
+				settingExpandTo = null;
+			}
+		}
+	}
+
+	public void setFont(Font font) {
+		item.setFont(font);
+	}
+
+	public String toString() {
+		return item.toString();
+	}
+
+	public void setFont(int index, Font font) {
+		item.setFont(index, font);
+	}
+
+	public void setForeground(Color color) {
+		item.setForeground(color);
+	}
+
+	public void setForeground(int index, Color color) {
+		item.setForeground(index, color);
+	}
+
+	public void setGrayed(boolean grayed) {
+		item.setGrayed(grayed);
+	}
+
+	public void setImage(Image[] images) {
+		item.setImage(images);
+	}
+
+	public void setImage(int index, Image image) {
+		item.setImage(index, image);
+	}
+
+	public void setImage(Image image) {
+		item.setImage(image);
+	}
+
+	public void setItemCount(int count) {
+		item.setItemCount(count);
+	}
+
+	public void setText(String[] strings) {
+		item.setText(strings);
+	}
+
+	public void setText(int index, String string) {
+		item.setText(index, string);
+	}
+
+	public void setText(String string) {
+		item.setText(string);
+	}
+
+	//////
+	
+	public Item getItem() {
+		return item;
+	}
+
+	protected int getStoredIndex() {
+		return index;
+	}
+	
+	protected void setStoredIndex(int i) {
+		index = i;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/painted/TableCellPainted.java b/org/gudy/azureus2/ui/swt/views/table/painted/TableCellPainted.java
new file mode 100644
index 0000000..e4a301f
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/painted/TableCellPainted.java
@@ -0,0 +1,361 @@
+package org.gudy.azureus2.ui.swt.views.table.painted;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+import org.gudy.azureus2.core3.util.AERunnable;
+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.tables.TableColumn;
+import org.gudy.azureus2.plugins.ui.tables.TableRow;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
+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.impl.TableCellSWTBase;
+
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+
+public class TableCellPainted
+	extends TableCellSWTBase
+{
+	private static final boolean DEBUG_CELLPAINT = false;
+
+	private Rectangle bounds;
+
+	private String text = "";
+
+	private int marginWidth;
+
+	private int marginHeight;
+
+	private boolean redrawScheduled;
+
+	private Color colorFG;
+
+	private Color colorBG;
+
+	public TableCellPainted(TableRowSWT row, TableColumnCore column, int pos) {
+		super(row, column);
+		tableColumn.invokeCellAddedListeners(TableCellPainted.this);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getDataSource()
+	 */
+	public Object getDataSource() {
+		if (isDisposed()) {
+			return null;
+		}
+		TableRowCore row = tableRow;
+		TableColumnCore col = tableColumn;
+
+		if (row == null || col == null) {
+			return (null);
+		}
+		return row.getDataSource(col.getUseCoreDataSource());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getTableColumn()
+	 */
+	public TableColumn getTableColumn() {
+		return tableColumn;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getTableRow()
+	 */
+	public TableRow getTableRow() {
+		return tableRow;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getTableID()
+	 */
+	public String getTableID() {
+		return tableRow.getTableID();
+	}
+
+	@SuppressWarnings("null")
+	public static boolean stringEquals(String s0, String s1) {
+		boolean s0Null = s0 == null;
+		boolean s1Null = s1 == null;
+		if (s0Null || s1Null) {
+			return s0Null == s1Null;
+		}
+		return s0.equals(s1);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getText()
+	 */
+	public String getText() {
+		if (hasFlag(FLAG_SORTVALUEISTEXT) && sortValue instanceof String) {
+			return (String) sortValue;
+		}
+
+		return text;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getSortValue()
+	 */
+	public Comparable<?> getSortValue() {
+		Comparable<?> value = super.getSortValue();
+		return value == null ? "" : value;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#isShown()
+	 */
+	public boolean isShown() {
+		return !isDisposed() && tableRow.getView().isColumnVisible(tableColumn);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMaxLines()
+	 */
+	public int getMaxLines() {
+		// TODO
+		return 1;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getWidth()
+	 */
+	public int getWidth() {
+		if (isDisposed()) {
+			return -1;
+		}
+		return tableColumn.getWidth() - 2 - (getMarginWidth() * 2);
+	}
+
+	public int getWidthRaw() {
+		if (isDisposed()) {
+			return -1;
+		}
+		return tableColumn.getWidth() - 2;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getHeight()
+	 */
+	public int getHeight() {
+		if (bounds == null) {
+			return tableRow.getView().getRowDefaultHeight();
+		}
+		return bounds.height - (getMarginHeight() * 2);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMarginHeight()
+	 */
+	public int getMarginHeight() {
+		return marginHeight;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#setMarginHeight(int)
+	 */
+	public void setMarginHeight(int height) {
+		marginHeight = height;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getMarginWidth()
+	 */
+	public int getMarginWidth() {
+		return marginWidth;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#setMarginWidth(int)
+	 */
+	public void setMarginWidth(int width) {
+		marginWidth = width;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.plugins.ui.tables.TableCell#getBackgroundGraphic()
+	 */
+	public Graphic getBackgroundGraphic() {
+		// WARNING: requires SWT Thread!
+		return new UISWTGraphicImpl(getBackgroundImage());
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableCellCore#locationChanged()
+	 */
+	public void locationChanged() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.impl.TableCellSWTBase#setCursorID(int)
+	 */
+	@Override
+	public boolean setCursorID(int cursorID) {
+		if (!super.setCursorID(cursorID)) {
+			return false;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (isDisposed() || tableRow == null) {
+					return;
+				}
+				if (isMouseOver()) {
+					TableViewSWT<?> view = (TableViewSWT<?>) tableRow.getView();
+					if (view != null) {
+						Composite composite = view.getComposite();
+						if (composite != null && !composite.isDisposed()) {
+							composite.setCursor(composite.getDisplay().getSystemCursor(
+									getCursorID()));
+						}
+					}
+				}
+			}
+		});
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableCellCore#redraw()
+	 */
+	public void redraw() {
+
+		if (tableRow==null || !tableRow.isVisible() || redrawScheduled) {
+			return;
+		}
+		redrawScheduled = true;
+		if (DEBUG_CELLPAINT) {
+			System.out.println(SystemTime.getCurrentTime() + "r"
+					+ tableRow.getIndex() + "c" + tableColumn.getPosition()
+					+ "} cellredraw via " + Debug.getCompressedStackTrace());
+		}
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				if (isDisposed()) {
+					return;
+				}
+				redrawScheduled = false;
+				if (DEBUG_CELLPAINT) {
+					System.out.println(SystemTime.getCurrentTime() + "r"
+							+ tableRow.getIndex() + "c" + tableColumn.getPosition()
+							+ "] cellredraw @ " + bounds);
+				}
+				if (bounds != null && tableRow != null) {
+					TableViewPainted view = (TableViewPainted) tableRow.getView();
+					if (view != null) {
+						view.swt_updateCanvasImage(bounds, false);
+					}
+				}
+			}
+		});
+	}
+
+	public boolean setForeground(Color color) {
+		// Don't need to set when not visible
+		if (isInvisibleAndCanRefresh()) {
+			return false;
+		}
+
+		if (color == colorFG || (color != null && color.equals(colorFG))
+				|| (colorFG != null && colorFG.equals(color))) {
+			return false;
+		}
+
+		colorFG = color;
+		setFlag(FLAG_VISUALLY_CHANGED_SINCE_REFRESH);
+
+		return true;
+	}
+
+	public Point getSize() {
+		if (bounds == null) {
+			return new Point(0, 0);
+		}
+		return new Point(bounds.width - (marginWidth * 2), bounds.height
+				- (marginHeight * 2));
+	}
+
+	public Rectangle getBounds() {
+		if (bounds == null) {
+			return new Rectangle(0, 0, 0, 0);
+		}
+		return new Rectangle(bounds.x + marginWidth, bounds.y + marginHeight,
+				bounds.width - (marginWidth * 2), bounds.height - (marginHeight * 2));
+	}
+
+	public Rectangle getBoundsRaw() {
+		if (bounds == null) {
+			return null;
+		}
+		return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
+	}
+
+	public Rectangle getBoundsOnDisplay() {
+		if (isDisposed() || tableRow == null) {
+			return null;
+		}
+		Rectangle bounds = getBoundsRaw();
+		if (bounds == null) {
+			return null;
+		}
+		TableViewPainted tv = ((TableViewPainted) tableRow.getView());
+		if (tv == null) {
+			return null;
+		}
+		Composite c = tv.getTableComposite();
+		if (c == null || c.isDisposed()) {
+			return null;
+		}
+		Point pt = c.toDisplay(bounds.x, bounds.y);
+		bounds.x = pt.x;
+		bounds.y = pt.y;
+		bounds.height = getHeight();
+		bounds.width = getWidthRaw();
+		return bounds;
+	}
+
+	public Image getBackgroundImage() {
+		if (bounds == null || bounds.isEmpty()) {
+			return null;
+		}
+
+		Image image = new Image(Display.getDefault(), bounds.width
+				- (marginWidth * 2), bounds.height - (marginHeight * 2));
+
+		GC gc = new GC(image);
+		gc.setForeground(getBackgroundSWT());
+		gc.setBackground(getBackgroundSWT());
+		gc.fillRectangle(0, 0, bounds.width, bounds.height);
+		gc.dispose();
+
+		return image;
+	}
+
+	public Color getForegroundSWT() {
+		return colorFG;
+	}
+
+	public Color getBackgroundSWT() {
+		return colorBG;
+	}
+
+	public void setBoundsRaw(Rectangle bounds) {
+		this.bounds = bounds;
+	}
+
+	@Override
+	public boolean uiSetText(String text) {
+		boolean bChanged = !stringEquals(this.text, text);
+		if (bChanged) {
+			this.text = text;
+		}
+		return bChanged;
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/painted/TableRowPainted.java b/org/gudy/azureus2/ui/swt/views/table/painted/TableRowPainted.java
new file mode 100644
index 0000000..5711a24
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/painted/TableRowPainted.java
@@ -0,0 +1,946 @@
+package org.gudy.azureus2.ui.swt.views.table.painted;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.Colors;
+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.TableViewSWT;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableCellSWTBase;
+import org.gudy.azureus2.ui.swt.views.table.impl.TableRowSWTBase;
+import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnSWTUtils;
+
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+import com.aelitis.azureus.ui.common.table.TableColumnCore;
+import com.aelitis.azureus.ui.common.table.TableRowCore;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+
+public class TableRowPainted
+	extends TableRowSWTBase
+{
+	private static final boolean DEBUG_SUBS = true;
+
+	private Point drawOffset = new Point(0, 0);
+
+	private int numSubItems;
+
+	private Object[] subDataSources;
+
+	private TableRowPainted[] subRows;
+
+	private Object subRows_sync;
+
+	private int subRowsHeight;
+
+	TableCellCore cellSort;
+
+	final static public Color[] alternatingColors = new Color[] {
+		null,
+		Colors.colorAltRow
+	};
+
+	private int height = 0;
+
+	private boolean initializing = true;
+
+	private Color colorFG = null;
+
+	private Color colorBG = null;
+
+	public TableRowPainted(TableRowCore parentRow, TableViewPainted tv,
+			Object dataSource, boolean triggerHeightChange) {
+		// in theory, TableRowPainted could have its own sync
+		// but in practice, I end up calling code within the sync which inevitably
+		// calls the TableView and causes locks.  So, use the TableView's sync!
+
+		super(tv.getSyncObject(), parentRow, tv, dataSource);
+		subRows_sync = tv.getSyncObject();
+
+		TableColumnCore sortColumn = tv.getSortColumn();
+		if (sortColumn != null
+				&& (parentRow == null || sortColumn.handlesDataSourceType(getDataSource(
+						false).getClass()))) {
+			cellSort = new TableCellPainted(TableRowPainted.this, sortColumn,
+					sortColumn.getPosition());
+		}
+
+		if (height == 0) {
+			setHeight(tv.getRowDefaultHeight(), false);
+		}
+		initializing = false;
+		if (triggerHeightChange) {
+			heightChanged(0, height);
+		}
+	}
+
+	private void buildCells() {
+		//debug("buildCells " + Debug.getCompressedStackTrace());
+		TableColumnCore[] visibleColumns = getView().getVisibleColumns();
+		if (visibleColumns == null) {
+			return;
+		}
+		synchronized (lock) {
+			mTableCells = new LinkedHashMap<String, TableCellCore>(
+					visibleColumns.length, 1);
+
+			TableColumn currentSortColumn = null;
+			if (cellSort != null) {
+				currentSortColumn = cellSort.getTableColumn();
+			}
+			TableRowCore parentRow = getParentRowCore();
+			// create all the cells for the column
+			for (int i = 0; i < visibleColumns.length; i++) {
+				if (visibleColumns[i] == null) {
+					continue;
+				}
+
+				if (parentRow != null
+						&& !visibleColumns[i].handlesDataSourceType(getDataSource(false).getClass())) {
+					mTableCells.put(visibleColumns[i].getName(), null);
+					continue;
+				}
+
+				//System.out.println(dataSource + ": " + tableColumns[i].getName() + ": " + tableColumns[i].getPosition());
+				TableCellCore cell = (currentSortColumn != null && visibleColumns[i].equals(currentSortColumn))
+						? cellSort : new TableCellPainted(TableRowPainted.this,
+								visibleColumns[i], i);
+				mTableCells.put(visibleColumns[i].getName(), cell);
+				//if (i == 10) cell.bDebug = true;
+			}
+		}
+	}
+
+	private void destroyCells() {
+		synchronized (lock) {
+			if (mTableCells != null) {
+				for (TableCellCore cell : mTableCells.values()) {
+					if (cell != null && cell != cellSort) {
+						cell.dispose();
+					}
+				}
+				mTableCells = null;
+			}
+		}
+	}
+
+	public TableViewPainted getViewPainted() {
+		return (TableViewPainted) getView();
+	}
+
+	/**
+	 * @param gc GC to draw to
+	 * @param drawBounds Area that needs redrawing
+	 * @param rowStartX where in the GC this row's x-axis starts
+	 * @param rowStartY where in the GC this row's y-axis starts
+	 * @param pos
+	 */
+	public void swt_paintGC(GC gc, Rectangle drawBounds, int rowStartX,
+			int rowStartY, int pos) {
+		if (isRowDisposed() || gc == null || gc.isDisposed() || drawBounds == null) {
+			return;
+		}
+		// done by caller
+		//if (!drawBounds.intersects(rowStartX, rowStartY, 9999, getHeight())) {
+		//	return;
+		//}
+
+		TableColumnCore[] visibleColumns = getView().getVisibleColumns();
+		if (visibleColumns == null || visibleColumns.length == 0) {
+			return;
+		}
+
+		boolean isSelected = isSelected();
+		boolean isSelectedNotFocused = isSelected && !getViewPainted().isTableSelected();
+		
+		Color origBG = gc.getBackground();
+		Color origFG = gc.getForeground();
+		
+		Color altColor = alternatingColors[pos >= 0 ? pos % 2 : 0];
+		if (altColor == null) {
+			altColor = gc.getDevice().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+		}
+		if (isSelected) {
+			Color color;
+			color = gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION);
+			gc.setBackground(color);
+		} else {
+			gc.setBackground(altColor);
+		}
+
+		Color bg = getBackground();
+		if (bg == null) {
+			bg = gc.getBackground();
+		} else {
+			gc.setBackground(bg);
+		}
+		Color fg = getForeground();
+		Color shadowColor = null;
+		if (isSelected) {
+			shadowColor = fg;
+			fg = gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
+			gc.setForeground(fg);
+		} else {
+  		if (fg == null) {
+  			if (isSelected) {
+  				fg = gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT);
+  			} else {
+  				fg = gc.getDevice().getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+  			}
+				gc.setForeground(fg);
+  		} else {
+  			gc.setForeground(fg);
+  		}
+		}
+
+		int rowAlpha = getAlpha();
+		Font font = gc.getFont();
+		Rectangle clipping = gc.getClipping();
+
+		int x = rowStartX;
+		//boolean paintedRow = false;
+		synchronized (lock) {
+			if (mTableCells != null) {
+				for (TableColumn tc : visibleColumns) {
+					TableCellCore cell = mTableCells.get(tc.getName());
+					int w = tc.getWidth();
+					if (!(cell instanceof TableCellPainted) || cell.isDisposed()) {
+						gc.fillRectangle(x, rowStartY, w, getHeight());
+						x += w;
+						continue;
+					}
+					TableCellPainted cellSWT = (TableCellPainted) cell;
+					Rectangle r = new Rectangle(x, rowStartY, w, getHeight());
+					cellSWT.setBoundsRaw(r);
+					if (drawBounds.intersects(r)) {
+						//paintedRow = true;
+						gc.setAlpha(255);
+						if (isSelectedNotFocused) {
+							gc.setBackground(altColor);
+							gc.fillRectangle(r);
+							gc.setAlpha(100);
+							gc.setBackground(bg);
+							gc.fillRectangle(r);
+						} else {
+							gc.setBackground(bg);
+							gc.fillRectangle(r);
+							if (isSelected) {
+  							gc.setAlpha(80);
+  							gc.setForeground(altColor);
+  							gc.fillGradientRectangle(r.x, r.y, r.width, r.height, true);
+  							gc.setForeground(fg);
+							}
+						}
+						gc.setAlpha(rowAlpha);
+						if (swt_paintCell(gc, cellSWT.getBounds(), cellSWT, shadowColor)) {
+							// row color may have changed; this would update the color
+							// for all new cells.  However, setting color triggers a
+							// row redraw that will fix up the UI
+							//Color fgNew = getForeground();
+							//if (fgNew != null && fgNew != fg) {
+							//	fg = fgNew;
+							//}
+							gc.setBackground(bg);
+							gc.setForeground(fg);
+							gc.setFont(font);
+							gc.setClipping(clipping);
+						}
+						if (DEBUG_ROW_PAINT) {
+							((TableCellSWTBase) cell).debug("painted "
+									+ (cell.getVisuallyChangedSinceRefresh() ? "VC" : "!P")
+									+ " @ " + r);
+						}
+					} else {
+						if (DEBUG_ROW_PAINT) {
+							((TableCellSWTBase) cell).debug("Skip paintItem; no intersects; r="
+									+ r
+									+ ";dB="
+									+ drawBounds
+									+ " from "
+									+ Debug.getCompressedStackTrace(4));
+						}
+					}
+
+					x += w;
+				}
+			}
+			int w = drawBounds.width - x;
+			if (w > 0) {
+				Rectangle r = new Rectangle(x, rowStartY, w, getHeight());
+				gc.setAlpha(255);
+				if (isSelectedNotFocused) {
+					gc.setBackground(altColor);
+					gc.fillRectangle(r);
+					gc.setAlpha(100);
+					gc.setBackground(bg);
+					gc.fillRectangle(r);
+				} else {
+					gc.fillRectangle(r);
+					if (isSelected) {
+						gc.setAlpha(80);
+						gc.setForeground(altColor);
+						gc.fillGradientRectangle(r.x, r.y, r.width, r.height, true);
+						gc.setForeground(fg);
+					}
+				}
+				gc.setAlpha(rowAlpha);
+			}
+
+		}
+
+		//if (paintedRow) {
+		//	debug("Paint " + e.x + "x" + e.y + " " + e.width + "x" + e.height + ".." + e.count + ";clip=" + e.gc.getClipping() +";drawOffset=" + drawOffset + " via " + Debug.getCompressedStackTrace());
+		//}
+
+		if (isFocused()) {
+			gc.setAlpha(40);
+			gc.setForeground(origFG);
+			gc.setLineStyle(SWT.LINE_DOT);
+			gc.drawRectangle(0, rowStartY,
+					getViewPainted().getClientArea().width - 1, getHeight() - 1);
+			gc.setLineStyle(SWT.LINE_SOLID);
+		}
+
+		gc.setAlpha(255);
+		gc.setBackground(origBG);
+		gc.setForeground(origFG);
+	}
+
+	private boolean swt_paintCell(GC gc, Rectangle cellBounds,
+			TableCellSWTBase cell, Color shadowColor) {
+		// Only called from swt_PaintGC, so we can assume GC, cell are valid
+		if (cellBounds == null) {
+			return false;
+		}
+
+		boolean gcChanged = false;
+		try {
+
+			gc.setTextAntialias(SWT.DEFAULT);
+
+			TableViewSWT<?> view = (TableViewSWT<?>) getView();
+
+			TableColumnCore column = (TableColumnCore) cell.getTableColumn();
+			view.invokePaintListeners(gc, this, column, cellBounds);
+
+			int fontStyle = getFontStyle();
+			Font oldFont = null;
+			if (fontStyle == SWT.BOLD) {
+				oldFont = gc.getFont();
+				gc.setFont(FontUtils.getAnyFontBold(gc));
+				gcChanged = true;
+			}
+
+			if (!cell.isUpToDate()) {
+				//System.out.println("R " + rowIndex + ":" + iColumnNo);
+				cell.refresh(true, true);
+				//return;
+			}
+
+			String text = cell.getText();
+
+			Color fg = cell.getForegroundSWT();
+			if (fg != null) {
+				gcChanged = true;
+				if (isSelected()) {
+					shadowColor = fg;
+				} else {
+					gc.setForeground(fg);
+				}
+			}
+			Color bg = cell.getBackgroundSWT();
+			if (bg != null) {
+				gcChanged = true;
+				gc.setBackground(bg);
+			}
+
+			//if (cell.getTableColumn().getClass().getSimpleName().equals("ColumnUnopened")) {
+			//	System.out.println("FOOO" + cell.needsPainting());
+			//}
+			if (cell.needsPainting()) {
+				Image graphicSWT = cell.getGraphicSWT();
+				if (graphicSWT != null && !graphicSWT.isDisposed()) {
+					Rectangle imageBounds = graphicSWT.getBounds();
+					Rectangle graphicBounds = new Rectangle(cellBounds.x, cellBounds.y,
+							cellBounds.width, cellBounds.height);
+					if (cell.getFillCell()) {
+						if (!graphicBounds.isEmpty()) {
+							gc.setAdvanced(true);
+							//System.out.println(imageBounds + ";" + graphicBounds);
+							gc.drawImage(graphicSWT, 0, 0, imageBounds.width,
+									imageBounds.height, graphicBounds.x, graphicBounds.y,
+									graphicBounds.width, graphicBounds.height);
+						}
+					} else {
+
+						if (imageBounds.width < graphicBounds.width) {
+							int alignment = column.getAlignment();
+							if ((alignment & TableColumn.ALIGN_CENTER) > 0) {
+								graphicBounds.x += (graphicBounds.width - imageBounds.width) / 2;
+							} else if ((alignment & TableColumn.ALIGN_TRAIL) > 0) {
+								graphicBounds.x = (graphicBounds.x + graphicBounds.width)
+										- imageBounds.width;
+							}
+						}
+
+						if (imageBounds.height < graphicBounds.height) {
+							graphicBounds.y += (graphicBounds.height - imageBounds.height) / 2;
+						}
+
+						gc.drawImage(graphicSWT, graphicBounds.x, graphicBounds.y);
+					}
+
+				}
+				cell.doPaint(gc);
+				gcChanged = true;
+			}
+			if (text.length() > 0) {
+				int ofsx = 0;
+				Image image = cell.getIcon();
+				Rectangle imageBounds = null;
+				if (image != null && !image.isDisposed()) {
+					imageBounds = image.getBounds();
+					int ofs = imageBounds.width;
+					ofsx += ofs;
+					cellBounds.x += ofs;
+					cellBounds.width -= ofs;
+				}
+				//System.out.println("PS " + rowIndex + ";" + cellBounds + ";" + cell.getText());
+				int style = TableColumnSWTUtils.convertColumnAlignmentToSWT(column.getAlignment());
+				if (cellBounds.height > 20) {
+					style |= SWT.WRAP;
+				}
+				int textOpacity = cell.getTextAlpha();
+				//gc.setFont(getRandomFont());
+				//textOpacity = 130;
+				if (textOpacity < 255) {
+					//gc.setTextAntialias(SWT.ON);
+					gc.setAlpha(textOpacity);
+					gcChanged = true;
+				} else if (textOpacity > 255) {
+					gc.setFont(FontUtils.getAnyFontBold(gc));
+					//gc.setTextAntialias(SWT.ON);
+					//gc.setAlpha(textOpacity & 255);
+					gcChanged = true;
+				}
+				// put some padding on text
+				ofsx += 6;
+				cellBounds.x += 3;
+				cellBounds.width -= 6;
+				cellBounds.y += 2;
+				cellBounds.height -= 4;
+				if (!cellBounds.isEmpty()) {
+					GCStringPrinter sp = new GCStringPrinter(gc, text, cellBounds, true,
+							cellBounds.height > 20, style);
+
+					boolean fit;
+					if (shadowColor != null) {
+						Color oldFG = gc.getForeground();
+						gc.setForeground(shadowColor);
+						
+						cellBounds.x += 1;
+						cellBounds.y += 1;
+						int alpha = gc.getAlpha();
+						gc.setAlpha(0x40);
+						sp.printString(gc, cellBounds, style);
+						gc.setAlpha(alpha);
+						gc.setForeground(oldFG);
+
+						cellBounds.x -= 1;
+						cellBounds.y -= 1;
+						fit = sp.printString2(gc, cellBounds, style);
+					} else {
+						fit = sp.printString();
+					}
+					
+					if (fit) {
+
+						cell.setDefaultToolTip(null);
+					} else {
+
+						cell.setDefaultToolTip(text);
+					}
+
+					Point size = sp.getCalculatedSize();
+					size.x += ofsx;
+
+					TableColumn tableColumn = cell.getTableColumn();
+					if (tableColumn != null && tableColumn.getPreferredWidth() < size.x) {
+						tableColumn.setPreferredWidth(size.x);
+					}
+
+					if (imageBounds != null) {
+						int drawToY = cellBounds.y + (cellBounds.height / 2)
+								- (imageBounds.height / 2);
+						if ((style & SWT.RIGHT) > 0) {
+							int drawToX = cellBounds.x + cellBounds.width - size.x;
+							gc.drawImage(image, drawToX, drawToY);
+						} else {
+							gc.drawImage(image, cellBounds.x - imageBounds.width - 3, drawToY);
+						}
+					}
+				} else {
+					cell.setDefaultToolTip(null);
+				}
+			}
+			cell.clearVisuallyChangedSinceRefresh();
+			
+			if (oldFont != null) {
+				gc.setFont(oldFont);
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		return gcChanged;
+	}
+
+	private Font getRandomFont() {
+		FontData[] fontList = Display.getDefault().getFontList(null, (Math.random() > 0.5));
+		FontData fontData = fontList[(int)(Math.random() * fontList.length)];
+		fontData.setStyle((int)(Math.random() * 4));
+		fontData.height = (float) (Math.random() * 50f);
+		return new Font(Display.getDefault(), fontData);
+	}
+
+	@Override
+	public List<TableCellCore> refresh(boolean bDoGraphics, boolean bVisible) {
+		final List<TableCellCore> invalidCells = super.refresh(bDoGraphics,
+				bVisible);
+		//System.out.print(SystemTime.getCurrentTime() + "] InvalidCells: ");
+		if (invalidCells.size() > 0) {
+			//for (TableCellCore cell : invalidCells) {
+			//	System.out.print(cell.getTableColumn().getName() + ", ");
+			//}
+			//System.out.println();
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					Composite composite = getViewPainted().getComposite();
+					if (composite == null || composite.isDisposed() || !isVisible()) {
+						return;
+					}
+					boolean allCells = (mTableCells != null)
+							&& invalidCells.size() == mTableCells.size();
+					if (allCells) {
+						getViewPainted().swt_updateCanvasImage(getDrawBounds(), false);
+					} else {
+						for (Object o : invalidCells) {
+							if (o instanceof TableCellPainted) {
+								TableCellPainted cell = (TableCellPainted) o;
+								Rectangle bounds = cell.getBoundsRaw();
+								if (bounds != null) {
+									getViewPainted().swt_updateCanvasImage(bounds, false);
+								}
+							}
+						}
+					}
+				}
+			});
+			//} else {
+			//System.out.println("NONE");
+		}
+		return invalidCells;
+	}
+
+	public void redraw(boolean doChildren) {
+		redraw(doChildren, false);
+	}
+
+	public void redraw(boolean doChildren, boolean immediateRedraw) {
+		if (isRowDisposed()) {
+			return;
+		}
+		getViewPainted().redrawRow(this, immediateRedraw);
+
+		if (!doChildren) {
+			return;
+		}
+		synchronized (subRows_sync) {
+			if (subRows != null) {
+				for (TableRowPainted subrow : subRows) {
+					subrow.redraw();
+				}
+			}
+		}
+	}
+
+	protected void debug(String s) {
+		AEDiagnosticsLogger diag_logger = AEDiagnostics.getLogger("table");
+		String prefix = SystemTime.getCurrentTime() + ":" + getTableID() + ": r"
+				+ getIndex();
+		if (getParentRowCore() != null) {
+			prefix += "of" + getParentRowCore().getIndex();
+		}
+		prefix += ": ";
+		diag_logger.log(prefix + s);
+
+		System.out.println(prefix + s);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.impl.TableRowSWTBase#getBounds()
+	 */
+	@Override
+	public Rectangle getBounds() {
+		//TableViewPainted view = (TableViewPainted) getView();
+		//Rectangle clientArea = view.getClientArea();
+		return new Rectangle(0, drawOffset.y, 9990, getHeight());
+	}
+
+	public Rectangle getDrawBounds() {
+		TableViewPainted view = (TableViewPainted) getView();
+		Rectangle clientArea = view.getClientArea();
+		Rectangle bounds = new Rectangle(0, drawOffset.y - clientArea.y, 9990,
+				getHeight());
+		return bounds;
+	}
+
+	public int getFullHeight() {
+		int h = getHeight();
+		if (numSubItems > 0 && isExpanded()) {
+			h += subRowsHeight;
+		}
+		return h;
+	}
+
+	public Point getDrawOffset() {
+		return drawOffset;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.impl.TableRowSWTBase#heightChanged(int, int)
+	 */
+	public void heightChanged(int oldHeight, int newHeight) {
+		getViewPainted().rowHeightChanged(this, oldHeight, newHeight);
+		TableRowCore row = getParentRowCore();
+		if (row instanceof TableRowPainted) {
+			((TableRowPainted) row).subRowHeightChanged(this, oldHeight, newHeight);
+		}
+	}
+
+	public void subRowHeightChanged(TableRowCore row, int oldHeight, int newHeight) {
+		subRowsHeight += (newHeight - oldHeight);
+	}
+
+	public boolean setDrawOffset(Point drawOffset) {
+		if (drawOffset.equals(this.drawOffset)) {
+			return false;
+		}
+		this.drawOffset = drawOffset;
+
+		return true;
+	}
+
+	@Override
+	public void setWidgetSelected(boolean selected) {
+		redraw(false, true);
+	}
+
+	@Override
+	public void setShown(boolean b, boolean force) {
+		synchronized (lock) {
+			if (b && mTableCells == null) {
+				buildCells();
+			}
+		}
+
+		super.setShown(b, force);
+		if (!b && mTableCells != null) {
+			destroyCells();
+		}
+	}
+	
+	@Override
+	public void delete() {
+		super.delete();
+		
+		deleteExistingSubRows();
+	}
+
+	private void deleteExistingSubRows() {
+		synchronized (subRows_sync) {
+			if (subRows != null) {
+				for (TableRowPainted subrow : subRows) {
+					subrow.delete();
+				}
+			}
+			subRows = null;
+		}
+	}
+
+	public void setSubItemCount(int length) {
+		numSubItems = length;
+		if (isExpanded() && subDataSources.length == length) {
+			if (DEBUG_SUBS) {
+				debug("setSubItemCount to " + length);
+			}
+
+			deleteExistingSubRows();
+			TableRowPainted[] newSubRows = new TableRowPainted[length];
+			TableViewPainted tv = getViewPainted();
+			int h = 0;
+			for (int i = 0; i < newSubRows.length; i++) {
+				newSubRows[i] = new TableRowPainted(this, tv, subDataSources[i], false);
+				newSubRows[i].setTableItem(i, false);
+				h += newSubRows[i].getHeight();
+			}
+
+			int oldHeight = getFullHeight();
+			subRowsHeight = h;
+			getViewPainted().rowHeightChanged(this, oldHeight, getFullHeight());
+			getViewPainted().triggerListenerRowAdded(newSubRows);
+
+			subRows = newSubRows;
+		}
+	}
+
+	public int getSubItemCount() {
+		return numSubItems;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#linkSubItem(int)
+	 */
+	public TableRowCore linkSubItem(int indexOf) {
+		// Not used by TableViewPainted
+		return null;
+	}
+
+	public void setSubItems(Object[] datasources) {
+		deleteExistingSubRows();
+		subDataSources = datasources;
+		subRowsHeight = 0;
+		setSubItemCount(datasources.length);
+	}
+
+	public TableRowCore[] getSubRowsWithNull() {
+		synchronized (subRows_sync) {
+			return subRows == null ? new TableRowCore[0] : subRows;
+		}
+	}
+
+	public void removeSubRow(Object datasource) {
+		synchronized (subRows_sync) {
+
+			for (int i = 0; i < subDataSources.length; i++) {
+				Object ds = subDataSources[i];
+				if (ds == datasource) { // use .equals instead?
+					TableRowPainted rowToDel = subRows[i];
+					TableRowPainted[] newSubRows = new TableRowPainted[subRows.length - 1];
+					System.arraycopy(subRows, 0, newSubRows, 0, i);
+					System.arraycopy(subRows, i + 1, newSubRows, i, subRows.length - i
+							- 1);
+					subRows = newSubRows;
+
+					Object[] newDatasources = new Object[subRows.length];
+					System.arraycopy(subDataSources, 0, newDatasources, 0, i);
+					System.arraycopy(subDataSources, i + 1, newDatasources, i,
+							subDataSources.length - i - 1);
+					subDataSources = newDatasources;
+
+					rowToDel.delete();
+
+					setSubItemCount(subRows.length);
+
+					break;
+				}
+			}
+		}
+	}
+
+	@Override
+	public void setExpanded(boolean b) {
+		int oldHeight = getFullHeight();
+		super.setExpanded(b);
+		synchronized (subRows_sync) {
+			TableRowPainted[] newSubRows = null;
+			if (b && (subRows == null || subRows.length != numSubItems)
+					&& subDataSources != null && subDataSources.length == numSubItems) {
+				if (DEBUG_SUBS) {
+					debug("building subrows " + numSubItems);
+				}
+
+				deleteExistingSubRows();
+				newSubRows = new TableRowPainted[numSubItems];
+				TableViewPainted tv = getViewPainted();
+				int h = 0;
+				for (int i = 0; i < newSubRows.length; i++) {
+					newSubRows[i] = new TableRowPainted(this, tv, subDataSources[i],
+							false);
+					newSubRows[i].setTableItem(i, false);
+					h += newSubRows[i].getHeight();
+				}
+
+				subRowsHeight = h;
+
+				subRows = newSubRows;
+			}
+
+			getViewPainted().rowHeightChanged(this, oldHeight, getFullHeight());
+
+			if (newSubRows != null) {
+				getViewPainted().triggerListenerRowAdded(newSubRows);
+			}
+
+		}
+		if (isVisible()) {
+			getViewPainted().visibleRowsChanged();
+			getViewPainted().redrawTable();
+		}
+	}
+
+	public TableRowCore getSubRow(int pos) {
+		synchronized (subRows_sync) {
+			if (subRows == null) {
+				return null;
+			}
+			if (pos >= 0 && pos < subRows.length) {
+				return subRows[pos];
+			}
+			return null;
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.impl.TableRowSWTBase#setForeground(org.eclipse.swt.graphics.Color)
+	 */
+	@Override
+	public boolean setForeground(Color color) {
+		if (isRowDisposed()) {
+			return false;
+		}
+		if (color == colorFG || (color != null && color.equals(colorFG))
+				|| (colorFG != null && colorFG.equals(color))) {
+			return false;
+		}
+
+		colorFG = color;
+		//delays redraw until after.  Could use execSWTThreadLater
+		Utils.getOffOfSWTThread(new AERunnable() {
+			public void runSupport() {
+				redraw(false, false);
+			}
+		});
+
+		return true;
+	}
+
+	@Override
+	public boolean setIconSize(Point pt) {
+		//TODO
+		return false;
+	}
+
+	@Override
+	public Color getForeground() {
+		return colorFG;
+	}
+
+	@Override
+	public Color getBackground() {
+		return colorBG;
+	}
+
+	@Override
+	public void setBackgroundImage(Image image) {
+		//TODO
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#getHeight()
+	 */
+	public int getHeight() {
+		return height == 0 ? getView().getRowDefaultHeight() : height;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableRowCore#setHeight(int)
+	 */
+	public boolean setHeight(int newHeight) {
+		TableRowCore parentRowCore = getParentRowCore();
+		boolean trigger = parentRowCore == null || parentRowCore.isExpanded();
+
+		return setHeight(newHeight, trigger);
+	}
+
+	public boolean setHeight(int newHeight, boolean trigger) {
+		if (height == newHeight) {
+			return false;
+		}
+		int oldHeight = height;
+		height = newHeight;
+		if (trigger && !initializing) {
+			heightChanged(oldHeight, newHeight);
+		}
+
+		return true;
+	}
+
+	@Override
+	public TableCellCore getTableCellCore(String name) {
+		if (isRowDisposed()) {
+			return null;
+		}
+		synchronized (lock) {
+			if (mTableCells == null) {
+				if (cellSort != null && !cellSort.isDisposed()
+						&& cellSort.getTableColumn().getName().equals(name)) {
+					return cellSort;
+				} else {
+					return null;
+				}
+			}
+			return mTableCells.get(name);
+		}
+	}
+
+	@Override
+	public TableCellSWT getTableCellSWT(String name) {
+		TableCellCore cell = getTableCellCore(name);
+		return (cell instanceof TableCellSWT) ? (TableCellSWT) cell : null;
+	}
+
+	@Override
+	public TableCell getTableCell(String field) {
+		return getTableCellCore(field);
+	}
+
+	public TableCellCore getSortColumnCell(String hint) {
+		return cellSort;
+	}
+
+	public void setSortColumn(String columnID) {
+		synchronized (lock) {
+
+			if (mTableCells == null) {
+				if (cellSort != null && !cellSort.isDisposed()) {
+					if (cellSort.getTableColumn().getName().equals(columnID)) {
+						return;
+					}
+					cellSort.dispose();
+					cellSort = null;
+				}
+				TableColumnCore sortColumn = (TableColumnCore) getView().getTableColumn(
+						columnID);
+				if (getParentRowCore() == null
+						|| sortColumn.handlesDataSourceType(getDataSource(false).getClass())) {
+					cellSort = new TableCellPainted(TableRowPainted.this, sortColumn,
+							sortColumn.getPosition());
+				} else {
+					cellSort = null;
+				}
+			} else {
+				cellSort = mTableCells.get(columnID);
+			}
+		}
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/painted/TableViewPainted.java b/org/gudy/azureus2/ui/swt/views/table/painted/TableViewPainted.java
new file mode 100644
index 0000000..fe4472a
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/table/painted/TableViewPainted.java
@@ -0,0 +1,2947 @@
+package org.gudy.azureus2.ui.swt.views.table.painted;
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+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.internat.MessageText.MessageTextListener;
+import org.gudy.azureus2.core3.util.*;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.plugins.ui.tables.TableColumn;
+import org.gudy.azureus2.ui.swt.MenuBuildUtils;
+import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
+import org.gudy.azureus2.ui.swt.Utils;
+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.mainwindow.HSLColor;
+import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.views.table.*;
+import org.gudy.azureus2.ui.swt.views.table.impl.*;
+
+import com.aelitis.azureus.ui.common.table.*;
+import com.aelitis.azureus.ui.common.table.TableViewFilterCheck;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
+import com.aelitis.azureus.ui.common.table.impl.TableRowCoreSorter;
+import com.aelitis.azureus.ui.common.table.impl.TableViewImpl;
+import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentListener;
+import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+import com.aelitis.azureus.ui.swt.utils.ColorCache;
+import com.aelitis.azureus.ui.swt.utils.FontUtils;
+
+/**
+ * A TableView implemented by painting on a canvas
+ * 
+ * TODO: 
+ * Keyboard Selection
+ * Cursor
+ * Column move and resize past bounds
+ */
+public class TableViewPainted
+	extends TableViewImpl<Object>
+	implements ParameterListener, TableViewSWT<Object>, ObfusticateImage,
+	MessageTextListener
+{
+
+	private static final boolean DEBUG_ROWCHANGE = false;
+
+	private static final boolean DEBUG_WITH_SHELL = false;
+
+	private static final int DEFAULT_HEADER_HEIGHT = 27;
+
+	private Composite cTable;
+
+	private int loopFactor;
+
+	/** How often graphic cells get updated
+	 */
+	protected int graphicsUpdate = configMan.getIntParameter("Graphics Update");
+
+	protected int reOrderDelay = configMan.getIntParameter("ReOrder Delay");
+	
+	protected boolean extendedErase = configMan.getBooleanParameter("Table.extendedErase");
+
+	private int defaultRowHeight = 17;
+
+	/**
+	 * Rows visible to user.  We assume this list is always up to date
+	 */
+	LinkedHashSet<TableRowPainted> visibleRows = new LinkedHashSet<TableRowPainted>();
+	
+	Object visibleRows_sync = new Object();
+
+	Object lock = new Object();
+
+	/**
+	 * Up to date table client area.  So far, the best places to refresh
+	 * this variable are in the PaintItem event and the scrollbar's events.
+	 * Typically table.getClientArea() is time consuming 
+	 */
+	protected Rectangle clientArea;
+
+	private boolean isVisible;
+
+	private Shell shell;
+
+	private Color colorLine;
+
+	private int headerHeight;
+
+	private Canvas cHeaderArea;
+
+	private Image canvasImage;
+
+	private final String sDefaultSortOn;
+
+	private TableViewSWT_Common tvSWTCommon;
+
+	private TableViewSWT_TabsCommon tvTabsCommon;
+
+	private TableViewSWTPanelCreator mainPanelCreator;
+
+	private boolean isMultiSelect;
+
+	private int columnsWidth;
+
+	private Menu menu;
+
+	protected boolean isHeaderDragging;
+
+	private TableRowPainted focusedRow;
+
+	private boolean enableTabViews;
+
+	protected boolean isDragging;
+
+	private Composite mainComposite;
+
+	private Object heightChangeSync = new Object();
+	private int totalHeight = 0;
+
+	private boolean redrawTableScheduled;
+
+	private Font fontHeaderSmall;
+	private Font fontHeader;
+
+	private ScrollBar hBar;
+
+	private ScrollBar vBar;
+	
+	private Canvas sCanvasImage;
+
+	class RefreshTableRunnable extends AERunnable {
+		private boolean forceSort;
+		public void runSupport() {
+			__refreshTable(isForceSort());
+		}
+		public boolean isForceSort() {
+			return forceSort;
+		}
+		public void setForceSort(boolean forceSort) {
+			this.forceSort = forceSort;
+		}
+	}
+	
+	private RefreshTableRunnable refreshTableRunnable = new RefreshTableRunnable();
+
+	protected boolean isFocused;
+
+	/**
+	 * Main Initializer
+	 * @param _sTableID Which table to handle (see 
+	 *                   {@link org.gudy.azureus2.plugins.ui.tables.TableManager}).
+	 *                   Config settings are stored with the prefix of  
+	 *                   "Table.<i>TableID</i>"
+	 * @param _sPropertiesPrefix Prefix for retrieving text from the properties
+	 *                            file (MessageText).  Typically 
+	 *                            <i>TableID</i> + "View"
+	 * @param _basicItems Column Definitions
+	 * @param _sDefaultSortOn Column name to sort on if user hasn't chosen one yet
+	 * @param _iTableStyle SWT style constants used when creating the table
+	 */
+	public TableViewPainted(Class<?> pluginDataSourceType, String _sTableID,
+			String _sPropertiesPrefix, TableColumnCore[] _basicItems,
+			String _sDefaultSortOn, int _iTableStyle) {
+		super(pluginDataSourceType, _sTableID, _sPropertiesPrefix, _basicItems);
+		setRowsSync(lock);
+		//		boolean wantTree = (_iTableStyle & SWT.CASCADE) != 0;
+		//		_iTableStyle &= ~SWT.CASCADE;
+		//		if (wantTree) {
+		//			useTree = COConfigurationManager.getBooleanParameter("Table.useTree")
+		//					&& !Utils.isCarbon;
+		//		}
+		//		basicItems = _basicItems;
+		//		sDefaultSortOn = _sDefaultSortOn;
+		//		iTableStyle = _iTableStyle | SWT.V_SCROLL | SWT.DOUBLE_BUFFERED;
+		this.sDefaultSortOn = _sDefaultSortOn;
+		this.isMultiSelect = (_iTableStyle & SWT.MULTI) > 0;
+		
+		// Deselect rows if user clicks on a blank spot (a spot with no row)
+		tvSWTCommon = new TableViewSWT_Common(this) {
+			public void widgetSelected(SelectionEvent event) {
+				//updateSelectedRows(table.getSelection(), true);
+			}
+
+			@Override
+			public void mouseUp(TableRowCore clickedRow, TableCellCore cell, int button,
+					int stateMask) {
+				super.mouseUp(clickedRow, cell, button, stateMask);
+				
+				if (clickedRow == null) {
+					return;
+				}
+				if (button == 1) {
+  				int keyboardModifier = (stateMask & SWT.MODIFIER_MASK);
+  				if ((keyboardModifier & SWT.SHIFT) > 0) {
+  					// select from focus to row
+  					selectRowsTo(clickedRow);
+  					return;
+  				} else if (keyboardModifier == 0) {
+  					setSelectedRows(new TableRowCore[] {
+  						clickedRow
+  					});
+  					return;
+  				}
+				}
+			}
+
+			@Override
+			public void mouseDown(TableRowSWT clickedRow, TableCellCore cell, int button,
+					int stateMask) {
+				if (clickedRow == null) {
+					return;
+				}
+				int keyboardModifier = (stateMask & SWT.MODIFIER_MASK);
+				if (button == 1) {
+  				if ((keyboardModifier & (SWT.MOD1)) > 0) {
+  					// control (win), alt (mac)
+  					setRowSelected(clickedRow, !clickedRow.isSelected(), true);
+  					return;
+  				} 
+				} else if (button == 3) {
+					if (!isSelected(clickedRow) && keyboardModifier == 0) {
+						setSelectedRows(new TableRowCore[] {
+							clickedRow
+						});
+					}
+				}
+				if (getSelectedRowsSize() == 0) {
+					setSelectedRows(new TableRowCore[] {
+						clickedRow
+					});
+				}
+			}
+
+			@Override
+			public void keyPressed(KeyEvent event) {
+				if (getComposite() != event.widget) {
+					super.keyPressed(event);	
+					return;
+				}
+				boolean updateTable = false;
+				if (event.keyCode == SWT.ARROW_UP) {
+					TableRowCore rowToSelect = getPreviousRow(focusedRow);
+					if ((event.stateMask & SWT.SHIFT) > 0) {
+						if (rowToSelect != null) {
+							TableRowCore[] selectedRows = getSelectedRows();
+							Arrays.sort(selectedRows, new TableRowCoreSorter());
+							boolean select = selectedRows.length == 0
+									|| selectedRows[0] == focusedRow;
+//							System.out.println("i=" + selectedRows[0].getIndex() + ";"
+//									+ select + ";" + focusedRow.getIndex());
+							if (select) {
+								rowToSelect.setSelected(select);
+							} else {
+								focusedRow.setSelected(false);
+								setFocusedRow(rowToSelect);
+							}
+							updateTable = true;
+						}
+					} else if ((event.stateMask & SWT.CONTROL) > 0) {
+						// show one more topRow
+						TableRowPainted firstRow = visibleRows.iterator().next();
+						if (firstRow != null) {
+							int hChange = 0;
+							if (isRowPartiallyVisible(firstRow)) {
+								hChange =  firstRow.getDrawOffset().y  - clientArea.y;
+							} else {
+  							TableRowCore prevRow = getPreviousRow(firstRow);
+  							if (prevRow != firstRow && prevRow != null) {
+  								hChange = -prevRow.getHeight();
+  							}
+							}
+							vBar.setSelection(vBar.getSelection() + hChange);
+							swt_vBarChanged();
+						}
+					} else {
+						setSelectedRows(new TableRowCore[] {
+							rowToSelect
+						});
+						updateTable = true;
+					}
+				} else if (event.keyCode == SWT.PAGE_UP) {
+					TableRowCore row = focusedRow;
+					TableRowPainted lastRow = getLastVisibleRow();
+					int y = lastRow == null ? 0 : (clientArea.y + clientArea.height) - lastRow.getDrawOffset().y;
+					while (row != null && y < clientArea.height) {
+						y += row.getHeight();
+						row = getPreviousRow(row);
+					}
+					if (row == null) {
+						row = getRow(0);
+					}
+					if ((event.stateMask & SWT.SHIFT) > 0) {
+						selectRowsTo(row);
+					} else if (event.stateMask == 0) {
+  					setSelectedRows(new TableRowCore[] {
+  						row
+  					});
+					}
+					updateTable = true;
+				} else if (event.keyCode == SWT.HOME) {
+					if ((event.stateMask & SWT.SHIFT) > 0) {
+						selectRowsTo(getRow(0));
+					} else if (event.stateMask == 0) {
+  					setSelectedRows(new TableRowCore[] {
+  						getRow(0)
+  					});
+					}
+					updateTable = true;
+				} else if (event.keyCode == SWT.ARROW_DOWN) {
+					if ((event.stateMask & SWT.CONTROL) > 0) {
+						// show one less topRow 
+						TableRowPainted firstRow = visibleRows.iterator().next();
+						if (firstRow != null) {
+							int hChange = 0;
+							if (isRowPartiallyVisible(firstRow)) {
+								hChange = firstRow.getHeight() + (firstRow.getDrawOffset().y - clientArea.y);
+							} else {
+								hChange = firstRow.getHeight();
+							}
+							vBar.setSelection(vBar.getSelection() + hChange);
+							swt_vBarChanged();
+						}
+					} else {
+						TableRowCore rowToSelect = getNextRow(focusedRow);
+  					if (rowToSelect != null) {
+  						if ((event.stateMask & SWT.SHIFT) > 0) {
+  							TableRowCore[] selectedRows = getSelectedRows();
+  							Arrays.sort(selectedRows, new TableRowCoreSorter());
+  							boolean select = selectedRows.length == 0
+  									|| selectedRows[selectedRows.length - 1] == focusedRow;
+  							if (select) {
+  								rowToSelect.setSelected(select);
+  							} else {
+  								focusedRow.setSelected(false);
+  								setFocusedRow(rowToSelect);
+  							}
+  						} else {
+  							setSelectedRows(new TableRowCore[] {
+  								rowToSelect
+  							});
+  						}
+							updateTable = true;
+  					}
+					}
+				} else if (event.keyCode == SWT.PAGE_DOWN) {
+					TableRowCore row = focusedRow;
+					TableRowPainted firstRow = visibleRows.size() == 0 ? null : visibleRows.iterator().next();
+
+					int y = firstRow == null ? 0 : firstRow.getHeight() - (clientArea.y - firstRow.getDrawOffset().y);
+					while (row != null && y < clientArea.height) {
+						y += row.getHeight();
+						TableRowCore nextRow = getNextRow(row);
+						if (nextRow == null) {
+							break;
+						}
+						row = nextRow;
+					}
+					if ((event.stateMask & SWT.SHIFT) > 0) {
+						selectRowsTo(row);
+					} else if (event.stateMask == 0) {
+  					setSelectedRows(new TableRowCore[] {
+  						row
+  					});
+					}
+					updateTable = true;
+				} else if (event.keyCode == SWT.END) {
+					TableRowCore lastRow = getRow(getRowCount() - 1);
+					if ((event.stateMask & SWT.SHIFT) > 0) {
+						selectRowsTo(lastRow);
+					} else if (event.stateMask == 0) {
+  					setSelectedRows(new TableRowCore[] {
+  						lastRow
+  					});
+					}
+					updateTable = true;
+				} else if (event.keyCode == SWT.ARROW_RIGHT) {
+					if (event.stateMask == 0 && focusedRow != null && !focusedRow.isExpanded() && canHaveSubItems()) {
+						focusedRow.setExpanded(true);
+					} else {
+						if (hBar.isEnabled()) {
+							hBar.setSelection(hBar.getSelection() + 50);
+							cTable.redraw();
+							updateTable = true;
+						}
+					}
+				} else if (event.keyCode == SWT.ARROW_LEFT) {
+					if (event.stateMask == 0 && focusedRow != null && focusedRow.isExpanded() && canHaveSubItems()) {
+						focusedRow.setExpanded(false);
+					} else {
+						if (hBar.isEnabled()) {
+							hBar.setSelection(hBar.getSelection() - 50);
+							cTable.redraw();
+							updateTable = true;
+						}
+					}
+				}
+				
+				if (updateTable) {
+					cTable.update();
+				}
+				super.keyPressed(event);
+			}
+
+			@Override
+			public void keyReleased(KeyEvent e) {
+				swt_calculateClientArea();
+				visibleRowsChanged();
+
+				super.keyReleased(e);
+			}
+		};
+	}
+
+	protected boolean isRowPartiallyVisible(TableRowPainted row) {
+		if (row == null) {
+			return false;
+		}
+		Point drawOffset = row.getDrawOffset();
+		int height = row.getHeight();
+		return (drawOffset.y < clientArea.y && drawOffset.y + height > clientArea.y)
+				|| (drawOffset.y < clientArea.y + clientArea.height && drawOffset.y
+						+ height > clientArea.y + clientArea.height);
+	}
+
+	protected void selectRowsTo(TableRowCore clickedRow) {
+		if (!isMultiSelect) {
+			setSelectedRows(new TableRowCore[] {
+				clickedRow
+			});
+			return;
+		}
+		TableRowCore[] selectedRows = getSelectedRows();
+		TableRowCore firstRow = selectedRows.length > 0 ? selectedRows[0]
+				: getRow(0);
+		TableRowCore parentFirstRow = firstRow;
+		while (parentFirstRow.getParentRowCore() != null) {
+			parentFirstRow = parentFirstRow.getParentRowCore();
+		}
+		TableRowCore parentClickedRow = clickedRow;
+		while (parentClickedRow.getParentRowCore() != null) {
+			parentClickedRow = parentClickedRow.getParentRowCore();
+		}
+		int startPos;
+		int endPos;
+		if (parentFirstRow == parentClickedRow) {
+			startPos = parentFirstRow == firstRow ? -1 : firstRow.getIndex();
+			endPos = parentClickedRow == clickedRow ? -1 : clickedRow.getIndex();
+		} else {
+			startPos = indexOf(parentFirstRow);
+			endPos = indexOf(parentClickedRow);
+			if (endPos == -1 || startPos == -1) {
+				return;
+			}
+		}
+		ArrayList<TableRowCore> rowsToSelect = new ArrayList<TableRowCore>(Arrays.asList(selectedRows));
+		TableRowCore curRow = firstRow;
+		do {
+			if (!rowsToSelect.contains(curRow)) {
+				rowsToSelect.add(curRow);
+			}
+			TableRowCore newRow = (startPos < endPos) ? getNextRow(curRow) : getPreviousRow(curRow);
+			
+				// prevent infinite loop if things go wonky (which they have been soon to do!)
+			if ( newRow == curRow ){
+				break;
+			}else{
+				curRow = newRow;
+			}
+			
+		} while (curRow != clickedRow && curRow != null);
+		if (curRow != null && !rowsToSelect.contains(curRow)) {
+			rowsToSelect.add(curRow);
+		}
+		setSelectedRows(rowsToSelect.toArray(new TableRowCore[0]));
+		setFocusedRow(clickedRow);
+	}
+
+	protected TableRowCore getPreviousRow(TableRowCore relativeToRow) {
+		TableRowCore rowToSelect = null;
+		if (relativeToRow != null) {
+			TableRowCore parentRow = relativeToRow.getParentRowCore();
+			if (parentRow == null) {
+				TableRowCore row = getRow(indexOf(relativeToRow) - 1);
+				if (row != null && row.isExpanded() && row.getSubItemCount() > 0) {
+					rowToSelect = row.getSubRow(row.getSubItemCount() - 1);
+				} else {
+					rowToSelect = row;
+				}
+			} else {
+				int index = relativeToRow.getIndex();
+				if (index > 0) {
+					rowToSelect = parentRow.getSubRow(index - 1);
+				} else {
+					rowToSelect = parentRow;
+				}
+			}
+		}
+		if (rowToSelect == null) {
+			rowToSelect = getRow(0);
+		}
+		return rowToSelect;
+	}
+
+	protected TableRowCore getNextRow(TableRowCore relativeToRow) {
+		TableRowCore rowToSelect = null;
+		if (relativeToRow == null) {
+			rowToSelect = getRow(0);
+		} else {
+			if (relativeToRow.isExpanded() && relativeToRow.getSubItemCount() > 0) {
+				TableRowCore[] subRowsWithNull = relativeToRow.getSubRowsWithNull();
+				for (TableRowCore row : subRowsWithNull) {
+					if (row != null) {
+						rowToSelect = row;
+						break;
+					}
+				}
+				if (rowToSelect == null) {
+					rowToSelect = getRow(relativeToRow.getIndex() + 1);
+				}
+			} else {
+				TableRowCore parentRow = relativeToRow.getParentRowCore();
+				if (parentRow != null) {
+					rowToSelect = parentRow.getSubRow(relativeToRow.getIndex() + 1);
+
+					if (rowToSelect == null) {
+						rowToSelect = getRow(parentRow.getIndex() + 1);
+					}
+				} else {
+					rowToSelect = getRow(relativeToRow.getIndex() + 1);
+				}
+			}
+		}
+		return rowToSelect;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#clipboardSelected()
+	 */
+	public void clipboardSelected() {
+		String sToClipboard = "";
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		for (int j = 0; j < visibleColumns.length; j++) {
+			if (j != 0) {
+				sToClipboard += "\t";
+			}
+			String title = MessageText.getString(visibleColumns[j].getTitleLanguageKey());
+			sToClipboard += title;
+		}
+
+		TableRowCore[] rows = getSelectedRows();
+		for (TableRowCore row : rows) {
+			sToClipboard += "\n";
+			for (int j = 0; j < visibleColumns.length; j++) {
+				TableColumnCore column = visibleColumns[j];
+				if (j != 0) {
+					sToClipboard += "\t";
+				}
+				TableCellCore cell = row.getTableCellCore(column.getName());
+				if (cell != null) {
+					sToClipboard += cell.getClipboardText();
+				}
+			}
+		}
+		new Clipboard(getComposite().getDisplay()).setContents(new Object[] {
+			sToClipboard
+		}, new Transfer[] {
+			TextTransfer.getInstance()
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#isDisposed()
+	 */
+	public boolean isDisposed() {
+		return cTable == null || cTable.isDisposed();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#refreshTable(boolean)
+	 */
+	public void refreshTable(final boolean bForceSort) {
+		//__refreshTable(bForceSort);
+		refreshTableRunnable.setForceSort(bForceSort);
+		Utils.getOffOfSWTThread(refreshTableRunnable);
+	}
+
+	public void __refreshTable(boolean bForceSort) {
+		long lStart = SystemTime.getCurrentTime();
+		super.refreshTable(bForceSort);
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				// call to trigger invalidation if visibility changes
+				isVisible();
+			}
+		});
+		final boolean bDoGraphics = (loopFactor % graphicsUpdate) == 0;
+		final boolean bWillSort = bForceSort || (reOrderDelay != 0)
+				&& ((loopFactor % reOrderDelay) == 0);
+		//System.out.println("Refresh.. WillSort? " + bWillSort);
+
+		if (bWillSort) {
+			TableColumnCore sortColumn = getSortColumn();
+			if (bForceSort && sortColumn != null) {
+				resetLastSortedOn();
+				sortColumn.setLastSortValueChange(SystemTime.getCurrentTime());
+			}
+			_sortColumn(true, false, false);
+		}
+
+		runForAllRows(new TableGroupRowVisibilityRunner() {
+			public void run(TableRowCore row, boolean bVisible) {
+				row.refresh(bDoGraphics, bVisible);
+			}
+		});
+		loopFactor++;
+
+		long diff = SystemTime.getCurrentTime() - lStart;
+		if (diff > 0) {
+			//debug("refreshTable took " + diff);
+		}
+
+		if (tvTabsCommon != null) {
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (tvTabsCommon != null) {
+						tvTabsCommon.swt_refresh();
+					}
+				}
+			});
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setEnableTabViews(boolean)
+	 */
+	public void setEnableTabViews(boolean enableTabViews) {
+		this.enableTabViews = enableTabViews;
+	}
+
+	public boolean isTabViewsEnabled() {
+		return enableTabViews;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setFocus()
+	 */
+	public void setFocus() {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (isDisposed()) {
+					return;
+				}
+				cTable.setFocus();
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setRowDefaultHeight(int)
+	 */
+	public void setRowDefaultHeight(int iHeight) {
+		if (iHeight > defaultRowHeight) {
+			defaultRowHeight = iHeight;
+			
+			Utils.execSWTThread(new AERunnable() {
+				public void runSupport() {
+					if (vBar != null && !vBar.isDisposed()) {
+						vBar.setIncrement(defaultRowHeight);
+					}
+				}
+			});
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getRow(int, int)
+	 */
+	public TableRowCore getRow(int x, int y) {
+		Set<TableRowPainted> visibleRows = this.visibleRows;
+		if (visibleRows.size() == 0) {
+			return null;
+		}
+		boolean firstRow = true;
+		int curY = 0;
+		for (TableRowPainted row : visibleRows) {
+			if (firstRow) {
+				curY = row.getDrawOffset().y;
+			}
+			int h = row.getHeight();
+			if (y >= curY && y < curY + h) {
+				return row;
+			}
+			curY += h;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#isRowVisible(com.aelitis.azureus.ui.common.table.TableRowCore)
+	 */
+	public boolean isRowVisible(TableRowCore row) {
+		if (row == null) {
+			return false;
+		}
+		synchronized (visibleRows_sync) {
+			return visibleRows.contains(row);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getTableCellWithCursor()
+	 */
+	public TableCellCore getTableCellWithCursor() {
+		// TODO: Make work outside SWT?
+		Point pt = cTable.getDisplay().getCursorLocation();
+		pt = cTable.toControl(pt);
+		return getTableCell(pt.x, clientArea.y + pt.y);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getTableRowWithCursor()
+	 */
+	public TableRowCore getTableRowWithCursor() {
+		// TODO: Make work outside SWT?
+		Point pt = cTable.getDisplay().getCursorLocation();
+		pt = cTable.toControl(pt);
+		return getTableRow(pt.x, pt.y, true);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getRowDefaultHeight()
+	 */
+	public int getRowDefaultHeight() {
+		return defaultRowHeight;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setEnabled(boolean)
+	 */
+	public void setEnabled(final boolean enable) {
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (!isDisposed()) {
+					cTable.setEnabled(enable);
+				}
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#canHaveSubItems()
+	 */
+	public boolean canHaveSubItems() {
+		return true;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setHeaderVisible(boolean)
+	 */
+	public void setHeaderVisible(final boolean visible) {
+		super.setHeaderVisible(visible);
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (cHeaderArea != null && !cHeaderArea.isDisposed()) {
+					cHeaderArea.setVisible(visible);
+					FormData fd = Utils.getFilledFormData();
+					fd.height = visible ? headerHeight : 1;
+					fd.bottom = null;
+					cHeaderArea.setLayoutData(fd);
+					cHeaderArea.getParent().layout(true);
+				}
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#getMaxItemShown()
+	 */
+	public int getMaxItemShown() {
+		// NOT USED
+		return 0;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableView#setMaxItemShown(int)
+	 */
+	public void setMaxItemShown(int newIndex) {
+		// NOT USED
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.core3.internat.MessageText.MessageTextListener#localeChanged(java.util.Locale, java.util.Locale)
+	 */
+	public void localeChanged(Locale old_locale, Locale new_locale) {
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				if (tvTabsCommon != null) {
+					tvTabsCommon.localeChanged();
+				}
+
+				tableInvalidate();
+				refreshTable(true);
+				cHeaderArea.redraw();
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableStructureModificationListener#columnOrderChanged(int[])
+	 */
+	public void columnOrderChanged(int[] iPositions) {
+		//TODO
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.TableStructureModificationListener#columnSizeChanged(com.aelitis.azureus.ui.common.table.TableColumnCore, int)
+	 */
+	public void columnSizeChanged(TableColumnCore tableColumn, int diff) {
+		columnsWidth += diff;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (cHeaderArea != null && !cHeaderArea.isDisposed()) {
+					cHeaderArea.redraw();
+				}
+				swt_fixupSize();
+				redrawTable();
+			}
+		});
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addKeyListener(org.eclipse.swt.events.KeyListener)
+	 */
+	public void addKeyListener(KeyListener listener) {
+		if (tvSWTCommon == null) {
+			return;
+		}
+		tvSWTCommon.addKeyListener(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeKeyListener(org.eclipse.swt.events.KeyListener)
+	 */
+	public void removeKeyListener(KeyListener listener) {
+		if (tvSWTCommon == null) {
+			return;
+		}
+		tvSWTCommon.removeKeyListener(listener);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getKeyListeners()
+	 */
+	public KeyListener[] getKeyListeners() {
+		if (tvSWTCommon == null) {
+			return new KeyListener[0];
+		}
+		return tvSWTCommon.getKeyListeners();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addMenuFillListener(org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener)
+	 */
+	public void addMenuFillListener(TableViewSWTMenuFillListener l) {
+		if (tvSWTCommon == null) {
+			return;
+		}
+		tvSWTCommon.addMenuFillListener(l);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#createDragSource(int)
+	 */
+	public DragSource createDragSource(int style) {
+		final DragSource dragSource = new DragSource(cTable, style);
+		dragSource.addDragListener(new DragSourceAdapter() {
+			public void dragStart(DragSourceEvent event) {
+				cTable.setCursor(null);
+				TableRowCore row = getTableRow(event.x, event.y, true);
+				if (row != null && !row.isSelected()) {
+					setSelectedRows(new TableRowCore[] { row });
+				}
+				isDragging = true;
+			}
+
+			public void dragFinished(DragSourceEvent event) {
+				isDragging = false;
+			}
+		});
+		cTable.addDisposeListener(new DisposeListener() {
+			// @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+			public void widgetDisposed(DisposeEvent e) {
+				if (!dragSource.isDisposed()) {
+					dragSource.dispose();
+				}
+			}
+		});
+		return dragSource;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#createDropTarget(int)
+	 */
+	public DropTarget createDropTarget(int style) {
+		final DropTarget dropTarget = new DropTarget(cTable, style);
+		cTable.addDisposeListener(new DisposeListener() {
+			// @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
+			public void widgetDisposed(DisposeEvent e) {
+				if (!dropTarget.isDisposed()) {
+					dropTarget.dispose();
+				}
+			}
+		});
+		return dropTarget;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getComposite()
+	 */
+	public Composite getComposite() {
+		return cTable;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getRow(org.eclipse.swt.dnd.DropTargetEvent)
+	 */
+	public TableRowCore getRow(DropTargetEvent event) {
+		//TODO
+		// maybe
+		Point pt = cTable.toControl(event.x, event.y);
+		return getRow(pt.x, clientArea.y + pt.y);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getRowSWT(java.lang.Object)
+	 */
+	public TableRowSWT getRowSWT(Object dataSource) {
+		return (TableRowSWT) getRow(dataSource);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableComposite()
+	 */
+	public Composite getTableComposite() {
+		return cTable;
+	}
+
+	/** Creates a composite within the specified composite and sets its layout
+	 * to a default FillLayout().
+	 *
+	 * @param composite to create your Composite under
+	 * @return The newly created composite
+	 */
+	public Composite createMainPanel(Composite composite) {
+		TableViewSWTPanelCreator mainPanelCreator = getMainPanelCreator();
+		if (mainPanelCreator != null) {
+			return mainPanelCreator.createTableViewPanel(composite);
+		}
+		Composite panel = new Composite(composite, SWT.NO_FOCUS);
+		composite.getLayout();
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		panel.setLayout(layout);
+
+		Object parentLayout = composite.getLayout();
+		if (parentLayout == null || (parentLayout instanceof GridLayout)) {
+			panel.setLayoutData(new GridData(GridData.FILL_BOTH));
+		}
+
+		return panel;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#initialize(org.eclipse.swt.widgets.Composite)
+	 */
+	public void initialize(Composite parent) {
+		tvTabsCommon = new TableViewSWT_TabsCommon(this);
+
+		shell = parent.getShell();
+		mainComposite = tvTabsCommon.createSashForm(parent);
+		mainComposite.setData("Name", tableID);
+		mainComposite.setData("ObfusticateImage", this);
+		Composite cTableComposite = tvTabsCommon.tableComposite;
+
+		cTableComposite.setLayout(new FormLayout());
+		Layout layout = parent.getLayout();
+		if (layout instanceof FormLayout) {
+			FormData fd = Utils.getFilledFormData();
+			cTableComposite.setLayoutData(fd);
+		}
+
+		cHeaderArea = new Canvas(cTableComposite, SWT.DOUBLE_BUFFERED);
+
+		fontHeader = FontUtils.getFontWithHeight(cHeaderArea.getFont(), null, 12);
+		fontHeaderSmall = FontUtils.getFontPercentOf(fontHeader, 0.8f);
+		cHeaderArea.setFont(fontHeader);
+
+		cTable = new Canvas(cTableComposite, SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.V_SCROLL);
+		
+		// good test
+		//cTable.setFont(FontUtils.getFontPercentOf(cTable.getFont(), 1.50f));
+		int minRowHeight = FontUtils.getFontHeightInPX(cTable.getFont());
+		minRowHeight += Math.ceil(minRowHeight * 2.0 / 16.0);
+		if (defaultRowHeight < minRowHeight) {
+			defaultRowHeight = minRowHeight;
+		}
+
+		cTable.setBackground(parent.getDisplay().getSystemColor(
+				SWT.COLOR_LIST_BACKGROUND));
+
+		headerHeight = configMan.getIntParameter("Table.headerHeight");
+		if (headerHeight <= 0) {
+			headerHeight = DEFAULT_HEADER_HEIGHT;
+		}
+
+		FormData fd = Utils.getFilledFormData();
+		fd.height = headerHeight;
+		fd.bottom = null;
+		cHeaderArea.setLayoutData(fd);
+		fd = Utils.getFilledFormData();
+		fd.top = new FormAttachment(cHeaderArea);
+		cTable.setLayoutData(fd);
+
+		clientArea = cTable.getClientArea();
+
+		TableColumnCore[] tableColumns = getAllColumns();
+		TableColumnCore[] tmpColumnsOrdered = new TableColumnCore[tableColumns.length];
+		//Create all columns
+		int columnOrderPos = 0;
+		Arrays.sort(tableColumns,
+				TableColumnManager.getTableColumnOrderComparator());
+		for (int i = 0; i < tableColumns.length; i++) {
+			int position = tableColumns[i].getPosition();
+			if (position != -1 && tableColumns[i].isVisible()) {
+				//table.createNewColumn(SWT.NULL);
+				//System.out.println(i + "] " + tableColumns[i].getName() + ";" + position);
+				tmpColumnsOrdered[columnOrderPos++] = tableColumns[i];
+			}
+		}
+		//int numSWTColumns = table.getColumnCount();
+		//int iNewLength = numSWTColumns - (bSkipFirstColumn ? 1 : 0);
+		TableColumnCore[] columnsOrdered = new TableColumnCore[columnOrderPos];
+		System.arraycopy(tmpColumnsOrdered, 0, columnsOrdered, 0, columnOrderPos);
+		setColumnsOrdered(columnsOrdered);
+
+		cTable.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent e) {
+				swt_paintComposite(e);
+			}
+		});
+
+		menu = createMenu();
+		cTable.setMenu(menu);
+		cHeaderArea.setMenu(menu);
+
+		setupHeaderArea(cHeaderArea);
+
+		cTable.addControlListener(new ControlListener() {
+
+			public void controlResized(ControlEvent e) {
+				swt_calculateClientArea();
+				swt_fixupSize();
+			}
+			
+			public void controlMoved(ControlEvent e) {
+			}
+		});
+		
+		hBar = cTable.getHorizontalBar();
+		if (hBar != null) {
+			hBar.setValues(0, 0, 0, 10, 10, 100);
+			hBar.addSelectionListener(new SelectionListener() {
+				
+				public void widgetSelected(SelectionEvent e) {
+					//swt_calculateClientArea();
+					cTable.redraw();
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+		}
+		vBar = cTable.getVerticalBar();
+		if (vBar != null) {
+			vBar.setValues(0, 0, 0, 50, getRowDefaultHeight(), 50);
+			vBar.addSelectionListener(new SelectionListener() {
+				public void widgetSelected(SelectionEvent e) {
+					swt_vBarChanged();
+				}
+				
+				public void widgetDefaultSelected(SelectionEvent e) {
+				}
+			});
+		}
+		
+		if (DEBUG_WITH_SHELL) {
+  		Shell shell = new Shell();
+  		sCanvasImage = new Canvas(shell, SWT.DOUBLE_BUFFERED);
+  		shell.setLayout(new FillLayout());
+  		sCanvasImage.addPaintListener(new PaintListener() {
+  			public void paintControl(PaintEvent e) {
+  				if (canvasImage == null) {
+  					return;
+  				}
+  				e.gc.drawImage(canvasImage, 0, 0);
+  				//System.out.println(System.currentTimeMillis() + "] Paint " + e.x + "x" + e.y + " " + e.width + "x" + e.height);
+  
+  			}
+  		});
+  		shell.addDisposeListener(new DisposeListener() {
+  			public void widgetDisposed(DisposeEvent e) {
+  				sCanvasImage = null;
+  			}
+  		});
+  		shell.setVisible(true);
+		}
+
+
+		cTable.addMouseListener(tvSWTCommon);
+		cTable.addMouseMoveListener(tvSWTCommon);
+		cTable.addKeyListener(tvSWTCommon);
+		//composite.addSelectionListener(tvSWTCommon);
+		
+		cTable.addTraverseListener(new TraverseListener() {
+			public void keyTraversed(TraverseEvent e) {
+				e.doit = true;
+			}
+		});
+		
+		
+		SelectedContentManager.addCurrentlySelectedContentListener(new SelectedContentListener() {
+			public void currentlySelectedContentChanged(
+					ISelectedContent[] currentContent, String viewID) {
+				redrawTable();
+			}
+		});
+		
+		cTable.addFocusListener(new FocusListener() {
+			public void focusLost(FocusEvent e) {
+				isFocused = false;
+				redrawTable();
+			}
+			
+			public void focusGained(FocusEvent e) {
+				isFocused = true;
+				redrawTable();
+			}
+		});
+		isFocused = cTable.isFocusControl();
+
+		new TableTooltips(this, cTable);
+
+		TableColumnManager tcManager = TableColumnManager.getInstance();
+
+		String sSortColumn = tcManager.getDefaultSortColumnName(tableID);
+		if (sSortColumn == null || sSortColumn.length() == 0) {
+			sSortColumn = sDefaultSortOn;
+		}
+
+		TableColumnCore tc = tcManager.getTableColumnCore(tableID, sSortColumn);
+		if (tc == null && tableColumns.length > 0) {
+			tc = tableColumns[0];
+		}
+		setSortColumn(tc, false);
+
+		triggerLifeCycleListener(TableLifeCycleListener.EVENT_INITIALIZED);
+
+		configMan.addParameterListener("Graphics Update", this);
+		configMan.addParameterListener("ReOrder Delay", this);
+		configMan.addParameterListener("Table.extendedErase", this);
+		configMan.addParameterListener("Table.headerHeight", this);
+		Colors.getInstance().addColorsChangedListener(this);
+
+		// So all TableView objects of the same TableID have the same columns,
+		// and column widths, etc
+		TableStructureEventDispatcher.getInstance(tableID).addListener(this);
+
+	}
+
+	protected void swt_vBarChanged() {
+		if (DEBUG_SELECTION) {
+			debug("vBar changed " + vBar.getSelection() + " via " + Debug.getCompressedStackTrace());
+		}
+		swt_calculateClientArea();
+		cTable.update();
+	}
+
+	private void setupHeaderArea(final Canvas cHeaderArea) {
+
+		cHeaderArea.addPaintListener(new PaintListener() {
+			public void paintControl(PaintEvent e) {
+				paintHeader(e);
+			}
+		});
+
+		Listener l = new Listener() {
+			boolean mouseDown = false;
+
+			TableColumnCore columnSizing;
+
+			int columnSizingStart = 0;
+
+			public void handleEvent(Event e) {
+				switch (e.type) {
+					case SWT.MouseDown: {
+						if (e.button != 1) {
+							return;
+						}
+						mouseDown = true;
+
+						columnSizing = null;
+						int x = -clientArea.x;
+						TableColumnCore[] visibleColumns = getVisibleColumns();
+						for (TableColumnCore column : visibleColumns) {
+							int w = column.getWidth();
+							x += w;
+
+							if (e.x >= x - 3 && e.x <= x + 3) {
+								columnSizing = column;
+								columnSizingStart = e.x;
+								break;
+							}
+						}
+
+						break;
+					}
+
+					case SWT.MouseUp: {
+						if (e.button != 1) {
+							return;
+						}
+						if (mouseDown && columnSizing == null) {
+							TableColumnCore column = getTableColumnByOffset(e.x);
+							if (column != null) {
+								setSortColumn(column, true);
+							}
+						}
+						columnSizing = null;
+						mouseDown = false;
+						break;
+					}
+
+					case SWT.MouseMove: {
+						if (columnSizing != null) {
+							int diff = (e.x - columnSizingStart);
+							columnSizing.setWidth(columnSizing.getWidth() + diff);
+							columnSizingStart = e.x;
+						} else {
+							int cursorID = SWT.CURSOR_HAND;
+							int x = -clientArea.x;
+							TableColumnCore[] visibleColumns = getVisibleColumns();
+							for (TableColumnCore column : visibleColumns) {
+								int w = column.getWidth();
+								x += w;
+
+								if (e.x >= x - 3 && e.x <= x + 3) {
+									cursorID = SWT.CURSOR_SIZEWE;
+									break;
+								}
+							}
+							cHeaderArea.setCursor(e.display.getSystemCursor(cursorID));
+							TableColumnCore column = getTableColumnByOffset(e.x);
+
+							if (column == null) {
+								cHeaderArea.setToolTipText(null);
+							} else {
+								String info = MessageText.getString(
+										column.getTitleLanguageKey() + ".info", (String) null);
+								if (column.showOnlyImage()) {
+									String tt = MessageText.getString(
+											column.getTitleLanguageKey());
+									if (info != null) {
+										tt += "\n" + info;
+									}
+									cHeaderArea.setToolTipText(tt);
+								} else {
+									cHeaderArea.setToolTipText(info);
+								}
+							}
+						}
+					}
+					
+				}
+			}
+		};
+
+		cHeaderArea.addListener(SWT.MouseDown, l);
+		cHeaderArea.addListener(SWT.MouseUp, l);
+		cHeaderArea.addListener(SWT.MouseMove, l);
+
+		Transfer[] types = new Transfer[] {
+			TextTransfer.getInstance()
+		};
+
+		final DragSource ds = new DragSource(cHeaderArea, DND.DROP_MOVE);
+		ds.setTransfer(types);
+		ds.addDragListener(new DragSourceListener() {
+			private String eventData;
+
+			public void dragStart(DragSourceEvent event) {
+				Cursor cursor = cHeaderArea.getCursor();
+				if (cursor != null
+						&& cursor.equals(event.display.getSystemCursor(SWT.CURSOR_SIZEWE))) {
+					event.doit = false;
+					return;
+				}
+
+				cHeaderArea.setCursor(null);
+				TableColumnCore tc = getTableColumnByOffset(event.x);
+				isHeaderDragging = tc != null;
+				if (isHeaderDragging) {
+					eventData = tc.getName();
+				}
+				System.out.println("drag " + eventData);
+			}
+
+			public void dragSetData(DragSourceEvent event) {
+				event.data = eventData;
+			}
+
+			public void dragFinished(DragSourceEvent event) {
+				isHeaderDragging = false;
+				eventData = null;
+			}
+		});
+
+		final DropTarget dt = new DropTarget(cHeaderArea, DND.DROP_MOVE);
+		dt.setTransfer(types);
+		dt.addDropListener(new DropTargetListener() {
+
+			public void dropAccept(DropTargetEvent event) {
+			}
+
+			public void drop(final DropTargetEvent event) {
+				if (event.data instanceof String) {
+					TableColumn tcOrig = getTableColumn((String) event.data);
+					Point pt = cTable.toControl(event.x, event.y);
+					TableColumn tcDest = getTableColumnByOffset(pt.x);
+					if (tcDest == null) {
+						TableColumnCore[] visibleColumns = getVisibleColumns();
+						if (visibleColumns != null && visibleColumns.length > 0) {
+							tcDest = visibleColumns[visibleColumns.length - 1];
+						}
+					}
+					if (tcOrig != null && tcDest != null) {
+						int destPos = tcDest.getPosition();
+						int origPos = tcOrig.getPosition();
+						final boolean moveRight = destPos > origPos;
+						TableColumnCore[] visibleColumns = getVisibleColumns();
+						((TableColumnCore) tcOrig).setPositionNoShift(destPos);
+
+						//System.out.println("Move " + origPos + " Right? " + moveRight + " of " + destPos);
+						Arrays.sort(visibleColumns, new Comparator<TableColumnCore>() {
+							public int compare(TableColumnCore o1, TableColumnCore o2) {
+								if (o1 == o2) {
+									return 0;
+								}
+								int diff = o1.getPosition() - o2.getPosition();
+								if (diff == 0) {
+									int i = o1.getName().equals(event.data) ? -1 : 1;
+									if (moveRight) {
+										i *= -1;
+									}
+									return i;
+								}
+								return diff;
+							}
+						});
+
+						for (int i = 0; i < visibleColumns.length; i++) {
+							TableColumnCore tc = visibleColumns[i];
+							tc.setPositionNoShift(i);
+						}
+						setColumnsOrdered(visibleColumns);
+
+						TableStructureEventDispatcher.getInstance(tableID).tableStructureChanged(
+								false, getDataSourceType());
+					}
+				}
+			}
+
+			public void dragOver(DropTargetEvent event) {
+			}
+
+			public void dragOperationChanged(DropTargetEvent event) {
+			}
+
+			public void dragLeave(DropTargetEvent event) {
+			}
+
+			public void dragEnter(DropTargetEvent event) {
+			}
+		});
+		cHeaderArea.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				Utils.disposeSWTObjects(new Object[] {
+					ds,
+					dt,
+					fontHeader,
+					fontHeaderSmall
+				});
+			}
+		});
+	}
+
+	@Override
+	public void tableStructureChanged(final boolean columnAddedOrRemoved,
+			final Class forPluginDataSourceType) {
+
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				TableViewPainted.super.tableStructureChanged(columnAddedOrRemoved, forPluginDataSourceType);
+				if (cHeaderArea != null && !cHeaderArea.isDisposed()) {
+					cHeaderArea.redraw();
+				}
+
+				redrawTable();
+			}
+		});
+	}
+
+	protected void swt_paintComposite(PaintEvent e) {
+		swt_calculateClientArea();
+		if (canvasImage == null) {
+			return;
+		}
+		
+		//System.out.println(e.count + " paint " + e.gc.getClipping() + ";" + e.x + "," + e.y + "," + e.width + "," + e.height + " via " + Debug.getCompressedStackTrace());
+
+		e.gc.drawImage(canvasImage, -clientArea.x, 0);
+		
+		// test line
+		//e.gc.drawLine(0, 0, cTable.getSize().x, canvasImage.getBounds().height);
+	}
+
+	protected void swt_paintCanvasImage(GC gc, Rectangle drawBounds) {
+		int end = drawBounds.y + drawBounds.height;
+
+		gc.setFont(cTable.getFont());
+		gc.setClipping(drawBounds);
+		TableRowCore oldRow = null;
+		int pos = -1;
+		Set<TableRowPainted> visibleRows = this.visibleRows;
+		
+		for (TableRowPainted row : visibleRows) {
+			TableRowPainted paintedRow = row;
+			if (pos == -1) {
+				pos = row.getIndex();
+			} else {
+				pos++;
+			}
+			Point drawOffset = paintedRow.getDrawOffset();
+			int rowStartX = 0;
+			int rowStartY = drawOffset.y - clientArea.y;
+			int rowHeight = paintedRow.getHeight();
+			//debug("Paint " + drawBounds.x + "x" + drawBounds.y + " " + drawBounds.width + "x" + drawBounds.height + "; Row=" +row.getIndex() + ";clip=" + gc.getClipping() +";drawOffset=" + drawOffset);
+			if (drawBounds.intersects(rowStartX, rowStartY, 9999, rowHeight)) {
+				// ensure full row height
+				int diffY2 = (rowStartY + rowHeight) - (drawBounds.y + drawBounds.height); 
+				if (diffY2 > 0 ) {
+					drawBounds.height += diffY2; 
+					gc.setClipping(drawBounds);
+				}
+				paintedRow.swt_paintGC(gc, drawBounds, rowStartX, rowStartY, pos);
+			}
+			oldRow = row;
+		}
+
+		int h;
+		int yDirty;
+		if (oldRow == null) {
+			yDirty = drawBounds.y;
+			h = drawBounds.height;
+		} else {
+			yDirty = ((TableRowPainted) oldRow).getDrawOffset().y
+					+ ((TableRowPainted) oldRow).getFullHeight();
+			h = (drawBounds.y + drawBounds.height) - yDirty;
+		}
+		if (h > 0) {
+			int rowHeight = getRowDefaultHeight();
+			if (extendedErase) {
+				while (yDirty < end) {
+					pos++;
+					Color color = TableRowPainted.alternatingColors[pos % 2];
+					if (color != null) {
+						gc.setBackground(color);
+					}
+					if (color == null) {
+						gc.setBackground(gc.getDevice().getSystemColor(
+								SWT.COLOR_LIST_BACKGROUND));
+					}
+					gc.fillRectangle(drawBounds.x, yDirty, drawBounds.width, rowHeight);
+					yDirty += rowHeight;
+				}
+			} else {
+				gc.setBackground(gc.getDevice().getSystemColor(
+						SWT.COLOR_LIST_BACKGROUND));
+				gc.fillRectangle(drawBounds.x, yDirty, drawBounds.width, h);
+			}
+		}
+
+		//gc.setForeground(getColorLine());
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		int x = 0;
+		gc.setAlpha(20);
+		for (TableColumnCore column : visibleColumns) {
+			x += column.getWidth();
+
+			// Vertical lines between columns
+			gc.drawLine(x - 1, drawBounds.y, x - 1, drawBounds.y + drawBounds.height);
+		}
+		gc.setAlpha(255);
+	}
+	
+	private Color getColorLine() {
+		if (colorLine == null) {
+			colorLine = cTable.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+			HSLColor hslColor = new HSLColor();
+			hslColor.initHSLbyRGB(colorLine.getRed(), colorLine.getGreen(),
+					colorLine.getBlue());
+
+			int lum = hslColor.getLuminence();
+			if (lum > 127)
+				lum -= 25;
+			else
+				lum += 40;
+			hslColor.setLuminence(lum);
+
+			colorLine = new Color(cTable.getDisplay(), hslColor.getRed(),
+					hslColor.getGreen(), hslColor.getBlue());
+		}
+
+		return colorLine;
+	}
+
+	private void paintHeader(PaintEvent e) {
+
+		Rectangle ca = cHeaderArea.getClientArea();
+		Color c1 = e.display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+		Color c2 = e.display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+		Color line = c2;
+		Color fg = e.display.getSystemColor(SWT.COLOR_LIST_FOREGROUND);
+
+		
+		Pattern patternUp = new Pattern(e.display, 0, 0, 0, ca.height, c1, c2);
+		Pattern patternDown = new Pattern(e.display, 0, -ca.height , 0, 0, c2, c1);
+		//e.gc.setBackgroundPattern(patternUp);
+		//e.gc.fillRectangle(ca);
+
+		e.gc.setForeground(line);
+		//e.gc.drawLine(0, 0, clientArea.width, 0);
+		e.gc.drawLine(0, headerHeight - 1, clientArea.width, headerHeight - 1);
+
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		GCStringPrinter sp;
+		TableColumnCore sortColumn = getSortColumn();
+		int x = -clientArea.x;
+		for (TableColumnCore column : visibleColumns) {
+			int w = column.getWidth();
+
+			//squeeze last column's text into available visible space
+			if (x + w > ca.width) {
+				w = ca.width - x;
+				if (w <= 16) {
+					break;
+				}
+			}
+
+			
+			boolean isSortColumn = column.equals(sortColumn);
+
+			e.gc.setBackgroundPattern(isSortColumn ? patternDown : patternUp);
+			e.gc.fillRectangle(x, 1, w, headerHeight - 2);
+			e.gc.setForeground(line);
+			e.gc.drawLine(x + w - 1, 0, x + w - 1, headerHeight - 1);
+
+			e.gc.setForeground(fg);
+			int yOfs = 0;
+			int wText = w;
+/* Top Center
+			if (isSortColumn) {
+				int arrowY = 2;
+				int arrowHeight = 6;
+				yOfs = 8;
+				// draw sort indicator
+				int middle = w / 2;
+				int y1, y2;
+				int arrowHalfW = 4;
+				if (column.isSortAscending()) {
+					y2 = arrowY;
+					y1 = y2 + arrowHeight;
+				} else {
+					y1 = arrowY;
+					y2 = y1 + arrowHeight;
+				}
+				e.gc.setAntialias(SWT.ON);
+				e.gc.setBackground(ColorCache.getColor(e.display, 0, 0, 0));
+				e.gc.fillPolygon(new int[] {
+					x + middle - arrowHalfW,
+					y1,
+					x + middle + arrowHalfW,
+					y1,
+					x + middle,
+					y2
+				});
+			}
+*/
+			if (isSortColumn) {
+				// draw sort indicator
+				int arrowHeight = 6;
+				int arrowY = (headerHeight / 2) - (arrowHeight / 2);
+				int arrowHalfW = 4;
+				int middle = w - arrowHalfW - 4;
+				wText = w - (arrowHalfW * 2) - 5;
+				int y1, y2;
+				if (column.isSortAscending()) {
+					y2 = arrowY;
+					y1 = y2 + arrowHeight;
+				} else {
+					y1 = arrowY;
+					y2 = y1 + arrowHeight;
+				}
+				e.gc.setAntialias(SWT.ON);
+				e.gc.setBackground(fg);
+				e.gc.fillPolygon(new int[] {
+					x + middle - arrowHalfW,
+					y1,
+					x + middle + arrowHalfW,
+					y1,
+					x + middle,
+					y2
+				});
+			}
+
+			int xOfs = x + 2;
+			
+			boolean onlyShowImage = column.showOnlyImage();
+			String text = "";
+			if (!onlyShowImage) {
+				text = MessageText.getString(column.getTitleLanguageKey());
+			}
+
+			int style = SWT.WRAP | SWT.CENTER;
+			Image image = null;
+			String imageID = column.getIconReference();
+			if (imageID != null) {
+				image = ImageLoader.getInstance().getImage(imageID);
+				if (ImageLoader.isRealImage(image)) {
+					if (onlyShowImage) {
+						text = null;
+						Rectangle imageBounds = image.getBounds();
+						e.gc.drawImage(image, (int) (x + (w / 2.0) - (imageBounds.width / 2.0) + 0.5),
+								(headerHeight / 2) - (imageBounds.height / 2));
+					} else {
+						text = "%0 " + text;
+					}
+				} else {
+					image = null;
+				}
+			}
+
+			if (text != null) {
+  			sp = new GCStringPrinter(e.gc, text, new Rectangle(xOfs, yOfs - 1,
+  					wText - 4, headerHeight - yOfs + 2), true, false,style);
+  			if (image != null) {
+  				sp.setImages(new Image[] { image } );
+  			}
+  			sp.calculateMetrics();
+  			if (sp.isWordCut() || sp.isCutoff()) {
+  				Font font = e.gc.getFont();
+  				e.gc.setFont(fontHeaderSmall);
+  				sp.printString();
+  				e.gc.setFont(font);
+  			} else {
+  				sp.printString();
+  			}
+			}
+			
+			if (imageID != null) {
+				ImageLoader.getInstance().releaseImage(imageID);
+			}
+
+			x += w;
+		}
+
+		e.gc.setBackgroundPattern(patternUp);
+		e.gc.fillRectangle(x, 1, clientArea.width - x, headerHeight - 2);
+
+		patternUp.dispose();
+		patternDown.dispose();
+		e.gc.setBackgroundPattern(null);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#obfusticatedImage(org.eclipse.swt.graphics.Image)
+	 */
+	public Image obfusticatedImage(Image image) {
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		TableRowPainted[] visibleRows = this.visibleRows.toArray(new TableRowPainted[0]);
+		
+		for (TableRowPainted row : visibleRows) {
+			if (row == null || row.isRowDisposed()) {
+				continue;
+			}
+
+			for (TableColumnCore tc : visibleColumns) {
+				if (tc == null || !tc.isObfusticated()) {
+					continue;
+				}
+
+				TableCellPainted cell = (TableCellPainted) row.getTableCell(tc.getName());
+				if (cell == null) {
+					continue;
+				}
+
+				String text = cell.getObfusticatedText();
+
+				if (text != null) {
+
+					final Rectangle cellBounds = cell.getBoundsOnDisplay();
+					Point ptDisplay = cTable.getShell().getLocation();
+					cellBounds.x -= ptDisplay.x;
+					cellBounds.y -= ptDisplay.y;
+					Rectangle boundsRaw = cell.getBoundsRaw();
+					if (boundsRaw.y + cellBounds.height > clientArea.y
+							+ clientArea.height) {
+						cellBounds.height -= (boundsRaw.y + cellBounds.height)
+								- (clientArea.y + clientArea.height);
+					}
+					int tableWidth = cTable.getClientArea().width;
+					if (boundsRaw.x + cellBounds.width > clientArea.x
+							+ tableWidth) {
+						cellBounds.width -= (boundsRaw.x + cellBounds.width)
+								- (clientArea.x + tableWidth);
+					}
+
+					UIDebugGenerator.obfusticateArea(image, cellBounds, text);
+				}
+
+			}
+		}
+
+		UISWTViewCore view = tvTabsCommon == null ? null
+				: tvTabsCommon.getActiveSubView();
+		if (view instanceof ObfusticateImage) {
+			try {
+				((ObfusticateImage) view).obfusticatedImage(image);
+			} catch (Exception e) {
+				Debug.out("Obfuscating " + view, e);
+			}
+		}
+		return image;
+	}
+
+	protected TableViewSWTPanelCreator getMainPanelCreator() {
+		return mainPanelCreator;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#setMainPanelCreator(org.gudy.azureus2.ui.swt.views.table.TableViewSWTPanelCreator)
+	 */
+	public void setMainPanelCreator(TableViewSWTPanelCreator mainPanelCreator) {
+		this.mainPanelCreator = mainPanelCreator;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#setRowDefaultIconSize(org.eclipse.swt.graphics.Point)
+	 */
+	public void setRowDefaultIconSize(Point size) {
+		setRowDefaultHeight(size.y);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableCell(int, int)
+	 */
+	public TableCellCore getTableCell(int x, int y) {
+		TableRowSWT row = getTableRow(x, y, true);
+		if (row == null) {
+			return null;
+		}
+
+		TableColumnCore column = getTableColumnByOffset(x);
+		if (column == null) {
+			return null;
+		}
+
+		return row.getTableCellCore(column.getName());
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableCellMouseOffset(org.gudy.azureus2.ui.swt.views.table.TableCellSWT)
+	 */
+	public Point getTableCellMouseOffset(TableCellSWT tableCell) {
+		if (tableCell == null) {
+			return null;
+		}
+		Point pt = cTable.getDisplay().getCursorLocation();
+		pt = cTable.toControl(pt);
+
+		Rectangle bounds = tableCell.getBounds();
+		int x = pt.x - bounds.x;
+		if (x < 0 || x > bounds.width) {
+			return null;
+		}
+		int y = pt.y - bounds.y;
+		if (y < 0 || y > bounds.height) {
+			return null;
+		}
+		return new Point(x, y);
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#enableFilterCheck(org.eclipse.swt.widgets.Text, com.aelitis.azureus.ui.common.table.TableViewFilterCheck)
+	public void enableFilterCheck(Text txtFilter,
+			TableViewFilterCheck<Object> filterCheck) {
+		TableViewSWTFilter<?> filter = getSWTFilter();
+		if (filter != null) {
+			if (filter.widget != null && !filter.widget.isDisposed()) {
+				filter.widget.removeKeyListener(tvSWTCommon);
+				filter.widget.removeModifyListener(filter.widgetModifyListener);
+			}
+		} else {
+			this.filter = filter = new TableViewSWTFilter();
+		}
+		filter.widget = txtFilter;
+		if (txtFilter != null) {
+			txtFilter.setMessage(MessageText.getString("MyTorrentsView.filter"));
+			txtFilter.addKeyListener(tvSWTCommon);
+
+			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 void disableFilterCheck() {
+		TableViewSWTFilter<?> filter = getSWTFilter();
+		if ( filter == null ){
+			return;
+		}
+		
+		if (filter.widget != null && !filter.widget.isDisposed()) {
+			filter.widget.removeKeyListener(tvSWTCommon);
+			filter.widget.removeModifyListener(filter.widgetModifyListener);
+		}
+		filter = null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#setFilterText(java.lang.String)
+	 */
+	public void setFilterText(String s) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.setFilterText(s);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#enableSizeSlider(org.eclipse.swt.widgets.Composite, int, int)
+	 */
+	public boolean enableSizeSlider(Composite composite, int min, int max) {
+		// TODO
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#disableSizeSlider()
+	 */
+	public void disableSizeSlider() {
+		// TODO
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void addRowPaintListener(TableRowSWTPaintListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.addRowPaintListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeRowPaintListener(org.gudy.azureus2.ui.swt.views.table.TableRowSWTPaintListener)
+	 */
+	public void removeRowPaintListener(TableRowSWTPaintListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.removeRowPaintListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#invokePaintListeners(org.eclipse.swt.graphics.GC, com.aelitis.azureus.ui.common.table.TableRowCore, com.aelitis.azureus.ui.common.table.TableColumnCore, org.eclipse.swt.graphics.Rectangle)
+	 */
+	public void invokePaintListeners(GC gc, TableRowCore row,
+			TableColumnCore column, Rectangle cellArea) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.invokePaintListeners(gc, row, column, cellArea);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#addRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void addRowMouseListener(TableRowMouseListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.addRowMouseListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#removeRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseListener)
+	 */
+	public void removeRowMouseListener(TableRowMouseListener listener) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.removeRowMouseListener(listener);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#invokeRowMouseListener(org.gudy.azureus2.plugins.ui.tables.TableRowMouseEvent)
+	 */
+	public void invokeRowMouseListener(TableRowMouseEvent event) {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.invokeRowMouseListener(event);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableOrTreeSWT()
+	 */
+	public TableOrTreeSWT getTableOrTreeSWT() {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#packColumns()
+	 */
+	public void packColumns() {
+		// TODO
+	}
+
+	/* (non-Javadoc)
+	 * @see org.gudy.azureus2.core3.config.ParameterListener#parameterChanged(java.lang.String)
+	 */
+	public void parameterChanged(String parameterName) {
+		boolean invalidate = parameterName == null;
+		if (parameterName == null || parameterName.equals("Graphics Update")) {
+			graphicsUpdate = configMan.getIntParameter("Graphics Update");
+		}
+		if (parameterName == null || parameterName.equals("ReOrder Delay")) {
+			reOrderDelay = configMan.getIntParameter("ReOrder Delay");
+		}
+		if (parameterName == null || parameterName.equals("Table.extendedErase")) {
+			extendedErase = configMan.getBooleanParameter("Table.extendedErase");
+			invalidate = true;
+		}
+		if (parameterName == null || parameterName.equals("Table.headerHeight")) {
+			headerHeight = configMan.getIntParameter("Table.headerHeight");
+			if (headerHeight == 0) {
+				headerHeight = DEFAULT_HEADER_HEIGHT;
+			}
+			setHeaderVisible(getHeaderVisible());
+		}
+		
+		if (parameterName == null || parameterName.startsWith("Color")) {
+			tableInvalidate();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#createNewRow(java.lang.Object)
+	 */
+	@Override
+	public TableRowCore createNewRow(Object object) {
+		return new TableRowPainted(null, this, object, true);
+	}
+
+	/* (non-Javadoc)
+	 * @see com.aelitis.azureus.ui.common.table.impl.TableViewImpl#visibleRowsChanged()
+	 */
+	@Override
+	public void visibleRowsChanged() {
+		swt_visibleRowsChanged();
+	}
+
+	private void swt_visibleRowsChanged() {
+		final List<TableRowSWT> newlyVisibleRows = new ArrayList<TableRowSWT>();
+		final List<TableRowSWT> nowInVisibleRows;
+		final ArrayList<TableRowSWT> rowsStayedVisibleButMoved = new ArrayList<TableRowSWT>();
+		List<TableRowSWT> newVisibleRows;
+		if (isVisible()) {
+			// this makes a copy.. slower
+			TableRowCore[] rows = getRows();
+			newVisibleRows = new ArrayList<TableRowSWT>();
+			recalculateVisibleRows(rows, 0, newVisibleRows,
+					rowsStayedVisibleButMoved);
+
+		} else {
+			newVisibleRows = Collections.emptyList();
+		}
+		nowInVisibleRows = new ArrayList<TableRowSWT>(0);
+		synchronized (visibleRows_sync) {
+			if (visibleRows != null) {
+				nowInVisibleRows.addAll(visibleRows);
+			}
+		}
+
+		LinkedHashSet<TableRowPainted> rows = new LinkedHashSet<TableRowPainted>(newVisibleRows.size());
+		for (TableRowSWT row : newVisibleRows) {
+			rows.add((TableRowPainted) row);
+			boolean removed = nowInVisibleRows.remove(row);
+			if (!removed) {
+				newlyVisibleRows.add(row);
+			}
+		}
+
+		synchronized (visibleRows_sync) {
+			visibleRows = rows;
+		}
+
+		if (DEBUG_ROWCHANGE) {
+			debug("visRowsChanged; shown=" + visibleRows.size() + "; +"
+					+ newlyVisibleRows.size() + "/-" + nowInVisibleRows.size() + "/"
+					+ rowsStayedVisibleButMoved.size() + " via "
+					+ Debug.getCompressedStackTrace(8));
+		}
+		Utils.getOffOfSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				boolean bTableUpdate = false;
+
+				for (TableRowSWT row : newlyVisibleRows) {
+					// no need to refres, the redraw will do it
+					//row.refresh(true, true);
+					row.setShown(true, false);
+					row.invalidate();
+					redrawRow((TableRowPainted) row, false);
+					rowsStayedVisibleButMoved.remove(row);
+					if (Constants.isOSX) {
+						bTableUpdate = true;
+					}
+				}
+
+				for (TableRowSWT row : rowsStayedVisibleButMoved) {
+					row.invalidate();
+					redrawRow((TableRowPainted) row, false);
+				}
+
+				for (TableRowSWT row : nowInVisibleRows) {
+					row.setShown(false, false);
+				}
+
+				if (bTableUpdate) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							if (cTable != null && !cTable.isDisposed()) {
+								cTable.update();
+							}
+						}
+					});
+				}
+
+			}
+		});
+	}
+
+	private void recalculateVisibleRows(TableRowCore[] rows, int yStart,
+			List<TableRowSWT> newVisibleRows,
+			List<TableRowSWT> rowsStayedVisibleButMoved) {
+		Rectangle bounds = clientArea;
+
+		int y = yStart;
+		String sDebug;
+		if (DEBUG_ROWCHANGE) {
+			sDebug = "Visible Rows: ";
+		}
+		for (TableRowCore row : rows) {
+			if (row == null) {
+				continue;
+			}
+			TableRowPainted rowSWT = ((TableRowPainted) row);
+			int rowHeight = rowSWT.getHeight();
+			int rowFullHeight = rowSWT.getFullHeight();
+
+			if ((y < bounds.y + bounds.height) && (y + rowFullHeight > bounds.y)) {
+				// this row or subrows are visible
+
+				boolean offsetChanged = rowSWT.setDrawOffset(new Point(bounds.x, y));
+
+				// check if this row
+				if (y + rowHeight > bounds.y) {
+					if (DEBUG_ROWCHANGE) {
+						sDebug += (rowSWT.getParentRowCore() == null ? ""
+								: rowSWT.getParentRowCore().getIndex() + ".")
+								+ rowSWT.getIndex()
+								+ "(ofs=" + (offsetChanged ? "*" : "")
+								+ y
+								+ ";rh="
+								+ rowHeight + "/" + rowFullHeight + ")" + ", ";
+					}
+
+					if (offsetChanged) {
+						rowsStayedVisibleButMoved.add(rowSWT);
+					}
+					newVisibleRows.add(rowSWT);
+				}
+
+				// check if subrows
+				if (row.isExpanded()) {
+					TableRowCore[] subRowsWithNull = row.getSubRowsWithNull();
+					if (subRowsWithNull.length > 0) {
+						recalculateVisibleRows(subRowsWithNull, y + rowHeight,
+								newVisibleRows, rowsStayedVisibleButMoved);
+					}
+				}
+			} else if (newVisibleRows.size() > 0) {
+				if (DEBUG_ROWCHANGE) {
+					sDebug += "break(ofs=" + y + ";bounds=" + bounds + ";rh=" + rowFullHeight + ")";
+				}
+				break;
+			}
+			y += rowFullHeight;
+		}
+		if (DEBUG_ROWCHANGE) {
+			if (yStart == 0) {
+				debug(sDebug);
+			}
+		}
+	}
+	
+	@Override
+	public int uiGuessMaxVisibleRows() {
+		return (clientArea.height / defaultRowHeight) + 1;
+	}
+
+	@Override
+	public void uiRemoveRows(TableRowCore[] rows, Integer[] rowIndexes) {
+		if (focusedRow != null) {
+  		for (TableRowCore row : rows) {
+  			if (row == focusedRow) {
+  				setFocusedRow(null);
+  				break;
+  			}
+  		}
+  	}
+		int bottomIndex = getRowCount() - 1;
+		if (bottomIndex < 0) {
+			redrawTable();
+		} else {
+			TableRowCore rowBottom = getLastVisibleRow();
+			if (rowBottom != null) {
+				while (rowBottom.getParentRowCore() != null) {
+					rowBottom = rowBottom.getParentRowCore();
+				}
+				
+				if (indexOf(rowBottom) < 0) {
+					redrawTable();
+				}
+			}
+		}
+	}
+	
+	private TableRowPainted getLastVisibleRow() {
+		synchronized (visibleRows_sync) {
+			if (visibleRows == null || visibleRows.size() == 0) {
+				return null;
+			}
+			TableRowPainted rowBottom = null;
+			for (TableRowPainted row : visibleRows) {
+				rowBottom = row;
+			}
+			return rowBottom;
+		}
+	}
+
+
+	@Override
+	public void getOffUIThread(AERunnable runnable) {
+		Utils.getOffOfSWTThread(runnable);
+	}
+
+	protected void swt_calculateClientArea() {
+		if (cTable == null || cTable.isDisposed()) {
+			return;
+		}
+		Rectangle oldClientArea = clientArea;
+		Rectangle newClientArea = cTable.getClientArea();
+		newClientArea.x = hBar.getSelection();
+		newClientArea.y = vBar.getSelection();
+
+		int w = 0;
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		for (TableColumnCore column : visibleColumns) {
+			w += column.getWidth();
+		}
+		columnsWidth = w;
+		w = newClientArea.width = Math.max(newClientArea.width, w);
+
+		boolean refreshTable = false;
+		boolean changedX;
+		boolean changedY;
+		//boolean changedW;
+		boolean changedH;
+		if (oldClientArea != null) {
+			changedX = oldClientArea.x != newClientArea.x;
+			changedY = oldClientArea.y != newClientArea.y;
+			//changedW = oldClientArea.width != newClientArea.width;
+			changedH = oldClientArea.height != newClientArea.height;
+		} else {
+			changedX = changedY = changedH = true;
+			//changedX = changedY = changedW = changedH = true;
+		}
+		
+		clientArea = newClientArea;
+		if (tvSWTCommon != null) {
+			tvSWTCommon.xAdj = -clientArea.x;
+		}
+		
+		//System.out.println("CA=" + clientArea + " via " + Debug.getCompressedStackTrace());
+
+		boolean needRedraw = false;
+		if (changedY || changedH) {
+			visibleRowsChanged();
+			if (changedY && oldClientArea != null) {
+				Set<TableRowPainted> visibleRows = this.visibleRows;
+				if (visibleRows.size() > 0) {
+					if (canvasImage != null && !canvasImage.isDisposed() && !changedH) {
+
+						int yDiff = oldClientArea.y - newClientArea.y;
+						if (Math.abs(yDiff) < clientArea.height) {
+							boolean wasIn = in_swt_updateCanvasImage;
+							in_swt_updateCanvasImage = true;
+  						GC gc = new GC(canvasImage);
+  						Rectangle bounds = canvasImage.getBounds();
+  						//System.out.println("moving y " + yDiff + ";cah=" + clientArea.height);
+  						if (yDiff > 0) {
+  							gc.copyArea(0, 0, bounds.width, bounds.height, 0, yDiff, false);
+					  		swt_paintCanvasImage(gc, new Rectangle(0, 0, 9999, yDiff));
+					  		gc.setClipping((Rectangle) null);
+  						} else {
+  							gc.copyArea(0, -yDiff, bounds.width, bounds.height , 0, 0, false);
+  							int h = -yDiff;
+  							TableRowPainted row = getLastVisibleRow();
+  							if (row != null) {
+  								//row.invalidate();
+  								h += row.getHeight();
+  							}
+					  		swt_paintCanvasImage(gc, new Rectangle(0, bounds.height - h, 9999, h));
+					  		gc.setClipping((Rectangle) null);
+  						}
+  						gc.dispose();
+							in_swt_updateCanvasImage = wasIn;
+  						
+  						needRedraw = true;
+						} else {
+							refreshTable = true;
+						}
+					}
+
+				}
+			}
+		}
+
+		if (changedX) {
+			cHeaderArea.redraw();
+		}
+
+		Image newImage = canvasImage;
+
+		//List<TableRowSWT> visibleRows = getVisibleRows();
+		int h = 0;
+		synchronized (visibleRows_sync) {
+			TableRowPainted lastRow = getLastVisibleRow();
+			if (lastRow != null) {
+				h = lastRow.getDrawOffset().y - clientArea.y + lastRow.getHeight();
+				if (h < clientArea.height && lastRow.isExpanded()) {
+					TableRowCore[] subRows = lastRow.getSubRowsWithNull();
+					for (TableRowCore subRow : subRows) {
+						if (subRow == null) {
+							continue;
+						}
+						TableRowPainted subRowP = (TableRowPainted) subRow;
+
+						h += subRowP.getFullHeight();
+						if (h >= clientArea.height) {
+							break;
+						}
+					}
+				}
+			}
+		}
+		if (h < clientArea.height) {
+			h = clientArea.height;
+		}
+
+		int oldH = canvasImage == null || canvasImage.isDisposed() ? 0
+				: canvasImage.getBounds().height;
+		int oldW = canvasImage == null || canvasImage.isDisposed() ? 0
+				: canvasImage.getBounds().width;
+
+		if (canvasImage == null || oldW != w || h > oldH) {
+			//System.out.println("oldW=" + oldW + ";" + w+ ";h=" + h + ";" + oldH);
+			if (h <= 0 || clientArea.width <= 0) {
+				newImage = null;
+			} else {
+				newImage = new Image(shell.getDisplay(), w, h);
+			}
+		}
+		boolean canvasChanged = (canvasImage != newImage);
+		if (canvasChanged) {
+			Image oldImage = canvasImage;
+			canvasImage = newImage;
+			
+			if (oldImage != null && !oldImage.isDisposed()) {
+				oldImage.dispose();
+			}
+		}
+		
+		
+
+		// paint event will handle any changedX or changedW
+		if (changedH || canvasChanged || refreshTable) {
+			//System.out.println(changedX + ";" + changedY + ";" + changedH + ";" + canvasChanged);
+			//System.out.println("Redraw " + Debug.getCompressedStackTrace());
+
+			// run refreshTable on SWT (this) thread to ensure rows have been
+			// refreshed for the updateCanvasImage call immediately after it
+			__refreshTable(false);
+			swt_updateCanvasImage(false);
+		}
+		
+		//		System.out.println("imgBounds = " + canvasImage.getBounds() + ";ca="
+		//				+ clientArea + ";" + composite.getClientArea() + ";h=" + h + ";oh="
+		//				+ oldH + " via " + Debug.getCompressedStackTrace(3));
+
+		if (needRedraw) {
+			cTable.redraw();
+		}
+	}
+
+	public void swt_updateCanvasImage(boolean immediateRedraw) {
+		if (canvasImage != null && !canvasImage.isDisposed()) {
+			swt_updateCanvasImage(canvasImage.getBounds(), immediateRedraw);
+		}
+	}
+
+	private boolean in_swt_updateCanvasImage = false;
+	protected void swt_updateCanvasImage(final Rectangle bounds, final boolean immediateRedraw) {
+		// no need to sync around in_swt_updateCanvasImage, we are assumed to always
+		// be on SWT thread and in_swt_updateCanvasImage is only used here
+		if (in_swt_updateCanvasImage) {
+			Utils.execSWTThreadLater(0, new AERunnable() {
+				public void runSupport() {
+					swt_updateCanvasImage(bounds, immediateRedraw);
+				}
+			});
+			return;
+		}
+		in_swt_updateCanvasImage = true;
+		try {
+  		if (canvasImage == null || canvasImage.isDisposed() || bounds == null) {
+  			return;
+  		}
+  		//System.out.println("UpdateCanvasImage " + bounds + "; via " + Debug.getCompressedStackTrace());
+  		GC gc = new GC(canvasImage);
+  		swt_paintCanvasImage(gc, bounds);
+  		gc.dispose();
+  		if (cTable != null && !cTable.isDisposed()) {
+  			cTable.redraw(bounds.x - clientArea.x, bounds.y, bounds.width, bounds.height, false);
+  			if (immediateRedraw) {
+  				cTable.update();
+  			}
+  		}
+  		if (sCanvasImage != null) {
+  			sCanvasImage.getShell().setSize(canvasImage.getBounds().width, canvasImage.getBounds().height);
+  			sCanvasImage.redraw(bounds.x, bounds.y, bounds.width, bounds.height, true);
+  			sCanvasImage.update();
+  		}
+		} finally {
+			in_swt_updateCanvasImage = false;
+		}
+	}
+
+	public Rectangle getClientArea() {
+		return clientArea;
+	}
+
+	public boolean isVisible() {
+		if (!Utils.isThisThreadSWT()) {
+			return isVisible;
+		}
+		boolean wasVisible = isVisible;
+		isVisible = cTable != null && !cTable.isDisposed() && cTable.isVisible()
+				&& !shell.getMinimized();
+		if (isVisible != wasVisible) {
+			visibleRowsChanged();
+			UISWTViewCore view = tvTabsCommon == null ? null
+					: tvTabsCommon.getActiveSubView();
+			if (isVisible) {
+				loopFactor = 0;
+
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
+				}
+			} else {
+				if (view != null) {
+					view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
+				}
+			}
+		}
+		return isVisible;
+	}
+
+	public void removeAllTableRows() {
+		if (DEBUG_ROWCHANGE) {
+			debug("RemoveAlLRows");
+		}
+		super.removeAllTableRows();
+		synchronized (visibleRows_sync) {
+			visibleRows = new LinkedHashSet<TableRowPainted>();
+		}
+		setFocusedRow(null);
+		totalHeight = 0;
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (cTable == null || cTable.isDisposed()) {
+					return;
+				}
+				swt_fixupSize();
+				swt_updateCanvasImage(false);
+				if (DEBUG_ROWCHANGE) {
+					debug("RemoveAllRows done");
+				}
+			}
+		});
+	}
+
+	protected void swt_fixupSize() {
+		//debug("Set minSize to " + columnsWidth + "x" + totalHeight + ";ca=" + clientArea + ";" + Debug.getCompressedStackTrace());
+		if (vBar != null && !vBar.isDisposed()) {
+			int tableSize = clientArea.height;
+			int max = totalHeight;
+			if (max < tableSize) {
+				vBar.setSelection(0);
+				vBar.setEnabled(false);
+				vBar.setVisible(false);
+			} else {
+				if (!vBar.isVisible()) {
+					vBar.setVisible(true);
+					vBar.setEnabled(true);
+				}
+				if (vBar.getMaximum() != max) {
+					vBar.setMaximum(max);
+					swt_vBarChanged();
+				}
+				vBar.setThumb(tableSize);
+				vBar.setPageIncrement(tableSize);
+			}
+		}
+		if (hBar != null && !hBar.isDisposed()) {
+			int tableSize = cTable.getSize().x;
+			int max = columnsWidth;
+			if (vBar.isVisible()) {
+				max += vBar.getSize().x;
+			}
+			if (max < tableSize) {
+				hBar.setSelection(0);
+				hBar.setEnabled(false);
+				hBar.setVisible(false);
+			} else {
+				if (!hBar.isVisible()) {
+					hBar.setVisible(true);
+					hBar.setEnabled(true);
+				}
+				hBar.setValues(hBar.getSelection(), 0, max, tableSize, 50, tableSize);
+			}
+			if (vBar != null && !vBar.isDisposed() && hBar.isVisible()) {
+				vBar.setThumb(clientArea.height - hBar.getSize().y);
+				vBar.setMaximum(totalHeight - hBar.getSize().y);
+				vBar.setPageIncrement(vBar.getPageIncrement() - hBar.getSize().y);
+			}
+
+		}
+	}
+
+	@Override
+	protected void uiChangeColumnIndicator() {
+		Utils.execSWTThread(new AERunnable() {
+
+			@Override
+			public void runSupport() {
+				if (cHeaderArea != null && !cHeaderArea.isDisposed()) {
+					cHeaderArea.redraw();
+				}
+			}
+		});
+	}
+
+	public TableColumnCore getTableColumnByOffset(int mouseX) {
+		int x = -clientArea.x;
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		for (TableColumnCore column : visibleColumns) {
+			int w = column.getWidth();
+
+			if (mouseX >= x && mouseX < x + w) {
+				return column;
+			}
+
+			x += w;
+		}
+		return null;
+	}
+
+	// @see org.gudy.azureus2.ui.swt.views.table.TableViewSWT#getTableRow(int, int, boolean)
+	public TableRowSWT getTableRow(int x, int y, boolean anyX) {
+		return (TableRowSWT) getRow(anyX ? 2 : x, clientArea.y + y);
+	}
+
+	@Override
+	public void setSelectedRows(TableRowCore[] newSelectionArray, boolean trigger) {
+		super.setSelectedRows(newSelectionArray, trigger);
+
+		boolean focusInSelection = false;
+		for (TableRowCore row : newSelectionArray) {
+			if (row == null) {
+				continue;
+			}
+			if (row.equals(focusedRow)) {
+				focusInSelection = true;
+				break;
+			}
+		}
+		if (!focusInSelection) {
+			setFocusedRow(newSelectionArray.length == 0 ? null : newSelectionArray[0]);
+		}
+	}
+
+	public void setRowSelected(final TableRowCore row, boolean selected,
+			boolean trigger) {
+		if (selected && !isSelected(row)) {
+			setFocusedRow(row);
+		}
+		super.setRowSelected(row, selected, trigger);
+
+		if (row instanceof TableRowSWT) {
+			((TableRowSWT) row).setWidgetSelected(selected);
+		}
+	}
+
+	public void editCell(int column, int row) {
+		//TODO
+	}
+
+	public int getColumnNo(int mouseX) {
+		int x = -clientArea.x;
+		TableColumnCore[] visibleColumns = getVisibleColumns();
+		for (int i = 0; i < visibleColumns.length; i++) {
+			TableColumnCore column = visibleColumns[i];
+			int w = column.getWidth();
+
+			if (mouseX >= x && mouseX < x + w) {
+				return i;
+			}
+
+			x += w;
+		}
+		return -1;
+	}
+
+	public boolean isDragging() {
+		return isDragging;
+	}
+
+	public TableViewSWTFilter<?> getSWTFilter() {
+		return (TableViewSWTFilter<?>) filter;
+	}
+
+	public 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);
+	}
+
+	public boolean isSingleSelection() {
+		return !isMultiSelect;
+	}
+
+	public void expandColumns() {
+		//TODO
+	}
+
+	@Override
+	public void triggerTabViewsDataSourceChanged(boolean sendParent) {
+		if (tvTabsCommon != null) {
+			tvTabsCommon.triggerTabViewsDataSourceChanged(sendParent);
+		}
+	}
+	
+	@Override
+	public void uiSelectionChanged(final TableRowCore[] newlySelectedRows,
+			final TableRowCore[] deselectedRows) {
+		//System.out.println("Redraw " + Debug.getCompressedStackTrace());
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				for (TableRowCore row : deselectedRows) {
+					row.invalidate();
+					redrawRow((TableRowPainted) row, false);
+				}
+				for (TableRowCore row : newlySelectedRows) {
+					row.invalidate();
+					redrawRow((TableRowPainted) row, false);
+				}
+			}
+		});
+	}
+
+	public void delete() {
+		triggerLifeCycleListener(TableLifeCycleListener.EVENT_DESTROYED);
+
+		if (tvTabsCommon != null) {
+			tvTabsCommon.delete();
+			tvTabsCommon = null;
+		}
+
+		TableStructureEventDispatcher.getInstance(tableID).removeListener(this);
+		TableColumnManager tcManager = TableColumnManager.getInstance();
+		if (tcManager != null) {
+			tcManager.saveTableColumns(getDataSourceType(), tableID);
+		}
+
+		Utils.disposeSWTObjects(new Object[] {
+			cTable
+		});
+		cTable = null;
+
+		removeAllTableRows();
+		configMan.removeParameterListener("ReOrder Delay", this);
+		configMan.removeParameterListener("Graphics Update", this);
+		configMan.removeParameterListener("Table.extendedErase", this);
+		configMan.removeParameterListener("Table.headerHeight", this);
+		Colors.getInstance().removeColorsChangedListener(this);
+
+		super.delete();
+
+		MessageText.removeListener(this);
+	}
+
+	@Override
+	public void generate(IndentWriter writer) {
+		super.generate(writer);
+
+		if (tvTabsCommon != null) {
+			tvTabsCommon.generate(writer);
+		}
+	}
+
+	private Menu createMenu() {
+		if (!isMenuEnabled()) {
+			return null;
+		}
+
+		final Menu menu = new Menu(shell, SWT.POP_UP);
+		cTable.addListener(SWT.MenuDetect, new Listener() {
+			public void handleEvent(Event event) {
+				if (event.widget == cHeaderArea) {
+					menu.setData("inBlankArea", false);
+					menu.setData("isHeader", true);
+
+				} else {
+					boolean noRow = getTableRowWithCursor() == null;
+
+					menu.setData("inBlankArea", noRow);
+					menu.setData("isHeader", false);
+				}
+				Point pt = cHeaderArea.toControl(event.x, event.y);
+				menu.setData("column", getTableColumnByOffset(pt.x));
+			}
+		});
+		cHeaderArea.addListener(SWT.MenuDetect, new Listener() {
+			public void handleEvent(Event event) {
+				menu.setData("inBlankArea", false);
+				menu.setData("isHeader", true);
+				Point pt = cHeaderArea.toControl(event.x, event.y);
+				menu.setData("column", getTableColumnByOffset(pt.x));
+			}
+		});
+		MenuBuildUtils.addMaintenanceListenerForMenu(menu,
+				new MenuBuildUtils.MenuBuilder() {
+					public void buildMenu(Menu menu, MenuEvent menuEvent) {
+						Object oIsHeader = menu.getData("isHeader");
+						boolean isHeader = (oIsHeader instanceof Boolean)
+								? ((Boolean) oIsHeader).booleanValue() : false;
+
+						Object oInBlankArea = menu.getData("inBlankArea");
+						boolean inBlankArea = (oInBlankArea instanceof Boolean)
+								? ((Boolean) oInBlankArea).booleanValue() : false;
+
+						TableColumnCore column = (TableColumnCore) menu.getData("column");
+
+						if (isHeader) {
+							tvSWTCommon.fillColumnMenu(menu, column, false);
+						} else if (inBlankArea) {
+							tvSWTCommon.fillColumnMenu(menu, column, true);
+						} else {
+							tvSWTCommon.fillMenu(menu, column);
+						}
+
+					}
+				});
+
+		return menu;
+	}
+
+	public void showColumnEditor() {
+		if (tvSWTCommon != null) {
+			tvSWTCommon.showColumnEditor();
+		}
+	}
+
+	@Override
+	public TableRowCore getFocusedRow() {
+		return focusedRow;
+	}
+
+	public void setFocusedRow(TableRowCore row) {
+		TableRowPainted oldFocusedRow = focusedRow;
+		if (!(row instanceof TableRowPainted)) {
+			row = null;
+		}
+		focusedRow = (TableRowPainted) row;
+		if (focusedRow != null) {
+			if (focusedRow.isVisible()
+					&& focusedRow.getDrawOffset().y + focusedRow.getHeight() <= clientArea.y + clientArea.height
+					&& focusedRow.getDrawOffset().y >= clientArea.y) {
+				// redraw for BG color change
+				redrawRow(focusedRow, false);
+			} else {
+
+				showRow(focusedRow);
+			}
+		}
+		if (oldFocusedRow != null) {
+			redrawRow(oldFocusedRow, false);
+		}
+	}
+
+	public void showRow(final TableRowCore rowToShow) {
+		// scrollto
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				if (isDisposed()) {
+					return;
+				}
+				
+				if (rowToShow.isVisible()) {
+					// draw offset is valid, use that to scroll
+					int y = ((TableRowPainted) rowToShow).getDrawOffset().y;
+					if (y + rowToShow.getHeight() > clientArea.y + clientArea.height) {
+						y -= (clientArea.height - rowToShow.getHeight());
+					}
+					vBar.setSelection(y);
+					swt_vBarChanged();
+				} else {
+					TableRowCore parentFocusedRow = rowToShow;
+					while (parentFocusedRow.getParentRowCore() != null) {
+						parentFocusedRow = parentFocusedRow.getParentRowCore();
+					}
+					TableRowCore[] rows = getRows();
+					int y = 0;
+					for (TableRowCore row : rows) {
+						if (row == parentFocusedRow) {
+							if (parentFocusedRow != rowToShow) {
+								y += row.getHeight();
+								TableRowCore[] subRowsWithNull = parentFocusedRow.getSubRowsWithNull();
+								for (TableRowCore subrow : subRowsWithNull) {
+									if (subrow == rowToShow) {
+										break;
+									}
+									y += ((TableRowPainted) subrow).getFullHeight();
+								}
+							}
+							break;
+						}
+						y += ((TableRowPainted) row).getFullHeight();
+					}
+
+					if (y + rowToShow.getHeight() > clientArea.y + clientArea.height) {
+						y -= (clientArea.height - rowToShow.getHeight());
+					}
+					// y now at top of focused row
+					vBar.setSelection(y);
+					swt_vBarChanged();
+				}
+			}
+		});
+	}
+
+	boolean qdRowHeightChanged = false;
+	public void rowHeightChanged(final TableRowCore row, int oldHeight,
+			int newHeight) {
+
+		synchronized (heightChangeSync) {
+  		totalHeight += (newHeight - oldHeight);
+  		//System.out.println("Height delta: " + (newHeight - oldHeight) + ";ttl=" + totalHeight);
+  
+  		if (qdRowHeightChanged) {
+  			return;
+  		}
+  		qdRowHeightChanged = true;
+		}
+		Utils.execSWTThread(new AERunnable() {
+			public void runSupport() {
+				synchronized (heightChangeSync) {
+					qdRowHeightChanged = false;
+				}
+				// if moving visibleRowsChanged(), make sure subrows being resized on
+				// add trigger work properly
+				visibleRowsChanged();
+				swt_fixupSize();
+			}
+		});
+	}
+
+	public void redrawTable() {
+		synchronized (TableViewPainted.this) {
+			if (redrawTableScheduled) {
+				return;
+			}
+			redrawTableScheduled = true;
+		}
+
+		visibleRowsChanged();
+		//System.out.println("Redraw " + Debug.getCompressedStackTrace());
+		Utils.execSWTThreadLater(0, new AERunnable() {
+			public void runSupport() {
+				synchronized (TableViewPainted.this) {
+					redrawTableScheduled = false;
+				}
+
+				if (canvasImage != null && !canvasImage.isDisposed()) {
+					canvasImage.dispose();
+					canvasImage = null;
+				}
+				swt_calculateClientArea();
+			}
+		});
+	}
+	
+	private String prettyIndex(TableRowCore row) {
+		String s = "" + row.getIndex();
+		if (row.getParentRowCore() != null) {
+			s = row.getParentRowCore().getIndex() + "." + s;
+		}
+		return s;
+	}
+
+	public void redrawRow(final TableRowPainted row, final boolean immediateRedraw) {
+		if (row == null) {
+			return;
+		}
+		if (TableRowPainted.DEBUG_ROW_PAINT) {
+			System.out.println(SystemTime.getCurrentTime() + "} redraw "
+					+ prettyIndex(row) + " scheduled via " + Debug.getCompressedStackTrace());
+		}
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				if (!isVisible || !row.isVisible()) {
+					return;
+				}
+				Rectangle bounds = row.getDrawBounds();
+				if (TableRowPainted.DEBUG_ROW_PAINT) {
+					System.out.println(SystemTime.getCurrentTime() + "] redraw "
+							+ prettyIndex(row) + " @ " + bounds);
+				}
+				if (bounds != null) {
+					Composite composite = getComposite();
+					if (composite != null && !composite.isDisposed()) {
+						int h = isLastRow(row) ? composite.getSize().y - bounds.y
+								: bounds.height;
+						//row.debug("isLastRow?" + isLastRow(row) + ";" + bounds + ";" + h);
+						swt_updateCanvasImage(new Rectangle(bounds.x, bounds.y, bounds.width, h), immediateRedraw);
+					}
+				}
+			}
+		});
+	}
+
+	public Object getSyncObject() {
+		return lock;
+	}
+	
+	@Override
+	public boolean isTableSelected() {
+		TableView tv = SelectedContentManager.getCurrentlySelectedTableView();
+		return tv == this || (tv == null && isFocused);
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/table/utils/CoreTableColumn.java b/org/gudy/azureus2/ui/swt/views/table/utils/CoreTableColumn.java
index 045fc2e..0fcfcbf 100644
--- a/org/gudy/azureus2/ui/swt/views/table/utils/CoreTableColumn.java
+++ b/org/gudy/azureus2/ui/swt/views/table/utils/CoreTableColumn.java
@@ -60,7 +60,8 @@ public abstract class CoreTableColumn
 
   public CoreTableColumn(Class forDataSourceType, String sName, int iAlignment,
 			int iWidth, String sTableID) {
-		super(forDataSourceType, sTableID, sName);
+		super(sTableID, sName);
+		addDataSourceType(forDataSourceType);
 		super.initialize(iAlignment, POSITION_INVISIBLE, iWidth);
 		setUseCoreDataSource(true);
 		addListeners(this);
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 646b10e..be4d172 100644
--- a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java
+++ b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnCreator.java
@@ -32,10 +32,11 @@ 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 com.aelitis.azureus.ui.common.table.TableColumnCoreCreationListener;
+import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
 
 /**
  * @author TuxPaper
@@ -51,6 +52,7 @@ public class TableColumnCreator
 			HealthItem.COLUMN_ID,
 			RankItem.COLUMN_ID,
 			NameItem.COLUMN_ID,
+			"TorrentStream",
 			"azsubs.ui.column.subs",
 			"Info",
 			CommentIconItem.COLUMN_ID,
@@ -141,7 +143,11 @@ public class TableColumnCreator
 	private static void setVisibility(Map mapTCs, String[] defaultVisibleOrder) {
 		for (Iterator iter = mapTCs.values().iterator(); iter.hasNext();) {
 			TableColumnCore tc = (TableColumnCore) iter.next();
-			tc.setVisible(false);
+			Long force_visible = (Long)tc.getUserData( TableColumn.UD_FORCE_VISIBLE );
+			if ( force_visible == null || force_visible==0 ){
+			
+				tc.setVisible(false);
+			}
 		}
 
 		for (int i = 0; i < defaultVisibleOrder.length; i++) {
@@ -189,6 +195,7 @@ public class TableColumnCreator
 		c.put(MaxUploadsItem.COLUMN_ID, new cInfo(MaxUploadsItem.class, MaxUploadsItem.DATASOURCE_TYPE));
 		c.put(TotalSpeedItem.COLUMN_ID, new cInfo(TotalSpeedItem.class, TotalSpeedItem.DATASOURCE_TYPE));
 		c.put(FilesDoneItem.COLUMN_ID, new cInfo(FilesDoneItem.class, FilesDoneItem.DATASOURCE_TYPE));
+		c.put(FileExtensionItem.COLUMN_ID, new cInfo(FileExtensionItem.class, FileExtensionItem.DATASOURCE_TYPE));
 		c.put(SavePathItem.COLUMN_ID, new cInfo(SavePathItem.class, SavePathItem.DATASOURCE_TYPE));
 		c.put(TorrentPathItem.COLUMN_ID, new cInfo(TorrentPathItem.class, TorrentPathItem.DATASOURCE_TYPE));
 		c.put(CategoryItem.COLUMN_ID, new cInfo(CategoryItem.class, CategoryItem.DATASOURCE_TYPE));
@@ -208,10 +215,14 @@ public class TableColumnCreator
 		c.put(SwarmAverageSpeed.COLUMN_ID, new cInfo(SwarmAverageSpeed.class, SwarmAverageSpeed.DATASOURCE_TYPE));
 		c.put(SwarmAverageCompletion.COLUMN_ID, new cInfo(SwarmAverageCompletion.class, SwarmAverageCompletion.DATASOURCE_TYPE));
 		c.put(BadAvailTimeItem.COLUMN_ID, new cInfo(BadAvailTimeItem.class, BadAvailTimeItem.DATASOURCE_TYPE));
+		c.put(ColumnFileCount.COLUMN_ID, new cInfo(ColumnFileCount.class, ColumnFileCount.DATASOURCE_TYPE));
+		c.put(ColumnTorrentSpeed.COLUMN_ID, new cInfo(ColumnTorrentSpeed.class, ColumnTorrentSpeed.DATASOURCE_TYPE));
 
 		c.put(DateCompletedItem.COLUMN_ID, new cInfo(DateCompletedItem.class, DateCompletedItem.DATASOURCE_TYPE));
 		c.put(DateAddedItem.COLUMN_ID, new cInfo(DateAddedItem.class, DateAddedItem.DATASOURCE_TYPE));
-		
+		c.put(IPFilterItem.COLUMN_ID, new cInfo(IPFilterItem.class, IPFilterItem.DATASOURCE_TYPE));
+		c.put(TorrentCreateDateItem.COLUMN_ID, new cInfo(TorrentCreateDateItem.class, TorrentCreateDateItem.DATASOURCE_TYPE));
+
 		c.put(ColumnTC_NameInfo.COLUMN_ID, new cInfo(ColumnTC_NameInfo.class, tc));
 		c.put(ColumnTC_Sample.COLUMN_ID, new cInfo(ColumnTC_Sample.class, tc));
 		c.put(ColumnTC_ChosenColumn.COLUMN_ID, new cInfo(ColumnTC_ChosenColumn.class, tc));
diff --git a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnInfoImpl.java b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnInfoImpl.java
index ca366ba..575ec5c 100644
--- a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnInfoImpl.java
+++ b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnInfoImpl.java
@@ -32,7 +32,7 @@ public class TableColumnInfoImpl
 {
 	String[] categories;
 
-	byte proficiency;
+	byte proficiency = TableColumnInfo.PROFICIENCY_INTERMEDIATE;
 
 	private final TableColumnCore column;
 
diff --git a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java b/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java
deleted file mode 100644
index d9c7cc6..0000000
--- a/org/gudy/azureus2/ui/swt/views/table/utils/TableColumnManager.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * File    : TableColumnManager.java
-*
- * 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.table.utils;
-
-import java.util.*;
-
-import org.gudy.azureus2.core3.config.COConfigurationManager;
-import org.gudy.azureus2.core3.util.*;
-import org.gudy.azureus2.ui.swt.views.table.TableColumnCoreCreationListener;
-
-import com.aelitis.azureus.ui.common.table.TableColumnCore;
-import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl;
-
-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.*;
-
-
-/** Holds a list of column definitions (TableColumnCore) for 
- * all the tables in Azureus.
- *
- * Column definitions are added via 
- * PluginInterface.addColumn(TableColumn)
- * See Use javadoc section for more uses.
- *
- * @author Oliver (Original Code)
- * @author TuxPaper (Modifications to make generic & comments)
- */
-public class TableColumnManager {
-
-  private static final String CONFIG_FILE = "tables.config";
-	private static TableColumnManager instance;
-  private static AEMonitor 			class_mon 	= new AEMonitor( "TableColumnManager" );
-
-  /* Holds all the TableColumnCore objects.
-   * key   = TABLE_* type (see TableColumnCore)
-   * value = Map:
-   *           key = column name
-   *           value = TableColumnCore object
-   */
-  private Map<String,Map>	items;
-  private AEMonitor 		items_mon 	= new AEMonitor( "TableColumnManager:items" );
-  
-  /**
-   * Holds the order in which the columns are auto-hidden
-   * 
-   * key   = TABLE_* type
-   * value = List of TableColumn, indexed in the order they should be removed
-   */ 
-  private Map autoHideOrder = new LightHashMap();
-
-  /**
-   * key = table; value = map of columns
-   * 
-   * Do not access directly.  Use {@link #getTableConfigMap(String)}
-   * or {@link #saveTableConfigs()}
-   */
-	private Map mapTablesConfig;
-	private long lastTableConfigAccess;
-	private static Comparator orderComparator;
-	
-	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() {
-			public int compare(Object arg0, Object arg1) {				
-				if ((arg1 instanceof TableColumn) && (arg0 instanceof TableColumn)) {
-					int iPositionA = ((TableColumn) arg0).getPosition();
-					if (iPositionA < 0)
-						iPositionA = 0xFFFF + iPositionA;
-					int iPositionB = ((TableColumn) arg1).getPosition();
-					if (iPositionB < 0)
-						iPositionB = 0xFFFF + iPositionB;
-
-					return iPositionA - iPositionB;
-				}
-				return 0;
-			}
-		};
-	}
-
-  
-  private TableColumnManager() {
-   items = new HashMap<String,Map>();
-  }
-  
-  /** Retrieve the static TableColumnManager instance
-   * @return the static TableColumnManager instance
-   */
-  public static TableColumnManager getInstance() {
-  	try{
-  		class_mon.enter();
-  	
-  		if(instance == null)
-  			instance = new TableColumnManager();
-  		return instance;
-  	}finally{
-  		
-  		class_mon.exit();
-  	}
-  }
-  
-  /** Adds a column definition to the list
-   * @param item The column definition object
-   */
-  public void addColumns(TableColumnCore[] itemsToAdd) {
-		try {
-			items_mon.enter();
-			for (int i = 0; i < itemsToAdd.length; i++) {
-				TableColumnCore item = itemsToAdd[i];
-				if ( item.isRemoved()){
-					continue;
-				}
-				String name = item.getName();
-				String sTableID = item.getTableID();
-				Map mTypes = (Map) items.get(sTableID);
-				if (mTypes == null) {
-					// LinkedHashMap to preserve order
-					mTypes = new LinkedHashMap();
-					items.put(sTableID, mTypes);
-				}
-				if (!mTypes.containsKey(name)) {
-					mTypes.put(name, item);
-					Map mapColumnConfig = getTableConfigMap(sTableID);
-					((TableColumnCore) item).loadSettings(mapColumnConfig);
-				}
-				
-				if (!item.getColumnAdded()) {
-					item.setColumnAdded(true);
-				}
-			}
-		} catch (Exception e) {
-			System.out.println("Error while adding Table Column Extension");
-			Debug.printStackTrace(e);
-		} finally {
-			items_mon.exit();
-		}
-	}
-
-  /** Adds a column definition to the list
-   * @param item The column definition object
-   */
-  public void removeColumns(TableColumnCore[] itemsToRemove) {
-		try {
-			items_mon.enter();
-			for (int i = 0; i < itemsToRemove.length; i++) {
-				TableColumnCore item = itemsToRemove[i];
-				String name = item.getName();
-				String sTableID = item.getTableID();
-				Map mTypes = (Map) items.get(sTableID);
-				if (mTypes != null) {
-					if ( mTypes.remove(name) != null ){
-					}
-				}
-			}
-		} catch (Exception e) {
-			System.out.println("Error while adding Table Column Extension");
-			Debug.printStackTrace(e);
-		} finally {
-			items_mon.exit();
-		}
-	}
-  
-  /** Retrieves TableColumnCore objects of a particular type.
-   * @param sTableID TABLE_* constant.  See {@link TableColumn} for list 
-   * of constants
-   * @param forDataSourceType 
-   *
-   * @return Map of column definition objects matching the supplied criteria.
-   *         key = name
-   *         value = TableColumnCore object
-   */
-  public Map<String, TableColumnCore> getTableColumnsAsMap(
-			Class forDataSourceType, String sTableID) {
-    //System.out.println("getTableColumnsAsMap(" + sTableID + ")");
-    try{
-    	items_mon.enter();
-      Map<String, TableColumnCore> mReturn = new LinkedHashMap();
-    	Map<String, TableColumnCore> mTypes = getAllTableColumnCore(
-					forDataSourceType, sTableID);
-      if (mTypes != null) {
-        mReturn.putAll(mTypes);
-      }
-      //System.out.println("getTableColumnsAsMap(" + sTableID + ") returnsize: " + mReturn.size());
-      return mReturn;
-    }finally{
-    	
-    	items_mon.exit();
-    }
-  }
-  
-  public int getTableColumnCount(String sTableID) {
-    Map mTypes = (Map)items.get(sTableID);
-    if (mTypes == null) {
-    	return 0;
-    }
-    return mTypes.size();
-  }
-
-  
-  public TableColumnCore[] getAllTableColumnCoreAsArray(
-			Class forDataSourceType, String tableID)
-	{
-  	Map mTypes = getAllTableColumnCore(forDataSourceType, tableID);
-		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(
-			Class forDataSourceType, String tableID)
-	{
-		String[] dstColumnIDs = new String[0];
-		if (forDataSourceType != null) {
-  		List listDST = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
-  		if (listDST != null) {
-  			dstColumnIDs = (String[]) listDST.toArray(new String[0]);
-  		}
-  		if (forDataSourceType.equals(DownloadTypeComplete.class)
-  				|| forDataSourceType.equals(DownloadTypeIncomplete.class)) {
-  			listDST = (List) mapDataSourceTypeToColumnIDs.get(Download.class);
-  			if (listDST != null && listDST.size() > 0) {
-  				String[] ids1 = (String[]) listDST.toArray(new String[0]);
-  				String[] ids2 = dstColumnIDs;
-  				dstColumnIDs = new String[ids2.length + ids1.length];
-  				System.arraycopy(ids2, 0, dstColumnIDs, 0, ids2.length);
-  				System.arraycopy(ids1, 0, dstColumnIDs, ids2.length, ids1.length);
-  			}
-  		} else if (forDataSourceType.equals(Download.class)) {
-  			listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeComplete.class);
-  			if (listDST != null && listDST.size() > 0) {
-  				String[] ids = (String[]) listDST.toArray(new String[listDST.size()]);
-  				dstColumnIDs = appendLists(ids, dstColumnIDs);
-  			}
-  			listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeIncomplete.class);
-  			if (listDST != null && listDST.size() > 0) {
-  				String[] ids = (String[]) listDST.toArray(new String[listDST.size()]);
-  				dstColumnIDs = appendLists(ids, dstColumnIDs);
-  			}
-  		}
-		}
-
-		try {
-			items_mon.enter();
-
-			Map mTypes = (Map) items.get(tableID);
-			if (mTypes == null) {
-        mTypes = new LinkedHashMap();
-				items.put(tableID, mTypes);
-			}
-
-			for (int i = 0; i < dstColumnIDs.length; i++) {
-				String columnID = dstColumnIDs[i];
-				if (!mTypes.containsKey(columnID)) {
-					try {
-						TableColumnCreationListener l = mapColumnIDsToListener.get(forDataSourceType
-								+ "." + columnID);
-						TableColumnCore tc = null;
-						if (l instanceof TableColumnCoreCreationListener) {
-							tc = ((TableColumnCoreCreationListener) l).createTableColumnCore(
-									tableID, columnID);
-						}
-						if (tc == null) {
-							tc = new TableColumnImpl(tableID, columnID);
-						}
-
-						l.tableColumnCreated(tc);
-
-						addColumns(new TableColumnCore[] { tc });
-
-					} catch (Exception e) {
-						Debug.out(e);
-					}
-				}
-			}
-
-			return mTypes;
-		} finally {
-			items_mon.exit();
-		}
-	}
-  */
-
-  /**
-   * Will create columns for tableID if needed
-   */
-  private Map<String, TableColumnCore> getAllTableColumnCore(
-			Class forDataSourceType, String tableID) {
-		Map mTypes = null;
-		try {
-			items_mon.enter();
-
-			mTypes = (Map) items.get(tableID);
-			if (mTypes == null) {
-				mTypes = new LinkedHashMap();
-				items.put(tableID, mTypes);
-			}
-
-			if (forDataSourceType != null) {
-				List listDST = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
-				if (listDST != null) {
-					doAddCreate(mTypes, forDataSourceType, tableID, listDST);
-				}
-				if (forDataSourceType.equals(DownloadTypeComplete.class)
-						|| forDataSourceType.equals(DownloadTypeIncomplete.class)) {
-					listDST = (List) mapDataSourceTypeToColumnIDs.get(Download.class);
-					if (listDST != null && listDST.size() > 0) {
-						doAddCreate(mTypes, Download.class, tableID, listDST);
-					}
-				} else if (Download.class.equals(forDataSourceType)) {
-					listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeComplete.class);
-					if (listDST != null && listDST.size() > 0) {
-						doAddCreate(mTypes, DownloadTypeComplete.class, tableID, listDST);
-					}
-					listDST = (List) mapDataSourceTypeToColumnIDs.get(DownloadTypeIncomplete.class);
-					if (listDST != null && listDST.size() > 0) {
-						doAddCreate(mTypes, DownloadTypeIncomplete.class, tableID, listDST);
-					}
-				}
-			}
-		} finally {
-			items_mon.exit();
-		}
-
-		return mTypes;
-	}
-
-  /** 
-   * Helper for getAllTableColumnCore
-	 * @param types
-	 * @param listDST
-	 *
-	 * @since 4.0.0.5
-	 */
-	private void doAddCreate(Map mTypes, Class forDataSourceType, String tableID, List listDST) {
-		for (Iterator iter = listDST.iterator(); iter.hasNext();) {
-			String columnID = (String) iter.next();
-			if (!mTypes.containsKey(columnID)) {
-				try {
-					TableColumnCreationListener l = mapColumnIDsToListener.get(forDataSourceType
-							+ "." + columnID);
-					TableColumnCore tc = null;
-					if (l instanceof TableColumnCoreCreationListener) {
-						tc = ((TableColumnCoreCreationListener) l).createTableColumnCore(
-								forDataSourceType, tableID, columnID);
-					}
-					if (tc == null) {
-						tc = new TableColumnImpl(forDataSourceType, tableID, columnID);
-					}
-
-					if (l != null) {
-						l.tableColumnCreated(tc);
-					}
-
-					addColumns(new TableColumnCore[] {
-						tc
-					});
-
-				} catch (Exception e) {
-					Debug.out(e);
-				}
-			}
-		}
-	}
-
-		public String[]
-  	getTableIDs()
-  	{
-		try {
-			items_mon.enter();
-
-			Set<String> ids = items.keySet();
-			
-			return( ids.toArray( new String[ids.size()]));
-			
-		} finally {
-			items_mon.exit();
-		}
-	}
-  	
-  public String[] appendLists(String[] list1, String[] list2) {
-  	int size = list1.length + list2.length;
-  	String[] list = new String[size];
-  	System.arraycopy(list1, 0, list, 0, list1.length);
-  	System.arraycopy(list2, 0, list, list1.length, list2.length);
-  	return list;
-  }
-  
-  public TableColumnCore getTableColumnCore(String sTableID,
-                                            String sColumnName) {
-    Map mTypes = (Map)items.get(sTableID);
-    if (mTypes == null)
-      return null;
-    return (TableColumnCore)mTypes.get(sColumnName);
-  }
-  
-  public void ensureIntegrety(String sTableID) {
-    Map mTypes = (Map)items.get(sTableID);
-    if (mTypes == null)
-      return;
-
-    TableColumnCore[] tableColumns = 
-      (TableColumnCore[])mTypes.values().toArray(new TableColumnCore[mTypes.values().size()]);
-
-    Arrays.sort(tableColumns, getTableColumnOrderComparator());
-
-    int iPos = 0;
-    for (int i = 0; i < tableColumns.length; i++) {
-      int iCurPos = tableColumns[i].getPosition();
-      if (iCurPos == TableColumnCore.POSITION_INVISIBLE) {
-      	tableColumns[i].setVisible(false);
-      } else {
-        tableColumns[i].setPositionNoShift(iPos++);
-      }
-    }
-  }
-  
-  public String getDefaultSortColumnName(String tableID) {
-  	Map mapTableConfig = getTableConfigMap(tableID);
-  	Object object = mapTableConfig.get("SortColumn");
-  	if( object instanceof byte[])
-  		object =  new String((byte[])object);
-  	
-  	if (object instanceof String) {
-			return (String) object;
-		}
-
-		String s = COConfigurationManager.getStringParameter(tableID + ".sortColumn");
-		if (s != null) {
-			COConfigurationManager.removeParameter(tableID + ".sortColumn");
-			COConfigurationManager.removeParameter(tableID + ".sortAsc");
-		}
-		return s;
-  }
-  
-  public void setDefaultSortColumnName(String tableID, String columnName) {
-  	Map mapTableConfig = getTableConfigMap(tableID);
-  	mapTableConfig.put("SortColumn", columnName);
-  	saveTableConfigs();
-  }
-
-  private void saveTableConfigs() {
-		if (mapTablesConfig != null) {
-			FileUtil.writeResilientConfigFile(CONFIG_FILE, mapTablesConfig);
-		}
-	}
-
-	/** Saves all the user configurable Table Column settings at once, complete
-   * with a COConfigurationManager.save().
-   *
-   * @param sTableID Table to save settings for
-   */
-  public void saveTableColumns(Class forDataSourceType, String sTableID) {
-  	try {
-  		Map mapTableConfig = getTableConfigMap(sTableID);
-      TableColumnCore[] tcs = getAllTableColumnCoreAsArray(forDataSourceType,
-					sTableID);
-      for (int i = 0; i < tcs.length; i++) {
-        if (tcs[i] != null)
-          tcs[i].saveSettings(mapTableConfig);
-      }
-      saveTableConfigs();
-  	} catch (Exception e) {
-  		Debug.out(e);
-  	}
-  }
-  
-  public boolean loadTableColumnSettings(Class forDataSourceType, String sTableID) {
-  	try {
-  		Map mapTableConfig = getTableConfigMap(sTableID);
-  		int size = mapTableConfig.size();
-  		if (size == 0 || (size == 1 && mapTableConfig.containsKey("SortColumn"))) {
-  			return false;
-  		}
-      TableColumnCore[] tcs = getAllTableColumnCoreAsArray(forDataSourceType,
-					sTableID);
-      for (int i = 0; i < tcs.length; i++) {
-        if (tcs[i] != null)
-          tcs[i].loadSettings(mapTableConfig);
-      }
-  	} catch (Exception e) {
-  		Debug.out(e);
-  	}
-  	return true;
-  }
-  
-  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( TableColumnManager.this ){
-									
-									long	now = SystemTime.getMonotonousTime();
-									
-									if ( now - lastTableConfigAccess > 25000 ){
-									
-										mapTablesConfig = null;
-										
-									}else{
-										SimpleTimer.addEvent(
-											"DisposeTbaleConfigMap",
-											SystemTime.getOffsetTime(30000), 
-											this );
-									}
-								}
-							}
-						});
-			}
-
-			Map mapTableConfig = (Map) mapTablesConfig.get("Table." + sTableID);
-			if (mapTableConfig == null) {
-				mapTableConfig = new HashMap();
-				mapTablesConfig.put("Table." + sTableID, mapTableConfig);
-			}
-
-			return mapTableConfig;
-		}
-	}
-  
-  public void setAutoHideOrder(String sTableID, String[] autoHideOrderColumnIDs) {
-  	ArrayList autoHideOrderList = new ArrayList(autoHideOrderColumnIDs.length);
-  	for (int i = 0; i < autoHideOrderColumnIDs.length; i++) {
-			String sColumnID = autoHideOrderColumnIDs[i];
-			TableColumnCore column = getTableColumnCore(sTableID, sColumnID);
-			if (column != null) {
-				autoHideOrderList.add(column);
-			}
-		}
-  	
-  	autoHideOrder.put(sTableID, autoHideOrderList);
-  }
-  
-  public List getAutoHideOrder(String sTableID) {
-		List list = (List) autoHideOrder.get(sTableID);
-		if (list == null) {
-			return Collections.EMPTY_LIST;
-		}
-		return list;
-	}
-
-	/**
-	 * @param writer
-	 */
-	public void generateDiagnostics(IndentWriter writer) {
-    try{
-     	items_mon.enter();
-     	
-     	writer.println("TableColumns");
-
-     	for (Iterator iter = items.keySet().iterator(); iter.hasNext();) {
-     		String sTableID = (String)iter.next();
-        Map mTypes = (Map)items.get(sTableID);
-
-        writer.indent();
-     		writer.println(sTableID + ": " + mTypes.size() + " columns:");
-     		
-     		writer.indent();
-       	for (Iterator iter2 = mTypes.values().iterator(); iter2.hasNext();) {
-       		TableColumnCore tc = (TableColumnCore)iter2.next();
-       		tc.generateDiagnostics(writer);
-       	}
-        writer.exdent();
-
-        writer.exdent();
-			}
-    } catch (Exception e) {
-    	e.printStackTrace();
-    } finally {
-    	items_mon.exit();
-    }
-	}
-	
-	public static Comparator getTableColumnOrderComparator()
-	{
-		return orderComparator;
-	}
-
-	/**
-	 * @param forDataSourceType
-	 * @param columnID
-	 * @param listener
-	 *
-	 * @since 3.1.1.1
-	 */
-	public void registerColumn(Class forDataSourceType, String columnID,
-			TableColumnCreationListener listener) {
-		if (listener != null) {
-			mapColumnIDsToListener.put(forDataSourceType + "." + columnID, listener);
-		}
-		try {
-			items_mon.enter();
-
-  		List list = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
-  		if (list == null) {
-  			list = new ArrayList(1);
-  			mapDataSourceTypeToColumnIDs.put(forDataSourceType, list);
-  		}
-  		if (!list.contains(columnID)) {
-  			list.add(columnID);
-  		}
-		} finally {
-			items_mon.exit();
-		}
-	}
-	
-	public void unregisterColumn(Class forDataSourceType, String columnID,
-			TableColumnCreationListener listener) {
-		try {
-			items_mon.enter();
-
-			mapColumnIDsToListener.remove(forDataSourceType + "." + columnID);
-			List list = (List) mapDataSourceTypeToColumnIDs.get(forDataSourceType);
-			if (list != null) {
-				list.remove(columnID);
-			}
-		} finally {
-			items_mon.exit();
-		}
-	}
-
-	public TableColumnInfo getColumnInfo(Class forDataSourceType, String forTableID,
-			String columnID) {
-
-		TableColumnCore column = getTableColumnCore(forTableID, columnID);
-		
-		TableColumnInfoImpl columnInfo = new TableColumnInfoImpl(column);
-		List<TableColumnExtraInfoListener> listeners = column.getColumnExtraInfoListeners();
-		for (TableColumnExtraInfoListener l : listeners) {
-			l.fillTableColumnInfo(columnInfo);
-		}
-		if (columnInfo.getCategories() == null && !(column instanceof CoreTableColumn)) {
-			columnInfo.addCategories(new String[] { "plugin" });
-		}
-
-		return columnInfo;
-	}
-}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java b/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
index 5ffc327..70c8b06 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/ColumnDateSizer.java
@@ -26,10 +26,15 @@ import org.eclipse.swt.graphics.*;
 import org.eclipse.swt.widgets.Display;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
+import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.util.AERunnable;
 import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.views.ViewUtils;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import org.gudy.azureus2.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemFillListener;
 import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
@@ -55,8 +60,12 @@ public abstract class ColumnDateSizer
 
 	private boolean multiline = true;
 
+	private String tableFormatOverride = "";
+
 	private static Font fontBold;
 
+	private ViewUtils.CustomDateFormat cdf;
+	
 	/**
 	 * @param name
 	 * @param tableID
@@ -64,7 +73,14 @@ public abstract class ColumnDateSizer
 	public ColumnDateSizer(Class forDataSrouceType, String columnID, int width, String tableID) {
 		super(forDataSrouceType, columnID, ALIGN_TRAIL, width, tableID);
 
-		TableContextMenuItem menuShowTime = addContextMenuItem("TableColumn.menu.date_added.time");
+		final TableContextMenuItem menuShowTime = addContextMenuItem(
+				"TableColumn.menu.date_added.time", MENU_STYLE_HEADER);
+		menuShowTime.setStyle(TableContextMenuItem.STYLE_CHECK);
+		menuShowTime.addFillListener(new MenuItemFillListener() {
+			public void menuWillBeShown(MenuItem menu, Object data) {
+				menu.setData(showTime);
+			}
+		});
 		menuShowTime.addListener(new MenuItemListener() {
 			public void selected(MenuItem menu, Object target) {
 				showTime = !showTime;
@@ -78,6 +94,30 @@ public abstract class ColumnDateSizer
 				}
 			}
 		});
+
+		COConfigurationManager.addAndFireParameterListener(
+				"Table.column.dateformat", new ParameterListener() {
+					public void parameterChanged(String parameterName) {
+						tableFormatOverride = COConfigurationManager.getStringParameter(
+								"Table.column.dateformat", "");
+						if (tableFormatOverride == null) {
+							tableFormatOverride = "";
+						}
+						curFormat = -1;
+						if (tableFormatOverride.length() == 0) {
+							recalcWidth(new Date());
+							if (curFormat < 0) {
+								curFormat = TimeFormatter.DATEFORMATS_DESC.length - 1;
+							}
+							menuShowTime.setVisible(true);
+						} else {
+							invalidateCells();
+							menuShowTime.setVisible(false);
+						}
+					}
+		});
+		
+		cdf = ViewUtils.addCustomDateFormat( this );
 	}
 	
 	// @see com.aelitis.azureus.ui.common.table.impl.TableColumnImpl#postConfigLoad()
@@ -90,6 +130,10 @@ public abstract class ColumnDateSizer
 	    int userMode = COConfigurationManager.getIntParameter("User Mode");
 			showTime = userMode > 1;
 		}
+		
+		cdf.update();
+		
+		super.postConfigLoad();
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
@@ -98,7 +142,7 @@ public abstract class ColumnDateSizer
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener#refresh(org.gudy.azureus2.plugins.ui.tables.TableCell)
-	public void refresh(TableCell cell, long timestamp) {
+	public void refresh(final TableCell cell, final long timestamp) {
 		if (!cell.setSortValue(timestamp) && cell.isValid()) {
 			return;
 		}
@@ -106,33 +150,60 @@ public abstract class ColumnDateSizer
 		if (timestamp <= 0) {
 			return;
 		}
-
-		Date date = new Date(timestamp);
-
-		if (curFormat >= 0) {
-			if (multiline && cell.getHeight() < 20) {
-				multiline = false;
+		
+		SimpleDateFormat format = cdf.getDateFormat();
+		
+		if ( format != null ){
+			Date date = new Date(timestamp);
+			try {
+				cell.setText(format.format(date));
+  			return;
+			} catch (Exception e) {
+
+			}	
+		}
+		if (tableFormatOverride.length() > 0) {
+			Date date = new Date(timestamp);
+			try {
+				SimpleDateFormat temp = new SimpleDateFormat(tableFormatOverride);
+				cell.setText(temp.format(date));
+  			return;
+			} catch (Exception e) {
+				// probably illegalargumentexception
 			}
-			String suffix = showTime && !multiline ? " hh:mm a" : "";
+		}
 
-			int newWidth = calcWidth(date, TimeFormatter.DATEFORMATS_DESC[curFormat]
-					+ suffix);
+		Utils.execSWTThread(new AERunnable() {
+			
+			public void runSupport() {
+				Date date = new Date(timestamp);
+
+				if (curFormat >= 0) {
+					if (multiline && cell.getHeight() < 20) {
+						multiline = false;
+					}
+					String suffix = showTime && !multiline ? " hh:mm a" : "";
+
+					int newWidth = calcWidth(date, TimeFormatter.DATEFORMATS_DESC[curFormat]
+							+ suffix);
+
+					//SimpleDateFormat temp2 = new SimpleDateFormat(TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix + (showTime && multiline ? "\nh:mm a" : ""));
+					//System.out.println(curFormat + ":newWidth=" +  newWidth + ":max=" + maxWidthUsed[curFormat] + ":cell=" + cell.getWidth() + "::" + temp2.format(date));
+					if (newWidth > cell.getWidth() - PADDING) {
+						if (newWidth > maxWidthUsed[curFormat]) {
+							maxWidthUsed[curFormat] = newWidth;
+							maxWidthDate[curFormat] = date;
+						}
+						recalcWidth(date);
+					}
 
-			//SimpleDateFormat temp2 = new SimpleDateFormat(TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix + (showTime && multiline ? "\nh:mm a" : ""));
-			//System.out.println(curFormat + ":newWidth=" +  newWidth + ":max=" + maxWidthUsed[curFormat] + ":cell=" + cell.getWidth() + "::" + temp2.format(date));
-			if (newWidth > cell.getWidth() - PADDING) {
-				if (newWidth > maxWidthUsed[curFormat]) {
-					maxWidthUsed[curFormat] = newWidth;
-					maxWidthDate[curFormat] = date;
+					String s = TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix;
+					SimpleDateFormat temp = new SimpleDateFormat(s
+							+ (showTime && multiline ? "\nh:mm a" : ""));
+					cell.setText(temp.format(date));
 				}
-				recalcWidth(date);
 			}
-
-			String s = TimeFormatter.DATEFORMATS_DESC[curFormat] + suffix;
-			SimpleDateFormat temp = new SimpleDateFormat(s
-					+ (showTime && multiline ? "\nh:mm a" : ""));
-			cell.setText(temp.format(date));
-		}
+		});
 	}
 
 	// @see com.aelitis.azureus.ui.common.table.impl.TableColumnImpl#setWidth(int)
@@ -143,7 +214,7 @@ public abstract class ColumnDateSizer
 		if (oldWidth == width) {
 			return;
 		}
-		if (maxWidthDate != null) {
+		if (maxWidthDate != null && curFormat >= 0) {
 			if (maxWidthDate[curFormat] == null) {
 				maxWidthDate[curFormat] = new Date();
 			}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/DoneItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/DoneItem.java
index 35fc278..b5856fd 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/DoneItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/DoneItem.java
@@ -47,6 +47,7 @@ public class DoneItem
 			CAT_BYTES,
 			CAT_PROGRESS,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void refresh(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileCRC32Item.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileCRC32Item.java
new file mode 100644
index 0000000..287199a
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileCRC32Item.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.gudy.azureus2.ui.swt.views.tableitems.files;
+
+public class 
+FileCRC32Item
+	extends FileHashItemBase 
+{	
+	public 
+	FileCRC32Item() 
+	{	
+		super( HT_CRC32, 80 );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileExtensionItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileExtensionItem.java
index 4a38bc5..9c580bb 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileExtensionItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileExtensionItem.java
@@ -23,6 +23,8 @@ package org.gudy.azureus2.ui.swt.views.tableitems.files;
 import org.gudy.azureus2.plugins.ui.tables.*;
 
 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.ui.swt.views.table.utils.CoreTableColumn;
 
 public class FileExtensionItem
@@ -40,6 +42,7 @@ public class FileExtensionItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
 	}
 
   public void refresh(TableCell cell) {
@@ -49,9 +52,20 @@ public class FileExtensionItem
   
   private static String determineFileExt(DiskManagerFileInfo fileInfo) {
 	String name = (fileInfo == null) ? "" : fileInfo.getFile(true).getName();
+	
+	DownloadManager dm = fileInfo==null?null:fileInfo.getDownloadManager();
+
+	String incomp_suffix = dm==null?null:dm.getDownloadState().getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
+	
+	if ( incomp_suffix != null && name.endsWith( incomp_suffix )){
+		
+		name = name.substring( 0, name.length() - incomp_suffix.length());
+	}
+	
 	int dot_position = name.lastIndexOf(".");
 	if (dot_position == -1) {return "";}
+	
+
 	return name.substring(dot_position+1);
   }
-	
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileHashItemBase.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileHashItemBase.java
new file mode 100644
index 0000000..cd00b01
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileHashItemBase.java
@@ -0,0 +1,433 @@
+/*
+ * 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 org.gudy.azureus2.ui.swt.views.tableitems.files;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.MessageDigest;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.CRC32;
+
+import org.eclipse.swt.SWT;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+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;
+import org.gudy.azureus2.core3.util.AERunnable;
+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.plugins.ui.menus.MenuItem;
+import org.gudy.azureus2.plugins.ui.menus.MenuItemListener;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+
+
+public class 
+FileHashItemBase
+	extends CoreTableColumn 
+	implements TableCellRefreshListener, TableCellMouseListener
+{	
+	protected static final String	HT_CRC32	= "crc32";
+	protected static final String	HT_MD5		= "md5";
+	
+	final String				hash_type;
+	final TableContextMenuItem 	menuItem;
+
+	public 
+	FileHashItemBase(
+		String		_hash_type,
+		int			width )
+	{	
+		super( _hash_type, ALIGN_LEAD, POSITION_INVISIBLE, width, TableManager.TABLE_TORRENT_FILES);
+
+		hash_type = _hash_type;
+		
+		setType( TableColumn.TYPE_TEXT );
+
+		setRefreshInterval( INTERVAL_LIVE );
+		 
+		menuItem = addContextMenuItem( "FilesView." + hash_type + ".calculate" );
+
+		menuItem.setStyle( MenuItem.STYLE_PUSH );
+
+		menuItem.addMultiListener(
+			new MenuItemListener()
+			{
+				public void 
+				selected(
+					MenuItem menu, Object target)
+				{
+					Object[]	files = (Object[])target;
+					
+					for ( Object _file: files ){
+						
+						DiskManagerFileInfo file = (DiskManagerFileInfo)_file;
+						
+						updateHash( hash_type, file );
+					}
+				}
+			});
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info) 
+	{
+		info.addCategories(new String[] {
+				CAT_CONTENT,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_ADVANCED );
+	}
+
+	public void 
+	cellMouseTrigger(
+		TableCellMouseEvent event) 
+	{
+		DiskManagerFileInfo file = (DiskManagerFileInfo) event.cell.getDataSource();
+		
+		if ( file == null ){
+			
+			return;
+		}
+		
+		TableCellCore core_cell = (TableCellCore)event.cell;
+		
+		if ( !event.cell.getText().startsWith( "<" )){
+			
+			core_cell.setCursorID( SWT.CURSOR_ARROW );
+			core_cell.setToolTip( null );
+			
+			return;
+		}
+
+		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER){
+						
+			core_cell.setCursorID( SWT.CURSOR_HAND );
+			core_cell.setToolTip( MessageText.getString( "FilesView.click.info" ) );
+			
+		}else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEEXIT ){
+			
+			core_cell.setCursorID( SWT.CURSOR_ARROW );
+			core_cell.setToolTip( null );
+		}
+		
+		if ( event.eventType != TableCellMouseEvent.EVENT_MOUSEUP ){
+			
+			return;
+		}
+
+			// Only activate on LMB.
+		
+		if ( event.button != 1 ){
+		
+			return;
+		}
+		
+		event.skipCoreFunctionality = true;
+
+		updateHash( hash_type, file );
+	}
+	
+	public void 
+	refresh(
+		TableCell cell) 
+	{
+		DiskManagerFileInfo file = (DiskManagerFileInfo)cell.getDataSource();
+		
+		if ( file == null ){
+			
+			return;
+		}
+		
+		cell.setText( getHash( hash_type, file ));
+	}
+	
+	
+	private static AsyncDispatcher dispatcher = new AsyncDispatcher();
+	
+	private static Map<DiskManagerFileInfo,Set<String>>	pending = new HashMap<DiskManagerFileInfo,Set<String>>();
+	
+	private static volatile DiskManagerFileInfo	active;
+	private static volatile String				active_hash;
+	private static volatile int					active_percent;
+	
+	private static boolean
+	isFileReady(
+		DiskManagerFileInfo		file )
+	{
+		if ( 	file == null || 
+				file.getLength() != file.getDownloaded() || 
+				file.getAccessMode() != DiskManagerFileInfo.READ ){
+			
+			return( false );
+		}
+		
+		File f = file.getFile( true );
+		
+		if ( f.length() != file.getLength() || !f.canRead()){
+			
+			return( false );
+		}
+		
+		return( true );
+	}
+	
+	private static void
+	updateHash(
+		final String				hash_type,
+		final DiskManagerFileInfo	file )
+	{
+		if ( !isFileReady( file )){
+			
+			return;
+		}
+		
+		synchronized( pending ){
+			
+			Set<String> hashes = pending.get( file );
+			
+			if ( hashes != null && hashes.contains( hash_type )){
+				
+				return;
+			}
+			
+			if ( hashes == null ){
+				
+				hashes = new HashSet<String>();
+				
+				pending.put( file, hashes );
+			}
+			
+			hashes.add( hash_type );
+		}
+		
+		dispatcher.dispatch(
+			new AERunnable()
+			{
+				public void 
+				runSupport() 
+				{
+					try{
+						DownloadManager dm = file.getDownloadManager();
+						
+						if ( dm == null ){
+							
+							return;
+						}
+						
+						if ( !isFileReady( file )){
+							
+							return;
+						}
+						
+						active_percent	= 0;
+						active_hash		= hash_type;
+						active 			= file;
+
+						File f = file.getFile( true );
+						
+						CRC32 			crc32 	= null;
+						MessageDigest	md5		= null;
+						
+						if ( hash_type == HT_CRC32 ){
+							
+							crc32 = new CRC32();
+							
+						}else{
+							
+							md5 = MessageDigest.getInstance( "md5" );
+						}
+						
+						FileInputStream fis = new FileInputStream( f );
+						
+						long	size 	= f.length();
+						long	done	= 0;
+						
+						if ( size == 0 ){
+							
+							size = 1;
+						}
+						
+						try{
+							byte[]	buffer = new byte[512*1024];
+							
+							while( true ){
+								
+								int	len = fis.read( buffer );
+								
+								if ( len <= 0 ){
+									
+									break;
+								}
+								
+								if ( crc32 != null ){
+									
+									crc32.update( buffer, 0, len );
+								}
+								
+								if ( md5 != null ){
+									
+									md5.update( buffer, 0, len );
+								}
+								
+								done += len;
+								
+								active_percent = (int)(( 1000*done) / size );
+							}
+							
+							byte[]		hash;
+							
+							if ( crc32 != null ){
+								
+								long	val = crc32.getValue();
+							
+								hash = ByteFormatter.intToByteArray( val );
+								
+							}else{
+								
+								hash = md5.digest();
+							}
+							
+							Map other_hashes = dm.getDownloadState().getMapAttribute( DownloadManagerState.AT_FILE_OTHER_HASHES );
+							
+							if ( other_hashes == null ){
+								
+								other_hashes = new HashMap();
+								
+							}else{
+								
+								other_hashes = BEncoder.cloneMap( other_hashes );
+							}
+							
+							Map file_hashes = (Map)other_hashes.get( String.valueOf( file.getIndex()));
+														
+							if ( file_hashes == null ){
+								
+								file_hashes = new HashMap();
+								
+								other_hashes.put( String.valueOf( file.getIndex()), file_hashes );
+							}
+							
+							file_hashes.put( hash_type, hash );
+							
+							dm.getDownloadState().setMapAttribute( DownloadManagerState.AT_FILE_OTHER_HASHES, other_hashes );
+							
+						}finally{
+							
+							fis.close();
+						}
+					}catch( Throwable e ){
+						
+						Debug.out( e );
+						
+					}finally{
+					
+						synchronized( pending ){
+							
+							Set<String> hashes = pending.get( file );
+
+							hashes.remove( hash_type );
+							
+							if ( hashes.size() == 0 ){
+								
+								pending.remove( file );
+							}
+							
+							active = null;
+						}
+					}
+				}
+			});
+	}
+	
+	private static String
+	getHash(
+		String					hash_type,
+		DiskManagerFileInfo		file )
+	{
+		if ( file == null ){
+			
+			return( "" );	
+		}
+		
+		DownloadManager dm = file.getDownloadManager();
+		
+		if ( dm == null ){
+			
+			return( "" );
+		}
+		
+		synchronized( pending ){
+			
+			Set<String> hashes = pending.get( file );
+			
+			if ( hashes != null && hashes.contains( hash_type )){
+		
+				if ( active == file && active_hash == hash_type ){
+					
+					return( DisplayFormatters.formatPercentFromThousands( active_percent ));
+					
+				}else{
+					
+					return( "..." );
+				}
+			}
+		}
+		
+		Map other_hashes = dm.getDownloadState().getMapAttribute( DownloadManagerState.AT_FILE_OTHER_HASHES );
+		
+		if ( other_hashes != null ){
+			
+			Map file_hashes = (Map)other_hashes.get( String.valueOf( file.getIndex()));
+			
+			if ( file_hashes != null ){
+				
+				byte[] hash = (byte[])file_hashes.get( hash_type );
+				
+				if ( hash != null ){
+					
+					return( ByteFormatter.encodeString( hash ).toLowerCase());
+				}
+			}
+		}
+		
+		if ( !isFileReady( file )){
+			
+			return( "" );
+		}
+
+		return( "<" + MessageText.getString( "FilesView.click" ) + ">" );
+	}
+	
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileIndexItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileIndexItem.java
new file mode 100644
index 0000000..ad61bc5
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileIndexItem.java
@@ -0,0 +1,52 @@
+/*
+ * 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.tableitems.files;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+
+
+public class FileIndexItem
+       extends CoreTableColumn 
+       implements TableCellRefreshListener
+{
+  
+  
+  /** Default Constructor */
+  public FileIndexItem() {
+    super("torrentfileindex", ALIGN_TRAIL, POSITION_INVISIBLE, 40, TableManager.TABLE_TORRENT_FILES);
+  }
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONTENT,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
+  public void refresh(TableCell cell) {
+    DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)cell.getDataSource();
+    cell.setText( fileInfo==null?"":String.valueOf(fileInfo.getIndex()));
+  }
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/FileMD5Item.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileMD5Item.java
new file mode 100644
index 0000000..399f366
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FileMD5Item.java
@@ -0,0 +1,36 @@
+/*
+ * 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 org.gudy.azureus2.ui.swt.views.tableitems.files;
+
+public class 
+FileMD5Item
+	extends FileHashItemBase 
+{	
+	public 
+	FileMD5Item() 
+	{	
+		super( HT_MD5, 220 );
+	}
+}
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 8eaab21..3f126d3 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/FirstPieceItem.java
@@ -44,6 +44,7 @@ public class FirstPieceItem
 		info.addCategories(new String[] {
 			CAT_PROTOCOL,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_ADVANCED);
 	}
 
   public void refresh(TableCell cell) {
@@ -68,6 +69,6 @@ public class FirstPieceItem
     
 		// < 0 -> unknown skeleton value 
 	
-    cell.setText( sort_value<0?"":(""+fileInfo.getFirstPieceNumber()));
+    cell.setText( sort_value<0 || fileInfo == null?"":(""+fileInfo.getFirstPieceNumber()));
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/ModeItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/ModeItem.java
index 6cedd33..c369e29 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/ModeItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/ModeItem.java
@@ -46,6 +46,7 @@ public class ModeItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
 	}
 
   public void refresh(TableCell cell) {
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 6b33b67..29ad77b 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/NameItem.java
@@ -96,6 +96,7 @@ public class NameItem extends CoreTableColumn implements
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 	
 	public void postConfigLoad() {
@@ -112,25 +113,54 @@ public class NameItem extends CoreTableColumn implements
 	
 	public void refresh(TableCell cell, boolean sortOnlyRefresh)
 	{
-		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) cell.getDataSource();
+		final DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) cell.getDataSource();
 		String name = (fileInfo == null) ? "" : fileInfo.getFile(true).getName();
 		if (name == null)
 			name = "";
 		//setText returns true only if the text is updated
 		if (cell.setText(name) || !cell.isValid()) {
 			if (bShowIcon && !sortOnlyRefresh) {
-				Image icon;
+				Image icon = null;
+				
+				final TableCellSWT _cell = (TableCellSWT)cell;
+				
 				if (fileInfo == null) {
 					icon = null;
 				} else {
+					
 					// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
-					icon = ImageRepository.getPathIcon(fileInfo.getFile(true).getPath(),
-							false, false);
+					
+					if ( Utils.isSWTThread()){
+					
+						icon = ImageRepository.getPathIcon(fileInfo.getFile(true).getPath(),
+								false, false);
+					}else{	
+							// happens rarely (seen of filtering of file-view rows
+							// when a new row is added )
+												
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									Image icon = ImageRepository.getPathIcon(fileInfo.getFile(true).getPath(),
+											false, false);
+									
+									_cell.setIcon(icon);
+									
+									_cell.redraw();
+								}
+							});
+					}
 				}
 
 				// cheat for core, since we really know it's a TabeCellImpl and want to use
 				// those special functions not available to Plugins
-				((TableCellSWT) cell).setIcon(icon);
+				
+				if ( icon != null ){
+					_cell.setIcon(icon);
+				}
 			}
 		}
 	}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/PathItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/PathItem.java
index 887cfee..8dc2ef2 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/PathItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/PathItem.java
@@ -49,6 +49,7 @@ public class PathItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void refresh(TableCell cell) {
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 e19eb21..5123252 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/PercentItem.java
@@ -17,7 +17,7 @@
  * 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.tableitems.files;
 
 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
@@ -32,50 +32,60 @@ import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
  * @since 2.0.8.5
  */
 public class PercentItem
-       extends CoreTableColumn 
-       implements TableCellRefreshListener
+	extends CoreTableColumn
+	implements TableCellRefreshListener
 {
-  /** Default Constructor */
-  public PercentItem() {
-    super("%", ALIGN_TRAIL, POSITION_LAST, 60, TableManager.TABLE_TORRENT_FILES);
-    setRefreshInterval(INTERVAL_LIVE);
-    setMinWidthAuto(true);
-  }
+	/** Default Constructor */
+	public PercentItem() {
+		super("%", ALIGN_TRAIL, POSITION_LAST, 60, TableManager.TABLE_TORRENT_FILES);
+		setRefreshInterval(INTERVAL_LIVE);
+		setMinWidthAuto(true);
+	}
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] {
 			CAT_PROGRESS,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
-  public void refresh(TableCell cell) {
-	  
-    DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)cell.getDataSource();
-	
-    long percent = 0;
-	
-    if (fileInfo != null ){
-    	long bytesDownloaded = fileInfo.getDownloaded();
-		
-		if ( bytesDownloaded < 0 ){
-			
+	public void refresh(TableCell cell) {
+
+		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) cell.getDataSource();
+
+		long percent = 0;
+
+		if (fileInfo != null) {
+			long bytesDownloaded = fileInfo.getDownloaded();
+
+			if (bytesDownloaded < 0) {
+
+				percent = -1; // unknown skeleton value
+
+			} else {
+				long length = fileInfo.getLength();
+
+				if (length != 0) {
+
+					percent = (1000 * bytesDownloaded) / length;
+
+				} else {
+
+					percent = 1000;
+				}
+			}
+
+		} else {
+
 			percent = -1; // unknown skeleton value
-			
-		}else if ( fileInfo.getLength() != 0 ){
+		}
+
+		if (!cell.setSortValue(percent) && cell.isValid()) {
 
-			percent = (1000 * bytesDownloaded) / fileInfo.getLength();
+			return;
 		}
-	  
-    }else{
-		
-		percent = -1;	// unknown skeleton value
-    }
-	
-    if( !cell.setSortValue( percent ) && cell.isValid() ) {
-		
-      return;
-    }
-    
-    cell.setText( percent < 0?"":DisplayFormatters.formatPercentFromThousands((int)percent));
-  }
+
+		cell.setText(percent < 0 ? ""
+				: DisplayFormatters.formatPercentFromThousands((int) percent));
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/PieceCountItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/PieceCountItem.java
index 3488d9c..486feaa 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/PieceCountItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/PieceCountItem.java
@@ -44,6 +44,7 @@ public class PieceCountItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
 	}
 
   public void refresh(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/PriorityItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/PriorityItem.java
index afc1bfb..14083e7 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/PriorityItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/PriorityItem.java
@@ -45,6 +45,7 @@ public class PriorityItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void refresh(TableCell cell) {
@@ -55,7 +56,8 @@ public class PriorityItem
 			tmp = "";
 		else
 		{
-			if(fileInfo.getStorageType() == DiskManagerFileInfo.ST_COMPACT && fileInfo.isSkipped())
+			int	st = fileInfo.getStorageType();
+			if((st == DiskManagerFileInfo.ST_COMPACT || st == DiskManagerFileInfo.ST_REORDER_COMPACT ) && fileInfo.isSkipped())
 			{
 				tmp = MessageText.getString("FileItem.delete");
 				sortval = 1;				
@@ -63,9 +65,28 @@ public class PriorityItem
 			{
 				tmp = MessageText.getString("FileItem.donotdownload");
 				sortval = 2;
-			} else if (fileInfo.isPriority()) {
+			} else if (fileInfo.getPriority() > 0 ) {
+				
+				int pri = fileInfo.getPriority();
 				tmp = MessageText.getString("FileItem.high");
 				sortval = 4;
+				
+				if ( pri > 1 ){
+					tmp += " (" + pri + ")";
+					
+					sortval += pri;
+				}
+			} else if (fileInfo.getPriority() < 0 ) {
+				
+				int pri = fileInfo.getPriority();
+				tmp = MessageText.getString("FileItem.low");
+				sortval = 4;
+				
+				if ( pri < -1 ){
+					tmp += " (" + pri + ")";
+					
+					sortval += pri;
+				}
 			} else {
 				tmp = MessageText.getString("FileItem.normal");
 				sortval = 3;
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/ProgressGraphItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/ProgressGraphItem.java
index e411d2e..b7bb374 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/ProgressGraphItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/ProgressGraphItem.java
@@ -60,6 +60,7 @@ public class ProgressGraphItem extends CoreTableColumn implements TableCellAdded
 		info.addCategories(new String[] {
 			CAT_PROGRESS,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public void cellAdded(TableCell cell) {
@@ -121,7 +122,7 @@ public class ProgressGraphItem extends CoreTableColumn implements TableCellAdded
 			if (x1 < 10 || y1 < 3)
 				return;
 			
-			final DiskManager manager = fileInfo.getDiskManager();
+			final DiskManager manager = fileInfo == null ? null : fileInfo.getDiskManager();
 			// we want to run through the image part once one the transition from with a disk manager (running)
 			// to without a disk manager (stopped) in order to clear the pieces view
 			boolean running = manager != null;
@@ -146,11 +147,16 @@ public class ProgressGraphItem extends CoreTableColumn implements TableCellAdded
 			if (piecesImage != null && !piecesImage.isDisposed())
 				piecesImage.dispose();
 			
+			if (!running) {
+				cell.setGraphic(null);
+				return;
+			}
+			
 			piecesImage = new Image(SWTThread.getInstance().getDisplay(), newWidth, newHeight);
 			final GC gcImage = new GC(piecesImage);
 			
 			// dm may be null if this is a skeleton file view
-			DownloadManager download_manager = fileInfo.getDownloadManager();
+			DownloadManager download_manager = fileInfo == null ? null : fileInfo.getDownloadManager();
 			PEPeerManager peer_manager = download_manager == null ? null : download_manager.getPeerManager();
 			PEPiece[] pe_pieces = peer_manager == null ? null : peer_manager.getPieces();
 			final long now = SystemTime.getCurrentTime();
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/RemainingPiecesItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/RemainingPiecesItem.java
index f1a9b73..25f0a9f 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/RemainingPiecesItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/RemainingPiecesItem.java
@@ -47,6 +47,7 @@ public class RemainingPiecesItem
 		info.addCategories(new String[] {
 			CAT_PROGRESS,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
 	}
 
   public void refresh(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/SizeItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/SizeItem.java
index 1a03c5f..ccca99e 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/SizeItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/SizeItem.java
@@ -45,6 +45,7 @@ public class SizeItem
 		info.addCategories(new String[] {
 			CAT_BYTES,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void refresh(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/StorageTypeItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/StorageTypeItem.java
index aa4b1a5..5c3f5e1 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/files/StorageTypeItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/StorageTypeItem.java
@@ -44,6 +44,7 @@ public class StorageTypeItem
 		info.addCategories(new String[] {
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
 	}
 
   public void refresh(TableCell cell) {
@@ -52,10 +53,13 @@ public class StorageTypeItem
     if (fileInfo == null) {
       tmp = "";
     } else {
-      if (fileInfo.getStorageType() == DiskManagerFileInfo.ST_LINEAR ){
+      int st = fileInfo.getStorageType();
+      if (st == DiskManagerFileInfo.ST_LINEAR ){
         tmp = MessageText.getString("FileItem.storage.linear");
-      }else{
+      }else if ( st == DiskManagerFileInfo.ST_COMPACT ){
         tmp = MessageText.getString("FileItem.storage.compact");
+      }else{
+    	tmp = MessageText.getString("FileItem.storage.reorder");
       }
     }
     cell.setText(tmp);
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/files/TorrentRelativePathItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/files/TorrentRelativePathItem.java
new file mode 100644
index 0000000..ea59612
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/files/TorrentRelativePathItem.java
@@ -0,0 +1,52 @@
+/*
+ * 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.tableitems.files;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+
+
+public class TorrentRelativePathItem
+       extends CoreTableColumn 
+       implements TableCellRefreshListener
+{
+  
+  
+  /** Default Constructor */
+  public TorrentRelativePathItem() {
+    super("torrentrelpath", ALIGN_LEAD, POSITION_INVISIBLE, 200, TableManager.TABLE_TORRENT_FILES);
+  }
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONTENT,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
+  public void refresh(TableCell cell) {
+    DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)cell.getDataSource();
+    cell.setText( fileInfo==null?"":fileInfo.getTorrentFile().getRelativePath());
+  }
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnFileCount.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnFileCount.java
new file mode 100644
index 0000000..9720900
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnFileCount.java
@@ -0,0 +1,177 @@
+/*
+ * Created on Jan 17, 2010 2:19:53 AM
+ * Copyright (C) 2010 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.views.tableitems.mytorrents;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.util.AERunnable;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.components.shell.ShellFactory;
+import org.gudy.azureus2.ui.swt.shells.GCStringPrinter;
+import org.gudy.azureus2.ui.swt.views.FilesView;
+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 org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+import com.aelitis.azureus.ui.common.updater.UIUpdatable;
+import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
+
+/**
+ * @author TuxPaper
+ * @created Jan 17, 2010
+ *
+ */
+public class ColumnFileCount
+	extends CoreTableColumn
+	implements TableCellMouseListener, TableCellSWTPaintListener,
+	TableCellAddedListener
+{
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	public static final String COLUMN_ID = "filecount";
+
+	public ColumnFileCount(String sTableID) {
+		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 60, sTableID);
+		setRefreshInterval(INTERVAL_INVALID_ONLY);
+	}
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONTENT,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
+	public void cellAdded(TableCell cell) {
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		int sortVal = dm.getNumFileInfos();
+		cell.setSortValue(sortVal);
+	}
+
+	public void cellMouseTrigger(final TableCellMouseEvent event) {
+
+		if (Utils.getUserMode() < 2) { // remove prototype for now
+			return;
+		}
+		final DownloadManager dm = (DownloadManager) event.cell.getDataSource();
+		
+		if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER) {
+			((TableCellCore) event.cell).setCursorID(SWT.CURSOR_HAND);
+		} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEENTER) {
+			((TableCellCore) event.cell).setCursorID(SWT.CURSOR_ARROW);
+		} else if (event.eventType == TableRowMouseEvent.EVENT_MOUSEUP
+				&& event.button == 1) {
+			Utils.execSWTThreadLater(0, new AERunnable() {
+
+				public void runSupport() {
+					openFilesMiniView(dm, event.cell);
+				}
+			});
+		}
+	}
+
+	// @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) {
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		if (dm == null) {
+			return;
+		}
+
+		int sortVal = dm.getNumFileInfos();
+		Rectangle bounds = cell.getBounds();
+		Rectangle printArea = new Rectangle(bounds.x, bounds.y, bounds.width - 6,
+				bounds.height);
+		GCStringPrinter.printString(gc, "" + sortVal, printArea, true, true,
+				SWT.RIGHT);
+	}
+
+	private void openFilesMiniView(DownloadManager dm, TableCell cell) {
+		Shell shell = ShellFactory.createShell(Utils.findAnyShell(), SWT.SHELL_TRIM);
+
+		shell.setLayout(new FillLayout());
+
+		Rectangle bounds = ((TableCellSWT) cell).getBoundsOnDisplay();
+		bounds.y += bounds.height;
+		bounds.width = 630;
+		bounds.height = (16 * dm.getNumFileInfos()) + 60;
+		Rectangle realBounds = shell.computeTrim(0, 0, bounds.width, bounds.height);
+		realBounds.width -= realBounds.x;
+		realBounds.height -= realBounds.y;
+		realBounds.x = bounds.x;
+		realBounds.y = bounds.y;
+		if (bounds.height > 500) {
+			bounds.height = 500;
+		}
+		shell.setBounds(realBounds);
+		shell.setAlpha(230);
+
+		Utils.verifyShellRect(shell, true);
+
+		
+		final FilesView view = new FilesView(false);
+		view.dataSourceChanged(dm);
+
+		view.initialize(shell);
+
+		Composite composite = view.getComposite();
+		//composite.setLayoutData(null);
+		shell.setLayout(new FillLayout());
+
+		view.viewActivated();
+		view.refresh();
+
+		final UIUpdatable viewUpdater = new UIUpdatable() {
+			public void updateUI() {
+				view.refresh();
+			}
+
+			public String getUpdateUIName() {
+				return view.getFullTitle();
+			}
+		};
+		UIUpdaterSWT.getInstance().addUpdater(viewUpdater);
+
+		shell.addDisposeListener(new DisposeListener() {
+			public void widgetDisposed(DisposeEvent e) {
+				UIUpdaterSWT.getInstance().removeUpdater(viewUpdater);
+			}
+		});
+
+		shell.layout(true, true);
+
+
+		shell.setText(dm.getDisplayName());
+
+		shell.open();
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnTorrentSpeed.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnTorrentSpeed.java
new file mode 100644
index 0000000..f0f505c
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ColumnTorrentSpeed.java
@@ -0,0 +1,85 @@
+/**
+ * 
+ */
+package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.tables.*;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+
+/**
+ * @author TuxPaper
+ * @created Jul 11, 2010
+ *
+ */
+public class ColumnTorrentSpeed
+	extends CoreTableColumn
+	implements TableCellRefreshListener
+{
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	public static final String COLUMN_ID = "torrentspeed";
+
+	private Image imgUp;
+
+	private Image imgDown;
+
+	public ColumnTorrentSpeed(String tableID) {
+		super(COLUMN_ID, 80, tableID);
+		setAlignment(ALIGN_TRAIL);
+		setType(TableColumn.TYPE_TEXT);
+    setRefreshInterval(INTERVAL_LIVE);
+    setUseCoreDataSource(false);
+    
+    ImageLoader imageLoader = ImageLoader.getInstance();
+    imgUp = imageLoader.getImage("image.torrentspeed.up");
+    imgDown = imageLoader.getImage("image.torrentspeed.down");
+	}
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_ESSENTIAL,
+			CAT_BYTES,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+  public void refresh(TableCell cell) {
+  	if (!(cell.getDataSource() instanceof Download)) {
+  		return;
+  	}
+    Download dm = (Download)cell.getDataSource();
+    long value;
+    long sortValue;
+    String prefix = "";
+    if (dm == null) {
+    	sortValue = value = 0;
+    } else {
+    	int iState;
+      iState = dm.getState();
+      if (iState == Download.ST_DOWNLOADING) {
+      	value = dm.getStats().getDownloadAverage();
+      	((TableCellSWT)cell).setIcon(imgDown);
+      } else if (iState == Download.ST_SEEDING) {
+      	value = dm.getStats().getUploadAverage();
+      	((TableCellSWT)cell).setIcon(imgUp);
+      } else {
+      	((TableCellSWT)cell).setIcon(null);
+      	value = 0;
+      }
+      sortValue = (value << 4) | iState;
+    }
+    
+    if (cell.setSortValue(sortValue) || !cell.isValid()) {
+    	cell.setText(value > 0 ? prefix + DisplayFormatters.formatByteCountToKiBEtcPerSec(value) : "");
+    }
+  }
+
+}
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 08dc527..8b3d203 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CommentIconItem.java
@@ -70,6 +70,7 @@ public class CommentIconItem
 		setRefreshInterval(INTERVAL_LIVE);
 		initializeAsGraphic(POSITION_LAST, 20);
 		setMinWidth(20);
+		setIconReference("comment", true);
 	}
   
   public void cellAdded(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CompletionItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CompletionItem.java
index 9e32b89..5bbea43 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CompletionItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/CompletionItem.java
@@ -90,7 +90,7 @@ public class CompletionItem
 		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_LEAD, 150, sTableID);
 		this.marginHeight = marginHeight;
 		initializeAsGraphic(POSITION_INVISIBLE, 150);
-		setMinWidth(100);
+		setMinWidth(50);
 	}
 
 	// @see org.gudy.azureus2.plugins.ui.tables.TableCellAddedListener#cellAdded(org.gudy.azureus2.plugins.ui.tables.TableCell)
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateAddedItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateAddedItem.java
index 0036d8e..27e52ca 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateAddedItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateAddedItem.java
@@ -47,6 +47,7 @@ public class DateAddedItem
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_TIME, CAT_CONTENT });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public DateAddedItem(String sTableID) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateCompletedItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateCompletedItem.java
index 267da61..55c81a9 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateCompletedItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DateCompletedItem.java
@@ -54,6 +54,7 @@ public class DateCompletedItem
 			CAT_TIME,
 			CAT_CONTENT,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	/**
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DoneItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DoneItem.java
index 25c9799..a8fc53b 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DoneItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DoneItem.java
@@ -24,6 +24,7 @@
  
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
@@ -48,6 +49,7 @@ public class DoneItem
 	/** Default Constructor */
   public DoneItem(String sTableID) {
     super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 55, sTableID);
+    addDataSourceType(DiskManagerFileInfo.class);
     setRefreshInterval(INTERVAL_LIVE);
     if (sTableID.equals(TableManager.TABLE_MYTORRENTS_INCOMPLETE))
       setPosition(POSITION_LAST);
@@ -58,11 +60,26 @@ public class DoneItem
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_PROGRESS });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void refresh(TableCell cell) {
-    DownloadManager dm = (DownloadManager)cell.getDataSource();
-    int value = (dm == null) ? 0 : dm.getStats().getCompleted();
+  	int value;
+  	Object ds = cell.getDataSource();
+  	if (ds instanceof DownloadManager) {
+  			// show amount completed of non-dnd files as makes more sense 
+  		value = ((DownloadManager) ds).getStats().getDownloadCompleted(false);
+  	} else if (ds instanceof DiskManagerFileInfo) {
+  		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+			long length = fileInfo.getLength();
+			if (length == 0) {
+				value = 1000;
+			} else {
+				value = (int) (fileInfo.getDownloaded() * 1000 / length);
+			}
+  	} else {
+  		return;
+  	}
     if (!cell.setSortValue(value) && cell.isValid())
       return;
     cell.setText(DisplayFormatters.formatPercentFromThousands(value));
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownItem.java
index 760381f..1886280 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownItem.java
@@ -24,14 +24,15 @@
  
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
-import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
-
+import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
 import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 
 /** bytes downloaded column
@@ -43,7 +44,7 @@ public class DownItem
        extends CoreTableColumn 
        implements TableCellRefreshListener
 {
-	public static final Class DATASOURCE_TYPE = DownloadTypeIncomplete.class;
+	public static final Class DATASOURCE_TYPE = Download.class;
 
   public static final String COLUMN_ID = "down";
 
@@ -58,13 +59,21 @@ public class DownItem
 	/** Default Constructor */
   public DownItem(String sTableID) {
     super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 70, sTableID);
+		addDataSourceType(DiskManagerFileInfo.class);
     setRefreshInterval(INTERVAL_LIVE);
     setMinWidthAuto(true);
   }
 
   public void refresh(TableCell cell) {
-    DownloadManager dm = (DownloadManager)cell.getDataSource();
-    long value = (dm == null) ? 0 : dm.getStats().getTotalGoodDataBytesReceived();
+  	Object ds = cell.getDataSource();
+  	long value = 0;
+  	if (ds instanceof DownloadManager) {
+      DownloadManager dm = (DownloadManager)cell.getDataSource();
+      value = dm.getStats().getTotalGoodDataBytesReceived();
+  	} else if (ds instanceof DiskManagerFileInfo) {
+  		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+  		value = fileInfo.getDownloaded();
+  	}
     if (!cell.setSortValue(value) && cell.isValid())
       return;
     cell.setText(DisplayFormatters.formatByteCountToKiBEtc(value));
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownSpeedItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownSpeedItem.java
index 5b53b6c..53043a9 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownSpeedItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/DownSpeedItem.java
@@ -67,6 +67,7 @@ public class DownSpeedItem
 			CAT_ESSENTIAL,
 			CAT_BYTES,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
   public void cellAdded(TableCell cell) {
@@ -92,7 +93,7 @@ public class DownSpeedItem
       boolean bChangeColor = (++loop % 10) == 0;
 
       if (cell.setSortValue(value) || !cell.isValid() || (iState != iLastState)) {
-      	cell.setText(DisplayFormatters.formatByteCountToKiBEtcPerSec(value));
+      	cell.setText(value == 0 ? "" : DisplayFormatters.formatByteCountToKiBEtcPerSec(value));
       	bChangeColor = true;
       }
       
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ETAItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ETAItem.java
index 1359582..6cd4719 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ETAItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ETAItem.java
@@ -24,16 +24,18 @@
  
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
-import org.gudy.azureus2.core3.download.DownloadManager;
-import org.gudy.azureus2.core3.util.DisplayFormatters;
+
+import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
+import org.gudy.azureus2.ui.swt.views.ViewUtils;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
+import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete;
+
 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 Olivier
@@ -45,24 +47,39 @@ public class ETAItem
 {
 	public static final Class DATASOURCE_TYPE = DownloadTypeIncomplete.class;
 
-  public static final String COLUMN_ID = "eta";
+	public static final String COLUMN_ID = "eta";
 
-  public void fillTableColumnInfo(TableColumnInfo info) {
+	private ViewUtils.CustomDateFormat cdf;
+	
+	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_ESSENTIAL });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	/** Default Constructor */
-  public ETAItem(String sTableID) {
-    super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 60, sTableID);
-    setRefreshInterval(INTERVAL_LIVE);
-  }
+	public ETAItem(String sTableID) {
+		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 60, sTableID);
+		setRefreshInterval(INTERVAL_LIVE);
+		
+		cdf = ViewUtils.addCustomDateFormat( this );
+	}
 
-  public void refresh(TableCell cell) {
-    DownloadManager dm = (DownloadManager)cell.getDataSource();
-    long value = (dm == null) ? 0 : dm.getStats().getETA();
+	public void refresh(TableCell cell) {
+		DownloadManager dm = (DownloadManager)cell.getDataSource();
+		long value = (dm == null) ? 0 : dm.getStats().getETA();
 
-    if (!cell.setSortValue(value) && cell.isValid())
-      return;
-    cell.setText(DisplayFormatters.formatETA(value));
-  }
+		if (!cell.setSortValue(value) && cell.isValid()){
+			return;
+		}
+		
+		cell.setText( ViewUtils.formatETA( value, MyTorrentsView.eta_absolute, cdf.getDateFormat()));
+	}
+	
+	public void 
+	postConfigLoad() 
+	{
+		super.postConfigLoad();
+		
+		cdf.update();
+	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/FileExtensionItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/FileExtensionItem.java
new file mode 100644
index 0000000..dccea41
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/FileExtensionItem.java
@@ -0,0 +1,104 @@
+/*
+ * 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.tableitems.mytorrents;
+
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+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.ui.swt.views.table.utils.CoreTableColumn;
+
+public class FileExtensionItem
+	extends CoreTableColumn 
+	implements TableCellRefreshListener
+{
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	public static final String COLUMN_ID = "fileext";
+
+	public 
+	FileExtensionItem(String sTableID) 
+	{
+		super( DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, 50, sTableID);
+		addDataSourceType(DiskManagerFileInfo.class);
+		setMinWidthAuto(true);
+	}
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONTENT,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
+	public void 
+	refresh( TableCell cell )
+	{		
+		Object ds = cell.getDataSource();
+
+		String	text = "";
+
+		DownloadManager dm;
+		
+		if ( ds instanceof DownloadManager ){
+			
+			dm = (DownloadManager) ds;
+			
+			DiskManagerFileInfo prim = dm.getDownloadState().getPrimaryFile();
+			
+			text = prim==null?"":prim.getFile( true ).getName();
+			
+		}else if ( ds instanceof DiskManagerFileInfo ){
+			
+			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo)ds;
+			
+			dm = fileInfo.getDownloadManager();
+			
+			text = fileInfo.getFile( true ).getName();
+			
+		}else{
+			
+			return;
+		}		
+		
+		String incomp_suffix = dm==null?null:dm.getDownloadState().getAttribute( DownloadManagerState.AT_INCOMP_FILE_SUFFIX );
+		
+		if ( incomp_suffix != null && text.endsWith( incomp_suffix )){
+			
+			text = text.substring( 0, text.length() - incomp_suffix.length());
+		}
+		
+		int	pos = text.lastIndexOf( "." );
+			
+		if ( pos >= 0 ){
+				
+			text = text.substring( pos+1 );
+			
+		}else{
+			
+			text = "";
+		}
+		
+		cell.setText( text );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/HealthItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/HealthItem.java
index 9eed086..f3e2e5d 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/HealthItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/HealthItem.java
@@ -68,6 +68,7 @@ public class HealthItem
 		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, COLUMN_WIDTH, sTableID);
 		initializeAsGraphic(POSITION_LAST, COLUMN_WIDTH);
 		setMinWidth(COLUMN_WIDTH);
+		setIconReference("st_stopped", true);
 	}
 
 	public void cellAdded(TableCell cell) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/IPFilterItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/IPFilterItem.java
new file mode 100644
index 0000000..628ec57
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/IPFilterItem.java
@@ -0,0 +1,108 @@
+/*
+ * File    : CategoryItem.java
+ * Created : 01 feb. 2004
+ * By      : TuxPaper
+ *
+ * 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.tableitems.mytorrents;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.download.DownloadManagerState;
+import org.gudy.azureus2.core3.ipfilter.IpFilter;
+import org.gudy.azureus2.core3.ipfilter.IpFilterManagerFactory;
+import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
+import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTGraphicImpl;
+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;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+
+import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
+
+/** Display Category torrent belongs to.
+ *
+ * @author TuxPaper
+ */
+public class IPFilterItem
+       extends CoreTableColumn 
+       implements TableCellRefreshListener
+{
+	private static final IpFilter ipfilter = IpFilterManagerFactory.getSingleton().getIPFilter();
+	
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	private static final UISWTGraphic tick_icon;
+
+	private static final UISWTGraphic cross_icon;
+	
+	static {
+		tick_icon = new UISWTGraphicImpl(ImageLoader.getInstance().getImage("tick_mark"));
+		cross_icon = new UISWTGraphicImpl(ImageLoader.getInstance().getImage("cross_mark"));
+	}
+	
+  public static final String COLUMN_ID = "ipfilter";
+
+	/** Default Constructor */
+  public IPFilterItem(String sTableID) {
+    super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_CENTER, 100, sTableID);
+    setRefreshInterval(INTERVAL_LIVE);
+	initializeAsGraphic(POSITION_INVISIBLE, 100);
+	setMinWidth(20);
+  }
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONNECTION,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE );
+	}
+
+  public void refresh(TableCell cell) {
+    //String state = "";
+    
+    UISWTGraphic	icon = null;
+    
+    if( ipfilter.isEnabled()){
+	    DownloadManager dm = (DownloadManager)cell.getDataSource();
+	    if (dm != null) {
+	       boolean excluded = dm.getDownloadState().getFlag( DownloadManagerState.FLAG_DISABLE_IP_FILTER );
+	  
+	       if ( excluded ){
+	    	   
+	    	   icon = cross_icon;
+	    	   
+	    	   //state = "\u2718";
+	    	   
+	       }else{
+	    	   
+	    	   icon = tick_icon;
+	    	  // state = "\u2714";
+	       }
+	    }
+    }
+    if ( cell.getGraphic() != icon ){
+    	
+    	cell.setGraphic( icon );
+    }
+  }
+}
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 392934d..5b13790 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/NameItem.java
@@ -28,6 +28,7 @@ import org.eclipse.swt.graphics.Image;
 
 import org.gudy.azureus2.core3.config.COConfigurationManager;
 import org.gudy.azureus2.core3.config.ParameterListener;
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.plugins.download.Download;
@@ -58,6 +59,7 @@ public class NameItem extends CoreTableColumn implements
 	
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_ESSENTIAL, CAT_CONTENT });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	/**
@@ -110,6 +112,11 @@ public class NameItem extends CoreTableColumn implements
 					}
 				});
 	}
+	
+	public void reset() {
+		super.reset();
+		COConfigurationManager.removeParameter("NameColumn.showProgramIcon");
+	}
 
 	public void refresh(TableCell cell)
 	{
@@ -129,12 +136,13 @@ public class NameItem extends CoreTableColumn implements
 		if ((cell.setText(name) || !cell.isValid())) {
 			if (dm != null && isShowIcon() && !sortOnlyRefresh
 					&& (cell instanceof TableCellSWT)) {
-				String path = dm.getDownloadState().getPrimaryFile();
-				if (path != null) {
+				DiskManagerFileInfo fileInfo = dm.getDownloadState().getPrimaryFile();
+				if (fileInfo != null) {
 					// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
 					TOTorrent torrent = dm.getTorrent();
-					Image icon = ImageRepository.getPathIcon(path, false, torrent != null
-							&& !torrent.isSimpleTorrent());
+					Image icon = ImageRepository.getPathIcon(
+							fileInfo.getFile(false).getName(), false, torrent != null
+									&& !torrent.isSimpleTorrent());
 					((TableCellSWT) cell).setIcon(icon);
 				}
 			}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/PeersItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/PeersItem.java
index 16e6986..6ec1533 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/PeersItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/PeersItem.java
@@ -24,8 +24,11 @@
 
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import java.util.Locale;
+
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
@@ -56,6 +59,26 @@ public class PeersItem extends CoreTableColumn implements
 
 	public static final String COLUMN_ID = "peers";
 
+
+	private static String textStarted;
+	private static String textStartedOver;
+	private static String textNotStarted;
+	private static String textStartedNoScrape;
+	private static String textNotStartedNoScrape;
+
+	
+	static {
+		MessageText.addAndFireListener(new MessageTextListener() {
+			public void localeChanged(Locale old_locale, Locale new_locale) {
+				textStarted = MessageText.getString("Column.seedspeers.started");
+				textStartedOver = MessageText.getString("Column.seedspeers.started.over");
+				textNotStarted = MessageText.getString("Column.seedspeers.notstarted");
+				textStartedNoScrape = MessageText.getString("Column.seedspeers.started.noscrape");
+				textNotStartedNoScrape = MessageText.getString("Column.seedspeers.notstarted.noscrape");
+			}
+		});
+	}
+
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_SWARM });
 	}
@@ -118,10 +141,21 @@ public class PeersItem extends CoreTableColumn implements
 			if (!cell.setSortValue(value) && cell.isValid())
 				return;
 
-			String tmp = String.valueOf(lConnectedPeers);
-			if (totalPeers != -1)
-				tmp += " (" + totalPeers + ")";
+			int state = dm.getState();
+			boolean started = state == DownloadManager.STATE_SEEDING
+					|| state == DownloadManager.STATE_DOWNLOADING;
+			boolean hasScrape = lTotalPeers >= 0;
 
+			String tmp;
+			if (started) {
+				tmp = hasScrape ? (lConnectedPeers > lTotalPeers ? textStartedOver
+						: textStarted) : textStartedNoScrape;
+			} else {
+				tmp = hasScrape ? textNotStarted : textNotStartedNoScrape;
+			}
+			
+			tmp = tmp.replaceAll("%1", String.valueOf(lConnectedPeers));
+			tmp = tmp.replaceAll("%2", String.valueOf(totalPeers));
 			cell.setText(tmp);
 		}
 
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/RemainingItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/RemainingItem.java
index fa03f24..79ebbda 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/RemainingItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/RemainingItem.java
@@ -24,6 +24,7 @@
  
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
@@ -50,6 +51,7 @@ public class RemainingItem
 	/** Default Constructor */
   public RemainingItem(String sTableID) {
     super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 70, sTableID);
+		addDataSourceType(DiskManagerFileInfo.class);
     setRefreshInterval(INTERVAL_LIVE);
     setMinWidthAuto(true);
   }
@@ -78,10 +80,16 @@ public class RemainingItem
   }
 
   private long getRemaining(TableCell cell) {
-    DownloadManager manager = (DownloadManager)cell.getDataSource();
-    if (manager == null)
-      return 0;
-
-   return( manager.getStats().getRemaining());
+  	Object ds = cell.getDataSource();
+  	if (ds instanceof DownloadManager) {
+      DownloadManager manager = (DownloadManager)cell.getDataSource();
+      if (manager != null) {
+      	return( manager.getStats().getRemaining());
+      }
+  	} else if (ds instanceof DiskManagerFileInfo) {
+  		DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+  		return fileInfo.getLength() - fileInfo.getDownloaded();
+  	}
+  	return 0;
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SeedsItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SeedsItem.java
index ccabb73..958002d 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SeedsItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SeedsItem.java
@@ -24,17 +24,19 @@
 
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import java.util.Locale;
+
 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.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
-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.TableCellAddedListener;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 /**
  *
@@ -54,6 +56,25 @@ public class SeedsItem
 
 	public static final String COLUMN_ID = "seeds";
 
+	private static String textStarted;
+	private static String textStartedOver;
+	private static String textNotStarted;
+	private static String textStartedNoScrape;
+	private static String textNotStartedNoScrape;
+
+	
+	static {
+		MessageText.addAndFireListener(new MessageTextListener() {
+			public void localeChanged(Locale old_locale, Locale new_locale) {
+				textStarted = MessageText.getString("Column.seedspeers.started");
+				textStartedOver = MessageText.getString("Column.seedspeers.started.over");
+				textNotStarted = MessageText.getString("Column.seedspeers.notstarted");
+				textStartedNoScrape = MessageText.getString("Column.seedspeers.started.noscrape");
+				textNotStartedNoScrape = MessageText.getString("Column.seedspeers.notstarted.noscrape");
+			}
+		});
+	}
+
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] { CAT_SWARM });
 	}
@@ -142,17 +163,30 @@ public class SeedsItem
 
 			boolean bCompleteTorrent = dm == null ? false : dm.getAssumedComplete();
 			
-			String tmp = String.valueOf(lConnectedSeeds);
+			int state = dm.getState();
+			boolean started = (state == DownloadManager.STATE_SEEDING || state == DownloadManager.STATE_DOWNLOADING);
+			boolean hasScrape = lTotalSeeds >= 0;
+			String tmp;
+			
+			if (started) {
+				tmp = hasScrape ? (lConnectedSeeds > lTotalSeeds ? textStartedOver
+						: textStarted) : textStartedNoScrape;
+			} else {
+				tmp = hasScrape ? textNotStarted : textNotStartedNoScrape;
+			}
+			tmp = tmp.replaceAll("%1", String.valueOf(lConnectedSeeds));
+			String param2 = "?";
 			if (lTotalSeeds != -1) {
-				tmp += " (" + lTotalSeeds;
+				param2 = String.valueOf(lTotalSeeds);
 				if (bCompleteTorrent && iFC_NumPeers > 0 && lTotalSeeds >= iFC_MinSeeds
 						&& lTotalPeers > 0) {
 					long lSeedsToAdd = lTotalPeers / iFC_NumPeers;
-					if (lSeedsToAdd > 0)
-						tmp += "+" + lSeedsToAdd;
+					if (lSeedsToAdd > 0) {
+						param2 += "+" + lSeedsToAdd;
+					}
 				}
-				tmp += ")";
 			}
+			tmp = tmp.replaceAll("%2", param2);
 			cell.setText(tmp);
 		}
 
@@ -181,7 +215,7 @@ public class SeedsItem
 					&& lTotalPeers > 0) {
 				long lSeedsToAdd = lTotalPeers / iFC_NumPeers;
 				sToolTip += "\n"
-						+ MessageText.getString("MyTorrentsView.seeds.fullcopycalc",
+						+ MessageText.getString("TableColumn.header.seeds.fullcopycalc",
 								new String[] {
 									"" + lTotalPeers,
 									"" + lSeedsToAdd
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ShareRatioItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ShareRatioItem.java
index 2b1ecbf..3a296c4 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ShareRatioItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/ShareRatioItem.java
@@ -61,7 +61,7 @@ public class ShareRatioItem
 
 	/** Default Constructor */
   public ShareRatioItem(String sTableID) {
-    super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 70, sTableID);
+    super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 73, sTableID);
 		setType(TableColumn.TYPE_TEXT);
     setRefreshInterval(INTERVAL_LIVE);
     setMinWidthAuto(true);
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SizeItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SizeItem.java
index 93d5054..5d19bb2 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SizeItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/SizeItem.java
@@ -24,8 +24,12 @@
 
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.util.DisplayFormatters;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.mainwindow.HSLColor;
+import org.gudy.azureus2.ui.swt.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import org.gudy.azureus2.plugins.download.Download;
@@ -33,6 +37,8 @@ import org.gudy.azureus2.plugins.ui.tables.TableCell;
 import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
 import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
 
+import com.aelitis.azureus.ui.common.table.TableCellCore;
+
 /** Size of Torrent cell
  *
  * @author Olivier
@@ -51,6 +57,7 @@ public class SizeItem
 	/** Default Constructor */
 	public SizeItem(String sTableID) {
 		super(DATASOURCE_TYPE, COLUMN_ID, ALIGN_TRAIL, 70, sTableID);
+		addDataSourceType(DiskManagerFileInfo.class);
 		setRefreshInterval(INTERVAL_GRAPHIC);
 		setMinWidthAuto(true);
 	}
@@ -61,12 +68,23 @@ public class SizeItem
 			CAT_CONTENT,
 			CAT_BYTES
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public void refresh(TableCell cell) {
-		DownloadManager dm = (DownloadManager) cell.getDataSource();
-		sizeitemsort value = (dm == null) ? new sizeitemsort(0, 0)
-				: new sizeitemsort(dm.getSize(), dm.getStats().getRemaining());
+		Object ds = cell.getDataSource();
+		sizeitemsort value;
+		if (ds instanceof DownloadManager) {
+			DownloadManager dm = (DownloadManager) ds;
+			
+			value = new sizeitemsort(dm.getSize(), dm.getStats().getRemaining());
+		} else if (ds instanceof DiskManagerFileInfo) {
+			DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
+			value = new sizeitemsort(fileInfo.getLength(), fileInfo.getLength()
+					- fileInfo.getDownloaded());
+		} else {
+			return;
+		}
 
 		// cell.setSortValue(value) always returns true and if I change it,
 		// I'm afraid something will break.. so use compareTo
@@ -83,6 +101,15 @@ public class SizeItem
 							false, 0) + " to go";
 		}
 		cell.setText(s);
+		if (Utils.getUserMode() > 0 && (cell instanceof TableCellSWT)) {
+			if (value.size >= 0x40000000l) {
+				((TableCellSWT)cell).setTextAlpha(200 | 0x100);
+			} else if (value.size < 0x100000) {
+				((TableCellSWT)cell).setTextAlpha(180);
+			} else {
+				((TableCellSWT)cell).setTextAlpha(255);
+			}
+		}
 	}
 
 	private class sizeitemsort
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/StatusItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/StatusItem.java
index 17360f4..3dadbc0 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/StatusItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/StatusItem.java
@@ -73,6 +73,7 @@ public class StatusItem
 		info.addCategories(new String[] {
 			CAT_ESSENTIAL,
 		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 	}
 
 	public void 
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TorrentCreateDateItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TorrentCreateDateItem.java
new file mode 100644
index 0000000..31effe5
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TorrentCreateDateItem.java
@@ -0,0 +1,70 @@
+/*
+ * Created on 05-May-2006
+ * Created by Paul Gardner
+ * 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 org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
+
+import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
+import org.gudy.azureus2.ui.swt.views.tableitems.ColumnDateSizer;
+
+import org.gudy.azureus2.plugins.download.Download;
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+
+public class TorrentCreateDateItem
+	extends ColumnDateSizer
+{
+	public static final Class DATASOURCE_TYPE = Download.class;
+
+	public static final String COLUMN_ID = "torrent_created";
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] { CAT_TIME, CAT_CONTENT });
+		info.setProficiency(TableColumnInfo.PROFICIENCY_INTERMEDIATE);
+	}
+
+	public TorrentCreateDateItem(String sTableID) {
+		super(DATASOURCE_TYPE, COLUMN_ID, TableColumnCreator.DATE_COLUMN_WIDTH, sTableID);
+		
+		setMultiline(false);
+		
+		setRefreshInterval(INTERVAL_INVALID_ONLY);
+
+		setShowTime( false );
+	}
+
+	/**
+	 * @param tableID
+	 * @param b
+	 */
+	public TorrentCreateDateItem(String tableID, boolean v) {
+		this(tableID);
+		setVisible(v);
+	}
+
+	public void refresh(TableCell cell, long timestamp) {
+		DownloadManager dm = (DownloadManager) cell.getDataSource();
+		timestamp = (dm == null) ? 0 : dm.getTorrentCreationDate();
+		super.refresh(cell, timestamp*1000);
+		//cell.setText(DisplayFormatters.formatDate(timestamp));
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerNameItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerNameItem.java
index 3f1a63f..41ed9d6 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerNameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerNameItem.java
@@ -24,8 +24,14 @@
  
 package org.gudy.azureus2.ui.swt.views.tableitems.mytorrents;
 
+import java.net.URL;
+import java.util.Set;
+
 import org.gudy.azureus2.core3.download.DownloadManager;
+import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet;
 import org.gudy.azureus2.core3.util.StringInterner;
+import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
 
 import org.gudy.azureus2.plugins.download.Download;
@@ -60,25 +66,85 @@ public class TrackerNameItem
     String name = "";
     
     if( dm != null && dm.getTorrent() != null ) {
-      String host = dm.getTorrent().getAnnounceURL().getHost();
-      String[] parts = host.split( "\\." );
-        
-      int used = 0;
-      for( int i = parts.length-1; i >= 0; i-- ) {
-        if( used > 4 ) break; //don't use more than 4 segments
-        String chunk = parts[ i ];
-        if( used < 2 || chunk.length() < 11 ) {  //use first end two always, but trim out >10 chars (passkeys)
-          if( used == 0 ) name = chunk;
-          else name = chunk + "." + name;
-          used++;
-        }
-        else break;
-      }
-      
-      if(name.equals(host))
-    	  name = host;
-      else
-    	  name = StringInterner.intern(name);
+    	TOTorrent torrent = dm.getTorrent();
+
+    	Set<String> pref_names = MyTorrentsView.preferred_tracker_names;
+    	
+    	URL	url = null;
+    	
+    	if ( pref_names != null ){
+    		
+    		TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
+    		
+    		if ( sets.length > 0 ){
+    			
+    			String host = torrent.getAnnounceURL().getHost();
+    			
+    			if ( pref_names.contains( host )){
+    				
+    				url = torrent.getAnnounceURL();
+    				
+    			}else{
+    				
+    				for ( TOTorrentAnnounceURLSet set: sets ){
+    					
+    					URL[] urls = set.getAnnounceURLs();
+    					
+    					for ( URL u: urls ){
+    						
+    						if ( pref_names.contains( u.getHost())){
+    							
+    							url = u;
+    							
+    							break;
+    						}
+    					}
+    					
+    					if ( url != null ){
+    						
+    						break;
+    					}
+    				}
+    			}
+    		}
+    	}
+    	
+    	if ( url == null ){
+    		
+    		url = torrent.getAnnounceURL();
+    	}
+    	
+    	String host = url.getHost();
+    	
+    	if ( host.endsWith( ".dht" )){
+    		
+    		name = "dht";
+    		
+    	}else{
+    		
+	    	String[] parts = host.split( "\\." );
+	
+	    	int used = 0;
+	    	for( int i = parts.length-1; i >= 0; i-- ) {
+	    		if( used > 4 ) break; //don't use more than 4 segments
+	    		String chunk = parts[ i ];
+	    		if( used < 2 || chunk.length() < 11 ) {  //use first end two always, but trim out >10 chars (passkeys)
+	    			if( used == 0 ) name = chunk;
+	    			else name = chunk + "." + name;
+	    			used++;
+	    		}
+	    		else break;
+	    	}
+    	}
+    	
+    	if(name.equals(host)){
+    		
+    		name = host;
+    		
+    	}else{
+    		
+    		name = StringInterner.intern(name);
+    	}
     }
         
     if (cell.setText(name) || !cell.isValid()) {
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerStatusItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerStatusItem.java
index efca2af..555d46b 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerStatusItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/TrackerStatusItem.java
@@ -42,7 +42,7 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  *
  */
 public class TrackerStatusItem extends CoreTableColumn implements
-		TableCellAddedListener, TableCellToolTipListener, TableCellMouseMoveListener
+		TableCellAddedListener, TableCellToolTipListener
 {
 	public static final Class DATASOURCE_TYPE = Download.class;
 
@@ -64,62 +64,6 @@ public class TrackerStatusItem extends CoreTableColumn implements
 		new Cell(cell);
 	}
 
-	public void 
-	cellMouseTrigger(
-		TableCellMouseEvent event )
-	{
-		Object ds = event.cell.getDataSource();
-		
-		if ( !( ds instanceof DownloadManager )){
-			
-			return;
-		}
-		
-		DownloadManager dm = (DownloadManager)ds;
-
-		AZ3Functions.provider az3 = AZ3Functions.getProvider();
-		
-		if ( az3 == null || !az3.canShowCDP( dm )){
-			
-			return;
-		}
-		
-		if ( !(event.cell instanceof TableCellSWT )){
-			
-			return;
-		}
-		
-		TableCellSWT cell = (TableCellSWT)event.cell;
-		
-		boolean invalidateAndRefresh = false;
-		
-		int newCursor = dm.isUnauthorisedOnTracker()?SWT.CURSOR_HAND:SWT.CURSOR_ARROW;
-		
-		int oldCursor = cell.getCursorID();
-		
-		if ( oldCursor != newCursor ){
-			
-			invalidateAndRefresh = true;
-			
-			cell.setCursorID(newCursor);
-		}
-		
-		if ( event.eventType == TableCellMouseEvent.EVENT_MOUSEUP ){
-			
-			if ( newCursor == SWT.CURSOR_HAND ){
-				
-				az3.showCDP( dm, "tracker.unauth" );
-			}
-		}
-		
-		if ( invalidateAndRefresh ){
-			
-			cell.invalidate();
-			
-			cell.redraw();
-		}
-	}
-	
 	private class Cell extends AbstractTrackerCell {
 		public Cell(TableCell cell) {
 			super(cell);
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/UpSpeedItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/UpSpeedItem.java
index 8e686d4..1366af6 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/UpSpeedItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytorrents/UpSpeedItem.java
@@ -77,6 +77,7 @@ public class UpSpeedItem
 			info.addCategories(new String[] {
 				CAT_ESSENTIAL
 			});
+			info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
 		}
 	}
 
@@ -103,7 +104,9 @@ public class UpSpeedItem
       boolean bChangeColor = (++loop % 10) == 0;
 
       if (cell.setSortValue(value) || !cell.isValid() || (iState != iLastState)) {
-      	cell.setText(StringInterner.intern(DisplayFormatters.formatByteCountToKiBEtcPerSec(value)));
+				cell.setText(value == 0
+						? ""
+						: StringInterner.intern(DisplayFormatters.formatByteCountToKiBEtcPerSec(value)));
       	bChangeColor = true;
       }
       
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/mytracker/NameItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/mytracker/NameItem.java
index e3b035c..d39f93f 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/mytracker/NameItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/mytracker/NameItem.java
@@ -34,6 +34,7 @@ import org.gudy.azureus2.core3.util.ByteFormatter;
 import org.gudy.azureus2.core3.util.Constants;
 import org.gudy.azureus2.core3.util.TorrentUtils;
 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.views.table.TableCellSWT;
 import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
@@ -75,15 +76,47 @@ public class NameItem extends CoreTableColumn implements
 			if (item != null && item.getTorrent() != null && bShowIcon 
 					&& (cell instanceof TableCellSWT)) {
 				try {
-  				TOTorrent torrent = item.getTorrent();
-  				String path = torrent.getFiles()[0].getRelativePath();
-  				
-  				if (path != null) {
-  					// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
-  					Image icon = ImageRepository.getPathIcon(path, false, torrent != null
-  							&& !torrent.isSimpleTorrent());
-  					((TableCellSWT) cell).setIcon(icon);
-  				}
+	  				final TOTorrent torrent = item.getTorrent();
+	  				final String path = torrent.getFiles()[0].getRelativePath();
+	  				
+	  				if ( path != null ){
+	  					
+	  					Image icon = null;
+	  					
+	  					final TableCellSWT _cell = (TableCellSWT)cell;
+
+						// Don't ever dispose of PathIcon, it's cached and may be used elsewhere
+						
+						if ( Utils.isSWTThread()){
+						
+							icon = ImageRepository.getPathIcon(path, false, torrent != null
+		  							&& !torrent.isSimpleTorrent());
+						}else{	
+								// happens rarely (seen of filtering of file-view rows
+								// when a new row is added )
+													
+							Utils.execSWTThread(
+								new Runnable()
+								{
+									public void
+									run()
+									{
+										Image icon = ImageRepository.getPathIcon(path, false, torrent != null
+					  							&& !torrent.isSimpleTorrent());
+										
+										_cell.setIcon(icon);
+										
+										_cell.redraw();
+									}
+								});
+						}
+	  					
+	  					
+						if ( icon != null ){
+							
+							_cell.setIcon(icon);
+						}
+	  				}
 				} catch (Exception e) {
 				}
 			}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/peers/ChokedItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/peers/ChokedItem.java
index 79c2eb5..ae81f3b 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/peers/ChokedItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/peers/ChokedItem.java
@@ -56,11 +56,11 @@ public class ChokedItem
 
   public void refresh(TableCell cell) {
     PEPeer peer = (PEPeer)cell.getDataSource();
-    long value = (peer == null) ? 0 : (peer.isChokingMe() ? 1 : 0);
+    long value = (peer == null) ? 0 : (peer.isChokingMe() ? 1 : (peer.isUnchokeOverride()?2:0));
 
     if (!cell.setSortValue(value) && cell.isValid())
       return;
 
-    cell.setText((value == 1) ? "*" : "");
+    cell.setText((value >0) ?(peer.isUnchokeOverride()?"+":"*") : "");
   }
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/peers/EncryptionItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/peers/EncryptionItem.java
index 4943249..4a957d1 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/peers/EncryptionItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/peers/EncryptionItem.java
@@ -44,7 +44,7 @@ public class EncryptionItem
 
   /** Default Constructor */
   public EncryptionItem(String table_id) {
-    super(COLUMN_ID, ALIGN_CENTER, POSITION_INVISIBLE, 20, table_id);
+    super(COLUMN_ID, ALIGN_CENTER, POSITION_INVISIBLE, 50, table_id);
     setRefreshInterval(INTERVAL_LIVE);
   }
 
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/peers/PiecesItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/peers/PiecesItem.java
index 5630b64..6b6e2a0 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/peers/PiecesItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/peers/PiecesItem.java
@@ -24,7 +24,6 @@
 
 package org.gudy.azureus2.ui.swt.views.tableitems.peers;
 
-
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Rectangle;
@@ -32,7 +31,9 @@ import org.eclipse.swt.graphics.Rectangle;
 import org.gudy.azureus2.core3.disk.*;
 import org.gudy.azureus2.core3.peer.PEPeer;
 import org.gudy.azureus2.core3.peer.impl.PEPeerTransport;
+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.mainwindow.Colors;
 import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
 import org.gudy.azureus2.ui.swt.plugins.UISWTGraphic;
@@ -51,23 +52,28 @@ import org.gudy.azureus2.plugins.ui.tables.*;
  * @author TuxPaper (2004/Apr/19: modified to TableCellAdapter)
  */
 public class PiecesItem
-       extends CoreTableColumn 
-       implements TableCellAddedListener, TableCellRefreshListener, TableCellDisposeListener, DiskManagerListener
+	extends CoreTableColumn
+	implements TableCellAddedListener, TableCellRefreshListener,
+	TableCellDisposeListener, DiskManagerListener
 {
-  private final static int INDEX_COLOR_FADEDSTARTS = Colors.BLUES_DARKEST + 1;
-  // only supports 0 or 1 border width
-  private final static int borderHorizontalSize = 1;
-  private final static int borderVerticalSize = 1;
-  private final static int borderSplit = 1;
-  private final static int completionHeight = 2;
-  
-  private int row_count;
-  
-  /** Default Constructor */
-  public PiecesItem(String table_id) {
-    super("pieces", table_id);
-    initializeAsGraphic(POSITION_LAST, 200);
-  }
+	private final static int INDEX_COLOR_FADEDSTARTS = Colors.BLUES_DARKEST + 1;
+
+	// only supports 0 or 1 border width
+	private final static int borderHorizontalSize = 1;
+
+	private final static int borderVerticalSize = 1;
+
+	private final static int borderSplit = 1;
+
+	private final static int completionHeight = 2;
+
+	private int row_count;
+
+	/** Default Constructor */
+	public PiecesItem(String table_id) {
+		super("pieces", table_id);
+		initializeAsGraphic(POSITION_LAST, 200);
+	}
 
 	public void fillTableColumnInfo(TableColumnInfo info) {
 		info.addCategories(new String[] {
@@ -75,246 +81,264 @@ public class PiecesItem
 		});
 	}
 
-  public void cellAdded(TableCell cell) {
-	synchronized( this ){
-		row_count++;
-	}
-    cell.setFillCell(true);
-    Object ds = cell.getDataSource();
-    if (ds instanceof PEPeer) {
+	public void cellAdded(TableCell cell) {
+		synchronized (this) {
+			row_count++;
+		}
+		cell.setFillCell(true);
+		Object ds = cell.getDataSource();
+		if (ds instanceof PEPeer) {
 			PEPeer peer = (PEPeer) ds;
 			DiskManager diskmanager = peer.getManager().getDiskManager();
-			
-			if ( diskmanager.getRemaining() > 0 ){
-				if ( !diskmanager.hasListener( this )){
-					diskmanager.addListener( this );
+
+			if (diskmanager.getRemaining() > 0) {
+				if (!diskmanager.hasListener(this)) {
+					diskmanager.addListener(this);
 				}
 			}
 		}
-  }
-
-  public void dispose(TableCell cell) {
-	synchronized( this ){
-	  row_count--;
 	}
-    // Named infoObj so code can be copied easily to the other PiecesItem
-    PEPeer infoObj = (PEPeer)cell.getDataSource();
-    if (infoObj == null)
-      return;
-
-    Image img = (Image)infoObj.getData("PiecesImage");
-    if (img != null && !img.isDisposed())
-      img.dispose();
-
-    infoObj.setData("PiecesImageBuffer", null);
-    infoObj.setData("PiecesImage", null);
-  }
-  
-  public void refresh(TableCell cell) {
-    /* Notes:
-     * We store our image and imageBufer in PEPeer using
-     * setData & getData.
-     */
-
-    // Named infoObj so code can be copied easily to the other PiecesItem
-    PEPeer infoObj = (PEPeer)cell.getDataSource();
-    long lCompleted = (infoObj == null) ? 0 : infoObj.getPercentDoneInThousandNotation();
-
-    if( !cell.setSortValue( lCompleted ) && cell.isValid() ) {
-      return;
-    }
-    
-    if (infoObj == null)
-      return;
-
-    //Compute bounds ...
-    int newWidth = cell.getWidth();
-    if (newWidth <= 0)
-      return;
-    int newHeight = cell.getHeight();
-
-    int x0 = borderVerticalSize;
-    int x1 = newWidth - 1 - borderVerticalSize;
-    int y0 = completionHeight + borderHorizontalSize + borderSplit;
-    int y1 = newHeight - 1 - borderHorizontalSize;
-    int drawWidth = x1 - x0 + 1;
-    if (drawWidth < 10 || y1 < 3)
-      return;
-    int[] imageBuffer = (int [])infoObj.getData("PiecesImageBuffer");
-    boolean bImageBufferValid = imageBuffer != null && imageBuffer.length == drawWidth;
-
-    Image image = (Image)infoObj.getData("PiecesImage");
-    GC gcImage;
-    boolean bImageChanged;
-    Rectangle imageBounds;
-    if (image == null || image.isDisposed()) {
-      bImageChanged = true;
-    } else {
-      imageBounds = image.getBounds();
-      bImageChanged = imageBounds.width != newWidth ||
-                      imageBounds.height != newHeight;
-    }
-    if (bImageChanged) {
-      if (image != null && !image.isDisposed()) {
-        image.dispose();
-      }
-      image = new Image(SWTThread.getInstance().getDisplay(),
-                        newWidth, newHeight);
-      imageBounds = image.getBounds();
-      bImageBufferValid = false;
-
-      // draw border
-      gcImage = new GC(image);
-      gcImage.setForeground(Colors.grey);
-      if (borderHorizontalSize > 0) {
-        if (borderVerticalSize > 0) {
-          gcImage.drawRectangle(0, 0, newWidth - 1, newHeight - 1);
-        } else {
-          gcImage.drawLine(0, 0, newWidth - 1, 0);
-          gcImage.drawLine(0, newHeight -1, newWidth - 1, newHeight - 1);
-        }
-      } else if (borderVerticalSize > 0) {
-        gcImage.drawLine(0, 0, 0, newHeight - 1);
-        gcImage.drawLine(newWidth - 1, 0, newWidth - 1, newHeight - 1);
-      }
-
-      if (borderSplit > 0) {
-        gcImage.setForeground(Colors.white);
-        gcImage.drawLine(x0, completionHeight + borderHorizontalSize,
-                         x1, completionHeight + borderHorizontalSize);
-      }
-    } else {
-      gcImage = new GC(image);
-    }
-
-    final BitFlags peerHave = infoObj.getAvailable();
-    boolean established = ((PEPeerTransport)infoObj).getConnectionState() == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED;
-    
-    if (established && peerHave != null && peerHave.flags.length > 0) {
-      if (imageBuffer == null || imageBuffer.length != drawWidth) {
-        imageBuffer = new int[drawWidth];
-      }
-        final boolean available[] =peerHave.flags;
-    try {
-      
-      int nbComplete = 0;
-      int nbPieces = available.length;
-      
-      DiskManager disk_manager = infoObj.getManager().getDiskManager();
-      DiskManagerPiece[]  pieces = disk_manager==null?null:disk_manager.getPieces();
-                      
-      
-      int a0;
-      int a1 = 0;
-      for (int i = 0; i < drawWidth; i++) {
-        if (i == 0) {
-          // always start out with one piece
-          a0 = 0;
-          a1 = nbPieces / drawWidth;
-          if (a1 == 0)
-            a1 = 1;
-        } else {
-          // the last iteration, a1 will be nbPieces
-          a0 = a1;
-          a1 = ((i + 1) * nbPieces) / (drawWidth);
-        }
-
-        int index;
-        int nbNeeded = 0;
-
-        if (a1 <= a0) {
-          index = imageBuffer[i - 1];
-        } else {
-          int nbAvailable = 0;
-          for (int j = a0; j < a1; j++) {
-            if (available[j]) {
-              if (pieces==null || !pieces[j].isDone()) {
-                nbNeeded++;
-              }
-              nbAvailable++;
-            }
-          }
-          nbComplete += nbAvailable;
-          index = (nbAvailable * Colors.BLUES_DARKEST) / (a1 - a0);
-          if (nbNeeded <= nbAvailable / 2)
-            index += INDEX_COLOR_FADEDSTARTS;
-        }
-
-        if (imageBuffer[i] != index) {
-          imageBuffer[i] = index;
-          if (bImageBufferValid) {
-            bImageChanged = true;
-            if (imageBuffer[i] >= INDEX_COLOR_FADEDSTARTS)
-              gcImage.setForeground(Colors.faded[index - INDEX_COLOR_FADEDSTARTS]);
-            else
-              gcImage.setForeground(Colors.blues[index]);
-            gcImage.drawLine(i + x0, y0, i + x0, y1);
-          }
-        }
-      }
-      if (!bImageBufferValid) {
-        if(established) {
-          int iLastIndex = imageBuffer[0];
-          int iWidth = 1;
-          for (int i = 1; i < drawWidth; i++) {
-            if (iLastIndex == imageBuffer[i]) {
-              iWidth++;
-            } else {
-              if (iLastIndex >= INDEX_COLOR_FADEDSTARTS) {
-                gcImage.setBackground(Colors.faded[iLastIndex - INDEX_COLOR_FADEDSTARTS]);
-              } else
-                gcImage.setBackground(Colors.blues[iLastIndex]);
-              gcImage.fillRectangle(i - iWidth + x0, y0, iWidth, y1 - y0 + 1);
-              iWidth = 1;
-              iLastIndex = imageBuffer[i];
-            }
-          }
-          if (iLastIndex >= INDEX_COLOR_FADEDSTARTS)
-            gcImage.setBackground(Colors.faded[iLastIndex - INDEX_COLOR_FADEDSTARTS]);
-          else
-            gcImage.setBackground(Colors.blues[iLastIndex]);
-          gcImage.fillRectangle(x1 - iWidth + 1, y0, iWidth, y1 - y0 + 1);
-          bImageChanged = true;
-        }
-      }
-
-      int limit = (drawWidth * nbComplete) / nbPieces;
-      if (limit < drawWidth) {
-        gcImage.setBackground(Colors.blues[Colors.BLUES_LIGHTEST]);
-        gcImage.fillRectangle(limit+x0, borderHorizontalSize,
-                              x1-limit, completionHeight);
-      }
-      gcImage.setBackground(Colors.colorProgressBar);
-      gcImage.fillRectangle(x0, borderHorizontalSize,
-                            limit, completionHeight);
-    } catch (Exception e) {
-      System.out.println("Error Drawing PiecesItem");
-      Debug.printStackTrace( e );
-    } } else {
-        gcImage.setForeground(Colors.grey);
-        gcImage.setBackground(Colors.grey);
-        gcImage.fillRectangle(x0,y0,newWidth,y1);
-    }
-    gcImage.dispose();
-
-		Image oldImage = null;
-		Graphic graphic = cell.getGraphic();
-		if (graphic instanceof UISWTGraphic) {
-			oldImage = ((UISWTGraphic) graphic).getImage();
+
+	public void dispose(TableCell cell) {
+		synchronized (this) {
+			row_count--;
 		}
-		if (bImageChanged || image != oldImage || !cell.isValid()) {
-			if (cell instanceof TableCellSWT) {
-				((TableCellSWT) cell).setGraphic(image);
-			} else {
-				cell.setGraphic(new UISWTGraphicImpl(image));
+		// Named infoObj so code can be copied easily to the other PiecesItem
+		PEPeer infoObj = (PEPeer) cell.getDataSource();
+		if (infoObj == null)
+			return;
+
+		final Image img = (Image) infoObj.getData("PiecesImage");
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				if (img != null && !img.isDisposed())
+					img.dispose();
 			}
-			if (bImageChanged || image != oldImage) {
-				cell.invalidate();
+		});
+
+		infoObj.setData("PiecesImageBuffer", null);
+		infoObj.setData("PiecesImage", null);
+	}
+
+	public void refresh(final TableCell cell) {
+		/* Notes:
+		 * We store our image and imageBufer in PEPeer using
+		 * setData & getData.
+		 */
+
+		// Named infoObj so code can be copied easily to the other PiecesItem
+		final PEPeer infoObj = (PEPeer) cell.getDataSource();
+		long lCompleted = (infoObj == null) ? 0
+				: infoObj.getPercentDoneInThousandNotation();
+
+		if (!cell.setSortValue(lCompleted) && cell.isValid()) {
+			return;
+		}
+
+		if (infoObj == null)
+			return;
+
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+
+				//Compute bounds ...
+				int newWidth = cell.getWidth();
+				if (newWidth <= 0)
+					return;
+				int newHeight = cell.getHeight();
+
+				int x0 = borderVerticalSize;
+				int x1 = newWidth - 1 - borderVerticalSize;
+				int y0 = completionHeight + borderHorizontalSize + borderSplit;
+				int y1 = newHeight - 1 - borderHorizontalSize;
+				int drawWidth = x1 - x0 + 1;
+				if (drawWidth < 10 || y1 < 3)
+					return;
+				int[] imageBuffer = (int[]) infoObj.getData("PiecesImageBuffer");
+				boolean bImageBufferValid = imageBuffer != null
+						&& imageBuffer.length == drawWidth;
+
+				Image image = (Image) infoObj.getData("PiecesImage");
+				GC gcImage;
+				boolean bImageChanged;
+				Rectangle imageBounds;
+				if (image == null || image.isDisposed()) {
+					bImageChanged = true;
+				} else {
+					imageBounds = image.getBounds();
+					bImageChanged = imageBounds.width != newWidth
+							|| imageBounds.height != newHeight;
+				}
+				if (bImageChanged) {
+					if (image != null && !image.isDisposed()) {
+						image.dispose();
+					}
+					image = new Image(SWTThread.getInstance().getDisplay(), newWidth,
+							newHeight);
+					imageBounds = image.getBounds();
+					bImageBufferValid = false;
+
+					// draw border
+					gcImage = new GC(image);
+					gcImage.setForeground(Colors.grey);
+					if (borderHorizontalSize > 0) {
+						if (borderVerticalSize > 0) {
+							gcImage.drawRectangle(0, 0, newWidth - 1, newHeight - 1);
+						} else {
+							gcImage.drawLine(0, 0, newWidth - 1, 0);
+							gcImage.drawLine(0, newHeight - 1, newWidth - 1, newHeight - 1);
+						}
+					} else if (borderVerticalSize > 0) {
+						gcImage.drawLine(0, 0, 0, newHeight - 1);
+						gcImage.drawLine(newWidth - 1, 0, newWidth - 1, newHeight - 1);
+					}
+
+					if (borderSplit > 0) {
+						gcImage.setForeground(Colors.white);
+						gcImage.drawLine(x0, completionHeight + borderHorizontalSize, x1,
+								completionHeight + borderHorizontalSize);
+					}
+				} else {
+					gcImage = new GC(image);
+				}
+
+				final BitFlags peerHave = infoObj.getAvailable();
+				boolean established = ((PEPeerTransport) infoObj).getConnectionState() == PEPeerTransport.CONNECTION_FULLY_ESTABLISHED;
+
+				if (established && peerHave != null && peerHave.flags.length > 0) {
+					if (imageBuffer == null || imageBuffer.length != drawWidth) {
+						imageBuffer = new int[drawWidth];
+					}
+					final boolean available[] = peerHave.flags;
+					try {
+
+						int nbComplete = 0;
+						int nbPieces = available.length;
+
+						DiskManager disk_manager = infoObj.getManager().getDiskManager();
+						DiskManagerPiece[] pieces = disk_manager == null ? null
+								: disk_manager.getPieces();
+
+						int a0;
+						int a1 = 0;
+						for (int i = 0; i < drawWidth; i++) {
+							if (i == 0) {
+								// always start out with one piece
+								a0 = 0;
+								a1 = nbPieces / drawWidth;
+								if (a1 == 0)
+									a1 = 1;
+							} else {
+								// the last iteration, a1 will be nbPieces
+								a0 = a1;
+								a1 = ((i + 1) * nbPieces) / (drawWidth);
+							}
+
+							int index;
+							int nbNeeded = 0;
+
+							if (a1 <= a0) {
+								index = imageBuffer[i - 1];
+							} else {
+								int nbAvailable = 0;
+								for (int j = a0; j < a1; j++) {
+									if (available[j]) {
+										if (pieces == null || !pieces[j].isDone()) {
+											nbNeeded++;
+										}
+										nbAvailable++;
+									}
+								}
+								nbComplete += nbAvailable;
+								index = (nbAvailable * Colors.BLUES_DARKEST) / (a1 - a0);
+								if (nbNeeded <= nbAvailable / 2)
+									index += INDEX_COLOR_FADEDSTARTS;
+							}
+
+							if (imageBuffer[i] != index) {
+								imageBuffer[i] = index;
+								if (bImageBufferValid) {
+									bImageChanged = true;
+									if (imageBuffer[i] >= INDEX_COLOR_FADEDSTARTS)
+										gcImage.setForeground(Colors.faded[index
+												- INDEX_COLOR_FADEDSTARTS]);
+									else
+										gcImage.setForeground(Colors.blues[index]);
+									gcImage.drawLine(i + x0, y0, i + x0, y1);
+								}
+							}
+						}
+						if (!bImageBufferValid) {
+							if (established) {
+								int iLastIndex = imageBuffer[0];
+								int iWidth = 1;
+								for (int i = 1; i < drawWidth; i++) {
+									if (iLastIndex == imageBuffer[i]) {
+										iWidth++;
+									} else {
+										if (iLastIndex >= INDEX_COLOR_FADEDSTARTS) {
+											gcImage.setBackground(Colors.faded[iLastIndex
+													- INDEX_COLOR_FADEDSTARTS]);
+										} else
+											gcImage.setBackground(Colors.blues[iLastIndex]);
+										gcImage.fillRectangle(i - iWidth + x0, y0, iWidth, y1 - y0
+												+ 1);
+										iWidth = 1;
+										iLastIndex = imageBuffer[i];
+									}
+								}
+								if (iLastIndex >= INDEX_COLOR_FADEDSTARTS)
+									gcImage.setBackground(Colors.faded[iLastIndex
+											- INDEX_COLOR_FADEDSTARTS]);
+								else
+									gcImage.setBackground(Colors.blues[iLastIndex]);
+								gcImage.fillRectangle(x1 - iWidth + 1, y0, iWidth, y1 - y0 + 1);
+								bImageChanged = true;
+							}
+						}
+
+						int limit = (drawWidth * nbComplete) / nbPieces;
+						if (limit < drawWidth) {
+							gcImage.setBackground(Colors.blues[Colors.BLUES_LIGHTEST]);
+							gcImage.fillRectangle(limit + x0, borderHorizontalSize, x1
+									- limit, completionHeight);
+						}
+						gcImage.setBackground(Colors.colorProgressBar);
+						gcImage.fillRectangle(x0, borderHorizontalSize, limit,
+								completionHeight);
+					} catch (Exception e) {
+						System.out.println("Error Drawing PiecesItem");
+						Debug.printStackTrace(e);
+					}
+				} else {
+					gcImage.setForeground(Colors.grey);
+					gcImage.setBackground(Colors.grey);
+					gcImage.fillRectangle(x0, y0, newWidth, y1);
+				}
+				gcImage.dispose();
+
+				Image oldImage = null;
+				Graphic graphic = cell.getGraphic();
+				if (graphic instanceof UISWTGraphic) {
+					oldImage = ((UISWTGraphic) graphic).getImage();
+				}
+				if (bImageChanged || image != oldImage || !cell.isValid()) {
+					if (cell instanceof TableCellSWT) {
+						((TableCellSWT) cell).setGraphic(image);
+					} else {
+						cell.setGraphic(new UISWTGraphicImpl(image));
+					}
+					if (bImageChanged || image != oldImage) {
+						cell.invalidate();
+					}
+					infoObj.setData("PiecesImage", image);
+					infoObj.setData("PiecesImageBuffer", imageBuffer);
+				}
 			}
-      infoObj.setData("PiecesImage", image);
-      infoObj.setData("PiecesImageBuffer", imageBuffer);
-    }
-  }
+		});
+	}
 
 	// @see org.gudy.azureus2.core3.disk.DiskManagerListener#fileAccessModeChanged(org.gudy.azureus2.core3.disk.DiskManagerFileInfo, int, int)
 	public void fileAccessModeChanged(DiskManagerFileInfo file, int old_mode,
@@ -329,18 +353,18 @@ public class PiecesItem
 	public void pieceDoneChanged(DiskManagerPiece piece) {
 		DiskManager diskmanager = piece.getManager();
 
-		boolean	remove_listener;
-		synchronized( this ){
-			remove_listener = row_count==0;
+		boolean remove_listener;
+		synchronized (this) {
+			remove_listener = row_count == 0;
 		}
-		
-		if ( remove_listener ){
-			diskmanager.removeListener( this );
-		}else{
+
+		if (remove_listener) {
+			diskmanager.removeListener(this);
+		} else {
 			invalidateCells();
-	
-			if ( diskmanager.getRemaining() == 0 ){
-				
+
+			if (diskmanager.getRemaining() == 0) {
+
 				diskmanager.removeListener(this);
 			}
 		}
@@ -349,5 +373,5 @@ public class PiecesItem
 	// @see org.gudy.azureus2.core3.disk.DiskManagerListener#stateChanged(int, int)
 	public void stateChanged(int oldState, int newState) {
 	}
-  
+
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/peers/ProtocolItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/peers/ProtocolItem.java
new file mode 100644
index 0000000..c325c5d
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/peers/ProtocolItem.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 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.tableitems.peers;
+
+import org.gudy.azureus2.core3.peer.PEPeer;
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import org.gudy.azureus2.plugins.ui.tables.TableCell;
+import org.gudy.azureus2.plugins.ui.tables.TableCellRefreshListener;
+import org.gudy.azureus2.plugins.ui.tables.TableColumnInfo;
+
+/**
+ * 
+ */
+public class ProtocolItem
+       extends CoreTableColumn 
+       implements TableCellRefreshListener
+{
+	public static final String COLUMN_ID = "Protocol";
+
+	public void fillTableColumnInfo(TableColumnInfo info) {
+		info.addCategories(new String[] {
+			CAT_CONNECTION,
+		});
+	}
+
+  /** Default Constructor */
+  public ProtocolItem(String table_id) {
+    super(COLUMN_ID, ALIGN_CENTER, POSITION_INVISIBLE, 50, table_id);
+    setRefreshInterval(INTERVAL_LIVE);
+  }
+
+  public void refresh(TableCell cell) {
+    PEPeer peer = (PEPeer)cell.getDataSource();
+    String value = peer == null ? "" : peer.getProtocol();
+
+    if (!cell.setSortValue(value) && cell.isValid())
+      return;
+
+    cell.setText(value);
+  }
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/pieces/BlocksItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/pieces/BlocksItem.java
index b0b45f3..39aa58b 100644
--- a/org/gudy/azureus2/ui/swt/views/tableitems/pieces/BlocksItem.java
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/pieces/BlocksItem.java
@@ -29,6 +29,8 @@ import org.eclipse.swt.graphics.Image;
 import org.gudy.azureus2.core3.disk.DiskManager;
 import org.gudy.azureus2.core3.peer.PEPiece;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
+import org.gudy.azureus2.core3.util.AERunnable;
+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.plugins.UISWTGraphic;
@@ -92,14 +94,20 @@ public class BlocksItem
 		cell.setFillCell(true);
 	}
 
-	public void dispose(TableCell cell) {
-		Image img = ((TableCellSWT) cell).getGraphicSWT();
-		if (img != null && !img.isDisposed())
-			img.dispose();
+	public void dispose(final TableCell cell) {
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+				Image img = ((TableCellSWT) cell).getGraphicSWT();
+				if (img != null && !img.isDisposed()) {
+					img.dispose();
+				}
+			}
+		});
 	}
 
-	public void refresh(TableCell cell) {
-		PEPiece pePiece = (PEPiece) cell.getDataSource();
+	public void refresh(final TableCell cell) {
+		final PEPiece pePiece = (PEPiece) cell.getDataSource();
 		if (pePiece == null) {
 			cell.setSortValue(0);
 			dispose(cell);
@@ -108,126 +116,135 @@ public class BlocksItem
 		}
 
 		cell.setSortValue(pePiece.getNbWritten());
-		long lNumBlocks = pePiece.getNbBlocks();
-
-		int newWidth = cell.getWidth();
-		if (newWidth <= 0) {
-			dispose(cell);
-			cell.setGraphic(null);
-			return;
-		}
-		int newHeight = cell.getHeight();
-
-		int x1 = newWidth - 2;
-		int y1 = newHeight - 3;
-		if (x1 < 10 || y1 < 3) {
-			dispose(cell);
-			cell.setGraphic(null);
-			return;
-		}
-		Image image = new Image(SWTThread.getInstance().getDisplay(), newWidth,
-				newHeight);
-		Color color;
-		GC gcImage = new GC(image);
-		gcImage.setForeground(Colors.grey);
-		gcImage.drawRectangle(0, 0, x1 + 1, y1 + 1);
-		int blocksPerPixel = 0;
-		int iPixelsPerBlock = 0;
-		int pxRes = 0;
-		long pxBlockStep = 0;
-		int factor = 4;
-
-		while (iPixelsPerBlock <= 0) {
-			blocksPerPixel++;
-			iPixelsPerBlock = (int) ((x1 + 1) / (lNumBlocks / blocksPerPixel));
-		}
 
-		pxRes = (int) (x1 - ((lNumBlocks / blocksPerPixel) * iPixelsPerBlock)); // kolik mi zbyde
-		if (pxRes <= 0)
-			pxRes = 1;
-		pxBlockStep = (lNumBlocks * factor) / pxRes; // kolikaty blok na +1 k sirce
-		long addBlocks = (lNumBlocks * factor) / pxBlockStep;
-		if ((addBlocks * iPixelsPerBlock) > pxRes)
-			pxBlockStep += 1;
-
-		/*      String msg = "iPixelsPerBlock = "+iPixelsPerBlock + ", blocksPerPixel = " + blocksPerPixel;
-		      msg += ", pxRes = " + pxRes + ", pxBlockStep = " + pxBlockStep + ", addBlocks = " + addBlocks + ", x1 = " + x1;
-		      Debug.out(msg);*/
-
-		TOTorrent torrent = pePiece.getManager().getDiskManager().getTorrent();
-
-		boolean[] written = pePiece.getDMPiece().getWritten();
-		boolean piece_written = pePiece.isWritten();
-		int drawnWidth = 0;
-		int blockStep = 0;
-
-		int pieceNumber = pePiece.getPieceNumber();
-		long[] offsets = new long[(int) lNumBlocks];
-		long[] lengths = (long[]) offsets.clone();
-		Arrays.fill(offsets,
-				(long) pePiece.getManager().getDiskManager().getPieceLength()
-						* (long) pieceNumber);
-		for (int i = 0; i < lNumBlocks; lengths[i] = pePiece.getBlockSize(i), offsets[i] += DiskManager.BLOCK_SIZE * i, i++)
-			;
-
-		boolean[] isCached = cacheStats == null ? null
-				: cacheStats.getBytesInCache(torrent, offsets, lengths);
-
-		for (int i = 0; i < lNumBlocks; i += blocksPerPixel) {
-			int nextWidth = iPixelsPerBlock;
-
-			blockStep += blocksPerPixel * factor;
-			if (blockStep >= pxBlockStep) { // pokud jsem prelezl dany pocet bloku, zvys tomuhle sirku
-				nextWidth += (int) (blockStep / pxBlockStep);
-				blockStep -= pxBlockStep;
+		Utils.execSWTThread(new AERunnable() {
+
+			public void runSupport() {
+
+				long lNumBlocks = pePiece.getNbBlocks();
+
+				int newWidth = cell.getWidth();
+				if (newWidth <= 0) {
+					dispose(cell);
+					cell.setGraphic(null);
+					return;
+				}
+				int newHeight = cell.getHeight();
+
+				int x1 = newWidth - 2;
+				int y1 = newHeight - 3;
+				if (x1 < 10 || y1 < 3) {
+					dispose(cell);
+					cell.setGraphic(null);
+					return;
+				}
+				Image image = new Image(SWTThread.getInstance().getDisplay(), newWidth,
+						newHeight);
+				Color color;
+				GC gcImage = new GC(image);
+				gcImage.setForeground(Colors.grey);
+				gcImage.drawRectangle(0, 0, x1 + 1, y1 + 1);
+				int blocksPerPixel = 0;
+				int iPixelsPerBlock = 0;
+				int pxRes = 0;
+				long pxBlockStep = 0;
+				int factor = 4;
+
+				while (iPixelsPerBlock <= 0) {
+					blocksPerPixel++;
+					iPixelsPerBlock = (int) ((x1 + 1) / (lNumBlocks / blocksPerPixel));
+				}
+
+				pxRes = (int) (x1 - ((lNumBlocks / blocksPerPixel) * iPixelsPerBlock)); // kolik mi zbyde
+				if (pxRes <= 0)
+					pxRes = 1;
+				pxBlockStep = (lNumBlocks * factor) / pxRes; // kolikaty blok na +1 k sirce
+				long addBlocks = (lNumBlocks * factor) / pxBlockStep;
+				if ((addBlocks * iPixelsPerBlock) > pxRes)
+					pxBlockStep += 1;
+
+				/*      String msg = "iPixelsPerBlock = "+iPixelsPerBlock + ", blocksPerPixel = " + blocksPerPixel;
+				      msg += ", pxRes = " + pxRes + ", pxBlockStep = " + pxBlockStep + ", addBlocks = " + addBlocks + ", x1 = " + x1;
+				      Debug.out(msg);*/
+
+				TOTorrent torrent = pePiece.getManager().getDiskManager().getTorrent();
+
+				boolean[] written = pePiece.getDMPiece().getWritten();
+				boolean piece_written = pePiece.isWritten();
+				int drawnWidth = 0;
+				int blockStep = 0;
+
+				int pieceNumber = pePiece.getPieceNumber();
+				long[] offsets = new long[(int) lNumBlocks];
+				long[] lengths = (long[]) offsets.clone();
+				Arrays.fill(offsets,
+						(long) pePiece.getManager().getDiskManager().getPieceLength()
+								* (long) pieceNumber);
+				for (int i = 0; i < lNumBlocks; lengths[i] = pePiece.getBlockSize(i), offsets[i] += DiskManager.BLOCK_SIZE
+						* i, i++)
+					;
+
+				boolean[] isCached = cacheStats == null ? null
+						: cacheStats.getBytesInCache(torrent, offsets, lengths);
+
+				for (int i = 0; i < lNumBlocks; i += blocksPerPixel) {
+					int nextWidth = iPixelsPerBlock;
+
+					blockStep += blocksPerPixel * factor;
+					if (blockStep >= pxBlockStep) { // pokud jsem prelezl dany pocet bloku, zvys tomuhle sirku
+						nextWidth += (int) (blockStep / pxBlockStep);
+						blockStep -= pxBlockStep;
+					}
+
+					if (i >= lNumBlocks - blocksPerPixel) { // pokud je posledni, at zasahuje az na konec
+						nextWidth = x1 - drawnWidth;
+					}
+					color = Colors.white;
+
+					if ((written == null && piece_written)
+							|| (written != null && written[i])) {
+
+						color = colors[COLOR_WRITTEN];
+
+					} else if (pePiece.isDownloaded(i)) {
+
+						color = colors[COLOR_DOWNLOADED];
+
+					} else if (pePiece.isRequested(i)) {
+
+						color = colors[COLOR_REQUESTED];
+					}
+
+					gcImage.setBackground(color);
+					gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, y1);
+
+					if (isCached[i]) {
+						gcImage.setBackground(colors[COLOR_INCACHE]);
+						gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, 3);
+
+					}
+
+					drawnWidth += nextWidth;
+
+				}
+				gcImage.dispose();
+
+				Image oldImage = null;
+				Graphic graphic = cell.getGraphic();
+				if (graphic instanceof UISWTGraphic) {
+					oldImage = ((UISWTGraphic) graphic).getImage();
+				}
+
+				if (cell instanceof TableCellSWT) {
+					((TableCellSWT) cell).setGraphic(image);
+				} else {
+					cell.setGraphic(new UISWTGraphicImpl(image));
+				}
+				if (oldImage != null && !oldImage.isDisposed())
+					oldImage.dispose();
+
+				gcImage.dispose();
 			}
-
-			if (i >= lNumBlocks - blocksPerPixel) { // pokud je posledni, at zasahuje az na konec
-				nextWidth = x1 - drawnWidth;
-			}
-			color = Colors.white;
-
-			if ((written == null && piece_written) || (written != null && written[i])) {
-
-				color = colors[COLOR_WRITTEN];
-
-			} else if (pePiece.isDownloaded(i)) {
-
-				color = colors[COLOR_DOWNLOADED];
-
-			} else if (pePiece.isRequested(i)) {
-
-				color = colors[COLOR_REQUESTED];
-			}
-
-			gcImage.setBackground(color);
-			gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, y1);
-
-			if (isCached[i]) {
-				gcImage.setBackground(colors[COLOR_INCACHE]);
-				gcImage.fillRectangle(drawnWidth + 1, 1, nextWidth, 3);
-
-			}
-
-			drawnWidth += nextWidth;
-
-		}
-		gcImage.dispose();
-		
-		Image oldImage = null;
-		Graphic graphic = cell.getGraphic();
-		if (graphic instanceof UISWTGraphic) {
-			oldImage = ((UISWTGraphic)graphic).getImage();
-		}
-
-		if (cell instanceof TableCellSWT) {
-			((TableCellSWT) cell).setGraphic(image);
-		} else {
-			cell.setGraphic(new UISWTGraphicImpl(image));
-		}
-		if (oldImage != null && !oldImage.isDisposed())
-			oldImage.dispose();
-
-		gcImage.dispose();
+		});
 	}
 }
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/IntervalItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/IntervalItem.java
new file mode 100644
index 0000000..508e4e9
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/IntervalItem.java
@@ -0,0 +1,99 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+IntervalItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	IntervalItem()
+	{
+		super( "interval", ALIGN_CENTER, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		long	interval 		= 0;
+		long	min_interval 	= 0;
+
+		if ( ps != null ){
+			
+			interval		= ps.getInterval();
+			min_interval	= ps.getMinInterval();
+		}
+		
+		long	sort = ( interval<<31 ) | min_interval;
+		
+		if (!cell.setSortValue(sort) && cell.isValid()){
+		
+			return;
+		}
+
+		String	str;
+		
+		if ( interval <= 0 && min_interval <= 0 ){
+			
+			str = "";
+			
+		}else if ( interval <= 0 ){
+			
+			str = "(" + min_interval + ")";
+			
+		}else if ( min_interval <= 0 ){
+		
+			str = String.valueOf( interval );
+			
+		}else{
+		
+			str = interval + " (" + min_interval + ")";
+		}
+		
+		cell.setText( str );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/LeechersItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/LeechersItem.java
new file mode 100644
index 0000000..4d53b57
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/LeechersItem.java
@@ -0,0 +1,71 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+LeechersItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	LeechersItem()
+	{
+		super( "leechers", ALIGN_CENTER, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int value = (ps==null)?-1:ps.getLeecherCount();
+
+		if (!cell.setSortValue(value) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText(value<0?"":String.valueOf( value ));
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/NameItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/NameItem.java
new file mode 100644
index 0000000..64589be
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/NameItem.java
@@ -0,0 +1,72 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+NameItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	NameItem()
+	{
+		super( "name", ALIGN_LEAD, POSITION_LAST, 300, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		String name = (ps==null)?"":ps.getName();
+
+		if (!cell.setSortValue(name) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText( name );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/PeersItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/PeersItem.java
new file mode 100644
index 0000000..97cc2b5
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/PeersItem.java
@@ -0,0 +1,72 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+PeersItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	PeersItem()
+	{
+		super( "peers", ALIGN_CENTER, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int value = (ps==null)?-1:ps.getPeers();
+
+		if (!cell.setSortValue(value) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText(value<0?"":String.valueOf( value ));
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/SeedsItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/SeedsItem.java
new file mode 100644
index 0000000..23f93f0
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/SeedsItem.java
@@ -0,0 +1,72 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+SeedsItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	SeedsItem()
+	{
+		super( "seeds", ALIGN_CENTER, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int value = (ps==null)?-1:ps.getSeedCount();
+
+		if (!cell.setSortValue(value) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText(value<0?"":String.valueOf( value ));
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/StatusItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/StatusItem.java
new file mode 100644
index 0000000..f0c139d
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/StatusItem.java
@@ -0,0 +1,139 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import java.util.Locale;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+StatusItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	private static final String[] js_resource_keys = {
+		"SpeedView.stats.unknown",
+		"pairing.status.disabled",
+		"ManagerItem.stopped",
+		"ManagerItem.queued",
+		"GeneralView.label.updatein.querying",
+		"azbuddy.ui.table.online",
+		"ManagerItem.error",
+		"tps.status.available",
+		"tps.status.unavailable",
+		"ManagerItem.initializing",
+	};
+
+	private static String[] js_resources = new String[js_resource_keys.length];
+
+	
+	public 
+	StatusItem()
+	{
+		super( "status", ALIGN_LEAD, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_GRAPHIC );
+		
+		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]);
+				}
+			}
+		});
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+		info.setProficiency(TableColumnInfo.PROFICIENCY_BEGINNER);
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int status;
+		
+		if ( ps == null ){
+			
+			status = TrackerPeerSource.ST_UNKNOWN;
+			
+		}else{
+			
+			if ( ps.isUpdating()){
+				
+				status = TrackerPeerSource.ST_UPDATING;
+				
+			}else{
+				
+				status = ps.getStatus();
+			}
+		}
+
+		String str = js_resources[status];
+		
+		String extra = ps.getStatusString();
+
+		if ( status == TrackerPeerSource.ST_ONLINE ){
+			
+			if ( extra != null ){
+				
+				int	pos = extra.indexOf( " (" );
+				
+				if ( pos != -1 ){
+					
+					str += extra.substring( pos );
+				}
+			}
+		}else if ( status == TrackerPeerSource.ST_ERROR ){
+			
+			if ( extra != null ){
+				
+				str += ": " + extra;
+			}
+		}
+
+		if (!cell.setSortValue(str) && cell.isValid()){
+			
+			return;
+		}
+
+		cell.setText( str );
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/TypeItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/TypeItem.java
new file mode 100644
index 0000000..f67053c
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/TypeItem.java
@@ -0,0 +1,97 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import java.util.Locale;
+
+import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.internat.MessageText.MessageTextListener;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+TypeItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	private static final String[] js_resource_keys = {
+		"SpeedView.stats.unknown",
+		"MyTrackerView.tracker",
+		"wizard.webseed.title",
+		"tps.type.dht",
+		"ConfigView.section.transfer.lan",
+		"tps.type.pex",
+		"tps.type.incoming",
+		"tps.type.plugin",
+	};
+
+	private static String[] js_resources = new String[js_resource_keys.length];
+
+	
+	public 
+	TypeItem()
+	{
+		super( "type", ALIGN_LEAD, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval(INTERVAL_INVALID_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]);
+				}
+			}
+		});
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int value = (ps==null)?TrackerPeerSource.TP_UNKNOWN:ps.getType();
+
+		if (!cell.setSortValue(value) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText( js_resources[value]);
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/tableitems/tracker/UpdateInItem.java b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/UpdateInItem.java
new file mode 100644
index 0000000..9fd0d38
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/tableitems/tracker/UpdateInItem.java
@@ -0,0 +1,92 @@
+/*
+ * File    : TypeItem.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 org.gudy.azureus2.ui.swt.views.tableitems.tracker;
+
+import org.gudy.azureus2.core3.util.TimeFormatter;
+import org.gudy.azureus2.plugins.ui.tables.*;
+
+import org.gudy.azureus2.ui.swt.views.table.utils.CoreTableColumn;
+
+import com.aelitis.azureus.core.tracker.TrackerPeerSource;
+
+
+public class 
+UpdateInItem
+	extends CoreTableColumn 
+    implements TableCellRefreshListener
+{
+	public 
+	UpdateInItem()
+	{
+		super( "updatein", ALIGN_CENTER, POSITION_LAST, 75, TableManager.TABLE_TORRENT_TRACKERS );
+    
+		setRefreshInterval( INTERVAL_LIVE );
+	}
+
+	public void 
+	fillTableColumnInfo(
+		TableColumnInfo info ) 
+	{
+		info.addCategories( new String[]{
+			CAT_ESSENTIAL,
+		});
+	}
+
+	public void 
+	refresh(
+		TableCell cell ) 
+	{
+		TrackerPeerSource ps = (TrackerPeerSource)cell.getDataSource();
+    
+		int secs;
+		
+		if ( ps == null ){
+			
+			secs = -1;
+			
+		}else{
+			
+			int	state = ps.getStatus();
+			
+			if ( 	( 	state == TrackerPeerSource.ST_ONLINE || 
+						state == TrackerPeerSource.ST_ERROR ) &&
+					!ps.isUpdating()){
+				
+				secs = ps.getSecondsToUpdate();
+				
+			}else{
+				
+				secs = -1;
+			}
+		}
+
+		if (!cell.setSortValue(secs) && cell.isValid()){
+		
+			return;
+		}
+
+		cell.setText( TimeFormatter.formatColon( secs ));
+	}
+}
diff --git a/org/gudy/azureus2/ui/swt/views/utils/CategoryUIUtils.java b/org/gudy/azureus2/ui/swt/views/utils/CategoryUIUtils.java
new file mode 100644
index 0000000..6e5c4e9
--- /dev/null
+++ b/org/gudy/azureus2/ui/swt/views/utils/CategoryUIUtils.java
@@ -0,0 +1,399 @@
+/**
+ * Created on Nov 15, 2010
+ *
+ * Copyright 2010 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.utils;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+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.download.DownloadManager;
+import org.gudy.azureus2.core3.global.GlobalManager;
+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.plugins.PluginInterface;
+import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
+import org.gudy.azureus2.ui.swt.Messages;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
+import org.gudy.azureus2.ui.swt.Utils;
+import org.gudy.azureus2.ui.swt.views.ViewUtils;
+import org.gudy.azureus2.ui.swt.views.ViewUtils.SpeedAdapter;
+
+import com.aelitis.azureus.core.AzureusCoreFactory;
+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.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
+
+/**
+ * @author TuxPaper
+ * @created Nov 15, 2010
+ *
+ */
+public class CategoryUIUtils
+{
+	public static void setupCategoryMenu(final Menu menu, final Category category) {
+		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;
+
+				createMenuItems(menu, category);
+			}
+		});
+	}
+
+	public static void createMenuItems(final Menu menu, final Category category) {
+		if (category.getType() == Category.TYPE_USER) {
+
+			final MenuItem itemDelete = new MenuItem(menu, SWT.PUSH);
+
+			Messages.setLanguageText(itemDelete,
+					"MyTorrentsView.menu.category.delete");
+
+			itemDelete.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event event) {
+					GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+					List<?> managers = category.getDownloadManagers(gm.getDownloadManagers());
+					// move to array,since setcategory removed it from the category,
+					// which would mess up our loop
+					DownloadManager dms[] = managers.toArray(new DownloadManager[managers.size()]);
+					for (int i = 0; i < dms.length; i++) {
+						dms[i].getDownloadState().setCategory(null);
+					}
+					CategoryManager.removeCategory(category);
+				}
+			});
+		}
+
+		if (category.getType() != Category.TYPE_ALL) {
+
+			long maxDownload = COConfigurationManager.getIntParameter(
+					"Max Download Speed KBs", 0) * 1024;
+			long maxUpload = COConfigurationManager.getIntParameter(
+					"Max Upload Speed KBs", 0) * 1024;
+
+			int down_speed = category.getDownloadSpeed();
+			int up_speed = category.getUploadSpeed();
+
+			ViewUtils.addSpeedMenu(menu.getShell(), menu, true, true, false,
+					down_speed == 0, down_speed, down_speed, maxDownload, false,
+					up_speed == 0, up_speed, up_speed, maxUpload, 1, new SpeedAdapter() {
+						public void setDownSpeed(int val) {
+							category.setDownloadSpeed(val);
+						}
+
+						public void setUpSpeed(int val) {
+							category.setUploadSpeed(val);
+
+						}
+					});
+		}
+
+		GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+		List<?> managers = category.getDownloadManagers(gm.getDownloadManagers());
+
+		final DownloadManager dms[] = managers.toArray(new DownloadManager[managers.size()]);
+
+		boolean start = false;
+		boolean stop = false;
+
+		for (int i = 0; i < dms.length; i++) {
+
+			DownloadManager dm = dms[i];
+
+			stop = stop || ManagerUtils.isStopable(dm);
+
+			start = start || ManagerUtils.isStartable(dm);
+
+		}
+
+		// Queue
+
+		final MenuItem itemQueue = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemQueue, "MyTorrentsView.menu.queue");
+		Utils.setMenuItemImage(itemQueue, "start");
+		itemQueue.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+				List<?> managers = category.getDownloadManagers(gm.getDownloadManagers());
+
+				Object[] dms = managers.toArray();
+				TorrentUtil.queueDataSources(dms, true);
+			}
+		});
+		itemQueue.setEnabled(start);
+
+		// Stop
+
+		final MenuItem itemStop = new MenuItem(menu, SWT.PUSH);
+		Messages.setLanguageText(itemStop, "MyTorrentsView.menu.stop");
+		Utils.setMenuItemImage(itemStop, "stop");
+		itemStop.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				GlobalManager gm = AzureusCoreFactory.getSingleton().getGlobalManager();
+				List<?> managers = category.getDownloadManagers(gm.getDownloadManagers());
+
+				Object[] dms = managers.toArray();
+				TorrentUtil.stopDataSources(dms);
+			}
+		});
+		itemStop.setEnabled(stop);
+
+		// share with friends
+
+		PluginInterface bpi = PluginInitializer.getDefaultInterface().getPluginManager().getPluginInterfaceByClass(
+				BuddyPlugin.class);
+
+		int cat_type = category.getType();
+
+		if (bpi != null && cat_type != Category.TYPE_UNCATEGORIZED) {
+
+			final BuddyPlugin buddy_plugin = (BuddyPlugin) bpi.getPlugin();
+
+			if (buddy_plugin.isEnabled()) {
+
+				final Menu share_menu = new Menu(menu.getShell(), SWT.DROP_DOWN);
+				final MenuItem share_item = new MenuItem(menu, SWT.CASCADE);
+				Messages.setLanguageText(share_item, "azbuddy.ui.menu.cat.share");
+				share_item.setMenu(share_menu);
+
+				List<BuddyPluginBuddy> buddies = buddy_plugin.getBuddies();
+
+				if (buddies.size() == 0) {
+
+					final MenuItem item = new MenuItem(share_menu, SWT.CHECK);
+
+					item.setText(MessageText.getString("general.add.friends"));
+
+					item.setEnabled(false);
+
+				} else {
+					final String cname;
+
+					if (cat_type == Category.TYPE_ALL) {
+
+						cname = "All";
+
+					} else {
+
+						cname = category.getName();
+					}
+
+					final boolean is_public = buddy_plugin.isPublicCategory(cname);
+
+					final MenuItem itemPubCat = new MenuItem(share_menu, SWT.CHECK);
+
+					Messages.setLanguageText(itemPubCat, "general.all.friends");
+
+					itemPubCat.setSelection(is_public);
+
+					itemPubCat.addListener(SWT.Selection, new Listener() {
+						public void handleEvent(Event event) {
+							if (is_public) {
+
+								buddy_plugin.removePublicCategory(cname);
+
+							} else {
+
+								buddy_plugin.addPublicCategory(cname);
+							}
+						}
+					});
+
+					new MenuItem(share_menu, SWT.SEPARATOR);
+
+					for (final BuddyPluginBuddy buddy : buddies) {
+
+						if (buddy.getNickName() == null) {
+
+							continue;
+						}
+
+						final boolean auth = buddy.isLocalRSSCategoryAuthorised(cname);
+
+						final MenuItem itemShare = new MenuItem(share_menu, SWT.CHECK);
+
+						itemShare.setText(buddy.getName());
+
+						itemShare.setSelection(auth || is_public);
+
+						if (is_public) {
+
+							itemShare.setEnabled(false);
+						}
+
+						itemShare.addListener(SWT.Selection, new Listener() {
+							public void handleEvent(Event event) {
+								if (auth) {
+
+									buddy.removeLocalAuthorisedRSSCategory(cname);
+
+								} else {
+
+									buddy.addLocalAuthorisedRSSCategory(cname);
+								}
+							}
+						});
+
+					}
+				}
+			}
+		}
+
+		// auto-transcode
+
+		AZ3Functions.provider provider = AZ3Functions.getProvider();
+
+		if (provider != null && category.getType() != Category.TYPE_ALL) {
+
+			AZ3Functions.provider.TranscodeTarget[] tts = provider.getTranscodeTargets();
+
+			if (tts.length > 0) {
+
+				final Menu t_menu = new Menu(menu.getShell(), SWT.DROP_DOWN);
+				final MenuItem t_item = new MenuItem(menu, SWT.CASCADE);
+				Messages.setLanguageText(t_item, "cat.autoxcode");
+				t_item.setMenu(t_menu);
+
+				String existing = category.getStringAttribute(Category.AT_AUTO_TRANSCODE_TARGET);
+
+				for (AZ3Functions.provider.TranscodeTarget tt : tts) {
+
+					AZ3Functions.provider.TranscodeProfile[] profiles = tt.getProfiles();
+
+					if (profiles.length > 0) {
+
+						final Menu tt_menu = new Menu(t_menu.getShell(), SWT.DROP_DOWN);
+						final MenuItem tt_item = new MenuItem(t_menu, SWT.CASCADE);
+						tt_item.setText(tt.getName());
+						tt_item.setMenu(tt_menu);
+
+						for (final AZ3Functions.provider.TranscodeProfile tp : profiles) {
+
+							final MenuItem p_item = new MenuItem(tt_menu, SWT.CHECK);
+
+							p_item.setText(tp.getName());
+
+							boolean	selected = existing != null	&& existing.equals(tp.getUID());
+							
+							if ( selected ){
+								
+								Utils.setMenuItemImage(tt_item, "blackdot");
+							}
+							p_item.setSelection(selected );
+
+							p_item.addListener(SWT.Selection, new Listener() {
+								public void handleEvent(Event event) {
+									category.setStringAttribute(
+											Category.AT_AUTO_TRANSCODE_TARGET, p_item.getSelection()
+													? tp.getUID() : null);
+								}
+							});
+						}
+					}
+				}
+			}
+		}
+
+		// rss feed
+		
+		final MenuItem rssOption = new MenuItem(menu, SWT.CHECK );
+
+		rssOption.setSelection( category.getBooleanAttribute( Category.AT_RSS_GEN ));
+		
+		Messages.setLanguageText(rssOption, "cat.rss.gen");
+		rssOption.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				boolean set = rssOption.getSelection();
+				category.setBooleanAttribute( Category.AT_RSS_GEN, set );
+			}
+		});
+		
+		// upload priority
+		
+		if ( 	cat_type != Category.TYPE_UNCATEGORIZED &&
+				cat_type != Category.TYPE_ALL ){
+			
+			final MenuItem upPriority = new MenuItem(menu, SWT.CHECK );
+	
+			upPriority.setSelection( category.getIntAttribute( Category.AT_UPLOAD_PRIORITY ) > 0 );
+			
+			Messages.setLanguageText(upPriority, "cat.upload.priority");
+			upPriority.addListener(SWT.Selection, new Listener() {
+				public void handleEvent(Event event) {
+					boolean set = upPriority.getSelection();
+					category.setIntAttribute( Category.AT_UPLOAD_PRIORITY, set?1:0 );
+				}
+			});
+		}
+		
+		// options
+
+		MenuItem itemOptions = new MenuItem(menu, SWT.PUSH);
+
+		Messages.setLanguageText(itemOptions, "cat.options");
+		itemOptions.addListener(SWT.Selection, new Listener() {
+			public void handleEvent(Event event) {
+				UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions();
+
+				uiFunctions.openView(UIFunctions.VIEW_DM_MULTI_OPTIONS, dms);
+			}
+		});
+
+		if (dms.length == 0) {
+
+			itemOptions.setEnabled(false);
+		}
+	}
+
+}
diff --git a/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java b/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
index de74de7..fba51a3 100644
--- a/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
+++ b/org/gudy/azureus2/ui/swt/views/utils/ManagerUtils.java
@@ -24,16 +24,20 @@
 package org.gudy.azureus2.ui.swt.views.utils;
 
 import java.io.File;
+import java.util.Arrays;
 
 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.disk.DiskManagerFileInfo;
 import org.gudy.azureus2.core3.download.DownloadManager;
 import org.gudy.azureus2.core3.download.DownloadManagerState;
 import org.gudy.azureus2.core3.global.GlobalManagerDownloadRemovalVetoException;
 import org.gudy.azureus2.core3.internat.MessageText;
+import org.gudy.azureus2.core3.logging.LogAlert;
+import org.gudy.azureus2.core3.logging.Logger;
 import org.gudy.azureus2.core3.torrent.TOTorrent;
 import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse;
 import org.gudy.azureus2.core3.tracker.host.TRHostException;
@@ -44,15 +48,29 @@ 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;
+import org.gudy.azureus2.plugins.PluginInterface;
+import org.gudy.azureus2.plugins.download.Download;
 import org.gudy.azureus2.plugins.platform.PlatformManagerException;
+import org.gudy.azureus2.plugins.sharing.ShareManager;
+import org.gudy.azureus2.plugins.sharing.ShareResource;
+import org.gudy.azureus2.plugins.sharing.ShareResourceDir;
+import org.gudy.azureus2.plugins.sharing.ShareResourceFile;
+import org.gudy.azureus2.plugins.tracker.Tracker;
+import org.gudy.azureus2.plugins.tracker.TrackerTorrent;
+import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
 import org.gudy.azureus2.ui.swt.Alerts;
+import org.gudy.azureus2.ui.swt.TorrentUtil;
 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.AzureusCore;
+import com.aelitis.azureus.core.AzureusCoreFactory;
 import com.aelitis.azureus.core.AzureusCoreRunningListener;
+import com.aelitis.azureus.core.util.LaunchManager;
+import com.aelitis.azureus.ui.UIFunctions;
+import com.aelitis.azureus.ui.UIFunctionsManager;
 
 /**
  * @author Olivier
@@ -70,14 +88,42 @@ public class ManagerUtils {
 		ManagerUtils.run = run;
 	}
   
-  public static void run(DownloadManager dm) {
-    if(dm != null) {
-    	if (run != null) {
-    		run.run(dm);
-    	} else {
-    		Utils.launch(dm.getSaveLocation().toString());
-    	}
-    }
+  public static void run( final DownloadManager dm) {
+	if(dm != null) {
+		LaunchManager	launch_manager = LaunchManager.getManager();
+		
+		LaunchManager.LaunchTarget target = launch_manager.createTarget( dm );
+		
+		launch_manager.launchRequest(
+			target,
+			new LaunchManager.LaunchAction()
+			{
+				public void
+				actionAllowed()
+				{
+					Utils.execSWTThread(
+						new Runnable()
+						{
+							public void
+							run()
+							{
+							   	if (run != null) {
+						    		run.run(dm);
+						    	} else {
+						    		Utils.launch(dm.getSaveLocation().toString());
+						    	}
+							}
+						});
+				}
+				
+				public void
+				actionDenied(
+					Throwable			reason )
+				{
+					Debug.out( "Launch request denied", reason );
+				}
+			});
+	}
   }
   
  /**
@@ -86,10 +132,86 @@ public class ManagerUtils {
   */
 	public static void open(DownloadManager dm) {open(dm, false);}
 	
-	public static void open(DownloadManager dm, boolean open_containing_folder_mode) {
-		if (dm != null) {open(dm.getSaveLocation(), open_containing_folder_mode);}
+	public static void open(final DownloadManager dm, final boolean open_containing_folder_mode) {
+
+		if ( dm != null ){
+			
+			LaunchManager	launch_manager = LaunchManager.getManager();
+			
+			LaunchManager.LaunchTarget target = launch_manager.createTarget( dm );
+			
+			launch_manager.launchRequest(
+				target,
+				new LaunchManager.LaunchAction()
+				{
+					public void
+					actionAllowed()
+					{
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									open( dm.getSaveLocation(), open_containing_folder_mode );
+								}
+							});
+					}
+					
+					public void
+					actionDenied(
+						Throwable			reason )
+					{
+						Debug.out( "Launch request denied", reason );
+					}
+				});
+		}		
 	}
 
+	public static void 
+	open(
+		final DiskManagerFileInfo		file,
+		final boolean					open_containing_folder_mode )
+	{
+		if ( file != null ){
+			
+			LaunchManager	launch_manager = LaunchManager.getManager();
+			
+			LaunchManager.LaunchTarget target = launch_manager.createTarget( file );
+			
+			launch_manager.launchRequest(
+				target,
+				new LaunchManager.LaunchAction()
+				{
+					public void
+					actionAllowed()
+					{
+						Utils.execSWTThread(
+							new Runnable()
+							{
+								public void
+								run()
+								{
+									File this_file = file.getFile(true);
+									
+									File parent_file = (open_containing_folder_mode) ? this_file.getParentFile() : null;
+									
+									open((parent_file == null) ? this_file : parent_file);		
+								}
+							});
+					}
+					
+					public void
+					actionDenied(
+						Throwable			reason )
+					{
+						Debug.out( "Launch request denied", reason );
+					}
+				});
+		}
+	}
+	
+	
 	public static void open(File f, boolean open_containing_folder_mode) {
 		if (open_containing_folder_mode) {
 			Utils.launch(f.getParent());
@@ -231,7 +353,7 @@ public class ManagerUtils {
   public static void 
   queue(
   		DownloadManager dm,
-		Composite panel) 
+		Composite panelNotUsed) 
   {
     if (dm != null) {
     	if (dm.getState() == DownloadManager.STATE_STOPPED){
@@ -255,12 +377,8 @@ public class ManagerUtils {
   	stop(dm, shell, DownloadManager.STATE_STOPPED);
   }
   
-  public static void 
-  stop(
-  		final DownloadManager dm,
-		Shell shell,
-		int stateAfterStopped ) 
-  {
+	public static void stop(final DownloadManager dm, final Shell shell,
+			final int stateAfterStopped) {
 		if (dm == null) {
 			return;
 		}
@@ -279,10 +397,16 @@ public class ManagerUtils {
 			if (dm.getStats().getShareRatio() >= 0
 					&& dm.getStats().getShareRatio() < 1000
 					&& COConfigurationManager.getBooleanParameter("Alert on close", false)) {
-				if (shell == null) {
-					shell = Utils.findAnyShell();
+				if (!Utils.isThisThreadSWT()) {
+					Utils.execSWTThread(new AERunnable() {
+						public void runSupport() {
+							stop(dm, shell, stateAfterStopped);
+						}
+					});
+					return;
 				}
-				MessageBox mb = new MessageBox(shell, SWT.ICON_WARNING
+				Shell aShell = shell == null ? Utils.findAnyShell() : shell;
+				MessageBox mb = new MessageBox(aShell, SWT.ICON_WARNING
 						| SWT.YES | SWT.NO);
 				mb.setText(MessageText.getString("seedmore.title"));
 				mb.setMessage(MessageText.getString("seedmore.shareratio")
@@ -290,34 +414,6 @@ public class ManagerUtils {
 						+ MessageText.getString("seedmore.uploadmore"));
 				int action = mb.open();
 				stopme = action == SWT.YES;
-			} else if (dm.getDownloadState().isOurContent()
-					&& dm.getStats().getAvailability() < 2) {
-				TRTrackerScraperResponse scrape = dm.getTrackerScrapeResponse();
-				int numSeeds = scrape.getSeeds();
-	      long seedingStartedOn = dm.getStats().getTimeStartedSeeding();
-	      if ((numSeeds > 0) &&
-	          (seedingStartedOn > 0) &&
-	          (scrape.getScrapeStartTime() > seedingStartedOn))
-	        numSeeds--;
-	      
-	      if (numSeeds == 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;
-	      }
 			}
 		}
 		
@@ -326,71 +422,22 @@ public class ManagerUtils {
 		}
 	}
 
-  public static void remove(final DownloadManager dm, Shell shell,
+  /**
+   * @deprecated Use {@link TorrentUtil#removeDownloads(DownloadManager[], AERunnable)}
+   */
+  public static void remove(final DownloadManager dm, Shell unused_shell,
 			final boolean bDeleteTorrent, final boolean bDeleteData) {
-  	remove(dm, shell, bDeleteTorrent, bDeleteData, null);
+  	remove(dm, unused_shell, bDeleteTorrent, bDeleteData, null);
 	}
   
-  public static void remove(final DownloadManager dm, Shell shell,
+  /**
+   * @deprecated Use {@link TorrentUtil#removeDownloads(DownloadManager[], AERunnable)}
+   */
+  public static void remove(final DownloadManager dm, Shell unused_shell,
 			final boolean bDeleteTorrent, final boolean bDeleteData,
 			final AERunnable deleteFailed) {
-
-		if (!dm.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
-			if (COConfigurationManager.getBooleanParameter("confirm_torrent_removal")) {
-
-				String title = MessageText.getString("deletedata.title");
-				String text = MessageText.getString("deletetorrent.message1")
-						+ dm.getDisplayName() + " :\n" + dm.getTorrentFileName()
-						+ MessageText.getString("deletetorrent.message2");
-
-				MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO, title, text);
-				mb.setDefaultButtonUsingStyle(SWT.NO);
-				mb.setRelatedObject(dm);
-				mb.setLeftImage(SWT.ICON_WARNING);
-
-				mb.open(null);
-				int result = mb.waitUntilClosed();
-				if (result != SWT.YES) {
-					if (deleteFailed != null) {
-						deleteFailed.runSupport();
-					}
-					return;
-				}
-			}
-
-			boolean confirmDataDelete = COConfigurationManager.getBooleanParameter(
-					"Confirm Data Delete");
-
-			if (confirmDataDelete && bDeleteData) {
-				String path = dm.getSaveLocation().toString();
-
-				String title = MessageText.getString("deletedata.title");
-				String text = MessageText.getString("deletedata.message1",
-						new String[] {
-							dm.getDisplayName()
-						});
-						
-				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);
-
-				mb.open(null);
-				int result = mb.waitUntilClosed();
-				if (result != SWT.YES) {
-					if (deleteFailed != null) {
-						deleteFailed.runSupport();
-					}
-					return;
-				}
-			}
-		}
-
-		asyncStopDelete(dm, DownloadManager.STATE_STOPPED, bDeleteTorrent,
-				bDeleteData, deleteFailed);
+  	TorrentUtil.removeDownloads(new DownloadManager[] { dm }, null);
+  	Debug.out("ManagerUtils.remove is Deprecated.  Use TorrentUtil.removeDownloads");
 	}
   
   private static AsyncDispatcher async = new AsyncDispatcher(2000);
@@ -404,13 +451,92 @@ public class ManagerUtils {
 			public void runSupport() {
 
 				try {
+					// I would move the FLAG_DO_NOT_DELETE_DATA_ON_REMOVE even deeper
+					// but I fear what could possibly go wrong.
+					boolean reallyDeleteData = bDeleteData
+							&& !dm.getDownloadState().getFlag(
+									Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE);
+
 					dm.getGlobalManager().removeDownloadManager(dm, bDeleteTorrent,
-							bDeleteData);
+							reallyDeleteData);
 				} catch (GlobalManagerDownloadRemovalVetoException f) {
+					
+						// see if we can delete a corresponding share as users frequently share
+						// stuff by mistake and then don't understand how to delete the share
+						// properly
+					
+					try{
+						PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getDefaultPluginInterface();
+						
+						ShareManager sm = pi.getShareManager();
+						
+						Tracker	tracker = pi.getTracker();
+						
+						ShareResource[] shares = sm.getShares();
+						
+						TOTorrent torrent = dm.getTorrent();
+						
+						byte[] target_hash = torrent.getHash();
+						
+						for ( ShareResource share: shares ){
+							
+							int type = share.getType();
+							
+							byte[] hash;
+							
+							if ( type == ShareResource.ST_DIR ){
+								
+								hash = ((ShareResourceDir)share).getItem().getTorrent().getHash();
+								
+							}else if ( type == ShareResource.ST_FILE ){
+								
+								hash = ((ShareResourceFile)share).getItem().getTorrent().getHash();
+								
+							}else{
+								
+								hash = null;
+							}
+							
+							if ( hash != null ){
+								
+								if ( Arrays.equals( target_hash, hash )){
+									
+									try{
+										dm.stopIt( DownloadManager.STATE_STOPPED, false, false );
+										
+									}catch( Throwable e ){
+									}
+									
+									
+									try{
+						        		TrackerTorrent	tracker_torrent = tracker.getTorrent( PluginCoreUtils.wrap( torrent ));
+
+						        		if ( tracker_torrent != null ){
+						        			
+						        			tracker_torrent.stop();
+						        		}
+									}catch( Throwable e ){
+									}
+									
+									share.delete();
+									
+									return;
+								}
+							}
+						}
+						
+					}catch( Throwable e ){
+						
+					}
+					
 					if (!f.isSilent()) {
-						Alerts.showErrorMessageBoxUsingResourceString(new Object[] {
-							dm
-						}, "globalmanager.download.remove.veto", f, 0 );
+						UIFunctionsManager.getUIFunctions().forceNotify(
+							UIFunctions.STATUSICON_WARNING, 
+							MessageText.getString( "globalmanager.download.remove.veto" ), 
+							f.getMessage(), null, null, -1 );
+						
+						//Logger.log(new LogAlert(dm, false,
+						//		"{globalmanager.download.remove.veto}", f));
 					}
 					if (deleteFailed != null) {
 						deleteFailed.runSupport();
diff --git a/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java b/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
index 4b908a7..a7f5824 100644
--- a/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
+++ b/org/gudy/azureus2/ui/swt/welcome/WelcomeWindow.java
@@ -39,7 +39,6 @@ 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.core3.util.*;
 import org.gudy.azureus2.pluginsimpl.local.utils.resourcedownloader.ResourceDownloaderFactoryImpl;
@@ -54,8 +53,6 @@ import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFact
 
 public class WelcomeWindow {
 	
-	private static final String URL_WHATSNEW = "http://www.vuze.com/releasenotes";
-  
   private static final String lineSeparator = System.getProperty ("line.separator");
   
   Display display;
@@ -279,10 +276,6 @@ public class WelcomeWindow {
 				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");
 
diff --git a/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java b/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
index 4bed862..63ef55f 100644
--- a/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
+++ b/org/gudy/azureus2/ui/swt/win32/Win32UIEnhancer.java
@@ -22,14 +22,23 @@ package org.gudy.azureus2.ui.swt.win32;
 
 import java.io.File;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
 
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Device;
 import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.internal.win32.*;
 import org.eclipse.swt.widgets.Shell;
 
+import org.gudy.azureus2.core3.util.AEThread2;
+import org.gudy.azureus2.core3.util.Constants;
+import org.gudy.azureus2.platform.win32.access.AEWin32Access;
 import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
+import org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessImpl;
+import org.gudy.azureus2.platform.win32.access.impl.AEWin32AccessInterface;
 
 import com.aelitis.azureus.core.drivedetector.*;
 
@@ -45,6 +54,12 @@ public class Win32UIEnhancer
 
 	public static final boolean DEBUG = false;
 
+	public static final int SHGFI_ICON = 0x000000100;
+	
+	public static final int SHGFI_SMALLICON= 0x1;
+	
+	public static final int SHGFI_USEFILEATTRIBUTES = 0x000000010;
+
 	public static final int SHGFI_LARGEICON = 0x2;
 
 	public static final int WM_DEVICECHANGE = 0x219;
@@ -55,6 +70,8 @@ public class Win32UIEnhancer
 
 	public static final int DBT_DEVTYP_VOLUME = 0x2;
 
+	public static final int FILE_ATTRIBUTE_NORMAL = 0x00000080; 
+
 	private static int messageProcInt;
 
 	private static long messageProcLong;
@@ -81,9 +98,55 @@ public class Win32UIEnhancer
 
 	private static Method mOS_memmove_int;
 
+	private static boolean isUnicode;
+
+	private static Class<?> claSHFILEINFO;
+
+	private static Class<?> claSHFILEINFOA;
+
+	private static Class<?> claSHFILEINFOW;
+
+	private static Class<?> claTCHAR;
+
+	private static Method mSHGetFileInfo;
+
+	private static Method mImage_win32_new;
+
+	private static Constructor<?> constTCHAR3;
+
+	private static int SHFILEINFO_sizeof;
+
 	static {
 		try {
 			claOS = Class.forName("org.eclipse.swt.internal.win32.OS");
+			
+			isUnicode = claOS.getDeclaredField("IsUnicode").getBoolean(null);
+						
+			claSHFILEINFO = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFO");
+			
+			SHFILEINFO_sizeof = claSHFILEINFO.getField("sizeof").getInt(null);
+			
+			claSHFILEINFOA = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFOA");
+			claSHFILEINFOW = Class.forName("org.eclipse.swt.internal.win32.SHFILEINFOW");
+			
+			claTCHAR = Class.forName("org.eclipse.swt.internal.win32.TCHAR");
+			
+			// public TCHAR (int codePage, String string, boolean terminate) {
+			constTCHAR3 = claTCHAR.getConstructor(new Class[] {
+				int.class,
+				String.class,
+				boolean.class
+			});
+			
+			//public static long /*int*/ SHGetFileInfo (TCHAR pszPath, int dwFileAttributes, SHFILEINFO psfi, int cbFileInfo, int uFlags)
+			mSHGetFileInfo = claOS.getMethod("SHGetFileInfo", new Class<?>[] {
+				claTCHAR,
+				int.class,
+				claSHFILEINFO,
+				int.class,
+				int.class,
+			});
+
 
 			// public Callback (Object object, String method, int argCount)
 			claCallback = Class.forName("org.eclipse.swt.internal.Callback");
@@ -117,6 +180,12 @@ public class Win32UIEnhancer
 					int.class,
 					int.class
 				});
+				
+				mImage_win32_new = Image.class.getMethod("win32_new", new Class[] {
+					Device.class,
+					int.class,
+					int.class
+				});
 			} catch (Exception e) {
 				//e.printStackTrace();
 				mSetWindowLongPtr = claOS.getMethod("SetWindowLongPtr",
@@ -137,6 +206,12 @@ public class Win32UIEnhancer
 					long.class,
 					long.class
 				});
+
+				mImage_win32_new = Image.class.getMethod("win32_new", new Class[] {
+					Device.class,
+					int.class,
+					long.class
+				});
 			}
 
 			//OS.GWLP_WNDPROC
@@ -147,22 +222,49 @@ public class Win32UIEnhancer
 	}
 
 	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;
-		}
-		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;
+		try {
+  		int flags = SHGFI_ICON;
+  		flags |= big ? SHGFI_LARGEICON : SHGFI_SMALLICON;
+  		if (!file.exists()) {
+  			flags |= SHGFI_USEFILEATTRIBUTES;
+  		}
+  		Object shfi;
+  		if (isUnicode) {
+  			shfi = claSHFILEINFOW.newInstance();
+  		} else {
+  			shfi = claSHFILEINFOA.newInstance();
+  		}
+  		Object pszPath = constTCHAR3.newInstance(0, file.getAbsolutePath(), true);
+  		
+  		mSHGetFileInfo.invoke(null, new Object[] {
+  			pszPath,
+  			file.isDirectory() ? 16
+  					: FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO_sizeof, flags
+  		});
+  
+  		Field fldHIcon = claSHFILEINFO.getField("hIcon");
+  		if (fldHIcon.getLong(shfi) == 0) {
+  			return null;
+  		}
+  		Image image = null;
+  		if (useLong) {
+  			image = (Image) mImage_win32_new.invoke(null, new Object[] {
+  				null,
+  				SWT.ICON,
+  				fldHIcon.getLong(shfi)
+  			});
+  		} else {
+  			image = (Image) mImage_win32_new.invoke(null, new Object[] {
+  				null,
+  				SWT.ICON,
+  				fldHIcon.getInt(shfi)
+  			});
+  		}
+  		
+  		return image;
+		} catch (Exception e) {
+			return null;
 		}
-
-		return null;
 	}
 
 	public static void initMainShell(Shell shell) {
@@ -177,13 +279,14 @@ public class Win32UIEnhancer
 				4
 			});
 
+			Object oHandle = subshell.getClass().getField("handle").get(subshell);
 			if (useLong) {
 				Number n = (Number) mCallback_getAddress.invoke(messageCallback,
 						new Object[] {});
 				messageProcLong = n.longValue();
 				if (messageProcLong != 0) {
 					mSetWindowLongPtr.invoke(null, new Object[] {
-						subshell.handle,
+						oHandle,
 						OS_GWLP_WNDPROC,
 						messageProcLong
 					});
@@ -194,7 +297,7 @@ public class Win32UIEnhancer
 				messageProcInt = n.intValue();
 				if (messageProcInt != 0) {
 					mSetWindowLongPtr.invoke(null, new Object[] {
-						subshell.handle,
+						oHandle,
 						OS_GWLP_WNDPROC,
 						messageProcInt
 					});
@@ -204,12 +307,34 @@ public class Win32UIEnhancer
 			ex.printStackTrace();
 		}
 
-		File[] drives = AEWin32Manager.getAccessor(false).getUSBDrives();
-		if (drives != null) {
-			for (File file : drives) {
-				DriveDetectorFactory.getDeviceDetector().driveDetected(file);
+		new AEThread2( "Async:USB" )
+		{
+			public void
+			run()
+			{
+				if ( Constants.isWindows7OrHigher ){
+					
+					String version = AEWin32Manager.getAccessor( false ).getVersion();
+					
+					if ( Constants.compareVersions( "1.21", version ) > 0 ){
+				
+							// bug fixed in 1.21 whereby some win7 users got crashes
+						
+						return;
+					}
+				}
+				
+		  		Map<File, Map> drives = AEWin32Manager.getAccessor(false).getAllDrives();
+		  		if (drives != null) {
+		  			for (File file : drives.keySet()) {
+		  				Map driveInfo = drives.get(file);
+							boolean isWritableUSB = AEWin32Manager.getAccessor(false).isUSBDrive(driveInfo);
+							driveInfo.put("isWritableUSB", isWritableUSB);
+		  				DriveDetectorFactory.getDeviceDetector().driveDetected(file, driveInfo);
+		  			}
+		  		}
 			}
-		}
+		}.start();
 	}
 
 	static int /*long*/messageProc2(int /*long*/hwnd, int /*long*/msg,
@@ -264,21 +389,22 @@ public class Win32UIEnhancer
   								(int) st[0]
   							});
 							}
-							long unitMask = b[12] + (b[13] << 8) + (b[14] << 16)
-									+ (b[14] << 24);
+							long unitMask = (b[12] & 255) + ((b[13] & 255) << 8) + ((b[14] & 255) << 16)
+									+ ((b[15] & 3) << 24);
 							char letter = '?';
 							for (int i = 0; i < 26; i++) {
-								if (1 << i == unitMask) {
+								if (((1 << i) & unitMask) > 0) {
 									letter = (char) ('A' + i);
+									if (DEBUG) {
+										System.out.println("Drive " + letter + ";mask=" + unitMask);
+									}
+									Map driveInfo = AEWin32AccessInterface.getDriveInfo(letter);
+									boolean isWritableUSB = AEWin32Manager.getAccessor(false).isUSBDrive(driveInfo);
+									driveInfo.put("isWritableUSB", isWritableUSB);
+									DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
+									driveDetector.driveDetected(new File(letter + ":\\"), driveInfo);
 								}
 							}
-							if (DEBUG) {
-								System.out.println("Drive " + letter);
-							}
-							if (letter != '?') {
-								DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
-								driveDetector.driveDetected(new File(letter + ":\\"));
-							}
 						}
 
 					} else if (wParam == DBT_DEVICEREMOVECOMPLETE) {
@@ -320,21 +446,35 @@ public class Win32UIEnhancer
   								(int) st[0]
   							});
 							}
-							long unitMask = b[12] + (b[13] << 8) + (b[14] << 16)
-									+ (b[14] << 24);
+							long unitMask = (b[12] & 255) + ((b[13] & 255) << 8)
+									+ ((b[14] & 255) << 16) + ((b[15] & 3) << 24);
 							char letter = '?';
+							DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
 							for (int i = 0; i < 26; i++) {
-								if (1 << i == unitMask) {
+								if (((1 << i) & unitMask) > 0) {
 									letter = (char) ('A' + i);
+									if (DEBUG) {
+										System.out.println("Drive " + letter + ";mask=" + unitMask);
+									}
+									driveDetector.driveRemoved(new File(letter + ":\\"));
 								}
 							}
-							if (DEBUG) {
-								System.out.println("Drive " + letter);
-							}
-							if (letter != '?') {
-								DriveDetector driveDetector = DriveDetectorFactory.getDeviceDetector();
-								driveDetector.driveRemoved(new File(letter + ":\\"));
-							}
+
+							Map<File, Map> drives = AEWin32Manager.getAccessor(false).getAllDrives();
+				  		if (drives != null) {
+  							DriveDetectedInfo[] existingDrives = driveDetector.getDetectedDriveInfo();
+  							for (DriveDetectedInfo existingDrive : existingDrives) {
+  								File existingDriveFile = existingDrive.getLocation();
+  								boolean found = drives.containsKey(existingDriveFile);
+  								if (!found) {
+  									if (DEBUG) {
+  										System.out.println("Fixup: Remove Drive " + existingDriveFile);
+  									}
+  									driveDetector.driveRemoved(existingDriveFile);
+  								}
+  							}
+				  		}
+
 						}
 
 					}
diff --git a/org/gudy/azureus2/ui/swt/wizard/AbstractWizardPanel.java b/org/gudy/azureus2/ui/swt/wizard/AbstractWizardPanel.java
index b8368d0..d84d7f5 100644
--- a/org/gudy/azureus2/ui/swt/wizard/AbstractWizardPanel.java
+++ b/org/gudy/azureus2/ui/swt/wizard/AbstractWizardPanel.java
@@ -25,11 +25,11 @@ package org.gudy.azureus2.ui.swt.wizard;
  * @author Olivier
  * 
  */
-public abstract class AbstractWizardPanel implements IWizardPanel {
-  protected IWizardPanel previousPanel;
-  protected Wizard wizard;
+public abstract class AbstractWizardPanel<W extends Wizard> implements IWizardPanel<W> {
+  protected IWizardPanel<W> previousPanel;
+  protected W wizard;
 
-  public AbstractWizardPanel(Wizard wizard, IWizardPanel previousPanel) {
+  public AbstractWizardPanel(W wizard, IWizardPanel<W> previousPanel) {
     this.previousPanel = previousPanel;
     this.wizard = wizard;
   }
@@ -46,15 +46,15 @@ public abstract class AbstractWizardPanel implements IWizardPanel {
     return false;
   }
 
-  public IWizardPanel getPreviousPanel() {
+  public IWizardPanel<W> getPreviousPanel() {
     return previousPanel;
   }
 
-  public IWizardPanel getNextPanel() {
+  public IWizardPanel<W> getNextPanel() {
     return null;
   }
 
-  public IWizardPanel getFinishPanel() {
+  public IWizardPanel<W> getFinishPanel() {
     return null;
   }
 
@@ -63,6 +63,11 @@ public abstract class AbstractWizardPanel implements IWizardPanel {
   {
   	return( true );
   }
+  
+  public void cancelled()
+  {		
+  }
+  
   public void finish() {}
 
 }
diff --git a/org/gudy/azureus2/ui/swt/wizard/IWizardPanel.java b/org/gudy/azureus2/ui/swt/wizard/IWizardPanel.java
index 05710d0..51f52f9 100644
--- a/org/gudy/azureus2/ui/swt/wizard/IWizardPanel.java
+++ b/org/gudy/azureus2/ui/swt/wizard/IWizardPanel.java
@@ -25,13 +25,13 @@ package org.gudy.azureus2.ui.swt.wizard;
  * @author Olivier
  * 
  */
-public interface IWizardPanel {
+public interface IWizardPanel<W> {
   
   public void show();
   
-  public IWizardPanel getNextPanel();
-  public IWizardPanel getPreviousPanel();
-  public IWizardPanel getFinishPanel();
+  public IWizardPanel<W> getNextPanel();
+  public IWizardPanel<W> getPreviousPanel();
+  public IWizardPanel<W> getFinishPanel();
   
   public boolean isPreviousEnabled();
   public boolean isNextEnabled();
@@ -45,5 +45,7 @@ public interface IWizardPanel {
    */
   public boolean isFinishSelectionOK();
   
+  public void cancelled();
+  
   public void finish();
 }
diff --git a/org/gudy/azureus2/ui/swt/wizard/Wizard.java b/org/gudy/azureus2/ui/swt/wizard/Wizard.java
index e61579f..fdfbbb9 100644
--- a/org/gudy/azureus2/ui/swt/wizard/Wizard.java
+++ b/org/gudy/azureus2/ui/swt/wizard/Wizard.java
@@ -61,22 +61,47 @@ public class Wizard {
   
   int wizardHeight;
   
+  private boolean	completed;
+
+  public 
+  Wizard(
+	String keyTitle )
+  {
+	this( keyTitle, false );
+  }
+  
   public 
   Wizard(
   	String 			keyTitle,
-  	boolean modal) 
+  	boolean 		modal ) 
   {
-    this(modal);
-    setTitleKey(keyTitle);
+    this( modal );
+    
+    setTitleKey( keyTitle );
+  }
+  
+  public 
+  Wizard(
+  	String 			keyTitle,
+  	boolean 		modal,
+  	int				width )
+  {
+    this( modal, width );
+    
+    setTitleKey( keyTitle );
   }
 
-	public Wizard(String keyTitle) {
-		this(keyTitle, false);
-	}
-
   public 
   Wizard(
-  	boolean modal) 
+	boolean modal )
+  {
+	  this( modal, DEFAULT_WIDTH );
+  }
+  
+  public 
+  Wizard(
+  	boolean modal,
+  	int		width )
   {
   	int style = SWT.DIALOG_TRIM | SWT.RESIZE;
   	if (modal) {
@@ -113,8 +138,8 @@ public class Wizard {
     }
     titleFont=new Font(display,data);
     title.setFont(titleFont);
-    currentInfo = new Label(cTitle, SWT.NULL);
-    gridData = new GridData(GridData.FILL_HORIZONTAL);
+    currentInfo = new Label(cTitle, SWT.WRAP);
+    gridData = Utils.getWrappableLabelGridData(1, GridData.FILL_HORIZONTAL );
     currentInfo.setLayoutData(gridData);
     currentInfo.setBackground(white);
     errorMessage = new Label(cTitle, SWT.NULL);
@@ -217,7 +242,7 @@ public class Wizard {
        * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
        */
       public void handleEvent(Event arg0) {
-        wizardWindow.dispose();
+    	  cancelSelected();
       }
     });
 
@@ -241,15 +266,28 @@ public class Wizard {
 		}
 	});
  	
- 	wizardHeight = wizardWindow.computeSize(DEFAULT_WIDTH,SWT.DEFAULT).y - 50;
- 	wizardWindow.setSize(DEFAULT_WIDTH,400);
+ 	wizardHeight = wizardWindow.computeSize(width,SWT.DEFAULT).y - 50;
+ 	wizardWindow.setSize(width,400);
 
   }
 
-	private void
-   finishSelected()
-   {
-	   if ( currentPanel.isFinishSelectionOK()){      			   
+  private void
+  cancelSelected()
+  {
+	  completed = true;
+	  
+	  if ( currentPanel != null ){
+		  
+		  currentPanel.cancelled();
+	  }
+	  wizardWindow.dispose();
+  }
+  
+  private void
+  finishSelected()
+  {
+	   if ( currentPanel.isFinishSelectionOK()){   
+		   completed = true;
 		   wizardWindow.addListener(SWT.Close, closeCatcher);
 		   clearPanel();
 		   currentPanel = currentPanel.getFinishPanel();
@@ -259,6 +297,9 @@ public class Wizard {
   }
 
   private void clearPanel() {
+	if ( panel.isDisposed()){
+		return;
+	}
     Control[] controls = panel.getChildren();
     for (int i = 0; i < controls.length; i++) {
       if (controls[i] != null && !controls[i].isDisposed())
@@ -340,7 +381,9 @@ public class Wizard {
   }
 
   public void setCurrentInfo(String currentInfo) {
-    this.currentInfo.setText("\t" + currentInfo);
+	  currentInfo = currentInfo.replaceAll( "\n", "\n\t" );
+	  this.currentInfo.setText("\t" + currentInfo);
+	  this.currentInfo.getParent().layout();
   }
 
   public void setErrorMessage(String errorMessage) {
@@ -401,6 +444,17 @@ public class Wizard {
     }
   }
   
+  public void
+  close()
+  {
+	  completed = true;
+	  
+	  if ( !wizardWindow.isDisposed()){
+	  
+		  wizardWindow.dispose();
+	  }
+  }
+  
   public void onClose() {
   	if (titleFont != null && !titleFont.isDisposed()) {
   		titleFont.dispose();
@@ -411,6 +465,13 @@ public class Wizard {
   		
   		listeners.get(i).closed();
   	}
+  	
+  	if ( !completed ){
+  		
+  		completed = true;
+  		
+  		currentPanel.cancelled();
+  	}
   }  
   /**
    * @return Returns the currentPanel.
diff --git a/org/gudy/azureus2/ui/systray/Main.java b/org/gudy/azureus2/ui/systray/Main.java
deleted file mode 100644
index 7af8ae7..0000000
--- a/org/gudy/azureus2/ui/systray/Main.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * File    : Main.java
- * Created : 2 avr. 2004
- * By      : Olivier
- * 
- * 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.systray;
-
-  import org.eclipse.swt.*;
-  import org.eclipse.swt.graphics.*;
-  import org.eclipse.swt.widgets.*;
-
-  
-
-  public class Main {
-
-  public static void main(String[] args) {
-    Display display = new Display ();
-    Shell shell = new Shell (display);
-    Image image = new Image (display, 16, 16);
-    final Tray tray = display.getSystemTray ();
-    final TrayItem item = new TrayItem (tray, SWT.NONE);
-    item.setToolTipText("SWT TrayItem");
-    item.addListener (SWT.Show, new Listener () {
-      public void handleEvent (Event event) {
-        System.out.println("show");
-      }
-    });
-    item.addListener (SWT.Hide, new Listener () {
-      public void handleEvent (Event event) {
-        System.out.println("hide");
-      }
-    });
-    item.addListener (SWT.Selection, new Listener () {
-      public void handleEvent (Event event) {
-        System.out.println("selection");
-      }
-    });
-    item.addListener (SWT.DefaultSelection, new Listener () {
-      public void handleEvent (Event event) {
-        System.out.println("default selection");
-      }
-    });
-    final Menu menu = new Menu (shell, SWT.POP_UP);
-    for (int i = 0; i < 8; i++) {
-      MenuItem mi = new MenuItem (menu, SWT.PUSH);
-      mi.setText ("Item" + i);
-    }
-    item.addListener (SWT.MenuDetect, new Listener () {
-      public void handleEvent (Event event) {
-        menu.setVisible (true);
-      }
-    });
-    item.setImage (image);
-    shell.setBounds(50, 50, 300, 200);
-    shell.open ();
-    while (!shell.isDisposed ()) {
-      if (!display.readAndDispatch ()) display.sleep ();
-    }
-    image.dispose ();
-    display.dispose ();
-  }
-}
diff --git a/org/gudy/azureus2/ui/systray/SystemTraySWT.java b/org/gudy/azureus2/ui/systray/SystemTraySWT.java
index 1ca1bce..39fd000 100644
--- a/org/gudy/azureus2/ui/systray/SystemTraySWT.java
+++ b/org/gudy/azureus2/ui/systray/SystemTraySWT.java
@@ -60,7 +60,14 @@ import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
 public class SystemTraySWT
 	implements UIUpdatableAlways, MessageTextListener
 {
-
+	private static final SystemTraySWT	singleton = new SystemTraySWT();
+	
+	public static SystemTraySWT
+	getTray()
+	{
+		return( singleton );
+	}
+	
 	protected static AzureusCore core = null;
 
 	Display display;
@@ -90,7 +97,7 @@ public class SystemTraySWT
 
 	protected boolean enableTooltip;
 
-	public SystemTraySWT() {
+	private SystemTraySWT() {
 		AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
 			public void azureusCoreRunning(AzureusCore core) {
 				SystemTraySWT.core = core;
@@ -292,7 +299,14 @@ public class SystemTraySWT
 		
 		itemExit.addListener(SWT.Selection, new Listener() {
 			public void handleEvent(Event arg0) {
-    		uiFunctions.dispose(false, false);
+				// User got a stack overflow (all SWT code) because of this dispose,
+				// so execute it outside of the selection trigger and hope it doesn't
+				// overflow there.
+				Utils.execSWTThreadLater(0, new AERunnable() {
+					public void runSupport() {
+						uiFunctions.dispose(false, false);
+					}
+				});
 			}
 		});
 	}
diff --git a/org/gudy/azureus2/ui/webplugin/WebPlugin.java b/org/gudy/azureus2/ui/webplugin/WebPlugin.java
index 2fab9fc..711b5ef 100644
--- a/org/gudy/azureus2/ui/webplugin/WebPlugin.java
+++ b/org/gudy/azureus2/ui/webplugin/WebPlugin.java
@@ -45,6 +45,9 @@ 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.core.pairing.PairingTest;
+import com.aelitis.azureus.core.pairing.PairingTestListener;
+import com.aelitis.azureus.plugins.upnp.UPnPMapping;
 import com.aelitis.azureus.plugins.upnp.UPnPPlugin;
 
 public class 
@@ -60,6 +63,7 @@ WebPlugin
 	public static final String	PR_ACCESS					= "Access";						// String
 	public static final String	PR_LOG						= "DefaultLoggerChannel";		// LoggerChannel
 	public static final String	PR_CONFIG_MODEL_PARAMS		= "DefaultConfigModelParams";	// String[] params to use when creating config model
+	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
@@ -67,13 +71,21 @@ WebPlugin
 	
 	public static final String	PROPERTIES_MIGRATED		= "Properties Migrated";
 	public static final String	CONFIG_MIGRATED			= "Config Migrated";
-	
+	public static final String	PAIRING_MIGRATED		= "Pairing Migrated";
+	public static final String	PAIRING_SESSION_KEY		= "Pairing Session Key";
+
 	public static final String	CONFIG_PASSWORD_ENABLE			= "Password Enable";
 	public static final boolean	CONFIG_PASSWORD_ENABLE_DEFAULT	= false;
 	
 	public static final String	CONFIG_PAIRING_ENABLE			= "Pairing Enable";
 	public static final boolean	CONFIG_PAIRING_ENABLE_DEFAULT	= true;
 
+	public static final String	CONFIG_PORT_OVERRIDE			= "Port Override";
+	
+	public static final String	CONFIG_PAIRING_AUTO_AUTH			= "Pairing Auto Auth";
+	public static final boolean	CONFIG_PAIRING_AUTO_AUTH_DEFAULT	= true;
+
+	
 	public static final String	CONFIG_ENABLE					= PR_ENABLE;
 	public  			boolean	CONFIG_ENABLE_DEFAULT			= true;
 	
@@ -117,23 +129,68 @@ WebPlugin
 	protected static File[]				welcome_files;
 	
 	protected PluginInterface			plugin_interface;	// unfortunately this is accessed by webui - fix sometime
+	
 	private LoggerChannel			log;
-	private Tracker					tracker;
+	private PluginConfig			plugin_config;
 	private BasicPluginViewModel 	view_model;
 	private BasicPluginConfigModel	config_model;
 	
+	private StringParameter			param_home;
+	private StringParameter			param_rootdir;
+	private StringParameter			param_rootres;
+
 	private IntParameter			param_port;
 	private StringListParameter		param_protocol;
+	private StringParameter			param_bind;
+	
+	private StringParameter			param_access;
+	
+	private BooleanParameter		p_upnp_enable;
+	
+	private BooleanParameter		pw_enable;
+	private StringParameter			p_user_name;
+	private PasswordParameter		p_password;
+	
+	private BooleanParameter		param_auto_auth;
+	private IntParameter			param_port_or;
+	private boolean					setting_auto_auth;
+	private String					pairing_access_code;
+	private String					pairing_session_code;
+	
+	private boolean				plugin_enabled;
 	
 	private String				home_page;
 	private String				file_root;
 	private String				resource_root;
 	
+	private String				root_dir;
+	
 	private boolean				ip_range_all	= false;
 	private List<IPRange>		ip_ranges;
 	
+	private TrackerWebContext			tracker_context;
+	private UPnPMapping					upnp_mapping;
+	private PairingManagerListener		pairing_listener;
+	
 	private Properties	properties;
 	
+	private static ThreadLocal<String>		tls	= 
+		new ThreadLocal<String>()
+		{
+			public String
+			initialValue()
+			{
+				return( null );
+			}
+		};
+	
+	private static final int	LOGOUT_GRACE_MILLIS	= 5*1000;
+	private static final String	GRACE_PERIOD_MARKER	= "<grace_period>";
+	
+	private Map<String,Long>	logout_timer 		= new HashMap<String, Long>();
+	
+	private PairingManager	pairing_manager;
+	
 	public 
 	WebPlugin()
 	{
@@ -155,6 +212,20 @@ WebPlugin
 	{	
 		plugin_interface	= _plugin_interface;
 		
+		plugin_config = plugin_interface.getPluginconfig();
+
+		Properties plugin_properties = plugin_interface.getPluginProperties();
+		
+		if ( plugin_properties != null ){
+			
+			Object o = plugin_properties.get( "plugin." + PR_ROOT_DIR.replaceAll( " ", "_" ));
+			
+			if ( o instanceof String ){
+				
+				properties.put( PR_ROOT_DIR, o );
+			}
+		}
+		
 		Boolean	pr_enable = (Boolean)properties.get(PR_ENABLE);
 		
 		if ( pr_enable != null ){
@@ -243,21 +314,25 @@ WebPlugin
 				}
 			});
 		
-		PluginConfig	plugin_config = plugin_interface.getPluginconfig();
 		
-		String[] cm_params = (String[])properties.get( PR_CONFIG_MODEL_PARAMS );
-
-		if ( cm_params == null || cm_params.length == 0 ){
-			
-			config_model = ui_manager.createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, sConfigSectionID);
-			
-		}else if ( cm_params.length == 1 ){
-			
-			config_model = ui_manager.createBasicPluginConfigModel( cm_params[0] );
-
-		}else{
+		config_model = (BasicPluginConfigModel)properties.get( PR_CONFIG_MODEL );
+		
+		if ( config_model == null ){
 			
-			config_model = ui_manager.createBasicPluginConfigModel( cm_params[0], cm_params[1] );
+			String[] cm_params = (String[])properties.get( PR_CONFIG_MODEL_PARAMS );
+	
+			if ( cm_params == null || cm_params.length == 0 ){
+				
+				config_model = ui_manager.createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, sConfigSectionID);
+				
+			}else if ( cm_params.length == 1 ){
+				
+				config_model = ui_manager.createBasicPluginConfigModel( cm_params[0] );
+	
+			}else{
+				
+				config_model = ui_manager.createBasicPluginConfigModel( cm_params[0], cm_params[1] );
+			}
 		}
 		
 		boolean	save_needed = false;
@@ -365,116 +440,188 @@ WebPlugin
 			plugin_config.save();
 		}
 		
-		final LabelParameter param_info = config_model.addLabelParameter2( "webui.restart.info" );
-
 		Boolean	disablable = (Boolean)properties.get( PR_DISABLABLE );
-		
-		boolean	enabled = true;
-		
-		BooleanParameter	param_enable = null;
+				
+		final BooleanParameter	param_enable;
 		
 		if ( disablable != null && disablable ){
 			
 			param_enable = 
 				config_model.addBooleanParameter2( CONFIG_ENABLE, "webui.enable", CONFIG_ENABLE_DEFAULT );
-
-			enabled	= param_enable.getValue();
+			
+			plugin_enabled = param_enable.getValue();
+			
+		}else{
+			param_enable 	= null;
+			
+			plugin_enabled 	= true;
 		}
+		
+		initStage(1);
+		
 			// 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 );
+		param_bind = config_model.addStringParameter2(	CONFIG_BIND_IP, "webui.bindip", CONFIG_BIND_IP_DEFAULT );
 		
 		param_protocol = 
 			config_model.addStringListParameter2(
 					CONFIG_PROTOCOL, "webui.protocol", new String[]{ "http", "https" }, CONFIG_PROTOCOL_DEFAULT );
 		
+		ParameterListener update_server_listener = 
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param ) 
+				{
+					setupServer();
+				}
+			};
+		
+		param_port.addListener( update_server_listener );
+		param_bind.addListener( update_server_listener );
+		param_protocol.addListener( update_server_listener );		
 		
-		final BooleanParameter	upnp_enable = 
+		p_upnp_enable = 
 			config_model.addBooleanParameter2( 
 							CONFIG_UPNP_ENABLE, 
 							"webui.upnpenable",
 							CONFIG_UPNP_ENABLE_DEFAULT );
 
+		p_upnp_enable.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param ) 
+				{
+					setupUPnP();
+				}
+			});	
+		
+		plugin_interface.addListener(
+				new PluginListener()
+				{
+					public void
+					initializationComplete()
+					{
+						setupUPnP();
+					}
+					
+					public void
+					closedownInitiated()
+					{
+					}
+					
+					public void
+					closedownComplete()
+					{	
+					}
+				});
+		
+		
 		final String p_sid = (String)properties.get( PR_PAIRING_SID );
 		
-		final LabelParameter	pairing_info;
-		final BooleanParameter	pairing_enable;
+		final LabelParameter		pairing_info;
+		final BooleanParameter		pairing_enable;
+		final HyperlinkParameter	pairing_test;
+		final HyperlinkParameter	connection_test;
 		
 		if ( p_sid != null ){
 			
-			PairingManager pm = PairingManagerFactory.getSingleton();
+			final 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 = config_model.addBooleanParameter2( CONFIG_PAIRING_ENABLE, "webui.pairingenable", CONFIG_PAIRING_ENABLE_DEFAULT );
 			
-			pairing_enable.setEnabled( pm.isEnabled());
+			if ( !plugin_config.getPluginBooleanParameter( PAIRING_MIGRATED, false )){
 			
-			pm.addListener(
-				new PairingManagerListener()
-				{
-					public void 
-					somethingChanged(
-						PairingManager pm ) 
-					{
-						pairing_info.setLabelKey( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
-
-						pairing_enable.setEnabled( pm.isEnabled());
-					}		
-				});
+					// if they already have a password, don't override it by setting auto-auth
+				
+				boolean	has_pw_enabled = plugin_config.getPluginBooleanParameter( CONFIG_PASSWORD_ENABLE, CONFIG_PASSWORD_ENABLE_DEFAULT );
+				
+				if ( has_pw_enabled ){
+					
+					plugin_config.setPluginParameter( CONFIG_PAIRING_AUTO_AUTH, false );
+				}
+				
+				plugin_config.setPluginParameter( PAIRING_MIGRATED, true );
+			}
 			
-			setupPairing( p_sid, pairing_enable.getValue());
+			param_port_or	=  config_model.addIntParameter2( CONFIG_PORT_OVERRIDE, "webui.port.override", 0 );
+
+			param_auto_auth = config_model.addBooleanParameter2( CONFIG_PAIRING_AUTO_AUTH, "webui.pairing.autoauth", CONFIG_PAIRING_AUTO_AUTH_DEFAULT );
 			
-			ParameterListener update_pairing_listener = 
+			param_auto_auth.addListener(
 				new ParameterListener()
 				{
 					public void 
 					parameterChanged(
 						Parameter param ) 
 					{
-						updatePairing( p_sid );
+						if ( pairing_enable.getValue() && pm.isEnabled()){
+					
+							setupAutoAuth();
+						}
 					}
-				};
-				
-			param_port.addListener( update_pairing_listener );
-			param_protocol.addListener( update_pairing_listener );
+				});
+						
+			connection_test = config_model.addHyperlinkParameter2( "webui.connectiontest", getConnectionTestURL( p_sid ));
+
+			pairing_test = config_model.addHyperlinkParameter2( "webui.pairingtest", "http://remote.vuze.com/?sid=" + p_sid );
+
+				// listeners setup later as they depend on userame params etc
+			
 		}else{
 			pairing_info	= null;
 			pairing_enable 	= null;
+			param_auto_auth	= null;
+			param_port_or	= null;
+			pairing_test	= null;
+			connection_test	= null;
 		}
 			
 		config_model.createGroup(
+				"ConfigView.section.Pairing",
+				new Parameter[]{
+					pairing_info, pairing_enable, param_port_or, param_auto_auth, connection_test, pairing_test,
+				});
+		
+		config_model.createGroup(
 			"ConfigView.section.server",
 			new Parameter[]{
-				param_port, param_bind, param_protocol, upnp_enable, pairing_info, pairing_enable,
+				param_port, param_bind, param_protocol, p_upnp_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 );
+		param_home 		= config_model.addStringParameter2(	CONFIG_HOME_PAGE, "webui.homepage", CONFIG_HOME_PAGE_DEFAULT );
+		param_rootdir 	= config_model.addStringParameter2(	CONFIG_ROOT_DIR, "webui.rootdir", CONFIG_ROOT_DIR_DEFAULT );
+		param_rootres	= config_model.addStringParameter2(	CONFIG_ROOT_RESOURCE, "webui.rootres", CONFIG_ROOT_RESOURCE_DEFAULT );
 		
 		if ( pr_hide_resource_config != null && pr_hide_resource_config.booleanValue()){
 			
 			param_home.setVisible( false );
 			param_rootdir.setVisible( false );
 			param_rootres.setVisible( false );
+			
+		}else{
+			
+			ParameterListener update_resources_listener = 
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param ) 
+					{
+						setupResources();
+					}
+				};
+				
+			param_home.addListener( update_resources_listener );
+			param_rootdir.addListener( update_resources_listener );
+			param_rootres.addListener( update_resources_listener );
 		}
 		
 			// access group
@@ -486,50 +633,197 @@ WebPlugin
 		
 		
 		LabelParameter a_label2 = config_model.addLabelParameter2( "webui.access.info" );
-		StringParameter	param_access	= config_model.addStringParameter2(	CONFIG_ACCESS, "webui.access", CONFIG_ACCESS_DEFAULT );
 		
+		param_access	= config_model.addStringParameter2(	CONFIG_ACCESS, "webui.access", CONFIG_ACCESS_DEFAULT );
+		
+		param_access.addListener(
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param ) 
+				{
+					setupAccess();
+				}		
+			});
 		
-		final BooleanParameter	pw_enable = 
+		pw_enable = 
 			config_model.addBooleanParameter2( 
 							CONFIG_PASSWORD_ENABLE, 
 							"webui.passwordenable",
 							CONFIG_PASSWORD_ENABLE_DEFAULT );
 		
-		final StringParameter		user_name = 
+		p_user_name = 
 			config_model.addStringParameter2( 
 							CONFIG_USER, 
 							"webui.user",
 							CONFIG_USER_DEFAULT );
 		
-		final PasswordParameter	password = 
+		p_password = 
 			config_model.addPasswordParameter2( 
 							CONFIG_PASSWORD, 
 							"webui.password",
 							PasswordParameter.ET_SHA1,
 							CONFIG_PASSWORD_DEFAULT );
 		
-		pw_enable.addEnabledOnSelection( user_name );
-		pw_enable.addEnabledOnSelection( password );
+		pw_enable.addEnabledOnSelection( p_user_name );
+		pw_enable.addEnabledOnSelection( p_password );
 		
+		ParameterListener auth_change_listener = 
+			new ParameterListener()
+			{
+				public void 
+				parameterChanged(
+					Parameter param ) 
+				{
+					if ( param_auto_auth != null ){
+						
+						if ( !setting_auto_auth ){
+							
+							log( "Disabling pairing auto-authentication as overridden by user" );
+							
+							param_auto_auth.setValue( false );
+						}
+					}
+				}
+			};
 
+		p_user_name.addListener( auth_change_listener );
+		p_password.addListener( auth_change_listener );
+		pw_enable.addListener( auth_change_listener );
+			
 		config_model.createGroup(
 			"webui.group.access",
 			new Parameter[]{
 				a_label1, param_mode, a_label2, param_access,
-				pw_enable, user_name, password,
+				pw_enable, p_user_name, p_password,
 			});
 			    
+		if ( p_sid != null ){
+			
+			final PairingManager pm = PairingManagerFactory.getSingleton();
+
+			pairing_enable.addListener(
+					new ParameterListener()
+					{
+						public void 
+						parameterChanged(
+							Parameter param ) 
+						{
+							boolean enabled = pairing_enable.getValue();
+							
+							param_auto_auth.setEnabled( pm.isEnabled() && enabled );
+							param_port_or.setEnabled( pm.isEnabled() && enabled );
+							
+							boolean test_ok = pm.isEnabled() && pairing_enable.getValue() && pm.peekAccessCode() != null && !pm.hasActionOutstanding();
+
+							pairing_test.setEnabled( test_ok );
+							connection_test.setEnabled( test_ok );
+
+							setupPairing( p_sid, enabled );
+						}
+					});
+							
+			pairing_listener = 
+				new PairingManagerListener()
+				{
+					public void 
+					somethingChanged(
+						PairingManager pm ) 
+					{
+						pairing_info.setLabelKey( "webui.pairing.info." + (pm.isEnabled()?"y":"n"));
+	
+						if ( plugin_enabled ){
+							
+							pairing_enable.setEnabled( pm.isEnabled());
+								
+							param_auto_auth.setEnabled( pm.isEnabled() && pairing_enable.getValue() );
+							param_port_or.setEnabled( pm.isEnabled() && pairing_enable.getValue() );
+							
+							boolean test_ok = pm.isEnabled() && pairing_enable.getValue() && pm.peekAccessCode() != null && !pm.hasActionOutstanding();
+							
+							pairing_test.setEnabled( test_ok );
+							connection_test.setEnabled( test_ok );
+						}
+						
+						connection_test.setHyperlink( getConnectionTestURL( p_sid ));
+								  				
+						setupPairing( p_sid, pairing_enable.getValue());
+					}
+				};
+				
+			pairing_listener.somethingChanged( pm );
+			
+			pm.addListener( pairing_listener );
+
+			setupPairing( p_sid, pairing_enable.getValue());
+			
+			ParameterListener update_pairing_listener = 
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param ) 
+					{
+						updatePairing( p_sid );
+						
+						setupUPnP();
+					}
+				};
+				
+			param_port.addListener( update_pairing_listener );
+			
+			param_port_or.addListener( update_pairing_listener );
+			
+			param_protocol.addListener( update_pairing_listener );
+			
+			/*
+			config_model.addActionParameter2( "test", "test" ).addListener(
+				new ParameterListener()
+				{
+					public void 
+					parameterChanged(
+						Parameter param )
+					{
+						try{
+							pm.testService( 
+								p_sid,
+								new PairingTestListener()
+								{
+									public void 
+									testStarted(
+										PairingTest test )
+									{
+										System.out.println( "Test starts" );
+									}
+									
+									public void 
+									testComplete(
+										PairingTest test) 
+									{
+										System.out.println( "Test complete: " + test.getOutcome() + "/" + test.getErrorMessage());
+									}
+								});
+						}catch( Throwable e ){
+							
+							Debug.out( e );
+						}
+					}
+				});
+			*/
+		}
+		
 		if ( param_enable != null ){
 						
 			final List<Parameter> changed_params = new ArrayList<Parameter>();
 			
-			if ( !enabled ){
+			if ( !plugin_enabled){
 				
 				Parameter[] params = config_model.getParameters();
 
 				for ( Parameter param: params ){
 					
-					if ( param == param_enable || param == param_info ){
+					if ( param == param_enable ){
 						
 						continue;
 					}
@@ -554,9 +848,9 @@ WebPlugin
 							// badly and only toggles the UI component, not the enabled state of the
 							// underlying parameter. grr. better than nothing though
 						
-						boolean	is_enabled = ((BooleanParameter)e_p).getValue();
+						plugin_enabled = ((BooleanParameter)e_p).getValue();
 						
-						if ( is_enabled ){
+						if ( plugin_enabled ){
 						
 							for ( Parameter p: changed_params ){
 								
@@ -570,7 +864,7 @@ WebPlugin
 							
 							for ( Parameter param: params ){
 								
-								if ( param == e_p || param == param_info ){
+								if ( param == e_p ){
 									
 									continue;
 								}
@@ -583,57 +877,143 @@ WebPlugin
 								}
 							}
 						}
+						
+						setupServer();
+						
+						setupUPnP();
+						
+						if ( p_sid != null ){
+						
+							setupPairing( p_sid, pairing_enable.getValue());
+						}
 					}
 				});
-			
-			if ( !enabled ){
-				
-				return;
-			}
 		}
 		
 			// end config
-		
-		tracker = plugin_interface.getTracker();
-		
-		home_page = param_home.getValue().trim();
-		
-		if ( home_page.length() == 0 ){
-				
-			home_page = null;
-				
-		}else if (!home_page.startsWith("/" )){
-			
-			home_page = "/" + home_page;
-		}
-		
-		resource_root = param_rootres.getValue().trim();
-				
-		if ( resource_root.length() == 0 ){
 				
-			resource_root = null;
-				
-		}else if ( resource_root.startsWith("/" )){
+		setupResources();
 			
-			resource_root = resource_root.substring(1);
-		}
+		setupAccess();
+												
+		setupServer();
+	}
+	
+	protected void
+	initStage(
+		int	num )
+	{	
+	}
+	
+	private String
+	getConnectionTestURL(
+		String		sid )
+	{
+		String res = "http://pair.vuze.com/pairing/web/test?sid=" + sid;
 		
-		String	root_dir	= param_rootdir.getValue().trim();
+		PairingManager pm = PairingManagerFactory.getSingleton();
 		
-		if ( root_dir.length() == 0 ){
+		if ( pm.isEnabled()){
 			
-			file_root = plugin_interface.getPluginDirectoryName();
+			String ac = pm.peekAccessCode();
 			
-			if ( file_root == null ){
+			if ( ac != null ){
 				
-				file_root = SystemProperties.getUserPath() + "web";
+				res += "&ac=" + ac;
 			}
-		}else{
-			
-				// absolute or relative
-			
-			if ( root_dir.startsWith(File.separator) || root_dir.indexOf(":") != -1 ){
-				
+		}
+		
+		return( res );
+	}
+	
+	protected boolean
+	isPluginEnabled()
+	{
+		return( plugin_enabled );
+	}
+	
+	protected void
+	unloadPlugin()
+	{
+		if ( view_model != null ){
+		
+			view_model.destroy();
+		
+			view_model = null;
+		}
+		
+		if ( config_model != null ){
+			
+			config_model.destroy();
+			
+			config_model = null;
+		}
+	
+		if ( tracker_context != null ){
+			
+			tracker_context.destroy();
+			
+			tracker_context = null;
+		}
+		
+		if ( upnp_mapping != null ){
+			
+			upnp_mapping.destroy();
+			
+			upnp_mapping = null;
+		}
+		
+		if ( pairing_listener != null ){
+		
+			PairingManager pm = PairingManagerFactory.getSingleton();
+			
+			pm.removeListener( pairing_listener );
+			
+			pairing_listener = null;
+		}
+	}
+	
+	private void
+	setupResources()
+	{
+		home_page = param_home.getValue().trim();
+		
+		if ( home_page.length() == 0 ){
+				
+			home_page = null;
+				
+		}else if (!home_page.startsWith("/" )){
+			
+			home_page = "/" + home_page;
+		}
+		
+		resource_root = param_rootres.getValue().trim();
+				
+		if ( resource_root.length() == 0 ){
+				
+			resource_root = null;
+				
+		}else if ( resource_root.startsWith("/" )){
+			
+			resource_root = resource_root.substring(1);
+		}
+		
+		root_dir	= param_rootdir.getValue().trim();
+		
+		if ( root_dir.length() == 0 ){
+			
+			file_root = plugin_interface.getPluginDirectoryName();
+			
+			if ( file_root == null ){
+				
+				file_root = SystemProperties.getUserPath() + "web";
+			}
+		}else{
+			
+				// absolute or relative
+			
+			if ( root_dir.startsWith(File.separator) || root_dir.indexOf(":") != -1 ){
+				
 				file_root = root_dir;
 				
 			}else{
@@ -672,16 +1052,11 @@ WebPlugin
 			
 			log.log( LoggerChannel.LT_ERROR, error );
 			
-			throw( new PluginException( error ));
-		}
-
-		if ( !f_root.isDirectory()){
+		}else if ( !f_root.isDirectory()){
 			
 			String	error = "WebPlugin: root dir '" + file_root + "' isn't a directory";
 			
 			log.log( LoggerChannel.LT_ERROR, error );
-			
-			throw( new PluginException( error ));
 		}
 		
 		welcome_files = new File[welcome_pages.length];
@@ -690,39 +1065,18 @@ WebPlugin
 			
 			welcome_files[i] = new File( file_root + File.separator + welcome_pages[i] );
 		}
-		
-					
-		final int port	= param_port.getValue();
-
-		String	protocol_str = param_protocol.getValue().trim();
-		
-		String bind_ip_str = param_bind.getValue().trim();
-		
-		InetAddress	bind_ip = null;
-		
-		if ( bind_ip_str.length() > 0 ){
-			
-			try{
-				bind_ip = InetAddress.getByName( bind_ip_str );
-				
-			}catch( Throwable  e ){
-				
-				log.log( LoggerChannel.LT_ERROR, "Bind IP parameter '" + bind_ip_str + "' is invalid" );
-	
-			}
-		}
-		
-		int	protocol = protocol_str.equalsIgnoreCase( "HTTP")?Tracker.PR_HTTP:Tracker.PR_HTTPS;
+	}
 	
-		log.log( 	LoggerChannel.LT_INFORMATION, 
-					"Initialisation: port = " + port +
-					(bind_ip == null?"":(", bind = " + bind_ip_str + ")")) +
-					", protocol = " + protocol_str + (root_dir.length()==0?"":(", root = " + root_dir )));
-		
+	private void
+	setupAccess()
+	{
 		String	access_str = param_access.getValue().trim();
 		
 		String ip_ranges_str = "";
 		
+		ip_ranges 		= null;
+		ip_range_all	= false;
+		
 		if ( access_str.length() > 7 && Character.isDigit(access_str.charAt(0))){
 			
 			String[] ranges = access_str.replace( ';', ',' ).split( "," );
@@ -773,136 +1127,448 @@ WebPlugin
 			}
 		}else{
 			
-			if ( access_str.equalsIgnoreCase( "all" )){
+			if ( access_str.equalsIgnoreCase( "all" ) || access_str.length() == 0 ){
 								
 				ip_range_all	= true;				
 			}
 		}
 		
 		log.log( 	LoggerChannel.LT_INFORMATION, 
-					"Acceptable IP range = " +
-						( ip_ranges==null?
-							(ip_range_all?"all":"local"):
-							(ip_ranges_str)));
-				
-							
+				"Acceptable IP range = " +
+					( ip_ranges==null?
+						(ip_range_all?"all":"local"):
+						(ip_ranges_str)));
+	}
+	
+	protected void
+	setupServer()
+	{
 		try{
-			TrackerWebContext	context = 
-				tracker.createWebContext(
-						plugin_interface.getAzureusName() + " - " + plugin_interface.getPluginName(), 
+			if ( !plugin_enabled ){
+				
+				if ( tracker_context != null ){
+					
+					tracker_context.destroy();
+					
+					tracker_context = null;
+				}
+				
+				return;
+			}
+			
+			final int port	= param_port.getValue();
+
+			String	protocol_str = param_protocol.getValue().trim();
+			
+			String bind_ip_str = param_bind.getValue().trim();
+			
+			InetAddress	bind_ip = null;
+			
+			if ( bind_ip_str.length() > 0 ){
+				
+				try{
+					bind_ip = InetAddress.getByName( bind_ip_str );
+					
+				}catch( Throwable  e ){
+					
+					log.log( LoggerChannel.LT_ERROR, "Bind IP parameter '" + bind_ip_str + "' is invalid" );
+		
+				}
+			}
+			
+			if ( tracker_context != null ){
+				
+				URL	url = tracker_context.getURLs()[0];
+				
+				String		existing_protocol 	= url.getProtocol();
+				int			existing_port		= url.getPort()==-1?url.getDefaultPort():url.getPort();
+				InetAddress existing_bind_ip 	= tracker_context.getBindIP();
+				
+				if ( 	existing_port == port &&
+						existing_protocol.equalsIgnoreCase( protocol_str ) &&
+						sameAddress( bind_ip, existing_bind_ip )){
+					
+					return;
+				}
+				
+				tracker_context.destroy();
+				
+				tracker_context = null;
+			}
+
+			
+
+			int	protocol = protocol_str.equalsIgnoreCase( "HTTP")?Tracker.PR_HTTP:Tracker.PR_HTTPS;
+		
+			log.log( 	LoggerChannel.LT_INFORMATION, 
+						"Server initialisation: port = " + port +
+						(bind_ip == null?"":(", bind = " + bind_ip_str + ")")) +
+						", protocol = " + protocol_str + (root_dir.length()==0?"":(", root = " + root_dir )));
+
+			tracker_context = 
+				plugin_interface.getTracker().createWebContext(
+						Constants.APP_NAME + " - " + plugin_interface.getPluginName(), 
 						port, protocol, bind_ip );
 		
 			Boolean	pr_enable_keep_alive = (Boolean)properties.get( PR_ENABLE_KEEP_ALIVE );
 
 			if ( pr_enable_keep_alive != null && pr_enable_keep_alive ){
 			
-				context.setEnableKeepAlive( true );
+				tracker_context.setEnableKeepAlive( true );
 			}
 			
-			context.addPageGenerator( this );
+			tracker_context.addPageGenerator( this );
 	
-			context.addAuthenticationListener(
+			tracker_context.addAuthenticationListener(
 				new TrackerAuthenticationAdapter()
 				{
-					String	last_pw		= "";
-					byte[]	last_hash	= {};
+					private String	last_pw		= "";
+					private byte[]	last_hash	= {};
 					
-					AEMonitor	this_mon = new AEMonitor( "WebPlugin:auth" );
+					private final int DELAY = 10*1000;
+					
+					private Map<String,Object[]>	fail_map = new HashMap<String, Object[]>();
 					
 					public boolean
 					authenticate(
+						String		headers,
 						URL			resource,
 						String		user,
 						String		pw )
 					{
-						try{
-							this_mon.enter();
+						long	now = SystemTime.getMonotonousTime();
+
+						String	client_address = getHeaderField( headers, "X-Real-IP" );
 						
-							if ( !pw_enable.getValue()){
+						if ( client_address == null ){
+							
+							client_address = "<unknown>";
+						}
+
+						synchronized( logout_timer ){
+							
+							Long logout_time = logout_timer.get( client_address );
+							
+							if ( logout_time != null && now - logout_time <= LOGOUT_GRACE_MILLIS ){
+																
+								tls.set( GRACE_PERIOD_MARKER );
 								
 								return( true );
 							}
+						}
+						
+						boolean	result = authenticateSupport( headers, resource, user, pw );
+																				
+						if ( !result ){
 							
-							if ( !user.equals(user_name.getValue())){
+							AESemaphore waiter = null;
+							
+							synchronized( fail_map ){
+
 								
-								return( false );
+								Object[] x = fail_map.get( client_address );
+							
+								if ( x == null ){
+									
+									x = new Object[]{ new AESemaphore( "af:waiter" ), new Long(-1), new Long(-1), now };
+									
+									fail_map.put( client_address, x );
+									
+								}else{
+									
+									x[1] = x[2];
+									x[2] = x[3];
+									x[3] = now;
+									
+									long t = (Long)x[1];
+									
+									if ( now - t < 10*1000 ){
+										
+										log( "Too many recent authentication failures from '" + client_address + "' - rate limiting" );
+
+										x[2] = now+DELAY;
+										
+										waiter = (AESemaphore)x[0];
+									}
+								}
 							}
 							
-							byte[]	hash = last_hash;
+							if ( waiter != null ){
+								
+								waiter.reserve( DELAY );
+							}
+						}
+						
+						recordAuthRequest( client_address, result );
+						
+						return( result );
+					}
+					
+					private boolean
+					authenticateSupport(
+						String		headers,
+						URL			resource,
+						String		user,
+						String		pw )
+					{
+						boolean	result;
+						
+						boolean	auto_auth =  param_auto_auth != null && param_auto_auth.getValue();
+
+						if ( !pw_enable.getValue()){
+														
+							result = true;
 							
-							if (  !last_pw.equals( pw )){
-															
-								hash = plugin_interface.getUtilities().getSecurityManager().calculateSHA1( pw.getBytes());
+						}else{
+													
+							if ( auto_auth ){
 								
-								last_pw		= pw;
-								last_hash	= hash;
+								user = user.trim().toLowerCase();
 							}
 							
-							return( Arrays.equals( hash, password.getValue()));
+							if ( !user.equals( p_user_name.getValue())){
+								
+								result = false;
+								
+							}else{
 							
-						}finally{
+								byte[]	hash = last_hash;
+								
+								if (  !last_pw.equals( pw )){
+																
+									hash = plugin_interface.getUtilities().getSecurityManager().calculateSHA1( 
+											auto_auth?pw.toUpperCase().getBytes():pw.getBytes());
+									
+									last_pw		= pw;
+									last_hash	= hash;
+								}
+								
+								result = Arrays.equals( hash, p_password.getValue());
+							}
+						}
+						
+						if ( result ){
+						
+								// user name and password match, see if we've come from the pairing process 
+							
+							checkCookieSet( headers, resource );
+							
+						}else if ( auto_auth  ){
+							
+								// either the ac is in the url, referer or we have a cookie set
+														
+							int x = checkCookieSet( headers, resource );
+							
+							if ( x == 1 ){
+								
+								result = true;
+								
+							}else if ( x == 0 ){
+														
+								result = hasOurCookie( getHeaderField( headers, "Cookie" ));
+							}
+						}
+						
+						return( result );
+					}
+					
+						/**
+						 * 
+						 * @param headers
+						 * @param resource
+						 * @return 0 = unknown, 1 = ok, 2 = bad
+						 */
+					
+					private int
+					checkCookieSet(
+						String		headers,
+						URL			resource )
+					{
+						if ( pairing_access_code == null ){
+						
+							return( 2 );
+						}
+						
+						String[]	locations = { resource.getQuery(), getHeaderField( headers, "Referer" )};
+						
+						for ( String location: locations ){
+						
+							if ( location != null ){
+								
+								int p1 = location.indexOf( "vuze_pairing_ac=" );
+								
+								if ( p1 != -1 ){
+									
+									int p2 = location.indexOf( '&', p1 );
+									
+									String ac = location.substring( p1+16, p2==-1?location.length():p2 ).trim();
+									
+									p2 = ac.indexOf( '#' );
+									
+									if ( p2 != -1 ){
+										
+										ac = ac.substring( 0, p2 );
+									}
+																
+									if ( ac.equalsIgnoreCase( pairing_access_code )){
+								
+										tls.set( pairing_session_code );
+										
+										return( 1 );
+										
+									}else{
+										
+										return( 2 );
+									}
+								}
+							}
+						}
+						
+						return( 0 );
+					}
+					
+					private String
+					getHeaderField(
+						String	headers,
+						String	field )
+					{
+						String lc_headers = headers.toLowerCase();
+						
+						int p1 = lc_headers.indexOf( field.toLowerCase() + ":" );
+						
+						if ( p1 != -1 ){
+						
+							int	p2 = lc_headers.indexOf( '\n', p1 );
 							
-							this_mon.exit();
+							if ( p2 != -1 ){
+								
+								return( headers.substring( p1+field.length()+1, p2 ).trim());
+							}
 						}
+						
+						return( null );
 					}
 				});
 			
 		}catch( TrackerException e ){
 			
-			log.log( "Plugin Initialisation Fails", e );
+			log.log( "Server initialisation failed", e );
+		}
+	}
+	
+	private boolean
+	hasOurCookie(
+		String		cookies )
+	{
+		if ( cookies == null ){
+			
+			return( false );
 		}
 		
-		plugin_interface.addListener(
-			new PluginListener()
-			{
-				public void
-				initializationComplete()
-				{
-					PluginInterface pi_upnp = plugin_interface.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
+		String[] cookie_list = cookies.split( ";" );
+		
+		for ( String cookie: cookie_list ){
+			
+			String[] bits = cookie.split( "=" );
+			
+			if ( bits.length == 2 ){
+				
+				if ( bits[0].trim().equals( "vuze_pairing_sc" )){
 					
-					if ( pi_upnp == null ){
-						
-						log.log( "No UPnP plugin available, not attempting port mapping");
-						
-					}else{
+					if ( bits[1].trim().equals( pairing_session_code )){
 						
-						if ( upnp_enable.getValue()){
-							
-							((UPnPPlugin)pi_upnp.getPlugin()).addMapping( plugin_interface.getPluginName(), true, port, true );
-							
-						}else{
-							
-							log.log( "UPnP disabled for the plugin, not attempting port mapping");
-							
-						}
+						return( true );
 					}
 				}
+			}
+		}
+		
+		return( false );
+	}
+	
+	private boolean
+	sameAddress(
+		InetAddress	a1,
+		InetAddress a2 )
+	{
+		if ( a1 == null && a2 == null ){
+			
+			return( true );
+			
+		}else if ( a1 == null || a2 == null ){
+			
+			return( false );
+			
+		}else{
+			
+			return( a1.equals( a2 ));
+		}
+	}
+	
+	protected void
+	setupUPnP()
+	{
+		if ( !plugin_enabled  || !p_upnp_enable.getValue()){
+			
+			if ( upnp_mapping != null ){
 				
-				public void
-				closedownInitiated()
-				{
-				}
+				log( "Removing UPnP mapping" );
 				
-				public void
-				closedownComplete()
-				{	
+				upnp_mapping.destroy();
+				
+				upnp_mapping = null;
+			}
+			
+			return;
+		}
+		
+		PluginInterface pi_upnp = plugin_interface.getPluginManager().getPluginInterfaceByClass( UPnPPlugin.class );
+		
+		if ( pi_upnp == null ){
+			
+			log.log( "No UPnP plugin available, not attempting port mapping");
+			
+		}else{
+			
+			int port = param_port.getValue();
+			
+			if ( upnp_mapping != null ){
+				
+				if ( upnp_mapping.getPort() == port ){
+					
+					return;
 				}
-			});
+				
+				log( "Updating UPnP mapping" );
+				
+				upnp_mapping.destroy();
+				
+			}else{
+				
+				log( "Creating UPnP mapping" );
+			}
+						
+			upnp_mapping = ((UPnPPlugin)pi_upnp.getPlugin()).addMapping( plugin_interface.getPluginName(), true, port, true );
+		}
 	}
 	
 	protected void
 	setupPairing(
 		String		sid,
-		boolean		enable )
+		boolean		pairing_enabled )
 	{
 		PairingManager pm = PairingManagerFactory.getSingleton();
 		
 		PairedService service = pm.getService( sid );
 		
-		if ( enable ){
+		if ( plugin_enabled && pairing_enabled && pm.isEnabled()){
+			
+			setupAutoAuth();
 			
 			if ( service == null ){
 				
+				log( "Adding pairing service" );
+				
 				service =  pm.addService( sid ); 
 				
 				PairingConnectionData cd = service.getConnectionData();
@@ -917,14 +1583,83 @@ WebPlugin
 			}
 		}else{
 			
+			pairing_access_code 	= null;
+			pairing_session_code	= null;
+			
 			if ( service != null ){
 				
+				log( "Removing pairing service" );
+				
 				service.remove();
 			}
 		}
 	}
 		
 	protected void
+	setupAutoAuth()
+	{
+		PairingManager pm = PairingManagerFactory.getSingleton();
+
+		String ac = pm.peekAccessCode();
+		
+		if ( ac != null && ( pairing_access_code == null || !ac.equals( pairing_access_code ))){
+			
+			synchronized( this ){
+			
+				String existing_key = plugin_config.getPluginStringParameter( PAIRING_SESSION_KEY, "" );
+			
+				String[]	bits = existing_key.split( "=" );
+				
+				if ( bits.length == 2 && bits[0].equals( ac )){
+					
+					pairing_session_code = bits[1];
+					
+				}else{
+			
+					pairing_session_code = Base32.encode( RandomUtils.nextSecureHash());
+					
+					plugin_config.setPluginParameter( PAIRING_SESSION_KEY, ac + "=" + pairing_session_code );
+				}
+			}
+		}
+		
+		pairing_access_code = ac;
+		
+			// good time to check the default pairing auth settings
+		
+		if ( pairing_access_code != null ){
+			
+			if ( param_auto_auth.getValue()){
+				
+				try{
+					setting_auto_auth = true;
+					
+					if ( !p_user_name.getValue().equals( "vuze" )){
+						
+						p_user_name.setValue( "vuze" );
+					}
+					
+			        SHA1Hasher hasher = new SHA1Hasher();
+			        
+			        byte[] encoded = hasher.calculateHash( pairing_access_code.getBytes());
+			        
+					if ( !Arrays.equals( p_password.getValue(), encoded )){
+						
+						p_password.setValue( pairing_access_code );
+					}
+					
+					if ( !pw_enable.getValue()){
+						
+						pw_enable.setValue( true );
+					}
+				}finally{
+					
+					setting_auto_auth = false;
+				}
+			}
+		}
+	}
+	protected void
 	updatePairing(
 		String		sid )
 	{
@@ -936,6 +1671,8 @@ WebPlugin
 			
 			PairingConnectionData cd = service.getConnectionData();
 			
+			log( "Updating pairing information" );
+			
 			try{
 				updatePairing( cd );
 				
@@ -951,6 +1688,18 @@ WebPlugin
 		PairingConnectionData		cd )
 	{
 		cd.setAttribute( PairingConnectionData.ATTR_PORT, 		String.valueOf( param_port.getValue()));
+		
+		int	override = param_port_or==null?0:param_port_or.getValue();
+		
+		if ( override > 0 ){
+			
+			cd.setAttribute( PairingConnectionData.ATTR_PORT_OVERRIDE, 	String.valueOf( override ));
+			
+		}else{
+			
+			cd.setAttribute( PairingConnectionData.ATTR_PORT_OVERRIDE, null );
+		}
+		
 		cd.setAttribute( PairingConnectionData.ATTR_PROTOCOL, 	param_protocol.getValue());
 	}
 
@@ -966,6 +1715,42 @@ WebPlugin
 		return( param_protocol.getValue());
 	}
 	
+	public void
+	setUserAndPassword(
+		String		user,
+		String		password )
+	{
+		p_user_name.setValue( user );
+		p_password.setValue( password );
+		pw_enable.setValue( true );
+	}
+	
+	public void
+	unsetUserAndPassword()
+	{
+		pw_enable.setValue( false );
+	}
+		
+	private void
+	recordAuthRequest(
+		String						client_ip,
+		boolean						good )
+	{
+		PairingManager pm = PairingManagerFactory.getSingleton();
+		
+		pm.recordRequest( plugin_interface.getPluginName(), client_ip, good );
+	}
+	
+	private void
+	recordRequest(
+		TrackerWebPageRequest		request,
+		boolean						good )
+	{					
+		PairingManager pm = PairingManagerFactory.getSingleton();
+		
+		pm.recordRequest( plugin_interface.getPluginName(), request.getClientAddress(), good );
+	}
+	
 	public boolean
 	generateSupport(
 		TrackerWebPageRequest		request,
@@ -983,10 +1768,12 @@ WebPlugin
 	
 		throws IOException
 	{
-		if ( !ip_range_all ){
+		// System.out.println( request.getURL());
 		
-			String	client = request.getClientAddress();
-			
+		String	client = request.getClientAddress();
+
+		if ( !ip_range_all ){
+					
 			// System.out.println( "client = " + client );
 			
 			try{
@@ -998,6 +1785,7 @@ WebPlugin
 					if ( !ia.isLoopbackAddress()){
 				
 						log.log( LoggerChannel.LT_ERROR, "Client '" + client + "' is not local, rejecting" );
+						
 						valid_ip = false;
 					}
 				}else{
@@ -1015,44 +1803,167 @@ WebPlugin
 					if ( !ok ){
 						
 						log.log( LoggerChannel.LT_ERROR, "Client '" + client + "' (" + ia.getHostAddress() + ") is not in range, rejecting" );
+						
 						valid_ip = false;
 					}
 				}
 				
-				if (!valid_ip) {
-					response.setReplyStatus(403);
-					response.setContentType("text/plain");
-
-					PrintWriter pw = new PrintWriter(response.getOutputStream());
-					pw.println("Cannot access resource from this IP address.");
-					pw.flush();
-					pw.close();
-					return true;
+				if ( !valid_ip ){
+					
+					response.setReplyStatus( 403 );
+					
+					recordRequest( request, false );
+					
+					return( returnTextPlain( response, "Cannot access resource from this IP address." ));
 				}
 				
 			}catch( Throwable e ){
 				
 				Debug.printStackTrace( e );
 				
+				recordRequest( request, false );
+				
 				return( false );
 			}
 		}
 		
-		if ( request.getURL().toString().endsWith(".class")){
+		recordRequest( request, true );
+		
+		String url = request.getURL();
+		
+	
+		if ( url.toString().endsWith(".class")){
+			
+			System.out.println( "WebPlugin::generate:" + url );
+		}
+	
+		String	cookie_to_set = tls.get();
+		
+		if ( cookie_to_set == GRACE_PERIOD_MARKER ){
 			
-			System.out.println( "WebPlugin::generate:" + request.getURL());
+			return( returnTextPlain( response, "Logout in progress, please try again later." ));
 		}
+		
+		if ( cookie_to_set != null ){
 			
-		if ( generateSupport( request, response )){
+				// set session cookie
+		
+			response.setHeader( "Set-Cookie", "vuze_pairing_sc=" + cookie_to_set + "; HttpOnly" );
 			
-			return(true);
+			tls.set( null );
 		}
 		
-		String	url = request.getURL();
+		URL full_url = request.getAbsoluteURL();
+		
+		String	full_url_path = full_url.getPath();
 		
-		if (url.equals("/")){
+		if ( full_url_path.equals( "/isPairedServiceAvailable" )){
 			
-			if (home_page != null ){
+			String redirect = getArgumentFromURL( full_url, "redirect_to" );
+			
+			if ( redirect != null ){
+				
+				try{
+					URL target = new URL( redirect );
+					
+					String	host = target.getHost();
+					
+					if ( !Constants.isAzureusDomain( host )){
+					
+						if ( !InetAddress.getByName(host).isLoopbackAddress()){
+							
+							log( "Invalid redirect host: " + host );
+							
+							redirect = null;
+						}
+					}
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+					
+					redirect = null;
+				}
+			}
+			
+			if ( redirect != null ){
+								
+				response.setReplyStatus( 302 );
+				
+				response.setHeader( "Location", redirect );
+				
+				return( true );
+			}
+			
+			String callback = getArgumentFromURL( full_url, "jsoncallback" );
+				
+			if ( callback != null ){
+					
+				return( returnTextPlain( response,  callback + "( {'pairedserviceavailable':true} )"));
+			}
+		}else if ( full_url_path.equals( "/isServicePaired" )){
+			
+			boolean paired = cookie_to_set != null || hasOurCookie((String)request.getHeaders().get( "cookie" ));
+			
+			return( returnJSON( response, "{ 'servicepaired': " + ( paired?"true":"false" ) + " }" ));
+			
+		}else if ( full_url_path.equals( "/pairedServiceLogout")){
+			
+			synchronized( logout_timer ){
+				
+				logout_timer.put( client, SystemTime.getMonotonousTime());
+			}
+			
+			response.setHeader( "Set-Cookie", "vuze_pairing_sc=<deleted>, expires=" + TimeFormatter.getCookieDate(0));
+			
+			String redirect = getArgumentFromURL( full_url, "redirect_to" );
+			
+			if ( redirect != null ){
+				
+				try{
+					URL target = new URL( redirect );
+					
+					String	host = target.getHost();
+					
+					if ( !Constants.isAzureusDomain( host )){
+					
+						if ( !InetAddress.getByName(host).isLoopbackAddress()){
+							
+							log( "Invalid redirect host: " + host );
+							
+							redirect = null;
+						}
+					}
+				}catch( Throwable e ){
+					
+					Debug.out( e );
+					
+					redirect = null;
+				}
+			}
+			if ( redirect == null ){
+					
+				return( returnTextPlain( response, "" ));
+				
+			}else{
+				
+				response.setReplyStatus( 302 );
+				
+				response.setHeader( "Location", redirect );
+				
+				return( true );
+			}
+		}
+	
+		if ( generateSupport( request, response )){
+			
+			return(true);
+		}
+				
+		if ( url.equals("/") || url.startsWith( "/?" )){
+			
+			url = "/";
+			
+			if ( home_page != null ){
 				
 				url = home_page;
 				
@@ -1127,6 +2038,69 @@ WebPlugin
 		return( false );
 	}
 	
+	private String
+	getArgumentFromURL(
+		URL			url,
+		String		argument )
+	{
+		String query = url.getQuery();
+		
+		if ( query != null ){
+						
+			String[] args = query.split( "&" );
+			
+			for ( String arg: args ){
+				
+				String [] x = arg.split( "=" );
+				
+				if ( x.length == 2 ){
+					
+					if ( x[0].equals( argument )){
+						
+						return( UrlUtils.decode( x[1] ));
+					}
+				}
+			}
+		}
+		
+		return( null );
+	}
+	
+	private boolean
+	returnTextPlain(
+		TrackerWebPageResponse		response,
+		String						str )
+	{
+		return( returnStuff( response, "text/plain", str ));
+	}
+	
+	private boolean
+	returnJSON(
+		TrackerWebPageResponse		response,
+		String						str )
+	{
+		return( returnStuff( response, "text/plain", str ));
+	}
+	
+	private boolean
+	returnStuff(
+		TrackerWebPageResponse		response,
+		String						content_type,
+		String						str )
+	{
+		response.setContentType( content_type );
+		
+		PrintWriter pw = new PrintWriter( response.getOutputStream());
+		
+		pw.println( str );
+		
+		pw.flush();
+		
+		pw.close();
+	
+		return( true );
+	}
+	
 	protected BasicPluginConfigModel
 	getConfigModel()
 	{
diff --git a/org/gudy/azureus2/ui/webplugin/WebPluginAccessController.java b/org/gudy/azureus2/ui/webplugin/WebPluginAccessController.java
index 899df2d..6bbce2c 100644
--- a/org/gudy/azureus2/ui/webplugin/WebPluginAccessController.java
+++ b/org/gudy/azureus2/ui/webplugin/WebPluginAccessController.java
@@ -23,6 +23,8 @@
 package org.gudy.azureus2.ui.webplugin;
 
 import org.gudy.azureus2.plugins.*;
+import org.gudy.azureus2.plugins.config.ConfigParameter;
+import org.gudy.azureus2.plugins.config.ConfigParameterListener;
 import org.gudy.azureus2.pluginsimpl.remote.*;
 import org.gudy.azureus2.pluginsimpl.remote.rpexceptions.*;
 
@@ -39,7 +41,34 @@ WebPluginAccessController
 
     public
     WebPluginAccessController(
-        PluginInterface     pi )
+        final PluginInterface     pi )
+    {
+        ConfigParameter mode_parameter = pi.getPluginconfig().getPluginParameter( WebPlugin.CONFIG_MODE );
+
+        if ( mode_parameter == null ){
+        	
+        	view_mode = true;
+        	
+        }else{
+        	
+        	mode_parameter.addConfigParameterListener(
+        		new ConfigParameterListener()
+        		{
+        			public void 
+        			configParameterChanged(
+        				ConfigParameter param )
+        			{
+        				setViewMode( pi );
+        			}
+        		});
+        	
+        	setViewMode( pi );
+        }
+    }
+    
+    protected void
+    setViewMode(
+    	PluginInterface		pi )
     {
         String mode_str = pi.getPluginconfig().getPluginStringParameter( WebPlugin.CONFIG_MODE, ((WebPlugin)pi.getPlugin()).CONFIG_MODE_DEFAULT );
 
diff --git a/org/gudy/azureus2/update/CorePatchChecker.java b/org/gudy/azureus2/update/CorePatchChecker.java
index 82fd9ae..f885d99 100644
--- a/org/gudy/azureus2/update/CorePatchChecker.java
+++ b/org/gudy/azureus2/update/CorePatchChecker.java
@@ -28,6 +28,7 @@ package org.gudy.azureus2.update;
  */
 
 import java.io.*;
+import java.util.*;
 
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.logging.*;
@@ -47,6 +48,8 @@ CorePatchChecker
 	
 	protected PluginInterface	plugin_interface;
 	
+	private Map<UpdateCheckInstance,Update>	my_updates = new HashMap<UpdateCheckInstance, Update>(1);
+	
 	public void 
 	initialize(
 		PluginInterface _plugin_interface )
@@ -91,9 +94,11 @@ CorePatchChecker
 		
 			inst.addListener( this );
 		
-			checker.addUpdate( "Core Patch Checker", new String[0], "",
+			my_updates.put(
+				inst,
+				checker.addUpdate( "Core Patch Checker", new String[0], "",
 								new ResourceDownloader[0],
-								Update.RESTART_REQUIRED_MAYBE );
+								Update.RESTART_REQUIRED_MAYBE ));
 		}finally{
 			
 			checker.completed();
@@ -104,12 +109,25 @@ CorePatchChecker
 	cancelled(
 		UpdateCheckInstance		instance )
 	{
+		Update update = my_updates.remove( instance );
+		
+		if ( update != null ){
+			
+			update.cancel();
+		}
 	}
 	
 	public void
 	complete(
 		final UpdateCheckInstance		instance )
 	{
+		Update my_update = my_updates.remove( instance );
+		
+		if ( my_update != null ){
+			
+			my_update.complete( true );
+		}
+		
 		Update[]	updates = instance.getUpdates();
 		
 		final PluginInterface updater_plugin = plugin_interface.getPluginManager().getPluginInterfaceByClass( UpdaterUpdateChecker.class );
diff --git a/org/gudy/azureus2/update/CoreUpdateChecker.java b/org/gudy/azureus2/update/CoreUpdateChecker.java
index a19e928..d5b08e5 100644
--- a/org/gudy/azureus2/update/CoreUpdateChecker.java
+++ b/org/gudy/azureus2/update/CoreUpdateChecker.java
@@ -36,15 +36,19 @@ import java.io.*;
 import org.gudy.azureus2.core3.util.*;
 import org.gudy.azureus2.core3.logging.*;
 import org.gudy.azureus2.core3.config.*;
-import org.gudy.azureus2.core3.html.*;
+import org.gudy.azureus2.core3.internat.MessageText;
 
 import org.gudy.azureus2.platform.win32.access.AEWin32Access;
 import org.gudy.azureus2.platform.win32.access.AEWin32Manager;
 import org.gudy.azureus2.plugins.*;
 import org.gudy.azureus2.plugins.logging.LoggerChannel;
+import org.gudy.azureus2.plugins.ui.UIManager;
+import org.gudy.azureus2.plugins.ui.UIManagerEvent;
 import org.gudy.azureus2.plugins.update.*;
+import org.gudy.azureus2.plugins.utils.StaticUtilities;
 import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
 
+import com.aelitis.azureus.core.util.GeneralUtils;
 import com.aelitis.azureus.core.versioncheck.*;
 import com.aelitis.azureus.ui.UIFunctions;
 import com.aelitis.azureus.ui.UIFunctionsManager;
@@ -433,6 +437,16 @@ CoreUpdateChecker
 									
 							return( true );
 						}
+						
+						public void
+						failed(
+							ResourceDownloader			downloader,
+							ResourceDownloaderException e )
+						{
+							Debug.out( downloader.getName() + " failed", e );
+							
+							update.complete( false );
+						}
 					});
 		}catch( Throwable e ){
 			
@@ -513,6 +527,8 @@ CoreUpdateChecker
 	
 				  if ( !message.equals( last )){
 	
+					  boolean	repeatable = false;
+					  
 					  byte[]	signature = (byte[])reply.get( sig_key );
 	
 					  if ( signature == null ){
@@ -534,14 +550,19 @@ CoreUpdateChecker
 	
 					  boolean	completed = false;
 					  
-					  if ( message.startsWith( "x:" )){
+					  if ( message.startsWith( "x:" ) || message.startsWith( "y:" )){
 						  
 						  	// emergency patch application
 						  
+						  repeatable = message.startsWith( "y:" );
+						  
 						  try{
 							  URL jar_url = new URL( message.substring(2));
 							  
-							  Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application requsted: url=" + jar_url ));
+							  if ( !repeatable ){
+							  
+								  Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application requsted: url=" + jar_url ));
+							  }
 
 							  File	temp_dir = AETemporaryFileHandler.createTempDir();
 							  
@@ -587,10 +608,17 @@ CoreUpdateChecker
 								  
 									  is.close();
 								  }
+								  
+								  jar_file.delete();
+								  
+								  temp_dir.delete();
 							  }
 						  }catch( Throwable e ){
 							  
-							  Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application failed", e  ));
+							  if ( !repeatable ){
+							  
+								  Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application failed", e  ));
+							  }
 						  }
 					  } else if ( message.startsWith("u:") && message.length() > 4 ) {
 					  	try {
@@ -611,6 +639,15 @@ CoreUpdateChecker
 						  
 						  String  alert_text    = message;
 		
+						  boolean	force = false;
+						  
+						  if ( alert_text.startsWith( "f:" )){
+							  
+							  force = true;
+						  
+							  alert_text = alert_text.substring( 2 );
+						  }
+						  
 						  if ( alert_text.startsWith("i:" )){
 		
 							  alert_type = LogAlert.AT_INFORMATION;
@@ -620,16 +657,39 @@ CoreUpdateChecker
 		
 						  plugin_interface.getPluginProperties().setProperty( MESSAGE_PROPERTY, alert_text );
 		
-						  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, alert_type, alert_text, 0 ));
+						  if ( force ){
+							  
+							  UIFunctions uif = UIFunctionsManager.getUIFunctions();
+							  
+							  if ( uif != null ){
+								  
+								  try{
+									  uif.forceNotify( UIFunctions.STATUSICON_NONE, null, alert_text, null, null, 0 );
+								  
+									  completed = true;
+									  
+								  }catch( Throwable e ){
+									  
+								  }
+							  }
+						  }
+						  
+						  if ( !completed ){
+							  
+							  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, alert_type, alert_text, 0 ));
+						  }
 						  
 						  completed = true;
 					  }
 					  
 					  if ( completed ){
 						  
-						  COConfigurationManager.setParameter( last_message_key, message );
-	
-						  COConfigurationManager.save();
+						  if ( !repeatable ){
+							  
+							  COConfigurationManager.setParameter( last_message_key, message );
+		
+							  COConfigurationManager.save();
+						  }
 					  }
 				  }
 			  }
@@ -665,7 +725,7 @@ CoreUpdateChecker
 				
 				rd.addListener( rd_logger );
 				
-				String	page = HTMLPageFactory.loadPage( rd.download()).getContent();
+				String page = FileUtil.readInputStreamAsString(rd.download(), 65535);
 				
 				String pattern = "/azureus/" + latest_file_name + "?use_mirror=";
 	     
@@ -738,7 +798,7 @@ CoreUpdateChecker
 							
 				log.log( "Downloading backup mirrors" );
 				
-				URL mirrors_url = new URL("http://azureus.sourceforge.net/mirrors.php");
+				URL mirrors_url = new URL("http://plugins.vuze.com/mirrors.php");
 				
 				ResourceDownloader	rd = rdf.create( mirrors_url );
 				
@@ -833,8 +893,13 @@ CoreUpdateChecker
 						installer.getInstallDir() + File.separator + target_jar_name );
 				}
 			}
+			
+			update.complete( true );
+			
 		}catch( Throwable e ){
 			
+			update.complete( false );
+			
 			rd.reportActivity("Update install failed:" + e.getMessage());
 		}
 	}
@@ -913,7 +978,23 @@ CoreUpdateChecker
 			
 			throw( new Exception( "Update property 'info.url' missing" ));
 		}
+			
+			// update_properties.setProperty( "launch.args" , "-silent" );
+			// update_properties.setProperty( "launch.silent" , "true" );
+		
+		String	s_args = update_properties.getProperty( "launch.args", "" ).trim();
 				
+		final String[] args;
+		
+		if ( s_args.length() > 0 ){
+			
+			args = GeneralUtils.splitQuotedTokens( s_args );
+			
+		}else{
+			
+			args = new String[0];
+		}
+		
 		UIFunctions uif = UIFunctionsManager.getUIFunctions();
 
 		if ( uif == null ){
@@ -924,27 +1005,74 @@ CoreUpdateChecker
 		checker.getCheckInstance().setProperty( UpdateCheckInstance.PT_CLOSE_OR_RESTART_ALREADY_IN_PROGRESS, true );
 
 		final File f_update_file = update_file;
+			
+		boolean	silent = update_properties.getProperty( "launch.silent", "false" ).equals( "true" );
+		
+		if ( silent ){
+			
+				// problem on OSX if they have renamed their app and we're running silently as it
+				// installs to Vuze.app regardless
+			
+			if ( Constants.isOSX ){
 				
-		uif.performAction( 
-			UIFunctions.ACTION_FULL_UPDATE,
-			info_url,
-			new UIFunctions.actionListener()
-			{
-				public void
-				actionComplete(
-					Object	result )
+				String app_name = SystemProperties.getApplicationName();
+				
+				if ( !( app_name.equals( "Vuze" ) || app_name.equals( "Azureus" ))){
+					
+					UIManager ui_manager = StaticUtilities.getUIManager( 120*1000 );
+					
+					String details = MessageText.getString(
+							"update.fail.app.changed",
+							new String[]{ app_name });
+					
+					ui_manager.showMessageBox(
+							"update.fail.app.changed.title",
+							"!" + details + "!",
+							UIManagerEvent.MT_OK );
+					
+					return;
+				}
+			}
+			
+			uif.performAction( 
+					UIFunctions.ACTION_UPDATE_RESTART_REQUEST,
+					!FileUtil.canReallyWriteToAppDirectory(),
+					new UIFunctions.actionListener()
+					{
+						public void
+						actionComplete(
+							Object	result )
+						{
+							if ((Boolean)result){
+								
+								launchUpdate( f_update_file, args );
+							}
+						}
+					});
+		}else{
+			
+			uif.performAction( 
+				UIFunctions.ACTION_FULL_UPDATE,
+				info_url,
+				new UIFunctions.actionListener()
 				{
-					if ((Boolean)result){
-						
-						launchUpdate( f_update_file );
+					public void
+					actionComplete(
+						Object	result )
+					{
+						if ((Boolean)result){
+							
+							launchUpdate( f_update_file, args );
+						}
 					}
-				}
-			});
+				});
+		}
 	}
 	
 	protected void
 	launchUpdate(
-		File		file )
+		File		file,
+		String[]	args )
 	{
 		try{
 				// hack here to allow testing of osx on windows (parg) - should replace with
@@ -957,10 +1085,22 @@ CoreUpdateChecker
 					
 					// accessor.createProcess( , false );
 					
+					String	s_args = null;
+					
+					if ( args.length > 0 ){
+					
+						s_args = "";
+						
+						for ( String s: args ){
+							
+							s_args += (s_args.length()==0?"":" ") + s;
+						}
+					}
+					
 					accessor.shellExecute( 
 						null, 
 						file.getAbsolutePath(), 
-						null,
+						s_args,
 						SystemProperties.getApplicationPath(),
 						AEWin32Access.SW_NORMAL );
 					
@@ -968,7 +1108,20 @@ CoreUpdateChecker
 					
 					Logger.log( new LogEvent( LogIDs.LOGGER, "AEWin32Access failed", e  ));
 
-					Runtime.getRuntime().exec( file.getAbsolutePath() );
+					if ( args.length > 0 ){
+					
+						String[] s_args = new String[args.length+1];
+						
+						s_args[0] = file.getAbsolutePath();
+						
+						System.arraycopy( args, 0, s_args, 1, args.length );
+						
+						Runtime.getRuntime().exec( s_args );
+						
+					}else{
+					
+						Runtime.getRuntime().exec( file.getAbsolutePath() );
+					}
 				}
 			}else{
 					// osx, need to unzip .app and launch
@@ -979,6 +1132,8 @@ CoreUpdateChecker
 		    		
 			   	Throwable unzip_error = null;
 			   	
+			   	String chmod_command = findCommand( "chmod" );
+			   	
 		    	try{
 					while( true ){
 												
@@ -1034,7 +1189,7 @@ CoreUpdateChecker
 								if ( name.endsWith( ".jnilib" ) || name.endsWith( "JavaApplicationStub" )){
 										
 									try{
-										String[] to_run = { "/bin/sh", "-c", "chmod a+x \"" + entry_file.getAbsolutePath() + "\""};
+										String[] to_run = { chmod_command, "a+x", entry_file.getAbsolutePath() };
 									  	
 										runCommand( to_run, true );
 												
@@ -1064,8 +1219,27 @@ CoreUpdateChecker
 		    		
 		    		if ( f.getName().endsWith( ".app" )){
 		    	
-		    			String[] to_run = { "/bin/sh", "-c", "open \"" + f.getAbsolutePath() + "\""};
-			  		
+		    			String[] to_run;
+		    			
+		    				// can't pass args unless using 'open' on 10.6 or higher. Update process
+		    				// has been changed to avoid arg passing on OSX anyway, but leaving this
+		    				// in in case needed in the future
+		    			
+		    			if ( args.length == 0 || !Constants.isOSX_10_6_OrHigher){
+		    				
+			    			to_run = new String[]{ "/bin/sh", "-c", "open \"" + f.getAbsolutePath() + "\""};
+			    			
+		    			}else{
+		    				
+		    				to_run = new String[ 3 + args.length ];
+		    				
+		    				to_run[0] = findCommand( "open" );
+		    				to_run[1] = f.getAbsolutePath();		    				
+		    				to_run[2] = "--args";
+		    				
+		    				System.arraycopy( args, 0, to_run, 3, args.length );
+		    			}
+		    			
 		    			runCommand( to_run, false );
 		    			
 		    			launched = true;
@@ -1083,6 +1257,25 @@ CoreUpdateChecker
 		}
 	}
 	
+	private static String
+	findCommand(
+		String	name )
+	{
+		final String[]  locations = { "/bin", "/usr/bin" };
+
+		for ( String s: locations ){
+
+			File f = new File( s, name );
+
+			if ( f.exists() && f.canRead()){
+
+				return( f.getAbsolutePath());
+			}
+		}
+
+		return( name );
+	}
+	  
 	private static void
 	runCommand(
 		String[]	command,
@@ -1095,7 +1288,7 @@ CoreUpdateChecker
 			
 			for ( String s: command ){
 				
-				str += (str.length()==0?"":", ") + s;
+				str += (str.length()==0?"":" ") + s;
 			}
 			
 			System.out.println( "running " + str );
@@ -1131,16 +1324,16 @@ CoreUpdateChecker
 			//	3) 2.4.0.1_B12 -> 2.4.0.2  and 2.4.0.1_B14
 		
 			// but NOT
-			//  1) 2.4.0.0 	   -> 2.4.0.1_CVS or 2.4.0.1_B23
+			//  1) 2.4.0.0 	   -> 2.4.0.1_CVS
 			//  2) 2.4.0.1_CVS -> 2.4.0.1_B23
 		
 			// for inc values: 0 = not CVS, -1 = _CVS, > 0 = Bnn
 
 		int	major_comp = Constants.compareVersions( current_base, latest_base );
 		
-		if ( major_comp < 0 && latest_inc == 0 ){
-			
-			return( true );		// latest is higher version and not CVS
+		if ( major_comp < 0 && latest_inc >= 0 ){
+						
+			return( true );		// latest is higher version and not CVS			
 		}
 		
 			// same version, both are B versions and latest B is more recent
@@ -1159,7 +1352,7 @@ CoreUpdateChecker
 				{ "2.4.0.1_B12", 	"2.4.0.1_B34",	"true" },
 				{ "2.4.0.1_B12", 	"2.4.0.1_B6",	"false" },
 				{ "2.4.0.0", 		"2.4.0.1_CVS",	"false" },
-				{ "2.4.0.0", 		"2.4.0.1_B12",	"false" },
+				{ "2.4.0.0", 		"2.4.0.1_B12",	"true" },
 				{ "2.4.0.0", 		"2.4.0.0"	,	"false" },
 				{ "2.4.0.1_CVS", 	"2.4.0.1_CVS",	"false" },
 				{ "2.4.0.1_B2", 	"2.4.0.1_B2",	"false" },
diff --git a/org/gudy/azureus2/update/Test.java b/org/gudy/azureus2/update/Test.java
deleted file mode 100644
index 1e7d005..0000000
--- a/org/gudy/azureus2/update/Test.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Created on 25-May-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 org.gudy.azureus2.update;
-
-/**
- * @author parg
- *
- */
-
-import java.io.*;
-
-import org.gudy.azureus2.core3.util.Debug;
-
-public class 
-Test 
-{
-	protected
-	Test()
-	{
-		try{
-			InputStream	is 	= new FileInputStream( "Azureus2.jar" );
-			
-			InputStream pis = new FileInputStream( "plugins" + File.separator + "azupdater" + File.separator + "Azureus2_2.0.8.5_P1.pat" );
-			
-			OutputStream os = new FileOutputStream( "test.jar" );
-			
-			new UpdateJarPatcher( is, pis, os, null );
-			
-			is.close();
-			
-			pis.close();
-						
-			os.close();
-			
-		}catch( Throwable e ){
-			
-			Debug.printStackTrace( e );
-		}
-		
-	}
-	
-	public static void
-	main(
-		String[]	args )
-	{
-		new Test();
-	}
-}
diff --git a/org/gudy/azureus2/update/UpdaterUtils.java b/org/gudy/azureus2/update/UpdaterUtils.java
index 5f4c805..f0b5312 100644
--- a/org/gudy/azureus2/update/UpdaterUtils.java
+++ b/org/gudy/azureus2/update/UpdaterUtils.java
@@ -43,6 +43,7 @@ public class UpdaterUtils
 	public static String AZUPDATERPATCHER_PLUGIN_ID 	= "azupdaterpatcher";
 	
 	protected static String AZUPNPAV_PLUGIN_ID 			= "azupnpav";
+	protected static String AEFEATMAN_PLUGIN_ID 		= "aefeatman_v";
 
 	public static boolean 
 	disableNativeCode(
@@ -107,6 +108,21 @@ public class UpdaterUtils
 						"plugin.name=UPnP Media Server",
 						"plugin.id=azupnpav" });
 			}
+			
+				// user-dir is better anyway
+			
+			target_props = getPropsIfNotPresent( AEFEATMAN_PLUGIN_ID, false );
+			
+			if ( target_props != null ){
+				
+				writePluginProperties(
+					target_props,
+					new String[]{
+						"plugin.class=com.aelitis.azureus.plugins.featman.FeatManPlugin",
+						"plugin.name=Vuze Feature Manager",
+						"plugin.id=aefeatman_v" });
+			}
+			
 		}catch( Throwable e){
 			
 			Debug.printStackTrace(e);
@@ -145,6 +161,8 @@ public class UpdaterUtils
 			PrintWriter pw = null;
 			
 			try{
+				target.getParentFile().mkdirs();
+				
 				pw = new PrintWriter(new FileWriter(target));
 	
 				for (int i=0;i<lines.length;i++){
diff --git a/org/json/simple/ItemList.java b/org/json/simple/ItemList.java
index 28a4705..2166a60 100644
--- a/org/json/simple/ItemList.java
+++ b/org/json/simple/ItemList.java
@@ -1,5 +1,5 @@
 /*
- * $Id: ItemList.java,v 1.2 2009/03/15 22:12:18 parg Exp $
+ * $Id: ItemList.java,v 1.2 2009-03-15 22:12:18 parg Exp $
  * Created on 2006-3-24
  */
 package org.json.simple;
diff --git a/org/json/simple/JSONArray.java b/org/json/simple/JSONArray.java
index dda8ab8..379721f 100644
--- a/org/json/simple/JSONArray.java
+++ b/org/json/simple/JSONArray.java
@@ -1,5 +1,5 @@
 /*
- * $Id: JSONArray.java,v 1.1 2007/06/05 00:43:56 tuxpaper Exp $
+ * $Id: JSONArray.java,v 1.1 2007-06-05 00:43:56 tuxpaper Exp $
  * Created on 2006-4-10
  */
 package org.json.simple;
diff --git a/org/json/simple/JSONObject.java b/org/json/simple/JSONObject.java
index 5b9d08c..7ed3668 100644
--- a/org/json/simple/JSONObject.java
+++ b/org/json/simple/JSONObject.java
@@ -1,5 +1,5 @@
 /*
- * $Id: JSONObject.java,v 1.2 2008/08/07 01:18:54 parg Exp $
+ * $Id: JSONObject.java,v 1.2 2008-08-07 01:18:54 parg Exp $
  * Created on 2006-4-10
  */
 package org.json.simple;
diff --git a/org/json/simple/JSONValue.java b/org/json/simple/JSONValue.java
index cea150f..50e388a 100644
--- a/org/json/simple/JSONValue.java
+++ b/org/json/simple/JSONValue.java
@@ -1,5 +1,5 @@
 /*
- * $Id: JSONValue.java,v 1.1 2007/06/05 00:43:56 tuxpaper Exp $
+ * $Id: JSONValue.java,v 1.1 2007-06-05 00:43:56 tuxpaper Exp $
  * Created on 2006-4-15
  */
 package org.json.simple;
diff --git a/org/json/simple/Test.java b/org/json/simple/Test.java
index be9a3e1..750b34b 100644
--- a/org/json/simple/Test.java
+++ b/org/json/simple/Test.java
@@ -1,5 +1,5 @@
 /*
- * $Id: Test.java,v 1.1 2007/06/05 00:43:56 tuxpaper Exp $
+ * $Id: Test.java,v 1.1 2007-06-05 00:43:56 tuxpaper Exp $
  * Created on 2006-4-15
  */
 package org.json.simple;
diff --git a/org/json/simple/parser/JSONParser.java b/org/json/simple/parser/JSONParser.java
index 5fee75c..90e0886 100644
--- a/org/json/simple/parser/JSONParser.java
+++ b/org/json/simple/parser/JSONParser.java
@@ -1,5 +1,5 @@
 /*
- * $Id: JSONParser.java,v 1.2 2008/08/07 01:18:55 parg Exp $
+ * $Id: JSONParser.java,v 1.2 2008-08-07 01:18:55 parg Exp $
  * Created on 2006-4-15
  */
 package org.json.simple.parser;
diff --git a/org/json/simple/parser/Yytoken.java b/org/json/simple/parser/Yytoken.java
index 5587a3f..4c90001 100644
--- a/org/json/simple/parser/Yytoken.java
+++ b/org/json/simple/parser/Yytoken.java
@@ -1,5 +1,5 @@
 /*
- * $Id: Yytoken.java,v 1.1 2007/06/05 00:43:56 tuxpaper Exp $
+ * $Id: Yytoken.java,v 1.1 2007-06-05 00:43:56 tuxpaper Exp $
  * Created on 2006-4-15
  */
 package org.json.simple.parser;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/azureus.git



More information about the pkg-java-commits mailing list